package.dist.src.internal.cache-data-client.js Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of sdk Show documentation
Show all versions of sdk Show documentation
Client SDK for Momento services
The newest version!
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.CacheDataClient = exports.CONNECTION_ID_KEY = void 0;
const generated_types_1 = require("@gomomento/generated-types");
// older versions of node don't have the global util variables https://github.com/nodejs/node/issues/20365
const util_1 = require("util");
const headers_interceptor_1 = require("./grpc/headers-interceptor");
const retry_interceptor_1 = require("./grpc/retry-interceptor");
const cache_service_error_mapper_1 = require("../errors/cache-service-error-mapper");
const grpc_js_1 = require("@grpc/grpc-js");
const __1 = require("..");
const package_json_1 = require("../../package.json");
const idle_grpc_client_wrapper_1 = require("./grpc/idle-grpc-client-wrapper");
const middlewares_interceptor_1 = require("./grpc/middlewares-interceptor");
const cacheclient_1 = require("@gomomento/generated-types/dist/cacheclient");
const utils_1 = require("@gomomento/sdk-core/dist/src/internal/utils");
const grpc_response_types_1 = require("@gomomento/sdk-core/dist/src/messages/responses/grpc-response-types");
const connectivity_state_1 = require("@grpc/grpc-js/build/src/connectivity-state");
const grpc_channel_options_1 = require("./grpc/grpc-channel-options");
const errors_1 = require("@gomomento/sdk-core/dist/src/errors");
const common_1 = require("@gomomento/generated-types/dist/common");
const utils_2 = require("@gomomento/sdk-core/dist/src/utils");
const compression_error_1 = require("../errors/compression-error");
const sdk_core_1 = require("@gomomento/sdk-core");
var grpcCache = generated_types_1.cache.cache_client;
var ECacheResult = cacheclient_1.cache_client.ECacheResult;
var _ItemGetTypeResponse = cacheclient_1.cache_client._ItemGetTypeResponse;
var _Unbounded = common_1.common._Unbounded;
var Absent = common_1.common.Absent;
var Present = common_1.common.Present;
var Equal = common_1.common.Equal;
var NotEqual = common_1.common.NotEqual;
var PresentAndNotEqual = common_1.common.PresentAndNotEqual;
var AbsentOrEqual = common_1.common.AbsentOrEqual;
exports.CONNECTION_ID_KEY = Symbol('connectionID');
class CacheDataClient {
/**
* @param {CacheClientProps} props
* @param dataClientID
* @param semaphore
*/
constructor(props, dataClientID, semaphore) {
var _a, _b;
this.configuration = props.configuration;
this.credentialProvider = props.credentialProvider;
this.logger = this.configuration.getLoggerFactory().getLogger(this);
this.cacheServiceErrorMapper = new cache_service_error_mapper_1.CacheServiceErrorMapper(props.configuration.getThrowOnErrors());
const compression = this.configuration.getCompressionStrategy();
if (compression !== undefined) {
this.compressionDetails = {
valueCompressor: compression.compressorFactory,
compressionLevel: (_a = compression.compressionLevel) !== null && _a !== void 0 ? _a : __1.CompressionLevel.Balanced,
autoDecompressEnabled: ((_b = compression.automaticDecompression) !== null && _b !== void 0 ? _b : __1.AutomaticDecompression.Enabled) === __1.AutomaticDecompression.Enabled,
};
}
else {
this.compressionDetails = undefined;
}
this.requestConcurrencySemaphore = semaphore;
const grpcConfig = this.configuration
.getTransportStrategy()
.getGrpcConfig();
this.requestTimeoutMs =
grpcConfig.getDeadlineMillis() ||
CacheDataClient.DEFAULT_REQUEST_TIMEOUT_MS;
this.validateRequestTimeout(this.requestTimeoutMs);
this.logger.debug(`Creating cache client using endpoint: '${this.credentialProvider.getCacheEndpoint()}'`);
const channelOptions = (0, grpc_channel_options_1.grpcChannelOptionsFromGrpcConfig)(grpcConfig);
this.clientWrapper = new idle_grpc_client_wrapper_1.IdleGrpcClientWrapper({
clientFactoryFn: () => {
this.logger.debug(`Constructing channel for clientID ${dataClientID}`);
return new grpcCache.ScsClient(this.credentialProvider.getCacheEndpoint(), this.credentialProvider.isCacheEndpointSecure()
? grpc_js_1.ChannelCredentials.createSsl()
: grpc_js_1.ChannelCredentials.createInsecure(), channelOptions);
},
loggerFactory: this.configuration.getLoggerFactory(),
maxIdleMillis: this.configuration
.getTransportStrategy()
.getMaxIdleMillis(),
maxClientAgeMillis: this.configuration
.getTransportStrategy()
.getMaxClientAgeMillis(),
});
this.textEncoder = new util_1.TextEncoder();
this.defaultTtlSeconds = props.defaultTtlSeconds;
// this context object is currently internal only but can be extended in the Configuration object is we wants clients
// to be able to set it.
const context = {};
context[exports.CONNECTION_ID_KEY] = dataClientID;
const headers = [
new headers_interceptor_1.Header('Authorization', this.credentialProvider.getAuthToken()),
new headers_interceptor_1.Header('agent', `nodejs:cache:${package_json_1.version}`),
new headers_interceptor_1.Header('runtime-version', `nodejs:${process.versions.node}`),
];
// Not sending a head concern header is treated the same as sending a BALANCED read concern header
const readConcern = this.configuration.getReadConcern();
if (readConcern !== __1.ReadConcern.BALANCED) {
headers.push(new headers_interceptor_1.Header('read-concern', readConcern));
}
this.interceptors = this.initializeInterceptors(headers, this.configuration.getLoggerFactory(), this.configuration.getMiddlewares(), context);
this.streamingInterceptors = this.initializeStreamingInterceptors(headers);
}
close() {
this.logger.debug('Closing cache data client');
this.clientWrapper.getClient().close();
}
connect(timeoutSeconds = 10) {
this.logger.debug('Attempting to eagerly connect to channel');
const deadline = new Date();
deadline.setSeconds(deadline.getSeconds() + timeoutSeconds);
return this.connectWithinDeadline(deadline);
}
connectionStateToString(state) {
switch (state) {
case connectivity_state_1.ConnectivityState.IDLE:
return 'IDLE';
case connectivity_state_1.ConnectivityState.CONNECTING:
return 'CONNECTING';
case connectivity_state_1.ConnectivityState.READY:
return 'READY';
case connectivity_state_1.ConnectivityState.TRANSIENT_FAILURE:
return 'TRANSIENT_FAILURE';
case connectivity_state_1.ConnectivityState.SHUTDOWN:
return 'SHUTDOWN';
}
}
connectWithinDeadline(deadline) {
return new Promise((resolve, reject) => {
// Get the current state and initiate a connection
const currentState = this.clientWrapper
.getClient()
.getChannel()
.getConnectivityState(true);
this.logger.debug(`Client connectivity state: ${currentState}`);
if (currentState === connectivity_state_1.ConnectivityState.READY) {
resolve();
return;
}
const now = new Date();
if (now >= deadline) {
const errorMessage = 'Unable to connect to Momento: deadline exceeded.';
this.logger.error(errorMessage);
reject(new errors_1.ConnectionError(errorMessage));
return;
}
this.clientWrapper
.getClient()
.getChannel()
.watchConnectivityState(currentState, deadline, (error) => {
if (error) {
const errorMessage = `Unable to eagerly connect to Momento. Please contact Momento if this persists. currentState: ${this.connectionStateToString(currentState)}, errorName: ${error.name} : errorMessage: ${error.message}, errorStack: ${error.stack ? error.stack : 'Stack trace undefined'}`;
this.logger.error(errorMessage);
reject(new errors_1.ConnectionError(errorMessage));
return;
}
const newState = this.clientWrapper
.getClient()
.getChannel()
.getConnectivityState(false);
if (newState === connectivity_state_1.ConnectivityState.READY) {
this.logger.debug(`Connected! Current state: ${this.connectionStateToString(newState)}`);
resolve();
}
else if (newState === connectivity_state_1.ConnectivityState.CONNECTING) {
// The connection goes through the CONNECTING state before becoming READY,
// so we must watch it twice.
this.logger.debug(`Connecting! Current state: ${this.connectionStateToString(newState)}`);
this.connectWithinDeadline(deadline).then(resolve).catch(reject);
}
else {
const errorMessage = `Unable to connect to Momento: Unexpected connection state: ${this.connectionStateToString(newState)}., oldState: ${this.connectionStateToString(currentState)}
Please contact Momento if this persists.`;
this.logger.error(errorMessage);
reject(new errors_1.ConnectionError(errorMessage));
return;
}
});
});
}
getEndpoint() {
const endpoint = this.credentialProvider.getCacheEndpoint();
this.logger.debug(`Using cache endpoint: ${endpoint}`);
return endpoint;
}
validateRequestTimeout(timeout) {
this.logger.debug(`Request timeout ms: ${String(timeout)}`);
if (timeout !== undefined && timeout <= 0) {
throw new __1.InvalidArgumentError('request timeout must be greater than zero.');
}
}
convertECacheResult(result) {
switch (result) {
case grpcCache.ECacheResult.Hit:
return grpc_response_types_1._ECacheResult.Hit;
case grpcCache.ECacheResult.Invalid:
return grpc_response_types_1._ECacheResult.Invalid;
case grpcCache.ECacheResult.Miss:
return grpc_response_types_1._ECacheResult.Miss;
case grpcCache.ECacheResult.Ok:
return grpc_response_types_1._ECacheResult.Ok;
}
}
convertItemTypeResult(result) {
switch (result) {
case _ItemGetTypeResponse.ItemType.SCALAR:
return __1.ItemType.SCALAR;
case _ItemGetTypeResponse.ItemType.LIST:
return __1.ItemType.LIST;
case _ItemGetTypeResponse.ItemType.DICTIONARY:
return __1.ItemType.DICTIONARY;
case _ItemGetTypeResponse.ItemType.SET:
return __1.ItemType.SET;
case _ItemGetTypeResponse.ItemType.SORTED_SET:
return __1.ItemType.SORTED_SET;
}
}
// If maxConcurrentRequests is set, use the semaphore to limit the number of concurrent requests.
// Otherwise, execute the cache operation without any rate limiting.
async rateLimited(cacheOperation) {
try {
if (this.requestConcurrencySemaphore !== undefined)
await this.requestConcurrencySemaphore.acquire();
return await cacheOperation();
}
finally {
if (this.requestConcurrencySemaphore !== undefined)
this.requestConcurrencySemaphore.release();
}
}
/**
* Returns the TTL in milliseconds for a collection.
* If the provided TTL is not set, it defaults to the instance's default TTL.
* @param ttl - The CollectionTttl object containing the TTL value.
* @returns The TTL in milliseconds.
*/
collectionTtlOrDefaultMilliseconds(ttl) {
var _a;
return ((_a = ttl.ttlMilliseconds()) !== null && _a !== void 0 ? _a : (0, utils_2.secondsToMilliseconds)(this.defaultTtlSeconds));
}
/**
* Returns the TTL in milliseconds.
* If the provided TTL is not set, it defaults to the instance's default TTL.
* @param ttl
* @returns The TTL in milliseconds.
*/
ttlOrDefaultMilliseconds(ttl) {
const ttlSeconds = ttl !== null && ttl !== void 0 ? ttl : this.defaultTtlSeconds;
return (0, utils_2.secondsToMilliseconds)(ttlSeconds);
}
async set(cacheName, key, value, options) {
try {
(0, utils_1.validateCacheName)(cacheName);
if ((options === null || options === void 0 ? void 0 : options.ttl) !== undefined) {
(0, utils_1.validateTtlSeconds)(options.ttl);
}
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheSet.Error(err));
}
const ttlToUse = (options === null || options === void 0 ? void 0 : options.ttl) || this.defaultTtlSeconds;
const encodedKey = this.convert(key);
let encodedValue = this.convert(value);
if (options === null || options === void 0 ? void 0 : options.compress) {
this.logger.trace('CacheClient.set; compression enabled, calling value compressor');
if (this.compressionDetails === undefined) {
return this.cacheServiceErrorMapper.returnOrThrowError(new compression_error_1.CompressionError('CacheClient.set', 'compress'), err => new __1.CacheSet.Error(err));
}
encodedValue = await this.compressionDetails.valueCompressor.compress(this.compressionDetails.compressionLevel, encodedValue);
}
return await this.rateLimited(async () => {
return await this.sendSet(cacheName, encodedKey, encodedValue, ttlToUse);
});
}
async sendSet(cacheName, key, value, ttl) {
const request = new grpcCache._SetRequest({
cache_body: value,
cache_key: key,
ttl_milliseconds: (0, utils_2.secondsToMilliseconds)(ttl),
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().Set(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
if (resp) {
resolve(new __1.CacheSet.Success());
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheSet.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async setFetch(cacheName, setName) {
try {
(0, utils_1.validateCacheName)(cacheName);
(0, utils_1.validateSetName)(setName);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheSetFetch.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendSetFetch(cacheName, this.convert(setName));
});
}
async sendSetFetch(cacheName, setName) {
const request = new grpcCache._SetFetchRequest({
set_name: setName,
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().SetFetch(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
if (resp === null || resp === void 0 ? void 0 : resp.missing) {
resolve(new __1.CacheSetFetch.Miss());
}
else if (resp === null || resp === void 0 ? void 0 : resp.found) {
resolve(new __1.CacheSetFetch.Hit(resp.found.elements));
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheSetFetch.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async setAddElements(cacheName, setName, elements, ttl = __1.CollectionTtl.fromCacheTtl()) {
try {
(0, utils_1.validateCacheName)(cacheName);
(0, utils_1.validateSetName)(setName);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheSetAddElements.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendSetAddElements(cacheName, this.convert(setName), this.convertArray(elements), this.collectionTtlOrDefaultMilliseconds(ttl), ttl.refreshTtl());
});
}
async sendSetAddElements(cacheName, setName, elements, ttlMilliseconds, refreshTtl) {
const request = new grpcCache._SetUnionRequest({
set_name: setName,
elements: elements,
ttl_milliseconds: ttlMilliseconds,
refresh_ttl: refreshTtl,
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().SetUnion(request, metadata, {
interceptors: this.interceptors,
}, err => {
if (err) {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheSetAddElements.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
else {
resolve(new __1.CacheSetAddElements.Success());
}
});
});
}
async setContainsElement(cacheName, setName, element) {
try {
(0, utils_1.validateCacheName)(cacheName);
(0, utils_1.validateSetName)(setName);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheSetContainsElement.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendSetContainsElement(cacheName, this.convert(setName), this.convert(element));
});
}
async sendSetContainsElement(cacheName, setName, element) {
const request = new grpcCache._SetContainsRequest({
set_name: setName,
elements: [element],
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().SetContains(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
if (resp === null || resp === void 0 ? void 0 : resp.found) {
const found_mask = resp === null || resp === void 0 ? void 0 : resp.found.contains;
if (found_mask === undefined || found_mask.length === 0) {
return reject(new __1.CacheSetContainsElement.Error(new __1.UnknownError('SetContains response missing contains mask')));
}
resolve(new __1.CacheSetContainsElement.Hit(found_mask[0]));
}
else if (resp === null || resp === void 0 ? void 0 : resp.missing) {
resolve(new __1.CacheSetContainsElement.Miss());
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheSetContainsElement.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async setContainsElements(cacheName, setName, elements) {
try {
(0, utils_1.validateCacheName)(cacheName);
(0, utils_1.validateSetName)(setName);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheSetContainsElements.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendSetContainsElements(cacheName, this.convert(setName), this.convertArray(elements));
});
}
async sendSetContainsElements(cacheName, setName, elements) {
const request = new grpcCache._SetContainsRequest({
set_name: setName,
elements: elements,
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().SetContains(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
if (resp === null || resp === void 0 ? void 0 : resp.found) {
resolve(new __1.CacheSetContainsElements.Hit(elements, resp === null || resp === void 0 ? void 0 : resp.found.contains));
}
else if (resp === null || resp === void 0 ? void 0 : resp.missing) {
resolve(new __1.CacheSetContainsElements.Miss());
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheSetContainsElements.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async setRemoveElements(cacheName, setName, elements) {
try {
(0, utils_1.validateCacheName)(cacheName);
(0, utils_1.validateSetName)(setName);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheSetRemoveElements.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendSetRemoveElements(cacheName, this.convert(setName), this.convertArray(elements));
});
}
async sendSetRemoveElements(cacheName, setName, elements) {
const subtrahend = new grpcCache._SetDifferenceRequest._Subtrahend({
set: new grpcCache._SetDifferenceRequest._Subtrahend._Set({
elements: elements,
}),
});
const request = new grpcCache._SetDifferenceRequest({
set_name: setName,
subtrahend: subtrahend,
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().SetDifference(request, metadata, {
interceptors: this.interceptors,
}, err => {
if (err) {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheSetRemoveElements.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
else {
resolve(new __1.CacheSetRemoveElements.Success());
}
});
});
}
async setSample(cacheName, setName, limit) {
try {
(0, utils_1.validateCacheName)(cacheName);
(0, utils_1.validateSetName)(setName);
(0, utils_1.validateSetSampleLimit)(limit);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheSetSample.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendSetSample(cacheName, this.convert(setName), limit);
});
}
async sendSetSample(cacheName, setName, limit) {
const request = new grpcCache._SetSampleRequest({
set_name: setName,
limit: limit,
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().SetSample(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
if (resp === null || resp === void 0 ? void 0 : resp.missing) {
resolve(new __1.CacheSetSample.Miss());
}
else if (resp === null || resp === void 0 ? void 0 : resp.found) {
resolve(new __1.CacheSetSample.Hit(resp.found.elements));
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheSetSample.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async setPop(cacheName, setName, count) {
try {
(0, utils_1.validateCacheName)(cacheName);
(0, utils_1.validateSetName)(setName);
(0, utils_1.validateSetPopCount)(count);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new sdk_core_1.CacheSetPop.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendSetPop(cacheName, this.convert(setName), count);
});
}
async sendSetPop(cacheName, setName, count) {
const request = new grpcCache._SetPopRequest({
set_name: setName,
count: count,
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().SetPop(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
if (resp === null || resp === void 0 ? void 0 : resp.missing) {
resolve(new sdk_core_1.CacheSetPop.Miss());
}
else if (resp === null || resp === void 0 ? void 0 : resp.found) {
resolve(new sdk_core_1.CacheSetPop.Hit(resp.found.elements));
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new sdk_core_1.CacheSetPop.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async setLength(cacheName, setName) {
try {
(0, utils_1.validateCacheName)(cacheName);
(0, utils_1.validateSetName)(setName);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new sdk_core_1.CacheSetLength.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendSetLength(cacheName, this.convert(setName));
});
}
async sendSetLength(cacheName, setName) {
const request = new grpcCache._SetLengthRequest({
set_name: setName,
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().SetLength(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
if (resp === null || resp === void 0 ? void 0 : resp.missing) {
resolve(new sdk_core_1.CacheSetLength.Miss());
}
else if (resp === null || resp === void 0 ? void 0 : resp.found) {
if (!resp.found.length) {
resolve(new sdk_core_1.CacheSetLength.Miss());
}
else {
resolve(new sdk_core_1.CacheSetLength.Hit(resp.found.length));
}
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new sdk_core_1.CacheSetLength.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
// setIfNotExists is deprecated on the service. Here we call the new `SetIf` method with the absent field set
// and return `CacheSetIfNotExists` responses.
async setIfNotExists(cacheName, key, value, ttl) {
try {
(0, utils_1.validateCacheName)(cacheName);
if (ttl !== undefined) {
(0, utils_1.validateTtlSeconds)(ttl);
}
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheSetIfNotExists.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendSetIfNotExists(cacheName, this.convert(key), this.convert(value), this.ttlOrDefaultMilliseconds(ttl));
});
}
async sendSetIfNotExists(cacheName, key, value, ttlMilliseconds) {
const request = new grpcCache._SetIfRequest({
cache_key: key,
cache_body: value,
ttl_milliseconds: ttlMilliseconds,
absent: new Absent(),
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().SetIf(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
if (resp) {
switch (resp.result) {
case 'stored':
resolve(new __1.CacheSetIfNotExists.Stored());
break;
case 'not_stored':
resolve(new __1.CacheSetIfNotExists.NotStored());
break;
default:
resolve(new __1.CacheSetIfNotExists.Error(new __1.UnknownError('SetIfNotExists responded with an unknown result')));
break;
}
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheSetIfNotExists.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async setIfAbsent(cacheName, key, value, options) {
const ttl = options === null || options === void 0 ? void 0 : options.ttl;
try {
(0, utils_1.validateCacheName)(cacheName);
if (ttl !== undefined) {
(0, utils_1.validateTtlSeconds)(ttl);
}
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheSetIfAbsent.Error(err));
}
return await this.rateLimited(async () => {
let encodedValue = this.convert(value);
if (options === null || options === void 0 ? void 0 : options.compress) {
this.logger.trace('CacheClient.setIfAbsent; compression enabled, calling value compressor');
if (this.compressionDetails === undefined) {
return this.cacheServiceErrorMapper.returnOrThrowError(new __1.InvalidArgumentError('Compressor is not set, but `CacheClient.setIfAbsent` was called with the `compress` option; please install @gomomento/sdk-nodejs-compression and call `Configuration.withCompressionStrategy` to enable compression.'), err => new __1.CacheSetIfAbsent.Error(err));
}
encodedValue = await this.compressionDetails.valueCompressor.compress(this.compressionDetails.compressionLevel, encodedValue);
}
return await this.sendSetIfAbsent(cacheName, this.convert(key), encodedValue, this.ttlOrDefaultMilliseconds(ttl));
});
}
async sendSetIfAbsent(cacheName, key, value, ttlMilliseconds) {
const request = new grpcCache._SetIfRequest({
cache_key: key,
cache_body: value,
ttl_milliseconds: ttlMilliseconds,
absent: new Absent(),
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().SetIf(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
if (resp) {
switch (resp.result) {
case 'stored':
resolve(new __1.CacheSetIfAbsent.Stored());
break;
case 'not_stored':
resolve(new __1.CacheSetIfAbsent.NotStored());
break;
default:
resolve(new __1.CacheSetIfAbsent.Error(new __1.UnknownError('SetIfAbsent responded with an unknown result')));
break;
}
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheSetIfAbsent.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async setIfPresent(cacheName, key, value, ttl) {
try {
(0, utils_1.validateCacheName)(cacheName);
if (ttl !== undefined) {
(0, utils_1.validateTtlSeconds)(ttl);
}
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheSetIfPresent.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendSetIfPresent(cacheName, this.convert(key), this.convert(value), this.ttlOrDefaultMilliseconds(ttl));
});
}
async sendSetIfPresent(cacheName, key, value, ttlMilliseconds) {
const request = new grpcCache._SetIfRequest({
cache_key: key,
cache_body: value,
ttl_milliseconds: ttlMilliseconds,
present: new Present(),
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().SetIf(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
if (resp) {
switch (resp.result) {
case 'stored':
resolve(new __1.CacheSetIfPresent.Stored());
break;
case 'not_stored':
resolve(new __1.CacheSetIfPresent.NotStored());
break;
default:
resolve(new __1.CacheSetIfPresent.Error(new __1.UnknownError('SetIfPresent responded with an unknown result')));
break;
}
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheSetIfPresent.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async setIfEqual(cacheName, key, value, equal, ttl) {
try {
(0, utils_1.validateCacheName)(cacheName);
if (ttl !== undefined) {
(0, utils_1.validateTtlSeconds)(ttl);
}
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheSetIfEqual.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendSetIfEqual(cacheName, this.convert(key), this.convert(value), this.convert(equal), this.ttlOrDefaultMilliseconds(ttl));
});
}
async sendSetIfEqual(cacheName, key, value, equal, ttlMilliseconds) {
const request = new grpcCache._SetIfRequest({
cache_key: key,
cache_body: value,
ttl_milliseconds: ttlMilliseconds,
equal: new Equal({ value_to_check: equal }),
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().SetIf(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
if (resp) {
switch (resp.result) {
case 'stored':
resolve(new __1.CacheSetIfEqual.Stored());
break;
case 'not_stored':
resolve(new __1.CacheSetIfEqual.NotStored());
break;
default:
resolve(new __1.CacheSetIfEqual.Error(new __1.UnknownError('SetIfEqual responded with an unknown result')));
break;
}
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheSetIfEqual.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async setIfNotEqual(cacheName, key, value, notEqual, ttl) {
try {
(0, utils_1.validateCacheName)(cacheName);
if (ttl !== undefined) {
(0, utils_1.validateTtlSeconds)(ttl);
}
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheSetIfNotEqual.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendSetIfNotEqual(cacheName, this.convert(key), this.convert(value), this.convert(notEqual), this.ttlOrDefaultMilliseconds(ttl));
});
}
async sendSetIfNotEqual(cacheName, key, value, notEqual, ttlMilliseconds) {
const request = new grpcCache._SetIfRequest({
cache_key: key,
cache_body: value,
ttl_milliseconds: ttlMilliseconds,
not_equal: new NotEqual({ value_to_check: notEqual }),
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().SetIf(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
if (resp) {
switch (resp.result) {
case 'stored':
resolve(new __1.CacheSetIfNotEqual.Stored());
break;
case 'not_stored':
resolve(new __1.CacheSetIfNotEqual.NotStored());
break;
default:
resolve(new __1.CacheSetIfNotEqual.Error(new __1.UnknownError('SetIfNotEqual responded with an unknown result')));
break;
}
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheSetIfNotEqual.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async setIfPresentAndNotEqual(cacheName, key, value, notEqual, ttl) {
try {
(0, utils_1.validateCacheName)(cacheName);
if (ttl !== undefined) {
(0, utils_1.validateTtlSeconds)(ttl);
}
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheSetIfPresentAndNotEqual.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendSetIfPresentAndNotEqual(cacheName, this.convert(key), this.convert(value), this.convert(notEqual), this.ttlOrDefaultMilliseconds(ttl));
});
}
async sendSetIfPresentAndNotEqual(cacheName, key, value, notEqual, ttlMilliseconds) {
const request = new grpcCache._SetIfRequest({
cache_key: key,
cache_body: value,
ttl_milliseconds: ttlMilliseconds,
present_and_not_equal: new PresentAndNotEqual({ value_to_check: notEqual }),
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().SetIf(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
if (resp) {
switch (resp.result) {
case 'stored':
resolve(new __1.CacheSetIfPresentAndNotEqual.Stored());
break;
case 'not_stored':
resolve(new __1.CacheSetIfPresentAndNotEqual.NotStored());
break;
default:
resolve(new __1.CacheSetIfPresentAndNotEqual.Error(new __1.UnknownError('SetIfPresentAndNotEqual responded with an unknown result')));
break;
}
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheSetIfPresentAndNotEqual.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async setIfAbsentOrEqual(cacheName, key, value, equal, ttl) {
try {
(0, utils_1.validateCacheName)(cacheName);
if (ttl !== undefined) {
(0, utils_1.validateTtlSeconds)(ttl);
}
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheSetIfAbsentOrEqual.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendSetIfAbsentOrEqual(cacheName, this.convert(key), this.convert(value), this.convert(equal), this.ttlOrDefaultMilliseconds(ttl));
});
}
async sendSetIfAbsentOrEqual(cacheName, key, value, equal, ttlMilliseconds) {
const request = new grpcCache._SetIfRequest({
cache_key: key,
cache_body: value,
ttl_milliseconds: ttlMilliseconds,
absent_or_equal: new AbsentOrEqual({ value_to_check: equal }),
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().SetIf(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
if (resp) {
switch (resp.result) {
case 'stored':
resolve(new __1.CacheSetIfAbsentOrEqual.Stored());
break;
case 'not_stored':
resolve(new __1.CacheSetIfAbsentOrEqual.NotStored());
break;
default:
resolve(new __1.CacheSetIfAbsentOrEqual.Error(new __1.UnknownError('SetIfAbsentOrEqual responded with an unknown result')));
break;
}
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheSetIfAbsentOrEqual.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async delete(cacheName, key) {
try {
(0, utils_1.validateCacheName)(cacheName);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheDelete.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendDelete(cacheName, this.convert(key));
});
}
async sendDelete(cacheName, key) {
const request = new grpcCache._DeleteRequest({
cache_key: key,
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().Delete(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
if (resp) {
resolve(new __1.CacheDelete.Success());
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheDelete.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async get(cacheName, key, options) {
try {
(0, utils_1.validateCacheName)(cacheName);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheGet.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendGet(cacheName, this.convert(key), options);
});
}
async sendGet(cacheName, key, options) {
const request = new grpcCache._GetRequest({
cache_key: key,
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().Get(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
var _a, _b;
if (resp) {
switch (resp.result) {
case grpcCache.ECacheResult.Miss:
resolve(new __1.CacheGet.Miss());
break;
case grpcCache.ECacheResult.Hit: {
const shouldDecompress = (_a = options === null || options === void 0 ? void 0 : options.decompress) !== null && _a !== void 0 ? _a : ((_b = this.compressionDetails) === null || _b === void 0 ? void 0 : _b.autoDecompressEnabled) === true;
if (!shouldDecompress) {
resolve(new __1.CacheGet.Hit(resp.cache_body));
}
else {
if (this.compressionDetails === undefined) {
resolve(new __1.CacheGet.Error(new compression_error_1.CompressionError('CacheClient.Get', 'decompress')));
}
else {
this.compressionDetails.valueCompressor
.decompressIfCompressed(resp.cache_body)
.then(v => resolve(new __1.CacheGet.Hit(v)))
.catch(e => resolve(
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
new __1.CacheGet.Error(new __1.InvalidArgumentError(`${e}`))));
}
}
break;
}
case grpcCache.ECacheResult.Invalid:
case grpcCache.ECacheResult.Ok:
resolve(new __1.CacheGet.Error(new __1.UnknownError(resp.message)));
break;
default:
resolve(new __1.CacheGet.Error(new __1.UnknownError('An unknown error occurred: ' + resp.message)));
break;
}
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheGet.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async getBatch(cacheName, keys, options) {
try {
(0, utils_1.validateCacheName)(cacheName);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheGetBatch.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendGetBatch(cacheName, keys.map(key => this.convert(key)), options === null || options === void 0 ? void 0 : options.decompress);
});
}
async sendGetBatch(cacheName, keys, decompress) {
const getRequests = [];
for (const k of keys) {
const getRequest = new grpcCache._GetRequest({
cache_key: k,
});
getRequests.push(getRequest);
}
const request = new grpcCache._GetBatchRequest({
items: getRequests,
});
const metadata = this.createMetadata(cacheName);
const call = this.clientWrapper.getClient().GetBatch(request, metadata, {
interceptors: this.streamingInterceptors,
});
return await new Promise((resolve, reject) => {
const results = [];
call.on('data', (getResponse) => {
const result = getResponse.result;
switch (result) {
case grpcCache.ECacheResult.Hit:
results.push(new __1.CacheGet.Hit(getResponse.cache_body));
break;
case grpcCache.ECacheResult.Miss:
results.push(new __1.CacheGet.Miss());
break;
default:
results.push(new __1.CacheGet.Error(new __1.UnknownError(getResponse.message)));
}
});
call.on('end', () => {
var _a;
const shouldDecompress = decompress !== null && decompress !== void 0 ? decompress : ((_a = this.compressionDetails) === null || _a === void 0 ? void 0 : _a.autoDecompressEnabled) === true;
if (!shouldDecompress) {
resolve(new __1.CacheGetBatch.Success(results, keys));
}
else {
if (this.compressionDetails === undefined) {
resolve(new __1.CacheGetBatch.Error(new compression_error_1.CompressionError('CacheClient.Get', 'decompress')));
}
else {
const compressor = this.compressionDetails.valueCompressor;
Promise.all(results.map(async (r) => {
if (r instanceof __1.CacheGet.Hit) {
return new __1.CacheGet.Hit(await compressor.decompressIfCompressed(r.valueUint8Array()));
}
return r;
}))
.then(decompressedResults => resolve(new __1.CacheGetBatch.Success(decompressedResults, keys)))
.catch(e =>
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
resolve(new __1.CacheGetBatch.Error(new __1.UnknownError(`${e}`))));
}
}
});
call.on('error', (err) => {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheGetBatch.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
});
});
}
async setBatch(cacheName, items, options) {
try {
(0, utils_1.validateCacheName)(cacheName);
if ((options === null || options === void 0 ? void 0 : options.ttl) !== undefined) {
(0, utils_1.validateTtlSeconds)(options === null || options === void 0 ? void 0 : options.ttl);
}
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheSetBatch.Error(err));
}
const ttlToUse = (options === null || options === void 0 ? void 0 : options.ttl) || this.defaultTtlSeconds;
return await this.rateLimited(async () => {
let itemsToUse = this.convertSetBatchElements(items, ttlToUse);
if (options === null || options === void 0 ? void 0 : options.compress) {
this.logger.trace('CacheClient.setBatch; compression enabled, calling value compressor');
if (this.compressionDetails === undefined) {
return this.cacheServiceErrorMapper.returnOrThrowError(new compression_error_1.CompressionError('CacheClient.setBatch', 'compress'), err => new __1.CacheSetBatch.Error(err));
}
else {
const compressor = this.compressionDetails.valueCompressor;
const compressionLevel = this.compressionDetails.compressionLevel;
itemsToUse = await Promise.all(itemsToUse.map(async ([key, value, ttl]) => {
return [
key,
await compressor.compress(compressionLevel, value),
ttl,
];
}));
}
}
return await this.sendSetBatch(cacheName, itemsToUse);
});
}
async sendSetBatch(cacheName, items) {
const setRequests = [];
for (const item of items) {
const setRequest = new grpcCache._SetRequest({
cache_key: item[0],
cache_body: item[1],
ttl_milliseconds: (0, utils_2.secondsToMilliseconds)(item[2]),
});
setRequests.push(setRequest);
}
const request = new grpcCache._SetBatchRequest({
items: setRequests,
});
const metadata = this.createMetadata(cacheName);
const call = this.clientWrapper.getClient().SetBatch(request, metadata, {
interceptors: this.streamingInterceptors,
});
return await new Promise((resolve, reject) => {
const results = [];
call.on('data', (setResponse) => {
const result = setResponse.result;
switch (result) {
case grpcCache.ECacheResult.Ok:
results.push(new __1.CacheSet.Success());
break;
default:
results.push(new __1.CacheSet.Error(new __1.UnknownError(setResponse.message)));
}
});
call.on('end', () => {
resolve(new __1.CacheSetBatch.Success(results));
});
call.on('error', (err) => {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheSetBatch.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
});
});
}
async listConcatenateBack(cacheName, listName, values, truncateFrontToSize, ttl = __1.CollectionTtl.fromCacheTtl()) {
try {
(0, utils_1.validateCacheName)(cacheName);
(0, utils_1.validateListName)(listName);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheListConcatenateBack.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendListConcatenateBack(cacheName, this.convert(listName), this.convertArray(values), this.collectionTtlOrDefaultMilliseconds(ttl), ttl.refreshTtl(), truncateFrontToSize);
});
}
async sendListConcatenateBack(cacheName, listName, values, ttlMilliseconds, refreshTtl, truncateFrontToSize) {
const request = new grpcCache._ListConcatenateBackRequest({
list_name: listName,
values: values,
ttl_milliseconds: ttlMilliseconds,
refresh_ttl: refreshTtl,
truncate_front_to_size: truncateFrontToSize,
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().ListConcatenateBack(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
if (resp) {
resolve(new __1.CacheListConcatenateBack.Success(resp.list_length));
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheListConcatenateBack.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async listConcatenateFront(cacheName, listName, values, truncateBackToSize, ttl = __1.CollectionTtl.fromCacheTtl()) {
try {
(0, utils_1.validateCacheName)(cacheName);
(0, utils_1.validateListName)(listName);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheListConcatenateFront.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendListConcatenateFront(cacheName, this.convert(listName), this.convertArray(values), this.collectionTtlOrDefaultMilliseconds(ttl), ttl.refreshTtl(), truncateBackToSize);
});
}
async sendListConcatenateFront(cacheName, listName, values, ttlMilliseconds, refreshTtl, truncateBackToSize) {
const request = new grpcCache._ListConcatenateFrontRequest({
list_name: listName,
values: values,
ttl_milliseconds: ttlMilliseconds,
refresh_ttl: refreshTtl,
truncate_back_to_size: truncateBackToSize,
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().ListConcatenateFront(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
if (resp) {
resolve(new __1.CacheListConcatenateFront.Success(resp.list_length));
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheListConcatenateFront.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async listFetch(cacheName, listName, startIndex, endIndex) {
try {
(0, utils_1.validateCacheName)(cacheName);
(0, utils_1.validateListName)(listName);
(0, utils_1.validateListSliceStartEnd)(startIndex, endIndex);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheListFetch.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendListFetch(cacheName, this.convert(listName), startIndex, endIndex);
});
}
async sendListFetch(cacheName, listName, start, end) {
const request = new grpcCache._ListFetchRequest({
list_name: listName,
});
if (start) {
request.inclusive_start = start;
}
else {
request.unbounded_start = new _Unbounded();
}
if (end) {
request.exclusive_end = end;
}
else {
request.unbounded_end = new _Unbounded();
}
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().ListFetch(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
if (resp === null || resp === void 0 ? void 0 : resp.missing) {
resolve(new __1.CacheListFetch.Miss());
}
else if (resp === null || resp === void 0 ? void 0 : resp.found) {
resolve(new __1.CacheListFetch.Hit(resp.found.values));
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheListFetch.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async listRetain(cacheName, listName, startIndex, endIndex, ttl = __1.CollectionTtl.fromCacheTtl()) {
try {
(0, utils_1.validateCacheName)(cacheName);
(0, utils_1.validateListName)(listName);
(0, utils_1.validateListSliceStartEnd)(startIndex, endIndex);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheListRetain.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendListRetain(cacheName, this.convert(listName), startIndex, endIndex, this.collectionTtlOrDefaultMilliseconds(ttl), ttl.refreshTtl());
});
}
async sendListRetain(cacheName, listName, start, end, ttlMilliseconds, refreshTtl) {
const request = new grpcCache._ListRetainRequest({
list_name: listName,
ttl_milliseconds: ttlMilliseconds,
refresh_ttl: refreshTtl,
});
if (start) {
request.inclusive_start = start;
}
else {
request.unbounded_start = new _Unbounded();
}
if (end) {
request.exclusive_end = end;
}
else {
request.unbounded_end = new _Unbounded();
}
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().ListRetain(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
if (resp) {
resolve(new __1.CacheListRetain.Success());
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheListRetain.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async listLength(cacheName, listName) {
try {
(0, utils_1.validateCacheName)(cacheName);
(0, utils_1.validateListName)(listName);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheListLength.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendListLength(cacheName, this.convert(listName));
});
}
async sendListLength(cacheName, listName) {
const request = new grpcCache._ListLengthRequest({
list_name: listName,
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().ListLength(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
if (resp === null || resp === void 0 ? void 0 : resp.missing) {
resolve(new __1.CacheListLength.Miss());
}
else if (resp === null || resp === void 0 ? void 0 : resp.found) {
resolve(new __1.CacheListLength.Hit(resp.found.length));
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheListLength.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async listPopBack(cacheName, listName) {
try {
(0, utils_1.validateCacheName)(cacheName);
(0, utils_1.validateListName)(listName);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheListPopBack.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendListPopBack(cacheName, this.convert(listName));
});
}
async sendListPopBack(cacheName, listName) {
const request = new grpcCache._ListPopBackRequest({
list_name: listName,
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().ListPopBack(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
if (resp === null || resp === void 0 ? void 0 : resp.missing) {
resolve(new __1.CacheListPopBack.Miss());
}
else if (resp === null || resp === void 0 ? void 0 : resp.found) {
resolve(new __1.CacheListPopBack.Hit(resp.found.back));
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheListPopBack.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async listPopFront(cacheName, listName) {
try {
(0, utils_1.validateCacheName)(cacheName);
(0, utils_1.validateListName)(listName);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheListPopFront.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendListPopFront(cacheName, this.convert(listName));
});
}
async sendListPopFront(cacheName, listName) {
const request = new grpcCache._ListPopFrontRequest({
list_name: listName,
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().ListPopFront(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
if (resp === null || resp === void 0 ? void 0 : resp.missing) {
resolve(new __1.CacheListPopFront.Miss());
}
else if (resp === null || resp === void 0 ? void 0 : resp.found) {
resolve(new __1.CacheListPopFront.Hit(resp.found.front));
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheListPopFront.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async listPushBack(cacheName, listName, value, truncateFrontToSize, ttl = __1.CollectionTtl.fromCacheTtl()) {
try {
(0, utils_1.validateCacheName)(cacheName);
(0, utils_1.validateListName)(listName);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheListPushBack.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendListPushBack(cacheName, this.convert(listName), this.convert(value), this.collectionTtlOrDefaultMilliseconds(ttl), ttl.refreshTtl(), truncateFrontToSize);
});
}
async sendListPushBack(cacheName, listName, value, ttlMilliseconds, refreshTtl, truncateFrontToSize) {
const request = new grpcCache._ListPushBackRequest({
list_name: listName,
value: value,
ttl_milliseconds: ttlMilliseconds,
refresh_ttl: refreshTtl,
truncate_front_to_size: truncateFrontToSize,
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().ListPushBack(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
if (resp) {
resolve(new __1.CacheListPushBack.Success(resp.list_length));
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheListPushBack.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async listPushFront(cacheName, listName, value, truncateBackToSize, ttl = __1.CollectionTtl.fromCacheTtl()) {
try {
(0, utils_1.validateCacheName)(cacheName);
(0, utils_1.validateListName)(listName);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheListPushFront.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendListPushFront(cacheName, this.convert(listName), this.convert(value), this.collectionTtlOrDefaultMilliseconds(ttl), ttl.refreshTtl(), truncateBackToSize);
});
}
async sendListPushFront(cacheName, listName, value, ttlMilliseconds, refreshTtl, truncateBackToSize) {
const request = new grpcCache._ListPushFrontRequest({
list_name: listName,
value: value,
ttl_milliseconds: ttlMilliseconds,
refresh_ttl: refreshTtl,
truncate_back_to_size: truncateBackToSize,
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().ListPushFront(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
if (resp) {
resolve(new __1.CacheListPushFront.Success(resp.list_length));
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheListPushFront.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async listRemoveValue(cacheName, listName, value) {
try {
(0, utils_1.validateCacheName)(cacheName);
(0, utils_1.validateListName)(listName);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheListRemoveValue.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendListRemoveValue(cacheName, this.convert(listName), this.convert(value));
});
}
async sendListRemoveValue(cacheName, listName, value) {
const request = new grpcCache._ListRemoveRequest({
list_name: listName,
all_elements_with_value: value,
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().ListRemove(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
if (resp) {
resolve(new __1.CacheListRemoveValue.Success());
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheListRemoveValue.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async dictionaryFetch(cacheName, dictionaryName) {
try {
(0, utils_1.validateCacheName)(cacheName);
(0, utils_1.validateDictionaryName)(dictionaryName);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheDictionaryFetch.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendDictionaryFetch(cacheName, this.convert(dictionaryName));
});
}
async sendDictionaryFetch(cacheName, dictionaryName) {
const request = new grpcCache._DictionaryFetchRequest({
dictionary_name: dictionaryName,
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().DictionaryFetch(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
if (resp === null || resp === void 0 ? void 0 : resp.found) {
resolve(new __1.CacheDictionaryFetch.Hit(resp.found.items));
}
else if (resp === null || resp === void 0 ? void 0 : resp.missing) {
resolve(new __1.CacheDictionaryFetch.Miss());
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheDictionaryFetch.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async dictionarySetField(cacheName, dictionaryName, field, value, ttl = __1.CollectionTtl.fromCacheTtl()) {
try {
(0, utils_1.validateCacheName)(cacheName);
(0, utils_1.validateDictionaryName)(dictionaryName);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheDictionarySetField.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendDictionarySetField(cacheName, this.convert(dictionaryName), this.convert(field), this.convert(value), this.collectionTtlOrDefaultMilliseconds(ttl), ttl.refreshTtl());
});
}
async sendDictionarySetField(cacheName, dictionaryName, field, value, ttlMilliseconds, refreshTtl) {
const request = new grpcCache._DictionarySetRequest({
dictionary_name: dictionaryName,
items: this.toSingletonFieldValuePair(field, value),
ttl_milliseconds: ttlMilliseconds,
refresh_ttl: refreshTtl,
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().DictionarySet(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
if (resp) {
resolve(new __1.CacheDictionarySetField.Success());
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheDictionarySetField.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async dictionarySetFields(cacheName, dictionaryName, elements, ttl = __1.CollectionTtl.fromCacheTtl()) {
try {
(0, utils_1.validateCacheName)(cacheName);
(0, utils_1.validateDictionaryName)(dictionaryName);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheDictionarySetFields.Error(err));
}
return await this.rateLimited(async () => {
const dictionaryFieldValuePairs = this.convertElements(elements);
return await this.sendDictionarySetFields(cacheName, this.convert(dictionaryName), dictionaryFieldValuePairs, this.collectionTtlOrDefaultMilliseconds(ttl), ttl.refreshTtl());
});
}
async sendDictionarySetFields(cacheName, dictionaryName, elements, ttlMilliseconds, refreshTtl) {
const request = new grpcCache._DictionarySetRequest({
dictionary_name: dictionaryName,
items: elements,
ttl_milliseconds: ttlMilliseconds,
refresh_ttl: refreshTtl,
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().DictionarySet(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
if (resp) {
resolve(new __1.CacheDictionarySetFields.Success());
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheDictionarySetFields.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async dictionaryGetField(cacheName, dictionaryName, field) {
try {
(0, utils_1.validateCacheName)(cacheName);
(0, utils_1.validateDictionaryName)(dictionaryName);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheDictionaryGetField.Error(err, this.convert(field)));
}
return await this.rateLimited(async () => {
return await this.sendDictionaryGetField(cacheName, this.convert(dictionaryName), this.convert(field));
});
}
async sendDictionaryGetField(cacheName, dictionaryName, field) {
const request = new grpcCache._DictionaryGetRequest({
dictionary_name: dictionaryName,
fields: [field],
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().DictionaryGet(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
if ((resp === null || resp === void 0 ? void 0 : resp.dictionary) === 'missing') {
resolve(new __1.CacheDictionaryGetField.Miss(field));
}
else if ((resp === null || resp === void 0 ? void 0 : resp.dictionary) === 'found') {
if ((resp === null || resp === void 0 ? void 0 : resp.found.items.length) === 0) {
resolve(new __1.CacheDictionaryGetField.Error(new __1.UnknownError('_DictionaryGetResponseResponse contained no data but was found'), field));
}
else if ((resp === null || resp === void 0 ? void 0 : resp.found.items[0].result) === grpcCache.ECacheResult.Miss) {
resolve(new __1.CacheDictionaryGetField.Miss(field));
}
else {
resolve(new __1.CacheDictionaryGetField.Hit(resp === null || resp === void 0 ? void 0 : resp.found.items[0].cache_body, field));
}
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheDictionaryGetField.Error(e, field),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async dictionaryGetFields(cacheName, dictionaryName, fields) {
try {
(0, utils_1.validateCacheName)(cacheName);
(0, utils_1.validateDictionaryName)(dictionaryName);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheDictionaryGetFields.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendDictionaryGetFields(cacheName, this.convert(dictionaryName), this.convertArray(fields));
});
}
async sendDictionaryGetFields(cacheName, dictionaryName, fields) {
const request = new grpcCache._DictionaryGetRequest({
dictionary_name: dictionaryName,
fields: fields,
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().DictionaryGet(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
if ((resp === null || resp === void 0 ? void 0 : resp.dictionary) === 'found') {
const items = resp.found.items.map(item => {
const result = this.convertECacheResult(item.result);
return new grpc_response_types_1._DictionaryGetResponsePart(result, item.cache_body);
});
resolve(new __1.CacheDictionaryGetFields.Hit(items, fields));
}
else if ((resp === null || resp === void 0 ? void 0 : resp.dictionary) === 'missing') {
resolve(new __1.CacheDictionaryGetFields.Miss());
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheDictionaryGetFields.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async dictionaryRemoveField(cacheName, dictionaryName, field) {
try {
(0, utils_1.validateCacheName)(cacheName);
(0, utils_1.validateDictionaryName)(dictionaryName);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheDictionaryRemoveField.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendDictionaryRemoveField(cacheName, this.convert(dictionaryName), this.convert(field));
});
}
async sendDictionaryRemoveField(cacheName, dictionaryName, field) {
const request = new grpcCache._DictionaryDeleteRequest({
dictionary_name: dictionaryName,
some: new grpcCache._DictionaryDeleteRequest.Some(),
});
request.some.fields.push(field);
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().DictionaryDelete(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
if (resp) {
resolve(new __1.CacheDictionaryRemoveField.Success());
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheDictionaryRemoveField.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async dictionaryRemoveFields(cacheName, dictionaryName, fields) {
try {
(0, utils_1.validateCacheName)(cacheName);
(0, utils_1.validateDictionaryName)(dictionaryName);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheDictionaryRemoveFields.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendDictionaryRemoveFields(cacheName, this.convert(dictionaryName), this.convertArray(fields));
});
}
async sendDictionaryRemoveFields(cacheName, dictionaryName, fields) {
const request = new grpcCache._DictionaryDeleteRequest({
dictionary_name: dictionaryName,
some: new grpcCache._DictionaryDeleteRequest.Some(),
});
fields.forEach(field => request.some.fields.push(field));
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().DictionaryDelete(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
if (resp) {
resolve(new __1.CacheDictionaryRemoveFields.Success());
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheDictionaryRemoveFields.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async dictionaryLength(cacheName, dictionaryName) {
try {
(0, utils_1.validateCacheName)(cacheName);
(0, utils_1.validateDictionaryName)(dictionaryName);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheDictionaryLength.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendDictionaryLength(cacheName, this.convert(dictionaryName));
});
}
async sendDictionaryLength(cacheName, dictionaryName) {
const request = new grpcCache._DictionaryLengthRequest({
dictionary_name: dictionaryName,
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().DictionaryLength(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
if (resp === null || resp === void 0 ? void 0 : resp.missing) {
resolve(new __1.CacheDictionaryLength.Miss());
}
else if (resp === null || resp === void 0 ? void 0 : resp.found) {
resolve(new __1.CacheDictionaryLength.Hit(resp.found.length));
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheDictionaryLength.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async increment(cacheName, field, amount = 1, ttl) {
try {
(0, utils_1.validateCacheName)(cacheName);
if (ttl !== undefined) {
(0, utils_1.validateTtlSeconds)(ttl);
}
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheIncrement.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendIncrement(cacheName, this.convert(field), amount, this.ttlOrDefaultMilliseconds(ttl));
});
}
async sendIncrement(cacheName, field, amount = 1, ttlMilliseconds) {
const request = new grpcCache._IncrementRequest({
cache_key: field,
amount,
ttl_milliseconds: ttlMilliseconds,
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().Increment(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
if (resp) {
if (resp.value) {
resolve(new __1.CacheIncrement.Success(resp.value));
}
else {
resolve(new __1.CacheIncrement.Success(0));
}
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheIncrement.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async dictionaryIncrement(cacheName, dictionaryName, field, amount = 1, ttl = __1.CollectionTtl.fromCacheTtl()) {
try {
(0, utils_1.validateCacheName)(cacheName);
(0, utils_1.validateDictionaryName)(dictionaryName);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheDictionaryIncrement.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendDictionaryIncrement(cacheName, this.convert(dictionaryName), this.convert(field), amount, this.collectionTtlOrDefaultMilliseconds(ttl), ttl.refreshTtl());
});
}
async sendDictionaryIncrement(cacheName, dictionaryName, field, amount, ttlMilliseconds, refreshTtl) {
const request = new grpcCache._DictionaryIncrementRequest({
dictionary_name: dictionaryName,
field,
amount,
ttl_milliseconds: ttlMilliseconds,
refresh_ttl: refreshTtl,
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().DictionaryIncrement(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
if (resp) {
if (resp.value) {
resolve(new __1.CacheDictionaryIncrement.Success(resp.value));
}
else {
resolve(new __1.CacheDictionaryIncrement.Success(0));
}
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheDictionaryIncrement.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async sortedSetPutElement(cacheName, sortedSetName, value, score, ttl = __1.CollectionTtl.fromCacheTtl()) {
try {
(0, utils_1.validateCacheName)(cacheName);
(0, utils_1.validateSortedSetName)(sortedSetName);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheSortedSetPutElement.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendSortedSetPutElement(cacheName, this.convert(sortedSetName), this.convert(value), score, this.collectionTtlOrDefaultMilliseconds(ttl), ttl.refreshTtl());
});
}
async sendSortedSetPutElement(cacheName, sortedSetName, value, score, ttlMilliseconds, refreshTtl) {
const request = new grpcCache._SortedSetPutRequest({
set_name: sortedSetName,
elements: [new grpcCache._SortedSetElement({ value, score })],
ttl_milliseconds: ttlMilliseconds,
refresh_ttl: refreshTtl,
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().SortedSetPut(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
if (resp) {
resolve(new __1.CacheSortedSetPutElement.Success());
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheSortedSetPutElement.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async sortedSetPutElements(cacheName, sortedSetName, elements, ttl = __1.CollectionTtl.fromCacheTtl()) {
try {
(0, utils_1.validateCacheName)(cacheName);
(0, utils_1.validateSortedSetName)(sortedSetName);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheSortedSetPutElements.Error(err));
}
return await this.rateLimited(async () => {
const sortedSetValueScorePairs = this.convertSortedSetMapOrRecord(elements);
return await this.sendSortedSetPutElements(cacheName, this.convert(sortedSetName), sortedSetValueScorePairs, this.collectionTtlOrDefaultMilliseconds(ttl), ttl.refreshTtl());
});
}
async sendSortedSetPutElements(cacheName, sortedSetName, elements, ttlMilliseconds, refreshTtl) {
const request = new grpcCache._SortedSetPutRequest({
set_name: sortedSetName,
elements: elements,
ttl_milliseconds: ttlMilliseconds,
refresh_ttl: refreshTtl,
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().SortedSetPut(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
if (resp) {
resolve(new __1.CacheSortedSetPutElements.Success());
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheSortedSetPutElements.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async sortedSetFetchByRank(cacheName, sortedSetName, order, startRank, endRank) {
try {
(0, utils_1.validateCacheName)(cacheName);
(0, utils_1.validateSortedSetName)(sortedSetName);
(0, utils_1.validateSortedSetRanks)(startRank, endRank);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheSortedSetFetch.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendSortedSetFetchByRank(cacheName, this.convert(sortedSetName), order, startRank, endRank);
});
}
async sendSortedSetFetchByRank(cacheName, sortedSetName, order, startRank, endRank) {
const by_index = new grpcCache._SortedSetFetchRequest._ByIndex();
if (startRank) {
by_index.inclusive_start_index = startRank;
}
else {
by_index.unbounded_start = new _Unbounded();
}
if (endRank) {
by_index.exclusive_end_index = endRank;
}
else {
by_index.unbounded_end = new _Unbounded();
}
const protoBufOrder = order === __1.SortedSetOrder.Descending
? grpcCache._SortedSetFetchRequest.Order.DESCENDING
: grpcCache._SortedSetFetchRequest.Order.ASCENDING;
const request = new grpcCache._SortedSetFetchRequest({
set_name: sortedSetName,
order: protoBufOrder,
with_scores: true,
by_index: by_index,
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().SortedSetFetch(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
var _a;
if (resp) {
if (resp === null || resp === void 0 ? void 0 : resp.found) {
if ((_a = resp === null || resp === void 0 ? void 0 : resp.found) === null || _a === void 0 ? void 0 : _a.values_with_scores) {
resolve(new __1.CacheSortedSetFetch.Hit(resp.found.values_with_scores.elements));
}
else {
resolve(new __1.CacheSortedSetFetch.Error(new __1.UnknownError('Unknown sorted set fetch hit response type')));
}
}
else if (resp === null || resp === void 0 ? void 0 : resp.missing) {
resolve(new __1.CacheSortedSetFetch.Miss());
}
else {
resolve(new __1.CacheSortedSetFetch.Error(new __1.UnknownError('Unknown sorted set fetch response type')));
}
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheSortedSetFetch.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async sortedSetFetchByScore(cacheName, sortedSetName, order, minScore, maxScore, offset, count) {
try {
(0, utils_1.validateCacheName)(cacheName);
(0, utils_1.validateSortedSetName)(sortedSetName);
(0, utils_1.validateSortedSetScores)(minScore, maxScore);
if (offset !== undefined) {
(0, utils_1.validateSortedSetOffset)(offset);
}
if (count !== undefined) {
(0, utils_1.validateSortedSetCount)(count);
}
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheSortedSetFetch.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendSortedSetFetchByScore(cacheName, this.convert(sortedSetName), order, minScore, maxScore, offset, count);
});
}
async sendSortedSetFetchByScore(cacheName, sortedSetName, order, minScore, maxScore, offset, count) {
const by_score = new grpcCache._SortedSetFetchRequest._ByScore();
if (minScore !== undefined) {
by_score.min_score = new grpcCache._SortedSetFetchRequest._ByScore._Score({
score: minScore,
exclusive: false,
});
}
else {
by_score.unbounded_min = new _Unbounded();
}
if (maxScore !== undefined) {
by_score.max_score = new grpcCache._SortedSetFetchRequest._ByScore._Score({
score: maxScore,
exclusive: false,
});
}
else {
by_score.unbounded_max = new _Unbounded();
}
by_score.offset = offset !== null && offset !== void 0 ? offset : 0;
// Note: the service reserves negative counts to mean all elements in the
// result set.
by_score.count = count !== null && count !== void 0 ? count : -1;
const protoBufOrder = order === __1.SortedSetOrder.Descending
? grpcCache._SortedSetFetchRequest.Order.DESCENDING
: grpcCache._SortedSetFetchRequest.Order.ASCENDING;
const request = new grpcCache._SortedSetFetchRequest({
set_name: sortedSetName,
order: protoBufOrder,
with_scores: true,
by_score: by_score,
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().SortedSetFetch(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
var _a;
if (resp) {
if (resp === null || resp === void 0 ? void 0 : resp.found) {
if ((_a = resp === null || resp === void 0 ? void 0 : resp.found) === null || _a === void 0 ? void 0 : _a.values_with_scores) {
resolve(new __1.CacheSortedSetFetch.Hit(resp.found.values_with_scores.elements));
}
else {
resolve(new __1.CacheSortedSetFetch.Error(new __1.UnknownError('Unknown sorted set fetch hit response type')));
}
}
else if (resp === null || resp === void 0 ? void 0 : resp.missing) {
resolve(new __1.CacheSortedSetFetch.Miss());
}
else {
resolve(new __1.CacheSortedSetFetch.Error(new __1.UnknownError('Unknown sorted set fetch response type')));
}
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheSortedSetFetch.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async sortedSetGetRank(cacheName, sortedSetName, value, order) {
try {
(0, utils_1.validateCacheName)(cacheName);
(0, utils_1.validateSortedSetName)(sortedSetName);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheSortedSetGetRank.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendSortedSetGetRank(cacheName, this.convert(sortedSetName), this.convert(value), order);
});
}
async sendSortedSetGetRank(cacheName, sortedSetName, value, order) {
const protoBufOrder = order === __1.SortedSetOrder.Descending
? grpcCache._SortedSetGetRankRequest.Order.DESCENDING
: grpcCache._SortedSetGetRankRequest.Order.ASCENDING;
const request = new grpcCache._SortedSetGetRankRequest({
set_name: sortedSetName,
value: value,
order: protoBufOrder,
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper
.getClient()
.SortedSetGetRank(request, metadata, { interceptors: this.interceptors }, (err, resp) => {
var _a, _b;
if ((resp === null || resp === void 0 ? void 0 : resp.missing) ||
((_a = resp === null || resp === void 0 ? void 0 : resp.element_rank) === null || _a === void 0 ? void 0 : _a.result) === ECacheResult.Miss) {
resolve(new __1.CacheSortedSetGetRank.Miss());
}
else if (((_b = resp === null || resp === void 0 ? void 0 : resp.element_rank) === null || _b === void 0 ? void 0 : _b.result) === ECacheResult.Hit) {
if ((resp === null || resp === void 0 ? void 0 : resp.element_rank.rank) === undefined) {
resolve(new __1.CacheSortedSetGetRank.Miss());
}
else {
resolve(new __1.CacheSortedSetGetRank.Hit(resp.element_rank.rank));
}
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheSortedSetGetRank.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async sortedSetGetScore(cacheName, sortedSetName, value) {
const responses = await this.sortedSetGetScores(cacheName, sortedSetName, [
value,
]);
if (responses instanceof __1.CacheSortedSetGetScores.Hit) {
return responses.responses()[0];
}
else if (responses instanceof __1.CacheSortedSetGetScores.Miss) {
return new __1.CacheSortedSetGetScore.Miss(this.convert(value));
}
else if (responses instanceof __1.CacheSortedSetGetScores.Error) {
return this.cacheServiceErrorMapper.returnOrThrowError(responses.innerException(), err => new __1.CacheSortedSetGetScore.Error(err, this.convert(value)));
}
return this.cacheServiceErrorMapper.returnOrThrowError(new __1.UnknownError('Unknown response type'), err => new __1.CacheSortedSetGetScore.Error(err, this.convert(value)));
}
async sortedSetGetScores(cacheName, sortedSetName, values) {
try {
(0, utils_1.validateCacheName)(cacheName);
(0, utils_1.validateSortedSetName)(sortedSetName);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheSortedSetGetScores.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendSortedSetGetScores(cacheName, this.convert(sortedSetName), values.map(value => this.convert(value)));
});
}
async sendSortedSetGetScores(cacheName, sortedSetName, values) {
const request = new grpcCache._SortedSetGetScoreRequest({
set_name: sortedSetName,
values: values,
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper
.getClient()
.SortedSetGetScore(request, metadata, { interceptors: this.interceptors }, (err, resp) => {
if (resp === null || resp === void 0 ? void 0 : resp.missing) {
resolve(new __1.CacheSortedSetGetScores.Miss());
}
else if (resp === null || resp === void 0 ? void 0 : resp.found) {
const elements = resp.found.elements.map(ele => {
const result = this.convertECacheResult(ele.result);
return new grpc_response_types_1._SortedSetGetScoreResponsePart(result, ele.score);
});
resolve(new __1.CacheSortedSetGetScores.Hit(elements, values));
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheSortedSetGetScores.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async sortedSetIncrementScore(cacheName, sortedSetName, value, amount = 1, ttl = __1.CollectionTtl.fromCacheTtl()) {
try {
(0, utils_1.validateCacheName)(cacheName);
(0, utils_1.validateSortedSetName)(sortedSetName);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheSortedSetIncrementScore.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendSortedSetIncrementScore(cacheName, this.convert(sortedSetName), this.convert(value), amount, this.collectionTtlOrDefaultMilliseconds(ttl), ttl.refreshTtl());
});
}
async sendSortedSetIncrementScore(cacheName, sortedSetName, value, amount, ttlMilliseconds, refreshTtl) {
const request = new grpcCache._SortedSetIncrementRequest({
set_name: sortedSetName,
value: value,
amount: amount,
ttl_milliseconds: ttlMilliseconds,
refresh_ttl: refreshTtl,
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper
.getClient()
.SortedSetIncrement(request, metadata, { interceptors: this.interceptors }, (err, resp) => {
if (resp) {
if (resp.score) {
resolve(new __1.CacheSortedSetIncrementScore.Success(resp.score));
}
else {
resolve(new __1.CacheSortedSetIncrementScore.Success(0));
}
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheSortedSetIncrementScore.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async sortedSetRemoveElement(cacheName, sortedSetName, value) {
try {
(0, utils_1.validateCacheName)(cacheName);
(0, utils_1.validateSortedSetName)(sortedSetName);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheSortedSetRemoveElement.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendSortedSetRemoveElement(cacheName, this.convert(sortedSetName), this.convert(value));
});
}
async sendSortedSetRemoveElement(cacheName, sortedSetName, value) {
const request = new grpcCache._SortedSetRemoveRequest({
set_name: sortedSetName,
some: new grpcCache._SortedSetRemoveRequest._Some({
values: [value],
}),
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().SortedSetRemove(request, metadata, {
interceptors: this.interceptors,
}, err => {
if (err) {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheSortedSetRemoveElement.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
else {
resolve(new __1.CacheSortedSetRemoveElement.Success());
}
});
});
}
async sortedSetRemoveElements(cacheName, sortedSetName, values) {
try {
(0, utils_1.validateCacheName)(cacheName);
(0, utils_1.validateSortedSetName)(sortedSetName);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheSortedSetRemoveElements.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendSortedSetRemoveElements(cacheName, this.convert(sortedSetName), this.convertArray(values));
});
}
async sendSortedSetRemoveElements(cacheName, sortedSetName, values) {
const request = new grpcCache._SortedSetRemoveRequest({
set_name: sortedSetName,
some: new grpcCache._SortedSetRemoveRequest._Some({
values: values,
}),
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().SortedSetRemove(request, metadata, {
interceptors: this.interceptors,
}, err => {
if (err) {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheSortedSetRemoveElements.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
else {
resolve(new __1.CacheSortedSetRemoveElements.Success());
}
});
});
}
async sortedSetLength(cacheName, sortedSetName) {
try {
(0, utils_1.validateCacheName)(cacheName);
(0, utils_1.validateSortedSetName)(sortedSetName);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheSortedSetLength.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendSortedSetLength(cacheName, this.convert(sortedSetName));
});
}
async sendSortedSetLength(cacheName, sortedSetName) {
const request = new grpcCache._SortedSetLengthRequest({
set_name: sortedSetName,
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().SortedSetLength(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
if (resp === null || resp === void 0 ? void 0 : resp.missing) {
resolve(new __1.CacheSortedSetLength.Miss());
}
else if (resp === null || resp === void 0 ? void 0 : resp.found) {
if (!resp.found.length) {
resolve(new __1.CacheSortedSetLength.Miss());
}
else {
resolve(new __1.CacheSortedSetLength.Hit(resp.found.length));
}
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheSortedSetLength.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async sortedSetLengthByScore(cacheName, sortedSetName, minScore, maxScore) {
try {
(0, utils_1.validateCacheName)(cacheName);
(0, utils_1.validateSortedSetName)(sortedSetName);
(0, utils_1.validateSortedSetScores)(minScore, maxScore);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheSortedSetLengthByScore.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendSortedSetLengthByScore(cacheName, this.convert(sortedSetName), minScore, maxScore);
});
}
async sendSortedSetLengthByScore(cacheName, sortedSetName, minScore, maxScore) {
const request = new grpcCache._SortedSetLengthByScoreRequest({
set_name: sortedSetName,
});
if (minScore === undefined) {
request.unbounded_min = new _Unbounded();
}
else {
request.inclusive_min = minScore;
}
if (maxScore === undefined) {
request.unbounded_max = new _Unbounded();
}
else {
request.inclusive_max = maxScore;
}
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().SortedSetLengthByScore(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
if (resp === null || resp === void 0 ? void 0 : resp.missing) {
resolve(new __1.CacheSortedSetLengthByScore.Miss());
}
else if (resp === null || resp === void 0 ? void 0 : resp.found) {
if (!resp.found.length) {
resolve(new __1.CacheSortedSetLengthByScore.Miss());
}
else {
resolve(new __1.CacheSortedSetLengthByScore.Hit(resp.found.length));
}
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheSortedSetLengthByScore.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
initializeInterceptors(headers, loggerFactory, middlewares, middlewareRequestContext) {
return [
(0, middlewares_interceptor_1.middlewaresInterceptor)(loggerFactory, middlewares, middlewareRequestContext, this.clientWrapper.getClient()),
headers_interceptor_1.HeaderInterceptor.createHeadersInterceptor(headers),
retry_interceptor_1.RetryInterceptor.createRetryInterceptor({
clientName: 'CacheDataClient',
loggerFactory: this.configuration.getLoggerFactory(),
retryStrategy: this.configuration.getRetryStrategy(),
overallRequestTimeoutMs: this.requestTimeoutMs,
}),
];
}
// TODO https://github.com/momentohq/client-sdk-nodejs/issues/349
// decide on streaming interceptors and middlewares
initializeStreamingInterceptors(headers) {
return [headers_interceptor_1.HeaderInterceptor.createHeadersInterceptor(headers)];
}
convert(v) {
if (typeof v === 'string') {
return this.textEncoder.encode(v);
}
return v;
}
convertArray(v) {
return v.map(i => this.convert(i));
}
convertElements(elements) {
if (elements instanceof Array) {
return this.convertElements(new Map(elements));
}
else if (elements instanceof Map) {
return [...elements.entries()].map(element => new grpcCache._DictionaryFieldValuePair({
field: this.convert(element[0]),
value: this.convert(element[1]),
}));
}
else {
return Object.entries(elements).map(element => new grpcCache._DictionaryFieldValuePair({
field: this.convert(element[0]),
value: this.convert(element[1]),
}));
}
}
convertSortedSetMapOrRecord(elements) {
if (elements instanceof Array) {
return this.convertSortedSetMapOrRecord(new Map(elements));
}
else if (elements instanceof Map) {
return [...elements.entries()].map(element => new grpcCache._SortedSetElement({
value: this.convert(element[0]),
score: element[1],
}));
}
else {
return Object.entries(elements).map(element => new grpcCache._SortedSetElement({
value: this.convert(element[0]),
score: element[1],
}));
}
}
convertSetBatchElements(elements, ttl) {
if (elements instanceof Array) {
return elements.map(element => {
var _a;
return [
this.convert(element.key),
this.convert(element.value),
(_a = element.ttl) !== null && _a !== void 0 ? _a : ttl,
];
});
}
else if (elements instanceof Map) {
return [...elements.entries()].map(([k, v]) => [
this.convert(k),
this.convert(v),
ttl,
]);
}
else {
return Object.entries(elements).map(element => [
this.convert(element[0]),
this.convert(element[1]),
ttl,
]);
}
}
async itemGetType(cacheName, key) {
try {
(0, utils_1.validateCacheName)(cacheName);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheItemGetType.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendItemGetType(cacheName, this.convert(key));
});
}
async sendItemGetType(cacheName, key) {
const request = new grpcCache._ItemGetTypeRequest({
cache_key: key,
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().ItemGetType(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
if (resp === null || resp === void 0 ? void 0 : resp.missing) {
resolve(new __1.CacheItemGetType.Miss());
}
else if (resp === null || resp === void 0 ? void 0 : resp.found) {
resolve(new __1.CacheItemGetType.Hit(this.convertItemTypeResult(resp.found.item_type)));
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheItemGetType.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async itemGetTtl(cacheName, key) {
try {
(0, utils_1.validateCacheName)(cacheName);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheItemGetTtl.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendItemGetTtl(cacheName, this.convert(key));
});
}
async sendItemGetTtl(cacheName, key) {
const request = new grpcCache._ItemGetTtlRequest({
cache_key: key,
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().ItemGetTtl(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
if (resp === null || resp === void 0 ? void 0 : resp.missing) {
resolve(new __1.CacheItemGetTtl.Miss());
}
else if (resp === null || resp === void 0 ? void 0 : resp.found) {
resolve(new __1.CacheItemGetTtl.Hit(resp.found.remaining_ttl_millis));
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheItemGetTtl.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async keyExists(cacheName, key) {
try {
(0, utils_1.validateCacheName)(cacheName);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheKeyExists.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendKeyExists(cacheName, this.convert(key));
});
}
async sendKeyExists(cacheName, key) {
const request = new grpcCache._KeysExistRequest({
cache_keys: [key],
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().KeysExist(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
if (resp) {
resolve(new __1.CacheKeyExists.Success(resp.exists));
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheKeyExists.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async updateTtl(cacheName, key, ttlMilliseconds) {
try {
(0, utils_1.validateCacheName)(cacheName);
(0, utils_1.validateValidForSeconds)(ttlMilliseconds);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheUpdateTtl.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendUpdateTtl(cacheName, this.convert(key), ttlMilliseconds);
});
}
async sendUpdateTtl(cacheName, key, ttlMilliseconds) {
const request = new grpcCache._UpdateTtlRequest({
cache_key: key,
overwrite_to_milliseconds: ttlMilliseconds,
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().UpdateTtl(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
if (resp === null || resp === void 0 ? void 0 : resp.missing) {
resolve(new __1.CacheUpdateTtl.Miss());
}
else if (resp === null || resp === void 0 ? void 0 : resp.set) {
resolve(new __1.CacheUpdateTtl.Set());
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheUpdateTtl.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async keysExist(cacheName, keys) {
try {
(0, utils_1.validateCacheName)(cacheName);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheKeysExist.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendKeysExist(cacheName, this.convertArray(keys));
});
}
async sendKeysExist(cacheName, keys) {
const request = new grpcCache._KeysExistRequest({
cache_keys: keys,
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().KeysExist(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
if (resp) {
resolve(new __1.CacheKeysExist.Success(keys, resp.exists));
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheKeysExist.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async increaseTtl(cacheName, key, ttlMilliseconds) {
try {
(0, utils_1.validateCacheName)(cacheName);
(0, utils_1.validateValidForSeconds)(ttlMilliseconds);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheIncreaseTtl.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendIncreaseTtl(cacheName, this.convert(key), ttlMilliseconds);
});
}
async sendIncreaseTtl(cacheName, key, ttlMilliseconds) {
const request = new grpcCache._UpdateTtlRequest({
cache_key: key,
increase_to_milliseconds: ttlMilliseconds,
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().UpdateTtl(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
if (resp === null || resp === void 0 ? void 0 : resp.missing) {
resolve(new __1.CacheIncreaseTtl.Miss());
}
else if (resp === null || resp === void 0 ? void 0 : resp.not_set) {
resolve(new __1.CacheIncreaseTtl.NotSet());
}
else if (resp === null || resp === void 0 ? void 0 : resp.set) {
resolve(new __1.CacheIncreaseTtl.Set());
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheIncreaseTtl.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async decreaseTtl(cacheName, key, ttlMilliseconds) {
try {
(0, utils_1.validateCacheName)(cacheName);
(0, utils_1.validateValidForSeconds)(ttlMilliseconds);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheDecreaseTtl.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendDecreaseTtl(cacheName, this.convert(key), ttlMilliseconds);
});
}
async sendDecreaseTtl(cacheName, key, ttlMilliseconds) {
const request = new grpcCache._UpdateTtlRequest({
cache_key: key,
decrease_to_milliseconds: ttlMilliseconds,
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().UpdateTtl(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
if (resp === null || resp === void 0 ? void 0 : resp.missing) {
resolve(new __1.CacheDecreaseTtl.Miss());
}
else if (resp === null || resp === void 0 ? void 0 : resp.not_set) {
resolve(new __1.CacheDecreaseTtl.NotSet());
}
else if (resp === null || resp === void 0 ? void 0 : resp.set) {
resolve(new __1.CacheDecreaseTtl.Set());
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheDecreaseTtl.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
createMetadata(cacheName) {
const metadata = new grpc_js_1.Metadata();
metadata.set('cache', cacheName);
return metadata;
}
toSingletonFieldValuePair(field, value) {
return [
new grpcCache._DictionaryFieldValuePair({
field: field,
value: value,
}),
];
}
}
exports.CacheDataClient = CacheDataClient;
CacheDataClient.DEFAULT_REQUEST_TIMEOUT_MS = (0, utils_2.secondsToMilliseconds)(5);
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FjaGUtZGF0YS1jbGllbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvaW50ZXJuYWwvY2FjaGUtZGF0YS1jbGllbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsZ0VBQWlEO0FBQ2pELDBHQUEwRztBQUMxRywrQkFBaUM7QUFDakMsb0VBQXFFO0FBQ3JFLGdFQUEwRDtBQUMxRCxxRkFBNkU7QUFDN0UsMkNBS3VCO0FBQ3ZCLDBCQXFFWTtBQUNaLHFEQUEyQztBQUMzQyw4RUFBc0U7QUFNdEUsNEVBQXNFO0FBQ3RFLDZFQUF5RTtBQUV6RSx1RUFnQnFEO0FBQ3JELDZHQUk2RTtBQUU3RSxtRkFBNkU7QUFFN0Usc0VBQTZFO0FBQzdFLGdFQUFvRTtBQUNwRSxtRUFBOEQ7QUFDOUQsOERBUTRDO0FBQzVDLG1FQUE2RDtBQUM3RCxrREFBZ0U7QUFDaEUsSUFBTyxTQUFTLEdBQUcsdUJBQUssQ0FBQyxZQUFZLENBQUM7QUFDdEMsSUFBTyxZQUFZLEdBQUcsMEJBQVksQ0FBQyxZQUFZLENBQUM7QUFDaEQsSUFBTyxvQkFBb0IsR0FBRywwQkFBWSxDQUFDLG9CQUFvQixDQUFDO0FBQ2hFLElBQU8sVUFBVSxHQUFHLGVBQU0sQ0FBQyxVQUFVLENBQUM7QUFDdEMsSUFBTyxNQUFNLEdBQUcsZUFBTSxDQUFDLE1BQU0sQ0FBQztBQUM5QixJQUFPLE9BQU8sR0FBRyxlQUFNLENBQUMsT0FBTyxDQUFDO0FBQ2hDLElBQU8sS0FBSyxHQUFHLGVBQU0sQ0FBQyxLQUFLLENBQUM7QUFDNUIsSUFBTyxRQUFRLEdBQUcsZUFBTSxDQUFDLFFBQVEsQ0FBQztBQUNsQyxJQUFPLGtCQUFrQixHQUFHLGVBQU0sQ0FBQyxrQkFBa0IsQ0FBQztBQUN0RCxJQUFPLGFBQWEsR0FBRyxlQUFNLENBQUMsYUFBYSxDQUFDO0FBRS9CLFFBQUEsaUJBQWlCLEdBQUcsTUFBTSxDQUFDLGNBQWMsQ0FBQyxDQUFDO0FBUXhELE1BQWEsZUFBZTtJ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c291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtjYWNoZX0gZnJvbSAnQGdvbW9tZW50by9nZW5lcmF0ZWQtdHlwZXMnO1xuLy8gb2xkZXIgdmVyc2lvbnMgb2Ygbm9kZSBkb24ndCBoYXZlIHRoZSBnbG9iYWwgdXRpbCB2YXJpYWJsZXMgaHR0cHM6Ly9naXRodWIuY29tL25vZGVqcy9ub2RlL2lzc3Vlcy8yMDM2NVxuaW1wb3J0IHtUZXh0RW5jb2Rlcn0gZnJvbSAndXRpbCc7XG5pbXBvcnQge0hlYWRlciwgSGVhZGVySW50ZXJjZXB0b3J9IGZyb20gJy4vZ3JwYy9oZWFkZXJzLWludGVyY2VwdG9yJztcbmltcG9ydCB7UmV0cnlJbnRlcmNlcHRvcn0gZnJvbSAnLi9ncnBjL3JldHJ5LWludGVyY2VwdG9yJztcbmltcG9ydCB7Q2FjaGVTZXJ2aWNlRXJyb3JNYXBwZXJ9IGZyb20gJy4uL2Vycm9ycy9jYWNoZS1zZXJ2aWNlLWVycm9yLW1hcHBlcic7XG5pbXBvcnQge1xuICBDaGFubmVsQ3JlZGVudGlhbHMsXG4gIEludGVyY2VwdG9yLFxuICBNZXRhZGF0YSxcbiAgU2VydmljZUVycm9yLFxufSBmcm9tICdAZ3JwYy9ncnBjLWpzJztcbmltcG9ydCB7XG4gIEF1dG9tYXRpY0RlY29tcHJlc3Npb24sXG4gIENhY2hlRGVjcmVhc2VUdGwsXG4gIENhY2hlRGVsZXRlLFxuICBDYWNoZURpY3Rpb25hcnlGZXRjaCxcbiAgQ2FjaGVEaWN0aW9uYXJ5R2V0RmllbGQsXG4gIENhY2hlRGljdGlvbmFyeUdldEZpZWxkcyxcbiAgQ2FjaGVEaWN0aW9uYXJ5SW5jcmVtZW50LFxuICBDYWNoZURpY3Rpb25hcnlMZW5ndGgsXG4gIENhY2hlRGljdGlvbmFyeVJlbW92ZUZpZWxkLFxuICBDYWNoZURpY3Rpb25hcnlSZW1vdmVGaWVsZHMsXG4gIENhY2hlRGljdGlvbmFyeVNldEZpZWxkLFxuICBDYWNoZURpY3Rpb25hcnlTZXRGaWVsZHMsXG4gIENhY2hlR2V0LFxuICBDYWNoZUdldEJhdGNoLFxuICBDYWNoZUluY3JlYXNlVHRsLFxuICBDYWNoZUluY3JlbWVudCxcbiAgQ2FjaGVJdGVtR2V0VHRsLFxuICBDYWNoZUl0ZW1HZXRUeXBlLFxuICBDYWNoZUtleUV4aXN0cyxcbiAgQ2FjaGVLZXlzRXhpc3QsXG4gIENhY2hlTGlzdENvbmNhdGVuYXRlQmFjayxcbiAgQ2FjaGVMaXN0Q29uY2F0ZW5hdGVGcm9udCxcbiAgQ2FjaGVMaXN0RmV0Y2gsXG4gIENhY2hlTGlzdExlbmd0aCxcbiAgQ2FjaGVMaXN0UG9wQmFjayxcbiAgQ2FjaGVMaXN0UG9wRnJvbnQsXG4gIENhY2hlTGlzdFB1c2hCYWNrLFxuICBDYWNoZUxpc3RQdXNoRnJvbnQsXG4gIENhY2hlTGlzdFJlbW92ZVZhbHVlLFxuICBDYWNoZUxpc3RSZXRhaW4sXG4gIENhY2hlU2V0LFxuICBDYWNoZVNldEFkZEVsZW1lbnRzLFxuICBDYWNoZVNldEJhdGNoLFxuICBDYWNoZVNldENvbnRhaW5zRWxlbWVudCxcbiAgQ2FjaGVTZXRDb250YWluc0VsZW1lbnRzLFxuICBDYWNoZVNldEZldGNoLFxuICBDYWNoZVNldElmQWJzZW50LFxuICBDYWNoZVNldElmQWJzZW50T3JFcXVhbCxcbiAgQ2FjaGVTZXRJZkVxdWFsLFxuICBDYWNoZVNldElmTm90RXF1YWwsXG4gIENhY2hlU2V0SWZOb3RFeGlzdHMsXG4gIENhY2hlU2V0SWZQcmVzZW50LFxuICBDYWNoZVNldElmUHJlc2VudEFuZE5vdEVxdWFsLFxuICBDYWNoZVNldFJlbW92ZUVsZW1lbnRzLFxuICBDYWNoZVNldFNhbXBsZSxcbiAgQ2FjaGVTb3J0ZWRTZXRGZXRjaCxcbiAgQ2FjaGVTb3J0ZWRTZXRHZXRSYW5rLFxuICBDYWNoZVNvcnRlZFNldEdldFNjb3JlLFxuICBDYWNoZVNvcnRlZFNldEdldFNjb3JlcyxcbiAgQ2FjaGVTb3J0ZWRTZXRJbmNyZW1lbnRTY29yZSxcbiAgQ2FjaGVTb3J0ZWRTZXRMZW5ndGgsXG4gIENhY2hlU29ydGVkU2V0TGVuZ3RoQnlTY29yZSxcbiAgQ2FjaGVTb3J0ZWRTZXRQdXRFbGVtZW50LFxuICBDYWNoZVNvcnRlZFNldFB1dEVsZW1lbnRzLFxuICBDYWNoZVNvcnRlZFNldFJlbW92ZUVsZW1lbnQsXG4gIENhY2hlU29ydGVkU2V0UmVtb3ZlRWxlbWVudHMsXG4gIENhY2hlVXBkYXRlVHRsLFxuICBDb2xsZWN0aW9uVHRsLFxuICBDb21wcmVzc2lvbkxldmVsLFxuICBDcmVkZW50aWFsUHJvdmlkZXIsXG4gIElDb21wcmVzc2lvbixcbiAgSW52YWxpZEFyZ3VtZW50RXJyb3IsXG4gIEl0ZW1UeXBlLFxuICBNb21lbnRvTG9nZ2VyLFxuICBNb21lbnRvTG9nZ2VyRmFjdG9yeSxcbiAgUmVhZENvbmNlcm4sXG4gIFNvcnRlZFNldE9yZGVyLFxuICBVbmtub3duRXJyb3IsXG59IGZyb20gJy4uJztcbmltcG9ydCB7dmVyc2lvbn0gZnJvbSAnLi4vLi4vcGFja2FnZS5qc29uJztcbmltcG9ydCB7SWRsZUdycGNDbGllbnRXcmFwcGVyfSBmcm9tICcuL2dycGMvaWRsZS1ncnBjLWNsaWVudC13cmFwcGVyJztcbmltcG9ydCB7R3JwY0NsaWVudFdyYXBwZXJ9IGZyb20gJy4vZ3JwYy9ncnBjLWNsaWVudC13cmFwcGVyJztcbmltcG9ydCB7XG4gIE1pZGRsZXdhcmUsXG4gIE1pZGRsZXdhcmVSZXF1ZXN0SGFuZGxlckNvbnRleHQsXG59IGZyb20gJy4uL2NvbmZpZy9taWRkbGV3YXJlL21pZGRsZXdhcmUnO1xuaW1wb3J0IHttaWRkbGV3YXJlc0ludGVyY2VwdG9yfSBmcm9tICcuL2dycGMvbWlkZGxld2FyZXMtaW50ZXJjZXB0b3InO1xuaW1wb3J0IHtjYWNoZV9jbGllbnR9IGZyb20gJ0Bnb21vbWVudG8vZ2VuZXJhdGVkLXR5cGVzL2Rpc3QvY2FjaGVjbGllbnQnO1xuaW1wb3J0IHtDb25maWd1cmF0aW9ufSBmcm9tICcuLi9jb25maWcvY29uZmlndXJhdGlvbic7XG5pbXBvcnQge1xuICBTZW1hcGhvcmUsXG4gIHZhbGlkYXRlQ2FjaGVOYW1lLFxuICB2YWxpZGF0ZURpY3Rpb25hcnlOYW1lLFxuICB2YWxpZGF0ZUxpc3ROYW1lLFxuICB2YWxpZGF0ZUxpc3RTbGljZVN0YXJ0RW5kLFxuICB2YWxpZGF0ZVNldE5hbWUsXG4gIHZhbGlkYXRlU2V0UG9wQ291bnQsXG4gIHZhbGlkYXRlU2V0U2FtcGxlTGltaXQsXG4gIHZhbGlkYXRlU29ydGVkU2V0Q291bnQsXG4gIHZhbGlkYXRlU29ydGVkU2V0TmFtZSxcbiAgdmFsaWRhdGVTb3J0ZWRTZXRPZmZzZXQsXG4gIHZhbGlkYXRlU29ydGVkU2V0UmFua3MsXG4gIHZhbGlkYXRlU29ydGVkU2V0U2NvcmVzLFxuICB2YWxpZGF0ZVR0bFNlY29uZHMsXG4gIHZhbGlkYXRlVmFsaWRGb3JTZWNvbmRzLFxufSBmcm9tICdAZ29tb21lbnRvL3Nkay1jb3JlL2Rpc3Qvc3JjL2ludGVybmFsL3V0aWxzJztcbmltcG9ydCB7XG4gIF9EaWN0aW9uYXJ5R2V0UmVzcG9uc2VQYXJ0LFxuICBfRUNhY2hlUmVzdWx0LFxuICBfU29ydGVkU2V0R2V0U2NvcmVSZXNwb25zZVBhcnQsXG59IGZyb20gJ0Bnb21vbWVudG8vc2RrLWNvcmUvZGlzdC9zcmMvbWVzc2FnZXMvcmVzcG9uc2VzL2dycGMtcmVzcG9uc2UtdHlwZXMnO1xuaW1wb3J0IHtJRGF0YUNsaWVudH0gZnJvbSAnQGdvbW9tZW50by9zZGstY29yZS9kaXN0L3NyYy9pbnRlcm5hbC9jbGllbnRzJztcbmltcG9ydCB7Q29ubmVjdGl2aXR5U3RhdGV9IGZyb20gJ0BncnBjL2dycGMtanMvYnVpbGQvc3JjL2Nvbm5lY3Rpdml0eS1zdGF0ZSc7XG5pbXBvcnQge0NhY2hlQ2xpZW50QWxsUHJvcHN9IGZyb20gJy4vY2FjaGUtY2xpZW50LWFsbC1wcm9wcyc7XG5pbXBvcnQge2dycGNDaGFubmVsT3B0aW9uc0Zyb21HcnBjQ29uZmlnfSBmcm9tICcuL2dycGMvZ3JwYy1jaGFubmVsLW9wdGlvbnMnO1xuaW1wb3J0IHtDb25uZWN0aW9uRXJyb3J9IGZyb20gJ0Bnb21vbWVudG8vc2RrLWNvcmUvZGlzdC9zcmMvZXJyb3JzJztcbmltcG9ydCB7Y29tbW9ufSBmcm9tICdAZ29tb21lbnRvL2dlbmVyYXRlZC10eXBlcy9kaXN0L2NvbW1vbic7XG5pbXBvcnQge1xuICBHZXRCYXRjaENhbGxPcHRpb25zLFxuICBHZXRDYWxsT3B0aW9ucyxcbiAgc2Vjb25kc1RvTWlsbGlzZWNvbmRzLFxuICBTZXRCYXRjaENhbGxPcHRpb25zLFxuICBTZXRCYXRjaEl0ZW0sXG4gIFNldENhbGxPcHRpb25zLFxuICBTZXRJZkFic2VudENhbGxPcHRpb25zLFxufSBmcm9tICdAZ29tb21lbnRvL3Nkay1jb3JlL2Rpc3Qvc3JjL3V0aWxzJztcbmltcG9ydCB7Q29tcHJlc3Npb25FcnJvcn0gZnJvbSAnLi4vZXJyb3JzL2NvbXByZXNzaW9uLWVycm9yJztcbmltcG9ydCB7Q2FjaGVTZXRMZW5ndGgsIENhY2hlU2V0UG9wfSBmcm9tICdAZ29tb21lbnRvL3Nkay1jb3JlJztcbmltcG9ydCBncnBjQ2FjaGUgPSBjYWNoZS5jYWNoZV9jbGllbnQ7XG5pbXBvcnQgRUNhY2hlUmVzdWx0ID0gY2FjaGVfY2xpZW50LkVDYWNoZVJlc3VsdDtcbmltcG9ydCBfSXRlbUdldFR5cGVSZXNwb25zZSA9IGNhY2hlX2NsaWVudC5fSXRlbUdldFR5cGVSZXNwb25zZTtcbmltcG9ydCBfVW5ib3VuZGVkID0gY29tbW9uLl9VbmJvdW5kZWQ7XG5pbXBvcnQgQWJzZW50ID0gY29tbW9uLkFic2VudDtcbmltcG9ydCBQcmVzZW50ID0gY29tbW9uLlByZXNlbnQ7XG5pbXBvcnQgRXF1YWwgPSBjb21tb24uRXF1YWw7XG5pbXBvcnQgTm90RXF1YWwgPSBjb21tb24uTm90RXF1YWw7XG5pbXBvcnQgUHJlc2VudEFuZE5vdEVxdWFsID0gY29tbW9uLlByZXNlbnRBbmROb3RFcXVhbDtcbmltcG9ydCBBYnNlbnRPckVxdWFsID0gY29tbW9uLkFic2VudE9yRXF1YWw7XG5cbmV4cG9ydCBjb25zdCBDT05ORUNUSU9OX0lEX0tFWSA9IFN5bWJvbCgnY29ubmVjdGlvbklEJyk7XG5cbmludGVyZmFjZSBDb21wcmVzc2lvbkRldGFpbHMge1xuICB2YWx1ZUNvbXByZXNzb3I6IElDb21wcmVzc2lvbjtcbiAgY29tcHJlc3Npb25MZXZlbDogQ29tcHJlc3Npb25MZXZlbDtcbiAgYXV0b0RlY29tcHJlc3NFbmFibGVkOiBib29sZWFuO1xufVxuXG5leHBvcnQgY2xhc3MgQ2FjaGVEYXRhQ2xpZW50IGltcGxlbWVudHMgSURhdGFDbGllbnQge1xuICBwcml2YXRlIHJlYWRvbmx5IGNsaWVudFdyYXBwZXI6IEdycGNDbGllbnRXcmFwcGVyPGdycGNDYWNoZS5TY3NDbGllbnQ+O1xuICBwcml2YXRlIHJlYWRvbmx5IHRleHRFbmNvZGVyOiBUZXh0RW5jb2RlcjtcbiAgcHJpdmF0ZSByZWFkb25seSBjb25maWd1cmF0aW9uOiBDb25maWd1cmF0aW9uO1xuICBwcml2YXRlIHJlYWRvbmx5IGNyZWRlbnRpYWxQcm92aWRlcjogQ3JlZGVudGlhbFByb3ZpZGVyO1xuICBwcml2YXRlIHJlYWRvbmx5IGRlZmF1bHRUdGxTZWNvbmRzOiBudW1iZXI7XG4gIHByaXZhdGUgcmVhZG9ubHkgcmVxdWVzdFRpbWVvdXRNczogbnVtYmVyO1xuICBwcml2YXRlIHN0YXRpYyByZWFkb25seSBERUZBVUxUX1JFUVVFU1RfVElNRU9VVF9NUzogbnVtYmVyID1cbiAgICBzZWNvbmRzVG9NaWxsaXNlY29uZHMoNSk7XG4gIHByaXZhdGUgcmVhZG9ubHkgbG9nZ2VyOiBNb21lbnRvTG9nZ2VyO1xuICBwcml2YXRlIHJlYWRvbmx5IGNhY2hlU2VydmljZUVycm9yTWFwcGVyOiBDYWNoZVNlcnZpY2VFcnJvck1hcHBlcjtcbiAgcHJpdmF0ZSByZWFkb25seSBpbnRlcmNlcHRvcnM6IEludGVyY2VwdG9yW107XG4gIHByaXZhdGUgcmVhZG9ubHkgc3RyZWFtaW5nSW50ZXJjZXB0b3JzOiBJbnRlcmNlcHRvcltdO1xuICBwcml2YXRlIHJlYWRvbmx5IGNvbXByZXNzaW9uRGV0YWlscz86IENvbXByZXNzaW9uRGV0YWlscztcbiAgcHJpdmF0ZSByZWFkb25seSByZXF1ZXN0Q29uY3VycmVuY3lTZW1hcGhvcmU6IFNlbWFwaG9yZSB8IHVuZGVmaW5lZDtcblxuICAvKipcbiAgICogQHBhcmFtIHtDYWNoZUNsaWVudFByb3BzfSBwcm9wc1xuICAgKiBAcGFyYW0gZGF0YUNsaWVudElEXG4gICAqIEBwYXJhbSBzZW1hcGhvcmVcbiAgICovXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByb3BzOiBDYWNoZUNsaWVudEFsbFByb3BzLFxuICAgIGRhdGFDbGllbnRJRDogc3RyaW5nLFxuICAgIHNlbWFwaG9yZTogU2VtYXBob3JlIHwgdW5kZWZpbmVkXG4gICkge1xuICAgIHRoaXMuY29uZmlndXJhdGlvbiA9IHByb3BzLmNvbmZpZ3VyYXRpb247XG4gICAgdGhpcy5jcmVkZW50aWFsUHJvdmlkZXIgPSBwcm9wcy5jcmVkZW50aWFsUHJvdmlkZXI7XG4gICAgdGhpcy5sb2dnZXIgPSB0aGlzLmNvbmZpZ3VyYXRpb24uZ2V0TG9nZ2VyRmFjdG9yeSgpLmdldExvZ2dlcih0aGlzKTtcbiAgICB0aGlzLmNhY2hlU2VydmljZUVycm9yTWFwcGVyID0gbmV3IENhY2hlU2VydmljZUVycm9yTWFwcGVyKFxuICAgICAgcHJvcHMuY29uZmlndXJhdGlvbi5nZXRUaHJvd09uRXJyb3JzKClcbiAgICApO1xuICAgIGNvbnN0IGNvbXByZXNzaW9uID0gdGhpcy5jb25maWd1cmF0aW9uLmdldENvbXByZXNzaW9uU3RyYXRlZ3koKTtcbiAgICBpZiAoY29tcHJlc3Npb24gIT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhpcy5jb21wcmVzc2lvbkRldGFpbHMgPSB7XG4gICAgICAgIHZhbHVlQ29tcHJlc3NvcjogY29tcHJlc3Npb24uY29tcHJlc3NvckZhY3RvcnksXG4gICAgICAgIGNvbXByZXNzaW9uTGV2ZWw6XG4gICAgICAgICAgY29tcHJlc3Npb24uY29tcHJlc3Npb25MZXZlbCA/PyBDb21wcmVzc2lvbkxldmVsLkJhbGFuY2VkLFxuICAgICAgICBhdXRvRGVjb21wcmVzc0VuYWJsZWQ6XG4gICAgICAgICAgKGNvbXByZXNzaW9uLmF1dG9tYXRpY0RlY29tcHJlc3Npb24gPz9cbiAgICAgICAgICAgIEF1dG9tYXRpY0RlY29tcHJlc3Npb24uRW5hYmxlZCkgPT09IEF1dG9tYXRpY0RlY29tcHJlc3Npb24uRW5hYmxlZCxcbiAgICAgIH07XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuY29tcHJlc3Npb25EZXRhaWxzID0gdW5kZWZpbmVkO1xuICAgIH1cbiAgICB0aGlzLnJlcXVlc3RDb25jdXJyZW5jeVNlbWFwaG9yZSA9IHNlbWFwaG9yZTtcblxuICAgIGNvbnN0IGdycGNDb25maWcgPSB0aGlzLmNvbmZpZ3VyYXRpb25cbiAgICAgIC5nZXRUcmFuc3BvcnRTdHJhdGVneSgpXG4gICAgICAuZ2V0R3JwY0NvbmZpZygpO1xuXG4gICAgdGhpcy5yZXF1ZXN0VGltZW91dE1zID1cbiAgICAgIGdycGNDb25maWcuZ2V0RGVhZGxpbmVNaWxsaXMoKSB8fFxuICAgICAgQ2FjaGVEYXRhQ2xpZW50LkRFRkFVTFRfUkVRVUVTVF9USU1FT1VUX01TO1xuICAgIHRoaXMudmFsaWRhdGVSZXF1ZXN0VGltZW91dCh0aGlzLnJlcXVlc3RUaW1lb3V0TXMpO1xuICAgIHRoaXMubG9nZ2VyLmRlYnVnKFxuICAgICAgYENyZWF0aW5nIGNhY2hlIGNsaWVudCB1c2luZyBlbmRwb2ludDogJyR7dGhpcy5jcmVkZW50aWFsUHJvdmlkZXIuZ2V0Q2FjaGVFbmRwb2ludCgpfSdgXG4gICAgKTtcblxuICAgIGNvbnN0IGNoYW5uZWxPcHRpb25zID0gZ3JwY0NoYW5uZWxPcHRpb25zRnJvbUdycGNDb25maWcoZ3JwY0NvbmZpZyk7XG5cbiAgICB0aGlzLmNsaWVudFdyYXBwZXIgPSBuZXcgSWRsZUdycGNDbGllbnRXcmFwcGVyKHtcbiAgICAgIGNsaWVudEZhY3RvcnlGbjogKCkgPT4ge1xuICAgICAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhgQ29uc3RydWN0aW5nIGNoYW5uZWwgZm9yIGNsaWVudElEICR7ZGF0YUNsaWVudElEfWApO1xuICAgICAgICByZXR1cm4gbmV3IGdycGNDYWNoZS5TY3NDbGllbnQoXG4gICAgICAgICAgdGhpcy5jcmVkZW50aWFsUHJvdmlkZXIuZ2V0Q2FjaGVFbmRwb2ludCgpLFxuICAgICAgICAgIHRoaXMuY3JlZGVudGlhbFByb3ZpZGVyLmlzQ2FjaGVFbmRwb2ludFNlY3VyZSgpXG4gICAgICAgICAgICA/IENoYW5uZWxDcmVkZW50aWFscy5jcmVhdGVTc2woKVxuICAgICAgICAgICAgOiBDaGFubmVsQ3JlZGVudGlhbHMuY3JlYXRlSW5zZWN1cmUoKSxcbiAgICAgICAgICBjaGFubmVsT3B0aW9uc1xuICAgICAgICApO1xuICAgICAgfSxcbiAgICAgIGxvZ2dlckZhY3Rvcnk6IHRoaXMuY29uZmlndXJhdGlvbi5nZXRMb2dnZXJGYWN0b3J5KCksXG4gICAgICBtYXhJZGxlTWlsbGlzOiB0aGlzLmNvbmZpZ3VyYXRpb25cbiAgICAgICAgLmdldFRyYW5zcG9ydFN0cmF0ZWd5KClcbiAgICAgICAgLmdldE1heElkbGVNaWxsaXMoKSxcbiAgICAgIG1heENsaWVudEFnZU1pbGxpczogdGhpcy5jb25maWd1cmF0aW9uXG4gICAgICAgIC5nZXRUcmFuc3BvcnRTdHJhdGVneSgpXG4gICAgICAgIC5nZXRNYXhDbGllbnRBZ2VNaWxsaXMoKSxcbiAgICB9KTtcblxuICAgIHRoaXMudGV4dEVuY29kZXIgPSBuZXcgVGV4dEVuY29kZXIoKTtcbiAgICB0aGlzLmRlZmF1bHRUdGxTZWNvbmRzID0gcHJvcHMuZGVmYXVsdFR0bFNlY29uZHM7XG5cbiAgICAvLyB0aGlzIGNvbnRleHQgb2JqZWN0IGlzIGN1cnJlbnRseSBpbnRlcm5hbCBvbmx5IGJ1dCBjYW4gYmUgZXh0ZW5kZWQgaW4gdGhlIENvbmZpZ3VyYXRpb24gb2JqZWN0IGlzIHdlIHdhbnRzIGNsaWVudHNcbiAgICAvLyB0byBiZSBhYmxlIHRvIHNldCBpdC5cbiAgICBjb25zdCBjb250ZXh0OiBNaWRkbGV3YXJlUmVxdWVzdEhhbmRsZXJDb250ZXh0ID0ge307XG4gICAgY29udGV4dFtDT05ORUNUSU9OX0lEX0tFWV0gPSBkYXRhQ2xpZW50SUQ7XG5cbiAgICBjb25zdCBoZWFkZXJzID0gW1xuICAgICAgbmV3IEhlYWRlcignQXV0aG9yaXphdGlvbicsIHRoaXMuY3JlZGVudGlhbFByb3ZpZGVyLmdldEF1dGhUb2tlbigpKSxcbiAgICAgIG5ldyBIZWFkZXIoJ2FnZW50JywgYG5vZGVqczpjYWNoZToke3ZlcnNpb259YCksXG4gICAgICBuZXcgSGVhZGVyKCdydW50aW1lLXZlcnNpb24nLCBgbm9kZWpzOiR7cHJvY2Vzcy52ZXJzaW9ucy5ub2RlfWApLFxuICAgIF07XG5cbiAgICAvLyBOb3Qgc2VuZGluZyBhIGhlYWQgY29uY2VybiBoZWFkZXIgaXMgdHJlYXRlZCB0aGUgc2FtZSBhcyBzZW5kaW5nIGEgQkFMQU5DRUQgcmVhZCBjb25jZXJuIGhlYWRlclxuICAgIGNvbnN0IHJlYWRDb25jZXJuID0gdGhpcy5jb25maWd1cmF0aW9uLmdldFJlYWRDb25jZXJuKCk7XG4gICAgaWYgKHJlYWRDb25jZXJuICE9PSBSZWFkQ29uY2Vybi5CQUxBTkNFRCkge1xuICAgICAgaGVhZGVycy5wdXNoKG5ldyBIZWFkZXIoJ3JlYWQtY29uY2VybicsIHJlYWRDb25jZXJuKSk7XG4gICAgfVxuXG4gICAgdGhpcy5pbnRlcmNlcHRvcnMgPSB0aGlzLmluaXRpYWxpemVJbnRlcmNlcHRvcnMoXG4gICAgICBoZWFkZXJzLFxuICAgICAgdGhpcy5jb25maWd1cmF0aW9uLmdldExvZ2dlckZhY3RvcnkoKSxcbiAgICAgIHRoaXMuY29uZmlndXJhdGlvbi5nZXRNaWRkbGV3YXJlcygpLFxuICAgICAgY29udGV4dFxuICAgICk7XG4gICAgdGhpcy5zdHJlYW1pbmdJbnRlcmNlcHRvcnMgPSB0aGlzLmluaXRpYWxpemVTdHJlYW1pbmdJbnRlcmNlcHRvcnMoaGVhZGVycyk7XG4gIH1cblxuICBjbG9zZSgpIHtcbiAgICB0aGlzLmxvZ2dlci5kZWJ1ZygnQ2xvc2luZyBjYWNoZSBkYXRhIGNsaWVudCcpO1xuICAgIHRoaXMuY2xpZW50V3JhcHBlci5nZXRDbGllbnQoKS5jbG9zZSgpO1xuICB9XG5cbiAgcHVibGljIGNvbm5lY3QodGltZW91dFNlY29uZHMgPSAxMCk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRoaXMubG9nZ2VyLmRlYnVnKCdBdHRlbXB0aW5nIHRvIGVhZ2VybHkgY29ubmVjdCB0byBjaGFubmVsJyk7XG4gICAgY29uc3QgZGVhZGxpbmUgPSBuZXcgRGF0ZSgpO1xuICAgIGRlYWRsaW5lLnNldFNlY29uZHMoZGVhZGxpbmUuZ2V0U2Vjb25kcygpICsgdGltZW91dFNlY29uZHMpO1xuXG4gICAgcmV0dXJuIHRoaXMuY29ubmVjdFdpdGhpbkRlYWRsaW5lKGRlYWRsaW5lKTtcbiAgfVxuXG4gIHByaXZhdGUgY29ubmVjdGlvblN0YXRlVG9TdHJpbmcoc3RhdGU6IENvbm5lY3Rpdml0eVN0YXRlKTogc3RyaW5nIHtcbiAgICBzd2l0Y2ggKHN0YXRlKSB7XG4gICAgICBjYXNlIENvbm5lY3Rpdml0eVN0YXRlLklETEU6XG4gICAgICAgIHJldHVybiAnSURMRSc7XG4gICAgICBjYXNlIENvbm5lY3Rpdml0eVN0YXRlLkNPTk5FQ1RJTkc6XG4gICAgICAgIHJldHVybiAnQ09OTkVDVElORyc7XG4gICAgICBjYXNlIENvbm5lY3Rpdml0eVN0YXRlLlJFQURZOlxuICAgICAgICByZXR1cm4gJ1JFQURZJztcbiAgICAgIGNhc2UgQ29ubmVjdGl2aXR5U3RhdGUuVFJBTlNJRU5UX0ZBSUxVUkU6XG4gICAgICAgIHJldHVybiAnVFJBTlNJRU5UX0ZBSUxVUkUnO1xuICAgICAgY2FzZSBDb25uZWN0aXZpdHlTdGF0ZS5TSFVURE9XTjpcbiAgICAgICAgcmV0dXJuICdTSFVURE9XTic7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBjb25uZWN0V2l0aGluRGVhZGxpbmUoZGVhZGxpbmU6IERhdGUpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgLy8gR2V0IHRoZSBjdXJyZW50IHN0YXRlIGFuZCBpbml0aWF0ZSBhIGNvbm5lY3Rpb25cbiAgICAgIGNvbnN0IGN1cnJlbnRTdGF0ZSA9IHRoaXMuY2xpZW50V3JhcHBlclxuICAgICAgICAuZ2V0Q2xpZW50KClcbiAgICAgICAgLmdldENoYW5uZWwoKVxuICAgICAgICAuZ2V0Q29ubmVjdGl2aXR5U3RhdGUodHJ1ZSk7XG5cbiAgICAgIHRoaXMubG9nZ2VyLmRlYnVnKGBDbGllbnQgY29ubmVjdGl2aXR5IHN0YXRlOiAke2N1cnJlbnRTdGF0ZX1gKTtcblxuICAgICAgaWYgKGN1cnJlbnRTdGF0ZSA9PT0gQ29ubmVjdGl2aXR5U3RhdGUuUkVBRFkpIHtcbiAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IG5vdyA9IG5ldyBEYXRlKCk7XG5cbiAgICAgIGlmIChub3cgPj0gZGVhZGxpbmUpIHtcbiAgICAgICAgY29uc3QgZXJyb3JNZXNzYWdlID0gJ1VuYWJsZSB0byBjb25uZWN0IHRvIE1vbWVudG86IGRlYWRsaW5lIGV4Y2VlZGVkLic7XG4gICAgICAgIHRoaXMubG9nZ2VyLmVycm9yKGVycm9yTWVzc2FnZSk7XG4gICAgICAgIHJlamVjdChuZXcgQ29ubmVjdGlvbkVycm9yKGVycm9yTWVzc2FnZSkpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHRoaXMuY2xpZW50V3JhcHBlclxuICAgICAgICAuZ2V0Q2xpZW50KClcbiAgICAgICAgLmdldENoYW5uZWwoKVxuICAgICAgICAud2F0Y2hDb25uZWN0aXZpdHlTdGF0ZShjdXJyZW50U3RhdGUsIGRlYWRsaW5lLCAoZXJyb3I/OiBFcnJvcikgPT4ge1xuICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgY29uc3QgZXJyb3JNZXNzYWdlID0gYFVuYWJsZSB0byBlYWdlcmx5IGNvbm5lY3QgdG8gTW9tZW50by4gUGxlYXNlIGNvbnRhY3QgTW9tZW50byBpZiB0aGlzIHBlcnNpc3RzLiBjdXJyZW50U3RhdGU6ICR7dGhpcy5jb25uZWN0aW9uU3RhdGVUb1N0cmluZyhcbiAgICAgICAgICAgICAgY3VycmVudFN0YXRlXG4gICAgICAgICAgICApfSwgZXJyb3JOYW1lOiAke2Vycm9yLm5hbWV9IDogZXJyb3JNZXNzYWdlOiAke1xuICAgICAgICAgICAgICBlcnJvci5tZXNzYWdlXG4gICAgICAgICAgICB9LCBlcnJvclN0YWNrOiAke1xuICAgICAgICAgICAgICBlcnJvci5zdGFjayA/IGVycm9yLnN0YWNrIDogJ1N0YWNrIHRyYWNlIHVuZGVmaW5lZCdcbiAgICAgICAgICAgIH1gO1xuICAgICAgICAgICAgdGhpcy5sb2dnZXIuZXJyb3IoZXJyb3JNZXNzYWdlKTtcbiAgICAgICAgICAgIHJlamVjdChuZXcgQ29ubmVjdGlvbkVycm9yKGVycm9yTWVzc2FnZSkpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGNvbnN0IG5ld1N0YXRlID0gdGhpcy5jbGllbnRXcmFwcGVyXG4gICAgICAgICAgICAuZ2V0Q2xpZW50KClcbiAgICAgICAgICAgIC5nZXRDaGFubmVsKClcbiAgICAgICAgICAgIC5nZXRDb25uZWN0aXZpdHlTdGF0ZShmYWxzZSk7XG5cbiAgICAgICAgICBpZiAobmV3U3RhdGUgPT09IENvbm5lY3Rpdml0eVN0YXRlLlJFQURZKSB7XG4gICAgICAgICAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhcbiAgICAgICAgICAgICAgYENvbm5lY3RlZCEgQ3VycmVudCBzdGF0ZTogJHt0aGlzLmNvbm5lY3Rpb25TdGF0ZVRvU3RyaW5nKFxuICAgICAgICAgICAgICAgIG5ld1N0YXRlXG4gICAgICAgICAgICAgICl9YFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICB9IGVsc2UgaWYgKG5ld1N0YXRlID09PSBDb25uZWN0aXZpdHlTdGF0ZS5DT05ORUNUSU5HKSB7XG4gICAgICAgICAgICAvLyBUaGUgY29ubmVjdGlvbiBnb2VzIHRocm91Z2ggdGhlIENPTk5FQ1RJTkcgc3RhdGUgYmVmb3JlIGJlY29taW5nIFJFQURZLFxuICAgICAgICAgICAgLy8gc28gd2UgbXVzdCB3YXRjaCBpdCB0d2ljZS5cbiAgICAgICAgICAgIHRoaXMubG9nZ2VyLmRlYnVnKFxuICAgICAgICAgICAgICBgQ29ubmVjdGluZyEgQ3VycmVudCBzdGF0ZTogJHt0aGlzLmNvbm5lY3Rpb25TdGF0ZVRvU3RyaW5nKFxuICAgICAgICAgICAgICAgIG5ld1N0YXRlXG4gICAgICAgICAgICAgICl9YFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIHRoaXMuY29ubmVjdFdpdGhpbkRlYWRsaW5lKGRlYWRsaW5lKS50aGVuKHJlc29sdmUpLmNhdGNoKHJlamVjdCk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IGVycm9yTWVzc2FnZSA9IGBVbmFibGUgdG8gY29ubmVjdCB0byBNb21lbnRvOiBVbmV4cGVjdGVkIGNvbm5lY3Rpb24gc3RhdGU6ICR7dGhpcy5jb25uZWN0aW9uU3RhdGVUb1N0cmluZyhcbiAgICAgICAgICAgICAgbmV3U3RhdGVcbiAgICAgICAgICAgICl9Liwgb2xkU3RhdGU6ICR7dGhpcy5jb25uZWN0aW9uU3RhdGVUb1N0cmluZyhjdXJyZW50U3RhdGUpfVxuICAgICAgICAgICAgICBQbGVhc2UgY29udGFjdCBNb21lbnRvIGlmIHRoaXMgcGVyc2lzdHMuYDtcbiAgICAgICAgICAgIHRoaXMubG9nZ2VyLmVycm9yKGVycm9yTWVzc2FnZSk7XG4gICAgICAgICAgICByZWplY3QobmV3IENvbm5lY3Rpb25FcnJvcihlcnJvck1lc3NhZ2UpKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgcHVibGljIGdldEVuZHBvaW50KCk6IHN0cmluZyB7XG4gICAgY29uc3QgZW5kcG9pbnQgPSB0aGlzLmNyZWRlbnRpYWxQcm92aWRlci5nZXRDYWNoZUVuZHBvaW50KCk7XG4gICAgdGhpcy5sb2dnZXIuZGVidWcoYFVzaW5nIGNhY2hlIGVuZHBvaW50OiAke2VuZHBvaW50fWApO1xuICAgIHJldHVybiBlbmRwb2ludDtcbiAgfVxuXG4gIHByaXZhdGUgdmFsaWRhdGVSZXF1ZXN0VGltZW91dCh0aW1lb3V0PzogbnVtYmVyKSB7XG4gICAgdGhpcy5sb2dnZXIuZGVidWcoYFJlcXVlc3QgdGltZW91dCBtczogJHtTdHJpbmcodGltZW91dCl9YCk7XG4gICAgaWYgKHRpbWVvdXQgIT09IHVuZGVmaW5lZCAmJiB0aW1lb3V0IDw9IDApIHtcbiAgICAgIHRocm93IG5ldyBJbnZhbGlkQXJndW1lbnRFcnJvcihcbiAgICAgICAgJ3JlcXVlc3QgdGltZW91dCBtdXN0IGJlIGdyZWF0ZXIgdGhhbiB6ZXJvLidcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBjb252ZXJ0RUNhY2hlUmVzdWx0KHJlc3VsdDogZ3JwY0NhY2hlLkVDYWNoZVJlc3VsdCk6IF9FQ2FjaGVSZXN1bHQge1xuICAgIHN3aXRjaCAocmVzdWx0KSB7XG4gICAgICBjYXNlIGdycGNDYWNoZS5FQ2FjaGVSZXN1bHQuSGl0OlxuICAgICAgICByZXR1cm4gX0VDYWNoZVJlc3VsdC5IaXQ7XG4gICAgICBjYXNlIGdycGNDYWNoZS5FQ2FjaGVSZXN1bHQuSW52YWxpZDpcbiAgICAgICAgcmV0dXJuIF9FQ2FjaGVSZXN1bHQuSW52YWxpZDtcbiAgICAgIGNhc2UgZ3JwY0NhY2hlLkVDYWNoZVJlc3VsdC5NaXNzOlxuICAgICAgICByZXR1cm4gX0VDYWNoZVJlc3VsdC5NaXNzO1xuICAgICAgY2FzZSBncnBjQ2FjaGUuRUNhY2hlUmVzdWx0Lk9rOlxuICAgICAgICByZXR1cm4gX0VDYWNoZVJlc3VsdC5PaztcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGNvbnZlcnRJdGVtVHlwZVJlc3VsdChcbiAgICByZXN1bHQ6IF9JdGVtR2V0VHlwZVJlc3BvbnNlLkl0ZW1UeXBlXG4gICk6IEl0ZW1UeXBlIHtcbiAgICBzd2l0Y2ggKHJlc3VsdCkge1xuICAgICAgY2FzZSBfSXRlbUdldFR5cGVSZXNwb25zZS5JdGVtVHlwZS5TQ0FMQVI6XG4gICAgICAgIHJldHVybiBJdGVtVHlwZS5TQ0FMQVI7XG4gICAgICBjYXNlIF9JdGVtR2V0VHlwZVJlc3BvbnNlLkl0ZW1UeXBlLkxJU1Q6XG4gICAgICAgIHJldHVybiBJdGVtVHlwZS5MSVNUO1xuICAgICAgY2FzZSBfSXRlbUdldFR5cGVSZXNwb25zZS5JdGVtVHlwZS5ESUNUSU9OQVJZOlxuICAgICAgICByZXR1cm4gSXRlbVR5cGUuRElDVElPTkFSWTtcbiAgICAgIGNhc2UgX0l0ZW1HZXRUeXBlUmVzcG9uc2UuSXRlbVR5cGUuU0VUOlxuICAgICAgICByZXR1cm4gSXRlbVR5cGUuU0VUO1xuICAgICAgY2FzZSBfSXRlbUdldFR5cGVSZXNwb25zZS5JdGVtVHlwZS5TT1JURURfU0VUOlxuICAgICAgICByZXR1cm4gSXRlbVR5cGUuU09SVEVEX1NFVDtcbiAgICB9XG4gIH1cblxuICAvLyBJZiBtYXhDb25jdXJyZW50UmVxdWVzdHMgaXMgc2V0LCB1c2UgdGhlIHNlbWFwaG9yZSB0byBsaW1pdCB0aGUgbnVtYmVyIG9mIGNvbmN1cnJlbnQgcmVxdWVzdHMuXG4gIC8vIE90aGVyd2lzZSwgZXhlY3V0ZSB0aGUgY2FjaGUgb3BlcmF0aW9uIHdpdGhvdXQgYW55IHJhdGUgbGltaXRpbmcuXG4gIHByaXZhdGUgYXN5bmMgcmF0ZUxpbWl0ZWQ8VD4oY2FjaGVPcGVyYXRpb246ICgpID0+IFByb21pc2U8VD4pOiBQcm9taXNlPFQ+IHtcbiAgICB0cnkge1xuICAgICAgaWYgKHRoaXMucmVxdWVzdENvbmN1cnJlbmN5U2VtYXBob3JlICE9PSB1bmRlZmluZWQpXG4gICAgICAgIGF3YWl0IHRoaXMucmVxdWVzdENvbmN1cnJlbmN5U2VtYXBob3JlLmFjcXVpcmUoKTtcblxuICAgICAgcmV0dXJuIGF3YWl0IGNhY2hlT3BlcmF0aW9uKCk7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIGlmICh0aGlzLnJlcXVlc3RDb25jdXJyZW5jeVNlbWFwaG9yZSAhPT0gdW5kZWZpbmVkKVxuICAgICAgICB0aGlzLnJlcXVlc3RDb25jdXJyZW5jeVNlbWFwaG9yZS5yZWxlYXNlKCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIFRUTCBpbiBtaWxsaXNlY29uZHMgZm9yIGEgY29sbGVjdGlvbi5cbiAgICogSWYgdGhlIHByb3ZpZGVkIFRUTCBpcyBub3Qgc2V0LCBpdCBkZWZhdWx0cyB0byB0aGUgaW5zdGFuY2UncyBkZWZhdWx0IFRUTC5cbiAgICogQHBhcmFtIHR0bCAtIFRoZSBDb2xsZWN0aW9uVHR0bCBvYmplY3QgY29udGFpbmluZyB0aGUgVFRMIHZhbHVlLlxuICAgKiBAcmV0dXJucyBUaGUgVFRMIGluIG1pbGxpc2Vjb25kcy5cbiAgICovXG4gIHByaXZhdGUgY29sbGVjdGlvblR0bE9yRGVmYXVsdE1pbGxpc2Vjb25kcyh0dGw6IENvbGxlY3Rpb25UdGwpOiBudW1iZXIge1xuICAgIHJldHVybiAoXG4gICAgICB0dGwudHRsTWlsbGlzZWNvbmRzKCkgPz8gc2Vjb25kc1RvTWlsbGlzZWNvbmRzKHRoaXMuZGVmYXVsdFR0bFNlY29uZHMpXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBUVEwgaW4gbWlsbGlzZWNvbmRzLlxuICAgKiBJZiB0aGUgcHJvdmlkZWQgVFRMIGlzIG5vdCBzZXQsIGl0IGRlZmF1bHRzIHRvIHRoZSBpbnN0YW5jZSdzIGRlZmF1bHQgVFRMLlxuICAgKiBAcGFyYW0gdHRsXG4gICAqIEByZXR1cm5zIFRoZSBUVEwgaW4gbWlsbGlzZWNvbmRzLlxuICAgKi9cbiAgcHJpdmF0ZSB0dGxPckRlZmF1bHRNaWxsaXNlY29uZHModHRsPzogbnVtYmVyKTogbnVtYmVyIHtcbiAgICBjb25zdCB0dGxTZWNvbmRzID0gdHRsID8/IHRoaXMuZGVmYXVsdFR0bFNlY29uZHM7XG4gICAgcmV0dXJuIHNlY29uZHNUb01pbGxpc2Vjb25kcyh0dGxTZWNvbmRzKTtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBzZXQoXG4gICAgY2FjaGVOYW1lOiBzdHJpbmcsXG4gICAga2V5OiBzdHJpbmcgfCBVaW50OEFycmF5LFxuICAgIHZhbHVlOiBzdHJpbmcgfCBVaW50OEFycmF5LFxuICAgIG9wdGlvbnM/OiBTZXRDYWxsT3B0aW9uc1xuICApOiBQcm9taXNlPENhY2hlU2V0LlJlc3BvbnNlPiB7XG4gICAgdHJ5IHtcbiAgICAgIHZhbGlkYXRlQ2FjaGVOYW1lKGNhY2hlTmFtZSk7XG4gICAgICBpZiAob3B0aW9ucz8udHRsICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdmFsaWRhdGVUdGxTZWNvbmRzKG9wdGlvbnMudHRsKTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIHJldHVybiB0aGlzLmNhY2hlU2VydmljZUVycm9yTWFwcGVyLnJldHVybk9yVGhyb3dFcnJvcihcbiAgICAgICAgZXJyIGFzIEVycm9yLFxuICAgICAgICBlcnIgPT4gbmV3IENhY2hlU2V0LkVycm9yKGVycilcbiAgICAgICk7XG4gICAgfVxuXG4gICAgY29uc3QgdHRsVG9Vc2UgPSBvcHRpb25zPy50dGwgfHwgdGhpcy5kZWZhdWx0VHRsU2Vjb25kcztcbiAgICBjb25zdCBlbmNvZGVkS2V5ID0gdGhpcy5jb252ZXJ0KGtleSk7XG4gICAgbGV0IGVuY29kZWRWYWx1ZSA9IHRoaXMuY29udmVydCh2YWx1ZSk7XG4gICAgaWYgKG9wdGlvbnM/LmNvbXByZXNzKSB7XG4gICAgICB0aGlzLmxvZ2dlci50cmFjZShcbiAgICAgICAgJ0NhY2hlQ2xpZW50LnNldDsgY29tcHJlc3Npb24gZW5hYmxlZCwgY2FsbGluZyB2YWx1ZSBjb21wcmVzc29yJ1xuICAgICAgKTtcbiAgICAgIGlmICh0aGlzLmNvbXByZXNzaW9uRGV0YWlscyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNhY2hlU2VydmljZUVycm9yTWFwcGVyLnJldHVybk9yVGhyb3dFcnJvcihcbiAgICAgICAgICBuZXcgQ29tcHJlc3Npb25FcnJvcignQ2FjaGVDbGllbnQuc2V0JywgJ2NvbXByZXNzJyksXG4gICAgICAgICAgZXJyID0+IG5ldyBDYWNoZVNldC5FcnJvcihlcnIpXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICBlbmNvZGVkVmFsdWUgPSBhd2FpdCB0aGlzLmNvbXByZXNzaW9uRGV0YWlscy52YWx1ZUNvbXByZXNzb3IuY29tcHJlc3MoXG4gICAgICAgIHRoaXMuY29tcHJlc3Npb25EZXRhaWxzLmNvbXByZXNzaW9uTGV2ZWwsXG4gICAgICAgIGVuY29kZWRWYWx1ZVxuICAgICAgKTtcbiAgICB9XG5cbiAgICByZXR1cm4gYXdhaXQgdGhpcy5yYXRlTGltaXRlZChhc3luYyAoKSA9PiB7XG4gICAgICByZXR1cm4gYXdhaXQgdGhpcy5zZW5kU2V0KGNhY2hlTmFtZSwgZW5jb2RlZEtleSwgZW5jb2RlZFZhbHVlLCB0dGxUb1VzZSk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHNlbmRTZXQoXG4gICAgY2FjaGVOYW1lOiBzdHJpbmcsXG4gICAga2V5OiBVaW50OEFycmF5LFxuICAgIHZhbHVlOiBVaW50OEFycmF5LFxuICAgIHR0bDogbnVtYmVyXG4gICk6IFByb21pc2U8Q2FjaGVTZXQuUmVzcG9uc2U+IHtcbiAgICBjb25zdCByZXF1ZXN0ID0gbmV3IGdycGNDYWNoZS5fU2V0UmVxdWVzdCh7XG4gICAgICBjYWNoZV9ib2R5OiB2YWx1ZSxcbiAgICAgIGNhY2hlX2tleToga2V5LFxuICAgICAgdHRsX21pbGxpc2Vjb25kczogc2Vjb25kc1RvTWlsbGlzZWNvbmRzKHR0bCksXG4gICAgfSk7XG4gICAgY29uc3QgbWV0YWRhdGEgPSB0aGlzLmNyZWF0ZU1ldGFkYXRhKGNhY2hlTmFtZSk7XG4gICAgcmV0dXJuIGF3YWl0IG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHRoaXMuY2xpZW50V3JhcHBlci5nZXRDbGllbnQoKS5TZXQoXG4gICAgICAgIHJlcXVlc3QsXG4gICAgICAgIG1ldGFkYXRhLFxuICAgICAgICB7XG4gICAgICAgICAgaW50ZXJjZXB0b3JzOiB0aGlzLmludGVyY2VwdG9ycyxcbiAgICAgICAgfSxcbiAgICAgICAgKGVyciwgcmVzcCkgPT4ge1xuICAgICAgICAgIGlmIChyZXNwKSB7XG4gICAgICAgICAgICByZXNvbHZlKG5ldyBDYWNoZVNldC5TdWNjZXNzKCkpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmNhY2hlU2VydmljZUVycm9yTWFwcGVyLnJlc29sdmVPclJlamVjdEVycm9yKHtcbiAgICAgICAgICAgICAgZXJyOiBlcnIsXG4gICAgICAgICAgICAgIGVycm9yUmVzcG9uc2VGYWN0b3J5Rm46IGUgPT4gbmV3IENhY2hlU2V0LkVycm9yKGUpLFxuICAgICAgICAgICAgICByZXNvbHZlRm46IHJlc29sdmUsXG4gICAgICAgICAgICAgIHJlamVjdEZuOiByZWplY3QsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICk7XG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgc2V0RmV0Y2goXG4gICAgY2FjaGVOYW1lOiBzdHJpbmcsXG4gICAgc2V0TmFtZTogc3RyaW5nXG4gICk6IFByb21pc2U8Q2FjaGVTZXRGZXRjaC5SZXNwb25zZT4ge1xuICAgIHRyeSB7XG4gICAgICB2YWxpZGF0ZUNhY2hlTmFtZShjYWNoZU5hbWUpO1xuICAgICAgdmFsaWRhdGVTZXROYW1lKHNldE5hbWUpO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgcmV0dXJuIHRoaXMuY2FjaGVTZXJ2aWNlRXJyb3JNYXBwZXIucmV0dXJuT3JUaHJvd0Vycm9yKFxuICAgICAgICBlcnIgYXMgRXJyb3IsXG4gICAgICAgIGVyciA9PiBuZXcgQ2FjaGVTZXRGZXRjaC5FcnJvcihlcnIpXG4gICAgICApO1xuICAgIH1cblxuICAgIHJldHVybiBhd2FpdCB0aGlzLnJhdGVMaW1pdGVkKGFzeW5jICgpID0+IHtcbiAgICAgIHJldHVybiBhd2FpdCB0aGlzLnNlbmRTZXRGZXRjaChjYWNoZU5hbWUsIHRoaXMuY29udmVydChzZXROYW1lKSk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHNlbmRTZXRGZXRjaChcbiAgICBjYWNoZU5hbWU6IHN0cmluZyxcbiAgICBzZXROYW1lOiBVaW50OEFycmF5XG4gICk6IFByb21pc2U8Q2FjaGVTZXRGZXRjaC5SZXNwb25zZT4ge1xuICAgIGNvbnN0IHJlcXVlc3QgPSBuZXcgZ3JwY0NhY2hlLl9TZXRGZXRjaFJlcXVlc3Qoe1xuICAgICAgc2V0X25hbWU6IHNldE5hbWUsXG4gICAgfSk7XG4gICAgY29uc3QgbWV0YWRhdGEgPSB0aGlzLmNyZWF0ZU1ldGFkYXRhKGNhY2hlTmFtZSk7XG4gICAgcmV0dXJuIGF3YWl0IG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHRoaXMuY2xpZW50V3JhcHBlci5nZXRDbGllbnQoKS5TZXRGZXRjaChcbiAgICAgICAgcmVxdWVzdCxcbiAgICAgICAgbWV0YWRhdGEsXG4gICAgICAgIHtcbiAgICAgICAgICBpbnRlcmNlcHRvcnM6IHRoaXMuaW50ZXJjZXB0b3JzLFxuICAgICAgICB9LFxuICAgICAgICAoZXJyLCByZXNwKSA9PiB7XG4gICAgICAgICAgaWYgKHJlc3A/Lm1pc3NpbmcpIHtcbiAgICAgICAgICAgIHJlc29sdmUobmV3IENhY2hlU2V0RmV0Y2guTWlzcygpKTtcbiAgICAgICAgICB9IGVsc2UgaWYgKHJlc3A/LmZvdW5kKSB7XG4gICAgICAgICAgICByZXNvbHZlKG5ldyBDYWNoZVNldEZldGNoLkhpdChyZXNwLmZvdW5kLmVsZW1lbnRzKSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuY2FjaGVTZXJ2aWNlRXJyb3JNYXBwZXIucmVzb2x2ZU9yUmVqZWN0RXJyb3Ioe1xuICAgICAgICAgICAgICBlcnI6IGVycixcbiAgICAgICAgICAgICAgZXJyb3JSZXNwb25zZUZhY3RvcnlGbjogZSA9PiBuZXcgQ2FjaGVTZXRGZXRjaC5FcnJvcihlKSxcbiAgICAgICAgICAgICAgcmVzb2x2ZUZuOiByZXNvbHZlLFxuICAgICAgICAgICAgICByZWplY3RGbjogcmVqZWN0LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICApO1xuICAgIH0pO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIHNldEFkZEVsZW1lbnRzKFxuICAgIGNhY2hlTmFtZTogc3RyaW5nLFxuICAgIHNldE5hbWU6IHN0cmluZyxcbiAgICBlbGVtZW50czogc3RyaW5nW10gfCBVaW50OEFycmF5W10sXG4gICAgdHRsOiBDb2xsZWN0aW9uVHRsID0gQ29sbGVjdGlvblR0bC5mcm9tQ2FjaGVUdGwoKVxuICApOiBQcm9taXNlPENhY2hlU2V0QWRkRWxlbWVudHMuUmVzcG9uc2U+IHtcbiAgICB0cnkge1xuICAgICAgdmFsaWRhdGVDYWNoZU5hbWUoY2FjaGVOYW1lKTtcbiAgICAgIHZhbGlkYXRlU2V0TmFtZShzZXROYW1lKTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIHJldHVybiB0aGlzLmNhY2hlU2VydmljZUVycm9yTWFwcGVyLnJldHVybk9yVGhyb3dFcnJvcihcbiAgICAgICAgZXJyIGFzIEVycm9yLFxuICAgICAgICBlcnIgPT4gbmV3IENhY2hlU2V0QWRkRWxlbWVudHMuRXJyb3IoZXJyKVxuICAgICAgKTtcbiAgICB9XG5cbiAgICByZXR1cm4gYXdhaXQgdGhpcy5yYXRlTGltaXRlZChhc3luYyAoKSA9PiB7XG4gICAgICByZXR1cm4gYXdhaXQgdGhpcy5zZW5kU2V0QWRkRWxlbWVudHMoXG4gICAgICAgIGNhY2hlTmFtZSxcbiAgICAgICAgdGhpcy5jb252ZXJ0KHNldE5hbWUpLFxuICAgICAgICB0aGlzLmNvbnZlcnRBcnJheShlbGVtZW50cyksXG4gICAgICAgIHRoaXMuY29sbGVjdGlvblR0bE9yRGVmYXVsdE1pbGxpc2Vjb25kcyh0dGwpLFxuICAgICAgICB0dGwucmVmcmVzaFR0bCgpXG4gICAgICApO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBzZW5kU2V0QWRkRWxlbWVudHMoXG4gICAgY2FjaGVOYW1lOiBzdHJpbmcsXG4gICAgc2V0TmFtZTogVWludDhBcnJheSxcbiAgICBlbGVtZW50czogVWludDhBcnJheVtdLFxuICAgIHR0bE1pbGxpc2Vjb25kczogbnVtYmVyLFxuICAgIHJlZnJlc2hUdGw6IGJvb2xlYW5cbiAgKTogUHJvbWlzZTxDYWNoZVNldEFkZEVsZW1lbnRzLlJlc3BvbnNlPiB7XG4gICAgY29uc3QgcmVxdWVzdCA9IG5ldyBncnBjQ2FjaGUuX1NldFVuaW9uUmVxdWVzdCh7XG4gICAgICBzZXRfbmFtZTogc2V0TmFtZSxcbiAgICAgIGVsZW1lbnRzOiBlbGVtZW50cyxcbiAgICAgIHR0bF9taWxsaXNlY29uZHM6IHR0bE1pbGxpc2Vjb25kcyxcbiAgICAgIHJlZnJlc2hfdHRsOiByZWZyZXNoVHRsLFxuICAgIH0pO1xuICAgIGNvbnN0IG1ldGFkYXRhID0gdGhpcy5jcmVhdGVNZXRhZGF0YShjYWNoZU5hbWUpO1xuICAgIHJldHVybiBhd2FpdCBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICB0aGlzLmNsaWVudFdyYXBwZXIuZ2V0Q2xpZW50KCkuU2V0VW5pb24oXG4gICAgICAgIHJlcXVlc3QsXG4gICAgICAgIG1ldGFkYXRhLFxuICAgICAgICB7XG4gICAgICAgICAgaW50ZXJjZXB0b3JzOiB0aGlzLmludGVyY2VwdG9ycyxcbiAgICAgICAgfSxcbiAgICAgICAgZXJyID0+IHtcbiAgICAgICAgICBpZiAoZXJyKSB7XG4gICAgICAgICAgICB0aGlzLmNhY2hlU2VydmljZUVycm9yTWFwcGVyLnJlc29sdmVPclJlamVjdEVycm9yKHtcbiAgICAgICAgICAgICAgZXJyOiBlcnIsXG4gICAgICAgICAgICAgIGVycm9yUmVzcG9uc2VGYWN0b3J5Rm46IGUgPT4gbmV3IENhY2hlU2V0QWRkRWxlbWVudHMuRXJyb3IoZSksXG4gICAgICAgICAgICAgIHJlc29sdmVGbjogcmVzb2x2ZSxcbiAgICAgICAgICAgICAgcmVqZWN0Rm46IHJlamVjdCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXNvbHZlKG5ldyBDYWNoZVNldEFkZEVsZW1lbnRzLlN1Y2Nlc3MoKSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICApO1xuICAgIH0pO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIHNldENvbnRhaW5zRWxlbWVudChcbiAgICBjYWNoZU5hbWU6IHN0cmluZyxcbiAgICBzZXROYW1lOiBzdHJpbmcsXG4gICAgZWxlbWVudDogc3RyaW5nIHwgVWludDhBcnJheVxuICApOiBQcm9taXNlPENhY2hlU2V0Q29udGFpbnNFbGVtZW50LlJlc3BvbnNlPiB7XG4gICAgdHJ5IHtcbiAgICAgIHZhbGlkYXRlQ2FjaGVOYW1lKGNhY2hlTmFtZSk7XG4gICAgICB2YWxpZGF0ZVNldE5hbWUoc2V0TmFtZSk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICByZXR1cm4gdGhpcy5jYWNoZVNlcnZpY2VFcnJvck1hcHBlci5yZXR1cm5PclRocm93RXJyb3IoXG4gICAgICAgIGVyciBhcyBFcnJvcixcbiAgICAgICAgZXJyID0+IG5ldyBDYWNoZVNldENvbnRhaW5zRWxlbWVudC5FcnJvcihlcnIpXG4gICAgICApO1xuICAgIH1cblxuICAgIHJldHVybiBhd2FpdCB0aGlzLnJhdGVMaW1pdGVkKGFzeW5jICgpID0+IHtcbiAgICAgIHJldHVybiBhd2FpdCB0aGlzLnNlbmRTZXRDb250YWluc0VsZW1lbnQoXG4gICAgICAgIGNhY2hlTmFtZSxcbiAgICAgICAgdGhpcy5jb252ZXJ0KHNldE5hbWUpLFxuICAgICAgICB0aGlzLmNvbnZlcnQoZWxlbWVudClcbiAgICAgICk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHNlbmRTZXRDb250YWluc0VsZW1lbnQoXG4gICAgY2FjaGVOYW1lOiBzdHJpbmcsXG4gICAgc2V0TmFtZTogVWludDhBcnJheSxcbiAgICBlbGVtZW50OiBVaW50OEFycmF5XG4gICk6IFByb21pc2U8Q2FjaGVTZXRDb250YWluc0VsZW1lbnQuUmVzcG9uc2U+IHtcbiAgICBjb25zdCByZXF1ZXN0ID0gbmV3IGdycGNDYWNoZS5fU2V0Q29udGFpbnNSZXF1ZXN0KHtcbiAgICAgIHNldF9uYW1lOiBzZXROYW1lLFxuICAgICAgZWxlbWVudHM6IFtlbGVtZW50XSxcbiAgICB9KTtcbiAgICBjb25zdCBtZXRhZGF0YSA9IHRoaXMuY3JlYXRlTWV0YWRhdGEoY2FjaGVOYW1lKTtcbiAgICByZXR1cm4gYXdhaXQgbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgdGhpcy5jbGllbnRXcmFwcGVyLmdldENsaWVudCgpLlNldENvbnRhaW5zKFxuICAgICAgICByZXF1ZXN0LFxuICAgICAgICBtZXRhZGF0YSxcbiAgICAgICAge1xuICAgICAgICAgIGludGVyY2VwdG9yczogdGhpcy5pbnRlcmNlcHRvcnMsXG4gICAgICAgIH0sXG4gICAgICAgIChlcnIsIHJlc3ApID0+IHtcbiAgICAgICAgICBpZiAocmVzcD8uZm91bmQpIHtcbiAgICAgICAgICAgIGNvbnN0IGZvdW5kX21hc2sgPSByZXNwPy5mb3VuZC5jb250YWlucztcbiAgICAgICAgICAgIGlmIChmb3VuZF9tYXNrID09PSB1bmRlZmluZWQgfHwgZm91bmRfbWFzay5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChcbiAgICAgICAgICAgICAgICBuZXcgQ2FjaGVTZXRDb250YWluc0VsZW1lbnQuRXJyb3IoXG4gICAgICAgICAgICAgICAgICBuZXcgVW5rbm93bkVycm9yKCdTZXRDb250YWlucyByZXNwb25zZSBtaXNzaW5nIGNvbnRhaW5zIG1hc2snKVxuICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJlc29sdmUobmV3IENhY2hlU2V0Q29udGFpbnNFbGVtZW50LkhpdChmb3VuZF9tYXNrWzBdKSk7XG4gICAgICAgICAgfSBlbHNlIGlmIChyZXNwPy5taXNzaW5nKSB7XG4gICAgICAgICAgICByZXNvbHZlKG5ldyBDYWNoZVNldENvbnRhaW5zRWxlbWVudC5NaXNzKCkpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmNhY2hlU2VydmljZUVycm9yTWFwcGVyLnJlc29sdmVPclJlamVjdEVycm9yKHtcbiAgICAgICAgICAgICAgZXJyOiBlcnIsXG4gICAgICAgICAgICAgIGVycm9yUmVzcG9uc2VGYWN0b3J5Rm46IGUgPT4gbmV3IENhY2hlU2V0Q29udGFpbnNFbGVtZW50LkVycm9yKGUpLFxuICAgICAgICAgICAgICByZXNvbHZlRm46IHJlc29sdmUsXG4gICAgICAgICAgICAgIHJlamVjdEZuOiByZWplY3QsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICk7XG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgc2V0Q29udGFpbnNFbGVtZW50cyhcbiAgICBjYWNoZU5hbWU6IHN0cmluZyxcbiAgICBzZXROYW1lOiBzdHJpbmcsXG4gICAgZWxlbWVudHM6IHN0cmluZ1tdIHwgVWludDhBcnJheVtdXG4gICk6IFByb21pc2U8Q2FjaGVTZXRDb250YWluc0VsZW1lbnRzLlJlc3BvbnNlPiB7XG4gICAgdHJ5IHtcbiAgICAgIHZhbGlkYXRlQ2FjaGVOYW1lKGNhY2hlTmFtZSk7XG4gICAgICB2YWxpZGF0ZVNldE5hbWUoc2V0TmFtZSk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICByZXR1cm4gdGhpcy5jYWNoZVNlcnZpY2VFcnJvck1hcHBlci5yZXR1cm5PclRocm93RXJyb3IoXG4gICAgICAgIGVyciBhcyBFcnJvcixcbiAgICAgICAgZXJyID0+IG5ldyBDYWNoZVNldENvbnRhaW5zRWxlbWVudHMuRXJyb3IoZXJyKVxuICAgICAgKTtcbiAgICB9XG5cbiAgICByZXR1cm4gYXdhaXQgdGhpcy5yYXRlTGltaXRlZChhc3luYyAoKSA9PiB7XG4gICAgICByZXR1cm4gYXdhaXQgdGhpcy5zZW5kU2V0Q29udGFpbnNFbGVtZW50cyhcbiAgICAgICAgY2FjaGVOYW1lLFxuICAgICAgICB0aGlzLmNvbnZlcnQoc2V0TmFtZSksXG4gICAgICAgIHRoaXMuY29udmVydEFycmF5KGVsZW1lbnRzKVxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgc2VuZFNldENvbnRhaW5zRWxlbWVudHMoXG4gICAgY2FjaGVOYW1lOiBzdHJpbmcsXG4gICAgc2V0TmFtZTogVWludDhBcnJheSxcbiAgICBlbGVtZW50czogVWludDhBcnJheVtdXG4gICk6IFByb21pc2U8Q2FjaGVTZXRDb250YWluc0VsZW1lbnRzLlJlc3BvbnNlPiB7XG4gICAgY29uc3QgcmVxdWVzdCA9IG5ldyBncnBjQ2FjaGUuX1NldENvbnRhaW5zUmVxdWVzdCh7XG4gICAgICBzZXRfbmFtZTogc2V0TmFtZSxcbiAgICAgIGVsZW1lbnRzOiBlbGVtZW50cyxcbiAgICB9KTtcbiAgICBjb25zdCBtZXRhZGF0YSA9IHRoaXMuY3JlYXRlTWV0YWRhdGEoY2FjaGVOYW1lKTtcbiAgICByZXR1cm4gYXdhaXQgbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgdGhpcy5jbGllbnRXcmFwcGVyLmdldENsaWVudCgpLlNldENvbnRhaW5zKFxuICAgICAgICByZXF1ZXN0LFxuICAgICAgICBtZXRhZGF0YSxcbiAgICAgICAge1xuICAgICAgICAgIGludGVyY2VwdG9yczogdGhpcy5pbnRlcmNlcHRvcnMsXG4gICAgICAgIH0sXG4gICAgICAgIChlcnIsIHJlc3ApID0+IHtcbiAgICAgICAgICBpZiAocmVzcD8uZm91bmQpIHtcbiAgICAgICAgICAgIHJlc29sdmUoXG4gICAgICAgICAgICAgIG5ldyBDYWNoZVNldENvbnRhaW5zRWxlbWVudHMuSGl0KGVsZW1lbnRzLCByZXNwPy5mb3VuZC5jb250YWlucylcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfSBlbHNlIGlmIChyZXNwPy5taXNzaW5nKSB7XG4gICAgICAgICAgICByZXNvbHZlKG5ldyBDYWNoZVNldENvbnRhaW5zRWxlbWVudHMuTWlzcygpKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5jYWNoZVNlcnZpY2VFcnJvck1hcHBlci5yZXNvbHZlT3JSZWplY3RFcnJvcih7XG4gICAgICAgICAgICAgIGVycjogZXJyLFxuICAgICAgICAgICAgICBlcnJvclJlc3BvbnNlRmFjdG9yeUZuOiBlID0+XG4gICAgICAgICAgICAgICAgbmV3IENhY2hlU2V0Q29udGFpbnNFbGVtZW50cy5FcnJvcihlKSxcbiAgICAgICAgICAgICAgcmVzb2x2ZUZuOiByZXNvbHZlLFxuICAgICAgICAgICAgICByZWplY3RGbjogcmVqZWN0LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICApO1xuICAgIH0pO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIHNldFJlbW92ZUVsZW1lbnRzKFxuICAgIGNhY2hlTmFtZTogc3RyaW5nLFxuICAgIHNldE5hbWU6IHN0cmluZyxcbiAgICBlbGVtZW50czogc3RyaW5nW10gfCBVaW50OEFycmF5W11cbiAgKTogUHJvbWlzZTxDYWNoZVNldFJlbW92ZUVsZW1lbnRzLlJlc3BvbnNlPiB7XG4gICAgdHJ5IHtcbiAgICAgIHZhbGlkYXRlQ2FjaGVOYW1lKGNhY2hlTmFtZSk7XG4gICAgICB2YWxpZGF0ZVNldE5hbWUoc2V0TmFtZSk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICByZXR1cm4gdGhpcy5jYWNoZVNlcnZpY2VFcnJvck1hcHBlci5yZXR1cm5PclRocm93RXJyb3IoXG4gICAgICAgIGVyciBhcyBFcnJvcixcbiAgICAgICAgZXJyID0+IG5ldyBDYWNoZVNldFJlbW92ZUVsZW1lbnRzLkVycm9yKGVycilcbiAgICAgICk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGF3YWl0IHRoaXMucmF0ZUxpbWl0ZWQoYXN5bmMgKCkgPT4ge1xuICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuc2VuZFNldFJlbW92ZUVsZW1lbnRzKFxuICAgICAgICBjYWNoZU5hbWUsXG4gICAgICAgIHRoaXMuY29udmVydChzZXROYW1lKSxcbiAgICAgICAgdGhpcy5jb252ZXJ0QXJyYXkoZWxlbWVudHMpXG4gICAgICApO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBzZW5kU2V0UmVtb3ZlRWxlbWVudHMoXG4gICAgY2FjaGVOYW1lOiBzdHJpbmcsXG4gICAgc2V0TmFtZTogVWludDhBcnJheSxcbiAgICBlbGVtZW50czogVWludDhBcnJheVtdXG4gICk6IFByb21pc2U8Q2FjaGVTZXRSZW1vdmVFbGVtZW50cy5SZXNwb25zZT4ge1xuICAgIGNvbnN0IHN1YnRyYWhlbmQgPSBuZXcgZ3JwY0NhY2hlLl9TZXREaWZmZXJlbmNlUmVxdWVzdC5fU3VidHJhaGVuZCh7XG4gICAgICBzZXQ6IG5ldyBncnBjQ2FjaGUuX1NldERpZmZlcmVuY2VSZXF1ZXN0Ll9TdWJ0cmFoZW5kLl9TZXQoe1xuICAgICAgICBlbGVtZW50czogZWxlbWVudHMsXG4gICAgICB9KSxcbiAgICB9KTtcbiAgICBjb25zdCByZXF1ZXN0ID0gbmV3IGdycGNDYWNoZS5fU2V0RGlmZmVyZW5jZVJlcXVlc3Qoe1xuICAgICAgc2V0X25hbWU6IHNldE5hbWUsXG4gICAgICBzdWJ0cmFoZW5kOiBzdWJ0cmFoZW5kLFxuICAgIH0pO1xuXG4gICAgY29uc3QgbWV0YWRhdGEgPSB0aGlzLmNyZWF0ZU1ldGFkYXRhKGNhY2hlTmFtZSk7XG4gICAgcmV0dXJuIGF3YWl0IG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHRoaXMuY2xpZW50V3JhcHBlci5nZXRDbGllbnQoKS5TZXREaWZmZXJlbmNlKFxuICAgICAgICByZXF1ZXN0LFxuICAgICAgICBtZXRhZGF0YSxcbiAgICAgICAge1xuICAgICAgICAgIGludGVyY2VwdG9yczogdGhpcy5pbnRlcmNlcHRvcnMsXG4gICAgICAgIH0sXG4gICAgICAgIGVyciA9PiB7XG4gICAgICAgICAgaWYgKGVycikge1xuICAgICAgICAgICAgdGhpcy5jYWNoZVNlcnZpY2VFcnJvck1hcHBlci5yZXNvbHZlT3JSZWplY3RFcnJvcih7XG4gICAgICAgICAgICAgIGVycjogZXJyLFxuICAgICAgICAgICAgICBlcnJvclJlc3BvbnNlRmFjdG9yeUZuOiBlID0+IG5ldyBDYWNoZVNldFJlbW92ZUVsZW1lbnRzLkVycm9yKGUpLFxuICAgICAgICAgICAgICByZXNvbHZlRm46IHJlc29sdmUsXG4gICAgICAgICAgICAgIHJlamVjdEZuOiByZWplY3QsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmVzb2x2ZShuZXcgQ2FjaGVTZXRSZW1vdmVFbGVtZW50cy5TdWNjZXNzKCkpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBzZXRTYW1wbGUoXG4gICAgY2FjaGVOYW1lOiBzdHJpbmcsXG4gICAgc2V0TmFtZTogc3RyaW5nLFxuICAgIGxpbWl0OiBudW1iZXJcbiAgKTogUHJvbWlzZTxDYWNoZVNldFNhbXBsZS5SZXNwb25zZT4ge1xuICAgIHRyeSB7XG4gICAgICB2YWxpZGF0ZUNhY2hlTmFtZShjYWNoZU5hbWUpO1xuICAgICAgdmFsaWRhdGVTZXROYW1lKHNldE5hbWUpO1xuICAgICAgdmFsaWRhdGVTZXRTYW1wbGVMaW1pdChsaW1pdCk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICByZXR1cm4gdGhpcy5jYWNoZVNlcnZpY2VFcnJvck1hcHBlci5yZXR1cm5PclRocm93RXJyb3IoXG4gICAgICAgIGVyciBhcyBFcnJvcixcbiAgICAgICAgZXJyID0+IG5ldyBDYWNoZVNldFNhbXBsZS5FcnJvcihlcnIpXG4gICAgICApO1xuICAgIH1cblxuICAgIHJldHVybiBhd2FpdCB0aGlzLnJhdGVMaW1pdGVkKGFzeW5jICgpID0+IHtcbiAgICAgIHJldHVybiBhd2FpdCB0aGlzLnNlbmRTZXRTYW1wbGUoY2FjaGVOYW1lLCB0aGlzLmNvbnZlcnQoc2V0TmFtZSksIGxpbWl0KTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgc2VuZFNldFNhbXBsZShcbiAgICBjYWNoZU5hbWU6IHN0cmluZyxcbiAgICBzZXROYW1lOiBVaW50OEFycmF5LFxuICAgIGxpbWl0OiBudW1iZXJcbiAgKTogUHJvbWlzZTxDYWNoZVNldFNhbXBsZS5SZXNwb25zZT4ge1xuICAgIGNvbnN0IHJlcXVlc3QgPSBuZXcgZ3JwY0NhY2hlLl9TZXRTYW1wbGVSZXF1ZXN0KHtcbiAgICAgIHNldF9uYW1lOiBzZXROYW1lLFxuICAgICAgbGltaXQ6IGxpbWl0LFxuICAgIH0pO1xuICAgIGNvbnN0IG1ldGFkYXRhID0gdGhpcy5jcmVhdGVNZXRhZGF0YShjYWNoZU5hbWUpO1xuICAgIHJldHVybiBhd2FpdCBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICB0aGlzLmNsaWVudFdyYXBwZXIuZ2V0Q2xpZW50KCkuU2V0U2FtcGxlKFxuICAgICAgICByZXF1ZXN0LFxuICAgICAgICBtZXRhZGF0YSxcbiAgICAgICAge1xuICAgICAgICAgIGludGVyY2VwdG9yczogdGhpcy5pbnRlcmNlcHRvcnMsXG4gICAgICAgIH0sXG4gICAgICAgIChlcnIsIHJlc3ApID0+IHtcbiAgICAgICAgICBpZiAocmVzcD8ubWlzc2luZykge1xuICAgICAgICAgICAgcmVzb2x2ZShuZXcgQ2FjaGVTZXRTYW1wbGUuTWlzcygpKTtcbiAgICAgICAgICB9IGVsc2UgaWYgKHJlc3A/LmZvdW5kKSB7XG4gICAgICAgICAgICByZXNvbHZlKG5ldyBDYWNoZVNldFNhbXBsZS5IaXQocmVzcC5mb3VuZC5lbGVtZW50cykpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmNhY2hlU2VydmljZUVycm9yTWFwcGVyLnJlc29sdmVPclJlamVjdEVycm9yKHtcbiAgICAgICAgICAgICAgZXJyOiBlcnIsXG4gICAgICAgICAgICAgIGVycm9yUmVzcG9uc2VGYWN0b3J5Rm46IGUgPT4gbmV3IENhY2hlU2V0U2FtcGxlLkVycm9yKGUpLFxuICAgICAgICAgICAgICByZXNvbHZlRm46IHJlc29sdmUsXG4gICAgICAgICAgICAgIHJlamVjdEZuOiByZWplY3QsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICk7XG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgc2V0UG9wKFxuICAgIGNhY2hlTmFtZTogc3RyaW5nLFxuICAgIHNldE5hbWU6IHN0cmluZyxcbiAgICBjb3VudDogbnVtYmVyXG4gICk6IFByb21pc2U8Q2FjaGVTZXRQb3AuUmVzcG9uc2U+IHtcbiAgICB0cnkge1xuICAgICAgdmFsaWRhdGVDYWNoZU5hbWUoY2FjaGVOYW1lKTtcbiAgICAgIHZhbGlkYXRlU2V0TmFtZShzZXROYW1lKTtcbiAgICAgIHZhbGlkYXRlU2V0UG9wQ291bnQoY291bnQpO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgcmV0dXJuIHRoaXMuY2FjaGVTZXJ2aWNlRXJyb3JNYXBwZXIucmV0dXJuT3JUaHJvd0Vycm9yKFxuICAgICAgICBlcnIgYXMgRXJyb3IsXG4gICAgICAgIGVyciA9PiBuZXcgQ2FjaGVTZXRQb3AuRXJyb3IoZXJyKVxuICAgICAgKTtcbiAgICB9XG5cbiAgICByZXR1cm4gYXdhaXQgdGhpcy5yYXRlTGltaXRlZChhc3luYyAoKSA9PiB7XG4gICAgICByZXR1cm4gYXdhaXQgdGhpcy5zZW5kU2V0UG9wKGNhY2hlTmFtZSwgdGhpcy5jb252ZXJ0KHNldE5hbWUpLCBjb3VudCk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHNlbmRTZXRQb3AoXG4gICAgY2FjaGVOYW1lOiBzdHJpbmcsXG4gICAgc2V0TmFtZTogVWludDhBcnJheSxcbiAgICBjb3VudDogbnVtYmVyXG4gICk6IFByb21pc2U8Q2FjaGVTZXRQb3AuUmVzcG9uc2U+IHtcbiAgICBjb25zdCByZXF1ZXN0ID0gbmV3IGdycGNDYWNoZS5fU2V0UG9wUmVxdWVzdCh7XG4gICAgICBzZXRfbmFtZTogc2V0TmFtZSxcbiAgICAgIGNvdW50OiBjb3VudCxcbiAgICB9KTtcbiAgICBjb25zdCBtZXRhZGF0YSA9IHRoaXMuY3JlYXRlTWV0YWRhdGEoY2FjaGVOYW1lKTtcbiAgICByZXR1cm4gYXdhaXQgbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgdGhpcy5jbGllbnRXcmFwcGVyLmdldENsaWVudCgpLlNldFBvcChcbiAgICAgICAgcmVxdWVzdCxcbiAgICAgICAgbWV0YWRhdGEsXG4gICAgICAgIHtcbiAgICAgICAgICBpbnRlcmNlcHRvcnM6IHRoaXMuaW50ZXJjZXB0b3JzLFxuICAgICAgICB9LFxuICAgICAgICAoZXJyLCByZXNwKSA9PiB7XG4gICAgICAgICAgaWYgKHJlc3A/Lm1pc3NpbmcpIHtcbiAgICAgICAgICAgIHJlc29sdmUobmV3IENhY2hlU2V0UG9wLk1pc3MoKSk7XG4gICAgICAgICAgfSBlbHNlIGlmIChyZXNwPy5mb3VuZCkge1xuICAgICAgICAgICAgcmVzb2x2ZShuZXcgQ2FjaGVTZXRQb3AuSGl0KHJlc3AuZm91bmQuZWxlbWVudHMpKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5jYWNoZVNlcnZpY2VFcnJvck1hcHBlci5yZXNvbHZlT3JSZWplY3RFcnJvcih7XG4gICAgICAgICAgICAgIGVycjogZXJyLFxuICAgICAgICAgICAgICBlcnJvclJlc3BvbnNlRmFjdG9yeUZuOiBlID0+IG5ldyBDYWNoZVNldFBvcC5FcnJvcihlKSxcbiAgICAgICAgICAgICAgcmVzb2x2ZUZuOiByZXNvbHZlLFxuICAgICAgICAgICAgICByZWplY3RGbjogcmVqZWN0LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICApO1xuICAgIH0pO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIHNldExlbmd0aChcbiAgICBjYWNoZU5hbWU6IHN0cmluZyxcbiAgICBzZXROYW1lOiBzdHJpbmdcbiAgKTogUHJvbWlzZTxDYWNoZVNldExlbmd0aC5SZXNwb25zZT4ge1xuICAgIHRyeSB7XG4gICAgICB2YWxpZGF0ZUNhY2hlTmFtZShjYWNoZU5hbWUpO1xuICAgICAgdmFsaWRhdGVTZXROYW1lKHNldE5hbWUpO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgcmV0dXJuIHRoaXMuY2FjaGVTZXJ2aWNlRXJyb3JNYXBwZXIucmV0dXJuT3JUaHJvd0Vycm9yKFxuICAgICAgICBlcnIgYXMgRXJyb3IsXG4gICAgICAgIGVyciA9PiBuZXcgQ2FjaGVTZXRMZW5ndGguRXJyb3IoZXJyKVxuICAgICAgKTtcbiAgICB9XG5cbiAgICByZXR1cm4gYXdhaXQgdGhpcy5yYXRlTGltaXRlZChhc3luYyAoKSA9PiB7XG4gICAgICByZXR1cm4gYXdhaXQgdGhpcy5zZW5kU2V0TGVuZ3RoKGNhY2hlTmFtZSwgdGhpcy5jb252ZXJ0KHNldE5hbWUpKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgc2VuZFNldExlbmd0aChcbiAgICBjYWNoZU5hbWU6IHN0cmluZyxcbiAgICBzZXROYW1lOiBVaW50OEFycmF5XG4gICk6IFByb21pc2U8Q2FjaGVTZXRMZW5ndGguUmVzcG9uc2U+IHtcbiAgICBjb25zdCByZXF1ZXN0ID0gbmV3IGdycGNDYWNoZS5fU2V0TGVuZ3RoUmVxdWVzdCh7XG4gICAgICBzZXRfbmFtZTogc2V0TmFtZSxcbiAgICB9KTtcblxuICAgIGNvbnN0IG1ldGFkYXRhID0gdGhpcy5jcmVhdGVNZXRhZGF0YShjYWNoZU5hbWUpO1xuICAgIHJldHVybiBhd2FpdCBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICB0aGlzLmNsaWVudFdyYXBwZXIuZ2V0Q2xpZW50KCkuU2V0TGVuZ3RoKFxuICAgICAgICByZXF1ZXN0LFxuICAgICAgICBtZXRhZGF0YSxcbiAgICAgICAge1xuICAgICAgICAgIGludGVyY2VwdG9yczogdGhpcy5pbnRlcmNlcHRvcnMsXG4gICAgICAgIH0sXG4gICAgICAgIChlcnIsIHJlc3ApID0+IHtcbiAgICAgICAgICBpZiAocmVzcD8ubWlzc2luZykge1xuICAgICAgICAgICAgcmVzb2x2ZShuZXcgQ2FjaGVTZXRMZW5ndGguTWlzcygpKTtcbiAgICAgICAgICB9IGVsc2UgaWYgKHJlc3A/LmZvdW5kKSB7XG4gICAgICAgICAgICBpZiAoIXJlc3AuZm91bmQubGVuZ3RoKSB7XG4gICAgICAgICAgICAgIHJlc29sdmUobmV3IENhY2hlU2V0TGVuZ3RoLk1pc3MoKSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICByZXNvbHZlKG5ldyBDYWNoZVNldExlbmd0aC5IaXQocmVzcC5mb3VuZC5sZW5ndGgpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5jYWNoZVNlcnZpY2VFcnJvck1hcHBlci5yZXNvbHZlT3JSZWplY3RFcnJvcih7XG4gICAgICAgICAgICAgIGVycjogZXJyLFxuICAgICAgICAgICAgICBlcnJvclJlc3BvbnNlRmFjdG9yeUZuOiBlID0+IG5ldyBDYWNoZVNldExlbmd0aC5FcnJvcihlKSxcbiAgICAgICAgICAgICAgcmVzb2x2ZUZuOiByZXNvbHZlLFxuICAgICAgICAgICAgICByZWplY3RGbjogcmVqZWN0LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICApO1xuICAgIH0pO1xuICB9XG5cbiAgLy8gc2V0SWZOb3RFeGlzdHMgaXMgZGVwcmVjYXRlZCBvbiB0aGUgc2VydmljZS4gSGVyZSB3ZSBjYWxsIHRoZSBuZXcgYFNldElmYCBtZXRob2Qgd2l0aCB0aGUgYWJzZW50IGZpZWxkIHNldFxuICAvLyBhbmQgcmV0dXJuIGBDYWNoZVNldElmTm90RXhpc3RzYCByZXNwb25zZXMuXG4gIHB1YmxpYyBhc3luYyBzZXRJZk5vdEV4aXN0cyhcbiAgICBjYWNoZU5hbWU6IHN0cmluZyxcbiAgICBrZXk6IHN0cmluZyB8IFVpbnQ4QXJyYXksXG4gICAgdmFsdWU6IHN0cmluZyB8IFVpbnQ4QXJyYXksXG4gICAgdHRsPzogbnVtYmVyXG4gICk6IFByb21pc2U8Q2FjaGVTZXRJZk5vdEV4aXN0cy5SZXNwb25zZT4ge1xuICAgIHRyeSB7XG4gICAgICB2YWxpZGF0ZUNhY2hlTmFtZShjYWNoZU5hbWUpO1xuICAgICAgaWYgKHR0bCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHZhbGlkYXRlVHRsU2Vjb25kcyh0dGwpO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgcmV0dXJuIHRoaXMuY2FjaGVTZXJ2aWNlRXJyb3JNYXBwZXIucmV0dXJuT3JUaHJvd0Vycm9yKFxuICAgICAgICBlcnIgYXMgRXJyb3IsXG4gICAgICAgIGVyciA9PiBuZXcgQ2FjaGVTZXRJZk5vdEV4aXN0cy5FcnJvcihlcnIpXG4gICAgICApO1xuICAgIH1cblxuICAgIHJldHVybiBhd2FpdCB0aGlzLnJhdGVMaW1pdGVkKGFzeW5jICgpID0+IHtcbiAgICAgIHJldHVybiBhd2FpdCB0aGlzLnNlbmRTZXRJZk5vdEV4aXN0cyhcbiAgICAgICAgY2FjaGVOYW1lLFxuICAgICAgICB0aGlzLmNvbnZlcnQoa2V5KSxcbiAgICAgICAgdGhpcy5jb252ZXJ0KHZhbHVlKSxcbiAgICAgICAgdGhpcy50dGxPckRlZmF1bHRNaWxsaXNlY29uZHModHRsKVxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgc2VuZFNldElmTm90RXhpc3RzKFxuICAgIGNhY2hlTmFtZTogc3RyaW5nLFxuICAgIGtleTogVWludDhBcnJheSxcbiAgICB2YWx1ZTogVWludDhBcnJheSxcbiAgICB0dGxNaWxsaXNlY29uZHM6IG51bWJlclxuICApOiBQcm9taXNlPENhY2hlU2V0SWZOb3RFeGlzdHMuUmVzcG9uc2U+IHtcbiAgICBjb25zdCByZXF1ZXN0ID0gbmV3IGdycGNDYWNoZS5fU2V0SWZSZXF1ZXN0KHtcbiAgICAgIGNhY2hlX2tleToga2V5LFxuICAgICAgY2FjaGVfYm9keTogdmFsdWUsXG4gICAgICB0dGxfbWlsbGlzZWNvbmRzOiB0dGxNaWxsaXNlY29uZHMsXG4gICAgICBhYnNlbnQ6IG5ldyBBYnNlbnQoKSxcbiAgICB9KTtcbiAgICBjb25zdCBtZXRhZGF0YSA9IHRoaXMuY3JlYXRlTWV0YWRhdGEoY2FjaGVOYW1lKTtcblxuICAgIHJldHVybiBhd2FpdCBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICB0aGlzLmNsaWVudFdyYXBwZXIuZ2V0Q2xpZW50KCkuU2V0SWYoXG4gICAgICAgIHJlcXVlc3QsXG4gICAgICAgIG1ldGFkYXRhLFxuICAgICAgICB7XG4gICAgICAgICAgaW50ZXJjZXB0b3JzOiB0aGlzLmludGVyY2VwdG9ycyxcbiAgICAgICAgfSxcbiAgICAgICAgKGVyciwgcmVzcCkgPT4ge1xuICAgICAgICAgIGlmIChyZXNwKSB7XG4gICAgICAgICAgICBzd2l0Y2ggKHJlc3AucmVzdWx0KSB7XG4gICAgICAgICAgICAgIGNhc2UgJ3N0b3JlZCc6XG4gICAgICAgICAgICAgICAgcmVzb2x2ZShuZXcgQ2FjaGVTZXRJZk5vdEV4aXN0cy5TdG9yZWQoKSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgIGNhc2UgJ25vdF9zdG9yZWQnOlxuICAgICAgICAgICAgICAgIHJlc29sdmUobmV3IENhY2hlU2V0SWZOb3RFeGlzdHMuTm90U3RvcmVkKCkpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIHJlc29sdmUoXG4gICAgICAgICAgICAgICAgICBuZXcgQ2FjaGVTZXRJZk5vdEV4aXN0cy5FcnJvcihcbiAgICAgICAgICAgICAgICAgICAgbmV3IFVua25vd25FcnJvcihcbiAgICAgICAgICAgICAgICAgICAgICAnU2V0SWZOb3RFeGlzdHMgcmVzcG9uZGVkIHdpdGggYW4gdW5rbm93biByZXN1bHQnXG4gICAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmNhY2hlU2VydmljZUVycm9yTWFwcGVyLnJlc29sdmVPclJlamVjdEVycm9yKHtcbiAgICAgICAgICAgICAgZXJyOiBlcnIsXG4gICAgICAgICAgICAgIGVycm9yUmVzcG9uc2VGYWN0b3J5Rm46IGUgPT4gbmV3IENhY2hlU2V0SWZOb3RFeGlzdHMuRXJyb3IoZSksXG4gICAgICAgICAgICAgIHJlc29sdmVGbjogcmVzb2x2ZSxcbiAgICAgICAgICAgICAgcmVqZWN0Rm46IHJlamVjdCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBzZXRJZkFic2VudChcbiAgICBjYWNoZU5hbWU6IHN0cmluZyxcbiAgICBrZXk6IHN0cmluZyB8IFVpbnQ4QXJyYXksXG4gICAgdmFsdWU6IHN0cmluZyB8IFVpbnQ4QXJyYXksXG4gICAgb3B0aW9ucz86IFNldElmQWJzZW50Q2FsbE9wdGlvbnNcbiAgKTogUHJvbWlzZTxDYWNoZVNldElmQWJzZW50LlJlc3BvbnNlPiB7XG4gICAgY29uc3QgdHRsID0gb3B0aW9ucz8udHRsO1xuICAgIHRyeSB7XG4gICAgICB2YWxpZGF0ZUNhY2hlTmFtZShjYWNoZU5hbWUpO1xuICAgICAgaWYgKHR0bCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHZhbGlkYXRlVHRsU2Vjb25kcyh0dGwpO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgcmV0dXJuIHRoaXMuY2FjaGVTZXJ2aWNlRXJyb3JNYXBwZXIucmV0dXJuT3JUaHJvd0Vycm9yKFxuICAgICAgICBlcnIgYXMgRXJyb3IsXG4gICAgICAgIGVyciA9PiBuZXcgQ2FjaGVTZXRJZkFic2VudC5FcnJvcihlcnIpXG4gICAgICApO1xuICAgIH1cblxuICAgIHJldHVybiBhd2FpdCB0aGlzLnJhdGVMaW1pdGVkKGFzeW5jICgpID0+IHtcbiAgICAgIGxldCBlbmNvZGVkVmFsdWUgPSB0aGlzLmNvbnZlcnQodmFsdWUpO1xuICAgICAgaWYgKG9wdGlvbnM/LmNvbXByZXNzKSB7XG4gICAgICAgIHRoaXMubG9nZ2VyLnRyYWNlKFxuICAgICAgICAgICdDYWNoZUNsaWVudC5zZXRJZkFic2VudDsgY29tcHJlc3Npb24gZW5hYmxlZCwgY2FsbGluZyB2YWx1ZSBjb21wcmVzc29yJ1xuICAgICAgICApO1xuICAgICAgICBpZiAodGhpcy5jb21wcmVzc2lvbkRldGFpbHMgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHJldHVybiB0aGlzLmNhY2hlU2VydmljZUVycm9yTWFwcGVyLnJldHVybk9yVGhyb3dFcnJvcihcbiAgICAgICAgICAgIG5ldyBJbnZhbGlkQXJndW1lbnRFcnJvcihcbiAgICAgICAgICAgICAgJ0NvbXByZXNzb3IgaXMgbm90IHNldCwgYnV0IGBDYWNoZUNsaWVudC5zZXRJZkFic2VudGAgd2FzIGNhbGxlZCB3aXRoIHRoZSBgY29tcHJlc3NgIG9wdGlvbjsgcGxlYXNlIGluc3RhbGwgQGdvbW9tZW50by9zZGstbm9kZWpzLWNvbXByZXNzaW9uIGFuZCBjYWxsIGBDb25maWd1cmF0aW9uLndpdGhDb21wcmVzc2lvblN0cmF0ZWd5YCB0byBlbmFibGUgY29tcHJlc3Npb24uJ1xuICAgICAgICAgICAgKSxcbiAgICAgICAgICAgIGVyciA9PiBuZXcgQ2FjaGVTZXRJZkFic2VudC5FcnJvcihlcnIpXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgICBlbmNvZGVkVmFsdWUgPSBhd2FpdCB0aGlzLmNvbXByZXNzaW9uRGV0YWlscy52YWx1ZUNvbXByZXNzb3IuY29tcHJlc3MoXG4gICAgICAgICAgdGhpcy5jb21wcmVzc2lvbkRldGFpbHMuY29tcHJlc3Npb25MZXZlbCxcbiAgICAgICAgICBlbmNvZGVkVmFsdWVcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuc2VuZFNldElmQWJzZW50KFxuICAgICAgICBjYWNoZU5hbWUsXG4gICAgICAgIHRoaXMuY29udmVydChrZXkpLFxuICAgICAgICBlbmNvZGVkVmFsdWUsXG4gICAgICAgIHRoaXMudHRsT3JEZWZhdWx0TWlsbGlzZWNvbmRzKHR0bClcbiAgICAgICk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHNlbmRTZXRJZkFic2VudChcbiAgICBjYWNoZU5hbWU6IHN0cmluZyxcbiAgICBrZXk6IFVpbnQ4QXJyYXksXG4gICAgdmFsdWU6IFVpbnQ4QXJyYXksXG4gICAgdHRsTWlsbGlzZWNvbmRzOiBudW1iZXJcbiAgKTogUHJvbWlzZTxDYWNoZVNldElmQWJzZW50LlJlc3BvbnNlPiB7XG4gICAgY29uc3QgcmVxdWVzdCA9IG5ldyBncnBjQ2FjaGUuX1NldElmUmVxdWVzdCh7XG4gICAgICBjYWNoZV9rZXk6IGtleSxcbiAgICAgIGNhY2hlX2JvZHk6IHZhbHVlLFxuICAgICAgdHRsX21pbGxpc2Vjb25kczogdHRsTWlsbGlzZWNvbmRzLFxuICAgICAgYWJzZW50OiBuZXcgQWJzZW50KCksXG4gICAgfSk7XG4gICAgY29uc3QgbWV0YWRhdGEgPSB0aGlzLmNyZWF0ZU1ldGFkYXRhKGNhY2hlTmFtZSk7XG5cbiAgICByZXR1cm4gYXdhaXQgbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgdGhpcy5jbGllbnRXcmFwcGVyLmdldENsaWVudCgpLlNldElmKFxuICAgICAgICByZXF1ZXN0LFxuICAgICAgICBtZXRhZGF0YSxcbiAgICAgICAge1xuICAgICAgICAgIGludGVyY2VwdG9yczogdGhpcy5pbnRlcmNlcHRvcnMsXG4gICAgICAgIH0sXG4gICAgICAgIChlcnIsIHJlc3ApID0+IHtcbiAgICAgICAgICBpZiAocmVzcCkge1xuICAgICAgICAgICAgc3dpdGNoIChyZXNwLnJlc3VsdCkge1xuICAgICAgICAgICAgICBjYXNlICdzdG9yZWQnOlxuICAgICAgICAgICAgICAgIHJlc29sdmUobmV3IENhY2hlU2V0SWZBYnNlbnQuU3RvcmVkKCkpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICBjYXNlICdub3Rfc3RvcmVkJzpcbiAgICAgICAgICAgICAgICByZXNvbHZlKG5ldyBDYWNoZVNldElmQWJzZW50Lk5vdFN0b3JlZCgpKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICByZXNvbHZlKFxuICAgICAgICAgICAgICAgICAgbmV3IENhY2hlU2V0SWZBYnNlbnQuRXJyb3IoXG4gICAgICAgICAgICAgICAgICAgIG5ldyBVbmtub3duRXJyb3IoXG4gICAgICAgICAgICAgICAgICAgICAgJ1NldElmQWJzZW50IHJlc3BvbmRlZCB3aXRoIGFuIHVua25vd24gcmVzdWx0J1xuICAgICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5jYWNoZVNlcnZpY2VFcnJvck1hcHBlci5yZXNvbHZlT3JSZWplY3RFcnJvcih7XG4gICAgICAgICAgICAgIGVycjogZXJyLFxuICAgICAgICAgICAgICBlcnJvclJlc3BvbnNlRmFjdG9yeUZuOiBlID0+IG5ldyBDYWNoZVNldElmQWJzZW50LkVycm9yKGUpLFxuICAgICAgICAgICAgICByZXNvbHZlRm46IHJlc29sdmUsXG4gICAgICAgICAgICAgIHJlamVjdEZuOiByZWplY3QsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICk7XG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgc2V0SWZQcmVzZW50KFxuICAgIGNhY2hlTmFtZTogc3RyaW5nLFxuICAgIGtleTogc3RyaW5nIHwgVWludDhBcnJheSxcbiAgICB2YWx1ZTogc3RyaW5nIHwgVWludDhBcnJheSxcbiAgICB0dGw/OiBudW1iZXJcbiAgKTogUHJvbWlzZTxDYWNoZVNldElmUHJlc2VudC5SZXNwb25zZT4ge1xuICAgIHRyeSB7XG4gICAgICB2YWxpZGF0ZUNhY2hlTmFtZShjYWNoZU5hbWUpO1xuICAgICAgaWYgKHR0bCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHZhbGlkYXRlVHRsU2Vjb25kcyh0dGwpO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgcmV0dXJuIHRoaXMuY2FjaGVTZXJ2aWNlRXJyb3JNYXBwZXIucmV0dXJuT3JUaHJvd0Vycm9yKFxuICAgICAgICBlcnIgYXMgRXJyb3IsXG4gICAgICAgIGVyciA9PiBuZXcgQ2FjaGVTZXRJZlByZXNlbnQuRXJyb3IoZXJyKVxuICAgICAgKTtcbiAgICB9XG5cbiAgICByZXR1cm4gYXdhaXQgdGhpcy5yYXRlTGltaXRlZChhc3luYyAoKSA9PiB7XG4gICAgICByZXR1cm4gYXdhaXQgdGhpcy5zZW5kU2V0SWZQcmVzZW50KFxuICAgICAgICBjYWNoZU5hbWUsXG4gICAgICAgIHRoaXMuY29udmVydChrZXkpLFxuICAgICAgICB0aGlzLmNvbnZlcnQodmFsdWUpLFxuICAgICAgICB0aGlzLnR0bE9yRGVmYXVsdE1pbGxpc2Vjb25kcyh0dGwpXG4gICAgICApO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBzZW5kU2V0SWZQcmVzZW50KFxuICAgIGNhY2hlTmFtZTogc3RyaW5nLFxuICAgIGtleTogVWludDhBcnJheSxcbiAgICB2YWx1ZTogVWludDhBcnJheSxcbiAgICB0dGxNaWxsaXNlY29uZHM6IG51bWJlclxuICApOiBQcm9taXNlPENhY2hlU2V0SWZQcmVzZW50LlJlc3BvbnNlPiB7XG4gICAgY29uc3QgcmVxdWVzdCA9IG5ldyBncnBjQ2FjaGUuX1NldElmUmVxdWVzdCh7XG4gICAgICBjYWNoZV9rZXk6IGtleSxcbiAgICAgIGNhY2hlX2JvZHk6IHZhbHVlLFxuICAgICAgdHRsX21pbGxpc2Vjb25kczogdHRsTWlsbGlzZWNvbmRzLFxuICAgICAgcHJlc2VudDogbmV3IFByZXNlbnQoKSxcbiAgICB9KTtcbiAgICBjb25zdCBtZXRhZGF0YSA9IHRoaXMuY3JlYXRlTWV0YWRhdGEoY2FjaGVOYW1lKTtcblxuICAgIHJldHVybiBhd2FpdCBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICB0aGlzLmNsaWVudFdyYXBwZXIuZ2V0Q2xpZW50KCkuU2V0SWYoXG4gICAgICAgIHJlcXVlc3QsXG4gICAgICAgIG1ldGFkYXRhLFxuICAgICAgICB7XG4gICAgICAgICAgaW50ZXJjZXB0b3JzOiB0aGlzLmludGVyY2VwdG9ycyxcbiAgICAgICAgfSxcbiAgICAgICAgKGVyciwgcmVzcCkgPT4ge1xuICAgICAgICAgIGlmIChyZXNwKSB7XG4gICAgICAgICAgICBzd2l0Y2ggKHJlc3AucmVzdWx0KSB7XG4gICAgICAgICAgICAgIGNhc2UgJ3N0b3JlZCc6XG4gICAgICAgICAgICAgICAgcmVzb2x2ZShuZXcgQ2FjaGVTZXRJZlByZXNlbnQuU3RvcmVkKCkpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICBjYXNlICdub3Rfc3RvcmVkJzpcbiAgICAgICAgICAgICAgICByZXNvbHZlKG5ldyBDYWNoZVNldElmUHJlc2VudC5Ob3RTdG9yZWQoKSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgcmVzb2x2ZShcbiAgICAgICAgICAgICAgICAgIG5ldyBDYWNoZVNldElmUHJlc2VudC5FcnJvcihcbiAgICAgICAgICAgICAgICAgICAgbmV3IFVua25vd25FcnJvcihcbiAgICAgICAgICAgICAgICAgICAgICAnU2V0SWZQcmVzZW50IHJlc3BvbmRlZCB3aXRoIGFuIHVua25vd24gcmVzdWx0J1xuICAgICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5jYWNoZVNlcnZpY2VFcnJvck1hcHBlci5yZXNvbHZlT3JSZWplY3RFcnJvcih7XG4gICAgICAgICAgICAgIGVycjogZXJyLFxuICAgICAgICAgICAgICBlcnJvclJlc3BvbnNlRmFjdG9yeUZuOiBlID0+IG5ldyBDYWNoZVNldElmUHJlc2VudC5FcnJvcihlKSxcbiAgICAgICAgICAgICAgcmVzb2x2ZUZuOiByZXNvbHZlLFxuICAgICAgICAgICAgICByZWplY3RGbjogcmVqZWN0LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICApO1xuICAgIH0pO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIHNldElmRXF1YWwoXG4gICAgY2FjaGVOYW1lOiBzdHJpbmcsXG4gICAga2V5OiBzdHJpbmcgfCBVaW50OEFycmF5LFxuICAgIHZhbHVlOiBzdHJpbmcgfCBVaW50OEFycmF5LFxuICAgIGVxdWFsOiBzdHJpbmcgfCBVaW50OEFycmF5LFxuICAgIHR0bD86IG51bWJlclxuICApOiBQcm9taXNlPENhY2hlU2V0SWZFcXVhbC5SZXNwb25zZT4ge1xuICAgIHRyeSB7XG4gICAgICB2YWxpZGF0ZUNhY2hlTmFtZShjYWNoZU5hbWUpO1xuICAgICAgaWYgKHR0bCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHZhbGlkYXRlVHRsU2Vjb25kcyh0dGwpO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgcmV0dXJuIHRoaXMuY2FjaGVTZXJ2aWNlRXJyb3JNYXBwZXIucmV0dXJuT3JUaHJvd0Vycm9yKFxuICAgICAgICBlcnIgYXMgRXJyb3IsXG4gICAgICAgIGVyciA9PiBuZXcgQ2FjaGVTZXRJZkVxdWFsLkVycm9yKGVycilcbiAgICAgICk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGF3YWl0IHRoaXMucmF0ZUxpbWl0ZWQoYXN5bmMgKCkgPT4ge1xuICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuc2VuZFNldElmRXF1YWwoXG4gICAgICAgIGNhY2hlTmFtZSxcbiAgICAgICAgdGhpcy5jb252ZXJ0KGtleSksXG4gICAgICAgIHRoaXMuY29udmVydCh2YWx1ZSksXG4gICAgICAgIHRoaXMuY29udmVydChlcXVhbCksXG4gICAgICAgIHRoaXMudHRsT3JEZWZhdWx0TWlsbGlzZWNvbmRzKHR0bClcbiAgICAgICk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHNlbmRTZXRJZkVxdWFsKFxuICAgIGNhY2hlTmFtZTogc3RyaW5nLFxuICAgIGtleTogVWludDhBcnJheSxcbiAgICB2YWx1ZTogVWludDhBcnJheSxcbiAgICBlcXVhbDogVWludDhBcnJheSxcbiAgICB0dGxNaWxsaXNlY29uZHM6IG51bWJlclxuICApOiBQcm9taXNlPENhY2hlU2V0SWZFcXVhbC5SZXNwb25zZT4ge1xuICAgIGNvbnN0IHJlcXVlc3QgPSBuZXcgZ3JwY0NhY2hlLl9TZXRJZlJlcXVlc3Qoe1xuICAgICAgY2FjaGVfa2V5OiBrZXksXG4gICAgICBjYWNoZV9ib2R5OiB2YWx1ZSxcbiAgICAgIHR0bF9taWxsaXNlY29uZHM6IHR0bE1pbGxpc2Vjb25kcyxcbiAgICAgIGVxdWFsOiBuZXcgRXF1YWwoe3ZhbHVlX3RvX2NoZWNrOiBlcXVhbH0pLFxuICAgIH0pO1xuICAgIGNvbnN0IG1ldGFkYXRhID0gdGhpcy5jcmVhdGVNZXRhZGF0YShjYWNoZU5hbWUpO1xuXG4gICAgcmV0dXJuIGF3YWl0IG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHRoaXMuY2xpZW50V3JhcHBlci5nZXRDbGllbnQoKS5TZXRJZihcbiAgICAgICAgcmVxdWVzdCxcbiAgICAgICAgbWV0YWRhdGEsXG4gICAgICAgIHtcbiAgICAgICAgICBpbnRlcmNlcHRvcnM6IHRoaXMuaW50ZXJjZXB0b3JzLFxuICAgICAgICB9LFxuICAgICAgICAoZXJyLCByZXNwKSA9PiB7XG4gICAgICAgICAgaWYgKHJlc3ApIHtcbiAgICAgICAgICAgIHN3aXRjaCAocmVzcC5yZXN1bHQpIHtcbiAgICAgICAgICAgICAgY2FzZSAnc3RvcmVkJzpcbiAgICAgICAgICAgICAgICByZXNvbHZlKG5ldyBDYWNoZVNldElmRXF1YWwuU3RvcmVkKCkpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICBjYXNlICdub3Rfc3RvcmVkJzpcbiAgICAgICAgICAgICAgICByZXNvbHZlKG5ldyBDYWNoZVNldElmRXF1YWwuTm90U3RvcmVkKCkpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIHJlc29sdmUoXG4gICAgICAgICAgICAgICAgICBuZXcgQ2FjaGVTZXRJZkVxdWFsLkVycm9yKFxuICAgICAgICAgICAgICAgICAgICBuZXcgVW5rbm93bkVycm9yKFxuICAgICAgICAgICAgICAgICAgICAgICdTZXRJZkVxdWFsIHJlc3BvbmRlZCB3aXRoIGFuIHVua25vd24gcmVzdWx0J1xuICAgICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5jYWNoZVNlcnZpY2VFcnJvck1hcHBlci5yZXNvbHZlT3JSZWplY3RFcnJvcih7XG4gICAgICAgICAgICAgIGVycjogZXJyLFxuICAgICAgICAgICAgICBlcnJvclJlc3BvbnNlRmFjdG9yeUZuOiBlID0+IG5ldyBDYWNoZVNldElmRXF1YWwuRXJyb3IoZSksXG4gICAgICAgICAgICAgIHJlc29sdmVGbjogcmVzb2x2ZSxcbiAgICAgICAgICAgICAgcmVqZWN0Rm46IHJlamVjdCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBzZXRJZk5vdEVxdWFsKFxuICAgIGNhY2hlTmFtZTogc3RyaW5nLFxuICAgIGtleTogc3RyaW5nIHwgVWludDhBcnJheSxcbiAgICB2YWx1ZTogc3RyaW5nIHwgVWludDhBcnJheSxcbiAgICBub3RFcXVhbDogc3RyaW5nIHwgVWludDhBcnJheSxcbiAgICB0dGw/OiBudW1iZXJcbiAgKTogUHJvbWlzZTxDYWNoZVNldElmTm90RXF1YWwuUmVzcG9uc2U+IHtcbiAgICB0cnkge1xuICAgICAgdmFsaWRhdGVDYWNoZU5hbWUoY2FjaGVOYW1lKTtcbiAgICAgIGlmICh0dGwgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICB2YWxpZGF0ZVR0bFNlY29uZHModHRsKTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIHJldHVybiB0aGlzLmNhY2hlU2VydmljZUVycm9yTWFwcGVyLnJldHVybk9yVGhyb3dFcnJvcihcbiAgICAgICAgZXJyIGFzIEVycm9yLFxuICAgICAgICBlcnIgPT4gbmV3IENhY2hlU2V0SWZOb3RFcXVhbC5FcnJvcihlcnIpXG4gICAgICApO1xuICAgIH1cblxuICAgIHJldHVybiBhd2FpdCB0aGlzLnJhdGVMaW1pdGVkKGFzeW5jICgpID0+IHtcbiAgICAgIHJldHVybiBhd2FpdCB0aGlzLnNlbmRTZXRJZk5vdEVxdWFsKFxuICAgICAgICBjYWNoZU5hbWUsXG4gICAgICAgIHRoaXMuY29udmVydChrZXkpLFxuICAgICAgICB0aGlzLmNvbnZlcnQodmFsdWUpLFxuICAgICAgICB0aGlzLmNvbnZlcnQobm90RXF1YWwpLFxuICAgICAgICB0aGlzLnR0bE9yRGVmYXVsdE1pbGxpc2Vjb25kcyh0dGwpXG4gICAgICApO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBzZW5kU2V0SWZOb3RFcXVhbChcbiAgICBjYWNoZU5hbWU6IHN0cmluZyxcbiAgICBrZXk6IFVpbnQ4QXJyYXksXG4gICAgdmFsdWU6IFVpbnQ4QXJyYXksXG4gICAgbm90RXF1YWw6IFVpbnQ4QXJyYXksXG4gICAgdHRsTWlsbGlzZWNvbmRzOiBudW1iZXJcbiAgKTogUHJvbWlzZTxDYWNoZVNldElmTm90RXF1YWwuUmVzcG9uc2U+IHtcbiAgICBjb25zdCByZXF1ZXN0ID0gbmV3IGdycGNDYWNoZS5fU2V0SWZSZXF1ZXN0KHtcbiAgICAgIGNhY2hlX2tleToga2V5LFxuICAgICAgY2FjaGVfYm9keTogdmFsdWUsXG4gICAgICB0dGxfbWlsbGlzZWNvbmRzOiB0dGxNaWxsaXNlY29uZHMsXG4gICAgICBub3RfZXF1YWw6IG5ldyBOb3RFcXVhbCh7dmFsdWVfdG9fY2hlY2s6IG5vdEVxdWFsfSksXG4gICAgfSk7XG4gICAgY29uc3QgbWV0YWRhdGEgPSB0aGlzLmNyZWF0ZU1ldGFkYXRhKGNhY2hlTmFtZSk7XG5cbiAgICByZXR1cm4gYXdhaXQgbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgdGhpcy5jbGllbnRXcmFwcGVyLmdldENsaWVudCgpLlNldElmKFxuICAgICAgICByZXF1ZXN0LFxuICAgICAgICBtZXRhZGF0YSxcbiAgICAgICAge1xuICAgICAgICAgIGludGVyY2VwdG9yczogdGhpcy5pbnRlcmNlcHRvcnMsXG4gICAgICAgIH0sXG4gICAgICAgIChlcnIsIHJlc3ApID0+IHtcbiAgICAgICAgICBpZiAocmVzcCkge1xuICAgICAgICAgICAgc3dpdGNoIChyZXNwLnJlc3VsdCkge1xuICAgICAgICAgICAgICBjYXNlICdzdG9yZWQnOlxuICAgICAgICAgICAgICAgIHJlc29sdmUobmV3IENhY2hlU2V0SWZOb3RFcXVhbC5TdG9yZWQoKSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgIGNhc2UgJ25vdF9zdG9yZWQnOlxuICAgICAgICAgICAgICAgIHJlc29sdmUobmV3IENhY2hlU2V0SWZOb3RFcXVhbC5Ob3RTdG9yZWQoKSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgcmVzb2x2ZShcbiAgICAgICAgICAgICAgICAgIG5ldyBDYWNoZVNldElmTm90RXF1YWwuRXJyb3IoXG4gICAgICAgICAgICAgICAgICAgIG5ldyBVbmtub3duRXJyb3IoXG4gICAgICAgICAgICAgICAgICAgICAgJ1NldElmTm90RXF1YWwgcmVzcG9uZGVkIHdpdGggYW4gdW5rbm93biByZXN1bHQnXG4gICAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmNhY2hlU2VydmljZUVycm9yTWFwcGVyLnJlc29sdmVPclJlamVjdEVycm9yKHtcbiAgICAgICAgICAgICAgZXJyOiBlcnIsXG4gICAgICAgICAgICAgIGVycm9yUmVzcG9uc2VGYWN0b3J5Rm46IGUgPT4gbmV3IENhY2hlU2V0SWZOb3RFcXVhbC5FcnJvcihlKSxcbiAgICAgICAgICAgICAgcmVzb2x2ZUZuOiByZXNvbHZlLFxuICAgICAgICAgICAgICByZWplY3RGbjogcmVqZWN0LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICApO1xuICAgIH0pO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIHNldElmUHJlc2VudEFuZE5vdEVxdWFsKFxuICAgIGNhY2hlTmFtZTogc3RyaW5nLFxuICAgIGtleTogc3RyaW5nIHwgVWludDhBcnJheSxcbiAgICB2YWx1ZTogc3RyaW5nIHwgVWludDhBcnJheSxcbiAgICBub3RFcXVhbDogc3RyaW5nIHwgVWludDhBcnJheSxcbiAgICB0dGw/OiBudW1iZXJcbiAgKTogUHJvbWlzZTxDYWNoZVNldElmUHJlc2VudEFuZE5vdEVxdWFsLlJlc3BvbnNlPiB7XG4gICAgdHJ5IHtcbiAgICAgIHZhbGlkYXRlQ2FjaGVOYW1lKGNhY2hlTmFtZSk7XG4gICAgICBpZiAodHRsICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdmFsaWRhdGVUdGxTZWNvbmRzKHR0bCk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICByZXR1cm4gdGhpcy5jYWNoZVNlcnZpY2VFcnJvck1hcHBlci5yZXR1cm5PclRocm93RXJyb3IoXG4gICAgICAgIGVyciBhcyBFcnJvcixcbiAgICAgICAgZXJyID0+IG5ldyBDYWNoZVNldElmUHJlc2VudEFuZE5vdEVxdWFsLkVycm9yKGVycilcbiAgICAgICk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGF3YWl0IHRoaXMucmF0ZUxpbWl0ZWQoYXN5bmMgKCkgPT4ge1xuICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuc2VuZFNldElmUHJlc2VudEFuZE5vdEVxdWFsKFxuICAgICAgICBjYWNoZU5hbWUsXG4gICAgICAgIHRoaXMuY29udmVydChrZXkpLFxuICAgICAgICB0aGlzLmNvbnZlcnQodmFsdWUpLFxuICAgICAgICB0aGlzLmNvbnZlcnQobm90RXF1YWwpLFxuICAgICAgICB0aGlzLnR0bE9yRGVmYXVsdE1pbGxpc2Vjb25kcyh0dGwpXG4gICAgICApO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBzZW5kU2V0SWZQcmVzZW50QW5kTm90RXF1YWwoXG4gICAgY2FjaGVOYW1lOiBzdHJpbmcsXG4gICAga2V5OiBVaW50OEFycmF5LFxuICAgIHZhbHVlOiBVaW50OEFycmF5LFxuICAgIG5vdEVxdWFsOiBVaW50OEFycmF5LFxuICAgIHR0bE1pbGxpc2Vjb25kczogbnVtYmVyXG4gICk6IFByb21pc2U8Q2FjaGVTZXRJZlByZXNlbnRBbmROb3RFcXVhbC5SZXNwb25zZT4ge1xuICAgIGNvbnN0IHJlcXVlc3QgPSBuZXcgZ3JwY0NhY2hlLl9TZXRJZlJlcXVlc3Qoe1xuICAgICAgY2FjaGVfa2V5OiBrZXksXG4gICAgICBjYWNoZV9ib2R5OiB2YWx1ZSxcbiAgICAgIHR0bF9taWxsaXNlY29uZHM6IHR0bE1pbGxpc2Vjb25kcyxcbiAgICAgIHByZXNlbnRfYW5kX25vdF9lcXVhbDogbmV3IFByZXNlbnRBbmROb3RFcXVhbCh7dmFsdWVfdG9fY2hlY2s6IG5vdEVxdWFsfSksXG4gICAgfSk7XG4gICAgY29uc3QgbWV0YWRhdGEgPSB0aGlzLmNyZWF0ZU1ldGFkYXRhKGNhY2hlTmFtZSk7XG5cbiAgICByZXR1cm4gYXdhaXQgbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgdGhpcy5jbGllbnRXcmFwcGVyLmdldENsaWVudCgpLlNldElmKFxuICAgICAgICByZXF1ZXN0LFxuICAgICAgICBtZXRhZGF0YSxcbiAgICAgICAge1xuICAgICAgICAgIGludGVyY2VwdG9yczogdGhpcy5pbnRlcmNlcHRvcnMsXG4gICAgICAgIH0sXG4gICAgICAgIChlcnIsIHJlc3ApID0+IHtcbiAgICAgICAgICBpZiAocmVzcCkge1xuICAgICAgICAgICAgc3dpdGNoIChyZXNwLnJlc3VsdCkge1xuICAgICAgICAgICAgICBjYXNlICdzdG9yZWQnOlxuICAgICAgICAgICAgICAgIHJlc29sdmUobmV3IENhY2hlU2V0SWZQcmVzZW50QW5kTm90RXF1YWwuU3RvcmVkKCkpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICBjYXNlICdub3Rfc3RvcmVkJzpcbiAgICAgICAgICAgICAgICByZXNvbHZlKG5ldyBDYWNoZVNldElmUHJlc2VudEFuZE5vdEVxdWFsLk5vdFN0b3JlZCgpKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICByZXNvbHZlKFxuICAgICAgICAgICAgICAgICAgbmV3IENhY2hlU2V0SWZQcmVzZW50QW5kTm90RXF1YWwuRXJyb3IoXG4gICAgICAgICAgICAgICAgICAgIG5ldyBVbmtub3duRXJyb3IoXG4gICAgICAgICAgICAgICAgICAgICAgJ1NldElmUHJlc2VudEFuZE5vdEVxdWFsIHJlc3BvbmRlZCB3aXRoIGFuIHVua25vd24gcmVzdWx0J1xuICAgICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5jYWNoZVNlcnZpY2VFcnJvck1hcHBlci5yZXNvbHZlT3JSZWplY3RFcnJvcih7XG4gICAgICAgICAgICAgIGVycjogZXJyLFxuICAgICAgICAgICAgICBlcnJvclJlc3BvbnNlRmFjdG9yeUZuOiBlID0+XG4gICAgICAgICAgICAgICAgbmV3IENhY2hlU2V0SWZQcmVzZW50QW5kTm90RXF1YWwuRXJyb3IoZSksXG4gICAgICAgICAgICAgIHJlc29sdmVGbjogcmVzb2x2ZSxcbiAgICAgICAgICAgICAgcmVqZWN0Rm46IHJlamVjdCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBzZXRJZkFic2VudE9yRXF1YWwoXG4gICAgY2FjaGVOYW1lOiBzdHJpbmcsXG4gICAga2V5OiBzdHJpbmcgfCBVaW50OEFycmF5LFxuICAgIHZhbHVlOiBzdHJpbmcgfCBVaW50OEFycmF5LFxuICAgIGVxdWFsOiBzdHJpbmcgfCBVaW50OEFycmF5LFxuICAgIHR0bD86IG51bWJlclxuICApOiBQcm9taXNlPENhY2hlU2V0SWZBYnNlbnRPckVxdWFsLlJlc3BvbnNlPiB7XG4gICAgdHJ5IHtcbiAgICAgIHZhbGlkYXRlQ2FjaGVOYW1lKGNhY2hlTmFtZSk7XG4gICAgICBpZiAodHRsICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdmFsaWRhdGVUdGxTZWNvbmRzKHR0bCk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICByZXR1cm4gdGhpcy5jYWNoZVNlcnZpY2VFcnJvck1hcHBlci5yZXR1cm5PclRocm93RXJyb3IoXG4gICAgICAgIGVyciBhcyBFcnJvcixcbiAgICAgICAgZXJyID0+IG5ldyBDYWNoZVNldElmQWJzZW50T3JFcXVhbC5FcnJvcihlcnIpXG4gICAgICApO1xuICAgIH1cblxuICAgIHJldHVybiBhd2FpdCB0aGlzLnJhdGVMaW1pdGVkKGFzeW5jICgpID0+IHtcbiAgICAgIHJldHVybiBhd2FpdCB0aGlzLnNlbmRTZXRJZkFic2VudE9yRXF1YWwoXG4gICAgICAgIGNhY2hlTmFtZSxcbiAgICAgICAgdGhpcy5jb252ZXJ0KGtleSksXG4gICAgICAgIHRoaXMuY29udmVydCh2YWx1ZSksXG4gICAgICAgIHRoaXMuY29udmVydChlcXVhbCksXG4gICAgICAgIHRoaXMudHRsT3JEZWZhdWx0TWlsbGlzZWNvbmRzKHR0bClcbiAgICAgICk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHNlbmRTZXRJZkFic2VudE9yRXF1YWwoXG4gICAgY2FjaGVOYW1lOiBzdHJpbmcsXG4gICAga2V5OiBVaW50OEFycmF5LFxuICAgIHZhbHVlOiBVaW50OEFycmF5LFxuICAgIGVxdWFsOiBVaW50OEFycmF5LFxuICAgIHR0bE1pbGxpc2Vjb25kczogbnVtYmVyXG4gICk6IFByb21pc2U8Q2FjaGVTZXRJZkFic2VudE9yRXF1YWwuUmVzcG9uc2U+IHtcbiAgICBjb25zdCByZXF1ZXN0ID0gbmV3IGdycGNDYWNoZS5fU2V0SWZSZXF1ZXN0KHtcbiAgICAgIGNhY2hlX2tleToga2V5LFxuICAgICAgY2FjaGVfYm9keTogdmFsdWUsXG4gICAgICB0dGxfbWlsbGlzZWNvbmRzOiB0dGxNaWxsaXNlY29uZHMsXG4gICAgICBhYnNlbnRfb3JfZXF1YWw6IG5ldyBBYnNlbnRPckVxdWFsKHt2YWx1ZV90b19jaGVjazogZXF1YWx9KSxcbiAgICB9KTtcbiAgICBjb25zdCBtZXRhZGF0YSA9IHRoaXMuY3JlYXRlTWV0YWRhdGEoY2FjaGVOYW1lKTtcblxuICAgIHJldHVybiBhd2FpdCBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICB0aGlzLmNsaWVudFdyYXBwZXIuZ2V0Q2xpZW50KCkuU2V0SWYoXG4gICAgICAgIHJlcXVlc3QsXG4gICAgICAgIG1ldGFkYXRhLFxuICAgICAgICB7XG4gICAgICAgICAgaW50ZXJjZXB0b3JzOiB0aGlzLmludGVyY2VwdG9ycyxcbiAgICAgICAgfSxcbiAgICAgICAgKGVyciwgcmVzcCkgPT4ge1xuICAgICAgICAgIGlmIChyZXNwKSB7XG4gICAgICAgICAgICBzd2l0Y2ggKHJlc3AucmVzdWx0KSB7XG4gICAgICAgICAgICAgIGNhc2UgJ3N0b3JlZCc6XG4gICAgICAgICAgICAgICAgcmVzb2x2ZShuZXcgQ2FjaGVTZXRJZkFic2VudE9yRXF1YWwuU3RvcmVkKCkpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICBjYXNlICdub3Rfc3RvcmVkJzpcbiAgICAgICAgICAgICAgICByZXNvbHZlKG5ldyBDYWNoZVNldElmQWJzZW50T3JFcXVhbC5Ob3RTdG9yZWQoKSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgcmVzb2x2ZShcbiAgICAgICAgICAgICAgICAgIG5ldyBDYWNoZVNldElmQWJzZW50T3JFcXVhbC5FcnJvcihcbiAgICAgICAgICAgICAgICAgICAgbmV3IFVua25vd25FcnJvcihcbiAgICAgICAgICAgICAgICAgICAgICAnU2V0SWZBYnNlbnRPckVxdWFsIHJlc3BvbmRlZCB3aXRoIGFuIHVua25vd24gcmVzdWx0J1xuICAgICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5jYWNoZVNlcnZpY2VFcnJvck1hcHBlci5yZXNvbHZlT3JSZWplY3RFcnJvcih7XG4gICAgICAgICAgICAgIGVycjogZXJyLFxuICAgICAgICAgICAgICBlcnJvclJlc3BvbnNlRmFjdG9yeUZuOiBlID0+IG5ldyBDYWNoZVNldElmQWJzZW50T3JFcXVhbC5FcnJvcihlKSxcbiAgICAgICAgICAgICAgcmVzb2x2ZUZuOiByZXNvbHZlLFxuICAgICAgICAgICAgICByZWplY3RGbjogcmVqZWN0LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICApO1xuICAgIH0pO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIGRlbGV0ZShcbiAgICBjYWNoZU5hbWU6IHN0cmluZyxcbiAgICBrZXk6IHN0cmluZyB8IFVpbnQ4QXJyYXlcbiAgKTogUHJvbWlzZTxDYWNoZURlbGV0ZS5SZXNwb25zZT4ge1xuICAgIHRyeSB7XG4gICAgICB2YWxpZGF0ZUNhY2hlTmFtZShjYWNoZU5hbWUpO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgcmV0dXJuIHRoaXMuY2FjaGVTZXJ2aWNlRXJyb3JNYXBwZXIucmV0dXJuT3JUaHJvd0Vycm9yKFxuICAgICAgICBlcnIgYXMgRXJyb3IsXG4gICAgICAgIGVyciA9PiBuZXcgQ2FjaGVEZWxldGUuRXJyb3IoZXJyKVxuICAgICAgKTtcbiAgICB9XG5cbiAgICByZXR1cm4gYXdhaXQgdGhpcy5yYXRlTGltaXRlZChhc3luYyAoKSA9PiB7XG4gICAgICByZXR1cm4gYXdhaXQgdGhpcy5zZW5kRGVsZXRlKGNhY2hlTmFtZSwgdGhpcy5jb252ZXJ0KGtleSkpO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBzZW5kRGVsZXRlKFxuICAgIGNhY2hlTmFtZTogc3RyaW5nLFxuICAgIGtleTogVWludDhBcnJheVxuICApOiBQcm9taXNlPENhY2hlRGVsZXRlLlJlc3BvbnNlPiB7XG4gICAgY29uc3QgcmVxdWVzdCA9IG5ldyBncnBjQ2FjaGUuX0RlbGV0ZVJlcXVlc3Qoe1xuICAgICAgY2FjaGVfa2V5OiBrZXksXG4gICAgfSk7XG4gICAgY29uc3QgbWV0YWRhdGEgPSB0aGlzLmNyZWF0ZU1ldGFkYXRhKGNhY2hlTmFtZSk7XG4gICAgcmV0dXJuIGF3YWl0IG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHRoaXMuY2xpZW50V3JhcHBlci5nZXRDbGllbnQoKS5EZWxldGUoXG4gICAgICAgIHJlcXVlc3QsXG4gICAgICAgIG1ldGFkYXRhLFxuICAgICAgICB7XG4gICAgICAgICAgaW50ZXJjZXB0b3JzOiB0aGlzLmludGVyY2VwdG9ycyxcbiAgICAgICAgfSxcbiAgICAgICAgKGVyciwgcmVzcCkgPT4ge1xuICAgICAgICAgIGlmIChyZXNwKSB7XG4gICAgICAgICAgICByZXNvbHZlKG5ldyBDYWNoZURlbGV0ZS5TdWNjZXNzKCkpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmNhY2hlU2VydmljZUVycm9yTWFwcGVyLnJlc29sdmVPclJlamVjdEVycm9yKHtcbiAgICAgICAgICAgICAgZXJyOiBlcnIsXG4gICAgICAgICAgICAgIGVycm9yUmVzcG9uc2VGYWN0b3J5Rm46IGUgPT4gbmV3IENhY2hlRGVsZXRlLkVycm9yKGUpLFxuICAgICAgICAgICAgICByZXNvbHZlRm46IHJlc29sdmUsXG4gICAgICAgICAgICAgIHJlamVjdEZuOiByZWplY3QsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICk7XG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgZ2V0KFxuICAgIGNhY2hlTmFtZTogc3RyaW5nLFxuICAgIGtleTogc3RyaW5nIHwgVWludDhBcnJheSxcbiAgICBvcHRpb25zPzogR2V0Q2FsbE9wdGlvbnNcbiAgKTogUHJvbWlzZTxDYWNoZUdldC5SZXNwb25zZT4ge1xuICAgIHRyeSB7XG4gICAgICB2YWxpZGF0ZUNhY2hlTmFtZShjYWNoZU5hbWUpO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgcmV0dXJuIHRoaXMuY2FjaGVTZXJ2aWNlRXJyb3JNYXBwZXIucmV0dXJuT3JUaHJvd0Vycm9yKFxuICAgICAgICBlcnIgYXMgRXJyb3IsXG4gICAgICAgIGVyciA9PiBuZXcgQ2FjaGVHZXQuRXJyb3IoZXJyKVxuICAgICAgKTtcbiAgICB9XG5cbiAgICByZXR1cm4gYXdhaXQgdGhpcy5yYXRlTGltaXRlZChhc3luYyAoKSA9PiB7XG4gICAgICByZXR1cm4gYXdhaXQgdGhpcy5zZW5kR2V0KGNhY2hlTmFtZSwgdGhpcy5jb252ZXJ0KGtleSksIG9wdGlvbnMpO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBzZW5kR2V0KFxuICAgIGNhY2hlTmFtZTogc3RyaW5nLFxuICAgIGtleTogVWludDhBcnJheSxcbiAgICBvcHRpb25zPzogR2V0Q2FsbE9wdGlvbnNcbiAgKTogUHJvbWlzZTxDYWNoZUdldC5SZXNwb25zZT4ge1xuICAgIGNvbnN0IHJlcXVlc3QgPSBuZXcgZ3JwY0NhY2hlLl9HZXRSZXF1ZXN0KHtcbiAgICAgIGNhY2hlX2tleToga2V5LFxuICAgIH0pO1xuICAgIGNvbnN0IG1ldGFkYXRhID0gdGhpcy5jcmVhdGVNZXRhZGF0YShjYWNoZU5hbWUpO1xuXG4gICAgcmV0dXJuIGF3YWl0IG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHRoaXMuY2xpZW50V3JhcHBlci5nZXRDbGllbnQoKS5HZXQoXG4gICAgICAgIHJlcXVlc3QsXG4gICAgICAgIG1ldGFkYXRhLFxuICAgICAgICB7XG4gICAgICAgICAgaW50ZXJjZXB0b3JzOiB0aGlzLmludGVyY2VwdG9ycyxcbiAgICAgICAgfSxcbiAgICAgICAgKGVyciwgcmVzcCkgPT4ge1xuICAgICAgICAgIGlmIChyZXNwKSB7XG4gICAgICAgICAgICBzd2l0Y2ggKHJlc3AucmVzdWx0KSB7XG4gICAgICAgICAgICAgIGNhc2UgZ3JwY0NhY2hlLkVDYWNoZVJlc3VsdC5NaXNzOlxuICAgICAgICAgICAgICAgIHJlc29sdmUobmV3IENhY2hlR2V0Lk1pc3MoKSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgIGNhc2UgZ3JwY0NhY2hlLkVDYWNoZVJlc3VsdC5IaXQ6IHtcbiAgICAgICAgICAgICAgICBjb25zdCBzaG91bGREZWNvbXByZXNzID1cbiAgICAgICAgICAgICAgICAgIG9wdGlvbnM/LmRlY29tcHJlc3MgPz9cbiAgICAgICAgICAgICAgICAgIHRoaXMuY29tcHJlc3Npb25EZXRhaWxzPy5hdXRvRGVjb21wcmVzc0VuYWJsZWQgPT09IHRydWU7XG4gICAgICAgICAgICAgICAgaWYgKCFzaG91bGREZWNvbXByZXNzKSB7XG4gICAgICAgICAgICAgICAgICByZXNvbHZlKG5ldyBDYWNoZUdldC5IaXQocmVzcC5jYWNoZV9ib2R5KSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgIGlmICh0aGlzLmNvbXByZXNzaW9uRGV0YWlscyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUoXG4gICAgICAgICAgICAgICAgICAgICAgbmV3IENhY2hlR2V0LkVycm9yKFxuICAgICAgICAgICAgICAgICAgICAgICAgbmV3IENvbXByZXNzaW9uRXJyb3IoJ0NhY2hlQ2xpZW50LkdldCcsICdkZWNvbXByZXNzJylcbiAgICAgICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbXByZXNzaW9uRGV0YWlscy52YWx1ZUNvbXByZXNzb3JcbiAgICAgICAgICAgICAgICAgICAgICAuZGVjb21wcmVzc0lmQ29tcHJlc3NlZChyZXNwLmNhY2hlX2JvZHkpXG4gICAgICAgICAgICAgICAgICAgICAgLnRoZW4odiA9PiByZXNvbHZlKG5ldyBDYWNoZUdldC5IaXQodikpKVxuICAgICAgICAgICAgICAgICAgICAgIC5jYXRjaChlID0+XG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L3Jlc3RyaWN0LXRlbXBsYXRlLWV4cHJlc3Npb25zXG4gICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBDYWNoZUdldC5FcnJvcihuZXcgSW52YWxpZEFyZ3VtZW50RXJyb3IoYCR7ZX1gKSlcbiAgICAgICAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBjYXNlIGdycGNDYWNoZS5FQ2FjaGVSZXN1bHQuSW52YWxpZDpcbiAgICAgICAgICAgICAgY2FzZSBncnBjQ2FjaGUuRUNhY2hlUmVzdWx0Lk9rOlxuICAgICAgICAgICAgICAgIHJlc29sdmUobmV3IENhY2hlR2V0LkVycm9yKG5ldyBVbmtub3duRXJyb3IocmVzcC5tZXNzYWdlKSkpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIHJlc29sdmUoXG4gICAgICAgICAgICAgICAgICBuZXcgQ2FjaGVHZXQuRXJyb3IoXG4gICAgICAgICAgICAgICAgICAgIG5ldyBVbmtub3duRXJyb3IoXG4gICAgICAgICAgICAgICAgICAgICAgJ0FuIHVua25vd24gZXJyb3Igb2NjdXJyZWQ6ICcgKyByZXNwLm1lc3NhZ2VcbiAgICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuY2FjaGVTZXJ2aWNlRXJyb3JNYXBwZXIucmVzb2x2ZU9yUmVqZWN0RXJyb3Ioe1xuICAgICAgICAgICAgICBlcnI6IGVycixcbiAgICAgICAgICAgICAgZXJyb3JSZXNwb25zZUZhY3RvcnlGbjogZSA9PiBuZXcgQ2FjaGVHZXQuRXJyb3IoZSksXG4gICAgICAgICAgICAgIHJlc29sdmVGbjogcmVzb2x2ZSxcbiAgICAgICAgICAgICAgcmVqZWN0Rm46IHJlamVjdCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBnZXRCYXRjaChcbiAgICBjYWNoZU5hbWU6IHN0cmluZyxcbiAgICBrZXlzOiBBcnJheTxzdHJpbmcgfCBVaW50OEFycmF5PixcbiAgICBvcHRpb25zPzogR2V0QmF0Y2hDYWxsT3B0aW9uc1xuICApOiBQcm9taXNlPENhY2hlR2V0QmF0Y2guUmVzcG9uc2U+IHtcbiAgICB0cnkge1xuICAgICAgdmFsaWRhdGVDYWNoZU5hbWUoY2FjaGVOYW1lKTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIHJldHVybiB0aGlzLmNhY2hlU2VydmljZUVycm9yTWFwcGVyLnJldHVybk9yVGhyb3dFcnJvcihcbiAgICAgICAgZXJyIGFzIEVycm9yLFxuICAgICAgICBlcnIgPT4gbmV3IENhY2hlR2V0QmF0Y2guRXJyb3IoZXJyKVxuICAgICAgKTtcbiAgICB9XG5cbiAgICByZXR1cm4gYXdhaXQgdGhpcy5yYXRlTGltaXRlZChhc3luYyAoKSA9PiB7XG4gICAgICByZXR1cm4gYXdhaXQgdGhpcy5zZW5kR2V0QmF0Y2goXG4gICAgICAgIGNhY2hlTmFtZSxcbiAgICAgICAga2V5cy5tYXAoa2V5ID0+IHRoaXMuY29udmVydChrZXkpKSxcbiAgICAgICAgb3B0aW9ucz8uZGVjb21wcmVzc1xuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgc2VuZEdldEJhdGNoKFxuICAgIGNhY2hlTmFtZTogc3RyaW5nLFxuICAgIGtleXM6IFVpbnQ4QXJyYXlbXSxcbiAgICBkZWNvbXByZXNzPzogYm9vbGVhblxuICApOiBQcm9taXNlPENhY2hlR2V0QmF0Y2guUmVzcG9uc2U+IHtcbiAgICBjb25zdCBnZXRSZXF1ZXN0cyA9IFtdO1xuICAgIGZvciAoY29uc3QgayBvZiBrZXlzKSB7XG4gICAgICBjb25zdCBnZXRSZXF1ZXN0ID0gbmV3IGdycGNDYWNoZS5fR2V0UmVxdWVzdCh7XG4gICAgICAgIGNhY2hlX2tleTogayxcbiAgICAgIH0pO1xuICAgICAgZ2V0UmVxdWVzdHMucHVzaChnZXRSZXF1ZXN0KTtcbiAgICB9XG4gICAgY29uc3QgcmVxdWVzdCA9IG5ldyBncnBjQ2FjaGUuX0dldEJhdGNoUmVxdWVzdCh7XG4gICAgICBpdGVtczogZ2V0UmVxdWVzdHMsXG4gICAgfSk7XG4gICAgY29uc3QgbWV0YWRhdGEgPSB0aGlzLmNyZWF0ZU1ldGFkYXRhKGNhY2hlTmFtZSk7XG5cbiAgICBjb25zdCBjYWxsID0gdGhpcy5jbGllbnRXcmFwcGVyLmdldENsaWVudCgpLkdldEJhdGNoKHJlcXVlc3QsIG1ldGFkYXRhLCB7XG4gICAgICBpbnRlcmNlcHRvcnM6IHRoaXMuc3RyZWFtaW5nSW50ZXJjZXB0b3JzLFxuICAgIH0pO1xuXG4gICAgcmV0dXJuIGF3YWl0IG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIGNvbnN0IHJlc3VsdHM6IENhY2hlR2V0LlJlc3BvbnNlW10gPSBbXTtcbiAgICAgIGNhbGwub24oJ2RhdGEnLCAoZ2V0UmVzcG9uc2U6IGdycGNDYWNoZS5fR2V0UmVzcG9uc2UpID0+IHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gZ2V0UmVzcG9uc2UucmVzdWx0O1xuICAgICAgICBzd2l0Y2ggKHJlc3VsdCkge1xuICAgICAgICAgIGNhc2UgZ3JwY0NhY2hlLkVDYWNoZVJlc3VsdC5IaXQ6XG4gICAgICAgICAgICByZXN1bHRzLnB1c2gobmV3IENhY2hlR2V0LkhpdChnZXRSZXNwb25zZS5jYWNoZV9ib2R5KSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBjYXNlIGdycGNDYWNoZS5FQ2FjaGVSZXN1bHQuTWlzczpcbiAgICAgICAgICAgIHJlc3VsdHMucHVzaChuZXcgQ2FjaGVHZXQuTWlzcygpKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICByZXN1bHRzLnB1c2goXG4gICAgICAgICAgICAgIG5ldyBDYWNoZUdldC5FcnJvcihuZXcgVW5rbm93bkVycm9yKGdldFJlc3BvbnNlLm1lc3NhZ2UpKVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIGNhbGwub24oJ2VuZCcsICgpID0+IHtcbiAgICAgICAgY29uc3Qgc2hvdWxkRGVjb21wcmVzcyA9XG4gICAgICAgICAgZGVjb21wcmVzcyA/PyB0aGlzLmNvbXByZXNzaW9uRGV0YWlscz8uYXV0b0RlY29tcHJlc3NFbmFibGVkID09PSB0cnVlO1xuICAgICAgICBpZiAoIXNob3VsZERlY29tcHJlc3MpIHtcbiAgICAgICAgICByZXNvbHZlKG5ldyBDYWNoZUdldEJhdGNoLlN1Y2Nlc3MocmVzdWx0cywga2V5cykpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGlmICh0aGlzLmNvbXByZXNzaW9uRGV0YWlscyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXNvbHZlKFxuICAgICAgICAgICAgICBuZXcgQ2FjaGVHZXRCYXRjaC5FcnJvcihcbiAgICAgICAgICAgICAgICBuZXcgQ29tcHJlc3Npb25FcnJvcignQ2FjaGVDbGllbnQuR2V0JywgJ2RlY29tcHJlc3MnKVxuICAgICAgICAgICAgICApXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBjb21wcmVzc29yOiBJQ29tcHJlc3Npb24gPVxuICAgICAgICAgICAgICB0aGlzLmNvbXByZXNzaW9uRGV0YWlscy52YWx1ZUNvbXByZXNzb3I7XG4gICAgICAgICAgICBQcm9taXNlLmFsbChcbiAgICAgICAgICAgICAgcmVzdWx0cy5tYXAoYXN5bmMgciA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHIgaW5zdGFuY2VvZiBDYWNoZUdldC5IaXQpIHtcbiAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgQ2FjaGVHZXQuSGl0KFxuICAgICAgICAgICAgICAgICAgICBhd2FpdCBjb21wcmVzc29yLmRlY29tcHJlc3NJZkNvbXByZXNzZWQoci52YWx1ZVVpbnQ4QXJyYXkoKSlcbiAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiByO1xuICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAudGhlbihkZWNvbXByZXNzZWRSZXN1bHRzID0+XG4gICAgICAgICAgICAgICAgcmVzb2x2ZShuZXcgQ2FjaGVHZXRCYXRjaC5TdWNjZXNzKGRlY29tcHJlc3NlZFJlc3VsdHMsIGtleXMpKVxuICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgIC5jYXRjaChlID0+XG4gICAgICAgICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9yZXN0cmljdC10ZW1wbGF0ZS1leHByZXNzaW9uc1xuICAgICAgICAgICAgICAgIHJlc29sdmUobmV3IENhY2hlR2V0QmF0Y2guRXJyb3IobmV3IFVua25vd25FcnJvcihgJHtlfWApKSlcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICBjYWxsLm9uKCdlcnJvcicsIChlcnI6IFNlcnZpY2VFcnJvciB8IG51bGwpID0+IHtcbiAgICAgICAgdGhpcy5jYWNoZVNlcnZpY2VFcnJvck1hcHBlci5yZXNvbHZlT3JSZWplY3RFcnJvcih7XG4gICAgICAgICAgZXJyOiBlcnIsXG4gICAgICAgICAgZXJyb3JSZXNwb25zZUZhY3RvcnlGbjogZSA9PiBuZXcgQ2FjaGVHZXRCYXRjaC5FcnJvcihlKSxcbiAgICAgICAgICByZXNvbHZlRm46IHJlc29sdmUsXG4gICAgICAgICAgcmVqZWN0Rm46IHJlamVjdCxcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBzZXRCYXRjaChcbiAgICBjYWNoZU5hbWU6IHN0cmluZyxcbiAgICBpdGVtczpcbiAgICAgIHwgUmVjb3JkPHN0cmluZywgc3RyaW5nIHwgVWludDhBcnJheT5cbiAgICAgIHwgTWFwPHN0cmluZyB8IFVpbnQ4QXJyYXksIHN0cmluZyB8IFVpbnQ4QXJyYXk+XG4gICAgICB8IEFycmF5PFNldEJhdGNoSXRlbT4sXG4gICAgb3B0aW9ucz86IFNldEJhdGNoQ2FsbE9wdGlvbnNcbiAgKTogUHJvbWlzZTxDYWNoZVNldEJhdGNoLlJlc3BvbnNlPiB7XG4gICAgdHJ5IHtcbiAgICAgIHZhbGlkYXRlQ2FjaGVOYW1lKGNhY2hlTmFtZSk7XG4gICAgICBpZiAob3B0aW9ucz8udHRsICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdmFsaWRhdGVUdGxTZWNvbmRzKG9wdGlvbnM/LnR0bCk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICByZXR1cm4gdGhpcy5jYWNoZVNlcnZpY2VFcnJvck1hcHBlci5yZXR1cm5PclRocm93RXJyb3IoXG4gICAgICAgIGVyciBhcyBFcnJvcixcbiAgICAgICAgZXJyID0+IG5ldyBDYWNoZVNldEJhdGNoLkVycm9yKGVycilcbiAgICAgICk7XG4gICAgfVxuXG4gICAgY29uc3QgdHRsVG9Vc2UgPSBvcHRpb25zPy50dGwgfHwgdGhpcy5kZWZhdWx0VHRsU2Vjb25kcztcblxuICAgIHJldHVybiBhd2FpdCB0aGlzLnJhdGVMaW1pdGVkKGFzeW5jICgpID0+IHtcbiAgICAgIGxldCBpdGVtc1RvVXNlOiBbVWludDhBcnJheSwgVWludDhBcnJheSwgbnVtYmVyXVtdID1cbiAgICAgICAgdGhpcy5jb252ZXJ0U2V0QmF0Y2hFbGVtZW50cyhpdGVtcywgdHRsVG9Vc2UpO1xuICAgICAgaWYgKG9wdGlvbnM/LmNvbXByZXNzKSB7XG4gICAgICAgIHRoaXMubG9nZ2VyLnRyYWNlKFxuICAgICAgICAgICdDYWNoZUNsaWVudC5zZXRCYXRjaDsgY29tcHJlc3Npb24gZW5hYmxlZCwgY2FsbGluZyB2YWx1ZSBjb21wcmVzc29yJ1xuICAgICAgICApO1xuICAgICAgICBpZiAodGhpcy5jb21wcmVzc2lvbkRldGFpbHMgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHJldHVybiB0aGlzLmNhY2hlU2VydmljZUVycm9yTWFwcGVyLnJldHVybk9yVGhyb3dFcnJvcihcbiAgICAgICAgICAgIG5ldyBDb21wcmVzc2lvbkVycm9yKCdDYWNoZUNsaWVudC5zZXRCYXRjaCcsICdjb21wcmVzcycpLFxuICAgICAgICAgICAgZXJyID0+IG5ldyBDYWNoZVNldEJhdGNoLkVycm9yKGVycilcbiAgICAgICAgICApO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbnN0IGNvbXByZXNzb3I6IElDb21wcmVzc2lvbiA9XG4gICAgICAgICAgICB0aGlzLmNvbXByZXNzaW9uRGV0YWlscy52YWx1ZUNvbXByZXNzb3I7XG4gICAgICAgICAgY29uc3QgY29tcHJlc3Npb25MZXZlbDogQ29tcHJlc3Npb25MZXZlbCA9XG4gICAgICAgICAgICB0aGlzLmNvbXByZXNzaW9uRGV0YWlscy5jb21wcmVzc2lvbkxldmVsO1xuICAgICAgICAgIGl0ZW1zVG9Vc2UgPSBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgICAgICAgIGl0ZW1zVG9Vc2UubWFwKGFzeW5jIChba2V5LCB2YWx1ZSwgdHRsXSkgPT4ge1xuICAgICAgICAgICAgICByZXR1cm4gW1xuICAgICAgICAgICAgICAgIGtleSxcbiAgICAgICAgICAgICAgICBhd2FpdCBjb21wcmVzc29yLmNvbXByZXNzKGNvbXByZXNzaW9uTGV2ZWwsIHZhbHVlKSxcbiAgICAgICAgICAgICAgICB0dGwsXG4gICAgICAgICAgICAgIF07XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuc2VuZFNldEJhdGNoKGNhY2hlTmFtZSwgaXRlbXNUb1VzZSk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHNlbmRTZXRCYXRjaChcbiAgICBjYWNoZU5hbWU6IHN0cmluZyxcbiAgICBpdGVtczogW1VpbnQ4QXJyYXksIFVpbnQ4QXJyYXksIG51bWJlcl1bXVxuICApOiBQcm9taXNlPENhY2hlU2V0QmF0Y2guUmVzcG9uc2U+IHtcbiAgICBjb25zdCBzZXRSZXF1ZXN0cyA9IFtdO1xuICAgIGZvciAoY29uc3QgaXRlbSBvZiBpdGVtcykge1xuICAgICAgY29uc3Qgc2V0UmVxdWVzdCA9IG5ldyBncnBjQ2FjaGUuX1NldFJlcXVlc3Qoe1xuICAgICAgICBjYWNoZV9rZXk6IGl0ZW1bMF0sXG4gICAgICAgIGNhY2hlX2JvZHk6IGl0ZW1bMV0sXG4gICAgICAgIHR0bF9taWxsaXNlY29uZHM6IHNlY29uZHNUb01pbGxpc2Vjb25kcyhpdGVtWzJdKSxcbiAgICAgIH0pO1xuICAgICAgc2V0UmVxdWVzdHMucHVzaChzZXRSZXF1ZXN0KTtcbiAgICB9XG4gICAgY29uc3QgcmVxdWVzdCA9IG5ldyBncnBjQ2FjaGUuX1NldEJhdGNoUmVxdWVzdCh7XG4gICAgICBpdGVtczogc2V0UmVxdWVzdHMsXG4gICAgfSk7XG5cbiAgICBjb25zdCBtZXRhZGF0YSA9IHRoaXMuY3JlYXRlTWV0YWRhdGEoY2FjaGVOYW1lKTtcblxuICAgIGNvbnN0IGNhbGwgPSB0aGlzLmNsaWVudFdyYXBwZXIuZ2V0Q2xpZW50KCkuU2V0QmF0Y2gocmVxdWVzdCwgbWV0YWRhdGEsIHtcbiAgICAgIGludGVyY2VwdG9yczogdGhpcy5zdHJlYW1pbmdJbnRlcmNlcHRvcnMsXG4gICAgfSk7XG5cbiAgICByZXR1cm4gYXdhaXQgbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgY29uc3QgcmVzdWx0czogQ2FjaGVTZXQuUmVzcG9uc2VbXSA9IFtdO1xuICAgICAgY2FsbC5vbignZGF0YScsIChzZXRSZXNwb25zZTogZ3JwY0NhY2hlLl9TZXRSZXNwb25zZSkgPT4ge1xuICAgICAgICBjb25zdCByZXN1bHQgPSBzZXRSZXNwb25zZS5yZXN1bHQ7XG4gICAgICAgIHN3aXRjaCAocmVzdWx0KSB7XG4gICAgICAgICAgY2FzZSBncnBjQ2FjaGUuRUNhY2hlUmVzdWx0Lk9rOlxuICAgICAgICAgICAgcmVzdWx0cy5wdXNoKG5ldyBDYWNoZVNldC5TdWNjZXNzKCkpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIHJlc3VsdHMucHVzaChcbiAgICAgICAgICAgICAgbmV3IENhY2hlU2V0LkVycm9yKG5ldyBVbmtub3duRXJyb3Ioc2V0UmVzcG9uc2UubWVzc2FnZSkpXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgY2FsbC5vbignZW5kJywgKCkgPT4ge1xuICAgICAgICByZXNvbHZlKG5ldyBDYWNoZVNldEJhdGNoLlN1Y2Nlc3MocmVzdWx0cykpO1xuICAgICAgfSk7XG5cbiAgICAgIGNhbGwub24oJ2Vycm9yJywgKGVycjogU2VydmljZUVycm9yIHwgbnVsbCkgPT4ge1xuICAgICAgICB0aGlzLmNhY2hlU2VydmljZUVycm9yTWFwcGVyLnJlc29sdmVPclJlamVjdEVycm9yKHtcbiAgICAgICAgICBlcnI6IGVycixcbiAgICAgICAgICBlcnJvclJlc3BvbnNlRmFjdG9yeUZuOiBlID0+IG5ldyBDYWNoZVNldEJhdGNoLkVycm9yKGUpLFxuICAgICAgICAgIHJlc29sdmVGbjogcmVzb2x2ZSxcbiAgICAgICAgICByZWplY3RGbjogcmVqZWN0LFxuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIGxpc3RDb25jYXRlbmF0ZUJhY2soXG4gICAgY2FjaGVOYW1lOiBzdHJpbmcsXG4gICAgbGlzdE5hbWU6IHN0cmluZyxcbiAgICB2YWx1ZXM6IHN0cmluZ1tdIHwgVWludDhBcnJheVtdLFxuICAgIHRydW5jYXRlRnJvbnRUb1NpemU/OiBudW1iZXIsXG4gICAgdHRsOiBDb2xsZWN0aW9uVHRsID0gQ29sbGVjdGlvblR0bC5mcm9tQ2FjaGVUdGwoKVxuICApOiBQcm9taXNlPENhY2hlTGlzdENvbmNhdGVuYXRlQmFjay5SZXNwb25zZT4ge1xuICAgIHRyeSB7XG4gICAgICB2YWxpZGF0ZUNhY2hlTmFtZShjYWNoZU5hbWUpO1xuICAgICAgdmFsaWRhdGVMaXN0TmFtZShsaXN0TmFtZSk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICByZXR1cm4gdGhpcy5jYWNoZVNlcnZpY2VFcnJvck1hcHBlci5yZXR1cm5PclRocm93RXJyb3IoXG4gICAgICAgIGVyciBhcyBFcnJvcixcbiAgICAgICAgZXJyID0+IG5ldyBDYWNoZUxpc3RDb25jYXRlbmF0ZUJhY2suRXJyb3IoZXJyKVxuICAgICAgKTtcbiAgICB9XG5cbiAgICByZXR1cm4gYXdhaXQgdGhpcy5yYXRlTGltaXRlZChhc3luYyAoKSA9PiB7XG4gICAgICByZXR1cm4gYXdhaXQgdGhpcy5zZW5kTGlzdENvbmNhdGVuYXRlQmFjayhcbiAgICAgICAgY2FjaGVOYW1lLFxuICAgICAgICB0aGlzLmNvbnZlcnQobGlzdE5hbWUpLFxuICAgICAgICB0aGlzLmNvbnZlcnRBcnJheSh2YWx1ZXMpLFxuICAgICAgICB0aGlzLmNvbGxlY3Rpb25UdGxPckRlZmF1bHRNaWxsaXNlY29uZHModHRsKSxcbiAgICAgICAgdHRsLnJlZnJlc2hUdGwoKSxcbiAgICAgICAgdHJ1bmNhdGVGcm9udFRvU2l6ZVxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgc2VuZExpc3RDb25jYXRlbmF0ZUJhY2soXG4gICAgY2FjaGVOYW1lOiBzdHJpbmcsXG4gICAgbGlzdE5hbWU6IFVpbnQ4QXJyYXksXG4gICAgdmFsdWVzOiBVaW50OEFycmF5W10sXG4gICAgdHRsTWlsbGlzZWNvbmRzOiBudW1iZXIsXG4gICAgcmVmcmVzaFR0bDogYm9vbGVhbixcbiAgICB0cnVuY2F0ZUZyb250VG9TaXplPzogbnVtYmVyXG4gICk6IFByb21pc2U8Q2FjaGVMaXN0Q29uY2F0ZW5hdGVCYWNrLlJlc3BvbnNlPiB7XG4gICAgY29uc3QgcmVxdWVzdCA9IG5ldyBncnBjQ2FjaGUuX0xpc3RDb25jYXRlbmF0ZUJhY2tSZXF1ZXN0KHtcbiAgICAgIGxpc3RfbmFtZTogbGlzdE5hbWUsXG4gICAgICB2YWx1ZXM6IHZhbHVlcyxcbiAgICAgIHR0bF9taWxsaXNlY29uZHM6IHR0bE1pbGxpc2Vjb25kcyxcbiAgICAgIHJlZnJlc2hfdHRsOiByZWZyZXNoVHRsLFxuICAgICAgdHJ1bmNhdGVfZnJvbnRfdG9fc2l6ZTogdHJ1bmNhdGVGcm9udFRvU2l6ZSxcbiAgICB9KTtcbiAgICBjb25zdCBtZXRhZGF0YSA9IHRoaXMuY3JlYXRlTWV0YWRhdGEoY2FjaGVOYW1lKTtcbiAgICByZXR1cm4gYXdhaXQgbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgdGhpcy5jbGllbnRXcmFwcGVyLmdldENsaWVudCgpLkxpc3RDb25jYXRlbmF0ZUJhY2soXG4gICAgICAgIHJlcXVlc3QsXG4gICAgICAgIG1ldGFkYXRhLFxuICAgICAgICB7XG4gICAgICAgICAgaW50ZXJjZXB0b3JzOiB0aGlzLmludGVyY2VwdG9ycyxcbiAgICAgICAgfSxcbiAgICAgICAgKGVyciwgcmVzcCkgPT4ge1xuICAgICAgICAgIGlmIChyZXNwKSB7XG4gICAgICAgICAgICByZXNvbHZlKG5ldyBDYWNoZUxpc3RDb25jYXRlbmF0ZUJhY2suU3VjY2VzcyhyZXNwLmxpc3RfbGVuZ3RoKSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuY2FjaGVTZXJ2aWNlRXJyb3JNYXBwZXIucmVzb2x2ZU9yUmVqZWN0RXJyb3Ioe1xuICAgICAgICAgICAgICBlcnI6IGVycixcbiAgICAgICAgICAgICAgZXJyb3JSZXNwb25zZUZhY3RvcnlGbjogZSA9PlxuICAgICAgICAgICAgICAgIG5ldyBDYWNoZUxpc3RDb25jYXRlbmF0ZUJhY2suRXJyb3IoZSksXG4gICAgICAgICAgICAgIHJlc29sdmVGbjogcmVzb2x2ZSxcbiAgICAgICAgICAgICAgcmVqZWN0Rm46IHJlamVjdCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBsaXN0Q29uY2F0ZW5hdGVGcm9udChcbiAgICBjYWNoZU5hbWU6IHN0cmluZyxcbiAgICBsaXN0TmFtZTogc3RyaW5nLFxuICAgIHZhbHVlczogc3RyaW5nW10gfCBVaW50OEFycmF5W10sXG4gICAgdHJ1bmNhdGVCYWNrVG9TaXplPzogbnVtYmVyLFxuICAgIHR0bDogQ29sbGVjdGlvblR0bCA9IENvbGxlY3Rpb25UdGwuZnJvbUNhY2hlVHRsKClcbiAgKTogUHJvbWlzZTxDYWNoZUxpc3RDb25jYXRlbmF0ZUZyb250LlJlc3BvbnNlPiB7XG4gICAgdHJ5IHtcbiAgICAgIHZhbGlkYXRlQ2FjaGVOYW1lKGNhY2hlTmFtZSk7XG4gICAgICB2YWxpZGF0ZUxpc3ROYW1lKGxpc3ROYW1lKTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIHJldHVybiB0aGlzLmNhY2hlU2VydmljZUVycm9yTWFwcGVyLnJldHVybk9yVGhyb3dFcnJvcihcbiAgICAgICAgZXJyIGFzIEVycm9yLFxuICAgICAgICBlcnIgPT4gbmV3IENhY2hlTGlzdENvbmNhdGVuYXRlRnJvbnQuRXJyb3IoZXJyKVxuICAgICAgKTtcbiAgICB9XG5cbiAgICByZXR1cm4gYXdhaXQgdGhpcy5yYXRlTGltaXRlZChhc3luYyAoKSA9PiB7XG4gICAgICByZXR1cm4gYXdhaXQgdGhpcy5zZW5kTGlzdENvbmNhdGVuYXRlRnJvbnQoXG4gICAgICAgIGNhY2hlTmFtZSxcbiAgICAgICAgdGhpcy5jb252ZXJ0KGxpc3ROYW1lKSxcbiAgICAgICAgdGhpcy5jb252ZXJ0QXJyYXkodmFsdWVzKSxcbiAgICAgICAgdGhpcy5jb2xsZWN0aW9uVHRsT3JEZWZhdWx0TWlsbGlzZWNvbmRzKHR0bCksXG4gICAgICAgIHR0bC5yZWZyZXNoVHRsKCksXG4gICAgICAgIHRydW5jYXRlQmFja1RvU2l6ZVxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgc2VuZExpc3RDb25jYXRlbmF0ZUZyb250KFxuICAgIGNhY2hlTmFtZTogc3RyaW5nLFxuICAgIGxpc3ROYW1lOiBVaW50OEFycmF5LFxuICAgIHZhbHVlczogVWludDhBcnJheVtdLFxuICAgIHR0bE1pbGxpc2Vjb25kczogbnVtYmVyLFxuICAgIHJlZnJlc2hUdGw6IGJvb2xlYW4sXG4gICAgdHJ1bmNhdGVCYWNrVG9TaXplPzogbnVtYmVyXG4gICk6IFByb21pc2U8Q2FjaGVMaXN0Q29uY2F0ZW5hdGVGcm9udC5SZXNwb25zZT4ge1xuICAgIGNvbnN0IHJlcXVlc3QgPSBuZXcgZ3JwY0NhY2hlLl9MaXN0Q29uY2F0ZW5hdGVGcm9udFJlcXVlc3Qoe1xuICAgICAgbGlzdF9uYW1lOiBsaXN0TmFtZSxcbiAgICAgIHZhbHVlczogdmFsdWVzLFxuICAgICAgdHRsX21pbGxpc2Vjb25kczogdHRsTWlsbGlzZWNvbmRzLFxuICAgICAgcmVmcmVzaF90dGw6IHJlZnJlc2hUdGwsXG4gICAgICB0cnVuY2F0ZV9iYWNrX3RvX3NpemU6IHRydW5jYXRlQmFja1RvU2l6ZSxcbiAgICB9KTtcbiAgICBjb25zdCBtZXRhZGF0YSA9IHRoaXMuY3JlYXRlTWV0YWRhdGEoY2FjaGVOYW1lKTtcbiAgICByZXR1cm4gYXdhaXQgbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgdGhpcy5jbGllbnRXcmFwcGVyLmdldENsaWVudCgpLkxpc3RDb25jYXRlbmF0ZUZyb250KFxuICAgICAgICByZXF1ZXN0LFxuICAgICAgICBtZXRhZGF0YSxcbiAgICAgICAge1xuICAgICAgICAgIGludGVyY2VwdG9yczogdGhpcy5pbnRlcmNlcHRvcnMsXG4gICAgICAgIH0sXG4gICAgICAgIChlcnIsIHJlc3ApID0+IHtcbiAgICAgICAgICBpZiAocmVzcCkge1xuICAgICAgICAgICAgcmVzb2x2ZShuZXcgQ2FjaGVMaXN0Q29uY2F0ZW5hdGVGcm9udC5TdWNjZXNzKHJlc3AubGlzdF9sZW5ndGgpKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5jYWNoZVNlcnZpY2VFcnJvck1hcHBlci5yZXNvbHZlT3JSZWplY3RFcnJvcih7XG4gICAgICAgICAgICAgIGVycjogZXJyLFxuICAgICAgICAgICAgICBlcnJvclJlc3BvbnNlRmFjdG9yeUZuOiBlID0+XG4gICAgICAgICAgICAgICAgbmV3IENhY2hlTGlzdENvbmNhdGVuYXRlRnJvbnQuRXJyb3IoZSksXG4gICAgICAgICAgICAgIHJlc29sdmVGbjogcmVzb2x2ZSxcbiAgICAgICAgICAgICAgcmVqZWN0Rm46IHJlamVjdCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBsaXN0RmV0Y2goXG4gICAgY2FjaGVOYW1lOiBzdHJpbmcsXG4gICAgbGlzdE5hbWU6IHN0cmluZyxcbiAgICBzdGFydEluZGV4PzogbnVtYmVyLFxuICAgIGVuZEluZGV4PzogbnVtYmVyXG4gICk6IFByb21pc2U8Q2FjaGVMaXN0RmV0Y2guUmVzcG9uc2U+IHtcbiAgICB0cnkge1xuICAgICAgdmFsaWRhdGVDYWNoZU5hbWUoY2FjaGVOYW1lKTtcbiAgICAgIHZhbGlkYXRlTGlzdE5hbWUobGlzdE5hbWUpO1xuICAgICAgdmFsaWRhdGVMaXN0U2xpY2VTdGFydEVuZChzdGFydEluZGV4LCBlbmRJbmRleCk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICByZXR1cm4gdGhpcy5jYWNoZVNlcnZpY2VFcnJvck1hcHBlci5yZXR1cm5PclRocm93RXJyb3IoXG4gICAgICAgIGVyciBhcyBFcnJvcixcbiAgICAgICAgZXJyID0+IG5ldyBDYWNoZUxpc3RGZXRjaC5FcnJvcihlcnIpXG4gICAgICApO1xuICAgIH1cblxuICAgIHJldHVybiBhd2FpdCB0aGlzLnJhdGVMaW1pdGVkKGFzeW5jICgpID0+IHtcbiAgICAgIHJldHVybiBhd2FpdCB0aGlzLnNlbmRMaXN0RmV0Y2goXG4gICAgICAgIGNhY2hlTmFtZSxcbiAgICAgICAgdGhpcy5jb252ZXJ0KGxpc3ROYW1lKSxcbiAgICAgICAgc3RhcnRJbmRleCxcbiAgICAgICAgZW5kSW5kZXhcbiAgICAgICk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHNlbmRMaXN0RmV0Y2goXG4gICAgY2FjaGVOYW1lOiBzdHJpbmcsXG4gICAgbGlzdE5hbWU6IFVpbnQ4QXJyYXksXG4gICAgc3RhcnQ/OiBudW1iZXIsXG4gICAgZW5kPzogbnVtYmVyXG4gICk6IFByb21pc2U8Q2FjaGVMaXN0RmV0Y2guUmVzcG9uc2U+IHtcbiAgICBjb25zdCByZXF1ZXN0ID0gbmV3IGdycGNDYWNoZS5fTGlzdEZldGNoUmVxdWVzdCh7XG4gICAgICBsaXN0X25hbWU6IGxpc3ROYW1lLFxuICAgIH0pO1xuICAgIGlmIChzdGFydCkge1xuICAgICAgcmVxdWVzdC5pbmNsdXNpdmVfc3RhcnQgPSBzdGFydDtcbiAgICB9IGVsc2Uge1xuICAgICAgcmVxdWVzdC51bmJvdW5kZWRfc3RhcnQgPSBuZXcgX1VuYm91bmRlZCgpO1xuICAgIH1cbiAgICBpZiAoZW5kKSB7XG4gICAgICByZXF1ZXN0LmV4Y2x1c2l2ZV9lbmQgPSBlbmQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJlcXVlc3QudW5ib3VuZGVkX2VuZCA9IG5ldyBfVW5ib3VuZGVkKCk7XG4gICAgfVxuICAgIGNvbnN0IG1ldGFkYXRhID0gdGhpcy5jcmVhdGVNZXRhZGF0YShjYWNoZU5hbWUpO1xuXG4gICAgcmV0dXJuIGF3YWl0IG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHRoaXMuY2xpZW50V3JhcHBlci5nZXRDbGllbnQoKS5MaXN0RmV0Y2goXG4gICAgICAgIHJlcXVlc3QsXG4gICAgICAgIG1ldGFkYXRhLFxuICAgICAgICB7XG4gICAgICAgICAgaW50ZXJjZXB0b3JzOiB0aGlzLmludGVyY2VwdG9ycyxcbiAgICAgICAgfSxcbiAgICAgICAgKGVyciwgcmVzcCkgPT4ge1xuICAgICAgICAgIGlmIChyZXNwPy5taXNzaW5nKSB7XG4gICAgICAgICAgICByZXNvbHZlKG5ldyBDYWNoZUxpc3RGZXRjaC5NaXNzKCkpO1xuICAgICAgICAgIH0gZWxzZSBpZiAocmVzcD8uZm91bmQpIHtcbiAgICAgICAgICAgIHJlc29sdmUobmV3IENhY2hlTGlzdEZldGNoLkhpdChyZXNwLmZvdW5kLnZhbHVlcykpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmNhY2hlU2VydmljZUVycm9yTWFwcGVyLnJlc29sdmVPclJlamVjdEVycm9yKHtcbiAgICAgICAgICAgICAgZXJyOiBlcnIsXG4gICAgICAgICAgICAgIGVycm9yUmVzcG9uc2VGYWN0b3J5Rm46IGUgPT4gbmV3IENhY2hlTGlzdEZldGNoLkVycm9yKGUpLFxuICAgICAgICAgICAgICByZXNvbHZlRm46IHJlc29sdmUsXG4gICAgICAgICAgICAgIHJlamVjdEZuOiByZWplY3QsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICk7XG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgbGlzdFJldGFpbihcbiAgICBjYWNoZU5hbWU6IHN0cmluZyxcbiAgICBsaXN0TmFtZTogc3RyaW5nLFxuICAgIHN0YXJ0SW5kZXg/OiBudW1iZXIsXG4gICAgZW5kSW5kZXg/OiBudW1iZXIsXG4gICAgdHRsOiBDb2xsZWN0aW9uVHRsID0gQ29sbGVjdGlvblR0bC5mcm9tQ2FjaGVUdGwoKVxuICApOiBQcm9taXNlPENhY2hlTGlzdFJldGFpbi5SZXNwb25zZT4ge1xuICAgIHRyeSB7XG4gICAgICB2YWxpZGF0ZUNhY2hlTmFtZShjYWNoZU5hbWUpO1xuICAgICAgdmFsaWRhdGVMaXN0TmFtZShsaXN0TmFtZSk7XG4gICAgICB2YWxpZGF0ZUxpc3RTbGljZVN0YXJ0RW5kKHN0YXJ0SW5kZXgsIGVuZEluZGV4KTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIHJldHVybiB0aGlzLmNhY2hlU2VydmljZUVycm9yTWFwcGVyLnJldHVybk9yVGhyb3dFcnJvcihcbiAgICAgICAgZXJyIGFzIEVycm9yLFxuICAgICAgICBlcnIgPT4gbmV3IENhY2hlTGlzdFJldGFpbi5FcnJvcihlcnIpXG4gICAgICApO1xuICAgIH1cblxuICAgIHJldHVybiBhd2FpdCB0aGlzLnJhdGVMaW1pdGVkKGFzeW5jICgpID0+IHtcbiAgICAgIHJldHVybiBhd2FpdCB0aGlzLnNlbmRMaXN0UmV0YWluKFxuICAgICAgICBjYWNoZU5hbWUsXG4gICAgICAgIHRoaXMuY29udmVydChsaXN0TmFtZSksXG4gICAgICAgIHN0YXJ0SW5kZXgsXG4gICAgICAgIGVuZEluZGV4LFxuICAgICAgICB0aGlzLmNvbGxlY3Rpb25UdGxPckRlZmF1bHRNaWxsaXNlY29uZHModHRsKSxcbiAgICAgICAgdHRsLnJlZnJlc2hUdGwoKVxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgc2VuZExpc3RSZXRhaW4oXG4gICAgY2FjaGVOYW1lOiBzdHJpbmcsXG4gICAgbGlzdE5hbWU6IFVpbnQ4QXJyYXksXG4gICAgc3RhcnQ/OiBudW1iZXIsXG4gICAgZW5kPzogbnVtYmVyLFxuICAgIHR0bE1pbGxpc2Vjb25kcz86IG51bWJlcixcbiAgICByZWZyZXNoVHRsPzogYm9vbGVhblxuICApOiBQcm9taXNlPENhY2hlTGlzdFJldGFpbi5SZXNwb25zZT4ge1xuICAgIGNvbnN0IHJlcXVlc3QgPSBuZXcgZ3JwY0NhY2hlLl9MaXN0UmV0YWluUmVxdWVzdCh7XG4gICAgICBsaXN0X25hbWU6IGxpc3ROYW1lLFxuICAgICAgdHRsX21pbGxpc2Vjb25kczogdHRsTWlsbGlzZWNvbmRzLFxuICAgICAgcmVmcmVzaF90dGw6IHJlZnJlc2hUdGwsXG4gICAgfSk7XG4gICAgaWYgKHN0YXJ0KSB7XG4gICAgICByZXF1ZXN0LmluY2x1c2l2ZV9zdGFydCA9IHN0YXJ0O1xuICAgIH0gZWxzZSB7XG4gICAgICByZXF1ZXN0LnVuYm91bmRlZF9zdGFydCA9IG5ldyBfVW5ib3VuZGVkKCk7XG4gICAgfVxuICAgIGlmIChlbmQpIHtcbiAgICAgIHJlcXVlc3QuZXhjbHVzaXZlX2VuZCA9IGVuZDtcbiAgICB9IGVsc2Uge1xuICAgICAgcmVxdWVzdC51bmJvdW5kZWRfZW5kID0gbmV3IF9VbmJvdW5kZWQoKTtcbiAgICB9XG4gICAgY29uc3QgbWV0YWRhdGEgPSB0aGlzLmNyZWF0ZU1ldGFkYXRhKGNhY2hlTmFtZSk7XG5cbiAgICByZXR1cm4gYXdhaXQgbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgdGhpcy5jbGllbnRXcmFwcGVyLmdldENsaWVudCgpLkxpc3RSZXRhaW4oXG4gICAgICAgIHJlcXVlc3QsXG4gICAgICAgIG1ldGFkYXRhLFxuICAgICAgICB7XG4gICAgICAgICAgaW50ZXJjZXB0b3JzOiB0aGlzLmludGVyY2VwdG9ycyxcbiAgICAgICAgfSxcbiAgICAgICAgKGVyciwgcmVzcCkgPT4ge1xuICAgICAgICAgIGlmIChyZXNwKSB7XG4gICAgICAgICAgICByZXNvbHZlKG5ldyBDYWNoZUxpc3RSZXRhaW4uU3VjY2VzcygpKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5jYWNoZVNlcnZpY2VFcnJvck1hcHBlci5yZXNvbHZlT3JSZWplY3RFcnJvcih7XG4gICAgICAgICAgICAgIGVycjogZXJyLFxuICAgICAgICAgICAgICBlcnJvclJlc3BvbnNlRmFjdG9yeUZuOiBlID0+IG5ldyBDYWNoZUxpc3RSZXRhaW4uRXJyb3IoZSksXG4gICAgICAgICAgICAgIHJlc29sdmVGbjogcmVzb2x2ZSxcbiAgICAgICAgICAgICAgcmVqZWN0Rm46IHJlamVjdCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBsaXN0TGVuZ3RoKFxuICAgIGNhY2hlTmFtZTogc3RyaW5nLFxuICAgIGxpc3ROYW1lOiBzdHJpbmdcbiAgKTogUHJvbWlzZTxDYWNoZUxpc3RMZW5ndGguUmVzcG9uc2U+IHtcbiAgICB0cnkge1xuICAgICAgdmFsaWRhdGVDYWNoZU5hbWUoY2FjaGVOYW1lKTtcbiAgICAgIHZhbGlkYXRlTGlzdE5hbWUobGlzdE5hbWUpO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgcmV0dXJuIHRoaXMuY2FjaGVTZXJ2aWNlRXJyb3JNYXBwZXIucmV0dXJuT3JUaHJvd0Vycm9yKFxuICAgICAgICBlcnIgYXMgRXJyb3IsXG4gICAgICAgIGVyciA9PiBuZXcgQ2FjaGVMaXN0TGVuZ3RoLkVycm9yKGVycilcbiAgICAgICk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGF3YWl0IHRoaXMucmF0ZUxpbWl0ZWQoYXN5bmMgKCkgPT4ge1xuICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuc2VuZExpc3RMZW5ndGgoY2FjaGVOYW1lLCB0aGlzLmNvbnZlcnQobGlzdE5hbWUpKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgc2VuZExpc3RMZW5ndGgoXG4gICAgY2FjaGVOYW1lOiBzdHJpbmcsXG4gICAgbGlzdE5hbWU6IFVpbnQ4QXJyYXlcbiAgKTogUHJvbWlzZTxDYWNoZUxpc3RMZW5ndGguUmVzcG9uc2U+IHtcbiAgICBjb25zdCByZXF1ZXN0ID0gbmV3IGdycGNDYWNoZS5fTGlzdExlbmd0aFJlcXVlc3Qoe1xuICAgICAgbGlzdF9uYW1lOiBsaXN0TmFtZSxcbiAgICB9KTtcbiAgICBjb25zdCBtZXRhZGF0YSA9IHRoaXMuY3JlYXRlTWV0YWRhdGEoY2FjaGVOYW1lKTtcblxuICAgIHJldHVybiBhd2FpdCBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICB0aGlzLmNsaWVudFdyYXBwZXIuZ2V0Q2xpZW50KCkuTGlzdExlbmd0aChcbiAgICAgICAgcmVxdWVzdCxcbiAgICAgICAgbWV0YWRhdGEsXG4gICAgICAgIHtcbiAgICAgICAgICBpbnRlcmNlcHRvcnM6IHRoaXMuaW50ZXJjZXB0b3JzLFxuICAgICAgICB9LFxuICAgICAgICAoZXJyLCByZXNwKSA9PiB7XG4gICAgICAgICAgaWYgKHJlc3A/Lm1pc3NpbmcpIHtcbiAgICAgICAgICAgIHJlc29sdmUobmV3IENhY2hlTGlzdExlbmd0aC5NaXNzKCkpO1xuICAgICAgICAgIH0gZWxzZSBpZiAocmVzcD8uZm91bmQpIHtcbiAgICAgICAgICAgIHJlc29sdmUobmV3IENhY2hlTGlzdExlbmd0aC5IaXQocmVzcC5mb3VuZC5sZW5ndGgpKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5jYWNoZVNlcnZpY2VFcnJvck1hcHBlci5yZXNvbHZlT3JSZWplY3RFcnJvcih7XG4gICAgICAgICAgICAgIGVycjogZXJyLFxuICAgICAgICAgICAgICBlcnJvclJlc3BvbnNlRmFjdG9yeUZuOiBlID0+IG5ldyBDYWNoZUxpc3RMZW5ndGguRXJyb3IoZSksXG4gICAgICAgICAgICAgIHJlc29sdmVGbjogcmVzb2x2ZSxcbiAgICAgICAgICAgICAgcmVqZWN0Rm46IHJlamVjdCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBsaXN0UG9wQmFjayhcbiAgICBjYWNoZU5hbWU6IHN0cmluZyxcbiAgICBsaXN0TmFtZTogc3RyaW5nXG4gICk6IFByb21pc2U8Q2FjaGVMaXN0UG9wQmFjay5SZXNwb25zZT4ge1xuICAgIHRyeSB7XG4gICAgICB2YWxpZGF0ZUNhY2hlTmFtZShjYWNoZU5hbWUpO1xuICAgICAgdmFsaWRhdGVMaXN0TmFtZShsaXN0TmFtZSk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICByZXR1cm4gdGhpcy5jYWNoZVNlcnZpY2VFcnJvck1hcHBlci5yZXR1cm5PclRocm93RXJyb3IoXG4gICAgICAgIGVyciBhcyBFcnJvcixcbiAgICAgICAgZXJyID0+IG5ldyBDYWNoZUxpc3RQb3BCYWNrLkVycm9yKGVycilcbiAgICAgICk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGF3YWl0IHRoaXMucmF0ZUxpbWl0ZWQoYXN5bmMgKCkgPT4ge1xuICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuc2VuZExpc3RQb3BCYWNrKGNhY2hlTmFtZSwgdGhpcy5jb252ZXJ0KGxpc3ROYW1lKSk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHNlbmRMaXN0UG9wQmFjayhcbiAgICBjYWNoZU5hbWU6IHN0cmluZyxcbiAgICBsaXN0TmFtZTogVWludDhBcnJheVxuICApOiBQcm9taXNlPENhY2hlTGlzdFBvcEJhY2suUmVzcG9uc2U+IHtcbiAgICBjb25zdCByZXF1ZXN0ID0gbmV3IGdycGNDYWNoZS5fTGlzdFBvcEJhY2tSZXF1ZXN0KHtcbiAgICAgIGxpc3RfbmFtZTogbGlzdE5hbWUsXG4gICAgfSk7XG4gICAgY29uc3QgbWV0YWRhdGEgPSB0aGlzLmNyZWF0ZU1ldGFkYXRhKGNhY2hlTmFtZSk7XG5cbiAgICByZXR1cm4gYXdhaXQgbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgdGhpcy5jbGllbnRXcmFwcGVyLmdldENsaWVudCgpLkxpc3RQb3BCYWNrKFxuICAgICAgICByZXF1ZXN0LFxuICAgICAgICBtZXRhZGF0YSxcbiAgICAgICAge1xuICAgICAgICAgIGludGVyY2VwdG9yczogdGhpcy5pbnRlcmNlcHRvcnMsXG4gICAgICAgIH0sXG4gICAgICAgIChlcnIsIHJlc3ApID0+IHtcbiAgICAgICAgICBpZiAocmVzcD8ubWlzc2luZykge1xuICAgICAgICAgICAgcmVzb2x2ZShuZXcgQ2FjaGVMaXN0UG9wQmFjay5NaXNzKCkpO1xuICAgICAgICAgIH0gZWxzZSBpZiAocmVzcD8uZm91bmQpIHtcbiAgICAgICAgICAgIHJlc29sdmUobmV3IENhY2hlTGlzdFBvcEJhY2suSGl0KHJlc3AuZm91bmQuYmFjaykpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmNhY2hlU2VydmljZUVycm9yTWFwcGVyLnJlc29sdmVPclJlamVjdEVycm9yKHtcbiAgICAgICAgICAgICAgZXJyOiBlcnIsXG4gICAgICAgICAgICAgIGVycm9yUmVzcG9uc2VGYWN0b3J5Rm46IGUgPT4gbmV3IENhY2hlTGlzdFBvcEJhY2suRXJyb3IoZSksXG4gICAgICAgICAgICAgIHJlc29sdmVGbjogcmVzb2x2ZSxcbiAgICAgICAgICAgICAgcmVqZWN0Rm46IHJlamVjdCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBsaXN0UG9wRnJvbnQoXG4gICAgY2FjaGVOYW1lOiBzdHJpbmcsXG4gICAgbGlzdE5hbWU6IHN0cmluZ1xuICApOiBQcm9taXNlPENhY2hlTGlzdFBvcEZyb250LlJlc3BvbnNlPiB7XG4gICAgdHJ5IHtcbiAgICAgIHZhbGlkYXRlQ2FjaGVOYW1lKGNhY2hlTmFtZSk7XG4gICAgICB2YWxpZGF0ZUxpc3ROYW1lKGxpc3ROYW1lKTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIHJldHVybiB0aGlzLmNhY2hlU2VydmljZUVycm9yTWFwcGVyLnJldHVybk9yVGhyb3dFcnJvcihcbiAgICAgICAgZXJyIGFzIEVycm9yLFxuICAgICAgICBlcnIgPT4gbmV3IENhY2hlTGlzdFBvcEZyb250LkVycm9yKGVycilcbiAgICAgICk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGF3YWl0IHRoaXMucmF0ZUxpbWl0ZWQoYXN5bmMgKCkgPT4ge1xuICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuc2VuZExpc3RQb3BGcm9udChjYWNoZU5hbWUsIHRoaXMuY29udmVydChsaXN0TmFtZSkpO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBzZW5kTGlzdFBvcEZyb250KFxuICAgIGNhY2hlTmFtZTogc3RyaW5nLFxuICAgIGxpc3ROYW1lOiBVaW50OEFycmF5XG4gICk6IFByb21pc2U8Q2FjaGVMaXN0UG9wRnJvbnQuUmVzcG9uc2U+IHtcbiAgICBjb25zdCByZXF1ZXN0ID0gbmV3IGdycGNDYWNoZS5fTGlzdFBvcEZyb250UmVxdWVzdCh7XG4gICAgICBsaXN0X25hbWU6IGxpc3ROYW1lLFxuICAgIH0pO1xuICAgIGNvbnN0IG1ldGFkYXRhID0gdGhpcy5jcmVhdGVNZXRhZGF0YShjYWNoZU5hbWUpO1xuXG4gICAgcmV0dXJuIGF3YWl0IG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHRoaXMuY2xpZW50V3JhcHBlci5nZXRDbGllbnQoKS5MaXN0UG9wRnJvbnQoXG4gICAgICAgIHJlcXVlc3QsXG4gICAgICAgIG1ldGFkYXRhLFxuICAgICAgICB7XG4gICAgICAgICAgaW50ZXJjZXB0b3JzOiB0aGlzLmludGVyY2VwdG9ycyxcbiAgICAgICAgfSxcbiAgICAgICAgKGVyciwgcmVzcCkgPT4ge1xuICAgICAgICAgIGlmIChyZXNwPy5taXNzaW5nKSB7XG4gICAgICAgICAgICByZXNvbHZlKG5ldyBDYWNoZUxpc3RQb3BGcm9udC5NaXNzKCkpO1xuICAgICAgICAgIH0gZWxzZSBpZiAocmVzcD8uZm91bmQpIHtcbiAgICAgICAgICAgIHJlc29sdmUobmV3IENhY2hlTGlzdFBvcEZyb250LkhpdChyZXNwLmZvdW5kLmZyb250KSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuY2FjaGVTZXJ2aWNlRXJyb3JNYXBwZXIucmVzb2x2ZU9yUmVqZWN0RXJyb3Ioe1xuICAgICAgICAgICAgICBlcnI6IGVycixcbiAgICAgICAgICAgICAgZXJyb3JSZXNwb25zZUZhY3RvcnlGbjogZSA9PiBuZXcgQ2FjaGVMaXN0UG9wRnJvbnQuRXJyb3IoZSksXG4gICAgICAgICAgICAgIHJlc29sdmVGbjogcmVzb2x2ZSxcbiAgICAgICAgICAgICAgcmVqZWN0Rm46IHJlamVjdCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBsaXN0UHVzaEJhY2soXG4gICAgY2FjaGVOYW1lOiBzdHJpbmcsXG4gICAgbGlzdE5hbWU6IHN0cmluZyxcbiAgICB2YWx1ZTogc3RyaW5nIHwgVWludDhBcnJheSxcbiAgICB0cnVuY2F0ZUZyb250VG9TaXplPzogbnVtYmVyLFxuICAgIHR0bDogQ29sbGVjdGlvblR0bCA9IENvbGxlY3Rpb25UdGwuZnJvbUNhY2hlVHRsKClcbiAgKTogUHJvbWlzZTxDYWNoZUxpc3RQdXNoQmFjay5SZXNwb25zZT4ge1xuICAgIHRyeSB7XG4gICAgICB2YWxpZGF0ZUNhY2hlTmFtZShjYWNoZU5hbWUpO1xuICAgICAgdmFsaWRhdGVMaXN0TmFtZShsaXN0TmFtZSk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICByZXR1cm4gdGhpcy5jYWNoZVNlcnZpY2VFcnJvck1hcHBlci5yZXR1cm5PclRocm93RXJyb3IoXG4gICAgICAgIGVyciBhcyBFcnJvcixcbiAgICAgICAgZXJyID0+IG5ldyBDYWNoZUxpc3RQdXNoQmFjay5FcnJvcihlcnIpXG4gICAgICApO1xuICAgIH1cblxuICAgIHJldHVybiBhd2FpdCB0aGlzLnJhdGVMaW1pdGVkKGFzeW5jICgpID0+IHtcbiAgICAgIHJldHVybiBhd2FpdCB0aGlzLnNlbmRMaXN0UHVzaEJhY2soXG4gICAgICAgIGNhY2hlTmFtZSxcbiAgICAgICAgdGhpcy5jb252ZXJ0KGxpc3ROYW1lKSxcbiAgICAgICAgdGhpcy5jb252ZXJ0KHZhbHVlKSxcbiAgICAgICAgdGhpcy5jb2xsZWN0aW9uVHRsT3JEZWZhdWx0TWlsbGlzZWNvbmRzKHR0bCksXG4gICAgICAgIHR0bC5yZWZyZXNoVHRsKCksXG4gICAgICAgIHRydW5jYXRlRnJvbnRUb1NpemVcbiAgICAgICk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHNlbmRMaXN0UHVzaEJhY2soXG4gICAgY2FjaGVOYW1lOiBzdHJpbmcsXG4gICAgbGlzdE5hbWU6IFVpbnQ4QXJyYXksXG4gICAgdmFsdWU6IFVpbnQ4QXJyYXksXG4gICAgdHRsTWlsbGlzZWNvbmRzOiBudW1iZXIsXG4gICAgcmVmcmVzaFR0bDogYm9vbGVhbixcbiAgICB0cnVuY2F0ZUZyb250VG9TaXplPzogbnVtYmVyXG4gICk6IFByb21pc2U8Q2FjaGVMaXN0UHVzaEJhY2suUmVzcG9uc2U+IHtcbiAgICBjb25zdCByZXF1ZXN0ID0gbmV3IGdycGNDYWNoZS5fTGlzdFB1c2hCYWNrUmVxdWVzdCh7XG4gICAgICBsaXN0X25hbWU6IGxpc3ROYW1lLFxuICAgICAgdmFsdWU6IHZhbHVlLFxuICAgICAgdHRsX21pbGxpc2Vjb25kczogdHRsTWlsbGlzZWNvbmRzLFxuICAgICAgcmVmcmVzaF90dGw6IHJlZnJlc2hUdGwsXG4gICAgICB0cnVuY2F0ZV9mcm9udF90b19zaXplOiB0cnVuY2F0ZUZyb250VG9TaXplLFxuICAgIH0pO1xuICAgIGNvbnN0IG1ldGFkYXRhID0gdGhpcy5jcmVhdGVNZXRhZGF0YShjYWNoZU5hbWUpO1xuICAgIHJldHVybiBhd2FpdCBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICB0aGlzLmNsaWVudFdyYXBwZXIuZ2V0Q2xpZW50KCkuTGlzdFB1c2hCYWNrKFxuICAgICAgICByZXF1ZXN0LFxuICAgICAgICBtZXRhZGF0YSxcbiAgICAgICAge1xuICAgICAgICAgIGludGVyY2VwdG9yczogdGhpcy5pbnRlcmNlcHRvcnMsXG4gICAgICAgIH0sXG4gICAgICAgIChlcnIsIHJlc3ApID0+IHtcbiAgICAgICAgICBpZiAocmVzcCkge1xuICAgICAgICAgICAgcmVzb2x2ZShuZXcgQ2FjaGVMaXN0UHVzaEJhY2suU3VjY2VzcyhyZXNwLmxpc3RfbGVuZ3RoKSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuY2FjaGVTZXJ2aWNlRXJyb3JNYXBwZXIucmVzb2x2ZU9yUmVqZWN0RXJyb3Ioe1xuICAgICAgICAgICAgICBlcnI6IGVycixcbiAgICAgICAgICAgICAgZXJyb3JSZXNwb25zZUZhY3RvcnlGbjogZSA9PiBuZXcgQ2FjaGVMaXN0UHVzaEJhY2suRXJyb3IoZSksXG4gICAgICAgICAgICAgIHJlc29sdmVGbjogcmVzb2x2ZSxcbiAgICAgICAgICAgICAgcmVqZWN0Rm46IHJlamVjdCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBsaXN0UHVzaEZyb250KFxuICAgIGNhY2hlTmFtZTogc3RyaW5nLFxuICAgIGxpc3ROYW1lOiBzdHJpbmcsXG4gICAgdmFsdWU6IHN0cmluZyB8IFVpbnQ4QXJyYXksXG4gICAgdHJ1bmNhdGVCYWNrVG9TaXplPzogbnVtYmVyLFxuICAgIHR0bDogQ29sbGVjdGlvblR0bCA9IENvbGxlY3Rpb25UdGwuZnJvbUNhY2hlVHRsKClcbiAgKTogUHJvbWlzZTxDYWNoZUxpc3RQdXNoRnJvbnQuUmVzcG9uc2U+IHtcbiAgICB0cnkge1xuICAgICAgdmFsaWRhdGVDYWNoZU5hbWUoY2FjaGVOYW1lKTtcbiAgICAgIHZhbGlkYXRlTGlzdE5hbWUobGlzdE5hbWUpO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgcmV0dXJuIHRoaXMuY2FjaGVTZXJ2aWNlRXJyb3JNYXBwZXIucmV0dXJuT3JUaHJvd0Vycm9yKFxuICAgICAgICBlcnIgYXMgRXJyb3IsXG4gICAgICAgIGVyciA9PiBuZXcgQ2FjaGVMaXN0UHVzaEZyb250LkVycm9yKGVycilcbiAgICAgICk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGF3YWl0IHRoaXMucmF0ZUxpbWl0ZWQoYXN5bmMgKCkgPT4ge1xuICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuc2VuZExpc3RQdXNoRnJvbnQoXG4gICAgICAgIGNhY2hlTmFtZSxcbiAgICAgICAgdGhpcy5jb252ZXJ0KGxpc3ROYW1lKSxcbiAgICAgICAgdGhpcy5jb252ZXJ0KHZhbHVlKSxcbiAgICAgICAgdGhpcy5jb2xsZWN0aW9uVHRsT3JEZWZhdWx0TWlsbGlzZWNvbmRzKHR0bCksXG4gICAgICAgIHR0bC5yZWZyZXNoVHRsKCksXG4gICAgICAgIHRydW5jYXRlQmFja1RvU2l6ZVxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgc2VuZExpc3RQdXNoRnJvbnQoXG4gICAgY2FjaGVOYW1lOiBzdHJpbmcsXG4gICAgbGlzdE5hbWU6IFVpbnQ4QXJyYXksXG4gICAgdmFsdWU6IFVpbnQ4QXJyYXksXG4gICAgdHRsTWlsbGlzZWNvbmRzOiBudW1iZXIsXG4gICAgcmVmcmVzaFR0bDogYm9vbGVhbixcbiAgICB0cnVuY2F0ZUJhY2tUb1NpemU/OiBudW1iZXJcbiAgKTogUHJvbWlzZTxDYWNoZUxpc3RQdXNoRnJvbnQuUmVzcG9uc2U+IHtcbiAgICBjb25zdCByZXF1ZXN0ID0gbmV3IGdycGNDYWNoZS5fTGlzdFB1c2hGcm9udFJlcXVlc3Qoe1xuICAgICAgbGlzdF9uYW1lOiBsaXN0TmFtZSxcbiAgICAgIHZhbHVlOiB2YWx1ZSxcbiAgICAgIHR0bF9taWxsaXNlY29uZHM6IHR0bE1pbGxpc2Vjb25kcyxcbiAgICAgIHJlZnJlc2hfdHRsOiByZWZyZXNoVHRsLFxuICAgICAgdHJ1bmNhdGVfYmFja190b19zaXplOiB0cnVuY2F0ZUJhY2tUb1NpemUsXG4gICAgfSk7XG4gICAgY29uc3QgbWV0YWRhdGEgPSB0aGlzLmNyZWF0ZU1ldGFkYXRhKGNhY2hlTmFtZSk7XG4gICAgcmV0dXJuIGF3YWl0IG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHRoaXMuY2xpZW50V3JhcHBlci5nZXRDbGllbnQoKS5MaXN0UHVzaEZyb250KFxuICAgICAgICByZXF1ZXN0LFxuICAgICAgICBtZXRhZGF0YSxcbiAgICAgICAge1xuICAgICAgICAgIGludGVyY2VwdG9yczogdGhpcy5pbnRlcmNlcHRvcnMsXG4gICAgICAgIH0sXG4gICAgICAgIChlcnIsIHJlc3ApID0+IHtcbiAgICAgICAgICBpZiAocmVzcCkge1xuICAgICAgICAgICAgcmVzb2x2ZShuZXcgQ2FjaGVMaXN0UHVzaEZyb250LlN1Y2Nlc3MocmVzcC5saXN0X2xlbmd0aCkpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmNhY2hlU2VydmljZUVycm9yTWFwcGVyLnJlc29sdmVPclJlamVjdEVycm9yKHtcbiAgICAgICAgICAgICAgZXJyOiBlcnIsXG4gICAgICAgICAgICAgIGVycm9yUmVzcG9uc2VGYWN0b3J5Rm46IGUgPT4gbmV3IENhY2hlTGlzdFB1c2hGcm9udC5FcnJvcihlKSxcbiAgICAgICAgICAgICAgcmVzb2x2ZUZuOiByZXNvbHZlLFxuICAgICAgICAgICAgICByZWplY3RGbjogcmVqZWN0LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICApO1xuICAgIH0pO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIGxpc3RSZW1vdmVWYWx1ZShcbiAgICBjYWNoZU5hbWU6IHN0cmluZyxcbiAgICBsaXN0TmFtZTogc3RyaW5nLFxuICAgIHZhbHVlOiBzdHJpbmcgfCBVaW50OEFycmF5XG4gICk6IFByb21pc2U8Q2FjaGVMaXN0UmVtb3ZlVmFsdWUuUmVzcG9uc2U+IHtcbiAgICB0cnkge1xuICAgICAgdmFsaWRhdGVDYWNoZU5hbWUoY2FjaGVOYW1lKTtcbiAgICAgIHZhbGlkYXRlTGlzdE5hbWUobGlzdE5hbWUpO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgcmV0dXJuIHRoaXMuY2FjaGVTZXJ2aWNlRXJyb3JNYXBwZXIucmV0dXJuT3JUaHJvd0Vycm9yKFxuICAgICAgICBlcnIgYXMgRXJyb3IsXG4gICAgICAgIGVyciA9PiBuZXcgQ2FjaGVMaXN0UmVtb3ZlVmFsdWUuRXJyb3IoZXJyKVxuICAgICAgKTtcbiAgICB9XG5cbiAgICByZXR1cm4gYXdhaXQgdGhpcy5yYXRlTGltaXRlZChhc3luYyAoKSA9PiB7XG4gICAgICByZXR1cm4gYXdhaXQgdGhpcy5zZW5kTGlzdFJlbW92ZVZhbHVlKFxuICAgICAgICBjYWNoZU5hbWUsXG4gICAgICAgIHRoaXMuY29udmVydChsaXN0TmFtZSksXG4gICAgICAgIHRoaXMuY29udmVydCh2YWx1ZSlcbiAgICAgICk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHNlbmRMaXN0UmVtb3ZlVmFsdWUoXG4gICAgY2FjaGVOYW1lOiBzdHJpbmcsXG4gICAgbGlzdE5hbWU6IFVpbnQ4QXJyYXksXG4gICAgdmFsdWU6IFVpbnQ4QXJyYXlcbiAgKTogUHJvbWlzZTxDYWNoZUxpc3RSZW1vdmVWYWx1ZS5SZXNwb25zZT4ge1xuICAgIGNvbnN0IHJlcXVlc3QgPSBuZXcgZ3JwY0NhY2hlLl9MaXN0UmVtb3ZlUmVxdWVzdCh7XG4gICAgICBsaXN0X25hbWU6IGxpc3ROYW1lLFxuICAgICAgYWxsX2VsZW1lbnRzX3dpdGhfdmFsdWU6IHZhbHVlLFxuICAgIH0pO1xuICAgIGNvbnN0IG1ldGFkYXRhID0gdGhpcy5jcmVhdGVNZXRhZGF0YShjYWNoZU5hbWUpO1xuICAgIHJldHVybiBhd2FpdCBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICB0aGlzLmNsaWVudFdyYXBwZXIuZ2V0Q2xpZW50KCkuTGlzdFJlbW92ZShcbiAgICAgICAgcmVxdWVzdCxcbiAgICAgICAgbWV0YWRhdGEsXG4gICAgICAgIHtcbiAgICAgICAgICBpbnRlcmNlcHRvcnM6IHRoaXMuaW50ZXJjZXB0b3JzLFxuICAgICAgICB9LFxuICAgICAgICAoZXJyLCByZXNwKSA9PiB7XG4gICAgICAgICAgaWYgKHJlc3ApIHtcbiAgICAgICAgICAgIHJlc29sdmUobmV3IENhY2hlTGlzdFJlbW92ZVZhbHVlLlN1Y2Nlc3MoKSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuY2FjaGVTZXJ2aWNlRXJyb3JNYXBwZXIucmVzb2x2ZU9yUmVqZWN0RXJyb3Ioe1xuICAgICAgICAgICAgICBlcnI6IGVycixcbiAgICAgICAgICAgICAgZXJyb3JSZXNwb25zZUZhY3RvcnlGbjogZSA9PiBuZXcgQ2FjaGVMaXN0UmVtb3ZlVmFsdWUuRXJyb3IoZSksXG4gICAgICAgICAgICAgIHJlc29sdmVGbjogcmVzb2x2ZSxcbiAgICAgICAgICAgICAgcmVqZWN0Rm46IHJlamVjdCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBkaWN0aW9uYXJ5RmV0Y2goXG4gICAgY2FjaGVOYW1lOiBzdHJpbmcsXG4gICAgZGljdGlvbmFyeU5hbWU6IHN0cmluZ1xuICApOiBQcm9taXNlPENhY2hlRGljdGlvbmFyeUZldGNoLlJlc3BvbnNlPiB7XG4gICAgdHJ5IHtcbiAgICAgIHZhbGlkYXRlQ2FjaGVOYW1lKGNhY2hlTmFtZSk7XG4gICAgICB2YWxpZGF0ZURpY3Rpb25hcnlOYW1lKGRpY3Rpb25hcnlOYW1lKTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIHJldHVybiB0aGlzLmNhY2hlU2VydmljZUVycm9yTWFwcGVyLnJldHVybk9yVGhyb3dFcnJvcihcbiAgICAgICAgZXJyIGFzIEVycm9yLFxuICAgICAgICBlcnIgPT4gbmV3IENhY2hlRGljdGlvbmFyeUZldGNoLkVycm9yKGVycilcbiAgICAgICk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGF3YWl0IHRoaXMucmF0ZUxpbWl0ZWQoYXN5bmMgKCkgPT4ge1xuICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuc2VuZERpY3Rpb25hcnlGZXRjaChcbiAgICAgICAgY2FjaGVOYW1lLFxuICAgICAgICB0aGlzLmNvbnZlcnQoZGljdGlvbmFyeU5hbWUpXG4gICAgICApO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBzZW5kRGljdGlvbmFyeUZldGNoKFxuICAgIGNhY2hlTmFtZTogc3RyaW5nLFxuICAgIGRpY3Rpb25hcnlOYW1lOiBVaW50OEFycmF5XG4gICk6IFByb21pc2U8Q2FjaGVEaWN0aW9uYXJ5RmV0Y2guUmVzcG9uc2U+IHtcbiAgICBjb25zdCByZXF1ZXN0ID0gbmV3IGdycGNDYWNoZS5fRGljdGlvbmFyeUZldGNoUmVxdWVzdCh7XG4gICAgICBkaWN0aW9uYXJ5X25hbWU6IGRpY3Rpb25hcnlOYW1lLFxuICAgIH0pO1xuICAgIGNvbnN0IG1ldGFkYXRhID0gdGhpcy5jcmVhdGVNZXRhZGF0YShjYWNoZU5hbWUpO1xuICAgIHJldHVybiBhd2FpdCBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICB0aGlzLmNsaWVudFdyYXBwZXIuZ2V0Q2xpZW50KCkuRGljdGlvbmFyeUZldGNoKFxuICAgICAgICByZXF1ZXN0LFxuICAgICAgICBtZXRhZGF0YSxcbiAgICAgICAge1xuICAgICAgICAgIGludGVyY2VwdG9yczogdGhpcy5pbnRlcmNlcHRvcnMsXG4gICAgICAgIH0sXG4gICAgICAgIChlcnIsIHJlc3ApID0+IHtcbiAgICAgICAgICBpZiAocmVzcD8uZm91bmQpIHtcbiAgICAgICAgICAgIHJlc29sdmUobmV3IENhY2hlRGljdGlvbmFyeUZldGNoLkhpdChyZXNwLmZvdW5kLml0ZW1zKSk7XG4gICAgICAgICAgfSBlbHNlIGlmIChyZXNwPy5taXNzaW5nKSB7XG4gICAgICAgICAgICByZXNvbHZlKG5ldyBDYWNoZURpY3Rpb25hcnlGZXRjaC5NaXNzKCkpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmNhY2hlU2VydmljZUVycm9yTWFwcGVyLnJlc29sdmVPclJlamVjdEVycm9yKHtcbiAgICAgICAgICAgICAgZXJyOiBlcnIsXG4gICAgICAgICAgICAgIGVycm9yUmVzcG9uc2VGYWN0b3J5Rm46IGUgPT4gbmV3IENhY2hlRGljdGlvbmFyeUZldGNoLkVycm9yKGUpLFxuICAgICAgICAgICAgICByZXNvbHZlRm46IHJlc29sdmUsXG4gICAgICAgICAgICAgIHJlamVjdEZuOiByZWplY3QsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICk7XG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgZGljdGlvbmFyeVNldEZpZWxkKFxuICAgIGNhY2hlTmFtZTogc3RyaW5nLFxuICAgIGRpY3Rpb25hcnlOYW1lOiBzdHJpbmcsXG4gICAgZmllbGQ6IHN0cmluZyB8IFVpbnQ4QXJyYXksXG4gICAgdmFsdWU6IHN0cmluZyB8IFVpbnQ4QXJyYXksXG4gICAgdHRsOiBDb2xsZWN0aW9uVHRsID0gQ29sbGVjdGlvblR0bC5mcm9tQ2FjaGVUdGwoKVxuICApOiBQcm9taXNlPENhY2hlRGljdGlvbmFyeVNldEZpZWxkLlJlc3BvbnNlPiB7XG4gICAgdHJ5IHtcbiAgICAgIHZhbGlkYXRlQ2FjaGVOYW1lKGNhY2hlTmFtZSk7XG4gICAgICB2YWxpZGF0ZURpY3Rpb25hcnlOYW1lKGRpY3Rpb25hcnlOYW1lKTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIHJldHVybiB0aGlzLmNhY2hlU2VydmljZUVycm9yTWFwcGVyLnJldHVybk9yVGhyb3dFcnJvcihcbiAgICAgICAgZXJyIGFzIEVycm9yLFxuICAgICAgICBlcnIgPT4gbmV3IENhY2hlRGljdGlvbmFyeVNldEZpZWxkLkVycm9yKGVycilcbiAgICAgICk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGF3YWl0IHRoaXMucmF0ZUxpbWl0ZWQoYXN5bmMgKCkgPT4ge1xuICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuc2VuZERpY3Rpb25hcnlTZXRGaWVsZChcbiAgICAgICAgY2FjaGVOYW1lLFxuICAgICAgICB0aGlzLmNvbnZlcnQoZGljdGlvbmFyeU5hbWUpLFxuICAgICAgICB0aGlzLmNvbnZlcnQoZmllbGQpLFxuICAgICAgICB0aGlzLmNvbnZlcnQodmFsdWUpLFxuICAgICAgICB0aGlzLmNvbGxlY3Rpb25UdGxPckRlZmF1bHRNaWxsaXNlY29uZHModHRsKSxcbiAgICAgICAgdHRsLnJlZnJlc2hUdGwoKVxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgc2VuZERpY3Rpb25hcnlTZXRGaWVsZChcbiAgICBjYWNoZU5hbWU6IHN0cmluZyxcbiAgICBkaWN0aW9uYXJ5TmFtZTogVWludDhBcnJheSxcbiAgICBmaWVsZDogVWludDhBcnJheSxcbiAgICB2YWx1ZTogVWludDhBcnJheSxcbiAgICB0dGxNaWxsaXNlY29uZHM6IG51bWJlcixcbiAgICByZWZyZXNoVHRsOiBib29sZWFuXG4gICk6IFByb21pc2U8Q2FjaGVEaWN0aW9uYXJ5U2V0RmllbGQuUmVzcG9uc2U+IHtcbiAgICBjb25zdCByZXF1ZXN0ID0gbmV3IGdycGNDYWNoZS5fRGljdGlvbmFyeVNldFJlcXVlc3Qoe1xuICAgICAgZGljdGlvbmFyeV9uYW1lOiBkaWN0aW9uYXJ5TmFtZSxcbiAgICAgIGl0ZW1zOiB0aGlzLnRvU2luZ2xldG9uRmllbGRWYWx1ZVBhaXIoZmllbGQsIHZhbHVlKSxcbiAgICAgIHR0bF9taWxsaXNlY29uZHM6IHR0bE1pbGxpc2Vjb25kcyxcbiAgICAgIHJlZnJlc2hfdHRsOiByZWZyZXNoVHRsLFxuICAgIH0pO1xuICAgIGNvbnN0IG1ldGFkYXRhID0gdGhpcy5jcmVhdGVNZXRhZGF0YShjYWNoZU5hbWUpO1xuICAgIHJldHVybiBhd2FpdCBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICB0aGlzLmNsaWVudFdyYXBwZXIuZ2V0Q2xpZW50KCkuRGljdGlvbmFyeVNldChcbiAgICAgICAgcmVxdWVzdCxcbiAgICAgICAgbWV0YWRhdGEsXG4gICAgICAgIHtcbiAgICAgICAgICBpbnRlcmNlcHRvcnM6IHRoaXMuaW50ZXJjZXB0b3JzLFxuICAgICAgICB9LFxuICAgICAgICAoZXJyLCByZXNwKSA9PiB7XG4gICAgICAgICAgaWYgKHJlc3ApIHtcbiAgICAgICAgICAgIHJlc29sdmUobmV3IENhY2hlRGljdGlvbmFyeVNldEZpZWxkLlN1Y2Nlc3MoKSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuY2FjaGVTZXJ2aWNlRXJyb3JNYXBwZXIucmVzb2x2ZU9yUmVqZWN0RXJyb3Ioe1xuICAgICAgICAgICAgICBlcnI6IGVycixcbiAgICAgICAgICAgICAgZXJyb3JSZXNwb25zZUZhY3RvcnlGbjogZSA9PiBuZXcgQ2FjaGVEaWN0aW9uYXJ5U2V0RmllbGQuRXJyb3IoZSksXG4gICAgICAgICAgICAgIHJlc29sdmVGbjogcmVzb2x2ZSxcbiAgICAgICAgICAgICAgcmVqZWN0Rm46IHJlamVjdCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBkaWN0aW9uYXJ5U2V0RmllbGRzKFxuICAgIGNhY2hlTmFtZTogc3RyaW5nLFxuICAgIGRpY3Rpb25hcnlOYW1lOiBzdHJpbmcsXG4gICAgZWxlbWVudHM6XG4gICAgICB8IE1hcDxzdHJpbmcgfCBVaW50OEFycmF5LCBzdHJpbmcgfCBVaW50OEFycmF5PlxuICAgICAgfCBSZWNvcmQ8c3RyaW5nLCBzdHJpbmcgfCBVaW50OEFycmF5PlxuICAgICAgfCBBcnJheTxbc3RyaW5nLCBzdHJpbmcgfCBVaW50OEFycmF5XT4sXG4gICAgdHRsOiBDb2xsZWN0aW9uVHRsID0gQ29sbGVjdGlvblR0bC5mcm9tQ2FjaGVUdGwoKVxuICApOiBQcm9taXNlPENhY2hlRGljdGlvbmFyeVNldEZpZWxkcy5SZXNwb25zZT4ge1xuICAgIHRyeSB7XG4gICAgICB2YWxpZGF0ZUNhY2hlTmFtZShjYWNoZU5hbWUpO1xuICAgICAgdmFsaWRhdGVEaWN0aW9uYXJ5TmFtZShkaWN0aW9uYXJ5TmFtZSk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICByZXR1cm4gdGhpcy5jYWNoZVNlcnZpY2VFcnJvck1hcHBlci5yZXR1cm5PclRocm93RXJyb3IoXG4gICAgICAgIGVyciBhcyBFcnJvcixcbiAgICAgICAgZXJyID0+IG5ldyBDYWNoZURpY3Rpb25hcnlTZXRGaWVsZHMuRXJyb3IoZXJyKVxuICAgICAgKTtcbiAgICB9XG5cbiAgICByZXR1cm4gYXdhaXQgdGhpcy5yYXRlTGltaXRlZChhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBkaWN0aW9uYXJ5RmllbGRWYWx1ZVBhaXJzID0gdGhpcy5jb252ZXJ0RWxlbWVudHMoZWxlbWVudHMpO1xuXG4gICAgICByZXR1cm4gYXdhaXQgdGhpcy5zZW5kRGljdGlvbmFyeVNldEZpZWxkcyhcbiAgICAgICAgY2FjaGVOYW1lLFxuICAgICAgICB0aGlzLmNvbnZlcnQoZGljdGlvbmFyeU5hbWUpLFxuICAgICAgICBkaWN0aW9uYXJ5RmllbGRWYWx1ZVBhaXJzLFxuICAgICAgICB0aGlzLmNvbGxlY3Rpb25UdGxPckRlZmF1bHRNaWxsaXNlY29uZHModHRsKSxcbiAgICAgICAgdHRsLnJlZnJlc2hUdGwoKVxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgc2VuZERpY3Rpb25hcnlTZXRGaWVsZHMoXG4gICAgY2FjaGVOYW1lOiBzdHJpbmcsXG4gICAgZGljdGlvbmFyeU5hbWU6IFVpbnQ4QXJyYXksXG4gICAgZWxlbWVudHM6IGdycGNDYWNoZS5fRGljdGlvbmFyeUZpZWxkVmFsdWVQYWlyW10sXG4gICAgdHRsTWlsbGlzZWNvbmRzOiBudW1iZXIsXG4gICAgcmVmcmVzaFR0bDogYm9vbGVhblxuICApOiBQcm9taXNlPENhY2hlRGljdGlvbmFyeVNldEZpZWxkcy5SZXNwb25zZT4ge1xuICAgIGNvbnN0IHJlcXVlc3QgPSBuZXcgZ3JwY0NhY2hlLl9EaWN0aW9uYXJ5U2V0UmVxdWVzdCh7XG4gICAgICBkaWN0aW9uYXJ5X25hbWU6IGRpY3Rpb25hcnlOYW1lLFxuICAgICAgaXRlbXM6IGVsZW1lbnRzLFxuICAgICAgdHRsX21pbGxpc2Vjb25kczogdHRsTWlsbGlzZWNvbmRzLFxuICAgICAgcmVmcmVzaF90dGw6IHJlZnJlc2hUdGwsXG4gICAgfSk7XG4gICAgY29uc3QgbWV0YWRhdGEgPSB0aGlzLmNyZWF0ZU1ldGFkYXRhKGNhY2hlTmFtZSk7XG4gICAgcmV0dXJuIGF3YWl0IG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHRoaXMuY2xpZW50V3JhcHBlci5nZXRDbGllbnQoKS5EaWN0aW9uYXJ5U2V0KFxuICAgICAgICByZXF1ZXN0LFxuICAgICAgICBtZXRhZGF0YSxcbiAgICAgICAge1xuICAgICAgICAgIGludGVyY2VwdG9yczogdGhpcy5pbnRlcmNlcHRvcnMsXG4gICAgICAgIH0sXG4gICAgICAgIChlcnIsIHJlc3ApID0+IHtcbiAgICAgICAgICBpZiAocmVzcCkge1xuICAgICAgICAgICAgcmVzb2x2ZShuZXcgQ2FjaGVEaWN0aW9uYXJ5U2V0RmllbGRzLlN1Y2Nlc3MoKSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuY2FjaGVTZXJ2aWNlRXJyb3JNYXBwZXIucmVzb2x2ZU9yUmVqZWN0RXJyb3Ioe1xuICAgICAgICAgICAgICBlcnI6IGVycixcbiAgICAgICAgICAgICAgZXJyb3JSZXNwb25zZUZhY3RvcnlGbjogZSA9PlxuICAgICAgICAgICAgICAgIG5ldyBDYWNoZURpY3Rpb25hcnlTZXRGaWVsZHMuRXJyb3IoZSksXG4gICAgICAgICAgICAgIHJlc29sdmVGbjogcmVzb2x2ZSxcbiAgICAgICAgICAgICAgcmVqZWN0Rm46IHJlamVjdCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBkaWN0aW9uYXJ5R2V0RmllbGQoXG4gICAgY2FjaGVOYW1lOiBzdHJpbmcsXG4gICAgZGljdGlvbmFyeU5hbWU6IHN0cmluZyxcbiAgICBmaWVsZDogc3RyaW5nIHwgVWludDhBcnJheVxuICApOiBQcm9taXNlPENhY2hlRGljdGlvbmFyeUdldEZpZWxkLlJlc3BvbnNlPiB7XG4gICAgdHJ5IHtcbiAgICAgIHZhbGlkYXRlQ2FjaGVOYW1lKGNhY2hlTmFtZSk7XG4gICAgICB2YWxpZGF0ZURpY3Rpb25hcnlOYW1lKGRpY3Rpb25hcnlOYW1lKTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIHJldHVybiB0aGlzLmNhY2hlU2VydmljZUVycm9yTWFwcGVyLnJldHVybk9yVGhyb3dFcnJvcihcbiAgICAgICAgZXJyIGFzIEVycm9yLFxuICAgICAgICBlcnIgPT4gbmV3IENhY2hlRGljdGlvbmFyeUdldEZpZWxkLkVycm9yKGVyciwgdGhpcy5jb252ZXJ0KGZpZWxkKSlcbiAgICAgICk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGF3YWl0IHRoaXMucmF0ZUxpbWl0ZWQoYXN5bmMgKCkgPT4ge1xuICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuc2VuZERpY3Rpb25hcnlHZXRGaWVsZChcbiAgICAgICAgY2FjaGVOYW1lLFxuICAgICAgICB0aGlzLmNvbnZlcnQoZGljdGlvbmFyeU5hbWUpLFxuICAgICAgICB0aGlzLmNvbnZlcnQoZmllbGQpXG4gICAgICApO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBzZW5kRGljdGlvbmFyeUdldEZpZWxkKFxuICAgIGNhY2hlTmFtZTogc3RyaW5nLFxuICAgIGRpY3Rpb25hcnlOYW1lOiBVaW50OEFycmF5LFxuICAgIGZpZWxkOiBVaW50OEFycmF5XG4gICk6IFByb21pc2U8Q2FjaGVEaWN0aW9uYXJ5R2V0RmllbGQuUmVzcG9uc2U+IHtcbiAgICBjb25zdCByZXF1ZXN0ID0gbmV3IGdycGNDYWNoZS5fRGljdGlvbmFyeUdldFJlcXVlc3Qoe1xuICAgICAgZGljdGlvbmFyeV9uYW1lOiBkaWN0aW9uYXJ5TmFtZSxcbiAgICAgIGZpZWxkczogW2ZpZWxkXSxcbiAgICB9KTtcbiAgICBjb25zdCBtZXRhZGF0YSA9IHRoaXMuY3JlYXRlTWV0YWRhdGEoY2FjaGVOYW1lKTtcblxuICAgIHJldHVybiBhd2FpdCBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICB0aGlzLmNsaWVudFdyYXBwZXIuZ2V0Q2xpZW50KCkuRGljdGlvbmFyeUdldChcbiAgICAgICAgcmVxdWVzdCxcbiAgICAgICAgbWV0YWRhdGEsXG4gICAgICAgIHtcbiAgICAgICAgICBpbnRlcmNlcHRvcnM6IHRoaXMuaW50ZXJjZXB0b3JzLFxuICAgICAgICB9LFxuICAgICAgICAoZXJyLCByZXNwKSA9PiB7XG4gICAgICAgICAgaWYgKHJlc3A/LmRpY3Rpb25hcnkgPT09ICdtaXNzaW5nJykge1xuICAgICAgICAgICAgcmVzb2x2ZShuZXcgQ2FjaGVEaWN0aW9uYXJ5R2V0RmllbGQuTWlzcyhmaWVsZCkpO1xuICAgICAgICAgIH0gZWxzZSBpZiAocmVzcD8uZGljdGlvbmFyeSA9PT0gJ2ZvdW5kJykge1xuICAgICAgICAgICAgaWYgKHJlc3A/LmZvdW5kLml0ZW1zLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICByZXNvbHZlKFxuICAgICAgICAgICAgICAgIG5ldyBDYWNoZURpY3Rpb25hcnlHZXRGaWVsZC5FcnJvcihcbiAgICAgICAgICAgICAgICAgIG5ldyBVbmtub3duRXJyb3IoXG4gICAgICAgICAgICAgICAgICAgICdfRGljdGlvbmFyeUdldFJlc3BvbnNlUmVzcG9uc2UgY29udGFpbmVkIG5vIGRhdGEgYnV0IHdhcyBmb3VuZCdcbiAgICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgICAgICBmaWVsZFxuICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoXG4gICAgICAgICAgICAgIHJlc3A/LmZvdW5kLml0ZW1zWzBdLnJlc3VsdCA9PT0gZ3JwY0NhY2hlLkVDYWNoZVJlc3VsdC5NaXNzXG4gICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgcmVzb2x2ZShuZXcgQ2FjaGVEaWN0aW9uYXJ5R2V0RmllbGQuTWlzcyhmaWVsZCkpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgcmVzb2x2ZShcbiAgICAgICAgICAgICAgICBuZXcgQ2FjaGVEaWN0aW9uYXJ5R2V0RmllbGQuSGl0KFxuICAgICAgICAgICAgICAgICAgcmVzcD8uZm91bmQuaXRlbXNbMF0uY2FjaGVfYm9keSxcbiAgICAgICAgICAgICAgICAgIGZpZWxkXG4gICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmNhY2hlU2VydmljZUVycm9yTWFwcGVyLnJlc29sdmVPclJlamVjdEVycm9yKHtcbiAgICAgICAgICAgICAgZXJyOiBlcnIsXG4gICAgICAgICAgICAgIGVycm9yUmVzcG9uc2VGYWN0b3J5Rm46IGUgPT5cbiAgICAgICAgICAgICAgICBuZXcgQ2FjaGVEaWN0aW9uYXJ5R2V0RmllbGQuRXJyb3IoZSwgZmllbGQpLFxuICAgICAgICAgICAgICByZXNvbHZlRm46IHJlc29sdmUsXG4gICAgICAgICAgICAgIHJlamVjdEZuOiByZWplY3QsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICk7XG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgZGljdGlvbmFyeUdldEZpZWxkcyhcbiAgICBjYWNoZU5hbWU6IHN0cmluZyxcbiAgICBkaWN0aW9uYXJ5TmFtZTogc3RyaW5nLFxuICAgIGZpZWxkczogc3RyaW5nW10gfCBVaW50OEFycmF5W11cbiAgKTogUHJvbWlzZTxDYWNoZURpY3Rpb25hcnlHZXRGaWVsZHMuUmVzcG9uc2U+IHtcbiAgICB0cnkge1xuICAgICAgdmFsaWRhdGVDYWNoZU5hbWUoY2FjaGVOYW1lKTtcbiAgICAgIHZhbGlkYXRlRGljdGlvbmFyeU5hbWUoZGljdGlvbmFyeU5hbWUpO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgcmV0dXJuIHRoaXMuY2FjaGVTZXJ2aWNlRXJyb3JNYXBwZXIucmV0dXJuT3JUaHJvd0Vycm9yKFxuICAgICAgICBlcnIgYXMgRXJyb3IsXG4gICAgICAgIGVyciA9PiBuZXcgQ2FjaGVEaWN0aW9uYXJ5R2V0RmllbGRzLkVycm9yKGVycilcbiAgICAgICk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGF3YWl0IHRoaXMucmF0ZUxpbWl0ZWQoYXN5bmMgKCkgPT4ge1xuICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuc2VuZERpY3Rpb25hcnlHZXRGaWVsZHMoXG4gICAgICAgIGNhY2hlTmFtZSxcbiAgICAgICAgdGhpcy5jb252ZXJ0KGRpY3Rpb25hcnlOYW1lKSxcbiAgICAgICAgdGhpcy5jb252ZXJ0QXJyYXkoZmllbGRzKVxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgc2VuZERpY3Rpb25hcnlHZXRGaWVsZHMoXG4gICAgY2FjaGVOYW1lOiBzdHJpbmcsXG4gICAgZGljdGlvbmFyeU5hbWU6IFVpbnQ4QXJyYXksXG4gICAgZmllbGRzOiBVaW50OEFycmF5W11cbiAgKTogUHJvbWlzZTxDYWNoZURpY3Rpb25hcnlHZXRGaWVsZHMuUmVzcG9uc2U+IHtcbiAgICBjb25zdCByZXF1ZXN0ID0gbmV3IGdycGNDYWNoZS5fRGljdGlvbmFyeUdldFJlcXVlc3Qoe1xuICAgICAgZGljdGlvbmFyeV9uYW1lOiBkaWN0aW9uYXJ5TmFtZSxcbiAgICAgIGZpZWxkczogZmllbGRzLFxuICAgIH0pO1xuICAgIGNvbnN0IG1ldGFkYXRhID0gdGhpcy5jcmVhdGVNZXRhZGF0YShjYWNoZU5hbWUpO1xuXG4gICAgcmV0dXJuIGF3YWl0IG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHRoaXMuY2xpZW50V3JhcHBlci5nZXRDbGllbnQoKS5EaWN0aW9uYXJ5R2V0KFxuICAgICAgICByZXF1ZXN0LFxuICAgICAgICBtZXRhZGF0YSxcbiAgICAgICAge1xuICAgICAgICAgIGludGVyY2VwdG9yczogdGhpcy5pbnRlcmNlcHRvcnMsXG4gICAgICAgIH0sXG4gICAgICAgIChlcnIsIHJlc3ApID0+IHtcbiAgICAgICAgICBpZiAocmVzcD8uZGljdGlvbmFyeSA9PT0gJ2ZvdW5kJykge1xuICAgICAgICAgICAgY29uc3QgaXRlbXMgPSByZXNwLmZvdW5kLml0ZW1zLm1hcChpdGVtID0+IHtcbiAgICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gdGhpcy5jb252ZXJ0RUNhY2hlUmVzdWx0KGl0ZW0ucmVzdWx0KTtcbiAgICAgICAgICAgICAgcmV0dXJuIG5ldyBfRGljdGlvbmFyeUdldFJlc3BvbnNlUGFydChyZXN1bHQsIGl0ZW0uY2FjaGVfYm9keSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHJlc29sdmUobmV3IENhY2hlRGljdGlvbmFyeUdldEZpZWxkcy5IaXQoaXRlbXMsIGZpZWxkcykpO1xuICAgICAgICAgIH0gZWxzZSBpZiAocmVzcD8uZGljdGlvbmFyeSA9PT0gJ21pc3NpbmcnKSB7XG4gICAgICAgICAgICByZXNvbHZlKG5ldyBDYWNoZURpY3Rpb25hcnlHZXRGaWVsZHMuTWlzcygpKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5jYWNoZVNlcnZpY2VFcnJvck1hcHBlci5yZXNvbHZlT3JSZWplY3RFcnJvcih7XG4gICAgICAgICAgICAgIGVycjogZXJyLFxuICAgICAgICAgICAgICBlcnJvclJlc3BvbnNlRmFjdG9yeUZuOiBlID0+XG4gICAgICAgICAgICAgICAgbmV3IENhY2hlRGljdGlvbmFyeUdldEZpZWxkcy5FcnJvcihlKSxcbiAgICAgICAgICAgICAgcmVzb2x2ZUZuOiByZXNvbHZlLFxuICAgICAgICAgICAgICByZWplY3RGbjogcmVqZWN0LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICApO1xuICAgIH0pO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIGRpY3Rpb25hcnlSZW1vdmVGaWVsZChcbiAgICBjYWNoZU5hbWU6IHN0cmluZyxcbiAgICBkaWN0aW9uYXJ5TmFtZTogc3RyaW5nLFxuICAgIGZpZWxkOiBzdHJpbmcgfCBVaW50OEFycmF5XG4gICk6IFByb21pc2U8Q2FjaGVEaWN0aW9uYXJ5UmVtb3ZlRmllbGQuUmVzcG9uc2U+IHtcbiAgICB0cnkge1xuICAgICAgdmFsaWRhdGVDYWNoZU5hbWUoY2FjaGVOYW1lKTtcbiAgICAgIHZhbGlkYXRlRGljdGlvbmFyeU5hbWUoZGljdGlvbmFyeU5hbWUpO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgcmV0dXJuIHRoaXMuY2FjaGVTZXJ2aWNlRXJyb3JNYXBwZXIucmV0dXJuT3JUaHJvd0Vycm9yKFxuICAgICAgICBlcnIgYXMgRXJyb3IsXG4gICAgICAgIGVyciA9PiBuZXcgQ2FjaGVEaWN0aW9uYXJ5UmVtb3ZlRmllbGQuRXJyb3IoZXJyKVxuICAgICAgKTtcbiAgICB9XG5cbiAgICByZXR1cm4gYXdhaXQgdGhpcy5yYXRlTGltaXRlZChhc3luYyAoKSA9PiB7XG4gICAgICByZXR1cm4gYXdhaXQgdGhpcy5zZW5kRGljdGlvbmFyeVJlbW92ZUZpZWxkKFxuICAgICAgICBjYWNoZU5hbWUsXG4gICAgICAgIHRoaXMuY29udmVydChkaWN0aW9uYXJ5TmFtZSksXG4gICAgICAgIHRoaXMuY29udmVydChmaWVsZClcbiAgICAgICk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHNlbmREaWN0aW9uYXJ5UmVtb3ZlRmllbGQoXG4gICAgY2FjaGVOYW1lOiBzdHJpbmcsXG4gICAgZGljdGlvbmFyeU5hbWU6IFVpbnQ4QXJyYXksXG4gICAgZmllbGQ6IFVpbnQ4QXJyYXlcbiAgKTogUHJvbWlzZTxDYWNoZURpY3Rpb25hcnlSZW1vdmVGaWVsZC5SZXNwb25zZT4ge1xuICAgIGNvbnN0IHJlcXVlc3QgPSBuZXcgZ3JwY0NhY2hlLl9EaWN0aW9uYXJ5RGVsZXRlUmVxdWVzdCh7XG4gICAgICBkaWN0aW9uYXJ5X25hbWU6IGRpY3Rpb25hcnlOYW1lLFxuICAgICAgc29tZTogbmV3IGdycGNDYWNoZS5fRGljdGlvbmFyeURlbGV0ZVJlcXVlc3QuU29tZSgpLFxuICAgIH0pO1xuICAgIHJlcXVlc3Quc29tZS5maWVsZHMucHVzaChmaWVsZCk7XG4gICAgY29uc3QgbWV0YWRhdGEgPSB0aGlzLmNyZWF0ZU1ldGFkYXRhKGNhY2hlTmFtZSk7XG5cbiAgICByZXR1cm4gYXdhaXQgbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgdGhpcy5jbGllbnRXcmFwcGVyLmdldENsaWVudCgpLkRpY3Rpb25hcnlEZWxldGUoXG4gICAgICAgIHJlcXVlc3QsXG4gICAgICAgIG1ldGFkYXRhLFxuICAgICAgICB7XG4gICAgICAgICAgaW50ZXJjZXB0b3JzOiB0aGlzLmludGVyY2VwdG9ycyxcbiAgICAgICAgfSxcbiAgICAgICAgKGVyciwgcmVzcCkgPT4ge1xuICAgICAgICAgIGlmIChyZXNwKSB7XG4gICAgICAgICAgICByZXNvbHZlKG5ldyBDYWNoZURpY3Rpb25hcnlSZW1vdmVGaWVsZC5TdWNjZXNzKCkpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmNhY2hlU2VydmljZUVycm9yTWFwcGVyLnJlc29sdmVPclJlamVjdEVycm9yKHtcbiAgICAgICAgICAgICAgZXJyOiBlcnIsXG4gICAgICAgICAgICAgIGVycm9yUmVzcG9uc2VGYWN0b3J5Rm46IGUgPT5cbiAgICAgICAgICAgICAgICBuZXcgQ2FjaGVEaWN0aW9uYXJ5UmVtb3ZlRmllbGQuRXJyb3IoZSksXG4gICAgICAgICAgICAgIHJlc29sdmVGbjogcmVzb2x2ZSxcbiAgICAgICAgICAgICAgcmVqZWN0Rm46IHJlamVjdCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBkaWN0aW9uYXJ5UmVtb3ZlRmllbGRzKFxuICAgIGNhY2hlTmFtZTogc3RyaW5nLFxuICAgIGRpY3Rpb25hcnlOYW1lOiBzdHJpbmcsXG4gICAgZmllbGRzOiBzdHJpbmdbXSB8IFVpbnQ4QXJyYXlbXVxuICApOiBQcm9taXNlPENhY2hlRGljdGlvbmFyeVJlbW92ZUZpZWxkcy5SZXNwb25zZT4ge1xuICAgIHRyeSB7XG4gICAgICB2YWxpZGF0ZUNhY2hlTmFtZShjYWNoZU5hbWUpO1xuICAgICAgdmFsaWRhdGVEaWN0aW9uYXJ5TmFtZShkaWN0aW9uYXJ5TmFtZSk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICByZXR1cm4gdGhpcy5jYWNoZVNlcnZpY2VFcnJvck1hcHBlci5yZXR1cm5PclRocm93RXJyb3IoXG4gICAgICAgIGVyciBhcyBFcnJvcixcbiAgICAgICAgZXJyID0+IG5ldyBDYWNoZURpY3Rpb25hcnlSZW1vdmVGaWVsZHMuRXJyb3IoZXJyKVxuICAgICAgKTtcbiAgICB9XG5cbiAgICByZXR1cm4gYXdhaXQgdGhpcy5yYXRlTGltaXRlZChhc3luYyAoKSA9PiB7XG4gICAgICByZXR1cm4gYXdhaXQgdGhpcy5zZW5kRGljdGlvbmFyeVJlbW92ZUZpZWxkcyhcbiAgICAgICAgY2FjaGVOYW1lLFxuICAgICAgICB0aGlzLmNvbnZlcnQoZGljdGlvbmFyeU5hbWUpLFxuICAgICAgICB0aGlzLmNvbnZlcnRBcnJheShmaWVsZHMpXG4gICAgICApO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBzZW5kRGljdGlvbmFyeVJlbW92ZUZpZWxkcyhcbiAgICBjYWNoZU5hbWU6IHN0cmluZyxcbiAgICBkaWN0aW9uYXJ5TmFtZTogVWludDhBcnJheSxcbiAgICBmaWVsZHM6IFVpbnQ4QXJyYXlbXVxuICApOiBQcm9taXNlPENhY2hlRGljdGlvbmFyeVJlbW92ZUZpZWxkcy5SZXNwb25zZT4ge1xuICAgIGNvbnN0IHJlcXVlc3QgPSBuZXcgZ3JwY0NhY2hlLl9EaWN0aW9uYXJ5RGVsZXRlUmVxdWVzdCh7XG4gICAgICBkaWN0aW9uYXJ5X25hbWU6IGRpY3Rpb25hcnlOYW1lLFxuICAgICAgc29tZTogbmV3IGdycGNDYWNoZS5fRGljdGlvbmFyeURlbGV0ZVJlcXVlc3QuU29tZSgpLFxuICAgIH0pO1xuICAgIGZpZWxkcy5mb3JFYWNoKGZpZWxkID0+IHJlcXVlc3Quc29tZS5maWVsZHMucHVzaChmaWVsZCkpO1xuICAgIGNvbnN0IG1ldGFkYXRhID0gdGhpcy5jcmVhdGVNZXRhZGF0YShjYWNoZU5hbWUpO1xuXG4gICAgcmV0dXJuIGF3YWl0IG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHRoaXMuY2xpZW50V3JhcHBlci5nZXRDbGllbnQoKS5EaWN0aW9uYXJ5RGVsZXRlKFxuICAgICAgICByZXF1ZXN0LFxuICAgICAgICBtZXRhZGF0YSxcbiAgICAgICAge1xuICAgICAgICAgIGludGVyY2VwdG9yczogdGhpcy5pbnRlcmNlcHRvcnMsXG4gICAgICAgIH0sXG4gICAgICAgIChlcnIsIHJlc3ApID0+IHtcbiAgICAgICAgICBpZiAocmVzcCkge1xuICAgICAgICAgICAgcmVzb2x2ZShuZXcgQ2FjaGVEaWN0aW9uYXJ5UmVtb3ZlRmllbGRzLlN1Y2Nlc3MoKSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuY2FjaGVTZXJ2aWNlRXJyb3JNYXBwZXIucmVzb2x2ZU9yUmVqZWN0RXJyb3Ioe1xuICAgICAgICAgICAgICBlcnI6IGVycixcbiAgICAgICAgICAgICAgZXJyb3JSZXNwb25zZUZhY3RvcnlGbjogZSA9PlxuICAgICAgICAgICAgICAgIG5ldyBDYWNoZURpY3Rpb25hcnlSZW1vdmVGaWVsZHMuRXJyb3IoZSksXG4gICAgICAgICAgICAgIHJlc29sdmVGbjogcmVzb2x2ZSxcbiAgICAgICAgICAgICAgcmVqZWN0Rm46IHJlamVjdCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBkaWN0aW9uYXJ5TGVuZ3RoKFxuICAgIGNhY2hlTmFtZTogc3RyaW5nLFxuICAgIGRpY3Rpb25hcnlOYW1lOiBzdHJpbmdcbiAgKTogUHJvbWlzZTxDYWNoZURpY3Rpb25hcnlMZW5ndGguUmVzcG9uc2U+IHtcbiAgICB0cnkge1xuICAgICAgdmFsaWRhdGVDYWNoZU5hbWUoY2FjaGVOYW1lKTtcbiAgICAgIHZhbGlkYXRlRGljdGlvbmFyeU5hbWUoZGljdGlvbmFyeU5hbWUpO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgcmV0dXJuIHRoaXMuY2FjaGVTZXJ2aWNlRXJyb3JNYXBwZXIucmV0dXJuT3JUaHJvd0Vycm9yKFxuICAgICAgICBlcnIgYXMgRXJyb3IsXG4gICAgICAgIGVyciA9PiBuZXcgQ2FjaGVEaWN0aW9uYXJ5TGVuZ3RoLkVycm9yKGVycilcbiAgICAgICk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGF3YWl0IHRoaXMucmF0ZUxpbWl0ZWQoYXN5bmMgKCkgPT4ge1xuICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuc2VuZERpY3Rpb25hcnlMZW5ndGgoXG4gICAgICAgIGNhY2hlTmFtZSxcbiAgICAgICAgdGhpcy5jb252ZXJ0KGRpY3Rpb25hcnlOYW1lKVxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgc2VuZERpY3Rpb25hcnlMZW5ndGgoXG4gICAgY2FjaGVOYW1lOiBzdHJpbmcsXG4gICAgZGljdGlvbmFyeU5hbWU6IFVpbnQ4QXJyYXlcbiAgKTogUHJvbWlzZTxDYWNoZURpY3Rpb25hcnlMZW5ndGguUmVzcG9uc2U+IHtcbiAgICBjb25zdCByZXF1ZXN0ID0gbmV3IGdycGNDYWNoZS5fRGljdGlvbmFyeUxlbmd0aFJlcXVlc3Qoe1xuICAgICAgZGljdGlvbmFyeV9uYW1lOiBkaWN0aW9uYXJ5TmFtZSxcbiAgICB9KTtcbiAgICBjb25zdCBtZXRhZGF0YSA9IHRoaXMuY3JlYXRlTWV0YWRhdGEoY2FjaGVOYW1lKTtcblxuICAgIHJldHVybiBhd2FpdCBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICB0aGlzLmNsaWVudFdyYXBwZXIuZ2V0Q2xpZW50KCkuRGljdGlvbmFyeUxlbmd0aChcbiAgICAgICAgcmVxdWVzdCxcbiAgICAgICAgbWV0YWRhdGEsXG4gICAgICAgIHtcbiAgICAgICAgICBpbnRlcmNlcHRvcnM6IHRoaXMuaW50ZXJjZXB0b3JzLFxuICAgICAgICB9LFxuICAgICAgICAoZXJyLCByZXNwKSA9PiB7XG4gICAgICAgICAgaWYgKHJlc3A/Lm1pc3NpbmcpIHtcbiAgICAgICAgICAgIHJlc29sdmUobmV3IENhY2hlRGljdGlvbmFyeUxlbmd0aC5NaXNzKCkpO1xuICAgICAgICAgIH0gZWxzZSBpZiAocmVzcD8uZm91bmQpIHtcbiAgICAgICAgICAgIHJlc29sdmUobmV3IENhY2hlRGljdGlvbmFyeUxlbmd0aC5IaXQocmVzcC5mb3VuZC5sZW5ndGgpKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5jYWNoZVNlcnZpY2VFcnJvck1hcHBlci5yZXNvbHZlT3JSZWplY3RFcnJvcih7XG4gICAgICAgICAgICAgIGVycjogZXJyLFxuICAgICAgICAgICAgICBlcnJvclJlc3BvbnNlRmFjdG9yeUZuOiBlID0+IG5ldyBDYWNoZURpY3Rpb25hcnlMZW5ndGguRXJyb3IoZSksXG4gICAgICAgICAgICAgIHJlc29sdmVGbjogcmVzb2x2ZSxcbiAgICAgICAgICAgICAgcmVqZWN0Rm46IHJlamVjdCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBpbmNyZW1lbnQoXG4gICAgY2FjaGVOYW1lOiBzdHJpbmcsXG4gICAgZmllbGQ6IHN0cmluZyB8IFVpbnQ4QXJyYXksXG4gICAgYW1vdW50ID0gMSxcbiAgICB0dGw/OiBudW1iZXJcbiAgKTogUHJvbWlzZTxDYWNoZUluY3JlbWVudC5SZXNwb25zZT4ge1xuICAgIHRyeSB7XG4gICAgICB2YWxpZGF0ZUNhY2hlTmFtZShjYWNoZU5hbWUpO1xuICAgICAgaWYgKHR0bCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHZhbGlkYXRlVHRsU2Vjb25kcyh0dGwpO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgcmV0dXJuIHRoaXMuY2FjaGVTZXJ2aWNlRXJyb3JNYXBwZXIucmV0dXJuT3JUaHJvd0Vycm9yKFxuICAgICAgICBlcnIgYXMgRXJyb3IsXG4gICAgICAgIGVyciA9PiBuZXcgQ2FjaGVJbmNyZW1lbnQuRXJyb3IoZXJyKVxuICAgICAgKTtcbiAgICB9XG5cbiAgICByZXR1cm4gYXdhaXQgdGhpcy5yYXRlTGltaXRlZChhc3luYyAoKSA9PiB7XG4gICAgICByZXR1cm4gYXdhaXQgdGhpcy5zZW5kSW5jcmVtZW50KFxuICAgICAgICBjYWNoZU5hbWUsXG4gICAgICAgIHRoaXMuY29udmVydChmaWVsZCksXG4gICAgICAgIGFtb3VudCxcbiAgICAgICAgdGhpcy50dGxPckRlZmF1bHRNaWxsaXNlY29uZHModHRsKVxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgc2VuZEluY3JlbWVudChcbiAgICBjYWNoZU5hbWU6IHN0cmluZyxcbiAgICBmaWVsZDogVWludDhBcnJheSxcbiAgICBhbW91bnQgPSAxLFxuICAgIHR0bE1pbGxpc2Vjb25kczogbnVtYmVyXG4gICk6IFByb21pc2U8Q2FjaGVJbmNyZW1lbnQuUmVzcG9uc2U+IHtcbiAgICBjb25zdCByZXF1ZXN0ID0gbmV3IGdycGNDYWNoZS5fSW5jcmVtZW50UmVxdWVzdCh7XG4gICAgICBjYWNoZV9rZXk6IGZpZWxkLFxuICAgICAgYW1vdW50LFxuICAgICAgdHRsX21pbGxpc2Vjb25kczogdHRsTWlsbGlzZWNvbmRzLFxuICAgIH0pO1xuICAgIGNvbnN0IG1ldGFkYXRhID0gdGhpcy5jcmVhdGVNZXRhZGF0YShjYWNoZU5hbWUpO1xuXG4gICAgcmV0dXJuIGF3YWl0IG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHRoaXMuY2xpZW50V3JhcHBlci5nZXRDbGllbnQoKS5JbmNyZW1lbnQoXG4gICAgICAgIHJlcXVlc3QsXG4gICAgICAgIG1ldGFkYXRhLFxuICAgICAgICB7XG4gICAgICAgICAgaW50ZXJjZXB0b3JzOiB0aGlzLmludGVyY2VwdG9ycyxcbiAgICAgICAgfSxcbiAgICAgICAgKGVyciwgcmVzcCkgPT4ge1xuICAgICAgICAgIGlmIChyZXNwKSB7XG4gICAgICAgICAgICBpZiAocmVzcC52YWx1ZSkge1xuICAgICAgICAgICAgICByZXNvbHZlKG5ldyBDYWNoZUluY3JlbWVudC5TdWNjZXNzKHJlc3AudmFsdWUpKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHJlc29sdmUobmV3IENhY2hlSW5jcmVtZW50LlN1Y2Nlc3MoMCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmNhY2hlU2VydmljZUVycm9yTWFwcGVyLnJlc29sdmVPclJlamVjdEVycm9yKHtcbiAgICAgICAgICAgICAgZXJyOiBlcnIsXG4gICAgICAgICAgICAgIGVycm9yUmVzcG9uc2VGYWN0b3J5Rm46IGUgPT4gbmV3IENhY2hlSW5jcmVtZW50LkVycm9yKGUpLFxuICAgICAgICAgICAgICByZXNvbHZlRm46IHJlc29sdmUsXG4gICAgICAgICAgICAgIHJlamVjdEZuOiByZWplY3QsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICk7XG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgZGljdGlvbmFyeUluY3JlbWVudChcbiAgICBjYWNoZU5hbWU6IHN0cmluZyxcbiAgICBkaWN0aW9uYXJ5TmFtZTogc3RyaW5nLFxuICAgIGZpZWxkOiBzdHJpbmcgfCBVaW50OEFycmF5LFxuICAgIGFtb3VudCA9IDEsXG4gICAgdHRsOiBDb2xsZWN0aW9uVHRsID0gQ29sbGVjdGlvblR0bC5mcm9tQ2FjaGVUdGwoKVxuICApOiBQcm9taXNlPENhY2hlRGljdGlvbmFyeUluY3JlbWVudC5SZXNwb25zZT4ge1xuICAgIHRyeSB7XG4gICAgICB2YWxpZGF0ZUNhY2hlTmFtZShjYWNoZU5hbWUpO1xuICAgICAgdmFsaWRhdGVEaWN0aW9uYXJ5TmFtZShkaWN0aW9uYXJ5TmFtZSk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICByZXR1cm4gdGhpcy5jYWNoZVNlcnZpY2VFcnJvck1hcHBlci5yZXR1cm5PclRocm93RXJyb3IoXG4gICAgICAgIGVyciBhcyBFcnJvcixcbiAgICAgICAgZXJyID0+IG5ldyBDYWNoZURpY3Rpb25hcnlJbmNyZW1lbnQuRXJyb3IoZXJyKVxuICAgICAgKTtcbiAgICB9XG5cbiAgICByZXR1cm4gYXdhaXQgdGhpcy5yYXRlTGltaXRlZChhc3luYyAoKSA9PiB7XG4gICAgICByZXR1cm4gYXdhaXQgdGhpcy5zZW5kRGljdGlvbmFyeUluY3JlbWVudChcbiAgICAgICAgY2FjaGVOYW1lLFxuICAgICAgICB0aGlzLmNvbnZlcnQoZGljdGlvbmFyeU5hbWUpLFxuICAgICAgICB0aGlzLmNvbnZlcnQoZmllbGQpLFxuICAgICAgICBhbW91bnQsXG4gICAgICAgIHRoaXMuY29sbGVjdGlvblR0bE9yRGVmYXVsdE1pbGxpc2Vjb25kcyh0dGwpLFxuICAgICAgICB0dGwucmVmcmVzaFR0bCgpXG4gICAgICApO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBzZW5kRGljdGlvbmFyeUluY3JlbWVudChcbiAgICBjYWNoZU5hbWU6IHN0cmluZyxcbiAgICBkaWN0aW9uYXJ5TmFtZTogVWludDhBcnJheSxcbiAgICBmaWVsZDogVWludDhBcnJheSxcbiAgICBhbW91bnQ6IG51bWJlcixcbiAgICB0dGxNaWxsaXNlY29uZHM6IG51bWJlcixcbiAgICByZWZyZXNoVHRsOiBib29sZWFuXG4gICk6IFByb21pc2U8Q2FjaGVEaWN0aW9uYXJ5SW5jcmVtZW50LlJlc3BvbnNlPiB7XG4gICAgY29uc3QgcmVxdWVzdCA9IG5ldyBncnBjQ2FjaGUuX0RpY3Rpb25hcnlJbmNyZW1lbnRSZXF1ZXN0KHtcbiAgICAgIGRpY3Rpb25hcnlfbmFtZTogZGljdGlvbmFyeU5hbWUsXG4gICAgICBmaWVsZCxcbiAgICAgIGFtb3VudCxcbiAgICAgIHR0bF9taWxsaXNlY29uZHM6IHR0bE1pbGxpc2Vjb25kcyxcbiAgICAgIHJlZnJlc2hfdHRsOiByZWZyZXNoVHRsLFxuICAgIH0pO1xuICAgIGNvbnN0IG1ldGFkYXRhID0gdGhpcy5jcmVhdGVNZXRhZGF0YShjYWNoZU5hbWUpO1xuICAgIHJldHVybiBhd2FpdCBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICB0aGlzLmNsaWVudFdyYXBwZXIuZ2V0Q2xpZW50KCkuRGljdGlvbmFyeUluY3JlbWVudChcbiAgICAgICAgcmVxdWVzdCxcbiAgICAgICAgbWV0YWRhdGEsXG4gICAgICAgIHtcbiAgICAgICAgICBpbnRlcmNlcHRvcnM6IHRoaXMuaW50ZXJjZXB0b3JzLFxuICAgICAgICB9LFxuICAgICAgICAoZXJyLCByZXNwKSA9PiB7XG4gICAgICAgICAgaWYgKHJlc3ApIHtcbiAgICAgICAgICAgIGlmIChyZXNwLnZhbHVlKSB7XG4gICAgICAgICAgICAgIHJlc29sdmUobmV3IENhY2hlRGljdGlvbmFyeUluY3JlbWVudC5TdWNjZXNzKHJlc3AudmFsdWUpKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHJlc29sdmUobmV3IENhY2hlRGljdGlvbmFyeUluY3JlbWVudC5TdWNjZXNzKDApKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5jYWNoZVNlcnZpY2VFcnJvck1hcHBlci5yZXNvbHZlT3JSZWplY3RFcnJvcih7XG4gICAgICAgICAgICAgIGVycjogZXJyLFxuICAgICAgICAgICAgICBlcnJvclJlc3BvbnNlRmFjdG9yeUZuOiBlID0+XG4gICAgICAgICAgICAgICAgbmV3IENhY2hlRGljdGlvbmFyeUluY3JlbWVudC5FcnJvcihlKSxcbiAgICAgICAgICAgICAgcmVzb2x2ZUZuOiByZXNvbHZlLFxuICAgICAgICAgICAgICByZWplY3RGbjogcmVqZWN0LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICApO1xuICAgIH0pO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIHNvcnRlZFNldFB1dEVsZW1lbnQoXG4gICAgY2FjaGVOYW1lOiBzdHJpbmcsXG4gICAgc29ydGVkU2V0TmFtZTogc3RyaW5nLFxuICAgIHZhbHVlOiBzdHJpbmcgfCBVaW50OEFycmF5LFxuICAgIHNjb3JlOiBudW1iZXIsXG4gICAgdHRsOiBDb2xsZWN0aW9uVHRsID0gQ29sbGVjdGlvblR0bC5mcm9tQ2FjaGVUdGwoKVxuICApOiBQcm9taXNlPENhY2hlU29ydGVkU2V0UHV0RWxlbWVudC5SZXNwb25zZT4ge1xuICAgIHRyeSB7XG4gICAgICB2YWxpZGF0ZUNhY2hlTmFtZShjYWNoZU5hbWUpO1xuICAgICAgdmFsaWRhdGVTb3J0ZWRTZXROYW1lKHNvcnRlZFNldE5hbWUpO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgcmV0dXJuIHRoaXMuY2FjaGVTZXJ2aWNlRXJyb3JNYXBwZXIucmV0dXJuT3JUaHJvd0Vycm9yKFxuICAgICAgICBlcnIgYXMgRXJyb3IsXG4gICAgICAgIGVyciA9PiBuZXcgQ2FjaGVTb3J0ZWRTZXRQdXRFbGVtZW50LkVycm9yKGVycilcbiAgICAgICk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGF3YWl0IHRoaXMucmF0ZUxpbWl0ZWQoYXN5bmMgKCkgPT4ge1xuICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuc2VuZFNvcnRlZFNldFB1dEVsZW1lbnQoXG4gICAgICAgIGNhY2hlTmFtZSxcbiAgICAgICAgdGhpcy5jb252ZXJ0KHNvcnRlZFNldE5hbWUpLFxuICAgICAgICB0aGlzLmNvbnZlcnQodmFsdWUpLFxuICAgICAgICBzY29yZSxcbiAgICAgICAgdGhpcy5jb2xsZWN0aW9uVHRsT3JEZWZhdWx0TWlsbGlzZWNvbmRzKHR0bCksXG4gICAgICAgIHR0bC5yZWZyZXNoVHRsKClcbiAgICAgICk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHNlbmRTb3J0ZWRTZXRQdXRFbGVtZW50KFxuICAgIGNhY2hlTmFtZTogc3RyaW5nLFxuICAgIHNvcnRlZFNldE5hbWU6IFVpbnQ4QXJyYXksXG4gICAgdmFsdWU6IFVpbnQ4QXJyYXksXG4gICAgc2NvcmU6IG51bWJlcixcbiAgICB0dGxNaWxsaXNlY29uZHM6IG51bWJlcixcbiAgICByZWZyZXNoVHRsOiBib29sZWFuXG4gICk6IFByb21pc2U8Q2FjaGVTb3J0ZWRTZXRQdXRFbGVtZW50LlJlc3BvbnNlPiB7XG4gICAgY29uc3QgcmVxdWVzdCA9IG5ldyBncnBjQ2FjaGUuX1NvcnRlZFNldFB1dFJlcXVlc3Qoe1xuICAgICAgc2V0X25hbWU6IHNvcnRlZFNldE5hbWUsXG4gICAgICBlbGVtZW50czogW25ldyBncnBjQ2FjaGUuX1NvcnRlZFNldEVsZW1lbnQoe3ZhbHVlLCBzY29yZX0pXSxcbiAgICAgIHR0bF9taWxsaXNlY29uZHM6IHR0bE1pbGxpc2Vjb25kcyxcbiAgICAgIHJlZnJlc2hfdHRsOiByZWZyZXNoVHRsLFxuICAgIH0pO1xuICAgIGNvbnN0IG1ldGFkYXRhID0gdGhpcy5jcmVhdGVNZXRhZGF0YShjYWNoZU5hbWUpO1xuICAgIHJldHVybiBhd2FpdCBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICB0aGlzLmNsaWVudFdyYXBwZXIuZ2V0Q2xpZW50KCkuU29ydGVkU2V0UHV0KFxuICAgICAgICByZXF1ZXN0LFxuICAgICAgICBtZXRhZGF0YSxcbiAgICAgICAge1xuICAgICAgICAgIGludGVyY2VwdG9yczogdGhpcy5pbnRlcmNlcHRvcnMsXG4gICAgICAgIH0sXG4gICAgICAgIChlcnIsIHJlc3ApID0+IHtcbiAgICAgICAgICBpZiAocmVzcCkge1xuICAgICAgICAgICAgcmVzb2x2ZShuZXcgQ2FjaGVTb3J0ZWRTZXRQdXRFbGVtZW50LlN1Y2Nlc3MoKSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuY2FjaGVTZXJ2aWNlRXJyb3JNYXBwZXIucmVzb2x2ZU9yUmVqZWN0RXJyb3Ioe1xuICAgICAgICAgICAgICBlcnI6IGVycixcbiAgICAgICAgICAgICAgZXJyb3JSZXNwb25zZUZhY3RvcnlGbjogZSA9PlxuICAgICAgICAgICAgICAgIG5ldyBDYWNoZVNvcnRlZFNldFB1dEVsZW1lbnQuRXJyb3IoZSksXG4gICAgICAgICAgICAgIHJlc29sdmVGbjogcmVzb2x2ZSxcbiAgICAgICAgICAgICAgcmVqZWN0Rm46IHJlamVjdCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBzb3J0ZWRTZXRQdXRFbGVtZW50cyhcbiAgICBjYWNoZU5hbWU6IHN0cmluZyxcbiAgICBzb3J0ZWRTZXROYW1lOiBzdHJpbmcsXG4gICAgZWxlbWVudHM6XG4gICAgICB8IE1hcDxzdHJpbmcgfCBVaW50OEFycmF5LCBudW1iZXI+XG4gICAgICB8IFJlY29yZDxzdHJpbmcsIG51bWJlcj5cbiAgICAgIHwgQXJyYXk8W3N0cmluZywgbnVtYmVyXT4sXG4gICAgdHRsOiBDb2xsZWN0aW9uVHRsID0gQ29sbGVjdGlvblR0bC5mcm9tQ2FjaGVUdGwoKVxuICApOiBQcm9taXNlPENhY2hlU29ydGVkU2V0UHV0RWxlbWVudHMuUmVzcG9uc2U+IHtcbiAgICB0cnkge1xuICAgICAgdmFsaWRhdGVDYWNoZU5hbWUoY2FjaGVOYW1lKTtcbiAgICAgIHZhbGlkYXRlU29ydGVkU2V0TmFtZShzb3J0ZWRTZXROYW1lKTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIHJldHVybiB0aGlzLmNhY2hlU2VydmljZUVycm9yTWFwcGVyLnJldHVybk9yVGhyb3dFcnJvcihcbiAgICAgICAgZXJyIGFzIEVycm9yLFxuICAgICAgICBlcnIgPT4gbmV3IENhY2hlU29ydGVkU2V0UHV0RWxlbWVudHMuRXJyb3IoZXJyKVxuICAgICAgKTtcbiAgICB9XG5cbiAgICByZXR1cm4gYXdhaXQgdGhpcy5yYXRlTGltaXRlZChhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBzb3J0ZWRTZXRWYWx1ZVNjb3JlUGFpcnMgPVxuICAgICAgICB0aGlzLmNvbnZlcnRTb3J0ZWRTZXRNYXBPclJlY29yZChlbGVtZW50cyk7XG5cbiAgICAgIHJldHVybiBhd2FpdCB0aGlzLnNlbmRTb3J0ZWRTZXRQdXRFbGVtZW50cyhcbiAgICAgICAgY2FjaGVOYW1lLFxuICAgICAgICB0aGlzLmNvbnZlcnQoc29ydGVkU2V0TmFtZSksXG4gICAgICAgIHNvcnRlZFNldFZhbHVlU2NvcmVQYWlycyxcbiAgICAgICAgdGhpcy5jb2xsZWN0aW9uVHRsT3JEZWZhdWx0TWlsbGlzZWNvbmRzKHR0bCksXG4gICAgICAgIHR0bC5yZWZyZXNoVHRsKClcbiAgICAgICk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHNlbmRTb3J0ZWRTZXRQdXRFbGVtZW50cyhcbiAgICBjYWNoZU5hbWU6IHN0cmluZyxcbiAgICBzb3J0ZWRTZXROYW1lOiBVaW50OEFycmF5LFxuICAgIGVsZW1lbnRzOiBncnBjQ2FjaGUuX1NvcnRlZFNldEVsZW1lbnRbXSxcbiAgICB0dGxNaWxsaXNlY29uZHM6IG51bWJlcixcbiAgICByZWZyZXNoVHRsOiBib29sZWFuXG4gICk6IFByb21pc2U8Q2FjaGVTb3J0ZWRTZXRQdXRFbGVtZW50cy5SZXNwb25zZT4ge1xuICAgIGNvbnN0IHJlcXVlc3QgPSBuZXcgZ3JwY0NhY2hlLl9Tb3J0ZWRTZXRQdXRSZXF1ZXN0KHtcbiAgICAgIHNldF9uYW1lOiBzb3J0ZWRTZXROYW1lLFxuICAgICAgZWxlbWVudHM6IGVsZW1lbnRzLFxuICAgICAgdHRsX21pbGxpc2Vjb25kczogdHRsTWlsbGlzZWNvbmRzLFxuICAgICAgcmVmcmVzaF90dGw6IHJlZnJlc2hUdGwsXG4gICAgfSk7XG4gICAgY29uc3QgbWV0YWRhdGEgPSB0aGlzLmNyZWF0ZU1ldGFkYXRhKGNhY2hlTmFtZSk7XG4gICAgcmV0dXJuIGF3YWl0IG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHRoaXMuY2xpZW50V3JhcHBlci5nZXRDbGllbnQoKS5Tb3J0ZWRTZXRQdXQoXG4gICAgICAgIHJlcXVlc3QsXG4gICAgICAgIG1ldGFkYXRhLFxuICAgICAgICB7XG4gICAgICAgICAgaW50ZXJjZXB0b3JzOiB0aGlzLmludGVyY2VwdG9ycyxcbiAgICAgICAgfSxcbiAgICAgICAgKGVyciwgcmVzcCkgPT4ge1xuICAgICAgICAgIGlmIChyZXNwKSB7XG4gICAgICAgICAgICByZXNvbHZlKG5ldyBDYWNoZVNvcnRlZFNldFB1dEVsZW1lbnRzLlN1Y2Nlc3MoKSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuY2FjaGVTZXJ2aWNlRXJyb3JNYXBwZXIucmVzb2x2ZU9yUmVqZWN0RXJyb3Ioe1xuICAgICAgICAgICAgICBlcnI6IGVycixcbiAgICAgICAgICAgICAgZXJyb3JSZXNwb25zZUZhY3RvcnlGbjogZSA9PlxuICAgICAgICAgICAgICAgIG5ldyBDYWNoZVNvcnRlZFNldFB1dEVsZW1lbnRzLkVycm9yKGUpLFxuICAgICAgICAgICAgICByZXNvbHZlRm46IHJlc29sdmUsXG4gICAgICAgICAgICAgIHJlamVjdEZuOiByZWplY3QsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICk7XG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgc29ydGVkU2V0RmV0Y2hCeVJhbmsoXG4gICAgY2FjaGVOYW1lOiBzdHJpbmcsXG4gICAgc29ydGVkU2V0TmFtZTogc3RyaW5nLFxuICAgIG9yZGVyOiBTb3J0ZWRTZXRPcmRlcixcbiAgICBzdGFydFJhbms6IG51bWJlcixcbiAgICBlbmRSYW5rPzogbnVtYmVyXG4gICk6IFByb21pc2U8Q2FjaGVTb3J0ZWRTZXRGZXRjaC5SZXNwb25zZT4ge1xuICAgIHRyeSB7XG4gICAgICB2YWxpZGF0ZUNhY2hlTmFtZShjYWNoZU5hbWUpO1xuICAgICAgdmFsaWRhdGVTb3J0ZWRTZXROYW1lKHNvcnRlZFNldE5hbWUpO1xuICAgICAgdmFsaWRhdGVTb3J0ZWRTZXRSYW5rcyhzdGFydFJhbmssIGVuZFJhbmspO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgcmV0dXJuIHRoaXMuY2FjaGVTZXJ2aWNlRXJyb3JNYXBwZXIucmV0dXJuT3JUaHJvd0Vycm9yKFxuICAgICAgICBlcnIgYXMgRXJyb3IsXG4gICAgICAgIGVyciA9PiBuZXcgQ2FjaGVTb3J0ZWRTZXRGZXRjaC5FcnJvcihlcnIpXG4gICAgICApO1xuICAgIH1cblxuICAgIHJldHVybiBhd2FpdCB0aGlzLnJhdGVMaW1pdGVkKGFzeW5jICgpID0+IHtcbiAgICAgIHJldHVybiBhd2FpdCB0aGlzLnNlbmRTb3J0ZWRTZXRGZXRjaEJ5UmFuayhcbiAgICAgICAgY2FjaGVOYW1lLFxuICAgICAgICB0aGlzLmNvbnZlcnQoc29ydGVkU2V0TmFtZSksXG4gICAgICAgIG9yZGVyLFxuICAgICAgICBzdGFydFJhbmssXG4gICAgICAgIGVuZFJhbmtcbiAgICAgICk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHNlbmRTb3J0ZWRTZXRGZXRjaEJ5UmFuayhcbiAgICBjYWNoZU5hbWU6IHN0cmluZyxcbiAgICBzb3J0ZWRTZXROYW1lOiBVaW50OEFycmF5LFxuICAgIG9yZGVyOiBTb3J0ZWRTZXRPcmRlcixcbiAgICBzdGFydFJhbms6IG51bWJlcixcbiAgICBlbmRSYW5rPzogbnVtYmVyXG4gICk6IFByb21pc2U8Q2FjaGVTb3J0ZWRTZXRGZXRjaC5SZXNwb25zZT4ge1xuICAgIGNvbnN0IGJ5X2luZGV4ID0gbmV3IGdycGNDYWNoZS5fU29ydGVkU2V0RmV0Y2hSZXF1ZXN0Ll9CeUluZGV4KCk7XG4gICAgaWYgKHN0YXJ0UmFuaykge1xuICAgICAgYnlfaW5kZXguaW5jbHVzaXZlX3N0YXJ0X2luZGV4ID0gc3RhcnRSYW5rO1xuICAgIH0gZWxzZSB7XG4gICAgICBieV9pbmRleC51bmJvdW5kZWRfc3RhcnQgPSBuZXcgX1VuYm91bmRlZCgpO1xuICAgIH1cbiAgICBpZiAoZW5kUmFuaykge1xuICAgICAgYnlfaW5kZXguZXhjbHVzaXZlX2VuZF9pbmRleCA9IGVuZFJhbms7XG4gICAgfSBlbHNlIHtcbiAgICAgIGJ5X2luZGV4LnVuYm91bmRlZF9lbmQgPSBuZXcgX1VuYm91bmRlZCgpO1xuICAgIH1cblxuICAgIGNvbnN0IHByb3RvQnVmT3JkZXIgPVxuICAgICAgb3JkZXIgPT09IFNvcnRlZFNldE9yZGVyLkRlc2NlbmRpbmdcbiAgICAgICAgPyBncnBjQ2FjaGUuX1NvcnRlZFNldEZldGNoUmVxdWVzdC5PcmRlci5ERVNDRU5ESU5HXG4gICAgICAgIDogZ3JwY0NhY2hlLl9Tb3J0ZWRTZXRGZXRjaFJlcXVlc3QuT3JkZXIuQVNDRU5ESU5HO1xuXG4gICAgY29uc3QgcmVxdWVzdCA9IG5ldyBncnBjQ2FjaGUuX1NvcnRlZFNldEZldGNoUmVxdWVzdCh7XG4gICAgICBzZXRfbmFtZTogc29ydGVkU2V0TmFtZSxcbiAgICAgIG9yZGVyOiBwcm90b0J1Zk9yZGVyLFxuICAgICAgd2l0aF9zY29yZXM6IHRydWUsXG4gICAgICBieV9pbmRleDogYnlfaW5kZXgsXG4gICAgfSk7XG5cbiAgICBjb25zdCBtZXRhZGF0YSA9IHRoaXMuY3JlYXRlTWV0YWRhdGEoY2FjaGVOYW1lKTtcbiAgICByZXR1cm4gYXdhaXQgbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgdGhpcy5jbGllbnRXcmFwcGVyLmdldENsaWVudCgpLlNvcnRlZFNldEZldGNoKFxuICAgICAgICByZXF1ZXN0LFxuICAgICAgICBtZXRhZGF0YSxcbiAgICAgICAge1xuICAgICAgICAgIGludGVyY2VwdG9yczogdGhpcy5pbnRlcmNlcHRvcnMsXG4gICAgICAgIH0sXG4gICAgICAgIChlcnIsIHJlc3ApID0+IHtcbiAgICAgICAgICBpZiAocmVzcCkge1xuICAgICAgICAgICAgaWYgKHJlc3A/LmZvdW5kKSB7XG4gICAgICAgICAgICAgIGlmIChyZXNwPy5mb3VuZD8udmFsdWVzX3dpdGhfc2NvcmVzKSB7XG4gICAgICAgICAgICAgICAgcmVzb2x2ZShcbiAgICAgICAgICAgICAgICAgIG5ldyBDYWNoZVNvcnRlZFNldEZldGNoLkhpdChcbiAgICAgICAgICAgICAgICAgICAgcmVzcC5mb3VuZC52YWx1ZXNfd2l0aF9zY29yZXMuZWxlbWVudHNcbiAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJlc29sdmUoXG4gICAgICAgICAgICAgICAgICBuZXcgQ2FjaGVTb3J0ZWRTZXRGZXRjaC5FcnJvcihcbiAgICAgICAgICAgICAgICAgICAgbmV3IFVua25vd25FcnJvcihcbiAgICAgICAgICAgICAgICAgICAgICAnVW5rbm93biBzb3J0ZWQgc2V0IGZldGNoIGhpdCByZXNwb25zZSB0eXBlJ1xuICAgICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIGlmIChyZXNwPy5taXNzaW5nKSB7XG4gICAgICAgICAgICAgIHJlc29sdmUobmV3IENhY2hlU29ydGVkU2V0RmV0Y2guTWlzcygpKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHJlc29sdmUoXG4gICAgICAgICAgICAgICAgbmV3IENhY2hlU29ydGVkU2V0RmV0Y2guRXJyb3IoXG4gICAgICAgICAgICAgICAgICBuZXcgVW5rbm93bkVycm9yKCdVbmtub3duIHNvcnRlZCBzZXQgZmV0Y2ggcmVzcG9uc2UgdHlwZScpXG4gICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmNhY2hlU2VydmljZUVycm9yTWFwcGVyLnJlc29sdmVPclJlamVjdEVycm9yKHtcbiAgICAgICAgICAgICAgZXJyOiBlcnIsXG4gICAgICAgICAgICAgIGVycm9yUmVzcG9uc2VGYWN0b3J5Rm46IGUgPT4gbmV3IENhY2hlU29ydGVkU2V0RmV0Y2guRXJyb3IoZSksXG4gICAgICAgICAgICAgIHJlc29sdmVGbjogcmVzb2x2ZSxcbiAgICAgICAgICAgICAgcmVqZWN0Rm46IHJlamVjdCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBzb3J0ZWRTZXRGZXRjaEJ5U2NvcmUoXG4gICAgY2FjaGVOYW1lOiBzdHJpbmcsXG4gICAgc29ydGVkU2V0TmFtZTogc3RyaW5nLFxuICAgIG9yZGVyOiBTb3J0ZWRTZXRPcmRlcixcbiAgICBtaW5TY29yZT86IG51bWJlcixcbiAgICBtYXhTY29yZT86IG51bWJlcixcbiAgICBvZmZzZXQ/OiBudW1iZXIsXG4gICAgY291bnQ/OiBudW1iZXJcbiAgKTogUHJvbWlzZTxDYWNoZVNvcnRlZFNldEZldGNoLlJlc3BvbnNlPiB7XG4gICAgdHJ5IHtcbiAgICAgIHZhbGlkYXRlQ2FjaGVOYW1lKGNhY2hlTmFtZSk7XG4gICAgICB2YWxpZGF0ZVNvcnRlZFNldE5hbWUoc29ydGVkU2V0TmFtZSk7XG4gICAgICB2YWxpZGF0ZVNvcnRlZFNldFNjb3JlcyhtaW5TY29yZSwgbWF4U2NvcmUpO1xuICAgICAgaWYgKG9mZnNldCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHZhbGlkYXRlU29ydGVkU2V0T2Zmc2V0KG9mZnNldCk7XG4gICAgICB9XG4gICAgICBpZiAoY291bnQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICB2YWxpZGF0ZVNvcnRlZFNldENvdW50KGNvdW50KTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIHJldHVybiB0aGlzLmNhY2hlU2VydmljZUVycm9yTWFwcGVyLnJldHVybk9yVGhyb3dFcnJvcihcbiAgICAgICAgZXJyIGFzIEVycm9yLFxuICAgICAgICBlcnIgPT4gbmV3IENhY2hlU29ydGVkU2V0RmV0Y2guRXJyb3IoZXJyKVxuICAgICAgKTtcbiAgICB9XG5cbiAgICByZXR1cm4gYXdhaXQgdGhpcy5yYXRlTGltaXRlZChhc3luYyAoKSA9PiB7XG4gICAgICByZXR1cm4gYXdhaXQgdGhpcy5zZW5kU29ydGVkU2V0RmV0Y2hCeVNjb3JlKFxuICAgICAgICBjYWNoZU5hbWUsXG4gICAgICAgIHRoaXMuY29udmVydChzb3J0ZWRTZXROYW1lKSxcbiAgICAgICAgb3JkZXIsXG4gICAgICAgIG1pblNjb3JlLFxuICAgICAgICBtYXhTY29yZSxcbiAgICAgICAgb2Zmc2V0LFxuICAgICAgICBjb3VudFxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgc2VuZFNvcnRlZFNldEZldGNoQnlTY29yZShcbiAgICBjYWNoZU5hbWU6IHN0cmluZyxcbiAgICBzb3J0ZWRTZXROYW1lOiBVaW50OEFycmF5LFxuICAgIG9yZGVyOiBTb3J0ZWRTZXRPcmRlcixcbiAgICBtaW5TY29yZT86IG51bWJlcixcbiAgICBtYXhTY29yZT86IG51bWJlcixcbiAgICBvZmZzZXQ/OiBudW1iZXIsXG4gICAgY291bnQ/OiBudW1iZXJcbiAgKTogUHJvbWlzZTxDYWNoZVNvcnRlZFNldEZldGNoLlJlc3BvbnNlPiB7XG4gICAgY29uc3QgYnlfc2NvcmUgPSBuZXcgZ3JwY0NhY2hlLl9Tb3J0ZWRTZXRGZXRjaFJlcXVlc3QuX0J5U2NvcmUoKTtcbiAgICBpZiAobWluU2NvcmUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgYnlfc2NvcmUubWluX3Njb3JlID0gbmV3IGdycGNDYWNoZS5fU29ydGVkU2V0RmV0Y2hSZXF1ZXN0Ll9CeVNjb3JlLl9TY29yZShcbiAgICAgICAge1xuICAgICAgICAgIHNjb3JlOiBtaW5TY29yZSxcbiAgICAgICAgICBleGNsdXNpdmU6IGZhbHNlLFxuICAgICAgICB9XG4gICAgICApO1xuICAgIH0gZWxzZSB7XG4gICAgICBieV9zY29yZS51bmJvdW5kZWRfbWluID0gbmV3IF9VbmJvdW5kZWQoKTtcbiAgICB9XG4gICAgaWYgKG1heFNjb3JlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGJ5X3Njb3JlLm1heF9zY29yZSA9IG5ldyBncnBjQ2FjaGUuX1NvcnRlZFNldEZldGNoUmVxdWVzdC5fQnlTY29yZS5fU2NvcmUoXG4gICAgICAgIHtcbiAgICAgICAgICBzY29yZTogbWF4U2NvcmUsXG4gICAgICAgICAgZXhjbHVzaXZlOiBmYWxzZSxcbiAgICAgICAgfVxuICAgICAgKTtcbiAgICB9IGVsc2Uge1xuICAgICAgYnlfc2NvcmUudW5ib3VuZGVkX21heCA9IG5ldyBfVW5ib3VuZGVkKCk7XG4gICAgfVxuICAgIGJ5X3Njb3JlLm9mZnNldCA9IG9mZnNldCA/PyAwO1xuICAgIC8vIE5vdGU6IHRoZSBzZXJ2aWNlIHJlc2VydmVzIG5lZ2F0aXZlIGNvdW50cyB0byBtZWFuIGFsbCBlbGVtZW50cyBpbiB0aGVcbiAgICAvLyByZXN1bHQgc2V0LlxuICAgIGJ5X3Njb3JlLmNvdW50ID0gY291bnQgPz8gLTE7XG5cbiAgICBjb25zdCBwcm90b0J1Zk9yZGVyID1cbiAgICAgIG9yZGVyID09PSBTb3J0ZWRTZXRPcmRlci5EZXNjZW5kaW5nXG4gICAgICAgID8gZ3JwY0NhY2hlLl9Tb3J0ZWRTZXRGZXRjaFJlcXVlc3QuT3JkZXIuREVTQ0VORElOR1xuICAgICAgICA6IGdycGNDYWNoZS5fU29ydGVkU2V0RmV0Y2hSZXF1ZXN0Lk9yZGVyLkFTQ0VORElORztcblxuICAgIGNvbnN0IHJlcXVlc3QgPSBuZXcgZ3JwY0NhY2hlLl9Tb3J0ZWRTZXRGZXRjaFJlcXVlc3Qoe1xuICAgICAgc2V0X25hbWU6IHNvcnRlZFNldE5hbWUsXG4gICAgICBvcmRlcjogcHJvdG9CdWZPcmRlcixcbiAgICAgIHdpdGhfc2NvcmVzOiB0cnVlLFxuICAgICAgYnlfc2NvcmU6IGJ5X3Njb3JlLFxuICAgIH0pO1xuXG4gICAgY29uc3QgbWV0YWRhdGEgPSB0aGlzLmNyZWF0ZU1ldGFkYXRhKGNhY2hlTmFtZSk7XG4gICAgcmV0dXJuIGF3YWl0IG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHRoaXMuY2xpZW50V3JhcHBlci5nZXRDbGllbnQoKS5Tb3J0ZWRTZXRGZXRjaChcbiAgICAgICAgcmVxdWVzdCxcbiAgICAgICAgbWV0YWRhdGEsXG4gICAgICAgIHtcbiAgICAgICAgICBpbnRlcmNlcHRvcnM6IHRoaXMuaW50ZXJjZXB0b3JzLFxuICAgICAgICB9LFxuICAgICAgICAoZXJyLCByZXNwKSA9PiB7XG4gICAgICAgICAgaWYgKHJlc3ApIHtcbiAgICAgICAgICAgIGlmIChyZXNwPy5mb3VuZCkge1xuICAgICAgICAgICAgICBpZiAocmVzcD8uZm91bmQ/LnZhbHVlc193aXRoX3Njb3Jlcykge1xuICAgICAgICAgICAgICAgIHJlc29sdmUoXG4gICAgICAgICAgICAgICAgICBuZXcgQ2FjaGVTb3J0ZWRTZXRGZXRjaC5IaXQoXG4gICAgICAgICAgICAgICAgICAgIHJlc3AuZm91bmQudmFsdWVzX3dpdGhfc2NvcmVzLmVsZW1lbnRzXG4gICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXNvbHZlKFxuICAgICAgICAgICAgICAgICAgbmV3IENhY2hlU29ydGVkU2V0RmV0Y2guRXJyb3IoXG4gICAgICAgICAgICAgICAgICAgIG5ldyBVbmtub3duRXJyb3IoXG4gICAgICAgICAgICAgICAgICAgICAgJ1Vua25vd24gc29ydGVkIHNldCBmZXRjaCBoaXQgcmVzcG9uc2UgdHlwZSdcbiAgICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSBpZiAocmVzcD8ubWlzc2luZykge1xuICAgICAgICAgICAgICByZXNvbHZlKG5ldyBDYWNoZVNvcnRlZFNldEZldGNoLk1pc3MoKSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICByZXNvbHZlKFxuICAgICAgICAgICAgICAgIG5ldyBDYWNoZVNvcnRlZFNldEZldGNoLkVycm9yKFxuICAgICAgICAgICAgICAgICAgbmV3IFVua25vd25FcnJvcignVW5rbm93biBzb3J0ZWQgc2V0IGZldGNoIHJlc3BvbnNlIHR5cGUnKVxuICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5jYWNoZVNlcnZpY2VFcnJvck1hcHBlci5yZXNvbHZlT3JSZWplY3RFcnJvcih7XG4gICAgICAgICAgICAgIGVycjogZXJyLFxuICAgICAgICAgICAgICBlcnJvclJlc3BvbnNlRmFjdG9yeUZuOiBlID0+IG5ldyBDYWNoZVNvcnRlZFNldEZldGNoLkVycm9yKGUpLFxuICAgICAgICAgICAgICByZXNvbHZlRm46IHJlc29sdmUsXG4gICAgICAgICAgICAgIHJlamVjdEZuOiByZWplY3QsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICk7XG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgc29ydGVkU2V0R2V0UmFuayhcbiAgICBjYWNoZU5hbWU6IHN0cmluZyxcbiAgICBzb3J0ZWRTZXROYW1lOiBzdHJpbmcsXG4gICAgdmFsdWU6IHN0cmluZyB8IFVpbnQ4QXJyYXksXG4gICAgb3JkZXI/OiBTb3J0ZWRTZXRPcmRlclxuICApOiBQcm9taXNlPENhY2hlU29ydGVkU2V0R2V0UmFuay5SZXNwb25zZT4ge1xuICAgIHRyeSB7XG4gICAgICB2YWxpZGF0ZUNhY2hlTmFtZShjYWNoZU5hbWUpO1xuICAgICAgdmFsaWRhdGVTb3J0ZWRTZXROYW1lKHNvcnRlZFNldE5hbWUpO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgcmV0dXJuIHRoaXMuY2FjaGVTZXJ2aWNlRXJyb3JNYXBwZXIucmV0dXJuT3JUaHJvd0Vycm9yKFxuICAgICAgICBlcnIgYXMgRXJyb3IsXG4gICAgICAgIGVyciA9PiBuZXcgQ2FjaGVTb3J0ZWRTZXRHZXRSYW5rLkVycm9yKGVycilcbiAgICAgICk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGF3YWl0IHRoaXMucmF0ZUxpbWl0ZWQoYXN5bmMgKCkgPT4ge1xuICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuc2VuZFNvcnRlZFNldEdldFJhbmsoXG4gICAgICAgIGNhY2hlTmFtZSxcbiAgICAgICAgdGhpcy5jb252ZXJ0KHNvcnRlZFNldE5hbWUpLFxuICAgICAgICB0aGlzLmNvbnZlcnQodmFsdWUpLFxuICAgICAgICBvcmRlclxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgc2VuZFNvcnRlZFNldEdldFJhbmsoXG4gICAgY2FjaGVOYW1lOiBzdHJpbmcsXG4gICAgc29ydGVkU2V0TmFtZTogVWludDhBcnJheSxcbiAgICB2YWx1ZTogVWludDhBcnJheSxcbiAgICBvcmRlcj86IFNvcnRlZFNldE9yZGVyXG4gICk6IFByb21pc2U8Q2FjaGVTb3J0ZWRTZXRHZXRSYW5rLlJlc3BvbnNlPiB7XG4gICAgY29uc3QgcHJvdG9CdWZPcmRlciA9XG4gICAgICBvcmRlciA9PT0gU29ydGVkU2V0T3JkZXIuRGVzY2VuZGluZ1xuICAgICAgICA/IGdycGNDYWNoZS5fU29ydGVkU2V0R2V0UmFua1JlcXVlc3QuT3JkZXIuREVTQ0VORElOR1xuICAgICAgICA6IGdycGNDYWNoZS5fU29ydGVkU2V0R2V0UmFua1JlcXVlc3QuT3JkZXIuQVNDRU5ESU5HO1xuXG4gICAgY29uc3QgcmVxdWVzdCA9IG5ldyBncnBjQ2FjaGUuX1NvcnRlZFNldEdldFJhbmtSZXF1ZXN0KHtcbiAgICAgIHNldF9uYW1lOiBzb3J0ZWRTZXROYW1lLFxuICAgICAgdmFsdWU6IHZhbHVlLFxuICAgICAgb3JkZXI6IHByb3RvQnVmT3JkZXIsXG4gICAgfSk7XG4gICAgY29uc3QgbWV0YWRhdGEgPSB0aGlzLmNyZWF0ZU1ldGFkYXRhKGNhY2hlTmFtZSk7XG4gICAgcmV0dXJuIGF3YWl0IG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHRoaXMuY2xpZW50V3JhcHBlclxuICAgICAgICAuZ2V0Q2xpZW50KClcbiAgICAgICAgLlNvcnRlZFNldEdldFJhbmsoXG4gICAgICAgICAgcmVxdWVzdCxcbiAgICAgICAgICBtZXRhZGF0YSxcbiAgICAgICAgICB7aW50ZXJjZXB0b3JzOiB0aGlzLmludGVyY2VwdG9yc30sXG4gICAgICAgICAgKGVyciwgcmVzcCkgPT4ge1xuICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICByZXNwPy5taXNzaW5nIHx8XG4gICAgICAgICAgICAgIHJlc3A/LmVsZW1lbnRfcmFuaz8ucmVzdWx0ID09PSBFQ2FjaGVSZXN1bHQuTWlzc1xuICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgIHJlc29sdmUobmV3IENhY2hlU29ydGVkU2V0R2V0UmFuay5NaXNzKCkpO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChyZXNwPy5lbGVtZW50X3Jhbms/LnJlc3VsdCA9PT0gRUNhY2hlUmVzdWx0LkhpdCkge1xuICAgICAgICAgICAgICBpZiAocmVzcD8uZWxlbWVudF9yYW5rLnJhbmsgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIHJlc29sdmUobmV3IENhY2hlU29ydGVkU2V0R2V0UmFuay5NaXNzKCkpO1xuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJlc29sdmUobmV3IENhY2hlU29ydGVkU2V0R2V0UmFuay5IaXQocmVzcC5lbGVtZW50X3JhbmsucmFuaykpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICB0aGlzLmNhY2hlU2VydmljZUVycm9yTWFwcGVyLnJlc29sdmVPclJlamVjdEVycm9yKHtcbiAgICAgICAgICAgICAgICBlcnI6IGVycixcbiAgICAgICAgICAgICAgICBlcnJvclJlc3BvbnNlRmFjdG9yeUZuOiBlID0+IG5ldyBDYWNoZVNvcnRlZFNldEdldFJhbmsuRXJyb3IoZSksXG4gICAgICAgICAgICAgICAgcmVzb2x2ZUZuOiByZXNvbHZlLFxuICAgICAgICAgICAgICAgIHJlamVjdEZuOiByZWplY3QsXG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBzb3J0ZWRTZXRHZXRTY29yZShcbiAgICBjYWNoZU5hbWU6IHN0cmluZyxcbiAgICBzb3J0ZWRTZXROYW1lOiBzdHJpbmcsXG4gICAgdmFsdWU6IHN0cmluZyB8IFVpbnQ4QXJyYXlcbiAgKTogUHJvbWlzZTxDYWNoZVNvcnRlZFNldEdldFNjb3JlLlJlc3BvbnNlPiB7XG4gICAgY29uc3QgcmVzcG9uc2VzID0gYXdhaXQgdGhpcy5zb3J0ZWRTZXRHZXRTY29yZXMoY2FjaGVOYW1lLCBzb3J0ZWRTZXROYW1lLCBbXG4gICAgICB2YWx1ZSxcbiAgICBdIGFzIHN0cmluZ1tdIHwgVWludDhBcnJheVtdKTtcbiAgICBpZiAocmVzcG9uc2VzIGluc3RhbmNlb2YgQ2FjaGVTb3J0ZWRTZXRHZXRTY29yZXMuSGl0KSB7XG4gICAgICByZXR1cm4gcmVzcG9uc2VzLnJlc3BvbnNlcygpWzBdO1xuICAgIH0gZWxzZSBpZiAocmVzcG9uc2VzIGluc3RhbmNlb2YgQ2FjaGVTb3J0ZWRTZXRHZXRTY29yZXMuTWlzcykge1xuICAgICAgcmV0dXJuIG5ldyBDYWNoZVNvcnRlZFNldEdldFNjb3JlLk1pc3ModGhpcy5jb252ZXJ0KHZhbHVlKSk7XG4gICAgfSBlbHNlIGlmIChyZXNwb25zZXMgaW5zdGFuY2VvZiBDYWNoZVNvcnRlZFNldEdldFNjb3Jlcy5FcnJvcikge1xuICAgICAgcmV0dXJuIHRoaXMuY2FjaGVTZXJ2aWNlRXJyb3JNYXBwZXIucmV0dXJuT3JUaHJvd0Vycm9yKFxuICAgICAgICByZXNwb25zZXMuaW5uZXJFeGNlcHRpb24oKSxcbiAgICAgICAgZXJyID0+IG5ldyBDYWNoZVNvcnRlZFNldEdldFNjb3JlLkVycm9yKGVyciwgdGhpcy5jb252ZXJ0KHZhbHVlKSlcbiAgICAgICk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuY2FjaGVTZXJ2aWNlRXJyb3JNYXBwZXIucmV0dXJuT3JUaHJvd0Vycm9yKFxuICAgICAgbmV3IFVua25vd25FcnJvcignVW5rbm93biByZXNwb25zZSB0eXBlJyksXG4gICAgICBlcnIgPT4gbmV3IENhY2hlU29ydGVkU2V0R2V0U2NvcmUuRXJyb3IoZXJyLCB0aGlzLmNvbnZlcnQodmFsdWUpKVxuICAgICk7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgc29ydGVkU2V0R2V0U2NvcmVzKFxuICAgIGNhY2hlTmFtZTogc3RyaW5nLFxuICAgIHNvcnRlZFNldE5hbWU6IHN0cmluZyxcbiAgICB2YWx1ZXM6IHN0cmluZ1tdIHwgVWludDhBcnJheVtdXG4gICk6IFByb21pc2U8Q2FjaGVTb3J0ZWRTZXRHZXRTY29yZXMuUmVzcG9uc2U+IHtcbiAgICB0cnkge1xuICAgICAgdmFsaWRhdGVDYWNoZU5hbWUoY2FjaGVOYW1lKTtcbiAgICAgIHZhbGlkYXRlU29ydGVkU2V0TmFtZShzb3J0ZWRTZXROYW1lKTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIHJldHVybiB0aGlzLmNhY2hlU2VydmljZUVycm9yTWFwcGVyLnJldHVybk9yVGhyb3dFcnJvcihcbiAgICAgICAgZXJyIGFzIEVycm9yLFxuICAgICAgICBlcnIgPT4gbmV3IENhY2hlU29ydGVkU2V0R2V0U2NvcmVzLkVycm9yKGVycilcbiAgICAgICk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGF3YWl0IHRoaXMucmF0ZUxpbWl0ZWQoYXN5bmMgKCkgPT4ge1xuICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuc2VuZFNvcnRlZFNldEdldFNjb3JlcyhcbiAgICAgICAgY2FjaGVOYW1lLFxuICAgICAgICB0aGlzLmNvbnZlcnQoc29ydGVkU2V0TmFtZSksXG4gICAgICAgIHZhbHVlcy5tYXAodmFsdWUgPT4gdGhpcy5jb252ZXJ0KHZhbHVlKSlcbiAgICAgICk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHNlbmRTb3J0ZWRTZXRHZXRTY29yZXMoXG4gICAgY2FjaGVOYW1lOiBzdHJpbmcsXG4gICAgc29ydGVkU2V0TmFtZTogVWludDhBcnJheSxcbiAgICB2YWx1ZXM6IFVpbnQ4QXJyYXlbXVxuICApOiBQcm9taXNlPENhY2hlU29ydGVkU2V0R2V0U2NvcmVzLlJlc3BvbnNlPiB7XG4gICAgY29uc3QgcmVxdWVzdCA9IG5ldyBncnBjQ2FjaGUuX1NvcnRlZFNldEdldFNjb3JlUmVxdWVzdCh7XG4gICAgICBzZXRfbmFtZTogc29ydGVkU2V0TmFtZSxcbiAgICAgIHZhbHVlczogdmFsdWVzLFxuICAgIH0pO1xuICAgIGNvbnN0IG1ldGFkYXRhID0gdGhpcy5jcmVhdGVNZXRhZGF0YShjYWNoZU5hbWUpO1xuICAgIHJldHVybiBhd2FpdCBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICB0aGlzLmNsaWVudFdyYXBwZXJcbiAgICAgICAgLmdldENsaWVudCgpXG4gICAgICAgIC5Tb3J0ZWRTZXRHZXRTY29yZShcbiAgICAgICAgICByZXF1ZXN0LFxuICAgICAgICAgIG1ldGFkYXRhLFxuICAgICAgICAgIHtpbnRlcmNlcHRvcnM6IHRoaXMuaW50ZXJjZXB0b3JzfSxcbiAgICAgICAgICAoZXJyLCByZXNwKSA9PiB7XG4gICAgICAgICAgICBpZiAocmVzcD8ubWlzc2luZykge1xuICAgICAgICAgICAgICByZXNvbHZlKG5ldyBDYWNoZVNvcnRlZFNldEdldFNjb3Jlcy5NaXNzKCkpO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChyZXNwPy5mb3VuZCkge1xuICAgICAgICAgICAgICBjb25zdCBlbGVtZW50cyA9IHJlc3AuZm91bmQuZWxlbWVudHMubWFwKGVsZSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gdGhpcy5jb252ZXJ0RUNhY2hlUmVzdWx0KGVsZS5yZXN1bHQpO1xuICAgICAgICAgICAgICAgIHJldHVybiBuZXcgX1NvcnRlZFNldEdldFNjb3JlUmVzcG9uc2VQYXJ0KHJlc3VsdCwgZWxlLnNjb3JlKTtcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgIHJlc29sdmUobmV3IENhY2hlU29ydGVkU2V0R2V0U2NvcmVzLkhpdChlbGVtZW50cywgdmFsdWVzKSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICB0aGlzLmNhY2hlU2VydmljZUVycm9yTWFwcGVyLnJlc29sdmVPclJlamVjdEVycm9yKHtcbiAgICAgICAgICAgICAgICBlcnI6IGVycixcbiAgICAgICAgICAgICAgICBlcnJvclJlc3BvbnNlRmFjdG9yeUZuOiBlID0+XG4gICAgICAgICAgICAgICAgICBuZXcgQ2FjaGVTb3J0ZWRTZXRHZXRTY29yZXMuRXJyb3IoZSksXG4gICAgICAgICAgICAgICAgcmVzb2x2ZUZuOiByZXNvbHZlLFxuICAgICAgICAgICAgICAgIHJlamVjdEZuOiByZWplY3QsXG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBzb3J0ZWRTZXRJbmNyZW1lbnRTY29yZShcbiAgICBjYWNoZU5hbWU6IHN0cmluZyxcbiAgICBzb3J0ZWRTZXROYW1lOiBzdHJpbmcsXG4gICAgdmFsdWU6IHN0cmluZyB8IFVpbnQ4QXJyYXksXG4gICAgYW1vdW50ID0gMSxcbiAgICB0dGw6IENvbGxlY3Rpb25UdGwgPSBDb2xsZWN0aW9uVHRsLmZyb21DYWNoZVR0bCgpXG4gICk6IFByb21pc2U8Q2FjaGVTb3J0ZWRTZXRJbmNyZW1lbnRTY29yZS5SZXNwb25zZT4ge1xuICAgIHRyeSB7XG4gICAgICB2YWxpZGF0ZUNhY2hlTmFtZShjYWNoZU5hbWUpO1xuICAgICAgdmFsaWRhdGVTb3J0ZWRTZXROYW1lKHNvcnRlZFNldE5hbWUpO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgcmV0dXJuIHRoaXMuY2FjaGVTZXJ2aWNlRXJyb3JNYXBwZXIucmV0dXJuT3JUaHJvd0Vycm9yKFxuICAgICAgICBlcnIgYXMgRXJyb3IsXG4gICAgICAgIGVyciA9PiBuZXcgQ2FjaGVTb3J0ZWRTZXRJbmNyZW1lbnRTY29yZS5FcnJvcihlcnIpXG4gICAgICApO1xuICAgIH1cblxuICAgIHJldHVybiBhd2FpdCB0aGlzLnJhdGVMaW1pdGVkKGFzeW5jICgpID0+IHtcbiAgICAgIHJldHVybiBhd2FpdCB0aGlzLnNlbmRTb3J0ZWRTZXRJbmNyZW1lbnRTY29yZShcbiAgICAgICAgY2FjaGVOYW1lLFxuICAgICAgICB0aGlzLmNvbnZlcnQoc29ydGVkU2V0TmFtZSksXG4gICAgICAgIHRoaXMuY29udmVydCh2YWx1ZSksXG4gICAgICAgIGFtb3VudCxcbiAgICAgICAgdGhpcy5jb2xsZWN0aW9uVHRsT3JEZWZhdWx0TWlsbGlzZWNvbmRzKHR0bCksXG4gICAgICAgIHR0bC5yZWZyZXNoVHRsKClcbiAgICAgICk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHNlbmRTb3J0ZWRTZXRJbmNyZW1lbnRTY29yZShcbiAgICBjYWNoZU5hbWU6IHN0cmluZyxcbiAgICBzb3J0ZWRTZXROYW1lOiBVaW50OEFycmF5LFxuICAgIHZhbHVlOiBVaW50OEFycmF5LFxuICAgIGFtb3VudDogbnVtYmVyLFxuICAgIHR0bE1pbGxpc2Vjb25kczogbnVtYmVyLFxuICAgIHJlZnJlc2hUdGw6IGJvb2xlYW5cbiAgKTogUHJvbWlzZTxDYWNoZVNvcnRlZFNldEluY3JlbWVudFNjb3JlLlJlc3BvbnNlPiB7XG4gICAgY29uc3QgcmVxdWVzdCA9IG5ldyBncnBjQ2FjaGUuX1NvcnRlZFNldEluY3JlbWVudFJlcXVlc3Qoe1xuICAgICAgc2V0X25hbWU6IHNvcnRlZFNldE5hbWUsXG4gICAgICB2YWx1ZTogdmFsdWUsXG4gICAgICBhbW91bnQ6IGFtb3VudCxcbiAgICAgIHR0bF9taWxsaXNlY29uZHM6IHR0bE1pbGxpc2Vjb25kcyxcbiAgICAgIHJlZnJlc2hfdHRsOiByZWZyZXNoVHRsLFxuICAgIH0pO1xuICAgIGNvbnN0IG1ldGFkYXRhID0gdGhpcy5jcmVhdGVNZXRhZGF0YShjYWNoZU5hbWUpO1xuICAgIHJldHVybiBhd2FpdCBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICB0aGlzLmNsaWVudFdyYXBwZXJcbiAgICAgICAgLmdldENsaWVudCgpXG4gICAgICAgIC5Tb3J0ZWRTZXRJbmNyZW1lbnQoXG4gICAgICAgICAgcmVxdWVzdCxcbiAgICAgICAgICBtZXRhZGF0YSxcbiAgICAgICAgICB7aW50ZXJjZXB0b3JzOiB0aGlzLmludGVyY2VwdG9yc30sXG4gICAgICAgICAgKGVyciwgcmVzcCkgPT4ge1xuICAgICAgICAgICAgaWYgKHJlc3ApIHtcbiAgICAgICAgICAgICAgaWYgKHJlc3Auc2NvcmUpIHtcbiAgICAgICAgICAgICAgICByZXNvbHZlKG5ldyBDYWNoZVNvcnRlZFNldEluY3JlbWVudFNjb3JlLlN1Y2Nlc3MocmVzcC5zY29yZSkpO1xuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJlc29sdmUobmV3IENhY2hlU29ydGVkU2V0SW5jcmVtZW50U2NvcmUuU3VjY2VzcygwKSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHRoaXMuY2FjaGVTZXJ2aWNlRXJyb3JNYXBwZXIucmVzb2x2ZU9yUmVqZWN0RXJyb3Ioe1xuICAgICAgICAgICAgICAgIGVycjogZXJyLFxuICAgICAgICAgICAgICAgIGVycm9yUmVzcG9uc2VGYWN0b3J5Rm46IGUgPT5cbiAgICAgICAgICAgICAgICAgIG5ldyBDYWNoZVNvcnRlZFNldEluY3JlbWVudFNjb3JlLkVycm9yKGUpLFxuICAgICAgICAgICAgICAgIHJlc29sdmVGbjogcmVzb2x2ZSxcbiAgICAgICAgICAgICAgICByZWplY3RGbjogcmVqZWN0LFxuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICk7XG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgc29ydGVkU2V0UmVtb3ZlRWxlbWVudChcbiAgICBjYWNoZU5hbWU6IHN0cmluZyxcbiAgICBzb3J0ZWRTZXROYW1lOiBzdHJpbmcsXG4gICAgdmFsdWU6IHN0cmluZyB8IFVpbnQ4QXJyYXlcbiAgKTogUHJvbWlzZTxDYWNoZVNvcnRlZFNldFJlbW92ZUVsZW1lbnQuUmVzcG9uc2U+IHtcbiAgICB0cnkge1xuICAgICAgdmFsaWRhdGVDYWNoZU5hbWUoY2FjaGVOYW1lKTtcbiAgICAgIHZhbGlkYXRlU29ydGVkU2V0TmFtZShzb3J0ZWRTZXROYW1lKTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIHJldHVybiB0aGlzLmNhY2hlU2VydmljZUVycm9yTWFwcGVyLnJldHVybk9yVGhyb3dFcnJvcihcbiAgICAgICAgZXJyIGFzIEVycm9yLFxuICAgICAgICBlcnIgPT4gbmV3IENhY2hlU29ydGVkU2V0UmVtb3ZlRWxlbWVudC5FcnJvcihlcnIpXG4gICAgICApO1xuICAgIH1cblxuICAgIHJldHVybiBhd2FpdCB0aGlzLnJhdGVMaW1pdGVkKGFzeW5jICgpID0+IHtcbiAgICAgIHJldHVybiBhd2FpdCB0aGlzLnNlbmRTb3J0ZWRTZXRSZW1vdmVFbGVtZW50KFxuICAgICAgICBjYWNoZU5hbWUsXG4gICAgICAgIHRoaXMuY29udmVydChzb3J0ZWRTZXROYW1lKSxcbiAgICAgICAgdGhpcy5jb252ZXJ0KHZhbHVlKVxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgc2VuZFNvcnRlZFNldFJlbW92ZUVsZW1lbnQoXG4gICAgY2FjaGVOYW1lOiBzdHJpbmcsXG4gICAgc29ydGVkU2V0TmFtZTogVWludDhBcnJheSxcbiAgICB2YWx1ZTogVWludDhBcnJheVxuICApOiBQcm9taXNlPENhY2hlU29ydGVkU2V0UmVtb3ZlRWxlbWVudC5SZXNwb25zZT4ge1xuICAgIGNvbnN0IHJlcXVlc3QgPSBuZXcgZ3JwY0NhY2hlLl9Tb3J0ZWRTZXRSZW1vdmVSZXF1ZXN0KHtcbiAgICAgIHNldF9uYW1lOiBzb3J0ZWRTZXROYW1lLFxuICAgICAgc29tZTogbmV3IGdycGNDYWNoZS5fU29ydGVkU2V0UmVtb3ZlUmVxdWVzdC5fU29tZSh7XG4gICAgICAgIHZhbHVlczogW3ZhbHVlXSxcbiAgICAgIH0pLFxuICAgIH0pO1xuXG4gICAgY29uc3QgbWV0YWRhdGEgPSB0aGlzLmNyZWF0ZU1ldGFkYXRhKGNhY2hlTmFtZSk7XG4gICAgcmV0dXJuIGF3YWl0IG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHRoaXMuY2xpZW50V3JhcHBlci5nZXRDbGllbnQoKS5Tb3J0ZWRTZXRSZW1vdmUoXG4gICAgICAgIHJlcXVlc3QsXG4gICAgICAgIG1ldGFkYXRhLFxuICAgICAgICB7XG4gICAgICAgICAgaW50ZXJjZXB0b3JzOiB0aGlzLmludGVyY2VwdG9ycyxcbiAgICAgICAgfSxcbiAgICAgICAgZXJyID0+IHtcbiAgICAgICAgICBpZiAoZXJyKSB7XG4gICAgICAgICAgICB0aGlzLmNhY2hlU2VydmljZUVycm9yTWFwcGVyLnJlc29sdmVPclJlamVjdEVycm9yKHtcbiAgICAgICAgICAgICAgZXJyOiBlcnIsXG4gICAgICAgICAgICAgIGVycm9yUmVzcG9uc2VGYWN0b3J5Rm46IGUgPT5cbiAgICAgICAgICAgICAgICBuZXcgQ2FjaGVTb3J0ZWRTZXRSZW1vdmVFbGVtZW50LkVycm9yKGUpLFxuICAgICAgICAgICAgICByZXNvbHZlRm46IHJlc29sdmUsXG4gICAgICAgICAgICAgIHJlamVjdEZuOiByZWplY3QsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmVzb2x2ZShuZXcgQ2FjaGVTb3J0ZWRTZXRSZW1vdmVFbGVtZW50LlN1Y2Nlc3MoKSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICApO1xuICAgIH0pO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIHNvcnRlZFNldFJlbW92ZUVsZW1lbnRzKFxuICAgIGNhY2hlTmFtZTogc3RyaW5nLFxuICAgIHNvcnRlZFNldE5hbWU6IHN0cmluZyxcbiAgICB2YWx1ZXM6IHN0cmluZ1tdIHwgVWludDhBcnJheVtdXG4gICk6IFByb21pc2U8Q2FjaGVTb3J0ZWRTZXRSZW1vdmVFbGVtZW50cy5SZXNwb25zZT4ge1xuICAgIHRyeSB7XG4gICAgICB2YWxpZGF0ZUNhY2hlTmFtZShjYWNoZU5hbWUpO1xuICAgICAgdmFsaWRhdGVTb3J0ZWRTZXROYW1lKHNvcnRlZFNldE5hbWUpO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgcmV0dXJuIHRoaXMuY2FjaGVTZXJ2aWNlRXJyb3JNYXBwZXIucmV0dXJuT3JUaHJvd0Vycm9yKFxuICAgICAgICBlcnIgYXMgRXJyb3IsXG4gICAgICAgIGVyciA9PiBuZXcgQ2FjaGVTb3J0ZWRTZXRSZW1vdmVFbGVtZW50cy5FcnJvcihlcnIpXG4gICAgICApO1xuICAgIH1cblxuICAgIHJldHVybiBhd2FpdCB0aGlzLnJhdGVMaW1pdGVkKGFzeW5jICgpID0+IHtcbiAgICAgIHJldHVybiBhd2FpdCB0aGlzLnNlbmRTb3J0ZWRTZXRSZW1vdmVFbGVtZW50cyhcbiAgICAgICAgY2FjaGVOYW1lLFxuICAgICAgICB0aGlzLmNvbnZlcnQoc29ydGVkU2V0TmFtZSksXG4gICAgICAgIHRoaXMuY29udmVydEFycmF5KHZhbHVlcylcbiAgICAgICk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHNlbmRTb3J0ZWRTZXRSZW1vdmVFbGVtZW50cyhcbiAgICBjYWNoZU5hbWU6IHN0cmluZyxcbiAgICBzb3J0ZWRTZXROYW1lOiBVaW50OEFycmF5LFxuICAgIHZhbHVlczogVWludDhBcnJheVtdXG4gICk6IFByb21pc2U8Q2FjaGVTb3J0ZWRTZXRSZW1vdmVFbGVtZW50cy5SZXNwb25zZT4ge1xuICAgIGNvbnN0IHJlcXVlc3QgPSBuZXcgZ3JwY0NhY2hlLl9Tb3J0ZWRTZXRSZW1vdmVSZXF1ZXN0KHtcbiAgICAgIHNldF9uYW1lOiBzb3J0ZWRTZXROYW1lLFxuICAgICAgc29tZTogbmV3IGdycGNDYWNoZS5fU29ydGVkU2V0UmVtb3ZlUmVxdWVzdC5fU29tZSh7XG4gICAgICAgIHZhbHVlczogdmFsdWVzLFxuICAgICAgfSksXG4gICAgfSk7XG5cbiAgICBjb25zdCBtZXRhZGF0YSA9IHRoaXMuY3JlYXRlTWV0YWRhdGEoY2FjaGVOYW1lKTtcbiAgICByZXR1cm4gYXdhaXQgbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgdGhpcy5jbGllbnRXcmFwcGVyLmdldENsaWVudCgpLlNvcnRlZFNldFJlbW92ZShcbiAgICAgICAgcmVxdWVzdCxcbiAgICAgICAgbWV0YWRhdGEsXG4gICAgICAgIHtcbiAgICAgICAgICBpbnRlcmNlcHRvcnM6IHRoaXMuaW50ZXJjZXB0b3JzLFxuICAgICAgICB9LFxuICAgICAgICBlcnIgPT4ge1xuICAgICAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgICAgIHRoaXMuY2FjaGVTZXJ2aWNlRXJyb3JNYXBwZXIucmVzb2x2ZU9yUmVqZWN0RXJyb3Ioe1xuICAgICAgICAgICAgICBlcnI6IGVycixcbiAgICAgICAgICAgICAgZXJyb3JSZXNwb25zZUZhY3RvcnlGbjogZSA9PlxuICAgICAgICAgICAgICAgIG5ldyBDYWNoZVNvcnRlZFNldFJlbW92ZUVsZW1lbnRzLkVycm9yKGUpLFxuICAgICAgICAgICAgICByZXNvbHZlRm46IHJlc29sdmUsXG4gICAgICAgICAgICAgIHJlamVjdEZuOiByZWplY3QsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmVzb2x2ZShuZXcgQ2FjaGVTb3J0ZWRTZXRSZW1vdmVFbGVtZW50cy5TdWNjZXNzKCkpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBzb3J0ZWRTZXRMZW5ndGgoXG4gICAgY2FjaGVOYW1lOiBzdHJpbmcsXG4gICAgc29ydGVkU2V0TmFtZTogc3RyaW5nXG4gICk6IFByb21pc2U8Q2FjaGVTb3J0ZWRTZXRMZW5ndGguUmVzcG9uc2U+IHtcbiAgICB0cnkge1xuICAgICAgdmFsaWRhdGVDYWNoZU5hbWUoY2FjaGVOYW1lKTtcbiAgICAgIHZhbGlkYXRlU29ydGVkU2V0TmFtZShzb3J0ZWRTZXROYW1lKTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIHJldHVybiB0aGlzLmNhY2hlU2VydmljZUVycm9yTWFwcGVyLnJldHVybk9yVGhyb3dFcnJvcihcbiAgICAgICAgZXJyIGFzIEVycm9yLFxuICAgICAgICBlcnIgPT4gbmV3IENhY2hlU29ydGVkU2V0TGVuZ3RoLkVycm9yKGVycilcbiAgICAgICk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGF3YWl0IHRoaXMucmF0ZUxpbWl0ZWQoYXN5bmMgKCkgPT4ge1xuICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuc2VuZFNvcnRlZFNldExlbmd0aChcbiAgICAgICAgY2FjaGVOYW1lLFxuICAgICAgICB0aGlzLmNvbnZlcnQoc29ydGVkU2V0TmFtZSlcbiAgICAgICk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHNlbmRTb3J0ZWRTZXRMZW5ndGgoXG4gICAgY2FjaGVOYW1lOiBzdHJpbmcsXG4gICAgc29ydGVkU2V0TmFtZTogVWludDhBcnJheVxuICApOiBQcm9taXNlPENhY2hlU29ydGVkU2V0TGVuZ3RoLlJlc3BvbnNlPiB7XG4gICAgY29uc3QgcmVxdWVzdCA9IG5ldyBncnBjQ2FjaGUuX1NvcnRlZFNldExlbmd0aFJlcXVlc3Qoe1xuICAgICAgc2V0X25hbWU6IHNvcnRlZFNldE5hbWUsXG4gICAgfSk7XG5cbiAgICBjb25zdCBtZXRhZGF0YSA9IHRoaXMuY3JlYXRlTWV0YWRhdGEoY2FjaGVOYW1lKTtcbiAgICByZXR1cm4gYXdhaXQgbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgdGhpcy5jbGllbnRXcmFwcGVyLmdldENsaWVudCgpLlNvcnRlZFNldExlbmd0aChcbiAgICAgICAgcmVxdWVzdCxcbiAgICAgICAgbWV0YWRhdGEsXG4gICAgICAgIHtcbiAgICAgICAgICBpbnRlcmNlcHRvcnM6IHRoaXMuaW50ZXJjZXB0b3JzLFxuICAgICAgICB9LFxuICAgICAgICAoZXJyLCByZXNwKSA9PiB7XG4gICAgICAgICAgaWYgKHJlc3A/Lm1pc3NpbmcpIHtcbiAgICAgICAgICAgIHJlc29sdmUobmV3IENhY2hlU29ydGVkU2V0TGVuZ3RoLk1pc3MoKSk7XG4gICAgICAgICAgfSBlbHNlIGlmIChyZXNwPy5mb3VuZCkge1xuICAgICAgICAgICAgaWYgKCFyZXNwLmZvdW5kLmxlbmd0aCkge1xuICAgICAgICAgICAgICByZXNvbHZlKG5ldyBDYWNoZVNvcnRlZFNldExlbmd0aC5NaXNzKCkpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgcmVzb2x2ZShuZXcgQ2FjaGVTb3J0ZWRTZXRMZW5ndGguSGl0KHJlc3AuZm91bmQubGVuZ3RoKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuY2FjaGVTZXJ2aWNlRXJyb3JNYXBwZXIucmVzb2x2ZU9yUmVqZWN0RXJyb3Ioe1xuICAgICAgICAgICAgICBlcnI6IGVycixcbiAgICAgICAgICAgICAgZXJyb3JSZXNwb25zZUZhY3RvcnlGbjogZSA9PiBuZXcgQ2FjaGVTb3J0ZWRTZXRMZW5ndGguRXJyb3IoZSksXG4gICAgICAgICAgICAgIHJlc29sdmVGbjogcmVzb2x2ZSxcbiAgICAgICAgICAgICAgcmVqZWN0Rm46IHJlamVjdCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBzb3J0ZWRTZXRMZW5ndGhCeVNjb3JlKFxuICAgIGNhY2hlTmFtZTogc3RyaW5nLFxuICAgIHNvcnRlZFNldE5hbWU6IHN0cmluZyxcbiAgICBtaW5TY29yZT86IG51bWJlcixcbiAgICBtYXhTY29yZT86IG51bWJlclxuICApOiBQcm9taXNlPENhY2hlU29ydGVkU2V0TGVuZ3RoQnlTY29yZS5SZXNwb25zZT4ge1xuICAgIHRyeSB7XG4gICAgICB2YWxpZGF0ZUNhY2hlTmFtZShjYWNoZU5hbWUpO1xuICAgICAgdmFsaWRhdGVTb3J0ZWRTZXROYW1lKHNvcnRlZFNldE5hbWUpO1xuICAgICAgdmFsaWRhdGVTb3J0ZWRTZXRTY29yZXMobWluU2NvcmUsIG1heFNjb3JlKTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIHJldHVybiB0aGlzLmNhY2hlU2VydmljZUVycm9yTWFwcGVyLnJldHVybk9yVGhyb3dFcnJvcihcbiAgICAgICAgZXJyIGFzIEVycm9yLFxuICAgICAgICBlcnIgPT4gbmV3IENhY2hlU29ydGVkU2V0TGVuZ3RoQnlTY29yZS5FcnJvcihlcnIpXG4gICAgICApO1xuICAgIH1cblxuICAgIHJldHVybiBhd2FpdCB0aGlzLnJhdGVMaW1pdGVkKGFzeW5jICgpID0+IHtcbiAgICAgIHJldHVybiBhd2FpdCB0aGlzLnNlbmRTb3J0ZWRTZXRMZW5ndGhCeVNjb3JlKFxuICAgICAgICBjYWNoZU5hbWUsXG4gICAgICAgIHRoaXMuY29udmVydChzb3J0ZWRTZXROYW1lKSxcbiAgICAgICAgbWluU2NvcmUsXG4gICAgICAgIG1heFNjb3JlXG4gICAgICApO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBzZW5kU29ydGVkU2V0TGVuZ3RoQnlTY29yZShcbiAgICBjYWNoZU5hbWU6IHN0cmluZyxcbiAgICBzb3J0ZWRTZXROYW1lOiBVaW50OEFycmF5LFxuICAgIG1pblNjb3JlPzogbnVtYmVyLFxuICAgIG1heFNjb3JlPzogbnVtYmVyXG4gICk6IFByb21pc2U8Q2FjaGVTb3J0ZWRTZXRMZW5ndGhCeVNjb3JlLlJlc3BvbnNlPiB7XG4gICAgY29uc3QgcmVxdWVzdCA9IG5ldyBncnBjQ2FjaGUuX1NvcnRlZFNldExlbmd0aEJ5U2NvcmVSZXF1ZXN0KHtcbiAgICAgIHNldF9uYW1lOiBzb3J0ZWRTZXROYW1lLFxuICAgIH0pO1xuXG4gICAgaWYgKG1pblNjb3JlID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJlcXVlc3QudW5ib3VuZGVkX21pbiA9IG5ldyBfVW5ib3VuZGVkKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJlcXVlc3QuaW5jbHVzaXZlX21pbiA9IG1pblNjb3JlO1xuICAgIH1cblxuICAgIGlmIChtYXhTY29yZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXF1ZXN0LnVuYm91bmRlZF9tYXggPSBuZXcgX1VuYm91bmRlZCgpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXF1ZXN0LmluY2x1c2l2ZV9tYXggPSBtYXhTY29yZTtcbiAgICB9XG5cbiAgICBjb25zdCBtZXRhZGF0YSA9IHRoaXMuY3JlYXRlTWV0YWRhdGEoY2FjaGVOYW1lKTtcbiAgICByZXR1cm4gYXdhaXQgbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgdGhpcy5jbGllbnRXcmFwcGVyLmdldENsaWVudCgpLlNvcnRlZFNldExlbmd0aEJ5U2NvcmUoXG4gICAgICAgIHJlcXVlc3QsXG4gICAgICAgIG1ldGFkYXRhLFxuICAgICAgICB7XG4gICAgICAgICAgaW50ZXJjZXB0b3JzOiB0aGlzLmludGVyY2VwdG9ycyxcbiAgICAgICAgfSxcbiAgICAgICAgKGVyciwgcmVzcCkgPT4ge1xuICAgICAgICAgIGlmIChyZXNwPy5taXNzaW5nKSB7XG4gICAgICAgICAgICByZXNvbHZlKG5ldyBDYWNoZVNvcnRlZFNldExlbmd0aEJ5U2NvcmUuTWlzcygpKTtcbiAgICAgICAgICB9IGVsc2UgaWYgKHJlc3A/LmZvdW5kKSB7XG4gICAgICAgICAgICBpZiAoIXJlc3AuZm91bmQubGVuZ3RoKSB7XG4gICAgICAgICAgICAgIHJlc29sdmUobmV3IENhY2hlU29ydGVkU2V0TGVuZ3RoQnlTY29yZS5NaXNzKCkpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgcmVzb2x2ZShuZXcgQ2FjaGVTb3J0ZWRTZXRMZW5ndGhCeVNjb3JlLkhpdChyZXNwLmZvdW5kLmxlbmd0aCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmNhY2hlU2VydmljZUVycm9yTWFwcGVyLnJlc29sdmVPclJlamVjdEVycm9yKHtcbiAgICAgICAgICAgICAgZXJyOiBlcnIsXG4gICAgICAgICAgICAgIGVycm9yUmVzcG9uc2VGYWN0b3J5Rm46IGUgPT5cbiAgICAgICAgICAgICAgICBuZXcgQ2FjaGVTb3J0ZWRTZXRMZW5ndGhCeVNjb3JlLkVycm9yKGUpLFxuICAgICAgICAgICAgICByZXNvbHZlRm46IHJlc29sdmUsXG4gICAgICAgICAgICAgIHJlamVjdEZuOiByZWplY3QsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGluaXRpYWxpemVJbnRlcmNlcHRvcnMoXG4gICAgaGVhZGVyczogSGVhZGVyW10sXG4gICAgbG9nZ2VyRmFjdG9yeTogTW9tZW50b0xvZ2dlckZhY3RvcnksXG4gICAgbWlkZGxld2FyZXM6IE1pZGRsZXdhcmVbXSxcbiAgICBtaWRkbGV3YXJlUmVxdWVzdENvbnRleHQ6IE1pZGRsZXdhcmVSZXF1ZXN0SGFuZGxlckNvbnRleHRcbiAgKTogSW50ZXJjZXB0b3JbXSB7XG4gICAgcmV0dXJuIFtcbiAgICAgIG1pZGRsZXdhcmVzSW50ZXJjZXB0b3IoXG4gICAgICAgIGxvZ2dlckZhY3RvcnksXG4gICAgICAgIG1pZGRsZXdhcmVzLFxuICAgICAgICBtaWRkbGV3YXJlUmVxdWVzdENvbnRleHQsXG4gICAgICAgIHRoaXMuY2xpZW50V3JhcHBlci5nZXRDbGllbnQoKVxuICAgICAgKSxcbiAgICAgIEhlYWRlckludGVyY2VwdG9yLmNyZWF0ZUhlYWRlcnNJbnRlcmNlcHRvcihoZWFkZXJzKSxcbiAgICAgIFJldHJ5SW50ZXJjZXB0b3IuY3JlYXRlUmV0cnlJbnRlcmNlcHRvcih7XG4gICAgICAgIGNsaWVudE5hbWU6ICdDYWNoZURhdGFDbGllbnQnLFxuICAgICAgICBsb2dnZXJGYWN0b3J5OiB0aGlzLmNvbmZpZ3VyYXRpb24uZ2V0TG9nZ2VyRmFjdG9yeSgpLFxuICAgICAgICByZXRyeVN0cmF0ZWd5OiB0aGlzLmNvbmZpZ3VyYXRpb24uZ2V0UmV0cnlTdHJhdGVneSgpLFxuICAgICAgICBvdmVyYWxsUmVxdWVzdFRpbWVvdXRNczogdGhpcy5yZXF1ZXN0VGltZW91dE1zLFxuICAgICAgfSksXG4gICAgXTtcbiAgfVxuXG4gIC8vIFRPRE8gaHR0cHM6Ly9naXRodWIuY29tL21vbWVudG9ocS9jbGllbnQtc2RrLW5vZGVqcy9pc3N1ZXMvMzQ5XG4gIC8vIGRlY2lkZSBvbiBzdHJlYW1pbmcgaW50ZXJjZXB0b3JzIGFuZCBtaWRkbGV3YXJlc1xuICBwcml2YXRlIGluaXRpYWxpemVTdHJlYW1pbmdJbnRlcmNlcHRvcnMoaGVhZGVyczogSGVhZGVyW10pOiBJbnRlcmNlcHRvcltdIHtcbiAgICByZXR1cm4gW0hlYWRlckludGVyY2VwdG9yLmNyZWF0ZUhlYWRlcnNJbnRlcmNlcHRvcihoZWFkZXJzKV07XG4gIH1cblxuICBwcml2YXRlIGNvbnZlcnQodjogc3RyaW5nIHwgVWludDhBcnJheSk6IFVpbnQ4QXJyYXkge1xuICAgIGlmICh0eXBlb2YgdiA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHJldHVybiB0aGlzLnRleHRFbmNvZGVyLmVuY29kZSh2KTtcbiAgICB9XG4gICAgcmV0dXJuIHY7XG4gIH1cblxuICBwcml2YXRlIGNvbnZlcnRBcnJheSh2OiBzdHJpbmdbXSB8IFVpbnQ4QXJyYXlbXSk6IFVpbnQ4QXJyYXlbXSB7XG4gICAgcmV0dXJuIHYubWFwKGkgPT4gdGhpcy5jb252ZXJ0KGkpKTtcbiAgfVxuXG4gIHByaXZhdGUgY29udmVydEVsZW1lbnRzKFxuICAgIGVsZW1lbnRzOlxuICAgICAgfCBNYXA8c3RyaW5nIHwgVWludDhBcnJheSwgc3RyaW5nIHwgVWludDhBcnJheT5cbiAgICAgIHwgUmVjb3JkPHN0cmluZywgc3RyaW5nIHwgVWludDhBcnJheT5cbiAgICAgIHwgQXJyYXk8W3N0cmluZywgc3RyaW5nIHwgVWludDhBcnJheV0+XG4gICk6IGdycGNDYWNoZS5fRGljdGlvbmFyeUZpZWxkVmFsdWVQYWlyW10ge1xuICAgIGlmIChlbGVtZW50cyBpbnN0YW5jZW9mIEFycmF5KSB7XG4gICAgICByZXR1cm4gdGhpcy5jb252ZXJ0RWxlbWVudHMobmV3IE1hcChlbGVtZW50cykpO1xuICAgIH0gZWxzZSBpZiAoZWxlbWVudHMgaW5zdGFuY2VvZiBNYXApIHtcbiAgICAgIHJldHVybiBbLi4uZWxlbWVudHMuZW50cmllcygpXS5tYXAoXG4gICAgICAgIGVsZW1lbnQgPT5cbiAgICAgICAgICBuZXcgZ3JwY0NhY2hlLl9EaWN0aW9uYXJ5RmllbGRWYWx1ZVBhaXIoe1xuICAgICAgICAgICAgZmllbGQ6IHRoaXMuY29udmVydChlbGVtZW50WzBdKSxcbiAgICAgICAgICAgIHZhbHVlOiB0aGlzLmNvbnZlcnQoZWxlbWVudFsxXSksXG4gICAgICAgICAgfSlcbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBPYmplY3QuZW50cmllcyhlbGVtZW50cykubWFwKFxuICAgICAgICBlbGVtZW50ID0+XG4gICAgICAgICAgbmV3IGdycGNDYWNoZS5fRGljdGlvbmFyeUZpZWxkVmFsdWVQYWlyKHtcbiAgICAgICAgICAgIGZpZWxkOiB0aGlzLmNvbnZlcnQoZWxlbWVudFswXSksXG4gICAgICAgICAgICB2YWx1ZTogdGhpcy5jb252ZXJ0KGVsZW1lbnRbMV0pLFxuICAgICAgICAgIH0pXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgY29udmVydFNvcnRlZFNldE1hcE9yUmVjb3JkKFxuICAgIGVsZW1lbnRzOlxuICAgICAgfCBNYXA8c3RyaW5nIHwgVWludDhBcnJheSwgbnVtYmVyPlxuICAgICAgfCBSZWNvcmQ8c3RyaW5nLCBudW1iZXI+XG4gICAgICB8IEFycmF5PFtzdHJpbmcsIG51bWJlcl0+XG4gICk6IGdycGNDYWNoZS5fU29ydGVkU2V0RWxlbWVudFtdIHtcbiAgICBpZiAoZWxlbWVudHMgaW5zdGFuY2VvZiBBcnJheSkge1xuICAgICAgcmV0dXJuIHRoaXMuY29udmVydFNvcnRlZFNldE1hcE9yUmVjb3JkKG5ldyBNYXAoZWxlbWVudHMpKTtcbiAgICB9IGVsc2UgaWYgKGVsZW1lbnRzIGluc3RhbmNlb2YgTWFwKSB7XG4gICAgICByZXR1cm4gWy4uLmVsZW1lbnRzLmVudHJpZXMoKV0ubWFwKFxuICAgICAgICBlbGVtZW50ID0+XG4gICAgICAgICAgbmV3IGdycGNDYWNoZS5fU29ydGVkU2V0RWxlbWVudCh7XG4gICAgICAgICAgICB2YWx1ZTogdGhpcy5jb252ZXJ0KGVsZW1lbnRbMF0pLFxuICAgICAgICAgICAgc2NvcmU6IGVsZW1lbnRbMV0sXG4gICAgICAgICAgfSlcbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBPYmplY3QuZW50cmllcyhlbGVtZW50cykubWFwKFxuICAgICAgICBlbGVtZW50ID0+XG4gICAgICAgICAgbmV3IGdycGNDYWNoZS5fU29ydGVkU2V0RWxlbWVudCh7XG4gICAgICAgICAgICB2YWx1ZTogdGhpcy5jb252ZXJ0KGVsZW1lbnRbMF0pLFxuICAgICAgICAgICAgc2NvcmU6IGVsZW1lbnRbMV0sXG4gICAgICAgICAgfSlcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBjb252ZXJ0U2V0QmF0Y2hFbGVtZW50cyhcbiAgICBlbGVtZW50czpcbiAgICAgIHwgTWFwPHN0cmluZyB8IFVpbnQ4QXJyYXksIHN0cmluZyB8IFVpbnQ4QXJyYXk+XG4gICAgICB8IFJlY29yZDxzdHJpbmcsIHN0cmluZyB8IFVpbnQ4QXJyYXk+XG4gICAgICB8IEFycmF5PFNldEJhdGNoSXRlbT4sXG4gICAgdHRsOiBudW1iZXJcbiAgKTogW1VpbnQ4QXJyYXksIFVpbnQ4QXJyYXksIG51bWJlcl1bXSB7XG4gICAgaWYgKGVsZW1lbnRzIGluc3RhbmNlb2YgQXJyYXkpIHtcbiAgICAgIHJldHVybiBlbGVtZW50cy5tYXAoZWxlbWVudCA9PiBbXG4gICAgICAgIHRoaXMuY29udmVydChlbGVtZW50LmtleSksXG4gICAgICAgIHRoaXMuY29udmVydChlbGVtZW50LnZhbHVlKSxcbiAgICAgICAgZWxlbWVudC50dGwgPz8gdHRsLFxuICAgICAgXSk7XG4gICAgfSBlbHNlIGlmIChlbGVtZW50cyBpbnN0YW5jZW9mIE1hcCkge1xuICAgICAgcmV0dXJuIFsuLi5lbGVtZW50cy5lbnRyaWVzKCldLm1hcCgoW2ssIHZdKSA9PiBbXG4gICAgICAgIHRoaXMuY29udmVydChrKSxcbiAgICAgICAgdGhpcy5jb252ZXJ0KHYpLFxuICAgICAgICB0dGwsXG4gICAgICBdKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIE9iamVjdC5lbnRyaWVzKGVsZW1lbnRzKS5tYXAoZWxlbWVudCA9PiBbXG4gICAgICAgIHRoaXMuY29udmVydChlbGVtZW50WzBdKSxcbiAgICAgICAgdGhpcy5jb252ZXJ0KGVsZW1lbnRbMV0pLFxuICAgICAgICB0dGwsXG4gICAgICBdKTtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgaXRlbUdldFR5cGUoXG4gICAgY2FjaGVOYW1lOiBzdHJpbmcsXG4gICAga2V5OiBzdHJpbmcgfCBVaW50OEFycmF5XG4gICk6IFByb21pc2U8Q2FjaGVJdGVtR2V0VHlwZS5SZXNwb25zZT4ge1xuICAgIHRyeSB7XG4gICAgICB2YWxpZGF0ZUNhY2hlTmFtZShjYWNoZU5hbWUpO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgcmV0dXJuIHRoaXMuY2FjaGVTZXJ2aWNlRXJyb3JNYXBwZXIucmV0dXJuT3JUaHJvd0Vycm9yKFxuICAgICAgICBlcnIgYXMgRXJyb3IsXG4gICAgICAgIGVyciA9PiBuZXcgQ2FjaGVJdGVtR2V0VHlwZS5FcnJvcihlcnIpXG4gICAgICApO1xuICAgIH1cblxuICAgIHJldHVybiBhd2FpdCB0aGlzLnJhdGVMaW1pdGVkKGFzeW5jICgpID0+IHtcbiAgICAgIHJldHVybiBhd2FpdCB0aGlzLnNlbmRJdGVtR2V0VHlwZShjYWNoZU5hbWUsIHRoaXMuY29udmVydChrZXkpKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgc2VuZEl0ZW1HZXRUeXBlKFxuICAgIGNhY2hlTmFtZTogc3RyaW5nLFxuICAgIGtleTogVWludDhBcnJheVxuICApOiBQcm9taXNlPENhY2hlSXRlbUdldFR5cGUuUmVzcG9uc2U+IHtcbiAgICBjb25zdCByZXF1ZXN0ID0gbmV3IGdycGNDYWNoZS5fSXRlbUdldFR5cGVSZXF1ZXN0KHtcbiAgICAgIGNhY2hlX2tleToga2V5LFxuICAgIH0pO1xuICAgIGNvbnN0IG1ldGFkYXRhID0gdGhpcy5jcmVhdGVNZXRhZGF0YShjYWNoZU5hbWUpO1xuICAgIHJldHVybiBhd2FpdCBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICB0aGlzLmNsaWVudFdyYXBwZXIuZ2V0Q2xpZW50KCkuSXRlbUdldFR5cGUoXG4gICAgICAgIHJlcXVlc3QsXG4gICAgICAgIG1ldGFkYXRhLFxuICAgICAgICB7XG4gICAgICAgICAgaW50ZXJjZXB0b3JzOiB0aGlzLmludGVyY2VwdG9ycyxcbiAgICAgICAgfSxcbiAgICAgICAgKGVyciwgcmVzcCkgPT4ge1xuICAgICAgICAgIGlmIChyZXNwPy5taXNzaW5nKSB7XG4gICAgICAgICAgICByZXNvbHZlKG5ldyBDYWNoZUl0ZW1HZXRUeXBlLk1pc3MoKSk7XG4gICAgICAgICAgfSBlbHNlIGlmIChyZXNwPy5mb3VuZCkge1xuICAgICAgICAgICAgcmVzb2x2ZShcbiAgICAgICAgICAgICAgbmV3IENhY2hlSXRlbUdldFR5cGUuSGl0KFxuICAgICAgICAgICAgICAgIHRoaXMuY29udmVydEl0ZW1UeXBlUmVzdWx0KHJlc3AuZm91bmQuaXRlbV90eXBlKVxuICAgICAgICAgICAgICApXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmNhY2hlU2VydmljZUVycm9yTWFwcGVyLnJlc29sdmVPclJlamVjdEVycm9yKHtcbiAgICAgICAgICAgICAgZXJyOiBlcnIsXG4gICAgICAgICAgICAgIGVycm9yUmVzcG9uc2VGYWN0b3J5Rm46IGUgPT4gbmV3IENhY2hlSXRlbUdldFR5cGUuRXJyb3IoZSksXG4gICAgICAgICAgICAgIHJlc29sdmVGbjogcmVzb2x2ZSxcbiAgICAgICAgICAgICAgcmVqZWN0Rm46IHJlamVjdCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBpdGVtR2V0VHRsKFxuICAgIGNhY2hlTmFtZTogc3RyaW5nLFxuICAgIGtleTogc3RyaW5nIHwgVWludDhBcnJheVxuICApOiBQcm9taXNlPENhY2hlSXRlbUdldFR0bC5SZXNwb25zZT4ge1xuICAgIHRyeSB7XG4gICAgICB2YWxpZGF0ZUNhY2hlTmFtZShjYWNoZU5hbWUpO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgcmV0dXJuIHRoaXMuY2FjaGVTZXJ2aWNlRXJyb3JNYXBwZXIucmV0dXJuT3JUaHJvd0Vycm9yKFxuICAgICAgICBlcnIgYXMgRXJyb3IsXG4gICAgICAgIGVyciA9PiBuZXcgQ2FjaGVJdGVtR2V0VHRsLkVycm9yKGVycilcbiAgICAgICk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGF3YWl0IHRoaXMucmF0ZUxpbWl0ZWQoYXN5bmMgKCkgPT4ge1xuICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuc2VuZEl0ZW1HZXRUdGwoY2FjaGVOYW1lLCB0aGlzLmNvbnZlcnQoa2V5KSk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHNlbmRJdGVtR2V0VHRsKFxuICAgIGNhY2hlTmFtZTogc3RyaW5nLFxuICAgIGtleTogVWludDhBcnJheVxuICApOiBQcm9taXNlPENhY2hlSXRlbUdldFR0bC5SZXNwb25zZT4ge1xuICAgIGNvbnN0IHJlcXVlc3QgPSBuZXcgZ3JwY0NhY2hlLl9JdGVtR2V0VHRsUmVxdWVzdCh7XG4gICAgICBjYWNoZV9rZXk6IGtleSxcbiAgICB9KTtcbiAgICBjb25zdCBtZXRhZGF0YSA9IHRoaXMuY3JlYXRlTWV0YWRhdGEoY2FjaGVOYW1lKTtcbiAgICByZXR1cm4gYXdhaXQgbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgdGhpcy5jbGllbnRXcmFwcGVyLmdldENsaWVudCgpLkl0ZW1HZXRUdGwoXG4gICAgICAgIHJlcXVlc3QsXG4gICAgICAgIG1ldGFkYXRhLFxuICAgICAgICB7XG4gICAgICAgICAgaW50ZXJjZXB0b3JzOiB0aGlzLmludGVyY2VwdG9ycyxcbiAgICAgICAgfSxcbiAgICAgICAgKGVyciwgcmVzcCkgPT4ge1xuICAgICAgICAgIGlmIChyZXNwPy5taXNzaW5nKSB7XG4gICAgICAgICAgICByZXNvbHZlKG5ldyBDYWNoZUl0ZW1HZXRUdGwuTWlzcygpKTtcbiAgICAgICAgICB9IGVsc2UgaWYgKHJlc3A/LmZvdW5kKSB7XG4gICAgICAgICAgICByZXNvbHZlKG5ldyBDYWNoZUl0ZW1HZXRUdGwuSGl0KHJlc3AuZm91bmQucmVtYWluaW5nX3R0bF9taWxsaXMpKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5jYWNoZVNlcnZpY2VFcnJvck1hcHBlci5yZXNvbHZlT3JSZWplY3RFcnJvcih7XG4gICAgICAgICAgICAgIGVycjogZXJyLFxuICAgICAgICAgICAgICBlcnJvclJlc3BvbnNlRmFjdG9yeUZuOiBlID0+IG5ldyBDYWNoZUl0ZW1HZXRUdGwuRXJyb3IoZSksXG4gICAgICAgICAgICAgIHJlc29sdmVGbjogcmVzb2x2ZSxcbiAgICAgICAgICAgICAgcmVqZWN0Rm46IHJlamVjdCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBrZXlFeGlzdHMoXG4gICAgY2FjaGVOYW1lOiBzdHJpbmcsXG4gICAga2V5OiBzdHJpbmcgfCBVaW50OEFycmF5XG4gICk6IFByb21pc2U8Q2FjaGVLZXlFeGlzdHMuUmVzcG9uc2U+IHtcbiAgICB0cnkge1xuICAgICAgdmFsaWRhdGVDYWNoZU5hbWUoY2FjaGVOYW1lKTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIHJldHVybiB0aGlzLmNhY2hlU2VydmljZUVycm9yTWFwcGVyLnJldHVybk9yVGhyb3dFcnJvcihcbiAgICAgICAgZXJyIGFzIEVycm9yLFxuICAgICAgICBlcnIgPT4gbmV3IENhY2hlS2V5RXhpc3RzLkVycm9yKGVycilcbiAgICAgICk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGF3YWl0IHRoaXMucmF0ZUxpbWl0ZWQoYXN5bmMgKCkgPT4ge1xuICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuc2VuZEtleUV4aXN0cyhjYWNoZU5hbWUsIHRoaXMuY29udmVydChrZXkpKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgc2VuZEtleUV4aXN0cyhcbiAgICBjYWNoZU5hbWU6IHN0cmluZyxcbiAgICBrZXk6IFVpbnQ4QXJyYXlcbiAgKTogUHJvbWlzZTxDYWNoZUtleUV4aXN0cy5SZXNwb25zZT4ge1xuICAgIGNvbnN0IHJlcXVlc3QgPSBuZXcgZ3JwY0NhY2hlLl9LZXlzRXhpc3RSZXF1ZXN0KHtcbiAgICAgIGNhY2hlX2tleXM6IFtrZXldLFxuICAgIH0pO1xuICAgIGNvbnN0IG1ldGFkYXRhID0gdGhpcy5jcmVhdGVNZXRhZGF0YShjYWNoZU5hbWUpO1xuICAgIHJldHVybiBhd2FpdCBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICB0aGlzLmNsaWVudFdyYXBwZXIuZ2V0Q2xpZW50KCkuS2V5c0V4aXN0KFxuICAgICAgICByZXF1ZXN0LFxuICAgICAgICBtZXRhZGF0YSxcbiAgICAgICAge1xuICAgICAgICAgIGludGVyY2VwdG9yczogdGhpcy5pbnRlcmNlcHRvcnMsXG4gICAgICAgIH0sXG4gICAgICAgIChlcnIsIHJlc3ApID0+IHtcbiAgICAgICAgICBpZiAocmVzcCkge1xuICAgICAgICAgICAgcmVzb2x2ZShuZXcgQ2FjaGVLZXlFeGlzdHMuU3VjY2VzcyhyZXNwLmV4aXN0cykpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmNhY2hlU2VydmljZUVycm9yTWFwcGVyLnJlc29sdmVPclJlamVjdEVycm9yKHtcbiAgICAgICAgICAgICAgZXJyOiBlcnIsXG4gICAgICAgICAgICAgIGVycm9yUmVzcG9uc2VGYWN0b3J5Rm46IGUgPT4gbmV3IENhY2hlS2V5RXhpc3RzLkVycm9yKGUpLFxuICAgICAgICAgICAgICByZXNvbHZlRm46IHJlc29sdmUsXG4gICAgICAgICAgICAgIHJlamVjdEZuOiByZWplY3QsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICk7XG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgdXBkYXRlVHRsKFxuICAgIGNhY2hlTmFtZTogc3RyaW5nLFxuICAgIGtleTogc3RyaW5nIHwgVWludDhBcnJheSxcbiAgICB0dGxNaWxsaXNlY29uZHM6IG51bWJlclxuICApOiBQcm9taXNlPENhY2hlVXBkYXRlVHRsLlJlc3BvbnNlPiB7XG4gICAgdHJ5IHtcbiAgICAgIHZhbGlkYXRlQ2FjaGVOYW1lKGNhY2hlTmFtZSk7XG4gICAgICB2YWxpZGF0ZVZhbGlkRm9yU2Vjb25kcyh0dGxNaWxsaXNlY29uZHMpO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgcmV0dXJuIHRoaXMuY2FjaGVTZXJ2aWNlRXJyb3JNYXBwZXIucmV0dXJuT3JUaHJvd0Vycm9yKFxuICAgICAgICBlcnIgYXMgRXJyb3IsXG4gICAgICAgIGVyciA9PiBuZXcgQ2FjaGVVcGRhdGVUdGwuRXJyb3IoZXJyKVxuICAgICAgKTtcbiAgICB9XG5cbiAgICByZXR1cm4gYXdhaXQgdGhpcy5yYXRlTGltaXRlZChhc3luYyAoKSA9PiB7XG4gICAgICByZXR1cm4gYXdhaXQgdGhpcy5zZW5kVXBkYXRlVHRsKFxuICAgICAgICBjYWNoZU5hbWUsXG4gICAgICAgIHRoaXMuY29udmVydChrZXkpLFxuICAgICAgICB0dGxNaWxsaXNlY29uZHNcbiAgICAgICk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHNlbmRVcGRhdGVUdGwoXG4gICAgY2FjaGVOYW1lOiBzdHJpbmcsXG4gICAga2V5OiBVaW50OEFycmF5LFxuICAgIHR0bE1pbGxpc2Vjb25kczogbnVtYmVyXG4gICk6IFByb21pc2U8Q2FjaGVVcGRhdGVUdGwuUmVzcG9uc2U+IHtcbiAgICBjb25zdCByZXF1ZXN0ID0gbmV3IGdycGNDYWNoZS5fVXBkYXRlVHRsUmVxdWVzdCh7XG4gICAgICBjYWNoZV9rZXk6IGtleSxcbiAgICAgIG92ZXJ3cml0ZV90b19taWxsaXNlY29uZHM6IHR0bE1pbGxpc2Vjb25kcyxcbiAgICB9KTtcbiAgICBjb25zdCBtZXRhZGF0YSA9IHRoaXMuY3JlYXRlTWV0YWRhdGEoY2FjaGVOYW1lKTtcbiAgICByZXR1cm4gYXdhaXQgbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgdGhpcy5jbGllbnRXcmFwcGVyLmdldENsaWVudCgpLlVwZGF0ZVR0bChcbiAgICAgICAgcmVxdWVzdCxcbiAgICAgICAgbWV0YWRhdGEsXG4gICAgICAgIHtcbiAgICAgICAgICBpbnRlcmNlcHRvcnM6IHRoaXMuaW50ZXJjZXB0b3JzLFxuICAgICAgICB9LFxuICAgICAgICAoZXJyLCByZXNwKSA9PiB7XG4gICAgICAgICAgaWYgKHJlc3A/Lm1pc3NpbmcpIHtcbiAgICAgICAgICAgIHJlc29sdmUobmV3IENhY2hlVXBkYXRlVHRsLk1pc3MoKSk7XG4gICAgICAgICAgfSBlbHNlIGlmIChyZXNwPy5zZXQpIHtcbiAgICAgICAgICAgIHJlc29sdmUobmV3IENhY2hlVXBkYXRlVHRsLlNldCgpKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5jYWNoZVNlcnZpY2VFcnJvck1hcHBlci5yZXNvbHZlT3JSZWplY3RFcnJvcih7XG4gICAgICAgICAgICAgIGVycjogZXJyLFxuICAgICAgICAgICAgICBlcnJvclJlc3BvbnNlRmFjdG9yeUZuOiBlID0+IG5ldyBDYWNoZVVwZGF0ZVR0bC5FcnJvcihlKSxcbiAgICAgICAgICAgICAgcmVzb2x2ZUZuOiByZXNvbHZlLFxuICAgICAgICAgICAgICByZWplY3RGbjogcmVqZWN0LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICApO1xuICAgIH0pO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIGtleXNFeGlzdChcbiAgICBjYWNoZU5hbWU6IHN0cmluZyxcbiAgICBrZXlzOiBzdHJpbmdbXSB8IFVpbnQ4QXJyYXlbXVxuICApOiBQcm9taXNlPENhY2hlS2V5c0V4aXN0LlJlc3BvbnNlPiB7XG4gICAgdHJ5IHtcbiAgICAgIHZhbGlkYXRlQ2FjaGVOYW1lKGNhY2hlTmFtZSk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICByZXR1cm4gdGhpcy5jYWNoZVNlcnZpY2VFcnJvck1hcHBlci5yZXR1cm5PclRocm93RXJyb3IoXG4gICAgICAgIGVyciBhcyBFcnJvcixcbiAgICAgICAgZXJyID0+IG5ldyBDYWNoZUtleXNFeGlzdC5FcnJvcihlcnIpXG4gICAgICApO1xuICAgIH1cblxuICAgIHJldHVybiBhd2FpdCB0aGlzLnJhdGVMaW1pdGVkKGFzeW5jICgpID0+IHtcbiAgICAgIHJldHVybiBhd2FpdCB0aGlzLnNlbmRLZXlzRXhpc3QoY2FjaGVOYW1lLCB0aGlzLmNvbnZlcnRBcnJheShrZXlzKSk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHNlbmRLZXlzRXhpc3QoXG4gICAgY2FjaGVOYW1lOiBzdHJpbmcsXG4gICAga2V5czogVWludDhBcnJheVtdXG4gICk6IFByb21pc2U8Q2FjaGVLZXlzRXhpc3QuUmVzcG9uc2U+IHtcbiAgICBjb25zdCByZXF1ZXN0ID0gbmV3IGdycGNDYWNoZS5fS2V5c0V4aXN0UmVxdWVzdCh7XG4gICAgICBjYWNoZV9rZXlzOiBrZXlzLFxuICAgIH0pO1xuICAgIGNvbnN0IG1ldGFkYXRhID0gdGhpcy5jcmVhdGVNZXRhZGF0YShjYWNoZU5hbWUpO1xuICAgIHJldHVybiBhd2FpdCBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICB0aGlzLmNsaWVudFdyYXBwZXIuZ2V0Q2xpZW50KCkuS2V5c0V4aXN0KFxuICAgICAgICByZXF1ZXN0LFxuICAgICAgICBtZXRhZGF0YSxcbiAgICAgICAge1xuICAgICAgICAgIGludGVyY2VwdG9yczogdGhpcy5pbnRlcmNlcHRvcnMsXG4gICAgICAgIH0sXG4gICAgICAgIChlcnIsIHJlc3ApID0+IHtcbiAgICAgICAgICBpZiAocmVzcCkge1xuICAgICAgICAgICAgcmVzb2x2ZShuZXcgQ2FjaGVLZXlzRXhpc3QuU3VjY2VzcyhrZXlzLCByZXNwLmV4aXN0cykpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmNhY2hlU2VydmljZUVycm9yTWFwcGVyLnJlc29sdmVPclJlamVjdEVycm9yKHtcbiAgICAgICAgICAgICAgZXJyOiBlcnIsXG4gICAgICAgICAgICAgIGVycm9yUmVzcG9uc2VGYWN0b3J5Rm46IGUgPT4gbmV3IENhY2hlS2V5c0V4aXN0LkVycm9yKGUpLFxuICAgICAgICAgICAgICByZXNvbHZlRm46IHJlc29sdmUsXG4gICAgICAgICAgICAgIHJlamVjdEZuOiByZWplY3QsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICk7XG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgaW5jcmVhc2VUdGwoXG4gICAgY2FjaGVOYW1lOiBzdHJpbmcsXG4gICAga2V5OiBzdHJpbmcgfCBVaW50OEFycmF5LFxuICAgIHR0bE1pbGxpc2Vjb25kczogbnVtYmVyXG4gICk6IFByb21pc2U8Q2FjaGVJbmNyZWFzZVR0bC5SZXNwb25zZT4ge1xuICAgIHRyeSB7XG4gICAgICB2YWxpZGF0ZUNhY2hlTmFtZShjYWNoZU5hbWUpO1xuICAgICAgdmFsaWRhdGVWYWxpZEZvclNlY29uZHModHRsTWlsbGlzZWNvbmRzKTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIHJldHVybiB0aGlzLmNhY2hlU2VydmljZUVycm9yTWFwcGVyLnJldHVybk9yVGhyb3dFcnJvcihcbiAgICAgICAgZXJyIGFzIEVycm9yLFxuICAgICAgICBlcnIgPT4gbmV3IENhY2hlSW5jcmVhc2VUdGwuRXJyb3IoZXJyKVxuICAgICAgKTtcbiAgICB9XG5cbiAgICByZXR1cm4gYXdhaXQgdGhpcy5yYXRlTGltaXRlZChhc3luYyAoKSA9PiB7XG4gICAgICByZXR1cm4gYXdhaXQgdGhpcy5zZW5kSW5jcmVhc2VUdGwoXG4gICAgICAgIGNhY2hlTmFtZSxcbiAgICAgICAgdGhpcy5jb252ZXJ0KGtleSksXG4gICAgICAgIHR0bE1pbGxpc2Vjb25kc1xuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgc2VuZEluY3JlYXNlVHRsKFxuICAgIGNhY2hlTmFtZTogc3RyaW5nLFxuICAgIGtleTogVWludDhBcnJheSxcbiAgICB0dGxNaWxsaXNlY29uZHM6IG51bWJlclxuICApOiBQcm9taXNlPENhY2hlSW5jcmVhc2VUdGwuUmVzcG9uc2U+IHtcbiAgICBjb25zdCByZXF1ZXN0ID0gbmV3IGdycGNDYWNoZS5fVXBkYXRlVHRsUmVxdWVzdCh7XG4gICAgICBjYWNoZV9rZXk6IGtleSxcbiAgICAgIGluY3JlYXNlX3RvX21pbGxpc2Vjb25kczogdHRsTWlsbGlzZWNvbmRzLFxuICAgIH0pO1xuICAgIGNvbnN0IG1ldGFkYXRhID0gdGhpcy5jcmVhdGVNZXRhZGF0YShjYWNoZU5hbWUpO1xuICAgIHJldHVybiBhd2FpdCBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICB0aGlzLmNsaWVudFdyYXBwZXIuZ2V0Q2xpZW50KCkuVXBkYXRlVHRsKFxuICAgICAgICByZXF1ZXN0LFxuICAgICAgICBtZXRhZGF0YSxcbiAgICAgICAge1xuICAgICAgICAgIGludGVyY2VwdG9yczogdGhpcy5pbnRlcmNlcHRvcnMsXG4gICAgICAgIH0sXG4gICAgICAgIChlcnIsIHJlc3ApID0+IHtcbiAgICAgICAgICBpZiAocmVzcD8ubWlzc2luZykge1xuICAgICAgICAgICAgcmVzb2x2ZShuZXcgQ2FjaGVJbmNyZWFzZVR0bC5NaXNzKCkpO1xuICAgICAgICAgIH0gZWxzZSBpZiAocmVzcD8ubm90X3NldCkge1xuICAgICAgICAgICAgcmVzb2x2ZShuZXcgQ2FjaGVJbmNyZWFzZVR0bC5Ob3RTZXQoKSk7XG4gICAgICAgICAgfSBlbHNlIGlmIChyZXNwPy5zZXQpIHtcbiAgICAgICAgICAgIHJlc29sdmUobmV3IENhY2hlSW5jcmVhc2VUdGwuU2V0KCkpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmNhY2hlU2VydmljZUVycm9yTWFwcGVyLnJlc29sdmVPclJlamVjdEVycm9yKHtcbiAgICAgICAgICAgICAgZXJyOiBlcnIsXG4gICAgICAgICAgICAgIGVycm9yUmVzcG9uc2VGYWN0b3J5Rm46IGUgPT4gbmV3IENhY2hlSW5jcmVhc2VUdGwuRXJyb3IoZSksXG4gICAgICAgICAgICAgIHJlc29sdmVGbjogcmVzb2x2ZSxcbiAgICAgICAgICAgICAgcmVqZWN0Rm46IHJlamVjdCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBkZWNyZWFzZVR0bChcbiAgICBjYWNoZU5hbWU6IHN0cmluZyxcbiAgICBrZXk6IHN0cmluZyB8IFVpbnQ4QXJyYXksXG4gICAgdHRsTWlsbGlzZWNvbmRzOiBudW1iZXJcbiAgKTogUHJvbWlzZTxDYWNoZURlY3JlYXNlVHRsLlJlc3BvbnNlPiB7XG4gICAgdHJ5IHtcbiAgICAgIHZhbGlkYXRlQ2FjaGVOYW1lKGNhY2hlTmFtZSk7XG4gICAgICB2YWxpZGF0ZVZhbGlkRm9yU2Vjb25kcyh0dGxNaWxsaXNlY29uZHMpO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgcmV0dXJuIHRoaXMuY2FjaGVTZXJ2aWNlRXJyb3JNYXBwZXIucmV0dXJuT3JUaHJvd0Vycm9yKFxuICAgICAgICBlcnIgYXMgRXJyb3IsXG4gICAgICAgIGVyciA9PiBuZXcgQ2FjaGVEZWNyZWFzZVR0bC5FcnJvcihlcnIpXG4gICAgICApO1xuICAgIH1cblxuICAgIHJldHVybiBhd2FpdCB0aGlzLnJhdGVMaW1pdGVkKGFzeW5jICgpID0+IHtcbiAgICAgIHJldHVybiBhd2FpdCB0aGlzLnNlbmREZWNyZWFzZVR0bChcbiAgICAgICAgY2FjaGVOYW1lLFxuICAgICAgICB0aGlzLmNvbnZlcnQoa2V5KSxcbiAgICAgICAgdHRsTWlsbGlzZWNvbmRzXG4gICAgICApO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBzZW5kRGVjcmVhc2VUdGwoXG4gICAgY2FjaGVOYW1lOiBzdHJpbmcsXG4gICAga2V5OiBVaW50OEFycmF5LFxuICAgIHR0bE1pbGxpc2Vjb25kczogbnVtYmVyXG4gICk6IFByb21pc2U8Q2FjaGVEZWNyZWFzZVR0bC5SZXNwb25zZT4ge1xuICAgIGNvbnN0IHJlcXVlc3QgPSBuZXcgZ3JwY0NhY2hlLl9VcGRhdGVUdGxSZXF1ZXN0KHtcbiAgICAgIGNhY2hlX2tleToga2V5LFxuICAgICAgZGVjcmVhc2VfdG9fbWlsbGlzZWNvbmRzOiB0dGxNaWxsaXNlY29uZHMsXG4gICAgfSk7XG4gICAgY29uc3QgbWV0YWRhdGEgPSB0aGlzLmNyZWF0ZU1ldGFkYXRhKGNhY2hlTmFtZSk7XG4gICAgcmV0dXJuIGF3YWl0IG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHRoaXMuY2xpZW50V3JhcHBlci5nZXRDbGllbnQoKS5VcGRhdGVUdGwoXG4gICAgICAgIHJlcXVlc3QsXG4gICAgICAgIG1ldGFkYXRhLFxuICAgICAgICB7XG4gICAgICAgICAgaW50ZXJjZXB0b3JzOiB0aGlzLmludGVyY2VwdG9ycyxcbiAgICAgICAgfSxcbiAgICAgICAgKGVyciwgcmVzcCkgPT4ge1xuICAgICAgICAgIGlmIChyZXNwPy5taXNzaW5nKSB7XG4gICAgICAgICAgICByZXNvbHZlKG5ldyBDYWNoZURlY3JlYXNlVHRsLk1pc3MoKSk7XG4gICAgICAgICAgfSBlbHNlIGlmIChyZXNwPy5ub3Rfc2V0KSB7XG4gICAgICAgICAgICByZXNvbHZlKG5ldyBDYWNoZURlY3JlYXNlVHRsLk5vdFNldCgpKTtcbiAgICAgICAgICB9IGVsc2UgaWYgKHJlc3A/LnNldCkge1xuICAgICAgICAgICAgcmVzb2x2ZShuZXcgQ2FjaGVEZWNyZWFzZVR0bC5TZXQoKSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuY2FjaGVTZXJ2aWNlRXJyb3JNYXBwZXIucmVzb2x2ZU9yUmVqZWN0RXJyb3Ioe1xuICAgICAgICAgICAgICBlcnI6IGVycixcbiAgICAgICAgICAgICAgZXJyb3JSZXNwb25zZUZhY3RvcnlGbjogZSA9PiBuZXcgQ2FjaGVEZWNyZWFzZVR0bC5FcnJvcihlKSxcbiAgICAgICAgICAgICAgcmVzb2x2ZUZuOiByZXNvbHZlLFxuICAgICAgICAgICAgICByZWplY3RGbjogcmVqZWN0LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICApO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBjcmVhdGVNZXRhZGF0YShjYWNoZU5hbWU6IHN0cmluZyk6IE1ldGFkYXRhIHtcbiAgICBjb25zdCBtZXRhZGF0YSA9IG5ldyBNZXRhZGF0YSgpO1xuICAgIG1ldGFkYXRhLnNldCgnY2FjaGUnLCBjYWNoZU5hbWUpO1xuICAgIHJldHVybiBtZXRhZGF0YTtcbiAgfVxuXG4gIHByaXZhdGUgdG9TaW5nbGV0b25GaWVsZFZhbHVlUGFpcihcbiAgICBmaWVsZDogVWludDhBcnJheSxcbiAgICB2YWx1ZTogVWludDhBcnJheVxuICApOiBncnBjQ2FjaGUuX0RpY3Rpb25hcnlGaWVsZFZhbHVlUGFpcltdIHtcbiAgICByZXR1cm4gW1xuICAgICAgbmV3IGdycGNDYWNoZS5fRGljdGlvbmFyeUZpZWxkVmFsdWVQYWlyKHtcbiAgICAgICAgZmllbGQ6IGZpZWxkLFxuICAgICAgICB2YWx1ZTogdmFsdWUsXG4gICAgICB9KSxcbiAgICBdO1xuICB9XG59XG4iXX0=
© 2015 - 2025 Weber Informatics LLC | Privacy Policy