appium 2.0.0-beta.3 → 2.0.0-beta.34
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -11
- package/build/lib/appium.d.ts +215 -0
- package/build/lib/appium.d.ts.map +1 -0
- package/build/lib/appium.js +241 -132
- package/build/lib/cli/args.d.ts +20 -0
- package/build/lib/cli/args.d.ts.map +1 -0
- package/build/lib/cli/args.js +96 -282
- package/build/lib/cli/driver-command.d.ts +36 -0
- package/build/lib/cli/driver-command.d.ts.map +1 -0
- package/build/lib/cli/driver-command.js +19 -12
- package/build/lib/cli/extension-command.d.ts +345 -0
- package/build/lib/cli/extension-command.d.ts.map +1 -0
- package/build/lib/cli/extension-command.js +171 -96
- package/build/lib/cli/extension.d.ts +14 -0
- package/build/lib/cli/extension.d.ts.map +1 -0
- package/build/lib/cli/extension.js +31 -16
- package/build/lib/cli/parser.d.ts +80 -0
- package/build/lib/cli/parser.d.ts.map +1 -0
- package/build/lib/cli/parser.js +152 -95
- package/build/lib/cli/plugin-command.d.ts +39 -0
- package/build/lib/cli/plugin-command.d.ts.map +1 -0
- package/build/lib/cli/plugin-command.js +18 -13
- package/build/lib/cli/utils.d.ts +29 -0
- package/build/lib/cli/utils.d.ts.map +1 -0
- package/build/lib/cli/utils.js +27 -3
- package/build/lib/config-file.d.ts +100 -0
- package/build/lib/config-file.d.ts.map +1 -0
- package/build/lib/config-file.js +136 -0
- package/build/lib/config.d.ts +41 -0
- package/build/lib/config.d.ts.map +1 -0
- package/build/lib/config.js +92 -67
- package/build/lib/constants.d.ts +48 -0
- package/build/lib/constants.d.ts.map +1 -0
- package/build/lib/constants.js +60 -0
- package/build/lib/extension/driver-config.d.ts +84 -0
- package/build/lib/extension/driver-config.d.ts.map +1 -0
- package/build/lib/extension/driver-config.js +190 -0
- package/build/lib/extension/extension-config.d.ts +170 -0
- package/build/lib/extension/extension-config.d.ts.map +1 -0
- package/build/lib/extension/extension-config.js +297 -0
- package/build/lib/extension/index.d.ts +39 -0
- package/build/lib/extension/index.d.ts.map +1 -0
- package/build/lib/extension/index.js +77 -0
- package/build/lib/extension/manifest.d.ts +174 -0
- package/build/lib/extension/manifest.d.ts.map +1 -0
- package/build/lib/extension/manifest.js +246 -0
- package/build/lib/extension/package-changed.d.ts +11 -0
- package/build/lib/extension/package-changed.d.ts.map +1 -0
- package/build/lib/extension/package-changed.js +68 -0
- package/build/lib/extension/plugin-config.d.ts +62 -0
- package/build/lib/extension/plugin-config.d.ts.map +1 -0
- package/build/lib/extension/plugin-config.js +87 -0
- package/build/lib/grid-register.d.ts +10 -0
- package/build/lib/grid-register.d.ts.map +1 -0
- package/build/lib/grid-register.js +21 -25
- package/build/lib/logger.d.ts +3 -0
- package/build/lib/logger.d.ts.map +1 -0
- package/build/lib/logger.js +4 -6
- package/build/lib/logsink.d.ts +4 -0
- package/build/lib/logsink.d.ts.map +1 -0
- package/build/lib/logsink.js +12 -16
- package/build/lib/main.d.ts +54 -0
- package/build/lib/main.d.ts.map +1 -0
- package/build/lib/main.js +189 -90
- package/build/lib/schema/arg-spec.d.ts +143 -0
- package/build/lib/schema/arg-spec.d.ts.map +1 -0
- package/build/lib/schema/arg-spec.js +119 -0
- package/build/lib/schema/cli-args.d.ts +19 -0
- package/build/lib/schema/cli-args.d.ts.map +1 -0
- package/build/lib/schema/cli-args.js +180 -0
- package/build/lib/schema/cli-transformers.d.ts +5 -0
- package/build/lib/schema/cli-transformers.d.ts.map +1 -0
- package/build/lib/schema/cli-transformers.js +74 -0
- package/build/lib/schema/index.d.ts +3 -0
- package/build/lib/schema/index.d.ts.map +1 -0
- package/build/lib/schema/index.js +34 -0
- package/build/lib/schema/keywords.d.ts +24 -0
- package/build/lib/schema/keywords.d.ts.map +1 -0
- package/build/lib/schema/keywords.js +70 -0
- package/build/lib/schema/schema.d.ts +259 -0
- package/build/lib/schema/schema.d.ts.map +1 -0
- package/build/lib/schema/schema.js +452 -0
- package/build/lib/utils.d.ts +66 -0
- package/build/lib/utils.d.ts.map +1 -0
- package/build/lib/utils.js +35 -139
- package/build/tsconfig.tsbuildinfo +1 -0
- package/build/types/appium-manifest.d.ts +40 -0
- package/build/types/appium-manifest.d.ts.map +1 -0
- package/build/types/cli.d.ts +112 -0
- package/build/types/cli.d.ts.map +1 -0
- package/build/types/extension.d.ts +43 -0
- package/build/types/extension.d.ts.map +1 -0
- package/build/types/external-manifest.d.ts +47 -0
- package/build/types/external-manifest.d.ts.map +1 -0
- package/build/types/index.d.ts +15 -0
- package/build/types/index.d.ts.map +1 -0
- package/index.js +11 -0
- package/lib/appium-config.schema.json +278 -0
- package/lib/appium.js +402 -155
- package/lib/cli/args.js +174 -377
- package/lib/cli/driver-command.js +22 -7
- package/lib/cli/extension-command.js +372 -177
- package/lib/cli/extension.js +32 -10
- package/lib/cli/parser.js +253 -83
- package/lib/cli/plugin-command.js +19 -6
- package/lib/cli/utils.js +22 -2
- package/lib/config-file.js +223 -0
- package/lib/config.js +170 -69
- package/lib/constants.js +78 -0
- package/lib/extension/driver-config.js +249 -0
- package/lib/extension/extension-config.js +458 -0
- package/lib/extension/index.js +102 -0
- package/lib/extension/manifest.js +484 -0
- package/lib/extension/package-changed.js +63 -0
- package/lib/extension/plugin-config.js +113 -0
- package/lib/grid-register.js +25 -22
- package/lib/logger.js +1 -1
- package/lib/logsink.js +14 -7
- package/lib/main.js +255 -90
- package/lib/schema/arg-spec.js +232 -0
- package/lib/schema/cli-args.js +261 -0
- package/lib/schema/cli-transformers.js +122 -0
- package/lib/schema/index.js +2 -0
- package/lib/schema/keywords.js +134 -0
- package/lib/schema/schema.js +734 -0
- package/lib/utils.js +85 -129
- package/package.json +68 -85
- package/scripts/postinstall.js +71 -0
- package/types/appium-manifest.ts +61 -0
- package/types/cli.ts +153 -0
- package/types/extension.ts +56 -0
- package/types/external-manifest.ts +58 -0
- package/types/index.ts +14 -0
- package/CHANGELOG.md +0 -3515
- package/bin/ios-webkit-debug-proxy-launcher.js +0 -71
- package/build/lib/cli/npm.js +0 -206
- package/build/lib/cli/parser-helpers.js +0 -82
- package/build/lib/driver-config.js +0 -77
- package/build/lib/drivers.js +0 -96
- package/build/lib/extension-config.js +0 -251
- package/build/lib/plugin-config.js +0 -59
- package/build/lib/plugins.js +0 -14
- package/lib/cli/npm.js +0 -183
- package/lib/cli/parser-helpers.js +0 -79
- package/lib/driver-config.js +0 -46
- package/lib/drivers.js +0 -81
- package/lib/extension-config.js +0 -208
- package/lib/plugin-config.js +0 -34
- package/lib/plugins.js +0 -10
package/build/lib/appium.js
CHANGED
|
@@ -5,29 +5,25 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", {
|
|
6
6
|
value: true
|
|
7
7
|
});
|
|
8
|
-
exports.AppiumDriver = void 0;
|
|
8
|
+
exports.NoDriverProxyCommandError = exports.AppiumDriver = void 0;
|
|
9
9
|
|
|
10
10
|
require("source-map-support/register");
|
|
11
11
|
|
|
12
12
|
var _lodash = _interopRequireDefault(require("lodash"));
|
|
13
13
|
|
|
14
|
-
var _logger = _interopRequireDefault(require("./logger"));
|
|
15
|
-
|
|
16
14
|
var _config = require("./config");
|
|
17
15
|
|
|
18
|
-
var
|
|
19
|
-
|
|
20
|
-
var _appiumBaseDriver = require("appium-base-driver");
|
|
21
|
-
|
|
22
|
-
var _bluebird = _interopRequireDefault(require("bluebird"));
|
|
16
|
+
var _baseDriver = require("@appium/base-driver");
|
|
23
17
|
|
|
24
18
|
var _asyncLock = _interopRequireDefault(require("async-lock"));
|
|
25
19
|
|
|
26
20
|
var _utils = require("./utils");
|
|
27
21
|
|
|
28
|
-
var
|
|
22
|
+
var _support = require("@appium/support");
|
|
29
23
|
|
|
30
|
-
|
|
24
|
+
var _schema = require("./schema");
|
|
25
|
+
|
|
26
|
+
const desiredCapabilityConstraints = Object.freeze({
|
|
31
27
|
automationName: {
|
|
32
28
|
presence: true,
|
|
33
29
|
isString: true
|
|
@@ -36,24 +32,41 @@ const desiredCapabilityConstraints = {
|
|
|
36
32
|
presence: true,
|
|
37
33
|
isString: true
|
|
38
34
|
}
|
|
39
|
-
};
|
|
35
|
+
});
|
|
40
36
|
const sessionsListGuard = new _asyncLock.default();
|
|
41
37
|
const pendingDriversGuard = new _asyncLock.default();
|
|
42
38
|
|
|
43
|
-
class AppiumDriver extends
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
39
|
+
class AppiumDriver extends _baseDriver.DriverCore {
|
|
40
|
+
sessions = {};
|
|
41
|
+
pendingDrivers = {};
|
|
42
|
+
newCommandTimeoutMs = 0;
|
|
43
|
+
pluginClasses = [];
|
|
44
|
+
sessionPlugins = {};
|
|
45
|
+
sessionlessPlugins = [];
|
|
46
|
+
driverConfig;
|
|
47
|
+
server;
|
|
48
|
+
|
|
49
|
+
constructor(opts) {
|
|
50
|
+
if (opts.tmpDir) {
|
|
51
|
+
process.env.APPIUM_TMP_DIR = opts.tmpDir;
|
|
47
52
|
}
|
|
48
53
|
|
|
49
|
-
super(
|
|
54
|
+
super(opts);
|
|
50
55
|
this.desiredCapConstraints = desiredCapabilityConstraints;
|
|
51
|
-
this.
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
56
|
+
this.args = { ...opts
|
|
57
|
+
};
|
|
58
|
+
(0, _config.updateBuildInfo)().catch(err => {
|
|
59
|
+
this.log.debug(err);
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
get log() {
|
|
64
|
+
if (!this._log) {
|
|
65
|
+
const instanceName = `${this.constructor.name}@${_support.node.getObjectId(this).substring(0, 4)}`;
|
|
66
|
+
this._log = _support.logger.getLogger(instanceName);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return this._log;
|
|
57
70
|
}
|
|
58
71
|
|
|
59
72
|
get isCommandsQueueEnabled() {
|
|
@@ -76,34 +89,52 @@ class AppiumDriver extends _appiumBaseDriver.BaseDriver {
|
|
|
76
89
|
}
|
|
77
90
|
|
|
78
91
|
async getSessions() {
|
|
79
|
-
|
|
80
|
-
return _lodash.default.toPairs(sessions).map(([id, driver]) => ({
|
|
92
|
+
return _lodash.default.toPairs(this.sessions).map(([id, driver]) => ({
|
|
81
93
|
id,
|
|
82
94
|
capabilities: driver.caps
|
|
83
95
|
}));
|
|
84
96
|
}
|
|
85
97
|
|
|
86
|
-
printNewSessionAnnouncement(driverName, driverVersion) {
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
98
|
+
printNewSessionAnnouncement(driverName, driverVersion, driverBaseVersion) {
|
|
99
|
+
this.log.info(driverVersion ? `Appium v${_config.APPIUM_VER} creating new ${driverName} (v${driverVersion}) session` : `Appium v${_config.APPIUM_VER} creating new ${driverName} session`);
|
|
100
|
+
this.log.info(`Checking BaseDriver versions for Appium and ${driverName}`);
|
|
101
|
+
this.log.info(AppiumDriver.baseVersion ? `Appium's BaseDriver version is ${AppiumDriver.baseVersion}` : `Could not determine Appium's BaseDriver version`);
|
|
102
|
+
this.log.info(driverBaseVersion ? `${driverName}'s BaseDriver version is ${driverBaseVersion}` : `Could not determine ${driverName}'s BaseDriver version`);
|
|
90
103
|
}
|
|
91
104
|
|
|
92
|
-
|
|
93
|
-
|
|
105
|
+
assignCliArgsToExtension(extType, extName, extInstance) {
|
|
106
|
+
var _this$args$extType;
|
|
107
|
+
|
|
108
|
+
const allCliArgsForExt = (_this$args$extType = this.args[extType]) === null || _this$args$extType === void 0 ? void 0 : _this$args$extType[extName];
|
|
109
|
+
|
|
110
|
+
if (!_lodash.default.isEmpty(allCliArgsForExt)) {
|
|
111
|
+
const defaults = (0, _schema.getDefaultsForExtension)(extType, extName);
|
|
112
|
+
const cliArgs = _lodash.default.isEmpty(defaults) ? allCliArgsForExt : _lodash.default.omitBy(allCliArgsForExt, (value, key) => _lodash.default.isEqual(defaults[key], value));
|
|
113
|
+
|
|
114
|
+
if (!_lodash.default.isEmpty(cliArgs)) {
|
|
115
|
+
extInstance.cliArgs = cliArgs;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
94
118
|
}
|
|
95
119
|
|
|
96
|
-
async createSession(jsonwpCaps, reqCaps, w3cCapabilities) {
|
|
120
|
+
async createSession(jsonwpCaps, reqCaps, w3cCapabilities, driverData) {
|
|
121
|
+
var _alwaysMatch, _w3cCapabilities;
|
|
122
|
+
|
|
97
123
|
const defaultCapabilities = _lodash.default.cloneDeep(this.args.defaultCapabilities);
|
|
98
124
|
|
|
99
125
|
const defaultSettings = (0, _utils.pullSettings)(defaultCapabilities);
|
|
100
126
|
jsonwpCaps = _lodash.default.cloneDeep(jsonwpCaps);
|
|
101
|
-
const jwpSettings =
|
|
127
|
+
const jwpSettings = { ...defaultSettings,
|
|
128
|
+
...(0, _utils.pullSettings)(jsonwpCaps)
|
|
129
|
+
};
|
|
102
130
|
w3cCapabilities = _lodash.default.cloneDeep(w3cCapabilities);
|
|
103
|
-
const w3cSettings =
|
|
104
|
-
|
|
131
|
+
const w3cSettings = { ...jwpSettings,
|
|
132
|
+
...(0, _utils.pullSettings)((_alwaysMatch = ((_w3cCapabilities = w3cCapabilities) !== null && _w3cCapabilities !== void 0 ? _w3cCapabilities : {}).alwaysMatch) !== null && _alwaysMatch !== void 0 ? _alwaysMatch : {})
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
for (const firstMatchEntry of (_firstMatch = ((_w3cCapabilities2 = w3cCapabilities) !== null && _w3cCapabilities2 !== void 0 ? _w3cCapabilities2 : {}).firstMatch) !== null && _firstMatch !== void 0 ? _firstMatch : []) {
|
|
136
|
+
var _firstMatch, _w3cCapabilities2;
|
|
105
137
|
|
|
106
|
-
for (const firstMatchEntry of (w3cCapabilities || {}).firstMatch || []) {
|
|
107
138
|
Object.assign(w3cSettings, (0, _utils.pullSettings)(firstMatchEntry));
|
|
108
139
|
}
|
|
109
140
|
|
|
@@ -115,10 +146,10 @@ class AppiumDriver extends _appiumBaseDriver.BaseDriver {
|
|
|
115
146
|
const {
|
|
116
147
|
desiredCaps,
|
|
117
148
|
processedJsonwpCapabilities,
|
|
118
|
-
processedW3CCapabilities
|
|
119
|
-
error
|
|
149
|
+
processedW3CCapabilities
|
|
120
150
|
} = parsedCaps;
|
|
121
151
|
protocol = parsedCaps.protocol;
|
|
152
|
+
const error = parsedCaps.error;
|
|
122
153
|
|
|
123
154
|
if (error) {
|
|
124
155
|
throw error;
|
|
@@ -126,78 +157,76 @@ class AppiumDriver extends _appiumBaseDriver.BaseDriver {
|
|
|
126
157
|
|
|
127
158
|
const {
|
|
128
159
|
driver: InnerDriver,
|
|
129
|
-
version: driverVersion
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
this.printNewSessionAnnouncement(InnerDriver.name, driverVersion);
|
|
160
|
+
version: driverVersion,
|
|
161
|
+
driverName
|
|
162
|
+
} = this.driverConfig.findMatchingDriver(desiredCaps);
|
|
163
|
+
this.printNewSessionAnnouncement(InnerDriver.name, driverVersion, InnerDriver.baseVersion);
|
|
133
164
|
|
|
134
165
|
if (this.args.sessionOverride) {
|
|
135
166
|
await this.deleteAllSessions();
|
|
136
167
|
}
|
|
137
168
|
|
|
138
|
-
let runningDriversData
|
|
139
|
-
|
|
169
|
+
let runningDriversData = [];
|
|
170
|
+
let otherPendingDriversData = [];
|
|
171
|
+
const driverInstance = new InnerDriver(this.args, true);
|
|
140
172
|
|
|
141
173
|
if (this.args.relaxedSecurityEnabled) {
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
d.relaxedSecurityEnabled = true;
|
|
174
|
+
this.log.info(`Applying relaxed security to '${InnerDriver.name}' as per ` + `server command line argument. All insecure features will be ` + `enabled unless explicitly disabled by --deny-insecure`);
|
|
175
|
+
driverInstance.relaxedSecurityEnabled = true;
|
|
145
176
|
}
|
|
146
177
|
|
|
147
178
|
if (!_lodash.default.isEmpty(this.args.denyInsecure)) {
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
d.denyInsecure = this.args.denyInsecure;
|
|
179
|
+
this.log.info('Explicitly preventing use of insecure features:');
|
|
180
|
+
this.args.denyInsecure.map(a => this.log.info(` ${a}`));
|
|
181
|
+
driverInstance.denyInsecure = this.args.denyInsecure;
|
|
152
182
|
}
|
|
153
183
|
|
|
154
184
|
if (!_lodash.default.isEmpty(this.args.allowInsecure)) {
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
d.allowInsecure = this.args.allowInsecure;
|
|
185
|
+
this.log.info('Explicitly enabling use of insecure features:');
|
|
186
|
+
this.args.allowInsecure.map(a => this.log.info(` ${a}`));
|
|
187
|
+
driverInstance.allowInsecure = this.args.allowInsecure;
|
|
159
188
|
}
|
|
160
189
|
|
|
161
|
-
|
|
190
|
+
this.assignCliArgsToExtension('driver', driverName, driverInstance);
|
|
191
|
+
driverInstance.server = this.server;
|
|
192
|
+
driverInstance.serverHost = this.args.address;
|
|
193
|
+
driverInstance.serverPort = this.args.port;
|
|
194
|
+
driverInstance.serverPath = this.args.basePath;
|
|
162
195
|
|
|
163
196
|
try {
|
|
164
|
-
|
|
197
|
+
var _await$this$curSessio;
|
|
198
|
+
|
|
199
|
+
runningDriversData = (_await$this$curSessio = await this.curSessionDataForDriver(InnerDriver)) !== null && _await$this$curSessio !== void 0 ? _await$this$curSessio : [];
|
|
165
200
|
} catch (e) {
|
|
166
|
-
throw new
|
|
201
|
+
throw new _baseDriver.errors.SessionNotCreatedError(e.message);
|
|
167
202
|
}
|
|
168
203
|
|
|
169
204
|
await pendingDriversGuard.acquire(AppiumDriver.name, () => {
|
|
170
205
|
this.pendingDrivers[InnerDriver.name] = this.pendingDrivers[InnerDriver.name] || [];
|
|
171
|
-
otherPendingDriversData = this.pendingDrivers[InnerDriver.name].map(drv => drv.driverData);
|
|
172
|
-
this.pendingDrivers[InnerDriver.name].push(
|
|
206
|
+
otherPendingDriversData = _lodash.default.compact(this.pendingDrivers[InnerDriver.name].map(drv => drv.driverData));
|
|
207
|
+
this.pendingDrivers[InnerDriver.name].push(driverInstance);
|
|
173
208
|
});
|
|
174
209
|
|
|
175
210
|
try {
|
|
176
|
-
[innerSessionId, dCaps] = await
|
|
177
|
-
protocol =
|
|
178
|
-
|
|
179
|
-
this.sessions[innerSessionId] = d;
|
|
180
|
-
});
|
|
211
|
+
[innerSessionId, dCaps] = await driverInstance.createSession(processedJsonwpCapabilities, reqCaps, processedW3CCapabilities, [...runningDriversData, ...otherPendingDriversData]);
|
|
212
|
+
protocol = driverInstance.protocol;
|
|
213
|
+
this.sessions[innerSessionId] = driverInstance;
|
|
181
214
|
} finally {
|
|
182
215
|
await pendingDriversGuard.acquire(AppiumDriver.name, () => {
|
|
183
|
-
_lodash.default.pull(this.pendingDrivers[InnerDriver.name],
|
|
216
|
+
_lodash.default.pull(this.pendingDrivers[InnerDriver.name], driverInstance);
|
|
184
217
|
});
|
|
185
218
|
}
|
|
186
219
|
|
|
187
|
-
this.attachUnexpectedShutdownHandler(
|
|
220
|
+
this.attachUnexpectedShutdownHandler(driverInstance, innerSessionId);
|
|
221
|
+
this.log.info(`New ${InnerDriver.name} session created successfully, session ` + `${innerSessionId} added to master session list`);
|
|
222
|
+
driverInstance.startNewCommandTimeout();
|
|
188
223
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
await d.updateSettings(w3cSettings);
|
|
197
|
-
} else if (d.isMjsonwpProtocol() && !_lodash.default.isEmpty(jwpSettings)) {
|
|
198
|
-
_logger.default.info(`Applying the initial values to Appium settings parsed from MJSONWP caps: ` + JSON.stringify(jwpSettings));
|
|
199
|
-
|
|
200
|
-
await d.updateSettings(jwpSettings);
|
|
224
|
+
if (driverInstance.isW3CProtocol() && !_lodash.default.isEmpty(w3cSettings)) {
|
|
225
|
+
this.log.info(`Applying the initial values to Appium settings parsed from W3C caps: ` + JSON.stringify(w3cSettings));
|
|
226
|
+
await driverInstance.updateSettings(w3cSettings);
|
|
227
|
+
} else if (driverInstance.isMjsonwpProtocol() && !_lodash.default.isEmpty(jwpSettings)) {
|
|
228
|
+
this.log.info(`Applying the initial values to Appium settings parsed from MJSONWP caps: ` + JSON.stringify(jwpSettings));
|
|
229
|
+
await driverInstance.updateSettings(jwpSettings);
|
|
201
230
|
}
|
|
202
231
|
} catch (error) {
|
|
203
232
|
return {
|
|
@@ -213,37 +242,43 @@ class AppiumDriver extends _appiumBaseDriver.BaseDriver {
|
|
|
213
242
|
}
|
|
214
243
|
|
|
215
244
|
attachUnexpectedShutdownHandler(driver, innerSessionId) {
|
|
216
|
-
const
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
245
|
+
const onShutdown = (cause = new Error('Unknown error')) => {
|
|
246
|
+
this.log.warn(`Ending session, cause was '${cause.message}'`);
|
|
247
|
+
|
|
248
|
+
if (this.sessionPlugins[innerSessionId]) {
|
|
249
|
+
for (const plugin of this.sessionPlugins[innerSessionId]) {
|
|
250
|
+
if (_lodash.default.isFunction(plugin.onUnexpectedShutdown)) {
|
|
251
|
+
this.log.debug(`Plugin ${plugin.name} defines an unexpected shutdown handler; calling it now`);
|
|
252
|
+
|
|
253
|
+
try {
|
|
254
|
+
plugin.onUnexpectedShutdown(driver, cause);
|
|
255
|
+
} catch (e) {
|
|
256
|
+
this.log.warn(`Got an error when running plugin ${plugin.name} shutdown handler: ${e}`);
|
|
257
|
+
}
|
|
258
|
+
} else {
|
|
259
|
+
this.log.debug(`Plugin ${plugin.name} does not define an unexpected shutdown handler`);
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
}
|
|
220
263
|
|
|
264
|
+
this.log.info(`Removing session '${innerSessionId}' from our master session list`);
|
|
221
265
|
delete this.sessions[innerSessionId];
|
|
266
|
+
delete this.sessionPlugins[innerSessionId];
|
|
222
267
|
};
|
|
223
268
|
|
|
224
|
-
if (_lodash.default.isFunction(
|
|
225
|
-
driver.onUnexpectedShutdown
|
|
226
|
-
throw new Error('Unexpected shutdown');
|
|
227
|
-
}).catch(e => {
|
|
228
|
-
if (!(e instanceof _bluebird.default.CancellationError)) {
|
|
229
|
-
removeSessionFromMasterList(e);
|
|
230
|
-
}
|
|
231
|
-
});
|
|
232
|
-
} else if (_lodash.default.isFunction(driver.onUnexpectedShutdown)) {
|
|
233
|
-
driver.onUnexpectedShutdown(removeSessionFromMasterList);
|
|
269
|
+
if (_lodash.default.isFunction(driver.onUnexpectedShutdown)) {
|
|
270
|
+
driver.onUnexpectedShutdown(onShutdown);
|
|
234
271
|
} else {
|
|
235
|
-
|
|
272
|
+
this.log.warn(`Failed to attach the unexpected shutdown listener. ` + `Is 'onUnexpectedShutdown' method available for '${driver.constructor.name}'?`);
|
|
236
273
|
}
|
|
237
274
|
}
|
|
238
275
|
|
|
239
276
|
async curSessionDataForDriver(InnerDriver) {
|
|
240
|
-
const
|
|
241
|
-
|
|
242
|
-
const data = _lodash.default.values(sessions).filter(s => s.constructor.name === InnerDriver.name).map(s => s.driverData);
|
|
277
|
+
const data = _lodash.default.compact(_lodash.default.values(this.sessions).filter(s => s.constructor.name === InnerDriver.name).map(s => s.driverData));
|
|
243
278
|
|
|
244
|
-
for (
|
|
279
|
+
for (const datum of data) {
|
|
245
280
|
if (!datum) {
|
|
246
|
-
throw new Error(`Problem getting session data for driver type ` + `${InnerDriver.name}; does it implement 'get
|
|
281
|
+
throw new Error(`Problem getting session data for driver type ` + `${InnerDriver.name}; does it implement 'get driverData'?`);
|
|
247
282
|
}
|
|
248
283
|
}
|
|
249
284
|
|
|
@@ -254,29 +289,32 @@ class AppiumDriver extends _appiumBaseDriver.BaseDriver {
|
|
|
254
289
|
let protocol;
|
|
255
290
|
|
|
256
291
|
try {
|
|
257
|
-
let otherSessionsData
|
|
258
|
-
|
|
259
|
-
await sessionsListGuard.acquire(AppiumDriver.name, () => {
|
|
292
|
+
let otherSessionsData;
|
|
293
|
+
const dstSession = await sessionsListGuard.acquire(AppiumDriver.name, () => {
|
|
260
294
|
if (!this.sessions[sessionId]) {
|
|
261
295
|
return;
|
|
262
296
|
}
|
|
263
297
|
|
|
264
298
|
const curConstructorName = this.sessions[sessionId].constructor.name;
|
|
265
299
|
otherSessionsData = _lodash.default.toPairs(this.sessions).filter(([key, value]) => value.constructor.name === curConstructorName && key !== sessionId).map(([, value]) => value.driverData);
|
|
266
|
-
dstSession = this.sessions[sessionId];
|
|
300
|
+
const dstSession = this.sessions[sessionId];
|
|
267
301
|
protocol = dstSession.protocol;
|
|
268
|
-
|
|
269
|
-
_logger.default.info(`Removing session ${sessionId} from our master session list`);
|
|
270
|
-
|
|
302
|
+
this.log.info(`Removing session ${sessionId} from our master session list`);
|
|
271
303
|
delete this.sessions[sessionId];
|
|
304
|
+
delete this.sessionPlugins[sessionId];
|
|
305
|
+
return dstSession;
|
|
272
306
|
});
|
|
307
|
+
|
|
308
|
+
if (!dstSession) {
|
|
309
|
+
throw new Error('Session not found');
|
|
310
|
+
}
|
|
311
|
+
|
|
273
312
|
return {
|
|
274
313
|
protocol,
|
|
275
314
|
value: await dstSession.deleteSession(sessionId, otherSessionsData)
|
|
276
315
|
};
|
|
277
316
|
} catch (e) {
|
|
278
|
-
|
|
279
|
-
|
|
317
|
+
this.log.error(`Had trouble ending session ${sessionId}: ${e.message}`);
|
|
280
318
|
return {
|
|
281
319
|
protocol,
|
|
282
320
|
error: e
|
|
@@ -288,8 +326,7 @@ class AppiumDriver extends _appiumBaseDriver.BaseDriver {
|
|
|
288
326
|
const sessionsCount = _lodash.default.size(this.sessions);
|
|
289
327
|
|
|
290
328
|
if (0 === sessionsCount) {
|
|
291
|
-
|
|
292
|
-
|
|
329
|
+
this.log.debug('There are no active sessions for cleanup');
|
|
293
330
|
return;
|
|
294
331
|
}
|
|
295
332
|
|
|
@@ -297,64 +334,109 @@ class AppiumDriver extends _appiumBaseDriver.BaseDriver {
|
|
|
297
334
|
force = false,
|
|
298
335
|
reason
|
|
299
336
|
} = opts;
|
|
300
|
-
|
|
301
|
-
_logger.default.debug(`Cleaning up ${_appiumSupport.util.pluralize('active session', sessionsCount, true)}`);
|
|
302
|
-
|
|
337
|
+
this.log.debug(`Cleaning up ${_support.util.pluralize('active session', sessionsCount, true)}`);
|
|
303
338
|
const cleanupPromises = force ? _lodash.default.values(this.sessions).map(drv => drv.startUnexpectedShutdown(reason && new Error(reason))) : _lodash.default.keys(this.sessions).map(id => this.deleteSession(id));
|
|
304
339
|
|
|
305
340
|
for (const cleanupPromise of cleanupPromises) {
|
|
306
341
|
try {
|
|
307
342
|
await cleanupPromise;
|
|
308
343
|
} catch (e) {
|
|
309
|
-
|
|
344
|
+
this.log.debug(e);
|
|
310
345
|
}
|
|
311
346
|
}
|
|
312
347
|
}
|
|
313
348
|
|
|
314
|
-
|
|
315
|
-
|
|
349
|
+
pluginsForSession(sessionId = null) {
|
|
350
|
+
if (sessionId) {
|
|
351
|
+
if (!this.sessionPlugins[sessionId]) {
|
|
352
|
+
this.sessionPlugins[sessionId] = this.createPluginInstances();
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
return this.sessionPlugins[sessionId];
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
if (_lodash.default.isEmpty(this.sessionlessPlugins)) {
|
|
359
|
+
this.sessionlessPlugins = this.createPluginInstances();
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
return this.sessionlessPlugins;
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
pluginsToHandleCmd(cmd, sessionId = null) {
|
|
366
|
+
return this.pluginsForSession(sessionId).filter(p => _lodash.default.isFunction(p[cmd]) || _lodash.default.isFunction(p.handle));
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
createPluginInstances() {
|
|
370
|
+
return this.pluginClasses.map(PluginClass => {
|
|
371
|
+
const name = PluginClass.pluginName;
|
|
372
|
+
const plugin = new PluginClass(name);
|
|
373
|
+
this.assignCliArgsToExtension('plugin', name, plugin);
|
|
374
|
+
return plugin;
|
|
375
|
+
});
|
|
316
376
|
}
|
|
317
377
|
|
|
318
378
|
async executeCommand(cmd, ...args) {
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
const
|
|
322
|
-
const
|
|
379
|
+
var _$last;
|
|
380
|
+
|
|
381
|
+
const isGetStatus = cmd === _baseDriver.GET_STATUS_COMMAND;
|
|
382
|
+
const isUmbrellaCmd = isAppiumDriverCommand(cmd);
|
|
383
|
+
const isSessionCmd = (0, _baseDriver.isSessionCommand)(cmd);
|
|
384
|
+
const reqForProxy = (_$last = _lodash.default.last(args)) === null || _$last === void 0 ? void 0 : _$last.reqForProxy;
|
|
385
|
+
|
|
386
|
+
if (reqForProxy) {
|
|
387
|
+
args.pop();
|
|
388
|
+
}
|
|
389
|
+
|
|
323
390
|
let sessionId = null;
|
|
324
391
|
let dstSession = null;
|
|
325
392
|
let protocol = null;
|
|
393
|
+
let driver = this;
|
|
326
394
|
|
|
327
395
|
if (isSessionCmd) {
|
|
328
396
|
sessionId = _lodash.default.last(args);
|
|
329
|
-
dstSession =
|
|
397
|
+
dstSession = this.sessions[sessionId];
|
|
330
398
|
|
|
331
399
|
if (!dstSession) {
|
|
332
400
|
throw new Error(`The session with id '${sessionId}' does not exist`);
|
|
333
401
|
}
|
|
334
402
|
|
|
335
403
|
protocol = dstSession.protocol;
|
|
404
|
+
|
|
405
|
+
if (!isUmbrellaCmd) {
|
|
406
|
+
driver = dstSession;
|
|
407
|
+
}
|
|
336
408
|
}
|
|
337
409
|
|
|
410
|
+
const plugins = this.pluginsToHandleCmd(cmd, sessionId);
|
|
338
411
|
const cmdHandledBy = {
|
|
339
412
|
default: false
|
|
340
413
|
};
|
|
341
414
|
|
|
342
415
|
const defaultBehavior = async () => {
|
|
343
|
-
plugins.length &&
|
|
416
|
+
plugins.length && this.log.info(`Executing default handling behavior for command '${cmd}'`);
|
|
344
417
|
cmdHandledBy.default = true;
|
|
345
418
|
|
|
419
|
+
if (reqForProxy) {
|
|
420
|
+
if (!dstSession.proxyCommand) {
|
|
421
|
+
throw new NoDriverProxyCommandError();
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
return await dstSession.proxyCommand(reqForProxy.originalUrl, reqForProxy.method, reqForProxy.body);
|
|
425
|
+
}
|
|
426
|
+
|
|
346
427
|
if (isGetStatus) {
|
|
347
428
|
return await this.getStatus();
|
|
348
429
|
}
|
|
349
430
|
|
|
350
431
|
if (isUmbrellaCmd) {
|
|
351
|
-
return await
|
|
432
|
+
return await _baseDriver.BaseDriver.prototype.executeCommand.call(this, cmd, ...args);
|
|
352
433
|
}
|
|
353
434
|
|
|
354
435
|
return await dstSession.executeCommand(cmd, ...args);
|
|
355
436
|
};
|
|
356
437
|
|
|
357
438
|
const wrappedCmd = this.wrapCommandWithPlugins({
|
|
439
|
+
driver,
|
|
358
440
|
cmd,
|
|
359
441
|
args,
|
|
360
442
|
plugins,
|
|
@@ -365,45 +447,63 @@ class AppiumDriver extends _appiumBaseDriver.BaseDriver {
|
|
|
365
447
|
wrappedCmd,
|
|
366
448
|
protocol
|
|
367
449
|
});
|
|
368
|
-
|
|
450
|
+
this.logPluginHandlerReport(plugins, {
|
|
369
451
|
cmd,
|
|
370
452
|
cmdHandledBy
|
|
371
453
|
});
|
|
454
|
+
|
|
455
|
+
if (cmd === _baseDriver.CREATE_SESSION_COMMAND && this.sessionlessPlugins.length && !res.error) {
|
|
456
|
+
const sessionId = _lodash.default.first(res.value);
|
|
457
|
+
|
|
458
|
+
this.log.info(`Promoting ${this.sessionlessPlugins.length} sessionless plugins to be attached ` + `to session ID ${sessionId}`);
|
|
459
|
+
this.sessionPlugins[sessionId] = this.sessionlessPlugins;
|
|
460
|
+
this.sessionlessPlugins = [];
|
|
461
|
+
}
|
|
462
|
+
|
|
372
463
|
return res;
|
|
373
464
|
}
|
|
374
465
|
|
|
375
466
|
wrapCommandWithPlugins({
|
|
467
|
+
driver,
|
|
376
468
|
cmd,
|
|
377
469
|
args,
|
|
378
470
|
next,
|
|
379
471
|
cmdHandledBy,
|
|
380
472
|
plugins
|
|
381
473
|
}) {
|
|
382
|
-
plugins.length &&
|
|
474
|
+
plugins.length && this.log.info(`Plugins which can handle cmd '${cmd}': ${plugins.map(p => p.name)}`);
|
|
383
475
|
|
|
384
476
|
for (const plugin of plugins) {
|
|
385
477
|
cmdHandledBy[plugin.name] = false;
|
|
386
478
|
|
|
387
479
|
next = (_next => async () => {
|
|
388
|
-
|
|
389
|
-
|
|
480
|
+
this.log.info(`Plugin ${plugin.name} is now handling cmd '${cmd}'`);
|
|
390
481
|
cmdHandledBy[plugin.name] = true;
|
|
391
|
-
|
|
482
|
+
|
|
483
|
+
if (plugin[cmd]) {
|
|
484
|
+
return await plugin[cmd](_next, driver, ...args);
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
return await plugin.handle(_next, driver, cmd, ...args);
|
|
392
488
|
})(next);
|
|
393
489
|
}
|
|
394
490
|
|
|
395
491
|
return next;
|
|
396
492
|
}
|
|
397
493
|
|
|
398
|
-
logPluginHandlerReport({
|
|
494
|
+
logPluginHandlerReport(plugins, {
|
|
399
495
|
cmd,
|
|
400
496
|
cmdHandledBy
|
|
401
497
|
}) {
|
|
498
|
+
if (!plugins.length) {
|
|
499
|
+
return;
|
|
500
|
+
}
|
|
501
|
+
|
|
402
502
|
const didHandle = Object.keys(cmdHandledBy).filter(k => cmdHandledBy[k]);
|
|
403
503
|
const didntHandle = Object.keys(cmdHandledBy).filter(k => !cmdHandledBy[k]);
|
|
404
504
|
|
|
405
505
|
if (didntHandle.length > 0) {
|
|
406
|
-
|
|
506
|
+
this.log.info(`Command '${cmd}' was *not* handled by the following behaviours or plugins, even ` + `though they were registered to handle it: ${JSON.stringify(didntHandle)}. The ` + `command *was* handled by these: ${JSON.stringify(didHandle)}.`);
|
|
407
507
|
}
|
|
408
508
|
}
|
|
409
509
|
|
|
@@ -452,8 +552,17 @@ class AppiumDriver extends _appiumBaseDriver.BaseDriver {
|
|
|
452
552
|
exports.AppiumDriver = AppiumDriver;
|
|
453
553
|
|
|
454
554
|
function isAppiumDriverCommand(cmd) {
|
|
455
|
-
return !(0,
|
|
456
|
-
}
|
|
555
|
+
return !(0, _baseDriver.isSessionCommand)(cmd) || cmd === _baseDriver.DELETE_SESSION_COMMAND;
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
class NoDriverProxyCommandError extends Error {
|
|
559
|
+
code = 'APPIUMERR_NO_DRIVER_PROXYCOMMAND';
|
|
457
560
|
|
|
561
|
+
constructor() {
|
|
562
|
+
super(`The default behavior for this command was to proxy, but the driver ` + `did not have the 'proxyCommand' method defined. To fully support ` + `plugins, drivers should have 'proxyCommand' set to a jwpProxy object's ` + `'command()' method, in addition to the normal 'proxyReqRes'`);
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
}
|
|
458
566
|
|
|
459
|
-
//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImxpYi9hcHBpdW0uanMiXSwibmFtZXMiOlsiZGVzaXJlZENhcGFiaWxpdHlDb25zdHJhaW50cyIsImF1dG9tYXRpb25OYW1lIiwicHJlc2VuY2UiLCJpc1N0cmluZyIsInBsYXRmb3JtTmFtZSIsInNlc3Npb25zTGlzdEd1YXJkIiwiQXN5bmNMb2NrIiwicGVuZGluZ0RyaXZlcnNHdWFyZCIsIkFwcGl1bURyaXZlciIsIkJhc2VEcml2ZXIiLCJjb25zdHJ1Y3RvciIsImFyZ3MiLCJ0bXBEaXIiLCJwcm9jZXNzIiwiZW52IiwiQVBQSVVNX1RNUF9ESVIiLCJkZXNpcmVkQ2FwQ29uc3RyYWludHMiLCJuZXdDb21tYW5kVGltZW91dE1zIiwiT2JqZWN0IiwiYXNzaWduIiwic2Vzc2lvbnMiLCJwZW5kaW5nRHJpdmVycyIsInBsdWdpbnMiLCJpc0NvbW1hbmRzUXVldWVFbmFibGVkIiwic2Vzc2lvbkV4aXN0cyIsInNlc3Npb25JZCIsImRzdFNlc3Npb24iLCJkcml2ZXJGb3JTZXNzaW9uIiwiZ2V0U3RhdHVzIiwiYnVpbGQiLCJfIiwiY2xvbmUiLCJnZXRTZXNzaW9ucyIsImFjcXVpcmUiLCJuYW1lIiwidG9QYWlycyIsIm1hcCIsImlkIiwiZHJpdmVyIiwiY2FwYWJpbGl0aWVzIiwiY2FwcyIsInByaW50TmV3U2Vzc2lvbkFubm91bmNlbWVudCIsImRyaXZlck5hbWUiLCJkcml2ZXJWZXJzaW9uIiwiaW50cm9TdHJpbmciLCJBUFBJVU1fVkVSIiwibG9nIiwiaW5mbyIsIl9maW5kTWF0Y2hpbmdEcml2ZXIiLCJjcmVhdGVTZXNzaW9uIiwianNvbndwQ2FwcyIsInJlcUNhcHMiLCJ3M2NDYXBhYmlsaXRpZXMiLCJkZWZhdWx0Q2FwYWJpbGl0aWVzIiwiY2xvbmVEZWVwIiwiZGVmYXVsdFNldHRpbmdzIiwiandwU2V0dGluZ3MiLCJ3M2NTZXR0aW5ncyIsImFsd2F5c01hdGNoIiwiZmlyc3RNYXRjaEVudHJ5IiwiZmlyc3RNYXRjaCIsInByb3RvY29sIiwiaW5uZXJTZXNzaW9uSWQiLCJkQ2FwcyIsInBhcnNlZENhcHMiLCJkZXNpcmVkQ2FwcyIsInByb2Nlc3NlZEpzb253cENhcGFiaWxpdGllcyIsInByb2Nlc3NlZFczQ0NhcGFiaWxpdGllcyIsImVycm9yIiwiSW5uZXJEcml2ZXIiLCJ2ZXJzaW9uIiwiZHJpdmVyQ29uZmlnIiwic2Vzc2lvbk92ZXJyaWRlIiwiZGVsZXRlQWxsU2Vzc2lvbnMiLCJydW5uaW5nRHJpdmVyc0RhdGEiLCJvdGhlclBlbmRpbmdEcml2ZXJzRGF0YSIsImQiLCJyZWxheGVkU2VjdXJpdHlFbmFibGVkIiwiaXNFbXB0eSIsImRlbnlJbnNlY3VyZSIsImEiLCJhbGxvd0luc2VjdXJlIiwic2VydmVyIiwiY3VyU2Vzc2lvbkRhdGFGb3JEcml2ZXIiLCJlIiwiZXJyb3JzIiwiU2Vzc2lvbk5vdENyZWF0ZWRFcnJvciIsIm1lc3NhZ2UiLCJkcnYiLCJkcml2ZXJEYXRhIiwicHVzaCIsInB1bGwiLCJhdHRhY2hVbmV4cGVjdGVkU2h1dGRvd25IYW5kbGVyIiwic3RhcnROZXdDb21tYW5kVGltZW91dCIsImlzVzNDUHJvdG9jb2wiLCJKU09OIiwic3RyaW5naWZ5IiwidXBkYXRlU2V0dGluZ3MiLCJpc01qc29ud3BQcm90b2NvbCIsInZhbHVlIiwicmVtb3ZlU2Vzc2lvbkZyb21NYXN0ZXJMaXN0IiwiY2F1c2UiLCJFcnJvciIsIndhcm4iLCJpc0Z1bmN0aW9uIiwib25VbmV4cGVjdGVkU2h1dGRvd24iLCJ0aGVuIiwiY2F0Y2giLCJCIiwiQ2FuY2VsbGF0aW9uRXJyb3IiLCJkYXRhIiwidmFsdWVzIiwiZmlsdGVyIiwicyIsImRhdHVtIiwiZGVsZXRlU2Vzc2lvbiIsIm90aGVyU2Vzc2lvbnNEYXRhIiwiY3VyQ29uc3RydWN0b3JOYW1lIiwia2V5Iiwib3B0cyIsInNlc3Npb25zQ291bnQiLCJzaXplIiwiZGVidWciLCJmb3JjZSIsInJlYXNvbiIsInV0aWwiLCJwbHVyYWxpemUiLCJjbGVhbnVwUHJvbWlzZXMiLCJzdGFydFVuZXhwZWN0ZWRTaHV0ZG93biIsImtleXMiLCJjbGVhbnVwUHJvbWlzZSIsInBsdWdpbnNUb0hhbmRsZUNtZCIsImNtZCIsInAiLCJjb21tYW5kcyIsImlzQXJyYXkiLCJpbmNsdWRlcyIsImV4ZWN1dGVDb21tYW5kIiwiaXNHZXRTdGF0dXMiLCJpc1VtYnJlbGxhQ21kIiwiaXNBcHBpdW1Ecml2ZXJDb21tYW5kIiwiaXNTZXNzaW9uQ21kIiwibGFzdCIsImNtZEhhbmRsZWRCeSIsImRlZmF1bHQiLCJkZWZhdWx0QmVoYXZpb3IiLCJsZW5ndGgiLCJ3cmFwcGVkQ21kIiwid3JhcENvbW1hbmRXaXRoUGx1Z2lucyIsIm5leHQiLCJyZXMiLCJleGVjdXRlV3JhcHBlZENvbW1hbmQiLCJsb2dQbHVnaW5IYW5kbGVyUmVwb3J0IiwicGx1Z2luIiwiX25leHQiLCJoYW5kbGUiLCJkaWRIYW5kbGUiLCJrIiwiZGlkbnRIYW5kbGUiLCJjbWRSZXMiLCJjbWRFcnIiLCJpc1BsYWluT2JqZWN0IiwiaGFzIiwicHJveHlBY3RpdmUiLCJnZXRQcm94eUF2b2lkTGlzdCIsImNhblByb3h5Il0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7OztBQUFBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUVBLE1BQU1BLDRCQUE0QixHQUFHO0FBQ25DQyxFQUFBQSxjQUFjLEVBQUU7QUFDZEMsSUFBQUEsUUFBUSxFQUFFLElBREk7QUFFZEMsSUFBQUEsUUFBUSxFQUFFO0FBRkksR0FEbUI7QUFLbkNDLEVBQUFBLFlBQVksRUFBRTtBQUNaRixJQUFBQSxRQUFRLEVBQUUsSUFERTtBQUVaQyxJQUFBQSxRQUFRLEVBQUU7QUFGRTtBQUxxQixDQUFyQztBQVdBLE1BQU1FLGlCQUFpQixHQUFHLElBQUlDLGtCQUFKLEVBQTFCO0FBQ0EsTUFBTUMsbUJBQW1CLEdBQUcsSUFBSUQsa0JBQUosRUFBNUI7O0FBRUEsTUFBTUUsWUFBTixTQUEyQkMsNEJBQTNCLENBQXNDO0FBQ3BDQyxFQUFBQSxXQUFXLENBQUVD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LE1BRU87QUFDTFQsTUFBQUEsR0FBRyxDQUFDbkQsS0FBSixHQUFZNEQsTUFBWjtBQUNBVCxNQUFBQSxHQUFHLENBQUNsRixLQUFKLEdBQVk0RixNQUFaO0FBQ0FWLE1BQUFBLEdBQUcsQ0FBQ3pGLFFBQUosR0FBZUEsUUFBZjtBQUNEOztBQUNELFdBQU95RixHQUFQO0FBQ0Q7O0FBR0RhLEVBQUFBLFdBQVcsQ0FBRTFJLFNBQUYsRUFBYTtBQUN0QixVQUFNQyxVQUFVLEdBQUcsS0FBS04sUUFBTCxDQUFjSyxTQUFkLENBQW5CO0FBQ0EsV0FBT0MsVUFBVSxJQUFJSSxnQkFBRTBFLFVBQUYsQ0FBYTlFLFVBQVUsQ0FBQ3lJLFdBQXhCLENBQWQsSUFBc0R6SSxVQUFVLENBQUN5SSxXQUFYLENBQXVCMUksU0FBdkIsQ0FBN0Q7QUFDRDs7QUFFRDJJLEVBQUFBLGlCQUFpQixDQUFFM0ksU0FBRixFQUFhO0FBQzVCLFVBQU1DLFVBQVUsR0FBRyxLQUFLTixRQUFMLENBQWNLLFNBQWQsQ0FBbkI7QUFDQSxXQUFPQyxVQUFVLEdBQUdBLFVBQVUsQ0FBQzBJLGlCQUFYLEVBQUgsR0FBb0MsRUFBckQ7QUFDRDs7QUFFREMsRUFBQUEsUUFBUSxDQUFFNUksU0FBRixFQUFhO0FBQ25CLFVBQU1DLFVBQVUsR0FBRyxLQUFLTixRQUFMLENBQWNLLFNBQWQsQ0FBbkI7QUFDQSxXQUFPQyxVQUFVLElBQUlBLFVBQVUsQ0FBQzJJLFFBQVgsQ0FBb0I1SSxTQUFwQixDQUFyQjtBQUNEOztBQW5lbUM7Ozs7QUF3ZXRDLFNBQVNtSCxxQkFBVCxDQUFnQ1IsR0FBaEMsRUFBcUM7QUFDbkMsU0FBTyxDQUFDLHdDQUFpQkEsR0FBakIsQ0FBRCxJQUEwQkEsR0FBRyxLQUFLLGVBQXpDO0FBQ0QiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgXyBmcm9tICdsb2Rhc2gnO1xuaW1wb3J0IGxvZyBmcm9tICcuL2xvZ2dlcic7XG5pbXBvcnQgeyBnZXRCdWlsZEluZm8sIHVwZGF0ZUJ1aWxkSW5mbywgQVBQSVVNX1ZFUiB9IGZyb20gJy4vY29uZmlnJztcbmltcG9ydCB7IGZpbmRNYXRjaGluZ0RyaXZlciB9IGZyb20gJy4vZHJpdmVycyc7XG5pbXBvcnQgeyBCYXNlRHJpdmVyLCBlcnJvcnMsIGlzU2Vzc2lvbkNvbW1hbmQgfSBmcm9tICdhcHBpdW0tYmFzZS1kcml2ZXInO1xuaW1wb3J0IEIgZnJvbSAnYmx1ZWJpcmQnO1xuaW1wb3J0IEFzeW5jTG9jayBmcm9tICdhc3luYy1sb2NrJztcbmltcG9ydCB7IHBhcnNlQ2Fwc0ZvcklubmVyRHJpdmVyLCBwdWxsU2V0dGluZ3MgfSBmcm9tICcuL3V0aWxzJztcbmltcG9ydCB7IHV0aWwgfSBmcm9tICdhcHBpdW0tc3VwcG9ydCc7XG5cbmNvbnN0IGRlc2lyZWRDYXBhYmlsaXR5Q29uc3RyYWludHMgPSB7XG4gIGF1dG9tYXRpb25OYW1lOiB7XG4gICAgcHJlc2VuY2U6IHRydWUsXG4gICAgaXNTdHJpbmc6IHRydWUsXG4gIH0sXG4gIHBsYXRmb3JtTmFtZToge1xuICAgIHByZXNlbmNlOiB0cnVlLFxuICAgIGlzU3RyaW5nOiB0cnVlLFxuICB9LFxufTtcblxuY29uc3Qgc2Vzc2lvbnNMaXN0R3VhcmQgPSBuZXcgQXN5bmNMb2NrKCk7XG5jb25zdCBwZW5kaW5nRHJpdmVyc0d1YXJkID0gbmV3IEFzeW5jTG9jaygpO1xuXG5jbGFzcyBBcHBpdW1Ecml2ZXIgZXh0ZW5kcyBCYXNlRHJpdmVyIHtcbiAgY29uc3RydWN0b3IgKGFyZ3MpIHtcbiAgICAvLyBJdCBpcyBuZWNlc3NhcnkgdG8gc2V0IGAtLXRtcGAgaGVyZSBzaW5jZSBpdCBzaG91bGQgYmUgc2V0IHRvXG4gICAgLy8gcHJvY2Vzcy5lbnYuQVBQSVVNX1RNUF9ESVIgb25jZSBhdCBhbiBpbml0aWFsIHBvaW50IGluIHRoZSBBcHBpdW0gbGlmZWN5Y2xlLlxuICAgIC8vIFRoZSBwcm9jZXNzIGFyZ3VtZW50IHdpbGwgYmUgcmVmZXJlbmNlZCBieSBCYXNlRHJpdmVyLlxuICAgIC8vIFBsZWFzZSBjYWxsIGFwcGl1bS1zdXBwb3J0LnRlbXBEaXIgbW9kdWxlIHRvIGFwcGx5IHRoaXMgYmVuZWZpdC5cbiAgICBpZiAoYXJncy50bXBEaXIpIHtcbiAgICAgIHByb2Nlc3MuZW52LkFQUElVTV9UTVBfRElSID0gYXJncy50bXBEaXI7XG4gICAgfVxuXG4gICAgc3VwZXIoYXJncyk7XG5cbiAgICB0aGlzLmRlc2lyZWRDYXBDb25zdHJhaW50cyA9IGRlc2lyZWRDYXBhYmlsaXR5Q29uc3RyYWludHM7XG5cbiAgICAvLyB0aGUgbWFpbiBBcHBpdW0gRHJpdmVyIGhhcyBubyBuZXcgY29tbWFuZCB0aW1lb3V0XG4gICAgdGhpcy5uZXdDb21tYW5kVGltZW91dE1zID0gMDtcblxuICAgIHRoaXMuYXJncyA9IE9iamVjdC5hc3NpZ24oe30sIGFyZ3MpO1xuXG4gICAgLy8gQWNjZXNzIHRvIHNlc3Npb25zIGxpc3QgbXVzdCBiZSBndWFyZGVkIHdpdGggYSBTZW1hcGhvcmUsIGJlY2F1c2VcbiAgICAvLyBpdCBtaWdodCBiZSBjaGFuZ2VkIGJ5IG90aGVyIGFzeW5jIGNhbGxzIGF0IGFueSB0aW1lXG4gICAgLy8gSXQgaXMgbm90IHJlY29tbWVuZGVkIHRvIGFjY2VzcyB0aGlzIHByb3BlcnR5IGRpcmVjdGx5IGZyb20gdGhlIG91dHNpZGVcbiAgICB0aGlzLnNlc3Npb25zID0ge307XG5cbiAgICAvLyBBY2Nlc3MgdG8gcGVuZGluZyBkcml2ZXJzIGxpc3QgbXVzdCBiZSBndWFyZGVkIHdpdGggYSBTZW1hcGhvcmUsIGJlY2F1c2VcbiAgICAvLyBpdCBtaWdodCBiZSBjaGFuZ2VkIGJ5IG90aGVyIGFzeW5jIGNhbGxzIGF0IGFueSB0aW1lXG4gICAgLy8gSXQgaXMgbm90IHJlY29tbWVuZGVkIHRvIGFjY2VzcyB0aGlzIHByb3BlcnR5IGRpcmVjdGx5IGZyb20gdGhlIG91dHNpZGVcbiAgICB0aGlzLnBlbmRpbmdEcml2ZXJzID0ge307XG5cbiAgICB0aGlzLnBsdWdpbnMgPSBbXTtcblxuICAgIC8vIGFsbG93IHRoaXMgdG8gaGFwcGVuIGluIHRoZSBiYWNrZ3JvdW5kLCBzbyBubyBgYXdhaXRgXG4gICAgdXBkYXRlQnVpbGRJbmZvKCk7XG4gIH1cblxuICAvKipcbiAgICogQ2FuY2VsIGNvbW1hbmRzIHF1ZXVlaW5nIGZvciB0aGUgdW1icmVsbGEgQXBwaXVtIGRyaXZlclxuICAgKi9cbiAgZ2V0IGlzQ29tbWFuZHNRdWV1ZUVuYWJsZWQgKCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHNlc3Npb25FeGlzdHMgKHNlc3Npb25JZCkge1xuICAgIGNvbnN0IGRzdFNlc3Npb24gPSB0aGlzLnNlc3Npb25zW3Nlc3Npb25JZF07XG4gICAgcmV0dXJuIGRzdFNlc3Npb24gJiYgZHN0U2Vzc2lvbi5zZXNzaW9uSWQgIT09IG51bGw7XG4gIH1cblxuICBkcml2ZXJGb3JTZXNzaW9uIChzZXNzaW9uSWQpIHtcbiAgICByZXR1cm4gdGhpcy5zZXNzaW9uc1tzZXNzaW9uSWRdO1xuICB9XG5cbiAgYXN5bmMgZ2V0U3RhdHVzICgpIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSByZXF1aXJlLWF3YWl0XG4gICAgcmV0dXJuIHtcbiAgICAgIGJ1aWxkOiBfLmNsb25lKGdldEJ1aWxkSW5mbygpKSxcbiAgICB9O1xuICB9XG5cbiAgYXN5bmMgZ2V0U2Vzc2lvbnMgKCkge1xuICAgIGNvbnN0IHNlc3Npb25zID0gYXdhaXQgc2Vzc2lvbnNMaXN0R3VhcmQuYWNxdWlyZShBcHBpdW1Ecml2ZXIubmFtZSwgKCkgPT4gdGhpcy5zZXNzaW9ucyk7XG4gICAgcmV0dXJuIF8udG9QYWlycyhzZXNzaW9ucylcbiAgICAgIC5tYXAoKFtpZCwgZHJpdmVyXSkgPT4gKHtpZCwgY2FwYWJpbGl0aWVzOiBkcml2ZXIuY2Fwc30pKTtcbiAgfVxuXG4gIHByaW50TmV3U2Vzc2lvbkFubm91bmNlbWVudCAoZHJpdmVyTmFtZSwgZHJpdmVyVmVyc2lvbikge1xuICAgIGNvbnN0IGludHJvU3RyaW5nID0gZHJpdmVyVmVyc2lvblxuICAgICAgPyBgQXBwaXVtIHYke0FQUElVTV9WRVJ9IGNyZWF0aW5nIG5ldyAke2RyaXZlck5hbWV9ICh2JHtkcml2ZXJWZXJzaW9ufSkgc2Vzc2lvbmBcbiAgICAgIDogYEFwcGl1bSB2JHtBUFBJVU1fVkVSfSBjcmVhdGluZyBuZXcgJHtkcml2ZXJOYW1lfSBzZXNzaW9uYDtcbiAgICBsb2cuaW5mbyhpbnRyb1N0cmluZyk7XG4gIH1cblxuICAvKipcbiAgICogVGhpcyBpcyBqdXN0IGFuIGFsaWFzIGZvciBkcml2ZXIuanMncyBtZXRob2QsIHdoaWNoIGlzIG5lY2Vzc2FyeSBmb3JcbiAgICogbW9ja2luZyBpbiB0aGUgdGVzdCBzdWl0ZVxuICAgKi9cbiAgX2ZpbmRNYXRjaGluZ0RyaXZlciAoLi4uYXJncykge1xuICAgIHJldHVybiBmaW5kTWF0Y2hpbmdEcml2ZXIoLi4uYXJncyk7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlIGEgbmV3IHNlc3Npb25cbiAgICogQHBhcmFtIHtPYmplY3R9IGpzb253cENhcHMgSlNPTldQIGZvcm1hdHRlZCBkZXNpcmVkIGNhcGFiaWxpdGllc1xuICAgKiBAcGFyYW0ge09iamVjdH0gcmVxQ2FwcyBSZXF1aXJlZCBjYXBhYmlsaXRpZXMgKEpTT05XUCBzdGFuZGFyZClcbiAgICogQHBhcmFtIHtPYmplY3R9IHczY0NhcGFiaWxpdGllcyBXM0MgY2FwYWJpbGl0aWVzXG4gICAqIEByZXR1cm4ge0FycmF5fSBVbmlxdWUgc2Vzc2lvbiBJRCBhbmQgY2FwYWJpbGl0aWVzXG4gICAqL1xuICBhc3luYyBjcmVhdGVTZXNzaW9uIChqc29ud3BDYXBzLCByZXFDYXBzLCB3M2NDYXBhYmlsaXRpZXMpIHtcbiAgICBjb25zdCBkZWZhdWx0Q2FwYWJpbGl0aWVzID0gXy5jbG9uZURlZXAodGhpcy5hcmdzLmRlZmF1bHRDYXBhYmlsaXRpZXMpO1xuICAgIGNvbnN0IGRlZmF1bHRTZXR0aW5ncyA9IHB1bGxTZXR0aW5ncyhkZWZhdWx0Q2FwYWJpbGl0aWVzKTtcbiAgICBqc29ud3BDYXBzID0gXy5jbG9uZURlZXAoanNvbndwQ2Fwcyk7XG4gICAgY29uc3QgandwU2V0dGluZ3MgPSBPYmplY3QuYXNzaWduKHt9LCBkZWZhdWx0U2V0dGluZ3MsIHB1bGxTZXR0aW5ncyhqc29ud3BDYXBzKSk7XG4gICAgdzNjQ2FwYWJpbGl0aWVzID0gXy5jbG9uZURlZXAodzNjQ2FwYWJpbGl0aWVzKTtcbiAgICAvLyBJdCBpcyBwb3NzaWJsZSB0aGF0IHRoZSBjbGllbnQgb25seSBwcm92aWRlcyBjYXBzIHVzaW5nIEpTT05XUCBzdGFuZGFyZCxcbiAgICAvLyBhbHRob3VnaCBmaXJzdE1hdGNoL2Fsd2F5c01hdGNoIHByb3BlcnRpZXMgYXJlIHN0aWxsIHByZXNlbnQuXG4gICAgLy8gSW4gc3VjaCBjYXNlIHdlIGFzc3VtZSB0aGUgY2xpZW50IHVuZGVyc3RhbmRzIFczQyBwcm90b2NvbCBhbmQgbWVyZ2UgdGhlIGdpdmVuXG4gICAgLy8gSlNPTldQIGNhcHMgdG8gVzNDIGNhcHNcbiAgICBjb25zdCB3M2NTZXR0aW5ncyA9IE9iamVjdC5hc3NpZ24oe30sIGp3cFNldHRpbmdzKTtcbiAgICBPYmplY3QuYXNzaWduKHczY1NldHRpbmdzLCBwdWxsU2V0dGluZ3MoKHczY0NhcGFiaWxpdGllcyB8fCB7fSkuYWx3YXlzTWF0Y2ggfHwge30pKTtcbiAgICBmb3IgKGNvbnN0IGZpcnN0TWF0Y2hFbnRyeSBvZiAoKHczY0NhcGFiaWxpdGllcyB8fCB7fSkuZmlyc3RNYXRjaCB8fCBbXSkpIHtcbiAgICAgIE9iamVjdC5hc3NpZ24odzNjU2V0dGluZ3MsIHB1bGxTZXR0aW5ncyhmaXJzdE1hdGNoRW50cnkpKTtcbiAgICB9XG5cbiAgICBsZXQgcHJvdG9jb2w7XG4gICAgbGV0IGlubmVyU2Vzc2lvbklkLCBkQ2FwcztcbiAgICB0cnkge1xuICAgICAgLy8gUGFyc2UgdGhlIGNhcHMgaW50byBhIGZvcm1hdCB0aGF0IHRoZSBJbm5lckRyaXZlciB3aWxsIGFjY2VwdFxuICAgICAgY29uc3QgcGFyc2VkQ2FwcyA9IHBhcnNlQ2Fwc0ZvcklubmVyRHJpdmVyKFxuICAgICAgICBqc29ud3BDYXBzLFxuICAgICAgICB3M2NDYXBhYmlsaXRpZXMsXG4gICAgICAgIHRoaXMuZGVzaXJlZENhcENvbnN0cmFpbnRzLFxuICAgICAgICBkZWZhdWx0Q2FwYWJpbGl0aWVzXG4gICAgICApO1xuXG4gICAgICBjb25zdCB7ZGVzaXJlZENhcHMsIHByb2Nlc3NlZEpzb253cENhcGFiaWxpdGllcywgcHJvY2Vzc2VkVzNDQ2FwYWJpbGl0aWVzLCBlcnJvcn0gPSBwYXJzZWRDYXBzO1xuICAgICAgcHJvdG9jb2wgPSBwYXJzZWRDYXBzLnByb3RvY29sO1xuXG4gICAgICAvLyBJZiB0aGUgcGFyc2luZyBvZiB0aGUgY2FwcyBwcm9kdWNlZCBhbiBlcnJvciwgdGhyb3cgaXQgaW4gaGVyZVxuICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgIHRocm93IGVycm9yO1xuICAgICAgfVxuXG4gICAgICBjb25zdCB7XG4gICAgICAgIGRyaXZlcjogSW5uZXJEcml2ZXIsXG4gICAgICAgIHZlcnNpb246IGRyaXZlclZlcnNpb25cbiAgICAgIH0gPSB0aGlzLl9maW5kTWF0Y2hpbmdEcml2ZXIodGhpcy5kcml2ZXJDb25maWcsIGRlc2lyZWRDYXBzKTtcbiAgICAgIHRoaXMucHJpbnROZXdTZXNzaW9uQW5ub3VuY2VtZW50KElubmVyRHJpdmVyLm5hbWUsIGRyaXZlclZlcnNpb24pO1xuXG4gICAgICBpZiAodGhpcy5hcmdzLnNlc3Npb25PdmVycmlkZSkge1xuICAgICAgICBhd2FpdCB0aGlzLmRlbGV0ZUFsbFNlc3Npb25zKCk7XG4gICAgICB9XG5cbiAgICAgIGxldCBydW5uaW5nRHJpdmVyc0RhdGEsIG90aGVyUGVuZGluZ0RyaXZlcnNEYXRhO1xuICAgICAgY29uc3QgZCA9IG5ldyBJbm5lckRyaXZlcih0aGlzLmFyZ3MpO1xuXG4gICAgICAvLyBXZSB3YW50IHRvIGFzc2lnbiBzZWN1cml0eSB2YWx1ZXMgZGlyZWN0bHkgb24gdGhlIGRyaXZlci4gVGhlIGRyaXZlclxuICAgICAgLy8gc2hvdWxkIG5vdCByZWFkIHNlY3VyaXR5IHZhbHVlcyBmcm9tIGB0aGlzLm9wdHNgIGJlY2F1c2UgdGhvc2UgdmFsdWVzXG4gICAgICAvLyBjb3VsZCBoYXZlIGJlZW4gc2V0IGJ5IGEgbWFsaWNpb3VzIHVzZXIgdmlhIGNhcGFiaWxpdGllcywgd2hlcmVhcyB3ZVxuICAgICAgLy8gd2FudCBhIGd1YXJhbnRlZSB0aGUgdmFsdWVzIHdlcmUgc2V0IGJ5IHRoZSBhcHBpdW0gc2VydmVyIGFkbWluXG4gICAgICBpZiAodGhpcy5hcmdzLnJlbGF4ZWRTZWN1cml0eUVuYWJsZWQpIHtcbiAgICAgICAgbG9nLmluZm8oYEFwcGx5aW5nIHJlbGF4ZWQgc2VjdXJpdHkgdG8gJyR7SW5uZXJEcml2ZXIubmFtZX0nIGFzIHBlciBgICtcbiAgICAgICAgICAgICAgICAgYHNlcnZlciBjb21tYW5kIGxpbmUgYXJndW1lbnQuIEFsbCBpbnNlY3VyZSBmZWF0dXJlcyB3aWxsIGJlIGAgK1xuICAgICAgICAgICAgICAgICBgZW5hYmxlZCB1bmxlc3MgZXhwbGljaXRseSBkaXNhYmxlZCBieSAtLWRlbnktaW5zZWN1cmVgKTtcbiAgICAgICAgZC5yZWxheGVkU2VjdXJpdHlFbmFibGVkID0gdHJ1ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKCFfLmlzRW1wdHkodGhpcy5hcmdzLmRlbnlJbnNlY3VyZSkpIHtcbiAgICAgICAgbG9nLmluZm8oJ0V4cGxpY2l0bHkgcHJldmVudGluZyB1c2Ugb2YgaW5zZWN1cmUgZmVhdHVyZXM6Jyk7XG4gICAgICAgIHRoaXMuYXJncy5kZW55SW5zZWN1cmUubWFwKChhKSA9PiBsb2cuaW5mbyhgICAgICR7YX1gKSk7XG4gICAgICAgIGQuZGVueUluc2VjdXJlID0gdGhpcy5hcmdzLmRlbnlJbnNlY3VyZTtcbiAgICAgIH1cblxuICAgICAgaWYgKCFfLmlzRW1wdHkodGhpcy5hcmdzLmFsbG93SW5zZWN1cmUpKSB7XG4gICAgICAgIGxvZy5pbmZvKCdFeHBsaWNpdGx5IGVuYWJsaW5nIHVzZSBvZiBpbnNlY3VyZSBmZWF0dXJlczonKTtcbiAgICAgICAgdGhpcy5hcmdzLmFsbG93SW5zZWN1cmUubWFwKChhKSA9PiBsb2cuaW5mbyhgICAgICR7YX1gKSk7XG4gICAgICAgIGQuYWxsb3dJbnNlY3VyZSA9IHRoaXMuYXJncy5hbGxvd0luc2VjdXJlO1xuICAgICAgfVxuXG4gICAgICAvLyBUaGlzIGFzc2lnbm1lbnQgaXMgcmVxdWlyZWQgZm9yIGNvcnJlY3Qgd2ViIHNvY2tldHMgZnVuY3Rpb25hbGl0eSBpbnNpZGUgdGhlIGRyaXZlclxuICAgICAgZC5zZXJ2ZXIgPSB0aGlzLnNlcnZlcjtcbiAgICAgIHRyeSB7XG4gICAgICAgIHJ1bm5pbmdEcml2ZXJzRGF0YSA9IGF3YWl0IHRoaXMuY3VyU2Vzc2lvbkRhdGFGb3JEcml2ZXIoSW5uZXJEcml2ZXIpO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICB0aHJvdyBuZXcgZXJyb3JzLlNlc3Npb25Ob3RDcmVhdGVkRXJyb3IoZS5tZXNzYWdlKTtcbiAgICAgIH1cbiAgICAgIGF3YWl0IHBlbmRpbmdEcml2ZXJzR3VhcmQuYWNxdWlyZShBcHBpdW1Ecml2ZXIubmFtZSwgKCkgPT4ge1xuICAgICAgICB0aGlzLnBlbmRpbmdEcml2ZXJzW0lubmVyRHJpdmVyLm5hbWVdID0gdGhpcy5wZW5kaW5nRHJpdmVyc1tJbm5lckRyaXZlci5uYW1lXSB8fCBbXTtcbiAgICAgICAgb3RoZXJQZW5kaW5nRHJpdmVyc0RhdGEgPSB0aGlzLnBlbmRpbmdEcml2ZXJzW0lubmVyRHJpdmVyLm5hbWVdLm1hcCgoZHJ2KSA9PiBkcnYuZHJpdmVyRGF0YSk7XG4gICAgICAgIHRoaXMucGVuZGluZ0RyaXZlcnNbSW5uZXJEcml2ZXIubmFtZV0ucHVzaChkKTtcbiAgICAgIH0pO1xuXG4gICAgICB0cnkge1xuICAgICAgICBbaW5uZXJTZXNzaW9uSWQsIGRDYXBzXSA9IGF3YWl0IGQuY3JlYXRlU2Vzc2lvbihcbiAgICAgICAgICBwcm9jZXNzZWRKc29ud3BDYXBhYmlsaXRpZXMsXG4gICAgICAgICAgcmVxQ2FwcyxcbiAgICAgICAgICBwcm9jZXNzZWRXM0NDYXBhYmlsaXRpZXMsXG4gICAgICAgICAgWy4uLnJ1bm5pbmdEcml2ZXJzRGF0YSwgLi4ub3RoZXJQZW5kaW5nRHJpdmVyc0RhdGFdXG4gICAgICAgICk7XG4gICAgICAgIHByb3RvY29sID0gZC5wcm90b2NvbDtcbiAgICAgICAgYXdhaXQgc2Vzc2lvbnNMaXN0R3VhcmQuYWNxdWlyZShBcHBpdW1Ecml2ZXIubmFtZSwgKCkgPT4ge1xuICAgICAgICAgIHRoaXMuc2Vzc2lvbnNbaW5uZXJTZXNzaW9uSWRdID0gZDtcbiAgICAgICAgfSk7XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICBhd2FpdCBwZW5kaW5nRHJpdmVyc0d1YXJkLmFjcXVpcmUoQXBwaXVtRHJpdmVyLm5hbWUsICgpID0+IHtcbiAgICAgICAgICBfLnB1bGwodGhpcy5wZW5kaW5nRHJpdmVyc1tJbm5lckRyaXZlci5uYW1lXSwgZCk7XG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICB0aGlzLmF0dGFjaFVuZXhwZWN0ZWRTaHV0ZG93bkhhbmRsZXIoZCwgaW5uZXJTZXNzaW9uSWQpO1xuXG4gICAgICBsb2cuaW5mbyhgTmV3ICR7SW5uZXJEcml2ZXIubmFtZX0gc2Vzc2lvbiBjcmVhdGVkIHN1Y2Nlc3NmdWxseSwgc2Vzc2lvbiBgICtcbiAgICAgICAgICAgICAgYCR7aW5uZXJTZXNzaW9uSWR9IGFkZGVkIHRvIG1hc3RlciBzZXNzaW9uIGxpc3RgKTtcblxuICAgICAgLy8gc2V0IHRoZSBOZXcgQ29tbWFuZCBUaW1lb3V0IGZvciB0aGUgaW5uZXIgZHJpdmVyXG4gICAgICBkLnN0YXJ0TmV3Q29tbWFuZFRpbWVvdXQoKTtcblxuICAgICAgLy8gYXBwbHkgaW5pdGlhbCB2YWx1ZXMgdG8gQXBwaXVtIHNldHRpbmdzIChpZiBwcm92aWRlZClcbiAgICAgIGlmIChkLmlzVzNDUHJvdG9jb2woKSAmJiAhXy5pc0VtcHR5KHczY1NldHRpbmdzKSkge1xuICAgICAgICBsb2cuaW5mbyhgQXBwbHlpbmcgdGhlIGluaXRpYWwgdmFsdWVzIHRvIEFwcGl1bSBzZXR0aW5ncyBwYXJzZWQgZnJvbSBXM0MgY2FwczogYCArXG4gICAgICAgICAgSlNPTi5zdHJpbmdpZnkodzNjU2V0dGluZ3MpKTtcbiAgICAgICAgYXdhaXQgZC51cGRhdGVTZXR0aW5ncyh3M2NTZXR0aW5ncyk7XG4gICAgICB9IGVsc2UgaWYgKGQuaXNNanNvbndwUHJvdG9jb2woKSAmJiAhXy5pc0VtcHR5KGp3cFNldHRpbmdzKSkge1xuICAgICAgICBsb2cuaW5mbyhgQXBwbHlpbmcgdGhlIGluaXRpYWwgdmFsdWVzIHRvIEFwcGl1bSBzZXR0aW5ncyBwYXJzZWQgZnJvbSBNSlNPTldQIGNhcHM6IGAgK1xuICAgICAgICAgIEpTT04uc3RyaW5naWZ5KGp3cFNldHRpbmdzKSk7XG4gICAgICAgIGF3YWl0IGQudXBkYXRlU2V0dGluZ3MoandwU2V0dGluZ3MpO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBwcm90b2NvbCxcbiAgICAgICAgZXJyb3IsXG4gICAgICB9O1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICBwcm90b2NvbCxcbiAgICAgIHZhbHVlOiBbaW5uZXJTZXNzaW9uSWQsIGRDYXBzLCBwcm90b2NvbF1cbiAgICB9O1xuICB9XG5cbiAgYXR0YWNoVW5leHBlY3RlZFNodXRkb3duSGFuZGxlciAoZHJpdmVyLCBpbm5lclNlc3Npb25JZCkge1xuICAgIGNvbnN0IHJlbW92ZVNlc3Npb25Gcm9tTWFzdGVyTGlzdCA9IChjYXVzZSA9IG5ldyBFcnJvcignVW5rbm93biBlcnJvcicpKSA9PiB7XG4gICAgICBsb2cud2FybihgQ2xvc2luZyBzZXNzaW9uLCBjYXVzZSB3YXMgJyR7Y2F1c2UubWVzc2FnZX0nYCk7XG4gICAgICBsb2cuaW5mbyhgUmVtb3Zpbmcgc2Vzc2lvbiAnJHtpbm5lclNlc3Npb25JZH0nIGZyb20gb3VyIG1hc3RlciBzZXNzaW9uIGxpc3RgKTtcbiAgICAgIGRlbGV0ZSB0aGlzLnNlc3Npb25zW2lubmVyU2Vzc2lvbklkXTtcbiAgICB9O1xuXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHByb21pc2UvcHJlZmVyLWF3YWl0LXRvLXRoZW5cbiAgICBpZiAoXy5pc0Z1bmN0aW9uKChkcml2ZXIub25VbmV4cGVjdGVkU2h1dGRvd24gfHwge30pLnRoZW4pKSB7XG4gICAgICAvLyBUT0RPOiBSZW1vdmUgdGhpcyBibG9jayBhZnRlciBhbGwgdGhlIGRyaXZlcnMgdXNlIGJhc2UgZHJpdmVyIGFib3ZlIHYgNS4wLjBcbiAgICAgIC8vIFJlbW92ZSB0aGUgc2Vzc2lvbiBvbiB1bmV4cGVjdGVkIHNodXRkb3duLCBzbyB0aGF0IHdlIGFyZSBpbiBhIHBvc2l0aW9uXG4gICAgICAvLyB0byBvcGVuIGFub3RoZXIgc2Vzc2lvbiBsYXRlciBvbi5cbiAgICAgIGRyaXZlci5vblVuZXhwZWN0ZWRTaHV0ZG93blxuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgcHJvbWlzZS9wcmVmZXItYXdhaXQtdG8tdGhlblxuICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgLy8gaWYgd2UgZ2V0IGhlcmUsIHdlJ3ZlIGhhZCBhbiB1bmV4cGVjdGVkIHNodXRkb3duLCBzbyBlcnJvclxuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignVW5leHBlY3RlZCBzaHV0ZG93bicpO1xuICAgICAgICB9KVxuICAgICAgICAuY2F0Y2goKGUpID0+IHtcbiAgICAgICAgICAvLyBpZiB3ZSBjYW5jZWxsZWQgdGhlIHVuZXhwZWN0ZWQgc2h1dGRvd24gcHJvbWlzZSwgdGhhdCBtZWFucyB3ZVxuICAgICAgICAgIC8vIG5vIGxvbmdlciBjYXJlIGFib3V0IGl0LCBhbmQgY2FuIHNhZmVseSBpZ25vcmUgaXRcbiAgICAgICAgICBpZiAoIShlIGluc3RhbmNlb2YgQi5DYW5jZWxsYXRpb25FcnJvcikpIHtcbiAgICAgICAgICAgIHJlbW92ZVNlc3Npb25Gcm9tTWFzdGVyTGlzdChlKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pOyAvLyB0aGlzIGlzIGEgY2FuY2VsbGFibGUgcHJvbWlzZVxuICAgIH0gZWxzZSBpZiAoXy5pc0Z1bmN0aW9uKGRyaXZlci5vblVuZXhwZWN0ZWRTaHV0ZG93bikpIHtcbiAgICAgIC8vIHNpbmNlIGJhc2UgZHJpdmVyIHYgNS4wLjBcbiAgICAgIGRyaXZlci5vblVuZXhwZWN0ZWRTaHV0ZG93bihyZW1vdmVTZXNzaW9uRnJvbU1hc3Rlckxpc3QpO1xuICAgIH0gZWxzZSB7XG4gICAgICBsb2cud2FybihgRmFpbGVkIHRvIGF0dGFjaCB0aGUgdW5leHBlY3RlZCBzaHV0ZG93biBsaXN0ZW5lci4gYCArXG4gICAgICAgIGBJcyAnb25VbmV4cGVjdGVkU2h1dGRvd24nIG1ldGhvZCBhdmFpbGFibGUgZm9yICcke2RyaXZlci5jb25zdHJ1Y3Rvci5uYW1lfSc/YCk7XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgY3VyU2Vzc2lvbkRhdGFGb3JEcml2ZXIgKElubmVyRHJpdmVyKSB7XG4gICAgY29uc3Qgc2Vzc2lvbnMgPSBhd2FpdCBzZXNzaW9uc0xpc3RHdWFyZC5hY3F1aXJlKEFwcGl1bURyaXZlci5uYW1lLCAoKSA9PiB0aGlzLnNlc3Npb25zKTtcbiAgICBjb25zdCBkYXRhID0gXy52YWx1ZXMoc2Vzc2lvbnMpXG4gICAgICAgICAgICAgICAgICAgLmZpbHRlcigocykgPT4gcy5jb25zdHJ1Y3Rvci5uYW1lID09PSBJbm5lckRyaXZlci5uYW1lKVxuICAgICAgICAgICAgICAgICAgIC5tYXAoKHMpID0+IHMuZHJpdmVyRGF0YSk7XG4gICAgZm9yIChsZXQgZGF0dW0gb2YgZGF0YSkge1xuICAgICAgaWYgKCFkYXR1bSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFByb2JsZW0gZ2V0dGluZyBzZXNzaW9uIGRhdGEgZm9yIGRyaXZlciB0eXBlIGAgK1xuICAgICAgICAgICAgICAgICAgICAgICAgYCR7SW5uZXJEcml2ZXIubmFtZX07IGRvZXMgaXQgaW1wbGVtZW50ICdnZXQgYCArXG4gICAgICAgICAgICAgICAgICAgICAgICBgZHJpdmVyRGF0YSc/YCk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBkYXRhO1xuICB9XG5cbiAgYXN5bmMgZGVsZXRlU2Vzc2lvbiAoc2Vzc2lvbklkKSB7XG4gICAgbGV0IHByb3RvY29sO1xuICAgIHRyeSB7XG4gICAgICBsZXQgb3RoZXJTZXNzaW9uc0RhdGEgPSBudWxsO1xuICAgICAgbGV0IGRzdFNlc3Npb24gPSBudWxsO1xuICAgICAgYXdhaXQgc2Vzc2lvbnNMaXN0R3VhcmQuYWNxdWlyZShBcHBpdW1Ecml2ZXIubmFtZSwgKCkgPT4ge1xuICAgICAgICBpZiAoIXRoaXMuc2Vzc2lvbnNbc2Vzc2lvbklkXSkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBjdXJDb25zdHJ1Y3Rvck5hbWUgPSB0aGlzLnNlc3Npb25zW3Nlc3Npb25JZF0uY29uc3RydWN0b3IubmFtZTtcbiAgICAgICAgb3RoZXJTZXNzaW9uc0RhdGEgPSBfLnRvUGFpcnModGhpcy5zZXNzaW9ucylcbiAgICAgICAgICAgICAgLmZpbHRlcigoW2tleSwgdmFsdWVdKSA9PiB2YWx1ZS5jb25zdHJ1Y3Rvci5uYW1lID09PSBjdXJDb25zdHJ1Y3Rvck5hbWUgJiYga2V5ICE9PSBzZXNzaW9uSWQpXG4gICAgICAgICAgICAgIC5tYXAoKFssIHZhbHVlXSkgPT4gdmFsdWUuZHJpdmVyRGF0YSk7XG4gICAgICAgIGRzdFNlc3Npb24gPSB0aGlzLnNlc3Npb25zW3Nlc3Npb25JZF07XG4gICAgICAgIHByb3RvY29sID0gZHN0U2Vzc2lvbi5wcm90b2NvbDtcbiAgICAgICAgbG9nLmluZm8oYFJlbW92aW5nIHNlc3Npb24gJHtzZXNzaW9uSWR9IGZyb20gb3VyIG1hc3RlciBzZXNzaW9uIGxpc3RgKTtcbiAgICAgICAgLy8gcmVnYXJkbGVzcyBvZiB3aGV0aGVyIHRoZSBkZWxldGVTZXNzaW9uIGNvbXBsZXRlcyBzdWNjZXNzZnVsbHkgb3Igbm90XG4gICAgICAgIC8vIG1ha2UgdGhlIHNlc3Npb24gdW5hdmFpbGFibGUsIGJlY2F1c2Ugd2hvIGtub3dzIHdoYXQgc3RhdGUgaXQgbWlnaHRcbiAgICAgICAgLy8gYmUgaW4gb3RoZXJ3aXNlXG4gICAgICAgIGRlbGV0ZSB0aGlzLnNlc3Npb25zW3Nlc3Npb25JZF07XG4gICAgICB9KTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHByb3RvY29sLFxuICAgICAgICB2YWx1ZTogYXdhaXQgZHN0U2Vzc2lvbi5kZWxldGVTZXNzaW9uKHNlc3Npb25JZCwgb3RoZXJTZXNzaW9uc0RhdGEpLFxuICAgICAgfTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBsb2cuZXJyb3IoYEhhZCB0cm91YmxlIGVuZGluZyBzZXNzaW9uICR7c2Vzc2lvbklkfTogJHtlLm1lc3NhZ2V9YCk7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBwcm90b2NvbCxcbiAgICAgICAgZXJyb3I6IGUsXG4gICAgICB9O1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIGRlbGV0ZUFsbFNlc3Npb25zIChvcHRzID0ge30pIHtcbiAgICBjb25zdCBzZXNzaW9uc0NvdW50ID0gXy5zaXplKHRoaXMuc2Vzc2lvbnMpO1xuICAgIGlmICgwID09PSBzZXNzaW9uc0NvdW50KSB7XG4gICAgICBsb2cuZGVidWcoJ1RoZXJlIGFyZSBubyBhY3RpdmUgc2Vzc2lvbnMgZm9yIGNsZWFudXAnKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCB7XG4gICAgICBmb3JjZSA9IGZhbHNlLFxuICAgICAgcmVhc29uLFxuICAgIH0gPSBvcHRzO1xuICAgIGxvZy5kZWJ1ZyhgQ2xlYW5pbmcgdXAgJHt1dGlsLnBsdXJhbGl6ZSgnYWN0aXZlIHNlc3Npb24nLCBzZXNzaW9uc0NvdW50LCB0cnVlKX1gKTtcbiAgICBjb25zdCBjbGVhbnVwUHJvbWlzZXMgPSBmb3JjZVxuICAgICAgPyBfLnZhbHVlcyh0aGlzLnNlc3Npb25zKS5tYXAoKGRydikgPT4gZHJ2LnN0YXJ0VW5leHBlY3RlZFNodXRkb3duKHJlYXNvbiAmJiBuZXcgRXJyb3IocmVhc29uKSkpXG4gICAgICA6IF8ua2V5cyh0aGlzLnNlc3Npb25zKS5tYXAoKGlkKSA9PiB0aGlzLmRlbGV0ZVNlc3Npb24oaWQpKTtcbiAgICBmb3IgKGNvbnN0IGNsZWFudXBQcm9taXNlIG9mIGNsZWFudXBQcm9taXNlcykge1xuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgY2xlYW51cFByb21pc2U7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGxvZy5kZWJ1ZyhlKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwbHVnaW5zVG9IYW5kbGVDbWQgKGNtZCkge1xuICAgIHJldHVybiB0aGlzLnBsdWdpbnMuZmlsdGVyKChwKSA9PlxuICAgICAgcC5jb21tYW5kcyA9PT0gdHJ1ZSB8fFxuICAgICAgKF8uaXNBcnJheShwLmNvbW1hbmRzKSAmJiBfLmluY2x1ZGVzKHAuY29tbWFuZHMsIGNtZCkpXG4gICAgKTtcbiAgfVxuXG4gIGFzeW5jIGV4ZWN1dGVDb21tYW5kIChjbWQsIC4uLmFyZ3MpIHtcbiAgICAvLyBXZSBoYXZlIGJhc2ljYWxseSB0aHJlZSBjYXNlcyBmb3IgaG93IHRvIGhhbmRsZSBjb21tYW5kczpcbiAgICAvLyAxLiBoYW5kbGUgZ2V0U3RhdHVzICh3ZSBkbyB0aGlzIGFzIGEgc3BlY2lhbCBvdXQgb2YgYmFuZCBjYXNlIHNvIGl0IGRvZXNuJ3QgZ2V0IGFkZGVkIHRvIGFuXG4gICAgLy8gICAgZXhlY3V0aW9uIHF1ZXVlLCBhbmQgY2FuIGJlIGNhbGxlZCB3aGlsZSBlLmcuIGNyZWF0ZVNlc3Npb24gaXMgaW4gcHJvZ3Jlc3MpXG4gICAgLy8gMi4gaGFuZGxlIGNvbW1hbmRzIHRoYXQgdGhpcyB1bWJyZWxsYSBkcml2ZXIgc2hvdWxkIGhhbmRsZSwgcmF0aGVyIHRoYW4gdGhlIGFjdHVhbCBzZXNzaW9uXG4gICAgLy8gICAgZHJpdmVyIChmb3IgZXhhbXBsZSwgZGVsZXRlU2Vzc2lvbiwgb3Igb3RoZXIgbm9uLXNlc3Npb24gY29tbWFuZHMpXG4gICAgLy8gMy4gaGFuZGxlIHNlc3Npb24gZHJpdmVyIGNvbW1hbmRzLlxuICAgIC8vIFRoZSB0cmlja3kgcGFydCBpcyB0aGF0IGJlY2F1c2Ugd2Ugc3VwcG9ydCBjb21tYW5kIHBsdWdpbnMsIHdlIG5lZWQgdG8gd3JhcCBhbnkgb2YgdGhlc2VcbiAgICAvLyBjYXNlcyB3aXRoIHBsdWdpbiBoYW5kbGluZy5cblxuICAgIGNvbnN0IGlzR2V0U3RhdHVzID0gY21kID09PSAnZ2V0U3RhdHVzJztcbiAgICBjb25zdCBpc1VtYnJlbGxhQ21kID0gIWlzR2V0U3RhdHVzICYmIGlzQXBwaXVtRHJpdmVyQ29tbWFuZChjbWQpO1xuICAgIGNvbnN0IGlzU2Vzc2lvbkNtZCA9ICFpc0dldFN0YXR1cyAmJiAhaXNVbWJyZWxsYUNtZDtcblxuICAgIC8vIGdldCBhbnkgcGx1Z2lucyB3aGljaCBhcmUgcmVnaXN0ZXJlZCBhcyBoYW5kbGluZyB0aGlzIGNvbW1hbmRcbiAgICBjb25zdCBwbHVnaW5zID0gdGhpcy5wbHVnaW5zVG9IYW5kbGVDbWQoY21kKTtcblxuICAgIC8vIGZpcnN0IGRvIHNvbWUgZXJyb3IgY2hlY2tpbmcuIElmIHdlJ3JlIHJlcXVlc3RpbmcgYSBzZXNzaW9uIGNvbW1hbmQgZXhlY3V0aW9uLCB0aGVuIG1ha2VcbiAgICAvLyBzdXJlIHRoYXQgc2Vzc2lvbiBhY3R1YWxseSBleGlzdHMgb24gdGhlIHNlc3Npb24gZHJpdmVyLCBhbmQgc2V0IHRoZSBzZXNzaW9uIGRyaXZlciBpdHNlbGZcbiAgICBsZXQgc2Vzc2lvbklkID0gbnVsbDtcbiAgICBsZXQgZHN0U2Vzc2lvbiA9IG51bGw7XG4gICAgbGV0IHByb3RvY29sID0gbnVsbDtcbiAgICBpZiAoaXNTZXNzaW9uQ21kKSB7XG4gICAgICBzZXNzaW9uSWQgPSBfLmxhc3QoYXJncyk7XG4gICAgICBkc3RTZXNzaW9uID0gYXdhaXQgc2Vzc2lvbnNMaXN0R3VhcmQuYWNxdWlyZShBcHBpdW1Ecml2ZXIubmFtZSwgKCkgPT4gdGhpcy5zZXNzaW9uc1tzZXNzaW9uSWRdKTtcbiAgICAgIGlmICghZHN0U2Vzc2lvbikge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFRoZSBzZXNzaW9uIHdpdGggaWQgJyR7c2Vzc2lvbklkfScgZG9lcyBub3QgZXhpc3RgKTtcbiAgICAgIH1cbiAgICAgIC8vIG5vdyBzYXZlIHRoZSByZXNwb25zZSBwcm90b2NvbCBnaXZlbiB0aGF0IHRoZSBzZXNzaW9uIGRyaXZlcidzIHByb3RvY29sIG1pZ2h0IGRpZmZlclxuICAgICAgcHJvdG9jb2wgPSBkc3RTZXNzaW9uLnByb3RvY29sO1xuICAgIH1cblxuICAgIC8vIG5vdyB3ZSBkZWZpbmUgYSAnY21kSGFuZGxlZEJ5JyBvYmplY3Qgd2hpY2ggd2lsbCBrZWVwIHRyYWNrIG9mIHdoaWNoIHBsdWdpbnMgaGF2ZSBoYW5kbGVkIHRoaXNcbiAgICAvLyBjb21tYW5kLiB3ZSBjYXJlIGFib3V0IHRoaXMgYmVjYXVzZSAoYSkgbXVsdGlwbGUgcGx1Z2lucyBjYW4gaGFuZGxlIHRoZSBzYW1lIGNvbW1hbmQsIGFuZFxuICAgIC8vIChiKSB0aGVyZSdzIG5vIGd1YXJhbnRlZSB0aGF0IGEgcGx1Z2luIHdpbGwgYWN0dWFsbHkgY2FsbCB0aGUgbmV4dCgpIG1ldGhvZCB3aGljaCBydW5zIHRoZVxuICAgIC8vIG9yaWdpbmFsIGNvbW1hbmQgZXhlY3V0aW9uLiBUaGlzIHJlc3VsdHMgaW4gYSBzaXR1YXRpb24gd2hlcmUgdGhlIGNvbW1hbmQgbWlnaHQgYmUgaGFuZGxlZFxuICAgIC8vIGJ5IHNvbWUgYnV0IG5vdCBhbGwgcGx1Z2lucywgb3IgYnkgcGx1Z2luKHMpIGJ1dCBub3QgYnkgdGhlIGRlZmF1bHQgYmVoYXZpb3IuIFNvIHN0YXJ0IG91dFxuICAgIC8vIHRoaXMgb2JqZWN0IGRlY2xhcmluZyB0aGF0IHRoZSBkZWZhdWx0IGhhbmRsZXIgaGFzIG5vdCBiZWVuIGV4ZWN1dGVkLlxuICAgIGNvbnN0IGNtZEhhbmRsZWRCeSA9IHtkZWZhdWx0OiBmYWxzZX07XG5cbiAgICAvLyBub3cgd2UgZGVmaW5lIGFuIGFzeW5jIGZ1bmN0aW9uIHdoaWNoIHdpbGwgYmUgcGFzc2VkIHRvIHBsdWdpbnMsIGFuZCBzdWNjZXNzaXZlbHkgd3JhcHBlZFxuICAgIC8vIGlmIHRoZXJlIGlzIG1vcmUgdGhhbiBvbmUgcGx1Z2luIHRoYXQgY2FuIGhhbmRsZSB0aGUgY29tbWFuZC4gVG8gc3RhcnQgb2ZmIHdpdGgsIHRoZSBhc3luY1xuICAgIC8vIGZ1bmN0aW9uIGlzIGRlZmluZWQgYXMgY2FsbGluZyB0aGUgZGVmYXVsdCBiZWhhdmlvciwgaS5lLiwgd2hpY2hldmVyIG9mIHRoZSAzIGNhc2VzIGFib3ZlIGlzXG4gICAgLy8gdGhlIGFwcHJvcHJpYXRlIG9uZVxuICAgIGNvbnN0IGRlZmF1bHRCZWhhdmlvciA9IGFzeW5jICgpID0+IHtcbiAgICAgIC8vIGlmIHdlJ3JlIHJ1bm5pbmcgd2l0aCBwbHVnaW5zLCBtYWtlIHN1cmUgd2UgbG9nIHRoYXQgdGhlIGRlZmF1bHQgYmVoYXZpb3IgaXMgYWN0dWFsbHlcbiAgICAgIC8vIGhhcHBlbmluZyBzbyB3ZSBjYW4gdGVsbCB3aGVuIHRoZSBwbHVnaW4gY2FsbCBjaGFpbiBpcyB1bndyYXBwaW5nIHRvIHRoZSBkZWZhdWx0IGJlaGF2aW9yXG4gICAgICAvLyBpZiB0aGF0J3Mgd2hhdCBoYXBwZW5zXG4gICAgICBwbHVnaW5zLmxlbmd0aCAmJiBsb2cuaW5mbyhgRXhlY3V0aW5nIGRlZmF1bHQgaGFuZGxpbmcgYmVoYXZpb3IgZm9yIGNvbW1hbmQgJyR7Y21kfSdgKTtcblxuICAgICAgLy8gaWYgd2UgbWFrZSBpdCBoZXJlLCB3ZSBrbm93IHRoYXQgdGhlIGRlZmF1bHQgYmVoYXZpb3IgaXMgaGFuZGxlZFxuICAgICAgY21kSGFuZGxlZEJ5LmRlZmF1bHQgPSB0cnVlO1xuXG4gICAgICBpZiAoaXNHZXRTdGF0dXMpIHtcbiAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuZ2V0U3RhdHVzKCk7XG4gICAgICB9XG5cbiAgICAgIGlmIChpc1VtYnJlbGxhQ21kKSB7XG4gICAgICAgIC8vIHNvbWUgY29tbWFuZHMsIGxpa2UgZGVsZXRlU2Vzc2lvbiwgd2Ugd2FudCB0byBtYWtlIHN1cmUgdG8gaGFuZGxlIG9uICp0aGlzKiBkcml2ZXIsXG4gICAgICAgIC8vIG5vdCB0aGUgcGxhdGZvcm0gZHJpdmVyXG4gICAgICAgIHJldHVybiBhd2FpdCBzdXBlci5leGVjdXRlQ29tbWFuZChjbWQsIC4uLmFyZ3MpO1xuICAgICAgfVxuXG4gICAgICAvLyBoZXJlIHdlIGtub3cgdGhhdCB3ZSBhcmUgZXhlY3V0aW5nIGEgc2Vzc2lvbiBjb21tYW5kLCBhbmQgaGF2ZSBhIHZhbGlkIHNlc3Npb24gZHJpdmVyXG4gICAgICByZXR1cm4gYXdhaXQgZHN0U2Vzc2lvbi5leGVjdXRlQ29tbWFuZChjbWQsIC4uLmFyZ3MpO1xuICAgIH07XG5cbiAgICAvLyBub3cgdGFrZSBvdXIgZGVmYXVsdCBiZWhhdmlvciwgd3JhcCBpdCB3aXRoIGFueSBudW1iZXIgb2YgcGx1Z2luIGJlaGF2aW9ycywgYW5kIHJ1biBpdFxuICAgIGNvbnN0IHdyYXBwZWRDbWQgPSB0aGlzLndyYXBDb21tYW5kV2l0aFBsdWdpbnMoe2NtZCwgYXJncywgcGx1Z2lucywgY21kSGFuZGxlZEJ5LCBuZXh0OiBkZWZhdWx0QmVoYXZpb3J9KTtcbiAgICBjb25zdCByZXMgPSBhd2FpdCB0aGlzLmV4ZWN1dGVXcmFwcGVkQ29tbWFuZCh7d3JhcHBlZENtZCwgcHJvdG9jb2x9KTtcblxuICAgIC8vIGlmIHdlIGhhZCBwbHVnaW5zLCBtYWtlIHN1cmUgdG8gbG9nIG91dCB0aGUgaGVscGZ1bCByZXBvcnQgYWJvdXQgd2hpY2ggcGx1Z2lucyBlbmRlZCB1cFxuICAgIC8vIGhhbmRsaW5nIHRoZSBjb21tYW5kIGFuZCB3aGljaCBkaWRuJ3RcbiAgICBwbHVnaW5zLmxlbmd0aCAmJiB0aGlzLmxvZ1BsdWdpbkhhbmRsZXJSZXBvcnQoe2NtZCwgY21kSGFuZGxlZEJ5fSk7XG5cbiAgICByZXR1cm4gcmVzO1xuICB9XG5cbiAgd3JhcENvbW1hbmRXaXRoUGx1Z2lucyAoe2NtZCwgYXJncywgbmV4dCwgY21kSGFuZGxlZEJ5LCBwbHVnaW5zfSkge1xuICAgIHBsdWdpbnMubGVuZ3RoICYmIGxvZy5pbmZvKGBQbHVnaW5zIHdoaWNoIGNhbiBoYW5kbGUgY21kICcke2NtZH0nOiAke3BsdWdpbnMubWFwKChwKSA9PiBwLm5hbWUpfWApO1xuXG4gICAgLy8gbm93IHdlIGNhbiBnbyB0aHJvdWdoIGVhY2ggcGx1Z2luIGFuZCB3cmFwIGBuZXh0YCBhcm91bmQgaXRzIG93biBoYW5kbGVyLCBwYXNzaW5nIHRoZSAqb2xkKlxuICAgIC8vIG5leHQgaW4gc28gdGhhdCBpdCBjYW4gY2FsbCBpdCBpZiBpdCB3YW50cyB0b1xuICAgIGZvciAoY29uc3QgcGx1Z2luIG9mIHBsdWdpbnMpIHtcbiAgICAgIC8vIG5lZWQgYW4gSUlGRSBoZXJlIGJlY2F1c2Ugd2Ugd2FudCB0aGUgdmFsdWUgb2YgbmV4dCB0aGF0J3MgcGFzc2VkIHRvIHBsdWdpbi5oYW5kbGUgdG8gYmVcbiAgICAgIC8vIGV4YWN0bHkgdGhlIHZhbHVlIG9mIG5leHQgaGVyZSBiZWZvcmUgcmVhc3NpZ25tZW50OyB3ZSBkb24ndCB3YW50IGl0IHRvIGJlIGxhemlseVxuICAgICAgLy8gZXZhbHVhdGVkLCBvdGhlcndpc2Ugd2UgZW5kIHVwIHdpdGggaW5maW5pdGUgcmVjdXJzaW9uIG9mIHRoZSBsYXN0IGBuZXh0YCB0byBiZSBkZWZpbmVkLlxuICAgICAgY21kSGFuZGxlZEJ5W3BsdWdpbi5uYW1lXSA9IGZhbHNlOyAvLyB3ZSBzZWUgYSBuZXcgcGx1Z2luLCBzbyBhZGQgaXQgdG8gdGhlICdjbWRIYW5kbGVkQnknIG9iamVjdFxuICAgICAgbmV4dCA9ICgoX25leHQpID0+IGFzeW5jICgpID0+IHtcbiAgICAgICAgbG9nLmluZm8oYFBsdWdpbiAke3BsdWdpbi5uYW1lfSBpcyBub3cgaGFuZGxpbmcgY21kICcke2NtZH0nYCk7XG4gICAgICAgIGNtZEhhbmRsZWRCeVtwbHVnaW4ubmFtZV0gPSB0cnVlOyAvLyBpZiB3ZSBtYWtlIGl0IGhlcmUsIHRoaXMgcGx1Z2luIGhhcyBhdHRlbXB0ZWQgdG8gaGFuZGxlIGNtZFxuICAgICAgICByZXR1cm4gYXdhaXQgcGx1Z2luLmhhbmRsZShfbmV4dCwgdGhpcywgY21kLCAuLi5hcmdzKTtcbiAgICAgIH0pKG5leHQpO1xuICAgIH1cblxuICAgIHJldHVybiBuZXh0O1xuICB9XG5cbiAgbG9nUGx1Z2luSGFuZGxlclJlcG9ydCAoe2NtZCwgY21kSGFuZGxlZEJ5fSkge1xuICAgIC8vIGF0IHRoZSBlbmQgb2YgdGhlIGRheSwgd2UgaGF2ZSBhbiBvYmplY3QgcmVwcmVzZW50aW5nIHdoaWNoIHBsdWdpbnMgZW5kZWQgdXAgZ2V0dGluZ1xuICAgIC8vIHRoZWlyIGNvZGUgcnVuIGFzIHBhcnQgb2YgaGFuZGxpbmcgdGhpcyBjb21tYW5kLiBCZWNhdXNlIHBsdWdpbnMgY2FuIGNob29zZSAqbm90KiB0b1xuICAgIC8vIHBhc3MgY29udHJvbCB0byBvdGhlciBwbHVnaW5zIG9yIHRvIHRoZSBkZWZhdWx0IGRyaXZlciBiZWhhdmlvciwgdGhpcyBpcyBpbmZvcm1hdGlvblxuICAgIC8vIHdoaWNoIGlzIHByb2JhYmx5IHVzZWZ1bCB0byB0aGUgdXNlciAoZXNwZWNpYWxseSBpbiBzaXR1YXRpb25zIHdoZXJlIHBsdWdpbnMgbWlnaHQgbm90XG4gICAgLy8gaW50ZXJhY3Qgd2VsbCB0b2dldGhlciwgYW5kIGl0IHdvdWxkIGJlIGhhcmQgdG8gZGVidWcgb3RoZXJ3aXNlIHdpdGhvdXQgdGhpcyBraW5kIG9mXG4gICAgLy8gbWVzc2FnZSkuXG4gICAgY29uc3QgZGlkSGFuZGxlID0gT2JqZWN0LmtleXMoY21kSGFuZGxlZEJ5KS5maWx0ZXIoKGspID0+IGNtZEhhbmRsZWRCeVtrXSk7XG4gICAgY29uc3QgZGlkbnRIYW5kbGUgPSBPYmplY3Qua2V5cyhjbWRIYW5kbGVkQnkpLmZpbHRlcigoaykgPT4gIWNtZEhhbmRsZWRCeVtrXSk7XG4gICAgaWYgKGRpZG50SGFuZGxlLmxlbmd0aCA+IDApIHtcbiAgICAgIGxvZy5pbmZvKGBDb21tYW5kICcke2NtZH0nIHdhcyBub3QgaGFuZGxlZCBieSB0aGUgZm9sbG93aW5nIGJlYWh2aW9ycyBvciBwbHVnaW5zLCBldmVuIGAgK1xuICAgICAgICAgICAgICAgYHRob3VnaCB0aGV5IHdlcmUgcmVnaXN0ZXJlZCB0byBoYW5kbGUgaXQ6ICR7SlNPTi5zdHJpbmdpZnkoZGlkbnRIYW5kbGUpfS4gVGhlIGAgK1xuICAgICAgICAgICAgICAgYGNvbW1hbmQgKndhcyogaGFuZGxlZCBieSB0aGVzZTogJHtKU09OLnN0cmluZ2lmeShkaWRIYW5kbGUpfS5gKTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBleGVjdXRlV3JhcHBlZENvbW1hbmQgKHt3cmFwcGVkQ21kLCBwcm90b2NvbH0pIHtcbiAgICBsZXQgY21kUmVzLCBjbWRFcnIsIHJlcyA9IHt9O1xuICAgIHRyeSB7XG4gICAgICAvLyBBdCB0aGlzIHBvaW50LCBgd3JhcHBlZENtZGAgZGVmaW5lcyBhIHdob2xlIHNlcXVlbmNlIG9mIHBsdWdpbiBoYW5kbGVycywgY3VsbWluYXRpbmcgaW5cbiAgICAgIC8vIG91ciBkZWZhdWx0IGhhbmRsZXIuIFdoYXRldmVyIGl0IHJldHVybnMgaXMgd2hhdCB3ZSdyZSBnb2luZyB0byB3YW50IHRvIHNlbmQgYmFjayB0byB0aGVcbiAgICAgIC8vIHVzZXIuXG4gICAgICBjbWRSZXMgPSBhd2FpdCB3cmFwcGVkQ21kKCk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgY21kRXJyID0gZTtcbiAgICB9XG5cbiAgICAvLyBTYWRseSwgd2UgZG9uJ3Qga25vdyBleGFjdGx5IHdoYXQga2luZCBvZiBvYmplY3Qgd2lsbCBiZSByZXR1cm5lZC4gSXQgd2lsbCBlaXRoZXIgYmUgYSBiYXJlXG4gICAgLy8gb2JqZWN0LCBvciBhIHByb3RvY29sLWF3YXJlIG9iamVjdCB3aXRoIHByb3RvY29sIGFuZCBlcnJvci92YWx1ZSBrZXlzLiBTbyB3ZSBuZWVkIHRvIHNuaWZmXG4gICAgLy8gaXQgYW5kIG1ha2Ugc3VyZSB3ZSBkb24ndCBkb3VibGUtd3JhcCBpdCBpZiBpdCdzIHRoZSBsYXR0ZXIga2luZC5cbiAgICBpZiAoXy5pc1BsYWluT2JqZWN0KGNtZFJlcykgJiYgXy5oYXMoY21kUmVzLCAncHJvdG9jb2wnKSkge1xuICAgICAgcmVzID0gY21kUmVzO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXMudmFsdWUgPSBjbWRSZXM7XG4gICAgICByZXMuZXJyb3IgPSBjbWRFcnI7XG4gICAgICByZXMucHJvdG9jb2wgPSBwcm90b2NvbDtcbiAgICB9XG4gICAgcmV0dXJuIHJlcztcbiAgfVxuXG5cbiAgcHJveHlBY3RpdmUgKHNlc3Npb25JZCkge1xuICAgIGNvbnN0IGRzdFNlc3Npb24gPSB0aGlzLnNlc3Npb25zW3Nlc3Npb25JZF07XG4gICAgcmV0dXJuIGRzdFNlc3Npb24gJiYgXy5pc0Z1bmN0aW9uKGRzdFNlc3Npb24ucHJveHlBY3RpdmUpICYmIGRzdFNlc3Npb24ucHJveHlBY3RpdmUoc2Vzc2lvbklkKTtcbiAgfVxuXG4gIGdldFByb3h5QXZvaWRMaXN0IChzZXNzaW9uSWQpIHtcbiAgICBjb25zdCBkc3RTZXNzaW9uID0gdGhpcy5zZXNzaW9uc1tzZXNzaW9uSWRdO1xuICAgIHJldHVybiBkc3RTZXNzaW9uID8gZHN0U2Vzc2lvbi5nZXRQcm94eUF2b2lkTGlzdCgpIDogW107XG4gIH1cblxuICBjYW5Qcm94eSAoc2Vzc2lvbklkKSB7XG4gICAgY29uc3QgZHN0U2Vzc2lvbiA9IHRoaXMuc2Vzc2lvbnNbc2Vzc2lvbklkXTtcbiAgICByZXR1cm4gZHN0U2Vzc2lvbiAmJiBkc3RTZXNzaW9uLmNhblByb3h5KHNlc3Npb25JZCk7XG4gIH1cbn1cblxuLy8gaGVscCBkZWNpZGUgd2hpY2ggY29tbWFuZHMgc2hvdWxkIGJlIHByb3hpZWQgdG8gc3ViLWRyaXZlcnMgYW5kIHdoaWNoXG4vLyBzaG91bGQgYmUgaGFuZGxlZCBieSB0aGlzLCBvdXIgdW1icmVsbGEgZHJpdmVyXG5mdW5jdGlvbiBpc0FwcGl1bURyaXZlckNvbW1hbmQgKGNtZCkge1xuICByZXR1cm4gIWlzU2Vzc2lvbkNvbW1hbmQoY21kKSB8fCBjbWQgPT09ICdkZWxldGVTZXNzaW9uJztcbn1cblxuZXhwb3J0IHsgQXBwaXVtRHJpdmVyIH07XG4iXSwiZmlsZSI6ImxpYi9hcHBpdW0uanMiLCJzb3VyY2VSb290IjoiLi4vLi4ifQ==
|
|
567
|
+
exports.NoDriverProxyCommandError = NoDriverProxyCommandError;
|
|
568
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJkZXNpcmVkQ2FwYWJpbGl0eUNvbnN0cmFpbnRzIiwiT2JqZWN0IiwiZnJlZXplIiwiYXV0b21hdGlvbk5hbWUiLCJwcmVzZW5jZSIsImlzU3RyaW5nIiwicGxhdGZvcm1OYW1lIiwic2Vzc2lvbnNMaXN0R3VhcmQiLCJBc3luY0xvY2siLCJwZW5kaW5nRHJpdmVyc0d1YXJkIiwiQXBwaXVtRHJpdmVyIiwiRHJpdmVyQ29yZSIsInNlc3Npb25zIiwicGVuZGluZ0RyaXZlcnMiLCJuZXdDb21tYW5kVGltZW91dE1zIiwicGx1Z2luQ2xhc3NlcyIsInNlc3Npb25QbHVnaW5zIiwic2Vzc2lvbmxlc3NQbHVnaW5zIiwiZHJpdmVyQ29uZmlnIiwic2VydmVyIiwiY29uc3RydWN0b3IiLCJvcHRzIiwidG1wRGlyIiwicHJvY2VzcyIsImVudiIsIkFQUElVTV9UTVBfRElSIiwiZGVzaXJlZENhcENvbnN0cmFpbnRzIiwiYXJncyIsImNhdGNoIiwiZXJyIiwibG9nIiwiZGVidWciLCJfbG9nIiwiaW5zdGFuY2VOYW1lIiwibmFtZSIsIm5vZGUiLCJnZXRPYmplY3RJZCIsInN1YnN0cmluZyIsImxvZ2dlciIsImdldExvZ2dlciIsImlzQ29tbWFuZHNRdWV1ZUVuYWJsZWQiLCJzZXNzaW9uRXhpc3RzIiwic2Vzc2lvbklkIiwiZHN0U2Vzc2lvbiIsImRyaXZlckZvclNlc3Npb24iLCJnZXRTdGF0dXMiLCJidWlsZCIsIl8iLCJjbG9uZSIsImdldFNlc3Npb25zIiwidG9QYWlycyIsIm1hcCIsImlkIiwiZHJpdmVyIiwiY2FwYWJpbGl0aWVzIiwiY2FwcyIsInByaW50TmV3U2Vzc2lvbkFubm91bmNlbWVudCIsImRyaXZlck5hbWUiLCJkcml2ZXJWZXJzaW9uIiwiZHJpdmVyQmFzZVZlcnNpb24iLCJpbmZvIiwiQVBQSVVNX1ZFUiIsImJhc2VWZXJzaW9uIiwiYXNzaWduQ2xpQXJnc1RvRXh0ZW5zaW9uIiwiZXh0VHlwZSIsImV4dE5hbWUiLCJleHRJbnN0YW5jZSIsImFsbENsaUFyZ3NGb3JFeHQiLCJpc0VtcHR5IiwiZGVmYXVsdHMiLCJjbGlBcmdzIiwib21pdEJ5IiwidmFsdWUiLCJrZXkiLCJpc0VxdWFsIiwiY3JlYXRlU2Vzc2lvbiIsImpzb253cENhcHMiLCJyZXFDYXBzIiwidzNjQ2FwYWJpbGl0aWVzIiwiZHJpdmVyRGF0YSIsImRlZmF1bHRDYXBhYmlsaXRpZXMiLCJjbG9uZURlZXAiLCJkZWZhdWx0U2V0dGluZ3MiLCJqd3BTZXR0aW5ncyIsInczY1NldHRpbmdzIiwiYWx3YXlzTWF0Y2giLCJmaXJzdE1hdGNoRW50cnkiLCJmaXJzdE1hdGNoIiwiYXNzaWduIiwicHJvdG9jb2wiLCJpbm5lclNlc3Npb25JZCIsImRDYXBzIiwicGFyc2VkQ2FwcyIsImRlc2lyZWRDYXBzIiwicHJvY2Vzc2VkSnNvbndwQ2FwYWJpbGl0aWVzIiwicHJvY2Vzc2VkVzNDQ2FwYWJpbGl0aWVzIiwiZXJyb3IiLCJJbm5lckRyaXZlciIsInZlcnNpb24iLCJmaW5kTWF0Y2hpbmdEcml2ZXIiLCJzZXNzaW9uT3ZlcnJpZGUiLCJkZWxldGVBbGxTZXNzaW9ucyIsInJ1bm5pbmdEcml2ZXJzRGF0YSIsIm90aGVyUGVuZGluZ0RyaXZlcnNEYXRhIiwiZHJpdmVySW5zdGFuY2UiLCJyZWxheGVkU2VjdXJpdHlFbmFibGVkIiwiZGVueUluc2VjdXJlIiwiYSIsImFsbG93SW5zZWN1cmUiLCJzZXJ2ZXJIb3N0IiwiYWRkcmVzcyIsInNlcnZlclBvcnQiLCJwb3J0Iiwic2VydmVyUGF0aCIsImJhc2VQYXRoIiwiY3VyU2Vzc2lvbkRhdGFGb3JEcml2ZXIiLCJlIiwiZXJyb3JzIiwiU2Vzc2lvbk5vdENyZWF0ZWRFcnJvciIsIm1lc3NhZ2UiLCJhY3F1aXJlIiwiY29tcGFjdCIsImRydiIsInB1c2giLCJwdWxsIiwiYXR0YWNoVW5leHBlY3RlZFNodXRkb3duSGFuZGxlciIsInN0YXJ0TmV3Q29tbWFuZFRpbWVvdXQiLCJpc1czQ1Byb3RvY29sIiwiSlNPTiIsInN0cmluZ2lmeSIsInVwZGF0ZVNldHRpbmdzIiwiaXNNanNvbndwUHJvdG9jb2wiLCJvblNodXRkb3duIiwiY2F1c2UiLCJFcnJvciIsIndhcm4iLCJwbHVnaW4iLCJpc0Z1bmN0aW9uIiwib25VbmV4cGVjdGVkU2h1dGRvd24iLCJkYXRhIiwidmFsdWVzIiwiZmlsdGVyIiwicyIsImRhdHVtIiwiZGVsZXRlU2Vzc2lvbiIsIm90aGVyU2Vzc2lvbnNEYXRhIiwiY3VyQ29uc3RydWN0b3JOYW1lIiwic2Vzc2lvbnNDb3VudCIsInNpemUiLCJmb3JjZSIsInJlYXNvbiIsInV0aWwiLCJwbHVyYWxpemUiLCJjbGVhbnVwUHJvbWlzZXMiLCJzdGFydFVuZXhwZWN0ZWRTaHV0ZG93biIsImtleXMiLCJjbGVhbnVwUHJvbWlzZSIsInBsdWdpbnNGb3JTZXNzaW9uIiwiY3JlYXRlUGx1Z2luSW5zdGFuY2VzIiwicGx1Z2luc1RvSGFuZGxlQ21kIiwiY21kIiwicCIsImhhbmRsZSIsIlBsdWdpbkNsYXNzIiwicGx1Z2luTmFtZSIsImV4ZWN1dGVDb21tYW5kIiwiaXNHZXRTdGF0dXMiLCJHRVRfU1RBVFVTX0NPTU1BTkQiLCJpc1VtYnJlbGxhQ21kIiwiaXNBcHBpdW1Ecml2ZXJDb21tYW5kIiwiaXNTZXNzaW9uQ21kIiwicmVxRm9yUHJveHkiLCJsYXN0IiwicG9wIiwicGx1Z2lucyIsImNtZEhhbmRsZWRCeSIsImRlZmF1bHQiLCJkZWZhdWx0QmVoYXZpb3IiLCJsZW5ndGgiLCJwcm94eUNvbW1hbmQiLCJOb0RyaXZlclByb3h5Q29tbWFuZEVycm9yIiwib3JpZ2luYWxVcmwiLCJtZXRob2QiLCJib2R5IiwiQmFzZURyaXZlciIsInByb3RvdHlwZSIsImNhbGwiLCJ3cmFwcGVkQ21kIiwid3JhcENvbW1hbmRXaXRoUGx1Z2lucyIsIm5leHQiLCJyZXMiLCJleGVjdXRlV3JhcHBlZENvbW1hbmQiLCJsb2dQbHVnaW5IYW5kbGVyUmVwb3J0IiwiQ1JFQVRFX1NFU1NJT05fQ09NTUFORCIsImZpcnN0IiwiX25leHQiLCJkaWRIYW5kbGUiLCJrIiwiZGlkbnRIYW5kbGUiLCJjbWRSZXMiLCJjbWRFcnIiLCJpc1BsYWluT2JqZWN0IiwiaGFzIiwicHJveHlBY3RpdmUiLCJnZXRQcm94eUF2b2lkTGlzdCIsImNhblByb3h5IiwiREVMRVRFX1NFU1NJT05fQ09NTUFORCIsImNvZGUiXSwic291cmNlcyI6WyIuLi8uLi9saWIvYXBwaXVtLmpzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qIGVzbGludC1kaXNhYmxlIG5vLXVudXNlZC12YXJzICovXG5pbXBvcnQgXyBmcm9tICdsb2Rhc2gnO1xuaW1wb3J0IHsgZ2V0QnVpbGRJbmZvLCB1cGRhdGVCdWlsZEluZm8sIEFQUElVTV9WRVIgfSBmcm9tICcuL2NvbmZpZyc7XG5pbXBvcnQgeyBCYXNlRHJpdmVyLCBEcml2ZXJDb3JlLCBlcnJvcnMsIGlzU2Vzc2lvbkNvbW1hbmQsXG4gICAgICAgICBDUkVBVEVfU0VTU0lPTl9DT01NQU5ELCBERUxFVEVfU0VTU0lPTl9DT01NQU5ELCBHRVRfU1RBVFVTX0NPTU1BTkRcbn0gZnJvbSAnQGFwcGl1bS9iYXNlLWRyaXZlcic7XG5pbXBvcnQgQXN5bmNMb2NrIGZyb20gJ2FzeW5jLWxvY2snO1xuaW1wb3J0IHsgcGFyc2VDYXBzRm9ySW5uZXJEcml2ZXIsIHB1bGxTZXR0aW5ncyB9IGZyb20gJy4vdXRpbHMnO1xuaW1wb3J0IHsgdXRpbCwgbm9kZSwgbG9nZ2VyIH0gZnJvbSAnQGFwcGl1bS9zdXBwb3J0JztcbmltcG9ydCB7IGdldERlZmF1bHRzRm9yRXh0ZW5zaW9uIH0gZnJvbSAnLi9zY2hlbWEnO1xuXG4vKipcbiAqIEludmFyaWFudCBzZXQgb2YgYmFzZSBjb25zdHJhaW50c1xuICogQHR5cGUge1JlYWRvbmx5PENvbnN0cmFpbnRzPn1cbiAqL1xuY29uc3QgZGVzaXJlZENhcGFiaWxpdHlDb25zdHJhaW50cyA9IE9iamVjdC5mcmVlemUoe1xuICBhdXRvbWF0aW9uTmFtZToge1xuICAgIHByZXNlbmNlOiB0cnVlLFxuICAgIGlzU3RyaW5nOiB0cnVlLFxuICB9LFxuICBwbGF0Zm9ybU5hbWU6IHtcbiAgICBwcmVzZW5jZTogdHJ1ZSxcbiAgICBpc1N0cmluZzogdHJ1ZSxcbiAgfSxcbn0pO1xuXG5jb25zdCBzZXNzaW9uc0xpc3RHdWFyZCA9IG5ldyBBc3luY0xvY2soKTtcbmNvbnN0IHBlbmRpbmdEcml2ZXJzR3VhcmQgPSBuZXcgQXN5bmNMb2NrKCk7XG5cbi8qKlxuICogQGltcGxlbWVudHMge1Nlc3Npb25IYW5kbGVyfVxuICovXG5jbGFzcyBBcHBpdW1Ecml2ZXIgZXh0ZW5kcyBEcml2ZXJDb3JlIHtcbiAgLyoqXG4gICAqIEFjY2VzcyB0byBzZXNzaW9ucyBsaXN0IG11c3QgYmUgZ3VhcmRlZCB3aXRoIGEgU2VtYXBob3JlLCBiZWNhdXNlXG4gICAqIGl0IG1pZ2h0IGJlIGNoYW5nZWQgYnkgb3RoZXIgYXN5bmMgY2FsbHMgYXQgYW55IHRpbWVcbiAgICogSXQgaXMgbm90IHJlY29tbWVuZGVkIHRvIGFjY2VzcyB0aGlzIHByb3BlcnR5IGRpcmVjdGx5IGZyb20gdGhlIG91dHNpZGVcbiAgICogQHR5cGUge1JlY29yZDxzdHJpbmcsRXh0ZXJuYWxEcml2ZXI+fVxuICAgKi9cbiAgc2Vzc2lvbnMgPSB7fTtcblxuICAvKipcbiAgICogQWNjZXNzIHRvIHBlbmRpbmcgZHJpdmVycyBsaXN0IG11c3QgYmUgZ3VhcmRlZCB3aXRoIGEgU2VtYXBob3JlLCBiZWNhdXNlXG4gICAqIGl0IG1pZ2h0IGJlIGNoYW5nZWQgYnkgb3RoZXIgYXN5bmMgY2FsbHMgYXQgYW55IHRpbWVcbiAgICogSXQgaXMgbm90IHJlY29tbWVuZGVkIHRvIGFjY2VzcyB0aGlzIHByb3BlcnR5IGRpcmVjdGx5IGZyb20gdGhlIG91dHNpZGVcbiAgICogQHR5cGUge1JlY29yZDxzdHJpbmcsRXh0ZXJuYWxEcml2ZXJbXT59XG4gICAqL1xuICBwZW5kaW5nRHJpdmVycyA9IHt9O1xuXG4gIC8qKlxuICAgKiBOb3RlIHRoYXQge0BsaW5rY29kZSBBcHBpdW1Ecml2ZXJ9IGhhcyBubyBgbmV3Q29tbWFuZFRpbWVvdXRgIG1ldGhvZC5cbiAgICogYEFwcGl1bURyaXZlcmAgZG9lcyBub3Qgc2V0IGFuZCBvYnNlcnZlIGl0cyBvd24gdGltZW91dHM7IGluZGl2aWR1YWxcbiAgICogc2Vzc2lvbnMgKG1hbmFnZWQgZHJpdmVycykgZG8gaW5zdGVhZC5cbiAgICovXG4gIG5ld0NvbW1hbmRUaW1lb3V0TXMgPSAwO1xuXG4gIC8qKlxuICAgKiBMaXN0IG9mIGFjdGl2ZSBwbHVnaW5zXG4gICAqIEB0eXBlIHtQbHVnaW5DbGFzc1tdfVxuICAgKi9cbiAgcGx1Z2luQ2xhc3NlcyA9IFtdO1xuXG4gIC8qKlxuICAgKiBtYXAgb2Ygc2Vzc2lvbnMgdG8gYWN0dWFsIHBsdWdpbiBpbnN0YW5jZXMgcGVyIHNlc3Npb25cbiAgICogQHR5cGUge1JlY29yZDxzdHJpbmcsSW5zdGFuY2VUeXBlPFBsdWdpbkNsYXNzPltdPn1cbiAgICovXG4gIHNlc3Npb25QbHVnaW5zID0ge307XG5cbiAgLyoqXG4gICAqIHNvbWUgY29tbWFuZHMgYXJlIHNlc3Npb25sZXNzLCBzbyB3ZSBuZWVkIGEgc2V0IG9mIHBsdWdpbnMgZm9yIHRoZW1cbiAgICogQHR5cGUge0luc3RhbmNlVHlwZTxQbHVnaW5DbGFzcz5bXX1cbiAgICovXG4gIHNlc3Npb25sZXNzUGx1Z2lucyA9IFtdOztcblxuICAvKiogQHR5cGUge0RyaXZlckNvbmZpZ30gKi9cbiAgZHJpdmVyQ29uZmlnO1xuXG4gIC8qKiBAdHlwZSB7QXBwaXVtU2VydmVyfSAqL1xuICBzZXJ2ZXI7XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7RHJpdmVyT3B0c30gb3B0c1xuICAgKi9cbiAgY29uc3RydWN0b3IgKG9wdHMpIHtcbiAgICAvLyBJdCBpcyBuZWNlc3NhcnkgdG8gc2V0IGAtLXRtcGAgaGVyZSBzaW5jZSBpdCBzaG91bGQgYmUgc2V0IHRvXG4gICAgLy8gcHJvY2Vzcy5lbnYuQVBQSVVNX1RNUF9ESVIgb25jZSBhdCBhbiBpbml0aWFsIHBvaW50IGluIHRoZSBBcHBpdW0gbGlmZWN5Y2xlLlxuICAgIC8vIFRoZSBwcm9jZXNzIGFyZ3VtZW50IHdpbGwgYmUgcmVmZXJlbmNlZCBieSBCYXNlRHJpdmVyLlxuICAgIC8vIFBsZWFzZSBjYWxsIEBhcHBpdW0vc3VwcG9ydC50ZW1wRGlyIG1vZHVsZSB0byBhcHBseSB0aGlzIGJlbmVmaXQuXG4gICAgaWYgKG9wdHMudG1wRGlyKSB7XG4gICAgICBwcm9jZXNzLmVudi5BUFBJVU1fVE1QX0RJUiA9IG9wdHMudG1wRGlyO1xuICAgIH1cblxuICAgIHN1cGVyKG9wdHMpO1xuXG4gICAgdGhpcy5kZXNpcmVkQ2FwQ29uc3RyYWludHMgPSBkZXNpcmVkQ2FwYWJpbGl0eUNvbnN0cmFpbnRzO1xuXG4gICAgdGhpcy5hcmdzID0gey4uLm9wdHN9O1xuXG4gICAgLy8gYWxsb3cgdGhpcyB0byBoYXBwZW4gaW4gdGhlIGJhY2tncm91bmQsIHNvIG5vIGBhd2FpdGBcbiAgICAvLyBjYXRjaCB0aGlzIHRvIGF2b2lkIGFuIHVuaGFuZGxlZCByZWplY3Rpb25cbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgcHJvbWlzZS9wcmVmZXItYXdhaXQtdG8tdGhlbixwcm9taXNlL3ByZWZlci1hd2FpdC10by1jYWxsYmFja3NcbiAgICB1cGRhdGVCdWlsZEluZm8oKS5jYXRjaCgoZXJyKSA9PiB7XG4gICAgICB0aGlzLmxvZy5kZWJ1ZyhlcnIpO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHJpZXZlcyBsb2dnZXIgaW5zdGFuY2UgZm9yIHRoZSBjdXJyZW50IHVtYnJlbGxhIGRyaXZlciBpbnN0YW5jZVxuICAgKi9cbiAgZ2V0IGxvZyAoKSB7XG4gICAgaWYgKCF0aGlzLl9sb2cpIHtcbiAgICAgIGNvbnN0IGluc3RhbmNlTmFtZSA9IGAke3RoaXMuY29uc3RydWN0b3IubmFtZX1AJHtub2RlLmdldE9iamVjdElkKHRoaXMpLnN1YnN0cmluZygwLCA0KX1gO1xuICAgICAgdGhpcy5fbG9nID0gbG9nZ2VyLmdldExvZ2dlcihpbnN0YW5jZU5hbWUpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5fbG9nO1xuICB9XG5cbiAgLyoqXG4gICAqIENhbmNlbCBjb21tYW5kcyBxdWV1ZWluZyBmb3IgdGhlIHVtYnJlbGxhIEFwcGl1bSBkcml2ZXJcbiAgICovXG4gIGdldCBpc0NvbW1hbmRzUXVldWVFbmFibGVkICgpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBzZXNzaW9uRXhpc3RzIChzZXNzaW9uSWQpIHtcbiAgICBjb25zdCBkc3RTZXNzaW9uID0gdGhpcy5zZXNzaW9uc1tzZXNzaW9uSWRdO1xuICAgIHJldHVybiBkc3RTZXNzaW9uICYmIGRzdFNlc3Npb24uc2Vzc2lvbklkICE9PSBudWxsO1xuICB9XG5cbiAgZHJpdmVyRm9yU2Vzc2lvbiAoc2Vzc2lvbklkKSB7XG4gICAgcmV0dXJuIHRoaXMuc2Vzc2lvbnNbc2Vzc2lvbklkXTtcbiAgfVxuXG4gIGFzeW5jIGdldFN0YXR1cyAoKSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgcmVxdWlyZS1hd2FpdFxuICAgIHJldHVybiB7XG4gICAgICBidWlsZDogXy5jbG9uZShnZXRCdWlsZEluZm8oKSksXG4gICAgfTtcbiAgfVxuXG4gIGFzeW5jIGdldFNlc3Npb25zICgpIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSByZXF1aXJlLWF3YWl0XG4gICAgcmV0dXJuIF8udG9QYWlycyh0aGlzLnNlc3Npb25zKVxuICAgICAgLm1hcCgoW2lkLCBkcml2ZXJdKSA9PiAoe2lkLCBjYXBhYmlsaXRpZXM6IGRyaXZlci5jYXBzfSkpO1xuICB9XG5cbiAgcHJpbnROZXdTZXNzaW9uQW5ub3VuY2VtZW50IChkcml2ZXJOYW1lLCBkcml2ZXJWZXJzaW9uLCBkcml2ZXJCYXNlVmVyc2lvbikge1xuICAgIHRoaXMubG9nLmluZm8oZHJpdmVyVmVyc2lvblxuICAgICAgPyBgQXBwaXVtIHYke0FQUElVTV9WRVJ9IGNyZWF0aW5nIG5ldyAke2RyaXZlck5hbWV9ICh2JHtkcml2ZXJWZXJzaW9ufSkgc2Vzc2lvbmBcbiAgICAgIDogYEFwcGl1bSB2JHtBUFBJVU1fVkVSfSBjcmVhdGluZyBuZXcgJHtkcml2ZXJOYW1lfSBzZXNzaW9uYFxuICAgICk7XG4gICAgdGhpcy5sb2cuaW5mbyhgQ2hlY2tpbmcgQmFzZURyaXZlciB2ZXJzaW9ucyBmb3IgQXBwaXVtIGFuZCAke2RyaXZlck5hbWV9YCk7XG4gICAgdGhpcy5sb2cuaW5mbyhBcHBpdW1Ecml2ZXIuYmFzZVZlcnNpb25cbiAgICAgID8gYEFwcGl1bSdzIEJhc2VEcml2ZXIgdmVyc2lvbiBpcyAke0FwcGl1bURyaXZlci5iYXNlVmVyc2lvbn1gXG4gICAgICA6IGBDb3VsZCBub3QgZGV0ZXJtaW5lIEFwcGl1bSdzIEJhc2VEcml2ZXIgdmVyc2lvbmBcbiAgICApO1xuICAgIHRoaXMubG9nLmluZm8oZHJpdmVyQmFzZVZlcnNpb25cbiAgICAgID8gYCR7ZHJpdmVyTmFtZX0ncyBCYXNlRHJpdmVyIHZlcnNpb24gaXMgJHtkcml2ZXJCYXNlVmVyc2lvbn1gXG4gICAgICA6IGBDb3VsZCBub3QgZGV0ZXJtaW5lICR7ZHJpdmVyTmFtZX0ncyBCYXNlRHJpdmVyIHZlcnNpb25gXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBWYWxpZGF0ZSBhbmQgYXNzaWduIENMSSBhcmdzIGZvciBhIGRyaXZlciBvciBwbHVnaW5cbiAgICpcbiAgICogSWYgdGhlIGV4dGVuc2lvbiBoYXMgcHJvdmlkZWQgYSBzY2hlbWEsIHZhbGlkYXRpb24gaGFzIGFscmVhZHkgaGFwcGVuZWQuXG4gICAqXG4gICAqIEFueSBhcmcgd2hpY2ggaXMgZXF1YWwgdG8gaXRzIGRlZmF1bHQgdmFsdWUgd2lsbCBub3QgYmUgYXNzaWduZWQgdG8gdGhlIGV4dGVuc2lvbi5cbiAgICogQHBhcmFtIHtFeHRlbnNpb25UeXBlfSBleHRUeXBlICdkcml2ZXInIG9yICdwbHVnaW4nXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBleHROYW1lIHRoZSBuYW1lIG9mIHRoZSBleHRlbnNpb25cbiAgICogQHBhcmFtIHtPYmplY3R9IGV4dEluc3RhbmNlIHRoZSBkcml2ZXIgb3IgcGx1Z2luIGluc3RhbmNlXG4gICAqL1xuICBhc3NpZ25DbGlBcmdzVG9FeHRlbnNpb24gKGV4dFR5cGUsIGV4dE5hbWUsIGV4dEluc3RhbmNlKSB7XG4gICAgY29uc3QgYWxsQ2xpQXJnc0ZvckV4dCA9IC8qKiBAdHlwZSB7UmVjb3JkPHN0cmluZyx1bmtub3duPnx1bmRlZmluZWR9ICovKHRoaXMuYXJnc1tleHRUeXBlXT8uW2V4dE5hbWVdKTtcbiAgICBpZiAoIV8uaXNFbXB0eShhbGxDbGlBcmdzRm9yRXh0KSkge1xuICAgICAgY29uc3QgZGVmYXVsdHMgPSBnZXREZWZhdWx0c0ZvckV4dGVuc2lvbihleHRUeXBlLCBleHROYW1lKTtcbiAgICAgIGNvbnN0IGNsaUFyZ3MgPSBfLmlzRW1wdHkoZGVmYXVsdHMpXG4gICAgICAgID8gYWxsQ2xpQXJnc0ZvckV4dFxuICAgICAgICA6IF8ub21pdEJ5KGFsbENsaUFyZ3NGb3JFeHQsICh2YWx1ZSwga2V5KSA9PiBfLmlzRXF1YWwoZGVmYXVsdHNba2V5XSwgdmFsdWUpKTtcbiAgICAgIGlmICghXy5pc0VtcHR5KGNsaUFyZ3MpKSB7XG4gICAgICAgIGV4dEluc3RhbmNlLmNsaUFyZ3MgPSBjbGlBcmdzO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGUgYSBuZXcgc2Vzc2lvblxuICAgKiBAcGFyYW0ge1czQ0NhcGFiaWxpdGllc30ganNvbndwQ2FwcyBKU09OV1AgZm9ybWF0dGVkIGRlc2lyZWQgY2FwYWJpbGl0aWVzXG4gICAqIEBwYXJhbSB7VzNDQ2FwYWJpbGl0aWVzfSByZXFDYXBzIFJlcXVpcmVkIGNhcGFiaWxpdGllcyAoSlNPTldQIHN0YW5kYXJkKVxuICAgKiBAcGFyYW0ge1czQ0NhcGFiaWxpdGllc30gdzNjQ2FwYWJpbGl0aWVzIFczQyBjYXBhYmlsaXRpZXNcbiAgICogQHBhcmFtIHtpbXBvcnQoJ0BhcHBpdW0vdHlwZXMnKS5Ecml2ZXJEYXRhW119IFtkcml2ZXJEYXRhXVxuICAgKi9cbiAgYXN5bmMgY3JlYXRlU2Vzc2lvbiAoanNvbndwQ2FwcywgcmVxQ2FwcywgdzNjQ2FwYWJpbGl0aWVzLCBkcml2ZXJEYXRhKSB7XG4gICAgY29uc3QgZGVmYXVsdENhcGFiaWxpdGllcyA9IF8uY2xvbmVEZWVwKHRoaXMuYXJncy5kZWZhdWx0Q2FwYWJpbGl0aWVzKTtcbiAgICBjb25zdCBkZWZhdWx0U2V0dGluZ3MgPSBwdWxsU2V0dGluZ3MoZGVmYXVsdENhcGFiaWxpdGllcyk7XG4gICAganNvbndwQ2FwcyA9IF8uY2xvbmVEZWVwKGpzb253cENhcHMpO1xuICAgIGNvbnN0IGp3cFNldHRpbmdzID0gey4uLmRlZmF1bHRTZXR0aW5ncywgLi4ucHVsbFNldHRpbmdzKGpzb253cENhcHMpfTtcbiAgICB3M2NDYXBhYmlsaXRpZXMgPSBfLmNsb25lRGVlcCh3M2NDYXBhYmlsaXRpZXMpO1xuICAgIC8vIEl0IGlzIHBvc3NpYmxlIHRoYXQgdGhlIGNsaWVudCBvbmx5IHByb3ZpZGVzIGNhcHMgdXNpbmcgSlNPTldQIHN0YW5kYXJkLFxuICAgIC8vIGFsdGhvdWdoIGZpcnN0TWF0Y2gvYWx3YXlzTWF0Y2ggcHJvcGVydGllcyBhcmUgc3RpbGwgcHJlc2VudC5cbiAgICAvLyBJbiBzdWNoIGNhc2Ugd2UgYXNzdW1lIHRoZSBjbGllbnQgdW5kZXJzdGFuZHMgVzNDIHByb3RvY29sIGFuZCBtZXJnZSB0aGUgZ2l2ZW5cbiAgICAvLyBKU09OV1AgY2FwcyB0byBXM0MgY2Fwc1xuICAgIGNvbnN0IHczY1NldHRpbmdzID0ge1xuICAgICAgLi4uandwU2V0dGluZ3MsXG4gICAgICAuLi5wdWxsU2V0dGluZ3MoKHczY0NhcGFiaWxpdGllcyA/PyB7fSkuYWx3YXlzTWF0Y2ggPz8ge30pXG4gICAgfTtcbiAgICBmb3IgKGNvbnN0IGZpcnN0TWF0Y2hFbnRyeSBvZiAoKHczY0NhcGFiaWxpdGllcyA/PyB7fSkuZmlyc3RNYXRjaCA/PyBbXSkpIHtcbiAgICAgIE9iamVjdC5hc3NpZ24odzNjU2V0dGluZ3MsIHB1bGxTZXR0aW5ncyhmaXJzdE1hdGNoRW50cnkpKTtcbiAgICB9XG5cbiAgICBsZXQgcHJvdG9jb2w7XG4gICAgbGV0IGlubmVyU2Vzc2lvbklkLCBkQ2FwcztcbiAgICB0cnkge1xuICAgICAgLy8gUGFyc2UgdGhlIGNhcHMgaW50byBhIGZvcm1hdCB0aGF0IHRoZSBJbm5lckRyaXZlciB3aWxsIGFjY2VwdFxuICAgICAgY29uc3QgcGFyc2VkQ2FwcyA9IHBhcnNlQ2Fwc0ZvcklubmVyRHJpdmVyKFxuICAgICAgICBqc29ud3BDYXBzLFxuICAgICAgICB3M2NDYXBhYmlsaXRpZXMsXG4gICAgICAgIHRoaXMuZGVzaXJlZENhcENvbnN0cmFpbnRzLFxuICAgICAgICBkZWZhdWx0Q2FwYWJpbGl0aWVzXG4gICAgICApO1xuXG4gICAgICBjb25zdCB7ZGVzaXJlZENhcHMsIHByb2Nlc3NlZEpzb253cENhcGFiaWxpdGllcywgcHJvY2Vzc2VkVzNDQ2FwYWJpbGl0aWVzfSA9IC8qKiBAdHlwZSB7aW1wb3J0KCcuL3V0aWxzJykuUGFyc2VkRHJpdmVyQ2Fwc30gKi8ocGFyc2VkQ2Fwcyk7XG4gICAgICBwcm90b2NvbCA9IHBhcnNlZENhcHMucHJvdG9jb2w7XG4gICAgICBjb25zdCBlcnJvciA9IC8qKiBAdHlwZSB7aW1wb3J0KCcuL3V0aWxzJykuSW52YWxpZENhcHN9ICovKHBhcnNlZENhcHMpLmVycm9yO1xuICAgICAgLy8gSWYgdGhlIHBhcnNpbmcgb2YgdGhlIGNhcHMgcHJvZHVjZWQgYW4gZXJyb3IsIHRocm93IGl0IGluIGhlcmVcbiAgICAgIGlmIChlcnJvcikge1xuICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgIH1cblxuICAgICAgY29uc3Qge1xuICAgICAgICBkcml2ZXI6IElubmVyRHJpdmVyLFxuICAgICAgICB2ZXJzaW9uOiBkcml2ZXJWZXJzaW9uLFxuICAgICAgICBkcml2ZXJOYW1lXG4gICAgICB9ID0gdGhpcy5kcml2ZXJDb25maWcuZmluZE1hdGNoaW5nRHJpdmVyKGRlc2lyZWRDYXBzKTtcbiAgICAgIHRoaXMucHJpbnROZXdTZXNzaW9uQW5ub3VuY2VtZW50KElubmVyRHJpdmVyLm5hbWUsIGRyaXZlclZlcnNpb24sIElubmVyRHJpdmVyLmJhc2VWZXJzaW9uKTtcblxuICAgICAgaWYgKHRoaXMuYXJncy5zZXNzaW9uT3ZlcnJpZGUpIHtcbiAgICAgICAgYXdhaXQgdGhpcy5kZWxldGVBbGxTZXNzaW9ucygpO1xuICAgICAgfVxuXG4gICAgICAvKipcbiAgICAgICAqIEB0eXBlIHtEcml2ZXJEYXRhW119XG4gICAgICAgKi9cbiAgICAgIGxldCBydW5uaW5nRHJpdmVyc0RhdGEgPSBbXTtcbiAgICAgIC8qKlxuICAgICAgICogQHR5cGUge0RyaXZlckRhdGFbXX1cbiAgICAgICAqL1xuICAgICAgbGV0IG90aGVyUGVuZGluZ0RyaXZlcnNEYXRhID0gW107XG5cbiAgICAgIGNvbnN0IGRyaXZlckluc3RhbmNlID0gbmV3IElubmVyRHJpdmVyKHRoaXMuYXJncywgdHJ1ZSk7XG5cbiAgICAgIC8vIFdlIHdhbnQgdG8gYXNzaWduIHNlY3VyaXR5IHZhbHVlcyBkaXJlY3RseSBvbiB0aGUgZHJpdmVyLiBUaGUgZHJpdmVyXG4gICAgICAvLyBzaG91bGQgbm90IHJlYWQgc2VjdXJpdHkgdmFsdWVzIGZyb20gYHRoaXMub3B0c2AgYmVjYXVzZSB0aG9zZSB2YWx1ZXNcbiAgICAgIC8vIGNvdWxkIGhhdmUgYmVlbiBzZXQgYnkgYSBtYWxpY2lvdXMgdXNlciB2aWEgY2FwYWJpbGl0aWVzLCB3aGVyZWFzIHdlXG4gICAgICAvLyB3YW50IGEgZ3VhcmFudGVlIHRoZSB2YWx1ZXMgd2VyZSBzZXQgYnkgdGhlIGFwcGl1bSBzZXJ2ZXIgYWRtaW5cbiAgICAgIGlmICh0aGlzLmFyZ3MucmVsYXhlZFNlY3VyaXR5RW5hYmxlZCkge1xuICAgICAgICB0aGlzLmxvZy5pbmZvKGBBcHBseWluZyByZWxheGVkIHNlY3VyaXR5IHRvICcke0lubmVyRHJpdmVyLm5hbWV9JyBhcyBwZXIgYCArXG4gICAgICAgICAgYHNlcnZlciBjb21tYW5kIGxpbmUgYXJndW1lbnQuIEFsbCBpbnNlY3VyZSBmZWF0dXJlcyB3aWxsIGJlIGAgK1xuICAgICAgICAgIGBlbmFibGVkIHVubGVzcyBleHBsaWNpdGx5IGRpc2FibGVkIGJ5IC0tZGVueS1pbnNlY3VyZWApO1xuICAgICAgICBkcml2ZXJJbnN0YW5jZS5yZWxheGVkU2VjdXJpdHlFbmFibGVkID0gdHJ1ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKCFfLmlzRW1wdHkodGhpcy5hcmdzLmRlbnlJbnNlY3VyZSkpIHtcbiAgICAgICAgdGhpcy5sb2cuaW5mbygnRXhwbGljaXRseSBwcmV2ZW50aW5nIHVzZSBvZiBpbnNlY3VyZSBmZWF0dXJlczonKTtcbiAgICAgICAgdGhpcy5hcmdzLmRlbnlJbnNlY3VyZS5tYXAoKGEpID0+IHRoaXMubG9nLmluZm8oYCAgICAke2F9YCkpO1xuICAgICAgICBkcml2ZXJJbnN0YW5jZS5kZW55SW5zZWN1cmUgPSB0aGlzLmFyZ3MuZGVueUluc2VjdXJlO1xuICAgICAgfVxuXG4gICAgICBpZiAoIV8uaXNFbXB0eSh0aGlzLmFyZ3MuYWxsb3dJbnNlY3VyZSkpIHtcbiAgICAgICAgdGhpcy5sb2cuaW5mbygnRXhwbGljaXRseSBlbmFibGluZyB1c2Ugb2YgaW5zZWN1cmUgZmVhdHVyZXM6Jyk7XG4gICAgICAgIHRoaXMuYXJncy5hbGxvd0luc2VjdXJlLm1hcCgoYSkgPT4gdGhpcy5sb2cuaW5mbyhgICAgICR7YX1gKSk7XG4gICAgICAgIGRyaXZlckluc3RhbmNlLmFsbG93SW5zZWN1cmUgPSB0aGlzLmFyZ3MuYWxsb3dJbnNlY3VyZTtcbiAgICAgIH1cblxuICAgICAgLy8gTGlrZXdpc2UsIGFueSBkcml2ZXItc3BlY2lmaWMgQ0xJIGFyZ3MgdGhhdCB3ZXJlIHBhc3NlZCBpbiBzaG91bGQgYmUgYXNzaWduZWQgZGlyZWN0bHkgdG9cbiAgICAgIC8vIHRoZSBkcml2ZXIgc28gdGhhdCB0aGV5IGNhbm5vdCBiZSBtaW1pY2tlZCBieSBhIG1hbGljaW91cyB1c2VyIHNlbmRpbmcgaW4gY2FwYWJpbGl0aWVzXG4gICAgICB0aGlzLmFzc2lnbkNsaUFyZ3NUb0V4dGVuc2lvbignZHJpdmVyJywgZHJpdmVyTmFtZSwgZHJpdmVySW5zdGFuY2UpO1xuXG4gICAgICAvLyBUaGlzIGFzc2lnbm1lbnQgaXMgcmVxdWlyZWQgZm9yIGNvcnJlY3Qgd2ViIHNvY2tldHMgZnVuY3Rpb25hbGl0eSBpbnNpZGUgdGhlIGRyaXZlclxuICAgICAgLy8gRHJpdmVycy9wbHVnaW5zIG1pZ2h0IGFsc28gd2FudCB0byBrbm93IHdoZXJlIHRoZXkgYXJlIGhvc3RlZFxuXG4gICAgICAvLyBYWFg6IHRlbXBvcmFyeSBoYWNrIHRvIHdvcmsgYXJvdW5kICMxNjc0N1xuICAgICAgZHJpdmVySW5zdGFuY2Uuc2VydmVyID0gdGhpcy5zZXJ2ZXI7XG4gICAgICBkcml2ZXJJbnN0YW5jZS5zZXJ2ZXJIb3N0ID0gdGhpcy5hcmdzLmFkZHJlc3M7XG4gICAgICBkcml2ZXJJbnN0YW5jZS5zZXJ2ZXJQb3J0ID0gdGhpcy5hcmdzLnBvcnQ7XG4gICAgICBkcml2ZXJJbnN0YW5jZS5zZXJ2ZXJQYXRoID0gdGhpcy5hcmdzLmJhc2VQYXRoO1xuXG4gICAgICB0cnkge1xuICAgICAgICBydW5uaW5nRHJpdmVyc0RhdGEgPSBhd2FpdCB0aGlzLmN1clNlc3Npb25EYXRhRm9yRHJpdmVyKElubmVyRHJpdmVyKSA/PyBbXTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgdGhyb3cgbmV3IGVycm9ycy5TZXNzaW9uTm90Q3JlYXRlZEVycm9yKGUubWVzc2FnZSk7XG4gICAgICB9XG4gICAgICBhd2FpdCBwZW5kaW5nRHJpdmVyc0d1YXJkLmFjcXVpcmUoQXBwaXVtRHJpdmVyLm5hbWUsICgpID0+IHtcbiAgICAgICAgdGhpcy5wZW5kaW5nRHJpdmVyc1tJbm5lckRyaXZlci5uYW1lXSA9IHRoaXMucGVuZGluZ0RyaXZlcnNbSW5uZXJEcml2ZXIubmFtZV0gfHwgW107XG4gICAgICAgIG90aGVyUGVuZGluZ0RyaXZlcnNEYXRhID0gXy5jb21wYWN0KHRoaXMucGVuZGluZ0RyaXZlcnNbSW5uZXJEcml2ZXIubmFtZV0ubWFwKChkcnYpID0+IGRydi5kcml2ZXJEYXRhKSk7XG4gICAgICAgIHRoaXMucGVuZGluZ0RyaXZlcnNbSW5uZXJEcml2ZXIubmFtZV0ucHVzaChkcml2ZXJJbnN0YW5jZSk7XG4gICAgICB9KTtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgW2lubmVyU2Vzc2lvbklkLCBkQ2Fwc10gPSBhd2FpdCBkcml2ZXJJbnN0YW5jZS5jcmVhdGVTZXNzaW9uKFxuICAgICAgICAgIHByb2Nlc3NlZEpzb253cENhcGFiaWxpdGllcyxcbiAgICAgICAgICByZXFDYXBzLFxuICAgICAgICAgIHByb2Nlc3NlZFczQ0NhcGFiaWxpdGllcyxcbiAgICAgICAgICBbLi4ucnVubmluZ0RyaXZlcnNEYXRhLCAuLi5vdGhlclBlbmRpbmdEcml2ZXJzRGF0YV1cbiAgICAgICAgKTtcbiAgICAgICAgcHJvdG9jb2wgPSBkcml2ZXJJbnN0YW5jZS5wcm90b2NvbDtcbiAgICAgICAgdGhpcy5zZXNzaW9uc1tpbm5lclNlc3Npb25JZF0gPSBkcml2ZXJJbnN0YW5jZTtcbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIGF3YWl0IHBlbmRpbmdEcml2ZXJzR3VhcmQuYWNxdWlyZShBcHBpdW1Ecml2ZXIubmFtZSwgKCkgPT4ge1xuICAgICAgICAgIF8ucHVsbCh0aGlzLnBlbmRpbmdEcml2ZXJzW0lubmVyRHJpdmVyLm5hbWVdLCBkcml2ZXJJbnN0YW5jZSk7XG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICB0aGlzLmF0dGFjaFVuZXhwZWN0ZWRTaHV0ZG93bkhhbmRsZXIoZHJpdmVySW5zdGFuY2UsIGlubmVyU2Vzc2lvbklkKTtcblxuICAgICAgdGhpcy5sb2cuaW5mbyhgTmV3ICR7SW5uZXJEcml2ZXIubmFtZX0gc2Vzc2lvbiBjcmVhdGVkIHN1Y2Nlc3NmdWxseSwgc2Vzc2lvbiBgICtcbiAgICAgICAgYCR7aW5uZXJTZXNzaW9uSWR9IGFkZGVkIHRvIG1hc3RlciBzZXNzaW9uIGxpc3RgKTtcblxuICAgICAgLy8gc2V0IHRoZSBOZXcgQ29tbWFuZCBUaW1lb3V0IGZvciB0aGUgaW5uZXIgZHJpdmVyXG4gICAgICBkcml2ZXJJbnN0YW5jZS5zdGFydE5ld0NvbW1hbmRUaW1lb3V0KCk7XG5cbiAgICAgIC8vIGFwcGx5IGluaXRpYWwgdmFsdWVzIHRvIEFwcGl1bSBzZXR0aW5ncyAoaWYgcHJvdmlkZWQpXG4gICAgICBpZiAoZHJpdmVySW5zdGFuY2UuaXNXM0NQcm90b2NvbCgpICYmICFfLmlzRW1wdHkodzNjU2V0dGluZ3MpKSB7XG4gICAgICAgIHRoaXMubG9nLmluZm8oYEFwcGx5aW5nIHRoZSBpbml0aWFsIHZhbHVlcyB0byBBcHBpdW0gc2V0dGluZ3MgcGFyc2VkIGZyb20gVzNDIGNhcHM6IGAgK1xuICAgICAgICAgIEpTT04uc3RyaW5naWZ5KHczY1NldHRpbmdzKSk7XG4gICAgICAgIGF3YWl0IGRyaXZlckluc3RhbmNlLnVwZGF0ZVNldHRpbmdzKHczY1NldHRpbmdzKTtcbiAgICAgIH0gZWxzZSBpZiAoZHJpdmVySW5zdGFuY2UuaXNNanNvbndwUHJvdG9jb2woKSAmJiAhXy5pc0VtcHR5KGp3cFNldHRpbmdzKSkge1xuICAgICAgICB0aGlzLmxvZy5pbmZvKGBBcHBseWluZyB0aGUgaW5pdGlhbCB2YWx1ZXMgdG8gQXBwaXVtIHNldHRpbmdzIHBhcnNlZCBmcm9tIE1KU09OV1AgY2FwczogYCArXG4gICAgICAgICAgSlNPTi5zdHJpbmdpZnkoandwU2V0dGluZ3MpKTtcbiAgICAgICAgYXdhaXQgZHJpdmVySW5zdGFuY2UudXBkYXRlU2V0dGluZ3MoandwU2V0dGluZ3MpO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBwcm90b2NvbCxcbiAgICAgICAgZXJyb3IsXG4gICAgICB9O1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICBwcm90b2NvbCxcbiAgICAgIHZhbHVlOiBbaW5uZXJTZXNzaW9uSWQsIGRDYXBzLCBwcm90b2NvbF1cbiAgICB9O1xuICB9XG5cbiAgYXR0YWNoVW5leHBlY3RlZFNodXRkb3duSGFuZGxlciAoZHJpdmVyLCBpbm5lclNlc3Npb25JZCkge1xuICAgIGNvbnN0IG9uU2h1dGRvd24gPSAoY2F1c2UgPSBuZXcgRXJyb3IoJ1Vua25vd24gZXJyb3InKSkgPT4ge1xuICAgICAgdGhpcy5sb2cud2FybihgRW5kaW5nIHNlc3Npb24sIGNhdXNlIHdhcyAnJHtjYXVzZS5tZXNzYWdlfSdgKTtcblxuICAgICAgaWYgKHRoaXMuc2Vzc2lvblBsdWdpbnNbaW5uZXJTZXNzaW9uSWRdKSB7XG4gICAgICAgIGZvciAoY29uc3QgcGx1Z2luIG9mIHRoaXMuc2Vzc2lvblBsdWdpbnNbaW5uZXJTZXNzaW9uSWRdKSB7XG4gICAgICAgICAgaWYgKF8uaXNGdW5jdGlvbihwbHVnaW4ub25VbmV4cGVjdGVkU2h1dGRvd24pKSB7XG4gICAgICAgICAgICB0aGlzLmxvZy5kZWJ1ZyhgUGx1Z2luICR7cGx1Z2luLm5hbWV9IGRlZmluZXMgYW4gdW5leHBlY3RlZCBzaHV0ZG93biBoYW5kbGVyOyBjYWxsaW5nIGl0IG5vd2ApO1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgcGx1Z2luLm9uVW5leHBlY3RlZFNodXRkb3duKGRyaXZlciwgY2F1c2UpO1xuICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICB0aGlzLmxvZy53YXJuKGBHb3QgYW4gZXJyb3Igd2hlbiBydW5uaW5nIHBsdWdpbiAke3BsdWdpbi5uYW1lfSBzaHV0ZG93biBoYW5kbGVyOiAke2V9YCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMubG9nLmRlYnVnKGBQbHVnaW4gJHtwbHVnaW4ubmFtZX0gZG9lcyBub3QgZGVmaW5lIGFuIHVuZXhwZWN0ZWQgc2h1dGRvd24gaGFuZGxlcmApO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICB0aGlzLmxvZy5pbmZvKGBSZW1vdmluZyBzZXNzaW9uICcke2lubmVyU2Vzc2lvbklkfScgZnJvbSBvdXIgbWFzdGVyIHNlc3Npb24gbGlzdGApO1xuICAgICAgZGVsZXRlIHRoaXMuc2Vzc2lvbnNbaW5uZXJTZXNzaW9uSWRdO1xuICAgICAgZGVsZXRlIHRoaXMuc2Vzc2lvblBsdWdpbnNbaW5uZXJTZXNzaW9uSWRdO1xuICAgIH07XG5cbiAgICBpZiAoXy5pc0Z1bmN0aW9uKGRyaXZlci5vblVuZXhwZWN0ZWRTaHV0ZG93bikpIHtcbiAgICAgIGRyaXZlci5vblVuZXhwZWN0ZWRTaHV0ZG93bihvblNodXRkb3duKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5sb2cud2FybihgRmFpbGVkIHRvIGF0dGFjaCB0aGUgdW5leHBlY3RlZCBzaHV0ZG93biBsaXN0ZW5lci4gYCArXG4gICAgICAgIGBJcyAnb25VbmV4cGVjdGVkU2h1dGRvd24nIG1ldGhvZCBhdmFpbGFibGUgZm9yICcke2RyaXZlci5jb25zdHJ1Y3Rvci5uYW1lfSc/YCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqXG4gICAqIEBwYXJhbSB7aW1wb3J0KCcuLi90eXBlcy9leHRlbnNpb24nKS5Ecml2ZXJDbGFzc30gSW5uZXJEcml2ZXJcbiAgICogQHJldHVybnMge1Byb21pc2U8RHJpdmVyRGF0YVtdPn19XG4gICAqL1xuICBhc3luYyBjdXJTZXNzaW9uRGF0YUZvckRyaXZlciAoSW5uZXJEcml2ZXIpIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSByZXF1aXJlLWF3YWl0XG4gICAgY29uc3QgZGF0YSA9IF8uY29tcGFjdChfLnZhbHVlcyh0aGlzLnNlc3Npb25zKVxuICAgICAgLmZpbHRlcigocykgPT4gcy5jb25zdHJ1Y3Rvci5uYW1lID09PSBJbm5lckRyaXZlci5uYW1lKVxuICAgICAgLm1hcCgocykgPT4gcy5kcml2ZXJEYXRhKSk7XG4gICAgZm9yIChjb25zdCBkYXR1bSBvZiBkYXRhKSB7XG4gICAgICBpZiAoIWRhdHVtKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgUHJvYmxlbSBnZXR0aW5nIHNlc3Npb24gZGF0YSBmb3IgZHJpdmVyIHR5cGUgYCArXG4gICAgICAgICAgYCR7SW5uZXJEcml2ZXIubmFtZX07IGRvZXMgaXQgaW1wbGVtZW50ICdnZXQgZHJpdmVyRGF0YSc/YCk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBkYXRhO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBzZXNzaW9uSWRcbiAgICovXG4gIGFzeW5jIGRlbGV0ZVNlc3Npb24gKHNlc3Npb25JZCkge1xuICAgIGxldCBwcm90b2NvbDtcbiAgICB0cnkge1xuICAgICAgbGV0IG90aGVyU2Vzc2lvbnNEYXRhO1xuICAgICAgY29uc3QgZHN0U2Vzc2lvbiA9IGF3YWl0IHNlc3Npb25zTGlzdEd1YXJkLmFjcXVpcmUoQXBwaXVtRHJpdmVyLm5hbWUsICgpID0+IHtcbiAgICAgICAgaWYgKCF0aGlzLnNlc3Npb25zW3Nlc3Npb25JZF0pIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgY3VyQ29uc3RydWN0b3JOYW1lID0gdGhpcy5zZXNzaW9uc1tzZXNzaW9uSWRdLmNvbnN0cnVjdG9yLm5hbWU7XG4gICAgICAgIG90aGVyU2Vzc2lvbnNEYXRhID0gXy50b1BhaXJzKHRoaXMuc2Vzc2lvbnMpXG4gICAgICAgICAgICAgIC5maWx0ZXIoKFtrZXksIHZhbHVlXSkgPT4gdmFsdWUuY29uc3RydWN0b3IubmFtZSA9PT0gY3VyQ29uc3RydWN0b3JOYW1lICYmIGtleSAhPT0gc2Vzc2lvbklkKVxuICAgICAgICAgICAgICAubWFwKChbLCB2YWx1ZV0pID0+IHZhbHVlLmRyaXZlckRhdGEpO1xuICAgICAgICBjb25zdCBkc3RTZXNzaW9uID0gdGhpcy5zZXNzaW9uc1tzZXNzaW9uSWRdO1xuICAgICAgICBwcm90b2NvbCA9IGRzdFNlc3Npb24ucHJvdG9jb2w7XG4gICAgICAgIHRoaXMubG9nLmluZm8oYFJlbW92aW5nIHNlc3Npb24gJHtzZXNzaW9uSWR9IGZyb20gb3VyIG1hc3RlciBzZXNzaW9uIGxpc3RgKTtcbiAgICAgICAgLy8gcmVnYXJkbGVzcyBvZiB3aGV0aGVyIHRoZSBkZWxldGVTZXNzaW9uIGNvbXBsZXRlcyBzdWNjZXNzZnVsbHkgb3Igbm90XG4gICAgICAgIC8vIG1ha2UgdGhlIHNlc3Npb24gdW5hdmFpbGFibGUsIGJlY2F1c2Ugd2hvIGtub3dzIHdoYXQgc3RhdGUgaXQgbWlnaHRcbiAgICAgICAgLy8gYmUgaW4gb3RoZXJ3aXNlXG4gICAgICAgIGRlbGV0ZSB0aGlzLnNlc3Npb25zW3Nlc3Npb25JZF07XG4gICAgICAgIGRlbGV0ZSB0aGlzLnNlc3Npb25QbHVnaW5zW3Nlc3Npb25JZF07XG4gICAgICAgIHJldHVybiBkc3RTZXNzaW9uO1xuICAgICAgfSk7XG4gICAgICAvLyB0aGlzIG1heSBub3QgYmUgY29ycmVjdCwgYnV0IGlmIGBkc3RTZXNzaW9uYCB3YXMgZmFsc3ksIHRoZSBjYWxsIHRvIGBkZWxldGVTZXNzaW9uKClgIHdvdWxkXG4gICAgICAvLyB0aHJvdyBhbnl3YXkuXG4gICAgICBpZiAoIWRzdFNlc3Npb24pIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdTZXNzaW9uIG5vdCBmb3VuZCcpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgcHJvdG9jb2wsXG4gICAgICAgIHZhbHVlOiBhd2FpdCBkc3RTZXNzaW9uLmRlbGV0ZVNlc3Npb24oc2Vzc2lvbklkLCBvdGhlclNlc3Npb25zRGF0YSksXG4gICAgICB9O1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHRoaXMubG9nLmVycm9yKGBIYWQgdHJvdWJsZSBlbmRpbmcgc2Vzc2lvbiAke3Nlc3Npb25JZH06ICR7ZS5tZXNzYWdlfWApO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgcHJvdG9jb2wsXG4gICAgICAgIGVycm9yOiBlLFxuICAgICAgfTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBkZWxldGVBbGxTZXNzaW9ucyAob3B0cyA9IHt9KSB7XG4gICAgY29uc3Qgc2Vzc2lvbnNDb3VudCA9IF8uc2l6ZSh0aGlzLnNlc3Npb25zKTtcbiAgICBpZiAoMCA9PT0gc2Vzc2lvbnNDb3VudCkge1xuICAgICAgdGhpcy5sb2cuZGVidWcoJ1RoZXJlIGFyZSBubyBhY3RpdmUgc2Vzc2lvbnMgZm9yIGNsZWFudXAnKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCB7XG4gICAgICBmb3JjZSA9IGZhbHNlLFxuICAgICAgcmVhc29uLFxuICAgIH0gPSBvcHRzO1xuICAgIHRoaXMubG9nLmRlYnVnKGBDbGVhbmluZyB1cCAke3V0aWwucGx1cmFsaXplKCdhY3RpdmUgc2Vzc2lvbicsIHNlc3Npb25zQ291bnQsIHRydWUpfWApO1xuICAgIGNvbnN0IGNsZWFudXBQcm9taXNlcyA9IGZvcmNlXG4gICAgICA/IF8udmFsdWVzKHRoaXMuc2Vzc2lvbnMpLm1hcCgoZHJ2KSA9PiBkcnYuc3RhcnRVbmV4cGVjdGVkU2h1dGRvd24ocmVhc29uICYmIG5ldyBFcnJvcihyZWFzb24pKSlcbiAgICAgIDogXy5rZXlzKHRoaXMuc2Vzc2lvbnMpLm1hcCgoaWQpID0+IHRoaXMuZGVsZXRlU2Vzc2lvbihpZCkpO1xuICAgIGZvciAoY29uc3QgY2xlYW51cFByb21pc2Ugb2YgY2xlYW51cFByb21pc2VzKSB7XG4gICAgICB0cnkge1xuICAgICAgICBhd2FpdCBjbGVhbnVwUHJvbWlzZTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgdGhpcy5sb2cuZGVidWcoZSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEdldCB0aGUgYXBwcm9wcmlhdGUgcGx1Z2lucyBmb3IgYSBzZXNzaW9uIChvciBzZXNzaW9ubGVzcyBwbHVnaW5zKVxuICAgKlxuICAgKiBAcGFyYW0gez9zdHJpbmd9IHNlc3Npb25JZCAtIHRoZSBzZXNzaW9uSWQgKG9yIG51bGwpIHRvIHVzZSB0byBmaW5kIHBsdWdpbnNcbiAgICogQHJldHVybnMge0FycmF5fSAtIGFycmF5IG9mIHBsdWdpbiBpbnN0YW5jZXNcbiAgICovXG4gIHBsdWdpbnNGb3JTZXNzaW9uIChzZXNzaW9uSWQgPSBudWxsKSB7XG4gICAgaWYgKHNlc3Npb25JZCkge1xuICAgICAgaWYgKCF0aGlzLnNlc3Npb25QbHVnaW5zW3Nlc3Npb25JZF0pIHtcbiAgICAgICAgdGhpcy5zZXNzaW9uUGx1Z2luc1tzZXNzaW9uSWRdID0gdGhpcy5jcmVhdGVQbHVnaW5JbnN0YW5jZXMoKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzLnNlc3Npb25QbHVnaW5zW3Nlc3Npb25JZF07XG4gICAgfVxuXG4gICAgaWYgKF8uaXNFbXB0eSh0aGlzLnNlc3Npb25sZXNzUGx1Z2lucykpIHtcbiAgICAgIHRoaXMuc2Vzc2lvbmxlc3NQbHVnaW5zID0gdGhpcy5jcmVhdGVQbHVnaW5JbnN0YW5jZXMoKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuc2Vzc2lvbmxlc3NQbHVnaW5zO1xuICB9XG5cbiAgLyoqXG4gICAqIFRvIGdldCBwbHVnaW5zIGZvciBhIGNvbW1hbmQsIHdlIGVpdGhlciBnZXQgdGhlIHBsdWdpbiBpbnN0YW5jZXMgYXNzb2NpYXRlZCB3aXRoIHRoZVxuICAgKiBwYXJ0aWN1bGFyIGNvbW1hbmQncyBzZXNzaW9uLCBvciBpbiB0aGUgY2FzZSBvZiBzZXNzaW9ubGVzcyBwbHVnaW5zLCBwdWxsIGZyb20gdGhlIHNldCBvZlxuICAgKiBwbHVnaW4gaW5zdGFuY2VzIHJlc2VydmVkIGZvciBzZXNzaW9ubGVzcyBjb21tYW5kcyAoYW5kIHdlIGxhemlseSBjcmVhdGUgcGx1Z2luIGluc3RhbmNlcyBvblxuICAgKiBmaXJzdCB1c2UpXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBjbWQgLSB0aGUgbmFtZSBvZiB0aGUgY29tbWFuZCB0byBmaW5kIGEgcGx1Z2luIHRvIGhhbmRsZVxuICAgKiBAcGFyYW0gez9zdHJpbmd9IHNlc3Npb25JZCAtIHRoZSBwYXJ0aWN1bGFyIHNlc3Npb24gZm9yIHdoaWNoIHRvIGZpbmQgYSBwbHVnaW4sIG9yIG51bGwgaWZcbiAgICogc2Vzc2lvbmxlc3NcbiAgICovXG4gIHBsdWdpbnNUb0hhbmRsZUNtZCAoY21kLCBzZXNzaW9uSWQgPSBudWxsKSB7XG4gICAgLy8gdG8gaGFuZGxlIGEgZ2l2ZW4gY29tbWFuZCwgYSBwbHVnaW4gc2hvdWxkIGVpdGhlciBpbXBsZW1lbnQgdGhhdCBjb21tYW5kIGFzIGEgcGx1Z2luXG4gICAgLy8gaW5zdGFuY2UgbWV0aG9kIG9yIGl0IHNob3VsZCBpbXBsZW1lbnQgYSBnZW5lcmljICdoYW5kbGUnIG1ldGhvZFxuICAgIHJldHVybiB0aGlzLnBsdWdpbnNGb3JTZXNzaW9uKHNlc3Npb25JZClcbiAgICAgIC5maWx0ZXIoKHApID0+IF8uaXNGdW5jdGlvbihwW2NtZF0pIHx8IF8uaXNGdW5jdGlvbihwLmhhbmRsZSkpO1xuICB9XG5cbiAgY3JlYXRlUGx1Z2luSW5zdGFuY2VzICgpIHtcbiAgICByZXR1cm4gdGhpcy5wbHVnaW5DbGFzc2VzLm1hcCgoUGx1Z2luQ2xhc3MpID0+IHtcbiAgICAgIGNvbnN0IG5hbWUgPSBQbHVnaW5DbGFzcy5wbHVnaW5OYW1lO1xuICAgICAgY29uc3QgcGx1Z2luID0gbmV3IFBsdWdpbkNsYXNzKG5hbWUpO1xuICAgICAgdGhpcy5hc3NpZ25DbGlBcmdzVG9FeHRlbnNpb24oJ3BsdWdpbicsIG5hbWUsIHBsdWdpbik7XG4gICAgICByZXR1cm4gcGx1Z2luO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBjbWRcbiAgICogQHBhcmFtICB7Li4uYW55fSBhcmdzXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHt2YWx1ZTogYW55LCBlcnJvcj86IEVycm9yLCBwcm90b2NvbDogc3RyaW5nfSB8IGltcG9ydCgndHlwZS1mZXN0JykuQXN5bmNSZXR1cm5UeXBlPGltcG9ydCgnQGFwcGl1bS90eXBlcycpLkRyaXZlclsnZXhlY3V0ZUNvbW1hbmQnXT4+fVxuICAgKi9cbiAgYXN5bmMgZXhlY3V0ZUNvbW1hbmQgKGNtZCwgLi4uYXJncykge1xuICAgIC8vIFdlIGhhdmUgYmFzaWNhbGx5IHRocmVlIGNhc2VzIGZvciBob3cgdG8gaGFuZGxlIGNvbW1hbmRzOlxuICAgIC8vIDEuIGhhbmRsZSBnZXRTdGF0dXMgKHdlIGRvIHRoaXMgYXMgYSBzcGVjaWFsIG91dCBvZiBiYW5kIGNhc2Ugc28gaXQgZG9lc24ndCBnZXQgYWRkZWQgdG8gYW5cbiAgICAvLyAgICBleGVjdXRpb24gcXVldWUsIGFuZCBjYW4gYmUgY2FsbGVkIHdoaWxlIGUuZy4gY3JlYXRlU2Vzc2lvbiBpcyBpbiBwcm9ncmVzcylcbiAgICAvLyAyLiBoYW5kbGUgY29tbWFuZHMgdGhhdCB0aGlzIHVtYnJlbGxhIGRyaXZlciBzaG91bGQgaGFuZGxlLCByYXRoZXIgdGhhbiB0aGUgYWN0dWFsIHNlc3Npb25cbiAgICAvLyAgICBkcml2ZXIgKGZvciBleGFtcGxlLCBkZWxldGVTZXNzaW9uLCBvciBvdGhlciBub24tc2Vzc2lvbiBjb21tYW5kcylcbiAgICAvLyAzLiBoYW5kbGUgc2Vzc2lvbiBkcml2ZXIgY29tbWFuZHMuXG4gICAgLy8gVGhlIHRyaWNreSBwYXJ0IGlzIHRoYXQgYmVjYXVzZSB3ZSBzdXBwb3J0IGNvbW1hbmQgcGx1Z2lucywgd2UgbmVlZCB0byB3cmFwIGFueSBvZiB0aGVzZVxuICAgIC8vIGNhc2VzIHdpdGggcGx1Z2luIGhhbmRsaW5nLlxuXG4gICAgY29uc3QgaXNHZXRTdGF0dXMgPSBjbWQgPT09IEdFVF9TVEFUVVNfQ09NTUFORDtcbiAgICBjb25zdCBpc1VtYnJlbGxhQ21kID0gaXNBcHBpdW1Ecml2ZXJDb21tYW5kKGNtZCk7XG4gICAgY29uc3QgaXNTZXNzaW9uQ21kID0gaXNTZXNzaW9uQ29tbWFuZChjbWQpO1xuXG4gICAgLy8gaWYgYSBwbHVnaW4gb3ZlcnJpZGUgcHJveHlpbmcgZm9yIHRoaXMgY29tbWFuZCBhbmQgdGhhdCBpcyB3aHkgd2UgYXJlIGhlcmUgaW5zdGVhZCBvZiBqdXN0XG4gICAgLy8gbGV0dGluZyB0aGUgcHJvdG9jb2wgcHJveHkgdGhlIGNvbW1hbmQgZW50aXJlbHksIGRldGVybWluZSB0aGF0LCBnZXQgdGhlIHJlcXVlc3Qgb2JqZWN0IGZvclxuICAgIC8vIHVzZSBsYXRlciBvbiwgdGhlbiBjbGVhbiB1cCB0aGUgYXJnc1xuICAgIGNvbnN0IHJlcUZvclByb3h5ID0gXy5sYXN0KGFyZ3MpPy5yZXFGb3JQcm94eTtcbiAgICBpZiAocmVxRm9yUHJveHkpIHtcbiAgICAgIGFyZ3MucG9wKCk7XG4gICAgfVxuXG5cbiAgICAvLyBmaXJzdCBkbyBzb21lIGVycm9yIGNoZWNraW5nLiBJZiB3ZSdyZSByZXF1ZXN0aW5nIGEgc2Vzc2lvbiBjb21tYW5kIGV4ZWN1dGlvbiwgdGhlbiBtYWtlXG4gICAgLy8gc3VyZSB0aGF0IHNlc3Npb24gYWN0dWFsbHkgZXhpc3RzIG9uIHRoZSBzZXNzaW9uIGRyaXZlciwgYW5kIHNldCB0aGUgc2Vzc2lvbiBkcml2ZXIgaXRzZWxmXG4gICAgbGV0IHNlc3Npb25JZCA9IG51bGw7XG4gICAgbGV0IGRzdFNlc3Npb24gPSBudWxsO1xuICAgIGxldCBwcm90b2NvbCA9IG51bGw7XG4gICAgLyoqIEB0eXBlIHt0aGlzIHwgRXh0ZXJuYWxEcml2ZXJ9ICovXG4gICAgbGV0IGRyaXZlciA9IHRoaXM7XG4gICAgaWYgKGlzU2Vzc2lvbkNtZCkge1xuICAgICAgc2Vzc2lvbklkID0gXy5sYXN0KGFyZ3MpO1xuICAgICAgZHN0U2Vzc2lvbiA9IHRoaXMuc2Vzc2lvbnNbc2Vzc2lvbklkXTtcbiAgICAgIGlmICghZHN0U2Vzc2lvbikge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFRoZSBzZXNzaW9uIHdpdGggaWQgJyR7c2Vzc2lvbklkfScgZG9lcyBub3QgZXhpc3RgKTtcbiAgICAgIH1cbiAgICAgIC8vIG5vdyBzYXZlIHRoZSByZXNwb25zZSBwcm90b2NvbCBnaXZlbiB0aGF0IHRoZSBzZXNzaW9uIGRyaXZlcidzIHByb3RvY29sIG1pZ2h0IGRpZmZlclxuICAgICAgcHJvdG9jb2wgPSBkc3RTZXNzaW9uLnByb3RvY29sO1xuICAgICAgaWYgKCFpc1VtYnJlbGxhQ21kKSB7XG4gICAgICAgIGRyaXZlciA9IGRzdFNlc3Npb247XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gZ2V0IGFueSBwbHVnaW5zIHdoaWNoIGFyZSByZWdpc3RlcmVkIGFzIGhhbmRsaW5nIHRoaXMgY29tbWFuZFxuICAgIGNvbnN0IHBsdWdpbnMgPSB0aGlzLnBsdWdpbnNUb0hhbmRsZUNtZChjbWQsIHNlc3Npb25JZCk7XG5cbiAgICAvLyBub3cgd2UgZGVmaW5lIGEgJ2NtZEhhbmRsZWRCeScgb2JqZWN0IHdoaWNoIHdpbGwga2VlcCB0cmFjayBvZiB3aGljaCBwbHVnaW5zIGhhdmUgaGFuZGxlZCB0aGlzXG4gICAgLy8gY29tbWFuZC4gd2UgY2FyZSBhYm91dCB0aGlzIGJlY2F1c2UgKGEpIG11bHRpcGxlIHBsdWdpbnMgY2FuIGhhbmRsZSB0aGUgc2FtZSBjb21tYW5kLCBhbmRcbiAgICAvLyAoYikgdGhlcmUncyBubyBndWFyYW50ZWUgdGhhdCBhIHBsdWdpbiB3aWxsIGFjdHVhbGx5IGNhbGwgdGhlIG5leHQoKSBtZXRob2Qgd2hpY2ggcnVucyB0aGVcbiAgICAvLyBvcmlnaW5hbCBjb21tYW5kIGV4ZWN1dGlvbi4gVGhpcyByZXN1bHRzIGluIGEgc2l0dWF0aW9uIHdoZXJlIHRoZSBjb21tYW5kIG1pZ2h0IGJlIGhhbmRsZWRcbiAgICAvLyBieSBzb21lIGJ1dCBub3QgYWxsIHBsdWdpbnMsIG9yIGJ5IHBsdWdpbihzKSBidXQgbm90IGJ5IHRoZSBkZWZhdWx0IGJlaGF2aW9yLiBTbyBzdGFydCBvdXRcbiAgICAvLyB0aGlzIG9iamVjdCBkZWNsYXJpbmcgdGhhdCB0aGUgZGVmYXVsdCBoYW5kbGVyIGhhcyBub3QgYmVlbiBleGVjdXRlZC5cbiAgICBjb25zdCBjbWRIYW5kbGVkQnkgPSB7ZGVmYXVsdDogZmFsc2V9O1xuXG4gICAgLy8gbm93IHdlIGRlZmluZSBhbiBhc3luYyBmdW5jdGlvbiB3aGljaCB3aWxsIGJlIHBhc3NlZCB0byBwbHVnaW5zLCBhbmQgc3VjY2Vzc2l2ZWx5IHdyYXBwZWRcbiAgICAvLyBpZiB0aGVyZSBpcyBtb3JlIHRoYW4gb25lIHBsdWdpbiB0aGF0IGNhbiBoYW5kbGUgdGhlIGNvbW1hbmQuIFRvIHN0YXJ0IG9mZiB3aXRoLCB0aGUgYXN5bmNcbiAgICAvLyBmdW5jdGlvbiBpcyBkZWZpbmVkIGFzIGNhbGxpbmcgdGhlIGRlZmF1bHQgYmVoYXZpb3IsIGkuZS4sIHdoaWNoZXZlciBvZiB0aGUgMyBjYXNlcyBhYm92ZSBpc1xuICAgIC8vIHRoZSBhcHByb3ByaWF0ZSBvbmVcbiAgICBjb25zdCBkZWZhdWx0QmVoYXZpb3IgPSBhc3luYyAoKSA9PiB7XG4gICAgICAvLyBpZiB3ZSdyZSBydW5uaW5nIHdpdGggcGx1Z2lucywgbWFrZSBzdXJlIHdlIGxvZyB0aGF0IHRoZSBkZWZhdWx0IGJlaGF2aW9yIGlzIGFjdHVhbGx5XG4gICAgICAvLyBoYXBwZW5pbmcgc28gd2UgY2FuIHRlbGwgd2hlbiB0aGUgcGx1Z2luIGNhbGwgY2hhaW4gaXMgdW53cmFwcGluZyB0byB0aGUgZGVmYXVsdCBiZWhhdmlvclxuICAgICAgLy8gaWYgdGhhdCdzIHdoYXQgaGFwcGVuc1xuICAgICAgcGx1Z2lucy5sZW5ndGggJiYgdGhpcy5sb2cuaW5mbyhgRXhlY3V0aW5nIGRlZmF1bHQgaGFuZGxpbmcgYmVoYXZpb3IgZm9yIGNvbW1hbmQgJyR7Y21kfSdgKTtcblxuICAgICAgLy8gaWYgd2UgbWFrZSBpdCBoZXJlLCB3ZSBrbm93IHRoYXQgdGhlIGRlZmF1bHQgYmVoYXZpb3IgaXMgaGFuZGxlZFxuICAgICAgY21kSGFuZGxlZEJ5LmRlZmF1bHQgPSB0cnVlO1xuXG4gICAgICBpZiAocmVxRm9yUHJveHkpIHtcbiAgICAgICAgLy8gd2Ugd291bGQgaGF2ZSBwcm94aWVkIHRoaXMgY29tbWFuZCBoYWQgYSBwbHVnaW4gbm90IGhhbmRsZWQgaXQsIHNvIHRoZSBkZWZhdWx0IGJlaGF2aW9yXG4gICAgICAgIC8vIGlzIHRvIGRvIHRoZSBwcm94eSBhbmQgcmV0cmlldmUgdGhlIHJlc3VsdCBpbnRlcm5hbGx5IHNvIGl0IGNhbiBiZSBwYXNzZWQgdG8gdGhlIHBsdWdpblxuICAgICAgICAvLyBpbiBjYXNlIGl0IGNhbGxzICdhd2FpdCBuZXh0KCknLiBUaGlzIHJlcXVpcmVzIHRoYXQgdGhlIGRyaXZlciBoYXZlIGRlZmluZWRcbiAgICAgICAgLy8gJ3Byb3h5Q29tbWFuZCcgYW5kIG5vdCBqdXN0ICdwcm94eVJlcVJlcycuXG4gICAgICAgIGlmICghZHN0U2Vzc2lvbi5wcm94eUNvbW1hbmQpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgTm9Ecml2ZXJQcm94eUNvbW1hbmRFcnJvcigpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBhd2FpdCBkc3RTZXNzaW9uLnByb3h5Q29tbWFuZChyZXFGb3JQcm94eS5vcmlnaW5hbFVybCwgcmVxRm9yUHJveHkubWV0aG9kLFxuICAgICAgICAgIHJlcUZvclByb3h5LmJvZHkpO1xuICAgICAgfVxuXG4gICAgICBpZiAoaXNHZXRTdGF0dXMpIHtcbiAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuZ2V0U3RhdHVzKCk7XG4gICAgICB9XG5cbiAgICAgIGlmIChpc1VtYnJlbGxhQ21kKSB7XG4gICAgICAgIC8vIHNvbWUgY29tbWFuZHMsIGxpa2UgZGVsZXRlU2Vzc2lvbiwgd2Ugd2FudCB0byBtYWtlIHN1cmUgdG8gaGFuZGxlIG9uICp0aGlzKiBkcml2ZXIsXG4gICAgICAgIC8vIG5vdCB0aGUgcGxhdGZvcm0gZHJpdmVyXG4gICAgICAgIHJldHVybiBhd2FpdCBCYXNlRHJpdmVyLnByb3RvdHlwZS5leGVjdXRlQ29tbWFuZC5jYWxsKHRoaXMsIGNtZCwgLi4uYXJncyk7XG4gICAgICB9XG5cbiAgICAgIC8vIGhlcmUgd2Uga25vdyB0aGF0IHdlIGFyZSBleGVjdXRpbmcgYSBzZXNzaW9uIGNvbW1hbmQsIGFuZCBoYXZlIGEgdmFsaWQgc2Vzc2lvbiBkcml2ZXJcbiAgICAgIHJldHVybiBhd2FpdCBkc3RTZXNzaW9uLmV4ZWN1dGVDb21tYW5kKGNtZCwgLi4uYXJncyk7XG4gICAgfTtcblxuICAgIC8vIG5vdyB0YWtlIG91ciBkZWZhdWx0IGJlaGF2aW9yLCB3cmFwIGl0IHdpdGggYW55IG51bWJlciBvZiBwbHVnaW4gYmVoYXZpb3JzLCBhbmQgcnVuIGl0XG4gICAgY29uc3Qgd3JhcHBlZENtZCA9IHRoaXMud3JhcENvbW1hbmRXaXRoUGx1Z2lucyh7XG4gICAgICBkcml2ZXIsIGNtZCwgYXJncywgcGx1Z2lucywgY21kSGFuZGxlZEJ5LCBuZXh0OiBkZWZhdWx0QmVoYXZpb3JcbiAgICB9KTtcbiAgICBjb25zdCByZXMgPSBhd2FpdCB0aGlzLmV4ZWN1dGVXcmFwcGVkQ29tbWFuZCh7d3JhcHBlZENtZCwgcHJvdG9jb2x9KTtcblxuICAgIC8vIGlmIHdlIGhhZCBwbHVnaW5zLCBtYWtlIHN1cmUgdG8gbG9nIG91dCB0aGUgaGVscGZ1bCByZXBvcnQgYWJvdXQgd2hpY2ggcGx1Z2lucyBlbmRlZCB1cFxuICAgIC8vIGhhbmRsaW5nIHRoZSBjb21tYW5kIGFuZCB3aGljaCBkaWRuJ3RcbiAgICB0aGlzLmxvZ1BsdWdpbkhhbmRsZXJSZXBvcnQocGx1Z2lucywge2NtZCwgY21kSGFuZGxlZEJ5fSk7XG5cbiAgICAvLyBBbmQgZmluYWxseSwgaWYgdGhlIGNvbW1hbmQgd2FzIGNyZWF0ZVNlc3Npb24sIHdlIHdhbnQgdG8gbWlncmF0ZSBhbnkgcGx1Z2lucyB3aGljaCB3ZXJlXG4gICAgLy8gcHJldmlvdXNseSBzZXNzaW9ubGVzcyB0byB1c2UgdGhlIG5ldyBzZXNzaW9uSWQsIHNvIHRoYXQgcGx1Z2lucyBjYW4gc2hhcmUgc3RhdGUgYmV0d2VlblxuICAgIC8vIHRoZWlyIGNyZWF0ZVNlc3Npb24gbWV0aG9kIGFuZCBvdGhlciBpbnN0YW5jZSBtZXRob2RzXG4gICAgaWYgKGNtZCA9PT0gQ1JFQVRFX1NFU1NJT05fQ09NTUFORCAmJiB0aGlzLnNlc3Npb25sZXNzUGx1Z2lucy5sZW5ndGggJiYgIXJlcy5lcnJvcikge1xuICAgICAgY29uc3Qgc2Vzc2lvbklkID0gXy5maXJzdChyZXMudmFsdWUpO1xuICAgICAgdGhpcy5sb2cuaW5mbyhgUHJvbW90aW5nICR7dGhpcy5zZXNzaW9ubGVzc1BsdWdpbnMubGVuZ3RofSBzZXNzaW9ubGVzcyBwbHVnaW5zIHRvIGJlIGF0dGFjaGVkIGAgK1xuICAgICAgICBgdG8gc2Vzc2lvbiBJRCAke3Nlc3Npb25JZH1gKTtcbiAgICAgIHRoaXMuc2Vzc2lvblBsdWdpbnNbc2Vzc2lvbklkXSA9IHRoaXMuc2Vzc2lvbmxlc3NQbHVnaW5zO1xuICAgICAgdGhpcy5zZXNzaW9ubGVzc1BsdWdpbnMgPSBbXTtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVzO1xuICB9XG5cbiAgd3JhcENvbW1hbmRXaXRoUGx1Z2lucyAoe2RyaXZlciwgY21kLCBhcmdzLCBuZXh0LCBjbWRIYW5kbGVkQnksIHBsdWdpbnN9KSB7XG4gICAgcGx1Z2lucy5sZW5ndGggJiYgdGhpcy5sb2cuaW5mbyhgUGx1Z2lucyB3aGljaCBjYW4gaGFuZGxlIGNtZCAnJHtjbWR9JzogJHtwbHVnaW5zLm1hcCgocCkgPT4gcC5uYW1lKX1gKTtcblxuICAgIC8vIG5vdyB3ZSBjYW4gZ28gdGhyb3VnaCBlYWNoIHBsdWdpbiBhbmQgd3JhcCBgbmV4dGAgYXJvdW5kIGl0cyBvd24gaGFuZGxlciwgcGFzc2luZyB0aGUgKm9sZCpcbiAgICAvLyBuZXh0IGluIHNvIHRoYXQgaXQgY2FuIGNhbGwgaXQgaWYgaXQgd2FudHMgdG9cbiAgICBmb3IgKGNvbnN0IHBsdWdpbiBvZiBwbHVnaW5zKSB7XG4gICAgICAvLyBuZWVkIGFuIElJRkUgaGVyZSBiZWNhdXNlIHdlIHdhbnQgdGhlIHZhbHVlIG9mIG5leHQgdGhhdCdzIHBhc3NlZCB0byBwbHVnaW4uaGFuZGxlIHRvIGJlXG4gICAgICAvLyBleGFjdGx5IHRoZSB2YWx1ZSBvZiBuZXh0IGhlcmUgYmVmb3JlIHJlYXNzaWdubWVudDsgd2UgZG9uJ3Qgd2FudCBpdCB0byBiZSBsYXppbHlcbiAgICAgIC8vIGV2YWx1YXRlZCwgb3RoZXJ3aXNlIHdlIGVuZCB1cCB3aXRoIGluZmluaXRlIHJlY3Vyc2lvbiBvZiB0aGUgbGFzdCBgbmV4dGAgdG8gYmUgZGVmaW5lZC5cbiAgICAgIGNtZEhhbmRsZWRCeVtwbHVnaW4ubmFtZV0gPSBmYWxzZTsgLy8gd2Ugc2VlIGEgbmV3IHBsdWdpbiwgc28gYWRkIGl0IHRvIHRoZSAnY21kSGFuZGxlZEJ5JyBvYmplY3RcbiAgICAgIG5leHQgPSAoKF9uZXh0KSA9PiBhc3luYyAoKSA9PiB7XG4gICAgICAgIHRoaXMubG9nLmluZm8oYFBsdWdpbiAke3BsdWdpbi5uYW1lfSBpcyBub3cgaGFuZGxpbmcgY21kICcke2NtZH0nYCk7XG4gICAgICAgIGNtZEhhbmRsZWRCeVtwbHVnaW4ubmFtZV0gPSB0cnVlOyAvLyBpZiB3ZSBtYWtlIGl0IGhlcmUsIHRoaXMgcGx1Z2luIGhhcyBhdHRlbXB0ZWQgdG8gaGFuZGxlIGNtZFxuICAgICAgICAvLyBmaXJzdCBhdHRlbXB0IHRvIGhhbmRsZSB0aGUgY29tbWFuZCB2aWEgYSBjb21tYW5kLXNwZWNpZmljIGhhbmRsZXIgb24gdGhlIHBsdWdpblxuICAgICAgICBpZiAocGx1Z2luW2NtZF0pIHtcbiAgICAgICAgICByZXR1cm4gYXdhaXQgcGx1Z2luW2NtZF0oX25leHQsIGRyaXZlciwgLi4uYXJncyk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gb3RoZXJ3aXNlLCBjYWxsIHRoZSBnZW5lcmljICdoYW5kbGUnIG1ldGhvZFxuICAgICAgICByZXR1cm4gYXdhaXQgcGx1Z2luLmhhbmRsZShfbmV4dCwgZHJpdmVyLCBjbWQsIC4uLmFyZ3MpO1xuICAgICAgfSkobmV4dCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG5leHQ7XG4gIH1cblxuICBsb2dQbHVnaW5IYW5kbGVyUmVwb3J0IChwbHVnaW5zLCB7Y21kLCBjbWRIYW5kbGVkQnl9KSB7XG4gICAgaWYgKCFwbHVnaW5zLmxlbmd0aCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIGF0IHRoZSBlbmQgb2YgdGhlIGRheSwgd2UgaGF2ZSBhbiBvYmplY3QgcmVwcmVzZW50aW5nIHdoaWNoIHBsdWdpbnMgZW5kZWQgdXAgZ2V0dGluZ1xuICAgIC8vIHRoZWlyIGNvZGUgcnVuIGFzIHBhcnQgb2YgaGFuZGxpbmcgdGhpcyBjb21tYW5kLiBCZWNhdXNlIHBsdWdpbnMgY2FuIGNob29zZSAqbm90KiB0b1xuICAgIC8vIHBhc3MgY29udHJvbCB0byBvdGhlciBwbHVnaW5zIG9yIHRvIHRoZSBkZWZhdWx0IGRyaXZlciBiZWhhdmlvciwgdGhpcyBpcyBpbmZvcm1hdGlvblxuICAgIC8vIHdoaWNoIGlzIHByb2JhYmx5IHVzZWZ1bCB0byB0aGUgdXNlciAoZXNwZWNpYWxseSBpbiBzaXR1YXRpb25zIHdoZXJlIHBsdWdpbnMgbWlnaHQgbm90XG4gICAgLy8gaW50ZXJhY3Qgd2VsbCB0b2dldGhlciwgYW5kIGl0IHdvdWxkIGJlIGhhcmQgdG8gZGVidWcgb3RoZXJ3aXNlIHdpdGhvdXQgdGhpcyBraW5kIG9mXG4gICAgLy8gbWVzc2FnZSkuXG4gICAgY29uc3QgZGlkSGFuZGxlID0gT2JqZWN0LmtleXMoY21kSGFuZGxlZEJ5KS5maWx0ZXIoKGspID0+IGNtZEhhbmRsZWRCeVtrXSk7XG4gICAgY29uc3QgZGlkbnRIYW5kbGUgPSBPYmplY3Qua2V5cyhjbWRIYW5kbGVkQnkpLmZpbHRlcigoaykgPT4gIWNtZEhhbmRsZWRCeVtrXSk7XG4gICAgaWYgKGRpZG50SGFuZGxlLmxlbmd0aCA+IDApIHtcbiAgICAgIHRoaXMubG9nLmluZm8oYENvbW1hbmQgJyR7Y21kfScgd2FzICpub3QqIGhhbmRsZWQgYnkgdGhlIGZvbGxvd2luZyBiZWhhdmlvdXJzIG9yIHBsdWdpbnMsIGV2ZW4gYCArXG4gICAgICAgIGB0aG91Z2ggdGhleSB3ZXJlIHJlZ2lzdGVyZWQgdG8gaGFuZGxlIGl0OiAke0pTT04uc3RyaW5naWZ5KGRpZG50SGFuZGxlKX0uIFRoZSBgICtcbiAgICAgICAgYGNvbW1hbmQgKndhcyogaGFuZGxlZCBieSB0aGVzZTogJHtKU09OLnN0cmluZ2lmeShkaWRIYW5kbGUpfS5gKTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBleGVjdXRlV3JhcHBlZENvbW1hbmQgKHt3cmFwcGVkQ21kLCBwcm90b2NvbH0pIHtcbiAgICBsZXQgY21kUmVzLCBjbWRFcnIsIHJlcyA9IHt9O1xuICAgIHRyeSB7XG4gICAgICAvLyBBdCB0aGlzIHBvaW50LCBgd3JhcHBlZENtZGAgZGVmaW5lcyBhIHdob2xlIHNlcXVlbmNlIG9mIHBsdWdpbiBoYW5kbGVycywgY3VsbWluYXRpbmcgaW5cbiAgICAgIC8vIG91ciBkZWZhdWx0IGhhbmRsZXIuIFdoYXRldmVyIGl0IHJldHVybnMgaXMgd2hhdCB3ZSdyZSBnb2luZyB0byB3YW50IHRvIHNlbmQgYmFjayB0byB0aGVcbiAgICAgIC8vIHVzZXIuXG4gICAgICBjbWRSZXMgPSBhd2FpdCB3cmFwcGVkQ21kKCk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgY21kRXJyID0gZTtcbiAgICB9XG5cbiAgICAvLyBTYWRseSwgd2UgZG9uJ3Qga25vdyBleGFjdGx5IHdoYXQga2luZCBvZiBvYmplY3Qgd2lsbCBiZSByZXR1cm5lZC4gSXQgd2lsbCBlaXRoZXIgYmUgYSBiYXJlXG4gICAgLy8gb2JqZWN0LCBvciBhIHByb3RvY29sLWF3YXJlIG9iamVjdCB3aXRoIHByb3RvY29sIGFuZCBlcnJvci92YWx1ZSBrZXlzLiBTbyB3ZSBuZWVkIHRvIHNuaWZmXG4gICAgLy8gaXQgYW5kIG1ha2Ugc3VyZSB3ZSBkb24ndCBkb3VibGUtd3JhcCBpdCBpZiBpdCdzIHRoZSBsYXR0ZXIga2luZC5cbiAgICBpZiAoXy5pc1BsYWluT2JqZWN0KGNtZFJlcykgJiYgXy5oYXMoY21kUmVzLCAncHJvdG9jb2wnKSkge1xuICAgICAgcmVzID0gY21kUmVzO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXMudmFsdWUgPSBjbWRSZXM7XG4gICAgICByZXMuZXJyb3IgPSBjbWRFcnI7XG4gICAgICByZXMucHJvdG9jb2wgPSBwcm90b2NvbDtcbiAgICB9XG4gICAgcmV0dXJuIHJlcztcbiAgfVxuXG4gIHByb3h5QWN0aXZlIChzZXNzaW9uSWQpIHtcbiAgICBjb25zdCBkc3RTZXNzaW9uID0gdGhpcy5zZXNzaW9uc1tzZXNzaW9uSWRdO1xuICAgIHJldHVybiBkc3RTZXNzaW9uICYmIF8uaXNGdW5jdGlvbihkc3RTZXNzaW9uLnByb3h5QWN0aXZlKSAmJiBkc3RTZXNzaW9uLnByb3h5QWN0aXZlKHNlc3Npb25JZCk7XG4gIH1cblxuICBnZXRQcm94eUF2b2lkTGlzdCAoc2Vzc2lvbklkKSB7XG4gICAgY29uc3QgZHN0U2Vzc2lvbiA9IHRoaXMuc2Vzc2lvbnNbc2Vzc2lvbklkXTtcbiAgICByZXR1cm4gZHN0U2Vzc2lvbiA/IGRzdFNlc3Npb24uZ2V0UHJveHlBdm9pZExpc3QoKSA6IFtdO1xuICB9XG5cbiAgY2FuUHJveHkgKHNlc3Npb25JZCkge1xuICAgIGNvbnN0IGRzdFNlc3Npb24gPSB0aGlzLnNlc3Npb25zW3Nlc3Npb25JZF07XG4gICAgcmV0dXJuIGRzdFNlc3Npb24gJiYgZHN0U2Vzc2lvbi5jYW5Qcm94eShzZXNzaW9uSWQpO1xuICB9XG59XG5cbi8vIGhlbHAgZGVjaWRlIHdoaWNoIGNvbW1hbmRzIHNob3VsZCBiZSBwcm94aWVkIHRvIHN1Yi1kcml2ZXJzIGFuZCB3aGljaFxuLy8gc2hvdWxkIGJlIGhhbmRsZWQgYnkgdGhpcywgb3VyIHVtYnJlbGxhIGRyaXZlclxuZnVuY3Rpb24gaXNBcHBpdW1Ecml2ZXJDb21tYW5kIChjbWQpIHtcbiAgcmV0dXJuICFpc1Nlc3Npb25Db21tYW5kKGNtZCkgfHwgY21kID09PSBERUxFVEVfU0VTU0lPTl9DT01NQU5EO1xufVxuXG4vKipcbiAqIFRocm93biB3aGVuIEFwcGl1bSB0cmllZCB0byBwcm94eSBhIGNvbW1hbmQgdXNpbmcgYSBkcml2ZXIncyBgcHJveHlDb21tYW5kYCBtZXRob2QgYnV0IHRoZVxuICogbWV0aG9kIGRpZCBub3QgZXhpc3RcbiAqL1xuZXhwb3J0IGNsYXNzIE5vRHJpdmVyUHJveHlDb21tYW5kRXJyb3IgZXh0ZW5kcyBFcnJvciB7XG4gIC8qKlxuICAgKiBAdHlwZSB7UmVhZG9ubHk8c3RyaW5nPn1cbiAgICovXG4gIGNvZGUgPSAnQVBQSVVNRVJSX05PX0RSSVZFUl9QUk9YWUNPTU1BTkQnO1xuXG4gIGNvbnN0cnVjdG9yICgpIHtcbiAgICBzdXBlcihgVGhlIGRlZmF1bHQgYmVoYXZpb3IgZm9yIHRoaXMgY29tbWFuZCB3YXMgdG8gcHJveHksIGJ1dCB0aGUgZHJpdmVyIGAgK1xuICAgICAgICAgIGBkaWQgbm90IGhhdmUgdGhlICdwcm94eUNvbW1hbmQnIG1ldGhvZCBkZWZpbmVkLiBUbyBmdWxseSBzdXBwb3J0IGAgK1xuICAgICAgICAgIGBwbHVnaW5zLCBkcml2ZXJzIHNob3VsZCBoYXZlICdwcm94eUNvbW1hbmQnIHNldCB0byBhIGp3cFByb3h5IG9iamVjdCdzIGAgK1xuICAgICAgICAgIGAnY29tbWFuZCgpJyBtZXRob2QsIGluIGFkZGl0aW9uIHRvIHRoZSBub3JtYWwgJ3Byb3h5UmVxUmVzJ2ApO1xuICB9XG59XG5cbmV4cG9ydCB7IEFwcGl1bURyaXZlciB9O1xuXG4vKipcbiAqIEB0eXBlZGVmIHtpbXBvcnQoJ0BhcHBpdW0vdHlwZXMnKS5FeHRlcm5hbERyaXZlcn0gRXh0ZXJuYWxEcml2ZXJcbiAqIEB0eXBlZGVmIHtpbXBvcnQoJ0BhcHBpdW0vdHlwZXMnKS5XM0NDYXBhYmlsaXRpZXN9IFczQ0NhcGFiaWxpdGllc1xuICogQHR5cGVkZWYge2ltcG9ydCgnQGFwcGl1bS90eXBlcycpLkRyaXZlckRhdGF9IERyaXZlckRhdGFcbiAqIEB0eXBlZGVmIHtpbXBvcnQoJ0BhcHBpdW0vdHlwZXMnKS5TZXJ2ZXJBcmdzfSBEcml2ZXJPcHRzXG4gKiBAdHlwZWRlZiB7aW1wb3J0KCdAYXBwaXVtL3R5cGVzJykuQ29uc3RyYWludHN9IENvbnN0cmFpbnRzXG4gKiBAdHlwZWRlZiB7aW1wb3J0KCdAYXBwaXVtL3R5cGVzJykuQXBwaXVtU2VydmVyfSBBcHBpdW1TZXJ2ZXJcbiAqIEB0eXBlZGVmIHtpbXBvcnQoJy4uL3R5cGVzJykuRXh0ZW5zaW9uVHlwZX0gRXh0ZW5zaW9uVHlwZVxuICogQHR5cGVkZWYge2ltcG9ydCgnLi4vdHlwZXMvZXh0ZW5zaW9uJykuUGx1Z2luQ2xhc3N9IFBsdWdpbkNsYXNzXG4gKiBAdHlwZWRlZiB7aW1wb3J0KCcuL2V4dGVuc2lvbi9kcml2ZXItY29uZmlnJykuRHJpdmVyQ29uZmlnfSBEcml2ZXJDb25maWdcbiAqL1xuXG4vKipcbiAqIFVzZWQgYnkge0BsaW5rY29kZSBBcHBpdW1Ecml2ZXIuY3JlYXRlU2Vzc2lvbn0gYW5kIHtAbGlua2NvZGUgQXBwaXVtRHJpdmVyLmRlbGV0ZVNlc3Npb259IHRvIGRlc2NyaWJlXG4gKiByZXN1bHQuXG4gKiBAdGVtcGxhdGUgVlxuICogQHR5cGVkZWYgU2Vzc2lvbkhhbmRsZXJSZXN1bHRcbiAqIEBwcm9wZXJ0eSB7Vn0gW3ZhbHVlXVxuICogQHByb3BlcnR5IHtFcnJvcn0gW2Vycm9yXVxuICogQHByb3BlcnR5IHtzdHJpbmd9IFtwcm90b2NvbF1cbiAqL1xuXG4vKipcbiAqIEB0eXBlZGVmIHtpbXBvcnQoJ0BhcHBpdW0vdHlwZXMnKS5TZXNzaW9uSGFuZGxlcjxTZXNzaW9uSGFuZGxlclJlc3VsdDxhbnlbXT4sU2Vzc2lvbkhhbmRsZXJSZXN1bHQ8dm9pZD4+fSBTZXNzaW9uSGFuZGxlclxuICovXG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7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
|