cdk-nextjs 0.7.11 → 0.7.12
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.
- package/.jsii +76 -22
- package/.jsii.tabl.json +1 -1
- package/API.md +59 -3
- package/README.md +1 -1
- package/docs/breaking-changes.md +32 -0
- package/docs/next-build-output-guide.md +1 -1
- package/lib/adapter/adapter.mjs +1 -1
- package/lib/nextjs-api.js +1 -1
- package/lib/nextjs-build/nextjs-build.js +1 -1
- package/lib/nextjs-cache.js +1 -1
- package/lib/nextjs-compute/nextjs-containers.js +1 -1
- package/lib/nextjs-compute/nextjs-functions.js +1 -1
- package/lib/nextjs-distribution.js +1 -1
- package/lib/nextjs-post-deploy.js +1 -1
- package/lib/nextjs-static-assets.d.ts +74 -5
- package/lib/nextjs-static-assets.js +276 -41
- package/lib/nextjs-static-assets.test.js +286 -1
- package/lib/root-constructs/nextjs-base-construct.d.ts +5 -4
- package/lib/root-constructs/nextjs-base-construct.js +17 -8
- package/lib/root-constructs/nextjs-global-containers.js +1 -1
- package/lib/root-constructs/nextjs-global-functions.js +1 -1
- package/lib/root-constructs/nextjs-regional-containers.js +1 -1
- package/lib/root-constructs/nextjs-regional-functions.js +1 -1
- package/lib/runtime/image-utils.d.ts +1 -0
- package/lib/runtime/image-utils.js +2 -1
- package/lib/runtime/image-utils.test.js +17 -1
- package/lib/runtime/image.js +5 -2
- package/lib/runtime/image.test.js +21 -1
- package/lib/runtime/lambda.mjs +6 -2
- package/lib/runtime/server.mjs +6 -2
- package/package.json +1 -1
|
@@ -10,6 +10,19 @@ import { Construct } from "constructs";
|
|
|
10
10
|
export declare function staticAssetsObjectsPattern(keyPrefix?: string): string;
|
|
11
11
|
export interface NextjsStaticAssetsOverrides {
|
|
12
12
|
readonly bucketProps?: BucketProps;
|
|
13
|
+
/**
|
|
14
|
+
* Applied to every upload (`public/`, `_next/static/` and
|
|
15
|
+
* `_next/static/service-worker/`), except that the two `_next/static` uploads
|
|
16
|
+
* always keep the `Cache-Control` Next.js sends for them. So a `cacheControl`
|
|
17
|
+
* here sets the header for `public/` files only, while anything else, such as
|
|
18
|
+
* a `distribution` to invalidate, applies to each upload in turn.
|
|
19
|
+
*
|
|
20
|
+
* `sources` and `destinationBucket`, which the type requires, are ignored:
|
|
21
|
+
* the uploads are always the build's assets, to the bucket CloudFront and
|
|
22
|
+
* API Gateway read from (pass `bucket` to bring your own). `prune: true` and
|
|
23
|
+
* `retainOnDelete: false` are rejected, since each would break the other
|
|
24
|
+
* uploads.
|
|
25
|
+
*/
|
|
13
26
|
readonly bucketDeploymentProps?: BucketDeploymentProps;
|
|
14
27
|
}
|
|
15
28
|
export interface NextjsStaticAssetsProps {
|
|
@@ -43,7 +56,35 @@ export interface NextjsStaticAssetsProps {
|
|
|
43
56
|
*/
|
|
44
57
|
export declare class NextjsStaticAssets extends Construct {
|
|
45
58
|
bucket: IBucket;
|
|
59
|
+
/**
|
|
60
|
+
* The first of `staticDeployment`, `serviceWorkerDeployment` and
|
|
61
|
+
* `publicDeployment` the build has files for.
|
|
62
|
+
*
|
|
63
|
+
* @deprecated The assets are uploaded by up to three deployments, and this
|
|
64
|
+
* is only one of them: a dependency on it doesn't wait for the others. Use
|
|
65
|
+
* `staticDeployment`, `serviceWorkerDeployment` and `publicDeployment`.
|
|
66
|
+
*/
|
|
46
67
|
deployment: BucketDeployment;
|
|
68
|
+
/**
|
|
69
|
+
* Uploads `.next/static` to `_next/static/` with
|
|
70
|
+
* `Cache-Control: public, max-age=31536000, immutable`, except for
|
|
71
|
+
* `service-worker/` (see `serviceWorkerDeployment`). Absent if the build has
|
|
72
|
+
* no `.next/static`.
|
|
73
|
+
*/
|
|
74
|
+
readonly staticDeployment?: BucketDeployment;
|
|
75
|
+
/**
|
|
76
|
+
* Uploads `.next/static/service-worker` with
|
|
77
|
+
* `Cache-Control: public, max-age=0, must-revalidate`, as Next.js serves it:
|
|
78
|
+
* a service worker keeps its URL across builds, so it can't be `immutable`.
|
|
79
|
+
* Absent if the build has no service worker.
|
|
80
|
+
*/
|
|
81
|
+
readonly serviceWorkerDeployment?: BucketDeployment;
|
|
82
|
+
/**
|
|
83
|
+
* Uploads `public/`, separately from `staticDeployment` because its files
|
|
84
|
+
* keep their names when they change and so can't be `immutable`. Absent if
|
|
85
|
+
* the build has no `public` directory.
|
|
86
|
+
*/
|
|
87
|
+
readonly publicDeployment?: BucketDeployment;
|
|
47
88
|
/**
|
|
48
89
|
* S3 key prefix the assets are actually uploaded under, normalized to a bare
|
|
49
90
|
* path segment (empty when they live at the bucket root).
|
|
@@ -57,9 +98,34 @@ export declare class NextjsStaticAssets extends Construct {
|
|
|
57
98
|
* bytes were uploaded.
|
|
58
99
|
*/
|
|
59
100
|
readonly keyPrefix: string;
|
|
60
|
-
private stagingDir?;
|
|
61
101
|
private props;
|
|
62
102
|
constructor(scope: Construct, id: string, props: NextjsStaticAssetsProps);
|
|
103
|
+
/**
|
|
104
|
+
* Stages each tree and creates its deployment, adding every staging
|
|
105
|
+
* directory to `staged` as it's made, so the caller can remove them even if
|
|
106
|
+
* a later step throws.
|
|
107
|
+
*/
|
|
108
|
+
private createDeployments;
|
|
109
|
+
/**
|
|
110
|
+
* Rejects the `bucketDeploymentProps` that can't work across several
|
|
111
|
+
* deployments sharing one prefix. Each is spread into every one of them:
|
|
112
|
+
*
|
|
113
|
+
* - `prune: true` makes each deployment's `s3 sync --delete` remove the files
|
|
114
|
+
* the others uploaded.
|
|
115
|
+
* - `retainOnDelete: false` makes a deployment `s3 rm --recursive` its old
|
|
116
|
+
* prefix when the prefix changes, without checking whether the bucket is
|
|
117
|
+
* CDK's (only Delete checks), so it can delete files another deployment has
|
|
118
|
+
* just uploaded there. On Delete, CDK skips that `rm` only for a bucket it
|
|
119
|
+
* tagged, and it can't tag an imported one, so a build that stops having
|
|
120
|
+
* files for one deployment would lose the others' files too.
|
|
121
|
+
*
|
|
122
|
+
* `sources` and `destinationBucket` aren't rejected, because the type
|
|
123
|
+
* requires them; `newDeployment` sets them after the spread instead.
|
|
124
|
+
*
|
|
125
|
+
* Compared against the exact value, as with `destinationKeyPrefix`, so an
|
|
126
|
+
* explicit `undefined` from a JSII binding is not mistaken for an override.
|
|
127
|
+
*/
|
|
128
|
+
private validateDeploymentOverrides;
|
|
63
129
|
/**
|
|
64
130
|
* Resolves the single prefix both the upload and the URLs use. A
|
|
65
131
|
* `bucketDeploymentProps.destinationKeyPrefix` override wins over `basePath`,
|
|
@@ -77,11 +143,14 @@ export declare class NextjsStaticAssets extends Construct {
|
|
|
77
143
|
private createBucket;
|
|
78
144
|
private createDeployment;
|
|
79
145
|
/**
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
*
|
|
146
|
+
* Copies `sourceDir` to `<staging>/<subPath>` in a new staging directory, or
|
|
147
|
+
* returns `undefined` if there is no `sourceDir` or no file in it passes
|
|
148
|
+
* `include`. Staged under `subPath` rather than uploaded with a longer
|
|
149
|
+
* `destinationKeyPrefix`, so every deployment shares the one prefix
|
|
150
|
+
* `keyPrefix` resolves. `include` gets each entry's path relative to
|
|
151
|
+
* `sourceDir`.
|
|
83
152
|
*/
|
|
84
|
-
private
|
|
153
|
+
private stageDirectory;
|
|
85
154
|
/**
|
|
86
155
|
* Check if a directory exists
|
|
87
156
|
*/
|
|
@@ -1,4 +1,37 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
2
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
36
|
exports.NextjsStaticAssets = void 0;
|
|
4
37
|
exports.staticAssetsObjectsPattern = staticAssetsObjectsPattern;
|
|
@@ -9,6 +42,7 @@ const node_path_1 = require("node:path");
|
|
|
9
42
|
const aws_cdk_lib_1 = require("aws-cdk-lib");
|
|
10
43
|
const aws_s3_1 = require("aws-cdk-lib/aws-s3");
|
|
11
44
|
const aws_s3_deployment_1 = require("aws-cdk-lib/aws-s3-deployment");
|
|
45
|
+
const cxapi = __importStar(require("aws-cdk-lib/cx-api"));
|
|
12
46
|
const constructs_1 = require("constructs");
|
|
13
47
|
const constants_1 = require("./constants");
|
|
14
48
|
const base_path_1 = require("./utils/base-path");
|
|
@@ -25,13 +59,90 @@ function staticAssetsObjectsPattern(keyPrefix) {
|
|
|
25
59
|
const prefix = (0, base_path_1.normalizeBasePath)(keyPrefix);
|
|
26
60
|
return prefix ? `${prefix}/*` : "*";
|
|
27
61
|
}
|
|
62
|
+
/** Where `.next/static` is served from, relative to `keyPrefix`. */
|
|
63
|
+
const STATIC_PATH = (0, node_path_1.join)("_next", "static");
|
|
64
|
+
/** Where Next.js compiles service workers to, relative to `.next/static`. */
|
|
65
|
+
const SERVICE_WORKER_DIR = "service-worker";
|
|
66
|
+
/**
|
|
67
|
+
* Every file under `dir`, relative to it, through symlinks too: CDK uploads a
|
|
68
|
+
* linked file or directory as what it points to, under every name it's reached
|
|
69
|
+
* by.
|
|
70
|
+
*
|
|
71
|
+
* An explicit walk rather than `readdirSync({ recursive: true })`, which never
|
|
72
|
+
* returns on a symlink cycle (Node 24 follows directory links), and whose
|
|
73
|
+
* `Dirent.parentPath` doesn't exist before Node 20.12. A link back to a
|
|
74
|
+
* directory already on the current path is a cycle and isn't followed; one that
|
|
75
|
+
* can't be stat'd (dangling, or a loop of links) counts as a file.
|
|
76
|
+
*/
|
|
77
|
+
function listFiles(dir) {
|
|
78
|
+
const files = [];
|
|
79
|
+
const walk = (sub, ancestors) => {
|
|
80
|
+
const real = (0, node_fs_1.realpathSync)((0, node_path_1.join)(dir, sub));
|
|
81
|
+
if (ancestors.has(real)) {
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
const path = new Set(ancestors).add(real);
|
|
85
|
+
for (const entry of (0, node_fs_1.readdirSync)(real, { withFileTypes: true })) {
|
|
86
|
+
const child = (0, node_path_1.join)(sub, entry.name);
|
|
87
|
+
if (entry.isDirectory() ||
|
|
88
|
+
(entry.isSymbolicLink() && isDirectoryLink((0, node_path_1.join)(real, entry.name)))) {
|
|
89
|
+
walk(child, path);
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
files.push(child);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
walk("", new Set());
|
|
97
|
+
return files;
|
|
98
|
+
}
|
|
99
|
+
function isDirectoryLink(path) {
|
|
100
|
+
try {
|
|
101
|
+
return (0, node_fs_1.statSync)(path).isDirectory();
|
|
102
|
+
}
|
|
103
|
+
catch {
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
/** Whether the relative `path` is `dir` or inside it. */
|
|
108
|
+
function isWithin(path, dir) {
|
|
109
|
+
return path === dir || path.startsWith(dir + node_path_1.sep);
|
|
110
|
+
}
|
|
28
111
|
/**
|
|
29
112
|
* Creates S3 Bucket for public and _next/static assets and deploys them using S3Deployment.
|
|
30
113
|
*/
|
|
31
114
|
class NextjsStaticAssets extends constructs_1.Construct {
|
|
32
|
-
static [JSII_RTTI_SYMBOL_1] = { fqn: "cdk-nextjs.NextjsStaticAssets", version: "0.7.
|
|
115
|
+
static [JSII_RTTI_SYMBOL_1] = { fqn: "cdk-nextjs.NextjsStaticAssets", version: "0.7.12" };
|
|
33
116
|
bucket;
|
|
117
|
+
/**
|
|
118
|
+
* The first of `staticDeployment`, `serviceWorkerDeployment` and
|
|
119
|
+
* `publicDeployment` the build has files for.
|
|
120
|
+
*
|
|
121
|
+
* @deprecated The assets are uploaded by up to three deployments, and this
|
|
122
|
+
* is only one of them: a dependency on it doesn't wait for the others. Use
|
|
123
|
+
* `staticDeployment`, `serviceWorkerDeployment` and `publicDeployment`.
|
|
124
|
+
*/
|
|
34
125
|
deployment;
|
|
126
|
+
/**
|
|
127
|
+
* Uploads `.next/static` to `_next/static/` with
|
|
128
|
+
* `Cache-Control: public, max-age=31536000, immutable`, except for
|
|
129
|
+
* `service-worker/` (see `serviceWorkerDeployment`). Absent if the build has
|
|
130
|
+
* no `.next/static`.
|
|
131
|
+
*/
|
|
132
|
+
staticDeployment;
|
|
133
|
+
/**
|
|
134
|
+
* Uploads `.next/static/service-worker` with
|
|
135
|
+
* `Cache-Control: public, max-age=0, must-revalidate`, as Next.js serves it:
|
|
136
|
+
* a service worker keeps its URL across builds, so it can't be `immutable`.
|
|
137
|
+
* Absent if the build has no service worker.
|
|
138
|
+
*/
|
|
139
|
+
serviceWorkerDeployment;
|
|
140
|
+
/**
|
|
141
|
+
* Uploads `public/`, separately from `staticDeployment` because its files
|
|
142
|
+
* keep their names when they change and so can't be `immutable`. Absent if
|
|
143
|
+
* the build has no `public` directory.
|
|
144
|
+
*/
|
|
145
|
+
publicDeployment;
|
|
35
146
|
/**
|
|
36
147
|
* S3 key prefix the assets are actually uploaded under, normalized to a bare
|
|
37
148
|
* path segment (empty when they live at the bucket root).
|
|
@@ -45,14 +156,132 @@ class NextjsStaticAssets extends constructs_1.Construct {
|
|
|
45
156
|
* bytes were uploaded.
|
|
46
157
|
*/
|
|
47
158
|
keyPrefix;
|
|
48
|
-
stagingDir;
|
|
49
159
|
props;
|
|
50
160
|
constructor(scope, id, props) {
|
|
51
161
|
super(scope, id);
|
|
52
162
|
this.props = props;
|
|
163
|
+
this.validateDeploymentOverrides();
|
|
53
164
|
this.keyPrefix = this.resolveKeyPrefix();
|
|
54
165
|
this.bucket = props.bucket ?? this.createBucket();
|
|
55
|
-
|
|
166
|
+
const staged = [];
|
|
167
|
+
try {
|
|
168
|
+
const uploads = this.createDeployments(staged);
|
|
169
|
+
this.staticDeployment = uploads.staticDeployment;
|
|
170
|
+
this.serviceWorkerDeployment = uploads.serviceWorkerDeployment;
|
|
171
|
+
this.publicDeployment = uploads.publicDeployment;
|
|
172
|
+
}
|
|
173
|
+
finally {
|
|
174
|
+
// `Source.asset` stages during `BucketDeployment`'s construction (CDK's
|
|
175
|
+
// `AssetStaging` copies into `cdk.out` from its own constructor), so the
|
|
176
|
+
// temporary copies are dead once the deployments exist, or once one of
|
|
177
|
+
// them failed. Left behind, every synth would add another full copy of
|
|
178
|
+
// the app's static assets to the temp directory.
|
|
179
|
+
//
|
|
180
|
+
// Unless staging is disabled (`cdk synth --no-staging`, and SAM, which
|
|
181
|
+
// sets the same context): then the asset manifest points at these
|
|
182
|
+
// directories themselves, and removing them would fail the publish that
|
|
183
|
+
// follows.
|
|
184
|
+
if (!this.node.tryGetContext(cxapi.DISABLE_ASSET_STAGING_CONTEXT)) {
|
|
185
|
+
for (const dir of staged) {
|
|
186
|
+
(0, node_fs_1.rmSync)(dir, { recursive: true, force: true });
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
this.deployment = (this.staticDeployment ??
|
|
191
|
+
this.serviceWorkerDeployment ??
|
|
192
|
+
this.publicDeployment);
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Stages each tree and creates its deployment, adding every staging
|
|
196
|
+
* directory to `staged` as it's made, so the caller can remove them even if
|
|
197
|
+
* a later step throws.
|
|
198
|
+
*/
|
|
199
|
+
createDeployments(staged) {
|
|
200
|
+
const stage = (...args) => {
|
|
201
|
+
const dir = this.stageDirectory(...args);
|
|
202
|
+
if (dir) {
|
|
203
|
+
staged.push(dir);
|
|
204
|
+
}
|
|
205
|
+
return dir;
|
|
206
|
+
};
|
|
207
|
+
const builtDir = (0, node_path_1.join)(this.props.buildDirectory, ".next", "static");
|
|
208
|
+
const publicSourceDir = (0, node_path_1.join)(this.props.buildDirectory, "public");
|
|
209
|
+
// Only a directory is uploaded as service workers, so only a directory is
|
|
210
|
+
// left out here.
|
|
211
|
+
const hasServiceWorkers = this.directoryExists((0, node_path_1.join)(builtDir, SERVICE_WORKER_DIR));
|
|
212
|
+
const staticDir = stage(builtDir, STATIC_PATH, (path) => !hasServiceWorkers || !isWithin(path, SERVICE_WORKER_DIR));
|
|
213
|
+
const serviceWorkerDir = stage((0, node_path_1.join)(builtDir, SERVICE_WORKER_DIR), (0, node_path_1.join)(STATIC_PATH, SERVICE_WORKER_DIR));
|
|
214
|
+
// A `public/_next/static` file with a built file's name would land on the
|
|
215
|
+
// same key. `next start` serves the built one, so the public copy is left
|
|
216
|
+
// out; uploading both would leave whichever deployment finished last.
|
|
217
|
+
// Other `public/_next/static` files are served as `next start` does.
|
|
218
|
+
// Matched against a listing rather than with `existsSync`, which on macOS
|
|
219
|
+
// and Windows would let `Legacy.js` shadow `legacy.js`: Next.js and S3 keys
|
|
220
|
+
// are case-sensitive.
|
|
221
|
+
const builtFiles = new Set(this.directoryExists(builtDir) ? listFiles(builtDir) : []);
|
|
222
|
+
const publicDir = stage(publicSourceDir, "", (path) => !isWithin(path, STATIC_PATH) ||
|
|
223
|
+
!builtFiles.has((0, node_path_1.relative)(STATIC_PATH, path)));
|
|
224
|
+
if (!staticDir && !serviceWorkerDir && !publicDir) {
|
|
225
|
+
throw new Error(`No static assets found to deploy. Ensure your Next.js build output contains files in either:
|
|
226
|
+
- A 'public' directory at: ${publicSourceDir}
|
|
227
|
+
- A '.next/static' directory at: ${builtDir}`);
|
|
228
|
+
}
|
|
229
|
+
// `_next/static/` files are content-hashed, so they get the same header
|
|
230
|
+
// Next.js sends for them. Nothing else would: CloudFront and API Gateway
|
|
231
|
+
// serve them straight from S3, where the object's metadata is the only
|
|
232
|
+
// `Cache-Control` there is. A `BucketDeployment`'s `cacheControl` applies to
|
|
233
|
+
// every object it uploads, hence one deployment per header.
|
|
234
|
+
return {
|
|
235
|
+
staticDeployment: staticDir
|
|
236
|
+
? this.createDeployment("Deployment", staticDir, [
|
|
237
|
+
aws_s3_deployment_1.CacheControl.setPublic(),
|
|
238
|
+
aws_s3_deployment_1.CacheControl.maxAge(aws_cdk_lib_1.Duration.days(365)),
|
|
239
|
+
aws_s3_deployment_1.CacheControl.immutable(),
|
|
240
|
+
])
|
|
241
|
+
: undefined,
|
|
242
|
+
serviceWorkerDeployment: serviceWorkerDir
|
|
243
|
+
? this.createDeployment("ServiceWorkerDeployment", serviceWorkerDir, [
|
|
244
|
+
aws_s3_deployment_1.CacheControl.setPublic(),
|
|
245
|
+
aws_s3_deployment_1.CacheControl.maxAge(aws_cdk_lib_1.Duration.seconds(0)),
|
|
246
|
+
aws_s3_deployment_1.CacheControl.mustRevalidate(),
|
|
247
|
+
])
|
|
248
|
+
: undefined,
|
|
249
|
+
publicDeployment: publicDir
|
|
250
|
+
? this.createDeployment("PublicDeployment", publicDir)
|
|
251
|
+
: undefined,
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Rejects the `bucketDeploymentProps` that can't work across several
|
|
256
|
+
* deployments sharing one prefix. Each is spread into every one of them:
|
|
257
|
+
*
|
|
258
|
+
* - `prune: true` makes each deployment's `s3 sync --delete` remove the files
|
|
259
|
+
* the others uploaded.
|
|
260
|
+
* - `retainOnDelete: false` makes a deployment `s3 rm --recursive` its old
|
|
261
|
+
* prefix when the prefix changes, without checking whether the bucket is
|
|
262
|
+
* CDK's (only Delete checks), so it can delete files another deployment has
|
|
263
|
+
* just uploaded there. On Delete, CDK skips that `rm` only for a bucket it
|
|
264
|
+
* tagged, and it can't tag an imported one, so a build that stops having
|
|
265
|
+
* files for one deployment would lose the others' files too.
|
|
266
|
+
*
|
|
267
|
+
* `sources` and `destinationBucket` aren't rejected, because the type
|
|
268
|
+
* requires them; `newDeployment` sets them after the spread instead.
|
|
269
|
+
*
|
|
270
|
+
* Compared against the exact value, as with `destinationKeyPrefix`, so an
|
|
271
|
+
* explicit `undefined` from a JSII binding is not mistaken for an override.
|
|
272
|
+
*/
|
|
273
|
+
validateDeploymentOverrides() {
|
|
274
|
+
const overrides = this.props.overrides?.bucketDeploymentProps;
|
|
275
|
+
const rejected = [
|
|
276
|
+
overrides?.prune === true &&
|
|
277
|
+
"`prune: true` (old assets are pruned after deploy by NextjsPostDeploy, once they are past its TTL)",
|
|
278
|
+
overrides?.retainOnDelete === false && "`retainOnDelete: false`",
|
|
279
|
+
].filter((reason) => !!reason);
|
|
280
|
+
if (rejected.length > 0) {
|
|
281
|
+
throw new Error(`${constants_1.LOG_PREFIX} overrides.bucketDeploymentProps can't set ${rejected.join(", or ")}: ` +
|
|
282
|
+
"the static assets are uploaded by one deployment per Cache-Control, " +
|
|
283
|
+
"and each of these would break the others.");
|
|
284
|
+
}
|
|
56
285
|
}
|
|
57
286
|
/**
|
|
58
287
|
* Resolves the single prefix both the upload and the URLs use. A
|
|
@@ -85,24 +314,24 @@ class NextjsStaticAssets extends constructs_1.Construct {
|
|
|
85
314
|
...this.props.overrides?.bucketProps,
|
|
86
315
|
});
|
|
87
316
|
}
|
|
88
|
-
createDeployment() {
|
|
89
|
-
|
|
90
|
-
this.stagingDir = this.createStagingDirectory();
|
|
91
|
-
if (!this.stagingDir) {
|
|
92
|
-
throw new Error(`No static assets found to deploy. Ensure your Next.js build output contains either:
|
|
93
|
-
- A 'public' directory at: ${(0, node_path_1.join)(this.props.buildDirectory, "public")}
|
|
94
|
-
- A '.next/static' directory at: ${(0, node_path_1.join)(this.props.buildDirectory, ".next", "static")}`);
|
|
95
|
-
}
|
|
96
|
-
return new aws_s3_deployment_1.BucketDeployment(this, "Deployment", {
|
|
97
|
-
sources: [aws_s3_deployment_1.Source.asset(this.stagingDir)],
|
|
98
|
-
destinationBucket: this.bucket,
|
|
317
|
+
createDeployment(id, stagingDir, cacheControl) {
|
|
318
|
+
return new aws_s3_deployment_1.BucketDeployment(this, id, {
|
|
99
319
|
// Add BUILD_ID as metadata to all objects for version tracking
|
|
100
320
|
metadata: {
|
|
101
321
|
BUILD_ID: this.props.buildId,
|
|
102
322
|
},
|
|
103
|
-
prune: false, // Don't delete existing assets to prevent 404s during deployment, pruning will be handled by post-deploy
|
|
104
323
|
// S3Deployment automatically detects content types based on file extensions
|
|
105
324
|
...this.props.overrides?.bucketDeploymentProps,
|
|
325
|
+
// Set after the spread. The type makes callers pass `sources` and
|
|
326
|
+
// `destinationBucket`, and either would upload something other than the
|
|
327
|
+
// build's assets, or somewhere CloudFront and API Gateway don't read from.
|
|
328
|
+
// `validateDeploymentOverrides` lets `prune` through only as `false` or an
|
|
329
|
+
// explicit `undefined` from a JSII binding, which would turn on CDK's
|
|
330
|
+
// default `prune: true`.
|
|
331
|
+
sources: [aws_s3_deployment_1.Source.asset(stagingDir)],
|
|
332
|
+
destinationBucket: this.bucket,
|
|
333
|
+
prune: false, // Don't delete existing assets to prevent 404s during deployment, pruning will be handled by post-deploy
|
|
334
|
+
...(cacheControl && { cacheControl }),
|
|
106
335
|
// Set after the spread: `resolveKeyPrefix` already folded in any
|
|
107
336
|
// `destinationKeyPrefix` override, so this is the normalized form of it.
|
|
108
337
|
// Letting the raw override through here would upload the assets somewhere
|
|
@@ -111,43 +340,49 @@ class NextjsStaticAssets extends constructs_1.Construct {
|
|
|
111
340
|
});
|
|
112
341
|
}
|
|
113
342
|
/**
|
|
114
|
-
*
|
|
115
|
-
*
|
|
116
|
-
*
|
|
343
|
+
* Copies `sourceDir` to `<staging>/<subPath>` in a new staging directory, or
|
|
344
|
+
* returns `undefined` if there is no `sourceDir` or no file in it passes
|
|
345
|
+
* `include`. Staged under `subPath` rather than uploaded with a longer
|
|
346
|
+
* `destinationKeyPrefix`, so every deployment shares the one prefix
|
|
347
|
+
* `keyPrefix` resolves. `include` gets each entry's path relative to
|
|
348
|
+
* `sourceDir`.
|
|
117
349
|
*/
|
|
118
|
-
|
|
350
|
+
stageDirectory(sourceDir, subPath, include = () => true) {
|
|
351
|
+
if (!this.directoryExists(sourceDir)) {
|
|
352
|
+
return undefined;
|
|
353
|
+
}
|
|
354
|
+
// From the real path, and dereferencing links inside it: `cpSync` would
|
|
355
|
+
// copy a link as a link, which fails for a symlinked `sourceDir` (onto the
|
|
356
|
+
// directory made for it here) and hides a linked directory's files from
|
|
357
|
+
// `include`, though CDK uploads them.
|
|
358
|
+
const realSourceDir = (0, node_fs_1.realpathSync)(sourceDir);
|
|
119
359
|
const stagingDir = (0, node_fs_1.mkdtempSync)((0, node_path_1.join)((0, node_os_1.tmpdir)(), "nextjs-assets-"));
|
|
120
|
-
let hasAssets = false;
|
|
121
360
|
try {
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
const staticDestDir = (0, node_path_1.join)(nextDir, "static");
|
|
133
|
-
// Create _next directory
|
|
134
|
-
(0, node_fs_1.mkdirSync)(nextDir, { recursive: true });
|
|
135
|
-
// Copy static assets
|
|
136
|
-
(0, node_fs_1.cpSync)(staticPath, staticDestDir, { recursive: true });
|
|
137
|
-
hasAssets = true;
|
|
361
|
+
const destDir = (0, node_path_1.join)(stagingDir, subPath);
|
|
362
|
+
(0, node_fs_1.mkdirSync)(destDir, { recursive: true });
|
|
363
|
+
(0, node_fs_1.cpSync)(realSourceDir, destDir, {
|
|
364
|
+
recursive: true,
|
|
365
|
+
dereference: true,
|
|
366
|
+
filter: (path) => include((0, node_path_1.relative)(realSourceDir, path)),
|
|
367
|
+
});
|
|
368
|
+
if (listFiles(destDir).length === 0) {
|
|
369
|
+
(0, node_fs_1.rmSync)(stagingDir, { recursive: true, force: true });
|
|
370
|
+
return undefined;
|
|
138
371
|
}
|
|
139
|
-
return
|
|
372
|
+
return stagingDir;
|
|
140
373
|
}
|
|
141
374
|
catch (error) {
|
|
142
|
-
|
|
143
|
-
//
|
|
375
|
+
// Thrown rather than skipped, which would deploy without these assets.
|
|
376
|
+
// The cleanup's own failure must not replace that error.
|
|
144
377
|
try {
|
|
145
378
|
(0, node_fs_1.rmSync)(stagingDir, { recursive: true, force: true });
|
|
146
379
|
}
|
|
147
380
|
catch {
|
|
148
381
|
// Ignore cleanup errors
|
|
149
382
|
}
|
|
150
|
-
|
|
383
|
+
throw new Error(`${constants_1.LOG_PREFIX} Could not stage ${sourceDir} for upload`, {
|
|
384
|
+
cause: error,
|
|
385
|
+
});
|
|
151
386
|
}
|
|
152
387
|
}
|
|
153
388
|
/**
|
|
@@ -163,4 +398,4 @@ class NextjsStaticAssets extends constructs_1.Construct {
|
|
|
163
398
|
}
|
|
164
399
|
}
|
|
165
400
|
exports.NextjsStaticAssets = NextjsStaticAssets;
|
|
166
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmV4dGpzLXN0YXRpYy1hc3NldHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvbmV4dGpzLXN0YXRpYy1hc3NldHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBaUNBLGdFQU1DOztBQXZDRCxxQ0FPaUI7QUFDakIscUNBQWlDO0FBQ2pDLHlDQUFpQztBQUNqQyw2Q0FBbUQ7QUFDbkQsK0NBTTRCO0FBQzVCLHFFQUl1QztBQUN2QywyQ0FBdUM7QUFDdkMsMkNBQXlDO0FBQ3pDLGlEQUFzRDtBQUV0RDs7Ozs7R0FLRztBQUNILFNBQWdCLDBCQUEwQixDQUFDLFNBQWtCO0lBQzNELElBQUksU0FBUyxJQUFJLG1CQUFLLENBQUMsWUFBWSxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUM7UUFDL0MsT0FBTyxHQUFHLENBQUM7SUFDYixDQUFDO0lBQ0QsTUFBTSxNQUFNLEdBQUcsSUFBQSw2QkFBaUIsRUFBQyxTQUFTLENBQUMsQ0FBQztJQUM1QyxPQUFPLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxNQUFNLElBQUksQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDO0FBQ3RDLENBQUM7QUFrQ0Q7O0dBRUc7QUFDSCxNQUFhLGtCQUFtQixTQUFRLHNCQUFTOztJQUMvQyxNQUFNLENBQVU7SUFDaEIsVUFBVSxDQUFtQjtJQUM3Qjs7Ozs7Ozs7Ozs7T0FXRztJQUNNLFNBQVMsQ0FBUztJQUNuQixVQUFVLENBQVU7SUFFcEIsS0FBSyxDQUEwQjtJQUV2QyxZQUFZLEtBQWdCLEVBQUUsRUFBVSxFQUFFLEtBQThCO1FBQ3RFLEtBQUssQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFDakIsSUFBSSxDQUFDLEtBQUssR0FBRyxLQUFLLENBQUM7UUFDbkIsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztRQUN6QyxJQUFJLENBQUMsTUFBTSxHQUFHLEtBQUssQ0FBQyxNQUFNLElBQUksSUFBSSxDQUFD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O0lBQ0ssZUFBZSxDQUFDLE9BQWU7UUFDckMsSUFBSSxDQUFDO1lBQ0gsT0FBTyxJQUFBLG9CQUFVLEVBQUMsT0FBTyxDQUFDLElBQUksSUFBQSxrQkFBUSxFQUFDLE9BQU8sQ0FBQyxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQ2hFLENBQUM7UUFBQyxNQUFNLENBQUM7WUFDUCxPQUFPLEtBQUssQ0FBQztRQUNmLENBQUM7SUFDSCxDQUFDOztBQWpKSCxnREFrSkMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBjcFN5bmMsXG4gIGV4aXN0c1N5bmMsXG4gIG1rZGlyU3luYyxcbiAgbWtkdGVtcFN5bmMsXG4gIHJtU3luYyxcbiAgc3RhdFN5bmMsXG59IGZyb20gXCJub2RlOmZzXCI7XG5pbXBvcnQgeyB0bXBkaXIgfSBmcm9tIFwibm9kZTpvc1wiO1xuaW1wb3J0IHsgam9pbiB9IGZyb20gXCJub2RlOnBhdGhcIjtcbmltcG9ydCB7IFJlbW92YWxQb2xpY3ksIFRva2VuIH0gZnJvbSBcImF3cy1jZGstbGliXCI7XG5pbXBvcnQge1xuICBCbG9ja1B1YmxpY0FjY2VzcyxcbiAgQnVja2V0LFxuICBCdWNrZXRFbmNyeXB0aW9uLFxuICBCdWNrZXRQcm9wcyxcbiAgSUJ1Y2tldCxcbn0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1zM1wiO1xuaW1wb3J0IHtcbiAgQnVja2V0RGVwbG95bWVudCxcbiAgQnVja2V0RGVwbG95bWVudFByb3BzLFxuICBTb3VyY2UsXG59IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtczMtZGVwbG95bWVudFwiO1xuaW1wb3J0IHsgQ29uc3RydWN0IH0gZnJvbSBcImNvbnN0cnVjdHNcIjtcbmltcG9ydCB7IExPR19QUkVGSVggfSBmcm9tIFwiLi9jb25zdGFudHNcIjtcbmltcG9ydCB7IG5vcm1hbGl6ZUJhc2VQYXRoIH0gZnJvbSBcIi4vdXRpbHMvYmFzZS1wYXRoXCI7XG5cbi8qKlxuICogVGhlIFMzIG9iamVjdCBrZXkgcGF0dGVybiBjb3ZlcmluZyBldmVyeSBzdGF0aWMgYXNzZXQgdXBsb2FkZWQgdW5kZXJcbiAqIGBrZXlQcmVmaXhgIChgTmV4dGpzU3RhdGljQXNzZXRzLmtleVByZWZpeGApOiBgXCJiYXNlLypcImAsIG9yIGBcIipcImAgYXQgdGhlXG4gKiBidWNrZXQgcm9vdC4gRm9yIHNjb3BpbmcgdGhlIGNvbXB1dGUncyByZWFkIGdyYW50IHRvIHRoZSBhcHAncyBvd24gb2JqZWN0c1xuICogd2hlbiBzZXZlcmFsIGFwcHMgc2hhcmUgb25lIGJ1Y2tldC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHN0YXRpY0Fzc2V0c09iamVjdHNQYXR0ZXJuKGtleVByZWZpeD86IHN0cmluZyk6IHN0cmluZyB7XG4gIGlmIChrZXlQcmVmaXggJiYgVG9rZW4uaXNVbnJlc29sdmVkKGtleVByZWZpeCkpIHtcbiAgICByZXR1cm4gXCIqXCI7XG4gIH1cbiAgY29uc3QgcHJlZml4ID0gbm9ybWFsaXplQmFzZVBhdGgoa2V5UHJlZml4KTtcbiAgcmV0dXJuIHByZWZpeCA/IGAke3ByZWZpeH0vKmAgOiBcIipcIjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBOZXh0anNTdGF0aWNBc3NldHNPdmVycmlkZXMge1xuICByZWFkb25seSBidWNrZXRQcm9wcz86IEJ1Y2tldFByb3BzO1xuICByZWFkb25seSBidWNrZXREZXBsb3ltZW50UHJvcHM/OiBCdWNrZXREZXBsb3ltZW50UHJvcHM7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgTmV4dGpzU3RhdGljQXNzZXRzUHJvcHMge1xuICAvKipcbiAgICogQnJpbmcgeW91ciBvd24gUzMgYnVja2V0IGZvciBzdGF0aWMgYXNzZXRzLiBXaGVuIHByb3ZpZGVkLCBjZGstbmV4dGpzXG4gICAqIHdpbGwgc2tpcCBjcmVhdGluZyBhIG5ldyBidWNrZXQgYW5kIGRlcGxveSBhc3NldHMgdG8gdGhpcyBidWNrZXQgaW5zdGVhZC5cbiAgICogQ2FuIGJlIHNoYXJlZCBvbmx5IGJldHdlZW4gZGVwbG95bWVudHMgd2l0aCBkaWZmZXJlbnQgYGJhc2VQYXRoYHMgKFMzIGtleVxuICAgKiBwcmVmaXhlcyk6IHBydW5pbmcgaXMgc2NvcGVkIHRvIGA8YmFzZVBhdGg+L19uZXh0L2AsIGJ1dCB0d28gZGVwbG95bWVudHNcbiAgICogdW5kZXIgdGhlIHNhbWUgcHJlZml4IG92ZXJ3cml0ZSBlYWNoIG90aGVyJ3MgYHB1YmxpYy9gIGZpbGVzIGFuZCBwcnVuZSBlYWNoXG4gICAqIG90aGVyJ3Mgb2xkZXIgYF9uZXh0L2AgYXNzZXRzLlxuICAgKi9cbiAgcmVhZG9ubHkgYnVja2V0PzogSUJ1Y2tldDtcbiAgLyoqXG4gICAqIERpcmVjdG9yeSB3aGVyZSB0aGUgTmV4dC5qcyBhcHBsaWNhdGlvbiBpcyBsb2NhdGVkLlxuICAgKiBUaGlzIHNob3VsZCBjb250YWluIHRoZSAubmV4dCBkaXJlY3RvcnkgYW5kIG90aGVyIGJ1aWxkIGFydGlmYWN0cy5cbiAgICovXG4gIHJlYWRvbmx5IGJ1aWxkRGlyZWN0b3J5OiBzdHJpbmc7XG4gIC8qKlxuICAgKiBCdWlsZCBJRCBmcm9tIE5leHRqc0J1aWxkIHRvIHRyYWNrIGFzc2V0IHZlcnNpb25zXG4gICAqL1xuICByZWFkb25seSBidWlsZElkOiBzdHJpbmc7XG4gIC8qKlxuICAgKiBQcmVmaXggdG8gdGhlIFVSSSBwYXRoIHRoZSBhcHAgd2lsbCBiZSBzZXJ2ZWQgYXQuXG4gICAqIEBleGFtcGxlIFwiL215LWJhc2UtcGF0aFwiXG4gICAqL1xuICByZWFkb25seSBiYXNlUGF0aD86IHN0cmluZztcbiAgcmVhZG9ubHkgb3ZlcnJpZGVzPzogTmV4dGpzU3RhdGljQXNzZXRzT3ZlcnJpZGVzO1xufVxuXG4vKipcbiAqIENyZWF0ZXMgUzMgQnVja2V0IGZvciBwdWJsaWMgYW5kIF9uZXh0L3N0YXRpYyBhc3NldHMgYW5kIGRlcGxveXMgdGhlbSB1c2luZyBTM0RlcGxveW1lbnQuXG4gKi9cbmV4cG9ydCBjbGFzcyBOZXh0anNTdGF0aWNBc3NldHMgZXh0ZW5kcyBDb25zdHJ1Y3Qge1xuICBidWNrZXQ6IElCdWNrZXQ7XG4gIGRlcGxveW1lbnQ6IEJ1Y2tldERlcGxveW1lbnQ7XG4gIC8qKlxuICAgKiBTMyBrZXkgcHJlZml4IHRoZSBhc3NldHMgYXJlIGFjdHVhbGx5IHVwbG9hZGVkIHVuZGVyLCBub3JtYWxpemVkIHRvIGEgYmFyZVxuICAgKiBwYXRoIHNlZ21lbnQgKGVtcHR5IHdoZW4gdGhleSBsaXZlIGF0IHRoZSBidWNrZXQgcm9vdCkuXG4gICAqXG4gICAqIENvbnN1bWVycyB0aGF0IHJlYWQgYXNzZXRzIGJhY2sgb3V0IG9mIHRoZSBidWNrZXQgKHRoZSBydW50aW1lJ3MgaW1hZ2VcbiAgICogb3B0aW1pemVyLCBgTmV4dGpzQXBpYCdzIFMzIGludGVncmF0aW9ucykgbXVzdCB1c2UgdGhpcyByYXRoZXIgdGhhbiB0aGVcbiAgICogYGJhc2VQYXRoYCBwcm9wLCBzaW5jZSBgb3ZlcnJpZGVzLmJ1Y2tldERlcGxveW1lbnRQcm9wc2AgY2FuIHJlcGxhY2UgdGhlXG4gICAqIHByZWZpeCBvdXRyaWdodC4gTm9yIGNhbiB0aGV5IGRlcml2ZSBpdCBmcm9tIHRoZSBhcHAncyBvd24gYGJhc2VQYXRoYDogdGhhdFxuICAgKiBpcyB0aGUgcHJlZml4IG9mIHRoZSAqVVJMKiB0aGUgYXBwIGlzIHNlcnZlZCBhdCwgd2hpY2ggZm9yIHRoZSBBUEkgR2F0ZXdheVxuICAgKiBkZXBsb3ltZW50IHR5cGVzIGlzIHRoZSBzdGFnZSBuYW1lIGFuZCBoYXMgbm90aGluZyB0byBkbyB3aXRoIHdoZXJlIHRoZVxuICAgKiBieXRlcyB3ZXJlIHVwbG9hZGVkLlxuICAgKi9cbiAgcmVhZG9ubHkga2V5UHJlZml4OiBzdHJpbmc7XG4gIHByaXZhdGUgc3RhZ2luZ0Rpcj86IHN0cmluZztcblxuICBwcml2YXRlIHByb3BzOiBOZXh0anNTdGF0aWNBc3NldHNQcm9wcztcblxuICBjb25zdHJ1Y3RvcihzY29wZTogQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wczogTmV4dGpzU3RhdGljQXNzZXRzUHJvcHMpIHtcbiAgICBzdXBlcihzY29wZSwgaWQpO1xuICAgIHRoaXMucHJvcHMgPSBwcm9wcztcbiAgICB0aGlzLmtleVByZWZpeCA9IHRoaXMucmVzb2x2ZUtleVByZWZpeCgpO1xuICAgIHRoaXMuYnVja2V0ID0gcHJvcHMuYnVja2V0ID8/IHRoaXMuY3JlYXRlQnVja2V0KCk7XG4gICAgdGhpcy5kZXBsb3ltZW50ID0gdGhpcy5jcmVhdGVEZXBsb3ltZW50KCk7XG4gIH1cblxuICAvKipcbiAgICogUmVzb2x2ZXMgdGhlIHNpbmdsZSBwcmVmaXggYm90aCB0aGUgdXBsb2FkIGFuZCB0aGUgVVJMcyB1c2UuIEFcbiAgICogYGJ1Y2tldERlcGxveW1lbnRQcm9wcy5kZXN0aW5hdGlvbktleVByZWZpeGAgb3ZlcnJpZGUgd2lucyBvdmVyIGBiYXNlUGF0aGAsXG4gICAqIGJ1dCBpdCdzIG5vcm1hbGl6ZWQgaGVyZSBhbmQgYGNyZWF0ZURlcGxveW1lbnRgIHNldHMgdGhlIG5vcm1hbGl6ZWQgdmFsdWVcbiAgICogYWZ0ZXIgdGhlIG92ZXJyaWRlIHNwcmVhZCwgc28gYGtleVByZWZpeGAgY2FuJ3QgZHJpZnQgZnJvbSB3aGVyZSB0aGUgYXNzZXRzXG4gICAqIGxhbmQuXG4gICAqXG4gICAqIENvbXBhcmVkIGFnYWluc3QgYHVuZGVmaW5lZGAgcmF0aGVyIHRoYW4gdGVzdGVkIHdpdGggYGluYCwgYmVjYXVzZSBhIEpTSUlcbiAgICogbGFuZ3VhZ2UgYmluZGluZyAob3IgYSBwcm9ncmFtbWF0aWNhbGx5IGJ1aWx0IHByb3BzIG9iamVjdCkgY2FuIG1hdGVyaWFsaXplXG4gICAqIGFuIHVuc2V0IG9wdGlvbmFsIGZpZWxkIGFzIGFuIGV4cGxpY2l0IGB1bmRlZmluZWRgLiBUcmVhdGluZyB0aGF0IGFzIGFuXG4gICAqIGludGVudGlvbmFsIFwibW92ZSB0aGUgYXNzZXRzIHRvIHRoZSBidWNrZXQgcm9vdFwiIG92ZXJyaWRlIHdvdWxkIHNpbGVudGx5XG4gICAqIGRyb3AgYGJhc2VQYXRoYCBmcm9tIHRoZSBwcmVmaXguXG4gICAqL1xuICBwcml2YXRlIHJlc29sdmVLZXlQcmVmaXgoKTogc3RyaW5nIHtcbiAgICBjb25zdCBkZXBsb3ltZW50T3ZlcnJpZGVzID0gdGhpcy5wcm9wcy5vdmVycmlkZXM/LmJ1Y2tldERlcGxveW1lbnRQcm9wcztcbiAgICBjb25zdCBwcmVmaXggPVxuICAgICAgZGVwbG95bWVudE92ZXJyaWRlcz8uZGVzdGluYXRpb25LZXlQcmVmaXggIT09IHVuZGVmaW5lZFxuICAgICAgICA/IGRlcGxveW1lbnRPdmVycmlkZXMuZGVzdGluYXRpb25LZXlQcmVmaXhcbiAgICAgICAgOiB0aGlzLnByb3BzLmJhc2VQYXRoO1xuICAgIHJldHVybiBub3JtYWxpemVCYXNlUGF0aChwcmVmaXgpO1xuICB9XG5cbiAgcHJpdmF0ZSBjcmVhdGVCdWNrZXQoKSB7XG4gICAgcmV0dXJuIG5ldyBCdWNrZXQodGhpcywgXCJCdWNrZXRcIiwge1xuICAgICAgcmVtb3ZhbFBvbGljeTogUmVtb3ZhbFBvbGljeS5ERVNUUk9ZLFxuICAgICAgYXV0b0RlbGV0ZU9iamVjdHM6IHRydWUsXG4gICAgICBlbmZvcmNlU1NMOiB0cnVlLFxuICAgICAgYmxvY2tQdWJsaWNBY2Nlc3M6IEJsb2NrUHVibGljQWNjZXNzLkJMT0NLX0FMTCxcbiAgICAgIGVuY3J5cHRpb246IEJ1Y2tldEVuY3J5cHRpb24uUzNfTUFOQUdFRCxcbiAgICAgIG1pbmltdW1UTFNWZXJzaW9uOiAxLjIsXG4gICAgICAuLi50aGlzLnByb3BzLm92ZXJyaWRlcz8uYnVja2V0UHJvcHMsXG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGNyZWF0ZURlcGxveW1lbnQoKSB7XG4gICAgLy8gQ3JlYXRlIGEgc3RhZ2luZyBkaXJlY3Rvcnkgd2l0aCB0aGUgY29ycmVjdCBzdHJ1Y3R1cmVcbiAgICB0aGlzLnN0YWdpbmdEaXIgPSB0aGlzLmNyZWF0ZVN0YWdpbmdEaXJlY3RvcnkoKTtcblxuICAgIGlmICghdGhpcy5zdGFnaW5nRGlyKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIGBObyBzdGF0aWMgYXNzZXRzIGZvdW5kIHRvIGRlcGxveS4gRW5zdXJlIHlvdXIgTmV4dC5qcyBidWlsZCBvdXRwdXQgY29udGFpbnMgZWl0aGVyOlxuICAgICAgICAtIEEgJ3B1YmxpYycgZGlyZWN0b3J5IGF0OiAke2pvaW4odGhpcy5wcm9wcy5idWlsZERpcmVjdG9yeSwgXCJwdWJsaWNcIil9XG4gICAgICAgIC0gQSAnLm5leHQvc3RhdGljJyBkaXJlY3RvcnkgYXQ6ICR7am9pbih0aGlzLnByb3BzLmJ1aWxkRGlyZWN0b3J5LCBcIi5uZXh0XCIsIFwic3RhdGljXCIpfWAsXG4gICAgICApO1xuICAgIH1cblxuICAgIHJldHVybiBuZXcgQnVja2V0RGVwbG95bWVudCh0aGlzLCBcIkRlcGxveW1lbnRcIiwge1xuICAgICAgc291cmNlczogW1NvdXJjZS5hc3NldCh0aGlzLnN0YWdpbmdEaXIpXSxcbiAgICAgIGRlc3RpbmF0aW9uQnVja2V0OiB0aGlzLmJ1Y2tldCxcbiAgICAgIC8vIEFkZCBCVUlMRF9JRCBhcyBtZXRhZGF0YSB0byBhbGwgb2JqZWN0cyBmb3IgdmVyc2lvbiB0cmFja2luZ1xuICAgICAgbWV0YWRhdGE6IHtcbiAgICAgICAgQlVJTERfSUQ6IHRoaXMucHJvcHMuYnVpbGRJZCxcbiAgICAgIH0sXG4gICAgICBwcnVuZTogZmFsc2UsIC8vIERvbid0IGRlbGV0ZSBleGlzdGluZyBhc3NldHMgdG8gcHJldmVudCA0MDRzIGR1cmluZyBkZXBsb3ltZW50LCBwcnVuaW5nIHdpbGwgYmUgaGFuZGxlZCBieSBwb3N0LWRlcGxveVxuICAgICAgLy8gUzNEZXBsb3ltZW50IGF1dG9tYXRpY2FsbHkgZGV0ZWN0cyBjb250ZW50IHR5cGVzIGJhc2VkIG9uIGZpbGUgZXh0ZW5zaW9uc1xuICAgICAgLi4udGhpcy5wcm9wcy5vdmVycmlkZXM/LmJ1Y2tldERlcGxveW1lbnRQcm9wcyxcbiAgICAgIC8vIFNldCBhZnRlciB0aGUgc3ByZWFkOiBgcmVzb2x2ZUtleVByZWZpeGAgYWxyZWFkeSBmb2xkZWQgaW4gYW55XG4gICAgICAvLyBgZGVzdGluYXRpb25LZXlQcmVmaXhgIG92ZXJyaWRlLCBzbyB0aGlzIGlzIHRoZSBub3JtYWxpemVkIGZvcm0gb2YgaXQuXG4gICAgICAvLyBMZXR0aW5nIHRoZSByYXcgb3ZlcnJpZGUgdGhyb3VnaCBoZXJlIHdvdWxkIHVwbG9hZCB0aGUgYXNzZXRzIHNvbWV3aGVyZVxuICAgICAgLy8gb3RoZXIgdGhhbiB0aGUgYGtleVByZWZpeGAgdXNlZCB0byBidWlsZCB0aGVpciBVUkxzLlxuICAgICAgZGVzdGluYXRpb25LZXlQcmVmaXg6IHRoaXMua2V5UHJlZml4IHx8IHVuZGVmaW5lZCxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGUgYSBzdGFnaW5nIGRpcmVjdG9yeSB3aXRoIHRoZSBjb3JyZWN0IHN0cnVjdHVyZTpcbiAgICogLSBwdWJsaWMvIGZpbGVzIGdvIHRvIHJvb3RcbiAgICogLSAubmV4dC9zdGF0aWMvIGZpbGVzIGdvIHRvIF9uZXh0L3N0YXRpYy9cbiAgICovXG4gIHByaXZhdGUgY3JlYXRlU3RhZ2luZ0RpcmVjdG9yeSgpOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICAgIGNvbnN0IHN0YWdpbmdEaXIgPSBta2R0ZW1wU3luYyhqb2luKHRtcGRpcigpLCBcIm5leHRqcy1hc3NldHMtXCIpKTtcbiAgICBsZXQgaGFzQXNzZXRzID0gZmFsc2U7XG5cbiAgICB0cnkge1xuICAgICAgLy8gQ29weSBwdWJsaWMgZGlyZWN0b3J5IGNvbnRlbnRzIHRvIHN0YWdpbmcgcm9vdFxuICAgICAgY29uc3QgcHVibGljUGF0aCA9IGpvaW4odGhpcy5wcm9wcy5idWlsZERpcmVjdG9yeSwgXCJwdWJsaWNcIik7XG4gICAgICBpZiAodGhpcy5kaXJlY3RvcnlFeGlzdHMocHVibGljUGF0aCkpIHtcbiAgICAgICAgY3BTeW5jKHB1YmxpY1BhdGgsIHN0YWdpbmdEaXIsIHsgcmVjdXJzaXZlOiB0cnVlIH0pO1xuICAgICAgICBoYXNBc3NldHMgPSB0cnVlO1xuICAgICAgfVxuXG4gICAgICAvLyBDb3B5IC5uZXh0L3N0YXRpYyB0byBzdGFnaW5nL19uZXh0L3N0YXRpY1xuICAgICAgY29uc3Qgc3RhdGljUGF0aCA9IGpvaW4odGhpcy5wcm9wcy5idWlsZERpcmVjdG9yeSwgXCIubmV4dFwiLCBcInN0YXRpY1wiKTtcbiAgICAgIGlmICh0aGlzLmRpcmVjdG9yeUV4aXN0cyhzdGF0aWNQYXRoKSkge1xuICAgICAgICBjb25zdCBuZXh0RGlyID0gam9pbihzdGFnaW5nRGlyLCBcIl9uZXh0XCIpO1xuICAgICAgICBjb25zdCBzdGF0aWNEZXN0RGlyID0gam9pbihuZXh0RGlyLCBcInN0YXRpY1wiKTtcblxuICAgICAgICAvLyBDcmVhdGUgX25leHQgZGlyZWN0b3J5XG4gICAgICAgIG1rZGlyU3luYyhuZXh0RGlyLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcblxuICAgICAgICAvLyBDb3B5IHN0YXRpYyBhc3NldHNcbiAgICAgICAgY3BTeW5jKHN0YXRpY1BhdGgsIHN0YXRpY0Rlc3REaXIsIHsgcmVjdXJzaXZlOiB0cnVlIH0pO1xuICAgICAgICBoYXNBc3NldHMgPSB0cnVlO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gaGFzQXNzZXRzID8gc3RhZ2luZ0RpciA6IHVuZGVmaW5lZDtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgY29uc29sZS5lcnJvcihgJHtMT0dfUFJFRklYfSBFcnJvciBjcmVhdGluZyBzdGFnaW5nIGRpcmVjdG9yeTpgLCBlcnJvcik7XG4gICAgICAvLyBDbGVhbiB1cCBvbiBlcnJvclxuICAgICAgdHJ5IHtcbiAgICAgICAgcm1TeW5jKHN0YWdpbmdEaXIsIHsgcmVjdXJzaXZlOiB0cnVlLCBmb3JjZTogdHJ1ZSB9KTtcbiAgICAgIH0gY2F0Y2gge1xuICAgICAgICAvLyBJZ25vcmUgY2xlYW51cCBlcnJvcnNcbiAgICAgIH1cbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIENoZWNrIGlmIGEgZGlyZWN0b3J5IGV4aXN0c1xuICAgKi9cbiAgcHJpdmF0ZSBkaXJlY3RvcnlFeGlzdHMoZGlyUGF0aDogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiBleGlzdHNTeW5jKGRpclBhdGgpICYmIHN0YXRTeW5jKGRpclBhdGgpLmlzRGlyZWN0b3J5KCk7XG4gICAgfSBjYXRjaCB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG59XG4iXX0=
|
|
401
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmV4dGpzLXN0YXRpYy1hc3NldHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvbmV4dGpzLXN0YXRpYy1hc3NldHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBcUNBLGdFQU1DOztBQTNDRCxxQ0FTaUI7QUFDakIscUNBQWlDO0FBQ2pDLHlDQUFnRDtBQUNoRCw2Q0FBNkQ7QUFDN0QsK0NBTTRCO0FBQzVCLHFFQUt1QztBQUN2QywwREFBNEM7QUFDNUMsMkNBQXVDO0FBQ3ZDLDJDQUF5QztBQUN6QyxpREFBc0Q7QUFFdEQ7Ozs7O0dBS0c7QUFDSCxTQUFnQiwwQkFBMEIsQ0FBQyxTQUFrQjtJQUMzRCxJQUFJLFNBQVMsSUFBSSxtQkFBSyxDQUFDLFlBQVksQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDO1FBQy9DLE9BQU8sR0FBRyxDQUFDO0lBQ2IsQ0FBQztJQUNELE1BQU0sTUFBTSxHQUFHLElBQUEsNkJBQWlCLEVBQUMsU0FBUyxDQUFDLENBQUM7SUFDNUMsT0FBTyxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsTUFBTSxJQUFJLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQztBQUN0QyxDQUFDO0FBRUQsb0VBQW9FO0FBQ3BFLE1BQU0sV0FBVyxHQUFHLElBQUEsZ0JBQUksRUFBQyxPQUFPLEVBQUUsUUFBUSxDQUFDLENBQUM7QUFDNUMsNkVBQTZFO0FBQzdFLE1BQU0sa0JBQWtCLEdBQUcsZ0JBQWdCLENBQUM7QUFFNUM7Ozs7Ozs7Ozs7R0FVRztBQUNILFNBQVMsU0FBUyxDQUFDLEdBQVc7SUFDNUIsTUFBTSxLQUFLLEdBQWEsRUFBRSxDQUFDO0lBQzNCLE1BQU0sSUFBSSxHQUFHLENBQUMsR0FBVyxFQUFFLFNBQThCLEVBQUUsRUFBRTtRQUMzRCxNQUFNLElBQUksR0FBRyxJQUFBLHNCQUFZLEVBQUMsSUFBQSxnQkFBSSxFQUFDLEdBQUcsRUFBRSxHQUFHLENB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QyxPQUFlO1FBQ3JDLElBQUksQ0FBQztZQUNILE9BQU8sSUFBQSxvQkFBVSxFQUFDLE9BQU8sQ0FBQyxJQUFJLElBQUEsa0JBQVEsRUFBQyxPQUFPLENBQUMsQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUNoRSxDQUFDO1FBQUMsTUFBTSxDQUFDO1lBQ1AsT0FBTyxLQUFLLENBQUM7UUFDZixDQUFDO0lBQ0gsQ0FBQzs7QUFqVUgsZ0RBa1VDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgY3BTeW5jLFxuICBleGlzdHNTeW5jLFxuICBta2RpclN5bmMsXG4gIG1rZHRlbXBTeW5jLFxuICByZWFkZGlyU3luYyxcbiAgcmVhbHBhdGhTeW5jLFxuICBybVN5bmMsXG4gIHN0YXRTeW5jLFxufSBmcm9tIFwibm9kZTpmc1wiO1xuaW1wb3J0IHsgdG1wZGlyIH0gZnJvbSBcIm5vZGU6b3NcIjtcbmltcG9ydCB7IGpvaW4sIHJlbGF0aXZlLCBzZXAgfSBmcm9tIFwibm9kZTpwYXRoXCI7XG5pbXBvcnQgeyBEdXJhdGlvbiwgUmVtb3ZhbFBvbGljeSwgVG9rZW4gfSBmcm9tIFwiYXdzLWNkay1saWJcIjtcbmltcG9ydCB7XG4gIEJsb2NrUHVibGljQWNjZXNzLFxuICBCdWNrZXQsXG4gIEJ1Y2tldEVuY3J5cHRpb24sXG4gIEJ1Y2tldFByb3BzLFxuICBJQnVja2V0LFxufSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLXMzXCI7XG5pbXBvcnQge1xuICBCdWNrZXREZXBsb3ltZW50LFxuICBCdWNrZXREZXBsb3ltZW50UHJvcHMsXG4gIENhY2hlQ29udHJvbCxcbiAgU291cmNlLFxufSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLXMzLWRlcGxveW1lbnRcIjtcbmltcG9ydCAqIGFzIGN4YXBpIGZyb20gXCJhd3MtY2RrLWxpYi9jeC1hcGlcIjtcbmltcG9ydCB7IENvbnN0cnVjdCB9IGZyb20gXCJjb25zdHJ1Y3RzXCI7XG5pbXBvcnQgeyBMT0dfUFJFRklYIH0gZnJvbSBcIi4vY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBub3JtYWxpemVCYXNlUGF0aCB9IGZyb20gXCIuL3V0aWxzL2Jhc2UtcGF0aFwiO1xuXG4vKipcbiAqIFRoZSBTMyBvYmplY3Qga2V5IHBhdHRlcm4gY292ZXJpbmcgZXZlcnkgc3RhdGljIGFzc2V0IHVwbG9hZGVkIHVuZGVyXG4gKiBga2V5UHJlZml4YCAoYE5leHRqc1N0YXRpY0Fzc2V0cy5rZXlQcmVmaXhgKTogYFwiYmFzZS8qXCJgLCBvciBgXCIqXCJgIGF0IHRoZVxuICogYnVja2V0IHJvb3QuIEZvciBzY29waW5nIHRoZSBjb21wdXRlJ3MgcmVhZCBncmFudCB0byB0aGUgYXBwJ3Mgb3duIG9iamVjdHNcbiAqIHdoZW4gc2V2ZXJhbCBhcHBzIHNoYXJlIG9uZSBidWNrZXQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzdGF0aWNBc3NldHNPYmplY3RzUGF0dGVybihrZXlQcmVmaXg/OiBzdHJpbmcpOiBzdHJpbmcge1xuICBpZiAoa2V5UHJlZml4ICYmIFRva2VuLmlzVW5yZXNvbHZlZChrZXlQcmVmaXgpKSB7XG4gICAgcmV0dXJuIFwiKlwiO1xuICB9XG4gIGNvbnN0IHByZWZpeCA9IG5vcm1hbGl6ZUJhc2VQYXRoKGtleVByZWZpeCk7XG4gIHJldHVybiBwcmVmaXggPyBgJHtwcmVmaXh9LypgIDogXCIqXCI7XG59XG5cbi8qKiBXaGVyZSBgLm5leHQvc3RhdGljYCBpcyBzZXJ2ZWQgZnJvbSwgcmVsYXRpdmUgdG8gYGtleVByZWZpeGAuICovXG5jb25zdCBTVEFUSUNfUEFUSCA9IGpvaW4oXCJfbmV4dFwiLCBcInN0YXRpY1wiKTtcbi8qKiBXaGVyZSBOZXh0LmpzIGNvbXBpbGVzIHNlcnZpY2Ugd29ya2VycyB0bywgcmVsYXRpdmUgdG8gYC5uZXh0L3N0YXRpY2AuICovXG5jb25zdCBTRVJWSUNFX1dPUktFUl9ESVIgPSBcInNlcnZpY2Utd29ya2VyXCI7XG5cbi8qKlxuICogRXZlcnkgZmlsZSB1bmRlciBgZGlyYCwgcmVsYXRpdmUgdG8gaXQsIHRocm91Z2ggc3ltbGlua3MgdG9vOiBDREsgdXBsb2FkcyBhXG4gKiBsaW5rZWQgZmlsZSBvciBkaXJlY3RvcnkgYXMgd2hhdCBpdCBwb2ludHMgdG8sIHVuZGVyIGV2ZXJ5IG5hbWUgaXQncyByZWFjaGVkXG4gKiBieS5cbiAqXG4gKiBBbiBleHBsaWNpdCB3YWxrIHJhdGhlciB0aGFuIGByZWFkZGlyU3luYyh7IHJlY3Vyc2l2ZTogdHJ1ZSB9KWAsIHdoaWNoIG5ldmVyXG4gKiByZXR1cm5zIG9uIGEgc3ltbGluayBjeWNsZSAoTm9kZSAyNCBmb2xsb3dzIGRpcmVjdG9yeSBsaW5rcyksIGFuZCB3aG9zZVxuICogYERpcmVudC5wYXJlbnRQYXRoYCBkb2Vzbid0IGV4aXN0IGJlZm9yZSBOb2RlIDIwLjEyLiBBIGxpbmsgYmFjayB0byBhXG4gKiBkaXJlY3RvcnkgYWxyZWFkeSBvbiB0aGUgY3VycmVudCBwYXRoIGlzIGEgY3ljbGUgYW5kIGlzbid0IGZvbGxvd2VkOyBvbmUgdGhhdFxuICogY2FuJ3QgYmUgc3RhdCdkIChkYW5nbGluZywgb3IgYSBsb29wIG9mIGxpbmtzKSBjb3VudHMgYXMgYSBmaWxlLlxuICovXG5mdW5jdGlvbiBsaXN0RmlsZXMoZGlyOiBzdHJpbmcpOiBzdHJpbmdbXSB7XG4gIGNvbnN0IGZpbGVzOiBzdHJpbmdbXSA9IFtdO1xuICBjb25zdCB3YWxrID0gKHN1Yjogc3RyaW5nLCBhbmNlc3RvcnM6IFJlYWRvbmx5U2V0PHN0cmluZz4pID0+IHtcbiAgICBjb25zdCByZWFsID0gcmVhbHBhdGhTeW5jKGpvaW4oZGlyLCBzdWIpKTtcbiAgICBpZiAoYW5jZXN0b3JzLmhhcyhyZWFsKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBwYXRoID0gbmV3IFNldChhbmNlc3RvcnMpLmFkZChyZWFsKTtcbiAgICBmb3IgKGNvbnN0IGVudHJ5IG9mIHJlYWRkaXJTeW5jKHJlYWwsIHsgd2l0aEZpbGVUeXBlczogdHJ1ZSB9KSkge1xuICAgICAgY29uc3QgY2hpbGQgPSBqb2luKHN1YiwgZW50cnkubmFtZSk7XG4gICAgICBpZiAoXG4gICAgICAgIGVudHJ5LmlzRGlyZWN0b3J5KCkgfHxcbiAgICAgICAgKGVudHJ5LmlzU3ltYm9saWNMaW5rKCkgJiYgaXNEaXJlY3RvcnlMaW5rKGpvaW4ocmVhbCwgZW50cnkubmFtZSkpKVxuICAgICAgKSB7XG4gICAgICAgIHdhbGsoY2hpbGQsIHBhdGgpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZmlsZXMucHVzaChjaGlsZCk7XG4gICAgICB9XG4gICAgfVxuICB9O1xuICB3YWxrKFwiXCIsIG5ldyBTZXQoKSk7XG4gIHJldHVybiBmaWxlcztcbn1cblxuZnVuY3Rpb24gaXNEaXJlY3RvcnlMaW5rKHBhdGg6IHN0cmluZyk6IGJvb2xlYW4ge1xuICB0cnkge1xuICAgIHJldHVybiBzdGF0U3luYyhwYXRoKS5pc0RpcmVjdG9yeSgpO1xuICB9IGNhdGNoIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn1cblxuLyoqIFdoZXRoZXIgdGhlIHJlbGF0aXZlIGBwYXRoYCBpcyBgZGlyYCBvciBpbnNpZGUgaXQuICovXG5mdW5jdGlvbiBpc1dpdGhpbihwYXRoOiBzdHJpbmcsIGRpcjogc3RyaW5nKTogYm9vbGVhbiB7XG4gIHJldHVybiBwYXRoID09PSBkaXIgfHwgcGF0aC5zdGFydHNXaXRoKGRpciArIHNlcCk7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgTmV4dGpzU3RhdGljQXNzZXRzT3ZlcnJpZGVzIHtcbiAgcmVhZG9ubHkgYnVja2V0UHJvcHM/OiBCdWNrZXRQcm9wcztcbiAgLyoqXG4gICAqIEFwcGxpZWQgdG8gZXZlcnkgdXBsb2FkIChgcHVibGljL2AsIGBfbmV4dC9zdGF0aWMvYCBhbmRcbiAgICogYF9uZXh0L3N0YXRpYy9zZXJ2aWNlLXdvcmtlci9gKSwgZXhjZXB0IHRoYXQgdGhlIHR3byBgX25leHQvc3RhdGljYCB1cGxvYWRzXG4gICAqIGFsd2F5cyBrZWVwIHRoZSBgQ2FjaGUtQ29udHJvbGAgTmV4dC5qcyBzZW5kcyBmb3IgdGhlbS4gU28gYSBgY2FjaGVDb250cm9sYFxuICAgKiBoZXJlIHNldHMgdGhlIGhlYWRlciBmb3IgYHB1YmxpYy9gIGZpbGVzIG9ubHksIHdoaWxlIGFueXRoaW5nIGVsc2UsIHN1Y2ggYXNcbiAgICogYSBgZGlzdHJpYnV0aW9uYCB0byBpbnZhbGlkYXRlLCBhcHBsaWVzIHRvIGVhY2ggdXBsb2FkIGluIHR1cm4uXG4gICAqXG4gICAqIGBzb3VyY2VzYCBhbmQgYGRlc3RpbmF0aW9uQnVja2V0YCwgd2hpY2ggdGhlIHR5cGUgcmVxdWlyZXMsIGFyZSBpZ25vcmVkOlxuICAgKiB0aGUgdXBsb2FkcyBhcmUgYWx3YXlzIHRoZSBidWlsZCdzIGFzc2V0cywgdG8gdGhlIGJ1Y2tldCBDbG91ZEZyb250IGFuZFxuICAgKiBBUEkgR2F0ZXdheSByZWFkIGZyb20gKHBhc3MgYGJ1Y2tldGAgdG8gYnJpbmcgeW91ciBvd24pLiBgcHJ1bmU6IHRydWVgIGFuZFxuICAgKiBgcmV0YWluT25EZWxldGU6IGZhbHNlYCBhcmUgcmVqZWN0ZWQsIHNpbmNlIGVhY2ggd291bGQgYnJlYWsgdGhlIG90aGVyXG4gICAqIHVwbG9hZHMuXG4gICAqL1xuICByZWFkb25seSBidWNrZXREZXBsb3ltZW50UHJvcHM/OiBCdWNrZXREZXBsb3ltZW50UHJvcHM7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgTmV4dGpzU3RhdGljQXNzZXRzUHJvcHMge1xuICAvKipcbiAgICogQnJpbmcgeW91ciBvd24gUzMgYnVja2V0IGZvciBzdGF0aWMgYXNzZXRzLiBXaGVuIHByb3ZpZGVkLCBjZGstbmV4dGpzXG4gICAqIHdpbGwgc2tpcCBjcmVhdGluZyBhIG5ldyBidWNrZXQgYW5kIGRlcGxveSBhc3NldHMgdG8gdGhpcyBidWNrZXQgaW5zdGVhZC5cbiAgICogQ2FuIGJlIHNoYXJlZCBvbmx5IGJldHdlZW4gZGVwbG95bWVudHMgd2l0aCBkaWZmZXJlbnQgYGJhc2VQYXRoYHMgKFMzIGtleVxuICAgKiBwcmVmaXhlcyk6IHBydW5pbmcgaXMgc2NvcGVkIHRvIGA8YmFzZVBhdGg+L19uZXh0L2AsIGJ1dCB0d28gZGVwbG95bWVudHNcbiAgICogdW5kZXIgdGhlIHNhbWUgcHJlZml4IG92ZXJ3cml0ZSBlYWNoIG90aGVyJ3MgYHB1YmxpYy9gIGZpbGVzIGFuZCBwcnVuZSBlYWNoXG4gICAqIG90aGVyJ3Mgb2xkZXIgYF9uZXh0L2AgYXNzZXRzLlxuICAgKi9cbiAgcmVhZG9ubHkgYnVja2V0PzogSUJ1Y2tldDtcbiAgLyoqXG4gICAqIERpcmVjdG9yeSB3aGVyZSB0aGUgTmV4dC5qcyBhcHBsaWNhdGlvbiBpcyBsb2NhdGVkLlxuICAgKiBUaGlzIHNob3VsZCBjb250YWluIHRoZSAubmV4dCBkaXJlY3RvcnkgYW5kIG90aGVyIGJ1aWxkIGFydGlmYWN0cy5cbiAgICovXG4gIHJlYWRvbmx5IGJ1aWxkRGlyZWN0b3J5OiBzdHJpbmc7XG4gIC8qKlxuICAgKiBCdWlsZCBJRCBmcm9tIE5leHRqc0J1aWxkIHRvIHRyYWNrIGFzc2V0IHZlcnNpb25zXG4gICAqL1xuICByZWFkb25seSBidWlsZElkOiBzdHJpbmc7XG4gIC8qKlxuICAgKiBQcmVmaXggdG8gdGhlIFVSSSBwYXRoIHRoZSBhcHAgd2lsbCBiZSBzZXJ2ZWQgYXQuXG4gICAqIEBleGFtcGxlIFwiL215LWJhc2UtcGF0aFwiXG4gICAqL1xuICByZWFkb25seSBiYXNlUGF0aD86IHN0cmluZztcbiAgcmVhZG9ubHkgb3ZlcnJpZGVzPzogTmV4dGpzU3RhdGljQXNzZXRzT3ZlcnJpZGVzO1xufVxuXG4vKipcbiAqIENyZWF0ZXMgUzMgQnVja2V0IGZvciBwdWJsaWMgYW5kIF9uZXh0L3N0YXRpYyBhc3NldHMgYW5kIGRlcGxveXMgdGhlbSB1c2luZyBTM0RlcGxveW1lbnQuXG4gKi9cbmV4cG9ydCBjbGFzcyBOZXh0anNTdGF0aWNBc3NldHMgZXh0ZW5kcyBDb25zdHJ1Y3Qge1xuICBidWNrZXQ6IElCdWNrZXQ7XG4gIC8qKlxuICAgKiBUaGUgZmlyc3Qgb2YgYHN0YXRpY0RlcGxveW1lbnRgLCBgc2VydmljZVdvcmtlckRlcGxveW1lbnRgIGFuZFxuICAgKiBgcHVibGljRGVwbG95bWVudGAgdGhlIGJ1aWxkIGhhcyBmaWxlcyBmb3IuXG4gICAqXG4gICAqIEBkZXByZWNhdGVkIFRoZSBhc3NldHMgYXJlIHVwbG9hZGVkIGJ5IHVwIHRvIHRocmVlIGRlcGxveW1lbnRzLCBhbmQgdGhpc1xuICAgKiBpcyBvbmx5IG9uZSBvZiB0aGVtOiBhIGRlcGVuZGVuY3kgb24gaXQgZG9lc24ndCB3YWl0IGZvciB0aGUgb3RoZXJzLiBVc2VcbiAgICogYHN0YXRpY0RlcGxveW1lbnRgLCBgc2VydmljZVdvcmtlckRlcGxveW1lbnRgIGFuZCBgcHVibGljRGVwbG95bWVudGAuXG4gICAqL1xuICBkZXBsb3ltZW50OiBCdWNrZXREZXBsb3ltZW50O1xuICAvKipcbiAgICogVXBsb2FkcyBgLm5leHQvc3RhdGljYCB0byBgX25leHQvc3RhdGljL2Agd2l0aFxuICAgKiBgQ2FjaGUtQ29udHJvbDogcHVibGljLCBtYXgtYWdlPTMxNTM2MDAwLCBpbW11dGFibGVgLCBleGNlcHQgZm9yXG4gICAqIGBzZXJ2aWNlLXdvcmtlci9gIChzZWUgYHNlcnZpY2VXb3JrZXJEZXBsb3ltZW50YCkuIEFic2VudCBpZiB0aGUgYnVpbGQgaGFzXG4gICAqIG5vIGAubmV4dC9zdGF0aWNgLlxuICAgKi9cbiAgcmVhZG9ubHkgc3RhdGljRGVwbG95bWVudD86IEJ1Y2tldERlcGxveW1lbnQ7XG4gIC8qKlxuICAgKiBVcGxvYWRzIGAubmV4dC9zdGF0aWMvc2VydmljZS13b3JrZXJgIHdpdGhcbiAgICogYENhY2hlLUNvbnRyb2w6IHB1YmxpYywgbWF4LWFnZT0wLCBtdXN0LXJldmFsaWRhdGVgLCBhcyBOZXh0LmpzIHNlcnZlcyBpdDpcbiAgICogYSBzZXJ2aWNlIHdvcmtlciBrZWVwcyBpdHMgVVJMIGFjcm9zcyBidWlsZHMsIHNvIGl0IGNhbid0IGJlIGBpbW11dGFibGVgLlxuICAgKiBBYnNlbnQgaWYgdGhlIGJ1aWxkIGhhcyBubyBzZXJ2aWNlIHdvcmtlci5cbiAgICovXG4gIHJlYWRvbmx5IHNlcnZpY2VXb3JrZXJEZXBsb3ltZW50PzogQnVja2V0RGVwbG95bWVudDtcbiAgLyoqXG4gICAqIFVwbG9hZHMgYHB1YmxpYy9gLCBzZXBhcmF0ZWx5IGZyb20gYHN0YXRpY0RlcGxveW1lbnRgIGJlY2F1c2UgaXRzIGZpbGVzXG4gICAqIGtlZXAgdGhlaXIgbmFtZXMgd2hlbiB0aGV5IGNoYW5nZSBhbmQgc28gY2FuJ3QgYmUgYGltbXV0YWJsZWAuIEFic2VudCBpZlxuICAgKiB0aGUgYnVpbGQgaGFzIG5vIGBwdWJsaWNgIGRpcmVjdG9yeS5cbiAgICovXG4gIHJlYWRvbmx5IHB1YmxpY0RlcGxveW1lbnQ/OiBCdWNrZXREZXBsb3ltZW50O1xuICAvKipcbiAgICogUzMga2V5IHByZWZpeCB0aGUgYXNzZXRzIGFyZSBhY3R1YWxseSB1cGxvYWRlZCB1bmRlciwgbm9ybWFsaXplZCB0byBhIGJhcmVcbiAgICogcGF0aCBzZWdtZW50IChlbXB0eSB3aGVuIHRoZXkgbGl2ZSBhdCB0aGUgYnVja2V0IHJvb3QpLlxuICAgKlxuICAgKiBDb25zdW1lcnMgdGhhdCByZWFkIGFzc2V0cyBiYWNrIG91dCBvZiB0aGUgYnVja2V0ICh0aGUgcnVudGltZSdzIGltYWdlXG4gICAqIG9wdGltaXplciwgYE5leHRqc0FwaWAncyBTMyBpbnRlZ3JhdGlvbnMpIG11c3QgdXNlIHRoaXMgcmF0aGVyIHRoYW4gdGhlXG4gICAqIGBiYXNlUGF0aGAgcHJvcCwgc2luY2UgYG92ZXJyaWRlcy5idWNrZXREZXBsb3ltZW50UHJvcHNgIGNhbiByZXBsYWNlIHRoZVxuICAgKiBwcmVmaXggb3V0cmlnaHQuIE5vciBjYW4gdGhleSBkZXJpdmUgaXQgZnJvbSB0aGUgYXBwJ3Mgb3duIGBiYXNlUGF0aGA6IHRoYXRcbiAgICogaXMgdGhlIHByZWZpeCBvZiB0aGUgKlVSTCogdGhlIGFwcCBpcyBzZXJ2ZWQgYXQsIHdoaWNoIGZvciB0aGUgQVBJIEdhdGV3YXlcbiAgICogZGVwbG95bWVudCB0eXBlcyBpcyB0aGUgc3RhZ2UgbmFtZSBhbmQgaGFzIG5vdGhpbmcgdG8gZG8gd2l0aCB3aGVyZSB0aGVcbiAgICogYnl0ZXMgd2VyZSB1cGxvYWRlZC5cbiAgICovXG4gIHJlYWRvbmx5IGtleVByZWZpeDogc3RyaW5nO1xuXG4gIHByaXZhdGUgcHJvcHM6IE5leHRqc1N0YXRpY0Fzc2V0c1Byb3BzO1xuXG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBDb25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByb3BzOiBOZXh0anNTdGF0aWNBc3NldHNQcm9wcykge1xuICAgIHN1cGVyKHNjb3BlLCBpZCk7XG4gICAgdGhpcy5wcm9wcyA9IHByb3BzO1xuICAgIHRoaXMudmFsaWRhdGVEZXBsb3ltZW50T3ZlcnJpZGVzKCk7XG4gICAgdGhpcy5rZXlQcmVmaXggPSB0aGlzLnJlc29sdmVLZXlQcmVmaXgoKTtcbiAgICB0aGlzLmJ1Y2tldCA9IHByb3BzLmJ1Y2tldCA/PyB0aGlzLmNyZWF0ZUJ1Y2tldCgpO1xuICAgIGNvbnN0IHN0YWdlZDogc3RyaW5nW10gPSBbXTtcbiAgICB0cnkge1xuICAgICAgY29uc3QgdXBsb2FkcyA9IHRoaXMuY3JlYXRlRGVwbG95bWVudHMoc3RhZ2VkKTtcbiAgICAgIHRoaXMuc3RhdGljRGVwbG95bWVudCA9IHVwbG9hZHMuc3RhdGljRGVwbG95bWVudDtcbiAgICAgIHRoaXMuc2VydmljZVdvcmtlckRlcGxveW1lbnQgPSB1cGxvYWRzLnNlcnZpY2VXb3JrZXJEZXBsb3ltZW50O1xuICAgICAgdGhpcy5wdWJsaWNEZXBsb3ltZW50ID0gdXBsb2Fkcy5wdWJsaWNEZXBsb3ltZW50O1xuICAgIH0gZmluYWxseSB7XG4gICAgICAvLyBgU291cmNlLmFzc2V0YCBzdGFnZXMgZHVyaW5nIGBCdWNrZXREZXBsb3ltZW50YCdzIGNvbnN0cnVjdGlvbiAoQ0RLJ3NcbiAgICAgIC8vIGBBc3NldFN0YWdpbmdgIGNvcGllcyBpbnRvIGBjZGsub3V0YCBmcm9tIGl0cyBvd24gY29uc3RydWN0b3IpLCBzbyB0aGVcbiAgICAgIC8vIHRlbXBvcmFyeSBjb3BpZXMgYXJlIGRlYWQgb25jZSB0aGUgZGVwbG95bWVudHMgZXhpc3QsIG9yIG9uY2Ugb25lIG9mXG4gICAgICAvLyB0aGVtIGZhaWxlZC4gTGVmdCBiZWhpbmQsIGV2ZXJ5IHN5bnRoIHdvdWxkIGFkZCBhbm90aGVyIGZ1bGwgY29weSBvZlxuICAgICAgLy8gdGhlIGFwcCdzIHN0YXRpYyBhc3NldHMgdG8gdGhlIHRlbXAgZGlyZWN0b3J5LlxuICAgICAgLy9cbiAgICAgIC8vIFVubGVzcyBzdGFnaW5nIGlzIGRpc2FibGVkIChgY2RrIHN5bnRoIC0tbm8tc3RhZ2luZ2AsIGFuZCBTQU0sIHdoaWNoXG4gICAgICAvLyBzZXRzIHRoZSBzYW1lIGNvbnRleHQpOiB0aGVuIHRoZSBhc3NldCBtYW5pZmVzdCBwb2ludHMgYXQgdGhlc2VcbiAgICAgIC8vIGRpcmVjdG9yaWVzIHRoZW1zZWx2ZXMsIGFuZCByZW1vdmluZyB0aGVtIHdvdWxkIGZhaWwgdGhlIHB1Ymxpc2ggdGhhdFxuICAgICAgLy8gZm9sbG93cy5cbiAgICAgIGlmICghdGhpcy5ub2RlLnRyeUdldENvbnRleHQoY3hhcGkuRElTQUJMRV9BU1NFVF9TVEFHSU5HX0NPTlRFWFQpKSB7XG4gICAgICAgIGZvciAoY29uc3QgZGlyIG9mIHN0YWdlZCkge1xuICAgICAgICAgIHJtU3luYyhkaXIsIHsgcmVjdXJzaXZlOiB0cnVlLCBmb3JjZTogdHJ1ZSB9KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICB0aGlzLmRlcGxveW1lbnQgPSAodGhpcy5zdGF0aWNEZXBsb3ltZW50ID8/XG4gICAgICB0aGlzLnNlcnZpY2VXb3JrZXJEZXBsb3ltZW50ID8/XG4gICAgICB0aGlzLnB1YmxpY0RlcGxveW1lbnQpITtcbiAgfVxuXG4gIC8qKlxuICAgKiBTdGFnZXMgZWFjaCB0cmVlIGFuZCBjcmVhdGVzIGl0cyBkZXBsb3ltZW50LCBhZGRpbmcgZXZlcnkgc3RhZ2luZ1xuICAgKiBkaXJlY3RvcnkgdG8gYHN0YWdlZGAgYXMgaXQncyBtYWRlLCBzbyB0aGUgY2FsbGVyIGNhbiByZW1vdmUgdGhlbSBldmVuIGlmXG4gICAqIGEgbGF0ZXIgc3RlcCB0aHJvd3MuXG4gICAqL1xuICBwcml2YXRlIGNyZWF0ZURlcGxveW1lbnRzKHN0YWdlZDogc3RyaW5nW10pOiB7XG4gICAgc3RhdGljRGVwbG95bWVudD86IEJ1Y2tldERlcGxveW1lbnQ7XG4gICAgc2VydmljZVdvcmtlckRlcGxveW1lbnQ/OiBCdWNrZXREZXBsb3ltZW50O1xuICAgIHB1YmxpY0RlcGxveW1lbnQ/OiBCdWNrZXREZXBsb3ltZW50O1xuICB9IHtcbiAgICBjb25zdCBzdGFnZTogdHlwZW9mIHRoaXMuc3RhZ2VEaXJlY3RvcnkgPSAoLi4uYXJncykgPT4ge1xuICAgICAgY29uc3QgZGlyID0gdGhpcy5zdGFnZURpcmVjdG9yeSguLi5hcmdzKTtcbiAgICAgIGlmIChkaXIpIHtcbiAgICAgICAgc3RhZ2VkLnB1c2goZGlyKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBkaXI7XG4gICAgfTtcbiAgICBjb25zdCBidWlsdERpciA9IGpvaW4odGhpcy5wcm9wcy5idWlsZERpcmVjdG9yeSwgXCIubmV4dFwiLCBcInN0YXRpY1wiKTtcbiAgICBjb25zdCBwdWJsaWNTb3VyY2VEaXIgPSBqb2luKHRoaXMucHJvcHMuYnVpbGREaXJlY3RvcnksIFwicHVibGljXCIpO1xuICAgIC8vIE9ubHkgYSBkaXJlY3RvcnkgaXMgdXBsb2FkZWQgYXMgc2VydmljZSB3b3JrZXJzLCBzbyBvbmx5IGEgZGlyZWN0b3J5IGlzXG4gICAgLy8gbGVmdCBvdXQgaGVyZS5cbiAgICBjb25zdCBoYXNTZXJ2aWNlV29ya2VycyA9IHRoaXMuZGlyZWN0b3J5RXhpc3RzKFxuICAgICAgam9pbihidWlsdERpciwgU0VSVklDRV9XT1JLRVJfRElSKSxcbiAgICApO1xuICAgIGNvbnN0IHN0YXRpY0RpciA9IHN0YWdlKFxuICAgICAgYnVpbHREaXIsXG4gICAgICBTVEFUSUNfUEFUSCxcbiAgICAgIChwYXRoKSA9PiAhaGFzU2VydmljZVdvcmtlcnMgfHwgIWlzV2l0aGluKHBhdGgsIFNFUlZJQ0VfV09SS0VSX0RJUiksXG4gICAgKTtcbiAgICBjb25zdCBzZXJ2aWNlV29ya2VyRGlyID0gc3RhZ2UoXG4gICAgICBqb2luKGJ1aWx0RGlyLCBTRVJWSUNFX1dPUktFUl9ESVIpLFxuICAgICAgam9pbihTVEFUSUNfUEFUSCwgU0VSVklDRV9XT1JLRVJfRElSKSxcbiAgICApO1xuICAgIC8vIEEgYHB1YmxpYy9fbmV4dC9zdGF0aWNgIGZpbGUgd2l0aCBhIGJ1aWx0IGZpbGUncyBuYW1lIHdvdWxkIGxhbmQgb24gdGhlXG4gICAgLy8gc2FtZSBrZXkuIGBuZXh0IHN0YXJ0YCBzZXJ2ZXMgdGhlIGJ1aWx0IG9uZSwgc28gdGhlIHB1YmxpYyBjb3B5IGlzIGxlZnRcbiAgICAvLyBvdXQ7IHVwbG9hZGluZyBib3RoIHdvdWxkIGxlYXZlIHdoaWNoZXZlciBkZXBsb3ltZW50IGZpbmlzaGVkIGxhc3QuXG4gICAgLy8gT3RoZXIgYHB1YmxpYy9fbmV4dC9zdGF0aWNgIGZpbGVzIGFyZSBzZXJ2ZWQgYXMgYG5leHQgc3RhcnRgIGRvZXMuXG4gICAgLy8gTWF0Y2hlZCBhZ2FpbnN0IGEgbGlzdGluZyByYXRoZXIgdGhhbiB3aXRoIGBleGlzdHNTeW5jYCwgd2hpY2ggb24gbWFjT1NcbiAgICAvLyBhbmQgV2luZG93cyB3b3VsZCBsZXQgYExlZ2FjeS5qc2Agc2hhZG93IGBsZWdhY3kuanNgOiBOZXh0LmpzIGFuZCBTMyBrZXlzXG4gICAgLy8gYXJlIGNhc2Utc2Vuc2l0aXZlLlxuICAgIGNvbnN0IGJ1aWx0RmlsZXMgPSBuZXcgU2V0KFxuICAgICAgdGhpcy5kaXJlY3RvcnlFeGlzdHMoYnVpbHREaXIpID8gbGlzdEZpbGVzKGJ1aWx0RGlyKSA6IFtdLFxuICAgICk7XG4gICAgY29uc3QgcHVibGljRGlyID0gc3RhZ2UoXG4gICAgICBwdWJsaWNTb3VyY2VEaXIsXG4gICAgICBcIlwiLFxuICAgICAgKHBhdGgpID0+XG4gICAgICAgICFpc1dpdGhpbihwYXRoLCBTVEFUSUNfUEFUSCkgfHxcbiAgICAgICAgIWJ1aWx0RmlsZXMuaGFzKHJlbGF0aXZlKFNUQVRJQ19QQVRILCBwYXRoKSksXG4gICAgKTtcbiAgICBpZiAoIXN0YXRpY0RpciAmJiAhc2VydmljZVdvcmtlckRpciAmJiAhcHVibGljRGlyKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIGBObyBzdGF0aWMgYXNzZXRzIGZvdW5kIHRvIGRlcGxveS4gRW5zdXJlIHlvdXIgTmV4dC5qcyBidWlsZCBvdXRwdXQgY29udGFpbnMgZmlsZXMgaW4gZWl0aGVyOlxuICAgICAgICAtIEEgJ3B1YmxpYycgZGlyZWN0b3J5IGF0OiAke3B1YmxpY1NvdXJjZURpcn1cbiAgICAgICAgLSBBICcubmV4dC9zdGF0aWMnIGRpcmVjdG9yeSBhdDogJHtidWlsdERpcn1gLFxuICAgICAgKTtcbiAgICB9XG4gICAgLy8gYF9uZXh0L3N0YXRpYy9gIGZpbGVzIGFyZSBjb250ZW50LWhhc2hlZCwgc28gdGhleSBnZXQgdGhlIHNhbWUgaGVhZGVyXG4gICAgLy8gTmV4dC5qcyBzZW5kcyBmb3IgdGhlbS4gTm90aGluZyBlbHNlIHdvdWxkOiBDbG91ZEZyb250IGFuZCBBUEkgR2F0ZXdheVxuICAgIC8vIHNlcnZlIHRoZW0gc3RyYWlnaHQgZnJvbSBTMywgd2hlcmUgdGhlIG9iamVjdCdzIG1ldGFkYXRhIGlzIHRoZSBvbmx5XG4gICAgLy8gYENhY2hlLUNvbnRyb2xgIHRoZXJlIGlzLiBBIGBCdWNrZXREZXBsb3ltZW50YCdzIGBjYWNoZUNvbnRyb2xgIGFwcGxpZXMgdG9cbiAgICAvLyBldmVyeSBvYmplY3QgaXQgdXBsb2FkcywgaGVuY2Ugb25lIGRlcGxveW1lbnQgcGVyIGhlYWRlci5cbiAgICByZXR1cm4ge1xuICAgICAgc3RhdGljRGVwbG95bWVudDogc3RhdGljRGlyXG4gICAgICAgID8gdGhpcy5jcmVhdGVEZXBsb3ltZW50KFwiRGVwbG95bWVudFwiLCBzdGF0aWNEaXIsIFtcbiAgICAgICAgICAgIENhY2hlQ29udHJvbC5zZXRQdWJsaWMoKSxcbiAgICAgICAgICAgIENhY2hlQ29udHJvbC5tYXhBZ2UoRHVyYXRpb24uZGF5cygzNjUpKSxcbiAgICAgICAgICAgIENhY2hlQ29udHJvbC5pbW11dGFibGUoKSxcbiAgICAgICAgICBdKVxuICAgICAgICA6IHVuZGVmaW5lZCxcbiAgICAgIHNlcnZpY2VXb3JrZXJEZXBsb3ltZW50OiBzZXJ2aWNlV29ya2VyRGlyXG4gICAgICAgID8gdGhpcy5jcmVhdGVEZXBsb3ltZW50KFwiU2VydmljZVdvcmtlckRlcGxveW1lbnRcIiwgc2VydmljZVdvcmtlckRpciwgW1xuICAgICAgICAgICAgQ2FjaGVDb250cm9sLnNldFB1YmxpYygpLFxuICAgICAgICAgICAgQ2FjaGVDb250cm9sLm1heEFnZShEdXJhdGlvbi5zZWNvbmRzKDApKSxcbiAgICAgICAgICAgIENhY2hlQ29udHJvbC5tdXN0UmV2YWxpZGF0ZSgpLFxuICAgICAgICAgIF0pXG4gICAgICAgIDogdW5kZWZpbmVkLFxuICAgICAgcHVibGljRGVwbG95bWVudDogcHVibGljRGlyXG4gICAgICAgID8gdGhpcy5jcmVhdGVEZXBsb3ltZW50KFwiUHVibGljRGVwbG95bWVudFwiLCBwdWJsaWNEaXIpXG4gICAgICAgIDogdW5kZWZpbmVkLFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogUmVqZWN0cyB0aGUgYGJ1Y2tldERlcGxveW1lbnRQcm9wc2AgdGhhdCBjYW4ndCB3b3JrIGFjcm9zcyBzZXZlcmFsXG4gICAqIGRlcGxveW1lbnRzIHNoYXJpbmcgb25lIHByZWZpeC4gRWFjaCBpcyBzcHJlYWQgaW50byBldmVyeSBvbmUgb2YgdGhlbTpcbiAgICpcbiAgICogLSBgcHJ1bmU6IHRydWVgIG1ha2VzIGVhY2ggZGVwbG95bWVudCdzIGBzMyBzeW5jIC0tZGVsZXRlYCByZW1vdmUgdGhlIGZpbGVzXG4gICAqICAgdGhlIG90aGVycyB1cGxvYWRlZC5cbiAgICogLSBgcmV0YWluT25EZWxldGU6IGZhbHNlYCBtYWtlcyBhIGRlcGxveW1lbnQgYHMzIHJtIC0tcmVjdXJzaXZlYCBpdHMgb2xkXG4gICAqICAgcHJlZml4IHdoZW4gdGhlIHByZWZpeCBjaGFuZ2VzLCB3aXRob3V0IGNoZWNraW5nIHdoZXRoZXIgdGhlIGJ1Y2tldCBpc1xuICAgKiAgIENESydzIChvbmx5IERlbGV0ZSBjaGVja3MpLCBzbyBpdCBjYW4gZGVsZXRlIGZpbGVzIGFub3RoZXIgZGVwbG95bWVudCBoYXNcbiAgICogICBqdXN0IHVwbG9hZGVkIHRoZXJlLiBPbiBEZWxldGUsIENESyBza2lwcyB0aGF0IGBybWAgb25seSBmb3IgYSBidWNrZXQgaXRcbiAgICogICB0YWdnZWQsIGFuZCBpdCBjYW4ndCB0YWcgYW4gaW1wb3J0ZWQgb25lLCBzbyBhIGJ1aWxkIHRoYXQgc3RvcHMgaGF2aW5nXG4gICAqICAgZmlsZXMgZm9yIG9uZSBkZXBsb3ltZW50IHdvdWxkIGxvc2UgdGhlIG90aGVycycgZmlsZXMgdG9vLlxuICAgKlxuICAgKiBgc291cmNlc2AgYW5kIGBkZXN0aW5hdGlvbkJ1Y2tldGAgYXJlbid0IHJlamVjdGVkLCBiZWNhdXNlIHRoZSB0eXBlXG4gICAqIHJlcXVpcmVzIHRoZW07IGBuZXdEZXBsb3ltZW50YCBzZXRzIHRoZW0gYWZ0ZXIgdGhlIHNwcmVhZCBpbnN0ZWFkLlxuICAgKlxuICAgKiBDb21wYXJlZCBhZ2FpbnN0IHRoZSBleGFjdCB2YWx1ZSwgYXMgd2l0aCBgZGVzdGluYXRpb25LZXlQcmVmaXhgLCBzbyBhblxuICAgKiBleHBsaWNpdCBgdW5kZWZpbmVkYCBmcm9tIGEgSlNJSSBiaW5kaW5nIGlzIG5vdCBtaXN0YWtlbiBmb3IgYW4gb3ZlcnJpZGUuXG4gICAqL1xuICBwcml2YXRlIHZhbGlkYXRlRGVwbG95bWVudE92ZXJyaWRlcygpIHtcbiAgICBjb25zdCBvdmVycmlkZXMgPSB0aGlzLnByb3BzLm92ZXJyaWRlcz8uYnVja2V0RGVwbG95bWVudFByb3BzO1xuICAgIGNvbnN0IHJlamVjdGVkID0gW1xuICAgICAgb3ZlcnJpZGVzPy5wcnVuZSA9PT0gdHJ1ZSAmJlxuICAgICAgICBcImBwcnVuZTogdHJ1ZWAgKG9sZCBhc3NldHMgYXJlIHBydW5lZCBhZnRlciBkZXBsb3kgYnkgTmV4dGpzUG9zdERlcGxveSwgb25jZSB0aGV5IGFyZSBwYXN0IGl0cyBUVEwpXCIsXG4gICAgICBvdmVycmlkZXM/LnJldGFpbk9uRGVsZXRlID09PSBmYWxzZSAmJiBcImByZXRhaW5PbkRlbGV0ZTogZmFsc2VgXCIsXG4gICAgXS5maWx0ZXIoKHJlYXNvbik6IHJlYXNvbiBpcyBzdHJpbmcgPT4gISFyZWFzb24pO1xuICAgIGlmIChyZWplY3RlZC5sZW5ndGggPiAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIGAke0xPR19QUkVGSVh9IG92ZXJyaWRlcy5idWNrZXREZXBsb3ltZW50UHJvcHMgY2FuJ3Qgc2V0ICR7cmVqZWN0ZWQuam9pbihcIiwgb3IgXCIpfTogYCArXG4gICAgICAgICAgXCJ0aGUgc3RhdGljIGFzc2V0cyBhcmUgdXBsb2FkZWQgYnkgb25lIGRlcGxveW1lbnQgcGVyIENhY2hlLUNvbnRyb2wsIFwiICtcbiAgICAgICAgICBcImFuZCBlYWNoIG9mIHRoZXNlIHdvdWxkIGJyZWFrIHRoZSBvdGhlcnMuXCIsXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZXNvbHZlcyB0aGUgc2luZ2xlIHByZWZpeCBib3RoIHRoZSB1cGxvYWQgYW5kIHRoZSBVUkxzIHVzZS4gQVxuICAgKiBgYnVja2V0RGVwbG95bWVudFByb3BzLmRlc3RpbmF0aW9uS2V5UHJlZml4YCBvdmVycmlkZSB3aW5zIG92ZXIgYGJhc2VQYXRoYCxcbiAgICogYnV0IGl0J3Mgbm9ybWFsaXplZCBoZXJlIGFuZCBgY3JlYXRlRGVwbG95bWVudGAgc2V0cyB0aGUgbm9ybWFsaXplZCB2YWx1ZVxuICAgKiBhZnRlciB0aGUgb3ZlcnJpZGUgc3ByZWFkLCBzbyBga2V5UHJlZml4YCBjYW4ndCBkcmlmdCBmcm9tIHdoZXJlIHRoZSBhc3NldHNcbiAgICogbGFuZC5cbiAgICpcbiAgICogQ29tcGFyZWQgYWdhaW5zdCBgdW5kZWZpbmVkYCByYXRoZXIgdGhhbiB0ZXN0ZWQgd2l0aCBgaW5gLCBiZWNhdXNlIGEgSlNJSVxuICAgKiBsYW5ndWFnZSBiaW5kaW5nIChvciBhIHByb2dyYW1tYXRpY2FsbHkgYnVpbHQgcHJvcHMgb2JqZWN0KSBjYW4gbWF0ZXJpYWxpemVcbiAgICogYW4gdW5zZXQgb3B0aW9uYWwgZmllbGQgYXMgYW4gZXhwbGljaXQgYHVuZGVmaW5lZGAuIFRyZWF0aW5nIHRoYXQgYXMgYW5cbiAgICogaW50ZW50aW9uYWwgXCJtb3ZlIHRoZSBhc3NldHMgdG8gdGhlIGJ1Y2tldCByb290XCIgb3ZlcnJpZGUgd291bGQgc2lsZW50bHlcbiAgICogZHJvcCBgYmFzZVBhdGhgIGZyb20gdGhlIHByZWZpeC5cbiAgICovXG4gIHByaXZhdGUgcmVzb2x2ZUtleVByZWZpeCgpOiBzdHJpbmcge1xuICAgIGNvbnN0IGRlcGxveW1lbnRPdmVycmlkZXMgPSB0aGlzLnByb3BzLm92ZXJyaWRlcz8uYnVja2V0RGVwbG95bWVudFByb3BzO1xuICAgIGNvbnN0IHByZWZpeCA9XG4gICAgICBkZXBsb3ltZW50T3ZlcnJpZGVzPy5kZXN0aW5hdGlvbktleVByZWZpeCAhPT0gdW5kZWZpbmVkXG4gICAgICAgID8gZGVwbG95bWVudE92ZXJyaWRlcy5kZXN0aW5hdGlvbktleVByZWZpeFxuICAgICAgICA6IHRoaXMucHJvcHMuYmFzZVBhdGg7XG4gICAgcmV0dXJuIG5vcm1hbGl6ZUJhc2VQYXRoKHByZWZpeCk7XG4gIH1cblxuICBwcml2YXRlIGNyZWF0ZUJ1Y2tldCgpIHtcbiAgICByZXR1cm4gbmV3IEJ1Y2tldCh0aGlzLCBcIkJ1Y2tldFwiLCB7XG4gICAgICByZW1vdmFsUG9saWN5OiBSZW1vdmFsUG9saWN5LkRFU1RST1ksXG4gICAgICBhdXRvRGVsZXRlT2JqZWN0czogdHJ1ZSxcbiAgICAgIGVuZm9yY2VTU0w6IHRydWUsXG4gICAgICBibG9ja1B1YmxpY0FjY2VzczogQmxvY2tQdWJsaWNBY2Nlc3MuQkxPQ0tfQUxMLFxuICAgICAgZW5jcnlwdGlvbjogQnVja2V0RW5jcnlwdGlvbi5TM19NQU5BR0VELFxuICAgICAgbWluaW11bVRMU1ZlcnNpb246IDEuMixcbiAgICAgIC4uLnRoaXMucHJvcHMub3ZlcnJpZGVzPy5idWNrZXRQcm9wcyxcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlRGVwbG95bWVudChcbiAgICBpZDogc3RyaW5nLFxuICAgIHN0YWdpbmdEaXI6IHN0cmluZyxcbiAgICBjYWNoZUNvbnRyb2w/OiBDYWNoZUNvbnRyb2xbXSxcbiAgKSB7XG4gICAgcmV0dXJuIG5ldyBCdWNrZXREZXBsb3ltZW50KHRoaXMsIGlkLCB7XG4gICAgICAvLyBBZGQgQlVJTERfSUQgYXMgbWV0YWRhdGEgdG8gYWxsIG9iamVjdHMgZm9yIHZlcnNpb24gdHJhY2tpbmdcbiAgICAgIG1ldGFkYXRhOiB7XG4gICAgICAgIEJVSUxEX0lEOiB0aGlzLnByb3BzLmJ1aWxkSWQsXG4gICAgICB9LFxuICAgICAgLy8gUzNEZXBsb3ltZW50IGF1dG9tYXRpY2FsbHkgZGV0ZWN0cyBjb250ZW50IHR5cGVzIGJhc2VkIG9uIGZpbGUgZXh0ZW5zaW9uc1xuICAgICAgLi4udGhpcy5wcm9wcy5vdmVycmlkZXM/LmJ1Y2tldERlcGxveW1lbnRQcm9wcyxcbiAgICAgIC8vIFNldCBhZnRlciB0aGUgc3ByZWFkLiBUaGUgdHlwZSBtYWtlcyBjYWxsZXJzIHBhc3MgYHNvdXJjZXNgIGFuZFxuICAgICAgLy8gYGRlc3RpbmF0aW9uQnVja2V0YCwgYW5kIGVpdGhlciB3b3VsZCB1cGxvYWQgc29tZXRoaW5nIG90aGVyIHRoYW4gdGhlXG4gICAgICAvLyBidWlsZCdzIGFzc2V0cywgb3Igc29tZXdoZXJlIENsb3VkRnJvbnQgYW5kIEFQSSBHYXRld2F5IGRvbid0IHJlYWQgZnJvbS5cbiAgICAgIC8vIGB2YWxpZGF0ZURlcGxveW1lbnRPdmVycmlkZXNgIGxldHMgYHBydW5lYCB0aHJvdWdoIG9ubHkgYXMgYGZhbHNlYCBvciBhblxuICAgICAgLy8gZXhwbGljaXQgYHVuZGVmaW5lZGAgZnJvbSBhIEpTSUkgYmluZGluZywgd2hpY2ggd291bGQgdHVybiBvbiBDREsnc1xuICAgICAgLy8gZGVmYXVsdCBgcHJ1bmU6IHRydWVgLlxuICAgICAgc291cmNlczogW1NvdXJjZS5hc3NldChzdGFnaW5nRGlyKV0sXG4gICAgICBkZXN0aW5hdGlvbkJ1Y2tldDogdGhpcy5idWNrZXQsXG4gICAgICBwcnVuZTogZmFsc2UsIC8vIERvbid0IGRlbGV0ZSBleGlzdGluZyBhc3NldHMgdG8gcHJldmVudCA0MDRzIGR1cmluZyBkZXBsb3ltZW50LCBwcnVuaW5nIHdpbGwgYmUgaGFuZGxlZCBieSBwb3N0LWRlcGxveVxuICAgICAgLi4uKGNhY2hlQ29udHJvbCAmJiB7IGNhY2hlQ29udHJvbCB9KSxcbiAgICAgIC8vIFNldCBhZnRlciB0aGUgc3ByZWFkOiBgcmVzb2x2ZUtleVByZWZpeGAgYWxyZWFkeSBmb2xkZWQgaW4gYW55XG4gICAgICAvLyBgZGVzdGluYXRpb25LZXlQcmVmaXhgIG92ZXJyaWRlLCBzbyB0aGlzIGlzIHRoZSBub3JtYWxpemVkIGZvcm0gb2YgaXQuXG4gICAgICAvLyBMZXR0aW5nIHRoZSByYXcgb3ZlcnJpZGUgdGhyb3VnaCBoZXJlIHdvdWxkIHVwbG9hZCB0aGUgYXNzZXRzIHNvbWV3aGVyZVxuICAgICAgLy8gb3RoZXIgdGhhbiB0aGUgYGtleVByZWZpeGAgdXNlZCB0byBidWlsZCB0aGVpciBVUkxzLlxuICAgICAgZGVzdGluYXRpb25LZXlQcmVmaXg6IHRoaXMua2V5UHJlZml4IHx8IHVuZGVmaW5lZCxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb3BpZXMgYHNvdXJjZURpcmAgdG8gYDxzdGFnaW5nPi88c3ViUGF0aD5gIGluIGEgbmV3IHN0YWdpbmcgZGlyZWN0b3J5LCBvclxuICAgKiByZXR1cm5zIGB1bmRlZmluZWRgIGlmIHRoZXJlIGlzIG5vIGBzb3VyY2VEaXJgIG9yIG5vIGZpbGUgaW4gaXQgcGFzc2VzXG4gICAqIGBpbmNsdWRlYC4gU3RhZ2VkIHVuZGVyIGBzdWJQYXRoYCByYXRoZXIgdGhhbiB1cGxvYWRlZCB3aXRoIGEgbG9uZ2VyXG4gICAqIGBkZXN0aW5hdGlvbktleVByZWZpeGAsIHNvIGV2ZXJ5IGRlcGxveW1lbnQgc2hhcmVzIHRoZSBvbmUgcHJlZml4XG4gICAqIGBrZXlQcmVmaXhgIHJlc29sdmVzLiBgaW5jbHVkZWAgZ2V0cyBlYWNoIGVudHJ5J3MgcGF0aCByZWxhdGl2ZSB0b1xuICAgKiBgc291cmNlRGlyYC5cbiAgICovXG4gIHByaXZhdGUgc3RhZ2VEaXJlY3RvcnkoXG4gICAgc291cmNlRGlyOiBzdHJpbmcsXG4gICAgc3ViUGF0aDogc3RyaW5nLFxuICAgIGluY2x1ZGU6IChwYXRoOiBzdHJpbmcpID0+IGJvb2xlYW4gPSAoKSA9PiB0cnVlLFxuICApOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICAgIGlmICghdGhpcy5kaXJlY3RvcnlFeGlzdHMoc291cmNlRGlyKSkge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gICAgLy8gRnJvbSB0aGUgcmVhbCBwYXRoLCBhbmQgZGVyZWZlcmVuY2luZyBsaW5rcyBpbnNpZGUgaXQ6IGBjcFN5bmNgIHdvdWxkXG4gICAgLy8gY29weSBhIGxpbmsgYXMgYSBsaW5rLCB3aGljaCBmYWlscyBmb3IgYSBzeW1saW5rZWQgYHNvdXJjZURpcmAgKG9udG8gdGhlXG4gICAgLy8gZGlyZWN0b3J5IG1hZGUgZm9yIGl0IGhlcmUpIGFuZCBoaWRlcyBhIGxpbmtlZCBkaXJlY3RvcnkncyBmaWxlcyBmcm9tXG4gICAgLy8gYGluY2x1ZGVgLCB0aG91Z2ggQ0RLIHVwbG9hZHMgdGhlbS5cbiAgICBjb25zdCByZWFsU291cmNlRGlyID0gcmVhbHBhdGhTeW5jKHNvdXJjZURpcik7XG4gICAgY29uc3Qgc3RhZ2luZ0RpciA9IG1rZHRlbXBTeW5jKGpvaW4odG1wZGlyKCksIFwibmV4dGpzLWFzc2V0cy1cIikpO1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBkZXN0RGlyID0gam9pbihzdGFnaW5nRGlyLCBzdWJQYXRoKTtcbiAgICAgIG1rZGlyU3luYyhkZXN0RGlyLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcbiAgICAgIGNwU3luYyhyZWFsU291cmNlRGlyLCBkZXN0RGlyLCB7XG4gICAgICAgIHJlY3Vyc2l2ZTogdHJ1ZSxcbiAgICAgICAgZGVyZWZlcmVuY2U6IHRydWUsXG4gICAgICAgIGZpbHRlcjogKHBhdGgpID0+IGluY2x1ZGUocmVsYXRpdmUocmVhbFNvdXJjZURpciwgcGF0aCkpLFxuICAgICAgfSk7XG4gICAgICBpZiAobGlzdEZpbGVzKGRlc3REaXIpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICBybVN5bmMoc3RhZ2luZ0RpciwgeyByZWN1cnNpdmU6IHRydWUsIGZvcmNlOiB0cnVlIH0pO1xuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHN0YWdpbmdEaXI7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIC8vIFRocm93biByYXRoZXIgdGhhbiBza2lwcGVkLCB3aGljaCB3b3VsZCBkZXBsb3kgd2l0aG91dCB0aGVzZSBhc3NldHMuXG4gICAgICAvLyBUaGUgY2xlYW51cCdzIG93biBmYWlsdXJlIG11c3Qgbm90IHJlcGxhY2UgdGhhdCBlcnJvci5cbiAgICAgIHRyeSB7XG4gICAgICAgIHJtU3luYyhzdGFnaW5nRGlyLCB7IHJlY3Vyc2l2ZTogdHJ1ZSwgZm9yY2U6IHRydWUgfSk7XG4gICAgICB9IGNhdGNoIHtcbiAgICAgICAgLy8gSWdub3JlIGNsZWFudXAgZXJyb3JzXG4gICAgICB9XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7TE9HX1BSRUZJWH0gQ291bGQgbm90IHN0YWdlICR7c291cmNlRGlyfSBmb3IgdXBsb2FkYCwge1xuICAgICAgICBjYXVzZTogZXJyb3IsXG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2sgaWYgYSBkaXJlY3RvcnkgZXhpc3RzXG4gICAqL1xuICBwcml2YXRlIGRpcmVjdG9yeUV4aXN0cyhkaXJQYXRoOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIGV4aXN0c1N5bmMoZGlyUGF0aCkgJiYgc3RhdFN5bmMoZGlyUGF0aCkuaXNEaXJlY3RvcnkoKTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cbn1cbiJdfQ==
|