construct-hub 0.4.430 → 0.4.432

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 (47) hide show
  1. package/.jsii +9 -9
  2. package/docs/operator-runbook.md +96 -0
  3. package/lib/backend/orchestration/index.d.ts +5 -1
  4. package/lib/backend/orchestration/index.js +9 -2
  5. package/lib/backend/orchestration/read-uninstallable-report.d.ts +7 -0
  6. package/lib/backend/orchestration/read-uninstallable-report.js +20 -0
  7. package/lib/backend/orchestration/read-uninstallable-report.lambda.bundle/index.js +60016 -0
  8. package/lib/backend/orchestration/read-uninstallable-report.lambda.bundle/index.js.map +7 -0
  9. package/lib/backend/orchestration/read-uninstallable-report.lambda.d.ts +13 -0
  10. package/lib/backend/orchestration/read-uninstallable-report.lambda.js +33 -0
  11. package/lib/backend/orchestration/retry-uninstallable-packages.d.ts +19 -0
  12. package/lib/backend/orchestration/retry-uninstallable-packages.js +100 -0
  13. package/lib/backend/package-stats/index.d.ts +15 -2
  14. package/lib/backend/package-stats/index.js +79 -21
  15. package/lib/backend/package-stats/package-stats-aggregator.d.ts +7 -0
  16. package/lib/backend/package-stats/package-stats-aggregator.js +20 -0
  17. package/lib/backend/package-stats/package-stats-aggregator.lambda.bundle/index.js +62489 -0
  18. package/lib/backend/package-stats/{package-stats.lambda.bundle → package-stats-aggregator.lambda.bundle}/index.js.map +4 -4
  19. package/lib/backend/package-stats/package-stats-aggregator.lambda.d.ts +13 -0
  20. package/lib/backend/package-stats/package-stats-aggregator.lambda.js +78 -0
  21. package/lib/backend/package-stats/package-stats-chunker.d.ts +7 -0
  22. package/lib/backend/package-stats/package-stats-chunker.js +20 -0
  23. package/lib/backend/package-stats/package-stats-chunker.lambda.bundle/index.js +60075 -0
  24. package/lib/backend/package-stats/package-stats-chunker.lambda.bundle/index.js.map +7 -0
  25. package/lib/backend/package-stats/package-stats-chunker.lambda.d.ts +6 -0
  26. package/lib/backend/package-stats/package-stats-chunker.lambda.js +25 -0
  27. package/lib/backend/package-stats/package-stats-processor.d.ts +7 -0
  28. package/lib/backend/package-stats/package-stats-processor.js +20 -0
  29. package/lib/backend/package-stats/{package-stats.lambda.bundle → package-stats-processor.lambda.bundle}/index.js +36 -2556
  30. package/lib/backend/package-stats/package-stats-processor.lambda.bundle/index.js.map +7 -0
  31. package/lib/backend/package-stats/package-stats-processor.lambda.d.ts +10 -0
  32. package/lib/backend/package-stats/package-stats-processor.lambda.js +41 -0
  33. package/lib/backend-dashboard.js +11 -6
  34. package/lib/construct-hub.d.ts +1 -1
  35. package/lib/construct-hub.js +12 -4
  36. package/lib/package-sources/code-artifact.js +1 -1
  37. package/lib/package-sources/npmjs.js +1 -1
  38. package/lib/package-tag/index.js +3 -3
  39. package/lib/package-tag-group/index.js +2 -2
  40. package/lib/preload-file/index.js +1 -1
  41. package/lib/s3/storage.js +1 -1
  42. package/lib/spdx-license.js +1 -1
  43. package/package.json +9 -3
  44. package/lib/backend/package-stats/package-stats.d.ts +0 -7
  45. package/lib/backend/package-stats/package-stats.js +0 -20
  46. package/lib/backend/package-stats/package-stats.lambda.d.ts +0 -25
  47. 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==