jsii-release
Version:
Release jsii modules to multiple package managers
290 lines • 38.2 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.CodeArtifactRepo = void 0;
const client_codeartifact_1 = require("@aws-sdk/client-codeartifact");
const sleep_1 = require("../help/sleep");
const COLLECT_BY_TAG = 'collect-by';
const REPO_LIFETIME_MS = 24 * 3600 * 1000; // One day
/**
* A CodeArtifact repository
*/
class CodeArtifactRepo {
/**
* Create a CodeArtifact repo with a random name
*/
static async createRandom(options = {}) {
const qualifier = Math.random().toString(36).replace(/[^a-z0-9]+/g, '');
const repo = new CodeArtifactRepo(`test-${qualifier}`, options);
await repo.create();
return repo;
}
/**
* Create a CodeArtifact repository with a given name
*/
static async createWithName(name, options = {}) {
const repo = new CodeArtifactRepo(name, options);
await repo.create();
return repo;
}
/**
* Reference an existing CodeArtifact repository
*/
static existing(repositoryName, options = {}) {
return new CodeArtifactRepo(repositoryName, options);
}
/**
* Garbage collect repositories
*/
static async gc(options = {}) {
if (!await CodeArtifactRepo.existing('*dummy*').domainExists()) {
return;
}
const codeArtifact = new client_codeartifact_1.CodeartifactClient({
credentials: options.credentials,
});
let nextToken;
do {
const page = await retryThrottled(() => codeArtifact.send(new client_codeartifact_1.ListRepositoriesCommand({ nextToken })));
for (const repo of page.repositories ?? []) {
const tags = await retryThrottled(() => codeArtifact.send(new client_codeartifact_1.ListTagsForResourceCommand({ resourceArn: repo.arn })));
const collectable = tags?.tags?.find(t => t.key === COLLECT_BY_TAG && Number(t.value) < Date.now());
if (collectable) {
// eslint-disable-next-line no-console
console.error('Deleting', repo.name);
await retryThrottled(() => codeArtifact.send(new client_codeartifact_1.DeleteRepositoryCommand({
domain: repo.domainName,
repository: repo.name,
})));
}
}
nextToken = page.nextToken;
} while (nextToken);
}
constructor(repositoryName, options = {}) {
this.repositoryName = repositoryName;
this.npmUpstream = 'npm-upstream';
this.pypiUpstream = 'pypi-upstream';
this.nugetUpstream = 'nuget-upstream';
this.mavenUpstream = 'maven-upstream';
this.domain = CodeArtifactRepo.DEFAULT_DOMAIN;
this.codeArtifact = new client_codeartifact_1.CodeartifactClient({ credentials: options.credentials });
// Letting the compiler infer the types in this way is the only way to get it to typecheck
this.send = (command) => retryThrottled(() => this.codeArtifact.send(command));
}
/**
* Create the repository
*/
async create() {
await this.ensureDomain();
await this.ensureUpstreams();
await this.ensureRepository(this.repositoryName, {
description: 'Testing repository',
upstreams: [
this.npmUpstream,
this.pypiUpstream,
this.nugetUpstream,
this.mavenUpstream,
],
tags: {
[COLLECT_BY_TAG]: `${Date.now() + REPO_LIFETIME_MS}`,
},
});
}
/**
* Absorb old login information
*/
setLoginInformation(loginInfo) {
if (loginInfo.repositoryName !== this.repositoryName) {
throw new Error(`This login info seems to be for a different repo. '${this.repositoryName}' != '${loginInfo.repositoryName}'`);
}
this._loginInformation = loginInfo;
}
async login() {
if (this._loginInformation) {
return this._loginInformation;
}
const durationSeconds = 12 * 3600;
const authToken = await this.send(new client_codeartifact_1.GetAuthorizationTokenCommand({ domain: this.domain, durationSeconds }));
this._loginInformation = {
// eslint-disable-next-line max-len
authToken: authToken.authorizationToken,
expirationTimeMs: authToken.expiration?.getTime() ?? (Date.now() + durationSeconds * 1000),
repositoryName: this.repositoryName,
npmEndpoint: (await this.send(new client_codeartifact_1.GetRepositoryEndpointCommand({ domain: this.domain, repository: this.repositoryName, format: 'npm' }))).repositoryEndpoint,
mavenEndpoint: (await this.send(new client_codeartifact_1.GetRepositoryEndpointCommand({ domain: this.domain, repository: this.repositoryName, format: 'maven' }))).repositoryEndpoint,
nugetEndpoint: (await this.send(new client_codeartifact_1.GetRepositoryEndpointCommand({ domain: this.domain, repository: this.repositoryName, format: 'nuget' }))).repositoryEndpoint,
pypiEndpoint: (await this.send(new client_codeartifact_1.GetRepositoryEndpointCommand({ domain: this.domain, repository: this.repositoryName, format: 'pypi' }))).repositoryEndpoint,
};
return this._loginInformation;
}
async delete() {
try {
await this.send(new client_codeartifact_1.DeleteRepositoryCommand({
domain: this.domain,
repository: this.repositoryName,
}));
// eslint-disable-next-line no-console
console.error('Deleted', this.repositoryName);
}
catch (e) {
if (!isResourceNotFoundException(e)) {
throw e;
}
// Okay
}
}
/**
* List all packages and mark them as "allow upstream versions".
*
* If we don't do this and we publish `foo@2.3.4-rc.0`, then we can't
* download `foo@2.3.0` anymore because by default CodeArtifact will
* block different versions from the same package.
*/
async markAllUpstreamAllow() {
for await (const pkg of this.listPackages({ upstream: 'BLOCK' })) {
await this.send(new client_codeartifact_1.PutPackageOriginConfigurationCommand({
domain: this.domain,
repository: this.repositoryName,
format: pkg.format,
package: pkg.package,
namespace: pkg.namespace,
restrictions: {
publish: 'ALLOW',
upstream: 'ALLOW',
},
}));
}
}
async ensureDomain() {
if (await this.domainExists()) {
return;
}
await this.send(new client_codeartifact_1.CreateDomainCommand({
domain: this.domain,
tags: [{ key: 'testing', value: 'true' }],
}));
}
async ensureUpstreams() {
await this.ensureRepository(this.npmUpstream, {
description: 'The upstream repository for NPM',
external: 'public:npmjs',
});
await this.ensureRepository(this.mavenUpstream, {
description: 'The upstream repository for Maven',
external: 'public:maven-central',
});
await this.ensureRepository(this.nugetUpstream, {
description: 'The upstream repository for NuGet',
external: 'public:nuget-org',
});
await this.ensureRepository(this.pypiUpstream, {
description: 'The upstream repository for PyPI',
external: 'public:pypi',
});
}
async ensureRepository(name, options) {
if (await this.repositoryExists(name)) {
return;
}
await this.send(new client_codeartifact_1.CreateRepositoryCommand({
domain: this.domain,
repository: name,
description: options?.description,
upstreams: options?.upstreams?.map(repositoryName => ({ repositoryName })),
tags: options?.tags ? Object.entries(options.tags).map(([key, value]) => ({ key, value })) : undefined,
}));
if (options?.external) {
const externalConnection = options.external;
await retry(() => this.send(new client_codeartifact_1.AssociateExternalConnectionCommand({
domain: this.domain,
repository: name,
externalConnection,
})));
}
}
async domainExists() {
try {
await this.send(new client_codeartifact_1.DescribeDomainCommand({ domain: this.domain }));
return true;
}
catch (e) {
if (!isResourceNotFoundException(e)) {
throw e;
}
return false;
}
}
async repositoryExists(name) {
try {
await this.send(new client_codeartifact_1.DescribeRepositoryCommand({ domain: this.domain, repository: name }));
return true;
}
catch (e) {
if (!isResourceNotFoundException(e)) {
throw e;
}
return false;
}
}
async *listPackages(filter = {}) {
let response = await this.send(new client_codeartifact_1.ListPackagesCommand({
domain: this.domain,
repository: this.repositoryName,
...filter,
}));
while (true) {
for (const p of response.packages ?? []) {
yield p;
}
if (!response.nextToken) {
break;
}
response = await this.send(new client_codeartifact_1.ListPackagesCommand({
domain: this.domain,
repository: this.repositoryName,
...filter,
nextToken: response.nextToken,
}));
}
}
}
exports.CodeArtifactRepo = CodeArtifactRepo;
CodeArtifactRepo.DEFAULT_DOMAIN = 'publib-ca';
async function retry(block) {
let attempts = 3;
while (true) {
try {
return await block();
}
catch (e) {
if (attempts-- === 0) {
throw e;
}
// eslint-disable-next-line no-console
console.debug(e.message);
await (0, sleep_1.sleep)(500);
}
}
}
async function retryThrottled(block) {
let time = 100;
let attempts = 15;
while (true) {
try {
return await block();
}
catch (e) {
// eslint-disable-next-line no-console
console.debug(e);
if (!(e instanceof client_codeartifact_1.ThrottlingException) || --attempts === 0) {
throw e;
}
await (0, sleep_1.sleep)(Math.floor(Math.random() * time));
time *= 2;
}
}
}
function isResourceNotFoundException(x) {
return x instanceof client_codeartifact_1.ResourceNotFoundException;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29kZWFydGlmYWN0LXJlcG8uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvY29kZWFydGlmYWN0L2NvZGVhcnRpZmFjdC1yZXBvLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLHNFQUFxZDtBQUVyZCx5Q0FBc0M7QUFFdEMsTUFBTSxjQUFjLEdBQUcsWUFBWSxDQUFDO0FBQ3BDLE1BQU0sZ0JBQWdCLEdBQUcsRUFBRSxHQUFHLElBQUksR0FBRyxJQUFJLENBQUMsQ0FBQyxVQUFVO0FBTXJEOztHQUVHO0FBQ0gsTUFBYSxnQkFBZ0I7SUFHM0I7O09BRUc7SUFDSSxNQUFNLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQyxVQUFtQyxFQUFFO1FBQ3BFLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDLENBQUMsT0FBTyxDQUFDLGFBQWEsRUFBRSxFQUFFLENBQUMsQ0FBQztRQUV4RSxNQUFNLElBQUksR0FBRyxJQUFJLGdCQUFnQixDQUFDLFFBQVEsU0FBUyxFQUFFLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFDaEUsTUFBTSxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDcEIsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQ7O09BRUc7SUFDSSxNQUFNLENBQUMsS0FBSyxDQUFDLGNBQWMsQ0FBQyxJQUFZLEVBQUUsVUFBbUMsRUFBRTtRQUNwRixNQUFNLElBQUksR0FBRyxJQUFJLGdCQUFnQixDQUFDLElBQUksRUFBRSxPQUFPLENBQUMsQ0FBQztRQUNqRCxNQUFNLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUNwQixPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRDs7T0FFRztJQUNJLE1BQU0sQ0FBQyxRQUFRLENBQUMsY0FBc0IsRUFBRSxVQUFtQyxFQUFFO1FBQ2xGLE9BQU8sSUFBSSxnQkFBZ0IsQ0FBQyxjQUFjLEVBQUUsT0FBTyxDQUFDLENBQUM7SUFDdkQsQ0FBQztJQUVEOztPQUVHO0lBQ0ksTUFBTSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsVUFBbUMsRUFBRTtRQUMxRCxJQUFJLENBQUMsTUFBTSxnQkFBZ0IsQ0FBQyxRQUFRLENBQUMsU0FBUyxDQUFDLENBQUMsWUFBWSxFQUFFLEVBQUUsQ0FBQztZQUMvRCxPQUFPO1FBQ1QsQ0FBQztRQUVELE1BQU0sWUFBWSxHQUFHLElBQUksd0NBQWtCLENBQUM7WUFDMUMsV0FBVyxFQUFFLE9BQU8sQ0FBQyxXQUFXO1NBQ2pDLENBQUMsQ0FBQztRQUVILElBQUksU0FBNkIsQ0FBQztRQUNsQyxHQUFHLENBQUM7WUFDRixNQUFNLElBQUksR0FBRyxNQUFNLGNBQWMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLElBQUksNkNBQXVCLENBQUMsRUFBRSxTQUFTLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUV2RyxLQUFLLE1BQU0sSUFBSSxJQUFJLElBQUksQ0FBQyxZQUFZLElBQUksRUFBRSxFQUFFLENBQUM7Z0JBQzNDLE1BQU0sSUFBSSxHQUFHLE1BQU0sY0FBYyxDQUFDLEdBQUcsRUFBRSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsSUFBSSxnREFBMEIsQ0FBQyxFQUFFLFdBQVcsRUFBRSxJQUFJLENBQUMsR0FBSSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQ3ZILE1BQU0sV0FBVyxHQUFHLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxjQUFjLElBQUksTUFBTSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQztnQkFDcEcsSUFBSSxXQUFXLEVBQUUsQ0FBQztvQkFDaEIsc0NBQXNDO29CQUN0QyxPQUFPLENBQUMsS0FBSyxDQUFDLFVBQVUsRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7b0JBQ3JDLE1BQU0sY0FBYyxDQUFDLEdBQUcsRUFBRSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsSUFBSSw2Q0FBdUIsQ0FBQzt3QkFDdkUsTUFBTSxFQUFFLElBQUksQ0FBQyxVQUFXO3dCQUN4QixVQUFVLEVBQUUsSUFBSSxDQUFDLElBQUs7cUJBQ3ZCLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQ1AsQ0FBQztZQUNILENBQUM7WUFFRCxTQUFTLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQztRQUM3QixDQUFDLFFBQVEsU0FBUyxFQUFFO0lBQ3RCLENBQUM7SUFhRCxZQUNrQixjQUFzQixFQUN0QyxVQUFtQyxFQUFFO1FBRHJCLG1CQUFjLEdBQWQsY0FBYyxDQUFRO1FBWnhCLGdCQUFXLEdBQUcsY0FBYyxDQUFDO1FBQzdCLGlCQUFZLEdBQUcsZUFBZSxDQUFDO1FBQy9CLGtCQUFhLEdBQUcsZ0JBQWdCLENBQUM7UUFDakMsa0JBQWEsR0FBRyxnQkFBZ0IsQ0FBQztRQUNqQyxXQUFNLEdBQUcsZ0JBQWdCLENBQUMsY0FBYyxDQUFDO1FBV3ZELElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSx3Q0FBa0IsQ0FBQyxFQUFFLFdBQVcsRUFBRSxPQUFPLENBQUMsV0FBVyxFQUFFLENBQUMsQ0FBQztRQUVqRiwwRkFBMEY7UUFDMUYsSUFBSSxDQUFDLElBQUksR0FBRyxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUMsY0FBYyxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7SUFDakYsQ0FBQztJQUVEOztPQUVHO0lBQ0ksS0FBSyxDQUFDLE1BQU07UUFDakIsTUFBTSxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7UUFDMUIsTUFBTSxJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7UUFFN0IsTUFBTSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLGNBQWMsRUFBRTtZQUMvQyxXQUFXLEVBQUUsb0JBQW9CO1lBQ2pDLFNBQVMsRUFBRTtnQkFDVCxJQUFJLENBQUMsV0FBVztnQkFDaEIsSUFBSSxDQUFDLFlBQVk7Z0JBQ2pCLElBQUksQ0FBQyxhQUFhO2dCQUNsQixJQUFJLENBQUMsYUFBYTthQUNuQjtZQUNELElBQUksRUFBRTtnQkFDSixDQUFDLGNBQWMsQ0FBQyxFQUFFLEdBQUcsSUFBSSxDQUFDLEdBQUcsRUFBRSxHQUFHLGdCQUFnQixFQUFFO2FBQ3JEO1NBQ0YsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVEOztPQUVHO0lBQ0ksbUJBQW1CLENBQUMsU0FBMkI7UUFDcEQsSUFBSSxTQUFTLENBQUMsY0FBYyxLQUFLLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztZQUNyRCxNQUFNLElBQUksS0FBSyxDQUFDLHNEQUFzRCxJQUFJLENBQUMsY0FBYyxTQUFTLFNBQVMsQ0FBQyxjQUFjLEdBQUcsQ0FBQyxDQUFDO1FBQ2pJLENBQUM7UUFDRCxJQUFJLENBQUMsaUJBQWlCLEdBQUcsU0FBUyxDQUFDO0lBQ3JDLENBQUM7SUFFTSxLQUFLLENBQUMsS0FBSztRQUNoQixJQUFJLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO1lBQzNCLE9BQU8sSUFBSSxDQUFDLGlCQUFpQixDQUFDO1FBQ2hDLENBQUM7UUFFRCxNQUFNLGVBQWUsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDO1FBQ2xDLE1BQU0sU0FBUyxHQUFHLE1BQU0sSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLGtEQUE0QixDQUFDLEVBQUUsTUFBTSxFQUFFLElBQUksQ0FBQyxNQUFNLEVBQUUsZUFBZSxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBRTlHLElBQUksQ0FBQyxpQkFBaUIsR0FBRztZQUN2QixtQ0FBbUM7WUFDbkMsU0FBUyxFQUFFLFNBQVMsQ0FBQyxrQkFBbUI7WUFDeEMsZ0JBQWdCLEVBQUUsU0FBUyxDQUFDLFVBQVUsRUFBRSxPQUFPLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsR0FBRyxlQUFlLEdBQUcsSUFBSSxDQUFDO1lBQzFGLGNBQWMsRUFBRSxJQUFJLENBQUMsY0FBYztZQUNuQyxXQUFXLEVBQUUsQ0FBQyxNQUFNLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxrREFBNEIsQ0FBQyxFQUFFLE1BQU0sRUFBRSxJQUFJLENBQUMsTUFBTSxFQUFFLFVBQVUsRUFBRSxJQUFJLENBQUMsY0FBYyxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxrQkFBbUI7WUFDN0osYUFBYSxFQUFFLENBQUMsTUFBTSxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksa0RBQTRCLENBQUMsRUFBRSxNQUFNLEVBQUUsSUFBSSxDQUFDLE1BQU0sRUFBRSxVQUFVLEVBQUUsSUFBSSxDQUFDLGNBQWMsRUFBRSxNQUFNLEVBQUUsT0FBTyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsa0JBQW1CO1lBQ2pLLGFBQWEsRUFBRSxDQUFDLE1BQU0sSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLGtEQUE0QixDQUFDLEVBQUUsTUFBTSxFQUFFLElBQUksQ0FBQyxNQUFNLEVBQUUsVUFBVSxFQUFFLElBQUksQ0FBQyxjQUFjLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLGtCQUFtQjtZQUNqSyxZQUFZLEVBQUUsQ0FBQyxNQUFNLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxrREFBNEIsQ0FBQyxFQUFFLE1BQU0sRUFBRSxJQUFJLENBQUMsTUFBTSxFQUFFLFVBQVUsRUFBRSxJQUFJLENBQUMsY0FBYyxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxrQkFBbUI7U0FDaEssQ0FBQztRQUNGLE9BQU8sSUFBSSxDQUFDLGlCQUFpQixDQUFDO0lBQ2hDLENBQUM7SUFFTSxLQUFLLENBQUMsTUFBTTtRQUNqQixJQUFJLENBQUM7WUFDSCxNQUFNLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSw2Q0FBdUIsQ0FBQztnQkFDMUMsTUFBTSxFQUFFLElBQUksQ0FBQyxNQUFNO2dCQUNuQixVQUFVLEVBQUUsSUFBSSxDQUFDLGNBQWM7YUFDaEMsQ0FBQyxDQUFDLENBQUM7WUFFSixzQ0FBc0M7WUFDdEMsT0FBTyxDQUFDLEtBQUssQ0FBQyxTQUFTLEVBQUUsSUFBSSxDQUFDLGNBQWMsQ0FBQyxDQUFDO1FBQ2hELENBQUM7UUFBQyxPQUFPLENBQU0sRUFBRSxDQUFDO1lBQ2hCLElBQUksQ0FBQywyQkFBMkIsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO2dCQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQUMsQ0FBQztZQUNqRCxPQUFPO1FBQ1QsQ0FBQztJQUNILENBQUM7SUFFRDs7Ozs7O09BTUc7SUFDSSxLQUFLLENBQUMsb0JBQW9CO1FBQy9CLElBQUksS0FBSyxFQUFFLE1BQU0sR0FBRyxJQUFJLElBQUksQ0FBQyxZQUFZLENBQUMsRUFBRSxRQUFRLEVBQUUsT0FBTyxFQUFFLENBQUMsRUFBRSxDQUFDO1lBQ2pFLE1BQU0sSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLDBEQUFvQyxDQUFDO2dCQUN2RCxNQUFNLEVBQUUsSUFBSSxDQUFDLE1BQU07Z0JBQ25CLFVBQVUsRUFBRSxJQUFJLENBQUMsY0FBYztnQkFFL0IsTUFBTSxFQUFFLEdBQUcsQ0FBQyxNQUFPO2dCQUNuQixPQUFPLEVBQUUsR0FBRyxDQUFDLE9BQVE7Z0JBQ3JCLFNBQVMsRUFBRSxHQUFHLENBQUMsU0FBVTtnQkFDekIsWUFBWSxFQUFFO29CQUNaLE9BQU8sRUFBRSxPQUFPO29CQUNoQixRQUFRLEVBQUUsT0FBTztpQkFDbEI7YUFDRixDQUFDLENBQUMsQ0FBQztRQUNOLENBQUM7SUFDSCxDQUFDO0lBRU8sS0FBSyxDQUFDLFlBQVk7UUFDeEIsSUFBSSxNQUFNLElBQUksQ0FBQyxZQUFZLEVBQUUsRUFBRSxDQUFDO1lBQUMsT0FBTztRQUFDLENBQUM7UUFDMUMsTUFBTSxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUkseUNBQW1CLENBQUM7WUFDdEMsTUFBTSxFQUFFLElBQUksQ0FBQyxNQUFNO1lBQ25CLElBQUksRUFBRSxDQUFDLEVBQUUsR0FBRyxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLENBQUM7U0FDMUMsQ0FBQyxDQUFDLENBQUM7SUFDTixDQUFDO0lBRU8sS0FBSyxDQUFDLGVBQWU7UUFDM0IsTUFBTSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRTtZQUM1QyxXQUFXLEVBQUUsaUNBQWlDO1lBQzlDLFFBQVEsRUFBRSxjQUFjO1NBQ3pCLENBQUMsQ0FBQztRQUNILE1BQU0sSUFBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxhQUFhLEVBQUU7WUFDOUMsV0FBVyxFQUFFLG1DQUFtQztZQUNoRCxRQUFRLEVBQUUsc0JBQXNCO1NBQ2pDLENBQUMsQ0FBQztRQUNILE1BQU0sSUFBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxhQUFhLEVBQUU7WUFDOUMsV0FBVyxFQUFFLG1DQUFtQztZQUNoRCxRQUFRLEVBQUUsa0JBQWtCO1NBQzdCLENBQUMsQ0FBQztRQUNILE1BQU0sSUFBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxZQUFZLEVBQUU7WUFDN0MsV0FBVyxFQUFFLGtDQUFrQztZQUMvQyxRQUFRLEVBQUUsYUFBYTtTQUN4QixDQUFDLENBQUM7SUFDTCxDQUFDO0lBRU8sS0FBSyxDQUFDLGdCQUFnQixDQUFDLElBQVksRUFBRSxPQUs1QztRQUNDLElBQUksTUFBTSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQztZQUFDLE9BQU87UUFBQyxDQUFDO1FBRWxELE1BQU0sSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLDZDQUF1QixDQUFDO1lBQzFDLE1BQU0sRUFBRSxJQUFJLENBQUMsTUFBTTtZQUNuQixVQUFVLEVBQUUsSUFBSTtZQUNoQixXQUFXLEVBQUUsT0FBTyxFQUFFLFdBQVc7WUFDakMsU0FBUyxFQUFFLE9BQU8sRUFBRSxTQUFTLEVBQUUsR0FBRyxDQUFDLGNBQWMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLGNBQWMsRUFBRSxDQUFDLENBQUM7WUFDMUUsSUFBSSxFQUFFLE9BQU8sRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLEVBQUUsR0FBRyxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUztTQUN2RyxDQUFDLENBQUMsQ0FBQztRQUVKLElBQUksT0FBTyxFQUFFLFFBQVEsRUFBRSxDQUFDO1lBQ3RCLE1BQU0sa0JBQWtCLEdBQUcsT0FBTyxDQUFDLFFBQVEsQ0FBQztZQUM1QyxNQUFNLEtBQUssQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksd0RBQWtDLENBQUM7Z0JBQ2pFLE1BQU0sRUFBRSxJQUFJLENBQUMsTUFBTTtnQkFDbkIsVUFBVSxFQUFFLElBQUk7Z0JBQ2hCLGtCQUFrQjthQUNuQixDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ1AsQ0FBQztJQUNILENBQUM7SUFFTyxLQUFLLENBQUMsWUFBWTtRQUN4QixJQUFJLENBQUM7WUFDSCxNQUFNLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSwyQ0FBcUIsQ0FBQyxFQUFFLE1BQU0sRUFBRSxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQ3BFLE9BQU8sSUFBSSxDQUFDO1FBQ2QsQ0FBQztRQUFDLE9BQU8sQ0FBTSxFQUFFLENBQUM7WUFDaEIsSUFBSSxDQUFDLDJCQUEyQixDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7Z0JBQUMsTUFBTSxDQUFDLENBQUM7WUFBQyxDQUFDO1lBQ2pELE9BQU8sS0FBSyxDQUFDO1FBQ2YsQ0FBQztJQUNILENBQUM7SUFFTyxLQUFLLENBQUMsZ0JBQWdCLENBQUMsSUFBWTtRQUN6QyxJQUFJLENBQUM7WUFDSCxNQUFNLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSwrQ0FBeUIsQ0FBQyxFQUFFLE1BQU0sRUFBRSxJQUFJLENBQUMsTUFBTSxFQUFFLFVBQVUsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFDMUYsT0FBTyxJQUFJLENBQUM7UUFDZCxDQUFDO1FBQUMsT0FBTyxDQUFNLEVBQUUsQ0FBQztZQUNoQixJQUFJLENBQUMsMkJBQTJCLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztnQkFBQyxNQUFNLENBQUMsQ0FBQztZQUFDLENBQUM7WUFDakQsT0FBTyxLQUFLLENBQUM7UUFDZixDQUFDO0lBQ0gsQ0FBQztJQUVPLEtBQUssQ0FBQSxDQUFFLFlBQVksQ0FBQyxTQUF3RSxFQUFFO1FBQ3BHLElBQUksUUFBUSxHQUFHLE1BQU0sSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLHlDQUFtQixDQUFDO1lBQ3JELE1BQU0sRUFBRSxJQUFJLENBQUMsTUFBTTtZQUNuQixVQUFVLEVBQUUsSUFBSSxDQUFDLGNBQWM7WUFDL0IsR0FBRyxNQUFNO1NBQ1YsQ0FBQyxDQUFDLENBQUM7UUFFSixPQUFPLElBQUksRUFBRSxDQUFDO1lBQ1osS0FBSyxNQUFNLENBQUMsSUFBSSxRQUFRLENBQUMsUUFBUSxJQUFJLEVBQUUsRUFBRSxDQUFDO2dCQUN4QyxNQUFNLENBQUMsQ0FBQztZQUNWLENBQUM7WUFFRCxJQUFJLENBQUMsUUFBUSxDQUFDLFNBQVMsRUFBRSxDQUFDO2dCQUN4QixNQUFNO1lBQ1IsQ0FBQztZQUVELFFBQVEsR0FBRyxNQUFNLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSx5Q0FBbUIsQ0FBQztnQkFDakQsTUFBTSxFQUFFLElBQUksQ0FBQyxNQUFNO2dCQUNuQixVQUFVLEVBQUUsSUFBSSxDQUFDLGNBQWM7Z0JBQy9CLEdBQUcsTUFBTTtnQkFDVCxTQUFTLEVBQUUsUUFBUSxDQUFDLFNBQVM7YUFDOUIsQ0FBQyxDQUFDLENBQUM7UUFDTixDQUFDO0lBQ0gsQ0FBQzs7QUEvUUgsNENBZ1JDO0FBL1F3QiwrQkFBYyxHQUFHLFdBQVcsQUFBZCxDQUFlO0FBaVJ0RCxLQUFLLFVBQVUsS0FBSyxDQUFJLEtBQXVCO0lBQzdDLElBQUksUUFBUSxHQUFHLENBQUMsQ0FBQztJQUNqQixPQUFPLElBQUksRUFBRSxDQUFDO1FBQ1osSUFBSSxDQUFDO1lBQ0gsT0FBTyxNQUFNLEtBQUssRUFBRSxDQUFDO1FBQ3ZCLENBQUM7UUFBQyxPQUFPLENBQU0sRUFBRSxDQUFDO1lBQ2hCLElBQUksUUFBUSxFQUFFLEtBQUssQ0FBQyxFQUFFLENBQUM7Z0JBQUMsTUFBTSxDQUFDLENBQUM7WUFBQyxDQUFDO1lBQ2xDLHNDQUFzQztZQUN0QyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUN6QixNQUFNLElBQUEsYUFBSyxFQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ25CLENBQUM7SUFDSCxDQUFDO0FBQ0gsQ0FBQztBQUVELEtBQUssVUFBVSxjQUFjLENBQUksS0FBdUI7SUFDdEQsSUFBSSxJQUFJLEdBQUcsR0FBRyxDQUFDO0lBQ2YsSUFBSSxRQUFRLEdBQUcsRUFBRSxDQUFDO0lBQ2xCLE9BQU8sSUFBSSxFQUFFLENBQUM7UUFDWixJQUFJLENBQUM7WUFDSCxPQUFPLE1BQU0sS0FBSyxFQUFFLENBQUM7UUFDdkIsQ0FBQztRQUFDLE9BQU8sQ0FBTSxFQUFFLENBQUM7WUFDaEIsc0NBQXNDO1lBQ3RDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFFakIsSUFBSSxDQUFDLENBQUMsQ0FBQyxZQUFZLHlDQUFtQixDQUFDLElBQUksRUFBRSxRQUFRLEtBQUssQ0FBQyxFQUFFLENBQUM7Z0JBQzVELE1BQU0sQ0FBQyxDQUFDO1lBQ1YsQ0FBQztZQUVELE1BQU0sSUFBQSxhQUFLLEVBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQztZQUM5QyxJQUFJLElBQUksQ0FBQyxDQUFDO1FBQ1osQ0FBQztJQUNILENBQUM7QUFDSCxDQUFDO0FBWUQsU0FBUywyQkFBMkIsQ0FBQyxDQUFNO0lBQ3pDLE9BQU8sQ0FBQyxZQUFZLCtDQUF5QixDQUFDO0FBQ2hELENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBBc3NvY2lhdGVFeHRlcm5hbENvbm5lY3Rpb25Db21tYW5kLCBDb2RlYXJ0aWZhY3RDbGllbnQsIENyZWF0ZURvbWFpbkNvbW1hbmQsIENyZWF0ZVJlcG9zaXRvcnlDb21tYW5kLCBEZWxldGVSZXBvc2l0b3J5Q29tbWFuZCwgRGVzY3JpYmVEb21haW5Db21tYW5kLCBEZXNjcmliZVJlcG9zaXRvcnlDb21tYW5kLCBHZXRBdXRob3JpemF0aW9uVG9rZW5Db21tYW5kLCBHZXRSZXBvc2l0b3J5RW5kcG9pbnRDb21tYW5kLCBMaXN0UGFja2FnZXNDb21tYW5kLCBMaXN0UGFja2FnZXNDb21tYW5kSW5wdXQsIExpc3RSZXBvc2l0b3JpZXNDb21tYW5kLCBMaXN0VGFnc0ZvclJlc291cmNlQ29tbWFuZCwgUHV0UGFja2FnZU9yaWdpbkNvbmZpZ3VyYXRpb25Db21tYW5kLCBSZXNvdXJjZU5vdEZvdW5kRXhjZXB0aW9uLCBUaHJvdHRsaW5nRXhjZXB0aW9uIH0gZnJvbSAnQGF3cy1zZGsvY2xpZW50LWNvZGVhcnRpZmFjdCc7XG5pbXBvcnQgdHlwZSB7IEF3c0NyZWRlbnRpYWxJZGVudGl0eVByb3ZpZGVyIH0gZnJvbSAnQHNtaXRoeS90eXBlcyc7XG5pbXBvcnQgeyBzbGVlcCB9IGZyb20gJy4uL2hlbHAvc2xlZXAnO1xuXG5jb25zdCBDT0xMRUNUX0JZX1RBRyA9ICdjb2xsZWN0LWJ5JztcbmNvbnN0IFJFUE9fTElGRVRJTUVfTVMgPSAyNCAqIDM2MDAgKiAxMDAwOyAvLyBPbmUgZGF5XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ29kZUFydGlmYWN0UmVwb09wdGlvbnMge1xuICByZWFkb25seSBjcmVkZW50aWFscz86IEF3c0NyZWRlbnRpYWxJZGVudGl0eVByb3ZpZGVyO1xufVxuXG4vKipcbiAqIEEgQ29kZUFydGlmYWN0IHJlcG9zaXRvcnlcbiAqL1xuZXhwb3J0IGNsYXNzIENvZGVBcnRpZmFjdFJlcG8ge1xuICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IERFRkFVTFRfRE9NQUlOID0gJ3B1YmxpYi1jYSc7XG5cbiAgLyoqXG4gICAqIENyZWF0ZSBhIENvZGVBcnRpZmFjdCByZXBvIHdpdGggYSByYW5kb20gbmFtZVxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBhc3luYyBjcmVhdGVSYW5kb20ob3B0aW9uczogQ29kZUFydGlmYWN0UmVwb09wdGlvbnMgPSB7fSkge1xuICAgIGNvbnN0IHF1YWxpZmllciA9IE1hdGgucmFuZG9tKCkudG9TdHJpbmcoMzYpLnJlcGxhY2UoL1teYS16MC05XSsvZywgJycpO1xuXG4gICAgY29uc3QgcmVwbyA9IG5ldyBDb2RlQXJ0aWZhY3RSZXBvKGB0ZXN0LSR7cXVhbGlmaWVyfWAsIG9wdGlvbnMpO1xuICAgIGF3YWl0IHJlcG8uY3JlYXRlKCk7XG4gICAgcmV0dXJuIHJlcG87XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlIGEgQ29kZUFydGlmYWN0IHJlcG9zaXRvcnkgd2l0aCBhIGdpdmVuIG5hbWVcbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgYXN5bmMgY3JlYXRlV2l0aE5hbWUobmFtZTogc3RyaW5nLCBvcHRpb25zOiBDb2RlQXJ0aWZhY3RSZXBvT3B0aW9ucyA9IHt9KSB7XG4gICAgY29uc3QgcmVwbyA9IG5ldyBDb2RlQXJ0aWZhY3RSZXBvKG5hbWUsIG9wdGlvbnMpO1xuICAgIGF3YWl0IHJlcG8uY3JlYXRlKCk7XG4gICAgcmV0dXJuIHJlcG87XG4gIH1cblxuICAvKipcbiAgICogUmVmZXJlbmNlIGFuIGV4aXN0aW5nIENvZGVBcnRpZmFjdCByZXBvc2l0b3J5XG4gICAqL1xuICBwdWJsaWMgc3RhdGljIGV4aXN0aW5nKHJlcG9zaXRvcnlOYW1lOiBzdHJpbmcsIG9wdGlvbnM6IENvZGVBcnRpZmFjdFJlcG9PcHRpb25zID0ge30pIHtcbiAgICByZXR1cm4gbmV3IENvZGVBcnRpZmFjdFJlcG8ocmVwb3NpdG9yeU5hbWUsIG9wdGlvbnMpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdhcmJhZ2UgY29sbGVjdCByZXBvc2l0b3JpZXNcbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgYXN5bmMgZ2Mob3B0aW9uczogQ29kZUFydGlmYWN0UmVwb09wdGlvbnMgPSB7fSkge1xuICAgIGlmICghYXdhaXQgQ29kZUFydGlmYWN0UmVwby5leGlzdGluZygnKmR1bW15KicpLmRvbWFpbkV4aXN0cygpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgY29kZUFydGlmYWN0ID0gbmV3IENvZGVhcnRpZmFjdENsaWVudCh7XG4gICAgICBjcmVkZW50aWFsczogb3B0aW9ucy5jcmVkZW50aWFscyxcbiAgICB9KTtcblxuICAgIGxldCBuZXh0VG9rZW46IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgICBkbyB7XG4gICAgICBjb25zdCBwYWdlID0gYXdhaXQgcmV0cnlUaHJvdHRsZWQoKCkgPT4gY29kZUFydGlmYWN0LnNlbmQobmV3IExpc3RSZXBvc2l0b3JpZXNDb21tYW5kKHsgbmV4dFRva2VuIH0pKSk7XG5cbiAgICAgIGZvciAoY29uc3QgcmVwbyBvZiBwYWdlLnJlcG9zaXRvcmllcyA/PyBbXSkge1xuICAgICAgICBjb25zdCB0YWdzID0gYXdhaXQgcmV0cnlUaHJvdHRsZWQoKCkgPT4gY29kZUFydGlmYWN0LnNlbmQobmV3IExpc3RUYWdzRm9yUmVzb3VyY2VDb21tYW5kKHsgcmVzb3VyY2VBcm46IHJlcG8uYXJuISB9KSkpO1xuICAgICAgICBjb25zdCBjb2xsZWN0YWJsZSA9IHRhZ3M/LnRhZ3M/LmZpbmQodCA9PiB0LmtleSA9PT0gQ09MTEVDVF9CWV9UQUcgJiYgTnVtYmVyKHQudmFsdWUpIDwgRGF0ZS5ub3coKSk7XG4gICAgICAgIGlmIChjb2xsZWN0YWJsZSkge1xuICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zb2xlXG4gICAgICAgICAgY29uc29sZS5lcnJvcignRGVsZXRpbmcnLCByZXBvLm5hbWUpO1xuICAgICAgICAgIGF3YWl0IHJldHJ5VGhyb3R0bGVkKCgpID0+IGNvZGVBcnRpZmFjdC5zZW5kKG5ldyBEZWxldGVSZXBvc2l0b3J5Q29tbWFuZCh7XG4gICAgICAgICAgICBkb21haW46IHJlcG8uZG9tYWluTmFtZSEsXG4gICAgICAgICAgICByZXBvc2l0b3J5OiByZXBvLm5hbWUhLFxuICAgICAgICAgIH0pKSk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgbmV4dFRva2VuID0gcGFnZS5uZXh0VG9rZW47XG4gICAgfSB3aGlsZSAobmV4dFRva2VuKTtcbiAgfVxuXG4gIHB1YmxpYyByZWFkb25seSBucG1VcHN0cmVhbSA9ICducG0tdXBzdHJlYW0nO1xuICBwdWJsaWMgcmVhZG9ubHkgcHlwaVVwc3RyZWFtID0gJ3B5cGktdXBzdHJlYW0nO1xuICBwdWJsaWMgcmVhZG9ubHkgbnVnZXRVcHN0cmVhbSA9ICdudWdldC11cHN0cmVhbSc7XG4gIHB1YmxpYyByZWFkb25seSBtYXZlblVwc3RyZWFtID0gJ21hdmVuLXVwc3RyZWFtJztcbiAgcHVibGljIHJlYWRvbmx5IGRvbWFpbiA9IENvZGVBcnRpZmFjdFJlcG8uREVGQVVMVF9ET01BSU47XG5cbiAgcHJpdmF0ZSByZWFkb25seSBjb2RlQXJ0aWZhY3Q7XG5cbiAgcHJpdmF0ZSBfbG9naW5JbmZvcm1hdGlvbjogTG9naW5JbmZvcm1hdGlvbiB8IHVuZGVmaW5lZDtcbiAgcHJpdmF0ZSByZWFkb25seSBzZW5kOiBDb2RlYXJ0aWZhY3RDbGllbnRbJ3NlbmQnXTtcblxuICBwcml2YXRlIGNvbnN0cnVjdG9yKFxuICAgIHB1YmxpYyByZWFkb25seSByZXBvc2l0b3J5TmFtZTogc3RyaW5nLFxuICAgIG9wdGlvbnM6IENvZGVBcnRpZmFjdFJlcG9PcHRpb25zID0ge30sXG4gICkge1xuICAgIHRoaXMuY29kZUFydGlmYWN0ID0gbmV3IENvZGVhcnRpZmFjdENsaWVudCh7IGNyZWRlbnRpYWxzOiBvcHRpb25zLmNyZWRlbnRpYWxzIH0pO1xuXG4gICAgLy8gTGV0dGluZyB0aGUgY29tcGlsZXIgaW5mZXIgdGhlIHR5cGVzIGluIHRoaXMgd2F5IGlzIHRoZSBvbmx5IHdheSB0byBnZXQgaXQgdG8gdHlwZWNoZWNrXG4gICAgdGhpcy5zZW5kID0gKGNvbW1hbmQpID0+IHJldHJ5VGhyb3R0bGVkKCgpID0+IHRoaXMuY29kZUFydGlmYWN0LnNlbmQoY29tbWFuZCkpO1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZSB0aGUgcmVwb3NpdG9yeVxuICAgKi9cbiAgcHVibGljIGFzeW5jIGNyZWF0ZSgpIHtcbiAgICBhd2FpdCB0aGlzLmVuc3VyZURvbWFpbigpO1xuICAgIGF3YWl0IHRoaXMuZW5zdXJlVXBzdHJlYW1zKCk7XG5cbiAgICBhd2FpdCB0aGlzLmVuc3VyZVJlcG9zaXRvcnkodGhpcy5yZXBvc2l0b3J5TmFtZSwge1xuICAgICAgZGVzY3JpcHRpb246ICdUZXN0aW5nIHJlcG9zaXRvcnknLFxuICAgICAgdXBzdHJlYW1zOiBbXG4gICAgICAgIHRoaXMubnBtVXBzdHJlYW0sXG4gICAgICAgIHRoaXMucHlwaVVwc3RyZWFtLFxuICAgICAgICB0aGlzLm51Z2V0VXBzdHJlYW0sXG4gICAgICAgIHRoaXMubWF2ZW5VcHN0cmVhbSxcbiAgICAgIF0sXG4gICAgICB0YWdzOiB7XG4gICAgICAgIFtDT0xMRUNUX0JZX1RBR106IGAke0RhdGUubm93KCkgKyBSRVBPX0xJRkVUSU1FX01TfWAsXG4gICAgICB9LFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEFic29yYiBvbGQgbG9naW4gaW5mb3JtYXRpb25cbiAgICovXG4gIHB1YmxpYyBzZXRMb2dpbkluZm9ybWF0aW9uKGxvZ2luSW5mbzogTG9naW5JbmZvcm1hdGlvbikge1xuICAgIGlmIChsb2dpbkluZm8ucmVwb3NpdG9yeU5hbWUgIT09IHRoaXMucmVwb3NpdG9yeU5hbWUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgVGhpcyBsb2dpbiBpbmZvIHNlZW1zIHRvIGJlIGZvciBhIGRpZmZlcmVudCByZXBvLiAnJHt0aGlzLnJlcG9zaXRvcnlOYW1lfScgIT0gJyR7bG9naW5JbmZvLnJlcG9zaXRvcnlOYW1lfSdgKTtcbiAgICB9XG4gICAgdGhpcy5fbG9naW5JbmZvcm1hdGlvbiA9IGxvZ2luSW5mbztcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBsb2dpbigpOiBQcm9taXNlPExvZ2luSW5mb3JtYXRpb24+IHtcbiAgICBpZiAodGhpcy5fbG9naW5JbmZvcm1hdGlvbikge1xuICAgICAgcmV0dXJuIHRoaXMuX2xvZ2luSW5mb3JtYXRpb247XG4gICAgfVxuXG4gICAgY29uc3QgZHVyYXRpb25TZWNvbmRzID0gMTIgKiAzNjAwO1xuICAgIGNvbnN0IGF1dGhUb2tlbiA9IGF3YWl0IHRoaXMuc2VuZChuZXcgR2V0QXV0aG9yaXphdGlvblRva2VuQ29tbWFuZCh7IGRvbWFpbjogdGhpcy5kb21haW4sIGR1cmF0aW9uU2Vjb25kcyB9KSk7XG5cbiAgICB0aGlzLl9sb2dpbkluZm9ybWF0aW9uID0ge1xuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG1heC1sZW5cbiAgICAgIGF1dGhUb2tlbjogYXV0aFRva2VuLmF1dGhvcml6YXRpb25Ub2tlbiEsXG4gICAgICBleHBpcmF0aW9uVGltZU1zOiBhdXRoVG9rZW4uZXhwaXJhdGlvbj8uZ2V0VGltZSgpID8/IChEYXRlLm5vdygpICsgZHVyYXRpb25TZWNvbmRzICogMTAwMCksXG4gICAgICByZXBvc2l0b3J5TmFtZTogdGhpcy5yZXBvc2l0b3J5TmFtZSxcbiAgICAgIG5wbUVuZHBvaW50OiAoYXdhaXQgdGhpcy5zZW5kKG5ldyBHZXRSZXBvc2l0b3J5RW5kcG9pbnRDb21tYW5kKHsgZG9tYWluOiB0aGlzLmRvbWFpbiwgcmVwb3NpdG9yeTogdGhpcy5yZXBvc2l0b3J5TmFtZSwgZm9ybWF0OiAnbnBtJyB9KSkpLnJlcG9zaXRvcnlFbmRwb2ludCEsXG4gICAgICBtYXZlbkVuZHBvaW50OiAoYXdhaXQgdGhpcy5zZW5kKG5ldyBHZXRSZXBvc2l0b3J5RW5kcG9pbnRDb21tYW5kKHsgZG9tYWluOiB0aGlzLmRvbWFpbiwgcmVwb3NpdG9yeTogdGhpcy5yZXBvc2l0b3J5TmFtZSwgZm9ybWF0OiAnbWF2ZW4nIH0pKSkucmVwb3NpdG9yeUVuZHBvaW50ISxcbiAgICAgIG51Z2V0RW5kcG9pbnQ6IChhd2FpdCB0aGlzLnNlbmQobmV3IEdldFJlcG9zaXRvcnlFbmRwb2ludENvbW1hbmQoeyBkb21haW46IHRoaXMuZG9tYWluLCByZXBvc2l0b3J5OiB0aGlzLnJlcG9zaXRvcnlOYW1lLCBmb3JtYXQ6ICdudWdldCcgfSkpKS5yZXBvc2l0b3J5RW5kcG9pbnQhLFxuICAgICAgcHlwaUVuZHBvaW50OiAoYXdhaXQgdGhpcy5zZW5kKG5ldyBHZXRSZXBvc2l0b3J5RW5kcG9pbnRDb21tYW5kKHsgZG9tYWluOiB0aGlzLmRvbWFpbiwgcmVwb3NpdG9yeTogdGhpcy5yZXBvc2l0b3J5TmFtZSwgZm9ybWF0OiAncHlwaScgfSkpKS5yZXBvc2l0b3J5RW5kcG9pbnQhLFxuICAgIH07XG4gICAgcmV0dXJuIHRoaXMuX2xvZ2luSW5mb3JtYXRpb247XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgZGVsZXRlKCkge1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCB0aGlzLnNlbmQobmV3IERlbGV0ZVJlcG9zaXRvcnlDb21tYW5kKHtcbiAgICAgICAgZG9tYWluOiB0aGlzLmRvbWFpbixcbiAgICAgICAgcmVwb3NpdG9yeTogdGhpcy5yZXBvc2l0b3J5TmFtZSxcbiAgICAgIH0pKTtcblxuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnNvbGVcbiAgICAgIGNvbnNvbGUuZXJyb3IoJ0RlbGV0ZWQnLCB0aGlzLnJlcG9zaXRvcnlOYW1lKTtcbiAgICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICAgIGlmICghaXNSZXNvdXJjZU5vdEZvdW5kRXhjZXB0aW9uKGUpKSB7IHRocm93IGU7IH1cbiAgICAgIC8vIE9rYXlcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogTGlzdCBhbGwgcGFja2FnZXMgYW5kIG1hcmsgdGhlbSBhcyBcImFsbG93IHVwc3RyZWFtIHZlcnNpb25zXCIuXG4gICAqXG4gICAqIElmIHdlIGRvbid0IGRvIHRoaXMgYW5kIHdlIHB1Ymxpc2ggYGZvb0AyLjMuNC1yYy4wYCwgdGhlbiB3ZSBjYW4ndFxuICAgKiBkb3dubG9hZCBgZm9vQDIuMy4wYCBhbnltb3JlIGJlY2F1c2UgYnkgZGVmYXVsdCBDb2RlQXJ0aWZhY3Qgd2lsbFxuICAgKiBibG9jayBkaWZmZXJlbnQgdmVyc2lvbnMgZnJvbSB0aGUgc2FtZSBwYWNrYWdlLlxuICAgKi9cbiAgcHVibGljIGFzeW5jIG1hcmtBbGxVcHN0cmVhbUFsbG93KCkge1xuICAgIGZvciBhd2FpdCAoY29uc3QgcGtnIG9mIHRoaXMubGlzdFBhY2thZ2VzKHsgdXBzdHJlYW06ICdCTE9DSycgfSkpIHtcbiAgICAgIGF3YWl0IHRoaXMuc2VuZChuZXcgUHV0UGFja2FnZU9yaWdpbkNvbmZpZ3VyYXRpb25Db21tYW5kKHtcbiAgICAgICAgZG9tYWluOiB0aGlzLmRvbWFpbixcbiAgICAgICAgcmVwb3NpdG9yeTogdGhpcy5yZXBvc2l0b3J5TmFtZSxcblxuICAgICAgICBmb3JtYXQ6IHBrZy5mb3JtYXQhLFxuICAgICAgICBwYWNrYWdlOiBwa2cucGFja2FnZSEsXG4gICAgICAgIG5hbWVzcGFjZTogcGtnLm5hbWVzcGFjZSEsXG4gICAgICAgIHJlc3RyaWN0aW9uczoge1xuICAgICAgICAgIHB1Ymxpc2g6ICdBTExPVycsXG4gICAgICAgICAgdXBzdHJlYW06ICdBTExPVycsXG4gICAgICAgIH0sXG4gICAgICB9KSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBlbnN1cmVEb21haW4oKSB7XG4gICAgaWYgKGF3YWl0IHRoaXMuZG9tYWluRXhpc3RzKCkpIHsgcmV0dXJuOyB9XG4gICAgYXdhaXQgdGhpcy5zZW5kKG5ldyBDcmVhdGVEb21haW5Db21tYW5kKHtcbiAgICAgIGRvbWFpbjogdGhpcy5kb21haW4sXG4gICAgICB0YWdzOiBbeyBrZXk6ICd0ZXN0aW5nJywgdmFsdWU6ICd0cnVlJyB9XSxcbiAgICB9KSk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGVuc3VyZVVwc3RyZWFtcygpIHtcbiAgICBhd2FpdCB0aGlzLmVuc3VyZVJlcG9zaXRvcnkodGhpcy5ucG1VcHN0cmVhbSwge1xuICAgICAgZGVzY3JpcHRpb246ICdUaGUgdXBzdHJlYW0gcmVwb3NpdG9yeSBmb3IgTlBNJyxcbiAgICAgIGV4dGVybmFsOiAncHVibGljOm5wbWpzJyxcbiAgICB9KTtcbiAgICBhd2FpdCB0aGlzLmVuc3VyZVJlcG9zaXRvcnkodGhpcy5tYXZlblVwc3RyZWFtLCB7XG4gICAgICBkZXNjcmlwdGlvbjogJ1RoZSB1cHN0cmVhbSByZXBvc2l0b3J5IGZvciBNYXZlbicsXG4gICAgICBleHRlcm5hbDogJ3B1YmxpYzptYXZlbi1jZW50cmFsJyxcbiAgICB9KTtcbiAgICBhd2FpdCB0aGlzLmVuc3VyZVJlcG9zaXRvcnkodGhpcy5udWdldFVwc3RyZWFtLCB7XG4gICAgICBkZXNjcmlwdGlvbjogJ1RoZSB1cHN0cmVhbSByZXBvc2l0b3J5IGZvciBOdUdldCcsXG4gICAgICBleHRlcm5hbDogJ3B1YmxpYzpudWdldC1vcmcnLFxuICAgIH0pO1xuICAgIGF3YWl0IHRoaXMuZW5zdXJlUmVwb3NpdG9yeSh0aGlzLnB5cGlVcHN0cmVhbSwge1xuICAgICAgZGVzY3JpcHRpb246ICdUaGUgdXBzdHJlYW0gcmVwb3NpdG9yeSBmb3IgUHlQSScsXG4gICAgICBleHRlcm5hbDogJ3B1YmxpYzpweXBpJyxcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgZW5zdXJlUmVwb3NpdG9yeShuYW1lOiBzdHJpbmcsIG9wdGlvbnM/OiB7XG4gICAgcmVhZG9ubHkgZGVzY3JpcHRpb24/OiBzdHJpbmc7XG4gICAgcmVhZG9ubHkgZXh0ZXJuYWw/OiBzdHJpbmc7XG4gICAgcmVhZG9ubHkgdXBzdHJlYW1zPzogc3RyaW5nW107XG4gICAgcmVhZG9ubHkgdGFncz86IFJlY29yZDxzdHJpbmcsIHN0cmluZz47XG4gIH0pIHtcbiAgICBpZiAoYXdhaXQgdGhpcy5yZXBvc2l0b3J5RXhpc3RzKG5hbWUpKSB7IHJldHVybjsgfVxuXG4gICAgYXdhaXQgdGhpcy5zZW5kKG5ldyBDcmVhdGVSZXBvc2l0b3J5Q29tbWFuZCh7XG4gICAgICBkb21haW46IHRoaXMuZG9tYWluLFxuICAgICAgcmVwb3NpdG9yeTogbmFtZSxcbiAgICAgIGRlc2NyaXB0aW9uOiBvcHRpb25zPy5kZXNjcmlwdGlvbixcbiAgICAgIHVwc3RyZWFtczogb3B0aW9ucz8udXBzdHJlYW1zPy5tYXAocmVwb3NpdG9yeU5hbWUgPT4gKHsgcmVwb3NpdG9yeU5hbWUgfSkpLFxuICAgICAgdGFnczogb3B0aW9ucz8udGFncyA/IE9iamVjdC5lbnRyaWVzKG9wdGlvbnMudGFncykubWFwKChba2V5LCB2YWx1ZV0pID0+ICh7IGtleSwgdmFsdWUgfSkpIDogdW5kZWZpbmVkLFxuICAgIH0pKTtcblxuICAgIGlmIChvcHRpb25zPy5leHRlcm5hbCkge1xuICAgICAgY29uc3QgZXh0ZXJuYWxDb25uZWN0aW9uID0gb3B0aW9ucy5leHRlcm5hbDtcbiAgICAgIGF3YWl0IHJldHJ5KCgpID0+IHRoaXMuc2VuZChuZXcgQXNzb2NpYXRlRXh0ZXJuYWxDb25uZWN0aW9uQ29tbWFuZCh7XG4gICAgICAgIGRvbWFpbjogdGhpcy5kb21haW4sXG4gICAgICAgIHJlcG9zaXRvcnk6IG5hbWUsXG4gICAgICAgIGV4dGVybmFsQ29ubmVjdGlvbixcbiAgICAgIH0pKSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBkb21haW5FeGlzdHMoKSB7XG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IHRoaXMuc2VuZChuZXcgRGVzY3JpYmVEb21haW5Db21tYW5kKHsgZG9tYWluOiB0aGlzLmRvbWFpbiB9KSk7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICAgIGlmICghaXNSZXNvdXJjZU5vdEZvdW5kRXhjZXB0aW9uKGUpKSB7IHRocm93IGU7IH1cbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHJlcG9zaXRvcnlFeGlzdHMobmFtZTogc3RyaW5nKSB7XG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IHRoaXMuc2VuZChuZXcgRGVzY3JpYmVSZXBvc2l0b3J5Q29tbWFuZCh7IGRvbWFpbjogdGhpcy5kb21haW4sIHJlcG9zaXRvcnk6IG5hbWUgfSkpO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBjYXRjaCAoZTogYW55KSB7XG4gICAgICBpZiAoIWlzUmVzb3VyY2VOb3RGb3VuZEV4Y2VwdGlvbihlKSkgeyB0aHJvdyBlOyB9XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyogbGlzdFBhY2thZ2VzKGZpbHRlcjogUGljazxMaXN0UGFja2FnZXNDb21tYW5kSW5wdXQsICd1cHN0cmVhbSd8J3B1Ymxpc2gnfCdmb3JtYXQnPiA9IHt9KSB7XG4gICAgbGV0IHJlc3BvbnNlID0gYXdhaXQgdGhpcy5zZW5kKG5ldyBMaXN0UGFja2FnZXNDb21tYW5kKHtcbiAgICAgIGRvbWFpbjogdGhpcy5kb21haW4sXG4gICAgICByZXBvc2l0b3J5OiB0aGlzLnJlcG9zaXRvcnlOYW1lLFxuICAgICAgLi4uZmlsdGVyLFxuICAgIH0pKTtcblxuICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICBmb3IgKGNvbnN0IHAgb2YgcmVzcG9uc2UucGFja2FnZXMgPz8gW10pIHtcbiAgICAgICAgeWllbGQgcDtcbiAgICAgIH1cblxuICAgICAgaWYgKCFyZXNwb25zZS5uZXh0VG9rZW4pIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICAgIHJlc3BvbnNlID0gYXdhaXQgdGhpcy5zZW5kKG5ldyBMaXN0UGFja2FnZXNDb21tYW5kKHtcbiAgICAgICAgZG9tYWluOiB0aGlzLmRvbWFpbixcbiAgICAgICAgcmVwb3NpdG9yeTogdGhpcy5yZXBvc2l0b3J5TmFtZSxcbiAgICAgICAgLi4uZmlsdGVyLFxuICAgICAgICBuZXh0VG9rZW46IHJlc3BvbnNlLm5leHRUb2tlbixcbiAgICAgIH0pKTtcbiAgICB9XG4gIH1cbn1cblxuYXN5bmMgZnVuY3Rpb24gcmV0cnk8QT4oYmxvY2s6ICgpID0+IFByb21pc2U8QT4pIHtcbiAgbGV0IGF0dGVtcHRzID0gMztcbiAgd2hpbGUgKHRydWUpIHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIGF3YWl0IGJsb2NrKCk7XG4gICAgfSBjYXRjaCAoZTogYW55KSB7XG4gICAgICBpZiAoYXR0ZW1wdHMtLSA9PT0gMCkgeyB0aHJvdyBlOyB9XG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tY29uc29sZVxuICAgICAgY29uc29sZS5kZWJ1ZyhlLm1lc3NhZ2UpO1xuICAgICAgYXdhaXQgc2xlZXAoNTAwKTtcbiAgICB9XG4gIH1cbn1cblxuYXN5bmMgZnVuY3Rpb24gcmV0cnlUaHJvdHRsZWQ8QT4oYmxvY2s6ICgpID0+IFByb21pc2U8QT4pIHtcbiAgbGV0IHRpbWUgPSAxMDA7XG4gIGxldCBhdHRlbXB0cyA9IDE1O1xuICB3aGlsZSAodHJ1ZSkge1xuICAgIHRyeSB7XG4gICAgICByZXR1cm4gYXdhaXQgYmxvY2soKTtcbiAgICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zb2xlXG4gICAgICBjb25zb2xlLmRlYnVnKGUpO1xuXG4gICAgICBpZiAoIShlIGluc3RhbmNlb2YgVGhyb3R0bGluZ0V4Y2VwdGlvbikgfHwgLS1hdHRlbXB0cyA9PT0gMCkge1xuICAgICAgICB0aHJvdyBlO1xuICAgICAgfVxuXG4gICAgICBhd2FpdCBzbGVlcChNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiB0aW1lKSk7XG4gICAgICB0aW1lICo9IDI7XG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgTG9naW5JbmZvcm1hdGlvbiB7XG4gIHJlYWRvbmx5IGF1dGhUb2tlbjogc3RyaW5nO1xuICByZWFkb25seSBleHBpcmF0aW9uVGltZU1zOiBudW1iZXI7XG4gIHJlYWRvbmx5IHJlcG9zaXRvcnlOYW1lOiBzdHJpbmc7XG4gIHJlYWRvbmx5IG5wbUVuZHBvaW50OiBzdHJpbmc7XG4gIHJlYWRvbmx5IG1hdmVuRW5kcG9pbnQ6IHN0cmluZztcbiAgcmVhZG9ubHkgbnVnZXRFbmRwb2ludDogc3RyaW5nO1xuICByZWFkb25seSBweXBpRW5kcG9pbnQ6IHN0cmluZztcbn1cblxuZnVuY3Rpb24gaXNSZXNvdXJjZU5vdEZvdW5kRXhjZXB0aW9uKHg6IGFueSk6IHggaXMgUmVzb3VyY2VOb3RGb3VuZEV4Y2VwdGlvbiB7XG4gIHJldHVybiB4IGluc3RhbmNlb2YgUmVzb3VyY2VOb3RGb3VuZEV4Y2VwdGlvbjtcbn1cbiJdfQ==