UNPKG

kinto

Version:

An Offline-First JavaScript client for Kinto.

18,506 lines 1.55 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 = [];
    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).

      var i = 0; // `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"];
/**
 * 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 () {
  (0, _createClass2.default)(SyncResultObject, null, [{
    key: "defaults",

    /**
     * Object default values.
     * @type {Object}
     */
    get: function get() {
      return {
        ok: true,
        lastModified: null,
        errors: [],
        created: [],
        updated: [],
        deleted: [],
        published: [],
        conflicts: [],
        skipped: [],
        resolved: []
      };
    }
    /**
     * Public constructor.
     */

  }]);

  function SyncResultObject() {
    (0, _classCallCheck2.default)(this, SyncResultObject);

    /**
     * Current synchronization result status; becomes `false` when conflicts or
     * errors are registered.
     * @type {Boolean}
     */
    this.ok = true;
    Object.assign(this, SyncResultObject.defaults);
  }
  /**
   * 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[type])) {
        return;
      }

      if (!Array.isArray(entries)) {
        entries = [entries];
      } // Deduplicate entries by id. If the values don't have `id` attribute, just
      // keep all.


      var recordsWithoutId = new Set();
      var recordsById = new Map();

      function addOneRecord(record) {
        if (!record.id) {
          recordsWithoutId.add(record);
        } else {
          recordsById.set(record.id, record);
        }
      }

      this[type].forEach(addOneRecord);
      entries.forEach(addOneRecord);
      this[type] = Array.from(recordsById.values()).concat(Array.from(recordsWithoutId));
      this.ok = this.errors.length + this.conflicts.length === 0;
      return this;
    }
    /**
     * Reinitializes result entries for a given result type.
     *
     * @param  {String} type The result type.
     * @return {SyncResultObject}
     */

  }, {
    key: "reset",
    value: function reset(type) {
      this[type] = SyncResultObject.defaults[type];
      this.ok = this.errors.length + this.conflicts.length === 0;
      return this;
    }
  }]);
  return SyncResultObject;
}();

exports.SyncResultObject = SyncResultObject;

var ServerWasFlushedError =
/*#__PURE__*/
function (_Error) {
  (0, _inherits2.default)(ServerWasFlushedError, _Error);

  function ServerWasFlushedError(clientTimestamp, serverTimestamp, message) {
    var _this;

    (0, _classCallCheck2.default)(this, ServerWasFlushedError);
    _this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(ServerWasFlushedError).call(this, message));

    if (Error.captureStackTrace) {
      Error.captureStackTrace((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), ServerWasFlushedError);
    }

    _this.clientTimestamp = clientTimestamp;
    _this.serverTimestamp = serverTimestamp;
    return _this;
  }

  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.
 * @return {Object}
 */


function importChange(transaction, remote, localFields) {
  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
    };
  } // Compare local and remote, ignoring local fields.


  var isIdentical = recordsEqual(local, remote, localFields); // Apply remote changes on local record.

  var synced = (0, _objectSpread2.default)({}, local, markSynced(remote)); // 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) && !record.hasOwnProperty("id")) {
        return reject("Missing required Id; synced and useRecordId options require one");
      }

      if (!options.synced && !options.useRecordId && record.hasOwnProperty("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 (!record.hasOwnProperty("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 (!record.hasOwnProperty("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 _this2 = this;

        var strategy,
            _ref2,
            imports,
            resolved,
            data,
            _args4 = arguments;

        return _regenerator.default.wrap(function _callee4$(_context4) {
          while (1) {
            switch (_context4.prev = _context4.next) {
              case 0:
                strategy = _args4.length > 2 && _args4[2] !== undefined ? _args4[2] : Collection.strategy.MANUAL;
                _context4.prev = 1;
                _context4.next = 4;
                return this.db.execute(function (transaction) {
                  var imports = decodedChanges.map(function (remote) {
                    // Store remote change into local database.
                    return importChange(transaction, remote, _this2.localFields);
                  });
                  var conflicts = imports.filter(function (i) {
                    return i.type === "conflicts";
                  }).map(function (i) {
                    return i.data;
                  });

                  var resolved = _this2._handleConflicts(transaction, conflicts, strategy);

                  return {
                    imports: imports,
                    resolved: resolved
                  };
                }, {
                  preload: decodedChanges.map(function (record) {
                    return record.id;
                  })
                });

              case 4:
                _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);
                }

                _context4.next = 15;
                break;

              case 11:
                _context4.prev = 11;
                _context4.t0 = _context4["catch"](1);
                data = {
                  type: "incoming",
                  message: _context4.t0.message,
                  stack: _context4.t0.stack
                }; // XXX one error of the whole transaction instead of per atomic op

                syncResultObject.add("errors", data);

              case 15:
                return _context4.abrupt("return", syncResultObject);

              case 16:
              case "end":
                return _context4.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 _this3 = this;

        var strategy,
            toDeleteLocally,
            toUpdateLocally,
            _ref4,
            published,
            resolved,
            _args5 = arguments;

        return _regenerator.default.wrap(function _callee5$(_context5) {
          while (1) {
            switch (_context5.prev = _context5.next) {
              case 0:
                strategy = _args5.length > 3 && _args5[3] !== undefined ? _args5[3] : Collection.strategy.MANUAL;
                toDeleteLocally = toApplyLocally.filter(function (r) {
                  return r.deleted;
                });
                toUpdateLocally = toApplyLocally.filter(function (r) {
                  return !r.deleted;
                });
                _context5.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 = _this3._handleConflicts(transaction, conflicts, strategy);

                  return {
                    published: published,
                    resolved: resolved
                  };
                });

              case 5:
                _ref4 = _context5.sent;
                published = _ref4.published;
                resolved = _ref4.resolved;
                syncResultObject.add("published", published);

                if (resolved.length > 0) {
                  syncResultObject.reset("conflicts").reset("resolved").add("resolved", resolved);
                }

                return _context5.abrupt("return", syncResultObject);

              case 11:
              case "end":
                return _context5.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 _this4 = 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 = _this4._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 _this5 = 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(_this5, 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$(_context6) {
          while (1) {
            switch (_context6.prev = _context6.next) {
              case 0:
                _context6.next = 2;
                return this.list({
                  filters: {
                    _status: ["deleted", "synced"]
                  },
                  order: ""
                }, {
                  includeDeleted: true
                });

              case 2:
                unsynced = _context6.sent;
                _context6.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;
                _context6.next = 8;
                return this.db.saveLastModified(null);

              case 8:
                return _context6.abrupt("return", unsynced.data.length);

              case 9:
              case "end":
                return _context6.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$(_context7) {
          while (1) {
            switch (_context7.prev = _context7.next) {
              case 0:
                _context7.next = 2;
                return this.list({
                  filters: {
                    _status: ["created", "updated"]
                  },
                  order: ""
                });

              case 2:
                unsynced = _context7.sent;
                _context7.next = 5;
                return this.list({
                  filters: {
                    _status: "deleted"
                  },
                  order: ""
                }, {
                  includeDeleted: true
                });

              case 5:
                deleted = _context7.sent;
                _context7.next = 8;
                return Promise.all(unsynced.data.concat(deleted.data).map(this._encodeRecord.bind(this, "remote")));

              case 8:
                return _context7.abrupt("return", _context7.sent);

              case 9:
              case "end":
                return _context7.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 _this6 = this;

        var options,
            since,
            filters,
            exclude_id,
            _ref6,
            data,
            last_modified,
            unquoted,
            localSynced,
            serverChanged,
            emptyCollection,
            e,
            decodedChanges,
            payload,
            afterHooks,
            _args8 = arguments;

        return _regenerator.default.wrap(function _callee8$(_context8) {
          while (1) {
            switch (_context8.prev = _context8.next) {
              case 0:
                options = _args8.length > 2 && _args8[2] !== undefined ? _args8[2] : {};

                if (syncResultObject.ok) {
                  _context8.next = 3;
                  break;
                }

                return _context8.abrupt("return", syncResultObject);

              case 3:
                if (!this.lastModified) {
                  _context8.next = 7;
                  break;
                }

                _context8.t0 = this.lastModified;
                _context8.next = 10;
                break;

              case 7:
                _context8.next = 9;
                return this.db.getLastModified();

              case 9:
                _context8.t0 = _context8.sent;

              case 10:
                since = _context8.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


                _context8.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 = _context8.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)) {
                  _context8.next = 26;
                  break;
                }

                e = new ServerWasFlushedError(localSynced, unquoted, "Server has been flushed. Client Side Timestamp: " + localSynced + " Server Side Timestamp: " + unquoted);
                throw e;

              case 26:
                syncResultObject.lastModified = unquoted; // Decode incoming changes.

                _context8.next = 29;
                return Promise.all(data.map(function (change) {
                  return _this6._decodeRecord("remote", change);
                }));

              case 29:
                decodedChanges = _context8.sent;
                // Hook receives decoded records.
                payload = {
                  lastModified: unquoted,
                  changes: decodedChanges
                };
                _context8.next = 33;
                return this.applyHook("incoming-changes", payload);

              case 33:
                afterHooks = _context8.sent;

                if (!(afterHooks.changes.length > 0)) {
                  _context8.next = 37;
                  break;
                }

                _context8.next = 37;
                return this.importChanges(syncResultObject, afterHooks.changes, options.strategy);

              case 37:
                return _context8.abrupt("return", syncResultObject);

              case 38:
              case "end":
                return _context8.stop();
            }
          }
        }, _callee8, this);
      }));

      return function pullChanges(_x6, _x7) {
        return _pullChanges.apply(this, arguments);
      };
    }()
  }, {
    key: "applyHook",
    value: function applyHook(hookName, payload) {
      var _this7 = 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, _this7);
          var resultThenable = result && typeof result.then === "function";
          var resultChanges = result && result.hasOwnProperty("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 _this8 = 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,
            _args9 = arguments;

        return _regenerator.default.wrap(function _callee9$(_context9) {
          while (1) {
            switch (_context9.prev = _context9.next) {
              case 0:
                options = _args9.length > 3 && _args9[3] !== undefined ? _args9[3] : {};

                if (syncResultObject.ok) {
                  _context9.next = 3;
                  break;
                }

                return _context9.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.

                _context9.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 = _this8.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 = _context9.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;
                _context9.prev = 14;
                _iterator2 = synced.conflicts[Symbol.iterator]();

              case 16:
                if (_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done) {
                  _context9.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
                };
                _context9.next = 21;
                return this._decodeRecord("remote", safeLocal);

              case 21:
                realLocal = _context9.sent;
                _context9.t0 = remote;

                if (!_context9.t0) {
                  _context9.next = 27;
                  break;
                }

                _context9.next = 26;
                return this._decodeRecord("remote", remote);

              case 26:
                _context9.t0 = _context9.sent;

              case 27:
                realRemote = _context9.t0;
                conflict = {
                  type: type,
                  local: realLocal,
                  remote: realRemote
                };
                conflicts.push(conflict);

              case 30:
                _iteratorNormalCompletion2 = true;
                _context9.next = 16;
                break;

              case 33:
                _context9.next = 39;
                break;

              case 35:
                _context9.prev = 35;
                _context9.t1 = _context9["catch"](14);
                _didIteratorError2 = true;
                _iteratorError2 = _context9.t1;

              case 39:
                _context9.prev = 39;
                _context9.prev = 40;

                if (!_iteratorNormalCompletion2 && _iterator2.return != null) {
                  _iterator2.return();
                }

              case 42:
                _context9.prev = 42;

                if (!_didIteratorError2) {
                  _context9.next = 45;
                  break;
                }

                throw _iteratorError2;

              case 45:
                return _context9.finish(42);

              case 46:
                return _context9.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

                _context9.next = 53;
                return Promise.all(toApplyLocally.map(function (record) {
                  return _this8._decodeRecord("remote", record);
                }));

              case 53:
                decoded = _context9.sent;

                if (!(decoded.length > 0 || conflicts.length > 0)) {
                  _context9.next = 57;
                  break;
                }

                _context9.next = 57;
                return this._applyPushedResults(syncResultObject, decoded, conflicts, options.strategy);

              case 57:
                return _context9.abrupt("return", syncResultObject);

              case 58:
              case "end":
                return _context9.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 _this9 = this;

      return this.db.execute(function (transaction) {
        var updated = _this9._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 _this10 = this;

        var options,
            previousRemote,
            seconds,
            client,
            result,
            lastModified,
            toSync,
            resolvedUnsynced,
            resolvedEncoded,
            pullOpts,
            _args10 = arguments;
        return _regenerator.default.wrap(function _callee10$(_context10) {
          while (1) {
            switch (_context10.prev = _context10.next) {
              case 0:
                options = _args10.length > 0 && _args10[0] !== undefined ? _args10[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)) {
                  _context10.next = 7;
                  break;
                }

                seconds = Math.ceil(this.api.backoff / 1000);
                return _context10.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();
                _context10.prev = 9;
                _context10.next = 12;
                return this.pullMetadata(client, options);

              case 12:
                _context10.next = 14;
                return this.pullChanges(client, result, options);

              case 14:
                lastModified = result.lastModified; // Fetch local changes

                _context10.next = 17;
                return this.gatherLocalChanges();

              case 17:
                toSync = _context10.sent;
                _context10.next = 20;
                return this.pushChanges(client, toSync, result, options);

              case 20:
                // 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)) {
                  _context10.next = 27;
                  break;
                }

                _context10.next = 24;
                return Promise.all(resolvedUnsynced.map(function (resolution) {
                  var record = resolution.accepted;

                  if (record === null) {
                    record = {
                      id: resolution.id,
                      _status: resolution._status
                    };
                  }

                  return _this10._encodeRecord("remote", record);
                }));

              case 24:
                resolvedEncoded = _context10.sent;
                _context10.next = 27;
                return this.pushChanges(client, resolvedEncoded, result, options);

              case 27:
                if (!(result.published.length > 0)) {
                  _context10.next = 31;
                  break;
                }

                // Avoid redownloading our own changes during the last pull.
                pullOpts = (0, _objectSpread2.default)({}, options, {
                  lastModified: lastModified,
                  exclude: result.published
                });
                _context10.next = 31;
                return this.pullChanges(client, result, pullOpts);

              case 31:
                if (!result.ok) {
                  _context10.next = 35;
                  break;
                }

                _context10.next = 34;
                return this.db.saveLastModified(result.lastModified);

              case 34:
                this._lastModified = _context10.sent;

              case 35:
                _context10.next = 41;
                break;

              case 37:
                _context10.prev = 37;
                _context10.t0 = _context10["catch"](9);
                this.events.emit("sync:error", (0, _objectSpread2.default)({}, options, {
                  error: _context10.t0
                }));
                throw _context10.t0;

              case 41:
                _context10.prev = 41;
                // Ensure API default remote is reverted if a custom one's been used
                this.api.remote = previousRemote;
                return _context10.finish(41);

              case 44:
                this.events.emit("sync:success", (0, _objectSpread2.default)({}, options, {
                  result: result
                }));
                return _context10.abrupt("return", result);

              case 46:
              case "end":
                return _context10.stop();
            }
          }
        }, _callee10, this, [[9, 37, 41, 44]]);
      }));

      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$(_context11) {
          while (1) {
            switch (_context11.prev = _context11.next) {
              case 0:
                return _context11.abrupt("return", this.importBulk(records));

              case 1:
              case "end":
                return _context11.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$(_context12) {
          while (1) {
            switch (_context12.prev = _context12.next) {
              case 0:
                if (Array.isArray(records)) {
                  _context12.next = 2;
                  break;
                }

                throw new Error("Records is not an array.");

              case 2:
                _iteratorNormalCompletion3 = true;
                _didIteratorError3 = false;
                _iteratorError3 = undefined;
                _context12.prev = 5;
                _iterator3 = records[Symbol.iterator]();

              case 7:
                if (_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done) {
                  _context12.next = 16;
                  break;
                }

                record = _step3.value;

                if (!(!record.hasOwnProperty("id") || !this.idSchema.validate(record.id))) {
                  _context12.next = 11;
                  break;
                }

                throw new Error("Record has invalid ID: " + JSON.stringify(record));

              case 11:
                if (record.last_modified) {
                  _context12.next = 13;
                  break;
                }

                throw new Error("Record has no last_modified value: " + JSON.stringify(record));

              case 13:
                _iteratorNormalCompletion3 = true;
                _context12.next = 7;
                break;

              case 16:
                _context12.next = 22;
                break;

              case 18:
                _context12.prev = 18;
                _context12.t0 = _context12["catch"](5);
                _didIteratorError3 = true;
                _iteratorError3 = _context12.t0;

              case 22:
                _context12.prev = 22;
                _context12.prev = 23;

                if (!_iteratorNormalCompletion3 && _iterator3.return != null) {
                  _iterator3.return();
                }

              case 25:
                _context12.prev = 25;

                if (!_didIteratorError3) {
                  _context12.next = 28;
                  break;
                }

                throw _iteratorError3;

              case 28:
                return _context12.finish(25);

              case 29:
                return _context12.finish(22);

              case 30:
                _context12.next = 32;
                return this.list({}, {
                  includeDeleted: true
                });

              case 32:
                _ref7 = _context12.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;
                });
                _context12.next = 38;
                return this.db.importBulk(newRecords.map(markSynced));

              case 38:
                return _context12.abrupt("return", _context12.sent);

              case 39:
              case "end":
                return _context12.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,
            _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] : {};
                expectedTimestamp = options.expectedTimestamp, headers = options.headers;
                query = expectedTimestamp ? {
                  query: {
                    _expected: expectedTimestamp
                  }
                } : undefined;
                _context13.next = 5;
                return client.getData((0, _objectSpread2.default)({}, query, {
                  headers: headers
                }));

              case 5:
                metadata = _context13.sent;
                return _context13.abrupt("return", this.db.saveMetadata(metadata));

              case 7:
              case "end":
                return _context13.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$(_context14) {
          while (1) {
            switch (_context14.prev = _context14.next) {
              case 0:
                return _context14.abrupt("return", this.db.getMetadata());

              case 1:
              case "end":
                return _context14.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",
        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 _this11 = this;

      var existingRecords = [];
      ids.forEach(function (id) {
        existingRecords.push(_this11.adapterTransaction.get(id));

        _this11.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 (!record.hasOwnProperty("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 (!record.hasOwnProperty("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.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 (!record.hasOwnProperty("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 (!entry.hasOwnProperty(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 (acc.hasOwnProperty(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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QUcsQ0FBQyxjQUFKLENBQW1CLEVBQW5CLENBQUosRUFBNEI7QUFDakMsYUFBTyxHQUFHLENBQUMsRUFBRCxDQUFWO0FBQ0QsS0FGTSxNQUVBO0FBQ0wsYUFBUSxHQUFHLENBQUMsRUFBRCxDQUFILEdBQVUsRUFBbEI7QUFDRDtBQUNGLEdBUk0sRUFRSixnQkFSSSxDQUFQO0FBU0Q7O0FBRU0sU0FBUyx5QkFBVCxDQUFtQyxVQUFuQyxFQUErQztBQUNwRCxNQUFNLGtCQUFrQixHQUFHLEVBQTNCOztBQUNBLE9BQUssSUFBTSxHQUFYLElBQWtCLFVBQWxCLEVBQThCO0FBQzVCLFFBQU0sT0FBTyxHQUFHLEdBQUcsQ0FBQyxLQUFKLENBQVUsR0FBVixDQUFoQjtBQUNBLFFBQU0sR0FBRyxHQUFHLFVBQVUsQ0FBQyxHQUFELENBQXRCO0FBQ0EsSUFBQSx1QkFBdUIsQ0FBQyxPQUFELEVBQVUsR0FBVixFQUFlLGtCQUFmLENBQXZCO0FBQ0Q7O0FBQ0QsU0FBTyxrQkFBUDtBQUNEIiwiZmlsZSI6ImdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzQ29udGVudCI6WyIoZnVuY3Rpb24oKXtmdW5jdGlvbiByKGUsbix0KXtmdW5jdGlvbiBvKGksZil7aWYoIW5baV0pe2lmKCFlW2ldKXt2YXIgYz1cImZ1bmN0aW9uXCI9PXR5cGVvZiByZXF1aXJlJiZyZXF1aXJlO2lmKCFmJiZjKXJldHVybiBjKGksITApO2lmKHUpcmV0dXJuIHUoaSwhMCk7dmFyIGE9bmV3IEVycm9yKFwiQ2Fubm90IGZpbmQgbW9kdWxlICdcIitpK1wiJ1wiKTt0aHJvdyBhLmNvZGU9XCJNT0RVTEVfTk9UX0ZPVU5EXCIsYX12YXIgcD1uW2ldPXtleHBvcnRzOnt9fTtlW2ldWzBdLmNhbGwocC5leHBvcnRzLGZ1bmN0aW9uKHIpe3ZhciBuPWVbaV1bMV1bcl07cmV0dXJuIG8obnx8cil9LHAscC5leHBvcnRzLHIsZSxuLHQpfXJldHVybiBuW2ldLmV4cG9ydHN9Zm9yKHZhciB1PVwiZnVuY3Rpb25cIj09dHlwZW9mIHJlcXVpcmUmJnJlcXVpcmUsaT0wO2k8dC5sZW5ndGg7aSsrKW8odFtpXSk7cmV0dXJuIG99cmV0dXJuIHJ9KSgpIiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbnJlcXVpcmUoXCJjb3JlLWpzL2VzNlwiKTtcblxucmVxdWlyZShcImNvcmUtanMvZm4vYXJyYXkvaW5jbHVkZXNcIik7XG5cbnJlcXVpcmUoXCJjb3JlLWpzL2ZuL3N0cmluZy9wYWQtc3RhcnRcIik7XG5cbnJlcXVpcmUoXCJjb3JlLWpzL2ZuL3N0cmluZy9wYWQtZW5kXCIpO1xuXG5yZXF1aXJlKFwiY29yZS1qcy9mbi9zeW1ib2wvYXN5bmMtaXRlcmF0b3JcIik7XG5cbnJlcXVpcmUoXCJjb3JlLWpzL2ZuL29iamVjdC9nZXQtb3duLXByb3BlcnR5LWRlc2NyaXB0b3JzXCIpO1xuXG5yZXF1aXJlKFwiY29yZS1qcy9mbi9vYmplY3QvdmFsdWVzXCIpO1xuXG5yZXF1aXJlKFwiY29yZS1qcy9mbi9vYmplY3QvZW50cmllc1wiKTtcblxucmVxdWlyZShcImNvcmUtanMvZm4vcHJvbWlzZS9maW5hbGx5XCIpO1xuXG5yZXF1aXJlKFwiY29yZS1qcy93ZWJcIik7XG5cbnJlcXVpcmUoXCJyZWdlbmVyYXRvci1ydW50aW1lL3J1bnRpbWVcIik7XG5cbmlmIChnbG9iYWwuX2JhYmVsUG9seWZpbGwgJiYgdHlwZW9mIGNvbnNvbGUgIT09IFwidW5kZWZpbmVkXCIgJiYgY29uc29sZS53YXJuKSB7XG4gIGNvbnNvbGUud2FybihcIkBiYWJlbC9wb2x5ZmlsbCBpcyBsb2FkZWQgbW9yZSB0aGFuIG9uY2Ugb24gdGhpcyBwYWdlLiBUaGlzIGlzIHByb2JhYmx5IG5vdCBkZXNpcmFibGUvaW50ZW5kZWQgXCIgKyBcImFuZCBtYXkgaGF2ZSBjb25zZXF1ZW5jZXMgaWYgZGlmZmVyZW50IHZlcnNpb25zIG9mIHRoZSBwb2x5ZmlsbHMgYXJlIGFwcGxpZWQgc2VxdWVudGlhbGx5LiBcIiArIFwiSWYgeW91IGRvIG5lZWQgdG8gbG9hZCB0aGUgcG9seWZpbGwgbW9yZSB0aGFuIG9uY2UsIHVzZSBAYmFiZWwvcG9seWZpbGwvbm9Db25mbGljdCBcIiArIFwiaW5zdGVhZCB0byBieXBhc3MgdGhlIHdhcm5pbmcuXCIpO1xufVxuXG5nbG9iYWwuX2JhYmVsUG9seWZpbGwgPSB0cnVlOyIsInJlcXVpcmUoJy4uL21vZHVsZXMvZXM2LnN5bWJvbCcpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYub2JqZWN0LmNyZWF0ZScpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYub2JqZWN0LmRlZmluZS1wcm9wZXJ0eScpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYub2JqZWN0LmRlZmluZS1wcm9wZXJ0aWVzJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5vYmplY3QuZ2V0LW93bi1wcm9wZXJ0eS1kZXNjcmlwdG9yJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5vYmplY3QuZ2V0LXByb3RvdHlwZS1vZicpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYub2JqZWN0LmtleXMnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2Lm9iamVjdC5nZXQtb3duLXByb3BlcnR5LW5hbWVzJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5vYmplY3QuZnJlZXplJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5vYmplY3Quc2VhbCcpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYub2JqZWN0LnByZXZlbnQtZXh0ZW5zaW9ucycpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYub2JqZWN0LmlzLWZyb3plbicpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYub2JqZWN0LmlzLXNlYWxlZCcpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYub2JqZWN0LmlzLWV4dGVuc2libGUnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2Lm9iamVjdC5hc3NpZ24nKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2Lm9iamVjdC5pcycpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYub2JqZWN0LnNldC1wcm90b3R5cGUtb2YnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2Lm9iamVjdC50by1zdHJpbmcnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2LmZ1bmN0aW9uLmJpbmQnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2LmZ1bmN0aW9uLm5hbWUnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2LmZ1bmN0aW9uLmhhcy1pbnN0YW5jZScpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYucGFyc2UtaW50Jyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5wYXJzZS1mbG9hdCcpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYubnVtYmVyLmNvbnN0cnVjdG9yJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5udW1iZXIudG8tZml4ZWQnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2Lm51bWJlci50by1wcmVjaXNpb24nKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2Lm51bWJlci5lcHNpbG9uJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5udW1iZXIuaXMtZmluaXRlJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5udW1iZXIuaXMtaW50ZWdlcicpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYubnVtYmVyLmlzLW5hbicpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYubnVtYmVyLmlzLXNhZmUtaW50ZWdlcicpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYubnVtYmVyLm1heC1zYWZlLWludGVnZXInKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2Lm51bWJlci5taW4tc2FmZS1pbnRlZ2VyJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5udW1iZXIucGFyc2UtZmxvYXQnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2Lm51bWJlci5wYXJzZS1pbnQnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2Lm1hdGguYWNvc2gnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2Lm1hdGguYXNpbmgnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2Lm1hdGguYXRhbmgnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2Lm1hdGguY2JydCcpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYubWF0aC5jbHozMicpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYubWF0aC5jb3NoJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5tYXRoLmV4cG0xJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5tYXRoLmZyb3VuZCcpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYubWF0aC5oeXBvdCcpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYubWF0aC5pbXVsJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5tYXRoLmxvZzEwJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5tYXRoLmxvZzFwJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5tYXRoLmxvZzInKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2Lm1hdGguc2lnbicpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYubWF0aC5zaW5oJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5tYXRoLnRhbmgnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2Lm1hdGgudHJ1bmMnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2LnN0cmluZy5mcm9tLWNvZGUtcG9pbnQnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2LnN0cmluZy5yYXcnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2LnN0cmluZy50cmltJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5zdHJpbmcuaXRlcmF0b3InKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2LnN0cmluZy5jb2RlLXBvaW50LWF0Jyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5zdHJpbmcuZW5kcy13aXRoJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5zdHJpbmcuaW5jbHVkZXMnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2LnN0cmluZy5yZXBlYXQnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2LnN0cmluZy5zdGFydHMtd2l0aCcpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYuc3RyaW5nLmFuY2hvcicpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYuc3RyaW5nLmJpZycpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYuc3RyaW5nLmJsaW5rJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5zdHJpbmcuYm9sZCcpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYuc3RyaW5nLmZpeGVkJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5zdHJpbmcuZm9udGNvbG9yJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5zdHJpbmcuZm9udHNpemUnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2LnN0cmluZy5pdGFsaWNzJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5zdHJpbmcubGluaycpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYuc3RyaW5nLnNtYWxsJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5zdHJpbmcuc3RyaWtlJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5zdHJpbmcuc3ViJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5zdHJpbmcuc3VwJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5kYXRlLm5vdycpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYuZGF0ZS50by1qc29uJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5kYXRlLnRvLWlzby1zdHJpbmcnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2LmRhdGUudG8tc3RyaW5nJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5kYXRlLnRvLXByaW1pdGl2ZScpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYuYXJyYXkuaXMtYXJyYXknKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2LmFycmF5LmZyb20nKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2LmFycmF5Lm9mJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5hcnJheS5qb2luJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5hcnJheS5zbGljZScpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYuYXJyYXkuc29ydCcpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYuYXJyYXkuZm9yLWVhY2gnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2LmFycmF5Lm1hcCcpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYuYXJyYXkuZmlsdGVyJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5hcnJheS5zb21lJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5hcnJheS5ldmVyeScpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYuYXJyYXkucmVkdWNlJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5hcnJheS5yZWR1Y2UtcmlnaHQnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2LmFycmF5LmluZGV4LW9mJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5hcnJheS5sYXN0LWluZGV4LW9mJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5hcnJheS5jb3B5LXdpdGhpbicpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYuYXJyYXkuZmlsbCcpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYuYXJyYXkuZmluZCcpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYuYXJyYXkuZmluZC1pbmRleCcpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYuYXJyYXkuc3BlY2llcycpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYuYXJyYXkuaXRlcmF0b3InKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2LnJlZ2V4cC5jb25zdHJ1Y3RvcicpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYucmVnZXhwLnRvLXN0cmluZycpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYucmVnZXhwLmZsYWdzJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5yZWdleHAubWF0Y2gnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2LnJlZ2V4cC5yZXBsYWNlJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5yZWdleHAuc2VhcmNoJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5yZWdleHAuc3BsaXQnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2LnByb21pc2UnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2Lm1hcCcpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYuc2V0Jyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi53ZWFrLW1hcCcpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYud2Vhay1zZXQnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2LnR5cGVkLmFycmF5LWJ1ZmZlcicpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYudHlwZWQuZGF0YS12aWV3Jyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi50eXBlZC5pbnQ4LWFycmF5Jyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi50eXBlZC51aW50OC1hcnJheScpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYudHlwZWQudWludDgtY2xhbXBlZC1hcnJheScpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYudHlwZWQuaW50MTYtYXJyYXknKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2LnR5cGVkLnVpbnQxNi1hcnJheScpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYudHlwZWQuaW50MzItYXJyYXknKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2LnR5cGVkLnVpbnQzMi1hcnJheScpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYudHlwZWQuZmxvYXQzMi1hcnJheScpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYudHlwZWQuZmxvYXQ2NC1hcnJheScpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYucmVmbGVjdC5hcHBseScpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYucmVmbGVjdC5jb25zdHJ1Y3QnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2LnJlZmxlY3QuZGVmaW5lLXByb3BlcnR5Jyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5yZWZsZWN0LmRlbGV0ZS1wcm9wZXJ0eScpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYucmVmbGVjdC5lbnVtZXJhdGUnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2LnJlZmxlY3QuZ2V0Jyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5yZWZsZWN0LmdldC1vd24tcHJvcGVydHktZGVzY3JpcHRvcicpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYucmVmbGVjdC5nZXQtcHJvdG90eXBlLW9mJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5yZWZsZWN0LmhhcycpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYucmVmbGVjdC5pcy1leHRlbnNpYmxlJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5yZWZsZWN0Lm93bi1rZXlzJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5yZWZsZWN0LnByZXZlbnQtZXh0ZW5zaW9ucycpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYucmVmbGVjdC5zZXQnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2LnJlZmxlY3Quc2V0LXByb3RvdHlwZS1vZicpO1xubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuLi9tb2R1bGVzL19jb3JlJyk7XG4iLCJyZXF1aXJlKCcuLi8uLi9tb2R1bGVzL2VzNy5hcnJheS5pbmNsdWRlcycpO1xubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuLi8uLi9tb2R1bGVzL19jb3JlJykuQXJyYXkuaW5jbHVkZXM7XG4iLCJyZXF1aXJlKCcuLi8uLi9tb2R1bGVzL2VzNy5vYmplY3QuZW50cmllcycpO1xubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuLi8uLi9tb2R1bGVzL19jb3JlJykuT2JqZWN0LmVudHJpZXM7XG4iLCJyZXF1aXJlKCcuLi8uLi9tb2R1bGVzL2VzNy5vYmplY3QuZ2V0LW93bi1wcm9wZXJ0eS1kZXNjcmlwdG9ycycpO1xubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuLi8uLi9tb2R1bGVzL19jb3JlJykuT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcnM7XG4iLCJyZXF1aXJlKCcuLi8uLi9tb2R1bGVzL2VzNy5vYmplY3QudmFsdWVzJyk7XG5tb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4uLy4uL21vZHVsZXMvX2NvcmUnKS5PYmplY3QudmFsdWVzO1xuIiwiJ3VzZSBzdHJpY3QnO1xucmVxdWlyZSgnLi4vLi4vbW9kdWxlcy9lczYucHJvbWlzZScpO1xucmVxdWlyZSgnLi4vLi4vbW9kdWxlcy9lczcucHJvbWlzZS5maW5hbGx5Jyk7XG5tb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4uLy4uL21vZHVsZXMvX2NvcmUnKS5Qcm9taXNlWydmaW5hbGx5J107XG4iLCJyZXF1aXJlKCcuLi8uLi9tb2R1bGVzL2VzNy5zdHJpbmcucGFkLWVuZCcpO1xubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuLi8uLi9tb2R1bGVzL19jb3JlJykuU3RyaW5nLnBhZEVuZDtcbiIsInJlcXVpcmUoJy4uLy4uL21vZHVsZXMvZXM3LnN0cmluZy5wYWQtc3RhcnQnKTtcbm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi4vLi4vbW9kdWxlcy9fY29yZScpLlN0cmluZy5wYWRTdGFydDtcbiIsInJlcXVpcmUoJy4uLy4uL21vZHVsZXMvZXM3LnN5bWJvbC5hc3luYy1pdGVyYXRvcicpO1xubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuLi8uLi9tb2R1bGVzL193a3MtZXh0JykuZignYXN5bmNJdGVyYXRvcicpO1xuIiwibW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoaXQpIHtcbiAgaWYgKHR5cGVvZiBpdCAhPSAnZnVuY3Rpb24nKSB0aHJvdyBUeXBlRXJyb3IoaXQgKyAnIGlzIG5vdCBhIGZ1bmN0aW9uIScpO1xuICByZXR1cm4gaXQ7XG59O1xuIiwidmFyIGNvZiA9IHJlcXVpcmUoJy4vX2NvZicpO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoaXQsIG1zZykge1xuICBpZiAodHlwZW9mIGl0ICE9ICdudW1iZXInICYmIGNvZihpdCkgIT0gJ051bWJlcicpIHRocm93IFR5cGVFcnJvcihtc2cpO1xuICByZXR1cm4gK2l0O1xufTtcbiIsIi8vIDIyLjEuMy4zMSBBcnJheS5wcm90b3R5cGVbQEB1bnNjb3BhYmxlc11cbnZhciBVTlNDT1BBQkxFUyA9IHJlcXVpcmUoJy4vX3drcycpKCd1bnNjb3BhYmxlcycpO1xudmFyIEFycmF5UHJvdG8gPSBBcnJheS5wcm90b3R5cGU7XG5pZiAoQXJyYXlQcm90b1tVTlNDT1BBQkxFU10gPT0gdW5kZWZpbmVkKSByZXF1aXJlKCcuL19oaWRlJykoQXJyYXlQcm90bywgVU5TQ09QQUJMRVMsIHt9KTtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGtleSkge1xuICBBcnJheVByb3RvW1VOU0NPUEFCTEVTXVtrZXldID0gdHJ1ZTtcbn07XG4iLCJtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChpdCwgQ29uc3RydWN0b3IsIG5hbWUsIGZvcmJpZGRlbkZpZWxkKSB7XG4gIGlmICghKGl0IGluc3RhbmNlb2YgQ29uc3RydWN0b3IpIHx8IChmb3JiaWRkZW5GaWVsZCAhPT0gdW5kZWZpbmVkICYmIGZvcmJpZGRlbkZpZWxkIGluIGl0KSkge1xuICAgIHRocm93IFR5cGVFcnJvcihuYW1lICsgJzogaW5jb3JyZWN0IGludm9jYXRpb24hJyk7XG4gIH0gcmV0dXJuIGl0O1xufTtcbiIsInZhciBpc09iamVjdCA9IHJlcXVpcmUoJy4vX2lzLW9iamVjdCcpO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoaXQpIHtcbiAgaWYgKCFpc09iamVjdChpdCkpIHRocm93IFR5cGVFcnJvcihpdCArICcgaXMgbm90IGFuIG9iamVjdCEnKTtcbiAgcmV0dXJuIGl0O1xufTtcbiIsIi8vIDIyLjEuMy4zIEFycmF5LnByb3RvdHlwZS5jb3B5V2l0aGluKHRhcmdldCwgc3RhcnQsIGVuZCA9IHRoaXMubGVuZ3RoKVxuJ3VzZSBzdHJpY3QnO1xudmFyIHRvT2JqZWN0ID0gcmVxdWlyZSgnLi9fdG8tb2JqZWN0Jyk7XG52YXIgdG9BYnNvbHV0ZUluZGV4ID0gcmVxdWlyZSgnLi9fdG8tYWJzb2x1dGUtaW5kZXgnKTtcbnZhciB0b0xlbmd0aCA9IHJlcXVpcmUoJy4vX3RvLWxlbmd0aCcpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IFtdLmNvcHlXaXRoaW4gfHwgZnVuY3Rpb24gY29weVdpdGhpbih0YXJnZXQgLyogPSAwICovLCBzdGFydCAvKiA9IDAsIGVuZCA9IEBsZW5ndGggKi8pIHtcbiAgdmFyIE8gPSB0b09iamVjdCh0aGlzKTtcbiAgdmFyIGxlbiA9IHRvTGVuZ3RoKE8ubGVuZ3RoKTtcbiAgdmFyIHRvID0gdG9BYnNvbHV0ZUluZGV4KHRhcmdldCwgbGVuKTtcbiAgdmFyIGZyb20gPSB0b0Fic29sdXRlSW5kZXgoc3RhcnQsIGxlbik7XG4gIHZhciBlbmQgPSBhcmd1bWVudHMubGVuZ3RoID4gMiA/IGFyZ3VtZW50c1syXSA6IHVuZGVmaW5lZDtcbiAgdmFyIGNvdW50ID0gTWF0aC5taW4oKGVuZCA9PT0gdW5kZWZpbmVkID8gbGVuIDogdG9BYnNvbHV0ZUluZGV4KGVuZCwgbGVuKSkgLSBmcm9tLCBsZW4gLSB0byk7XG4gIHZhciBpbmMgPSAxO1xuICBpZiAoZnJvbSA8IHRvICYmIHRvIDwgZnJvbSArIGNvdW50KSB7XG4gICAgaW5jID0gLTE7XG4gICAgZnJvbSArPSBjb3VudCAtIDE7XG4gICAgdG8gKz0gY291bnQgLSAxO1xuICB9XG4gIHdoaWxlIChjb3VudC0tID4gMCkge1xuICAgIGlmIChmcm9tIGluIE8pIE9bdG9dID0gT1tmcm9tXTtcbiAgICBlbHNlIGRlbGV0ZSBPW3RvXTtcbiAgICB0byArPSBpbmM7XG4gICAgZnJvbSArPSBpbmM7XG4gIH0gcmV0dXJuIE87XG59O1xuIiwiLy8gMjIuMS4zLjYgQXJyYXkucHJvdG90eXBlLmZpbGwodmFsdWUsIHN0YXJ0ID0gMCwgZW5kID0gdGhpcy5sZW5ndGgpXG4ndXNlIHN0cmljdCc7XG52YXIgdG9PYmplY3QgPSByZXF1aXJlKCcuL190by1vYmplY3QnKTtcbnZhciB0b0Fic29sdXRlSW5kZXggPSByZXF1aXJlKCcuL190by1hYnNvbHV0ZS1pbmRleCcpO1xudmFyIHRvTGVuZ3RoID0gcmVxdWlyZSgnLi9fdG8tbGVuZ3RoJyk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGZpbGwodmFsdWUgLyogLCBzdGFydCA9IDAsIGVuZCA9IEBsZW5ndGggKi8pIHtcbiAgdmFyIE8gPSB0b09iamVjdCh0aGlzKTtcbiAgdmFyIGxlbmd0aCA9IHRvTGVuZ3RoKE8ubGVuZ3RoKTtcbiAgdmFyIGFMZW4gPSBhcmd1bWVudHMubGVuZ3RoO1xuICB2YXIgaW5kZXggPSB0b0Fic29sdXRlSW5kZXgoYUxlbiA+IDEgPyBhcmd1bWVudHNbMV0gOiB1bmRlZmluZWQsIGxlbmd0aCk7XG4gIHZhciBlbmQgPSBhTGVuID4gMiA/IGFyZ3VtZW50c1syXSA6IHVuZGVmaW5lZDtcbiAgdmFyIGVuZFBvcyA9IGVuZCA9PT0gdW5kZWZpbmVkID8gbGVuZ3RoIDogdG9BYnNvbHV0ZUluZGV4KGVuZCwgbGVuZ3RoKTtcbiAgd2hpbGUgKGVuZFBvcyA+IGluZGV4KSBPW2luZGV4KytdID0gdmFsdWU7XG4gIHJldHVybiBPO1xufTtcbiIsIi8vIGZhbHNlIC0+IEFycmF5I2luZGV4T2Zcbi8vIHRydWUgIC0+IEFycmF5I2luY2x1ZGVzXG52YXIgdG9JT2JqZWN0ID0gcmVxdWlyZSgnLi9fdG8taW9iamVjdCcpO1xudmFyIHRvTGVuZ3RoID0gcmVxdWlyZSgnLi9fdG8tbGVuZ3RoJyk7XG52YXIgdG9BYnNvbHV0ZUluZGV4ID0gcmVxdWlyZSgnLi9fdG8tYWJzb2x1dGUtaW5kZXgnKTtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKElTX0lOQ0xVREVTKSB7XG4gIHJldHVybiBmdW5jdGlvbiAoJHRoaXMsIGVsLCBmcm9tSW5kZXgpIHtcbiAgICB2YXIgTyA9IHRvSU9iamVjdCgkdGhpcyk7XG4gICAgdmFyIGxlbmd0aCA9IHRvTGVuZ3RoKE8ubGVuZ3RoKTtcbiAgICB2YXIgaW5kZXggPSB0b0Fic29sdXRlSW5kZXgoZnJvbUluZGV4LCBsZW5ndGgpO1xuICAgIHZhciB2YWx1ZTtcbiAgICAvLyBBcnJheSNpbmNsdWRlcyB1c2VzIFNhbWVWYWx1ZVplcm8gZXF1YWxpdHkgYWxnb3JpdGhtXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXNlbGYtY29tcGFyZVxuICAgIGlmIChJU19JTkNMVURFUyAmJiBlbCAhPSBlbCkgd2hpbGUgKGxlbmd0aCA+IGluZGV4KSB7XG4gICAgICB2YWx1ZSA9IE9baW5kZXgrK107XG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tc2VsZi1jb21wYXJlXG4gICAgICBpZiAodmFsdWUgIT0gdmFsdWUpIHJldHVybiB0cnVlO1xuICAgIC8vIEFycmF5I2luZGV4T2YgaWdub3JlcyBob2xlcywgQXJyYXkjaW5jbHVkZXMgLSBub3RcbiAgICB9IGVsc2UgZm9yICg7bGVuZ3RoID4gaW5kZXg7IGluZGV4KyspIGlmIChJU19JTkNMVURFUyB8fCBpbmRleCBpbiBPKSB7XG4gICAgICBpZiAoT1tpbmRleF0gPT09IGVsKSByZXR1cm4gSVNfSU5DTFVERVMgfHwgaW5kZXggfHwgMDtcbiAgICB9IHJldHVybiAhSVNfSU5DTFVERVMgJiYgLTE7XG4gIH07XG59O1xuIiwiLy8gMCAtPiBBcnJheSNmb3JFYWNoXG4vLyAxIC0+IEFycmF5I21hcFxuLy8gMiAtPiBBcnJheSNmaWx0ZXJcbi8vIDMgLT4gQXJyYXkjc29tZVxuLy8gNCAtPiBBcnJheSNldmVyeVxuLy8gNSAtPiBBcnJheSNmaW5kXG4vLyA2IC0+IEFycmF5I2ZpbmRJbmRleFxudmFyIGN0eCA9IHJlcXVpcmUoJy4vX2N0eCcpO1xudmFyIElPYmplY3QgPSByZXF1aXJlKCcuL19pb2JqZWN0Jyk7XG52YXIgdG9PYmplY3QgPSByZXF1aXJlKCcuL190by1vYmplY3QnKTtcbnZhciB0b0xlbmd0aCA9IHJlcXVpcmUoJy4vX3RvLWxlbmd0aCcpO1xudmFyIGFzYyA9IHJlcXVpcmUoJy4vX2FycmF5LXNwZWNpZXMtY3JlYXRlJyk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChUWVBFLCAkY3JlYXRlKSB7XG4gIHZhciBJU19NQVAgPSBUWVBFID09IDE7XG4gIHZhciBJU19GSUxURVIgPSBUWVBFID09IDI7XG4gIHZhciBJU19TT01FID0gVFlQRSA9PSAzO1xuICB2YXIgSVNfRVZFUlkgPSBUWVBFID09IDQ7XG4gIHZhciBJU19GSU5EX0lOREVYID0gVFlQRSA9PSA2O1xuICB2YXIgTk9fSE9MRVMgPSBUWVBFID09IDUgfHwgSVNfRklORF9JTkRFWDtcbiAgdmFyIGNyZWF0ZSA9ICRjcmVhdGUgfHwgYXNjO1xuICByZXR1cm4gZnVuY3Rpb24gKCR0aGlzLCBjYWxsYmFja2ZuLCB0aGF0KSB7XG4gICAgdmFyIE8gPSB0b09iamVjdCgkdGhpcyk7XG4gICAgdmFyIHNlbGYgPSBJT2JqZWN0KE8pO1xuICAgIHZhciBmID0gY3R4KGNhbGxiYWNrZm4sIHRoYXQsIDMpO1xuICAgIHZhciBsZW5ndGggPSB0b0xlbmd0aChzZWxmLmxlbmd0aCk7XG4gICAgdmFyIGluZGV4ID0gMDtcbiAgICB2YXIgcmVzdWx0ID0gSVNfTUFQID8gY3JlYXRlKCR0aGlzLCBsZW5ndGgpIDogSVNfRklMVEVSID8gY3JlYXRlKCR0aGlzLCAwKSA6IHVuZGVmaW5lZDtcbiAgICB2YXIgdmFsLCByZXM7XG4gICAgZm9yICg7bGVuZ3RoID4gaW5kZXg7IGluZGV4KyspIGlmIChOT19IT0xFUyB8fCBpbmRleCBpbiBzZWxmKSB7XG4gICAgICB2YWwgPSBzZWxmW2luZGV4XTtcbiAgICAgIHJlcyA9IGYodmFsLCBpbmRleCwgTyk7XG4gICAgICBpZiAoVFlQRSkge1xuICAgICAgICBpZiAoSVNfTUFQKSByZXN1bHRbaW5kZXhdID0gcmVzOyAgIC8vIG1hcFxuICAgICAgICBlbHNlIGlmIChyZXMpIHN3aXRjaCAoVFlQRSkge1xuICAgICAgICAgIGNhc2UgMzogcmV0dXJuIHRydWU7ICAgICAgICAgICAgIC8vIHNvbWVcbiAgICAgICAgICBjYXNlIDU6IHJldHVybiB2YWw7ICAgICAgICAgICAgICAvLyBmaW5kXG4gICAgICAgICAgY2FzZSA2OiByZXR1cm4gaW5kZXg7ICAgICAgICAgICAgLy8gZmluZEluZGV4XG4gICAgICAgICAgY2FzZSAyOiByZXN1bHQucHVzaCh2YWwpOyAgICAgICAgLy8gZmlsdGVyXG4gICAgICAgIH0gZWxzZSBpZiAoSVNfRVZFUlkpIHJldHVybiBmYWxzZTsgLy8gZXZlcnlcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIElTX0ZJTkRfSU5ERVggPyAtMSA6IElTX1NPTUUgfHwgSVNfRVZFUlkgPyBJU19FVkVSWSA6IHJlc3VsdDtcbiAgfTtcbn07XG4iLCJ2YXIgYUZ1bmN0aW9uID0gcmVxdWlyZSgnLi9fYS1mdW5jdGlvbicpO1xudmFyIHRvT2JqZWN0ID0gcmVxdWlyZSgnLi9fdG8tb2JqZWN0Jyk7XG52YXIgSU9iamVjdCA9IHJlcXVpcmUoJy4vX2lvYmplY3QnKTtcbnZhciB0b0xlbmd0aCA9IHJlcXVpcmUoJy4vX3RvLWxlbmd0aCcpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uICh0aGF0LCBjYWxsYmFja2ZuLCBhTGVuLCBtZW1vLCBpc1JpZ2h0KSB7XG4gIGFGdW5jdGlvbihjYWxsYmFja2ZuKTtcbiAgdmFyIE8gPSB0b09iamVjdCh0aGF0KTtcbiAgdmFyIHNlbGYgPSBJT2JqZWN0KE8pO1xuICB2YXIgbGVuZ3RoID0gdG9MZW5ndGgoTy5sZW5ndGgpO1xuICB2YXIgaW5kZXggPSBpc1JpZ2h0ID8gbGVuZ3RoIC0gMSA6IDA7XG4gIHZhciBpID0gaXNSaWdodCA/IC0xIDogMTtcbiAgaWYgKGFMZW4gPCAyKSBmb3IgKDs7KSB7XG4gICAgaWYgKGluZGV4IGluIHNlbGYpIHtcbiAgICAgIG1lbW8gPSBzZWxmW2luZGV4XTtcbiAgICAgIGluZGV4ICs9IGk7XG4gICAgICBicmVhaztcbiAgICB9XG4gICAgaW5kZXggKz0gaTtcbiAgICBpZiAoaXNSaWdodCA/IGluZGV4IDwgMCA6IGxlbmd0aCA8PSBpbmRleCkge1xuICAgICAgdGhyb3cgVHlwZUVycm9yKCdSZWR1Y2Ugb2YgZW1wdHkgYXJyYXkgd2l0aCBubyBpbml0aWFsIHZhbHVlJyk7XG4gICAgfVxuICB9XG4gIGZvciAoO2lzUmlnaHQgPyBpbmRleCA+PSAwIDogbGVuZ3RoID4gaW5kZXg7IGluZGV4ICs9IGkpIGlmIChpbmRleCBpbiBzZWxmKSB7XG4gICAgbWVtbyA9IGNhbGxiYWNrZm4obWVtbywgc2VsZltpbmRleF0sIGluZGV4LCBPKTtcbiAgfVxuICByZXR1cm4gbWVtbztcbn07XG4iLCJ2YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuL19pcy1vYmplY3QnKTtcbnZhciBpc0FycmF5ID0gcmVxdWlyZSgnLi9faXMtYXJyYXknKTtcbnZhciBTUEVDSUVTID0gcmVxdWlyZSgnLi9fd2tzJykoJ3NwZWNpZXMnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAob3JpZ2luYWwpIHtcbiAgdmFyIEM7XG4gIGlmIChpc0FycmF5KG9yaWdpbmFsKSkge1xuICAgIEMgPSBvcmlnaW5hbC5jb25zdHJ1Y3RvcjtcbiAgICAvLyBjcm9zcy1yZWFsbSBmYWxsYmFja1xuICAgIGlmICh0eXBlb2YgQyA9PSAnZnVuY3Rpb24nICYmIChDID09PSBBcnJheSB8fCBpc0FycmF5KEMucHJvdG90eXBlKSkpIEMgPSB1bmRlZmluZWQ7XG4gICAgaWYgKGlzT2JqZWN0KEMpKSB7XG4gICAgICBDID0gQ1tTUEVDSUVTXTtcbiAgICAgIGlmIChDID09PSBudWxsKSBDID0gdW5kZWZpbmVkO1xuICAgIH1cbiAgfSByZXR1cm4gQyA9PT0gdW5kZWZpbmVkID8gQXJyYXkgOiBDO1xufTtcbiIsIi8vIDkuNC4yLjMgQXJyYXlTcGVjaWVzQ3JlYXRlKG9yaWdpbmFsQXJyYXksIGxlbmd0aClcbnZhciBzcGVjaWVzQ29uc3RydWN0b3IgPSByZXF1aXJlKCcuL19hcnJheS1zcGVjaWVzLWNvbnN0cnVjdG9yJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKG9yaWdpbmFsLCBsZW5ndGgpIHtcbiAgcmV0dXJuIG5ldyAoc3BlY2llc0NvbnN0cnVjdG9yKG9yaWdpbmFsKSkobGVuZ3RoKTtcbn07XG4iLCIndXNlIHN0cmljdCc7XG52YXIgYUZ1bmN0aW9uID0gcmVxdWlyZSgnLi9fYS1mdW5jdGlvbicpO1xudmFyIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi9faXMtb2JqZWN0Jyk7XG52YXIgaW52b2tlID0gcmVxdWlyZSgnLi9faW52b2tlJyk7XG52YXIgYXJyYXlTbGljZSA9IFtdLnNsaWNlO1xudmFyIGZhY3RvcmllcyA9IHt9O1xuXG52YXIgY29uc3RydWN0ID0gZnVuY3Rpb24gKEYsIGxlbiwgYXJncykge1xuICBpZiAoIShsZW4gaW4gZmFjdG9yaWVzKSkge1xuICAgIGZvciAodmFyIG4gPSBbXSwgaSA9IDA7IGkgPCBsZW47IGkrKykgbltpXSA9ICdhWycgKyBpICsgJ10nO1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1uZXctZnVuY1xuICAgIGZhY3Rvcmllc1tsZW5dID0gRnVuY3Rpb24oJ0YsYScsICdyZXR1cm4gbmV3IEYoJyArIG4uam9pbignLCcpICsgJyknKTtcbiAgfSByZXR1cm4gZmFjdG9yaWVzW2xlbl0oRiwgYXJncyk7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IEZ1bmN0aW9uLmJpbmQgfHwgZnVuY3Rpb24gYmluZCh0aGF0IC8qICwgLi4uYXJncyAqLykge1xuICB2YXIgZm4gPSBhRnVuY3Rpb24odGhpcyk7XG4gIHZhciBwYXJ0QXJncyA9IGFycmF5U2xpY2UuY2FsbChhcmd1bWVudHMsIDEpO1xuICB2YXIgYm91bmQgPSBmdW5jdGlvbiAoLyogYXJncy4uLiAqLykge1xuICAgIHZhciBhcmdzID0gcGFydEFyZ3MuY29uY2F0KGFycmF5U2xpY2UuY2FsbChhcmd1bWVudHMpKTtcbiAgICByZXR1cm4gdGhpcyBpbnN0YW5jZW9mIGJvdW5kID8gY29uc3RydWN0KGZuLCBhcmdzLmxlbmd0aCwgYXJncykgOiBpbnZva2UoZm4sIGFyZ3MsIHRoYXQpO1xuICB9O1xuICBpZiAoaXNPYmplY3QoZm4ucHJvdG90eXBlKSkgYm91bmQucHJvdG90eXBlID0gZm4ucHJvdG90eXBlO1xuICByZXR1cm4gYm91bmQ7XG59O1xuIiwiLy8gZ2V0dGluZyB0YWcgZnJvbSAxOS4xLjMuNiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nKClcbnZhciBjb2YgPSByZXF1aXJlKCcuL19jb2YnKTtcbnZhciBUQUcgPSByZXF1aXJlKCcuL193a3MnKSgndG9TdHJpbmdUYWcnKTtcbi8vIEVTMyB3cm9uZyBoZXJlXG52YXIgQVJHID0gY29mKGZ1bmN0aW9uICgpIHsgcmV0dXJuIGFyZ3VtZW50czsgfSgpKSA9PSAnQXJndW1lbnRzJztcblxuLy8gZmFsbGJhY2sgZm9yIElFMTEgU2NyaXB0IEFjY2VzcyBEZW5pZWQgZXJyb3JcbnZhciB0cnlHZXQgPSBmdW5jdGlvbiAoaXQsIGtleSkge1xuICB0cnkge1xuICAgIHJldHVybiBpdFtrZXldO1xuICB9IGNhdGNoIChlKSB7IC8qIGVtcHR5ICovIH1cbn07XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGl0KSB7XG4gIHZhciBPLCBULCBCO1xuICByZXR1cm4gaXQgPT09IHVuZGVmaW5lZCA/ICdVbmRlZmluZWQnIDogaXQgPT09IG51bGwgPyAnTnVsbCdcbiAgICAvLyBAQHRvU3RyaW5nVGFnIGNhc2VcbiAgICA6IHR5cGVvZiAoVCA9IHRyeUdldChPID0gT2JqZWN0KGl0KSwgVEFHKSkgPT0gJ3N0cmluZycgPyBUXG4gICAgLy8gYnVpbHRpblRhZyBjYXNlXG4gICAgOiBBUkcgPyBjb2YoTylcbiAgICAvLyBFUzMgYXJndW1lbnRzIGZhbGxiYWNrXG4gICAgOiAoQiA9IGNvZihPKSkgPT0gJ09iamVjdCcgJiYgdHlwZW9mIE8uY2FsbGVlID09ICdmdW5jdGlvbicgPyAnQXJndW1lbnRzJyA6IEI7XG59O1xuIiwidmFyIHRvU3RyaW5nID0ge30udG9TdHJpbmc7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGl0KSB7XG4gIHJldHVybiB0b1N0cmluZy5jYWxsKGl0KS5zbGljZSg4LCAtMSk7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyIGRQID0gcmVxdWlyZSgnLi9fb2JqZWN0LWRwJykuZjtcbnZhciBjcmVhdGUgPSByZXF1aXJlKCcuL19vYmplY3QtY3JlYXRlJyk7XG52YXIgcmVkZWZpbmVBbGwgPSByZXF1aXJlKCcuL19yZWRlZmluZS1hbGwnKTtcbnZhciBjdHggPSByZXF1aXJlKCcuL19jdHgnKTtcbnZhciBhbkluc3RhbmNlID0gcmVxdWlyZSgnLi9fYW4taW5zdGFuY2UnKTtcbnZhciBmb3JPZiA9IHJlcXVpcmUoJy4vX2Zvci1vZicpO1xudmFyICRpdGVyRGVmaW5lID0gcmVxdWlyZSgnLi9faXRlci1kZWZpbmUnKTtcbnZhciBzdGVwID0gcmVxdWlyZSgnLi9faXRlci1zdGVwJyk7XG52YXIgc2V0U3BlY2llcyA9IHJlcXVpcmUoJy4vX3NldC1zcGVjaWVzJyk7XG52YXIgREVTQ1JJUFRPUlMgPSByZXF1aXJlKCcuL19kZXNjcmlwdG9ycycpO1xudmFyIGZhc3RLZXkgPSByZXF1aXJlKCcuL19tZXRhJykuZmFzdEtleTtcbnZhciB2YWxpZGF0ZSA9IHJlcXVpcmUoJy4vX3ZhbGlkYXRlLWNvbGxlY3Rpb24nKTtcbnZhciBTSVpFID0gREVTQ1JJUFRPUlMgPyAnX3MnIDogJ3NpemUnO1xuXG52YXIgZ2V0RW50cnkgPSBmdW5jdGlvbiAodGhhdCwga2V5KSB7XG4gIC8vIGZhc3QgY2FzZVxuICB2YXIgaW5kZXggPSBmYXN0S2V5KGtleSk7XG4gIHZhciBlbnRyeTtcbiAgaWYgKGluZGV4ICE9PSAnRicpIHJldHVybiB0aGF0Ll9pW2luZGV4XTtcbiAgLy8gZnJvemVuIG9iamVjdCBjYXNlXG4gIGZvciAoZW50cnkgPSB0aGF0Ll9mOyBlbnRyeTsgZW50cnkgPSBlbnRyeS5uKSB7XG4gICAgaWYgKGVudHJ5LmsgPT0ga2V5KSByZXR1cm4gZW50cnk7XG4gIH1cbn07XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBnZXRDb25zdHJ1Y3RvcjogZnVuY3Rpb24gKHdyYXBwZXIsIE5BTUUsIElTX01BUCwgQURERVIpIHtcbiAgICB2YXIgQyA9IHdyYXBwZXIoZnVuY3Rpb24gKHRoYXQsIGl0ZXJhYmxlKSB7XG4gICAgICBhbkluc3RhbmNlKHRoYXQsIEMsIE5BTUUsICdfaScpO1xuICAgICAgdGhhdC5fdCA9IE5BTUU7ICAgICAgICAgLy8gY29sbGVjdGlvbiB0eXBlXG4gICAgICB0aGF0Ll9pID0gY3JlYXRlKG51bGwpOyAvLyBpbmRleFxuICAgICAgdGhhdC5fZiA9IHVuZGVmaW5lZDsgICAgLy8gZmlyc3QgZW50cnlcbiAgICAgIHRoYXQuX2wgPSB1bmRlZmluZWQ7ICAgIC8vIGxhc3QgZW50cnlcbiAgICAgIHRoYXRbU0laRV0gPSAwOyAgICAgICAgIC8vIHNpemVcbiAgICAgIGlmIChpdGVyYWJsZSAhPSB1bmRlZmluZWQpIGZvck9mKGl0ZXJhYmxlLCBJU19NQVAsIHRoYXRbQURERVJdLCB0aGF0KTtcbiAgICB9KTtcbiAgICByZWRlZmluZUFsbChDLnByb3RvdHlwZSwge1xuICAgICAgLy8gMjMuMS4zLjEgTWFwLnByb3RvdHlwZS5jbGVhcigpXG4gICAgICAvLyAyMy4yLjMuMiBTZXQucHJvdG90eXBlLmNsZWFyKClcbiAgICAgIGNsZWFyOiBmdW5jdGlvbiBjbGVhcigpIHtcbiAgICAgICAgZm9yICh2YXIgdGhhdCA9IHZhbGlkYXRlKHRoaXMsIE5BTUUpLCBkYXRhID0gdGhhdC5faSwgZW50cnkgPSB0aGF0Ll9mOyBlbnRyeTsgZW50cnkgPSBlbnRyeS5uKSB7XG4gICAgICAgICAgZW50cnkuciA9IHRydWU7XG4gICAgICAgICAgaWYgKGVudHJ5LnApIGVudHJ5LnAgPSBlbnRyeS5wLm4gPSB1bmRlZmluZWQ7XG4gICAgICAgICAgZGVsZXRlIGRhdGFbZW50cnkuaV07XG4gICAgICAgIH1cbiAgICAgICAgdGhhdC5fZiA9IHRoYXQuX2wgPSB1bmRlZmluZWQ7XG4gICAgICAgIHRoYXRbU0laRV0gPSAwO1xuICAgICAgfSxcbiAgICAgIC8vIDIzLjEuMy4zIE1hcC5wcm90b3R5cGUuZGVsZXRlKGtleSlcbiAgICAgIC8vIDIzLjIuMy40IFNldC5wcm90b3R5cGUuZGVsZXRlKHZhbHVlKVxuICAgICAgJ2RlbGV0ZSc6IGZ1bmN0aW9uIChrZXkpIHtcbiAgICAgICAgdmFyIHRoYXQgPSB2YWxpZGF0ZSh0aGlzLCBOQU1FKTtcbiAgICAgICAgdmFyIGVudHJ5ID0gZ2V0RW50cnkodGhhdCwga2V5KTtcbiAgICAgICAgaWYgKGVudHJ5KSB7XG4gICAgICAgICAgdmFyIG5leHQgPSBlbnRyeS5uO1xuICAgICAgICAgIHZhciBwcmV2ID0gZW50cnkucDtcbiAgICAgICAgICBkZWxldGUgdGhhdC5faVtlbnRyeS5pXTtcbiAgICAgICAgICBlbnRyeS5yID0gdHJ1ZTtcbiAgICAgICAgICBpZiAocHJldikgcHJldi5uID0gbmV4dDtcbiAgICAgICAgICBpZiAobmV4dCkgbmV4dC5wID0gcHJldjtcbiAgICAgICAgICBpZiAodGhhdC5fZiA9PSBlbnRyeSkgdGhhdC5fZiA9IG5leHQ7XG4gICAgICAgICAgaWYgKHRoYXQuX2wgPT0gZW50cnkpIHRoYXQuX2wgPSBwcmV2O1xuICAgICAgICAgIHRoYXRbU0laRV0tLTtcbiAgICAgICAgfSByZXR1cm4gISFlbnRyeTtcbiAgICAgIH0sXG4gICAgICAvLyAyMy4yLjMuNiBTZXQucHJvdG90eXBlLmZvckVhY2goY2FsbGJhY2tmbiwgdGhpc0FyZyA9IHVuZGVmaW5lZClcbiAgICAgIC8vIDIzLjEuMy41IE1hcC5wcm90b3R5cGUuZm9yRWFjaChjYWxsYmFja2ZuLCB0aGlzQXJnID0gdW5kZWZpbmVkKVxuICAgICAgZm9yRWFjaDogZnVuY3Rpb24gZm9yRWFjaChjYWxsYmFja2ZuIC8qICwgdGhhdCA9IHVuZGVmaW5lZCAqLykge1xuICAgICAgICB2YWxpZGF0ZSh0aGlzLCBOQU1FKTtcbiAgICAgICAgdmFyIGYgPSBjdHgoY2FsbGJhY2tmbiwgYXJndW1lbnRzLmxlbmd0aCA+IDEgPyBhcmd1bWVudHNbMV0gOiB1bmRlZmluZWQsIDMpO1xuICAgICAgICB2YXIgZW50cnk7XG4gICAgICAgIHdoaWxlIChlbnRyeSA9IGVudHJ5ID8gZW50cnkubiA6IHRoaXMuX2YpIHtcbiAgICAgICAgICBmKGVudHJ5LnYsIGVudHJ5LmssIHRoaXMpO1xuICAgICAgICAgIC8vIHJldmVydCB0byB0aGUgbGFzdCBleGlzdGluZyBlbnRyeVxuICAgICAgICAgIHdoaWxlIChlbnRyeSAmJiBlbnRyeS5yKSBlbnRyeSA9IGVudHJ5LnA7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICAvLyAyMy4xLjMuNyBNYXAucHJvdG90eXBlLmhhcyhrZXkpXG4gICAgICAvLyAyMy4yLjMuNyBTZXQucHJvdG90eXBlLmhhcyh2YWx1ZSlcbiAgICAgIGhhczogZnVuY3Rpb24gaGFzKGtleSkge1xuICAgICAgICByZXR1cm4gISFnZXRFbnRyeSh2YWxpZGF0ZSh0aGlzLCBOQU1FKSwga2V5KTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICBpZiAoREVTQ1JJUFRPUlMpIGRQKEMucHJvdG90eXBlLCAnc2l6ZScsIHtcbiAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdmFsaWRhdGUodGhpcywgTkFNRSlbU0laRV07XG4gICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIEM7XG4gIH0sXG4gIGRlZjogZnVuY3Rpb24gKHRoYXQsIGtleSwgdmFsdWUpIHtcbiAgICB2YXIgZW50cnkgPSBnZXRFbnRyeSh0aGF0LCBrZXkpO1xuICAgIHZhciBwcmV2LCBpbmRleDtcbiAgICAvLyBjaGFuZ2UgZXhpc3RpbmcgZW50cnlcbiAgICBpZiAoZW50cnkpIHtcbiAgICAgIGVudHJ5LnYgPSB2YWx1ZTtcbiAgICAvLyBjcmVhdGUgbmV3IGVudHJ5XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoYXQuX2wgPSBlbnRyeSA9IHtcbiAgICAgICAgaTogaW5kZXggPSBmYXN0S2V5KGtleSwgdHJ1ZSksIC8vIDwtIGluZGV4XG4gICAgICAgIGs6IGtleSwgICAgICAgICAgICAgICAgICAgICAgICAvLyA8LSBrZXlcbiAgICAgICAgdjogdmFsdWUsICAgICAgICAgICAgICAgICAgICAgIC8vIDwtIHZhbHVlXG4gICAgICAgIHA6IHByZXYgPSB0aGF0Ll9sLCAgICAgICAgICAgICAvLyA8LSBwcmV2aW91cyBlbnRyeVxuICAgICAgICBuOiB1bmRlZmluZWQsICAgICAgICAgICAgICAgICAgLy8gPC0gbmV4dCBlbnRyeVxuICAgICAgICByOiBmYWxzZSAgICAgICAgICAgICAgICAgICAgICAgLy8gPC0gcmVtb3ZlZFxuICAgICAgfTtcbiAgICAgIGlmICghdGhhdC5fZikgdGhhdC5fZiA9IGVudHJ5O1xuICAgICAgaWYgKHByZXYpIHByZXYubiA9IGVudHJ5O1xuICAgICAgdGhhdFtTSVpFXSsrO1xuICAgICAgLy8gYWRkIHRvIGluZGV4XG4gICAgICBpZiAoaW5kZXggIT09ICdGJykgdGhhdC5faVtpbmRleF0gPSBlbnRyeTtcbiAgICB9IHJldHVybiB0aGF0O1xuICB9LFxuICBnZXRFbnRyeTogZ2V0RW50cnksXG4gIHNldFN0cm9uZzogZnVuY3Rpb24gKEMsIE5BTUUsIElTX01BUCkge1xuICAgIC8vIGFkZCAua2V5cywgLnZhbHVlcywgLmVudHJpZXMsIFtAQGl0ZXJhdG9yXVxuICAgIC8vIDIzLjEuMy40LCAyMy4xLjMuOCwgMjMuMS4zLjExLCAyMy4xLjMuMTIsIDIzLjIuMy41LCAyMy4yLjMuOCwgMjMuMi4zLjEwLCAyMy4yLjMuMTFcbiAgICAkaXRlckRlZmluZShDLCBOQU1FLCBmdW5jdGlvbiAoaXRlcmF0ZWQsIGtpbmQpIHtcbiAgICAgIHRoaXMuX3QgPSB2YWxpZGF0ZShpdGVyYXRlZCwgTkFNRSk7IC8vIHRhcmdldFxuICAgICAgdGhpcy5fayA9IGtpbmQ7ICAgICAgICAgICAgICAgICAgICAgLy8ga2luZFxuICAgICAgdGhpcy5fbCA9IHVuZGVmaW5lZDsgICAgICAgICAgICAgICAgLy8gcHJldmlvdXNcbiAgICB9LCBmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgdGhhdCA9IHRoaXM7XG4gICAgICB2YXIga2luZCA9IHRoYXQuX2s7XG4gICAgICB2YXIgZW50cnkgPSB0aGF0Ll9sO1xuICAgICAgLy8gcmV2ZXJ0IHRvIHRoZSBsYXN0IGV4aXN0aW5nIGVudHJ5XG4gICAgICB3aGlsZSAoZW50cnkgJiYgZW50cnkucikgZW50cnkgPSBlbnRyeS5wO1xuICAgICAgLy8gZ2V0IG5leHQgZW50cnlcbiAgICAgIGlmICghdGhhdC5fdCB8fCAhKHRoYXQuX2wgPSBlbnRyeSA9IGVudHJ5ID8gZW50cnkubiA6IHRoYXQuX3QuX2YpKSB7XG4gICAgICAgIC8vIG9yIGZpbmlzaCB0aGUgaXRlcmF0aW9uXG4gICAgICAgIHRoYXQuX3QgPSB1bmRlZmluZWQ7XG4gICAgICAgIHJldHVybiBzdGVwKDEpO1xuICAgICAgfVxuICAgICAgLy8gcmV0dXJuIHN0ZXAgYnkga2luZFxuICAgICAgaWYgKGtpbmQgPT0gJ2tleXMnKSByZXR1cm4gc3RlcCgwLCBlbnRyeS5rKTtcbiAgICAgIGlmIChraW5kID09ICd2YWx1ZXMnKSByZXR1cm4gc3RlcCgwLCBlbnRyeS52KTtcbiAgICAgIHJldHVybiBzdGVwKDAsIFtlbnRyeS5rLCBlbnRyeS52XSk7XG4gICAgfSwgSVNfTUFQID8gJ2VudHJpZXMnIDogJ3ZhbHVlcycsICFJU19NQVAsIHRydWUpO1xuXG4gICAgLy8gYWRkIFtAQHNwZWNpZXNdLCAyMy4xLjIuMiwgMjMuMi4yLjJcbiAgICBzZXRTcGVjaWVzKE5BTUUpO1xuICB9XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyIHJlZGVmaW5lQWxsID0gcmVxdWlyZSgnLi9fcmVkZWZpbmUtYWxsJyk7XG52YXIgZ2V0V2VhayA9IHJlcXVpcmUoJy4vX21ldGEnKS5nZXRXZWFrO1xudmFyIGFuT2JqZWN0ID0gcmVxdWlyZSgnLi9fYW4tb2JqZWN0Jyk7XG52YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuL19pcy1vYmplY3QnKTtcbnZhciBhbkluc3RhbmNlID0gcmVxdWlyZSgnLi9fYW4taW5zdGFuY2UnKTtcbnZhciBmb3JPZiA9IHJlcXVpcmUoJy4vX2Zvci1vZicpO1xudmFyIGNyZWF0ZUFycmF5TWV0aG9kID0gcmVxdWlyZSgnLi9fYXJyYXktbWV0aG9kcycpO1xudmFyICRoYXMgPSByZXF1aXJlKCcuL19oYXMnKTtcbnZhciB2YWxpZGF0ZSA9IHJlcXVpcmUoJy4vX3ZhbGlkYXRlLWNvbGxlY3Rpb24nKTtcbnZhciBhcnJheUZpbmQgPSBjcmVhdGVBcnJheU1ldGhvZCg1KTtcbnZhciBhcnJheUZpbmRJbmRleCA9IGNyZWF0ZUFycmF5TWV0aG9kKDYpO1xudmFyIGlkID0gMDtcblxuLy8gZmFsbGJhY2sgZm9yIHVuY2F1Z2h0IGZyb3plbiBrZXlzXG52YXIgdW5jYXVnaHRGcm96ZW5TdG9yZSA9IGZ1bmN0aW9uICh0aGF0KSB7XG4gIHJldHVybiB0aGF0Ll9sIHx8ICh0aGF0Ll9sID0gbmV3IFVuY2F1Z2h0RnJvemVuU3RvcmUoKSk7XG59O1xudmFyIFVuY2F1Z2h0RnJvemVuU3RvcmUgPSBmdW5jdGlvbiAoKSB7XG4gIHRoaXMuYSA9IFtdO1xufTtcbnZhciBmaW5kVW5jYXVnaHRGcm96ZW4gPSBmdW5jdGlvbiAoc3RvcmUsIGtleSkge1xuICByZXR1cm4gYXJyYXlGaW5kKHN0b3JlLmEsIGZ1bmN0aW9uIChpdCkge1xuICAgIHJldHVybiBpdFswXSA9PT0ga2V5O1xuICB9KTtcbn07XG5VbmNhdWdodEZyb3plblN0b3JlLnByb3RvdHlwZSA9IHtcbiAgZ2V0OiBmdW5jdGlvbiAoa2V5KSB7XG4gICAgdmFyIGVudHJ5ID0gZmluZFVuY2F1Z2h0RnJvemVuKHRoaXMsIGtleSk7XG4gICAgaWYgKGVudHJ5KSByZXR1cm4gZW50cnlbMV07XG4gIH0sXG4gIGhhczogZnVuY3Rpb24gKGtleSkge1xuICAgIHJldHVybiAhIWZpbmRVbmNhdWdodEZyb3plbih0aGlzLCBrZXkpO1xuICB9LFxuICBzZXQ6IGZ1bmN0aW9uIChrZXksIHZhbHVlKSB7XG4gICAgdmFyIGVudHJ5ID0gZmluZFVuY2F1Z2h0RnJvemVuKHRoaXMsIGtleSk7XG4gICAgaWYgKGVudHJ5KSBlbnRyeVsxXSA9IHZhbHVlO1xuICAgIGVsc2UgdGhpcy5hLnB1c2goW2tleSwgdmFsdWVdKTtcbiAgfSxcbiAgJ2RlbGV0ZSc6IGZ1bmN0aW9uIChrZXkpIHtcbiAgICB2YXIgaW5kZXggPSBhcnJheUZpbmRJbmRleCh0aGlzLmEsIGZ1bmN0aW9uIChpdCkge1xuICAgICAgcmV0dXJuIGl0WzBdID09PSBrZXk7XG4gICAgfSk7XG4gICAgaWYgKH5pbmRleCkgdGhpcy5hLnNwbGljZShpbmRleCwgMSk7XG4gICAgcmV0dXJuICEhfmluZGV4O1xuICB9XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgZ2V0Q29uc3RydWN0b3I6IGZ1bmN0aW9uICh3cmFwcGVyLCBOQU1FLCBJU19NQVAsIEFEREVSKSB7XG4gICAgdmFyIEMgPSB3cmFwcGVyKGZ1bmN0aW9uICh0aGF0LCBpdGVyYWJsZSkge1xuICAgICAgYW5JbnN0YW5jZSh0aGF0LCBDLCBOQU1FLCAnX2knKTtcbiAgICAgIHRoYXQuX3QgPSBOQU1FOyAgICAgIC8vIGNvbGxlY3Rpb24gdHlwZVxuICAgICAgdGhhdC5faSA9IGlkKys7ICAgICAgLy8gY29sbGVjdGlvbiBpZFxuICAgICAgdGhhdC5fbCA9IHVuZGVmaW5lZDsgLy8gbGVhayBzdG9yZSBmb3IgdW5jYXVnaHQgZnJvemVuIG9iamVjdHNcbiAgICAgIGlmIChpdGVyYWJsZSAhPSB1bmRlZmluZWQpIGZvck9mKGl0ZXJhYmxlLCBJU19NQVAsIHRoYXRbQURERVJdLCB0aGF0KTtcbiAgICB9KTtcbiAgICByZWRlZmluZUFsbChDLnByb3RvdHlwZSwge1xuICAgICAgLy8gMjMuMy4zLjIgV2Vha01hcC5wcm90b3R5cGUuZGVsZXRlKGtleSlcbiAgICAgIC8vIDIzLjQuMy4zIFdlYWtTZXQucHJvdG90eXBlLmRlbGV0ZSh2YWx1ZSlcbiAgICAgICdkZWxldGUnOiBmdW5jdGlvbiAoa2V5KSB7XG4gICAgICAgIGlmICghaXNPYmplY3Qoa2V5KSkgcmV0dXJuIGZhbHNlO1xuICAgICAgICB2YXIgZGF0YSA9IGdldFdlYWsoa2V5KTtcbiAgICAgICAgaWYgKGRhdGEgPT09IHRydWUpIHJldHVybiB1bmNhdWdodEZyb3plblN0b3JlKHZhbGlkYXRlKHRoaXMsIE5BTUUpKVsnZGVsZXRlJ10oa2V5KTtcbiAgICAgICAgcmV0dXJuIGRhdGEgJiYgJGhhcyhkYXRhLCB0aGlzLl9pKSAmJiBkZWxldGUgZGF0YVt0aGlzLl9pXTtcbiAgICAgIH0sXG4gICAgICAvLyAyMy4zLjMuNCBXZWFrTWFwLnByb3RvdHlwZS5oYXMoa2V5KVxuICAgICAgLy8gMjMuNC4zLjQgV2Vha1NldC5wcm90b3R5cGUuaGFzKHZhbHVlKVxuICAgICAgaGFzOiBmdW5jdGlvbiBoYXMoa2V5KSB7XG4gICAgICAgIGlmICghaXNPYmplY3Qoa2V5KSkgcmV0dXJuIGZhbHNlO1xuICAgICAgICB2YXIgZGF0YSA9IGdldFdlYWsoa2V5KTtcbiAgICAgICAgaWYgKGRhdGEgPT09IHRydWUpIHJldHVybiB1bmNhdWdodEZyb3plblN0b3JlKHZhbGlkYXRlKHRoaXMsIE5BTUUpKS5oYXMoa2V5KTtcbiAgICAgICAgcmV0dXJuIGRhdGEgJiYgJGhhcyhkYXRhLCB0aGlzLl9pKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gQztcbiAgfSxcbiAgZGVmOiBmdW5jdGlvbiAodGhhdCwga2V5LCB2YWx1ZSkge1xuICAgIHZhciBkYXRhID0gZ2V0V2Vhayhhbk9iamVjdChrZXkpLCB0cnVlKTtcbiAgICBpZiAoZGF0YSA9PT0gdHJ1ZSkgdW5jYXVnaHRGcm96ZW5TdG9yZSh0aGF0KS5zZXQoa2V5LCB2YWx1ZSk7XG4gICAgZWxzZSBkYXRhW3RoYXQuX2ldID0gdmFsdWU7XG4gICAgcmV0dXJuIHRoYXQ7XG4gIH0sXG4gIHVmc3RvcmU6IHVuY2F1Z2h0RnJvemVuU3RvcmVcbn07XG4iLCIndXNlIHN0cmljdCc7XG52YXIgZ2xvYmFsID0gcmVxdWlyZSgnLi9fZ2xvYmFsJyk7XG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyIHJlZGVmaW5lID0gcmVxdWlyZSgnLi9fcmVkZWZpbmUnKTtcbnZhciByZWRlZmluZUFsbCA9IHJlcXVpcmUoJy4vX3JlZGVmaW5lLWFsbCcpO1xudmFyIG1ldGEgPSByZXF1aXJlKCcuL19tZXRhJyk7XG52YXIgZm9yT2YgPSByZXF1aXJlKCcuL19mb3Itb2YnKTtcbnZhciBhbkluc3RhbmNlID0gcmVxdWlyZSgnLi9fYW4taW5zdGFuY2UnKTtcbnZhciBpc09iamVjdCA9IHJlcXVpcmUoJy4vX2lzLW9iamVjdCcpO1xudmFyIGZhaWxzID0gcmVxdWlyZSgnLi9fZmFpbHMnKTtcbnZhciAkaXRlckRldGVjdCA9IHJlcXVpcmUoJy4vX2l0ZXItZGV0ZWN0Jyk7XG52YXIgc2V0VG9TdHJpbmdUYWcgPSByZXF1aXJlKCcuL19zZXQtdG8tc3RyaW5nLXRhZycpO1xudmFyIGluaGVyaXRJZlJlcXVpcmVkID0gcmVxdWlyZSgnLi9faW5oZXJpdC1pZi1yZXF1aXJlZCcpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChOQU1FLCB3cmFwcGVyLCBtZXRob2RzLCBjb21tb24sIElTX01BUCwgSVNfV0VBSykge1xuICB2YXIgQmFzZSA9IGdsb2JhbFtOQU1FXTtcbiAgdmFyIEMgPSBCYXNlO1xuICB2YXIgQURERVIgPSBJU19NQVAgPyAnc2V0JyA6ICdhZGQnO1xuICB2YXIgcHJvdG8gPSBDICYmIEMucHJvdG90eXBlO1xuICB2YXIgTyA9IHt9O1xuICB2YXIgZml4TWV0aG9kID0gZnVuY3Rpb24gKEtFWSkge1xuICAgIHZhciBmbiA9IHByb3RvW0tFWV07XG4gICAgcmVkZWZpbmUocHJvdG8sIEtFWSxcbiAgICAgIEtFWSA9PSAnZGVsZXRlJyA/IGZ1bmN0aW9uIChhKSB7XG4gICAgICAgIHJldHVybiBJU19XRUFLICYmICFpc09iamVjdChhKSA/IGZhbHNlIDogZm4uY2FsbCh0aGlzLCBhID09PSAwID8gMCA6IGEpO1xuICAgICAgfSA6IEtFWSA9PSAnaGFzJyA/IGZ1bmN0aW9uIGhhcyhhKSB7XG4gICAgICAgIHJldHVybiBJU19XRUFLICYmICFpc09iamVjdChhKSA/IGZhbHNlIDogZm4uY2FsbCh0aGlzLCBhID09PSAwID8gMCA6IGEpO1xuICAgICAgfSA6IEtFWSA9PSAnZ2V0JyA/IGZ1bmN0aW9uIGdldChhKSB7XG4gICAgICAgIHJldHVybiBJU19XRUFLICYmICFpc09iamVjdChhKSA/IHVuZGVmaW5lZCA6IGZuLmNhbGwodGhpcywgYSA9PT0gMCA/IDAgOiBhKTtcbiAgICAgIH0gOiBLRVkgPT0gJ2FkZCcgPyBmdW5jdGlvbiBhZGQoYSkgeyBmbi5jYWxsKHRoaXMsIGEgPT09IDAgPyAwIDogYSk7IHJldHVybiB0aGlzOyB9XG4gICAgICAgIDogZnVuY3Rpb24gc2V0KGEsIGIpIHsgZm4uY2FsbCh0aGlzLCBhID09PSAwID8gMCA6IGEsIGIpOyByZXR1cm4gdGhpczsgfVxuICAgICk7XG4gIH07XG4gIGlmICh0eXBlb2YgQyAhPSAnZnVuY3Rpb24nIHx8ICEoSVNfV0VBSyB8fCBwcm90by5mb3JFYWNoICYmICFmYWlscyhmdW5jdGlvbiAoKSB7XG4gICAgbmV3IEMoKS5lbnRyaWVzKCkubmV4dCgpO1xuICB9KSkpIHtcbiAgICAvLyBjcmVhdGUgY29sbGVjdGlvbiBjb25zdHJ1Y3RvclxuICAgIEMgPSBjb21tb24uZ2V0Q29uc3RydWN0b3Iod3JhcHBlciwgTkFNRSwgSVNfTUFQLCBBRERFUik7XG4gICAgcmVkZWZpbmVBbGwoQy5wcm90b3R5cGUsIG1ldGhvZHMpO1xuICAgIG1ldGEuTkVFRCA9IHRydWU7XG4gIH0gZWxzZSB7XG4gICAgdmFyIGluc3RhbmNlID0gbmV3IEMoKTtcbiAgICAvLyBlYXJseSBpbXBsZW1lbnRhdGlvbnMgbm90IHN1cHBvcnRzIGNoYWluaW5nXG4gICAgdmFyIEhBU05UX0NIQUlOSU5HID0gaW5zdGFuY2VbQURERVJdKElTX1dFQUsgPyB7fSA6IC0wLCAxKSAhPSBpbnN0YW5jZTtcbiAgICAvLyBWOCB+ICBDaHJvbWl1bSA0MC0gd2Vhay1jb2xsZWN0aW9ucyB0aHJvd3Mgb24gcHJpbWl0aXZlcywgYnV0IHNob3VsZCByZXR1cm4gZmFsc2VcbiAgICB2YXIgVEhST1dTX09OX1BSSU1JVElWRVMgPSBmYWlscyhmdW5jdGlvbiAoKSB7IGluc3RhbmNlLmhhcygxKTsgfSk7XG4gICAgLy8gbW9zdCBlYXJseSBpbXBsZW1lbnRhdGlvbnMgZG9lc24ndCBzdXBwb3J0cyBpdGVyYWJsZXMsIG1vc3QgbW9kZXJuIC0gbm90IGNsb3NlIGl0IGNvcnJlY3RseVxuICAgIHZhciBBQ0NFUFRfSVRFUkFCTEVTID0gJGl0ZXJEZXRlY3QoZnVuY3Rpb24gKGl0ZXIpIHsgbmV3IEMoaXRlcik7IH0pOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLW5ld1xuICAgIC8vIGZvciBlYXJseSBpbXBsZW1lbnRhdGlvbnMgLTAgYW5kICswIG5vdCB0aGUgc2FtZVxuICAgIHZhciBCVUdHWV9aRVJPID0gIUlTX1dFQUsgJiYgZmFpbHMoZnVuY3Rpb24gKCkge1xuICAgICAgLy8gVjggfiBDaHJvbWl1bSA0Mi0gZmFpbHMgb25seSB3aXRoIDUrIGVsZW1lbnRzXG4gICAgICB2YXIgJGluc3RhbmNlID0gbmV3IEMoKTtcbiAgICAgIHZhciBpbmRleCA9IDU7XG4gICAgICB3aGlsZSAoaW5kZXgtLSkgJGluc3RhbmNlW0FEREVSXShpbmRleCwgaW5kZXgpO1xuICAgICAgcmV0dXJuICEkaW5zdGFuY2UuaGFzKC0wKTtcbiAgICB9KTtcbiAgICBpZiAoIUFDQ0VQVF9JVEVSQUJMRVMpIHtcbiAgICAgIEMgPSB3cmFwcGVyKGZ1bmN0aW9uICh0YXJnZXQsIGl0ZXJhYmxlKSB7XG4gICAgICAgIGFuSW5zdGFuY2UodGFyZ2V0LCBDLCBOQU1FKTtcbiAgICAgICAgdmFyIHRoYXQgPSBpbmhlcml0SWZSZXF1aXJlZChuZXcgQmFzZSgpLCB0YXJnZXQsIEMpO1xuICAgICAgICBpZiAoaXRlcmFibGUgIT0gdW5kZWZpbmVkKSBmb3JPZihpdGVyYWJsZSwgSVNfTUFQLCB0aGF0W0FEREVSXSwgdGhhdCk7XG4gICAgICAgIHJldHVybiB0aGF0O1xuICAgICAgfSk7XG4gICAgICBDLnByb3RvdHlwZSA9IHByb3RvO1xuICAgICAgcHJvdG8uY29uc3RydWN0b3IgPSBDO1xuICAgIH1cbiAgICBpZiAoVEhST1dTX09OX1BSSU1JVElWRVMgfHwgQlVHR1lfWkVSTykge1xuICAgICAgZml4TWV0aG9kKCdkZWxldGUnKTtcbiAgICAgIGZpeE1ldGhvZCgnaGFzJyk7XG4gICAgICBJU19NQVAgJiYgZml4TWV0aG9kKCdnZXQnKTtcbiAgICB9XG4gICAgaWYgKEJVR0dZX1pFUk8gfHwgSEFTTlRfQ0hBSU5JTkcpIGZpeE1ldGhvZChBRERFUik7XG4gICAgLy8gd2VhayBjb2xsZWN0aW9ucyBzaG91bGQgbm90IGNvbnRhaW5zIC5jbGVhciBtZXRob2RcbiAgICBpZiAoSVNfV0VBSyAmJiBwcm90by5jbGVhcikgZGVsZXRlIHByb3RvLmNsZWFyO1xuICB9XG5cbiAgc2V0VG9TdHJpbmdUYWcoQywgTkFNRSk7XG5cbiAgT1tOQU1FXSA9IEM7XG4gICRleHBvcnQoJGV4cG9ydC5HICsgJGV4cG9ydC5XICsgJGV4cG9ydC5GICogKEMgIT0gQmFzZSksIE8pO1xuXG4gIGlmICghSVNfV0VBSykgY29tbW9uLnNldFN0cm9uZyhDLCBOQU1FLCBJU19NQVApO1xuXG4gIHJldHVybiBDO1xufTtcbiIsInZhciBjb3JlID0gbW9kdWxlLmV4cG9ydHMgPSB7IHZlcnNpb246ICcyLjUuNycgfTtcbmlmICh0eXBlb2YgX19lID09ICdudW1iZXInKSBfX2UgPSBjb3JlOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXVuZGVmXG4iLCIndXNlIHN0cmljdCc7XG52YXIgJGRlZmluZVByb3BlcnR5ID0gcmVxdWlyZSgnLi9fb2JqZWN0LWRwJyk7XG52YXIgY3JlYXRlRGVzYyA9IHJlcXVpcmUoJy4vX3Byb3BlcnR5LWRlc2MnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAob2JqZWN0LCBpbmRleCwgdmFsdWUpIHtcbiAgaWYgKGluZGV4IGluIG9iamVjdCkgJGRlZmluZVByb3BlcnR5LmYob2JqZWN0LCBpbmRleCwgY3JlYXRlRGVzYygwLCB2YWx1ZSkpO1xuICBlbHNlIG9iamVjdFtpbmRleF0gPSB2YWx1ZTtcbn07XG4iLCIvLyBvcHRpb25hbCAvIHNpbXBsZSBjb250ZXh0IGJpbmRpbmdcbnZhciBhRnVuY3Rpb24gPSByZXF1aXJlKCcuL19hLWZ1bmN0aW9uJyk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChmbiwgdGhhdCwgbGVuZ3RoKSB7XG4gIGFGdW5jdGlvbihmbik7XG4gIGlmICh0aGF0ID09PSB1bmRlZmluZWQpIHJldHVybiBmbjtcbiAgc3dpdGNoIChsZW5ndGgpIHtcbiAgICBjYXNlIDE6IHJldHVybiBmdW5jdGlvbiAoYSkge1xuICAgICAgcmV0dXJuIGZuLmNhbGwodGhhdCwgYSk7XG4gICAgfTtcbiAgICBjYXNlIDI6IHJldHVybiBmdW5jdGlvbiAoYSwgYikge1xuICAgICAgcmV0dXJuIGZuLmNhbGwodGhhdCwgYSwgYik7XG4gICAgfTtcbiAgICBjYXNlIDM6IHJldHVybiBmdW5jdGlvbiAoYSwgYiwgYykge1xuICAgICAgcmV0dXJuIGZuLmNhbGwodGhhdCwgYSwgYiwgYyk7XG4gICAgfTtcbiAgfVxuICByZXR1cm4gZnVuY3Rpb24gKC8qIC4uLmFyZ3MgKi8pIHtcbiAgICByZXR1cm4gZm4uYXBwbHkodGhhdCwgYXJndW1lbnRzKTtcbiAgfTtcbn07XG4iLCIndXNlIHN0cmljdCc7XG4vLyAyMC4zLjQuMzYgLyAxNS45LjUuNDMgRGF0ZS5wcm90b3R5cGUudG9JU09TdHJpbmcoKVxudmFyIGZhaWxzID0gcmVxdWlyZSgnLi9fZmFpbHMnKTtcbnZhciBnZXRUaW1lID0gRGF0ZS5wcm90b3R5cGUuZ2V0VGltZTtcbnZhciAkdG9JU09TdHJpbmcgPSBEYXRlLnByb3RvdHlwZS50b0lTT1N0cmluZztcblxudmFyIGx6ID0gZnVuY3Rpb24gKG51bSkge1xuICByZXR1cm4gbnVtID4gOSA/IG51bSA6ICcwJyArIG51bTtcbn07XG5cbi8vIFBoYW50b21KUyAvIG9sZCBXZWJLaXQgaGFzIGEgYnJva2VuIGltcGxlbWVudGF0aW9uc1xubW9kdWxlLmV4cG9ydHMgPSAoZmFpbHMoZnVuY3Rpb24gKCkge1xuICByZXR1cm4gJHRvSVNPU3RyaW5nLmNhbGwobmV3IERhdGUoLTVlMTMgLSAxKSkgIT0gJzAzODUtMDctMjVUMDc6MDY6MzkuOTk5Wic7XG59KSB8fCAhZmFpbHMoZnVuY3Rpb24gKCkge1xuICAkdG9JU09TdHJpbmcuY2FsbChuZXcgRGF0ZShOYU4pKTtcbn0pKSA/IGZ1bmN0aW9uIHRvSVNPU3RyaW5nKCkge1xuICBpZiAoIWlzRmluaXRlKGdldFRpbWUuY2FsbCh0aGlzKSkpIHRocm93IFJhbmdlRXJyb3IoJ0ludmFsaWQgdGltZSB2YWx1ZScpO1xuICB2YXIgZCA9IHRoaXM7XG4gIHZhciB5ID0gZC5nZXRVVENGdWxsWWVhcigpO1xuICB2YXIgbSA9IGQuZ2V0VVRDTWlsbGlzZWNvbmRzKCk7XG4gIHZhciBzID0geSA8IDAgPyAnLScgOiB5ID4gOTk5OSA/ICcrJyA6ICcnO1xuICByZXR1cm4gcyArICgnMDAwMDAnICsgTWF0aC5hYnMoeSkpLnNsaWNlKHMgPyAtNiA6IC00KSArXG4gICAgJy0nICsgbHooZC5nZXRVVENNb250aCgpICsgMSkgKyAnLScgKyBseihkLmdldFVUQ0RhdGUoKSkgK1xuICAgICdUJyArIGx6KGQuZ2V0VVRDSG91cnMoKSkgKyAnOicgKyBseihkLmdldFVUQ01pbnV0ZXMoKSkgK1xuICAgICc6JyArIGx6KGQuZ2V0VVRDU2Vjb25kcygpKSArICcuJyArIChtID4gOTkgPyBtIDogJzAnICsgbHoobSkpICsgJ1onO1xufSA6ICR0b0lTT1N0cmluZztcbiIsIid1c2Ugc3RyaWN0JztcbnZhciBhbk9iamVjdCA9IHJlcXVpcmUoJy4vX2FuLW9iamVjdCcpO1xudmFyIHRvUHJpbWl0aXZlID0gcmVxdWlyZSgnLi9fdG8tcHJpbWl0aXZlJyk7XG52YXIgTlVNQkVSID0gJ251bWJlcic7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGhpbnQpIHtcbiAgaWYgKGhpbnQgIT09ICdzdHJpbmcnICYmIGhpbnQgIT09IE5VTUJFUiAmJiBoaW50ICE9PSAnZGVmYXVsdCcpIHRocm93IFR5cGVFcnJvcignSW5jb3JyZWN0IGhpbnQnKTtcbiAgcmV0dXJuIHRvUHJpbWl0aXZlKGFuT2JqZWN0KHRoaXMpLCBoaW50ICE9IE5VTUJFUik7XG59O1xuIiwiLy8gNy4yLjEgUmVxdWlyZU9iamVjdENvZXJjaWJsZShhcmd1bWVudClcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGl0KSB7XG4gIGlmIChpdCA9PSB1bmRlZmluZWQpIHRocm93IFR5cGVFcnJvcihcIkNhbid0IGNhbGwgbWV0aG9kIG9uICBcIiArIGl0KTtcbiAgcmV0dXJuIGl0O1xufTtcbiIsIi8vIFRoYW5rJ3MgSUU4IGZvciBoaXMgZnVubnkgZGVmaW5lUHJvcGVydHlcbm1vZHVsZS5leHBvcnRzID0gIXJlcXVpcmUoJy4vX2ZhaWxzJykoZnVuY3Rpb24gKCkge1xuICByZXR1cm4gT2JqZWN0LmRlZmluZVByb3BlcnR5KHt9LCAnYScsIHsgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiA3OyB9IH0pLmEgIT0gNztcbn0pO1xuIiwidmFyIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi9faXMtb2JqZWN0Jyk7XG52YXIgZG9jdW1lbnQgPSByZXF1aXJlKCcuL19nbG9iYWwnKS5kb2N1bWVudDtcbi8vIHR5cGVvZiBkb2N1bWVudC5jcmVhdGVFbGVtZW50IGlzICdvYmplY3QnIGluIG9sZCBJRVxudmFyIGlzID0gaXNPYmplY3QoZG9jdW1lbnQpICYmIGlzT2JqZWN0KGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQpO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoaXQpIHtcbiAgcmV0dXJuIGlzID8gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChpdCkgOiB7fTtcbn07XG4iLCIvLyBJRSA4LSBkb24ndCBlbnVtIGJ1ZyBrZXlzXG5tb2R1bGUuZXhwb3J0cyA9IChcbiAgJ2NvbnN0cnVjdG9yLGhhc093blByb3BlcnR5LGlzUHJvdG90eXBlT2YscHJvcGVydHlJc0VudW1lcmFibGUsdG9Mb2NhbGVTdHJpbmcsdG9TdHJpbmcsdmFsdWVPZidcbikuc3BsaXQoJywnKTtcbiIsIi8vIGFsbCBlbnVtZXJhYmxlIG9iamVjdCBrZXlzLCBpbmNsdWRlcyBzeW1ib2xzXG52YXIgZ2V0S2V5cyA9IHJlcXVpcmUoJy4vX29iamVjdC1rZXlzJyk7XG52YXIgZ09QUyA9IHJlcXVpcmUoJy4vX29iamVjdC1nb3BzJyk7XG52YXIgcElFID0gcmVxdWlyZSgnLi9fb2JqZWN0LXBpZScpO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoaXQpIHtcbiAgdmFyIHJlc3VsdCA9IGdldEtleXMoaXQpO1xuICB2YXIgZ2V0U3ltYm9scyA9IGdPUFMuZjtcbiAgaWYgKGdldFN5bWJvbHMpIHtcbiAgICB2YXIgc3ltYm9scyA9IGdldFN5bWJvbHMoaXQpO1xuICAgIHZhciBpc0VudW0gPSBwSUUuZjtcbiAgICB2YXIgaSA9IDA7XG4gICAgdmFyIGtleTtcbiAgICB3aGlsZSAoc3ltYm9scy5sZW5ndGggPiBpKSBpZiAoaXNFbnVtLmNhbGwoaXQsIGtleSA9IHN5bWJvbHNbaSsrXSkpIHJlc3VsdC5wdXNoKGtleSk7XG4gIH0gcmV0dXJuIHJlc3VsdDtcbn07XG4iLCJ2YXIgZ2xvYmFsID0gcmVxdWlyZSgnLi9fZ2xvYmFsJyk7XG52YXIgY29yZSA9IHJlcXVpcmUoJy4vX2NvcmUnKTtcbnZhciBoaWRlID0gcmVxdWlyZSgnLi9faGlkZScpO1xudmFyIHJlZGVmaW5lID0gcmVxdWlyZSgnLi9fcmVkZWZpbmUnKTtcbnZhciBjdHggPSByZXF1aXJlKCcuL19jdHgnKTtcbnZhciBQUk9UT1RZUEUgPSAncHJvdG90eXBlJztcblxudmFyICRleHBvcnQgPSBmdW5jdGlvbiAodHlwZSwgbmFtZSwgc291cmNlKSB7XG4gIHZhciBJU19GT1JDRUQgPSB0eXBlICYgJGV4cG9ydC5GO1xuICB2YXIgSVNfR0xPQkFMID0gdHlwZSAmICRleHBvcnQuRztcbiAgdmFyIElTX1NUQVRJQyA9IHR5cGUgJiAkZXhwb3J0LlM7XG4gIHZhciBJU19QUk9UTyA9IHR5cGUgJiAkZXhwb3J0LlA7XG4gIHZhciBJU19CSU5EID0gdHlwZSAmICRleHBvcnQuQjtcbiAgdmFyIHRhcmdldCA9IElTX0dMT0JBTCA/IGdsb2JhbCA6IElTX1NUQVRJQyA/IGdsb2JhbFtuYW1lXSB8fCAoZ2xvYmFsW25hbWVdID0ge30pIDogKGdsb2JhbFtuYW1lXSB8fCB7fSlbUFJPVE9UWVBFXTtcbiAgdmFyIGV4cG9ydHMgPSBJU19HTE9CQUwgPyBjb3JlIDogY29yZVtuYW1lXSB8fCAoY29yZVtuYW1lXSA9IHt9KTtcbiAgdmFyIGV4cFByb3RvID0gZXhwb3J0c1tQUk9UT1RZUEVdIHx8IChleHBvcnRzW1BST1RPVFlQRV0gPSB7fSk7XG4gIHZhciBrZXksIG93biwgb3V0LCBleHA7XG4gIGlmIChJU19HTE9CQUwpIHNvdXJjZSA9IG5hbWU7XG4gIGZvciAoa2V5IGluIHNvdXJjZSkge1xuICAgIC8vIGNvbnRhaW5zIGluIG5hdGl2ZVxuICAgIG93biA9ICFJU19GT1JDRUQgJiYgdGFyZ2V0ICYmIHRhcmdldFtrZXldICE9PSB1bmRlZmluZWQ7XG4gICAgLy8gZXhwb3J0IG5hdGl2ZSBvciBwYXNzZWRcbiAgICBvdXQgPSAob3duID8gdGFyZ2V0IDogc291cmNlKVtrZXldO1xuICAgIC8vIGJpbmQgdGltZXJzIHRvIGdsb2JhbCBmb3IgY2FsbCBmcm9tIGV4cG9ydCBjb250ZXh0XG4gICAgZXhwID0gSVNfQklORCAmJiBvd24gPyBjdHgob3V0LCBnbG9iYWwpIDogSVNfUFJPVE8gJiYgdHlwZW9mIG91dCA9PSAnZnVuY3Rpb24nID8gY3R4KEZ1bmN0aW9uLmNhbGwsIG91dCkgOiBvdXQ7XG4gICAgLy8gZXh0ZW5kIGdsb2JhbFxuICAgIGlmICh0YXJnZXQpIHJlZGVmaW5lKHRhcmdldCwga2V5LCBvdXQsIHR5cGUgJiAkZXhwb3J0LlUpO1xuICAgIC8vIGV4cG9ydFxuICAgIGlmIChleHBvcnRzW2tleV0gIT0gb3V0KSBoaWRlKGV4cG9ydHMsIGtleSwgZXhwKTtcbiAgICBpZiAoSVNfUFJPVE8gJiYgZXhwUHJvdG9ba2V5XSAhPSBvdXQpIGV4cFByb3RvW2tleV0gPSBvdXQ7XG4gIH1cbn07XG5nbG9iYWwuY29yZSA9IGNvcmU7XG4vLyB0eXBlIGJpdG1hcFxuJGV4cG9ydC5GID0gMTsgICAvLyBmb3JjZWRcbiRleHBvcnQuRyA9IDI7ICAgLy8gZ2xvYmFsXG4kZXhwb3J0LlMgPSA0OyAgIC8vIHN0YXRpY1xuJGV4cG9ydC5QID0gODsgICAvLyBwcm90b1xuJGV4cG9ydC5CID0gMTY7ICAvLyBiaW5kXG4kZXhwb3J0LlcgPSAzMjsgIC8vIHdyYXBcbiRleHBvcnQuVSA9IDY0OyAgLy8gc2FmZVxuJGV4cG9ydC5SID0gMTI4OyAvLyByZWFsIHByb3RvIG1ldGhvZCBmb3IgYGxpYnJhcnlgXG5tb2R1bGUuZXhwb3J0cyA9ICRleHBvcnQ7XG4iLCJ2YXIgTUFUQ0ggPSByZXF1aXJlKCcuL193a3MnKSgnbWF0Y2gnKTtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKEtFWSkge1xuICB2YXIgcmUgPSAvLi87XG4gIHRyeSB7XG4gICAgJy8uLydbS0VZXShyZSk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICB0cnkge1xuICAgICAgcmVbTUFUQ0hdID0gZmFsc2U7XG4gICAgICByZXR1cm4gIScvLi8nW0tFWV0ocmUpO1xuICAgIH0gY2F0Y2ggKGYpIHsgLyogZW1wdHkgKi8gfVxuICB9IHJldHVybiB0cnVlO1xufTtcbiIsIm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGV4ZWMpIHtcbiAgdHJ5IHtcbiAgICByZXR1cm4gISFleGVjKCk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxufTtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciBoaWRlID0gcmVxdWlyZSgnLi9faGlkZScpO1xudmFyIHJlZGVmaW5lID0gcmVxdWlyZSgnLi9fcmVkZWZpbmUnKTtcbnZhciBmYWlscyA9IHJlcXVpcmUoJy4vX2ZhaWxzJyk7XG52YXIgZGVmaW5lZCA9IHJlcXVpcmUoJy4vX2RlZmluZWQnKTtcbnZhciB3a3MgPSByZXF1aXJlKCcuL193a3MnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoS0VZLCBsZW5ndGgsIGV4ZWMpIHtcbiAgdmFyIFNZTUJPTCA9IHdrcyhLRVkpO1xuICB2YXIgZm5zID0gZXhlYyhkZWZpbmVkLCBTWU1CT0wsICcnW0tFWV0pO1xuICB2YXIgc3RyZm4gPSBmbnNbMF07XG4gIHZhciByeGZuID0gZm5zWzFdO1xuICBpZiAoZmFpbHMoZnVuY3Rpb24gKCkge1xuICAgIHZhciBPID0ge307XG4gICAgT1tTWU1CT0xdID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gNzsgfTtcbiAgICByZXR1cm4gJydbS0VZXShPKSAhPSA3O1xuICB9KSkge1xuICAgIHJlZGVmaW5lKFN0cmluZy5wcm90b3R5cGUsIEtFWSwgc3RyZm4pO1xuICAgIGhpZGUoUmVnRXhwLnByb3RvdHlwZSwgU1lNQk9MLCBsZW5ndGggPT0gMlxuICAgICAgLy8gMjEuMi41LjggUmVnRXhwLnByb3RvdHlwZVtAQHJlcGxhY2VdKHN0cmluZywgcmVwbGFjZVZhbHVlKVxuICAgICAgLy8gMjEuMi41LjExIFJlZ0V4cC5wcm90b3R5cGVbQEBzcGxpdF0oc3RyaW5nLCBsaW1pdClcbiAgICAgID8gZnVuY3Rpb24gKHN0cmluZywgYXJnKSB7IHJldHVybiByeGZuLmNhbGwoc3RyaW5nLCB0aGlzLCBhcmcpOyB9XG4gICAgICAvLyAyMS4yLjUuNiBSZWdFeHAucHJvdG90eXBlW0BAbWF0Y2hdKHN0cmluZylcbiAgICAgIC8vIDIxLjIuNS45IFJlZ0V4cC5wcm90b3R5cGVbQEBzZWFyY2hdKHN0cmluZylcbiAgICAgIDogZnVuY3Rpb24gKHN0cmluZykgeyByZXR1cm4gcnhmbi5jYWxsKHN0cmluZywgdGhpcyk7IH1cbiAgICApO1xuICB9XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuLy8gMjEuMi41LjMgZ2V0IFJlZ0V4cC5wcm90b3R5cGUuZmxhZ3NcbnZhciBhbk9iamVjdCA9IHJlcXVpcmUoJy4vX2FuLW9iamVjdCcpO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciB0aGF0ID0gYW5PYmplY3QodGhpcyk7XG4gIHZhciByZXN1bHQgPSAnJztcbiAgaWYgKHRoYXQuZ2xvYmFsKSByZXN1bHQgKz0gJ2cnO1xuICBpZiAodGhhdC5pZ25vcmVDYXNlKSByZXN1bHQgKz0gJ2knO1xuICBpZiAodGhhdC5tdWx0aWxpbmUpIHJlc3VsdCArPSAnbSc7XG4gIGlmICh0aGF0LnVuaWNvZGUpIHJlc3VsdCArPSAndSc7XG4gIGlmICh0aGF0LnN0aWNreSkgcmVzdWx0ICs9ICd5JztcbiAgcmV0dXJuIHJlc3VsdDtcbn07XG4iLCJ2YXIgY3R4ID0gcmVxdWlyZSgnLi9fY3R4Jyk7XG52YXIgY2FsbCA9IHJlcXVpcmUoJy4vX2l0ZXItY2FsbCcpO1xudmFyIGlzQXJyYXlJdGVyID0gcmVxdWlyZSgnLi9faXMtYXJyYXktaXRlcicpO1xudmFyIGFuT2JqZWN0ID0gcmVxdWlyZSgnLi9fYW4tb2JqZWN0Jyk7XG52YXIgdG9MZW5ndGggPSByZXF1aXJlKCcuL190by1sZW5ndGgnKTtcbnZhciBnZXRJdGVyRm4gPSByZXF1aXJlKCcuL2NvcmUuZ2V0LWl0ZXJhdG9yLW1ldGhvZCcpO1xudmFyIEJSRUFLID0ge307XG52YXIgUkVUVVJOID0ge307XG52YXIgZXhwb3J0cyA9IG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGl0ZXJhYmxlLCBlbnRyaWVzLCBmbiwgdGhhdCwgSVRFUkFUT1IpIHtcbiAgdmFyIGl0ZXJGbiA9IElURVJBVE9SID8gZnVuY3Rpb24gKCkgeyByZXR1cm4gaXRlcmFibGU7IH0gOiBnZXRJdGVyRm4oaXRlcmFibGUpO1xuICB2YXIgZiA9IGN0eChmbiwgdGhhdCwgZW50cmllcyA/IDIgOiAxKTtcbiAgdmFyIGluZGV4ID0gMDtcbiAgdmFyIGxlbmd0aCwgc3RlcCwgaXRlcmF0b3IsIHJlc3VsdDtcbiAgaWYgKHR5cGVvZiBpdGVyRm4gIT0gJ2Z1bmN0aW9uJykgdGhyb3cgVHlwZUVycm9yKGl0ZXJhYmxlICsgJyBpcyBub3QgaXRlcmFibGUhJyk7XG4gIC8vIGZhc3QgY2FzZSBmb3IgYXJyYXlzIHdpdGggZGVmYXVsdCBpdGVyYXRvclxuICBpZiAoaXNBcnJheUl0ZXIoaXRlckZuKSkgZm9yIChsZW5ndGggPSB0b0xlbmd0aChpdGVyYWJsZS5sZW5ndGgpOyBsZW5ndGggPiBpbmRleDsgaW5kZXgrKykge1xuICAgIHJlc3VsdCA9IGVudHJpZXMgPyBmKGFuT2JqZWN0KHN0ZXAgPSBpdGVyYWJsZVtpbmRleF0pWzBdLCBzdGVwWzFdKSA6IGYoaXRlcmFibGVbaW5kZXhdKTtcbiAgICBpZiAocmVzdWx0ID09PSBCUkVBSyB8fCByZXN1bHQgPT09IFJFVFVSTikgcmV0dXJuIHJlc3VsdDtcbiAgfSBlbHNlIGZvciAoaXRlcmF0b3IgPSBpdGVyRm4uY2FsbChpdGVyYWJsZSk7ICEoc3RlcCA9IGl0ZXJhdG9yLm5leHQoKSkuZG9uZTspIHtcbiAgICByZXN1bHQgPSBjYWxsKGl0ZXJhdG9yLCBmLCBzdGVwLnZhbHVlLCBlbnRyaWVzKTtcbiAgICBpZiAocmVzdWx0ID09PSBCUkVBSyB8fCByZXN1bHQgPT09IFJFVFVSTikgcmV0dXJuIHJlc3VsdDtcbiAgfVxufTtcbmV4cG9ydHMuQlJFQUsgPSBCUkVBSztcbmV4cG9ydHMuUkVUVVJOID0gUkVUVVJOO1xuIiwiLy8gaHR0cHM6Ly9naXRodWIuY29tL3psb2lyb2NrL2NvcmUtanMvaXNzdWVzLzg2I2lzc3VlY29tbWVudC0xMTU3NTkwMjhcbnZhciBnbG9iYWwgPSBtb2R1bGUuZXhwb3J0cyA9IHR5cGVvZiB3aW5kb3cgIT0gJ3VuZGVmaW5lZCcgJiYgd2luZG93Lk1hdGggPT0gTWF0aFxuICA/IHdpbmRvdyA6IHR5cGVvZiBzZWxmICE9ICd1bmRlZmluZWQnICYmIHNlbGYuTWF0aCA9PSBNYXRoID8gc2VsZlxuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tbmV3LWZ1bmNcbiAgOiBGdW5jdGlvbigncmV0dXJuIHRoaXMnKSgpO1xuaWYgKHR5cGVvZiBfX2cgPT0gJ251bWJlcicpIF9fZyA9IGdsb2JhbDsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby11bmRlZlxuIiwidmFyIGhhc093blByb3BlcnR5ID0ge30uaGFzT3duUHJvcGVydHk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChpdCwga2V5KSB7XG4gIHJldHVybiBoYXNPd25Qcm9wZXJ0eS5jYWxsKGl0LCBrZXkpO1xufTtcbiIsInZhciBkUCA9IHJlcXVpcmUoJy4vX29iamVjdC1kcCcpO1xudmFyIGNyZWF0ZURlc2MgPSByZXF1aXJlKCcuL19wcm9wZXJ0eS1kZXNjJyk7XG5tb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vX2Rlc2NyaXB0b3JzJykgPyBmdW5jdGlvbiAob2JqZWN0LCBrZXksIHZhbHVlKSB7XG4gIHJldHVybiBkUC5mKG9iamVjdCwga2V5LCBjcmVhdGVEZXNjKDEsIHZhbHVlKSk7XG59IDogZnVuY3Rpb24gKG9iamVjdCwga2V5LCB2YWx1ZSkge1xuICBvYmplY3Rba2V5XSA9IHZhbHVlO1xuICByZXR1cm4gb2JqZWN0O1xufTtcbiIsInZhciBkb2N1bWVudCA9IHJlcXVpcmUoJy4vX2dsb2JhbCcpLmRvY3VtZW50O1xubW9kdWxlLmV4cG9ydHMgPSBkb2N1bWVudCAmJiBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQ7XG4iLCJtb2R1bGUuZXhwb3J0cyA9ICFyZXF1aXJlKCcuL19kZXNjcmlwdG9ycycpICYmICFyZXF1aXJlKCcuL19mYWlscycpKGZ1bmN0aW9uICgpIHtcbiAgcmV0dXJuIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShyZXF1aXJlKCcuL19kb20tY3JlYXRlJykoJ2RpdicpLCAnYScsIHsgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiA3OyB9IH0pLmEgIT0gNztcbn0pO1xuIiwidmFyIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi9faXMtb2JqZWN0Jyk7XG52YXIgc2V0UHJvdG90eXBlT2YgPSByZXF1aXJlKCcuL19zZXQtcHJvdG8nKS5zZXQ7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uICh0aGF0LCB0YXJnZXQsIEMpIHtcbiAgdmFyIFMgPSB0YXJnZXQuY29uc3RydWN0b3I7XG4gIHZhciBQO1xuICBpZiAoUyAhPT0gQyAmJiB0eXBlb2YgUyA9PSAnZnVuY3Rpb24nICYmIChQID0gUy5wcm90b3R5cGUpICE9PSBDLnByb3RvdHlwZSAmJiBpc09iamVjdChQKSAmJiBzZXRQcm90b3R5cGVPZikge1xuICAgIHNldFByb3RvdHlwZU9mKHRoYXQsIFApO1xuICB9IHJldHVybiB0aGF0O1xufTtcbiIsIi8vIGZhc3QgYXBwbHksIGh0dHA6Ly9qc3BlcmYubG5raXQuY29tL2Zhc3QtYXBwbHkvNVxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoZm4sIGFyZ3MsIHRoYXQpIHtcbiAgdmFyIHVuID0gdGhhdCA9PT0gdW5kZWZpbmVkO1xuICBzd2l0Y2ggKGFyZ3MubGVuZ3RoKSB7XG4gICAgY2FzZSAwOiByZXR1cm4gdW4gPyBmbigpXG4gICAgICAgICAgICAgICAgICAgICAgOiBmbi5jYWxsKHRoYXQpO1xuICAgIGNhc2UgMTogcmV0dXJuIHVuID8gZm4oYXJnc1swXSlcbiAgICAgICAgICAgICAgICAgICAgICA6IGZuLmNhbGwodGhhdCwgYXJnc1swXSk7XG4gICAgY2FzZSAyOiByZXR1cm4gdW4gPyBmbihhcmdzWzBdLCBhcmdzWzFdKVxuICAgICAgICAgICAgICAgICAgICAgIDogZm4uY2FsbCh0aGF0LCBhcmdzWzBdLCBhcmdzWzFdKTtcbiAgICBjYXNlIDM6IHJldHVybiB1biA/IGZuKGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0pXG4gICAgICAgICAgICAgICAgICAgICAgOiBmbi5jYWxsKHRoYXQsIGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0pO1xuICAgIGNhc2UgNDogcmV0dXJuIHVuID8gZm4oYXJnc1swXSwgYXJnc1sxXSwgYXJnc1syXSwgYXJnc1szXSlcbiAgICAgICAgICAgICAgICAgICAgICA6IGZuLmNhbGwodGhhdCwgYXJnc1swXSwgYXJnc1sxXSwgYXJnc1syXSwgYXJnc1szXSk7XG4gIH0gcmV0dXJuIGZuLmFwcGx5KHRoYXQsIGFyZ3MpO1xufTtcbiIsIi8vIGZhbGxiYWNrIGZvciBub24tYXJyYXktbGlrZSBFUzMgYW5kIG5vbi1lbnVtZXJhYmxlIG9sZCBWOCBzdHJpbmdzXG52YXIgY29mID0gcmVxdWlyZSgnLi9fY29mJyk7XG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tcHJvdG90eXBlLWJ1aWx0aW5zXG5tb2R1bGUuZXhwb3J0cyA9IE9iamVjdCgneicpLnByb3BlcnR5SXNFbnVtZXJhYmxlKDApID8gT2JqZWN0IDogZnVuY3Rpb24gKGl0KSB7XG4gIHJldHVybiBjb2YoaXQpID09ICdTdHJpbmcnID8gaXQuc3BsaXQoJycpIDogT2JqZWN0KGl0KTtcbn07XG4iLCIvLyBjaGVjayBvbiBkZWZhdWx0IEFycmF5IGl0ZXJhdG9yXG52YXIgSXRlcmF0b3JzID0gcmVxdWlyZSgnLi9faXRlcmF0b3JzJyk7XG52YXIgSVRFUkFUT1IgPSByZXF1aXJlKCcuL193a3MnKSgnaXRlcmF0b3InKTtcbnZhciBBcnJheVByb3RvID0gQXJyYXkucHJvdG90eXBlO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChpdCkge1xuICByZXR1cm4gaXQgIT09IHVuZGVmaW5lZCAmJiAoSXRlcmF0b3JzLkFycmF5ID09PSBpdCB8fCBBcnJheVByb3RvW0lURVJBVE9SXSA9PT0gaXQpO1xufTtcbiIsIi8vIDcuMi4yIElzQXJyYXkoYXJndW1lbnQpXG52YXIgY29mID0gcmVxdWlyZSgnLi9fY29mJyk7XG5tb2R1bGUuZXhwb3J0cyA9IEFycmF5LmlzQXJyYXkgfHwgZnVuY3Rpb24gaXNBcnJheShhcmcpIHtcbiAgcmV0dXJuIGNvZihhcmcpID09ICdBcnJheSc7XG59O1xuIiwiLy8gMjAuMS4yLjMgTnVtYmVyLmlzSW50ZWdlcihudW1iZXIpXG52YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuL19pcy1vYmplY3QnKTtcbnZhciBmbG9vciA9IE1hdGguZmxvb3I7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGlzSW50ZWdlcihpdCkge1xuICByZXR1cm4gIWlzT2JqZWN0KGl0KSAmJiBpc0Zpbml0ZShpdCkgJiYgZmxvb3IoaXQpID09PSBpdDtcbn07XG4iLCJtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChpdCkge1xuICByZXR1cm4gdHlwZW9mIGl0ID09PSAnb2JqZWN0JyA/IGl0ICE9PSBudWxsIDogdHlwZW9mIGl0ID09PSAnZnVuY3Rpb24nO1xufTtcbiIsIi8vIDcuMi44IElzUmVnRXhwKGFyZ3VtZW50KVxudmFyIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi9faXMtb2JqZWN0Jyk7XG52YXIgY29mID0gcmVxdWlyZSgnLi9fY29mJyk7XG52YXIgTUFUQ0ggPSByZXF1aXJlKCcuL193a3MnKSgnbWF0Y2gnKTtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGl0KSB7XG4gIHZhciBpc1JlZ0V4cDtcbiAgcmV0dXJuIGlzT2JqZWN0KGl0KSAmJiAoKGlzUmVnRXhwID0gaXRbTUFUQ0hdKSAhPT0gdW5kZWZpbmVkID8gISFpc1JlZ0V4cCA6IGNvZihpdCkgPT0gJ1JlZ0V4cCcpO1xufTtcbiIsIi8vIGNhbGwgc29tZXRoaW5nIG9uIGl0ZXJhdG9yIHN0ZXAgd2l0aCBzYWZlIGNsb3Npbmcgb24gZXJyb3JcbnZhciBhbk9iamVjdCA9IHJlcXVpcmUoJy4vX2FuLW9iamVjdCcpO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoaXRlcmF0b3IsIGZuLCB2YWx1ZSwgZW50cmllcykge1xuICB0cnkge1xuICAgIHJldHVybiBlbnRyaWVzID8gZm4oYW5PYmplY3QodmFsdWUpWzBdLCB2YWx1ZVsxXSkgOiBmbih2YWx1ZSk7XG4gIC8vIDcuNC42IEl0ZXJhdG9yQ2xvc2UoaXRlcmF0b3IsIGNvbXBsZXRpb24pXG4gIH0gY2F0Y2ggKGUpIHtcbiAgICB2YXIgcmV0ID0gaXRlcmF0b3JbJ3JldHVybiddO1xuICAgIGlmIChyZXQgIT09IHVuZGVmaW5lZCkgYW5PYmplY3QocmV0LmNhbGwoaXRlcmF0b3IpKTtcbiAgICB0aHJvdyBlO1xuICB9XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyIGNyZWF0ZSA9IHJlcXVpcmUoJy4vX29iamVjdC1jcmVhdGUnKTtcbnZhciBkZXNjcmlwdG9yID0gcmVxdWlyZSgnLi9fcHJvcGVydHktZGVzYycpO1xudmFyIHNldFRvU3RyaW5nVGFnID0gcmVxdWlyZSgnLi9fc2V0LXRvLXN0cmluZy10YWcnKTtcbnZhciBJdGVyYXRvclByb3RvdHlwZSA9IHt9O1xuXG4vLyAyNS4xLjIuMS4xICVJdGVyYXRvclByb3RvdHlwZSVbQEBpdGVyYXRvcl0oKVxucmVxdWlyZSgnLi9faGlkZScpKEl0ZXJhdG9yUHJvdG90eXBlLCByZXF1aXJlKCcuL193a3MnKSgnaXRlcmF0b3InKSwgZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpczsgfSk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKENvbnN0cnVjdG9yLCBOQU1FLCBuZXh0KSB7XG4gIENvbnN0cnVjdG9yLnByb3RvdHlwZSA9IGNyZWF0ZShJdGVyYXRvclByb3RvdHlwZSwgeyBuZXh0OiBkZXNjcmlwdG9yKDEsIG5leHQpIH0pO1xuICBzZXRUb1N0cmluZ1RhZyhDb25zdHJ1Y3RvciwgTkFNRSArICcgSXRlcmF0b3InKTtcbn07XG4iLCIndXNlIHN0cmljdCc7XG52YXIgTElCUkFSWSA9IHJlcXVpcmUoJy4vX2xpYnJhcnknKTtcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgcmVkZWZpbmUgPSByZXF1aXJlKCcuL19yZWRlZmluZScpO1xudmFyIGhpZGUgPSByZXF1aXJlKCcuL19oaWRlJyk7XG52YXIgSXRlcmF0b3JzID0gcmVxdWlyZSgnLi9faXRlcmF0b3JzJyk7XG52YXIgJGl0ZXJDcmVhdGUgPSByZXF1aXJlKCcuL19pdGVyLWNyZWF0ZScpO1xudmFyIHNldFRvU3RyaW5nVGFnID0gcmVxdWlyZSgnLi9fc2V0LXRvLXN0cmluZy10YWcnKTtcbnZhciBnZXRQcm90b3R5cGVPZiA9IHJlcXVpcmUoJy4vX29iamVjdC1ncG8nKTtcbnZhciBJVEVSQVRPUiA9IHJlcXVpcmUoJy4vX3drcycpKCdpdGVyYXRvcicpO1xudmFyIEJVR0dZID0gIShbXS5rZXlzICYmICduZXh0JyBpbiBbXS5rZXlzKCkpOyAvLyBTYWZhcmkgaGFzIGJ1Z2d5IGl0ZXJhdG9ycyB3L28gYG5leHRgXG52YXIgRkZfSVRFUkFUT1IgPSAnQEBpdGVyYXRvcic7XG52YXIgS0VZUyA9ICdrZXlzJztcbnZhciBWQUxVRVMgPSAndmFsdWVzJztcblxudmFyIHJldHVyblRoaXMgPSBmdW5jdGlvbiAoKSB7IHJldHVybiB0aGlzOyB9O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChCYXNlLCBOQU1FLCBDb25zdHJ1Y3RvciwgbmV4dCwgREVGQVVMVCwgSVNfU0VULCBGT1JDRUQpIHtcbiAgJGl0ZXJDcmVhdGUoQ29uc3RydWN0b3IsIE5BTUUsIG5leHQpO1xuICB2YXIgZ2V0TWV0aG9kID0gZnVuY3Rpb24gKGtpbmQpIHtcbiAgICBpZiAoIUJVR0dZICYmIGtpbmQgaW4gcHJvdG8pIHJldHVybiBwcm90b1traW5kXTtcbiAgICBzd2l0Y2ggKGtpbmQpIHtcbiAgICAgIGNhc2UgS0VZUzogcmV0dXJuIGZ1bmN0aW9uIGtleXMoKSB7IHJldHVybiBuZXcgQ29uc3RydWN0b3IodGhpcywga2luZCk7IH07XG4gICAgICBjYXNlIFZBTFVFUzogcmV0dXJuIGZ1bmN0aW9uIHZhbHVlcygpIHsgcmV0dXJuIG5ldyBDb25zdHJ1Y3Rvcih0aGlzLCBraW5kKTsgfTtcbiAgICB9IHJldHVybiBmdW5jdGlvbiBlbnRyaWVzKCkgeyByZXR1cm4gbmV3IENvbnN0cnVjdG9yKHRoaXMsIGtpbmQpOyB9O1xuICB9O1xuICB2YXIgVEFHID0gTkFNRSArICcgSXRlcmF0b3InO1xuICB2YXIgREVGX1ZBTFVFUyA9IERFRkFVTFQgPT0gVkFMVUVTO1xuICB2YXIgVkFMVUVTX0JVRyA9IGZhbHNlO1xuICB2YXIgcHJvdG8gPSBCYXNlLnByb3RvdHlwZTtcbiAgdmFyICRuYXRpdmUgPSBwcm90b1tJVEVSQVRPUl0gfHwgcHJvdG9bRkZfSVRFUkFUT1JdIHx8IERFRkFVTFQgJiYgcHJvdG9bREVGQVVMVF07XG4gIHZhciAkZGVmYXVsdCA9ICRuYXRpdmUgfHwgZ2V0TWV0aG9kKERFRkFVTFQpO1xuICB2YXIgJGVudHJpZXMgPSBERUZBVUxUID8gIURFRl9WQUxVRVMgPyAkZGVmYXVsdCA6IGdldE1ldGhvZCgnZW50cmllcycpIDogdW5kZWZpbmVkO1xuICB2YXIgJGFueU5hdGl2ZSA9IE5BTUUgPT0gJ0FycmF5JyA/IHByb3RvLmVudHJpZXMgfHwgJG5hdGl2ZSA6ICRuYXRpdmU7XG4gIHZhciBtZXRob2RzLCBrZXksIEl0ZXJhdG9yUHJvdG90eXBlO1xuICAvLyBGaXggbmF0aXZlXG4gIGlmICgkYW55TmF0aXZlKSB7XG4gICAgSXRlcmF0b3JQcm90b3R5cGUgPSBnZXRQcm90b3R5cGVPZigkYW55TmF0aXZlLmNhbGwobmV3IEJhc2UoKSkpO1xuICAgIGlmIChJdGVyYXRvclByb3RvdHlwZSAhPT0gT2JqZWN0LnByb3RvdHlwZSAmJiBJdGVyYXRvclByb3RvdHlwZS5uZXh0KSB7XG4gICAgICAvLyBTZXQgQEB0b1N0cmluZ1RhZyB0byBuYXRpdmUgaXRlcmF0b3JzXG4gICAgICBzZXRUb1N0cmluZ1RhZyhJdGVyYXRvclByb3RvdHlwZSwgVEFHLCB0cnVlKTtcbiAgICAgIC8vIGZpeCBmb3Igc29tZSBvbGQgZW5naW5lc1xuICAgICAgaWYgKCFMSUJSQVJZICYmIHR5cGVvZiBJdGVyYXRvclByb3RvdHlwZVtJVEVSQVRPUl0gIT0gJ2Z1bmN0aW9uJykgaGlkZShJdGVyYXRvclByb3RvdHlwZSwgSVRFUkFUT1IsIHJldHVyblRoaXMpO1xuICAgIH1cbiAgfVxuICAvLyBmaXggQXJyYXkje3ZhbHVlcywgQEBpdGVyYXRvcn0ubmFtZSBpbiBWOCAvIEZGXG4gIGlmIChERUZfVkFMVUVTICYmICRuYXRpdmUgJiYgJG5hdGl2ZS5uYW1lICE9PSBWQUxVRVMpIHtcbiAgICBWQUxVRVNfQlVHID0gdHJ1ZTtcbiAgICAkZGVmYXVsdCA9IGZ1bmN0aW9uIHZhbHVlcygpIHsgcmV0dXJuICRuYXRpdmUuY2FsbCh0aGlzKTsgfTtcbiAgfVxuICAvLyBEZWZpbmUgaXRlcmF0b3JcbiAgaWYgKCghTElCUkFSWSB8fCBGT1JDRUQpICYmIChCVUdHWSB8fCBWQUxVRVNfQlVHIHx8ICFwcm90b1tJVEVSQVRPUl0pKSB7XG4gICAgaGlkZShwcm90bywgSVRFUkFUT1IsICRkZWZhdWx0KTtcbiAgfVxuICAvLyBQbHVnIGZvciBsaWJyYXJ5XG4gIEl0ZXJhdG9yc1tOQU1FXSA9ICRkZWZhdWx0O1xuICBJdGVyYXRvcnNbVEFHXSA9IHJldHVyblRoaXM7XG4gIGlmIChERUZBVUxUKSB7XG4gICAgbWV0aG9kcyA9IHtcbiAgICAgIHZhbHVlczogREVGX1ZBTFVFUyA/ICRkZWZhdWx0IDogZ2V0TWV0aG9kKFZBTFVFUyksXG4gICAgICBrZXlzOiBJU19TRVQgPyAkZGVmYXVsdCA6IGdldE1ldGhvZChLRVlTKSxcbiAgICAgIGVudHJpZXM6ICRlbnRyaWVzXG4gICAgfTtcbiAgICBpZiAoRk9SQ0VEKSBmb3IgKGtleSBpbiBtZXRob2RzKSB7XG4gICAgICBpZiAoIShrZXkgaW4gcHJvdG8pKSByZWRlZmluZShwcm90bywga2V5LCBtZXRob2RzW2tleV0pO1xuICAgIH0gZWxzZSAkZXhwb3J0KCRleHBvcnQuUCArICRleHBvcnQuRiAqIChCVUdHWSB8fCBWQUxVRVNfQlVHKSwgTkFNRSwgbWV0aG9kcyk7XG4gIH1cbiAgcmV0dXJuIG1ldGhvZHM7XG59O1xuIiwidmFyIElURVJBVE9SID0gcmVxdWlyZSgnLi9fd2tzJykoJ2l0ZXJhdG9yJyk7XG52YXIgU0FGRV9DTE9TSU5HID0gZmFsc2U7XG5cbnRyeSB7XG4gIHZhciByaXRlciA9IFs3XVtJVEVSQVRPUl0oKTtcbiAgcml0ZXJbJ3JldHVybiddID0gZnVuY3Rpb24gKCkgeyBTQUZFX0NMT1NJTkcgPSB0cnVlOyB9O1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdGhyb3ctbGl0ZXJhbFxuICBBcnJheS5mcm9tKHJpdGVyLCBmdW5jdGlvbiAoKSB7IHRocm93IDI7IH0pO1xufSBjYXRjaCAoZSkgeyAvKiBlbXB0eSAqLyB9XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGV4ZWMsIHNraXBDbG9zaW5nKSB7XG4gIGlmICghc2tpcENsb3NpbmcgJiYgIVNBRkVfQ0xPU0lORykgcmV0dXJuIGZhbHNlO1xuICB2YXIgc2FmZSA9IGZhbHNlO1xuICB0cnkge1xuICAgIHZhciBhcnIgPSBbN107XG4gICAgdmFyIGl0ZXIgPSBhcnJbSVRFUkFUT1JdKCk7XG4gICAgaXRlci5uZXh0ID0gZnVuY3Rpb24gKCkgeyByZXR1cm4geyBkb25lOiBzYWZlID0gdHJ1ZSB9OyB9O1xuICAgIGFycltJVEVSQVRPUl0gPSBmdW5jdGlvbiAoKSB7IHJldHVybiBpdGVyOyB9O1xuICAgIGV4ZWMoYXJyKTtcbiAgfSBjYXRjaCAoZSkgeyAvKiBlbXB0eSAqLyB9XG4gIHJldHVybiBzYWZlO1xufTtcbiIsIm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGRvbmUsIHZhbHVlKSB7XG4gIHJldHVybiB7IHZhbHVlOiB2YWx1ZSwgZG9uZTogISFkb25lIH07XG59O1xuIiwibW9kdWxlLmV4cG9ydHMgPSB7fTtcbiIsIm1vZHVsZS5leHBvcnRzID0gZmFsc2U7XG4iLCIvLyAyMC4yLjIuMTQgTWF0aC5leHBtMSh4KVxudmFyICRleHBtMSA9IE1hdGguZXhwbTE7XG5tb2R1bGUuZXhwb3J0cyA9ICghJGV4cG0xXG4gIC8vIE9sZCBGRiBidWdcbiAgfHwgJGV4cG0xKDEwKSA+IDIyMDI1LjQ2NTc5NDgwNjcxOSB8fCAkZXhwbTEoMTApIDwgMjIwMjUuNDY1Nzk0ODA2NzE2NTE2OFxuICAvLyBUb3IgQnJvd3NlciBidWdcbiAgfHwgJGV4cG0xKC0yZS0xNykgIT0gLTJlLTE3XG4pID8gZnVuY3Rpb24gZXhwbTEoeCkge1xuICByZXR1cm4gKHggPSAreCkgPT0gMCA/IHggOiB4ID4gLTFlLTYgJiYgeCA8IDFlLTYgPyB4ICsgeCAqIHggLyAyIDogTWF0aC5leHAoeCkgLSAxO1xufSA6ICRleHBtMTtcbiIsIi8vIDIwLjIuMi4xNiBNYXRoLmZyb3VuZCh4KVxudmFyIHNpZ24gPSByZXF1aXJlKCcuL19tYXRoLXNpZ24nKTtcbnZhciBwb3cgPSBNYXRoLnBvdztcbnZhciBFUFNJTE9OID0gcG93KDIsIC01Mik7XG52YXIgRVBTSUxPTjMyID0gcG93KDIsIC0yMyk7XG52YXIgTUFYMzIgPSBwb3coMiwgMTI3KSAqICgyIC0gRVBTSUxPTjMyKTtcbnZhciBNSU4zMiA9IHBvdygyLCAtMTI2KTtcblxudmFyIHJvdW5kVGllc1RvRXZlbiA9IGZ1bmN0aW9uIChuKSB7XG4gIHJldHVybiBuICsgMSAvIEVQU0lMT04gLSAxIC8gRVBTSUxPTjtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gTWF0aC5mcm91bmQgfHwgZnVuY3Rpb24gZnJvdW5kKHgpIHtcbiAgdmFyICRhYnMgPSBNYXRoLmFicyh4KTtcbiAgdmFyICRzaWduID0gc2lnbih4KTtcbiAgdmFyIGEsIHJlc3VsdDtcbiAgaWYgKCRhYnMgPCBNSU4zMikgcmV0dXJuICRzaWduICogcm91bmRUaWVzVG9FdmVuKCRhYnMgLyBNSU4zMiAvIEVQU0lMT04zMikgKiBNSU4zMiAqIEVQU0lMT04zMjtcbiAgYSA9ICgxICsgRVBTSUxPTjMyIC8gRVBTSUxPTikgKiAkYWJzO1xuICByZXN1bHQgPSBhIC0gKGEgLSAkYWJzKTtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXNlbGYtY29tcGFyZVxuICBpZiAocmVzdWx0ID4gTUFYMzIgfHwgcmVzdWx0ICE9IHJlc3VsdCkgcmV0dXJuICRzaWduICogSW5maW5pdHk7XG4gIHJldHVybiAkc2lnbiAqIHJlc3VsdDtcbn07XG4iLCIvLyAyMC4yLjIuMjAgTWF0aC5sb2cxcCh4KVxubW9kdWxlLmV4cG9ydHMgPSBNYXRoLmxvZzFwIHx8IGZ1bmN0aW9uIGxvZzFwKHgpIHtcbiAgcmV0dXJuICh4ID0gK3gpID4gLTFlLTggJiYgeCA8IDFlLTggPyB4IC0geCAqIHggLyAyIDogTWF0aC5sb2coMSArIHgpO1xufTtcbiIsIi8vIDIwLjIuMi4yOCBNYXRoLnNpZ24oeClcbm1vZHVsZS5leHBvcnRzID0gTWF0aC5zaWduIHx8IGZ1bmN0aW9uIHNpZ24oeCkge1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tc2VsZi1jb21wYXJlXG4gIHJldHVybiAoeCA9ICt4KSA9PSAwIHx8IHggIT0geCA/IHggOiB4IDwgMCA/IC0xIDogMTtcbn07XG4iLCJ2YXIgTUVUQSA9IHJlcXVpcmUoJy4vX3VpZCcpKCdtZXRhJyk7XG52YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuL19pcy1vYmplY3QnKTtcbnZhciBoYXMgPSByZXF1aXJlKCcuL19oYXMnKTtcbnZhciBzZXREZXNjID0gcmVxdWlyZSgnLi9fb2JqZWN0LWRwJykuZjtcbnZhciBpZCA9IDA7XG52YXIgaXNFeHRlbnNpYmxlID0gT2JqZWN0LmlzRXh0ZW5zaWJsZSB8fCBmdW5jdGlvbiAoKSB7XG4gIHJldHVybiB0cnVlO1xufTtcbnZhciBGUkVFWkUgPSAhcmVxdWlyZSgnLi9fZmFpbHMnKShmdW5jdGlvbiAoKSB7XG4gIHJldHVybiBpc0V4dGVuc2libGUoT2JqZWN0LnByZXZlbnRFeHRlbnNpb25zKHt9KSk7XG59KTtcbnZhciBzZXRNZXRhID0gZnVuY3Rpb24gKGl0KSB7XG4gIHNldERlc2MoaXQsIE1FVEEsIHsgdmFsdWU6IHtcbiAgICBpOiAnTycgKyArK2lkLCAvLyBvYmplY3QgSURcbiAgICB3OiB7fSAgICAgICAgICAvLyB3ZWFrIGNvbGxlY3Rpb25zIElEc1xuICB9IH0pO1xufTtcbnZhciBmYXN0S2V5ID0gZnVuY3Rpb24gKGl0LCBjcmVhdGUpIHtcbiAgLy8gcmV0dXJuIHByaW1pdGl2ZSB3aXRoIHByZWZpeFxuICBpZiAoIWlzT2JqZWN0KGl0KSkgcmV0dXJuIHR5cGVvZiBpdCA9PSAnc3ltYm9sJyA/IGl0IDogKHR5cGVvZiBpdCA9PSAnc3RyaW5nJyA/ICdTJyA6ICdQJykgKyBpdDtcbiAgaWYgKCFoYXMoaXQsIE1FVEEpKSB7XG4gICAgLy8gY2FuJ3Qgc2V0IG1ldGFkYXRhIHRvIHVuY2F1Z2h0IGZyb3plbiBvYmplY3RcbiAgICBpZiAoIWlzRXh0ZW5zaWJsZShpdCkpIHJldHVybiAnRic7XG4gICAgLy8gbm90IG5lY2Vzc2FyeSB0byBhZGQgbWV0YWRhdGFcbiAgICBpZiAoIWNyZWF0ZSkgcmV0dXJuICdFJztcbiAgICAvLyBhZGQgbWlzc2luZyBtZXRhZGF0YVxuICAgIHNldE1ldGEoaXQpO1xuICAvLyByZXR1cm4gb2JqZWN0IElEXG4gIH0gcmV0dXJuIGl0W01FVEFdLmk7XG59O1xudmFyIGdldFdlYWsgPSBmdW5jdGlvbiAoaXQsIGNyZWF0ZSkge1xuICBpZiAoIWhhcyhpdCwgTUVUQSkpIHtcbiAgICAvLyBjYW4ndCBzZXQgbWV0YWRhdGEgdG8gdW5jYXVnaHQgZnJvemVuIG9iamVjdFxuICAgIGlmICghaXNFeHRlbnNpYmxlKGl0KSkgcmV0dXJuIHRydWU7XG4gICAgLy8gbm90IG5lY2Vzc2FyeSB0byBhZGQgbWV0YWRhdGFcbiAgICBpZiAoIWNyZWF0ZSkgcmV0dXJuIGZhbHNlO1xuICAgIC8vIGFkZCBtaXNzaW5nIG1ldGFkYXRhXG4gICAgc2V0TWV0YShpdCk7XG4gIC8vIHJldHVybiBoYXNoIHdlYWsgY29sbGVjdGlvbnMgSURzXG4gIH0gcmV0dXJuIGl0W01FVEFdLnc7XG59O1xuLy8gYWRkIG1ldGFkYXRhIG9uIGZyZWV6ZS1mYW1pbHkgbWV0aG9kcyBjYWxsaW5nXG52YXIgb25GcmVlemUgPSBmdW5jdGlvbiAoaXQpIHtcbiAgaWYgKEZSRUVaRSAmJiBtZXRhLk5FRUQgJiYgaXNFeHRlbnNpYmxlKGl0KSAmJiAhaGFzKGl0LCBNRVRBKSkgc2V0TWV0YShpdCk7XG4gIHJldHVybiBpdDtcbn07XG52YXIgbWV0YSA9IG1vZHVsZS5leHBvcnRzID0ge1xuICBLRVk6IE1FVEEsXG4gIE5FRUQ6IGZhbHNlLFxuICBmYXN0S2V5OiBmYXN0S2V5LFxuICBnZXRXZWFrOiBnZXRXZWFrLFxuICBvbkZyZWV6ZTogb25GcmVlemVcbn07XG4iLCJ2YXIgZ2xvYmFsID0gcmVxdWlyZSgnLi9fZ2xvYmFsJyk7XG52YXIgbWFjcm90YXNrID0gcmVxdWlyZSgnLi9fdGFzaycpLnNldDtcbnZhciBPYnNlcnZlciA9IGdsb2JhbC5NdXRhdGlvbk9ic2VydmVyIHx8IGdsb2JhbC5XZWJLaXRNdXRhdGlvbk9ic2VydmVyO1xudmFyIHByb2Nlc3MgPSBnbG9iYWwucHJvY2VzcztcbnZhciBQcm9taXNlID0gZ2xvYmFsLlByb21pc2U7XG52YXIgaXNOb2RlID0gcmVxdWlyZSgnLi9fY29mJykocHJvY2VzcykgPT0gJ3Byb2Nlc3MnO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIGhlYWQsIGxhc3QsIG5vdGlmeTtcblxuICB2YXIgZmx1c2ggPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIHBhcmVudCwgZm47XG4gICAgaWYgKGlzTm9kZSAmJiAocGFyZW50ID0gcHJvY2Vzcy5kb21haW4pKSBwYXJlbnQuZXhpdCgpO1xuICAgIHdoaWxlIChoZWFkKSB7XG4gICAgICBmbiA9IGhlYWQuZm47XG4gICAgICBoZWFkID0gaGVhZC5uZXh0O1xuICAgICAgdHJ5IHtcbiAgICAgICAgZm4oKTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgaWYgKGhlYWQpIG5vdGlmeSgpO1xuICAgICAgICBlbHNlIGxhc3QgPSB1bmRlZmluZWQ7XG4gICAgICAgIHRocm93IGU7XG4gICAgICB9XG4gICAgfSBsYXN0ID0gdW5kZWZpbmVkO1xuICAgIGlmIChwYXJlbnQpIHBhcmVudC5lbnRlcigpO1xuICB9O1xuXG4gIC8vIE5vZGUuanNcbiAgaWYgKGlzTm9kZSkge1xuICAgIG5vdGlmeSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgIHByb2Nlc3MubmV4dFRpY2soZmx1c2gpO1xuICAgIH07XG4gIC8vIGJyb3dzZXJzIHdpdGggTXV0YXRpb25PYnNlcnZlciwgZXhjZXB0IGlPUyBTYWZhcmkgLSBodHRwczovL2dpdGh1Yi5jb20vemxvaXJvY2svY29yZS1qcy9pc3N1ZXMvMzM5XG4gIH0gZWxzZSBpZiAoT2JzZXJ2ZXIgJiYgIShnbG9iYWwubmF2aWdhdG9yICYmIGdsb2JhbC5uYXZpZ2F0b3Iuc3RhbmRhbG9uZSkpIHtcbiAgICB2YXIgdG9nZ2xlID0gdHJ1ZTtcbiAgICB2YXIgbm9kZSA9IGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKCcnKTtcbiAgICBuZXcgT2JzZXJ2ZXIoZmx1c2gpLm9ic2VydmUobm9kZSwgeyBjaGFyYWN0ZXJEYXRhOiB0cnVlIH0pOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLW5ld1xuICAgIG5vdGlmeSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgIG5vZGUuZGF0YSA9IHRvZ2dsZSA9ICF0b2dnbGU7XG4gICAgfTtcbiAgLy8gZW52aXJvbm1lbnRzIHdpdGggbWF5YmUgbm9uLWNvbXBsZXRlbHkgY29ycmVjdCwgYnV0IGV4aXN0ZW50IFByb21pc2VcbiAgfSBlbHNlIGlmIChQcm9taXNlICYmIFByb21pc2UucmVzb2x2ZSkge1xuICAgIC8vIFByb21pc2UucmVzb2x2ZSB3aXRob3V0IGFuIGFyZ3VtZW50IHRocm93cyBhbiBlcnJvciBpbiBMRyBXZWJPUyAyXG4gICAgdmFyIHByb21pc2UgPSBQcm9taXNlLnJlc29sdmUodW5kZWZpbmVkKTtcbiAgICBub3RpZnkgPSBmdW5jdGlvbiAoKSB7XG4gICAgICBwcm9taXNlLnRoZW4oZmx1c2gpO1xuICAgIH07XG4gIC8vIGZvciBvdGhlciBlbnZpcm9ubWVudHMgLSBtYWNyb3Rhc2sgYmFzZWQgb246XG4gIC8vIC0gc2V0SW1tZWRpYXRlXG4gIC8vIC0gTWVzc2FnZUNoYW5uZWxcbiAgLy8gLSB3aW5kb3cucG9zdE1lc3NhZ1xuICAvLyAtIG9ucmVhZHlzdGF0ZWNoYW5nZVxuICAvLyAtIHNldFRpbWVvdXRcbiAgfSBlbHNlIHtcbiAgICBub3RpZnkgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAvLyBzdHJhbmdlIElFICsgd2VicGFjayBkZXYgc2VydmVyIGJ1ZyAtIHVzZSAuY2FsbChnbG9iYWwpXG4gICAgICBtYWNyb3Rhc2suY2FsbChnbG9iYWwsIGZsdXNoKTtcbiAgICB9O1xuICB9XG5cbiAgcmV0dXJuIGZ1bmN0aW9uIChmbikge1xuICAgIHZhciB0YXNrID0geyBmbjogZm4sIG5leHQ6IHVuZGVmaW5lZCB9O1xuICAgIGlmIChsYXN0KSBsYXN0Lm5leHQgPSB0YXNrO1xuICAgIGlmICghaGVhZCkge1xuICAgICAgaGVhZCA9IHRhc2s7XG4gICAgICBub3RpZnkoKTtcbiAgICB9IGxhc3QgPSB0YXNrO1xuICB9O1xufTtcbiIsIid1c2Ugc3RyaWN0Jztcbi8vIDI1LjQuMS41IE5ld1Byb21pc2VDYXBhYmlsaXR5KEMpXG52YXIgYUZ1bmN0aW9uID0gcmVxdWlyZSgnLi9fYS1mdW5jdGlvbicpO1xuXG5mdW5jdGlvbiBQcm9taXNlQ2FwYWJpbGl0eShDKSB7XG4gIHZhciByZXNvbHZlLCByZWplY3Q7XG4gIHRoaXMucHJvbWlzZSA9IG5ldyBDKGZ1bmN0aW9uICgkJHJlc29sdmUsICQkcmVqZWN0KSB7XG4gICAgaWYgKHJlc29sdmUgIT09IHVuZGVmaW5lZCB8fCByZWplY3QgIT09IHVuZGVmaW5lZCkgdGhyb3cgVHlwZUVycm9yKCdCYWQgUHJvbWlzZSBjb25zdHJ1Y3RvcicpO1xuICAgIHJlc29sdmUgPSAkJHJlc29sdmU7XG4gICAgcmVqZWN0ID0gJCRyZWplY3Q7XG4gIH0pO1xuICB0aGlzLnJlc29sdmUgPSBhRnVuY3Rpb24ocmVzb2x2ZSk7XG4gIHRoaXMucmVqZWN0ID0gYUZ1bmN0aW9uKHJlamVjdCk7XG59XG5cbm1vZHVsZS5leHBvcnRzLmYgPSBmdW5jdGlvbiAoQykge1xuICByZXR1cm4gbmV3IFByb21pc2VDYXBhYmlsaXR5KEMpO1xufTtcbiIsIid1c2Ugc3RyaWN0Jztcbi8vIDE5LjEuMi4xIE9iamVjdC5hc3NpZ24odGFyZ2V0LCBzb3VyY2UsIC4uLilcbnZhciBnZXRLZXlzID0gcmVxdWlyZSgnLi9fb2JqZWN0LWtleXMnKTtcbnZhciBnT1BTID0gcmVxdWlyZSgnLi9fb2JqZWN0LWdvcHMnKTtcbnZhciBwSUUgPSByZXF1aXJlKCcuL19vYmplY3QtcGllJyk7XG52YXIgdG9PYmplY3QgPSByZXF1aXJlKCcuL190by1vYmplY3QnKTtcbnZhciBJT2JqZWN0ID0gcmVxdWlyZSgnLi9faW9iamVjdCcpO1xudmFyICRhc3NpZ24gPSBPYmplY3QuYXNzaWduO1xuXG4vLyBzaG91bGQgd29yayB3aXRoIHN5bWJvbHMgYW5kIHNob3VsZCBoYXZlIGRldGVybWluaXN0aWMgcHJvcGVydHkgb3JkZXIgKFY4IGJ1Zylcbm1vZHVsZS5leHBvcnRzID0gISRhc3NpZ24gfHwgcmVxdWlyZSgnLi9fZmFpbHMnKShmdW5jdGlvbiAoKSB7XG4gIHZhciBBID0ge307XG4gIHZhciBCID0ge307XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby11bmRlZlxuICB2YXIgUyA9IFN5bWJvbCgpO1xuICB2YXIgSyA9ICdhYmNkZWZnaGlqa2xtbm9wcXJzdCc7XG4gIEFbU10gPSA3O1xuICBLLnNwbGl0KCcnKS5mb3JFYWNoKGZ1bmN0aW9uIChrKSB7IEJba10gPSBrOyB9KTtcbiAgcmV0dXJuICRhc3NpZ24oe30sIEEpW1NdICE9IDcgfHwgT2JqZWN0LmtleXMoJGFzc2lnbih7fSwgQikpLmpvaW4oJycpICE9IEs7XG59KSA/IGZ1bmN0aW9uIGFzc2lnbih0YXJnZXQsIHNvdXJjZSkgeyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXVudXNlZC12YXJzXG4gIHZhciBUID0gdG9PYmplY3QodGFyZ2V0KTtcbiAgdmFyIGFMZW4gPSBhcmd1bWVudHMubGVuZ3RoO1xuICB2YXIgaW5kZXggPSAxO1xuICB2YXIgZ2V0U3ltYm9scyA9IGdPUFMuZjtcbiAgdmFyIGlzRW51bSA9IHBJRS5mO1xuICB3aGlsZSAoYUxlbiA+IGluZGV4KSB7XG4gICAgdmFyIFMgPSBJT2JqZWN0KGFyZ3VtZW50c1tpbmRleCsrXSk7XG4gICAgdmFyIGtleXMgPSBnZXRTeW1ib2xzID8gZ2V0S2V5cyhTKS5jb25jYXQoZ2V0U3ltYm9scyhTKSkgOiBnZXRLZXlzKFMpO1xuICAgIHZhciBsZW5ndGggPSBrZXlzLmxlbmd0aDtcbiAgICB2YXIgaiA9IDA7XG4gICAgdmFyIGtleTtcbiAgICB3aGlsZSAobGVuZ3RoID4gaikgaWYgKGlzRW51bS5jYWxsKFMsIGtleSA9IGtleXNbaisrXSkpIFRba2V5XSA9IFNba2V5XTtcbiAgfSByZXR1cm4gVDtcbn0gOiAkYXNzaWduO1xuIiwiLy8gMTkuMS4yLjIgLyAxNS4yLjMuNSBPYmplY3QuY3JlYXRlKE8gWywgUHJvcGVydGllc10pXG52YXIgYW5PYmplY3QgPSByZXF1aXJlKCcuL19hbi1vYmplY3QnKTtcbnZhciBkUHMgPSByZXF1aXJlKCcuL19vYmplY3QtZHBzJyk7XG52YXIgZW51bUJ1Z0tleXMgPSByZXF1aXJlKCcuL19lbnVtLWJ1Zy1rZXlzJyk7XG52YXIgSUVfUFJPVE8gPSByZXF1aXJlKCcuL19zaGFyZWQta2V5JykoJ0lFX1BST1RPJyk7XG52YXIgRW1wdHkgPSBmdW5jdGlvbiAoKSB7IC8qIGVtcHR5ICovIH07XG52YXIgUFJPVE9UWVBFID0gJ3Byb3RvdHlwZSc7XG5cbi8vIENyZWF0ZSBvYmplY3Qgd2l0aCBmYWtlIGBudWxsYCBwcm90b3R5cGU6IHVzZSBpZnJhbWUgT2JqZWN0IHdpdGggY2xlYXJlZCBwcm90b3R5cGVcbnZhciBjcmVhdGVEaWN0ID0gZnVuY3Rpb24gKCkge1xuICAvLyBUaHJhc2gsIHdhc3RlIGFuZCBzb2RvbXk6IElFIEdDIGJ1Z1xuICB2YXIgaWZyYW1lID0gcmVxdWlyZSgnLi9fZG9tLWNyZWF0ZScpKCdpZnJhbWUnKTtcbiAgdmFyIGkgPSBlbnVtQnVnS2V5cy5sZW5ndGg7XG4gIHZhciBsdCA9ICc8JztcbiAgdmFyIGd0ID0gJz4nO1xuICB2YXIgaWZyYW1lRG9jdW1lbnQ7XG4gIGlmcmFtZS5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICByZXF1aXJlKCcuL19odG1sJykuYXBwZW5kQ2hpbGQoaWZyYW1lKTtcbiAgaWZyYW1lLnNyYyA9ICdqYXZhc2NyaXB0Oic7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tc2NyaXB0LXVybFxuICAvLyBjcmVhdGVEaWN0ID0gaWZyYW1lLmNvbnRlbnRXaW5kb3cuT2JqZWN0O1xuICAvLyBodG1sLnJlbW92ZUNoaWxkKGlmcmFtZSk7XG4gIGlmcmFtZURvY3VtZW50ID0gaWZyYW1lLmNvbnRlbnRXaW5kb3cuZG9jdW1lbnQ7XG4gIGlmcmFtZURvY3VtZW50Lm9wZW4oKTtcbiAgaWZyYW1lRG9jdW1lbnQud3JpdGUobHQgKyAnc2NyaXB0JyArIGd0ICsgJ2RvY3VtZW50LkY9T2JqZWN0JyArIGx0ICsgJy9zY3JpcHQnICsgZ3QpO1xuICBpZnJhbWVEb2N1bWVudC5jbG9zZSgpO1xuICBjcmVhdGVEaWN0ID0gaWZyYW1lRG9jdW1lbnQuRjtcbiAgd2hpbGUgKGktLSkgZGVsZXRlIGNyZWF0ZURpY3RbUFJPVE9UWVBFXVtlbnVtQnVnS2V5c1tpXV07XG4gIHJldHVybiBjcmVhdGVEaWN0KCk7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IE9iamVjdC5jcmVhdGUgfHwgZnVuY3Rpb24gY3JlYXRlKE8sIFByb3BlcnRpZXMpIHtcbiAgdmFyIHJlc3VsdDtcbiAgaWYgKE8gIT09IG51bGwpIHtcbiAgICBFbXB0eVtQUk9UT1RZUEVdID0gYW5PYmplY3QoTyk7XG4gICAgcmVzdWx0ID0gbmV3IEVtcHR5KCk7XG4gICAgRW1wdHlbUFJPVE9UWVBFXSA9IG51bGw7XG4gICAgLy8gYWRkIFwiX19wcm90b19fXCIgZm9yIE9iamVjdC5nZXRQcm90b3R5cGVPZiBwb2x5ZmlsbFxuICAgIHJlc3VsdFtJRV9QUk9UT10gPSBPO1xuICB9IGVsc2UgcmVzdWx0ID0gY3JlYXRlRGljdCgpO1xuICByZXR1cm4gUHJvcGVydGllcyA9PT0gdW5kZWZpbmVkID8gcmVzdWx0IDogZFBzKHJlc3VsdCwgUHJvcGVydGllcyk7XG59O1xuIiwidmFyIGFuT2JqZWN0ID0gcmVxdWlyZSgnLi9fYW4tb2JqZWN0Jyk7XG52YXIgSUU4X0RPTV9ERUZJTkUgPSByZXF1aXJlKCcuL19pZTgtZG9tLWRlZmluZScpO1xudmFyIHRvUHJpbWl0aXZlID0gcmVxdWlyZSgnLi9fdG8tcHJpbWl0aXZlJyk7XG52YXIgZFAgPSBPYmplY3QuZGVmaW5lUHJvcGVydHk7XG5cbmV4cG9ydHMuZiA9IHJlcXVpcmUoJy4vX2Rlc2NyaXB0b3JzJykgPyBPYmplY3QuZGVmaW5lUHJvcGVydHkgOiBmdW5jdGlvbiBkZWZpbmVQcm9wZXJ0eShPLCBQLCBBdHRyaWJ1dGVzKSB7XG4gIGFuT2JqZWN0KE8pO1xuICBQID0gdG9QcmltaXRpdmUoUCwgdHJ1ZSk7XG4gIGFuT2JqZWN0KEF0dHJpYnV0ZXMpO1xuICBpZiAoSUU4X0RPTV9ERUZJTkUpIHRyeSB7XG4gICAgcmV0dXJuIGRQKE8sIFAsIEF0dHJpYnV0ZXMpO1xuICB9IGNhdGNoIChlKSB7IC8qIGVtcHR5ICovIH1cbiAgaWYgKCdnZXQnIGluIEF0dHJpYnV0ZXMgfHwgJ3NldCcgaW4gQXR0cmlidXRlcykgdGhyb3cgVHlwZUVycm9yKCdBY2Nlc3NvcnMgbm90IHN1cHBvcnRlZCEnKTtcbiAgaWYgKCd2YWx1ZScgaW4gQXR0cmlidXRlcykgT1tQXSA9IEF0dHJpYnV0ZXMudmFsdWU7XG4gIHJldHVybiBPO1xufTtcbiIsInZhciBkUCA9IHJlcXVpcmUoJy4vX29iamVjdC1kcCcpO1xudmFyIGFuT2JqZWN0ID0gcmVxdWlyZSgnLi9fYW4tb2JqZWN0Jyk7XG52YXIgZ2V0S2V5cyA9IHJlcXVpcmUoJy4vX29iamVjdC1rZXlzJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi9fZGVzY3JpcHRvcnMnKSA/IE9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzIDogZnVuY3Rpb24gZGVmaW5lUHJvcGVydGllcyhPLCBQcm9wZXJ0aWVzKSB7XG4gIGFuT2JqZWN0KE8pO1xuICB2YXIga2V5cyA9IGdldEtleXMoUHJvcGVydGllcyk7XG4gIHZhciBsZW5ndGggPSBrZXlzLmxlbmd0aDtcbiAgdmFyIGkgPSAwO1xuICB2YXIgUDtcbiAgd2hpbGUgKGxlbmd0aCA+IGkpIGRQLmYoTywgUCA9IGtleXNbaSsrXSwgUHJvcGVydGllc1tQXSk7XG4gIHJldHVybiBPO1xufTtcbiIsInZhciBwSUUgPSByZXF1aXJlKCcuL19vYmplY3QtcGllJyk7XG52YXIgY3JlYXRlRGVzYyA9IHJlcXVpcmUoJy4vX3Byb3BlcnR5LWRlc2MnKTtcbnZhciB0b0lPYmplY3QgPSByZXF1aXJlKCcuL190by1pb2JqZWN0Jyk7XG52YXIgdG9QcmltaXRpdmUgPSByZXF1aXJlKCcuL190by1wcmltaXRpdmUnKTtcbnZhciBoYXMgPSByZXF1aXJlKCcuL19oYXMnKTtcbnZhciBJRThfRE9NX0RFRklORSA9IHJlcXVpcmUoJy4vX2llOC1kb20tZGVmaW5lJyk7XG52YXIgZ09QRCA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3I7XG5cbmV4cG9ydHMuZiA9IHJlcXVpcmUoJy4vX2Rlc2NyaXB0b3JzJykgPyBnT1BEIDogZnVuY3Rpb24gZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKE8sIFApIHtcbiAgTyA9IHRvSU9iamVjdChPKTtcbiAgUCA9IHRvUHJpbWl0aXZlKFAsIHRydWUpO1xuICBpZiAoSUU4X0RPTV9ERUZJTkUpIHRyeSB7XG4gICAgcmV0dXJuIGdPUEQoTywgUCk7XG4gIH0gY2F0Y2ggKGUpIHsgLyogZW1wdHkgKi8gfVxuICBpZiAoaGFzKE8sIFApKSByZXR1cm4gY3JlYXRlRGVzYyghcElFLmYuY2FsbChPLCBQKSwgT1tQXSk7XG59O1xuIiwiLy8gZmFsbGJhY2sgZm9yIElFMTEgYnVnZ3kgT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMgd2l0aCBpZnJhbWUgYW5kIHdpbmRvd1xudmFyIHRvSU9iamVjdCA9IHJlcXVpcmUoJy4vX3RvLWlvYmplY3QnKTtcbnZhciBnT1BOID0gcmVxdWlyZSgnLi9fb2JqZWN0LWdvcG4nKS5mO1xudmFyIHRvU3RyaW5nID0ge30udG9TdHJpbmc7XG5cbnZhciB3aW5kb3dOYW1lcyA9IHR5cGVvZiB3aW5kb3cgPT0gJ29iamVjdCcgJiYgd2luZG93ICYmIE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzXG4gID8gT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMod2luZG93KSA6IFtdO1xuXG52YXIgZ2V0V2luZG93TmFtZXMgPSBmdW5jdGlvbiAoaXQpIHtcbiAgdHJ5IHtcbiAgICByZXR1cm4gZ09QTihpdCk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICByZXR1cm4gd2luZG93TmFtZXMuc2xpY2UoKTtcbiAgfVxufTtcblxubW9kdWxlLmV4cG9ydHMuZiA9IGZ1bmN0aW9uIGdldE93blByb3BlcnR5TmFtZXMoaXQpIHtcbiAgcmV0dXJuIHdpbmRvd05hbWVzICYmIHRvU3RyaW5nLmNhbGwoaXQpID09ICdbb2JqZWN0IFdpbmRvd10nID8gZ2V0V2luZG93TmFtZXMoaXQpIDogZ09QTih0b0lPYmplY3QoaXQpKTtcbn07XG4iLCIvLyAxOS4xLjIuNyAvIDE1LjIuMy40IE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKE8pXG52YXIgJGtleXMgPSByZXF1aXJlKCcuL19vYmplY3Qta2V5cy1pbnRlcm5hbCcpO1xudmFyIGhpZGRlbktleXMgPSByZXF1aXJlKCcuL19lbnVtLWJ1Zy1rZXlzJykuY29uY2F0KCdsZW5ndGgnLCAncHJvdG90eXBlJyk7XG5cbmV4cG9ydHMuZiA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzIHx8IGZ1bmN0aW9uIGdldE93blByb3BlcnR5TmFtZXMoTykge1xuICByZXR1cm4gJGtleXMoTywgaGlkZGVuS2V5cyk7XG59O1xuIiwiZXhwb3J0cy5mID0gT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scztcbiIsIi8vIDE5LjEuMi45IC8gMTUuMi4zLjIgT2JqZWN0LmdldFByb3RvdHlwZU9mKE8pXG52YXIgaGFzID0gcmVxdWlyZSgnLi9faGFzJyk7XG52YXIgdG9PYmplY3QgPSByZXF1aXJlKCcuL190by1vYmplY3QnKTtcbnZhciBJRV9QUk9UTyA9IHJlcXVpcmUoJy4vX3NoYXJlZC1rZXknKSgnSUVfUFJPVE8nKTtcbnZhciBPYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGU7XG5cbm1vZHVsZS5leHBvcnRzID0gT2JqZWN0LmdldFByb3RvdHlwZU9mIHx8IGZ1bmN0aW9uIChPKSB7XG4gIE8gPSB0b09iamVjdChPKTtcbiAgaWYgKGhhcyhPLCBJRV9QUk9UTykpIHJldHVybiBPW0lFX1BST1RPXTtcbiAgaWYgKHR5cGVvZiBPLmNvbnN0cnVjdG9yID09ICdmdW5jdGlvbicgJiYgTyBpbnN0YW5jZW9mIE8uY29uc3RydWN0b3IpIHtcbiAgICByZXR1cm4gTy5jb25zdHJ1Y3Rvci5wcm90b3R5cGU7XG4gIH0gcmV0dXJuIE8gaW5zdGFuY2VvZiBPYmplY3QgPyBPYmplY3RQcm90byA6IG51bGw7XG59O1xuIiwidmFyIGhhcyA9IHJlcXVpcmUoJy4vX2hhcycpO1xudmFyIHRvSU9iamVjdCA9IHJlcXVpcmUoJy4vX3RvLWlvYmplY3QnKTtcbnZhciBhcnJheUluZGV4T2YgPSByZXF1aXJlKCcuL19hcnJheS1pbmNsdWRlcycpKGZhbHNlKTtcbnZhciBJRV9QUk9UTyA9IHJlcXVpcmUoJy4vX3NoYXJlZC1rZXknKSgnSUVfUFJPVE8nKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAob2JqZWN0LCBuYW1lcykge1xuICB2YXIgTyA9IHRvSU9iamVjdChvYmplY3QpO1xuICB2YXIgaSA9IDA7XG4gIHZhciByZXN1bHQgPSBbXTtcbiAgdmFyIGtleTtcbiAgZm9yIChrZXkgaW4gTykgaWYgKGtleSAhPSBJRV9QUk9UTykgaGFzKE8sIGtleSkgJiYgcmVzdWx0LnB1c2goa2V5KTtcbiAgLy8gRG9uJ3QgZW51bSBidWcgJiBoaWRkZW4ga2V5c1xuICB3aGlsZSAobmFtZXMubGVuZ3RoID4gaSkgaWYgKGhhcyhPLCBrZXkgPSBuYW1lc1tpKytdKSkge1xuICAgIH5hcnJheUluZGV4T2YocmVzdWx0LCBrZXkpIHx8IHJlc3VsdC5wdXNoKGtleSk7XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn07XG4iLCIvLyAxOS4xLjIuMTQgLyAxNS4yLjMuMTQgT2JqZWN0LmtleXMoTylcbnZhciAka2V5cyA9IHJlcXVpcmUoJy4vX29iamVjdC1rZXlzLWludGVybmFsJyk7XG52YXIgZW51bUJ1Z0tleXMgPSByZXF1aXJlKCcuL19lbnVtLWJ1Zy1rZXlzJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gT2JqZWN0LmtleXMgfHwgZnVuY3Rpb24ga2V5cyhPKSB7XG4gIHJldHVybiAka2V5cyhPLCBlbnVtQnVnS2V5cyk7XG59O1xuIiwiZXhwb3J0cy5mID0ge30ucHJvcGVydHlJc0VudW1lcmFibGU7XG4iLCIvLyBtb3N0IE9iamVjdCBtZXRob2RzIGJ5IEVTNiBzaG91bGQgYWNjZXB0IHByaW1pdGl2ZXNcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgY29yZSA9IHJlcXVpcmUoJy4vX2NvcmUnKTtcbnZhciBmYWlscyA9IHJlcXVpcmUoJy4vX2ZhaWxzJyk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChLRVksIGV4ZWMpIHtcbiAgdmFyIGZuID0gKGNvcmUuT2JqZWN0IHx8IHt9KVtLRVldIHx8IE9iamVjdFtLRVldO1xuICB2YXIgZXhwID0ge307XG4gIGV4cFtLRVldID0gZXhlYyhmbik7XG4gICRleHBvcnQoJGV4cG9ydC5TICsgJGV4cG9ydC5GICogZmFpbHMoZnVuY3Rpb24gKCkgeyBmbigxKTsgfSksICdPYmplY3QnLCBleHApO1xufTtcbiIsInZhciBnZXRLZXlzID0gcmVxdWlyZSgnLi9fb2JqZWN0LWtleXMnKTtcbnZhciB0b0lPYmplY3QgPSByZXF1aXJlKCcuL190by1pb2JqZWN0Jyk7XG52YXIgaXNFbnVtID0gcmVxdWlyZSgnLi9fb2JqZWN0LXBpZScpLmY7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChpc0VudHJpZXMpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIChpdCkge1xuICAgIHZhciBPID0gdG9JT2JqZWN0KGl0KTtcbiAgICB2YXIga2V5cyA9IGdldEtleXMoTyk7XG4gICAgdmFyIGxlbmd0aCA9IGtleXMubGVuZ3RoO1xuICAgIHZhciBpID0gMDtcbiAgICB2YXIgcmVzdWx0ID0gW107XG4gICAgdmFyIGtleTtcbiAgICB3aGlsZSAobGVuZ3RoID4gaSkgaWYgKGlzRW51bS5jYWxsKE8sIGtleSA9IGtleXNbaSsrXSkpIHtcbiAgICAgIHJlc3VsdC5wdXNoKGlzRW50cmllcyA/IFtrZXksIE9ba2V5XV0gOiBPW2tleV0pO1xuICAgIH0gcmV0dXJuIHJlc3VsdDtcbiAgfTtcbn07XG4iLCIvLyBhbGwgb2JqZWN0IGtleXMsIGluY2x1ZGVzIG5vbi1lbnVtZXJhYmxlIGFuZCBzeW1ib2xzXG52YXIgZ09QTiA9IHJlcXVpcmUoJy4vX29iamVjdC1nb3BuJyk7XG52YXIgZ09QUyA9IHJlcXVpcmUoJy4vX29iamVjdC1nb3BzJyk7XG52YXIgYW5PYmplY3QgPSByZXF1aXJlKCcuL19hbi1vYmplY3QnKTtcbnZhciBSZWZsZWN0ID0gcmVxdWlyZSgnLi9fZ2xvYmFsJykuUmVmbGVjdDtcbm1vZHVsZS5leHBvcnRzID0gUmVmbGVjdCAmJiBSZWZsZWN0Lm93bktleXMgfHwgZnVuY3Rpb24gb3duS2V5cyhpdCkge1xuICB2YXIga2V5cyA9IGdPUE4uZihhbk9iamVjdChpdCkpO1xuICB2YXIgZ2V0U3ltYm9scyA9IGdPUFMuZjtcbiAgcmV0dXJuIGdldFN5bWJvbHMgPyBrZXlzLmNvbmNhdChnZXRTeW1ib2xzKGl0KSkgOiBrZXlzO1xufTtcbiIsInZhciAkcGFyc2VGbG9hdCA9IHJlcXVpcmUoJy4vX2dsb2JhbCcpLnBhcnNlRmxvYXQ7XG52YXIgJHRyaW0gPSByZXF1aXJlKCcuL19zdHJpbmctdHJpbScpLnRyaW07XG5cbm1vZHVsZS5leHBvcnRzID0gMSAvICRwYXJzZUZsb2F0KHJlcXVpcmUoJy4vX3N0cmluZy13cycpICsgJy0wJykgIT09IC1JbmZpbml0eSA/IGZ1bmN0aW9uIHBhcnNlRmxvYXQoc3RyKSB7XG4gIHZhciBzdHJpbmcgPSAkdHJpbShTdHJpbmcoc3RyKSwgMyk7XG4gIHZhciByZXN1bHQgPSAkcGFyc2VGbG9hdChzdHJpbmcpO1xuICByZXR1cm4gcmVzdWx0ID09PSAwICYmIHN0cmluZy5jaGFyQXQoMCkgPT0gJy0nID8gLTAgOiByZXN1bHQ7XG59IDogJHBhcnNlRmxvYXQ7XG4iLCJ2YXIgJHBhcnNlSW50ID0gcmVxdWlyZSgnLi9fZ2xvYmFsJykucGFyc2VJbnQ7XG52YXIgJHRyaW0gPSByZXF1aXJlKCcuL19zdHJpbmctdHJpbScpLnRyaW07XG52YXIgd3MgPSByZXF1aXJlKCcuL19zdHJpbmctd3MnKTtcbnZhciBoZXggPSAvXlstK10/MFt4WF0vO1xuXG5tb2R1bGUuZXhwb3J0cyA9ICRwYXJzZUludCh3cyArICcwOCcpICE9PSA4IHx8ICRwYXJzZUludCh3cyArICcweDE2JykgIT09IDIyID8gZnVuY3Rpb24gcGFyc2VJbnQoc3RyLCByYWRpeCkge1xuICB2YXIgc3RyaW5nID0gJHRyaW0oU3RyaW5nKHN0ciksIDMpO1xuICByZXR1cm4gJHBhcnNlSW50KHN0cmluZywgKHJhZGl4ID4+PiAwKSB8fCAoaGV4LnRlc3Qoc3RyaW5nKSA/IDE2IDogMTApKTtcbn0gOiAkcGFyc2VJbnQ7XG4iLCJtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChleGVjKSB7XG4gIHRyeSB7XG4gICAgcmV0dXJuIHsgZTogZmFsc2UsIHY6IGV4ZWMoKSB9O1xuICB9IGNhdGNoIChlKSB7XG4gICAgcmV0dXJuIHsgZTogdHJ1ZSwgdjogZSB9O1xuICB9XG59O1xuIiwidmFyIGFuT2JqZWN0ID0gcmVxdWlyZSgnLi9fYW4tb2JqZWN0Jyk7XG52YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuL19pcy1vYmplY3QnKTtcbnZhciBuZXdQcm9taXNlQ2FwYWJpbGl0eSA9IHJlcXVpcmUoJy4vX25ldy1wcm9taXNlLWNhcGFiaWxpdHknKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoQywgeCkge1xuICBhbk9iamVjdChDKTtcbiAgaWYgKGlzT2JqZWN0KHgpICYmIHguY29uc3RydWN0b3IgPT09IEMpIHJldHVybiB4O1xuICB2YXIgcHJvbWlzZUNhcGFiaWxpdHkgPSBuZXdQcm9taXNlQ2FwYWJpbGl0eS5mKEMpO1xuICB2YXIgcmVzb2x2ZSA9IHByb21pc2VDYXBhYmlsaXR5LnJlc29sdmU7XG4gIHJlc29sdmUoeCk7XG4gIHJldHVybiBwcm9taXNlQ2FwYWJpbGl0eS5wcm9taXNlO1xufTtcbiIsIm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGJpdG1hcCwgdmFsdWUpIHtcbiAgcmV0dXJuIHtcbiAgICBlbnVtZXJhYmxlOiAhKGJpdG1hcCAmIDEpLFxuICAgIGNvbmZpZ3VyYWJsZTogIShiaXRtYXAgJiAyKSxcbiAgICB3cml0YWJsZTogIShiaXRtYXAgJiA0KSxcbiAgICB2YWx1ZTogdmFsdWVcbiAgfTtcbn07XG4iLCJ2YXIgcmVkZWZpbmUgPSByZXF1aXJlKCcuL19yZWRlZmluZScpO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAodGFyZ2V0LCBzcmMsIHNhZmUpIHtcbiAgZm9yICh2YXIga2V5IGluIHNyYykgcmVkZWZpbmUodGFyZ2V0LCBrZXksIHNyY1trZXldLCBzYWZlKTtcbiAgcmV0dXJuIHRhcmdldDtcbn07XG4iLCJ2YXIgZ2xvYmFsID0gcmVxdWlyZSgnLi9fZ2xvYmFsJyk7XG52YXIgaGlkZSA9IHJlcXVpcmUoJy4vX2hpZGUnKTtcbnZhciBoYXMgPSByZXF1aXJlKCcuL19oYXMnKTtcbnZhciBTUkMgPSByZXF1aXJlKCcuL191aWQnKSgnc3JjJyk7XG52YXIgVE9fU1RSSU5HID0gJ3RvU3RyaW5nJztcbnZhciAkdG9TdHJpbmcgPSBGdW5jdGlvbltUT19TVFJJTkddO1xudmFyIFRQTCA9ICgnJyArICR0b1N0cmluZykuc3BsaXQoVE9fU1RSSU5HKTtcblxucmVxdWlyZSgnLi9fY29yZScpLmluc3BlY3RTb3VyY2UgPSBmdW5jdGlvbiAoaXQpIHtcbiAgcmV0dXJuICR0b1N0cmluZy5jYWxsKGl0KTtcbn07XG5cbihtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChPLCBrZXksIHZhbCwgc2FmZSkge1xuICB2YXIgaXNGdW5jdGlvbiA9IHR5cGVvZiB2YWwgPT0gJ2Z1bmN0aW9uJztcbiAgaWYgKGlzRnVuY3Rpb24pIGhhcyh2YWwsICduYW1lJykgfHwgaGlkZSh2YWwsICduYW1lJywga2V5KTtcbiAgaWYgKE9ba2V5XSA9PT0gdmFsKSByZXR1cm47XG4gIGlmIChpc0Z1bmN0aW9uKSBoYXModmFsLCBTUkMpIHx8IGhpZGUodmFsLCBTUkMsIE9ba2V5XSA/ICcnICsgT1trZXldIDogVFBMLmpvaW4oU3RyaW5nKGtleSkpKTtcbiAgaWYgKE8gPT09IGdsb2JhbCkge1xuICAgIE9ba2V5XSA9IHZhbDtcbiAgfSBlbHNlIGlmICghc2FmZSkge1xuICAgIGRlbGV0ZSBPW2tleV07XG4gICAgaGlkZShPLCBrZXksIHZhbCk7XG4gIH0gZWxzZSBpZiAoT1trZXldKSB7XG4gICAgT1trZXldID0gdmFsO1xuICB9IGVsc2Uge1xuICAgIGhpZGUoTywga2V5LCB2YWwpO1xuICB9XG4vLyBhZGQgZmFrZSBGdW5jdGlvbiN0b1N0cmluZyBmb3IgY29ycmVjdCB3b3JrIHdyYXBwZWQgbWV0aG9kcyAvIGNvbnN0cnVjdG9ycyB3aXRoIG1ldGhvZHMgbGlrZSBMb0Rhc2ggaXNOYXRpdmVcbn0pKEZ1bmN0aW9uLnByb3RvdHlwZSwgVE9fU1RSSU5HLCBmdW5jdGlvbiB0b1N0cmluZygpIHtcbiAgcmV0dXJuIHR5cGVvZiB0aGlzID09ICdmdW5jdGlvbicgJiYgdGhpc1tTUkNdIHx8ICR0b1N0cmluZy5jYWxsKHRoaXMpO1xufSk7XG4iLCIvLyA3LjIuOSBTYW1lVmFsdWUoeCwgeSlcbm1vZHVsZS5leHBvcnRzID0gT2JqZWN0LmlzIHx8IGZ1bmN0aW9uIGlzKHgsIHkpIHtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXNlbGYtY29tcGFyZVxuICByZXR1cm4geCA9PT0geSA/IHggIT09IDAgfHwgMSAvIHggPT09IDEgLyB5IDogeCAhPSB4ICYmIHkgIT0geTtcbn07XG4iLCIvLyBXb3JrcyB3aXRoIF9fcHJvdG9fXyBvbmx5LiBPbGQgdjggY2FuJ3Qgd29yayB3aXRoIG51bGwgcHJvdG8gb2JqZWN0cy5cbi8qIGVzbGludC1kaXNhYmxlIG5vLXByb3RvICovXG52YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuL19pcy1vYmplY3QnKTtcbnZhciBhbk9iamVjdCA9IHJlcXVpcmUoJy4vX2FuLW9iamVjdCcpO1xudmFyIGNoZWNrID0gZnVuY3Rpb24gKE8sIHByb3RvKSB7XG4gIGFuT2JqZWN0KE8pO1xuICBpZiAoIWlzT2JqZWN0KHByb3RvKSAmJiBwcm90byAhPT0gbnVsbCkgdGhyb3cgVHlwZUVycm9yKHByb3RvICsgXCI6IGNhbid0IHNldCBhcyBwcm90b3R5cGUhXCIpO1xufTtcbm1vZHVsZS5leHBvcnRzID0ge1xuICBzZXQ6IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fCAoJ19fcHJvdG9fXycgaW4ge30gPyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lXG4gICAgZnVuY3Rpb24gKHRlc3QsIGJ1Z2d5LCBzZXQpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHNldCA9IHJlcXVpcmUoJy4vX2N0eCcpKEZ1bmN0aW9uLmNhbGwsIHJlcXVpcmUoJy4vX29iamVjdC1nb3BkJykuZihPYmplY3QucHJvdG90eXBlLCAnX19wcm90b19fJykuc2V0LCAyKTtcbiAgICAgICAgc2V0KHRlc3QsIFtdKTtcbiAgICAgICAgYnVnZ3kgPSAhKHRlc3QgaW5zdGFuY2VvZiBBcnJheSk7XG4gICAgICB9IGNhdGNoIChlKSB7IGJ1Z2d5ID0gdHJ1ZTsgfVxuICAgICAgcmV0dXJuIGZ1bmN0aW9uIHNldFByb3RvdHlwZU9mKE8sIHByb3RvKSB7XG4gICAgICAgIGNoZWNrKE8sIHByb3RvKTtcbiAgICAgICAgaWYgKGJ1Z2d5KSBPLl9fcHJvdG9fXyA9IHByb3RvO1xuICAgICAgICBlbHNlIHNldChPLCBwcm90byk7XG4gICAgICAgIHJldHVybiBPO1xuICAgICAgfTtcbiAgICB9KHt9LCBmYWxzZSkgOiB1bmRlZmluZWQpLFxuICBjaGVjazogY2hlY2tcbn07XG4iLCIndXNlIHN0cmljdCc7XG52YXIgZ2xvYmFsID0gcmVxdWlyZSgnLi9fZ2xvYmFsJyk7XG52YXIgZFAgPSByZXF1aXJlKCcuL19vYmplY3QtZHAnKTtcbnZhciBERVNDUklQVE9SUyA9IHJlcXVpcmUoJy4vX2Rlc2NyaXB0b3JzJyk7XG52YXIgU1BFQ0lFUyA9IHJlcXVpcmUoJy4vX3drcycpKCdzcGVjaWVzJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKEtFWSkge1xuICB2YXIgQyA9IGdsb2JhbFtLRVldO1xuICBpZiAoREVTQ1JJUFRPUlMgJiYgQyAmJiAhQ1tTUEVDSUVTXSkgZFAuZihDLCBTUEVDSUVTLCB7XG4gICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpczsgfVxuICB9KTtcbn07XG4iLCJ2YXIgZGVmID0gcmVxdWlyZSgnLi9fb2JqZWN0LWRwJykuZjtcbnZhciBoYXMgPSByZXF1aXJlKCcuL19oYXMnKTtcbnZhciBUQUcgPSByZXF1aXJlKCcuL193a3MnKSgndG9TdHJpbmdUYWcnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoaXQsIHRhZywgc3RhdCkge1xuICBpZiAoaXQgJiYgIWhhcyhpdCA9IHN0YXQgPyBpdCA6IGl0LnByb3RvdHlwZSwgVEFHKSkgZGVmKGl0LCBUQUcsIHsgY29uZmlndXJhYmxlOiB0cnVlLCB2YWx1ZTogdGFnIH0pO1xufTtcbiIsInZhciBzaGFyZWQgPSByZXF1aXJlKCcuL19zaGFyZWQnKSgna2V5cycpO1xudmFyIHVpZCA9IHJlcXVpcmUoJy4vX3VpZCcpO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoa2V5KSB7XG4gIHJldHVybiBzaGFyZWRba2V5XSB8fCAoc2hhcmVkW2tleV0gPSB1aWQoa2V5KSk7XG59O1xuIiwidmFyIGNvcmUgPSByZXF1aXJlKCcuL19jb3JlJyk7XG52YXIgZ2xvYmFsID0gcmVxdWlyZSgnLi9fZ2xvYmFsJyk7XG52YXIgU0hBUkVEID0gJ19fY29yZS1qc19zaGFyZWRfXyc7XG52YXIgc3RvcmUgPSBnbG9iYWxbU0hBUkVEXSB8fCAoZ2xvYmFsW1NIQVJFRF0gPSB7fSk7XG5cbihtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChrZXksIHZhbHVlKSB7XG4gIHJldHVybiBzdG9yZVtrZXldIHx8IChzdG9yZVtrZXldID0gdmFsdWUgIT09IHVuZGVmaW5lZCA/IHZhbHVlIDoge30pO1xufSkoJ3ZlcnNpb25zJywgW10pLnB1c2goe1xuICB2ZXJzaW9uOiBjb3JlLnZlcnNpb24sXG4gIG1vZGU6IHJlcXVpcmUoJy4vX2xpYnJhcnknKSA/ICdwdXJlJyA6ICdnbG9iYWwnLFxuICBjb3B5cmlnaHQ6ICfCqSAyMDE4IERlbmlzIFB1c2hrYXJldiAoemxvaXJvY2sucnUpJ1xufSk7XG4iLCIvLyA3LjMuMjAgU3BlY2llc0NvbnN0cnVjdG9yKE8sIGRlZmF1bHRDb25zdHJ1Y3RvcilcbnZhciBhbk9iamVjdCA9IHJlcXVpcmUoJy4vX2FuLW9iamVjdCcpO1xudmFyIGFGdW5jdGlvbiA9IHJlcXVpcmUoJy4vX2EtZnVuY3Rpb24nKTtcbnZhciBTUEVDSUVTID0gcmVxdWlyZSgnLi9fd2tzJykoJ3NwZWNpZXMnKTtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKE8sIEQpIHtcbiAgdmFyIEMgPSBhbk9iamVjdChPKS5jb25zdHJ1Y3RvcjtcbiAgdmFyIFM7XG4gIHJldHVybiBDID09PSB1bmRlZmluZWQgfHwgKFMgPSBhbk9iamVjdChDKVtTUEVDSUVTXSkgPT0gdW5kZWZpbmVkID8gRCA6IGFGdW5jdGlvbihTKTtcbn07XG4iLCIndXNlIHN0cmljdCc7XG52YXIgZmFpbHMgPSByZXF1aXJlKCcuL19mYWlscycpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChtZXRob2QsIGFyZykge1xuICByZXR1cm4gISFtZXRob2QgJiYgZmFpbHMoZnVuY3Rpb24gKCkge1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby11c2VsZXNzLWNhbGxcbiAgICBhcmcgPyBtZXRob2QuY2FsbChudWxsLCBmdW5jdGlvbiAoKSB7IC8qIGVtcHR5ICovIH0sIDEpIDogbWV0aG9kLmNhbGwobnVsbCk7XG4gIH0pO1xufTtcbiIsInZhciB0b0ludGVnZXIgPSByZXF1aXJlKCcuL190by1pbnRlZ2VyJyk7XG52YXIgZGVmaW5lZCA9IHJlcXVpcmUoJy4vX2RlZmluZWQnKTtcbi8vIHRydWUgIC0+IFN0cmluZyNhdFxuLy8gZmFsc2UgLT4gU3RyaW5nI2NvZGVQb2ludEF0XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChUT19TVFJJTkcpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uICh0aGF0LCBwb3MpIHtcbiAgICB2YXIgcyA9IFN0cmluZyhkZWZpbmVkKHRoYXQpKTtcbiAgICB2YXIgaSA9IHRvSW50ZWdlcihwb3MpO1xuICAgIHZhciBsID0gcy5sZW5ndGg7XG4gICAgdmFyIGEsIGI7XG4gICAgaWYgKGkgPCAwIHx8IGkgPj0gbCkgcmV0dXJuIFRPX1NUUklORyA/ICcnIDogdW5kZWZpbmVkO1xuICAgIGEgPSBzLmNoYXJDb2RlQXQoaSk7XG4gICAgcmV0dXJuIGEgPCAweGQ4MDAgfHwgYSA+IDB4ZGJmZiB8fCBpICsgMSA9PT0gbCB8fCAoYiA9IHMuY2hhckNvZGVBdChpICsgMSkpIDwgMHhkYzAwIHx8IGIgPiAweGRmZmZcbiAgICAgID8gVE9fU1RSSU5HID8gcy5jaGFyQXQoaSkgOiBhXG4gICAgICA6IFRPX1NUUklORyA/IHMuc2xpY2UoaSwgaSArIDIpIDogKGEgLSAweGQ4MDAgPDwgMTApICsgKGIgLSAweGRjMDApICsgMHgxMDAwMDtcbiAgfTtcbn07XG4iLCIvLyBoZWxwZXIgZm9yIFN0cmluZyN7c3RhcnRzV2l0aCwgZW5kc1dpdGgsIGluY2x1ZGVzfVxudmFyIGlzUmVnRXhwID0gcmVxdWlyZSgnLi9faXMtcmVnZXhwJyk7XG52YXIgZGVmaW5lZCA9IHJlcXVpcmUoJy4vX2RlZmluZWQnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAodGhhdCwgc2VhcmNoU3RyaW5nLCBOQU1FKSB7XG4gIGlmIChpc1JlZ0V4cChzZWFyY2hTdHJpbmcpKSB0aHJvdyBUeXBlRXJyb3IoJ1N0cmluZyMnICsgTkFNRSArIFwiIGRvZXNuJ3QgYWNjZXB0IHJlZ2V4IVwiKTtcbiAgcmV0dXJuIFN0cmluZyhkZWZpbmVkKHRoYXQpKTtcbn07XG4iLCJ2YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyIGZhaWxzID0gcmVxdWlyZSgnLi9fZmFpbHMnKTtcbnZhciBkZWZpbmVkID0gcmVxdWlyZSgnLi9fZGVmaW5lZCcpO1xudmFyIHF1b3QgPSAvXCIvZztcbi8vIEIuMi4zLjIuMSBDcmVhdGVIVE1MKHN0cmluZywgdGFnLCBhdHRyaWJ1dGUsIHZhbHVlKVxudmFyIGNyZWF0ZUhUTUwgPSBmdW5jdGlvbiAoc3RyaW5nLCB0YWcsIGF0dHJpYnV0ZSwgdmFsdWUpIHtcbiAgdmFyIFMgPSBTdHJpbmcoZGVmaW5lZChzdHJpbmcpKTtcbiAgdmFyIHAxID0gJzwnICsgdGFnO1xuICBpZiAoYXR0cmlidXRlICE9PSAnJykgcDEgKz0gJyAnICsgYXR0cmlidXRlICsgJz1cIicgKyBTdHJpbmcodmFsdWUpLnJlcGxhY2UocXVvdCwgJyZxdW90OycpICsgJ1wiJztcbiAgcmV0dXJuIHAxICsgJz4nICsgUyArICc8LycgKyB0YWcgKyAnPic7XG59O1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoTkFNRSwgZXhlYykge1xuICB2YXIgTyA9IHt9O1xuICBPW05BTUVdID0gZXhlYyhjcmVhdGVIVE1MKTtcbiAgJGV4cG9ydCgkZXhwb3J0LlAgKyAkZXhwb3J0LkYgKiBmYWlscyhmdW5jdGlvbiAoKSB7XG4gICAgdmFyIHRlc3QgPSAnJ1tOQU1FXSgnXCInKTtcbiAgICByZXR1cm4gdGVzdCAhPT0gdGVzdC50b0xvd2VyQ2FzZSgpIHx8IHRlc3Quc3BsaXQoJ1wiJykubGVuZ3RoID4gMztcbiAgfSksICdTdHJpbmcnLCBPKTtcbn07XG4iLCIvLyBodHRwczovL2dpdGh1Yi5jb20vdGMzOS9wcm9wb3NhbC1zdHJpbmctcGFkLXN0YXJ0LWVuZFxudmFyIHRvTGVuZ3RoID0gcmVxdWlyZSgnLi9fdG8tbGVuZ3RoJyk7XG52YXIgcmVwZWF0ID0gcmVxdWlyZSgnLi9fc3RyaW5nLXJlcGVhdCcpO1xudmFyIGRlZmluZWQgPSByZXF1aXJlKCcuL19kZWZpbmVkJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKHRoYXQsIG1heExlbmd0aCwgZmlsbFN0cmluZywgbGVmdCkge1xuICB2YXIgUyA9IFN0cmluZyhkZWZpbmVkKHRoYXQpKTtcbiAgdmFyIHN0cmluZ0xlbmd0aCA9IFMubGVuZ3RoO1xuICB2YXIgZmlsbFN0ciA9IGZpbGxTdHJpbmcgPT09IHVuZGVmaW5lZCA/ICcgJyA6IFN0cmluZyhmaWxsU3RyaW5nKTtcbiAgdmFyIGludE1heExlbmd0aCA9IHRvTGVuZ3RoKG1heExlbmd0aCk7XG4gIGlmIChpbnRNYXhMZW5ndGggPD0gc3RyaW5nTGVuZ3RoIHx8IGZpbGxTdHIgPT0gJycpIHJldHVybiBTO1xuICB2YXIgZmlsbExlbiA9IGludE1heExlbmd0aCAtIHN0cmluZ0xlbmd0aDtcbiAgdmFyIHN0cmluZ0ZpbGxlciA9IHJlcGVhdC5jYWxsKGZpbGxTdHIsIE1hdGguY2VpbChmaWxsTGVuIC8gZmlsbFN0ci5sZW5ndGgpKTtcbiAgaWYgKHN0cmluZ0ZpbGxlci5sZW5ndGggPiBmaWxsTGVuKSBzdHJpbmdGaWxsZXIgPSBzdHJpbmdGaWxsZXIuc2xpY2UoMCwgZmlsbExlbik7XG4gIHJldHVybiBsZWZ0ID8gc3RyaW5nRmlsbGVyICsgUyA6IFMgKyBzdHJpbmdGaWxsZXI7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyIHRvSW50ZWdlciA9IHJlcXVpcmUoJy4vX3RvLWludGVnZXInKTtcbnZhciBkZWZpbmVkID0gcmVxdWlyZSgnLi9fZGVmaW5lZCcpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIHJlcGVhdChjb3VudCkge1xuICB2YXIgc3RyID0gU3RyaW5nKGRlZmluZWQodGhpcykpO1xuICB2YXIgcmVzID0gJyc7XG4gIHZhciBuID0gdG9JbnRlZ2VyKGNvdW50KTtcbiAgaWYgKG4gPCAwIHx8IG4gPT0gSW5maW5pdHkpIHRocm93IFJhbmdlRXJyb3IoXCJDb3VudCBjYW4ndCBiZSBuZWdhdGl2ZVwiKTtcbiAgZm9yICg7biA+IDA7IChuID4+Pj0gMSkgJiYgKHN0ciArPSBzdHIpKSBpZiAobiAmIDEpIHJlcyArPSBzdHI7XG4gIHJldHVybiByZXM7XG59O1xuIiwidmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciBkZWZpbmVkID0gcmVxdWlyZSgnLi9fZGVmaW5lZCcpO1xudmFyIGZhaWxzID0gcmVxdWlyZSgnLi9fZmFpbHMnKTtcbnZhciBzcGFjZXMgPSByZXF1aXJlKCcuL19zdHJpbmctd3MnKTtcbnZhciBzcGFjZSA9ICdbJyArIHNwYWNlcyArICddJztcbnZhciBub24gPSAnXFx1MjAwYlxcdTAwODUnO1xudmFyIGx0cmltID0gUmVnRXhwKCdeJyArIHNwYWNlICsgc3BhY2UgKyAnKicpO1xudmFyIHJ0cmltID0gUmVnRXhwKHNwYWNlICsgc3BhY2UgKyAnKiQnKTtcblxudmFyIGV4cG9ydGVyID0gZnVuY3Rpb24gKEtFWSwgZXhlYywgQUxJQVMpIHtcbiAgdmFyIGV4cCA9IHt9O1xuICB2YXIgRk9SQ0UgPSBmYWlscyhmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuICEhc3BhY2VzW0tFWV0oKSB8fCBub25bS0VZXSgpICE9IG5vbjtcbiAgfSk7XG4gIHZhciBmbiA9IGV4cFtLRVldID0gRk9SQ0UgPyBleGVjKHRyaW0pIDogc3BhY2VzW0tFWV07XG4gIGlmIChBTElBUykgZXhwW0FMSUFTXSA9IGZuO1xuICAkZXhwb3J0KCRleHBvcnQuUCArICRleHBvcnQuRiAqIEZPUkNFLCAnU3RyaW5nJywgZXhwKTtcbn07XG5cbi8vIDEgLT4gU3RyaW5nI3RyaW1MZWZ0XG4vLyAyIC0+IFN0cmluZyN0cmltUmlnaHRcbi8vIDMgLT4gU3RyaW5nI3RyaW1cbnZhciB0cmltID0gZXhwb3J0ZXIudHJpbSA9IGZ1bmN0aW9uIChzdHJpbmcsIFRZUEUpIHtcbiAgc3RyaW5nID0gU3RyaW5nKGRlZmluZWQoc3RyaW5nKSk7XG4gIGlmIChUWVBFICYgMSkgc3RyaW5nID0gc3RyaW5nLnJlcGxhY2UobHRyaW0sICcnKTtcbiAgaWYgKFRZUEUgJiAyKSBzdHJpbmcgPSBzdHJpbmcucmVwbGFjZShydHJpbSwgJycpO1xuICByZXR1cm4gc3RyaW5nO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRlcjtcbiIsIm1vZHVsZS5leHBvcnRzID0gJ1xceDA5XFx4MEFcXHgwQlxceDBDXFx4MERcXHgyMFxceEEwXFx1MTY4MFxcdTE4MEVcXHUyMDAwXFx1MjAwMVxcdTIwMDJcXHUyMDAzJyArXG4gICdcXHUyMDA0XFx1MjAwNVxcdTIwMDZcXHUyMDA3XFx1MjAwOFxcdTIwMDlcXHUyMDBBXFx1MjAyRlxcdTIwNUZcXHUzMDAwXFx1MjAyOFxcdTIwMjlcXHVGRUZGJztcbiIsInZhciBjdHggPSByZXF1aXJlKCcuL19jdHgnKTtcbnZhciBpbnZva2UgPSByZXF1aXJlKCcuL19pbnZva2UnKTtcbnZhciBodG1sID0gcmVxdWlyZSgnLi9faHRtbCcpO1xudmFyIGNlbCA9IHJlcXVpcmUoJy4vX2RvbS1jcmVhdGUnKTtcbnZhciBnbG9iYWwgPSByZXF1aXJlKCcuL19nbG9iYWwnKTtcbnZhciBwcm9jZXNzID0gZ2xvYmFsLnByb2Nlc3M7XG52YXIgc2V0VGFzayA9IGdsb2JhbC5zZXRJbW1lZGlhdGU7XG52YXIgY2xlYXJUYXNrID0gZ2xvYmFsLmNsZWFySW1tZWRpYXRlO1xudmFyIE1lc3NhZ2VDaGFubmVsID0gZ2xvYmFsLk1lc3NhZ2VDaGFubmVsO1xudmFyIERpc3BhdGNoID0gZ2xvYmFsLkRpc3BhdGNoO1xudmFyIGNvdW50ZXIgPSAwO1xudmFyIHF1ZXVlID0ge307XG52YXIgT05SRUFEWVNUQVRFQ0hBTkdFID0gJ29ucmVhZHlzdGF0ZWNoYW5nZSc7XG52YXIgZGVmZXIsIGNoYW5uZWwsIHBvcnQ7XG52YXIgcnVuID0gZnVuY3Rpb24gKCkge1xuICB2YXIgaWQgPSArdGhpcztcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXByb3RvdHlwZS1idWlsdGluc1xuICBpZiAocXVldWUuaGFzT3duUHJvcGVydHkoaWQpKSB7XG4gICAgdmFyIGZuID0gcXVldWVbaWRdO1xuICAgIGRlbGV0ZSBxdWV1ZVtpZF07XG4gICAgZm4oKTtcbiAgfVxufTtcbnZhciBsaXN0ZW5lciA9IGZ1bmN0aW9uIChldmVudCkge1xuICBydW4uY2FsbChldmVudC5kYXRhKTtcbn07XG4vLyBOb2RlLmpzIDAuOSsgJiBJRTEwKyBoYXMgc2V0SW1tZWRpYXRlLCBvdGhlcndpc2U6XG5pZiAoIXNldFRhc2sgfHwgIWNsZWFyVGFzaykge1xuICBzZXRUYXNrID0gZnVuY3Rpb24gc2V0SW1tZWRpYXRlKGZuKSB7XG4gICAgdmFyIGFyZ3MgPSBbXTtcbiAgICB2YXIgaSA9IDE7XG4gICAgd2hpbGUgKGFyZ3VtZW50cy5sZW5ndGggPiBpKSBhcmdzLnB1c2goYXJndW1lbnRzW2krK10pO1xuICAgIHF1ZXVlWysrY291bnRlcl0gPSBmdW5jdGlvbiAoKSB7XG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tbmV3LWZ1bmNcbiAgICAgIGludm9rZSh0eXBlb2YgZm4gPT0gJ2Z1bmN0aW9uJyA/IGZuIDogRnVuY3Rpb24oZm4pLCBhcmdzKTtcbiAgICB9O1xuICAgIGRlZmVyKGNvdW50ZXIpO1xuICAgIHJldHVybiBjb3VudGVyO1xuICB9O1xuICBjbGVhclRhc2sgPSBmdW5jdGlvbiBjbGVhckltbWVkaWF0ZShpZCkge1xuICAgIGRlbGV0ZSBxdWV1ZVtpZF07XG4gIH07XG4gIC8vIE5vZGUuanMgMC44LVxuICBpZiAocmVxdWlyZSgnLi9fY29mJykocHJvY2VzcykgPT0gJ3Byb2Nlc3MnKSB7XG4gICAgZGVmZXIgPSBmdW5jdGlvbiAoaWQpIHtcbiAgICAgIHByb2Nlc3MubmV4dFRpY2soY3R4KHJ1biwgaWQsIDEpKTtcbiAgICB9O1xuICAvLyBTcGhlcmUgKEpTIGdhbWUgZW5naW5lKSBEaXNwYXRjaCBBUElcbiAgfSBlbHNlIGlmIChEaXNwYXRjaCAmJiBEaXNwYXRjaC5ub3cpIHtcbiAgICBkZWZlciA9IGZ1bmN0aW9uIChpZCkge1xuICAgICAgRGlzcGF0Y2gubm93KGN0eChydW4sIGlkLCAxKSk7XG4gICAgfTtcbiAgLy8gQnJvd3NlcnMgd2l0aCBNZXNzYWdlQ2hhbm5lbCwgaW5jbHVkZXMgV2ViV29ya2Vyc1xuICB9IGVsc2UgaWYgKE1lc3NhZ2VDaGFubmVsKSB7XG4gICAgY2hhbm5lbCA9IG5ldyBNZXNzYWdlQ2hhbm5lbCgpO1xuICAgIHBvcnQgPSBjaGFubmVsLnBvcnQyO1xuICAgIGNoYW5uZWwucG9ydDEub25tZXNzYWdlID0gbGlzdGVuZXI7XG4gICAgZGVmZXIgPSBjdHgocG9ydC5wb3N0TWVzc2FnZSwgcG9ydCwgMSk7XG4gIC8vIEJyb3dzZXJzIHdpdGggcG9zdE1lc3NhZ2UsIHNraXAgV2ViV29ya2Vyc1xuICAvLyBJRTggaGFzIHBvc3RNZXNzYWdlLCBidXQgaXQncyBzeW5jICYgdHlwZW9mIGl0cyBwb3N0TWVzc2FnZSBpcyAnb2JqZWN0J1xuICB9IGVsc2UgaWYgKGdsb2JhbC5hZGRFdmVudExpc3RlbmVyICYmIHR5cGVvZiBwb3N0TWVzc2FnZSA9PSAnZnVuY3Rpb24nICYmICFnbG9iYWwuaW1wb3J0U2NyaXB0cykge1xuICAgIGRlZmVyID0gZnVuY3Rpb24gKGlkKSB7XG4gICAgICBnbG9iYWwucG9zdE1lc3NhZ2UoaWQgKyAnJywgJyonKTtcbiAgICB9O1xuICAgIGdsb2JhbC5hZGRFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgbGlzdGVuZXIsIGZhbHNlKTtcbiAgLy8gSUU4LVxuICB9IGVsc2UgaWYgKE9OUkVBRFlTVEFURUNIQU5HRSBpbiBjZWwoJ3NjcmlwdCcpKSB7XG4gICAgZGVmZXIgPSBmdW5jdGlvbiAoaWQpIHtcbiAgICAgIGh0bWwuYXBwZW5kQ2hpbGQoY2VsKCdzY3JpcHQnKSlbT05SRUFEWVNUQVRFQ0hBTkdFXSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaHRtbC5yZW1vdmVDaGlsZCh0aGlzKTtcbiAgICAgICAgcnVuLmNhbGwoaWQpO1xuICAgICAgfTtcbiAgICB9O1xuICAvLyBSZXN0IG9sZCBicm93c2Vyc1xuICB9IGVsc2Uge1xuICAgIGRlZmVyID0gZnVuY3Rpb24gKGlkKSB7XG4gICAgICBzZXRUaW1lb3V0KGN0eChydW4sIGlkLCAxKSwgMCk7XG4gICAgfTtcbiAgfVxufVxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIHNldDogc2V0VGFzayxcbiAgY2xlYXI6IGNsZWFyVGFza1xufTtcbiIsInZhciB0b0ludGVnZXIgPSByZXF1aXJlKCcuL190by1pbnRlZ2VyJyk7XG52YXIgbWF4ID0gTWF0aC5tYXg7XG52YXIgbWluID0gTWF0aC5taW47XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChpbmRleCwgbGVuZ3RoKSB7XG4gIGluZGV4ID0gdG9JbnRlZ2VyKGluZGV4KTtcbiAgcmV0dXJuIGluZGV4IDwgMCA/IG1heChpbmRleCArIGxlbmd0aCwgMCkgOiBtaW4oaW5kZXgsIGxlbmd0aCk7XG59O1xuIiwiLy8gaHR0cHM6Ly90YzM5LmdpdGh1Yi5pby9lY21hMjYyLyNzZWMtdG9pbmRleFxudmFyIHRvSW50ZWdlciA9IHJlcXVpcmUoJy4vX3RvLWludGVnZXInKTtcbnZhciB0b0xlbmd0aCA9IHJlcXVpcmUoJy4vX3RvLWxlbmd0aCcpO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoaXQpIHtcbiAgaWYgKGl0ID09PSB1bmRlZmluZWQpIHJldHVybiAwO1xuICB2YXIgbnVtYmVyID0gdG9JbnRlZ2VyKGl0KTtcbiAgdmFyIGxlbmd0aCA9IHRvTGVuZ3RoKG51bWJlcik7XG4gIGlmIChudW1iZXIgIT09IGxlbmd0aCkgdGhyb3cgUmFuZ2VFcnJvcignV3JvbmcgbGVuZ3RoIScpO1xuICByZXR1cm4gbGVuZ3RoO1xufTtcbiIsIi8vIDcuMS40IFRvSW50ZWdlclxudmFyIGNlaWwgPSBNYXRoLmNlaWw7XG52YXIgZmxvb3IgPSBNYXRoLmZsb29yO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoaXQpIHtcbiAgcmV0dXJuIGlzTmFOKGl0ID0gK2l0KSA/IDAgOiAoaXQgPiAwID8gZmxvb3IgOiBjZWlsKShpdCk7XG59O1xuIiwiLy8gdG8gaW5kZXhlZCBvYmplY3QsIHRvT2JqZWN0IHdpdGggZmFsbGJhY2sgZm9yIG5vbi1hcnJheS1saWtlIEVTMyBzdHJpbmdzXG52YXIgSU9iamVjdCA9IHJlcXVpcmUoJy4vX2lvYmplY3QnKTtcbnZhciBkZWZpbmVkID0gcmVxdWlyZSgnLi9fZGVmaW5lZCcpO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoaXQpIHtcbiAgcmV0dXJuIElPYmplY3QoZGVmaW5lZChpdCkpO1xufTtcbiIsIi8vIDcuMS4xNSBUb0xlbmd0aFxudmFyIHRvSW50ZWdlciA9IHJlcXVpcmUoJy4vX3RvLWludGVnZXInKTtcbnZhciBtaW4gPSBNYXRoLm1pbjtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGl0KSB7XG4gIHJldHVybiBpdCA+IDAgPyBtaW4odG9JbnRlZ2VyKGl0KSwgMHgxZmZmZmZmZmZmZmZmZikgOiAwOyAvLyBwb3coMiwgNTMpIC0gMSA9PSA5MDA3MTk5MjU0NzQwOTkxXG59O1xuIiwiLy8gNy4xLjEzIFRvT2JqZWN0KGFyZ3VtZW50KVxudmFyIGRlZmluZWQgPSByZXF1aXJlKCcuL19kZWZpbmVkJyk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChpdCkge1xuICByZXR1cm4gT2JqZWN0KGRlZmluZWQoaXQpKTtcbn07XG4iLCIvLyA3LjEuMSBUb1ByaW1pdGl2ZShpbnB1dCBbLCBQcmVmZXJyZWRUeXBlXSlcbnZhciBpc09iamVjdCA9IHJlcXVpcmUoJy4vX2lzLW9iamVjdCcpO1xuLy8gaW5zdGVhZCBvZiB0aGUgRVM2IHNwZWMgdmVyc2lvbiwgd2UgZGlkbid0IGltcGxlbWVudCBAQHRvUHJpbWl0aXZlIGNhc2Vcbi8vIGFuZCB0aGUgc2Vjb25kIGFyZ3VtZW50IC0gZmxhZyAtIHByZWZlcnJlZCB0eXBlIGlzIGEgc3RyaW5nXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChpdCwgUykge1xuICBpZiAoIWlzT2JqZWN0KGl0KSkgcmV0dXJuIGl0O1xuICB2YXIgZm4sIHZhbDtcbiAgaWYgKFMgJiYgdHlwZW9mIChmbiA9IGl0LnRvU3RyaW5nKSA9PSAnZnVuY3Rpb24nICYmICFpc09iamVjdCh2YWwgPSBmbi5jYWxsKGl0KSkpIHJldHVybiB2YWw7XG4gIGlmICh0eXBlb2YgKGZuID0gaXQudmFsdWVPZikgPT0gJ2Z1bmN0aW9uJyAmJiAhaXNPYmplY3QodmFsID0gZm4uY2FsbChpdCkpKSByZXR1cm4gdmFsO1xuICBpZiAoIVMgJiYgdHlwZW9mIChmbiA9IGl0LnRvU3RyaW5nKSA9PSAnZnVuY3Rpb24nICYmICFpc09iamVjdCh2YWwgPSBmbi5jYWxsKGl0KSkpIHJldHVybiB2YWw7XG4gIHRocm93IFR5cGVFcnJvcihcIkNhbid0IGNvbnZlcnQgb2JqZWN0IHRvIHByaW1pdGl2ZSB2YWx1ZVwiKTtcbn07XG4iLCIndXNlIHN0cmljdCc7XG5pZiAocmVxdWlyZSgnLi9fZGVzY3JpcHRvcnMnKSkge1xuICB2YXIgTElCUkFSWSA9IHJlcXVpcmUoJy4vX2xpYnJhcnknKTtcbiAgdmFyIGdsb2JhbCA9IHJlcXVpcmUoJy4vX2dsb2JhbCcpO1xuICB2YXIgZmFpbHMgPSByZXF1aXJlKCcuL19mYWlscycpO1xuICB2YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xuICB2YXIgJHR5cGVkID0gcmVxdWlyZSgnLi9fdHlwZWQnKTtcbiAgdmFyICRidWZmZXIgPSByZXF1aXJlKCcuL190eXBlZC1idWZmZXInKTtcbiAgdmFyIGN0eCA9IHJlcXVpcmUoJy4vX2N0eCcpO1xuICB2YXIgYW5JbnN0YW5jZSA9IHJlcXVpcmUoJy4vX2FuLWluc3RhbmNlJyk7XG4gIHZhciBwcm9wZXJ0eURlc2MgPSByZXF1aXJlKCcuL19wcm9wZXJ0eS1kZXNjJyk7XG4gIHZhciBoaWRlID0gcmVxdWlyZSgnLi9faGlkZScpO1xuICB2YXIgcmVkZWZpbmVBbGwgPSByZXF1aXJlKCcuL19yZWRlZmluZS1hbGwnKTtcbiAgdmFyIHRvSW50ZWdlciA9IHJlcXVpcmUoJy4vX3RvLWludGVnZXInKTtcbiAgdmFyIHRvTGVuZ3RoID0gcmVxdWlyZSgnLi9fdG8tbGVuZ3RoJyk7XG4gIHZhciB0b0luZGV4ID0gcmVxdWlyZSgnLi9fdG8taW5kZXgnKTtcbiAgdmFyIHRvQWJzb2x1dGVJbmRleCA9IHJlcXVpcmUoJy4vX3RvLWFic29sdXRlLWluZGV4Jyk7XG4gIHZhciB0b1ByaW1pdGl2ZSA9IHJlcXVpcmUoJy4vX3RvLXByaW1pdGl2ZScpO1xuICB2YXIgaGFzID0gcmVxdWlyZSgnLi9faGFzJyk7XG4gIHZhciBjbGFzc29mID0gcmVxdWlyZSgnLi9fY2xhc3NvZicpO1xuICB2YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuL19pcy1vYmplY3QnKTtcbiAgdmFyIHRvT2JqZWN0ID0gcmVxdWlyZSgnLi9fdG8tb2JqZWN0Jyk7XG4gIHZhciBpc0FycmF5SXRlciA9IHJlcXVpcmUoJy4vX2lzLWFycmF5LWl0ZXInKTtcbiAgdmFyIGNyZWF0ZSA9IHJlcXVpcmUoJy4vX29iamVjdC1jcmVhdGUnKTtcbiAgdmFyIGdldFByb3RvdHlwZU9mID0gcmVxdWlyZSgnLi9fb2JqZWN0LWdwbycpO1xuICB2YXIgZ09QTiA9IHJlcXVpcmUoJy4vX29iamVjdC1nb3BuJykuZjtcbiAgdmFyIGdldEl0ZXJGbiA9IHJlcXVpcmUoJy4vY29yZS5nZXQtaXRlcmF0b3ItbWV0aG9kJyk7XG4gIHZhciB1aWQgPSByZXF1aXJlKCcuL191aWQnKTtcbiAgdmFyIHdrcyA9IHJlcXVpcmUoJy4vX3drcycpO1xuICB2YXIgY3JlYXRlQXJyYXlNZXRob2QgPSByZXF1aXJlKCcuL19hcnJheS1tZXRob2RzJyk7XG4gIHZhciBjcmVhdGVBcnJheUluY2x1ZGVzID0gcmVxdWlyZSgnLi9fYXJyYXktaW5jbHVkZXMnKTtcbiAgdmFyIHNwZWNpZXNDb25zdHJ1Y3RvciA9IHJlcXVpcmUoJy4vX3NwZWNpZXMtY29uc3RydWN0b3InKTtcbiAgdmFyIEFycmF5SXRlcmF0b3JzID0gcmVxdWlyZSgnLi9lczYuYXJyYXkuaXRlcmF0b3InKTtcbiAgdmFyIEl0ZXJhdG9ycyA9IHJlcXVpcmUoJy4vX2l0ZXJhdG9ycycpO1xuICB2YXIgJGl0ZXJEZXRlY3QgPSByZXF1aXJlKCcuL19pdGVyLWRldGVjdCcpO1xuICB2YXIgc2V0U3BlY2llcyA9IHJlcXVpcmUoJy4vX3NldC1zcGVjaWVzJyk7XG4gIHZhciBhcnJheUZpbGwgPSByZXF1aXJlKCcuL19hcnJheS1maWxsJyk7XG4gIHZhciBhcnJheUNvcHlXaXRoaW4gPSByZXF1aXJlKCcuL19hcnJheS1jb3B5LXdpdGhpbicpO1xuICB2YXIgJERQID0gcmVxdWlyZSgnLi9fb2JqZWN0LWRwJyk7XG4gIHZhciAkR09QRCA9IHJlcXVpcmUoJy4vX29iamVjdC1nb3BkJyk7XG4gIHZhciBkUCA9ICREUC5mO1xuICB2YXIgZ09QRCA9ICRHT1BELmY7XG4gIHZhciBSYW5nZUVycm9yID0gZ2xvYmFsLlJhbmdlRXJyb3I7XG4gIHZhciBUeXBlRXJyb3IgPSBnbG9iYWwuVHlwZUVycm9yO1xuICB2YXIgVWludDhBcnJheSA9IGdsb2JhbC5VaW50OEFycmF5O1xuICB2YXIgQVJSQVlfQlVGRkVSID0gJ0FycmF5QnVmZmVyJztcbiAgdmFyIFNIQVJFRF9CVUZGRVIgPSAnU2hhcmVkJyArIEFSUkFZX0JVRkZFUjtcbiAgdmFyIEJZVEVTX1BFUl9FTEVNRU5UID0gJ0JZVEVTX1BFUl9FTEVNRU5UJztcbiAgdmFyIFBST1RPVFlQRSA9ICdwcm90b3R5cGUnO1xuICB2YXIgQXJyYXlQcm90byA9IEFycmF5W1BST1RPVFlQRV07XG4gIHZhciAkQXJyYXlCdWZmZXIgPSAkYnVmZmVyLkFycmF5QnVmZmVyO1xuICB2YXIgJERhdGFWaWV3ID0gJGJ1ZmZlci5EYXRhVmlldztcbiAgdmFyIGFycmF5Rm9yRWFjaCA9IGNyZWF0ZUFycmF5TWV0aG9kKDApO1xuICB2YXIgYXJyYXlGaWx0ZXIgPSBjcmVhdGVBcnJheU1ldGhvZCgyKTtcbiAgdmFyIGFycmF5U29tZSA9IGNyZWF0ZUFycmF5TWV0aG9kKDMpO1xuICB2YXIgYXJyYXlFdmVyeSA9IGNyZWF0ZUFycmF5TWV0aG9kKDQpO1xuICB2YXIgYXJyYXlGaW5kID0gY3JlYXRlQXJyYXlNZXRob2QoNSk7XG4gIHZhciBhcnJheUZpbmRJbmRleCA9IGNyZWF0ZUFycmF5TWV0aG9kKDYpO1xuICB2YXIgYXJyYXlJbmNsdWRlcyA9IGNyZWF0ZUFycmF5SW5jbHVkZXModHJ1ZSk7XG4gIHZhciBhcnJheUluZGV4T2YgPSBjcmVhdGVBcnJheUluY2x1ZGVzKGZhbHNlKTtcbiAgdmFyIGFycmF5VmFsdWVzID0gQXJyYXlJdGVyYXRvcnMudmFsdWVzO1xuICB2YXIgYXJyYXlLZXlzID0gQXJyYXlJdGVyYXRvcnMua2V5cztcbiAgdmFyIGFycmF5RW50cmllcyA9IEFycmF5SXRlcmF0b3JzLmVudHJpZXM7XG4gIHZhciBhcnJheUxhc3RJbmRleE9mID0gQXJyYXlQcm90by5sYXN0SW5kZXhPZjtcbiAgdmFyIGFycmF5UmVkdWNlID0gQXJyYXlQcm90by5yZWR1Y2U7XG4gIHZhciBhcnJheVJlZHVjZVJpZ2h0ID0gQXJyYXlQcm90by5yZWR1Y2VSaWdodDtcbiAgdmFyIGFycmF5Sm9pbiA9IEFycmF5UHJvdG8uam9pbjtcbiAgdmFyIGFycmF5U29ydCA9IEFycmF5UHJvdG8uc29ydDtcbiAgdmFyIGFycmF5U2xpY2UgPSBBcnJheVByb3RvLnNsaWNlO1xuICB2YXIgYXJyYXlUb1N0cmluZyA9IEFycmF5UHJvdG8udG9TdHJpbmc7XG4gIHZhciBhcnJheVRvTG9jYWxlU3RyaW5nID0gQXJyYXlQcm90by50b0xvY2FsZVN0cmluZztcbiAgdmFyIElURVJBVE9SID0gd2tzKCdpdGVyYXRvcicpO1xuICB2YXIgVEFHID0gd2tzKCd0b1N0cmluZ1RhZycpO1xuICB2YXIgVFlQRURfQ09OU1RSVUNUT1IgPSB1aWQoJ3R5cGVkX2NvbnN0cnVjdG9yJyk7XG4gIHZhciBERUZfQ09OU1RSVUNUT1IgPSB1aWQoJ2RlZl9jb25zdHJ1Y3RvcicpO1xuICB2YXIgQUxMX0NPTlNUUlVDVE9SUyA9ICR0eXBlZC5DT05TVFI7XG4gIHZhciBUWVBFRF9BUlJBWSA9ICR0eXBlZC5UWVBFRDtcbiAgdmFyIFZJRVcgPSAkdHlwZWQuVklFVztcbiAgdmFyIFdST05HX0xFTkdUSCA9ICdXcm9uZyBsZW5ndGghJztcblxuICB2YXIgJG1hcCA9IGNyZWF0ZUFycmF5TWV0aG9kKDEsIGZ1bmN0aW9uIChPLCBsZW5ndGgpIHtcbiAgICByZXR1cm4gYWxsb2NhdGUoc3BlY2llc0NvbnN0cnVjdG9yKE8sIE9bREVGX0NPTlNUUlVDVE9SXSksIGxlbmd0aCk7XG4gIH0pO1xuXG4gIHZhciBMSVRUTEVfRU5ESUFOID0gZmFpbHMoZnVuY3Rpb24gKCkge1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby11bmRlZlxuICAgIHJldHVybiBuZXcgVWludDhBcnJheShuZXcgVWludDE2QXJyYXkoWzFdKS5idWZmZXIpWzBdID09PSAxO1xuICB9KTtcblxuICB2YXIgRk9SQ0VEX1NFVCA9ICEhVWludDhBcnJheSAmJiAhIVVpbnQ4QXJyYXlbUFJPVE9UWVBFXS5zZXQgJiYgZmFpbHMoZnVuY3Rpb24gKCkge1xuICAgIG5ldyBVaW50OEFycmF5KDEpLnNldCh7fSk7XG4gIH0pO1xuXG4gIHZhciB0b09mZnNldCA9IGZ1bmN0aW9uIChpdCwgQllURVMpIHtcbiAgICB2YXIgb2Zmc2V0ID0gdG9JbnRlZ2VyKGl0KTtcbiAgICBpZiAob2Zmc2V0IDwgMCB8fCBvZmZzZXQgJSBCWVRFUykgdGhyb3cgUmFuZ2VFcnJvcignV3Jvbmcgb2Zmc2V0IScpO1xuICAgIHJldHVybiBvZmZzZXQ7XG4gIH07XG5cbiAgdmFyIHZhbGlkYXRlID0gZnVuY3Rpb24gKGl0KSB7XG4gICAgaWYgKGlzT2JqZWN0KGl0KSAmJiBUWVBFRF9BUlJBWSBpbiBpdCkgcmV0dXJuIGl0O1xuICAgIHRocm93IFR5cGVFcnJvcihpdCArICcgaXMgbm90IGEgdHlwZWQgYXJyYXkhJyk7XG4gIH07XG5cbiAgdmFyIGFsbG9jYXRlID0gZnVuY3Rpb24gKEMsIGxlbmd0aCkge1xuICAgIGlmICghKGlzT2JqZWN0KEMpICYmIFRZUEVEX0NPTlNUUlVDVE9SIGluIEMpKSB7XG4gICAgICB0aHJvdyBUeXBlRXJyb3IoJ0l0IGlzIG5vdCBhIHR5cGVkIGFycmF5IGNvbnN0cnVjdG9yIScpO1xuICAgIH0gcmV0dXJuIG5ldyBDKGxlbmd0aCk7XG4gIH07XG5cbiAgdmFyIHNwZWNpZXNGcm9tTGlzdCA9IGZ1bmN0aW9uIChPLCBsaXN0KSB7XG4gICAgcmV0dXJuIGZyb21MaXN0KHNwZWNpZXNDb25zdHJ1Y3RvcihPLCBPW0RFRl9DT05TVFJVQ1RPUl0pLCBsaXN0KTtcbiAgfTtcblxuICB2YXIgZnJvbUxpc3QgPSBmdW5jdGlvbiAoQywgbGlzdCkge1xuICAgIHZhciBpbmRleCA9IDA7XG4gICAgdmFyIGxlbmd0aCA9IGxpc3QubGVuZ3RoO1xuICAgIHZhciByZXN1bHQgPSBhbGxvY2F0ZShDLCBsZW5ndGgpO1xuICAgIHdoaWxlIChsZW5ndGggPiBpbmRleCkgcmVzdWx0W2luZGV4XSA9IGxpc3RbaW5kZXgrK107XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfTtcblxuICB2YXIgYWRkR2V0dGVyID0gZnVuY3Rpb24gKGl0LCBrZXksIGludGVybmFsKSB7XG4gICAgZFAoaXQsIGtleSwgeyBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXMuX2RbaW50ZXJuYWxdOyB9IH0pO1xuICB9O1xuXG4gIHZhciAkZnJvbSA9IGZ1bmN0aW9uIGZyb20oc291cmNlIC8qICwgbWFwZm4sIHRoaXNBcmcgKi8pIHtcbiAgICB2YXIgTyA9IHRvT2JqZWN0KHNvdXJjZSk7XG4gICAgdmFyIGFMZW4gPSBhcmd1bWVudHMubGVuZ3RoO1xuICAgIHZhciBtYXBmbiA9IGFMZW4gPiAxID8gYXJndW1lbnRzWzFdIDogdW5kZWZpbmVkO1xuICAgIHZhciBtYXBwaW5nID0gbWFwZm4gIT09IHVuZGVmaW5lZDtcbiAgICB2YXIgaXRlckZuID0gZ2V0SXRlckZuKE8pO1xuICAgIHZhciBpLCBsZW5ndGgsIHZhbHVlcywgcmVzdWx0LCBzdGVwLCBpdGVyYXRvcjtcbiAgICBpZiAoaXRlckZuICE9IHVuZGVmaW5lZCAmJiAhaXNBcnJheUl0ZXIoaXRlckZuKSkge1xuICAgICAgZm9yIChpdGVyYXRvciA9IGl0ZXJGbi5jYWxsKE8pLCB2YWx1ZXMgPSBbXSwgaSA9IDA7ICEoc3RlcCA9IGl0ZXJhdG9yLm5leHQoKSkuZG9uZTsgaSsrKSB7XG4gICAgICAgIHZhbHVlcy5wdXNoKHN0ZXAudmFsdWUpO1xuICAgICAgfSBPID0gdmFsdWVzO1xuICAgIH1cbiAgICBpZiAobWFwcGluZyAmJiBhTGVuID4gMikgbWFwZm4gPSBjdHgobWFwZm4sIGFyZ3VtZW50c1syXSwgMik7XG4gICAgZm9yIChpID0gMCwgbGVuZ3RoID0gdG9MZW5ndGgoTy5sZW5ndGgpLCByZXN1bHQgPSBhbGxvY2F0ZSh0aGlzLCBsZW5ndGgpOyBsZW5ndGggPiBpOyBpKyspIHtcbiAgICAgIHJlc3VsdFtpXSA9IG1hcHBpbmcgPyBtYXBmbihPW2ldLCBpKSA6IE9baV07XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG4gIH07XG5cbiAgdmFyICRvZiA9IGZ1bmN0aW9uIG9mKC8qIC4uLml0ZW1zICovKSB7XG4gICAgdmFyIGluZGV4ID0gMDtcbiAgICB2YXIgbGVuZ3RoID0gYXJndW1lbnRzLmxlbmd0aDtcbiAgICB2YXIgcmVzdWx0ID0gYWxsb2NhdGUodGhpcywgbGVuZ3RoKTtcbiAgICB3aGlsZSAobGVuZ3RoID4gaW5kZXgpIHJlc3VsdFtpbmRleF0gPSBhcmd1bWVudHNbaW5kZXgrK107XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfTtcblxuICAvLyBpT1MgU2FmYXJpIDYueCBmYWlscyBoZXJlXG4gIHZhciBUT19MT0NBTEVfQlVHID0gISFVaW50OEFycmF5ICYmIGZhaWxzKGZ1bmN0aW9uICgpIHsgYXJyYXlUb0xvY2FsZVN0cmluZy5jYWxsKG5ldyBVaW50OEFycmF5KDEpKTsgfSk7XG5cbiAgdmFyICR0b0xvY2FsZVN0cmluZyA9IGZ1bmN0aW9uIHRvTG9jYWxlU3RyaW5nKCkge1xuICAgIHJldHVybiBhcnJheVRvTG9jYWxlU3RyaW5nLmFwcGx5KFRPX0xPQ0FMRV9CVUcgPyBhcnJheVNsaWNlLmNhbGwodmFsaWRhdGUodGhpcykpIDogdmFsaWRhdGUodGhpcyksIGFyZ3VtZW50cyk7XG4gIH07XG5cbiAgdmFyIHByb3RvID0ge1xuICAgIGNvcHlXaXRoaW46IGZ1bmN0aW9uIGNvcHlXaXRoaW4odGFyZ2V0LCBzdGFydCAvKiAsIGVuZCAqLykge1xuICAgICAgcmV0dXJuIGFycmF5Q29weVdpdGhpbi5jYWxsKHZhbGlkYXRlKHRoaXMpLCB0YXJnZXQsIHN0YXJ0LCBhcmd1bWVudHMubGVuZ3RoID4gMiA/IGFyZ3VtZW50c1syXSA6IHVuZGVmaW5lZCk7XG4gICAgfSxcbiAgICBldmVyeTogZnVuY3Rpb24gZXZlcnkoY2FsbGJhY2tmbiAvKiAsIHRoaXNBcmcgKi8pIHtcbiAgICAgIHJldHVybiBhcnJheUV2ZXJ5KHZhbGlkYXRlKHRoaXMpLCBjYWxsYmFja2ZuLCBhcmd1bWVudHMubGVuZ3RoID4gMSA/IGFyZ3VtZW50c1sxXSA6IHVuZGVmaW5lZCk7XG4gICAgfSxcbiAgICBmaWxsOiBmdW5jdGlvbiBmaWxsKHZhbHVlIC8qICwgc3RhcnQsIGVuZCAqLykgeyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXVudXNlZC12YXJzXG4gICAgICByZXR1cm4gYXJyYXlGaWxsLmFwcGx5KHZhbGlkYXRlKHRoaXMpLCBhcmd1bWVudHMpO1xuICAgIH0sXG4gICAgZmlsdGVyOiBmdW5jdGlvbiBmaWx0ZXIoY2FsbGJhY2tmbiAvKiAsIHRoaXNBcmcgKi8pIHtcbiAgICAgIHJldHVybiBzcGVjaWVzRnJvbUxpc3QodGhpcywgYXJyYXlGaWx0ZXIodmFsaWRhdGUodGhpcyksIGNhbGxiYWNrZm4sXG4gICAgICAgIGFyZ3VtZW50cy5sZW5ndGggPiAxID8gYXJndW1lbnRzWzFdIDogdW5kZWZpbmVkKSk7XG4gICAgfSxcbiAgICBmaW5kOiBmdW5jdGlvbiBmaW5kKHByZWRpY2F0ZSAvKiAsIHRoaXNBcmcgKi8pIHtcbiAgICAgIHJldHVybiBhcnJheUZpbmQodmFsaWRhdGUodGhpcyksIHByZWRpY2F0ZSwgYXJndW1lbnRzLmxlbmd0aCA+IDEgPyBhcmd1bWVudHNbMV0gOiB1bmRlZmluZWQpO1xuICAgIH0sXG4gICAgZmluZEluZGV4OiBmdW5jdGlvbiBmaW5kSW5kZXgocHJlZGljYXRlIC8qICwgdGhpc0FyZyAqLykge1xuICAgICAgcmV0dXJuIGFycmF5RmluZEluZGV4KHZhbGlkYXRlKHRoaXMpLCBwcmVkaWNhdGUsIGFyZ3VtZW50cy5sZW5ndGggPiAxID8gYXJndW1lbnRzWzFdIDogdW5kZWZpbmVkKTtcbiAgICB9LFxuICAgIGZvckVhY2g6IGZ1bmN0aW9uIGZvckVhY2goY2FsbGJhY2tmbiAvKiAsIHRoaXNBcmcgKi8pIHtcbiAgICAgIGFycmF5Rm9yRWFjaCh2YWxpZGF0ZSh0aGlzKSwgY2FsbGJhY2tmbiwgYXJndW1lbnRzLmxlbmd0aCA+IDEgPyBhcmd1bWVudHNbMV0gOiB1bmRlZmluZWQpO1xuICAgIH0sXG4gICAgaW5kZXhPZjogZnVuY3Rpb24gaW5kZXhPZihzZWFyY2hFbGVtZW50IC8qICwgZnJvbUluZGV4ICovKSB7XG4gICAgICByZXR1cm4gYXJyYXlJbmRleE9mKHZhbGlkYXRlKHRoaXMpLCBzZWFyY2hFbGVtZW50LCBhcmd1bWVudHMubGVuZ3RoID4gMSA/IGFyZ3VtZW50c1sxXSA6IHVuZGVmaW5lZCk7XG4gICAgfSxcbiAgICBpbmNsdWRlczogZnVuY3Rpb24gaW5jbHVkZXMoc2VhcmNoRWxlbWVudCAvKiAsIGZyb21JbmRleCAqLykge1xuICAgICAgcmV0dXJuIGFycmF5SW5jbHVkZXModmFsaWRhdGUodGhpcyksIHNlYXJjaEVsZW1lbnQsIGFyZ3VtZW50cy5sZW5ndGggPiAxID8gYXJndW1lbnRzWzFdIDogdW5kZWZpbmVkKTtcbiAgICB9LFxuICAgIGpvaW46IGZ1bmN0aW9uIGpvaW4oc2VwYXJhdG9yKSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tdW51c2VkLXZhcnNcbiAgICAgIHJldHVybiBhcnJheUpvaW4uYXBwbHkodmFsaWRhdGUodGhpcyksIGFyZ3VtZW50cyk7XG4gICAgfSxcbiAgICBsYXN0SW5kZXhPZjogZnVuY3Rpb24gbGFzdEluZGV4T2Yoc2VhcmNoRWxlbWVudCAvKiAsIGZyb21JbmRleCAqLykgeyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXVudXNlZC12YXJzXG4gICAgICByZXR1cm4gYXJyYXlMYXN0SW5kZXhPZi5hcHBseSh2YWxpZGF0ZSh0aGlzKSwgYXJndW1lbnRzKTtcbiAgICB9LFxuICAgIG1hcDogZnVuY3Rpb24gbWFwKG1hcGZuIC8qICwgdGhpc0FyZyAqLykge1xuICAgICAgcmV0dXJuICRtYXAodmFsaWRhdGUodGhpcyksIG1hcGZuLCBhcmd1bWVudHMubGVuZ3RoID4gMSA/IGFyZ3VtZW50c1sxXSA6IHVuZGVmaW5lZCk7XG4gICAgfSxcbiAgICByZWR1Y2U6IGZ1bmN0aW9uIHJlZHVjZShjYWxsYmFja2ZuIC8qICwgaW5pdGlhbFZhbHVlICovKSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tdW51c2VkLXZhcnNcbiAgICAgIHJldHVybiBhcnJheVJlZHVjZS5hcHBseSh2YWxpZGF0ZSh0aGlzKSwgYXJndW1lbnRzKTtcbiAgICB9LFxuICAgIHJlZHVjZVJpZ2h0OiBmdW5jdGlvbiByZWR1Y2VSaWdodChjYWxsYmFja2ZuIC8qICwgaW5pdGlhbFZhbHVlICovKSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tdW51c2VkLXZhcnNcbiAgICAgIHJldHVybiBhcnJheVJlZHVjZVJpZ2h0LmFwcGx5KHZhbGlkYXRlKHRoaXMpLCBhcmd1bWVudHMpO1xuICAgIH0sXG4gICAgcmV2ZXJzZTogZnVuY3Rpb24gcmV2ZXJzZSgpIHtcbiAgICAgIHZhciB0aGF0ID0gdGhpcztcbiAgICAgIHZhciBsZW5ndGggPSB2YWxpZGF0ZSh0aGF0KS5sZW5ndGg7XG4gICAgICB2YXIgbWlkZGxlID0gTWF0aC5mbG9vcihsZW5ndGggLyAyKTtcbiAgICAgIHZhciBpbmRleCA9IDA7XG4gICAgICB2YXIgdmFsdWU7XG4gICAgICB3aGlsZSAoaW5kZXggPCBtaWRkbGUpIHtcbiAgICAgICAgdmFsdWUgPSB0aGF0W2luZGV4XTtcbiAgICAgICAgdGhhdFtpbmRleCsrXSA9IHRoYXRbLS1sZW5ndGhdO1xuICAgICAgICB0aGF0W2xlbmd0aF0gPSB2YWx1ZTtcbiAgICAgIH0gcmV0dXJuIHRoYXQ7XG4gICAgfSxcbiAgICBzb21lOiBmdW5jdGlvbiBzb21lKGNhbGxiYWNrZm4gLyogLCB0aGlzQXJnICovKSB7XG4gICAgICByZXR1cm4gYXJyYXlTb21lKHZhbGlkYXRlKHRoaXMpLCBjYWxsYmFja2ZuLCBhcmd1bWVudHMubGVuZ3RoID4gMSA/IGFyZ3VtZW50c1sxXSA6IHVuZGVmaW5lZCk7XG4gICAgfSxcbiAgICBzb3J0OiBmdW5jdGlvbiBzb3J0KGNvbXBhcmVmbikge1xuICAgICAgcmV0dXJuIGFycmF5U29ydC5jYWxsKHZhbGlkYXRlKHRoaXMpLCBjb21wYXJlZm4pO1xuICAgIH0sXG4gICAgc3ViYXJyYXk6IGZ1bmN0aW9uIHN1YmFycmF5KGJlZ2luLCBlbmQpIHtcbiAgICAgIHZhciBPID0gdmFsaWRhdGUodGhpcyk7XG4gICAgICB2YXIgbGVuZ3RoID0gTy5sZW5ndGg7XG4gICAgICB2YXIgJGJlZ2luID0gdG9BYnNvbHV0ZUluZGV4KGJlZ2luLCBsZW5ndGgpO1xuICAgICAgcmV0dXJuIG5ldyAoc3BlY2llc0NvbnN0cnVjdG9yKE8sIE9bREVGX0NPTlNUUlVDVE9SXSkpKFxuICAgICAgICBPLmJ1ZmZlcixcbiAgICAgICAgTy5ieXRlT2Zmc2V0ICsgJGJlZ2luICogTy5CWVRFU19QRVJfRUxFTUVOVCxcbiAgICAgICAgdG9MZW5ndGgoKGVuZCA9PT0gdW5kZWZpbmVkID8gbGVuZ3RoIDogdG9BYnNvbHV0ZUluZGV4KGVuZCwgbGVuZ3RoKSkgLSAkYmVnaW4pXG4gICAgICApO1xuICAgIH1cbiAgfTtcblxuICB2YXIgJHNsaWNlID0gZnVuY3Rpb24gc2xpY2Uoc3RhcnQsIGVuZCkge1xuICAgIHJldHVybiBzcGVjaWVzRnJvbUxpc3QodGhpcywgYXJyYXlTbGljZS5jYWxsKHZhbGlkYXRlKHRoaXMpLCBzdGFydCwgZW5kKSk7XG4gIH07XG5cbiAgdmFyICRzZXQgPSBmdW5jdGlvbiBzZXQoYXJyYXlMaWtlIC8qICwgb2Zmc2V0ICovKSB7XG4gICAgdmFsaWRhdGUodGhpcyk7XG4gICAgdmFyIG9mZnNldCA9IHRvT2Zmc2V0KGFyZ3VtZW50c1sxXSwgMSk7XG4gICAgdmFyIGxlbmd0aCA9IHRoaXMubGVuZ3RoO1xuICAgIHZhciBzcmMgPSB0b09iamVjdChhcnJheUxpa2UpO1xuICAgIHZhciBsZW4gPSB0b0xlbmd0aChzcmMubGVuZ3RoKTtcbiAgICB2YXIgaW5kZXggPSAwO1xuICAgIGlmIChsZW4gKyBvZmZzZXQgPiBsZW5ndGgpIHRocm93IFJhbmdlRXJyb3IoV1JPTkdfTEVOR1RIKTtcbiAgICB3aGlsZSAoaW5kZXggPCBsZW4pIHRoaXNbb2Zmc2V0ICsgaW5kZXhdID0gc3JjW2luZGV4KytdO1xuICB9O1xuXG4gIHZhciAkaXRlcmF0b3JzID0ge1xuICAgIGVudHJpZXM6IGZ1bmN0aW9uIGVudHJpZXMoKSB7XG4gICAgICByZXR1cm4gYXJyYXlFbnRyaWVzLmNhbGwodmFsaWRhdGUodGhpcykpO1xuICAgIH0sXG4gICAga2V5czogZnVuY3Rpb24ga2V5cygpIHtcbiAgICAgIHJldHVybiBhcnJheUtleXMuY2FsbCh2YWxpZGF0ZSh0aGlzKSk7XG4gICAgfSxcbiAgICB2YWx1ZXM6IGZ1bmN0aW9uIHZhbHVlcygpIHtcbiAgICAgIHJldHVybiBhcnJheVZhbHVlcy5jYWxsKHZhbGlkYXRlKHRoaXMpKTtcbiAgICB9XG4gIH07XG5cbiAgdmFyIGlzVEFJbmRleCA9IGZ1bmN0aW9uICh0YXJnZXQsIGtleSkge1xuICAgIHJldHVybiBpc09iamVjdCh0YXJnZXQpXG4gICAgICAmJiB0YXJnZXRbVFlQRURfQVJSQVldXG4gICAgICAmJiB0eXBlb2Yga2V5ICE9ICdzeW1ib2wnXG4gICAgICAmJiBrZXkgaW4gdGFyZ2V0XG4gICAgICAmJiBTdHJpbmcoK2tleSkgPT0gU3RyaW5nKGtleSk7XG4gIH07XG4gIHZhciAkZ2V0RGVzYyA9IGZ1bmN0aW9uIGdldE93blByb3BlcnR5RGVzY3JpcHRvcih0YXJnZXQsIGtleSkge1xuICAgIHJldHVybiBpc1RBSW5kZXgodGFyZ2V0LCBrZXkgPSB0b1ByaW1pdGl2ZShrZXksIHRydWUpKVxuICAgICAgPyBwcm9wZXJ0eURlc2MoMiwgdGFyZ2V0W2tleV0pXG4gICAgICA6IGdPUEQodGFyZ2V0LCBrZXkpO1xuICB9O1xuICB2YXIgJHNldERlc2MgPSBmdW5jdGlvbiBkZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGtleSwgZGVzYykge1xuICAgIGlmIChpc1RBSW5kZXgodGFyZ2V0LCBrZXkgPSB0b1ByaW1pdGl2ZShrZXksIHRydWUpKVxuICAgICAgJiYgaXNPYmplY3QoZGVzYylcbiAgICAgICYmIGhhcyhkZXNjLCAndmFsdWUnKVxuICAgICAgJiYgIWhhcyhkZXNjLCAnZ2V0JylcbiAgICAgICYmICFoYXMoZGVzYywgJ3NldCcpXG4gICAgICAvLyBUT0RPOiBhZGQgdmFsaWRhdGlvbiBkZXNjcmlwdG9yIHcvbyBjYWxsaW5nIGFjY2Vzc29yc1xuICAgICAgJiYgIWRlc2MuY29uZmlndXJhYmxlXG4gICAgICAmJiAoIWhhcyhkZXNjLCAnd3JpdGFibGUnKSB8fCBkZXNjLndyaXRhYmxlKVxuICAgICAgJiYgKCFoYXMoZGVzYywgJ2VudW1lcmFibGUnKSB8fCBkZXNjLmVudW1lcmFibGUpXG4gICAgKSB7XG4gICAgICB0YXJnZXRba2V5XSA9IGRlc2MudmFsdWU7XG4gICAgICByZXR1cm4gdGFyZ2V0O1xuICAgIH0gcmV0dXJuIGRQKHRhcmdldCwga2V5LCBkZXNjKTtcbiAgfTtcblxuICBpZiAoIUFMTF9DT05TVFJVQ1RPUlMpIHtcbiAgICAkR09QRC5mID0gJGdldERlc2M7XG4gICAgJERQLmYgPSAkc2V0RGVzYztcbiAgfVxuXG4gICRleHBvcnQoJGV4cG9ydC5TICsgJGV4cG9ydC5GICogIUFMTF9DT05TVFJVQ1RPUlMsICdPYmplY3QnLCB7XG4gICAgZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yOiAkZ2V0RGVzYyxcbiAgICBkZWZpbmVQcm9wZXJ0eTogJHNldERlc2NcbiAgfSk7XG5cbiAgaWYgKGZhaWxzKGZ1bmN0aW9uICgpIHsgYXJyYXlUb1N0cmluZy5jYWxsKHt9KTsgfSkpIHtcbiAgICBhcnJheVRvU3RyaW5nID0gYXJyYXlUb0xvY2FsZVN0cmluZyA9IGZ1bmN0aW9uIHRvU3RyaW5nKCkge1xuICAgICAgcmV0dXJuIGFycmF5Sm9pbi5jYWxsKHRoaXMpO1xuICAgIH07XG4gIH1cblxuICB2YXIgJFR5cGVkQXJyYXlQcm90b3R5cGUkID0gcmVkZWZpbmVBbGwoe30sIHByb3RvKTtcbiAgcmVkZWZpbmVBbGwoJFR5cGVkQXJyYXlQcm90b3R5cGUkLCAkaXRlcmF0b3JzKTtcbiAgaGlkZSgkVHlwZWRBcnJheVByb3RvdHlwZSQsIElURVJBVE9SLCAkaXRlcmF0b3JzLnZhbHVlcyk7XG4gIHJlZGVmaW5lQWxsKCRUeXBlZEFycmF5UHJvdG90eXBlJCwge1xuICAgIHNsaWNlOiAkc2xpY2UsXG4gICAgc2V0OiAkc2V0LFxuICAgIGNvbnN0cnVjdG9yOiBmdW5jdGlvbiAoKSB7IC8qIG5vb3AgKi8gfSxcbiAgICB0b1N0cmluZzogYXJyYXlUb1N0cmluZyxcbiAgICB0b0xvY2FsZVN0cmluZzogJHRvTG9jYWxlU3RyaW5nXG4gIH0pO1xuICBhZGRHZXR0ZXIoJFR5cGVkQXJyYXlQcm90b3R5cGUkLCAnYnVmZmVyJywgJ2InKTtcbiAgYWRkR2V0dGVyKCRUeXBlZEFycmF5UHJvdG90eXBlJCwgJ2J5dGVPZmZzZXQnLCAnbycpO1xuICBhZGRHZXR0ZXIoJFR5cGVkQXJyYXlQcm90b3R5cGUkLCAnYnl0ZUxlbmd0aCcsICdsJyk7XG4gIGFkZEdldHRlcigkVHlwZWRBcnJheVByb3RvdHlwZSQsICdsZW5ndGgnLCAnZScpO1xuICBkUCgkVHlwZWRBcnJheVByb3RvdHlwZSQsIFRBRywge1xuICAgIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpc1tUWVBFRF9BUlJBWV07IH1cbiAgfSk7XG5cbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG1heC1zdGF0ZW1lbnRzXG4gIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKEtFWSwgQllURVMsIHdyYXBwZXIsIENMQU1QRUQpIHtcbiAgICBDTEFNUEVEID0gISFDTEFNUEVEO1xuICAgIHZhciBOQU1FID0gS0VZICsgKENMQU1QRUQgPyAnQ2xhbXBlZCcgOiAnJykgKyAnQXJyYXknO1xuICAgIHZhciBHRVRURVIgPSAnZ2V0JyArIEtFWTtcbiAgICB2YXIgU0VUVEVSID0gJ3NldCcgKyBLRVk7XG4gICAgdmFyIFR5cGVkQXJyYXkgPSBnbG9iYWxbTkFNRV07XG4gICAgdmFyIEJhc2UgPSBUeXBlZEFycmF5IHx8IHt9O1xuICAgIHZhciBUQUMgPSBUeXBlZEFycmF5ICYmIGdldFByb3RvdHlwZU9mKFR5cGVkQXJyYXkpO1xuICAgIHZhciBGT1JDRUQgPSAhVHlwZWRBcnJheSB8fCAhJHR5cGVkLkFCVjtcbiAgICB2YXIgTyA9IHt9O1xuICAgIHZhciBUeXBlZEFycmF5UHJvdG90eXBlID0gVHlwZWRBcnJheSAmJiBUeXBlZEFycmF5W1BST1RPVFlQRV07XG4gICAgdmFyIGdldHRlciA9IGZ1bmN0aW9uICh0aGF0LCBpbmRleCkge1xuICAgICAgdmFyIGRhdGEgPSB0aGF0Ll9kO1xuICAgICAgcmV0dXJuIGRhdGEudltHRVRURVJdKGluZGV4ICogQllURVMgKyBkYXRhLm8sIExJVFRMRV9FTkRJQU4pO1xuICAgIH07XG4gICAgdmFyIHNldHRlciA9IGZ1bmN0aW9uICh0aGF0LCBpbmRleCwgdmFsdWUpIHtcbiAgICAgIHZhciBkYXRhID0gdGhhdC5fZDtcbiAgICAgIGlmIChDTEFNUEVEKSB2YWx1ZSA9ICh2YWx1ZSA9IE1hdGgucm91bmQodmFsdWUpKSA8IDAgPyAwIDogdmFsdWUgPiAweGZmID8gMHhmZiA6IHZhbHVlICYgMHhmZjtcbiAgICAgIGRhdGEudltTRVRURVJdKGluZGV4ICogQllURVMgKyBkYXRhLm8sIHZhbHVlLCBMSVRUTEVfRU5ESUFOKTtcbiAgICB9O1xuICAgIHZhciBhZGRFbGVtZW50ID0gZnVuY3Rpb24gKHRoYXQsIGluZGV4KSB7XG4gICAgICBkUCh0aGF0LCBpbmRleCwge1xuICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICByZXR1cm4gZ2V0dGVyKHRoaXMsIGluZGV4KTtcbiAgICAgICAgfSxcbiAgICAgICAgc2V0OiBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgICByZXR1cm4gc2V0dGVyKHRoaXMsIGluZGV4LCB2YWx1ZSk7XG4gICAgICAgIH0sXG4gICAgICAgIGVudW1lcmFibGU6IHRydWVcbiAgICAgIH0pO1xuICAgIH07XG4gICAgaWYgKEZPUkNFRCkge1xuICAgICAgVHlwZWRBcnJheSA9IHdyYXBwZXIoZnVuY3Rpb24gKHRoYXQsIGRhdGEsICRvZmZzZXQsICRsZW5ndGgpIHtcbiAgICAgICAgYW5JbnN0YW5jZSh0aGF0LCBUeXBlZEFycmF5LCBOQU1FLCAnX2QnKTtcbiAgICAgICAgdmFyIGluZGV4ID0gMDtcbiAgICAgICAgdmFyIG9mZnNldCA9IDA7XG4gICAgICAgIHZhciBidWZmZXIsIGJ5dGVMZW5ndGgsIGxlbmd0aCwga2xhc3M7XG4gICAgICAgIGlmICghaXNPYmplY3QoZGF0YSkpIHtcbiAgICAgICAgICBsZW5ndGggPSB0b0luZGV4KGRhdGEpO1xuICAgICAgICAgIGJ5dGVMZW5ndGggPSBsZW5ndGggKiBCWVRFUztcbiAgICAgICAgICBidWZmZXIgPSBuZXcgJEFycmF5QnVmZmVyKGJ5dGVMZW5ndGgpO1xuICAgICAgICB9IGVsc2UgaWYgKGRhdGEgaW5zdGFuY2VvZiAkQXJyYXlCdWZmZXIgfHwgKGtsYXNzID0gY2xhc3NvZihkYXRhKSkgPT0gQVJSQVlfQlVGRkVSIHx8IGtsYXNzID09IFNIQVJFRF9CVUZGRVIpIHtcbiAgICAgICAgICBidWZmZXIgPSBkYXRhO1xuICAgICAgICAgIG9mZnNldCA9IHRvT2Zmc2V0KCRvZmZzZXQsIEJZVEVTKTtcbiAgICAgICAgICB2YXIgJGxlbiA9IGRhdGEuYnl0ZUxlbmd0aDtcbiAgICAgICAgICBpZiAoJGxlbmd0aCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBpZiAoJGxlbiAlIEJZVEVTKSB0aHJvdyBSYW5nZUVycm9yKFdST05HX0xFTkdUSCk7XG4gICAgICAgICAgICBieXRlTGVuZ3RoID0gJGxlbiAtIG9mZnNldDtcbiAgICAgICAgICAgIGlmIChieXRlTGVuZ3RoIDwgMCkgdGhyb3cgUmFuZ2VFcnJvcihXUk9OR19MRU5HVEgpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBieXRlTGVuZ3RoID0gdG9MZW5ndGgoJGxlbmd0aCkgKiBCWVRFUztcbiAgICAgICAgICAgIGlmIChieXRlTGVuZ3RoICsgb2Zmc2V0ID4gJGxlbikgdGhyb3cgUmFuZ2VFcnJvcihXUk9OR19MRU5HVEgpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBsZW5ndGggPSBieXRlTGVuZ3RoIC8gQllURVM7XG4gICAgICAgIH0gZWxzZSBpZiAoVFlQRURfQVJSQVkgaW4gZGF0YSkge1xuICAgICAgICAgIHJldHVybiBmcm9tTGlzdChUeXBlZEFycmF5LCBkYXRhKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gJGZyb20uY2FsbChUeXBlZEFycmF5LCBkYXRhKTtcbiAgICAgICAgfVxuICAgICAgICBoaWRlKHRoYXQsICdfZCcsIHtcbiAgICAgICAgICBiOiBidWZmZXIsXG4gICAgICAgICAgbzogb2Zmc2V0LFxuICAgICAgICAgIGw6IGJ5dGVMZW5ndGgsXG4gICAgICAgICAgZTogbGVuZ3RoLFxuICAgICAgICAgIHY6IG5ldyAkRGF0YVZpZXcoYnVmZmVyKVxuICAgICAgICB9KTtcbiAgICAgICAgd2hpbGUgKGluZGV4IDwgbGVuZ3RoKSBhZGRFbGVtZW50KHRoYXQsIGluZGV4KyspO1xuICAgICAgfSk7XG4gICAgICBUeXBlZEFycmF5UHJvdG90eXBlID0gVHlwZWRBcnJheVtQUk9UT1RZUEVdID0gY3JlYXRlKCRUeXBlZEFycmF5UHJvdG90eXBlJCk7XG4gICAgICBoaWRlKFR5cGVkQXJyYXlQcm90b3R5cGUsICdjb25zdHJ1Y3RvcicsIFR5cGVkQXJyYXkpO1xuICAgIH0gZWxzZSBpZiAoIWZhaWxzKGZ1bmN0aW9uICgpIHtcbiAgICAgIFR5cGVkQXJyYXkoMSk7XG4gICAgfSkgfHwgIWZhaWxzKGZ1bmN0aW9uICgpIHtcbiAgICAgIG5ldyBUeXBlZEFycmF5KC0xKTsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1uZXdcbiAgICB9KSB8fCAhJGl0ZXJEZXRlY3QoZnVuY3Rpb24gKGl0ZXIpIHtcbiAgICAgIG5ldyBUeXBlZEFycmF5KCk7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tbmV3XG4gICAgICBuZXcgVHlwZWRBcnJheShudWxsKTsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1uZXdcbiAgICAgIG5ldyBUeXBlZEFycmF5KDEuNSk7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tbmV3XG4gICAgICBuZXcgVHlwZWRBcnJheShpdGVyKTsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1uZXdcbiAgICB9LCB0cnVlKSkge1xuICAgICAgVHlwZWRBcnJheSA9IHdyYXBwZXIoZnVuY3Rpb24gKHRoYXQsIGRhdGEsICRvZmZzZXQsICRsZW5ndGgpIHtcbiAgICAgICAgYW5JbnN0YW5jZSh0aGF0LCBUeXBlZEFycmF5LCBOQU1FKTtcbiAgICAgICAgdmFyIGtsYXNzO1xuICAgICAgICAvLyBgd3NgIG1vZHVsZSBidWcsIHRlbXBvcmFyaWx5IHJlbW92ZSB2YWxpZGF0aW9uIGxlbmd0aCBmb3IgVWludDhBcnJheVxuICAgICAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vd2Vic29ja2V0cy93cy9wdWxsLzY0NVxuICAgICAgICBpZiAoIWlzT2JqZWN0KGRhdGEpKSByZXR1cm4gbmV3IEJhc2UodG9JbmRleChkYXRhKSk7XG4gICAgICAgIGlmIChkYXRhIGluc3RhbmNlb2YgJEFycmF5QnVmZmVyIHx8IChrbGFzcyA9IGNsYXNzb2YoZGF0YSkpID09IEFSUkFZX0JVRkZFUiB8fCBrbGFzcyA9PSBTSEFSRURfQlVGRkVSKSB7XG4gICAgICAgICAgcmV0dXJuICRsZW5ndGggIT09IHVuZGVmaW5lZFxuICAgICAgICAgICAgPyBuZXcgQmFzZShkYXRhLCB0b09mZnNldCgkb2Zmc2V0LCBCWVRFUyksICRsZW5ndGgpXG4gICAgICAgICAgICA6ICRvZmZzZXQgIT09IHVuZGVmaW5lZFxuICAgICAgICAgICAgICA/IG5ldyBCYXNlKGRhdGEsIHRvT2Zmc2V0KCRvZmZzZXQsIEJZVEVTKSlcbiAgICAgICAgICAgICAgOiBuZXcgQmFzZShkYXRhKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoVFlQRURfQVJSQVkgaW4gZGF0YSkgcmV0dXJuIGZyb21MaXN0KFR5cGVkQXJyYXksIGRhdGEpO1xuICAgICAgICByZXR1cm4gJGZyb20uY2FsbChUeXBlZEFycmF5LCBkYXRhKTtcbiAgICAgIH0pO1xuICAgICAgYXJyYXlGb3JFYWNoKFRBQyAhPT0gRnVuY3Rpb24ucHJvdG90eXBlID8gZ09QTihCYXNlKS5jb25jYXQoZ09QTihUQUMpKSA6IGdPUE4oQmFzZSksIGZ1bmN0aW9uIChrZXkpIHtcbiAgICAgICAgaWYgKCEoa2V5IGluIFR5cGVkQXJyYXkpKSBoaWRlKFR5cGVkQXJyYXksIGtleSwgQmFzZVtrZXldKTtcbiAgICAgIH0pO1xuICAgICAgVHlwZWRBcnJheVtQUk9UT1RZUEVdID0gVHlwZWRBcnJheVByb3RvdHlwZTtcbiAgICAgIGlmICghTElCUkFSWSkgVHlwZWRBcnJheVByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IFR5cGVkQXJyYXk7XG4gICAgfVxuICAgIHZhciAkbmF0aXZlSXRlcmF0b3IgPSBUeXBlZEFycmF5UHJvdG90eXBlW0lURVJBVE9SXTtcbiAgICB2YXIgQ09SUkVDVF9JVEVSX05BTUUgPSAhISRuYXRpdmVJdGVyYXRvclxuICAgICAgJiYgKCRuYXRpdmVJdGVyYXRvci5uYW1lID09ICd2YWx1ZXMnIHx8ICRuYXRpdmVJdGVyYXRvci5uYW1lID09IHVuZGVmaW5lZCk7XG4gICAgdmFyICRpdGVyYXRvciA9ICRpdGVyYXRvcnMudmFsdWVzO1xuICAgIGhpZGUoVHlwZWRBcnJheSwgVFlQRURfQ09OU1RSVUNUT1IsIHRydWUpO1xuICAgIGhpZGUoVHlwZWRBcnJheVByb3RvdHlwZSwgVFlQRURfQVJSQVksIE5BTUUpO1xuICAgIGhpZGUoVHlwZWRBcnJheVByb3RvdHlwZSwgVklFVywgdHJ1ZSk7XG4gICAgaGlkZShUeXBlZEFycmF5UHJvdG90eXBlLCBERUZfQ09OU1RSVUNUT1IsIFR5cGVkQXJyYXkpO1xuXG4gICAgaWYgKENMQU1QRUQgPyBuZXcgVHlwZWRBcnJheSgxKVtUQUddICE9IE5BTUUgOiAhKFRBRyBpbiBUeXBlZEFycmF5UHJvdG90eXBlKSkge1xuICAgICAgZFAoVHlwZWRBcnJheVByb3RvdHlwZSwgVEFHLCB7XG4gICAgICAgIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gTkFNRTsgfVxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgT1tOQU1FXSA9IFR5cGVkQXJyYXk7XG5cbiAgICAkZXhwb3J0KCRleHBvcnQuRyArICRleHBvcnQuVyArICRleHBvcnQuRiAqIChUeXBlZEFycmF5ICE9IEJhc2UpLCBPKTtcblxuICAgICRleHBvcnQoJGV4cG9ydC5TLCBOQU1FLCB7XG4gICAgICBCWVRFU19QRVJfRUxFTUVOVDogQllURVNcbiAgICB9KTtcblxuICAgICRleHBvcnQoJGV4cG9ydC5TICsgJGV4cG9ydC5GICogZmFpbHMoZnVuY3Rpb24gKCkgeyBCYXNlLm9mLmNhbGwoVHlwZWRBcnJheSwgMSk7IH0pLCBOQU1FLCB7XG4gICAgICBmcm9tOiAkZnJvbSxcbiAgICAgIG9mOiAkb2ZcbiAgICB9KTtcblxuICAgIGlmICghKEJZVEVTX1BFUl9FTEVNRU5UIGluIFR5cGVkQXJyYXlQcm90b3R5cGUpKSBoaWRlKFR5cGVkQXJyYXlQcm90b3R5cGUsIEJZVEVTX1BFUl9FTEVNRU5ULCBCWVRFUyk7XG5cbiAgICAkZXhwb3J0KCRleHBvcnQuUCwgTkFNRSwgcHJvdG8pO1xuXG4gICAgc2V0U3BlY2llcyhOQU1FKTtcblxuICAgICRleHBvcnQoJGV4cG9ydC5QICsgJGV4cG9ydC5GICogRk9SQ0VEX1NFVCwgTkFNRSwgeyBzZXQ6ICRzZXQgfSk7XG5cbiAgICAkZXhwb3J0KCRleHBvcnQuUCArICRleHBvcnQuRiAqICFDT1JSRUNUX0lURVJfTkFNRSwgTkFNRSwgJGl0ZXJhdG9ycyk7XG5cbiAgICBpZiAoIUxJQlJBUlkgJiYgVHlwZWRBcnJheVByb3RvdHlwZS50b1N0cmluZyAhPSBhcnJheVRvU3RyaW5nKSBUeXBlZEFycmF5UHJvdG90eXBlLnRvU3RyaW5nID0gYXJyYXlUb1N0cmluZztcblxuICAgICRleHBvcnQoJGV4cG9ydC5QICsgJGV4cG9ydC5GICogZmFpbHMoZnVuY3Rpb24gKCkge1xuICAgICAgbmV3IFR5cGVkQXJyYXkoMSkuc2xpY2UoKTtcbiAgICB9KSwgTkFNRSwgeyBzbGljZTogJHNsaWNlIH0pO1xuXG4gICAgJGV4cG9ydCgkZXhwb3J0LlAgKyAkZXhwb3J0LkYgKiAoZmFpbHMoZnVuY3Rpb24gKCkge1xuICAgICAgcmV0dXJuIFsxLCAyXS50b0xvY2FsZVN0cmluZygpICE9IG5ldyBUeXBlZEFycmF5KFsxLCAyXSkudG9Mb2NhbGVTdHJpbmcoKTtcbiAgICB9KSB8fCAhZmFpbHMoZnVuY3Rpb24gKCkge1xuICAgICAgVHlwZWRBcnJheVByb3RvdHlwZS50b0xvY2FsZVN0cmluZy5jYWxsKFsxLCAyXSk7XG4gICAgfSkpLCBOQU1FLCB7IHRvTG9jYWxlU3RyaW5nOiAkdG9Mb2NhbGVTdHJpbmcgfSk7XG5cbiAgICBJdGVyYXRvcnNbTkFNRV0gPSBDT1JSRUNUX0lURVJfTkFNRSA/ICRuYXRpdmVJdGVyYXRvciA6ICRpdGVyYXRvcjtcbiAgICBpZiAoIUxJQlJBUlkgJiYgIUNPUlJFQ1RfSVRFUl9OQU1FKSBoaWRlKFR5cGVkQXJyYXlQcm90b3R5cGUsIElURVJBVE9SLCAkaXRlcmF0b3IpO1xuICB9O1xufSBlbHNlIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKCkgeyAvKiBlbXB0eSAqLyB9O1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyIGdsb2JhbCA9IHJlcXVpcmUoJy4vX2dsb2JhbCcpO1xudmFyIERFU0NSSVBUT1JTID0gcmVxdWlyZSgnLi9fZGVzY3JpcHRvcnMnKTtcbnZhciBMSUJSQVJZID0gcmVxdWlyZSgnLi9fbGlicmFyeScpO1xudmFyICR0eXBlZCA9IHJlcXVpcmUoJy4vX3R5cGVkJyk7XG52YXIgaGlkZSA9IHJlcXVpcmUoJy4vX2hpZGUnKTtcbnZhciByZWRlZmluZUFsbCA9IHJlcXVpcmUoJy4vX3JlZGVmaW5lLWFsbCcpO1xudmFyIGZhaWxzID0gcmVxdWlyZSgnLi9fZmFpbHMnKTtcbnZhciBhbkluc3RhbmNlID0gcmVxdWlyZSgnLi9fYW4taW5zdGFuY2UnKTtcbnZhciB0b0ludGVnZXIgPSByZXF1aXJlKCcuL190by1pbnRlZ2VyJyk7XG52YXIgdG9MZW5ndGggPSByZXF1aXJlKCcuL190by1sZW5ndGgnKTtcbnZhciB0b0luZGV4ID0gcmVxdWlyZSgnLi9fdG8taW5kZXgnKTtcbnZhciBnT1BOID0gcmVxdWlyZSgnLi9fb2JqZWN0LWdvcG4nKS5mO1xudmFyIGRQID0gcmVxdWlyZSgnLi9fb2JqZWN0LWRwJykuZjtcbnZhciBhcnJheUZpbGwgPSByZXF1aXJlKCcuL19hcnJheS1maWxsJyk7XG52YXIgc2V0VG9TdHJpbmdUYWcgPSByZXF1aXJlKCcuL19zZXQtdG8tc3RyaW5nLXRhZycpO1xudmFyIEFSUkFZX0JVRkZFUiA9ICdBcnJheUJ1ZmZlcic7XG52YXIgREFUQV9WSUVXID0gJ0RhdGFWaWV3JztcbnZhciBQUk9UT1RZUEUgPSAncHJvdG90eXBlJztcbnZhciBXUk9OR19MRU5HVEggPSAnV3JvbmcgbGVuZ3RoISc7XG52YXIgV1JPTkdfSU5ERVggPSAnV3JvbmcgaW5kZXghJztcbnZhciAkQXJyYXlCdWZmZXIgPSBnbG9iYWxbQVJSQVlfQlVGRkVSXTtcbnZhciAkRGF0YVZpZXcgPSBnbG9iYWxbREFUQV9WSUVXXTtcbnZhciBNYXRoID0gZ2xvYmFsLk1hdGg7XG52YXIgUmFuZ2VFcnJvciA9IGdsb2JhbC5SYW5nZUVycm9yO1xuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXNoYWRvdy1yZXN0cmljdGVkLW5hbWVzXG52YXIgSW5maW5pdHkgPSBnbG9iYWwuSW5maW5pdHk7XG52YXIgQmFzZUJ1ZmZlciA9ICRBcnJheUJ1ZmZlcjtcbnZhciBhYnMgPSBNYXRoLmFicztcbnZhciBwb3cgPSBNYXRoLnBvdztcbnZhciBmbG9vciA9IE1hdGguZmxvb3I7XG52YXIgbG9nID0gTWF0aC5sb2c7XG52YXIgTE4yID0gTWF0aC5MTjI7XG52YXIgQlVGRkVSID0gJ2J1ZmZlcic7XG52YXIgQllURV9MRU5HVEggPSAnYnl0ZUxlbmd0aCc7XG52YXIgQllURV9PRkZTRVQgPSAnYnl0ZU9mZnNldCc7XG52YXIgJEJVRkZFUiA9IERFU0NSSVBUT1JTID8gJ19iJyA6IEJVRkZFUjtcbnZhciAkTEVOR1RIID0gREVTQ1JJUFRPUlMgPyAnX2wnIDogQllURV9MRU5HVEg7XG52YXIgJE9GRlNFVCA9IERFU0NSSVBUT1JTID8gJ19vJyA6IEJZVEVfT0ZGU0VUO1xuXG4vLyBJRUVFNzU0IGNvbnZlcnNpb25zIGJhc2VkIG9uIGh0dHBzOi8vZ2l0aHViLmNvbS9mZXJvc3MvaWVlZTc1NFxuZnVuY3Rpb24gcGFja0lFRUU3NTQodmFsdWUsIG1MZW4sIG5CeXRlcykge1xuICB2YXIgYnVmZmVyID0gbmV3IEFycmF5KG5CeXRlcyk7XG4gIHZhciBlTGVuID0gbkJ5dGVzICogOCAtIG1MZW4gLSAxO1xuICB2YXIgZU1heCA9ICgxIDw8IGVMZW4pIC0gMTtcbiAgdmFyIGVCaWFzID0gZU1heCA+PiAxO1xuICB2YXIgcnQgPSBtTGVuID09PSAyMyA/IHBvdygyLCAtMjQpIC0gcG93KDIsIC03NykgOiAwO1xuICB2YXIgaSA9IDA7XG4gIHZhciBzID0gdmFsdWUgPCAwIHx8IHZhbHVlID09PSAwICYmIDEgLyB2YWx1ZSA8IDAgPyAxIDogMDtcbiAgdmFyIGUsIG0sIGM7XG4gIHZhbHVlID0gYWJzKHZhbHVlKTtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXNlbGYtY29tcGFyZVxuICBpZiAodmFsdWUgIT0gdmFsdWUgfHwgdmFsdWUgPT09IEluZmluaXR5KSB7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXNlbGYtY29tcGFyZVxuICAgIG0gPSB2YWx1ZSAhPSB2YWx1ZSA/IDEgOiAwO1xuICAgIGUgPSBlTWF4O1xuICB9IGVsc2Uge1xuICAgIGUgPSBmbG9vcihsb2codmFsdWUpIC8gTE4yKTtcbiAgICBpZiAodmFsdWUgKiAoYyA9IHBvdygyLCAtZSkpIDwgMSkge1xuICAgICAgZS0tO1xuICAgICAgYyAqPSAyO1xuICAgIH1cbiAgICBpZiAoZSArIGVCaWFzID49IDEpIHtcbiAgICAgIHZhbHVlICs9IHJ0IC8gYztcbiAgICB9IGVsc2Uge1xuICAgICAgdmFsdWUgKz0gcnQgKiBwb3coMiwgMSAtIGVCaWFzKTtcbiAgICB9XG4gICAgaWYgKHZhbHVlICogYyA+PSAyKSB7XG4gICAgICBlKys7XG4gICAgICBjIC89IDI7XG4gICAgfVxuICAgIGlmIChlICsgZUJpYXMgPj0gZU1heCkge1xuICAgICAgbSA9IDA7XG4gICAgICBlID0gZU1heDtcbiAgICB9IGVsc2UgaWYgKGUgKyBlQmlhcyA+PSAxKSB7XG4gICAgICBtID0gKHZhbHVlICogYyAtIDEpICogcG93KDIsIG1MZW4pO1xuICAgICAgZSA9IGUgKyBlQmlhcztcbiAgICB9IGVsc2Uge1xuICAgICAgbSA9IHZhbHVlICogcG93KDIsIGVCaWFzIC0gMSkgKiBwb3coMiwgbUxlbik7XG4gICAgICBlID0gMDtcbiAgICB9XG4gIH1cbiAgZm9yICg7IG1MZW4gPj0gODsgYnVmZmVyW2krK10gPSBtICYgMjU1LCBtIC89IDI1NiwgbUxlbiAtPSA4KTtcbiAgZSA9IGUgPDwgbUxlbiB8IG07XG4gIGVMZW4gKz0gbUxlbjtcbiAgZm9yICg7IGVMZW4gPiAwOyBidWZmZXJbaSsrXSA9IGUgJiAyNTUsIGUgLz0gMjU2LCBlTGVuIC09IDgpO1xuICBidWZmZXJbLS1pXSB8PSBzICogMTI4O1xuICByZXR1cm4gYnVmZmVyO1xufVxuZnVuY3Rpb24gdW5wYWNrSUVFRTc1NChidWZmZXIsIG1MZW4sIG5CeXRlcykge1xuICB2YXIgZUxlbiA9IG5CeXRlcyAqIDggLSBtTGVuIC0gMTtcbiAgdmFyIGVNYXggPSAoMSA8PCBlTGVuKSAtIDE7XG4gIHZhciBlQmlhcyA9IGVNYXggPj4gMTtcbiAgdmFyIG5CaXRzID0gZUxlbiAtIDc7XG4gIHZhciBpID0gbkJ5dGVzIC0gMTtcbiAgdmFyIHMgPSBidWZmZXJbaS0tXTtcbiAgdmFyIGUgPSBzICYgMTI3O1xuICB2YXIgbTtcbiAgcyA+Pj0gNztcbiAgZm9yICg7IG5CaXRzID4gMDsgZSA9IGUgKiAyNTYgKyBidWZmZXJbaV0sIGktLSwgbkJpdHMgLT0gOCk7XG4gIG0gPSBlICYgKDEgPDwgLW5CaXRzKSAtIDE7XG4gIGUgPj49IC1uQml0cztcbiAgbkJpdHMgKz0gbUxlbjtcbiAgZm9yICg7IG5CaXRzID4gMDsgbSA9IG0gKiAyNTYgKyBidWZmZXJbaV0sIGktLSwgbkJpdHMgLT0gOCk7XG4gIGlmIChlID09PSAwKSB7XG4gICAgZSA9IDEgLSBlQmlhcztcbiAgfSBlbHNlIGlmIChlID09PSBlTWF4KSB7XG4gICAgcmV0dXJuIG0gPyBOYU4gOiBzID8gLUluZmluaXR5IDogSW5maW5pdHk7XG4gIH0gZWxzZSB7XG4gICAgbSA9IG0gKyBwb3coMiwgbUxlbik7XG4gICAgZSA9IGUgLSBlQmlhcztcbiAgfSByZXR1cm4gKHMgPyAtMSA6IDEpICogbSAqIHBvdygyLCBlIC0gbUxlbik7XG59XG5cbmZ1bmN0aW9uIHVucGFja0kzMihieXRlcykge1xuICByZXR1cm4gYnl0ZXNbM10gPDwgMjQgfCBieXRlc1syXSA8PCAxNiB8IGJ5dGVzWzFdIDw8IDggfCBieXRlc1swXTtcbn1cbmZ1bmN0aW9uIHBhY2tJOChpdCkge1xuICByZXR1cm4gW2l0ICYgMHhmZl07XG59XG5mdW5jdGlvbiBwYWNrSTE2KGl0KSB7XG4gIHJldHVybiBbaXQgJiAweGZmLCBpdCA+PiA4ICYgMHhmZl07XG59XG5mdW5jdGlvbiBwYWNrSTMyKGl0KSB7XG4gIHJldHVybiBbaXQgJiAweGZmLCBpdCA+PiA4ICYgMHhmZiwgaXQgPj4gMTYgJiAweGZmLCBpdCA+PiAyNCAmIDB4ZmZdO1xufVxuZnVuY3Rpb24gcGFja0Y2NChpdCkge1xuICByZXR1cm4gcGFja0lFRUU3NTQoaXQsIDUyLCA4KTtcbn1cbmZ1bmN0aW9uIHBhY2tGMzIoaXQpIHtcbiAgcmV0dXJuIHBhY2tJRUVFNzU0KGl0LCAyMywgNCk7XG59XG5cbmZ1bmN0aW9uIGFkZEdldHRlcihDLCBrZXksIGludGVybmFsKSB7XG4gIGRQKENbUFJPVE9UWVBFXSwga2V5LCB7IGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpc1tpbnRlcm5hbF07IH0gfSk7XG59XG5cbmZ1bmN0aW9uIGdldCh2aWV3LCBieXRlcywgaW5kZXgsIGlzTGl0dGxlRW5kaWFuKSB7XG4gIHZhciBudW1JbmRleCA9ICtpbmRleDtcbiAgdmFyIGludEluZGV4ID0gdG9JbmRleChudW1JbmRleCk7XG4gIGlmIChpbnRJbmRleCArIGJ5dGVzID4gdmlld1skTEVOR1RIXSkgdGhyb3cgUmFuZ2VFcnJvcihXUk9OR19JTkRFWCk7XG4gIHZhciBzdG9yZSA9IHZpZXdbJEJVRkZFUl0uX2I7XG4gIHZhciBzdGFydCA9IGludEluZGV4ICsgdmlld1skT0ZGU0VUXTtcbiAgdmFyIHBhY2sgPSBzdG9yZS5zbGljZShzdGFydCwgc3RhcnQgKyBieXRlcyk7XG4gIHJldHVybiBpc0xpdHRsZUVuZGlhbiA/IHBhY2sgOiBwYWNrLnJldmVyc2UoKTtcbn1cbmZ1bmN0aW9uIHNldCh2aWV3LCBieXRlcywgaW5kZXgsIGNvbnZlcnNpb24sIHZhbHVlLCBpc0xpdHRsZUVuZGlhbikge1xuICB2YXIgbnVtSW5kZXggPSAraW5kZXg7XG4gIHZhciBpbnRJbmRleCA9IHRvSW5kZXgobnVtSW5kZXgpO1xuICBpZiAoaW50SW5kZXggKyBieXRlcyA+IHZpZXdbJExFTkdUSF0pIHRocm93IFJhbmdlRXJyb3IoV1JPTkdfSU5ERVgpO1xuICB2YXIgc3RvcmUgPSB2aWV3WyRCVUZGRVJdLl9iO1xuICB2YXIgc3RhcnQgPSBpbnRJbmRleCArIHZpZXdbJE9GRlNFVF07XG4gIHZhciBwYWNrID0gY29udmVyc2lvbigrdmFsdWUpO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGJ5dGVzOyBpKyspIHN0b3JlW3N0YXJ0ICsgaV0gPSBwYWNrW2lzTGl0dGxlRW5kaWFuID8gaSA6IGJ5dGVzIC0gaSAtIDFdO1xufVxuXG5pZiAoISR0eXBlZC5BQlYpIHtcbiAgJEFycmF5QnVmZmVyID0gZnVuY3Rpb24gQXJyYXlCdWZmZXIobGVuZ3RoKSB7XG4gICAgYW5JbnN0YW5jZSh0aGlzLCAkQXJyYXlCdWZmZXIsIEFSUkFZX0JVRkZFUik7XG4gICAgdmFyIGJ5dGVMZW5ndGggPSB0b0luZGV4KGxlbmd0aCk7XG4gICAgdGhpcy5fYiA9IGFycmF5RmlsbC5jYWxsKG5ldyBBcnJheShieXRlTGVuZ3RoKSwgMCk7XG4gICAgdGhpc1skTEVOR1RIXSA9IGJ5dGVMZW5ndGg7XG4gIH07XG5cbiAgJERhdGFWaWV3ID0gZnVuY3Rpb24gRGF0YVZpZXcoYnVmZmVyLCBieXRlT2Zmc2V0LCBieXRlTGVuZ3RoKSB7XG4gICAgYW5JbnN0YW5jZSh0aGlzLCAkRGF0YVZpZXcsIERBVEFfVklFVyk7XG4gICAgYW5JbnN0YW5jZShidWZmZXIsICRBcnJheUJ1ZmZlciwgREFUQV9WSUVXKTtcbiAgICB2YXIgYnVmZmVyTGVuZ3RoID0gYnVmZmVyWyRMRU5HVEhdO1xuICAgIHZhciBvZmZzZXQgPSB0b0ludGVnZXIoYnl0ZU9mZnNldCk7XG4gICAgaWYgKG9mZnNldCA8IDAgfHwgb2Zmc2V0ID4gYnVmZmVyTGVuZ3RoKSB0aHJvdyBSYW5nZUVycm9yKCdXcm9uZyBvZmZzZXQhJyk7XG4gICAgYnl0ZUxlbmd0aCA9IGJ5dGVMZW5ndGggPT09IHVuZGVmaW5lZCA/IGJ1ZmZlckxlbmd0aCAtIG9mZnNldCA6IHRvTGVuZ3RoKGJ5dGVMZW5ndGgpO1xuICAgIGlmIChvZmZzZXQgKyBieXRlTGVuZ3RoID4gYnVmZmVyTGVuZ3RoKSB0aHJvdyBSYW5nZUVycm9yKFdST05HX0xFTkdUSCk7XG4gICAgdGhpc1skQlVGRkVSXSA9IGJ1ZmZlcjtcbiAgICB0aGlzWyRPRkZTRVRdID0gb2Zmc2V0O1xuICAgIHRoaXNbJExFTkdUSF0gPSBieXRlTGVuZ3RoO1xuICB9O1xuXG4gIGlmIChERVNDUklQVE9SUykge1xuICAgIGFkZEdldHRlcigkQXJyYXlCdWZmZXIsIEJZVEVfTEVOR1RILCAnX2wnKTtcbiAgICBhZGRHZXR0ZXIoJERhdGFWaWV3LCBCVUZGRVIsICdfYicpO1xuICAgIGFkZEdldHRlcigkRGF0YVZpZXcsIEJZVEVfTEVOR1RILCAnX2wnKTtcbiAgICBhZGRHZXR0ZXIoJERhdGFWaWV3LCBCWVRFX09GRlNFVCwgJ19vJyk7XG4gIH1cblxuICByZWRlZmluZUFsbCgkRGF0YVZpZXdbUFJPVE9UWVBFXSwge1xuICAgIGdldEludDg6IGZ1bmN0aW9uIGdldEludDgoYnl0ZU9mZnNldCkge1xuICAgICAgcmV0dXJuIGdldCh0aGlzLCAxLCBieXRlT2Zmc2V0KVswXSA8PCAyNCA+PiAyNDtcbiAgICB9LFxuICAgIGdldFVpbnQ4OiBmdW5jdGlvbiBnZXRVaW50OChieXRlT2Zmc2V0KSB7XG4gICAgICByZXR1cm4gZ2V0KHRoaXMsIDEsIGJ5dGVPZmZzZXQpWzBdO1xuICAgIH0sXG4gICAgZ2V0SW50MTY6IGZ1bmN0aW9uIGdldEludDE2KGJ5dGVPZmZzZXQgLyogLCBsaXR0bGVFbmRpYW4gKi8pIHtcbiAgICAgIHZhciBieXRlcyA9IGdldCh0aGlzLCAyLCBieXRlT2Zmc2V0LCBhcmd1bWVudHNbMV0pO1xuICAgICAgcmV0dXJuIChieXRlc1sxXSA8PCA4IHwgYnl0ZXNbMF0pIDw8IDE2ID4+IDE2O1xuICAgIH0sXG4gICAgZ2V0VWludDE2OiBmdW5jdGlvbiBnZXRVaW50MTYoYnl0ZU9mZnNldCAvKiAsIGxpdHRsZUVuZGlhbiAqLykge1xuICAgICAgdmFyIGJ5dGVzID0gZ2V0KHRoaXMsIDIsIGJ5dGVPZmZzZXQsIGFyZ3VtZW50c1sxXSk7XG4gICAgICByZXR1cm4gYnl0ZXNbMV0gPDwgOCB8IGJ5dGVzWzBdO1xuICAgIH0sXG4gICAgZ2V0SW50MzI6IGZ1bmN0aW9uIGdldEludDMyKGJ5dGVPZmZzZXQgLyogLCBsaXR0bGVFbmRpYW4gKi8pIHtcbiAgICAgIHJldHVybiB1bnBhY2tJMzIoZ2V0KHRoaXMsIDQsIGJ5dGVPZmZzZXQsIGFyZ3VtZW50c1sxXSkpO1xuICAgIH0sXG4gICAgZ2V0VWludDMyOiBmdW5jdGlvbiBnZXRVaW50MzIoYnl0ZU9mZnNldCAvKiAsIGxpdHRsZUVuZGlhbiAqLykge1xuICAgICAgcmV0dXJuIHVucGFja0kzMihnZXQodGhpcywgNCwgYnl0ZU9mZnNldCwgYXJndW1lbnRzWzFdKSkgPj4+IDA7XG4gICAgfSxcbiAgICBnZXRGbG9hdDMyOiBmdW5jdGlvbiBnZXRGbG9hdDMyKGJ5dGVPZmZzZXQgLyogLCBsaXR0bGVFbmRpYW4gKi8pIHtcbiAgICAgIHJldHVybiB1bnBhY2tJRUVFNzU0KGdldCh0aGlzLCA0LCBieXRlT2Zmc2V0LCBhcmd1bWVudHNbMV0pLCAyMywgNCk7XG4gICAgfSxcbiAgICBnZXRGbG9hdDY0OiBmdW5jdGlvbiBnZXRGbG9hdDY0KGJ5dGVPZmZzZXQgLyogLCBsaXR0bGVFbmRpYW4gKi8pIHtcbiAgICAgIHJldHVybiB1bnBhY2tJRUVFNzU0KGdldCh0aGlzLCA4LCBieXRlT2Zmc2V0LCBhcmd1bWVudHNbMV0pLCA1MiwgOCk7XG4gICAgfSxcbiAgICBzZXRJbnQ4OiBmdW5jdGlvbiBzZXRJbnQ4KGJ5dGVPZmZzZXQsIHZhbHVlKSB7XG4gICAgICBzZXQodGhpcywgMSwgYnl0ZU9mZnNldCwgcGFja0k4LCB2YWx1ZSk7XG4gICAgfSxcbiAgICBzZXRVaW50ODogZnVuY3Rpb24gc2V0VWludDgoYnl0ZU9mZnNldCwgdmFsdWUpIHtcbiAgICAgIHNldCh0aGlzLCAxLCBieXRlT2Zmc2V0LCBwYWNrSTgsIHZhbHVlKTtcbiAgICB9LFxuICAgIHNldEludDE2OiBmdW5jdGlvbiBzZXRJbnQxNihieXRlT2Zmc2V0LCB2YWx1ZSAvKiAsIGxpdHRsZUVuZGlhbiAqLykge1xuICAgICAgc2V0KHRoaXMsIDIsIGJ5dGVPZmZzZXQsIHBhY2tJMTYsIHZhbHVlLCBhcmd1bWVudHNbMl0pO1xuICAgIH0sXG4gICAgc2V0VWludDE2OiBmdW5jdGlvbiBzZXRVaW50MTYoYnl0ZU9mZnNldCwgdmFsdWUgLyogLCBsaXR0bGVFbmRpYW4gKi8pIHtcbiAgICAgIHNldCh0aGlzLCAyLCBieXRlT2Zmc2V0LCBwYWNrSTE2LCB2YWx1ZSwgYXJndW1lbnRzWzJdKTtcbiAgICB9LFxuICAgIHNldEludDMyOiBmdW5jdGlvbiBzZXRJbnQzMihieXRlT2Zmc2V0LCB2YWx1ZSAvKiAsIGxpdHRsZUVuZGlhbiAqLykge1xuICAgICAgc2V0KHRoaXMsIDQsIGJ5dGVPZmZzZXQsIHBhY2tJMzIsIHZhbHVlLCBhcmd1bWVudHNbMl0pO1xuICAgIH0sXG4gICAgc2V0VWludDMyOiBmdW5jdGlvbiBzZXRVaW50MzIoYnl0ZU9mZnNldCwgdmFsdWUgLyogLCBsaXR0bGVFbmRpYW4gKi8pIHtcbiAgICAgIHNldCh0aGlzLCA0LCBieXRlT2Zmc2V0LCBwYWNrSTMyLCB2YWx1ZSwgYXJndW1lbnRzWzJdKTtcbiAgICB9LFxuICAgIHNldEZsb2F0MzI6IGZ1bmN0aW9uIHNldEZsb2F0MzIoYnl0ZU9mZnNldCwgdmFsdWUgLyogLCBsaXR0bGVFbmRpYW4gKi8pIHtcbiAgICAgIHNldCh0aGlzLCA0LCBieXRlT2Zmc2V0LCBwYWNrRjMyLCB2YWx1ZSwgYXJndW1lbnRzWzJdKTtcbiAgICB9LFxuICAgIHNldEZsb2F0NjQ6IGZ1bmN0aW9uIHNldEZsb2F0NjQoYnl0ZU9mZnNldCwgdmFsdWUgLyogLCBsaXR0bGVFbmRpYW4gKi8pIHtcbiAgICAgIHNldCh0aGlzLCA4LCBieXRlT2Zmc2V0LCBwYWNrRjY0LCB2YWx1ZSwgYXJndW1lbnRzWzJdKTtcbiAgICB9XG4gIH0pO1xufSBlbHNlIHtcbiAgaWYgKCFmYWlscyhmdW5jdGlvbiAoKSB7XG4gICAgJEFycmF5QnVmZmVyKDEpO1xuICB9KSB8fCAhZmFpbHMoZnVuY3Rpb24gKCkge1xuICAgIG5ldyAkQXJyYXlCdWZmZXIoLTEpOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLW5ld1xuICB9KSB8fCBmYWlscyhmdW5jdGlvbiAoKSB7XG4gICAgbmV3ICRBcnJheUJ1ZmZlcigpOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLW5ld1xuICAgIG5ldyAkQXJyYXlCdWZmZXIoMS41KTsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1uZXdcbiAgICBuZXcgJEFycmF5QnVmZmVyKE5hTik7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tbmV3XG4gICAgcmV0dXJuICRBcnJheUJ1ZmZlci5uYW1lICE9IEFSUkFZX0JVRkZFUjtcbiAgfSkpIHtcbiAgICAkQXJyYXlCdWZmZXIgPSBmdW5jdGlvbiBBcnJheUJ1ZmZlcihsZW5ndGgpIHtcbiAgICAgIGFuSW5zdGFuY2UodGhpcywgJEFycmF5QnVmZmVyKTtcbiAgICAgIHJldHVybiBuZXcgQmFzZUJ1ZmZlcih0b0luZGV4KGxlbmd0aCkpO1xuICAgIH07XG4gICAgdmFyIEFycmF5QnVmZmVyUHJvdG8gPSAkQXJyYXlCdWZmZXJbUFJPVE9UWVBFXSA9IEJhc2VCdWZmZXJbUFJPVE9UWVBFXTtcbiAgICBmb3IgKHZhciBrZXlzID0gZ09QTihCYXNlQnVmZmVyKSwgaiA9IDAsIGtleTsga2V5cy5sZW5ndGggPiBqOykge1xuICAgICAgaWYgKCEoKGtleSA9IGtleXNbaisrXSkgaW4gJEFycmF5QnVmZmVyKSkgaGlkZSgkQXJyYXlCdWZmZXIsIGtleSwgQmFzZUJ1ZmZlcltrZXldKTtcbiAgICB9XG4gICAgaWYgKCFMSUJSQVJZKSBBcnJheUJ1ZmZlclByb3RvLmNvbnN0cnVjdG9yID0gJEFycmF5QnVmZmVyO1xuICB9XG4gIC8vIGlPUyBTYWZhcmkgNy54IGJ1Z1xuICB2YXIgdmlldyA9IG5ldyAkRGF0YVZpZXcobmV3ICRBcnJheUJ1ZmZlcigyKSk7XG4gIHZhciAkc2V0SW50OCA9ICREYXRhVmlld1tQUk9UT1RZUEVdLnNldEludDg7XG4gIHZpZXcuc2V0SW50OCgwLCAyMTQ3NDgzNjQ4KTtcbiAgdmlldy5zZXRJbnQ4KDEsIDIxNDc0ODM2NDkpO1xuICBpZiAodmlldy5nZXRJbnQ4KDApIHx8ICF2aWV3LmdldEludDgoMSkpIHJlZGVmaW5lQWxsKCREYXRhVmlld1tQUk9UT1RZUEVdLCB7XG4gICAgc2V0SW50ODogZnVuY3Rpb24gc2V0SW50OChieXRlT2Zmc2V0LCB2YWx1ZSkge1xuICAgICAgJHNldEludDguY2FsbCh0aGlzLCBieXRlT2Zmc2V0LCB2YWx1ZSA8PCAyNCA+PiAyNCk7XG4gICAgfSxcbiAgICBzZXRVaW50ODogZnVuY3Rpb24gc2V0VWludDgoYnl0ZU9mZnNldCwgdmFsdWUpIHtcbiAgICAgICRzZXRJbnQ4LmNhbGwodGhpcywgYnl0ZU9mZnNldCwgdmFsdWUgPDwgMjQgPj4gMjQpO1xuICAgIH1cbiAgfSwgdHJ1ZSk7XG59XG5zZXRUb1N0cmluZ1RhZygkQXJyYXlCdWZmZXIsIEFSUkFZX0JVRkZFUik7XG5zZXRUb1N0cmluZ1RhZygkRGF0YVZpZXcsIERBVEFfVklFVyk7XG5oaWRlKCREYXRhVmlld1tQUk9UT1RZUEVdLCAkdHlwZWQuVklFVywgdHJ1ZSk7XG5leHBvcnRzW0FSUkFZX0JVRkZFUl0gPSAkQXJyYXlCdWZmZXI7XG5leHBvcnRzW0RBVEFfVklFV10gPSAkRGF0YVZpZXc7XG4iLCJ2YXIgZ2xvYmFsID0gcmVxdWlyZSgnLi9fZ2xvYmFsJyk7XG52YXIgaGlkZSA9IHJlcXVpcmUoJy4vX2hpZGUnKTtcbnZhciB1aWQgPSByZXF1aXJlKCcuL191aWQnKTtcbnZhciBUWVBFRCA9IHVpZCgndHlwZWRfYXJyYXknKTtcbnZhciBWSUVXID0gdWlkKCd2aWV3Jyk7XG52YXIgQUJWID0gISEoZ2xvYmFsLkFycmF5QnVmZmVyICYmIGdsb2JhbC5EYXRhVmlldyk7XG52YXIgQ09OU1RSID0gQUJWO1xudmFyIGkgPSAwO1xudmFyIGwgPSA5O1xudmFyIFR5cGVkO1xuXG52YXIgVHlwZWRBcnJheUNvbnN0cnVjdG9ycyA9IChcbiAgJ0ludDhBcnJheSxVaW50OEFycmF5LFVpbnQ4Q2xhbXBlZEFycmF5LEludDE2QXJyYXksVWludDE2QXJyYXksSW50MzJBcnJheSxVaW50MzJBcnJheSxGbG9hdDMyQXJyYXksRmxvYXQ2NEFycmF5J1xuKS5zcGxpdCgnLCcpO1xuXG53aGlsZSAoaSA8IGwpIHtcbiAgaWYgKFR5cGVkID0gZ2xvYmFsW1R5cGVkQXJyYXlDb25zdHJ1Y3RvcnNbaSsrXV0pIHtcbiAgICBoaWRlKFR5cGVkLnByb3RvdHlwZSwgVFlQRUQsIHRydWUpO1xuICAgIGhpZGUoVHlwZWQucHJvdG90eXBlLCBWSUVXLCB0cnVlKTtcbiAgfSBlbHNlIENPTlNUUiA9IGZhbHNlO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgQUJWOiBBQlYsXG4gIENPTlNUUjogQ09OU1RSLFxuICBUWVBFRDogVFlQRUQsXG4gIFZJRVc6IFZJRVdcbn07XG4iLCJ2YXIgaWQgPSAwO1xudmFyIHB4ID0gTWF0aC5yYW5kb20oKTtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGtleSkge1xuICByZXR1cm4gJ1N5bWJvbCgnLmNvbmNhdChrZXkgPT09IHVuZGVmaW5lZCA/ICcnIDoga2V5LCAnKV8nLCAoKytpZCArIHB4KS50b1N0cmluZygzNikpO1xufTtcbiIsInZhciBnbG9iYWwgPSByZXF1aXJlKCcuL19nbG9iYWwnKTtcbnZhciBuYXZpZ2F0b3IgPSBnbG9iYWwubmF2aWdhdG9yO1xuXG5tb2R1bGUuZXhwb3J0cyA9IG5hdmlnYXRvciAmJiBuYXZpZ2F0b3IudXNlckFnZW50IHx8ICcnO1xuIiwidmFyIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi9faXMtb2JqZWN0Jyk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChpdCwgVFlQRSkge1xuICBpZiAoIWlzT2JqZWN0KGl0KSB8fCBpdC5fdCAhPT0gVFlQRSkgdGhyb3cgVHlwZUVycm9yKCdJbmNvbXBhdGlibGUgcmVjZWl2ZXIsICcgKyBUWVBFICsgJyByZXF1aXJlZCEnKTtcbiAgcmV0dXJuIGl0O1xufTtcbiIsInZhciBnbG9iYWwgPSByZXF1aXJlKCcuL19nbG9iYWwnKTtcbnZhciBjb3JlID0gcmVxdWlyZSgnLi9fY29yZScpO1xudmFyIExJQlJBUlkgPSByZXF1aXJlKCcuL19saWJyYXJ5Jyk7XG52YXIgd2tzRXh0ID0gcmVxdWlyZSgnLi9fd2tzLWV4dCcpO1xudmFyIGRlZmluZVByb3BlcnR5ID0gcmVxdWlyZSgnLi9fb2JqZWN0LWRwJykuZjtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKG5hbWUpIHtcbiAgdmFyICRTeW1ib2wgPSBjb3JlLlN5bWJvbCB8fCAoY29yZS5TeW1ib2wgPSBMSUJSQVJZID8ge30gOiBnbG9iYWwuU3ltYm9sIHx8IHt9KTtcbiAgaWYgKG5hbWUuY2hhckF0KDApICE9ICdfJyAmJiAhKG5hbWUgaW4gJFN5bWJvbCkpIGRlZmluZVByb3BlcnR5KCRTeW1ib2wsIG5hbWUsIHsgdmFsdWU6IHdrc0V4dC5mKG5hbWUpIH0pO1xufTtcbiIsImV4cG9ydHMuZiA9IHJlcXVpcmUoJy4vX3drcycpO1xuIiwidmFyIHN0b3JlID0gcmVxdWlyZSgnLi9fc2hhcmVkJykoJ3drcycpO1xudmFyIHVpZCA9IHJlcXVpcmUoJy4vX3VpZCcpO1xudmFyIFN5bWJvbCA9IHJlcXVpcmUoJy4vX2dsb2JhbCcpLlN5bWJvbDtcbnZhciBVU0VfU1lNQk9MID0gdHlwZW9mIFN5bWJvbCA9PSAnZnVuY3Rpb24nO1xuXG52YXIgJGV4cG9ydHMgPSBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gIHJldHVybiBzdG9yZVtuYW1lXSB8fCAoc3RvcmVbbmFtZV0gPVxuICAgIFVTRV9TWU1CT0wgJiYgU3ltYm9sW25hbWVdIHx8IChVU0VfU1lNQk9MID8gU3ltYm9sIDogdWlkKSgnU3ltYm9sLicgKyBuYW1lKSk7XG59O1xuXG4kZXhwb3J0cy5zdG9yZSA9IHN0b3JlO1xuIiwidmFyIGNsYXNzb2YgPSByZXF1aXJlKCcuL19jbGFzc29mJyk7XG52YXIgSVRFUkFUT1IgPSByZXF1aXJlKCcuL193a3MnKSgnaXRlcmF0b3InKTtcbnZhciBJdGVyYXRvcnMgPSByZXF1aXJlKCcuL19pdGVyYXRvcnMnKTtcbm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi9fY29yZScpLmdldEl0ZXJhdG9yTWV0aG9kID0gZnVuY3Rpb24gKGl0KSB7XG4gIGlmIChpdCAhPSB1bmRlZmluZWQpIHJldHVybiBpdFtJVEVSQVRPUl1cbiAgICB8fCBpdFsnQEBpdGVyYXRvciddXG4gICAgfHwgSXRlcmF0b3JzW2NsYXNzb2YoaXQpXTtcbn07XG4iLCIvLyAyMi4xLjMuMyBBcnJheS5wcm90b3R5cGUuY29weVdpdGhpbih0YXJnZXQsIHN0YXJ0LCBlbmQgPSB0aGlzLmxlbmd0aClcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG5cbiRleHBvcnQoJGV4cG9ydC5QLCAnQXJyYXknLCB7IGNvcHlXaXRoaW46IHJlcXVpcmUoJy4vX2FycmF5LWNvcHktd2l0aGluJykgfSk7XG5cbnJlcXVpcmUoJy4vX2FkZC10by11bnNjb3BhYmxlcycpKCdjb3B5V2l0aGluJyk7XG4iLCIndXNlIHN0cmljdCc7XG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyICRldmVyeSA9IHJlcXVpcmUoJy4vX2FycmF5LW1ldGhvZHMnKSg0KTtcblxuJGV4cG9ydCgkZXhwb3J0LlAgKyAkZXhwb3J0LkYgKiAhcmVxdWlyZSgnLi9fc3RyaWN0LW1ldGhvZCcpKFtdLmV2ZXJ5LCB0cnVlKSwgJ0FycmF5Jywge1xuICAvLyAyMi4xLjMuNSAvIDE1LjQuNC4xNiBBcnJheS5wcm90b3R5cGUuZXZlcnkoY2FsbGJhY2tmbiBbLCB0aGlzQXJnXSlcbiAgZXZlcnk6IGZ1bmN0aW9uIGV2ZXJ5KGNhbGxiYWNrZm4gLyogLCB0aGlzQXJnICovKSB7XG4gICAgcmV0dXJuICRldmVyeSh0aGlzLCBjYWxsYmFja2ZuLCBhcmd1bWVudHNbMV0pO1xuICB9XG59KTtcbiIsIi8vIDIyLjEuMy42IEFycmF5LnByb3RvdHlwZS5maWxsKHZhbHVlLCBzdGFydCA9IDAsIGVuZCA9IHRoaXMubGVuZ3RoKVxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcblxuJGV4cG9ydCgkZXhwb3J0LlAsICdBcnJheScsIHsgZmlsbDogcmVxdWlyZSgnLi9fYXJyYXktZmlsbCcpIH0pO1xuXG5yZXF1aXJlKCcuL19hZGQtdG8tdW5zY29wYWJsZXMnKSgnZmlsbCcpO1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciAkZmlsdGVyID0gcmVxdWlyZSgnLi9fYXJyYXktbWV0aG9kcycpKDIpO1xuXG4kZXhwb3J0KCRleHBvcnQuUCArICRleHBvcnQuRiAqICFyZXF1aXJlKCcuL19zdHJpY3QtbWV0aG9kJykoW10uZmlsdGVyLCB0cnVlKSwgJ0FycmF5Jywge1xuICAvLyAyMi4xLjMuNyAvIDE1LjQuNC4yMCBBcnJheS5wcm90b3R5cGUuZmlsdGVyKGNhbGxiYWNrZm4gWywgdGhpc0FyZ10pXG4gIGZpbHRlcjogZnVuY3Rpb24gZmlsdGVyKGNhbGxiYWNrZm4gLyogLCB0aGlzQXJnICovKSB7XG4gICAgcmV0dXJuICRmaWx0ZXIodGhpcywgY2FsbGJhY2tmbiwgYXJndW1lbnRzWzFdKTtcbiAgfVxufSk7XG4iLCIndXNlIHN0cmljdCc7XG4vLyAyMi4xLjMuOSBBcnJheS5wcm90b3R5cGUuZmluZEluZGV4KHByZWRpY2F0ZSwgdGhpc0FyZyA9IHVuZGVmaW5lZClcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgJGZpbmQgPSByZXF1aXJlKCcuL19hcnJheS1tZXRob2RzJykoNik7XG52YXIgS0VZID0gJ2ZpbmRJbmRleCc7XG52YXIgZm9yY2VkID0gdHJ1ZTtcbi8vIFNob3VsZG4ndCBza2lwIGhvbGVzXG5pZiAoS0VZIGluIFtdKSBBcnJheSgxKVtLRVldKGZ1bmN0aW9uICgpIHsgZm9yY2VkID0gZmFsc2U7IH0pO1xuJGV4cG9ydCgkZXhwb3J0LlAgKyAkZXhwb3J0LkYgKiBmb3JjZWQsICdBcnJheScsIHtcbiAgZmluZEluZGV4OiBmdW5jdGlvbiBmaW5kSW5kZXgoY2FsbGJhY2tmbiAvKiAsIHRoYXQgPSB1bmRlZmluZWQgKi8pIHtcbiAgICByZXR1cm4gJGZpbmQodGhpcywgY2FsbGJhY2tmbiwgYXJndW1lbnRzLmxlbmd0aCA+IDEgPyBhcmd1bWVudHNbMV0gOiB1bmRlZmluZWQpO1xuICB9XG59KTtcbnJlcXVpcmUoJy4vX2FkZC10by11bnNjb3BhYmxlcycpKEtFWSk7XG4iLCIndXNlIHN0cmljdCc7XG4vLyAyMi4xLjMuOCBBcnJheS5wcm90b3R5cGUuZmluZChwcmVkaWNhdGUsIHRoaXNBcmcgPSB1bmRlZmluZWQpXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyICRmaW5kID0gcmVxdWlyZSgnLi9fYXJyYXktbWV0aG9kcycpKDUpO1xudmFyIEtFWSA9ICdmaW5kJztcbnZhciBmb3JjZWQgPSB0cnVlO1xuLy8gU2hvdWxkbid0IHNraXAgaG9sZXNcbmlmIChLRVkgaW4gW10pIEFycmF5KDEpW0tFWV0oZnVuY3Rpb24gKCkgeyBmb3JjZWQgPSBmYWxzZTsgfSk7XG4kZXhwb3J0KCRleHBvcnQuUCArICRleHBvcnQuRiAqIGZvcmNlZCwgJ0FycmF5Jywge1xuICBmaW5kOiBmdW5jdGlvbiBmaW5kKGNhbGxiYWNrZm4gLyogLCB0aGF0ID0gdW5kZWZpbmVkICovKSB7XG4gICAgcmV0dXJuICRmaW5kKHRoaXMsIGNhbGxiYWNrZm4sIGFyZ3VtZW50cy5sZW5ndGggPiAxID8gYXJndW1lbnRzWzFdIDogdW5kZWZpbmVkKTtcbiAgfVxufSk7XG5yZXF1aXJlKCcuL19hZGQtdG8tdW5zY29wYWJsZXMnKShLRVkpO1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciAkZm9yRWFjaCA9IHJlcXVpcmUoJy4vX2FycmF5LW1ldGhvZHMnKSgwKTtcbnZhciBTVFJJQ1QgPSByZXF1aXJlKCcuL19zdHJpY3QtbWV0aG9kJykoW10uZm9yRWFjaCwgdHJ1ZSk7XG5cbiRleHBvcnQoJGV4cG9ydC5QICsgJGV4cG9ydC5GICogIVNUUklDVCwgJ0FycmF5Jywge1xuICAvLyAyMi4xLjMuMTAgLyAxNS40LjQuMTggQXJyYXkucHJvdG90eXBlLmZvckVhY2goY2FsbGJhY2tmbiBbLCB0aGlzQXJnXSlcbiAgZm9yRWFjaDogZnVuY3Rpb24gZm9yRWFjaChjYWxsYmFja2ZuIC8qICwgdGhpc0FyZyAqLykge1xuICAgIHJldHVybiAkZm9yRWFjaCh0aGlzLCBjYWxsYmFja2ZuLCBhcmd1bWVudHNbMV0pO1xuICB9XG59KTtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciBjdHggPSByZXF1aXJlKCcuL19jdHgnKTtcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgdG9PYmplY3QgPSByZXF1aXJlKCcuL190by1vYmplY3QnKTtcbnZhciBjYWxsID0gcmVxdWlyZSgnLi9faXRlci1jYWxsJyk7XG52YXIgaXNBcnJheUl0ZXIgPSByZXF1aXJlKCcuL19pcy1hcnJheS1pdGVyJyk7XG52YXIgdG9MZW5ndGggPSByZXF1aXJlKCcuL190by1sZW5ndGgnKTtcbnZhciBjcmVhdGVQcm9wZXJ0eSA9IHJlcXVpcmUoJy4vX2NyZWF0ZS1wcm9wZXJ0eScpO1xudmFyIGdldEl0ZXJGbiA9IHJlcXVpcmUoJy4vY29yZS5nZXQtaXRlcmF0b3ItbWV0aG9kJyk7XG5cbiRleHBvcnQoJGV4cG9ydC5TICsgJGV4cG9ydC5GICogIXJlcXVpcmUoJy4vX2l0ZXItZGV0ZWN0JykoZnVuY3Rpb24gKGl0ZXIpIHsgQXJyYXkuZnJvbShpdGVyKTsgfSksICdBcnJheScsIHtcbiAgLy8gMjIuMS4yLjEgQXJyYXkuZnJvbShhcnJheUxpa2UsIG1hcGZuID0gdW5kZWZpbmVkLCB0aGlzQXJnID0gdW5kZWZpbmVkKVxuICBmcm9tOiBmdW5jdGlvbiBmcm9tKGFycmF5TGlrZSAvKiAsIG1hcGZuID0gdW5kZWZpbmVkLCB0aGlzQXJnID0gdW5kZWZpbmVkICovKSB7XG4gICAgdmFyIE8gPSB0b09iamVjdChhcnJheUxpa2UpO1xuICAgIHZhciBDID0gdHlwZW9mIHRoaXMgPT0gJ2Z1bmN0aW9uJyA/IHRoaXMgOiBBcnJheTtcbiAgICB2YXIgYUxlbiA9IGFyZ3VtZW50cy5sZW5ndGg7XG4gICAgdmFyIG1hcGZuID0gYUxlbiA+IDEgPyBhcmd1bWVudHNbMV0gOiB1bmRlZmluZWQ7XG4gICAgdmFyIG1hcHBpbmcgPSBtYXBmbiAhPT0gdW5kZWZpbmVkO1xuICAgIHZhciBpbmRleCA9IDA7XG4gICAgdmFyIGl0ZXJGbiA9IGdldEl0ZXJGbihPKTtcbiAgICB2YXIgbGVuZ3RoLCByZXN1bHQsIHN0ZXAsIGl0ZXJhdG9yO1xuICAgIGlmIChtYXBwaW5nKSBtYXBmbiA9IGN0eChtYXBmbiwgYUxlbiA+IDIgPyBhcmd1bWVudHNbMl0gOiB1bmRlZmluZWQsIDIpO1xuICAgIC8vIGlmIG9iamVjdCBpc24ndCBpdGVyYWJsZSBvciBpdCdzIGFycmF5IHdpdGggZGVmYXVsdCBpdGVyYXRvciAtIHVzZSBzaW1wbGUgY2FzZVxuICAgIGlmIChpdGVyRm4gIT0gdW5kZWZpbmVkICYmICEoQyA9PSBBcnJheSAmJiBpc0FycmF5SXRlcihpdGVyRm4pKSkge1xuICAgICAgZm9yIChpdGVyYXRvciA9IGl0ZXJGbi5jYWxsKE8pLCByZXN1bHQgPSBuZXcgQygpOyAhKHN0ZXAgPSBpdGVyYXRvci5uZXh0KCkpLmRvbmU7IGluZGV4KyspIHtcbiAgICAgICAgY3JlYXRlUHJvcGVydHkocmVzdWx0LCBpbmRleCwgbWFwcGluZyA/IGNhbGwoaXRlcmF0b3IsIG1hcGZuLCBbc3RlcC52YWx1ZSwgaW5kZXhdLCB0cnVlKSA6IHN0ZXAudmFsdWUpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBsZW5ndGggPSB0b0xlbmd0aChPLmxlbmd0aCk7XG4gICAgICBmb3IgKHJlc3VsdCA9IG5ldyBDKGxlbmd0aCk7IGxlbmd0aCA+IGluZGV4OyBpbmRleCsrKSB7XG4gICAgICAgIGNyZWF0ZVByb3BlcnR5KHJlc3VsdCwgaW5kZXgsIG1hcHBpbmcgPyBtYXBmbihPW2luZGV4XSwgaW5kZXgpIDogT1tpbmRleF0pO1xuICAgICAgfVxuICAgIH1cbiAgICByZXN1bHQubGVuZ3RoID0gaW5kZXg7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxufSk7XG4iLCIndXNlIHN0cmljdCc7XG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyICRpbmRleE9mID0gcmVxdWlyZSgnLi9fYXJyYXktaW5jbHVkZXMnKShmYWxzZSk7XG52YXIgJG5hdGl2ZSA9IFtdLmluZGV4T2Y7XG52YXIgTkVHQVRJVkVfWkVSTyA9ICEhJG5hdGl2ZSAmJiAxIC8gWzFdLmluZGV4T2YoMSwgLTApIDwgMDtcblxuJGV4cG9ydCgkZXhwb3J0LlAgKyAkZXhwb3J0LkYgKiAoTkVHQVRJVkVfWkVSTyB8fCAhcmVxdWlyZSgnLi9fc3RyaWN0LW1ldGhvZCcpKCRuYXRpdmUpKSwgJ0FycmF5Jywge1xuICAvLyAyMi4xLjMuMTEgLyAxNS40LjQuMTQgQXJyYXkucHJvdG90eXBlLmluZGV4T2Yoc2VhcmNoRWxlbWVudCBbLCBmcm9tSW5kZXhdKVxuICBpbmRleE9mOiBmdW5jdGlvbiBpbmRleE9mKHNlYXJjaEVsZW1lbnQgLyogLCBmcm9tSW5kZXggPSAwICovKSB7XG4gICAgcmV0dXJuIE5FR0FUSVZFX1pFUk9cbiAgICAgIC8vIGNvbnZlcnQgLTAgdG8gKzBcbiAgICAgID8gJG5hdGl2ZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IDBcbiAgICAgIDogJGluZGV4T2YodGhpcywgc2VhcmNoRWxlbWVudCwgYXJndW1lbnRzWzFdKTtcbiAgfVxufSk7XG4iLCIvLyAyMi4xLjIuMiAvIDE1LjQuMy4yIEFycmF5LmlzQXJyYXkoYXJnKVxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcblxuJGV4cG9ydCgkZXhwb3J0LlMsICdBcnJheScsIHsgaXNBcnJheTogcmVxdWlyZSgnLi9faXMtYXJyYXknKSB9KTtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciBhZGRUb1Vuc2NvcGFibGVzID0gcmVxdWlyZSgnLi9fYWRkLXRvLXVuc2NvcGFibGVzJyk7XG52YXIgc3RlcCA9IHJlcXVpcmUoJy4vX2l0ZXItc3RlcCcpO1xudmFyIEl0ZXJhdG9ycyA9IHJlcXVpcmUoJy4vX2l0ZXJhdG9ycycpO1xudmFyIHRvSU9iamVjdCA9IHJlcXVpcmUoJy4vX3RvLWlvYmplY3QnKTtcblxuLy8gMjIuMS4zLjQgQXJyYXkucHJvdG90eXBlLmVudHJpZXMoKVxuLy8gMjIuMS4zLjEzIEFycmF5LnByb3RvdHlwZS5rZXlzKClcbi8vIDIyLjEuMy4yOSBBcnJheS5wcm90b3R5cGUudmFsdWVzKClcbi8vIDIyLjEuMy4zMCBBcnJheS5wcm90b3R5cGVbQEBpdGVyYXRvcl0oKVxubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL19pdGVyLWRlZmluZScpKEFycmF5LCAnQXJyYXknLCBmdW5jdGlvbiAoaXRlcmF0ZWQsIGtpbmQpIHtcbiAgdGhpcy5fdCA9IHRvSU9iamVjdChpdGVyYXRlZCk7IC8vIHRhcmdldFxuICB0aGlzLl9pID0gMDsgICAgICAgICAgICAgICAgICAgLy8gbmV4dCBpbmRleFxuICB0aGlzLl9rID0ga2luZDsgICAgICAgICAgICAgICAgLy8ga2luZFxuLy8gMjIuMS41LjIuMSAlQXJyYXlJdGVyYXRvclByb3RvdHlwZSUubmV4dCgpXG59LCBmdW5jdGlvbiAoKSB7XG4gIHZhciBPID0gdGhpcy5fdDtcbiAgdmFyIGtpbmQgPSB0aGlzLl9rO1xuICB2YXIgaW5kZXggPSB0aGlzLl9pKys7XG4gIGlmICghTyB8fCBpbmRleCA+PSBPLmxlbmd0aCkge1xuICAgIHRoaXMuX3QgPSB1bmRlZmluZWQ7XG4gICAgcmV0dXJuIHN0ZXAoMSk7XG4gIH1cbiAgaWYgKGtpbmQgPT0gJ2tleXMnKSByZXR1cm4gc3RlcCgwLCBpbmRleCk7XG4gIGlmIChraW5kID09ICd2YWx1ZXMnKSByZXR1cm4gc3RlcCgwLCBPW2luZGV4XSk7XG4gIHJldHVybiBzdGVwKDAsIFtpbmRleCwgT1tpbmRleF1dKTtcbn0sICd2YWx1ZXMnKTtcblxuLy8gYXJndW1lbnRzTGlzdFtAQGl0ZXJhdG9yXSBpcyAlQXJyYXlQcm90b192YWx1ZXMlICg5LjQuNC42LCA5LjQuNC43KVxuSXRlcmF0b3JzLkFyZ3VtZW50cyA9IEl0ZXJhdG9ycy5BcnJheTtcblxuYWRkVG9VbnNjb3BhYmxlcygna2V5cycpO1xuYWRkVG9VbnNjb3BhYmxlcygndmFsdWVzJyk7XG5hZGRUb1Vuc2NvcGFibGVzKCdlbnRyaWVzJyk7XG4iLCIndXNlIHN0cmljdCc7XG4vLyAyMi4xLjMuMTMgQXJyYXkucHJvdG90eXBlLmpvaW4oc2VwYXJhdG9yKVxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciB0b0lPYmplY3QgPSByZXF1aXJlKCcuL190by1pb2JqZWN0Jyk7XG52YXIgYXJyYXlKb2luID0gW10uam9pbjtcblxuLy8gZmFsbGJhY2sgZm9yIG5vdCBhcnJheS1saWtlIHN0cmluZ3NcbiRleHBvcnQoJGV4cG9ydC5QICsgJGV4cG9ydC5GICogKHJlcXVpcmUoJy4vX2lvYmplY3QnKSAhPSBPYmplY3QgfHwgIXJlcXVpcmUoJy4vX3N0cmljdC1tZXRob2QnKShhcnJheUpvaW4pKSwgJ0FycmF5Jywge1xuICBqb2luOiBmdW5jdGlvbiBqb2luKHNlcGFyYXRvcikge1xuICAgIHJldHVybiBhcnJheUpvaW4uY2FsbCh0b0lPYmplY3QodGhpcyksIHNlcGFyYXRvciA9PT0gdW5kZWZpbmVkID8gJywnIDogc2VwYXJhdG9yKTtcbiAgfVxufSk7XG4iLCIndXNlIHN0cmljdCc7XG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyIHRvSU9iamVjdCA9IHJlcXVpcmUoJy4vX3RvLWlvYmplY3QnKTtcbnZhciB0b0ludGVnZXIgPSByZXF1aXJlKCcuL190by1pbnRlZ2VyJyk7XG52YXIgdG9MZW5ndGggPSByZXF1aXJlKCcuL190by1sZW5ndGgnKTtcbnZhciAkbmF0aXZlID0gW10ubGFzdEluZGV4T2Y7XG52YXIgTkVHQVRJVkVfWkVSTyA9ICEhJG5hdGl2ZSAmJiAxIC8gWzFdLmxhc3RJbmRleE9mKDEsIC0wKSA8IDA7XG5cbiRleHBvcnQoJGV4cG9ydC5QICsgJGV4cG9ydC5GICogKE5FR0FUSVZFX1pFUk8gfHwgIXJlcXVpcmUoJy4vX3N0cmljdC1tZXRob2QnKSgkbmF0aXZlKSksICdBcnJheScsIHtcbiAgLy8gMjIuMS4zLjE0IC8gMTUuNC40LjE1IEFycmF5LnByb3RvdHlwZS5sYXN0SW5kZXhPZihzZWFyY2hFbGVtZW50IFssIGZyb21JbmRleF0pXG4gIGxhc3RJbmRleE9mOiBmdW5jdGlvbiBsYXN0SW5kZXhPZihzZWFyY2hFbGVtZW50IC8qICwgZnJvbUluZGV4ID0gQFsqLTFdICovKSB7XG4gICAgLy8gY29udmVydCAtMCB0byArMFxuICAgIGlmIChORUdBVElWRV9aRVJPKSByZXR1cm4gJG5hdGl2ZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IDA7XG4gICAgdmFyIE8gPSB0b0lPYmplY3QodGhpcyk7XG4gICAgdmFyIGxlbmd0aCA9IHRvTGVuZ3RoKE8ubGVuZ3RoKTtcbiAgICB2YXIgaW5kZXggPSBsZW5ndGggLSAxO1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMSkgaW5kZXggPSBNYXRoLm1pbihpbmRleCwgdG9JbnRlZ2VyKGFyZ3VtZW50c1sxXSkpO1xuICAgIGlmIChpbmRleCA8IDApIGluZGV4ID0gbGVuZ3RoICsgaW5kZXg7XG4gICAgZm9yICg7aW5kZXggPj0gMDsgaW5kZXgtLSkgaWYgKGluZGV4IGluIE8pIGlmIChPW2luZGV4XSA9PT0gc2VhcmNoRWxlbWVudCkgcmV0dXJuIGluZGV4IHx8IDA7XG4gICAgcmV0dXJuIC0xO1xuICB9XG59KTtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgJG1hcCA9IHJlcXVpcmUoJy4vX2FycmF5LW1ldGhvZHMnKSgxKTtcblxuJGV4cG9ydCgkZXhwb3J0LlAgKyAkZXhwb3J0LkYgKiAhcmVxdWlyZSgnLi9fc3RyaWN0LW1ldGhvZCcpKFtdLm1hcCwgdHJ1ZSksICdBcnJheScsIHtcbiAgLy8gMjIuMS4zLjE1IC8gMTUuNC40LjE5IEFycmF5LnByb3RvdHlwZS5tYXAoY2FsbGJhY2tmbiBbLCB0aGlzQXJnXSlcbiAgbWFwOiBmdW5jdGlvbiBtYXAoY2FsbGJhY2tmbiAvKiAsIHRoaXNBcmcgKi8pIHtcbiAgICByZXR1cm4gJG1hcCh0aGlzLCBjYWxsYmFja2ZuLCBhcmd1bWVudHNbMV0pO1xuICB9XG59KTtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgY3JlYXRlUHJvcGVydHkgPSByZXF1aXJlKCcuL19jcmVhdGUtcHJvcGVydHknKTtcblxuLy8gV2ViS2l0IEFycmF5Lm9mIGlzbid0IGdlbmVyaWNcbiRleHBvcnQoJGV4cG9ydC5TICsgJGV4cG9ydC5GICogcmVxdWlyZSgnLi9fZmFpbHMnKShmdW5jdGlvbiAoKSB7XG4gIGZ1bmN0aW9uIEYoKSB7IC8qIGVtcHR5ICovIH1cbiAgcmV0dXJuICEoQXJyYXkub2YuY2FsbChGKSBpbnN0YW5jZW9mIEYpO1xufSksICdBcnJheScsIHtcbiAgLy8gMjIuMS4yLjMgQXJyYXkub2YoIC4uLml0ZW1zKVxuICBvZjogZnVuY3Rpb24gb2YoLyogLi4uYXJncyAqLykge1xuICAgIHZhciBpbmRleCA9IDA7XG4gICAgdmFyIGFMZW4gPSBhcmd1bWVudHMubGVuZ3RoO1xuICAgIHZhciByZXN1bHQgPSBuZXcgKHR5cGVvZiB0aGlzID09ICdmdW5jdGlvbicgPyB0aGlzIDogQXJyYXkpKGFMZW4pO1xuICAgIHdoaWxlIChhTGVuID4gaW5kZXgpIGNyZWF0ZVByb3BlcnR5KHJlc3VsdCwgaW5kZXgsIGFyZ3VtZW50c1tpbmRleCsrXSk7XG4gICAgcmVzdWx0Lmxlbmd0aCA9IGFMZW47XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxufSk7XG4iLCIndXNlIHN0cmljdCc7XG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyICRyZWR1Y2UgPSByZXF1aXJlKCcuL19hcnJheS1yZWR1Y2UnKTtcblxuJGV4cG9ydCgkZXhwb3J0LlAgKyAkZXhwb3J0LkYgKiAhcmVxdWlyZSgnLi9fc3RyaWN0LW1ldGhvZCcpKFtdLnJlZHVjZVJpZ2h0LCB0cnVlKSwgJ0FycmF5Jywge1xuICAvLyAyMi4xLjMuMTkgLyAxNS40LjQuMjIgQXJyYXkucHJvdG90eXBlLnJlZHVjZVJpZ2h0KGNhbGxiYWNrZm4gWywgaW5pdGlhbFZhbHVlXSlcbiAgcmVkdWNlUmlnaHQ6IGZ1bmN0aW9uIHJlZHVjZVJpZ2h0KGNhbGxiYWNrZm4gLyogLCBpbml0aWFsVmFsdWUgKi8pIHtcbiAgICByZXR1cm4gJHJlZHVjZSh0aGlzLCBjYWxsYmFja2ZuLCBhcmd1bWVudHMubGVuZ3RoLCBhcmd1bWVudHNbMV0sIHRydWUpO1xuICB9XG59KTtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgJHJlZHVjZSA9IHJlcXVpcmUoJy4vX2FycmF5LXJlZHVjZScpO1xuXG4kZXhwb3J0KCRleHBvcnQuUCArICRleHBvcnQuRiAqICFyZXF1aXJlKCcuL19zdHJpY3QtbWV0aG9kJykoW10ucmVkdWNlLCB0cnVlKSwgJ0FycmF5Jywge1xuICAvLyAyMi4xLjMuMTggLyAxNS40LjQuMjEgQXJyYXkucHJvdG90eXBlLnJlZHVjZShjYWxsYmFja2ZuIFssIGluaXRpYWxWYWx1ZV0pXG4gIHJlZHVjZTogZnVuY3Rpb24gcmVkdWNlKGNhbGxiYWNrZm4gLyogLCBpbml0aWFsVmFsdWUgKi8pIHtcbiAgICByZXR1cm4gJHJlZHVjZSh0aGlzLCBjYWxsYmFja2ZuLCBhcmd1bWVudHMubGVuZ3RoLCBhcmd1bWVudHNbMV0sIGZhbHNlKTtcbiAgfVxufSk7XG4iLCIndXNlIHN0cmljdCc7XG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyIGh0bWwgPSByZXF1aXJlKCcuL19odG1sJyk7XG52YXIgY29mID0gcmVxdWlyZSgnLi9fY29mJyk7XG52YXIgdG9BYnNvbHV0ZUluZGV4ID0gcmVxdWlyZSgnLi9fdG8tYWJzb2x1dGUtaW5kZXgnKTtcbnZhciB0b0xlbmd0aCA9IHJlcXVpcmUoJy4vX3RvLWxlbmd0aCcpO1xudmFyIGFycmF5U2xpY2UgPSBbXS5zbGljZTtcblxuLy8gZmFsbGJhY2sgZm9yIG5vdCBhcnJheS1saWtlIEVTMyBzdHJpbmdzIGFuZCBET00gb2JqZWN0c1xuJGV4cG9ydCgkZXhwb3J0LlAgKyAkZXhwb3J0LkYgKiByZXF1aXJlKCcuL19mYWlscycpKGZ1bmN0aW9uICgpIHtcbiAgaWYgKGh0bWwpIGFycmF5U2xpY2UuY2FsbChodG1sKTtcbn0pLCAnQXJyYXknLCB7XG4gIHNsaWNlOiBmdW5jdGlvbiBzbGljZShiZWdpbiwgZW5kKSB7XG4gICAgdmFyIGxlbiA9IHRvTGVuZ3RoKHRoaXMubGVuZ3RoKTtcbiAgICB2YXIga2xhc3MgPSBjb2YodGhpcyk7XG4gICAgZW5kID0gZW5kID09PSB1bmRlZmluZWQgPyBsZW4gOiBlbmQ7XG4gICAgaWYgKGtsYXNzID09ICdBcnJheScpIHJldHVybiBhcnJheVNsaWNlLmNhbGwodGhpcywgYmVnaW4sIGVuZCk7XG4gICAgdmFyIHN0YXJ0ID0gdG9BYnNvbHV0ZUluZGV4KGJlZ2luLCBsZW4pO1xuICAgIHZhciB1cFRvID0gdG9BYnNvbHV0ZUluZGV4KGVuZCwgbGVuKTtcbiAgICB2YXIgc2l6ZSA9IHRvTGVuZ3RoKHVwVG8gLSBzdGFydCk7XG4gICAgdmFyIGNsb25lZCA9IG5ldyBBcnJheShzaXplKTtcbiAgICB2YXIgaSA9IDA7XG4gICAgZm9yICg7IGkgPCBzaXplOyBpKyspIGNsb25lZFtpXSA9IGtsYXNzID09ICdTdHJpbmcnXG4gICAgICA/IHRoaXMuY2hhckF0KHN0YXJ0ICsgaSlcbiAgICAgIDogdGhpc1tzdGFydCArIGldO1xuICAgIHJldHVybiBjbG9uZWQ7XG4gIH1cbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciAkc29tZSA9IHJlcXVpcmUoJy4vX2FycmF5LW1ldGhvZHMnKSgzKTtcblxuJGV4cG9ydCgkZXhwb3J0LlAgKyAkZXhwb3J0LkYgKiAhcmVxdWlyZSgnLi9fc3RyaWN0LW1ldGhvZCcpKFtdLnNvbWUsIHRydWUpLCAnQXJyYXknLCB7XG4gIC8vIDIyLjEuMy4yMyAvIDE1LjQuNC4xNyBBcnJheS5wcm90b3R5cGUuc29tZShjYWxsYmFja2ZuIFssIHRoaXNBcmddKVxuICBzb21lOiBmdW5jdGlvbiBzb21lKGNhbGxiYWNrZm4gLyogLCB0aGlzQXJnICovKSB7XG4gICAgcmV0dXJuICRzb21lKHRoaXMsIGNhbGxiYWNrZm4sIGFyZ3VtZW50c1sxXSk7XG4gIH1cbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciBhRnVuY3Rpb24gPSByZXF1aXJlKCcuL19hLWZ1bmN0aW9uJyk7XG52YXIgdG9PYmplY3QgPSByZXF1aXJlKCcuL190by1vYmplY3QnKTtcbnZhciBmYWlscyA9IHJlcXVpcmUoJy4vX2ZhaWxzJyk7XG52YXIgJHNvcnQgPSBbXS5zb3J0O1xudmFyIHRlc3QgPSBbMSwgMiwgM107XG5cbiRleHBvcnQoJGV4cG9ydC5QICsgJGV4cG9ydC5GICogKGZhaWxzKGZ1bmN0aW9uICgpIHtcbiAgLy8gSUU4LVxuICB0ZXN0LnNvcnQodW5kZWZpbmVkKTtcbn0pIHx8ICFmYWlscyhmdW5jdGlvbiAoKSB7XG4gIC8vIFY4IGJ1Z1xuICB0ZXN0LnNvcnQobnVsbCk7XG4gIC8vIE9sZCBXZWJLaXRcbn0pIHx8ICFyZXF1aXJlKCcuL19zdHJpY3QtbWV0aG9kJykoJHNvcnQpKSwgJ0FycmF5Jywge1xuICAvLyAyMi4xLjMuMjUgQXJyYXkucHJvdG90eXBlLnNvcnQoY29tcGFyZWZuKVxuICBzb3J0OiBmdW5jdGlvbiBzb3J0KGNvbXBhcmVmbikge1xuICAgIHJldHVybiBjb21wYXJlZm4gPT09IHVuZGVmaW5lZFxuICAgICAgPyAkc29ydC5jYWxsKHRvT2JqZWN0KHRoaXMpKVxuICAgICAgOiAkc29ydC5jYWxsKHRvT2JqZWN0KHRoaXMpLCBhRnVuY3Rpb24oY29tcGFyZWZuKSk7XG4gIH1cbn0pO1xuIiwicmVxdWlyZSgnLi9fc2V0LXNwZWNpZXMnKSgnQXJyYXknKTtcbiIsIi8vIDIwLjMuMy4xIC8gMTUuOS40LjQgRGF0ZS5ub3coKVxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcblxuJGV4cG9ydCgkZXhwb3J0LlMsICdEYXRlJywgeyBub3c6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIG5ldyBEYXRlKCkuZ2V0VGltZSgpOyB9IH0pO1xuIiwiLy8gMjAuMy40LjM2IC8gMTUuOS41LjQzIERhdGUucHJvdG90eXBlLnRvSVNPU3RyaW5nKClcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgdG9JU09TdHJpbmcgPSByZXF1aXJlKCcuL19kYXRlLXRvLWlzby1zdHJpbmcnKTtcblxuLy8gUGhhbnRvbUpTIC8gb2xkIFdlYktpdCBoYXMgYSBicm9rZW4gaW1wbGVtZW50YXRpb25zXG4kZXhwb3J0KCRleHBvcnQuUCArICRleHBvcnQuRiAqIChEYXRlLnByb3RvdHlwZS50b0lTT1N0cmluZyAhPT0gdG9JU09TdHJpbmcpLCAnRGF0ZScsIHtcbiAgdG9JU09TdHJpbmc6IHRvSVNPU3RyaW5nXG59KTtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgdG9PYmplY3QgPSByZXF1aXJlKCcuL190by1vYmplY3QnKTtcbnZhciB0b1ByaW1pdGl2ZSA9IHJlcXVpcmUoJy4vX3RvLXByaW1pdGl2ZScpO1xuXG4kZXhwb3J0KCRleHBvcnQuUCArICRleHBvcnQuRiAqIHJlcXVpcmUoJy4vX2ZhaWxzJykoZnVuY3Rpb24gKCkge1xuICByZXR1cm4gbmV3IERhdGUoTmFOKS50b0pTT04oKSAhPT0gbnVsbFxuICAgIHx8IERhdGUucHJvdG90eXBlLnRvSlNPTi5jYWxsKHsgdG9JU09TdHJpbmc6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIDE7IH0gfSkgIT09IDE7XG59KSwgJ0RhdGUnLCB7XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby11bnVzZWQtdmFyc1xuICB0b0pTT046IGZ1bmN0aW9uIHRvSlNPTihrZXkpIHtcbiAgICB2YXIgTyA9IHRvT2JqZWN0KHRoaXMpO1xuICAgIHZhciBwdiA9IHRvUHJpbWl0aXZlKE8pO1xuICAgIHJldHVybiB0eXBlb2YgcHYgPT0gJ251bWJlcicgJiYgIWlzRmluaXRlKHB2KSA/IG51bGwgOiBPLnRvSVNPU3RyaW5nKCk7XG4gIH1cbn0pO1xuIiwidmFyIFRPX1BSSU1JVElWRSA9IHJlcXVpcmUoJy4vX3drcycpKCd0b1ByaW1pdGl2ZScpO1xudmFyIHByb3RvID0gRGF0ZS5wcm90b3R5cGU7XG5cbmlmICghKFRPX1BSSU1JVElWRSBpbiBwcm90bykpIHJlcXVpcmUoJy4vX2hpZGUnKShwcm90bywgVE9fUFJJTUlUSVZFLCByZXF1aXJlKCcuL19kYXRlLXRvLXByaW1pdGl2ZScpKTtcbiIsInZhciBEYXRlUHJvdG8gPSBEYXRlLnByb3RvdHlwZTtcbnZhciBJTlZBTElEX0RBVEUgPSAnSW52YWxpZCBEYXRlJztcbnZhciBUT19TVFJJTkcgPSAndG9TdHJpbmcnO1xudmFyICR0b1N0cmluZyA9IERhdGVQcm90b1tUT19TVFJJTkddO1xudmFyIGdldFRpbWUgPSBEYXRlUHJvdG8uZ2V0VGltZTtcbmlmIChuZXcgRGF0ZShOYU4pICsgJycgIT0gSU5WQUxJRF9EQVRFKSB7XG4gIHJlcXVpcmUoJy4vX3JlZGVmaW5lJykoRGF0ZVByb3RvLCBUT19TVFJJTkcsIGZ1bmN0aW9uIHRvU3RyaW5nKCkge1xuICAgIHZhciB2YWx1ZSA9IGdldFRpbWUuY2FsbCh0aGlzKTtcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tc2VsZi1jb21wYXJlXG4gICAgcmV0dXJuIHZhbHVlID09PSB2YWx1ZSA/ICR0b1N0cmluZy5jYWxsKHRoaXMpIDogSU5WQUxJRF9EQVRFO1xuICB9KTtcbn1cbiIsIi8vIDE5LjIuMy4yIC8gMTUuMy40LjUgRnVuY3Rpb24ucHJvdG90eXBlLmJpbmQodGhpc0FyZywgYXJncy4uLilcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG5cbiRleHBvcnQoJGV4cG9ydC5QLCAnRnVuY3Rpb24nLCB7IGJpbmQ6IHJlcXVpcmUoJy4vX2JpbmQnKSB9KTtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciBpc09iamVjdCA9IHJlcXVpcmUoJy4vX2lzLW9iamVjdCcpO1xudmFyIGdldFByb3RvdHlwZU9mID0gcmVxdWlyZSgnLi9fb2JqZWN0LWdwbycpO1xudmFyIEhBU19JTlNUQU5DRSA9IHJlcXVpcmUoJy4vX3drcycpKCdoYXNJbnN0YW5jZScpO1xudmFyIEZ1bmN0aW9uUHJvdG8gPSBGdW5jdGlvbi5wcm90b3R5cGU7XG4vLyAxOS4yLjMuNiBGdW5jdGlvbi5wcm90b3R5cGVbQEBoYXNJbnN0YW5jZV0oVilcbmlmICghKEhBU19JTlNUQU5DRSBpbiBGdW5jdGlvblByb3RvKSkgcmVxdWlyZSgnLi9fb2JqZWN0LWRwJykuZihGdW5jdGlvblByb3RvLCBIQVNfSU5TVEFOQ0UsIHsgdmFsdWU6IGZ1bmN0aW9uIChPKSB7XG4gIGlmICh0eXBlb2YgdGhpcyAhPSAnZnVuY3Rpb24nIHx8ICFpc09iamVjdChPKSkgcmV0dXJuIGZhbHNlO1xuICBpZiAoIWlzT2JqZWN0KHRoaXMucHJvdG90eXBlKSkgcmV0dXJuIE8gaW5zdGFuY2VvZiB0aGlzO1xuICAvLyBmb3IgZW52aXJvbm1lbnQgdy9vIG5hdGl2ZSBgQEBoYXNJbnN0YW5jZWAgbG9naWMgZW5vdWdoIGBpbnN0YW5jZW9mYCwgYnV0IGFkZCB0aGlzOlxuICB3aGlsZSAoTyA9IGdldFByb3RvdHlwZU9mKE8pKSBpZiAodGhpcy5wcm90b3R5cGUgPT09IE8pIHJldHVybiB0cnVlO1xuICByZXR1cm4gZmFsc2U7XG59IH0pO1xuIiwidmFyIGRQID0gcmVxdWlyZSgnLi9fb2JqZWN0LWRwJykuZjtcbnZhciBGUHJvdG8gPSBGdW5jdGlvbi5wcm90b3R5cGU7XG52YXIgbmFtZVJFID0gL15cXHMqZnVuY3Rpb24gKFteIChdKikvO1xudmFyIE5BTUUgPSAnbmFtZSc7XG5cbi8vIDE5LjIuNC4yIG5hbWVcbk5BTUUgaW4gRlByb3RvIHx8IHJlcXVpcmUoJy4vX2Rlc2NyaXB0b3JzJykgJiYgZFAoRlByb3RvLCBOQU1FLCB7XG4gIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiAoJycgKyB0aGlzKS5tYXRjaChuYW1lUkUpWzFdO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHJldHVybiAnJztcbiAgICB9XG4gIH1cbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyIHN0cm9uZyA9IHJlcXVpcmUoJy4vX2NvbGxlY3Rpb24tc3Ryb25nJyk7XG52YXIgdmFsaWRhdGUgPSByZXF1aXJlKCcuL192YWxpZGF0ZS1jb2xsZWN0aW9uJyk7XG52YXIgTUFQID0gJ01hcCc7XG5cbi8vIDIzLjEgTWFwIE9iamVjdHNcbm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi9fY29sbGVjdGlvbicpKE1BUCwgZnVuY3Rpb24gKGdldCkge1xuICByZXR1cm4gZnVuY3Rpb24gTWFwKCkgeyByZXR1cm4gZ2V0KHRoaXMsIGFyZ3VtZW50cy5sZW5ndGggPiAwID8gYXJndW1lbnRzWzBdIDogdW5kZWZpbmVkKTsgfTtcbn0sIHtcbiAgLy8gMjMuMS4zLjYgTWFwLnByb3RvdHlwZS5nZXQoa2V5KVxuICBnZXQ6IGZ1bmN0aW9uIGdldChrZXkpIHtcbiAgICB2YXIgZW50cnkgPSBzdHJvbmcuZ2V0RW50cnkodmFsaWRhdGUodGhpcywgTUFQKSwga2V5KTtcbiAgICByZXR1cm4gZW50cnkgJiYgZW50cnkudjtcbiAgfSxcbiAgLy8gMjMuMS4zLjkgTWFwLnByb3RvdHlwZS5zZXQoa2V5LCB2YWx1ZSlcbiAgc2V0OiBmdW5jdGlvbiBzZXQoa2V5LCB2YWx1ZSkge1xuICAgIHJldHVybiBzdHJvbmcuZGVmKHZhbGlkYXRlKHRoaXMsIE1BUCksIGtleSA9PT0gMCA/IDAgOiBrZXksIHZhbHVlKTtcbiAgfVxufSwgc3Ryb25nLCB0cnVlKTtcbiIsIi8vIDIwLjIuMi4zIE1hdGguYWNvc2goeClcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgbG9nMXAgPSByZXF1aXJlKCcuL19tYXRoLWxvZzFwJyk7XG52YXIgc3FydCA9IE1hdGguc3FydDtcbnZhciAkYWNvc2ggPSBNYXRoLmFjb3NoO1xuXG4kZXhwb3J0KCRleHBvcnQuUyArICRleHBvcnQuRiAqICEoJGFjb3NoXG4gIC8vIFY4IGJ1ZzogaHR0cHM6Ly9jb2RlLmdvb2dsZS5jb20vcC92OC9pc3N1ZXMvZGV0YWlsP2lkPTM1MDlcbiAgJiYgTWF0aC5mbG9vcigkYWNvc2goTnVtYmVyLk1BWF9WQUxVRSkpID09IDcxMFxuICAvLyBUb3IgQnJvd3NlciBidWc6IE1hdGguYWNvc2goSW5maW5pdHkpIC0+IE5hTlxuICAmJiAkYWNvc2goSW5maW5pdHkpID09IEluZmluaXR5XG4pLCAnTWF0aCcsIHtcbiAgYWNvc2g6IGZ1bmN0aW9uIGFjb3NoKHgpIHtcbiAgICByZXR1cm4gKHggPSAreCkgPCAxID8gTmFOIDogeCA+IDk0OTA2MjY1LjYyNDI1MTU2XG4gICAgICA/IE1hdGgubG9nKHgpICsgTWF0aC5MTjJcbiAgICAgIDogbG9nMXAoeCAtIDEgKyBzcXJ0KHggLSAxKSAqIHNxcnQoeCArIDEpKTtcbiAgfVxufSk7XG4iLCIvLyAyMC4yLjIuNSBNYXRoLmFzaW5oKHgpXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyICRhc2luaCA9IE1hdGguYXNpbmg7XG5cbmZ1bmN0aW9uIGFzaW5oKHgpIHtcbiAgcmV0dXJuICFpc0Zpbml0ZSh4ID0gK3gpIHx8IHggPT0gMCA/IHggOiB4IDwgMCA/IC1hc2luaCgteCkgOiBNYXRoLmxvZyh4ICsgTWF0aC5zcXJ0KHggKiB4ICsgMSkpO1xufVxuXG4vLyBUb3IgQnJvd3NlciBidWc6IE1hdGguYXNpbmgoMCkgLT4gLTBcbiRleHBvcnQoJGV4cG9ydC5TICsgJGV4cG9ydC5GICogISgkYXNpbmggJiYgMSAvICRhc2luaCgwKSA+IDApLCAnTWF0aCcsIHsgYXNpbmg6IGFzaW5oIH0pO1xuIiwiLy8gMjAuMi4yLjcgTWF0aC5hdGFuaCh4KVxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciAkYXRhbmggPSBNYXRoLmF0YW5oO1xuXG4vLyBUb3IgQnJvd3NlciBidWc6IE1hdGguYXRhbmgoLTApIC0+IDBcbiRleHBvcnQoJGV4cG9ydC5TICsgJGV4cG9ydC5GICogISgkYXRhbmggJiYgMSAvICRhdGFuaCgtMCkgPCAwKSwgJ01hdGgnLCB7XG4gIGF0YW5oOiBmdW5jdGlvbiBhdGFuaCh4KSB7XG4gICAgcmV0dXJuICh4ID0gK3gpID09IDAgPyB4IDogTWF0aC5sb2coKDEgKyB4KSAvICgxIC0geCkpIC8gMjtcbiAgfVxufSk7XG4iLCIvLyAyMC4yLjIuOSBNYXRoLmNicnQoeClcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgc2lnbiA9IHJlcXVpcmUoJy4vX21hdGgtc2lnbicpO1xuXG4kZXhwb3J0KCRleHBvcnQuUywgJ01hdGgnLCB7XG4gIGNicnQ6IGZ1bmN0aW9uIGNicnQoeCkge1xuICAgIHJldHVybiBzaWduKHggPSAreCkgKiBNYXRoLnBvdyhNYXRoLmFicyh4KSwgMSAvIDMpO1xuICB9XG59KTtcbiIsIi8vIDIwLjIuMi4xMSBNYXRoLmNsejMyKHgpXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xuXG4kZXhwb3J0KCRleHBvcnQuUywgJ01hdGgnLCB7XG4gIGNsejMyOiBmdW5jdGlvbiBjbHozMih4KSB7XG4gICAgcmV0dXJuICh4ID4+Pj0gMCkgPyAzMSAtIE1hdGguZmxvb3IoTWF0aC5sb2coeCArIDAuNSkgKiBNYXRoLkxPRzJFKSA6IDMyO1xuICB9XG59KTtcbiIsIi8vIDIwLjIuMi4xMiBNYXRoLmNvc2goeClcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgZXhwID0gTWF0aC5leHA7XG5cbiRleHBvcnQoJGV4cG9ydC5TLCAnTWF0aCcsIHtcbiAgY29zaDogZnVuY3Rpb24gY29zaCh4KSB7XG4gICAgcmV0dXJuIChleHAoeCA9ICt4KSArIGV4cCgteCkpIC8gMjtcbiAgfVxufSk7XG4iLCIvLyAyMC4yLjIuMTQgTWF0aC5leHBtMSh4KVxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciAkZXhwbTEgPSByZXF1aXJlKCcuL19tYXRoLWV4cG0xJyk7XG5cbiRleHBvcnQoJGV4cG9ydC5TICsgJGV4cG9ydC5GICogKCRleHBtMSAhPSBNYXRoLmV4cG0xKSwgJ01hdGgnLCB7IGV4cG0xOiAkZXhwbTEgfSk7XG4iLCIvLyAyMC4yLjIuMTYgTWF0aC5mcm91bmQoeClcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG5cbiRleHBvcnQoJGV4cG9ydC5TLCAnTWF0aCcsIHsgZnJvdW5kOiByZXF1aXJlKCcuL19tYXRoLWZyb3VuZCcpIH0pO1xuIiwiLy8gMjAuMi4yLjE3IE1hdGguaHlwb3QoW3ZhbHVlMVssIHZhbHVlMlssIOKApiBdXV0pXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyIGFicyA9IE1hdGguYWJzO1xuXG4kZXhwb3J0KCRleHBvcnQuUywgJ01hdGgnLCB7XG4gIGh5cG90OiBmdW5jdGlvbiBoeXBvdCh2YWx1ZTEsIHZhbHVlMikgeyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXVudXNlZC12YXJzXG4gICAgdmFyIHN1bSA9IDA7XG4gICAgdmFyIGkgPSAwO1xuICAgIHZhciBhTGVuID0gYXJndW1lbnRzLmxlbmd0aDtcbiAgICB2YXIgbGFyZyA9IDA7XG4gICAgdmFyIGFyZywgZGl2O1xuICAgIHdoaWxlIChpIDwgYUxlbikge1xuICAgICAgYXJnID0gYWJzKGFyZ3VtZW50c1tpKytdKTtcbiAgICAgIGlmIChsYXJnIDwgYXJnKSB7XG4gICAgICAgIGRpdiA9IGxhcmcgLyBhcmc7XG4gICAgICAgIHN1bSA9IHN1bSAqIGRpdiAqIGRpdiArIDE7XG4gICAgICAgIGxhcmcgPSBhcmc7XG4gICAgICB9IGVsc2UgaWYgKGFyZyA+IDApIHtcbiAgICAgICAgZGl2ID0gYXJnIC8gbGFyZztcbiAgICAgICAgc3VtICs9IGRpdiAqIGRpdjtcbiAgICAgIH0gZWxzZSBzdW0gKz0gYXJnO1xuICAgIH1cbiAgICByZXR1cm4gbGFyZyA9PT0gSW5maW5pdHkgPyBJbmZpbml0eSA6IGxhcmcgKiBNYXRoLnNxcnQoc3VtKTtcbiAgfVxufSk7XG4iLCIvLyAyMC4yLjIuMTggTWF0aC5pbXVsKHgsIHkpXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyICRpbXVsID0gTWF0aC5pbXVsO1xuXG4vLyBzb21lIFdlYktpdCB2ZXJzaW9ucyBmYWlscyB3aXRoIGJpZyBudW1iZXJzLCBzb21lIGhhcyB3cm9uZyBhcml0eVxuJGV4cG9ydCgkZXhwb3J0LlMgKyAkZXhwb3J0LkYgKiByZXF1aXJlKCcuL19mYWlscycpKGZ1bmN0aW9uICgpIHtcbiAgcmV0dXJuICRpbXVsKDB4ZmZmZmZmZmYsIDUpICE9IC01IHx8ICRpbXVsLmxlbmd0aCAhPSAyO1xufSksICdNYXRoJywge1xuICBpbXVsOiBmdW5jdGlvbiBpbXVsKHgsIHkpIHtcbiAgICB2YXIgVUlOVDE2ID0gMHhmZmZmO1xuICAgIHZhciB4biA9ICt4O1xuICAgIHZhciB5biA9ICt5O1xuICAgIHZhciB4bCA9IFVJTlQxNiAmIHhuO1xuICAgIHZhciB5bCA9IFVJTlQxNiAmIHluO1xuICAgIHJldHVybiAwIHwgeGwgKiB5bCArICgoVUlOVDE2ICYgeG4gPj4+IDE2KSAqIHlsICsgeGwgKiAoVUlOVDE2ICYgeW4gPj4+IDE2KSA8PCAxNiA+Pj4gMCk7XG4gIH1cbn0pO1xuIiwiLy8gMjAuMi4yLjIxIE1hdGgubG9nMTAoeClcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG5cbiRleHBvcnQoJGV4cG9ydC5TLCAnTWF0aCcsIHtcbiAgbG9nMTA6IGZ1bmN0aW9uIGxvZzEwKHgpIHtcbiAgICByZXR1cm4gTWF0aC5sb2coeCkgKiBNYXRoLkxPRzEwRTtcbiAgfVxufSk7XG4iLCIvLyAyMC4yLjIuMjAgTWF0aC5sb2cxcCh4KVxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcblxuJGV4cG9ydCgkZXhwb3J0LlMsICdNYXRoJywgeyBsb2cxcDogcmVxdWlyZSgnLi9fbWF0aC1sb2cxcCcpIH0pO1xuIiwiLy8gMjAuMi4yLjIyIE1hdGgubG9nMih4KVxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcblxuJGV4cG9ydCgkZXhwb3J0LlMsICdNYXRoJywge1xuICBsb2cyOiBmdW5jdGlvbiBsb2cyKHgpIHtcbiAgICByZXR1cm4gTWF0aC5sb2coeCkgLyBNYXRoLkxOMjtcbiAgfVxufSk7XG4iLCIvLyAyMC4yLjIuMjggTWF0aC5zaWduKHgpXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xuXG4kZXhwb3J0KCRleHBvcnQuUywgJ01hdGgnLCB7IHNpZ246IHJlcXVpcmUoJy4vX21hdGgtc2lnbicpIH0pO1xuIiwiLy8gMjAuMi4yLjMwIE1hdGguc2luaCh4KVxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciBleHBtMSA9IHJlcXVpcmUoJy4vX21hdGgtZXhwbTEnKTtcbnZhciBleHAgPSBNYXRoLmV4cDtcblxuLy8gVjggbmVhciBDaHJvbWl1bSAzOCBoYXMgYSBwcm9ibGVtIHdpdGggdmVyeSBzbWFsbCBudW1iZXJzXG4kZXhwb3J0KCRleHBvcnQuUyArICRleHBvcnQuRiAqIHJlcXVpcmUoJy4vX2ZhaWxzJykoZnVuY3Rpb24gKCkge1xuICByZXR1cm4gIU1hdGguc2luaCgtMmUtMTcpICE9IC0yZS0xNztcbn0pLCAnTWF0aCcsIHtcbiAgc2luaDogZnVuY3Rpb24gc2luaCh4KSB7XG4gICAgcmV0dXJuIE1hdGguYWJzKHggPSAreCkgPCAxXG4gICAgICA/IChleHBtMSh4KSAtIGV4cG0xKC14KSkgLyAyXG4gICAgICA6IChleHAoeCAtIDEpIC0gZXhwKC14IC0gMSkpICogKE1hdGguRSAvIDIpO1xuICB9XG59KTtcbiIsIi8vIDIwLjIuMi4zMyBNYXRoLnRhbmgoeClcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgZXhwbTEgPSByZXF1aXJlKCcuL19tYXRoLWV4cG0xJyk7XG52YXIgZXhwID0gTWF0aC5leHA7XG5cbiRleHBvcnQoJGV4cG9ydC5TLCAnTWF0aCcsIHtcbiAgdGFuaDogZnVuY3Rpb24gdGFuaCh4KSB7XG4gICAgdmFyIGEgPSBleHBtMSh4ID0gK3gpO1xuICAgIHZhciBiID0gZXhwbTEoLXgpO1xuICAgIHJldHVybiBhID09IEluZmluaXR5ID8gMSA6IGIgPT0gSW5maW5pdHkgPyAtMSA6IChhIC0gYikgLyAoZXhwKHgpICsgZXhwKC14KSk7XG4gIH1cbn0pO1xuIiwiLy8gMjAuMi4yLjM0IE1hdGgudHJ1bmMoeClcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG5cbiRleHBvcnQoJGV4cG9ydC5TLCAnTWF0aCcsIHtcbiAgdHJ1bmM6IGZ1bmN0aW9uIHRydW5jKGl0KSB7XG4gICAgcmV0dXJuIChpdCA+IDAgPyBNYXRoLmZsb29yIDogTWF0aC5jZWlsKShpdCk7XG4gIH1cbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyIGdsb2JhbCA9IHJlcXVpcmUoJy4vX2dsb2JhbCcpO1xudmFyIGhhcyA9IHJlcXVpcmUoJy4vX2hhcycpO1xudmFyIGNvZiA9IHJlcXVpcmUoJy4vX2NvZicpO1xudmFyIGluaGVyaXRJZlJlcXVpcmVkID0gcmVxdWlyZSgnLi9faW5oZXJpdC1pZi1yZXF1aXJlZCcpO1xudmFyIHRvUHJpbWl0aXZlID0gcmVxdWlyZSgnLi9fdG8tcHJpbWl0aXZlJyk7XG52YXIgZmFpbHMgPSByZXF1aXJlKCcuL19mYWlscycpO1xudmFyIGdPUE4gPSByZXF1aXJlKCcuL19vYmplY3QtZ29wbicpLmY7XG52YXIgZ09QRCA9IHJlcXVpcmUoJy4vX29iamVjdC1nb3BkJykuZjtcbnZhciBkUCA9IHJlcXVpcmUoJy4vX29iamVjdC1kcCcpLmY7XG52YXIgJHRyaW0gPSByZXF1aXJlKCcuL19zdHJpbmctdHJpbScpLnRyaW07XG52YXIgTlVNQkVSID0gJ051bWJlcic7XG52YXIgJE51bWJlciA9IGdsb2JhbFtOVU1CRVJdO1xudmFyIEJhc2UgPSAkTnVtYmVyO1xudmFyIHByb3RvID0gJE51bWJlci5wcm90b3R5cGU7XG4vLyBPcGVyYSB+MTIgaGFzIGJyb2tlbiBPYmplY3QjdG9TdHJpbmdcbnZhciBCUk9LRU5fQ09GID0gY29mKHJlcXVpcmUoJy4vX29iamVjdC1jcmVhdGUnKShwcm90bykpID09IE5VTUJFUjtcbnZhciBUUklNID0gJ3RyaW0nIGluIFN0cmluZy5wcm90b3R5cGU7XG5cbi8vIDcuMS4zIFRvTnVtYmVyKGFyZ3VtZW50KVxudmFyIHRvTnVtYmVyID0gZnVuY3Rpb24gKGFyZ3VtZW50KSB7XG4gIHZhciBpdCA9IHRvUHJpbWl0aXZlKGFyZ3VtZW50LCBmYWxzZSk7XG4gIGlmICh0eXBlb2YgaXQgPT0gJ3N0cmluZycgJiYgaXQubGVuZ3RoID4gMikge1xuICAgIGl0ID0gVFJJTSA/IGl0LnRyaW0oKSA6ICR0cmltKGl0LCAzKTtcbiAgICB2YXIgZmlyc3QgPSBpdC5jaGFyQ29kZUF0KDApO1xuICAgIHZhciB0aGlyZCwgcmFkaXgsIG1heENvZGU7XG4gICAgaWYgKGZpcnN0ID09PSA0MyB8fCBmaXJzdCA9PT0gNDUpIHtcbiAgICAgIHRoaXJkID0gaXQuY2hhckNvZGVBdCgyKTtcbiAgICAgIGlmICh0aGlyZCA9PT0gODggfHwgdGhpcmQgPT09IDEyMCkgcmV0dXJuIE5hTjsgLy8gTnVtYmVyKCcrMHgxJykgc2hvdWxkIGJlIE5hTiwgb2xkIFY4IGZpeFxuICAgIH0gZWxzZSBpZiAoZmlyc3QgPT09IDQ4KSB7XG4gICAgICBzd2l0Y2ggKGl0LmNoYXJDb2RlQXQoMSkpIHtcbiAgICAgICAgY2FzZSA2NjogY2FzZSA5ODogcmFkaXggPSAyOyBtYXhDb2RlID0gNDk7IGJyZWFrOyAvLyBmYXN0IGVxdWFsIC9eMGJbMDFdKyQvaVxuICAgICAgICBjYXNlIDc5OiBjYXNlIDExMTogcmFkaXggPSA4OyBtYXhDb2RlID0gNTU7IGJyZWFrOyAvLyBmYXN0IGVxdWFsIC9eMG9bMC03XSskL2lcbiAgICAgICAgZGVmYXVsdDogcmV0dXJuICtpdDtcbiAgICAgIH1cbiAgICAgIGZvciAodmFyIGRpZ2l0cyA9IGl0LnNsaWNlKDIpLCBpID0gMCwgbCA9IGRpZ2l0cy5sZW5ndGgsIGNvZGU7IGkgPCBsOyBpKyspIHtcbiAgICAgICAgY29kZSA9IGRpZ2l0cy5jaGFyQ29kZUF0KGkpO1xuICAgICAgICAvLyBwYXJzZUludCBwYXJzZXMgYSBzdHJpbmcgdG8gYSBmaXJzdCB1bmF2YWlsYWJsZSBzeW1ib2xcbiAgICAgICAgLy8gYnV0IFRvTnVtYmVyIHNob3VsZCByZXR1cm4gTmFOIGlmIGEgc3RyaW5nIGNvbnRhaW5zIHVuYXZhaWxhYmxlIHN5bWJvbHNcbiAgICAgICAgaWYgKGNvZGUgPCA0OCB8fCBjb2RlID4gbWF4Q29kZSkgcmV0dXJuIE5hTjtcbiAgICAgIH0gcmV0dXJuIHBhcnNlSW50KGRpZ2l0cywgcmFkaXgpO1xuICAgIH1cbiAgfSByZXR1cm4gK2l0O1xufTtcblxuaWYgKCEkTnVtYmVyKCcgMG8xJykgfHwgISROdW1iZXIoJzBiMScpIHx8ICROdW1iZXIoJysweDEnKSkge1xuICAkTnVtYmVyID0gZnVuY3Rpb24gTnVtYmVyKHZhbHVlKSB7XG4gICAgdmFyIGl0ID0gYXJndW1lbnRzLmxlbmd0aCA8IDEgPyAwIDogdmFsdWU7XG4gICAgdmFyIHRoYXQgPSB0aGlzO1xuICAgIHJldHVybiB0aGF0IGluc3RhbmNlb2YgJE51bWJlclxuICAgICAgLy8gY2hlY2sgb24gMS4uY29uc3RydWN0b3IoZm9vKSBjYXNlXG4gICAgICAmJiAoQlJPS0VOX0NPRiA/IGZhaWxzKGZ1bmN0aW9uICgpIHsgcHJvdG8udmFsdWVPZi5jYWxsKHRoYXQpOyB9KSA6IGNvZih0aGF0KSAhPSBOVU1CRVIpXG4gICAgICAgID8gaW5oZXJpdElmUmVxdWlyZWQobmV3IEJhc2UodG9OdW1iZXIoaXQpKSwgdGhhdCwgJE51bWJlcikgOiB0b051bWJlcihpdCk7XG4gIH07XG4gIGZvciAodmFyIGtleXMgPSByZXF1aXJlKCcuL19kZXNjcmlwdG9ycycpID8gZ09QTihCYXNlKSA6IChcbiAgICAvLyBFUzM6XG4gICAgJ01BWF9WQUxVRSxNSU5fVkFMVUUsTmFOLE5FR0FUSVZFX0lORklOSVRZLFBPU0lUSVZFX0lORklOSVRZLCcgK1xuICAgIC8vIEVTNiAoaW4gY2FzZSwgaWYgbW9kdWxlcyB3aXRoIEVTNiBOdW1iZXIgc3RhdGljcyByZXF1aXJlZCBiZWZvcmUpOlxuICAgICdFUFNJTE9OLGlzRmluaXRlLGlzSW50ZWdlcixpc05hTixpc1NhZmVJbnRlZ2VyLE1BWF9TQUZFX0lOVEVHRVIsJyArXG4gICAgJ01JTl9TQUZFX0lOVEVHRVIscGFyc2VGbG9hdCxwYXJzZUludCxpc0ludGVnZXInXG4gICkuc3BsaXQoJywnKSwgaiA9IDAsIGtleTsga2V5cy5sZW5ndGggPiBqOyBqKyspIHtcbiAgICBpZiAoaGFzKEJhc2UsIGtleSA9IGtleXNbal0pICYmICFoYXMoJE51bWJlciwga2V5KSkge1xuICAgICAgZFAoJE51bWJlciwga2V5LCBnT1BEKEJhc2UsIGtleSkpO1xuICAgIH1cbiAgfVxuICAkTnVtYmVyLnByb3RvdHlwZSA9IHByb3RvO1xuICBwcm90by5jb25zdHJ1Y3RvciA9ICROdW1iZXI7XG4gIHJlcXVpcmUoJy4vX3JlZGVmaW5lJykoZ2xvYmFsLCBOVU1CRVIsICROdW1iZXIpO1xufVxuIiwiLy8gMjAuMS4yLjEgTnVtYmVyLkVQU0lMT05cbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG5cbiRleHBvcnQoJGV4cG9ydC5TLCAnTnVtYmVyJywgeyBFUFNJTE9OOiBNYXRoLnBvdygyLCAtNTIpIH0pO1xuIiwiLy8gMjAuMS4yLjIgTnVtYmVyLmlzRmluaXRlKG51bWJlcilcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgX2lzRmluaXRlID0gcmVxdWlyZSgnLi9fZ2xvYmFsJykuaXNGaW5pdGU7XG5cbiRleHBvcnQoJGV4cG9ydC5TLCAnTnVtYmVyJywge1xuICBpc0Zpbml0ZTogZnVuY3Rpb24gaXNGaW5pdGUoaXQpIHtcbiAgICByZXR1cm4gdHlwZW9mIGl0ID09ICdudW1iZXInICYmIF9pc0Zpbml0ZShpdCk7XG4gIH1cbn0pO1xuIiwiLy8gMjAuMS4yLjMgTnVtYmVyLmlzSW50ZWdlcihudW1iZXIpXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xuXG4kZXhwb3J0KCRleHBvcnQuUywgJ051bWJlcicsIHsgaXNJbnRlZ2VyOiByZXF1aXJlKCcuL19pcy1pbnRlZ2VyJykgfSk7XG4iLCIvLyAyMC4xLjIuNCBOdW1iZXIuaXNOYU4obnVtYmVyKVxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcblxuJGV4cG9ydCgkZXhwb3J0LlMsICdOdW1iZXInLCB7XG4gIGlzTmFOOiBmdW5jdGlvbiBpc05hTihudW1iZXIpIHtcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tc2VsZi1jb21wYXJlXG4gICAgcmV0dXJuIG51bWJlciAhPSBudW1iZXI7XG4gIH1cbn0pO1xuIiwiLy8gMjAuMS4yLjUgTnVtYmVyLmlzU2FmZUludGVnZXIobnVtYmVyKVxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciBpc0ludGVnZXIgPSByZXF1aXJlKCcuL19pcy1pbnRlZ2VyJyk7XG52YXIgYWJzID0gTWF0aC5hYnM7XG5cbiRleHBvcnQoJGV4cG9ydC5TLCAnTnVtYmVyJywge1xuICBpc1NhZmVJbnRlZ2VyOiBmdW5jdGlvbiBpc1NhZmVJbnRlZ2VyKG51bWJlcikge1xuICAgIHJldHVybiBpc0ludGVnZXIobnVtYmVyKSAmJiBhYnMobnVtYmVyKSA8PSAweDFmZmZmZmZmZmZmZmZmO1xuICB9XG59KTtcbiIsIi8vIDIwLjEuMi42IE51bWJlci5NQVhfU0FGRV9JTlRFR0VSXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xuXG4kZXhwb3J0KCRleHBvcnQuUywgJ051bWJlcicsIHsgTUFYX1NBRkVfSU5URUdFUjogMHgxZmZmZmZmZmZmZmZmZiB9KTtcbiIsIi8vIDIwLjEuMi4xMCBOdW1iZXIuTUlOX1NBRkVfSU5URUdFUlxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcblxuJGV4cG9ydCgkZXhwb3J0LlMsICdOdW1iZXInLCB7IE1JTl9TQUZFX0lOVEVHRVI6IC0weDFmZmZmZmZmZmZmZmZmIH0pO1xuIiwidmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciAkcGFyc2VGbG9hdCA9IHJlcXVpcmUoJy4vX3BhcnNlLWZsb2F0Jyk7XG4vLyAyMC4xLjIuMTIgTnVtYmVyLnBhcnNlRmxvYXQoc3RyaW5nKVxuJGV4cG9ydCgkZXhwb3J0LlMgKyAkZXhwb3J0LkYgKiAoTnVtYmVyLnBhcnNlRmxvYXQgIT0gJHBhcnNlRmxvYXQpLCAnTnVtYmVyJywgeyBwYXJzZUZsb2F0OiAkcGFyc2VGbG9hdCB9KTtcbiIsInZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgJHBhcnNlSW50ID0gcmVxdWlyZSgnLi9fcGFyc2UtaW50Jyk7XG4vLyAyMC4xLjIuMTMgTnVtYmVyLnBhcnNlSW50KHN0cmluZywgcmFkaXgpXG4kZXhwb3J0KCRleHBvcnQuUyArICRleHBvcnQuRiAqIChOdW1iZXIucGFyc2VJbnQgIT0gJHBhcnNlSW50KSwgJ051bWJlcicsIHsgcGFyc2VJbnQ6ICRwYXJzZUludCB9KTtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgdG9JbnRlZ2VyID0gcmVxdWlyZSgnLi9fdG8taW50ZWdlcicpO1xudmFyIGFOdW1iZXJWYWx1ZSA9IHJlcXVpcmUoJy4vX2EtbnVtYmVyLXZhbHVlJyk7XG52YXIgcmVwZWF0ID0gcmVxdWlyZSgnLi9fc3RyaW5nLXJlcGVhdCcpO1xudmFyICR0b0ZpeGVkID0gMS4wLnRvRml4ZWQ7XG52YXIgZmxvb3IgPSBNYXRoLmZsb29yO1xudmFyIGRhdGEgPSBbMCwgMCwgMCwgMCwgMCwgMF07XG52YXIgRVJST1IgPSAnTnVtYmVyLnRvRml4ZWQ6IGluY29ycmVjdCBpbnZvY2F0aW9uISc7XG52YXIgWkVSTyA9ICcwJztcblxudmFyIG11bHRpcGx5ID0gZnVuY3Rpb24gKG4sIGMpIHtcbiAgdmFyIGkgPSAtMTtcbiAgdmFyIGMyID0gYztcbiAgd2hpbGUgKCsraSA8IDYpIHtcbiAgICBjMiArPSBuICogZGF0YVtpXTtcbiAgICBkYXRhW2ldID0gYzIgJSAxZTc7XG4gICAgYzIgPSBmbG9vcihjMiAvIDFlNyk7XG4gIH1cbn07XG52YXIgZGl2aWRlID0gZnVuY3Rpb24gKG4pIHtcbiAgdmFyIGkgPSA2O1xuICB2YXIgYyA9IDA7XG4gIHdoaWxlICgtLWkgPj0gMCkge1xuICAgIGMgKz0gZGF0YVtpXTtcbiAgICBkYXRhW2ldID0gZmxvb3IoYyAvIG4pO1xuICAgIGMgPSAoYyAlIG4pICogMWU3O1xuICB9XG59O1xudmFyIG51bVRvU3RyaW5nID0gZnVuY3Rpb24gKCkge1xuICB2YXIgaSA9IDY7XG4gIHZhciBzID0gJyc7XG4gIHdoaWxlICgtLWkgPj0gMCkge1xuICAgIGlmIChzICE9PSAnJyB8fCBpID09PSAwIHx8IGRhdGFbaV0gIT09IDApIHtcbiAgICAgIHZhciB0ID0gU3RyaW5nKGRhdGFbaV0pO1xuICAgICAgcyA9IHMgPT09ICcnID8gdCA6IHMgKyByZXBlYXQuY2FsbChaRVJPLCA3IC0gdC5sZW5ndGgpICsgdDtcbiAgICB9XG4gIH0gcmV0dXJuIHM7XG59O1xudmFyIHBvdyA9IGZ1bmN0aW9uICh4LCBuLCBhY2MpIHtcbiAgcmV0dXJuIG4gPT09IDAgPyBhY2MgOiBuICUgMiA9PT0gMSA/IHBvdyh4LCBuIC0gMSwgYWNjICogeCkgOiBwb3coeCAqIHgsIG4gLyAyLCBhY2MpO1xufTtcbnZhciBsb2cgPSBmdW5jdGlvbiAoeCkge1xuICB2YXIgbiA9IDA7XG4gIHZhciB4MiA9IHg7XG4gIHdoaWxlICh4MiA+PSA0MDk2KSB7XG4gICAgbiArPSAxMjtcbiAgICB4MiAvPSA0MDk2O1xuICB9XG4gIHdoaWxlICh4MiA+PSAyKSB7XG4gICAgbiArPSAxO1xuICAgIHgyIC89IDI7XG4gIH0gcmV0dXJuIG47XG59O1xuXG4kZXhwb3J0KCRleHBvcnQuUCArICRleHBvcnQuRiAqICghISR0b0ZpeGVkICYmIChcbiAgMC4wMDAwOC50b0ZpeGVkKDMpICE9PSAnMC4wMDAnIHx8XG4gIDAuOS50b0ZpeGVkKDApICE9PSAnMScgfHxcbiAgMS4yNTUudG9GaXhlZCgyKSAhPT0gJzEuMjUnIHx8XG4gIDEwMDAwMDAwMDAwMDAwMDAxMjguMC50b0ZpeGVkKDApICE9PSAnMTAwMDAwMDAwMDAwMDAwMDEyOCdcbikgfHwgIXJlcXVpcmUoJy4vX2ZhaWxzJykoZnVuY3Rpb24gKCkge1xuICAvLyBWOCB+IEFuZHJvaWQgNC4zLVxuICAkdG9GaXhlZC5jYWxsKHt9KTtcbn0pKSwgJ051bWJlcicsIHtcbiAgdG9GaXhlZDogZnVuY3Rpb24gdG9GaXhlZChmcmFjdGlvbkRpZ2l0cykge1xuICAgIHZhciB4ID0gYU51bWJlclZhbHVlKHRoaXMsIEVSUk9SKTtcbiAgICB2YXIgZiA9IHRvSW50ZWdlcihmcmFjdGlvbkRpZ2l0cyk7XG4gICAgdmFyIHMgPSAnJztcbiAgICB2YXIgbSA9IFpFUk87XG4gICAgdmFyIGUsIHosIGosIGs7XG4gICAgaWYgKGYgPCAwIHx8IGYgPiAyMCkgdGhyb3cgUmFuZ2VFcnJvcihFUlJPUik7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXNlbGYtY29tcGFyZVxuICAgIGlmICh4ICE9IHgpIHJldHVybiAnTmFOJztcbiAgICBpZiAoeCA8PSAtMWUyMSB8fCB4ID49IDFlMjEpIHJldHVybiBTdHJpbmcoeCk7XG4gICAgaWYgKHggPCAwKSB7XG4gICAgICBzID0gJy0nO1xuICAgICAgeCA9IC14O1xuICAgIH1cbiAgICBpZiAoeCA+IDFlLTIxKSB7XG4gICAgICBlID0gbG9nKHggKiBwb3coMiwgNjksIDEpKSAtIDY5O1xuICAgICAgeiA9IGUgPCAwID8geCAqIHBvdygyLCAtZSwgMSkgOiB4IC8gcG93KDIsIGUsIDEpO1xuICAgICAgeiAqPSAweDEwMDAwMDAwMDAwMDAwO1xuICAgICAgZSA9IDUyIC0gZTtcbiAgICAgIGlmIChlID4gMCkge1xuICAgICAgICBtdWx0aXBseSgwLCB6KTtcbiAgICAgICAgaiA9IGY7XG4gICAgICAgIHdoaWxlIChqID49IDcpIHtcbiAgICAgICAgICBtdWx0aXBseSgxZTcsIDApO1xuICAgICAgICAgIGogLT0gNztcbiAgICAgICAgfVxuICAgICAgICBtdWx0aXBseShwb3coMTAsIGosIDEpLCAwKTtcbiAgICAgICAgaiA9IGUgLSAxO1xuICAgICAgICB3aGlsZSAoaiA+PSAyMykge1xuICAgICAgICAgIGRpdmlkZSgxIDw8IDIzKTtcbiAgICAgICAgICBqIC09IDIzO1xuICAgICAgICB9XG4gICAgICAgIGRpdmlkZSgxIDw8IGopO1xuICAgICAgICBtdWx0aXBseSgxLCAxKTtcbiAgICAgICAgZGl2aWRlKDIpO1xuICAgICAgICBtID0gbnVtVG9TdHJpbmcoKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG11bHRpcGx5KDAsIHopO1xuICAgICAgICBtdWx0aXBseSgxIDw8IC1lLCAwKTtcbiAgICAgICAgbSA9IG51bVRvU3RyaW5nKCkgKyByZXBlYXQuY2FsbChaRVJPLCBmKTtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKGYgPiAwKSB7XG4gICAgICBrID0gbS5sZW5ndGg7XG4gICAgICBtID0gcyArIChrIDw9IGYgPyAnMC4nICsgcmVwZWF0LmNhbGwoWkVSTywgZiAtIGspICsgbSA6IG0uc2xpY2UoMCwgayAtIGYpICsgJy4nICsgbS5zbGljZShrIC0gZikpO1xuICAgIH0gZWxzZSB7XG4gICAgICBtID0gcyArIG07XG4gICAgfSByZXR1cm4gbTtcbiAgfVxufSk7XG4iLCIndXNlIHN0cmljdCc7XG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyICRmYWlscyA9IHJlcXVpcmUoJy4vX2ZhaWxzJyk7XG52YXIgYU51bWJlclZhbHVlID0gcmVxdWlyZSgnLi9fYS1udW1iZXItdmFsdWUnKTtcbnZhciAkdG9QcmVjaXNpb24gPSAxLjAudG9QcmVjaXNpb247XG5cbiRleHBvcnQoJGV4cG9ydC5QICsgJGV4cG9ydC5GICogKCRmYWlscyhmdW5jdGlvbiAoKSB7XG4gIC8vIElFNy1cbiAgcmV0dXJuICR0b1ByZWNpc2lvbi5jYWxsKDEsIHVuZGVmaW5lZCkgIT09ICcxJztcbn0pIHx8ICEkZmFpbHMoZnVuY3Rpb24gKCkge1xuICAvLyBWOCB+IEFuZHJvaWQgNC4zLVxuICAkdG9QcmVjaXNpb24uY2FsbCh7fSk7XG59KSksICdOdW1iZXInLCB7XG4gIHRvUHJlY2lzaW9uOiBmdW5jdGlvbiB0b1ByZWNpc2lvbihwcmVjaXNpb24pIHtcbiAgICB2YXIgdGhhdCA9IGFOdW1iZXJWYWx1ZSh0aGlzLCAnTnVtYmVyI3RvUHJlY2lzaW9uOiBpbmNvcnJlY3QgaW52b2NhdGlvbiEnKTtcbiAgICByZXR1cm4gcHJlY2lzaW9uID09PSB1bmRlZmluZWQgPyAkdG9QcmVjaXNpb24uY2FsbCh0aGF0KSA6ICR0b1ByZWNpc2lvbi5jYWxsKHRoYXQsIHByZWNpc2lvbik7XG4gIH1cbn0pO1xuIiwiLy8gMTkuMS4zLjEgT2JqZWN0LmFzc2lnbih0YXJnZXQsIHNvdXJjZSlcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG5cbiRleHBvcnQoJGV4cG9ydC5TICsgJGV4cG9ydC5GLCAnT2JqZWN0JywgeyBhc3NpZ246IHJlcXVpcmUoJy4vX29iamVjdC1hc3NpZ24nKSB9KTtcbiIsInZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG4vLyAxOS4xLjIuMiAvIDE1LjIuMy41IE9iamVjdC5jcmVhdGUoTyBbLCBQcm9wZXJ0aWVzXSlcbiRleHBvcnQoJGV4cG9ydC5TLCAnT2JqZWN0JywgeyBjcmVhdGU6IHJlcXVpcmUoJy4vX29iamVjdC1jcmVhdGUnKSB9KTtcbiIsInZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG4vLyAxOS4xLjIuMyAvIDE1LjIuMy43IE9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKE8sIFByb3BlcnRpZXMpXG4kZXhwb3J0KCRleHBvcnQuUyArICRleHBvcnQuRiAqICFyZXF1aXJlKCcuL19kZXNjcmlwdG9ycycpLCAnT2JqZWN0JywgeyBkZWZpbmVQcm9wZXJ0aWVzOiByZXF1aXJlKCcuL19vYmplY3QtZHBzJykgfSk7XG4iLCJ2YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xuLy8gMTkuMS4yLjQgLyAxNS4yLjMuNiBPYmplY3QuZGVmaW5lUHJvcGVydHkoTywgUCwgQXR0cmlidXRlcylcbiRleHBvcnQoJGV4cG9ydC5TICsgJGV4cG9ydC5GICogIXJlcXVpcmUoJy4vX2Rlc2NyaXB0b3JzJyksICdPYmplY3QnLCB7IGRlZmluZVByb3BlcnR5OiByZXF1aXJlKCcuL19vYmplY3QtZHAnKS5mIH0pO1xuIiwiLy8gMTkuMS4yLjUgT2JqZWN0LmZyZWV6ZShPKVxudmFyIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi9faXMtb2JqZWN0Jyk7XG52YXIgbWV0YSA9IHJlcXVpcmUoJy4vX21ldGEnKS5vbkZyZWV6ZTtcblxucmVxdWlyZSgnLi9fb2JqZWN0LXNhcCcpKCdmcmVlemUnLCBmdW5jdGlvbiAoJGZyZWV6ZSkge1xuICByZXR1cm4gZnVuY3Rpb24gZnJlZXplKGl0KSB7XG4gICAgcmV0dXJuICRmcmVlemUgJiYgaXNPYmplY3QoaXQpID8gJGZyZWV6ZShtZXRhKGl0KSkgOiBpdDtcbiAgfTtcbn0pO1xuIiwiLy8gMTkuMS4yLjYgT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihPLCBQKVxudmFyIHRvSU9iamVjdCA9IHJlcXVpcmUoJy4vX3RvLWlvYmplY3QnKTtcbnZhciAkZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yID0gcmVxdWlyZSgnLi9fb2JqZWN0LWdvcGQnKS5mO1xuXG5yZXF1aXJlKCcuL19vYmplY3Qtc2FwJykoJ2dldE93blByb3BlcnR5RGVzY3JpcHRvcicsIGZ1bmN0aW9uICgpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIGdldE93blByb3BlcnR5RGVzY3JpcHRvcihpdCwga2V5KSB7XG4gICAgcmV0dXJuICRnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IodG9JT2JqZWN0KGl0KSwga2V5KTtcbiAgfTtcbn0pO1xuIiwiLy8gMTkuMS4yLjcgT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMoTylcbnJlcXVpcmUoJy4vX29iamVjdC1zYXAnKSgnZ2V0T3duUHJvcGVydHlOYW1lcycsIGZ1bmN0aW9uICgpIHtcbiAgcmV0dXJuIHJlcXVpcmUoJy4vX29iamVjdC1nb3BuLWV4dCcpLmY7XG59KTtcbiIsIi8vIDE5LjEuMi45IE9iamVjdC5nZXRQcm90b3R5cGVPZihPKVxudmFyIHRvT2JqZWN0ID0gcmVxdWlyZSgnLi9fdG8tb2JqZWN0Jyk7XG52YXIgJGdldFByb3RvdHlwZU9mID0gcmVxdWlyZSgnLi9fb2JqZWN0LWdwbycpO1xuXG5yZXF1aXJlKCcuL19vYmplY3Qtc2FwJykoJ2dldFByb3RvdHlwZU9mJywgZnVuY3Rpb24gKCkge1xuICByZXR1cm4gZnVuY3Rpb24gZ2V0UHJvdG90eXBlT2YoaXQpIHtcbiAgICByZXR1cm4gJGdldFByb3RvdHlwZU9mKHRvT2JqZWN0KGl0KSk7XG4gIH07XG59KTtcbiIsIi8vIDE5LjEuMi4xMSBPYmplY3QuaXNFeHRlbnNpYmxlKE8pXG52YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuL19pcy1vYmplY3QnKTtcblxucmVxdWlyZSgnLi9fb2JqZWN0LXNhcCcpKCdpc0V4dGVuc2libGUnLCBmdW5jdGlvbiAoJGlzRXh0ZW5zaWJsZSkge1xuICByZXR1cm4gZnVuY3Rpb24gaXNFeHRlbnNpYmxlKGl0KSB7XG4gICAgcmV0dXJuIGlzT2JqZWN0KGl0KSA/ICRpc0V4dGVuc2libGUgPyAkaXNFeHRlbnNpYmxlKGl0KSA6IHRydWUgOiBmYWxzZTtcbiAgfTtcbn0pO1xuIiwiLy8gMTkuMS4yLjEyIE9iamVjdC5pc0Zyb3plbihPKVxudmFyIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi9faXMtb2JqZWN0Jyk7XG5cbnJlcXVpcmUoJy4vX29iamVjdC1zYXAnKSgnaXNGcm96ZW4nLCBmdW5jdGlvbiAoJGlzRnJvemVuKSB7XG4gIHJldHVybiBmdW5jdGlvbiBpc0Zyb3plbihpdCkge1xuICAgIHJldHVybiBpc09iamVjdChpdCkgPyAkaXNGcm96ZW4gPyAkaXNGcm96ZW4oaXQpIDogZmFsc2UgOiB0cnVlO1xuICB9O1xufSk7XG4iLCIvLyAxOS4xLjIuMTMgT2JqZWN0LmlzU2VhbGVkKE8pXG52YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuL19pcy1vYmplY3QnKTtcblxucmVxdWlyZSgnLi9fb2JqZWN0LXNhcCcpKCdpc1NlYWxlZCcsIGZ1bmN0aW9uICgkaXNTZWFsZWQpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIGlzU2VhbGVkKGl0KSB7XG4gICAgcmV0dXJuIGlzT2JqZWN0KGl0KSA/ICRpc1NlYWxlZCA/ICRpc1NlYWxlZChpdCkgOiBmYWxzZSA6IHRydWU7XG4gIH07XG59KTtcbiIsIi8vIDE5LjEuMy4xMCBPYmplY3QuaXModmFsdWUxLCB2YWx1ZTIpXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xuJGV4cG9ydCgkZXhwb3J0LlMsICdPYmplY3QnLCB7IGlzOiByZXF1aXJlKCcuL19zYW1lLXZhbHVlJykgfSk7XG4iLCIvLyAxOS4xLjIuMTQgT2JqZWN0LmtleXMoTylcbnZhciB0b09iamVjdCA9IHJlcXVpcmUoJy4vX3RvLW9iamVjdCcpO1xudmFyICRrZXlzID0gcmVxdWlyZSgnLi9fb2JqZWN0LWtleXMnKTtcblxucmVxdWlyZSgnLi9fb2JqZWN0LXNhcCcpKCdrZXlzJywgZnVuY3Rpb24gKCkge1xuICByZXR1cm4gZnVuY3Rpb24ga2V5cyhpdCkge1xuICAgIHJldHVybiAka2V5cyh0b09iamVjdChpdCkpO1xuICB9O1xufSk7XG4iLCIvLyAxOS4xLjIuMTUgT2JqZWN0LnByZXZlbnRFeHRlbnNpb25zKE8pXG52YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuL19pcy1vYmplY3QnKTtcbnZhciBtZXRhID0gcmVxdWlyZSgnLi9fbWV0YScpLm9uRnJlZXplO1xuXG5yZXF1aXJlKCcuL19vYmplY3Qtc2FwJykoJ3ByZXZlbnRFeHRlbnNpb25zJywgZnVuY3Rpb24gKCRwcmV2ZW50RXh0ZW5zaW9ucykge1xuICByZXR1cm4gZnVuY3Rpb24gcHJldmVudEV4dGVuc2lvbnMoaXQpIHtcbiAgICByZXR1cm4gJHByZXZlbnRFeHRlbnNpb25zICYmIGlzT2JqZWN0KGl0KSA/ICRwcmV2ZW50RXh0ZW5zaW9ucyhtZXRhKGl0KSkgOiBpdDtcbiAgfTtcbn0pO1xuIiwiLy8gMTkuMS4yLjE3IE9iamVjdC5zZWFsKE8pXG52YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuL19pcy1vYmplY3QnKTtcbnZhciBtZXRhID0gcmVxdWlyZSgnLi9fbWV0YScpLm9uRnJlZXplO1xuXG5yZXF1aXJlKCcuL19vYmplY3Qtc2FwJykoJ3NlYWwnLCBmdW5jdGlvbiAoJHNlYWwpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIHNlYWwoaXQpIHtcbiAgICByZXR1cm4gJHNlYWwgJiYgaXNPYmplY3QoaXQpID8gJHNlYWwobWV0YShpdCkpIDogaXQ7XG4gIH07XG59KTtcbiIsIi8vIDE5LjEuMy4xOSBPYmplY3Quc2V0UHJvdG90eXBlT2YoTywgcHJvdG8pXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xuJGV4cG9ydCgkZXhwb3J0LlMsICdPYmplY3QnLCB7IHNldFByb3RvdHlwZU9mOiByZXF1aXJlKCcuL19zZXQtcHJvdG8nKS5zZXQgfSk7XG4iLCIndXNlIHN0cmljdCc7XG4vLyAxOS4xLjMuNiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nKClcbnZhciBjbGFzc29mID0gcmVxdWlyZSgnLi9fY2xhc3NvZicpO1xudmFyIHRlc3QgPSB7fTtcbnRlc3RbcmVxdWlyZSgnLi9fd2tzJykoJ3RvU3RyaW5nVGFnJyldID0gJ3onO1xuaWYgKHRlc3QgKyAnJyAhPSAnW29iamVjdCB6XScpIHtcbiAgcmVxdWlyZSgnLi9fcmVkZWZpbmUnKShPYmplY3QucHJvdG90eXBlLCAndG9TdHJpbmcnLCBmdW5jdGlvbiB0b1N0cmluZygpIHtcbiAgICByZXR1cm4gJ1tvYmplY3QgJyArIGNsYXNzb2YodGhpcykgKyAnXSc7XG4gIH0sIHRydWUpO1xufVxuIiwidmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciAkcGFyc2VGbG9hdCA9IHJlcXVpcmUoJy4vX3BhcnNlLWZsb2F0Jyk7XG4vLyAxOC4yLjQgcGFyc2VGbG9hdChzdHJpbmcpXG4kZXhwb3J0KCRleHBvcnQuRyArICRleHBvcnQuRiAqIChwYXJzZUZsb2F0ICE9ICRwYXJzZUZsb2F0KSwgeyBwYXJzZUZsb2F0OiAkcGFyc2VGbG9hdCB9KTtcbiIsInZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgJHBhcnNlSW50ID0gcmVxdWlyZSgnLi9fcGFyc2UtaW50Jyk7XG4vLyAxOC4yLjUgcGFyc2VJbnQoc3RyaW5nLCByYWRpeClcbiRleHBvcnQoJGV4cG9ydC5HICsgJGV4cG9ydC5GICogKHBhcnNlSW50ICE9ICRwYXJzZUludCksIHsgcGFyc2VJbnQ6ICRwYXJzZUludCB9KTtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciBMSUJSQVJZID0gcmVxdWlyZSgnLi9fbGlicmFyeScpO1xudmFyIGdsb2JhbCA9IHJlcXVpcmUoJy4vX2dsb2JhbCcpO1xudmFyIGN0eCA9IHJlcXVpcmUoJy4vX2N0eCcpO1xudmFyIGNsYXNzb2YgPSByZXF1aXJlKCcuL19jbGFzc29mJyk7XG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi9faXMtb2JqZWN0Jyk7XG52YXIgYUZ1bmN0aW9uID0gcmVxdWlyZSgnLi9fYS1mdW5jdGlvbicpO1xudmFyIGFuSW5zdGFuY2UgPSByZXF1aXJlKCcuL19hbi1pbnN0YW5jZScpO1xudmFyIGZvck9mID0gcmVxdWlyZSgnLi9fZm9yLW9mJyk7XG52YXIgc3BlY2llc0NvbnN0cnVjdG9yID0gcmVxdWlyZSgnLi9fc3BlY2llcy1jb25zdHJ1Y3RvcicpO1xudmFyIHRhc2sgPSByZXF1aXJlKCcuL190YXNrJykuc2V0O1xudmFyIG1pY3JvdGFzayA9IHJlcXVpcmUoJy4vX21pY3JvdGFzaycpKCk7XG52YXIgbmV3UHJvbWlzZUNhcGFiaWxpdHlNb2R1bGUgPSByZXF1aXJlKCcuL19uZXctcHJvbWlzZS1jYXBhYmlsaXR5Jyk7XG52YXIgcGVyZm9ybSA9IHJlcXVpcmUoJy4vX3BlcmZvcm0nKTtcbnZhciB1c2VyQWdlbnQgPSByZXF1aXJlKCcuL191c2VyLWFnZW50Jyk7XG52YXIgcHJvbWlzZVJlc29sdmUgPSByZXF1aXJlKCcuL19wcm9taXNlLXJlc29sdmUnKTtcbnZhciBQUk9NSVNFID0gJ1Byb21pc2UnO1xudmFyIFR5cGVFcnJvciA9IGdsb2JhbC5UeXBlRXJyb3I7XG52YXIgcHJvY2VzcyA9IGdsb2JhbC5wcm9jZXNzO1xudmFyIHZlcnNpb25zID0gcHJvY2VzcyAmJiBwcm9jZXNzLnZlcnNpb25zO1xudmFyIHY4ID0gdmVyc2lvbnMgJiYgdmVyc2lvbnMudjggfHwgJyc7XG52YXIgJFByb21pc2UgPSBnbG9iYWxbUFJPTUlTRV07XG52YXIgaXNOb2RlID0gY2xhc3NvZihwcm9jZXNzKSA9PSAncHJvY2Vzcyc7XG52YXIgZW1wdHkgPSBmdW5jdGlvbiAoKSB7IC8qIGVtcHR5ICovIH07XG52YXIgSW50ZXJuYWwsIG5ld0dlbmVyaWNQcm9taXNlQ2FwYWJpbGl0eSwgT3duUHJvbWlzZUNhcGFiaWxpdHksIFdyYXBwZXI7XG52YXIgbmV3UHJvbWlzZUNhcGFiaWxpdHkgPSBuZXdHZW5lcmljUHJvbWlzZUNhcGFiaWxpdHkgPSBuZXdQcm9taXNlQ2FwYWJpbGl0eU1vZHVsZS5mO1xuXG52YXIgVVNFX05BVElWRSA9ICEhZnVuY3Rpb24gKCkge1xuICB0cnkge1xuICAgIC8vIGNvcnJlY3Qgc3ViY2xhc3Npbmcgd2l0aCBAQHNwZWNpZXMgc3VwcG9ydFxuICAgIHZhciBwcm9taXNlID0gJFByb21pc2UucmVzb2x2ZSgxKTtcbiAgICB2YXIgRmFrZVByb21pc2UgPSAocHJvbWlzZS5jb25zdHJ1Y3RvciA9IHt9KVtyZXF1aXJlKCcuL193a3MnKSgnc3BlY2llcycpXSA9IGZ1bmN0aW9uIChleGVjKSB7XG4gICAgICBleGVjKGVtcHR5LCBlbXB0eSk7XG4gICAgfTtcbiAgICAvLyB1bmhhbmRsZWQgcmVqZWN0aW9ucyB0cmFja2luZyBzdXBwb3J0LCBOb2RlSlMgUHJvbWlzZSB3aXRob3V0IGl0IGZhaWxzIEBAc3BlY2llcyB0ZXN0XG4gICAgcmV0dXJuIChpc05vZGUgfHwgdHlwZW9mIFByb21pc2VSZWplY3Rpb25FdmVudCA9PSAnZnVuY3Rpb24nKVxuICAgICAgJiYgcHJvbWlzZS50aGVuKGVtcHR5KSBpbnN0YW5jZW9mIEZha2VQcm9taXNlXG4gICAgICAvLyB2OCA2LjYgKE5vZGUgMTAgYW5kIENocm9tZSA2NikgaGF2ZSBhIGJ1ZyB3aXRoIHJlc29sdmluZyBjdXN0b20gdGhlbmFibGVzXG4gICAgICAvLyBodHRwczovL2J1Z3MuY2hyb21pdW0ub3JnL3AvY2hyb21pdW0vaXNzdWVzL2RldGFpbD9pZD04MzA1NjVcbiAgICAgIC8vIHdlIGNhbid0IGRldGVjdCBpdCBzeW5jaHJvbm91c2x5LCBzbyBqdXN0IGNoZWNrIHZlcnNpb25zXG4gICAgICAmJiB2OC5pbmRleE9mKCc2LjYnKSAhPT0gMFxuICAgICAgJiYgdXNlckFnZW50LmluZGV4T2YoJ0Nocm9tZS82NicpID09PSAtMTtcbiAgfSBjYXRjaCAoZSkgeyAvKiBlbXB0eSAqLyB9XG59KCk7XG5cbi8vIGhlbHBlcnNcbnZhciBpc1RoZW5hYmxlID0gZnVuY3Rpb24gKGl0KSB7XG4gIHZhciB0aGVuO1xuICByZXR1cm4gaXNPYmplY3QoaXQpICYmIHR5cGVvZiAodGhlbiA9IGl0LnRoZW4pID09ICdmdW5jdGlvbicgPyB0aGVuIDogZmFsc2U7XG59O1xudmFyIG5vdGlmeSA9IGZ1bmN0aW9uIChwcm9taXNlLCBpc1JlamVjdCkge1xuICBpZiAocHJvbWlzZS5fbikgcmV0dXJuO1xuICBwcm9taXNlLl9uID0gdHJ1ZTtcbiAgdmFyIGNoYWluID0gcHJvbWlzZS5fYztcbiAgbWljcm90YXNrKGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgdmFsdWUgPSBwcm9taXNlLl92O1xuICAgIHZhciBvayA9IHByb21pc2UuX3MgPT0gMTtcbiAgICB2YXIgaSA9IDA7XG4gICAgdmFyIHJ1biA9IGZ1bmN0aW9uIChyZWFjdGlvbikge1xuICAgICAgdmFyIGhhbmRsZXIgPSBvayA/IHJlYWN0aW9uLm9rIDogcmVhY3Rpb24uZmFpbDtcbiAgICAgIHZhciByZXNvbHZlID0gcmVhY3Rpb24ucmVzb2x2ZTtcbiAgICAgIHZhciByZWplY3QgPSByZWFjdGlvbi5yZWplY3Q7XG4gICAgICB2YXIgZG9tYWluID0gcmVhY3Rpb24uZG9tYWluO1xuICAgICAgdmFyIHJlc3VsdCwgdGhlbiwgZXhpdGVkO1xuICAgICAgdHJ5IHtcbiAgICAgICAgaWYgKGhhbmRsZXIpIHtcbiAgICAgICAgICBpZiAoIW9rKSB7XG4gICAgICAgICAgICBpZiAocHJvbWlzZS5faCA9PSAyKSBvbkhhbmRsZVVuaGFuZGxlZChwcm9taXNlKTtcbiAgICAgICAgICAgIHByb21pc2UuX2ggPSAxO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoaGFuZGxlciA9PT0gdHJ1ZSkgcmVzdWx0ID0gdmFsdWU7XG4gICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBpZiAoZG9tYWluKSBkb21haW4uZW50ZXIoKTtcbiAgICAgICAgICAgIHJlc3VsdCA9IGhhbmRsZXIodmFsdWUpOyAvLyBtYXkgdGhyb3dcbiAgICAgICAgICAgIGlmIChkb21haW4pIHtcbiAgICAgICAgICAgICAgZG9tYWluLmV4aXQoKTtcbiAgICAgICAgICAgICAgZXhpdGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKHJlc3VsdCA9PT0gcmVhY3Rpb24ucHJvbWlzZSkge1xuICAgICAgICAgICAgcmVqZWN0KFR5cGVFcnJvcignUHJvbWlzZS1jaGFpbiBjeWNsZScpKTtcbiAgICAgICAgICB9IGVsc2UgaWYgKHRoZW4gPSBpc1RoZW5hYmxlKHJlc3VsdCkpIHtcbiAgICAgICAgICAgIHRoZW4uY2FsbChyZXN1bHQsIHJlc29sdmUsIHJlamVjdCk7XG4gICAgICAgICAgfSBlbHNlIHJlc29sdmUocmVzdWx0KTtcbiAgICAgICAgfSBlbHNlIHJlamVjdCh2YWx1ZSk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGlmIChkb21haW4gJiYgIWV4aXRlZCkgZG9tYWluLmV4aXQoKTtcbiAgICAgICAgcmVqZWN0KGUpO1xuICAgICAgfVxuICAgIH07XG4gICAgd2hpbGUgKGNoYWluLmxlbmd0aCA+IGkpIHJ1bihjaGFpbltpKytdKTsgLy8gdmFyaWFibGUgbGVuZ3RoIC0gY2FuJ3QgdXNlIGZvckVhY2hcbiAgICBwcm9taXNlLl9jID0gW107XG4gICAgcHJvbWlzZS5fbiA9IGZhbHNlO1xuICAgIGlmIChpc1JlamVjdCAmJiAhcHJvbWlzZS5faCkgb25VbmhhbmRsZWQocHJvbWlzZSk7XG4gIH0pO1xufTtcbnZhciBvblVuaGFuZGxlZCA9IGZ1bmN0aW9uIChwcm9taXNlKSB7XG4gIHRhc2suY2FsbChnbG9iYWwsIGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgdmFsdWUgPSBwcm9taXNlLl92O1xuICAgIHZhciB1bmhhbmRsZWQgPSBpc1VuaGFuZGxlZChwcm9taXNlKTtcbiAgICB2YXIgcmVzdWx0LCBoYW5kbGVyLCBjb25zb2xlO1xuICAgIGlmICh1bmhhbmRsZWQpIHtcbiAgICAgIHJlc3VsdCA9IHBlcmZvcm0oZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAoaXNOb2RlKSB7XG4gICAgICAgICAgcHJvY2Vzcy5lbWl0KCd1bmhhbmRsZWRSZWplY3Rpb24nLCB2YWx1ZSwgcHJvbWlzZSk7XG4gICAgICAgIH0gZWxzZSBpZiAoaGFuZGxlciA9IGdsb2JhbC5vbnVuaGFuZGxlZHJlamVjdGlvbikge1xuICAgICAgICAgIGhhbmRsZXIoeyBwcm9taXNlOiBwcm9taXNlLCByZWFzb246IHZhbHVlIH0pO1xuICAgICAgICB9IGVsc2UgaWYgKChjb25zb2xlID0gZ2xvYmFsLmNvbnNvbGUpICYmIGNvbnNvbGUuZXJyb3IpIHtcbiAgICAgICAgICBjb25zb2xlLmVycm9yKCdVbmhhbmRsZWQgcHJvbWlzZSByZWplY3Rpb24nLCB2YWx1ZSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgLy8gQnJvd3NlcnMgc2hvdWxkIG5vdCB0cmlnZ2VyIGByZWplY3Rpb25IYW5kbGVkYCBldmVudCBpZiBpdCB3YXMgaGFuZGxlZCBoZXJlLCBOb2RlSlMgLSBzaG91bGRcbiAgICAgIHByb21pc2UuX2ggPSBpc05vZGUgfHwgaXNVbmhhbmRsZWQocHJvbWlzZSkgPyAyIDogMTtcbiAgICB9IHByb21pc2UuX2EgPSB1bmRlZmluZWQ7XG4gICAgaWYgKHVuaGFuZGxlZCAmJiByZXN1bHQuZSkgdGhyb3cgcmVzdWx0LnY7XG4gIH0pO1xufTtcbnZhciBpc1VuaGFuZGxlZCA9IGZ1bmN0aW9uIChwcm9taXNlKSB7XG4gIHJldHVybiBwcm9taXNlLl9oICE9PSAxICYmIChwcm9taXNlLl9hIHx8IHByb21pc2UuX2MpLmxlbmd0aCA9PT0gMDtcbn07XG52YXIgb25IYW5kbGVVbmhhbmRsZWQgPSBmdW5jdGlvbiAocHJvbWlzZSkge1xuICB0YXNrLmNhbGwoZ2xvYmFsLCBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIGhhbmRsZXI7XG4gICAgaWYgKGlzTm9kZSkge1xuICAgICAgcHJvY2Vzcy5lbWl0KCdyZWplY3Rpb25IYW5kbGVkJywgcHJvbWlzZSk7XG4gICAgfSBlbHNlIGlmIChoYW5kbGVyID0gZ2xvYmFsLm9ucmVqZWN0aW9uaGFuZGxlZCkge1xuICAgICAgaGFuZGxlcih7IHByb21pc2U6IHByb21pc2UsIHJlYXNvbjogcHJvbWlzZS5fdiB9KTtcbiAgICB9XG4gIH0pO1xufTtcbnZhciAkcmVqZWN0ID0gZnVuY3Rpb24gKHZhbHVlKSB7XG4gIHZhciBwcm9taXNlID0gdGhpcztcbiAgaWYgKHByb21pc2UuX2QpIHJldHVybjtcbiAgcHJvbWlzZS5fZCA9IHRydWU7XG4gIHByb21pc2UgPSBwcm9taXNlLl93IHx8IHByb21pc2U7IC8vIHVud3JhcFxuICBwcm9taXNlLl92ID0gdmFsdWU7XG4gIHByb21pc2UuX3MgPSAyO1xuICBpZiAoIXByb21pc2UuX2EpIHByb21pc2UuX2EgPSBwcm9taXNlLl9jLnNsaWNlKCk7XG4gIG5vdGlmeShwcm9taXNlLCB0cnVlKTtcbn07XG52YXIgJHJlc29sdmUgPSBmdW5jdGlvbiAodmFsdWUpIHtcbiAgdmFyIHByb21pc2UgPSB0aGlzO1xuICB2YXIgdGhlbjtcbiAgaWYgKHByb21pc2UuX2QpIHJldHVybjtcbiAgcHJvbWlzZS5fZCA9IHRydWU7XG4gIHByb21pc2UgPSBwcm9taXNlLl93IHx8IHByb21pc2U7IC8vIHVud3JhcFxuICB0cnkge1xuICAgIGlmIChwcm9taXNlID09PSB2YWx1ZSkgdGhyb3cgVHlwZUVycm9yKFwiUHJvbWlzZSBjYW4ndCBiZSByZXNvbHZlZCBpdHNlbGZcIik7XG4gICAgaWYgKHRoZW4gPSBpc1RoZW5hYmxlKHZhbHVlKSkge1xuICAgICAgbWljcm90YXNrKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHdyYXBwZXIgPSB7IF93OiBwcm9taXNlLCBfZDogZmFsc2UgfTsgLy8gd3JhcFxuICAgICAgICB0cnkge1xuICAgICAgICAgIHRoZW4uY2FsbCh2YWx1ZSwgY3R4KCRyZXNvbHZlLCB3cmFwcGVyLCAxKSwgY3R4KCRyZWplY3QsIHdyYXBwZXIsIDEpKTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICRyZWplY3QuY2FsbCh3cmFwcGVyLCBlKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHByb21pc2UuX3YgPSB2YWx1ZTtcbiAgICAgIHByb21pc2UuX3MgPSAxO1xuICAgICAgbm90aWZ5KHByb21pc2UsIGZhbHNlKTtcbiAgICB9XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICAkcmVqZWN0LmNhbGwoeyBfdzogcHJvbWlzZSwgX2Q6IGZhbHNlIH0sIGUpOyAvLyB3cmFwXG4gIH1cbn07XG5cbi8vIGNvbnN0cnVjdG9yIHBvbHlmaWxsXG5pZiAoIVVTRV9OQVRJVkUpIHtcbiAgLy8gMjUuNC4zLjEgUHJvbWlzZShleGVjdXRvcilcbiAgJFByb21pc2UgPSBmdW5jdGlvbiBQcm9taXNlKGV4ZWN1dG9yKSB7XG4gICAgYW5JbnN0YW5jZSh0aGlzLCAkUHJvbWlzZSwgUFJPTUlTRSwgJ19oJyk7XG4gICAgYUZ1bmN0aW9uKGV4ZWN1dG9yKTtcbiAgICBJbnRlcm5hbC5jYWxsKHRoaXMpO1xuICAgIHRyeSB7XG4gICAgICBleGVjdXRvcihjdHgoJHJlc29sdmUsIHRoaXMsIDEpLCBjdHgoJHJlamVjdCwgdGhpcywgMSkpO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgJHJlamVjdC5jYWxsKHRoaXMsIGVycik7XG4gICAgfVxuICB9O1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdW51c2VkLXZhcnNcbiAgSW50ZXJuYWwgPSBmdW5jdGlvbiBQcm9taXNlKGV4ZWN1dG9yKSB7XG4gICAgdGhpcy5fYyA9IFtdOyAgICAgICAgICAgICAvLyA8LSBhd2FpdGluZyByZWFjdGlvbnNcbiAgICB0aGlzLl9hID0gdW5kZWZpbmVkOyAgICAgIC8vIDwtIGNoZWNrZWQgaW4gaXNVbmhhbmRsZWQgcmVhY3Rpb25zXG4gICAgdGhpcy5fcyA9IDA7ICAgICAgICAgICAgICAvLyA8LSBzdGF0ZVxuICAgIHRoaXMuX2QgPSBmYWxzZTsgICAgICAgICAgLy8gPC0gZG9uZVxuICAgIHRoaXMuX3YgPSB1bmRlZmluZWQ7ICAgICAgLy8gPC0gdmFsdWVcbiAgICB0aGlzLl9oID0gMDsgICAgICAgICAgICAgIC8vIDwtIHJlamVjdGlvbiBzdGF0ZSwgMCAtIGRlZmF1bHQsIDEgLSBoYW5kbGVkLCAyIC0gdW5oYW5kbGVkXG4gICAgdGhpcy5fbiA9IGZhbHNlOyAgICAgICAgICAvLyA8LSBub3RpZnlcbiAgfTtcbiAgSW50ZXJuYWwucHJvdG90eXBlID0gcmVxdWlyZSgnLi9fcmVkZWZpbmUtYWxsJykoJFByb21pc2UucHJvdG90eXBlLCB7XG4gICAgLy8gMjUuNC41LjMgUHJvbWlzZS5wcm90b3R5cGUudGhlbihvbkZ1bGZpbGxlZCwgb25SZWplY3RlZClcbiAgICB0aGVuOiBmdW5jdGlvbiB0aGVuKG9uRnVsZmlsbGVkLCBvblJlamVjdGVkKSB7XG4gICAgICB2YXIgcmVhY3Rpb24gPSBuZXdQcm9taXNlQ2FwYWJpbGl0eShzcGVjaWVzQ29uc3RydWN0b3IodGhpcywgJFByb21pc2UpKTtcbiAgICAgIHJlYWN0aW9uLm9rID0gdHlwZW9mIG9uRnVsZmlsbGVkID09ICdmdW5jdGlvbicgPyBvbkZ1bGZpbGxlZCA6IHRydWU7XG4gICAgICByZWFjdGlvbi5mYWlsID0gdHlwZW9mIG9uUmVqZWN0ZWQgPT0gJ2Z1bmN0aW9uJyAmJiBvblJlamVjdGVkO1xuICAgICAgcmVhY3Rpb24uZG9tYWluID0gaXNOb2RlID8gcHJvY2Vzcy5kb21haW4gOiB1bmRlZmluZWQ7XG4gICAgICB0aGlzLl9jLnB1c2gocmVhY3Rpb24pO1xuICAgICAgaWYgKHRoaXMuX2EpIHRoaXMuX2EucHVzaChyZWFjdGlvbik7XG4gICAgICBpZiAodGhpcy5fcykgbm90aWZ5KHRoaXMsIGZhbHNlKTtcbiAgICAgIHJldHVybiByZWFjdGlvbi5wcm9taXNlO1xuICAgIH0sXG4gICAgLy8gMjUuNC41LjEgUHJvbWlzZS5wcm90b3R5cGUuY2F0Y2gob25SZWplY3RlZClcbiAgICAnY2F0Y2gnOiBmdW5jdGlvbiAob25SZWplY3RlZCkge1xuICAgICAgcmV0dXJuIHRoaXMudGhlbih1bmRlZmluZWQsIG9uUmVqZWN0ZWQpO1xuICAgIH1cbiAgfSk7XG4gIE93blByb21pc2VDYXBhYmlsaXR5ID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciBwcm9taXNlID0gbmV3IEludGVybmFsKCk7XG4gICAgdGhpcy5wcm9taXNlID0gcHJvbWlzZTtcbiAgICB0aGlzLnJlc29sdmUgPSBjdHgoJHJlc29sdmUsIHByb21pc2UsIDEpO1xuICAgIHRoaXMucmVqZWN0ID0gY3R4KCRyZWplY3QsIHByb21pc2UsIDEpO1xuICB9O1xuICBuZXdQcm9taXNlQ2FwYWJpbGl0eU1vZHVsZS5mID0gbmV3UHJvbWlzZUNhcGFiaWxpdHkgPSBmdW5jdGlvbiAoQykge1xuICAgIHJldHVybiBDID09PSAkUHJvbWlzZSB8fCBDID09PSBXcmFwcGVyXG4gICAgICA/IG5ldyBPd25Qcm9taXNlQ2FwYWJpbGl0eShDKVxuICAgICAgOiBuZXdHZW5lcmljUHJvbWlzZUNhcGFiaWxpdHkoQyk7XG4gIH07XG59XG5cbiRleHBvcnQoJGV4cG9ydC5HICsgJGV4cG9ydC5XICsgJGV4cG9ydC5GICogIVVTRV9OQVRJVkUsIHsgUHJvbWlzZTogJFByb21pc2UgfSk7XG5yZXF1aXJlKCcuL19zZXQtdG8tc3RyaW5nLXRhZycpKCRQcm9taXNlLCBQUk9NSVNFKTtcbnJlcXVpcmUoJy4vX3NldC1zcGVjaWVzJykoUFJPTUlTRSk7XG5XcmFwcGVyID0gcmVxdWlyZSgnLi9fY29yZScpW1BST01JU0VdO1xuXG4vLyBzdGF0aWNzXG4kZXhwb3J0KCRleHBvcnQuUyArICRleHBvcnQuRiAqICFVU0VfTkFUSVZFLCBQUk9NSVNFLCB7XG4gIC8vIDI1LjQuNC41IFByb21pc2UucmVqZWN0KHIpXG4gIHJlamVjdDogZnVuY3Rpb24gcmVqZWN0KHIpIHtcbiAgICB2YXIgY2FwYWJpbGl0eSA9IG5ld1Byb21pc2VDYXBhYmlsaXR5KHRoaXMpO1xuICAgIHZhciAkJHJlamVjdCA9IGNhcGFiaWxpdHkucmVqZWN0O1xuICAgICQkcmVqZWN0KHIpO1xuICAgIHJldHVybiBjYXBhYmlsaXR5LnByb21pc2U7XG4gIH1cbn0pO1xuJGV4cG9ydCgkZXhwb3J0LlMgKyAkZXhwb3J0LkYgKiAoTElCUkFSWSB8fCAhVVNFX05BVElWRSksIFBST01JU0UsIHtcbiAgLy8gMjUuNC40LjYgUHJvbWlzZS5yZXNvbHZlKHgpXG4gIHJlc29sdmU6IGZ1bmN0aW9uIHJlc29sdmUoeCkge1xuICAgIHJldHVybiBwcm9taXNlUmVzb2x2ZShMSUJSQVJZICYmIHRoaXMgPT09IFdyYXBwZXIgPyAkUHJvbWlzZSA6IHRoaXMsIHgpO1xuICB9XG59KTtcbiRleHBvcnQoJGV4cG9ydC5TICsgJGV4cG9ydC5GICogIShVU0VfTkFUSVZFICYmIHJlcXVpcmUoJy4vX2l0ZXItZGV0ZWN0JykoZnVuY3Rpb24gKGl0ZXIpIHtcbiAgJFByb21pc2UuYWxsKGl0ZXIpWydjYXRjaCddKGVtcHR5KTtcbn0pKSwgUFJPTUlTRSwge1xuICAvLyAyNS40LjQuMSBQcm9taXNlLmFsbChpdGVyYWJsZSlcbiAgYWxsOiBmdW5jdGlvbiBhbGwoaXRlcmFibGUpIHtcbiAgICB2YXIgQyA9IHRoaXM7XG4gICAgdmFyIGNhcGFiaWxpdHkgPSBuZXdQcm9taXNlQ2FwYWJpbGl0eShDKTtcbiAgICB2YXIgcmVzb2x2ZSA9IGNhcGFiaWxpdHkucmVzb2x2ZTtcbiAgICB2YXIgcmVqZWN0ID0gY2FwYWJpbGl0eS5yZWplY3Q7XG4gICAgdmFyIHJlc3VsdCA9IHBlcmZvcm0oZnVuY3Rpb24gKCkge1xuICAgICAgdmFyIHZhbHVlcyA9IFtdO1xuICAgICAgdmFyIGluZGV4ID0gMDtcbiAgICAgIHZhciByZW1haW5pbmcgPSAxO1xuICAgICAgZm9yT2YoaXRlcmFibGUsIGZhbHNlLCBmdW5jdGlvbiAocHJvbWlzZSkge1xuICAgICAgICB2YXIgJGluZGV4ID0gaW5kZXgrKztcbiAgICAgICAgdmFyIGFscmVhZHlDYWxsZWQgPSBmYWxzZTtcbiAgICAgICAgdmFsdWVzLnB1c2godW5kZWZpbmVkKTtcbiAgICAgICAgcmVtYWluaW5nKys7XG4gICAgICAgIEMucmVzb2x2ZShwcm9taXNlKS50aGVuKGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICAgIGlmIChhbHJlYWR5Q2FsbGVkKSByZXR1cm47XG4gICAgICAgICAgYWxyZWFkeUNhbGxlZCA9IHRydWU7XG4gICAgICAgICAgdmFsdWVzWyRpbmRleF0gPSB2YWx1ZTtcbiAgICAgICAgICAtLXJlbWFpbmluZyB8fCByZXNvbHZlKHZhbHVlcyk7XG4gICAgICAgIH0sIHJlamVjdCk7XG4gICAgICB9KTtcbiAgICAgIC0tcmVtYWluaW5nIHx8IHJlc29sdmUodmFsdWVzKTtcbiAgICB9KTtcbiAgICBpZiAocmVzdWx0LmUpIHJlamVjdChyZXN1bHQudik7XG4gICAgcmV0dXJuIGNhcGFiaWxpdHkucHJvbWlzZTtcbiAgfSxcbiAgLy8gMjUuNC40LjQgUHJvbWlzZS5yYWNlKGl0ZXJhYmxlKVxuICByYWNlOiBmdW5jdGlvbiByYWNlKGl0ZXJhYmxlKSB7XG4gICAgdmFyIEMgPSB0aGlzO1xuICAgIHZhciBjYXBhYmlsaXR5ID0gbmV3UHJvbWlzZUNhcGFiaWxpdHkoQyk7XG4gICAgdmFyIHJlamVjdCA9IGNhcGFiaWxpdHkucmVqZWN0O1xuICAgIHZhciByZXN1bHQgPSBwZXJmb3JtKGZ1bmN0aW9uICgpIHtcbiAgICAgIGZvck9mKGl0ZXJhYmxlLCBmYWxzZSwgZnVuY3Rpb24gKHByb21pc2UpIHtcbiAgICAgICAgQy5yZXNvbHZlKHByb21pc2UpLnRoZW4oY2FwYWJpbGl0eS5yZXNvbHZlLCByZWplY3QpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gICAgaWYgKHJlc3VsdC5lKSByZWplY3QocmVzdWx0LnYpO1xuICAgIHJldHVybiBjYXBhYmlsaXR5LnByb21pc2U7XG4gIH1cbn0pO1xuIiwiLy8gMjYuMS4xIFJlZmxlY3QuYXBwbHkodGFyZ2V0LCB0aGlzQXJndW1lbnQsIGFyZ3VtZW50c0xpc3QpXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyIGFGdW5jdGlvbiA9IHJlcXVpcmUoJy4vX2EtZnVuY3Rpb24nKTtcbnZhciBhbk9iamVjdCA9IHJlcXVpcmUoJy4vX2FuLW9iamVjdCcpO1xudmFyIHJBcHBseSA9IChyZXF1aXJlKCcuL19nbG9iYWwnKS5SZWZsZWN0IHx8IHt9KS5hcHBseTtcbnZhciBmQXBwbHkgPSBGdW5jdGlvbi5hcHBseTtcbi8vIE1TIEVkZ2UgYXJndW1lbnRzTGlzdCBhcmd1bWVudCBpcyBvcHRpb25hbFxuJGV4cG9ydCgkZXhwb3J0LlMgKyAkZXhwb3J0LkYgKiAhcmVxdWlyZSgnLi9fZmFpbHMnKShmdW5jdGlvbiAoKSB7XG4gIHJBcHBseShmdW5jdGlvbiAoKSB7IC8qIGVtcHR5ICovIH0pO1xufSksICdSZWZsZWN0Jywge1xuICBhcHBseTogZnVuY3Rpb24gYXBwbHkodGFyZ2V0LCB0aGlzQXJndW1lbnQsIGFyZ3VtZW50c0xpc3QpIHtcbiAgICB2YXIgVCA9IGFGdW5jdGlvbih0YXJnZXQpO1xuICAgIHZhciBMID0gYW5PYmplY3QoYXJndW1lbnRzTGlzdCk7XG4gICAgcmV0dXJuIHJBcHBseSA/IHJBcHBseShULCB0aGlzQXJndW1lbnQsIEwpIDogZkFwcGx5LmNhbGwoVCwgdGhpc0FyZ3VtZW50LCBMKTtcbiAgfVxufSk7XG4iLCIvLyAyNi4xLjIgUmVmbGVjdC5jb25zdHJ1Y3QodGFyZ2V0LCBhcmd1bWVudHNMaXN0IFssIG5ld1RhcmdldF0pXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyIGNyZWF0ZSA9IHJlcXVpcmUoJy4vX29iamVjdC1jcmVhdGUnKTtcbnZhciBhRnVuY3Rpb24gPSByZXF1aXJlKCcuL19hLWZ1bmN0aW9uJyk7XG52YXIgYW5PYmplY3QgPSByZXF1aXJlKCcuL19hbi1vYmplY3QnKTtcbnZhciBpc09iamVjdCA9IHJlcXVpcmUoJy4vX2lzLW9iamVjdCcpO1xudmFyIGZhaWxzID0gcmVxdWlyZSgnLi9fZmFpbHMnKTtcbnZhciBiaW5kID0gcmVxdWlyZSgnLi9fYmluZCcpO1xudmFyIHJDb25zdHJ1Y3QgPSAocmVxdWlyZSgnLi9fZ2xvYmFsJykuUmVmbGVjdCB8fCB7fSkuY29uc3RydWN0O1xuXG4vLyBNUyBFZGdlIHN1cHBvcnRzIG9ubHkgMiBhcmd1bWVudHMgYW5kIGFyZ3VtZW50c0xpc3QgYXJndW1lbnQgaXMgb3B0aW9uYWxcbi8vIEZGIE5pZ2h0bHkgc2V0cyB0aGlyZCBhcmd1bWVudCBhcyBgbmV3LnRhcmdldGAsIGJ1dCBkb2VzIG5vdCBjcmVhdGUgYHRoaXNgIGZyb20gaXRcbnZhciBORVdfVEFSR0VUX0JVRyA9IGZhaWxzKGZ1bmN0aW9uICgpIHtcbiAgZnVuY3Rpb24gRigpIHsgLyogZW1wdHkgKi8gfVxuICByZXR1cm4gIShyQ29uc3RydWN0KGZ1bmN0aW9uICgpIHsgLyogZW1wdHkgKi8gfSwgW10sIEYpIGluc3RhbmNlb2YgRik7XG59KTtcbnZhciBBUkdTX0JVRyA9ICFmYWlscyhmdW5jdGlvbiAoKSB7XG4gIHJDb25zdHJ1Y3QoZnVuY3Rpb24gKCkgeyAvKiBlbXB0eSAqLyB9KTtcbn0pO1xuXG4kZXhwb3J0KCRleHBvcnQuUyArICRleHBvcnQuRiAqIChORVdfVEFSR0VUX0JVRyB8fCBBUkdTX0JVRyksICdSZWZsZWN0Jywge1xuICBjb25zdHJ1Y3Q6IGZ1bmN0aW9uIGNvbnN0cnVjdChUYXJnZXQsIGFyZ3MgLyogLCBuZXdUYXJnZXQgKi8pIHtcbiAgICBhRnVuY3Rpb24oVGFyZ2V0KTtcbiAgICBhbk9iamVjdChhcmdzKTtcbiAgICB2YXIgbmV3VGFyZ2V0ID0gYXJndW1lbnRzLmxlbmd0aCA8IDMgPyBUYXJnZXQgOiBhRnVuY3Rpb24oYXJndW1lbnRzWzJdKTtcbiAgICBpZiAoQVJHU19CVUcgJiYgIU5FV19UQVJHRVRfQlVHKSByZXR1cm4gckNvbnN0cnVjdChUYXJnZXQsIGFyZ3MsIG5ld1RhcmdldCk7XG4gICAgaWYgKFRhcmdldCA9PSBuZXdUYXJnZXQpIHtcbiAgICAgIC8vIHcvbyBhbHRlcmVkIG5ld1RhcmdldCwgb3B0aW1pemF0aW9uIGZvciAwLTQgYXJndW1lbnRzXG4gICAgICBzd2l0Y2ggKGFyZ3MubGVuZ3RoKSB7XG4gICAgICAgIGNhc2UgMDogcmV0dXJuIG5ldyBUYXJnZXQoKTtcbiAgICAgICAgY2FzZSAxOiByZXR1cm4gbmV3IFRhcmdldChhcmdzWzBdKTtcbiAgICAgICAgY2FzZSAyOiByZXR1cm4gbmV3IFRhcmdldChhcmdzWzBdLCBhcmdzWzFdKTtcbiAgICAgICAgY2FzZSAzOiByZXR1cm4gbmV3IFRhcmdldChhcmdzWzBdLCBhcmdzWzFdLCBhcmdzWzJdKTtcbiAgICAgICAgY2FzZSA0OiByZXR1cm4gbmV3IFRhcmdldChhcmdzWzBdLCBhcmdzWzFdLCBhcmdzWzJdLCBhcmdzWzNdKTtcbiAgICAgIH1cbiAgICAgIC8vIHcvbyBhbHRlcmVkIG5ld1RhcmdldCwgbG90IG9mIGFyZ3VtZW50cyBjYXNlXG4gICAgICB2YXIgJGFyZ3MgPSBbbnVsbF07XG4gICAgICAkYXJncy5wdXNoLmFwcGx5KCRhcmdzLCBhcmdzKTtcbiAgICAgIHJldHVybiBuZXcgKGJpbmQuYXBwbHkoVGFyZ2V0LCAkYXJncykpKCk7XG4gICAgfVxuICAgIC8vIHdpdGggYWx0ZXJlZCBuZXdUYXJnZXQsIG5vdCBzdXBwb3J0IGJ1aWx0LWluIGNvbnN0cnVjdG9yc1xuICAgIHZhciBwcm90byA9IG5ld1RhcmdldC5wcm90b3R5cGU7XG4gICAgdmFyIGluc3RhbmNlID0gY3JlYXRlKGlzT2JqZWN0KHByb3RvKSA/IHByb3RvIDogT2JqZWN0LnByb3RvdHlwZSk7XG4gICAgdmFyIHJlc3VsdCA9IEZ1bmN0aW9uLmFwcGx5LmNhbGwoVGFyZ2V0LCBpbnN0YW5jZSwgYXJncyk7XG4gICAgcmV0dXJuIGlzT2JqZWN0KHJlc3VsdCkgPyByZXN1bHQgOiBpbnN0YW5jZTtcbiAgfVxufSk7XG4iLCIvLyAyNi4xLjMgUmVmbGVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIHByb3BlcnR5S2V5LCBhdHRyaWJ1dGVzKVxudmFyIGRQID0gcmVxdWlyZSgnLi9fb2JqZWN0LWRwJyk7XG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyIGFuT2JqZWN0ID0gcmVxdWlyZSgnLi9fYW4tb2JqZWN0Jyk7XG52YXIgdG9QcmltaXRpdmUgPSByZXF1aXJlKCcuL190by1wcmltaXRpdmUnKTtcblxuLy8gTVMgRWRnZSBoYXMgYnJva2VuIFJlZmxlY3QuZGVmaW5lUHJvcGVydHkgLSB0aHJvd2luZyBpbnN0ZWFkIG9mIHJldHVybmluZyBmYWxzZVxuJGV4cG9ydCgkZXhwb3J0LlMgKyAkZXhwb3J0LkYgKiByZXF1aXJlKCcuL19mYWlscycpKGZ1bmN0aW9uICgpIHtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXVuZGVmXG4gIFJlZmxlY3QuZGVmaW5lUHJvcGVydHkoZFAuZih7fSwgMSwgeyB2YWx1ZTogMSB9KSwgMSwgeyB2YWx1ZTogMiB9KTtcbn0pLCAnUmVmbGVjdCcsIHtcbiAgZGVmaW5lUHJvcGVydHk6IGZ1bmN0aW9uIGRlZmluZVByb3BlcnR5KHRhcmdldCwgcHJvcGVydHlLZXksIGF0dHJpYnV0ZXMpIHtcbiAgICBhbk9iamVjdCh0YXJnZXQpO1xuICAgIHByb3BlcnR5S2V5ID0gdG9QcmltaXRpdmUocHJvcGVydHlLZXksIHRydWUpO1xuICAgIGFuT2JqZWN0KGF0dHJpYnV0ZXMpO1xuICAgIHRyeSB7XG4gICAgICBkUC5mKHRhcmdldCwgcHJvcGVydHlLZXksIGF0dHJpYnV0ZXMpO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxufSk7XG4iLCIvLyAyNi4xLjQgUmVmbGVjdC5kZWxldGVQcm9wZXJ0eSh0YXJnZXQsIHByb3BlcnR5S2V5KVxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciBnT1BEID0gcmVxdWlyZSgnLi9fb2JqZWN0LWdvcGQnKS5mO1xudmFyIGFuT2JqZWN0ID0gcmVxdWlyZSgnLi9fYW4tb2JqZWN0Jyk7XG5cbiRleHBvcnQoJGV4cG9ydC5TLCAnUmVmbGVjdCcsIHtcbiAgZGVsZXRlUHJvcGVydHk6IGZ1bmN0aW9uIGRlbGV0ZVByb3BlcnR5KHRhcmdldCwgcHJvcGVydHlLZXkpIHtcbiAgICB2YXIgZGVzYyA9IGdPUEQoYW5PYmplY3QodGFyZ2V0KSwgcHJvcGVydHlLZXkpO1xuICAgIHJldHVybiBkZXNjICYmICFkZXNjLmNvbmZpZ3VyYWJsZSA/IGZhbHNlIDogZGVsZXRlIHRhcmdldFtwcm9wZXJ0eUtleV07XG4gIH1cbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuLy8gMjYuMS41IFJlZmxlY3QuZW51bWVyYXRlKHRhcmdldClcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgYW5PYmplY3QgPSByZXF1aXJlKCcuL19hbi1vYmplY3QnKTtcbnZhciBFbnVtZXJhdGUgPSBmdW5jdGlvbiAoaXRlcmF0ZWQpIHtcbiAgdGhpcy5fdCA9IGFuT2JqZWN0KGl0ZXJhdGVkKTsgLy8gdGFyZ2V0XG4gIHRoaXMuX2kgPSAwOyAgICAgICAgICAgICAgICAgIC8vIG5leHQgaW5kZXhcbiAgdmFyIGtleXMgPSB0aGlzLl9rID0gW107ICAgICAgLy8ga2V5c1xuICB2YXIga2V5O1xuICBmb3IgKGtleSBpbiBpdGVyYXRlZCkga2V5cy5wdXNoKGtleSk7XG59O1xucmVxdWlyZSgnLi9faXRlci1jcmVhdGUnKShFbnVtZXJhdGUsICdPYmplY3QnLCBmdW5jdGlvbiAoKSB7XG4gIHZhciB0aGF0ID0gdGhpcztcbiAgdmFyIGtleXMgPSB0aGF0Ll9rO1xuICB2YXIga2V5O1xuICBkbyB7XG4gICAgaWYgKHRoYXQuX2kgPj0ga2V5cy5sZW5ndGgpIHJldHVybiB7IHZhbHVlOiB1bmRlZmluZWQsIGRvbmU6IHRydWUgfTtcbiAgfSB3aGlsZSAoISgoa2V5ID0ga2V5c1t0aGF0Ll9pKytdKSBpbiB0aGF0Ll90KSk7XG4gIHJldHVybiB7IHZhbHVlOiBrZXksIGRvbmU6IGZhbHNlIH07XG59KTtcblxuJGV4cG9ydCgkZXhwb3J0LlMsICdSZWZsZWN0Jywge1xuICBlbnVtZXJhdGU6IGZ1bmN0aW9uIGVudW1lcmF0ZSh0YXJnZXQpIHtcbiAgICByZXR1cm4gbmV3IEVudW1lcmF0ZSh0YXJnZXQpO1xuICB9XG59KTtcbiIsIi8vIDI2LjEuNyBSZWZsZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcih0YXJnZXQsIHByb3BlcnR5S2V5KVxudmFyIGdPUEQgPSByZXF1aXJlKCcuL19vYmplY3QtZ29wZCcpO1xudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciBhbk9iamVjdCA9IHJlcXVpcmUoJy4vX2FuLW9iamVjdCcpO1xuXG4kZXhwb3J0KCRleHBvcnQuUywgJ1JlZmxlY3QnLCB7XG4gIGdldE93blByb3BlcnR5RGVzY3JpcHRvcjogZnVuY3Rpb24gZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHRhcmdldCwgcHJvcGVydHlLZXkpIHtcbiAgICByZXR1cm4gZ09QRC5mKGFuT2JqZWN0KHRhcmdldCksIHByb3BlcnR5S2V5KTtcbiAgfVxufSk7XG4iLCIvLyAyNi4xLjggUmVmbGVjdC5nZXRQcm90b3R5cGVPZih0YXJnZXQpXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyIGdldFByb3RvID0gcmVxdWlyZSgnLi9fb2JqZWN0LWdwbycpO1xudmFyIGFuT2JqZWN0ID0gcmVxdWlyZSgnLi9fYW4tb2JqZWN0Jyk7XG5cbiRleHBvcnQoJGV4cG9ydC5TLCAnUmVmbGVjdCcsIHtcbiAgZ2V0UHJvdG90eXBlT2Y6IGZ1bmN0aW9uIGdldFByb3RvdHlwZU9mKHRhcmdldCkge1xuICAgIHJldHVybiBnZXRQcm90byhhbk9iamVjdCh0YXJnZXQpKTtcbiAgfVxufSk7XG4iLCIvLyAyNi4xLjYgUmVmbGVjdC5nZXQodGFyZ2V0LCBwcm9wZXJ0eUtleSBbLCByZWNlaXZlcl0pXG52YXIgZ09QRCA9IHJlcXVpcmUoJy4vX29iamVjdC1nb3BkJyk7XG52YXIgZ2V0UHJvdG90eXBlT2YgPSByZXF1aXJlKCcuL19vYmplY3QtZ3BvJyk7XG52YXIgaGFzID0gcmVxdWlyZSgnLi9faGFzJyk7XG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi9faXMtb2JqZWN0Jyk7XG52YXIgYW5PYmplY3QgPSByZXF1aXJlKCcuL19hbi1vYmplY3QnKTtcblxuZnVuY3Rpb24gZ2V0KHRhcmdldCwgcHJvcGVydHlLZXkgLyogLCByZWNlaXZlciAqLykge1xuICB2YXIgcmVjZWl2ZXIgPSBhcmd1bWVudHMubGVuZ3RoIDwgMyA/IHRhcmdldCA6IGFyZ3VtZW50c1syXTtcbiAgdmFyIGRlc2MsIHByb3RvO1xuICBpZiAoYW5PYmplY3QodGFyZ2V0KSA9PT0gcmVjZWl2ZXIpIHJldHVybiB0YXJnZXRbcHJvcGVydHlLZXldO1xuICBpZiAoZGVzYyA9IGdPUEQuZih0YXJnZXQsIHByb3BlcnR5S2V5KSkgcmV0dXJuIGhhcyhkZXNjLCAndmFsdWUnKVxuICAgID8gZGVzYy52YWx1ZVxuICAgIDogZGVzYy5nZXQgIT09IHVuZGVmaW5lZFxuICAgICAgPyBkZXNjLmdldC5jYWxsKHJlY2VpdmVyKVxuICAgICAgOiB1bmRlZmluZWQ7XG4gIGlmIChpc09iamVjdChwcm90byA9IGdldFByb3RvdHlwZU9mKHRhcmdldCkpKSByZXR1cm4gZ2V0KHByb3RvLCBwcm9wZXJ0eUtleSwgcmVjZWl2ZXIpO1xufVxuXG4kZXhwb3J0KCRleHBvcnQuUywgJ1JlZmxlY3QnLCB7IGdldDogZ2V0IH0pO1xuIiwiLy8gMjYuMS45IFJlZmxlY3QuaGFzKHRhcmdldCwgcHJvcGVydHlLZXkpXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xuXG4kZXhwb3J0KCRleHBvcnQuUywgJ1JlZmxlY3QnLCB7XG4gIGhhczogZnVuY3Rpb24gaGFzKHRhcmdldCwgcHJvcGVydHlLZXkpIHtcbiAgICByZXR1cm4gcHJvcGVydHlLZXkgaW4gdGFyZ2V0O1xuICB9XG59KTtcbiIsIi8vIDI2LjEuMTAgUmVmbGVjdC5pc0V4dGVuc2libGUodGFyZ2V0KVxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciBhbk9iamVjdCA9IHJlcXVpcmUoJy4vX2FuLW9iamVjdCcpO1xudmFyICRpc0V4dGVuc2libGUgPSBPYmplY3QuaXNFeHRlbnNpYmxlO1xuXG4kZXhwb3J0KCRleHBvcnQuUywgJ1JlZmxlY3QnLCB7XG4gIGlzRXh0ZW5zaWJsZTogZnVuY3Rpb24gaXNFeHRlbnNpYmxlKHRhcmdldCkge1xuICAgIGFuT2JqZWN0KHRhcmdldCk7XG4gICAgcmV0dXJuICRpc0V4dGVuc2libGUgPyAkaXNFeHRlbnNpYmxlKHRhcmdldCkgOiB0cnVlO1xuICB9XG59KTtcbiIsIi8vIDI2LjEuMTEgUmVmbGVjdC5vd25LZXlzKHRhcmdldClcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG5cbiRleHBvcnQoJGV4cG9ydC5TLCAnUmVmbGVjdCcsIHsgb3duS2V5czogcmVxdWlyZSgnLi9fb3duLWtleXMnKSB9KTtcbiIsIi8vIDI2LjEuMTIgUmVmbGVjdC5wcmV2ZW50RXh0ZW5zaW9ucyh0YXJnZXQpXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyIGFuT2JqZWN0ID0gcmVxdWlyZSgnLi9fYW4tb2JqZWN0Jyk7XG52YXIgJHByZXZlbnRFeHRlbnNpb25zID0gT2JqZWN0LnByZXZlbnRFeHRlbnNpb25zO1xuXG4kZXhwb3J0KCRleHBvcnQuUywgJ1JlZmxlY3QnLCB7XG4gIHByZXZlbnRFeHRlbnNpb25zOiBmdW5jdGlvbiBwcmV2ZW50RXh0ZW5zaW9ucyh0YXJnZXQpIHtcbiAgICBhbk9iamVjdCh0YXJnZXQpO1xuICAgIHRyeSB7XG4gICAgICBpZiAoJHByZXZlbnRFeHRlbnNpb25zKSAkcHJldmVudEV4dGVuc2lvbnModGFyZ2V0KTtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cbn0pO1xuIiwiLy8gMjYuMS4xNCBSZWZsZWN0LnNldFByb3RvdHlwZU9mKHRhcmdldCwgcHJvdG8pXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyIHNldFByb3RvID0gcmVxdWlyZSgnLi9fc2V0LXByb3RvJyk7XG5cbmlmIChzZXRQcm90bykgJGV4cG9ydCgkZXhwb3J0LlMsICdSZWZsZWN0Jywge1xuICBzZXRQcm90b3R5cGVPZjogZnVuY3Rpb24gc2V0UHJvdG90eXBlT2YodGFyZ2V0LCBwcm90bykge1xuICAgIHNldFByb3RvLmNoZWNrKHRhcmdldCwgcHJvdG8pO1xuICAgIHRyeSB7XG4gICAgICBzZXRQcm90by5zZXQodGFyZ2V0LCBwcm90byk7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG59KTtcbiIsIi8vIDI2LjEuMTMgUmVmbGVjdC5zZXQodGFyZ2V0LCBwcm9wZXJ0eUtleSwgViBbLCByZWNlaXZlcl0pXG52YXIgZFAgPSByZXF1aXJlKCcuL19vYmplY3QtZHAnKTtcbnZhciBnT1BEID0gcmVxdWlyZSgnLi9fb2JqZWN0LWdvcGQnKTtcbnZhciBnZXRQcm90b3R5cGVPZiA9IHJlcXVpcmUoJy4vX29iamVjdC1ncG8nKTtcbnZhciBoYXMgPSByZXF1aXJlKCcuL19oYXMnKTtcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgY3JlYXRlRGVzYyA9IHJlcXVpcmUoJy4vX3Byb3BlcnR5LWRlc2MnKTtcbnZhciBhbk9iamVjdCA9IHJlcXVpcmUoJy4vX2FuLW9iamVjdCcpO1xudmFyIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi9faXMtb2JqZWN0Jyk7XG5cbmZ1bmN0aW9uIHNldCh0YXJnZXQsIHByb3BlcnR5S2V5LCBWIC8qICwgcmVjZWl2ZXIgKi8pIHtcbiAgdmFyIHJlY2VpdmVyID0gYXJndW1lbnRzLmxlbmd0aCA8IDQgPyB0YXJnZXQgOiBhcmd1bWVudHNbM107XG4gIHZhciBvd25EZXNjID0gZ09QRC5mKGFuT2JqZWN0KHRhcmdldCksIHByb3BlcnR5S2V5KTtcbiAgdmFyIGV4aXN0aW5nRGVzY3JpcHRvciwgcHJvdG87XG4gIGlmICghb3duRGVzYykge1xuICAgIGlmIChpc09iamVjdChwcm90byA9IGdldFByb3RvdHlwZU9mKHRhcmdldCkpKSB7XG4gICAgICByZXR1cm4gc2V0KHByb3RvLCBwcm9wZXJ0eUtleSwgViwgcmVjZWl2ZXIpO1xuICAgIH1cbiAgICBvd25EZXNjID0gY3JlYXRlRGVzYygwKTtcbiAgfVxuICBpZiAoaGFzKG93bkRlc2MsICd2YWx1ZScpKSB7XG4gICAgaWYgKG93bkRlc2Mud3JpdGFibGUgPT09IGZhbHNlIHx8ICFpc09iamVjdChyZWNlaXZlcikpIHJldHVybiBmYWxzZTtcbiAgICBpZiAoZXhpc3RpbmdEZXNjcmlwdG9yID0gZ09QRC5mKHJlY2VpdmVyLCBwcm9wZXJ0eUtleSkpIHtcbiAgICAgIGlmIChleGlzdGluZ0Rlc2NyaXB0b3IuZ2V0IHx8IGV4aXN0aW5nRGVzY3JpcHRvci5zZXQgfHwgZXhpc3RpbmdEZXNjcmlwdG9yLndyaXRhYmxlID09PSBmYWxzZSkgcmV0dXJuIGZhbHNlO1xuICAgICAgZXhpc3RpbmdEZXNjcmlwdG9yLnZhbHVlID0gVjtcbiAgICAgIGRQLmYocmVjZWl2ZXIsIHByb3BlcnR5S2V5LCBleGlzdGluZ0Rlc2NyaXB0b3IpO1xuICAgIH0gZWxzZSBkUC5mKHJlY2VpdmVyLCBwcm9wZXJ0eUtleSwgY3JlYXRlRGVzYygwLCBWKSk7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgcmV0dXJuIG93bkRlc2Muc2V0ID09PSB1bmRlZmluZWQgPyBmYWxzZSA6IChvd25EZXNjLnNldC5jYWxsKHJlY2VpdmVyLCBWKSwgdHJ1ZSk7XG59XG5cbiRleHBvcnQoJGV4cG9ydC5TLCAnUmVmbGVjdCcsIHsgc2V0OiBzZXQgfSk7XG4iLCJ2YXIgZ2xvYmFsID0gcmVxdWlyZSgnLi9fZ2xvYmFsJyk7XG52YXIgaW5oZXJpdElmUmVxdWlyZWQgPSByZXF1aXJlKCcuL19pbmhlcml0LWlmLXJlcXVpcmVkJyk7XG52YXIgZFAgPSByZXF1aXJlKCcuL19vYmplY3QtZHAnKS5mO1xudmFyIGdPUE4gPSByZXF1aXJlKCcuL19vYmplY3QtZ29wbicpLmY7XG52YXIgaXNSZWdFeHAgPSByZXF1aXJlKCcuL19pcy1yZWdleHAnKTtcbnZhciAkZmxhZ3MgPSByZXF1aXJlKCcuL19mbGFncycpO1xudmFyICRSZWdFeHAgPSBnbG9iYWwuUmVnRXhwO1xudmFyIEJhc2UgPSAkUmVnRXhwO1xudmFyIHByb3RvID0gJFJlZ0V4cC5wcm90b3R5cGU7XG52YXIgcmUxID0gL2EvZztcbnZhciByZTIgPSAvYS9nO1xuLy8gXCJuZXdcIiBjcmVhdGVzIGEgbmV3IG9iamVjdCwgb2xkIHdlYmtpdCBidWdneSBoZXJlXG52YXIgQ09SUkVDVF9ORVcgPSBuZXcgJFJlZ0V4cChyZTEpICE9PSByZTE7XG5cbmlmIChyZXF1aXJlKCcuL19kZXNjcmlwdG9ycycpICYmICghQ09SUkVDVF9ORVcgfHwgcmVxdWlyZSgnLi9fZmFpbHMnKShmdW5jdGlvbiAoKSB7XG4gIHJlMltyZXF1aXJlKCcuL193a3MnKSgnbWF0Y2gnKV0gPSBmYWxzZTtcbiAgLy8gUmVnRXhwIGNvbnN0cnVjdG9yIGNhbiBhbHRlciBmbGFncyBhbmQgSXNSZWdFeHAgd29ya3MgY29ycmVjdCB3aXRoIEBAbWF0Y2hcbiAgcmV0dXJuICRSZWdFeHAocmUxKSAhPSByZTEgfHwgJFJlZ0V4cChyZTIpID09IHJlMiB8fCAkUmVnRXhwKHJlMSwgJ2knKSAhPSAnL2EvaSc7XG59KSkpIHtcbiAgJFJlZ0V4cCA9IGZ1bmN0aW9uIFJlZ0V4cChwLCBmKSB7XG4gICAgdmFyIHRpUkUgPSB0aGlzIGluc3RhbmNlb2YgJFJlZ0V4cDtcbiAgICB2YXIgcGlSRSA9IGlzUmVnRXhwKHApO1xuICAgIHZhciBmaVUgPSBmID09PSB1bmRlZmluZWQ7XG4gICAgcmV0dXJuICF0aVJFICYmIHBpUkUgJiYgcC5jb25zdHJ1Y3RvciA9PT0gJFJlZ0V4cCAmJiBmaVUgPyBwXG4gICAgICA6IGluaGVyaXRJZlJlcXVpcmVkKENPUlJFQ1RfTkVXXG4gICAgICAgID8gbmV3IEJhc2UocGlSRSAmJiAhZmlVID8gcC5zb3VyY2UgOiBwLCBmKVxuICAgICAgICA6IEJhc2UoKHBpUkUgPSBwIGluc3RhbmNlb2YgJFJlZ0V4cCkgPyBwLnNvdXJjZSA6IHAsIHBpUkUgJiYgZmlVID8gJGZsYWdzLmNhbGwocCkgOiBmKVxuICAgICAgLCB0aVJFID8gdGhpcyA6IHByb3RvLCAkUmVnRXhwKTtcbiAgfTtcbiAgdmFyIHByb3h5ID0gZnVuY3Rpb24gKGtleSkge1xuICAgIGtleSBpbiAkUmVnRXhwIHx8IGRQKCRSZWdFeHAsIGtleSwge1xuICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBCYXNlW2tleV07IH0sXG4gICAgICBzZXQ6IGZ1bmN0aW9uIChpdCkgeyBCYXNlW2tleV0gPSBpdDsgfVxuICAgIH0pO1xuICB9O1xuICBmb3IgKHZhciBrZXlzID0gZ09QTihCYXNlKSwgaSA9IDA7IGtleXMubGVuZ3RoID4gaTspIHByb3h5KGtleXNbaSsrXSk7XG4gIHByb3RvLmNvbnN0cnVjdG9yID0gJFJlZ0V4cDtcbiAgJFJlZ0V4cC5wcm90b3R5cGUgPSBwcm90bztcbiAgcmVxdWlyZSgnLi9fcmVkZWZpbmUnKShnbG9iYWwsICdSZWdFeHAnLCAkUmVnRXhwKTtcbn1cblxucmVxdWlyZSgnLi9fc2V0LXNwZWNpZXMnKSgnUmVnRXhwJyk7XG4iLCIvLyAyMS4yLjUuMyBnZXQgUmVnRXhwLnByb3RvdHlwZS5mbGFncygpXG5pZiAocmVxdWlyZSgnLi9fZGVzY3JpcHRvcnMnKSAmJiAvLi9nLmZsYWdzICE9ICdnJykgcmVxdWlyZSgnLi9fb2JqZWN0LWRwJykuZihSZWdFeHAucHJvdG90eXBlLCAnZmxhZ3MnLCB7XG4gIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgZ2V0OiByZXF1aXJlKCcuL19mbGFncycpXG59KTtcbiIsIi8vIEBAbWF0Y2ggbG9naWNcbnJlcXVpcmUoJy4vX2ZpeC1yZS13a3MnKSgnbWF0Y2gnLCAxLCBmdW5jdGlvbiAoZGVmaW5lZCwgTUFUQ0gsICRtYXRjaCkge1xuICAvLyAyMS4xLjMuMTEgU3RyaW5nLnByb3RvdHlwZS5tYXRjaChyZWdleHApXG4gIHJldHVybiBbZnVuY3Rpb24gbWF0Y2gocmVnZXhwKSB7XG4gICAgJ3VzZSBzdHJpY3QnO1xuICAgIHZhciBPID0gZGVmaW5lZCh0aGlzKTtcbiAgICB2YXIgZm4gPSByZWdleHAgPT0gdW5kZWZpbmVkID8gdW5kZWZpbmVkIDogcmVnZXhwW01BVENIXTtcbiAgICByZXR1cm4gZm4gIT09IHVuZGVmaW5lZCA/IGZuLmNhbGwocmVnZXhwLCBPKSA6IG5ldyBSZWdFeHAocmVnZXhwKVtNQVRDSF0oU3RyaW5nKE8pKTtcbiAgfSwgJG1hdGNoXTtcbn0pO1xuIiwiLy8gQEByZXBsYWNlIGxvZ2ljXG5yZXF1aXJlKCcuL19maXgtcmUtd2tzJykoJ3JlcGxhY2UnLCAyLCBmdW5jdGlvbiAoZGVmaW5lZCwgUkVQTEFDRSwgJHJlcGxhY2UpIHtcbiAgLy8gMjEuMS4zLjE0IFN0cmluZy5wcm90b3R5cGUucmVwbGFjZShzZWFyY2hWYWx1ZSwgcmVwbGFjZVZhbHVlKVxuICByZXR1cm4gW2Z1bmN0aW9uIHJlcGxhY2Uoc2VhcmNoVmFsdWUsIHJlcGxhY2VWYWx1ZSkge1xuICAgICd1c2Ugc3RyaWN0JztcbiAgICB2YXIgTyA9IGRlZmluZWQodGhpcyk7XG4gICAgdmFyIGZuID0gc2VhcmNoVmFsdWUgPT0gdW5kZWZpbmVkID8gdW5kZWZpbmVkIDogc2VhcmNoVmFsdWVbUkVQTEFDRV07XG4gICAgcmV0dXJuIGZuICE9PSB1bmRlZmluZWRcbiAgICAgID8gZm4uY2FsbChzZWFyY2hWYWx1ZSwgTywgcmVwbGFjZVZhbHVlKVxuICAgICAgOiAkcmVwbGFjZS5jYWxsKFN0cmluZyhPKSwgc2VhcmNoVmFsdWUsIHJlcGxhY2VWYWx1ZSk7XG4gIH0sICRyZXBsYWNlXTtcbn0pO1xuIiwiLy8gQEBzZWFyY2ggbG9naWNcbnJlcXVpcmUoJy4vX2ZpeC1yZS13a3MnKSgnc2VhcmNoJywgMSwgZnVuY3Rpb24gKGRlZmluZWQsIFNFQVJDSCwgJHNlYXJjaCkge1xuICAvLyAyMS4xLjMuMTUgU3RyaW5nLnByb3RvdHlwZS5zZWFyY2gocmVnZXhwKVxuICByZXR1cm4gW2Z1bmN0aW9uIHNlYXJjaChyZWdleHApIHtcbiAgICAndXNlIHN0cmljdCc7XG4gICAgdmFyIE8gPSBkZWZpbmVkKHRoaXMpO1xuICAgIHZhciBmbiA9IHJlZ2V4cCA9PSB1bmRlZmluZWQgPyB1bmRlZmluZWQgOiByZWdleHBbU0VBUkNIXTtcbiAgICByZXR1cm4gZm4gIT09IHVuZGVmaW5lZCA/IGZuLmNhbGwocmVnZXhwLCBPKSA6IG5ldyBSZWdFeHAocmVnZXhwKVtTRUFSQ0hdKFN0cmluZyhPKSk7XG4gIH0sICRzZWFyY2hdO1xufSk7XG4iLCIvLyBAQHNwbGl0IGxvZ2ljXG5yZXF1aXJlKCcuL19maXgtcmUtd2tzJykoJ3NwbGl0JywgMiwgZnVuY3Rpb24gKGRlZmluZWQsIFNQTElULCAkc3BsaXQpIHtcbiAgJ3VzZSBzdHJpY3QnO1xuICB2YXIgaXNSZWdFeHAgPSByZXF1aXJlKCcuL19pcy1yZWdleHAnKTtcbiAgdmFyIF9zcGxpdCA9ICRzcGxpdDtcbiAgdmFyICRwdXNoID0gW10ucHVzaDtcbiAgdmFyICRTUExJVCA9ICdzcGxpdCc7XG4gIHZhciBMRU5HVEggPSAnbGVuZ3RoJztcbiAgdmFyIExBU1RfSU5ERVggPSAnbGFzdEluZGV4JztcbiAgaWYgKFxuICAgICdhYmJjJ1skU1BMSVRdKC8oYikqLylbMV0gPT0gJ2MnIHx8XG4gICAgJ3Rlc3QnWyRTUExJVF0oLyg/OikvLCAtMSlbTEVOR1RIXSAhPSA0IHx8XG4gICAgJ2FiJ1skU1BMSVRdKC8oPzphYikqLylbTEVOR1RIXSAhPSAyIHx8XG4gICAgJy4nWyRTUExJVF0oLyguPykoLj8pLylbTEVOR1RIXSAhPSA0IHx8XG4gICAgJy4nWyRTUExJVF0oLygpKCkvKVtMRU5HVEhdID4gMSB8fFxuICAgICcnWyRTUExJVF0oLy4/LylbTEVOR1RIXVxuICApIHtcbiAgICB2YXIgTlBDRyA9IC8oKT8/Ly5leGVjKCcnKVsxXSA9PT0gdW5kZWZpbmVkOyAvLyBub25wYXJ0aWNpcGF0aW5nIGNhcHR1cmluZyBncm91cFxuICAgIC8vIGJhc2VkIG9uIGVzNS1zaGltIGltcGxlbWVudGF0aW9uLCBuZWVkIHRvIHJld29yayBpdFxuICAgICRzcGxpdCA9IGZ1bmN0aW9uIChzZXBhcmF0b3IsIGxpbWl0KSB7XG4gICAgICB2YXIgc3RyaW5nID0gU3RyaW5nKHRoaXMpO1xuICAgICAgaWYgKHNlcGFyYXRvciA9PT0gdW5kZWZpbmVkICYmIGxpbWl0ID09PSAwKSByZXR1cm4gW107XG4gICAgICAvLyBJZiBgc2VwYXJhdG9yYCBpcyBub3QgYSByZWdleCwgdXNlIG5hdGl2ZSBzcGxpdFxuICAgICAgaWYgKCFpc1JlZ0V4cChzZXBhcmF0b3IpKSByZXR1cm4gX3NwbGl0LmNhbGwoc3RyaW5nLCBzZXBhcmF0b3IsIGxpbWl0KTtcbiAgICAgIHZhciBvdXRwdXQgPSBbXTtcbiAgICAgIHZhciBmbGFncyA9IChzZXBhcmF0b3IuaWdub3JlQ2FzZSA/ICdpJyA6ICcnKSArXG4gICAgICAgICAgICAgICAgICAoc2VwYXJhdG9yLm11bHRpbGluZSA/ICdtJyA6ICcnKSArXG4gICAgICAgICAgICAgICAgICAoc2VwYXJhdG9yLnVuaWNvZGUgPyAndScgOiAnJykgK1xuICAgICAgICAgICAgICAgICAgKHNlcGFyYXRvci5zdGlja3kgPyAneScgOiAnJyk7XG4gICAgICB2YXIgbGFzdExhc3RJbmRleCA9IDA7XG4gICAgICB2YXIgc3BsaXRMaW1pdCA9IGxpbWl0ID09PSB1bmRlZmluZWQgPyA0Mjk0OTY3Mjk1IDogbGltaXQgPj4+IDA7XG4gICAgICAvLyBNYWtlIGBnbG9iYWxgIGFuZCBhdm9pZCBgbGFzdEluZGV4YCBpc3N1ZXMgYnkgd29ya2luZyB3aXRoIGEgY29weVxuICAgICAgdmFyIHNlcGFyYXRvckNvcHkgPSBuZXcgUmVnRXhwKHNlcGFyYXRvci5zb3VyY2UsIGZsYWdzICsgJ2cnKTtcbiAgICAgIHZhciBzZXBhcmF0b3IyLCBtYXRjaCwgbGFzdEluZGV4LCBsYXN0TGVuZ3RoLCBpO1xuICAgICAgLy8gRG9lc24ndCBuZWVkIGZsYWdzIGd5LCBidXQgdGhleSBkb24ndCBodXJ0XG4gICAgICBpZiAoIU5QQ0cpIHNlcGFyYXRvcjIgPSBuZXcgUmVnRXhwKCdeJyArIHNlcGFyYXRvckNvcHkuc291cmNlICsgJyQoPyFcXFxccyknLCBmbGFncyk7XG4gICAgICB3aGlsZSAobWF0Y2ggPSBzZXBhcmF0b3JDb3B5LmV4ZWMoc3RyaW5nKSkge1xuICAgICAgICAvLyBgc2VwYXJhdG9yQ29weS5sYXN0SW5kZXhgIGlzIG5vdCByZWxpYWJsZSBjcm9zcy1icm93c2VyXG4gICAgICAgIGxhc3RJbmRleCA9IG1hdGNoLmluZGV4ICsgbWF0Y2hbMF1bTEVOR1RIXTtcbiAgICAgICAgaWYgKGxhc3RJbmRleCA+IGxhc3RMYXN0SW5kZXgpIHtcbiAgICAgICAgICBvdXRwdXQucHVzaChzdHJpbmcuc2xpY2UobGFzdExhc3RJbmRleCwgbWF0Y2guaW5kZXgpKTtcbiAgICAgICAgICAvLyBGaXggYnJvd3NlcnMgd2hvc2UgYGV4ZWNgIG1ldGhvZHMgZG9uJ3QgY29uc2lzdGVudGx5IHJldHVybiBgdW5kZWZpbmVkYCBmb3IgTlBDR1xuICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1sb29wLWZ1bmNcbiAgICAgICAgICBpZiAoIU5QQ0cgJiYgbWF0Y2hbTEVOR1RIXSA+IDEpIG1hdGNoWzBdLnJlcGxhY2Uoc2VwYXJhdG9yMiwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgZm9yIChpID0gMTsgaSA8IGFyZ3VtZW50c1tMRU5HVEhdIC0gMjsgaSsrKSBpZiAoYXJndW1lbnRzW2ldID09PSB1bmRlZmluZWQpIG1hdGNoW2ldID0gdW5kZWZpbmVkO1xuICAgICAgICAgIH0pO1xuICAgICAgICAgIGlmIChtYXRjaFtMRU5HVEhdID4gMSAmJiBtYXRjaC5pbmRleCA8IHN0cmluZ1tMRU5HVEhdKSAkcHVzaC5hcHBseShvdXRwdXQsIG1hdGNoLnNsaWNlKDEpKTtcbiAgICAgICAgICBsYXN0TGVuZ3RoID0gbWF0Y2hbMF1bTEVOR1RIXTtcbiAgICAgICAgICBsYXN0TGFzdEluZGV4ID0gbGFzdEluZGV4O1xuICAgICAgICAgIGlmIChvdXRwdXRbTEVOR1RIXSA+PSBzcGxpdExpbWl0KSBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBpZiAoc2VwYXJhdG9yQ29weVtMQVNUX0lOREVYXSA9PT0gbWF0Y2guaW5kZXgpIHNlcGFyYXRvckNvcHlbTEFTVF9JTkRFWF0rKzsgLy8gQXZvaWQgYW4gaW5maW5pdGUgbG9vcFxuICAgICAgfVxuICAgICAgaWYgKGxhc3RMYXN0SW5kZXggPT09IHN0cmluZ1tMRU5HVEhdKSB7XG4gICAgICAgIGlmIChsYXN0TGVuZ3RoIHx8ICFzZXBhcmF0b3JDb3B5LnRlc3QoJycpKSBvdXRwdXQucHVzaCgnJyk7XG4gICAgICB9IGVsc2Ugb3V0cHV0LnB1c2goc3RyaW5nLnNsaWNlKGxhc3RMYXN0SW5kZXgpKTtcbiAgICAgIHJldHVybiBvdXRwdXRbTEVOR1RIXSA+IHNwbGl0TGltaXQgPyBvdXRwdXQuc2xpY2UoMCwgc3BsaXRMaW1pdCkgOiBvdXRwdXQ7XG4gICAgfTtcbiAgLy8gQ2hha3JhLCBWOFxuICB9IGVsc2UgaWYgKCcwJ1skU1BMSVRdKHVuZGVmaW5lZCwgMClbTEVOR1RIXSkge1xuICAgICRzcGxpdCA9IGZ1bmN0aW9uIChzZXBhcmF0b3IsIGxpbWl0KSB7XG4gICAgICByZXR1cm4gc2VwYXJhdG9yID09PSB1bmRlZmluZWQgJiYgbGltaXQgPT09IDAgPyBbXSA6IF9zcGxpdC5jYWxsKHRoaXMsIHNlcGFyYXRvciwgbGltaXQpO1xuICAgIH07XG4gIH1cbiAgLy8gMjEuMS4zLjE3IFN0cmluZy5wcm90b3R5cGUuc3BsaXQoc2VwYXJhdG9yLCBsaW1pdClcbiAgcmV0dXJuIFtmdW5jdGlvbiBzcGxpdChzZXBhcmF0b3IsIGxpbWl0KSB7XG4gICAgdmFyIE8gPSBkZWZpbmVkKHRoaXMpO1xuICAgIHZhciBmbiA9IHNlcGFyYXRvciA9PSB1bmRlZmluZWQgPyB1bmRlZmluZWQgOiBzZXBhcmF0b3JbU1BMSVRdO1xuICAgIHJldHVybiBmbiAhPT0gdW5kZWZpbmVkID8gZm4uY2FsbChzZXBhcmF0b3IsIE8sIGxpbWl0KSA6ICRzcGxpdC5jYWxsKFN0cmluZyhPKSwgc2VwYXJhdG9yLCBsaW1pdCk7XG4gIH0sICRzcGxpdF07XG59KTtcbiIsIid1c2Ugc3RyaWN0JztcbnJlcXVpcmUoJy4vZXM2LnJlZ2V4cC5mbGFncycpO1xudmFyIGFuT2JqZWN0ID0gcmVxdWlyZSgnLi9fYW4tb2JqZWN0Jyk7XG52YXIgJGZsYWdzID0gcmVxdWlyZSgnLi9fZmxhZ3MnKTtcbnZhciBERVNDUklQVE9SUyA9IHJlcXVpcmUoJy4vX2Rlc2NyaXB0b3JzJyk7XG52YXIgVE9fU1RSSU5HID0gJ3RvU3RyaW5nJztcbnZhciAkdG9TdHJpbmcgPSAvLi9bVE9fU1RSSU5HXTtcblxudmFyIGRlZmluZSA9IGZ1bmN0aW9uIChmbikge1xuICByZXF1aXJlKCcuL19yZWRlZmluZScpKFJlZ0V4cC5wcm90b3R5cGUsIFRPX1NUUklORywgZm4sIHRydWUpO1xufTtcblxuLy8gMjEuMi41LjE0IFJlZ0V4cC5wcm90b3R5cGUudG9TdHJpbmcoKVxuaWYgKHJlcXVpcmUoJy4vX2ZhaWxzJykoZnVuY3Rpb24gKCkgeyByZXR1cm4gJHRvU3RyaW5nLmNhbGwoeyBzb3VyY2U6ICdhJywgZmxhZ3M6ICdiJyB9KSAhPSAnL2EvYic7IH0pKSB7XG4gIGRlZmluZShmdW5jdGlvbiB0b1N0cmluZygpIHtcbiAgICB2YXIgUiA9IGFuT2JqZWN0KHRoaXMpO1xuICAgIHJldHVybiAnLycuY29uY2F0KFIuc291cmNlLCAnLycsXG4gICAgICAnZmxhZ3MnIGluIFIgPyBSLmZsYWdzIDogIURFU0NSSVBUT1JTICYmIFIgaW5zdGFuY2VvZiBSZWdFeHAgPyAkZmxhZ3MuY2FsbChSKSA6IHVuZGVmaW5lZCk7XG4gIH0pO1xuLy8gRkY0NC0gUmVnRXhwI3RvU3RyaW5nIGhhcyBhIHdyb25nIG5hbWVcbn0gZWxzZSBpZiAoJHRvU3RyaW5nLm5hbWUgIT0gVE9fU1RSSU5HKSB7XG4gIGRlZmluZShmdW5jdGlvbiB0b1N0cmluZygpIHtcbiAgICByZXR1cm4gJHRvU3RyaW5nLmNhbGwodGhpcyk7XG4gIH0pO1xufVxuIiwiJ3VzZSBzdHJpY3QnO1xudmFyIHN0cm9uZyA9IHJlcXVpcmUoJy4vX2NvbGxlY3Rpb24tc3Ryb25nJyk7XG52YXIgdmFsaWRhdGUgPSByZXF1aXJlKCcuL192YWxpZGF0ZS1jb2xsZWN0aW9uJyk7XG52YXIgU0VUID0gJ1NldCc7XG5cbi8vIDIzLjIgU2V0IE9iamVjdHNcbm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi9fY29sbGVjdGlvbicpKFNFVCwgZnVuY3Rpb24gKGdldCkge1xuICByZXR1cm4gZnVuY3Rpb24gU2V0KCkgeyByZXR1cm4gZ2V0KHRoaXMsIGFyZ3VtZW50cy5sZW5ndGggPiAwID8gYXJndW1lbnRzWzBdIDogdW5kZWZpbmVkKTsgfTtcbn0sIHtcbiAgLy8gMjMuMi4zLjEgU2V0LnByb3RvdHlwZS5hZGQodmFsdWUpXG4gIGFkZDogZnVuY3Rpb24gYWRkKHZhbHVlKSB7XG4gICAgcmV0dXJuIHN0cm9uZy5kZWYodmFsaWRhdGUodGhpcywgU0VUKSwgdmFsdWUgPSB2YWx1ZSA9PT0gMCA/IDAgOiB2YWx1ZSwgdmFsdWUpO1xuICB9XG59LCBzdHJvbmcpO1xuIiwiJ3VzZSBzdHJpY3QnO1xuLy8gQi4yLjMuMiBTdHJpbmcucHJvdG90eXBlLmFuY2hvcihuYW1lKVxucmVxdWlyZSgnLi9fc3RyaW5nLWh0bWwnKSgnYW5jaG9yJywgZnVuY3Rpb24gKGNyZWF0ZUhUTUwpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIGFuY2hvcihuYW1lKSB7XG4gICAgcmV0dXJuIGNyZWF0ZUhUTUwodGhpcywgJ2EnLCAnbmFtZScsIG5hbWUpO1xuICB9O1xufSk7XG4iLCIndXNlIHN0cmljdCc7XG4vLyBCLjIuMy4zIFN0cmluZy5wcm90b3R5cGUuYmlnKClcbnJlcXVpcmUoJy4vX3N0cmluZy1odG1sJykoJ2JpZycsIGZ1bmN0aW9uIChjcmVhdGVIVE1MKSB7XG4gIHJldHVybiBmdW5jdGlvbiBiaWcoKSB7XG4gICAgcmV0dXJuIGNyZWF0ZUhUTUwodGhpcywgJ2JpZycsICcnLCAnJyk7XG4gIH07XG59KTtcbiIsIid1c2Ugc3RyaWN0Jztcbi8vIEIuMi4zLjQgU3RyaW5nLnByb3RvdHlwZS5ibGluaygpXG5yZXF1aXJlKCcuL19zdHJpbmctaHRtbCcpKCdibGluaycsIGZ1bmN0aW9uIChjcmVhdGVIVE1MKSB7XG4gIHJldHVybiBmdW5jdGlvbiBibGluaygpIHtcbiAgICByZXR1cm4gY3JlYXRlSFRNTCh0aGlzLCAnYmxpbmsnLCAnJywgJycpO1xuICB9O1xufSk7XG4iLCIndXNlIHN0cmljdCc7XG4vLyBCLjIuMy41IFN0cmluZy5wcm90b3R5cGUuYm9sZCgpXG5yZXF1aXJlKCcuL19zdHJpbmctaHRtbCcpKCdib2xkJywgZnVuY3Rpb24gKGNyZWF0ZUhUTUwpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIGJvbGQoKSB7XG4gICAgcmV0dXJuIGNyZWF0ZUhUTUwodGhpcywgJ2InLCAnJywgJycpO1xuICB9O1xufSk7XG4iLCIndXNlIHN0cmljdCc7XG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyICRhdCA9IHJlcXVpcmUoJy4vX3N0cmluZy1hdCcpKGZhbHNlKTtcbiRleHBvcnQoJGV4cG9ydC5QLCAnU3RyaW5nJywge1xuICAvLyAyMS4xLjMuMyBTdHJpbmcucHJvdG90eXBlLmNvZGVQb2ludEF0KHBvcylcbiAgY29kZVBvaW50QXQ6IGZ1bmN0aW9uIGNvZGVQb2ludEF0KHBvcykge1xuICAgIHJldHVybiAkYXQodGhpcywgcG9zKTtcbiAgfVxufSk7XG4iLCIvLyAyMS4xLjMuNiBTdHJpbmcucHJvdG90eXBlLmVuZHNXaXRoKHNlYXJjaFN0cmluZyBbLCBlbmRQb3NpdGlvbl0pXG4ndXNlIHN0cmljdCc7XG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyIHRvTGVuZ3RoID0gcmVxdWlyZSgnLi9fdG8tbGVuZ3RoJyk7XG52YXIgY29udGV4dCA9IHJlcXVpcmUoJy4vX3N0cmluZy1jb250ZXh0Jyk7XG52YXIgRU5EU19XSVRIID0gJ2VuZHNXaXRoJztcbnZhciAkZW5kc1dpdGggPSAnJ1tFTkRTX1dJVEhdO1xuXG4kZXhwb3J0KCRleHBvcnQuUCArICRleHBvcnQuRiAqIHJlcXVpcmUoJy4vX2ZhaWxzLWlzLXJlZ2V4cCcpKEVORFNfV0lUSCksICdTdHJpbmcnLCB7XG4gIGVuZHNXaXRoOiBmdW5jdGlvbiBlbmRzV2l0aChzZWFyY2hTdHJpbmcgLyogLCBlbmRQb3NpdGlvbiA9IEBsZW5ndGggKi8pIHtcbiAgICB2YXIgdGhhdCA9IGNvbnRleHQodGhpcywgc2VhcmNoU3RyaW5nLCBFTkRTX1dJVEgpO1xuICAgIHZhciBlbmRQb3NpdGlvbiA9IGFyZ3VtZW50cy5sZW5ndGggPiAxID8gYXJndW1lbnRzWzFdIDogdW5kZWZpbmVkO1xuICAgIHZhciBsZW4gPSB0b0xlbmd0aCh0aGF0Lmxlbmd0aCk7XG4gICAgdmFyIGVuZCA9IGVuZFBvc2l0aW9uID09PSB1bmRlZmluZWQgPyBsZW4gOiBNYXRoLm1pbih0b0xlbmd0aChlbmRQb3NpdGlvbiksIGxlbik7XG4gICAgdmFyIHNlYXJjaCA9IFN0cmluZyhzZWFyY2hTdHJpbmcpO1xuICAgIHJldHVybiAkZW5kc1dpdGhcbiAgICAgID8gJGVuZHNXaXRoLmNhbGwodGhhdCwgc2VhcmNoLCBlbmQpXG4gICAgICA6IHRoYXQuc2xpY2UoZW5kIC0gc2VhcmNoLmxlbmd0aCwgZW5kKSA9PT0gc2VhcmNoO1xuICB9XG59KTtcbiIsIid1c2Ugc3RyaWN0Jztcbi8vIEIuMi4zLjYgU3RyaW5nLnByb3RvdHlwZS5maXhlZCgpXG5yZXF1aXJlKCcuL19zdHJpbmctaHRtbCcpKCdmaXhlZCcsIGZ1bmN0aW9uIChjcmVhdGVIVE1MKSB7XG4gIHJldHVybiBmdW5jdGlvbiBmaXhlZCgpIHtcbiAgICByZXR1cm4gY3JlYXRlSFRNTCh0aGlzLCAndHQnLCAnJywgJycpO1xuICB9O1xufSk7XG4iLCIndXNlIHN0cmljdCc7XG4vLyBCLjIuMy43IFN0cmluZy5wcm90b3R5cGUuZm9udGNvbG9yKGNvbG9yKVxucmVxdWlyZSgnLi9fc3RyaW5nLWh0bWwnKSgnZm9udGNvbG9yJywgZnVuY3Rpb24gKGNyZWF0ZUhUTUwpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIGZvbnRjb2xvcihjb2xvcikge1xuICAgIHJldHVybiBjcmVhdGVIVE1MKHRoaXMsICdmb250JywgJ2NvbG9yJywgY29sb3IpO1xuICB9O1xufSk7XG4iLCIndXNlIHN0cmljdCc7XG4vLyBCLjIuMy44IFN0cmluZy5wcm90b3R5cGUuZm9udHNpemUoc2l6ZSlcbnJlcXVpcmUoJy4vX3N0cmluZy1odG1sJykoJ2ZvbnRzaXplJywgZnVuY3Rpb24gKGNyZWF0ZUhUTUwpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIGZvbnRzaXplKHNpemUpIHtcbiAgICByZXR1cm4gY3JlYXRlSFRNTCh0aGlzLCAnZm9udCcsICdzaXplJywgc2l6ZSk7XG4gIH07XG59KTtcbiIsInZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgdG9BYnNvbHV0ZUluZGV4ID0gcmVxdWlyZSgnLi9fdG8tYWJzb2x1dGUtaW5kZXgnKTtcbnZhciBmcm9tQ2hhckNvZGUgPSBTdHJpbmcuZnJvbUNoYXJDb2RlO1xudmFyICRmcm9tQ29kZVBvaW50ID0gU3RyaW5nLmZyb21Db2RlUG9pbnQ7XG5cbi8vIGxlbmd0aCBzaG91bGQgYmUgMSwgb2xkIEZGIHByb2JsZW1cbiRleHBvcnQoJGV4cG9ydC5TICsgJGV4cG9ydC5GICogKCEhJGZyb21Db2RlUG9pbnQgJiYgJGZyb21Db2RlUG9pbnQubGVuZ3RoICE9IDEpLCAnU3RyaW5nJywge1xuICAvLyAyMS4xLjIuMiBTdHJpbmcuZnJvbUNvZGVQb2ludCguLi5jb2RlUG9pbnRzKVxuICBmcm9tQ29kZVBvaW50OiBmdW5jdGlvbiBmcm9tQ29kZVBvaW50KHgpIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby11bnVzZWQtdmFyc1xuICAgIHZhciByZXMgPSBbXTtcbiAgICB2YXIgYUxlbiA9IGFyZ3VtZW50cy5sZW5ndGg7XG4gICAgdmFyIGkgPSAwO1xuICAgIHZhciBjb2RlO1xuICAgIHdoaWxlIChhTGVuID4gaSkge1xuICAgICAgY29kZSA9ICthcmd1bWVudHNbaSsrXTtcbiAgICAgIGlmICh0b0Fic29sdXRlSW5kZXgoY29kZSwgMHgxMGZmZmYpICE9PSBjb2RlKSB0aHJvdyBSYW5nZUVycm9yKGNvZGUgKyAnIGlzIG5vdCBhIHZhbGlkIGNvZGUgcG9pbnQnKTtcbiAgICAgIHJlcy5wdXNoKGNvZGUgPCAweDEwMDAwXG4gICAgICAgID8gZnJvbUNoYXJDb2RlKGNvZGUpXG4gICAgICAgIDogZnJvbUNoYXJDb2RlKCgoY29kZSAtPSAweDEwMDAwKSA+PiAxMCkgKyAweGQ4MDAsIGNvZGUgJSAweDQwMCArIDB4ZGMwMClcbiAgICAgICk7XG4gICAgfSByZXR1cm4gcmVzLmpvaW4oJycpO1xuICB9XG59KTtcbiIsIi8vIDIxLjEuMy43IFN0cmluZy5wcm90b3R5cGUuaW5jbHVkZXMoc2VhcmNoU3RyaW5nLCBwb3NpdGlvbiA9IDApXG4ndXNlIHN0cmljdCc7XG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyIGNvbnRleHQgPSByZXF1aXJlKCcuL19zdHJpbmctY29udGV4dCcpO1xudmFyIElOQ0xVREVTID0gJ2luY2x1ZGVzJztcblxuJGV4cG9ydCgkZXhwb3J0LlAgKyAkZXhwb3J0LkYgKiByZXF1aXJlKCcuL19mYWlscy1pcy1yZWdleHAnKShJTkNMVURFUyksICdTdHJpbmcnLCB7XG4gIGluY2x1ZGVzOiBmdW5jdGlvbiBpbmNsdWRlcyhzZWFyY2hTdHJpbmcgLyogLCBwb3NpdGlvbiA9IDAgKi8pIHtcbiAgICByZXR1cm4gISF+Y29udGV4dCh0aGlzLCBzZWFyY2hTdHJpbmcsIElOQ0xVREVTKVxuICAgICAgLmluZGV4T2Yoc2VhcmNoU3RyaW5nLCBhcmd1bWVudHMubGVuZ3RoID4gMSA/IGFyZ3VtZW50c1sxXSA6IHVuZGVmaW5lZCk7XG4gIH1cbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuLy8gQi4yLjMuOSBTdHJpbmcucHJvdG90eXBlLml0YWxpY3MoKVxucmVxdWlyZSgnLi9fc3RyaW5nLWh0bWwnKSgnaXRhbGljcycsIGZ1bmN0aW9uIChjcmVhdGVIVE1MKSB7XG4gIHJldHVybiBmdW5jdGlvbiBpdGFsaWNzKCkge1xuICAgIHJldHVybiBjcmVhdGVIVE1MKHRoaXMsICdpJywgJycsICcnKTtcbiAgfTtcbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyICRhdCA9IHJlcXVpcmUoJy4vX3N0cmluZy1hdCcpKHRydWUpO1xuXG4vLyAyMS4xLjMuMjcgU3RyaW5nLnByb3RvdHlwZVtAQGl0ZXJhdG9yXSgpXG5yZXF1aXJlKCcuL19pdGVyLWRlZmluZScpKFN0cmluZywgJ1N0cmluZycsIGZ1bmN0aW9uIChpdGVyYXRlZCkge1xuICB0aGlzLl90ID0gU3RyaW5nKGl0ZXJhdGVkKTsgLy8gdGFyZ2V0XG4gIHRoaXMuX2kgPSAwOyAgICAgICAgICAgICAgICAvLyBuZXh0IGluZGV4XG4vLyAyMS4xLjUuMi4xICVTdHJpbmdJdGVyYXRvclByb3RvdHlwZSUubmV4dCgpXG59LCBmdW5jdGlvbiAoKSB7XG4gIHZhciBPID0gdGhpcy5fdDtcbiAgdmFyIGluZGV4ID0gdGhpcy5faTtcbiAgdmFyIHBvaW50O1xuICBpZiAoaW5kZXggPj0gTy5sZW5ndGgpIHJldHVybiB7IHZhbHVlOiB1bmRlZmluZWQsIGRvbmU6IHRydWUgfTtcbiAgcG9pbnQgPSAkYXQoTywgaW5kZXgpO1xuICB0aGlzLl9pICs9IHBvaW50Lmxlbmd0aDtcbiAgcmV0dXJuIHsgdmFsdWU6IHBvaW50LCBkb25lOiBmYWxzZSB9O1xufSk7XG4iLCIndXNlIHN0cmljdCc7XG4vLyBCLjIuMy4xMCBTdHJpbmcucHJvdG90eXBlLmxpbmsodXJsKVxucmVxdWlyZSgnLi9fc3RyaW5nLWh0bWwnKSgnbGluaycsIGZ1bmN0aW9uIChjcmVhdGVIVE1MKSB7XG4gIHJldHVybiBmdW5jdGlvbiBsaW5rKHVybCkge1xuICAgIHJldHVybiBjcmVhdGVIVE1MKHRoaXMsICdhJywgJ2hyZWYnLCB1cmwpO1xuICB9O1xufSk7XG4iLCJ2YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyIHRvSU9iamVjdCA9IHJlcXVpcmUoJy4vX3RvLWlvYmplY3QnKTtcbnZhciB0b0xlbmd0aCA9IHJlcXVpcmUoJy4vX3RvLWxlbmd0aCcpO1xuXG4kZXhwb3J0KCRleHBvcnQuUywgJ1N0cmluZycsIHtcbiAgLy8gMjEuMS4yLjQgU3RyaW5nLnJhdyhjYWxsU2l0ZSwgLi4uc3Vic3RpdHV0aW9ucylcbiAgcmF3OiBmdW5jdGlvbiByYXcoY2FsbFNpdGUpIHtcbiAgICB2YXIgdHBsID0gdG9JT2JqZWN0KGNhbGxTaXRlLnJhdyk7XG4gICAgdmFyIGxlbiA9IHRvTGVuZ3RoKHRwbC5sZW5ndGgpO1xuICAgIHZhciBhTGVuID0gYXJndW1lbnRzLmxlbmd0aDtcbiAgICB2YXIgcmVzID0gW107XG4gICAgdmFyIGkgPSAwO1xuICAgIHdoaWxlIChsZW4gPiBpKSB7XG4gICAgICByZXMucHVzaChTdHJpbmcodHBsW2krK10pKTtcbiAgICAgIGlmIChpIDwgYUxlbikgcmVzLnB1c2goU3RyaW5nKGFyZ3VtZW50c1tpXSkpO1xuICAgIH0gcmV0dXJuIHJlcy5qb2luKCcnKTtcbiAgfVxufSk7XG4iLCJ2YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xuXG4kZXhwb3J0KCRleHBvcnQuUCwgJ1N0cmluZycsIHtcbiAgLy8gMjEuMS4zLjEzIFN0cmluZy5wcm90b3R5cGUucmVwZWF0KGNvdW50KVxuICByZXBlYXQ6IHJlcXVpcmUoJy4vX3N0cmluZy1yZXBlYXQnKVxufSk7XG4iLCIndXNlIHN0cmljdCc7XG4vLyBCLjIuMy4xMSBTdHJpbmcucHJvdG90eXBlLnNtYWxsKClcbnJlcXVpcmUoJy4vX3N0cmluZy1odG1sJykoJ3NtYWxsJywgZnVuY3Rpb24gKGNyZWF0ZUhUTUwpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIHNtYWxsKCkge1xuICAgIHJldHVybiBjcmVhdGVIVE1MKHRoaXMsICdzbWFsbCcsICcnLCAnJyk7XG4gIH07XG59KTtcbiIsIi8vIDIxLjEuMy4xOCBTdHJpbmcucHJvdG90eXBlLnN0YXJ0c1dpdGgoc2VhcmNoU3RyaW5nIFssIHBvc2l0aW9uIF0pXG4ndXNlIHN0cmljdCc7XG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyIHRvTGVuZ3RoID0gcmVxdWlyZSgnLi9fdG8tbGVuZ3RoJyk7XG52YXIgY29udGV4dCA9IHJlcXVpcmUoJy4vX3N0cmluZy1jb250ZXh0Jyk7XG52YXIgU1RBUlRTX1dJVEggPSAnc3RhcnRzV2l0aCc7XG52YXIgJHN0YXJ0c1dpdGggPSAnJ1tTVEFSVFNfV0lUSF07XG5cbiRleHBvcnQoJGV4cG9ydC5QICsgJGV4cG9ydC5GICogcmVxdWlyZSgnLi9fZmFpbHMtaXMtcmVnZXhwJykoU1RBUlRTX1dJVEgpLCAnU3RyaW5nJywge1xuICBzdGFydHNXaXRoOiBmdW5jdGlvbiBzdGFydHNXaXRoKHNlYXJjaFN0cmluZyAvKiAsIHBvc2l0aW9uID0gMCAqLykge1xuICAgIHZhciB0aGF0ID0gY29udGV4dCh0aGlzLCBzZWFyY2hTdHJpbmcsIFNUQVJUU19XSVRIKTtcbiAgICB2YXIgaW5kZXggPSB0b0xlbmd0aChNYXRoLm1pbihhcmd1bWVudHMubGVuZ3RoID4gMSA/IGFyZ3VtZW50c1sxXSA6IHVuZGVmaW5lZCwgdGhhdC5sZW5ndGgpKTtcbiAgICB2YXIgc2VhcmNoID0gU3RyaW5nKHNlYXJjaFN0cmluZyk7XG4gICAgcmV0dXJuICRzdGFydHNXaXRoXG4gICAgICA/ICRzdGFydHNXaXRoLmNhbGwodGhhdCwgc2VhcmNoLCBpbmRleClcbiAgICAgIDogdGhhdC5zbGljZShpbmRleCwgaW5kZXggKyBzZWFyY2gubGVuZ3RoKSA9PT0gc2VhcmNoO1xuICB9XG59KTtcbiIsIid1c2Ugc3RyaWN0Jztcbi8vIEIuMi4zLjEyIFN0cmluZy5wcm90b3R5cGUuc3RyaWtlKClcbnJlcXVpcmUoJy4vX3N0cmluZy1odG1sJykoJ3N0cmlrZScsIGZ1bmN0aW9uIChjcmVhdGVIVE1MKSB7XG4gIHJldHVybiBmdW5jdGlvbiBzdHJpa2UoKSB7XG4gICAgcmV0dXJuIGNyZWF0ZUhUTUwodGhpcywgJ3N0cmlrZScsICcnLCAnJyk7XG4gIH07XG59KTtcbiIsIid1c2Ugc3RyaWN0Jztcbi8vIEIuMi4zLjEzIFN0cmluZy5wcm90b3R5cGUuc3ViKClcbnJlcXVpcmUoJy4vX3N0cmluZy1odG1sJykoJ3N1YicsIGZ1bmN0aW9uIChjcmVhdGVIVE1MKSB7XG4gIHJldHVybiBmdW5jdGlvbiBzdWIoKSB7XG4gICAgcmV0dXJuIGNyZWF0ZUhUTUwodGhpcywgJ3N1YicsICcnLCAnJyk7XG4gIH07XG59KTtcbiIsIid1c2Ugc3RyaWN0Jztcbi8vIEIuMi4zLjE0IFN0cmluZy5wcm90b3R5cGUuc3VwKClcbnJlcXVpcmUoJy4vX3N0cmluZy1odG1sJykoJ3N1cCcsIGZ1bmN0aW9uIChjcmVhdGVIVE1MKSB7XG4gIHJldHVybiBmdW5jdGlvbiBzdXAoKSB7XG4gICAgcmV0dXJuIGNyZWF0ZUhUTUwodGhpcywgJ3N1cCcsICcnLCAnJyk7XG4gIH07XG59KTtcbiIsIid1c2Ugc3RyaWN0Jztcbi8vIDIxLjEuMy4yNSBTdHJpbmcucHJvdG90eXBlLnRyaW0oKVxucmVxdWlyZSgnLi9fc3RyaW5nLXRyaW0nKSgndHJpbScsIGZ1bmN0aW9uICgkdHJpbSkge1xuICByZXR1cm4gZnVuY3Rpb24gdHJpbSgpIHtcbiAgICByZXR1cm4gJHRyaW0odGhpcywgMyk7XG4gIH07XG59KTtcbiIsIid1c2Ugc3RyaWN0Jztcbi8vIEVDTUFTY3JpcHQgNiBzeW1ib2xzIHNoaW1cbnZhciBnbG9iYWwgPSByZXF1aXJlKCcuL19nbG9iYWwnKTtcbnZhciBoYXMgPSByZXF1aXJlKCcuL19oYXMnKTtcbnZhciBERVNDUklQVE9SUyA9IHJlcXVpcmUoJy4vX2Rlc2NyaXB0b3JzJyk7XG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyIHJlZGVmaW5lID0gcmVxdWlyZSgnLi9fcmVkZWZpbmUnKTtcbnZhciBNRVRBID0gcmVxdWlyZSgnLi9fbWV0YScpLktFWTtcbnZhciAkZmFpbHMgPSByZXF1aXJlKCcuL19mYWlscycpO1xudmFyIHNoYXJlZCA9IHJlcXVpcmUoJy4vX3NoYXJlZCcpO1xudmFyIHNldFRvU3RyaW5nVGFnID0gcmVxdWlyZSgnLi9fc2V0LXRvLXN0cmluZy10YWcnKTtcbnZhciB1aWQgPSByZXF1aXJlKCcuL191aWQnKTtcbnZhciB3a3MgPSByZXF1aXJlKCcuL193a3MnKTtcbnZhciB3a3NFeHQgPSByZXF1aXJlKCcuL193a3MtZXh0Jyk7XG52YXIgd2tzRGVmaW5lID0gcmVxdWlyZSgnLi9fd2tzLWRlZmluZScpO1xudmFyIGVudW1LZXlzID0gcmVxdWlyZSgnLi9fZW51bS1rZXlzJyk7XG52YXIgaXNBcnJheSA9IHJlcXVpcmUoJy4vX2lzLWFycmF5Jyk7XG52YXIgYW5PYmplY3QgPSByZXF1aXJlKCcuL19hbi1vYmplY3QnKTtcbnZhciBpc09iamVjdCA9IHJlcXVpcmUoJy4vX2lzLW9iamVjdCcpO1xudmFyIHRvSU9iamVjdCA9IHJlcXVpcmUoJy4vX3RvLWlvYmplY3QnKTtcbnZhciB0b1ByaW1pdGl2ZSA9IHJlcXVpcmUoJy4vX3RvLXByaW1pdGl2ZScpO1xudmFyIGNyZWF0ZURlc2MgPSByZXF1aXJlKCcuL19wcm9wZXJ0eS1kZXNjJyk7XG52YXIgX2NyZWF0ZSA9IHJlcXVpcmUoJy4vX29iamVjdC1jcmVhdGUnKTtcbnZhciBnT1BORXh0ID0gcmVxdWlyZSgnLi9fb2JqZWN0LWdvcG4tZXh0Jyk7XG52YXIgJEdPUEQgPSByZXF1aXJlKCcuL19vYmplY3QtZ29wZCcpO1xudmFyICREUCA9IHJlcXVpcmUoJy4vX29iamVjdC1kcCcpO1xudmFyICRrZXlzID0gcmVxdWlyZSgnLi9fb2JqZWN0LWtleXMnKTtcbnZhciBnT1BEID0gJEdPUEQuZjtcbnZhciBkUCA9ICREUC5mO1xudmFyIGdPUE4gPSBnT1BORXh0LmY7XG52YXIgJFN5bWJvbCA9IGdsb2JhbC5TeW1ib2w7XG52YXIgJEpTT04gPSBnbG9iYWwuSlNPTjtcbnZhciBfc3RyaW5naWZ5ID0gJEpTT04gJiYgJEpTT04uc3RyaW5naWZ5O1xudmFyIFBST1RPVFlQRSA9ICdwcm90b3R5cGUnO1xudmFyIEhJRERFTiA9IHdrcygnX2hpZGRlbicpO1xudmFyIFRPX1BSSU1JVElWRSA9IHdrcygndG9QcmltaXRpdmUnKTtcbnZhciBpc0VudW0gPSB7fS5wcm9wZXJ0eUlzRW51bWVyYWJsZTtcbnZhciBTeW1ib2xSZWdpc3RyeSA9IHNoYXJlZCgnc3ltYm9sLXJlZ2lzdHJ5Jyk7XG52YXIgQWxsU3ltYm9scyA9IHNoYXJlZCgnc3ltYm9scycpO1xudmFyIE9QU3ltYm9scyA9IHNoYXJlZCgnb3Atc3ltYm9scycpO1xudmFyIE9iamVjdFByb3RvID0gT2JqZWN0W1BST1RPVFlQRV07XG52YXIgVVNFX05BVElWRSA9IHR5cGVvZiAkU3ltYm9sID09ICdmdW5jdGlvbic7XG52YXIgUU9iamVjdCA9IGdsb2JhbC5RT2JqZWN0O1xuLy8gRG9uJ3QgdXNlIHNldHRlcnMgaW4gUXQgU2NyaXB0LCBodHRwczovL2dpdGh1Yi5jb20vemxvaXJvY2svY29yZS1qcy9pc3N1ZXMvMTczXG52YXIgc2V0dGVyID0gIVFPYmplY3QgfHwgIVFPYmplY3RbUFJPVE9UWVBFXSB8fCAhUU9iamVjdFtQUk9UT1RZUEVdLmZpbmRDaGlsZDtcblxuLy8gZmFsbGJhY2sgZm9yIG9sZCBBbmRyb2lkLCBodHRwczovL2NvZGUuZ29vZ2xlLmNvbS9wL3Y4L2lzc3Vlcy9kZXRhaWw/aWQ9Njg3XG52YXIgc2V0U3ltYm9sRGVzYyA9IERFU0NSSVBUT1JTICYmICRmYWlscyhmdW5jdGlvbiAoKSB7XG4gIHJldHVybiBfY3JlYXRlKGRQKHt9LCAnYScsIHtcbiAgICBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGRQKHRoaXMsICdhJywgeyB2YWx1ZTogNyB9KS5hOyB9XG4gIH0pKS5hICE9IDc7XG59KSA/IGZ1bmN0aW9uIChpdCwga2V5LCBEKSB7XG4gIHZhciBwcm90b0Rlc2MgPSBnT1BEKE9iamVjdFByb3RvLCBrZXkpO1xuICBpZiAocHJvdG9EZXNjKSBkZWxldGUgT2JqZWN0UHJvdG9ba2V5XTtcbiAgZFAoaXQsIGtleSwgRCk7XG4gIGlmIChwcm90b0Rlc2MgJiYgaXQgIT09IE9iamVjdFByb3RvKSBkUChPYmplY3RQcm90bywga2V5LCBwcm90b0Rlc2MpO1xufSA6IGRQO1xuXG52YXIgd3JhcCA9IGZ1bmN0aW9uICh0YWcpIHtcbiAgdmFyIHN5bSA9IEFsbFN5bWJvbHNbdGFnXSA9IF9jcmVhdGUoJFN5bWJvbFtQUk9UT1RZUEVdKTtcbiAgc3ltLl9rID0gdGFnO1xuICByZXR1cm4gc3ltO1xufTtcblxudmFyIGlzU3ltYm9sID0gVVNFX05BVElWRSAmJiB0eXBlb2YgJFN5bWJvbC5pdGVyYXRvciA9PSAnc3ltYm9sJyA/IGZ1bmN0aW9uIChpdCkge1xuICByZXR1cm4gdHlwZW9mIGl0ID09ICdzeW1ib2wnO1xufSA6IGZ1bmN0aW9uIChpdCkge1xuICByZXR1cm4gaXQgaW5zdGFuY2VvZiAkU3ltYm9sO1xufTtcblxudmFyICRkZWZpbmVQcm9wZXJ0eSA9IGZ1bmN0aW9uIGRlZmluZVByb3BlcnR5KGl0LCBrZXksIEQpIHtcbiAgaWYgKGl0ID09PSBPYmplY3RQcm90bykgJGRlZmluZVByb3BlcnR5KE9QU3ltYm9scywga2V5LCBEKTtcbiAgYW5PYmplY3QoaXQpO1xuICBrZXkgPSB0b1ByaW1pdGl2ZShrZXksIHRydWUpO1xuICBhbk9iamVjdChEKTtcbiAgaWYgKGhhcyhBbGxTeW1ib2xzLCBrZXkpKSB7XG4gICAgaWYgKCFELmVudW1lcmFibGUpIHtcbiAgICAgIGlmICghaGFzKGl0LCBISURERU4pKSBkUChpdCwgSElEREVOLCBjcmVhdGVEZXNjKDEsIHt9KSk7XG4gICAgICBpdFtISURERU5dW2tleV0gPSB0cnVlO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoaGFzKGl0LCBISURERU4pICYmIGl0W0hJRERFTl1ba2V5XSkgaXRbSElEREVOXVtrZXldID0gZmFsc2U7XG4gICAgICBEID0gX2NyZWF0ZShELCB7IGVudW1lcmFibGU6IGNyZWF0ZURlc2MoMCwgZmFsc2UpIH0pO1xuICAgIH0gcmV0dXJuIHNldFN5bWJvbERlc2MoaXQsIGtleSwgRCk7XG4gIH0gcmV0dXJuIGRQKGl0LCBrZXksIEQpO1xufTtcbnZhciAkZGVmaW5lUHJvcGVydGllcyA9IGZ1bmN0aW9uIGRlZmluZVByb3BlcnRpZXMoaXQsIFApIHtcbiAgYW5PYmplY3QoaXQpO1xuICB2YXIga2V5cyA9IGVudW1LZXlzKFAgPSB0b0lPYmplY3QoUCkpO1xuICB2YXIgaSA9IDA7XG4gIHZhciBsID0ga2V5cy5sZW5ndGg7XG4gIHZhciBrZXk7XG4gIHdoaWxlIChsID4gaSkgJGRlZmluZVByb3BlcnR5KGl0LCBrZXkgPSBrZXlzW2krK10sIFBba2V5XSk7XG4gIHJldHVybiBpdDtcbn07XG52YXIgJGNyZWF0ZSA9IGZ1bmN0aW9uIGNyZWF0ZShpdCwgUCkge1xuICByZXR1cm4gUCA9PT0gdW5kZWZpbmVkID8gX2NyZWF0ZShpdCkgOiAkZGVmaW5lUHJvcGVydGllcyhfY3JlYXRlKGl0KSwgUCk7XG59O1xudmFyICRwcm9wZXJ0eUlzRW51bWVyYWJsZSA9IGZ1bmN0aW9uIHByb3BlcnR5SXNFbnVtZXJhYmxlKGtleSkge1xuICB2YXIgRSA9IGlzRW51bS5jYWxsKHRoaXMsIGtleSA9IHRvUHJpbWl0aXZlKGtleSwgdHJ1ZSkpO1xuICBpZiAodGhpcyA9PT0gT2JqZWN0UHJvdG8gJiYgaGFzKEFsbFN5bWJvbHMsIGtleSkgJiYgIWhhcyhPUFN5bWJvbHMsIGtleSkpIHJldHVybiBmYWxzZTtcbiAgcmV0dXJuIEUgfHwgIWhhcyh0aGlzLCBrZXkpIHx8ICFoYXMoQWxsU3ltYm9scywga2V5KSB8fCBoYXModGhpcywgSElEREVOKSAmJiB0aGlzW0hJRERFTl1ba2V5XSA/IEUgOiB0cnVlO1xufTtcbnZhciAkZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yID0gZnVuY3Rpb24gZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKGl0LCBrZXkpIHtcbiAgaXQgPSB0b0lPYmplY3QoaXQpO1xuICBrZXkgPSB0b1ByaW1pdGl2ZShrZXksIHRydWUpO1xuICBpZiAoaXQgPT09IE9iamVjdFByb3RvICYmIGhhcyhBbGxTeW1ib2xzLCBrZXkpICYmICFoYXMoT1BTeW1ib2xzLCBrZXkpKSByZXR1cm47XG4gIHZhciBEID0gZ09QRChpdCwga2V5KTtcbiAgaWYgKEQgJiYgaGFzKEFsbFN5bWJvbHMsIGtleSkgJiYgIShoYXMoaXQsIEhJRERFTikgJiYgaXRbSElEREVOXVtrZXldKSkgRC5lbnVtZXJhYmxlID0gdHJ1ZTtcbiAgcmV0dXJuIEQ7XG59O1xudmFyICRnZXRPd25Qcm9wZXJ0eU5hbWVzID0gZnVuY3Rpb24gZ2V0T3duUHJvcGVydHlOYW1lcyhpdCkge1xuICB2YXIgbmFtZXMgPSBnT1BOKHRvSU9iamVjdChpdCkpO1xuICB2YXIgcmVzdWx0ID0gW107XG4gIHZhciBpID0gMDtcbiAgdmFyIGtleTtcbiAgd2hpbGUgKG5hbWVzLmxlbmd0aCA+IGkpIHtcbiAgICBpZiAoIWhhcyhBbGxTeW1ib2xzLCBrZXkgPSBuYW1lc1tpKytdKSAmJiBrZXkgIT0gSElEREVOICYmIGtleSAhPSBNRVRBKSByZXN1bHQucHVzaChrZXkpO1xuICB9IHJldHVybiByZXN1bHQ7XG59O1xudmFyICRnZXRPd25Qcm9wZXJ0eVN5bWJvbHMgPSBmdW5jdGlvbiBnZXRPd25Qcm9wZXJ0eVN5bWJvbHMoaXQpIHtcbiAgdmFyIElTX09QID0gaXQgPT09IE9iamVjdFByb3RvO1xuICB2YXIgbmFtZXMgPSBnT1BOKElTX09QID8gT1BTeW1ib2xzIDogdG9JT2JqZWN0KGl0KSk7XG4gIHZhciByZXN1bHQgPSBbXTtcbiAgdmFyIGkgPSAwO1xuICB2YXIga2V5O1xuICB3aGlsZSAobmFtZXMubGVuZ3RoID4gaSkge1xuICAgIGlmIChoYXMoQWxsU3ltYm9scywga2V5ID0gbmFtZXNbaSsrXSkgJiYgKElTX09QID8gaGFzKE9iamVjdFByb3RvLCBrZXkpIDogdHJ1ZSkpIHJlc3VsdC5wdXNoKEFsbFN5bWJvbHNba2V5XSk7XG4gIH0gcmV0dXJuIHJlc3VsdDtcbn07XG5cbi8vIDE5LjQuMS4xIFN5bWJvbChbZGVzY3JpcHRpb25dKVxuaWYgKCFVU0VfTkFUSVZFKSB7XG4gICRTeW1ib2wgPSBmdW5jdGlvbiBTeW1ib2woKSB7XG4gICAgaWYgKHRoaXMgaW5zdGFuY2VvZiAkU3ltYm9sKSB0aHJvdyBUeXBlRXJyb3IoJ1N5bWJvbCBpcyBub3QgYSBjb25zdHJ1Y3RvciEnKTtcbiAgICB2YXIgdGFnID0gdWlkKGFyZ3VtZW50cy5sZW5ndGggPiAwID8gYXJndW1lbnRzWzBdIDogdW5kZWZpbmVkKTtcbiAgICB2YXIgJHNldCA9IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgaWYgKHRoaXMgPT09IE9iamVjdFByb3RvKSAkc2V0LmNhbGwoT1BTeW1ib2xzLCB2YWx1ZSk7XG4gICAgICBpZiAoaGFzKHRoaXMsIEhJRERFTikgJiYgaGFzKHRoaXNbSElEREVOXSwgdGFnKSkgdGhpc1tISURERU5dW3RhZ10gPSBmYWxzZTtcbiAgICAgIHNldFN5bWJvbERlc2ModGhpcywgdGFnLCBjcmVhdGVEZXNjKDEsIHZhbHVlKSk7XG4gICAgfTtcbiAgICBpZiAoREVTQ1JJUFRPUlMgJiYgc2V0dGVyKSBzZXRTeW1ib2xEZXNjKE9iamVjdFByb3RvLCB0YWcsIHsgY29uZmlndXJhYmxlOiB0cnVlLCBzZXQ6ICRzZXQgfSk7XG4gICAgcmV0dXJuIHdyYXAodGFnKTtcbiAgfTtcbiAgcmVkZWZpbmUoJFN5bWJvbFtQUk9UT1RZUEVdLCAndG9TdHJpbmcnLCBmdW5jdGlvbiB0b1N0cmluZygpIHtcbiAgICByZXR1cm4gdGhpcy5faztcbiAgfSk7XG5cbiAgJEdPUEQuZiA9ICRnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3I7XG4gICREUC5mID0gJGRlZmluZVByb3BlcnR5O1xuICByZXF1aXJlKCcuL19vYmplY3QtZ29wbicpLmYgPSBnT1BORXh0LmYgPSAkZ2V0T3duUHJvcGVydHlOYW1lcztcbiAgcmVxdWlyZSgnLi9fb2JqZWN0LXBpZScpLmYgPSAkcHJvcGVydHlJc0VudW1lcmFibGU7XG4gIHJlcXVpcmUoJy4vX29iamVjdC1nb3BzJykuZiA9ICRnZXRPd25Qcm9wZXJ0eVN5bWJvbHM7XG5cbiAgaWYgKERFU0NSSVBUT1JTICYmICFyZXF1aXJlKCcuL19saWJyYXJ5JykpIHtcbiAgICByZWRlZmluZShPYmplY3RQcm90bywgJ3Byb3BlcnR5SXNFbnVtZXJhYmxlJywgJHByb3BlcnR5SXNFbnVtZXJhYmxlLCB0cnVlKTtcbiAgfVxuXG4gIHdrc0V4dC5mID0gZnVuY3Rpb24gKG5hbWUpIHtcbiAgICByZXR1cm4gd3JhcCh3a3MobmFtZSkpO1xuICB9O1xufVxuXG4kZXhwb3J0KCRleHBvcnQuRyArICRleHBvcnQuVyArICRleHBvcnQuRiAqICFVU0VfTkFUSVZFLCB7IFN5bWJvbDogJFN5bWJvbCB9KTtcblxuZm9yICh2YXIgZXM2U3ltYm9scyA9IChcbiAgLy8gMTkuNC4yLjIsIDE5LjQuMi4zLCAxOS40LjIuNCwgMTkuNC4yLjYsIDE5LjQuMi44LCAxOS40LjIuOSwgMTkuNC4yLjEwLCAxOS40LjIuMTEsIDE5LjQuMi4xMiwgMTkuNC4yLjEzLCAxOS40LjIuMTRcbiAgJ2hhc0luc3RhbmNlLGlzQ29uY2F0U3ByZWFkYWJsZSxpdGVyYXRvcixtYXRjaCxyZXBsYWNlLHNlYXJjaCxzcGVjaWVzLHNwbGl0LHRvUHJpbWl0aXZlLHRvU3RyaW5nVGFnLHVuc2NvcGFibGVzJ1xuKS5zcGxpdCgnLCcpLCBqID0gMDsgZXM2U3ltYm9scy5sZW5ndGggPiBqOyl3a3MoZXM2U3ltYm9sc1tqKytdKTtcblxuZm9yICh2YXIgd2VsbEtub3duU3ltYm9scyA9ICRrZXlzKHdrcy5zdG9yZSksIGsgPSAwOyB3ZWxsS25vd25TeW1ib2xzLmxlbmd0aCA+IGs7KSB3a3NEZWZpbmUod2VsbEtub3duU3ltYm9sc1trKytdKTtcblxuJGV4cG9ydCgkZXhwb3J0LlMgKyAkZXhwb3J0LkYgKiAhVVNFX05BVElWRSwgJ1N5bWJvbCcsIHtcbiAgLy8gMTkuNC4yLjEgU3ltYm9sLmZvcihrZXkpXG4gICdmb3InOiBmdW5jdGlvbiAoa2V5KSB7XG4gICAgcmV0dXJuIGhhcyhTeW1ib2xSZWdpc3RyeSwga2V5ICs9ICcnKVxuICAgICAgPyBTeW1ib2xSZWdpc3RyeVtrZXldXG4gICAgICA6IFN5bWJvbFJlZ2lzdHJ5W2tleV0gPSAkU3ltYm9sKGtleSk7XG4gIH0sXG4gIC8vIDE5LjQuMi41IFN5bWJvbC5rZXlGb3Ioc3ltKVxuICBrZXlGb3I6IGZ1bmN0aW9uIGtleUZvcihzeW0pIHtcbiAgICBpZiAoIWlzU3ltYm9sKHN5bSkpIHRocm93IFR5cGVFcnJvcihzeW0gKyAnIGlzIG5vdCBhIHN5bWJvbCEnKTtcbiAgICBmb3IgKHZhciBrZXkgaW4gU3ltYm9sUmVnaXN0cnkpIGlmIChTeW1ib2xSZWdpc3RyeVtrZXldID09PSBzeW0pIHJldHVybiBrZXk7XG4gIH0sXG4gIHVzZVNldHRlcjogZnVuY3Rpb24gKCkgeyBzZXR0ZXIgPSB0cnVlOyB9LFxuICB1c2VTaW1wbGU6IGZ1bmN0aW9uICgpIHsgc2V0dGVyID0gZmFsc2U7IH1cbn0pO1xuXG4kZXhwb3J0KCRleHBvcnQuUyArICRleHBvcnQuRiAqICFVU0VfTkFUSVZFLCAnT2JqZWN0Jywge1xuICAvLyAxOS4xLjIuMiBPYmplY3QuY3JlYXRlKE8gWywgUHJvcGVydGllc10pXG4gIGNyZWF0ZTogJGNyZWF0ZSxcbiAgLy8gMTkuMS4yLjQgT2JqZWN0LmRlZmluZVByb3BlcnR5KE8sIFAsIEF0dHJpYnV0ZXMpXG4gIGRlZmluZVByb3BlcnR5OiAkZGVmaW5lUHJvcGVydHksXG4gIC8vIDE5LjEuMi4zIE9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKE8sIFByb3BlcnRpZXMpXG4gIGRlZmluZVByb3BlcnRpZXM6ICRkZWZpbmVQcm9wZXJ0aWVzLFxuICAvLyAxOS4xLjIuNiBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKE8sIFApXG4gIGdldE93blByb3BlcnR5RGVzY3JpcHRvcjogJGdldE93blByb3BlcnR5RGVzY3JpcHRvcixcbiAgLy8gMTkuMS4yLjcgT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMoTylcbiAgZ2V0T3duUHJvcGVydHlOYW1lczogJGdldE93blByb3BlcnR5TmFtZXMsXG4gIC8vIDE5LjEuMi44IE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMoTylcbiAgZ2V0T3duUHJvcGVydHlTeW1ib2xzOiAkZ2V0T3duUHJvcGVydHlTeW1ib2xzXG59KTtcblxuLy8gMjQuMy4yIEpTT04uc3RyaW5naWZ5KHZhbHVlIFssIHJlcGxhY2VyIFssIHNwYWNlXV0pXG4kSlNPTiAmJiAkZXhwb3J0KCRleHBvcnQuUyArICRleHBvcnQuRiAqICghVVNFX05BVElWRSB8fCAkZmFpbHMoZnVuY3Rpb24gKCkge1xuICB2YXIgUyA9ICRTeW1ib2woKTtcbiAgLy8gTVMgRWRnZSBjb252ZXJ0cyBzeW1ib2wgdmFsdWVzIHRvIEpTT04gYXMge31cbiAgLy8gV2ViS2l0IGNvbnZlcnRzIHN5bWJvbCB2YWx1ZXMgdG8gSlNPTiBhcyBudWxsXG4gIC8vIFY4IHRocm93cyBvbiBib3hlZCBzeW1ib2xzXG4gIHJldHVybiBfc3RyaW5naWZ5KFtTXSkgIT0gJ1tudWxsXScgfHwgX3N0cmluZ2lmeSh7IGE6IFMgfSkgIT0gJ3t9JyB8fCBfc3RyaW5naWZ5KE9iamVjdChTKSkgIT0gJ3t9Jztcbn0pKSwgJ0pTT04nLCB7XG4gIHN0cmluZ2lmeTogZnVuY3Rpb24gc3RyaW5naWZ5KGl0KSB7XG4gICAgdmFyIGFyZ3MgPSBbaXRdO1xuICAgIHZhciBpID0gMTtcbiAgICB2YXIgcmVwbGFjZXIsICRyZXBsYWNlcjtcbiAgICB3aGlsZSAoYXJndW1lbnRzLmxlbmd0aCA+IGkpIGFyZ3MucHVzaChhcmd1bWVudHNbaSsrXSk7XG4gICAgJHJlcGxhY2VyID0gcmVwbGFjZXIgPSBhcmdzWzFdO1xuICAgIGlmICghaXNPYmplY3QocmVwbGFjZXIpICYmIGl0ID09PSB1bmRlZmluZWQgfHwgaXNTeW1ib2woaXQpKSByZXR1cm47IC8vIElFOCByZXR1cm5zIHN0cmluZyBvbiB1bmRlZmluZWRcbiAgICBpZiAoIWlzQXJyYXkocmVwbGFjZXIpKSByZXBsYWNlciA9IGZ1bmN0aW9uIChrZXksIHZhbHVlKSB7XG4gICAgICBpZiAodHlwZW9mICRyZXBsYWNlciA9PSAnZnVuY3Rpb24nKSB2YWx1ZSA9ICRyZXBsYWNlci5jYWxsKHRoaXMsIGtleSwgdmFsdWUpO1xuICAgICAgaWYgKCFpc1N5bWJvbCh2YWx1ZSkpIHJldHVybiB2YWx1ZTtcbiAgICB9O1xuICAgIGFyZ3NbMV0gPSByZXBsYWNlcjtcbiAgICByZXR1cm4gX3N0cmluZ2lmeS5hcHBseSgkSlNPTiwgYXJncyk7XG4gIH1cbn0pO1xuXG4vLyAxOS40LjMuNCBTeW1ib2wucHJvdG90eXBlW0BAdG9QcmltaXRpdmVdKGhpbnQpXG4kU3ltYm9sW1BST1RPVFlQRV1bVE9fUFJJTUlUSVZFXSB8fCByZXF1aXJlKCcuL19oaWRlJykoJFN5bWJvbFtQUk9UT1RZUEVdLCBUT19QUklNSVRJVkUsICRTeW1ib2xbUFJPVE9UWVBFXS52YWx1ZU9mKTtcbi8vIDE5LjQuMy41IFN5bWJvbC5wcm90b3R5cGVbQEB0b1N0cmluZ1RhZ11cbnNldFRvU3RyaW5nVGFnKCRTeW1ib2wsICdTeW1ib2wnKTtcbi8vIDIwLjIuMS45IE1hdGhbQEB0b1N0cmluZ1RhZ11cbnNldFRvU3RyaW5nVGFnKE1hdGgsICdNYXRoJywgdHJ1ZSk7XG4vLyAyNC4zLjMgSlNPTltAQHRvU3RyaW5nVGFnXVxuc2V0VG9TdHJpbmdUYWcoZ2xvYmFsLkpTT04sICdKU09OJywgdHJ1ZSk7XG4iLCIndXNlIHN0cmljdCc7XG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyICR0eXBlZCA9IHJlcXVpcmUoJy4vX3R5cGVkJyk7XG52YXIgYnVmZmVyID0gcmVxdWlyZSgnLi9fdHlwZWQtYnVmZmVyJyk7XG52YXIgYW5PYmplY3QgPSByZXF1aXJlKCcuL19hbi1vYmplY3QnKTtcbnZhciB0b0Fic29sdXRlSW5kZXggPSByZXF1aXJlKCcuL190by1hYnNvbHV0ZS1pbmRleCcpO1xudmFyIHRvTGVuZ3RoID0gcmVxdWlyZSgnLi9fdG8tbGVuZ3RoJyk7XG52YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuL19pcy1vYmplY3QnKTtcbnZhciBBcnJheUJ1ZmZlciA9IHJlcXVpcmUoJy4vX2dsb2JhbCcpLkFycmF5QnVmZmVyO1xudmFyIHNwZWNpZXNDb25zdHJ1Y3RvciA9IHJlcXVpcmUoJy4vX3NwZWNpZXMtY29uc3RydWN0b3InKTtcbnZhciAkQXJyYXlCdWZmZXIgPSBidWZmZXIuQXJyYXlCdWZmZXI7XG52YXIgJERhdGFWaWV3ID0gYnVmZmVyLkRhdGFWaWV3O1xudmFyICRpc1ZpZXcgPSAkdHlwZWQuQUJWICYmIEFycmF5QnVmZmVyLmlzVmlldztcbnZhciAkc2xpY2UgPSAkQXJyYXlCdWZmZXIucHJvdG90eXBlLnNsaWNlO1xudmFyIFZJRVcgPSAkdHlwZWQuVklFVztcbnZhciBBUlJBWV9CVUZGRVIgPSAnQXJyYXlCdWZmZXInO1xuXG4kZXhwb3J0KCRleHBvcnQuRyArICRleHBvcnQuVyArICRleHBvcnQuRiAqIChBcnJheUJ1ZmZlciAhPT0gJEFycmF5QnVmZmVyKSwgeyBBcnJheUJ1ZmZlcjogJEFycmF5QnVmZmVyIH0pO1xuXG4kZXhwb3J0KCRleHBvcnQuUyArICRleHBvcnQuRiAqICEkdHlwZWQuQ09OU1RSLCBBUlJBWV9CVUZGRVIsIHtcbiAgLy8gMjQuMS4zLjEgQXJyYXlCdWZmZXIuaXNWaWV3KGFyZylcbiAgaXNWaWV3OiBmdW5jdGlvbiBpc1ZpZXcoaXQpIHtcbiAgICByZXR1cm4gJGlzVmlldyAmJiAkaXNWaWV3KGl0KSB8fCBpc09iamVjdChpdCkgJiYgVklFVyBpbiBpdDtcbiAgfVxufSk7XG5cbiRleHBvcnQoJGV4cG9ydC5QICsgJGV4cG9ydC5VICsgJGV4cG9ydC5GICogcmVxdWlyZSgnLi9fZmFpbHMnKShmdW5jdGlvbiAoKSB7XG4gIHJldHVybiAhbmV3ICRBcnJheUJ1ZmZlcigyKS5zbGljZSgxLCB1bmRlZmluZWQpLmJ5dGVMZW5ndGg7XG59KSwgQVJSQVlfQlVGRkVSLCB7XG4gIC8vIDI0LjEuNC4zIEFycmF5QnVmZmVyLnByb3RvdHlwZS5zbGljZShzdGFydCwgZW5kKVxuICBzbGljZTogZnVuY3Rpb24gc2xpY2Uoc3RhcnQsIGVuZCkge1xuICAgIGlmICgkc2xpY2UgIT09IHVuZGVmaW5lZCAmJiBlbmQgPT09IHVuZGVmaW5lZCkgcmV0dXJuICRzbGljZS5jYWxsKGFuT2JqZWN0KHRoaXMpLCBzdGFydCk7IC8vIEZGIGZpeFxuICAgIHZhciBsZW4gPSBhbk9iamVjdCh0aGlzKS5ieXRlTGVuZ3RoO1xuICAgIHZhciBmaXJzdCA9IHRvQWJzb2x1dGVJbmRleChzdGFydCwgbGVuKTtcbiAgICB2YXIgZmluID0gdG9BYnNvbHV0ZUluZGV4KGVuZCA9PT0gdW5kZWZpbmVkID8gbGVuIDogZW5kLCBsZW4pO1xuICAgIHZhciByZXN1bHQgPSBuZXcgKHNwZWNpZXNDb25zdHJ1Y3Rvcih0aGlzLCAkQXJyYXlCdWZmZXIpKSh0b0xlbmd0aChmaW4gLSBmaXJzdCkpO1xuICAgIHZhciB2aWV3UyA9IG5ldyAkRGF0YVZpZXcodGhpcyk7XG4gICAgdmFyIHZpZXdUID0gbmV3ICREYXRhVmlldyhyZXN1bHQpO1xuICAgIHZhciBpbmRleCA9IDA7XG4gICAgd2hpbGUgKGZpcnN0IDwgZmluKSB7XG4gICAgICB2aWV3VC5zZXRVaW50OChpbmRleCsrLCB2aWV3Uy5nZXRVaW50OChmaXJzdCsrKSk7XG4gICAgfSByZXR1cm4gcmVzdWx0O1xuICB9XG59KTtcblxucmVxdWlyZSgnLi9fc2V0LXNwZWNpZXMnKShBUlJBWV9CVUZGRVIpO1xuIiwidmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbiRleHBvcnQoJGV4cG9ydC5HICsgJGV4cG9ydC5XICsgJGV4cG9ydC5GICogIXJlcXVpcmUoJy4vX3R5cGVkJykuQUJWLCB7XG4gIERhdGFWaWV3OiByZXF1aXJlKCcuL190eXBlZC1idWZmZXInKS5EYXRhVmlld1xufSk7XG4iLCJyZXF1aXJlKCcuL190eXBlZC1hcnJheScpKCdGbG9hdDMyJywgNCwgZnVuY3Rpb24gKGluaXQpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIEZsb2F0MzJBcnJheShkYXRhLCBieXRlT2Zmc2V0LCBsZW5ndGgpIHtcbiAgICByZXR1cm4gaW5pdCh0aGlzLCBkYXRhLCBieXRlT2Zmc2V0LCBsZW5ndGgpO1xuICB9O1xufSk7XG4iLCJyZXF1aXJlKCcuL190eXBlZC1hcnJheScpKCdGbG9hdDY0JywgOCwgZnVuY3Rpb24gKGluaXQpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIEZsb2F0NjRBcnJheShkYXRhLCBieXRlT2Zmc2V0LCBsZW5ndGgpIHtcbiAgICByZXR1cm4gaW5pdCh0aGlzLCBkYXRhLCBieXRlT2Zmc2V0LCBsZW5ndGgpO1xuICB9O1xufSk7XG4iLCJyZXF1aXJlKCcuL190eXBlZC1hcnJheScpKCdJbnQxNicsIDIsIGZ1bmN0aW9uIChpbml0KSB7XG4gIHJldHVybiBmdW5jdGlvbiBJbnQxNkFycmF5KGRhdGEsIGJ5dGVPZmZzZXQsIGxlbmd0aCkge1xuICAgIHJldHVybiBpbml0KHRoaXMsIGRhdGEsIGJ5dGVPZmZzZXQsIGxlbmd0aCk7XG4gIH07XG59KTtcbiIsInJlcXVpcmUoJy4vX3R5cGVkLWFycmF5JykoJ0ludDMyJywgNCwgZnVuY3Rpb24gKGluaXQpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIEludDMyQXJyYXkoZGF0YSwgYnl0ZU9mZnNldCwgbGVuZ3RoKSB7XG4gICAgcmV0dXJuIGluaXQodGhpcywgZGF0YSwgYnl0ZU9mZnNldCwgbGVuZ3RoKTtcbiAgfTtcbn0pO1xuIiwicmVxdWlyZSgnLi9fdHlwZWQtYXJyYXknKSgnSW50OCcsIDEsIGZ1bmN0aW9uIChpbml0KSB7XG4gIHJldHVybiBmdW5jdGlvbiBJbnQ4QXJyYXkoZGF0YSwgYnl0ZU9mZnNldCwgbGVuZ3RoKSB7XG4gICAgcmV0dXJuIGluaXQodGhpcywgZGF0YSwgYnl0ZU9mZnNldCwgbGVuZ3RoKTtcbiAgfTtcbn0pO1xuIiwicmVxdWlyZSgnLi9fdHlwZWQtYXJyYXknKSgnVWludDE2JywgMiwgZnVuY3Rpb24gKGluaXQpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIFVpbnQxNkFycmF5KGRhdGEsIGJ5dGVPZmZzZXQsIGxlbmd0aCkge1xuICAgIHJldHVybiBpbml0KHRoaXMsIGRhdGEsIGJ5dGVPZmZzZXQsIGxlbmd0aCk7XG4gIH07XG59KTtcbiIsInJlcXVpcmUoJy4vX3R5cGVkLWFycmF5JykoJ1VpbnQzMicsIDQsIGZ1bmN0aW9uIChpbml0KSB7XG4gIHJldHVybiBmdW5jdGlvbiBVaW50MzJBcnJheShkYXRhLCBieXRlT2Zmc2V0LCBsZW5ndGgpIHtcbiAgICByZXR1cm4gaW5pdCh0aGlzLCBkYXRhLCBieXRlT2Zmc2V0LCBsZW5ndGgpO1xuICB9O1xufSk7XG4iLCJyZXF1aXJlKCcuL190eXBlZC1hcnJheScpKCdVaW50OCcsIDEsIGZ1bmN0aW9uIChpbml0KSB7XG4gIHJldHVybiBmdW5jdGlvbiBVaW50OEFycmF5KGRhdGEsIGJ5dGVPZmZzZXQsIGxlbmd0aCkge1xuICAgIHJldHVybiBpbml0KHRoaXMsIGRhdGEsIGJ5dGVPZmZzZXQsIGxlbmd0aCk7XG4gIH07XG59KTtcbiIsInJlcXVpcmUoJy4vX3R5cGVkLWFycmF5JykoJ1VpbnQ4JywgMSwgZnVuY3Rpb24gKGluaXQpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIFVpbnQ4Q2xhbXBlZEFycmF5KGRhdGEsIGJ5dGVPZmZzZXQsIGxlbmd0aCkge1xuICAgIHJldHVybiBpbml0KHRoaXMsIGRhdGEsIGJ5dGVPZmZzZXQsIGxlbmd0aCk7XG4gIH07XG59LCB0cnVlKTtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciBlYWNoID0gcmVxdWlyZSgnLi9fYXJyYXktbWV0aG9kcycpKDApO1xudmFyIHJlZGVmaW5lID0gcmVxdWlyZSgnLi9fcmVkZWZpbmUnKTtcbnZhciBtZXRhID0gcmVxdWlyZSgnLi9fbWV0YScpO1xudmFyIGFzc2lnbiA9IHJlcXVpcmUoJy4vX29iamVjdC1hc3NpZ24nKTtcbnZhciB3ZWFrID0gcmVxdWlyZSgnLi9fY29sbGVjdGlvbi13ZWFrJyk7XG52YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuL19pcy1vYmplY3QnKTtcbnZhciBmYWlscyA9IHJlcXVpcmUoJy4vX2ZhaWxzJyk7XG52YXIgdmFsaWRhdGUgPSByZXF1aXJlKCcuL192YWxpZGF0ZS1jb2xsZWN0aW9uJyk7XG52YXIgV0VBS19NQVAgPSAnV2Vha01hcCc7XG52YXIgZ2V0V2VhayA9IG1ldGEuZ2V0V2VhaztcbnZhciBpc0V4dGVuc2libGUgPSBPYmplY3QuaXNFeHRlbnNpYmxlO1xudmFyIHVuY2F1Z2h0RnJvemVuU3RvcmUgPSB3ZWFrLnVmc3RvcmU7XG52YXIgdG1wID0ge307XG52YXIgSW50ZXJuYWxNYXA7XG5cbnZhciB3cmFwcGVyID0gZnVuY3Rpb24gKGdldCkge1xuICByZXR1cm4gZnVuY3Rpb24gV2Vha01hcCgpIHtcbiAgICByZXR1cm4gZ2V0KHRoaXMsIGFyZ3VtZW50cy5sZW5ndGggPiAwID8gYXJndW1lbnRzWzBdIDogdW5kZWZpbmVkKTtcbiAgfTtcbn07XG5cbnZhciBtZXRob2RzID0ge1xuICAvLyAyMy4zLjMuMyBXZWFrTWFwLnByb3RvdHlwZS5nZXQoa2V5KVxuICBnZXQ6IGZ1bmN0aW9uIGdldChrZXkpIHtcbiAgICBpZiAoaXNPYmplY3Qoa2V5KSkge1xuICAgICAgdmFyIGRhdGEgPSBnZXRXZWFrKGtleSk7XG4gICAgICBpZiAoZGF0YSA9PT0gdHJ1ZSkgcmV0dXJuIHVuY2F1Z2h0RnJvemVuU3RvcmUodmFsaWRhdGUodGhpcywgV0VBS19NQVApKS5nZXQoa2V5KTtcbiAgICAgIHJldHVybiBkYXRhID8gZGF0YVt0aGlzLl9pXSA6IHVuZGVmaW5lZDtcbiAgICB9XG4gIH0sXG4gIC8vIDIzLjMuMy41IFdlYWtNYXAucHJvdG90eXBlLnNldChrZXksIHZhbHVlKVxuICBzZXQ6IGZ1bmN0aW9uIHNldChrZXksIHZhbHVlKSB7XG4gICAgcmV0dXJuIHdlYWsuZGVmKHZhbGlkYXRlKHRoaXMsIFdFQUtfTUFQKSwga2V5LCB2YWx1ZSk7XG4gIH1cbn07XG5cbi8vIDIzLjMgV2Vha01hcCBPYmplY3RzXG52YXIgJFdlYWtNYXAgPSBtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vX2NvbGxlY3Rpb24nKShXRUFLX01BUCwgd3JhcHBlciwgbWV0aG9kcywgd2VhaywgdHJ1ZSwgdHJ1ZSk7XG5cbi8vIElFMTEgV2Vha01hcCBmcm96ZW4ga2V5cyBmaXhcbmlmIChmYWlscyhmdW5jdGlvbiAoKSB7IHJldHVybiBuZXcgJFdlYWtNYXAoKS5zZXQoKE9iamVjdC5mcmVlemUgfHwgT2JqZWN0KSh0bXApLCA3KS5nZXQodG1wKSAhPSA3OyB9KSkge1xuICBJbnRlcm5hbE1hcCA9IHdlYWsuZ2V0Q29uc3RydWN0b3Iod3JhcHBlciwgV0VBS19NQVApO1xuICBhc3NpZ24oSW50ZXJuYWxNYXAucHJvdG90eXBlLCBtZXRob2RzKTtcbiAgbWV0YS5ORUVEID0gdHJ1ZTtcbiAgZWFjaChbJ2RlbGV0ZScsICdoYXMnLCAnZ2V0JywgJ3NldCddLCBmdW5jdGlvbiAoa2V5KSB7XG4gICAgdmFyIHByb3RvID0gJFdlYWtNYXAucHJvdG90eXBlO1xuICAgIHZhciBtZXRob2QgPSBwcm90b1trZXldO1xuICAgIHJlZGVmaW5lKHByb3RvLCBrZXksIGZ1bmN0aW9uIChhLCBiKSB7XG4gICAgICAvLyBzdG9yZSBmcm96ZW4gb2JqZWN0cyBvbiBpbnRlcm5hbCB3ZWFrbWFwIHNoaW1cbiAgICAgIGlmIChpc09iamVjdChhKSAmJiAhaXNFeHRlbnNpYmxlKGEpKSB7XG4gICAgICAgIGlmICghdGhpcy5fZikgdGhpcy5fZiA9IG5ldyBJbnRlcm5hbE1hcCgpO1xuICAgICAgICB2YXIgcmVzdWx0ID0gdGhpcy5fZltrZXldKGEsIGIpO1xuICAgICAgICByZXR1cm4ga2V5ID09ICdzZXQnID8gdGhpcyA6IHJlc3VsdDtcbiAgICAgIC8vIHN0b3JlIGFsbCB0aGUgcmVzdCBvbiBuYXRpdmUgd2Vha21hcFxuICAgICAgfSByZXR1cm4gbWV0aG9kLmNhbGwodGhpcywgYSwgYik7XG4gICAgfSk7XG4gIH0pO1xufVxuIiwiJ3VzZSBzdHJpY3QnO1xudmFyIHdlYWsgPSByZXF1aXJlKCcuL19jb2xsZWN0aW9uLXdlYWsnKTtcbnZhciB2YWxpZGF0ZSA9IHJlcXVpcmUoJy4vX3ZhbGlkYXRlLWNvbGxlY3Rpb24nKTtcbnZhciBXRUFLX1NFVCA9ICdXZWFrU2V0JztcblxuLy8gMjMuNCBXZWFrU2V0IE9iamVjdHNcbnJlcXVpcmUoJy4vX2NvbGxlY3Rpb24nKShXRUFLX1NFVCwgZnVuY3Rpb24gKGdldCkge1xuICByZXR1cm4gZnVuY3Rpb24gV2Vha1NldCgpIHsgcmV0dXJuIGdldCh0aGlzLCBhcmd1bWVudHMubGVuZ3RoID4gMCA/IGFyZ3VtZW50c1swXSA6IHVuZGVmaW5lZCk7IH07XG59LCB7XG4gIC8vIDIzLjQuMy4xIFdlYWtTZXQucHJvdG90eXBlLmFkZCh2YWx1ZSlcbiAgYWRkOiBmdW5jdGlvbiBhZGQodmFsdWUpIHtcbiAgICByZXR1cm4gd2Vhay5kZWYodmFsaWRhdGUodGhpcywgV0VBS19TRVQpLCB2YWx1ZSwgdHJ1ZSk7XG4gIH1cbn0sIHdlYWssIGZhbHNlLCB0cnVlKTtcbiIsIid1c2Ugc3RyaWN0Jztcbi8vIGh0dHBzOi8vZ2l0aHViLmNvbS90YzM5L0FycmF5LnByb3RvdHlwZS5pbmNsdWRlc1xudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciAkaW5jbHVkZXMgPSByZXF1aXJlKCcuL19hcnJheS1pbmNsdWRlcycpKHRydWUpO1xuXG4kZXhwb3J0KCRleHBvcnQuUCwgJ0FycmF5Jywge1xuICBpbmNsdWRlczogZnVuY3Rpb24gaW5jbHVkZXMoZWwgLyogLCBmcm9tSW5kZXggPSAwICovKSB7XG4gICAgcmV0dXJuICRpbmNsdWRlcyh0aGlzLCBlbCwgYXJndW1lbnRzLmxlbmd0aCA+IDEgPyBhcmd1bWVudHNbMV0gOiB1bmRlZmluZWQpO1xuICB9XG59KTtcblxucmVxdWlyZSgnLi9fYWRkLXRvLXVuc2NvcGFibGVzJykoJ2luY2x1ZGVzJyk7XG4iLCIvLyBodHRwczovL2dpdGh1Yi5jb20vdGMzOS9wcm9wb3NhbC1vYmplY3QtdmFsdWVzLWVudHJpZXNcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgJGVudHJpZXMgPSByZXF1aXJlKCcuL19vYmplY3QtdG8tYXJyYXknKSh0cnVlKTtcblxuJGV4cG9ydCgkZXhwb3J0LlMsICdPYmplY3QnLCB7XG4gIGVudHJpZXM6IGZ1bmN0aW9uIGVudHJpZXMoaXQpIHtcbiAgICByZXR1cm4gJGVudHJpZXMoaXQpO1xuICB9XG59KTtcbiIsIi8vIGh0dHBzOi8vZ2l0aHViLmNvbS90YzM5L3Byb3Bvc2FsLW9iamVjdC1nZXRvd25wcm9wZXJ0eWRlc2NyaXB0b3JzXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyIG93bktleXMgPSByZXF1aXJlKCcuL19vd24ta2V5cycpO1xudmFyIHRvSU9iamVjdCA9IHJlcXVpcmUoJy4vX3RvLWlvYmplY3QnKTtcbnZhciBnT1BEID0gcmVxdWlyZSgnLi9fb2JqZWN0LWdvcGQnKTtcbnZhciBjcmVhdGVQcm9wZXJ0eSA9IHJlcXVpcmUoJy4vX2NyZWF0ZS1wcm9wZXJ0eScpO1xuXG4kZXhwb3J0KCRleHBvcnQuUywgJ09iamVjdCcsIHtcbiAgZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yczogZnVuY3Rpb24gZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9ycyhvYmplY3QpIHtcbiAgICB2YXIgTyA9IHRvSU9iamVjdChvYmplY3QpO1xuICAgIHZhciBnZXREZXNjID0gZ09QRC5mO1xuICAgIHZhciBrZXlzID0gb3duS2V5cyhPKTtcbiAgICB2YXIgcmVzdWx0ID0ge307XG4gICAgdmFyIGkgPSAwO1xuICAgIHZhciBrZXksIGRlc2M7XG4gICAgd2hpbGUgKGtleXMubGVuZ3RoID4gaSkge1xuICAgICAgZGVzYyA9IGdldERlc2MoTywga2V5ID0ga2V5c1tpKytdKTtcbiAgICAgIGlmIChkZXNjICE9PSB1bmRlZmluZWQpIGNyZWF0ZVByb3BlcnR5KHJlc3VsdCwga2V5LCBkZXNjKTtcbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxufSk7XG4iLCIvLyBodHRwczovL2dpdGh1Yi5jb20vdGMzOS9wcm9wb3NhbC1vYmplY3QtdmFsdWVzLWVudHJpZXNcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgJHZhbHVlcyA9IHJlcXVpcmUoJy4vX29iamVjdC10by1hcnJheScpKGZhbHNlKTtcblxuJGV4cG9ydCgkZXhwb3J0LlMsICdPYmplY3QnLCB7XG4gIHZhbHVlczogZnVuY3Rpb24gdmFsdWVzKGl0KSB7XG4gICAgcmV0dXJuICR2YWx1ZXMoaXQpO1xuICB9XG59KTtcbiIsIi8vIGh0dHBzOi8vZ2l0aHViLmNvbS90YzM5L3Byb3Bvc2FsLXByb21pc2UtZmluYWxseVxuJ3VzZSBzdHJpY3QnO1xudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciBjb3JlID0gcmVxdWlyZSgnLi9fY29yZScpO1xudmFyIGdsb2JhbCA9IHJlcXVpcmUoJy4vX2dsb2JhbCcpO1xudmFyIHNwZWNpZXNDb25zdHJ1Y3RvciA9IHJlcXVpcmUoJy4vX3NwZWNpZXMtY29uc3RydWN0b3InKTtcbnZhciBwcm9taXNlUmVzb2x2ZSA9IHJlcXVpcmUoJy4vX3Byb21pc2UtcmVzb2x2ZScpO1xuXG4kZXhwb3J0KCRleHBvcnQuUCArICRleHBvcnQuUiwgJ1Byb21pc2UnLCB7ICdmaW5hbGx5JzogZnVuY3Rpb24gKG9uRmluYWxseSkge1xuICB2YXIgQyA9IHNwZWNpZXNDb25zdHJ1Y3Rvcih0aGlzLCBjb3JlLlByb21pc2UgfHwgZ2xvYmFsLlByb21pc2UpO1xuICB2YXIgaXNGdW5jdGlvbiA9IHR5cGVvZiBvbkZpbmFsbHkgPT0gJ2Z1bmN0aW9uJztcbiAgcmV0dXJuIHRoaXMudGhlbihcbiAgICBpc0Z1bmN0aW9uID8gZnVuY3Rpb24gKHgpIHtcbiAgICAgIHJldHVybiBwcm9taXNlUmVzb2x2ZShDLCBvbkZpbmFsbHkoKSkudGhlbihmdW5jdGlvbiAoKSB7IHJldHVybiB4OyB9KTtcbiAgICB9IDogb25GaW5hbGx5LFxuICAgIGlzRnVuY3Rpb24gPyBmdW5jdGlvbiAoZSkge1xuICAgICAgcmV0dXJuIHByb21pc2VSZXNvbHZlKEMsIG9uRmluYWxseSgpKS50aGVuKGZ1bmN0aW9uICgpIHsgdGhyb3cgZTsgfSk7XG4gICAgfSA6IG9uRmluYWxseVxuICApO1xufSB9KTtcbiIsIid1c2Ugc3RyaWN0Jztcbi8vIGh0dHBzOi8vZ2l0aHViLmNvbS90YzM5L3Byb3Bvc2FsLXN0cmluZy1wYWQtc3RhcnQtZW5kXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyICRwYWQgPSByZXF1aXJlKCcuL19zdHJpbmctcGFkJyk7XG52YXIgdXNlckFnZW50ID0gcmVxdWlyZSgnLi9fdXNlci1hZ2VudCcpO1xuXG4vLyBodHRwczovL2dpdGh1Yi5jb20vemxvaXJvY2svY29yZS1qcy9pc3N1ZXMvMjgwXG4kZXhwb3J0KCRleHBvcnQuUCArICRleHBvcnQuRiAqIC9WZXJzaW9uXFwvMTBcXC5cXGQrKFxcLlxcZCspPyBTYWZhcmlcXC8vLnRlc3QodXNlckFnZW50KSwgJ1N0cmluZycsIHtcbiAgcGFkRW5kOiBmdW5jdGlvbiBwYWRFbmQobWF4TGVuZ3RoIC8qICwgZmlsbFN0cmluZyA9ICcgJyAqLykge1xuICAgIHJldHVybiAkcGFkKHRoaXMsIG1heExlbmd0aCwgYXJndW1lbnRzLmxlbmd0aCA+IDEgPyBhcmd1bWVudHNbMV0gOiB1bmRlZmluZWQsIGZhbHNlKTtcbiAgfVxufSk7XG4iLCIndXNlIHN0cmljdCc7XG4vLyBodHRwczovL2dpdGh1Yi5jb20vdGMzOS9wcm9wb3NhbC1zdHJpbmctcGFkLXN0YXJ0LWVuZFxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciAkcGFkID0gcmVxdWlyZSgnLi9fc3RyaW5nLXBhZCcpO1xudmFyIHVzZXJBZ2VudCA9IHJlcXVpcmUoJy4vX3VzZXItYWdlbnQnKTtcblxuLy8gaHR0cHM6Ly9naXRodWIuY29tL3psb2lyb2NrL2NvcmUtanMvaXNzdWVzLzI4MFxuJGV4cG9ydCgkZXhwb3J0LlAgKyAkZXhwb3J0LkYgKiAvVmVyc2lvblxcLzEwXFwuXFxkKyhcXC5cXGQrKT8gU2FmYXJpXFwvLy50ZXN0KHVzZXJBZ2VudCksICdTdHJpbmcnLCB7XG4gIHBhZFN0YXJ0OiBmdW5jdGlvbiBwYWRTdGFydChtYXhMZW5ndGggLyogLCBmaWxsU3RyaW5nID0gJyAnICovKSB7XG4gICAgcmV0dXJuICRwYWQodGhpcywgbWF4TGVuZ3RoLCBhcmd1bWVudHMubGVuZ3RoID4gMSA/IGFyZ3VtZW50c1sxXSA6IHVuZGVmaW5lZCwgdHJ1ZSk7XG4gIH1cbn0pO1xuIiwicmVxdWlyZSgnLi9fd2tzLWRlZmluZScpKCdhc3luY0l0ZXJhdG9yJyk7XG4iLCJ2YXIgJGl0ZXJhdG9ycyA9IHJlcXVpcmUoJy4vZXM2LmFycmF5Lml0ZXJhdG9yJyk7XG52YXIgZ2V0S2V5cyA9IHJlcXVpcmUoJy4vX29iamVjdC1rZXlzJyk7XG52YXIgcmVkZWZpbmUgPSByZXF1aXJlKCcuL19yZWRlZmluZScpO1xudmFyIGdsb2JhbCA9IHJlcXVpcmUoJy4vX2dsb2JhbCcpO1xudmFyIGhpZGUgPSByZXF1aXJlKCcuL19oaWRlJyk7XG52YXIgSXRlcmF0b3JzID0gcmVxdWlyZSgnLi9faXRlcmF0b3JzJyk7XG52YXIgd2tzID0gcmVxdWlyZSgnLi9fd2tzJyk7XG52YXIgSVRFUkFUT1IgPSB3a3MoJ2l0ZXJhdG9yJyk7XG52YXIgVE9fU1RSSU5HX1RBRyA9IHdrcygndG9TdHJpbmdUYWcnKTtcbnZhciBBcnJheVZhbHVlcyA9IEl0ZXJhdG9ycy5BcnJheTtcblxudmFyIERPTUl0ZXJhYmxlcyA9IHtcbiAgQ1NTUnVsZUxpc3Q6IHRydWUsIC8vIFRPRE86IE5vdCBzcGVjIGNvbXBsaWFudCwgc2hvdWxkIGJlIGZhbHNlLlxuICBDU1NTdHlsZURlY2xhcmF0aW9uOiBmYWxzZSxcbiAgQ1NTVmFsdWVMaXN0OiBmYWxzZSxcbiAgQ2xpZW50UmVjdExpc3Q6IGZhbHNlLFxuICBET01SZWN0TGlzdDogZmFsc2UsXG4gIERPTVN0cmluZ0xpc3Q6IGZhbHNlLFxuICBET01Ub2tlbkxpc3Q6IHRydWUsXG4gIERhdGFUcmFuc2Zlckl0ZW1MaXN0OiBmYWxzZSxcbiAgRmlsZUxpc3Q6IGZhbHNlLFxuICBIVE1MQWxsQ29sbGVjdGlvbjogZmFsc2UsXG4gIEhUTUxDb2xsZWN0aW9uOiBmYWxzZSxcbiAgSFRNTEZvcm1FbGVtZW50OiBmYWxzZSxcbiAgSFRNTFNlbGVjdEVsZW1lbnQ6IGZhbHNlLFxuICBNZWRpYUxpc3Q6IHRydWUsIC8vIFRPRE86IE5vdCBzcGVjIGNvbXBsaWFudCwgc2hvdWxkIGJlIGZhbHNlLlxuICBNaW1lVHlwZUFycmF5OiBmYWxzZSxcbiAgTmFtZWROb2RlTWFwOiBmYWxzZSxcbiAgTm9kZUxpc3Q6IHRydWUsXG4gIFBhaW50UmVxdWVzdExpc3Q6IGZhbHNlLFxuICBQbHVnaW46IGZhbHNlLFxuICBQbHVnaW5BcnJheTogZmFsc2UsXG4gIFNWR0xlbmd0aExpc3Q6IGZhbHNlLFxuICBTVkdOdW1iZXJMaXN0OiBmYWxzZSxcbiAgU1ZHUGF0aFNlZ0xpc3Q6IGZhbHNlLFxuICBTVkdQb2ludExpc3Q6IGZhbHNlLFxuICBTVkdTdHJpbmdMaXN0OiBmYWxzZSxcbiAgU1ZHVHJhbnNmb3JtTGlzdDogZmFsc2UsXG4gIFNvdXJjZUJ1ZmZlckxpc3Q6IGZhbHNlLFxuICBTdHlsZVNoZWV0TGlzdDogdHJ1ZSwgLy8gVE9ETzogTm90IHNwZWMgY29tcGxpYW50LCBzaG91bGQgYmUgZmFsc2UuXG4gIFRleHRUcmFja0N1ZUxpc3Q6IGZhbHNlLFxuICBUZXh0VHJhY2tMaXN0OiBmYWxzZSxcbiAgVG91Y2hMaXN0OiBmYWxzZVxufTtcblxuZm9yICh2YXIgY29sbGVjdGlvbnMgPSBnZXRLZXlzKERPTUl0ZXJhYmxlcyksIGkgPSAwOyBpIDwgY29sbGVjdGlvbnMubGVuZ3RoOyBpKyspIHtcbiAgdmFyIE5BTUUgPSBjb2xsZWN0aW9uc1tpXTtcbiAgdmFyIGV4cGxpY2l0ID0gRE9NSXRlcmFibGVzW05BTUVdO1xuICB2YXIgQ29sbGVjdGlvbiA9IGdsb2JhbFtOQU1FXTtcbiAgdmFyIHByb3RvID0gQ29sbGVjdGlvbiAmJiBDb2xsZWN0aW9uLnByb3RvdHlwZTtcbiAgdmFyIGtleTtcbiAgaWYgKHByb3RvKSB7XG4gICAgaWYgKCFwcm90b1tJVEVSQVRPUl0pIGhpZGUocHJvdG8sIElURVJBVE9SLCBBcnJheVZhbHVlcyk7XG4gICAgaWYgKCFwcm90b1tUT19TVFJJTkdfVEFHXSkgaGlkZShwcm90bywgVE9fU1RSSU5HX1RBRywgTkFNRSk7XG4gICAgSXRlcmF0b3JzW05BTUVdID0gQXJyYXlWYWx1ZXM7XG4gICAgaWYgKGV4cGxpY2l0KSBmb3IgKGtleSBpbiAkaXRlcmF0b3JzKSBpZiAoIXByb3RvW2tleV0pIHJlZGVmaW5lKHByb3RvLCBrZXksICRpdGVyYXRvcnNba2V5XSwgdHJ1ZSk7XG4gIH1cbn1cbiIsInZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgJHRhc2sgPSByZXF1aXJlKCcuL190YXNrJyk7XG4kZXhwb3J0KCRleHBvcnQuRyArICRleHBvcnQuQiwge1xuICBzZXRJbW1lZGlhdGU6ICR0YXNrLnNldCxcbiAgY2xlYXJJbW1lZGlhdGU6ICR0YXNrLmNsZWFyXG59KTtcbiIsIi8vIGllOS0gc2V0VGltZW91dCAmIHNldEludGVydmFsIGFkZGl0aW9uYWwgcGFyYW1ldGVycyBmaXhcbnZhciBnbG9iYWwgPSByZXF1aXJlKCcuL19nbG9iYWwnKTtcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgdXNlckFnZW50ID0gcmVxdWlyZSgnLi9fdXNlci1hZ2VudCcpO1xudmFyIHNsaWNlID0gW10uc2xpY2U7XG52YXIgTVNJRSA9IC9NU0lFIC5cXC4vLnRlc3QodXNlckFnZW50KTsgLy8gPC0gZGlydHkgaWU5LSBjaGVja1xudmFyIHdyYXAgPSBmdW5jdGlvbiAoc2V0KSB7XG4gIHJldHVybiBmdW5jdGlvbiAoZm4sIHRpbWUgLyogLCAuLi5hcmdzICovKSB7XG4gICAgdmFyIGJvdW5kQXJncyA9IGFyZ3VtZW50cy5sZW5ndGggPiAyO1xuICAgIHZhciBhcmdzID0gYm91bmRBcmdzID8gc2xpY2UuY2FsbChhcmd1bWVudHMsIDIpIDogZmFsc2U7XG4gICAgcmV0dXJuIHNldChib3VuZEFyZ3MgPyBmdW5jdGlvbiAoKSB7XG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tbmV3LWZ1bmNcbiAgICAgICh0eXBlb2YgZm4gPT0gJ2Z1bmN0aW9uJyA/IGZuIDogRnVuY3Rpb24oZm4pKS5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICB9IDogZm4sIHRpbWUpO1xuICB9O1xufTtcbiRleHBvcnQoJGV4cG9ydC5HICsgJGV4cG9ydC5CICsgJGV4cG9ydC5GICogTVNJRSwge1xuICBzZXRUaW1lb3V0OiB3cmFwKGdsb2JhbC5zZXRUaW1lb3V0KSxcbiAgc2V0SW50ZXJ2YWw6IHdyYXAoZ2xvYmFsLnNldEludGVydmFsKVxufSk7XG4iLCJyZXF1aXJlKCcuLi9tb2R1bGVzL3dlYi50aW1lcnMnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvd2ViLmltbWVkaWF0ZScpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy93ZWIuZG9tLml0ZXJhYmxlJyk7XG5tb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4uL21vZHVsZXMvX2NvcmUnKTtcbiIsIi8qKlxuICogQ29weXJpZ2h0IChjKSAyMDE0LXByZXNlbnQsIEZhY2Vib29rLCBJbmMuXG4gKlxuICogVGhpcyBzb3VyY2UgY29kZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgTUlUIGxpY2Vuc2UgZm91bmQgaW4gdGhlXG4gKiBMSUNFTlNFIGZpbGUgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mIHRoaXMgc291cmNlIHRyZWUuXG4gKi9cblxuIShmdW5jdGlvbihnbG9iYWwpIHtcbiAgXCJ1c2Ugc3RyaWN0XCI7XG5cbiAgdmFyIE9wID0gT2JqZWN0LnByb3RvdHlwZTtcbiAgdmFyIGhhc093biA9IE9wLmhhc093blByb3BlcnR5O1xuICB2YXIgdW5kZWZpbmVkOyAvLyBNb3JlIGNvbXByZXNzaWJsZSB0aGFuIHZvaWQgMC5cbiAgdmFyICRTeW1ib2wgPSB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgPyBTeW1ib2wgOiB7fTtcbiAgdmFyIGl0ZXJhdG9yU3ltYm9sID0gJFN5bWJvbC5pdGVyYXRvciB8fCBcIkBAaXRlcmF0b3JcIjtcbiAgdmFyIGFzeW5jSXRlcmF0b3JTeW1ib2wgPSAkU3ltYm9sLmFzeW5jSXRlcmF0b3IgfHwgXCJAQGFzeW5jSXRlcmF0b3JcIjtcbiAgdmFyIHRvU3RyaW5nVGFnU3ltYm9sID0gJFN5bWJvbC50b1N0cmluZ1RhZyB8fCBcIkBAdG9TdHJpbmdUYWdcIjtcblxuICB2YXIgaW5Nb2R1bGUgPSB0eXBlb2YgbW9kdWxlID09PSBcIm9iamVjdFwiO1xuICB2YXIgcnVudGltZSA9IGdsb2JhbC5yZWdlbmVyYXRvclJ1bnRpbWU7XG4gIGlmIChydW50aW1lKSB7XG4gICAgaWYgKGluTW9kdWxlKSB7XG4gICAgICAvLyBJZiByZWdlbmVyYXRvclJ1bnRpbWUgaXMgZGVmaW5lZCBnbG9iYWxseSBhbmQgd2UncmUgaW4gYSBtb2R1bGUsXG4gICAgICAvLyBtYWtlIHRoZSBleHBvcnRzIG9iamVjdCBpZGVudGljYWwgdG8gcmVnZW5lcmF0b3JSdW50aW1lLlxuICAgICAgbW9kdWxlLmV4cG9ydHMgPSBydW50aW1lO1xuICAgIH1cbiAgICAvLyBEb24ndCBib3RoZXIgZXZhbHVhdGluZyB0aGUgcmVzdCBvZiB0aGlzIGZpbGUgaWYgdGhlIHJ1bnRpbWUgd2FzXG4gICAgLy8gYWxyZWFkeSBkZWZpbmVkIGdsb2JhbGx5LlxuICAgIHJldHVybjtcbiAgfVxuXG4gIC8vIERlZmluZSB0aGUgcnVudGltZSBnbG9iYWxseSAoYXMgZXhwZWN0ZWQgYnkgZ2VuZXJhdGVkIGNvZGUpIGFzIGVpdGhlclxuICAvLyBtb2R1bGUuZXhwb3J0cyAoaWYgd2UncmUgaW4gYSBtb2R1bGUpIG9yIGEgbmV3LCBlbXB0eSBvYmplY3QuXG4gIHJ1bnRpbWUgPSBnbG9iYWwucmVnZW5lcmF0b3JSdW50aW1lID0gaW5Nb2R1bGUgPyBtb2R1bGUuZXhwb3J0cyA6IHt9O1xuXG4gIGZ1bmN0aW9uIHdyYXAoaW5uZXJGbiwgb3V0ZXJGbiwgc2VsZiwgdHJ5TG9jc0xpc3QpIHtcbiAgICAvLyBJZiBvdXRlckZuIHByb3ZpZGVkIGFuZCBvdXRlckZuLnByb3RvdHlwZSBpcyBhIEdlbmVyYXRvciwgdGhlbiBvdXRlckZuLnByb3RvdHlwZSBpbnN0YW5jZW9mIEdlbmVyYXRvci5cbiAgICB2YXIgcHJvdG9HZW5lcmF0b3IgPSBvdXRlckZuICYmIG91dGVyRm4ucHJvdG90eXBlIGluc3RhbmNlb2YgR2VuZXJhdG9yID8gb3V0ZXJGbiA6IEdlbmVyYXRvcjtcbiAgICB2YXIgZ2VuZXJhdG9yID0gT2JqZWN0LmNyZWF0ZShwcm90b0dlbmVyYXRvci5wcm90b3R5cGUpO1xuICAgIHZhciBjb250ZXh0ID0gbmV3IENvbnRleHQodHJ5TG9jc0xpc3QgfHwgW10pO1xuXG4gICAgLy8gVGhlIC5faW52b2tlIG1ldGhvZCB1bmlmaWVzIHRoZSBpbXBsZW1lbnRhdGlvbnMgb2YgdGhlIC5uZXh0LFxuICAgIC8vIC50aHJvdywgYW5kIC5yZXR1cm4gbWV0aG9kcy5cbiAgICBnZW5lcmF0b3IuX2ludm9rZSA9IG1ha2VJbnZva2VNZXRob2QoaW5uZXJGbiwgc2VsZiwgY29udGV4dCk7XG5cbiAgICByZXR1cm4gZ2VuZXJhdG9yO1xuICB9XG4gIHJ1bnRpbWUud3JhcCA9IHdyYXA7XG5cbiAgLy8gVHJ5L2NhdGNoIGhlbHBlciB0byBtaW5pbWl6ZSBkZW9wdGltaXphdGlvbnMuIFJldHVybnMgYSBjb21wbGV0aW9uXG4gIC8vIHJlY29yZCBsaWtlIGNvbnRleHQudHJ5RW50cmllc1tpXS5jb21wbGV0aW9uLiBUaGlzIGludGVyZmFjZSBjb3VsZFxuICAvLyBoYXZlIGJlZW4gKGFuZCB3YXMgcHJldmlvdXNseSkgZGVzaWduZWQgdG8gdGFrZSBhIGNsb3N1cmUgdG8gYmVcbiAgLy8gaW52b2tlZCB3aXRob3V0IGFyZ3VtZW50cywgYnV0IGluIGFsbCB0aGUgY2FzZXMgd2UgY2FyZSBhYm91dCB3ZVxuICAvLyBhbHJlYWR5IGhhdmUgYW4gZXhpc3RpbmcgbWV0aG9kIHdlIHdhbnQgdG8gY2FsbCwgc28gdGhlcmUncyBubyBuZWVkXG4gIC8vIHRvIGNyZWF0ZSBhIG5ldyBmdW5jdGlvbiBvYmplY3QuIFdlIGNhbiBldmVuIGdldCBhd2F5IHdpdGggYXNzdW1pbmdcbiAgLy8gdGhlIG1ldGhvZCB0YWtlcyBleGFjdGx5IG9uZSBhcmd1bWVudCwgc2luY2UgdGhhdCBoYXBwZW5zIHRvIGJlIHRydWVcbiAgLy8gaW4gZXZlcnkgY2FzZSwgc28gd2UgZG9uJ3QgaGF2ZSB0byB0b3VjaCB0aGUgYXJndW1lbnRzIG9iamVjdC4gVGhlXG4gIC8vIG9ubHkgYWRkaXRpb25hbCBhbGxvY2F0aW9uIHJlcXVpcmVkIGlzIHRoZSBjb21wbGV0aW9uIHJlY29yZCwgd2hpY2hcbiAgLy8gaGFzIGEgc3RhYmxlIHNoYXBlIGFuZCBzbyBob3BlZnVsbHkgc2hvdWxkIGJlIGNoZWFwIHRvIGFsbG9jYXRlLlxuICBmdW5jdGlvbiB0cnlDYXRjaChmbiwgb2JqLCBhcmcpIHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIHsgdHlwZTogXCJub3JtYWxcIiwgYXJnOiBmbi5jYWxsKG9iaiwgYXJnKSB9O1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgcmV0dXJuIHsgdHlwZTogXCJ0aHJvd1wiLCBhcmc6IGVyciB9O1xuICAgIH1cbiAgfVxuXG4gIHZhciBHZW5TdGF0ZVN1c3BlbmRlZFN0YXJ0ID0gXCJzdXNwZW5kZWRTdGFydFwiO1xuICB2YXIgR2VuU3RhdGVTdXNwZW5kZWRZaWVsZCA9IFwic3VzcGVuZGVkWWllbGRcIjtcbiAgdmFyIEdlblN0YXRlRXhlY3V0aW5nID0gXCJleGVjdXRpbmdcIjtcbiAgdmFyIEdlblN0YXRlQ29tcGxldGVkID0gXCJjb21wbGV0ZWRcIjtcblxuICAvLyBSZXR1cm5pbmcgdGhpcyBvYmplY3QgZnJvbSB0aGUgaW5uZXJGbiBoYXMgdGhlIHNhbWUgZWZmZWN0IGFzXG4gIC8vIGJyZWFraW5nIG91dCBvZiB0aGUgZGlzcGF0Y2ggc3dpdGNoIHN0YXRlbWVudC5cbiAgdmFyIENvbnRpbnVlU2VudGluZWwgPSB7fTtcblxuICAvLyBEdW1teSBjb25zdHJ1Y3RvciBmdW5jdGlvbnMgdGhhdCB3ZSB1c2UgYXMgdGhlIC5jb25zdHJ1Y3RvciBhbmRcbiAgLy8gLmNvbnN0cnVjdG9yLnByb3RvdHlwZSBwcm9wZXJ0aWVzIGZvciBmdW5jdGlvbnMgdGhhdCByZXR1cm4gR2VuZXJhdG9yXG4gIC8vIG9iamVjdHMuIEZvciBmdWxsIHNwZWMgY29tcGxpYW5jZSwgeW91IG1heSB3aXNoIHRvIGNvbmZpZ3VyZSB5b3VyXG4gIC8vIG1pbmlmaWVyIG5vdCB0byBtYW5nbGUgdGhlIG5hbWVzIG9mIHRoZXNlIHR3byBmdW5jdGlvbnMuXG4gIGZ1bmN0aW9uIEdlbmVyYXRvcigpIHt9XG4gIGZ1bmN0aW9uIEdlbmVyYXRvckZ1bmN0aW9uKCkge31cbiAgZnVuY3Rpb24gR2VuZXJhdG9yRnVuY3Rpb25Qcm90b3R5cGUoKSB7fVxuXG4gIC8vIFRoaXMgaXMgYSBwb2x5ZmlsbCBmb3IgJUl0ZXJhdG9yUHJvdG90eXBlJSBmb3IgZW52aXJvbm1lbnRzIHRoYXRcbiAgLy8gZG9uJ3QgbmF0aXZlbHkgc3VwcG9ydCBpdC5cbiAgdmFyIEl0ZXJhdG9yUHJvdG90eXBlID0ge307XG4gIEl0ZXJhdG9yUHJvdG90eXBlW2l0ZXJhdG9yU3ltYm9sXSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcztcbiAgfTtcblxuICB2YXIgZ2V0UHJvdG8gPSBPYmplY3QuZ2V0UHJvdG90eXBlT2Y7XG4gIHZhciBOYXRpdmVJdGVyYXRvclByb3RvdHlwZSA9IGdldFByb3RvICYmIGdldFByb3RvKGdldFByb3RvKHZhbHVlcyhbXSkpKTtcbiAgaWYgKE5hdGl2ZUl0ZXJhdG9yUHJvdG90eXBlICYmXG4gICAgICBOYXRpdmVJdGVyYXRvclByb3RvdHlwZSAhPT0gT3AgJiZcbiAgICAgIGhhc093bi5jYWxsKE5hdGl2ZUl0ZXJhdG9yUHJvdG90eXBlLCBpdGVyYXRvclN5bWJvbCkpIHtcbiAgICAvLyBUaGlzIGVudmlyb25tZW50IGhhcyBhIG5hdGl2ZSAlSXRlcmF0b3JQcm90b3R5cGUlOyB1c2UgaXQgaW5zdGVhZFxuICAgIC8vIG9mIHRoZSBwb2x5ZmlsbC5cbiAgICBJdGVyYXRvclByb3RvdHlwZSA9IE5hdGl2ZUl0ZXJhdG9yUHJvdG90eXBlO1xuICB9XG5cbiAgdmFyIEdwID0gR2VuZXJhdG9yRnVuY3Rpb25Qcm90b3R5cGUucHJvdG90eXBlID1cbiAgICBHZW5lcmF0b3IucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShJdGVyYXRvclByb3RvdHlwZSk7XG4gIEdlbmVyYXRvckZ1bmN0aW9uLnByb3RvdHlwZSA9IEdwLmNvbnN0cnVjdG9yID0gR2VuZXJhdG9yRnVuY3Rpb25Qcm90b3R5cGU7XG4gIEdlbmVyYXRvckZ1bmN0aW9uUHJvdG90eXBlLmNvbnN0cnVjdG9yID0gR2VuZXJhdG9yRnVuY3Rpb247XG4gIEdlbmVyYXRvckZ1bmN0aW9uUHJvdG90eXBlW3RvU3RyaW5nVGFnU3ltYm9sXSA9XG4gICAgR2VuZXJhdG9yRnVuY3Rpb24uZGlzcGxheU5hbWUgPSBcIkdlbmVyYXRvckZ1bmN0aW9uXCI7XG5cbiAgLy8gSGVscGVyIGZvciBkZWZpbmluZyB0aGUgLm5leHQsIC50aHJvdywgYW5kIC5yZXR1cm4gbWV0aG9kcyBvZiB0aGVcbiAgLy8gSXRlcmF0b3IgaW50ZXJmYWNlIGluIHRlcm1zIG9mIGEgc2luZ2xlIC5faW52b2tlIG1ldGhvZC5cbiAgZnVuY3Rpb24gZGVmaW5lSXRlcmF0b3JNZXRob2RzKHByb3RvdHlwZSkge1xuICAgIFtcIm5leHRcIiwgXCJ0aHJvd1wiLCBcInJldHVyblwiXS5mb3JFYWNoKGZ1bmN0aW9uKG1ldGhvZCkge1xuICAgICAgcHJvdG90eXBlW21ldGhvZF0gPSBmdW5jdGlvbihhcmcpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2ludm9rZShtZXRob2QsIGFyZyk7XG4gICAgICB9O1xuICAgIH0pO1xuICB9XG5cbiAgcnVudGltZS5pc0dlbmVyYXRvckZ1bmN0aW9uID0gZnVuY3Rpb24oZ2VuRnVuKSB7XG4gICAgdmFyIGN0b3IgPSB0eXBlb2YgZ2VuRnVuID09PSBcImZ1bmN0aW9uXCIgJiYgZ2VuRnVuLmNvbnN0cnVjdG9yO1xuICAgIHJldHVybiBjdG9yXG4gICAgICA/IGN0b3IgPT09IEdlbmVyYXRvckZ1bmN0aW9uIHx8XG4gICAgICAgIC8vIEZvciB0aGUgbmF0aXZlIEdlbmVyYXRvckZ1bmN0aW9uIGNvbnN0cnVjdG9yLCB0aGUgYmVzdCB3ZSBjYW5cbiAgICAgICAgLy8gZG8gaXMgdG8gY2hlY2sgaXRzIC5uYW1lIHByb3BlcnR5LlxuICAgICAgICAoY3Rvci5kaXNwbGF5TmFtZSB8fCBjdG9yLm5hbWUpID09PSBcIkdlbmVyYXRvckZ1bmN0aW9uXCJcbiAgICAgIDogZmFsc2U7XG4gIH07XG5cbiAgcnVudGltZS5tYXJrID0gZnVuY3Rpb24oZ2VuRnVuKSB7XG4gICAgaWYgKE9iamVjdC5zZXRQcm90b3R5cGVPZikge1xuICAgICAgT2JqZWN0LnNldFByb3RvdHlwZU9mKGdlbkZ1biwgR2VuZXJhdG9yRnVuY3Rpb25Qcm90b3R5cGUpO1xuICAgIH0gZWxzZSB7XG4gICAgICBnZW5GdW4uX19wcm90b19fID0gR2VuZXJhdG9yRnVuY3Rpb25Qcm90b3R5cGU7XG4gICAgICBpZiAoISh0b1N0cmluZ1RhZ1N5bWJvbCBpbiBnZW5GdW4pKSB7XG4gICAgICAgIGdlbkZ1blt0b1N0cmluZ1RhZ1N5bWJvbF0gPSBcIkdlbmVyYXRvckZ1bmN0aW9uXCI7XG4gICAgICB9XG4gICAgfVxuICAgIGdlbkZ1bi5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKEdwKTtcbiAgICByZXR1cm4gZ2VuRnVuO1xuICB9O1xuXG4gIC8vIFdpdGhpbiB0aGUgYm9keSBvZiBhbnkgYXN5bmMgZnVuY3Rpb24sIGBhd2FpdCB4YCBpcyB0cmFuc2Zvcm1lZCB0b1xuICAvLyBgeWllbGQgcmVnZW5lcmF0b3JSdW50aW1lLmF3cmFwKHgpYCwgc28gdGhhdCB0aGUgcnVudGltZSBjYW4gdGVzdFxuICAvLyBgaGFzT3duLmNhbGwodmFsdWUsIFwiX19hd2FpdFwiKWAgdG8gZGV0ZXJtaW5lIGlmIHRoZSB5aWVsZGVkIHZhbHVlIGlzXG4gIC8vIG1lYW50IHRvIGJlIGF3YWl0ZWQuXG4gIHJ1bnRpbWUuYXdyYXAgPSBmdW5jdGlvbihhcmcpIHtcbiAgICByZXR1cm4geyBfX2F3YWl0OiBhcmcgfTtcbiAgfTtcblxuICBmdW5jdGlvbiBBc3luY0l0ZXJhdG9yKGdlbmVyYXRvcikge1xuICAgIGZ1bmN0aW9uIGludm9rZShtZXRob2QsIGFyZywgcmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgICB2YXIgcmVjb3JkID0gdHJ5Q2F0Y2goZ2VuZXJhdG9yW21ldGhvZF0sIGdlbmVyYXRvciwgYXJnKTtcbiAgICAgIGlmIChyZWNvcmQudHlwZSA9PT0gXCJ0aHJvd1wiKSB7XG4gICAgICAgIHJlamVjdChyZWNvcmQuYXJnKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHZhciByZXN1bHQgPSByZWNvcmQuYXJnO1xuICAgICAgICB2YXIgdmFsdWUgPSByZXN1bHQudmFsdWU7XG4gICAgICAgIGlmICh2YWx1ZSAmJlxuICAgICAgICAgICAgdHlwZW9mIHZhbHVlID09PSBcIm9iamVjdFwiICYmXG4gICAgICAgICAgICBoYXNPd24uY2FsbCh2YWx1ZSwgXCJfX2F3YWl0XCIpKSB7XG4gICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh2YWx1ZS5fX2F3YWl0KS50aGVuKGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICAgICAgICBpbnZva2UoXCJuZXh0XCIsIHZhbHVlLCByZXNvbHZlLCByZWplY3QpO1xuICAgICAgICAgIH0sIGZ1bmN0aW9uKGVycikge1xuICAgICAgICAgICAgaW52b2tlKFwidGhyb3dcIiwgZXJyLCByZXNvbHZlLCByZWplY3QpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh2YWx1ZSkudGhlbihmdW5jdGlvbih1bndyYXBwZWQpIHtcbiAgICAgICAgICAvLyBXaGVuIGEgeWllbGRlZCBQcm9taXNlIGlzIHJlc29sdmVkLCBpdHMgZmluYWwgdmFsdWUgYmVjb21lc1xuICAgICAgICAgIC8vIHRoZSAudmFsdWUgb2YgdGhlIFByb21pc2U8e3ZhbHVlLGRvbmV9PiByZXN1bHQgZm9yIHRoZVxuICAgICAgICAgIC8vIGN1cnJlbnQgaXRlcmF0aW9uLiBJZiB0aGUgUHJvbWlzZSBpcyByZWplY3RlZCwgaG93ZXZlciwgdGhlXG4gICAgICAgICAgLy8gcmVzdWx0IGZvciB0aGlzIGl0ZXJhdGlvbiB3aWxsIGJlIHJlamVjdGVkIHdpdGggdGhlIHNhbWVcbiAgICAgICAgICAvLyByZWFzb24uIE5vdGUgdGhhdCByZWplY3Rpb25zIG9mIHlpZWxkZWQgUHJvbWlzZXMgYXJlIG5vdFxuICAgICAgICAgIC8vIHRocm93biBiYWNrIGludG8gdGhlIGdlbmVyYXRvciBmdW5jdGlvbiwgYXMgaXMgdGhlIGNhc2VcbiAgICAgICAgICAvLyB3aGVuIGFuIGF3YWl0ZWQgUHJvbWlzZSBpcyByZWplY3RlZC4gVGhpcyBkaWZmZXJlbmNlIGluXG4gICAgICAgICAgLy8gYmVoYXZpb3IgYmV0d2VlbiB5aWVsZCBhbmQgYXdhaXQgaXMgaW1wb3J0YW50LCBiZWNhdXNlIGl0XG4gICAgICAgICAgLy8gYWxsb3dzIHRoZSBjb25zdW1lciB0byBkZWNpZGUgd2hhdCB0byBkbyB3aXRoIHRoZSB5aWVsZGVkXG4gICAgICAgICAgLy8gcmVqZWN0aW9uIChzd2FsbG93IGl0IGFuZCBjb250aW51ZSwgbWFudWFsbHkgLnRocm93IGl0IGJhY2tcbiAgICAgICAgICAvLyBpbnRvIHRoZSBnZW5lcmF0b3IsIGFiYW5kb24gaXRlcmF0aW9uLCB3aGF0ZXZlcikuIFdpdGhcbiAgICAgICAgICAvLyBhd2FpdCwgYnkgY29udHJhc3QsIHRoZXJlIGlzIG5vIG9wcG9ydHVuaXR5IHRvIGV4YW1pbmUgdGhlXG4gICAgICAgICAgLy8gcmVqZWN0aW9uIHJlYXNvbiBvdXRzaWRlIHRoZSBnZW5lcmF0b3IgZnVuY3Rpb24sIHNvIHRoZVxuICAgICAgICAgIC8vIG9ubHkgb3B0aW9uIGlzIHRvIHRocm93IGl0IGZyb20gdGhlIGF3YWl0IGV4cHJlc3Npb24sIGFuZFxuICAgICAgICAgIC8vIGxldCB0aGUgZ2VuZXJhdG9yIGZ1bmN0aW9uIGhhbmRsZSB0aGUgZXhjZXB0aW9uLlxuICAgICAgICAgIHJlc3VsdC52YWx1ZSA9IHVud3JhcHBlZDtcbiAgICAgICAgICByZXNvbHZlKHJlc3VsdCk7XG4gICAgICAgIH0sIHJlamVjdCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdmFyIHByZXZpb3VzUHJvbWlzZTtcblxuICAgIGZ1bmN0aW9uIGVucXVldWUobWV0aG9kLCBhcmcpIHtcbiAgICAgIGZ1bmN0aW9uIGNhbGxJbnZva2VXaXRoTWV0aG9kQW5kQXJnKCkge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24ocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgICAgICAgaW52b2tlKG1ldGhvZCwgYXJnLCByZXNvbHZlLCByZWplY3QpO1xuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHByZXZpb3VzUHJvbWlzZSA9XG4gICAgICAgIC8vIElmIGVucXVldWUgaGFzIGJlZW4gY2FsbGVkIGJlZm9yZSwgdGhlbiB3ZSB3YW50IHRvIHdhaXQgdW50aWxcbiAgICAgICAgLy8gYWxsIHByZXZpb3VzIFByb21pc2VzIGhhdmUgYmVlbiByZXNvbHZlZCBiZWZvcmUgY2FsbGluZyBpbnZva2UsXG4gICAgICAgIC8vIHNvIHRoYXQgcmVzdWx0cyBhcmUgYWx3YXlzIGRlbGl2ZXJlZCBpbiB0aGUgY29ycmVjdCBvcmRlci4gSWZcbiAgICAgICAgLy8gZW5xdWV1ZSBoYXMgbm90IGJlZW4gY2FsbGVkIGJlZm9yZSwgdGhlbiBpdCBpcyBpbXBvcnRhbnQgdG9cbiAgICAgICAgLy8gY2FsbCBpbnZva2UgaW1tZWRpYXRlbHksIHdpdGhvdXQgd2FpdGluZyBvbiBhIGNhbGxiYWNrIHRvIGZpcmUsXG4gICAgICAgIC8vIHNvIHRoYXQgdGhlIGFzeW5jIGdlbmVyYXRvciBmdW5jdGlvbiBoYXMgdGhlIG9wcG9ydHVuaXR5IHRvIGRvXG4gICAgICAgIC8vIGFueSBuZWNlc3Nhcnkgc2V0dXAgaW4gYSBwcmVkaWN0YWJsZSB3YXkuIFRoaXMgcHJlZGljdGFiaWxpdHlcbiAgICAgICAgLy8gaXMgd2h5IHRoZSBQcm9taXNlIGNvbnN0cnVjdG9yIHN5bmNocm9ub3VzbHkgaW52b2tlcyBpdHNcbiAgICAgICAgLy8gZXhlY3V0b3IgY2FsbGJhY2ssIGFuZCB3aHkgYXN5bmMgZnVuY3Rpb25zIHN5bmNocm9ub3VzbHlcbiAgICAgICAgLy8gZXhlY3V0ZSBjb2RlIGJlZm9yZSB0aGUgZmlyc3QgYXdhaXQuIFNpbmNlIHdlIGltcGxlbWVudCBzaW1wbGVcbiAgICAgICAgLy8gYXN5bmMgZnVuY3Rpb25zIGluIHRlcm1zIG9mIGFzeW5jIGdlbmVyYXRvcnMsIGl0IGlzIGVzcGVjaWFsbHlcbiAgICAgICAgLy8gaW1wb3J0YW50IHRvIGdldCB0aGlzIHJpZ2h0LCBldmVuIHRob3VnaCBpdCByZXF1aXJlcyBjYXJlLlxuICAgICAgICBwcmV2aW91c1Byb21pc2UgPyBwcmV2aW91c1Byb21pc2UudGhlbihcbiAgICAgICAgICBjYWxsSW52b2tlV2l0aE1ldGhvZEFuZEFyZyxcbiAgICAgICAgICAvLyBBdm9pZCBwcm9wYWdhdGluZyBmYWlsdXJlcyB0byBQcm9taXNlcyByZXR1cm5lZCBieSBsYXRlclxuICAgICAgICAgIC8vIGludm9jYXRpb25zIG9mIHRoZSBpdGVyYXRvci5cbiAgICAgICAgICBjYWxsSW52b2tlV2l0aE1ldGhvZEFuZEFyZ1xuICAgICAgICApIDogY2FsbEludm9rZVdpdGhNZXRob2RBbmRBcmcoKTtcbiAgICB9XG5cbiAgICAvLyBEZWZpbmUgdGhlIHVuaWZpZWQgaGVscGVyIG1ldGhvZCB0aGF0IGlzIHVzZWQgdG8gaW1wbGVtZW50IC5uZXh0LFxuICAgIC8vIC50aHJvdywgYW5kIC5yZXR1cm4gKHNlZSBkZWZpbmVJdGVyYXRvck1ldGhvZHMpLlxuICAgIHRoaXMuX2ludm9rZSA9IGVucXVldWU7XG4gIH1cblxuICBkZWZpbmVJdGVyYXRvck1ldGhvZHMoQXN5bmNJdGVyYXRvci5wcm90b3R5cGUpO1xuICBBc3luY0l0ZXJhdG9yLnByb3RvdHlwZVthc3luY0l0ZXJhdG9yU3ltYm9sXSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcztcbiAgfTtcbiAgcnVudGltZS5Bc3luY0l0ZXJhdG9yID0gQXN5bmNJdGVyYXRvcjtcblxuICAvLyBOb3RlIHRoYXQgc2ltcGxlIGFzeW5jIGZ1bmN0aW9ucyBhcmUgaW1wbGVtZW50ZWQgb24gdG9wIG9mXG4gIC8vIEFzeW5jSXRlcmF0b3Igb2JqZWN0czsgdGhleSBqdXN0IHJldHVybiBhIFByb21pc2UgZm9yIHRoZSB2YWx1ZSBvZlxuICAvLyB0aGUgZmluYWwgcmVzdWx0IHByb2R1Y2VkIGJ5IHRoZSBpdGVyYXRvci5cbiAgcnVudGltZS5hc3luYyA9IGZ1bmN0aW9uKGlubmVyRm4sIG91dGVyRm4sIHNlbGYsIHRyeUxvY3NMaXN0KSB7XG4gICAgdmFyIGl0ZXIgPSBuZXcgQXN5bmNJdGVyYXRvcihcbiAgICAgIHdyYXAoaW5uZXJGbiwgb3V0ZXJGbiwgc2VsZiwgdHJ5TG9jc0xpc3QpXG4gICAgKTtcblxuICAgIHJldHVybiBydW50aW1lLmlzR2VuZXJhdG9yRnVuY3Rpb24ob3V0ZXJGbilcbiAgICAgID8gaXRlciAvLyBJZiBvdXRlckZuIGlzIGEgZ2VuZXJhdG9yLCByZXR1cm4gdGhlIGZ1bGwgaXRlcmF0b3IuXG4gICAgICA6IGl0ZXIubmV4dCgpLnRoZW4oZnVuY3Rpb24ocmVzdWx0KSB7XG4gICAgICAgICAgcmV0dXJuIHJlc3VsdC5kb25lID8gcmVzdWx0LnZhbHVlIDogaXRlci5uZXh0KCk7XG4gICAgICAgIH0pO1xuICB9O1xuXG4gIGZ1bmN0aW9uIG1ha2VJbnZva2VNZXRob2QoaW5uZXJGbiwgc2VsZiwgY29udGV4dCkge1xuICAgIHZhciBzdGF0ZSA9IEdlblN0YXRlU3VzcGVuZGVkU3RhcnQ7XG5cbiAgICByZXR1cm4gZnVuY3Rpb24gaW52b2tlKG1ldGhvZCwgYXJnKSB7XG4gICAgICBpZiAoc3RhdGUgPT09IEdlblN0YXRlRXhlY3V0aW5nKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIkdlbmVyYXRvciBpcyBhbHJlYWR5IHJ1bm5pbmdcIik7XG4gICAgICB9XG5cbiAgICAgIGlmIChzdGF0ZSA9PT0gR2VuU3RhdGVDb21wbGV0ZWQpIHtcbiAgICAgICAgaWYgKG1ldGhvZCA9PT0gXCJ0aHJvd1wiKSB7XG4gICAgICAgICAgdGhyb3cgYXJnO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gQmUgZm9yZ2l2aW5nLCBwZXIgMjUuMy4zLjMuMyBvZiB0aGUgc3BlYzpcbiAgICAgICAgLy8gaHR0cHM6Ly9wZW9wbGUubW96aWxsYS5vcmcvfmpvcmVuZG9yZmYvZXM2LWRyYWZ0Lmh0bWwjc2VjLWdlbmVyYXRvcnJlc3VtZVxuICAgICAgICByZXR1cm4gZG9uZVJlc3VsdCgpO1xuICAgICAgfVxuXG4gICAgICBjb250ZXh0Lm1ldGhvZCA9IG1ldGhvZDtcbiAgICAgIGNvbnRleHQuYXJnID0gYXJnO1xuXG4gICAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgICB2YXIgZGVsZWdhdGUgPSBjb250ZXh0LmRlbGVnYXRlO1xuICAgICAgICBpZiAoZGVsZWdhdGUpIHtcbiAgICAgICAgICB2YXIgZGVsZWdhdGVSZXN1bHQgPSBtYXliZUludm9rZURlbGVnYXRlKGRlbGVnYXRlLCBjb250ZXh0KTtcbiAgICAgICAgICBpZiAoZGVsZWdhdGVSZXN1bHQpIHtcbiAgICAgICAgICAgIGlmIChkZWxlZ2F0ZVJlc3VsdCA9PT0gQ29udGludWVTZW50aW5lbCkgY29udGludWU7XG4gICAgICAgICAgICByZXR1cm4gZGVsZWdhdGVSZXN1bHQ7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGNvbnRleHQubWV0aG9kID09PSBcIm5leHRcIikge1xuICAgICAgICAgIC8vIFNldHRpbmcgY29udGV4dC5fc2VudCBmb3IgbGVnYWN5IHN1cHBvcnQgb2YgQmFiZWwnc1xuICAgICAgICAgIC8vIGZ1bmN0aW9uLnNlbnQgaW1wbGVtZW50YXRpb24uXG4gICAgICAgICAgY29udGV4dC5zZW50ID0gY29udGV4dC5fc2VudCA9IGNvbnRleHQuYXJnO1xuXG4gICAgICAgIH0gZWxzZSBpZiAoY29udGV4dC5tZXRob2QgPT09IFwidGhyb3dcIikge1xuICAgICAgICAgIGlmIChzdGF0ZSA9PT0gR2VuU3RhdGVTdXNwZW5kZWRTdGFydCkge1xuICAgICAgICAgICAgc3RhdGUgPSBHZW5TdGF0ZUNvbXBsZXRlZDtcbiAgICAgICAgICAgIHRocm93IGNvbnRleHQuYXJnO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGNvbnRleHQuZGlzcGF0Y2hFeGNlcHRpb24oY29udGV4dC5hcmcpO1xuXG4gICAgICAgIH0gZWxzZSBpZiAoY29udGV4dC5tZXRob2QgPT09IFwicmV0dXJuXCIpIHtcbiAgICAgICAgICBjb250ZXh0LmFicnVwdChcInJldHVyblwiLCBjb250ZXh0LmFyZyk7XG4gICAgICAgIH1cblxuICAgICAgICBzdGF0ZSA9IEdlblN0YXRlRXhlY3V0aW5nO1xuXG4gICAgICAgIHZhciByZWNvcmQgPSB0cnlDYXRjaChpbm5lckZuLCBzZWxmLCBjb250ZXh0KTtcbiAgICAgICAgaWYgKHJlY29yZC50eXBlID09PSBcIm5vcm1hbFwiKSB7XG4gICAgICAgICAgLy8gSWYgYW4gZXhjZXB0aW9uIGlzIHRocm93biBmcm9tIGlubmVyRm4sIHdlIGxlYXZlIHN0YXRlID09PVxuICAgICAgICAgIC8vIEdlblN0YXRlRXhlY3V0aW5nIGFuZCBsb29wIGJhY2sgZm9yIGFub3RoZXIgaW52b2NhdGlvbi5cbiAgICAgICAgICBzdGF0ZSA9IGNvbnRleHQuZG9uZVxuICAgICAgICAgICAgPyBHZW5TdGF0ZUNvbXBsZXRlZFxuICAgICAgICAgICAgOiBHZW5TdGF0ZVN1c3BlbmRlZFlpZWxkO1xuXG4gICAgICAgICAgaWYgKHJlY29yZC5hcmcgPT09IENvbnRpbnVlU2VudGluZWwpIHtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB2YWx1ZTogcmVjb3JkLmFyZyxcbiAgICAgICAgICAgIGRvbmU6IGNvbnRleHQuZG9uZVxuICAgICAgICAgIH07XG5cbiAgICAgICAgfSBlbHNlIGlmIChyZWNvcmQudHlwZSA9PT0gXCJ0aHJvd1wiKSB7XG4gICAgICAgICAgc3RhdGUgPSBHZW5TdGF0ZUNvbXBsZXRlZDtcbiAgICAgICAgICAvLyBEaXNwYXRjaCB0aGUgZXhjZXB0aW9uIGJ5IGxvb3BpbmcgYmFjayBhcm91bmQgdG8gdGhlXG4gICAgICAgICAgLy8gY29udGV4dC5kaXNwYXRjaEV4Y2VwdGlvbihjb250ZXh0LmFyZykgY2FsbCBhYm92ZS5cbiAgICAgICAgICBjb250ZXh0Lm1ldGhvZCA9IFwidGhyb3dcIjtcbiAgICAgICAgICBjb250ZXh0LmFyZyA9IHJlY29yZC5hcmc7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9O1xuICB9XG5cbiAgLy8gQ2FsbCBkZWxlZ2F0ZS5pdGVyYXRvcltjb250ZXh0Lm1ldGhvZF0oY29udGV4dC5hcmcpIGFuZCBoYW5kbGUgdGhlXG4gIC8vIHJlc3VsdCwgZWl0aGVyIGJ5IHJldHVybmluZyBhIHsgdmFsdWUsIGRvbmUgfSByZXN1bHQgZnJvbSB0aGVcbiAgLy8gZGVsZWdhdGUgaXRlcmF0b3IsIG9yIGJ5IG1vZGlmeWluZyBjb250ZXh0Lm1ldGhvZCBhbmQgY29udGV4dC5hcmcsXG4gIC8vIHNldHRpbmcgY29udGV4dC5kZWxlZ2F0ZSB0byBudWxsLCBhbmQgcmV0dXJuaW5nIHRoZSBDb250aW51ZVNlbnRpbmVsLlxuICBmdW5jdGlvbiBtYXliZUludm9rZURlbGVnYXRlKGRlbGVnYXRlLCBjb250ZXh0KSB7XG4gICAgdmFyIG1ldGhvZCA9IGRlbGVnYXRlLml0ZXJhdG9yW2NvbnRleHQubWV0aG9kXTtcbiAgICBpZiAobWV0aG9kID09PSB1bmRlZmluZWQpIHtcbiAgICAgIC8vIEEgLnRocm93IG9yIC5yZXR1cm4gd2hlbiB0aGUgZGVsZWdhdGUgaXRlcmF0b3IgaGFzIG5vIC50aHJvd1xuICAgICAgLy8gbWV0aG9kIGFsd2F5cyB0ZXJtaW5hdGVzIHRoZSB5aWVsZCogbG9vcC5cbiAgICAgIGNvbnRleHQuZGVsZWdhdGUgPSBudWxsO1xuXG4gICAgICBpZiAoY29udGV4dC5tZXRob2QgPT09IFwidGhyb3dcIikge1xuICAgICAgICBpZiAoZGVsZWdhdGUuaXRlcmF0b3IucmV0dXJuKSB7XG4gICAgICAgICAgLy8gSWYgdGhlIGRlbGVnYXRlIGl0ZXJhdG9yIGhhcyBhIHJldHVybiBtZXRob2QsIGdpdmUgaXQgYVxuICAgICAgICAgIC8vIGNoYW5jZSB0byBjbGVhbiB1cC5cbiAgICAgICAgICBjb250ZXh0Lm1ldGhvZCA9IFwicmV0dXJuXCI7XG4gICAgICAgICAgY29udGV4dC5hcmcgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgbWF5YmVJbnZva2VEZWxlZ2F0ZShkZWxlZ2F0ZSwgY29udGV4dCk7XG5cbiAgICAgICAgICBpZiAoY29udGV4dC5tZXRob2QgPT09IFwidGhyb3dcIikge1xuICAgICAgICAgICAgLy8gSWYgbWF5YmVJbnZva2VEZWxlZ2F0ZShjb250ZXh0KSBjaGFuZ2VkIGNvbnRleHQubWV0aG9kIGZyb21cbiAgICAgICAgICAgIC8vIFwicmV0dXJuXCIgdG8gXCJ0aHJvd1wiLCBsZXQgdGhhdCBvdmVycmlkZSB0aGUgVHlwZUVycm9yIGJlbG93LlxuICAgICAgICAgICAgcmV0dXJuIENvbnRpbnVlU2VudGluZWw7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgY29udGV4dC5tZXRob2QgPSBcInRocm93XCI7XG4gICAgICAgIGNvbnRleHQuYXJnID0gbmV3IFR5cGVFcnJvcihcbiAgICAgICAgICBcIlRoZSBpdGVyYXRvciBkb2VzIG5vdCBwcm92aWRlIGEgJ3Rocm93JyBtZXRob2RcIik7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBDb250aW51ZVNlbnRpbmVsO1xuICAgIH1cblxuICAgIHZhciByZWNvcmQgPSB0cnlDYXRjaChtZXRob2QsIGRlbGVnYXRlLml0ZXJhdG9yLCBjb250ZXh0LmFyZyk7XG5cbiAgICBpZiAocmVjb3JkLnR5cGUgPT09IFwidGhyb3dcIikge1xuICAgICAgY29udGV4dC5tZXRob2QgPSBcInRocm93XCI7XG4gICAgICBjb250ZXh0LmFyZyA9IHJlY29yZC5hcmc7XG4gICAgICBjb250ZXh0LmRlbGVnYXRlID0gbnVsbDtcbiAgICAgIHJldHVybiBDb250aW51ZVNlbnRpbmVsO1xuICAgIH1cblxuICAgIHZhciBpbmZvID0gcmVjb3JkLmFyZztcblxuICAgIGlmICghIGluZm8pIHtcbiAgICAgIGNvbnRleHQubWV0aG9kID0gXCJ0aHJvd1wiO1xuICAgICAgY29udGV4dC5hcmcgPSBuZXcgVHlwZUVycm9yKFwiaXRlcmF0b3IgcmVzdWx0IGlzIG5vdCBhbiBvYmplY3RcIik7XG4gICAgICBjb250ZXh0LmRlbGVnYXRlID0gbnVsbDtcbiAgICAgIHJldHVybiBDb250aW51ZVNlbnRpbmVsO1xuICAgIH1cblxuICAgIGlmIChpbmZvLmRvbmUpIHtcbiAgICAgIC8vIEFzc2lnbiB0aGUgcmVzdWx0IG9mIHRoZSBmaW5pc2hlZCBkZWxlZ2F0ZSB0byB0aGUgdGVtcG9yYXJ5XG4gICAgICAvLyB2YXJpYWJsZSBzcGVjaWZpZWQgYnkgZGVsZWdhdGUucmVzdWx0TmFtZSAoc2VlIGRlbGVnYXRlWWllbGQpLlxuICAgICAgY29udGV4dFtkZWxlZ2F0ZS5yZXN1bHROYW1lXSA9IGluZm8udmFsdWU7XG5cbiAgICAgIC8vIFJlc3VtZSBleGVjdXRpb24gYXQgdGhlIGRlc2lyZWQgbG9jYXRpb24gKHNlZSBkZWxlZ2F0ZVlpZWxkKS5cbiAgICAgIGNvbnRleHQubmV4dCA9IGRlbGVnYXRlLm5leHRMb2M7XG5cbiAgICAgIC8vIElmIGNvbnRleHQubWV0aG9kIHdhcyBcInRocm93XCIgYnV0IHRoZSBkZWxlZ2F0ZSBoYW5kbGVkIHRoZVxuICAgICAgLy8gZXhjZXB0aW9uLCBsZXQgdGhlIG91dGVyIGdlbmVyYXRvciBwcm9jZWVkIG5vcm1hbGx5LiBJZlxuICAgICAgLy8gY29udGV4dC5tZXRob2Qgd2FzIFwibmV4dFwiLCBmb3JnZXQgY29udGV4dC5hcmcgc2luY2UgaXQgaGFzIGJlZW5cbiAgICAgIC8vIFwiY29uc3VtZWRcIiBieSB0aGUgZGVsZWdhdGUgaXRlcmF0b3IuIElmIGNvbnRleHQubWV0aG9kIHdhc1xuICAgICAgLy8gXCJyZXR1cm5cIiwgYWxsb3cgdGhlIG9yaWdpbmFsIC5yZXR1cm4gY2FsbCB0byBjb250aW51ZSBpbiB0aGVcbiAgICAgIC8vIG91dGVyIGdlbmVyYXRvci5cbiAgICAgIGlmIChjb250ZXh0Lm1ldGhvZCAhPT0gXCJyZXR1cm5cIikge1xuICAgICAgICBjb250ZXh0Lm1ldGhvZCA9IFwibmV4dFwiO1xuICAgICAgICBjb250ZXh0LmFyZyA9IHVuZGVmaW5lZDtcbiAgICAgIH1cblxuICAgIH0gZWxzZSB7XG4gICAgICAvLyBSZS15aWVsZCB0aGUgcmVzdWx0IHJldHVybmVkIGJ5IHRoZSBkZWxlZ2F0ZSBtZXRob2QuXG4gICAgICByZXR1cm4gaW5mbztcbiAgICB9XG5cbiAgICAvLyBUaGUgZGVsZWdhdGUgaXRlcmF0b3IgaXMgZmluaXNoZWQsIHNvIGZvcmdldCBpdCBhbmQgY29udGludWUgd2l0aFxuICAgIC8vIHRoZSBvdXRlciBnZW5lcmF0b3IuXG4gICAgY29udGV4dC5kZWxlZ2F0ZSA9IG51bGw7XG4gICAgcmV0dXJuIENvbnRpbnVlU2VudGluZWw7XG4gIH1cblxuICAvLyBEZWZpbmUgR2VuZXJhdG9yLnByb3RvdHlwZS57bmV4dCx0aHJvdyxyZXR1cm59IGluIHRlcm1zIG9mIHRoZVxuICAvLyB1bmlmaWVkIC5faW52b2tlIGhlbHBlciBtZXRob2QuXG4gIGRlZmluZUl0ZXJhdG9yTWV0aG9kcyhHcCk7XG5cbiAgR3BbdG9TdHJpbmdUYWdTeW1ib2xdID0gXCJHZW5lcmF0b3JcIjtcblxuICAvLyBBIEdlbmVyYXRvciBzaG91bGQgYWx3YXlzIHJldHVybiBpdHNlbGYgYXMgdGhlIGl0ZXJhdG9yIG9iamVjdCB3aGVuIHRoZVxuICAvLyBAQGl0ZXJhdG9yIGZ1bmN0aW9uIGlzIGNhbGxlZCBvbiBpdC4gU29tZSBicm93c2VycycgaW1wbGVtZW50YXRpb25zIG9mIHRoZVxuICAvLyBpdGVyYXRvciBwcm90b3R5cGUgY2hhaW4gaW5jb3JyZWN0bHkgaW1wbGVtZW50IHRoaXMsIGNhdXNpbmcgdGhlIEdlbmVyYXRvclxuICAvLyBvYmplY3QgdG8gbm90IGJlIHJldHVybmVkIGZyb20gdGhpcyBjYWxsLiBUaGlzIGVuc3VyZXMgdGhhdCBkb2Vzbid0IGhhcHBlbi5cbiAgLy8gU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9mYWNlYm9vay9yZWdlbmVyYXRvci9pc3N1ZXMvMjc0IGZvciBtb3JlIGRldGFpbHMuXG4gIEdwW2l0ZXJhdG9yU3ltYm9sXSA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB0aGlzO1xuICB9O1xuXG4gIEdwLnRvU3RyaW5nID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIFwiW29iamVjdCBHZW5lcmF0b3JdXCI7XG4gIH07XG5cbiAgZnVuY3Rpb24gcHVzaFRyeUVudHJ5KGxvY3MpIHtcbiAgICB2YXIgZW50cnkgPSB7IHRyeUxvYzogbG9jc1swXSB9O1xuXG4gICAgaWYgKDEgaW4gbG9jcykge1xuICAgICAgZW50cnkuY2F0Y2hMb2MgPSBsb2NzWzFdO1xuICAgIH1cblxuICAgIGlmICgyIGluIGxvY3MpIHtcbiAgICAgIGVudHJ5LmZpbmFsbHlMb2MgPSBsb2NzWzJdO1xuICAgICAgZW50cnkuYWZ0ZXJMb2MgPSBsb2NzWzNdO1xuICAgIH1cblxuICAgIHRoaXMudHJ5RW50cmllcy5wdXNoKGVudHJ5KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHJlc2V0VHJ5RW50cnkoZW50cnkpIHtcbiAgICB2YXIgcmVjb3JkID0gZW50cnkuY29tcGxldGlvbiB8fCB7fTtcbiAgICByZWNvcmQudHlwZSA9IFwibm9ybWFsXCI7XG4gICAgZGVsZXRlIHJlY29yZC5hcmc7XG4gICAgZW50cnkuY29tcGxldGlvbiA9IHJlY29yZDtcbiAgfVxuXG4gIGZ1bmN0aW9uIENvbnRleHQodHJ5TG9jc0xpc3QpIHtcbiAgICAvLyBUaGUgcm9vdCBlbnRyeSBvYmplY3QgKGVmZmVjdGl2ZWx5IGEgdHJ5IHN0YXRlbWVudCB3aXRob3V0IGEgY2F0Y2hcbiAgICAvLyBvciBhIGZpbmFsbHkgYmxvY2spIGdpdmVzIHVzIGEgcGxhY2UgdG8gc3RvcmUgdmFsdWVzIHRocm93biBmcm9tXG4gICAgLy8gbG9jYXRpb25zIHdoZXJlIHRoZXJlIGlzIG5vIGVuY2xvc2luZyB0cnkgc3RhdGVtZW50LlxuICAgIHRoaXMudHJ5RW50cmllcyA9IFt7IHRyeUxvYzogXCJyb290XCIgfV07XG4gICAgdHJ5TG9jc0xpc3QuZm9yRWFjaChwdXNoVHJ5RW50cnksIHRoaXMpO1xuICAgIHRoaXMucmVzZXQodHJ1ZSk7XG4gIH1cblxuICBydW50aW1lLmtleXMgPSBmdW5jdGlvbihvYmplY3QpIHtcbiAgICB2YXIga2V5cyA9IFtdO1xuICAgIGZvciAodmFyIGtleSBpbiBvYmplY3QpIHtcbiAgICAgIGtleXMucHVzaChrZXkpO1xuICAgIH1cbiAgICBrZXlzLnJldmVyc2UoKTtcblxuICAgIC8vIFJhdGhlciB0aGFuIHJldHVybmluZyBhbiBvYmplY3Qgd2l0aCBhIG5leHQgbWV0aG9kLCB3ZSBrZWVwXG4gICAgLy8gdGhpbmdzIHNpbXBsZSBhbmQgcmV0dXJuIHRoZSBuZXh0IGZ1bmN0aW9uIGl0c2VsZi5cbiAgICByZXR1cm4gZnVuY3Rpb24gbmV4dCgpIHtcbiAgICAgIHdoaWxlIChrZXlzLmxlbmd0aCkge1xuICAgICAgICB2YXIga2V5ID0ga2V5cy5wb3AoKTtcbiAgICAgICAgaWYgKGtleSBpbiBvYmplY3QpIHtcbiAgICAgICAgICBuZXh0LnZhbHVlID0ga2V5O1xuICAgICAgICAgIG5leHQuZG9uZSA9IGZhbHNlO1xuICAgICAgICAgIHJldHVybiBuZXh0O1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIFRvIGF2b2lkIGNyZWF0aW5nIGFuIGFkZGl0aW9uYWwgb2JqZWN0LCB3ZSBqdXN0IGhhbmcgdGhlIC52YWx1ZVxuICAgICAgLy8gYW5kIC5kb25lIHByb3BlcnRpZXMgb2ZmIHRoZSBuZXh0IGZ1bmN0aW9uIG9iamVjdCBpdHNlbGYuIFRoaXNcbiAgICAgIC8vIGFsc28gZW5zdXJlcyB0aGF0IHRoZSBtaW5pZmllciB3aWxsIG5vdCBhbm9ueW1pemUgdGhlIGZ1bmN0aW9uLlxuICAgICAgbmV4dC5kb25lID0gdHJ1ZTtcbiAgICAgIHJldHVybiBuZXh0O1xuICAgIH07XG4gIH07XG5cbiAgZnVuY3Rpb24gdmFsdWVzKGl0ZXJhYmxlKSB7XG4gICAgaWYgKGl0ZXJhYmxlKSB7XG4gICAgICB2YXIgaXRlcmF0b3JNZXRob2QgPSBpdGVyYWJsZVtpdGVyYXRvclN5bWJvbF07XG4gICAgICBpZiAoaXRlcmF0b3JNZXRob2QpIHtcbiAgICAgICAgcmV0dXJuIGl0ZXJhdG9yTWV0aG9kLmNhbGwoaXRlcmFibGUpO1xuICAgICAgfVxuXG4gICAgICBpZiAodHlwZW9mIGl0ZXJhYmxlLm5leHQgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICByZXR1cm4gaXRlcmFibGU7XG4gICAgICB9XG5cbiAgICAgIGlmICghaXNOYU4oaXRlcmFibGUubGVuZ3RoKSkge1xuICAgICAgICB2YXIgaSA9IC0xLCBuZXh0ID0gZnVuY3Rpb24gbmV4dCgpIHtcbiAgICAgICAgICB3aGlsZSAoKytpIDwgaXRlcmFibGUubGVuZ3RoKSB7XG4gICAgICAgICAgICBpZiAoaGFzT3duLmNhbGwoaXRlcmFibGUsIGkpKSB7XG4gICAgICAgICAgICAgIG5leHQudmFsdWUgPSBpdGVyYWJsZVtpXTtcbiAgICAgICAgICAgICAgbmV4dC5kb25lID0gZmFsc2U7XG4gICAgICAgICAgICAgIHJldHVybiBuZXh0O1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIG5leHQudmFsdWUgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgbmV4dC5kb25lID0gdHJ1ZTtcblxuICAgICAgICAgIHJldHVybiBuZXh0O1xuICAgICAgICB9O1xuXG4gICAgICAgIHJldHVybiBuZXh0Lm5leHQgPSBuZXh0O1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIFJldHVybiBhbiBpdGVyYXRvciB3aXRoIG5vIHZhbHVlcy5cbiAgICByZXR1cm4geyBuZXh0OiBkb25lUmVzdWx0IH07XG4gIH1cbiAgcnVudGltZS52YWx1ZXMgPSB2YWx1ZXM7XG5cbiAgZnVuY3Rpb24gZG9uZVJlc3VsdCgpIHtcbiAgICByZXR1cm4geyB2YWx1ZTogdW5kZWZpbmVkLCBkb25lOiB0cnVlIH07XG4gIH1cblxuICBDb250ZXh0LnByb3RvdHlwZSA9IHtcbiAgICBjb25zdHJ1Y3RvcjogQ29udGV4dCxcblxuICAgIHJlc2V0OiBmdW5jdGlvbihza2lwVGVtcFJlc2V0KSB7XG4gICAgICB0aGlzLnByZXYgPSAwO1xuICAgICAgdGhpcy5uZXh0ID0gMDtcbiAgICAgIC8vIFJlc2V0dGluZyBjb250ZXh0Ll9zZW50IGZvciBsZWdhY3kgc3VwcG9ydCBvZiBCYWJlbCdzXG4gICAgICAvLyBmdW5jdGlvbi5zZW50IGltcGxlbWVudGF0aW9uLlxuICAgICAgdGhpcy5zZW50ID0gdGhpcy5fc2VudCA9IHVuZGVmaW5lZDtcbiAgICAgIHRoaXMuZG9uZSA9IGZhbHNlO1xuICAgICAgdGhpcy5kZWxlZ2F0ZSA9IG51bGw7XG5cbiAgICAgIHRoaXMubWV0aG9kID0gXCJuZXh0XCI7XG4gICAgICB0aGlzLmFyZyA9IHVuZGVmaW5lZDtcblxuICAgICAgdGhpcy50cnlFbnRyaWVzLmZvckVhY2gocmVzZXRUcnlFbnRyeSk7XG5cbiAgICAgIGlmICghc2tpcFRlbXBSZXNldCkge1xuICAgICAgICBmb3IgKHZhciBuYW1lIGluIHRoaXMpIHtcbiAgICAgICAgICAvLyBOb3Qgc3VyZSBhYm91dCB0aGUgb3B0aW1hbCBvcmRlciBvZiB0aGVzZSBjb25kaXRpb25zOlxuICAgICAgICAgIGlmIChuYW1lLmNoYXJBdCgwKSA9PT0gXCJ0XCIgJiZcbiAgICAgICAgICAgICAgaGFzT3duLmNhbGwodGhpcywgbmFtZSkgJiZcbiAgICAgICAgICAgICAgIWlzTmFOKCtuYW1lLnNsaWNlKDEpKSkge1xuICAgICAgICAgICAgdGhpc1tuYW1lXSA9IHVuZGVmaW5lZDtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9LFxuXG4gICAgc3RvcDogZnVuY3Rpb24oKSB7XG4gICAgICB0aGlzLmRvbmUgPSB0cnVlO1xuXG4gICAgICB2YXIgcm9vdEVudHJ5ID0gdGhpcy50cnlFbnRyaWVzWzBdO1xuICAgICAgdmFyIHJvb3RSZWNvcmQgPSByb290RW50cnkuY29tcGxldGlvbjtcbiAgICAgIGlmIChyb290UmVjb3JkLnR5cGUgPT09IFwidGhyb3dcIikge1xuICAgICAgICB0aHJvdyByb290UmVjb3JkLmFyZztcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRoaXMucnZhbDtcbiAgICB9LFxuXG4gICAgZGlzcGF0Y2hFeGNlcHRpb246IGZ1bmN0aW9uKGV4Y2VwdGlvbikge1xuICAgICAgaWYgKHRoaXMuZG9uZSkge1xuICAgICAgICB0aHJvdyBleGNlcHRpb247XG4gICAgICB9XG5cbiAgICAgIHZhciBjb250ZXh0ID0gdGhpcztcbiAgICAgIGZ1bmN0aW9uIGhhbmRsZShsb2MsIGNhdWdodCkge1xuICAgICAgICByZWNvcmQudHlwZSA9IFwidGhyb3dcIjtcbiAgICAgICAgcmVjb3JkLmFyZyA9IGV4Y2VwdGlvbjtcbiAgICAgICAgY29udGV4dC5uZXh0ID0gbG9jO1xuXG4gICAgICAgIGlmIChjYXVnaHQpIHtcbiAgICAgICAgICAvLyBJZiB0aGUgZGlzcGF0Y2hlZCBleGNlcHRpb24gd2FzIGNhdWdodCBieSBhIGNhdGNoIGJsb2NrLFxuICAgICAgICAgIC8vIHRoZW4gbGV0IHRoYXQgY2F0Y2ggYmxvY2sgaGFuZGxlIHRoZSBleGNlcHRpb24gbm9ybWFsbHkuXG4gICAgICAgICAgY29udGV4dC5tZXRob2QgPSBcIm5leHRcIjtcbiAgICAgICAgICBjb250ZXh0LmFyZyA9IHVuZGVmaW5lZDtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiAhISBjYXVnaHQ7XG4gICAgICB9XG5cbiAgICAgIGZvciAodmFyIGkgPSB0aGlzLnRyeUVudHJpZXMubGVuZ3RoIC0gMTsgaSA+PSAwOyAtLWkpIHtcbiAgICAgICAgdmFyIGVudHJ5ID0gdGhpcy50cnlFbnRyaWVzW2ldO1xuICAgICAgICB2YXIgcmVjb3JkID0gZW50cnkuY29tcGxldGlvbjtcblxuICAgICAgICBpZiAoZW50cnkudHJ5TG9jID09PSBcInJvb3RcIikge1xuICAgICAgICAgIC8vIEV4Y2VwdGlvbiB0aHJvd24gb3V0c2lkZSBvZiBhbnkgdHJ5IGJsb2NrIHRoYXQgY291bGQgaGFuZGxlXG4gICAgICAgICAgLy8gaXQsIHNvIHNldCB0aGUgY29tcGxldGlvbiB2YWx1ZSBvZiB0aGUgZW50aXJlIGZ1bmN0aW9uIHRvXG4gICAgICAgICAgLy8gdGhyb3cgdGhlIGV4Y2VwdGlvbi5cbiAgICAgICAgICByZXR1cm4gaGFuZGxlKFwiZW5kXCIpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGVudHJ5LnRyeUxvYyA8PSB0aGlzLnByZXYpIHtcbiAgICAgICAgICB2YXIgaGFzQ2F0Y2ggPSBoYXNPd24uY2FsbChlbnRyeSwgXCJjYXRjaExvY1wiKTtcbiAgICAgICAgICB2YXIgaGFzRmluYWxseSA9IGhhc093bi5jYWxsKGVudHJ5LCBcImZpbmFsbHlMb2NcIik7XG5cbiAgICAgICAgICBpZiAoaGFzQ2F0Y2ggJiYgaGFzRmluYWxseSkge1xuICAgICAgICAgICAgaWYgKHRoaXMucHJldiA8IGVudHJ5LmNhdGNoTG9jKSB7XG4gICAgICAgICAgICAgIHJldHVybiBoYW5kbGUoZW50cnkuY2F0Y2hMb2MsIHRydWUpO1xuICAgICAgICAgICAgfSBlbHNlIGlmICh0aGlzLnByZXYgPCBlbnRyeS5maW5hbGx5TG9jKSB7XG4gICAgICAgICAgICAgIHJldHVybiBoYW5kbGUoZW50cnkuZmluYWxseUxvYyk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICB9IGVsc2UgaWYgKGhhc0NhdGNoKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5wcmV2IDwgZW50cnkuY2F0Y2hMb2MpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIGhhbmRsZShlbnRyeS5jYXRjaExvYywgdHJ1ZSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICB9IGVsc2UgaWYgKGhhc0ZpbmFsbHkpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnByZXYgPCBlbnRyeS5maW5hbGx5TG9jKSB7XG4gICAgICAgICAgICAgIHJldHVybiBoYW5kbGUoZW50cnkuZmluYWxseUxvYyk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwidHJ5IHN0YXRlbWVudCB3aXRob3V0IGNhdGNoIG9yIGZpbmFsbHlcIik7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSxcblxuICAgIGFicnVwdDogZnVuY3Rpb24odHlwZSwgYXJnKSB7XG4gICAgICBmb3IgKHZhciBpID0gdGhpcy50cnlFbnRyaWVzLmxlbmd0aCAtIDE7IGkgPj0gMDsgLS1pKSB7XG4gICAgICAgIHZhciBlbnRyeSA9IHRoaXMudHJ5RW50cmllc1tpXTtcbiAgICAgICAgaWYgKGVudHJ5LnRyeUxvYyA8PSB0aGlzLnByZXYgJiZcbiAgICAgICAgICAgIGhhc093bi5jYWxsKGVudHJ5LCBcImZpbmFsbHlMb2NcIikgJiZcbiAgICAgICAgICAgIHRoaXMucHJldiA8IGVudHJ5LmZpbmFsbHlMb2MpIHtcbiAgICAgICAgICB2YXIgZmluYWxseUVudHJ5ID0gZW50cnk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKGZpbmFsbHlFbnRyeSAmJlxuICAgICAgICAgICh0eXBlID09PSBcImJyZWFrXCIgfHxcbiAgICAgICAgICAgdHlwZSA9PT0gXCJjb250aW51ZVwiKSAmJlxuICAgICAgICAgIGZpbmFsbHlFbnRyeS50cnlMb2MgPD0gYXJnICYmXG4gICAgICAgICAgYXJnIDw9IGZpbmFsbHlFbnRyeS5maW5hbGx5TG9jKSB7XG4gICAgICAgIC8vIElnbm9yZSB0aGUgZmluYWxseSBlbnRyeSBpZiBjb250cm9sIGlzIG5vdCBqdW1waW5nIHRvIGFcbiAgICAgICAgLy8gbG9jYXRpb24gb3V0c2lkZSB0aGUgdHJ5L2NhdGNoIGJsb2NrLlxuICAgICAgICBmaW5hbGx5RW50cnkgPSBudWxsO1xuICAgICAgfVxuXG4gICAgICB2YXIgcmVjb3JkID0gZmluYWxseUVudHJ5ID8gZmluYWxseUVudHJ5LmNvbXBsZXRpb24gOiB7fTtcbiAgICAgIHJlY29yZC50eXBlID0gdHlwZTtcbiAgICAgIHJlY29yZC5hcmcgPSBhcmc7XG5cbiAgICAgIGlmIChmaW5hbGx5RW50cnkpIHtcbiAgICAgICAgdGhpcy5tZXRob2QgPSBcIm5leHRcIjtcbiAgICAgICAgdGhpcy5uZXh0ID0gZmluYWxseUVudHJ5LmZpbmFsbHlMb2M7XG4gICAgICAgIHJldHVybiBDb250aW51ZVNlbnRpbmVsO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gdGhpcy5jb21wbGV0ZShyZWNvcmQpO1xuICAgIH0sXG5cbiAgICBjb21wbGV0ZTogZnVuY3Rpb24ocmVjb3JkLCBhZnRlckxvYykge1xuICAgICAgaWYgKHJlY29yZC50eXBlID09PSBcInRocm93XCIpIHtcbiAgICAgICAgdGhyb3cgcmVjb3JkLmFyZztcbiAgICAgIH1cblxuICAgICAgaWYgKHJlY29yZC50eXBlID09PSBcImJyZWFrXCIgfHxcbiAgICAgICAgICByZWNvcmQudHlwZSA9PT0gXCJjb250aW51ZVwiKSB7XG4gICAgICAgIHRoaXMubmV4dCA9IHJlY29yZC5hcmc7XG4gICAgICB9IGVsc2UgaWYgKHJlY29yZC50eXBlID09PSBcInJldHVyblwiKSB7XG4gICAgICAgIHRoaXMucnZhbCA9IHRoaXMuYXJnID0gcmVjb3JkLmFyZztcbiAgICAgICAgdGhpcy5tZXRob2QgPSBcInJldHVyblwiO1xuICAgICAgICB0aGlzLm5leHQgPSBcImVuZFwiO1xuICAgICAgfSBlbHNlIGlmIChyZWNvcmQudHlwZSA9PT0gXCJub3JtYWxcIiAmJiBhZnRlckxvYykge1xuICAgICAgICB0aGlzLm5leHQgPSBhZnRlckxvYztcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIENvbnRpbnVlU2VudGluZWw7XG4gICAgfSxcblxuICAgIGZpbmlzaDogZnVuY3Rpb24oZmluYWxseUxvYykge1xuICAgICAgZm9yICh2YXIgaSA9IHRoaXMudHJ5RW50cmllcy5sZW5ndGggLSAxOyBpID49IDA7IC0taSkge1xuICAgICAgICB2YXIgZW50cnkgPSB0aGlzLnRyeUVudHJpZXNbaV07XG4gICAgICAgIGlmIChlbnRyeS5maW5hbGx5TG9jID09PSBmaW5hbGx5TG9jKSB7XG4gICAgICAgICAgdGhpcy5jb21wbGV0ZShlbnRyeS5jb21wbGV0aW9uLCBlbnRyeS5hZnRlckxvYyk7XG4gICAgICAgICAgcmVzZXRUcnlFbnRyeShlbnRyeSk7XG4gICAgICAgICAgcmV0dXJuIENvbnRpbnVlU2VudGluZWw7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9LFxuXG4gICAgXCJjYXRjaFwiOiBmdW5jdGlvbih0cnlMb2MpIHtcbiAgICAgIGZvciAodmFyIGkgPSB0aGlzLnRyeUVudHJpZXMubGVuZ3RoIC0gMTsgaSA+PSAwOyAtLWkpIHtcbiAgICAgICAgdmFyIGVudHJ5ID0gdGhpcy50cnlFbnRyaWVzW2ldO1xuICAgICAgICBpZiAoZW50cnkudHJ5TG9jID09PSB0cnlMb2MpIHtcbiAgICAgICAgICB2YXIgcmVjb3JkID0gZW50cnkuY29tcGxldGlvbjtcbiAgICAgICAgICBpZiAocmVjb3JkLnR5cGUgPT09IFwidGhyb3dcIikge1xuICAgICAgICAgICAgdmFyIHRocm93biA9IHJlY29yZC5hcmc7XG4gICAgICAgICAgICByZXNldFRyeUVudHJ5KGVudHJ5KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIHRocm93bjtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBUaGUgY29udGV4dC5jYXRjaCBtZXRob2QgbXVzdCBvbmx5IGJlIGNhbGxlZCB3aXRoIGEgbG9jYXRpb25cbiAgICAgIC8vIGFyZ3VtZW50IHRoYXQgY29ycmVzcG9uZHMgdG8gYSBrbm93biBjYXRjaCBibG9jay5cbiAgICAgIHRocm93IG5ldyBFcnJvcihcImlsbGVnYWwgY2F0Y2ggYXR0ZW1wdFwiKTtcbiAgICB9LFxuXG4gICAgZGVsZWdhdGVZaWVsZDogZnVuY3Rpb24oaXRlcmFibGUsIHJlc3VsdE5hbWUsIG5leHRMb2MpIHtcbiAgICAgIHRoaXMuZGVsZWdhdGUgPSB7XG4gICAgICAgIGl0ZXJhdG9yOiB2YWx1ZXMoaXRlcmFibGUpLFxuICAgICAgICByZXN1bHROYW1lOiByZXN1bHROYW1lLFxuICAgICAgICBuZXh0TG9jOiBuZXh0TG9jXG4gICAgICB9O1xuXG4gICAgICBpZiAodGhpcy5tZXRob2QgPT09IFwibmV4dFwiKSB7XG4gICAgICAgIC8vIERlbGliZXJhdGVseSBmb3JnZXQgdGhlIGxhc3Qgc2VudCB2YWx1ZSBzbyB0aGF0IHdlIGRvbid0XG4gICAgICAgIC8vIGFjY2lkZW50YWxseSBwYXNzIGl0IG9uIHRvIHRoZSBkZWxlZ2F0ZS5cbiAgICAgICAgdGhpcy5hcmcgPSB1bmRlZmluZWQ7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBDb250aW51ZVNlbnRpbmVsO1xuICAgIH1cbiAgfTtcbn0pKFxuICAvLyBJbiBzbG9wcHkgbW9kZSwgdW5ib3VuZCBgdGhpc2AgcmVmZXJzIHRvIHRoZSBnbG9iYWwgb2JqZWN0LCBmYWxsYmFjayB0b1xuICAvLyBGdW5jdGlvbiBjb25zdHJ1Y3RvciBpZiB3ZSdyZSBpbiBnbG9iYWwgc3RyaWN0IG1vZGUuIFRoYXQgaXMgc2FkbHkgYSBmb3JtXG4gIC8vIG9mIGluZGlyZWN0IGV2YWwgd2hpY2ggdmlvbGF0ZXMgQ29udGVudCBTZWN1cml0eSBQb2xpY3kuXG4gIChmdW5jdGlvbigpIHsgcmV0dXJuIHRoaXMgfSkoKSB8fCBGdW5jdGlvbihcInJldHVybiB0aGlzXCIpKClcbik7XG4iLCJmdW5jdGlvbiBfYXBwbHlEZWNvcmF0ZWREZXNjcmlwdG9yKHRhcmdldCwgcHJvcGVydHksIGRlY29yYXRvcnMsIGRlc2NyaXB0b3IsIGNvbnRleHQpIHtcbiAgdmFyIGRlc2MgPSB7fTtcbiAgT2JqZWN0WydrZScgKyAneXMnXShkZXNjcmlwdG9yKS5mb3JFYWNoKGZ1bmN0aW9uIChrZXkpIHtcbiAgICBkZXNjW2tleV0gPSBkZXNjcmlwdG9yW2tleV07XG4gIH0pO1xuICBkZXNjLmVudW1lcmFibGUgPSAhIWRlc2MuZW51bWVyYWJsZTtcbiAgZGVzYy5jb25maWd1cmFibGUgPSAhIWRlc2MuY29uZmlndXJhYmxlO1xuXG4gIGlmICgndmFsdWUnIGluIGRlc2MgfHwgZGVzYy5pbml0aWFsaXplcikge1xuICAgIGRlc2Mud3JpdGFibGUgPSB0cnVlO1xuICB9XG5cbiAgZGVzYyA9IGRlY29yYXRvcnMuc2xpY2UoKS5yZXZlcnNlKCkucmVkdWNlKGZ1bmN0aW9uIChkZXNjLCBkZWNvcmF0b3IpIHtcbiAgICByZXR1cm4gZGVjb3JhdG9yKHRhcmdldCwgcHJvcGVydHksIGRlc2MpIHx8IGRlc2M7XG4gIH0sIGRlc2MpO1xuXG4gIGlmIChjb250ZXh0ICYmIGRlc2MuaW5pdGlhbGl6ZXIgIT09IHZvaWQgMCkge1xuICAgIGRlc2MudmFsdWUgPSBkZXNjLmluaXRpYWxpemVyID8gZGVzYy5pbml0aWFsaXplci5jYWxsKGNvbnRleHQpIDogdm9pZCAwO1xuICAgIGRlc2MuaW5pdGlhbGl6ZXIgPSB1bmRlZmluZWQ7XG4gIH1cblxuICBpZiAoZGVzYy5pbml0aWFsaXplciA9PT0gdm9pZCAwKSB7XG4gICAgT2JqZWN0WydkZWZpbmUnICsgJ1Byb3BlcnR5J10odGFyZ2V0LCBwcm9wZXJ0eSwgZGVzYyk7XG4gICAgZGVzYyA9IG51bGw7XG4gIH1cblxuICByZXR1cm4gZGVzYztcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBfYXBwbHlEZWNvcmF0ZWREZXNjcmlwdG9yOyIsImZ1bmN0aW9uIF9hcnJheVdpdGhIb2xlcyhhcnIpIHtcbiAgaWYgKEFycmF5LmlzQXJyYXkoYXJyKSkgcmV0dXJuIGFycjtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBfYXJyYXlXaXRoSG9sZXM7IiwiZnVuY3Rpb24gX2FycmF5V2l0aG91dEhvbGVzKGFycikge1xuICBpZiAoQXJyYXkuaXNBcnJheShhcnIpKSB7XG4gICAgZm9yICh2YXIgaSA9IDAsIGFycjIgPSBuZXcgQXJyYXkoYXJyLmxlbmd0aCk7IGkgPCBhcnIubGVuZ3RoOyBpKyspIHtcbiAgICAgIGFycjJbaV0gPSBhcnJbaV07XG4gICAgfVxuXG4gICAgcmV0dXJuIGFycjI7XG4gIH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBfYXJyYXlXaXRob3V0SG9sZXM7IiwiZnVuY3Rpb24gX2Fzc2VydFRoaXNJbml0aWFsaXplZChzZWxmKSB7XG4gIGlmIChzZWxmID09PSB2b2lkIDApIHtcbiAgICB0aHJvdyBuZXcgUmVmZXJlbmNlRXJyb3IoXCJ0aGlzIGhhc24ndCBiZWVuIGluaXRpYWxpc2VkIC0gc3VwZXIoKSBoYXNuJ3QgYmVlbiBjYWxsZWRcIik7XG4gIH1cblxuICByZXR1cm4gc2VsZjtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBfYXNzZXJ0VGhpc0luaXRpYWxpemVkOyIsImZ1bmN0aW9uIGFzeW5jR2VuZXJhdG9yU3RlcChnZW4sIHJlc29sdmUsIHJlamVjdCwgX25leHQsIF90aHJvdywga2V5LCBhcmcpIHtcbiAgdHJ5IHtcbiAgICB2YXIgaW5mbyA9IGdlbltrZXldKGFyZyk7XG4gICAgdmFyIHZhbHVlID0gaW5mby52YWx1ZTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICByZWplY3QoZXJyb3IpO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmIChpbmZvLmRvbmUpIHtcbiAgICByZXNvbHZlKHZhbHVlKTtcbiAgfSBlbHNlIHtcbiAgICBQcm9taXNlLnJlc29sdmUodmFsdWUpLnRoZW4oX25leHQsIF90aHJvdyk7XG4gIH1cbn1cblxuZnVuY3Rpb24gX2FzeW5jVG9HZW5lcmF0b3IoZm4pIHtcbiAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgc2VsZiA9IHRoaXMsXG4gICAgICAgIGFyZ3MgPSBhcmd1bWVudHM7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcbiAgICAgIHZhciBnZW4gPSBmbi5hcHBseShzZWxmLCBhcmdzKTtcblxuICAgICAgZnVuY3Rpb24gX25leHQodmFsdWUpIHtcbiAgICAgICAgYXN5bmNHZW5lcmF0b3JTdGVwKGdlbiwgcmVzb2x2ZSwgcmVqZWN0LCBfbmV4dCwgX3Rocm93LCBcIm5leHRcIiwgdmFsdWUpO1xuICAgICAgfVxuXG4gICAgICBmdW5jdGlvbiBfdGhyb3coZXJyKSB7XG4gICAgICAgIGFzeW5jR2VuZXJhdG9yU3RlcChnZW4sIHJlc29sdmUsIHJlamVjdCwgX25leHQsIF90aHJvdywgXCJ0aHJvd1wiLCBlcnIpO1xuICAgICAgfVxuXG4gICAgICBfbmV4dCh1bmRlZmluZWQpO1xuICAgIH0pO1xuICB9O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IF9hc3luY1RvR2VuZXJhdG9yOyIsImZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHtcbiAgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uXCIpO1xuICB9XG59XG5cbm1vZHVsZS5leHBvcnRzID0gX2NsYXNzQ2FsbENoZWNrOyIsInZhciBzZXRQcm90b3R5cGVPZiA9IHJlcXVpcmUoXCIuL3NldFByb3RvdHlwZU9mXCIpO1xuXG5mdW5jdGlvbiBpc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QoKSB7XG4gIGlmICh0eXBlb2YgUmVmbGVjdCA9PT0gXCJ1bmRlZmluZWRcIiB8fCAhUmVmbGVjdC5jb25zdHJ1Y3QpIHJldHVybiBmYWxzZTtcbiAgaWYgKFJlZmxlY3QuY29uc3RydWN0LnNoYW0pIHJldHVybiBmYWxzZTtcbiAgaWYgKHR5cGVvZiBQcm94eSA9PT0gXCJmdW5jdGlvblwiKSByZXR1cm4gdHJ1ZTtcblxuICB0cnkge1xuICAgIERhdGUucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoUmVmbGVjdC5jb25zdHJ1Y3QoRGF0ZSwgW10sIGZ1bmN0aW9uICgpIHt9KSk7XG4gICAgcmV0dXJuIHRydWU7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn1cblxuZnVuY3Rpb24gX2NvbnN0cnVjdChQYXJlbnQsIGFyZ3MsIENsYXNzKSB7XG4gIGlmIChpc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QoKSkge1xuICAgIG1vZHVsZS5leHBvcnRzID0gX2NvbnN0cnVjdCA9IFJlZmxlY3QuY29uc3RydWN0O1xuICB9IGVsc2Uge1xuICAgIG1vZHVsZS5leHBvcnRzID0gX2NvbnN0cnVjdCA9IGZ1bmN0aW9uIF9jb25zdHJ1Y3QoUGFyZW50LCBhcmdzLCBDbGFzcykge1xuICAgICAgdmFyIGEgPSBbbnVsbF07XG4gICAgICBhLnB1c2guYXBwbHkoYSwgYXJncyk7XG4gICAgICB2YXIgQ29uc3RydWN0b3IgPSBGdW5jdGlvbi5iaW5kLmFwcGx5KFBhcmVudCwgYSk7XG4gICAgICB2YXIgaW5zdGFuY2UgPSBuZXcgQ29uc3RydWN0b3IoKTtcbiAgICAgIGlmIChDbGFzcykgc2V0UHJvdG90eXBlT2YoaW5zdGFuY2UsIENsYXNzLnByb3RvdHlwZSk7XG4gICAgICByZXR1cm4gaW5zdGFuY2U7XG4gICAgfTtcbiAgfVxuXG4gIHJldHVybiBfY29uc3RydWN0LmFwcGx5KG51bGwsIGFyZ3VtZW50cyk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gX2NvbnN0cnVjdDsiLCJmdW5jdGlvbiBfZGVmaW5lUHJvcGVydGllcyh0YXJnZXQsIHByb3BzKSB7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgcHJvcHMubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgZGVzY3JpcHRvciA9IHByb3BzW2ldO1xuICAgIGRlc2NyaXB0b3IuZW51bWVyYWJsZSA9IGRlc2NyaXB0b3IuZW51bWVyYWJsZSB8fCBmYWxzZTtcbiAgICBkZXNjcmlwdG9yLmNvbmZpZ3VyYWJsZSA9IHRydWU7XG4gICAgaWYgKFwidmFsdWVcIiBpbiBkZXNjcmlwdG9yKSBkZXNjcmlwdG9yLndyaXRhYmxlID0gdHJ1ZTtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBkZXNjcmlwdG9yLmtleSwgZGVzY3JpcHRvcik7XG4gIH1cbn1cblxuZnVuY3Rpb24gX2NyZWF0ZUNsYXNzKENvbnN0cnVjdG9yLCBwcm90b1Byb3BzLCBzdGF0aWNQcm9wcykge1xuICBpZiAocHJvdG9Qcm9wcykgX2RlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IucHJvdG90eXBlLCBwcm90b1Byb3BzKTtcbiAgaWYgKHN0YXRpY1Byb3BzKSBfZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvciwgc3RhdGljUHJvcHMpO1xuICByZXR1cm4gQ29uc3RydWN0b3I7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gX2NyZWF0ZUNsYXNzOyIsImZ1bmN0aW9uIF9kZWZpbmVQcm9wZXJ0eShvYmosIGtleSwgdmFsdWUpIHtcbiAgaWYgKGtleSBpbiBvYmopIHtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkob2JqLCBrZXksIHtcbiAgICAgIHZhbHVlOiB2YWx1ZSxcbiAgICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICB3cml0YWJsZTogdHJ1ZVxuICAgIH0pO1xuICB9IGVsc2Uge1xuICAgIG9ialtrZXldID0gdmFsdWU7XG4gIH1cblxuICByZXR1cm4gb2JqO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IF9kZWZpbmVQcm9wZXJ0eTsiLCJmdW5jdGlvbiBfZ2V0UHJvdG90eXBlT2Yobykge1xuICBtb2R1bGUuZXhwb3J0cyA9IF9nZXRQcm90b3R5cGVPZiA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiA/IE9iamVjdC5nZXRQcm90b3R5cGVPZiA6IGZ1bmN0aW9uIF9nZXRQcm90b3R5cGVPZihvKSB7XG4gICAgcmV0dXJuIG8uX19wcm90b19fIHx8IE9iamVjdC5nZXRQcm90b3R5cGVPZihvKTtcbiAgfTtcbiAgcmV0dXJuIF9nZXRQcm90b3R5cGVPZihvKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBfZ2V0UHJvdG90eXBlT2Y7IiwidmFyIHNldFByb3RvdHlwZU9mID0gcmVxdWlyZShcIi4vc2V0UHJvdG90eXBlT2ZcIik7XG5cbmZ1bmN0aW9uIF9pbmhlcml0cyhzdWJDbGFzcywgc3VwZXJDbGFzcykge1xuICBpZiAodHlwZW9mIHN1cGVyQ2xhc3MgIT09IFwiZnVuY3Rpb25cIiAmJiBzdXBlckNsYXNzICE9PSBudWxsKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlN1cGVyIGV4cHJlc3Npb24gbXVzdCBlaXRoZXIgYmUgbnVsbCBvciBhIGZ1bmN0aW9uXCIpO1xuICB9XG5cbiAgc3ViQ2xhc3MucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShzdXBlckNsYXNzICYmIHN1cGVyQ2xhc3MucHJvdG90eXBlLCB7XG4gICAgY29uc3RydWN0b3I6IHtcbiAgICAgIHZhbHVlOiBzdWJDbGFzcyxcbiAgICAgIHdyaXRhYmxlOiB0cnVlLFxuICAgICAgY29uZmlndXJhYmxlOiB0cnVlXG4gICAgfVxuICB9KTtcbiAgaWYgKHN1cGVyQ2xhc3MpIHNldFByb3RvdHlwZU9mKHN1YkNsYXNzLCBzdXBlckNsYXNzKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBfaW5oZXJpdHM7IiwiZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHtcbiAgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHtcbiAgICBkZWZhdWx0OiBvYmpcbiAgfTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0OyIsImZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZVdpbGRjYXJkKG9iaikge1xuICBpZiAob2JqICYmIG9iai5fX2VzTW9kdWxlKSB7XG4gICAgcmV0dXJuIG9iajtcbiAgfSBlbHNlIHtcbiAgICB2YXIgbmV3T2JqID0ge307XG5cbiAgICBpZiAob2JqICE9IG51bGwpIHtcbiAgICAgIGZvciAodmFyIGtleSBpbiBvYmopIHtcbiAgICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvYmosIGtleSkpIHtcbiAgICAgICAgICB2YXIgZGVzYyA9IE9iamVjdC5kZWZpbmVQcm9wZXJ0eSAmJiBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yID8gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihvYmosIGtleSkgOiB7fTtcblxuICAgICAgICAgIGlmIChkZXNjLmdldCB8fCBkZXNjLnNldCkge1xuICAgICAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG5ld09iaiwga2V5LCBkZXNjKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbmV3T2JqW2tleV0gPSBvYmpba2V5XTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBuZXdPYmouZGVmYXVsdCA9IG9iajtcbiAgICByZXR1cm4gbmV3T2JqO1xuICB9XG59XG5cbm1vZHVsZS5leHBvcnRzID0gX2ludGVyb3BSZXF1aXJlV2lsZGNhcmQ7IiwiZnVuY3Rpb24gX2lzTmF0aXZlRnVuY3Rpb24oZm4pIHtcbiAgcmV0dXJuIEZ1bmN0aW9uLnRvU3RyaW5nLmNhbGwoZm4pLmluZGV4T2YoXCJbbmF0aXZlIGNvZGVdXCIpICE9PSAtMTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBfaXNOYXRpdmVGdW5jdGlvbjsiLCJmdW5jdGlvbiBfaXRlcmFibGVUb0FycmF5KGl0ZXIpIHtcbiAgaWYgKFN5bWJvbC5pdGVyYXRvciBpbiBPYmplY3QoaXRlcikgfHwgT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKGl0ZXIpID09PSBcIltvYmplY3QgQXJndW1lbnRzXVwiKSByZXR1cm4gQXJyYXkuZnJvbShpdGVyKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBfaXRlcmFibGVUb0FycmF5OyIsImZ1bmN0aW9uIF9pdGVyYWJsZVRvQXJyYXlMaW1pdChhcnIsIGkpIHtcbiAgdmFyIF9hcnIgPSBbXTtcbiAgdmFyIF9uID0gdHJ1ZTtcbiAgdmFyIF9kID0gZmFsc2U7XG4gIHZhciBfZSA9IHVuZGVmaW5lZDtcblxuICB0cnkge1xuICAgIGZvciAodmFyIF9pID0gYXJyW1N5bWJvbC5pdGVyYXRvcl0oKSwgX3M7ICEoX24gPSAoX3MgPSBfaS5uZXh0KCkpLmRvbmUpOyBfbiA9IHRydWUpIHtcbiAgICAgIF9hcnIucHVzaChfcy52YWx1ZSk7XG5cbiAgICAgIGlmIChpICYmIF9hcnIubGVuZ3RoID09PSBpKSBicmVhaztcbiAgICB9XG4gIH0gY2F0Y2ggKGVycikge1xuICAgIF9kID0gdHJ1ZTtcbiAgICBfZSA9IGVycjtcbiAgfSBmaW5hbGx5IHtcbiAgICB0cnkge1xuICAgICAgaWYgKCFfbiAmJiBfaVtcInJldHVyblwiXSAhPSBudWxsKSBfaVtcInJldHVyblwiXSgpO1xuICAgIH0gZmluYWxseSB7XG4gICAgICBpZiAoX2QpIHRocm93IF9lO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBfYXJyO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IF9pdGVyYWJsZVRvQXJyYXlMaW1pdDsiLCJmdW5jdGlvbiBfbm9uSXRlcmFibGVSZXN0KCkge1xuICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiSW52YWxpZCBhdHRlbXB0IHRvIGRlc3RydWN0dXJlIG5vbi1pdGVyYWJsZSBpbnN0YW5jZVwiKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBfbm9uSXRlcmFibGVSZXN0OyIsImZ1bmN0aW9uIF9ub25JdGVyYWJsZVNwcmVhZCgpIHtcbiAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkludmFsaWQgYXR0ZW1wdCB0byBzcHJlYWQgbm9uLWl0ZXJhYmxlIGluc3RhbmNlXCIpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IF9ub25JdGVyYWJsZVNwcmVhZDsiLCJ2YXIgZGVmaW5lUHJvcGVydHkgPSByZXF1aXJlKFwiLi9kZWZpbmVQcm9wZXJ0eVwiKTtcblxuZnVuY3Rpb24gX29iamVjdFNwcmVhZCh0YXJnZXQpIHtcbiAgZm9yICh2YXIgaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgc291cmNlID0gYXJndW1lbnRzW2ldICE9IG51bGwgPyBhcmd1bWVudHNbaV0gOiB7fTtcbiAgICB2YXIgb3duS2V5cyA9IE9iamVjdC5rZXlzKHNvdXJjZSk7XG5cbiAgICBpZiAodHlwZW9mIE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIG93bktleXMgPSBvd25LZXlzLmNvbmNhdChPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzKHNvdXJjZSkuZmlsdGVyKGZ1bmN0aW9uIChzeW0pIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3Ioc291cmNlLCBzeW0pLmVudW1lcmFibGU7XG4gICAgICB9KSk7XG4gICAgfVxuXG4gICAgb3duS2V5cy5mb3JFYWNoKGZ1bmN0aW9uIChrZXkpIHtcbiAgICAgIGRlZmluZVByb3BlcnR5KHRhcmdldCwga2V5LCBzb3VyY2Vba2V5XSk7XG4gICAgfSk7XG4gIH1cblxuICByZXR1cm4gdGFyZ2V0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IF9vYmplY3RTcHJlYWQ7IiwidmFyIF90eXBlb2YgPSByZXF1aXJlKFwiLi4vaGVscGVycy90eXBlb2ZcIik7XG5cbnZhciBhc3NlcnRUaGlzSW5pdGlhbGl6ZWQgPSByZXF1aXJlKFwiLi9hc3NlcnRUaGlzSW5pdGlhbGl6ZWRcIik7XG5cbmZ1bmN0aW9uIF9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuKHNlbGYsIGNhbGwpIHtcbiAgaWYgKGNhbGwgJiYgKF90eXBlb2YoY2FsbCkgPT09IFwib2JqZWN0XCIgfHwgdHlwZW9mIGNhbGwgPT09IFwiZnVuY3Rpb25cIikpIHtcbiAgICByZXR1cm4gY2FsbDtcbiAgfVxuXG4gIHJldHVybiBhc3NlcnRUaGlzSW5pdGlhbGl6ZWQoc2VsZik7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm47IiwiZnVuY3Rpb24gX3NldFByb3RvdHlwZU9mKG8sIHApIHtcbiAgbW9kdWxlLmV4cG9ydHMgPSBfc2V0UHJvdG90eXBlT2YgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHwgZnVuY3Rpb24gX3NldFByb3RvdHlwZU9mKG8sIHApIHtcbiAgICBvLl9fcHJvdG9fXyA9IHA7XG4gICAgcmV0dXJuIG87XG4gIH07XG5cbiAgcmV0dXJuIF9zZXRQcm90b3R5cGVPZihvLCBwKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBfc2V0UHJvdG90eXBlT2Y7IiwidmFyIGFycmF5V2l0aEhvbGVzID0gcmVxdWlyZShcIi4vYXJyYXlXaXRoSG9sZXNcIik7XG5cbnZhciBpdGVyYWJsZVRvQXJyYXlMaW1pdCA9IHJlcXVpcmUoXCIuL2l0ZXJhYmxlVG9BcnJheUxpbWl0XCIpO1xuXG52YXIgbm9uSXRlcmFibGVSZXN0ID0gcmVxdWlyZShcIi4vbm9uSXRlcmFibGVSZXN0XCIpO1xuXG5mdW5jdGlvbiBfc2xpY2VkVG9BcnJheShhcnIsIGkpIHtcbiAgcmV0dXJuIGFycmF5V2l0aEhvbGVzKGFycikgfHwgaXRlcmFibGVUb0FycmF5TGltaXQoYXJyLCBpKSB8fCBub25JdGVyYWJsZVJlc3QoKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBfc2xpY2VkVG9BcnJheTsiLCJ2YXIgYXJyYXlXaXRoSG9sZXMgPSByZXF1aXJlKFwiLi9hcnJheVdpdGhIb2xlc1wiKTtcblxudmFyIGl0ZXJhYmxlVG9BcnJheSA9IHJlcXVpcmUoXCIuL2l0ZXJhYmxlVG9BcnJheVwiKTtcblxudmFyIG5vbkl0ZXJhYmxlUmVzdCA9IHJlcXVpcmUoXCIuL25vbkl0ZXJhYmxlUmVzdFwiKTtcblxuZnVuY3Rpb24gX3RvQXJyYXkoYXJyKSB7XG4gIHJldHVybiBhcnJheVdpdGhIb2xlcyhhcnIpIHx8IGl0ZXJhYmxlVG9BcnJheShhcnIpIHx8IG5vbkl0ZXJhYmxlUmVzdCgpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IF90b0FycmF5OyIsInZhciBhcnJheVdpdGhvdXRIb2xlcyA9IHJlcXVpcmUoXCIuL2FycmF5V2l0aG91dEhvbGVzXCIpO1xuXG52YXIgaXRlcmFibGVUb0FycmF5ID0gcmVxdWlyZShcIi4vaXRlcmFibGVUb0FycmF5XCIpO1xuXG52YXIgbm9uSXRlcmFibGVTcHJlYWQgPSByZXF1aXJlKFwiLi9ub25JdGVyYWJsZVNwcmVhZFwiKTtcblxuZnVuY3Rpb24gX3RvQ29uc3VtYWJsZUFycmF5KGFycikge1xuICByZXR1cm4gYXJyYXlXaXRob3V0SG9sZXMoYXJyKSB8fCBpdGVyYWJsZVRvQXJyYXkoYXJyKSB8fCBub25JdGVyYWJsZVNwcmVhZCgpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IF90b0NvbnN1bWFibGVBcnJheTsiLCJmdW5jdGlvbiBfdHlwZW9mMihvYmopIHsgaWYgKHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiB0eXBlb2YgU3ltYm9sLml0ZXJhdG9yID09PSBcInN5bWJvbFwiKSB7IF90eXBlb2YyID0gZnVuY3Rpb24gX3R5cGVvZjIob2JqKSB7IHJldHVybiB0eXBlb2Ygb2JqOyB9OyB9IGVsc2UgeyBfdHlwZW9mMiA9IGZ1bmN0aW9uIF90eXBlb2YyKG9iaikgeyByZXR1cm4gb2JqICYmIHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiBvYmouY29uc3RydWN0b3IgPT09IFN5bWJvbCAmJiBvYmogIT09IFN5bWJvbC5wcm90b3R5cGUgPyBcInN5bWJvbFwiIDogdHlwZW9mIG9iajsgfTsgfSByZXR1cm4gX3R5cGVvZjIob2JqKTsgfVxuXG5mdW5jdGlvbiBfdHlwZW9mKG9iaikge1xuICBpZiAodHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIF90eXBlb2YyKFN5bWJvbC5pdGVyYXRvcikgPT09IFwic3ltYm9sXCIpIHtcbiAgICBtb2R1bGUuZXhwb3J0cyA9IF90eXBlb2YgPSBmdW5jdGlvbiBfdHlwZW9mKG9iaikge1xuICAgICAgcmV0dXJuIF90eXBlb2YyKG9iaik7XG4gICAgfTtcbiAgfSBlbHNlIHtcbiAgICBtb2R1bGUuZXhwb3J0cyA9IF90eXBlb2YgPSBmdW5jdGlvbiBfdHlwZW9mKG9iaikge1xuICAgICAgcmV0dXJuIG9iaiAmJiB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgb2JqLmNvbnN0cnVjdG9yID09PSBTeW1ib2wgJiYgb2JqICE9PSBTeW1ib2wucHJvdG90eXBlID8gXCJzeW1ib2xcIiA6IF90eXBlb2YyKG9iaik7XG4gICAgfTtcbiAgfVxuXG4gIHJldHVybiBfdHlwZW9mKG9iaik7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gX3R5cGVvZjsiLCJ2YXIgZ2V0UHJvdG90eXBlT2YgPSByZXF1aXJlKFwiLi9nZXRQcm90b3R5cGVPZlwiKTtcblxudmFyIHNldFByb3RvdHlwZU9mID0gcmVxdWlyZShcIi4vc2V0UHJvdG90eXBlT2ZcIik7XG5cbnZhciBpc05hdGl2ZUZ1bmN0aW9uID0gcmVxdWlyZShcIi4vaXNOYXRpdmVGdW5jdGlvblwiKTtcblxudmFyIGNvbnN0cnVjdCA9IHJlcXVpcmUoXCIuL2NvbnN0cnVjdFwiKTtcblxuZnVuY3Rpb24gX3dyYXBOYXRpdmVTdXBlcihDbGFzcykge1xuICB2YXIgX2NhY2hlID0gdHlwZW9mIE1hcCA9PT0gXCJmdW5jdGlvblwiID8gbmV3IE1hcCgpIDogdW5kZWZpbmVkO1xuXG4gIG1vZHVsZS5leHBvcnRzID0gX3dyYXBOYXRpdmVTdXBlciA9IGZ1bmN0aW9uIF93cmFwTmF0aXZlU3VwZXIoQ2xhc3MpIHtcbiAgICBpZiAoQ2xhc3MgPT09IG51bGwgfHwgIWlzTmF0aXZlRnVuY3Rpb24oQ2xhc3MpKSByZXR1cm4gQ2xhc3M7XG5cbiAgICBpZiAodHlwZW9mIENsYXNzICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJTdXBlciBleHByZXNzaW9uIG11c3QgZWl0aGVyIGJlIG51bGwgb3IgYSBmdW5jdGlvblwiKTtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIF9jYWNoZSAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgaWYgKF9jYWNoZS5oYXMoQ2xhc3MpKSByZXR1cm4gX2NhY2hlLmdldChDbGFzcyk7XG5cbiAgICAgIF9jYWNoZS5zZXQoQ2xhc3MsIFdyYXBwZXIpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIFdyYXBwZXIoKSB7XG4gICAgICByZXR1cm4gY29uc3RydWN0KENsYXNzLCBhcmd1bWVudHMsIGdldFByb3RvdHlwZU9mKHRoaXMpLmNvbnN0cnVjdG9yKTtcbiAgICB9XG5cbiAgICBXcmFwcGVyLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoQ2xhc3MucHJvdG90eXBlLCB7XG4gICAgICBjb25zdHJ1Y3Rvcjoge1xuICAgICAgICB2YWx1ZTogV3JhcHBlcixcbiAgICAgICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgICAgIHdyaXRhYmxlOiB0cnVlLFxuICAgICAgICBjb25maWd1cmFibGU6IHRydWVcbiAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gc2V0UHJvdG90eXBlT2YoV3JhcHBlciwgQ2xhc3MpO1xuICB9O1xuXG4gIHJldHVybiBfd3JhcE5hdGl2ZVN1cGVyKENsYXNzKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBfd3JhcE5hdGl2ZVN1cGVyOyIsIi8qKlxuICogQ29weXJpZ2h0IChjKSAyMDE0LXByZXNlbnQsIEZhY2Vib29rLCBJbmMuXG4gKlxuICogVGhpcyBzb3VyY2UgY29kZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgTUlUIGxpY2Vuc2UgZm91bmQgaW4gdGhlXG4gKiBMSUNFTlNFIGZpbGUgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mIHRoaXMgc291cmNlIHRyZWUuXG4gKi9cblxuLy8gVGhpcyBtZXRob2Qgb2Ygb2J0YWluaW5nIGEgcmVmZXJlbmNlIHRvIHRoZSBnbG9iYWwgb2JqZWN0IG5lZWRzIHRvIGJlXG4vLyBrZXB0IGlkZW50aWNhbCB0byB0aGUgd2F5IGl0IGlzIG9idGFpbmVkIGluIHJ1bnRpbWUuanNcbnZhciBnID0gKGZ1bmN0aW9uKCkge1xuICByZXR1cm4gdGhpcyB8fCAodHlwZW9mIHNlbGYgPT09IFwib2JqZWN0XCIgJiYgc2VsZik7XG59KSgpIHx8IEZ1bmN0aW9uKFwicmV0dXJuIHRoaXNcIikoKTtcblxuLy8gVXNlIGBnZXRPd25Qcm9wZXJ0eU5hbWVzYCBiZWNhdXNlIG5vdCBhbGwgYnJvd3NlcnMgc3VwcG9ydCBjYWxsaW5nXG4vLyBgaGFzT3duUHJvcGVydHlgIG9uIHRoZSBnbG9iYWwgYHNlbGZgIG9iamVjdCBpbiBhIHdvcmtlci4gU2VlICMxODMuXG52YXIgaGFkUnVudGltZSA9IGcucmVnZW5lcmF0b3JSdW50aW1lICYmXG4gIE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKGcpLmluZGV4T2YoXCJyZWdlbmVyYXRvclJ1bnRpbWVcIikgPj0gMDtcblxuLy8gU2F2ZSB0aGUgb2xkIHJlZ2VuZXJhdG9yUnVudGltZSBpbiBjYXNlIGl0IG5lZWRzIHRvIGJlIHJlc3RvcmVkIGxhdGVyLlxudmFyIG9sZFJ1bnRpbWUgPSBoYWRSdW50aW1lICYmIGcucmVnZW5lcmF0b3JSdW50aW1lO1xuXG4vLyBGb3JjZSByZWV2YWx1dGF0aW9uIG9mIHJ1bnRpbWUuanMuXG5nLnJlZ2VuZXJhdG9yUnVudGltZSA9IHVuZGVmaW5lZDtcblxubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiLi9ydW50aW1lXCIpO1xuXG5pZiAoaGFkUnVudGltZSkge1xuICAvLyBSZXN0b3JlIHRoZSBvcmlnaW5hbCBydW50aW1lLlxuICBnLnJlZ2VuZXJhdG9yUnVudGltZSA9IG9sZFJ1bnRpbWU7XG59IGVsc2Uge1xuICAvLyBSZW1vdmUgdGhlIGdsb2JhbCBwcm9wZXJ0eSBhZGRlZCBieSBydW50aW1lLmpzLlxuICB0cnkge1xuICAgIGRlbGV0ZSBnLnJlZ2VuZXJhdG9yUnVudGltZTtcbiAgfSBjYXRjaChlKSB7XG4gICAgZy5yZWdlbmVyYXRvclJ1bnRpbWUgPSB1bmRlZmluZWQ7XG4gIH1cbn1cbiIsIi8qKlxuICogQ29weXJpZ2h0IChjKSAyMDE0LXByZXNlbnQsIEZhY2Vib29rLCBJbmMuXG4gKlxuICogVGhpcyBzb3VyY2UgY29kZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgTUlUIGxpY2Vuc2UgZm91bmQgaW4gdGhlXG4gKiBMSUNFTlNFIGZpbGUgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mIHRoaXMgc291cmNlIHRyZWUuXG4gKi9cblxuIShmdW5jdGlvbihnbG9iYWwpIHtcbiAgXCJ1c2Ugc3RyaWN0XCI7XG5cbiAgdmFyIE9wID0gT2JqZWN0LnByb3RvdHlwZTtcbiAgdmFyIGhhc093biA9IE9wLmhhc093blByb3BlcnR5O1xuICB2YXIgdW5kZWZpbmVkOyAvLyBNb3JlIGNvbXByZXNzaWJsZSB0aGFuIHZvaWQgMC5cbiAgdmFyICRTeW1ib2wgPSB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgPyBTeW1ib2wgOiB7fTtcbiAgdmFyIGl0ZXJhdG9yU3ltYm9sID0gJFN5bWJvbC5pdGVyYXRvciB8fCBcIkBAaXRlcmF0b3JcIjtcbiAgdmFyIGFzeW5jSXRlcmF0b3JTeW1ib2wgPSAkU3ltYm9sLmFzeW5jSXRlcmF0b3IgfHwgXCJAQGFzeW5jSXRlcmF0b3JcIjtcbiAgdmFyIHRvU3RyaW5nVGFnU3ltYm9sID0gJFN5bWJvbC50b1N0cmluZ1RhZyB8fCBcIkBAdG9TdHJpbmdUYWdcIjtcblxuICB2YXIgaW5Nb2R1bGUgPSB0eXBlb2YgbW9kdWxlID09PSBcIm9iamVjdFwiO1xuICB2YXIgcnVudGltZSA9IGdsb2JhbC5yZWdlbmVyYXRvclJ1bnRpbWU7XG4gIGlmIChydW50aW1lKSB7XG4gICAgaWYgKGluTW9kdWxlKSB7XG4gICAgICAvLyBJZiByZWdlbmVyYXRvclJ1bnRpbWUgaXMgZGVmaW5lZCBnbG9iYWxseSBhbmQgd2UncmUgaW4gYSBtb2R1bGUsXG4gICAgICAvLyBtYWtlIHRoZSBleHBvcnRzIG9iamVjdCBpZGVudGljYWwgdG8gcmVnZW5lcmF0b3JSdW50aW1lLlxuICAgICAgbW9kdWxlLmV4cG9ydHMgPSBydW50aW1lO1xuICAgIH1cbiAgICAvLyBEb24ndCBib3RoZXIgZXZhbHVhdGluZyB0aGUgcmVzdCBvZiB0aGlzIGZpbGUgaWYgdGhlIHJ1bnRpbWUgd2FzXG4gICAgLy8gYWxyZWFkeSBkZWZpbmVkIGdsb2JhbGx5LlxuICAgIHJldHVybjtcbiAgfVxuXG4gIC8vIERlZmluZSB0aGUgcnVudGltZSBnbG9iYWxseSAoYXMgZXhwZWN0ZWQgYnkgZ2VuZXJhdGVkIGNvZGUpIGFzIGVpdGhlclxuICAvLyBtb2R1bGUuZXhwb3J0cyAoaWYgd2UncmUgaW4gYSBtb2R1bGUpIG9yIGEgbmV3LCBlbXB0eSBvYmplY3QuXG4gIHJ1bnRpbWUgPSBnbG9iYWwucmVnZW5lcmF0b3JSdW50aW1lID0gaW5Nb2R1bGUgPyBtb2R1bGUuZXhwb3J0cyA6IHt9O1xuXG4gIGZ1bmN0aW9uIHdyYXAoaW5uZXJGbiwgb3V0ZXJGbiwgc2VsZiwgdHJ5TG9jc0xpc3QpIHtcbiAgICAvLyBJZiBvdXRlckZuIHByb3ZpZGVkIGFuZCBvdXRlckZuLnByb3RvdHlwZSBpcyBhIEdlbmVyYXRvciwgdGhlbiBvdXRlckZuLnByb3RvdHlwZSBpbnN0YW5jZW9mIEdlbmVyYXRvci5cbiAgICB2YXIgcHJvdG9HZW5lcmF0b3IgPSBvdXRlckZuICYmIG91dGVyRm4ucHJvdG90eXBlIGluc3RhbmNlb2YgR2VuZXJhdG9yID8gb3V0ZXJGbiA6IEdlbmVyYXRvcjtcbiAgICB2YXIgZ2VuZXJhdG9yID0gT2JqZWN0LmNyZWF0ZShwcm90b0dlbmVyYXRvci5wcm90b3R5cGUpO1xuICAgIHZhciBjb250ZXh0ID0gbmV3IENvbnRleHQodHJ5TG9jc0xpc3QgfHwgW10pO1xuXG4gICAgLy8gVGhlIC5faW52b2tlIG1ldGhvZCB1bmlmaWVzIHRoZSBpbXBsZW1lbnRhdGlvbnMgb2YgdGhlIC5uZXh0LFxuICAgIC8vIC50aHJvdywgYW5kIC5yZXR1cm4gbWV0aG9kcy5cbiAgICBnZW5lcmF0b3IuX2ludm9rZSA9IG1ha2VJbnZva2VNZXRob2QoaW5uZXJGbiwgc2VsZiwgY29udGV4dCk7XG5cbiAgICByZXR1cm4gZ2VuZXJhdG9yO1xuICB9XG4gIHJ1bnRpbWUud3JhcCA9IHdyYXA7XG5cbiAgLy8gVHJ5L2NhdGNoIGhlbHBlciB0byBtaW5pbWl6ZSBkZW9wdGltaXphdGlvbnMuIFJldHVybnMgYSBjb21wbGV0aW9uXG4gIC8vIHJlY29yZCBsaWtlIGNvbnRleHQudHJ5RW50cmllc1tpXS5jb21wbGV0aW9uLiBUaGlzIGludGVyZmFjZSBjb3VsZFxuICAvLyBoYXZlIGJlZW4gKGFuZCB3YXMgcHJldmlvdXNseSkgZGVzaWduZWQgdG8gdGFrZSBhIGNsb3N1cmUgdG8gYmVcbiAgLy8gaW52b2tlZCB3aXRob3V0IGFyZ3VtZW50cywgYnV0IGluIGFsbCB0aGUgY2FzZXMgd2UgY2FyZSBhYm91dCB3ZVxuICAvLyBhbHJlYWR5IGhhdmUgYW4gZXhpc3RpbmcgbWV0aG9kIHdlIHdhbnQgdG8gY2FsbCwgc28gdGhlcmUncyBubyBuZWVkXG4gIC8vIHRvIGNyZWF0ZSBhIG5ldyBmdW5jdGlvbiBvYmplY3QuIFdlIGNhbiBldmVuIGdldCBhd2F5IHdpdGggYXNzdW1pbmdcbiAgLy8gdGhlIG1ldGhvZCB0YWtlcyBleGFjdGx5IG9uZSBhcmd1bWVudCwgc2luY2UgdGhhdCBoYXBwZW5zIHRvIGJlIHRydWVcbiAgLy8gaW4gZXZlcnkgY2FzZSwgc28gd2UgZG9uJ3QgaGF2ZSB0byB0b3VjaCB0aGUgYXJndW1lbnRzIG9iamVjdC4gVGhlXG4gIC8vIG9ubHkgYWRkaXRpb25hbCBhbGxvY2F0aW9uIHJlcXVpcmVkIGlzIHRoZSBjb21wbGV0aW9uIHJlY29yZCwgd2hpY2hcbiAgLy8gaGFzIGEgc3RhYmxlIHNoYXBlIGFuZCBzbyBob3BlZnVsbHkgc2hvdWxkIGJlIGNoZWFwIHRvIGFsbG9jYXRlLlxuICBmdW5jdGlvbiB0cnlDYXRjaChmbiwgb2JqLCBhcmcpIHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIHsgdHlwZTogXCJub3JtYWxcIiwgYXJnOiBmbi5jYWxsKG9iaiwgYXJnKSB9O1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgcmV0dXJuIHsgdHlwZTogXCJ0aHJvd1wiLCBhcmc6IGVyciB9O1xuICAgIH1cbiAgfVxuXG4gIHZhciBHZW5TdGF0ZVN1c3BlbmRlZFN0YXJ0ID0gXCJzdXNwZW5kZWRTdGFydFwiO1xuICB2YXIgR2VuU3RhdGVTdXNwZW5kZWRZaWVsZCA9IFwic3VzcGVuZGVkWWllbGRcIjtcbiAgdmFyIEdlblN0YXRlRXhlY3V0aW5nID0gXCJleGVjdXRpbmdcIjtcbiAgdmFyIEdlblN0YXRlQ29tcGxldGVkID0gXCJjb21wbGV0ZWRcIjtcblxuICAvLyBSZXR1cm5pbmcgdGhpcyBvYmplY3QgZnJvbSB0aGUgaW5uZXJGbiBoYXMgdGhlIHNhbWUgZWZmZWN0IGFzXG4gIC8vIGJyZWFraW5nIG91dCBvZiB0aGUgZGlzcGF0Y2ggc3dpdGNoIHN0YXRlbWVudC5cbiAgdmFyIENvbnRpbnVlU2VudGluZWwgPSB7fTtcblxuICAvLyBEdW1teSBjb25zdHJ1Y3RvciBmdW5jdGlvbnMgdGhhdCB3ZSB1c2UgYXMgdGhlIC5jb25zdHJ1Y3RvciBhbmRcbiAgLy8gLmNvbnN0cnVjdG9yLnByb3RvdHlwZSBwcm9wZXJ0aWVzIGZvciBmdW5jdGlvbnMgdGhhdCByZXR1cm4gR2VuZXJhdG9yXG4gIC8vIG9iamVjdHMuIEZvciBmdWxsIHNwZWMgY29tcGxpYW5jZSwgeW91IG1heSB3aXNoIHRvIGNvbmZpZ3VyZSB5b3VyXG4gIC8vIG1pbmlmaWVyIG5vdCB0byBtYW5nbGUgdGhlIG5hbWVzIG9mIHRoZXNlIHR3byBmdW5jdGlvbnMuXG4gIGZ1bmN0aW9uIEdlbmVyYXRvcigpIHt9XG4gIGZ1bmN0aW9uIEdlbmVyYXRvckZ1bmN0aW9uKCkge31cbiAgZnVuY3Rpb24gR2VuZXJhdG9yRnVuY3Rpb25Qcm90b3R5cGUoKSB7fVxuXG4gIC8vIFRoaXMgaXMgYSBwb2x5ZmlsbCBmb3IgJUl0ZXJhdG9yUHJvdG90eXBlJSBmb3IgZW52aXJvbm1lbnRzIHRoYXRcbiAgLy8gZG9uJ3QgbmF0aXZlbHkgc3VwcG9ydCBpdC5cbiAgdmFyIEl0ZXJhdG9yUHJvdG90eXBlID0ge307XG4gIEl0ZXJhdG9yUHJvdG90eXBlW2l0ZXJhdG9yU3ltYm9sXSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcztcbiAgfTtcblxuICB2YXIgZ2V0UHJvdG8gPSBPYmplY3QuZ2V0UHJvdG90eXBlT2Y7XG4gIHZhciBOYXRpdmVJdGVyYXRvclByb3RvdHlwZSA9IGdldFByb3RvICYmIGdldFByb3RvKGdldFByb3RvKHZhbHVlcyhbXSkpKTtcbiAgaWYgKE5hdGl2ZUl0ZXJhdG9yUHJvdG90eXBlICYmXG4gICAgICBOYXRpdmVJdGVyYXRvclByb3RvdHlwZSAhPT0gT3AgJiZcbiAgICAgIGhhc093bi5jYWxsKE5hdGl2ZUl0ZXJhdG9yUHJvdG90eXBlLCBpdGVyYXRvclN5bWJvbCkpIHtcbiAgICAvLyBUaGlzIGVudmlyb25tZW50IGhhcyBhIG5hdGl2ZSAlSXRlcmF0b3JQcm90b3R5cGUlOyB1c2UgaXQgaW5zdGVhZFxuICAgIC8vIG9mIHRoZSBwb2x5ZmlsbC5cbiAgICBJdGVyYXRvclByb3RvdHlwZSA9IE5hdGl2ZUl0ZXJhdG9yUHJvdG90eXBlO1xuICB9XG5cbiAgdmFyIEdwID0gR2VuZXJhdG9yRnVuY3Rpb25Qcm90b3R5cGUucHJvdG90eXBlID1cbiAgICBHZW5lcmF0b3IucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShJdGVyYXRvclByb3RvdHlwZSk7XG4gIEdlbmVyYXRvckZ1bmN0aW9uLnByb3RvdHlwZSA9IEdwLmNvbnN0cnVjdG9yID0gR2VuZXJhdG9yRnVuY3Rpb25Qcm90b3R5cGU7XG4gIEdlbmVyYXRvckZ1bmN0aW9uUHJvdG90eXBlLmNvbnN0cnVjdG9yID0gR2VuZXJhdG9yRnVuY3Rpb247XG4gIEdlbmVyYXRvckZ1bmN0aW9uUHJvdG90eXBlW3RvU3RyaW5nVGFnU3ltYm9sXSA9XG4gICAgR2VuZXJhdG9yRnVuY3Rpb24uZGlzcGxheU5hbWUgPSBcIkdlbmVyYXRvckZ1bmN0aW9uXCI7XG5cbiAgLy8gSGVscGVyIGZvciBkZWZpbmluZyB0aGUgLm5leHQsIC50aHJvdywgYW5kIC5yZXR1cm4gbWV0aG9kcyBvZiB0aGVcbiAgLy8gSXRlcmF0b3IgaW50ZXJmYWNlIGluIHRlcm1zIG9mIGEgc2luZ2xlIC5faW52b2tlIG1ldGhvZC5cbiAgZnVuY3Rpb24gZGVmaW5lSXRlcmF0b3JNZXRob2RzKHByb3RvdHlwZSkge1xuICAgIFtcIm5leHRcIiwgXCJ0aHJvd1wiLCBcInJldHVyblwiXS5mb3JFYWNoKGZ1bmN0aW9uKG1ldGhvZCkge1xuICAgICAgcHJvdG90eXBlW21ldGhvZF0gPSBmdW5jdGlvbihhcmcpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2ludm9rZShtZXRob2QsIGFyZyk7XG4gICAgICB9O1xuICAgIH0pO1xuICB9XG5cbiAgcnVudGltZS5pc0dlbmVyYXRvckZ1bmN0aW9uID0gZnVuY3Rpb24oZ2VuRnVuKSB7XG4gICAgdmFyIGN0b3IgPSB0eXBlb2YgZ2VuRnVuID09PSBcImZ1bmN0aW9uXCIgJiYgZ2VuRnVuLmNvbnN0cnVjdG9yO1xuICAgIHJldHVybiBjdG9yXG4gICAgICA/IGN0b3IgPT09IEdlbmVyYXRvckZ1bmN0aW9uIHx8XG4gICAgICAgIC8vIEZvciB0aGUgbmF0aXZlIEdlbmVyYXRvckZ1bmN0aW9uIGNvbnN0cnVjdG9yLCB0aGUgYmVzdCB3ZSBjYW5cbiAgICAgICAgLy8gZG8gaXMgdG8gY2hlY2sgaXRzIC5uYW1lIHByb3BlcnR5LlxuICAgICAgICAoY3Rvci5kaXNwbGF5TmFtZSB8fCBjdG9yLm5hbWUpID09PSBcIkdlbmVyYXRvckZ1bmN0aW9uXCJcbiAgICAgIDogZmFsc2U7XG4gIH07XG5cbiAgcnVudGltZS5tYXJrID0gZnVuY3Rpb24oZ2VuRnVuKSB7XG4gICAgaWYgKE9iamVjdC5zZXRQcm90b3R5cGVPZikge1xuICAgICAgT2JqZWN0LnNldFByb3RvdHlwZU9mKGdlbkZ1biwgR2VuZXJhdG9yRnVuY3Rpb25Qcm90b3R5cGUpO1xuICAgIH0gZWxzZSB7XG4gICAgICBnZW5GdW4uX19wcm90b19fID0gR2VuZXJhdG9yRnVuY3Rpb25Qcm90b3R5cGU7XG4gICAgICBpZiAoISh0b1N0cmluZ1RhZ1N5bWJvbCBpbiBnZW5GdW4pKSB7XG4gICAgICAgIGdlbkZ1blt0b1N0cmluZ1RhZ1N5bWJvbF0gPSBcIkdlbmVyYXRvckZ1bmN0aW9uXCI7XG4gICAgICB9XG4gICAgfVxuICAgIGdlbkZ1bi5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKEdwKTtcbiAgICByZXR1cm4gZ2VuRnVuO1xuICB9O1xuXG4gIC8vIFdpdGhpbiB0aGUgYm9keSBvZiBhbnkgYXN5bmMgZnVuY3Rpb24sIGBhd2FpdCB4YCBpcyB0cmFuc2Zvcm1lZCB0b1xuICAvLyBgeWllbGQgcmVnZW5lcmF0b3JSdW50aW1lLmF3cmFwKHgpYCwgc28gdGhhdCB0aGUgcnVudGltZSBjYW4gdGVzdFxuICAvLyBgaGFzT3duLmNhbGwodmFsdWUsIFwiX19hd2FpdFwiKWAgdG8gZGV0ZXJtaW5lIGlmIHRoZSB5aWVsZGVkIHZhbHVlIGlzXG4gIC8vIG1lYW50IHRvIGJlIGF3YWl0ZWQuXG4gIHJ1bnRpbWUuYXdyYXAgPSBmdW5jdGlvbihhcmcpIHtcbiAgICByZXR1cm4geyBfX2F3YWl0OiBhcmcgfTtcbiAgfTtcblxuICBmdW5jdGlvbiBBc3luY0l0ZXJhdG9yKGdlbmVyYXRvcikge1xuICAgIGZ1bmN0aW9uIGludm9rZShtZXRob2QsIGFyZywgcmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgICB2YXIgcmVjb3JkID0gdHJ5Q2F0Y2goZ2VuZXJhdG9yW21ldGhvZF0sIGdlbmVyYXRvciwgYXJnKTtcbiAgICAgIGlmIChyZWNvcmQudHlwZSA9PT0gXCJ0aHJvd1wiKSB7XG4gICAgICAgIHJlamVjdChyZWNvcmQuYXJnKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHZhciByZXN1bHQgPSByZWNvcmQuYXJnO1xuICAgICAgICB2YXIgdmFsdWUgPSByZXN1bHQudmFsdWU7XG4gICAgICAgIGlmICh2YWx1ZSAmJlxuICAgICAgICAgICAgdHlwZW9mIHZhbHVlID09PSBcIm9iamVjdFwiICYmXG4gICAgICAgICAgICBoYXNPd24uY2FsbCh2YWx1ZSwgXCJfX2F3YWl0XCIpKSB7XG4gICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh2YWx1ZS5fX2F3YWl0KS50aGVuKGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICAgICAgICBpbnZva2UoXCJuZXh0XCIsIHZhbHVlLCByZXNvbHZlLCByZWplY3QpO1xuICAgICAgICAgIH0sIGZ1bmN0aW9uKGVycikge1xuICAgICAgICAgICAgaW52b2tlKFwidGhyb3dcIiwgZXJyLCByZXNvbHZlLCByZWplY3QpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh2YWx1ZSkudGhlbihmdW5jdGlvbih1bndyYXBwZWQpIHtcbiAgICAgICAgICAvLyBXaGVuIGEgeWllbGRlZCBQcm9taXNlIGlzIHJlc29sdmVkLCBpdHMgZmluYWwgdmFsdWUgYmVjb21lc1xuICAgICAgICAgIC8vIHRoZSAudmFsdWUgb2YgdGhlIFByb21pc2U8e3ZhbHVlLGRvbmV9PiByZXN1bHQgZm9yIHRoZVxuICAgICAgICAgIC8vIGN1cnJlbnQgaXRlcmF0aW9uLlxuICAgICAgICAgIHJlc3VsdC52YWx1ZSA9IHVud3JhcHBlZDtcbiAgICAgICAgICByZXNvbHZlKHJlc3VsdCk7XG4gICAgICAgIH0sIGZ1bmN0aW9uKGVycm9yKSB7XG4gICAgICAgICAgLy8gSWYgYSByZWplY3RlZCBQcm9taXNlIHdhcyB5aWVsZGVkLCB0aHJvdyB0aGUgcmVqZWN0aW9uIGJhY2tcbiAgICAgICAgICAvLyBpbnRvIHRoZSBhc3luYyBnZW5lcmF0b3IgZnVuY3Rpb24gc28gaXQgY2FuIGJlIGhhbmRsZWQgdGhlcmUuXG4gICAgICAgICAgcmV0dXJuIGludm9rZShcInRocm93XCIsIGVycm9yLCByZXNvbHZlLCByZWplY3QpO1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgcHJldmlvdXNQcm9taXNlO1xuXG4gICAgZnVuY3Rpb24gZW5xdWV1ZShtZXRob2QsIGFyZykge1xuICAgICAgZnVuY3Rpb24gY2FsbEludm9rZVdpdGhNZXRob2RBbmRBcmcoKSB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbihyZXNvbHZlLCByZWplY3QpIHtcbiAgICAgICAgICBpbnZva2UobWV0aG9kLCBhcmcsIHJlc29sdmUsIHJlamVjdCk7XG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gcHJldmlvdXNQcm9taXNlID1cbiAgICAgICAgLy8gSWYgZW5xdWV1ZSBoYXMgYmVlbiBjYWxsZWQgYmVmb3JlLCB0aGVuIHdlIHdhbnQgdG8gd2FpdCB1bnRpbFxuICAgICAgICAvLyBhbGwgcHJldmlvdXMgUHJvbWlzZXMgaGF2ZSBiZWVuIHJlc29sdmVkIGJlZm9yZSBjYWxsaW5nIGludm9rZSxcbiAgICAgICAgLy8gc28gdGhhdCByZXN1bHRzIGFyZSBhbHdheXMgZGVsaXZlcmVkIGluIHRoZSBjb3JyZWN0IG9yZGVyLiBJZlxuICAgICAgICAvLyBlbnF1ZXVlIGhhcyBub3QgYmVlbiBjYWxsZWQgYmVmb3JlLCB0aGVuIGl0IGlzIGltcG9ydGFudCB0b1xuICAgICAgICAvLyBjYWxsIGludm9rZSBpbW1lZGlhdGVseSwgd2l0aG91dCB3YWl0aW5nIG9uIGEgY2FsbGJhY2sgdG8gZmlyZSxcbiAgICAgICAgLy8gc28gdGhhdCB0aGUgYXN5bmMgZ2VuZXJhdG9yIGZ1bmN0aW9uIGhhcyB0aGUgb3Bwb3J0dW5pdHkgdG8gZG9cbiAgICAgICAgLy8gYW55IG5lY2Vzc2FyeSBzZXR1cCBpbiBhIHByZWRpY3RhYmxlIHdheS4gVGhpcyBwcmVkaWN0YWJpbGl0eVxuICAgICAgICAvLyBpcyB3aHkgdGhlIFByb21pc2UgY29uc3RydWN0b3Igc3luY2hyb25vdXNseSBpbnZva2VzIGl0c1xuICAgICAgICAvLyBleGVjdXRvciBjYWxsYmFjaywgYW5kIHdoeSBhc3luYyBmdW5jdGlvbnMgc3luY2hyb25vdXNseVxuICAgICAgICAvLyBleGVjdXRlIGNvZGUgYmVmb3JlIHRoZSBmaXJzdCBhd2FpdC4gU2luY2Ugd2UgaW1wbGVtZW50IHNpbXBsZVxuICAgICAgICAvLyBhc3luYyBmdW5jdGlvbnMgaW4gdGVybXMgb2YgYXN5bmMgZ2VuZXJhdG9ycywgaXQgaXMgZXNwZWNpYWxseVxuICAgICAgICAvLyBpbXBvcnRhbnQgdG8gZ2V0IHRoaXMgcmlnaHQsIGV2ZW4gdGhvdWdoIGl0IHJlcXVpcmVzIGNhcmUuXG4gICAgICAgIHByZXZpb3VzUHJvbWlzZSA/IHByZXZpb3VzUHJvbWlzZS50aGVuKFxuICAgICAgICAgIGNhbGxJbnZva2VXaXRoTWV0aG9kQW5kQXJnLFxuICAgICAgICAgIC8vIEF2b2lkIHByb3BhZ2F0aW5nIGZhaWx1cmVzIHRvIFByb21pc2VzIHJldHVybmVkIGJ5IGxhdGVyXG4gICAgICAgICAgLy8gaW52b2NhdGlvbnMgb2YgdGhlIGl0ZXJhdG9yLlxuICAgICAgICAgIGNhbGxJbnZva2VXaXRoTWV0aG9kQW5kQXJnXG4gICAgICAgICkgOiBjYWxsSW52b2tlV2l0aE1ldGhvZEFuZEFyZygpO1xuICAgIH1cblxuICAgIC8vIERlZmluZSB0aGUgdW5pZmllZCBoZWxwZXIgbWV0aG9kIHRoYXQgaXMgdXNlZCB0byBpbXBsZW1lbnQgLm5leHQsXG4gICAgLy8gLnRocm93LCBhbmQgLnJldHVybiAoc2VlIGRlZmluZUl0ZXJhdG9yTWV0aG9kcykuXG4gICAgdGhpcy5faW52b2tlID0gZW5xdWV1ZTtcbiAgfVxuXG4gIGRlZmluZUl0ZXJhdG9yTWV0aG9kcyhBc3luY0l0ZXJhdG9yLnByb3RvdHlwZSk7XG4gIEFzeW5jSXRlcmF0b3IucHJvdG90eXBlW2FzeW5jSXRlcmF0b3JTeW1ib2xdID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzO1xuICB9O1xuICBydW50aW1lLkFzeW5jSXRlcmF0b3IgPSBBc3luY0l0ZXJhdG9yO1xuXG4gIC8vIE5vdGUgdGhhdCBzaW1wbGUgYXN5bmMgZnVuY3Rpb25zIGFyZSBpbXBsZW1lbnRlZCBvbiB0b3Agb2ZcbiAgLy8gQXN5bmNJdGVyYXRvciBvYmplY3RzOyB0aGV5IGp1c3QgcmV0dXJuIGEgUHJvbWlzZSBmb3IgdGhlIHZhbHVlIG9mXG4gIC8vIHRoZSBmaW5hbCByZXN1bHQgcHJvZHVjZWQgYnkgdGhlIGl0ZXJhdG9yLlxuICBydW50aW1lLmFzeW5jID0gZnVuY3Rpb24oaW5uZXJGbiwgb3V0ZXJGbiwgc2VsZiwgdHJ5TG9jc0xpc3QpIHtcbiAgICB2YXIgaXRlciA9IG5ldyBBc3luY0l0ZXJhdG9yKFxuICAgICAgd3JhcChpbm5lckZuLCBvdXRlckZuLCBzZWxmLCB0cnlMb2NzTGlzdClcbiAgICApO1xuXG4gICAgcmV0dXJuIHJ1bnRpbWUuaXNHZW5lcmF0b3JGdW5jdGlvbihvdXRlckZuKVxuICAgICAgPyBpdGVyIC8vIElmIG91dGVyRm4gaXMgYSBnZW5lcmF0b3IsIHJldHVybiB0aGUgZnVsbCBpdGVyYXRvci5cbiAgICAgIDogaXRlci5uZXh0KCkudGhlbihmdW5jdGlvbihyZXN1bHQpIHtcbiAgICAgICAgICByZXR1cm4gcmVzdWx0LmRvbmUgPyByZXN1bHQudmFsdWUgOiBpdGVyLm5leHQoKTtcbiAgICAgICAgfSk7XG4gIH07XG5cbiAgZnVuY3Rpb24gbWFrZUludm9rZU1ldGhvZChpbm5lckZuLCBzZWxmLCBjb250ZXh0KSB7XG4gICAgdmFyIHN0YXRlID0gR2VuU3RhdGVTdXNwZW5kZWRTdGFydDtcblxuICAgIHJldHVybiBmdW5jdGlvbiBpbnZva2UobWV0aG9kLCBhcmcpIHtcbiAgICAgIGlmIChzdGF0ZSA9PT0gR2VuU3RhdGVFeGVjdXRpbmcpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiR2VuZXJhdG9yIGlzIGFscmVhZHkgcnVubmluZ1wiKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHN0YXRlID09PSBHZW5TdGF0ZUNvbXBsZXRlZCkge1xuICAgICAgICBpZiAobWV0aG9kID09PSBcInRocm93XCIpIHtcbiAgICAgICAgICB0aHJvdyBhcmc7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBCZSBmb3JnaXZpbmcsIHBlciAyNS4zLjMuMy4zIG9mIHRoZSBzcGVjOlxuICAgICAgICAvLyBodHRwczovL3Blb3BsZS5tb3ppbGxhLm9yZy9+am9yZW5kb3JmZi9lczYtZHJhZnQuaHRtbCNzZWMtZ2VuZXJhdG9ycmVzdW1lXG4gICAgICAgIHJldHVybiBkb25lUmVzdWx0KCk7XG4gICAgICB9XG5cbiAgICAgIGNvbnRleHQubWV0aG9kID0gbWV0aG9kO1xuICAgICAgY29udGV4dC5hcmcgPSBhcmc7XG5cbiAgICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICAgIHZhciBkZWxlZ2F0ZSA9IGNvbnRleHQuZGVsZWdhdGU7XG4gICAgICAgIGlmIChkZWxlZ2F0ZSkge1xuICAgICAgICAgIHZhciBkZWxlZ2F0ZVJlc3VsdCA9IG1heWJlSW52b2tlRGVsZWdhdGUoZGVsZWdhdGUsIGNvbnRleHQpO1xuICAgICAgICAgIGlmIChkZWxlZ2F0ZVJlc3VsdCkge1xuICAgICAgICAgICAgaWYgKGRlbGVnYXRlUmVzdWx0ID09PSBDb250aW51ZVNlbnRpbmVsKSBjb250aW51ZTtcbiAgICAgICAgICAgIHJldHVybiBkZWxlZ2F0ZVJlc3VsdDtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoY29udGV4dC5tZXRob2QgPT09IFwibmV4dFwiKSB7XG4gICAgICAgICAgLy8gU2V0dGluZyBjb250ZXh0Ll9zZW50IGZvciBsZWdhY3kgc3VwcG9ydCBvZiBCYWJlbCdzXG4gICAgICAgICAgLy8gZnVuY3Rpb24uc2VudCBpbXBsZW1lbnRhdGlvbi5cbiAgICAgICAgICBjb250ZXh0LnNlbnQgPSBjb250ZXh0Ll9zZW50ID0gY29udGV4dC5hcmc7XG5cbiAgICAgICAgfSBlbHNlIGlmIChjb250ZXh0Lm1ldGhvZCA9PT0gXCJ0aHJvd1wiKSB7XG4gICAgICAgICAgaWYgKHN0YXRlID09PSBHZW5TdGF0ZVN1c3BlbmRlZFN0YXJ0KSB7XG4gICAgICAgICAgICBzdGF0ZSA9IEdlblN0YXRlQ29tcGxldGVkO1xuICAgICAgICAgICAgdGhyb3cgY29udGV4dC5hcmc7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY29udGV4dC5kaXNwYXRjaEV4Y2VwdGlvbihjb250ZXh0LmFyZyk7XG5cbiAgICAgICAgfSBlbHNlIGlmIChjb250ZXh0Lm1ldGhvZCA9PT0gXCJyZXR1cm5cIikge1xuICAgICAgICAgIGNvbnRleHQuYWJydXB0KFwicmV0dXJuXCIsIGNvbnRleHQuYXJnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHN0YXRlID0gR2VuU3RhdGVFeGVjdXRpbmc7XG5cbiAgICAgICAgdmFyIHJlY29yZCA9IHRyeUNhdGNoKGlubmVyRm4sIHNlbGYsIGNvbnRleHQpO1xuICAgICAgICBpZiAocmVjb3JkLnR5cGUgPT09IFwibm9ybWFsXCIpIHtcbiAgICAgICAgICAvLyBJZiBhbiBleGNlcHRpb24gaXMgdGhyb3duIGZyb20gaW5uZXJGbiwgd2UgbGVhdmUgc3RhdGUgPT09XG4gICAgICAgICAgLy8gR2VuU3RhdGVFeGVjdXRpbmcgYW5kIGxvb3AgYmFjayBmb3IgYW5vdGhlciBpbnZvY2F0aW9uLlxuICAgICAgICAgIHN0YXRlID0gY29udGV4dC5kb25lXG4gICAgICAgICAgICA/IEdlblN0YXRlQ29tcGxldGVkXG4gICAgICAgICAgICA6IEdlblN0YXRlU3VzcGVuZGVkWWllbGQ7XG5cbiAgICAgICAgICBpZiAocmVjb3JkLmFyZyA9PT0gQ29udGludWVTZW50aW5lbCkge1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHZhbHVlOiByZWNvcmQuYXJnLFxuICAgICAgICAgICAgZG9uZTogY29udGV4dC5kb25lXG4gICAgICAgICAgfTtcblxuICAgICAgICB9IGVsc2UgaWYgKHJlY29yZC50eXBlID09PSBcInRocm93XCIpIHtcbiAgICAgICAgICBzdGF0ZSA9IEdlblN0YXRlQ29tcGxldGVkO1xuICAgICAgICAgIC8vIERpc3BhdGNoIHRoZSBleGNlcHRpb24gYnkgbG9vcGluZyBiYWNrIGFyb3VuZCB0byB0aGVcbiAgICAgICAgICAvLyBjb250ZXh0LmRpc3BhdGNoRXhjZXB0aW9uKGNvbnRleHQuYXJnKSBjYWxsIGFib3ZlLlxuICAgICAgICAgIGNvbnRleHQubWV0aG9kID0gXCJ0aHJvd1wiO1xuICAgICAgICAgIGNvbnRleHQuYXJnID0gcmVjb3JkLmFyZztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH07XG4gIH1cblxuICAvLyBDYWxsIGRlbGVnYXRlLml0ZXJhdG9yW2NvbnRleHQubWV0aG9kXShjb250ZXh0LmFyZykgYW5kIGhhbmRsZSB0aGVcbiAgLy8gcmVzdWx0LCBlaXRoZXIgYnkgcmV0dXJuaW5nIGEgeyB2YWx1ZSwgZG9uZSB9IHJlc3VsdCBmcm9tIHRoZVxuICAvLyBkZWxlZ2F0ZSBpdGVyYXRvciwgb3IgYnkgbW9kaWZ5aW5nIGNvbnRleHQubWV0aG9kIGFuZCBjb250ZXh0LmFyZyxcbiAgLy8gc2V0dGluZyBjb250ZXh0LmRlbGVnYXRlIHRvIG51bGwsIGFuZCByZXR1cm5pbmcgdGhlIENvbnRpbnVlU2VudGluZWwuXG4gIGZ1bmN0aW9uIG1heWJlSW52b2tlRGVsZWdhdGUoZGVsZWdhdGUsIGNvbnRleHQpIHtcbiAgICB2YXIgbWV0aG9kID0gZGVsZWdhdGUuaXRlcmF0b3JbY29udGV4dC5tZXRob2RdO1xuICAgIGlmIChtZXRob2QgPT09IHVuZGVmaW5lZCkge1xuICAgICAgLy8gQSAudGhyb3cgb3IgLnJldHVybiB3aGVuIHRoZSBkZWxlZ2F0ZSBpdGVyYXRvciBoYXMgbm8gLnRocm93XG4gICAgICAvLyBtZXRob2QgYWx3YXlzIHRlcm1pbmF0ZXMgdGhlIHlpZWxkKiBsb29wLlxuICAgICAgY29udGV4dC5kZWxlZ2F0ZSA9IG51bGw7XG5cbiAgICAgIGlmIChjb250ZXh0Lm1ldGhvZCA9PT0gXCJ0aHJvd1wiKSB7XG4gICAgICAgIGlmIChkZWxlZ2F0ZS5pdGVyYXRvci5yZXR1cm4pIHtcbiAgICAgICAgICAvLyBJZiB0aGUgZGVsZWdhdGUgaXRlcmF0b3IgaGFzIGEgcmV0dXJuIG1ldGhvZCwgZ2l2ZSBpdCBhXG4gICAgICAgICAgLy8gY2hhbmNlIHRvIGNsZWFuIHVwLlxuICAgICAgICAgIGNvbnRleHQubWV0aG9kID0gXCJyZXR1cm5cIjtcbiAgICAgICAgICBjb250ZXh0LmFyZyA9IHVuZGVmaW5lZDtcbiAgICAgICAgICBtYXliZUludm9rZURlbGVnYXRlKGRlbGVnYXRlLCBjb250ZXh0KTtcblxuICAgICAgICAgIGlmIChjb250ZXh0Lm1ldGhvZCA9PT0gXCJ0aHJvd1wiKSB7XG4gICAgICAgICAgICAvLyBJZiBtYXliZUludm9rZURlbGVnYXRlKGNvbnRleHQpIGNoYW5nZWQgY29udGV4dC5tZXRob2QgZnJvbVxuICAgICAgICAgICAgLy8gXCJyZXR1cm5cIiB0byBcInRocm93XCIsIGxldCB0aGF0IG92ZXJyaWRlIHRoZSBUeXBlRXJyb3IgYmVsb3cuXG4gICAgICAgICAgICByZXR1cm4gQ29udGludWVTZW50aW5lbDtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBjb250ZXh0Lm1ldGhvZCA9IFwidGhyb3dcIjtcbiAgICAgICAgY29udGV4dC5hcmcgPSBuZXcgVHlwZUVycm9yKFxuICAgICAgICAgIFwiVGhlIGl0ZXJhdG9yIGRvZXMgbm90IHByb3ZpZGUgYSAndGhyb3cnIG1ldGhvZFwiKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIENvbnRpbnVlU2VudGluZWw7XG4gICAgfVxuXG4gICAgdmFyIHJlY29yZCA9IHRyeUNhdGNoKG1ldGhvZCwgZGVsZWdhdGUuaXRlcmF0b3IsIGNvbnRleHQuYXJnKTtcblxuICAgIGlmIChyZWNvcmQudHlwZSA9PT0gXCJ0aHJvd1wiKSB7XG4gICAgICBjb250ZXh0Lm1ldGhvZCA9IFwidGhyb3dcIjtcbiAgICAgIGNvbnRleHQuYXJnID0gcmVjb3JkLmFyZztcbiAgICAgIGNvbnRleHQuZGVsZWdhdGUgPSBudWxsO1xuICAgICAgcmV0dXJuIENvbnRpbnVlU2VudGluZWw7XG4gICAgfVxuXG4gICAgdmFyIGluZm8gPSByZWNvcmQuYXJnO1xuXG4gICAgaWYgKCEgaW5mbykge1xuICAgICAgY29udGV4dC5tZXRob2QgPSBcInRocm93XCI7XG4gICAgICBjb250ZXh0LmFyZyA9IG5ldyBUeXBlRXJyb3IoXCJpdGVyYXRvciByZXN1bHQgaXMgbm90IGFuIG9iamVjdFwiKTtcbiAgICAgIGNvbnRleHQuZGVsZWdhdGUgPSBudWxsO1xuICAgICAgcmV0dXJuIENvbnRpbnVlU2VudGluZWw7XG4gICAgfVxuXG4gICAgaWYgKGluZm8uZG9uZSkge1xuICAgICAgLy8gQXNzaWduIHRoZSByZXN1bHQgb2YgdGhlIGZpbmlzaGVkIGRlbGVnYXRlIHRvIHRoZSB0ZW1wb3JhcnlcbiAgICAgIC8vIHZhcmlhYmxlIHNwZWNpZmllZCBieSBkZWxlZ2F0ZS5yZXN1bHROYW1lIChzZWUgZGVsZWdhdGVZaWVsZCkuXG4gICAgICBjb250ZXh0W2RlbGVnYXRlLnJlc3VsdE5hbWVdID0gaW5mby52YWx1ZTtcblxuICAgICAgLy8gUmVzdW1lIGV4ZWN1dGlvbiBhdCB0aGUgZGVzaXJlZCBsb2NhdGlvbiAoc2VlIGRlbGVnYXRlWWllbGQpLlxuICAgICAgY29udGV4dC5uZXh0ID0gZGVsZWdhdGUubmV4dExvYztcblxuICAgICAgLy8gSWYgY29udGV4dC5tZXRob2Qgd2FzIFwidGhyb3dcIiBidXQgdGhlIGRlbGVnYXRlIGhhbmRsZWQgdGhlXG4gICAgICAvLyBleGNlcHRpb24sIGxldCB0aGUgb3V0ZXIgZ2VuZXJhdG9yIHByb2NlZWQgbm9ybWFsbHkuIElmXG4gICAgICAvLyBjb250ZXh0Lm1ldGhvZCB3YXMgXCJuZXh0XCIsIGZvcmdldCBjb250ZXh0LmFyZyBzaW5jZSBpdCBoYXMgYmVlblxuICAgICAgLy8gXCJjb25zdW1lZFwiIGJ5IHRoZSBkZWxlZ2F0ZSBpdGVyYXRvci4gSWYgY29udGV4dC5tZXRob2Qgd2FzXG4gICAgICAvLyBcInJldHVyblwiLCBhbGxvdyB0aGUgb3JpZ2luYWwgLnJldHVybiBjYWxsIHRvIGNvbnRpbnVlIGluIHRoZVxuICAgICAgLy8gb3V0ZXIgZ2VuZXJhdG9yLlxuICAgICAgaWYgKGNvbnRleHQubWV0aG9kICE9PSBcInJldHVyblwiKSB7XG4gICAgICAgIGNvbnRleHQubWV0aG9kID0gXCJuZXh0XCI7XG4gICAgICAgIGNvbnRleHQuYXJnID0gdW5kZWZpbmVkO1xuICAgICAgfVxuXG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIFJlLXlpZWxkIHRoZSByZXN1bHQgcmV0dXJuZWQgYnkgdGhlIGRlbGVnYXRlIG1ldGhvZC5cbiAgICAgIHJldHVybiBpbmZvO1xuICAgIH1cblxuICAgIC8vIFRoZSBkZWxlZ2F0ZSBpdGVyYXRvciBpcyBmaW5pc2hlZCwgc28gZm9yZ2V0IGl0IGFuZCBjb250aW51ZSB3aXRoXG4gICAgLy8gdGhlIG91dGVyIGdlbmVyYXRvci5cbiAgICBjb250ZXh0LmRlbGVnYXRlID0gbnVsbDtcbiAgICByZXR1cm4gQ29udGludWVTZW50aW5lbDtcbiAgfVxuXG4gIC8vIERlZmluZSBHZW5lcmF0b3IucHJvdG90eXBlLntuZXh0LHRocm93LHJldHVybn0gaW4gdGVybXMgb2YgdGhlXG4gIC8vIHVuaWZpZWQgLl9pbnZva2UgaGVscGVyIG1ldGhvZC5cbiAgZGVmaW5lSXRlcmF0b3JNZXRob2RzKEdwKTtcblxuICBHcFt0b1N0cmluZ1RhZ1N5bWJvbF0gPSBcIkdlbmVyYXRvclwiO1xuXG4gIC8vIEEgR2VuZXJhdG9yIHNob3VsZCBhbHdheXMgcmV0dXJuIGl0c2VsZiBhcyB0aGUgaXRlcmF0b3Igb2JqZWN0IHdoZW4gdGhlXG4gIC8vIEBAaXRlcmF0b3IgZnVuY3Rpb24gaXMgY2FsbGVkIG9uIGl0LiBTb21lIGJyb3dzZXJzJyBpbXBsZW1lbnRhdGlvbnMgb2YgdGhlXG4gIC8vIGl0ZXJhdG9yIHByb3RvdHlwZSBjaGFpbiBpbmNvcnJlY3RseSBpbXBsZW1lbnQgdGhpcywgY2F1c2luZyB0aGUgR2VuZXJhdG9yXG4gIC8vIG9iamVjdCB0byBub3QgYmUgcmV0dXJuZWQgZnJvbSB0aGlzIGNhbGwuIFRoaXMgZW5zdXJlcyB0aGF0IGRvZXNuJ3QgaGFwcGVuLlxuICAvLyBTZWUgaHR0cHM6Ly9naXRodWIuY29tL2ZhY2Vib29rL3JlZ2VuZXJhdG9yL2lzc3Vlcy8yNzQgZm9yIG1vcmUgZGV0YWlscy5cbiAgR3BbaXRlcmF0b3JTeW1ib2xdID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH07XG5cbiAgR3AudG9TdHJpbmcgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gXCJbb2JqZWN0IEdlbmVyYXRvcl1cIjtcbiAgfTtcblxuICBmdW5jdGlvbiBwdXNoVHJ5RW50cnkobG9jcykge1xuICAgIHZhciBlbnRyeSA9IHsgdHJ5TG9jOiBsb2NzWzBdIH07XG5cbiAgICBpZiAoMSBpbiBsb2NzKSB7XG4gICAgICBlbnRyeS5jYXRjaExvYyA9IGxvY3NbMV07XG4gICAgfVxuXG4gICAgaWYgKDIgaW4gbG9jcykge1xuICAgICAgZW50cnkuZmluYWxseUxvYyA9IGxvY3NbMl07XG4gICAgICBlbnRyeS5hZnRlckxvYyA9IGxvY3NbM107XG4gICAgfVxuXG4gICAgdGhpcy50cnlFbnRyaWVzLnB1c2goZW50cnkpO1xuICB9XG5cbiAgZnVuY3Rpb24gcmVzZXRUcnlFbnRyeShlbnRyeSkge1xuICAgIHZhciByZWNvcmQgPSBlbnRyeS5jb21wbGV0aW9uIHx8IHt9O1xuICAgIHJlY29yZC50eXBlID0gXCJub3JtYWxcIjtcbiAgICBkZWxldGUgcmVjb3JkLmFyZztcbiAgICBlbnRyeS5jb21wbGV0aW9uID0gcmVjb3JkO1xuICB9XG5cbiAgZnVuY3Rpb24gQ29udGV4dCh0cnlMb2NzTGlzdCkge1xuICAgIC8vIFRoZSByb290IGVudHJ5IG9iamVjdCAoZWZmZWN0aXZlbHkgYSB0cnkgc3RhdGVtZW50IHdpdGhvdXQgYSBjYXRjaFxuICAgIC8vIG9yIGEgZmluYWxseSBibG9jaykgZ2l2ZXMgdXMgYSBwbGFjZSB0byBzdG9yZSB2YWx1ZXMgdGhyb3duIGZyb21cbiAgICAvLyBsb2NhdGlvbnMgd2hlcmUgdGhlcmUgaXMgbm8gZW5jbG9zaW5nIHRyeSBzdGF0ZW1lbnQuXG4gICAgdGhpcy50cnlFbnRyaWVzID0gW3sgdHJ5TG9jOiBcInJvb3RcIiB9XTtcbiAgICB0cnlMb2NzTGlzdC5mb3JFYWNoKHB1c2hUcnlFbnRyeSwgdGhpcyk7XG4gICAgdGhpcy5yZXNldCh0cnVlKTtcbiAgfVxuXG4gIHJ1bnRpbWUua2V5cyA9IGZ1bmN0aW9uKG9iamVjdCkge1xuICAgIHZhciBrZXlzID0gW107XG4gICAgZm9yICh2YXIga2V5IGluIG9iamVjdCkge1xuICAgICAga2V5cy5wdXNoKGtleSk7XG4gICAgfVxuICAgIGtleXMucmV2ZXJzZSgpO1xuXG4gICAgLy8gUmF0aGVyIHRoYW4gcmV0dXJuaW5nIGFuIG9iamVjdCB3aXRoIGEgbmV4dCBtZXRob2QsIHdlIGtlZXBcbiAgICAvLyB0aGluZ3Mgc2ltcGxlIGFuZCByZXR1cm4gdGhlIG5leHQgZnVuY3Rpb24gaXRzZWxmLlxuICAgIHJldHVybiBmdW5jdGlvbiBuZXh0KCkge1xuICAgICAgd2hpbGUgKGtleXMubGVuZ3RoKSB7XG4gICAgICAgIHZhciBrZXkgPSBrZXlzLnBvcCgpO1xuICAgICAgICBpZiAoa2V5IGluIG9iamVjdCkge1xuICAgICAgICAgIG5leHQudmFsdWUgPSBrZXk7XG4gICAgICAgICAgbmV4dC5kb25lID0gZmFsc2U7XG4gICAgICAgICAgcmV0dXJuIG5leHQ7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gVG8gYXZvaWQgY3JlYXRpbmcgYW4gYWRkaXRpb25hbCBvYmplY3QsIHdlIGp1c3QgaGFuZyB0aGUgLnZhbHVlXG4gICAgICAvLyBhbmQgLmRvbmUgcHJvcGVydGllcyBvZmYgdGhlIG5leHQgZnVuY3Rpb24gb2JqZWN0IGl0c2VsZi4gVGhpc1xuICAgICAgLy8gYWxzbyBlbnN1cmVzIHRoYXQgdGhlIG1pbmlmaWVyIHdpbGwgbm90IGFub255bWl6ZSB0aGUgZnVuY3Rpb24uXG4gICAgICBuZXh0LmRvbmUgPSB0cnVlO1xuICAgICAgcmV0dXJuIG5leHQ7XG4gICAgfTtcbiAgfTtcblxuICBmdW5jdGlvbiB2YWx1ZXMoaXRlcmFibGUpIHtcbiAgICBpZiAoaXRlcmFibGUpIHtcbiAgICAgIHZhciBpdGVyYXRvck1ldGhvZCA9IGl0ZXJhYmxlW2l0ZXJhdG9yU3ltYm9sXTtcbiAgICAgIGlmIChpdGVyYXRvck1ldGhvZCkge1xuICAgICAgICByZXR1cm4gaXRlcmF0b3JNZXRob2QuY2FsbChpdGVyYWJsZSk7XG4gICAgICB9XG5cbiAgICAgIGlmICh0eXBlb2YgaXRlcmFibGUubmV4dCA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIHJldHVybiBpdGVyYWJsZTtcbiAgICAgIH1cblxuICAgICAgaWYgKCFpc05hTihpdGVyYWJsZS5sZW5ndGgpKSB7XG4gICAgICAgIHZhciBpID0gLTEsIG5leHQgPSBmdW5jdGlvbiBuZXh0KCkge1xuICAgICAgICAgIHdoaWxlICgrK2kgPCBpdGVyYWJsZS5sZW5ndGgpIHtcbiAgICAgICAgICAgIGlmIChoYXNPd24uY2FsbChpdGVyYWJsZSwgaSkpIHtcbiAgICAgICAgICAgICAgbmV4dC52YWx1ZSA9IGl0ZXJhYmxlW2ldO1xuICAgICAgICAgICAgICBuZXh0LmRvbmUgPSBmYWxzZTtcbiAgICAgICAgICAgICAgcmV0dXJuIG5leHQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgbmV4dC52YWx1ZSA9IHVuZGVmaW5lZDtcbiAgICAgICAgICBuZXh0LmRvbmUgPSB0cnVlO1xuXG4gICAgICAgICAgcmV0dXJuIG5leHQ7XG4gICAgICAgIH07XG5cbiAgICAgICAgcmV0dXJuIG5leHQubmV4dCA9IG5leHQ7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gUmV0dXJuIGFuIGl0ZXJhdG9yIHdpdGggbm8gdmFsdWVzLlxuICAgIHJldHVybiB7IG5leHQ6IGRvbmVSZXN1bHQgfTtcbiAgfVxuICBydW50aW1lLnZhbHVlcyA9IHZhbHVlcztcblxuICBmdW5jdGlvbiBkb25lUmVzdWx0KCkge1xuICAgIHJldHVybiB7IHZhbHVlOiB1bmRlZmluZWQsIGRvbmU6IHRydWUgfTtcbiAgfVxuXG4gIENvbnRleHQucHJvdG90eXBlID0ge1xuICAgIGNvbnN0cnVjdG9yOiBDb250ZXh0LFxuXG4gICAgcmVzZXQ6IGZ1bmN0aW9uKHNraXBUZW1wUmVzZXQpIHtcbiAgICAgIHRoaXMucHJldiA9IDA7XG4gICAgICB0aGlzLm5leHQgPSAwO1xuICAgICAgLy8gUmVzZXR0aW5nIGNvbnRleHQuX3NlbnQgZm9yIGxlZ2FjeSBzdXBwb3J0IG9mIEJhYmVsJ3NcbiAgICAgIC8vIGZ1bmN0aW9uLnNlbnQgaW1wbGVtZW50YXRpb24uXG4gICAgICB0aGlzLnNlbnQgPSB0aGlzLl9zZW50ID0gdW5kZWZpbmVkO1xuICAgICAgdGhpcy5kb25lID0gZmFsc2U7XG4gICAgICB0aGlzLmRlbGVnYXRlID0gbnVsbDtcblxuICAgICAgdGhpcy5tZXRob2QgPSBcIm5leHRcIjtcbiAgICAgIHRoaXMuYXJnID0gdW5kZWZpbmVkO1xuXG4gICAgICB0aGlzLnRyeUVudHJpZXMuZm9yRWFjaChyZXNldFRyeUVudHJ5KTtcblxuICAgICAgaWYgKCFza2lwVGVtcFJlc2V0KSB7XG4gICAgICAgIGZvciAodmFyIG5hbWUgaW4gdGhpcykge1xuICAgICAgICAgIC8vIE5vdCBzdXJlIGFib3V0IHRoZSBvcHRpbWFsIG9yZGVyIG9mIHRoZXNlIGNvbmRpdGlvbnM6XG4gICAgICAgICAgaWYgKG5hbWUuY2hhckF0KDApID09PSBcInRcIiAmJlxuICAgICAgICAgICAgICBoYXNPd24uY2FsbCh0aGlzLCBuYW1lKSAmJlxuICAgICAgICAgICAgICAhaXNOYU4oK25hbWUuc2xpY2UoMSkpKSB7XG4gICAgICAgICAgICB0aGlzW25hbWVdID0gdW5kZWZpbmVkO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0sXG5cbiAgICBzdG9wOiBmdW5jdGlvbigpIHtcbiAgICAgIHRoaXMuZG9uZSA9IHRydWU7XG5cbiAgICAgIHZhciByb290RW50cnkgPSB0aGlzLnRyeUVudHJpZXNbMF07XG4gICAgICB2YXIgcm9vdFJlY29yZCA9IHJvb3RFbnRyeS5jb21wbGV0aW9uO1xuICAgICAgaWYgKHJvb3RSZWNvcmQudHlwZSA9PT0gXCJ0aHJvd1wiKSB7XG4gICAgICAgIHRocm93IHJvb3RSZWNvcmQuYXJnO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gdGhpcy5ydmFsO1xuICAgIH0sXG5cbiAgICBkaXNwYXRjaEV4Y2VwdGlvbjogZnVuY3Rpb24oZXhjZXB0aW9uKSB7XG4gICAgICBpZiAodGhpcy5kb25lKSB7XG4gICAgICAgIHRocm93IGV4Y2VwdGlvbjtcbiAgICAgIH1cblxuICAgICAgdmFyIGNvbnRleHQgPSB0aGlzO1xuICAgICAgZnVuY3Rpb24gaGFuZGxlKGxvYywgY2F1Z2h0KSB7XG4gICAgICAgIHJlY29yZC50eXBlID0gXCJ0aHJvd1wiO1xuICAgICAgICByZWNvcmQuYXJnID0gZXhjZXB0aW9uO1xuICAgICAgICBjb250ZXh0Lm5leHQgPSBsb2M7XG5cbiAgICAgICAgaWYgKGNhdWdodCkge1xuICAgICAgICAgIC8vIElmIHRoZSBkaXNwYXRjaGVkIGV4Y2VwdGlvbiB3YXMgY2F1Z2h0IGJ5IGEgY2F0Y2ggYmxvY2ssXG4gICAgICAgICAgLy8gdGhlbiBsZXQgdGhhdCBjYXRjaCBibG9jayBoYW5kbGUgdGhlIGV4Y2VwdGlvbiBub3JtYWxseS5cbiAgICAgICAgICBjb250ZXh0Lm1ldGhvZCA9IFwibmV4dFwiO1xuICAgICAgICAgIGNvbnRleHQuYXJnID0gdW5kZWZpbmVkO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuICEhIGNhdWdodDtcbiAgICAgIH1cblxuICAgICAgZm9yICh2YXIgaSA9IHRoaXMudHJ5RW50cmllcy5sZW5ndGggLSAxOyBpID49IDA7IC0taSkge1xuICAgICAgICB2YXIgZW50cnkgPSB0aGlzLnRyeUVudHJpZXNbaV07XG4gICAgICAgIHZhciByZWNvcmQgPSBlbnRyeS5jb21wbGV0aW9uO1xuXG4gICAgICAgIGlmIChlbnRyeS50cnlMb2MgPT09IFwicm9vdFwiKSB7XG4gICAgICAgICAgLy8gRXhjZXB0aW9uIHRocm93biBvdXRzaWRlIG9mIGFueSB0cnkgYmxvY2sgdGhhdCBjb3VsZCBoYW5kbGVcbiAgICAgICAgICAvLyBpdCwgc28gc2V0IHRoZSBjb21wbGV0aW9uIHZhbHVlIG9mIHRoZSBlbnRpcmUgZnVuY3Rpb24gdG9cbiAgICAgICAgICAvLyB0aHJvdyB0aGUgZXhjZXB0aW9uLlxuICAgICAgICAgIHJldHVybiBoYW5kbGUoXCJlbmRcIik7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZW50cnkudHJ5TG9jIDw9IHRoaXMucHJldikge1xuICAgICAgICAgIHZhciBoYXNDYXRjaCA9IGhhc093bi5jYWxsKGVudHJ5LCBcImNhdGNoTG9jXCIpO1xuICAgICAgICAgIHZhciBoYXNGaW5hbGx5ID0gaGFzT3duLmNhbGwoZW50cnksIFwiZmluYWxseUxvY1wiKTtcblxuICAgICAgICAgIGlmIChoYXNDYXRjaCAmJiBoYXNGaW5hbGx5KSB7XG4gICAgICAgICAgICBpZiAodGhpcy5wcmV2IDwgZW50cnkuY2F0Y2hMb2MpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIGhhbmRsZShlbnRyeS5jYXRjaExvYywgdHJ1ZSk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHRoaXMucHJldiA8IGVudHJ5LmZpbmFsbHlMb2MpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIGhhbmRsZShlbnRyeS5maW5hbGx5TG9jKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgIH0gZWxzZSBpZiAoaGFzQ2F0Y2gpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnByZXYgPCBlbnRyeS5jYXRjaExvYykge1xuICAgICAgICAgICAgICByZXR1cm4gaGFuZGxlKGVudHJ5LmNhdGNoTG9jLCB0cnVlKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgIH0gZWxzZSBpZiAoaGFzRmluYWxseSkge1xuICAgICAgICAgICAgaWYgKHRoaXMucHJldiA8IGVudHJ5LmZpbmFsbHlMb2MpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIGhhbmRsZShlbnRyeS5maW5hbGx5TG9jKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJ0cnkgc3RhdGVtZW50IHdpdGhvdXQgY2F0Y2ggb3IgZmluYWxseVwiKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9LFxuXG4gICAgYWJydXB0OiBmdW5jdGlvbih0eXBlLCBhcmcpIHtcbiAgICAgIGZvciAodmFyIGkgPSB0aGlzLnRyeUVudHJpZXMubGVuZ3RoIC0gMTsgaSA+PSAwOyAtLWkpIHtcbiAgICAgICAgdmFyIGVudHJ5ID0gdGhpcy50cnlFbnRyaWVzW2ldO1xuICAgICAgICBpZiAoZW50cnkudHJ5TG9jIDw9IHRoaXMucHJldiAmJlxuICAgICAgICAgICAgaGFzT3duLmNhbGwoZW50cnksIFwiZmluYWxseUxvY1wiKSAmJlxuICAgICAgICAgICAgdGhpcy5wcmV2IDwgZW50cnkuZmluYWxseUxvYykge1xuICAgICAgICAgIHZhciBmaW5hbGx5RW50cnkgPSBlbnRyeTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoZmluYWxseUVudHJ5ICYmXG4gICAgICAgICAgKHR5cGUgPT09IFwiYnJlYWtcIiB8fFxuICAgICAgICAgICB0eXBlID09PSBcImNvbnRpbnVlXCIpICYmXG4gICAgICAgICAgZmluYWxseUVudHJ5LnRyeUxvYyA8PSBhcmcgJiZcbiAgICAgICAgICBhcmcgPD0gZmluYWxseUVudHJ5LmZpbmFsbHlMb2MpIHtcbiAgICAgICAgLy8gSWdub3JlIHRoZSBmaW5hbGx5IGVudHJ5IGlmIGNvbnRyb2wgaXMgbm90IGp1bXBpbmcgdG8gYVxuICAgICAgICAvLyBsb2NhdGlvbiBvdXRzaWRlIHRoZSB0cnkvY2F0Y2ggYmxvY2suXG4gICAgICAgIGZpbmFsbHlFbnRyeSA9IG51bGw7XG4gICAgICB9XG5cbiAgICAgIHZhciByZWNvcmQgPSBmaW5hbGx5RW50cnkgPyBmaW5hbGx5RW50cnkuY29tcGxldGlvbiA6IHt9O1xuICAgICAgcmVjb3JkLnR5cGUgPSB0eXBlO1xuICAgICAgcmVjb3JkLmFyZyA9IGFyZztcblxuICAgICAgaWYgKGZpbmFsbHlFbnRyeSkge1xuICAgICAgICB0aGlzLm1ldGhvZCA9IFwibmV4dFwiO1xuICAgICAgICB0aGlzLm5leHQgPSBmaW5hbGx5RW50cnkuZmluYWxseUxvYztcbiAgICAgICAgcmV0dXJuIENvbnRpbnVlU2VudGluZWw7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0aGlzLmNvbXBsZXRlKHJlY29yZCk7XG4gICAgfSxcblxuICAgIGNvbXBsZXRlOiBmdW5jdGlvbihyZWNvcmQsIGFmdGVyTG9jKSB7XG4gICAgICBpZiAocmVjb3JkLnR5cGUgPT09IFwidGhyb3dcIikge1xuICAgICAgICB0aHJvdyByZWNvcmQuYXJnO1xuICAgICAgfVxuXG4gICAgICBpZiAocmVjb3JkLnR5cGUgPT09IFwiYnJlYWtcIiB8fFxuICAgICAgICAgIHJlY29yZC50eXBlID09PSBcImNvbnRpbnVlXCIpIHtcbiAgICAgICAgdGhpcy5uZXh0ID0gcmVjb3JkLmFyZztcbiAgICAgIH0gZWxzZSBpZiAocmVjb3JkLnR5cGUgPT09IFwicmV0dXJuXCIpIHtcbiAgICAgICAgdGhpcy5ydmFsID0gdGhpcy5hcmcgPSByZWNvcmQuYXJnO1xuICAgICAgICB0aGlzLm1ldGhvZCA9IFwicmV0dXJuXCI7XG4gICAgICAgIHRoaXMubmV4dCA9IFwiZW5kXCI7XG4gICAgICB9IGVsc2UgaWYgKHJlY29yZC50eXBlID09PSBcIm5vcm1hbFwiICYmIGFmdGVyTG9jKSB7XG4gICAgICAgIHRoaXMubmV4dCA9IGFmdGVyTG9jO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gQ29udGludWVTZW50aW5lbDtcbiAgICB9LFxuXG4gICAgZmluaXNoOiBmdW5jdGlvbihmaW5hbGx5TG9jKSB7XG4gICAgICBmb3IgKHZhciBpID0gdGhpcy50cnlFbnRyaWVzLmxlbmd0aCAtIDE7IGkgPj0gMDsgLS1pKSB7XG4gICAgICAgIHZhciBlbnRyeSA9IHRoaXMudHJ5RW50cmllc1tpXTtcbiAgICAgICAgaWYgKGVudHJ5LmZpbmFsbHlMb2MgPT09IGZpbmFsbHlMb2MpIHtcbiAgICAgICAgICB0aGlzLmNvbXBsZXRlKGVudHJ5LmNvbXBsZXRpb24sIGVudHJ5LmFmdGVyTG9jKTtcbiAgICAgICAgICByZXNldFRyeUVudHJ5KGVudHJ5KTtcbiAgICAgICAgICByZXR1cm4gQ29udGludWVTZW50aW5lbDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0sXG5cbiAgICBcImNhdGNoXCI6IGZ1bmN0aW9uKHRyeUxvYykge1xuICAgICAgZm9yICh2YXIgaSA9IHRoaXMudHJ5RW50cmllcy5sZW5ndGggLSAxOyBpID49IDA7IC0taSkge1xuICAgICAgICB2YXIgZW50cnkgPSB0aGlzLnRyeUVudHJpZXNbaV07XG4gICAgICAgIGlmIChlbnRyeS50cnlMb2MgPT09IHRyeUxvYykge1xuICAgICAgICAgIHZhciByZWNvcmQgPSBlbnRyeS5jb21wbGV0aW9uO1xuICAgICAgICAgIGlmIChyZWNvcmQudHlwZSA9PT0gXCJ0aHJvd1wiKSB7XG4gICAgICAgICAgICB2YXIgdGhyb3duID0gcmVjb3JkLmFyZztcbiAgICAgICAgICAgIHJlc2V0VHJ5RW50cnkoZW50cnkpO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gdGhyb3duO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIFRoZSBjb250ZXh0LmNhdGNoIG1ldGhvZCBtdXN0IG9ubHkgYmUgY2FsbGVkIHdpdGggYSBsb2NhdGlvblxuICAgICAgLy8gYXJndW1lbnQgdGhhdCBjb3JyZXNwb25kcyB0byBhIGtub3duIGNhdGNoIGJsb2NrLlxuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiaWxsZWdhbCBjYXRjaCBhdHRlbXB0XCIpO1xuICAgIH0sXG5cbiAgICBkZWxlZ2F0ZVlpZWxkOiBmdW5jdGlvbihpdGVyYWJsZSwgcmVzdWx0TmFtZSwgbmV4dExvYykge1xuICAgICAgdGhpcy5kZWxlZ2F0ZSA9IHtcbiAgICAgICAgaXRlcmF0b3I6IHZhbHVlcyhpdGVyYWJsZSksXG4gICAgICAgIHJlc3VsdE5hbWU6IHJlc3VsdE5hbWUsXG4gICAgICAgIG5leHRMb2M6IG5leHRMb2NcbiAgICAgIH07XG5cbiAgICAgIGlmICh0aGlzLm1ldGhvZCA9PT0gXCJuZXh0XCIpIHtcbiAgICAgICAgLy8gRGVsaWJlcmF0ZWx5IGZvcmdldCB0aGUgbGFzdCBzZW50IHZhbHVlIHNvIHRoYXQgd2UgZG9uJ3RcbiAgICAgICAgLy8gYWNjaWRlbnRhbGx5IHBhc3MgaXQgb24gdG8gdGhlIGRlbGVnYXRlLlxuICAgICAgICB0aGlzLmFyZyA9IHVuZGVmaW5lZDtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIENvbnRpbnVlU2VudGluZWw7XG4gICAgfVxuICB9O1xufSkoXG4gIC8vIEluIHNsb3BweSBtb2RlLCB1bmJvdW5kIGB0aGlzYCByZWZlcnMgdG8gdGhlIGdsb2JhbCBvYmplY3QsIGZhbGxiYWNrIHRvXG4gIC8vIEZ1bmN0aW9uIGNvbnN0cnVjdG9yIGlmIHdlJ3JlIGluIGdsb2JhbCBzdHJpY3QgbW9kZS4gVGhhdCBpcyBzYWRseSBhIGZvcm1cbiAgLy8gb2YgaW5kaXJlY3QgZXZhbCB3aGljaCB2aW9sYXRlcyBDb250ZW50IFNlY3VyaXR5IFBvbGljeS5cbiAgKGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB0aGlzIHx8ICh0eXBlb2Ygc2VsZiA9PT0gXCJvYmplY3RcIiAmJiBzZWxmKTtcbiAgfSkoKSB8fCBGdW5jdGlvbihcInJldHVybiB0aGlzXCIpKClcbik7XG4iLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJyZWdlbmVyYXRvci1ydW50aW1lXCIpO1xuIiwiLy8gQ29weXJpZ2h0IEpveWVudCwgSW5jLiBhbmQgb3RoZXIgTm9kZSBjb250cmlidXRvcnMuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGFcbi8vIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGVcbi8vIFwiU29mdHdhcmVcIiksIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZ1xuLy8gd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLFxuLy8gZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdFxuLy8gcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlXG4vLyBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vXG4vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZFxuLy8gaW4gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTU1xuLy8gT1IgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRlxuLy8gTUVSQ0hBTlRBQklMSVRZLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTlxuLy8gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sXG4vLyBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1Jcbi8vIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEVcbi8vIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuXG5cbnZhciBvYmplY3RDcmVhdGUgPSBPYmplY3QuY3JlYXRlIHx8IG9iamVjdENyZWF0ZVBvbHlmaWxsXG52YXIgb2JqZWN0S2V5cyA9IE9iamVjdC5rZXlzIHx8IG9iamVjdEtleXNQb2x5ZmlsbFxudmFyIGJpbmQgPSBGdW5jdGlvbi5wcm90b3R5cGUuYmluZCB8fCBmdW5jdGlvbkJpbmRQb2x5ZmlsbFxuXG5mdW5jdGlvbiBFdmVudEVtaXR0ZXIoKSB7XG4gIGlmICghdGhpcy5fZXZlbnRzIHx8ICFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwodGhpcywgJ19ldmVudHMnKSkge1xuICAgIHRoaXMuX2V2ZW50cyA9IG9iamVjdENyZWF0ZShudWxsKTtcbiAgICB0aGlzLl9ldmVudHNDb3VudCA9IDA7XG4gIH1cblxuICB0aGlzLl9tYXhMaXN0ZW5lcnMgPSB0aGlzLl9tYXhMaXN0ZW5lcnMgfHwgdW5kZWZpbmVkO1xufVxubW9kdWxlLmV4cG9ydHMgPSBFdmVudEVtaXR0ZXI7XG5cbi8vIEJhY2t3YXJkcy1jb21wYXQgd2l0aCBub2RlIDAuMTAueFxuRXZlbnRFbWl0dGVyLkV2ZW50RW1pdHRlciA9IEV2ZW50RW1pdHRlcjtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5fZXZlbnRzID0gdW5kZWZpbmVkO1xuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5fbWF4TGlzdGVuZXJzID0gdW5kZWZpbmVkO1xuXG4vLyBCeSBkZWZhdWx0IEV2ZW50RW1pdHRlcnMgd2lsbCBwcmludCBhIHdhcm5pbmcgaWYgbW9yZSB0aGFuIDEwIGxpc3RlbmVycyBhcmVcbi8vIGFkZGVkIHRvIGl0LiBUaGlzIGlzIGEgdXNlZnVsIGRlZmF1bHQgd2hpY2ggaGVscHMgZmluZGluZyBtZW1vcnkgbGVha3MuXG52YXIgZGVmYXVsdE1heExpc3RlbmVycyA9IDEwO1xuXG52YXIgaGFzRGVmaW5lUHJvcGVydHk7XG50cnkge1xuICB2YXIgbyA9IHt9O1xuICBpZiAoT2JqZWN0LmRlZmluZVByb3BlcnR5KSBPYmplY3QuZGVmaW5lUHJvcGVydHkobywgJ3gnLCB7IHZhbHVlOiAwIH0pO1xuICBoYXNEZWZpbmVQcm9wZXJ0eSA9IG8ueCA9PT0gMDtcbn0gY2F0Y2ggKGVycikgeyBoYXNEZWZpbmVQcm9wZXJ0eSA9IGZhbHNlIH1cbmlmIChoYXNEZWZpbmVQcm9wZXJ0eSkge1xuICBPYmplY3QuZGVmaW5lUHJvcGVydHkoRXZlbnRFbWl0dGVyLCAnZGVmYXVsdE1heExpc3RlbmVycycsIHtcbiAgICBlbnVtZXJhYmxlOiB0cnVlLFxuICAgIGdldDogZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gZGVmYXVsdE1heExpc3RlbmVycztcbiAgICB9LFxuICAgIHNldDogZnVuY3Rpb24oYXJnKSB7XG4gICAgICAvLyBjaGVjayB3aGV0aGVyIHRoZSBpbnB1dCBpcyBhIHBvc2l0aXZlIG51bWJlciAod2hvc2UgdmFsdWUgaXMgemVybyBvclxuICAgICAgLy8gZ3JlYXRlciBhbmQgbm90IGEgTmFOKS5cbiAgICAgIGlmICh0eXBlb2YgYXJnICE9PSAnbnVtYmVyJyB8fCBhcmcgPCAwIHx8IGFyZyAhPT0gYXJnKVxuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcImRlZmF1bHRNYXhMaXN0ZW5lcnNcIiBtdXN0IGJlIGEgcG9zaXRpdmUgbnVtYmVyJyk7XG4gICAgICBkZWZhdWx0TWF4TGlzdGVuZXJzID0gYXJnO1xuICAgIH1cbiAgfSk7XG59IGVsc2Uge1xuICBFdmVudEVtaXR0ZXIuZGVmYXVsdE1heExpc3RlbmVycyA9IGRlZmF1bHRNYXhMaXN0ZW5lcnM7XG59XG5cbi8vIE9idmlvdXNseSBub3QgYWxsIEVtaXR0ZXJzIHNob3VsZCBiZSBsaW1pdGVkIHRvIDEwLiBUaGlzIGZ1bmN0aW9uIGFsbG93c1xuLy8gdGhhdCB0byBiZSBpbmNyZWFzZWQuIFNldCB0byB6ZXJvIGZvciB1bmxpbWl0ZWQuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLnNldE1heExpc3RlbmVycyA9IGZ1bmN0aW9uIHNldE1heExpc3RlbmVycyhuKSB7XG4gIGlmICh0eXBlb2YgbiAhPT0gJ251bWJlcicgfHwgbiA8IDAgfHwgaXNOYU4obikpXG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignXCJuXCIgYXJndW1lbnQgbXVzdCBiZSBhIHBvc2l0aXZlIG51bWJlcicpO1xuICB0aGlzLl9tYXhMaXN0ZW5lcnMgPSBuO1xuICByZXR1cm4gdGhpcztcbn07XG5cbmZ1bmN0aW9uICRnZXRNYXhMaXN0ZW5lcnModGhhdCkge1xuICBpZiAodGhhdC5fbWF4TGlzdGVuZXJzID09PSB1bmRlZmluZWQpXG4gICAgcmV0dXJuIEV2ZW50RW1pdHRlci5kZWZhdWx0TWF4TGlzdGVuZXJzO1xuICByZXR1cm4gdGhhdC5fbWF4TGlzdGVuZXJzO1xufVxuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLmdldE1heExpc3RlbmVycyA9IGZ1bmN0aW9uIGdldE1heExpc3RlbmVycygpIHtcbiAgcmV0dXJuICRnZXRNYXhMaXN0ZW5lcnModGhpcyk7XG59O1xuXG4vLyBUaGVzZSBzdGFuZGFsb25lIGVtaXQqIGZ1bmN0aW9ucyBhcmUgdXNlZCB0byBvcHRpbWl6ZSBjYWxsaW5nIG9mIGV2ZW50XG4vLyBoYW5kbGVycyBmb3IgZmFzdCBjYXNlcyBiZWNhdXNlIGVtaXQoKSBpdHNlbGYgb2Z0ZW4gaGFzIGEgdmFyaWFibGUgbnVtYmVyIG9mXG4vLyBhcmd1bWVudHMgYW5kIGNhbiBiZSBkZW9wdGltaXplZCBiZWNhdXNlIG9mIHRoYXQuIFRoZXNlIGZ1bmN0aW9ucyBhbHdheXMgaGF2ZVxuLy8gdGhlIHNhbWUgbnVtYmVyIG9mIGFyZ3VtZW50cyBhbmQgdGh1cyBkbyBub3QgZ2V0IGRlb3B0aW1pemVkLCBzbyB0aGUgY29kZVxuLy8gaW5zaWRlIHRoZW0gY2FuIGV4ZWN1dGUgZmFzdGVyLlxuZnVuY3Rpb24gZW1pdE5vbmUoaGFuZGxlciwgaXNGbiwgc2VsZikge1xuICBpZiAoaXNGbilcbiAgICBoYW5kbGVyLmNhbGwoc2VsZik7XG4gIGVsc2Uge1xuICAgIHZhciBsZW4gPSBoYW5kbGVyLmxlbmd0aDtcbiAgICB2YXIgbGlzdGVuZXJzID0gYXJyYXlDbG9uZShoYW5kbGVyLCBsZW4pO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyArK2kpXG4gICAgICBsaXN0ZW5lcnNbaV0uY2FsbChzZWxmKTtcbiAgfVxufVxuZnVuY3Rpb24gZW1pdE9uZShoYW5kbGVyLCBpc0ZuLCBzZWxmLCBhcmcxKSB7XG4gIGlmIChpc0ZuKVxuICAgIGhhbmRsZXIuY2FsbChzZWxmLCBhcmcxKTtcbiAgZWxzZSB7XG4gICAgdmFyIGxlbiA9IGhhbmRsZXIubGVuZ3RoO1xuICAgIHZhciBsaXN0ZW5lcnMgPSBhcnJheUNsb25lKGhhbmRsZXIsIGxlbik7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47ICsraSlcbiAgICAgIGxpc3RlbmVyc1tpXS5jYWxsKHNlbGYsIGFyZzEpO1xuICB9XG59XG5mdW5jdGlvbiBlbWl0VHdvKGhhbmRsZXIsIGlzRm4sIHNlbGYsIGFyZzEsIGFyZzIpIHtcbiAgaWYgKGlzRm4pXG4gICAgaGFuZGxlci5jYWxsKHNlbGYsIGFyZzEsIGFyZzIpO1xuICBlbHNlIHtcbiAgICB2YXIgbGVuID0gaGFuZGxlci5sZW5ndGg7XG4gICAgdmFyIGxpc3RlbmVycyA9IGFycmF5Q2xvbmUoaGFuZGxlciwgbGVuKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgKytpKVxuICAgICAgbGlzdGVuZXJzW2ldLmNhbGwoc2VsZiwgYXJnMSwgYXJnMik7XG4gIH1cbn1cbmZ1bmN0aW9uIGVtaXRUaHJlZShoYW5kbGVyLCBpc0ZuLCBzZWxmLCBhcmcxLCBhcmcyLCBhcmczKSB7XG4gIGlmIChpc0ZuKVxuICAgIGhhbmRsZXIuY2FsbChzZWxmLCBhcmcxLCBhcmcyLCBhcmczKTtcbiAgZWxzZSB7XG4gICAgdmFyIGxlbiA9IGhhbmRsZXIubGVuZ3RoO1xuICAgIHZhciBsaXN0ZW5lcnMgPSBhcnJheUNsb25lKGhhbmRsZXIsIGxlbik7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47ICsraSlcbiAgICAgIGxpc3RlbmVyc1tpXS5jYWxsKHNlbGYsIGFyZzEsIGFyZzIsIGFyZzMpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGVtaXRNYW55KGhhbmRsZXIsIGlzRm4sIHNlbGYsIGFyZ3MpIHtcbiAgaWYgKGlzRm4pXG4gICAgaGFuZGxlci5hcHBseShzZWxmLCBhcmdzKTtcbiAgZWxzZSB7XG4gICAgdmFyIGxlbiA9IGhhbmRsZXIubGVuZ3RoO1xuICAgIHZhciBsaXN0ZW5lcnMgPSBhcnJheUNsb25lKGhhbmRsZXIsIGxlbik7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47ICsraSlcbiAgICAgIGxpc3RlbmVyc1tpXS5hcHBseShzZWxmLCBhcmdzKTtcbiAgfVxufVxuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLmVtaXQgPSBmdW5jdGlvbiBlbWl0KHR5cGUpIHtcbiAgdmFyIGVyLCBoYW5kbGVyLCBsZW4sIGFyZ3MsIGksIGV2ZW50cztcbiAgdmFyIGRvRXJyb3IgPSAodHlwZSA9PT0gJ2Vycm9yJyk7XG5cbiAgZXZlbnRzID0gdGhpcy5fZXZlbnRzO1xuICBpZiAoZXZlbnRzKVxuICAgIGRvRXJyb3IgPSAoZG9FcnJvciAmJiBldmVudHMuZXJyb3IgPT0gbnVsbCk7XG4gIGVsc2UgaWYgKCFkb0Vycm9yKVxuICAgIHJldHVybiBmYWxzZTtcblxuICAvLyBJZiB0aGVyZSBpcyBubyAnZXJyb3InIGV2ZW50IGxpc3RlbmVyIHRoZW4gdGhyb3cuXG4gIGlmIChkb0Vycm9yKSB7XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPiAxKVxuICAgICAgZXIgPSBhcmd1bWVudHNbMV07XG4gICAgaWYgKGVyIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgIHRocm93IGVyOyAvLyBVbmhhbmRsZWQgJ2Vycm9yJyBldmVudFxuICAgIH0gZWxzZSB7XG4gICAgICAvLyBBdCBsZWFzdCBnaXZlIHNvbWUga2luZCBvZiBjb250ZXh0IHRvIHRoZSB1c2VyXG4gICAgICB2YXIgZXJyID0gbmV3IEVycm9yKCdVbmhhbmRsZWQgXCJlcnJvclwiIGV2ZW50LiAoJyArIGVyICsgJyknKTtcbiAgICAgIGVyci5jb250ZXh0ID0gZXI7XG4gICAgICB0aHJvdyBlcnI7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGhhbmRsZXIgPSBldmVudHNbdHlwZV07XG5cbiAgaWYgKCFoYW5kbGVyKVxuICAgIHJldHVybiBmYWxzZTtcblxuICB2YXIgaXNGbiA9IHR5cGVvZiBoYW5kbGVyID09PSAnZnVuY3Rpb24nO1xuICBsZW4gPSBhcmd1bWVudHMubGVuZ3RoO1xuICBzd2l0Y2ggKGxlbikge1xuICAgICAgLy8gZmFzdCBjYXNlc1xuICAgIGNhc2UgMTpcbiAgICAgIGVtaXROb25lKGhhbmRsZXIsIGlzRm4sIHRoaXMpO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAyOlxuICAgICAgZW1pdE9uZShoYW5kbGVyLCBpc0ZuLCB0aGlzLCBhcmd1bWVudHNbMV0pO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAzOlxuICAgICAgZW1pdFR3byhoYW5kbGVyLCBpc0ZuLCB0aGlzLCBhcmd1bWVudHNbMV0sIGFyZ3VtZW50c1syXSk7XG4gICAgICBicmVhaztcbiAgICBjYXNlIDQ6XG4gICAgICBlbWl0VGhyZWUoaGFuZGxlciwgaXNGbiwgdGhpcywgYXJndW1lbnRzWzFdLCBhcmd1bWVudHNbMl0sIGFyZ3VtZW50c1szXSk7XG4gICAgICBicmVhaztcbiAgICAgIC8vIHNsb3dlclxuICAgIGRlZmF1bHQ6XG4gICAgICBhcmdzID0gbmV3IEFycmF5KGxlbiAtIDEpO1xuICAgICAgZm9yIChpID0gMTsgaSA8IGxlbjsgaSsrKVxuICAgICAgICBhcmdzW2kgLSAxXSA9IGFyZ3VtZW50c1tpXTtcbiAgICAgIGVtaXRNYW55KGhhbmRsZXIsIGlzRm4sIHRoaXMsIGFyZ3MpO1xuICB9XG5cbiAgcmV0dXJuIHRydWU7XG59O1xuXG5mdW5jdGlvbiBfYWRkTGlzdGVuZXIodGFyZ2V0LCB0eXBlLCBsaXN0ZW5lciwgcHJlcGVuZCkge1xuICB2YXIgbTtcbiAgdmFyIGV2ZW50cztcbiAgdmFyIGV4aXN0aW5nO1xuXG4gIGlmICh0eXBlb2YgbGlzdGVuZXIgIT09ICdmdW5jdGlvbicpXG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignXCJsaXN0ZW5lclwiIGFyZ3VtZW50IG11c3QgYmUgYSBmdW5jdGlvbicpO1xuXG4gIGV2ZW50cyA9IHRhcmdldC5fZXZlbnRzO1xuICBpZiAoIWV2ZW50cykge1xuICAgIGV2ZW50cyA9IHRhcmdldC5fZXZlbnRzID0gb2JqZWN0Q3JlYXRlKG51bGwpO1xuICAgIHRhcmdldC5fZXZlbnRzQ291bnQgPSAwO1xuICB9IGVsc2Uge1xuICAgIC8vIFRvIGF2b2lkIHJlY3Vyc2lvbiBpbiB0aGUgY2FzZSB0aGF0IHR5cGUgPT09IFwibmV3TGlzdGVuZXJcIiEgQmVmb3JlXG4gICAgLy8gYWRkaW5nIGl0IHRvIHRoZSBsaXN0ZW5lcnMsIGZpcnN0IGVtaXQgXCJuZXdMaXN0ZW5lclwiLlxuICAgIGlmIChldmVudHMubmV3TGlzdGVuZXIpIHtcbiAgICAgIHRhcmdldC5lbWl0KCduZXdMaXN0ZW5lcicsIHR5cGUsXG4gICAgICAgICAgbGlzdGVuZXIubGlzdGVuZXIgPyBsaXN0ZW5lci5saXN0ZW5lciA6IGxpc3RlbmVyKTtcblxuICAgICAgLy8gUmUtYXNzaWduIGBldmVudHNgIGJlY2F1c2UgYSBuZXdMaXN0ZW5lciBoYW5kbGVyIGNvdWxkIGhhdmUgY2F1c2VkIHRoZVxuICAgICAgLy8gdGhpcy5fZXZlbnRzIHRvIGJlIGFzc2lnbmVkIHRvIGEgbmV3IG9iamVjdFxuICAgICAgZXZlbnRzID0gdGFyZ2V0Ll9ldmVudHM7XG4gICAgfVxuICAgIGV4aXN0aW5nID0gZXZlbnRzW3R5cGVdO1xuICB9XG5cbiAgaWYgKCFleGlzdGluZykge1xuICAgIC8vIE9wdGltaXplIHRoZSBjYXNlIG9mIG9uZSBsaXN0ZW5lci4gRG9uJ3QgbmVlZCB0aGUgZXh0cmEgYXJyYXkgb2JqZWN0LlxuICAgIGV4aXN0aW5nID0gZXZlbnRzW3R5cGVdID0gbGlzdGVuZXI7XG4gICAgKyt0YXJnZXQuX2V2ZW50c0NvdW50O1xuICB9IGVsc2Uge1xuICAgIGlmICh0eXBlb2YgZXhpc3RpbmcgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIC8vIEFkZGluZyB0aGUgc2Vjb25kIGVsZW1lbnQsIG5lZWQgdG8gY2hhbmdlIHRvIGFycmF5LlxuICAgICAgZXhpc3RpbmcgPSBldmVudHNbdHlwZV0gPVxuICAgICAgICAgIHByZXBlbmQgPyBbbGlzdGVuZXIsIGV4aXN0aW5nXSA6IFtleGlzdGluZywgbGlzdGVuZXJdO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBJZiB3ZSd2ZSBhbHJlYWR5IGdvdCBhbiBhcnJheSwganVzdCBhcHBlbmQuXG4gICAgICBpZiAocHJlcGVuZCkge1xuICAgICAgICBleGlzdGluZy51bnNoaWZ0KGxpc3RlbmVyKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGV4aXN0aW5nLnB1c2gobGlzdGVuZXIpO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIENoZWNrIGZvciBsaXN0ZW5lciBsZWFrXG4gICAgaWYgKCFleGlzdGluZy53YXJuZWQpIHtcbiAgICAgIG0gPSAkZ2V0TWF4TGlzdGVuZXJzKHRhcmdldCk7XG4gICAgICBpZiAobSAmJiBtID4gMCAmJiBleGlzdGluZy5sZW5ndGggPiBtKSB7XG4gICAgICAgIGV4aXN0aW5nLndhcm5lZCA9IHRydWU7XG4gICAgICAgIHZhciB3ID0gbmV3IEVycm9yKCdQb3NzaWJsZSBFdmVudEVtaXR0ZXIgbWVtb3J5IGxlYWsgZGV0ZWN0ZWQuICcgK1xuICAgICAgICAgICAgZXhpc3RpbmcubGVuZ3RoICsgJyBcIicgKyBTdHJpbmcodHlwZSkgKyAnXCIgbGlzdGVuZXJzICcgK1xuICAgICAgICAgICAgJ2FkZGVkLiBVc2UgZW1pdHRlci5zZXRNYXhMaXN0ZW5lcnMoKSB0byAnICtcbiAgICAgICAgICAgICdpbmNyZWFzZSBsaW1pdC4nKTtcbiAgICAgICAgdy5uYW1lID0gJ01heExpc3RlbmVyc0V4Y2VlZGVkV2FybmluZyc7XG4gICAgICAgIHcuZW1pdHRlciA9IHRhcmdldDtcbiAgICAgICAgdy50eXBlID0gdHlwZTtcbiAgICAgICAgdy5jb3VudCA9IGV4aXN0aW5nLmxlbmd0aDtcbiAgICAgICAgaWYgKHR5cGVvZiBjb25zb2xlID09PSAnb2JqZWN0JyAmJiBjb25zb2xlLndhcm4pIHtcbiAgICAgICAgICBjb25zb2xlLndhcm4oJyVzOiAlcycsIHcubmFtZSwgdy5tZXNzYWdlKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiB0YXJnZXQ7XG59XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuYWRkTGlzdGVuZXIgPSBmdW5jdGlvbiBhZGRMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lcikge1xuICByZXR1cm4gX2FkZExpc3RlbmVyKHRoaXMsIHR5cGUsIGxpc3RlbmVyLCBmYWxzZSk7XG59O1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLm9uID0gRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5hZGRMaXN0ZW5lcjtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5wcmVwZW5kTGlzdGVuZXIgPVxuICAgIGZ1bmN0aW9uIHByZXBlbmRMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lcikge1xuICAgICAgcmV0dXJuIF9hZGRMaXN0ZW5lcih0aGlzLCB0eXBlLCBsaXN0ZW5lciwgdHJ1ZSk7XG4gICAgfTtcblxuZnVuY3Rpb24gb25jZVdyYXBwZXIoKSB7XG4gIGlmICghdGhpcy5maXJlZCkge1xuICAgIHRoaXMudGFyZ2V0LnJlbW92ZUxpc3RlbmVyKHRoaXMudHlwZSwgdGhpcy53cmFwRm4pO1xuICAgIHRoaXMuZmlyZWQgPSB0cnVlO1xuICAgIHN3aXRjaCAoYXJndW1lbnRzLmxlbmd0aCkge1xuICAgICAgY2FzZSAwOlxuICAgICAgICByZXR1cm4gdGhpcy5saXN0ZW5lci5jYWxsKHRoaXMudGFyZ2V0KTtcbiAgICAgIGNhc2UgMTpcbiAgICAgICAgcmV0dXJuIHRoaXMubGlzdGVuZXIuY2FsbCh0aGlzLnRhcmdldCwgYXJndW1lbnRzWzBdKTtcbiAgICAgIGNhc2UgMjpcbiAgICAgICAgcmV0dXJuIHRoaXMubGlzdGVuZXIuY2FsbCh0aGlzLnRhcmdldCwgYXJndW1lbnRzWzBdLCBhcmd1bWVudHNbMV0pO1xuICAgICAgY2FzZSAzOlxuICAgICAgICByZXR1cm4gdGhpcy5saXN0ZW5lci5jYWxsKHRoaXMudGFyZ2V0LCBhcmd1bWVudHNbMF0sIGFyZ3VtZW50c1sxXSxcbiAgICAgICAgICAgIGFyZ3VtZW50c1syXSk7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB2YXIgYXJncyA9IG5ldyBBcnJheShhcmd1bWVudHMubGVuZ3RoKTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBhcmdzLmxlbmd0aDsgKytpKVxuICAgICAgICAgIGFyZ3NbaV0gPSBhcmd1bWVudHNbaV07XG4gICAgICAgIHRoaXMubGlzdGVuZXIuYXBwbHkodGhpcy50YXJnZXQsIGFyZ3MpO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBfb25jZVdyYXAodGFyZ2V0LCB0eXBlLCBsaXN0ZW5lcikge1xuICB2YXIgc3RhdGUgPSB7IGZpcmVkOiBmYWxzZSwgd3JhcEZuOiB1bmRlZmluZWQsIHRhcmdldDogdGFyZ2V0LCB0eXBlOiB0eXBlLCBsaXN0ZW5lcjogbGlzdGVuZXIgfTtcbiAgdmFyIHdyYXBwZWQgPSBiaW5kLmNhbGwob25jZVdyYXBwZXIsIHN0YXRlKTtcbiAgd3JhcHBlZC5saXN0ZW5lciA9IGxpc3RlbmVyO1xuICBzdGF0ZS53cmFwRm4gPSB3cmFwcGVkO1xuICByZXR1cm4gd3JhcHBlZDtcbn1cblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5vbmNlID0gZnVuY3Rpb24gb25jZSh0eXBlLCBsaXN0ZW5lcikge1xuICBpZiAodHlwZW9mIGxpc3RlbmVyICE9PSAnZnVuY3Rpb24nKVxuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1wibGlzdGVuZXJcIiBhcmd1bWVudCBtdXN0IGJlIGEgZnVuY3Rpb24nKTtcbiAgdGhpcy5vbih0eXBlLCBfb25jZVdyYXAodGhpcywgdHlwZSwgbGlzdGVuZXIpKTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLnByZXBlbmRPbmNlTGlzdGVuZXIgPVxuICAgIGZ1bmN0aW9uIHByZXBlbmRPbmNlTGlzdGVuZXIodHlwZSwgbGlzdGVuZXIpIHtcbiAgICAgIGlmICh0eXBlb2YgbGlzdGVuZXIgIT09ICdmdW5jdGlvbicpXG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1wibGlzdGVuZXJcIiBhcmd1bWVudCBtdXN0IGJlIGEgZnVuY3Rpb24nKTtcbiAgICAgIHRoaXMucHJlcGVuZExpc3RlbmVyKHR5cGUsIF9vbmNlV3JhcCh0aGlzLCB0eXBlLCBsaXN0ZW5lcikpO1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuLy8gRW1pdHMgYSAncmVtb3ZlTGlzdGVuZXInIGV2ZW50IGlmIGFuZCBvbmx5IGlmIHRoZSBsaXN0ZW5lciB3YXMgcmVtb3ZlZC5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUucmVtb3ZlTGlzdGVuZXIgPVxuICAgIGZ1bmN0aW9uIHJlbW92ZUxpc3RlbmVyKHR5cGUsIGxpc3RlbmVyKSB7XG4gICAgICB2YXIgbGlzdCwgZXZlbnRzLCBwb3NpdGlvbiwgaSwgb3JpZ2luYWxMaXN0ZW5lcjtcblxuICAgICAgaWYgKHR5cGVvZiBsaXN0ZW5lciAhPT0gJ2Z1bmN0aW9uJylcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignXCJsaXN0ZW5lclwiIGFyZ3VtZW50IG11c3QgYmUgYSBmdW5jdGlvbicpO1xuXG4gICAgICBldmVudHMgPSB0aGlzLl9ldmVudHM7XG4gICAgICBpZiAoIWV2ZW50cylcbiAgICAgICAgcmV0dXJuIHRoaXM7XG5cbiAgICAgIGxpc3QgPSBldmVudHNbdHlwZV07XG4gICAgICBpZiAoIWxpc3QpXG4gICAgICAgIHJldHVybiB0aGlzO1xuXG4gICAgICBpZiAobGlzdCA9PT0gbGlzdGVuZXIgfHwgbGlzdC5saXN0ZW5lciA9PT0gbGlzdGVuZXIpIHtcbiAgICAgICAgaWYgKC0tdGhpcy5fZXZlbnRzQ291bnQgPT09IDApXG4gICAgICAgICAgdGhpcy5fZXZlbnRzID0gb2JqZWN0Q3JlYXRlKG51bGwpO1xuICAgICAgICBlbHNlIHtcbiAgICAgICAgICBkZWxldGUgZXZlbnRzW3R5cGVdO1xuICAgICAgICAgIGlmIChldmVudHMucmVtb3ZlTGlzdGVuZXIpXG4gICAgICAgICAgICB0aGlzLmVtaXQoJ3JlbW92ZUxpc3RlbmVyJywgdHlwZSwgbGlzdC5saXN0ZW5lciB8fCBsaXN0ZW5lcik7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGxpc3QgIT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgcG9zaXRpb24gPSAtMTtcblxuICAgICAgICBmb3IgKGkgPSBsaXN0Lmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgICAgaWYgKGxpc3RbaV0gPT09IGxpc3RlbmVyIHx8IGxpc3RbaV0ubGlzdGVuZXIgPT09IGxpc3RlbmVyKSB7XG4gICAgICAgICAgICBvcmlnaW5hbExpc3RlbmVyID0gbGlzdFtpXS5saXN0ZW5lcjtcbiAgICAgICAgICAgIHBvc2l0aW9uID0gaTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChwb3NpdGlvbiA8IDApXG4gICAgICAgICAgcmV0dXJuIHRoaXM7XG5cbiAgICAgICAgaWYgKHBvc2l0aW9uID09PSAwKVxuICAgICAgICAgIGxpc3Quc2hpZnQoKTtcbiAgICAgICAgZWxzZVxuICAgICAgICAgIHNwbGljZU9uZShsaXN0LCBwb3NpdGlvbik7XG5cbiAgICAgICAgaWYgKGxpc3QubGVuZ3RoID09PSAxKVxuICAgICAgICAgIGV2ZW50c1t0eXBlXSA9IGxpc3RbMF07XG5cbiAgICAgICAgaWYgKGV2ZW50cy5yZW1vdmVMaXN0ZW5lcilcbiAgICAgICAgICB0aGlzLmVtaXQoJ3JlbW92ZUxpc3RlbmVyJywgdHlwZSwgb3JpZ2luYWxMaXN0ZW5lciB8fCBsaXN0ZW5lcik7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUucmVtb3ZlQWxsTGlzdGVuZXJzID1cbiAgICBmdW5jdGlvbiByZW1vdmVBbGxMaXN0ZW5lcnModHlwZSkge1xuICAgICAgdmFyIGxpc3RlbmVycywgZXZlbnRzLCBpO1xuXG4gICAgICBldmVudHMgPSB0aGlzLl9ldmVudHM7XG4gICAgICBpZiAoIWV2ZW50cylcbiAgICAgICAgcmV0dXJuIHRoaXM7XG5cbiAgICAgIC8vIG5vdCBsaXN0ZW5pbmcgZm9yIHJlbW92ZUxpc3RlbmVyLCBubyBuZWVkIHRvIGVtaXRcbiAgICAgIGlmICghZXZlbnRzLnJlbW92ZUxpc3RlbmVyKSB7XG4gICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgdGhpcy5fZXZlbnRzID0gb2JqZWN0Q3JlYXRlKG51bGwpO1xuICAgICAgICAgIHRoaXMuX2V2ZW50c0NvdW50ID0gMDtcbiAgICAgICAgfSBlbHNlIGlmIChldmVudHNbdHlwZV0pIHtcbiAgICAgICAgICBpZiAoLS10aGlzLl9ldmVudHNDb3VudCA9PT0gMClcbiAgICAgICAgICAgIHRoaXMuX2V2ZW50cyA9IG9iamVjdENyZWF0ZShudWxsKTtcbiAgICAgICAgICBlbHNlXG4gICAgICAgICAgICBkZWxldGUgZXZlbnRzW3R5cGVdO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgfVxuXG4gICAgICAvLyBlbWl0IHJlbW92ZUxpc3RlbmVyIGZvciBhbGwgbGlzdGVuZXJzIG9uIGFsbCBldmVudHNcbiAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHZhciBrZXlzID0gb2JqZWN0S2V5cyhldmVudHMpO1xuICAgICAgICB2YXIga2V5O1xuICAgICAgICBmb3IgKGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7ICsraSkge1xuICAgICAgICAgIGtleSA9IGtleXNbaV07XG4gICAgICAgICAgaWYgKGtleSA9PT0gJ3JlbW92ZUxpc3RlbmVyJykgY29udGludWU7XG4gICAgICAgICAgdGhpcy5yZW1vdmVBbGxMaXN0ZW5lcnMoa2V5KTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnJlbW92ZUFsbExpc3RlbmVycygncmVtb3ZlTGlzdGVuZXInKTtcbiAgICAgICAgdGhpcy5fZXZlbnRzID0gb2JqZWN0Q3JlYXRlKG51bGwpO1xuICAgICAgICB0aGlzLl9ldmVudHNDb3VudCA9IDA7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgfVxuXG4gICAgICBsaXN0ZW5lcnMgPSBldmVudHNbdHlwZV07XG5cbiAgICAgIGlmICh0eXBlb2YgbGlzdGVuZXJzID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHRoaXMucmVtb3ZlTGlzdGVuZXIodHlwZSwgbGlzdGVuZXJzKTtcbiAgICAgIH0gZWxzZSBpZiAobGlzdGVuZXJzKSB7XG4gICAgICAgIC8vIExJRk8gb3JkZXJcbiAgICAgICAgZm9yIChpID0gbGlzdGVuZXJzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgICAgdGhpcy5yZW1vdmVMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lcnNbaV0pO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbmZ1bmN0aW9uIF9saXN0ZW5lcnModGFyZ2V0LCB0eXBlLCB1bndyYXApIHtcbiAgdmFyIGV2ZW50cyA9IHRhcmdldC5fZXZlbnRzO1xuXG4gIGlmICghZXZlbnRzKVxuICAgIHJldHVybiBbXTtcblxuICB2YXIgZXZsaXN0ZW5lciA9IGV2ZW50c1t0eXBlXTtcbiAgaWYgKCFldmxpc3RlbmVyKVxuICAgIHJldHVybiBbXTtcblxuICBpZiAodHlwZW9mIGV2bGlzdGVuZXIgPT09ICdmdW5jdGlvbicpXG4gICAgcmV0dXJuIHVud3JhcCA/IFtldmxpc3RlbmVyLmxpc3RlbmVyIHx8IGV2bGlzdGVuZXJdIDogW2V2bGlzdGVuZXJdO1xuXG4gIHJldHVybiB1bndyYXAgPyB1bndyYXBMaXN0ZW5lcnMoZXZsaXN0ZW5lcikgOiBhcnJheUNsb25lKGV2bGlzdGVuZXIsIGV2bGlzdGVuZXIubGVuZ3RoKTtcbn1cblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5saXN0ZW5lcnMgPSBmdW5jdGlvbiBsaXN0ZW5lcnModHlwZSkge1xuICByZXR1cm4gX2xpc3RlbmVycyh0aGlzLCB0eXBlLCB0cnVlKTtcbn07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUucmF3TGlzdGVuZXJzID0gZnVuY3Rpb24gcmF3TGlzdGVuZXJzKHR5cGUpIHtcbiAgcmV0dXJuIF9saXN0ZW5lcnModGhpcywgdHlwZSwgZmFsc2UpO1xufTtcblxuRXZlbnRFbWl0dGVyLmxpc3RlbmVyQ291bnQgPSBmdW5jdGlvbihlbWl0dGVyLCB0eXBlKSB7XG4gIGlmICh0eXBlb2YgZW1pdHRlci5saXN0ZW5lckNvdW50ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgcmV0dXJuIGVtaXR0ZXIubGlzdGVuZXJDb3VudCh0eXBlKTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gbGlzdGVuZXJDb3VudC5jYWxsKGVtaXR0ZXIsIHR5cGUpO1xuICB9XG59O1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLmxpc3RlbmVyQ291bnQgPSBsaXN0ZW5lckNvdW50O1xuZnVuY3Rpb24gbGlzdGVuZXJDb3VudCh0eXBlKSB7XG4gIHZhciBldmVudHMgPSB0aGlzLl9ldmVudHM7XG5cbiAgaWYgKGV2ZW50cykge1xuICAgIHZhciBldmxpc3RlbmVyID0gZXZlbnRzW3R5cGVdO1xuXG4gICAgaWYgKHR5cGVvZiBldmxpc3RlbmVyID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICByZXR1cm4gMTtcbiAgICB9IGVsc2UgaWYgKGV2bGlzdGVuZXIpIHtcbiAgICAgIHJldHVybiBldmxpc3RlbmVyLmxlbmd0aDtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gMDtcbn1cblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5ldmVudE5hbWVzID0gZnVuY3Rpb24gZXZlbnROYW1lcygpIHtcbiAgcmV0dXJuIHRoaXMuX2V2ZW50c0NvdW50ID4gMCA/IFJlZmxlY3Qub3duS2V5cyh0aGlzLl9ldmVudHMpIDogW107XG59O1xuXG4vLyBBYm91dCAxLjV4IGZhc3RlciB0aGFuIHRoZSB0d28tYXJnIHZlcnNpb24gb2YgQXJyYXkjc3BsaWNlKCkuXG5mdW5jdGlvbiBzcGxpY2VPbmUobGlzdCwgaW5kZXgpIHtcbiAgZm9yICh2YXIgaSA9IGluZGV4LCBrID0gaSArIDEsIG4gPSBsaXN0Lmxlbmd0aDsgayA8IG47IGkgKz0gMSwgayArPSAxKVxuICAgIGxpc3RbaV0gPSBsaXN0W2tdO1xuICBsaXN0LnBvcCgpO1xufVxuXG5mdW5jdGlvbiBhcnJheUNsb25lKGFyciwgbikge1xuICB2YXIgY29weSA9IG5ldyBBcnJheShuKTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBuOyArK2kpXG4gICAgY29weVtpXSA9IGFycltpXTtcbiAgcmV0dXJuIGNvcHk7XG59XG5cbmZ1bmN0aW9uIHVud3JhcExpc3RlbmVycyhhcnIpIHtcbiAgdmFyIHJldCA9IG5ldyBBcnJheShhcnIubGVuZ3RoKTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCByZXQubGVuZ3RoOyArK2kpIHtcbiAgICByZXRbaV0gPSBhcnJbaV0ubGlzdGVuZXIgfHwgYXJyW2ldO1xuICB9XG4gIHJldHVybiByZXQ7XG59XG5cbmZ1bmN0aW9uIG9iamVjdENyZWF0ZVBvbHlmaWxsKHByb3RvKSB7XG4gIHZhciBGID0gZnVuY3Rpb24oKSB7fTtcbiAgRi5wcm90b3R5cGUgPSBwcm90bztcbiAgcmV0dXJuIG5ldyBGO1xufVxuZnVuY3Rpb24gb2JqZWN0S2V5c1BvbHlmaWxsKG9iaikge1xuICB2YXIga2V5cyA9IFtdO1xuICBmb3IgKHZhciBrIGluIG9iaikgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvYmosIGspKSB7XG4gICAga2V5cy5wdXNoKGspO1xuICB9XG4gIHJldHVybiBrO1xufVxuZnVuY3Rpb24gZnVuY3Rpb25CaW5kUG9seWZpbGwoY29udGV4dCkge1xuICB2YXIgZm4gPSB0aGlzO1xuICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBmbi5hcHBseShjb250ZXh0LCBhcmd1bWVudHMpO1xuICB9O1xufVxuIiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbnZhciBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0ID0gcmVxdWlyZShcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvaW50ZXJvcFJlcXVpcmVEZWZhdWx0XCIpO1xuXG52YXIgX2ludGVyb3BSZXF1aXJlV2lsZGNhcmQgPSByZXF1aXJlKFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9pbnRlcm9wUmVxdWlyZVdpbGRjYXJkXCIpO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcbiAgdmFsdWU6IHRydWVcbn0pO1xuZXhwb3J0cy5kZWZhdWx0ID0gZXhwb3J0cy5TVVBQT1JURURfUFJPVE9DT0xfVkVSU0lPTiA9IHZvaWQgMDtcblxudmFyIF9yZWdlbmVyYXRvciA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIkBiYWJlbC9ydW50aW1lL3JlZ2VuZXJhdG9yXCIpKTtcblxudmFyIF9hc3luY1RvR2VuZXJhdG9yMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvYXN5bmNUb0dlbmVyYXRvclwiKSk7XG5cbnZhciBfb2JqZWN0U3ByZWFkMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvb2JqZWN0U3ByZWFkXCIpKTtcblxudmFyIF9jbGFzc0NhbGxDaGVjazIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KHJlcXVpcmUoXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2NsYXNzQ2FsbENoZWNrXCIpKTtcblxudmFyIF9jcmVhdGVDbGFzczIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KHJlcXVpcmUoXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2NyZWF0ZUNsYXNzXCIpKTtcblxudmFyIF9hcHBseURlY29yYXRlZERlc2NyaXB0b3IyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9hcHBseURlY29yYXRlZERlc2NyaXB0b3JcIikpO1xuXG52YXIgX3V0aWxzID0gcmVxdWlyZShcIi4vdXRpbHNcIik7XG5cbnZhciBfaHR0cCA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIi4vaHR0cFwiKSk7XG5cbnZhciBfZW5kcG9pbnQgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KHJlcXVpcmUoXCIuL2VuZHBvaW50XCIpKTtcblxudmFyIHJlcXVlc3RzID0gX2ludGVyb3BSZXF1aXJlV2lsZGNhcmQocmVxdWlyZShcIi4vcmVxdWVzdHNcIikpO1xuXG52YXIgX2JhdGNoMiA9IHJlcXVpcmUoXCIuL2JhdGNoXCIpO1xuXG52YXIgX2J1Y2tldCA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIi4vYnVja2V0XCIpKTtcblxudmFyIF9kZWMsIF9kZWMyLCBfZGVjMywgX2RlYzQsIF9kZWM1LCBfZGVjNiwgX2RlYzcsIF9jbGFzcztcblxuLyoqXG4gKiBDdXJyZW50bHkgc3VwcG9ydGVkIHByb3RvY29sIHZlcnNpb24uXG4gKiBAdHlwZSB7U3RyaW5nfVxuICovXG52YXIgU1VQUE9SVEVEX1BST1RPQ09MX1ZFUlNJT04gPSBcInYxXCI7XG4vKipcbiAqIEhpZ2ggbGV2ZWwgSFRUUCBjbGllbnQgZm9yIHRoZSBLaW50byBBUEkuXG4gKlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IGNsaWVudCA9IG5ldyBLaW50b0NsaWVudChcImh0dHBzOi8va2ludG8uZGV2Lm1vemF3cy5uZXQvdjFcIik7XG4gKiBjbGllbnQuYnVja2V0KFwiZGVmYXVsdFwiKVxuICogICAgLmNvbGxlY3Rpb24oXCJteS1ibG9nXCIpXG4gKiAgICAuY3JlYXRlUmVjb3JkKHt0aXRsZTogXCJGaXJzdCBhcnRpY2xlXCJ9KVxuICogICAudGhlbihjb25zb2xlLmxvZy5iaW5kKGNvbnNvbGUpKVxuICogICAuY2F0Y2goY29uc29sZS5lcnJvci5iaW5kKGNvbnNvbGUpKTtcbiAqL1xuXG5leHBvcnRzLlNVUFBPUlRFRF9QUk9UT0NPTF9WRVJTSU9OID0gU1VQUE9SVEVEX1BST1RPQ09MX1ZFUlNJT047XG52YXIgS2ludG9DbGllbnRCYXNlID0gKF9kZWMgPSAoMCwgX3V0aWxzLm5vYmF0Y2gpKFwiVGhpcyBvcGVyYXRpb24gaXMgbm90IHN1cHBvcnRlZCB3aXRoaW4gYSBiYXRjaCBvcGVyYXRpb24uXCIpLCBfZGVjMiA9ICgwLCBfdXRpbHMubm9iYXRjaCkoXCJUaGlzIG9wZXJhdGlvbiBpcyBub3Qgc3VwcG9ydGVkIHdpdGhpbiBhIGJhdGNoIG9wZXJhdGlvbi5cIiksIF9kZWMzID0gKDAsIF91dGlscy5ub2JhdGNoKShcIlRoaXMgb3BlcmF0aW9uIGlzIG5vdCBzdXBwb3J0ZWQgd2l0aGluIGEgYmF0Y2ggb3BlcmF0aW9uLlwiKSwgX2RlYzQgPSAoMCwgX3V0aWxzLm5vYmF0Y2gpKFwiVGhpcyBvcGVyYXRpb24gaXMgbm90IHN1cHBvcnRlZCB3aXRoaW4gYSBiYXRjaCBvcGVyYXRpb24uXCIpLCBfZGVjNSA9ICgwLCBfdXRpbHMubm9iYXRjaCkoXCJDYW4ndCB1c2UgYmF0Y2ggd2l0aGluIGEgYmF0Y2ghXCIpLCBfZGVjNiA9ICgwLCBfdXRpbHMuY2FwYWJsZSkoW1wicGVybWlzc2lvbnNfZW5kcG9pbnRcIl0pLCBfZGVjNyA9ICgwLCBfdXRpbHMuc3VwcG9ydCkoXCIxLjRcIiwgXCIyLjBcIiksIChfY2xhc3MgPVxuLyojX19QVVJFX18qL1xuZnVuY3Rpb24gKCkge1xuICAvKipcbiAgICogQ29uc3RydWN0b3IuXG4gICAqXG4gICAqIEBwYXJhbSAge1N0cmluZ30gICAgICAgcmVtb3RlICBUaGUgcmVtb3RlIFVSTC5cbiAgICogQHBhcmFtICB7T2JqZWN0fSAgICAgICBbb3B0aW9ucz17fV0gICAgICAgICAgICAgICAgICBUaGUgb3B0aW9ucyBvYmplY3QuXG4gICAqIEBwYXJhbSAge0Jvb2xlYW59ICAgICAgW29wdGlvbnMuc2FmZT10cnVlXSAgICAgICAgICAgQWRkcyBjb25jdXJyZW5jeSBoZWFkZXJzIHRvIGV2ZXJ5IHJlcXVlc3RzLlxuICAgKiBAcGFyYW0gIHtFdmVudEVtaXR0ZXJ9IFtvcHRpb25zLmV2ZW50cz1FdmVudEVtaXR0ZXJdIFRoZSBldmVudHMgaGFuZGxlciBpbnN0YW5jZS5cbiAgICogQHBhcmFtICB7T2JqZWN0fSAgICAgICBbb3B0aW9ucy5oZWFkZXJzPXt9XSAgICAgICAgICBUaGUga2V5LXZhbHVlIGhlYWRlcnMgdG8gcGFzcyB0byBlYWNoIHJlcXVlc3QuXG4gICAqIEBwYXJhbSAge09iamVjdH0gICAgICAgW29wdGlvbnMucmV0cnk9MF0gICAgICAgICAgICAgTnVtYmVyIG9mIHJldHJpZXMgd2hlbiByZXF1ZXN0IGZhaWxzIChkZWZhdWx0OiAwKVxuICAgKiBAcGFyYW0gIHtTdHJpbmd9ICAgICAgIFtvcHRpb25zLmJ1Y2tldD1cImRlZmF1bHRcIl0gICAgVGhlIGRlZmF1bHQgYnVja2V0IHRvIHVzZS5cbiAgICogQHBhcmFtICB7U3RyaW5nfSAgICAgICBbb3B0aW9ucy5yZXF1ZXN0TW9kZT1cImNvcnNcIl0gIFRoZSBIVFRQIHJlcXVlc3QgbW9kZSAoZnJvbSBFUzYgZmV0Y2ggc3BlYykuXG4gICAqIEBwYXJhbSAge051bWJlcn0gICAgICAgW29wdGlvbnMudGltZW91dD1udWxsXSAgICAgICAgVGhlIHJlcXVlc3QgdGltZW91dCBpbiBtcywgaWYgYW55LlxuICAgKi9cbiAgZnVuY3Rpb24gS2ludG9DbGllbnRCYXNlKHJlbW90ZSkge1xuICAgIHZhciBvcHRpb25zID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMV0gOiB7fTtcbiAgICAoMCwgX2NsYXNzQ2FsbENoZWNrMi5kZWZhdWx0KSh0aGlzLCBLaW50b0NsaWVudEJhc2UpO1xuXG4gICAgaWYgKHR5cGVvZiByZW1vdGUgIT09IFwic3RyaW5nXCIgfHwgIXJlbW90ZS5sZW5ndGgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIkludmFsaWQgcmVtb3RlIFVSTDogXCIgKyByZW1vdGUpO1xuICAgIH1cblxuICAgIGlmIChyZW1vdGVbcmVtb3RlLmxlbmd0aCAtIDFdID09PSBcIi9cIikge1xuICAgICAgcmVtb3RlID0gcmVtb3RlLnNsaWNlKDAsIC0xKTtcbiAgICB9XG5cbiAgICB0aGlzLl9iYWNrb2ZmUmVsZWFzZVRpbWUgPSBudWxsO1xuICAgIHRoaXMuX3JlcXVlc3RzID0gW107XG4gICAgdGhpcy5faXNCYXRjaCA9ICEhb3B0aW9ucy5iYXRjaDtcbiAgICB0aGlzLl9yZXRyeSA9IG9wdGlvbnMucmV0cnkgfHwgMDtcbiAgICB0aGlzLl9zYWZlID0gISFvcHRpb25zLnNhZmU7XG4gICAgdGhpcy5faGVhZGVycyA9IG9wdGlvbnMuaGVhZGVycyB8fCB7fTsgLy8gcHVibGljIHByb3BlcnRpZXNcblxuICAgIC8qKlxuICAgICAqIFRoZSByZW1vdGUgc2VydmVyIGJhc2UgVVJMLlxuICAgICAqIEB0eXBlIHtTdHJpbmd9XG4gICAgICovXG5cbiAgICB0aGlzLnJlbW90ZSA9IHJlbW90ZTtcbiAgICAvKipcbiAgICAgKiBDdXJyZW50IHNlcnZlciBpbmZvcm1hdGlvbi5cbiAgICAgKiBAaWdub3JlXG4gICAgICogQHR5cGUge09iamVjdHxudWxsfVxuICAgICAqL1xuXG4gICAgdGhpcy5zZXJ2ZXJJbmZvID0gbnVsbDtcbiAgICAvKipcbiAgICAgKiBUaGUgZXZlbnQgZW1pdHRlciBpbnN0YW5jZS4gU2hvdWxkIGNvbXBseSB3aXRoIHRoZSBgRXZlbnRFbWl0dGVyYFxuICAgICAqIGludGVyZmFjZS5cbiAgICAgKiBAaWdub3JlXG4gICAgICogQHR5cGUge0NsYXNzfVxuICAgICAqL1xuXG4gICAgdGhpcy5ldmVudHMgPSBvcHRpb25zLmV2ZW50cztcbiAgICB2YXIgcmVxdWVzdE1vZGUgPSBvcHRpb25zLnJlcXVlc3RNb2RlLFxuICAgICAgICB0aW1lb3V0ID0gb3B0aW9ucy50aW1lb3V0O1xuICAgIC8qKlxuICAgICAqIFRoZSBIVFRQIGluc3RhbmNlLlxuICAgICAqIEBpZ25vcmVcbiAgICAgKiBAdHlwZSB7SFRUUH1cbiAgICAgKi9cblxuICAgIHRoaXMuaHR0cCA9IG5ldyBfaHR0cC5kZWZhdWx0KHRoaXMuZXZlbnRzLCB7XG4gICAgICByZXF1ZXN0TW9kZTogcmVxdWVzdE1vZGUsXG4gICAgICB0aW1lb3V0OiB0aW1lb3V0XG4gICAgfSk7XG5cbiAgICB0aGlzLl9yZWdpc3RlckhUVFBFdmVudHMoKTtcbiAgfVxuICAvKipcbiAgICogVGhlIHJlbW90ZSBlbmRwb2ludCBiYXNlIFVSTC4gU2V0dGluZyB0aGUgdmFsdWUgd2lsbCBhbHNvIGV4dHJhY3QgYW5kXG4gICAqIHZhbGlkYXRlIHRoZSB2ZXJzaW9uLlxuICAgKiBAdHlwZSB7U3RyaW5nfVxuICAgKi9cblxuXG4gICgwLCBfY3JlYXRlQ2xhc3MyLmRlZmF1bHQpKEtpbnRvQ2xpZW50QmFzZSwgW3tcbiAgICBrZXk6IFwiX3JlZ2lzdGVySFRUUEV2ZW50c1wiLFxuXG4gICAgLyoqXG4gICAgICogUmVnaXN0ZXJzIEhUVFAgZXZlbnRzLlxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgdmFsdWU6IGZ1bmN0aW9uIF9yZWdpc3RlckhUVFBFdmVudHMoKSB7XG4gICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuXG4gICAgICAvLyBQcmV2ZW50IHJlZ2lzdGVyaW5nIGV2ZW50IGZyb20gYSBiYXRjaCBjbGllbnQgaW5zdGFuY2VcbiAgICAgIGlmICghdGhpcy5faXNCYXRjaCkge1xuICAgICAgICB0aGlzLmV2ZW50cy5vbihcImJhY2tvZmZcIiwgZnVuY3Rpb24gKGJhY2tvZmZNcykge1xuICAgICAgICAgIF90aGlzLl9iYWNrb2ZmUmVsZWFzZVRpbWUgPSBiYWNrb2ZmTXM7XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXRyaWV2ZSBhIGJ1Y2tldCBvYmplY3QgdG8gcGVyZm9ybSBvcGVyYXRpb25zIG9uIGl0LlxuICAgICAqXG4gICAgICogQHBhcmFtICB7U3RyaW5nfSAgbmFtZSAgICAgICAgICAgICAgVGhlIGJ1Y2tldCBuYW1lLlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gIFtvcHRpb25zPXt9XSAgICAgIFRoZSByZXF1ZXN0IG9wdGlvbnMuXG4gICAgICogQHBhcmFtICB7Qm9vbGVhbn0gW29wdGlvbnMuc2FmZV0gICAgVGhlIHJlc3VsdGluZyBzYWZlIG9wdGlvbi5cbiAgICAgKiBAcGFyYW0gIHtOdW1iZXJ9ICBbb3B0aW9ucy5yZXRyeV0gICBUaGUgcmVzdWx0aW5nIHJldHJ5IG9wdGlvbi5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICBbb3B0aW9ucy5oZWFkZXJzXSBUaGUgZXh0ZW5kZWQgaGVhZGVycyBvYmplY3Qgb3B0aW9uLlxuICAgICAqIEByZXR1cm4ge0J1Y2tldH1cbiAgICAgKi9cblxuICB9LCB7XG4gICAga2V5OiBcImJ1Y2tldFwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBidWNrZXQobmFtZSkge1xuICAgICAgdmFyIG9wdGlvbnMgPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6IHt9O1xuICAgICAgcmV0dXJuIG5ldyBfYnVja2V0LmRlZmF1bHQodGhpcywgbmFtZSwge1xuICAgICAgICBiYXRjaDogdGhpcy5faXNCYXRjaCxcbiAgICAgICAgaGVhZGVyczogdGhpcy5fZ2V0SGVhZGVycyhvcHRpb25zKSxcbiAgICAgICAgc2FmZTogdGhpcy5fZ2V0U2FmZShvcHRpb25zKSxcbiAgICAgICAgcmV0cnk6IHRoaXMuX2dldFJldHJ5KG9wdGlvbnMpXG4gICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU2V0IGNsaWVudCBcImhlYWRlcnNcIiBmb3IgZXZlcnkgcmVxdWVzdCwgdXBkYXRpbmcgcHJldmlvdXMgaGVhZGVycyAoaWYgYW55KS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBoZWFkZXJzIFRoZSBoZWFkZXJzIHRvIG1lcmdlIHdpdGggZXhpc3Rpbmcgb25lcy5cbiAgICAgKi9cblxuICB9LCB7XG4gICAga2V5OiBcInNldEhlYWRlcnNcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gc2V0SGVhZGVycyhoZWFkZXJzKSB7XG4gICAgICB0aGlzLl9oZWFkZXJzID0gKDAsIF9vYmplY3RTcHJlYWQyLmRlZmF1bHQpKHt9LCB0aGlzLl9oZWFkZXJzLCBoZWFkZXJzKTtcbiAgICAgIHRoaXMuc2VydmVySW5mbyA9IG51bGw7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgdmFsdWUgb2YgXCJoZWFkZXJzXCIgZm9yIGEgZ2l2ZW4gcmVxdWVzdCwgbWVyZ2luZyB0aGVcbiAgICAgKiBwZXItcmVxdWVzdCBoZWFkZXJzIHdpdGggb3VyIG93biBcImRlZmF1bHRcIiBoZWFkZXJzLlxuICAgICAqXG4gICAgICogTm90ZSB0aGF0IHVubGlrZSBvdGhlciBvcHRpb25zLCBoZWFkZXJzIGFyZW4ndCBvdmVycmlkZGVuLCBidXRcbiAgICAgKiBtZXJnZWQgaW5zdGVhZC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnMgVGhlIG9wdGlvbnMgZm9yIGEgcmVxdWVzdC5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fVxuICAgICAqL1xuXG4gIH0sIHtcbiAgICBrZXk6IFwiX2dldEhlYWRlcnNcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gX2dldEhlYWRlcnMob3B0aW9ucykge1xuICAgICAgcmV0dXJuICgwLCBfb2JqZWN0U3ByZWFkMi5kZWZhdWx0KSh7fSwgdGhpcy5faGVhZGVycywgb3B0aW9ucy5oZWFkZXJzKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IHRoZSB2YWx1ZSBvZiBcInNhZmVcIiBmb3IgYSBnaXZlbiByZXF1ZXN0LCB1c2luZyB0aGVcbiAgICAgKiBwZXItcmVxdWVzdCBvcHRpb24gaWYgcHJlc2VudCBvciBmYWxsaW5nIGJhY2sgdG8gb3VyIGRlZmF1bHRcbiAgICAgKiBvdGhlcndpc2UuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zIFRoZSBvcHRpb25zIGZvciBhIHJlcXVlc3QuXG4gICAgICogQHJldHVybnMge0Jvb2xlYW59XG4gICAgICovXG5cbiAgfSwge1xuICAgIGtleTogXCJfZ2V0U2FmZVwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBfZ2V0U2FmZShvcHRpb25zKSB7XG4gICAgICByZXR1cm4gKDAsIF9vYmplY3RTcHJlYWQyLmRlZmF1bHQpKHtcbiAgICAgICAgc2FmZTogdGhpcy5fc2FmZVxuICAgICAgfSwgb3B0aW9ucykuc2FmZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQXMgX2dldFNhZmUsIGJ1dCBmb3IgXCJyZXRyeVwiLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cblxuICB9LCB7XG4gICAga2V5OiBcIl9nZXRSZXRyeVwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBfZ2V0UmV0cnkob3B0aW9ucykge1xuICAgICAgcmV0dXJuICgwLCBfb2JqZWN0U3ByZWFkMi5kZWZhdWx0KSh7XG4gICAgICAgIHJldHJ5OiB0aGlzLl9yZXRyeVxuICAgICAgfSwgb3B0aW9ucykucmV0cnk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHJpZXZlcyB0aGUgc2VydmVyJ3MgXCJoZWxsb1wiIGVuZHBvaW50LiBUaGlzIGVuZHBvaW50IHJldmVhbHNcbiAgICAgKiBzZXJ2ZXIgY2FwYWJpbGl0aWVzIGFuZCBzZXR0aW5ncyBhcyB3ZWxsIGFzIHRlbGxpbmcgdGhlIGNsaWVudFxuICAgICAqIFwid2hvIHRoZXkgYXJlXCIgYWNjb3JkaW5nIHRvIHRoZWlyIGdpdmVuIGF1dGhvcml6YXRpb24gaGVhZGVycy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSAgW29wdGlvbnM9e31dIFRoZSByZXF1ZXN0IG9wdGlvbnMuXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSAgW29wdGlvbnMuaGVhZGVycz17fV0gSGVhZGVycyB0byB1c2Ugd2hlbiBtYWtpbmdcbiAgICAgKiAgICAgdGhpcyByZXF1ZXN0LlxuICAgICAqIEBwYXJhbSAge051bWJlcn0gIFtvcHRpb25zLnJldHJ5PTBdICAgIE51bWJlciBvZiByZXRyaWVzIHRvIG1ha2VcbiAgICAgKiAgICAgd2hlbiBmYWNlZCB3aXRoIHRyYW5zaWVudCBlcnJvcnMuXG4gICAgICogQHJldHVybiB7UHJvbWlzZTxPYmplY3QsIEVycm9yPn1cbiAgICAgKi9cblxuICB9LCB7XG4gICAga2V5OiBcIl9nZXRIZWxsb1wiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgX2dldEhlbGxvMiA9ICgwLCBfYXN5bmNUb0dlbmVyYXRvcjIuZGVmYXVsdCkoXG4gICAgICAvKiNfX1BVUkVfXyovXG4gICAgICBfcmVnZW5lcmF0b3IuZGVmYXVsdC5tYXJrKGZ1bmN0aW9uIF9jYWxsZWUoKSB7XG4gICAgICAgIHZhciBvcHRpb25zLFxuICAgICAgICAgICAgcGF0aCxcbiAgICAgICAgICAgIF9yZWYsXG4gICAgICAgICAgICBqc29uLFxuICAgICAgICAgICAgX2FyZ3MgPSBhcmd1bWVudHM7XG5cbiAgICAgICAgcmV0dXJuIF9yZWdlbmVyYXRvci5kZWZhdWx0LndyYXAoZnVuY3Rpb24gX2NhbGxlZSQoX2NvbnRleHQpIHtcbiAgICAgICAgICB3aGlsZSAoMSkge1xuICAgICAgICAgICAgc3dpdGNoIChfY29udGV4dC5wcmV2ID0gX2NvbnRleHQubmV4dCkge1xuICAgICAgICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICAgICAgb3B0aW9ucyA9IF9hcmdzLmxlbmd0aCA+IDAgJiYgX2FyZ3NbMF0gIT09IHVuZGVmaW5lZCA/IF9hcmdzWzBdIDoge307XG4gICAgICAgICAgICAgICAgcGF0aCA9IHRoaXMucmVtb3RlICsgKDAsIF9lbmRwb2ludC5kZWZhdWx0KShcInJvb3RcIik7XG4gICAgICAgICAgICAgICAgX2NvbnRleHQubmV4dCA9IDQ7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuaHR0cC5yZXF1ZXN0KHBhdGgsIHtcbiAgICAgICAgICAgICAgICAgIGhlYWRlcnM6IHRoaXMuX2dldEhlYWRlcnMob3B0aW9ucylcbiAgICAgICAgICAgICAgICB9LCB7XG4gICAgICAgICAgICAgICAgICByZXRyeTogdGhpcy5fZ2V0UmV0cnkob3B0aW9ucylcbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICBjYXNlIDQ6XG4gICAgICAgICAgICAgICAgX3JlZiA9IF9jb250ZXh0LnNlbnQ7XG4gICAgICAgICAgICAgICAganNvbiA9IF9yZWYuanNvbjtcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQuYWJydXB0KFwicmV0dXJuXCIsIGpzb24pO1xuXG4gICAgICAgICAgICAgIGNhc2UgNzpcbiAgICAgICAgICAgICAgY2FzZSBcImVuZFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dC5zdG9wKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9LCBfY2FsbGVlLCB0aGlzKTtcbiAgICAgIH0pKTtcblxuICAgICAgcmV0dXJuIGZ1bmN0aW9uIF9nZXRIZWxsbygpIHtcbiAgICAgICAgcmV0dXJuIF9nZXRIZWxsbzIuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgIH07XG4gICAgfSgpXG4gICAgLyoqXG4gICAgICogUmV0cmlldmVzIHNlcnZlciBpbmZvcm1hdGlvbiBhbmQgcGVyc2lzdCB0aGVtIGxvY2FsbHkuIFRoaXMgb3BlcmF0aW9uIGlzXG4gICAgICogdXN1YWxseSBwZXJmb3JtZWQgYSBzaW5nbGUgdGltZSBkdXJpbmcgdGhlIGluc3RhbmNlIGxpZmVjeWNsZS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gIFtvcHRpb25zPXt9XSBUaGUgcmVxdWVzdCBvcHRpb25zLlxuICAgICAqIEBwYXJhbSAge051bWJlcn0gIFtvcHRpb25zLnJldHJ5PTBdICAgIE51bWJlciBvZiByZXRyaWVzIHRvIG1ha2VcbiAgICAgKiAgICAgd2hlbiBmYWNlZCB3aXRoIHRyYW5zaWVudCBlcnJvcnMuXG4gICAgICogQHJldHVybiB7UHJvbWlzZTxPYmplY3QsIEVycm9yPn1cbiAgICAgKi9cblxuICB9LCB7XG4gICAga2V5OiBcImZldGNoU2VydmVySW5mb1wiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgX2ZldGNoU2VydmVySW5mbyA9ICgwLCBfYXN5bmNUb0dlbmVyYXRvcjIuZGVmYXVsdCkoXG4gICAgICAvKiNfX1BVUkVfXyovXG4gICAgICBfcmVnZW5lcmF0b3IuZGVmYXVsdC5tYXJrKGZ1bmN0aW9uIF9jYWxsZWUyKCkge1xuICAgICAgICB2YXIgb3B0aW9ucyxcbiAgICAgICAgICAgIF9hcmdzMiA9IGFyZ3VtZW50cztcbiAgICAgICAgcmV0dXJuIF9yZWdlbmVyYXRvci5kZWZhdWx0LndyYXAoZnVuY3Rpb24gX2NhbGxlZTIkKF9jb250ZXh0Mikge1xuICAgICAgICAgIHdoaWxlICgxKSB7XG4gICAgICAgICAgICBzd2l0Y2ggKF9jb250ZXh0Mi5wcmV2ID0gX2NvbnRleHQyLm5leHQpIHtcbiAgICAgICAgICAgICAgY2FzZSAwOlxuICAgICAgICAgICAgICAgIG9wdGlvbnMgPSBfYXJnczIubGVuZ3RoID4gMCAmJiBfYXJnczJbMF0gIT09IHVuZGVmaW5lZCA/IF9hcmdzMlswXSA6IHt9O1xuXG4gICAgICAgICAgICAgICAgaWYgKCF0aGlzLnNlcnZlckluZm8pIHtcbiAgICAgICAgICAgICAgICAgIF9jb250ZXh0Mi5uZXh0ID0gMztcbiAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDIuYWJydXB0KFwicmV0dXJuXCIsIHRoaXMuc2VydmVySW5mbyk7XG5cbiAgICAgICAgICAgICAgY2FzZSAzOlxuICAgICAgICAgICAgICAgIF9jb250ZXh0Mi5uZXh0ID0gNTtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fZ2V0SGVsbG8oe1xuICAgICAgICAgICAgICAgICAgcmV0cnk6IHRoaXMuX2dldFJldHJ5KG9wdGlvbnMpXG4gICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgY2FzZSA1OlxuICAgICAgICAgICAgICAgIHRoaXMuc2VydmVySW5mbyA9IF9jb250ZXh0Mi5zZW50O1xuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDIuYWJydXB0KFwicmV0dXJuXCIsIHRoaXMuc2VydmVySW5mbyk7XG5cbiAgICAgICAgICAgICAgY2FzZSA3OlxuICAgICAgICAgICAgICBjYXNlIFwiZW5kXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0Mi5zdG9wKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9LCBfY2FsbGVlMiwgdGhpcyk7XG4gICAgICB9KSk7XG5cbiAgICAgIHJldHVybiBmdW5jdGlvbiBmZXRjaFNlcnZlckluZm8oKSB7XG4gICAgICAgIHJldHVybiBfZmV0Y2hTZXJ2ZXJJbmZvLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICB9O1xuICAgIH0oKVxuICAgIC8qKlxuICAgICAqIFJldHJpZXZlcyBLaW50byBzZXJ2ZXIgc2V0dGluZ3MuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICBbb3B0aW9ucz17fV0gVGhlIHJlcXVlc3Qgb3B0aW9ucy5cbiAgICAgKiBAcGFyYW0gIHtOdW1iZXJ9ICBbb3B0aW9ucy5yZXRyeT0wXSAgICBOdW1iZXIgb2YgcmV0cmllcyB0byBtYWtlXG4gICAgICogICAgIHdoZW4gZmFjZWQgd2l0aCB0cmFuc2llbnQgZXJyb3JzLlxuICAgICAqIEByZXR1cm4ge1Byb21pc2U8T2JqZWN0LCBFcnJvcj59XG4gICAgICovXG5cbiAgfSwge1xuICAgIGtleTogXCJmZXRjaFNlcnZlclNldHRpbmdzXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciBfZmV0Y2hTZXJ2ZXJTZXR0aW5ncyA9ICgwLCBfYXN5bmNUb0dlbmVyYXRvcjIuZGVmYXVsdCkoXG4gICAgICAvKiNfX1BVUkVfXyovXG4gICAgICBfcmVnZW5lcmF0b3IuZGVmYXVsdC5tYXJrKGZ1bmN0aW9uIF9jYWxsZWUzKG9wdGlvbnMpIHtcbiAgICAgICAgdmFyIF9yZWYyLCBzZXR0aW5ncztcblxuICAgICAgICByZXR1cm4gX3JlZ2VuZXJhdG9yLmRlZmF1bHQud3JhcChmdW5jdGlvbiBfY2FsbGVlMyQoX2NvbnRleHQzKSB7XG4gICAgICAgICAgd2hpbGUgKDEpIHtcbiAgICAgICAgICAgIHN3aXRjaCAoX2NvbnRleHQzLnByZXYgPSBfY29udGV4dDMubmV4dCkge1xuICAgICAgICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICAgICAgX2NvbnRleHQzLm5leHQgPSAyO1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmZldGNoU2VydmVySW5mbyhvcHRpb25zKTtcblxuICAgICAgICAgICAgICBjYXNlIDI6XG4gICAgICAgICAgICAgICAgX3JlZjIgPSBfY29udGV4dDMuc2VudDtcbiAgICAgICAgICAgICAgICBzZXR0aW5ncyA9IF9yZWYyLnNldHRpbmdzO1xuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDMuYWJydXB0KFwicmV0dXJuXCIsIHNldHRpbmdzKTtcblxuICAgICAgICAgICAgICBjYXNlIDU6XG4gICAgICAgICAgICAgIGNhc2UgXCJlbmRcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQzLnN0b3AoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0sIF9jYWxsZWUzLCB0aGlzKTtcbiAgICAgIH0pKTtcblxuICAgICAgcmV0dXJuIGZ1bmN0aW9uIGZldGNoU2VydmVyU2V0dGluZ3MoX3gpIHtcbiAgICAgICAgcmV0dXJuIF9mZXRjaFNlcnZlclNldHRpbmdzLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICB9O1xuICAgIH0oKVxuICAgIC8qKlxuICAgICAqIFJldHJpZXZlIHNlcnZlciBjYXBhYmlsaXRpZXMgaW5mb3JtYXRpb24uXG4gICAgICpcbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICBbb3B0aW9ucz17fV0gVGhlIHJlcXVlc3Qgb3B0aW9ucy5cbiAgICAgKiBAcGFyYW0gIHtOdW1iZXJ9ICBbb3B0aW9ucy5yZXRyeT0wXSAgICBOdW1iZXIgb2YgcmV0cmllcyB0byBtYWtlXG4gICAgICogICAgIHdoZW4gZmFjZWQgd2l0aCB0cmFuc2llbnQgZXJyb3JzLlxuICAgICAqIEByZXR1cm4ge1Byb21pc2U8T2JqZWN0LCBFcnJvcj59XG4gICAgICovXG5cbiAgfSwge1xuICAgIGtleTogXCJmZXRjaFNlcnZlckNhcGFiaWxpdGllc1wiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgX2ZldGNoU2VydmVyQ2FwYWJpbGl0aWVzID0gKDAsIF9hc3luY1RvR2VuZXJhdG9yMi5kZWZhdWx0KShcbiAgICAgIC8qI19fUFVSRV9fKi9cbiAgICAgIF9yZWdlbmVyYXRvci5kZWZhdWx0Lm1hcmsoZnVuY3Rpb24gX2NhbGxlZTQoKSB7XG4gICAgICAgIHZhciBvcHRpb25zLFxuICAgICAgICAgICAgX3JlZjMsXG4gICAgICAgICAgICBjYXBhYmlsaXRpZXMsXG4gICAgICAgICAgICBfYXJnczQgPSBhcmd1bWVudHM7XG5cbiAgICAgICAgcmV0dXJuIF9yZWdlbmVyYXRvci5kZWZhdWx0LndyYXAoZnVuY3Rpb24gX2NhbGxlZTQkKF9jb250ZXh0NCkge1xuICAgICAgICAgIHdoaWxlICgxKSB7XG4gICAgICAgICAgICBzd2l0Y2ggKF9jb250ZXh0NC5wcmV2ID0gX2NvbnRleHQ0Lm5leHQpIHtcbiAgICAgICAgICAgICAgY2FzZSAwOlxuICAgICAgICAgICAgICAgIG9wdGlvbnMgPSBfYXJnczQubGVuZ3RoID4gMCAmJiBfYXJnczRbMF0gIT09IHVuZGVmaW5lZCA/IF9hcmdzNFswXSA6IHt9O1xuICAgICAgICAgICAgICAgIF9jb250ZXh0NC5uZXh0ID0gMztcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5mZXRjaFNlcnZlckluZm8ob3B0aW9ucyk7XG5cbiAgICAgICAgICAgICAgY2FzZSAzOlxuICAgICAgICAgICAgICAgIF9yZWYzID0gX2NvbnRleHQ0LnNlbnQ7XG4gICAgICAgICAgICAgICAgY2FwYWJpbGl0aWVzID0gX3JlZjMuY2FwYWJpbGl0aWVzO1xuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDQuYWJydXB0KFwicmV0dXJuXCIsIGNhcGFiaWxpdGllcyk7XG5cbiAgICAgICAgICAgICAgY2FzZSA2OlxuICAgICAgICAgICAgICBjYXNlIFwiZW5kXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0NC5zdG9wKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9LCBfY2FsbGVlNCwgdGhpcyk7XG4gICAgICB9KSk7XG5cbiAgICAgIHJldHVybiBmdW5jdGlvbiBmZXRjaFNlcnZlckNhcGFiaWxpdGllcygpIHtcbiAgICAgICAgcmV0dXJuIF9mZXRjaFNlcnZlckNhcGFiaWxpdGllcy5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgfTtcbiAgICB9KClcbiAgICAvKipcbiAgICAgKiBSZXRyaWV2ZSBhdXRoZW50aWNhdGVkIHVzZXIgaW5mb3JtYXRpb24uXG4gICAgICpcbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICBbb3B0aW9ucz17fV0gVGhlIHJlcXVlc3Qgb3B0aW9ucy5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICBbb3B0aW9ucy5oZWFkZXJzPXt9XSBIZWFkZXJzIHRvIHVzZSB3aGVuIG1ha2luZ1xuICAgICAqICAgICB0aGlzIHJlcXVlc3QuXG4gICAgICogQHBhcmFtICB7TnVtYmVyfSAgW29wdGlvbnMucmV0cnk9MF0gICAgTnVtYmVyIG9mIHJldHJpZXMgdG8gbWFrZVxuICAgICAqICAgICB3aGVuIGZhY2VkIHdpdGggdHJhbnNpZW50IGVycm9ycy5cbiAgICAgKiBAcmV0dXJuIHtQcm9taXNlPE9iamVjdCwgRXJyb3I+fVxuICAgICAqL1xuXG4gIH0sIHtcbiAgICBrZXk6IFwiZmV0Y2hVc2VyXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciBfZmV0Y2hVc2VyID0gKDAsIF9hc3luY1RvR2VuZXJhdG9yMi5kZWZhdWx0KShcbiAgICAgIC8qI19fUFVSRV9fKi9cbiAgICAgIF9yZWdlbmVyYXRvci5kZWZhdWx0Lm1hcmsoZnVuY3Rpb24gX2NhbGxlZTUoKSB7XG4gICAgICAgIHZhciBvcHRpb25zLFxuICAgICAgICAgICAgX3JlZjQsXG4gICAgICAgICAgICB1c2VyLFxuICAgICAgICAgICAgX2FyZ3M1ID0gYXJndW1lbnRzO1xuXG4gICAgICAgIHJldHVybiBfcmVnZW5lcmF0b3IuZGVmYXVsdC53cmFwKGZ1bmN0aW9uIF9jYWxsZWU1JChfY29udGV4dDUpIHtcbiAgICAgICAgICB3aGlsZSAoMSkge1xuICAgICAgICAgICAgc3dpdGNoIChfY29udGV4dDUucHJldiA9IF9jb250ZXh0NS5uZXh0KSB7XG4gICAgICAgICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgICAgICBvcHRpb25zID0gX2FyZ3M1Lmxlbmd0aCA+IDAgJiYgX2FyZ3M1WzBdICE9PSB1bmRlZmluZWQgPyBfYXJnczVbMF0gOiB7fTtcbiAgICAgICAgICAgICAgICBfY29udGV4dDUubmV4dCA9IDM7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2dldEhlbGxvKG9wdGlvbnMpO1xuXG4gICAgICAgICAgICAgIGNhc2UgMzpcbiAgICAgICAgICAgICAgICBfcmVmNCA9IF9jb250ZXh0NS5zZW50O1xuICAgICAgICAgICAgICAgIHVzZXIgPSBfcmVmNC51c2VyO1xuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDUuYWJydXB0KFwicmV0dXJuXCIsIHVzZXIpO1xuXG4gICAgICAgICAgICAgIGNhc2UgNjpcbiAgICAgICAgICAgICAgY2FzZSBcImVuZFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDUuc3RvcCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSwgX2NhbGxlZTUsIHRoaXMpO1xuICAgICAgfSkpO1xuXG4gICAgICByZXR1cm4gZnVuY3Rpb24gZmV0Y2hVc2VyKCkge1xuICAgICAgICByZXR1cm4gX2ZldGNoVXNlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgfTtcbiAgICB9KClcbiAgICAvKipcbiAgICAgKiBSZXRyaWV2ZSBhdXRoZW50aWNhdGVkIHVzZXIgaW5mb3JtYXRpb24uXG4gICAgICpcbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICBbb3B0aW9ucz17fV0gVGhlIHJlcXVlc3Qgb3B0aW9ucy5cbiAgICAgKiBAcGFyYW0gIHtOdW1iZXJ9ICBbb3B0aW9ucy5yZXRyeT0wXSAgICBOdW1iZXIgb2YgcmV0cmllcyB0byBtYWtlXG4gICAgICogICAgIHdoZW4gZmFjZWQgd2l0aCB0cmFuc2llbnQgZXJyb3JzLlxuICAgICAqIEByZXR1cm4ge1Byb21pc2U8T2JqZWN0LCBFcnJvcj59XG4gICAgICovXG5cbiAgfSwge1xuICAgIGtleTogXCJmZXRjaEhUVFBBcGlWZXJzaW9uXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciBfZmV0Y2hIVFRQQXBpVmVyc2lvbiA9ICgwLCBfYXN5bmNUb0dlbmVyYXRvcjIuZGVmYXVsdCkoXG4gICAgICAvKiNfX1BVUkVfXyovXG4gICAgICBfcmVnZW5lcmF0b3IuZGVmYXVsdC5tYXJrKGZ1bmN0aW9uIF9jYWxsZWU2KCkge1xuICAgICAgICB2YXIgb3B0aW9ucyxcbiAgICAgICAgICAgIF9yZWY1LFxuICAgICAgICAgICAgaHR0cF9hcGlfdmVyc2lvbixcbiAgICAgICAgICAgIF9hcmdzNiA9IGFyZ3VtZW50cztcblxuICAgICAgICByZXR1cm4gX3JlZ2VuZXJhdG9yLmRlZmF1bHQud3JhcChmdW5jdGlvbiBfY2FsbGVlNiQoX2NvbnRleHQ2KSB7XG4gICAgICAgICAgd2hpbGUgKDEpIHtcbiAgICAgICAgICAgIHN3aXRjaCAoX2NvbnRleHQ2LnByZXYgPSBfY29udGV4dDYubmV4dCkge1xuICAgICAgICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICAgICAgb3B0aW9ucyA9IF9hcmdzNi5sZW5ndGggPiAwICYmIF9hcmdzNlswXSAhPT0gdW5kZWZpbmVkID8gX2FyZ3M2WzBdIDoge307XG4gICAgICAgICAgICAgICAgX2NvbnRleHQ2Lm5leHQgPSAzO1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmZldGNoU2VydmVySW5mbyhvcHRpb25zKTtcblxuICAgICAgICAgICAgICBjYXNlIDM6XG4gICAgICAgICAgICAgICAgX3JlZjUgPSBfY29udGV4dDYuc2VudDtcbiAgICAgICAgICAgICAgICBodHRwX2FwaV92ZXJzaW9uID0gX3JlZjUuaHR0cF9hcGlfdmVyc2lvbjtcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQ2LmFicnVwdChcInJldHVyblwiLCBodHRwX2FwaV92ZXJzaW9uKTtcblxuICAgICAgICAgICAgICBjYXNlIDY6XG4gICAgICAgICAgICAgIGNhc2UgXCJlbmRcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQ2LnN0b3AoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0sIF9jYWxsZWU2LCB0aGlzKTtcbiAgICAgIH0pKTtcblxuICAgICAgcmV0dXJuIGZ1bmN0aW9uIGZldGNoSFRUUEFwaVZlcnNpb24oKSB7XG4gICAgICAgIHJldHVybiBfZmV0Y2hIVFRQQXBpVmVyc2lvbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgfTtcbiAgICB9KClcbiAgICAvKipcbiAgICAgKiBQcm9jZXNzIGJhdGNoIHJlcXVlc3RzLCBjaHVua2luZyB0aGVtIGFjY29yZGluZyB0byB0aGUgYmF0Y2hfbWF4X3JlcXVlc3RzXG4gICAgICogc2VydmVyIHNldHRpbmcgd2hlbiBuZWVkZWQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gIHtBcnJheX0gIHJlcXVlc3RzICAgICBUaGUgbGlzdCBvZiBiYXRjaCBzdWJyZXF1ZXN0cyB0byBwZXJmb3JtLlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gW29wdGlvbnM9e31dIFRoZSBvcHRpb25zIG9iamVjdC5cbiAgICAgKiBAcmV0dXJuIHtQcm9taXNlPE9iamVjdCwgRXJyb3I+fVxuICAgICAqL1xuXG4gIH0sIHtcbiAgICBrZXk6IFwiX2JhdGNoUmVxdWVzdHNcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gKCkge1xuICAgICAgdmFyIF9iYXRjaFJlcXVlc3RzMiA9ICgwLCBfYXN5bmNUb0dlbmVyYXRvcjIuZGVmYXVsdCkoXG4gICAgICAvKiNfX1BVUkVfXyovXG4gICAgICBfcmVnZW5lcmF0b3IuZGVmYXVsdC5tYXJrKGZ1bmN0aW9uIF9jYWxsZWU3KHJlcXVlc3RzKSB7XG4gICAgICAgIHZhciBfdGhpczIgPSB0aGlzO1xuXG4gICAgICAgIHZhciBvcHRpb25zLFxuICAgICAgICAgICAgaGVhZGVycyxcbiAgICAgICAgICAgIHNlcnZlclNldHRpbmdzLFxuICAgICAgICAgICAgbWF4UmVxdWVzdHMsXG4gICAgICAgICAgICBjaHVua3MsXG4gICAgICAgICAgICBfcmVmNixcbiAgICAgICAgICAgIHJlc3BvbnNlcyxcbiAgICAgICAgICAgIF9hcmdzNyA9IGFyZ3VtZW50cztcblxuICAgICAgICByZXR1cm4gX3JlZ2VuZXJhdG9yLmRlZmF1bHQud3JhcChmdW5jdGlvbiBfY2FsbGVlNyQoX2NvbnRleHQ3KSB7XG4gICAgICAgICAgd2hpbGUgKDEpIHtcbiAgICAgICAgICAgIHN3aXRjaCAoX2NvbnRleHQ3LnByZXYgPSBfY29udGV4dDcubmV4dCkge1xuICAgICAgICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICAgICAgb3B0aW9ucyA9IF9hcmdzNy5sZW5ndGggPiAxICYmIF9hcmdzN1sxXSAhPT0gdW5kZWZpbmVkID8gX2FyZ3M3WzFdIDoge307XG4gICAgICAgICAgICAgICAgaGVhZGVycyA9IHRoaXMuX2dldEhlYWRlcnMob3B0aW9ucyk7XG5cbiAgICAgICAgICAgICAgICBpZiAocmVxdWVzdHMubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICBfY29udGV4dDcubmV4dCA9IDQ7XG4gICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQ3LmFicnVwdChcInJldHVyblwiLCBbXSk7XG5cbiAgICAgICAgICAgICAgY2FzZSA0OlxuICAgICAgICAgICAgICAgIF9jb250ZXh0Ny5uZXh0ID0gNjtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5mZXRjaFNlcnZlclNldHRpbmdzKHtcbiAgICAgICAgICAgICAgICAgIHJldHJ5OiB0aGlzLl9nZXRSZXRyeShvcHRpb25zKVxuICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgIGNhc2UgNjpcbiAgICAgICAgICAgICAgICBzZXJ2ZXJTZXR0aW5ncyA9IF9jb250ZXh0Ny5zZW50O1xuICAgICAgICAgICAgICAgIG1heFJlcXVlc3RzID0gc2VydmVyU2V0dGluZ3NbXCJiYXRjaF9tYXhfcmVxdWVzdHNcIl07XG5cbiAgICAgICAgICAgICAgICBpZiAoIShtYXhSZXF1ZXN0cyAmJiByZXF1ZXN0cy5sZW5ndGggPiBtYXhSZXF1ZXN0cykpIHtcbiAgICAgICAgICAgICAgICAgIF9jb250ZXh0Ny5uZXh0ID0gMTE7XG4gICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBjaHVua3MgPSAoMCwgX3V0aWxzLnBhcnRpdGlvbikocmVxdWVzdHMsIG1heFJlcXVlc3RzKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQ3LmFicnVwdChcInJldHVyblwiLCAoMCwgX3V0aWxzLnBNYXApKGNodW5rcywgZnVuY3Rpb24gKGNodW5rKSB7XG4gICAgICAgICAgICAgICAgICByZXR1cm4gX3RoaXMyLl9iYXRjaFJlcXVlc3RzKGNodW5rLCBvcHRpb25zKTtcbiAgICAgICAgICAgICAgICB9KSk7XG5cbiAgICAgICAgICAgICAgY2FzZSAxMTpcbiAgICAgICAgICAgICAgICBfY29udGV4dDcubmV4dCA9IDEzO1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmV4ZWN1dGUoe1xuICAgICAgICAgICAgICAgICAgLy8gRklYTUU6IGlzIHRoaXMgcmVhbGx5IG5lY2Vzc2FyeSwgc2luY2UgaXQncyBhbHNvIHByZXNlbnQgaW5cbiAgICAgICAgICAgICAgICAgIC8vIHRoZSBcImRlZmF1bHRzXCI/XG4gICAgICAgICAgICAgICAgICBoZWFkZXJzOiBoZWFkZXJzLFxuICAgICAgICAgICAgICAgICAgcGF0aDogKDAsIF9lbmRwb2ludC5kZWZhdWx0KShcImJhdGNoXCIpLFxuICAgICAgICAgICAgICAgICAgbWV0aG9kOiBcIlBPU1RcIixcbiAgICAgICAgICAgICAgICAgIGJvZHk6IHtcbiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdHM6IHtcbiAgICAgICAgICAgICAgICAgICAgICBoZWFkZXJzOiBoZWFkZXJzXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIHJlcXVlc3RzOiByZXF1ZXN0c1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0sIHtcbiAgICAgICAgICAgICAgICAgIHJldHJ5OiB0aGlzLl9nZXRSZXRyeShvcHRpb25zKVxuICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgIGNhc2UgMTM6XG4gICAgICAgICAgICAgICAgX3JlZjYgPSBfY29udGV4dDcuc2VudDtcbiAgICAgICAgICAgICAgICByZXNwb25zZXMgPSBfcmVmNi5yZXNwb25zZXM7XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0Ny5hYnJ1cHQoXCJyZXR1cm5cIiwgcmVzcG9uc2VzKTtcblxuICAgICAgICAgICAgICBjYXNlIDE2OlxuICAgICAgICAgICAgICBjYXNlIFwiZW5kXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0Ny5zdG9wKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9LCBfY2FsbGVlNywgdGhpcyk7XG4gICAgICB9KSk7XG5cbiAgICAgIHJldHVybiBmdW5jdGlvbiBfYmF0Y2hSZXF1ZXN0cyhfeDIpIHtcbiAgICAgICAgcmV0dXJuIF9iYXRjaFJlcXVlc3RzMi5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgfTtcbiAgICB9KClcbiAgICAvKipcbiAgICAgKiBTZW5kcyBiYXRjaCByZXF1ZXN0cyB0byB0aGUgcmVtb3RlIHNlcnZlci5cbiAgICAgKlxuICAgICAqIE5vdGU6IFJlc2VydmVkIGZvciBpbnRlcm5hbCB1c2Ugb25seS5cbiAgICAgKlxuICAgICAqIEBpZ25vcmVcbiAgICAgKiBAcGFyYW0gIHtGdW5jdGlvbn0gZm4gICAgICAgICAgICAgICAgICAgICAgICBUaGUgZnVuY3Rpb24gdG8gdXNlIGZvciBkZXNjcmliaW5nIGJhdGNoIG9wcy5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICAgW29wdGlvbnM9e31dICAgICAgICAgICAgICBUaGUgb3B0aW9ucyBvYmplY3QuXG4gICAgICogQHBhcmFtICB7Qm9vbGVhbn0gIFtvcHRpb25zLnNhZmVdICAgICAgICAgICAgVGhlIHNhZmUgb3B0aW9uLlxuICAgICAqIEBwYXJhbSAge051bWJlcn0gICBbb3B0aW9ucy5yZXRyeV0gICAgICAgICAgIFRoZSByZXRyeSBvcHRpb24uXG4gICAgICogQHBhcmFtICB7U3RyaW5nfSAgIFtvcHRpb25zLmJ1Y2tldF0gICAgICAgICAgVGhlIGJ1Y2tldCBuYW1lIG9wdGlvbi5cbiAgICAgKiBAcGFyYW0gIHtTdHJpbmd9ICAgW29wdGlvbnMuY29sbGVjdGlvbl0gICAgICBUaGUgY29sbGVjdGlvbiBuYW1lIG9wdGlvbi5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICAgW29wdGlvbnMuaGVhZGVyc10gICAgICAgICBUaGUgaGVhZGVycyBvYmplY3Qgb3B0aW9uLlxuICAgICAqIEBwYXJhbSAge0Jvb2xlYW59ICBbb3B0aW9ucy5hZ2dyZWdhdGU9ZmFsc2VdIFByb2R1Y2VzIGFuIGFnZ3JlZ2F0ZWQgcmVzdWx0IG9iamVjdC5cbiAgICAgKiBAcmV0dXJuIHtQcm9taXNlPE9iamVjdCwgRXJyb3I+fVxuICAgICAqL1xuXG4gIH0sIHtcbiAgICBrZXk6IFwiYmF0Y2hcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gKCkge1xuICAgICAgdmFyIF9iYXRjaCA9ICgwLCBfYXN5bmNUb0dlbmVyYXRvcjIuZGVmYXVsdCkoXG4gICAgICAvKiNfX1BVUkVfXyovXG4gICAgICBfcmVnZW5lcmF0b3IuZGVmYXVsdC5tYXJrKGZ1bmN0aW9uIF9jYWxsZWU4KGZuKSB7XG4gICAgICAgIHZhciBvcHRpb25zLFxuICAgICAgICAgICAgcm9vdEJhdGNoLFxuICAgICAgICAgICAgYnVja2V0QmF0Y2gsXG4gICAgICAgICAgICBjb2xsQmF0Y2gsXG4gICAgICAgICAgICBiYXRjaENsaWVudCxcbiAgICAgICAgICAgIHJlc3BvbnNlcyxcbiAgICAgICAgICAgIF9hcmdzOCA9IGFyZ3VtZW50cztcbiAgICAgICAgcmV0dXJuIF9yZWdlbmVyYXRvci5kZWZhdWx0LndyYXAoZnVuY3Rpb24gX2NhbGxlZTgkKF9jb250ZXh0OCkge1xuICAgICAgICAgIHdoaWxlICgxKSB7XG4gICAgICAgICAgICBzd2l0Y2ggKF9jb250ZXh0OC5wcmV2ID0gX2NvbnRleHQ4Lm5leHQpIHtcbiAgICAgICAgICAgICAgY2FzZSAwOlxuICAgICAgICAgICAgICAgIG9wdGlvbnMgPSBfYXJnczgubGVuZ3RoID4gMSAmJiBfYXJnczhbMV0gIT09IHVuZGVmaW5lZCA/IF9hcmdzOFsxXSA6IHt9O1xuICAgICAgICAgICAgICAgIHJvb3RCYXRjaCA9IG5ldyBLaW50b0NsaWVudEJhc2UodGhpcy5yZW1vdGUsIHtcbiAgICAgICAgICAgICAgICAgIGV2ZW50czogdGhpcy5ldmVudHMsXG4gICAgICAgICAgICAgICAgICBiYXRjaDogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgIHNhZmU6IHRoaXMuX2dldFNhZmUob3B0aW9ucyksXG4gICAgICAgICAgICAgICAgICByZXRyeTogdGhpcy5fZ2V0UmV0cnkob3B0aW9ucylcbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgIGlmIChvcHRpb25zLmJ1Y2tldCkge1xuICAgICAgICAgICAgICAgICAgYnVja2V0QmF0Y2ggPSByb290QmF0Y2guYnVja2V0KG9wdGlvbnMuYnVja2V0KTtcblxuICAgICAgICAgICAgICAgICAgaWYgKG9wdGlvbnMuY29sbGVjdGlvbikge1xuICAgICAgICAgICAgICAgICAgICBjb2xsQmF0Y2ggPSBidWNrZXRCYXRjaC5jb2xsZWN0aW9uKG9wdGlvbnMuY29sbGVjdGlvbik7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgYmF0Y2hDbGllbnQgPSBjb2xsQmF0Y2ggfHwgYnVja2V0QmF0Y2ggfHwgcm9vdEJhdGNoO1xuICAgICAgICAgICAgICAgIGZuKGJhdGNoQ2xpZW50KTtcbiAgICAgICAgICAgICAgICBfY29udGV4dDgubmV4dCA9IDc7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2JhdGNoUmVxdWVzdHMocm9vdEJhdGNoLl9yZXF1ZXN0cywgb3B0aW9ucyk7XG5cbiAgICAgICAgICAgICAgY2FzZSA3OlxuICAgICAgICAgICAgICAgIHJlc3BvbnNlcyA9IF9jb250ZXh0OC5zZW50O1xuXG4gICAgICAgICAgICAgICAgaWYgKCFvcHRpb25zLmFnZ3JlZ2F0ZSkge1xuICAgICAgICAgICAgICAgICAgX2NvbnRleHQ4Lm5leHQgPSAxMjtcbiAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDguYWJydXB0KFwicmV0dXJuXCIsICgwLCBfYmF0Y2gyLmFnZ3JlZ2F0ZSkocmVzcG9uc2VzLCByb290QmF0Y2guX3JlcXVlc3RzKSk7XG5cbiAgICAgICAgICAgICAgY2FzZSAxMjpcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQ4LmFicnVwdChcInJldHVyblwiLCByZXNwb25zZXMpO1xuXG4gICAgICAgICAgICAgIGNhc2UgMTM6XG4gICAgICAgICAgICAgIGNhc2UgXCJlbmRcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQ4LnN0b3AoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0sIF9jYWxsZWU4LCB0aGlzKTtcbiAgICAgIH0pKTtcblxuICAgICAgcmV0dXJuIGZ1bmN0aW9uIGJhdGNoKF94Mykge1xuICAgICAgICByZXR1cm4gX2JhdGNoLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICB9O1xuICAgIH0oKVxuICAgIC8qKlxuICAgICAqIEV4ZWN1dGVzIGFuIGF0b21pYyBIVFRQIHJlcXVlc3QuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSAge09iamVjdH0gIHJlcXVlc3QgICAgICAgICAgICAgVGhlIHJlcXVlc3Qgb2JqZWN0LlxuICAgICAqIEBwYXJhbSAge1N0cmluZ30gIHJlcXVlc3QucGF0aCAgICAgICAgVGhlIHBhdGggdG8gZmV0Y2gsIHJlbGF0aXZlXG4gICAgICogICAgIHRvIHRoZSBLaW50byBzZXJ2ZXIgcm9vdC5cbiAgICAgKiBAcGFyYW0gIHtTdHJpbmd9ICBbcmVxdWVzdC5tZXRob2Q9XCJHRVRcIl0gVGhlIG1ldGhvZCB0byB1c2UgaW4gdGhlXG4gICAgICogICAgIHJlcXVlc3QuXG4gICAgICogQHBhcmFtICB7Qm9keX0gICAgW3JlcXVlc3QuYm9keV0gICAgICBUaGUgcmVxdWVzdCBib2R5LlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gIFtyZXF1ZXN0LmhlYWRlcnM9e31dIFRoZSByZXF1ZXN0IGhlYWRlcnMuXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSAgW29wdGlvbnM9e31dICAgICAgICBUaGUgb3B0aW9ucyBvYmplY3QuXG4gICAgICogQHBhcmFtICB7Qm9vbGVhbn0gW29wdGlvbnMucmF3PWZhbHNlXSBJZiB0cnVlLCByZXNvbHZlIHdpdGggZnVsbCByZXNwb25zZVxuICAgICAqIEBwYXJhbSAge0Jvb2xlYW59IFtvcHRpb25zLnN0cmluZ2lmeT10cnVlXSBJZiB0cnVlLCBzZXJpYWxpemUgYm9keSBkYXRhIHRvXG4gICAgICogQHBhcmFtICB7TnVtYmVyfSAgW29wdGlvbnMucmV0cnk9MF0gICBUaGUgbnVtYmVyIG9mIHRpbWVzIHRvXG4gICAgICogICAgIHJldHJ5IGEgcmVxdWVzdCBpZiB0aGUgc2VydmVyIHJlc3BvbmRzIHdpdGggUmV0cnktQWZ0ZXIuXG4gICAgICogSlNPTi5cbiAgICAgKiBAcmV0dXJuIHtQcm9taXNlPE9iamVjdCwgRXJyb3I+fVxuICAgICAqL1xuXG4gIH0sIHtcbiAgICBrZXk6IFwiZXhlY3V0ZVwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgX2V4ZWN1dGUgPSAoMCwgX2FzeW5jVG9HZW5lcmF0b3IyLmRlZmF1bHQpKFxuICAgICAgLyojX19QVVJFX18qL1xuICAgICAgX3JlZ2VuZXJhdG9yLmRlZmF1bHQubWFyayhmdW5jdGlvbiBfY2FsbGVlOShyZXF1ZXN0KSB7XG4gICAgICAgIHZhciBvcHRpb25zLFxuICAgICAgICAgICAgX29wdGlvbnMkcmF3LFxuICAgICAgICAgICAgcmF3LFxuICAgICAgICAgICAgX29wdGlvbnMkc3RyaW5naWZ5LFxuICAgICAgICAgICAgc3RyaW5naWZ5LFxuICAgICAgICAgICAgbXNnLFxuICAgICAgICAgICAgcmVzdWx0LFxuICAgICAgICAgICAgX2FyZ3M5ID0gYXJndW1lbnRzO1xuXG4gICAgICAgIHJldHVybiBfcmVnZW5lcmF0b3IuZGVmYXVsdC53cmFwKGZ1bmN0aW9uIF9jYWxsZWU5JChfY29udGV4dDkpIHtcbiAgICAgICAgICB3aGlsZSAoMSkge1xuICAgICAgICAgICAgc3dpdGNoIChfY29udGV4dDkucHJldiA9IF9jb250ZXh0OS5uZXh0KSB7XG4gICAgICAgICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgICAgICBvcHRpb25zID0gX2FyZ3M5Lmxlbmd0aCA+IDEgJiYgX2FyZ3M5WzFdICE9PSB1bmRlZmluZWQgPyBfYXJnczlbMV0gOiB7fTtcbiAgICAgICAgICAgICAgICBfb3B0aW9ucyRyYXcgPSBvcHRpb25zLnJhdywgcmF3ID0gX29wdGlvbnMkcmF3ID09PSB2b2lkIDAgPyBmYWxzZSA6IF9vcHRpb25zJHJhdywgX29wdGlvbnMkc3RyaW5naWZ5ID0gb3B0aW9ucy5zdHJpbmdpZnksIHN0cmluZ2lmeSA9IF9vcHRpb25zJHN0cmluZ2lmeSA9PT0gdm9pZCAwID8gdHJ1ZSA6IF9vcHRpb25zJHN0cmluZ2lmeTsgLy8gSWYgd2UncmUgd2l0aGluIGEgYmF0Y2gsIGFkZCB0aGUgcmVxdWVzdCB0byB0aGUgc3RhY2sgdG8gc2VuZCBhdCBvbmNlLlxuXG4gICAgICAgICAgICAgICAgaWYgKCF0aGlzLl9pc0JhdGNoKSB7XG4gICAgICAgICAgICAgICAgICBfY29udGV4dDkubmV4dCA9IDY7XG4gICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB0aGlzLl9yZXF1ZXN0cy5wdXNoKHJlcXVlc3QpOyAvLyBSZXNvbHZlIHdpdGggYSBtZXNzYWdlIGluIGNhc2UgcGVvcGxlIGF0dGVtcHQgYXQgY29uc3VtaW5nIHRoZSByZXN1bHRcbiAgICAgICAgICAgICAgICAvLyBmcm9tIHdpdGhpbiBhIGJhdGNoIG9wZXJhdGlvbi5cblxuXG4gICAgICAgICAgICAgICAgbXNnID0gXCJUaGlzIHJlc3VsdCBpcyBnZW5lcmF0ZWQgZnJvbSB3aXRoaW4gYSBiYXRjaCBcIiArIFwib3BlcmF0aW9uIGFuZCBzaG91bGQgbm90IGJlIGNvbnN1bWVkLlwiO1xuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDkuYWJydXB0KFwicmV0dXJuXCIsIHJhdyA/IHtcbiAgICAgICAgICAgICAgICAgIGpzb246IG1zZyxcbiAgICAgICAgICAgICAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgICAgICAgICAgICAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7fVxuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gOiBtc2cpO1xuXG4gICAgICAgICAgICAgIGNhc2UgNjpcbiAgICAgICAgICAgICAgICBfY29udGV4dDkubmV4dCA9IDg7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuaHR0cC5yZXF1ZXN0KHRoaXMucmVtb3RlICsgcmVxdWVzdC5wYXRoLCAoMCwgX3V0aWxzLmNsZWFuVW5kZWZpbmVkUHJvcGVydGllcykoe1xuICAgICAgICAgICAgICAgICAgLy8gTGltaXQgcmVxdWVzdHMgdG8gb25seSB0aG9zZSBwYXJ0cyB0aGF0IHdvdWxkIGJlIGFsbG93ZWQgaW5cbiAgICAgICAgICAgICAgICAgIC8vIGEgYmF0Y2ggcmVxdWVzdCAtLSBkb24ndCBwYXNzIHRocm91Z2ggb3RoZXIgZmFuY3kgZmV0Y2goKVxuICAgICAgICAgICAgICAgICAgLy8gb3B0aW9ucyBsaWtlIGludGVncml0eSwgcmVkaXJlY3QsIG1vZGUgYmVjYXVzZSB0aGV5IHdpbGxcbiAgICAgICAgICAgICAgICAgIC8vIGJyZWFrIG9uIGEgYmF0Y2ggcmVxdWVzdC4gIEEgYmF0Y2ggcmVxdWVzdCBvbmx5IGFsbG93c1xuICAgICAgICAgICAgICAgICAgLy8gaGVhZGVycywgbWV0aG9kLCBwYXRoIChhYm92ZSksIGFuZCBib2R5LlxuICAgICAgICAgICAgICAgICAgbWV0aG9kOiByZXF1ZXN0Lm1ldGhvZCxcbiAgICAgICAgICAgICAgICAgIGhlYWRlcnM6IHJlcXVlc3QuaGVhZGVycyxcbiAgICAgICAgICAgICAgICAgIGJvZHk6IHN0cmluZ2lmeSA/IEpTT04uc3RyaW5naWZ5KHJlcXVlc3QuYm9keSkgOiByZXF1ZXN0LmJvZHlcbiAgICAgICAgICAgICAgICB9KSwge1xuICAgICAgICAgICAgICAgICAgcmV0cnk6IHRoaXMuX2dldFJldHJ5KG9wdGlvbnMpXG4gICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgY2FzZSA4OlxuICAgICAgICAgICAgICAgIHJlc3VsdCA9IF9jb250ZXh0OS5zZW50O1xuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDkuYWJydXB0KFwicmV0dXJuXCIsIHJhdyA/IHJlc3VsdCA6IHJlc3VsdC5qc29uKTtcblxuICAgICAgICAgICAgICBjYXNlIDEwOlxuICAgICAgICAgICAgICBjYXNlIFwiZW5kXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0OS5zdG9wKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9LCBfY2FsbGVlOSwgdGhpcyk7XG4gICAgICB9KSk7XG5cbiAgICAgIHJldHVybiBmdW5jdGlvbiBleGVjdXRlKF94NCkge1xuICAgICAgICByZXR1cm4gX2V4ZWN1dGUuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgIH07XG4gICAgfSgpXG4gICAgLyoqXG4gICAgICogRmV0Y2ggc29tZSBwYWdlcyBmcm9tIGEgcGFnaW5hdGVkIGxpc3QsIGZvbGxvd2luZyB0aGUgYG5leHQtcGFnZWBcbiAgICAgKiBoZWFkZXIgYXV0b21hdGljYWxseSB1bnRpbCB3ZSBoYXZlIGZldGNoZWQgdGhlIHJlcXVlc3RlZCBudW1iZXJcbiAgICAgKiBvZiBwYWdlcy4gUmV0dXJuIGEgcmVzcG9uc2Ugd2l0aCBhIGAubmV4dCgpYCBtZXRob2QgdGhhdCBjYW4gYmVcbiAgICAgKiBjYWxsZWQgdG8gZmV0Y2ggbW9yZSByZXN1bHRzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0gIHtTdHJpbmd9ICBwYXRoXG4gICAgICogICAgIFRoZSBwYXRoIHRvIG1ha2UgdGhlIHJlcXVlc3QgdG8uXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSAgcGFyYW1zXG4gICAgICogICAgIFRoZSBwYXJhbWV0ZXJzIHRvIHVzZSB3aGVuIG1ha2luZyB0aGUgcmVxdWVzdC5cbiAgICAgKiBAcGFyYW0gIHtTdHJpbmd9ICBbcGFyYW1zLnNvcnQ9XCItbGFzdF9tb2RpZmllZFwiXVxuICAgICAqICAgICBUaGUgc29ydGluZyBvcmRlciB0byB1c2Ugd2hlbiBmZXRjaGluZy5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICBbcGFyYW1zLmZpbHRlcnM9e31dXG4gICAgICogICAgIFRoZSBmaWx0ZXJzIHRvIHNlbmQgaW4gdGhlIHJlcXVlc3QuXG4gICAgICogQHBhcmFtICB7TnVtYmVyfSAgW3BhcmFtcy5saW1pdD11bmRlZmluZWRdXG4gICAgICogICAgIFRoZSBsaW1pdCB0byBzZW5kIGluIHRoZSByZXF1ZXN0LiBVbmRlZmluZWQgbWVhbnMgbm8gbGltaXQuXG4gICAgICogQHBhcmFtICB7TnVtYmVyfSAgW3BhcmFtcy5wYWdlcz11bmRlZmluZWRdXG4gICAgICogICAgIFRoZSBudW1iZXIgb2YgcGFnZXMgdG8gZmV0Y2guIFVuZGVmaW5lZCBtZWFucyBvbmUgcGFnZS4gUGFzc1xuICAgICAqICAgICBJbmZpbml0eSB0byBmZXRjaCBldmVyeXRoaW5nLlxuICAgICAqIEBwYXJhbSAge1N0cmluZ30gIFtwYXJhbXMuc2luY2U9dW5kZWZpbmVkXVxuICAgICAqICAgICBUaGUgRVRhZyBmcm9tIHdoaWNoIHRvIHN0YXJ0IGZldGNoaW5nLlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gIFtvcHRpb25zPXt9XVxuICAgICAqICAgICBBZGRpdGlvbmFsIHJlcXVlc3QtbGV2ZWwgcGFyYW1ldGVycyB0byB1c2UgaW4gYWxsIHJlcXVlc3RzLlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gIFtvcHRpb25zLmhlYWRlcnM9e31dXG4gICAgICogICAgIEhlYWRlcnMgdG8gdXNlIGR1cmluZyBhbGwgcmVxdWVzdHMuXG4gICAgICogQHBhcmFtICB7TnVtYmVyfSAgW29wdGlvbnMucmV0cnk9MF1cbiAgICAgKiAgICAgTnVtYmVyIG9mIHRpbWVzIHRvIHJldHJ5IGVhY2ggcmVxdWVzdCBpZiB0aGUgc2VydmVyIHJlc3BvbmRzXG4gICAgICogICAgIHdpdGggUmV0cnktQWZ0ZXIuXG4gICAgICovXG5cbiAgfSwge1xuICAgIGtleTogXCJwYWdpbmF0ZWRMaXN0XCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciBfcGFnaW5hdGVkTGlzdCA9ICgwLCBfYXN5bmNUb0dlbmVyYXRvcjIuZGVmYXVsdCkoXG4gICAgICAvKiNfX1BVUkVfXyovXG4gICAgICBfcmVnZW5lcmF0b3IuZGVmYXVsdC5tYXJrKGZ1bmN0aW9uIF9jYWxsZWUxMyhwYXRoLCBwYXJhbXMpIHtcbiAgICAgICAgdmFyIF90aGlzMyA9IHRoaXM7XG5cbiAgICAgICAgdmFyIG9wdGlvbnMsXG4gICAgICAgICAgICBfc29ydCRwYXJhbXMsXG4gICAgICAgICAgICBzb3J0LFxuICAgICAgICAgICAgZmlsdGVycyxcbiAgICAgICAgICAgIGxpbWl0LFxuICAgICAgICAgICAgcGFnZXMsXG4gICAgICAgICAgICBzaW5jZSxcbiAgICAgICAgICAgIHF1ZXJ5c3RyaW5nLFxuICAgICAgICAgICAgcmVzdWx0cyxcbiAgICAgICAgICAgIGN1cnJlbnQsXG4gICAgICAgICAgICBuZXh0LFxuICAgICAgICAgICAgcHJvY2Vzc05leHRQYWdlLFxuICAgICAgICAgICAgcGFnZVJlc3VsdHMsXG4gICAgICAgICAgICBoYW5kbGVSZXNwb25zZSxcbiAgICAgICAgICAgIF9hcmdzMTMgPSBhcmd1bWVudHM7XG5cbiAgICAgICAgcmV0dXJuIF9yZWdlbmVyYXRvci5kZWZhdWx0LndyYXAoZnVuY3Rpb24gX2NhbGxlZTEzJChfY29udGV4dDEzKSB7XG4gICAgICAgICAgd2hpbGUgKDEpIHtcbiAgICAgICAgICAgIHN3aXRjaCAoX2NvbnRleHQxMy5wcmV2ID0gX2NvbnRleHQxMy5uZXh0KSB7XG4gICAgICAgICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgICAgICBvcHRpb25zID0gX2FyZ3MxMy5sZW5ndGggPiAyICYmIF9hcmdzMTNbMl0gIT09IHVuZGVmaW5lZCA/IF9hcmdzMTNbMl0gOiB7fTtcbiAgICAgICAgICAgICAgICAvLyBGSVhNRTogdGhpcyBpcyBjYWxsZWQgZXZlbiBpbiBiYXRjaCByZXF1ZXN0cywgd2hpY2ggZG9lc24ndFxuICAgICAgICAgICAgICAgIC8vIG1ha2UgYW55IHNlbnNlIChzaW5jZSBhbGwgYmF0Y2ggcmVxdWVzdHMgZ2V0IGEgXCJkdW1teVwiXG4gICAgICAgICAgICAgICAgLy8gcmVzcG9uc2U7IHNlZSBleGVjdXRlKCkgYWJvdmUpLlxuICAgICAgICAgICAgICAgIF9zb3J0JHBhcmFtcyA9ICgwLCBfb2JqZWN0U3ByZWFkMi5kZWZhdWx0KSh7XG4gICAgICAgICAgICAgICAgICBzb3J0OiBcIi1sYXN0X21vZGlmaWVkXCJcbiAgICAgICAgICAgICAgICB9LCBwYXJhbXMpLCBzb3J0ID0gX3NvcnQkcGFyYW1zLnNvcnQsIGZpbHRlcnMgPSBfc29ydCRwYXJhbXMuZmlsdGVycywgbGltaXQgPSBfc29ydCRwYXJhbXMubGltaXQsIHBhZ2VzID0gX3NvcnQkcGFyYW1zLnBhZ2VzLCBzaW5jZSA9IF9zb3J0JHBhcmFtcy5zaW5jZTsgLy8gU2FmZXR5L0NvbnNpc3RlbmN5IGNoZWNrIG9uIEVUYWcgdmFsdWUuXG5cbiAgICAgICAgICAgICAgICBpZiAoIShzaW5jZSAmJiB0eXBlb2Ygc2luY2UgIT09IFwic3RyaW5nXCIpKSB7XG4gICAgICAgICAgICAgICAgICBfY29udGV4dDEzLm5leHQgPSA0O1xuICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiSW52YWxpZCB2YWx1ZSBmb3Igc2luY2UgKFwiLmNvbmNhdChzaW5jZSwgXCIpLCBzaG91bGQgYmUgRVRhZyB2YWx1ZS5cIikpO1xuXG4gICAgICAgICAgICAgIGNhc2UgNDpcbiAgICAgICAgICAgICAgICBxdWVyeXN0cmluZyA9ICgwLCBfdXRpbHMucXNpZnkpKCgwLCBfb2JqZWN0U3ByZWFkMi5kZWZhdWx0KSh7fSwgZmlsdGVycywge1xuICAgICAgICAgICAgICAgICAgX3NvcnQ6IHNvcnQsXG4gICAgICAgICAgICAgICAgICBfbGltaXQ6IGxpbWl0LFxuICAgICAgICAgICAgICAgICAgX3NpbmNlOiBzaW5jZVxuICAgICAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgICAgICByZXN1bHRzID0gW10sIGN1cnJlbnQgPSAwO1xuXG4gICAgICAgICAgICAgICAgbmV4dCA9XG4gICAgICAgICAgICAgICAgLyojX19QVVJFX18qL1xuICAgICAgICAgICAgICAgIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgIHZhciBfcmVmNyA9ICgwLCBfYXN5bmNUb0dlbmVyYXRvcjIuZGVmYXVsdCkoXG4gICAgICAgICAgICAgICAgICAvKiNfX1BVUkVfXyovXG4gICAgICAgICAgICAgICAgICBfcmVnZW5lcmF0b3IuZGVmYXVsdC5tYXJrKGZ1bmN0aW9uIF9jYWxsZWUxMChuZXh0UGFnZSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gX3JlZ2VuZXJhdG9yLmRlZmF1bHQud3JhcChmdW5jdGlvbiBfY2FsbGVlMTAkKF9jb250ZXh0MTApIHtcbiAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAoMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3dpdGNoIChfY29udGV4dDEwLnByZXYgPSBfY29udGV4dDEwLm5leHQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAwOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChuZXh0UGFnZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX2NvbnRleHQxMC5uZXh0ID0gMjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIlBhZ2luYXRpb24gZXhoYXVzdGVkLlwiKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDI6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0MTAuYWJydXB0KFwicmV0dXJuXCIsIHByb2Nlc3NOZXh0UGFnZShuZXh0UGFnZSkpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMzpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBcImVuZFwiOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDEwLnN0b3AoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0sIF9jYWxsZWUxMCwgdGhpcyk7XG4gICAgICAgICAgICAgICAgICB9KSk7XG5cbiAgICAgICAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbiBuZXh0KF94Nykge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gX3JlZjcuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgfSgpO1xuXG4gICAgICAgICAgICAgICAgcHJvY2Vzc05leHRQYWdlID1cbiAgICAgICAgICAgICAgICAvKiNfX1BVUkVfXyovXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgdmFyIF9yZWY4ID0gKDAsIF9hc3luY1RvR2VuZXJhdG9yMi5kZWZhdWx0KShcbiAgICAgICAgICAgICAgICAgIC8qI19fUFVSRV9fKi9cbiAgICAgICAgICAgICAgICAgIF9yZWdlbmVyYXRvci5kZWZhdWx0Lm1hcmsoZnVuY3Rpb24gX2NhbGxlZTExKG5leHRQYWdlKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBoZWFkZXJzO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gX3JlZ2VuZXJhdG9yLmRlZmF1bHQud3JhcChmdW5jdGlvbiBfY2FsbGVlMTEkKF9jb250ZXh0MTEpIHtcbiAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAoMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3dpdGNoIChfY29udGV4dDExLnByZXYgPSBfY29udGV4dDExLm5leHQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAwOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhlYWRlcnMgPSBvcHRpb25zLmhlYWRlcnM7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX2NvbnRleHQxMS50MCA9IGhhbmRsZVJlc3BvbnNlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9jb250ZXh0MTEubmV4dCA9IDQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIF90aGlzMy5odHRwLnJlcXVlc3QobmV4dFBhZ2UsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhlYWRlcnM6IGhlYWRlcnNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDQ6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX2NvbnRleHQxMS50MSA9IF9jb250ZXh0MTEuc2VudDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQxMS5hYnJ1cHQoXCJyZXR1cm5cIiwgKDAsIF9jb250ZXh0MTEudDApKF9jb250ZXh0MTEudDEpKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDY6XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgXCJlbmRcIjpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQxMS5zdG9wKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9LCBfY2FsbGVlMTEsIHRoaXMpO1xuICAgICAgICAgICAgICAgICAgfSkpO1xuXG4gICAgICAgICAgICAgICAgICByZXR1cm4gZnVuY3Rpb24gcHJvY2Vzc05leHRQYWdlKF94OCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gX3JlZjguYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgfSgpO1xuXG4gICAgICAgICAgICAgICAgcGFnZVJlc3VsdHMgPSBmdW5jdGlvbiBwYWdlUmVzdWx0cyhyZXN1bHRzLCBuZXh0UGFnZSwgZXRhZywgdG90YWxSZWNvcmRzKSB7XG4gICAgICAgICAgICAgICAgICAvLyBFVGFnIHN0cmluZyBpcyBzdXBwb3NlZCB0byBiZSBvcGFxdWUgYW5kIHN0b3JlZCDCq2FzLWlzwrsuXG4gICAgICAgICAgICAgICAgICAvLyBFVGFnIGhlYWRlciB2YWx1ZXMgYXJlIHF1b3RlZCAoYmVjYXVzZSBvZiAqIGFuZCBXL1wiZm9vXCIpLlxuICAgICAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAgICAgbGFzdF9tb2RpZmllZDogZXRhZyA/IGV0YWcucmVwbGFjZSgvXCIvZywgXCJcIikgOiBldGFnLFxuICAgICAgICAgICAgICAgICAgICBkYXRhOiByZXN1bHRzLFxuICAgICAgICAgICAgICAgICAgICBuZXh0OiBuZXh0LmJpbmQobnVsbCwgbmV4dFBhZ2UpLFxuICAgICAgICAgICAgICAgICAgICBoYXNOZXh0UGFnZTogISFuZXh0UGFnZSxcbiAgICAgICAgICAgICAgICAgICAgdG90YWxSZWNvcmRzOiB0b3RhbFJlY29yZHNcbiAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgICAgIGhhbmRsZVJlc3BvbnNlID1cbiAgICAgICAgICAgICAgICAvKiNfX1BVUkVfXyovXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgdmFyIF9yZWY5ID0gKDAsIF9hc3luY1RvR2VuZXJhdG9yMi5kZWZhdWx0KShcbiAgICAgICAgICAgICAgICAgIC8qI19fUFVSRV9fKi9cbiAgICAgICAgICAgICAgICAgIF9yZWdlbmVyYXRvci5kZWZhdWx0Lm1hcmsoZnVuY3Rpb24gX2NhbGxlZTEyKF9yZWYxMCkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgaGVhZGVycywganNvbiwgbmV4dFBhZ2UsIGV0YWcsIHRvdGFsUmVjb3JkcztcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIF9yZWdlbmVyYXRvci5kZWZhdWx0LndyYXAoZnVuY3Rpb24gX2NhbGxlZTEyJChfY29udGV4dDEyKSB7XG4gICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN3aXRjaCAoX2NvbnRleHQxMi5wcmV2ID0gX2NvbnRleHQxMi5uZXh0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBoZWFkZXJzID0gX3JlZjEwLmhlYWRlcnMsIGpzb24gPSBfcmVmMTAuanNvbjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXh0UGFnZSA9IGhlYWRlcnMuZ2V0KFwiTmV4dC1QYWdlXCIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV0YWcgPSBoZWFkZXJzLmdldChcIkVUYWdcIik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxSZWNvcmRzID0gcGFyc2VJbnQoaGVhZGVycy5nZXQoXCJUb3RhbC1SZWNvcmRzXCIpLCAxMCk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocGFnZXMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9jb250ZXh0MTIubmV4dCA9IDY7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQxMi5hYnJ1cHQoXCJyZXR1cm5cIiwgcGFnZVJlc3VsdHMoanNvbi5kYXRhLCBuZXh0UGFnZSwgZXRhZywgdG90YWxSZWNvcmRzKSk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSA2OlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEFnZ3JlZ2F0ZSBuZXcgcmVzdWx0cyB3aXRoIHByZXZpb3VzIG9uZXNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHRzID0gcmVzdWx0cy5jb25jYXQoanNvbi5kYXRhKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50ICs9IDE7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIShjdXJyZW50ID49IHBhZ2VzIHx8ICFuZXh0UGFnZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9jb250ZXh0MTIubmV4dCA9IDEwO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0MTIuYWJydXB0KFwicmV0dXJuXCIsIHBhZ2VSZXN1bHRzKHJlc3VsdHMsIG5leHRQYWdlLCBldGFnLCB0b3RhbFJlY29yZHMpKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDEwOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDEyLmFicnVwdChcInJldHVyblwiLCBwcm9jZXNzTmV4dFBhZ2UobmV4dFBhZ2UpKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDExOlxuICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIFwiZW5kXCI6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0MTIuc3RvcCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSwgX2NhbGxlZTEyLCB0aGlzKTtcbiAgICAgICAgICAgICAgICAgIH0pKTtcblxuICAgICAgICAgICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uIGhhbmRsZVJlc3BvbnNlKF94OSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gX3JlZjkuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgfSgpO1xuXG4gICAgICAgICAgICAgICAgX2NvbnRleHQxMy50MCA9IGhhbmRsZVJlc3BvbnNlO1xuICAgICAgICAgICAgICAgIF9jb250ZXh0MTMubmV4dCA9IDEzO1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmV4ZWN1dGUoIC8vIE4uQi46IFRoaXMgZG9lc24ndCB1c2UgX2dldEhlYWRlcnMsIGJlY2F1c2UgYWxsIGNhbGxzIHRvXG4gICAgICAgICAgICAgICAgLy8gYHBhZ2luYXRlZExpc3RgIGFyZSBhc3N1bWVkIHRvIGNvbWUgZnJvbSBjYWxscyB0aGF0IGFscmVhZHlcbiAgICAgICAgICAgICAgICAvLyBoYXZlIGhlYWRlcnMgbWVyZ2VkIGF0IGUuZy4gdGhlIGJ1Y2tldCBvciBjb2xsZWN0aW9uIGxldmVsLlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgIGhlYWRlcnM6IG9wdGlvbnMuaGVhZGVycyxcbiAgICAgICAgICAgICAgICAgIHBhdGg6IHBhdGggKyBcIj9cIiArIHF1ZXJ5c3RyaW5nXG4gICAgICAgICAgICAgICAgfSwgLy8gTi5CLiBUaGlzIGRvZXNuJ3QgdXNlIF9nZXRSZXRyeSwgYmVjYXVzZSBhbGwgY2FsbHMgdG9cbiAgICAgICAgICAgICAgICAvLyBgcGFnaW5hdGVkTGlzdGAgYXJlIGFzc3VtZWQgdG8gY29tZSBmcm9tIGNhbGxzIHRoYXQgYWxyZWFkeVxuICAgICAgICAgICAgICAgIC8vIHVzZWQgYF9nZXRSZXRyeWAgYXQgZS5nLiB0aGUgYnVja2V0IG9yIGNvbGxlY3Rpb24gbGV2ZWwuXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgcmF3OiB0cnVlLFxuICAgICAgICAgICAgICAgICAgcmV0cnk6IG9wdGlvbnMucmV0cnkgfHwgMFxuICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgIGNhc2UgMTM6XG4gICAgICAgICAgICAgICAgX2NvbnRleHQxMy50MSA9IF9jb250ZXh0MTMuc2VudDtcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQxMy5hYnJ1cHQoXCJyZXR1cm5cIiwgKDAsIF9jb250ZXh0MTMudDApKF9jb250ZXh0MTMudDEpKTtcblxuICAgICAgICAgICAgICBjYXNlIDE1OlxuICAgICAgICAgICAgICBjYXNlIFwiZW5kXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0MTMuc3RvcCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSwgX2NhbGxlZTEzLCB0aGlzKTtcbiAgICAgIH0pKTtcblxuICAgICAgcmV0dXJuIGZ1bmN0aW9uIHBhZ2luYXRlZExpc3QoX3g1LCBfeDYpIHtcbiAgICAgICAgcmV0dXJuIF9wYWdpbmF0ZWRMaXN0LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICB9O1xuICAgIH0oKVxuICAgIC8qKlxuICAgICAqIExpc3RzIGFsbCBwZXJtaXNzaW9ucy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gW29wdGlvbnM9e31dICAgICAgVGhlIG9wdGlvbnMgb2JqZWN0LlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gW29wdGlvbnMuaGVhZGVycz17fV0gSGVhZGVycyB0byB1c2Ugd2hlbiBtYWtpbmdcbiAgICAgKiAgICAgdGhpcyByZXF1ZXN0LlxuICAgICAqIEBwYXJhbSAge051bWJlcn0gW29wdGlvbnMucmV0cnk9MF0gICAgTnVtYmVyIG9mIHJldHJpZXMgdG8gbWFrZVxuICAgICAqICAgICB3aGVuIGZhY2VkIHdpdGggdHJhbnNpZW50IGVycm9ycy5cbiAgICAgKiBAcmV0dXJuIHtQcm9taXNlPE9iamVjdFtdLCBFcnJvcj59XG4gICAgICovXG5cbiAgfSwge1xuICAgIGtleTogXCJsaXN0UGVybWlzc2lvbnNcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gKCkge1xuICAgICAgdmFyIF9saXN0UGVybWlzc2lvbnMgPSAoMCwgX2FzeW5jVG9HZW5lcmF0b3IyLmRlZmF1bHQpKFxuICAgICAgLyojX19QVVJFX18qL1xuICAgICAgX3JlZ2VuZXJhdG9yLmRlZmF1bHQubWFyayhmdW5jdGlvbiBfY2FsbGVlMTQoKSB7XG4gICAgICAgIHZhciBvcHRpb25zLFxuICAgICAgICAgICAgcGF0aCxcbiAgICAgICAgICAgIHBhZ2luYXRpb25PcHRpb25zLFxuICAgICAgICAgICAgX2FyZ3MxNCA9IGFyZ3VtZW50cztcbiAgICAgICAgcmV0dXJuIF9yZWdlbmVyYXRvci5kZWZhdWx0LndyYXAoZnVuY3Rpb24gX2NhbGxlZTE0JChfY29udGV4dDE0KSB7XG4gICAgICAgICAgd2hpbGUgKDEpIHtcbiAgICAgICAgICAgIHN3aXRjaCAoX2NvbnRleHQxNC5wcmV2ID0gX2NvbnRleHQxNC5uZXh0KSB7XG4gICAgICAgICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgICAgICBvcHRpb25zID0gX2FyZ3MxNC5sZW5ndGggPiAwICYmIF9hcmdzMTRbMF0gIT09IHVuZGVmaW5lZCA/IF9hcmdzMTRbMF0gOiB7fTtcbiAgICAgICAgICAgICAgICBwYXRoID0gKDAsIF9lbmRwb2ludC5kZWZhdWx0KShcInBlcm1pc3Npb25zXCIpOyAvLyBFbnN1cmUgdGhlIGRlZmF1bHQgc29ydCBwYXJhbWV0ZXIgaXMgc29tZXRoaW5nIHRoYXQgZXhpc3RzIGluIHBlcm1pc3Npb25zXG4gICAgICAgICAgICAgICAgLy8gZW50cmllcywgYXMgYGxhc3RfbW9kaWZpZWRgIGRvZXNuJ3Q7IGhlcmUsIHdlIHBpY2sgXCJpZFwiLlxuXG4gICAgICAgICAgICAgICAgcGFnaW5hdGlvbk9wdGlvbnMgPSAoMCwgX29iamVjdFNwcmVhZDIuZGVmYXVsdCkoe1xuICAgICAgICAgICAgICAgICAgc29ydDogXCJpZFwiXG4gICAgICAgICAgICAgICAgfSwgb3B0aW9ucyk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0MTQuYWJydXB0KFwicmV0dXJuXCIsIHRoaXMucGFnaW5hdGVkTGlzdChwYXRoLCBwYWdpbmF0aW9uT3B0aW9ucywge1xuICAgICAgICAgICAgICAgICAgaGVhZGVyczogdGhpcy5fZ2V0SGVhZGVycyhvcHRpb25zKSxcbiAgICAgICAgICAgICAgICAgIHJldHJ5OiB0aGlzLl9nZXRSZXRyeShvcHRpb25zKVxuICAgICAgICAgICAgICAgIH0pKTtcblxuICAgICAgICAgICAgICBjYXNlIDQ6XG4gICAgICAgICAgICAgIGNhc2UgXCJlbmRcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQxNC5zdG9wKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9LCBfY2FsbGVlMTQsIHRoaXMpO1xuICAgICAgfSkpO1xuXG4gICAgICByZXR1cm4gZnVuY3Rpb24gbGlzdFBlcm1pc3Npb25zKCkge1xuICAgICAgICByZXR1cm4gX2xpc3RQZXJtaXNzaW9ucy5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgfTtcbiAgICB9KClcbiAgICAvKipcbiAgICAgKiBSZXRyaWV2ZXMgdGhlIGxpc3Qgb2YgYnVja2V0cy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gW29wdGlvbnM9e31dICAgICAgVGhlIG9wdGlvbnMgb2JqZWN0LlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gW29wdGlvbnMuaGVhZGVycz17fV0gSGVhZGVycyB0byB1c2Ugd2hlbiBtYWtpbmdcbiAgICAgKiAgICAgdGhpcyByZXF1ZXN0LlxuICAgICAqIEBwYXJhbSAge051bWJlcn0gW29wdGlvbnMucmV0cnk9MF0gICAgTnVtYmVyIG9mIHJldHJpZXMgdG8gbWFrZVxuICAgICAqICAgICB3aGVuIGZhY2VkIHdpdGggdHJhbnNpZW50IGVycm9ycy5cbiAgICAgKiBAcmV0dXJuIHtQcm9taXNlPE9iamVjdFtdLCBFcnJvcj59XG4gICAgICovXG5cbiAgfSwge1xuICAgIGtleTogXCJsaXN0QnVja2V0c1wiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgX2xpc3RCdWNrZXRzID0gKDAsIF9hc3luY1RvR2VuZXJhdG9yMi5kZWZhdWx0KShcbiAgICAgIC8qI19fUFVSRV9fKi9cbiAgICAgIF9yZWdlbmVyYXRvci5kZWZhdWx0Lm1hcmsoZnVuY3Rpb24gX2NhbGxlZTE1KCkge1xuICAgICAgICB2YXIgb3B0aW9ucyxcbiAgICAgICAgICAgIHBhdGgsXG4gICAgICAgICAgICBfYXJnczE1ID0gYXJndW1lbnRzO1xuICAgICAgICByZXR1cm4gX3JlZ2VuZXJhdG9yLmRlZmF1bHQud3JhcChmdW5jdGlvbiBfY2FsbGVlMTUkKF9jb250ZXh0MTUpIHtcbiAgICAgICAgICB3aGlsZSAoMSkge1xuICAgICAgICAgICAgc3dpdGNoIChfY29udGV4dDE1LnByZXYgPSBfY29udGV4dDE1Lm5leHQpIHtcbiAgICAgICAgICAgICAgY2FzZSAwOlxuICAgICAgICAgICAgICAgIG9wdGlvbnMgPSBfYXJnczE1Lmxlbmd0aCA+IDAgJiYgX2FyZ3MxNVswXSAhPT0gdW5kZWZpbmVkID8gX2FyZ3MxNVswXSA6IHt9O1xuICAgICAgICAgICAgICAgIHBhdGggPSAoMCwgX2VuZHBvaW50LmRlZmF1bHQpKFwiYnVja2V0XCIpO1xuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDE1LmFicnVwdChcInJldHVyblwiLCB0aGlzLnBhZ2luYXRlZExpc3QocGF0aCwgb3B0aW9ucywge1xuICAgICAgICAgICAgICAgICAgaGVhZGVyczogdGhpcy5fZ2V0SGVhZGVycyhvcHRpb25zKSxcbiAgICAgICAgICAgICAgICAgIHJldHJ5OiB0aGlzLl9nZXRSZXRyeShvcHRpb25zKVxuICAgICAgICAgICAgICAgIH0pKTtcblxuICAgICAgICAgICAgICBjYXNlIDM6XG4gICAgICAgICAgICAgIGNhc2UgXCJlbmRcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQxNS5zdG9wKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9LCBfY2FsbGVlMTUsIHRoaXMpO1xuICAgICAgfSkpO1xuXG4gICAgICByZXR1cm4gZnVuY3Rpb24gbGlzdEJ1Y2tldHMoKSB7XG4gICAgICAgIHJldHVybiBfbGlzdEJ1Y2tldHMuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgIH07XG4gICAgfSgpXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIG5ldyBidWNrZXQgb24gdGhlIHNlcnZlci5cbiAgICAgKlxuICAgICAqIEBwYXJhbSAge1N0cmluZ3xudWxsfSAgaWQgICAgICAgICAgICAgICAgVGhlIGJ1Y2tldCBuYW1lIChvcHRpb25hbCkuXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSAgICAgICBbb3B0aW9ucz17fV0gICAgICBUaGUgb3B0aW9ucyBvYmplY3QuXG4gICAgICogQHBhcmFtICB7Qm9vbGVhbn0gICAgICBbb3B0aW9ucy5kYXRhXSAgICBUaGUgYnVja2V0IGRhdGEgb3B0aW9uLlxuICAgICAqIEBwYXJhbSAge0Jvb2xlYW59ICAgICAgW29wdGlvbnMuc2FmZV0gICAgVGhlIHNhZmUgb3B0aW9uLlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gICAgICAgW29wdGlvbnMuaGVhZGVyc10gVGhlIGhlYWRlcnMgb2JqZWN0IG9wdGlvbi5cbiAgICAgKiBAcGFyYW0gIHtOdW1iZXJ9ICAgICAgIFtvcHRpb25zLnJldHJ5PTBdIE51bWJlciBvZiByZXRyaWVzIHRvIG1ha2VcbiAgICAgKiAgICAgd2hlbiBmYWNlZCB3aXRoIHRyYW5zaWVudCBlcnJvcnMuXG4gICAgICogQHJldHVybiB7UHJvbWlzZTxPYmplY3QsIEVycm9yPn1cbiAgICAgKi9cblxuICB9LCB7XG4gICAga2V5OiBcImNyZWF0ZUJ1Y2tldFwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgX2NyZWF0ZUJ1Y2tldCA9ICgwLCBfYXN5bmNUb0dlbmVyYXRvcjIuZGVmYXVsdCkoXG4gICAgICAvKiNfX1BVUkVfXyovXG4gICAgICBfcmVnZW5lcmF0b3IuZGVmYXVsdC5tYXJrKGZ1bmN0aW9uIF9jYWxsZWUxNihpZCkge1xuICAgICAgICB2YXIgb3B0aW9ucyxcbiAgICAgICAgICAgIF9vcHRpb25zJGRhdGEsXG4gICAgICAgICAgICBkYXRhLFxuICAgICAgICAgICAgcGVybWlzc2lvbnMsXG4gICAgICAgICAgICBwYXRoLFxuICAgICAgICAgICAgX2FyZ3MxNiA9IGFyZ3VtZW50cztcblxuICAgICAgICByZXR1cm4gX3JlZ2VuZXJhdG9yLmRlZmF1bHQud3JhcChmdW5jdGlvbiBfY2FsbGVlMTYkKF9jb250ZXh0MTYpIHtcbiAgICAgICAgICB3aGlsZSAoMSkge1xuICAgICAgICAgICAgc3dpdGNoIChfY29udGV4dDE2LnByZXYgPSBfY29udGV4dDE2Lm5leHQpIHtcbiAgICAgICAgICAgICAgY2FzZSAwOlxuICAgICAgICAgICAgICAgIG9wdGlvbnMgPSBfYXJnczE2Lmxlbmd0aCA+IDEgJiYgX2FyZ3MxNlsxXSAhPT0gdW5kZWZpbmVkID8gX2FyZ3MxNlsxXSA6IHt9O1xuICAgICAgICAgICAgICAgIF9vcHRpb25zJGRhdGEgPSBvcHRpb25zLmRhdGEsIGRhdGEgPSBfb3B0aW9ucyRkYXRhID09PSB2b2lkIDAgPyB7fSA6IF9vcHRpb25zJGRhdGEsIHBlcm1pc3Npb25zID0gb3B0aW9ucy5wZXJtaXNzaW9ucztcblxuICAgICAgICAgICAgICAgIGlmIChpZCAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICBkYXRhLmlkID0gaWQ7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgcGF0aCA9IGRhdGEuaWQgPyAoMCwgX2VuZHBvaW50LmRlZmF1bHQpKFwiYnVja2V0XCIsIGRhdGEuaWQpIDogKDAsIF9lbmRwb2ludC5kZWZhdWx0KShcImJ1Y2tldFwiKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQxNi5hYnJ1cHQoXCJyZXR1cm5cIiwgdGhpcy5leGVjdXRlKHJlcXVlc3RzLmNyZWF0ZVJlcXVlc3QocGF0aCwge1xuICAgICAgICAgICAgICAgICAgZGF0YTogZGF0YSxcbiAgICAgICAgICAgICAgICAgIHBlcm1pc3Npb25zOiBwZXJtaXNzaW9uc1xuICAgICAgICAgICAgICAgIH0sIHtcbiAgICAgICAgICAgICAgICAgIGhlYWRlcnM6IHRoaXMuX2dldEhlYWRlcnMob3B0aW9ucyksXG4gICAgICAgICAgICAgICAgICBzYWZlOiB0aGlzLl9nZXRTYWZlKG9wdGlvbnMpXG4gICAgICAgICAgICAgICAgfSksIHtcbiAgICAgICAgICAgICAgICAgIHJldHJ5OiB0aGlzLl9nZXRSZXRyeShvcHRpb25zKVxuICAgICAgICAgICAgICAgIH0pKTtcblxuICAgICAgICAgICAgICBjYXNlIDU6XG4gICAgICAgICAgICAgIGNhc2UgXCJlbmRcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQxNi5zdG9wKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9LCBfY2FsbGVlMTYsIHRoaXMpO1xuICAgICAgfSkpO1xuXG4gICAgICByZXR1cm4gZnVuY3Rpb24gY3JlYXRlQnVja2V0KF94MTApIHtcbiAgICAgICAgcmV0dXJuIF9jcmVhdGVCdWNrZXQuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgIH07XG4gICAgfSgpXG4gICAgLyoqXG4gICAgICogRGVsZXRlcyBhIGJ1Y2tldCBmcm9tIHRoZSBzZXJ2ZXIuXG4gICAgICpcbiAgICAgKiBAaWdub3JlXG4gICAgICogQHBhcmFtICB7T2JqZWN0fFN0cmluZ30gYnVja2V0ICAgICAgICAgICAgICAgICAgVGhlIGJ1Y2tldCB0byBkZWxldGUuXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSAgICAgICAgW29wdGlvbnM9e31dICAgICAgICAgICAgVGhlIG9wdGlvbnMgb2JqZWN0LlxuICAgICAqIEBwYXJhbSAge0Jvb2xlYW59ICAgICAgIFtvcHRpb25zLnNhZmVdICAgICAgICAgIFRoZSBzYWZlIG9wdGlvbi5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICAgICAgICBbb3B0aW9ucy5oZWFkZXJzXSAgICAgICBUaGUgaGVhZGVycyBvYmplY3Qgb3B0aW9uLlxuICAgICAqIEBwYXJhbSAge051bWJlcn0gICAgICAgIFtvcHRpb25zLnJldHJ5PTBdICAgICAgIE51bWJlciBvZiByZXRyaWVzIHRvIG1ha2VcbiAgICAgKiAgICAgd2hlbiBmYWNlZCB3aXRoIHRyYW5zaWVudCBlcnJvcnMuXG4gICAgICogQHBhcmFtICB7TnVtYmVyfSAgICAgICAgW29wdGlvbnMubGFzdF9tb2RpZmllZF0gVGhlIGxhc3RfbW9kaWZpZWQgb3B0aW9uLlxuICAgICAqIEByZXR1cm4ge1Byb21pc2U8T2JqZWN0LCBFcnJvcj59XG4gICAgICovXG5cbiAgfSwge1xuICAgIGtleTogXCJkZWxldGVCdWNrZXRcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gKCkge1xuICAgICAgdmFyIF9kZWxldGVCdWNrZXQgPSAoMCwgX2FzeW5jVG9HZW5lcmF0b3IyLmRlZmF1bHQpKFxuICAgICAgLyojX19QVVJFX18qL1xuICAgICAgX3JlZ2VuZXJhdG9yLmRlZmF1bHQubWFyayhmdW5jdGlvbiBfY2FsbGVlMTcoYnVja2V0KSB7XG4gICAgICAgIHZhciBvcHRpb25zLFxuICAgICAgICAgICAgYnVja2V0T2JqLFxuICAgICAgICAgICAgcGF0aCxcbiAgICAgICAgICAgIF9idWNrZXRPYmokb3B0aW9ucyxcbiAgICAgICAgICAgIGxhc3RfbW9kaWZpZWQsXG4gICAgICAgICAgICBfYXJnczE3ID0gYXJndW1lbnRzO1xuXG4gICAgICAgIHJldHVybiBfcmVnZW5lcmF0b3IuZGVmYXVsdC53cmFwKGZ1bmN0aW9uIF9jYWxsZWUxNyQoX2NvbnRleHQxNykge1xuICAgICAgICAgIHdoaWxlICgxKSB7XG4gICAgICAgICAgICBzd2l0Y2ggKF9jb250ZXh0MTcucHJldiA9IF9jb250ZXh0MTcubmV4dCkge1xuICAgICAgICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICAgICAgb3B0aW9ucyA9IF9hcmdzMTcubGVuZ3RoID4gMSAmJiBfYXJnczE3WzFdICE9PSB1bmRlZmluZWQgPyBfYXJnczE3WzFdIDoge307XG4gICAgICAgICAgICAgICAgYnVja2V0T2JqID0gKDAsIF91dGlscy50b0RhdGFCb2R5KShidWNrZXQpO1xuXG4gICAgICAgICAgICAgICAgaWYgKGJ1Y2tldE9iai5pZCkge1xuICAgICAgICAgICAgICAgICAgX2NvbnRleHQxNy5uZXh0ID0gNDtcbiAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkEgYnVja2V0IGlkIGlzIHJlcXVpcmVkLlwiKTtcblxuICAgICAgICAgICAgICBjYXNlIDQ6XG4gICAgICAgICAgICAgICAgcGF0aCA9ICgwLCBfZW5kcG9pbnQuZGVmYXVsdCkoXCJidWNrZXRcIiwgYnVja2V0T2JqLmlkKTtcbiAgICAgICAgICAgICAgICBfYnVja2V0T2JqJG9wdGlvbnMgPSAoMCwgX29iamVjdFNwcmVhZDIuZGVmYXVsdCkoe30sIGJ1Y2tldE9iaiwgb3B0aW9ucyksIGxhc3RfbW9kaWZpZWQgPSBfYnVja2V0T2JqJG9wdGlvbnMubGFzdF9tb2RpZmllZDtcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQxNy5hYnJ1cHQoXCJyZXR1cm5cIiwgdGhpcy5leGVjdXRlKHJlcXVlc3RzLmRlbGV0ZVJlcXVlc3QocGF0aCwge1xuICAgICAgICAgICAgICAgICAgbGFzdF9tb2RpZmllZDogbGFzdF9tb2RpZmllZCxcbiAgICAgICAgICAgICAgICAgIGhlYWRlcnM6IHRoaXMuX2dldEhlYWRlcnMob3B0aW9ucyksXG4gICAgICAgICAgICAgICAgICBzYWZlOiB0aGlzLl9nZXRTYWZlKG9wdGlvbnMpXG4gICAgICAgICAgICAgICAgfSksIHtcbiAgICAgICAgICAgICAgICAgIHJldHJ5OiB0aGlzLl9nZXRSZXRyeShvcHRpb25zKVxuICAgICAgICAgICAgICAgIH0pKTtcblxuICAgICAgICAgICAgICBjYXNlIDc6XG4gICAgICAgICAgICAgIGNhc2UgXCJlbmRcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQxNy5zdG9wKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9LCBfY2FsbGVlMTcsIHRoaXMpO1xuICAgICAgfSkpO1xuXG4gICAgICByZXR1cm4gZnVuY3Rpb24gZGVsZXRlQnVja2V0KF94MTEpIHtcbiAgICAgICAgcmV0dXJuIF9kZWxldGVCdWNrZXQuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgIH07XG4gICAgfSgpXG4gICAgLyoqXG4gICAgICogRGVsZXRlcyBhbGwgYnVja2V0cyBvbiB0aGUgc2VydmVyLlxuICAgICAqXG4gICAgICogQGlnbm9yZVxuICAgICAqIEBwYXJhbSAge09iamVjdH0gIFtvcHRpb25zPXt9XSAgICAgICAgICAgIFRoZSBvcHRpb25zIG9iamVjdC5cbiAgICAgKiBAcGFyYW0gIHtCb29sZWFufSBbb3B0aW9ucy5zYWZlXSAgICAgICAgICBUaGUgc2FmZSBvcHRpb24uXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSAgW29wdGlvbnMuaGVhZGVyc10gICAgICAgVGhlIGhlYWRlcnMgb2JqZWN0IG9wdGlvbi5cbiAgICAgKiBAcGFyYW0gIHtOdW1iZXJ9ICBbb3B0aW9ucy5sYXN0X21vZGlmaWVkXSBUaGUgbGFzdF9tb2RpZmllZCBvcHRpb24uXG4gICAgICogQHJldHVybiB7UHJvbWlzZTxPYmplY3QsIEVycm9yPn1cbiAgICAgKi9cblxuICB9LCB7XG4gICAga2V5OiBcImRlbGV0ZUJ1Y2tldHNcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gKCkge1xuICAgICAgdmFyIF9kZWxldGVCdWNrZXRzID0gKDAsIF9hc3luY1RvR2VuZXJhdG9yMi5kZWZhdWx0KShcbiAgICAgIC8qI19fUFVSRV9fKi9cbiAgICAgIF9yZWdlbmVyYXRvci5kZWZhdWx0Lm1hcmsoZnVuY3Rpb24gX2NhbGxlZTE4KCkge1xuICAgICAgICB2YXIgb3B0aW9ucyxcbiAgICAgICAgICAgIHBhdGgsXG4gICAgICAgICAgICBfYXJnczE4ID0gYXJndW1lbnRzO1xuICAgICAgICByZXR1cm4gX3JlZ2VuZXJhdG9yLmRlZmF1bHQud3JhcChmdW5jdGlvbiBfY2FsbGVlMTgkKF9jb250ZXh0MTgpIHtcbiAgICAgICAgICB3aGlsZSAoMSkge1xuICAgICAgICAgICAgc3dpdGNoIChfY29udGV4dDE4LnByZXYgPSBfY29udGV4dDE4Lm5leHQpIHtcbiAgICAgICAgICAgICAgY2FzZSAwOlxuICAgICAgICAgICAgICAgIG9wdGlvbnMgPSBfYXJnczE4Lmxlbmd0aCA+IDAgJiYgX2FyZ3MxOFswXSAhPT0gdW5kZWZpbmVkID8gX2FyZ3MxOFswXSA6IHt9O1xuICAgICAgICAgICAgICAgIHBhdGggPSAoMCwgX2VuZHBvaW50LmRlZmF1bHQpKFwiYnVja2V0XCIpO1xuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDE4LmFicnVwdChcInJldHVyblwiLCB0aGlzLmV4ZWN1dGUocmVxdWVzdHMuZGVsZXRlUmVxdWVzdChwYXRoLCB7XG4gICAgICAgICAgICAgICAgICBsYXN0X21vZGlmaWVkOiBvcHRpb25zLmxhc3RfbW9kaWZpZWQsXG4gICAgICAgICAgICAgICAgICBoZWFkZXJzOiB0aGlzLl9nZXRIZWFkZXJzKG9wdGlvbnMpLFxuICAgICAgICAgICAgICAgICAgc2FmZTogdGhpcy5fZ2V0U2FmZShvcHRpb25zKVxuICAgICAgICAgICAgICAgIH0pLCB7XG4gICAgICAgICAgICAgICAgICByZXRyeTogdGhpcy5fZ2V0UmV0cnkob3B0aW9ucylcbiAgICAgICAgICAgICAgICB9KSk7XG5cbiAgICAgICAgICAgICAgY2FzZSAzOlxuICAgICAgICAgICAgICBjYXNlIFwiZW5kXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0MTguc3RvcCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSwgX2NhbGxlZTE4LCB0aGlzKTtcbiAgICAgIH0pKTtcblxuICAgICAgcmV0dXJuIGZ1bmN0aW9uIGRlbGV0ZUJ1Y2tldHMoKSB7XG4gICAgICAgIHJldHVybiBfZGVsZXRlQnVja2V0cy5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgfTtcbiAgICB9KClcbiAgfSwge1xuICAgIGtleTogXCJyZW1vdGVcIixcbiAgICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHtcbiAgICAgIHJldHVybiB0aGlzLl9yZW1vdGU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEBpZ25vcmVcbiAgICAgKi9cbiAgICAsXG4gICAgc2V0OiBmdW5jdGlvbiBzZXQodXJsKSB7XG4gICAgICB2YXIgdmVyc2lvbjtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgdmVyc2lvbiA9IHVybC5tYXRjaCgvXFwvKHZcXGQrKVxcLz8kLylbMV07XG4gICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVGhlIHJlbW90ZSBVUkwgbXVzdCBjb250YWluIHRoZSB2ZXJzaW9uOiBcIiArIHVybCk7XG4gICAgICB9XG5cbiAgICAgIGlmICh2ZXJzaW9uICE9PSBTVVBQT1JURURfUFJPVE9DT0xfVkVSU0lPTikge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJVbnN1cHBvcnRlZCBwcm90b2NvbCB2ZXJzaW9uOiBcIi5jb25jYXQodmVyc2lvbikpO1xuICAgICAgfVxuXG4gICAgICB0aGlzLl9yZW1vdGUgPSB1cmw7XG4gICAgICB0aGlzLl92ZXJzaW9uID0gdmVyc2lvbjtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGN1cnJlbnQgc2VydmVyIHByb3RvY29sIHZlcnNpb24sIGVnLiBgdjFgLlxuICAgICAqIEB0eXBlIHtTdHJpbmd9XG4gICAgICovXG5cbiAgfSwge1xuICAgIGtleTogXCJ2ZXJzaW9uXCIsXG4gICAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7XG4gICAgICByZXR1cm4gdGhpcy5fdmVyc2lvbjtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQmFja29mZiByZW1haW5pbmcgdGltZSwgaW4gbWlsbGlzZWNvbmRzLiBEZWZhdWx0cyB0byB6ZXJvIGlmIG5vIGJhY2tvZmYgaXNcbiAgICAgKiBvbmdvaW5nLlxuICAgICAqXG4gICAgICogQHR5cGUge051bWJlcn1cbiAgICAgKi9cblxuICB9LCB7XG4gICAga2V5OiBcImJhY2tvZmZcIixcbiAgICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHtcbiAgICAgIHZhciBjdXJyZW50VGltZSA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpO1xuXG4gICAgICBpZiAodGhpcy5fYmFja29mZlJlbGVhc2VUaW1lICYmIGN1cnJlbnRUaW1lIDwgdGhpcy5fYmFja29mZlJlbGVhc2VUaW1lKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9iYWNrb2ZmUmVsZWFzZVRpbWUgLSBjdXJyZW50VGltZTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIDA7XG4gICAgfVxuICB9XSk7XG4gIHJldHVybiBLaW50b0NsaWVudEJhc2U7XG59KCksICgoMCwgX2FwcGx5RGVjb3JhdGVkRGVzY3JpcHRvcjIuZGVmYXVsdCkoX2NsYXNzLnByb3RvdHlwZSwgXCJmZXRjaFNlcnZlclNldHRpbmdzXCIsIFtfZGVjXSwgT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihfY2xhc3MucHJvdG90eXBlLCBcImZldGNoU2VydmVyU2V0dGluZ3NcIiksIF9jbGFzcy5wcm90b3R5cGUpLCAoMCwgX2FwcGx5RGVjb3JhdGVkRGVzY3JpcHRvcjIuZGVmYXVsdCkoX2NsYXNzLnByb3RvdHlwZSwgXCJmZXRjaFNlcnZlckNhcGFiaWxpdGllc1wiLCBbX2RlYzJdLCBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKF9jbGFzcy5wcm90b3R5cGUsIFwiZmV0Y2hTZXJ2ZXJDYXBhYmlsaXRpZXNcIiksIF9jbGFzcy5wcm90b3R5cGUpLCAoMCwgX2FwcGx5RGVjb3JhdGVkRGVzY3JpcHRvcjIuZGVmYXVsdCkoX2NsYXNzLnByb3RvdHlwZSwgXCJmZXRjaFVzZXJcIiwgW19kZWMzXSwgT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihfY2xhc3MucHJvdG90eXBlLCBcImZldGNoVXNlclwiKSwgX2NsYXNzLnByb3RvdHlwZSksICgwLCBfYXBwbHlEZWNvcmF0ZWREZXNjcmlwdG9yMi5kZWZhdWx0KShfY2xhc3MucHJvdG90eXBlLCBcImZldGNoSFRUUEFwaVZlcnNpb25cIiwgW19kZWM0XSwgT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihfY2xhc3MucHJvdG90eXBlLCBcImZldGNoSFRUUEFwaVZlcnNpb25cIiksIF9jbGFzcy5wcm90b3R5cGUpLCAoMCwgX2FwcGx5RGVjb3JhdGVkRGVzY3JpcHRvcjIuZGVmYXVsdCkoX2NsYXNzLnByb3RvdHlwZSwgXCJiYXRjaFwiLCBbX2RlYzVdLCBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKF9jbGFzcy5wcm90b3R5cGUsIFwiYmF0Y2hcIiksIF9jbGFzcy5wcm90b3R5cGUpLCAoMCwgX2FwcGx5RGVjb3JhdGVkRGVzY3JpcHRvcjIuZGVmYXVsdCkoX2NsYXNzLnByb3RvdHlwZSwgXCJsaXN0UGVybWlzc2lvbnNcIiwgW19kZWM2XSwgT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihfY2xhc3MucHJvdG90eXBlLCBcImxpc3RQZXJtaXNzaW9uc1wiKSwgX2NsYXNzLnByb3RvdHlwZSksICgwLCBfYXBwbHlEZWNvcmF0ZWREZXNjcmlwdG9yMi5kZWZhdWx0KShfY2xhc3MucHJvdG90eXBlLCBcImRlbGV0ZUJ1Y2tldHNcIiwgW19kZWM3XSwgT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihfY2xhc3MucHJvdG90eXBlLCBcImRlbGV0ZUJ1Y2tldHNcIiksIF9jbGFzcy5wcm90b3R5cGUpKSwgX2NsYXNzKSk7XG5leHBvcnRzLmRlZmF1bHQgPSBLaW50b0NsaWVudEJhc2U7IiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5leHBvcnRzLmFnZ3JlZ2F0ZSA9IGFnZ3JlZ2F0ZTtcblxuLyoqXG4gKiBFeHBvcnRzIGJhdGNoIHJlc3BvbnNlcyBhcyBhIHJlc3VsdCBvYmplY3QuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSAge0FycmF5fSByZXNwb25zZXMgVGhlIGJhdGNoIHN1YnJlcXVlc3QgcmVzcG9uc2VzLlxuICogQHBhcmFtICB7QXJyYXl9IHJlcXVlc3RzICBUaGUgaW5pdGlhbCBpc3N1ZWQgcmVxdWVzdHMuXG4gKiBAcmV0dXJuIHtPYmplY3R9XG4gKi9cbmZ1bmN0aW9uIGFnZ3JlZ2F0ZSgpIHtcbiAgdmFyIHJlc3BvbnNlcyA9IGFyZ3VtZW50cy5sZW5ndGggPiAwICYmIGFyZ3VtZW50c1swXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzBdIDogW107XG4gIHZhciByZXF1ZXN0cyA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDogW107XG5cbiAgaWYgKHJlc3BvbnNlcy5sZW5ndGggIT09IHJlcXVlc3RzLmxlbmd0aCkge1xuICAgIHRocm93IG5ldyBFcnJvcihcIlJlc3BvbnNlcyBsZW5ndGggc2hvdWxkIG1hdGNoIHJlcXVlc3RzIG9uZS5cIik7XG4gIH1cblxuICB2YXIgcmVzdWx0cyA9IHtcbiAgICBlcnJvcnM6IFtdLFxuICAgIHB1Ymxpc2hlZDogW10sXG4gICAgY29uZmxpY3RzOiBbXSxcbiAgICBza2lwcGVkOiBbXVxuICB9O1xuICByZXR1cm4gcmVzcG9uc2VzLnJlZHVjZShmdW5jdGlvbiAoYWNjLCByZXNwb25zZSwgaW5kZXgpIHtcbiAgICB2YXIgc3RhdHVzID0gcmVzcG9uc2Uuc3RhdHVzO1xuICAgIHZhciByZXF1ZXN0ID0gcmVxdWVzdHNbaW5kZXhdO1xuXG4gICAgaWYgKHN0YXR1cyA+PSAyMDAgJiYgc3RhdHVzIDwgNDAwKSB7XG4gICAgICBhY2MucHVibGlzaGVkLnB1c2gocmVzcG9uc2UuYm9keSk7XG4gICAgfSBlbHNlIGlmIChzdGF0dXMgPT09IDQwNCkge1xuICAgICAgLy8gRXh0cmFjdCB0aGUgaWQgbWFudWFsbHkgZnJvbSByZXF1ZXN0IHBhdGggd2hpbGUgd2FpdGluZyBmb3IgS2ludG8va2ludG8jODE4XG4gICAgICB2YXIgcmVnZXggPSAvKGJ1Y2tldHN8Z3JvdXBzfGNvbGxlY3Rpb25zfHJlY29yZHMpXFwvKFteL10rKSQvO1xuICAgICAgdmFyIGV4dHJhY3RzID0gcmVxdWVzdC5wYXRoLm1hdGNoKHJlZ2V4KTtcbiAgICAgIHZhciBpZCA9IGV4dHJhY3RzLmxlbmd0aCA9PT0gMyA/IGV4dHJhY3RzWzJdIDogdW5kZWZpbmVkO1xuICAgICAgYWNjLnNraXBwZWQucHVzaCh7XG4gICAgICAgIGlkOiBpZCxcbiAgICAgICAgcGF0aDogcmVxdWVzdC5wYXRoLFxuICAgICAgICBlcnJvcjogcmVzcG9uc2UuYm9keVxuICAgICAgfSk7XG4gICAgfSBlbHNlIGlmIChzdGF0dXMgPT09IDQxMikge1xuICAgICAgYWNjLmNvbmZsaWN0cy5wdXNoKHtcbiAgICAgICAgLy8gWFhYOiBzcGVjaWZ5aW5nIHRoZSB0eXBlIGlzIHByb2JhYmx5IHN1cGVyZmx1b3VzXG4gICAgICAgIHR5cGU6IFwib3V0Z29pbmdcIixcbiAgICAgICAgbG9jYWw6IHJlcXVlc3QuYm9keSxcbiAgICAgICAgcmVtb3RlOiByZXNwb25zZS5ib2R5LmRldGFpbHMgJiYgcmVzcG9uc2UuYm9keS5kZXRhaWxzLmV4aXN0aW5nIHx8IG51bGxcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICBhY2MuZXJyb3JzLnB1c2goe1xuICAgICAgICBwYXRoOiByZXF1ZXN0LnBhdGgsXG4gICAgICAgIHNlbnQ6IHJlcXVlc3QsXG4gICAgICAgIGVycm9yOiByZXNwb25zZS5ib2R5XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICByZXR1cm4gYWNjO1xuICB9LCByZXN1bHRzKTtcbn0iLCJcInVzZSBzdHJpY3RcIjtcblxudmFyIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQgPSByZXF1aXJlKFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9pbnRlcm9wUmVxdWlyZURlZmF1bHRcIik7XG5cbnZhciBfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZCA9IHJlcXVpcmUoXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2ludGVyb3BSZXF1aXJlV2lsZGNhcmRcIik7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5leHBvcnRzLmRlZmF1bHQgPSB2b2lkIDA7XG5cbnZhciBfcmVnZW5lcmF0b3IgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KHJlcXVpcmUoXCJAYmFiZWwvcnVudGltZS9yZWdlbmVyYXRvclwiKSk7XG5cbnZhciBfYXN5bmNUb0dlbmVyYXRvcjIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KHJlcXVpcmUoXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2FzeW5jVG9HZW5lcmF0b3JcIikpO1xuXG52YXIgX29iamVjdFNwcmVhZDIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KHJlcXVpcmUoXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL29iamVjdFNwcmVhZFwiKSk7XG5cbnZhciBfY2xhc3NDYWxsQ2hlY2syID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9jbGFzc0NhbGxDaGVja1wiKSk7XG5cbnZhciBfY3JlYXRlQ2xhc3MyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9jcmVhdGVDbGFzc1wiKSk7XG5cbnZhciBfYXBwbHlEZWNvcmF0ZWREZXNjcmlwdG9yMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvYXBwbHlEZWNvcmF0ZWREZXNjcmlwdG9yXCIpKTtcblxudmFyIF91dGlscyA9IHJlcXVpcmUoXCIuL3V0aWxzXCIpO1xuXG52YXIgX2NvbGxlY3Rpb24gPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KHJlcXVpcmUoXCIuL2NvbGxlY3Rpb25cIikpO1xuXG52YXIgcmVxdWVzdHMgPSBfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZChyZXF1aXJlKFwiLi9yZXF1ZXN0c1wiKSk7XG5cbnZhciBfZW5kcG9pbnQgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KHJlcXVpcmUoXCIuL2VuZHBvaW50XCIpKTtcblxudmFyIF9kZWMsIF9jbGFzcztcblxuLyoqXG4gKiBBYnN0cmFjdCByZXByZXNlbnRhdGlvbiBvZiBhIHNlbGVjdGVkIGJ1Y2tldC5cbiAqXG4gKi9cbnZhciBCdWNrZXQgPSAoX2RlYyA9ICgwLCBfdXRpbHMuY2FwYWJsZSkoW1wiaGlzdG9yeVwiXSksIChfY2xhc3MgPVxuLyojX19QVVJFX18qL1xuZnVuY3Rpb24gKCkge1xuICAvKipcbiAgICogQ29uc3RydWN0b3IuXG4gICAqXG4gICAqIEBwYXJhbSAge0tpbnRvQ2xpZW50fSBjbGllbnQgICAgICAgICAgICBUaGUgY2xpZW50IGluc3RhbmNlLlxuICAgKiBAcGFyYW0gIHtTdHJpbmd9ICAgICAgbmFtZSAgICAgICAgICAgICAgVGhlIGJ1Y2tldCBuYW1lLlxuICAgKiBAcGFyYW0gIHtPYmplY3R9ICAgICAgW29wdGlvbnM9e31dICAgICAgVGhlIGhlYWRlcnMgb2JqZWN0IG9wdGlvbi5cbiAgICogQHBhcmFtICB7T2JqZWN0fSAgICAgIFtvcHRpb25zLmhlYWRlcnNdIFRoZSBoZWFkZXJzIG9iamVjdCBvcHRpb24uXG4gICAqIEBwYXJhbSAge0Jvb2xlYW59ICAgICBbb3B0aW9ucy5zYWZlXSAgICBUaGUgc2FmZSBvcHRpb24uXG4gICAqIEBwYXJhbSAge051bWJlcn0gICAgICBbb3B0aW9ucy5yZXRyeV0gICBUaGUgcmV0cnkgb3B0aW9uLlxuICAgKi9cbiAgZnVuY3Rpb24gQnVja2V0KGNsaWVudCwgbmFtZSkge1xuICAgIHZhciBvcHRpb25zID0gYXJndW1lbnRzLmxlbmd0aCA+IDIgJiYgYXJndW1lbnRzWzJdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMl0gOiB7fTtcbiAgICAoMCwgX2NsYXNzQ2FsbENoZWNrMi5kZWZhdWx0KSh0aGlzLCBCdWNrZXQpO1xuXG4gICAgLyoqXG4gICAgICogQGlnbm9yZVxuICAgICAqL1xuICAgIHRoaXMuY2xpZW50ID0gY2xpZW50O1xuICAgIC8qKlxuICAgICAqIFRoZSBidWNrZXQgbmFtZS5cbiAgICAgKiBAdHlwZSB7U3RyaW5nfVxuICAgICAqL1xuXG4gICAgdGhpcy5uYW1lID0gbmFtZTtcbiAgICAvKipcbiAgICAgKiBAaWdub3JlXG4gICAgICovXG5cbiAgICB0aGlzLl9pc0JhdGNoID0gISFvcHRpb25zLmJhdGNoO1xuICAgIC8qKlxuICAgICAqIEBpZ25vcmVcbiAgICAgKi9cblxuICAgIHRoaXMuX2hlYWRlcnMgPSBvcHRpb25zLmhlYWRlcnMgfHwge307XG4gICAgdGhpcy5fcmV0cnkgPSBvcHRpb25zLnJldHJ5IHx8IDA7XG4gICAgdGhpcy5fc2FmZSA9ICEhb3B0aW9ucy5zYWZlO1xuICB9XG4gIC8qKlxuICAgKiBHZXQgdGhlIHZhbHVlIG9mIFwiaGVhZGVyc1wiIGZvciBhIGdpdmVuIHJlcXVlc3QsIG1lcmdpbmcgdGhlXG4gICAqIHBlci1yZXF1ZXN0IGhlYWRlcnMgd2l0aCBvdXIgb3duIFwiZGVmYXVsdFwiIGhlYWRlcnMuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuXG5cbiAgKDAsIF9jcmVhdGVDbGFzczIuZGVmYXVsdCkoQnVja2V0LCBbe1xuICAgIGtleTogXCJfZ2V0SGVhZGVyc1wiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBfZ2V0SGVhZGVycyhvcHRpb25zKSB7XG4gICAgICByZXR1cm4gKDAsIF9vYmplY3RTcHJlYWQyLmRlZmF1bHQpKHt9LCB0aGlzLl9oZWFkZXJzLCBvcHRpb25zLmhlYWRlcnMpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIHZhbHVlIG9mIFwic2FmZVwiIGZvciBhIGdpdmVuIHJlcXVlc3QsIHVzaW5nIHRoZVxuICAgICAqIHBlci1yZXF1ZXN0IG9wdGlvbiBpZiBwcmVzZW50IG9yIGZhbGxpbmcgYmFjayB0byBvdXIgZGVmYXVsdFxuICAgICAqIG90aGVyd2lzZS5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnMgVGhlIG9wdGlvbnMgZm9yIGEgcmVxdWVzdC5cbiAgICAgKiBAcmV0dXJucyB7Qm9vbGVhbn1cbiAgICAgKi9cblxuICB9LCB7XG4gICAga2V5OiBcIl9nZXRTYWZlXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIF9nZXRTYWZlKG9wdGlvbnMpIHtcbiAgICAgIHJldHVybiAoMCwgX29iamVjdFNwcmVhZDIuZGVmYXVsdCkoe1xuICAgICAgICBzYWZlOiB0aGlzLl9zYWZlXG4gICAgICB9LCBvcHRpb25zKS5zYWZlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBBcyBfZ2V0U2FmZSwgYnV0IGZvciBcInJldHJ5XCIuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuXG4gIH0sIHtcbiAgICBrZXk6IFwiX2dldFJldHJ5XCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIF9nZXRSZXRyeShvcHRpb25zKSB7XG4gICAgICByZXR1cm4gKDAsIF9vYmplY3RTcHJlYWQyLmRlZmF1bHQpKHtcbiAgICAgICAgcmV0cnk6IHRoaXMuX3JldHJ5XG4gICAgICB9LCBvcHRpb25zKS5yZXRyeTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU2VsZWN0cyBhIGNvbGxlY3Rpb24uXG4gICAgICpcbiAgICAgKiBAcGFyYW0gIHtTdHJpbmd9ICBuYW1lICAgICAgICAgICAgICBUaGUgY29sbGVjdGlvbiBuYW1lLlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gIFtvcHRpb25zPXt9XSAgICAgIFRoZSBvcHRpb25zIG9iamVjdC5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICBbb3B0aW9ucy5oZWFkZXJzXSBUaGUgaGVhZGVycyBvYmplY3Qgb3B0aW9uLlxuICAgICAqIEBwYXJhbSAge0Jvb2xlYW59IFtvcHRpb25zLnNhZmVdICAgIFRoZSBzYWZlIG9wdGlvbi5cbiAgICAgKiBAcmV0dXJuIHtDb2xsZWN0aW9ufVxuICAgICAqL1xuXG4gIH0sIHtcbiAgICBrZXk6IFwiY29sbGVjdGlvblwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBjb2xsZWN0aW9uKG5hbWUpIHtcbiAgICAgIHZhciBvcHRpb25zID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMV0gOiB7fTtcbiAgICAgIHJldHVybiBuZXcgX2NvbGxlY3Rpb24uZGVmYXVsdCh0aGlzLmNsaWVudCwgdGhpcywgbmFtZSwge1xuICAgICAgICBiYXRjaDogdGhpcy5faXNCYXRjaCxcbiAgICAgICAgaGVhZGVyczogdGhpcy5fZ2V0SGVhZGVycyhvcHRpb25zKSxcbiAgICAgICAgcmV0cnk6IHRoaXMuX2dldFJldHJ5KG9wdGlvbnMpLFxuICAgICAgICBzYWZlOiB0aGlzLl9nZXRTYWZlKG9wdGlvbnMpXG4gICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0cmlldmVzIGJ1Y2tldCBkYXRhLlxuICAgICAqXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSBbb3B0aW9ucz17fV0gICAgICBUaGUgb3B0aW9ucyBvYmplY3QuXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSBbb3B0aW9ucy5oZWFkZXJzXSBUaGUgaGVhZGVycyBvYmplY3Qgb3B0aW9uLlxuICAgICAqIEBwYXJhbSAge051bWJlcn0gW29wdGlvbnMucmV0cnk9MF0gTnVtYmVyIG9mIHJldHJpZXMgdG8gbWFrZVxuICAgICAqICAgICB3aGVuIGZhY2VkIHdpdGggdHJhbnNpZW50IGVycm9ycy5cbiAgICAgKiBAcmV0dXJuIHtQcm9taXNlPE9iamVjdCwgRXJyb3I+fVxuICAgICAqL1xuXG4gIH0sIHtcbiAgICBrZXk6IFwiZ2V0RGF0YVwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgX2dldERhdGEgPSAoMCwgX2FzeW5jVG9HZW5lcmF0b3IyLmRlZmF1bHQpKFxuICAgICAgLyojX19QVVJFX18qL1xuICAgICAgX3JlZ2VuZXJhdG9yLmRlZmF1bHQubWFyayhmdW5jdGlvbiBfY2FsbGVlKCkge1xuICAgICAgICB2YXIgb3B0aW9ucyxcbiAgICAgICAgICAgIHJlcXVlc3QsXG4gICAgICAgICAgICBfcmVmLFxuICAgICAgICAgICAgZGF0YSxcbiAgICAgICAgICAgIF9hcmdzID0gYXJndW1lbnRzO1xuXG4gICAgICAgIHJldHVybiBfcmVnZW5lcmF0b3IuZGVmYXVsdC53cmFwKGZ1bmN0aW9uIF9jYWxsZWUkKF9jb250ZXh0KSB7XG4gICAgICAgICAgd2hpbGUgKDEpIHtcbiAgICAgICAgICAgIHN3aXRjaCAoX2NvbnRleHQucHJldiA9IF9jb250ZXh0Lm5leHQpIHtcbiAgICAgICAgICAgICAgY2FzZSAwOlxuICAgICAgICAgICAgICAgIG9wdGlvbnMgPSBfYXJncy5sZW5ndGggPiAwICYmIF9hcmdzWzBdICE9PSB1bmRlZmluZWQgPyBfYXJnc1swXSA6IHt9O1xuICAgICAgICAgICAgICAgIHJlcXVlc3QgPSB7XG4gICAgICAgICAgICAgICAgICBoZWFkZXJzOiB0aGlzLl9nZXRIZWFkZXJzKG9wdGlvbnMpLFxuICAgICAgICAgICAgICAgICAgcGF0aDogKDAsIF9lbmRwb2ludC5kZWZhdWx0KShcImJ1Y2tldFwiLCB0aGlzLm5hbWUpXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBfY29udGV4dC5uZXh0ID0gNDtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5jbGllbnQuZXhlY3V0ZShyZXF1ZXN0LCB7XG4gICAgICAgICAgICAgICAgICByZXRyeTogdGhpcy5fZ2V0UmV0cnkob3B0aW9ucylcbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICBjYXNlIDQ6XG4gICAgICAgICAgICAgICAgX3JlZiA9IF9jb250ZXh0LnNlbnQ7XG4gICAgICAgICAgICAgICAgZGF0YSA9IF9yZWYuZGF0YTtcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQuYWJydXB0KFwicmV0dXJuXCIsIGRhdGEpO1xuXG4gICAgICAgICAgICAgIGNhc2UgNzpcbiAgICAgICAgICAgICAgY2FzZSBcImVuZFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dC5zdG9wKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9LCBfY2FsbGVlLCB0aGlzKTtcbiAgICAgIH0pKTtcblxuICAgICAgcmV0dXJuIGZ1bmN0aW9uIGdldERhdGEoKSB7XG4gICAgICAgIHJldHVybiBfZ2V0RGF0YS5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgfTtcbiAgICB9KClcbiAgICAvKipcbiAgICAgKiBTZXQgYnVja2V0IGRhdGEuXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSAgZGF0YSAgICAgICAgICAgICAgICAgICAgVGhlIGJ1Y2tldCBkYXRhIG9iamVjdC5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICBbb3B0aW9ucz17fV0gICAgICAgICAgICBUaGUgb3B0aW9ucyBvYmplY3QuXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSAgW29wdGlvbnMuaGVhZGVycz17fV0gICAgVGhlIGhlYWRlcnMgb2JqZWN0IG9wdGlvbi5cbiAgICAgKiBAcGFyYW0gIHtCb29sZWFufSBbb3B0aW9ucy5zYWZlXSAgICAgICAgICBUaGUgc2FmZSBvcHRpb24uXG4gICAgICogQHBhcmFtICB7TnVtYmVyfSAgW29wdGlvbnMucmV0cnk9MF0gICAgICAgTnVtYmVyIG9mIHJldHJpZXMgdG8gbWFrZVxuICAgICAqICAgICB3aGVuIGZhY2VkIHdpdGggdHJhbnNpZW50IGVycm9ycy5cbiAgICAgKiBAcGFyYW0gIHtCb29sZWFufSBbb3B0aW9ucy5wYXRjaF0gICAgICAgICBUaGUgcGF0Y2ggb3B0aW9uLlxuICAgICAqIEBwYXJhbSAge051bWJlcn0gIFtvcHRpb25zLmxhc3RfbW9kaWZpZWRdIFRoZSBsYXN0X21vZGlmaWVkIG9wdGlvbi5cbiAgICAgKiBAcmV0dXJuIHtQcm9taXNlPE9iamVjdCwgRXJyb3I+fVxuICAgICAqL1xuXG4gIH0sIHtcbiAgICBrZXk6IFwic2V0RGF0YVwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgX3NldERhdGEgPSAoMCwgX2FzeW5jVG9HZW5lcmF0b3IyLmRlZmF1bHQpKFxuICAgICAgLyojX19QVVJFX18qL1xuICAgICAgX3JlZ2VuZXJhdG9yLmRlZmF1bHQubWFyayhmdW5jdGlvbiBfY2FsbGVlMihkYXRhKSB7XG4gICAgICAgIHZhciBvcHRpb25zLFxuICAgICAgICAgICAgYnVja2V0LFxuICAgICAgICAgICAgYnVja2V0SWQsXG4gICAgICAgICAgICBwYXRoLFxuICAgICAgICAgICAgcGF0Y2gsXG4gICAgICAgICAgICBwZXJtaXNzaW9ucyxcbiAgICAgICAgICAgIF9kYXRhJG9wdGlvbnMsXG4gICAgICAgICAgICBsYXN0X21vZGlmaWVkLFxuICAgICAgICAgICAgcmVxdWVzdCxcbiAgICAgICAgICAgIF9hcmdzMiA9IGFyZ3VtZW50cztcblxuICAgICAgICByZXR1cm4gX3JlZ2VuZXJhdG9yLmRlZmF1bHQud3JhcChmdW5jdGlvbiBfY2FsbGVlMiQoX2NvbnRleHQyKSB7XG4gICAgICAgICAgd2hpbGUgKDEpIHtcbiAgICAgICAgICAgIHN3aXRjaCAoX2NvbnRleHQyLnByZXYgPSBfY29udGV4dDIubmV4dCkge1xuICAgICAgICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICAgICAgb3B0aW9ucyA9IF9hcmdzMi5sZW5ndGggPiAxICYmIF9hcmdzMlsxXSAhPT0gdW5kZWZpbmVkID8gX2FyZ3MyWzFdIDoge307XG5cbiAgICAgICAgICAgICAgICBpZiAoKDAsIF91dGlscy5pc09iamVjdCkoZGF0YSkpIHtcbiAgICAgICAgICAgICAgICAgIF9jb250ZXh0Mi5uZXh0ID0gMztcbiAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkEgYnVja2V0IG9iamVjdCBpcyByZXF1aXJlZC5cIik7XG5cbiAgICAgICAgICAgICAgY2FzZSAzOlxuICAgICAgICAgICAgICAgIGJ1Y2tldCA9ICgwLCBfb2JqZWN0U3ByZWFkMi5kZWZhdWx0KSh7fSwgZGF0YSwge1xuICAgICAgICAgICAgICAgICAgaWQ6IHRoaXMubmFtZVxuICAgICAgICAgICAgICAgIH0pOyAvLyBGb3IgZGVmYXVsdCBidWNrZXQsIHdlIG5lZWQgdG8gZHJvcCB0aGUgaWQgZnJvbSB0aGUgZGF0YSBvYmplY3QuXG4gICAgICAgICAgICAgICAgLy8gQnVnIGluIEtpbnRvIDwgMy4xLjFcblxuICAgICAgICAgICAgICAgIGJ1Y2tldElkID0gYnVja2V0LmlkO1xuXG4gICAgICAgICAgICAgICAgaWYgKGJ1Y2tldC5pZCA9PT0gXCJkZWZhdWx0XCIpIHtcbiAgICAgICAgICAgICAgICAgIGRlbGV0ZSBidWNrZXQuaWQ7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgcGF0aCA9ICgwLCBfZW5kcG9pbnQuZGVmYXVsdCkoXCJidWNrZXRcIiwgYnVja2V0SWQpO1xuICAgICAgICAgICAgICAgIHBhdGNoID0gb3B0aW9ucy5wYXRjaCwgcGVybWlzc2lvbnMgPSBvcHRpb25zLnBlcm1pc3Npb25zO1xuICAgICAgICAgICAgICAgIF9kYXRhJG9wdGlvbnMgPSAoMCwgX29iamVjdFNwcmVhZDIuZGVmYXVsdCkoe30sIGRhdGEsIG9wdGlvbnMpLCBsYXN0X21vZGlmaWVkID0gX2RhdGEkb3B0aW9ucy5sYXN0X21vZGlmaWVkO1xuICAgICAgICAgICAgICAgIHJlcXVlc3QgPSByZXF1ZXN0cy51cGRhdGVSZXF1ZXN0KHBhdGgsIHtcbiAgICAgICAgICAgICAgICAgIGRhdGE6IGJ1Y2tldCxcbiAgICAgICAgICAgICAgICAgIHBlcm1pc3Npb25zOiBwZXJtaXNzaW9uc1xuICAgICAgICAgICAgICAgIH0sIHtcbiAgICAgICAgICAgICAgICAgIGxhc3RfbW9kaWZpZWQ6IGxhc3RfbW9kaWZpZWQsXG4gICAgICAgICAgICAgICAgICBwYXRjaDogcGF0Y2gsXG4gICAgICAgICAgICAgICAgICBoZWFkZXJzOiB0aGlzLl9nZXRIZWFkZXJzKG9wdGlvbnMpLFxuICAgICAgICAgICAgICAgICAgc2FmZTogdGhpcy5fZ2V0U2FmZShvcHRpb25zKVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDIuYWJydXB0KFwicmV0dXJuXCIsIHRoaXMuY2xpZW50LmV4ZWN1dGUocmVxdWVzdCwge1xuICAgICAgICAgICAgICAgICAgcmV0cnk6IHRoaXMuX2dldFJldHJ5KG9wdGlvbnMpXG4gICAgICAgICAgICAgICAgfSkpO1xuXG4gICAgICAgICAgICAgIGNhc2UgMTE6XG4gICAgICAgICAgICAgIGNhc2UgXCJlbmRcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQyLnN0b3AoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0sIF9jYWxsZWUyLCB0aGlzKTtcbiAgICAgIH0pKTtcblxuICAgICAgcmV0dXJuIGZ1bmN0aW9uIHNldERhdGEoX3gpIHtcbiAgICAgICAgcmV0dXJuIF9zZXREYXRhLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICB9O1xuICAgIH0oKVxuICAgIC8qKlxuICAgICAqIFJldHJpZXZlcyB0aGUgbGlzdCBvZiBoaXN0b3J5IGVudHJpZXMgaW4gdGhlIGN1cnJlbnQgYnVja2V0LlxuICAgICAqXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSBbb3B0aW9ucz17fV0gICAgICBUaGUgb3B0aW9ucyBvYmplY3QuXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSBbb3B0aW9ucy5oZWFkZXJzXSBUaGUgaGVhZGVycyBvYmplY3Qgb3B0aW9uLlxuICAgICAqIEBwYXJhbSAge051bWJlcn0gW29wdGlvbnMucmV0cnk9MF0gTnVtYmVyIG9mIHJldHJpZXMgdG8gbWFrZVxuICAgICAqICAgICB3aGVuIGZhY2VkIHdpdGggdHJhbnNpZW50IGVycm9ycy5cbiAgICAgKiBAcmV0dXJuIHtQcm9taXNlPEFycmF5PE9iamVjdD4sIEVycm9yPn1cbiAgICAgKi9cblxuICB9LCB7XG4gICAga2V5OiBcImxpc3RIaXN0b3J5XCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciBfbGlzdEhpc3RvcnkgPSAoMCwgX2FzeW5jVG9HZW5lcmF0b3IyLmRlZmF1bHQpKFxuICAgICAgLyojX19QVVJFX18qL1xuICAgICAgX3JlZ2VuZXJhdG9yLmRlZmF1bHQubWFyayhmdW5jdGlvbiBfY2FsbGVlMygpIHtcbiAgICAgICAgdmFyIG9wdGlvbnMsXG4gICAgICAgICAgICBwYXRoLFxuICAgICAgICAgICAgX2FyZ3MzID0gYXJndW1lbnRzO1xuICAgICAgICByZXR1cm4gX3JlZ2VuZXJhdG9yLmRlZmF1bHQud3JhcChmdW5jdGlvbiBfY2FsbGVlMyQoX2NvbnRleHQzKSB7XG4gICAgICAgICAgd2hpbGUgKDEpIHtcbiAgICAgICAgICAgIHN3aXRjaCAoX2NvbnRleHQzLnByZXYgPSBfY29udGV4dDMubmV4dCkge1xuICAgICAgICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICAgICAgb3B0aW9ucyA9IF9hcmdzMy5sZW5ndGggPiAwICYmIF9hcmdzM1swXSAhPT0gdW5kZWZpbmVkID8gX2FyZ3MzWzBdIDoge307XG4gICAgICAgICAgICAgICAgcGF0aCA9ICgwLCBfZW5kcG9pbnQuZGVmYXVsdCkoXCJoaXN0b3J5XCIsIHRoaXMubmFtZSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0My5hYnJ1cHQoXCJyZXR1cm5cIiwgdGhpcy5jbGllbnQucGFnaW5hdGVkTGlzdChwYXRoLCBvcHRpb25zLCB7XG4gICAgICAgICAgICAgICAgICBoZWFkZXJzOiB0aGlzLl9nZXRIZWFkZXJzKG9wdGlvbnMpLFxuICAgICAgICAgICAgICAgICAgcmV0cnk6IHRoaXMuX2dldFJldHJ5KG9wdGlvbnMpXG4gICAgICAgICAgICAgICAgfSkpO1xuXG4gICAgICAgICAgICAgIGNhc2UgMzpcbiAgICAgICAgICAgICAgY2FzZSBcImVuZFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDMuc3RvcCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSwgX2NhbGxlZTMsIHRoaXMpO1xuICAgICAgfSkpO1xuXG4gICAgICByZXR1cm4gZnVuY3Rpb24gbGlzdEhpc3RvcnkoKSB7XG4gICAgICAgIHJldHVybiBfbGlzdEhpc3RvcnkuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgIH07XG4gICAgfSgpXG4gICAgLyoqXG4gICAgICogUmV0cmlldmVzIHRoZSBsaXN0IG9mIGNvbGxlY3Rpb25zIGluIHRoZSBjdXJyZW50IGJ1Y2tldC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gW29wdGlvbnM9e31dICAgICAgVGhlIG9wdGlvbnMgb2JqZWN0LlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gW29wdGlvbnMuaGVhZGVyc10gVGhlIGhlYWRlcnMgb2JqZWN0IG9wdGlvbi5cbiAgICAgKiBAcGFyYW0gIHtOdW1iZXJ9IFtvcHRpb25zLnJldHJ5PTBdIE51bWJlciBvZiByZXRyaWVzIHRvIG1ha2VcbiAgICAgKiAgICAgd2hlbiBmYWNlZCB3aXRoIHRyYW5zaWVudCBlcnJvcnMuXG4gICAgICogQHJldHVybiB7UHJvbWlzZTxBcnJheTxPYmplY3Q+LCBFcnJvcj59XG4gICAgICovXG5cbiAgfSwge1xuICAgIGtleTogXCJsaXN0Q29sbGVjdGlvbnNcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gKCkge1xuICAgICAgdmFyIF9saXN0Q29sbGVjdGlvbnMgPSAoMCwgX2FzeW5jVG9HZW5lcmF0b3IyLmRlZmF1bHQpKFxuICAgICAgLyojX19QVVJFX18qL1xuICAgICAgX3JlZ2VuZXJhdG9yLmRlZmF1bHQubWFyayhmdW5jdGlvbiBfY2FsbGVlNCgpIHtcbiAgICAgICAgdmFyIG9wdGlvbnMsXG4gICAgICAgICAgICBwYXRoLFxuICAgICAgICAgICAgX2FyZ3M0ID0gYXJndW1lbnRzO1xuICAgICAgICByZXR1cm4gX3JlZ2VuZXJhdG9yLmRlZmF1bHQud3JhcChmdW5jdGlvbiBfY2FsbGVlNCQoX2NvbnRleHQ0KSB7XG4gICAgICAgICAgd2hpbGUgKDEpIHtcbiAgICAgICAgICAgIHN3aXRjaCAoX2NvbnRleHQ0LnByZXYgPSBfY29udGV4dDQubmV4dCkge1xuICAgICAgICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICAgICAgb3B0aW9ucyA9IF9hcmdzNC5sZW5ndGggPiAwICYmIF9hcmdzNFswXSAhPT0gdW5kZWZpbmVkID8gX2FyZ3M0WzBdIDoge307XG4gICAgICAgICAgICAgICAgcGF0aCA9ICgwLCBfZW5kcG9pbnQuZGVmYXVsdCkoXCJjb2xsZWN0aW9uXCIsIHRoaXMubmFtZSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0NC5hYnJ1cHQoXCJyZXR1cm5cIiwgdGhpcy5jbGllbnQucGFnaW5hdGVkTGlzdChwYXRoLCBvcHRpb25zLCB7XG4gICAgICAgICAgICAgICAgICBoZWFkZXJzOiB0aGlzLl9nZXRIZWFkZXJzKG9wdGlvbnMpLFxuICAgICAgICAgICAgICAgICAgcmV0cnk6IHRoaXMuX2dldFJldHJ5KG9wdGlvbnMpXG4gICAgICAgICAgICAgICAgfSkpO1xuXG4gICAgICAgICAgICAgIGNhc2UgMzpcbiAgICAgICAgICAgICAgY2FzZSBcImVuZFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDQuc3RvcCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSwgX2NhbGxlZTQsIHRoaXMpO1xuICAgICAgfSkpO1xuXG4gICAgICByZXR1cm4gZnVuY3Rpb24gbGlzdENvbGxlY3Rpb25zKCkge1xuICAgICAgICByZXR1cm4gX2xpc3RDb2xsZWN0aW9ucy5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgfTtcbiAgICB9KClcbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgbmV3IGNvbGxlY3Rpb24gaW4gY3VycmVudCBidWNrZXQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gIHtTdHJpbmd8dW5kZWZpbmVkfSAgaWQgICAgICAgICAgVGhlIGNvbGxlY3Rpb24gaWQuXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSAgW29wdGlvbnM9e31dICAgICAgICAgIFRoZSBvcHRpb25zIG9iamVjdC5cbiAgICAgKiBAcGFyYW0gIHtCb29sZWFufSBbb3B0aW9ucy5zYWZlXSAgICAgICAgVGhlIHNhZmUgb3B0aW9uLlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gIFtvcHRpb25zLmhlYWRlcnNdICAgICBUaGUgaGVhZGVycyBvYmplY3Qgb3B0aW9uLlxuICAgICAqIEBwYXJhbSAge051bWJlcn0gIFtvcHRpb25zLnJldHJ5PTBdICAgICBOdW1iZXIgb2YgcmV0cmllcyB0byBtYWtlXG4gICAgICogICAgIHdoZW4gZmFjZWQgd2l0aCB0cmFuc2llbnQgZXJyb3JzLlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gIFtvcHRpb25zLnBlcm1pc3Npb25zXSBUaGUgcGVybWlzc2lvbnMgb2JqZWN0LlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gIFtvcHRpb25zLmRhdGFdICAgICAgICBUaGUgZGF0YSBvYmplY3QuXG4gICAgICogQHJldHVybiB7UHJvbWlzZTxPYmplY3QsIEVycm9yPn1cbiAgICAgKi9cblxuICB9LCB7XG4gICAga2V5OiBcImNyZWF0ZUNvbGxlY3Rpb25cIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gKCkge1xuICAgICAgdmFyIF9jcmVhdGVDb2xsZWN0aW9uID0gKDAsIF9hc3luY1RvR2VuZXJhdG9yMi5kZWZhdWx0KShcbiAgICAgIC8qI19fUFVSRV9fKi9cbiAgICAgIF9yZWdlbmVyYXRvci5kZWZhdWx0Lm1hcmsoZnVuY3Rpb24gX2NhbGxlZTUoaWQpIHtcbiAgICAgICAgdmFyIG9wdGlvbnMsXG4gICAgICAgICAgICBwZXJtaXNzaW9ucyxcbiAgICAgICAgICAgIF9vcHRpb25zJGRhdGEsXG4gICAgICAgICAgICBkYXRhLFxuICAgICAgICAgICAgcGF0aCxcbiAgICAgICAgICAgIHJlcXVlc3QsXG4gICAgICAgICAgICBfYXJnczUgPSBhcmd1bWVudHM7XG5cbiAgICAgICAgcmV0dXJuIF9yZWdlbmVyYXRvci5kZWZhdWx0LndyYXAoZnVuY3Rpb24gX2NhbGxlZTUkKF9jb250ZXh0NSkge1xuICAgICAgICAgIHdoaWxlICgxKSB7XG4gICAgICAgICAgICBzd2l0Y2ggKF9jb250ZXh0NS5wcmV2ID0gX2NvbnRleHQ1Lm5leHQpIHtcbiAgICAgICAgICAgICAgY2FzZSAwOlxuICAgICAgICAgICAgICAgIG9wdGlvbnMgPSBfYXJnczUubGVuZ3RoID4gMSAmJiBfYXJnczVbMV0gIT09IHVuZGVmaW5lZCA/IF9hcmdzNVsxXSA6IHt9O1xuICAgICAgICAgICAgICAgIHBlcm1pc3Npb25zID0gb3B0aW9ucy5wZXJtaXNzaW9ucywgX29wdGlvbnMkZGF0YSA9IG9wdGlvbnMuZGF0YSwgZGF0YSA9IF9vcHRpb25zJGRhdGEgPT09IHZvaWQgMCA/IHt9IDogX29wdGlvbnMkZGF0YTtcbiAgICAgICAgICAgICAgICBkYXRhLmlkID0gaWQ7XG4gICAgICAgICAgICAgICAgcGF0aCA9ICgwLCBfZW5kcG9pbnQuZGVmYXVsdCkoXCJjb2xsZWN0aW9uXCIsIHRoaXMubmFtZSwgaWQpO1xuICAgICAgICAgICAgICAgIHJlcXVlc3QgPSByZXF1ZXN0cy5jcmVhdGVSZXF1ZXN0KHBhdGgsIHtcbiAgICAgICAgICAgICAgICAgIGRhdGE6IGRhdGEsXG4gICAgICAgICAgICAgICAgICBwZXJtaXNzaW9uczogcGVybWlzc2lvbnNcbiAgICAgICAgICAgICAgICB9LCB7XG4gICAgICAgICAgICAgICAgICBoZWFkZXJzOiB0aGlzLl9nZXRIZWFkZXJzKG9wdGlvbnMpLFxuICAgICAgICAgICAgICAgICAgc2FmZTogdGhpcy5fZ2V0U2FmZShvcHRpb25zKVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDUuYWJydXB0KFwicmV0dXJuXCIsIHRoaXMuY2xpZW50LmV4ZWN1dGUocmVxdWVzdCwge1xuICAgICAgICAgICAgICAgICAgcmV0cnk6IHRoaXMuX2dldFJldHJ5KG9wdGlvbnMpXG4gICAgICAgICAgICAgICAgfSkpO1xuXG4gICAgICAgICAgICAgIGNhc2UgNjpcbiAgICAgICAgICAgICAgY2FzZSBcImVuZFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDUuc3RvcCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSwgX2NhbGxlZTUsIHRoaXMpO1xuICAgICAgfSkpO1xuXG4gICAgICByZXR1cm4gZnVuY3Rpb24gY3JlYXRlQ29sbGVjdGlvbihfeDIpIHtcbiAgICAgICAgcmV0dXJuIF9jcmVhdGVDb2xsZWN0aW9uLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICB9O1xuICAgIH0oKVxuICAgIC8qKlxuICAgICAqIERlbGV0ZXMgYSBjb2xsZWN0aW9uIGZyb20gdGhlIGN1cnJlbnQgYnVja2V0LlxuICAgICAqXG4gICAgICogQHBhcmFtICB7T2JqZWN0fFN0cmluZ30gY29sbGVjdGlvbiAgICAgICAgICAgICAgVGhlIGNvbGxlY3Rpb24gdG8gZGVsZXRlLlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gICAgICAgIFtvcHRpb25zPXt9XSAgICAgICAgICAgIFRoZSBvcHRpb25zIG9iamVjdC5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICAgICAgICBbb3B0aW9ucy5oZWFkZXJzXSAgICAgICBUaGUgaGVhZGVycyBvYmplY3Qgb3B0aW9uLlxuICAgICAqIEBwYXJhbSAge051bWJlcn0gICAgICAgIFtvcHRpb25zLnJldHJ5PTBdICAgICAgIE51bWJlciBvZiByZXRyaWVzIHRvIG1ha2VcbiAgICAgKiAgICAgd2hlbiBmYWNlZCB3aXRoIHRyYW5zaWVudCBlcnJvcnMuXG4gICAgICogQHBhcmFtICB7Qm9vbGVhbn0gICAgICAgW29wdGlvbnMuc2FmZV0gICAgICAgICAgVGhlIHNhZmUgb3B0aW9uLlxuICAgICAqIEBwYXJhbSAge051bWJlcn0gICAgICAgIFtvcHRpb25zLmxhc3RfbW9kaWZpZWRdIFRoZSBsYXN0X21vZGlmaWVkIG9wdGlvbi5cbiAgICAgKiBAcmV0dXJuIHtQcm9taXNlPE9iamVjdCwgRXJyb3I+fVxuICAgICAqL1xuXG4gIH0sIHtcbiAgICBrZXk6IFwiZGVsZXRlQ29sbGVjdGlvblwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgX2RlbGV0ZUNvbGxlY3Rpb24gPSAoMCwgX2FzeW5jVG9HZW5lcmF0b3IyLmRlZmF1bHQpKFxuICAgICAgLyojX19QVVJFX18qL1xuICAgICAgX3JlZ2VuZXJhdG9yLmRlZmF1bHQubWFyayhmdW5jdGlvbiBfY2FsbGVlNihjb2xsZWN0aW9uKSB7XG4gICAgICAgIHZhciBvcHRpb25zLFxuICAgICAgICAgICAgY29sbGVjdGlvbk9iaixcbiAgICAgICAgICAgIGlkLFxuICAgICAgICAgICAgX2NvbGxlY3Rpb25PYmokb3B0aW9uLFxuICAgICAgICAgICAgbGFzdF9tb2RpZmllZCxcbiAgICAgICAgICAgIHBhdGgsXG4gICAgICAgICAgICByZXF1ZXN0LFxuICAgICAgICAgICAgX2FyZ3M2ID0gYXJndW1lbnRzO1xuXG4gICAgICAgIHJldHVybiBfcmVnZW5lcmF0b3IuZGVmYXVsdC53cmFwKGZ1bmN0aW9uIF9jYWxsZWU2JChfY29udGV4dDYpIHtcbiAgICAgICAgICB3aGlsZSAoMSkge1xuICAgICAgICAgICAgc3dpdGNoIChfY29udGV4dDYucHJldiA9IF9jb250ZXh0Ni5uZXh0KSB7XG4gICAgICAgICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgICAgICBvcHRpb25zID0gX2FyZ3M2Lmxlbmd0aCA+IDEgJiYgX2FyZ3M2WzFdICE9PSB1bmRlZmluZWQgPyBfYXJnczZbMV0gOiB7fTtcbiAgICAgICAgICAgICAgICBjb2xsZWN0aW9uT2JqID0gKDAsIF91dGlscy50b0RhdGFCb2R5KShjb2xsZWN0aW9uKTtcblxuICAgICAgICAgICAgICAgIGlmIChjb2xsZWN0aW9uT2JqLmlkKSB7XG4gICAgICAgICAgICAgICAgICBfY29udGV4dDYubmV4dCA9IDQ7XG4gICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJBIGNvbGxlY3Rpb24gaWQgaXMgcmVxdWlyZWQuXCIpO1xuXG4gICAgICAgICAgICAgIGNhc2UgNDpcbiAgICAgICAgICAgICAgICBpZCA9IGNvbGxlY3Rpb25PYmouaWQ7XG4gICAgICAgICAgICAgICAgX2NvbGxlY3Rpb25PYmokb3B0aW9uID0gKDAsIF9vYmplY3RTcHJlYWQyLmRlZmF1bHQpKHt9LCBjb2xsZWN0aW9uT2JqLCBvcHRpb25zKSwgbGFzdF9tb2RpZmllZCA9IF9jb2xsZWN0aW9uT2JqJG9wdGlvbi5sYXN0X21vZGlmaWVkO1xuICAgICAgICAgICAgICAgIHBhdGggPSAoMCwgX2VuZHBvaW50LmRlZmF1bHQpKFwiY29sbGVjdGlvblwiLCB0aGlzLm5hbWUsIGlkKTtcbiAgICAgICAgICAgICAgICByZXF1ZXN0ID0gcmVxdWVzdHMuZGVsZXRlUmVxdWVzdChwYXRoLCB7XG4gICAgICAgICAgICAgICAgICBsYXN0X21vZGlmaWVkOiBsYXN0X21vZGlmaWVkLFxuICAgICAgICAgICAgICAgICAgaGVhZGVyczogdGhpcy5fZ2V0SGVhZGVycyhvcHRpb25zKSxcbiAgICAgICAgICAgICAgICAgIHNhZmU6IHRoaXMuX2dldFNhZmUob3B0aW9ucylcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQ2LmFicnVwdChcInJldHVyblwiLCB0aGlzLmNsaWVudC5leGVjdXRlKHJlcXVlc3QsIHtcbiAgICAgICAgICAgICAgICAgIHJldHJ5OiB0aGlzLl9nZXRSZXRyeShvcHRpb25zKVxuICAgICAgICAgICAgICAgIH0pKTtcblxuICAgICAgICAgICAgICBjYXNlIDk6XG4gICAgICAgICAgICAgIGNhc2UgXCJlbmRcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQ2LnN0b3AoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0sIF9jYWxsZWU2LCB0aGlzKTtcbiAgICAgIH0pKTtcblxuICAgICAgcmV0dXJuIGZ1bmN0aW9uIGRlbGV0ZUNvbGxlY3Rpb24oX3gzKSB7XG4gICAgICAgIHJldHVybiBfZGVsZXRlQ29sbGVjdGlvbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgfTtcbiAgICB9KClcbiAgICAvKipcbiAgICAgKiBSZXRyaWV2ZXMgdGhlIGxpc3Qgb2YgZ3JvdXBzIGluIHRoZSBjdXJyZW50IGJ1Y2tldC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gW29wdGlvbnM9e31dICAgICAgVGhlIG9wdGlvbnMgb2JqZWN0LlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gW29wdGlvbnMuaGVhZGVyc10gVGhlIGhlYWRlcnMgb2JqZWN0IG9wdGlvbi5cbiAgICAgKiBAcGFyYW0gIHtOdW1iZXJ9IFtvcHRpb25zLnJldHJ5PTBdIE51bWJlciBvZiByZXRyaWVzIHRvIG1ha2VcbiAgICAgKiAgICAgd2hlbiBmYWNlZCB3aXRoIHRyYW5zaWVudCBlcnJvcnMuXG4gICAgICogQHJldHVybiB7UHJvbWlzZTxBcnJheTxPYmplY3Q+LCBFcnJvcj59XG4gICAgICovXG5cbiAgfSwge1xuICAgIGtleTogXCJsaXN0R3JvdXBzXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciBfbGlzdEdyb3VwcyA9ICgwLCBfYXN5bmNUb0dlbmVyYXRvcjIuZGVmYXVsdCkoXG4gICAgICAvKiNfX1BVUkVfXyovXG4gICAgICBfcmVnZW5lcmF0b3IuZGVmYXVsdC5tYXJrKGZ1bmN0aW9uIF9jYWxsZWU3KCkge1xuICAgICAgICB2YXIgb3B0aW9ucyxcbiAgICAgICAgICAgIHBhdGgsXG4gICAgICAgICAgICBfYXJnczcgPSBhcmd1bWVudHM7XG4gICAgICAgIHJldHVybiBfcmVnZW5lcmF0b3IuZGVmYXVsdC53cmFwKGZ1bmN0aW9uIF9jYWxsZWU3JChfY29udGV4dDcpIHtcbiAgICAgICAgICB3aGlsZSAoMSkge1xuICAgICAgICAgICAgc3dpdGNoIChfY29udGV4dDcucHJldiA9IF9jb250ZXh0Ny5uZXh0KSB7XG4gICAgICAgICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgICAgICBvcHRpb25zID0gX2FyZ3M3Lmxlbmd0aCA+IDAgJiYgX2FyZ3M3WzBdICE9PSB1bmRlZmluZWQgPyBfYXJnczdbMF0gOiB7fTtcbiAgICAgICAgICAgICAgICBwYXRoID0gKDAsIF9lbmRwb2ludC5kZWZhdWx0KShcImdyb3VwXCIsIHRoaXMubmFtZSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0Ny5hYnJ1cHQoXCJyZXR1cm5cIiwgdGhpcy5jbGllbnQucGFnaW5hdGVkTGlzdChwYXRoLCBvcHRpb25zLCB7XG4gICAgICAgICAgICAgICAgICBoZWFkZXJzOiB0aGlzLl9nZXRIZWFkZXJzKG9wdGlvbnMpLFxuICAgICAgICAgICAgICAgICAgcmV0cnk6IHRoaXMuX2dldFJldHJ5KG9wdGlvbnMpXG4gICAgICAgICAgICAgICAgfSkpO1xuXG4gICAgICAgICAgICAgIGNhc2UgMzpcbiAgICAgICAgICAgICAgY2FzZSBcImVuZFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDcuc3RvcCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSwgX2NhbGxlZTcsIHRoaXMpO1xuICAgICAgfSkpO1xuXG4gICAgICByZXR1cm4gZnVuY3Rpb24gbGlzdEdyb3VwcygpIHtcbiAgICAgICAgcmV0dXJuIF9saXN0R3JvdXBzLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICB9O1xuICAgIH0oKVxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBuZXcgZ3JvdXAgaW4gY3VycmVudCBidWNrZXQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gIHtTdHJpbmd9IGlkICAgICAgICAgICAgICAgIFRoZSBncm91cCBpZC5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9IFtvcHRpb25zPXt9XSAgICAgIFRoZSBvcHRpb25zIG9iamVjdC5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9IFtvcHRpb25zLmhlYWRlcnNdIFRoZSBoZWFkZXJzIG9iamVjdCBvcHRpb24uXG4gICAgICogQHBhcmFtICB7TnVtYmVyfSBbb3B0aW9ucy5yZXRyeT0wXSBOdW1iZXIgb2YgcmV0cmllcyB0byBtYWtlXG4gICAgICogICAgIHdoZW4gZmFjZWQgd2l0aCB0cmFuc2llbnQgZXJyb3JzLlxuICAgICAqIEByZXR1cm4ge1Byb21pc2U8T2JqZWN0LCBFcnJvcj59XG4gICAgICovXG5cbiAgfSwge1xuICAgIGtleTogXCJnZXRHcm91cFwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgX2dldEdyb3VwID0gKDAsIF9hc3luY1RvR2VuZXJhdG9yMi5kZWZhdWx0KShcbiAgICAgIC8qI19fUFVSRV9fKi9cbiAgICAgIF9yZWdlbmVyYXRvci5kZWZhdWx0Lm1hcmsoZnVuY3Rpb24gX2NhbGxlZTgoaWQpIHtcbiAgICAgICAgdmFyIG9wdGlvbnMsXG4gICAgICAgICAgICByZXF1ZXN0LFxuICAgICAgICAgICAgX2FyZ3M4ID0gYXJndW1lbnRzO1xuICAgICAgICByZXR1cm4gX3JlZ2VuZXJhdG9yLmRlZmF1bHQud3JhcChmdW5jdGlvbiBfY2FsbGVlOCQoX2NvbnRleHQ4KSB7XG4gICAgICAgICAgd2hpbGUgKDEpIHtcbiAgICAgICAgICAgIHN3aXRjaCAoX2NvbnRleHQ4LnByZXYgPSBfY29udGV4dDgubmV4dCkge1xuICAgICAgICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICAgICAgb3B0aW9ucyA9IF9hcmdzOC5sZW5ndGggPiAxICYmIF9hcmdzOFsxXSAhPT0gdW5kZWZpbmVkID8gX2FyZ3M4WzFdIDoge307XG4gICAgICAgICAgICAgICAgcmVxdWVzdCA9IHtcbiAgICAgICAgICAgICAgICAgIGhlYWRlcnM6IHRoaXMuX2dldEhlYWRlcnMob3B0aW9ucyksXG4gICAgICAgICAgICAgICAgICBwYXRoOiAoMCwgX2VuZHBvaW50LmRlZmF1bHQpKFwiZ3JvdXBcIiwgdGhpcy5uYW1lLCBpZClcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDguYWJydXB0KFwicmV0dXJuXCIsIHRoaXMuY2xpZW50LmV4ZWN1dGUocmVxdWVzdCwge1xuICAgICAgICAgICAgICAgICAgcmV0cnk6IHRoaXMuX2dldFJldHJ5KG9wdGlvbnMpXG4gICAgICAgICAgICAgICAgfSkpO1xuXG4gICAgICAgICAgICAgIGNhc2UgMzpcbiAgICAgICAgICAgICAgY2FzZSBcImVuZFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDguc3RvcCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSwgX2NhbGxlZTgsIHRoaXMpO1xuICAgICAgfSkpO1xuXG4gICAgICByZXR1cm4gZnVuY3Rpb24gZ2V0R3JvdXAoX3g0KSB7XG4gICAgICAgIHJldHVybiBfZ2V0R3JvdXAuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgIH07XG4gICAgfSgpXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIG5ldyBncm91cCBpbiBjdXJyZW50IGJ1Y2tldC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSAge1N0cmluZ3x1bmRlZmluZWR9ICBpZCAgICAgICAgICAgICAgICAgICAgVGhlIGdyb3VwIGlkLlxuICAgICAqIEBwYXJhbSAge0FycmF5PFN0cmluZz59ICAgICBbbWVtYmVycz1bXV0gICAgICAgICAgVGhlIGxpc3Qgb2YgcHJpbmNpcGFscy5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICAgICAgICAgICAgW29wdGlvbnM9e31dICAgICAgICAgIFRoZSBvcHRpb25zIG9iamVjdC5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICAgICAgICAgICAgW29wdGlvbnMuZGF0YV0gICAgICAgIFRoZSBkYXRhIG9iamVjdC5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICAgICAgICAgICAgW29wdGlvbnMucGVybWlzc2lvbnNdIFRoZSBwZXJtaXNzaW9ucyBvYmplY3QuXG4gICAgICogQHBhcmFtICB7Qm9vbGVhbn0gICAgICAgICAgIFtvcHRpb25zLnNhZmVdICAgICAgICBUaGUgc2FmZSBvcHRpb24uXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSAgICAgICAgICAgIFtvcHRpb25zLmhlYWRlcnNdICAgICBUaGUgaGVhZGVycyBvYmplY3Qgb3B0aW9uLlxuICAgICAqIEBwYXJhbSAge051bWJlcn0gICAgICAgICAgICBbb3B0aW9ucy5yZXRyeT0wXSAgICAgTnVtYmVyIG9mIHJldHJpZXMgdG8gbWFrZVxuICAgICAqICAgICB3aGVuIGZhY2VkIHdpdGggdHJhbnNpZW50IGVycm9ycy5cbiAgICAgKiBAcmV0dXJuIHtQcm9taXNlPE9iamVjdCwgRXJyb3I+fVxuICAgICAqL1xuXG4gIH0sIHtcbiAgICBrZXk6IFwiY3JlYXRlR3JvdXBcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gKCkge1xuICAgICAgdmFyIF9jcmVhdGVHcm91cCA9ICgwLCBfYXN5bmNUb0dlbmVyYXRvcjIuZGVmYXVsdCkoXG4gICAgICAvKiNfX1BVUkVfXyovXG4gICAgICBfcmVnZW5lcmF0b3IuZGVmYXVsdC5tYXJrKGZ1bmN0aW9uIF9jYWxsZWU5KGlkKSB7XG4gICAgICAgIHZhciBtZW1iZXJzLFxuICAgICAgICAgICAgb3B0aW9ucyxcbiAgICAgICAgICAgIGRhdGEsXG4gICAgICAgICAgICBwYXRoLFxuICAgICAgICAgICAgcGVybWlzc2lvbnMsXG4gICAgICAgICAgICByZXF1ZXN0LFxuICAgICAgICAgICAgX2FyZ3M5ID0gYXJndW1lbnRzO1xuICAgICAgICByZXR1cm4gX3JlZ2VuZXJhdG9yLmRlZmF1bHQud3JhcChmdW5jdGlvbiBfY2FsbGVlOSQoX2NvbnRleHQ5KSB7XG4gICAgICAgICAgd2hpbGUgKDEpIHtcbiAgICAgICAgICAgIHN3aXRjaCAoX2NvbnRleHQ5LnByZXYgPSBfY29udGV4dDkubmV4dCkge1xuICAgICAgICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICAgICAgbWVtYmVycyA9IF9hcmdzOS5sZW5ndGggPiAxICYmIF9hcmdzOVsxXSAhPT0gdW5kZWZpbmVkID8gX2FyZ3M5WzFdIDogW107XG4gICAgICAgICAgICAgICAgb3B0aW9ucyA9IF9hcmdzOS5sZW5ndGggPiAyICYmIF9hcmdzOVsyXSAhPT0gdW5kZWZpbmVkID8gX2FyZ3M5WzJdIDoge307XG4gICAgICAgICAgICAgICAgZGF0YSA9ICgwLCBfb2JqZWN0U3ByZWFkMi5kZWZhdWx0KSh7fSwgb3B0aW9ucy5kYXRhLCB7XG4gICAgICAgICAgICAgICAgICBpZDogaWQsXG4gICAgICAgICAgICAgICAgICBtZW1iZXJzOiBtZW1iZXJzXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgcGF0aCA9ICgwLCBfZW5kcG9pbnQuZGVmYXVsdCkoXCJncm91cFwiLCB0aGlzLm5hbWUsIGlkKTtcbiAgICAgICAgICAgICAgICBwZXJtaXNzaW9ucyA9IG9wdGlvbnMucGVybWlzc2lvbnM7XG4gICAgICAgICAgICAgICAgcmVxdWVzdCA9IHJlcXVlc3RzLmNyZWF0ZVJlcXVlc3QocGF0aCwge1xuICAgICAgICAgICAgICAgICAgZGF0YTogZGF0YSxcbiAgICAgICAgICAgICAgICAgIHBlcm1pc3Npb25zOiBwZXJtaXNzaW9uc1xuICAgICAgICAgICAgICAgIH0sIHtcbiAgICAgICAgICAgICAgICAgIGhlYWRlcnM6IHRoaXMuX2dldEhlYWRlcnMob3B0aW9ucyksXG4gICAgICAgICAgICAgICAgICBzYWZlOiB0aGlzLl9nZXRTYWZlKG9wdGlvbnMpXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0OS5hYnJ1cHQoXCJyZXR1cm5cIiwgdGhpcy5jbGllbnQuZXhlY3V0ZShyZXF1ZXN0LCB7XG4gICAgICAgICAgICAgICAgICByZXRyeTogdGhpcy5fZ2V0UmV0cnkob3B0aW9ucylcbiAgICAgICAgICAgICAgICB9KSk7XG5cbiAgICAgICAgICAgICAgY2FzZSA3OlxuICAgICAgICAgICAgICBjYXNlIFwiZW5kXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0OS5zdG9wKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9LCBfY2FsbGVlOSwgdGhpcyk7XG4gICAgICB9KSk7XG5cbiAgICAgIHJldHVybiBmdW5jdGlvbiBjcmVhdGVHcm91cChfeDUpIHtcbiAgICAgICAgcmV0dXJuIF9jcmVhdGVHcm91cC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgfTtcbiAgICB9KClcbiAgICAvKipcbiAgICAgKiBVcGRhdGVzIGFuIGV4aXN0aW5nIGdyb3VwIGluIGN1cnJlbnQgYnVja2V0LlxuICAgICAqXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSAgZ3JvdXAgICAgICAgICAgICAgICAgICAgVGhlIGdyb3VwIG9iamVjdC5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICBbb3B0aW9ucz17fV0gICAgICAgICAgICBUaGUgb3B0aW9ucyBvYmplY3QuXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSAgW29wdGlvbnMuZGF0YV0gICAgICAgICAgVGhlIGRhdGEgb2JqZWN0LlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gIFtvcHRpb25zLnBlcm1pc3Npb25zXSAgIFRoZSBwZXJtaXNzaW9ucyBvYmplY3QuXG4gICAgICogQHBhcmFtICB7Qm9vbGVhbn0gW29wdGlvbnMuc2FmZV0gICAgICAgICAgVGhlIHNhZmUgb3B0aW9uLlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gIFtvcHRpb25zLmhlYWRlcnNdICAgICAgIFRoZSBoZWFkZXJzIG9iamVjdCBvcHRpb24uXG4gICAgICogQHBhcmFtICB7TnVtYmVyfSAgW29wdGlvbnMucmV0cnk9MF0gICAgICAgTnVtYmVyIG9mIHJldHJpZXMgdG8gbWFrZVxuICAgICAqICAgICB3aGVuIGZhY2VkIHdpdGggdHJhbnNpZW50IGVycm9ycy5cbiAgICAgKiBAcGFyYW0gIHtOdW1iZXJ9ICBbb3B0aW9ucy5sYXN0X21vZGlmaWVkXSBUaGUgbGFzdF9tb2RpZmllZCBvcHRpb24uXG4gICAgICogQHJldHVybiB7UHJvbWlzZTxPYmplY3QsIEVycm9yPn1cbiAgICAgKi9cblxuICB9LCB7XG4gICAga2V5OiBcInVwZGF0ZUdyb3VwXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciBfdXBkYXRlR3JvdXAgPSAoMCwgX2FzeW5jVG9HZW5lcmF0b3IyLmRlZmF1bHQpKFxuICAgICAgLyojX19QVVJFX18qL1xuICAgICAgX3JlZ2VuZXJhdG9yLmRlZmF1bHQubWFyayhmdW5jdGlvbiBfY2FsbGVlMTAoZ3JvdXApIHtcbiAgICAgICAgdmFyIG9wdGlvbnMsXG4gICAgICAgICAgICBkYXRhLFxuICAgICAgICAgICAgcGF0aCxcbiAgICAgICAgICAgIHBhdGNoLFxuICAgICAgICAgICAgcGVybWlzc2lvbnMsXG4gICAgICAgICAgICBfZGF0YSRvcHRpb25zMixcbiAgICAgICAgICAgIGxhc3RfbW9kaWZpZWQsXG4gICAgICAgICAgICByZXF1ZXN0LFxuICAgICAgICAgICAgX2FyZ3MxMCA9IGFyZ3VtZW50cztcblxuICAgICAgICByZXR1cm4gX3JlZ2VuZXJhdG9yLmRlZmF1bHQud3JhcChmdW5jdGlvbiBfY2FsbGVlMTAkKF9jb250ZXh0MTApIHtcbiAgICAgICAgICB3aGlsZSAoMSkge1xuICAgICAgICAgICAgc3dpdGNoIChfY29udGV4dDEwLnByZXYgPSBfY29udGV4dDEwLm5leHQpIHtcbiAgICAgICAgICAgICAgY2FzZSAwOlxuICAgICAgICAgICAgICAgIG9wdGlvbnMgPSBfYXJnczEwLmxlbmd0aCA+IDEgJiYgX2FyZ3MxMFsxXSAhPT0gdW5kZWZpbmVkID8gX2FyZ3MxMFsxXSA6IHt9O1xuXG4gICAgICAgICAgICAgICAgaWYgKCgwLCBfdXRpbHMuaXNPYmplY3QpKGdyb3VwKSkge1xuICAgICAgICAgICAgICAgICAgX2NvbnRleHQxMC5uZXh0ID0gMztcbiAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkEgZ3JvdXAgb2JqZWN0IGlzIHJlcXVpcmVkLlwiKTtcblxuICAgICAgICAgICAgICBjYXNlIDM6XG4gICAgICAgICAgICAgICAgaWYgKGdyb3VwLmlkKSB7XG4gICAgICAgICAgICAgICAgICBfY29udGV4dDEwLm5leHQgPSA1O1xuICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQSBncm91cCBpZCBpcyByZXF1aXJlZC5cIik7XG5cbiAgICAgICAgICAgICAgY2FzZSA1OlxuICAgICAgICAgICAgICAgIGRhdGEgPSAoMCwgX29iamVjdFNwcmVhZDIuZGVmYXVsdCkoe30sIG9wdGlvbnMuZGF0YSwgZ3JvdXApO1xuICAgICAgICAgICAgICAgIHBhdGggPSAoMCwgX2VuZHBvaW50LmRlZmF1bHQpKFwiZ3JvdXBcIiwgdGhpcy5uYW1lLCBncm91cC5pZCk7XG4gICAgICAgICAgICAgICAgcGF0Y2ggPSBvcHRpb25zLnBhdGNoLCBwZXJtaXNzaW9ucyA9IG9wdGlvbnMucGVybWlzc2lvbnM7XG4gICAgICAgICAgICAgICAgX2RhdGEkb3B0aW9uczIgPSAoMCwgX29iamVjdFNwcmVhZDIuZGVmYXVsdCkoe30sIGRhdGEsIG9wdGlvbnMpLCBsYXN0X21vZGlmaWVkID0gX2RhdGEkb3B0aW9uczIubGFzdF9tb2RpZmllZDtcbiAgICAgICAgICAgICAgICByZXF1ZXN0ID0gcmVxdWVzdHMudXBkYXRlUmVxdWVzdChwYXRoLCB7XG4gICAgICAgICAgICAgICAgICBkYXRhOiBkYXRhLFxuICAgICAgICAgICAgICAgICAgcGVybWlzc2lvbnM6IHBlcm1pc3Npb25zXG4gICAgICAgICAgICAgICAgfSwge1xuICAgICAgICAgICAgICAgICAgbGFzdF9tb2RpZmllZDogbGFzdF9tb2RpZmllZCxcbiAgICAgICAgICAgICAgICAgIHBhdGNoOiBwYXRjaCxcbiAgICAgICAgICAgICAgICAgIGhlYWRlcnM6IHRoaXMuX2dldEhlYWRlcnMob3B0aW9ucyksXG4gICAgICAgICAgICAgICAgICBzYWZlOiB0aGlzLl9nZXRTYWZlKG9wdGlvbnMpXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0MTAuYWJydXB0KFwicmV0dXJuXCIsIHRoaXMuY2xpZW50LmV4ZWN1dGUocmVxdWVzdCwge1xuICAgICAgICAgICAgICAgICAgcmV0cnk6IHRoaXMuX2dldFJldHJ5KG9wdGlvbnMpXG4gICAgICAgICAgICAgICAgfSkpO1xuXG4gICAgICAgICAgICAgIGNhc2UgMTE6XG4gICAgICAgICAgICAgIGNhc2UgXCJlbmRcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQxMC5zdG9wKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9LCBfY2FsbGVlMTAsIHRoaXMpO1xuICAgICAgfSkpO1xuXG4gICAgICByZXR1cm4gZnVuY3Rpb24gdXBkYXRlR3JvdXAoX3g2KSB7XG4gICAgICAgIHJldHVybiBfdXBkYXRlR3JvdXAuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgIH07XG4gICAgfSgpXG4gICAgLyoqXG4gICAgICogRGVsZXRlcyBhIGdyb3VwIGZyb20gdGhlIGN1cnJlbnQgYnVja2V0LlxuICAgICAqXG4gICAgICogQHBhcmFtICB7T2JqZWN0fFN0cmluZ30gZ3JvdXAgICAgICAgICAgICAgICAgICAgVGhlIGdyb3VwIHRvIGRlbGV0ZS5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICAgICAgICBbb3B0aW9ucz17fV0gICAgICAgICAgICBUaGUgb3B0aW9ucyBvYmplY3QuXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSAgICAgICAgW29wdGlvbnMuaGVhZGVyc10gICAgICAgVGhlIGhlYWRlcnMgb2JqZWN0IG9wdGlvbi5cbiAgICAgKiBAcGFyYW0gIHtOdW1iZXJ9ICAgICAgICBbb3B0aW9ucy5yZXRyeT0wXSAgICAgICBOdW1iZXIgb2YgcmV0cmllcyB0byBtYWtlXG4gICAgICogICAgIHdoZW4gZmFjZWQgd2l0aCB0cmFuc2llbnQgZXJyb3JzLlxuICAgICAqIEBwYXJhbSAge0Jvb2xlYW59ICAgICAgIFtvcHRpb25zLnNhZmVdICAgICAgICAgIFRoZSBzYWZlIG9wdGlvbi5cbiAgICAgKiBAcGFyYW0gIHtOdW1iZXJ9ICAgICAgICBbb3B0aW9ucy5sYXN0X21vZGlmaWVkXSBUaGUgbGFzdF9tb2RpZmllZCBvcHRpb24uXG4gICAgICogQHJldHVybiB7UHJvbWlzZTxPYmplY3QsIEVycm9yPn1cbiAgICAgKi9cblxuICB9LCB7XG4gICAga2V5OiBcImRlbGV0ZUdyb3VwXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciBfZGVsZXRlR3JvdXAgPSAoMCwgX2FzeW5jVG9HZW5lcmF0b3IyLmRlZmF1bHQpKFxuICAgICAgLyojX19QVVJFX18qL1xuICAgICAgX3JlZ2VuZXJhdG9yLmRlZmF1bHQubWFyayhmdW5jdGlvbiBfY2FsbGVlMTEoZ3JvdXApIHtcbiAgICAgICAgdmFyIG9wdGlvbnMsXG4gICAgICAgICAgICBncm91cE9iaixcbiAgICAgICAgICAgIGlkLFxuICAgICAgICAgICAgX2dyb3VwT2JqJG9wdGlvbnMsXG4gICAgICAgICAgICBsYXN0X21vZGlmaWVkLFxuICAgICAgICAgICAgcGF0aCxcbiAgICAgICAgICAgIHJlcXVlc3QsXG4gICAgICAgICAgICBfYXJnczExID0gYXJndW1lbnRzO1xuXG4gICAgICAgIHJldHVybiBfcmVnZW5lcmF0b3IuZGVmYXVsdC53cmFwKGZ1bmN0aW9uIF9jYWxsZWUxMSQoX2NvbnRleHQxMSkge1xuICAgICAgICAgIHdoaWxlICgxKSB7XG4gICAgICAgICAgICBzd2l0Y2ggKF9jb250ZXh0MTEucHJldiA9IF9jb250ZXh0MTEubmV4dCkge1xuICAgICAgICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICAgICAgb3B0aW9ucyA9IF9hcmdzMTEubGVuZ3RoID4gMSAmJiBfYXJnczExWzFdICE9PSB1bmRlZmluZWQgPyBfYXJnczExWzFdIDoge307XG4gICAgICAgICAgICAgICAgZ3JvdXBPYmogPSAoMCwgX3V0aWxzLnRvRGF0YUJvZHkpKGdyb3VwKTtcbiAgICAgICAgICAgICAgICBpZCA9IGdyb3VwT2JqLmlkO1xuICAgICAgICAgICAgICAgIF9ncm91cE9iaiRvcHRpb25zID0gKDAsIF9vYmplY3RTcHJlYWQyLmRlZmF1bHQpKHt9LCBncm91cE9iaiwgb3B0aW9ucyksIGxhc3RfbW9kaWZpZWQgPSBfZ3JvdXBPYmokb3B0aW9ucy5sYXN0X21vZGlmaWVkO1xuICAgICAgICAgICAgICAgIHBhdGggPSAoMCwgX2VuZHBvaW50LmRlZmF1bHQpKFwiZ3JvdXBcIiwgdGhpcy5uYW1lLCBpZCk7XG4gICAgICAgICAgICAgICAgcmVxdWVzdCA9IHJlcXVlc3RzLmRlbGV0ZVJlcXVlc3QocGF0aCwge1xuICAgICAgICAgICAgICAgICAgbGFzdF9tb2RpZmllZDogbGFzdF9tb2RpZmllZCxcbiAgICAgICAgICAgICAgICAgIGhlYWRlcnM6IHRoaXMuX2dldEhlYWRlcnMob3B0aW9ucyksXG4gICAgICAgICAgICAgICAgICBzYWZlOiB0aGlzLl9nZXRTYWZlKG9wdGlvbnMpXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0MTEuYWJydXB0KFwicmV0dXJuXCIsIHRoaXMuY2xpZW50LmV4ZWN1dGUocmVxdWVzdCwge1xuICAgICAgICAgICAgICAgICAgcmV0cnk6IHRoaXMuX2dldFJldHJ5KG9wdGlvbnMpXG4gICAgICAgICAgICAgICAgfSkpO1xuXG4gICAgICAgICAgICAgIGNhc2UgNzpcbiAgICAgICAgICAgICAgY2FzZSBcImVuZFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDExLnN0b3AoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0sIF9jYWxsZWUxMSwgdGhpcyk7XG4gICAgICB9KSk7XG5cbiAgICAgIHJldHVybiBmdW5jdGlvbiBkZWxldGVHcm91cChfeDcpIHtcbiAgICAgICAgcmV0dXJuIF9kZWxldGVHcm91cC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgfTtcbiAgICB9KClcbiAgICAvKipcbiAgICAgKiBSZXRyaWV2ZXMgdGhlIGxpc3Qgb2YgcGVybWlzc2lvbnMgZm9yIHRoaXMgYnVja2V0LlxuICAgICAqXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSBbb3B0aW9ucz17fV0gICAgICBUaGUgb3B0aW9ucyBvYmplY3QuXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSBbb3B0aW9ucy5oZWFkZXJzXSBUaGUgaGVhZGVycyBvYmplY3Qgb3B0aW9uLlxuICAgICAqIEBwYXJhbSAge051bWJlcn0gW29wdGlvbnMucmV0cnk9MF0gTnVtYmVyIG9mIHJldHJpZXMgdG8gbWFrZVxuICAgICAqICAgICB3aGVuIGZhY2VkIHdpdGggdHJhbnNpZW50IGVycm9ycy5cbiAgICAgKiBAcmV0dXJuIHtQcm9taXNlPE9iamVjdCwgRXJyb3I+fVxuICAgICAqL1xuXG4gIH0sIHtcbiAgICBrZXk6IFwiZ2V0UGVybWlzc2lvbnNcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gKCkge1xuICAgICAgdmFyIF9nZXRQZXJtaXNzaW9ucyA9ICgwLCBfYXN5bmNUb0dlbmVyYXRvcjIuZGVmYXVsdCkoXG4gICAgICAvKiNfX1BVUkVfXyovXG4gICAgICBfcmVnZW5lcmF0b3IuZGVmYXVsdC5tYXJrKGZ1bmN0aW9uIF9jYWxsZWUxMigpIHtcbiAgICAgICAgdmFyIG9wdGlvbnMsXG4gICAgICAgICAgICByZXF1ZXN0LFxuICAgICAgICAgICAgX3JlZjIsXG4gICAgICAgICAgICBwZXJtaXNzaW9ucyxcbiAgICAgICAgICAgIF9hcmdzMTIgPSBhcmd1bWVudHM7XG5cbiAgICAgICAgcmV0dXJuIF9yZWdlbmVyYXRvci5kZWZhdWx0LndyYXAoZnVuY3Rpb24gX2NhbGxlZTEyJChfY29udGV4dDEyKSB7XG4gICAgICAgICAgd2hpbGUgKDEpIHtcbiAgICAgICAgICAgIHN3aXRjaCAoX2NvbnRleHQxMi5wcmV2ID0gX2NvbnRleHQxMi5uZXh0KSB7XG4gICAgICAgICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgICAgICBvcHRpb25zID0gX2FyZ3MxMi5sZW5ndGggPiAwICYmIF9hcmdzMTJbMF0gIT09IHVuZGVmaW5lZCA/IF9hcmdzMTJbMF0gOiB7fTtcbiAgICAgICAgICAgICAgICByZXF1ZXN0ID0ge1xuICAgICAgICAgICAgICAgICAgaGVhZGVyczogdGhpcy5fZ2V0SGVhZGVycyhvcHRpb25zKSxcbiAgICAgICAgICAgICAgICAgIHBhdGg6ICgwLCBfZW5kcG9pbnQuZGVmYXVsdCkoXCJidWNrZXRcIiwgdGhpcy5uYW1lKVxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgX2NvbnRleHQxMi5uZXh0ID0gNDtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5jbGllbnQuZXhlY3V0ZShyZXF1ZXN0LCB7XG4gICAgICAgICAgICAgICAgICByZXRyeTogdGhpcy5fZ2V0UmV0cnkob3B0aW9ucylcbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICBjYXNlIDQ6XG4gICAgICAgICAgICAgICAgX3JlZjIgPSBfY29udGV4dDEyLnNlbnQ7XG4gICAgICAgICAgICAgICAgcGVybWlzc2lvbnMgPSBfcmVmMi5wZXJtaXNzaW9ucztcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQxMi5hYnJ1cHQoXCJyZXR1cm5cIiwgcGVybWlzc2lvbnMpO1xuXG4gICAgICAgICAgICAgIGNhc2UgNzpcbiAgICAgICAgICAgICAgY2FzZSBcImVuZFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDEyLnN0b3AoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0sIF9jYWxsZWUxMiwgdGhpcyk7XG4gICAgICB9KSk7XG5cbiAgICAgIHJldHVybiBmdW5jdGlvbiBnZXRQZXJtaXNzaW9ucygpIHtcbiAgICAgICAgcmV0dXJuIF9nZXRQZXJtaXNzaW9ucy5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgfTtcbiAgICB9KClcbiAgICAvKipcbiAgICAgKiBSZXBsYWNlcyBhbGwgZXhpc3RpbmcgYnVja2V0IHBlcm1pc3Npb25zIHdpdGggdGhlIG9uZXMgcHJvdmlkZWQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICBwZXJtaXNzaW9ucyAgICAgICAgICAgICBUaGUgcGVybWlzc2lvbnMgb2JqZWN0LlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gIFtvcHRpb25zPXt9XSAgICAgICAgICAgIFRoZSBvcHRpb25zIG9iamVjdFxuICAgICAqIEBwYXJhbSAge0Jvb2xlYW59IFtvcHRpb25zLnNhZmVdICAgICAgICAgIFRoZSBzYWZlIG9wdGlvbi5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICBbb3B0aW9ucy5oZWFkZXJzPXt9XSAgICBUaGUgaGVhZGVycyBvYmplY3Qgb3B0aW9uLlxuICAgICAqIEBwYXJhbSAge051bWJlcn0gIFtvcHRpb25zLnJldHJ5PTBdICAgICAgIE51bWJlciBvZiByZXRyaWVzIHRvIG1ha2VcbiAgICAgKiAgICAgd2hlbiBmYWNlZCB3aXRoIHRyYW5zaWVudCBlcnJvcnMuXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSAgW29wdGlvbnMubGFzdF9tb2RpZmllZF0gVGhlIGxhc3RfbW9kaWZpZWQgb3B0aW9uLlxuICAgICAqIEByZXR1cm4ge1Byb21pc2U8T2JqZWN0LCBFcnJvcj59XG4gICAgICovXG5cbiAgfSwge1xuICAgIGtleTogXCJzZXRQZXJtaXNzaW9uc1wiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgX3NldFBlcm1pc3Npb25zID0gKDAsIF9hc3luY1RvR2VuZXJhdG9yMi5kZWZhdWx0KShcbiAgICAgIC8qI19fUFVSRV9fKi9cbiAgICAgIF9yZWdlbmVyYXRvci5kZWZhdWx0Lm1hcmsoZnVuY3Rpb24gX2NhbGxlZTEzKHBlcm1pc3Npb25zKSB7XG4gICAgICAgIHZhciBvcHRpb25zLFxuICAgICAgICAgICAgcGF0aCxcbiAgICAgICAgICAgIGxhc3RfbW9kaWZpZWQsXG4gICAgICAgICAgICBkYXRhLFxuICAgICAgICAgICAgcmVxdWVzdCxcbiAgICAgICAgICAgIF9hcmdzMTMgPSBhcmd1bWVudHM7XG4gICAgICAgIHJldHVybiBfcmVnZW5lcmF0b3IuZGVmYXVsdC53cmFwKGZ1bmN0aW9uIF9jYWxsZWUxMyQoX2NvbnRleHQxMykge1xuICAgICAgICAgIHdoaWxlICgxKSB7XG4gICAgICAgICAgICBzd2l0Y2ggKF9jb250ZXh0MTMucHJldiA9IF9jb250ZXh0MTMubmV4dCkge1xuICAgICAgICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICAgICAgb3B0aW9ucyA9IF9hcmdzMTMubGVuZ3RoID4gMSAmJiBfYXJnczEzWzFdICE9PSB1bmRlZmluZWQgPyBfYXJnczEzWzFdIDoge307XG5cbiAgICAgICAgICAgICAgICBpZiAoKDAsIF91dGlscy5pc09iamVjdCkocGVybWlzc2lvbnMpKSB7XG4gICAgICAgICAgICAgICAgICBfY29udGV4dDEzLm5leHQgPSAzO1xuICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQSBwZXJtaXNzaW9ucyBvYmplY3QgaXMgcmVxdWlyZWQuXCIpO1xuXG4gICAgICAgICAgICAgIGNhc2UgMzpcbiAgICAgICAgICAgICAgICBwYXRoID0gKDAsIF9lbmRwb2ludC5kZWZhdWx0KShcImJ1Y2tldFwiLCB0aGlzLm5hbWUpO1xuICAgICAgICAgICAgICAgIGxhc3RfbW9kaWZpZWQgPSBvcHRpb25zLmxhc3RfbW9kaWZpZWQ7XG4gICAgICAgICAgICAgICAgZGF0YSA9IHtcbiAgICAgICAgICAgICAgICAgIGxhc3RfbW9kaWZpZWQ6IGxhc3RfbW9kaWZpZWRcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIHJlcXVlc3QgPSByZXF1ZXN0cy51cGRhdGVSZXF1ZXN0KHBhdGgsIHtcbiAgICAgICAgICAgICAgICAgIGRhdGE6IGRhdGEsXG4gICAgICAgICAgICAgICAgICBwZXJtaXNzaW9uczogcGVybWlzc2lvbnNcbiAgICAgICAgICAgICAgICB9LCB7XG4gICAgICAgICAgICAgICAgICBoZWFkZXJzOiB0aGlzLl9nZXRIZWFkZXJzKG9wdGlvbnMpLFxuICAgICAgICAgICAgICAgICAgc2FmZTogdGhpcy5fZ2V0U2FmZShvcHRpb25zKVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDEzLmFicnVwdChcInJldHVyblwiLCB0aGlzLmNsaWVudC5leGVjdXRlKHJlcXVlc3QsIHtcbiAgICAgICAgICAgICAgICAgIHJldHJ5OiB0aGlzLl9nZXRSZXRyeShvcHRpb25zKVxuICAgICAgICAgICAgICAgIH0pKTtcblxuICAgICAgICAgICAgICBjYXNlIDg6XG4gICAgICAgICAgICAgIGNhc2UgXCJlbmRcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQxMy5zdG9wKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9LCBfY2FsbGVlMTMsIHRoaXMpO1xuICAgICAgfSkpO1xuXG4gICAgICByZXR1cm4gZnVuY3Rpb24gc2V0UGVybWlzc2lvbnMoX3g4KSB7XG4gICAgICAgIHJldHVybiBfc2V0UGVybWlzc2lvbnMuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgIH07XG4gICAgfSgpXG4gICAgLyoqXG4gICAgICogQXBwZW5kIHByaW5jaXBhbHMgdG8gdGhlIGJ1Y2tldCBwZXJtaXNzaW9ucy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gIHBlcm1pc3Npb25zICAgICAgICAgICAgIFRoZSBwZXJtaXNzaW9ucyBvYmplY3QuXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSAgW29wdGlvbnM9e31dICAgICAgICAgICAgVGhlIG9wdGlvbnMgb2JqZWN0XG4gICAgICogQHBhcmFtICB7Qm9vbGVhbn0gW29wdGlvbnMuc2FmZV0gICAgICAgICAgVGhlIHNhZmUgb3B0aW9uLlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gIFtvcHRpb25zLmhlYWRlcnNdICAgICAgIFRoZSBoZWFkZXJzIG9iamVjdCBvcHRpb24uXG4gICAgICogQHBhcmFtICB7TnVtYmVyfSAgW29wdGlvbnMucmV0cnk9MF0gICAgICAgTnVtYmVyIG9mIHJldHJpZXMgdG8gbWFrZVxuICAgICAqICAgICB3aGVuIGZhY2VkIHdpdGggdHJhbnNpZW50IGVycm9ycy5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICBbb3B0aW9ucy5sYXN0X21vZGlmaWVkXSBUaGUgbGFzdF9tb2RpZmllZCBvcHRpb24uXG4gICAgICogQHJldHVybiB7UHJvbWlzZTxPYmplY3QsIEVycm9yPn1cbiAgICAgKi9cblxuICB9LCB7XG4gICAga2V5OiBcImFkZFBlcm1pc3Npb25zXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciBfYWRkUGVybWlzc2lvbnMgPSAoMCwgX2FzeW5jVG9HZW5lcmF0b3IyLmRlZmF1bHQpKFxuICAgICAgLyojX19QVVJFX18qL1xuICAgICAgX3JlZ2VuZXJhdG9yLmRlZmF1bHQubWFyayhmdW5jdGlvbiBfY2FsbGVlMTQocGVybWlzc2lvbnMpIHtcbiAgICAgICAgdmFyIG9wdGlvbnMsXG4gICAgICAgICAgICBwYXRoLFxuICAgICAgICAgICAgbGFzdF9tb2RpZmllZCxcbiAgICAgICAgICAgIHJlcXVlc3QsXG4gICAgICAgICAgICBfYXJnczE0ID0gYXJndW1lbnRzO1xuICAgICAgICByZXR1cm4gX3JlZ2VuZXJhdG9yLmRlZmF1bHQud3JhcChmdW5jdGlvbiBfY2FsbGVlMTQkKF9jb250ZXh0MTQpIHtcbiAgICAgICAgICB3aGlsZSAoMSkge1xuICAgICAgICAgICAgc3dpdGNoIChfY29udGV4dDE0LnByZXYgPSBfY29udGV4dDE0Lm5leHQpIHtcbiAgICAgICAgICAgICAgY2FzZSAwOlxuICAgICAgICAgICAgICAgIG9wdGlvbnMgPSBfYXJnczE0Lmxlbmd0aCA+IDEgJiYgX2FyZ3MxNFsxXSAhPT0gdW5kZWZpbmVkID8gX2FyZ3MxNFsxXSA6IHt9O1xuXG4gICAgICAgICAgICAgICAgaWYgKCgwLCBfdXRpbHMuaXNPYmplY3QpKHBlcm1pc3Npb25zKSkge1xuICAgICAgICAgICAgICAgICAgX2NvbnRleHQxNC5uZXh0ID0gMztcbiAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkEgcGVybWlzc2lvbnMgb2JqZWN0IGlzIHJlcXVpcmVkLlwiKTtcblxuICAgICAgICAgICAgICBjYXNlIDM6XG4gICAgICAgICAgICAgICAgcGF0aCA9ICgwLCBfZW5kcG9pbnQuZGVmYXVsdCkoXCJidWNrZXRcIiwgdGhpcy5uYW1lKTtcbiAgICAgICAgICAgICAgICBsYXN0X21vZGlmaWVkID0gb3B0aW9ucy5sYXN0X21vZGlmaWVkO1xuICAgICAgICAgICAgICAgIHJlcXVlc3QgPSByZXF1ZXN0cy5qc29uUGF0Y2hQZXJtaXNzaW9uc1JlcXVlc3QocGF0aCwgcGVybWlzc2lvbnMsIFwiYWRkXCIsIHtcbiAgICAgICAgICAgICAgICAgIGxhc3RfbW9kaWZpZWQ6IGxhc3RfbW9kaWZpZWQsXG4gICAgICAgICAgICAgICAgICBoZWFkZXJzOiB0aGlzLl9nZXRIZWFkZXJzKG9wdGlvbnMpLFxuICAgICAgICAgICAgICAgICAgc2FmZTogdGhpcy5fZ2V0U2FmZShvcHRpb25zKVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDE0LmFicnVwdChcInJldHVyblwiLCB0aGlzLmNsaWVudC5leGVjdXRlKHJlcXVlc3QsIHtcbiAgICAgICAgICAgICAgICAgIHJldHJ5OiB0aGlzLl9nZXRSZXRyeShvcHRpb25zKVxuICAgICAgICAgICAgICAgIH0pKTtcblxuICAgICAgICAgICAgICBjYXNlIDc6XG4gICAgICAgICAgICAgIGNhc2UgXCJlbmRcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQxNC5zdG9wKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9LCBfY2FsbGVlMTQsIHRoaXMpO1xuICAgICAgfSkpO1xuXG4gICAgICByZXR1cm4gZnVuY3Rpb24gYWRkUGVybWlzc2lvbnMoX3g5KSB7XG4gICAgICAgIHJldHVybiBfYWRkUGVybWlzc2lvbnMuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgIH07XG4gICAgfSgpXG4gICAgLyoqXG4gICAgICogUmVtb3ZlIHByaW5jaXBhbHMgZnJvbSB0aGUgYnVja2V0IHBlcm1pc3Npb25zLlxuICAgICAqXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSAgcGVybWlzc2lvbnMgICAgICAgICAgICAgVGhlIHBlcm1pc3Npb25zIG9iamVjdC5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICBbb3B0aW9ucz17fV0gICAgICAgICAgICBUaGUgb3B0aW9ucyBvYmplY3RcbiAgICAgKiBAcGFyYW0gIHtCb29sZWFufSBbb3B0aW9ucy5zYWZlXSAgICAgICAgICBUaGUgc2FmZSBvcHRpb24uXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSAgW29wdGlvbnMuaGVhZGVyc10gICAgICAgVGhlIGhlYWRlcnMgb2JqZWN0IG9wdGlvbi5cbiAgICAgKiBAcGFyYW0gIHtOdW1iZXJ9ICBbb3B0aW9ucy5yZXRyeT0wXSAgICAgICBOdW1iZXIgb2YgcmV0cmllcyB0byBtYWtlXG4gICAgICogICAgIHdoZW4gZmFjZWQgd2l0aCB0cmFuc2llbnQgZXJyb3JzLlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gIFtvcHRpb25zLmxhc3RfbW9kaWZpZWRdIFRoZSBsYXN0X21vZGlmaWVkIG9wdGlvbi5cbiAgICAgKiBAcmV0dXJuIHtQcm9taXNlPE9iamVjdCwgRXJyb3I+fVxuICAgICAqL1xuXG4gIH0sIHtcbiAgICBrZXk6IFwicmVtb3ZlUGVybWlzc2lvbnNcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gKCkge1xuICAgICAgdmFyIF9yZW1vdmVQZXJtaXNzaW9ucyA9ICgwLCBfYXN5bmNUb0dlbmVyYXRvcjIuZGVmYXVsdCkoXG4gICAgICAvKiNfX1BVUkVfXyovXG4gICAgICBfcmVnZW5lcmF0b3IuZGVmYXVsdC5tYXJrKGZ1bmN0aW9uIF9jYWxsZWUxNShwZXJtaXNzaW9ucykge1xuICAgICAgICB2YXIgb3B0aW9ucyxcbiAgICAgICAgICAgIHBhdGgsXG4gICAgICAgICAgICBsYXN0X21vZGlmaWVkLFxuICAgICAgICAgICAgcmVxdWVzdCxcbiAgICAgICAgICAgIF9hcmdzMTUgPSBhcmd1bWVudHM7XG4gICAgICAgIHJldHVybiBfcmVnZW5lcmF0b3IuZGVmYXVsdC53cmFwKGZ1bmN0aW9uIF9jYWxsZWUxNSQoX2NvbnRleHQxNSkge1xuICAgICAgICAgIHdoaWxlICgxKSB7XG4gICAgICAgICAgICBzd2l0Y2ggKF9jb250ZXh0MTUucHJldiA9IF9jb250ZXh0MTUubmV4dCkge1xuICAgICAgICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICAgICAgb3B0aW9ucyA9IF9hcmdzMTUubGVuZ3RoID4gMSAmJiBfYXJnczE1WzFdICE9PSB1bmRlZmluZWQgPyBfYXJnczE1WzFdIDoge307XG5cbiAgICAgICAgICAgICAgICBpZiAoKDAsIF91dGlscy5pc09iamVjdCkocGVybWlzc2lvbnMpKSB7XG4gICAgICAgICAgICAgICAgICBfY29udGV4dDE1Lm5leHQgPSAzO1xuICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQSBwZXJtaXNzaW9ucyBvYmplY3QgaXMgcmVxdWlyZWQuXCIpO1xuXG4gICAgICAgICAgICAgIGNhc2UgMzpcbiAgICAgICAgICAgICAgICBwYXRoID0gKDAsIF9lbmRwb2ludC5kZWZhdWx0KShcImJ1Y2tldFwiLCB0aGlzLm5hbWUpO1xuICAgICAgICAgICAgICAgIGxhc3RfbW9kaWZpZWQgPSBvcHRpb25zLmxhc3RfbW9kaWZpZWQ7XG4gICAgICAgICAgICAgICAgcmVxdWVzdCA9IHJlcXVlc3RzLmpzb25QYXRjaFBlcm1pc3Npb25zUmVxdWVzdChwYXRoLCBwZXJtaXNzaW9ucywgXCJyZW1vdmVcIiwge1xuICAgICAgICAgICAgICAgICAgbGFzdF9tb2RpZmllZDogbGFzdF9tb2RpZmllZCxcbiAgICAgICAgICAgICAgICAgIGhlYWRlcnM6IHRoaXMuX2dldEhlYWRlcnMob3B0aW9ucyksXG4gICAgICAgICAgICAgICAgICBzYWZlOiB0aGlzLl9nZXRTYWZlKG9wdGlvbnMpXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0MTUuYWJydXB0KFwicmV0dXJuXCIsIHRoaXMuY2xpZW50LmV4ZWN1dGUocmVxdWVzdCwge1xuICAgICAgICAgICAgICAgICAgcmV0cnk6IHRoaXMuX2dldFJldHJ5KG9wdGlvbnMpXG4gICAgICAgICAgICAgICAgfSkpO1xuXG4gICAgICAgICAgICAgIGNhc2UgNzpcbiAgICAgICAgICAgICAgY2FzZSBcImVuZFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDE1LnN0b3AoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0sIF9jYWxsZWUxNSwgdGhpcyk7XG4gICAgICB9KSk7XG5cbiAgICAgIHJldHVybiBmdW5jdGlvbiByZW1vdmVQZXJtaXNzaW9ucyhfeDEwKSB7XG4gICAgICAgIHJldHVybiBfcmVtb3ZlUGVybWlzc2lvbnMuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgIH07XG4gICAgfSgpXG4gICAgLyoqXG4gICAgICogUGVyZm9ybXMgYmF0Y2ggb3BlcmF0aW9ucyBhdCB0aGUgY3VycmVudCBidWNrZXQgbGV2ZWwuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gIHtGdW5jdGlvbn0gZm4gICAgICAgICAgICAgICAgICAgVGhlIGJhdGNoIG9wZXJhdGlvbiBmdW5jdGlvbi5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICAgW29wdGlvbnM9e31dICAgICAgICAgVGhlIG9wdGlvbnMgb2JqZWN0LlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gICBbb3B0aW9ucy5oZWFkZXJzXSAgICBUaGUgaGVhZGVycyBvYmplY3Qgb3B0aW9uLlxuICAgICAqIEBwYXJhbSAge0Jvb2xlYW59ICBbb3B0aW9ucy5zYWZlXSAgICAgICBUaGUgc2FmZSBvcHRpb24uXG4gICAgICogQHBhcmFtICB7TnVtYmVyfSAgIFtvcHRpb25zLnJldHJ5PTBdICAgIFRoZSByZXRyeSBvcHRpb24uXG4gICAgICogQHBhcmFtICB7Qm9vbGVhbn0gIFtvcHRpb25zLmFnZ3JlZ2F0ZV0gIFByb2R1Y2VzIGEgZ3JvdXBlZCByZXN1bHQgb2JqZWN0LlxuICAgICAqIEByZXR1cm4ge1Byb21pc2U8T2JqZWN0LCBFcnJvcj59XG4gICAgICovXG5cbiAgfSwge1xuICAgIGtleTogXCJiYXRjaFwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgX2JhdGNoID0gKDAsIF9hc3luY1RvR2VuZXJhdG9yMi5kZWZhdWx0KShcbiAgICAgIC8qI19fUFVSRV9fKi9cbiAgICAgIF9yZWdlbmVyYXRvci5kZWZhdWx0Lm1hcmsoZnVuY3Rpb24gX2NhbGxlZTE2KGZuKSB7XG4gICAgICAgIHZhciBvcHRpb25zLFxuICAgICAgICAgICAgX2FyZ3MxNiA9IGFyZ3VtZW50cztcbiAgICAgICAgcmV0dXJuIF9yZWdlbmVyYXRvci5kZWZhdWx0LndyYXAoZnVuY3Rpb24gX2NhbGxlZTE2JChfY29udGV4dDE2KSB7XG4gICAgICAgICAgd2hpbGUgKDEpIHtcbiAgICAgICAgICAgIHN3aXRjaCAoX2NvbnRleHQxNi5wcmV2ID0gX2NvbnRleHQxNi5uZXh0KSB7XG4gICAgICAgICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgICAgICBvcHRpb25zID0gX2FyZ3MxNi5sZW5ndGggPiAxICYmIF9hcmdzMTZbMV0gIT09IHVuZGVmaW5lZCA/IF9hcmdzMTZbMV0gOiB7fTtcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQxNi5hYnJ1cHQoXCJyZXR1cm5cIiwgdGhpcy5jbGllbnQuYmF0Y2goZm4sIHtcbiAgICAgICAgICAgICAgICAgIGJ1Y2tldDogdGhpcy5uYW1lLFxuICAgICAgICAgICAgICAgICAgaGVhZGVyczogdGhpcy5fZ2V0SGVhZGVycyhvcHRpb25zKSxcbiAgICAgICAgICAgICAgICAgIHJldHJ5OiB0aGlzLl9nZXRSZXRyeShvcHRpb25zKSxcbiAgICAgICAgICAgICAgICAgIHNhZmU6IHRoaXMuX2dldFNhZmUob3B0aW9ucyksXG4gICAgICAgICAgICAgICAgICBhZ2dyZWdhdGU6ICEhb3B0aW9ucy5hZ2dyZWdhdGVcbiAgICAgICAgICAgICAgICB9KSk7XG5cbiAgICAgICAgICAgICAgY2FzZSAyOlxuICAgICAgICAgICAgICBjYXNlIFwiZW5kXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0MTYuc3RvcCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSwgX2NhbGxlZTE2LCB0aGlzKTtcbiAgICAgIH0pKTtcblxuICAgICAgcmV0dXJuIGZ1bmN0aW9uIGJhdGNoKF94MTEpIHtcbiAgICAgICAgcmV0dXJuIF9iYXRjaC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgfTtcbiAgICB9KClcbiAgfV0pO1xuICByZXR1cm4gQnVja2V0O1xufSgpLCAoKDAsIF9hcHBseURlY29yYXRlZERlc2NyaXB0b3IyLmRlZmF1bHQpKF9jbGFzcy5wcm90b3R5cGUsIFwibGlzdEhpc3RvcnlcIiwgW19kZWNdLCBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKF9jbGFzcy5wcm90b3R5cGUsIFwibGlzdEhpc3RvcnlcIiksIF9jbGFzcy5wcm90b3R5cGUpKSwgX2NsYXNzKSk7XG5leHBvcnRzLmRlZmF1bHQgPSBCdWNrZXQ7IiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbnZhciBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0ID0gcmVxdWlyZShcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvaW50ZXJvcFJlcXVpcmVEZWZhdWx0XCIpO1xuXG52YXIgX2ludGVyb3BSZXF1aXJlV2lsZGNhcmQgPSByZXF1aXJlKFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9pbnRlcm9wUmVxdWlyZVdpbGRjYXJkXCIpO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcbiAgdmFsdWU6IHRydWVcbn0pO1xuZXhwb3J0cy5kZWZhdWx0ID0gdm9pZCAwO1xuXG52YXIgX3NsaWNlZFRvQXJyYXkyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9zbGljZWRUb0FycmF5XCIpKTtcblxudmFyIF9yZWdlbmVyYXRvciA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIkBiYWJlbC9ydW50aW1lL3JlZ2VuZXJhdG9yXCIpKTtcblxudmFyIF9hc3luY1RvR2VuZXJhdG9yMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvYXN5bmNUb0dlbmVyYXRvclwiKSk7XG5cbnZhciBfb2JqZWN0U3ByZWFkMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvb2JqZWN0U3ByZWFkXCIpKTtcblxudmFyIF9jbGFzc0NhbGxDaGVjazIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KHJlcXVpcmUoXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2NsYXNzQ2FsbENoZWNrXCIpKTtcblxudmFyIF9jcmVhdGVDbGFzczIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KHJlcXVpcmUoXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2NyZWF0ZUNsYXNzXCIpKTtcblxudmFyIF9hcHBseURlY29yYXRlZERlc2NyaXB0b3IyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9hcHBseURlY29yYXRlZERlc2NyaXB0b3JcIikpO1xuXG52YXIgX3V1aWQgPSByZXF1aXJlKFwidXVpZFwiKTtcblxudmFyIF91dGlscyA9IHJlcXVpcmUoXCIuL3V0aWxzXCIpO1xuXG52YXIgcmVxdWVzdHMgPSBfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZChyZXF1aXJlKFwiLi9yZXF1ZXN0c1wiKSk7XG5cbnZhciBfZW5kcG9pbnQgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KHJlcXVpcmUoXCIuL2VuZHBvaW50XCIpKTtcblxudmFyIF9kZWMsIF9kZWMyLCBfZGVjMywgX2NsYXNzO1xuXG4vKipcbiAqIEFic3RyYWN0IHJlcHJlc2VudGF0aW9uIG9mIGEgc2VsZWN0ZWQgY29sbGVjdGlvbi5cbiAqXG4gKi9cbnZhciBDb2xsZWN0aW9uID0gKF9kZWMgPSAoMCwgX3V0aWxzLmNhcGFibGUpKFtcImF0dGFjaG1lbnRzXCJdKSwgX2RlYzIgPSAoMCwgX3V0aWxzLmNhcGFibGUpKFtcImF0dGFjaG1lbnRzXCJdKSwgX2RlYzMgPSAoMCwgX3V0aWxzLmNhcGFibGUpKFtcImhpc3RvcnlcIl0pLCAoX2NsYXNzID1cbi8qI19fUFVSRV9fKi9cbmZ1bmN0aW9uICgpIHtcbiAgLyoqXG4gICAqIENvbnN0cnVjdG9yLlxuICAgKlxuICAgKiBAcGFyYW0gIHtLaW50b0NsaWVudH0gIGNsaWVudCAgICAgICAgICAgIFRoZSBjbGllbnQgaW5zdGFuY2UuXG4gICAqIEBwYXJhbSAge0J1Y2tldH0gICAgICAgYnVja2V0ICAgICAgICAgICAgVGhlIGJ1Y2tldCBpbnN0YW5jZS5cbiAgICogQHBhcmFtICB7U3RyaW5nfSAgICAgICBuYW1lICAgICAgICAgICAgICBUaGUgY29sbGVjdGlvbiBuYW1lLlxuICAgKiBAcGFyYW0gIHtPYmplY3R9ICAgICAgIFtvcHRpb25zPXt9XSAgICAgIFRoZSBvcHRpb25zIG9iamVjdC5cbiAgICogQHBhcmFtICB7T2JqZWN0fSAgICAgICBbb3B0aW9ucy5oZWFkZXJzXSBUaGUgaGVhZGVycyBvYmplY3Qgb3B0aW9uLlxuICAgKiBAcGFyYW0gIHtCb29sZWFufSAgICAgIFtvcHRpb25zLnNhZmVdICAgIFRoZSBzYWZlIG9wdGlvbi5cbiAgICogQHBhcmFtICB7TnVtYmVyfSAgICAgICBbb3B0aW9ucy5yZXRyeV0gICBUaGUgcmV0cnkgb3B0aW9uLlxuICAgKiBAcGFyYW0gIHtCb29sZWFufSAgICAgIFtvcHRpb25zLmJhdGNoXSAgIChQcml2YXRlKSBXaGV0aGVyIHRoaXNcbiAgICogICAgIENvbGxlY3Rpb24gaXMgb3BlcmF0aW5nIGFzIHBhcnQgb2YgYSBiYXRjaC5cbiAgICovXG4gIGZ1bmN0aW9uIENvbGxlY3Rpb24oY2xpZW50LCBidWNrZXQsIG5hbWUpIHtcbiAgICB2YXIgb3B0aW9ucyA9IGFyZ3VtZW50cy5sZW5ndGggPiAzICYmIGFyZ3VtZW50c1szXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzNdIDoge307XG4gICAgKDAsIF9jbGFzc0NhbGxDaGVjazIuZGVmYXVsdCkodGhpcywgQ29sbGVjdGlvbik7XG5cbiAgICAvKipcbiAgICAgKiBAaWdub3JlXG4gICAgICovXG4gICAgdGhpcy5jbGllbnQgPSBjbGllbnQ7XG4gICAgLyoqXG4gICAgICogQGlnbm9yZVxuICAgICAqL1xuXG4gICAgdGhpcy5idWNrZXQgPSBidWNrZXQ7XG4gICAgLyoqXG4gICAgICogVGhlIGNvbGxlY3Rpb24gbmFtZS5cbiAgICAgKiBAdHlwZSB7U3RyaW5nfVxuICAgICAqL1xuXG4gICAgdGhpcy5uYW1lID0gbmFtZTtcbiAgICAvKipcbiAgICAgKiBAaWdub3JlXG4gICAgICovXG5cbiAgICB0aGlzLl9pc0JhdGNoID0gISFvcHRpb25zLmJhdGNoO1xuICAgIC8qKlxuICAgICAqIEBpZ25vcmVcbiAgICAgKi9cblxuICAgIHRoaXMuX3JldHJ5ID0gb3B0aW9ucy5yZXRyeSB8fCAwO1xuICAgIHRoaXMuX3NhZmUgPSAhIW9wdGlvbnMuc2FmZTsgLy8gRklYTUU6IFRoaXMgaXMga2luZCBvZiB1Z2x5OyBzaG91bGRuJ3QgdGhlIGJ1Y2tldCBiZSByZXNwb25zaWJsZVxuICAgIC8vIGZvciBkb2luZyB0aGUgbWVyZ2U/XG5cbiAgICB0aGlzLl9oZWFkZXJzID0gKDAsIF9vYmplY3RTcHJlYWQyLmRlZmF1bHQpKHt9LCB0aGlzLmJ1Y2tldC5faGVhZGVycywgb3B0aW9ucy5oZWFkZXJzKTtcbiAgfVxuICAvKipcbiAgICogR2V0IHRoZSB2YWx1ZSBvZiBcImhlYWRlcnNcIiBmb3IgYSBnaXZlbiByZXF1ZXN0LCBtZXJnaW5nIHRoZVxuICAgKiBwZXItcmVxdWVzdCBoZWFkZXJzIHdpdGggb3VyIG93biBcImRlZmF1bHRcIiBoZWFkZXJzLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cblxuXG4gICgwLCBfY3JlYXRlQ2xhc3MyLmRlZmF1bHQpKENvbGxlY3Rpb24sIFt7XG4gICAga2V5OiBcIl9nZXRIZWFkZXJzXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIF9nZXRIZWFkZXJzKG9wdGlvbnMpIHtcbiAgICAgIHJldHVybiAoMCwgX29iamVjdFNwcmVhZDIuZGVmYXVsdCkoe30sIHRoaXMuX2hlYWRlcnMsIG9wdGlvbnMuaGVhZGVycyk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgdmFsdWUgb2YgXCJzYWZlXCIgZm9yIGEgZ2l2ZW4gcmVxdWVzdCwgdXNpbmcgdGhlXG4gICAgICogcGVyLXJlcXVlc3Qgb3B0aW9uIGlmIHByZXNlbnQgb3IgZmFsbGluZyBiYWNrIHRvIG91ciBkZWZhdWx0XG4gICAgICogb3RoZXJ3aXNlLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb3B0aW9ucyBUaGUgb3B0aW9ucyBmb3IgYSByZXF1ZXN0LlxuICAgICAqIEByZXR1cm5zIHtCb29sZWFufVxuICAgICAqL1xuXG4gIH0sIHtcbiAgICBrZXk6IFwiX2dldFNhZmVcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gX2dldFNhZmUob3B0aW9ucykge1xuICAgICAgcmV0dXJuICgwLCBfb2JqZWN0U3ByZWFkMi5kZWZhdWx0KSh7XG4gICAgICAgIHNhZmU6IHRoaXMuX3NhZmVcbiAgICAgIH0sIG9wdGlvbnMpLnNhZmU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEFzIF9nZXRTYWZlLCBidXQgZm9yIFwicmV0cnlcIi5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG5cbiAgfSwge1xuICAgIGtleTogXCJfZ2V0UmV0cnlcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gX2dldFJldHJ5KG9wdGlvbnMpIHtcbiAgICAgIHJldHVybiAoMCwgX29iamVjdFNwcmVhZDIuZGVmYXVsdCkoe1xuICAgICAgICByZXRyeTogdGhpcy5fcmV0cnlcbiAgICAgIH0sIG9wdGlvbnMpLnJldHJ5O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXRyaWV2ZXMgdGhlIHRvdGFsIG51bWJlciBvZiByZWNvcmRzIGluIHRoaXMgY29sbGVjdGlvbi5cbiAgICAgKlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gW29wdGlvbnM9e31dICAgICAgVGhlIG9wdGlvbnMgb2JqZWN0LlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gW29wdGlvbnMuaGVhZGVyc10gVGhlIGhlYWRlcnMgb2JqZWN0IG9wdGlvbi5cbiAgICAgKiBAcGFyYW0gIHtOdW1iZXJ9IFtvcHRpb25zLnJldHJ5PTBdIE51bWJlciBvZiByZXRyaWVzIHRvIG1ha2VcbiAgICAgKiAgICAgd2hlbiBmYWNlZCB3aXRoIHRyYW5zaWVudCBlcnJvcnMuXG4gICAgICogQHJldHVybiB7UHJvbWlzZTxOdW1iZXIsIEVycm9yPn1cbiAgICAgKi9cblxuICB9LCB7XG4gICAga2V5OiBcImdldFRvdGFsUmVjb3Jkc1wiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgX2dldFRvdGFsUmVjb3JkcyA9ICgwLCBfYXN5bmNUb0dlbmVyYXRvcjIuZGVmYXVsdCkoXG4gICAgICAvKiNfX1BVUkVfXyovXG4gICAgICBfcmVnZW5lcmF0b3IuZGVmYXVsdC5tYXJrKGZ1bmN0aW9uIF9jYWxsZWUoKSB7XG4gICAgICAgIHZhciBvcHRpb25zLFxuICAgICAgICAgICAgcGF0aCxcbiAgICAgICAgICAgIHJlcXVlc3QsXG4gICAgICAgICAgICBfcmVmLFxuICAgICAgICAgICAgaGVhZGVycyxcbiAgICAgICAgICAgIF9hcmdzID0gYXJndW1lbnRzO1xuXG4gICAgICAgIHJldHVybiBfcmVnZW5lcmF0b3IuZGVmYXVsdC53cmFwKGZ1bmN0aW9uIF9jYWxsZWUkKF9jb250ZXh0KSB7XG4gICAgICAgICAgd2hpbGUgKDEpIHtcbiAgICAgICAgICAgIHN3aXRjaCAoX2NvbnRleHQucHJldiA9IF9jb250ZXh0Lm5leHQpIHtcbiAgICAgICAgICAgICAgY2FzZSAwOlxuICAgICAgICAgICAgICAgIG9wdGlvbnMgPSBfYXJncy5sZW5ndGggPiAwICYmIF9hcmdzWzBdICE9PSB1bmRlZmluZWQgPyBfYXJnc1swXSA6IHt9O1xuICAgICAgICAgICAgICAgIHBhdGggPSAoMCwgX2VuZHBvaW50LmRlZmF1bHQpKFwicmVjb3JkXCIsIHRoaXMuYnVja2V0Lm5hbWUsIHRoaXMubmFtZSk7XG4gICAgICAgICAgICAgICAgcmVxdWVzdCA9IHtcbiAgICAgICAgICAgICAgICAgIGhlYWRlcnM6IHRoaXMuX2dldEhlYWRlcnMob3B0aW9ucyksXG4gICAgICAgICAgICAgICAgICBwYXRoOiBwYXRoLFxuICAgICAgICAgICAgICAgICAgbWV0aG9kOiBcIkhFQURcIlxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgX2NvbnRleHQubmV4dCA9IDU7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuY2xpZW50LmV4ZWN1dGUocmVxdWVzdCwge1xuICAgICAgICAgICAgICAgICAgcmF3OiB0cnVlLFxuICAgICAgICAgICAgICAgICAgcmV0cnk6IHRoaXMuX2dldFJldHJ5KG9wdGlvbnMpXG4gICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgY2FzZSA1OlxuICAgICAgICAgICAgICAgIF9yZWYgPSBfY29udGV4dC5zZW50O1xuICAgICAgICAgICAgICAgIGhlYWRlcnMgPSBfcmVmLmhlYWRlcnM7XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0LmFicnVwdChcInJldHVyblwiLCBwYXJzZUludChoZWFkZXJzLmdldChcIlRvdGFsLVJlY29yZHNcIiksIDEwKSk7XG5cbiAgICAgICAgICAgICAgY2FzZSA4OlxuICAgICAgICAgICAgICBjYXNlIFwiZW5kXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0LnN0b3AoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0sIF9jYWxsZWUsIHRoaXMpO1xuICAgICAgfSkpO1xuXG4gICAgICByZXR1cm4gZnVuY3Rpb24gZ2V0VG90YWxSZWNvcmRzKCkge1xuICAgICAgICByZXR1cm4gX2dldFRvdGFsUmVjb3Jkcy5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgfTtcbiAgICB9KClcbiAgICAvKipcbiAgICAgKiBSZXRyaWV2ZXMgY29sbGVjdGlvbiBkYXRhLlxuICAgICAqXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSBbb3B0aW9ucz17fV0gICAgICBUaGUgb3B0aW9ucyBvYmplY3QuXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSBbb3B0aW9ucy5oZWFkZXJzXSBUaGUgaGVhZGVycyBvYmplY3Qgb3B0aW9uLlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gW29wdGlvbnMucXVlcnldICAgUXVlcnkgcGFyYW1ldGVycyB0byBwYXNzIGluXG4gICAgICogICAgIHRoZSByZXF1ZXN0LiBUaGlzIG1pZ2h0IGJlIHVzZWZ1bCBmb3IgZmVhdHVyZXMgdGhhdCBhcmVuJ3RcbiAgICAgKiAgICAgeWV0IHN1cHBvcnRlZCBieSB0aGlzIGxpYnJhcnkuXG4gICAgICogQHBhcmFtICB7TnVtYmVyfSBbb3B0aW9ucy5yZXRyeT0wXSBOdW1iZXIgb2YgcmV0cmllcyB0byBtYWtlXG4gICAgICogICAgIHdoZW4gZmFjZWQgd2l0aCB0cmFuc2llbnQgZXJyb3JzLlxuICAgICAqIEByZXR1cm4ge1Byb21pc2U8T2JqZWN0LCBFcnJvcj59XG4gICAgICovXG5cbiAgfSwge1xuICAgIGtleTogXCJnZXREYXRhXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciBfZ2V0RGF0YSA9ICgwLCBfYXN5bmNUb0dlbmVyYXRvcjIuZGVmYXVsdCkoXG4gICAgICAvKiNfX1BVUkVfXyovXG4gICAgICBfcmVnZW5lcmF0b3IuZGVmYXVsdC5tYXJrKGZ1bmN0aW9uIF9jYWxsZWUyKCkge1xuICAgICAgICB2YXIgb3B0aW9ucyxcbiAgICAgICAgICAgIHBhdGgsXG4gICAgICAgICAgICBxdWVyeXN0cmluZyxcbiAgICAgICAgICAgIHJlcXVlc3QsXG4gICAgICAgICAgICBfcmVmMixcbiAgICAgICAgICAgIGRhdGEsXG4gICAgICAgICAgICBfYXJnczIgPSBhcmd1bWVudHM7XG5cbiAgICAgICAgcmV0dXJuIF9yZWdlbmVyYXRvci5kZWZhdWx0LndyYXAoZnVuY3Rpb24gX2NhbGxlZTIkKF9jb250ZXh0Mikge1xuICAgICAgICAgIHdoaWxlICgxKSB7XG4gICAgICAgICAgICBzd2l0Y2ggKF9jb250ZXh0Mi5wcmV2ID0gX2NvbnRleHQyLm5leHQpIHtcbiAgICAgICAgICAgICAgY2FzZSAwOlxuICAgICAgICAgICAgICAgIG9wdGlvbnMgPSBfYXJnczIubGVuZ3RoID4gMCAmJiBfYXJnczJbMF0gIT09IHVuZGVmaW5lZCA/IF9hcmdzMlswXSA6IHt9O1xuICAgICAgICAgICAgICAgIHBhdGggPSAoMCwgX2VuZHBvaW50LmRlZmF1bHQpKFwiY29sbGVjdGlvblwiLCB0aGlzLmJ1Y2tldC5uYW1lLCB0aGlzLm5hbWUpO1xuXG4gICAgICAgICAgICAgICAgaWYgKG9wdGlvbnMucXVlcnkpIHtcbiAgICAgICAgICAgICAgICAgIHF1ZXJ5c3RyaW5nID0gKDAsIF91dGlscy5xc2lmeSkob3B0aW9ucy5xdWVyeSk7XG4gICAgICAgICAgICAgICAgICBwYXRoID0gcGF0aCArIFwiP1wiICsgcXVlcnlzdHJpbmc7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgcmVxdWVzdCA9IHtcbiAgICAgICAgICAgICAgICAgIGhlYWRlcnM6IHRoaXMuX2dldEhlYWRlcnMob3B0aW9ucyksXG4gICAgICAgICAgICAgICAgICBwYXRoOiBwYXRoXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBfY29udGV4dDIubmV4dCA9IDY7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuY2xpZW50LmV4ZWN1dGUocmVxdWVzdCwge1xuICAgICAgICAgICAgICAgICAgcmV0cnk6IHRoaXMuX2dldFJldHJ5KG9wdGlvbnMpXG4gICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgY2FzZSA2OlxuICAgICAgICAgICAgICAgIF9yZWYyID0gX2NvbnRleHQyLnNlbnQ7XG4gICAgICAgICAgICAgICAgZGF0YSA9IF9yZWYyLmRhdGE7XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0Mi5hYnJ1cHQoXCJyZXR1cm5cIiwgZGF0YSk7XG5cbiAgICAgICAgICAgICAgY2FzZSA5OlxuICAgICAgICAgICAgICBjYXNlIFwiZW5kXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0Mi5zdG9wKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9LCBfY2FsbGVlMiwgdGhpcyk7XG4gICAgICB9KSk7XG5cbiAgICAgIHJldHVybiBmdW5jdGlvbiBnZXREYXRhKCkge1xuICAgICAgICByZXR1cm4gX2dldERhdGEuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgIH07XG4gICAgfSgpXG4gICAgLyoqXG4gICAgICogU2V0IGNvbGxlY3Rpb24gZGF0YS5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICAgZGF0YSAgICAgICAgICAgICAgICAgICAgVGhlIGNvbGxlY3Rpb24gZGF0YSBvYmplY3QuXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSAgIFtvcHRpb25zPXt9XSAgICAgICAgICAgIFRoZSBvcHRpb25zIG9iamVjdC5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICAgW29wdGlvbnMuaGVhZGVyc10gICAgICAgVGhlIGhlYWRlcnMgb2JqZWN0IG9wdGlvbi5cbiAgICAgKiBAcGFyYW0gIHtOdW1iZXJ9ICAgW29wdGlvbnMucmV0cnk9MF0gICAgICAgTnVtYmVyIG9mIHJldHJpZXMgdG8gbWFrZVxuICAgICAqICAgICB3aGVuIGZhY2VkIHdpdGggdHJhbnNpZW50IGVycm9ycy5cbiAgICAgKiBAcGFyYW0gIHtCb29sZWFufSAgW29wdGlvbnMuc2FmZV0gICAgICAgICAgVGhlIHNhZmUgb3B0aW9uLlxuICAgICAqIEBwYXJhbSAge0Jvb2xlYW59ICBbb3B0aW9ucy5wYXRjaF0gICAgICAgICBUaGUgcGF0Y2ggb3B0aW9uLlxuICAgICAqIEBwYXJhbSAge051bWJlcn0gICBbb3B0aW9ucy5sYXN0X21vZGlmaWVkXSBUaGUgbGFzdF9tb2RpZmllZCBvcHRpb24uXG4gICAgICogQHJldHVybiB7UHJvbWlzZTxPYmplY3QsIEVycm9yPn1cbiAgICAgKi9cblxuICB9LCB7XG4gICAga2V5OiBcInNldERhdGFcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gKCkge1xuICAgICAgdmFyIF9zZXREYXRhID0gKDAsIF9hc3luY1RvR2VuZXJhdG9yMi5kZWZhdWx0KShcbiAgICAgIC8qI19fUFVSRV9fKi9cbiAgICAgIF9yZWdlbmVyYXRvci5kZWZhdWx0Lm1hcmsoZnVuY3Rpb24gX2NhbGxlZTMoZGF0YSkge1xuICAgICAgICB2YXIgb3B0aW9ucyxcbiAgICAgICAgICAgIHBhdGNoLFxuICAgICAgICAgICAgcGVybWlzc2lvbnMsXG4gICAgICAgICAgICBfZGF0YSRvcHRpb25zLFxuICAgICAgICAgICAgbGFzdF9tb2RpZmllZCxcbiAgICAgICAgICAgIHBhdGgsXG4gICAgICAgICAgICByZXF1ZXN0LFxuICAgICAgICAgICAgX2FyZ3MzID0gYXJndW1lbnRzO1xuXG4gICAgICAgIHJldHVybiBfcmVnZW5lcmF0b3IuZGVmYXVsdC53cmFwKGZ1bmN0aW9uIF9jYWxsZWUzJChfY29udGV4dDMpIHtcbiAgICAgICAgICB3aGlsZSAoMSkge1xuICAgICAgICAgICAgc3dpdGNoIChfY29udGV4dDMucHJldiA9IF9jb250ZXh0My5uZXh0KSB7XG4gICAgICAgICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgICAgICBvcHRpb25zID0gX2FyZ3MzLmxlbmd0aCA+IDEgJiYgX2FyZ3MzWzFdICE9PSB1bmRlZmluZWQgPyBfYXJnczNbMV0gOiB7fTtcblxuICAgICAgICAgICAgICAgIGlmICgoMCwgX3V0aWxzLmlzT2JqZWN0KShkYXRhKSkge1xuICAgICAgICAgICAgICAgICAgX2NvbnRleHQzLm5leHQgPSAzO1xuICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQSBjb2xsZWN0aW9uIG9iamVjdCBpcyByZXF1aXJlZC5cIik7XG5cbiAgICAgICAgICAgICAgY2FzZSAzOlxuICAgICAgICAgICAgICAgIHBhdGNoID0gb3B0aW9ucy5wYXRjaCwgcGVybWlzc2lvbnMgPSBvcHRpb25zLnBlcm1pc3Npb25zO1xuICAgICAgICAgICAgICAgIF9kYXRhJG9wdGlvbnMgPSAoMCwgX29iamVjdFNwcmVhZDIuZGVmYXVsdCkoe30sIGRhdGEsIG9wdGlvbnMpLCBsYXN0X21vZGlmaWVkID0gX2RhdGEkb3B0aW9ucy5sYXN0X21vZGlmaWVkO1xuICAgICAgICAgICAgICAgIHBhdGggPSAoMCwgX2VuZHBvaW50LmRlZmF1bHQpKFwiY29sbGVjdGlvblwiLCB0aGlzLmJ1Y2tldC5uYW1lLCB0aGlzLm5hbWUpO1xuICAgICAgICAgICAgICAgIHJlcXVlc3QgPSByZXF1ZXN0cy51cGRhdGVSZXF1ZXN0KHBhdGgsIHtcbiAgICAgICAgICAgICAgICAgIGRhdGE6IGRhdGEsXG4gICAgICAgICAgICAgICAgICBwZXJtaXNzaW9uczogcGVybWlzc2lvbnNcbiAgICAgICAgICAgICAgICB9LCB7XG4gICAgICAgICAgICAgICAgICBsYXN0X21vZGlmaWVkOiBsYXN0X21vZGlmaWVkLFxuICAgICAgICAgICAgICAgICAgcGF0Y2g6IHBhdGNoLFxuICAgICAgICAgICAgICAgICAgaGVhZGVyczogdGhpcy5fZ2V0SGVhZGVycyhvcHRpb25zKSxcbiAgICAgICAgICAgICAgICAgIHNhZmU6IHRoaXMuX2dldFNhZmUob3B0aW9ucylcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQzLmFicnVwdChcInJldHVyblwiLCB0aGlzLmNsaWVudC5leGVjdXRlKHJlcXVlc3QsIHtcbiAgICAgICAgICAgICAgICAgIHJldHJ5OiB0aGlzLl9nZXRSZXRyeShvcHRpb25zKVxuICAgICAgICAgICAgICAgIH0pKTtcblxuICAgICAgICAgICAgICBjYXNlIDg6XG4gICAgICAgICAgICAgIGNhc2UgXCJlbmRcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQzLnN0b3AoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0sIF9jYWxsZWUzLCB0aGlzKTtcbiAgICAgIH0pKTtcblxuICAgICAgcmV0dXJuIGZ1bmN0aW9uIHNldERhdGEoX3gpIHtcbiAgICAgICAgcmV0dXJuIF9zZXREYXRhLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICB9O1xuICAgIH0oKVxuICAgIC8qKlxuICAgICAqIFJldHJpZXZlcyB0aGUgbGlzdCBvZiBwZXJtaXNzaW9ucyBmb3IgdGhpcyBjb2xsZWN0aW9uLlxuICAgICAqXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSBbb3B0aW9ucz17fV0gICAgICBUaGUgb3B0aW9ucyBvYmplY3QuXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSBbb3B0aW9ucy5oZWFkZXJzXSBUaGUgaGVhZGVycyBvYmplY3Qgb3B0aW9uLlxuICAgICAqIEBwYXJhbSAge051bWJlcn0gW29wdGlvbnMucmV0cnk9MF0gTnVtYmVyIG9mIHJldHJpZXMgdG8gbWFrZVxuICAgICAqICAgICB3aGVuIGZhY2VkIHdpdGggdHJhbnNpZW50IGVycm9ycy5cbiAgICAgKiBAcmV0dXJuIHtQcm9taXNlPE9iamVjdCwgRXJyb3I+fVxuICAgICAqL1xuXG4gIH0sIHtcbiAgICBrZXk6IFwiZ2V0UGVybWlzc2lvbnNcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gKCkge1xuICAgICAgdmFyIF9nZXRQZXJtaXNzaW9ucyA9ICgwLCBfYXN5bmNUb0dlbmVyYXRvcjIuZGVmYXVsdCkoXG4gICAgICAvKiNfX1BVUkVfXyovXG4gICAgICBfcmVnZW5lcmF0b3IuZGVmYXVsdC5tYXJrKGZ1bmN0aW9uIF9jYWxsZWU0KCkge1xuICAgICAgICB2YXIgb3B0aW9ucyxcbiAgICAgICAgICAgIHBhdGgsXG4gICAgICAgICAgICByZXF1ZXN0LFxuICAgICAgICAgICAgX3JlZjMsXG4gICAgICAgICAgICBwZXJtaXNzaW9ucyxcbiAgICAgICAgICAgIF9hcmdzNCA9IGFyZ3VtZW50cztcblxuICAgICAgICByZXR1cm4gX3JlZ2VuZXJhdG9yLmRlZmF1bHQud3JhcChmdW5jdGlvbiBfY2FsbGVlNCQoX2NvbnRleHQ0KSB7XG4gICAgICAgICAgd2hpbGUgKDEpIHtcbiAgICAgICAgICAgIHN3aXRjaCAoX2NvbnRleHQ0LnByZXYgPSBfY29udGV4dDQubmV4dCkge1xuICAgICAgICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICAgICAgb3B0aW9ucyA9IF9hcmdzNC5sZW5ndGggPiAwICYmIF9hcmdzNFswXSAhPT0gdW5kZWZpbmVkID8gX2FyZ3M0WzBdIDoge307XG4gICAgICAgICAgICAgICAgcGF0aCA9ICgwLCBfZW5kcG9pbnQuZGVmYXVsdCkoXCJjb2xsZWN0aW9uXCIsIHRoaXMuYnVja2V0Lm5hbWUsIHRoaXMubmFtZSk7XG4gICAgICAgICAgICAgICAgcmVxdWVzdCA9IHtcbiAgICAgICAgICAgICAgICAgIGhlYWRlcnM6IHRoaXMuX2dldEhlYWRlcnMob3B0aW9ucyksXG4gICAgICAgICAgICAgICAgICBwYXRoOiBwYXRoXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBfY29udGV4dDQubmV4dCA9IDU7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuY2xpZW50LmV4ZWN1dGUocmVxdWVzdCwge1xuICAgICAgICAgICAgICAgICAgcmV0cnk6IHRoaXMuX2dldFJldHJ5KG9wdGlvbnMpXG4gICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgY2FzZSA1OlxuICAgICAgICAgICAgICAgIF9yZWYzID0gX2NvbnRleHQ0LnNlbnQ7XG4gICAgICAgICAgICAgICAgcGVybWlzc2lvbnMgPSBfcmVmMy5wZXJtaXNzaW9ucztcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQ0LmFicnVwdChcInJldHVyblwiLCBwZXJtaXNzaW9ucyk7XG5cbiAgICAgICAgICAgICAgY2FzZSA4OlxuICAgICAgICAgICAgICBjYXNlIFwiZW5kXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0NC5zdG9wKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9LCBfY2FsbGVlNCwgdGhpcyk7XG4gICAgICB9KSk7XG5cbiAgICAgIHJldHVybiBmdW5jdGlvbiBnZXRQZXJtaXNzaW9ucygpIHtcbiAgICAgICAgcmV0dXJuIF9nZXRQZXJtaXNzaW9ucy5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgfTtcbiAgICB9KClcbiAgICAvKipcbiAgICAgKiBSZXBsYWNlcyBhbGwgZXhpc3RpbmcgY29sbGVjdGlvbiBwZXJtaXNzaW9ucyB3aXRoIHRoZSBvbmVzIHByb3ZpZGVkLlxuICAgICAqXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSAgIHBlcm1pc3Npb25zICAgICAgICAgICAgIFRoZSBwZXJtaXNzaW9ucyBvYmplY3QuXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSAgIFtvcHRpb25zPXt9XSAgICAgICAgICAgIFRoZSBvcHRpb25zIG9iamVjdFxuICAgICAqIEBwYXJhbSAge09iamVjdH0gICBbb3B0aW9ucy5oZWFkZXJzXSAgICAgICBUaGUgaGVhZGVycyBvYmplY3Qgb3B0aW9uLlxuICAgICAqIEBwYXJhbSAge051bWJlcn0gICBbb3B0aW9ucy5yZXRyeT0wXSAgICAgICBOdW1iZXIgb2YgcmV0cmllcyB0byBtYWtlXG4gICAgICogICAgIHdoZW4gZmFjZWQgd2l0aCB0cmFuc2llbnQgZXJyb3JzLlxuICAgICAqIEBwYXJhbSAge0Jvb2xlYW59ICBbb3B0aW9ucy5zYWZlXSAgICAgICAgICBUaGUgc2FmZSBvcHRpb24uXG4gICAgICogQHBhcmFtICB7TnVtYmVyfSAgIFtvcHRpb25zLmxhc3RfbW9kaWZpZWRdIFRoZSBsYXN0X21vZGlmaWVkIG9wdGlvbi5cbiAgICAgKiBAcmV0dXJuIHtQcm9taXNlPE9iamVjdCwgRXJyb3I+fVxuICAgICAqL1xuXG4gIH0sIHtcbiAgICBrZXk6IFwic2V0UGVybWlzc2lvbnNcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gKCkge1xuICAgICAgdmFyIF9zZXRQZXJtaXNzaW9ucyA9ICgwLCBfYXN5bmNUb0dlbmVyYXRvcjIuZGVmYXVsdCkoXG4gICAgICAvKiNfX1BVUkVfXyovXG4gICAgICBfcmVnZW5lcmF0b3IuZGVmYXVsdC5tYXJrKGZ1bmN0aW9uIF9jYWxsZWU1KHBlcm1pc3Npb25zKSB7XG4gICAgICAgIHZhciBvcHRpb25zLFxuICAgICAgICAgICAgcGF0aCxcbiAgICAgICAgICAgIGRhdGEsXG4gICAgICAgICAgICByZXF1ZXN0LFxuICAgICAgICAgICAgX2FyZ3M1ID0gYXJndW1lbnRzO1xuICAgICAgICByZXR1cm4gX3JlZ2VuZXJhdG9yLmRlZmF1bHQud3JhcChmdW5jdGlvbiBfY2FsbGVlNSQoX2NvbnRleHQ1KSB7XG4gICAgICAgICAgd2hpbGUgKDEpIHtcbiAgICAgICAgICAgIHN3aXRjaCAoX2NvbnRleHQ1LnByZXYgPSBfY29udGV4dDUubmV4dCkge1xuICAgICAgICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICAgICAgb3B0aW9ucyA9IF9hcmdzNS5sZW5ndGggPiAxICYmIF9hcmdzNVsxXSAhPT0gdW5kZWZpbmVkID8gX2FyZ3M1WzFdIDoge307XG5cbiAgICAgICAgICAgICAgICBpZiAoKDAsIF91dGlscy5pc09iamVjdCkocGVybWlzc2lvbnMpKSB7XG4gICAgICAgICAgICAgICAgICBfY29udGV4dDUubmV4dCA9IDM7XG4gICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJBIHBlcm1pc3Npb25zIG9iamVjdCBpcyByZXF1aXJlZC5cIik7XG5cbiAgICAgICAgICAgICAgY2FzZSAzOlxuICAgICAgICAgICAgICAgIHBhdGggPSAoMCwgX2VuZHBvaW50LmRlZmF1bHQpKFwiY29sbGVjdGlvblwiLCB0aGlzLmJ1Y2tldC5uYW1lLCB0aGlzLm5hbWUpO1xuICAgICAgICAgICAgICAgIGRhdGEgPSB7XG4gICAgICAgICAgICAgICAgICBsYXN0X21vZGlmaWVkOiBvcHRpb25zLmxhc3RfbW9kaWZpZWRcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIHJlcXVlc3QgPSByZXF1ZXN0cy51cGRhdGVSZXF1ZXN0KHBhdGgsIHtcbiAgICAgICAgICAgICAgICAgIGRhdGE6IGRhdGEsXG4gICAgICAgICAgICAgICAgICBwZXJtaXNzaW9uczogcGVybWlzc2lvbnNcbiAgICAgICAgICAgICAgICB9LCB7XG4gICAgICAgICAgICAgICAgICBoZWFkZXJzOiB0aGlzLl9nZXRIZWFkZXJzKG9wdGlvbnMpLFxuICAgICAgICAgICAgICAgICAgc2FmZTogdGhpcy5fZ2V0U2FmZShvcHRpb25zKVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDUuYWJydXB0KFwicmV0dXJuXCIsIHRoaXMuY2xpZW50LmV4ZWN1dGUocmVxdWVzdCwge1xuICAgICAgICAgICAgICAgICAgcmV0cnk6IHRoaXMuX2dldFJldHJ5KG9wdGlvbnMpXG4gICAgICAgICAgICAgICAgfSkpO1xuXG4gICAgICAgICAgICAgIGNhc2UgNzpcbiAgICAgICAgICAgICAgY2FzZSBcImVuZFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDUuc3RvcCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSwgX2NhbGxlZTUsIHRoaXMpO1xuICAgICAgfSkpO1xuXG4gICAgICByZXR1cm4gZnVuY3Rpb24gc2V0UGVybWlzc2lvbnMoX3gyKSB7XG4gICAgICAgIHJldHVybiBfc2V0UGVybWlzc2lvbnMuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgIH07XG4gICAgfSgpXG4gICAgLyoqXG4gICAgICogQXBwZW5kIHByaW5jaXBhbHMgdG8gdGhlIGNvbGxlY3Rpb24gcGVybWlzc2lvbnMuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICBwZXJtaXNzaW9ucyAgICAgICAgICAgICBUaGUgcGVybWlzc2lvbnMgb2JqZWN0LlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gIFtvcHRpb25zPXt9XSAgICAgICAgICAgIFRoZSBvcHRpb25zIG9iamVjdFxuICAgICAqIEBwYXJhbSAge0Jvb2xlYW59IFtvcHRpb25zLnNhZmVdICAgICAgICAgIFRoZSBzYWZlIG9wdGlvbi5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICBbb3B0aW9ucy5oZWFkZXJzXSAgICAgICBUaGUgaGVhZGVycyBvYmplY3Qgb3B0aW9uLlxuICAgICAqIEBwYXJhbSAge051bWJlcn0gIFtvcHRpb25zLnJldHJ5PTBdICAgICAgIE51bWJlciBvZiByZXRyaWVzIHRvIG1ha2VcbiAgICAgKiAgICAgd2hlbiBmYWNlZCB3aXRoIHRyYW5zaWVudCBlcnJvcnMuXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSAgW29wdGlvbnMubGFzdF9tb2RpZmllZF0gVGhlIGxhc3RfbW9kaWZpZWQgb3B0aW9uLlxuICAgICAqIEByZXR1cm4ge1Byb21pc2U8T2JqZWN0LCBFcnJvcj59XG4gICAgICovXG5cbiAgfSwge1xuICAgIGtleTogXCJhZGRQZXJtaXNzaW9uc1wiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgX2FkZFBlcm1pc3Npb25zID0gKDAsIF9hc3luY1RvR2VuZXJhdG9yMi5kZWZhdWx0KShcbiAgICAgIC8qI19fUFVSRV9fKi9cbiAgICAgIF9yZWdlbmVyYXRvci5kZWZhdWx0Lm1hcmsoZnVuY3Rpb24gX2NhbGxlZTYocGVybWlzc2lvbnMpIHtcbiAgICAgICAgdmFyIG9wdGlvbnMsXG4gICAgICAgICAgICBwYXRoLFxuICAgICAgICAgICAgbGFzdF9tb2RpZmllZCxcbiAgICAgICAgICAgIHJlcXVlc3QsXG4gICAgICAgICAgICBfYXJnczYgPSBhcmd1bWVudHM7XG4gICAgICAgIHJldHVybiBfcmVnZW5lcmF0b3IuZGVmYXVsdC53cmFwKGZ1bmN0aW9uIF9jYWxsZWU2JChfY29udGV4dDYpIHtcbiAgICAgICAgICB3aGlsZSAoMSkge1xuICAgICAgICAgICAgc3dpdGNoIChfY29udGV4dDYucHJldiA9IF9jb250ZXh0Ni5uZXh0KSB7XG4gICAgICAgICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgICAgICBvcHRpb25zID0gX2FyZ3M2Lmxlbmd0aCA+IDEgJiYgX2FyZ3M2WzFdICE9PSB1bmRlZmluZWQgPyBfYXJnczZbMV0gOiB7fTtcblxuICAgICAgICAgICAgICAgIGlmICgoMCwgX3V0aWxzLmlzT2JqZWN0KShwZXJtaXNzaW9ucykpIHtcbiAgICAgICAgICAgICAgICAgIF9jb250ZXh0Ni5uZXh0ID0gMztcbiAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkEgcGVybWlzc2lvbnMgb2JqZWN0IGlzIHJlcXVpcmVkLlwiKTtcblxuICAgICAgICAgICAgICBjYXNlIDM6XG4gICAgICAgICAgICAgICAgcGF0aCA9ICgwLCBfZW5kcG9pbnQuZGVmYXVsdCkoXCJjb2xsZWN0aW9uXCIsIHRoaXMuYnVja2V0Lm5hbWUsIHRoaXMubmFtZSk7XG4gICAgICAgICAgICAgICAgbGFzdF9tb2RpZmllZCA9IG9wdGlvbnMubGFzdF9tb2RpZmllZDtcbiAgICAgICAgICAgICAgICByZXF1ZXN0ID0gcmVxdWVzdHMuanNvblBhdGNoUGVybWlzc2lvbnNSZXF1ZXN0KHBhdGgsIHBlcm1pc3Npb25zLCBcImFkZFwiLCB7XG4gICAgICAgICAgICAgICAgICBsYXN0X21vZGlmaWVkOiBsYXN0X21vZGlmaWVkLFxuICAgICAgICAgICAgICAgICAgaGVhZGVyczogdGhpcy5fZ2V0SGVhZGVycyhvcHRpb25zKSxcbiAgICAgICAgICAgICAgICAgIHNhZmU6IHRoaXMuX2dldFNhZmUob3B0aW9ucylcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQ2LmFicnVwdChcInJldHVyblwiLCB0aGlzLmNsaWVudC5leGVjdXRlKHJlcXVlc3QsIHtcbiAgICAgICAgICAgICAgICAgIHJldHJ5OiB0aGlzLl9nZXRSZXRyeShvcHRpb25zKVxuICAgICAgICAgICAgICAgIH0pKTtcblxuICAgICAgICAgICAgICBjYXNlIDc6XG4gICAgICAgICAgICAgIGNhc2UgXCJlbmRcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQ2LnN0b3AoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0sIF9jYWxsZWU2LCB0aGlzKTtcbiAgICAgIH0pKTtcblxuICAgICAgcmV0dXJuIGZ1bmN0aW9uIGFkZFBlcm1pc3Npb25zKF94Mykge1xuICAgICAgICByZXR1cm4gX2FkZFBlcm1pc3Npb25zLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICB9O1xuICAgIH0oKVxuICAgIC8qKlxuICAgICAqIFJlbW92ZSBwcmluY2lwYWxzIGZyb20gdGhlIGNvbGxlY3Rpb24gcGVybWlzc2lvbnMuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICBwZXJtaXNzaW9ucyAgICAgICAgICAgICBUaGUgcGVybWlzc2lvbnMgb2JqZWN0LlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gIFtvcHRpb25zPXt9XSAgICAgICAgICAgIFRoZSBvcHRpb25zIG9iamVjdFxuICAgICAqIEBwYXJhbSAge0Jvb2xlYW59IFtvcHRpb25zLnNhZmVdICAgICAgICAgIFRoZSBzYWZlIG9wdGlvbi5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICBbb3B0aW9ucy5oZWFkZXJzXSAgICAgICBUaGUgaGVhZGVycyBvYmplY3Qgb3B0aW9uLlxuICAgICAqIEBwYXJhbSAge051bWJlcn0gIFtvcHRpb25zLnJldHJ5PTBdICAgICAgIE51bWJlciBvZiByZXRyaWVzIHRvIG1ha2VcbiAgICAgKiAgICAgd2hlbiBmYWNlZCB3aXRoIHRyYW5zaWVudCBlcnJvcnMuXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSAgW29wdGlvbnMubGFzdF9tb2RpZmllZF0gVGhlIGxhc3RfbW9kaWZpZWQgb3B0aW9uLlxuICAgICAqIEByZXR1cm4ge1Byb21pc2U8T2JqZWN0LCBFcnJvcj59XG4gICAgICovXG5cbiAgfSwge1xuICAgIGtleTogXCJyZW1vdmVQZXJtaXNzaW9uc1wiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgX3JlbW92ZVBlcm1pc3Npb25zID0gKDAsIF9hc3luY1RvR2VuZXJhdG9yMi5kZWZhdWx0KShcbiAgICAgIC8qI19fUFVSRV9fKi9cbiAgICAgIF9yZWdlbmVyYXRvci5kZWZhdWx0Lm1hcmsoZnVuY3Rpb24gX2NhbGxlZTcocGVybWlzc2lvbnMpIHtcbiAgICAgICAgdmFyIG9wdGlvbnMsXG4gICAgICAgICAgICBwYXRoLFxuICAgICAgICAgICAgbGFzdF9tb2RpZmllZCxcbiAgICAgICAgICAgIHJlcXVlc3QsXG4gICAgICAgICAgICBfYXJnczcgPSBhcmd1bWVudHM7XG4gICAgICAgIHJldHVybiBfcmVnZW5lcmF0b3IuZGVmYXVsdC53cmFwKGZ1bmN0aW9uIF9jYWxsZWU3JChfY29udGV4dDcpIHtcbiAgICAgICAgICB3aGlsZSAoMSkge1xuICAgICAgICAgICAgc3dpdGNoIChfY29udGV4dDcucHJldiA9IF9jb250ZXh0Ny5uZXh0KSB7XG4gICAgICAgICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgICAgICBvcHRpb25zID0gX2FyZ3M3Lmxlbmd0aCA+IDEgJiYgX2FyZ3M3WzFdICE9PSB1bmRlZmluZWQgPyBfYXJnczdbMV0gOiB7fTtcblxuICAgICAgICAgICAgICAgIGlmICgoMCwgX3V0aWxzLmlzT2JqZWN0KShwZXJtaXNzaW9ucykpIHtcbiAgICAgICAgICAgICAgICAgIF9jb250ZXh0Ny5uZXh0ID0gMztcbiAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkEgcGVybWlzc2lvbnMgb2JqZWN0IGlzIHJlcXVpcmVkLlwiKTtcblxuICAgICAgICAgICAgICBjYXNlIDM6XG4gICAgICAgICAgICAgICAgcGF0aCA9ICgwLCBfZW5kcG9pbnQuZGVmYXVsdCkoXCJjb2xsZWN0aW9uXCIsIHRoaXMuYnVja2V0Lm5hbWUsIHRoaXMubmFtZSk7XG4gICAgICAgICAgICAgICAgbGFzdF9tb2RpZmllZCA9IG9wdGlvbnMubGFzdF9tb2RpZmllZDtcbiAgICAgICAgICAgICAgICByZXF1ZXN0ID0gcmVxdWVzdHMuanNvblBhdGNoUGVybWlzc2lvbnNSZXF1ZXN0KHBhdGgsIHBlcm1pc3Npb25zLCBcInJlbW92ZVwiLCB7XG4gICAgICAgICAgICAgICAgICBsYXN0X21vZGlmaWVkOiBsYXN0X21vZGlmaWVkLFxuICAgICAgICAgICAgICAgICAgaGVhZGVyczogdGhpcy5fZ2V0SGVhZGVycyhvcHRpb25zKSxcbiAgICAgICAgICAgICAgICAgIHNhZmU6IHRoaXMuX2dldFNhZmUob3B0aW9ucylcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQ3LmFicnVwdChcInJldHVyblwiLCB0aGlzLmNsaWVudC5leGVjdXRlKHJlcXVlc3QsIHtcbiAgICAgICAgICAgICAgICAgIHJldHJ5OiB0aGlzLl9nZXRSZXRyeShvcHRpb25zKVxuICAgICAgICAgICAgICAgIH0pKTtcblxuICAgICAgICAgICAgICBjYXNlIDc6XG4gICAgICAgICAgICAgIGNhc2UgXCJlbmRcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQ3LnN0b3AoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0sIF9jYWxsZWU3LCB0aGlzKTtcbiAgICAgIH0pKTtcblxuICAgICAgcmV0dXJuIGZ1bmN0aW9uIHJlbW92ZVBlcm1pc3Npb25zKF94NCkge1xuICAgICAgICByZXR1cm4gX3JlbW92ZVBlcm1pc3Npb25zLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICB9O1xuICAgIH0oKVxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSByZWNvcmQgaW4gY3VycmVudCBjb2xsZWN0aW9uLlxuICAgICAqXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSAgcmVjb3JkICAgICAgICAgICAgICAgIFRoZSByZWNvcmQgdG8gY3JlYXRlLlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gIFtvcHRpb25zPXt9XSAgICAgICAgICBUaGUgb3B0aW9ucyBvYmplY3QuXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSAgW29wdGlvbnMuaGVhZGVyc10gICAgIFRoZSBoZWFkZXJzIG9iamVjdCBvcHRpb24uXG4gICAgICogQHBhcmFtICB7TnVtYmVyfSAgW29wdGlvbnMucmV0cnk9MF0gICAgIE51bWJlciBvZiByZXRyaWVzIHRvIG1ha2VcbiAgICAgKiAgICAgd2hlbiBmYWNlZCB3aXRoIHRyYW5zaWVudCBlcnJvcnMuXG4gICAgICogQHBhcmFtICB7Qm9vbGVhbn0gW29wdGlvbnMuc2FmZV0gICAgICAgIFRoZSBzYWZlIG9wdGlvbi5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICBbb3B0aW9ucy5wZXJtaXNzaW9uc10gVGhlIHBlcm1pc3Npb25zIG9wdGlvbi5cbiAgICAgKiBAcmV0dXJuIHtQcm9taXNlPE9iamVjdCwgRXJyb3I+fVxuICAgICAqL1xuXG4gIH0sIHtcbiAgICBrZXk6IFwiY3JlYXRlUmVjb3JkXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciBfY3JlYXRlUmVjb3JkID0gKDAsIF9hc3luY1RvR2VuZXJhdG9yMi5kZWZhdWx0KShcbiAgICAgIC8qI19fUFVSRV9fKi9cbiAgICAgIF9yZWdlbmVyYXRvci5kZWZhdWx0Lm1hcmsoZnVuY3Rpb24gX2NhbGxlZTgocmVjb3JkKSB7XG4gICAgICAgIHZhciBvcHRpb25zLFxuICAgICAgICAgICAgcGVybWlzc2lvbnMsXG4gICAgICAgICAgICBwYXRoLFxuICAgICAgICAgICAgcmVxdWVzdCxcbiAgICAgICAgICAgIF9hcmdzOCA9IGFyZ3VtZW50cztcbiAgICAgICAgcmV0dXJuIF9yZWdlbmVyYXRvci5kZWZhdWx0LndyYXAoZnVuY3Rpb24gX2NhbGxlZTgkKF9jb250ZXh0OCkge1xuICAgICAgICAgIHdoaWxlICgxKSB7XG4gICAgICAgICAgICBzd2l0Y2ggKF9jb250ZXh0OC5wcmV2ID0gX2NvbnRleHQ4Lm5leHQpIHtcbiAgICAgICAgICAgICAgY2FzZSAwOlxuICAgICAgICAgICAgICAgIG9wdGlvbnMgPSBfYXJnczgubGVuZ3RoID4gMSAmJiBfYXJnczhbMV0gIT09IHVuZGVmaW5lZCA/IF9hcmdzOFsxXSA6IHt9O1xuICAgICAgICAgICAgICAgIHBlcm1pc3Npb25zID0gb3B0aW9ucy5wZXJtaXNzaW9ucztcbiAgICAgICAgICAgICAgICBwYXRoID0gKDAsIF9lbmRwb2ludC5kZWZhdWx0KShcInJlY29yZFwiLCB0aGlzLmJ1Y2tldC5uYW1lLCB0aGlzLm5hbWUsIHJlY29yZC5pZCk7XG4gICAgICAgICAgICAgICAgcmVxdWVzdCA9IHJlcXVlc3RzLmNyZWF0ZVJlcXVlc3QocGF0aCwge1xuICAgICAgICAgICAgICAgICAgZGF0YTogcmVjb3JkLFxuICAgICAgICAgICAgICAgICAgcGVybWlzc2lvbnM6IHBlcm1pc3Npb25zXG4gICAgICAgICAgICAgICAgfSwge1xuICAgICAgICAgICAgICAgICAgaGVhZGVyczogdGhpcy5fZ2V0SGVhZGVycyhvcHRpb25zKSxcbiAgICAgICAgICAgICAgICAgIHNhZmU6IHRoaXMuX2dldFNhZmUob3B0aW9ucylcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQ4LmFicnVwdChcInJldHVyblwiLCB0aGlzLmNsaWVudC5leGVjdXRlKHJlcXVlc3QsIHtcbiAgICAgICAgICAgICAgICAgIHJldHJ5OiB0aGlzLl9nZXRSZXRyeShvcHRpb25zKVxuICAgICAgICAgICAgICAgIH0pKTtcblxuICAgICAgICAgICAgICBjYXNlIDU6XG4gICAgICAgICAgICAgIGNhc2UgXCJlbmRcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQ4LnN0b3AoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0sIF9jYWxsZWU4LCB0aGlzKTtcbiAgICAgIH0pKTtcblxuICAgICAgcmV0dXJuIGZ1bmN0aW9uIGNyZWF0ZVJlY29yZChfeDUpIHtcbiAgICAgICAgcmV0dXJuIF9jcmVhdGVSZWNvcmQuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgIH07XG4gICAgfSgpXG4gICAgLyoqXG4gICAgICogQWRkcyBhbiBhdHRhY2htZW50IHRvIGEgcmVjb3JkLCBjcmVhdGluZyB0aGUgcmVjb3JkIHdoZW4gaXQgZG9lc24ndCBleGlzdC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSAge1N0cmluZ30gIGRhdGFVUkwgICAgICAgICAgICAgICAgIFRoZSBkYXRhIHVybC5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICBbcmVjb3JkPXt9XSAgICAgICAgICAgICBUaGUgcmVjb3JkIGRhdGEuXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSAgW29wdGlvbnM9e31dICAgICAgICAgICAgVGhlIG9wdGlvbnMgb2JqZWN0LlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gIFtvcHRpb25zLmhlYWRlcnNdICAgICAgIFRoZSBoZWFkZXJzIG9iamVjdCBvcHRpb24uXG4gICAgICogQHBhcmFtICB7TnVtYmVyfSAgW29wdGlvbnMucmV0cnk9MF0gICAgICAgTnVtYmVyIG9mIHJldHJpZXMgdG8gbWFrZVxuICAgICAqICAgICB3aGVuIGZhY2VkIHdpdGggdHJhbnNpZW50IGVycm9ycy5cbiAgICAgKiBAcGFyYW0gIHtCb29sZWFufSBbb3B0aW9ucy5zYWZlXSAgICAgICAgICBUaGUgc2FmZSBvcHRpb24uXG4gICAgICogQHBhcmFtICB7TnVtYmVyfSAgW29wdGlvbnMubGFzdF9tb2RpZmllZF0gVGhlIGxhc3RfbW9kaWZpZWQgb3B0aW9uLlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gIFtvcHRpb25zLnBlcm1pc3Npb25zXSAgIFRoZSBwZXJtaXNzaW9ucyBvcHRpb24uXG4gICAgICogQHBhcmFtICB7U3RyaW5nfSAgW29wdGlvbnMuZmlsZW5hbWVdICAgICAgRm9yY2UgdGhlIGF0dGFjaG1lbnQgZmlsZW5hbWUuXG4gICAgICogQHBhcmFtICB7U3RyaW5nfSAgW29wdGlvbnMuZ3ppcHBlZF0gICAgICAgRm9yY2UgdGhlIGF0dGFjaG1lbnQgdG8gYmUgZ3ppcHBlZCBvciBub3QuXG4gICAgICogQHJldHVybiB7UHJvbWlzZTxPYmplY3QsIEVycm9yPn1cbiAgICAgKi9cblxuICB9LCB7XG4gICAga2V5OiBcImFkZEF0dGFjaG1lbnRcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gKCkge1xuICAgICAgdmFyIF9hZGRBdHRhY2htZW50ID0gKDAsIF9hc3luY1RvR2VuZXJhdG9yMi5kZWZhdWx0KShcbiAgICAgIC8qI19fUFVSRV9fKi9cbiAgICAgIF9yZWdlbmVyYXRvci5kZWZhdWx0Lm1hcmsoZnVuY3Rpb24gX2NhbGxlZTkoZGF0YVVSSSkge1xuICAgICAgICB2YXIgcmVjb3JkLFxuICAgICAgICAgICAgb3B0aW9ucyxcbiAgICAgICAgICAgIHBlcm1pc3Npb25zLFxuICAgICAgICAgICAgaWQsXG4gICAgICAgICAgICBwYXRoLFxuICAgICAgICAgICAgX3JlY29yZCRvcHRpb25zLFxuICAgICAgICAgICAgbGFzdF9tb2RpZmllZCxcbiAgICAgICAgICAgIGFkZEF0dGFjaG1lbnRSZXF1ZXN0LFxuICAgICAgICAgICAgX2FyZ3M5ID0gYXJndW1lbnRzO1xuXG4gICAgICAgIHJldHVybiBfcmVnZW5lcmF0b3IuZGVmYXVsdC53cmFwKGZ1bmN0aW9uIF9jYWxsZWU5JChfY29udGV4dDkpIHtcbiAgICAgICAgICB3aGlsZSAoMSkge1xuICAgICAgICAgICAgc3dpdGNoIChfY29udGV4dDkucHJldiA9IF9jb250ZXh0OS5uZXh0KSB7XG4gICAgICAgICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgICAgICByZWNvcmQgPSBfYXJnczkubGVuZ3RoID4gMSAmJiBfYXJnczlbMV0gIT09IHVuZGVmaW5lZCA/IF9hcmdzOVsxXSA6IHt9O1xuICAgICAgICAgICAgICAgIG9wdGlvbnMgPSBfYXJnczkubGVuZ3RoID4gMiAmJiBfYXJnczlbMl0gIT09IHVuZGVmaW5lZCA/IF9hcmdzOVsyXSA6IHt9O1xuICAgICAgICAgICAgICAgIHBlcm1pc3Npb25zID0gb3B0aW9ucy5wZXJtaXNzaW9ucztcbiAgICAgICAgICAgICAgICBpZCA9IHJlY29yZC5pZCB8fCBfdXVpZC52NC52NCgpO1xuICAgICAgICAgICAgICAgIHBhdGggPSAoMCwgX2VuZHBvaW50LmRlZmF1bHQpKFwiYXR0YWNobWVudFwiLCB0aGlzLmJ1Y2tldC5uYW1lLCB0aGlzLm5hbWUsIGlkKTtcbiAgICAgICAgICAgICAgICBfcmVjb3JkJG9wdGlvbnMgPSAoMCwgX29iamVjdFNwcmVhZDIuZGVmYXVsdCkoe30sIHJlY29yZCwgb3B0aW9ucyksIGxhc3RfbW9kaWZpZWQgPSBfcmVjb3JkJG9wdGlvbnMubGFzdF9tb2RpZmllZDtcbiAgICAgICAgICAgICAgICBhZGRBdHRhY2htZW50UmVxdWVzdCA9IHJlcXVlc3RzLmFkZEF0dGFjaG1lbnRSZXF1ZXN0KHBhdGgsIGRhdGFVUkksIHtcbiAgICAgICAgICAgICAgICAgIGRhdGE6IHJlY29yZCxcbiAgICAgICAgICAgICAgICAgIHBlcm1pc3Npb25zOiBwZXJtaXNzaW9uc1xuICAgICAgICAgICAgICAgIH0sIHtcbiAgICAgICAgICAgICAgICAgIGxhc3RfbW9kaWZpZWQ6IGxhc3RfbW9kaWZpZWQsXG4gICAgICAgICAgICAgICAgICBmaWxlbmFtZTogb3B0aW9ucy5maWxlbmFtZSxcbiAgICAgICAgICAgICAgICAgIGd6aXBwZWQ6IG9wdGlvbnMuZ3ppcHBlZCxcbiAgICAgICAgICAgICAgICAgIGhlYWRlcnM6IHRoaXMuX2dldEhlYWRlcnMob3B0aW9ucyksXG4gICAgICAgICAgICAgICAgICBzYWZlOiB0aGlzLl9nZXRTYWZlKG9wdGlvbnMpXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgX2NvbnRleHQ5Lm5leHQgPSA5O1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmNsaWVudC5leGVjdXRlKGFkZEF0dGFjaG1lbnRSZXF1ZXN0LCB7XG4gICAgICAgICAgICAgICAgICBzdHJpbmdpZnk6IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgcmV0cnk6IHRoaXMuX2dldFJldHJ5KG9wdGlvbnMpXG4gICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgY2FzZSA5OlxuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDkuYWJydXB0KFwicmV0dXJuXCIsIHRoaXMuZ2V0UmVjb3JkKGlkKSk7XG5cbiAgICAgICAgICAgICAgY2FzZSAxMDpcbiAgICAgICAgICAgICAgY2FzZSBcImVuZFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDkuc3RvcCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSwgX2NhbGxlZTksIHRoaXMpO1xuICAgICAgfSkpO1xuXG4gICAgICByZXR1cm4gZnVuY3Rpb24gYWRkQXR0YWNobWVudChfeDYpIHtcbiAgICAgICAgcmV0dXJuIF9hZGRBdHRhY2htZW50LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICB9O1xuICAgIH0oKVxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgYW4gYXR0YWNobWVudCBmcm9tIGEgZ2l2ZW4gcmVjb3JkLlxuICAgICAqXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSAgcmVjb3JkSWQgICAgICAgICAgICAgICAgVGhlIHJlY29yZCBpZC5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICBbb3B0aW9ucz17fV0gICAgICAgICAgICBUaGUgb3B0aW9ucyBvYmplY3QuXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSAgW29wdGlvbnMuaGVhZGVyc10gICAgICAgVGhlIGhlYWRlcnMgb2JqZWN0IG9wdGlvbi5cbiAgICAgKiBAcGFyYW0gIHtOdW1iZXJ9ICBbb3B0aW9ucy5yZXRyeT0wXSAgICAgICBOdW1iZXIgb2YgcmV0cmllcyB0byBtYWtlXG4gICAgICogICAgIHdoZW4gZmFjZWQgd2l0aCB0cmFuc2llbnQgZXJyb3JzLlxuICAgICAqIEBwYXJhbSAge0Jvb2xlYW59IFtvcHRpb25zLnNhZmVdICAgICAgICAgIFRoZSBzYWZlIG9wdGlvbi5cbiAgICAgKiBAcGFyYW0gIHtOdW1iZXJ9ICBbb3B0aW9ucy5sYXN0X21vZGlmaWVkXSBUaGUgbGFzdF9tb2RpZmllZCBvcHRpb24uXG4gICAgICovXG5cbiAgfSwge1xuICAgIGtleTogXCJyZW1vdmVBdHRhY2htZW50XCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciBfcmVtb3ZlQXR0YWNobWVudCA9ICgwLCBfYXN5bmNUb0dlbmVyYXRvcjIuZGVmYXVsdCkoXG4gICAgICAvKiNfX1BVUkVfXyovXG4gICAgICBfcmVnZW5lcmF0b3IuZGVmYXVsdC5tYXJrKGZ1bmN0aW9uIF9jYWxsZWUxMChyZWNvcmRJZCkge1xuICAgICAgICB2YXIgb3B0aW9ucyxcbiAgICAgICAgICAgIGxhc3RfbW9kaWZpZWQsXG4gICAgICAgICAgICBwYXRoLFxuICAgICAgICAgICAgcmVxdWVzdCxcbiAgICAgICAgICAgIF9hcmdzMTAgPSBhcmd1bWVudHM7XG4gICAgICAgIHJldHVybiBfcmVnZW5lcmF0b3IuZGVmYXVsdC53cmFwKGZ1bmN0aW9uIF9jYWxsZWUxMCQoX2NvbnRleHQxMCkge1xuICAgICAgICAgIHdoaWxlICgxKSB7XG4gICAgICAgICAgICBzd2l0Y2ggKF9jb250ZXh0MTAucHJldiA9IF9jb250ZXh0MTAubmV4dCkge1xuICAgICAgICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICAgICAgb3B0aW9ucyA9IF9hcmdzMTAubGVuZ3RoID4gMSAmJiBfYXJnczEwWzFdICE9PSB1bmRlZmluZWQgPyBfYXJnczEwWzFdIDoge307XG4gICAgICAgICAgICAgICAgbGFzdF9tb2RpZmllZCA9IG9wdGlvbnMubGFzdF9tb2RpZmllZDtcbiAgICAgICAgICAgICAgICBwYXRoID0gKDAsIF9lbmRwb2ludC5kZWZhdWx0KShcImF0dGFjaG1lbnRcIiwgdGhpcy5idWNrZXQubmFtZSwgdGhpcy5uYW1lLCByZWNvcmRJZCk7XG4gICAgICAgICAgICAgICAgcmVxdWVzdCA9IHJlcXVlc3RzLmRlbGV0ZVJlcXVlc3QocGF0aCwge1xuICAgICAgICAgICAgICAgICAgbGFzdF9tb2RpZmllZDogbGFzdF9tb2RpZmllZCxcbiAgICAgICAgICAgICAgICAgIGhlYWRlcnM6IHRoaXMuX2dldEhlYWRlcnMob3B0aW9ucyksXG4gICAgICAgICAgICAgICAgICBzYWZlOiB0aGlzLl9nZXRTYWZlKG9wdGlvbnMpXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0MTAuYWJydXB0KFwicmV0dXJuXCIsIHRoaXMuY2xpZW50LmV4ZWN1dGUocmVxdWVzdCwge1xuICAgICAgICAgICAgICAgICAgcmV0cnk6IHRoaXMuX2dldFJldHJ5KG9wdGlvbnMpXG4gICAgICAgICAgICAgICAgfSkpO1xuXG4gICAgICAgICAgICAgIGNhc2UgNTpcbiAgICAgICAgICAgICAgY2FzZSBcImVuZFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDEwLnN0b3AoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0sIF9jYWxsZWUxMCwgdGhpcyk7XG4gICAgICB9KSk7XG5cbiAgICAgIHJldHVybiBmdW5jdGlvbiByZW1vdmVBdHRhY2htZW50KF94Nykge1xuICAgICAgICByZXR1cm4gX3JlbW92ZUF0dGFjaG1lbnQuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgIH07XG4gICAgfSgpXG4gICAgLyoqXG4gICAgICogVXBkYXRlcyBhIHJlY29yZCBpbiBjdXJyZW50IGNvbGxlY3Rpb24uXG4gICAgICpcbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICByZWNvcmQgICAgICAgICAgICAgICAgICBUaGUgcmVjb3JkIHRvIHVwZGF0ZS5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICBbb3B0aW9ucz17fV0gICAgICAgICAgICBUaGUgb3B0aW9ucyBvYmplY3QuXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSAgW29wdGlvbnMuaGVhZGVyc10gICAgICAgVGhlIGhlYWRlcnMgb2JqZWN0IG9wdGlvbi5cbiAgICAgKiBAcGFyYW0gIHtOdW1iZXJ9ICBbb3B0aW9ucy5yZXRyeT0wXSAgICAgICBOdW1iZXIgb2YgcmV0cmllcyB0byBtYWtlXG4gICAgICogICAgIHdoZW4gZmFjZWQgd2l0aCB0cmFuc2llbnQgZXJyb3JzLlxuICAgICAqIEBwYXJhbSAge0Jvb2xlYW59IFtvcHRpb25zLnNhZmVdICAgICAgICAgIFRoZSBzYWZlIG9wdGlvbi5cbiAgICAgKiBAcGFyYW0gIHtOdW1iZXJ9ICBbb3B0aW9ucy5sYXN0X21vZGlmaWVkXSBUaGUgbGFzdF9tb2RpZmllZCBvcHRpb24uXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSAgW29wdGlvbnMucGVybWlzc2lvbnNdICAgVGhlIHBlcm1pc3Npb25zIG9wdGlvbi5cbiAgICAgKiBAcmV0dXJuIHtQcm9taXNlPE9iamVjdCwgRXJyb3I+fVxuICAgICAqL1xuXG4gIH0sIHtcbiAgICBrZXk6IFwidXBkYXRlUmVjb3JkXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciBfdXBkYXRlUmVjb3JkID0gKDAsIF9hc3luY1RvR2VuZXJhdG9yMi5kZWZhdWx0KShcbiAgICAgIC8qI19fUFVSRV9fKi9cbiAgICAgIF9yZWdlbmVyYXRvci5kZWZhdWx0Lm1hcmsoZnVuY3Rpb24gX2NhbGxlZTExKHJlY29yZCkge1xuICAgICAgICB2YXIgb3B0aW9ucyxcbiAgICAgICAgICAgIHBlcm1pc3Npb25zLFxuICAgICAgICAgICAgX3JlY29yZCRvcHRpb25zMixcbiAgICAgICAgICAgIGxhc3RfbW9kaWZpZWQsXG4gICAgICAgICAgICBwYXRoLFxuICAgICAgICAgICAgcmVxdWVzdCxcbiAgICAgICAgICAgIF9hcmdzMTEgPSBhcmd1bWVudHM7XG5cbiAgICAgICAgcmV0dXJuIF9yZWdlbmVyYXRvci5kZWZhdWx0LndyYXAoZnVuY3Rpb24gX2NhbGxlZTExJChfY29udGV4dDExKSB7XG4gICAgICAgICAgd2hpbGUgKDEpIHtcbiAgICAgICAgICAgIHN3aXRjaCAoX2NvbnRleHQxMS5wcmV2ID0gX2NvbnRleHQxMS5uZXh0KSB7XG4gICAgICAgICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgICAgICBvcHRpb25zID0gX2FyZ3MxMS5sZW5ndGggPiAxICYmIF9hcmdzMTFbMV0gIT09IHVuZGVmaW5lZCA/IF9hcmdzMTFbMV0gOiB7fTtcblxuICAgICAgICAgICAgICAgIGlmICgoMCwgX3V0aWxzLmlzT2JqZWN0KShyZWNvcmQpKSB7XG4gICAgICAgICAgICAgICAgICBfY29udGV4dDExLm5leHQgPSAzO1xuICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQSByZWNvcmQgb2JqZWN0IGlzIHJlcXVpcmVkLlwiKTtcblxuICAgICAgICAgICAgICBjYXNlIDM6XG4gICAgICAgICAgICAgICAgaWYgKHJlY29yZC5pZCkge1xuICAgICAgICAgICAgICAgICAgX2NvbnRleHQxMS5uZXh0ID0gNTtcbiAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkEgcmVjb3JkIGlkIGlzIHJlcXVpcmVkLlwiKTtcblxuICAgICAgICAgICAgICBjYXNlIDU6XG4gICAgICAgICAgICAgICAgcGVybWlzc2lvbnMgPSBvcHRpb25zLnBlcm1pc3Npb25zO1xuICAgICAgICAgICAgICAgIF9yZWNvcmQkb3B0aW9uczIgPSAoMCwgX29iamVjdFNwcmVhZDIuZGVmYXVsdCkoe30sIHJlY29yZCwgb3B0aW9ucyksIGxhc3RfbW9kaWZpZWQgPSBfcmVjb3JkJG9wdGlvbnMyLmxhc3RfbW9kaWZpZWQ7XG4gICAgICAgICAgICAgICAgcGF0aCA9ICgwLCBfZW5kcG9pbnQuZGVmYXVsdCkoXCJyZWNvcmRcIiwgdGhpcy5idWNrZXQubmFtZSwgdGhpcy5uYW1lLCByZWNvcmQuaWQpO1xuICAgICAgICAgICAgICAgIHJlcXVlc3QgPSByZXF1ZXN0cy51cGRhdGVSZXF1ZXN0KHBhdGgsIHtcbiAgICAgICAgICAgICAgICAgIGRhdGE6IHJlY29yZCxcbiAgICAgICAgICAgICAgICAgIHBlcm1pc3Npb25zOiBwZXJtaXNzaW9uc1xuICAgICAgICAgICAgICAgIH0sIHtcbiAgICAgICAgICAgICAgICAgIGhlYWRlcnM6IHRoaXMuX2dldEhlYWRlcnMob3B0aW9ucyksXG4gICAgICAgICAgICAgICAgICBzYWZlOiB0aGlzLl9nZXRTYWZlKG9wdGlvbnMpLFxuICAgICAgICAgICAgICAgICAgbGFzdF9tb2RpZmllZDogbGFzdF9tb2RpZmllZCxcbiAgICAgICAgICAgICAgICAgIHBhdGNoOiAhIW9wdGlvbnMucGF0Y2hcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQxMS5hYnJ1cHQoXCJyZXR1cm5cIiwgdGhpcy5jbGllbnQuZXhlY3V0ZShyZXF1ZXN0LCB7XG4gICAgICAgICAgICAgICAgICByZXRyeTogdGhpcy5fZ2V0UmV0cnkob3B0aW9ucylcbiAgICAgICAgICAgICAgICB9KSk7XG5cbiAgICAgICAgICAgICAgY2FzZSAxMDpcbiAgICAgICAgICAgICAgY2FzZSBcImVuZFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDExLnN0b3AoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0sIF9jYWxsZWUxMSwgdGhpcyk7XG4gICAgICB9KSk7XG5cbiAgICAgIHJldHVybiBmdW5jdGlvbiB1cGRhdGVSZWNvcmQoX3g4KSB7XG4gICAgICAgIHJldHVybiBfdXBkYXRlUmVjb3JkLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICB9O1xuICAgIH0oKVxuICAgIC8qKlxuICAgICAqIERlbGV0ZXMgYSByZWNvcmQgZnJvbSB0aGUgY3VycmVudCBjb2xsZWN0aW9uLlxuICAgICAqXG4gICAgICogQHBhcmFtICB7T2JqZWN0fFN0cmluZ30gcmVjb3JkICAgICAgICAgICAgICAgICAgVGhlIHJlY29yZCB0byBkZWxldGUuXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSAgICAgICAgW29wdGlvbnM9e31dICAgICAgICAgICAgVGhlIG9wdGlvbnMgb2JqZWN0LlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gICAgICAgIFtvcHRpb25zLmhlYWRlcnNdICAgICAgIFRoZSBoZWFkZXJzIG9iamVjdCBvcHRpb24uXG4gICAgICogQHBhcmFtICB7TnVtYmVyfSAgICAgICAgW29wdGlvbnMucmV0cnk9MF0gICAgICAgTnVtYmVyIG9mIHJldHJpZXMgdG8gbWFrZVxuICAgICAqICAgICB3aGVuIGZhY2VkIHdpdGggdHJhbnNpZW50IGVycm9ycy5cbiAgICAgKiBAcGFyYW0gIHtCb29sZWFufSAgICAgICBbb3B0aW9ucy5zYWZlXSAgICAgICAgICBUaGUgc2FmZSBvcHRpb24uXG4gICAgICogQHBhcmFtICB7TnVtYmVyfSAgICAgICAgW29wdGlvbnMubGFzdF9tb2RpZmllZF0gVGhlIGxhc3RfbW9kaWZpZWQgb3B0aW9uLlxuICAgICAqIEByZXR1cm4ge1Byb21pc2U8T2JqZWN0LCBFcnJvcj59XG4gICAgICovXG5cbiAgfSwge1xuICAgIGtleTogXCJkZWxldGVSZWNvcmRcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gKCkge1xuICAgICAgdmFyIF9kZWxldGVSZWNvcmQgPSAoMCwgX2FzeW5jVG9HZW5lcmF0b3IyLmRlZmF1bHQpKFxuICAgICAgLyojX19QVVJFX18qL1xuICAgICAgX3JlZ2VuZXJhdG9yLmRlZmF1bHQubWFyayhmdW5jdGlvbiBfY2FsbGVlMTIocmVjb3JkKSB7XG4gICAgICAgIHZhciBvcHRpb25zLFxuICAgICAgICAgICAgcmVjb3JkT2JqLFxuICAgICAgICAgICAgaWQsXG4gICAgICAgICAgICBfcmVjb3JkT2JqJG9wdGlvbnMsXG4gICAgICAgICAgICBsYXN0X21vZGlmaWVkLFxuICAgICAgICAgICAgcGF0aCxcbiAgICAgICAgICAgIHJlcXVlc3QsXG4gICAgICAgICAgICBfYXJnczEyID0gYXJndW1lbnRzO1xuXG4gICAgICAgIHJldHVybiBfcmVnZW5lcmF0b3IuZGVmYXVsdC53cmFwKGZ1bmN0aW9uIF9jYWxsZWUxMiQoX2NvbnRleHQxMikge1xuICAgICAgICAgIHdoaWxlICgxKSB7XG4gICAgICAgICAgICBzd2l0Y2ggKF9jb250ZXh0MTIucHJldiA9IF9jb250ZXh0MTIubmV4dCkge1xuICAgICAgICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICAgICAgb3B0aW9ucyA9IF9hcmdzMTIubGVuZ3RoID4gMSAmJiBfYXJnczEyWzFdICE9PSB1bmRlZmluZWQgPyBfYXJnczEyWzFdIDoge307XG4gICAgICAgICAgICAgICAgcmVjb3JkT2JqID0gKDAsIF91dGlscy50b0RhdGFCb2R5KShyZWNvcmQpO1xuXG4gICAgICAgICAgICAgICAgaWYgKHJlY29yZE9iai5pZCkge1xuICAgICAgICAgICAgICAgICAgX2NvbnRleHQxMi5uZXh0ID0gNDtcbiAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkEgcmVjb3JkIGlkIGlzIHJlcXVpcmVkLlwiKTtcblxuICAgICAgICAgICAgICBjYXNlIDQ6XG4gICAgICAgICAgICAgICAgaWQgPSByZWNvcmRPYmouaWQ7XG4gICAgICAgICAgICAgICAgX3JlY29yZE9iaiRvcHRpb25zID0gKDAsIF9vYmplY3RTcHJlYWQyLmRlZmF1bHQpKHt9LCByZWNvcmRPYmosIG9wdGlvbnMpLCBsYXN0X21vZGlmaWVkID0gX3JlY29yZE9iaiRvcHRpb25zLmxhc3RfbW9kaWZpZWQ7XG4gICAgICAgICAgICAgICAgcGF0aCA9ICgwLCBfZW5kcG9pbnQuZGVmYXVsdCkoXCJyZWNvcmRcIiwgdGhpcy5idWNrZXQubmFtZSwgdGhpcy5uYW1lLCBpZCk7XG4gICAgICAgICAgICAgICAgcmVxdWVzdCA9IHJlcXVlc3RzLmRlbGV0ZVJlcXVlc3QocGF0aCwge1xuICAgICAgICAgICAgICAgICAgbGFzdF9tb2RpZmllZDogbGFzdF9tb2RpZmllZCxcbiAgICAgICAgICAgICAgICAgIGhlYWRlcnM6IHRoaXMuX2dldEhlYWRlcnMob3B0aW9ucyksXG4gICAgICAgICAgICAgICAgICBzYWZlOiB0aGlzLl9nZXRTYWZlKG9wdGlvbnMpXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0MTIuYWJydXB0KFwicmV0dXJuXCIsIHRoaXMuY2xpZW50LmV4ZWN1dGUocmVxdWVzdCwge1xuICAgICAgICAgICAgICAgICAgcmV0cnk6IHRoaXMuX2dldFJldHJ5KG9wdGlvbnMpXG4gICAgICAgICAgICAgICAgfSkpO1xuXG4gICAgICAgICAgICAgIGNhc2UgOTpcbiAgICAgICAgICAgICAgY2FzZSBcImVuZFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDEyLnN0b3AoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0sIF9jYWxsZWUxMiwgdGhpcyk7XG4gICAgICB9KSk7XG5cbiAgICAgIHJldHVybiBmdW5jdGlvbiBkZWxldGVSZWNvcmQoX3g5KSB7XG4gICAgICAgIHJldHVybiBfZGVsZXRlUmVjb3JkLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICB9O1xuICAgIH0oKVxuICAgIC8qKlxuICAgICAqIFJldHJpZXZlcyBhIHJlY29yZCBmcm9tIHRoZSBjdXJyZW50IGNvbGxlY3Rpb24uXG4gICAgICpcbiAgICAgKiBAcGFyYW0gIHtTdHJpbmd9IGlkICAgICAgICAgICAgICAgIFRoZSByZWNvcmQgaWQgdG8gcmV0cmlldmUuXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSBbb3B0aW9ucz17fV0gICAgICBUaGUgb3B0aW9ucyBvYmplY3QuXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSBbb3B0aW9ucy5oZWFkZXJzXSBUaGUgaGVhZGVycyBvYmplY3Qgb3B0aW9uLlxuICAgICAqIEBwYXJhbSAge051bWJlcn0gW29wdGlvbnMucmV0cnk9MF0gTnVtYmVyIG9mIHJldHJpZXMgdG8gbWFrZVxuICAgICAqICAgICB3aGVuIGZhY2VkIHdpdGggdHJhbnNpZW50IGVycm9ycy5cbiAgICAgKiBAcmV0dXJuIHtQcm9taXNlPE9iamVjdCwgRXJyb3I+fVxuICAgICAqL1xuXG4gIH0sIHtcbiAgICBrZXk6IFwiZ2V0UmVjb3JkXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciBfZ2V0UmVjb3JkID0gKDAsIF9hc3luY1RvR2VuZXJhdG9yMi5kZWZhdWx0KShcbiAgICAgIC8qI19fUFVSRV9fKi9cbiAgICAgIF9yZWdlbmVyYXRvci5kZWZhdWx0Lm1hcmsoZnVuY3Rpb24gX2NhbGxlZTEzKGlkKSB7XG4gICAgICAgIHZhciBvcHRpb25zLFxuICAgICAgICAgICAgcGF0aCxcbiAgICAgICAgICAgIHJlcXVlc3QsXG4gICAgICAgICAgICBfYXJnczEzID0gYXJndW1lbnRzO1xuICAgICAgICByZXR1cm4gX3JlZ2VuZXJhdG9yLmRlZmF1bHQud3JhcChmdW5jdGlvbiBfY2FsbGVlMTMkKF9jb250ZXh0MTMpIHtcbiAgICAgICAgICB3aGlsZSAoMSkge1xuICAgICAgICAgICAgc3dpdGNoIChfY29udGV4dDEzLnByZXYgPSBfY29udGV4dDEzLm5leHQpIHtcbiAgICAgICAgICAgICAgY2FzZSAwOlxuICAgICAgICAgICAgICAgIG9wdGlvbnMgPSBfYXJnczEzLmxlbmd0aCA+IDEgJiYgX2FyZ3MxM1sxXSAhPT0gdW5kZWZpbmVkID8gX2FyZ3MxM1sxXSA6IHt9O1xuICAgICAgICAgICAgICAgIHBhdGggPSAoMCwgX2VuZHBvaW50LmRlZmF1bHQpKFwicmVjb3JkXCIsIHRoaXMuYnVja2V0Lm5hbWUsIHRoaXMubmFtZSwgaWQpO1xuICAgICAgICAgICAgICAgIHJlcXVlc3QgPSB7XG4gICAgICAgICAgICAgICAgICBoZWFkZXJzOiB0aGlzLl9nZXRIZWFkZXJzKG9wdGlvbnMpLFxuICAgICAgICAgICAgICAgICAgcGF0aDogcGF0aFxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0MTMuYWJydXB0KFwicmV0dXJuXCIsIHRoaXMuY2xpZW50LmV4ZWN1dGUocmVxdWVzdCwge1xuICAgICAgICAgICAgICAgICAgcmV0cnk6IHRoaXMuX2dldFJldHJ5KG9wdGlvbnMpXG4gICAgICAgICAgICAgICAgfSkpO1xuXG4gICAgICAgICAgICAgIGNhc2UgNDpcbiAgICAgICAgICAgICAgY2FzZSBcImVuZFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDEzLnN0b3AoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0sIF9jYWxsZWUxMywgdGhpcyk7XG4gICAgICB9KSk7XG5cbiAgICAgIHJldHVybiBmdW5jdGlvbiBnZXRSZWNvcmQoX3gxMCkge1xuICAgICAgICByZXR1cm4gX2dldFJlY29yZC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgfTtcbiAgICB9KClcbiAgICAvKipcbiAgICAgKiBMaXN0cyByZWNvcmRzIGZyb20gdGhlIGN1cnJlbnQgY29sbGVjdGlvbi5cbiAgICAgKlxuICAgICAqIFNvcnRpbmcgaXMgZG9uZSBieSBwYXNzaW5nIGEgYHNvcnRgIHN0cmluZyBvcHRpb246XG4gICAgICpcbiAgICAgKiAtIFRoZSBmaWVsZCB0byBvcmRlciB0aGUgcmVzdWx0cyBieSwgcHJlZml4ZWQgd2l0aCBgLWAgZm9yIGRlc2NlbmRpbmcuXG4gICAgICogRGVmYXVsdDogYC1sYXN0X21vZGlmaWVkYC5cbiAgICAgKlxuICAgICAqIEBzZWUgaHR0cDovL2tpbnRvLnJlYWR0aGVkb2NzLmlvL2VuL3N0YWJsZS9hcGkvMS54L3NvcnRpbmcuaHRtbFxuICAgICAqXG4gICAgICogRmlsdGVyaW5nIGlzIGRvbmUgYnkgcGFzc2luZyBhIGBmaWx0ZXJzYCBvcHRpb24gb2JqZWN0OlxuICAgICAqXG4gICAgICogLSBge2ZpZWxkbmFtZTogXCJ2YWx1ZVwifWBcbiAgICAgKiAtIGB7bWluX2ZpZWxkbmFtZTogNDAwMH1gXG4gICAgICogLSBge2luX2ZpZWxkbmFtZTogXCIxLDIsM1wifWBcbiAgICAgKiAtIGB7bm90X2ZpZWxkbmFtZTogMH1gXG4gICAgICogLSBge2V4Y2x1ZGVfZmllbGRuYW1lOiBcIjAsMVwifWBcbiAgICAgKlxuICAgICAqIEBzZWUgaHR0cDovL2tpbnRvLnJlYWR0aGVkb2NzLmlvL2VuL3N0YWJsZS9hcGkvMS54L2ZpbHRlcmluZy5odG1sXG4gICAgICpcbiAgICAgKiBQYWdpbmF0aW5nIGlzIGRvbmUgYnkgcGFzc2luZyBhIGBsaW1pdGAgb3B0aW9uLCB0aGVuIGNhbGxpbmcgdGhlIGBuZXh0KClgXG4gICAgICogbWV0aG9kIGZyb20gdGhlIHJlc29sdmVkIHJlc3VsdCBvYmplY3QgdG8gZmV0Y2ggdGhlIG5leHQgcGFnZSwgaWYgYW55LlxuICAgICAqXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSAgIFtvcHRpb25zPXt9XSAgICAgICAgICAgICAgICAgICAgVGhlIG9wdGlvbnMgb2JqZWN0LlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gICBbb3B0aW9ucy5oZWFkZXJzXSAgICAgICAgICAgICAgIFRoZSBoZWFkZXJzIG9iamVjdCBvcHRpb24uXG4gICAgICogQHBhcmFtICB7TnVtYmVyfSAgIFtvcHRpb25zLnJldHJ5PTBdICAgICAgICAgICAgICAgTnVtYmVyIG9mIHJldHJpZXMgdG8gbWFrZVxuICAgICAqICAgICB3aGVuIGZhY2VkIHdpdGggdHJhbnNpZW50IGVycm9ycy5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICAgW29wdGlvbnMuZmlsdGVycz1bXV0gICAgICAgICAgICBUaGUgZmlsdGVycyBvYmplY3QuXG4gICAgICogQHBhcmFtICB7U3RyaW5nfSAgIFtvcHRpb25zLnNvcnQ9XCItbGFzdF9tb2RpZmllZFwiXSBUaGUgc29ydCBmaWVsZC5cbiAgICAgKiBAcGFyYW0gIHtTdHJpbmd9ICAgW29wdGlvbnMuYXRdICAgICAgICAgICAgICAgICAgICBUaGUgdGltZXN0YW1wIHRvIGdldCBhIHNuYXBzaG90IGF0LlxuICAgICAqIEBwYXJhbSAge1N0cmluZ30gICBbb3B0aW9ucy5saW1pdD1udWxsXSAgICAgICAgICAgIFRoZSBsaW1pdCBmaWVsZC5cbiAgICAgKiBAcGFyYW0gIHtTdHJpbmd9ICAgW29wdGlvbnMucGFnZXM9MV0gICAgICAgICAgICAgICBUaGUgbnVtYmVyIG9mIHJlc3VsdCBwYWdlcyB0byBhZ2dyZWdhdGUuXG4gICAgICogQHBhcmFtICB7TnVtYmVyfSAgIFtvcHRpb25zLnNpbmNlPW51bGxdICAgICAgICAgICAgT25seSByZXRyaWV2ZSByZWNvcmRzIG1vZGlmaWVkIHNpbmNlIHRoZSBwcm92aWRlZCB0aW1lc3RhbXAuXG4gICAgICogQHJldHVybiB7UHJvbWlzZTxPYmplY3QsIEVycm9yPn1cbiAgICAgKi9cblxuICB9LCB7XG4gICAga2V5OiBcImxpc3RSZWNvcmRzXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciBfbGlzdFJlY29yZHMgPSAoMCwgX2FzeW5jVG9HZW5lcmF0b3IyLmRlZmF1bHQpKFxuICAgICAgLyojX19QVVJFX18qL1xuICAgICAgX3JlZ2VuZXJhdG9yLmRlZmF1bHQubWFyayhmdW5jdGlvbiBfY2FsbGVlMTQoKSB7XG4gICAgICAgIHZhciBvcHRpb25zLFxuICAgICAgICAgICAgcGF0aCxcbiAgICAgICAgICAgIF9hcmdzMTQgPSBhcmd1bWVudHM7XG4gICAgICAgIHJldHVybiBfcmVnZW5lcmF0b3IuZGVmYXVsdC53cmFwKGZ1bmN0aW9uIF9jYWxsZWUxNCQoX2NvbnRleHQxNCkge1xuICAgICAgICAgIHdoaWxlICgxKSB7XG4gICAgICAgICAgICBzd2l0Y2ggKF9jb250ZXh0MTQucHJldiA9IF9jb250ZXh0MTQubmV4dCkge1xuICAgICAgICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICAgICAgb3B0aW9ucyA9IF9hcmdzMTQubGVuZ3RoID4gMCAmJiBfYXJnczE0WzBdICE9PSB1bmRlZmluZWQgPyBfYXJnczE0WzBdIDoge307XG4gICAgICAgICAgICAgICAgcGF0aCA9ICgwLCBfZW5kcG9pbnQuZGVmYXVsdCkoXCJyZWNvcmRcIiwgdGhpcy5idWNrZXQubmFtZSwgdGhpcy5uYW1lKTtcblxuICAgICAgICAgICAgICAgIGlmICghb3B0aW9ucy5oYXNPd25Qcm9wZXJ0eShcImF0XCIpKSB7XG4gICAgICAgICAgICAgICAgICBfY29udGV4dDE0Lm5leHQgPSA2O1xuICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0MTQuYWJydXB0KFwicmV0dXJuXCIsIHRoaXMuZ2V0U25hcHNob3Qob3B0aW9ucy5hdCkpO1xuXG4gICAgICAgICAgICAgIGNhc2UgNjpcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQxNC5hYnJ1cHQoXCJyZXR1cm5cIiwgdGhpcy5jbGllbnQucGFnaW5hdGVkTGlzdChwYXRoLCBvcHRpb25zLCB7XG4gICAgICAgICAgICAgICAgICBoZWFkZXJzOiB0aGlzLl9nZXRIZWFkZXJzKG9wdGlvbnMpLFxuICAgICAgICAgICAgICAgICAgcmV0cnk6IHRoaXMuX2dldFJldHJ5KG9wdGlvbnMpXG4gICAgICAgICAgICAgICAgfSkpO1xuXG4gICAgICAgICAgICAgIGNhc2UgNzpcbiAgICAgICAgICAgICAgY2FzZSBcImVuZFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDE0LnN0b3AoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0sIF9jYWxsZWUxNCwgdGhpcyk7XG4gICAgICB9KSk7XG5cbiAgICAgIHJldHVybiBmdW5jdGlvbiBsaXN0UmVjb3JkcygpIHtcbiAgICAgICAgcmV0dXJuIF9saXN0UmVjb3Jkcy5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgfTtcbiAgICB9KClcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuXG4gIH0sIHtcbiAgICBrZXk6IFwiaXNIaXN0b3J5Q29tcGxldGVcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gKCkge1xuICAgICAgdmFyIF9pc0hpc3RvcnlDb21wbGV0ZSA9ICgwLCBfYXN5bmNUb0dlbmVyYXRvcjIuZGVmYXVsdCkoXG4gICAgICAvKiNfX1BVUkVfXyovXG4gICAgICBfcmVnZW5lcmF0b3IuZGVmYXVsdC5tYXJrKGZ1bmN0aW9uIF9jYWxsZWUxNSgpIHtcbiAgICAgICAgdmFyIF9yZWY0LCBfcmVmNCRkYXRhLCBvbGRlc3RIaXN0b3J5RW50cnk7XG5cbiAgICAgICAgcmV0dXJuIF9yZWdlbmVyYXRvci5kZWZhdWx0LndyYXAoZnVuY3Rpb24gX2NhbGxlZTE1JChfY29udGV4dDE1KSB7XG4gICAgICAgICAgd2hpbGUgKDEpIHtcbiAgICAgICAgICAgIHN3aXRjaCAoX2NvbnRleHQxNS5wcmV2ID0gX2NvbnRleHQxNS5uZXh0KSB7XG4gICAgICAgICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgICAgICBfY29udGV4dDE1Lm5leHQgPSAyO1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmJ1Y2tldC5saXN0SGlzdG9yeSh7XG4gICAgICAgICAgICAgICAgICBsaW1pdDogMSxcbiAgICAgICAgICAgICAgICAgIGZpbHRlcnM6IHtcbiAgICAgICAgICAgICAgICAgICAgYWN0aW9uOiBcImNyZWF0ZVwiLFxuICAgICAgICAgICAgICAgICAgICByZXNvdXJjZV9uYW1lOiBcImNvbGxlY3Rpb25cIixcbiAgICAgICAgICAgICAgICAgICAgY29sbGVjdGlvbl9pZDogdGhpcy5uYW1lXG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgY2FzZSAyOlxuICAgICAgICAgICAgICAgIF9yZWY0ID0gX2NvbnRleHQxNS5zZW50O1xuICAgICAgICAgICAgICAgIF9yZWY0JGRhdGEgPSAoMCwgX3NsaWNlZFRvQXJyYXkyLmRlZmF1bHQpKF9yZWY0LmRhdGEsIDEpO1xuICAgICAgICAgICAgICAgIG9sZGVzdEhpc3RvcnlFbnRyeSA9IF9yZWY0JGRhdGFbMF07XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0MTUuYWJydXB0KFwicmV0dXJuXCIsICEhb2xkZXN0SGlzdG9yeUVudHJ5KTtcblxuICAgICAgICAgICAgICBjYXNlIDY6XG4gICAgICAgICAgICAgIGNhc2UgXCJlbmRcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQxNS5zdG9wKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9LCBfY2FsbGVlMTUsIHRoaXMpO1xuICAgICAgfSkpO1xuXG4gICAgICByZXR1cm4gZnVuY3Rpb24gaXNIaXN0b3J5Q29tcGxldGUoKSB7XG4gICAgICAgIHJldHVybiBfaXNIaXN0b3J5Q29tcGxldGUuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgIH07XG4gICAgfSgpXG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cblxuICB9LCB7XG4gICAga2V5OiBcImxpc3RDaGFuZ2VzQmFja1RvXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciBfbGlzdENoYW5nZXNCYWNrVG8gPSAoMCwgX2FzeW5jVG9HZW5lcmF0b3IyLmRlZmF1bHQpKFxuICAgICAgLyojX19QVVJFX18qL1xuICAgICAgX3JlZ2VuZXJhdG9yLmRlZmF1bHQubWFyayhmdW5jdGlvbiBfY2FsbGVlMTYoYXQpIHtcbiAgICAgICAgdmFyIF9yZWY1LCBjaGFuZ2VzO1xuXG4gICAgICAgIHJldHVybiBfcmVnZW5lcmF0b3IuZGVmYXVsdC53cmFwKGZ1bmN0aW9uIF9jYWxsZWUxNiQoX2NvbnRleHQxNikge1xuICAgICAgICAgIHdoaWxlICgxKSB7XG4gICAgICAgICAgICBzd2l0Y2ggKF9jb250ZXh0MTYucHJldiA9IF9jb250ZXh0MTYubmV4dCkge1xuICAgICAgICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICAgICAgX2NvbnRleHQxNi5uZXh0ID0gMjtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5pc0hpc3RvcnlDb21wbGV0ZSgpO1xuXG4gICAgICAgICAgICAgIGNhc2UgMjpcbiAgICAgICAgICAgICAgICBpZiAoX2NvbnRleHQxNi5zZW50KSB7XG4gICAgICAgICAgICAgICAgICBfY29udGV4dDE2Lm5leHQgPSA0O1xuICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQ29tcHV0aW5nIGEgc25hcHNob3QgaXMgb25seSBwb3NzaWJsZSB3aGVuIHRoZSBmdWxsIGhpc3RvcnkgZm9yIGEgXCIgKyBcImNvbGxlY3Rpb24gaXMgYXZhaWxhYmxlLiBIZXJlLCB0aGUgaGlzdG9yeSBwbHVnaW4gc2VlbXMgdG8gaGF2ZSBcIiArIFwiYmVlbiBlbmFibGVkIGFmdGVyIHRoZSBjcmVhdGlvbiBvZiB0aGUgY29sbGVjdGlvbi5cIik7XG5cbiAgICAgICAgICAgICAgY2FzZSA0OlxuICAgICAgICAgICAgICAgIF9jb250ZXh0MTYubmV4dCA9IDY7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuYnVja2V0Lmxpc3RIaXN0b3J5KHtcbiAgICAgICAgICAgICAgICAgIHBhZ2VzOiBJbmZpbml0eSxcbiAgICAgICAgICAgICAgICAgIC8vIGFsbCBwYWdlcyB1cCB0byB0YXJnZXQgdGltZXN0YW1wIGFyZSByZXF1aXJlZFxuICAgICAgICAgICAgICAgICAgc29ydDogXCItdGFyZ2V0LmRhdGEubGFzdF9tb2RpZmllZFwiLFxuICAgICAgICAgICAgICAgICAgZmlsdGVyczoge1xuICAgICAgICAgICAgICAgICAgICByZXNvdXJjZV9uYW1lOiBcInJlY29yZFwiLFxuICAgICAgICAgICAgICAgICAgICBjb2xsZWN0aW9uX2lkOiB0aGlzLm5hbWUsXG4gICAgICAgICAgICAgICAgICAgIFwibWF4X3RhcmdldC5kYXRhLmxhc3RfbW9kaWZpZWRcIjogU3RyaW5nKGF0KSAvLyBlcS4gdG8gPD1cblxuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgIGNhc2UgNjpcbiAgICAgICAgICAgICAgICBfcmVmNSA9IF9jb250ZXh0MTYuc2VudDtcbiAgICAgICAgICAgICAgICBjaGFuZ2VzID0gX3JlZjUuZGF0YTtcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQxNi5hYnJ1cHQoXCJyZXR1cm5cIiwgY2hhbmdlcyk7XG5cbiAgICAgICAgICAgICAgY2FzZSA5OlxuICAgICAgICAgICAgICBjYXNlIFwiZW5kXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0MTYuc3RvcCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSwgX2NhbGxlZTE2LCB0aGlzKTtcbiAgICAgIH0pKTtcblxuICAgICAgcmV0dXJuIGZ1bmN0aW9uIGxpc3RDaGFuZ2VzQmFja1RvKF94MTEpIHtcbiAgICAgICAgcmV0dXJuIF9saXN0Q2hhbmdlc0JhY2tUby5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgfTtcbiAgICB9KClcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuXG4gIH0sIHtcbiAgICBrZXk6IFwiZ2V0U25hcHNob3RcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gKCkge1xuICAgICAgdmFyIF9nZXRTbmFwc2hvdCA9ICgwLCBfYXN5bmNUb0dlbmVyYXRvcjIuZGVmYXVsdCkoXG4gICAgICAvKiNfX1BVUkVfXyovXG4gICAgICBfcmVnZW5lcmF0b3IuZGVmYXVsdC5tYXJrKGZ1bmN0aW9uIF9jYWxsZWUxNyhhdCkge1xuICAgICAgICB2YXIgY2hhbmdlcywgc2Vlbklkcywgc25hcHNob3QsIF9pdGVyYXRvck5vcm1hbENvbXBsZXRpb24sIF9kaWRJdGVyYXRvckVycm9yLCBfaXRlcmF0b3JFcnJvciwgX2xvb3AsIF9pdGVyYXRvciwgX3N0ZXA7XG5cbiAgICAgICAgcmV0dXJuIF9yZWdlbmVyYXRvci5kZWZhdWx0LndyYXAoZnVuY3Rpb24gX2NhbGxlZTE3JChfY29udGV4dDE3KSB7XG4gICAgICAgICAgd2hpbGUgKDEpIHtcbiAgICAgICAgICAgIHN3aXRjaCAoX2NvbnRleHQxNy5wcmV2ID0gX2NvbnRleHQxNy5uZXh0KSB7XG4gICAgICAgICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgICAgICBpZiAoISghTnVtYmVyLmlzSW50ZWdlcihhdCkgfHwgYXQgPD0gMCkpIHtcbiAgICAgICAgICAgICAgICAgIF9jb250ZXh0MTcubmV4dCA9IDI7XG4gICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJJbnZhbGlkIGFyZ3VtZW50LCBleHBlY3RlZCBhIHBvc2l0aXZlIGludGVnZXIuXCIpO1xuXG4gICAgICAgICAgICAgIGNhc2UgMjpcbiAgICAgICAgICAgICAgICBfY29udGV4dDE3Lm5leHQgPSA0O1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmxpc3RDaGFuZ2VzQmFja1RvKGF0KTtcblxuICAgICAgICAgICAgICBjYXNlIDQ6XG4gICAgICAgICAgICAgICAgY2hhbmdlcyA9IF9jb250ZXh0MTcuc2VudDtcbiAgICAgICAgICAgICAgICAvLyBSZXBsYXkgY2hhbmdlcyB0byBjb21wdXRlIHRoZSByZXF1ZXN0ZWQgc25hcHNob3QuXG4gICAgICAgICAgICAgICAgc2VlbklkcyA9IG5ldyBTZXQoKTtcbiAgICAgICAgICAgICAgICBzbmFwc2hvdCA9IFtdO1xuICAgICAgICAgICAgICAgIF9pdGVyYXRvck5vcm1hbENvbXBsZXRpb24gPSB0cnVlO1xuICAgICAgICAgICAgICAgIF9kaWRJdGVyYXRvckVycm9yID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgX2l0ZXJhdG9yRXJyb3IgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICAgICAgX2NvbnRleHQxNy5wcmV2ID0gMTA7XG5cbiAgICAgICAgICAgICAgICBfbG9vcCA9IGZ1bmN0aW9uIF9sb29wKCkge1xuICAgICAgICAgICAgICAgICAgdmFyIF9yZWY2ID0gX3N0ZXAudmFsdWU7XG4gICAgICAgICAgICAgICAgICB2YXIgYWN0aW9uID0gX3JlZjYuYWN0aW9uLFxuICAgICAgICAgICAgICAgICAgICAgIHJlY29yZCA9IF9yZWY2LnRhcmdldC5kYXRhO1xuXG4gICAgICAgICAgICAgICAgICBpZiAoYWN0aW9uID09IFwiZGVsZXRlXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgc2Vlbklkcy5hZGQocmVjb3JkLmlkKTsgLy8gZW5zdXJlIG5vdCByZXByb2Nlc3NpbmcgZGVsZXRlZCBlbnRyaWVzXG5cbiAgICAgICAgICAgICAgICAgICAgc25hcHNob3QgPSBzbmFwc2hvdC5maWx0ZXIoZnVuY3Rpb24gKHIpIHtcbiAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gci5pZCAhPT0gcmVjb3JkLmlkO1xuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoIXNlZW5JZHMuaGFzKHJlY29yZC5pZCkpIHtcbiAgICAgICAgICAgICAgICAgICAgc2Vlbklkcy5hZGQocmVjb3JkLmlkKTtcbiAgICAgICAgICAgICAgICAgICAgc25hcHNob3QucHVzaChyZWNvcmQpO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgICAgICBmb3IgKF9pdGVyYXRvciA9IGNoYW5nZXNbU3ltYm9sLml0ZXJhdG9yXSgpOyAhKF9pdGVyYXRvck5vcm1hbENvbXBsZXRpb24gPSAoX3N0ZXAgPSBfaXRlcmF0b3IubmV4dCgpKS5kb25lKTsgX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbiA9IHRydWUpIHtcbiAgICAgICAgICAgICAgICAgIF9sb29wKCk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgX2NvbnRleHQxNy5uZXh0ID0gMTk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICAgICAgY2FzZSAxNTpcbiAgICAgICAgICAgICAgICBfY29udGV4dDE3LnByZXYgPSAxNTtcbiAgICAgICAgICAgICAgICBfY29udGV4dDE3LnQwID0gX2NvbnRleHQxN1tcImNhdGNoXCJdKDEwKTtcbiAgICAgICAgICAgICAgICBfZGlkSXRlcmF0b3JFcnJvciA9IHRydWU7XG4gICAgICAgICAgICAgICAgX2l0ZXJhdG9yRXJyb3IgPSBfY29udGV4dDE3LnQwO1xuXG4gICAgICAgICAgICAgIGNhc2UgMTk6XG4gICAgICAgICAgICAgICAgX2NvbnRleHQxNy5wcmV2ID0gMTk7XG4gICAgICAgICAgICAgICAgX2NvbnRleHQxNy5wcmV2ID0gMjA7XG5cbiAgICAgICAgICAgICAgICBpZiAoIV9pdGVyYXRvck5vcm1hbENvbXBsZXRpb24gJiYgX2l0ZXJhdG9yLnJldHVybiAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICBfaXRlcmF0b3IucmV0dXJuKCk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIGNhc2UgMjI6XG4gICAgICAgICAgICAgICAgX2NvbnRleHQxNy5wcmV2ID0gMjI7XG5cbiAgICAgICAgICAgICAgICBpZiAoIV9kaWRJdGVyYXRvckVycm9yKSB7XG4gICAgICAgICAgICAgICAgICBfY29udGV4dDE3Lm5leHQgPSAyNTtcbiAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRocm93IF9pdGVyYXRvckVycm9yO1xuXG4gICAgICAgICAgICAgIGNhc2UgMjU6XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0MTcuZmluaXNoKDIyKTtcblxuICAgICAgICAgICAgICBjYXNlIDI2OlxuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDE3LmZpbmlzaCgxOSk7XG5cbiAgICAgICAgICAgICAgY2FzZSAyNzpcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQxNy5hYnJ1cHQoXCJyZXR1cm5cIiwge1xuICAgICAgICAgICAgICAgICAgbGFzdF9tb2RpZmllZDogU3RyaW5nKGF0KSxcbiAgICAgICAgICAgICAgICAgIGRhdGE6IHNuYXBzaG90LnNvcnQoZnVuY3Rpb24gKGEsIGIpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGIubGFzdF9tb2RpZmllZCAtIGEubGFzdF9tb2RpZmllZDtcbiAgICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICAgICAgbmV4dDogZnVuY3Rpb24gbmV4dCgpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiU25hcHNob3RzIGRvbid0IHN1cHBvcnQgcGFnaW5hdGlvblwiKTtcbiAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICBoYXNOZXh0UGFnZTogZmFsc2UsXG4gICAgICAgICAgICAgICAgICB0b3RhbFJlY29yZHM6IHNuYXBzaG90Lmxlbmd0aFxuICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgIGNhc2UgMjg6XG4gICAgICAgICAgICAgIGNhc2UgXCJlbmRcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQxNy5zdG9wKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9LCBfY2FsbGVlMTcsIHRoaXMsIFtbMTAsIDE1LCAxOSwgMjddLCBbMjAsLCAyMiwgMjZdXSk7XG4gICAgICB9KSk7XG5cbiAgICAgIHJldHVybiBmdW5jdGlvbiBnZXRTbmFwc2hvdChfeDEyKSB7XG4gICAgICAgIHJldHVybiBfZ2V0U25hcHNob3QuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgIH07XG4gICAgfSgpXG4gICAgLyoqXG4gICAgICogUGVyZm9ybXMgYmF0Y2ggb3BlcmF0aW9ucyBhdCB0aGUgY3VycmVudCBjb2xsZWN0aW9uIGxldmVsLlxuICAgICAqXG4gICAgICogQHBhcmFtICB7RnVuY3Rpb259IGZuICAgICAgICAgICAgICAgICAgIFRoZSBiYXRjaCBvcGVyYXRpb24gZnVuY3Rpb24uXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSAgIFtvcHRpb25zPXt9XSAgICAgICAgIFRoZSBvcHRpb25zIG9iamVjdC5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICAgW29wdGlvbnMuaGVhZGVyc10gICAgVGhlIGhlYWRlcnMgb2JqZWN0IG9wdGlvbi5cbiAgICAgKiBAcGFyYW0gIHtCb29sZWFufSAgW29wdGlvbnMuc2FmZV0gICAgICAgVGhlIHNhZmUgb3B0aW9uLlxuICAgICAqIEBwYXJhbSAge051bWJlcn0gICBbb3B0aW9ucy5yZXRyeV0gICAgICBUaGUgcmV0cnkgb3B0aW9uLlxuICAgICAqIEBwYXJhbSAge0Jvb2xlYW59ICBbb3B0aW9ucy5hZ2dyZWdhdGVdICBQcm9kdWNlcyBhIGdyb3VwZWQgcmVzdWx0IG9iamVjdC5cbiAgICAgKiBAcmV0dXJuIHtQcm9taXNlPE9iamVjdCwgRXJyb3I+fVxuICAgICAqL1xuXG4gIH0sIHtcbiAgICBrZXk6IFwiYmF0Y2hcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gKCkge1xuICAgICAgdmFyIF9iYXRjaCA9ICgwLCBfYXN5bmNUb0dlbmVyYXRvcjIuZGVmYXVsdCkoXG4gICAgICAvKiNfX1BVUkVfXyovXG4gICAgICBfcmVnZW5lcmF0b3IuZGVmYXVsdC5tYXJrKGZ1bmN0aW9uIF9jYWxsZWUxOChmbikge1xuICAgICAgICB2YXIgb3B0aW9ucyxcbiAgICAgICAgICAgIF9hcmdzMTggPSBhcmd1bWVudHM7XG4gICAgICAgIHJldHVybiBfcmVnZW5lcmF0b3IuZGVmYXVsdC53cmFwKGZ1bmN0aW9uIF9jYWxsZWUxOCQoX2NvbnRleHQxOCkge1xuICAgICAgICAgIHdoaWxlICgxKSB7XG4gICAgICAgICAgICBzd2l0Y2ggKF9jb250ZXh0MTgucHJldiA9IF9jb250ZXh0MTgubmV4dCkge1xuICAgICAgICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICAgICAgb3B0aW9ucyA9IF9hcmdzMTgubGVuZ3RoID4gMSAmJiBfYXJnczE4WzFdICE9PSB1bmRlZmluZWQgPyBfYXJnczE4WzFdIDoge307XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0MTguYWJydXB0KFwicmV0dXJuXCIsIHRoaXMuY2xpZW50LmJhdGNoKGZuLCB7XG4gICAgICAgICAgICAgICAgICBidWNrZXQ6IHRoaXMuYnVja2V0Lm5hbWUsXG4gICAgICAgICAgICAgICAgICBjb2xsZWN0aW9uOiB0aGlzLm5hbWUsXG4gICAgICAgICAgICAgICAgICBoZWFkZXJzOiB0aGlzLl9nZXRIZWFkZXJzKG9wdGlvbnMpLFxuICAgICAgICAgICAgICAgICAgcmV0cnk6IHRoaXMuX2dldFJldHJ5KG9wdGlvbnMpLFxuICAgICAgICAgICAgICAgICAgc2FmZTogdGhpcy5fZ2V0U2FmZShvcHRpb25zKSxcbiAgICAgICAgICAgICAgICAgIGFnZ3JlZ2F0ZTogISFvcHRpb25zLmFnZ3JlZ2F0ZVxuICAgICAgICAgICAgICAgIH0pKTtcblxuICAgICAgICAgICAgICBjYXNlIDI6XG4gICAgICAgICAgICAgIGNhc2UgXCJlbmRcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQxOC5zdG9wKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9LCBfY2FsbGVlMTgsIHRoaXMpO1xuICAgICAgfSkpO1xuXG4gICAgICByZXR1cm4gZnVuY3Rpb24gYmF0Y2goX3gxMykge1xuICAgICAgICByZXR1cm4gX2JhdGNoLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICB9O1xuICAgIH0oKVxuICB9XSk7XG4gIHJldHVybiBDb2xsZWN0aW9uO1xufSgpLCAoKDAsIF9hcHBseURlY29yYXRlZERlc2NyaXB0b3IyLmRlZmF1bHQpKF9jbGFzcy5wcm90b3R5cGUsIFwiYWRkQXR0YWNobWVudFwiLCBbX2RlY10sIE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoX2NsYXNzLnByb3RvdHlwZSwgXCJhZGRBdHRhY2htZW50XCIpLCBfY2xhc3MucHJvdG90eXBlKSwgKDAsIF9hcHBseURlY29yYXRlZERlc2NyaXB0b3IyLmRlZmF1bHQpKF9jbGFzcy5wcm90b3R5cGUsIFwicmVtb3ZlQXR0YWNobWVudFwiLCBbX2RlYzJdLCBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKF9jbGFzcy5wcm90b3R5cGUsIFwicmVtb3ZlQXR0YWNobWVudFwiKSwgX2NsYXNzLnByb3RvdHlwZSksICgwLCBfYXBwbHlEZWNvcmF0ZWREZXNjcmlwdG9yMi5kZWZhdWx0KShfY2xhc3MucHJvdG90eXBlLCBcImdldFNuYXBzaG90XCIsIFtfZGVjM10sIE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoX2NsYXNzLnByb3RvdHlwZSwgXCJnZXRTbmFwc2hvdFwiKSwgX2NsYXNzLnByb3RvdHlwZSkpLCBfY2xhc3MpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IENvbGxlY3Rpb247IiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5leHBvcnRzLmRlZmF1bHQgPSBlbmRwb2ludDtcblxuLyoqXG4gKiBFbmRwb2ludHMgdGVtcGxhdGVzLlxuICogQHR5cGUge09iamVjdH1cbiAqL1xudmFyIEVORFBPSU5UUyA9IHtcbiAgcm9vdDogZnVuY3Rpb24gcm9vdCgpIHtcbiAgICByZXR1cm4gXCIvXCI7XG4gIH0sXG4gIGJhdGNoOiBmdW5jdGlvbiBiYXRjaCgpIHtcbiAgICByZXR1cm4gXCIvYmF0Y2hcIjtcbiAgfSxcbiAgcGVybWlzc2lvbnM6IGZ1bmN0aW9uIHBlcm1pc3Npb25zKCkge1xuICAgIHJldHVybiBcIi9wZXJtaXNzaW9uc1wiO1xuICB9LFxuICBidWNrZXQ6IGZ1bmN0aW9uIGJ1Y2tldChfYnVja2V0KSB7XG4gICAgcmV0dXJuIFwiL2J1Y2tldHNcIiArIChfYnVja2V0ID8gXCIvXCIuY29uY2F0KF9idWNrZXQpIDogXCJcIik7XG4gIH0sXG4gIGhpc3Rvcnk6IGZ1bmN0aW9uIGhpc3RvcnkoYnVja2V0KSB7XG4gICAgcmV0dXJuIFwiXCIuY29uY2F0KEVORFBPSU5UUy5idWNrZXQoYnVja2V0KSwgXCIvaGlzdG9yeVwiKTtcbiAgfSxcbiAgY29sbGVjdGlvbjogZnVuY3Rpb24gY29sbGVjdGlvbihidWNrZXQsIGNvbGwpIHtcbiAgICByZXR1cm4gXCJcIi5jb25jYXQoRU5EUE9JTlRTLmJ1Y2tldChidWNrZXQpLCBcIi9jb2xsZWN0aW9uc1wiKSArIChjb2xsID8gXCIvXCIuY29uY2F0KGNvbGwpIDogXCJcIik7XG4gIH0sXG4gIGdyb3VwOiBmdW5jdGlvbiBncm91cChidWNrZXQsIF9ncm91cCkge1xuICAgIHJldHVybiBcIlwiLmNvbmNhdChFTkRQT0lOVFMuYnVja2V0KGJ1Y2tldCksIFwiL2dyb3Vwc1wiKSArIChfZ3JvdXAgPyBcIi9cIi5jb25jYXQoX2dyb3VwKSA6IFwiXCIpO1xuICB9LFxuICByZWNvcmQ6IGZ1bmN0aW9uIHJlY29yZChidWNrZXQsIGNvbGwsIGlkKSB7XG4gICAgcmV0dXJuIFwiXCIuY29uY2F0KEVORFBPSU5UUy5jb2xsZWN0aW9uKGJ1Y2tldCwgY29sbCksIFwiL3JlY29yZHNcIikgKyAoaWQgPyBcIi9cIi5jb25jYXQoaWQpIDogXCJcIik7XG4gIH0sXG4gIGF0dGFjaG1lbnQ6IGZ1bmN0aW9uIGF0dGFjaG1lbnQoYnVja2V0LCBjb2xsLCBpZCkge1xuICAgIHJldHVybiBcIlwiLmNvbmNhdChFTkRQT0lOVFMucmVjb3JkKGJ1Y2tldCwgY29sbCwgaWQpLCBcIi9hdHRhY2htZW50XCIpO1xuICB9XG59O1xuLyoqXG4gKiBSZXRyaWV2ZXMgYSBzZXJ2ZXIgZW5wb2ludCBieSBpdHMgbmFtZS5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtICB7U3RyaW5nfSAgICBuYW1lIFRoZSBlbmRwb2ludCBuYW1lLlxuICogQHBhcmFtICB7Li4uc3RyaW5nfSBhcmdzIFRoZSBlbmRwb2ludCBwYXJhbWV0ZXJzLlxuICogQHJldHVybiB7U3RyaW5nfVxuICovXG5cbmZ1bmN0aW9uIGVuZHBvaW50KG5hbWUpIHtcbiAgZm9yICh2YXIgX2xlbiA9IGFyZ3VtZW50cy5sZW5ndGgsIGFyZ3MgPSBuZXcgQXJyYXkoX2xlbiA+IDEgPyBfbGVuIC0gMSA6IDApLCBfa2V5ID0gMTsgX2tleSA8IF9sZW47IF9rZXkrKykge1xuICAgIGFyZ3NbX2tleSAtIDFdID0gYXJndW1lbnRzW19rZXldO1xuICB9XG5cbiAgcmV0dXJuIEVORFBPSU5UU1tuYW1lXS5hcHBseShFTkRQT0lOVFMsIGFyZ3MpO1xufSIsIlwidXNlIHN0cmljdFwiO1xuXG52YXIgX2ludGVyb3BSZXF1aXJlRGVmYXVsdCA9IHJlcXVpcmUoXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2ludGVyb3BSZXF1aXJlRGVmYXVsdFwiKTtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcbmV4cG9ydHMuVW5wYXJzZWFibGVSZXNwb25zZUVycm9yID0gZXhwb3J0cy5TZXJ2ZXJSZXNwb25zZSA9IGV4cG9ydHMuTmV0d29ya1RpbWVvdXRFcnJvciA9IGV4cG9ydHMuZGVmYXVsdCA9IHZvaWQgMDtcblxudmFyIF9jbGFzc0NhbGxDaGVjazIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KHJlcXVpcmUoXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2NsYXNzQ2FsbENoZWNrXCIpKTtcblxudmFyIF9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvcG9zc2libGVDb25zdHJ1Y3RvclJldHVyblwiKSk7XG5cbnZhciBfZ2V0UHJvdG90eXBlT2YyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9nZXRQcm90b3R5cGVPZlwiKSk7XG5cbnZhciBfaW5oZXJpdHMyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9pbmhlcml0c1wiKSk7XG5cbnZhciBfYXNzZXJ0VGhpc0luaXRpYWxpemVkMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvYXNzZXJ0VGhpc0luaXRpYWxpemVkXCIpKTtcblxuZnVuY3Rpb24gX2V4dGVuZGFibGVCdWlsdGluNShjbHMpIHtcbiAgZnVuY3Rpb24gRXh0ZW5kYWJsZUJ1aWx0aW4oKSB7XG4gICAgdmFyIGluc3RhbmNlID0gUmVmbGVjdC5jb25zdHJ1Y3QoY2xzLCBBcnJheS5mcm9tKGFyZ3VtZW50cykpO1xuICAgIE9iamVjdC5zZXRQcm90b3R5cGVPZihpbnN0YW5jZSwgT2JqZWN0LmdldFByb3RvdHlwZU9mKHRoaXMpKTtcbiAgICByZXR1cm4gaW5zdGFuY2U7XG4gIH1cblxuICBFeHRlbmRhYmxlQnVpbHRpbi5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKGNscy5wcm90b3R5cGUsIHtcbiAgICBjb25zdHJ1Y3Rvcjoge1xuICAgICAgdmFsdWU6IGNscyxcbiAgICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgICAgd3JpdGFibGU6IHRydWUsXG4gICAgICBjb25maWd1cmFibGU6IHRydWVcbiAgICB9XG4gIH0pO1xuXG4gIGlmIChPYmplY3Quc2V0UHJvdG90eXBlT2YpIHtcbiAgICBPYmplY3Quc2V0UHJvdG90eXBlT2YoRXh0ZW5kYWJsZUJ1aWx0aW4sIGNscyk7XG4gIH0gZWxzZSB7XG4gICAgRXh0ZW5kYWJsZUJ1aWx0aW4uX19wcm90b19fID0gY2xzO1xuICB9XG5cbiAgcmV0dXJuIEV4dGVuZGFibGVCdWlsdGluO1xufVxuXG5mdW5jdGlvbiBfZXh0ZW5kYWJsZUJ1aWx0aW4zKGNscykge1xuICBmdW5jdGlvbiBFeHRlbmRhYmxlQnVpbHRpbigpIHtcbiAgICB2YXIgaW5zdGFuY2UgPSBSZWZsZWN0LmNvbnN0cnVjdChjbHMsIEFycmF5LmZyb20oYXJndW1lbnRzKSk7XG4gICAgT2JqZWN0LnNldFByb3RvdHlwZU9mKGluc3RhbmNlLCBPYmplY3QuZ2V0UHJvdG90eXBlT2YodGhpcykpO1xuICAgIHJldHVybiBpbnN0YW5jZTtcbiAgfVxuXG4gIEV4dGVuZGFibGVCdWlsdGluLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoY2xzLnByb3RvdHlwZSwge1xuICAgIGNvbnN0cnVjdG9yOiB7XG4gICAgICB2YWx1ZTogY2xzLFxuICAgICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgICB3cml0YWJsZTogdHJ1ZSxcbiAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxuICAgIH1cbiAgfSk7XG5cbiAgaWYgKE9iamVjdC5zZXRQcm90b3R5cGVPZikge1xuICAgIE9iamVjdC5zZXRQcm90b3R5cGVPZihFeHRlbmRhYmxlQnVpbHRpbiwgY2xzKTtcbiAgfSBlbHNlIHtcbiAgICBFeHRlbmRhYmxlQnVpbHRpbi5fX3Byb3RvX18gPSBjbHM7XG4gIH1cblxuICByZXR1cm4gRXh0ZW5kYWJsZUJ1aWx0aW47XG59XG5cbmZ1bmN0aW9uIF9leHRlbmRhYmxlQnVpbHRpbihjbHMpIHtcbiAgZnVuY3Rpb24gRXh0ZW5kYWJsZUJ1aWx0aW4oKSB7XG4gICAgdmFyIGluc3RhbmNlID0gUmVmbGVjdC5jb25zdHJ1Y3QoY2xzLCBBcnJheS5mcm9tKGFyZ3VtZW50cykpO1xuICAgIE9iamVjdC5zZXRQcm90b3R5cGVPZihpbnN0YW5jZSwgT2JqZWN0LmdldFByb3RvdHlwZU9mKHRoaXMpKTtcbiAgICByZXR1cm4gaW5zdGFuY2U7XG4gIH1cblxuICBFeHRlbmRhYmxlQnVpbHRpbi5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKGNscy5wcm90b3R5cGUsIHtcbiAgICBjb25zdHJ1Y3Rvcjoge1xuICAgICAgdmFsdWU6IGNscyxcbiAgICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgICAgd3JpdGFibGU6IHRydWUsXG4gICAgICBjb25maWd1cmFibGU6IHRydWVcbiAgICB9XG4gIH0pO1xuXG4gIGlmIChPYmplY3Quc2V0UHJvdG90eXBlT2YpIHtcbiAgICBPYmplY3Quc2V0UHJvdG90eXBlT2YoRXh0ZW5kYWJsZUJ1aWx0aW4sIGNscyk7XG4gIH0gZWxzZSB7XG4gICAgRXh0ZW5kYWJsZUJ1aWx0aW4uX19wcm90b19fID0gY2xzO1xuICB9XG5cbiAgcmV0dXJuIEV4dGVuZGFibGVCdWlsdGluO1xufVxuXG4vKipcbiAqIEtpbnRvIHNlcnZlciBlcnJvciBjb2RlIGRlc2NyaXB0b3JzLlxuICogQHR5cGUge09iamVjdH1cbiAqL1xudmFyIEVSUk9SX0NPREVTID0ge1xuICAxMDQ6IFwiTWlzc2luZyBBdXRob3JpemF0aW9uIFRva2VuXCIsXG4gIDEwNTogXCJJbnZhbGlkIEF1dGhvcml6YXRpb24gVG9rZW5cIixcbiAgMTA2OiBcIlJlcXVlc3QgYm9keSB3YXMgbm90IHZhbGlkIEpTT05cIixcbiAgMTA3OiBcIkludmFsaWQgcmVxdWVzdCBwYXJhbWV0ZXJcIixcbiAgMTA4OiBcIk1pc3NpbmcgcmVxdWVzdCBwYXJhbWV0ZXJcIixcbiAgMTA5OiBcIkludmFsaWQgcG9zdGVkIGRhdGFcIixcbiAgMTEwOiBcIkludmFsaWQgVG9rZW4gLyBpZFwiLFxuICAxMTE6IFwiTWlzc2luZyBUb2tlbiAvIGlkXCIsXG4gIDExMjogXCJDb250ZW50LUxlbmd0aCBoZWFkZXIgd2FzIG5vdCBwcm92aWRlZFwiLFxuICAxMTM6IFwiUmVxdWVzdCBib2R5IHRvbyBsYXJnZVwiLFxuICAxMTQ6IFwiUmVzb3VyY2Ugd2FzIGNyZWF0ZWQsIHVwZGF0ZWQgb3IgZGVsZXRlZCBtZWFud2hpbGVcIixcbiAgMTE1OiBcIk1ldGhvZCBub3QgYWxsb3dlZCBvbiB0aGlzIGVuZCBwb2ludCAoaGludDogc2VydmVyIG1heSBiZSByZWFkb25seSlcIixcbiAgMTE2OiBcIlJlcXVlc3RlZCB2ZXJzaW9uIG5vdCBhdmFpbGFibGUgb24gdGhpcyBzZXJ2ZXJcIixcbiAgMTE3OiBcIkNsaWVudCBoYXMgc2VudCB0b28gbWFueSByZXF1ZXN0c1wiLFxuICAxMjE6IFwiUmVzb3VyY2UgYWNjZXNzIGlzIGZvcmJpZGRlbiBmb3IgdGhpcyB1c2VyXCIsXG4gIDEyMjogXCJBbm90aGVyIHJlc291cmNlIHZpb2xhdGVzIGNvbnN0cmFpbnRcIixcbiAgMjAxOiBcIlNlcnZpY2UgVGVtcG9yYXJ5IHVuYXZhaWxhYmxlIGR1ZSB0byBoaWdoIGxvYWRcIixcbiAgMjAyOiBcIlNlcnZpY2UgZGVwcmVjYXRlZFwiLFxuICA5OTk6IFwiSW50ZXJuYWwgU2VydmVyIEVycm9yXCJcbn07XG52YXIgX2RlZmF1bHQgPSBFUlJPUl9DT0RFUztcbmV4cG9ydHMuZGVmYXVsdCA9IF9kZWZhdWx0O1xuXG52YXIgTmV0d29ya1RpbWVvdXRFcnJvciA9XG4vKiNfX1BVUkVfXyovXG5mdW5jdGlvbiAoX2V4dGVuZGFibGVCdWlsdGluMikge1xuICAoMCwgX2luaGVyaXRzMi5kZWZhdWx0KShOZXR3b3JrVGltZW91dEVycm9yLCBfZXh0ZW5kYWJsZUJ1aWx0aW4yKTtcblxuICBmdW5jdGlvbiBOZXR3b3JrVGltZW91dEVycm9yKHVybCwgb3B0aW9ucykge1xuICAgIHZhciBfdGhpcztcblxuICAgICgwLCBfY2xhc3NDYWxsQ2hlY2syLmRlZmF1bHQpKHRoaXMsIE5ldHdvcmtUaW1lb3V0RXJyb3IpO1xuICAgIF90aGlzID0gKDAsIF9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuMi5kZWZhdWx0KSh0aGlzLCAoMCwgX2dldFByb3RvdHlwZU9mMi5kZWZhdWx0KShOZXR3b3JrVGltZW91dEVycm9yKS5jYWxsKHRoaXMsIFwiVGltZW91dCB3aGlsZSB0cnlpbmcgdG8gYWNjZXNzIFwiLmNvbmNhdCh1cmwsIFwiIHdpdGggXCIpLmNvbmNhdChKU09OLnN0cmluZ2lmeShvcHRpb25zKSkpKTtcblxuICAgIGlmIChFcnJvci5jYXB0dXJlU3RhY2tUcmFjZSkge1xuICAgICAgRXJyb3IuY2FwdHVyZVN0YWNrVHJhY2UoKDAsIF9hc3NlcnRUaGlzSW5pdGlhbGl6ZWQyLmRlZmF1bHQpKCgwLCBfYXNzZXJ0VGhpc0luaXRpYWxpemVkMi5kZWZhdWx0KShfdGhpcykpLCBOZXR3b3JrVGltZW91dEVycm9yKTtcbiAgICB9XG5cbiAgICBfdGhpcy51cmwgPSB1cmw7XG4gICAgX3RoaXMub3B0aW9ucyA9IG9wdGlvbnM7XG4gICAgcmV0dXJuIF90aGlzO1xuICB9XG5cbiAgcmV0dXJuIE5ldHdvcmtUaW1lb3V0RXJyb3I7XG59KF9leHRlbmRhYmxlQnVpbHRpbihFcnJvcikpO1xuXG5leHBvcnRzLk5ldHdvcmtUaW1lb3V0RXJyb3IgPSBOZXR3b3JrVGltZW91dEVycm9yO1xuXG52YXIgVW5wYXJzZWFibGVSZXNwb25zZUVycm9yID1cbi8qI19fUFVSRV9fKi9cbmZ1bmN0aW9uIChfZXh0ZW5kYWJsZUJ1aWx0aW40KSB7XG4gICgwLCBfaW5oZXJpdHMyLmRlZmF1bHQpKFVucGFyc2VhYmxlUmVzcG9uc2VFcnJvciwgX2V4dGVuZGFibGVCdWlsdGluNCk7XG5cbiAgZnVuY3Rpb24gVW5wYXJzZWFibGVSZXNwb25zZUVycm9yKHJlc3BvbnNlLCBib2R5LCBlcnJvcikge1xuICAgIHZhciBfdGhpczI7XG5cbiAgICAoMCwgX2NsYXNzQ2FsbENoZWNrMi5kZWZhdWx0KSh0aGlzLCBVbnBhcnNlYWJsZVJlc3BvbnNlRXJyb3IpO1xuICAgIHZhciBzdGF0dXMgPSByZXNwb25zZS5zdGF0dXM7XG4gICAgX3RoaXMyID0gKDAsIF9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuMi5kZWZhdWx0KSh0aGlzLCAoMCwgX2dldFByb3RvdHlwZU9mMi5kZWZhdWx0KShVbnBhcnNlYWJsZVJlc3BvbnNlRXJyb3IpLmNhbGwodGhpcywgXCJSZXNwb25zZSBmcm9tIHNlcnZlciB1bnBhcnNlYWJsZSAoSFRUUCBcIi5jb25jYXQoc3RhdHVzIHx8IDAsIFwiOyBcIikuY29uY2F0KGVycm9yLCBcIik6IFwiKS5jb25jYXQoYm9keSkpKTtcblxuICAgIGlmIChFcnJvci5jYXB0dXJlU3RhY2tUcmFjZSkge1xuICAgICAgRXJyb3IuY2FwdHVyZVN0YWNrVHJhY2UoKDAsIF9hc3NlcnRUaGlzSW5pdGlhbGl6ZWQyLmRlZmF1bHQpKCgwLCBfYXNzZXJ0VGhpc0luaXRpYWxpemVkMi5kZWZhdWx0KShfdGhpczIpKSwgVW5wYXJzZWFibGVSZXNwb25zZUVycm9yKTtcbiAgICB9XG5cbiAgICBfdGhpczIuc3RhdHVzID0gc3RhdHVzO1xuICAgIF90aGlzMi5yZXNwb25zZSA9IHJlc3BvbnNlO1xuICAgIF90aGlzMi5zdGFjayA9IGVycm9yLnN0YWNrO1xuICAgIF90aGlzMi5lcnJvciA9IGVycm9yO1xuICAgIHJldHVybiBfdGhpczI7XG4gIH1cblxuICByZXR1cm4gVW5wYXJzZWFibGVSZXNwb25zZUVycm9yO1xufShfZXh0ZW5kYWJsZUJ1aWx0aW4zKEVycm9yKSk7XG4vKipcbiAqIFwiRXJyb3JcIiBzdWJjbGFzcyByZXByZXNlbnRpbmcgYSA+PTQwMCByZXNwb25zZSBmcm9tIHRoZSBzZXJ2ZXIuXG4gKlxuICogV2hldGhlciBvciBub3QgdGhpcyBpcyBhbiBlcnJvciBkZXBlbmRzIG9uIHlvdXIgYXBwbGljYXRpb24uXG4gKlxuICogVGhlIGBqc29uYCBmaWVsZCBjYW4gYmUgdW5kZWZpbmVkIGlmIHRoZSBzZXJ2ZXIgcmVzcG9uZGVkIHdpdGggYW5cbiAqIGVtcHR5IHJlc3BvbnNlIGJvZHkuIFRoaXMgc2hvdWxkbid0IGdlbmVyYWxseSBoYXBwZW4uIE1vc3QgXCJiYWRcIlxuICogcmVzcG9uc2VzIGNvbWUgd2l0aCBhIEpTT04gZXJyb3IgZGVzY3JpcHRpb24sIG9yIChpZiB0aGV5J3JlXG4gKiBmcm9udGVkIGJ5IGEgQ0ROIG9yIG5naW54IG9yIHNvbWV0aGluZykgb2NjYXNpb25hbGx5IG5vbi1KU09OXG4gKiByZXNwb25zZXMgKHdoaWNoIGJlY29tZSBVbnBhcnNlYWJsZVJlc3BvbnNlRXJyb3JzLCBhYm92ZSkuXG4gKi9cblxuXG5leHBvcnRzLlVucGFyc2VhYmxlUmVzcG9uc2VFcnJvciA9IFVucGFyc2VhYmxlUmVzcG9uc2VFcnJvcjtcblxudmFyIFNlcnZlclJlc3BvbnNlID1cbi8qI19fUFVSRV9fKi9cbmZ1bmN0aW9uIChfZXh0ZW5kYWJsZUJ1aWx0aW42KSB7XG4gICgwLCBfaW5oZXJpdHMyLmRlZmF1bHQpKFNlcnZlclJlc3BvbnNlLCBfZXh0ZW5kYWJsZUJ1aWx0aW42KTtcblxuICBmdW5jdGlvbiBTZXJ2ZXJSZXNwb25zZShyZXNwb25zZSwganNvbikge1xuICAgIHZhciBfdGhpczM7XG5cbiAgICAoMCwgX2NsYXNzQ2FsbENoZWNrMi5kZWZhdWx0KSh0aGlzLCBTZXJ2ZXJSZXNwb25zZSk7XG4gICAgdmFyIHN0YXR1cyA9IHJlc3BvbnNlLnN0YXR1cztcbiAgICB2YXIgc3RhdHVzVGV4dCA9IHJlc3BvbnNlLnN0YXR1c1RleHQ7XG4gICAgdmFyIGVycm5vTXNnO1xuXG4gICAgaWYgKGpzb24pIHtcbiAgICAgIC8vIFRyeSB0byBmaWxsIGluIGluZm9ybWF0aW9uIGZyb20gdGhlIEpTT04gZXJyb3IuXG4gICAgICBzdGF0dXNUZXh0ID0ganNvbi5lcnJvciB8fCBzdGF0dXNUZXh0OyAvLyBUYWtlIGVycm5vTXNnIGZyb20gZWl0aGVyIEVSUk9SX0NPREVTIG9yIGpzb24ubWVzc2FnZS5cblxuICAgICAgaWYgKGpzb24uZXJybm8gJiYganNvbi5lcnJubyBpbiBFUlJPUl9DT0RFUykge1xuICAgICAgICBlcnJub01zZyA9IEVSUk9SX0NPREVTW2pzb24uZXJybm9dO1xuICAgICAgfSBlbHNlIGlmIChqc29uLm1lc3NhZ2UpIHtcbiAgICAgICAgZXJybm9Nc2cgPSBqc29uLm1lc3NhZ2U7XG4gICAgICB9IC8vIElmIHdlIGhhZCBib3RoIEVSUk9SX0NPREVTIGFuZCBqc29uLm1lc3NhZ2UsIGFuZCB0aGV5IGRpZmZlcixcbiAgICAgIC8vIGNvbWJpbmUgdGhlbS5cblxuXG4gICAgICBpZiAoZXJybm9Nc2cgJiYganNvbi5tZXNzYWdlICYmIGpzb24ubWVzc2FnZSAhPT0gZXJybm9Nc2cpIHtcbiAgICAgICAgZXJybm9Nc2cgKz0gXCIgKFwiLmNvbmNhdChqc29uLm1lc3NhZ2UsIFwiKVwiKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgbWVzc2FnZSA9IFwiSFRUUCBcIi5jb25jYXQoc3RhdHVzLCBcIiBcIikuY29uY2F0KHN0YXR1c1RleHQpO1xuXG4gICAgaWYgKGVycm5vTXNnKSB7XG4gICAgICBtZXNzYWdlICs9IFwiOiBcIi5jb25jYXQoZXJybm9Nc2cpO1xuICAgIH1cblxuICAgIF90aGlzMyA9ICgwLCBfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybjIuZGVmYXVsdCkodGhpcywgKDAsIF9nZXRQcm90b3R5cGVPZjIuZGVmYXVsdCkoU2VydmVyUmVzcG9uc2UpLmNhbGwodGhpcywgbWVzc2FnZS50cmltKCkpKTtcblxuICAgIGlmIChFcnJvci5jYXB0dXJlU3RhY2tUcmFjZSkge1xuICAgICAgRXJyb3IuY2FwdHVyZVN0YWNrVHJhY2UoKDAsIF9hc3NlcnRUaGlzSW5pdGlhbGl6ZWQyLmRlZmF1bHQpKCgwLCBfYXNzZXJ0VGhpc0luaXRpYWxpemVkMi5kZWZhdWx0KShfdGhpczMpKSwgU2VydmVyUmVzcG9uc2UpO1xuICAgIH1cblxuICAgIF90aGlzMy5yZXNwb25zZSA9IHJlc3BvbnNlO1xuICAgIF90aGlzMy5kYXRhID0ganNvbjtcbiAgICByZXR1cm4gX3RoaXMzO1xuICB9XG5cbiAgcmV0dXJuIFNlcnZlclJlc3BvbnNlO1xufShfZXh0ZW5kYWJsZUJ1aWx0aW41KEVycm9yKSk7XG5cbmV4cG9ydHMuU2VydmVyUmVzcG9uc2UgPSBTZXJ2ZXJSZXNwb25zZTsiLCJcInVzZSBzdHJpY3RcIjtcblxudmFyIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQgPSByZXF1aXJlKFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9pbnRlcm9wUmVxdWlyZURlZmF1bHRcIik7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5leHBvcnRzLmRlZmF1bHQgPSB2b2lkIDA7XG5cbnZhciBfb2JqZWN0U3ByZWFkMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvb2JqZWN0U3ByZWFkXCIpKTtcblxudmFyIF9yZWdlbmVyYXRvciA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIkBiYWJlbC9ydW50aW1lL3JlZ2VuZXJhdG9yXCIpKTtcblxudmFyIF9hc3luY1RvR2VuZXJhdG9yMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvYXN5bmNUb0dlbmVyYXRvclwiKSk7XG5cbnZhciBfY2xhc3NDYWxsQ2hlY2syID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9jbGFzc0NhbGxDaGVja1wiKSk7XG5cbnZhciBfY3JlYXRlQ2xhc3MyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9jcmVhdGVDbGFzc1wiKSk7XG5cbnZhciBfdXRpbHMgPSByZXF1aXJlKFwiLi91dGlsc1wiKTtcblxudmFyIF9lcnJvcnMgPSByZXF1aXJlKFwiLi9lcnJvcnNcIik7XG5cbi8qKlxuICogRW5oYW5jZWQgSFRUUCBjbGllbnQgZm9yIHRoZSBLaW50byBwcm90b2NvbC5cbiAqIEBwcml2YXRlXG4gKi9cbnZhciBIVFRQID1cbi8qI19fUFVSRV9fKi9cbmZ1bmN0aW9uICgpIHtcbiAgKDAsIF9jcmVhdGVDbGFzczIuZGVmYXVsdCkoSFRUUCwgbnVsbCwgW3tcbiAgICBrZXk6IFwiREVGQVVMVF9SRVFVRVNUX0hFQURFUlNcIixcblxuICAgIC8qKlxuICAgICAqIERlZmF1bHQgSFRUUCByZXF1ZXN0IGhlYWRlcnMgYXBwbGllZCB0byBlYWNoIG91dGdvaW5nIHJlcXVlc3QuXG4gICAgICpcbiAgICAgKiBAdHlwZSB7T2JqZWN0fVxuICAgICAqL1xuICAgIGdldDogZnVuY3Rpb24gZ2V0KCkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgQWNjZXB0OiBcImFwcGxpY2F0aW9uL2pzb25cIixcbiAgICAgICAgXCJDb250ZW50LVR5cGVcIjogXCJhcHBsaWNhdGlvbi9qc29uXCJcbiAgICAgIH07XG4gICAgfVxuICAgIC8qKlxuICAgICAqIERlZmF1bHQgb3B0aW9ucy5cbiAgICAgKlxuICAgICAqIEB0eXBlIHtPYmplY3R9XG4gICAgICovXG5cbiAgfSwge1xuICAgIGtleTogXCJkZWZhdWx0T3B0aW9uc1wiLFxuICAgIGdldDogZnVuY3Rpb24gZ2V0KCkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdGltZW91dDogbnVsbCxcbiAgICAgICAgcmVxdWVzdE1vZGU6IFwiY29yc1wiXG4gICAgICB9O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDb25zdHJ1Y3Rvci5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7RXZlbnRFbWl0dGVyfSBldmVudHMgICAgICAgICAgICAgICAgICAgICAgIFRoZSBldmVudCBoYW5kbGVyLlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSAgICAgICBbb3B0aW9ucz17fX0gICAgICAgICAgICAgICAgIFRoZSBvcHRpb25zIG9iamVjdC5cbiAgICAgKiBAcGFyYW0ge051bWJlcn0gICAgICAgW29wdGlvbnMudGltZW91dD1udWxsXSAgICAgICBUaGUgcmVxdWVzdCB0aW1lb3V0IGluIG1zLCBpZiBhbnkgKGRlZmF1bHQ6IGBudWxsYCkuXG4gICAgICogQHBhcmFtIHtTdHJpbmd9ICAgICAgIFtvcHRpb25zLnJlcXVlc3RNb2RlPVwiY29yc1wiXSBUaGUgSFRUUCByZXF1ZXN0IG1vZGUgKGRlZmF1bHQ6IGBcImNvcnNcImApLlxuICAgICAqL1xuXG4gIH1dKTtcblxuICBmdW5jdGlvbiBIVFRQKGV2ZW50cykge1xuICAgIHZhciBvcHRpb25zID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMV0gOiB7fTtcbiAgICAoMCwgX2NsYXNzQ2FsbENoZWNrMi5kZWZhdWx0KSh0aGlzLCBIVFRQKTtcblxuICAgIC8vIHB1YmxpYyBwcm9wZXJ0aWVzXG5cbiAgICAvKipcbiAgICAgKiBUaGUgZXZlbnQgZW1pdHRlciBpbnN0YW5jZS5cbiAgICAgKiBAdHlwZSB7RXZlbnRFbWl0dGVyfVxuICAgICAqL1xuICAgIGlmICghZXZlbnRzKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJObyBldmVudHMgaGFuZGxlciBwcm92aWRlZFwiKTtcbiAgICB9XG5cbiAgICB0aGlzLmV2ZW50cyA9IGV2ZW50cztcbiAgICAvKipcbiAgICAgKiBUaGUgcmVxdWVzdCBtb2RlLlxuICAgICAqIEBzZWUgIGh0dHBzOi8vZmV0Y2guc3BlYy53aGF0d2cub3JnLyNyZXF1ZXN0bW9kZVxuICAgICAqIEB0eXBlIHtTdHJpbmd9XG4gICAgICovXG5cbiAgICB0aGlzLnJlcXVlc3RNb2RlID0gb3B0aW9ucy5yZXF1ZXN0TW9kZSB8fCBIVFRQLmRlZmF1bHRPcHRpb25zLnJlcXVlc3RNb2RlO1xuICAgIC8qKlxuICAgICAqIFRoZSByZXF1ZXN0IHRpbWVvdXQuXG4gICAgICogQHR5cGUge051bWJlcn1cbiAgICAgKi9cblxuICAgIHRoaXMudGltZW91dCA9IG9wdGlvbnMudGltZW91dCB8fCBIVFRQLmRlZmF1bHRPcHRpb25zLnRpbWVvdXQ7XG4gIH1cbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuXG5cbiAgKDAsIF9jcmVhdGVDbGFzczIuZGVmYXVsdCkoSFRUUCwgW3tcbiAgICBrZXk6IFwidGltZWRGZXRjaFwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiB0aW1lZEZldGNoKHVybCwgb3B0aW9ucykge1xuICAgICAgdmFyIF90aGlzID0gdGhpcztcblxuICAgICAgdmFyIGhhc1RpbWVkb3V0ID0gZmFsc2U7XG4gICAgICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgICAvLyBEZXRlY3QgaWYgYSByZXF1ZXN0IGhhcyB0aW1lZCBvdXQuXG4gICAgICAgIHZhciBfdGltZW91dElkO1xuXG4gICAgICAgIGlmIChfdGhpcy50aW1lb3V0KSB7XG4gICAgICAgICAgX3RpbWVvdXRJZCA9IHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgaGFzVGltZWRvdXQgPSB0cnVlO1xuICAgICAgICAgICAgcmVqZWN0KG5ldyBfZXJyb3JzLk5ldHdvcmtUaW1lb3V0RXJyb3IodXJsLCBvcHRpb25zKSk7XG4gICAgICAgICAgfSwgX3RoaXMudGltZW91dCk7XG4gICAgICAgIH1cblxuICAgICAgICBmdW5jdGlvbiBwcm9jZWVkV2l0aEhhbmRsZXIoZm4pIHtcbiAgICAgICAgICByZXR1cm4gZnVuY3Rpb24gKGFyZykge1xuICAgICAgICAgICAgaWYgKCFoYXNUaW1lZG91dCkge1xuICAgICAgICAgICAgICBpZiAoX3RpbWVvdXRJZCkge1xuICAgICAgICAgICAgICAgIGNsZWFyVGltZW91dChfdGltZW91dElkKTtcbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIGZuKGFyZyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIGZldGNoKHVybCwgb3B0aW9ucykudGhlbihwcm9jZWVkV2l0aEhhbmRsZXIocmVzb2x2ZSkpLmNhdGNoKHByb2NlZWRXaXRoSGFuZGxlcihyZWplY3QpKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuXG4gIH0sIHtcbiAgICBrZXk6IFwicHJvY2Vzc1Jlc3BvbnNlXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciBfcHJvY2Vzc1Jlc3BvbnNlID0gKDAsIF9hc3luY1RvR2VuZXJhdG9yMi5kZWZhdWx0KShcbiAgICAgIC8qI19fUFVSRV9fKi9cbiAgICAgIF9yZWdlbmVyYXRvci5kZWZhdWx0Lm1hcmsoZnVuY3Rpb24gX2NhbGxlZShyZXNwb25zZSkge1xuICAgICAgICB2YXIgc3RhdHVzLCBoZWFkZXJzLCB0ZXh0LCBqc29uO1xuICAgICAgICByZXR1cm4gX3JlZ2VuZXJhdG9yLmRlZmF1bHQud3JhcChmdW5jdGlvbiBfY2FsbGVlJChfY29udGV4dCkge1xuICAgICAgICAgIHdoaWxlICgxKSB7XG4gICAgICAgICAgICBzd2l0Y2ggKF9jb250ZXh0LnByZXYgPSBfY29udGV4dC5uZXh0KSB7XG4gICAgICAgICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgICAgICBzdGF0dXMgPSByZXNwb25zZS5zdGF0dXMsIGhlYWRlcnMgPSByZXNwb25zZS5oZWFkZXJzO1xuICAgICAgICAgICAgICAgIF9jb250ZXh0Lm5leHQgPSAzO1xuICAgICAgICAgICAgICAgIHJldHVybiByZXNwb25zZS50ZXh0KCk7XG5cbiAgICAgICAgICAgICAgY2FzZSAzOlxuICAgICAgICAgICAgICAgIHRleHQgPSBfY29udGV4dC5zZW50O1xuXG4gICAgICAgICAgICAgICAgaWYgKCEodGV4dC5sZW5ndGggIT09IDApKSB7XG4gICAgICAgICAgICAgICAgICBfY29udGV4dC5uZXh0ID0gMTI7XG4gICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBfY29udGV4dC5wcmV2ID0gNTtcbiAgICAgICAgICAgICAgICBqc29uID0gSlNPTi5wYXJzZSh0ZXh0KTtcbiAgICAgICAgICAgICAgICBfY29udGV4dC5uZXh0ID0gMTI7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICAgICAgY2FzZSA5OlxuICAgICAgICAgICAgICAgIF9jb250ZXh0LnByZXYgPSA5O1xuICAgICAgICAgICAgICAgIF9jb250ZXh0LnQwID0gX2NvbnRleHRbXCJjYXRjaFwiXSg1KTtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgX2Vycm9ycy5VbnBhcnNlYWJsZVJlc3BvbnNlRXJyb3IocmVzcG9uc2UsIHRleHQsIF9jb250ZXh0LnQwKTtcblxuICAgICAgICAgICAgICBjYXNlIDEyOlxuICAgICAgICAgICAgICAgIGlmICghKHN0YXR1cyA+PSA0MDApKSB7XG4gICAgICAgICAgICAgICAgICBfY29udGV4dC5uZXh0ID0gMTQ7XG4gICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgX2Vycm9ycy5TZXJ2ZXJSZXNwb25zZShyZXNwb25zZSwganNvbik7XG5cbiAgICAgICAgICAgICAgY2FzZSAxNDpcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQuYWJydXB0KFwicmV0dXJuXCIsIHtcbiAgICAgICAgICAgICAgICAgIHN0YXR1czogc3RhdHVzLFxuICAgICAgICAgICAgICAgICAganNvbjoganNvbixcbiAgICAgICAgICAgICAgICAgIGhlYWRlcnM6IGhlYWRlcnNcbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICBjYXNlIDE1OlxuICAgICAgICAgICAgICBjYXNlIFwiZW5kXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0LnN0b3AoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0sIF9jYWxsZWUsIHRoaXMsIFtbNSwgOV1dKTtcbiAgICAgIH0pKTtcblxuICAgICAgcmV0dXJuIGZ1bmN0aW9uIHByb2Nlc3NSZXNwb25zZShfeCkge1xuICAgICAgICByZXR1cm4gX3Byb2Nlc3NSZXNwb25zZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgfTtcbiAgICB9KClcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuXG4gIH0sIHtcbiAgICBrZXk6IFwicmV0cnlcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gKCkge1xuICAgICAgdmFyIF9yZXRyeSA9ICgwLCBfYXN5bmNUb0dlbmVyYXRvcjIuZGVmYXVsdCkoXG4gICAgICAvKiNfX1BVUkVfXyovXG4gICAgICBfcmVnZW5lcmF0b3IuZGVmYXVsdC5tYXJrKGZ1bmN0aW9uIF9jYWxsZWUyKHVybCwgcmV0cnlBZnRlciwgcmVxdWVzdCwgb3B0aW9ucykge1xuICAgICAgICByZXR1cm4gX3JlZ2VuZXJhdG9yLmRlZmF1bHQud3JhcChmdW5jdGlvbiBfY2FsbGVlMiQoX2NvbnRleHQyKSB7XG4gICAgICAgICAgd2hpbGUgKDEpIHtcbiAgICAgICAgICAgIHN3aXRjaCAoX2NvbnRleHQyLnByZXYgPSBfY29udGV4dDIubmV4dCkge1xuICAgICAgICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICAgICAgX2NvbnRleHQyLm5leHQgPSAyO1xuICAgICAgICAgICAgICAgIHJldHVybiAoMCwgX3V0aWxzLmRlbGF5KShyZXRyeUFmdGVyKTtcblxuICAgICAgICAgICAgICBjYXNlIDI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0Mi5hYnJ1cHQoXCJyZXR1cm5cIiwgdGhpcy5yZXF1ZXN0KHVybCwgcmVxdWVzdCwgKDAsIF9vYmplY3RTcHJlYWQyLmRlZmF1bHQpKHt9LCBvcHRpb25zLCB7XG4gICAgICAgICAgICAgICAgICByZXRyeTogb3B0aW9ucy5yZXRyeSAtIDFcbiAgICAgICAgICAgICAgICB9KSkpO1xuXG4gICAgICAgICAgICAgIGNhc2UgMzpcbiAgICAgICAgICAgICAgY2FzZSBcImVuZFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDIuc3RvcCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSwgX2NhbGxlZTIsIHRoaXMpO1xuICAgICAgfSkpO1xuXG4gICAgICByZXR1cm4gZnVuY3Rpb24gcmV0cnkoX3gyLCBfeDMsIF94NCwgX3g1KSB7XG4gICAgICAgIHJldHVybiBfcmV0cnkuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgIH07XG4gICAgfSgpXG4gICAgLyoqXG4gICAgICogUGVyZm9ybXMgYW4gSFRUUCByZXF1ZXN0IHRvIHRoZSBLaW50byBzZXJ2ZXIuXG4gICAgICpcbiAgICAgKiBSZXNvbHZlcyB3aXRoIGFuIG9iamV0IGNvbnRhaW5pbmcgdGhlIGZvbGxvd2luZyBIVFRQIHJlc3BvbnNlIHByb3BlcnRpZXM6XG4gICAgICogLSBge051bWJlcn0gIHN0YXR1c2AgIFRoZSBIVFRQIHN0YXR1cyBjb2RlLlxuICAgICAqIC0gYHtPYmplY3R9ICBqc29uYCAgICBUaGUgSlNPTiByZXNwb25zZSBib2R5LlxuICAgICAqIC0gYHtIZWFkZXJzfSBoZWFkZXJzYCBUaGUgcmVzcG9uc2UgaGVhZGVycyBvYmplY3Q7IHNlZSB0aGUgRVM2IGZldGNoKCkgc3BlYy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSAge1N0cmluZ30gdXJsICAgICAgICAgICAgICAgVGhlIFVSTC5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9IFtyZXF1ZXN0PXt9XSAgICAgIFRoZSByZXF1ZXN0IG9iamVjdCwgcGFzc2VkIHRvXG4gICAgICogICAgIGZldGNoKCkgYXMgaXRzIG9wdGlvbnMgb2JqZWN0LlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gW3JlcXVlc3QuaGVhZGVyc10gVGhlIHJlcXVlc3QgaGVhZGVycyBvYmplY3QgKGRlZmF1bHQ6IHt9KVxuICAgICAqIEBwYXJhbSAge09iamVjdH0gW29wdGlvbnM9e31dICAgICAgT3B0aW9ucyBmb3IgbWFraW5nIHRoZVxuICAgICAqICAgICByZXF1ZXN0XG4gICAgICogQHBhcmFtICB7TnVtYmVyfSBbb3B0aW9ucy5yZXRyeV0gICBOdW1iZXIgb2YgcmV0cmllcyAoZGVmYXVsdDogMClcbiAgICAgKiBAcmV0dXJuIHtQcm9taXNlfVxuICAgICAqL1xuXG4gIH0sIHtcbiAgICBrZXk6IFwicmVxdWVzdFwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgX3JlcXVlc3QyID0gKDAsIF9hc3luY1RvR2VuZXJhdG9yMi5kZWZhdWx0KShcbiAgICAgIC8qI19fUFVSRV9fKi9cbiAgICAgIF9yZWdlbmVyYXRvci5kZWZhdWx0Lm1hcmsoZnVuY3Rpb24gX2NhbGxlZTModXJsKSB7XG4gICAgICAgIHZhciBfcmVxdWVzdCxcbiAgICAgICAgICAgIG9wdGlvbnMsXG4gICAgICAgICAgICByZXNwb25zZSxcbiAgICAgICAgICAgIHN0YXR1cyxcbiAgICAgICAgICAgIGhlYWRlcnMsXG4gICAgICAgICAgICByZXRyeUFmdGVyLFxuICAgICAgICAgICAgX2FyZ3MzID0gYXJndW1lbnRzO1xuXG4gICAgICAgIHJldHVybiBfcmVnZW5lcmF0b3IuZGVmYXVsdC53cmFwKGZ1bmN0aW9uIF9jYWxsZWUzJChfY29udGV4dDMpIHtcbiAgICAgICAgICB3aGlsZSAoMSkge1xuICAgICAgICAgICAgc3dpdGNoIChfY29udGV4dDMucHJldiA9IF9jb250ZXh0My5uZXh0KSB7XG4gICAgICAgICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgICAgICBfcmVxdWVzdCA9IF9hcmdzMy5sZW5ndGggPiAxICYmIF9hcmdzM1sxXSAhPT0gdW5kZWZpbmVkID8gX2FyZ3MzWzFdIDoge1xuICAgICAgICAgICAgICAgICAgaGVhZGVyczoge31cbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIG9wdGlvbnMgPSBfYXJnczMubGVuZ3RoID4gMiAmJiBfYXJnczNbMl0gIT09IHVuZGVmaW5lZCA/IF9hcmdzM1syXSA6IHtcbiAgICAgICAgICAgICAgICAgIHJldHJ5OiAwXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAvLyBFbnN1cmUgZGVmYXVsdCByZXF1ZXN0IGhlYWRlcnMgYXJlIGFsd2F5cyBzZXRcbiAgICAgICAgICAgICAgICBfcmVxdWVzdC5oZWFkZXJzID0gKDAsIF9vYmplY3RTcHJlYWQyLmRlZmF1bHQpKHt9LCBIVFRQLkRFRkFVTFRfUkVRVUVTVF9IRUFERVJTLCBfcmVxdWVzdC5oZWFkZXJzKTsgLy8gSWYgYSBtdWx0aXBhcnQgYm9keSBpcyBwcm92aWRlZCwgcmVtb3ZlIGFueSBjdXN0b20gQ29udGVudC1UeXBlIGhlYWRlciBhc1xuICAgICAgICAgICAgICAgIC8vIHRoZSBmZXRjaCgpIGltcGxlbWVudGF0aW9uIHdpbGwgYWRkIHRoZSBjb3JyZWN0IG9uZSBmb3IgdXMuXG5cbiAgICAgICAgICAgICAgICBpZiAoX3JlcXVlc3QuYm9keSAmJiB0eXBlb2YgX3JlcXVlc3QuYm9keS5hcHBlbmQgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgICAgICAgZGVsZXRlIF9yZXF1ZXN0LmhlYWRlcnNbXCJDb250ZW50LVR5cGVcIl07XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgX3JlcXVlc3QubW9kZSA9IHRoaXMucmVxdWVzdE1vZGU7XG4gICAgICAgICAgICAgICAgX2NvbnRleHQzLm5leHQgPSA3O1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnRpbWVkRmV0Y2godXJsLCBfcmVxdWVzdCk7XG5cbiAgICAgICAgICAgICAgY2FzZSA3OlxuICAgICAgICAgICAgICAgIHJlc3BvbnNlID0gX2NvbnRleHQzLnNlbnQ7XG4gICAgICAgICAgICAgICAgc3RhdHVzID0gcmVzcG9uc2Uuc3RhdHVzLCBoZWFkZXJzID0gcmVzcG9uc2UuaGVhZGVycztcblxuICAgICAgICAgICAgICAgIHRoaXMuX2NoZWNrRm9yRGVwcmVjYXRpb25IZWFkZXIoaGVhZGVycyk7XG5cbiAgICAgICAgICAgICAgICB0aGlzLl9jaGVja0ZvckJhY2tvZmZIZWFkZXIoc3RhdHVzLCBoZWFkZXJzKTsgLy8gQ2hlY2sgaWYgdGhlIHNlcnZlciBzdW1tb25zIHRoZSBjbGllbnQgdG8gcmV0cnkgYWZ0ZXIgYSB3aGlsZS5cblxuXG4gICAgICAgICAgICAgICAgcmV0cnlBZnRlciA9IHRoaXMuX2NoZWNrRm9yUmV0cnlBZnRlckhlYWRlcihzdGF0dXMsIGhlYWRlcnMpOyAvLyBJZiBudW1iZXIgb2YgYWxsb3dlZCBvZiByZXRyaWVzIGlzIG5vdCBleGhhdXN0ZWQsIHJldHJ5IHRoZSBzYW1lIHJlcXVlc3QuXG5cbiAgICAgICAgICAgICAgICBpZiAoIShyZXRyeUFmdGVyICYmIG9wdGlvbnMucmV0cnkgPiAwKSkge1xuICAgICAgICAgICAgICAgICAgX2NvbnRleHQzLm5leHQgPSAxNjtcbiAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDMuYWJydXB0KFwicmV0dXJuXCIsIHRoaXMucmV0cnkodXJsLCByZXRyeUFmdGVyLCBfcmVxdWVzdCwgb3B0aW9ucykpO1xuXG4gICAgICAgICAgICAgIGNhc2UgMTY6XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0My5hYnJ1cHQoXCJyZXR1cm5cIiwgdGhpcy5wcm9jZXNzUmVzcG9uc2UocmVzcG9uc2UpKTtcblxuICAgICAgICAgICAgICBjYXNlIDE3OlxuICAgICAgICAgICAgICBjYXNlIFwiZW5kXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0My5zdG9wKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9LCBfY2FsbGVlMywgdGhpcyk7XG4gICAgICB9KSk7XG5cbiAgICAgIHJldHVybiBmdW5jdGlvbiByZXF1ZXN0KF94Nikge1xuICAgICAgICByZXR1cm4gX3JlcXVlc3QyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICB9O1xuICAgIH0oKVxuICB9LCB7XG4gICAga2V5OiBcIl9jaGVja0ZvckRlcHJlY2F0aW9uSGVhZGVyXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIF9jaGVja0ZvckRlcHJlY2F0aW9uSGVhZGVyKGhlYWRlcnMpIHtcbiAgICAgIHZhciBhbGVydEhlYWRlciA9IGhlYWRlcnMuZ2V0KFwiQWxlcnRcIik7XG5cbiAgICAgIGlmICghYWxlcnRIZWFkZXIpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICB2YXIgYWxlcnQ7XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIGFsZXJ0ID0gSlNPTi5wYXJzZShhbGVydEhlYWRlcik7XG4gICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgY29uc29sZS53YXJuKFwiVW5hYmxlIHRvIHBhcnNlIEFsZXJ0IGhlYWRlciBtZXNzYWdlXCIsIGFsZXJ0SGVhZGVyKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBjb25zb2xlLndhcm4oYWxlcnQubWVzc2FnZSwgYWxlcnQudXJsKTtcbiAgICAgIHRoaXMuZXZlbnRzLmVtaXQoXCJkZXByZWNhdGVkXCIsIGFsZXJ0KTtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwiX2NoZWNrRm9yQmFja29mZkhlYWRlclwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBfY2hlY2tGb3JCYWNrb2ZmSGVhZGVyKHN0YXR1cywgaGVhZGVycykge1xuICAgICAgdmFyIGJhY2tvZmZNcztcbiAgICAgIHZhciBiYWNrb2ZmU2Vjb25kcyA9IHBhcnNlSW50KGhlYWRlcnMuZ2V0KFwiQmFja29mZlwiKSwgMTApO1xuXG4gICAgICBpZiAoYmFja29mZlNlY29uZHMgPiAwKSB7XG4gICAgICAgIGJhY2tvZmZNcyA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpICsgYmFja29mZlNlY29uZHMgKiAxMDAwO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgYmFja29mZk1zID0gMDtcbiAgICAgIH1cblxuICAgICAgdGhpcy5ldmVudHMuZW1pdChcImJhY2tvZmZcIiwgYmFja29mZk1zKTtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwiX2NoZWNrRm9yUmV0cnlBZnRlckhlYWRlclwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBfY2hlY2tGb3JSZXRyeUFmdGVySGVhZGVyKHN0YXR1cywgaGVhZGVycykge1xuICAgICAgdmFyIHJldHJ5QWZ0ZXIgPSBoZWFkZXJzLmdldChcIlJldHJ5LUFmdGVyXCIpO1xuXG4gICAgICBpZiAoIXJldHJ5QWZ0ZXIpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICB2YXIgZGVsYXkgPSBwYXJzZUludChyZXRyeUFmdGVyLCAxMCkgKiAxMDAwO1xuICAgICAgcmV0cnlBZnRlciA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpICsgZGVsYXk7XG4gICAgICB0aGlzLmV2ZW50cy5lbWl0KFwicmV0cnktYWZ0ZXJcIiwgcmV0cnlBZnRlcik7XG4gICAgICByZXR1cm4gZGVsYXk7XG4gICAgfVxuICB9XSk7XG4gIHJldHVybiBIVFRQO1xufSgpO1xuXG5leHBvcnRzLmRlZmF1bHQgPSBIVFRQOyIsIlwidXNlIHN0cmljdFwiO1xuXG52YXIgX2ludGVyb3BSZXF1aXJlRGVmYXVsdCA9IHJlcXVpcmUoXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2ludGVyb3BSZXF1aXJlRGVmYXVsdFwiKTtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcbmV4cG9ydHMuZGVmYXVsdCA9IHZvaWQgMDtcblxudmFyIF90eXBlb2YyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy90eXBlb2ZcIikpO1xuXG52YXIgX2NsYXNzQ2FsbENoZWNrMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvY2xhc3NDYWxsQ2hlY2tcIikpO1xuXG52YXIgX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm4yID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuXCIpKTtcblxudmFyIF9nZXRQcm90b3R5cGVPZjIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KHJlcXVpcmUoXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2dldFByb3RvdHlwZU9mXCIpKTtcblxudmFyIF9pbmhlcml0czIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KHJlcXVpcmUoXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2luaGVyaXRzXCIpKTtcblxudmFyIF9ldmVudHMgPSByZXF1aXJlKFwiZXZlbnRzXCIpO1xuXG52YXIgX2Jhc2UgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KHJlcXVpcmUoXCIuL2Jhc2VcIikpO1xuXG52YXIgS2ludG9DbGllbnQgPVxuLyojX19QVVJFX18qL1xuZnVuY3Rpb24gKF9LaW50b0NsaWVudEJhc2UpIHtcbiAgKDAsIF9pbmhlcml0czIuZGVmYXVsdCkoS2ludG9DbGllbnQsIF9LaW50b0NsaWVudEJhc2UpO1xuXG4gIGZ1bmN0aW9uIEtpbnRvQ2xpZW50KHJlbW90ZSkge1xuICAgIHZhciBvcHRpb25zID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMV0gOiB7fTtcbiAgICAoMCwgX2NsYXNzQ2FsbENoZWNrMi5kZWZhdWx0KSh0aGlzLCBLaW50b0NsaWVudCk7XG4gICAgdmFyIGV2ZW50cyA9IG9wdGlvbnMuZXZlbnRzIHx8IG5ldyBfZXZlbnRzLkV2ZW50RW1pdHRlcigpO1xuICAgIHJldHVybiAoMCwgX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm4yLmRlZmF1bHQpKHRoaXMsICgwLCBfZ2V0UHJvdG90eXBlT2YyLmRlZmF1bHQpKEtpbnRvQ2xpZW50KS5jYWxsKHRoaXMsIHJlbW90ZSwgT2JqZWN0LmFzc2lnbih7XG4gICAgICBldmVudHM6IGV2ZW50c1xuICAgIH0sIG9wdGlvbnMpKSk7XG4gIH1cblxuICByZXR1cm4gS2ludG9DbGllbnQ7XG59KF9iYXNlLmRlZmF1bHQpOyAvLyBUaGlzIGlzIGEgaGFjayB0byBhdm9pZCBCcm93c2VyaWZ5IHRvIGV4cG9zZSB0aGUgYWJvdmUgY2xhc3Ncbi8vIGF0IGBuZXcgS2ludG9DbGllbnQoKWAgaW5zdGVhZCBvZiBgbmV3IEtpbnRvQ2xpZW50LmRlZmF1bHQoKWAuXG4vLyBTZWUgaHR0cHM6Ly9naXRodWIuY29tL0tpbnRvL2tpbnRvLWh0dHAuanMvaXNzdWVzLzc3XG5cblxuZXhwb3J0cy5kZWZhdWx0ID0gS2ludG9DbGllbnQ7XG5cbmlmICgodHlwZW9mIG1vZHVsZSA9PT0gXCJ1bmRlZmluZWRcIiA/IFwidW5kZWZpbmVkXCIgOiAoMCwgX3R5cGVvZjIuZGVmYXVsdCkobW9kdWxlKSkgPT09IFwib2JqZWN0XCIpIHtcbiAgbW9kdWxlLmV4cG9ydHMgPSBLaW50b0NsaWVudDtcbn0iLCJcInVzZSBzdHJpY3RcIjtcblxudmFyIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQgPSByZXF1aXJlKFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9pbnRlcm9wUmVxdWlyZURlZmF1bHRcIik7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5leHBvcnRzLmNyZWF0ZVJlcXVlc3QgPSBjcmVhdGVSZXF1ZXN0O1xuZXhwb3J0cy51cGRhdGVSZXF1ZXN0ID0gdXBkYXRlUmVxdWVzdDtcbmV4cG9ydHMuanNvblBhdGNoUGVybWlzc2lvbnNSZXF1ZXN0ID0ganNvblBhdGNoUGVybWlzc2lvbnNSZXF1ZXN0O1xuZXhwb3J0cy5kZWxldGVSZXF1ZXN0ID0gZGVsZXRlUmVxdWVzdDtcbmV4cG9ydHMuYWRkQXR0YWNobWVudFJlcXVlc3QgPSBhZGRBdHRhY2htZW50UmVxdWVzdDtcblxudmFyIF9zbGljZWRUb0FycmF5MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvc2xpY2VkVG9BcnJheVwiKSk7XG5cbnZhciBfb2JqZWN0U3ByZWFkMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvb2JqZWN0U3ByZWFkXCIpKTtcblxudmFyIF91dGlscyA9IHJlcXVpcmUoXCIuL3V0aWxzXCIpO1xuXG52YXIgcmVxdWVzdERlZmF1bHRzID0ge1xuICBzYWZlOiBmYWxzZSxcbiAgLy8gY2hlY2sgaWYgd2Ugc2hvdWxkIHNldCBkZWZhdWx0IGNvbnRlbnQgdHlwZSBoZXJlXG4gIGhlYWRlcnM6IHt9LFxuICBwZXJtaXNzaW9uczogdW5kZWZpbmVkLFxuICBkYXRhOiB1bmRlZmluZWQsXG4gIHBhdGNoOiBmYWxzZVxufTtcbi8qKlxuICogQHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBzYWZlSGVhZGVyKHNhZmUsIGxhc3RfbW9kaWZpZWQpIHtcbiAgaWYgKCFzYWZlKSB7XG4gICAgcmV0dXJuIHt9O1xuICB9XG5cbiAgaWYgKGxhc3RfbW9kaWZpZWQpIHtcbiAgICByZXR1cm4ge1xuICAgICAgXCJJZi1NYXRjaFwiOiBcIlxcXCJcIi5jb25jYXQobGFzdF9tb2RpZmllZCwgXCJcXFwiXCIpXG4gICAgfTtcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgXCJJZi1Ob25lLU1hdGNoXCI6IFwiKlwiXG4gIH07XG59XG4vKipcbiAqIEBwcml2YXRlXG4gKi9cblxuXG5mdW5jdGlvbiBjcmVhdGVSZXF1ZXN0KHBhdGgsIF9yZWYpIHtcbiAgdmFyIGRhdGEgPSBfcmVmLmRhdGEsXG4gICAgICBwZXJtaXNzaW9ucyA9IF9yZWYucGVybWlzc2lvbnM7XG4gIHZhciBvcHRpb25zID0gYXJndW1lbnRzLmxlbmd0aCA+IDIgJiYgYXJndW1lbnRzWzJdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMl0gOiB7fTtcblxuICB2YXIgX3JlcXVlc3REZWZhdWx0cyRvcHRpID0gKDAsIF9vYmplY3RTcHJlYWQyLmRlZmF1bHQpKHt9LCByZXF1ZXN0RGVmYXVsdHMsIG9wdGlvbnMpLFxuICAgICAgaGVhZGVycyA9IF9yZXF1ZXN0RGVmYXVsdHMkb3B0aS5oZWFkZXJzLFxuICAgICAgc2FmZSA9IF9yZXF1ZXN0RGVmYXVsdHMkb3B0aS5zYWZlO1xuXG4gIHJldHVybiB7XG4gICAgbWV0aG9kOiBkYXRhICYmIGRhdGEuaWQgPyBcIlBVVFwiIDogXCJQT1NUXCIsXG4gICAgcGF0aDogcGF0aCxcbiAgICBoZWFkZXJzOiAoMCwgX29iamVjdFNwcmVhZDIuZGVmYXVsdCkoe30sIGhlYWRlcnMsIHNhZmVIZWFkZXIoc2FmZSkpLFxuICAgIGJvZHk6IHtcbiAgICAgIGRhdGE6IGRhdGEsXG4gICAgICBwZXJtaXNzaW9uczogcGVybWlzc2lvbnNcbiAgICB9XG4gIH07XG59XG4vKipcbiAqIEBwcml2YXRlXG4gKi9cblxuXG5mdW5jdGlvbiB1cGRhdGVSZXF1ZXN0KHBhdGgsIF9yZWYyKSB7XG4gIHZhciBkYXRhID0gX3JlZjIuZGF0YSxcbiAgICAgIHBlcm1pc3Npb25zID0gX3JlZjIucGVybWlzc2lvbnM7XG4gIHZhciBvcHRpb25zID0gYXJndW1lbnRzLmxlbmd0aCA+IDIgJiYgYXJndW1lbnRzWzJdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMl0gOiB7fTtcblxuICB2YXIgX3JlcXVlc3REZWZhdWx0cyRvcHRpMiA9ICgwLCBfb2JqZWN0U3ByZWFkMi5kZWZhdWx0KSh7fSwgcmVxdWVzdERlZmF1bHRzLCBvcHRpb25zKSxcbiAgICAgIGhlYWRlcnMgPSBfcmVxdWVzdERlZmF1bHRzJG9wdGkyLmhlYWRlcnMsXG4gICAgICBzYWZlID0gX3JlcXVlc3REZWZhdWx0cyRvcHRpMi5zYWZlLFxuICAgICAgcGF0Y2ggPSBfcmVxdWVzdERlZmF1bHRzJG9wdGkyLnBhdGNoO1xuXG4gIHZhciBfZGF0YSRvcHRpb25zID0gKDAsIF9vYmplY3RTcHJlYWQyLmRlZmF1bHQpKHt9LCBkYXRhLCBvcHRpb25zKSxcbiAgICAgIGxhc3RfbW9kaWZpZWQgPSBfZGF0YSRvcHRpb25zLmxhc3RfbW9kaWZpZWQ7XG5cbiAgaWYgKE9iamVjdC5rZXlzKCgwLCBfdXRpbHMub21pdCkoZGF0YSwgXCJpZFwiLCBcImxhc3RfbW9kaWZpZWRcIikpLmxlbmd0aCA9PT0gMCkge1xuICAgIGRhdGEgPSB1bmRlZmluZWQ7XG4gIH1cblxuICByZXR1cm4ge1xuICAgIG1ldGhvZDogcGF0Y2ggPyBcIlBBVENIXCIgOiBcIlBVVFwiLFxuICAgIHBhdGg6IHBhdGgsXG4gICAgaGVhZGVyczogKDAsIF9vYmplY3RTcHJlYWQyLmRlZmF1bHQpKHt9LCBoZWFkZXJzLCBzYWZlSGVhZGVyKHNhZmUsIGxhc3RfbW9kaWZpZWQpKSxcbiAgICBib2R5OiB7XG4gICAgICBkYXRhOiBkYXRhLFxuICAgICAgcGVybWlzc2lvbnM6IHBlcm1pc3Npb25zXG4gICAgfVxuICB9O1xufVxuLyoqXG4gKiBAcHJpdmF0ZVxuICovXG5cblxuZnVuY3Rpb24ganNvblBhdGNoUGVybWlzc2lvbnNSZXF1ZXN0KHBhdGgsIHBlcm1pc3Npb25zLCBvcFR5cGUpIHtcbiAgdmFyIG9wdGlvbnMgPSBhcmd1bWVudHMubGVuZ3RoID4gMyAmJiBhcmd1bWVudHNbM10gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1szXSA6IHt9O1xuXG4gIHZhciBfcmVxdWVzdERlZmF1bHRzJG9wdGkzID0gKDAsIF9vYmplY3RTcHJlYWQyLmRlZmF1bHQpKHt9LCByZXF1ZXN0RGVmYXVsdHMsIG9wdGlvbnMpLFxuICAgICAgaGVhZGVycyA9IF9yZXF1ZXN0RGVmYXVsdHMkb3B0aTMuaGVhZGVycyxcbiAgICAgIHNhZmUgPSBfcmVxdWVzdERlZmF1bHRzJG9wdGkzLnNhZmUsXG4gICAgICBsYXN0X21vZGlmaWVkID0gX3JlcXVlc3REZWZhdWx0cyRvcHRpMy5sYXN0X21vZGlmaWVkO1xuXG4gIHZhciBvcHMgPSBbXTtcblxuICB2YXIgX2FyciA9IE9iamVjdC5lbnRyaWVzKHBlcm1pc3Npb25zKTtcblxuICBmb3IgKHZhciBfaSA9IDA7IF9pIDwgX2Fyci5sZW5ndGg7IF9pKyspIHtcbiAgICB2YXIgX2FyciRfaSA9ICgwLCBfc2xpY2VkVG9BcnJheTIuZGVmYXVsdCkoX2FycltfaV0sIDIpLFxuICAgICAgICB0eXBlID0gX2FyciRfaVswXSxcbiAgICAgICAgcHJpbmNpcGFscyA9IF9hcnIkX2lbMV07XG5cbiAgICB2YXIgX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbiA9IHRydWU7XG4gICAgdmFyIF9kaWRJdGVyYXRvckVycm9yID0gZmFsc2U7XG4gICAgdmFyIF9pdGVyYXRvckVycm9yID0gdW5kZWZpbmVkO1xuXG4gICAgdHJ5IHtcbiAgICAgIGZvciAodmFyIF9pdGVyYXRvciA9IHByaW5jaXBhbHNbU3ltYm9sLml0ZXJhdG9yXSgpLCBfc3RlcDsgIShfaXRlcmF0b3JOb3JtYWxDb21wbGV0aW9uID0gKF9zdGVwID0gX2l0ZXJhdG9yLm5leHQoKSkuZG9uZSk7IF9pdGVyYXRvck5vcm1hbENvbXBsZXRpb24gPSB0cnVlKSB7XG4gICAgICAgIHZhciBwcmluY2lwYWwgPSBfc3RlcC52YWx1ZTtcbiAgICAgICAgb3BzLnB1c2goe1xuICAgICAgICAgIG9wOiBvcFR5cGUsXG4gICAgICAgICAgcGF0aDogXCIvcGVybWlzc2lvbnMvXCIuY29uY2F0KHR5cGUsIFwiL1wiKS5jb25jYXQocHJpbmNpcGFsKVxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIF9kaWRJdGVyYXRvckVycm9yID0gdHJ1ZTtcbiAgICAgIF9pdGVyYXRvckVycm9yID0gZXJyO1xuICAgIH0gZmluYWxseSB7XG4gICAgICB0cnkge1xuICAgICAgICBpZiAoIV9pdGVyYXRvck5vcm1hbENvbXBsZXRpb24gJiYgX2l0ZXJhdG9yLnJldHVybiAhPSBudWxsKSB7XG4gICAgICAgICAgX2l0ZXJhdG9yLnJldHVybigpO1xuICAgICAgICB9XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICBpZiAoX2RpZEl0ZXJhdG9yRXJyb3IpIHtcbiAgICAgICAgICB0aHJvdyBfaXRlcmF0b3JFcnJvcjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiB7XG4gICAgbWV0aG9kOiBcIlBBVENIXCIsXG4gICAgcGF0aDogcGF0aCxcbiAgICBoZWFkZXJzOiAoMCwgX29iamVjdFNwcmVhZDIuZGVmYXVsdCkoe30sIGhlYWRlcnMsIHNhZmVIZWFkZXIoc2FmZSwgbGFzdF9tb2RpZmllZCksIHtcbiAgICAgIFwiQ29udGVudC1UeXBlXCI6IFwiYXBwbGljYXRpb24vanNvbi1wYXRjaCtqc29uXCJcbiAgICB9KSxcbiAgICBib2R5OiBvcHNcbiAgfTtcbn1cbi8qKlxuICogQHByaXZhdGVcbiAqL1xuXG5cbmZ1bmN0aW9uIGRlbGV0ZVJlcXVlc3QocGF0aCkge1xuICB2YXIgb3B0aW9ucyA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDoge307XG5cbiAgdmFyIF9yZXF1ZXN0RGVmYXVsdHMkb3B0aTQgPSAoMCwgX29iamVjdFNwcmVhZDIuZGVmYXVsdCkoe30sIHJlcXVlc3REZWZhdWx0cywgb3B0aW9ucyksXG4gICAgICBoZWFkZXJzID0gX3JlcXVlc3REZWZhdWx0cyRvcHRpNC5oZWFkZXJzLFxuICAgICAgc2FmZSA9IF9yZXF1ZXN0RGVmYXVsdHMkb3B0aTQuc2FmZSxcbiAgICAgIGxhc3RfbW9kaWZpZWQgPSBfcmVxdWVzdERlZmF1bHRzJG9wdGk0Lmxhc3RfbW9kaWZpZWQ7XG5cbiAgaWYgKHNhZmUgJiYgIWxhc3RfbW9kaWZpZWQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJTYWZlIGNvbmN1cnJlbmN5IGNoZWNrIHJlcXVpcmVzIGEgbGFzdF9tb2RpZmllZCB2YWx1ZS5cIik7XG4gIH1cblxuICByZXR1cm4ge1xuICAgIG1ldGhvZDogXCJERUxFVEVcIixcbiAgICBwYXRoOiBwYXRoLFxuICAgIGhlYWRlcnM6ICgwLCBfb2JqZWN0U3ByZWFkMi5kZWZhdWx0KSh7fSwgaGVhZGVycywgc2FmZUhlYWRlcihzYWZlLCBsYXN0X21vZGlmaWVkKSlcbiAgfTtcbn1cbi8qKlxuICogQHByaXZhdGVcbiAqL1xuXG5cbmZ1bmN0aW9uIGFkZEF0dGFjaG1lbnRSZXF1ZXN0KHBhdGgsIGRhdGFVUkkpIHtcbiAgdmFyIF9yZWYzID0gYXJndW1lbnRzLmxlbmd0aCA+IDIgJiYgYXJndW1lbnRzWzJdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMl0gOiB7fSxcbiAgICAgIGRhdGEgPSBfcmVmMy5kYXRhLFxuICAgICAgcGVybWlzc2lvbnMgPSBfcmVmMy5wZXJtaXNzaW9ucztcblxuICB2YXIgb3B0aW9ucyA9IGFyZ3VtZW50cy5sZW5ndGggPiAzICYmIGFyZ3VtZW50c1szXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzNdIDoge307XG5cbiAgdmFyIF9yZXF1ZXN0RGVmYXVsdHMkb3B0aTUgPSAoMCwgX29iamVjdFNwcmVhZDIuZGVmYXVsdCkoe30sIHJlcXVlc3REZWZhdWx0cywgb3B0aW9ucyksXG4gICAgICBoZWFkZXJzID0gX3JlcXVlc3REZWZhdWx0cyRvcHRpNS5oZWFkZXJzLFxuICAgICAgc2FmZSA9IF9yZXF1ZXN0RGVmYXVsdHMkb3B0aTUuc2FmZSxcbiAgICAgIGd6aXBwZWQgPSBfcmVxdWVzdERlZmF1bHRzJG9wdGk1Lmd6aXBwZWQ7XG5cbiAgdmFyIF9kYXRhJG9wdGlvbnMyID0gKDAsIF9vYmplY3RTcHJlYWQyLmRlZmF1bHQpKHt9LCBkYXRhLCBvcHRpb25zKSxcbiAgICAgIGxhc3RfbW9kaWZpZWQgPSBfZGF0YSRvcHRpb25zMi5sYXN0X21vZGlmaWVkO1xuXG4gIHZhciBib2R5ID0ge1xuICAgIGRhdGE6IGRhdGEsXG4gICAgcGVybWlzc2lvbnM6IHBlcm1pc3Npb25zXG4gIH07XG4gIHZhciBmb3JtRGF0YSA9ICgwLCBfdXRpbHMuY3JlYXRlRm9ybURhdGEpKGRhdGFVUkksIGJvZHksIG9wdGlvbnMpO1xuICB2YXIgY3VzdG9tUGF0aCA9IGd6aXBwZWQgIT0gbnVsbCA/IGN1c3RvbVBhdGggPSBwYXRoICsgXCI/Z3ppcHBlZD1cIiArIChnemlwcGVkID8gXCJ0cnVlXCIgOiBcImZhbHNlXCIpIDogcGF0aDtcbiAgcmV0dXJuIHtcbiAgICBtZXRob2Q6IFwiUE9TVFwiLFxuICAgIHBhdGg6IGN1c3RvbVBhdGgsXG4gICAgaGVhZGVyczogKDAsIF9vYmplY3RTcHJlYWQyLmRlZmF1bHQpKHt9LCBoZWFkZXJzLCBzYWZlSGVhZGVyKHNhZmUsIGxhc3RfbW9kaWZpZWQpKSxcbiAgICBib2R5OiBmb3JtRGF0YVxuICB9O1xufSIsIlwidXNlIHN0cmljdFwiO1xuXG52YXIgX2ludGVyb3BSZXF1aXJlRGVmYXVsdCA9IHJlcXVpcmUoXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2ludGVyb3BSZXF1aXJlRGVmYXVsdFwiKTtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcbmV4cG9ydHMucGFydGl0aW9uID0gcGFydGl0aW9uO1xuZXhwb3J0cy5kZWxheSA9IGRlbGF5O1xuZXhwb3J0cy5wTWFwID0gcE1hcDtcbmV4cG9ydHMub21pdCA9IG9taXQ7XG5leHBvcnRzLnRvRGF0YUJvZHkgPSB0b0RhdGFCb2R5O1xuZXhwb3J0cy5xc2lmeSA9IHFzaWZ5O1xuZXhwb3J0cy5jaGVja1ZlcnNpb24gPSBjaGVja1ZlcnNpb247XG5leHBvcnRzLnN1cHBvcnQgPSBzdXBwb3J0O1xuZXhwb3J0cy5jYXBhYmxlID0gY2FwYWJsZTtcbmV4cG9ydHMubm9iYXRjaCA9IG5vYmF0Y2g7XG5leHBvcnRzLmlzT2JqZWN0ID0gaXNPYmplY3Q7XG5leHBvcnRzLnBhcnNlRGF0YVVSTCA9IHBhcnNlRGF0YVVSTDtcbmV4cG9ydHMuZXh0cmFjdEZpbGVJbmZvID0gZXh0cmFjdEZpbGVJbmZvO1xuZXhwb3J0cy5jcmVhdGVGb3JtRGF0YSA9IGNyZWF0ZUZvcm1EYXRhO1xuZXhwb3J0cy5jbGVhblVuZGVmaW5lZFByb3BlcnRpZXMgPSBjbGVhblVuZGVmaW5lZFByb3BlcnRpZXM7XG5cbnZhciBfcmVnZW5lcmF0b3IgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KHJlcXVpcmUoXCJAYmFiZWwvcnVudGltZS9yZWdlbmVyYXRvclwiKSk7XG5cbnZhciBfZGVmaW5lUHJvcGVydHkyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9kZWZpbmVQcm9wZXJ0eVwiKSk7XG5cbnZhciBfb2JqZWN0U3ByZWFkMyA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvb2JqZWN0U3ByZWFkXCIpKTtcblxudmFyIF90b0FycmF5MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvdG9BcnJheVwiKSk7XG5cbnZhciBfdHlwZW9mMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvdHlwZW9mXCIpKTtcblxudmFyIF9zbGljZWRUb0FycmF5MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvc2xpY2VkVG9BcnJheVwiKSk7XG5cbnZhciBfYXN5bmNUb0dlbmVyYXRvcjIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KHJlcXVpcmUoXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2FzeW5jVG9HZW5lcmF0b3JcIikpO1xuXG4vKipcbiAqIENodW5rcyBhbiBhcnJheSBpbnRvIG4gcGllY2VzLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0gIHtBcnJheX0gIGFycmF5XG4gKiBAcGFyYW0gIHtOdW1iZXJ9IG5cbiAqIEByZXR1cm4ge0FycmF5fVxuICovXG5mdW5jdGlvbiBwYXJ0aXRpb24oYXJyYXksIG4pIHtcbiAgaWYgKG4gPD0gMCkge1xuICAgIHJldHVybiBhcnJheTtcbiAgfVxuXG4gIHJldHVybiBhcnJheS5yZWR1Y2UoZnVuY3Rpb24gKGFjYywgeCwgaSkge1xuICAgIGlmIChpID09PSAwIHx8IGkgJSBuID09PSAwKSB7XG4gICAgICBhY2MucHVzaChbeF0pO1xuICAgIH0gZWxzZSB7XG4gICAgICBhY2NbYWNjLmxlbmd0aCAtIDFdLnB1c2goeCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGFjYztcbiAgfSwgW10pO1xufVxuLyoqXG4gKiBSZXR1cm5zIGEgUHJvbWlzZSBhbHdheXMgcmVzb2x2aW5nIGFmdGVyIHRoZSBzcGVjaWZpZWQgYW1vdW50IGluIG1pbGxpc2Vjb25kcy5cbiAqXG4gKiBAcmV0dXJuIFByb21pc2U8dm9pZD5cbiAqL1xuXG5cbmZ1bmN0aW9uIGRlbGF5KG1zKSB7XG4gIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSkge1xuICAgIHJldHVybiBzZXRUaW1lb3V0KHJlc29sdmUsIG1zKTtcbiAgfSk7XG59XG4vKipcbiAqIE1hcHMgYSBsaXN0IHRvIHByb21pc2VzIHVzaW5nIHRoZSBwcm92aWRlZCBtYXBwaW5nIGZ1bmN0aW9uLCBleGVjdXRlcyB0aGVtXG4gKiBzZXF1ZW50aWFsbHkgdGhlbiByZXR1cm5zIGEgUHJvbWlzZSByZXNvbHZpbmcgd2l0aCBvcmRlcmVkIHJlc3VsdHMgb2J0YWluZWQuXG4gKiBUaGluayBvZiB0aGlzIGFzIGEgc2VxdWVudGlhbCBQcm9taXNlLmFsbC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtICB7QXJyYXl9ICAgIGxpc3QgVGhlIGxpc3QgdG8gbWFwLlxuICogQHBhcmFtICB7RnVuY3Rpb259IGZuICAgVGhlIG1hcHBpbmcgZnVuY3Rpb24uXG4gKiBAcmV0dXJuIHtQcm9taXNlfVxuICovXG5cblxuZnVuY3Rpb24gcE1hcChfeCwgX3gyKSB7XG4gIHJldHVybiBfcE1hcC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xufVxuLyoqXG4gKiBUYWtlcyBhbiBvYmplY3QgYW5kIHJldHVybnMgYSBjb3B5IG9mIGl0IHdpdGggdGhlIHByb3ZpZGVkIGtleXMgb21pdHRlZC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtICB7T2JqZWN0fSAgICBvYmogIFRoZSBzb3VyY2Ugb2JqZWN0LlxuICogQHBhcmFtICB7Li4uU3RyaW5nfSBrZXlzIFRoZSBrZXlzIHRvIG9taXQuXG4gKiBAcmV0dXJuIHtPYmplY3R9XG4gKi9cblxuXG5mdW5jdGlvbiBfcE1hcCgpIHtcbiAgX3BNYXAgPSAoMCwgX2FzeW5jVG9HZW5lcmF0b3IyLmRlZmF1bHQpKFxuICAvKiNfX1BVUkVfXyovXG4gIF9yZWdlbmVyYXRvci5kZWZhdWx0Lm1hcmsoZnVuY3Rpb24gX2NhbGxlZTIobGlzdCwgZm4pIHtcbiAgICB2YXIgcmVzdWx0cztcbiAgICByZXR1cm4gX3JlZ2VuZXJhdG9yLmRlZmF1bHQud3JhcChmdW5jdGlvbiBfY2FsbGVlMiQoX2NvbnRleHQyKSB7XG4gICAgICB3aGlsZSAoMSkge1xuICAgICAgICBzd2l0Y2ggKF9jb250ZXh0Mi5wcmV2ID0gX2NvbnRleHQyLm5leHQpIHtcbiAgICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICByZXN1bHRzID0gW107XG4gICAgICAgICAgICBfY29udGV4dDIubmV4dCA9IDM7XG4gICAgICAgICAgICByZXR1cm4gbGlzdC5yZWR1Y2UoXG4gICAgICAgICAgICAvKiNfX1BVUkVfXyovXG4gICAgICAgICAgICBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgIHZhciBfcmVmID0gKDAsIF9hc3luY1RvR2VuZXJhdG9yMi5kZWZhdWx0KShcbiAgICAgICAgICAgICAgLyojX19QVVJFX18qL1xuICAgICAgICAgICAgICBfcmVnZW5lcmF0b3IuZGVmYXVsdC5tYXJrKGZ1bmN0aW9uIF9jYWxsZWUocHJvbWlzZSwgZW50cnkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gX3JlZ2VuZXJhdG9yLmRlZmF1bHQud3JhcChmdW5jdGlvbiBfY2FsbGVlJChfY29udGV4dCkge1xuICAgICAgICAgICAgICAgICAgd2hpbGUgKDEpIHtcbiAgICAgICAgICAgICAgICAgICAgc3dpdGNoIChfY29udGV4dC5wcmV2ID0gX2NvbnRleHQubmV4dCkge1xuICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgICAgICAgICAgICAgIF9jb250ZXh0Lm5leHQgPSAyO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHByb21pc2U7XG5cbiAgICAgICAgICAgICAgICAgICAgICBjYXNlIDI6XG4gICAgICAgICAgICAgICAgICAgICAgICBfY29udGV4dC50MCA9IHJlc3VsdHM7XG4gICAgICAgICAgICAgICAgICAgICAgICBfY29udGV4dC5uZXh0ID0gNTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmbihlbnRyeSk7XG5cbiAgICAgICAgICAgICAgICAgICAgICBjYXNlIDU6XG4gICAgICAgICAgICAgICAgICAgICAgICBfY29udGV4dC50MSA9IF9jb250ZXh0LnNlbnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXN1bHRzID0gX2NvbnRleHQudDAuY29uY2F0LmNhbGwoX2NvbnRleHQudDAsIF9jb250ZXh0LnQxKTtcblxuICAgICAgICAgICAgICAgICAgICAgIGNhc2UgNzpcbiAgICAgICAgICAgICAgICAgICAgICBjYXNlIFwiZW5kXCI6XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQuc3RvcCgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSwgX2NhbGxlZSwgdGhpcyk7XG4gICAgICAgICAgICAgIH0pKTtcblxuICAgICAgICAgICAgICByZXR1cm4gZnVuY3Rpb24gKF94MywgX3g0KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9yZWYuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH0oKSwgUHJvbWlzZS5yZXNvbHZlKCkpO1xuXG4gICAgICAgICAgY2FzZSAzOlxuICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0Mi5hYnJ1cHQoXCJyZXR1cm5cIiwgcmVzdWx0cyk7XG5cbiAgICAgICAgICBjYXNlIDQ6XG4gICAgICAgICAgY2FzZSBcImVuZFwiOlxuICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0Mi5zdG9wKCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9LCBfY2FsbGVlMiwgdGhpcyk7XG4gIH0pKTtcbiAgcmV0dXJuIF9wTWFwLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG59XG5cbmZ1bmN0aW9uIG9taXQob2JqKSB7XG4gIGZvciAodmFyIF9sZW4gPSBhcmd1bWVudHMubGVuZ3RoLCBrZXlzID0gbmV3IEFycmF5KF9sZW4gPiAxID8gX2xlbiAtIDEgOiAwKSwgX2tleSA9IDE7IF9rZXkgPCBfbGVuOyBfa2V5KyspIHtcbiAgICBrZXlzW19rZXkgLSAxXSA9IGFyZ3VtZW50c1tfa2V5XTtcbiAgfVxuXG4gIHJldHVybiBPYmplY3Qua2V5cyhvYmopLnJlZHVjZShmdW5jdGlvbiAoYWNjLCBrZXkpIHtcbiAgICBpZiAoIWtleXMuaW5jbHVkZXMoa2V5KSkge1xuICAgICAgYWNjW2tleV0gPSBvYmpba2V5XTtcbiAgICB9XG5cbiAgICByZXR1cm4gYWNjO1xuICB9LCB7fSk7XG59XG4vKipcbiAqIEFsd2F5cyByZXR1cm5zIGEgcmVzb3VyY2UgZGF0YSBvYmplY3QgZnJvbSB0aGUgcHJvdmlkZWQgYXJndW1lbnQuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSAge09iamVjdHxTdHJpbmd9IHJlc291cmNlXG4gKiBAcmV0dXJuIHtPYmplY3R9XG4gKi9cblxuXG5mdW5jdGlvbiB0b0RhdGFCb2R5KHJlc291cmNlKSB7XG4gIGlmIChpc09iamVjdChyZXNvdXJjZSkpIHtcbiAgICByZXR1cm4gcmVzb3VyY2U7XG4gIH1cblxuICBpZiAodHlwZW9mIHJlc291cmNlID09PSBcInN0cmluZ1wiKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGlkOiByZXNvdXJjZVxuICAgIH07XG4gIH1cblxuICB0aHJvdyBuZXcgRXJyb3IoXCJJbnZhbGlkIGFyZ3VtZW50LlwiKTtcbn1cbi8qKlxuICogVHJhbnNmb3JtcyBhbiBvYmplY3QgaW50byBhbiBVUkwgcXVlcnkgc3RyaW5nLCBzdHJpcHBpbmcgb3V0IGFueSB1bmRlZmluZWRcbiAqIHZhbHVlcy5cbiAqXG4gKiBAcGFyYW0gIHtPYmplY3R9IG9ialxuICogQHJldHVybiB7U3RyaW5nfVxuICovXG5cblxuZnVuY3Rpb24gcXNpZnkob2JqKSB7XG4gIHZhciBlbmNvZGUgPSBmdW5jdGlvbiBlbmNvZGUodikge1xuICAgIHJldHVybiBlbmNvZGVVUklDb21wb25lbnQodHlwZW9mIHYgPT09IFwiYm9vbGVhblwiID8gU3RyaW5nKHYpIDogdik7XG4gIH07XG5cbiAgdmFyIHN0cmlwVW5kZWZpbmVkID0gZnVuY3Rpb24gc3RyaXBVbmRlZmluZWQobykge1xuICAgIHJldHVybiBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KG8pKTtcbiAgfTtcblxuICB2YXIgc3RyaXBwZWQgPSBzdHJpcFVuZGVmaW5lZChvYmopO1xuICByZXR1cm4gT2JqZWN0LmtleXMoc3RyaXBwZWQpLm1hcChmdW5jdGlvbiAoaykge1xuICAgIHZhciBrcyA9IGVuY29kZShrKSArIFwiPVwiO1xuXG4gICAgaWYgKEFycmF5LmlzQXJyYXkoc3RyaXBwZWRba10pKSB7XG4gICAgICByZXR1cm4ga3MgKyBzdHJpcHBlZFtrXS5tYXAoZnVuY3Rpb24gKHYpIHtcbiAgICAgICAgcmV0dXJuIGVuY29kZSh2KTtcbiAgICAgIH0pLmpvaW4oXCIsXCIpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4ga3MgKyBlbmNvZGUoc3RyaXBwZWRba10pO1xuICAgIH1cbiAgfSkuam9pbihcIiZcIik7XG59XG4vKipcbiAqIENoZWNrcyBpZiBhIHZlcnNpb24gaXMgd2l0aGluIHRoZSBwcm92aWRlZCByYW5nZS5cbiAqXG4gKiBAcGFyYW0gIHtTdHJpbmd9IHZlcnNpb24gICAgVGhlIHZlcnNpb24gdG8gY2hlY2suXG4gKiBAcGFyYW0gIHtTdHJpbmd9IG1pblZlcnNpb24gVGhlIG1pbmltdW0gc3VwcG9ydGVkIHZlcnNpb24gKGluY2x1c2l2ZSkuXG4gKiBAcGFyYW0gIHtTdHJpbmd9IG1heFZlcnNpb24gVGhlIG1pbmltdW0gc3VwcG9ydGVkIHZlcnNpb24gKGV4Y2x1c2l2ZSkuXG4gKiBAdGhyb3dzIHtFcnJvcn0gSWYgdGhlIHZlcnNpb24gaXMgb3V0c2lkZSBvZiB0aGUgcHJvdmlkZWQgcmFuZ2UuXG4gKi9cblxuXG5mdW5jdGlvbiBjaGVja1ZlcnNpb24odmVyc2lvbiwgbWluVmVyc2lvbiwgbWF4VmVyc2lvbikge1xuICB2YXIgZXh0cmFjdCA9IGZ1bmN0aW9uIGV4dHJhY3Qoc3RyKSB7XG4gICAgcmV0dXJuIHN0ci5zcGxpdChcIi5cIikubWFwKGZ1bmN0aW9uICh4KSB7XG4gICAgICByZXR1cm4gcGFyc2VJbnQoeCwgMTApO1xuICAgIH0pO1xuICB9O1xuXG4gIHZhciBfZXh0cmFjdCA9IGV4dHJhY3QodmVyc2lvbiksXG4gICAgICBfZXh0cmFjdDIgPSAoMCwgX3NsaWNlZFRvQXJyYXkyLmRlZmF1bHQpKF9leHRyYWN0LCAyKSxcbiAgICAgIHZlck1ham9yID0gX2V4dHJhY3QyWzBdLFxuICAgICAgdmVyTWlub3IgPSBfZXh0cmFjdDJbMV07XG5cbiAgdmFyIF9leHRyYWN0MyA9IGV4dHJhY3QobWluVmVyc2lvbiksXG4gICAgICBfZXh0cmFjdDQgPSAoMCwgX3NsaWNlZFRvQXJyYXkyLmRlZmF1bHQpKF9leHRyYWN0MywgMiksXG4gICAgICBtaW5NYWpvciA9IF9leHRyYWN0NFswXSxcbiAgICAgIG1pbk1pbm9yID0gX2V4dHJhY3Q0WzFdO1xuXG4gIHZhciBfZXh0cmFjdDUgPSBleHRyYWN0KG1heFZlcnNpb24pLFxuICAgICAgX2V4dHJhY3Q2ID0gKDAsIF9zbGljZWRUb0FycmF5Mi5kZWZhdWx0KShfZXh0cmFjdDUsIDIpLFxuICAgICAgbWF4TWFqb3IgPSBfZXh0cmFjdDZbMF0sXG4gICAgICBtYXhNaW5vciA9IF9leHRyYWN0NlsxXTtcblxuICB2YXIgY2hlY2tzID0gW3Zlck1ham9yIDwgbWluTWFqb3IsIHZlck1ham9yID09PSBtaW5NYWpvciAmJiB2ZXJNaW5vciA8IG1pbk1pbm9yLCB2ZXJNYWpvciA+IG1heE1ham9yLCB2ZXJNYWpvciA9PT0gbWF4TWFqb3IgJiYgdmVyTWlub3IgPj0gbWF4TWlub3JdO1xuXG4gIGlmIChjaGVja3Muc29tZShmdW5jdGlvbiAoeCkge1xuICAgIHJldHVybiB4O1xuICB9KSkge1xuICAgIHRocm93IG5ldyBFcnJvcihcIlZlcnNpb24gXCIuY29uY2F0KHZlcnNpb24sIFwiIGRvZXNuJ3Qgc2F0aXNmeSBcIikuY29uY2F0KG1pblZlcnNpb24sIFwiIDw9IHggPCBcIikuY29uY2F0KG1heFZlcnNpb24pKTtcbiAgfVxufVxuLyoqXG4gKiBHZW5lcmF0ZXMgYSBkZWNvcmF0b3IgZnVuY3Rpb24gZW5zdXJpbmcgYSB2ZXJzaW9uIGNoZWNrIGlzIHBlcmZvcm1lZCBhZ2FpbnN0XG4gKiB0aGUgcHJvdmlkZWQgcmVxdWlyZW1lbnRzIGJlZm9yZSBleGVjdXRpbmcgaXQuXG4gKlxuICogQHBhcmFtICB7U3RyaW5nfSBtaW4gVGhlIHJlcXVpcmVkIG1pbiB2ZXJzaW9uIChpbmNsdXNpdmUpLlxuICogQHBhcmFtICB7U3RyaW5nfSBtYXggVGhlIHJlcXVpcmVkIG1heCB2ZXJzaW9uIChpbmNsdXNpdmUpLlxuICogQHJldHVybiB7RnVuY3Rpb259XG4gKi9cblxuXG5mdW5jdGlvbiBzdXBwb3J0KG1pbiwgbWF4KSB7XG4gIHJldHVybiBmdW5jdGlvbiAodGFyZ2V0LCBrZXksIGRlc2NyaXB0b3IpIHtcbiAgICB2YXIgZm4gPSBkZXNjcmlwdG9yLnZhbHVlO1xuICAgIHJldHVybiB7XG4gICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcblxuICAgICAgICB2YXIgd3JhcHBlZE1ldGhvZCA9IGZ1bmN0aW9uIHdyYXBwZWRNZXRob2QoKSB7XG4gICAgICAgICAgZm9yICh2YXIgX2xlbjIgPSBhcmd1bWVudHMubGVuZ3RoLCBhcmdzID0gbmV3IEFycmF5KF9sZW4yKSwgX2tleTIgPSAwOyBfa2V5MiA8IF9sZW4yOyBfa2V5MisrKSB7XG4gICAgICAgICAgICBhcmdzW19rZXkyXSA9IGFyZ3VtZW50c1tfa2V5Ml07XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLy8gXCJ0aGlzXCIgaXMgdGhlIGN1cnJlbnQgaW5zdGFuY2Ugd2hpY2ggaXRzIG1ldGhvZCBpcyBkZWNvcmF0ZWQuXG4gICAgICAgICAgdmFyIGNsaWVudCA9IFwiY2xpZW50XCIgaW4gX3RoaXMgPyBfdGhpcy5jbGllbnQgOiBfdGhpcztcbiAgICAgICAgICByZXR1cm4gY2xpZW50LmZldGNoSFRUUEFwaVZlcnNpb24oKS50aGVuKGZ1bmN0aW9uICh2ZXJzaW9uKSB7XG4gICAgICAgICAgICByZXR1cm4gY2hlY2tWZXJzaW9uKHZlcnNpb24sIG1pbiwgbWF4KTtcbiAgICAgICAgICB9KS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJldHVybiBmbi5hcHBseShfdGhpcywgYXJncyk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH07XG5cbiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsIGtleSwge1xuICAgICAgICAgIHZhbHVlOiB3cmFwcGVkTWV0aG9kLFxuICAgICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgICAgICB3cml0YWJsZTogdHJ1ZVxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHdyYXBwZWRNZXRob2Q7XG4gICAgICB9XG4gICAgfTtcbiAgfTtcbn1cbi8qKlxuICogR2VuZXJhdGVzIGEgZGVjb3JhdG9yIGZ1bmN0aW9uIGVuc3VyaW5nIHRoYXQgdGhlIHNwZWNpZmllZCBjYXBhYmlsaXRpZXMgYXJlXG4gKiBhdmFpbGFibGUgb24gdGhlIHNlcnZlciBiZWZvcmUgZXhlY3V0aW5nIGl0LlxuICpcbiAqIEBwYXJhbSAge0FycmF5PFN0cmluZz59IGNhcGFiaWxpdGllcyBUaGUgcmVxdWlyZWQgY2FwYWJpbGl0aWVzLlxuICogQHJldHVybiB7RnVuY3Rpb259XG4gKi9cblxuXG5mdW5jdGlvbiBjYXBhYmxlKGNhcGFiaWxpdGllcykge1xuICByZXR1cm4gZnVuY3Rpb24gKHRhcmdldCwga2V5LCBkZXNjcmlwdG9yKSB7XG4gICAgdmFyIGZuID0gZGVzY3JpcHRvci52YWx1ZTtcbiAgICByZXR1cm4ge1xuICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7XG4gICAgICAgIHZhciBfdGhpczIgPSB0aGlzO1xuXG4gICAgICAgIHZhciB3cmFwcGVkTWV0aG9kID0gZnVuY3Rpb24gd3JhcHBlZE1ldGhvZCgpIHtcbiAgICAgICAgICBmb3IgKHZhciBfbGVuMyA9IGFyZ3VtZW50cy5sZW5ndGgsIGFyZ3MgPSBuZXcgQXJyYXkoX2xlbjMpLCBfa2V5MyA9IDA7IF9rZXkzIDwgX2xlbjM7IF9rZXkzKyspIHtcbiAgICAgICAgICAgIGFyZ3NbX2tleTNdID0gYXJndW1lbnRzW19rZXkzXTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvLyBcInRoaXNcIiBpcyB0aGUgY3VycmVudCBpbnN0YW5jZSB3aGljaCBpdHMgbWV0aG9kIGlzIGRlY29yYXRlZC5cbiAgICAgICAgICB2YXIgY2xpZW50ID0gXCJjbGllbnRcIiBpbiBfdGhpczIgPyBfdGhpczIuY2xpZW50IDogX3RoaXMyO1xuICAgICAgICAgIHJldHVybiBjbGllbnQuZmV0Y2hTZXJ2ZXJDYXBhYmlsaXRpZXMoKS50aGVuKGZ1bmN0aW9uIChhdmFpbGFibGUpIHtcbiAgICAgICAgICAgIHZhciBtaXNzaW5nID0gY2FwYWJpbGl0aWVzLmZpbHRlcihmdW5jdGlvbiAoYykge1xuICAgICAgICAgICAgICByZXR1cm4gIShjIGluIGF2YWlsYWJsZSk7XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgaWYgKG1pc3NpbmcubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICB2YXIgbWlzc2luZ1N0ciA9IG1pc3Npbmcuam9pbihcIiwgXCIpO1xuICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJSZXF1aXJlZCBjYXBhYmlsaXRpZXMgXCIuY29uY2F0KG1pc3NpbmdTdHIsIFwiIG5vdCBwcmVzZW50IG9uIHNlcnZlclwiKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gZm4uYXBwbHkoX3RoaXMyLCBhcmdzKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfTtcblxuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywga2V5LCB7XG4gICAgICAgICAgdmFsdWU6IHdyYXBwZWRNZXRob2QsXG4gICAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgICAgIHdyaXRhYmxlOiB0cnVlXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gd3JhcHBlZE1ldGhvZDtcbiAgICAgIH1cbiAgICB9O1xuICB9O1xufVxuLyoqXG4gKiBHZW5lcmF0ZXMgYSBkZWNvcmF0b3IgZnVuY3Rpb24gZW5zdXJpbmcgYW4gb3BlcmF0aW9uIGlzIG5vdCBwZXJmb3JtZWQgZnJvbVxuICogd2l0aGluIGEgYmF0Y2ggcmVxdWVzdC5cbiAqXG4gKiBAcGFyYW0gIHtTdHJpbmd9IG1lc3NhZ2UgVGhlIGVycm9yIG1lc3NhZ2UgdG8gdGhyb3cuXG4gKiBAcmV0dXJuIHtGdW5jdGlvbn1cbiAqL1xuXG5cbmZ1bmN0aW9uIG5vYmF0Y2gobWVzc2FnZSkge1xuICByZXR1cm4gZnVuY3Rpb24gKHRhcmdldCwga2V5LCBkZXNjcmlwdG9yKSB7XG4gICAgdmFyIGZuID0gZGVzY3JpcHRvci52YWx1ZTtcbiAgICByZXR1cm4ge1xuICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7XG4gICAgICAgIHZhciBfdGhpczMgPSB0aGlzO1xuXG4gICAgICAgIHZhciB3cmFwcGVkTWV0aG9kID0gZnVuY3Rpb24gd3JhcHBlZE1ldGhvZCgpIHtcbiAgICAgICAgICAvLyBcInRoaXNcIiBpcyB0aGUgY3VycmVudCBpbnN0YW5jZSB3aGljaCBpdHMgbWV0aG9kIGlzIGRlY29yYXRlZC5cbiAgICAgICAgICBpZiAoX3RoaXMzLl9pc0JhdGNoKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IobWVzc2FnZSk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgZm9yICh2YXIgX2xlbjQgPSBhcmd1bWVudHMubGVuZ3RoLCBhcmdzID0gbmV3IEFycmF5KF9sZW40KSwgX2tleTQgPSAwOyBfa2V5NCA8IF9sZW40OyBfa2V5NCsrKSB7XG4gICAgICAgICAgICBhcmdzW19rZXk0XSA9IGFyZ3VtZW50c1tfa2V5NF07XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmV0dXJuIGZuLmFwcGx5KF90aGlzMywgYXJncyk7XG4gICAgICAgIH07XG5cbiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsIGtleSwge1xuICAgICAgICAgIHZhbHVlOiB3cmFwcGVkTWV0aG9kLFxuICAgICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgICAgICB3cml0YWJsZTogdHJ1ZVxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHdyYXBwZWRNZXRob2Q7XG4gICAgICB9XG4gICAgfTtcbiAgfTtcbn1cbi8qKlxuICogUmV0dXJucyB0cnVlIGlmIHRoZSBzcGVjaWZpZWQgdmFsdWUgaXMgYW4gb2JqZWN0IChpLmUuIG5vdCBhbiBhcnJheSBub3IgbnVsbCkuXG4gKiBAcGFyYW0gIHtPYmplY3R9IHRoaW5nIFRoZSB2YWx1ZSB0byBpbnNwZWN0LlxuICogQHJldHVybiB7Ym9vbH1cbiAqL1xuXG5cbmZ1bmN0aW9uIGlzT2JqZWN0KHRoaW5nKSB7XG4gIHJldHVybiAoMCwgX3R5cGVvZjIuZGVmYXVsdCkodGhpbmcpID09PSBcIm9iamVjdFwiICYmIHRoaW5nICE9PSBudWxsICYmICFBcnJheS5pc0FycmF5KHRoaW5nKTtcbn1cbi8qKlxuICogUGFyc2VzIGEgZGF0YSB1cmwuXG4gKiBAcGFyYW0gIHtTdHJpbmd9IGRhdGFVUkwgVGhlIGRhdGEgdXJsLlxuICogQHJldHVybiB7T2JqZWN0fVxuICovXG5cblxuZnVuY3Rpb24gcGFyc2VEYXRhVVJMKGRhdGFVUkwpIHtcbiAgdmFyIHJlZ2V4ID0gL15kYXRhOiguKik7YmFzZTY0LCguKikvO1xuICB2YXIgbWF0Y2ggPSBkYXRhVVJMLm1hdGNoKHJlZ2V4KTtcblxuICBpZiAoIW1hdGNoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwiSW52YWxpZCBkYXRhLXVybDogXCIuY29uY2F0KFN0cmluZyhkYXRhVVJMKS5zdWJzdHIoMCwgMzIpLCBcIi4uLlwiKSk7XG4gIH1cblxuICB2YXIgcHJvcHMgPSBtYXRjaFsxXTtcbiAgdmFyIGJhc2U2NCA9IG1hdGNoWzJdO1xuXG4gIHZhciBfcHJvcHMkc3BsaXQgPSBwcm9wcy5zcGxpdChcIjtcIiksXG4gICAgICBfcHJvcHMkc3BsaXQyID0gKDAsIF90b0FycmF5Mi5kZWZhdWx0KShfcHJvcHMkc3BsaXQpLFxuICAgICAgdHlwZSA9IF9wcm9wcyRzcGxpdDJbMF0sXG4gICAgICByYXdQYXJhbXMgPSBfcHJvcHMkc3BsaXQyLnNsaWNlKDEpO1xuXG4gIHZhciBwYXJhbXMgPSByYXdQYXJhbXMucmVkdWNlKGZ1bmN0aW9uIChhY2MsIHBhcmFtKSB7XG4gICAgdmFyIF9wYXJhbSRzcGxpdCA9IHBhcmFtLnNwbGl0KFwiPVwiKSxcbiAgICAgICAgX3BhcmFtJHNwbGl0MiA9ICgwLCBfc2xpY2VkVG9BcnJheTIuZGVmYXVsdCkoX3BhcmFtJHNwbGl0LCAyKSxcbiAgICAgICAga2V5ID0gX3BhcmFtJHNwbGl0MlswXSxcbiAgICAgICAgdmFsdWUgPSBfcGFyYW0kc3BsaXQyWzFdO1xuXG4gICAgcmV0dXJuICgwLCBfb2JqZWN0U3ByZWFkMy5kZWZhdWx0KSh7fSwgYWNjLCAoMCwgX2RlZmluZVByb3BlcnR5Mi5kZWZhdWx0KSh7fSwga2V5LCB2YWx1ZSkpO1xuICB9LCB7fSk7XG4gIHJldHVybiAoMCwgX29iamVjdFNwcmVhZDMuZGVmYXVsdCkoe30sIHBhcmFtcywge1xuICAgIHR5cGU6IHR5cGUsXG4gICAgYmFzZTY0OiBiYXNlNjRcbiAgfSk7XG59XG4vKipcbiAqIEV4dHJhY3RzIGZpbGUgaW5mb3JtYXRpb24gZnJvbSBhIGRhdGEgdXJsLlxuICogQHBhcmFtICB7U3RyaW5nfSBkYXRhVVJMIFRoZSBkYXRhIHVybC5cbiAqIEByZXR1cm4ge09iamVjdH1cbiAqL1xuXG5cbmZ1bmN0aW9uIGV4dHJhY3RGaWxlSW5mbyhkYXRhVVJMKSB7XG4gIHZhciBfcGFyc2VEYXRhVVJMID0gcGFyc2VEYXRhVVJMKGRhdGFVUkwpLFxuICAgICAgbmFtZSA9IF9wYXJzZURhdGFVUkwubmFtZSxcbiAgICAgIHR5cGUgPSBfcGFyc2VEYXRhVVJMLnR5cGUsXG4gICAgICBiYXNlNjQgPSBfcGFyc2VEYXRhVVJMLmJhc2U2NDtcblxuICB2YXIgYmluYXJ5ID0gYXRvYihiYXNlNjQpO1xuICB2YXIgYXJyYXkgPSBbXTtcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IGJpbmFyeS5sZW5ndGg7IGkrKykge1xuICAgIGFycmF5LnB1c2goYmluYXJ5LmNoYXJDb2RlQXQoaSkpO1xuICB9XG5cbiAgdmFyIGJsb2IgPSBuZXcgQmxvYihbbmV3IFVpbnQ4QXJyYXkoYXJyYXkpXSwge1xuICAgIHR5cGU6IHR5cGVcbiAgfSk7XG4gIHJldHVybiB7XG4gICAgYmxvYjogYmxvYixcbiAgICBuYW1lOiBuYW1lXG4gIH07XG59XG4vKipcbiAqIENyZWF0ZXMgYSBGb3JtRGF0YSBpbnN0YW5jZSBmcm9tIGEgZGF0YSB1cmwgYW5kIGFuIGV4aXN0aW5nIEpTT04gcmVzcG9uc2VcbiAqIGJvZHkuXG4gKiBAcGFyYW0gIHtTdHJpbmd9IGRhdGFVUkwgICAgICAgICAgICBUaGUgZGF0YSB1cmwuXG4gKiBAcGFyYW0gIHtPYmplY3R9IGJvZHkgICAgICAgICAgICAgICBUaGUgcmVzcG9uc2UgYm9keS5cbiAqIEBwYXJhbSAge09iamVjdH0gW29wdGlvbnM9e31dICAgICAgIFRoZSBvcHRpb25zIG9iamVjdC5cbiAqIEBwYXJhbSAge09iamVjdH0gW29wdGlvbnMuZmlsZW5hbWVdIEZvcmNlIGF0dGFjaG1lbnQgZmlsZSBuYW1lLlxuICogQHJldHVybiB7Rm9ybURhdGF9XG4gKi9cblxuXG5mdW5jdGlvbiBjcmVhdGVGb3JtRGF0YShkYXRhVVJMLCBib2R5KSB7XG4gIHZhciBvcHRpb25zID0gYXJndW1lbnRzLmxlbmd0aCA+IDIgJiYgYXJndW1lbnRzWzJdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMl0gOiB7fTtcbiAgdmFyIF9vcHRpb25zJGZpbGVuYW1lID0gb3B0aW9ucy5maWxlbmFtZSxcbiAgICAgIGZpbGVuYW1lID0gX29wdGlvbnMkZmlsZW5hbWUgPT09IHZvaWQgMCA/IFwidW50aXRsZWRcIiA6IF9vcHRpb25zJGZpbGVuYW1lO1xuXG4gIHZhciBfZXh0cmFjdEZpbGVJbmZvID0gZXh0cmFjdEZpbGVJbmZvKGRhdGFVUkwpLFxuICAgICAgYmxvYiA9IF9leHRyYWN0RmlsZUluZm8uYmxvYixcbiAgICAgIG5hbWUgPSBfZXh0cmFjdEZpbGVJbmZvLm5hbWU7XG5cbiAgdmFyIGZvcm1EYXRhID0gbmV3IEZvcm1EYXRhKCk7XG4gIGZvcm1EYXRhLmFwcGVuZChcImF0dGFjaG1lbnRcIiwgYmxvYiwgbmFtZSB8fCBmaWxlbmFtZSk7XG5cbiAgZm9yICh2YXIgcHJvcGVydHkgaW4gYm9keSkge1xuICAgIGlmICh0eXBlb2YgYm9keVtwcm9wZXJ0eV0gIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgIGZvcm1EYXRhLmFwcGVuZChwcm9wZXJ0eSwgSlNPTi5zdHJpbmdpZnkoYm9keVtwcm9wZXJ0eV0pKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gZm9ybURhdGE7XG59XG4vKipcbiAqIENsb25lcyBhbiBvYmplY3Qgd2l0aCBhbGwgaXRzIHVuZGVmaW5lZCBrZXlzIHJlbW92ZWQuXG4gKiBAcHJpdmF0ZVxuICovXG5cblxuZnVuY3Rpb24gY2xlYW5VbmRlZmluZWRQcm9wZXJ0aWVzKG9iaikge1xuICB2YXIgcmVzdWx0ID0ge307XG5cbiAgZm9yICh2YXIga2V5IGluIG9iaikge1xuICAgIGlmICh0eXBlb2Ygb2JqW2tleV0gIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgIHJlc3VsdFtrZXldID0gb2JqW2tleV07XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn0iLCJ2YXIgdjEgPSByZXF1aXJlKCcuL3YxJyk7XG52YXIgdjQgPSByZXF1aXJlKCcuL3Y0Jyk7XG5cbnZhciB1dWlkID0gdjQ7XG51dWlkLnYxID0gdjE7XG51dWlkLnY0ID0gdjQ7XG5cbm1vZHVsZS5leHBvcnRzID0gdXVpZDtcbiIsIi8qKlxuICogQ29udmVydCBhcnJheSBvZiAxNiBieXRlIHZhbHVlcyB0byBVVUlEIHN0cmluZyBmb3JtYXQgb2YgdGhlIGZvcm06XG4gKiBYWFhYWFhYWC1YWFhYLVhYWFgtWFhYWC1YWFhYWFhYWFhYWFhcbiAqL1xudmFyIGJ5dGVUb0hleCA9IFtdO1xuZm9yICh2YXIgaSA9IDA7IGkgPCAyNTY7ICsraSkge1xuICBieXRlVG9IZXhbaV0gPSAoaSArIDB4MTAwKS50b1N0cmluZygxNikuc3Vic3RyKDEpO1xufVxuXG5mdW5jdGlvbiBieXRlc1RvVXVpZChidWYsIG9mZnNldCkge1xuICB2YXIgaSA9IG9mZnNldCB8fCAwO1xuICB2YXIgYnRoID0gYnl0ZVRvSGV4O1xuICAvLyBqb2luIHVzZWQgdG8gZml4IG1lbW9yeSBpc3N1ZSBjYXVzZWQgYnkgY29uY2F0ZW5hdGlvbjogaHR0cHM6Ly9idWdzLmNocm9taXVtLm9yZy9wL3Y4L2lzc3Vlcy9kZXRhaWw/aWQ9MzE3NSNjNFxuICByZXR1cm4gKFtidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dLCBcblx0YnRoW2J1ZltpKytdXSwgYnRoW2J1ZltpKytdXSwgJy0nLFxuXHRidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dLCAnLScsXG5cdGJ0aFtidWZbaSsrXV0sIGJ0aFtidWZbaSsrXV0sICctJyxcblx0YnRoW2J1ZltpKytdXSwgYnRoW2J1ZltpKytdXSwgJy0nLFxuXHRidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dLFxuXHRidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dLFxuXHRidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dXSkuam9pbignJyk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYnl0ZXNUb1V1aWQ7XG4iLCIvLyBVbmlxdWUgSUQgY3JlYXRpb24gcmVxdWlyZXMgYSBoaWdoIHF1YWxpdHkgcmFuZG9tICMgZ2VuZXJhdG9yLiAgSW4gdGhlXG4vLyBicm93c2VyIHRoaXMgaXMgYSBsaXR0bGUgY29tcGxpY2F0ZWQgZHVlIHRvIHVua25vd24gcXVhbGl0eSBvZiBNYXRoLnJhbmRvbSgpXG4vLyBhbmQgaW5jb25zaXN0ZW50IHN1cHBvcnQgZm9yIHRoZSBgY3J5cHRvYCBBUEkuICBXZSBkbyB0aGUgYmVzdCB3ZSBjYW4gdmlhXG4vLyBmZWF0dXJlLWRldGVjdGlvblxuXG4vLyBnZXRSYW5kb21WYWx1ZXMgbmVlZHMgdG8gYmUgaW52b2tlZCBpbiBhIGNvbnRleHQgd2hlcmUgXCJ0aGlzXCIgaXMgYSBDcnlwdG9cbi8vIGltcGxlbWVudGF0aW9uLiBBbHNvLCBmaW5kIHRoZSBjb21wbGV0ZSBpbXBsZW1lbnRhdGlvbiBvZiBjcnlwdG8gb24gSUUxMS5cbnZhciBnZXRSYW5kb21WYWx1ZXMgPSAodHlwZW9mKGNyeXB0bykgIT0gJ3VuZGVmaW5lZCcgJiYgY3J5cHRvLmdldFJhbmRvbVZhbHVlcyAmJiBjcnlwdG8uZ2V0UmFuZG9tVmFsdWVzLmJpbmQoY3J5cHRvKSkgfHxcbiAgICAgICAgICAgICAgICAgICAgICAodHlwZW9mKG1zQ3J5cHRvKSAhPSAndW5kZWZpbmVkJyAmJiB0eXBlb2Ygd2luZG93Lm1zQ3J5cHRvLmdldFJhbmRvbVZhbHVlcyA9PSAnZnVuY3Rpb24nICYmIG1zQ3J5cHRvLmdldFJhbmRvbVZhbHVlcy5iaW5kKG1zQ3J5cHRvKSk7XG5cbmlmIChnZXRSYW5kb21WYWx1ZXMpIHtcbiAgLy8gV0hBVFdHIGNyeXB0byBSTkcgLSBodHRwOi8vd2lraS53aGF0d2cub3JnL3dpa2kvQ3J5cHRvXG4gIHZhciBybmRzOCA9IG5ldyBVaW50OEFycmF5KDE2KTsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby11bmRlZlxuXG4gIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gd2hhdHdnUk5HKCkge1xuICAgIGdldFJhbmRvbVZhbHVlcyhybmRzOCk7XG4gICAgcmV0dXJuIHJuZHM4O1xuICB9O1xufSBlbHNlIHtcbiAgLy8gTWF0aC5yYW5kb20oKS1iYXNlZCAoUk5HKVxuICAvL1xuICAvLyBJZiBhbGwgZWxzZSBmYWlscywgdXNlIE1hdGgucmFuZG9tKCkuICBJdCdzIGZhc3QsIGJ1dCBpcyBvZiB1bnNwZWNpZmllZFxuICAvLyBxdWFsaXR5LlxuICB2YXIgcm5kcyA9IG5ldyBBcnJheSgxNik7XG5cbiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBtYXRoUk5HKCkge1xuICAgIGZvciAodmFyIGkgPSAwLCByOyBpIDwgMTY7IGkrKykge1xuICAgICAgaWYgKChpICYgMHgwMykgPT09IDApIHIgPSBNYXRoLnJhbmRvbSgpICogMHgxMDAwMDAwMDA7XG4gICAgICBybmRzW2ldID0gciA+Pj4gKChpICYgMHgwMykgPDwgMykgJiAweGZmO1xuICAgIH1cblxuICAgIHJldHVybiBybmRzO1xuICB9O1xufVxuIiwidmFyIHJuZyA9IHJlcXVpcmUoJy4vbGliL3JuZycpO1xudmFyIGJ5dGVzVG9VdWlkID0gcmVxdWlyZSgnLi9saWIvYnl0ZXNUb1V1aWQnKTtcblxuLy8gKipgdjEoKWAgLSBHZW5lcmF0ZSB0aW1lLWJhc2VkIFVVSUQqKlxuLy9cbi8vIEluc3BpcmVkIGJ5IGh0dHBzOi8vZ2l0aHViLmNvbS9MaW9zSy9VVUlELmpzXG4vLyBhbmQgaHR0cDovL2RvY3MucHl0aG9uLm9yZy9saWJyYXJ5L3V1aWQuaHRtbFxuXG52YXIgX25vZGVJZDtcbnZhciBfY2xvY2tzZXE7XG5cbi8vIFByZXZpb3VzIHV1aWQgY3JlYXRpb24gdGltZVxudmFyIF9sYXN0TVNlY3MgPSAwO1xudmFyIF9sYXN0TlNlY3MgPSAwO1xuXG4vLyBTZWUgaHR0cHM6Ly9naXRodWIuY29tL2Jyb29mYS9ub2RlLXV1aWQgZm9yIEFQSSBkZXRhaWxzXG5mdW5jdGlvbiB2MShvcHRpb25zLCBidWYsIG9mZnNldCkge1xuICB2YXIgaSA9IGJ1ZiAmJiBvZmZzZXQgfHwgMDtcbiAgdmFyIGIgPSBidWYgfHwgW107XG5cbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG4gIHZhciBub2RlID0gb3B0aW9ucy5ub2RlIHx8IF9ub2RlSWQ7XG4gIHZhciBjbG9ja3NlcSA9IG9wdGlvbnMuY2xvY2tzZXEgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMuY2xvY2tzZXEgOiBfY2xvY2tzZXE7XG5cbiAgLy8gbm9kZSBhbmQgY2xvY2tzZXEgbmVlZCB0byBiZSBpbml0aWFsaXplZCB0byByYW5kb20gdmFsdWVzIGlmIHRoZXkncmUgbm90XG4gIC8vIHNwZWNpZmllZC4gIFdlIGRvIHRoaXMgbGF6aWx5IHRvIG1pbmltaXplIGlzc3VlcyByZWxhdGVkIHRvIGluc3VmZmljaWVudFxuICAvLyBzeXN0ZW0gZW50cm9weS4gIFNlZSAjMTg5XG4gIGlmIChub2RlID09IG51bGwgfHwgY2xvY2tzZXEgPT0gbnVsbCkge1xuICAgIHZhciBzZWVkQnl0ZXMgPSBybmcoKTtcbiAgICBpZiAobm9kZSA9PSBudWxsKSB7XG4gICAgICAvLyBQZXIgNC41LCBjcmVhdGUgYW5kIDQ4LWJpdCBub2RlIGlkLCAoNDcgcmFuZG9tIGJpdHMgKyBtdWx0aWNhc3QgYml0ID0gMSlcbiAgICAgIG5vZGUgPSBfbm9kZUlkID0gW1xuICAgICAgICBzZWVkQnl0ZXNbMF0gfCAweDAxLFxuICAgICAgICBzZWVkQnl0ZXNbMV0sIHNlZWRCeXRlc1syXSwgc2VlZEJ5dGVzWzNdLCBzZWVkQnl0ZXNbNF0sIHNlZWRCeXRlc1s1XVxuICAgICAgXTtcbiAgICB9XG4gICAgaWYgKGNsb2Nrc2VxID09IG51bGwpIHtcbiAgICAgIC8vIFBlciA0LjIuMiwgcmFuZG9taXplICgxNCBiaXQpIGNsb2Nrc2VxXG4gICAgICBjbG9ja3NlcSA9IF9jbG9ja3NlcSA9IChzZWVkQnl0ZXNbNl0gPDwgOCB8IHNlZWRCeXRlc1s3XSkgJiAweDNmZmY7XG4gICAgfVxuICB9XG5cbiAgLy8gVVVJRCB0aW1lc3RhbXBzIGFyZSAxMDAgbmFuby1zZWNvbmQgdW5pdHMgc2luY2UgdGhlIEdyZWdvcmlhbiBlcG9jaCxcbiAgLy8gKDE1ODItMTAtMTUgMDA6MDApLiAgSlNOdW1iZXJzIGFyZW4ndCBwcmVjaXNlIGVub3VnaCBmb3IgdGhpcywgc29cbiAgLy8gdGltZSBpcyBoYW5kbGVkIGludGVybmFsbHkgYXMgJ21zZWNzJyAoaW50ZWdlciBtaWxsaXNlY29uZHMpIGFuZCAnbnNlY3MnXG4gIC8vICgxMDAtbmFub3NlY29uZHMgb2Zmc2V0IGZyb20gbXNlY3MpIHNpbmNlIHVuaXggZXBvY2gsIDE5NzAtMDEtMDEgMDA6MDAuXG4gIHZhciBtc2VjcyA9IG9wdGlvbnMubXNlY3MgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMubXNlY3MgOiBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcblxuICAvLyBQZXIgNC4yLjEuMiwgdXNlIGNvdW50IG9mIHV1aWQncyBnZW5lcmF0ZWQgZHVyaW5nIHRoZSBjdXJyZW50IGNsb2NrXG4gIC8vIGN5Y2xlIHRvIHNpbXVsYXRlIGhpZ2hlciByZXNvbHV0aW9uIGNsb2NrXG4gIHZhciBuc2VjcyA9IG9wdGlvbnMubnNlY3MgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMubnNlY3MgOiBfbGFzdE5TZWNzICsgMTtcblxuICAvLyBUaW1lIHNpbmNlIGxhc3QgdXVpZCBjcmVhdGlvbiAoaW4gbXNlY3MpXG4gIHZhciBkdCA9IChtc2VjcyAtIF9sYXN0TVNlY3MpICsgKG5zZWNzIC0gX2xhc3ROU2VjcykvMTAwMDA7XG5cbiAgLy8gUGVyIDQuMi4xLjIsIEJ1bXAgY2xvY2tzZXEgb24gY2xvY2sgcmVncmVzc2lvblxuICBpZiAoZHQgPCAwICYmIG9wdGlvbnMuY2xvY2tzZXEgPT09IHVuZGVmaW5lZCkge1xuICAgIGNsb2Nrc2VxID0gY2xvY2tzZXEgKyAxICYgMHgzZmZmO1xuICB9XG5cbiAgLy8gUmVzZXQgbnNlY3MgaWYgY2xvY2sgcmVncmVzc2VzIChuZXcgY2xvY2tzZXEpIG9yIHdlJ3ZlIG1vdmVkIG9udG8gYSBuZXdcbiAgLy8gdGltZSBpbnRlcnZhbFxuICBpZiAoKGR0IDwgMCB8fCBtc2VjcyA+IF9sYXN0TVNlY3MpICYmIG9wdGlvbnMubnNlY3MgPT09IHVuZGVmaW5lZCkge1xuICAgIG5zZWNzID0gMDtcbiAgfVxuXG4gIC8vIFBlciA0LjIuMS4yIFRocm93IGVycm9yIGlmIHRvbyBtYW55IHV1aWRzIGFyZSByZXF1ZXN0ZWRcbiAgaWYgKG5zZWNzID49IDEwMDAwKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCd1dWlkLnYxKCk6IENhblxcJ3QgY3JlYXRlIG1vcmUgdGhhbiAxME0gdXVpZHMvc2VjJyk7XG4gIH1cblxuICBfbGFzdE1TZWNzID0gbXNlY3M7XG4gIF9sYXN0TlNlY3MgPSBuc2VjcztcbiAgX2Nsb2Nrc2VxID0gY2xvY2tzZXE7XG5cbiAgLy8gUGVyIDQuMS40IC0gQ29udmVydCBmcm9tIHVuaXggZXBvY2ggdG8gR3JlZ29yaWFuIGVwb2NoXG4gIG1zZWNzICs9IDEyMjE5MjkyODAwMDAwO1xuXG4gIC8vIGB0aW1lX2xvd2BcbiAgdmFyIHRsID0gKChtc2VjcyAmIDB4ZmZmZmZmZikgKiAxMDAwMCArIG5zZWNzKSAlIDB4MTAwMDAwMDAwO1xuICBiW2krK10gPSB0bCA+Pj4gMjQgJiAweGZmO1xuICBiW2krK10gPSB0bCA+Pj4gMTYgJiAweGZmO1xuICBiW2krK10gPSB0bCA+Pj4gOCAmIDB4ZmY7XG4gIGJbaSsrXSA9IHRsICYgMHhmZjtcblxuICAvLyBgdGltZV9taWRgXG4gIHZhciB0bWggPSAobXNlY3MgLyAweDEwMDAwMDAwMCAqIDEwMDAwKSAmIDB4ZmZmZmZmZjtcbiAgYltpKytdID0gdG1oID4+PiA4ICYgMHhmZjtcbiAgYltpKytdID0gdG1oICYgMHhmZjtcblxuICAvLyBgdGltZV9oaWdoX2FuZF92ZXJzaW9uYFxuICBiW2krK10gPSB0bWggPj4+IDI0ICYgMHhmIHwgMHgxMDsgLy8gaW5jbHVkZSB2ZXJzaW9uXG4gIGJbaSsrXSA9IHRtaCA+Pj4gMTYgJiAweGZmO1xuXG4gIC8vIGBjbG9ja19zZXFfaGlfYW5kX3Jlc2VydmVkYCAoUGVyIDQuMi4yIC0gaW5jbHVkZSB2YXJpYW50KVxuICBiW2krK10gPSBjbG9ja3NlcSA+Pj4gOCB8IDB4ODA7XG5cbiAgLy8gYGNsb2NrX3NlcV9sb3dgXG4gIGJbaSsrXSA9IGNsb2Nrc2VxICYgMHhmZjtcblxuICAvLyBgbm9kZWBcbiAgZm9yICh2YXIgbiA9IDA7IG4gPCA2OyArK24pIHtcbiAgICBiW2kgKyBuXSA9IG5vZGVbbl07XG4gIH1cblxuICByZXR1cm4gYnVmID8gYnVmIDogYnl0ZXNUb1V1aWQoYik7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gdjE7XG4iLCJ2YXIgcm5nID0gcmVxdWlyZSgnLi9saWIvcm5nJyk7XG52YXIgYnl0ZXNUb1V1aWQgPSByZXF1aXJlKCcuL2xpYi9ieXRlc1RvVXVpZCcpO1xuXG5mdW5jdGlvbiB2NChvcHRpb25zLCBidWYsIG9mZnNldCkge1xuICB2YXIgaSA9IGJ1ZiAmJiBvZmZzZXQgfHwgMDtcblxuICBpZiAodHlwZW9mKG9wdGlvbnMpID09ICdzdHJpbmcnKSB7XG4gICAgYnVmID0gb3B0aW9ucyA9PT0gJ2JpbmFyeScgPyBuZXcgQXJyYXkoMTYpIDogbnVsbDtcbiAgICBvcHRpb25zID0gbnVsbDtcbiAgfVxuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcblxuICB2YXIgcm5kcyA9IG9wdGlvbnMucmFuZG9tIHx8IChvcHRpb25zLnJuZyB8fCBybmcpKCk7XG5cbiAgLy8gUGVyIDQuNCwgc2V0IGJpdHMgZm9yIHZlcnNpb24gYW5kIGBjbG9ja19zZXFfaGlfYW5kX3Jlc2VydmVkYFxuICBybmRzWzZdID0gKHJuZHNbNl0gJiAweDBmKSB8IDB4NDA7XG4gIHJuZHNbOF0gPSAocm5kc1s4XSAmIDB4M2YpIHwgMHg4MDtcblxuICAvLyBDb3B5IGJ5dGVzIHRvIGJ1ZmZlciwgaWYgcHJvdmlkZWRcbiAgaWYgKGJ1Zikge1xuICAgIGZvciAodmFyIGlpID0gMDsgaWkgPCAxNjsgKytpaSkge1xuICAgICAgYnVmW2kgKyBpaV0gPSBybmRzW2lpXTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gYnVmIHx8IGJ5dGVzVG9VdWlkKHJuZHMpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHY0O1xuIiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbmltcG9ydCBDb2xsZWN0aW9uIGZyb20gXCIuL2NvbGxlY3Rpb25cIjtcbmltcG9ydCBCYXNlQWRhcHRlciBmcm9tIFwiLi9hZGFwdGVycy9iYXNlXCI7XG5cbmNvbnN0IERFRkFVTFRfQlVDS0VUX05BTUUgPSBcImRlZmF1bHRcIjtcbmNvbnN0IERFRkFVTFRfUkVNT1RFID0gXCJodHRwOi8vbG9jYWxob3N0Ojg4ODgvdjFcIjtcbmNvbnN0IERFRkFVTFRfUkVUUlkgPSAxO1xuXG4vKipcbiAqIEtpbnRvQmFzZSBjbGFzcy5cbiAqL1xuZXhwb3J0IGRlZmF1bHQgY2xhc3MgS2ludG9CYXNlIHtcbiAgLyoqXG4gICAqIFByb3ZpZGVzIGEgcHVibGljIGFjY2VzcyB0byB0aGUgYmFzZSBhZGFwdGVyIGNsYXNzLiBVc2VycyBjYW4gY3JlYXRlIGFcbiAgICogY3VzdG9tIERCIGFkYXB0ZXIgYnkgZXh0ZW5kaW5nIHtAbGluayBCYXNlQWRhcHRlcn0uXG4gICAqXG4gICAqIEB0eXBlIHtPYmplY3R9XG4gICAqL1xuICBzdGF0aWMgZ2V0IGFkYXB0ZXJzKCkge1xuICAgIHJldHVybiB7XG4gICAgICBCYXNlQWRhcHRlcjogQmFzZUFkYXB0ZXIsXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTeW5jaHJvbml6YXRpb24gc3RyYXRlZ2llcy4gQXZhaWxhYmxlIHN0cmF0ZWdpZXMgYXJlOlxuICAgKlxuICAgKiAtIGBNQU5VQUxgOiBDb25mbGljdHMgd2lsbCBiZSByZXBvcnRlZCBpbiBhIGRlZGljYXRlZCBhcnJheS5cbiAgICogLSBgU0VSVkVSX1dJTlNgOiBDb25mbGljdHMgYXJlIHJlc29sdmVkIHVzaW5nIHJlbW90ZSBkYXRhLlxuICAgKiAtIGBDTElFTlRfV0lOU2A6IENvbmZsaWN0cyBhcmUgcmVzb2x2ZWQgdXNpbmcgbG9jYWwgZGF0YS5cbiAgICpcbiAgICogQHR5cGUge09iamVjdH1cbiAgICovXG4gIHN0YXRpYyBnZXQgc3luY1N0cmF0ZWd5KCkge1xuICAgIHJldHVybiBDb2xsZWN0aW9uLnN0cmF0ZWd5O1xuICB9XG5cbiAgLyoqXG4gICAqIENvbnN0cnVjdG9yLlxuICAgKlxuICAgKiBPcHRpb25zOlxuICAgKiAtIGB7U3RyaW5nfWAgICAgICAgYHJlbW90ZWAgICAgICAgICBUaGUgc2VydmVyIFVSTCB0byB1c2UuXG4gICAqIC0gYHtTdHJpbmd9YCAgICAgICBgYnVja2V0YCAgICAgICAgIFRoZSBjb2xsZWN0aW9uIGJ1Y2tldCBuYW1lLlxuICAgKiAtIGB7RXZlbnRFbWl0dGVyfWAgYGV2ZW50c2AgICAgICAgICBFdmVudHMgaGFuZGxlci5cbiAgICogLSBge0Jhc2VBZGFwdGVyfWAgIGBhZGFwdGVyYCAgICAgICAgVGhlIGJhc2UgREIgYWRhcHRlciBjbGFzcy5cbiAgICogLSBge09iamVjdH1gICAgICAgIGBhZGFwdGVyT3B0aW9uc2AgT3B0aW9ucyBnaXZlbiB0byB0aGUgYWRhcHRlci5cbiAgICogLSBge09iamVjdH1gICAgICAgIGBoZWFkZXJzYCAgICAgICAgVGhlIEhUVFAgaGVhZGVycyB0byB1c2UuXG4gICAqIC0gYHtPYmplY3R9YCAgICAgICBgcmV0cnlgICAgICAgICAgIE51bWJlciBvZiByZXRyaWVzIHdoZW4gdGhlIHNlcnZlciBmYWlscyB0byBwcm9jZXNzIHRoZSByZXF1ZXN0IChkZWZhdWx0OiBgMWApXG4gICAqIC0gYHtTdHJpbmd9YCAgICAgICBgcmVxdWVzdE1vZGVgICAgIFRoZSBIVFRQIENPUlMgbW9kZSB0byB1c2UuXG4gICAqIC0gYHtOdW1iZXJ9YCAgICAgICBgdGltZW91dGAgICAgICAgIFRoZSByZXF1ZXN0cyB0aW1lb3V0IGluIG1zIChkZWZhdWx0OiBgNTAwMGApLlxuICAgKlxuICAgKiBAcGFyYW0gIHtPYmplY3R9IG9wdGlvbnMgVGhlIG9wdGlvbnMgb2JqZWN0LlxuICAgKi9cbiAgY29uc3RydWN0b3Iob3B0aW9ucyA9IHt9KSB7XG4gICAgY29uc3QgZGVmYXVsdHMgPSB7XG4gICAgICBidWNrZXQ6IERFRkFVTFRfQlVDS0VUX05BTUUsXG4gICAgICByZW1vdGU6IERFRkFVTFRfUkVNT1RFLFxuICAgICAgcmV0cnk6IERFRkFVTFRfUkVUUlksXG4gICAgfTtcbiAgICB0aGlzLl9vcHRpb25zID0geyAuLi5kZWZhdWx0cywgLi4ub3B0aW9ucyB9O1xuICAgIGlmICghdGhpcy5fb3B0aW9ucy5hZGFwdGVyKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJObyBhZGFwdGVyIHByb3ZpZGVkXCIpO1xuICAgIH1cblxuICAgIGNvbnN0IHtcbiAgICAgIEFwaUNsYXNzLFxuICAgICAgZXZlbnRzLFxuICAgICAgaGVhZGVycyxcbiAgICAgIHJlbW90ZSxcbiAgICAgIHJlcXVlc3RNb2RlLFxuICAgICAgcmV0cnksXG4gICAgICB0aW1lb3V0LFxuICAgIH0gPSB0aGlzLl9vcHRpb25zO1xuXG4gICAgLy8gcHVibGljIHByb3BlcnRpZXNcblxuICAgIC8qKlxuICAgICAqIFRoZSBraW50byBIVFRQIGNsaWVudCBpbnN0YW5jZS5cbiAgICAgKiBAdHlwZSB7S2ludG9DbGllbnR9XG4gICAgICovXG4gICAgdGhpcy5hcGkgPSBuZXcgQXBpQ2xhc3MocmVtb3RlLCB7XG4gICAgICBldmVudHMsXG4gICAgICBoZWFkZXJzLFxuICAgICAgcmVxdWVzdE1vZGUsXG4gICAgICByZXRyeSxcbiAgICAgIHRpbWVvdXQsXG4gICAgfSk7XG4gICAgLyoqXG4gICAgICogVGhlIGV2ZW50IGVtaXR0ZXIgaW5zdGFuY2UuXG4gICAgICogQHR5cGUge0V2ZW50RW1pdHRlcn1cbiAgICAgKi9cbiAgICB0aGlzLmV2ZW50cyA9IHRoaXMuX29wdGlvbnMuZXZlbnRzO1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgYSB7QGxpbmsgQ29sbGVjdGlvbn0gaW5zdGFuY2UuIFRoZSBzZWNvbmQgKG9wdGlvbmFsKSBwYXJhbWV0ZXJcbiAgICogd2lsbCBzZXQgY29sbGVjdGlvbi1sZXZlbCBvcHRpb25zIGxpa2UgZS5nLiBgcmVtb3RlVHJhbnNmb3JtZXJzYC5cbiAgICpcbiAgICogQHBhcmFtICB7U3RyaW5nfSBjb2xsTmFtZSBUaGUgY29sbGVjdGlvbiBuYW1lLlxuICAgKiBAcGFyYW0gIHtPYmplY3R9IFtvcHRpb25zPXt9XSAgICAgICAgICAgICAgICAgRXh0cmEgb3B0aW9ucyBvciBvdmVycmlkZSBjbGllbnQncyBvcHRpb25zLlxuICAgKiBAcGFyYW0gIHtPYmplY3R9IFtvcHRpb25zLmlkU2NoZW1hXSAgICAgICAgICAgSWRTY2hlbWEgaW5zdGFuY2UgKGRlZmF1bHQ6IFVVSUQpXG4gICAqIEBwYXJhbSAge09iamVjdH0gW29wdGlvbnMucmVtb3RlVHJhbnNmb3JtZXJzXSBBcnJheTxSZW1vdGVUcmFuc2Zvcm1lcj4gKGRlZmF1bHQ6IGBbXWBdKVxuICAgKiBAcGFyYW0gIHtPYmplY3R9IFtvcHRpb25zLmhvb2tzXSAgICAgICAgICAgICAgQXJyYXk8SG9vaz4gKGRlZmF1bHQ6IGBbXWBdKVxuICAgKiBAcGFyYW0gIHtPYmplY3R9IFtvcHRpb25zLmxvY2FsRmllbGRzXSAgICAgICAgQXJyYXk8RmllbGQ+IChkZWZhdWx0OiBgW11gXSlcbiAgICogQHJldHVybiB7Q29sbGVjdGlvbn1cbiAgICovXG4gIGNvbGxlY3Rpb24oY29sbE5hbWUsIG9wdGlvbnMgPSB7fSkge1xuICAgIGlmICghY29sbE5hbWUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIm1pc3NpbmcgY29sbGVjdGlvbiBuYW1lXCIpO1xuICAgIH1cbiAgICBjb25zdCB7IGJ1Y2tldCwgZXZlbnRzLCBhZGFwdGVyLCBhZGFwdGVyT3B0aW9ucyB9ID0ge1xuICAgICAgLi4udGhpcy5fb3B0aW9ucyxcbiAgICAgIC4uLm9wdGlvbnMsXG4gICAgfTtcbiAgICBjb25zdCB7IGlkU2NoZW1hLCByZW1vdGVUcmFuc2Zvcm1lcnMsIGhvb2tzLCBsb2NhbEZpZWxkcyB9ID0gb3B0aW9ucztcblxuICAgIHJldHVybiBuZXcgQ29sbGVjdGlvbihidWNrZXQsIGNvbGxOYW1lLCB0aGlzLmFwaSwge1xuICAgICAgZXZlbnRzLFxuICAgICAgYWRhcHRlcixcbiAgICAgIGFkYXB0ZXJPcHRpb25zLFxuICAgICAgaWRTY2hlbWEsXG4gICAgICByZW1vdGVUcmFuc2Zvcm1lcnMsXG4gICAgICBob29rcyxcbiAgICAgIGxvY2FsRmllbGRzLFxuICAgIH0pO1xuICB9XG59XG4iLCJcInVzZSBzdHJpY3RcIjtcblxuaW1wb3J0IEJhc2VBZGFwdGVyIGZyb20gXCIuL2Jhc2UuanNcIjtcbmltcG9ydCB7XG4gIGZpbHRlck9iamVjdCxcbiAgb21pdEtleXMsXG4gIHNvcnRPYmplY3RzLFxuICBhcnJheUVxdWFsLFxuICB0cmFuc2Zvcm1TdWJPYmplY3RGaWx0ZXJzLFxufSBmcm9tIFwiLi4vdXRpbHNcIjtcblxuY29uc3QgSU5ERVhFRF9GSUVMRFMgPSBbXCJpZFwiLCBcIl9zdGF0dXNcIiwgXCJsYXN0X21vZGlmaWVkXCJdO1xuXG4vKipcbiAqIFNtYWxsIGhlbHBlciB0aGF0IHdyYXBzIHRoZSBvcGVuaW5nIG9mIGFuIEluZGV4ZWREQiBpbnRvIGEgUHJvbWlzZS5cbiAqXG4gKiBAcGFyYW0gZGJuYW1lICAgICAgICAgIHtTdHJpbmd9ICAgVGhlIGRhdGFiYXNlIG5hbWUuXG4gKiBAcGFyYW0gdmVyc2lvbiAgICAgICAgIHtJbnRlZ2VyfSAgU2NoZW1hIHZlcnNpb25cbiAqIEBwYXJhbSBvbnVwZ3JhZGVuZWVkZWQge0Z1bmN0aW9ufSBUaGUgY2FsbGJhY2sgdG8gZXhlY3V0ZSBpZiBzY2hlbWEgaXNcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtaXNzaW5nIG9yIGRpZmZlcmVudC5cbiAqIEByZXR1cm4ge1Byb21pc2U8SURCRGF0YWJhc2U+fVxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gb3BlbihkYm5hbWUsIHsgdmVyc2lvbiwgb251cGdyYWRlbmVlZGVkIH0pIHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICBjb25zdCByZXF1ZXN0ID0gaW5kZXhlZERCLm9wZW4oZGJuYW1lLCB2ZXJzaW9uKTtcbiAgICByZXF1ZXN0Lm9udXBncmFkZW5lZWRlZCA9IGV2ZW50ID0+IHtcbiAgICAgIGNvbnN0IGRiID0gZXZlbnQudGFyZ2V0LnJlc3VsdDtcbiAgICAgIGRiLm9uZXJyb3IgPSBldmVudCA9PiByZWplY3QoZXZlbnQudGFyZ2V0LmVycm9yKTtcbiAgICAgIHJldHVybiBvbnVwZ3JhZGVuZWVkZWQoZXZlbnQpO1xuICAgIH07XG4gICAgcmVxdWVzdC5vbmVycm9yID0gZXZlbnQgPT4ge1xuICAgICAgcmVqZWN0KGV2ZW50LnRhcmdldC5lcnJvcik7XG4gICAgfTtcbiAgICByZXF1ZXN0Lm9uc3VjY2VzcyA9IGV2ZW50ID0+IHtcbiAgICAgIGNvbnN0IGRiID0gZXZlbnQudGFyZ2V0LnJlc3VsdDtcbiAgICAgIHJlc29sdmUoZGIpO1xuICAgIH07XG4gIH0pO1xufVxuXG4vKipcbiAqIEhlbHBlciB0byBydW4gdGhlIHNwZWNpZmllZCBjYWxsYmFjayBpbiBhIHNpbmdsZSB0cmFuc2FjdGlvbiBvbiB0aGVcbiAqIHNwZWNpZmllZCBzdG9yZS5cbiAqIFRoZSBoZWxwZXIgZm9jdXNlcyBvbiB0cmFuc2FjdGlvbiB3cmFwcGluZyBpbnRvIGEgcHJvbWlzZS5cbiAqXG4gKiBAcGFyYW0gZGIgICAgICAgICAgIHtJREJEYXRhYmFzZX0gVGhlIGRhdGFiYXNlIGluc3RhbmNlLlxuICogQHBhcmFtIG5hbWUgICAgICAgICB7U3RyaW5nfSAgICAgIFRoZSBzdG9yZSBuYW1lLlxuICogQHBhcmFtIGNhbGxiYWNrICAgICB7RnVuY3Rpb259ICAgIFRoZSBwaWVjZSBvZiBjb2RlIHRvIGV4ZWN1dGUgaW4gdGhlIHRyYW5zYWN0aW9uLlxuICogQHBhcmFtIG9wdGlvbnMgICAgICB7T2JqZWN0fSAgICAgIE9wdGlvbnMuXG4gKiBAcGFyYW0gb3B0aW9ucy5tb2RlIHtTdHJpbmd9ICAgICAgVHJhbnNhY3Rpb24gbW9kZSAoZGVmYXVsdDogcmVhZCkuXG4gKiBAcmV0dXJuIHtQcm9taXNlfSBhbnkgdmFsdWUgcmV0dXJuZWQgYnkgdGhlIGNhbGxiYWNrLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZXhlY3V0ZShkYiwgbmFtZSwgY2FsbGJhY2ssIG9wdGlvbnMgPSB7fSkge1xuICBjb25zdCB7IG1vZGUgfSA9IG9wdGlvbnM7XG4gIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgLy8gT24gU2FmYXJpLCBjYWxsaW5nIElEQkRhdGFiYXNlLnRyYW5zYWN0aW9uIHdpdGggbW9kZSA9PSB1bmRlZmluZWQgcmFpc2VzXG4gICAgLy8gYSBUeXBlRXJyb3IuXG4gICAgY29uc3QgdHJhbnNhY3Rpb24gPSBtb2RlXG4gICAgICA/IGRiLnRyYW5zYWN0aW9uKFtuYW1lXSwgbW9kZSlcbiAgICAgIDogZGIudHJhbnNhY3Rpb24oW25hbWVdKTtcbiAgICBjb25zdCBzdG9yZSA9IHRyYW5zYWN0aW9uLm9iamVjdFN0b3JlKG5hbWUpO1xuXG4gICAgLy8gTGV0IHRoZSBjYWxsYmFjayBhYm9ydCB0aGlzIHRyYW5zYWN0aW9uLlxuICAgIGNvbnN0IGFib3J0ID0gZSA9PiB7XG4gICAgICB0cmFuc2FjdGlvbi5hYm9ydCgpO1xuICAgICAgcmVqZWN0KGUpO1xuICAgIH07XG4gICAgLy8gRXhlY3V0ZSB0aGUgc3BlY2lmaWVkIGNhbGxiYWNrICoqc3luY2hyb25vdXNseSoqLlxuICAgIGxldCByZXN1bHQ7XG4gICAgdHJ5IHtcbiAgICAgIHJlc3VsdCA9IGNhbGxiYWNrKHN0b3JlLCBhYm9ydCk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgYWJvcnQoZSk7XG4gICAgfVxuICAgIHRyYW5zYWN0aW9uLm9uZXJyb3IgPSBldmVudCA9PiByZWplY3QoZXZlbnQudGFyZ2V0LmVycm9yKTtcbiAgICB0cmFuc2FjdGlvbi5vbmNvbXBsZXRlID0gZXZlbnQgPT4gcmVzb2x2ZShyZXN1bHQpO1xuICB9KTtcbn1cblxuLyoqXG4gKiBIZWxwZXIgdG8gd3JhcCB0aGUgZGVsZXRpb24gb2YgYW4gSW5kZXhlZERCIGRhdGFiYXNlIGludG8gYSBwcm9taXNlLlxuICpcbiAqIEBwYXJhbSBkYk5hbWUge1N0cmluZ30gdGhlIGRhdGFiYXNlIHRvIGRlbGV0ZVxuICogQHJldHVybiB7UHJvbWlzZX1cbiAqL1xuYXN5bmMgZnVuY3Rpb24gZGVsZXRlRGF0YWJhc2UoZGJOYW1lKSB7XG4gIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgY29uc3QgcmVxdWVzdCA9IGluZGV4ZWREQi5kZWxldGVEYXRhYmFzZShkYk5hbWUpO1xuICAgIHJlcXVlc3Qub25zdWNjZXNzID0gZXZlbnQgPT4gcmVzb2x2ZShldmVudC50YXJnZXQpO1xuICAgIHJlcXVlc3Qub25lcnJvciA9IGV2ZW50ID0+IHJlamVjdChldmVudC50YXJnZXQuZXJyb3IpO1xuICB9KTtcbn1cblxuLyoqXG4gKiBJREIgY3Vyc29yIGhhbmRsZXJzLlxuICogQHR5cGUge09iamVjdH1cbiAqL1xuY29uc3QgY3Vyc29ySGFuZGxlcnMgPSB7XG4gIGFsbChmaWx0ZXJzLCBkb25lKSB7XG4gICAgY29uc3QgcmVzdWx0cyA9IFtdO1xuICAgIHJldHVybiBldmVudCA9PiB7XG4gICAgICBjb25zdCBjdXJzb3IgPSBldmVudC50YXJnZXQucmVzdWx0O1xuICAgICAgaWYgKGN1cnNvcikge1xuICAgICAgICBjb25zdCB7IHZhbHVlIH0gPSBjdXJzb3I7XG4gICAgICAgIGlmIChmaWx0ZXJPYmplY3QoZmlsdGVycywgdmFsdWUpKSB7XG4gICAgICAgICAgcmVzdWx0cy5wdXNoKHZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgICBjdXJzb3IuY29udGludWUoKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGRvbmUocmVzdWx0cyk7XG4gICAgICB9XG4gICAgfTtcbiAgfSxcblxuICBpbih2YWx1ZXMsIGZpbHRlcnMsIGRvbmUpIHtcbiAgICBjb25zdCByZXN1bHRzID0gW107XG4gICAgcmV0dXJuIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgICBjb25zdCBjdXJzb3IgPSBldmVudC50YXJnZXQucmVzdWx0O1xuICAgICAgaWYgKCFjdXJzb3IpIHtcbiAgICAgICAgZG9uZShyZXN1bHRzKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgY29uc3QgeyBrZXksIHZhbHVlIH0gPSBjdXJzb3I7XG4gICAgICAvLyBga2V5YCBjYW4gYmUgYW4gYXJyYXkgb2YgdHdvIHZhbHVlcyAoc2VlIGBrZXlQYXRoYCBpbiBpbmRpY2VzIGRlZmluaXRpb25zKS5cbiAgICAgIGxldCBpID0gMDtcbiAgICAgIC8vIGB2YWx1ZXNgIGNhbiBiZSBhbiBhcnJheSBvZiBhcnJheXMgaWYgd2UgZmlsdGVyIHVzaW5nIGFuIGluZGV4IHdob3NlIGtleSBwYXRoXG4gICAgICAvLyBpcyBhbiBhcnJheSAoZWcuIGBjdXJzb3JIYW5kbGVycy5pbihbW1wiYmlkL2NpZFwiLCA0Ml0sIFtcImJpZC9jaWRcIiwgNDNdXSwgLi4uKWApXG4gICAgICB3aGlsZSAoa2V5ID4gdmFsdWVzW2ldKSB7XG4gICAgICAgIC8vIFRoZSBjdXJzb3IgaGFzIHBhc3NlZCBiZXlvbmQgdGhpcyBrZXkuIENoZWNrIG5leHQuXG4gICAgICAgICsraTtcbiAgICAgICAgaWYgKGkgPT09IHZhbHVlcy5sZW5ndGgpIHtcbiAgICAgICAgICBkb25lKHJlc3VsdHMpOyAvLyBUaGVyZSBpcyBubyBuZXh0LiBTdG9wIHNlYXJjaGluZy5cbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGNvbnN0IGlzRXF1YWwgPSBBcnJheS5pc0FycmF5KGtleSlcbiAgICAgICAgPyBhcnJheUVxdWFsKGtleSwgdmFsdWVzW2ldKVxuICAgICAgICA6IGtleSA9PT0gdmFsdWVzW2ldO1xuICAgICAgaWYgKGlzRXF1YWwpIHtcbiAgICAgICAgaWYgKGZpbHRlck9iamVjdChmaWx0ZXJzLCB2YWx1ZSkpIHtcbiAgICAgICAgICByZXN1bHRzLnB1c2godmFsdWUpO1xuICAgICAgICB9XG4gICAgICAgIGN1cnNvci5jb250aW51ZSgpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY3Vyc29yLmNvbnRpbnVlKHZhbHVlc1tpXSk7XG4gICAgICB9XG4gICAgfTtcbiAgfSxcbn07XG5cbi8qKlxuICogQ3JlYXRlcyBhbiBJREIgcmVxdWVzdCBhbmQgYXR0YWNoIGl0IHRoZSBhcHByb3ByaWF0ZSBjdXJzb3IgZXZlbnQgaGFuZGxlciB0b1xuICogcGVyZm9ybSBhIGxpc3QgcXVlcnkuXG4gKlxuICogTXVsdGlwbGUgbWF0Y2hpbmcgdmFsdWVzIGFyZSBoYW5kbGVkIGJ5IHBhc3NpbmcgYW4gYXJyYXkuXG4gKlxuICogQHBhcmFtICB7U3RyaW5nfSAgICAgICAgICAgY2lkICAgICAgICBUaGUgY29sbGVjdGlvbiBpZCAoaWUuIGB7YmlkfS97Y2lkfWApXG4gKiBAcGFyYW0gIHtJREJTdG9yZX0gICAgICAgICBzdG9yZSAgICAgIFRoZSBJREIgc3RvcmUuXG4gKiBAcGFyYW0gIHtPYmplY3R9ICAgICAgICAgICBmaWx0ZXJzICAgIEZpbHRlciB0aGUgcmVjb3JkcyBieSBmaWVsZC5cbiAqIEBwYXJhbSAge0Z1bmN0aW9ufSAgICAgICAgIGRvbmUgICAgICAgVGhlIG9wZXJhdGlvbiBjb21wbGV0aW9uIGhhbmRsZXIuXG4gKiBAcmV0dXJuIHtJREJSZXF1ZXN0fVxuICovXG5mdW5jdGlvbiBjcmVhdGVMaXN0UmVxdWVzdChjaWQsIHN0b3JlLCBmaWx0ZXJzLCBkb25lKSB7XG4gIGNvbnN0IGZpbHRlckZpZWxkcyA9IE9iamVjdC5rZXlzKGZpbHRlcnMpO1xuXG4gIC8vIElmIG5vIGZpbHRlcnMsIGdldCBhbGwgcmVzdWx0cyBpbiBvbmUgYnVsay5cbiAgaWYgKGZpbHRlckZpZWxkcy5sZW5ndGggPT0gMCkge1xuICAgIGNvbnN0IHJlcXVlc3QgPSBzdG9yZS5pbmRleChcImNpZFwiKS5nZXRBbGwoSURCS2V5UmFuZ2Uub25seShjaWQpKTtcbiAgICByZXF1ZXN0Lm9uc3VjY2VzcyA9IGV2ZW50ID0+IGRvbmUoZXZlbnQudGFyZ2V0LnJlc3VsdCk7XG4gICAgcmV0dXJuIHJlcXVlc3Q7XG4gIH1cblxuICAvLyBJbnRyb3NwZWN0IGZpbHRlcnMgYW5kIGNoZWNrIGlmIHRoZXkgbGV2ZXJhZ2UgYW4gaW5kZXhlZCBmaWVsZC5cbiAgY29uc3QgaW5kZXhGaWVsZCA9IGZpbHRlckZpZWxkcy5maW5kKGZpZWxkID0+IHtcbiAgICByZXR1cm4gSU5ERVhFRF9GSUVMRFMuaW5jbHVkZXMoZmllbGQpO1xuICB9KTtcblxuICBpZiAoIWluZGV4RmllbGQpIHtcbiAgICAvLyBJdGVyYXRlIG9uIGFsbCByZWNvcmRzIGZvciB0aGlzIGNvbGxlY3Rpb24gKGllLiBjaWQpXG4gICAgY29uc3QgaXNTdWJRdWVyeSA9IE9iamVjdC5rZXlzKGZpbHRlcnMpLnNvbWUoa2V5ID0+IGtleS5pbmNsdWRlcyhcIi5cIikpOyAvLyAoaWUuIGZpbHRlcnM6IHtcImFydGljbGUudGl0bGVcIjogXCJoZWxsb1wifSlcbiAgICBpZiAoaXNTdWJRdWVyeSkge1xuICAgICAgY29uc3QgbmV3RmlsdGVyID0gdHJhbnNmb3JtU3ViT2JqZWN0RmlsdGVycyhmaWx0ZXJzKTtcbiAgICAgIGNvbnN0IHJlcXVlc3QgPSBzdG9yZS5pbmRleChcImNpZFwiKS5vcGVuQ3Vyc29yKElEQktleVJhbmdlLm9ubHkoY2lkKSk7XG4gICAgICByZXF1ZXN0Lm9uc3VjY2VzcyA9IGN1cnNvckhhbmRsZXJzLmFsbChuZXdGaWx0ZXIsIGRvbmUpO1xuICAgICAgcmV0dXJuIHJlcXVlc3Q7XG4gICAgfVxuXG4gICAgY29uc3QgcmVxdWVzdCA9IHN0b3JlLmluZGV4KFwiY2lkXCIpLm9wZW5DdXJzb3IoSURCS2V5UmFuZ2Uub25seShjaWQpKTtcbiAgICByZXF1ZXN0Lm9uc3VjY2VzcyA9IGN1cnNvckhhbmRsZXJzLmFsbChmaWx0ZXJzLCBkb25lKTtcbiAgICByZXR1cm4gcmVxdWVzdDtcbiAgfVxuICAvLyBJZiBgaW5kZXhGaWVsZGAgd2FzIHVzZWQgYWxyZWFkeSwgZG9uJ3QgZmlsdGVyIGFnYWluLlxuICBjb25zdCByZW1haW5pbmdGaWx0ZXJzID0gb21pdEtleXMoZmlsdGVycywgW2luZGV4RmllbGRdKTtcblxuICAvLyB2YWx1ZSBzcGVjaWZpZWQgaW4gdGhlIGZpbHRlciAoZWcuIGBmaWx0ZXJzOiB7IF9zdGF0dXM6IFtcImNyZWF0ZWRcIiwgXCJ1cGRhdGVkXCJdIH1gKVxuICBjb25zdCB2YWx1ZSA9IGZpbHRlcnNbaW5kZXhGaWVsZF07XG4gIC8vIEZvciB0aGUgXCJpZFwiIGZpZWxkLCB1c2UgdGhlIHByaW1hcnkga2V5LlxuICBjb25zdCBpbmRleFN0b3JlID0gaW5kZXhGaWVsZCA9PSBcImlkXCIgPyBzdG9yZSA6IHN0b3JlLmluZGV4KGluZGV4RmllbGQpO1xuXG4gIC8vIFdIRVJFIElOIGVxdWl2YWxlbnQgY2xhdXNlXG4gIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgIGlmICh2YWx1ZS5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiBkb25lKFtdKTtcbiAgICB9XG4gICAgY29uc3QgdmFsdWVzID0gdmFsdWUubWFwKGkgPT4gW2NpZCwgaV0pLnNvcnQoKTtcbiAgICBjb25zdCByYW5nZSA9IElEQktleVJhbmdlLmJvdW5kKHZhbHVlc1swXSwgdmFsdWVzW3ZhbHVlcy5sZW5ndGggLSAxXSk7XG4gICAgY29uc3QgcmVxdWVzdCA9IGluZGV4U3RvcmUub3BlbkN1cnNvcihyYW5nZSk7XG4gICAgcmVxdWVzdC5vbnN1Y2Nlc3MgPSBjdXJzb3JIYW5kbGVycy5pbih2YWx1ZXMsIHJlbWFpbmluZ0ZpbHRlcnMsIGRvbmUpO1xuICAgIHJldHVybiByZXF1ZXN0O1xuICB9XG5cbiAgLy8gSWYgbm8gZmlsdGVycyBvbiBjdXN0b20gYXR0cmlidXRlLCBnZXQgYWxsIHJlc3VsdHMgaW4gb25lIGJ1bGsuXG4gIGlmIChyZW1haW5pbmdGaWx0ZXJzLmxlbmd0aCA9PSAwKSB7XG4gICAgY29uc3QgcmVxdWVzdCA9IGluZGV4U3RvcmUuZ2V0QWxsKElEQktleVJhbmdlLm9ubHkoW2NpZCwgdmFsdWVdKSk7XG4gICAgcmVxdWVzdC5vbnN1Y2Nlc3MgPSBldmVudCA9PiBkb25lKGV2ZW50LnRhcmdldC5yZXN1bHQpO1xuICAgIHJldHVybiByZXF1ZXN0O1xuICB9XG5cbiAgLy8gV0hFUkUgZmllbGQgPSB2YWx1ZSBjbGF1c2VcbiAgY29uc3QgcmVxdWVzdCA9IGluZGV4U3RvcmUub3BlbkN1cnNvcihJREJLZXlSYW5nZS5vbmx5KFtjaWQsIHZhbHVlXSkpO1xuICByZXF1ZXN0Lm9uc3VjY2VzcyA9IGN1cnNvckhhbmRsZXJzLmFsbChyZW1haW5pbmdGaWx0ZXJzLCBkb25lKTtcbiAgcmV0dXJuIHJlcXVlc3Q7XG59XG5cbi8qKlxuICogSW5kZXhlZERCIGFkYXB0ZXIuXG4gKlxuICogVGhpcyBhZGFwdGVyIGRvZXNuJ3Qgc3VwcG9ydCBhbnkgb3B0aW9ucy5cbiAqL1xuZXhwb3J0IGRlZmF1bHQgY2xhc3MgSURCIGV4dGVuZHMgQmFzZUFkYXB0ZXIge1xuICAvKipcbiAgICogQ29uc3RydWN0b3IuXG4gICAqXG4gICAqIEBwYXJhbSAge1N0cmluZ30gY2lkICBUaGUga2V5IGJhc2UgZm9yIHRoaXMgY29sbGVjdGlvbiAoZWcuIGBiaWQvY2lkYClcbiAgICogQHBhcmFtICB7T2JqZWN0fSBvcHRpb25zXG4gICAqIEBwYXJhbSAge1N0cmluZ30gb3B0aW9ucy5kYk5hbWUgICAgICAgICBUaGUgSW5kZXhlZERCIG5hbWUgKGRlZmF1bHQ6IGBcIktpbnRvREJcImApXG4gICAqIEBwYXJhbSAge1N0cmluZ30gb3B0aW9ucy5taWdyYXRlT2xkRGF0YSBXaGV0aGVyIG9sZCBkYXRhYmFzZSBkYXRhIHNob3VsZCBiZSBtaWdyYXRlZCAoZGVmYXVsdDogYGZhbHNlYClcbiAgICovXG4gIGNvbnN0cnVjdG9yKGNpZCwgb3B0aW9ucyA9IHt9KSB7XG4gICAgc3VwZXIoKTtcblxuICAgIHRoaXMuY2lkID0gY2lkO1xuICAgIHRoaXMuZGJOYW1lID0gb3B0aW9ucy5kYk5hbWUgfHwgXCJLaW50b0RCXCI7XG5cbiAgICB0aGlzLl9vcHRpb25zID0gb3B0aW9ucztcbiAgICB0aGlzLl9kYiA9IG51bGw7XG4gIH1cblxuICBfaGFuZGxlRXJyb3IobWV0aG9kLCBlcnIpIHtcbiAgICBjb25zdCBlcnJvciA9IG5ldyBFcnJvcihgSW5kZXhlZERCICR7bWV0aG9kfSgpICR7ZXJyLm1lc3NhZ2V9YCk7XG4gICAgZXJyb3Iuc3RhY2sgPSBlcnIuc3RhY2s7XG4gICAgdGhyb3cgZXJyb3I7XG4gIH1cblxuICAvKipcbiAgICogRW5zdXJlcyBhIGNvbm5lY3Rpb24gdG8gdGhlIEluZGV4ZWREQiBkYXRhYmFzZSBoYXMgYmVlbiBvcGVuZWQuXG4gICAqXG4gICAqIEBvdmVycmlkZVxuICAgKiBAcmV0dXJuIHtQcm9taXNlfVxuICAgKi9cbiAgYXN5bmMgb3BlbigpIHtcbiAgICBpZiAodGhpcy5fZGIpIHtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8vIEluIHByZXZpb3VzIHZlcnNpb25zLCB3ZSB1c2VkIHRvIGhhdmUgYSBkYXRhYmFzZSB3aXRoIG5hbWUgYCR7YmlkfS8ke2NpZH1gLlxuICAgIC8vIENoZWNrIGlmIGl0IGV4aXN0cywgYW5kIG1pZ3JhdGUgZGF0YSBvbmNlIG5ldyBzY2hlbWEgaXMgaW4gcGxhY2UuXG4gICAgLy8gTm90ZTogdGhlIGJ1aWx0LWluIG1pZ3JhdGlvbnMgZnJvbSBJbmRleGVkREIgY2FuIG9ubHkgYmUgdXNlZCBpZiB0aGVcbiAgICAvLyBkYXRhYmFzZSBuYW1lIGRvZXMgbm90IGNoYW5nZS5cbiAgICBjb25zdCBkYXRhVG9NaWdyYXRlID0gdGhpcy5fb3B0aW9ucy5taWdyYXRlT2xkRGF0YVxuICAgICAgPyBhd2FpdCBtaWdyYXRpb25SZXF1aXJlZCh0aGlzLmNpZClcbiAgICAgIDogbnVsbDtcblxuICAgIHRoaXMuX2RiID0gYXdhaXQgb3Blbih0aGlzLmRiTmFtZSwge1xuICAgICAgdmVyc2lvbjogMixcbiAgICAgIG9udXBncmFkZW5lZWRlZDogZXZlbnQgPT4ge1xuICAgICAgICBjb25zdCBkYiA9IGV2ZW50LnRhcmdldC5yZXN1bHQ7XG5cbiAgICAgICAgaWYgKGV2ZW50Lm9sZFZlcnNpb24gPCAxKSB7XG4gICAgICAgICAgLy8gUmVjb3JkcyBzdG9yZVxuICAgICAgICAgIGNvbnN0IHJlY29yZHNTdG9yZSA9IGRiLmNyZWF0ZU9iamVjdFN0b3JlKFwicmVjb3Jkc1wiLCB7XG4gICAgICAgICAgICBrZXlQYXRoOiBbXCJfY2lkXCIsIFwiaWRcIl0sXG4gICAgICAgICAgfSk7XG4gICAgICAgICAgLy8gQW4gaW5kZXggdG8gb2J0YWluIGFsbCB0aGUgcmVjb3JkcyBpbiBhIGNvbGxlY3Rpb24uXG4gICAgICAgICAgcmVjb3Jkc1N0b3JlLmNyZWF0ZUluZGV4KFwiY2lkXCIsIFwiX2NpZFwiKTtcbiAgICAgICAgICAvLyBIZXJlIHdlIGNyZWF0ZSBpbmRpY2VzIGZvciBldmVyeSBrbm93biBmaWVsZCBpbiByZWNvcmRzIGJ5IGNvbGxlY3Rpb24uXG4gICAgICAgICAgLy8gTG9jYWwgcmVjb3JkIHN0YXR1cyAoXCJzeW5jZWRcIiwgXCJjcmVhdGVkXCIsIFwidXBkYXRlZFwiLCBcImRlbGV0ZWRcIilcbiAgICAgICAgICByZWNvcmRzU3RvcmUuY3JlYXRlSW5kZXgoXCJfc3RhdHVzXCIsIFtcIl9jaWRcIiwgXCJfc3RhdHVzXCJdKTtcbiAgICAgICAgICAvLyBMYXN0IG1vZGlmaWVkIGZpZWxkXG4gICAgICAgICAgcmVjb3Jkc1N0b3JlLmNyZWF0ZUluZGV4KFwibGFzdF9tb2RpZmllZFwiLCBbXCJfY2lkXCIsIFwibGFzdF9tb2RpZmllZFwiXSk7XG4gICAgICAgICAgLy8gVGltZXN0YW1wcyBzdG9yZVxuICAgICAgICAgIGRiLmNyZWF0ZU9iamVjdFN0b3JlKFwidGltZXN0YW1wc1wiLCB7XG4gICAgICAgICAgICBrZXlQYXRoOiBcImNpZFwiLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGV2ZW50Lm9sZFZlcnNpb24gPCAyKSB7XG4gICAgICAgICAgLy8gQ29sbGVjdGlvbnMgc3RvcmVcbiAgICAgICAgICBkYi5jcmVhdGVPYmplY3RTdG9yZShcImNvbGxlY3Rpb25zXCIsIHtcbiAgICAgICAgICAgIGtleVBhdGg6IFwiY2lkXCIsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgfSk7XG5cbiAgICBpZiAoZGF0YVRvTWlncmF0ZSkge1xuICAgICAgY29uc3QgeyByZWNvcmRzLCB0aW1lc3RhbXAgfSA9IGRhdGFUb01pZ3JhdGU7XG4gICAgICBhd2FpdCB0aGlzLmltcG9ydEJ1bGsocmVjb3Jkcyk7XG4gICAgICBhd2FpdCB0aGlzLnNhdmVMYXN0TW9kaWZpZWQodGltZXN0YW1wKTtcbiAgICAgIGNvbnNvbGUubG9nKGAke3RoaXMuY2lkfTogZGF0YSB3YXMgbWlncmF0ZWQgc3VjY2Vzc2Z1bGx5LmApO1xuICAgICAgLy8gRGVsZXRlIHRoZSBvbGQgZGF0YWJhc2UuXG4gICAgICBhd2FpdCBkZWxldGVEYXRhYmFzZSh0aGlzLmNpZCk7XG4gICAgICBjb25zb2xlLndhcm4oYCR7dGhpcy5jaWR9OiBvbGQgZGF0YWJhc2Ugd2FzIGRlbGV0ZWQuYCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKipcbiAgICogQ2xvc2VzIGN1cnJlbnQgY29ubmVjdGlvbiB0byB0aGUgZGF0YWJhc2UuXG4gICAqXG4gICAqIEBvdmVycmlkZVxuICAgKiBAcmV0dXJuIHtQcm9taXNlfVxuICAgKi9cbiAgY2xvc2UoKSB7XG4gICAgaWYgKHRoaXMuX2RiKSB7XG4gICAgICB0aGlzLl9kYi5jbG9zZSgpOyAvLyBpbmRleGVkREIuY2xvc2UgaXMgc3luY2hyb25vdXNcbiAgICAgIHRoaXMuX2RiID0gbnVsbDtcbiAgICB9XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgYSB0cmFuc2FjdGlvbiBhbmQgYW4gb2JqZWN0IHN0b3JlIGZvciBhIHN0b3JlIG5hbWUuXG4gICAqXG4gICAqIFRvIGRldGVybWluZSBpZiBhIHRyYW5zYWN0aW9uIGhhcyBjb21wbGV0ZWQgc3VjY2Vzc2Z1bGx5LCB3ZSBzaG91bGQgcmF0aGVyXG4gICAqIGxpc3RlbiB0byB0aGUgdHJhbnNhY3Rpb27igJlzIGNvbXBsZXRlIGV2ZW50IHJhdGhlciB0aGFuIHRoZSBJREJPYmplY3RTdG9yZVxuICAgKiByZXF1ZXN04oCZcyBzdWNjZXNzIGV2ZW50LCBiZWNhdXNlIHRoZSB0cmFuc2FjdGlvbiBtYXkgc3RpbGwgZmFpbCBhZnRlciB0aGVcbiAgICogc3VjY2VzcyBldmVudCBmaXJlcy5cbiAgICpcbiAgICogQHBhcmFtICB7U3RyaW5nfSAgICAgIG5hbWUgIFN0b3JlIG5hbWVcbiAgICogQHBhcmFtICB7RnVuY3Rpb259ICAgIGNhbGxiYWNrIHRvIGV4ZWN1dGVcbiAgICogQHBhcmFtICB7T2JqZWN0fSAgICAgIG9wdGlvbnMgT3B0aW9uc1xuICAgKiBAcGFyYW0gIHtTdHJpbmd9ICAgICAgb3B0aW9ucy5tb2RlICBUcmFuc2FjdGlvbiBtb2RlIChcInJlYWR3cml0ZVwiIG9yIHVuZGVmaW5lZClcbiAgICogQHJldHVybiB7T2JqZWN0fVxuICAgKi9cbiAgYXN5bmMgcHJlcGFyZShuYW1lLCBjYWxsYmFjaywgb3B0aW9ucykge1xuICAgIGF3YWl0IHRoaXMub3BlbigpO1xuICAgIGF3YWl0IGV4ZWN1dGUodGhpcy5fZGIsIG5hbWUsIGNhbGxiYWNrLCBvcHRpb25zKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEZWxldGVzIGV2ZXJ5IHJlY29yZHMgaW4gdGhlIGN1cnJlbnQgY29sbGVjdGlvbi5cbiAgICpcbiAgICogQG92ZXJyaWRlXG4gICAqIEByZXR1cm4ge1Byb21pc2V9XG4gICAqL1xuICBhc3luYyBjbGVhcigpIHtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgdGhpcy5wcmVwYXJlKFxuICAgICAgICBcInJlY29yZHNcIixcbiAgICAgICAgc3RvcmUgPT4ge1xuICAgICAgICAgIGNvbnN0IHJhbmdlID0gSURCS2V5UmFuZ2Uub25seSh0aGlzLmNpZCk7XG4gICAgICAgICAgY29uc3QgcmVxdWVzdCA9IHN0b3JlLmluZGV4KFwiY2lkXCIpLm9wZW5LZXlDdXJzb3IocmFuZ2UpO1xuICAgICAgICAgIHJlcXVlc3Qub25zdWNjZXNzID0gZXZlbnQgPT4ge1xuICAgICAgICAgICAgY29uc3QgY3Vyc29yID0gZXZlbnQudGFyZ2V0LnJlc3VsdDtcbiAgICAgICAgICAgIGlmIChjdXJzb3IpIHtcbiAgICAgICAgICAgICAgc3RvcmUuZGVsZXRlKGN1cnNvci5wcmltYXJ5S2V5KTtcbiAgICAgICAgICAgICAgY3Vyc29yLmNvbnRpbnVlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfTtcbiAgICAgICAgICByZXR1cm4gcmVxdWVzdDtcbiAgICAgICAgfSxcbiAgICAgICAgeyBtb2RlOiBcInJlYWR3cml0ZVwiIH1cbiAgICAgICk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgdGhpcy5faGFuZGxlRXJyb3IoXCJjbGVhclwiLCBlKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogRXhlY3V0ZXMgdGhlIHNldCBvZiBzeW5jaHJvbm91cyBDUlVEIG9wZXJhdGlvbnMgZGVzY3JpYmVkIGluIHRoZSBwcm92aWRlZFxuICAgKiBjYWxsYmFjayB3aXRoaW4gYW4gSW5kZXhlZERCIHRyYW5zYWN0aW9uLCBmb3IgY3VycmVudCBkYiBzdG9yZS5cbiAgICpcbiAgICogVGhlIGNhbGxiYWNrIHdpbGwgYmUgcHJvdmlkZWQgYW4gb2JqZWN0IGV4cG9zaW5nIHRoZSBmb2xsb3dpbmcgc3luY2hyb25vdXNcbiAgICogQ1JVRCBvcGVyYXRpb24gbWV0aG9kczogZ2V0LCBjcmVhdGUsIHVwZGF0ZSwgZGVsZXRlLlxuICAgKlxuICAgKiBJbXBvcnRhbnQgbm90ZTogYmVjYXVzZSBsaW1pdGF0aW9ucyBpbiBJbmRleGVkREIgaW1wbGVtZW50YXRpb25zLCBub1xuICAgKiBhc3luY2hyb25vdXMgY29kZSBzaG91bGQgYmUgcGVyZm9ybWVkIHdpdGhpbiB0aGUgcHJvdmlkZWQgY2FsbGJhY2s7IHRoZVxuICAgKiBwcm9taXNlIHdpbGwgdGhlcmVmb3JlIGJlIHJlamVjdGVkIGlmIHRoZSBjYWxsYmFjayByZXR1cm5zIGEgUHJvbWlzZS5cbiAgICpcbiAgICogT3B0aW9uczpcbiAgICogLSB7QXJyYXl9IHByZWxvYWQ6IFRoZSBsaXN0IG9mIHJlY29yZCBJRHMgdG8gZmV0Y2ggYW5kIG1ha2UgYXZhaWxhYmxlIHRvXG4gICAqICAgdGhlIHRyYW5zYWN0aW9uIG9iamVjdCBnZXQoKSBtZXRob2QgKGRlZmF1bHQ6IFtdKVxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKiBjb25zdCBkYiA9IG5ldyBJREIoXCJleGFtcGxlXCIpO1xuICAgKiBjb25zdCByZXN1bHQgPSBhd2FpdCBkYi5leGVjdXRlKHRyYW5zYWN0aW9uID0+IHtcbiAgICogICB0cmFuc2FjdGlvbi5jcmVhdGUoe2lkOiAxLCB0aXRsZTogXCJmb29cIn0pO1xuICAgKiAgIHRyYW5zYWN0aW9uLnVwZGF0ZSh7aWQ6IDIsIHRpdGxlOiBcImJhclwifSk7XG4gICAqICAgdHJhbnNhY3Rpb24uZGVsZXRlKDMpO1xuICAgKiAgIHJldHVybiBcImZvb1wiO1xuICAgKiB9KTtcbiAgICpcbiAgICogQG92ZXJyaWRlXG4gICAqIEBwYXJhbSAge0Z1bmN0aW9ufSBjYWxsYmFjayBUaGUgb3BlcmF0aW9uIGRlc2NyaXB0aW9uIGNhbGxiYWNrLlxuICAgKiBAcGFyYW0gIHtPYmplY3R9ICAgb3B0aW9ucyAgVGhlIG9wdGlvbnMgb2JqZWN0LlxuICAgKiBAcmV0dXJuIHtQcm9taXNlfVxuICAgKi9cbiAgYXN5bmMgZXhlY3V0ZShjYWxsYmFjaywgb3B0aW9ucyA9IHsgcHJlbG9hZDogW10gfSkge1xuICAgIC8vIFRyYW5zYWN0aW9ucyBpbiBJbmRleGVkREIgYXJlIGF1dG9jb21taXRlZCB3aGVuIGEgY2FsbGJhY2sgZG9lcyBub3RcbiAgICAvLyBwZXJmb3JtIGFueSBhZGRpdGlvbmFsIG9wZXJhdGlvbi5cbiAgICAvLyBUaGUgd2F5IFByb21pc2VzIGFyZSBpbXBsZW1lbnRlZCBpbiBGaXJlZm94IChzZWUgaHR0cHM6Ly9idWd6aWxsYS5tb3ppbGxhLm9yZy9zaG93X2J1Zy5jZ2k/aWQ9MTE5MzM5NClcbiAgICAvLyBwcmV2ZW50cyB1c2luZyB3aXRoaW4gYW4gb3BlbmVkIHRyYW5zYWN0aW9uLlxuICAgIC8vIFRvIGF2b2lkIG1hbmFnaW5nIGFzeW5jaHJvbm9jaXR5IGluIHRoZSBzcGVjaWZpZWQgYGNhbGxiYWNrYCwgd2UgcHJlbG9hZFxuICAgIC8vIGEgbGlzdCBvZiByZWNvcmQgaW4gb3JkZXIgdG8gZXhlY3V0ZSB0aGUgYGNhbGxiYWNrYCBzeW5jaHJvbm91c2x5LlxuICAgIC8vIFNlZSBhbHNvOlxuICAgIC8vIC0gaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL2EvMjgzODg4MDUvMzMwOTExXG4gICAgLy8gLSBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vYS8xMDQwNTE5NlxuICAgIC8vIC0gaHR0cHM6Ly9qYWtlYXJjaGliYWxkLmNvbS8yMDE1L3Rhc2tzLW1pY3JvdGFza3MtcXVldWVzLWFuZC1zY2hlZHVsZXMvXG4gICAgbGV0IHJlc3VsdDtcbiAgICBhd2FpdCB0aGlzLnByZXBhcmUoXG4gICAgICBcInJlY29yZHNcIixcbiAgICAgIChzdG9yZSwgYWJvcnQpID0+IHtcbiAgICAgICAgY29uc3QgcnVuQ2FsbGJhY2sgPSAocHJlbG9hZGVkID0gW10pID0+IHtcbiAgICAgICAgICAvLyBFeHBvc2UgYSBjb25zaXN0ZW50IEFQSSBmb3IgZXZlcnkgYWRhcHRlciBpbnN0ZWFkIG9mIHJhdyBzdG9yZSBtZXRob2RzLlxuICAgICAgICAgIGNvbnN0IHByb3h5ID0gdHJhbnNhY3Rpb25Qcm94eSh0aGlzLCBzdG9yZSwgcHJlbG9hZGVkKTtcbiAgICAgICAgICAvLyBUaGUgY2FsbGJhY2sgaXMgZXhlY3V0ZWQgc3luY2hyb25vdXNseSB3aXRoaW4gdGhlIHNhbWUgdHJhbnNhY3Rpb24uXG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNvbnN0IHJldHVybmVkID0gY2FsbGJhY2socHJveHkpO1xuICAgICAgICAgICAgaWYgKHJldHVybmVkIGluc3RhbmNlb2YgUHJvbWlzZSkge1xuICAgICAgICAgICAgICAvLyBYWFg6IGludmVzdGlnYXRlIGhvdyB0byBwcm92aWRlIGRvY3VtZW50YXRpb24gZGV0YWlscyBpbiBlcnJvci5cbiAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgICAgICAgIFwiZXhlY3V0ZSgpIGNhbGxiYWNrIHNob3VsZCBub3QgcmV0dXJuIGEgUHJvbWlzZS5cIlxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gQnJpbmcgdG8gc2NvcGUgdGhhdCB3aWxsIGJlIHJldHVybmVkIChvbmNlIHByb21pc2UgYXdhaXRlZCkuXG4gICAgICAgICAgICByZXN1bHQgPSByZXR1cm5lZDtcbiAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAvLyBUaGUgY2FsbGJhY2sgaGFzIHRocm93biBhbiBlcnJvciBleHBsaWNpdGx5LiBBYm9ydCB0cmFuc2FjdGlvbiBjbGVhbmx5LlxuICAgICAgICAgICAgYWJvcnQoZSk7XG4gICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICAgIC8vIE5vIG9wdGlvbiB0byBwcmVsb2FkIHJlY29yZHMsIGdvIHN0cmFpZ2h0IHRvIGBjYWxsYmFja2AuXG4gICAgICAgIGlmICghb3B0aW9ucy5wcmVsb2FkLmxlbmd0aCkge1xuICAgICAgICAgIHJldHVybiBydW5DYWxsYmFjaygpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gUHJlbG9hZCBzcGVjaWZpZWQgcmVjb3JkcyB1c2luZyBhIGxpc3QgcmVxdWVzdC5cbiAgICAgICAgY29uc3QgZmlsdGVycyA9IHsgaWQ6IG9wdGlvbnMucHJlbG9hZCB9O1xuICAgICAgICBjcmVhdGVMaXN0UmVxdWVzdCh0aGlzLmNpZCwgc3RvcmUsIGZpbHRlcnMsIHJlY29yZHMgPT4ge1xuICAgICAgICAgIC8vIFN0b3JlIG9idGFpbmVkIHJlY29yZHMgYnkgaWQuXG4gICAgICAgICAgY29uc3QgcHJlbG9hZGVkID0ge307XG4gICAgICAgICAgZm9yIChjb25zdCByZWNvcmQgb2YgcmVjb3Jkcykge1xuICAgICAgICAgICAgZGVsZXRlIHJlY29yZFtcIl9jaWRcIl07XG4gICAgICAgICAgICBwcmVsb2FkZWRbcmVjb3JkLmlkXSA9IHJlY29yZDtcbiAgICAgICAgICB9XG4gICAgICAgICAgcnVuQ2FsbGJhY2socHJlbG9hZGVkKTtcbiAgICAgICAgfSk7XG4gICAgICB9LFxuICAgICAgeyBtb2RlOiBcInJlYWR3cml0ZVwiIH1cbiAgICApO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICAvKipcbiAgICogUmV0cmlldmUgYSByZWNvcmQgYnkgaXRzIHByaW1hcnkga2V5IGZyb20gdGhlIEluZGV4ZWREQiBkYXRhYmFzZS5cbiAgICpcbiAgICogQG92ZXJyaWRlXG4gICAqIEBwYXJhbSAge1N0cmluZ30gaWQgVGhlIHJlY29yZCBpZC5cbiAgICogQHJldHVybiB7UHJvbWlzZX1cbiAgICovXG4gIGFzeW5jIGdldChpZCkge1xuICAgIHRyeSB7XG4gICAgICBsZXQgcmVjb3JkO1xuICAgICAgYXdhaXQgdGhpcy5wcmVwYXJlKFwicmVjb3Jkc1wiLCBzdG9yZSA9PiB7XG4gICAgICAgIHN0b3JlLmdldChbdGhpcy5jaWQsIGlkXSkub25zdWNjZXNzID0gZSA9PiAocmVjb3JkID0gZS50YXJnZXQucmVzdWx0KTtcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIHJlY29yZDtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICB0aGlzLl9oYW5kbGVFcnJvcihcImdldFwiLCBlKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogTGlzdHMgYWxsIHJlY29yZHMgZnJvbSB0aGUgSW5kZXhlZERCIGRhdGFiYXNlLlxuICAgKlxuICAgKiBAb3ZlcnJpZGVcbiAgICogQHBhcmFtICB7T2JqZWN0fSBwYXJhbXMgIFRoZSBmaWx0ZXJzIGFuZCBvcmRlciB0byBhcHBseSB0byB0aGUgcmVzdWx0cy5cbiAgICogQHJldHVybiB7UHJvbWlzZX1cbiAgICovXG4gIGFzeW5jIGxpc3QocGFyYW1zID0geyBmaWx0ZXJzOiB7fSB9KSB7XG4gICAgY29uc3QgeyBmaWx0ZXJzIH0gPSBwYXJhbXM7XG4gICAgdHJ5IHtcbiAgICAgIGxldCByZXN1bHRzID0gW107XG4gICAgICBhd2FpdCB0aGlzLnByZXBhcmUoXCJyZWNvcmRzXCIsIHN0b3JlID0+IHtcbiAgICAgICAgY3JlYXRlTGlzdFJlcXVlc3QodGhpcy5jaWQsIHN0b3JlLCBmaWx0ZXJzLCBfcmVzdWx0cyA9PiB7XG4gICAgICAgICAgLy8gd2UgaGF2ZSByZWNlaXZlZCBhbGwgcmVxdWVzdGVkIHJlY29yZHMgdGhhdCBtYXRjaCB0aGUgZmlsdGVycyxcbiAgICAgICAgICAvLyB3ZSBub3cgcGFyayB0aGVtIHdpdGhpbiBjdXJyZW50IHNjb3BlIGFuZCBoaWRlIHRoZSBgX2NpZGAgYXR0cmlidXRlLlxuICAgICAgICAgIGZvciAoY29uc3QgcmVzdWx0IG9mIF9yZXN1bHRzKSB7XG4gICAgICAgICAgICBkZWxldGUgcmVzdWx0W1wiX2NpZFwiXTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmVzdWx0cyA9IF9yZXN1bHRzO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgICAgLy8gVGhlIHJlc3VsdGluZyBsaXN0IG9mIHJlY29yZHMgaXMgc29ydGVkLlxuICAgICAgLy8gWFhYOiB3aXRoIHNvbWUgZWZmb3J0cywgdGhpcyBjb3VsZCBiZSBmdWxseSBpbXBsZW1lbnRlZCB1c2luZyBJREIgQVBJLlxuICAgICAgcmV0dXJuIHBhcmFtcy5vcmRlciA/IHNvcnRPYmplY3RzKHBhcmFtcy5vcmRlciwgcmVzdWx0cykgOiByZXN1bHRzO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHRoaXMuX2hhbmRsZUVycm9yKFwibGlzdFwiLCBlKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogU3RvcmUgdGhlIGxhc3RNb2RpZmllZCB2YWx1ZSBpbnRvIG1ldGFkYXRhIHN0b3JlLlxuICAgKlxuICAgKiBAb3ZlcnJpZGVcbiAgICogQHBhcmFtICB7TnVtYmVyfSAgbGFzdE1vZGlmaWVkXG4gICAqIEByZXR1cm4ge1Byb21pc2V9XG4gICAqL1xuICBhc3luYyBzYXZlTGFzdE1vZGlmaWVkKGxhc3RNb2RpZmllZCkge1xuICAgIGNvbnN0IHZhbHVlID0gcGFyc2VJbnQobGFzdE1vZGlmaWVkLCAxMCkgfHwgbnVsbDtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgdGhpcy5wcmVwYXJlKFxuICAgICAgICBcInRpbWVzdGFtcHNcIixcbiAgICAgICAgc3RvcmUgPT4gc3RvcmUucHV0KHsgY2lkOiB0aGlzLmNpZCwgdmFsdWUgfSksXG4gICAgICAgIHsgbW9kZTogXCJyZWFkd3JpdGVcIiB9XG4gICAgICApO1xuICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHRoaXMuX2hhbmRsZUVycm9yKFwic2F2ZUxhc3RNb2RpZmllZFwiLCBlKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUmV0cmlldmUgc2F2ZWQgbGFzdE1vZGlmaWVkIHZhbHVlLlxuICAgKlxuICAgKiBAb3ZlcnJpZGVcbiAgICogQHJldHVybiB7UHJvbWlzZX1cbiAgICovXG4gIGFzeW5jIGdldExhc3RNb2RpZmllZCgpIHtcbiAgICB0cnkge1xuICAgICAgbGV0IGVudHJ5ID0gbnVsbDtcbiAgICAgIGF3YWl0IHRoaXMucHJlcGFyZShcInRpbWVzdGFtcHNcIiwgc3RvcmUgPT4ge1xuICAgICAgICBzdG9yZS5nZXQodGhpcy5jaWQpLm9uc3VjY2VzcyA9IGUgPT4gKGVudHJ5ID0gZS50YXJnZXQucmVzdWx0KTtcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIGVudHJ5ID8gZW50cnkudmFsdWUgOiBudWxsO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHRoaXMuX2hhbmRsZUVycm9yKFwiZ2V0TGFzdE1vZGlmaWVkXCIsIGUpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBMb2FkIGEgZHVtcCBvZiByZWNvcmRzIGV4cG9ydGVkIGZyb20gYSBzZXJ2ZXIuXG4gICAqXG4gICAqIEBkZXByZWNhdGVkIFVzZSB7QGxpbmsgaW1wb3J0QnVsa30gaW5zdGVhZC5cbiAgICogQGFic3RyYWN0XG4gICAqIEBwYXJhbSAge0FycmF5fSByZWNvcmRzIFRoZSByZWNvcmRzIHRvIGxvYWQuXG4gICAqIEByZXR1cm4ge1Byb21pc2V9XG4gICAqL1xuICBhc3luYyBsb2FkRHVtcChyZWNvcmRzKSB7XG4gICAgcmV0dXJuIHRoaXMuaW1wb3J0QnVsayhyZWNvcmRzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBMb2FkIHJlY29yZHMgaW4gYnVsayB0aGF0IHdlcmUgZXhwb3J0ZWQgZnJvbSBhIHNlcnZlci5cbiAgICpcbiAgICogQGFic3RyYWN0XG4gICAqIEBwYXJhbSAge0FycmF5fSByZWNvcmRzIFRoZSByZWNvcmRzIHRvIGxvYWQuXG4gICAqIEByZXR1cm4ge1Byb21pc2V9XG4gICAqL1xuICBhc3luYyBpbXBvcnRCdWxrKHJlY29yZHMpIHtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgdGhpcy5leGVjdXRlKHRyYW5zYWN0aW9uID0+IHtcbiAgICAgICAgLy8gU2luY2UgdGhlIHB1dCBvcGVyYXRpb25zIGFyZSBhc3luY2hyb25vdXMsIHdlIGNoYWluXG4gICAgICAgIC8vIHRoZW0gdG9nZXRoZXIuIFRoZSBsYXN0IG9uZSB3aWxsIGJlIHdhaXRlZCBmb3IgdGhlXG4gICAgICAgIC8vIGB0cmFuc2FjdGlvbi5vbmNvbXBsZXRlYCBjYWxsYmFjay4gKHNlZSAjZXhlY3V0ZSgpKVxuICAgICAgICBsZXQgaSA9IDA7XG4gICAgICAgIHB1dE5leHQoKTtcblxuICAgICAgICBmdW5jdGlvbiBwdXROZXh0KCkge1xuICAgICAgICAgIGlmIChpID09IHJlY29yZHMubGVuZ3RoKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuICAgICAgICAgIC8vIE9uIGVycm9yLCBgdHJhbnNhY3Rpb24ub25lcnJvcmAgaXMgY2FsbGVkLlxuICAgICAgICAgIHRyYW5zYWN0aW9uLnVwZGF0ZShyZWNvcmRzW2ldKS5vbnN1Y2Nlc3MgPSBwdXROZXh0O1xuICAgICAgICAgICsraTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICBjb25zdCBwcmV2aW91c0xhc3RNb2RpZmllZCA9IGF3YWl0IHRoaXMuZ2V0TGFzdE1vZGlmaWVkKCk7XG4gICAgICBjb25zdCBsYXN0TW9kaWZpZWQgPSBNYXRoLm1heChcbiAgICAgICAgLi4ucmVjb3Jkcy5tYXAocmVjb3JkID0+IHJlY29yZC5sYXN0X21vZGlmaWVkKVxuICAgICAgKTtcbiAgICAgIGlmIChsYXN0TW9kaWZpZWQgPiBwcmV2aW91c0xhc3RNb2RpZmllZCkge1xuICAgICAgICBhd2FpdCB0aGlzLnNhdmVMYXN0TW9kaWZpZWQobGFzdE1vZGlmaWVkKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZWNvcmRzO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHRoaXMuX2hhbmRsZUVycm9yKFwiaW1wb3J0QnVsa1wiLCBlKTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBzYXZlTWV0YWRhdGEobWV0YWRhdGEpIHtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgdGhpcy5wcmVwYXJlKFxuICAgICAgICBcImNvbGxlY3Rpb25zXCIsXG4gICAgICAgIHN0b3JlID0+IHN0b3JlLnB1dCh7IGNpZDogdGhpcy5jaWQsIG1ldGFkYXRhIH0pLFxuICAgICAgICB7IG1vZGU6IFwicmVhZHdyaXRlXCIgfVxuICAgICAgKTtcbiAgICAgIHJldHVybiBtZXRhZGF0YTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICB0aGlzLl9oYW5kbGVFcnJvcihcInNhdmVNZXRhZGF0YVwiLCBlKTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBnZXRNZXRhZGF0YSgpIHtcbiAgICB0cnkge1xuICAgICAgbGV0IGVudHJ5ID0gbnVsbDtcbiAgICAgIGF3YWl0IHRoaXMucHJlcGFyZShcImNvbGxlY3Rpb25zXCIsIHN0b3JlID0+IHtcbiAgICAgICAgc3RvcmUuZ2V0KHRoaXMuY2lkKS5vbnN1Y2Nlc3MgPSBlID0+IChlbnRyeSA9IGUudGFyZ2V0LnJlc3VsdCk7XG4gICAgICB9KTtcbiAgICAgIHJldHVybiBlbnRyeSA/IGVudHJ5Lm1ldGFkYXRhIDogbnVsbDtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICB0aGlzLl9oYW5kbGVFcnJvcihcImdldE1ldGFkYXRhXCIsIGUpO1xuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIElEQiB0cmFuc2FjdGlvbiBwcm94eS5cbiAqXG4gKiBAcGFyYW0gIHtJREJ9IGFkYXB0ZXIgICAgICAgIFRoZSBjYWxsIElEQiBhZGFwdGVyXG4gKiBAcGFyYW0gIHtJREJTdG9yZX0gc3RvcmUgICAgIFRoZSBJbmRleGVkREIgZGF0YWJhc2Ugc3RvcmUuXG4gKiBAcGFyYW0gIHtBcnJheX0gICAgcHJlbG9hZGVkIFRoZSBsaXN0IG9mIHJlY29yZHMgdG8gbWFrZSBhdmFpbGFibGUgdG9cbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2V0KCkgKGRlZmF1bHQ6IFtdKS5cbiAqIEByZXR1cm4ge09iamVjdH1cbiAqL1xuZnVuY3Rpb24gdHJhbnNhY3Rpb25Qcm94eShhZGFwdGVyLCBzdG9yZSwgcHJlbG9hZGVkID0gW10pIHtcbiAgY29uc3QgX2NpZCA9IGFkYXB0ZXIuY2lkO1xuICByZXR1cm4ge1xuICAgIGNyZWF0ZShyZWNvcmQpIHtcbiAgICAgIHN0b3JlLmFkZCh7IC4uLnJlY29yZCwgX2NpZCB9KTtcbiAgICB9LFxuXG4gICAgdXBkYXRlKHJlY29yZCkge1xuICAgICAgcmV0dXJuIHN0b3JlLnB1dCh7IC4uLnJlY29yZCwgX2NpZCB9KTtcbiAgICB9LFxuXG4gICAgZGVsZXRlKGlkKSB7XG4gICAgICBzdG9yZS5kZWxldGUoW19jaWQsIGlkXSk7XG4gICAgfSxcblxuICAgIGdldChpZCkge1xuICAgICAgcmV0dXJuIHByZWxvYWRlZFtpZF07XG4gICAgfSxcbiAgfTtcbn1cblxuLyoqXG4gKiBVcCB0byB2ZXJzaW9uIDEwLlggb2Yga2ludG8uanMsIGVhY2ggY29sbGVjdGlvbiBoYWQgaXRzIG93biBjb2xsZWN0aW9uLlxuICogVGhlIGRhdGFiYXNlIG5hbWUgd2FzIGAke2JpZH0vJHtjaWR9YCAoZWcuIGBcImJsb2NrbGlzdHMvY2VydGlmaWNhdGVzXCJgKVxuICogYW5kIGNvbnRhaW5lZCBvbmx5IG9uZSBzdG9yZSB3aXRoIHRoZSBzYW1lIG5hbWUuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIG1pZ3JhdGlvblJlcXVpcmVkKGRiTmFtZSkge1xuICBsZXQgZXhpc3RzID0gdHJ1ZTtcbiAgY29uc3QgZGIgPSBhd2FpdCBvcGVuKGRiTmFtZSwge1xuICAgIHZlcnNpb246IDEsXG4gICAgb251cGdyYWRlbmVlZGVkOiBldmVudCA9PiB7XG4gICAgICBleGlzdHMgPSBmYWxzZTtcbiAgICB9LFxuICB9KTtcblxuICAvLyBDaGVjayB0aGF0IHRoZSBEQiB3ZSdyZSBsb29raW5nIGF0IGlzIHJlYWxseSBhIGxlZ2FjeSBvbmUsXG4gIC8vIGFuZCBub3Qgc29tZSByZW1haW5kZXIgb2YgdGhlIG9wZW4oKSBvcGVyYXRpb24gYWJvdmUuXG4gIGV4aXN0cyAmPVxuICAgIGRiLm9iamVjdFN0b3JlTmFtZXMuY29udGFpbnMoXCJfX21ldGFfX1wiKSAmJlxuICAgIGRiLm9iamVjdFN0b3JlTmFtZXMuY29udGFpbnMoZGJOYW1lKTtcblxuICBpZiAoIWV4aXN0cykge1xuICAgIGRiLmNsb3NlKCk7XG4gICAgLy8gVGVzdGluZyB0aGUgZXhpc3RlbmNlIGNyZWF0ZXMgaXQsIHNvIGRlbGV0ZSBpdCA6KVxuICAgIGF3YWl0IGRlbGV0ZURhdGFiYXNlKGRiTmFtZSk7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBjb25zb2xlLndhcm4oYCR7ZGJOYW1lfTogb2xkIEluZGV4ZWREQiBkYXRhYmFzZSBmb3VuZC5gKTtcbiAgdHJ5IHtcbiAgICAvLyBTY2FuIGFsbCByZWNvcmRzLlxuICAgIGxldCByZWNvcmRzO1xuICAgIGF3YWl0IGV4ZWN1dGUoZGIsIGRiTmFtZSwgc3RvcmUgPT4ge1xuICAgICAgc3RvcmUub3BlbkN1cnNvcigpLm9uc3VjY2VzcyA9IGN1cnNvckhhbmRsZXJzLmFsbChcbiAgICAgICAge30sXG4gICAgICAgIHJlcyA9PiAocmVjb3JkcyA9IHJlcylcbiAgICAgICk7XG4gICAgfSk7XG4gICAgY29uc29sZS5sb2coYCR7ZGJOYW1lfTogZm91bmQgJHtyZWNvcmRzLmxlbmd0aH0gcmVjb3Jkcy5gKTtcblxuICAgIC8vIENoZWNrIGlmIHRoZXJlJ3MgYSBlbnRyeSBmb3IgdGhpcy5cbiAgICBsZXQgdGltZXN0YW1wID0gbnVsbDtcbiAgICBhd2FpdCBleGVjdXRlKGRiLCBcIl9fbWV0YV9fXCIsIHN0b3JlID0+IHtcbiAgICAgIHN0b3JlLmdldChgJHtkYk5hbWV9LWxhc3RNb2RpZmllZGApLm9uc3VjY2VzcyA9IGUgPT4ge1xuICAgICAgICB0aW1lc3RhbXAgPSBlLnRhcmdldC5yZXN1bHQgPyBlLnRhcmdldC5yZXN1bHQudmFsdWUgOiBudWxsO1xuICAgICAgfTtcbiAgICB9KTtcbiAgICAvLyBTb21lIHByZXZpb3VzIHZlcnNpb25zLCBhbHNvIHVzZWQgdG8gc3RvcmUgdGhlIHRpbWVzdGFtcHMgd2l0aG91dCBwcmVmaXguXG4gICAgaWYgKCF0aW1lc3RhbXApIHtcbiAgICAgIGF3YWl0IGV4ZWN1dGUoZGIsIFwiX19tZXRhX19cIiwgc3RvcmUgPT4ge1xuICAgICAgICBzdG9yZS5nZXQoXCJsYXN0TW9kaWZpZWRcIikub25zdWNjZXNzID0gZSA9PiB7XG4gICAgICAgICAgdGltZXN0YW1wID0gZS50YXJnZXQucmVzdWx0ID8gZS50YXJnZXQucmVzdWx0LnZhbHVlIDogbnVsbDtcbiAgICAgICAgfTtcbiAgICAgIH0pO1xuICAgIH1cbiAgICBjb25zb2xlLmxvZyhgJHtkYk5hbWV9OiAke3RpbWVzdGFtcCA/IFwiZm91bmRcIiA6IFwibm9cIn0gdGltZXN0YW1wLmApO1xuXG4gICAgLy8gVGhvc2Ugd2lsbCBiZSBpbnNlcnRlZCBpbiB0aGUgbmV3IGRhdGFiYXNlL3NjaGVtYS5cbiAgICByZXR1cm4geyByZWNvcmRzLCB0aW1lc3RhbXAgfTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIGNvbnNvbGUuZXJyb3IoXCJFcnJvciBvY2N1cmVkIGR1cmluZyBtaWdyYXRpb25cIiwgZSk7XG4gICAgcmV0dXJuIG51bGw7XG4gIH0gZmluYWxseSB7XG4gICAgZGIuY2xvc2UoKTtcbiAgfVxufVxuIiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbi8qKlxuICogQmFzZSBkYiBhZGFwdGVyLlxuICpcbiAqIEBhYnN0cmFjdFxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBCYXNlQWRhcHRlciB7XG4gIC8qKlxuICAgKiBEZWxldGVzIGV2ZXJ5IHJlY29yZHMgcHJlc2VudCBpbiB0aGUgZGF0YWJhc2UuXG4gICAqXG4gICAqIEBhYnN0cmFjdFxuICAgKiBAcmV0dXJuIHtQcm9taXNlfVxuICAgKi9cbiAgY2xlYXIoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwiTm90IEltcGxlbWVudGVkLlwiKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFeGVjdXRlcyBhIGJhdGNoIG9mIG9wZXJhdGlvbnMgd2l0aGluIGEgc2luZ2xlIHRyYW5zYWN0aW9uLlxuICAgKlxuICAgKiBAYWJzdHJhY3RcbiAgICogQHBhcmFtICB7RnVuY3Rpb259IGNhbGxiYWNrIFRoZSBvcGVyYXRpb24gY2FsbGJhY2suXG4gICAqIEBwYXJhbSAge09iamVjdH0gICBvcHRpb25zICBUaGUgb3B0aW9ucyBvYmplY3QuXG4gICAqIEByZXR1cm4ge1Byb21pc2V9XG4gICAqL1xuICBleGVjdXRlKGNhbGxiYWNrLCBvcHRpb25zID0geyBwcmVsb2FkOiBbXSB9KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwiTm90IEltcGxlbWVudGVkLlwiKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXRyaWV2ZSBhIHJlY29yZCBieSBpdHMgcHJpbWFyeSBrZXkgZnJvbSB0aGUgZGF0YWJhc2UuXG4gICAqXG4gICAqIEBhYnN0cmFjdFxuICAgKiBAcGFyYW0gIHtTdHJpbmd9IGlkIFRoZSByZWNvcmQgaWQuXG4gICAqIEByZXR1cm4ge1Byb21pc2V9XG4gICAqL1xuICBnZXQoaWQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJOb3QgSW1wbGVtZW50ZWQuXCIpO1xuICB9XG5cbiAgLyoqXG4gICAqIExpc3RzIGFsbCByZWNvcmRzIGZyb20gdGhlIGRhdGFiYXNlLlxuICAgKlxuICAgKiBAYWJzdHJhY3RcbiAgICogQHBhcmFtICB7T2JqZWN0fSBwYXJhbXMgIFRoZSBmaWx0ZXJzIGFuZCBvcmRlciB0byBhcHBseSB0byB0aGUgcmVzdWx0cy5cbiAgICogQHJldHVybiB7UHJvbWlzZX1cbiAgICovXG4gIGxpc3QocGFyYW1zID0geyBmaWx0ZXJzOiB7fSwgb3JkZXI6IFwiXCIgfSkge1xuICAgIHRocm93IG5ldyBFcnJvcihcIk5vdCBJbXBsZW1lbnRlZC5cIik7XG4gIH1cblxuICAvKipcbiAgICogU3RvcmUgdGhlIGxhc3RNb2RpZmllZCB2YWx1ZS5cbiAgICpcbiAgICogQGFic3RyYWN0XG4gICAqIEBwYXJhbSAge051bWJlcn0gIGxhc3RNb2RpZmllZFxuICAgKiBAcmV0dXJuIHtQcm9taXNlfVxuICAgKi9cbiAgc2F2ZUxhc3RNb2RpZmllZChsYXN0TW9kaWZpZWQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJOb3QgSW1wbGVtZW50ZWQuXCIpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHJpZXZlIHNhdmVkIGxhc3RNb2RpZmllZCB2YWx1ZS5cbiAgICpcbiAgICogQGFic3RyYWN0XG4gICAqIEByZXR1cm4ge1Byb21pc2V9XG4gICAqL1xuICBnZXRMYXN0TW9kaWZpZWQoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwiTm90IEltcGxlbWVudGVkLlwiKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBMb2FkIHJlY29yZHMgaW4gYnVsayB0aGF0IHdlcmUgZXhwb3J0ZWQgZnJvbSBhIHNlcnZlci5cbiAgICpcbiAgICogQGFic3RyYWN0XG4gICAqIEBwYXJhbSAge0FycmF5fSByZWNvcmRzIFRoZSByZWNvcmRzIHRvIGxvYWQuXG4gICAqIEByZXR1cm4ge1Byb21pc2V9XG4gICAqL1xuICBpbXBvcnRCdWxrKHJlY29yZHMpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJOb3QgSW1wbGVtZW50ZWQuXCIpO1xuICB9XG5cbiAgLyoqXG4gICAqIExvYWQgYSBkdW1wIG9mIHJlY29yZHMgZXhwb3J0ZWQgZnJvbSBhIHNlcnZlci5cbiAgICpcbiAgICogQGRlcHJlY2F0ZWQgVXNlIHtAbGluayBpbXBvcnRCdWxrfSBpbnN0ZWFkLlxuICAgKiBAYWJzdHJhY3RcbiAgICogQHBhcmFtICB7QXJyYXl9IHJlY29yZHMgVGhlIHJlY29yZHMgdG8gbG9hZC5cbiAgICogQHJldHVybiB7UHJvbWlzZX1cbiAgICovXG4gIGxvYWREdW1wKHJlY29yZHMpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJOb3QgSW1wbGVtZW50ZWQuXCIpO1xuICB9XG5cbiAgc2F2ZU1ldGFkYXRhKG1ldGFkYXRhKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwiTm90IEltcGxlbWVudGVkLlwiKTtcbiAgfVxuXG4gIGdldE1ldGFkYXRhKCkge1xuICAgIHRocm93IG5ldyBFcnJvcihcIk5vdCBJbXBsZW1lbnRlZC5cIik7XG4gIH1cbn1cbiIsIlwidXNlIHN0cmljdFwiO1xuXG5pbXBvcnQgQmFzZUFkYXB0ZXIgZnJvbSBcIi4vYWRhcHRlcnMvYmFzZVwiO1xuaW1wb3J0IElEQiBmcm9tIFwiLi9hZGFwdGVycy9JREJcIjtcbmltcG9ydCB7IHdhdGVyZmFsbCwgZGVlcEVxdWFsIH0gZnJvbSBcIi4vdXRpbHNcIjtcbmltcG9ydCB7IHY0IGFzIHV1aWQ0IH0gZnJvbSBcInV1aWRcIjtcbmltcG9ydCB7IG9taXRLZXlzLCBSRV9SRUNPUkRfSUQgfSBmcm9tIFwiLi91dGlsc1wiO1xuXG5jb25zdCBSRUNPUkRfRklFTERTX1RPX0NMRUFOID0gW1wiX3N0YXR1c1wiXTtcbmNvbnN0IEFWQUlMQUJMRV9IT09LUyA9IFtcImluY29taW5nLWNoYW5nZXNcIl07XG5cbi8qKlxuICogQ29tcGFyZSB0d28gcmVjb3JkcyBvbWl0dGluZyBsb2NhbCBmaWVsZHMgYW5kIHN5bmNocm9uaXphdGlvblxuICogYXR0cmlidXRlcyAobGlrZSBfc3RhdHVzIGFuZCBsYXN0X21vZGlmaWVkKVxuICogQHBhcmFtIHtPYmplY3R9IGEgICAgQSByZWNvcmQgdG8gY29tcGFyZS5cbiAqIEBwYXJhbSB7T2JqZWN0fSBiICAgIEEgcmVjb3JkIHRvIGNvbXBhcmUuXG4gKiBAcGFyYW0ge0FycmF5fSBsb2NhbEZpZWxkcyBBZGRpdGlvbmFsIGZpZWxkcyB0byBpZ25vcmUgZHVyaW5nIHRoZSBjb21wYXJpc29uXG4gKiBAcmV0dXJuIHtib29sZWFufVxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVjb3Jkc0VxdWFsKGEsIGIsIGxvY2FsRmllbGRzID0gW10pIHtcbiAgY29uc3QgZmllbGRzVG9DbGVhbiA9IFJFQ09SRF9GSUVMRFNfVE9fQ0xFQU4uY29uY2F0KFtcImxhc3RfbW9kaWZpZWRcIl0pLmNvbmNhdChcbiAgICBsb2NhbEZpZWxkc1xuICApO1xuICBjb25zdCBjbGVhbkxvY2FsID0gciA9PiBvbWl0S2V5cyhyLCBmaWVsZHNUb0NsZWFuKTtcbiAgcmV0dXJuIGRlZXBFcXVhbChjbGVhbkxvY2FsKGEpLCBjbGVhbkxvY2FsKGIpKTtcbn1cblxuLyoqXG4gKiBTeW5jaHJvbml6YXRpb24gcmVzdWx0IG9iamVjdC5cbiAqL1xuZXhwb3J0IGNsYXNzIFN5bmNSZXN1bHRPYmplY3Qge1xuICAvKipcbiAgICogT2JqZWN0IGRlZmF1bHQgdmFsdWVzLlxuICAgKiBAdHlwZSB7T2JqZWN0fVxuICAgKi9cbiAgc3RhdGljIGdldCBkZWZhdWx0cygpIHtcbiAgICByZXR1cm4ge1xuICAgICAgb2s6IHRydWUsXG4gICAgICBsYXN0TW9kaWZpZWQ6IG51bGwsXG4gICAgICBlcnJvcnM6IFtdLFxuICAgICAgY3JlYXRlZDogW10sXG4gICAgICB1cGRhdGVkOiBbXSxcbiAgICAgIGRlbGV0ZWQ6IFtdLFxuICAgICAgcHVibGlzaGVkOiBbXSxcbiAgICAgIGNvbmZsaWN0czogW10sXG4gICAgICBza2lwcGVkOiBbXSxcbiAgICAgIHJlc29sdmVkOiBbXSxcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFB1YmxpYyBjb25zdHJ1Y3Rvci5cbiAgICovXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIC8qKlxuICAgICAqIEN1cnJlbnQgc3luY2hyb25pemF0aW9uIHJlc3VsdCBzdGF0dXM7IGJlY29tZXMgYGZhbHNlYCB3aGVuIGNvbmZsaWN0cyBvclxuICAgICAqIGVycm9ycyBhcmUgcmVnaXN0ZXJlZC5cbiAgICAgKiBAdHlwZSB7Qm9vbGVhbn1cbiAgICAgKi9cbiAgICB0aGlzLm9rID0gdHJ1ZTtcbiAgICBPYmplY3QuYXNzaWduKHRoaXMsIFN5bmNSZXN1bHRPYmplY3QuZGVmYXVsdHMpO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZHMgZW50cmllcyBmb3IgYSBnaXZlbiByZXN1bHQgdHlwZS5cbiAgICpcbiAgICogQHBhcmFtIHtTdHJpbmd9IHR5cGUgICAgVGhlIHJlc3VsdCB0eXBlLlxuICAgKiBAcGFyYW0ge0FycmF5fSAgZW50cmllcyBUaGUgcmVzdWx0IGVudHJpZXMuXG4gICAqIEByZXR1cm4ge1N5bmNSZXN1bHRPYmplY3R9XG4gICAqL1xuICBhZGQodHlwZSwgZW50cmllcykge1xuICAgIGlmICghQXJyYXkuaXNBcnJheSh0aGlzW3R5cGVdKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoIUFycmF5LmlzQXJyYXkoZW50cmllcykpIHtcbiAgICAgIGVudHJpZXMgPSBbZW50cmllc107XG4gICAgfVxuICAgIC8vIERlZHVwbGljYXRlIGVudHJpZXMgYnkgaWQuIElmIHRoZSB2YWx1ZXMgZG9uJ3QgaGF2ZSBgaWRgIGF0dHJpYnV0ZSwganVzdFxuICAgIC8vIGtlZXAgYWxsLlxuICAgIGNvbnN0IHJlY29yZHNXaXRob3V0SWQgPSBuZXcgU2V0KCk7XG4gICAgY29uc3QgcmVjb3Jkc0J5SWQgPSBuZXcgTWFwKCk7XG4gICAgZnVuY3Rpb24gYWRkT25lUmVjb3JkKHJlY29yZCkge1xuICAgICAgaWYgKCFyZWNvcmQuaWQpIHtcbiAgICAgICAgcmVjb3Jkc1dpdGhvdXRJZC5hZGQocmVjb3JkKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJlY29yZHNCeUlkLnNldChyZWNvcmQuaWQsIHJlY29yZCk7XG4gICAgICB9XG4gICAgfVxuICAgIHRoaXNbdHlwZV0uZm9yRWFjaChhZGRPbmVSZWNvcmQpO1xuICAgIGVudHJpZXMuZm9yRWFjaChhZGRPbmVSZWNvcmQpO1xuXG4gICAgdGhpc1t0eXBlXSA9IEFycmF5LmZyb20ocmVjb3Jkc0J5SWQudmFsdWVzKCkpLmNvbmNhdChcbiAgICAgIEFycmF5LmZyb20ocmVjb3Jkc1dpdGhvdXRJZClcbiAgICApO1xuICAgIHRoaXMub2sgPSB0aGlzLmVycm9ycy5sZW5ndGggKyB0aGlzLmNvbmZsaWN0cy5sZW5ndGggPT09IDA7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKipcbiAgICogUmVpbml0aWFsaXplcyByZXN1bHQgZW50cmllcyBmb3IgYSBnaXZlbiByZXN1bHQgdHlwZS5cbiAgICpcbiAgICogQHBhcmFtICB7U3RyaW5nfSB0eXBlIFRoZSByZXN1bHQgdHlwZS5cbiAgICogQHJldHVybiB7U3luY1Jlc3VsdE9iamVjdH1cbiAgICovXG4gIHJlc2V0KHR5cGUpIHtcbiAgICB0aGlzW3R5cGVdID0gU3luY1Jlc3VsdE9iamVjdC5kZWZhdWx0c1t0eXBlXTtcbiAgICB0aGlzLm9rID0gdGhpcy5lcnJvcnMubGVuZ3RoICsgdGhpcy5jb25mbGljdHMubGVuZ3RoID09PSAwO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG59XG5cbmV4cG9ydCBjbGFzcyBTZXJ2ZXJXYXNGbHVzaGVkRXJyb3IgZXh0ZW5kcyBFcnJvciB7XG4gIGNvbnN0cnVjdG9yKGNsaWVudFRpbWVzdGFtcCwgc2VydmVyVGltZXN0YW1wLCBtZXNzYWdlKSB7XG4gICAgc3VwZXIobWVzc2FnZSk7XG5cbiAgICBpZiAoRXJyb3IuY2FwdHVyZVN0YWNrVHJhY2UpIHtcbiAgICAgIEVycm9yLmNhcHR1cmVTdGFja1RyYWNlKHRoaXMsIFNlcnZlcldhc0ZsdXNoZWRFcnJvcik7XG4gICAgfVxuXG4gICAgdGhpcy5jbGllbnRUaW1lc3RhbXAgPSBjbGllbnRUaW1lc3RhbXA7XG4gICAgdGhpcy5zZXJ2ZXJUaW1lc3RhbXAgPSBzZXJ2ZXJUaW1lc3RhbXA7XG4gIH1cbn1cblxuZnVuY3Rpb24gY3JlYXRlVVVJRFNjaGVtYSgpIHtcbiAgcmV0dXJuIHtcbiAgICBnZW5lcmF0ZSgpIHtcbiAgICAgIHJldHVybiB1dWlkNCgpO1xuICAgIH0sXG5cbiAgICB2YWxpZGF0ZShpZCkge1xuICAgICAgcmV0dXJuIHR5cGVvZiBpZCA9PSBcInN0cmluZ1wiICYmIFJFX1JFQ09SRF9JRC50ZXN0KGlkKTtcbiAgICB9LFxuICB9O1xufVxuXG4vKipcbiAqIElEU2NoZW1hIGZvciB3aGVuIHVzaW5nIGtpbnRvLmpzIGFzIGEga2V5LXZhbHVlIHN0b3JlLlxuICogVXNpbmcgdGhpcyBJRFNjaGVtYSByZXF1aXJlcyB5b3UgdG8gc2V0IGEgcHJvcGVydHkgYXMgdGhlIGlkLlxuICogVGhpcyB3aWxsIGJlIHRoZSBwcm9wZXJ0eSB1c2VkIHRvIHJldHJpZXZlIHRoaXMgcmVjb3JkLlxuICpcbiAqIEBleGFtcGxlXG4gKiBjb25zdCBleGFtcGxlQ29sbGVjdGlvbiA9IGRiLmNvbGxlY3Rpb24oXCJleGFtcGxlXCIsIHsgaWRTY2hlbWE6IGNyZWF0ZUtleVZhbHVlU3RvcmVJZFNjaGVtYSgpIH0pXG4gKiBhd2FpdCBleGFtcGxlQ29sbGVjdGlvbi5jcmVhdGUoeyB0aXRsZTogXCJIb3cgdG8gdGllIGEgdGllXCIsIGZhdm9yaXRlQ29sb3I6IFwiYmx1ZVwiLCBpZDogXCJ1c2VyMTIzXCIgfSwgeyB1c2VSZWNvcmRJZDogdHJ1ZSB9KVxuICogYXdhaXQgZXhhbXBsZUNvbGxlY3Rpb24uZ2V0QW55KFwidXNlcjEyM1wiKVxuICovXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlS2V5VmFsdWVTdG9yZUlkU2NoZW1hKCkge1xuICByZXR1cm4ge1xuICAgIGdlbmVyYXRlKCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiY3JlYXRlS2V5VmFsdWVTdG9yZUlkU2NoZW1hKCkgZG9lcyBub3QgZ2VuZXJhdGUgYW4gaWRcIik7XG4gICAgfSxcbiAgICB2YWxpZGF0ZSgpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH0sXG4gIH07XG59XG5cbmZ1bmN0aW9uIG1hcmtTdGF0dXMocmVjb3JkLCBzdGF0dXMpIHtcbiAgcmV0dXJuIHsgLi4ucmVjb3JkLCBfc3RhdHVzOiBzdGF0dXMgfTtcbn1cblxuZnVuY3Rpb24gbWFya0RlbGV0ZWQocmVjb3JkKSB7XG4gIHJldHVybiBtYXJrU3RhdHVzKHJlY29yZCwgXCJkZWxldGVkXCIpO1xufVxuXG5mdW5jdGlvbiBtYXJrU3luY2VkKHJlY29yZCkge1xuICByZXR1cm4gbWFya1N0YXR1cyhyZWNvcmQsIFwic3luY2VkXCIpO1xufVxuXG4vKipcbiAqIEltcG9ydCBhIHJlbW90ZSBjaGFuZ2UgaW50byB0aGUgbG9jYWwgZGF0YWJhc2UuXG4gKlxuICogQHBhcmFtICB7SURCVHJhbnNhY3Rpb25Qcm94eX0gdHJhbnNhY3Rpb24gVGhlIHRyYW5zYWN0aW9uIGhhbmRsZXIuXG4gKiBAcGFyYW0gIHtPYmplY3R9ICAgICAgICAgICAgICByZW1vdGUgICAgICBUaGUgcmVtb3RlIGNoYW5nZSBvYmplY3QgdG8gaW1wb3J0LlxuICogQHBhcmFtICB7QXJyYXk8U3RyaW5nPn0gICAgICAgbG9jYWxGaWVsZHMgVGhlIGxpc3Qgb2YgZmllbGRzIHRoYXQgcmVtYWluIGxvY2FsLlxuICogQHJldHVybiB7T2JqZWN0fVxuICovXG5mdW5jdGlvbiBpbXBvcnRDaGFuZ2UodHJhbnNhY3Rpb24sIHJlbW90ZSwgbG9jYWxGaWVsZHMpIHtcbiAgY29uc3QgbG9jYWwgPSB0cmFuc2FjdGlvbi5nZXQocmVtb3RlLmlkKTtcbiAgaWYgKCFsb2NhbCkge1xuICAgIC8vIE5vdCBmb3VuZCBsb2NhbGx5IGJ1dCByZW1vdGUgY2hhbmdlIGlzIG1hcmtlZCBhcyBkZWxldGVkOyBza2lwIHRvXG4gICAgLy8gYXZvaWQgcmVjcmVhdGlvbi5cbiAgICBpZiAocmVtb3RlLmRlbGV0ZWQpIHtcbiAgICAgIHJldHVybiB7IHR5cGU6IFwic2tpcHBlZFwiLCBkYXRhOiByZW1vdGUgfTtcbiAgICB9XG4gICAgY29uc3Qgc3luY2VkID0gbWFya1N5bmNlZChyZW1vdGUpO1xuICAgIHRyYW5zYWN0aW9uLmNyZWF0ZShzeW5jZWQpO1xuICAgIHJldHVybiB7IHR5cGU6IFwiY3JlYXRlZFwiLCBkYXRhOiBzeW5jZWQgfTtcbiAgfVxuICAvLyBDb21wYXJlIGxvY2FsIGFuZCByZW1vdGUsIGlnbm9yaW5nIGxvY2FsIGZpZWxkcy5cbiAgY29uc3QgaXNJZGVudGljYWwgPSByZWNvcmRzRXF1YWwobG9jYWwsIHJlbW90ZSwgbG9jYWxGaWVsZHMpO1xuICAvLyBBcHBseSByZW1vdGUgY2hhbmdlcyBvbiBsb2NhbCByZWNvcmQuXG4gIGNvbnN0IHN5bmNlZCA9IHsgLi4ubG9jYWwsIC4uLm1hcmtTeW5jZWQocmVtb3RlKSB9O1xuICAvLyBEZXRlY3Qgb3IgaWdub3JlIGNvbmZsaWN0cyBpZiByZWNvcmQgaGFzIGFsc28gYmVlbiBtb2RpZmllZCBsb2NhbGx5LlxuICBpZiAobG9jYWwuX3N0YXR1cyAhPT0gXCJzeW5jZWRcIikge1xuICAgIC8vIExvY2FsbHkgZGVsZXRlZCwgdW5zeW5jZWQ6IHNjaGVkdWxlZCBmb3IgcmVtb3RlIGRlbGV0aW9uLlxuICAgIGlmIChsb2NhbC5fc3RhdHVzID09PSBcImRlbGV0ZWRcIikge1xuICAgICAgcmV0dXJuIHsgdHlwZTogXCJza2lwcGVkXCIsIGRhdGE6IGxvY2FsIH07XG4gICAgfVxuICAgIGlmIChpc0lkZW50aWNhbCkge1xuICAgICAgLy8gSWYgcmVjb3JkcyBhcmUgaWRlbnRpY2FsLCBpbXBvcnQgYW55d2F5LCBzbyB3ZSBidW1wIHRoZVxuICAgICAgLy8gbG9jYWwgbGFzdF9tb2RpZmllZCB2YWx1ZSBmcm9tIHRoZSBzZXJ2ZXIgYW5kIHNldCByZWNvcmRcbiAgICAgIC8vIHN0YXR1cyB0byBcInN5bmNlZFwiLlxuICAgICAgdHJhbnNhY3Rpb24udXBkYXRlKHN5bmNlZCk7XG4gICAgICByZXR1cm4geyB0eXBlOiBcInVwZGF0ZWRcIiwgZGF0YTogeyBvbGQ6IGxvY2FsLCBuZXc6IHN5bmNlZCB9IH07XG4gICAgfVxuICAgIGlmIChcbiAgICAgIGxvY2FsLmxhc3RfbW9kaWZpZWQgIT09IHVuZGVmaW5lZCAmJlxuICAgICAgbG9jYWwubGFzdF9tb2RpZmllZCA9PT0gcmVtb3RlLmxhc3RfbW9kaWZpZWRcbiAgICApIHtcbiAgICAgIC8vIElmIG91ciBsb2NhbCB2ZXJzaW9uIGhhcyB0aGUgc2FtZSBsYXN0X21vZGlmaWVkIGFzIHRoZSByZW1vdGVcbiAgICAgIC8vIG9uZSwgdGhpcyByZXByZXNlbnRzIGFuIG9iamVjdCB0aGF0IGNvcnJlc3BvbmRzIHRvIGEgcmVzb2x2ZWRcbiAgICAgIC8vIGNvbmZsaWN0LiBPdXIgbG9jYWwgdmVyc2lvbiByZXByZXNlbnRzIHRoZSBmaW5hbCBvdXRwdXQsIHNvXG4gICAgICAvLyB3ZSBrZWVwIHRoYXQgb25lLiAoTm8gdHJhbnNhY3Rpb24gb3BlcmF0aW9uIHRvIGRvLilcbiAgICAgIC8vIEJ1dCBpZiBvdXIgbGFzdF9tb2RpZmllZCBpcyB1bmRlZmluZWQsXG4gICAgICAvLyB0aGF0IG1lYW5zIHdlJ3ZlIGNyZWF0ZWQgdGhlIHNhbWUgb2JqZWN0IGxvY2FsbHkgYXMgb25lIG9uXG4gICAgICAvLyB0aGUgc2VydmVyLCB3aGljaCAqbXVzdCogYmUgYSBjb25mbGljdC5cbiAgICAgIHJldHVybiB7IHR5cGU6IFwidm9pZFwiIH07XG4gICAgfVxuICAgIHJldHVybiB7XG4gICAgICB0eXBlOiBcImNvbmZsaWN0c1wiLFxuICAgICAgZGF0YTogeyB0eXBlOiBcImluY29taW5nXCIsIGxvY2FsOiBsb2NhbCwgcmVtb3RlOiByZW1vdGUgfSxcbiAgICB9O1xuICB9XG4gIC8vIExvY2FsIHJlY29yZCB3YXMgc3luY2VkLlxuICBpZiAocmVtb3RlLmRlbGV0ZWQpIHtcbiAgICB0cmFuc2FjdGlvbi5kZWxldGUocmVtb3RlLmlkKTtcbiAgICByZXR1cm4geyB0eXBlOiBcImRlbGV0ZWRcIiwgZGF0YTogbG9jYWwgfTtcbiAgfVxuICAvLyBJbXBvcnQgbG9jYWxseS5cbiAgdHJhbnNhY3Rpb24udXBkYXRlKHN5bmNlZCk7XG4gIC8vIGlmIGlkZW50aWNhbCwgc2ltcGx5IGV4Y2x1ZGUgaXQgZnJvbSBhbGwgU3luY1Jlc3VsdE9iamVjdCBsaXN0c1xuICBjb25zdCB0eXBlID0gaXNJZGVudGljYWwgPyBcInZvaWRcIiA6IFwidXBkYXRlZFwiO1xuICByZXR1cm4geyB0eXBlLCBkYXRhOiB7IG9sZDogbG9jYWwsIG5ldzogc3luY2VkIH0gfTtcbn1cblxuLyoqXG4gKiBBYnN0cmFjdHMgYSBjb2xsZWN0aW9uIG9mIHJlY29yZHMgc3RvcmVkIGluIHRoZSBsb2NhbCBkYXRhYmFzZSwgcHJvdmlkaW5nXG4gKiBDUlVEIG9wZXJhdGlvbnMgYW5kIHN5bmNocm9uaXphdGlvbiBoZWxwZXJzLlxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBDb2xsZWN0aW9uIHtcbiAgLyoqXG4gICAqIENvbnN0cnVjdG9yLlxuICAgKlxuICAgKiBPcHRpb25zOlxuICAgKiAtIGB7QmFzZUFkYXB0ZXJ9IGFkYXB0ZXJgIFRoZSBEQiBhZGFwdGVyIChkZWZhdWx0OiBgSURCYClcbiAgICpcbiAgICogQHBhcmFtICB7U3RyaW5nfSBidWNrZXQgIFRoZSBidWNrZXQgaWRlbnRpZmllci5cbiAgICogQHBhcmFtICB7U3RyaW5nfSBuYW1lICAgIFRoZSBjb2xsZWN0aW9uIG5hbWUuXG4gICAqIEBwYXJhbSAge0FwaX0gICAgYXBpICAgICBUaGUgQXBpIGluc3RhbmNlLlxuICAgKiBAcGFyYW0gIHtPYmplY3R9IG9wdGlvbnMgVGhlIG9wdGlvbnMgb2JqZWN0LlxuICAgKi9cbiAgY29uc3RydWN0b3IoYnVja2V0LCBuYW1lLCBhcGksIG9wdGlvbnMgPSB7fSkge1xuICAgIHRoaXMuX2J1Y2tldCA9IGJ1Y2tldDtcbiAgICB0aGlzLl9uYW1lID0gbmFtZTtcbiAgICB0aGlzLl9sYXN0TW9kaWZpZWQgPSBudWxsO1xuXG4gICAgY29uc3QgREJBZGFwdGVyID0gb3B0aW9ucy5hZGFwdGVyIHx8IElEQjtcbiAgICBpZiAoIURCQWRhcHRlcikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTm8gYWRhcHRlciBwcm92aWRlZFwiKTtcbiAgICB9XG4gICAgY29uc3QgZGIgPSBuZXcgREJBZGFwdGVyKGAke2J1Y2tldH0vJHtuYW1lfWAsIG9wdGlvbnMuYWRhcHRlck9wdGlvbnMpO1xuICAgIGlmICghKGRiIGluc3RhbmNlb2YgQmFzZUFkYXB0ZXIpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJVbnN1cHBvcnRlZCBhZGFwdGVyLlwiKTtcbiAgICB9XG4gICAgLy8gcHVibGljIHByb3BlcnRpZXNcbiAgICAvKipcbiAgICAgKiBUaGUgZGIgYWRhcHRlciBpbnN0YW5jZVxuICAgICAqIEB0eXBlIHtCYXNlQWRhcHRlcn1cbiAgICAgKi9cbiAgICB0aGlzLmRiID0gZGI7XG4gICAgLyoqXG4gICAgICogVGhlIEFwaSBpbnN0YW5jZS5cbiAgICAgKiBAdHlwZSB7S2ludG9DbGllbnR9XG4gICAgICovXG4gICAgdGhpcy5hcGkgPSBhcGk7XG4gICAgLyoqXG4gICAgICogVGhlIGV2ZW50IGVtaXR0ZXIgaW5zdGFuY2UuXG4gICAgICogQHR5cGUge0V2ZW50RW1pdHRlcn1cbiAgICAgKi9cbiAgICB0aGlzLmV2ZW50cyA9IG9wdGlvbnMuZXZlbnRzO1xuICAgIC8qKlxuICAgICAqIFRoZSBJZFNjaGVtYSBpbnN0YW5jZS5cbiAgICAgKiBAdHlwZSB7T2JqZWN0fVxuICAgICAqL1xuICAgIHRoaXMuaWRTY2hlbWEgPSB0aGlzLl92YWxpZGF0ZUlkU2NoZW1hKG9wdGlvbnMuaWRTY2hlbWEpO1xuICAgIC8qKlxuICAgICAqIFRoZSBsaXN0IG9mIHJlbW90ZSB0cmFuc2Zvcm1lcnMuXG4gICAgICogQHR5cGUge0FycmF5fVxuICAgICAqL1xuICAgIHRoaXMucmVtb3RlVHJhbnNmb3JtZXJzID0gdGhpcy5fdmFsaWRhdGVSZW1vdGVUcmFuc2Zvcm1lcnMoXG4gICAgICBvcHRpb25zLnJlbW90ZVRyYW5zZm9ybWVyc1xuICAgICk7XG4gICAgLyoqXG4gICAgICogVGhlIGxpc3Qgb2YgaG9va3MuXG4gICAgICogQHR5cGUge09iamVjdH1cbiAgICAgKi9cbiAgICB0aGlzLmhvb2tzID0gdGhpcy5fdmFsaWRhdGVIb29rcyhvcHRpb25zLmhvb2tzKTtcbiAgICAvKipcbiAgICAgKiBUaGUgbGlzdCBvZiBmaWVsZHMgbmFtZXMgdGhhdCB3aWxsIHJlbWFpbiBsb2NhbC5cbiAgICAgKiBAdHlwZSB7QXJyYXl9XG4gICAgICovXG4gICAgdGhpcy5sb2NhbEZpZWxkcyA9IG9wdGlvbnMubG9jYWxGaWVsZHMgfHwgW107XG4gIH1cblxuICAvKipcbiAgICogVGhlIGNvbGxlY3Rpb24gbmFtZS5cbiAgICogQHR5cGUge1N0cmluZ31cbiAgICovXG4gIGdldCBuYW1lKCkge1xuICAgIHJldHVybiB0aGlzLl9uYW1lO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBidWNrZXQgbmFtZS5cbiAgICogQHR5cGUge1N0cmluZ31cbiAgICovXG4gIGdldCBidWNrZXQoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2J1Y2tldDtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgbGFzdCBtb2RpZmllZCB0aW1lc3RhbXAuXG4gICAqIEB0eXBlIHtOdW1iZXJ9XG4gICAqL1xuICBnZXQgbGFzdE1vZGlmaWVkKCkge1xuICAgIHJldHVybiB0aGlzLl9sYXN0TW9kaWZpZWQ7XG4gIH1cblxuICAvKipcbiAgICogU3luY2hyb25pemF0aW9uIHN0cmF0ZWdpZXMuIEF2YWlsYWJsZSBzdHJhdGVnaWVzIGFyZTpcbiAgICpcbiAgICogLSBgTUFOVUFMYDogQ29uZmxpY3RzIHdpbGwgYmUgcmVwb3J0ZWQgaW4gYSBkZWRpY2F0ZWQgYXJyYXkuXG4gICAqIC0gYFNFUlZFUl9XSU5TYDogQ29uZmxpY3RzIGFyZSByZXNvbHZlZCB1c2luZyByZW1vdGUgZGF0YS5cbiAgICogLSBgQ0xJRU5UX1dJTlNgOiBDb25mbGljdHMgYXJlIHJlc29sdmVkIHVzaW5nIGxvY2FsIGRhdGEuXG4gICAqXG4gICAqIEB0eXBlIHtPYmplY3R9XG4gICAqL1xuICBzdGF0aWMgZ2V0IHN0cmF0ZWd5KCkge1xuICAgIHJldHVybiB7XG4gICAgICBDTElFTlRfV0lOUzogXCJjbGllbnRfd2luc1wiLFxuICAgICAgU0VSVkVSX1dJTlM6IFwic2VydmVyX3dpbnNcIixcbiAgICAgIE1BTlVBTDogXCJtYW51YWxcIixcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFZhbGlkYXRlcyBhbiBpZFNjaGVtYS5cbiAgICpcbiAgICogQHBhcmFtICB7T2JqZWN0fHVuZGVmaW5lZH0gaWRTY2hlbWFcbiAgICogQHJldHVybiB7T2JqZWN0fVxuICAgKi9cbiAgX3ZhbGlkYXRlSWRTY2hlbWEoaWRTY2hlbWEpIHtcbiAgICBpZiAodHlwZW9mIGlkU2NoZW1hID09PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICByZXR1cm4gY3JlYXRlVVVJRFNjaGVtYSgpO1xuICAgIH1cbiAgICBpZiAodHlwZW9mIGlkU2NoZW1hICE9PSBcIm9iamVjdFwiKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJpZFNjaGVtYSBtdXN0IGJlIGFuIG9iamVjdC5cIik7XG4gICAgfSBlbHNlIGlmICh0eXBlb2YgaWRTY2hlbWEuZ2VuZXJhdGUgIT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiaWRTY2hlbWEgbXVzdCBwcm92aWRlIGEgZ2VuZXJhdGUgZnVuY3Rpb24uXCIpO1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIGlkU2NoZW1hLnZhbGlkYXRlICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcImlkU2NoZW1hIG11c3QgcHJvdmlkZSBhIHZhbGlkYXRlIGZ1bmN0aW9uLlwiKTtcbiAgICB9XG4gICAgcmV0dXJuIGlkU2NoZW1hO1xuICB9XG5cbiAgLyoqXG4gICAqIFZhbGlkYXRlcyBhIGxpc3Qgb2YgcmVtb3RlIHRyYW5zZm9ybWVycy5cbiAgICpcbiAgICogQHBhcmFtICB7QXJyYXl8dW5kZWZpbmVkfSByZW1vdGVUcmFuc2Zvcm1lcnNcbiAgICogQHJldHVybiB7QXJyYXl9XG4gICAqL1xuICBfdmFsaWRhdGVSZW1vdGVUcmFuc2Zvcm1lcnMocmVtb3RlVHJhbnNmb3JtZXJzKSB7XG4gICAgaWYgKHR5cGVvZiByZW1vdGVUcmFuc2Zvcm1lcnMgPT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgIHJldHVybiBbXTtcbiAgICB9XG4gICAgaWYgKCFBcnJheS5pc0FycmF5KHJlbW90ZVRyYW5zZm9ybWVycykpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcInJlbW90ZVRyYW5zZm9ybWVycyBzaG91bGQgYmUgYW4gYXJyYXkuXCIpO1xuICAgIH1cbiAgICByZXR1cm4gcmVtb3RlVHJhbnNmb3JtZXJzLm1hcCh0cmFuc2Zvcm1lciA9PiB7XG4gICAgICBpZiAodHlwZW9mIHRyYW5zZm9ybWVyICE9PSBcIm9iamVjdFwiKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIkEgdHJhbnNmb3JtZXIgbXVzdCBiZSBhbiBvYmplY3QuXCIpO1xuICAgICAgfSBlbHNlIGlmICh0eXBlb2YgdHJhbnNmb3JtZXIuZW5jb2RlICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQSB0cmFuc2Zvcm1lciBtdXN0IHByb3ZpZGUgYW4gZW5jb2RlIGZ1bmN0aW9uLlwiKTtcbiAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHRyYW5zZm9ybWVyLmRlY29kZSAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIkEgdHJhbnNmb3JtZXIgbXVzdCBwcm92aWRlIGEgZGVjb2RlIGZ1bmN0aW9uLlwiKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0cmFuc2Zvcm1lcjtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBWYWxpZGF0ZSB0aGUgcGFzc2VkIGhvb2sgaXMgY29ycmVjdC5cbiAgICpcbiAgICogQHBhcmFtIHtBcnJheXx1bmRlZmluZWR9IGhvb2suXG4gICAqIEByZXR1cm4ge0FycmF5fVxuICAgKiovXG4gIF92YWxpZGF0ZUhvb2soaG9vaykge1xuICAgIGlmICghQXJyYXkuaXNBcnJheShob29rKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQSBob29rIGRlZmluaXRpb24gc2hvdWxkIGJlIGFuIGFycmF5IG9mIGZ1bmN0aW9ucy5cIik7XG4gICAgfVxuICAgIHJldHVybiBob29rLm1hcChmbiA9PiB7XG4gICAgICBpZiAodHlwZW9mIGZuICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQSBob29rIGRlZmluaXRpb24gc2hvdWxkIGJlIGFuIGFycmF5IG9mIGZ1bmN0aW9ucy5cIik7XG4gICAgICB9XG4gICAgICByZXR1cm4gZm47XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogVmFsaWRhdGVzIGEgbGlzdCBvZiBob29rcy5cbiAgICpcbiAgICogQHBhcmFtICB7T2JqZWN0fHVuZGVmaW5lZH0gaG9va3NcbiAgICogQHJldHVybiB7T2JqZWN0fVxuICAgKi9cbiAgX3ZhbGlkYXRlSG9va3MoaG9va3MpIHtcbiAgICBpZiAodHlwZW9mIGhvb2tzID09PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICByZXR1cm4ge307XG4gICAgfVxuICAgIGlmIChBcnJheS5pc0FycmF5KGhvb2tzKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiaG9va3Mgc2hvdWxkIGJlIGFuIG9iamVjdCwgbm90IGFuIGFycmF5LlwiKTtcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBob29rcyAhPT0gXCJvYmplY3RcIikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiaG9va3Mgc2hvdWxkIGJlIGFuIG9iamVjdC5cIik7XG4gICAgfVxuXG4gICAgY29uc3QgdmFsaWRhdGVkSG9va3MgPSB7fTtcblxuICAgIGZvciAoY29uc3QgaG9vayBpbiBob29rcykge1xuICAgICAgaWYgKCFBVkFJTEFCTEVfSE9PS1MuaW5jbHVkZXMoaG9vaykpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgIFwiVGhlIGhvb2sgc2hvdWxkIGJlIG9uZSBvZiBcIiArIEFWQUlMQUJMRV9IT09LUy5qb2luKFwiLCBcIilcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIHZhbGlkYXRlZEhvb2tzW2hvb2tdID0gdGhpcy5fdmFsaWRhdGVIb29rKGhvb2tzW2hvb2tdKTtcbiAgICB9XG4gICAgcmV0dXJuIHZhbGlkYXRlZEhvb2tzO1xuICB9XG5cbiAgLyoqXG4gICAqIERlbGV0ZXMgZXZlcnkgcmVjb3JkcyBpbiB0aGUgY3VycmVudCBjb2xsZWN0aW9uIGFuZCBtYXJrcyB0aGUgY29sbGVjdGlvbiBhc1xuICAgKiBuZXZlciBzeW5jZWQuXG4gICAqXG4gICAqIEByZXR1cm4ge1Byb21pc2V9XG4gICAqL1xuICBhc3luYyBjbGVhcigpIHtcbiAgICBhd2FpdCB0aGlzLmRiLmNsZWFyKCk7XG4gICAgYXdhaXQgdGhpcy5kYi5zYXZlTWV0YWRhdGEobnVsbCk7XG4gICAgYXdhaXQgdGhpcy5kYi5zYXZlTGFzdE1vZGlmaWVkKG51bGwpO1xuICAgIHJldHVybiB7IGRhdGE6IFtdLCBwZXJtaXNzaW9uczoge30gfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFbmNvZGVzIGEgcmVjb3JkLlxuICAgKlxuICAgKiBAcGFyYW0gIHtTdHJpbmd9IHR5cGUgICBFaXRoZXIgXCJyZW1vdGVcIiBvciBcImxvY2FsXCIuXG4gICAqIEBwYXJhbSAge09iamVjdH0gcmVjb3JkIFRoZSByZWNvcmQgb2JqZWN0IHRvIGVuY29kZS5cbiAgICogQHJldHVybiB7UHJvbWlzZX1cbiAgICovXG4gIF9lbmNvZGVSZWNvcmQodHlwZSwgcmVjb3JkKSB7XG4gICAgaWYgKCF0aGlzW2Ake3R5cGV9VHJhbnNmb3JtZXJzYF0ubGVuZ3RoKSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHJlY29yZCk7XG4gICAgfVxuICAgIHJldHVybiB3YXRlcmZhbGwoXG4gICAgICB0aGlzW2Ake3R5cGV9VHJhbnNmb3JtZXJzYF0ubWFwKHRyYW5zZm9ybWVyID0+IHtcbiAgICAgICAgcmV0dXJuIHJlY29yZCA9PiB0cmFuc2Zvcm1lci5lbmNvZGUocmVjb3JkKTtcbiAgICAgIH0pLFxuICAgICAgcmVjb3JkXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEZWNvZGVzIGEgcmVjb3JkLlxuICAgKlxuICAgKiBAcGFyYW0gIHtTdHJpbmd9IHR5cGUgICBFaXRoZXIgXCJyZW1vdGVcIiBvciBcImxvY2FsXCIuXG4gICAqIEBwYXJhbSAge09iamVjdH0gcmVjb3JkIFRoZSByZWNvcmQgb2JqZWN0IHRvIGRlY29kZS5cbiAgICogQHJldHVybiB7UHJvbWlzZX1cbiAgICovXG4gIF9kZWNvZGVSZWNvcmQodHlwZSwgcmVjb3JkKSB7XG4gICAgaWYgKCF0aGlzW2Ake3R5cGV9VHJhbnNmb3JtZXJzYF0ubGVuZ3RoKSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHJlY29yZCk7XG4gICAgfVxuICAgIHJldHVybiB3YXRlcmZhbGwoXG4gICAgICB0aGlzW2Ake3R5cGV9VHJhbnNmb3JtZXJzYF0ucmV2ZXJzZSgpLm1hcCh0cmFuc2Zvcm1lciA9PiB7XG4gICAgICAgIHJldHVybiByZWNvcmQgPT4gdHJhbnNmb3JtZXIuZGVjb2RlKHJlY29yZCk7XG4gICAgICB9KSxcbiAgICAgIHJlY29yZFxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogQWRkcyBhIHJlY29yZCB0byB0aGUgbG9jYWwgZGF0YWJhc2UsIGFzc2VydGluZyB0aGF0IG5vbmVcbiAgICogYWxyZWFkeSBleGlzdCB3aXRoIHRoaXMgSUQuXG4gICAqXG4gICAqIE5vdGU6IElmIGVpdGhlciB0aGUgYHVzZVJlY29yZElkYCBvciBgc3luY2VkYCBvcHRpb25zIGFyZSB0cnVlLCB0aGVuIHRoZVxuICAgKiByZWNvcmQgb2JqZWN0IG11c3QgY29udGFpbiB0aGUgaWQgZmllbGQgdG8gYmUgdmFsaWRhdGVkLiBJZiBub25lIG9mIHRoZXNlXG4gICAqIG9wdGlvbnMgYXJlIHRydWUsIGFuIGlkIGlzIGdlbmVyYXRlZCB1c2luZyB0aGUgY3VycmVudCBJZFNjaGVtYTsgaW4gdGhpc1xuICAgKiBjYXNlLCB0aGUgcmVjb3JkIHBhc3NlZCBtdXN0IG5vdCBoYXZlIGFuIGlkLlxuICAgKlxuICAgKiBPcHRpb25zOlxuICAgKiAtIHtCb29sZWFufSBzeW5jZWQgICAgICAgU2V0cyByZWNvcmQgc3RhdHVzIHRvIFwic3luY2VkXCIgKGRlZmF1bHQ6IGBmYWxzZWApLlxuICAgKiAtIHtCb29sZWFufSB1c2VSZWNvcmRJZCAgRm9yY2VzIHRoZSBgaWRgIGZpZWxkIGZyb20gdGhlIHJlY29yZCB0byBiZSB1c2VkLFxuICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgaW5zdGVhZCBvZiBvbmUgdGhhdCBpcyBnZW5lcmF0ZWQgYXV0b21hdGljYWxseVxuICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgKGRlZmF1bHQ6IGBmYWxzZWApLlxuICAgKlxuICAgKiBAcGFyYW0gIHtPYmplY3R9IHJlY29yZFxuICAgKiBAcGFyYW0gIHtPYmplY3R9IG9wdGlvbnNcbiAgICogQHJldHVybiB7UHJvbWlzZX1cbiAgICovXG4gIGNyZWF0ZShyZWNvcmQsIG9wdGlvbnMgPSB7IHVzZVJlY29yZElkOiBmYWxzZSwgc3luY2VkOiBmYWxzZSB9KSB7XG4gICAgLy8gVmFsaWRhdGUgdGhlIHJlY29yZCBhbmQgaXRzIElEIChpZiBhbnkpLCBldmVuIHRob3VnaCB0aGlzXG4gICAgLy8gdmFsaWRhdGlvbiBpcyBhbHNvIGRvbmUgaW4gdGhlIENvbGxlY3Rpb25UcmFuc2FjdGlvbiBtZXRob2QsXG4gICAgLy8gYmVjYXVzZSB3ZSBuZWVkIHRvIHBhc3MgdGhlIElEIHRvIHByZWxvYWRJZHMuXG4gICAgY29uc3QgcmVqZWN0ID0gbXNnID0+IFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihtc2cpKTtcbiAgICBpZiAodHlwZW9mIHJlY29yZCAhPT0gXCJvYmplY3RcIikge1xuICAgICAgcmV0dXJuIHJlamVjdChcIlJlY29yZCBpcyBub3QgYW4gb2JqZWN0LlwiKTtcbiAgICB9XG4gICAgaWYgKFxuICAgICAgKG9wdGlvbnMuc3luY2VkIHx8IG9wdGlvbnMudXNlUmVjb3JkSWQpICYmXG4gICAgICAhcmVjb3JkLmhhc093blByb3BlcnR5KFwiaWRcIilcbiAgICApIHtcbiAgICAgIHJldHVybiByZWplY3QoXG4gICAgICAgIFwiTWlzc2luZyByZXF1aXJlZCBJZDsgc3luY2VkIGFuZCB1c2VSZWNvcmRJZCBvcHRpb25zIHJlcXVpcmUgb25lXCJcbiAgICAgICk7XG4gICAgfVxuICAgIGlmIChcbiAgICAgICFvcHRpb25zLnN5bmNlZCAmJlxuICAgICAgIW9wdGlvbnMudXNlUmVjb3JkSWQgJiZcbiAgICAgIHJlY29yZC5oYXNPd25Qcm9wZXJ0eShcImlkXCIpXG4gICAgKSB7XG4gICAgICByZXR1cm4gcmVqZWN0KFwiRXh0cmFuZW91cyBJZDsgY2FuJ3QgY3JlYXRlIGEgcmVjb3JkIGhhdmluZyBvbmUgc2V0LlwiKTtcbiAgICB9XG4gICAgY29uc3QgbmV3UmVjb3JkID0ge1xuICAgICAgLi4ucmVjb3JkLFxuICAgICAgaWQ6XG4gICAgICAgIG9wdGlvbnMuc3luY2VkIHx8IG9wdGlvbnMudXNlUmVjb3JkSWRcbiAgICAgICAgICA/IHJlY29yZC5pZFxuICAgICAgICAgIDogdGhpcy5pZFNjaGVtYS5nZW5lcmF0ZShyZWNvcmQpLFxuICAgICAgX3N0YXR1czogb3B0aW9ucy5zeW5jZWQgPyBcInN5bmNlZFwiIDogXCJjcmVhdGVkXCIsXG4gICAgfTtcbiAgICBpZiAoIXRoaXMuaWRTY2hlbWEudmFsaWRhdGUobmV3UmVjb3JkLmlkKSkge1xuICAgICAgcmV0dXJuIHJlamVjdChgSW52YWxpZCBJZDogJHtuZXdSZWNvcmQuaWR9YCk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmV4ZWN1dGUodHhuID0+IHR4bi5jcmVhdGUobmV3UmVjb3JkKSwge1xuICAgICAgcHJlbG9hZElkczogW25ld1JlY29yZC5pZF0sXG4gICAgfSkuY2F0Y2goZXJyID0+IHtcbiAgICAgIGlmIChvcHRpb25zLnVzZVJlY29yZElkKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICBcIkNvdWxkbid0IGNyZWF0ZSByZWNvcmQuIEl0IG1heSBoYXZlIGJlZW4gdmlydHVhbGx5IGRlbGV0ZWQuXCJcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIHRocm93IGVycjtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBMaWtlIHtAbGluayBDb2xsZWN0aW9uVHJhbnNhY3Rpb24jdXBkYXRlfSwgYnV0IHdyYXBwZWQgaW4gaXRzIG93biB0cmFuc2FjdGlvbi5cbiAgICpcbiAgICogT3B0aW9uczpcbiAgICogLSB7Qm9vbGVhbn0gc3luY2VkOiBTZXRzIHJlY29yZCBzdGF0dXMgdG8gXCJzeW5jZWRcIiAoZGVmYXVsdDogZmFsc2UpXG4gICAqIC0ge0Jvb2xlYW59IHBhdGNoOiAgRXh0ZW5kcyB0aGUgZXhpc3RpbmcgcmVjb3JkIGluc3RlYWQgb2Ygb3ZlcndyaXRpbmcgaXRcbiAgICogICAoZGVmYXVsdDogZmFsc2UpXG4gICAqXG4gICAqIEBwYXJhbSAge09iamVjdH0gcmVjb3JkXG4gICAqIEBwYXJhbSAge09iamVjdH0gb3B0aW9uc1xuICAgKiBAcmV0dXJuIHtQcm9taXNlfVxuICAgKi9cbiAgdXBkYXRlKHJlY29yZCwgb3B0aW9ucyA9IHsgc3luY2VkOiBmYWxzZSwgcGF0Y2g6IGZhbHNlIH0pIHtcbiAgICAvLyBWYWxpZGF0ZSB0aGUgcmVjb3JkIGFuZCBpdHMgSUQsIGV2ZW4gdGhvdWdoIHRoaXMgdmFsaWRhdGlvbiBpc1xuICAgIC8vIGFsc28gZG9uZSBpbiB0aGUgQ29sbGVjdGlvblRyYW5zYWN0aW9uIG1ldGhvZCwgYmVjYXVzZSB3ZSBuZWVkXG4gICAgLy8gdG8gcGFzcyB0aGUgSUQgdG8gcHJlbG9hZElkcy5cbiAgICBpZiAodHlwZW9mIHJlY29yZCAhPT0gXCJvYmplY3RcIikge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcIlJlY29yZCBpcyBub3QgYW4gb2JqZWN0LlwiKSk7XG4gICAgfVxuICAgIGlmICghcmVjb3JkLmhhc093blByb3BlcnR5KFwiaWRcIikpIHtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJDYW5ub3QgdXBkYXRlIGEgcmVjb3JkIG1pc3NpbmcgaWQuXCIpKTtcbiAgICB9XG4gICAgaWYgKCF0aGlzLmlkU2NoZW1hLnZhbGlkYXRlKHJlY29yZC5pZCkpIHtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoYEludmFsaWQgSWQ6ICR7cmVjb3JkLmlkfWApKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5leGVjdXRlKHR4biA9PiB0eG4udXBkYXRlKHJlY29yZCwgb3B0aW9ucyksIHtcbiAgICAgIHByZWxvYWRJZHM6IFtyZWNvcmQuaWRdLFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIExpa2Uge0BsaW5rIENvbGxlY3Rpb25UcmFuc2FjdGlvbiN1cHNlcnR9LCBidXQgd3JhcHBlZCBpbiBpdHMgb3duIHRyYW5zYWN0aW9uLlxuICAgKlxuICAgKiBAcGFyYW0gIHtPYmplY3R9IHJlY29yZFxuICAgKiBAcmV0dXJuIHtQcm9taXNlfVxuICAgKi9cbiAgdXBzZXJ0KHJlY29yZCkge1xuICAgIC8vIFZhbGlkYXRlIHRoZSByZWNvcmQgYW5kIGl0cyBJRCwgZXZlbiB0aG91Z2ggdGhpcyB2YWxpZGF0aW9uIGlzXG4gICAgLy8gYWxzbyBkb25lIGluIHRoZSBDb2xsZWN0aW9uVHJhbnNhY3Rpb24gbWV0aG9kLCBiZWNhdXNlIHdlIG5lZWRcbiAgICAvLyB0byBwYXNzIHRoZSBJRCB0byBwcmVsb2FkSWRzLlxuICAgIGlmICh0eXBlb2YgcmVjb3JkICE9PSBcIm9iamVjdFwiKSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiUmVjb3JkIGlzIG5vdCBhbiBvYmplY3QuXCIpKTtcbiAgICB9XG4gICAgaWYgKCFyZWNvcmQuaGFzT3duUHJvcGVydHkoXCJpZFwiKSkge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcIkNhbm5vdCB1cGRhdGUgYSByZWNvcmQgbWlzc2luZyBpZC5cIikpO1xuICAgIH1cbiAgICBpZiAoIXRoaXMuaWRTY2hlbWEudmFsaWRhdGUocmVjb3JkLmlkKSkge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihgSW52YWxpZCBJZDogJHtyZWNvcmQuaWR9YCkpO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLmV4ZWN1dGUodHhuID0+IHR4bi51cHNlcnQocmVjb3JkKSwgeyBwcmVsb2FkSWRzOiBbcmVjb3JkLmlkXSB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBMaWtlIHtAbGluayBDb2xsZWN0aW9uVHJhbnNhY3Rpb24jZ2V0fSwgYnV0IHdyYXBwZWQgaW4gaXRzIG93biB0cmFuc2FjdGlvbi5cbiAgICpcbiAgICogT3B0aW9uczpcbiAgICogLSB7Qm9vbGVhbn0gaW5jbHVkZURlbGV0ZWQ6IEluY2x1ZGUgdmlydHVhbGx5IGRlbGV0ZWQgcmVjb3Jkcy5cbiAgICpcbiAgICogQHBhcmFtICB7U3RyaW5nfSBpZFxuICAgKiBAcGFyYW0gIHtPYmplY3R9IG9wdGlvbnNcbiAgICogQHJldHVybiB7UHJvbWlzZX1cbiAgICovXG4gIGdldChpZCwgb3B0aW9ucyA9IHsgaW5jbHVkZURlbGV0ZWQ6IGZhbHNlIH0pIHtcbiAgICByZXR1cm4gdGhpcy5leGVjdXRlKHR4biA9PiB0eG4uZ2V0KGlkLCBvcHRpb25zKSwgeyBwcmVsb2FkSWRzOiBbaWRdIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIExpa2Uge0BsaW5rIENvbGxlY3Rpb25UcmFuc2FjdGlvbiNnZXRBbnl9LCBidXQgd3JhcHBlZCBpbiBpdHMgb3duIHRyYW5zYWN0aW9uLlxuICAgKlxuICAgKiBAcGFyYW0gIHtTdHJpbmd9IGlkXG4gICAqIEByZXR1cm4ge1Byb21pc2V9XG4gICAqL1xuICBnZXRBbnkoaWQpIHtcbiAgICByZXR1cm4gdGhpcy5leGVjdXRlKHR4biA9PiB0eG4uZ2V0QW55KGlkKSwgeyBwcmVsb2FkSWRzOiBbaWRdIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFNhbWUgYXMge0BsaW5rIENvbGxlY3Rpb24jZGVsZXRlfSwgYnV0IHdyYXBwZWQgaW4gaXRzIG93biB0cmFuc2FjdGlvbi5cbiAgICpcbiAgICogT3B0aW9uczpcbiAgICogLSB7Qm9vbGVhbn0gdmlydHVhbDogV2hlbiBzZXQgdG8gYHRydWVgLCBkb2Vzbid0IGFjdHVhbGx5IGRlbGV0ZSB0aGUgcmVjb3JkLFxuICAgKiAgIHVwZGF0ZSBpdHMgYF9zdGF0dXNgIGF0dHJpYnV0ZSB0byBgZGVsZXRlZGAgaW5zdGVhZCAoZGVmYXVsdDogdHJ1ZSlcbiAgICpcbiAgICogQHBhcmFtICB7U3RyaW5nfSBpZCAgICAgICBUaGUgcmVjb3JkJ3MgSWQuXG4gICAqIEBwYXJhbSAge09iamVjdH0gb3B0aW9ucyAgVGhlIG9wdGlvbnMgb2JqZWN0LlxuICAgKiBAcmV0dXJuIHtQcm9taXNlfVxuICAgKi9cbiAgZGVsZXRlKGlkLCBvcHRpb25zID0geyB2aXJ0dWFsOiB0cnVlIH0pIHtcbiAgICByZXR1cm4gdGhpcy5leGVjdXRlKFxuICAgICAgdHJhbnNhY3Rpb24gPT4ge1xuICAgICAgICByZXR1cm4gdHJhbnNhY3Rpb24uZGVsZXRlKGlkLCBvcHRpb25zKTtcbiAgICAgIH0sXG4gICAgICB7IHByZWxvYWRJZHM6IFtpZF0gfVxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogU2FtZSBhcyB7QGxpbmsgQ29sbGVjdGlvbiNkZWxldGVBbGx9LCBidXQgd3JhcHBlZCBpbiBpdHMgb3duIHRyYW5zYWN0aW9uLCBleGVjdWxkaW5nIHRoZSBwYXJhbWV0ZXIuXG4gICAqXG4gICAqIEByZXR1cm4ge1Byb21pc2V9XG4gICAqL1xuICBhc3luYyBkZWxldGVBbGwoKSB7XG4gICAgY29uc3QgeyBkYXRhIH0gPSBhd2FpdCB0aGlzLmxpc3Qoe30sIHsgaW5jbHVkZURlbGV0ZWQ6IGZhbHNlIH0pO1xuICAgIGNvbnN0IHJlY29yZElkcyA9IGRhdGEubWFwKHJlY29yZCA9PiByZWNvcmQuaWQpO1xuICAgIHJldHVybiB0aGlzLmV4ZWN1dGUoXG4gICAgICB0cmFuc2FjdGlvbiA9PiB7XG4gICAgICAgIHJldHVybiB0cmFuc2FjdGlvbi5kZWxldGVBbGwocmVjb3JkSWRzKTtcbiAgICAgIH0sXG4gICAgICB7IHByZWxvYWRJZHM6IHJlY29yZElkcyB9XG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgc2FtZSBhcyB7QGxpbmsgQ29sbGVjdGlvblRyYW5zYWN0aW9uI2RlbGV0ZUFueX0sIGJ1dCB3cmFwcGVkXG4gICAqIGluIGl0cyBvd24gdHJhbnNhY3Rpb24uXG4gICAqXG4gICAqIEBwYXJhbSAge1N0cmluZ30gaWQgICAgICAgVGhlIHJlY29yZCdzIElkLlxuICAgKiBAcmV0dXJuIHtQcm9taXNlfVxuICAgKi9cbiAgZGVsZXRlQW55KGlkKSB7XG4gICAgcmV0dXJuIHRoaXMuZXhlY3V0ZSh0eG4gPT4gdHhuLmRlbGV0ZUFueShpZCksIHsgcHJlbG9hZElkczogW2lkXSB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBMaXN0cyByZWNvcmRzIGZyb20gdGhlIGxvY2FsIGRhdGFiYXNlLlxuICAgKlxuICAgKiBQYXJhbXM6XG4gICAqIC0ge09iamVjdH0gZmlsdGVycyBGaWx0ZXIgdGhlIHJlc3VsdHMgKGRlZmF1bHQ6IGB7fWApLlxuICAgKiAtIHtTdHJpbmd9IG9yZGVyICAgVGhlIG9yZGVyIHRvIGFwcGx5ICAgKGRlZmF1bHQ6IGAtbGFzdF9tb2RpZmllZGApLlxuICAgKlxuICAgKiBPcHRpb25zOlxuICAgKiAtIHtCb29sZWFufSBpbmNsdWRlRGVsZXRlZDogSW5jbHVkZSB2aXJ0dWFsbHkgZGVsZXRlZCByZWNvcmRzLlxuICAgKlxuICAgKiBAcGFyYW0gIHtPYmplY3R9IHBhcmFtcyAgVGhlIGZpbHRlcnMgYW5kIG9yZGVyIHRvIGFwcGx5IHRvIHRoZSByZXN1bHRzLlxuICAgKiBAcGFyYW0gIHtPYmplY3R9IG9wdGlvbnMgVGhlIG9wdGlvbnMgb2JqZWN0LlxuICAgKiBAcmV0dXJuIHtQcm9taXNlfVxuICAgKi9cbiAgYXN5bmMgbGlzdChwYXJhbXMgPSB7fSwgb3B0aW9ucyA9IHsgaW5jbHVkZURlbGV0ZWQ6IGZhbHNlIH0pIHtcbiAgICBwYXJhbXMgPSB7IG9yZGVyOiBcIi1sYXN0X21vZGlmaWVkXCIsIGZpbHRlcnM6IHt9LCAuLi5wYXJhbXMgfTtcbiAgICBjb25zdCByZXN1bHRzID0gYXdhaXQgdGhpcy5kYi5saXN0KHBhcmFtcyk7XG4gICAgbGV0IGRhdGEgPSByZXN1bHRzO1xuICAgIGlmICghb3B0aW9ucy5pbmNsdWRlRGVsZXRlZCkge1xuICAgICAgZGF0YSA9IHJlc3VsdHMuZmlsdGVyKHJlY29yZCA9PiByZWNvcmQuX3N0YXR1cyAhPT0gXCJkZWxldGVkXCIpO1xuICAgIH1cbiAgICByZXR1cm4geyBkYXRhLCBwZXJtaXNzaW9uczoge30gfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBJbXBvcnRzIHJlbW90ZSBjaGFuZ2VzIGludG8gdGhlIGxvY2FsIGRhdGFiYXNlLlxuICAgKiBUaGlzIG1ldGhvZCBpcyBpbiBjaGFyZ2Ugb2YgZGV0ZWN0aW5nIHRoZSBjb25mbGljdHMsIGFuZCByZXNvbHZlIHRoZW1cbiAgICogYWNjb3JkaW5nIHRvIHRoZSBzcGVjaWZpZWQgc3RyYXRlZ3kuXG4gICAqIEBwYXJhbSAge1N5bmNSZXN1bHRPYmplY3R9IHN5bmNSZXN1bHRPYmplY3QgVGhlIHN5bmMgcmVzdWx0IG9iamVjdC5cbiAgICogQHBhcmFtICB7QXJyYXl9ICAgICAgICAgICAgZGVjb2RlZENoYW5nZXMgICBUaGUgbGlzdCBvZiBjaGFuZ2VzIHRvIGltcG9ydCBpbiB0aGUgbG9jYWwgZGF0YWJhc2UuXG4gICAqIEBwYXJhbSAge1N0cmluZ30gICAgICAgICAgIHN0cmF0ZWd5ICAgICAgICAgVGhlIHtAbGluayBDb2xsZWN0aW9uLnN0cmF0ZWd5fSAoZGVmYXVsdDogTUFOVUFMKVxuICAgKiBAcmV0dXJuIHtQcm9taXNlfVxuICAgKi9cbiAgYXN5bmMgaW1wb3J0Q2hhbmdlcyhcbiAgICBzeW5jUmVzdWx0T2JqZWN0LFxuICAgIGRlY29kZWRDaGFuZ2VzLFxuICAgIHN0cmF0ZWd5ID0gQ29sbGVjdGlvbi5zdHJhdGVneS5NQU5VQUxcbiAgKSB7XG4gICAgLy8gUmV0cmlldmUgcmVjb3JkcyBtYXRjaGluZyBjaGFuZ2UgaWRzLlxuICAgIHRyeSB7XG4gICAgICBjb25zdCB7IGltcG9ydHMsIHJlc29sdmVkIH0gPSBhd2FpdCB0aGlzLmRiLmV4ZWN1dGUoXG4gICAgICAgIHRyYW5zYWN0aW9uID0+IHtcbiAgICAgICAgICBjb25zdCBpbXBvcnRzID0gZGVjb2RlZENoYW5nZXMubWFwKHJlbW90ZSA9PiB7XG4gICAgICAgICAgICAvLyBTdG9yZSByZW1vdGUgY2hhbmdlIGludG8gbG9jYWwgZGF0YWJhc2UuXG4gICAgICAgICAgICByZXR1cm4gaW1wb3J0Q2hhbmdlKHRyYW5zYWN0aW9uLCByZW1vdGUsIHRoaXMubG9jYWxGaWVsZHMpO1xuICAgICAgICAgIH0pO1xuICAgICAgICAgIGNvbnN0IGNvbmZsaWN0cyA9IGltcG9ydHNcbiAgICAgICAgICAgIC5maWx0ZXIoaSA9PiBpLnR5cGUgPT09IFwiY29uZmxpY3RzXCIpXG4gICAgICAgICAgICAubWFwKGkgPT4gaS5kYXRhKTtcbiAgICAgICAgICBjb25zdCByZXNvbHZlZCA9IHRoaXMuX2hhbmRsZUNvbmZsaWN0cyhcbiAgICAgICAgICAgIHRyYW5zYWN0aW9uLFxuICAgICAgICAgICAgY29uZmxpY3RzLFxuICAgICAgICAgICAgc3RyYXRlZ3lcbiAgICAgICAgICApO1xuICAgICAgICAgIHJldHVybiB7IGltcG9ydHMsIHJlc29sdmVkIH07XG4gICAgICAgIH0sXG4gICAgICAgIHsgcHJlbG9hZDogZGVjb2RlZENoYW5nZXMubWFwKHJlY29yZCA9PiByZWNvcmQuaWQpIH1cbiAgICAgICk7XG5cbiAgICAgIC8vIExpc3RzIG9mIGNyZWF0ZWQvdXBkYXRlZC9kZWxldGVkIHJlY29yZHNcbiAgICAgIGltcG9ydHMuZm9yRWFjaCgoeyB0eXBlLCBkYXRhIH0pID0+IHN5bmNSZXN1bHRPYmplY3QuYWRkKHR5cGUsIGRhdGEpKTtcblxuICAgICAgLy8gQXV0b21hdGljYWxseSByZXNvbHZlZCBjb25mbGljdHMgKGlmIG5vdCBtYW51YWwpXG4gICAgICBpZiAocmVzb2x2ZWQubGVuZ3RoID4gMCkge1xuICAgICAgICBzeW5jUmVzdWx0T2JqZWN0LnJlc2V0KFwiY29uZmxpY3RzXCIpLmFkZChcInJlc29sdmVkXCIsIHJlc29sdmVkKTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIGNvbnN0IGRhdGEgPSB7XG4gICAgICAgIHR5cGU6IFwiaW5jb21pbmdcIixcbiAgICAgICAgbWVzc2FnZTogZXJyLm1lc3NhZ2UsXG4gICAgICAgIHN0YWNrOiBlcnIuc3RhY2ssXG4gICAgICB9O1xuICAgICAgLy8gWFhYIG9uZSBlcnJvciBvZiB0aGUgd2hvbGUgdHJhbnNhY3Rpb24gaW5zdGVhZCBvZiBwZXIgYXRvbWljIG9wXG4gICAgICBzeW5jUmVzdWx0T2JqZWN0LmFkZChcImVycm9yc1wiLCBkYXRhKTtcbiAgICB9XG5cbiAgICByZXR1cm4gc3luY1Jlc3VsdE9iamVjdDtcbiAgfVxuXG4gIC8qKlxuICAgKiBJbXBvcnRzIHRoZSByZXNwb25zZXMgb2YgcHVzaGVkIGNoYW5nZXMgaW50byB0aGUgbG9jYWwgZGF0YWJhc2UuXG4gICAqIEJhc2ljYWxseSBpdCBzdG9yZXMgdGhlIHRpbWVzdGFtcCBhc3NpZ25lZCBieSB0aGUgc2VydmVyIGludG8gdGhlIGxvY2FsXG4gICAqIGRhdGFiYXNlLlxuICAgKiBAcGFyYW0gIHtTeW5jUmVzdWx0T2JqZWN0fSBzeW5jUmVzdWx0T2JqZWN0IFRoZSBzeW5jIHJlc3VsdCBvYmplY3QuXG4gICAqIEBwYXJhbSAge0FycmF5fSAgICAgICAgICAgIHRvQXBwbHlMb2NhbGx5ICAgVGhlIGxpc3Qgb2YgY2hhbmdlcyB0byBpbXBvcnQgaW4gdGhlIGxvY2FsIGRhdGFiYXNlLlxuICAgKiBAcGFyYW0gIHtBcnJheX0gICAgICAgICAgICBjb25mbGljdHMgICAgICAgIFRoZSBsaXN0IG9mIGNvbmZsaWN0cyB0aGF0IGhhdmUgdG8gYmUgcmVzb2x2ZWQuXG4gICAqIEBwYXJhbSAge1N0cmluZ30gICAgICAgICAgIHN0cmF0ZWd5ICAgICAgICAgVGhlIHtAbGluayBDb2xsZWN0aW9uLnN0cmF0ZWd5fS5cbiAgICogQHJldHVybiB7UHJvbWlzZX1cbiAgICovXG4gIGFzeW5jIF9hcHBseVB1c2hlZFJlc3VsdHMoXG4gICAgc3luY1Jlc3VsdE9iamVjdCxcbiAgICB0b0FwcGx5TG9jYWxseSxcbiAgICBjb25mbGljdHMsXG4gICAgc3RyYXRlZ3kgPSBDb2xsZWN0aW9uLnN0cmF0ZWd5Lk1BTlVBTFxuICApIHtcbiAgICBjb25zdCB0b0RlbGV0ZUxvY2FsbHkgPSB0b0FwcGx5TG9jYWxseS5maWx0ZXIociA9PiByLmRlbGV0ZWQpO1xuICAgIGNvbnN0IHRvVXBkYXRlTG9jYWxseSA9IHRvQXBwbHlMb2NhbGx5LmZpbHRlcihyID0+ICFyLmRlbGV0ZWQpO1xuXG4gICAgY29uc3QgeyBwdWJsaXNoZWQsIHJlc29sdmVkIH0gPSBhd2FpdCB0aGlzLmRiLmV4ZWN1dGUodHJhbnNhY3Rpb24gPT4ge1xuICAgICAgY29uc3QgdXBkYXRlZCA9IHRvVXBkYXRlTG9jYWxseS5tYXAocmVjb3JkID0+IHtcbiAgICAgICAgY29uc3Qgc3luY2VkID0gbWFya1N5bmNlZChyZWNvcmQpO1xuICAgICAgICB0cmFuc2FjdGlvbi51cGRhdGUoc3luY2VkKTtcbiAgICAgICAgcmV0dXJuIHN5bmNlZDtcbiAgICAgIH0pO1xuICAgICAgY29uc3QgZGVsZXRlZCA9IHRvRGVsZXRlTG9jYWxseS5tYXAocmVjb3JkID0+IHtcbiAgICAgICAgdHJhbnNhY3Rpb24uZGVsZXRlKHJlY29yZC5pZCk7XG4gICAgICAgIC8vIEFtZW5kIHJlc3VsdCBkYXRhIHdpdGggdGhlIGRlbGV0ZWQgYXR0cmlidXRlIHNldFxuICAgICAgICByZXR1cm4geyBpZDogcmVjb3JkLmlkLCBkZWxldGVkOiB0cnVlIH07XG4gICAgICB9KTtcbiAgICAgIGNvbnN0IHB1Ymxpc2hlZCA9IHVwZGF0ZWQuY29uY2F0KGRlbGV0ZWQpO1xuICAgICAgLy8gSGFuZGxlIGNvbmZsaWN0cywgaWYgYW55XG4gICAgICBjb25zdCByZXNvbHZlZCA9IHRoaXMuX2hhbmRsZUNvbmZsaWN0cyh0cmFuc2FjdGlvbiwgY29uZmxpY3RzLCBzdHJhdGVneSk7XG4gICAgICByZXR1cm4geyBwdWJsaXNoZWQsIHJlc29sdmVkIH07XG4gICAgfSk7XG5cbiAgICBzeW5jUmVzdWx0T2JqZWN0LmFkZChcInB1Ymxpc2hlZFwiLCBwdWJsaXNoZWQpO1xuXG4gICAgaWYgKHJlc29sdmVkLmxlbmd0aCA+IDApIHtcbiAgICAgIHN5bmNSZXN1bHRPYmplY3RcbiAgICAgICAgLnJlc2V0KFwiY29uZmxpY3RzXCIpXG4gICAgICAgIC5yZXNldChcInJlc29sdmVkXCIpXG4gICAgICAgIC5hZGQoXCJyZXNvbHZlZFwiLCByZXNvbHZlZCk7XG4gICAgfVxuICAgIHJldHVybiBzeW5jUmVzdWx0T2JqZWN0O1xuICB9XG5cbiAgLyoqXG4gICAqIEhhbmRsZXMgc3luY2hyb25pemF0aW9uIGNvbmZsaWN0cyBhY2NvcmRpbmcgdG8gc3BlY2lmaWVkIHN0cmF0ZWd5LlxuICAgKlxuICAgKiBAcGFyYW0gIHtTeW5jUmVzdWx0T2JqZWN0fSByZXN1bHQgICAgVGhlIHN5bmMgcmVzdWx0IG9iamVjdC5cbiAgICogQHBhcmFtICB7U3RyaW5nfSAgICAgICAgICAgc3RyYXRlZ3kgIFRoZSB7QGxpbmsgQ29sbGVjdGlvbi5zdHJhdGVneX0uXG4gICAqIEByZXR1cm4ge1Byb21pc2U8QXJyYXk8T2JqZWN0Pj59IFRoZSByZXNvbHZlZCBjb25mbGljdHMsIGFzIGFuXG4gICAqICAgIGFycmF5IG9mIHthY2NlcHRlZCwgcmVqZWN0ZWR9IG9iamVjdHNcbiAgICovXG4gIF9oYW5kbGVDb25mbGljdHModHJhbnNhY3Rpb24sIGNvbmZsaWN0cywgc3RyYXRlZ3kpIHtcbiAgICBpZiAoc3RyYXRlZ3kgPT09IENvbGxlY3Rpb24uc3RyYXRlZ3kuTUFOVUFMKSB7XG4gICAgICByZXR1cm4gW107XG4gICAgfVxuICAgIHJldHVybiBjb25mbGljdHMubWFwKGNvbmZsaWN0ID0+IHtcbiAgICAgIGNvbnN0IHJlc29sdXRpb24gPVxuICAgICAgICBzdHJhdGVneSA9PT0gQ29sbGVjdGlvbi5zdHJhdGVneS5DTElFTlRfV0lOU1xuICAgICAgICAgID8gY29uZmxpY3QubG9jYWxcbiAgICAgICAgICA6IGNvbmZsaWN0LnJlbW90ZTtcbiAgICAgIGNvbnN0IHJlamVjdGVkID1cbiAgICAgICAgc3RyYXRlZ3kgPT09IENvbGxlY3Rpb24uc3RyYXRlZ3kuQ0xJRU5UX1dJTlNcbiAgICAgICAgICA/IGNvbmZsaWN0LnJlbW90ZVxuICAgICAgICAgIDogY29uZmxpY3QubG9jYWw7XG4gICAgICBsZXQgYWNjZXB0ZWQsIHN0YXR1cywgaWQ7XG4gICAgICBpZiAocmVzb2x1dGlvbiA9PT0gbnVsbCkge1xuICAgICAgICAvLyBXZSBcInJlc29sdmVkXCIgd2l0aCB0aGUgc2VydmVyLXNpZGUgZGVsZXRpb24uIERlbGV0ZSBsb2NhbGx5LlxuICAgICAgICAvLyBUaGlzIG9ubHkgaGFwcGVucyBkdXJpbmcgU0VSVkVSX1dJTlMgYmVjYXVzZSB0aGUgbG9jYWxcbiAgICAgICAgLy8gdmVyc2lvbiBvZiBhIHJlY29yZCBjYW4gbmV2ZXIgYmUgbnVsbC5cbiAgICAgICAgLy8gV2UgY2FuIGdldCBcIm51bGxcIiBmcm9tIHRoZSByZW1vdGUgc2lkZSBpZiB3ZSBnb3QgYSBjb25mbGljdFxuICAgICAgICAvLyBhbmQgdGhlcmUgaXMgbm8gcmVtb3RlIHZlcnNpb24gYXZhaWxhYmxlOyBzZWUga2ludG8taHR0cC5qc1xuICAgICAgICAvLyBiYXRjaC5qczphZ2dyZWdhdGUuXG4gICAgICAgIHRyYW5zYWN0aW9uLmRlbGV0ZShjb25mbGljdC5sb2NhbC5pZCk7XG4gICAgICAgIGFjY2VwdGVkID0gbnVsbDtcbiAgICAgICAgLy8gVGhlIHJlY29yZCB3YXMgZGVsZXRlZCwgYnV0IHRoYXQgc3RhdHVzIGlzIFwic3luY2VkXCIgd2l0aFxuICAgICAgICAvLyB0aGUgc2VydmVyLCBzbyB3ZSBkb24ndCBuZWVkIHRvIHB1c2ggdGhlIGNoYW5nZS5cbiAgICAgICAgc3RhdHVzID0gXCJzeW5jZWRcIjtcbiAgICAgICAgaWQgPSBjb25mbGljdC5sb2NhbC5pZDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnN0IHVwZGF0ZWQgPSB0aGlzLl9yZXNvbHZlUmF3KGNvbmZsaWN0LCByZXNvbHV0aW9uKTtcbiAgICAgICAgdHJhbnNhY3Rpb24udXBkYXRlKHVwZGF0ZWQpO1xuICAgICAgICBhY2NlcHRlZCA9IHVwZGF0ZWQ7XG4gICAgICAgIHN0YXR1cyA9IHVwZGF0ZWQuX3N0YXR1cztcbiAgICAgICAgaWQgPSB1cGRhdGVkLmlkO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHsgcmVqZWN0ZWQsIGFjY2VwdGVkLCBpZCwgX3N0YXR1czogc3RhdHVzIH07XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogRXhlY3V0ZSBhIGJ1bmNoIG9mIG9wZXJhdGlvbnMgaW4gYSB0cmFuc2FjdGlvbi5cbiAgICpcbiAgICogVGhpcyB0cmFuc2FjdGlvbiBzaG91bGQgYmUgYXRvbWljIC0tIGVpdGhlciBhbGwgb2YgaXRzIG9wZXJhdGlvbnNcbiAgICogd2lsbCBzdWNjZWVkLCBvciBub25lIHdpbGwuXG4gICAqXG4gICAqIFRoZSBhcmd1bWVudCB0byB0aGlzIGZ1bmN0aW9uIGlzIGl0c2VsZiBhIGZ1bmN0aW9uIHdoaWNoIHdpbGwgYmVcbiAgICogY2FsbGVkIHdpdGggYSB7QGxpbmsgQ29sbGVjdGlvblRyYW5zYWN0aW9ufS4gQ29sbGVjdGlvbiBtZXRob2RzXG4gICAqIGFyZSBhdmFpbGFibGUgb24gdGhpcyB0cmFuc2FjdGlvbiwgYnV0IGluc3RlYWQgb2YgcmV0dXJuaW5nXG4gICAqIHByb21pc2VzLCB0aGV5IGFyZSBzeW5jaHJvbm91cy4gZXhlY3V0ZSgpIHJldHVybnMgYSBQcm9taXNlIHdob3NlXG4gICAqIHZhbHVlIHdpbGwgYmUgdGhlIHJldHVybiB2YWx1ZSBvZiB0aGUgcHJvdmlkZWQgZnVuY3Rpb24uXG4gICAqXG4gICAqIE1vc3Qgb3BlcmF0aW9ucyB3aWxsIHJlcXVpcmUgYWNjZXNzIHRvIHRoZSByZWNvcmQgaXRzZWxmLCB3aGljaFxuICAgKiBtdXN0IGJlIHByZWxvYWRlZCBieSBwYXNzaW5nIGl0cyBJRCBpbiB0aGUgcHJlbG9hZElkcyBvcHRpb24uXG4gICAqXG4gICAqIE9wdGlvbnM6XG4gICAqIC0ge0FycmF5fSBwcmVsb2FkSWRzOiBsaXN0IG9mIElEcyB0byBmZXRjaCBhdCB0aGUgYmVnaW5uaW5nIG9mXG4gICAqICAgdGhlIHRyYW5zYWN0aW9uXG4gICAqXG4gICAqIEByZXR1cm4ge1Byb21pc2V9IFJlc29sdmVzIHdpdGggdGhlIHJlc3VsdCBvZiB0aGUgZ2l2ZW4gZnVuY3Rpb25cbiAgICogICAgd2hlbiB0aGUgdHJhbnNhY3Rpb24gY29tbWl0cy5cbiAgICovXG4gIGV4ZWN1dGUoZG9PcGVyYXRpb25zLCB7IHByZWxvYWRJZHMgPSBbXSB9ID0ge30pIHtcbiAgICBmb3IgKGNvbnN0IGlkIG9mIHByZWxvYWRJZHMpIHtcbiAgICAgIGlmICghdGhpcy5pZFNjaGVtYS52YWxpZGF0ZShpZCkpIHtcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KEVycm9yKGBJbnZhbGlkIElkOiAke2lkfWApKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5kYi5leGVjdXRlKFxuICAgICAgdHJhbnNhY3Rpb24gPT4ge1xuICAgICAgICBjb25zdCB0eG4gPSBuZXcgQ29sbGVjdGlvblRyYW5zYWN0aW9uKHRoaXMsIHRyYW5zYWN0aW9uKTtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gZG9PcGVyYXRpb25zKHR4bik7XG4gICAgICAgIHR4bi5lbWl0RXZlbnRzKCk7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9LFxuICAgICAgeyBwcmVsb2FkOiBwcmVsb2FkSWRzIH1cbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlc2V0cyB0aGUgbG9jYWwgcmVjb3JkcyBhcyBpZiB0aGV5IHdlcmUgbmV2ZXIgc3luY2VkOyBleGlzdGluZyByZWNvcmRzIGFyZVxuICAgKiBtYXJrZWQgYXMgbmV3bHkgY3JlYXRlZCwgZGVsZXRlZCByZWNvcmRzIGFyZSBkcm9wcGVkLlxuICAgKlxuICAgKiBBIG5leHQgY2FsbCB0byB7QGxpbmsgQ29sbGVjdGlvbi5zeW5jfSB3aWxsIHRodXMgcmVwdWJsaXNoIHRoZSB3aG9sZVxuICAgKiBjb250ZW50IG9mIHRoZSBsb2NhbCBjb2xsZWN0aW9uIHRvIHRoZSBzZXJ2ZXIuXG4gICAqXG4gICAqIEByZXR1cm4ge1Byb21pc2V9IFJlc29sdmVzIHdpdGggdGhlIG51bWJlciBvZiBwcm9jZXNzZWQgcmVjb3Jkcy5cbiAgICovXG4gIGFzeW5jIHJlc2V0U3luY1N0YXR1cygpIHtcbiAgICBjb25zdCB1bnN5bmNlZCA9IGF3YWl0IHRoaXMubGlzdChcbiAgICAgIHsgZmlsdGVyczogeyBfc3RhdHVzOiBbXCJkZWxldGVkXCIsIFwic3luY2VkXCJdIH0sIG9yZGVyOiBcIlwiIH0sXG4gICAgICB7IGluY2x1ZGVEZWxldGVkOiB0cnVlIH1cbiAgICApO1xuICAgIGF3YWl0IHRoaXMuZGIuZXhlY3V0ZSh0cmFuc2FjdGlvbiA9PiB7XG4gICAgICB1bnN5bmNlZC5kYXRhLmZvckVhY2gocmVjb3JkID0+IHtcbiAgICAgICAgaWYgKHJlY29yZC5fc3RhdHVzID09PSBcImRlbGV0ZWRcIikge1xuICAgICAgICAgIC8vIEdhcmJhZ2UgY29sbGVjdCBkZWxldGVkIHJlY29yZHMuXG4gICAgICAgICAgdHJhbnNhY3Rpb24uZGVsZXRlKHJlY29yZC5pZCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gUmVjb3JkcyB0aGF0IHdlcmUgc3luY2VkIGJlY29tZSDCq2NyZWF0ZWTCuy5cbiAgICAgICAgICB0cmFuc2FjdGlvbi51cGRhdGUoe1xuICAgICAgICAgICAgLi4ucmVjb3JkLFxuICAgICAgICAgICAgbGFzdF9tb2RpZmllZDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgX3N0YXR1czogXCJjcmVhdGVkXCIsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH0pO1xuICAgIHRoaXMuX2xhc3RNb2RpZmllZCA9IG51bGw7XG4gICAgYXdhaXQgdGhpcy5kYi5zYXZlTGFzdE1vZGlmaWVkKG51bGwpO1xuICAgIHJldHVybiB1bnN5bmNlZC5kYXRhLmxlbmd0aDtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGFuIG9iamVjdCBjb250YWluaW5nIHR3byBsaXN0czpcbiAgICpcbiAgICogLSBgdG9EZWxldGVgOiB1bnN5bmNlZCBkZWxldGVkIHJlY29yZHMgd2UgY2FuIHNhZmVseSBkZWxldGU7XG4gICAqIC0gYHRvU3luY2A6IGxvY2FsIHVwZGF0ZXMgdG8gc2VuZCB0byB0aGUgc2VydmVyLlxuICAgKlxuICAgKiBAcmV0dXJuIHtQcm9taXNlfVxuICAgKi9cbiAgYXN5bmMgZ2F0aGVyTG9jYWxDaGFuZ2VzKCkge1xuICAgIGNvbnN0IHVuc3luY2VkID0gYXdhaXQgdGhpcy5saXN0KHtcbiAgICAgIGZpbHRlcnM6IHsgX3N0YXR1czogW1wiY3JlYXRlZFwiLCBcInVwZGF0ZWRcIl0gfSxcbiAgICAgIG9yZGVyOiBcIlwiLFxuICAgIH0pO1xuICAgIGNvbnN0IGRlbGV0ZWQgPSBhd2FpdCB0aGlzLmxpc3QoXG4gICAgICB7IGZpbHRlcnM6IHsgX3N0YXR1czogXCJkZWxldGVkXCIgfSwgb3JkZXI6IFwiXCIgfSxcbiAgICAgIHsgaW5jbHVkZURlbGV0ZWQ6IHRydWUgfVxuICAgICk7XG5cbiAgICByZXR1cm4gYXdhaXQgUHJvbWlzZS5hbGwoXG4gICAgICB1bnN5bmNlZC5kYXRhXG4gICAgICAgIC5jb25jYXQoZGVsZXRlZC5kYXRhKVxuICAgICAgICAubWFwKHRoaXMuX2VuY29kZVJlY29yZC5iaW5kKHRoaXMsIFwicmVtb3RlXCIpKVxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogRmV0Y2ggcmVtb3RlIGNoYW5nZXMsIGltcG9ydCB0aGVtIHRvIHRoZSBsb2NhbCBkYXRhYmFzZSwgYW5kIGhhbmRsZVxuICAgKiBjb25mbGljdHMgYWNjb3JkaW5nIHRvIGBvcHRpb25zLnN0cmF0ZWd5YC4gVGhlbiwgdXBkYXRlcyB0aGUgcGFzc2VkXG4gICAqIHtAbGluayBTeW5jUmVzdWx0T2JqZWN0fSB3aXRoIGltcG9ydCByZXN1bHRzLlxuICAgKlxuICAgKiBPcHRpb25zOlxuICAgKiAtIHtTdHJpbmd9IHN0cmF0ZWd5OiBUaGUgc2VsZWN0ZWQgc3luYyBzdHJhdGVneS5cbiAgICogLSB7U3RyaW5nfSBleHBlY3RlZFRpbWVzdGFtcDogQSB0aW1lc3RhbXAgdG8gdXNlIGFzIGEgXCJjYWNoZSBidXN0aW5nXCIgcXVlcnkgcGFyYW1ldGVyLlxuICAgKiAtIHtBcnJheTxTdHJpbmc+fSBleGNsdWRlOiBBIGxpc3Qgb2YgcmVjb3JkIGlkcyB0byBleGNsdWRlIGZyb20gcHVsbC5cbiAgICogLSB7T2JqZWN0fSBoZWFkZXJzOiBUaGUgSFRUUCBoZWFkZXJzIHRvIHVzZSBpbiB0aGUgcmVxdWVzdC5cbiAgICogLSB7aW50fSByZXRyeTogVGhlIG51bWJlciBvZiByZXRyaWVzIHRvIGRvIGlmIHRoZSBIVFRQIHJlcXVlc3QgZmFpbHMuXG4gICAqIC0ge2ludH0gbGFzdE1vZGlmaWVkOiBUaGUgdGltZXN0YW1wIHRvIHVzZSBpbiBgP19zaW5jZWAgcXVlcnkuXG4gICAqXG4gICAqIEBwYXJhbSAge0tpbnRvQ2xpZW50LkNvbGxlY3Rpb259IGNsaWVudCAgICAgICAgICAgS2ludG8gY2xpZW50IENvbGxlY3Rpb24gaW5zdGFuY2UuXG4gICAqIEBwYXJhbSAge1N5bmNSZXN1bHRPYmplY3R9ICAgICAgIHN5bmNSZXN1bHRPYmplY3QgVGhlIHN5bmMgcmVzdWx0IG9iamVjdC5cbiAgICogQHBhcmFtICB7T2JqZWN0fSAgICAgICAgICAgICAgICAgb3B0aW9ucyAgICAgICAgICBUaGUgb3B0aW9ucyBvYmplY3QuXG4gICAqIEByZXR1cm4ge1Byb21pc2V9XG4gICAqL1xuICBhc3luYyBwdWxsQ2hhbmdlcyhjbGllbnQsIHN5bmNSZXN1bHRPYmplY3QsIG9wdGlvbnMgPSB7fSkge1xuICAgIGlmICghc3luY1Jlc3VsdE9iamVjdC5vaykge1xuICAgICAgcmV0dXJuIHN5bmNSZXN1bHRPYmplY3Q7XG4gICAgfVxuXG4gICAgY29uc3Qgc2luY2UgPSB0aGlzLmxhc3RNb2RpZmllZFxuICAgICAgPyB0aGlzLmxhc3RNb2RpZmllZFxuICAgICAgOiBhd2FpdCB0aGlzLmRiLmdldExhc3RNb2RpZmllZCgpO1xuXG4gICAgb3B0aW9ucyA9IHtcbiAgICAgIHN0cmF0ZWd5OiBDb2xsZWN0aW9uLnN0cmF0ZWd5Lk1BTlVBTCxcbiAgICAgIGxhc3RNb2RpZmllZDogc2luY2UsXG4gICAgICBoZWFkZXJzOiB7fSxcbiAgICAgIC4uLm9wdGlvbnMsXG4gICAgfTtcblxuICAgIC8vIE9wdGlvbmFsbHkgaWdub3JlIHNvbWUgcmVjb3JkcyB3aGVuIHB1bGxpbmcgZm9yIGNoYW5nZXMuXG4gICAgLy8gKGF2b2lkIHJlZG93bmxvYWRpbmcgb3VyIG93biBjaGFuZ2VzIG9uIGxhc3Qgc3RlcCBvZiAjc3luYygpKVxuICAgIGxldCBmaWx0ZXJzO1xuICAgIGlmIChvcHRpb25zLmV4Y2x1ZGUpIHtcbiAgICAgIC8vIExpbWl0IHRoZSBsaXN0IG9mIGV4Y2x1ZGVkIHJlY29yZHMgdG8gdGhlIGZpcnN0IDUwIHJlY29yZHMgaW4gb3JkZXJcbiAgICAgIC8vIHRvIHJlbWFpbiB1bmRlciBkZS1mYWN0byBVUkwgc2l6ZSBsaW1pdCAofjIwMDAgY2hhcnMpLlxuICAgICAgLy8gaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy80MTcxNDIvd2hhdC1pcy10aGUtbWF4aW11bS1sZW5ndGgtb2YtYS11cmwtaW4tZGlmZmVyZW50LWJyb3dzZXJzLzQxNzE4NCM0MTcxODRcbiAgICAgIGNvbnN0IGV4Y2x1ZGVfaWQgPSBvcHRpb25zLmV4Y2x1ZGVcbiAgICAgICAgLnNsaWNlKDAsIDUwKVxuICAgICAgICAubWFwKHIgPT4gci5pZClcbiAgICAgICAgLmpvaW4oXCIsXCIpO1xuICAgICAgZmlsdGVycyA9IHsgZXhjbHVkZV9pZCB9O1xuICAgIH1cbiAgICBpZiAob3B0aW9ucy5leHBlY3RlZFRpbWVzdGFtcCkge1xuICAgICAgZmlsdGVycyA9IHtcbiAgICAgICAgLi4uZmlsdGVycyxcbiAgICAgICAgX2V4cGVjdGVkOiBvcHRpb25zLmV4cGVjdGVkVGltZXN0YW1wLFxuICAgICAgfTtcbiAgICB9XG4gICAgLy8gRmlyc3QgZmV0Y2ggcmVtb3RlIGNoYW5nZXMgZnJvbSB0aGUgc2VydmVyXG4gICAgY29uc3QgeyBkYXRhLCBsYXN0X21vZGlmaWVkIH0gPSBhd2FpdCBjbGllbnQubGlzdFJlY29yZHMoe1xuICAgICAgLy8gU2luY2Ugc2hvdWxkIGJlIEVUYWcgKHNlZSBodHRwczovL2dpdGh1Yi5jb20vS2ludG8va2ludG8uanMvaXNzdWVzLzM1NilcbiAgICAgIHNpbmNlOiBvcHRpb25zLmxhc3RNb2RpZmllZCA/IGAke29wdGlvbnMubGFzdE1vZGlmaWVkfWAgOiB1bmRlZmluZWQsXG4gICAgICBoZWFkZXJzOiBvcHRpb25zLmhlYWRlcnMsXG4gICAgICByZXRyeTogb3B0aW9ucy5yZXRyeSxcbiAgICAgIC8vIEZldGNoIGV2ZXJ5IHBhZ2UgYnkgZGVmYXVsdCAoRklYTUU6IG9wdGlvbiB0byBsaW1pdCBwYWdlcywgc2VlICMyNzcpXG4gICAgICBwYWdlczogSW5maW5pdHksXG4gICAgICBmaWx0ZXJzLFxuICAgIH0pO1xuICAgIC8vIGxhc3RfbW9kaWZpZWQgaXMgdGhlIEVUYWcgaGVhZGVyIHZhbHVlIChzdHJpbmcpLlxuICAgIC8vIEZvciByZXRyby1jb21wYXRpYmlsaXR5IHdpdGggZmlyc3Qga2ludG8uanMgdmVyc2lvbnNcbiAgICAvLyBwYXJzZSBpdCB0byBpbnRlZ2VyLlxuICAgIGNvbnN0IHVucXVvdGVkID0gbGFzdF9tb2RpZmllZCA/IHBhcnNlSW50KGxhc3RfbW9kaWZpZWQsIDEwKSA6IHVuZGVmaW5lZDtcblxuICAgIC8vIENoZWNrIGlmIHNlcnZlciB3YXMgZmx1c2hlZC5cbiAgICAvLyBUaGlzIGlzIHJlbGV2YW50IGZvciB0aGUgS2ludG8gZGVtbyBzZXJ2ZXJcbiAgICAvLyAoYW5kIHRodXMgZm9yIG1hbnkgbmV3IGNvbWVycykuXG4gICAgY29uc3QgbG9jYWxTeW5jZWQgPSBvcHRpb25zLmxhc3RNb2RpZmllZDtcbiAgICBjb25zdCBzZXJ2ZXJDaGFuZ2VkID0gdW5xdW90ZWQgPiBvcHRpb25zLmxhc3RNb2RpZmllZDtcbiAgICBjb25zdCBlbXB0eUNvbGxlY3Rpb24gPSBkYXRhLmxlbmd0aCA9PT0gMDtcbiAgICBpZiAoIW9wdGlvbnMuZXhjbHVkZSAmJiBsb2NhbFN5bmNlZCAmJiBzZXJ2ZXJDaGFuZ2VkICYmIGVtcHR5Q29sbGVjdGlvbikge1xuICAgICAgY29uc3QgZSA9IG5ldyBTZXJ2ZXJXYXNGbHVzaGVkRXJyb3IoXG4gICAgICAgIGxvY2FsU3luY2VkLFxuICAgICAgICB1bnF1b3RlZCxcbiAgICAgICAgXCJTZXJ2ZXIgaGFzIGJlZW4gZmx1c2hlZC4gQ2xpZW50IFNpZGUgVGltZXN0YW1wOiBcIiArXG4gICAgICAgICAgbG9jYWxTeW5jZWQgK1xuICAgICAgICAgIFwiIFNlcnZlciBTaWRlIFRpbWVzdGFtcDogXCIgK1xuICAgICAgICAgIHVucXVvdGVkXG4gICAgICApO1xuICAgICAgdGhyb3cgZTtcbiAgICB9XG5cbiAgICBzeW5jUmVzdWx0T2JqZWN0Lmxhc3RNb2RpZmllZCA9IHVucXVvdGVkO1xuXG4gICAgLy8gRGVjb2RlIGluY29taW5nIGNoYW5nZXMuXG4gICAgY29uc3QgZGVjb2RlZENoYW5nZXMgPSBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgIGRhdGEubWFwKGNoYW5nZSA9PiB7XG4gICAgICAgIHJldHVybiB0aGlzLl9kZWNvZGVSZWNvcmQoXCJyZW1vdGVcIiwgY2hhbmdlKTtcbiAgICAgIH0pXG4gICAgKTtcbiAgICAvLyBIb29rIHJlY2VpdmVzIGRlY29kZWQgcmVjb3Jkcy5cbiAgICBjb25zdCBwYXlsb2FkID0geyBsYXN0TW9kaWZpZWQ6IHVucXVvdGVkLCBjaGFuZ2VzOiBkZWNvZGVkQ2hhbmdlcyB9O1xuICAgIGNvbnN0IGFmdGVySG9va3MgPSBhd2FpdCB0aGlzLmFwcGx5SG9vayhcImluY29taW5nLWNoYW5nZXNcIiwgcGF5bG9hZCk7XG5cbiAgICAvLyBObyBjaGFuZ2UsIG5vdGhpbmcgdG8gaW1wb3J0LlxuICAgIGlmIChhZnRlckhvb2tzLmNoYW5nZXMubGVuZ3RoID4gMCkge1xuICAgICAgLy8gUmVmbGVjdCB0aGVzZSBjaGFuZ2VzIGxvY2FsbHlcbiAgICAgIGF3YWl0IHRoaXMuaW1wb3J0Q2hhbmdlcyhcbiAgICAgICAgc3luY1Jlc3VsdE9iamVjdCxcbiAgICAgICAgYWZ0ZXJIb29rcy5jaGFuZ2VzLFxuICAgICAgICBvcHRpb25zLnN0cmF0ZWd5XG4gICAgICApO1xuICAgIH1cbiAgICByZXR1cm4gc3luY1Jlc3VsdE9iamVjdDtcbiAgfVxuXG4gIGFwcGx5SG9vayhob29rTmFtZSwgcGF5bG9hZCkge1xuICAgIGlmICh0eXBlb2YgdGhpcy5ob29rc1tob29rTmFtZV0gPT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShwYXlsb2FkKTtcbiAgICB9XG4gICAgcmV0dXJuIHdhdGVyZmFsbChcbiAgICAgIHRoaXMuaG9va3NbaG9va05hbWVdLm1hcChob29rID0+IHtcbiAgICAgICAgcmV0dXJuIHJlY29yZCA9PiB7XG4gICAgICAgICAgY29uc3QgcmVzdWx0ID0gaG9vayhwYXlsb2FkLCB0aGlzKTtcbiAgICAgICAgICBjb25zdCByZXN1bHRUaGVuYWJsZSA9IHJlc3VsdCAmJiB0eXBlb2YgcmVzdWx0LnRoZW4gPT09IFwiZnVuY3Rpb25cIjtcbiAgICAgICAgICBjb25zdCByZXN1bHRDaGFuZ2VzID0gcmVzdWx0ICYmIHJlc3VsdC5oYXNPd25Qcm9wZXJ0eShcImNoYW5nZXNcIik7XG4gICAgICAgICAgaWYgKCEocmVzdWx0VGhlbmFibGUgfHwgcmVzdWx0Q2hhbmdlcykpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICAgICAgYEludmFsaWQgcmV0dXJuIHZhbHVlIGZvciBob29rOiAke0pTT04uc3RyaW5naWZ5KFxuICAgICAgICAgICAgICAgIHJlc3VsdFxuICAgICAgICAgICAgICApfSBoYXMgbm8gJ3RoZW4oKScgb3IgJ2NoYW5nZXMnIHByb3BlcnRpZXNgXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICB9O1xuICAgICAgfSksXG4gICAgICBwYXlsb2FkXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQdWJsaXNoIGxvY2FsIGNoYW5nZXMgdG8gdGhlIHJlbW90ZSBzZXJ2ZXIgYW5kIHVwZGF0ZXMgdGhlIHBhc3NlZFxuICAgKiB7QGxpbmsgU3luY1Jlc3VsdE9iamVjdH0gd2l0aCBwdWJsaWNhdGlvbiByZXN1bHRzLlxuICAgKlxuICAgKiBPcHRpb25zOlxuICAgKiAtIHtTdHJpbmd9IHN0cmF0ZWd5OiBUaGUgc2VsZWN0ZWQgc3luYyBzdHJhdGVneS5cbiAgICogLSB7T2JqZWN0fSBoZWFkZXJzOiBUaGUgSFRUUCBoZWFkZXJzIHRvIHVzZSBpbiB0aGUgcmVxdWVzdC5cbiAgICogLSB7aW50fSByZXRyeTogVGhlIG51bWJlciBvZiByZXRyaWVzIHRvIGRvIGlmIHRoZSBIVFRQIHJlcXVlc3QgZmFpbHMuXG4gICAqXG4gICAqIEBwYXJhbSAge0tpbnRvQ2xpZW50LkNvbGxlY3Rpb259IGNsaWVudCAgICAgICAgICAgS2ludG8gY2xpZW50IENvbGxlY3Rpb24gaW5zdGFuY2UuXG4gICAqIEBwYXJhbSAge1N5bmNSZXN1bHRPYmplY3R9ICAgICAgIHN5bmNSZXN1bHRPYmplY3QgVGhlIHN5bmMgcmVzdWx0IG9iamVjdC5cbiAgICogQHBhcmFtICB7T2JqZWN0fSAgICAgICAgICAgICAgICAgY2hhbmdlcyAgICAgICAgICBUaGUgY2hhbmdlIG9iamVjdC5cbiAgICogQHBhcmFtICB7QXJyYXl9ICAgICAgICAgICAgICAgICAgY2hhbmdlcy50b0RlbGV0ZSBUaGUgbGlzdCBvZiByZWNvcmRzIHRvIGRlbGV0ZS5cbiAgICogQHBhcmFtICB7QXJyYXl9ICAgICAgICAgICAgICAgICAgY2hhbmdlcy50b1N5bmMgICBUaGUgbGlzdCBvZiByZWNvcmRzIHRvIGNyZWF0ZS91cGRhdGUuXG4gICAqIEBwYXJhbSAge09iamVjdH0gICAgICAgICAgICAgICAgIG9wdGlvbnMgICAgICAgICAgVGhlIG9wdGlvbnMgb2JqZWN0LlxuICAgKiBAcmV0dXJuIHtQcm9taXNlfVxuICAgKi9cbiAgYXN5bmMgcHVzaENoYW5nZXMoY2xpZW50LCBjaGFuZ2VzLCBzeW5jUmVzdWx0T2JqZWN0LCBvcHRpb25zID0ge30pIHtcbiAgICBpZiAoIXN5bmNSZXN1bHRPYmplY3Qub2spIHtcbiAgICAgIHJldHVybiBzeW5jUmVzdWx0T2JqZWN0O1xuICAgIH1cbiAgICBjb25zdCBzYWZlID1cbiAgICAgICFvcHRpb25zLnN0cmF0ZWd5IHx8IG9wdGlvbnMuc3RyYXRlZ3kgIT09IENvbGxlY3Rpb24uQ0xJRU5UX1dJTlM7XG4gICAgY29uc3QgdG9EZWxldGUgPSBjaGFuZ2VzLmZpbHRlcihyID0+IHIuX3N0YXR1cyA9PSBcImRlbGV0ZWRcIik7XG4gICAgY29uc3QgdG9TeW5jID0gY2hhbmdlcy5maWx0ZXIociA9PiByLl9zdGF0dXMgIT0gXCJkZWxldGVkXCIpO1xuXG4gICAgLy8gUGVyZm9ybSBhIGJhdGNoIHJlcXVlc3Qgd2l0aCBldmVyeSBjaGFuZ2VzLlxuICAgIGNvbnN0IHN5bmNlZCA9IGF3YWl0IGNsaWVudC5iYXRjaChcbiAgICAgIGJhdGNoID0+IHtcbiAgICAgICAgdG9EZWxldGUuZm9yRWFjaChyID0+IHtcbiAgICAgICAgICAvLyBuZXZlciBwdWJsaXNoZWQgbG9jYWxseSBkZWxldGVkIHJlY29yZHMgc2hvdWxkIG5vdCBiZSBwdXNibGlzaGVkXG4gICAgICAgICAgaWYgKHIubGFzdF9tb2RpZmllZCkge1xuICAgICAgICAgICAgYmF0Y2guZGVsZXRlUmVjb3JkKHIpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHRvU3luYy5mb3JFYWNoKHIgPT4ge1xuICAgICAgICAgIC8vIENsZWFuIGxvY2FsIGZpZWxkcyAobGlrZSBfc3RhdHVzKSBiZWZvcmUgc2VuZGluZyB0byBzZXJ2ZXIuXG4gICAgICAgICAgY29uc3QgcHVibGlzaGVkID0gdGhpcy5jbGVhbkxvY2FsRmllbGRzKHIpO1xuICAgICAgICAgIGlmIChyLl9zdGF0dXMgPT09IFwiY3JlYXRlZFwiKSB7XG4gICAgICAgICAgICBiYXRjaC5jcmVhdGVSZWNvcmQocHVibGlzaGVkKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgYmF0Y2gudXBkYXRlUmVjb3JkKHB1Ymxpc2hlZCk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIGhlYWRlcnM6IG9wdGlvbnMuaGVhZGVycyxcbiAgICAgICAgcmV0cnk6IG9wdGlvbnMucmV0cnksXG4gICAgICAgIHNhZmUsXG4gICAgICAgIGFnZ3JlZ2F0ZTogdHJ1ZSxcbiAgICAgIH1cbiAgICApO1xuXG4gICAgLy8gU3RvcmUgb3V0Z29pbmcgZXJyb3JzIGludG8gc3luYyByZXN1bHQgb2JqZWN0XG4gICAgc3luY1Jlc3VsdE9iamVjdC5hZGQoXG4gICAgICBcImVycm9yc1wiLFxuICAgICAgc3luY2VkLmVycm9ycy5tYXAoZSA9PiAoeyAuLi5lLCB0eXBlOiBcIm91dGdvaW5nXCIgfSkpXG4gICAgKTtcblxuICAgIC8vIFN0b3JlIG91dGdvaW5nIGNvbmZsaWN0cyBpbnRvIHN5bmMgcmVzdWx0IG9iamVjdFxuICAgIGNvbnN0IGNvbmZsaWN0cyA9IFtdO1xuICAgIGZvciAoY29uc3QgeyB0eXBlLCBsb2NhbCwgcmVtb3RlIH0gb2Ygc3luY2VkLmNvbmZsaWN0cykge1xuICAgICAgLy8gTm90ZTogd2UgZW5zdXJlIHRoYXQgbG9jYWwgZGF0YSBhcmUgYWN0dWFsbHkgYXZhaWxhYmxlLCBhcyB0aGV5IG1heVxuICAgICAgLy8gYmUgbWlzc2luZyBpbiB0aGUgY2FzZSBvZiBhIHB1Ymxpc2hlZCBkZWxldGlvbi5cbiAgICAgIGNvbnN0IHNhZmVMb2NhbCA9IChsb2NhbCAmJiBsb2NhbC5kYXRhKSB8fCB7IGlkOiByZW1vdGUuaWQgfTtcbiAgICAgIGNvbnN0IHJlYWxMb2NhbCA9IGF3YWl0IHRoaXMuX2RlY29kZVJlY29yZChcInJlbW90ZVwiLCBzYWZlTG9jYWwpO1xuICAgICAgLy8gV2UgY2FuIGdldCBcIm51bGxcIiBmcm9tIHRoZSByZW1vdGUgc2lkZSBpZiB3ZSBnb3QgYSBjb25mbGljdFxuICAgICAgLy8gYW5kIHRoZXJlIGlzIG5vIHJlbW90ZSB2ZXJzaW9uIGF2YWlsYWJsZTsgc2VlIGtpbnRvLWh0dHAuanNcbiAgICAgIC8vIGJhdGNoLmpzOmFnZ3JlZ2F0ZS5cbiAgICAgIGNvbnN0IHJlYWxSZW1vdGUgPSByZW1vdGUgJiYgKGF3YWl0IHRoaXMuX2RlY29kZVJlY29yZChcInJlbW90ZVwiLCByZW1vdGUpKTtcbiAgICAgIGNvbnN0IGNvbmZsaWN0ID0geyB0eXBlLCBsb2NhbDogcmVhbExvY2FsLCByZW1vdGU6IHJlYWxSZW1vdGUgfTtcbiAgICAgIGNvbmZsaWN0cy5wdXNoKGNvbmZsaWN0KTtcbiAgICB9XG4gICAgc3luY1Jlc3VsdE9iamVjdC5hZGQoXCJjb25mbGljdHNcIiwgY29uZmxpY3RzKTtcblxuICAgIC8vIFJlY29yZHMgdGhhdCBtdXN0IGJlIGRlbGV0ZWQgYXJlIGVpdGhlciBkZWxldGlvbnMgdGhhdCB3ZXJlIHB1c2hlZFxuICAgIC8vIHRvIHNlcnZlciAocHVibGlzaGVkKSBvciBkZWxldGVkIHJlY29yZHMgdGhhdCB3ZXJlIG5ldmVyIHB1c2hlZCAoc2tpcHBlZCkuXG4gICAgY29uc3QgbWlzc2luZ1JlbW90ZWx5ID0gc3luY2VkLnNraXBwZWQubWFwKHIgPT4gKHsgLi4uciwgZGVsZXRlZDogdHJ1ZSB9KSk7XG5cbiAgICAvLyBGb3IgY3JlYXRlZCBhbmQgdXBkYXRlZCByZWNvcmRzLCB0aGUgbGFzdF9tb2RpZmllZCBjb21pbmcgZnJvbSBzZXJ2ZXJcbiAgICAvLyB3aWxsIGJlIHN0b3JlZCBsb2NhbGx5LlxuICAgIC8vIFJlZmxlY3QgcHVibGljYXRpb24gcmVzdWx0cyBsb2NhbGx5IHVzaW5nIHRoZSByZXNwb25zZSBmcm9tXG4gICAgLy8gdGhlIGJhdGNoIHJlcXVlc3QuXG4gICAgY29uc3QgcHVibGlzaGVkID0gc3luY2VkLnB1Ymxpc2hlZC5tYXAoYyA9PiBjLmRhdGEpO1xuICAgIGNvbnN0IHRvQXBwbHlMb2NhbGx5ID0gcHVibGlzaGVkLmNvbmNhdChtaXNzaW5nUmVtb3RlbHkpO1xuXG4gICAgLy8gQXBwbHkgdGhlIGRlY29kZSB0cmFuc2Zvcm1lcnMsIGlmIGFueVxuICAgIGNvbnN0IGRlY29kZWQgPSBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgIHRvQXBwbHlMb2NhbGx5Lm1hcChyZWNvcmQgPT4ge1xuICAgICAgICByZXR1cm4gdGhpcy5fZGVjb2RlUmVjb3JkKFwicmVtb3RlXCIsIHJlY29yZCk7XG4gICAgICB9KVxuICAgICk7XG5cbiAgICAvLyBXZSBoYXZlIHRvIHVwZGF0ZSB0aGUgbG9jYWwgcmVjb3JkcyB3aXRoIHRoZSByZXNwb25zZXMgb2YgdGhlIHNlcnZlclxuICAgIC8vIChlZy4gbGFzdF9tb2RpZmllZCB2YWx1ZXMgZXRjLikuXG4gICAgaWYgKGRlY29kZWQubGVuZ3RoID4gMCB8fCBjb25mbGljdHMubGVuZ3RoID4gMCkge1xuICAgICAgYXdhaXQgdGhpcy5fYXBwbHlQdXNoZWRSZXN1bHRzKFxuICAgICAgICBzeW5jUmVzdWx0T2JqZWN0LFxuICAgICAgICBkZWNvZGVkLFxuICAgICAgICBjb25mbGljdHMsXG4gICAgICAgIG9wdGlvbnMuc3RyYXRlZ3lcbiAgICAgICk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHN5bmNSZXN1bHRPYmplY3Q7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJuIGEgY29weSBvZiB0aGUgc3BlY2lmaWVkIHJlY29yZCB3aXRob3V0IHRoZSBsb2NhbCBmaWVsZHMuXG4gICAqXG4gICAqIEBwYXJhbSAge09iamVjdH0gcmVjb3JkICBBIHJlY29yZCB3aXRoIHBvdGVudGlhbCBsb2NhbCBmaWVsZHMuXG4gICAqIEByZXR1cm4ge09iamVjdH1cbiAgICovXG4gIGNsZWFuTG9jYWxGaWVsZHMocmVjb3JkKSB7XG4gICAgY29uc3QgbG9jYWxLZXlzID0gUkVDT1JEX0ZJRUxEU19UT19DTEVBTi5jb25jYXQodGhpcy5sb2NhbEZpZWxkcyk7XG4gICAgcmV0dXJuIG9taXRLZXlzKHJlY29yZCwgbG9jYWxLZXlzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXNvbHZlcyBhIGNvbmZsaWN0LCB1cGRhdGluZyBsb2NhbCByZWNvcmQgYWNjb3JkaW5nIHRvIHByb3Bvc2VkXG4gICAqIHJlc29sdXRpb24g4oCUIGtlZXBpbmcgcmVtb3RlIHJlY29yZCBgbGFzdF9tb2RpZmllZGAgdmFsdWUgYXMgYSByZWZlcmVuY2UgZm9yXG4gICAqIGZ1cnRoZXIgYmF0Y2ggc2VuZGluZy5cbiAgICpcbiAgICogQHBhcmFtICB7T2JqZWN0fSBjb25mbGljdCAgIFRoZSBjb25mbGljdCBvYmplY3QuXG4gICAqIEBwYXJhbSAge09iamVjdH0gcmVzb2x1dGlvbiBUaGUgcHJvcG9zZWQgcmVjb3JkLlxuICAgKiBAcmV0dXJuIHtQcm9taXNlfVxuICAgKi9cbiAgcmVzb2x2ZShjb25mbGljdCwgcmVzb2x1dGlvbikge1xuICAgIHJldHVybiB0aGlzLmRiLmV4ZWN1dGUodHJhbnNhY3Rpb24gPT4ge1xuICAgICAgY29uc3QgdXBkYXRlZCA9IHRoaXMuX3Jlc29sdmVSYXcoY29uZmxpY3QsIHJlc29sdXRpb24pO1xuICAgICAgdHJhbnNhY3Rpb24udXBkYXRlKHVwZGF0ZWQpO1xuICAgICAgcmV0dXJuIHsgZGF0YTogdXBkYXRlZCwgcGVybWlzc2lvbnM6IHt9IH07XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG4gIF9yZXNvbHZlUmF3KGNvbmZsaWN0LCByZXNvbHV0aW9uKSB7XG4gICAgY29uc3QgcmVzb2x2ZWQgPSB7XG4gICAgICAuLi5yZXNvbHV0aW9uLFxuICAgICAgLy8gRW5zdXJlIGxvY2FsIHJlY29yZCBoYXMgdGhlIGxhdGVzdCBhdXRob3JpdGF0aXZlIHRpbWVzdGFtcFxuICAgICAgbGFzdF9tb2RpZmllZDogY29uZmxpY3QucmVtb3RlICYmIGNvbmZsaWN0LnJlbW90ZS5sYXN0X21vZGlmaWVkLFxuICAgIH07XG4gICAgLy8gSWYgdGhlIHJlc29sdXRpb24gb2JqZWN0IGlzIHN0cmljdGx5IGVxdWFsIHRvIHRoZVxuICAgIC8vIHJlbW90ZSByZWNvcmQsIHRoZW4gd2UgY2FuIG1hcmsgaXQgYXMgc3luY2VkIGxvY2FsbHkuXG4gICAgLy8gT3RoZXJ3aXNlLCBtYXJrIGl0IGFzIHVwZGF0ZWQgKHNvIHRoYXQgdGhlIHJlc29sdXRpb24gaXMgcHVzaGVkKS5cbiAgICBjb25zdCBzeW5jZWQgPSBkZWVwRXF1YWwocmVzb2x2ZWQsIGNvbmZsaWN0LnJlbW90ZSk7XG4gICAgcmV0dXJuIG1hcmtTdGF0dXMocmVzb2x2ZWQsIHN5bmNlZCA/IFwic3luY2VkXCIgOiBcInVwZGF0ZWRcIik7XG4gIH1cblxuICAvKipcbiAgICogU3luY2hyb25pemUgcmVtb3RlIGFuZCBsb2NhbCBkYXRhLiBUaGUgcHJvbWlzZSB3aWxsIHJlc29sdmUgd2l0aCBhXG4gICAqIHtAbGluayBTeW5jUmVzdWx0T2JqZWN0fSwgdGhvdWdoIHdpbGwgcmVqZWN0OlxuICAgKlxuICAgKiAtIGlmIHRoZSBzZXJ2ZXIgaXMgY3VycmVudGx5IGJhY2tlZCBvZmY7XG4gICAqIC0gaWYgdGhlIHNlcnZlciBoYXMgYmVlbiBkZXRlY3RlZCBmbHVzaGVkLlxuICAgKlxuICAgKiBPcHRpb25zOlxuICAgKiAtIHtPYmplY3R9IGhlYWRlcnM6IEhUVFAgaGVhZGVycyB0byBhdHRhY2ggdG8gb3V0Z29pbmcgcmVxdWVzdHMuXG4gICAqIC0ge1N0cmluZ30gZXhwZWN0ZWRUaW1lc3RhbXA6IEEgdGltZXN0YW1wIHRvIHVzZSBhcyBhIFwiY2FjaGUgYnVzdGluZ1wiIHF1ZXJ5IHBhcmFtZXRlci5cbiAgICogLSB7TnVtYmVyfSByZXRyeTogTnVtYmVyIG9mIHJldHJpZXMgd2hlbiBzZXJ2ZXIgZmFpbHMgdG8gcHJvY2VzcyB0aGUgcmVxdWVzdCAoZGVmYXVsdDogMSkuXG4gICAqIC0ge0NvbGxlY3Rpb24uc3RyYXRlZ3l9IHN0cmF0ZWd5OiBTZWUge0BsaW5rIENvbGxlY3Rpb24uc3RyYXRlZ3l9LlxuICAgKiAtIHtCb29sZWFufSBpZ25vcmVCYWNrb2ZmOiBGb3JjZSBzeW5jaHJvbml6YXRpb24gZXZlbiBpZiBzZXJ2ZXIgaXMgY3VycmVudGx5XG4gICAqICAgYmFja2VkIG9mZi5cbiAgICogLSB7U3RyaW5nfSBidWNrZXQ6IFRoZSByZW1vdmUgYnVja2V0IGlkIHRvIHVzZSAoZGVmYXVsdDogbnVsbClcbiAgICogLSB7U3RyaW5nfSBjb2xsZWN0aW9uOiBUaGUgcmVtb3ZlIGNvbGxlY3Rpb24gaWQgdG8gdXNlIChkZWZhdWx0OiBudWxsKVxuICAgKiAtIHtTdHJpbmd9IHJlbW90ZSBUaGUgcmVtb3RlIEtpbnRvIHNlcnZlciBlbmRwb2ludCB0byB1c2UgKGRlZmF1bHQ6IG51bGwpLlxuICAgKlxuICAgKiBAcGFyYW0gIHtPYmplY3R9IG9wdGlvbnMgT3B0aW9ucy5cbiAgICogQHJldHVybiB7UHJvbWlzZX1cbiAgICogQHRocm93cyB7RXJyb3J9IElmIGFuIGludmFsaWQgcmVtb3RlIG9wdGlvbiBpcyBwYXNzZWQuXG4gICAqL1xuICBhc3luYyBzeW5jKFxuICAgIG9wdGlvbnMgPSB7XG4gICAgICBzdHJhdGVneTogQ29sbGVjdGlvbi5zdHJhdGVneS5NQU5VQUwsXG4gICAgICBoZWFkZXJzOiB7fSxcbiAgICAgIHJldHJ5OiAxLFxuICAgICAgaWdub3JlQmFja29mZjogZmFsc2UsXG4gICAgICBidWNrZXQ6IG51bGwsXG4gICAgICBjb2xsZWN0aW9uOiBudWxsLFxuICAgICAgcmVtb3RlOiBudWxsLFxuICAgICAgZXhwZWN0ZWRUaW1lc3RhbXA6IG51bGwsXG4gICAgfVxuICApIHtcbiAgICBvcHRpb25zID0ge1xuICAgICAgLi4ub3B0aW9ucyxcbiAgICAgIGJ1Y2tldDogb3B0aW9ucy5idWNrZXQgfHwgdGhpcy5idWNrZXQsXG4gICAgICBjb2xsZWN0aW9uOiBvcHRpb25zLmNvbGxlY3Rpb24gfHwgdGhpcy5uYW1lLFxuICAgIH07XG5cbiAgICBjb25zdCBwcmV2aW91c1JlbW90ZSA9IHRoaXMuYXBpLnJlbW90ZTtcbiAgICBpZiAob3B0aW9ucy5yZW1vdGUpIHtcbiAgICAgIC8vIE5vdGU6IHNldHRpbmcgdGhlIHJlbW90ZSBlbnN1cmVzIGl0J3MgdmFsaWQsIHRocm93cyB3aGVuIGludmFsaWQuXG4gICAgICB0aGlzLmFwaS5yZW1vdGUgPSBvcHRpb25zLnJlbW90ZTtcbiAgICB9XG4gICAgaWYgKCFvcHRpb25zLmlnbm9yZUJhY2tvZmYgJiYgdGhpcy5hcGkuYmFja29mZiA+IDApIHtcbiAgICAgIGNvbnN0IHNlY29uZHMgPSBNYXRoLmNlaWwodGhpcy5hcGkuYmFja29mZiAvIDEwMDApO1xuICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KFxuICAgICAgICBuZXcgRXJyb3IoXG4gICAgICAgICAgYFNlcnZlciBpcyBhc2tpbmcgY2xpZW50cyB0byBiYWNrIG9mZjsgcmV0cnkgaW4gJHtzZWNvbmRzfXMgb3IgdXNlIHRoZSBpZ25vcmVCYWNrb2ZmIG9wdGlvbi5gXG4gICAgICAgIClcbiAgICAgICk7XG4gICAgfVxuXG4gICAgY29uc3QgY2xpZW50ID0gdGhpcy5hcGlcbiAgICAgIC5idWNrZXQob3B0aW9ucy5idWNrZXQpXG4gICAgICAuY29sbGVjdGlvbihvcHRpb25zLmNvbGxlY3Rpb24pO1xuXG4gICAgY29uc3QgcmVzdWx0ID0gbmV3IFN5bmNSZXN1bHRPYmplY3QoKTtcbiAgICB0cnkge1xuICAgICAgLy8gRmV0Y2ggY29sbGVjdGlvbiBtZXRhZGF0YS5cbiAgICAgIGF3YWl0IHRoaXMucHVsbE1ldGFkYXRhKGNsaWVudCwgb3B0aW9ucyk7XG5cbiAgICAgIC8vIEZldGNoIGxhc3QgY2hhbmdlcyBmcm9tIHRoZSBzZXJ2ZXIuXG4gICAgICBhd2FpdCB0aGlzLnB1bGxDaGFuZ2VzKGNsaWVudCwgcmVzdWx0LCBvcHRpb25zKTtcbiAgICAgIGNvbnN0IHsgbGFzdE1vZGlmaWVkIH0gPSByZXN1bHQ7XG5cbiAgICAgIC8vIEZldGNoIGxvY2FsIGNoYW5nZXNcbiAgICAgIGNvbnN0IHRvU3luYyA9IGF3YWl0IHRoaXMuZ2F0aGVyTG9jYWxDaGFuZ2VzKCk7XG5cbiAgICAgIC8vIFB1Ymxpc2ggbG9jYWwgY2hhbmdlcyBhbmQgcHVsbCBsb2NhbCByZXNvbHV0aW9uc1xuICAgICAgYXdhaXQgdGhpcy5wdXNoQ2hhbmdlcyhjbGllbnQsIHRvU3luYywgcmVzdWx0LCBvcHRpb25zKTtcblxuICAgICAgLy8gUHVibGlzaCBsb2NhbCByZXNvbHV0aW9uIG9mIHB1c2ggY29uZmxpY3RzIHRvIHNlcnZlciAob24gQ0xJRU5UX1dJTlMpXG4gICAgICBjb25zdCByZXNvbHZlZFVuc3luY2VkID0gcmVzdWx0LnJlc29sdmVkLmZpbHRlcihcbiAgICAgICAgciA9PiByLl9zdGF0dXMgIT09IFwic3luY2VkXCJcbiAgICAgICk7XG4gICAgICBpZiAocmVzb2x2ZWRVbnN5bmNlZC5sZW5ndGggPiAwKSB7XG4gICAgICAgIGNvbnN0IHJlc29sdmVkRW5jb2RlZCA9IGF3YWl0IFByb21pc2UuYWxsKFxuICAgICAgICAgIHJlc29sdmVkVW5zeW5jZWQubWFwKHJlc29sdXRpb24gPT4ge1xuICAgICAgICAgICAgbGV0IHJlY29yZCA9IHJlc29sdXRpb24uYWNjZXB0ZWQ7XG4gICAgICAgICAgICBpZiAocmVjb3JkID09PSBudWxsKSB7XG4gICAgICAgICAgICAgIHJlY29yZCA9IHsgaWQ6IHJlc29sdXRpb24uaWQsIF9zdGF0dXM6IHJlc29sdXRpb24uX3N0YXR1cyB9O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2VuY29kZVJlY29yZChcInJlbW90ZVwiLCByZWNvcmQpO1xuICAgICAgICAgIH0pXG4gICAgICAgICk7XG4gICAgICAgIGF3YWl0IHRoaXMucHVzaENoYW5nZXMoY2xpZW50LCByZXNvbHZlZEVuY29kZWQsIHJlc3VsdCwgb3B0aW9ucyk7XG4gICAgICB9XG4gICAgICAvLyBQZXJmb3JtIGEgbGFzdCBwdWxsIHRvIGNhdGNoIGNoYW5nZXMgdGhhdCBvY2N1cmVkIGFmdGVyIHRoZSBsYXN0IHB1bGwsXG4gICAgICAvLyB3aGlsZSBsb2NhbCBjaGFuZ2VzIHdlcmUgcHVzaGVkLiBEbyBub3QgZG8gaXQgbm90aGluZyB3YXMgcHVzaGVkLlxuICAgICAgaWYgKHJlc3VsdC5wdWJsaXNoZWQubGVuZ3RoID4gMCkge1xuICAgICAgICAvLyBBdm9pZCByZWRvd25sb2FkaW5nIG91ciBvd24gY2hhbmdlcyBkdXJpbmcgdGhlIGxhc3QgcHVsbC5cbiAgICAgICAgY29uc3QgcHVsbE9wdHMgPSB7XG4gICAgICAgICAgLi4ub3B0aW9ucyxcbiAgICAgICAgICBsYXN0TW9kaWZpZWQsXG4gICAgICAgICAgZXhjbHVkZTogcmVzdWx0LnB1Ymxpc2hlZCxcbiAgICAgICAgfTtcbiAgICAgICAgYXdhaXQgdGhpcy5wdWxsQ2hhbmdlcyhjbGllbnQsIHJlc3VsdCwgcHVsbE9wdHMpO1xuICAgICAgfVxuXG4gICAgICAvLyBEb24ndCBwZXJzaXN0IGxhc3RNb2RpZmllZCB2YWx1ZSBpZiBhbnkgY29uZmxpY3Qgb3IgZXJyb3Igb2NjdXJlZFxuICAgICAgaWYgKHJlc3VsdC5vaykge1xuICAgICAgICAvLyBObyBjb25mbGljdCBvY2N1cmVkLCBwZXJzaXN0IGNvbGxlY3Rpb24ncyBsYXN0TW9kaWZpZWQgdmFsdWVcbiAgICAgICAgdGhpcy5fbGFzdE1vZGlmaWVkID0gYXdhaXQgdGhpcy5kYi5zYXZlTGFzdE1vZGlmaWVkKFxuICAgICAgICAgIHJlc3VsdC5sYXN0TW9kaWZpZWRcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICB0aGlzLmV2ZW50cy5lbWl0KFwic3luYzplcnJvclwiLCB7IC4uLm9wdGlvbnMsIGVycm9yOiBlIH0pO1xuICAgICAgdGhyb3cgZTtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgLy8gRW5zdXJlIEFQSSBkZWZhdWx0IHJlbW90ZSBpcyByZXZlcnRlZCBpZiBhIGN1c3RvbSBvbmUncyBiZWVuIHVzZWRcbiAgICAgIHRoaXMuYXBpLnJlbW90ZSA9IHByZXZpb3VzUmVtb3RlO1xuICAgIH1cbiAgICB0aGlzLmV2ZW50cy5lbWl0KFwic3luYzpzdWNjZXNzXCIsIHsgLi4ub3B0aW9ucywgcmVzdWx0IH0pO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICAvKipcbiAgICogTG9hZCBhIGxpc3Qgb2YgcmVjb3JkcyBhbHJlYWR5IHN5bmNlZCB3aXRoIHRoZSByZW1vdGUgc2VydmVyLlxuICAgKlxuICAgKiBUaGUgbG9jYWwgcmVjb3JkcyB3aGljaCBhcmUgdW5zeW5jZWQgb3Igd2hvc2UgdGltZXN0YW1wIGlzIGVpdGhlciBtaXNzaW5nXG4gICAqIG9yIHN1cGVyaW9yIHRvIHRob3NlIGJlaW5nIGxvYWRlZCB3aWxsIGJlIGlnbm9yZWQuXG4gICAqXG4gICAqIEBkZXByZWNhdGVkIFVzZSB7QGxpbmsgaW1wb3J0QnVsa30gaW5zdGVhZC5cbiAgICogQHBhcmFtICB7QXJyYXl9IHJlY29yZHMgVGhlIHByZXZpb3VzbHkgZXhwb3J0ZWQgbGlzdCBvZiByZWNvcmRzIHRvIGxvYWQuXG4gICAqIEByZXR1cm4ge1Byb21pc2V9IHdpdGggdGhlIGVmZmVjdGl2ZWx5IGltcG9ydGVkIHJlY29yZHMuXG4gICAqL1xuICBhc3luYyBsb2FkRHVtcChyZWNvcmRzKSB7XG4gICAgcmV0dXJuIHRoaXMuaW1wb3J0QnVsayhyZWNvcmRzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBMb2FkIGEgbGlzdCBvZiByZWNvcmRzIGFscmVhZHkgc3luY2VkIHdpdGggdGhlIHJlbW90ZSBzZXJ2ZXIuXG4gICAqXG4gICAqIFRoZSBsb2NhbCByZWNvcmRzIHdoaWNoIGFyZSB1bnN5bmNlZCBvciB3aG9zZSB0aW1lc3RhbXAgaXMgZWl0aGVyIG1pc3NpbmdcbiAgICogb3Igc3VwZXJpb3IgdG8gdGhvc2UgYmVpbmcgbG9hZGVkIHdpbGwgYmUgaWdub3JlZC5cbiAgICpcbiAgICogQHBhcmFtICB7QXJyYXl9IHJlY29yZHMgVGhlIHByZXZpb3VzbHkgZXhwb3J0ZWQgbGlzdCBvZiByZWNvcmRzIHRvIGxvYWQuXG4gICAqIEByZXR1cm4ge1Byb21pc2V9IHdpdGggdGhlIGVmZmVjdGl2ZWx5IGltcG9ydGVkIHJlY29yZHMuXG4gICAqL1xuICBhc3luYyBpbXBvcnRCdWxrKHJlY29yZHMpIHtcbiAgICBpZiAoIUFycmF5LmlzQXJyYXkocmVjb3JkcykpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlJlY29yZHMgaXMgbm90IGFuIGFycmF5LlwiKTtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IHJlY29yZCBvZiByZWNvcmRzKSB7XG4gICAgICBpZiAoIXJlY29yZC5oYXNPd25Qcm9wZXJ0eShcImlkXCIpIHx8ICF0aGlzLmlkU2NoZW1hLnZhbGlkYXRlKHJlY29yZC5pZCkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiUmVjb3JkIGhhcyBpbnZhbGlkIElEOiBcIiArIEpTT04uc3RyaW5naWZ5KHJlY29yZCkpO1xuICAgICAgfVxuXG4gICAgICBpZiAoIXJlY29yZC5sYXN0X21vZGlmaWVkKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICBcIlJlY29yZCBoYXMgbm8gbGFzdF9tb2RpZmllZCB2YWx1ZTogXCIgKyBKU09OLnN0cmluZ2lmeShyZWNvcmQpXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gRmV0Y2ggYWxsIGV4aXN0aW5nIHJlY29yZHMgZnJvbSBsb2NhbCBkYXRhYmFzZSxcbiAgICAvLyBhbmQgc2tpcCB0aG9zZSB3aG8gYXJlIG5ld2VyIG9yIG5vdCBtYXJrZWQgYXMgc3luY2VkLlxuXG4gICAgLy8gWFhYIGZpbHRlciBieSBzdGF0dXMgLyBpZHMgaW4gcmVjb3Jkc1xuXG4gICAgY29uc3QgeyBkYXRhIH0gPSBhd2FpdCB0aGlzLmxpc3Qoe30sIHsgaW5jbHVkZURlbGV0ZWQ6IHRydWUgfSk7XG4gICAgY29uc3QgZXhpc3RpbmdCeUlkID0gZGF0YS5yZWR1Y2UoKGFjYywgcmVjb3JkKSA9PiB7XG4gICAgICBhY2NbcmVjb3JkLmlkXSA9IHJlY29yZDtcbiAgICAgIHJldHVybiBhY2M7XG4gICAgfSwge30pO1xuXG4gICAgY29uc3QgbmV3UmVjb3JkcyA9IHJlY29yZHMuZmlsdGVyKHJlY29yZCA9PiB7XG4gICAgICBjb25zdCBsb2NhbFJlY29yZCA9IGV4aXN0aW5nQnlJZFtyZWNvcmQuaWRdO1xuICAgICAgY29uc3Qgc2hvdWxkS2VlcCA9XG4gICAgICAgIC8vIE5vIGxvY2FsIHJlY29yZCB3aXRoIHRoaXMgaWQuXG4gICAgICAgIGxvY2FsUmVjb3JkID09PSB1bmRlZmluZWQgfHxcbiAgICAgICAgLy8gT3IgbG9jYWwgcmVjb3JkIGlzIHN5bmNlZFxuICAgICAgICAobG9jYWxSZWNvcmQuX3N0YXR1cyA9PT0gXCJzeW5jZWRcIiAmJlxuICAgICAgICAgIC8vIEFuZCB3YXMgc3luY2VkIGZyb20gc2VydmVyXG4gICAgICAgICAgbG9jYWxSZWNvcmQubGFzdF9tb2RpZmllZCAhPT0gdW5kZWZpbmVkICYmXG4gICAgICAgICAgLy8gQW5kIGlzIG9sZGVyIHRoYW4gaW1wb3J0ZWQgb25lLlxuICAgICAgICAgIHJlY29yZC5sYXN0X21vZGlmaWVkID4gbG9jYWxSZWNvcmQubGFzdF9tb2RpZmllZCk7XG4gICAgICByZXR1cm4gc2hvdWxkS2VlcDtcbiAgICB9KTtcblxuICAgIHJldHVybiBhd2FpdCB0aGlzLmRiLmltcG9ydEJ1bGsobmV3UmVjb3Jkcy5tYXAobWFya1N5bmNlZCkpO1xuICB9XG5cbiAgYXN5bmMgcHVsbE1ldGFkYXRhKGNsaWVudCwgb3B0aW9ucyA9IHt9KSB7XG4gICAgY29uc3QgeyBleHBlY3RlZFRpbWVzdGFtcCwgaGVhZGVycyB9ID0gb3B0aW9ucztcbiAgICBjb25zdCBxdWVyeSA9IGV4cGVjdGVkVGltZXN0YW1wXG4gICAgICA/IHsgcXVlcnk6IHsgX2V4cGVjdGVkOiBleHBlY3RlZFRpbWVzdGFtcCB9IH1cbiAgICAgIDogdW5kZWZpbmVkO1xuICAgIGNvbnN0IG1ldGFkYXRhID0gYXdhaXQgY2xpZW50LmdldERhdGEoe1xuICAgICAgLi4ucXVlcnksXG4gICAgICBoZWFkZXJzLFxuICAgIH0pO1xuICAgIHJldHVybiB0aGlzLmRiLnNhdmVNZXRhZGF0YShtZXRhZGF0YSk7XG4gIH1cblxuICBhc3luYyBtZXRhZGF0YSgpIHtcbiAgICByZXR1cm4gdGhpcy5kYi5nZXRNZXRhZGF0YSgpO1xuICB9XG59XG5cbi8qKlxuICogQSBDb2xsZWN0aW9uLW9yaWVudGVkIHdyYXBwZXIgZm9yIGFuIGFkYXB0ZXIncyB0cmFuc2FjdGlvbi5cbiAqXG4gKiBUaGlzIGRlZmluZXMgdGhlIGhpZ2gtbGV2ZWwgZnVuY3Rpb25zIGF2YWlsYWJsZSBvbiBhIGNvbGxlY3Rpb24uXG4gKiBUaGUgY29sbGVjdGlvbiBpdHNlbGYgb2ZmZXJzIGZ1bmN0aW9ucyBvZiB0aGUgc2FtZSBuYW1lLiBUaGVzZSB3aWxsXG4gKiBwZXJmb3JtIGp1c3Qgb25lIG9wZXJhdGlvbiBpbiBpdHMgb3duIHRyYW5zYWN0aW9uLlxuICovXG5leHBvcnQgY2xhc3MgQ29sbGVjdGlvblRyYW5zYWN0aW9uIHtcbiAgY29uc3RydWN0b3IoY29sbGVjdGlvbiwgYWRhcHRlclRyYW5zYWN0aW9uKSB7XG4gICAgdGhpcy5jb2xsZWN0aW9uID0gY29sbGVjdGlvbjtcbiAgICB0aGlzLmFkYXB0ZXJUcmFuc2FjdGlvbiA9IGFkYXB0ZXJUcmFuc2FjdGlvbjtcblxuICAgIHRoaXMuX2V2ZW50cyA9IFtdO1xuICB9XG5cbiAgX3F1ZXVlRXZlbnQoYWN0aW9uLCBwYXlsb2FkKSB7XG4gICAgdGhpcy5fZXZlbnRzLnB1c2goeyBhY3Rpb24sIHBheWxvYWQgfSk7XG4gIH1cblxuICAvKipcbiAgICogRW1pdCBxdWV1ZWQgZXZlbnRzLCB0byBiZSBjYWxsZWQgb25jZSBldmVyeSB0cmFuc2FjdGlvbiBvcGVyYXRpb25zIGhhdmVcbiAgICogYmVlbiBleGVjdXRlZCBzdWNjZXNzZnVsbHkuXG4gICAqL1xuICBlbWl0RXZlbnRzKCkge1xuICAgIGZvciAoY29uc3QgeyBhY3Rpb24sIHBheWxvYWQgfSBvZiB0aGlzLl9ldmVudHMpIHtcbiAgICAgIHRoaXMuY29sbGVjdGlvbi5ldmVudHMuZW1pdChhY3Rpb24sIHBheWxvYWQpO1xuICAgIH1cbiAgICBpZiAodGhpcy5fZXZlbnRzLmxlbmd0aCA+IDApIHtcbiAgICAgIGNvbnN0IHRhcmdldHMgPSB0aGlzLl9ldmVudHMubWFwKCh7IGFjdGlvbiwgcGF5bG9hZCB9KSA9PiAoe1xuICAgICAgICBhY3Rpb24sXG4gICAgICAgIC4uLnBheWxvYWQsXG4gICAgICB9KSk7XG4gICAgICB0aGlzLmNvbGxlY3Rpb24uZXZlbnRzLmVtaXQoXCJjaGFuZ2VcIiwgeyB0YXJnZXRzIH0pO1xuICAgIH1cbiAgICB0aGlzLl9ldmVudHMgPSBbXTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXRyaWV2ZSBhIHJlY29yZCBieSBpdHMgaWQgZnJvbSB0aGUgbG9jYWwgZGF0YWJhc2UsIG9yXG4gICAqIHVuZGVmaW5lZCBpZiBub25lIGV4aXN0cy5cbiAgICpcbiAgICogVGhpcyB3aWxsIGFsc28gcmV0dXJuIHZpcnR1YWxseSBkZWxldGVkIHJlY29yZHMuXG4gICAqXG4gICAqIEBwYXJhbSAge1N0cmluZ30gaWRcbiAgICogQHJldHVybiB7T2JqZWN0fVxuICAgKi9cbiAgZ2V0QW55KGlkKSB7XG4gICAgY29uc3QgcmVjb3JkID0gdGhpcy5hZGFwdGVyVHJhbnNhY3Rpb24uZ2V0KGlkKTtcbiAgICByZXR1cm4geyBkYXRhOiByZWNvcmQsIHBlcm1pc3Npb25zOiB7fSB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHJpZXZlIGEgcmVjb3JkIGJ5IGl0cyBpZCBmcm9tIHRoZSBsb2NhbCBkYXRhYmFzZS5cbiAgICpcbiAgICogT3B0aW9uczpcbiAgICogLSB7Qm9vbGVhbn0gaW5jbHVkZURlbGV0ZWQ6IEluY2x1ZGUgdmlydHVhbGx5IGRlbGV0ZWQgcmVjb3Jkcy5cbiAgICpcbiAgICogQHBhcmFtICB7U3RyaW5nfSBpZFxuICAgKiBAcGFyYW0gIHtPYmplY3R9IG9wdGlvbnNcbiAgICogQHJldHVybiB7T2JqZWN0fVxuICAgKi9cbiAgZ2V0KGlkLCBvcHRpb25zID0geyBpbmNsdWRlRGVsZXRlZDogZmFsc2UgfSkge1xuICAgIGNvbnN0IHJlcyA9IHRoaXMuZ2V0QW55KGlkKTtcbiAgICBpZiAoXG4gICAgICAhcmVzLmRhdGEgfHxcbiAgICAgICghb3B0aW9ucy5pbmNsdWRlRGVsZXRlZCAmJiByZXMuZGF0YS5fc3RhdHVzID09PSBcImRlbGV0ZWRcIilcbiAgICApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgUmVjb3JkIHdpdGggaWQ9JHtpZH0gbm90IGZvdW5kLmApO1xuICAgIH1cblxuICAgIHJldHVybiByZXM7XG4gIH1cblxuICAvKipcbiAgICogRGVsZXRlcyBhIHJlY29yZCBmcm9tIHRoZSBsb2NhbCBkYXRhYmFzZS5cbiAgICpcbiAgICogT3B0aW9uczpcbiAgICogLSB7Qm9vbGVhbn0gdmlydHVhbDogV2hlbiBzZXQgdG8gYHRydWVgLCBkb2Vzbid0IGFjdHVhbGx5IGRlbGV0ZSB0aGUgcmVjb3JkLFxuICAgKiAgIHVwZGF0ZSBpdHMgYF9zdGF0dXNgIGF0dHJpYnV0ZSB0byBgZGVsZXRlZGAgaW5zdGVhZCAoZGVmYXVsdDogdHJ1ZSlcbiAgICpcbiAgICogQHBhcmFtICB7U3RyaW5nfSBpZCAgICAgICBUaGUgcmVjb3JkJ3MgSWQuXG4gICAqIEBwYXJhbSAge09iamVjdH0gb3B0aW9ucyAgVGhlIG9wdGlvbnMgb2JqZWN0LlxuICAgKiBAcmV0dXJuIHtPYmplY3R9XG4gICAqL1xuICBkZWxldGUoaWQsIG9wdGlvbnMgPSB7IHZpcnR1YWw6IHRydWUgfSkge1xuICAgIC8vIEVuc3VyZSB0aGUgcmVjb3JkIGFjdHVhbGx5IGV4aXN0cy5cbiAgICBjb25zdCBleGlzdGluZyA9IHRoaXMuYWRhcHRlclRyYW5zYWN0aW9uLmdldChpZCk7XG4gICAgY29uc3QgYWxyZWFkeURlbGV0ZWQgPSBleGlzdGluZyAmJiBleGlzdGluZy5fc3RhdHVzID09IFwiZGVsZXRlZFwiO1xuICAgIGlmICghZXhpc3RpbmcgfHwgKGFscmVhZHlEZWxldGVkICYmIG9wdGlvbnMudmlydHVhbCkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgUmVjb3JkIHdpdGggaWQ9JHtpZH0gbm90IGZvdW5kLmApO1xuICAgIH1cbiAgICAvLyBWaXJ0dWFsIHVwZGF0ZXMgc3RhdHVzLlxuICAgIGlmIChvcHRpb25zLnZpcnR1YWwpIHtcbiAgICAgIHRoaXMuYWRhcHRlclRyYW5zYWN0aW9uLnVwZGF0ZShtYXJrRGVsZXRlZChleGlzdGluZykpO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBEZWxldGUgZm9yIHJlYWwuXG4gICAgICB0aGlzLmFkYXB0ZXJUcmFuc2FjdGlvbi5kZWxldGUoaWQpO1xuICAgIH1cbiAgICB0aGlzLl9xdWV1ZUV2ZW50KFwiZGVsZXRlXCIsIHsgZGF0YTogZXhpc3RpbmcgfSk7XG4gICAgcmV0dXJuIHsgZGF0YTogZXhpc3RpbmcsIHBlcm1pc3Npb25zOiB7fSB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFNvZnQgZGVsZXRlIGFsbCByZWNvcmRzIGZyb20gdGhlIGxvY2FsIGRhdGFiYXNlLlxuICAgKlxuICAgKiBAcGFyYW0gIHtBcnJheX0gaWRzICAgICAgICBBcnJheSBvZiBub24tZGVsZXRlZCBSZWNvcmQgSWRzLlxuICAgKiBAcmV0dXJuIHtPYmplY3R9XG4gICAqL1xuICBkZWxldGVBbGwoaWRzKSB7XG4gICAgY29uc3QgZXhpc3RpbmdSZWNvcmRzID0gW107XG4gICAgaWRzLmZvckVhY2goaWQgPT4ge1xuICAgICAgZXhpc3RpbmdSZWNvcmRzLnB1c2godGhpcy5hZGFwdGVyVHJhbnNhY3Rpb24uZ2V0KGlkKSk7XG4gICAgICB0aGlzLmRlbGV0ZShpZCk7XG4gICAgfSk7XG5cbiAgICB0aGlzLl9xdWV1ZUV2ZW50KFwiZGVsZXRlQWxsXCIsIHsgZGF0YTogZXhpc3RpbmdSZWNvcmRzIH0pO1xuICAgIHJldHVybiB7IGRhdGE6IGV4aXN0aW5nUmVjb3JkcywgcGVybWlzc2lvbnM6IHt9IH07XG4gIH1cblxuICAvKipcbiAgICogRGVsZXRlcyBhIHJlY29yZCBmcm9tIHRoZSBsb2NhbCBkYXRhYmFzZSwgaWYgYW55IGV4aXN0cy5cbiAgICogT3RoZXJ3aXNlLCBkbyBub3RoaW5nLlxuICAgKlxuICAgKiBAcGFyYW0gIHtTdHJpbmd9IGlkICAgICAgIFRoZSByZWNvcmQncyBJZC5cbiAgICogQHJldHVybiB7T2JqZWN0fVxuICAgKi9cbiAgZGVsZXRlQW55KGlkKSB7XG4gICAgY29uc3QgZXhpc3RpbmcgPSB0aGlzLmFkYXB0ZXJUcmFuc2FjdGlvbi5nZXQoaWQpO1xuICAgIGlmIChleGlzdGluZykge1xuICAgICAgdGhpcy5hZGFwdGVyVHJhbnNhY3Rpb24udXBkYXRlKG1hcmtEZWxldGVkKGV4aXN0aW5nKSk7XG4gICAgICB0aGlzLl9xdWV1ZUV2ZW50KFwiZGVsZXRlXCIsIHsgZGF0YTogZXhpc3RpbmcgfSk7XG4gICAgfVxuICAgIHJldHVybiB7IGRhdGE6IHsgaWQsIC4uLmV4aXN0aW5nIH0sIGRlbGV0ZWQ6ICEhZXhpc3RpbmcsIHBlcm1pc3Npb25zOiB7fSB9O1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZHMgYSByZWNvcmQgdG8gdGhlIGxvY2FsIGRhdGFiYXNlLCBhc3NlcnRpbmcgdGhhdCBub25lXG4gICAqIGFscmVhZHkgZXhpc3Qgd2l0aCB0aGlzIElELlxuICAgKlxuICAgKiBAcGFyYW0gIHtPYmplY3R9IHJlY29yZCwgd2hpY2ggbXVzdCBjb250YWluIGFuIElEXG4gICAqIEByZXR1cm4ge09iamVjdH1cbiAgICovXG4gIGNyZWF0ZShyZWNvcmQpIHtcbiAgICBpZiAodHlwZW9mIHJlY29yZCAhPT0gXCJvYmplY3RcIikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiUmVjb3JkIGlzIG5vdCBhbiBvYmplY3QuXCIpO1xuICAgIH1cbiAgICBpZiAoIXJlY29yZC5oYXNPd25Qcm9wZXJ0eShcImlkXCIpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJDYW5ub3QgY3JlYXRlIGEgcmVjb3JkIG1pc3NpbmcgaWRcIik7XG4gICAgfVxuICAgIGlmICghdGhpcy5jb2xsZWN0aW9uLmlkU2NoZW1hLnZhbGlkYXRlKHJlY29yZC5pZCkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCBJZDogJHtyZWNvcmQuaWR9YCk7XG4gICAgfVxuXG4gICAgdGhpcy5hZGFwdGVyVHJhbnNhY3Rpb24uY3JlYXRlKHJlY29yZCk7XG4gICAgdGhpcy5fcXVldWVFdmVudChcImNyZWF0ZVwiLCB7IGRhdGE6IHJlY29yZCB9KTtcbiAgICByZXR1cm4geyBkYXRhOiByZWNvcmQsIHBlcm1pc3Npb25zOiB7fSB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFVwZGF0ZXMgYSByZWNvcmQgZnJvbSB0aGUgbG9jYWwgZGF0YWJhc2UuXG4gICAqXG4gICAqIE9wdGlvbnM6XG4gICAqIC0ge0Jvb2xlYW59IHN5bmNlZDogU2V0cyByZWNvcmQgc3RhdHVzIHRvIFwic3luY2VkXCIgKGRlZmF1bHQ6IGZhbHNlKVxuICAgKiAtIHtCb29sZWFufSBwYXRjaDogIEV4dGVuZHMgdGhlIGV4aXN0aW5nIHJlY29yZCBpbnN0ZWFkIG9mIG92ZXJ3cml0aW5nIGl0XG4gICAqICAgKGRlZmF1bHQ6IGZhbHNlKVxuICAgKlxuICAgKiBAcGFyYW0gIHtPYmplY3R9IHJlY29yZFxuICAgKiBAcGFyYW0gIHtPYmplY3R9IG9wdGlvbnNcbiAgICogQHJldHVybiB7T2JqZWN0fVxuICAgKi9cbiAgdXBkYXRlKHJlY29yZCwgb3B0aW9ucyA9IHsgc3luY2VkOiBmYWxzZSwgcGF0Y2g6IGZhbHNlIH0pIHtcbiAgICBpZiAodHlwZW9mIHJlY29yZCAhPT0gXCJvYmplY3RcIikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiUmVjb3JkIGlzIG5vdCBhbiBvYmplY3QuXCIpO1xuICAgIH1cbiAgICBpZiAoIXJlY29yZC5oYXNPd25Qcm9wZXJ0eShcImlkXCIpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJDYW5ub3QgdXBkYXRlIGEgcmVjb3JkIG1pc3NpbmcgaWQuXCIpO1xuICAgIH1cbiAgICBpZiAoIXRoaXMuY29sbGVjdGlvbi5pZFNjaGVtYS52YWxpZGF0ZShyZWNvcmQuaWQpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgSWQ6ICR7cmVjb3JkLmlkfWApO1xuICAgIH1cblxuICAgIGNvbnN0IG9sZFJlY29yZCA9IHRoaXMuYWRhcHRlclRyYW5zYWN0aW9uLmdldChyZWNvcmQuaWQpO1xuICAgIGlmICghb2xkUmVjb3JkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFJlY29yZCB3aXRoIGlkPSR7cmVjb3JkLmlkfSBub3QgZm91bmQuYCk7XG4gICAgfVxuICAgIGNvbnN0IG5ld1JlY29yZCA9IG9wdGlvbnMucGF0Y2ggPyB7IC4uLm9sZFJlY29yZCwgLi4ucmVjb3JkIH0gOiByZWNvcmQ7XG4gICAgY29uc3QgdXBkYXRlZCA9IHRoaXMuX3VwZGF0ZVJhdyhvbGRSZWNvcmQsIG5ld1JlY29yZCwgb3B0aW9ucyk7XG4gICAgdGhpcy5hZGFwdGVyVHJhbnNhY3Rpb24udXBkYXRlKHVwZGF0ZWQpO1xuICAgIHRoaXMuX3F1ZXVlRXZlbnQoXCJ1cGRhdGVcIiwgeyBkYXRhOiB1cGRhdGVkLCBvbGRSZWNvcmQgfSk7XG4gICAgcmV0dXJuIHsgZGF0YTogdXBkYXRlZCwgb2xkUmVjb3JkLCBwZXJtaXNzaW9uczoge30gfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBMb3dlci1sZXZlbCBwcmltaXRpdmUgZm9yIHVwZGF0aW5nIGEgcmVjb3JkIHdoaWxlIHJlc3BlY3RpbmdcbiAgICogX3N0YXR1cyBhbmQgbGFzdF9tb2RpZmllZC5cbiAgICpcbiAgICogQHBhcmFtICB7T2JqZWN0fSBvbGRSZWNvcmQ6IHRoZSByZWNvcmQgcmV0cmlldmVkIGZyb20gdGhlIERCXG4gICAqIEBwYXJhbSAge09iamVjdH0gbmV3UmVjb3JkOiB0aGUgcmVjb3JkIHRvIHJlcGxhY2UgaXQgd2l0aFxuICAgKiBAcmV0dXJuIHtPYmplY3R9XG4gICAqL1xuICBfdXBkYXRlUmF3KG9sZFJlY29yZCwgbmV3UmVjb3JkLCB7IHN5bmNlZCA9IGZhbHNlIH0gPSB7fSkge1xuICAgIGNvbnN0IHVwZGF0ZWQgPSB7IC4uLm5ld1JlY29yZCB9O1xuICAgIC8vIE1ha2Ugc3VyZSB0byBuZXZlciBsb29zZSB0aGUgZXhpc3RpbmcgdGltZXN0YW1wLlxuICAgIGlmIChvbGRSZWNvcmQgJiYgb2xkUmVjb3JkLmxhc3RfbW9kaWZpZWQgJiYgIXVwZGF0ZWQubGFzdF9tb2RpZmllZCkge1xuICAgICAgdXBkYXRlZC5sYXN0X21vZGlmaWVkID0gb2xkUmVjb3JkLmxhc3RfbW9kaWZpZWQ7XG4gICAgfVxuICAgIC8vIElmIG9ubHkgbG9jYWwgZmllbGRzIGhhdmUgY2hhbmdlZCwgdGhlbiBrZWVwIHJlY29yZCBhcyBzeW5jZWQuXG4gICAgLy8gSWYgc3RhdHVzIGlzIGNyZWF0ZWQsIGtlZXAgcmVjb3JkIGFzIGNyZWF0ZWQuXG4gICAgLy8gSWYgc3RhdHVzIGlzIGRlbGV0ZWQsIG1hcmsgYXMgdXBkYXRlZC5cbiAgICBjb25zdCBpc0lkZW50aWNhbCA9XG4gICAgICBvbGRSZWNvcmQgJiYgcmVjb3Jkc0VxdWFsKG9sZFJlY29yZCwgdXBkYXRlZCwgdGhpcy5sb2NhbEZpZWxkcyk7XG4gICAgY29uc3Qga2VlcFN5bmNlZCA9IGlzSWRlbnRpY2FsICYmIG9sZFJlY29yZC5fc3RhdHVzID09IFwic3luY2VkXCI7XG4gICAgY29uc3QgbmV2ZXJTeW5jZWQgPVxuICAgICAgIW9sZFJlY29yZCB8fCAob2xkUmVjb3JkICYmIG9sZFJlY29yZC5fc3RhdHVzID09IFwiY3JlYXRlZFwiKTtcbiAgICBjb25zdCBuZXdTdGF0dXMgPVxuICAgICAga2VlcFN5bmNlZCB8fCBzeW5jZWQgPyBcInN5bmNlZFwiIDogbmV2ZXJTeW5jZWQgPyBcImNyZWF0ZWRcIiA6IFwidXBkYXRlZFwiO1xuICAgIHJldHVybiBtYXJrU3RhdHVzKHVwZGF0ZWQsIG5ld1N0YXR1cyk7XG4gIH1cblxuICAvKipcbiAgICogVXBzZXJ0IGEgcmVjb3JkIGludG8gdGhlIGxvY2FsIGRhdGFiYXNlLlxuICAgKlxuICAgKiBUaGlzIHJlY29yZCBtdXN0IGhhdmUgYW4gSUQuXG4gICAqXG4gICAqIElmIGEgcmVjb3JkIHdpdGggdGhpcyBJRCBhbHJlYWR5IGV4aXN0cywgaXQgd2lsbCBiZSByZXBsYWNlZC5cbiAgICogT3RoZXJ3aXNlLCB0aGlzIHJlY29yZCB3aWxsIGJlIGluc2VydGVkLlxuICAgKlxuICAgKiBAcGFyYW0gIHtPYmplY3R9IHJlY29yZFxuICAgKiBAcmV0dXJuIHtPYmplY3R9XG4gICAqL1xuICB1cHNlcnQocmVjb3JkKSB7XG4gICAgaWYgKHR5cGVvZiByZWNvcmQgIT09IFwib2JqZWN0XCIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlJlY29yZCBpcyBub3QgYW4gb2JqZWN0LlwiKTtcbiAgICB9XG4gICAgaWYgKCFyZWNvcmQuaGFzT3duUHJvcGVydHkoXCJpZFwiKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQ2Fubm90IHVwZGF0ZSBhIHJlY29yZCBtaXNzaW5nIGlkLlwiKTtcbiAgICB9XG4gICAgaWYgKCF0aGlzLmNvbGxlY3Rpb24uaWRTY2hlbWEudmFsaWRhdGUocmVjb3JkLmlkKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIElkOiAke3JlY29yZC5pZH1gKTtcbiAgICB9XG4gICAgbGV0IG9sZFJlY29yZCA9IHRoaXMuYWRhcHRlclRyYW5zYWN0aW9uLmdldChyZWNvcmQuaWQpO1xuICAgIGNvbnN0IHVwZGF0ZWQgPSB0aGlzLl91cGRhdGVSYXcob2xkUmVjb3JkLCByZWNvcmQpO1xuICAgIHRoaXMuYWRhcHRlclRyYW5zYWN0aW9uLnVwZGF0ZSh1cGRhdGVkKTtcbiAgICAvLyBEb24ndCByZXR1cm4gZGVsZXRlZCByZWNvcmRzIC0tIHByZXRlbmQgdGhleSBhcmUgZ29uZVxuICAgIGlmIChvbGRSZWNvcmQgJiYgb2xkUmVjb3JkLl9zdGF0dXMgPT0gXCJkZWxldGVkXCIpIHtcbiAgICAgIG9sZFJlY29yZCA9IHVuZGVmaW5lZDtcbiAgICB9XG4gICAgaWYgKG9sZFJlY29yZCkge1xuICAgICAgdGhpcy5fcXVldWVFdmVudChcInVwZGF0ZVwiLCB7IGRhdGE6IHVwZGF0ZWQsIG9sZFJlY29yZCB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5fcXVldWVFdmVudChcImNyZWF0ZVwiLCB7IGRhdGE6IHVwZGF0ZWQgfSk7XG4gICAgfVxuICAgIHJldHVybiB7IGRhdGE6IHVwZGF0ZWQsIG9sZFJlY29yZCwgcGVybWlzc2lvbnM6IHt9IH07XG4gIH1cbn1cbiIsIlwidXNlIHN0cmljdFwiO1xuXG5pbXBvcnQgeyBFdmVudEVtaXR0ZXIgfSBmcm9tIFwiZXZlbnRzXCI7XG5cbi8vIGJhYmVsLXBvbHlmaWxsIGNhbiBvbmx5IGJlIGltcG9ydGVkIG9uY2VcbmlmICghZ2xvYmFsLl9iYWJlbFBvbHlmaWxsKSB7XG4gIHJlcXVpcmUoXCJAYmFiZWwvcG9seWZpbGxcIik7XG59XG5cbmltcG9ydCBBcGkgZnJvbSBcImtpbnRvLWh0dHBcIjtcbmltcG9ydCBCYXNlQWRhcHRlciBmcm9tIFwiLi9hZGFwdGVycy9iYXNlXCI7XG5pbXBvcnQgSURCIGZyb20gXCIuL2FkYXB0ZXJzL0lEQlwiO1xuaW1wb3J0IEtpbnRvQmFzZSBmcm9tIFwiLi9LaW50b0Jhc2VcIjtcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgS2ludG8gZXh0ZW5kcyBLaW50b0Jhc2Uge1xuICAvKipcbiAgICogUHJvdmlkZXMgYSBwdWJsaWMgYWNjZXNzIHRvIHRoZSBiYXNlIGFkYXB0ZXIgY2xhc3Nlcy4gVXNlcnMgY2FuIGNyZWF0ZVxuICAgKiBhIGN1c3RvbSBEQiBhZGFwdGVyIGJ5IGV4dGVuZGluZyBCYXNlQWRhcHRlci5cbiAgICpcbiAgICogQHR5cGUge09iamVjdH1cbiAgICovXG4gIHN0YXRpYyBnZXQgYWRhcHRlcnMoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIEJhc2VBZGFwdGVyLFxuICAgICAgSURCLFxuICAgIH07XG4gIH1cblxuICBjb25zdHJ1Y3RvcihvcHRpb25zID0ge30pIHtcbiAgICBjb25zdCBkZWZhdWx0cyA9IHtcbiAgICAgIGFkYXB0ZXI6IEtpbnRvLmFkYXB0ZXJzLklEQixcbiAgICAgIGV2ZW50czogbmV3IEV2ZW50RW1pdHRlcigpLFxuICAgICAgQXBpQ2xhc3M6IEFwaSxcbiAgICB9O1xuXG4gICAgc3VwZXIoeyAuLi5kZWZhdWx0cywgLi4ub3B0aW9ucyB9KTtcbiAgfVxufVxuXG4vLyBUaGlzIGZpeGVzIGNvbXBhdGliaWxpdHkgd2l0aCBDb21tb25KUyByZXF1aXJlZCBieSBicm93c2VyaWZ5LlxuLy8gU2VlIGh0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvMzM1MDU5OTIvYmFiZWwtNi1jaGFuZ2VzLWhvdy1pdC1leHBvcnRzLWRlZmF1bHQvMzM2ODM0OTUjMzM2ODM0OTVcbmlmICh0eXBlb2YgbW9kdWxlID09PSBcIm9iamVjdFwiKSB7XG4gIG1vZHVsZS5leHBvcnRzID0gS2ludG87XG59XG4iLCJcInVzZSBzdHJpY3RcIjtcblxuZXhwb3J0IGNvbnN0IFJFX1JFQ09SRF9JRCA9IC9eW2EtekEtWjAtOV1bYS16QS1aMC05Xy1dKiQvO1xuXG4vKipcbiAqIENoZWNrcyBpZiBhIHZhbHVlIGlzIHVuZGVmaW5lZC5cbiAqIEBwYXJhbSAge0FueX0gIHZhbHVlXG4gKiBAcmV0dXJuIHtCb29sZWFufVxuICovXG5mdW5jdGlvbiBfaXNVbmRlZmluZWQodmFsdWUpIHtcbiAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PT0gXCJ1bmRlZmluZWRcIjtcbn1cblxuLyoqXG4gKiBTb3J0cyByZWNvcmRzIGluIGEgbGlzdCBhY2NvcmRpbmcgdG8gYSBnaXZlbiBvcmRlcmluZy5cbiAqXG4gKiBAcGFyYW0gIHtTdHJpbmd9IG9yZGVyIFRoZSBvcmRlcmluZywgZWcuIGAtbGFzdF9tb2RpZmllZGAuXG4gKiBAcGFyYW0gIHtBcnJheX0gIGxpc3QgIFRoZSBjb2xsZWN0aW9uIHRvIG9yZGVyLlxuICogQHJldHVybiB7QXJyYXl9XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzb3J0T2JqZWN0cyhvcmRlciwgbGlzdCkge1xuICBjb25zdCBoYXNEYXNoID0gb3JkZXJbMF0gPT09IFwiLVwiO1xuICBjb25zdCBmaWVsZCA9IGhhc0Rhc2ggPyBvcmRlci5zbGljZSgxKSA6IG9yZGVyO1xuICBjb25zdCBkaXJlY3Rpb24gPSBoYXNEYXNoID8gLTEgOiAxO1xuICByZXR1cm4gbGlzdC5zbGljZSgpLnNvcnQoKGEsIGIpID0+IHtcbiAgICBpZiAoYVtmaWVsZF0gJiYgX2lzVW5kZWZpbmVkKGJbZmllbGRdKSkge1xuICAgICAgcmV0dXJuIGRpcmVjdGlvbjtcbiAgICB9XG4gICAgaWYgKGJbZmllbGRdICYmIF9pc1VuZGVmaW5lZChhW2ZpZWxkXSkpIHtcbiAgICAgIHJldHVybiAtZGlyZWN0aW9uO1xuICAgIH1cbiAgICBpZiAoX2lzVW5kZWZpbmVkKGFbZmllbGRdKSAmJiBfaXNVbmRlZmluZWQoYltmaWVsZF0pKSB7XG4gICAgICByZXR1cm4gMDtcbiAgICB9XG4gICAgcmV0dXJuIGFbZmllbGRdID4gYltmaWVsZF0gPyBkaXJlY3Rpb24gOiAtZGlyZWN0aW9uO1xuICB9KTtcbn1cblxuLyoqXG4gKiBUZXN0IGlmIGEgc2luZ2xlIG9iamVjdCBtYXRjaGVzIGFsbCBnaXZlbiBmaWx0ZXJzLlxuICpcbiAqIEBwYXJhbSAge09iamVjdH0gZmlsdGVycyAgVGhlIGZpbHRlcnMgb2JqZWN0LlxuICogQHBhcmFtICB7T2JqZWN0fSBlbnRyeSAgICBUaGUgb2JqZWN0IHRvIGZpbHRlci5cbiAqIEByZXR1cm4ge0Jvb2xlYW59XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBmaWx0ZXJPYmplY3QoZmlsdGVycywgZW50cnkpIHtcbiAgcmV0dXJuIE9iamVjdC5rZXlzKGZpbHRlcnMpLmV2ZXJ5KGZpbHRlciA9PiB7XG4gICAgY29uc3QgdmFsdWUgPSBmaWx0ZXJzW2ZpbHRlcl07XG4gICAgaWYgKEFycmF5LmlzQXJyYXkodmFsdWUpKSB7XG4gICAgICByZXR1cm4gdmFsdWUuc29tZShjYW5kaWRhdGUgPT4gY2FuZGlkYXRlID09PSBlbnRyeVtmaWx0ZXJdKTtcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gXCJvYmplY3RcIikge1xuICAgICAgcmV0dXJuIGZpbHRlck9iamVjdCh2YWx1ZSwgZW50cnlbZmlsdGVyXSk7XG4gICAgfSBlbHNlIGlmICghZW50cnkuaGFzT3duUHJvcGVydHkoZmlsdGVyKSkge1xuICAgICAgY29uc29sZS5lcnJvcihgVGhlIHByb3BlcnR5ICR7ZmlsdGVyfSBkb2VzIG5vdCBleGlzdGApO1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4gZW50cnlbZmlsdGVyXSA9PT0gdmFsdWU7XG4gIH0pO1xufVxuXG4vKipcbiAqIEZpbHRlcnMgcmVjb3JkcyBpbiBhIGxpc3QgbWF0Y2hpbmcgYWxsIGdpdmVuIGZpbHRlcnMuXG4gKlxuICogQHBhcmFtICB7T2JqZWN0fSBmaWx0ZXJzICBUaGUgZmlsdGVycyBvYmplY3QuXG4gKiBAcGFyYW0gIHtBcnJheX0gIGxpc3QgICAgIFRoZSBjb2xsZWN0aW9uIHRvIGZpbHRlci5cbiAqIEByZXR1cm4ge0FycmF5fVxuICovXG5leHBvcnQgZnVuY3Rpb24gZmlsdGVyT2JqZWN0cyhmaWx0ZXJzLCBsaXN0KSB7XG4gIHJldHVybiBsaXN0LmZpbHRlcihlbnRyeSA9PiB7XG4gICAgcmV0dXJuIGZpbHRlck9iamVjdChmaWx0ZXJzLCBlbnRyeSk7XG4gIH0pO1xufVxuXG4vKipcbiAqIFJlc29sdmVzIGEgbGlzdCBvZiBmdW5jdGlvbnMgc2VxdWVudGlhbGx5LCB3aGljaCBjYW4gYmUgc3luYyBvciBhc3luYzsgaW5cbiAqIGNhc2Ugb2YgYXN5bmMsIGZ1bmN0aW9ucyBtdXN0IHJldHVybiBhIHByb21pc2UuXG4gKlxuICogQHBhcmFtICB7QXJyYXl9IGZucyAgVGhlIGxpc3Qgb2YgZnVuY3Rpb25zLlxuICogQHBhcmFtICB7QW55fSAgIGluaXQgVGhlIGluaXRpYWwgdmFsdWUuXG4gKiBAcmV0dXJuIHtQcm9taXNlfVxuICovXG5leHBvcnQgZnVuY3Rpb24gd2F0ZXJmYWxsKGZucywgaW5pdCkge1xuICBpZiAoIWZucy5sZW5ndGgpIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKGluaXQpO1xuICB9XG4gIHJldHVybiBmbnMucmVkdWNlKChwcm9taXNlLCBuZXh0Rm4pID0+IHtcbiAgICByZXR1cm4gcHJvbWlzZS50aGVuKG5leHRGbik7XG4gIH0sIFByb21pc2UucmVzb2x2ZShpbml0KSk7XG59XG5cbi8qKlxuICogU2ltcGxlIGRlZXAgb2JqZWN0IGNvbXBhcmlzb24gZnVuY3Rpb24uIFRoaXMgb25seSBzdXBwb3J0cyBjb21wYXJpc29uIG9mXG4gKiBzZXJpYWxpemFibGUgSmF2YVNjcmlwdCBvYmplY3RzLlxuICpcbiAqIEBwYXJhbSAge09iamVjdH0gYSBUaGUgc291cmNlIG9iamVjdC5cbiAqIEBwYXJhbSAge09iamVjdH0gYiBUaGUgY29tcGFyZWQgb2JqZWN0LlxuICogQHJldHVybiB7Qm9vbGVhbn1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRlZXBFcXVhbChhLCBiKSB7XG4gIGlmIChhID09PSBiKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgaWYgKHR5cGVvZiBhICE9PSB0eXBlb2YgYikge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBpZiAoIShhICYmIHR5cGVvZiBhID09IFwib2JqZWN0XCIpIHx8ICEoYiAmJiB0eXBlb2YgYiA9PSBcIm9iamVjdFwiKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBpZiAoT2JqZWN0LmtleXMoYSkubGVuZ3RoICE9PSBPYmplY3Qua2V5cyhiKS5sZW5ndGgpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgZm9yIChjb25zdCBrIGluIGEpIHtcbiAgICBpZiAoIWRlZXBFcXVhbChhW2tdLCBiW2tdKSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuICByZXR1cm4gdHJ1ZTtcbn1cblxuLyoqXG4gKiBSZXR1cm4gYW4gb2JqZWN0IHdpdGhvdXQgdGhlIHNwZWNpZmllZCBrZXlzLlxuICpcbiAqIEBwYXJhbSAge09iamVjdH0gb2JqICAgICAgICBUaGUgb3JpZ2luYWwgb2JqZWN0LlxuICogQHBhcmFtICB7QXJyYXl9ICBrZXlzICAgICAgIFRoZSBsaXN0IG9mIGtleXMgdG8gZXhjbHVkZS5cbiAqIEByZXR1cm4ge09iamVjdH0gICAgICAgICAgICBBIGNvcHkgd2l0aG91dCB0aGUgc3BlY2lmaWVkIGtleXMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBvbWl0S2V5cyhvYmosIGtleXMgPSBbXSkge1xuICBjb25zdCByZXN1bHQgPSB7IC4uLm9iaiB9O1xuICBmb3IgKGNvbnN0IGtleSBvZiBrZXlzKSB7XG4gICAgZGVsZXRlIHJlc3VsdFtrZXldO1xuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhcnJheUVxdWFsKGEsIGIpIHtcbiAgaWYgKGEubGVuZ3RoICE9PSBiLmxlbmd0aCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBmb3IgKGxldCBpID0gYS5sZW5ndGg7IGktLTsgKSB7XG4gICAgaWYgKGFbaV0gIT09IGJbaV0pIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHRydWU7XG59XG5cbmZ1bmN0aW9uIG1ha2VOZXN0ZWRPYmplY3RGcm9tQXJyKGFyciwgdmFsLCBuZXN0ZWRGaWx0ZXJzT2JqKSB7XG4gIGNvbnN0IGxhc3QgPSBhcnIubGVuZ3RoIC0gMTtcbiAgcmV0dXJuIGFyci5yZWR1Y2UoKGFjYywgY3YsIGkpID0+IHtcbiAgICBpZiAoaSA9PT0gbGFzdCkge1xuICAgICAgcmV0dXJuIChhY2NbY3ZdID0gdmFsKTtcbiAgICB9IGVsc2UgaWYgKGFjYy5oYXNPd25Qcm9wZXJ0eShjdikpIHtcbiAgICAgIHJldHVybiBhY2NbY3ZdO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gKGFjY1tjdl0gPSB7fSk7XG4gICAgfVxuICB9LCBuZXN0ZWRGaWx0ZXJzT2JqKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHRyYW5zZm9ybVN1Yk9iamVjdEZpbHRlcnMoZmlsdGVyc09iaikge1xuICBjb25zdCB0cmFuc2Zvcm1lZEZpbHRlcnMgPSB7fTtcbiAgZm9yIChjb25zdCBrZXkgaW4gZmlsdGVyc09iaikge1xuICAgIGNvbnN0IGtleXNBcnIgPSBrZXkuc3BsaXQoXCIuXCIpO1xuICAgIGNvbnN0IHZhbCA9IGZpbHRlcnNPYmpba2V5XTtcbiAgICBtYWtlTmVzdGVkT2JqZWN0RnJvbUFycihrZXlzQXJyLCB2YWwsIHRyYW5zZm9ybWVkRmlsdGVycyk7XG4gIH1cbiAgcmV0dXJuIHRyYW5zZm9ybWVkRmlsdGVycztcbn1cbiJdfQ==