package.dist.src.internal.internal-auth-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.permissionsFromDisposableTokenScope = exports.permissionsFromTokenScope = exports.InternalAuthClient = void 0;
const generated_types_1 = require("@gomomento/generated-types");
var grpcAuth = generated_types_1.auth.auth;
const headers_interceptor_1 = require("./grpc/headers-interceptor");
const grpc_js_1 = require("@grpc/grpc-js");
const package_json_1 = require("../../package.json");
const cache_service_error_mapper_1 = require("../errors/cache-service-error-mapper");
const utils_1 = require("@gomomento/sdk-core/dist/src/internal/utils");
var Never = grpcAuth._GenerateApiTokenRequest.Never;
var Expires = grpcAuth._GenerateApiTokenRequest.Expires;
const sdk_core_1 = require("@gomomento/sdk-core");
const permission_scope_1 = require("@gomomento/sdk-core/dist/src/auth/tokens/permission-scope");
const permissionmessages_1 = require("@gomomento/generated-types/dist/permissionmessages");
const utils_2 = require("./utils");
const disposable_token_scope_1 = require("@gomomento/sdk-core/dist/src/auth/tokens/disposable-token-scope");
const retry_interceptor_1 = require("./grpc/retry-interceptor");
const index_1 = require("../index");
const utils_3 = require("@gomomento/sdk-core/dist/src/utils");
class InternalAuthClient {
constructor(props) {
var _a, _b;
const configuration = (_a = props.configuration) !== null && _a !== void 0 ? _a : index_1.AuthClientConfigurations.Default.latest();
this.cacheServiceErrorMapper = new cache_service_error_mapper_1.CacheServiceErrorMapper((_b = props.throwOnErrors) !== null && _b !== void 0 ? _b : false);
this.creds = props.credentialProvider;
const headers = [
new headers_interceptor_1.Header('agent', `nodejs:auth:${package_json_1.version}`),
new headers_interceptor_1.Header('runtime-version', `nodejs:${process.versions.node}`),
];
this.interceptors = [
headers_interceptor_1.HeaderInterceptor.createHeadersInterceptor(headers),
retry_interceptor_1.RetryInterceptor.createRetryInterceptor({
clientName: 'AuthClient',
loggerFactory: configuration.getLoggerFactory(),
overallRequestTimeoutMs: InternalAuthClient.REQUEST_TIMEOUT_MS,
}),
];
this.tokenClient = new generated_types_1.token.token.TokenClient(this.creds.getTokenEndpoint(), this.creds.isTokenEndpointSecure()
? grpc_js_1.ChannelCredentials.createSsl()
: grpc_js_1.ChannelCredentials.createInsecure());
this.authClient = new grpcAuth.AuthClient(this.creds.getControlEndpoint(), this.creds.isTokenEndpointSecure()
? grpc_js_1.ChannelCredentials.createSsl()
: grpc_js_1.ChannelCredentials.createInsecure());
}
async generateApiKey(scope, expiresIn) {
let permissions;
try {
permissions = permissionsFromTokenScope(scope);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new sdk_core_1.GenerateApiKey.Error(err));
}
const request = new grpcAuth._GenerateApiTokenRequest({
auth_token: this.creds.getAuthToken(),
permissions: permissions,
});
if (expiresIn.doesExpire()) {
try {
(0, utils_1.validateValidForSeconds)(expiresIn.seconds());
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new sdk_core_1.GenerateApiKey.Error(err));
}
request.expires = new Expires({
valid_for_seconds: expiresIn.seconds(),
});
}
else {
request.never = new Never();
}
return await new Promise((resolve, reject) => {
this.authClient.GenerateApiToken(request, { interceptors: this.interceptors }, (err, resp) => {
if (err || !resp) {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new sdk_core_1.GenerateApiKey.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
else {
resolve(new sdk_core_1.GenerateApiKey.Success(resp.api_key, resp.refresh_token, resp.endpoint, sdk_core_1.ExpiresAt.fromEpoch(resp.valid_until)));
}
});
});
}
/**
* @deprecated please use `generateApiKey` instead
*/
generateAuthToken(scope, expiresIn) {
return this.generateApiKey(scope, expiresIn);
}
async refreshApiKey(refreshToken) {
const request = new grpcAuth._RefreshApiTokenRequest({
api_key: this.creds.getAuthToken(),
refresh_token: refreshToken,
});
return await new Promise((resolve, reject) => {
this.authClient.RefreshApiToken(request, { interceptors: this.interceptors }, (err, resp) => {
if (err || !resp) {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new sdk_core_1.RefreshApiKey.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
else {
resolve(new sdk_core_1.RefreshApiKey.Success(resp.api_key, resp.refresh_token, resp.endpoint, sdk_core_1.ExpiresAt.fromEpoch(resp.valid_until)));
}
});
});
}
/**
* @deprecated please use `refreshApiKey` instead
*/
refreshAuthToken(refreshToken) {
return this.refreshApiKey(refreshToken);
}
async generateDisposableToken(scope, expiresIn, disposableTokenProps) {
try {
(0, utils_1.validateDisposableTokenExpiry)(expiresIn);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new sdk_core_1.GenerateDisposableToken.Error(err));
}
const expires = new generated_types_1.token.token._GenerateDisposableTokenRequest.Expires({
valid_for_seconds: expiresIn.seconds(),
});
let permissions;
try {
permissions = permissionsFromDisposableTokenScope(scope);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new sdk_core_1.GenerateDisposableToken.Error(err));
}
const tokenId = disposableTokenProps === null || disposableTokenProps === void 0 ? void 0 : disposableTokenProps.tokenId;
if (tokenId !== undefined) {
try {
(0, utils_1.validateDisposableTokenTokenID)(tokenId);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new sdk_core_1.GenerateDisposableToken.Error(err));
}
}
const request = new generated_types_1.token.token._GenerateDisposableTokenRequest({
expires: expires,
auth_token: this.creds.getAuthToken(),
permissions: permissions,
token_id: tokenId,
});
return await new Promise((resolve, reject) => {
this.tokenClient.GenerateDisposableToken(request, { interceptors: this.interceptors }, (err, resp) => {
if (err || !resp) {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new sdk_core_1.GenerateDisposableToken.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
else {
resolve(new sdk_core_1.GenerateDisposableToken.Success(resp.api_key, resp.endpoint, sdk_core_1.ExpiresAt.fromEpoch(resp.valid_until)));
}
});
});
}
}
exports.InternalAuthClient = InternalAuthClient;
InternalAuthClient.REQUEST_TIMEOUT_MS = (0, utils_3.secondsToMilliseconds)(60);
function permissionsFromTokenScope(scope) {
const result = new permissionmessages_1.permission_messages.Permissions();
if (scope instanceof utils_1.InternalSuperUserPermissions) {
result.super_user = permissionmessages_1.permission_messages.SuperUserPermissions.SuperUser;
return result;
}
else if ((0, permission_scope_1.isPermissionsObject)(scope)) {
const scopePermissions = (0, permission_scope_1.asPermissionsObject)(scope);
const explicitPermissions = new permissionmessages_1.permission_messages.ExplicitPermissions();
explicitPermissions.permissions = scopePermissions.permissions.map(p => tokenPermissionToGrpcPermission(p));
result.explicit = explicitPermissions;
return result;
}
throw new Error(`Unrecognized token scope: ${JSON.stringify(scope)}`);
}
exports.permissionsFromTokenScope = permissionsFromTokenScope;
function permissionsFromDisposableTokenScope(scope) {
const result = new permissionmessages_1.permission_messages.Permissions();
if (!(scope instanceof permission_scope_1.PredefinedScope) &&
(0, disposable_token_scope_1.isDisposableTokenPermissionsObject)(scope)) {
const scopePermissions = (0, disposable_token_scope_1.asDisposableTokenPermissionsObject)(scope);
const explicitPermissions = new permissionmessages_1.permission_messages.ExplicitPermissions();
explicitPermissions.permissions = scopePermissions.permissions.map(p => disposableTokenPermissionToGrpcPermission(p));
result.explicit = explicitPermissions;
return result;
}
else if ((0, permission_scope_1.isPermissionsObject)(scope)) {
const scopePermissions = (0, permission_scope_1.asPermissionsObject)(scope);
const explicitPermissions = new permissionmessages_1.permission_messages.ExplicitPermissions();
explicitPermissions.permissions = scopePermissions.permissions.map(p => tokenPermissionToGrpcPermission(p));
result.explicit = explicitPermissions;
return result;
}
throw new Error(`Unrecognized token scope: ${JSON.stringify(scope)}`);
}
exports.permissionsFromDisposableTokenScope = permissionsFromDisposableTokenScope;
function tokenPermissionToGrpcPermission(permission) {
const result = new permissionmessages_1.permission_messages.PermissionsType();
if ((0, permission_scope_1.isTopicPermission)(permission)) {
result.topic_permissions = topicPermissionToGrpcPermission((0, permission_scope_1.asTopicPermission)(permission));
return result;
}
else if ((0, permission_scope_1.isCachePermission)(permission)) {
result.cache_permissions = cachePermissionToGrpcPermission((0, permission_scope_1.asCachePermission)(permission));
return result;
}
throw new Error(`Unrecognized token permission: ${JSON.stringify(permission)}`);
}
function topicPermissionToGrpcPermission(permission) {
const grpcPermission = new permissionmessages_1.permission_messages.PermissionsType.TopicPermissions();
switch (permission.role) {
case sdk_core_1.TopicRole.PublishSubscribe: {
grpcPermission.role = permissionmessages_1.permission_messages.TopicRole.TopicReadWrite;
break;
}
case sdk_core_1.TopicRole.SubscribeOnly: {
grpcPermission.role = permissionmessages_1.permission_messages.TopicRole.TopicReadOnly;
break;
}
case sdk_core_1.TopicRole.PublishOnly: {
grpcPermission.role = permissionmessages_1.permission_messages.TopicRole.TopicWriteOnly;
break;
}
default: {
throw new Error(`Unrecognized topic role: ${JSON.stringify(permission)}`);
}
}
if (permission.cache === sdk_core_1.AllCaches) {
grpcPermission.all_caches = new permissionmessages_1.permission_messages.PermissionsType.All();
}
else if (typeof permission.cache === 'string') {
grpcPermission.cache_selector =
new permissionmessages_1.permission_messages.PermissionsType.CacheSelector({
cache_name: permission.cache,
});
}
else if ((0, sdk_core_1.isCacheName)(permission.cache)) {
grpcPermission.cache_selector =
new permissionmessages_1.permission_messages.PermissionsType.CacheSelector({
cache_name: permission.cache.name,
});
}
else {
throw new Error(`Unrecognized cache specification in topic permission: ${JSON.stringify(permission)}`);
}
if (permission.topic === sdk_core_1.AllTopics) {
grpcPermission.all_topics = new permissionmessages_1.permission_messages.PermissionsType.All();
}
else if (typeof permission.topic === 'string') {
grpcPermission.topic_selector =
new permissionmessages_1.permission_messages.PermissionsType.TopicSelector({
topic_name: permission.topic,
});
}
else if ((0, sdk_core_1.isTopicName)(permission.topic)) {
grpcPermission.topic_selector =
new permissionmessages_1.permission_messages.PermissionsType.TopicSelector({
topic_name: permission.topic.name,
});
}
else {
throw new Error(`Unrecognized topic specification in topic permission: ${JSON.stringify(permission)}`);
}
return grpcPermission;
}
function assignCacheRole(permission, grpcPermission) {
switch (permission.role) {
case sdk_core_1.CacheRole.ReadWrite: {
grpcPermission.role = permissionmessages_1.permission_messages.CacheRole.CacheReadWrite;
break;
}
case sdk_core_1.CacheRole.ReadOnly: {
grpcPermission.role = permissionmessages_1.permission_messages.CacheRole.CacheReadOnly;
break;
}
case sdk_core_1.CacheRole.WriteOnly: {
grpcPermission.role = permissionmessages_1.permission_messages.CacheRole.CacheWriteOnly;
break;
}
default: {
throw new Error(`Unrecognized cache role: ${JSON.stringify(permission)}`);
}
}
return grpcPermission;
}
function assignCacheSelector(permission, grpcPermission) {
if (permission.cache === sdk_core_1.AllCaches) {
grpcPermission.all_caches = new permissionmessages_1.permission_messages.PermissionsType.All();
}
else if (typeof permission.cache === 'string') {
grpcPermission.cache_selector =
new permissionmessages_1.permission_messages.PermissionsType.CacheSelector({
cache_name: permission.cache,
});
}
else if ((0, sdk_core_1.isCacheName)(permission.cache)) {
grpcPermission.cache_selector =
new permissionmessages_1.permission_messages.PermissionsType.CacheSelector({
cache_name: permission.cache.name,
});
}
else {
throw new Error(`Unrecognized cache specification in cache permission: ${JSON.stringify(permission)}`);
}
return grpcPermission;
}
function assignCacheItemSelector(permission, grpcPermission) {
if (permission.item === sdk_core_1.AllCacheItems) {
grpcPermission.all_items = new permissionmessages_1.permission_messages.PermissionsType.All();
}
else if (typeof permission.item === 'string') {
grpcPermission.item_selector =
new permissionmessages_1.permission_messages.PermissionsType.CacheItemSelector({
key: (0, utils_2.convert)(permission.item),
});
}
else if ((0, sdk_core_1.isCacheItemKey)(permission.item)) {
(0, utils_1.validateCacheKeyOrPrefix)(permission.item.key);
grpcPermission.item_selector =
new permissionmessages_1.permission_messages.PermissionsType.CacheItemSelector({
key: (0, utils_2.convert)(permission.item.key),
});
}
else if ((0, sdk_core_1.isCacheItemKeyPrefix)(permission.item)) {
(0, utils_1.validateCacheKeyOrPrefix)(permission.item.keyPrefix);
grpcPermission.item_selector =
new permissionmessages_1.permission_messages.PermissionsType.CacheItemSelector({
key_prefix: (0, utils_2.convert)(permission.item.keyPrefix),
});
}
else {
throw new Error(`Unrecognized cache item specification in cache permission: ${JSON.stringify(permission)}`);
}
return grpcPermission;
}
function cachePermissionToGrpcPermission(permission) {
let grpcPermission = new permissionmessages_1.permission_messages.PermissionsType.CachePermissions();
grpcPermission = assignCacheRole(permission, grpcPermission);
grpcPermission = assignCacheSelector(permission, grpcPermission);
return grpcPermission;
}
function disposableTokenPermissionToGrpcPermission(permission) {
const result = new permissionmessages_1.permission_messages.PermissionsType();
if ((0, disposable_token_scope_1.isDisposableTokenCachePermission)(permission)) {
result.cache_permissions = disposableCachePermissionToGrpcPermission((0, disposable_token_scope_1.asDisposableTokenCachePermission)(permission));
return result;
}
throw new Error(`Unrecognized token permission: ${JSON.stringify(permission)}`);
}
function disposableCachePermissionToGrpcPermission(permission) {
let grpcPermission = new permissionmessages_1.permission_messages.PermissionsType.CachePermissions();
grpcPermission = assignCacheRole(permission, grpcPermission);
grpcPermission = assignCacheSelector(permission, grpcPermission);
grpcPermission = assignCacheItemSelector(permission, grpcPermission);
return grpcPermission;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW50ZXJuYWwtYXV0aC1jbGllbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvaW50ZXJuYWwvaW50ZXJuYWwtYXV0aC1jbGllbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsZ0VBQXVEO0FBQ3ZELElBQU8sUUFBUSxHQUFHLHNCQUFJLENBQUMsSUFBSSxDQUFDO0FBQzVCLG9FQUFxRTtBQUNyRSwyQ0FBOEQ7QUFDOUQscURBQTJDO0FBQzNDLHFGQUE2RTtBQUM3RSx1RUFNcUQ7QUFDckQsSUFBTyxLQUFLLEdBQUcsUUFBUSxDQUFDLHdCQUF3QixDQUFDLEtBQUssQ0FBQztBQUN2RCxJQUFPLE9BQU8sR0FBRyxRQUFRLENBQUMsd0JBQXdCLENBQUMsT0FBTyxDQUFDO0FBQzNELGtEQXNCNkI7QUFFN0IsZ0dBUW1FO0FBQ25FLDJGQUF1RjtBQUN2RixtQ0FBZ0M7QUFDaEMsNEdBT3lFO0FBQ3pFLGdFQUEwRDtBQUMxRCxvQ0FBa0Q7QUFFbEQsOERBQXlFO0FBRXpFLE1BQWEsa0JBQWtCO0lBVTdCLFlBQVksS0FBeUI7O1FBQ25DLE1BQU0sYUFBYSxHQUNqQixNQUFBLEtBQUssQ0FBQyxhQUFhLG1DQUFJLGdDQUF3QixDQUFDLE9BQU8sQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUNuRSxJQUFJLENBQUMsdUJBQXVCLEdBQUcsSUFBSSxvREFBdUIsQ0FDeEQsTUFBQSxLQUFLLENBQUMsYUFBYSxtQ0FBSSxLQUFLLENBQzdCLENBQUM7UUFDRixJQUFJLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQztRQUN0QyxNQUFNLE9BQU8sR0FBRztZQUNkLElBQUksNEJBQU0sQ0FBQyxPQUFPLEVBQUUsZUFBZSxzQkFBTyxFQUFFLENBQUM7WUFDN0MsSUFBSSw0QkFBTSxDQUFDLGlCQUFpQixFQUFFLFVBQVUsT0FBTyxDQUFDLFFBQVEsQ0FBQyxJQUFJLEVBQUUsQ0FBQztTQUNqRSxDQUFDO1FBQ0YsSUFB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SUFDN0QsY0FBYyxHQUFHLGVBQWUsQ0FBQyxVQUFVLEVBQUUsY0FBYyxDQUFDLENBQUM7SUFDN0QsY0FBYyxHQUFHLG1CQUFtQixDQUFDLFVBQVUsRUFBRSxjQUFjLENBQUMsQ0FBQztJQUNqRSxPQUFPLGNBQWMsQ0FBQztBQUN4QixDQUFDO0FBRUQsU0FBUyx5Q0FBeUMsQ0FDaEQsVUFBMEM7SUFFMUMsTUFBTSxNQUFNLEdBQUcsSUFBSSx3Q0FBbUIsQ0FBQyxlQUFlLEVBQUUsQ0FBQztJQUN6RCxJQUFJLElBQUEseURBQWdDLEVBQUMsVUFBVSxDQUFDLEVBQUU7UUFDaEQsTUFBTSxDQUFDLGlCQUFpQixHQUFHLHlDQUF5QyxDQUNsRSxJQUFBLHlEQUFnQyxFQUFDLFVBQVUsQ0FBQyxDQUM3QyxDQUFDO1FBQ0YsT0FBTyxNQUFNLENBQUM7S0FDZjtJQUNELE1BQU0sSUFBSSxLQUFLLENBQ2Isa0NBQWtDLElBQUksQ0FBQyxTQUFTLENBQUMsVUFBVSxDQUFDLEVBQUUsQ0FDL0QsQ0FBQztBQUNKLENBQUM7QUFFRCxTQUFTLHlDQUF5QyxDQUNoRCxVQUEwQztJQUUxQyxJQUFJLGNBQWMsR0FDaEIsSUFBSSx3Q0FBbUIsQ0FBQyxlQUFlLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztJQUM3RCxjQUFjLEdBQUcsZUFBZSxDQUFDLFVBQVUsRUFBRSxjQUFjLENBQUMsQ0FBQztJQUM3RCxjQUFjLEdBQUcsbUJBQW1CLENBQUMsVUFBVSxFQUFFLGNBQWMsQ0FBQyxDQUFDO0lBQ2pFLGNBQWMsR0FBRyx1QkFBdUIsQ0FBQyxVQUFVLEVBQUUsY0FBYyxDQUFDLENBQUM7SUFFckUsT0FBTyxjQUFjLENBQUM7QUFDeEIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7YXV0aCwgdG9rZW59IGZyb20gJ0Bnb21vbWVudG8vZ2VuZXJhdGVkLXR5cGVzJztcbmltcG9ydCBncnBjQXV0aCA9IGF1dGguYXV0aDtcbmltcG9ydCB7SGVhZGVyLCBIZWFkZXJJbnRlcmNlcHRvcn0gZnJvbSAnLi9ncnBjL2hlYWRlcnMtaW50ZXJjZXB0b3InO1xuaW1wb3J0IHtDaGFubmVsQ3JlZGVudGlhbHMsIEludGVyY2VwdG9yfSBmcm9tICdAZ3JwYy9ncnBjLWpzJztcbmltcG9ydCB7dmVyc2lvbn0gZnJvbSAnLi4vLi4vcGFja2FnZS5qc29uJztcbmltcG9ydCB7Q2FjaGVTZXJ2aWNlRXJyb3JNYXBwZXJ9IGZyb20gJy4uL2Vycm9ycy9jYWNoZS1zZXJ2aWNlLWVycm9yLW1hcHBlcic7XG5pbXBvcnQge1xuICBJbnRlcm5hbFN1cGVyVXNlclBlcm1pc3Npb25zLFxuICB2YWxpZGF0ZURpc3Bvc2FibGVUb2tlbkV4cGlyeSxcbiAgdmFsaWRhdGVWYWxpZEZvclNlY29uZHMsXG4gIHZhbGlkYXRlQ2FjaGVLZXlPclByZWZpeCxcbiAgdmFsaWRhdGVEaXNwb3NhYmxlVG9rZW5Ub2tlbklELFxufSBmcm9tICdAZ29tb21lbnRvL3Nkay1jb3JlL2Rpc3Qvc3JjL2ludGVybmFsL3V0aWxzJztcbmltcG9ydCBOZXZlciA9IGdycGNBdXRoLl9HZW5lcmF0ZUFwaVRva2VuUmVxdWVzdC5OZXZlcjtcbmltcG9ydCBFeHBpcmVzID0gZ3JwY0F1dGguX0dlbmVyYXRlQXBpVG9rZW5SZXF1ZXN0LkV4cGlyZXM7XG5pbXBvcnQge1xuICBFeHBpcmVzSW4sXG4gIEV4cGlyZXNBdCxcbiAgQ3JlZGVudGlhbFByb3ZpZGVyLFxuICBSZWZyZXNoQXBpS2V5LFxuICBHZW5lcmF0ZUFwaUtleSxcbiAgUGVybWlzc2lvblNjb3BlLFxuICBQZXJtaXNzaW9ucyxcbiAgUGVybWlzc2lvbixcbiAgVG9waWNQZXJtaXNzaW9uLFxuICBDYWNoZVBlcm1pc3Npb24sXG4gIFRvcGljUm9sZSxcbiAgQ2FjaGVSb2xlLFxuICBBbGxDYWNoZXMsXG4gIEFsbFRvcGljcyxcbiAgaXNDYWNoZU5hbWUsXG4gIGlzVG9waWNOYW1lLFxuICBHZW5lcmF0ZURpc3Bvc2FibGVUb2tlbixcbiAgQWxsQ2FjaGVJdGVtcyxcbiAgaXNDYWNoZUl0ZW1LZXksXG4gIGlzQ2FjaGVJdGVtS2V5UHJlZml4LFxuICBEaXNwb3NhYmxlVG9rZW5TY29wZSxcbn0gZnJvbSAnQGdvbW9tZW50by9zZGstY29yZSc7XG5pbXBvcnQge0lBdXRoQ2xpZW50fSBmcm9tICdAZ29tb21lbnRvL3Nkay1jb3JlL2Rpc3Qvc3JjL2ludGVybmFsL2NsaWVudHMnO1xuaW1wb3J0IHtcbiAgYXNDYWNoZVBlcm1pc3Npb24sXG4gIGFzUGVybWlzc2lvbnNPYmplY3QsXG4gIGFzVG9waWNQZXJtaXNzaW9uLFxuICBpc0NhY2hlUGVybWlzc2lvbixcbiAgaXNQZXJtaXNzaW9uc09iamVjdCxcbiAgaXNUb3BpY1Blcm1pc3Npb24sXG4gIFByZWRlZmluZWRTY29wZSxcbn0gZnJvbSAnQGdvbW9tZW50by9zZGstY29yZS9kaXN0L3NyYy9hdXRoL3Rva2Vucy9wZXJtaXNzaW9uLXNjb3BlJztcbmltcG9ydCB7cGVybWlzc2lvbl9tZXNzYWdlc30gZnJvbSAnQGdvbW9tZW50by9nZW5lcmF0ZWQtdHlwZXMvZGlzdC9wZXJtaXNzaW9ubWVzc2FnZXMnO1xuaW1wb3J0IHtjb252ZXJ0fSBmcm9tICcuL3V0aWxzJztcbmltcG9ydCB7XG4gIGFzRGlzcG9zYWJsZVRva2VuQ2FjaGVQZXJtaXNzaW9uLFxuICBhc0Rpc3Bvc2FibGVUb2tlblBlcm1pc3Npb25zT2JqZWN0LFxuICBEaXNwb3NhYmxlVG9rZW5DYWNoZVBlcm1pc3Npb24sXG4gIERpc3Bvc2FibGVUb2tlblByb3BzLFxuICBpc0Rpc3Bvc2FibGVUb2tlbkNhY2hlUGVybWlzc2lvbixcbiAgaXNEaXNwb3NhYmxlVG9rZW5QZXJtaXNzaW9uc09iamVjdCxcbn0gZnJvbSAnQGdvbW9tZW50by9zZGstY29yZS9kaXN0L3NyYy9hdXRoL3Rva2Vucy9kaXNwb3NhYmxlLXRva2VuLXNjb3BlJztcbmltcG9ydCB7UmV0cnlJbnRlcmNlcHRvcn0gZnJvbSAnLi9ncnBjL3JldHJ5LWludGVyY2VwdG9yJztcbmltcG9ydCB7QXV0aENsaWVudENvbmZpZ3VyYXRpb25zfSBmcm9tICcuLi9pbmRleCc7XG5pbXBvcnQge0F1dGhDbGllbnRBbGxQcm9wc30gZnJvbSAnLi9hdXRoLWNsaWVudC1hbGwtcHJvcHMnO1xuaW1wb3J0IHtzZWNvbmRzVG9NaWxsaXNlY29uZHN9IGZyb20gJ0Bnb21vbWVudG8vc2RrLWNvcmUvZGlzdC9zcmMvdXRpbHMnO1xuXG5leHBvcnQgY2xhc3MgSW50ZXJuYWxBdXRoQ2xpZW50IGltcGxlbWVudHMgSUF1dGhDbGllbnQge1xuICBwcml2YXRlIHN0YXRpYyByZWFkb25seSBSRVFVRVNUX1RJTUVPVVRfTVM6IG51bWJlciA9XG4gICAgc2Vjb25kc1RvTWlsbGlzZWNvbmRzKDYwKTtcblxuICBwcml2YXRlIHJlYWRvbmx5IGNhY2hlU2VydmljZUVycm9yTWFwcGVyOiBDYWNoZVNlcnZpY2VFcnJvck1hcHBlcjtcbiAgcHJpdmF0ZSByZWFkb25seSBjcmVkczogQ3JlZGVudGlhbFByb3ZpZGVyO1xuICBwcml2YXRlIHJlYWRvbmx5IGludGVyY2VwdG9yczogSW50ZXJjZXB0b3JbXTtcbiAgcHJpdmF0ZSByZWFkb25seSB0b2tlbkNsaWVudDogdG9rZW4udG9rZW4uVG9rZW5DbGllbnQ7XG4gIHByaXZhdGUgcmVhZG9ubHkgYXV0aENsaWVudDogZ3JwY0F1dGguQXV0aENsaWVudDtcblxuICBjb25zdHJ1Y3Rvcihwcm9wczogQXV0aENsaWVudEFsbFByb3BzKSB7XG4gICAgY29uc3QgY29uZmlndXJhdGlvbiA9XG4gICAgICBwcm9wcy5jb25maWd1cmF0aW9uID8/IEF1dGhDbGllbnRDb25maWd1cmF0aW9ucy5EZWZhdWx0LmxhdGVzdCgpO1xuICAgIHRoaXMuY2FjaGVTZXJ2aWNlRXJyb3JNYXBwZXIgPSBuZXcgQ2FjaGVTZXJ2aWNlRXJyb3JNYXBwZXIoXG4gICAgICBwcm9wcy50aHJvd09uRXJyb3JzID8/IGZhbHNlXG4gICAgKTtcbiAgICB0aGlzLmNyZWRzID0gcHJvcHMuY3JlZGVudGlhbFByb3ZpZGVyO1xuICAgIGNvbnN0IGhlYWRlcnMgPSBbXG4gICAgICBuZXcgSGVhZGVyKCdhZ2VudCcsIGBub2RlanM6YXV0aDoke3ZlcnNpb259YCksXG4gICAgICBuZXcgSGVhZGVyKCdydW50aW1lLXZlcnNpb24nLCBgbm9kZWpzOiR7cHJvY2Vzcy52ZXJzaW9ucy5ub2RlfWApLFxuICAgIF07XG4gICAgdGhpcy5pbnRlcmNlcHRvcnMgPSBbXG4gICAgICBIZWFkZXJJbnRlcmNlcHRvci5jcmVhdGVIZWFkZXJzSW50ZXJjZXB0b3IoaGVhZGVycyksXG4gICAgICBSZXRyeUludGVyY2VwdG9yLmNyZWF0ZVJldHJ5SW50ZXJjZXB0b3Ioe1xuICAgICAgICBjbGllbnROYW1lOiAnQXV0aENsaWVudCcsXG4gICAgICAgIGxvZ2dlckZhY3Rvcnk6IGNvbmZpZ3VyYXRpb24uZ2V0TG9nZ2VyRmFjdG9yeSgpLFxuICAgICAgICBvdmVyYWxsUmVxdWVzdFRpbWVvdXRNczogSW50ZXJuYWxBdXRoQ2xpZW50LlJFUVVFU1RfVElNRU9VVF9NUyxcbiAgICAgIH0pLFxuICAgIF07XG4gICAgdGhpcy50b2tlbkNsaWVudCA9IG5ldyB0b2tlbi50b2tlbi5Ub2tlbkNsaWVudChcbiAgICAgIHRoaXMuY3JlZHMuZ2V0VG9rZW5FbmRwb2ludCgpLFxuICAgICAgdGhpcy5jcmVkcy5pc1Rva2VuRW5kcG9pbnRTZWN1cmUoKVxuICAgICAgICA/IENoYW5uZWxDcmVkZW50aWFscy5jcmVhdGVTc2woKVxuICAgICAgICA6IENoYW5uZWxDcmVkZW50aWFscy5jcmVhdGVJbnNlY3VyZSgpXG4gICAgKTtcbiAgICB0aGlzLmF1dGhDbGllbnQgPSBuZXcgZ3JwY0F1dGguQXV0aENsaWVudChcbiAgICAgIHRoaXMuY3JlZHMuZ2V0Q29udHJvbEVuZHBvaW50KCksXG4gICAgICB0aGlzLmNyZWRzLmlzVG9rZW5FbmRwb2ludFNlY3VyZSgpXG4gICAgICAgID8gQ2hhbm5lbENyZWRlbnRpYWxzLmNyZWF0ZVNzbCgpXG4gICAgICAgIDogQ2hhbm5lbENyZWRlbnRpYWxzLmNyZWF0ZUluc2VjdXJlKClcbiAgICApO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIGdlbmVyYXRlQXBpS2V5KFxuICAgIHNjb3BlOiBQZXJtaXNzaW9uU2NvcGUsXG4gICAgZXhwaXJlc0luOiBFeHBpcmVzSW5cbiAgKTogUHJvbWlzZTxHZW5lcmF0ZUFwaUtleS5SZXNwb25zZT4ge1xuICAgIGxldCBwZXJtaXNzaW9ucztcbiAgICB0cnkge1xuICAgICAgcGVybWlzc2lvbnMgPSBwZXJtaXNzaW9uc0Zyb21Ub2tlblNjb3BlKHNjb3BlKTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIHJldHVybiB0aGlzLmNhY2hlU2VydmljZUVycm9yTWFwcGVyLnJldHVybk9yVGhyb3dFcnJvcihcbiAgICAgICAgZXJyIGFzIEVycm9yLFxuICAgICAgICBlcnIgPT4gbmV3IEdlbmVyYXRlQXBpS2V5LkVycm9yKGVycilcbiAgICAgICk7XG4gICAgfVxuICAgIGNvbnN0IHJlcXVlc3QgPSBuZXcgZ3JwY0F1dGguX0dlbmVyYXRlQXBpVG9rZW5SZXF1ZXN0KHtcbiAgICAgIGF1dGhfdG9rZW46IHRoaXMuY3JlZHMuZ2V0QXV0aFRva2VuKCksXG4gICAgICBwZXJtaXNzaW9uczogcGVybWlzc2lvbnMsXG4gICAgfSk7XG5cbiAgICBpZiAoZXhwaXJlc0luLmRvZXNFeHBpcmUoKSkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgdmFsaWRhdGVWYWxpZEZvclNlY29uZHMoZXhwaXJlc0luLnNlY29uZHMoKSk7XG4gICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY2FjaGVTZXJ2aWNlRXJyb3JNYXBwZXIucmV0dXJuT3JUaHJvd0Vycm9yKFxuICAgICAgICAgIGVyciBhcyBFcnJvcixcbiAgICAgICAgICBlcnIgPT4gbmV3IEdlbmVyYXRlQXBpS2V5LkVycm9yKGVycilcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgcmVxdWVzdC5leHBpcmVzID0gbmV3IEV4cGlyZXMoe1xuICAgICAgICB2YWxpZF9mb3Jfc2Vjb25kczogZXhwaXJlc0luLnNlY29uZHMoKSxcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXF1ZXN0Lm5ldmVyID0gbmV3IE5ldmVyKCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGF3YWl0IG5ldyBQcm9taXNlPEdlbmVyYXRlQXBpS2V5LlJlc3BvbnNlPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICB0aGlzLmF1dGhDbGllbnQuR2VuZXJhdGVBcGlUb2tlbihcbiAgICAgICAgcmVxdWVzdCxcbiAgICAgICAge2ludGVyY2VwdG9yczogdGhpcy5pbnRlcmNlcHRvcnN9LFxuICAgICAgICAoZXJyLCByZXNwKSA9PiB7XG4gICAgICAgICAgaWYgKGVyciB8fCAhcmVzcCkge1xuICAgICAgICAgICAgdGhpcy5jYWNoZVNlcnZpY2VFcnJvck1hcHBlci5yZXNvbHZlT3JSZWplY3RFcnJvcih7XG4gICAgICAgICAgICAgIGVycjogZXJyLFxuICAgICAgICAgICAgICBlcnJvclJlc3BvbnNlRmFjdG9yeUZuOiBlID0+IG5ldyBHZW5lcmF0ZUFwaUtleS5FcnJvcihlKSxcbiAgICAgICAgICAgICAgcmVzb2x2ZUZuOiByZXNvbHZlLFxuICAgICAgICAgICAgICByZWplY3RGbjogcmVqZWN0LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJlc29sdmUoXG4gICAgICAgICAgICAgIG5ldyBHZW5lcmF0ZUFwaUtleS5TdWNjZXNzKFxuICAgICAgICAgICAgICAgIHJlc3AuYXBpX2tleSxcbiAgICAgICAgICAgICAgICByZXNwLnJlZnJlc2hfdG9rZW4sXG4gICAgICAgICAgICAgICAgcmVzcC5lbmRwb2ludCxcbiAgICAgICAgICAgICAgICBFeHBpcmVzQXQuZnJvbUVwb2NoKHJlc3AudmFsaWRfdW50aWwpXG4gICAgICAgICAgICAgIClcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICApO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXByZWNhdGVkIHBsZWFzZSB1c2UgYGdlbmVyYXRlQXBpS2V5YCBpbnN0ZWFkXG4gICAqL1xuICBwdWJsaWMgZ2VuZXJhdGVBdXRoVG9rZW4oXG4gICAgc2NvcGU6IFBlcm1pc3Npb25TY29wZSxcbiAgICBleHBpcmVzSW46IEV4cGlyZXNJblxuICApOiBQcm9taXNlPEdlbmVyYXRlQXBpS2V5LlJlc3BvbnNlPiB7XG4gICAgcmV0dXJuIHRoaXMuZ2VuZXJhdGVBcGlLZXkoc2NvcGUsIGV4cGlyZXNJbik7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgcmVmcmVzaEFwaUtleShcbiAgICByZWZyZXNoVG9rZW46IHN0cmluZ1xuICApOiBQcm9taXNlPFJlZnJlc2hBcGlLZXkuUmVzcG9uc2U+IHtcbiAgICBjb25zdCByZXF1ZXN0ID0gbmV3IGdycGNBdXRoLl9SZWZyZXNoQXBpVG9rZW5SZXF1ZXN0KHtcbiAgICAgIGFwaV9rZXk6IHRoaXMuY3JlZHMuZ2V0QXV0aFRva2VuKCksXG4gICAgICByZWZyZXNoX3Rva2VuOiByZWZyZXNoVG9rZW4sXG4gICAgfSk7XG5cbiAgICByZXR1cm4gYXdhaXQgbmV3IFByb21pc2U8UmVmcmVzaEFwaUtleS5SZXNwb25zZT4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgdGhpcy5hdXRoQ2xpZW50LlJlZnJlc2hBcGlUb2tlbihcbiAgICAgICAgcmVxdWVzdCxcbiAgICAgICAge2ludGVyY2VwdG9yczogdGhpcy5pbnRlcmNlcHRvcnN9LFxuICAgICAgICAoZXJyLCByZXNwKSA9PiB7XG4gICAgICAgICAgaWYgKGVyciB8fCAhcmVzcCkge1xuICAgICAgICAgICAgdGhpcy5jYWNoZVNlcnZpY2VFcnJvck1hcHBlci5yZXNvbHZlT3JSZWplY3RFcnJvcih7XG4gICAgICAgICAgICAgIGVycjogZXJyLFxuICAgICAgICAgICAgICBlcnJvclJlc3BvbnNlRmFjdG9yeUZuOiBlID0+IG5ldyBSZWZyZXNoQXBpS2V5LkVycm9yKGUpLFxuICAgICAgICAgICAgICByZXNvbHZlRm46IHJlc29sdmUsXG4gICAgICAgICAgICAgIHJlamVjdEZuOiByZWplY3QsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmVzb2x2ZShcbiAgICAgICAgICAgICAgbmV3IFJlZnJlc2hBcGlLZXkuU3VjY2VzcyhcbiAgICAgICAgICAgICAgICByZXNwLmFwaV9rZXksXG4gICAgICAgICAgICAgICAgcmVzcC5yZWZyZXNoX3Rva2VuLFxuICAgICAgICAgICAgICAgIHJlc3AuZW5kcG9pbnQsXG4gICAgICAgICAgICAgICAgRXhwaXJlc0F0LmZyb21FcG9jaChyZXNwLnZhbGlkX3VudGlsKVxuICAgICAgICAgICAgICApXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVwcmVjYXRlZCBwbGVhc2UgdXNlIGByZWZyZXNoQXBpS2V5YCBpbnN0ZWFkXG4gICAqL1xuICBwdWJsaWMgcmVmcmVzaEF1dGhUb2tlbihcbiAgICByZWZyZXNoVG9rZW46IHN0cmluZ1xuICApOiBQcm9taXNlPFJlZnJlc2hBcGlLZXkuUmVzcG9uc2U+IHtcbiAgICByZXR1cm4gdGhpcy5yZWZyZXNoQXBpS2V5KHJlZnJlc2hUb2tlbik7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgZ2VuZXJhdGVEaXNwb3NhYmxlVG9rZW4oXG4gICAgc2NvcGU6IERpc3Bvc2FibGVUb2tlblNjb3BlLFxuICAgIGV4cGlyZXNJbjogRXhwaXJlc0luLFxuICAgIGRpc3Bvc2FibGVUb2tlblByb3BzPzogRGlzcG9zYWJsZVRva2VuUHJvcHNcbiAgKTogUHJvbWlzZTxHZW5lcmF0ZURpc3Bvc2FibGVUb2tlbi5SZXNwb25zZT4ge1xuICAgIHRyeSB7XG4gICAgICB2YWxpZGF0ZURpc3Bvc2FibGVUb2tlbkV4cGlyeShleHBpcmVzSW4pO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgcmV0dXJuIHRoaXMuY2FjaGVTZXJ2aWNlRXJyb3JNYXBwZXIucmV0dXJuT3JUaHJvd0Vycm9yKFxuICAgICAgICBlcnIgYXMgRXJyb3IsXG4gICAgICAgIGVyciA9PiBuZXcgR2VuZXJhdGVEaXNwb3NhYmxlVG9rZW4uRXJyb3IoZXJyKVxuICAgICAgKTtcbiAgICB9XG4gICAgY29uc3QgZXhwaXJlcyA9IG5ldyB0b2tlbi50b2tlbi5fR2VuZXJhdGVEaXNwb3NhYmxlVG9rZW5SZXF1ZXN0LkV4cGlyZXMoe1xuICAgICAgdmFsaWRfZm9yX3NlY29uZHM6IGV4cGlyZXNJbi5zZWNvbmRzKCksXG4gICAgfSk7XG5cbiAgICBsZXQgcGVybWlzc2lvbnM7XG4gICAgdHJ5IHtcbiAgICAgIHBlcm1pc3Npb25zID0gcGVybWlzc2lvbnNGcm9tRGlzcG9zYWJsZVRva2VuU2NvcGUoc2NvcGUpO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgcmV0dXJuIHRoaXMuY2FjaGVTZXJ2aWNlRXJyb3JNYXBwZXIucmV0dXJuT3JUaHJvd0Vycm9yKFxuICAgICAgICBlcnIgYXMgRXJyb3IsXG4gICAgICAgIGVyciA9PiBuZXcgR2VuZXJhdGVEaXNwb3NhYmxlVG9rZW4uRXJyb3IoZXJyKVxuICAgICAgKTtcbiAgICB9XG5cbiAgICBjb25zdCB0b2tlbklkID0gZGlzcG9zYWJsZVRva2VuUHJvcHM/LnRva2VuSWQ7XG4gICAgaWYgKHRva2VuSWQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgdmFsaWRhdGVEaXNwb3NhYmxlVG9rZW5Ub2tlbklEKHRva2VuSWQpO1xuICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNhY2hlU2VydmljZUVycm9yTWFwcGVyLnJldHVybk9yVGhyb3dFcnJvcihcbiAgICAgICAgICBlcnIgYXMgRXJyb3IsXG4gICAgICAgICAgZXJyID0+IG5ldyBHZW5lcmF0ZURpc3Bvc2FibGVUb2tlbi5FcnJvcihlcnIpXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgcmVxdWVzdCA9IG5ldyB0b2tlbi50b2tlbi5fR2VuZXJhdGVEaXNwb3NhYmxlVG9rZW5SZXF1ZXN0KHtcbiAgICAgIGV4cGlyZXM6IGV4cGlyZXMsXG4gICAgICBhdXRoX3Rva2VuOiB0aGlzLmNyZWRzLmdldEF1dGhUb2tlbigpLFxuICAgICAgcGVybWlzc2lvbnM6IHBlcm1pc3Npb25zLFxuICAgICAgdG9rZW5faWQ6IHRva2VuSWQsXG4gICAgfSk7XG5cbiAgICByZXR1cm4gYXdhaXQgbmV3IFByb21pc2U8R2VuZXJhdGVEaXNwb3NhYmxlVG9rZW4uUmVzcG9uc2U+KFxuICAgICAgKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICB0aGlzLnRva2VuQ2xpZW50LkdlbmVyYXRlRGlzcG9zYWJsZVRva2VuKFxuICAgICAgICAgIHJlcXVlc3QsXG4gICAgICAgICAge2ludGVyY2VwdG9yczogdGhpcy5pbnRlcmNlcHRvcnN9LFxuICAgICAgICAgIChlcnIsIHJlc3ApID0+IHtcbiAgICAgICAgICAgIGlmIChlcnIgfHwgIXJlc3ApIHtcbiAgICAgICAgICAgICAgdGhpcy5jYWNoZVNlcnZpY2VFcnJvck1hcHBlci5yZXNvbHZlT3JSZWplY3RFcnJvcih7XG4gICAgICAgICAgICAgICAgZXJyOiBlcnIsXG4gICAgICAgICAgICAgICAgZXJyb3JSZXNwb25zZUZhY3RvcnlGbjogZSA9PlxuICAgICAgICAgICAgICAgICAgbmV3IEdlbmVyYXRlRGlzcG9zYWJsZVRva2VuLkVycm9yKGUpLFxuICAgICAgICAgICAgICAgIHJlc29sdmVGbjogcmVzb2x2ZSxcbiAgICAgICAgICAgICAgICByZWplY3RGbjogcmVqZWN0LFxuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHJlc29sdmUoXG4gICAgICAgICAgICAgICAgbmV3IEdlbmVyYXRlRGlzcG9zYWJsZVRva2VuLlN1Y2Nlc3MoXG4gICAgICAgICAgICAgICAgICByZXNwLmFwaV9rZXksXG4gICAgICAgICAgICAgICAgICByZXNwLmVuZHBvaW50LFxuICAgICAgICAgICAgICAgICAgRXhwaXJlc0F0LmZyb21FcG9jaChyZXNwLnZhbGlkX3VudGlsKVxuICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICk7XG4gICAgICB9XG4gICAgKTtcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gcGVybWlzc2lvbnNGcm9tVG9rZW5TY29wZShcbiAgc2NvcGU6IFBlcm1pc3Npb25TY29wZVxuKTogcGVybWlzc2lvbl9tZXNzYWdlcy5QZXJtaXNzaW9ucyB7XG4gIGNvbnN0IHJlc3VsdCA9IG5ldyBwZXJtaXNzaW9uX21lc3NhZ2VzLlBlcm1pc3Npb25zKCk7XG4gIGlmIChzY29wZSBpbnN0YW5jZW9mIEludGVybmFsU3VwZXJVc2VyUGVybWlzc2lvbnMpIHtcbiAgICByZXN1bHQuc3VwZXJfdXNlciA9IHBlcm1pc3Npb25fbWVzc2FnZXMuU3VwZXJVc2VyUGVybWlzc2lvbnMuU3VwZXJVc2VyO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH0gZWxzZSBpZiAoaXNQZXJtaXNzaW9uc09iamVjdChzY29wZSkpIHtcbiAgICBjb25zdCBzY29wZVBlcm1pc3Npb25zOiBQZXJtaXNzaW9ucyA9IGFzUGVybWlzc2lvbnNPYmplY3Qoc2NvcGUpO1xuICAgIGNvbnN0IGV4cGxpY2l0UGVybWlzc2lvbnMgPSBuZXcgcGVybWlzc2lvbl9tZXNzYWdlcy5FeHBsaWNpdFBlcm1pc3Npb25zKCk7XG4gICAgZXhwbGljaXRQZXJtaXNzaW9ucy5wZXJtaXNzaW9ucyA9IHNjb3BlUGVybWlzc2lvbnMucGVybWlzc2lvbnMubWFwKHAgPT5cbiAgICAgIHRva2VuUGVybWlzc2lvblRvR3JwY1Blcm1pc3Npb24ocClcbiAgICApO1xuICAgIHJlc3VsdC5leHBsaWNpdCA9IGV4cGxpY2l0UGVybWlzc2lvbnM7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuICB0aHJvdyBuZXcgRXJyb3IoYFVucmVjb2duaXplZCB0b2tlbiBzY29wZTogJHtKU09OLnN0cmluZ2lmeShzY29wZSl9YCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBwZXJtaXNzaW9uc0Zyb21EaXNwb3NhYmxlVG9rZW5TY29wZShcbiAgc2NvcGU6IERpc3Bvc2FibGVUb2tlblNjb3BlXG4pOiBwZXJtaXNzaW9uX21lc3NhZ2VzLlBlcm1pc3Npb25zIHtcbiAgY29uc3QgcmVzdWx0ID0gbmV3IHBlcm1pc3Npb25fbWVzc2FnZXMuUGVybWlzc2lvbnMoKTtcbiAgaWYgKFxuICAgICEoc2NvcGUgaW5zdGFuY2VvZiBQcmVkZWZpbmVkU2NvcGUpICYmXG4gICAgaXNEaXNwb3NhYmxlVG9rZW5QZXJtaXNzaW9uc09iamVjdChzY29wZSlcbiAgKSB7XG4gICAgY29uc3Qgc2NvcGVQZXJtaXNzaW9ucyA9IGFzRGlzcG9zYWJsZVRva2VuUGVybWlzc2lvbnNPYmplY3Qoc2NvcGUpO1xuICAgIGNvbnN0IGV4cGxpY2l0UGVybWlzc2lvbnMgPSBuZXcgcGVybWlzc2lvbl9tZXNzYWdlcy5FeHBsaWNpdFBlcm1pc3Npb25zKCk7XG4gICAgZXhwbGljaXRQZXJtaXNzaW9ucy5wZXJtaXNzaW9ucyA9IHNjb3BlUGVybWlzc2lvbnMucGVybWlzc2lvbnMubWFwKHAgPT5cbiAgICAgIGRpc3Bvc2FibGVUb2tlblBlcm1pc3Npb25Ub0dycGNQZXJtaXNzaW9uKHApXG4gICAgKTtcbiAgICByZXN1bHQuZXhwbGljaXQgPSBleHBsaWNpdFBlcm1pc3Npb25zO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH0gZWxzZSBpZiAoaXNQZXJtaXNzaW9uc09iamVjdChzY29wZSkpIHtcbiAgICBjb25zdCBzY29wZVBlcm1pc3Npb25zOiBQZXJtaXNzaW9ucyA9IGFzUGVybWlzc2lvbnNPYmplY3Qoc2NvcGUpO1xuICAgIGNvbnN0IGV4cGxpY2l0UGVybWlzc2lvbnMgPSBuZXcgcGVybWlzc2lvbl9tZXNzYWdlcy5FeHBsaWNpdFBlcm1pc3Npb25zKCk7XG4gICAgZXhwbGljaXRQZXJtaXNzaW9ucy5wZXJtaXNzaW9ucyA9IHNjb3BlUGVybWlzc2lvbnMucGVybWlzc2lvbnMubWFwKHAgPT5cbiAgICAgIHRva2VuUGVybWlzc2lvblRvR3JwY1Blcm1pc3Npb24ocClcbiAgICApO1xuICAgIHJlc3VsdC5leHBsaWNpdCA9IGV4cGxpY2l0UGVybWlzc2lvbnM7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuICB0aHJvdyBuZXcgRXJyb3IoYFVucmVjb2duaXplZCB0b2tlbiBzY29wZTogJHtKU09OLnN0cmluZ2lmeShzY29wZSl9YCk7XG59XG5cbmZ1bmN0aW9uIHRva2VuUGVybWlzc2lvblRvR3JwY1Blcm1pc3Npb24oXG4gIHBlcm1pc3Npb246IFBlcm1pc3Npb25cbik6IHBlcm1pc3Npb25fbWVzc2FnZXMuUGVybWlzc2lvbnNUeXBlIHtcbiAgY29uc3QgcmVzdWx0ID0gbmV3IHBlcm1pc3Npb25fbWVzc2FnZXMuUGVybWlzc2lvbnNUeXBlKCk7XG4gIGlmIChpc1RvcGljUGVybWlzc2lvbihwZXJtaXNzaW9uKSkge1xuICAgIHJlc3VsdC50b3BpY19wZXJtaXNzaW9ucyA9IHRvcGljUGVybWlzc2lvblRvR3JwY1Blcm1pc3Npb24oXG4gICAgICBhc1RvcGljUGVybWlzc2lvbihwZXJtaXNzaW9uKVxuICAgICk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfSBlbHNlIGlmIChpc0NhY2hlUGVybWlzc2lvbihwZXJtaXNzaW9uKSkge1xuICAgIHJlc3VsdC5jYWNoZV9wZXJtaXNzaW9ucyA9IGNhY2hlUGVybWlzc2lvblRvR3JwY1Blcm1pc3Npb24oXG4gICAgICBhc0NhY2hlUGVybWlzc2lvbihwZXJtaXNzaW9uKVxuICAgICk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgYFVucmVjb2duaXplZCB0b2tlbiBwZXJtaXNzaW9uOiAke0pTT04uc3RyaW5naWZ5KHBlcm1pc3Npb24pfWBcbiAgKTtcbn1cblxuZnVuY3Rpb24gdG9waWNQZXJtaXNzaW9uVG9HcnBjUGVybWlzc2lvbihcbiAgcGVybWlzc2lvbjogVG9waWNQZXJtaXNzaW9uXG4pOiBwZXJtaXNzaW9uX21lc3NhZ2VzLlBlcm1pc3Npb25zVHlwZS5Ub3BpY1Blcm1pc3Npb25zIHtcbiAgY29uc3QgZ3JwY1Blcm1pc3Npb24gPVxuICAgIG5ldyBwZXJtaXNzaW9uX21lc3NhZ2VzLlBlcm1pc3Npb25zVHlwZS5Ub3BpY1Blcm1pc3Npb25zKCk7XG4gIHN3aXRjaCAocGVybWlzc2lvbi5yb2xlKSB7XG4gICAgY2FzZSBUb3BpY1JvbGUuUHVibGlzaFN1YnNjcmliZToge1xuICAgICAgZ3JwY1Blcm1pc3Npb24ucm9sZSA9IHBlcm1pc3Npb25fbWVzc2FnZXMuVG9waWNSb2xlLlRvcGljUmVhZFdyaXRlO1xuICAgICAgYnJlYWs7XG4gICAgfVxuICAgIGNhc2UgVG9waWNSb2xlLlN1YnNjcmliZU9ubHk6IHtcbiAgICAgIGdycGNQZXJtaXNzaW9uLnJvbGUgPSBwZXJtaXNzaW9uX21lc3NhZ2VzLlRvcGljUm9sZS5Ub3BpY1JlYWRPbmx5O1xuICAgICAgYnJlYWs7XG4gICAgfVxuICAgIGNhc2UgVG9waWNSb2xlLlB1Ymxpc2hPbmx5OiB7XG4gICAgICBncnBjUGVybWlzc2lvbi5yb2xlID0gcGVybWlzc2lvbl9tZXNzYWdlcy5Ub3BpY1JvbGUuVG9waWNXcml0ZU9ubHk7XG4gICAgICBicmVhaztcbiAgICB9XG4gICAgZGVmYXVsdDoge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbnJlY29nbml6ZWQgdG9waWMgcm9sZTogJHtKU09OLnN0cmluZ2lmeShwZXJtaXNzaW9uKX1gKTtcbiAgICB9XG4gIH1cblxuICBpZiAocGVybWlzc2lvbi5jYWNoZSA9PT0gQWxsQ2FjaGVzKSB7XG4gICAgZ3JwY1Blcm1pc3Npb24uYWxsX2NhY2hlcyA9IG5ldyBwZXJtaXNzaW9uX21lc3NhZ2VzLlBlcm1pc3Npb25zVHlwZS5BbGwoKTtcbiAgfSBlbHNlIGlmICh0eXBlb2YgcGVybWlzc2lvbi5jYWNoZSA9PT0gJ3N0cmluZycpIHtcbiAgICBncnBjUGVybWlzc2lvbi5jYWNoZV9zZWxlY3RvciA9XG4gICAgICBuZXcgcGVybWlzc2lvbl9tZXNzYWdlcy5QZXJtaXNzaW9uc1R5cGUuQ2FjaGVTZWxlY3Rvcih7XG4gICAgICAgIGNhY2hlX25hbWU6IHBlcm1pc3Npb24uY2FjaGUsXG4gICAgICB9KTtcbiAgfSBlbHNlIGlmIChpc0NhY2hlTmFtZShwZXJtaXNzaW9uLmNhY2hlKSkge1xuICAgIGdycGNQZXJtaXNzaW9uLmNhY2hlX3NlbGVjdG9yID1cbiAgICAgIG5ldyBwZXJtaXNzaW9uX21lc3NhZ2VzLlBlcm1pc3Npb25zVHlwZS5DYWNoZVNlbGVjdG9yKHtcbiAgICAgICAgY2FjaGVfbmFtZTogcGVybWlzc2lvbi5jYWNoZS5uYW1lLFxuICAgICAgfSk7XG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgYFVucmVjb2duaXplZCBjYWNoZSBzcGVjaWZpY2F0aW9uIGluIHRvcGljIHBlcm1pc3Npb246ICR7SlNPTi5zdHJpbmdpZnkoXG4gICAgICAgIHBlcm1pc3Npb25cbiAgICAgICl9YFxuICAgICk7XG4gIH1cblxuICBpZiAocGVybWlzc2lvbi50b3BpYyA9PT0gQWxsVG9waWNzKSB7XG4gICAgZ3JwY1Blcm1pc3Npb24uYWxsX3RvcGljcyA9IG5ldyBwZXJtaXNzaW9uX21lc3NhZ2VzLlBlcm1pc3Npb25zVHlwZS5BbGwoKTtcbiAgfSBlbHNlIGlmICh0eXBlb2YgcGVybWlzc2lvbi50b3BpYyA9PT0gJ3N0cmluZycpIHtcbiAgICBncnBjUGVybWlzc2lvbi50b3BpY19zZWxlY3RvciA9XG4gICAgICBuZXcgcGVybWlzc2lvbl9tZXNzYWdlcy5QZXJtaXNzaW9uc1R5cGUuVG9waWNTZWxlY3Rvcih7XG4gICAgICAgIHRvcGljX25hbWU6IHBlcm1pc3Npb24udG9waWMsXG4gICAgICB9KTtcbiAgfSBlbHNlIGlmIChpc1RvcGljTmFtZShwZXJtaXNzaW9uLnRvcGljKSkge1xuICAgIGdycGNQZXJtaXNzaW9uLnRvcGljX3NlbGVjdG9yID1cbiAgICAgIG5ldyBwZXJtaXNzaW9uX21lc3NhZ2VzLlBlcm1pc3Npb25zVHlwZS5Ub3BpY1NlbGVjdG9yKHtcbiAgICAgICAgdG9waWNfbmFtZTogcGVybWlzc2lvbi50b3BpYy5uYW1lLFxuICAgICAgfSk7XG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgYFVucmVjb2duaXplZCB0b3BpYyBzcGVjaWZpY2F0aW9uIGluIHRvcGljIHBlcm1pc3Npb246ICR7SlNPTi5zdHJpbmdpZnkoXG4gICAgICAgIHBlcm1pc3Npb25cbiAgICAgICl9YFxuICAgICk7XG4gIH1cbiAgcmV0dXJuIGdycGNQZXJtaXNzaW9uO1xufVxuXG5mdW5jdGlvbiBhc3NpZ25DYWNoZVJvbGUoXG4gIHBlcm1pc3Npb246IENhY2hlUGVybWlzc2lvbiB8IERpc3Bvc2FibGVUb2tlbkNhY2hlUGVybWlzc2lvbixcbiAgZ3JwY1Blcm1pc3Npb246IHBlcm1pc3Npb25fbWVzc2FnZXMuUGVybWlzc2lvbnNUeXBlLkNhY2hlUGVybWlzc2lvbnNcbik6IHBlcm1pc3Npb25fbWVzc2FnZXMuUGVybWlzc2lvbnNUeXBlLkNhY2hlUGVybWlzc2lvbnMge1xuICBzd2l0Y2ggKHBlcm1pc3Npb24ucm9sZSkge1xuICAgIGNhc2UgQ2FjaGVSb2xlLlJlYWRXcml0ZToge1xuICAgICAgZ3JwY1Blcm1pc3Npb24ucm9sZSA9IHBlcm1pc3Npb25fbWVzc2FnZXMuQ2FjaGVSb2xlLkNhY2hlUmVhZFdyaXRlO1xuICAgICAgYnJlYWs7XG4gICAgfVxuICAgIGNhc2UgQ2FjaGVSb2xlLlJlYWRPbmx5OiB7XG4gICAgICBncnBjUGVybWlzc2lvbi5yb2xlID0gcGVybWlzc2lvbl9tZXNzYWdlcy5DYWNoZVJvbGUuQ2FjaGVSZWFkT25seTtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgICBjYXNlIENhY2hlUm9sZS5Xcml0ZU9ubHk6IHtcbiAgICAgIGdycGNQZXJtaXNzaW9uLnJvbGUgPSBwZXJtaXNzaW9uX21lc3NhZ2VzLkNhY2hlUm9sZS5DYWNoZVdyaXRlT25seTtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgICBkZWZhdWx0OiB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFVucmVjb2duaXplZCBjYWNoZSByb2xlOiAke0pTT04uc3RyaW5naWZ5KHBlcm1pc3Npb24pfWApO1xuICAgIH1cbiAgfVxuICByZXR1cm4gZ3JwY1Blcm1pc3Npb247XG59XG5cbmZ1bmN0aW9uIGFzc2lnbkNhY2hlU2VsZWN0b3IoXG4gIHBlcm1pc3Npb246IENhY2hlUGVybWlzc2lvbiB8IERpc3Bvc2FibGVUb2tlbkNhY2hlUGVybWlzc2lvbixcbiAgZ3JwY1Blcm1pc3Npb246IHBlcm1pc3Npb25fbWVzc2FnZXMuUGVybWlzc2lvbnNUeXBlLkNhY2hlUGVybWlzc2lvbnNcbik6IHBlcm1pc3Npb25fbWVzc2FnZXMuUGVybWlzc2lvbnNUeXBlLkNhY2hlUGVybWlzc2lvbnMge1xuICBpZiAocGVybWlzc2lvbi5jYWNoZSA9PT0gQWxsQ2FjaGVzKSB7XG4gICAgZ3JwY1Blcm1pc3Npb24uYWxsX2NhY2hlcyA9IG5ldyBwZXJtaXNzaW9uX21lc3NhZ2VzLlBlcm1pc3Npb25zVHlwZS5BbGwoKTtcbiAgfSBlbHNlIGlmICh0eXBlb2YgcGVybWlzc2lvbi5jYWNoZSA9PT0gJ3N0cmluZycpIHtcbiAgICBncnBjUGVybWlzc2lvbi5jYWNoZV9zZWxlY3RvciA9XG4gICAgICBuZXcgcGVybWlzc2lvbl9tZXNzYWdlcy5QZXJtaXNzaW9uc1R5cGUuQ2FjaGVTZWxlY3Rvcih7XG4gICAgICAgIGNhY2hlX25hbWU6IHBlcm1pc3Npb24uY2FjaGUsXG4gICAgICB9KTtcbiAgfSBlbHNlIGlmIChpc0NhY2hlTmFtZShwZXJtaXNzaW9uLmNhY2hlKSkge1xuICAgIGdycGNQZXJtaXNzaW9uLmNhY2hlX3NlbGVjdG9yID1cbiAgICAgIG5ldyBwZXJtaXNzaW9uX21lc3NhZ2VzLlBlcm1pc3Npb25zVHlwZS5DYWNoZVNlbGVjdG9yKHtcbiAgICAgICAgY2FjaGVfbmFtZTogcGVybWlzc2lvbi5jYWNoZS5uYW1lLFxuICAgICAgfSk7XG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgYFVucmVjb2duaXplZCBjYWNoZSBzcGVjaWZpY2F0aW9uIGluIGNhY2hlIHBlcm1pc3Npb246ICR7SlNPTi5zdHJpbmdpZnkoXG4gICAgICAgIHBlcm1pc3Npb25cbiAgICAgICl9YFxuICAgICk7XG4gIH1cbiAgcmV0dXJuIGdycGNQZXJtaXNzaW9uO1xufVxuXG5mdW5jdGlvbiBhc3NpZ25DYWNoZUl0ZW1TZWxlY3RvcihcbiAgcGVybWlzc2lvbjogRGlzcG9zYWJsZVRva2VuQ2FjaGVQZXJtaXNzaW9uLFxuICBncnBjUGVybWlzc2lvbjogcGVybWlzc2lvbl9tZXNzYWdlcy5QZXJtaXNzaW9uc1R5cGUuQ2FjaGVQZXJtaXNzaW9uc1xuKTogcGVybWlzc2lvbl9tZXNzYWdlcy5QZXJtaXNzaW9uc1R5cGUuQ2FjaGVQZXJtaXNzaW9ucyB7XG4gIGlmIChwZXJtaXNzaW9uLml0ZW0gPT09IEFsbENhY2hlSXRlbXMpIHtcbiAgICBncnBjUGVybWlzc2lvbi5hbGxfaXRlbXMgPSBuZXcgcGVybWlzc2lvbl9tZXNzYWdlcy5QZXJtaXNzaW9uc1R5cGUuQWxsKCk7XG4gIH0gZWxzZSBpZiAodHlwZW9mIHBlcm1pc3Npb24uaXRlbSA9PT0gJ3N0cmluZycpIHtcbiAgICBncnBjUGVybWlzc2lvbi5pdGVtX3NlbGVjdG9yID1cbiAgICAgIG5ldyBwZXJtaXNzaW9uX21lc3NhZ2VzLlBlcm1pc3Npb25zVHlwZS5DYWNoZUl0ZW1TZWxlY3Rvcih7XG4gICAgICAgIGtleTogY29udmVydChwZXJtaXNzaW9uLml0ZW0pLFxuICAgICAgfSk7XG4gIH0gZWxzZSBpZiAoaXNDYWNoZUl0ZW1LZXkocGVybWlzc2lvbi5pdGVtKSkge1xuICAgIHZhbGlkYXRlQ2FjaGVLZXlPclByZWZpeChwZXJtaXNzaW9uLml0ZW0ua2V5KTtcbiAgICBncnBjUGVybWlzc2lvbi5pdGVtX3NlbGVjdG9yID1cbiAgICAgIG5ldyBwZXJtaXNzaW9uX21lc3NhZ2VzLlBlcm1pc3Npb25zVHlwZS5DYWNoZUl0ZW1TZWxlY3Rvcih7XG4gICAgICAgIGtleTogY29udmVydChwZXJtaXNzaW9uLml0ZW0ua2V5KSxcbiAgICAgIH0pO1xuICB9IGVsc2UgaWYgKGlzQ2FjaGVJdGVtS2V5UHJlZml4KHBlcm1pc3Npb24uaXRlbSkpIHtcbiAgICB2YWxpZGF0ZUNhY2hlS2V5T3JQcmVmaXgocGVybWlzc2lvbi5pdGVtLmtleVByZWZpeCk7XG4gICAgZ3JwY1Blcm1pc3Npb24uaXRlbV9zZWxlY3RvciA9XG4gICAgICBuZXcgcGVybWlzc2lvbl9tZXNzYWdlcy5QZXJtaXNzaW9uc1R5cGUuQ2FjaGVJdGVtU2VsZWN0b3Ioe1xuICAgICAgICBrZXlfcHJlZml4OiBjb252ZXJ0KHBlcm1pc3Npb24uaXRlbS5rZXlQcmVmaXgpLFxuICAgICAgfSk7XG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgYFVucmVjb2duaXplZCBjYWNoZSBpdGVtIHNwZWNpZmljYXRpb24gaW4gY2FjaGUgcGVybWlzc2lvbjogJHtKU09OLnN0cmluZ2lmeShcbiAgICAgICAgcGVybWlzc2lvblxuICAgICAgKX1gXG4gICAgKTtcbiAgfVxuICByZXR1cm4gZ3JwY1Blcm1pc3Npb247XG59XG5cbmZ1bmN0aW9uIGNhY2hlUGVybWlzc2lvblRvR3JwY1Blcm1pc3Npb24oXG4gIHBlcm1pc3Npb246IENhY2hlUGVybWlzc2lvblxuKTogcGVybWlzc2lvbl9tZXNzYWdlcy5QZXJtaXNzaW9uc1R5cGUuQ2FjaGVQZXJtaXNzaW9ucyB7XG4gIGxldCBncnBjUGVybWlzc2lvbiA9XG4gICAgbmV3IHBlcm1pc3Npb25fbWVzc2FnZXMuUGVybWlzc2lvbnNUeXBlLkNhY2hlUGVybWlzc2lvbnMoKTtcbiAgZ3JwY1Blcm1pc3Npb24gPSBhc3NpZ25DYWNoZVJvbGUocGVybWlzc2lvbiwgZ3JwY1Blcm1pc3Npb24pO1xuICBncnBjUGVybWlzc2lvbiA9IGFzc2lnbkNhY2hlU2VsZWN0b3IocGVybWlzc2lvbiwgZ3JwY1Blcm1pc3Npb24pO1xuICByZXR1cm4gZ3JwY1Blcm1pc3Npb247XG59XG5cbmZ1bmN0aW9uIGRpc3Bvc2FibGVUb2tlblBlcm1pc3Npb25Ub0dycGNQZXJtaXNzaW9uKFxuICBwZXJtaXNzaW9uOiBEaXNwb3NhYmxlVG9rZW5DYWNoZVBlcm1pc3Npb25cbik6IHBlcm1pc3Npb25fbWVzc2FnZXMuUGVybWlzc2lvbnNUeXBlIHtcbiAgY29uc3QgcmVzdWx0ID0gbmV3IHBlcm1pc3Npb25fbWVzc2FnZXMuUGVybWlzc2lvbnNUeXBlKCk7XG4gIGlmIChpc0Rpc3Bvc2FibGVUb2tlbkNhY2hlUGVybWlzc2lvbihwZXJtaXNzaW9uKSkge1xuICAgIHJlc3VsdC5jYWNoZV9wZXJtaXNzaW9ucyA9IGRpc3Bvc2FibGVDYWNoZVBlcm1pc3Npb25Ub0dycGNQZXJtaXNzaW9uKFxuICAgICAgYXNEaXNwb3NhYmxlVG9rZW5DYWNoZVBlcm1pc3Npb24ocGVybWlzc2lvbilcbiAgICApO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cbiAgdGhyb3cgbmV3IEVycm9yKFxuICAgIGBVbnJlY29nbml6ZWQgdG9rZW4gcGVybWlzc2lvbjogJHtKU09OLnN0cmluZ2lmeShwZXJtaXNzaW9uKX1gXG4gICk7XG59XG5cbmZ1bmN0aW9uIGRpc3Bvc2FibGVDYWNoZVBlcm1pc3Npb25Ub0dycGNQZXJtaXNzaW9uKFxuICBwZXJtaXNzaW9uOiBEaXNwb3NhYmxlVG9rZW5DYWNoZVBlcm1pc3Npb25cbik6IHBlcm1pc3Npb25fbWVzc2FnZXMuUGVybWlzc2lvbnNUeXBlLkNhY2hlUGVybWlzc2lvbnMge1xuICBsZXQgZ3JwY1Blcm1pc3Npb24gPVxuICAgIG5ldyBwZXJtaXNzaW9uX21lc3NhZ2VzLlBlcm1pc3Npb25zVHlwZS5DYWNoZVBlcm1pc3Npb25zKCk7XG4gIGdycGNQZXJtaXNzaW9uID0gYXNzaWduQ2FjaGVSb2xlKHBlcm1pc3Npb24sIGdycGNQZXJtaXNzaW9uKTtcbiAgZ3JwY1Blcm1pc3Npb24gPSBhc3NpZ25DYWNoZVNlbGVjdG9yKHBlcm1pc3Npb24sIGdycGNQZXJtaXNzaW9uKTtcbiAgZ3JwY1Blcm1pc3Npb24gPSBhc3NpZ25DYWNoZUl0ZW1TZWxlY3RvcihwZXJtaXNzaW9uLCBncnBjUGVybWlzc2lvbik7XG5cbiAgcmV0dXJuIGdycGNQZXJtaXNzaW9uO1xufVxuIl19
© 2015 - 2025 Weber Informatics LLC | Privacy Policy