@aws-cdk-testing/cli-integ
Version:
Integration tests for the AWS CDK CLI
135 lines • 16.7 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.atmosphereEnabled = atmosphereEnabled;
exports.atmosphereEndpoint = atmosphereEndpoint;
exports.atmospherePool = atmospherePool;
exports.withAws = withAws;
exports.regionPool = regionPool;
const cdk_atmosphere_client_1 = require("@cdklabs/cdk-atmosphere-client");
const aws_1 = require("./aws");
const resource_pool_1 = require("./resource-pool");
function atmosphereEnabled() {
const enabled = process.env.CDK_INTEG_ATMOSPHERE_ENABLED;
return enabled === 'true' || enabled === '1';
}
function atmosphereEndpoint() {
const value = process.env.CDK_INTEG_ATMOSPHERE_ENDPOINT;
if (!value) {
throw new Error('CDK_INTEG_ATMOSPHERE_ENDPOINT is not defined');
}
return value;
}
function atmospherePool() {
const value = process.env.CDK_INTEG_ATMOSPHERE_POOL;
if (!value) {
throw new Error('CDK_INTEG_ATMOSPHERE_POOL is not defined');
}
return value;
}
/**
* Higher order function to execute a block with an AWS client setup
*
* Allocate the next region from the REGION pool and dispose it afterwards.
*/
function withAws(block, options = {}) {
// Set a high Jest timeout because it includes the time waiting for locks; account for worst-case single-threaded runtime.
// This is not the actual test execution time. The effective test timeout is handled by withTimeout().
jest.setTimeout(2 * 60 * 60_000);
return async (context) => {
const disableBootstrap = options.disableBootstrap ?? false;
if (atmosphereEnabled()) {
const atmosphere = new cdk_atmosphere_client_1.AtmosphereClient(atmosphereEndpoint(), {
logStream: context.output,
});
const constraints = [];
if (options.regions) {
constraints.push({
type: 'region',
value: [...options.regions],
});
}
const start = Date.now();
const allocation = await atmosphere.acquire({
pool: atmospherePool(),
requester: context.name,
timeoutSeconds: 60 * 30,
constraints,
});
let outcome = 'success';
context.reportWaitTime(Date.now() - start);
try {
const aws = await aws_1.AwsClients.forIdentity(context.randomString, allocation.environment.region, {
accessKeyId: allocation.credentials.accessKeyId,
secretAccessKey: allocation.credentials.secretAccessKey,
sessionToken: allocation.credentials.sessionToken,
accountId: allocation.environment.account,
}, context.output);
await sanityCheck(aws);
try {
return await block({ ...context, disableBootstrap, aws });
}
catch (e) {
outcome = 'failure';
throw e;
}
finally {
await aws.dispose();
}
}
finally {
await atmosphere.release(allocation.id, outcome);
}
}
else {
return regionPool().using(async (region) => {
const aws = await aws_1.AwsClients.forRegion(context.randomString, region, context.output);
try {
await sanityCheck(aws);
return await block({ ...context, disableBootstrap, aws });
}
finally {
await aws.dispose();
}
});
}
};
}
let _regionPool;
function regionPool() {
if (_regionPool !== undefined) {
return _regionPool;
}
const REGIONS = process.env.AWS_REGIONS
? process.env.AWS_REGIONS.split(',')
: [process.env.AWS_REGION ?? process.env.AWS_DEFAULT_REGION ?? 'us-east-1'];
_regionPool = resource_pool_1.ResourcePool.withResources('aws_regions', REGIONS);
return _regionPool;
}
/**
* Perform a one-time quick sanity check that the AWS clients have properly configured credentials
*
* If we don't do this, calls are going to fail and they'll be retried and everything will take
* forever before the user notices a simple misconfiguration.
*
* We can't check for the presence of environment variables since credentials could come from
* anywhere, so do simple account retrieval.
*
* Only do it once per process.
*/
async function sanityCheck(aws) {
if (sanityChecked === undefined) {
try {
await aws.account();
sanityChecked = true;
}
catch (e) {
sanityChecked = false;
throw new Error(`AWS credentials probably not configured, got error: ${e.message}`);
}
}
if (!sanityChecked) {
throw new Error('AWS credentials probably not configured, see previous error');
}
}
let sanityChecked;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2l0aC1hd3MuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJ3aXRoLWF3cy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQU9BLDhDQUdDO0FBRUQsZ0RBTUM7QUFFRCx3Q0FNQztBQXlCRCwwQkFtRUM7QUFHRCxnQ0FXQztBQW5JRCwwRUFBa0U7QUFDbEUsK0JBQW1DO0FBRW5DLG1EQUErQztBQUcvQyxTQUFnQixpQkFBaUI7SUFDL0IsTUFBTSxPQUFPLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyw0QkFBNEIsQ0FBQztJQUN6RCxPQUFPLE9BQU8sS0FBSyxNQUFNLElBQUksT0FBTyxLQUFLLEdBQUcsQ0FBQztBQUMvQyxDQUFDO0FBRUQsU0FBZ0Isa0JBQWtCO0lBQ2hDLE1BQU0sS0FBSyxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsNkJBQTZCLENBQUM7SUFDeEQsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ1gsTUFBTSxJQUFJLEtBQUssQ0FBQyw4Q0FBOEMsQ0FBQyxDQUFDO0lBQ2xFLENBQUM7SUFDRCxPQUFPLEtBQUssQ0FBQztBQUNmLENBQUM7QUFFRCxTQUFnQixjQUFjO0lBQzVCLE1BQU0sS0FBSyxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMseUJBQXlCLENBQUM7SUFDcEQsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ1gsTUFBTSxJQUFJLEtBQUssQ0FBQywwQ0FBMEMsQ0FBQyxDQUFDO0lBQzlELENBQUM7SUFDRCxPQUFPLEtBQUssQ0FBQztBQUNmLENBQUM7QUFvQkQ7Ozs7R0FJRztBQUNILFNBQWdCLE9BQU8sQ0FDckIsS0FBMkUsRUFDM0UsVUFBNkIsRUFBRTtJQUUvQiwwSEFBMEg7SUFDMUgsc0dBQXNHO0lBQ3RHLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxNQUFNLENBQUMsQ0FBQztJQUVqQyxPQUFPLEtBQUssRUFBRSxPQUFVLEVBQUUsRUFBRTtRQUMxQixNQUFNLGdCQUFnQixHQUFHLE9BQU8sQ0FBQyxnQkFBZ0IsSUFBSSxLQUFLLENBQUM7UUFFM0QsSUFBSSxpQkFBaUIsRUFBRSxFQUFFLENBQUM7WUFDeEIsTUFBTSxVQUFVLEdBQUcsSUFBSSx3Q0FBZ0IsQ0FBQyxrQkFBa0IsRUFBRSxFQUFFO2dCQUM1RCxTQUFTLEVBQUUsT0FBTyxDQUFDLE1BQU07YUFDMUIsQ0FBQyxDQUFDO1lBRUgsTUFBTSxXQUFXLEdBQWlCLEVBQUUsQ0FBQztZQUNyQyxJQUFJLE9BQU8sQ0FBQyxPQUFPLEVBQUUsQ0FBQztnQkFDcEIsV0FBVyxDQUFDLElBQUksQ0FBQztvQkFDZixJQUFJLEVBQUUsUUFBUTtvQkFDZCxLQUFLLEVBQUUsQ0FBQyxHQUFHLE9BQU8sQ0FBQyxPQUFPLENBQUM7aUJBQzVCLENBQUMsQ0FBQztZQUNMLENBQUM7WUFFRCxNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUM7WUFDekIsTUFBTSxVQUFVLEdBQUcsTUFBTSxVQUFVLENBQUMsT0FBTyxDQUFDO2dCQUMxQyxJQUFJLEVBQUUsY0FBYyxFQUFFO2dCQUN0QixTQUFTLEVBQUUsT0FBTyxDQUFDLElBQUk7Z0JBQ3ZCLGNBQWMsRUFBRSxFQUFFLEdBQUcsRUFBRTtnQkFDdkIsV0FBVzthQUNaLENBQUMsQ0FBQztZQUNILElBQUksT0FBTyxHQUFHLFNBQVMsQ0FBQztZQUN4QixPQUFPLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsR0FBRyxLQUFLLENBQUMsQ0FBQztZQUUzQyxJQUFJLENBQUM7Z0JBQ0gsTUFBTSxHQUFHLEdBQUcsTUFBTSxnQkFBVSxDQUFDLFdBQVcsQ0FBQyxPQUFPLENBQUMsWUFBWSxFQUFFLFVBQVUsQ0FBQyxXQUFXLENBQUMsTUFBTSxFQUFFO29CQUM1RixXQUFXLEVBQUUsVUFBVSxDQUFDLFdBQVcsQ0FBQyxXQUFXO29CQUMvQyxlQUFlLEVBQUUsVUFBVSxDQUFDLFdBQVcsQ0FBQyxlQUFlO29CQUN2RCxZQUFZLEVBQUUsVUFBVSxDQUFDLFdBQVcsQ0FBQyxZQUFZO29CQUNqRCxTQUFTLEVBQUUsVUFBVSxDQUFDLFdBQVcsQ0FBQyxPQUFPO2lCQUMxQyxFQUFFLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQztnQkFDbkIsTUFBTSxXQUFXLENBQUMsR0FBRyxDQUFDLENBQUM7Z0JBRXZCLElBQUksQ0FBQztvQkFDSCxPQUFPLE1BQU0sS0FBSyxDQUFDLEVBQUUsR0FBRyxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsR0FBRyxFQUFFLENBQUMsQ0FBQztnQkFDNUQsQ0FBQztnQkFBQyxPQUFPLENBQU0sRUFBRSxDQUFDO29CQUNoQixPQUFPLEdBQUcsU0FBUyxDQUFDO29CQUNwQixNQUFNLENBQUMsQ0FBQztnQkFDVixDQUFDO3dCQUFTLENBQUM7b0JBQ1QsTUFBTSxHQUFHLENBQUMsT0FBTyxFQUFFLENBQUM7Z0JBQ3RCLENBQUM7WUFDSCxDQUFDO29CQUFTLENBQUM7Z0JBQ1QsTUFBTSxVQUFVLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxFQUFFLEVBQUUsT0FBTyxDQUFDLENBQUM7WUFDbkQsQ0FBQztRQUNILENBQUM7YUFBTSxDQUFDO1lBQ04sT0FBTyxVQUFVLEVBQUUsQ0FBQyxLQUFLLENBQUMsS0FBSyxFQUFFLE1BQU0sRUFBRSxFQUFFO2dCQUN6QyxNQUFNLEdBQUcsR0FBRyxNQUFNLGdCQUFVLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxZQUFZLEVBQUUsTUFBTSxFQUFFLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQztnQkFDckYsSUFBSSxDQUFDO29CQUNILE1BQU0sV0FBVyxDQUFDLEdBQUcsQ0FBQyxDQUFDO29CQUV2QixPQUFPLE1BQU0sS0FBSyxDQUFDLEVBQUUsR0FBRyxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsR0FBRyxFQUFFLENBQUMsQ0FBQztnQkFDNUQsQ0FBQzt3QkFBUyxDQUFDO29CQUNULE1BQU0sR0FBRyxDQUFDLE9BQU8sRUFBRSxDQUFDO2dCQUN0QixDQUFDO1lBQ0gsQ0FBQyxDQUFDLENBQUM7UUFDTCxDQUFDO0lBQ0gsQ0FBQyxDQUFDO0FBQ0osQ0FBQztBQUVELElBQUksV0FBcUMsQ0FBQztBQUMxQyxTQUFnQixVQUFVO0lBQ3hCLElBQUksV0FBVyxLQUFLLFNBQVMsRUFBRSxDQUFDO1FBQzlCLE9BQU8sV0FBVyxDQUFDO0lBQ3JCLENBQUM7SUFFRCxNQUFNLE9BQU8sR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLFdBQVc7UUFDckMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUM7UUFDcEMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxVQUFVLElBQUksT0FBTyxDQUFDLEdBQUcsQ0FBQyxrQkFBa0IsSUFBSSxXQUFXLENBQUMsQ0FBQztJQUU5RSxXQUFXLEdBQUcsNEJBQVksQ0FBQyxhQUFhLENBQUMsYUFBYSxFQUFFLE9BQU8sQ0FBQyxDQUFDO0lBQ2pFLE9BQU8sV0FBVyxDQUFDO0FBQ3JCLENBQUM7QUFFRDs7Ozs7Ozs7OztHQVVHO0FBQ0gsS0FBSyxVQUFVLFdBQVcsQ0FBQyxHQUFlO0lBQ3hDLElBQUksYUFBYSxLQUFLLFNBQVMsRUFBRSxDQUFDO1FBQ2hDLElBQUksQ0FBQztZQUNILE1BQU0sR0FBRyxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQ3BCLGFBQWEsR0FBRyxJQUFJLENBQUM7UUFDdkIsQ0FBQztRQUFDLE9BQU8sQ0FBTSxFQUFFLENBQUM7WUFDaEIsYUFBYSxHQUFHLEtBQUssQ0FBQztZQUN0QixNQUFNLElBQUksS0FBSyxDQUFDLHVEQUF1RCxDQUFDLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQztRQUN0RixDQUFDO0lBQ0gsQ0FBQztJQUNELElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztRQUNuQixNQUFNLElBQUksS0FBSyxDQUFDLDZEQUE2RCxDQUFDLENBQUM7SUFDakYsQ0FBQztBQUNILENBQUM7QUFDRCxJQUFJLGFBQWtDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgdHlwZSB7IENvbnN0cmFpbnQgfSBmcm9tICdAY2RrbGFicy9jZGstYXRtb3NwaGVyZS1jbGllbnQnO1xuaW1wb3J0IHsgQXRtb3NwaGVyZUNsaWVudCB9IGZyb20gJ0BjZGtsYWJzL2Nkay1hdG1vc3BoZXJlLWNsaWVudCc7XG5pbXBvcnQgeyBBd3NDbGllbnRzIH0gZnJvbSAnLi9hd3MnO1xuaW1wb3J0IHR5cGUgeyBUZXN0Q29udGV4dCB9IGZyb20gJy4vaW50ZWctdGVzdCc7XG5pbXBvcnQgeyBSZXNvdXJjZVBvb2wgfSBmcm9tICcuL3Jlc291cmNlLXBvb2wnO1xuaW1wb3J0IHR5cGUgeyBEaXNhYmxlQm9vdHN0cmFwQ29udGV4dCB9IGZyb20gJy4vd2l0aC1jZGstYXBwJztcblxuZXhwb3J0IGZ1bmN0aW9uIGF0bW9zcGhlcmVFbmFibGVkKCk6IGJvb2xlYW4ge1xuICBjb25zdCBlbmFibGVkID0gcHJvY2Vzcy5lbnYuQ0RLX0lOVEVHX0FUTU9TUEhFUkVfRU5BQkxFRDtcbiAgcmV0dXJuIGVuYWJsZWQgPT09ICd0cnVlJyB8fCBlbmFibGVkID09PSAnMSc7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhdG1vc3BoZXJlRW5kcG9pbnQoKTogc3RyaW5nIHtcbiAgY29uc3QgdmFsdWUgPSBwcm9jZXNzLmVudi5DREtfSU5URUdfQVRNT1NQSEVSRV9FTkRQT0lOVDtcbiAgaWYgKCF2YWx1ZSkge1xuICAgIHRocm93IG5ldyBFcnJvcignQ0RLX0lOVEVHX0FUTU9TUEhFUkVfRU5EUE9JTlQgaXMgbm90IGRlZmluZWQnKTtcbiAgfVxuICByZXR1cm4gdmFsdWU7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhdG1vc3BoZXJlUG9vbCgpIHtcbiAgY29uc3QgdmFsdWUgPSBwcm9jZXNzLmVudi5DREtfSU5URUdfQVRNT1NQSEVSRV9QT09MO1xuICBpZiAoIXZhbHVlKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdDREtfSU5URUdfQVRNT1NQSEVSRV9QT09MIGlzIG5vdCBkZWZpbmVkJyk7XG4gIH1cbiAgcmV0dXJuIHZhbHVlO1xufVxuXG5leHBvcnQgdHlwZSBBd3NDb250ZXh0ID0geyByZWFkb25seSBhd3M6IEF3c0NsaWVudHMgfTtcblxuZXhwb3J0IGludGVyZmFjZSBBd3NDb250ZXh0T3B0aW9ucyB7XG4gIC8qKlxuICAgKiBSZXF1ZXN0IHRoZSB0ZXN0IGVudmlyb25tZW50IHRvIGJlIGluIG9uZSBvZiB0aGVzZSByZWdpb25zXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gYWxsIHJlZ2lvbnMgYXJlIHBvc3NpYmxlXG4gICAqL1xuICByZWFkb25seSByZWdpb25zPzogc3RyaW5nW107XG5cbiAgLyoqXG4gICAqIERvIG5vdCBib290c3RyYXAgdGhlIGVudlxuICAgKlxuICAgKiBAZGVmYXVsdCBmYWxzZVxuICAgKi9cbiAgcmVhZG9ubHkgZGlzYWJsZUJvb3RzdHJhcD86IGJvb2xlYW47XG59XG5cbi8qKlxuICogSGlnaGVyIG9yZGVyIGZ1bmN0aW9uIHRvIGV4ZWN1dGUgYSBibG9jayB3aXRoIGFuIEFXUyBjbGllbnQgc2V0dXBcbiAqXG4gKiBBbGxvY2F0ZSB0aGUgbmV4dCByZWdpb24gZnJvbSB0aGUgUkVHSU9OIHBvb2wgYW5kIGRpc3Bvc2UgaXQgYWZ0ZXJ3YXJkcy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHdpdGhBd3M8QSBleHRlbmRzIFRlc3RDb250ZXh0PihcbiAgYmxvY2s6IChjb250ZXh0OiBBICYgQXdzQ29udGV4dCAmIERpc2FibGVCb290c3RyYXBDb250ZXh0KSA9PiBQcm9taXNlPHZvaWQ+LFxuICBvcHRpb25zOiBBd3NDb250ZXh0T3B0aW9ucyA9IHt9LFxuKTogKGNvbnRleHQ6IEEpID0+IFByb21pc2U8dm9pZD4ge1xuICAvLyBTZXQgYSBoaWdoIEplc3QgdGltZW91dCBiZWNhdXNlIGl0IGluY2x1ZGVzIHRoZSB0aW1lIHdhaXRpbmcgZm9yIGxvY2tzOyBhY2NvdW50IGZvciB3b3JzdC1jYXNlIHNpbmdsZS10aHJlYWRlZCBydW50aW1lLlxuICAvLyBUaGlzIGlzIG5vdCB0aGUgYWN0dWFsIHRlc3QgZXhlY3V0aW9uIHRpbWUuIFRoZSBlZmZlY3RpdmUgdGVzdCB0aW1lb3V0IGlzIGhhbmRsZWQgYnkgd2l0aFRpbWVvdXQoKS5cbiAgamVzdC5zZXRUaW1lb3V0KDIgKiA2MCAqIDYwXzAwMCk7XG5cbiAgcmV0dXJuIGFzeW5jIChjb250ZXh0OiBBKSA9PiB7XG4gICAgY29uc3QgZGlzYWJsZUJvb3RzdHJhcCA9IG9wdGlvbnMuZGlzYWJsZUJvb3RzdHJhcCA/PyBmYWxzZTtcblxuICAgIGlmIChhdG1vc3BoZXJlRW5hYmxlZCgpKSB7XG4gICAgICBjb25zdCBhdG1vc3BoZXJlID0gbmV3IEF0bW9zcGhlcmVDbGllbnQoYXRtb3NwaGVyZUVuZHBvaW50KCksIHtcbiAgICAgICAgbG9nU3RyZWFtOiBjb250ZXh0Lm91dHB1dCxcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCBjb25zdHJhaW50czogQ29uc3RyYWludFtdID0gW107XG4gICAgICBpZiAob3B0aW9ucy5yZWdpb25zKSB7XG4gICAgICAgIGNvbnN0cmFpbnRzLnB1c2goe1xuICAgICAgICAgIHR5cGU6ICdyZWdpb24nLFxuICAgICAgICAgIHZhbHVlOiBbLi4ub3B0aW9ucy5yZWdpb25zXSxcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHN0YXJ0ID0gRGF0ZS5ub3coKTtcbiAgICAgIGNvbnN0IGFsbG9jYXRpb24gPSBhd2FpdCBhdG1vc3BoZXJlLmFjcXVpcmUoe1xuICAgICAgICBwb29sOiBhdG1vc3BoZXJlUG9vbCgpLFxuICAgICAgICByZXF1ZXN0ZXI6IGNvbnRleHQubmFtZSxcbiAgICAgICAgdGltZW91dFNlY29uZHM6IDYwICogMzAsXG4gICAgICAgIGNvbnN0cmFpbnRzLFxuICAgICAgfSk7XG4gICAgICBsZXQgb3V0Y29tZSA9ICdzdWNjZXNzJztcbiAgICAgIGNvbnRleHQucmVwb3J0V2FpdFRpbWUoRGF0ZS5ub3coKSAtIHN0YXJ0KTtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgYXdzID0gYXdhaXQgQXdzQ2xpZW50cy5mb3JJZGVudGl0eShjb250ZXh0LnJhbmRvbVN0cmluZywgYWxsb2NhdGlvbi5lbnZpcm9ubWVudC5yZWdpb24sIHtcbiAgICAgICAgICBhY2Nlc3NLZXlJZDogYWxsb2NhdGlvbi5jcmVkZW50aWFscy5hY2Nlc3NLZXlJZCxcbiAgICAgICAgICBzZWNyZXRBY2Nlc3NLZXk6IGFsbG9jYXRpb24uY3JlZGVudGlhbHMuc2VjcmV0QWNjZXNzS2V5LFxuICAgICAgICAgIHNlc3Npb25Ub2tlbjogYWxsb2NhdGlvbi5jcmVkZW50aWFscy5zZXNzaW9uVG9rZW4sXG4gICAgICAgICAgYWNjb3VudElkOiBhbGxvY2F0aW9uLmVudmlyb25tZW50LmFjY291bnQsXG4gICAgICAgIH0sIGNvbnRleHQub3V0cHV0KTtcbiAgICAgICAgYXdhaXQgc2FuaXR5Q2hlY2soYXdzKTtcblxuICAgICAgICB0cnkge1xuICAgICAgICAgIHJldHVybiBhd2FpdCBibG9jayh7IC4uLmNvbnRleHQsIGRpc2FibGVCb290c3RyYXAsIGF3cyB9KTtcbiAgICAgICAgfSBjYXRjaCAoZTogYW55KSB7XG4gICAgICAgICAgb3V0Y29tZSA9ICdmYWlsdXJlJztcbiAgICAgICAgICB0aHJvdyBlO1xuICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgIGF3YWl0IGF3cy5kaXNwb3NlKCk7XG4gICAgICAgIH1cbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIGF3YWl0IGF0bW9zcGhlcmUucmVsZWFzZShhbGxvY2F0aW9uLmlkLCBvdXRjb21lKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHJlZ2lvblBvb2woKS51c2luZyhhc3luYyAocmVnaW9uKSA9PiB7XG4gICAgICAgIGNvbnN0IGF3cyA9IGF3YWl0IEF3c0NsaWVudHMuZm9yUmVnaW9uKGNvbnRleHQucmFuZG9tU3RyaW5nLCByZWdpb24sIGNvbnRleHQub3V0cHV0KTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBhd2FpdCBzYW5pdHlDaGVjayhhd3MpO1xuXG4gICAgICAgICAgcmV0dXJuIGF3YWl0IGJsb2NrKHsgLi4uY29udGV4dCwgZGlzYWJsZUJvb3RzdHJhcCwgYXdzIH0pO1xuICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgIGF3YWl0IGF3cy5kaXNwb3NlKCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cbiAgfTtcbn1cblxubGV0IF9yZWdpb25Qb29sOiB1bmRlZmluZWQgfCBSZXNvdXJjZVBvb2w7XG5leHBvcnQgZnVuY3Rpb24gcmVnaW9uUG9vbCgpOiBSZXNvdXJjZVBvb2wge1xuICBpZiAoX3JlZ2lvblBvb2wgIT09IHVuZGVmaW5lZCkge1xuICAgIHJldHVybiBfcmVnaW9uUG9vbDtcbiAgfVxuXG4gIGNvbnN0IFJFR0lPTlMgPSBwcm9jZXNzLmVudi5BV1NfUkVHSU9OU1xuICAgID8gcHJvY2Vzcy5lbnYuQVdTX1JFR0lPTlMuc3BsaXQoJywnKVxuICAgIDogW3Byb2Nlc3MuZW52LkFXU19SRUdJT04gPz8gcHJvY2Vzcy5lbnYuQVdTX0RFRkFVTFRfUkVHSU9OID8/ICd1cy1lYXN0LTEnXTtcblxuICBfcmVnaW9uUG9vbCA9IFJlc291cmNlUG9vbC53aXRoUmVzb3VyY2VzKCdhd3NfcmVnaW9ucycsIFJFR0lPTlMpO1xuICByZXR1cm4gX3JlZ2lvblBvb2w7XG59XG5cbi8qKlxuICogUGVyZm9ybSBhIG9uZS10aW1lIHF1aWNrIHNhbml0eSBjaGVjayB0aGF0IHRoZSBBV1MgY2xpZW50cyBoYXZlIHByb3Blcmx5IGNvbmZpZ3VyZWQgY3JlZGVudGlhbHNcbiAqXG4gKiBJZiB3ZSBkb24ndCBkbyB0aGlzLCBjYWxscyBhcmUgZ29pbmcgdG8gZmFpbCBhbmQgdGhleSdsbCBiZSByZXRyaWVkIGFuZCBldmVyeXRoaW5nIHdpbGwgdGFrZVxuICogZm9yZXZlciBiZWZvcmUgdGhlIHVzZXIgbm90aWNlcyBhIHNpbXBsZSBtaXNjb25maWd1cmF0aW9uLlxuICpcbiAqIFdlIGNhbid0IGNoZWNrIGZvciB0aGUgcHJlc2VuY2Ugb2YgZW52aXJvbm1lbnQgdmFyaWFibGVzIHNpbmNlIGNyZWRlbnRpYWxzIGNvdWxkIGNvbWUgZnJvbVxuICogYW55d2hlcmUsIHNvIGRvIHNpbXBsZSBhY2NvdW50IHJldHJpZXZhbC5cbiAqXG4gKiBPbmx5IGRvIGl0IG9uY2UgcGVyIHByb2Nlc3MuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIHNhbml0eUNoZWNrKGF3czogQXdzQ2xpZW50cykge1xuICBpZiAoc2FuaXR5Q2hlY2tlZCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IGF3cy5hY2NvdW50KCk7XG4gICAgICBzYW5pdHlDaGVja2VkID0gdHJ1ZTtcbiAgICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICAgIHNhbml0eUNoZWNrZWQgPSBmYWxzZTtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgQVdTIGNyZWRlbnRpYWxzIHByb2JhYmx5IG5vdCBjb25maWd1cmVkLCBnb3QgZXJyb3I6ICR7ZS5tZXNzYWdlfWApO1xuICAgIH1cbiAgfVxuICBpZiAoIXNhbml0eUNoZWNrZWQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0FXUyBjcmVkZW50aWFscyBwcm9iYWJseSBub3QgY29uZmlndXJlZCwgc2VlIHByZXZpb3VzIGVycm9yJyk7XG4gIH1cbn1cbmxldCBzYW5pdHlDaGVja2VkOiBib29sZWFuIHwgdW5kZWZpbmVkO1xuIl19