@verdaccio/canary 6.3.2-canary.404363f

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 (53) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +38 -0
  3. package/bin/verdaccio +3 -0
  4. package/bin/verdaccio-canary +3 -0
  5. package/build/api/debug/index.js +28 -0
  6. package/build/api/endpoint/api/dist-tags.js +77 -0
  7. package/build/api/endpoint/api/package.js +103 -0
  8. package/build/api/endpoint/api/ping.js +13 -0
  9. package/build/api/endpoint/api/publish.js +359 -0
  10. package/build/api/endpoint/api/search.js +107 -0
  11. package/build/api/endpoint/api/star.js +73 -0
  12. package/build/api/endpoint/api/stars.js +42 -0
  13. package/build/api/endpoint/api/user.js +84 -0
  14. package/build/api/endpoint/api/v1/profile.js +69 -0
  15. package/build/api/endpoint/api/v1/search.js +181 -0
  16. package/build/api/endpoint/api/v1/token.js +140 -0
  17. package/build/api/endpoint/api/whoami.js +15 -0
  18. package/build/api/endpoint/index.js +58 -0
  19. package/build/api/index.js +105 -0
  20. package/build/api/middleware.js +56 -0
  21. package/build/api/web/api/index.js +31 -0
  22. package/build/api/web/api/package.js +165 -0
  23. package/build/api/web/api/search.js +53 -0
  24. package/build/api/web/api/user.js +70 -0
  25. package/build/api/web/api/utils.js +14 -0
  26. package/build/api/web/html/favicon.ico +0 -0
  27. package/build/api/web/index.js +96 -0
  28. package/build/index.js +76 -0
  29. package/build/lib/auth-utils.js +16 -0
  30. package/build/lib/bootstrap.js +167 -0
  31. package/build/lib/cli/cli.js +26 -0
  32. package/build/lib/cli/commands/info.js +26 -0
  33. package/build/lib/cli/commands/init.js +78 -0
  34. package/build/lib/cli/commands/version.js +17 -0
  35. package/build/lib/cli/utils.js +14 -0
  36. package/build/lib/cli.js +16 -0
  37. package/build/lib/config.js +22 -0
  38. package/build/lib/constants.js +121 -0
  39. package/build/lib/experiments.js +29 -0
  40. package/build/lib/local-storage.js +760 -0
  41. package/build/lib/logger/index.js +21 -0
  42. package/build/lib/metadata-utils.js +39 -0
  43. package/build/lib/run-server.js +122 -0
  44. package/build/lib/storage-utils.js +282 -0
  45. package/build/lib/storage.js +676 -0
  46. package/build/lib/up-storage.js +605 -0
  47. package/build/lib/uplink-util.js +36 -0
  48. package/build/lib/utils.js +265 -0
  49. package/conf/.gitkeep +0 -0
  50. package/index.js +1 -0
  51. package/package.json +156 -0
  52. package/security.txt +5 -0
  53. package/systemd/verdaccio.service +11 -0
@@ -0,0 +1,676 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _assert = _interopRequireDefault(require("assert"));
8
+ var _async = _interopRequireDefault(require("async"));
9
+ var _debug = _interopRequireDefault(require("debug"));
10
+ var _lodash = _interopRequireDefault(require("lodash"));
11
+ var _stream = _interopRequireDefault(require("stream"));
12
+ var _config = require("@verdaccio/config");
13
+ var _core = require("@verdaccio/core");
14
+ var _loaders = require("@verdaccio/loaders");
15
+ var _localStorageLegacy = _interopRequireDefault(require("@verdaccio/local-storage-legacy"));
16
+ var _searchIndexer = require("@verdaccio/search-indexer");
17
+ var _streams = require("@verdaccio/streams");
18
+ var _logger = require("../lib/logger");
19
+ var _constants = require("./constants");
20
+ var _localStorage = _interopRequireDefault(require("./local-storage"));
21
+ var _metadataUtils = require("./metadata-utils");
22
+ var _storageUtils = require("./storage-utils");
23
+ var _upStorage = _interopRequireDefault(require("./up-storage"));
24
+ var _uplinkUtil = require("./uplink-util");
25
+ var _utils = require("./utils");
26
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
27
+ const debug = (0, _debug.default)('verdaccio:storage');
28
+ class Storage {
29
+ constructor(config) {
30
+ this.config = config;
31
+ this.uplinks = (0, _uplinkUtil.setupUpLinks)(config);
32
+ this.logger = _logger.logger;
33
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
34
+ // @ts-ignore
35
+ this.localStorage = null;
36
+ }
37
+ async init(config, filters) {
38
+ if (this.localStorage === null) {
39
+ this.filters = filters;
40
+ const storageInstance = await this.loadStorage(config, this.logger);
41
+ this.localStorage = new _localStorage.default(this.config, _logger.logger, storageInstance);
42
+ await this.localStorage.getSecret(config);
43
+ debug('initialization completed');
44
+ } else {
45
+ debug('storage has been already initialized');
46
+ }
47
+ if (!this.filters) {
48
+ this.filters = await (0, _loaders.asyncLoadPlugin)(this.config.filters, {
49
+ config: this.config,
50
+ logger: this.logger
51
+ }, plugin => {
52
+ return typeof plugin.filter_metadata !== 'undefined';
53
+ }, true, this.config?.serverSettings?.pluginPrefix, _core.PLUGIN_CATEGORY.FILTER);
54
+ debug('filters available %o', this.filters.length);
55
+ }
56
+ }
57
+ async loadStorage(config, logger) {
58
+ const Storage = await this.loadStorePlugin();
59
+ if (_lodash.default.isNil(Storage)) {
60
+ (0, _assert.default)(this.config.storage, 'CONFIG: storage path not defined');
61
+ debug('no custom storage found, loading default storage @verdaccio/local-storage');
62
+ const localStorage = new _localStorageLegacy.default(config, logger);
63
+ logger.info({
64
+ name: '@verdaccio/local-storage',
65
+ pluginCategory: _core.PLUGIN_CATEGORY.STORAGE
66
+ }, 'plugin @{name} successfully loaded (@{pluginCategory})');
67
+ return localStorage;
68
+ }
69
+ return Storage;
70
+ }
71
+ async loadStorePlugin() {
72
+ const plugins = await (0, _loaders.asyncLoadPlugin)(this.config.store, {
73
+ config: this.config,
74
+ logger: this.logger
75
+ }, plugin => {
76
+ return typeof plugin.getPackageStorage !== 'undefined';
77
+ }, true, this.config?.serverSettings?.pluginPrefix, _core.PLUGIN_CATEGORY.STORAGE);
78
+ if (plugins.length > 1) {
79
+ this.logger.warn('more than one storage plugins has been detected, multiple storage are not supported, one will be selected automatically');
80
+ }
81
+ return _lodash.default.head(plugins);
82
+ }
83
+
84
+ /**
85
+ * Add a {name} package to a system
86
+ Function checks if package with the same name is available from uplinks.
87
+ If it isn't, we create package locally
88
+ Used storages: local (write) && uplinks
89
+ */
90
+ async addPackage(name, metadata, callback) {
91
+ try {
92
+ await (0, _storageUtils.checkPackageLocal)(name, this.localStorage);
93
+ await (0, _storageUtils.checkPackageRemote)(name, this._isAllowPublishOffline(), this._syncUplinksMetadata.bind(this));
94
+ await (0, _storageUtils.publishPackage)(name, metadata, this.localStorage);
95
+ callback();
96
+ } catch (err) {
97
+ callback(err);
98
+ }
99
+ }
100
+ _isAllowPublishOffline() {
101
+ return typeof this.config.publish !== 'undefined' && _lodash.default.isBoolean(this.config.publish.allow_offline) && this.config.publish.allow_offline;
102
+ }
103
+ readTokens(filter) {
104
+ return this.localStorage.readTokens(filter);
105
+ }
106
+ saveToken(token) {
107
+ return this.localStorage.saveToken(token);
108
+ }
109
+ deleteToken(user, tokenKey) {
110
+ return this.localStorage.deleteToken(user, tokenKey);
111
+ }
112
+
113
+ /**
114
+ * Add a new version of package {name} to a system
115
+ Used storages: local (write)
116
+ */
117
+ addVersion(name, version, metadata, tag, callback) {
118
+ this.localStorage.addVersion(name, version, metadata, tag, callback);
119
+ }
120
+
121
+ /**
122
+ * Tags a package version with a provided tag
123
+ Used storages: local (write)
124
+ */
125
+ mergeTags(name, tagHash, callback) {
126
+ this.localStorage.mergeTags(name, tagHash, callback);
127
+ }
128
+
129
+ /**
130
+ * Change an existing package (i.e. unpublish one version)
131
+ Function changes a package info from local storage and all uplinks with write access./
132
+ Used storages: local (write)
133
+ */
134
+ changePackage(name, metadata, revision, callback) {
135
+ this.localStorage.changePackage(name, metadata, revision, callback);
136
+ }
137
+
138
+ /**
139
+ * Remove a package from a system
140
+ Function removes a package from local storage
141
+ Used storages: local (write)
142
+ */
143
+ removePackage(name, callback) {
144
+ this.localStorage.removePackage(name, callback);
145
+ // update the indexer
146
+ _searchIndexer.SearchMemoryIndexer.remove(name).catch(reason => {
147
+ debug('indexer has failed on remove item %o', reason);
148
+ _logger.logger.error('indexer has failed on remove item');
149
+ });
150
+ }
151
+
152
+ /**
153
+ Remove a tarball from a system
154
+ Function removes a tarball from local storage.
155
+ Tarball in question should not be linked to in any existing
156
+ versions, i.e. package version should be unpublished first.
157
+ Used storage: local (write)
158
+ */
159
+ removeTarball(name, filename, revision, callback) {
160
+ this.localStorage.removeTarball(name, filename, revision, callback);
161
+ }
162
+
163
+ /**
164
+ * Upload a tarball for {name} package
165
+ Function is synchronous and returns a WritableStream
166
+ Used storages: local (write)
167
+ */
168
+ addTarball(name, filename) {
169
+ return this.localStorage.addTarball(name, filename);
170
+ }
171
+ hasLocalTarball(name, filename) {
172
+ const self = this;
173
+ return new Promise((resolve, reject) => {
174
+ let localStream = self.localStorage.getTarball(name, filename);
175
+ let isOpen = false;
176
+ localStream.on('error', err => {
177
+ if (isOpen || err.status !== _constants.HTTP_STATUS.NOT_FOUND) {
178
+ reject(err);
179
+ }
180
+ // local reported 404 or request was aborted already
181
+ if (localStream) {
182
+ localStream.abort();
183
+ localStream = null;
184
+ }
185
+ resolve(false);
186
+ });
187
+ localStream.on('open', function () {
188
+ isOpen = true;
189
+ localStream.abort();
190
+ localStream = null;
191
+ resolve(true);
192
+ });
193
+ });
194
+ }
195
+
196
+ /**
197
+ Get a tarball from a storage for {name} package
198
+ Function is synchronous and returns a ReadableStream
199
+ Function tries to read tarball locally, if it fails then it reads package
200
+ information in order to figure out where we can get this tarball from
201
+ Used storages: local || uplink (just one)
202
+ */
203
+ getTarball(name, filename) {
204
+ const readStream = new _streams.ReadTarball({});
205
+ readStream.abort = function () {};
206
+ const self = this;
207
+
208
+ // Check if the tarball is allowed by filter plugins before serving.
209
+ // Filters may block specific versions, so we verify the tarball's version
210
+ // still exists in the filtered metadata.
211
+ this._isTarballAllowedByFilters(name, filename).then(async allowed => {
212
+ if (!allowed) {
213
+ readStream.emit('error', _utils.ErrorCode.getNotFound(_constants.API_ERROR.NO_PACKAGE));
214
+ return;
215
+ }
216
+
217
+ // trying local first
218
+ let localStream = self.localStorage.getTarball(name, filename);
219
+ let isOpen = false;
220
+ localStream.on('error', err => {
221
+ if (isOpen || err.status !== _constants.HTTP_STATUS.NOT_FOUND) {
222
+ return readStream.emit('error', err);
223
+ }
224
+
225
+ // local reported 404
226
+ const err404 = err;
227
+ localStream.abort();
228
+ localStream = null; // we force for garbage collector
229
+
230
+ const lookupFromUplinks = info => {
231
+ self._syncUplinksMetadata(name, info, {}, (syncErr, syncInfo) => {
232
+ if (_lodash.default.isNil(syncErr) === false) {
233
+ return readStream.emit('error', syncErr);
234
+ }
235
+ if (_lodash.default.isNil(syncInfo._distfiles) || _lodash.default.isNil(syncInfo._distfiles[filename])) {
236
+ return readStream.emit('error', err404);
237
+ }
238
+ serveFile(syncInfo._distfiles[filename]);
239
+ });
240
+ };
241
+ self.localStorage.getPackageMetadataAsync(name).then(info => {
242
+ if (info._distfiles && _lodash.default.isNil(info._distfiles[filename]) === false) {
243
+ // information about this file exists locally
244
+ serveFile(info._distfiles[filename]);
245
+ } else {
246
+ // we know nothing about this file, trying to get information elsewhere
247
+ lookupFromUplinks(info);
248
+ }
249
+ }, () => {
250
+ // we know nothing about this file, trying to get information elsewhere
251
+ lookupFromUplinks(null);
252
+ });
253
+ });
254
+ localStream.on('content-length', function (v) {
255
+ readStream.emit('content-length', v);
256
+ });
257
+ localStream.on('open', function () {
258
+ isOpen = true;
259
+ localStream.pipe(readStream);
260
+ });
261
+ });
262
+ return readStream;
263
+
264
+ /**
265
+ * Fetch and cache local/remote packages.
266
+ * @param {Object} file define the package shape
267
+ */
268
+ function serveFile(file) {
269
+ let uplink = null;
270
+ for (const uplinkId in self.uplinks) {
271
+ if ((0, _config.hasProxyTo)(name, uplinkId, self.config.packages)) {
272
+ uplink = self.uplinks[uplinkId];
273
+ }
274
+ }
275
+ if (uplink == null) {
276
+ uplink = new _upStorage.default({
277
+ url: file.url,
278
+ cache: true,
279
+ _autogenerated: true
280
+ }, self.config);
281
+ }
282
+ let savestream = null;
283
+ if (uplink.config.cache) {
284
+ savestream = self.localStorage.addTarball(name, filename);
285
+ }
286
+ let on_open = function () {
287
+ // prevent it from being called twice
288
+ on_open = function () {};
289
+ const rstream2 = uplink.fetchTarball(file.url);
290
+ rstream2.on('error', function (err) {
291
+ if (savestream) {
292
+ savestream.abort();
293
+ }
294
+ savestream = null;
295
+ readStream.emit('error', err);
296
+ });
297
+ rstream2.on('end', function () {
298
+ if (savestream) {
299
+ savestream.done();
300
+ }
301
+ });
302
+ rstream2.on('content-length', function (v) {
303
+ readStream.emit('content-length', v);
304
+ if (savestream) {
305
+ savestream.emit('content-length', v);
306
+ }
307
+ });
308
+ rstream2.pipe(readStream);
309
+ if (savestream) {
310
+ rstream2.pipe(savestream);
311
+ }
312
+ };
313
+ if (savestream) {
314
+ savestream.on('open', function () {
315
+ on_open();
316
+ });
317
+ savestream.on('error', function (err) {
318
+ self.logger.warn({
319
+ err: err,
320
+ fileName: file
321
+ }, 'error saving file @{fileName}: @{err.message}\n@{err.stack}');
322
+ if (savestream) {
323
+ savestream.abort();
324
+ }
325
+ savestream = null;
326
+ on_open();
327
+ });
328
+ } else {
329
+ on_open();
330
+ }
331
+ }
332
+ }
333
+
334
+ /**
335
+ Retrieve a package metadata for {name} package
336
+ Function invokes localStorage.getPackage and uplink.get_package for every
337
+ uplink with proxy_access rights against {name} and combines results
338
+ into one json object
339
+ Used storages: local && uplink (proxy_access)
340
+ * @param {object} options
341
+ * @property {string} options.name Package Name
342
+ * @property {object} options.req Express `req` object
343
+ * @property {boolean} options.keepUpLinkData keep up link info in package meta, last update, etc.
344
+ * @property {function} options.callback Callback for receive data
345
+ */
346
+ getPackage(options) {
347
+ this.localStorage.getPackageMetadata(options.name, (err, data) => {
348
+ if (err && (!err.status || err.status >= _constants.HTTP_STATUS.INTERNAL_ERROR)) {
349
+ // report internal errors right away
350
+ return options.callback(err);
351
+ }
352
+ this._syncUplinksMetadata(options.name, data, {
353
+ req: options.req,
354
+ uplinksLook: options.uplinksLook
355
+ }, function getPackageSynUpLinksCallback(err, result, uplinkErrors) {
356
+ if (err) {
357
+ return options.callback(err);
358
+ }
359
+ (0, _utils.normalizeDistTags)((0, _storageUtils.cleanUpLinksRef)(options.keepUpLinkData, result));
360
+
361
+ // npm can throw if this field doesn't exist
362
+ result._attachments = {};
363
+ if (options.abbreviated === true) {
364
+ options.callback(null, (0, _storageUtils.convertAbbreviatedManifest)(result), uplinkErrors);
365
+ } else {
366
+ options.callback(null, result, uplinkErrors);
367
+ }
368
+ });
369
+ });
370
+ }
371
+
372
+ /**
373
+ Retrieve remote and local packages more recent than {startkey}
374
+ Function streams all packages from all uplinks first, and then
375
+ local packages.
376
+ Note that local packages could override registry ones just because
377
+ they appear in JSON last. That's a trade-off we make to avoid
378
+ memory issues.
379
+ Used storages: local && uplink (proxy_access)
380
+ * @param {*} startkey
381
+ * @param {*} options
382
+ * @return {Stream}
383
+ */
384
+ search(startkey, options) {
385
+ const self = this;
386
+ const searchStream = new _stream.default.PassThrough({
387
+ objectMode: true
388
+ });
389
+ _async.default.eachSeries(Object.keys(this.uplinks), function (up_name, cb) {
390
+ // shortcut: if `local=1` is supplied, don't call uplinks
391
+ if (options.req?.query?.local !== undefined) {
392
+ return cb();
393
+ }
394
+ _logger.logger.info(`search for uplink ${up_name}`);
395
+ // search by keyword for each uplink
396
+ const uplinkStream = self.uplinks[up_name].search(options);
397
+ // join uplink stream with streams PassThrough
398
+ uplinkStream.pipe(searchStream, {
399
+ end: false
400
+ });
401
+ uplinkStream.on('error', function (err) {
402
+ self.logger.error({
403
+ err: err
404
+ }, 'uplink error: @{err.message}');
405
+ cb();
406
+ // to avoid call callback more than once
407
+ cb = function () {};
408
+ });
409
+ uplinkStream.on('end', function () {
410
+ cb();
411
+ // to avoid call callback more than once
412
+ cb = function () {};
413
+ });
414
+ searchStream.abort = function () {
415
+ if (uplinkStream.abort) {
416
+ uplinkStream.abort();
417
+ }
418
+ cb();
419
+ // to avoid call callback more than once
420
+ cb = function () {};
421
+ };
422
+ },
423
+ // executed after all series
424
+ function () {
425
+ // attach a local search results
426
+ const localSearchStream = self.localStorage.search(startkey, options);
427
+ searchStream.abort = function () {
428
+ localSearchStream.abort();
429
+ };
430
+ localSearchStream.pipe(searchStream, {
431
+ end: true
432
+ });
433
+ localSearchStream.on('error', function (err) {
434
+ self.logger.error({
435
+ err: err
436
+ }, 'search error: @{err.message}');
437
+ searchStream.end();
438
+ });
439
+ });
440
+ return searchStream;
441
+ }
442
+
443
+ /**
444
+ * Retrieve only private local packages
445
+ * @param {*} callback
446
+ */
447
+ getLocalDatabase(callback) {
448
+ this.localStorage.storagePlugin.get((err, locals) => {
449
+ if (err) {
450
+ return callback(err);
451
+ }
452
+ this._collectLocalPackages(locals).then(packages => callback(null, packages), err => callback(err));
453
+ });
454
+ }
455
+
456
+ /**
457
+ * Read each local package name, apply filters, and collect the latest version.
458
+ */
459
+ async _collectLocalPackages(locals) {
460
+ const packages = [];
461
+ for (const name of locals) {
462
+ try {
463
+ const pkgMetadata = await this.localStorage.getPackageMetadataAsync(name);
464
+ const {
465
+ filteredPackage
466
+ } = await this._applyFilters(pkgMetadata);
467
+ const latest = filteredPackage[_constants.DIST_TAGS]?.latest;
468
+ if (latest && filteredPackage.versions[latest]) {
469
+ const version = filteredPackage.versions[latest];
470
+ const timeList = filteredPackage.time;
471
+ const time = timeList[latest];
472
+ // @ts-ignore
473
+ version.time = time;
474
+
475
+ // Add for stars api
476
+ // @ts-ignore
477
+ version.users = filteredPackage.users;
478
+ packages.push(version);
479
+ } else {
480
+ this.logger.warn({
481
+ package: name
482
+ }, 'package @{package} does not have a "latest" tag?');
483
+ }
484
+ } catch (err) {
485
+ this.logger.error({
486
+ err,
487
+ package: name
488
+ }, 'error reading package @{package}');
489
+ }
490
+ }
491
+ return packages;
492
+ }
493
+
494
+ /**
495
+ * Function fetches package metadata from uplinks and synchronizes it with local data
496
+ if package is available locally, it MUST be provided in pkginfo
497
+ returns callback(err, result, uplink_errors)
498
+ */
499
+ _syncUplinksMetadata(name, packageInfo, options, callback) {
500
+ let found = true;
501
+ const self = this;
502
+ const upLinks = [];
503
+ const hasToLookIntoUplinks = _lodash.default.isNil(options.uplinksLook) || options.uplinksLook;
504
+ if (!packageInfo) {
505
+ found = false;
506
+ packageInfo = (0, _storageUtils.generatePackageTemplate)(name);
507
+ }
508
+ for (const uplink in this.uplinks) {
509
+ if ((0, _config.hasProxyTo)(name, uplink, this.config.packages) && hasToLookIntoUplinks) {
510
+ upLinks.push(this.uplinks[uplink]);
511
+ }
512
+ }
513
+ _async.default.map(upLinks, (upLink, cb) => {
514
+ const _options = Object.assign({}, options);
515
+ const upLinkMeta = packageInfo._uplinks[upLink.upname];
516
+ if ((0, _utils.isObject)(upLinkMeta)) {
517
+ const fetched = upLinkMeta.fetched;
518
+ if (fetched && Date.now() - fetched < upLink.maxage) {
519
+ return cb();
520
+ }
521
+ _options.etag = upLinkMeta.etag;
522
+ }
523
+ upLink.getRemoteMetadata(name, _options, (err, upLinkResponse, eTag) => {
524
+ if (err && err.remoteStatus === 304) {
525
+ upLinkMeta.fetched = Date.now();
526
+ }
527
+ if (err || !upLinkResponse) {
528
+ return cb(null, [err || _utils.ErrorCode.getInternalError('no data')]);
529
+ }
530
+ try {
531
+ upLinkResponse = _core.validationUtils.normalizeMetadata(upLinkResponse, name);
532
+ } catch (err) {
533
+ self.logger.error({
534
+ sub: 'out',
535
+ err: err
536
+ }, 'package.json validating error @{!err.message}\n@{err.stack}');
537
+ return cb(null, [err]);
538
+ }
539
+ packageInfo._uplinks[upLink.upname] = {
540
+ etag: eTag,
541
+ fetched: Date.now()
542
+ };
543
+ packageInfo = (0, _storageUtils.mergeUplinkTimeIntoLocal)(packageInfo, upLinkResponse);
544
+ (0, _uplinkUtil.updateVersionsHiddenUpLink)(upLinkResponse.versions, upLink);
545
+ try {
546
+ (0, _metadataUtils.mergeVersions)(packageInfo, upLinkResponse);
547
+ } catch (err) {
548
+ self.logger.error({
549
+ sub: 'out',
550
+ err: err
551
+ }, 'package.json parsing error @{!err.message}\n@{err.stack}');
552
+ return cb(null, [err]);
553
+ }
554
+
555
+ // if we got to this point, assume that the correct package exists
556
+ // on the uplink
557
+ found = true;
558
+ cb();
559
+ });
560
+ },
561
+ // @ts-ignore
562
+ async (err, upLinksErrors) => {
563
+ (0, _assert.default)(!err && Array.isArray(upLinksErrors));
564
+
565
+ // Check for connection timeout or reset errors with uplink(s)
566
+ // (these should be handled differently from the package not being found)
567
+ if (!found) {
568
+ let uplinkTimeoutError;
569
+ for (let i = 0; i < upLinksErrors.length; i++) {
570
+ if (upLinksErrors[i]) {
571
+ for (let j = 0; j < upLinksErrors[i].length; j++) {
572
+ if (upLinksErrors[i][j]) {
573
+ const code = upLinksErrors[i][j].code;
574
+ if (code === 'ETIMEDOUT' || code === 'ESOCKETTIMEDOUT' || code === 'ECONNRESET') {
575
+ uplinkTimeoutError = true;
576
+ break;
577
+ }
578
+ }
579
+ }
580
+ }
581
+ }
582
+ if (uplinkTimeoutError) {
583
+ return callback(_utils.ErrorCode.getServiceUnavailable(), null, upLinksErrors);
584
+ }
585
+ return callback(_utils.ErrorCode.getNotFound(_constants.API_ERROR.NO_PACKAGE), null, upLinksErrors);
586
+ }
587
+ if (upLinks.length === 0) {
588
+ const {
589
+ filteredPackage,
590
+ filterErrors
591
+ } = await self._applyFilters(packageInfo);
592
+ return callback(null, filteredPackage, filterErrors);
593
+ }
594
+ try {
595
+ const packageJsonLocal = await self.localStorage.updateVersionsAsync(name, packageInfo);
596
+ const {
597
+ filteredPackage,
598
+ filterErrors
599
+ } = await self._applyFilters(packageJsonLocal);
600
+ callback(null, filteredPackage, _lodash.default.concat(upLinksErrors, filterErrors));
601
+ } catch (err) {
602
+ callback(err);
603
+ }
604
+ });
605
+ }
606
+
607
+ /**
608
+ * Apply all configured filter plugins to a package manifest sequentially.
609
+ * Each filter's output is passed as input to the next filter.
610
+ * Returns the filtered manifest and any errors that occurred.
611
+ */
612
+ async _applyFilters(packageInfo) {
613
+ const filterErrors = [];
614
+ let filteredPackage = packageInfo;
615
+ for (const filter of this.filters ?? []) {
616
+ try {
617
+ filteredPackage = await filter.filter_metadata(filteredPackage);
618
+ } catch (err) {
619
+ filterErrors.push(err);
620
+ }
621
+ }
622
+ return {
623
+ filteredPackage,
624
+ filterErrors
625
+ };
626
+ }
627
+
628
+ /**
629
+ * Check if a tarball should be served based on filter plugins.
630
+ * Looks up package metadata, applies filters, and verifies the tarball
631
+ * still belongs to an allowed version.
632
+ */
633
+ async _isTarballAllowedByFilters(name, filename) {
634
+ if (!this.filters?.length) {
635
+ return true;
636
+ }
637
+ try {
638
+ const pkgMetadata = await this.localStorage.getPackageMetadataAsync(name);
639
+ const {
640
+ filteredPackage
641
+ } = await this._applyFilters(pkgMetadata);
642
+ return Object.values(filteredPackage.versions || {}).some(version => version.dist?.tarball?.endsWith('/' + filename));
643
+ } catch (err) {
644
+ if (err?.status === _constants.HTTP_STATUS.NOT_FOUND) {
645
+ // Package not yet cached locally — the request will fall through to uplinks.
646
+ debug('package %o not cached locally, skipping tarball filter check', name);
647
+ } else {
648
+ this.logger.error({
649
+ package: name,
650
+ fileName: filename,
651
+ err
652
+ }, 'error checking filters for tarball @{fileName} of package @{package}: @{err.message}');
653
+ }
654
+ return true;
655
+ }
656
+ }
657
+
658
+ /**
659
+ * Set a hidden value for each version.
660
+ * @param {Array} versions list of version
661
+ * @param {String} upLink uplink name
662
+ * @private
663
+ */
664
+ _updateVersionsHiddenUpLink(versions, upLink) {
665
+ for (const i in versions) {
666
+ if (Object.prototype.hasOwnProperty.call(versions, i)) {
667
+ const version = versions[i];
668
+
669
+ // holds a "hidden" value to be used by the package storage.
670
+ version[Symbol.for('__verdaccio_uplink')] = upLink.upname;
671
+ }
672
+ }
673
+ }
674
+ }
675
+ var _default = exports.default = Storage;
676
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfYXNzZXJ0IiwiX2ludGVyb3BSZXF1aXJlRGVmYXVsdCIsInJlcXVpcmUiLCJfYXN5bmMiLCJfZGVidWciLCJfbG9kYXNoIiwiX3N0cmVhbSIsIl9jb25maWciLCJfY29yZSIsIl9sb2FkZXJzIiwiX2xvY2FsU3RvcmFnZUxlZ2FjeSIsIl9zZWFyY2hJbmRleGVyIiwiX3N0cmVhbXMiLCJfbG9nZ2VyIiwiX2NvbnN0YW50cyIsIl9sb2NhbFN0b3JhZ2UiLCJfbWV0YWRhdGFVdGlscyIsIl9zdG9yYWdlVXRpbHMiLCJfdXBTdG9yYWdlIiwiX3VwbGlua1V0aWwiLCJfdXRpbHMiLCJlIiwiX19lc01vZHVsZSIsImRlZmF1bHQiLCJkZWJ1ZyIsImJ1aWxkRGVidWciLCJTdG9yYWdlIiwiY29uc3RydWN0b3IiLCJjb25maWciLCJ1cGxpbmtzIiwic2V0dXBVcExpbmtzIiwibG9nZ2VyIiwibG9jYWxTdG9yYWdlIiwiaW5pdCIsImZpbHRlcnMiLCJzdG9yYWdlSW5zdGFuY2UiLCJsb2FkU3RvcmFnZSIsIkxvY2FsU3RvcmFnZSIsImdldFNlY3JldCIsImFzeW5jTG9hZFBsdWdpbiIsInBsdWdpbiIsImZpbHRlcl9tZXRhZGF0YSIsInNlcnZlclNldHRpbmdzIiwicGx1Z2luUHJlZml4IiwiUExVR0lOX0NBVEVHT1JZIiwiRklMVEVSIiwibGVuZ3RoIiwibG9hZFN0b3JlUGx1Z2luIiwiXyIsImlzTmlsIiwiYXNzZXJ0Iiwic3RvcmFnZSIsIkxvY2FsRGF0YWJhc2VQbHVnaW4iLCJpbmZvIiwibmFtZSIsInBsdWdpbkNhdGVnb3J5IiwiU1RPUkFHRSIsInBsdWdpbnMiLCJzdG9yZSIsImdldFBhY2thZ2VTdG9yYWdlIiwid2FybiIsImhlYWQiLCJhZGRQYWNrYWdlIiwibWV0YWRhdGEiLCJjYWxsYmFjayIsImNoZWNrUGFja2FnZUxvY2FsIiwiY2hlY2tQYWNrYWdlUmVtb3RlIiwiX2lzQWxsb3dQdWJsaXNoT2ZmbGluZSIsIl9zeW5jVXBsaW5rc01ldGFkYXRhIiwiYmluZCIsInB1Ymxpc2hQYWNrYWdlIiwiZXJyIiwicHVibGlzaCIsImlzQm9vbGVhbiIsImFsbG93X29mZmxpbmUiLCJyZWFkVG9rZW5zIiwiZmlsdGVyIiwic2F2ZVRva2VuIiwidG9rZW4iLCJkZWxldGVUb2tlbiIsInVzZXIiLCJ0b2tlbktleSIsImFkZFZlcnNpb24iLCJ2ZXJzaW9uIiwidGFnIiwibWVyZ2VUYWdzIiwidGFnSGFzaCIsImNoYW5nZVBhY2thZ2UiLCJyZXZpc2lvbiIsInJlbW92ZVBhY2thZ2UiLCJTZWFyY2hNZW1vcnlJbmRleGVyIiwicmVtb3ZlIiwiY2F0Y2giLCJyZWFzb24iLCJlcnJvciIsInJlbW92ZVRhcmJhbGwiLCJmaWxlbmFtZSIsImFkZFRhcmJhbGwiLCJoYXNMb2NhbFRhcmJhbGwiLCJzZWxmIiwiUHJvbWlzZSIsInJlc29sdmUiLCJyZWplY3QiLCJsb2NhbFN0cmVhbSIsImdldFRhcmJhbGwiLCJpc09wZW4iLCJvbiIsInN0YXR1cyIsIkhUVFBfU1RBVFVTIiwiTk9UX0ZPVU5EIiwiYWJvcnQiLCJyZWFkU3RyZWFtIiwiUmVhZFRhcmJhbGwiLCJfaXNUYXJiYWxsQWxsb3dlZEJ5RmlsdGVycyIsInRoZW4iLCJhbGxvd2VkIiwiZW1pdCIsIkVycm9yQ29kZSIsImdldE5vdEZvdW5kIiwiQVBJX0VSUk9SIiwiTk9fUEFDS0FHRSIsImVycjQwNCIsImxvb2t1cEZyb21VcGxpbmtzIiwic3luY0VyciIsInN5bmNJbmZvIiwiX2Rpc3RmaWxlcyIsInNlcnZlRmlsZSIsImdldFBhY2thZ2VNZXRhZGF0YUFzeW5jIiwidiIsInBpcGUiLCJmaWxlIiwidXBsaW5rIiwidXBsaW5rSWQiLCJoYXNQcm94eVRvIiwicGFja2FnZXMiLCJQcm94eVN0b3JhZ2UiLCJ1cmwiLCJjYWNoZSIsIl9hdXRvZ2VuZXJhdGVkIiwic2F2ZXN0cmVhbSIsIm9uX29wZW4iLCJyc3RyZWFtMiIsImZldGNoVGFyYmFsbCIsImRvbmUiLCJmaWxlTmFtZSIsImdldFBhY2thZ2UiLCJvcHRpb25zIiwiZ2V0UGFja2FnZU1ldGFkYXRhIiwiZGF0YSIsIklOVEVSTkFMX0VSUk9SIiwicmVxIiwidXBsaW5rc0xvb2siLCJnZXRQYWNrYWdlU3luVXBMaW5rc0NhbGxiYWNrIiwicmVzdWx0IiwidXBsaW5rRXJyb3JzIiwibm9ybWFsaXplRGlzdFRhZ3MiLCJjbGVhblVwTGlua3NSZWYiLCJrZWVwVXBMaW5rRGF0YSIsIl9hdHRhY2htZW50cyIsImFiYnJldmlhdGVkIiwiY29udmVydEFiYnJldmlhdGVkTWFuaWZlc3QiLCJzZWFyY2giLCJzdGFydGtleSIsInNlYXJjaFN0cmVhbSIsIlN0cmVhbSIsIlBhc3NUaHJvdWdoIiwib2JqZWN0TW9kZSIsImFzeW5jIiwiZWFjaFNlcmllcyIsIk9iamVjdCIsImtleXMiLCJ1cF9uYW1lIiwiY2IiLCJxdWVyeSIsImxvY2FsIiwidW5kZWZpbmVkIiwidXBsaW5rU3RyZWFtIiwiZW5kIiwibG9jYWxTZWFyY2hTdHJlYW0iLCJnZXRMb2NhbERhdGFiYXNlIiwic3RvcmFnZVBsdWdpbiIsImdldCIsImxvY2FscyIsIl9jb2xsZWN0TG9jYWxQYWNrYWdlcyIsInBrZ01ldGFkYXRhIiwiZmlsdGVyZWRQYWNrYWdlIiwiX2FwcGx5RmlsdGVycyIsImxhdGVzdCIsIkRJU1RfVEFHUyIsInZlcnNpb25zIiwidGltZUxpc3QiLCJ0aW1lIiwidXNlcnMiLCJwdXNoIiwicGFja2FnZSIsInBhY2thZ2VJbmZvIiwiZm91bmQiLCJ1cExpbmtzIiwiaGFzVG9Mb29rSW50b1VwbGlua3MiLCJnZW5lcmF0ZVBhY2thZ2VUZW1wbGF0ZSIsIm1hcCIsInVwTGluayIsIl9vcHRpb25zIiwiYXNzaWduIiwidXBMaW5rTWV0YSIsIl91cGxpbmtzIiwidXBuYW1lIiwiaXNPYmplY3QiLCJmZXRjaGVkIiwiRGF0ZSIsIm5vdyIsIm1heGFnZSIsImV0YWciLCJnZXRSZW1vdGVNZXRhZGF0YSIsInVwTGlua1Jlc3BvbnNlIiwiZVRhZyIsInJlbW90ZVN0YXR1cyIsImdldEludGVybmFsRXJyb3IiLCJ2YWxpZGF0aW9uVXRpbHMiLCJub3JtYWxpemVNZXRhZGF0YSIsInN1YiIsIm1lcmdlVXBsaW5rVGltZUludG9Mb2NhbCIsInVwZGF0ZVZlcnNpb25zSGlkZGVuVXBMaW5rIiwibWVyZ2VWZXJzaW9ucyIsInVwTGlua3NFcnJvcnMiLCJBcnJheSIsImlzQXJyYXkiLCJ1cGxpbmtUaW1lb3V0RXJyb3IiLCJpIiwiaiIsImNvZGUiLCJnZXRTZXJ2aWNlVW5hdmFpbGFibGUiLCJmaWx0ZXJFcnJvcnMiLCJwYWNrYWdlSnNvbkxvY2FsIiwidXBkYXRlVmVyc2lvbnNBc3luYyIsImNvbmNhdCIsInZhbHVlcyIsInNvbWUiLCJkaXN0IiwidGFyYmFsbCIsImVuZHNXaXRoIiwiX3VwZGF0ZVZlcnNpb25zSGlkZGVuVXBMaW5rIiwicHJvdG90eXBlIiwiaGFzT3duUHJvcGVydHkiLCJjYWxsIiwiU3ltYm9sIiwiZm9yIiwiX2RlZmF1bHQiLCJleHBvcnRzIl0sInNvdXJjZXMiOlsiLi4vLi4vc3JjL2xpYi9zdG9yYWdlLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBhc3NlcnQgZnJvbSAnYXNzZXJ0JztcbmltcG9ydCBhc3luYyBmcm9tICdhc3luYyc7XG5pbXBvcnQgYnVpbGREZWJ1ZyBmcm9tICdkZWJ1Zyc7XG5pbXBvcnQgXyBmcm9tICdsb2Rhc2gnO1xuaW1wb3J0IFN0cmVhbSBmcm9tICdzdHJlYW0nO1xuXG5pbXBvcnQgeyBoYXNQcm94eVRvIH0gZnJvbSAnQHZlcmRhY2Npby9jb25maWcnO1xuaW1wb3J0IHsgUExVR0lOX0NBVEVHT1JZLCBwbHVnaW5VdGlscywgdmFsaWRhdGlvblV0aWxzIH0gZnJvbSAnQHZlcmRhY2Npby9jb3JlJztcbmltcG9ydCB7IGFzeW5jTG9hZFBsdWdpbiB9IGZyb20gJ0B2ZXJkYWNjaW8vbG9hZGVycyc7XG5pbXBvcnQgTG9jYWxEYXRhYmFzZVBsdWdpbiBmcm9tICdAdmVyZGFjY2lvL2xvY2FsLXN0b3JhZ2UtbGVnYWN5JztcbmltcG9ydCB7IFNlYXJjaE1lbW9yeUluZGV4ZXIgfSBmcm9tICdAdmVyZGFjY2lvL3NlYXJjaC1pbmRleGVyJztcbmltcG9ydCB7IFJlYWRUYXJiYWxsIH0gZnJvbSAnQHZlcmRhY2Npby9zdHJlYW1zJztcbmltcG9ydCB7XG4gIENhbGxiYWNrLFxuICBDb25maWcsXG4gIERpc3RGaWxlLFxuICBMb2dnZXIsXG4gIE1hbmlmZXN0LFxuICBNZXJnZVRhZ3MsXG4gIFZlcnNpb24sXG4gIFZlcnNpb25zLFxufSBmcm9tICdAdmVyZGFjY2lvL3R5cGVzJztcbmltcG9ydCB7IEdlbmVyaWNCb2R5LCBUb2tlbiwgVG9rZW5GaWx0ZXIgfSBmcm9tICdAdmVyZGFjY2lvL3R5cGVzJztcblxuaW1wb3J0IHsgU3RvcmFnZVBsdWdpbkxlZ2FjeSB9IGZyb20gJy4uLy4uL3R5cGVzL2N1c3RvbSc7XG5pbXBvcnQgeyBsb2dnZXIgfSBmcm9tICcuLi9saWIvbG9nZ2VyJztcbmltcG9ydCB7IElQbHVnaW5GaWx0ZXJzLCBJU3luY1VwbGlua3MsIFN0cmluZ1ZhbHVlIH0gZnJvbSAnLi4vdHlwZXMnO1xuaW1wb3J0IHsgQVBJX0VSUk9SLCBESVNUX1RBR1MsIEhUVFBfU1RBVFVTIH0gZnJvbSAnLi9jb25zdGFudHMnO1xuaW1wb3J0IExvY2FsU3RvcmFnZSwgeyBTdG9yYWdlUGx1Z2luIH0gZnJvbSAnLi9sb2NhbC1zdG9yYWdlJztcbmltcG9ydCB7IG1lcmdlVmVyc2lvbnMgfSBmcm9tICcuL21ldGFkYXRhLXV0aWxzJztcbmltcG9ydCB7XG4gIGNoZWNrUGFja2FnZUxvY2FsLFxuICBjaGVja1BhY2thZ2VSZW1vdGUsXG4gIGNsZWFuVXBMaW5rc1JlZixcbiAgY29udmVydEFiYnJldmlhdGVkTWFuaWZlc3QsXG4gIGdlbmVyYXRlUGFja2FnZVRlbXBsYXRlLFxuICBtZXJnZVVwbGlua1RpbWVJbnRvTG9jYWwsXG4gIHB1Ymxpc2hQYWNrYWdlLFxufSBmcm9tICcuL3N0b3JhZ2UtdXRpbHMnO1xuaW1wb3J0IFByb3h5U3RvcmFnZSBmcm9tICcuL3VwLXN0b3JhZ2UnO1xuaW1wb3J0IHsgc2V0dXBVcExpbmtzLCB1cGRhdGVWZXJzaW9uc0hpZGRlblVwTGluayB9IGZyb20gJy4vdXBsaW5rLXV0aWwnO1xuaW1wb3J0IHsgRXJyb3JDb2RlLCBpc09iamVjdCwgbm9ybWFsaXplRGlzdFRhZ3MgfSBmcm9tICcuL3V0aWxzJztcblxuY29uc3QgZGVidWcgPSBidWlsZERlYnVnKCd2ZXJkYWNjaW86c3RvcmFnZScpO1xuXG5jbGFzcyBTdG9yYWdlIHtcbiAgcHVibGljIGxvY2FsU3RvcmFnZTogTG9jYWxTdG9yYWdlO1xuICBwdWJsaWMgY29uZmlnOiBDb25maWc7XG4gIHB1YmxpYyBsb2dnZXI6IExvZ2dlcjtcbiAgcHVibGljIHVwbGlua3M6IFJlY29yZDxzdHJpbmcsIFByb3h5U3RvcmFnZT47XG4gIHB1YmxpYyBmaWx0ZXJzOiBJUGx1Z2luRmlsdGVycyB8IHVuZGVmaW5lZDtcblxuICBwdWJsaWMgY29uc3RydWN0b3IoY29uZmlnOiBDb25maWcpIHtcbiAgICB0aGlzLmNvbmZpZyA9IGNvbmZpZztcbiAgICB0aGlzLnVwbGlua3MgPSBzZXR1cFVwTGlua3MoY29uZmlnKTtcbiAgICB0aGlzLmxvZ2dlciA9IGxvZ2dlcjtcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L2Jhbi10cy1jb21tZW50XG4gICAgLy8gQHRzLWlnbm9yZVxuICAgIHRoaXMubG9jYWxTdG9yYWdlID0gbnVsbDtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBpbml0KGNvbmZpZzogQ29uZmlnLCBmaWx0ZXJzPzogSVBsdWdpbkZpbHRlcnMpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAodGhpcy5sb2NhbFN0b3JhZ2UgPT09IG51bGwpIHtcbiAgICAgIHRoaXMuZmlsdGVycyA9IGZpbHRlcnM7XG4gICAgICBjb25zdCBzdG9yYWdlSW5zdGFuY2UgPSBhd2FpdCB0aGlzLmxvYWRTdG9yYWdlKGNvbmZpZywgdGhpcy5sb2dnZXIpO1xuICAgICAgdGhpcy5sb2NhbFN0b3JhZ2UgPSBuZXcgTG9jYWxTdG9yYWdlKHRoaXMuY29uZmlnLCBsb2dnZXIsIHN0b3JhZ2VJbnN0YW5jZSk7XG4gICAgICBhd2FpdCB0aGlzLmxvY2FsU3RvcmFnZS5nZXRTZWNyZXQoY29uZmlnKTtcbiAgICAgIGRlYnVnKCdpbml0aWFsaXphdGlvbiBjb21wbGV0ZWQnKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZGVidWcoJ3N0b3JhZ2UgaGFzIGJlZW4gYWxyZWFkeSBpbml0aWFsaXplZCcpO1xuICAgIH1cblxuICAgIGlmICghdGhpcy5maWx0ZXJzKSB7XG4gICAgICB0aGlzLmZpbHRlcnMgPSBhd2FpdCBhc3luY0xvYWRQbHVnaW48cGx1Z2luVXRpbHMuTWFuaWZlc3RGaWx0ZXI8dW5rbm93bj4+KFxuICAgICAgICB0aGlzLmNvbmZpZy5maWx0ZXJzLFxuICAgICAgICB7XG4gICAgICAgICAgY29uZmlnOiB0aGlzLmNvbmZpZyxcbiAgICAgICAgICBsb2dnZXI6IHRoaXMubG9nZ2VyLFxuICAgICAgICB9LFxuICAgICAgICAocGx1Z2luOiBwbHVnaW5VdGlscy5NYW5pZmVzdEZpbHRlcjxDb25maWc+KSA9PiB7XG4gICAgICAgICAgcmV0dXJuIHR5cGVvZiBwbHVnaW4uZmlsdGVyX21ldGFkYXRhICE9PSAndW5kZWZpbmVkJztcbiAgICAgICAgfSxcbiAgICAgICAgdHJ1ZSxcbiAgICAgICAgdGhpcy5jb25maWc/LnNlcnZlclNldHRpbmdzPy5wbHVnaW5QcmVmaXgsXG4gICAgICAgIFBMVUdJTl9DQVRFR09SWS5GSUxURVJcbiAgICAgICk7XG4gICAgICBkZWJ1ZygnZmlsdGVycyBhdmFpbGFibGUgJW8nLCB0aGlzLmZpbHRlcnMubGVuZ3RoKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGxvYWRTdG9yYWdlKGNvbmZpZzogQ29uZmlnLCBsb2dnZXI6IExvZ2dlcik6IFByb21pc2U8U3RvcmFnZVBsdWdpbj4ge1xuICAgIGNvbnN0IFN0b3JhZ2UgPSBhd2FpdCB0aGlzLmxvYWRTdG9yZVBsdWdpbigpO1xuICAgIGlmIChfLmlzTmlsKFN0b3JhZ2UpKSB7XG4gICAgICBhc3NlcnQodGhpcy5jb25maWcuc3RvcmFnZSwgJ0NPTkZJRzogc3RvcmFnZSBwYXRoIG5vdCBkZWZpbmVkJyk7XG4gICAgICBkZWJ1Zygnbm8gY3VzdG9tIHN0b3JhZ2UgZm91bmQsIGxvYWRpbmcgZGVmYXVsdCBzdG9yYWdlIEB2ZXJkYWNjaW8vbG9jYWwtc3RvcmFnZScpO1xuICAgICAgY29uc3QgbG9jYWxTdG9yYWdlID0gbmV3IExvY2FsRGF0YWJhc2VQbHVnaW4oY29uZmlnLCBsb2dnZXIpO1xuICAgICAgbG9nZ2VyLmluZm8oXG4gICAgICAgIHsgbmFtZTogJ0B2ZXJkYWNjaW8vbG9jYWwtc3RvcmFnZScsIHBsdWdpbkNhdGVnb3J5OiBQTFVHSU5fQ0FURUdPUlkuU1RPUkFHRSB9LFxuICAgICAgICAncGx1Z2luIEB7bmFtZX0gc3VjY2Vzc2Z1bGx5IGxvYWRlZCAoQHtwbHVnaW5DYXRlZ29yeX0pJ1xuICAgICAgKTtcbiAgICAgIHJldHVybiBsb2NhbFN0b3JhZ2U7XG4gICAgfVxuICAgIHJldHVybiBTdG9yYWdlIGFzIFN0b3JhZ2VQbHVnaW47XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGxvYWRTdG9yZVBsdWdpbigpOiBQcm9taXNlPFN0b3JhZ2VQbHVnaW5MZWdhY3k8Q29uZmlnPiB8IHVuZGVmaW5lZD4ge1xuICAgIGNvbnN0IHBsdWdpbnM6IFN0b3JhZ2VQbHVnaW5MZWdhY3k8Q29uZmlnPltdID0gYXdhaXQgYXN5bmNMb2FkUGx1Z2luPFxuICAgICAgcGx1Z2luVXRpbHMuU3RvcmFnZTx1bmtub3duPlxuICAgID4oXG4gICAgICB0aGlzLmNvbmZpZy5zdG9yZSxcbiAgICAgIHtcbiAgICAgICAgY29uZmlnOiB0aGlzLmNvbmZpZyxcbiAgICAgICAgbG9nZ2VyOiB0aGlzLmxvZ2dlcixcbiAgICAgIH0sXG4gICAgICAocGx1Z2luKSA9PiB7XG4gICAgICAgIHJldHVybiB0eXBlb2YgcGx1Z2luLmdldFBhY2thZ2VTdG9yYWdlICE9PSAndW5kZWZpbmVkJztcbiAgICAgIH0sXG4gICAgICB0cnVlLFxuICAgICAgdGhpcy5jb25maWc/LnNlcnZlclNldHRpbmdzPy5wbHVnaW5QcmVmaXgsXG4gICAgICBQTFVHSU5fQ0FURUdPUlkuU1RPUkFHRVxuICAgICk7XG5cbiAgICBpZiAocGx1Z2lucy5sZW5ndGggPiAxKSB7XG4gICAgICB0aGlzLmxvZ2dlci53YXJuKFxuICAgICAgICAnbW9yZSB0aGFuIG9uZSBzdG9yYWdlIHBsdWdpbnMgaGFzIGJlZW4gZGV0ZWN0ZWQsIG11bHRpcGxlIHN0b3JhZ2UgYXJlIG5vdCBzdXBwb3J0ZWQsIG9uZSB3aWxsIGJlIHNlbGVjdGVkIGF1dG9tYXRpY2FsbHknXG4gICAgICApO1xuICAgIH1cblxuICAgIHJldHVybiBfLmhlYWQocGx1Z2lucyk7XG4gIH1cblxuICAvKipcbiAgICogIEFkZCBhIHtuYW1lfSBwYWNrYWdlIHRvIGEgc3lzdGVtXG4gICBGdW5jdGlvbiBjaGVja3MgaWYgcGFja2FnZSB3aXRoIHRoZSBzYW1lIG5hbWUgaXMgYXZhaWxhYmxlIGZyb20gdXBsaW5rcy5cbiAgIElmIGl0IGlzbid0LCB3ZSBjcmVhdGUgcGFja2FnZSBsb2NhbGx5XG4gICBVc2VkIHN0b3JhZ2VzOiBsb2NhbCAod3JpdGUpICYmIHVwbGlua3NcbiAgICovXG4gIHB1YmxpYyBhc3luYyBhZGRQYWNrYWdlKG5hbWU6IHN0cmluZywgbWV0YWRhdGE6IGFueSwgY2FsbGJhY2s6IGFueSk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCBjaGVja1BhY2thZ2VMb2NhbChuYW1lLCB0aGlzLmxvY2FsU3RvcmFnZSk7XG4gICAgICBhd2FpdCBjaGVja1BhY2thZ2VSZW1vdGUoXG4gICAgICAgIG5hbWUsXG4gICAgICAgIHRoaXMuX2lzQWxsb3dQdWJsaXNoT2ZmbGluZSgpLFxuICAgICAgICB0aGlzLl9zeW5jVXBsaW5rc01ldGFkYXRhLmJpbmQodGhpcylcbiAgICAgICk7XG4gICAgICBhd2FpdCBwdWJsaXNoUGFja2FnZShuYW1lLCBtZXRhZGF0YSwgdGhpcy5sb2NhbFN0b3JhZ2UpO1xuICAgICAgY2FsbGJhY2soKTtcbiAgICB9IGNhdGNoIChlcnI6IGFueSkge1xuICAgICAgY2FsbGJhY2soZXJyKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIF9pc0FsbG93UHVibGlzaE9mZmxpbmUoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIChcbiAgICAgIHR5cGVvZiB0aGlzLmNvbmZpZy5wdWJsaXNoICE9PSAndW5kZWZpbmVkJyAmJlxuICAgICAgXy5pc0Jvb2xlYW4odGhpcy5jb25maWcucHVibGlzaC5hbGxvd19vZmZsaW5lKSAmJlxuICAgICAgdGhpcy5jb25maWcucHVibGlzaC5hbGxvd19vZmZsaW5lXG4gICAgKTtcbiAgfVxuXG4gIHB1YmxpYyByZWFkVG9rZW5zKGZpbHRlcjogVG9rZW5GaWx0ZXIpOiBQcm9taXNlPFRva2VuW10+IHtcbiAgICByZXR1cm4gdGhpcy5sb2NhbFN0b3JhZ2UucmVhZFRva2VucyhmaWx0ZXIpO1xuICB9XG5cbiAgcHVibGljIHNhdmVUb2tlbih0b2tlbjogVG9rZW4pOiBQcm9taXNlPHZvaWQ+IHtcbiAgICByZXR1cm4gdGhpcy5sb2NhbFN0b3JhZ2Uuc2F2ZVRva2VuKHRva2VuKTtcbiAgfVxuXG4gIHB1YmxpYyBkZWxldGVUb2tlbih1c2VyOiBzdHJpbmcsIHRva2VuS2V5OiBzdHJpbmcpOiBQcm9taXNlPGFueT4ge1xuICAgIHJldHVybiB0aGlzLmxvY2FsU3RvcmFnZS5kZWxldGVUb2tlbih1c2VyLCB0b2tlbktleSk7XG4gIH1cblxuICAvKipcbiAgICogQWRkIGEgbmV3IHZlcnNpb24gb2YgcGFja2FnZSB7bmFtZX0gdG8gYSBzeXN0ZW1cbiAgIFVzZWQgc3RvcmFnZXM6IGxvY2FsICh3cml0ZSlcbiAgICovXG4gIHB1YmxpYyBhZGRWZXJzaW9uKFxuICAgIG5hbWU6IHN0cmluZyxcbiAgICB2ZXJzaW9uOiBzdHJpbmcsXG4gICAgbWV0YWRhdGE6IFZlcnNpb24sXG4gICAgdGFnOiBTdHJpbmdWYWx1ZSxcbiAgICBjYWxsYmFjazogQ2FsbGJhY2tcbiAgKTogdm9pZCB7XG4gICAgdGhpcy5sb2NhbFN0b3JhZ2UuYWRkVmVyc2lvbihuYW1lLCB2ZXJzaW9uLCBtZXRhZGF0YSwgdGFnLCBjYWxsYmFjayk7XG4gIH1cblxuICAvKipcbiAgICogVGFncyBhIHBhY2thZ2UgdmVyc2lvbiB3aXRoIGEgcHJvdmlkZWQgdGFnXG4gICBVc2VkIHN0b3JhZ2VzOiBsb2NhbCAod3JpdGUpXG4gICAqL1xuICBwdWJsaWMgbWVyZ2VUYWdzKG5hbWU6IHN0cmluZywgdGFnSGFzaDogTWVyZ2VUYWdzLCBjYWxsYmFjazogQ2FsbGJhY2spOiB2b2lkIHtcbiAgICB0aGlzLmxvY2FsU3RvcmFnZS5tZXJnZVRhZ3MobmFtZSwgdGFnSGFzaCwgY2FsbGJhY2spO1xuICB9XG5cbiAgLyoqXG4gICAqIENoYW5nZSBhbiBleGlzdGluZyBwYWNrYWdlIChpLmUuIHVucHVibGlzaCBvbmUgdmVyc2lvbilcbiAgIEZ1bmN0aW9uIGNoYW5nZXMgYSBwYWNrYWdlIGluZm8gZnJvbSBsb2NhbCBzdG9yYWdlIGFuZCBhbGwgdXBsaW5rcyB3aXRoIHdyaXRlIGFjY2Vzcy4vXG4gICBVc2VkIHN0b3JhZ2VzOiBsb2NhbCAod3JpdGUpXG4gICAqL1xuICBwdWJsaWMgY2hhbmdlUGFja2FnZShcbiAgICBuYW1lOiBzdHJpbmcsXG4gICAgbWV0YWRhdGE6IE1hbmlmZXN0LFxuICAgIHJldmlzaW9uOiBzdHJpbmcsXG4gICAgY2FsbGJhY2s6IENhbGxiYWNrXG4gICk6IHZvaWQge1xuICAgIHRoaXMubG9jYWxTdG9yYWdlLmNoYW5nZVBhY2thZ2UobmFtZSwgbWV0YWRhdGEsIHJldmlzaW9uLCBjYWxsYmFjayk7XG4gIH1cblxuICAvKipcbiAgICogUmVtb3ZlIGEgcGFja2FnZSBmcm9tIGEgc3lzdGVtXG4gICBGdW5jdGlvbiByZW1vdmVzIGEgcGFja2FnZSBmcm9tIGxvY2FsIHN0b3JhZ2VcbiAgIFVzZWQgc3RvcmFnZXM6IGxvY2FsICh3cml0ZSlcbiAgICovXG4gIHB1YmxpYyByZW1vdmVQYWNrYWdlKG5hbWU6IHN0cmluZywgY2FsbGJhY2s6IENhbGxiYWNrKTogdm9pZCB7XG4gICAgdGhpcy5sb2NhbFN0b3JhZ2UucmVtb3ZlUGFja2FnZShuYW1lLCBjYWxsYmFjayk7XG4gICAgLy8gdXBkYXRlIHRoZSBpbmRleGVyXG4gICAgU2VhcmNoTWVtb3J5SW5kZXhlci5yZW1vdmUobmFtZSkuY2F0Y2goKHJlYXNvbikgPT4ge1xuICAgICAgZGVidWcoJ2luZGV4ZXIgaGFzIGZhaWxlZCBvbiByZW1vdmUgaXRlbSAlbycsIHJlYXNvbik7XG4gICAgICBsb2dnZXIuZXJyb3IoJ2luZGV4ZXIgaGFzIGZhaWxlZCBvbiByZW1vdmUgaXRlbScpO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICBSZW1vdmUgYSB0YXJiYWxsIGZyb20gYSBzeXN0ZW1cbiAgIEZ1bmN0aW9uIHJlbW92ZXMgYSB0YXJiYWxsIGZyb20gbG9jYWwgc3RvcmFnZS5cbiAgIFRhcmJhbGwgaW4gcXVlc3Rpb24gc2hvdWxkIG5vdCBiZSBsaW5rZWQgdG8gaW4gYW55IGV4aXN0aW5nXG4gICB2ZXJzaW9ucywgaS5lLiBwYWNrYWdlIHZlcnNpb24gc2hvdWxkIGJlIHVucHVibGlzaGVkIGZpcnN0LlxuICAgVXNlZCBzdG9yYWdlOiBsb2NhbCAod3JpdGUpXG4gICAqL1xuICBwdWJsaWMgcmVtb3ZlVGFyYmFsbChuYW1lOiBzdHJpbmcsIGZpbGVuYW1lOiBzdHJpbmcsIHJldmlzaW9uOiBzdHJpbmcsIGNhbGxiYWNrOiBDYWxsYmFjayk6IHZvaWQge1xuICAgIHRoaXMubG9jYWxTdG9yYWdlLnJlbW92ZVRhcmJhbGwobmFtZSwgZmlsZW5hbWUsIHJldmlzaW9uLCBjYWxsYmFjayk7XG4gIH1cblxuICAvKipcbiAgICogVXBsb2FkIGEgdGFyYmFsbCBmb3Ige25hbWV9IHBhY2thZ2VcbiAgIEZ1bmN0aW9uIGlzIHN5bmNocm9ub3VzIGFuZCByZXR1cm5zIGEgV3JpdGFibGVTdHJlYW1cbiAgIFVzZWQgc3RvcmFnZXM6IGxvY2FsICh3cml0ZSlcbiAgICovXG4gIHB1YmxpYyBhZGRUYXJiYWxsKG5hbWU6IHN0cmluZywgZmlsZW5hbWU6IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLmxvY2FsU3RvcmFnZS5hZGRUYXJiYWxsKG5hbWUsIGZpbGVuYW1lKTtcbiAgfVxuXG4gIHB1YmxpYyBoYXNMb2NhbFRhcmJhbGwobmFtZTogc3RyaW5nLCBmaWxlbmFtZTogc3RyaW5nKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgY29uc3Qgc2VsZiA9IHRoaXM7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlPGJvb2xlYW4+KChyZXNvbHZlLCByZWplY3QpOiB2b2lkID0+IHtcbiAgICAgIGxldCBsb2NhbFN0cmVhbTogYW55ID0gc2VsZi5sb2NhbFN0b3JhZ2UuZ2V0VGFyYmFsbChuYW1lLCBmaWxlbmFtZSk7XG4gICAgICBsZXQgaXNPcGVuID0gZmFsc2U7XG4gICAgICBsb2NhbFN0cmVhbS5vbignZXJyb3InLCAoZXJyKTogYW55ID0+IHtcbiAgICAgICAgaWYgKGlzT3BlbiB8fCBlcnIuc3RhdHVzICE9PSBIVFRQX1NUQVRVUy5OT1RfRk9VTkQpIHtcbiAgICAgICAgICByZWplY3QoZXJyKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBsb2NhbCByZXBvcnRlZCA0MDQgb3IgcmVxdWVzdCB3YXMgYWJvcnRlZCBhbHJlYWR5XG4gICAgICAgIGlmIChsb2NhbFN0cmVhbSkge1xuICAgICAgICAgIGxvY2FsU3RyZWFtLmFib3J0KCk7XG4gICAgICAgICAgbG9jYWxTdHJlYW0gPSBudWxsO1xuICAgICAgICB9XG4gICAgICAgIHJlc29sdmUoZmFsc2UpO1xuICAgICAgfSk7XG4gICAgICBsb2NhbFN0cmVhbS5vbignb3BlbicsIGZ1bmN0aW9uICgpOiB2b2lkIHtcbiAgICAgICAgaXNPcGVuID0gdHJ1ZTtcbiAgICAgICAgbG9jYWxTdHJlYW0uYWJvcnQoKTtcbiAgICAgICAgbG9jYWxTdHJlYW0gPSBudWxsO1xuICAgICAgICByZXNvbHZlKHRydWUpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgIEdldCBhIHRhcmJhbGwgZnJvbSBhIHN0b3JhZ2UgZm9yIHtuYW1lfSBwYWNrYWdlXG4gICBGdW5jdGlvbiBpcyBzeW5jaHJvbm91cyBhbmQgcmV0dXJucyBhIFJlYWRhYmxlU3RyZWFtXG4gICBGdW5jdGlvbiB0cmllcyB0byByZWFkIHRhcmJhbGwgbG9jYWxseSwgaWYgaXQgZmFpbHMgdGhlbiBpdCByZWFkcyBwYWNrYWdlXG4gICBpbmZvcm1hdGlvbiBpbiBvcmRlciB0byBmaWd1cmUgb3V0IHdoZXJlIHdlIGNhbiBnZXQgdGhpcyB0YXJiYWxsIGZyb21cbiAgIFVzZWQgc3RvcmFnZXM6IGxvY2FsIHx8IHVwbGluayAoanVzdCBvbmUpXG4gICAqL1xuICBwdWJsaWMgZ2V0VGFyYmFsbChuYW1lOiBzdHJpbmcsIGZpbGVuYW1lOiBzdHJpbmcpIHtcbiAgICBjb25zdCByZWFkU3RyZWFtID0gbmV3IFJlYWRUYXJiYWxsKHt9KTtcbiAgICByZWFkU3RyZWFtLmFib3J0ID0gZnVuY3Rpb24gKCkge307XG5cbiAgICBjb25zdCBzZWxmID0gdGhpcztcblxuICAgIC8vIENoZWNrIGlmIHRoZSB0YXJiYWxsIGlzIGFsbG93ZWQgYnkgZmlsdGVyIHBsdWdpbnMgYmVmb3JlIHNlcnZpbmcuXG4gICAgLy8gRmlsdGVycyBtYXkgYmxvY2sgc3BlY2lmaWMgdmVyc2lvbnMsIHNvIHdlIHZlcmlmeSB0aGUgdGFyYmFsbCdzIHZlcnNpb25cbiAgICAvLyBzdGlsbCBleGlzdHMgaW4gdGhlIGZpbHRlcmVkIG1ldGFkYXRhLlxuICAgIHRoaXMuX2lzVGFyYmFsbEFsbG93ZWRCeUZpbHRlcnMobmFtZSwgZmlsZW5hbWUpLnRoZW4oYXN5bmMgKGFsbG93ZWQpID0+IHtcbiAgICAgIGlmICghYWxsb3dlZCkge1xuICAgICAgICByZWFkU3RyZWFtLmVtaXQoJ2Vycm9yJywgRXJyb3JDb2RlLmdldE5vdEZvdW5kKEFQSV9FUlJPUi5OT19QQUNLQUdFKSk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgLy8gdHJ5aW5nIGxvY2FsIGZpcnN0XG4gICAgICBsZXQgbG9jYWxTdHJlYW06IGFueSA9IHNlbGYubG9jYWxTdG9yYWdlLmdldFRhcmJhbGwobmFtZSwgZmlsZW5hbWUpO1xuICAgICAgbGV0IGlzT3BlbiA9IGZhbHNlO1xuICAgICAgbG9jYWxTdHJlYW0ub24oJ2Vycm9yJywgKGVycik6IGFueSA9PiB7XG4gICAgICAgIGlmIChpc09wZW4gfHwgZXJyLnN0YXR1cyAhPT0gSFRUUF9TVEFUVVMuTk9UX0ZPVU5EKSB7XG4gICAgICAgICAgcmV0dXJuIHJlYWRTdHJlYW0uZW1pdCgnZXJyb3InLCBlcnIpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gbG9jYWwgcmVwb3J0ZWQgNDA0XG4gICAgICAgIGNvbnN0IGVycjQwNCA9IGVycjtcbiAgICAgICAgbG9jYWxTdHJlYW0uYWJvcnQoKTtcbiAgICAgICAgbG9jYWxTdHJlYW0gPSBudWxsOyAvLyB3ZSBmb3JjZSBmb3IgZ2FyYmFnZSBjb2xsZWN0b3JcblxuICAgICAgICBjb25zdCBsb29rdXBGcm9tVXBsaW5rcyA9IChpbmZvOiBNYW5pZmVzdCB8IG51bGwpOiB2b2lkID0+IHtcbiAgICAgICAgICBzZWxmLl9zeW5jVXBsaW5rc01ldGFkYXRhKFxuICAgICAgICAgICAgbmFtZSxcbiAgICAgICAgICAgIGluZm8gYXMgTWFuaWZlc3QsXG4gICAgICAgICAgICB7fSxcbiAgICAgICAgICAgIChzeW5jRXJyLCBzeW5jSW5mbzogTWFuaWZlc3QpOiBhbnkgPT4ge1xuICAgICAgICAgICAgICBpZiAoXy5pc05pbChzeW5jRXJyKSA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVhZFN0cmVhbS5lbWl0KCdlcnJvcicsIHN5bmNFcnIpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGlmIChfLmlzTmlsKHN5bmNJbmZvLl9kaXN0ZmlsZXMpIHx8IF8uaXNOaWwoc3luY0luZm8uX2Rpc3RmaWxlc1tmaWxlbmFtZV0pKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlYWRTdHJlYW0uZW1pdCgnZXJyb3InLCBlcnI0MDQpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHNlcnZlRmlsZShzeW5jSW5mby5fZGlzdGZpbGVzW2ZpbGVuYW1lXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgKTtcbiAgICAgICAgfTtcblxuICAgICAgICBzZWxmLmxvY2FsU3RvcmFnZS5nZXRQYWNrYWdlTWV0YWRhdGFBc3luYyhuYW1lKS50aGVuKFxuICAgICAgICAgIChpbmZvKSA9PiB7XG4gICAgICAgICAgICBpZiAoaW5mby5fZGlzdGZpbGVzICYmIF8uaXNOaWwoaW5mby5fZGlzdGZpbGVzW2ZpbGVuYW1lXSkgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICAgIC8vIGluZm9ybWF0aW9uIGFib3V0IHRoaXMgZmlsZSBleGlzdHMgbG9jYWxseVxuICAgICAgICAgICAgICBzZXJ2ZUZpbGUoaW5mby5fZGlzdGZpbGVzW2ZpbGVuYW1lXSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAvLyB3ZSBrbm93IG5vdGhpbmcgYWJvdXQgdGhpcyBmaWxlLCB0cnlpbmcgdG8gZ2V0IGluZm9ybWF0aW9uIGVsc2V3aGVyZVxuICAgICAgICAgICAgICBsb29rdXBGcm9tVXBsaW5rcyhpbmZvKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9LFxuICAgICAgICAgICgpID0+IHtcbiAgICAgICAgICAgIC8vIHdlIGtub3cgbm90aGluZyBhYm91dCB0aGlzIGZpbGUsIHRyeWluZyB0byBnZXQgaW5mb3JtYXRpb24gZWxzZXdoZXJlXG4gICAgICAgICAgICBsb29rdXBGcm9tVXBsaW5rcyhudWxsKTtcbiAgICAgICAgICB9XG4gICAgICAgICk7XG4gICAgICB9KTtcbiAgICAgIGxvY2FsU3RyZWFtLm9uKCdjb250ZW50LWxlbmd0aCcsIGZ1bmN0aW9uICh2KTogdm9pZCB7XG4gICAgICAgIHJlYWRTdHJlYW0uZW1pdCgnY29udGVudC1sZW5ndGgnLCB2KTtcbiAgICAgIH0pO1xuICAgICAgbG9jYWxTdHJlYW0ub24oJ29wZW4nLCBmdW5jdGlvbiAoKTogdm9pZCB7XG4gICAgICAgIGlzT3BlbiA9IHRydWU7XG4gICAgICAgIGxvY2FsU3RyZWFtLnBpcGUocmVhZFN0cmVhbSk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIHJldHVybiByZWFkU3RyZWFtO1xuXG4gICAgLyoqXG4gICAgICogRmV0Y2ggYW5kIGNhY2hlIGxvY2FsL3JlbW90ZSBwYWNrYWdlcy5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gZmlsZSBkZWZpbmUgdGhlIHBhY2thZ2Ugc2hhcGVcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBzZXJ2ZUZpbGUoZmlsZTogRGlzdEZpbGUpOiB2b2lkIHtcbiAgICAgIGxldCB1cGxpbms6IGFueSA9IG51bGw7XG5cbiAgICAgIGZvciAoY29uc3QgdXBsaW5rSWQgaW4gc2VsZi51cGxpbmtzKSB7XG4gICAgICAgIGlmIChoYXNQcm94eVRvKG5hbWUsIHVwbGlua0lkLCBzZWxmLmNvbmZpZy5wYWNrYWdlcykpIHtcbiAgICAgICAgICB1cGxpbmsgPSBzZWxmLnVwbGlua3NbdXBsaW5rSWRdO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmICh1cGxpbmsgPT0gbnVsbCkge1xuICAgICAgICB1cGxpbmsgPSBuZXcgUHJveHlTdG9yYWdlKFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIHVybDogZmlsZS51cmwsXG4gICAgICAgICAgICBjYWNoZTogdHJ1ZSxcbiAgICAgICAgICAgIF9hdXRvZ2VuZXJhdGVkOiB0cnVlLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgc2VsZi5jb25maWdcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgbGV0IHNhdmVzdHJlYW06IGFueSA9IG51bGw7XG4gICAgICBpZiAodXBsaW5rLmNvbmZpZy5jYWNoZSkge1xuICAgICAgICBzYXZlc3RyZWFtID0gc2VsZi5sb2NhbFN0b3JhZ2UuYWRkVGFyYmFsbChuYW1lLCBmaWxlbmFtZSk7XG4gICAgICB9XG5cbiAgICAgIGxldCBvbl9vcGVuID0gZnVuY3Rpb24gKCk6IHZvaWQge1xuICAgICAgICAvLyBwcmV2ZW50IGl0IGZyb20gYmVpbmcgY2FsbGVkIHR3aWNlXG4gICAgICAgIG9uX29wZW4gPSBmdW5jdGlvbiAoKSB7fTtcbiAgICAgICAgY29uc3QgcnN0cmVhbTIgPSB1cGxpbmsuZmV0Y2hUYXJiYWxsKGZpbGUudXJsKTtcbiAgICAgICAgcnN0cmVhbTIub24oJ2Vycm9yJywgZnVuY3Rpb24gKGVycik6IHZvaWQge1xuICAgICAgICAgIGlmIChzYXZlc3RyZWFtKSB7XG4gICAgICAgICAgICBzYXZlc3RyZWFtLmFib3J0KCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHNhdmVzdHJlYW0gPSBudWxsO1xuICAgICAgICAgIHJlYWRTdHJlYW0uZW1pdCgnZXJyb3InLCBlcnIpO1xuICAgICAgICB9KTtcbiAgICAgICAgcnN0cmVhbTIub24oJ2VuZCcsIGZ1bmN0aW9uICgpOiB2b2lkIHtcbiAgICAgICAgICBpZiAoc2F2ZXN0cmVhbSkge1xuICAgICAgICAgICAgc2F2ZXN0cmVhbS5kb25lKCk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICByc3RyZWFtMi5vbignY29udGVudC1sZW5ndGgnLCBmdW5jdGlvbiAodik6IHZvaWQge1xuICAgICAgICAgIHJlYWRTdHJlYW0uZW1pdCgnY29udGVudC1sZW5ndGgnLCB2KTtcbiAgICAgICAgICBpZiAoc2F2ZXN0cmVhbSkge1xuICAgICAgICAgICAgc2F2ZXN0cmVhbS5lbWl0KCdjb250ZW50LWxlbmd0aCcsIHYpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHJzdHJlYW0yLnBpcGUocmVhZFN0cmVhbSk7XG4gICAgICAgIGlmIChzYXZlc3RyZWFtKSB7XG4gICAgICAgICAgcnN0cmVhbTIucGlwZShzYXZlc3RyZWFtKTtcbiAgICAgICAgfVxuICAgICAgfTtcblxuICAgICAgaWYgKHNhdmVzdHJlYW0pIHtcbiAgICAgICAgc2F2ZXN0cmVhbS5vbignb3BlbicsIGZ1bmN0aW9uICgpOiB2b2lkIHtcbiAgICAgICAgICBvbl9vcGVuKCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHNhdmVzdHJlYW0ub24oJ2Vycm9yJywgZnVuY3Rpb24gKGVycik6IHZvaWQge1xuICAgICAgICAgIHNlbGYubG9nZ2VyLndhcm4oXG4gICAgICAgICAgICB7IGVycjogZXJyLCBmaWxlTmFtZTogZmlsZSB9LFxuICAgICAgICAgICAgJ2Vycm9yIHNhdmluZyBmaWxlIEB7ZmlsZU5hbWV9OiBAe2Vyci5tZXNzYWdlfVxcbkB7ZXJyLnN0YWNrfSdcbiAgICAgICAgICApO1xuICAgICAgICAgIGlmIChzYXZlc3RyZWFtKSB7XG4gICAgICAgICAgICBzYXZlc3RyZWFtLmFib3J0KCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHNhdmVzdHJlYW0gPSBudWxsO1xuICAgICAgICAgIG9uX29wZW4oKTtcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBvbl9vcGVuKCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICBSZXRyaWV2ZSBhIHBhY2thZ2UgbWV0YWRhdGEgZm9yIHtuYW1lfSBwYWNrYWdlXG4gICBGdW5jdGlvbiBpbnZva2VzIGxvY2FsU3RvcmFnZS5nZXRQYWNrYWdlIGFuZCB1cGxpbmsuZ2V0X3BhY2thZ2UgZm9yIGV2ZXJ5XG4gICB1cGxpbmsgd2l0aCBwcm94eV9hY2Nlc3MgcmlnaHRzIGFnYWluc3Qge25hbWV9IGFuZCBjb21iaW5lcyByZXN1bHRzXG4gICBpbnRvIG9uZSBqc29uIG9iamVjdFxuICAgVXNlZCBzdG9yYWdlczogbG9jYWwgJiYgdXBsaW5rIChwcm94eV9hY2Nlc3MpXG5cbiAgICogQHBhcmFtIHtvYmplY3R9IG9wdGlvbnNcbiAgICogQHByb3BlcnR5IHtzdHJpbmd9IG9wdGlvbnMubmFtZSBQYWNrYWdlIE5hbWVcbiAgICogQHByb3BlcnR5IHtvYmplY3R9ICBvcHRpb25zLnJlcSBFeHByZXNzIGByZXFgIG9iamVjdFxuICAgKiBAcHJvcGVydHkge2Jvb2xlYW59IG9wdGlvbnMua2VlcFVwTGlua0RhdGEga2VlcCB1cCBsaW5rIGluZm8gaW4gcGFja2FnZSBtZXRhLCBsYXN0IHVwZGF0ZSwgZXRjLlxuICAgKiBAcHJvcGVydHkge2Z1bmN0aW9ufSBvcHRpb25zLmNhbGxiYWNrIENhbGxiYWNrIGZvciByZWNlaXZlIGRhdGFcbiAgICovXG4gIHB1YmxpYyBnZXRQYWNrYWdlKG9wdGlvbnMpOiB2b2lkIHtcbiAgICB0aGlzLmxvY2FsU3RvcmFnZS5nZXRQYWNrYWdlTWV0YWRhdGEob3B0aW9ucy5uYW1lLCAoZXJyLCBkYXRhKTogdm9pZCA9PiB7XG4gICAgICBpZiAoZXJyICYmICghZXJyLnN0YXR1cyB8fCBlcnIuc3RhdHVzID49IEhUVFBfU1RBVFVTLklOVEVSTkFMX0VSUk9SKSkge1xuICAgICAgICAvLyByZXBvcnQgaW50ZXJuYWwgZXJyb3JzIHJpZ2h0IGF3YXlcbiAgICAgICAgcmV0dXJuIG9wdGlvbnMuY2FsbGJhY2soZXJyKTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5fc3luY1VwbGlua3NNZXRhZGF0YShcbiAgICAgICAgb3B0aW9ucy5uYW1lLFxuICAgICAgICBkYXRhLFxuICAgICAgICB7IHJlcTogb3B0aW9ucy5yZXEsIHVwbGlua3NMb29rOiBvcHRpb25zLnVwbGlua3NMb29rIH0sXG4gICAgICAgIGZ1bmN0aW9uIGdldFBhY2thZ2VTeW5VcExpbmtzQ2FsbGJhY2soZXJyLCByZXN1bHQ6IE1hbmlmZXN0LCB1cGxpbmtFcnJvcnMpOiB2b2lkIHtcbiAgICAgICAgICBpZiAoZXJyKSB7XG4gICAgICAgICAgICByZXR1cm4gb3B0aW9ucy5jYWxsYmFjayhlcnIpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIG5vcm1hbGl6ZURpc3RUYWdzKGNsZWFuVXBMaW5rc1JlZihvcHRpb25zLmtlZXBVcExpbmtEYXRhLCByZXN1bHQpKTtcblxuICAgICAgICAgIC8vIG5wbSBjYW4gdGhyb3cgaWYgdGhpcyBmaWVsZCBkb2Vzbid0IGV4aXN0XG4gICAgICAgICAgcmVzdWx0Ll9hdHRhY2htZW50cyA9IHt9O1xuICAgICAgICAgIGlmIChvcHRpb25zLmFiYnJldmlhdGVkID09PSB0cnVlKSB7XG4gICAgICAgICAgICBvcHRpb25zLmNhbGxiYWNrKG51bGwsIGNvbnZlcnRBYmJyZXZpYXRlZE1hbmlmZXN0KHJlc3VsdCksIHVwbGlua0Vycm9ycyk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIG9wdGlvbnMuY2FsbGJhY2sobnVsbCwgcmVzdWx0LCB1cGxpbmtFcnJvcnMpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgUmV0cmlldmUgcmVtb3RlIGFuZCBsb2NhbCBwYWNrYWdlcyBtb3JlIHJlY2VudCB0aGFuIHtzdGFydGtleX1cbiAgIEZ1bmN0aW9uIHN0cmVhbXMgYWxsIHBhY2thZ2VzIGZyb20gYWxsIHVwbGlua3MgZmlyc3QsIGFuZCB0aGVuXG4gICBsb2NhbCBwYWNrYWdlcy5cbiAgIE5vdGUgdGhhdCBsb2NhbCBwYWNrYWdlcyBjb3VsZCBvdmVycmlkZSByZWdpc3RyeSBvbmVzIGp1c3QgYmVjYXVzZVxuICAgdGhleSBhcHBlYXIgaW4gSlNPTiBsYXN0LiBUaGF0J3MgYSB0cmFkZS1vZmYgd2UgbWFrZSB0byBhdm9pZFxuICAgbWVtb3J5IGlzc3Vlcy5cbiAgIFVzZWQgc3RvcmFnZXM6IGxvY2FsICYmIHVwbGluayAocHJveHlfYWNjZXNzKVxuICAgKiBAcGFyYW0geyp9IHN0YXJ0a2V5XG4gICAqIEBwYXJhbSB7Kn0gb3B0aW9uc1xuICAgKiBAcmV0dXJuIHtTdHJlYW19XG4gICAqL1xuICBwdWJsaWMgc2VhcmNoKHN0YXJ0a2V5OiBzdHJpbmcsIG9wdGlvbnM6IGFueSkge1xuICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuICAgIGNvbnN0IHNlYXJjaFN0cmVhbTogYW55ID0gbmV3IFN0cmVhbS5QYXNzVGhyb3VnaCh7IG9iamVjdE1vZGU6IHRydWUgfSk7XG4gICAgYXN5bmMuZWFjaFNlcmllcyhcbiAgICAgIE9iamVjdC5rZXlzKHRoaXMudXBsaW5rcyksXG4gICAgICBmdW5jdGlvbiAodXBfbmFtZSwgY2IpOiB2b2lkIHtcbiAgICAgICAgLy8gc2hvcnRjdXQ6IGlmIGBsb2NhbD0xYCBpcyBzdXBwbGllZCwgZG9uJ3QgY2FsbCB1cGxpbmtzXG4gICAgICAgIGlmIChvcHRpb25zLnJlcT8ucXVlcnk/LmxvY2FsICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICByZXR1cm4gY2IoKTtcbiAgICAgICAgfVxuICAgICAgICBsb2dnZXIuaW5mbyhgc2VhcmNoIGZvciB1cGxpbmsgJHt1cF9uYW1lfWApO1xuICAgICAgICAvLyBzZWFyY2ggYnkga2V5d29yZCBmb3IgZWFjaCB1cGxpbmtcbiAgICAgICAgY29uc3QgdXBsaW5rU3RyZWFtID0gc2VsZi51cGxpbmtzW3VwX25hbWVdLnNlYXJjaChvcHRpb25zKTtcbiAgICAgICAgLy8gam9pbiB1cGxpbmsgc3RyZWFtIHdpdGggc3RyZWFtcyBQYXNzVGhyb3VnaFxuICAgICAgICB1cGxpbmtTdHJlYW0ucGlwZShzZWFyY2hTdHJlYW0sIHsgZW5kOiBmYWxzZSB9KTtcbiAgICAgICAgdXBsaW5rU3RyZWFtLm9uKCdlcnJvcicsIGZ1bmN0aW9uIChlcnIpOiB2b2lkIHtcbiAgICAgICAgICBzZWxmLmxvZ2dlci5lcnJvcih7IGVycjogZXJyIH0sICd1cGxpbmsgZXJyb3I6IEB7ZXJyLm1lc3NhZ2V9Jyk7XG4gICAgICAgICAgY2IoKTtcbiAgICAgICAgICAvLyB0byBhdm9pZCBjYWxsIGNhbGxiYWNrIG1vcmUgdGhhbiBvbmNlXG4gICAgICAgICAgY2IgPSBmdW5jdGlvbiAoKTogdm9pZCB7fTtcbiAgICAgICAgfSk7XG4gICAgICAgIHVwbGlua1N0cmVhbS5vbignZW5kJywgZnVuY3Rpb24gKCk6IHZvaWQge1xuICAgICAgICAgIGNiKCk7XG4gICAgICAgICAgLy8gdG8gYXZvaWQgY2FsbCBjYWxsYmFjayBtb3JlIHRoYW4gb25jZVxuICAgICAgICAgIGNiID0gZnVuY3Rpb24gKCk6IHZvaWQge307XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHNlYXJjaFN0cmVhbS5hYm9ydCA9IGZ1bmN0aW9uICgpOiB2b2lkIHtcbiAgICAgICAgICBpZiAodXBsaW5rU3RyZWFtLmFib3J0KSB7XG4gICAgICAgICAgICB1cGxpbmtTdHJlYW0uYWJvcnQoKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgY2IoKTtcbiAgICAgICAgICAvLyB0byBhdm9pZCBjYWxsIGNhbGxiYWNrIG1vcmUgdGhhbiBvbmNlXG4gICAgICAgICAgY2IgPSBmdW5jdGlvbiAoKTogdm9pZCB7fTtcbiAgICAgICAgfTtcbiAgICAgIH0sXG4gICAgICAvLyBleGVjdXRlZCBhZnRlciBhbGwgc2VyaWVzXG4gICAgICBmdW5jdGlvbiAoKTogdm9pZCB7XG4gICAgICAgIC8vIGF0dGFjaCBhIGxvY2FsIHNlYXJjaCByZXN1bHRzXG4gICAgICAgIGNvbnN0IGxvY2FsU2VhcmNoU3RyZWFtID0gc2VsZi5sb2NhbFN0b3JhZ2Uuc2VhcmNoKHN0YXJ0a2V5LCBvcHRpb25zKTtcbiAgICAgICAgc2VhcmNoU3RyZWFtLmFib3J0ID0gZnVuY3Rpb24gKCk6IHZvaWQge1xuICAgICAgICAgIGxvY2FsU2VhcmNoU3RyZWFtLmFib3J0KCk7XG4gICAgICAgIH07XG4gICAgICAgIGxvY2FsU2VhcmNoU3RyZWFtLnBpcGUoc2VhcmNoU3RyZWFtLCB7IGVuZDogdHJ1ZSB9KTtcbiAgICAgICAgbG9jYWxTZWFyY2hTdHJlYW0ub24oJ2Vycm9yJywgZnVuY3Rpb24gKGVycjogYW55KTogdm9pZCB7XG4gICAgICAgICAgc2VsZi5sb2dnZXIuZXJyb3IoeyBlcnI6IGVyciB9LCAnc2VhcmNoIGVycm9yOiBAe2Vyci5tZXNzYWdlfScpO1xuICAgICAgICAgIHNlYXJjaFN0cmVhbS5lbmQoKTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgKTtcblxuICAgIHJldHVybiBzZWFyY2hTdHJlYW07XG4gIH1cblxuICAvKipcbiAgICogUmV0cmlldmUgb25seSBwcml2YXRlIGxvY2FsIHBhY2thZ2VzXG4gICAqIEBwYXJhbSB7Kn0gY2FsbGJhY2tcbiAgICovXG4gIHB1YmxpYyBnZXRMb2NhbERhdGFiYXNlKGNhbGxiYWNrOiBDYWxsYmFjayk6IHZvaWQge1xuICAgIHRoaXMubG9jYWxTdG9yYWdlLnN0b3JhZ2VQbHVnaW4uZ2V0KChlcnIsIGxvY2Fscyk6IHZvaWQgPT4ge1xuICAgICAgaWYgKGVycikge1xuICAgICAgICByZXR1cm4gY2FsbGJhY2soZXJyKTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5fY29sbGVjdExvY2FsUGFja2FnZXMobG9jYWxzKS50aGVuKFxuICAgICAgICAocGFja2FnZXMpID0+IGNhbGxiYWNrKG51bGwsIHBhY2thZ2VzKSxcbiAgICAgICAgKGVycikgPT4gY2FsbGJhY2soZXJyKVxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWFkIGVhY2ggbG9jYWwgcGFja2FnZSBuYW1lLCBhcHBseSBmaWx0ZXJzLCBhbmQgY29sbGVjdCB0aGUgbGF0ZXN0IHZlcnNpb24uXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIF9jb2xsZWN0TG9jYWxQYWNrYWdlcyhsb2NhbHM6IHN0cmluZ1tdKTogUHJvbWlzZTxWZXJzaW9uW10+IHtcbiAgICBjb25zdCBwYWNrYWdlczogVmVyc2lvbltdID0gW107XG4gICAgZm9yIChjb25zdCBuYW1lIG9mIGxvY2Fscykge1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgcGtnTWV0YWRhdGEgPSBhd2FpdCB0aGlzLmxvY2FsU3RvcmFnZS5nZXRQYWNrYWdlTWV0YWRhdGFBc3luYyhuYW1lKTtcbiAgICAgICAgY29uc3QgeyBmaWx0ZXJlZFBhY2thZ2UgfSA9IGF3YWl0IHRoaXMuX2FwcGx5RmlsdGVycyhwa2dNZXRhZGF0YSk7XG4gICAgICAgIGNvbnN0IGxhdGVzdCA9IGZpbHRlcmVkUGFja2FnZVtESVNUX1RBR1NdPy5sYXRlc3Q7XG4gICAgICAgIGlmIChsYXRlc3QgJiYgZmlsdGVyZWRQYWNrYWdlLnZlcnNpb25zW2xhdGVzdF0pIHtcbiAgICAgICAgICBjb25zdCB2ZXJzaW9uOiBWZXJzaW9uID0gZmlsdGVyZWRQYWNrYWdlLnZlcnNpb25zW2xhdGVzdF07XG4gICAgICAgICAgY29uc3QgdGltZUxpc3QgPSBmaWx0ZXJlZFBhY2thZ2UudGltZSBhcyBHZW5lcmljQm9keTtcbiAgICAgICAgICBjb25zdCB0aW1lID0gdGltZUxpc3RbbGF0ZXN0XTtcbiAgICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgICAgdmVyc2lvbi50aW1lID0gdGltZTtcblxuICAgICAgICAgIC8vIEFkZCBmb3Igc3RhcnMgYXBpXG4gICAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICAgIHZlcnNpb24udXNlcnMgPSBmaWx0ZXJlZFBhY2thZ2UudXNlcnM7XG5cbiAgICAgICAgICBwYWNrYWdlcy5wdXNoKHZlcnNpb24pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRoaXMubG9nZ2VyLndhcm4oeyBwYWNrYWdlOiBuYW1lIH0sICdwYWNrYWdlIEB7cGFja2FnZX0gZG9lcyBub3QgaGF2ZSBhIFwibGF0ZXN0XCIgdGFnPycpO1xuICAgICAgICB9XG4gICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgdGhpcy5sb2dnZXIuZXJyb3IoeyBlcnIsIHBhY2thZ2U6IG5hbWUgfSwgJ2Vycm9yIHJlYWRpbmcgcGFja2FnZSBAe3BhY2thZ2V9Jyk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBwYWNrYWdlcztcbiAgfVxuXG4gIC8qKlxuICAgKiBGdW5jdGlvbiBmZXRjaGVzIHBhY2thZ2UgbWV0YWRhdGEgZnJvbSB1cGxpbmtzIGFuZCBzeW5jaHJvbml6ZXMgaXQgd2l0aCBsb2NhbCBkYXRhXG4gICBpZiBwYWNrYWdlIGlzIGF2YWlsYWJsZSBsb2NhbGx5LCBpdCBNVVNUIGJlIHByb3ZpZGVkIGluIHBrZ2luZm9cbiAgIHJldHVybnMgY2FsbGJhY2soZXJyLCByZXN1bHQsIHVwbGlua19lcnJvcnMpXG4gICAqL1xuICBwdWJsaWMgX3N5bmNVcGxpbmtzTWV0YWRhdGEoXG4gICAgbmFtZTogc3RyaW5nLFxuICAgIHBhY2thZ2VJbmZvOiBNYW5pZmVzdCxcbiAgICBvcHRpb25zOiBJU3luY1VwbGlua3MsXG4gICAgY2FsbGJhY2s6IENhbGxiYWNrXG4gICk6IHZvaWQge1xuICAgIGxldCBmb3VuZCA9IHRydWU7XG4gICAgY29uc3Qgc2VsZiA9IHRoaXM7XG4gICAgY29uc3QgdXBMaW5rczogUHJveHlTdG9yYWdlW10gPSBbXTtcbiAgICBjb25zdCBoYXNUb0xvb2tJbnRvVXBsaW5rcyA9IF8uaXNOaWwob3B0aW9ucy51cGxpbmtzTG9vaykgfHwgb3B0aW9ucy51cGxpbmtzTG9vaztcblxuICAgIGlmICghcGFja2FnZUluZm8pIHtcbiAgICAgIGZvdW5kID0gZmFsc2U7XG4gICAgICBwYWNrYWdlSW5mbyA9IGdlbmVyYXRlUGFja2FnZVRlbXBsYXRlKG5hbWUpO1xuICAgIH1cblxuICAgIGZvciAoY29uc3QgdXBsaW5rIGluIHRoaXMudXBsaW5rcykge1xuICAgICAgaWYgKGhhc1Byb3h5VG8obmFtZSwgdXBsaW5rLCB0aGlzLmNvbmZpZy5wYWNrYWdlcykgJiYgaGFzVG9Mb29rSW50b1VwbGlua3MpIHtcbiAgICAgICAgdXBMaW5rcy5wdXNoKHRoaXMudXBsaW5rc1t1cGxpbmtdKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBhc3luYy5tYXAoXG4gICAgICB1cExpbmtzLFxuICAgICAgKHVwTGluazogUHJveHlTdG9yYWdlLCBjYik6IHZvaWQgPT4ge1xuICAgICAgICBjb25zdCBfb3B0aW9ucyA9IE9iamVjdC5hc3NpZ24oe30sIG9wdGlvbnMpO1xuICAgICAgICBjb25zdCB1cExpbmtNZXRhID0gcGFja2FnZUluZm8uX3VwbGlua3NbdXBMaW5rLnVwbmFtZV07XG5cbiAgICAgICAgaWYgKGlzT2JqZWN0KHVwTGlua01ldGEpKSB7XG4gICAgICAgICAgY29uc3QgZmV0Y2hlZCA9IHVwTGlua01ldGEuZmV0Y2hlZDtcblxuICAgICAgICAgIGlmIChmZXRjaGVkICYmIERhdGUubm93KCkgLSBmZXRjaGVkIDwgdXBMaW5rLm1heGFnZSkge1xuICAgICAgICAgICAgcmV0dXJuIGNiKCk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgX29wdGlvbnMuZXRhZyA9IHVwTGlua01ldGEuZXRhZztcbiAgICAgICAgfVxuXG4gICAgICAgIHVwTGluay5nZXRSZW1vdGVNZXRhZGF0YShuYW1lLCBfb3B0aW9ucywgKGVyciwgdXBMaW5rUmVzcG9uc2UsIGVUYWcpOiB2b2lkID0+IHtcbiAgICAgICAgICBpZiAoZXJyICYmIGVyci5yZW1vdGVTdGF0dXMgPT09IDMwNCkge1xuICAgICAgICAgICAgdXBMaW5rTWV0YS5mZXRjaGVkID0gRGF0ZS5ub3coKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoZXJyIHx8ICF1cExpbmtSZXNwb25zZSkge1xuICAgICAgICAgICAgcmV0dXJuIGNiKG51bGwsIFtlcnIgfHwgRXJyb3JDb2RlLmdldEludGVybmFsRXJyb3IoJ25vIGRhdGEnKV0pO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICB1cExpbmtSZXNwb25zZSA9IHZhbGlkYXRpb25VdGlscy5ub3JtYWxpemVNZXRhZGF0YSh1cExpbmtSZXNwb25zZSwgbmFtZSk7XG4gICAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICBzZWxmLmxvZ2dlci5lcnJvcihcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHN1YjogJ291dCcsXG4gICAgICAgICAgICAgICAgZXJyOiBlcnIsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICdwYWNrYWdlLmpzb24gdmFsaWRhdGluZyBlcnJvciBAeyFlcnIubWVzc2FnZX1cXG5Ae2Vyci5zdGFja30nXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgcmV0dXJuIGNiKG51bGwsIFtlcnJdKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBwYWNrYWdlSW5mby5fdXBsaW5rc1t1cExpbmsudXBuYW1lXSA9IHtcbiAgICAgICAgICAgIGV0YWc6IGVUYWcsXG4gICAgICAgICAgICBmZXRjaGVkOiBEYXRlLm5vdygpLFxuICAgICAgICAgIH07XG5cbiAgICAgICAgICBwYWNrYWdlSW5mbyA9IG1lcmdlVXBsaW5rVGltZUludG9Mb2NhbChwYWNrYWdlSW5mbywgdXBMaW5rUmVzcG9uc2UpO1xuXG4gICAgICAgICAgdXBkYXRlVmVyc2lvbnNIaWRkZW5VcExpbmsodXBMaW5rUmVzcG9uc2UudmVyc2lvbnMsIHVwTGluayk7XG5cbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgbWVyZ2VWZXJzaW9ucyhwYWNrYWdlSW5mbywgdXBMaW5rUmVzcG9uc2UpO1xuICAgICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgc2VsZi5sb2dnZXIuZXJyb3IoXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBzdWI6ICdvdXQnLFxuICAgICAgICAgICAgICAgIGVycjogZXJyLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAncGFja2FnZS5qc29uIHBhcnNpbmcgZXJyb3IgQHshZXJyLm1lc3NhZ2V9XFxuQHtlcnIuc3RhY2t9J1xuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIHJldHVybiBjYihudWxsLCBbZXJyXSk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLy8gaWYgd2UgZ290IHRvIHRoaXMgcG9pbnQsIGFzc3VtZSB0aGF0IHRoZSBjb3JyZWN0IHBhY2thZ2UgZXhpc3RzXG4gICAgICAgICAgLy8gb24gdGhlIHVwbGlua1xuICAgICAgICAgIGZvdW5kID0gdHJ1ZTtcbiAgICAgICAgICBjYigpO1xuICAgICAgICB9KTtcbiAgICAgIH0sXG4gICAgICAvLyBAdHMtaWdub3JlXG4gICAgICBhc3luYyAoZXJyOiBFcnJvciwgdXBMaW5rc0Vycm9yczogYW55KTogUHJvbWlzZTx2b2lkPiA9PiB7XG4gICAgICAgIGFzc2VydCghZXJyICYmIEFycmF5LmlzQXJyYXkodXBMaW5rc0Vycm9ycykpO1xuXG4gICAgICAgIC8vIENoZWNrIGZvciBjb25uZWN0aW9uIHRpbWVvdXQgb3IgcmVzZXQgZXJyb3JzIHdpdGggdXBsaW5rKHMpXG4gICAgICAgIC8vICh0aGVzZSBzaG91bGQgYmUgaGFuZGxlZCBkaWZmZXJlbnRseSBmcm9tIHRoZSBwYWNrYWdlIG5vdCBiZWluZyBmb3VuZClcbiAgICAgICAgaWYgKCFmb3VuZCkge1xuICAgICAgICAgIGxldCB1cGxpbmtUaW1lb3V0RXJyb3I7XG4gICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB1cExpbmtzRXJyb3JzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBpZiAodXBMaW5rc0Vycm9yc1tpXSkge1xuICAgICAgICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IHVwTGlua3NFcnJvcnNbaV0ubGVuZ3RoOyBqKyspIHtcbiAgICAgICAgICAgICAgICBpZiAodXBMaW5rc0Vycm9yc1tpXVtqXSkge1xuICAgICAgICAgICAgICAgICAgY29uc3QgY29kZSA9IHVwTGlua3NFcnJvcnNbaV1bal0uY29kZTtcbiAgICAgICAgICAgICAgICAgIGlmIChjb2RlID09PSAnRVRJTUVET1VUJyB8fCBjb2RlID09PSAnRVNPQ0tFVFRJTUVET1VUJyB8fCBjb2RlID09PSAnRUNPTk5SRVNFVCcpIHtcbiAgICAgICAgICAgICAgICAgICAgdXBsaW5rVGltZW91dEVycm9yID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKHVwbGlua1RpbWVvdXRFcnJvcikge1xuICAgICAgICAgICAgcmV0dXJuIGNhbGxiYWNrKEVycm9yQ29kZS5nZXRTZXJ2aWNlVW5hdmFpbGFibGUoKSwgbnVsbCwgdXBMaW5rc0Vycm9ycyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiBjYWxsYmFjayhFcnJvckNvZGUuZ2V0Tm90Rm91bmQoQVBJX0VSUk9SLk5PX1BBQ0tBR0UpLCBudWxsLCB1cExpbmtzRXJyb3JzKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh1cExpbmtzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgIGNvbnN0IHsgZmlsdGVyZWRQYWNrYWdlLCBmaWx0ZXJFcnJvcnMgfSA9IGF3YWl0IHNlbGYuX2FwcGx5RmlsdGVycyhcbiAgICAgICAgICAgIHBhY2thZ2VJbmZvIGFzIE1hbmlmZXN0XG4gICAgICAgICAgKTtcbiAgICAgICAgICByZXR1cm4gY2FsbGJhY2sobnVsbCwgZmlsdGVyZWRQYWNrYWdlLCBmaWx0ZXJFcnJvcnMpO1xuICAgICAgICB9XG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBjb25zdCBwYWNrYWdlSnNvbkxvY2FsID0gYXdhaXQgc2VsZi5sb2NhbFN0b3JhZ2UudXBkYXRlVmVyc2lvbnNBc3luYyhuYW1lLCBwYWNrYWdlSW5mbyk7XG4gICAgICAgICAgY29uc3QgeyBmaWx0ZXJlZFBhY2thZ2UsIGZpbHRlckVycm9ycyB9ID0gYXdhaXQgc2VsZi5fYXBwbHlGaWx0ZXJzKHBhY2thZ2VKc29uTG9jYWwpO1xuICAgICAgICAgIGNhbGxiYWNrKG51bGwsIGZpbHRlcmVkUGFja2FnZSwgXy5jb25jYXQodXBMaW5rc0Vycm9ycywgZmlsdGVyRXJyb3JzKSk7XG4gICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgIGNhbGxiYWNrKGVycik7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIEFwcGx5IGFsbCBjb25maWd1cmVkIGZpbHRlciBwbHVnaW5zIHRvIGEgcGFja2FnZSBtYW5pZmVzdCBzZXF1ZW50aWFsbHkuXG4gICAqIEVhY2ggZmlsdGVyJ3Mgb3V0cHV0IGlzIHBhc3NlZCBhcyBpbnB1dCB0byB0aGUgbmV4dCBmaWx0ZXIuXG4gICAqIFJldHVybnMgdGhlIGZpbHRlcmVkIG1hbmlmZXN0IGFuZCBhbnkgZXJyb3JzIHRoYXQgb2NjdXJyZWQuXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIF9hcHBseUZpbHRlcnMoXG4gICAgcGFja2FnZUluZm86IE1hbmlmZXN0XG4gICk6IFByb21pc2U8eyBmaWx0ZXJlZFBhY2thZ2U6IE1hbmlmZXN0OyBmaWx0ZXJFcnJvcnM6IEVycm9yW10gfT4ge1xuICAgIGNvbnN0IGZpbHRlckVycm9yczogRXJyb3JbXSA9IFtdO1xuICAgIGxldCBmaWx0ZXJlZFBhY2thZ2UgPSBwYWNrYWdlSW5mbztcbiAgICBmb3IgKGNvbnN0IGZpbHRlciBvZiB0aGlzLmZpbHRlcnMgPz8gW10pIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGZpbHRlcmVkUGFja2FnZSA9IGF3YWl0IGZpbHRlci5maWx0ZXJfbWV0YWRhdGEoZmlsdGVyZWRQYWNrYWdlKTtcbiAgICAgIH0gY2F0Y2ggKGVycjogYW55KSB7XG4gICAgICAgIGZpbHRlckVycm9ycy5wdXNoKGVycik7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiB7IGZpbHRlcmVkUGFja2FnZSwgZmlsdGVyRXJyb3JzIH07XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2sgaWYgYSB0YXJiYWxsIHNob3VsZCBiZSBzZXJ2ZWQgYmFzZWQgb24gZmlsdGVyIHBsdWdpbnMuXG4gICAqIExvb2tzIHVwIHBhY2thZ2UgbWV0YWRhdGEsIGFwcGxpZXMgZmlsdGVycywgYW5kIHZlcmlmaWVzIHRoZSB0YXJiYWxsXG4gICAqIHN0aWxsIGJlbG9uZ3MgdG8gYW4gYWxsb3dlZCB2ZXJzaW9uLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBfaXNUYXJiYWxsQWxsb3dlZEJ5RmlsdGVycyhuYW1lOiBzdHJpbmcsIGZpbGVuYW1lOiBzdHJpbmcpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICBpZiAoIXRoaXMuZmlsdGVycz8ubGVuZ3RoKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgcGtnTWV0YWRhdGEgPSBhd2FpdCB0aGlzLmxvY2FsU3RvcmFnZS5nZXRQYWNrYWdlTWV0YWRhdGFBc3luYyhuYW1lKTtcbiAgICAgIGNvbnN0IHsgZmlsdGVyZWRQYWNrYWdlIH0gPSBhd2FpdCB0aGlzLl9hcHBseUZpbHRlcnMocGtnTWV0YWRhdGEpO1xuICAgICAgcmV0dXJuIE9iamVjdC52YWx1ZXMoZmlsdGVyZWRQYWNrYWdlLnZlcnNpb25zIHx8IHt9KS5zb21lKCh2ZXJzaW9uKSA9PlxuICAgICAgICAodmVyc2lvbiBhcyBWZXJzaW9uKS5kaXN0Py50YXJiYWxsPy5lbmRzV2l0aCgnLycgKyBmaWxlbmFtZSlcbiAgICAgICk7XG4gICAgfSBjYXRjaCAoZXJyOiBhbnkpIHtcbiAgICAgIGlmIChlcnI/LnN0YXR1cyA9PT0gSFRUUF9TVEFUVVMuTk9UX0ZPVU5EKSB7XG4gICAgICAgIC8vIFBhY2thZ2Ugbm90IHlldCBjYWNoZWQgbG9jYWxseSDigJQgdGhlIHJlcXVlc3Qgd2lsbCBmYWxsIHRocm91Z2ggdG8gdXBsaW5rcy5cbiAgICAgICAgZGVidWcoJ3BhY2thZ2UgJW8gbm90IGNhY2hlZCBsb2NhbGx5LCBza2lwcGluZyB0YXJiYWxsIGZpbHRlciBjaGVjaycsIG5hbWUpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5sb2dnZXIuZXJyb3IoXG4gICAgICAgICAgeyBwYWNrYWdlOiBuYW1lLCBmaWxlTmFtZTogZmlsZW5hbWUsIGVyciB9LFxuICAgICAgICAgICdlcnJvciBjaGVja2luZyBmaWx0ZXJzIGZvciB0YXJiYWxsIEB7ZmlsZU5hbWV9IG9mIHBhY2thZ2UgQHtwYWNrYWdlfTogQHtlcnIubWVzc2FnZX0nXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogU2V0IGEgaGlkZGVuIHZhbHVlIGZvciBlYWNoIHZlcnNpb24uXG4gICAqIEBwYXJhbSB7QXJyYXl9IHZlcnNpb25zIGxpc3Qgb2YgdmVyc2lvblxuICAgKiBAcGFyYW0ge1N0cmluZ30gdXBMaW5rIHVwbGluayBuYW1lXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBwdWJsaWMgX3VwZGF0ZVZlcnNpb25zSGlkZGVuVXBMaW5rKHZlcnNpb25zOiBWZXJzaW9ucywgdXBMaW5rOiBQcm94eVN0b3JhZ2UpOiB2b2lkIHtcbiAgICBmb3IgKGNvbnN0IGkgaW4gdmVyc2lvbnMpIHtcbiAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwodmVyc2lvbnMsIGkpKSB7XG4gICAgICAgIGNvbnN0IHZlcnNpb24gPSB2ZXJzaW9uc1tpXTtcblxuICAgICAgICAvLyBob2xkcyBhIFwiaGlkZGVuXCIgdmFsdWUgdG8gYmUgdXNlZCBieSB0aGUgcGFja2FnZSBzdG9yYWdlLlxuICAgICAgICB2ZXJzaW9uW1N5bWJvbC5mb3IoJ19fdmVyZGFjY2lvX3VwbGluaycpXSA9IHVwTGluay51cG5hbWU7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFN0b3JhZ2U7XG4iXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBLElBQUFBLE9BQUEsR0FBQUMsc0JBQUEsQ0FBQUMsT0FBQTtBQUNBLElBQUFDLE1BQUEsR0FBQUYsc0JBQUEsQ0FB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