build-strap 4.0.0-dev.46 → 4.0.0-dev.54

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 (107) hide show
  1. package/README.md +3 -34
  2. package/package.json +23 -19
  3. package/src/ant.d.ts +19 -0
  4. package/src/ant.js +12 -36
  5. package/src/cert.d.ts +12 -0
  6. package/src/cert.js +87 -148
  7. package/src/clean.d.ts +4 -0
  8. package/src/clean.js +5 -13
  9. package/src/copy.d.ts +7 -0
  10. package/src/copy.js +48 -74
  11. package/src/cp.d.ts +17 -0
  12. package/src/cp.js +81 -165
  13. package/src/docker.container.d.ts +73 -0
  14. package/src/docker.container.js +208 -350
  15. package/src/docker.d.ts +68 -0
  16. package/src/docker.js +163 -339
  17. package/src/docker.network.d.ts +42 -0
  18. package/src/docker.network.js +67 -141
  19. package/src/docker.volume.d.ts +26 -0
  20. package/src/docker.volume.js +50 -124
  21. package/src/dockerCleanup.d.ts +38 -0
  22. package/src/dockerCleanup.js +62 -136
  23. package/src/dockerCompose.d.ts +154 -0
  24. package/src/dockerCompose.js +390 -716
  25. package/src/fs.d.ts +5 -0
  26. package/src/fs.js +33 -91
  27. package/src/git.d.ts +9 -0
  28. package/src/git.js +19 -29
  29. package/src/index.d.ts +20 -0
  30. package/src/index.js +20 -26
  31. package/src/maps.d.ts +33 -0
  32. package/src/maps.js +12 -82
  33. package/src/npm.d.ts +48 -0
  34. package/src/npm.js +128 -131
  35. package/src/pkg.d.ts +38 -0
  36. package/src/pkg.js +27 -74
  37. package/src/publish.d.ts +27 -0
  38. package/src/publish.js +51 -138
  39. package/src/run.d.ts +13 -0
  40. package/src/run.js +39 -84
  41. package/src/tgz.d.ts +13 -0
  42. package/src/tgz.js +54 -88
  43. package/src/version.d.ts +34 -0
  44. package/src/version.js +85 -126
  45. package/src/yarn.d.ts +44 -0
  46. package/src/yarn.js +147 -115
  47. package/ant.js +0 -43
  48. package/ant.js.flow +0 -42
  49. package/artifactory.js +0 -617
  50. package/artifactory.js.flow +0 -616
  51. package/cert.conf +0 -20
  52. package/cert.js +0 -153
  53. package/cert.js.flow +0 -152
  54. package/clean.js +0 -20
  55. package/clean.js.flow +0 -19
  56. package/copy.js +0 -80
  57. package/copy.js.flow +0 -79
  58. package/cp.js +0 -173
  59. package/cp.js.flow +0 -172
  60. package/docker.container.js +0 -390
  61. package/docker.container.js.flow +0 -389
  62. package/docker.js +0 -365
  63. package/docker.js.flow +0 -364
  64. package/docker.network.js +0 -160
  65. package/docker.network.js.flow +0 -159
  66. package/docker.volume.js +0 -136
  67. package/docker.volume.js.flow +0 -136
  68. package/dockerCleanup.js +0 -152
  69. package/dockerCleanup.js.flow +0 -151
  70. package/dockerCompose.js +0 -766
  71. package/dockerCompose.js.flow +0 -765
  72. package/flow.js +0 -21
  73. package/flow.js.flow +0 -20
  74. package/fs.js +0 -95
  75. package/fs.js.flow +0 -96
  76. package/git.js +0 -35
  77. package/git.js.flow +0 -34
  78. package/hg.js +0 -35
  79. package/hg.js.flow +0 -34
  80. package/index.js +0 -27
  81. package/index.js.flow +0 -26
  82. package/inline-resources.js +0 -158
  83. package/inline-resources.js.flow +0 -157
  84. package/maps.js +0 -112
  85. package/maps.js.flow +0 -111
  86. package/npm.js +0 -145
  87. package/npm.js.flow +0 -144
  88. package/pkg.js +0 -81
  89. package/pkg.js.flow +0 -80
  90. package/publish.js +0 -145
  91. package/publish.js.flow +0 -144
  92. package/run.js +0 -90
  93. package/run.js.flow +0 -89
  94. package/src/artifactory.js +0 -616
  95. package/src/cert.conf +0 -20
  96. package/src/flow.js +0 -20
  97. package/src/hg.js +0 -34
  98. package/src/inline-resources.js +0 -157
  99. package/src/test.js +0 -55
  100. package/test.js +0 -56
  101. package/test.js.flow +0 -55
  102. package/tgz.js +0 -102
  103. package/tgz.js.flow +0 -101
  104. package/version.js +0 -143
  105. package/version.js.flow +0 -142
  106. package/yarn.js +0 -124
  107. package/yarn.js.flow +0 -123
package/docker.js DELETED
@@ -1,365 +0,0 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", { value: true });exports.copyFilesFromDockerImage = copyFilesFromDockerImage;exports.dockerBuild = dockerBuild;exports.dockerImages = dockerImages;exports.dockerLogin = dockerLogin;exports.dockerPull = dockerPull;exports.dockerPullAndRunContainer = dockerPullAndRunContainer;exports.dockerPush = dockerPush;exports.dockerRmi = dockerRmi;exports.dockerTag = dockerTag;exports.dockerTagVersion = dockerTagVersion;exports.getDockerConfig = getDockerConfig;exports.getDockerDigest = getDockerDigest;exports.getDockerId = getDockerId;exports.getDockerRepo = getDockerRepo;exports.getDockerTags = getDockerTags;exports.getUntaggedDockerIds = getUntaggedDockerIds;exports.parseDockerDate = void 0;
2
- var _path = _interopRequireDefault(require("path"));
3
- var _bytes = _interopRequireDefault(require("bytes"));
4
- var _isReachable = _interopRequireDefault(require("is-reachable"));
5
- var _moment = _interopRequireDefault(require("moment"));
6
- var _run = require("./run");
7
- var _pkg = require("./pkg");
8
- var _cp = require("./cp");
9
- var _version = require("./version");
10
- var _docker = require("./docker.container");
11
-
12
-
13
-
14
- var _docker2 = require("./docker.network");function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };}
15
-
16
-
17
-
18
-
19
-
20
-
21
-
22
- function getDockerConfig() {
23
- return (0, _pkg.getCfg)().docker || {};
24
- }
25
-
26
- const parseDockerDate = (date) =>
27
- (0, _moment.default)(date, 'YYYY-MM-DD HH:mm:ss ZZ').toDate();exports.parseDockerDate = parseDockerDate;
28
-
29
- async function dockerBuild(
30
- tags = ['latest'],
31
- buildArgs = [],
32
- target = null,
33
- extraArgs = [],
34
- repo = getDockerRepo(),
35
- dockerFile = './Dockerfile',
36
- workDir = '.')
37
- {
38
- const args = [
39
- 'build',
40
- ...['-f', _path.default.resolve(dockerFile)],
41
- ...(target ? ['--target', target] : []),
42
- ...tags.reduce((ar, t) => [...ar, '-t', `${repo}:${t}`], []),
43
- ...buildArgs.reduce((ar, a) => [...ar, '--build-arg', a], []),
44
- ...(extraArgs || []),
45
- _path.default.resolve(workDir)];
46
-
47
-
48
- return (0, _cp.spawn)('docker', args, { stdio: 'inherit' });
49
- }
50
-
51
- async function dockerTag(
52
- imageId,
53
- tags = ['latest'],
54
- repo = getDockerRepo())
55
- {
56
- await Promise.all(
57
- tags.map(async (t) => {
58
- await (0, _cp.spawn)('docker', ['tag', imageId, `${repo}:${t}`]);
59
- (0, _run.buildLog)(`Tagged image ${imageId} as ${repo}:${t}`);
60
- }));
61
-
62
- }
63
-
64
- /**
65
- * Apply the standard convention for tagging the docker image for the project,
66
- * based on the source control branch being built.
67
- * For releases, applies `latest`, `M.m.p`, `M.m`, `M`
68
- * For release candidates, applies `latest-rc`
69
- * For feature branches, applies `latest-feature`
70
- * For development branch, applies `latest-dev`
71
- * All other branches, no tag is applies
72
- * @param {string} imageId id of the docker image to which to apply the tags
73
- * @param {string} repo optional override of the docker repo url to use (derived from package.json by default)
74
- */
75
- async function dockerTagVersion(
76
- imageId,
77
- repo = getDockerRepo())
78
- {
79
- const { isRelease, major, minor, patch, branch } = await (0, _version.getVersion)();
80
- // determine what tags to apply
81
- if (isRelease) {
82
- await dockerTag(
83
- imageId,
84
- ['latest', `${major}`, `${major}.${minor}`, `${major}.${minor}.${patch}`],
85
- repo);
86
-
87
- } else if (branch === (await (0, _version.getDevBranch)())) {
88
- await dockerTag(imageId, ['latest-dev'], repo);
89
- } else if (branch.match(/^(release|patch)-/)) {
90
- await dockerTag(imageId, ['latest-rc'], repo);
91
- } else if (branch.match(/^feature-/)) {
92
- await dockerTag(imageId, ['latest-feature'], repo);
93
- }
94
- }
95
-
96
-
97
-
98
-
99
-
100
-
101
-
102
-
103
-
104
-
105
-
106
-
107
- async function dockerImages(
108
- repo = getDockerRepo(),
109
- filter = null)
110
- {
111
- return (
112
- await (0, _cp.spawn)(
113
- 'docker',
114
- ['images', '--format', `{{json .}}`, ...(repo ? [repo] : [])],
115
- { captureOutput: true })).
116
-
117
-
118
- split('\n').
119
- filter((line) => !!line.trim()).
120
- map((l) => {
121
- const {
122
- Repository: repository,
123
- Tag: tag,
124
- ID: id,
125
- Digest: digest,
126
- CreatedAt,
127
- Size } =
128
- JSON.parse(l.trim());
129
- return {
130
- repository,
131
- tag,
132
- id,
133
- digest,
134
- created: parseDockerDate(CreatedAt),
135
- size: _bytes.default.parse(Size) };
136
-
137
- }).
138
- filter(
139
- (m) =>
140
- (m && m.id) != null && (
141
- typeof filter === 'function' ? filter(m) : true));
142
-
143
- }
144
-
145
- async function getDockerId(
146
- tag = 'latest',
147
- repo)
148
- {
149
- return (await dockerImages(repo, (m) => m.tag === tag)).map((m) => m.id)[0];
150
- }
151
-
152
- async function getUntaggedDockerIds(
153
- repo,
154
- filter = null)
155
- {
156
- return (
157
- await dockerImages(
158
- repo,
159
- (m) =>
160
- m.tag === '<none>' && (typeof filter === 'function' ? filter(m) : true))).
161
-
162
- map((m) => m.id);
163
- }
164
-
165
- async function getDockerTags(
166
- id,
167
- repo,
168
- fullName = false,
169
- filter = null)
170
- {
171
- return (
172
- await dockerImages(
173
- repo,
174
- (m) =>
175
- (!id || m.id === id) && (
176
- typeof filter === 'function' ? filter(m) : true))).
177
-
178
- map((m) => fullName ? `${m.repository}:${m.tag}` : m.tag);
179
- }
180
-
181
- async function getDockerDigest(
182
- imageId,
183
- repo)
184
- {
185
- return (await dockerImages(repo, (m) => m.id === imageId)).map(
186
- (m) => m.digest)[
187
- 0];
188
- }
189
-
190
- async function dockerLogin(
191
- user,
192
- password,
193
- registry)
194
- {
195
- const reg = registry || getDockerConfig().registry;
196
- await (0, _cp.spawn)(
197
- 'docker',
198
- [
199
- 'login',
200
- '-u',
201
- user || process.env.ARTIFACTORY_USER || '',
202
- '-p',
203
- password || process.env.ARTIFACTORY_PASSWORD || '',
204
- ...(reg ? [reg] : [])],
205
-
206
- { stdio: 'inherit' });
207
-
208
- }
209
-
210
- async function dockerPush(
211
- tags = ['latest'],
212
- repo = getDockerRepo())
213
- {
214
- // do this sequentially, so you don't push the same image simultaneously
215
- await tags.reduce(async (prev, tag) => {
216
- await prev;
217
- await (0, _cp.spawn)('docker', ['push', `${repo}:${tag}`], { stdio: 'inherit' });
218
- }, Promise.resolve());
219
- }
220
-
221
-
222
-
223
-
224
-
225
-
226
-
227
- async function dockerPull({
228
- image,
229
- offline = process.argv.includes('--offline'),
230
- testUrl })
231
- {
232
- if (offline || !(await (0, _isReachable.default)(testUrl || 'https://hub.docker.com'))) {
233
- if (offline === false) {
234
- throw new Error('Offline, cannot docker pull');
235
- }
236
- (0, _run.buildLog)('It looks like you are offline, skipping docker pull');
237
- } else {
238
- // throws on failure
239
- await (0, _cp.spawn)('docker', ['pull', image], { stdio: 'inherit' });
240
- }
241
- }
242
-
243
- async function dockerRmi(
244
- images = [],
245
- ignoreErrors = true)
246
- {
247
- // must do these sequentially, or they will interfere with each other
248
- await images.reduce(async (prev, image) => {
249
- await prev;
250
- await (0, _cp.spawn)('docker', ['rmi', image], { stdio: 'inherit' }).catch((err) => {
251
- if (ignoreErrors) {
252
- (0, _run.buildLog)(
253
- `Warning (ignored Error): Failed to rm image(s): ${err.message}`);
254
-
255
- } else {
256
- throw err;
257
- }
258
- });
259
- }, Promise.resolve());
260
- }
261
-
262
- function getDockerRepo() {
263
- const { registry, repository: dkrRepo, name: dkrName } = getDockerConfig();
264
- const repository = dkrRepo || (0, _pkg.getPkgScope)();
265
- const name = dkrName || (0, _pkg.getPkgName)(false);
266
- if (!repository || !name) {
267
- throw new Error(
268
- 'Docker configuration is missing or incomplete in package.json');
269
-
270
- }
271
- return `${registry ? `${registry}/` : ''}${repository}/${name}`;
272
- }
273
-
274
-
275
-
276
-
277
-
278
-
279
-
280
-
281
-
282
- async function dockerPullAndRunContainer(
283
- image,
284
- options = {})
285
- {
286
- const {
287
- runArgs = [],
288
- cmd = [],
289
- network,
290
- alias,
291
- offline = process.argv.includes('--offline'),
292
- testUrl } =
293
- options;
294
-
295
- try {
296
- await dockerPull({ image, offline, testUrl });
297
- } catch (err) {
298
- (0, _run.buildLog)(`docker pull failed (${err.message}), attempting to continue...`);
299
- }
300
- const { id } = await (0, _docker.dockerContainerRunDaemon)({ image, runArgs, cmd });
301
- if (network) {
302
- await (0, _docker2.dockerNetworkConnect)(network, id, alias);
303
- }
304
- return id;
305
- }
306
-
307
-
308
-
309
-
310
-
311
-
312
-
313
-
314
-
315
-
316
-
317
-
318
- async function copyFilesFromDockerImage({
319
- imageId,
320
- filePaths,
321
- ignoreErrors })
322
- {
323
- const container = await (0, _docker.dockerContainerRunDaemon)({
324
- image: imageId,
325
- runArgs: ['-it', '--rm', '--entrypoint=/bin/bash'],
326
- cmd: ['read', '-p', 'pause'] });
327
-
328
-
329
- (0, _run.buildLog)(`Copying Files from Docker Image - imageId (${imageId})`);
330
-
331
- const spawnOptions = {
332
- stdio: 'inherit',
333
- pipeOutput: true,
334
- captureOutput: false };
335
-
336
- const copyErrors = [];
337
-
338
- try {
339
- filePaths.forEach(async (fp) => {
340
- // Try to copy from the Debug Folder
341
- try {
342
- await (0, _cp.spawn)(
343
- 'docker',
344
- ['cp', `${container.id}:${fp.from}`, fp.to],
345
- spawnOptions);
346
-
347
- (0, _run.buildLog)(`Copied ${fp.from} => ${fp.to}`);
348
- } catch (error) {
349
- copyErrors.push(error);
350
- (0, _run.buildLog)(`Error copying file ${fp.from}`);
351
- }
352
- });
353
- } finally {
354
- try {
355
- await (0, _docker.dockerContainerKill)(container.id);
356
- } catch (error) {
357
- copyErrors.push(error);
358
- }
359
- }
360
-
361
- if (copyErrors.length > 0 && ignoreErrors !== true) {
362
- throw new Error('Some files failed to copy');
363
- }
364
- }
365
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9kb2NrZXIuanMiXSwibmFtZXMiOlsiZ2V0RG9ja2VyQ29uZmlnIiwiZG9ja2VyIiwicGFyc2VEb2NrZXJEYXRlIiwiZGF0ZSIsInRvRGF0ZSIsImRvY2tlckJ1aWxkIiwidGFncyIsImJ1aWxkQXJncyIsInRhcmdldCIsImV4dHJhQXJncyIsInJlcG8iLCJnZXREb2NrZXJSZXBvIiwiZG9ja2VyRmlsZSIsIndvcmtEaXIiLCJhcmdzIiwicGF0aCIsInJlc29sdmUiLCJyZWR1Y2UiLCJhciIsInQiLCJhIiwic3RkaW8iLCJkb2NrZXJUYWciLCJpbWFnZUlkIiwiUHJvbWlzZSIsImFsbCIsIm1hcCIsImRvY2tlclRhZ1ZlcnNpb24iLCJpc1JlbGVhc2UiLCJtYWpvciIsIm1pbm9yIiwicGF0Y2giLCJicmFuY2giLCJtYXRjaCIsImRvY2tlckltYWdlcyIsImZpbHRlciIsImNhcHR1cmVPdXRwdXQiLCJzcGxpdCIsImxpbmUiLCJ0cmltIiwibCIsIlJlcG9zaXRvcnkiLCJyZXBvc2l0b3J5IiwiVGFnIiwidGFnIiwiSUQiLCJpZCIsIkRpZ2VzdCIsImRpZ2VzdCIsIkNyZWF0ZWRBdCIsIlNpemUiLCJKU09OIiwicGFyc2UiLCJjcmVhdGVkIiwic2l6ZSIsImJ5dGVzIiwibSIsImdldERvY2tlcklkIiwiZ2V0VW50YWdnZWREb2NrZXJJZHMiLCJnZXREb2NrZXJUYWdzIiwiZnVsbE5hbWUiLCJnZXREb2NrZXJEaWdlc3QiLCJkb2NrZXJMb2dpbiIsInVzZXIiLCJwYXNzd29yZCIsInJlZ2lzdHJ5IiwicmVnIiwicHJvY2VzcyIsImVudiIsIkFSVElGQUNUT1JZX1VTRVIiLCJBUlRJRkFDVE9SWV9QQVNTV09SRCIsImRvY2tlclB1c2giLCJwcmV2IiwiZG9ja2VyUHVsbCIsImltYWdlIiwib2ZmbGluZSIsImFyZ3YiLCJpbmNsdWRlcyIsInRlc3RVcmwiLCJFcnJvciIsImRvY2tlclJtaSIsImltYWdlcyIsImlnbm9yZUVycm9ycyIsImNhdGNoIiwiZXJyIiwibWVzc2FnZSIsImRrclJlcG8iLCJuYW1lIiwiZGtyTmFtZSIsImRvY2tlclB1bGxBbmRSdW5Db250YWluZXIiLCJvcHRpb25zIiwicnVuQXJncyIsImNtZCIsIm5ldHdvcmsiLCJhbGlhcyIsImNvcHlGaWxlc0Zyb21Eb2NrZXJJbWFnZSIsImZpbGVQYXRocyIsImNvbnRhaW5lciIsInNwYXduT3B0aW9ucyIsInBpcGVPdXRwdXQiLCJjb3B5RXJyb3JzIiwiZm9yRWFjaCIsImZwIiwiZnJvbSIsInRvIiwiZXJyb3IiLCJwdXNoIiwibGVuZ3RoIl0sIm1hcHBpbmdzIjoiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FBSUEsMkM7Ozs7Ozs7O0FBUU8sU0FBU0EsZUFBVCxHQUF5QztBQUM5QyxTQUFPLG1CQUFTQyxNQUFULElBQW1CLEVBQTFCO0FBQ0Q7O0FBRU0sTUFBTUMsZUFBZSxHQUFHLENBQUNDLElBQUQ7QUFDN0IscUJBQU9BLElBQVAsRUFBYSx3QkFBYixFQUF1Q0MsTUFBdkMsRUFESyxDOztBQUdBLGVBQWVDLFdBQWY7QUFDTEMsSUFBYyxHQUFHLENBQUMsUUFBRCxDQURaO0FBRUxDLFNBQW1CLEdBQUcsRUFGakI7QUFHTEMsTUFBZSxHQUFHLElBSGI7QUFJTEMsU0FBdUIsR0FBRyxFQUpyQjtBQUtMQyxJQUFZLEdBQUdDLGFBQWEsRUFMdkI7QUFNTEMsVUFBa0IsR0FBRyxjQU5oQjtBQU9MQyxPQUFlLEdBQUcsR0FQYjtBQVFZO0FBQ2pCLFFBQU1DLElBQUksR0FBRztBQUNYLFNBRFc7QUFFWCxLQUFHLENBQUMsSUFBRCxFQUFPQyxjQUFLQyxPQUFMLENBQWFKLFVBQWIsQ0FBUCxDQUZRO0FBR1gsTUFBSUosTUFBTSxHQUFHLENBQUMsVUFBRCxFQUFhQSxNQUFiLENBQUgsR0FBMEIsRUFBcEMsQ0FIVztBQUlYLEtBQUdGLElBQUksQ0FBQ1csTUFBTCxDQUFZLENBQUNDLEVBQUQsRUFBS0MsQ0FBTCxLQUFXLENBQUMsR0FBR0QsRUFBSixF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LE9BQU8yRCxLQUFQLEVBQWM7QUFDZEwsTUFBQUEsVUFBVSxDQUFDTSxJQUFYLENBQWdCRCxLQUFoQjtBQUNEO0FBQ0Y7O0FBRUQsTUFBSUwsVUFBVSxDQUFDTyxNQUFYLEdBQW9CLENBQXBCLElBQXlCekIsWUFBWSxLQUFLLElBQTlDLEVBQW9EO0FBQ2xELFVBQU0sSUFBSUgsS0FBSixDQUFVLDJCQUFWLENBQU47QUFDRDtBQUNGIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQGZsb3dcbmltcG9ydCBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0IGJ5dGVzIGZyb20gJ2J5dGVzJztcbmltcG9ydCBpc1JlYWNoYWJsZSBmcm9tICdpcy1yZWFjaGFibGUnO1xuaW1wb3J0IG1vbWVudCBmcm9tICdtb21lbnQnO1xuaW1wb3J0IHsgYnVpbGRMb2cgfSBmcm9tICcuL3J1bic7XG5pbXBvcnQgeyBnZXRDZmcsIGdldFBrZ05hbWUsIGdldFBrZ1Njb3BlIH0gZnJvbSAnLi9wa2cnO1xuaW1wb3J0IHsgc3Bhd24gfSBmcm9tICcuL2NwJztcbmltcG9ydCB7IGdldFZlcnNpb24sIGdldERldkJyYW5jaCB9IGZyb20gJy4vdmVyc2lvbic7XG5pbXBvcnQge1xuICBkb2NrZXJDb250YWluZXJSdW5EYWVtb24sXG4gIGRvY2tlckNvbnRhaW5lcktpbGwsXG59IGZyb20gJy4vZG9ja2VyLmNvbnRhaW5lcic7XG5pbXBvcnQgeyBkb2NrZXJOZXR3b3JrQ29ubmVjdCB9IGZyb20gJy4vZG9ja2VyLm5ldHdvcmsnO1xuXG5leHBvcnQgdHlwZSBEb2NrZXJDb25maWcgPSB7XG4gIHJlZ2lzdHJ5Pzogc3RyaW5nLFxuICByZXBvc2l0b3J5Pzogc3RyaW5nLFxuICBuYW1lPzogc3RyaW5nLFxufTtcblxuZXhwb3J0IGZ1bmN0aW9uIGdldERvY2tlckNvbmZpZygpOiBEb2NrZXJDb25maWcge1xuICByZXR1cm4gZ2V0Q2ZnKCkuZG9ja2VyIHx8IHt9O1xufVxuXG5leHBvcnQgY29uc3QgcGFyc2VEb2NrZXJEYXRlID0gKGRhdGU6IHN0cmluZyk6IERhdGUgPT5cbiAgbW9tZW50KGRhdGUsICdZWVlZLU1NLUREIEhIOm1tOnNzIFpaJykudG9EYXRlKCk7XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBkb2NrZXJCdWlsZChcbiAgdGFnczogc3RyaW5nW10gPSBbJ2xhdGVzdCddLFxuICBidWlsZEFyZ3M6IHN0cmluZ1tdID0gW10sXG4gIHRhcmdldDogP3N0cmluZyA9IG51bGwsXG4gIGV4dHJhQXJncz86ID8oc3RyaW5nW10pID0gW10sXG4gIHJlcG86IHN0cmluZyA9IGdldERvY2tlclJlcG8oKSxcbiAgZG9ja2VyRmlsZTogc3RyaW5nID0gJy4vRG9ja2VyZmlsZScsXG4gIHdvcmtEaXI6IHN0cmluZyA9ICcuJyxcbik6IFByb21pc2U8c3RyaW5nPiB7XG4gIGNvbnN0IGFyZ3MgPSBbXG4gICAgJ2J1aWxkJyxcbiAgICAuLi5bJy1mJywgcGF0aC5yZXNvbHZlKGRvY2tlckZpbGUpXSxcbiAgICAuLi4odGFyZ2V0ID8gWyctLXRhcmdldCcsIHRhcmdldF0gOiBbXSksXG4gICAgLi4udGFncy5yZWR1Y2UoKGFyLCB0KSA9PiBbLi4uYXIsICctdCcsIGAke3JlcG99OiR7dH1gXSwgW10pLFxuICAgIC4uLmJ1aWxkQXJncy5yZWR1Y2UoKGFyLCBhKSA9PiBbLi4uYXIsICctLWJ1aWxkLWFyZycsIGFdLCBbXSksXG4gICAgLi4uKGV4dHJhQXJncyB8fCBbXSksXG4gICAgcGF0aC5yZXNvbHZlKHdvcmtEaXIpLFxuICBdO1xuXG4gIHJldHVybiBzcGF3bignZG9ja2VyJywgYXJncywgeyBzdGRpbzogJ2luaGVyaXQnIH0pO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZG9ja2VyVGFnKFxuICBpbWFnZUlkOiBzdHJpbmcsXG4gIHRhZ3M6IHN0cmluZ1tdID0gWydsYXRlc3QnXSxcbiAgcmVwbz86IHN0cmluZyA9IGdldERvY2tlclJlcG8oKSxcbik6IFByb21pc2U8dm9pZD4ge1xuICBhd2FpdCBQcm9taXNlLmFsbChcbiAgICB0YWdzLm1hcChhc3luYyAodCkgPT4ge1xuICAgICAgYXdhaXQgc3Bhd24oJ2RvY2tlcicsIFsndGFnJywgaW1hZ2VJZCwgYCR7cmVwb306JHt0fWBdKTtcbiAgICAgIGJ1aWxkTG9nKGBUYWdnZWQgaW1hZ2UgJHtpbWFnZUlkfSBhcyAke3JlcG99OiR7dH1gKTtcbiAgICB9KSxcbiAgKTtcbn1cblxuLyoqXG4gKiBBcHBseSB0aGUgc3RhbmRhcmQgY29udmVudGlvbiBmb3IgdGFnZ2luZyB0aGUgZG9ja2VyIGltYWdlIGZvciB0aGUgcHJvamVjdCxcbiAqIGJhc2VkIG9uIHRoZSBzb3VyY2UgY29udHJvbCBicmFuY2ggYmVpbmcgYnVpbHQuXG4gKiBGb3IgcmVsZWFzZXMsIGFwcGxpZXMgYGxhdGVzdGAsIGBNLm0ucGAsIGBNLm1gLCBgTWBcbiAqIEZvciByZWxlYXNlIGNhbmRpZGF0ZXMsIGFwcGxpZXMgYGxhdGVzdC1yY2BcbiAqIEZvciBmZWF0dXJlIGJyYW5jaGVzLCBhcHBsaWVzIGBsYXRlc3QtZmVhdHVyZWBcbiAqIEZvciBkZXZlbG9wbWVudCBicmFuY2gsIGFwcGxpZXMgYGxhdGVzdC1kZXZgXG4gKiBBbGwgb3RoZXIgYnJhbmNoZXMsIG5vIHRhZyBpcyBhcHBsaWVzXG4gKiBAcGFyYW0ge3N0cmluZ30gaW1hZ2VJZCBpZCBvZiB0aGUgZG9ja2VyIGltYWdlIHRvIHdoaWNoIHRvIGFwcGx5IHRoZSB0YWdzXG4gKiBAcGFyYW0ge3N0cmluZ30gcmVwbyBvcHRpb25hbCBvdmVycmlkZSBvZiB0aGUgZG9ja2VyIHJlcG8gdXJsIHRvIHVzZSAoZGVyaXZlZCBmcm9tIHBhY2thZ2UuanNvbiBieSBkZWZhdWx0KVxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZG9ja2VyVGFnVmVyc2lvbihcbiAgaW1hZ2VJZDogc3RyaW5nLFxuICByZXBvPzogc3RyaW5nID0gZ2V0RG9ja2VyUmVwbygpLFxuKSB7XG4gIGNvbnN0IHsgaXNSZWxlYXNlLCBtYWpvciwgbWlub3IsIHBhdGNoLCBicmFuY2ggfSA9IGF3YWl0IGdldFZlcnNpb24oKTtcbiAgLy8gZGV0ZXJtaW5lIHdoYXQgdGFncyB0byBhcHBseVxuICBpZiAoaXNSZWxlYXNlKSB7XG4gICAgYXdhaXQgZG9ja2VyVGFnKFxuICAgICAgaW1hZ2VJZCxcbiAgICAgIFsnbGF0ZXN0JywgYCR7bWFqb3J9YCwgYCR7bWFqb3J9LiR7bWlub3J9YCwgYCR7bWFqb3J9LiR7bWlub3J9LiR7cGF0Y2h9YF0sXG4gICAgICByZXBvLFxuICAgICk7XG4gIH0gZWxzZSBpZiAoYnJhbmNoID09PSAoYXdhaXQgZ2V0RGV2QnJhbmNoKCkpKSB7XG4gICAgYXdhaXQgZG9ja2VyVGFnKGltYWdlSWQsIFsnbGF0ZXN0LWRldiddLCByZXBvKTtcbiAgfSBlbHNlIGlmIChicmFuY2gubWF0Y2goL14ocmVsZWFzZXxwYXRjaCktLykpIHtcbiAgICBhd2FpdCBkb2NrZXJUYWcoaW1hZ2VJZCwgWydsYXRlc3QtcmMnXSwgcmVwbyk7XG4gIH0gZWxzZSBpZiAoYnJhbmNoLm1hdGNoKC9eZmVhdHVyZS0vKSkge1xuICAgIGF3YWl0IGRvY2tlclRhZyhpbWFnZUlkLCBbJ2xhdGVzdC1mZWF0dXJlJ10sIHJlcG8pO1xuICB9XG59XG5cbmV4cG9ydCB0eXBlIERvY2tlckltYWdlID0ge1xuICByZXBvc2l0b3J5OiBzdHJpbmcsXG4gIHRhZzogc3RyaW5nLFxuICBpZDogc3RyaW5nLFxuICBkaWdlc3Q6IHN0cmluZyxcbiAgY3JlYXRlZDogRGF0ZSxcbiAgc2l6ZTogbnVtYmVyLFxufTtcblxuZXhwb3J0IHR5cGUgRG9ja2VySW1hZ2VGaWx0ZXIgPSAoaTogRG9ja2VySW1hZ2UpID0+IGJvb2xlYW47XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBkb2NrZXJJbWFnZXMoXG4gIHJlcG8/OiA/c3RyaW5nID0gZ2V0RG9ja2VyUmVwbygpLFxuICBmaWx0ZXI/OiA/RG9ja2VySW1hZ2VGaWx0ZXIgPSBudWxsLFxuKTogUHJvbWlzZTxEb2NrZXJJbWFnZVtdPiB7XG4gIHJldHVybiAoXG4gICAgYXdhaXQgc3Bhd24oXG4gICAgICAnZG9ja2VyJyxcbiAgICAgIFsnaW1hZ2VzJywgJy0tZm9ybWF0JywgYHt7anNvbiAufX1gLCAuLi4ocmVwbyA/IFtyZXBvXSA6IFtdKV0sXG4gICAgICB7IGNhcHR1cmVPdXRwdXQ6IHRydWUgfSxcbiAgICApXG4gIClcbiAgICAuc3BsaXQoJ1xcbicpXG4gICAgLmZpbHRlcigobGluZSkgPT4gISFsaW5lLnRyaW0oKSlcbiAgICAubWFwKChsKSA9PiB7XG4gICAgICBjb25zdCB7XG4gICAgICAgIFJlcG9zaXRvcnk6IHJlcG9zaXRvcnksXG4gICAgICAgIFRhZzogdGFnLFxuICAgICAgICBJRDogaWQsXG4gICAgICAgIERpZ2VzdDogZGlnZXN0LFxuICAgICAgICBDcmVhdGVkQXQsXG4gICAgICAgIFNpemUsXG4gICAgICB9ID0gSlNPTi5wYXJzZShsLnRyaW0oKSk7XG4gICAgICByZXR1cm4ge1xuICAgICAgICByZXBvc2l0b3J5LFxuICAgICAgICB0YWcsXG4gICAgICAgIGlkLFxuICAgICAgICBkaWdlc3QsXG4gICAgICAgIGNyZWF0ZWQ6IHBhcnNlRG9ja2VyRGF0ZShDcmVhdGVkQXQpLFxuICAgICAgICBzaXplOiBieXRlcy5wYXJzZShTaXplKSxcbiAgICAgIH07XG4gICAgfSlcbiAgICAuZmlsdGVyKFxuICAgICAgKG0pID0+XG4gICAgICAgIChtICYmIG0uaWQpICE9IG51bGwgJiZcbiAgICAgICAgKHR5cGVvZiBmaWx0ZXIgPT09ICdmdW5jdGlvbicgPyBmaWx0ZXIobSkgOiB0cnVlKSxcbiAgICApO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZ2V0RG9ja2VySWQoXG4gIHRhZzogc3RyaW5nID0gJ2xhdGVzdCcsXG4gIHJlcG8/OiA/c3RyaW5nLFxuKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgcmV0dXJuIChhd2FpdCBkb2NrZXJJbWFnZXMocmVwbywgKG0pID0+IG0udGFnID09PSB0YWcpKS5tYXAoKG0pID0+IG0uaWQpWzBdO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZ2V0VW50YWdnZWREb2NrZXJJZHMoXG4gIHJlcG8/OiA/c3RyaW5nLFxuICBmaWx0ZXI/OiA/RG9ja2VySW1hZ2VGaWx0ZXIgPSBudWxsLFxuKTogUHJvbWlzZTxzdHJpbmdbXT4ge1xuICByZXR1cm4gKFxuICAgIGF3YWl0IGRvY2tlckltYWdlcyhcbiAgICAgIHJlcG8sXG4gICAgICAobSkgPT5cbiAgICAgICAgbS50YWcgPT09ICc8bm9uZT4nICYmICh0eXBlb2YgZmlsdGVyID09PSAnZnVuY3Rpb24nID8gZmlsdGVyKG0pIDogdHJ1ZSksXG4gICAgKVxuICApLm1hcCgobSkgPT4gbS5pZCk7XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBnZXREb2NrZXJUYWdzKFxuICBpZD86ID9zdHJpbmcsXG4gIHJlcG8/OiA/c3RyaW5nLFxuICBmdWxsTmFtZTogYm9vbGVhbiA9IGZhbHNlLFxuICBmaWx0ZXI/OiA/RG9ja2VySW1hZ2VGaWx0ZXIgPSBudWxsLFxuKTogUHJvbWlzZTxzdHJpbmdbXT4ge1xuICByZXR1cm4gKFxuICAgIGF3YWl0IGRvY2tlckltYWdlcyhcbiAgICAgIHJlcG8sXG4gICAgICAobSkgPT5cbiAgICAgICAgKCFpZCB8fCBtLmlkID09PSBpZCkgJiZcbiAgICAgICAgKHR5cGVvZiBmaWx0ZXIgPT09ICdmdW5jdGlvbicgPyBmaWx0ZXIobSkgOiB0cnVlKSxcbiAgICApXG4gICkubWFwKChtKSA9PiAoZnVsbE5hbWUgPyBgJHttLnJlcG9zaXRvcnl9OiR7bS50YWd9YCA6IG0udGFnKSk7XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBnZXREb2NrZXJEaWdlc3QoXG4gIGltYWdlSWQ6IHN0cmluZyxcbiAgcmVwbz86IHN0cmluZyxcbik6IFByb21pc2U8c3RyaW5nPiB7XG4gIHJldHVybiAoYXdhaXQgZG9ja2VySW1hZ2VzKHJlcG8sIChtKSA9PiBtLmlkID09PSBpbWFnZUlkKSkubWFwKFxuICAgIChtKSA9PiBtLmRpZ2VzdCxcbiAgKVswXTtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGRvY2tlckxvZ2luKFxuICB1c2VyOiBzdHJpbmcsXG4gIHBhc3N3b3JkOiBzdHJpbmcsXG4gIHJlZ2lzdHJ5OiBzdHJpbmcsXG4pOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3QgcmVnID0gcmVnaXN0cnkgfHwgZ2V0RG9ja2VyQ29uZmlnKCkucmVnaXN0cnk7XG4gIGF3YWl0IHNwYXduKFxuICAgICdkb2NrZXInLFxuICAgIFtcbiAgICAgICdsb2dpbicsXG4gICAgICAnLXUnLFxuICAgICAgdXNlciB8fCBwcm9jZXNzLmVudi5BUlRJRkFDVE9SWV9VU0VSIHx8ICcnLFxuICAgICAgJy1wJyxcbiAgICAgIHBhc3N3b3JkIHx8IHByb2Nlc3MuZW52LkFSVElGQUNUT1JZX1BBU1NXT1JEIHx8ICcnLFxuICAgICAgLi4uKHJlZyA/IFtyZWddIDogW10pLFxuICAgIF0sXG4gICAgeyBzdGRpbzogJ2luaGVyaXQnIH0sXG4gICk7XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBkb2NrZXJQdXNoKFxuICB0YWdzPzogc3RyaW5nW10gPSBbJ2xhdGVzdCddLFxuICByZXBvPzogc3RyaW5nID0gZ2V0RG9ja2VyUmVwbygpLFxuKSB7XG4gIC8vIGRvIHRoaXMgc2VxdWVudGlhbGx5LCBzbyB5b3UgZG9uJ3QgcHVzaCB0aGUgc2FtZSBpbWFnZSBzaW11bHRhbmVvdXNseVxuICBhd2FpdCB0YWdzLnJlZHVjZShhc3luYyAocHJldiwgdGFnKSA9PiB7XG4gICAgYXdhaXQgcHJldjtcbiAgICBhd2FpdCBzcGF3bignZG9ja2VyJywgWydwdXNoJywgYCR7cmVwb306JHt0YWd9YF0sIHsgc3RkaW86ICdpbmhlcml0JyB9KTtcbiAgfSwgUHJvbWlzZS5yZXNvbHZlKCkpO1xufVxuXG5leHBvcnQgdHlwZSBEb2NrZXJQdWxsT3B0aW9ucyA9IHtcbiAgaW1hZ2U6IHN0cmluZyxcbiAgb2ZmbGluZT86IGJvb2xlYW4sXG4gIHRlc3RVcmw/OiA/c3RyaW5nLFxufTtcblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGRvY2tlclB1bGwoe1xuICBpbWFnZSxcbiAgb2ZmbGluZSA9IHByb2Nlc3MuYXJndi5pbmNsdWRlcygnLS1vZmZsaW5lJyksXG4gIHRlc3RVcmwsXG59OiBEb2NrZXJQdWxsT3B0aW9ucykge1xuICBpZiAob2ZmbGluZSB8fCAhKGF3YWl0IGlzUmVhY2hhYmxlKHRlc3RVcmwgfHwgJ2h0dHBzOi8vaHViLmRvY2tlci5jb20nKSkpIHtcbiAgICBpZiAob2ZmbGluZSA9PT0gZmFsc2UpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignT2ZmbGluZSwgY2Fubm90IGRvY2tlciBwdWxsJyk7XG4gICAgfVxuICAgIGJ1aWxkTG9nKCdJdCBsb29rcyBsaWtlIHlvdSBhcmUgb2ZmbGluZSwgc2tpcHBpbmcgZG9ja2VyIHB1bGwnKTtcbiAgfSBlbHNlIHtcbiAgICAvLyB0aHJvd3Mgb24gZmFpbHVyZVxuICAgIGF3YWl0IHNwYXduKCdkb2NrZXInLCBbJ3B1bGwnLCBpbWFnZV0sIHsgc3RkaW86ICdpbmhlcml0JyB9KTtcbiAgfVxufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZG9ja2VyUm1pKFxuICBpbWFnZXM6IHN0cmluZ1tdID0gW10sXG4gIGlnbm9yZUVycm9yczogYm9vbGVhbiA9IHRydWUsXG4pOiBQcm9taXNlPHZvaWQ+IHtcbiAgLy8gbXVzdCBkbyB0aGVzZSBzZXF1ZW50aWFsbHksIG9yIHRoZXkgd2lsbCBpbnRlcmZlcmUgd2l0aCBlYWNoIG90aGVyXG4gIGF3YWl0IGltYWdlcy5yZWR1Y2UoYXN5bmMgKHByZXYsIGltYWdlKSA9PiB7XG4gICAgYXdhaXQgcHJldjtcbiAgICBhd2FpdCBzcGF3bignZG9ja2VyJywgWydybWknLCBpbWFnZV0sIHsgc3RkaW86ICdpbmhlcml0JyB9KS5jYXRjaCgoZXJyKSA9PiB7XG4gICAgICBpZiAoaWdub3JlRXJyb3JzKSB7XG4gICAgICAgIGJ1aWxkTG9nKFxuICAgICAgICAgIGBXYXJuaW5nIChpZ25vcmVkIEVycm9yKTogRmFpbGVkIHRvIHJtIGltYWdlKHMpOiAke2Vyci5tZXNzYWdlfWAsXG4gICAgICAgICk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvdyBlcnI7XG4gICAgICB9XG4gICAgfSk7XG4gIH0sIFByb21pc2UucmVzb2x2ZSgpKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldERvY2tlclJlcG8oKTogc3RyaW5nIHtcbiAgY29uc3QgeyByZWdpc3RyeSwgcmVwb3NpdG9yeTogZGtyUmVwbywgbmFtZTogZGtyTmFtZSB9ID0gZ2V0RG9ja2VyQ29uZmlnKCk7XG4gIGNvbnN0IHJlcG9zaXRvcnkgPSBka3JSZXBvIHx8IGdldFBrZ1Njb3BlKCk7XG4gIGNvbnN0IG5hbWUgPSBka3JOYW1lIHx8IGdldFBrZ05hbWUoZmFsc2UpO1xuICBpZiAoIXJlcG9zaXRvcnkgfHwgIW5hbWUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAnRG9ja2VyIGNvbmZpZ3VyYXRpb24gaXMgbWlzc2luZyBvciBpbmNvbXBsZXRlIGluIHBhY2thZ2UuanNvbicsXG4gICAgKTtcbiAgfVxuICByZXR1cm4gYCR7cmVnaXN0cnkgPyBgJHtyZWdpc3RyeX0vYCA6ICcnfSR7cmVwb3NpdG9yeX0vJHtuYW1lfWA7XG59XG5cbmV4cG9ydCB0eXBlIFB1bGxBbmRSdW5Db250YWluZXJPcHRpb25zID0ge1xuICAuLi5Eb2NrZXJQdWxsT3B0aW9ucyxcbiAgcnVuQXJncz86IHN0cmluZ1tdLFxuICBjbWQ/OiBzdHJpbmdbXSxcbiAgbmV0d29yaz86ID9zdHJpbmcsXG4gIGFsaWFzPzogP3N0cmluZyxcbn07XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBkb2NrZXJQdWxsQW5kUnVuQ29udGFpbmVyKFxuICBpbWFnZTogc3RyaW5nLFxuICBvcHRpb25zOiBQdWxsQW5kUnVuQ29udGFpbmVyT3B0aW9ucyA9IHt9LFxuKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgY29uc3Qge1xuICAgIHJ1bkFyZ3MgPSBbXSxcbiAgICBjbWQgPSBbXSxcbiAgICBuZXR3b3JrLFxuICAgIGFsaWFzLFxuICAgIG9mZmxpbmUgPSBwcm9jZXNzLmFyZ3YuaW5jbHVkZXMoJy0tb2ZmbGluZScpLFxuICAgIHRlc3RVcmwsXG4gIH0gPSBvcHRpb25zO1xuXG4gIHRyeSB7XG4gICAgYXdhaXQgZG9ja2VyUHVsbCh7IGltYWdlLCBvZmZsaW5lLCB0ZXN0VXJsIH0pO1xuICB9IGNhdGNoIChlcnIpIHtcbiAgICBidWlsZExvZyhgZG9ja2VyIHB1bGwgZmFpbGVkICgke2Vyci5tZXNzYWdlfSksIGF0dGVtcHRpbmcgdG8gY29udGludWUuLi5gKTtcbiAgfVxuICBjb25zdCB7IGlkIH0gPSBhd2FpdCBkb2NrZXJDb250YWluZXJSdW5EYWVtb24oeyBpbWFnZSwgcnVuQXJncywgY21kIH0pO1xuICBpZiAobmV0d29yaykge1xuICAgIGF3YWl0IGRvY2tlck5ldHdvcmtDb25uZWN0KG5ldHdvcmssIGlkLCBhbGlhcyk7XG4gIH1cbiAgcmV0dXJuIGlkO1xufVxuXG5leHBvcnQgdHlwZSBDb3B5RmlsZVBhdGhDb25maWcgPSB7XG4gIGZyb206IHN0cmluZyxcbiAgdG86IHN0cmluZyxcbn07XG5cbmV4cG9ydCB0eXBlIENvcHlGaWxlc0Zyb21Eb2NrZXJJbWFnZUNvbmZpZyA9IHtcbiAgaW1hZ2VJZDogc3RyaW5nLFxuICBmaWxlUGF0aHM6IENvcHlGaWxlUGF0aENvbmZpZ1tdLFxuICBpZ25vcmVFcnJvcnM/OiA/Ym9vbGVhbixcbn07XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBjb3B5RmlsZXNGcm9tRG9ja2VySW1hZ2Uoe1xuICBpbWFnZUlkLFxuICBmaWxlUGF0aHMsXG4gIGlnbm9yZUVycm9ycyxcbn06IENvcHlGaWxlc0Zyb21Eb2NrZXJJbWFnZUNvbmZpZyk6IFByb21pc2U8YW55PiB7XG4gIGNvbnN0IGNvbnRhaW5lciA9IGF3YWl0IGRvY2tlckNvbnRhaW5lclJ1bkRhZW1vbih7XG4gICAgaW1hZ2U6IGltYWdlSWQsXG4gICAgcnVuQXJnczogWyctaXQnLCAnLS1ybScsICctLWVudHJ5cG9pbnQ9L2Jpbi9iYXNoJ10sXG4gICAgY21kOiBbJ3JlYWQnLCAnLXAnLCAncGF1c2UnXSxcbiAgfSk7XG5cbiAgYnVpbGRMb2coYENvcHlpbmcgRmlsZXMgZnJvbSBEb2NrZXIgSW1hZ2UgLSBpbWFnZUlkICgke2ltYWdlSWR9KWApO1xuXG4gIGNvbnN0IHNwYXduT3B0aW9ucyA9IHtcbiAgICBzdGRpbzogJ2luaGVyaXQnLFxuICAgIHBpcGVPdXRwdXQ6IHRydWUsXG4gICAgY2FwdHVyZU91dHB1dDogZmFsc2UsXG4gIH07XG4gIGNvbnN0IGNvcHlFcnJvcnMgPSBbXTtcblxuICB0cnkge1xuICAgIGZpbGVQYXRocy5mb3JFYWNoKGFzeW5jIChmcCkgPT4ge1xuICAgICAgLy8gVHJ5IHRvIGNvcHkgZnJvbSB0aGUgRGVidWcgRm9sZGVyXG4gICAgICB0cnkge1xuICAgICAgICBhd2FpdCBzcGF3bihcbiAgICAgICAgICAnZG9ja2VyJyxcbiAgICAgICAgICBbJ2NwJywgYCR7Y29udGFpbmVyLmlkfToke2ZwLmZyb219YCwgZnAudG9dLFxuICAgICAgICAgIHNwYXduT3B0aW9ucyxcbiAgICAgICAgKTtcbiAgICAgICAgYnVpbGRMb2coYENvcGllZCAke2ZwLmZyb219ID0+ICR7ZnAudG99YCk7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBjb3B5RXJyb3JzLnB1c2goZXJyb3IpO1xuICAgICAgICBidWlsZExvZyhgRXJyb3IgY29weWluZyBmaWxlICR7ZnAuZnJvbX1gKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfSBmaW5hbGx5IHtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgZG9ja2VyQ29udGFpbmVyS2lsbChjb250YWluZXIuaWQpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBjb3B5RXJyb3JzLnB1c2goZXJyb3IpO1xuICAgIH1cbiAgfVxuXG4gIGlmIChjb3B5RXJyb3JzLmxlbmd0aCA+IDAgJiYgaWdub3JlRXJyb3JzICE9PSB0cnVlKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdTb21lIGZpbGVzIGZhaWxlZCB0byBjb3B5Jyk7XG4gIH1cbn1cbiJdfQ==