construct-hub 0.4.430 → 0.4.431

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/.jsii +9 -9
  2. package/docs/operator-runbook.md +45 -0
  3. package/lib/backend/package-stats/index.d.ts +15 -2
  4. package/lib/backend/package-stats/index.js +79 -21
  5. package/lib/backend/package-stats/package-stats-aggregator.d.ts +7 -0
  6. package/lib/backend/package-stats/package-stats-aggregator.js +20 -0
  7. package/lib/backend/package-stats/package-stats-aggregator.lambda.bundle/index.js +62489 -0
  8. package/lib/backend/package-stats/{package-stats.lambda.bundle → package-stats-aggregator.lambda.bundle}/index.js.map +4 -4
  9. package/lib/backend/package-stats/package-stats-aggregator.lambda.d.ts +13 -0
  10. package/lib/backend/package-stats/package-stats-aggregator.lambda.js +78 -0
  11. package/lib/backend/package-stats/package-stats-chunker.d.ts +7 -0
  12. package/lib/backend/package-stats/package-stats-chunker.js +20 -0
  13. package/lib/backend/package-stats/package-stats-chunker.lambda.bundle/index.js +60075 -0
  14. package/lib/backend/package-stats/package-stats-chunker.lambda.bundle/index.js.map +7 -0
  15. package/lib/backend/package-stats/package-stats-chunker.lambda.d.ts +6 -0
  16. package/lib/backend/package-stats/package-stats-chunker.lambda.js +25 -0
  17. package/lib/backend/package-stats/package-stats-processor.d.ts +7 -0
  18. package/lib/backend/package-stats/package-stats-processor.js +20 -0
  19. package/lib/backend/package-stats/{package-stats.lambda.bundle → package-stats-processor.lambda.bundle}/index.js +36 -2556
  20. package/lib/backend/package-stats/package-stats-processor.lambda.bundle/index.js.map +7 -0
  21. package/lib/backend/package-stats/package-stats-processor.lambda.d.ts +10 -0
  22. package/lib/backend/package-stats/package-stats-processor.lambda.js +41 -0
  23. package/lib/backend-dashboard.js +8 -6
  24. package/lib/construct-hub.d.ts +1 -1
  25. package/lib/construct-hub.js +12 -4
  26. package/lib/package-sources/code-artifact.js +1 -1
  27. package/lib/package-sources/npmjs.js +1 -1
  28. package/lib/package-tag/index.js +3 -3
  29. package/lib/package-tag-group/index.js +2 -2
  30. package/lib/preload-file/index.js +1 -1
  31. package/lib/s3/storage.js +1 -1
  32. package/lib/spdx-license.js +1 -1
  33. package/package.json +7 -3
  34. package/lib/backend/package-stats/package-stats.d.ts +0 -7
  35. package/lib/backend/package-stats/package-stats.js +0 -20
  36. package/lib/backend/package-stats/package-stats.lambda.d.ts +0 -25
  37. package/lib/backend/package-stats/package-stats.lambda.js +0 -79
@@ -1,79 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.handler = handler;
4
- const client_s3_1 = require("@aws-sdk/client-s3");
5
- const aws_embedded_metrics_1 = require("aws-embedded-metrics");
6
- const got_1 = require("got");
7
- const constants_1 = require("./constants");
8
- const npm_downloads_lambda_shared_1 = require("./npm-downloads.lambda-shared");
9
- const caching_1 = require("../../caching");
10
- const client_lambda_shared_1 = require("../catalog-builder/client.lambda-shared");
11
- const aws_lambda_shared_1 = require("../shared/aws.lambda-shared");
12
- const env_lambda_shared_1 = require("../shared/env.lambda-shared");
13
- /**
14
- * Rebuilds the `stats.json` object in the configured S3 bucket.
15
- * Validates that the number of packages on a full rebuild should not decrease
16
- * significantly (due to network errors from e.g. NPM) - can be ignored
17
- * by passing { ignoreValidation: true }.
18
- *
19
- * @param event configuration for the rebuild job.
20
- * @param context the lambda context in which this execution runs.
21
- *
22
- * @returns the information about the updated S3 object.
23
- */
24
- async function handler(event, context) {
25
- console.log(JSON.stringify(event, null, 2));
26
- const STATS_BUCKET_NAME = (0, env_lambda_shared_1.requireEnv)('STATS_BUCKET_NAME');
27
- const STATS_OBJECT_KEY = (0, env_lambda_shared_1.requireEnv)('STATS_OBJECT_KEY');
28
- const catalogClient = await client_lambda_shared_1.CatalogClient.newClient();
29
- const catalog = catalogClient.packages;
30
- if (catalog.length === 0) {
31
- throw new Error('No packages found.');
32
- }
33
- const currentDate = new Date().toISOString();
34
- const stats = { packages: {}, updated: currentDate };
35
- const npmClient = new npm_downloads_lambda_shared_1.NpmDownloadsClient(got_1.default);
36
- // remove duplicates from different major versions
37
- const packageNames = [...new Set(catalog.map((pkg) => pkg.name)).values()];
38
- console.log(`Retrieving download stats for all ${packageNames.length} registered packages: [${packageNames.join(',')}].`);
39
- const npmDownloads = await npmClient.getDownloads(packageNames, {
40
- period: npm_downloads_lambda_shared_1.NpmDownloadsPeriod.LAST_WEEK,
41
- throwErrors: false,
42
- });
43
- for (const [pkgName, entry] of npmDownloads.entries()) {
44
- updateStats(stats, pkgName, entry);
45
- }
46
- // Update metrics
47
- const statsCount = Object.keys(stats.packages).length;
48
- console.log(`There are now ${statsCount} packages with NPM stats stored.`);
49
- await (0, aws_embedded_metrics_1.metricScope)((metrics) => async () => {
50
- // Clear out default dimensions as we don't need those. See https://github.com/awslabs/aws-embedded-metrics-node/issues/73
51
- metrics.setDimensions({});
52
- metrics.setNamespace(constants_1.METRICS_NAMESPACE);
53
- metrics.putMetric("RegisteredPackagesWithStats" /* MetricName.REGISTERED_PACKAGES_WITH_STATS */, statsCount, aws_embedded_metrics_1.Unit.Count);
54
- })();
55
- // Upload the result to S3 and exit.
56
- return aws_lambda_shared_1.S3_CLIENT.send(new client_s3_1.PutObjectCommand({
57
- Bucket: STATS_BUCKET_NAME,
58
- Key: STATS_OBJECT_KEY,
59
- Body: JSON.stringify(stats, null, 2),
60
- ContentType: 'application/json',
61
- CacheControl: caching_1.CacheStrategy.default().toString(),
62
- Metadata: {
63
- 'Lambda-Log-Group': context.logGroupName,
64
- 'Lambda-Log-Stream': context.logStreamName,
65
- 'Lambda-Run-Id': context.awsRequestId,
66
- 'Package-Stats-Count': `${statsCount}`,
67
- },
68
- }));
69
- }
70
- function updateStats(stats, pkgName, entry) {
71
- stats.packages[pkgName] = {
72
- ...(stats.packages[pkgName] ?? {}),
73
- downloads: {
74
- ...(stats.packages[pkgName]?.downloads ?? {}),
75
- npm: entry.downloads,
76
- },
77
- };
78
- }
79
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFja2FnZS1zdGF0cy5sYW1iZGEuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvYmFja2VuZC9wYWNrYWdlLXN0YXRzL3BhY2thZ2Utc3RhdHMubGFtYmRhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBMEJBLDBCQWdFQztBQTFGRCxrREFBc0Q7QUFDdEQsK0RBQXlEO0FBRXpELDZCQUFzQjtBQUN0QiwyQ0FBNEQ7QUFDNUQsK0VBSXVDO0FBQ3ZDLDJDQUE4QztBQUM5QyxrRkFBd0U7QUFDeEUsbUVBQXdEO0FBQ3hELG1FQUF5RDtBQUV6RDs7Ozs7Ozs7OztHQVVHO0FBQ0ksS0FBSyxVQUFVLE9BQU8sQ0FBQyxLQUFVLEVBQUUsT0FBZ0I7SUFDeEQsT0FBTyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUU1QyxNQUFNLGlCQUFpQixHQUFHLElBQUEsOEJBQVUsRUFBQyxtQkFBbUIsQ0FBQyxDQUFDO0lBQzFELE1BQU0sZ0JBQWdCLEdBQUcsSUFBQSw4QkFBVSxFQUFDLGtCQUFrQixDQUFDLENBQUM7SUFFeEQsTUFBTSxhQUFhLEdBQUcsTUFBTSxvQ0FBYSxDQUFDLFNBQVMsRUFBRSxDQUFDO0lBQ3RELE1BQU0sT0FBTyxHQUFHLGFBQWEsQ0FBQyxRQUFRLENBQUM7SUFDdkMsSUFBSSxPQUFPLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxDQUFDO1FBQ3pCLE1BQU0sSUFBSSxLQUFLLENBQUMsb0JBQW9CLENBQUMsQ0FBQztJQUN4QyxDQUFDO0lBRUQsTUFBTSxXQUFXLEdBQUcsSUFBSSxJQUFJLEVBQUUsQ0FBQyxXQUFXLEVBQUUsQ0FBQztJQUM3QyxNQUFNLEtBQUssR0FBdUIsRUFBRSxRQUFRLEVBQUUsRUFBRSxFQUFFLE9BQU8sRUFBRSxXQUFXLEVBQUUsQ0FBQztJQUN6RSxNQUFNLFNBQVMsR0FBRyxJQUFJLGdEQUFrQixDQUFDLGFBQUcsQ0FBQyxDQUFDO0lBRTlDLGtEQUFrRDtJQUNsRCxNQUFNLFlBQVksR0FBRyxDQUFDLEdBQUcsSUFBSSxHQUFHLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQztJQUUzRSxPQUFPLENBQUMsR0FBRyxDQUNULHFDQUNFLFlBQVksQ0FBQyxNQUNmLDBCQUEwQixZQUFZLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQ3JELENBQUM7SUFDRixNQUFNLFlBQVksR0FBRyxNQUFNLFNBQVMsQ0FBQyxZQUFZLENBQUMsWUFBWSxFQUFFO1FBQzlELE1BQU0sRUFBRSxnREFBa0IsQ0FBQyxTQUFTO1FBQ3BDLFdBQVcsRUFBRSxLQUFLO0tBQ25CLENBQUMsQ0FBQztJQUVILEtBQUssTUFBTSxDQUFDLE9BQU8sRUFBRSxLQUFLLENBQUMsSUFBSSxZQUFZLENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FBQztRQUN0RCxXQUFXLENBQUMsS0FBSyxFQUFFLE9BQU8sRUFBRSxLQUFLLENBQUMsQ0FBQztJQUNyQyxDQUFDO0lBRUQsaUJBQWlCO0lBQ2pCLE1BQU0sVUFBVSxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDLE1BQU0sQ0FBQztJQUN0RCxPQUFPLENBQUMsR0FBRyxDQUFDLGlCQUFpQixVQUFVLGtDQUFrQyxDQUFDLENBQUM7SUFDM0UsTUFBTSxJQUFBLGtDQUFXLEVBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDLEtBQUssSUFBSSxFQUFFO1FBQ3hDLDBIQUEwSDtRQUMxSCxPQUFPLENBQUMsYUFBYSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBRTFCLE9BQU8sQ0FBQyxZQUFZLENBQUMsNkJBQWlCLENBQUMsQ0FBQztRQUN4QyxPQUFPLENBQUMsU0FBUyxnRkFFZixVQUFVLEVBQ1YsMkJBQUksQ0FBQyxLQUFLLENBQ1gsQ0FBQztJQUNKLENBQUMsQ0FBQyxFQUFFLENBQUM7SUFFTCxvQ0FBb0M7SUFDcEMsT0FBTyw2QkFBUyxDQUFDLElBQUksQ0FDbkIsSUFBSSw0QkFBZ0IsQ0FBQztRQUNuQixNQUFNLEVBQUUsaUJBQWlCO1FBQ3pCLEdBQUcsRUFBRSxnQkFBZ0I7UUFDckIsSUFBSSxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7UUFDcEMsV0FBVyxFQUFFLGtCQUFrQjtRQUMvQixZQUFZLEVBQUUsdUJBQWEsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxRQUFRLEVBQUU7UUFDaEQsUUFBUSxFQUFFO1lBQ1Isa0JBQWtCLEVBQUUsT0FBTyxDQUFDLFlBQVk7WUFDeEMsbUJBQW1CLEVBQUUsT0FBTyxDQUFDLGFBQWE7WUFDMUMsZUFBZSxFQUFFLE9BQU8sQ0FBQyxZQUFZO1lBQ3JDLHFCQUFxQixFQUFFLEdBQUcsVUFBVSxFQUFFO1NBQ3ZDO0tBQ0YsQ0FBQyxDQUNILENBQUM7QUFDSixDQUFDO0FBRUQsU0FBUyxXQUFXLENBQ2xCLEtBQXlCLEVBQ3pCLE9BQWUsRUFDZixLQUF3QjtJQUV4QixLQUFLLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxHQUFHO1FBQ3hCLEdBQUcsQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUNsQyxTQUFTLEVBQUU7WUFDVCxHQUFHLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsRUFBRSxTQUFTLElBQUksRUFBRSxDQUFDO1lBQzdDLEdBQUcsRUFBRSxLQUFLLENBQUMsU0FBUztTQUNyQjtLQUNGLENBQUM7QUFDSixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgUHV0T2JqZWN0Q29tbWFuZCB9IGZyb20gJ0Bhd3Mtc2RrL2NsaWVudC1zMyc7XG5pbXBvcnQgeyBtZXRyaWNTY29wZSwgVW5pdCB9IGZyb20gJ2F3cy1lbWJlZGRlZC1tZXRyaWNzJztcbmltcG9ydCB0eXBlIHsgQ29udGV4dCB9IGZyb20gJ2F3cy1sYW1iZGEnO1xuaW1wb3J0IGdvdCBmcm9tICdnb3QnO1xuaW1wb3J0IHsgTWV0cmljTmFtZSwgTUVUUklDU19OQU1FU1BBQ0UgfSBmcm9tICcuL2NvbnN0YW50cyc7XG5pbXBvcnQge1xuICBOcG1Eb3dubG9hZHNDbGllbnQsXG4gIE5wbURvd25sb2Fkc0VudHJ5LFxuICBOcG1Eb3dubG9hZHNQZXJpb2QsXG59IGZyb20gJy4vbnBtLWRvd25sb2Fkcy5sYW1iZGEtc2hhcmVkJztcbmltcG9ydCB7IENhY2hlU3RyYXRlZ3kgfSBmcm9tICcuLi8uLi9jYWNoaW5nJztcbmltcG9ydCB7IENhdGFsb2dDbGllbnQgfSBmcm9tICcuLi9jYXRhbG9nLWJ1aWxkZXIvY2xpZW50LmxhbWJkYS1zaGFyZWQnO1xuaW1wb3J0IHsgUzNfQ0xJRU5UIH0gZnJvbSAnLi4vc2hhcmVkL2F3cy5sYW1iZGEtc2hhcmVkJztcbmltcG9ydCB7IHJlcXVpcmVFbnYgfSBmcm9tICcuLi9zaGFyZWQvZW52LmxhbWJkYS1zaGFyZWQnO1xuXG4vKipcbiAqIFJlYnVpbGRzIHRoZSBgc3RhdHMuanNvbmAgb2JqZWN0IGluIHRoZSBjb25maWd1cmVkIFMzIGJ1Y2tldC5cbiAqIFZhbGlkYXRlcyB0aGF0IHRoZSBudW1iZXIgb2YgcGFja2FnZXMgb24gYSBmdWxsIHJlYnVpbGQgc2hvdWxkIG5vdCBkZWNyZWFzZVxuICogc2lnbmlmaWNhbnRseSAoZHVlIHRvIG5ldHdvcmsgZXJyb3JzIGZyb20gZS5nLiBOUE0pIC0gY2FuIGJlIGlnbm9yZWRcbiAqIGJ5IHBhc3NpbmcgeyBpZ25vcmVWYWxpZGF0aW9uOiB0cnVlIH0uXG4gKlxuICogQHBhcmFtIGV2ZW50IGNvbmZpZ3VyYXRpb24gZm9yIHRoZSByZWJ1aWxkIGpvYi5cbiAqIEBwYXJhbSBjb250ZXh0IHRoZSBsYW1iZGEgY29udGV4dCBpbiB3aGljaCB0aGlzIGV4ZWN1dGlvbiBydW5zLlxuICpcbiAqIEByZXR1cm5zIHRoZSBpbmZvcm1hdGlvbiBhYm91dCB0aGUgdXBkYXRlZCBTMyBvYmplY3QuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBoYW5kbGVyKGV2ZW50OiBhbnksIGNvbnRleHQ6IENvbnRleHQpIHtcbiAgY29uc29sZS5sb2coSlNPTi5zdHJpbmdpZnkoZXZlbnQsIG51bGwsIDIpKTtcblxuICBjb25zdCBTVEFUU19CVUNLRVRfTkFNRSA9IHJlcXVpcmVFbnYoJ1NUQVRTX0JVQ0tFVF9OQU1FJyk7XG4gIGNvbnN0IFNUQVRTX09CSkVDVF9LRVkgPSByZXF1aXJlRW52KCdTVEFUU19PQkpFQ1RfS0VZJyk7XG5cbiAgY29uc3QgY2F0YWxvZ0NsaWVudCA9IGF3YWl0IENhdGFsb2dDbGllbnQubmV3Q2xpZW50KCk7XG4gIGNvbnN0IGNhdGFsb2cgPSBjYXRhbG9nQ2xpZW50LnBhY2thZ2VzO1xuICBpZiAoY2F0YWxvZy5sZW5ndGggPT09IDApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ05vIHBhY2thZ2VzIGZvdW5kLicpO1xuICB9XG5cbiAgY29uc3QgY3VycmVudERhdGUgPSBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCk7XG4gIGNvbnN0IHN0YXRzOiBQYWNrYWdlU3RhdHNPdXRwdXQgPSB7IHBhY2thZ2VzOiB7fSwgdXBkYXRlZDogY3VycmVudERhdGUgfTtcbiAgY29uc3QgbnBtQ2xpZW50ID0gbmV3IE5wbURvd25sb2Fkc0NsaWVudChnb3QpO1xuXG4gIC8vIHJlbW92ZSBkdXBsaWNhdGVzIGZyb20gZGlmZmVyZW50IG1ham9yIHZlcnNpb25zXG4gIGNvbnN0IHBhY2thZ2VOYW1lcyA9IFsuLi5uZXcgU2V0KGNhdGFsb2cubWFwKChwa2cpID0+IHBrZy5uYW1lKSkudmFsdWVzKCldO1xuXG4gIGNvbnNvbGUubG9nKFxuICAgIGBSZXRyaWV2aW5nIGRvd25sb2FkIHN0YXRzIGZvciBhbGwgJHtcbiAgICAgIHBhY2thZ2VOYW1lcy5sZW5ndGhcbiAgICB9IHJlZ2lzdGVyZWQgcGFja2FnZXM6IFske3BhY2thZ2VOYW1lcy5qb2luKCcsJyl9XS5gXG4gICk7XG4gIGNvbnN0IG5wbURvd25sb2FkcyA9IGF3YWl0IG5wbUNsaWVudC5nZXREb3dubG9hZHMocGFja2FnZU5hbWVzLCB7XG4gICAgcGVyaW9kOiBOcG1Eb3dubG9hZHNQZXJpb2QuTEFTVF9XRUVLLFxuICAgIHRocm93RXJyb3JzOiBmYWxzZSxcbiAgfSk7XG5cbiAgZm9yIChjb25zdCBbcGtnTmFtZSwgZW50cnldIG9mIG5wbURvd25sb2Fkcy5lbnRyaWVzKCkpIHtcbiAgICB1cGRhdGVTdGF0cyhzdGF0cywgcGtnTmFtZSwgZW50cnkpO1xuICB9XG5cbiAgLy8gVXBkYXRlIG1ldHJpY3NcbiAgY29uc3Qgc3RhdHNDb3VudCA9IE9iamVjdC5rZXlzKHN0YXRzLnBhY2thZ2VzKS5sZW5ndGg7XG4gIGNvbnNvbGUubG9nKGBUaGVyZSBhcmUgbm93ICR7c3RhdHNDb3VudH0gcGFja2FnZXMgd2l0aCBOUE0gc3RhdHMgc3RvcmVkLmApO1xuICBhd2FpdCBtZXRyaWNTY29wZSgobWV0cmljcykgPT4gYXN5bmMgKCkgPT4ge1xuICAgIC8vIENsZWFyIG91dCBkZWZhdWx0IGRpbWVuc2lvbnMgYXMgd2UgZG9uJ3QgbmVlZCB0aG9zZS4gU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9hd3NsYWJzL2F3cy1lbWJlZGRlZC1tZXRyaWNzLW5vZGUvaXNzdWVzLzczXG4gICAgbWV0cmljcy5zZXREaW1lbnNpb25zKHt9KTtcblxuICAgIG1ldHJpY3Muc2V0TmFtZXNwYWNlKE1FVFJJQ1NfTkFNRVNQQUNFKTtcbiAgICBtZXRyaWNzLnB1dE1ldHJpYyhcbiAgICAgIE1ldHJpY05hbWUuUkVHSVNURVJFRF9QQUNLQUdFU19XSVRIX1NUQVRTLFxuICAgICAgc3RhdHNDb3VudCxcbiAgICAgIFVuaXQuQ291bnRcbiAgICApO1xuICB9KSgpO1xuXG4gIC8vIFVwbG9hZCB0aGUgcmVzdWx0IHRvIFMzIGFuZCBleGl0LlxuICByZXR1cm4gUzNfQ0xJRU5ULnNlbmQoXG4gICAgbmV3IFB1dE9iamVjdENvbW1hbmQoe1xuICAgICAgQnVja2V0OiBTVEFUU19CVUNLRVRfTkFNRSxcbiAgICAgIEtleTogU1RBVFNfT0JKRUNUX0tFWSxcbiAgICAgIEJvZHk6IEpTT04uc3RyaW5naWZ5KHN0YXRzLCBudWxsLCAyKSxcbiAgICAgIENvbnRlbnRUeXBlOiAnYXBwbGljYXRpb24vanNvbicsXG4gICAgICBDYWNoZUNvbnRyb2w6IENhY2hlU3RyYXRlZ3kuZGVmYXVsdCgpLnRvU3RyaW5nKCksXG4gICAgICBNZXRhZGF0YToge1xuICAgICAgICAnTGFtYmRhLUxvZy1Hcm91cCc6IGNvbnRleHQubG9nR3JvdXBOYW1lLFxuICAgICAgICAnTGFtYmRhLUxvZy1TdHJlYW0nOiBjb250ZXh0LmxvZ1N0cmVhbU5hbWUsXG4gICAgICAgICdMYW1iZGEtUnVuLUlkJzogY29udGV4dC5hd3NSZXF1ZXN0SWQsXG4gICAgICAgICdQYWNrYWdlLVN0YXRzLUNvdW50JzogYCR7c3RhdHNDb3VudH1gLFxuICAgICAgfSxcbiAgICB9KVxuICApO1xufVxuXG5mdW5jdGlvbiB1cGRhdGVTdGF0cyhcbiAgc3RhdHM6IFBhY2thZ2VTdGF0c091dHB1dCxcbiAgcGtnTmFtZTogc3RyaW5nLFxuICBlbnRyeTogTnBtRG93bmxvYWRzRW50cnlcbikge1xuICBzdGF0cy5wYWNrYWdlc1twa2dOYW1lXSA9IHtcbiAgICAuLi4oc3RhdHMucGFja2FnZXNbcGtnTmFtZV0gPz8ge30pLFxuICAgIGRvd25sb2Fkczoge1xuICAgICAgLi4uKHN0YXRzLnBhY2thZ2VzW3BrZ05hbWVdPy5kb3dubG9hZHMgPz8ge30pLFxuICAgICAgbnBtOiBlbnRyeS5kb3dubG9hZHMsXG4gICAgfSxcbiAgfTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBQYWNrYWdlU3RhdHNPdXRwdXQge1xuICByZWFkb25seSBwYWNrYWdlczogeyBba2V5OiBzdHJpbmddOiBQYWNrYWdlU3RhdHNFbnRyeSB9O1xuICByZWFkb25seSB1cGRhdGVkOiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUGFja2FnZVN0YXRzRW50cnkge1xuICByZWFkb25seSBkb3dubG9hZHM6IFBhY2thZ2VTdGF0c0Rvd25sb2Fkcztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBQYWNrYWdlU3RhdHNEb3dubG9hZHMge1xuICByZWFkb25seSBucG06IG51bWJlcjtcbn1cbiJdfQ==