1 | import { createEndpoint } from '@neo-one/node-core-esnext-esm';
|
2 | import { Config, killProcess } from '@neo-one/server-plugin-esnext-esm';
|
3 | import fetch from 'cross-fetch';
|
4 | import execa from 'execa';
|
5 | import * as fs from 'fs-extra';
|
6 | import _ from 'lodash';
|
7 | import * as path from 'path';
|
8 | import { take } from 'rxjs/operators';
|
9 | import { NodeAdapter } from './NodeAdapter';
|
10 | const DEFAULT_RPC_URLS = [
|
11 | 'http://node1.nyc3.bridgeprotocol.io:10332',
|
12 | 'http://node2.nyc3.bridgeprotocol.io:10332',
|
13 | 'https://seed1.switcheo.network:10331',
|
14 | 'https://seed2.switcheo.network:10331',
|
15 | 'https://seed3.switcheo.network:10331',
|
16 | 'http://seed1.aphelion-neo.com:10332',
|
17 | 'http://seed2.aphelion-neo.com:10332',
|
18 | 'http://seed3.aphelion-neo.com:10332',
|
19 | 'http://seed4.aphelion-neo.com:10332',
|
20 | ];
|
21 | const DEFAULT_SEEDS = [
|
22 | { type: 'tcp', host: 'node1.nyc3.bridgeprotocol.io', port: 10333 },
|
23 | { type: 'tcp', host: 'node2.nyc3.bridgeprotocol.io', port: 10333 },
|
24 | { type: 'tcp', host: 'seed1.switcheo.com', port: 10333 },
|
25 | { type: 'tcp', host: 'seed2.switcheo.com', port: 10333 },
|
26 | { type: 'tcp', host: 'seed3.switcheo.com', port: 10333 },
|
27 | { type: 'tcp', host: 'seed1.aphelion-neo.com', port: 10333 },
|
28 | { type: 'tcp', host: 'seed2.aphelion-neo.com', port: 10333 },
|
29 | { type: 'tcp', host: 'seed3.aphelion-neo.com', port: 10333 },
|
30 | { type: 'tcp', host: 'seed4.aphelion-neo.com', port: 10333 },
|
31 | ];
|
32 | const makeDefaultConfig = (dataPath) => ({
|
33 | log: {
|
34 | level: 'info',
|
35 | maxSize: 10 * 1024 * 1024,
|
36 | maxFiles: 5,
|
37 | },
|
38 | settings: {
|
39 | test: false,
|
40 | },
|
41 | environment: {
|
42 | dataPath: path.resolve(dataPath, 'node'),
|
43 | rpc: {},
|
44 | node: {},
|
45 | network: {},
|
46 | },
|
47 | options: {
|
48 | node: {
|
49 | consensus: {
|
50 | enabled: false,
|
51 | options: { privateKey: 'default', privateNet: false },
|
52 | },
|
53 | rpcURLs: [...DEFAULT_RPC_URLS],
|
54 | },
|
55 | network: {
|
56 | seeds: DEFAULT_SEEDS.map(createEndpoint),
|
57 | },
|
58 | rpc: {
|
59 | server: {
|
60 | keepAliveTimeout: 60000,
|
61 | },
|
62 | liveHealthCheck: {
|
63 | rpcURLs: DEFAULT_RPC_URLS,
|
64 | offset: 1,
|
65 | timeoutMS: 5000,
|
66 | },
|
67 | readyHealthCheck: {
|
68 | rpcURLs: DEFAULT_RPC_URLS,
|
69 | offset: 1,
|
70 | timeoutMS: 5000,
|
71 | },
|
72 | },
|
73 | },
|
74 | });
|
75 | export const createNodeConfig = ({ dataPath, defaultConfig = makeDefaultConfig(dataPath), }) => new Config({
|
76 | name: 'node',
|
77 | defaultConfig,
|
78 | schema: {
|
79 | type: 'object',
|
80 | required: ['log'],
|
81 | properties: {
|
82 | log: {
|
83 | type: 'object',
|
84 | required: ['level', 'maxSize', 'maxFiles'],
|
85 | properties: {
|
86 | level: { type: 'string' },
|
87 | maxSize: { type: 'number' },
|
88 | maxFiles: { type: 'number' },
|
89 | },
|
90 | },
|
91 | settings: {
|
92 | type: 'object',
|
93 | required: ['test'],
|
94 | properties: {
|
95 | test: { type: 'boolean' },
|
96 | privateNet: { type: 'boolean' },
|
97 | secondsPerBlock: { type: 'number' },
|
98 | standbyValidators: { type: 'array', items: { type: 'string' } },
|
99 | },
|
100 | },
|
101 | environment: {
|
102 | type: 'object',
|
103 | required: ['dataPath', 'rpc', 'node', 'network'],
|
104 | properties: {
|
105 | dataPath: { type: 'string' },
|
106 | rpc: {
|
107 | type: 'object',
|
108 | required: [],
|
109 | properties: {
|
110 | http: {
|
111 | type: 'object',
|
112 | required: ['host', 'port'],
|
113 | properties: {
|
114 | host: { type: 'string' },
|
115 | port: { type: 'number' },
|
116 | },
|
117 | },
|
118 | https: {
|
119 | type: 'object',
|
120 | required: ['host', 'port', 'key', 'cert'],
|
121 | properties: {
|
122 | host: { type: 'string' },
|
123 | port: { type: 'number' },
|
124 | key: { type: 'string' },
|
125 | cert: { type: 'string' },
|
126 | },
|
127 | },
|
128 | },
|
129 | },
|
130 | node: {
|
131 | type: 'object',
|
132 | required: [],
|
133 | properties: {
|
134 | externalPort: { type: 'number' },
|
135 | },
|
136 | },
|
137 | network: {
|
138 | type: 'object',
|
139 | required: [],
|
140 | properties: {
|
141 | listenTCP: {
|
142 | type: 'object',
|
143 | required: ['port'],
|
144 | properties: {
|
145 | host: { type: 'string' },
|
146 | port: { type: 'number' },
|
147 | },
|
148 | },
|
149 | externalEndpoints: {
|
150 | type: 'array',
|
151 | items: { type: 'string' },
|
152 | },
|
153 | connectPeersDelayMS: { type: 'number' },
|
154 | socketTimeoutMS: { type: 'number' },
|
155 | },
|
156 | },
|
157 | },
|
158 | },
|
159 | options: {
|
160 | type: 'object',
|
161 | required: ['node', 'network', 'rpc'],
|
162 | properties: {
|
163 | node: {
|
164 | type: 'object',
|
165 | required: ['consensus', 'rpcURLs'],
|
166 | properties: {
|
167 | consensus: {
|
168 | type: 'object',
|
169 | required: ['enabled', 'options'],
|
170 | properties: {
|
171 | enabled: { type: 'boolean' },
|
172 | options: {
|
173 | type: 'object',
|
174 | required: ['privateKey', 'privateNet'],
|
175 | properties: {
|
176 | privateKey: { type: 'string' },
|
177 | privateNet: { type: 'boolean' },
|
178 | },
|
179 | },
|
180 | },
|
181 | },
|
182 | rpcURLs: { type: 'array', items: { type: 'string' } },
|
183 | },
|
184 | },
|
185 | network: {
|
186 | type: 'object',
|
187 | required: ['seeds'],
|
188 | properties: {
|
189 | seeds: { type: 'array', items: { type: 'string' } },
|
190 | maxConnectedPeers: { type: 'number' },
|
191 | },
|
192 | },
|
193 | rpc: {
|
194 | type: 'object',
|
195 | required: ['server', 'liveHealthCheck', 'readyHealthCheck'],
|
196 | properties: {
|
197 | server: {
|
198 | type: 'object',
|
199 | required: ['keepAliveTimeout'],
|
200 | properties: {
|
201 | keepAliveTimeout: { type: 'number' },
|
202 | },
|
203 | },
|
204 | liveHealthCheck: {
|
205 | type: 'object',
|
206 | required: ['rpcURLs', 'offset', 'timeoutMS'],
|
207 | properties: {
|
208 | rpcURLs: { type: 'array', items: { type: 'string' } },
|
209 | offset: { type: 'number' },
|
210 | timeoutMS: { type: 'number' },
|
211 | },
|
212 | },
|
213 | readyHealthCheck: {
|
214 | type: 'object',
|
215 | required: ['rpcURLs', 'offset', 'timeoutMS'],
|
216 | properties: {
|
217 | rpcURLs: { type: 'array', items: { type: 'string' } },
|
218 | offset: { type: 'number' },
|
219 | timeoutMS: { type: 'number' },
|
220 | },
|
221 | },
|
222 | },
|
223 | },
|
224 | },
|
225 | },
|
226 | },
|
227 | },
|
228 | configPath: dataPath,
|
229 | });
|
230 | export class NEOONENodeAdapter extends NodeAdapter {
|
231 | constructor({ monitor, name, binary, dataPath, settings, }) {
|
232 | super({
|
233 | monitor: monitor.at('neo_one_node_adapter'),
|
234 | name,
|
235 | binary,
|
236 | dataPath,
|
237 | settings,
|
238 | });
|
239 | }
|
240 | getDebug() {
|
241 | return super
|
242 | .getDebug()
|
243 | .concat([
|
244 | ['Process ID', this.mutableProcess === undefined ? 'null' : `${this.mutableProcess.pid}`],
|
245 | ['Config Path', this.mutableConfig === undefined ? 'null' : this.mutableConfig.configPath],
|
246 | ]);
|
247 | }
|
248 | getNodeStatus() {
|
249 | return {
|
250 | rpcAddress: this.getAddress('/rpc'),
|
251 | tcpAddress: `localhost:${this.mutableSettings.listenTCPPort}`,
|
252 | telemetryAddress: `http://localhost:${this.mutableSettings.telemetryPort}/metrics`,
|
253 | };
|
254 | }
|
255 | async isLive() {
|
256 | return this.checkRPC('/live_health_check');
|
257 | }
|
258 | async isReady() {
|
259 | return this.checkRPC('/ready_health_check');
|
260 | }
|
261 | async createInternal() {
|
262 | await this.writeSettings(this.mutableSettings);
|
263 | }
|
264 | async updateInternal(settings) {
|
265 | const restart = await this.writeSettings(settings);
|
266 | if (restart && this.mutableProcess !== undefined) {
|
267 | await this.stop();
|
268 | await this.start();
|
269 | }
|
270 | }
|
271 | async startInternal() {
|
272 | if (this.mutableProcess === undefined) {
|
273 | const child = execa(this.binary.cmd, this.binary.firstArgs.concat(['start', 'node', this.dataPath]), {
|
274 | // @ts-ignore
|
275 | windowsHide: true,
|
276 | stdio: 'ignore',
|
277 | });
|
278 | this.mutableProcess = child;
|
279 | // tslint:disable-next-line no-floating-promises
|
280 | child
|
281 | .then(() => {
|
282 | this.monitor.log({
|
283 | name: 'neo_node_adapter_node_exit',
|
284 | message: 'Child process exited',
|
285 | });
|
286 | this.mutableProcess = undefined;
|
287 | })
|
288 | .catch((error) => {
|
289 | this.monitor.logError({
|
290 | name: 'neo_node_adapter_node_error',
|
291 | message: 'Child process exited with an error.',
|
292 | error,
|
293 | });
|
294 | this.mutableProcess = undefined;
|
295 | });
|
296 | }
|
297 | }
|
298 | async stopInternal() {
|
299 | const child = this.mutableProcess;
|
300 | this.mutableProcess = undefined;
|
301 | if (child !== undefined) {
|
302 | await killProcess(child.pid);
|
303 | }
|
304 | }
|
305 | async checkRPC(rpcPath) {
|
306 | try {
|
307 | const response = await fetch(this.getAddress(rpcPath));
|
308 | return response.ok;
|
309 | }
|
310 | catch (error) {
|
311 | if (error.code !== 'ECONNREFUSED') {
|
312 | this.monitor.withData({ [this.monitor.labels.HTTP_PATH]: rpcPath }).logError({
|
313 | name: 'http_client_request',
|
314 | message: 'Failed to check RPC.',
|
315 | error,
|
316 | });
|
317 | }
|
318 | return false;
|
319 | }
|
320 | }
|
321 | getAddress(rpcPath) {
|
322 | return `http://localhost:${this.mutableSettings.rpcPort}${rpcPath}`;
|
323 | }
|
324 | async writeSettings(settings) {
|
325 | let config = this.mutableConfig;
|
326 | if (config === undefined) {
|
327 | config = createNodeConfig({
|
328 | dataPath: this.dataPath,
|
329 | defaultConfig: this.createConfig(settings),
|
330 | });
|
331 | this.mutableConfig = config;
|
332 | }
|
333 | const nodeConfig = await config.config$.pipe(take(1)).toPromise();
|
334 | const newNodeConfig = this.createConfig(settings);
|
335 | await fs.ensureDir(newNodeConfig.environment.dataPath);
|
336 | await config.update({ config: newNodeConfig });
|
337 | return !(_.isEqual(nodeConfig.settings, newNodeConfig.settings) &&
|
338 | _.isEqual(nodeConfig.environment, newNodeConfig.environment));
|
339 | }
|
340 | createConfig(settings) {
|
341 | return {
|
342 | log: {
|
343 | level: 'info',
|
344 | maxSize: 10 * 1024 * 1024,
|
345 | maxFiles: 5,
|
346 | },
|
347 | settings: {
|
348 | test: settings.isTestNet,
|
349 | privateNet: settings.privateNet,
|
350 | secondsPerBlock: settings.secondsPerBlock,
|
351 | standbyValidators: settings.standbyValidators,
|
352 | address: settings.address,
|
353 | },
|
354 | environment: {
|
355 | dataPath: path.resolve(this.dataPath, 'chain'),
|
356 | rpc: {
|
357 | http: {
|
358 | port: settings.rpcPort,
|
359 | host: '0.0.0.0',
|
360 | },
|
361 | },
|
362 | node: {
|
363 | externalPort: settings.listenTCPPort,
|
364 | },
|
365 | network: {
|
366 | listenTCP: {
|
367 | port: settings.listenTCPPort,
|
368 | host: '0.0.0.0',
|
369 | },
|
370 | },
|
371 | telemetry: {
|
372 | port: settings.telemetryPort,
|
373 | },
|
374 | },
|
375 | options: {
|
376 | node: {
|
377 | consensus: settings.consensus,
|
378 | rpcURLs: settings.rpcEndpoints,
|
379 | },
|
380 | network: {
|
381 | seeds: settings.seeds,
|
382 | },
|
383 | rpc: {
|
384 | server: {
|
385 | keepAliveTimeout: 60000,
|
386 | },
|
387 | liveHealthCheck: {
|
388 | rpcURLs: settings.rpcEndpoints,
|
389 | offset: 1,
|
390 | timeoutMS: 5000,
|
391 | },
|
392 | readyHealthCheck: {
|
393 | rpcURLs: settings.rpcEndpoints,
|
394 | offset: 1,
|
395 | timeoutMS: 5000,
|
396 | },
|
397 | },
|
398 | },
|
399 | };
|
400 | }
|
401 | }
|
402 |
|
403 | //# sourceMappingURL=data:application/json;charset=utf8;base64,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T0FBTyxFQUFFO29CQUNQLFNBQVMsRUFBRTt3QkFDVCxJQUFJLEVBQUUsUUFBUSxDQUFDLGFBQWE7d0JBQzVCLElBQUksRUFBRSxTQUFTO3FCQUNoQjtpQkFDRjtnQkFDRCxTQUFTLEVBQUU7b0JBQ1QsSUFBSSxFQUFFLFFBQVEsQ0FBQyxhQUFhO2lCQUM3QjthQUNGO1lBQ0QsT0FBTyxFQUFFO2dCQUNQLElBQUksRUFBRTtvQkFDSixTQUFTLEVBQUUsUUFBUSxDQUFDLFNBQVM7b0JBQzdCLE9BQU8sRUFBRSxRQUFRLENBQUMsWUFBWTtpQkFDL0I7Z0JBQ0QsT0FBTyxFQUFFO29CQUNQLEtBQUssRUFBRSxRQUFRLENBQUMsS0FBSztpQkFDdEI7Z0JBQ0QsR0FBRyxFQUFFO29CQUNILE1BQU0sRUFBRTt3QkFDTixnQkFBZ0IsRUFBRSxLQUFLO3FCQUN4QjtvQkFDRCxlQUFlLEVBQUU7d0JBQ2YsT0FBTyxFQUFFLFFBQVEsQ0FBQyxZQUFZO3dCQUM5QixNQUFNLEVBQUUsQ0FBQzt3QkFDVCxTQUFTLEVBQUUsSUFBSTtxQkFDaEI7b0JBQ0QsZ0JBQWdCLEVBQUU7d0JBQ2hCLE9BQU8sRUFBRSxRQUFRLENBQUMsWUFBWTt3QkFDOUIsTUFBTSxFQUFFLENBQUM7d0JBQ1QsU0FBUyxFQUFFLElBQUk7cUJBQ2hCO2lCQUNGO2FBQ0Y7U0FDRixDQUFDO0lBQ0osQ0FBQztDQUNGIiwiZmlsZSI6Im5lby1vbmUtc2VydmVyLXBsdWdpbi1uZXR3b3JrL3NyYy9ub2RlL05FT09ORU5vZGVBZGFwdGVyLmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgTW9uaXRvciB9IGZyb20gJ0BuZW8tb25lL21vbml0b3InO1xuaW1wb3J0IHsgRnVsbE5vZGVFbnZpcm9ubWVudCwgRnVsbE5vZGVPcHRpb25zIH0gZnJvbSAnQG5lby1vbmUvbm9kZSc7XG5pbXBvcnQgeyBjcmVhdGVFbmRwb2ludCwgRW5kcG9pbnRDb25maWcgfSBmcm9tICdAbmVvLW9uZS9ub2RlLWNvcmUnO1xuaW1wb3J0IHsgQmluYXJ5LCBDb25maWcsIERlc2NyaWJlVGFibGUsIGtpbGxQcm9jZXNzIH0gZnJvbSAnQG5lby1vbmUvc2VydmVyLXBsdWdpbic7XG5pbXBvcnQgZmV0Y2ggZnJvbSAnY3Jvc3MtZmV0Y2gnO1xuaW1wb3J0IGV4ZWNhIGZyb20gJ2V4ZWNhJztcbmltcG9ydCAqIGFzIGZzIGZyb20gJ2ZzLWV4dHJhJztcbmltcG9ydCBfIGZyb20gJ2xvZGFzaCc7XG5pbXBvcnQgKiBhcyBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0IHsgdGFrZSB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7IE5vZGVTZXR0aW5ncyB9IGZyb20gJy4uL3R5cGVzJztcbmltcG9ydCB7IE5vZGVBZGFwdGVyLCBOb2RlU3RhdHVzIH0gZnJvbSAnLi9Ob2RlQWRhcHRlcic7XG5cbmV4cG9ydCBpbnRlcmZhY2UgTm9kZUNvbmZpZyB7XG4gIHJlYWRvbmx5IGxvZzoge1xuICAgIHJlYWRvbmx5IGxldmVsOiBzdHJpbmc7XG4gICAgcmVhZG9ubHkgbWF4U2l6ZTogbnVtYmVyO1xuICAgIHJlYWRvbmx5IG1heEZpbGVzOiBudW1iZXI7XG4gIH07XG5cbiAgcmVhZG9ubHkgc2V0dGluZ3M6IHtcbiAgICByZWFkb25seSB0ZXN0PzogYm9vbGVhbjtcbiAgICByZWFkb25seSBwcml2YXRlTmV0PzogYm9vbGVhbjtcbiAgICByZWFkb25seSBzZWNvbmRzUGVyQmxvY2s/OiBudW1iZXI7XG4gICAgcmVhZG9ubHkgc3RhbmRieVZhbGlkYXRvcnM/OiBSZWFkb25seUFycmF5PHN0cmluZz47XG4gICAgcmVhZG9ubHkgYWRkcmVzcz86IHN0cmluZztcbiAgfTtcblxuICByZWFkb25seSBlbnZpcm9ubWVudDogRnVsbE5vZGVFbnZpcm9ubWVudDtcbiAgcmVhZG9ubHkgb3B0aW9uczogRnVsbE5vZGVPcHRpb25zO1xufVxuXG5jb25zdCBERUZBVUxUX1JQQ19VUkxTOiBSZWFkb25seUFycmF5PHN0cmluZz4gPSBbXG4gICdodHRwOi8vbm9kZTEubnljMy5icmlkZ2Vwcm90b2NvbC5pbzoxMDMzMicsXG4gICdodHRwOi8vbm9kZTIubnljMy5icmlkZ2Vwcm90b2NvbC5pbzoxMDMzMicsXG4gICdodHRwczovL3NlZWQxLnN3aXRjaGVvLm5ldHdvcms6MTAzMzEnLFxuICAnaHR0cHM6Ly9zZWVkMi5zd2l0Y2hlby5uZXR3b3JrOjEwMzMxJyxcbiAgJ2h0dHBzOi8vc2VlZDMuc3dpdGNoZW8ubmV0d29yazoxMDMzMScsXG4gICdodHRwOi8vc2VlZDEuYXBoZWxpb24tbmVvLmNvbToxMDMzMicsXG4gICdodHRwOi8vc2VlZDIuYXBoZWxpb24tbmVvLmNvbToxMDMzMicsXG4gICdodHRwOi8vc2VlZDMuYXBoZWxpb24tbmVvLmNvbToxMDMzMicsXG4gICdodHRwOi8vc2VlZDQuYXBoZWxpb24tbmVvLmNvbToxMDMzMicsXG5dO1xuXG5jb25zdCBERUZBVUxUX1NFRURTOiBSZWFkb25seUFycmF5PEVuZHBvaW50Q29uZmlnPiA9IFtcbiAgeyB0eXBlOiAndGNwJywgaG9zdDogJ25vZGUxLm55YzMuYnJpZGdlcHJvdG9jb2wuaW8nLCBwb3J0OiAxMDMzMyB9LFxuICB7IHR5cGU6ICd0Y3AnLCBob3N0OiAnbm9kZTIubnljMy5icmlkZ2Vwcm90b2NvbC5pbycsIHBvcnQ6IDEwMzMzIH0sXG4gIHsgdHlwZTogJ3RjcCcsIGhvc3Q6ICdzZWVkMS5zd2l0Y2hlby5jb20nLCBwb3J0OiAxMDMzMyB9LFxuICB7IHR5cGU6ICd0Y3AnLCBob3N0OiAnc2VlZDIuc3dpdGNoZW8uY29tJywgcG9ydDogMTAzMzMgfSxcbiAgeyB0eXBlOiAndGNwJywgaG9zdDogJ3NlZWQzLnN3aXRjaGVvLmNvbScsIHBvcnQ6IDEwMzMzIH0sXG4gIHsgdHlwZTogJ3RjcCcsIGhvc3Q6ICdzZWVkMS5hcGhlbGlvbi1uZW8uY29tJywgcG9ydDogMTAzMzMgfSxcbiAgeyB0eXBlOiAndGNwJywgaG9zdDogJ3NlZWQyLmFwaGVsaW9uLW5lby5jb20nLCBwb3J0OiAxMDMzMyB9LFxuICB7IHR5cGU6ICd0Y3AnLCBob3N0OiAnc2VlZDMuYXBoZWxpb24tbmVvLmNvbScsIHBvcnQ6IDEwMzMzIH0sXG4gIHsgdHlwZTogJ3RjcCcsIGhvc3Q6ICdzZWVkNC5hcGhlbGlvbi1uZW8uY29tJywgcG9ydDogMTAzMzMgfSxcbl07XG5cbmNvbnN0IG1ha2VEZWZhdWx0Q29uZmlnID0gKGRhdGFQYXRoOiBzdHJpbmcpOiBOb2RlQ29uZmlnID0+ICh7XG4gIGxvZzoge1xuICAgIGxldmVsOiAnaW5mbycsXG4gICAgbWF4U2l6ZTogMTAgKiAxMDI0ICogMTAyNCxcbiAgICBtYXhGaWxlczogNSxcbiAgfSxcbiAgc2V0dGluZ3M6IHtcbiAgICB0ZXN0OiBmYWxzZSxcbiAgfSxcbiAgZW52aXJvbm1lbnQ6IHtcbiAgICBkYXRhUGF0aDogcGF0aC5yZXNvbHZlKGRhdGFQYXRoLCAnbm9kZScpLFxuICAgIHJwYzoge30sXG4gICAgbm9kZToge30sXG4gICAgbmV0d29yazoge30sXG4gIH0sXG4gIG9wdGlvbnM6IHtcbiAgICBub2RlOiB7XG4gICAgICBjb25zZW5zdXM6IHtcbiAgICAgICAgZW5hYmxlZDogZmFsc2UsXG4gICAgICAgIG9wdGlvbnM6IHsgcHJpdmF0ZUtleTogJ2RlZmF1bHQnLCBwcml2YXRlTmV0OiBmYWxzZSB9LFxuICAgICAgfSxcbiAgICAgIHJwY1VSTHM6IFsuLi5ERUZBVUxUX1JQQ19VUkxTXSxcbiAgICB9LFxuICAgIG5ldHdvcms6IHtcbiAgICAgIHNlZWRzOiBERUZBVUxUX1NFRURTLm1hcChjcmVhdGVFbmRwb2ludCksXG4gICAgfSxcbiAgICBycGM6IHtcbiAgICAgIHNlcnZlcjoge1xuICAgICAgICBrZWVwQWxpdmVUaW1lb3V0OiA2MDAwMCxcbiAgICAgIH0sXG4gICAgICBsaXZlSGVhbHRoQ2hlY2s6IHtcbiAgICAgICAgcnBjVVJMczogREVGQVVMVF9SUENfVVJMUyxcbiAgICAgICAgb2Zmc2V0OiAxLFxuICAgICAgICB0aW1lb3V0TVM6IDUwMDAsXG4gICAgICB9LFxuICAgICAgcmVhZHlIZWFsdGhDaGVjazoge1xuICAgICAgICBycGNVUkxzOiBERUZBVUxUX1JQQ19VUkxTLFxuICAgICAgICBvZmZzZXQ6IDEsXG4gICAgICAgIHRpbWVvdXRNUzogNTAwMCxcbiAgICAgIH0sXG4gICAgfSxcbiAgfSxcbn0pO1xuXG5leHBvcnQgY29uc3QgY3JlYXRlTm9kZUNvbmZpZyA9ICh7XG4gIGRhdGFQYXRoLFxuICBkZWZhdWx0Q29uZmlnID0gbWFrZURlZmF1bHRDb25maWcoZGF0YVBhdGgpLFxufToge1xuICByZWFkb25seSBkYXRhUGF0aDogc3RyaW5nO1xuICByZWFkb25seSBkZWZhdWx0Q29uZmlnPzogTm9kZUNvbmZpZztcbn0pOiBDb25maWc8Tm9kZUNvbmZpZz4gPT5cbiAgbmV3IENvbmZpZyh7XG4gICAgbmFtZTogJ25vZGUnLFxuICAgIGRlZmF1bHRDb25maWcsXG4gICAgc2NoZW1hOiB7XG4gICAgICB0eXBlOiAnb2JqZWN0JyxcbiAgICAgIHJlcXVpcmVkOiBbJ2xvZyddLFxuICAgICAgcHJvcGVydGllczoge1xuICAgICAgICBsb2c6IHtcbiAgICAgICAgICB0eXBlOiAnb2JqZWN0JyxcbiAgICAgICAgICByZXF1aXJlZDogWydsZXZlbCcsICdtYXhTaXplJywgJ21heEZpbGVzJ10sXG4gICAgICAgICAgcHJvcGVydGllczoge1xuICAgICAgICAgICAgbGV2ZWw6IHsgdHlwZTogJ3N0cmluZycgfSxcbiAgICAgICAgICAgIG1heFNpemU6IHsgdHlwZTogJ251bWJlcicgfSxcbiAgICAgICAgICAgIG1heEZpbGVzOiB7IHR5cGU6ICdudW1iZXInIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgICAgc2V0dGluZ3M6IHtcbiAgICAgICAgICB0eXBlOiAnb2JqZWN0JyxcbiAgICAgICAgICByZXF1aXJlZDogWyd0ZXN0J10sXG4gICAgICAgICAgcHJvcGVydGllczoge1xuICAgICAgICAgICAgdGVzdDogeyB0eXBlOiAnYm9vbGVhbicgfSxcbiAgICAgICAgICAgIHByaXZhdGVOZXQ6IHsgdHlwZTogJ2Jvb2xlYW4nIH0sXG4gICAgICAgICAgICBzZWNvbmRzUGVyQmxvY2s6IHsgdHlwZTogJ251bWJlcicgfSxcbiAgICAgICAgICAgIHN0YW5kYnlWYWxpZGF0b3JzOiB7IHR5cGU6ICdhcnJheScsIGl0ZW1zOiB7IHR5cGU6ICdzdHJpbmcnIH0gfSxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgICBlbnZpcm9ubWVudDoge1xuICAgICAgICAgIHR5cGU6ICdvYmplY3QnLFxuICAgICAgICAgIHJlcXVpcmVkOiBbJ2RhdGFQYXRoJywgJ3JwYycsICdub2RlJywgJ25ldHdvcmsnXSxcbiAgICAgICAgICBwcm9wZXJ0aWVzOiB7XG4gICAgICAgICAgICBkYXRhUGF0aDogeyB0eXBlOiAnc3RyaW5nJyB9LFxuICAgICAgICAgICAgcnBjOiB7XG4gICAgICAgICAgICAgIHR5cGU6ICdvYmplY3QnLFxuICAgICAgICAgICAgICByZXF1aXJlZDogW10sXG4gICAgICAgICAgICAgIHByb3BlcnRpZXM6IHtcbiAgICAgICAgICAgICAgICBodHRwOiB7XG4gICAgICAgICAgICAgICAgICB0eXBlOiAnb2JqZWN0JyxcbiAgICAgICAgICAgICAgICAgIHJlcXVpcmVkOiBbJ2hvc3QnLCAncG9ydCddLFxuICAgICAgICAgICAgICAgICAgcHJvcGVydGllczoge1xuICAgICAgICAgICAgICAgICAgICBob3N0OiB7IHR5cGU6ICdzdHJpbmcnIH0sXG4gICAgICAgICAgICAgICAgICAgIHBvcnQ6IHsgdHlwZTogJ251bWJlcicgfSxcbiAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgfSxcblxuICAgICAgICAgICAgICAgIGh0dHBzOiB7XG4gICAgICAgICAgICAgICAgICB0eXBlOiAnb2JqZWN0JyxcbiAgICAgICAgICAgICAgICAgIHJlcXVpcmVkOiBbJ2hvc3QnLCAncG9ydCcsICdrZXknLCAnY2VydCddLFxuICAgICAgICAgICAgICAgICAgcHJvcGVydGllczoge1xuICAgICAgICAgICAgICAgICAgICBob3N0OiB7IHR5cGU6ICdzdHJpbmcnIH0sXG4gICAgICAgICAgICAgICAgICAgIHBvcnQ6IHsgdHlwZTogJ251bWJlcicgfSxcbiAgICAgICAgICAgICAgICAgICAga2V5OiB7IHR5cGU6ICdzdHJpbmcnIH0sXG4gICAgICAgICAgICAgICAgICAgIGNlcnQ6IHsgdHlwZTogJ3N0cmluZycgfSxcbiAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBub2RlOiB7XG4gICAgICAgICAgICAgIHR5cGU6ICdvYmplY3QnLFxuICAgICAgICAgICAgICByZXF1aXJlZDogW10sXG4gICAgICAgICAgICAgIHByb3BlcnRpZXM6IHtcbiAgICAgICAgICAgICAgICBleHRlcm5hbFBvcnQ6IHsgdHlwZTogJ251bWJlcicgfSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBuZXR3b3JrOiB7XG4gICAgICAgICAgICAgIHR5cGU6ICdvYmplY3QnLFxuICAgICAgICAgICAgICByZXF1aXJlZDogW10sXG4gICAgICAgICAgICAgIHByb3BlcnRpZXM6IHtcbiAgICAgICAgICAgICAgICBsaXN0ZW5UQ1A6IHtcbiAgICAgICAgICAgICAgICAgIHR5cGU6ICdvYmplY3QnLFxuICAgICAgICAgICAgICAgICAgcmVxdWlyZWQ6IFsncG9ydCddLFxuICAgICAgICAgICAgICAgICAgcHJvcGVydGllczoge1xuICAgICAgICAgICAgICAgICAgICBob3N0OiB7IHR5cGU6ICdzdHJpbmcnIH0sXG4gICAgICAgICAgICAgICAgICAgIHBvcnQ6IHsgdHlwZTogJ251bWJlcicgfSxcbiAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgfSxcblxuICAgICAgICAgICAgICAgIGV4dGVybmFsRW5kcG9pbnRzOiB7XG4gICAgICAgICAgICAgICAgICB0eXBlOiAnYXJyYXknLFxuICAgICAgICAgICAgICAgICAgaXRlbXM6IHsgdHlwZTogJ3N0cmluZycgfSxcbiAgICAgICAgICAgICAgICB9LFxuXG4gICAgICAgICAgICAgICAgY29ubmVjdFBlZXJzRGVsYXlNUzogeyB0eXBlOiAnbnVtYmVyJyB9LFxuICAgICAgICAgICAgICAgIHNvY2tldFRpbWVvdXRNUzogeyB0eXBlOiAnbnVtYmVyJyB9LFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgICBvcHRpb25zOiB7XG4gICAgICAgICAgdHlwZTogJ29iamVjdCcsXG4gICAgICAgICAgcmVxdWlyZWQ6IFsnbm9kZScsICduZXR3b3JrJywgJ3JwYyddLFxuICAgICAgICAgIHByb3BlcnRpZXM6IHtcbiAgICAgICAgICAgIG5vZGU6IHtcbiAgICAgICAgICAgICAgdHlwZTogJ29iamVjdCcsXG4gICAgICAgICAgICAgIHJlcXVpcmVkOiBbJ2NvbnNlbnN1cycsICdycGNVUkxzJ10sXG4gICAgICAgICAgICAgIHByb3BlcnRpZXM6IHtcbiAgICAgICAgICAgICAgICBjb25zZW5zdXM6IHtcbiAgICAgICAgICAgICAgICAgIHR5cGU6ICdvYmplY3QnLFxuICAgICAgICAgICAgICAgICAgcmVxdWlyZWQ6IFsnZW5hYmxlZCcsICdvcHRpb25zJ10sXG4gICAgICAgICAgICAgICAgICBwcm9wZXJ0aWVzOiB7XG4gICAgICAgICAgICAgICAgICAgIGVuYWJsZWQ6IHsgdHlwZTogJ2Jvb2xlYW4nIH0sXG4gICAgICAgICAgICAgICAgICAgIG9wdGlvbnM6IHtcbiAgICAgICAgICAgICAgICAgICAgICB0eXBlOiAnb2JqZWN0JyxcbiAgICAgICAgICAgICAgICAgICAgICByZXF1aXJlZDogWydwcml2YXRlS2V5JywgJ3ByaXZhdGVOZXQnXSxcbiAgICAgICAgICAgICAgICAgICAgICBwcm9wZXJ0aWVzOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBwcml2YXRlS2V5OiB7IHR5cGU6ICdzdHJpbmcnIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICBwcml2YXRlTmV0OiB7IHR5cGU6ICdib29sZWFuJyB9LFxuICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgcnBjVVJMczogeyB0eXBlOiAnYXJyYXknLCBpdGVtczogeyB0eXBlOiAnc3RyaW5nJyB9IH0sXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgbmV0d29yazoge1xuICAgICAgICAgICAgICB0eXBlOiAnb2JqZWN0JyxcbiAgICAgICAgICAgICAgcmVxdWlyZWQ6IFsnc2VlZHMnXSxcbiAgICAgICAgICAgICAgcHJvcGVydGllczoge1xuICAgICAgICAgICAgICAgIHNlZWRzOiB7IHR5cGU6ICdhcnJheScsIGl0ZW1zOiB7IHR5cGU6ICdzdHJpbmcnIH0gfSxcbiAgICAgICAgICAgICAgICBtYXhDb25uZWN0ZWRQZWVyczogeyB0eXBlOiAnbnVtYmVyJyB9LFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHJwYzoge1xuICAgICAgICAgICAgICB0eXBlOiAnb2JqZWN0JyxcbiAgICAgICAgICAgICAgcmVxdWlyZWQ6IFsnc2VydmVyJywgJ2xpdmVIZWFsdGhDaGVjaycsICdyZWFkeUhlYWx0aENoZWNrJ10sXG4gICAgICAgICAgICAgIHByb3BlcnRpZXM6IHtcbiAgICAgICAgICAgICAgICBzZXJ2ZXI6IHtcbiAgICAgICAgICAgICAgICAgIHR5cGU6ICdvYmplY3QnLFxuICAgICAgICAgICAgICAgICAgcmVxdWlyZWQ6IFsna2VlcEFsaXZlVGltZW91dCddLFxuICAgICAgICAgICAgICAgICAgcHJvcGVydGllczoge1xuICAgICAgICAgICAgICAgICAgICBrZWVwQWxpdmVUaW1lb3V0OiB7IHR5cGU6ICdudW1iZXInIH0sXG4gICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgbGl2ZUhlYWx0aENoZWNrOiB7XG4gICAgICAgICAgICAgICAgICB0eXBlOiAnb2JqZWN0JyxcbiAgICAgICAgICAgICAgICAgIHJlcXVpcmVkOiBbJ3JwY1VSTHMnLCAnb2Zmc2V0JywgJ3RpbWVvdXRNUyddLFxuICAgICAgICAgICAgICAgICAgcHJvcGVydGllczoge1xuICAgICAgICAgICAgICAgICAgICBycGNVUkxzOiB7IHR5cGU6ICdhcnJheScsIGl0ZW1zOiB7IHR5cGU6ICdzdHJpbmcnIH0gfSxcbiAgICAgICAgICAgICAgICAgICAgb2Zmc2V0OiB7IHR5cGU6ICdudW1iZXInIH0sXG4gICAgICAgICAgICAgICAgICAgIHRpbWVvdXRNUzogeyB0eXBlOiAnbnVtYmVyJyB9LFxuICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHJlYWR5SGVhbHRoQ2hlY2s6IHtcbiAgICAgICAgICAgICAgICAgIHR5cGU6ICdvYmplY3QnLFxuICAgICAgICAgICAgICAgICAgcmVxdWlyZWQ6IFsncnBjVVJMcycsICdvZmZzZXQnLCAndGltZW91dE1TJ10sXG4gICAgICAgICAgICAgICAgICBwcm9wZXJ0aWVzOiB7XG4gICAgICAgICAgICAgICAgICAgIHJwY1VSTHM6IHsgdHlwZTogJ2FycmF5JywgaXRlbXM6IHsgdHlwZTogJ3N0cmluZycgfSB9LFxuICAgICAgICAgICAgICAgICAgICBvZmZzZXQ6IHsgdHlwZTogJ251bWJlcicgfSxcbiAgICAgICAgICAgICAgICAgICAgdGltZW91dE1TOiB7IHR5cGU6ICdudW1iZXInIH0sXG4gICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIH0sXG4gICAgY29uZmlnUGF0aDogZGF0YVBhdGgsXG4gIH0pO1xuXG5leHBvcnQgY2xhc3MgTkVPT05FTm9kZUFkYXB0ZXIgZXh0ZW5kcyBOb2RlQWRhcHRlciB7XG4gIHByaXZhdGUgbXV0YWJsZUNvbmZpZzogQ29uZmlnPE5vZGVDb25maWc+IHwgdW5kZWZpbmVkO1xuICBwcml2YXRlIG11dGFibGVQcm9jZXNzOiBleGVjYS5FeGVjYUNoaWxkUHJvY2VzcyB8IHVuZGVmaW5lZDtcblxuICBwdWJsaWMgY29uc3RydWN0b3Ioe1xuICAgIG1vbml0b3IsXG4gICAgbmFtZSxcbiAgICBiaW5hcnksXG4gICAgZGF0YVBhdGgsXG4gICAgc2V0dGluZ3MsXG4gIH06IHtcbiAgICByZWFkb25seSBtb25pdG9yOiBNb25pdG9yO1xuICAgIHJlYWRvbmx5IG5hbWU6IHN0cmluZztcbiAgICByZWFkb25seSBiaW5hcnk6IEJpbmFyeTtcbiAgICByZWFkb25seSBkYXRhUGF0aDogc3RyaW5nO1xuICAgIHJlYWRvbmx5IHNldHRpbmdzOiBOb2RlU2V0dGluZ3M7XG4gIH0pIHtcbiAgICBzdXBlcih7XG4gICAgICBtb25pdG9yOiBtb25pdG9yLmF0KCduZW9fb25lX25vZGVfYWRhcHRlcicpLFxuICAgICAgbmFtZSxcbiAgICAgIGJpbmFyeSxcbiAgICAgIGRhdGFQYXRoLFxuICAgICAgc2V0dGluZ3MsXG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgZ2V0RGVidWcoKTogRGVzY3JpYmVUYWJsZSB7XG4gICAgcmV0dXJuIHN1cGVyXG4gICAgICAuZ2V0RGVidWcoKVxuICAgICAgLmNvbmNhdChbXG4gICAgICAgIFsnUHJvY2VzcyBJRCcsIHRoaXMubXV0YWJsZVByb2Nlc3MgPT09IHVuZGVmaW5lZCA/ICdudWxsJyA6IGAke3RoaXMubXV0YWJsZVByb2Nlc3MucGlkfWBdLFxuICAgICAgICBbJ0NvbmZpZyBQYXRoJywgdGhpcy5tdXRhYmxlQ29uZmlnID09PSB1bmRlZmluZWQgPyAnbnVsbCcgOiB0aGlzLm11dGFibGVDb25maWcuY29uZmlnUGF0aF0sXG4gICAgICBdKTtcbiAgfVxuXG4gIHB1YmxpYyBnZXROb2RlU3RhdHVzKCk6IE5vZGVTdGF0dXMge1xuICAgIHJldHVybiB7XG4gICAgICBycGNBZGRyZXNzOiB0aGlzLmdldEFkZHJlc3MoJy9ycGMnKSxcbiAgICAgIHRjcEFkZHJlc3M6IGBsb2NhbGhvc3Q6JHt0aGlzLm11dGFibGVTZXR0aW5ncy5saXN0ZW5UQ1BQb3J0fWAsXG4gICAgICB0ZWxlbWV0cnlBZGRyZXNzOiBgaHR0cDovL2xvY2FsaG9zdDoke3RoaXMubXV0YWJsZVNldHRpbmdzLnRlbGVtZXRyeVBvcnR9L21ldHJpY3NgLFxuICAgIH07XG4gIH1cblxuICBwcm90ZWN0ZWQgYXN5bmMgaXNMaXZlKCk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIHJldHVybiB0aGlzLmNoZWNrUlBDKCcvbGl2ZV9oZWFsdGhfY2hlY2snKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBhc3luYyBpc1JlYWR5KCk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIHJldHVybiB0aGlzLmNoZWNrUlBDKCcvcmVhZHlfaGVhbHRoX2NoZWNrJyk7XG4gIH1cblxuICBwcm90ZWN0ZWQgYXN5bmMgY3JlYXRlSW50ZXJuYWwoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgYXdhaXQgdGhpcy53cml0ZVNldHRpbmdzKHRoaXMubXV0YWJsZVNldHRpbmdzKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBhc3luYyB1cGRhdGVJbnRlcm5hbChzZXR0aW5nczogTm9kZVNldHRpbmdzKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgcmVzdGFydCA9IGF3YWl0IHRoaXMud3JpdGVTZXR0aW5ncyhzZXR0aW5ncyk7XG4gICAgaWYgKHJlc3RhcnQgJiYgdGhpcy5tdXRhYmxlUHJvY2VzcyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBhd2FpdCB0aGlzLnN0b3AoKTtcbiAgICAgIGF3YWl0IHRoaXMuc3RhcnQoKTtcbiAgICB9XG4gIH1cblxuICBwcm90ZWN0ZWQgYXN5bmMgc3RhcnRJbnRlcm5hbCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAodGhpcy5tdXRhYmxlUHJvY2VzcyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBjb25zdCBjaGlsZCA9IGV4ZWNhKHRoaXMuYmluYXJ5LmNtZCwgdGhpcy5iaW5hcnkuZmlyc3RBcmdzLmNvbmNhdChbJ3N0YXJ0JywgJ25vZGUnLCB0aGlzLmRhdGFQYXRoXSksIHtcbiAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICB3aW5kb3dzSGlkZTogdHJ1ZSxcbiAgICAgICAgc3RkaW86ICdpZ25vcmUnLFxuICAgICAgfSk7XG5cbiAgICAgIHRoaXMubXV0YWJsZVByb2Nlc3MgPSBjaGlsZDtcbiAgICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZSBuby1mbG9hdGluZy1wcm9taXNlc1xuICAgICAgY2hpbGRcbiAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgIHRoaXMubW9uaXRvci5sb2coe1xuICAgICAgICAgICAgbmFtZTogJ25lb19ub2RlX2FkYXB0ZXJfbm9kZV9leGl0JyxcbiAgICAgICAgICAgIG1lc3NhZ2U6ICdDaGlsZCBwcm9jZXNzIGV4aXRlZCcsXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICB0aGlzLm11dGFibGVQcm9jZXNzID0gdW5kZWZpbmVkO1xuICAgICAgICB9KVxuICAgICAgICAuY2F0Y2goKGVycm9yOiBFcnJvcikgPT4ge1xuICAgICAgICAgIHRoaXMubW9uaXRvci5sb2dFcnJvcih7XG4gICAgICAgICAgICBuYW1lOiAnbmVvX25vZGVfYWRhcHRlcl9ub2RlX2Vycm9yJyxcbiAgICAgICAgICAgIG1lc3NhZ2U6ICdDaGlsZCBwcm9jZXNzIGV4aXRlZCB3aXRoIGFuIGVycm9yLicsXG4gICAgICAgICAgICBlcnJvcixcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIHRoaXMubXV0YWJsZVByb2Nlc3MgPSB1bmRlZmluZWQ7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIHByb3RlY3RlZCBhc3luYyBzdG9wSW50ZXJuYWwoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgY2hpbGQgPSB0aGlzLm11dGFibGVQcm9jZXNzO1xuICAgIHRoaXMubXV0YWJsZVByb2Nlc3MgPSB1bmRlZmluZWQ7XG4gICAgaWYgKGNoaWxkICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGF3YWl0IGtpbGxQcm9jZXNzKGNoaWxkLnBpZCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBjaGVja1JQQyhycGNQYXRoOiBzdHJpbmcpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaCh0aGlzLmdldEFkZHJlc3MocnBjUGF0aCkpO1xuXG4gICAgICByZXR1cm4gcmVzcG9uc2Uub2s7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGlmIChlcnJvci5jb2RlICE9PSAnRUNPTk5SRUZVU0VEJykge1xuICAgICAgICB0aGlzLm1vbml0b3Iud2l0aERhdGEoeyBbdGhpcy5tb25pdG9yLmxhYmVscy5IVFRQX1BBVEhdOiBycGNQYXRoIH0pLmxvZ0Vycm9yKHtcbiAgICAgICAgICBuYW1lOiAnaHR0cF9jbGllbnRfcmVxdWVzdCcsXG4gICAgICAgICAgbWVzc2FnZTogJ0ZhaWxlZCB0byBjaGVjayBSUEMuJyxcbiAgICAgICAgICBlcnJvcixcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGdldEFkZHJlc3MocnBjUGF0aDogc3RyaW5nKTogc3RyaW5nIHtcbiAgICByZXR1cm4gYGh0dHA6Ly9sb2NhbGhvc3Q6JHt0aGlzLm11dGFibGVTZXR0aW5ncy5ycGNQb3J0fSR7cnBjUGF0aH1gO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyB3cml0ZVNldHRpbmdzKHNldHRpbmdzOiBOb2RlU2V0dGluZ3MpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICBsZXQgY29uZmlnID0gdGhpcy5tdXRhYmxlQ29uZmlnO1xuICAgIGlmIChjb25maWcgPT09IHVuZGVmaW5lZCkge1xuICAgICAgY29uZmlnID0gY3JlYXRlTm9kZUNvbmZpZyh7XG4gICAgICAgIGRhdGFQYXRoOiB0aGlzLmRhdGFQYXRoLFxuICAgICAgICBkZWZhdWx0Q29uZmlnOiB0aGlzLmNyZWF0ZUNvbmZpZyhzZXR0aW5ncyksXG4gICAgICB9KTtcblxuICAgICAgdGhpcy5tdXRhYmxlQ29uZmlnID0gY29uZmlnO1xuICAgIH1cblxuICAgIGNvbnN0IG5vZGVDb25maWcgPSBhd2FpdCBjb25maWcuY29uZmlnJC5waXBlKHRha2UoMSkpLnRvUHJvbWlzZSgpO1xuICAgIGNvbnN0IG5ld05vZGVDb25maWcgPSB0aGlzLmNyZWF0ZUNvbmZpZyhzZXR0aW5ncyk7XG4gICAgYXdhaXQgZnMuZW5zdXJlRGlyKG5ld05vZGVDb25maWcuZW52aXJvbm1lbnQuZGF0YVBhdGgpO1xuICAgIGF3YWl0IGNvbmZpZy51cGRhdGUoeyBjb25maWc6IG5ld05vZGVDb25maWcgfSk7XG5cbiAgICByZXR1cm4gIShcbiAgICAgIF8uaXNFcXVhbChub2RlQ29uZmlnLnNldHRpbmdzLCBuZXdOb2RlQ29uZmlnLnNldHRpbmdzKSAmJlxuICAgICAgXy5pc0VxdWFsKG5vZGVDb25maWcuZW52aXJvbm1lbnQsIG5ld05vZGVDb25maWcuZW52aXJvbm1lbnQpXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlQ29uZmlnKHNldHRpbmdzOiBOb2RlU2V0dGluZ3MpOiBOb2RlQ29uZmlnIHtcbiAgICByZXR1cm4ge1xuICAgICAgbG9nOiB7XG4gICAgICAgIGxldmVsOiAnaW5mbycsXG4gICAgICAgIG1heFNpemU6IDEwICogMTAyNCAqIDEwMjQsXG4gICAgICAgIG1heEZpbGVzOiA1LFxuICAgICAgfSxcbiAgICAgIHNldHRpbmdzOiB7XG4gICAgICAgIHRlc3Q6IHNldHRpbmdzLmlzVGVzdE5ldCxcbiAgICAgICAgcHJpdmF0ZU5ldDogc2V0dGluZ3MucHJpdmF0ZU5ldCxcbiAgICAgICAgc2Vjb25kc1BlckJsb2NrOiBzZXR0aW5ncy5zZWNvbmRzUGVyQmxvY2ssXG4gICAgICAgIHN0YW5kYnlWYWxpZGF0b3JzOiBzZXR0aW5ncy5zdGFuZGJ5VmFsaWRhdG9ycyxcbiAgICAgICAgYWRkcmVzczogc2V0dGluZ3MuYWRkcmVzcyxcbiAgICAgIH0sXG4gICAgICBlbnZpcm9ubWVudDoge1xuICAgICAgICBkYXRhUGF0aDogcGF0aC5yZXNvbHZlKHRoaXMuZGF0YVBhdGgsICdjaGFpbicpLFxuICAgICAgICBycGM6IHtcbiAgICAgICAgICBodHRwOiB7XG4gICAgICAgICAgICBwb3J0OiBzZXR0aW5ncy5ycGNQb3J0LFxuICAgICAgICAgICAgaG9zdDogJzAuMC4wLjAnLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICAgIG5vZGU6IHtcbiAgICAgICAgICBleHRlcm5hbFBvcnQ6IHNldHRpbmdzLmxpc3RlblRDUFBvcnQsXG4gICAgICAgIH0sXG4gICAgICAgIG5ldHdvcms6IHtcbiAgICAgICAgICBsaXN0ZW5UQ1A6IHtcbiAgICAgICAgICAgIHBvcnQ6IHNldHRpbmdzLmxpc3RlblRDUFBvcnQsXG4gICAgICAgICAgICBob3N0OiAnMC4wLjAuMCcsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgICAgdGVsZW1ldHJ5OiB7XG4gICAgICAgICAgcG9ydDogc2V0dGluZ3MudGVsZW1ldHJ5UG9ydCxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgICBvcHRpb25zOiB7XG4gICAgICAgIG5vZGU6IHtcbiAgICAgICAgICBjb25zZW5zdXM6IHNldHRpbmdzLmNvbnNlbnN1cyxcbiAgICAgICAgICBycGNVUkxzOiBzZXR0aW5ncy5ycGNFbmRwb2ludHMsXG4gICAgICAgIH0sXG4gICAgICAgIG5ldHdvcms6IHtcbiAgICAgICAgICBzZWVkczogc2V0dGluZ3Muc2VlZHMsXG4gICAgICAgIH0sXG4gICAgICAgIHJwYzoge1xuICAgICAgICAgIHNlcnZlcjoge1xuICAgICAgICAgICAga2VlcEFsaXZlVGltZW91dDogNjAwMDAsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBsaXZlSGVhbHRoQ2hlY2s6IHtcbiAgICAgICAgICAgIHJwY1VSTHM6IHNldHRpbmdzLnJwY0VuZHBvaW50cyxcbiAgICAgICAgICAgIG9mZnNldDogMSxcbiAgICAgICAgICAgIHRpbWVvdXRNUzogNTAwMCxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHJlYWR5SGVhbHRoQ2hlY2s6IHtcbiAgICAgICAgICAgIHJwY1VSTHM6IHNldHRpbmdzLnJwY0VuZHBvaW50cyxcbiAgICAgICAgICAgIG9mZnNldDogMSxcbiAgICAgICAgICAgIHRpbWVvdXRNUzogNTAwMCxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9O1xuICB9XG59XG4iXX0=
|