PHP WebShell
Текущая директория: /usr/lib/node_modules/bitgo/node_modules/@bitgo/unspents/dist/src
Просмотр файла: dimensions.js
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.Dimensions = exports.OutputDimensions = void 0;
const utxolib = __importStar(require("@bitgo/utxo-lib"));
const utxo_lib_1 = require("@bitgo/utxo-lib");
const { isChainCode, scriptTypeForChain } = utxo_lib_1.bitgo;
const scriptSizes_1 = require("./scriptSizes");
const types_1 = require("./types");
const virtualSizes_1 = require("./virtualSizes");
/**
* Apply `f` to all properties of `d`
*/
function mapDimensions(d, f) {
return new Dimensions(Object.fromEntries(Object.entries(d).map(([key, value]) => [key, f(key, value)])));
}
/**
* Aggregate count and size of transaction outputs
*/
class OutputDimensions {
constructor({ count = 0, size = 0 } = { count: 0, size: 0 }) {
if (count === 0 || size === 0) {
if (count !== 0 || size !== 0) {
throw new Error(`count and size must both be zero if one is zero`);
}
}
this.count = count;
this.size = size;
Object.freeze(this);
}
}
exports.OutputDimensions = OutputDimensions;
const defaultUnspentParams = {
p2tr: {
// Default to recovery script paths, to make it easier for recovery case callers (WRW etc).
// WP can explicitly pass scriptPathLevel: 1 to use happy path.
scriptPathLevel: 2,
},
p2trMusig2: {
// Default to script path spend, to make it easier for recovery case callers (WRW etc).
// WP can explicitly pass scriptPathLevel: undefined to use key path.
scriptPathLevel: 1,
},
};
/**
* Dimensions of a BitGo wallet transactions.
*/
class Dimensions {
constructor(d = {}) {
/** Input counts for BitGo wallet multi-signature inputs */
this.nP2shInputs = 0;
this.nP2shP2wshInputs = 0;
this.nP2wshInputs = 0;
this.nP2trKeypathInputs = 0;
this.nP2trScriptPathLevel1Inputs = 0;
this.nP2trScriptPathLevel2Inputs = 0;
/* Input count for single-signature inputs (Replay Protection inputs) */
this.nP2shP2pkInputs = 0;
this.outputs = new OutputDimensions();
Object.entries(d).forEach(([key, value]) => this.setProperty(key, value));
Object.freeze(this);
}
setProperty(k, v) {
switch (k) {
case 'nP2shInputs':
case 'nP2shP2wshInputs':
case 'nP2wshInputs':
case 'nP2trKeypathInputs':
case 'nP2trScriptPathLevel1Inputs':
case 'nP2trScriptPathLevel2Inputs':
case 'nP2shP2pkInputs':
if (typeof v !== 'number') {
throw new Error(`property ${k} must be number`);
}
if (!Number.isSafeInteger(v) || v < 0) {
throw new Error(`property ${k} must be zero or positive integer`);
}
break;
case 'outputs':
if (!(v instanceof OutputDimensions)) {
v = new OutputDimensions(v);
}
break;
default:
throw new Error(`unknown property ${k}`);
}
this[k] = v;
}
/**
* @deprecated use ZERO
* @return Dimensions for an empty transaction
*/
static zero() {
return this.ZERO;
}
/**
* @param size
* @return Dimensions for a single output with given size
*/
static singleOutput(size) {
return Dimensions.sum({ outputs: { count: 1, size } });
}
/**
* @return Number of total inputs (p2sh + p2shP2wsh + p2wsh + p2tr)
*/
get nInputs() {
return (this.nP2shInputs +
this.nP2shP2wshInputs +
this.nP2wshInputs +
this.nP2trKeypathInputs +
this.nP2trScriptPathLevel1Inputs +
this.nP2trScriptPathLevel2Inputs +
this.nP2shP2pkInputs);
}
set nInputs(_) {
throw new Error('read-only property nInputs');
}
/**
* @return Number of total outputs
*/
get nOutputs() {
return this.outputs.count;
}
set nOutputs(_) {
throw new Error(`read-only property nOutputs`);
}
/**
* @param args - Dimensions (can be partially defined)
* @return {Dimensions} sum of arguments
*/
static sum(...args) {
return args.reduce((a, b) => a.plus(b), new Dimensions());
}
/**
* @param chain
* @return {Number}
*/
static getOutputScriptLengthForChain(chain) {
switch (scriptTypeForChain(chain)) {
case 'p2wsh':
case 'p2tr':
case 'p2trMusig2':
return 34;
default:
return 23;
}
}
/**
* @param scriptLength
* @return {Number} vSize of an output with script length
*/
static getVSizeForOutputWithScriptLength(scriptLength) {
if (!types_1.PositiveInteger.is(scriptLength)) {
throw new TypeError(`expected positive integer for scriptLength, got ${scriptLength}`);
}
return scriptLength + (0, scriptSizes_1.compactSize)(scriptLength) + virtualSizes_1.VirtualSizes.txOutputAmountSize;
}
/**
* @return
*/
static fromScriptType(scriptType, params = {}) {
switch (scriptType) {
case 'p2sh':
case 'p2shP2wsh':
case 'p2wsh':
case 'p2shP2pk':
return Dimensions.SingleInput[scriptType];
case 'p2tr':
case 'taprootScriptPathSpend':
switch (params.scriptPathLevel) {
case 1:
return Dimensions.SingleInput.p2trScriptPathLevel1;
case 2:
return Dimensions.SingleInput.p2trScriptPathLevel2;
default:
throw new Error(`unexpected script path level`);
}
case 'p2trMusig2':
switch (params.scriptPathLevel) {
case undefined:
return Dimensions.SingleInput.p2trKeypath;
case 1:
return Dimensions.SingleInput.p2trScriptPathLevel1;
default:
throw new Error(`unexpected script path level`);
}
case 'taprootKeyPathSpend':
return Dimensions.SingleInput.p2trKeypath;
default:
throw new Error(`unexpected scriptType ${scriptType}`);
}
}
static getAssumedDimension(params = {}, index) {
const { assumeUnsigned } = params;
if (!assumeUnsigned) {
throw new Error(`illegal input ${index}: empty script and assumeUnsigned not set`);
}
return assumeUnsigned;
}
/**
* @param input - the transaction input to count
* @param params
* [param.assumeUnsigned] - default type for unsigned input
*/
static fromInput(input, params = {}) {
if (input.script?.length || input.witness?.length) {
const parsed = utxolib.bitgo.parseSignatureScript(input);
return Dimensions.fromScriptType(parsed.scriptType, parsed);
}
return Dimensions.getAssumedDimension(params, input.index);
}
/**
* Create Dimensions from psbt input
* @param input - psbt input
*/
static fromPsbtInput(input) {
const parsed = utxo_lib_1.bitgo.parsePsbtInput(input);
return Dimensions.fromScriptType(parsed.scriptType, parsed);
}
/**
* @param inputs - Array of inputs
* @param params - @see Dimensions.fromInput()
* @return {Dimensions} sum of the dimensions for each input (@see Dimensions.fromInput())
*/
static fromInputs(inputs, params) {
if (!Array.isArray(inputs)) {
throw new TypeError(`inputs must be array`);
}
return Dimensions.sum(...inputs.map((i) => Dimensions.fromInput(i, params)));
}
/**
* Create Dimensions from multiple psbt inputs
* @param inputs psbt input array
* @return {Dimensions} sum of the dimensions for each input (@see Dimensions.fromPsbtInput())
*/
static fromPsbtInputs(inputs) {
if (!Array.isArray(inputs)) {
throw new TypeError(`inputs must be array`);
}
return Dimensions.sum(...inputs.map((input, _) => Dimensions.fromPsbtInput(input)));
}
/**
* @param scriptLength {number} - size of the output script in bytes
* @return {Dimensions} - Dimensions of the output
*/
static fromOutputScriptLength(scriptLength) {
return Dimensions.sum({
outputs: {
count: 1,
size: Dimensions.getVSizeForOutputWithScriptLength(scriptLength),
},
});
}
/**
* @param output - a tx output
* @return Dimensions - the dimensions of the given output
*/
static fromOutput({ script }) {
if (!script) {
throw new Error('expected output script to be defined');
}
if (!Buffer.isBuffer(script)) {
throw new TypeError('expected script to be buffer, got ' + typeof script);
}
return Dimensions.fromOutputScriptLength(script.length);
}
/**
* @param outputs - Array of outputs
* @return {Dimensions} sum of the dimensions for each output (@see Dimensions.fromOutput())
*/
static fromOutputs(outputs) {
if (!Array.isArray(outputs)) {
throw new TypeError(`outputs must be array`);
}
return Dimensions.sum(...outputs.map(Dimensions.fromOutput));
}
/**
* Returns the dimensions of an output that will be created on a specific chain.
* Currently, this simply adds a default output.
*
* @param chain - Chain code as defined by utxolib.bitgo
* @return {Dimensions} - Dimensions for a single output on the given chain.
*/
static fromOutputOnChain(chain) {
return Dimensions.fromOutputScriptLength(Dimensions.getOutputScriptLengthForChain(chain));
}
/**
* Return dimensions of an unspent according to `chain` parameter
* @param chain - Chain code as defined by utxo.chain
* @param params - Hint for unspents with variable input sizes (p2tr, p2trMusig2)
* @return {Dimensions} of the unspent
* @throws if the chain code is invalid or unsupported
*/
static fromUnspent({ chain }, params = defaultUnspentParams) {
if (!isChainCode(chain)) {
throw new TypeError('invalid chain code');
}
const scriptType = scriptTypeForChain(chain);
return Dimensions.fromScriptType(scriptType, scriptType === 'p2tr' ? params.p2tr : scriptType === 'p2trMusig2' ? params.p2trMusig2 : {});
}
/**
* @param unspents
* @param params - Hint for unspents with variable input sizes (p2tr, p2trMusig2)
* @return {Dimensions} sum of the dimensions for each unspent (@see Dimensions.fromUnspent())
*/
static fromUnspents(unspents, params = defaultUnspentParams) {
if (!Array.isArray(unspents)) {
throw new TypeError(`unspents must be array`);
}
// Convert the individual unspents into dimensions and sum them up
return Dimensions.sum(...unspents.map((u) => Dimensions.fromUnspent(u, params)));
}
/**
* @param transaction - bitcoin-like transaction
* @param [param.assumeUnsigned] - default type for unsigned inputs
* @return {Dimensions}
*/
static fromTransaction({ ins, outs, }, params) {
return Dimensions.fromInputs(ins, params).plus(Dimensions.fromOutputs(outs));
}
/**
* Create Dimensions from psbt inputs and outputs
* @param psbt
* @return {Dimensions}
*/
static fromPsbt(psbt) {
return Dimensions.fromPsbtInputs(psbt.data.inputs).plus(Dimensions.fromOutputs(psbt.getUnsignedTx().outs));
}
/**
* @param dimensions (can be partially defined)
* @return new dimensions with argument added
*/
plus(dimensions) {
if (typeof dimensions !== 'object') {
throw new TypeError(`expected argument to be object`);
}
if (!(dimensions instanceof Dimensions)) {
dimensions = new Dimensions(dimensions);
}
// Catch instances where we try to initialize Dimensions from partial data using deprecated parameters
// using only "nOutputs".
if ('nOutputs' in dimensions) {
if (!('outputs' in dimensions)) {
throw new Error('deprecated partial addition: argument has key "nOutputs" but no "outputs"');
}
const { outputs, nOutputs } = dimensions;
if (outputs.count !== nOutputs) {
throw new Error('deprecated partial addition: inconsistent values for "nOutputs" and "outputs.count"');
}
}
return mapDimensions(this, (key, v) => {
const w = dimensions[key] ?? Dimensions.ZERO[key];
if (key === 'outputs') {
const vOutputs = v;
const wOutputs = w;
return new OutputDimensions({
count: vOutputs.count + wOutputs.count,
size: vOutputs.size + wOutputs.size,
});
}
return v + w;
});
}
/**
* Multiply dimensions by a given factor
* @param factor - Positive integer
* @return {Dimensions}
*/
times(factor) {
if (!types_1.PositiveInteger.is(factor)) {
throw new TypeError(`expected factor to be positive integer`);
}
return mapDimensions(this, (key, value) => {
if (key === 'outputs') {
const vOutputs = value;
return {
count: vOutputs.count * factor,
size: vOutputs.size * factor,
};
}
return value * factor;
});
}
/**
* @return Number of total inputs (p2sh, p2shP2wsh and p2wsh)
* @deprecated use `dimension.nInputs` instead
*/
getNInputs() {
return this.nInputs;
}
/**
* @returns {boolean} true iff dimensions have one or more (p2sh)p2wsh inputs
*/
isSegwit() {
return (this.nP2wshInputs +
this.nP2shP2wshInputs +
this.nP2trKeypathInputs +
this.nP2trScriptPathLevel1Inputs +
this.nP2trScriptPathLevel2Inputs >
0);
}
/**
* @return {Number} overhead vsize, based on result isSegwit().
*/
getOverheadVSize() {
return this.isSegwit() ? virtualSizes_1.VirtualSizes.txSegOverheadVSize : virtualSizes_1.VirtualSizes.txOverheadSize;
}
/**
* @returns {number} vsize of inputs, without transaction overhead
*/
getInputsVSize() {
const { txP2shInputSize, txP2shP2wshInputSize, txP2wshInputSize, txP2trKeypathInputSize, txP2trScriptPathLevel1InputSize, txP2trScriptPathLevel2InputSize, txP2shP2pkInputSize, } = virtualSizes_1.VirtualSizes;
const { nP2shInputs, nP2shP2wshInputs, nP2wshInputs, nP2trKeypathInputs, nP2trScriptPathLevel1Inputs, nP2trScriptPathLevel2Inputs, nP2shP2pkInputs, } = this;
const size = nP2shInputs * txP2shInputSize +
nP2shP2wshInputs * txP2shP2wshInputSize +
nP2wshInputs * txP2wshInputSize +
nP2trKeypathInputs * txP2trKeypathInputSize +
nP2shP2pkInputs * txP2shP2pkInputSize +
nP2trScriptPathLevel1Inputs * txP2trScriptPathLevel1InputSize +
nP2trScriptPathLevel2Inputs * txP2trScriptPathLevel2InputSize;
if (Number.isNaN(size)) {
throw new Error(`invalid size`);
}
return size;
}
/**
* @returns {number} return vsize of outputs, without overhead
*/
getOutputsVSize() {
return this.outputs.size;
}
/**
* Estimates the virtual size (1/4 weight) of a signed transaction as sum of
* overhead vsize, input vsize and output vsize.
* @returns {Number} The estimated vsize of the transaction dimensions.
*/
getVSize() {
return this.getOverheadVSize() + this.getInputsVSize() + this.getOutputsVSize();
}
}
exports.Dimensions = Dimensions;
Dimensions.ZERO = Object.freeze(new Dimensions());
// Initialize static properties that require the class to be fully defined first
Dimensions.SingleOutput = Object.freeze({
p2sh: Dimensions.singleOutput(virtualSizes_1.VirtualSizes.txP2shOutputSize),
p2shP2wsh: Dimensions.singleOutput(virtualSizes_1.VirtualSizes.txP2shP2wshOutputSize),
p2wsh: Dimensions.singleOutput(virtualSizes_1.VirtualSizes.txP2wshOutputSize),
p2tr: Dimensions.singleOutput(virtualSizes_1.VirtualSizes.txP2trOutputSize),
p2pkh: Dimensions.singleOutput(virtualSizes_1.VirtualSizes.txP2pkhOutputSize),
p2wpkh: Dimensions.singleOutput(virtualSizes_1.VirtualSizes.txP2wpkhOutputSize),
});
// Initialize SingleInput after the class is fully defined
Dimensions.SingleInput = Object.freeze({
p2sh: Dimensions.sum({ nP2shInputs: 1 }),
p2shP2wsh: Dimensions.sum({ nP2shP2wshInputs: 1 }),
p2wsh: Dimensions.sum({ nP2wshInputs: 1 }),
p2trKeypath: Dimensions.sum({ nP2trKeypathInputs: 1 }),
p2trScriptPathLevel1: Dimensions.sum({ nP2trScriptPathLevel1Inputs: 1 }),
p2trScriptPathLevel2: Dimensions.sum({ nP2trScriptPathLevel2Inputs: 1 }),
p2shP2pk: Dimensions.sum({ nP2shP2pkInputs: 1 }),
});
// Initialize the ASSUME_ constants
Dimensions.ASSUME_P2SH = Dimensions.SingleInput.p2sh;
Dimensions.ASSUME_P2SH_P2WSH = Dimensions.SingleInput.p2shP2wsh;
Dimensions.ASSUME_P2WSH = Dimensions.SingleInput.p2wsh;
Dimensions.ASSUME_P2TR_KEYPATH = Dimensions.SingleInput.p2trKeypath;
Dimensions.ASSUME_P2TR_SCRIPTPATH_LEVEL1 = Dimensions.SingleInput.p2trScriptPathLevel1;
Dimensions.ASSUME_P2TR_SCRIPTPATH_LEVEL2 = Dimensions.SingleInput.p2trScriptPathLevel2;
Dimensions.ASSUME_P2SH_P2PK_INPUT = Dimensions.SingleInput.p2shP2pk;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGltZW5zaW9ucy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9kaW1lbnNpb25zLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLHlEQUEyQztBQUMzQyw4Q0FBd0M7QUFDeEMsTUFBTSxFQUFFLFdBQVcsRUFBRSxrQkFBa0IsRUFBRSxHQUFHLGdCQUFLLENBQUM7QUFHbEQsK0NBQTRDO0FBQzVDLG1DQUEwQztBQUUxQyxpREFBOEM7QUFFOUM7O0dBRUc7QUFDSCxTQUFTLGFBQWEsQ0FDcEIsQ0FBc0IsRUFDdEIsQ0FBZ0Y7SUFFaEYsT0FBTyxJQUFJLFVBQVUsQ0FDbkIsTUFBTSxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUMsR0FBdUIsRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FDdEcsQ0FBQztBQUNKLENBQUM7QUFFRDs7R0FFRztBQUNILE1BQWEsZ0JBQWdCO0lBVTNCLFlBQVksRUFBRSxLQUFLLEdBQUcsQ0FBQyxFQUFFLElBQUksR0FBRyxDQUFDLEtBQXVCLEVBQUUsS0FBSyxFQUFFLENBQUMsRUFBRSxJQUFJLEVBQUUsQ0FBQyxFQUFFO1FBQzNFLElBQUksS0FBSyxLQUFLLENBQUMsSUFBSSxJQUFJLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDOUIsSUFBSSxLQUFLLEtBQUssQ0FBQyxJQUFJLElBQUksS0FBSyxDQUFDLEVBQUUsQ0FBQztnQkFDOUIsTUFBTSxJQUFJLEtBQUssQ0FBQyxpREFBaUQsQ0FBQyxDQUFDO1lBQ3JFLENBQUM7UUFDSCxDQUFDO1FBRUQsSUFBSSxDQUFDLEtBQUssR0FBRyxLQUFLLENBQUM7UUFDbkIsSUFBSSxDQUFDLElBQUks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QixHQUFHLFVBQVUsQ0FBQyxXQUFXLENBQUMsU0FBUyxDQUFDO0FBQ2hFLFVBQVUsQ0FBQyxZQUFZLEdBQUcsVUFBVSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUM7QUFDdkQsVUFBVSxDQUFDLG1CQUFtQixHQUFHLFVBQVUsQ0FBQyxXQUFXLENBQUMsV0FBVyxDQUFDO0FBQ3BFLFVBQVUsQ0FBQyw2QkFBNkIsR0FBRyxVQUFVLENBQUMsV0FBVyxDQUFDLG9CQUFvQixDQUFDO0FBQ3ZGLFVBQVUsQ0FBQyw2QkFBNkIsR0FBRyxVQUFVLENBQUMsV0FBVyxDQUFDLG9CQUFvQixDQUFDO0FBQ3ZGLFVBQVUsQ0FBQyxzQkFBc0IsR0FBRyxVQUFVLENBQUMsV0FBVyxDQUFDLFFBQVEsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIHV0eG9saWIgZnJvbSAnQGJpdGdvL3V0eG8tbGliJztcbmltcG9ydCB7IGJpdGdvIH0gZnJvbSAnQGJpdGdvL3V0eG8tbGliJztcbmNvbnN0IHsgaXNDaGFpbkNvZGUsIHNjcmlwdFR5cGVGb3JDaGFpbiB9ID0gYml0Z287XG50eXBlIENoYWluQ29kZSA9IGJpdGdvLkNoYWluQ29kZTtcblxuaW1wb3J0IHsgY29tcGFjdFNpemUgfSBmcm9tICcuL3NjcmlwdFNpemVzJztcbmltcG9ydCB7IFBvc2l0aXZlSW50ZWdlciB9IGZyb20gJy4vdHlwZXMnO1xuXG5pbXBvcnQgeyBWaXJ0dWFsU2l6ZXMgfSBmcm9tICcuL3ZpcnR1YWxTaXplcyc7XG5cbi8qKlxuICogQXBwbHkgYGZgIHRvIGFsbCBwcm9wZXJ0aWVzIG9mIGBkYFxuICovXG5mdW5jdGlvbiBtYXBEaW1lbnNpb25zKFxuICBkOiBQYXJ0aWFsPERpbWVuc2lvbnM+LFxuICBmOiA8VCBleHRlbmRzIGtleW9mIERpbWVuc2lvbnM+KGtleTogVCwgdjogRGltZW5zaW9uc1tUXSB8IHVuZGVmaW5lZCkgPT4gdW5rbm93blxuKTogRGltZW5zaW9ucyB7XG4gIHJldHVybiBuZXcgRGltZW5zaW9ucyhcbiAgICBPYmplY3QuZnJvbUVudHJpZXMoT2JqZWN0LmVudHJpZXMoZCkubWFwKChba2V5LCB2YWx1ZV0pID0+IFtrZXksIGYoa2V5IGFzIGtleW9mIERpbWVuc2lvbnMsIHZhbHVlKV0pKVxuICApO1xufVxuXG4vKipcbiAqIEFnZ3JlZ2F0ZSBjb3VudCBhbmQgc2l6ZSBvZiB0cmFuc2FjdGlvbiBvdXRwdXRzXG4gKi9cbmV4cG9ydCBjbGFzcyBPdXRwdXREaW1lbnNpb25zIHtcbiAgLyoqXG4gICAqIE51bWJlciBvZiBvdXRwdXRzXG4gICAqL1xuICBjb3VudDogbnVtYmVyO1xuICAvKipcbiAgICogQWdncmVnYXRlIHZTaXplXG4gICAqL1xuICBzaXplOiBudW1iZXI7XG5cbiAgY29uc3RydWN0b3IoeyBjb3VudCA9IDAsIHNpemUgPSAwIH06IE91dHB1dERpbWVuc2lvbnMgPSB7IGNvdW50OiAwLCBzaXplOiAwIH0pIHtcbiAgICBpZiAoY291bnQgPT09IDAgfHwgc2l6ZSA9PT0gMCkge1xuICAgICAgaWYgKGNvdW50ICE9PSAwIHx8IHNpemUgIT09IDApIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBjb3VudCBhbmQgc2l6ZSBtdXN0IGJvdGggYmUgemVybyBpZiBvbmUgaXMgemVyb2ApO1xuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMuY291bnQgPSBjb3VudDtcbiAgICB0aGlzLnNpemUgPSBzaXplO1xuXG4gICAgT2JqZWN0LmZyZWV6ZSh0aGlzKTtcbiAgfVxufVxuXG5pbnRlcmZhY2UgRnJvbUlucHV0UGFyYW1zIHtcbiAgLy8gSW4gY2FzZXMgd2hlcmUgdGhlIGlucHV0IHR5cGUgaXMgYW1iaWd1b3VzLCB3ZSBtdXN0IHByb3ZpZGUgYSBoaW50IGFib3V0IHNwZW5kIHNjcmlwdCB0eXBlLlxuICBhc3N1bWVVbnNpZ25lZD86IERpbWVuc2lvbnM7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgRnJvbVVuc3BlbnRQYXJhbXMge1xuICBwMnRyOiB7XG4gICAgc2NyaXB0UGF0aExldmVsPzogbnVtYmVyO1xuICB9O1xuICBwMnRyTXVzaWcyOiB7XG4gICAgc2NyaXB0UGF0aExldmVsPzogbnVtYmVyO1xuICB9O1xufVxuXG5jb25zdCBkZWZhdWx0VW5zcGVudFBhcmFtczogRnJvbVVuc3BlbnRQYXJhbXMgPSB7XG4gIHAydHI6IHtcbiAgICAvLyBEZWZhdWx0IHRvIHJlY292ZXJ5IHNjcmlwdCBwYXRocywgdG8gbWFrZSBpdCBlYXNpZXIgZm9yIHJlY292ZXJ5IGNhc2UgY2FsbGVycyAoV1JXIGV0YykuXG4gICAgLy8gV1AgY2FuIGV4cGxpY2l0bHkgcGFzcyBzY3JpcHRQYXRoTGV2ZWw6IDEgdG8gdXNlIGhhcHB5IHBhdGguXG4gICAgc2NyaXB0UGF0aExldmVsOiAyLFxuICB9LFxuICBwMnRyTXVzaWcyOiB7XG4gICAgLy8gRGVmYXVsdCB0byBzY3JpcHQgcGF0aCBzcGVuZCwgdG8gbWFrZSBpdCBlYXNpZXIgZm9yIHJlY292ZXJ5IGNhc2UgY2FsbGVycyAoV1JXIGV0YykuXG4gICAgLy8gV1AgY2FuIGV4cGxpY2l0bHkgcGFzcyBzY3JpcHRQYXRoTGV2ZWw6IHVuZGVmaW5lZCB0byB1c2Uga2V5IHBhdGguXG4gICAgc2NyaXB0UGF0aExldmVsOiAxLFxuICB9LFxufTtcblxuLyoqXG4gKiBEaW1lbnNpb25zIG9mIGEgQml0R28gd2FsbGV0IHRyYW5zYWN0aW9ucy5cbiAqL1xuZXhwb3J0IGNsYXNzIERpbWVuc2lvbnMge1xuICAvKiogSW5wdXQgY291bnRzIGZvciBCaXRHbyB3YWxsZXQgbXVsdGktc2lnbmF0dXJlIGlucHV0cyAqL1xuICBwdWJsaWMgcmVhZG9ubHkgblAyc2hJbnB1dHM6IG51bWJlciA9IDA7XG4gIHB1YmxpYyByZWFkb25seSBuUDJzaFAyd3NoSW5wdXRzOiBudW1iZXIgPSAwO1xuICBwdWJsaWMgcmVhZG9ubHkgblAyd3NoSW5wdXRzOiBudW1iZXIgPSAwO1xuICBwdWJsaWMgcmVhZG9ubHkgblAydHJLZXlwYXRoSW5wdXRzOiBudW1iZXIgPSAwO1xuICBwdWJsaWMgcmVhZG9ubHkgblAydHJTY3JpcHRQYXRoTGV2ZWwxSW5wdXRzOiBudW1iZXIgPSAwO1xuICBwdWJsaWMgcmVhZG9ubHkgblAydHJTY3JpcHRQYXRoTGV2ZWwySW5wdXRzOiBudW1iZXIgPSAwO1xuXG4gIC8qIElucHV0IGNvdW50IGZvciBzaW5nbGUtc2lnbmF0dXJlIGlucHV0cyAoUmVwbGF5IFByb3RlY3Rpb24gaW5wdXRzKSAqL1xuICBwdWJsaWMgcmVhZG9ubHkgblAyc2hQMnBrSW5wdXRzOiBudW1iZXIgPSAwO1xuXG4gIHB1YmxpYyByZWFkb25seSBvdXRwdXRzOiBPdXRwdXREaW1lbnNpb25zID0gbmV3IE91dHB1dERpbWVuc2lvbnMoKTtcblxuICBjb25zdHJ1Y3RvcihkOiBQYXJ0aWFsPERpbWVuc2lvbnM+ID0ge30pIHtcbiAgICBPYmplY3QuZW50cmllcyhkKS5mb3JFYWNoKChba2V5LCB2YWx1ZV0pID0+IHRoaXMuc2V0UHJvcGVydHkoa2V5LCB2YWx1ZSkpO1xuXG4gICAgT2JqZWN0LmZyZWV6ZSh0aGlzKTtcbiAgfVxuXG4gIHByaXZhdGUgc2V0UHJvcGVydHkoazogc3RyaW5nLCB2OiB1bmtub3duKTogdm9pZCB7XG4gICAgc3dpdGNoIChrKSB7XG4gICAgICBjYXNlICduUDJzaElucHV0cyc6XG4gICAgICBjYXNlICduUDJzaFAyd3NoSW5wdXRzJzpcbiAgICAgIGNhc2UgJ25QMndzaElucHV0cyc6XG4gICAgICBjYXNlICduUDJ0cktleXBhdGhJbnB1dHMnOlxuICAgICAgY2FzZSAnblAydHJTY3JpcHRQYXRoTGV2ZWwxSW5wdXRzJzpcbiAgICAgIGNhc2UgJ25QMnRyU2NyaXB0UGF0aExldmVsMklucHV0cyc6XG4gICAgICBjYXNlICduUDJzaFAycGtJbnB1dHMnOlxuICAgICAgICBpZiAodHlwZW9mIHYgIT09ICdudW1iZXInKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBwcm9wZXJ0eSAke2t9IG11c3QgYmUgbnVtYmVyYCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFOdW1iZXIuaXNTYWZlSW50ZWdlcih2KSB8fCB2IDwgMCkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgcHJvcGVydHkgJHtrfSBtdXN0IGJlIHplcm8gb3IgcG9zaXRpdmUgaW50ZWdlcmApO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnb3V0cHV0cyc6XG4gICAgICAgIGlmICghKHYgaW5zdGFuY2VvZiBPdXRwdXREaW1lbnNpb25zKSkge1xuICAgICAgICAgIHYgPSBuZXcgT3V0cHV0RGltZW5zaW9ucyh2IGFzIE91dHB1dERpbWVuc2lvbnMpO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGB1bmtub3duIHByb3BlcnR5ICR7a31gKTtcbiAgICB9XG5cbiAgICAodGhpcyBhcyBhbnkpW2tdID0gdjtcbiAgfVxuXG4gIHN0YXRpYyByZWFkb25seSBaRVJPID0gT2JqZWN0LmZyZWV6ZShuZXcgRGltZW5zaW9ucygpKTtcblxuICAvKipcbiAgICogQGRlcHJlY2F0ZWQgdXNlIFpFUk9cbiAgICogQHJldHVybiBEaW1lbnNpb25zIGZvciBhbiBlbXB0eSB0cmFuc2FjdGlvblxuICAgKi9cbiAgc3RhdGljIHplcm8oKTogUmVhZG9ubHk8RGltZW5zaW9ucz4ge1xuICAgIHJldHVybiB0aGlzLlpFUk87XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHNpemVcbiAgICogQHJldHVybiBEaW1lbnNpb25zIGZvciBhIHNpbmdsZSBvdXRwdXQgd2l0aCBnaXZlbiBzaXplXG4gICAqL1xuICBzdGF0aWMgc2luZ2xlT3V0cHV0KHNpemU6IG51bWJlcik6IERpbWVuc2lvbnMge1xuICAgIHJldHVybiBEaW1lbnNpb25zLnN1bSh7IG91dHB1dHM6IHsgY291bnQ6IDEsIHNpemUgfSB9KTtcbiAgfVxuXG4gIHN0YXRpYyBTaW5nbGVPdXRwdXQ6IHtcbiAgICBwMnNoOiBEaW1lbnNpb25zO1xuICAgIHAyc2hQMndzaDogRGltZW5zaW9ucztcbiAgICBwMndzaDogRGltZW5zaW9ucztcbiAgICBwMnRyOiBEaW1lbnNpb25zO1xuICAgIHAycGtoOiBEaW1lbnNpb25zO1xuICAgIHAyd3BraDogRGltZW5zaW9ucztcbiAgfTtcblxuICAvKipcbiAgICogQHJldHVybiBOdW1iZXIgb2YgdG90YWwgaW5wdXRzIChwMnNoICsgcDJzaFAyd3NoICsgcDJ3c2ggKyBwMnRyKVxuICAgKi9cbiAgZ2V0IG5JbnB1dHMoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gKFxuICAgICAgdGhpcy5uUDJzaElucHV0cyArXG4gICAgICB0aGlzLm5QMnNoUDJ3c2hJbnB1dHMgK1xuICAgICAgdGhpcy5uUDJ3c2hJbnB1dHMgK1xuICAgICAgdGhpcy5uUDJ0cktleXBhdGhJbnB1dHMgK1xuICAgICAgdGhpcy5uUDJ0clNjcmlwdFBhdGhMZXZlbDFJbnB1dHMgK1xuICAgICAgdGhpcy5uUDJ0clNjcmlwdFBhdGhMZXZlbDJJbnB1dHMgK1xuICAgICAgdGhpcy5uUDJzaFAycGtJbnB1dHNcbiAgICApO1xuICB9XG5cbiAgc2V0IG5JbnB1dHMoXzogbnVtYmVyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdyZWFkLW9ubHkgcHJvcGVydHkgbklucHV0cycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm4gTnVtYmVyIG9mIHRvdGFsIG91dHB1dHNcbiAgICovXG4gIGdldCBuT3V0cHV0cygpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLm91dHB1dHMuY291bnQ7XG4gIH1cblxuICBzZXQgbk91dHB1dHMoXzogbnVtYmVyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGByZWFkLW9ubHkgcHJvcGVydHkgbk91dHB1dHNgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0gYXJncyAtIERpbWVuc2lvbnMgKGNhbiBiZSBwYXJ0aWFsbHkgZGVmaW5lZClcbiAgICogQHJldHVybiB7RGltZW5zaW9uc30gc3VtIG9mIGFyZ3VtZW50c1xuICAgKi9cbiAgc3RhdGljIHN1bSguLi5hcmdzOiBQYXJ0aWFsPERpbWVuc2lvbnM+W10pOiBEaW1lbnNpb25zIHtcbiAgICByZXR1cm4gYXJncy5yZWR1Y2UoKGE6IERpbWVuc2lvbnMsIGI6IFBhcnRpYWw8RGltZW5zaW9ucz4pID0+IGEucGx1cyhiKSwgbmV3IERpbWVuc2lvbnMoKSk7XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIGNoYWluXG4gICAqIEByZXR1cm4ge051bWJlcn1cbiAgICovXG4gIHN0YXRpYyBnZXRPdXRwdXRTY3JpcHRMZW5ndGhGb3JDaGFpbihjaGFpbjogQ2hhaW5Db2RlKTogbnVtYmVyIHtcbiAgICBzd2l0Y2ggKHNjcmlwdFR5cGVGb3JDaGFpbihjaGFpbikpIHtcbiAgICAgIGNhc2UgJ3Ayd3NoJzpcbiAgICAgIGNhc2UgJ3AydHInOlxuICAgICAgY2FzZSAncDJ0ck11c2lnMic6XG4gICAgICAgIHJldHVybiAzNDtcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHJldHVybiAyMztcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHNjcmlwdExlbmd0aFxuICAgKiBAcmV0dXJuIHtOdW1iZXJ9IHZTaXplIG9mIGFuIG91dHB1dCB3aXRoIHNjcmlwdCBsZW5ndGhcbiAgICovXG4gIHN0YXRpYyBnZXRWU2l6ZUZvck91dHB1dFdpdGhTY3JpcHRMZW5ndGgoc2NyaXB0TGVuZ3RoOiBudW1iZXIpOiBudW1iZXIge1xuICAgIGlmICghUG9zaXRpdmVJbnRlZ2VyLmlzKHNjcmlwdExlbmd0aCkpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYGV4cGVjdGVkIHBvc2l0aXZlIGludGVnZXIgZm9yIHNjcmlwdExlbmd0aCwgZ290ICR7c2NyaXB0TGVuZ3RofWApO1xuICAgIH1cbiAgICByZXR1cm4gc2NyaXB0TGVuZ3RoICsgY29tcGFjdFNpemUoc2NyaXB0TGVuZ3RoKSArIFZpcnR1YWxTaXplcy50eE91dHB1dEFtb3VudFNpemU7XG4gIH1cblxuICBzdGF0aWMgU2luZ2xlSW5wdXQ6IHtcbiAgICBwMnNoOiBEaW1lbnNpb25zO1xuICAgIHAyc2hQMndzaDogRGltZW5zaW9ucztcbiAgICBwMndzaDogRGltZW5zaW9ucztcbiAgICBwMnRyS2V5cGF0aDogRGltZW5zaW9ucztcbiAgICBwMnRyU2NyaXB0UGF0aExldmVsMTogRGltZW5zaW9ucztcbiAgICBwMnRyU2NyaXB0UGF0aExldmVsMjogRGltZW5zaW9ucztcbiAgICBwMnNoUDJwazogRGltZW5zaW9ucztcbiAgfTtcblxuICAvKipcbiAgICogQHJldHVyblxuICAgKi9cbiAgc3RhdGljIGZyb21TY3JpcHRUeXBlKFxuICAgIHNjcmlwdFR5cGU6IHV0eG9saWIuYml0Z28ub3V0cHV0U2NyaXB0cy5TY3JpcHRUeXBlIHwgdXR4b2xpYi5iaXRnby5QYXJzZWRTY3JpcHRUeXBlMk9mMyB8ICdwMnBraCcsXG4gICAgcGFyYW1zOiB7XG4gICAgICBzY3JpcHRQYXRoTGV2ZWw/OiBudW1iZXI7XG4gICAgfSA9IHt9XG4gICk6IERpbWVuc2lvbnMge1xuICAgIHN3aXRjaCAoc2NyaXB0VHlwZSkge1xuICAgICAgY2FzZSAncDJzaCc6XG4gICAgICBjYXNlICdwMnNoUDJ3c2gnOlxuICAgICAgY2FzZSAncDJ3c2gnOlxuICAgICAgY2FzZSAncDJzaFAycGsnOlxuICAgICAgICByZXR1cm4gRGltZW5zaW9ucy5TaW5nbGVJbnB1dFtzY3JpcHRUeXBlXTtcbiAgICAgIGNhc2UgJ3AydHInOlxuICAgICAgY2FzZSAndGFwcm9vdFNjcmlwdFBhdGhTcGVuZCc6XG4gICAgICAgIHN3aXRjaCAocGFyYW1zLnNjcmlwdFBhdGhMZXZlbCkge1xuICAgICAgICAgIGNhc2UgMTpcbiAgICAgICAgICAgIHJldHVybiBEaW1lbnNpb25zLlNpbmdsZUlucHV0LnAydHJTY3JpcHRQYXRoTGV2ZWwxO1xuICAgICAgICAgIGNhc2UgMjpcbiAgICAgICAgICAgIHJldHVybiBEaW1lbnNpb25zLlNpbmdsZUlucHV0LnAydHJTY3JpcHRQYXRoTGV2ZWwyO1xuICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYHVuZXhwZWN0ZWQgc2NyaXB0IHBhdGggbGV2ZWxgKTtcbiAgICAgICAgfVxuICAgICAgY2FzZSAncDJ0ck11c2lnMic6XG4gICAgICAgIHN3aXRjaCAocGFyYW1zLnNjcmlwdFBhdGhMZXZlbCkge1xuICAgICAgICAgIGNhc2UgdW5kZWZpbmVkOlxuICAgICAgICAgICAgcmV0dXJuIERpbWVuc2lvbnMuU2luZ2xlSW5wdXQucDJ0cktleXBhdGg7XG4gICAgICAgICAgY2FzZSAxOlxuICAgICAgICAgICAgcmV0dXJuIERpbWVuc2lvbnMuU2luZ2xlSW5wdXQucDJ0clNjcmlwdFBhdGhMZXZlbDE7XG4gICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgdW5leHBlY3RlZCBzY3JpcHQgcGF0aCBsZXZlbGApO1xuICAgICAgICB9XG4gICAgICBjYXNlICd0YXByb290S2V5UGF0aFNwZW5kJzpcbiAgICAgICAgcmV0dXJuIERpbWVuc2lvbnMuU2luZ2xlSW5wdXQucDJ0cktleXBhdGg7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYHVuZXhwZWN0ZWQgc2NyaXB0VHlwZSAke3NjcmlwdFR5cGV9YCk7XG4gICAgfVxuICB9XG5cbiAgc3RhdGljIEFTU1VNRV9QMlNIOiBEaW1lbnNpb25zO1xuICBzdGF0aWMgQVNTVU1FX1AyU0hfUDJXU0g6IERpbWVuc2lvbnM7XG4gIHN0YXRpYyBBU1NVTUVfUDJXU0g6IERpbWVuc2lvbnM7XG4gIHN0YXRpYyBBU1NVTUVfUDJUUl9LRVlQQVRIOiBEaW1lbnNpb25zO1xuICBzdGF0aWMgQVNTVU1FX1AyVFJfU0NSSVBUUEFUSF9MRVZFTDE6IERpbWVuc2lvbnM7XG4gIHN0YXRpYyBBU1NVTUVfUDJUUl9TQ1JJUFRQQVRIX0xFVkVMMjogRGltZW5zaW9ucztcbiAgc3RhdGljIEFTU1VNRV9QMlNIX1AyUEtfSU5QVVQ6IERpbWVuc2lvbnM7XG5cbiAgcHJpdmF0ZSBzdGF0aWMgZ2V0QXNzdW1lZERpbWVuc2lvbihwYXJhbXM6IEZyb21JbnB1dFBhcmFtcyA9IHt9LCBpbmRleDogbnVtYmVyKSB7XG4gICAgY29uc3QgeyBhc3N1bWVVbnNpZ25lZCB9ID0gcGFyYW1zO1xuICAgIGlmICghYXNzdW1lVW5zaWduZWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgaWxsZWdhbCBpbnB1dCAke2luZGV4fTogZW1wdHkgc2NyaXB0IGFuZCBhc3N1bWVVbnNpZ25lZCBub3Qgc2V0YCk7XG4gICAgfVxuICAgIHJldHVybiBhc3N1bWVVbnNpZ25lZDtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0gaW5wdXQgLSB0aGUgdHJhbnNhY3Rpb24gaW5wdXQgdG8gY291bnRcbiAgICogQHBhcmFtIHBhcmFtc1xuICAgKiAgICAgICAgW3BhcmFtLmFzc3VtZVVuc2lnbmVkXSAtIGRlZmF1bHQgdHlwZSBmb3IgdW5zaWduZWQgaW5wdXRcbiAgICovXG4gIHN0YXRpYyBmcm9tSW5wdXQoaW5wdXQ6IHV0eG9saWIuVHhJbnB1dCwgcGFyYW1zOiBGcm9tSW5wdXRQYXJhbXMgPSB7fSk6IERpbWVuc2lvbnMge1xuICAgIGlmIChpbnB1dC5zY3JpcHQ/Lmxlbmd0aCB8fCBpbnB1dC53aXRuZXNzPy5sZW5ndGgpIHtcbiAgICAgIGNvbnN0IHBhcnNlZCA9IHV0eG9saWIuYml0Z28ucGFyc2VTaWduYXR1cmVTY3JpcHQoaW5wdXQpO1xuICAgICAgcmV0dXJuIERpbWVuc2lvbnMuZnJvbVNjcmlwdFR5cGUocGFyc2VkLnNjcmlwdFR5cGUsIHBhcnNlZCBhcyB7IHNjcmlwdFBhdGhMZXZlbD86IG51bWJlciB9KTtcbiAgICB9XG5cbiAgICByZXR1cm4gRGltZW5zaW9ucy5nZXRBc3N1bWVkRGltZW5zaW9uKHBhcmFtcywgaW5wdXQuaW5kZXgpO1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZSBEaW1lbnNpb25zIGZyb20gcHNidCBpbnB1dFxuICAgKiBAcGFyYW0gaW5wdXQgLSBwc2J0IGlucHV0XG4gICAqL1xuICBzdGF0aWMgZnJvbVBzYnRJbnB1dChpbnB1dDogYml0Z28uUHNidElucHV0VHlwZSk6IERpbWVuc2lvbnMge1xuICAgIGNvbnN0IHBhcnNlZCA9IGJpdGdvLnBhcnNlUHNidElucHV0KGlucHV0KTtcbiAgICByZXR1cm4gRGltZW5zaW9ucy5mcm9tU2NyaXB0VHlwZShwYXJzZWQuc2NyaXB0VHlwZSwgcGFyc2VkIGFzIHsgc2NyaXB0UGF0aExldmVsPzogbnVtYmVyIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSBpbnB1dHMgLSBBcnJheSBvZiBpbnB1dHNcbiAgICogQHBhcmFtIHBhcmFtcyAtIEBzZWUgRGltZW5zaW9ucy5mcm9tSW5wdXQoKVxuICAgKiBAcmV0dXJuIHtEaW1lbnNpb25zfSBzdW0gb2YgdGhlIGRpbWVuc2lvbnMgZm9yIGVhY2ggaW5wdXQgKEBzZWUgRGltZW5zaW9ucy5mcm9tSW5wdXQoKSlcbiAgICovXG4gIHN0YXRpYyBmcm9tSW5wdXRzKGlucHV0czogdXR4b2xpYi5UeElucHV0W10sIHBhcmFtcz86IEZyb21JbnB1dFBhcmFtcyk6IERpbWVuc2lvbnMge1xuICAgIGlmICghQXJyYXkuaXNBcnJheShpbnB1dHMpKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGBpbnB1dHMgbXVzdCBiZSBhcnJheWApO1xuICAgIH1cbiAgICByZXR1cm4gRGltZW5zaW9ucy5zdW0oLi4uaW5wdXRzLm1hcCgoaSkgPT4gRGltZW5zaW9ucy5mcm9tSW5wdXQoaSwgcGFyYW1zKSkpO1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZSBEaW1lbnNpb25zIGZyb20gbXVsdGlwbGUgcHNidCBpbnB1dHNcbiAgICogQHBhcmFtIGlucHV0cyBwc2J0IGlucHV0IGFycmF5XG4gICAqIEByZXR1cm4ge0RpbWVuc2lvbnN9IHN1bSBvZiB0aGUgZGltZW5zaW9ucyBmb3IgZWFjaCBpbnB1dCAoQHNlZSBEaW1lbnNpb25zLmZyb21Qc2J0SW5wdXQoKSlcbiAgICovXG4gIHN0YXRpYyBmcm9tUHNidElucHV0cyhpbnB1dHM6IGJpdGdvLlBzYnRJbnB1dFR5cGVbXSk6IERpbWVuc2lvbnMge1xuICAgIGlmICghQXJyYXkuaXNBcnJheShpbnB1dHMpKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGBpbnB1dHMgbXVzdCBiZSBhcnJheWApO1xuICAgIH1cbiAgICByZXR1cm4gRGltZW5zaW9ucy5zdW0oLi4uaW5wdXRzLm1hcCgoaW5wdXQsIF8pID0+IERpbWVuc2lvbnMuZnJvbVBzYnRJbnB1dChpbnB1dCkpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0gc2NyaXB0TGVuZ3RoIHtudW1iZXJ9IC0gc2l6ZSBvZiB0aGUgb3V0cHV0IHNjcmlwdCBpbiBieXRlc1xuICAgKiBAcmV0dXJuIHtEaW1lbnNpb25zfSAtIERpbWVuc2lvbnMgb2YgdGhlIG91dHB1dFxuICAgKi9cbiAgc3RhdGljIGZyb21PdXRwdXRTY3JpcHRMZW5ndGgoc2NyaXB0TGVuZ3RoOiBudW1iZXIpOiBEaW1lbnNpb25zIHtcbiAgICByZXR1cm4gRGltZW5zaW9ucy5zdW0oe1xuICAgICAgb3V0cHV0czoge1xuICAgICAgICBjb3VudDogMSxcbiAgICAgICAgc2l6ZTogRGltZW5zaW9ucy5nZXRWU2l6ZUZvck91dHB1dFdpdGhTY3JpcHRMZW5ndGgoc2NyaXB0TGVuZ3RoKSxcbiAgICAgIH0sXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIG91dHB1dCAtIGEgdHggb3V0cHV0XG4gICAqIEByZXR1cm4gRGltZW5zaW9ucyAtIHRoZSBkaW1lbnNpb25zIG9mIHRoZSBnaXZlbiBvdXRwdXRcbiAgICovXG4gIHN0YXRpYyBmcm9tT3V0cHV0KHsgc2NyaXB0IH06IHsgc2NyaXB0OiBCdWZmZXIgfSk6IERpbWVuc2lvbnMge1xuICAgIGlmICghc2NyaXB0KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2V4cGVjdGVkIG91dHB1dCBzY3JpcHQgdG8gYmUgZGVmaW5lZCcpO1xuICAgIH1cbiAgICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcihzY3JpcHQpKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdleHBlY3RlZCBzY3JpcHQgdG8gYmUgYnVmZmVyLCBnb3QgJyArIHR5cGVvZiBzY3JpcHQpO1xuICAgIH1cbiAgICByZXR1cm4gRGltZW5zaW9ucy5mcm9tT3V0cHV0U2NyaXB0TGVuZ3RoKHNjcmlwdC5sZW5ndGgpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSBvdXRwdXRzIC0gQXJyYXkgb2Ygb3V0cHV0c1xuICAgKiBAcmV0dXJuIHtEaW1lbnNpb25zfSBzdW0gb2YgdGhlIGRpbWVuc2lvbnMgZm9yIGVhY2ggb3V0cHV0IChAc2VlIERpbWVuc2lvbnMuZnJvbU91dHB1dCgpKVxuICAgKi9cbiAgc3RhdGljIGZyb21PdXRwdXRzKG91dHB1dHM6IHsgc2NyaXB0OiBCdWZmZXIgfVtdKTogRGltZW5zaW9ucyB7XG4gICAgaWYgKCFBcnJheS5pc0FycmF5KG91dHB1dHMpKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGBvdXRwdXRzIG11c3QgYmUgYXJyYXlgKTtcbiAgICB9XG4gICAgcmV0dXJuIERpbWVuc2lvbnMuc3VtKC4uLm91dHB1dHMubWFwKERpbWVuc2lvbnMuZnJvbU91dHB1dCkpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIGRpbWVuc2lvbnMgb2YgYW4gb3V0cHV0IHRoYXQgd2lsbCBiZSBjcmVhdGVkIG9uIGEgc3BlY2lmaWMgY2hhaW4uXG4gICAqIEN1cnJlbnRseSwgdGhpcyBzaW1wbHkgYWRkcyBhIGRlZmF1bHQgb3V0cHV0LlxuICAgKlxuICAgKiBAcGFyYW0gY2hhaW4gLSBDaGFpbiBjb2RlIGFzIGRlZmluZWQgYnkgdXR4b2xpYi5iaXRnb1xuICAgKiBAcmV0dXJuIHtEaW1lbnNpb25zfSAtIERpbWVuc2lvbnMgZm9yIGEgc2luZ2xlIG91dHB1dCBvbiB0aGUgZ2l2ZW4gY2hhaW4uXG4gICAqL1xuICBzdGF0aWMgZnJvbU91dHB1dE9uQ2hhaW4oY2hhaW46IENoYWluQ29kZSk6IERpbWVuc2lvbnMge1xuICAgIHJldHVybiBEaW1lbnNpb25zLmZyb21PdXRwdXRTY3JpcHRMZW5ndGgoRGltZW5zaW9ucy5nZXRPdXRwdXRTY3JpcHRMZW5ndGhGb3JDaGFpbihjaGFpbikpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybiBkaW1lbnNpb25zIG9mIGFuIHVuc3BlbnQgYWNjb3JkaW5nIHRvIGBjaGFpbmAgcGFyYW1ldGVyXG4gICAqIEBwYXJhbSBjaGFpbiAtIENoYWluIGNvZGUgYXMgZGVmaW5lZCBieSB1dHhvLmNoYWluXG4gICAqIEBwYXJhbSBwYXJhbXMgLSBIaW50IGZvciB1bnNwZW50cyB3aXRoIHZhcmlhYmxlIGlucHV0IHNpemVzIChwMnRyLCBwMnRyTXVzaWcyKVxuICAgKiBAcmV0dXJuIHtEaW1lbnNpb25zfSBvZiB0aGUgdW5zcGVudFxuICAgKiBAdGhyb3dzIGlmIHRoZSBjaGFpbiBjb2RlIGlzIGludmFsaWQgb3IgdW5zdXBwb3J0ZWRcbiAgICovXG4gIHN0YXRpYyBmcm9tVW5zcGVudCh7IGNoYWluIH06IHsgY2hhaW46IG51bWJlciB9LCBwYXJhbXM6IEZyb21VbnNwZW50UGFyYW1zID0gZGVmYXVsdFVuc3BlbnRQYXJhbXMpOiBEaW1lbnNpb25zIHtcbiAgICBpZiAoIWlzQ2hhaW5Db2RlKGNoYWluKSkge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignaW52YWxpZCBjaGFpbiBjb2RlJyk7XG4gICAgfVxuXG4gICAgY29uc3Qgc2NyaXB0VHlwZSA9IHNjcmlwdFR5cGVGb3JDaGFpbihjaGFpbik7XG5cbiAgICByZXR1cm4gRGltZW5zaW9ucy5mcm9tU2NyaXB0VHlwZShcbiAgICAgIHNjcmlwdFR5cGUsXG4gICAgICBzY3JpcHRUeXBlID09PSAncDJ0cicgPyBwYXJhbXMucDJ0ciA6IHNjcmlwdFR5cGUgPT09ICdwMnRyTXVzaWcyJyA/IHBhcmFtcy5wMnRyTXVzaWcyIDoge31cbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB1bnNwZW50c1xuICAgKiBAcGFyYW0gcGFyYW1zIC0gSGludCBmb3IgdW5zcGVudHMgd2l0aCB2YXJpYWJsZSBpbnB1dCBzaXplcyAocDJ0ciwgcDJ0ck11c2lnMilcbiAgICogQHJldHVybiB7RGltZW5zaW9uc30gc3VtIG9mIHRoZSBkaW1lbnNpb25zIGZvciBlYWNoIHVuc3BlbnQgKEBzZWUgRGltZW5zaW9ucy5mcm9tVW5zcGVudCgpKVxuICAgKi9cbiAgc3RhdGljIGZyb21VbnNwZW50cyh1bnNwZW50czogeyBjaGFpbjogQ2hhaW5Db2RlIH1bXSwgcGFyYW1zOiBGcm9tVW5zcGVudFBhcmFtcyA9IGRlZmF1bHRVbnNwZW50UGFyYW1zKTogRGltZW5zaW9ucyB7XG4gICAgaWYgKCFBcnJheS5pc0FycmF5KHVuc3BlbnRzKSkge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgdW5zcGVudHMgbXVzdCBiZSBhcnJheWApO1xuICAgIH1cbiAgICAvLyBDb252ZXJ0IHRoZSBpbmRpdmlkdWFsIHVuc3BlbnRzIGludG8gZGltZW5zaW9ucyBhbmQgc3VtIHRoZW0gdXBcbiAgICByZXR1cm4gRGltZW5zaW9ucy5zdW0oLi4udW5zcGVudHMubWFwKCh1KSA9PiBEaW1lbnNpb25zLmZyb21VbnNwZW50KHUsIHBhcmFtcykpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0gdHJhbnNhY3Rpb24gLSBiaXRjb2luLWxpa2UgdHJhbnNhY3Rpb25cbiAgICogQHBhcmFtIFtwYXJhbS5hc3N1bWVVbnNpZ25lZF0gLSBkZWZhdWx0IHR5cGUgZm9yIHVuc2lnbmVkIGlucHV0c1xuICAgKiBAcmV0dXJuIHtEaW1lbnNpb25zfVxuICAgKi9cbiAgc3RhdGljIGZyb21UcmFuc2FjdGlvbihcbiAgICB7XG4gICAgICBpbnMsXG4gICAgICBvdXRzLFxuICAgIH06IHtcbiAgICAgIGluczogdXR4b2xpYi5UeElucHV0W107XG4gICAgICBvdXRzOiB1dHhvbGliLlR4T3V0cHV0W107XG4gICAgfSxcbiAgICBwYXJhbXM/OiBGcm9tSW5wdXRQYXJhbXNcbiAgKTogRGltZW5zaW9ucyB7XG4gICAgcmV0dXJuIERpbWVuc2lvbnMuZnJvbUlucHV0cyhpbnMsIHBhcmFtcykucGx1cyhEaW1lbnNpb25zLmZyb21PdXRwdXRzKG91dHMpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGUgRGltZW5zaW9ucyBmcm9tIHBzYnQgaW5wdXRzIGFuZCBvdXRwdXRzXG4gICAqIEBwYXJhbSBwc2J0XG4gICAqIEByZXR1cm4ge0RpbWVuc2lvbnN9XG4gICAqL1xuICBzdGF0aWMgZnJvbVBzYnQocHNidDogYml0Z28uVXR4b1BzYnQpOiBEaW1lbnNpb25zIHtcbiAgICByZXR1cm4gRGltZW5zaW9ucy5mcm9tUHNidElucHV0cyhwc2J0LmRhdGEuaW5wdXRzKS5wbHVzKERpbWVuc2lvbnMuZnJvbU91dHB1dHMocHNidC5nZXRVbnNpZ25lZFR4KCkub3V0cykpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSBkaW1lbnNpb25zIChjYW4gYmUgcGFydGlhbGx5IGRlZmluZWQpXG4gICAqIEByZXR1cm4gbmV3IGRpbWVuc2lvbnMgd2l0aCBhcmd1bWVudCBhZGRlZFxuICAgKi9cbiAgcGx1cyhkaW1lbnNpb25zOiBQYXJ0aWFsPERpbWVuc2lvbnM+KTogRGltZW5zaW9ucyB7XG4gICAgaWYgKHR5cGVvZiBkaW1lbnNpb25zICE9PSAnb2JqZWN0Jykge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgZXhwZWN0ZWQgYXJndW1lbnQgdG8gYmUgb2JqZWN0YCk7XG4gICAgfVxuXG4gICAgaWYgKCEoZGltZW5zaW9ucyBpbnN0YW5jZW9mIERpbWVuc2lvbnMpKSB7XG4gICAgICBkaW1lbnNpb25zID0gbmV3IERpbWVuc2lvbnMoZGltZW5zaW9ucyk7XG4gICAgfVxuXG4gICAgLy8gQ2F0Y2ggaW5zdGFuY2VzIHdoZXJlIHdlIHRyeSB0byBpbml0aWFsaXplIERpbWVuc2lvbnMgZnJvbSBwYXJ0aWFsIGRhdGEgdXNpbmcgZGVwcmVjYXRlZCBwYXJhbWV0ZXJzXG4gICAgLy8gdXNpbmcgb25seSBcIm5PdXRwdXRzXCIuXG4gICAgaWYgKCduT3V0cHV0cycgaW4gZGltZW5zaW9ucykge1xuICAgICAgaWYgKCEoJ291dHB1dHMnIGluIGRpbWVuc2lvbnMpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignZGVwcmVjYXRlZCBwYXJ0aWFsIGFkZGl0aW9uOiBhcmd1bWVudCBoYXMga2V5IFwibk91dHB1dHNcIiBidXQgbm8gXCJvdXRwdXRzXCInKTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgeyBvdXRwdXRzLCBuT3V0cHV0cyB9ID0gZGltZW5zaW9ucyBhcyBEaW1lbnNpb25zO1xuXG4gICAgICBpZiAob3V0cHV0cy5jb3VudCAhPT0gbk91dHB1dHMpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdkZXByZWNhdGVkIHBhcnRpYWwgYWRkaXRpb246IGluY29uc2lzdGVudCB2YWx1ZXMgZm9yIFwibk91dHB1dHNcIiBhbmQgXCJvdXRwdXRzLmNvdW50XCInKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gbWFwRGltZW5zaW9ucyh0aGlzLCAoa2V5LCB2KSA9PiB7XG4gICAgICBjb25zdCB3ID0gZGltZW5zaW9uc1trZXldID8/IERpbWVuc2lvbnMuWkVST1trZXldO1xuICAgICAgaWYgKGtleSA9PT0gJ291dHB1dHMnKSB7XG4gICAgICAgIGNvbnN0IHZPdXRwdXRzID0gdiBhcyBPdXRwdXREaW1lbnNpb25zO1xuICAgICAgICBjb25zdCB3T3V0cHV0cyA9IHcgYXMgT3V0cHV0RGltZW5zaW9ucztcbiAgICAgICAgcmV0dXJuIG5ldyBPdXRwdXREaW1lbnNpb25zKHtcbiAgICAgICAgICBjb3VudDogdk91dHB1dHMuY291bnQgKyB3T3V0cHV0cy5jb3VudCxcbiAgICAgICAgICBzaXplOiB2T3V0cHV0cy5zaXplICsgd091dHB1dHMuc2l6ZSxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gKHYgYXMgbnVtYmVyKSArICh3IGFzIG51bWJlcik7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogTXVsdGlwbHkgZGltZW5zaW9ucyBieSBhIGdpdmVuIGZhY3RvclxuICAgKiBAcGFyYW0gZmFjdG9yIC0gUG9zaXRpdmUgaW50ZWdlclxuICAgKiBAcmV0dXJuIHtEaW1lbnNpb25zfVxuICAgKi9cbiAgdGltZXMoZmFjdG9yOiBudW1iZXIpOiBEaW1lbnNpb25zIHtcbiAgICBpZiAoIVBvc2l0aXZlSW50ZWdlci5pcyhmYWN0b3IpKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGBleHBlY3RlZCBmYWN0b3IgdG8gYmUgcG9zaXRpdmUgaW50ZWdlcmApO1xuICAgIH1cblxuICAgIHJldHVybiBtYXBEaW1lbnNpb25zKHRoaXMsIChrZXksIHZhbHVlKSA9PiB7XG4gICAgICBpZiAoa2V5ID09PSAnb3V0cHV0cycpIHtcbiAgICAgICAgY29uc3Qgdk91dHB1dHMgPSB2YWx1ZSBhcyBPdXRwdXREaW1lbnNpb25zO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIGNvdW50OiB2T3V0cHV0cy5jb3VudCAqIGZhY3RvcixcbiAgICAgICAgICBzaXplOiB2T3V0cHV0cy5zaXplICogZmFjdG9yLFxuICAgICAgICB9O1xuICAgICAgfVxuICAgICAgcmV0dXJuICh2YWx1ZSBhcyBudW1iZXIpICogZmFjdG9yO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm4gTnVtYmVyIG9mIHRvdGFsIGlucHV0cyAocDJzaCwgcDJzaFAyd3NoIGFuZCBwMndzaClcbiAgICogQGRlcHJlY2F0ZWQgdXNlIGBkaW1lbnNpb24ubklucHV0c2AgaW5zdGVhZFxuICAgKi9cbiAgZ2V0TklucHV0cygpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLm5JbnB1dHM7XG4gIH1cblxuICAvKipcbiAgICogQHJldHVybnMge2Jvb2xlYW59IHRydWUgaWZmIGRpbWVuc2lvbnMgaGF2ZSBvbmUgb3IgbW9yZSAocDJzaClwMndzaCBpbnB1dHNcbiAgICovXG4gIGlzU2Vnd2l0KCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAoXG4gICAgICB0aGlzLm5QMndzaElucHV0cyArXG4gICAgICAgIHRoaXMublAyc2hQMndzaElucHV0cyArXG4gICAgICAgIHRoaXMublAydHJLZXlwYXRoSW5wdXRzICtcbiAgICAgICAgdGhpcy5uUDJ0clNjcmlwdFBhdGhMZXZlbDFJbnB1dHMgK1xuICAgICAgICB0aGlzLm5QMnRyU2NyaXB0UGF0aExldmVsMklucHV0cyA+XG4gICAgICAwXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJuIHtOdW1iZXJ9IG92ZXJoZWFkIHZzaXplLCBiYXNlZCBvbiByZXN1bHQgaXNTZWd3aXQoKS5cbiAgICovXG4gIGdldE92ZXJoZWFkVlNpemUoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5pc1NlZ3dpdCgpID8gVmlydHVhbFNpemVzLnR4U2VnT3ZlcmhlYWRWU2l6ZSA6IFZpcnR1YWxTaXplcy50eE92ZXJoZWFkU2l6ZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJucyB7bnVtYmVyfSB2c2l6ZSBvZiBpbnB1dHMsIHdpdGhvdXQgdHJhbnNhY3Rpb24gb3ZlcmhlYWRcbiAgICovXG4gIGdldElucHV0c1ZTaXplKCk6IG51bWJlciB7XG4gICAgY29uc3Qge1xuICAgICAgdHhQMnNoSW5wdXRTaXplLFxuICAgICAgdHhQMnNoUDJ3c2hJbnB1dFNpemUsXG4gICAgICB0eFAyd3NoSW5wdXRTaXplLFxuICAgICAgdHhQMnRyS2V5cGF0aElucHV0U2l6ZSxcbiAgICAgIHR4UDJ0clNjcmlwdFBhdGhMZXZlbDFJbnB1dFNpemUsXG4gICAgICB0eFAydHJTY3JpcHRQYXRoTGV2ZWwySW5wdXRTaXplLFxuICAgICAgdHhQMnNoUDJwa0lucHV0U2l6ZSxcbiAgICB9ID0gVmlydHVhbFNpemVzO1xuXG4gICAgY29uc3Qge1xuICAgICAgblAyc2hJbnB1dHMsXG4gICAgICBuUDJzaFAyd3NoSW5wdXRzLFxuICAgICAgblAyd3NoSW5wdXRzLFxuICAgICAgblAydHJLZXlwYXRoSW5wdXRzLFxuICAgICAgblAydHJTY3JpcHRQYXRoTGV2ZWwxSW5wdXRzLFxuICAgICAgblAydHJTY3JpcHRQYXRoTGV2ZWwySW5wdXRzLFxuICAgICAgblAyc2hQMnBrSW5wdXRzLFxuICAgIH0gPSB0aGlzO1xuXG4gICAgY29uc3Qgc2l6ZSA9XG4gICAgICBuUDJzaElucHV0cyAqIHR4UDJzaElucHV0U2l6ZSArXG4gICAgICBuUDJzaFAyd3NoSW5wdXRzICogdHhQMnNoUDJ3c2hJbnB1dFNpemUgK1xuICAgICAgblAyd3NoSW5wdXRzICogdHhQMndzaElucHV0U2l6ZSArXG4gICAgICBuUDJ0cktleXBhdGhJbnB1dHMgKiB0eFAydHJLZXlwYXRoSW5wdXRTaXplICtcbiAgICAgIG5QMnNoUDJwa0lucHV0cyAqIHR4UDJzaFAycGtJbnB1dFNpemUgK1xuICAgICAgblAydHJTY3JpcHRQYXRoTGV2ZWwxSW5wdXRzICogdHhQMnRyU2NyaXB0UGF0aExldmVsMUlucHV0U2l6ZSArXG4gICAgICBuUDJ0clNjcmlwdFBhdGhMZXZlbDJJbnB1dHMgKiB0eFAydHJTY3JpcHRQYXRoTGV2ZWwySW5wdXRTaXplO1xuICAgIGlmIChOdW1iZXIuaXNOYU4oc2l6ZSkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgaW52YWxpZCBzaXplYCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHNpemU7XG4gIH1cblxuICAvKipcbiAgICogQHJldHVybnMge251bWJlcn0gcmV0dXJuIHZzaXplIG9mIG91dHB1dHMsIHdpdGhvdXQgb3ZlcmhlYWRcbiAgICovXG4gIGdldE91dHB1dHNWU2l6ZSgpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLm91dHB1dHMuc2l6ZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFc3RpbWF0ZXMgdGhlIHZpcnR1YWwgc2l6ZSAoMS80IHdlaWdodCkgb2YgYSBzaWduZWQgdHJhbnNhY3Rpb24gYXMgc3VtIG9mXG4gICAqIG92ZXJoZWFkIHZzaXplLCBpbnB1dCB2c2l6ZSBhbmQgb3V0cHV0IHZzaXplLlxuICAgKiBAcmV0dXJucyB7TnVtYmVyfSBUaGUgZXN0aW1hdGVkIHZzaXplIG9mIHRoZSB0cmFuc2FjdGlvbiBkaW1lbnNpb25zLlxuICAgKi9cbiAgZ2V0VlNpemUoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5nZXRPdmVyaGVhZFZTaXplKCkgKyB0aGlzLmdldElucHV0c1ZTaXplKCkgKyB0aGlzLmdldE91dHB1dHNWU2l6ZSgpO1xuICB9XG59XG5cbi8vIEluaXRpYWxpemUgc3RhdGljIHByb3BlcnRpZXMgdGhhdCByZXF1aXJlIHRoZSBjbGFzcyB0byBiZSBmdWxseSBkZWZpbmVkIGZpcnN0XG5EaW1lbnNpb25zLlNpbmdsZU91dHB1dCA9IE9iamVjdC5mcmVlemUoe1xuICBwMnNoOiBEaW1lbnNpb25zLnNpbmdsZU91dHB1dChWaXJ0dWFsU2l6ZXMudHhQMnNoT3V0cHV0U2l6ZSksXG4gIHAyc2hQMndzaDogRGltZW5zaW9ucy5zaW5nbGVPdXRwdXQoVmlydHVhbFNpemVzLnR4UDJzaFAyd3NoT3V0cHV0U2l6ZSksXG4gIHAyd3NoOiBEaW1lbnNpb25zLnNpbmdsZU91dHB1dChWaXJ0dWFsU2l6ZXMudHhQMndzaE91dHB1dFNpemUpLFxuICBwMnRyOiBEaW1lbnNpb25zLnNpbmdsZU91dHB1dChWaXJ0dWFsU2l6ZXMudHhQMnRyT3V0cHV0U2l6ZSksXG4gIHAycGtoOiBEaW1lbnNpb25zLnNpbmdsZU91dHB1dChWaXJ0dWFsU2l6ZXMudHhQMnBraE91dHB1dFNpemUpLFxuICBwMndwa2g6IERpbWVuc2lvbnMuc2luZ2xlT3V0cHV0KFZpcnR1YWxTaXplcy50eFAyd3BraE91dHB1dFNpemUpLFxufSk7XG5cbi8vIEluaXRpYWxpemUgU2luZ2xlSW5wdXQgYWZ0ZXIgdGhlIGNsYXNzIGlzIGZ1bGx5IGRlZmluZWRcbkRpbWVuc2lvbnMuU2luZ2xlSW5wdXQgPSBPYmplY3QuZnJlZXplKHtcbiAgcDJzaDogRGltZW5zaW9ucy5zdW0oeyBuUDJzaElucHV0czogMSB9KSxcbiAgcDJzaFAyd3NoOiBEaW1lbnNpb25zLnN1bSh7IG5QMnNoUDJ3c2hJbnB1dHM6IDEgfSksXG4gIHAyd3NoOiBEaW1lbnNpb25zLnN1bSh7IG5QMndzaElucHV0czogMSB9KSxcbiAgcDJ0cktleXBhdGg6IERpbWVuc2lvbnMuc3VtKHsgblAydHJLZXlwYXRoSW5wdXRzOiAxIH0pLFxuICBwMnRyU2NyaXB0UGF0aExldmVsMTogRGltZW5zaW9ucy5zdW0oeyBuUDJ0clNjcmlwdFBhdGhMZXZlbDFJbnB1dHM6IDEgfSksXG4gIHAydHJTY3JpcHRQYXRoTGV2ZWwyOiBEaW1lbnNpb25zLnN1bSh7IG5QMnRyU2NyaXB0UGF0aExldmVsMklucHV0czogMSB9KSxcbiAgcDJzaFAycGs6IERpbWVuc2lvbnMuc3VtKHsgblAyc2hQMnBrSW5wdXRzOiAxIH0pLFxufSk7XG5cbi8vIEluaXRpYWxpemUgdGhlIEFTU1VNRV8gY29uc3RhbnRzXG5EaW1lbnNpb25zLkFTU1VNRV9QMlNIID0gRGltZW5zaW9ucy5TaW5nbGVJbnB1dC5wMnNoO1xuRGltZW5zaW9ucy5BU1NVTUVfUDJTSF9QMldTSCA9IERpbWVuc2lvbnMuU2luZ2xlSW5wdXQucDJzaFAyd3NoO1xuRGltZW5zaW9ucy5BU1NVTUVfUDJXU0ggPSBEaW1lbnNpb25zLlNpbmdsZUlucHV0LnAyd3NoO1xuRGltZW5zaW9ucy5BU1NVTUVfUDJUUl9LRVlQQVRIID0gRGltZW5zaW9ucy5TaW5nbGVJbnB1dC5wMnRyS2V5cGF0aDtcbkRpbWVuc2lvbnMuQVNTVU1FX1AyVFJfU0NSSVBUUEFUSF9MRVZFTDEgPSBEaW1lbnNpb25zLlNpbmdsZUlucHV0LnAydHJTY3JpcHRQYXRoTGV2ZWwxO1xuRGltZW5zaW9ucy5BU1NVTUVfUDJUUl9TQ1JJUFRQQVRIX0xFVkVMMiA9IERpbWVuc2lvbnMuU2luZ2xlSW5wdXQucDJ0clNjcmlwdFBhdGhMZXZlbDI7XG5EaW1lbnNpb25zLkFTU1VNRV9QMlNIX1AyUEtfSU5QVVQgPSBEaW1lbnNpb25zLlNpbmdsZUlucHV0LnAyc2hQMnBrO1xuIl19Выполнить команду
Для локальной разработки. Не используйте в интернете!