@ksangkuk10/wallet-controller 1.7.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (124) hide show
  1. package/README.md +7 -0
  2. package/_commonjs/controller.js +704 -0
  3. package/_commonjs/env.js +9 -0
  4. package/_commonjs/exception/isError.js +15 -0
  5. package/_commonjs/exception/mapExtensionTxError.js +46 -0
  6. package/_commonjs/exception/mapWalletConnectError.js +69 -0
  7. package/_commonjs/getChainOptions.js +57 -0
  8. package/_commonjs/index.js +22 -0
  9. package/_commonjs/modules/connect-modal/index.js +80 -0
  10. package/_commonjs/modules/connect-modal/style.js +161 -0
  11. package/_commonjs/modules/extension-router/ExtensionRouter.js +241 -0
  12. package/_commonjs/modules/extension-router/index.js +19 -0
  13. package/_commonjs/modules/extension-router/modal.js +80 -0
  14. package/_commonjs/modules/extension-router/modal.style.js +161 -0
  15. package/_commonjs/modules/extension-router/multiChannel.js +18 -0
  16. package/_commonjs/modules/extension-router/session.js +37 -0
  17. package/_commonjs/modules/extension-router/types.js +16 -0
  18. package/_commonjs/modules/legacy-extension/LegacyExtensionConnector.js +143 -0
  19. package/_commonjs/modules/legacy-extension/createFixedExtension.js +236 -0
  20. package/_commonjs/modules/legacy-extension/index.js +19 -0
  21. package/_commonjs/modules/readonly-wallet/connect.js +24 -0
  22. package/_commonjs/modules/readonly-wallet/index.js +20 -0
  23. package/_commonjs/modules/readonly-wallet/modal.js +123 -0
  24. package/_commonjs/modules/readonly-wallet/modal.style.js +204 -0
  25. package/_commonjs/modules/readonly-wallet/storage.js +40 -0
  26. package/_commonjs/modules/readonly-wallet/types.js +3 -0
  27. package/_commonjs/modules/walletconnect/connect.js +421 -0
  28. package/_commonjs/modules/walletconnect/errors.js +51 -0
  29. package/_commonjs/modules/walletconnect/impl/socket-transport/index.js +204 -0
  30. package/_commonjs/modules/walletconnect/impl/socket-transport/network.js +30 -0
  31. package/_commonjs/modules/walletconnect/index.js +22 -0
  32. package/_commonjs/modules/walletconnect/modal.js +147 -0
  33. package/_commonjs/modules/walletconnect/modal.style.js +138 -0
  34. package/_commonjs/modules/walletconnect/types.js +13 -0
  35. package/_commonjs/operators/getExtensions.js +55 -0
  36. package/_commonjs/operators/toConnectedWallet.js +24 -0
  37. package/_commonjs/operators/toLcdClient.js +15 -0
  38. package/_commonjs/utils/browser-check.js +47 -0
  39. package/_commonjs/utils/checkExtensionReady.js +28 -0
  40. package/_commonjs/utils/sortConnections.js +13 -0
  41. package/_commonjs/verifyBytes.js +19 -0
  42. package/controller.d.ts +220 -0
  43. package/controller.js +697 -0
  44. package/env.d.ts +2 -0
  45. package/env.js +5 -0
  46. package/exception/isError.d.ts +3 -0
  47. package/exception/isError.js +11 -0
  48. package/exception/mapExtensionTxError.d.ts +5 -0
  49. package/exception/mapExtensionTxError.js +41 -0
  50. package/exception/mapWalletConnectError.d.ts +6 -0
  51. package/exception/mapWalletConnectError.js +63 -0
  52. package/getChainOptions.d.ts +3 -0
  53. package/getChainOptions.js +53 -0
  54. package/index.d.ts +6 -0
  55. package/index.js +6 -0
  56. package/modules/connect-modal/index.d.ts +2 -0
  57. package/modules/connect-modal/index.js +76 -0
  58. package/modules/connect-modal/style.d.ts +1 -0
  59. package/modules/connect-modal/style.js +158 -0
  60. package/modules/extension-router/ExtensionRouter.d.ts +43 -0
  61. package/modules/extension-router/ExtensionRouter.js +237 -0
  62. package/modules/extension-router/index.d.ts +2 -0
  63. package/modules/extension-router/index.js +3 -0
  64. package/modules/extension-router/modal.d.ts +2 -0
  65. package/modules/extension-router/modal.js +76 -0
  66. package/modules/extension-router/modal.style.d.ts +1 -0
  67. package/modules/extension-router/modal.style.js +158 -0
  68. package/modules/extension-router/multiChannel.d.ts +13 -0
  69. package/modules/extension-router/multiChannel.js +14 -0
  70. package/modules/extension-router/session.d.ts +8 -0
  71. package/modules/extension-router/session.js +31 -0
  72. package/modules/extension-router/types.d.ts +35 -0
  73. package/modules/extension-router/types.js +13 -0
  74. package/modules/legacy-extension/LegacyExtensionConnector.d.ts +30 -0
  75. package/modules/legacy-extension/LegacyExtensionConnector.js +139 -0
  76. package/modules/legacy-extension/createFixedExtension.d.ts +46 -0
  77. package/modules/legacy-extension/createFixedExtension.js +232 -0
  78. package/modules/legacy-extension/index.d.ts +2 -0
  79. package/modules/legacy-extension/index.js +3 -0
  80. package/modules/readonly-wallet/connect.d.ts +8 -0
  81. package/modules/readonly-wallet/connect.js +19 -0
  82. package/modules/readonly-wallet/index.d.ts +3 -0
  83. package/modules/readonly-wallet/index.js +4 -0
  84. package/modules/readonly-wallet/modal.d.ts +7 -0
  85. package/modules/readonly-wallet/modal.js +119 -0
  86. package/modules/readonly-wallet/modal.style.d.ts +1 -0
  87. package/modules/readonly-wallet/modal.style.js +201 -0
  88. package/modules/readonly-wallet/storage.d.ts +4 -0
  89. package/modules/readonly-wallet/storage.js +34 -0
  90. package/modules/readonly-wallet/types.d.ts +5 -0
  91. package/modules/readonly-wallet/types.js +2 -0
  92. package/modules/walletconnect/connect.d.ts +42 -0
  93. package/modules/walletconnect/connect.js +390 -0
  94. package/modules/walletconnect/errors.d.ts +22 -0
  95. package/modules/walletconnect/errors.js +41 -0
  96. package/modules/walletconnect/impl/socket-transport/index.d.ts +39 -0
  97. package/modules/walletconnect/impl/socket-transport/index.js +199 -0
  98. package/modules/walletconnect/impl/socket-transport/network.d.ts +8 -0
  99. package/modules/walletconnect/impl/socket-transport/network.js +28 -0
  100. package/modules/walletconnect/index.d.ts +5 -0
  101. package/modules/walletconnect/index.js +6 -0
  102. package/modules/walletconnect/modal.d.ts +12 -0
  103. package/modules/walletconnect/modal.js +143 -0
  104. package/modules/walletconnect/modal.style.d.ts +1 -0
  105. package/modules/walletconnect/modal.style.js +135 -0
  106. package/modules/walletconnect/types.d.ts +24 -0
  107. package/modules/walletconnect/types.js +10 -0
  108. package/operators/getExtensions.d.ts +9 -0
  109. package/operators/getExtensions.js +51 -0
  110. package/operators/toConnectedWallet.d.ts +4 -0
  111. package/operators/toConnectedWallet.js +20 -0
  112. package/operators/toLcdClient.d.ts +4 -0
  113. package/operators/toLcdClient.js +11 -0
  114. package/package.json +550 -0
  115. package/utils/browser-check.d.ts +3 -0
  116. package/utils/browser-check.js +38 -0
  117. package/utils/checkExtensionReady.d.ts +6 -0
  118. package/utils/checkExtensionReady.js +24 -0
  119. package/utils/sortConnections.d.ts +2 -0
  120. package/utils/sortConnections.js +9 -0
  121. package/verifyBytes.d.ts +4 -0
  122. package/verifyBytes.js +15 -0
  123. package/~/.npm/_cacache/content-v2/sha512/ad/b5/8c87dfae7c208906a88f1997b323933e7efb4e481bcfdc559cb13199d077e1b40abcb161561a293ca59cd98aae224cd0877555e6e7a2e11021bc55ebedf4 +0 -0
  124. package/~/.npm/_cacache/index-v5/6a/39/c03f62d7353a7cc1411e180ec37c393f9fedcfd081fa567f67bf32e6fb68 +2 -0
@@ -0,0 +1,704 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.WalletController = void 0;
7
+ const xpla_js_1 = require("@xpla/xpla.js");
8
+ const wallet_types_1 = require("@ksangkuk10/wallet-types");
9
+ const web_extension_interface_1 = require("@ksangkuk10/web-extension-interface");
10
+ const fast_deep_equal_1 = __importDefault(require("fast-deep-equal"));
11
+ const rxjs_1 = require("rxjs");
12
+ const operators_1 = require("rxjs/operators");
13
+ const env_1 = require("./env");
14
+ const mapExtensionTxError_1 = require("./exception/mapExtensionTxError");
15
+ const mapWalletConnectError_1 = require("./exception/mapWalletConnectError");
16
+ const connect_modal_1 = require("./modules/connect-modal");
17
+ const extension_router_1 = require("./modules/extension-router");
18
+ const multiChannel_1 = require("./modules/extension-router/multiChannel");
19
+ const readonly_wallet_1 = require("./modules/readonly-wallet");
20
+ const walletconnect_1 = require("./modules/walletconnect");
21
+ const getExtensions_1 = require("./operators/getExtensions");
22
+ const toConnectedWallet_1 = require("./operators/toConnectedWallet");
23
+ const toLcdClient_1 = require("./operators/toLcdClient");
24
+ const browser_check_1 = require("./utils/browser-check");
25
+ const checkExtensionReady_1 = require("./utils/checkExtensionReady");
26
+ const sortConnections_1 = require("./utils/sortConnections");
27
+ const CONNECTIONS = {
28
+ [wallet_types_1.ConnectType.READONLY]: {
29
+ type: wallet_types_1.ConnectType.READONLY,
30
+ name: 'View an address',
31
+ icon: 'https://assets.xpla.io/icon/wallet-provider/readonly.svg',
32
+ },
33
+ [wallet_types_1.ConnectType.WALLETCONNECT]: {
34
+ type: wallet_types_1.ConnectType.WALLETCONNECT,
35
+ name: 'Wallet Connect',
36
+ icon: 'https://assets.xpla.io/icon/wallet-provider/walletconnect.svg',
37
+ },
38
+ };
39
+ const DEFAULT_WAITING_CHROME_EXTENSION_INSTALL_CHECK = 1000 * 3;
40
+ const WALLETCONNECT_SUPPORT_FEATURES = new Set([
41
+ 'post', 'sign', 'sign-bytes'
42
+ ]);
43
+ const EMPTY_SUPPORT_FEATURES = new Set();
44
+ //noinspection ES6MissingAwait
45
+ class WalletController {
46
+ constructor(options) {
47
+ var _a;
48
+ this.options = options;
49
+ this.extension = null;
50
+ this.walletConnect = null;
51
+ this.readonlyWallet = null;
52
+ this.disableReadonlyWallet = null;
53
+ this.disableExtension = null;
54
+ this.disableWalletConnect = null;
55
+ /**
56
+ * Some mobile wallet emulates the behavior of chrome extension.
57
+ * It confirms that the current connection environment is such a wallet.
58
+ * (If you are running connect() by checking availableConnectType, you do not need to use this API.)
59
+ *
60
+ * @see Wallet#isChromeExtensionCompatibleBrowser
61
+ */
62
+ this.isChromeExtensionCompatibleBrowser = () => {
63
+ var _a;
64
+ return ((_a = this.options.dangerously__chromeExtensionCompatibleBrowserCheck) !== null && _a !== void 0 ? _a : env_1.DEFAULT_CHROME_EXTENSION_COMPATIBLE_BROWSER_CHECK)(navigator.userAgent);
65
+ };
66
+ /**
67
+ * available connect types on the browser
68
+ *
69
+ * @see Wallet#availableConnectTypes
70
+ */
71
+ this.availableConnectTypes = () => {
72
+ return this._availableConnectTypes.asObservable();
73
+ };
74
+ /**
75
+ * available connections includes identifier, name, icon
76
+ *
77
+ * @see Wallet#availableConnections
78
+ */
79
+ this.availableConnections = () => {
80
+ return this._availableConnectTypes.pipe((0, operators_1.map)((connectTypes) => {
81
+ const connections = [];
82
+ for (const connectType of connectTypes) {
83
+ if (connectType === wallet_types_1.ConnectType.EXTENSION) {
84
+ const xplaExtensions = (0, multiChannel_1.getXplaExtensions)();
85
+ for (const xplaExtension of xplaExtensions) {
86
+ connections.push(memoConnection(wallet_types_1.ConnectType.EXTENSION, xplaExtension.name, xplaExtension.icon, xplaExtension.identifier));
87
+ }
88
+ }
89
+ else {
90
+ connections.push(CONNECTIONS[connectType]);
91
+ }
92
+ }
93
+ return (0, sortConnections_1.sortConnections)(connections);
94
+ }));
95
+ };
96
+ /**
97
+ * available install types on the browser
98
+ *
99
+ * in this time, this only contains [ConnectType.EXTENSION]
100
+ *
101
+ * @see Wallet#availableInstallTypes
102
+ */
103
+ this.availableInstallTypes = () => {
104
+ return this._availableInstallTypes.asObservable();
105
+ };
106
+ /**
107
+ * available installations includes identifier, name, icon, url
108
+ *
109
+ * @see Wallet#availableInstallations
110
+ */
111
+ this.availableInstallations = () => {
112
+ return (0, rxjs_1.combineLatest)([this.availableConnections(), (0, getExtensions_1.getExtensions)()]).pipe((0, operators_1.map)(([connections, extensions]) => {
113
+ const installedIdentifiers = new Set(connections
114
+ .filter(({ type, identifier }) => {
115
+ return type === wallet_types_1.ConnectType.EXTENSION && !!identifier;
116
+ })
117
+ .map(({ identifier }) => {
118
+ return identifier;
119
+ }));
120
+ return extensions
121
+ .filter(({ identifier }) => {
122
+ return !installedIdentifiers.has(identifier);
123
+ })
124
+ .map(({ name, identifier, icon, url }) => {
125
+ return {
126
+ type: wallet_types_1.ConnectType.EXTENSION,
127
+ identifier,
128
+ name,
129
+ icon,
130
+ url,
131
+ };
132
+ });
133
+ }));
134
+ };
135
+ /**
136
+ * @see Wallet#status
137
+ * @see Wallet#network
138
+ * @see Wallet#wallets
139
+ */
140
+ this.states = () => {
141
+ return this._states.asObservable();
142
+ };
143
+ /** get connectedWallet */
144
+ this.connectedWallet = () => {
145
+ return this._states.pipe((0, toConnectedWallet_1.toConnectedWallet)(this));
146
+ };
147
+ /** get lcdClient */
148
+ this.lcdClient = (lcdClientConfig) => {
149
+ return this._states.pipe((0, toLcdClient_1.toLcdClient)(lcdClientConfig));
150
+ };
151
+ /**
152
+ * reload the connected wallet states
153
+ *
154
+ * in this time, this only work on the ConnectType.EXTENSION
155
+ *
156
+ * @see Wallet#recheckStatus
157
+ */
158
+ this.refetchStates = () => {
159
+ var _a;
160
+ if (this.disableExtension) {
161
+ (_a = this.extension) === null || _a === void 0 ? void 0 : _a.refetchStates();
162
+ }
163
+ };
164
+ /**
165
+ * @deprecated Please use availableInstallations
166
+ *
167
+ * install for the connect type
168
+ *
169
+ * @see Wallet#install
170
+ */
171
+ this.install = (type) => {
172
+ if (type === wallet_types_1.ConnectType.EXTENSION) {
173
+ // TODO separate install links by browser types
174
+ window.open(env_1.CHROME_EXTENSION_INSTALL_URL, '_blank');
175
+ }
176
+ else {
177
+ console.warn(`[WalletController] ConnectType "${type}" does not support install() function`);
178
+ }
179
+ };
180
+ /**
181
+ * connect to wallet
182
+ *
183
+ * @see Wallet#connect
184
+ */
185
+ this.connect = async (_type, _identifier, _walletApp) => {
186
+ var _a, _b, _c, _d;
187
+ let type;
188
+ let identifier;
189
+ if (!!_type) {
190
+ type = _type;
191
+ identifier = _identifier;
192
+ }
193
+ else {
194
+ const connections = await (0, rxjs_1.firstValueFrom)(this.availableConnections());
195
+ const selector = (_a = this.options.selectConnection) !== null && _a !== void 0 ? _a : connect_modal_1.selectConnection;
196
+ const selected = await selector(connections);
197
+ if (!selected) {
198
+ return;
199
+ }
200
+ type = selected[0];
201
+ identifier = selected[1];
202
+ }
203
+ switch (type) {
204
+ case wallet_types_1.ConnectType.READONLY:
205
+ const networks = Object.keys(this.options.walletConnectChainIds).map((chainId) => this.options.walletConnectChainIds[+chainId]);
206
+ const createReadonlyWalletSession = (_d = (_c = (_b = this.options).createReadonlyWalletSession) === null || _c === void 0 ? void 0 : _c.call(_b, networks)) !== null && _d !== void 0 ? _d : (0, readonly_wallet_1.readonlyWalletModal)({ networks });
207
+ const readonlyWalletSession = await createReadonlyWalletSession;
208
+ if (readonlyWalletSession) {
209
+ this.enableReadonlyWallet((0, readonly_wallet_1.connect)(readonlyWalletSession));
210
+ }
211
+ break;
212
+ case wallet_types_1.ConnectType.WALLETCONNECT:
213
+ this.enableWalletConnect((0, walletconnect_1.connect)(this.options, false, _walletApp));
214
+ break;
215
+ case wallet_types_1.ConnectType.EXTENSION:
216
+ if (!this.extension) {
217
+ throw new Error(`extension instance is not created!`);
218
+ }
219
+ this.extension.connect(identifier);
220
+ this.enableExtension();
221
+ break;
222
+ default:
223
+ throw new Error(`Unknown ConnectType!`);
224
+ }
225
+ };
226
+ /**
227
+ * manual connect to read only session
228
+ *
229
+ * @see Wallet#connectReadonly
230
+ */
231
+ this.connectReadonly = (xplaAddress, network) => {
232
+ this.enableReadonlyWallet((0, readonly_wallet_1.connect)({
233
+ xplaAddress,
234
+ network,
235
+ }));
236
+ };
237
+ /** @see Wallet#disconnect */
238
+ this.disconnect = () => {
239
+ var _a, _b, _c;
240
+ (_a = this.disableReadonlyWallet) === null || _a === void 0 ? void 0 : _a.call(this);
241
+ this.disableReadonlyWallet = null;
242
+ (_b = this.disableExtension) === null || _b === void 0 ? void 0 : _b.call(this);
243
+ this.disableExtension = null;
244
+ (_c = this.disableWalletConnect) === null || _c === void 0 ? void 0 : _c.call(this);
245
+ this.disableWalletConnect = null;
246
+ this.updateStates(this._notConnected);
247
+ };
248
+ /**
249
+ * @see Wallet#post
250
+ * @param tx
251
+ * @param xplaAddress only available new extension
252
+ */
253
+ this.post = async (tx, xplaAddress, walletApp) => {
254
+ // ---------------------------------------------
255
+ // extension
256
+ // ---------------------------------------------
257
+ if (this.disableExtension) {
258
+ return new Promise((resolve, reject) => {
259
+ if (!this.extension) {
260
+ reject(new Error(`extension instance not created!`));
261
+ return;
262
+ }
263
+ const subscription = this.extension.post(tx, xplaAddress).subscribe({
264
+ next: (txResult) => {
265
+ if (txResult.status === web_extension_interface_1.WebExtensionTxStatus.SUCCEED) {
266
+ resolve({
267
+ ...tx,
268
+ result: txResult.payload,
269
+ success: true,
270
+ });
271
+ subscription.unsubscribe();
272
+ }
273
+ },
274
+ error: (error) => {
275
+ reject((0, mapExtensionTxError_1.mapExtensionTxError)(tx, error));
276
+ subscription.unsubscribe();
277
+ },
278
+ });
279
+ });
280
+ }
281
+ // ---------------------------------------------
282
+ // wallet connect
283
+ // ---------------------------------------------
284
+ else if (this.walletConnect) {
285
+ return this.walletConnect
286
+ .post(tx, walletApp)
287
+ .then((result) => ({
288
+ ...tx,
289
+ result,
290
+ success: true,
291
+ }))
292
+ .catch((error) => {
293
+ throw (0, mapWalletConnectError_1.mapWalletConnectError)(tx, error);
294
+ });
295
+ }
296
+ else {
297
+ throw new Error(`There are no connections that can be posting tx!`);
298
+ }
299
+ };
300
+ /**
301
+ * @see Wallet#sign
302
+ * @param tx
303
+ * @param xplaAddress only available new extension
304
+ */
305
+ this.sign = async (tx, xplaAddress, walletApp) => {
306
+ if (this.disableExtension) {
307
+ return new Promise((resolve, reject) => {
308
+ if (!this.extension) {
309
+ reject(new Error(`extension instance is not created!`));
310
+ return;
311
+ }
312
+ const subscription = this.extension.sign(tx, xplaAddress).subscribe({
313
+ next: (txResult) => {
314
+ if (txResult.status === web_extension_interface_1.WebExtensionTxStatus.SUCCEED) {
315
+ resolve({
316
+ ...tx,
317
+ result: xpla_js_1.Tx.fromData(txResult.payload),
318
+ success: true,
319
+ });
320
+ subscription.unsubscribe();
321
+ }
322
+ },
323
+ error: (error) => {
324
+ reject((0, mapExtensionTxError_1.mapExtensionTxError)(tx, error));
325
+ subscription.unsubscribe();
326
+ },
327
+ });
328
+ });
329
+ }
330
+ // ---------------------------------------------
331
+ // wallet connect
332
+ // ---------------------------------------------
333
+ else if (this.walletConnect) {
334
+ if (walletApp && walletApp === wallet_types_1.WalletApp.XPLA_GAMES) {
335
+ throw new Error(`There are no connections that can be signing!`);
336
+ }
337
+ return this.walletConnect
338
+ .sign(tx, walletApp)
339
+ .then((result) => {
340
+ return {
341
+ ...tx,
342
+ result: xpla_js_1.Tx.fromData(result, false),
343
+ success: true,
344
+ };
345
+ })
346
+ .catch((error) => {
347
+ throw (0, mapWalletConnectError_1.mapWalletConnectSignError)(tx, error);
348
+ });
349
+ }
350
+ else {
351
+ throw new Error(`There are no connections that can be signing!`);
352
+ }
353
+ };
354
+ /**
355
+ * @see Wallet#signBytes
356
+ * @param bytes
357
+ * @param xplaAddress only available new extension
358
+ */
359
+ this.signBytes = async (bytes, xplaAddress, walletApp) => {
360
+ if (this.disableExtension) {
361
+ return new Promise((resolve, reject) => {
362
+ if (!this.extension) {
363
+ reject(new Error(`extension instance is not created!`));
364
+ return;
365
+ }
366
+ const subscription = this.extension
367
+ .signBytes(bytes, xplaAddress)
368
+ .subscribe({
369
+ next: (txResult) => {
370
+ if (txResult.status === web_extension_interface_1.WebExtensionTxStatus.SUCCEED) {
371
+ resolve({
372
+ result: {
373
+ recid: txResult.payload.recid,
374
+ signature: Uint8Array.from(Buffer.from(txResult.payload.signature, 'base64')),
375
+ public_key: txResult.payload.public_key
376
+ ? xpla_js_1.PublicKey.fromData(txResult.payload.public_key)
377
+ : undefined,
378
+ },
379
+ success: true,
380
+ });
381
+ subscription.unsubscribe();
382
+ }
383
+ },
384
+ error: (error) => {
385
+ reject((0, mapExtensionTxError_1.mapExtensionSignBytesError)(bytes, error));
386
+ subscription.unsubscribe();
387
+ },
388
+ });
389
+ });
390
+ }
391
+ // ---------------------------------------------
392
+ // wallet connect
393
+ // ---------------------------------------------
394
+ else if (this.walletConnect) {
395
+ if (walletApp && walletApp === wallet_types_1.WalletApp.XPLA_GAMES) {
396
+ throw new Error(`There are no connections that can be signing bytes!`);
397
+ }
398
+ return this.walletConnect
399
+ .signBytes(bytes, walletApp)
400
+ .then((result) => {
401
+ const key = new xpla_js_1.SimplePublicKey(String(result.public_key)).toData();
402
+ return {
403
+ result: {
404
+ recid: result.recid,
405
+ signature: Uint8Array.from(Buffer.from(result.signature, 'base64')),
406
+ public_key: key
407
+ ? xpla_js_1.PublicKey.fromData(key)
408
+ : undefined,
409
+ },
410
+ success: true,
411
+ };
412
+ })
413
+ .catch((error) => {
414
+ throw (0, mapWalletConnectError_1.mapWalletConnectSignBytesError)(bytes, error);
415
+ });
416
+ }
417
+ else {
418
+ throw new Error(`There are no connections that can be signing bytes!`);
419
+ }
420
+ };
421
+ /**
422
+ * @see Wallet#hasCW20Tokens
423
+ * @param chainID
424
+ * @param tokenAddrs Token addresses
425
+ */
426
+ this.hasCW20Tokens = async (chainID, ...tokenAddrs) => {
427
+ if (this.availableExtensionFeature('cw20-token')) {
428
+ return this.extension.hasCW20Tokens(chainID, ...tokenAddrs);
429
+ }
430
+ throw new Error(`Does not support hasCW20Tokens() on this connection`);
431
+ };
432
+ /**
433
+ * @see Wallet#addCW20Tokens
434
+ * @param chainID
435
+ * @param tokenAddrs Token addresses
436
+ */
437
+ this.addCW20Tokens = async (chainID, ...tokenAddrs) => {
438
+ if (this.availableExtensionFeature('cw20-token')) {
439
+ return this.extension.addCW20Tokens(chainID, ...tokenAddrs);
440
+ }
441
+ throw new Error(`Does not support addCW20Tokens() on this connection`);
442
+ };
443
+ /**
444
+ * @see Wallet#hasNetwork
445
+ * @param network
446
+ */
447
+ this.hasNetwork = (network) => {
448
+ if (this.availableExtensionFeature('network')) {
449
+ return this.extension.hasNetwork(network);
450
+ }
451
+ throw new Error(`Does not support hasNetwork() on this connection`);
452
+ };
453
+ /**
454
+ * @see Wallet#hasNetwork
455
+ * @param network
456
+ */
457
+ this.addNetwork = (network) => {
458
+ if (this.availableExtensionFeature('network')) {
459
+ return this.extension.addNetwork(network);
460
+ }
461
+ throw new Error(`Does not support addNetwork() on this connection`);
462
+ };
463
+ // ================================================================
464
+ // internal
465
+ // connect type changing
466
+ // ================================================================
467
+ this.availableExtensionFeature = (feature) => {
468
+ if (this.disableExtension && this.extension) {
469
+ const states = this.extension.getLastStates();
470
+ return (states.type === extension_router_1.ExtensionRouterStatus.WALLET_CONNECTED &&
471
+ states.supportFeatures.has(feature));
472
+ }
473
+ };
474
+ this.updateStates = (next) => {
475
+ const prev = this._states.getValue();
476
+ if (next.status === wallet_types_1.WalletStatus.WALLET_CONNECTED &&
477
+ next.wallets.length === 0) {
478
+ next = {
479
+ status: wallet_types_1.WalletStatus.WALLET_NOT_CONNECTED,
480
+ network: next.network,
481
+ };
482
+ }
483
+ if (prev.status !== next.status || !(0, fast_deep_equal_1.default)(prev, next)) {
484
+ this._states.next(next);
485
+ }
486
+ };
487
+ this.enableReadonlyWallet = (readonlyWallet) => {
488
+ var _a, _b, _c;
489
+ (_a = this.disableWalletConnect) === null || _a === void 0 ? void 0 : _a.call(this);
490
+ (_b = this.disableExtension) === null || _b === void 0 ? void 0 : _b.call(this);
491
+ if (this.readonlyWallet === readonlyWallet ||
492
+ (((_c = this.readonlyWallet) === null || _c === void 0 ? void 0 : _c.xplaAddress) === readonlyWallet.xplaAddress &&
493
+ this.readonlyWallet.network === readonlyWallet.network)) {
494
+ return;
495
+ }
496
+ if (this.readonlyWallet) {
497
+ this.readonlyWallet.disconnect();
498
+ }
499
+ this.readonlyWallet = readonlyWallet;
500
+ this.updateStates({
501
+ status: wallet_types_1.WalletStatus.WALLET_CONNECTED,
502
+ network: readonlyWallet.network,
503
+ wallets: [
504
+ {
505
+ connectType: wallet_types_1.ConnectType.READONLY,
506
+ xplaAddress: readonlyWallet.xplaAddress,
507
+ design: 'readonly',
508
+ },
509
+ ],
510
+ supportFeatures: EMPTY_SUPPORT_FEATURES,
511
+ connection: CONNECTIONS.READONLY,
512
+ });
513
+ this.disableReadonlyWallet = () => {
514
+ readonlyWallet.disconnect();
515
+ this.readonlyWallet = null;
516
+ this.disableReadonlyWallet = null;
517
+ };
518
+ };
519
+ this.enableExtension = () => {
520
+ var _a, _b;
521
+ (_a = this.disableReadonlyWallet) === null || _a === void 0 ? void 0 : _a.call(this);
522
+ (_b = this.disableWalletConnect) === null || _b === void 0 ? void 0 : _b.call(this);
523
+ if (this.disableExtension || !this.extension) {
524
+ return;
525
+ }
526
+ const extensionSubscription = this.extension.states().subscribe({
527
+ next: (extensionStates) => {
528
+ if (extensionStates.type === extension_router_1.ExtensionRouterStatus.WALLET_CONNECTED &&
529
+ xpla_js_1.AccAddress.validate(extensionStates.wallet.xplaAddress)) {
530
+ this.updateStates({
531
+ status: wallet_types_1.WalletStatus.WALLET_CONNECTED,
532
+ network: extensionStates.network,
533
+ wallets: [
534
+ {
535
+ connectType: wallet_types_1.ConnectType.EXTENSION,
536
+ xplaAddress: extensionStates.wallet.xplaAddress,
537
+ design: extensionStates.wallet.design,
538
+ },
539
+ ],
540
+ supportFeatures: extensionStates.supportFeatures,
541
+ connection: memoConnection(wallet_types_1.ConnectType.EXTENSION, extensionStates.extensionInfo.name, extensionStates.extensionInfo.icon, extensionStates.extensionInfo.identifier),
542
+ });
543
+ }
544
+ else {
545
+ this.updateStates(this._notConnected);
546
+ }
547
+ },
548
+ });
549
+ this.disableExtension = () => {
550
+ var _a;
551
+ (_a = this.extension) === null || _a === void 0 ? void 0 : _a.disconnect();
552
+ extensionSubscription.unsubscribe();
553
+ this.disableExtension = null;
554
+ };
555
+ };
556
+ this.enableWalletConnect = (walletConnect) => {
557
+ var _a, _b;
558
+ (_a = this.disableReadonlyWallet) === null || _a === void 0 ? void 0 : _a.call(this);
559
+ (_b = this.disableExtension) === null || _b === void 0 ? void 0 : _b.call(this);
560
+ if (this.walletConnect === walletConnect) {
561
+ return;
562
+ }
563
+ if (this.walletConnect) {
564
+ this.walletConnect.disconnect();
565
+ }
566
+ this.walletConnect = walletConnect;
567
+ const subscribeWalletConnect = (wc) => {
568
+ return wc.session().subscribe({
569
+ next: (status) => {
570
+ var _a;
571
+ switch (status.status) {
572
+ case walletconnect_1.WalletConnectSessionStatus.CONNECTED:
573
+ this.updateStates({
574
+ status: wallet_types_1.WalletStatus.WALLET_CONNECTED,
575
+ network: (_a = this.options.walletConnectChainIds[status.chainId]) !== null && _a !== void 0 ? _a : this.options.defaultNetwork,
576
+ wallets: [
577
+ {
578
+ connectType: wallet_types_1.ConnectType.WALLETCONNECT,
579
+ xplaAddress: status.xplaAddress,
580
+ design: 'walletconnect',
581
+ },
582
+ ],
583
+ supportFeatures: WALLETCONNECT_SUPPORT_FEATURES,
584
+ connection: CONNECTIONS.WALLETCONNECT,
585
+ });
586
+ break;
587
+ default:
588
+ this.updateStates(this._notConnected);
589
+ break;
590
+ }
591
+ },
592
+ });
593
+ };
594
+ const walletConnectSessionSubscription = subscribeWalletConnect(walletConnect);
595
+ this.disableWalletConnect = () => {
596
+ var _a;
597
+ (_a = this.walletConnect) === null || _a === void 0 ? void 0 : _a.disconnect();
598
+ this.walletConnect = null;
599
+ walletConnectSessionSubscription.unsubscribe();
600
+ this.disableWalletConnect = null;
601
+ };
602
+ };
603
+ this._notConnected = {
604
+ status: wallet_types_1.WalletStatus.WALLET_NOT_CONNECTED,
605
+ network: options.defaultNetwork,
606
+ };
607
+ this._initializing = {
608
+ status: wallet_types_1.WalletStatus.INITIALIZING,
609
+ network: options.defaultNetwork,
610
+ };
611
+ this._availableConnectTypes = new rxjs_1.BehaviorSubject([
612
+ wallet_types_1.ConnectType.READONLY,
613
+ wallet_types_1.ConnectType.WALLETCONNECT,
614
+ ]);
615
+ this._availableInstallTypes = new rxjs_1.BehaviorSubject([]);
616
+ this._states = new rxjs_1.BehaviorSubject(this._initializing);
617
+ let numSessionCheck = 0;
618
+ // wait checking the availability of the chrome extension
619
+ // 0. check if extension wallet session is exists
620
+ (0, checkExtensionReady_1.checkExtensionReady)((_a = options.waitingChromeExtensionInstallCheck) !== null && _a !== void 0 ? _a : DEFAULT_WAITING_CHROME_EXTENSION_INSTALL_CHECK, this.isChromeExtensionCompatibleBrowser()).then((ready) => {
621
+ var _a;
622
+ if (ready) {
623
+ this._availableConnectTypes.next([
624
+ wallet_types_1.ConnectType.EXTENSION,
625
+ wallet_types_1.ConnectType.WALLETCONNECT,
626
+ wallet_types_1.ConnectType.READONLY,
627
+ ]);
628
+ this.extension = new extension_router_1.ExtensionRouter({
629
+ hostWindow: window,
630
+ selectExtension: options.selectExtension,
631
+ dangerously__chromeExtensionCompatibleBrowserCheck: (_a = options.dangerously__chromeExtensionCompatibleBrowserCheck) !== null && _a !== void 0 ? _a : env_1.DEFAULT_CHROME_EXTENSION_COMPATIBLE_BROWSER_CHECK,
632
+ defaultNetwork: options.defaultNetwork,
633
+ });
634
+ const subscription = this.extension
635
+ .states()
636
+ .pipe((0, operators_1.filter)(({ type }) => type !== extension_router_1.ExtensionRouterStatus.INITIALIZING))
637
+ .subscribe((extensionStates) => {
638
+ try {
639
+ subscription.unsubscribe();
640
+ }
641
+ catch (_a) { }
642
+ if (extensionStates.type === extension_router_1.ExtensionRouterStatus.WALLET_CONNECTED &&
643
+ !this.disableWalletConnect &&
644
+ !this.disableReadonlyWallet) {
645
+ this.enableExtension();
646
+ }
647
+ else if (numSessionCheck === 0) {
648
+ numSessionCheck += 1;
649
+ }
650
+ else {
651
+ this.updateStates(this._notConnected);
652
+ }
653
+ });
654
+ }
655
+ else {
656
+ if ((0, browser_check_1.isDesktopChrome)(this.isChromeExtensionCompatibleBrowser())) {
657
+ this._availableInstallTypes.next([wallet_types_1.ConnectType.EXTENSION]);
658
+ }
659
+ if (numSessionCheck === 0) {
660
+ numSessionCheck += 1;
661
+ }
662
+ else {
663
+ this.updateStates(this._notConnected);
664
+ }
665
+ }
666
+ });
667
+ // 1. check if readonly wallet session is exists
668
+ const draftReadonlyWallet = (0, readonly_wallet_1.connectIfSessionExists)();
669
+ if (draftReadonlyWallet) {
670
+ this.enableReadonlyWallet(draftReadonlyWallet);
671
+ return;
672
+ }
673
+ // 2. check if walletconnect sesison is exists
674
+ const draftWalletConnect = (0, walletconnect_1.connectIfSessionExists)(options);
675
+ if (draftWalletConnect &&
676
+ draftWalletConnect.getLatestSession().status ===
677
+ walletconnect_1.WalletConnectSessionStatus.CONNECTED) {
678
+ this.enableWalletConnect(draftWalletConnect);
679
+ }
680
+ else if (numSessionCheck === 0) {
681
+ numSessionCheck += 1;
682
+ }
683
+ else {
684
+ this.updateStates(this._notConnected);
685
+ }
686
+ }
687
+ }
688
+ exports.WalletController = WalletController;
689
+ const memoizedConnections = new Map();
690
+ function memoConnection(connectType, name, icon, identifier = '') {
691
+ const key = [connectType, name, icon, identifier].join(';');
692
+ if (memoizedConnections.has(key)) {
693
+ return memoizedConnections.get(key);
694
+ }
695
+ const connection = {
696
+ type: connectType,
697
+ name,
698
+ icon,
699
+ identifier,
700
+ };
701
+ memoizedConnections.set(key, connection);
702
+ return connection;
703
+ }
704
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29udHJvbGxlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9Aa3NhbmdrdWsxMC93YWxsZXQtY29udHJvbGxlci9jb250cm9sbGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBLDJDQVF1QjtBQUN2QiwyREFha0M7QUFDbEMsaUZBRzZDO0FBQzdDLHNFQUF3QztBQUN4QywrQkFNYztBQUNkLDhDQUE2QztBQUM3QywrQkFHZTtBQUNmLHlFQUd5QztBQUN6Qyw2RUFJMkM7QUFDM0MsMkRBQTJEO0FBQzNELGlFQUdvQztBQUNwQywwRUFHaUQ7QUFDakQsK0RBTW1DO0FBQ25DLDJEQU1pQztBQUNqQyw2REFBMEQ7QUFDMUQscUVBQWtFO0FBQ2xFLHlEQUFzRDtBQUN0RCx5REFBd0Q7QUFDeEQscUVBQWtFO0FBQ2xFLDZEQUEwRDtBQXdGMUQsTUFBTSxXQUFXLEdBQUc7SUFDbEIsQ0FBQywwQkFBVyxDQUFDLFFBQVEsQ0FBQyxFQUFFO1FBQ3RCLElBQUksRUFBRSwwQkFBVyxDQUFDLFFBQVE7UUFDMUIsSUFBSSxFQUFFLGlCQUFpQjtRQUN2QixJQUFJLEVBQUUsMERBQTBEO0tBQ25EO0lBQ2YsQ0FBQywwQkFBVyxDQUFDLGFBQWEsQ0FBQyxFQUFFO1FBQzNCLElBQUksRUFBRSwwQkFBVyxDQUFDLGFBQWE7UUFDL0IsSUFBSSxFQUFFLGdCQUFnQjtRQUN0QixJQUFJLEVBQUUsK0RBQStEO0tBQ3hEO0NBQ1AsQ0FBQztBQUVYLE1BQU0sOENBQThDLEdBQUcsSUFBSSxHQUFHLENBQUMsQ0FBQztBQUVoRSxNQUFNLDhCQUE4QixHQUFHLElBQUksR0FBRyxDQUEyQjtJQUN2RSxNQUFNLEVBQUUsTUFBTSxFQUFFLFlBQVk7Q0FDN0IsQ0FBQyxDQUFDO0FBRUgsTUFBTSxzQkFBc0IsR0FBRyxJQUFJLEdBQUcsRUFBNEIsQ0FBQztBQUVuRSw4QkFBOEI7QUFDOUIsTUFBYSxnQkFBZ0I7SUFnQjNCLFlBQXFCLE9B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LENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBBY2NBZGRyZXNzLFxuICBDcmVhdGVUeE9wdGlvbnMsXG4gIExDRENsaWVudCxcbiAgUHVibGljS2V5LFxuICBTaW1wbGVQdWJsaWNLZXksXG4gIFR4LFxuICBTaWduTW9kZSxcbn0gZnJvbSAnQHhwbGEveHBsYS5qcyc7XG5pbXBvcnQge1xuICBDb25uZWN0ZWRXYWxsZXQsXG4gIENvbm5lY3Rpb24sXG4gIENvbm5lY3RUeXBlLFxuICBJbnN0YWxsYXRpb24sXG4gIE5ldHdvcmtJbmZvLFxuICBTaWduQnl0ZXNSZXN1bHQsXG4gIFNpZ25SZXN1bHQsXG4gIFR4UmVzdWx0LFxuICBXYWxsZXRBcHAsXG4gIFdhbGxldExDRENsaWVudENvbmZpZyxcbiAgV2FsbGV0U3RhdGVzLFxuICBXYWxsZXRTdGF0dXMsXG59IGZyb20gJ0Brc2FuZ2t1azEwL3dhbGxldC10eXBlcyc7XG5pbXBvcnQge1xuICBYcGxhV2ViRXh0ZW5zaW9uRmVhdHVyZXMsXG4gIFdlYkV4dGVuc2lvblR4U3RhdHVzLFxufSBmcm9tICdAa3NhbmdrdWsxMC93ZWItZXh0ZW5zaW9uLWludGVyZmFjZSc7XG5pbXBvcnQgZGVlcEVxdWFsIGZyb20gJ2Zhc3QtZGVlcC1lcXVhbCc7XG5pbXBvcnQge1xuICBCZWhhdmlvclN1YmplY3QsXG4gIGNvbWJpbmVMYXRlc3QsXG4gIGZpcnN0VmFsdWVGcm9tLFxuICBPYnNlcnZhYmxlLFxuICBTdWJzY3JpcHRpb24sXG59IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgZmlsdGVyLCBtYXAgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQge1xuICBDSFJPTUVfRVhURU5TSU9OX0lOU1RBTExfVVJMLFxuICBERUZBVUxUX0NIUk9NRV9FWFRFTlNJT05fQ09NUEFUSUJMRV9CUk9XU0VSX0NIRUNLLFxufSBmcm9tICcuL2Vudic7XG5pbXBvcnQge1xuICBtYXBFeHRlbnNpb25TaWduQnl0ZXNFcnJvcixcbiAgbWFwRXh0ZW5zaW9uVHhFcnJvcixcbn0gZnJvbSAnLi9leGNlcHRpb24vbWFwRXh0ZW5zaW9uVHhFcnJvcic7XG5pbXBvcnQgeyBcbiAgbWFwV2FsbGV0Q29ubmVjdEVycm9yLFxuICBtYXBXYWxsZXRDb25uZWN0U2lnbkVycm9yLFxuICBtYXBXYWxsZXRDb25uZWN0U2lnbkJ5dGVzRXJyb3IsXG59IGZyb20gJy4vZXhjZXB0aW9uL21hcFdhbGxldENvbm5lY3RFcnJvcic7XG5pbXBvcnQgeyBzZWxlY3RDb25uZWN0aW9uIH0gZnJvbSAnLi9tb2R1bGVzL2Nvbm5lY3QtbW9kYWwnO1xuaW1wb3J0IHtcbiAgRXh0ZW5zaW9uUm91dGVyLFxuICBFeHRlbnNpb25Sb3V0ZXJTdGF0dXMsXG59IGZyb20gJy4vbW9kdWxlcy9leHRlbnNpb24tcm91dGVyJztcbmltcG9ydCB7XG4gIEV4dGVuc2lvbkluZm8sXG4gIGdldFhwbGFFeHRlbnNpb25zLFxufSBmcm9tICcuL21vZHVsZXMvZXh0ZW5zaW9uLXJvdXRlci9tdWx0aUNoYW5uZWwnO1xuaW1wb3J0IHtcbiAgY29ubmVjdCBhcyByZUNvbm5lY3QsXG4gIGNvbm5lY3RJZlNlc3Npb25FeGlzdHMgYXMgcmVDb25uZWN0SWZTZXNzaW9uRXhpc3RzLFxuICBSZWFkb25seVdhbGxldENvbnRyb2xsZXIsXG4gIHJlYWRvbmx5V2FsbGV0TW9kYWwsXG4gIFJlYWRvbmx5V2FsbGV0U2Vzc2lvbixcbn0gZnJvbSAnLi9tb2R1bGVzL3JlYWRvbmx5LXdhbGxldCc7XG5pbXBvcnQge1xuICBjb25uZWN0IGFzIHdjQ29ubmVjdCxcbiAgY29ubmVjdElmU2Vzc2lvbkV4aXN0cyBhcyB3Y0Nvbm5lY3RJZlNlc3Npb25FeGlzdHMsXG4gIFdhbGxldENvbm5lY3RDb250cm9sbGVyLFxuICBXYWxsZXRDb25uZWN0Q29udHJvbGxlck9wdGlvbnMsXG4gIFdhbGxldENvbm5lY3RTZXNzaW9uU3RhdHVzLFxufSBmcm9tICcuL21vZHVsZXMvd2FsbGV0Y29ubmVjdCc7XG5pbXBvcnQgeyBnZXRFeHRlbnNpb25zIH0gZnJvbSAnLi9vcGVyYXRvcnMvZ2V0RXh0ZW5zaW9ucyc7XG5pbXBvcnQgeyB0b0Nvbm5lY3RlZFdhbGxldCB9IGZyb20gJy4vb3BlcmF0b3JzL3RvQ29ubmVjdGVkV2FsbGV0JztcbmltcG9ydCB7IHRvTGNkQ2xpZW50IH0gZnJvbSAnLi9vcGVyYXRvcnMvdG9MY2RDbGllbnQnO1xuaW1wb3J0IHsgaXNEZXNrdG9wQ2hyb21lIH0gZnJvbSAnLi91dGlscy9icm93c2VyLWNoZWNrJztcbmltcG9ydCB7IGNoZWNrRXh0ZW5zaW9uUmVhZHkgfSBmcm9tICcuL3V0aWxzL2NoZWNrRXh0ZW5zaW9uUmVhZHknO1xuaW1wb3J0IHsgc29ydENvbm5lY3Rpb25zIH0gZnJvbSAnLi91dGlscy9zb3J0Q29ubmVjdGlvbnMnO1xuXG5leHBvcnQgaW50ZXJmYWNlIFdhbGxldENvbnRyb2xsZXJPcHRpb25zXG4gIGV4dGVuZHMgV2FsbGV0Q29ubmVjdENvbnRyb2xsZXJPcHRpb25zIHtcbiAgLyoqXG4gICAqIOKaoO+4jyBEb24ndCBoYXJkY29kaW5nIHRoaXMsIHVzZSBnZXRDaGFpbiBPcHRpb25zKClcbiAgICpcbiAgICogZmFsbGJhY2sgbmV0d29yayBpZiBjb250cm9sbGVyIGlzIG5vdCBjb25uZWN0ZWRcbiAgICovXG4gIGRlZmF1bHROZXR3b3JrOiBOZXR3b3JrSW5mbztcblxuICAvKipcbiAgICog4pqg77iPIERvbid0IGhhcmRjb2RpbmcgdGhpcywgdXNlIGdldENoYWluIE9wdGlvbnMoKVxuICAgKlxuICAgKiBmb3Igd2FsbGV0Y29ubmVjdFxuICAgKlxuICAgKiBUaGUgbmV0d29yayBydWxlcyBwYXNzZWQgYnkgdGhlIFhwbGEgTW9iaWxlIGFyZSAwIGlzIHRlc3RuZXQsIDEgaXMgbWFpbm5ldC5cbiAgICpcbiAgICogQWx3YXlzIHNldCB0ZXN0bmV0IGZvciAwIGFuZCBtYWlubmV0IGZvciAxLlxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKiBgYGBcbiAgICogY29uc3QgbWFpbm5ldDogTmV0d29ya0luZm8gPSB7XG4gICAqICBuYW1lOiAnbWFpbm5ldCcsXG4gICAqICBjaGFpbklEOiAnZGltZW5zaW9uLTEnLFxuICAgKiAgbGNkOiAnaHR0cHM6Ly9sY2QueHBsYS5uZXQnLFxuICAgKiB9XG4gICAqXG4gICAqIGNvbnN0IHRlc3RuZXQ6IE5ldHdvcmtJbmZvID0ge1xuICAgKiAgbmFtZTogJ3Rlc3RuZXQnLFxuICAgKiAgY2hhaW5JRDogJ2N1YmUtMScsXG4gICAqICBsY2Q6ICdodHRwczovL2xjZC54cGxhLm5ldCcsXG4gICAqIH1cbiAgICpcbiAgICogY29uc3Qgd2FsbGV0Q29ubmVjdENoYWluSWRzOiBSZWNvcmQ8bnVtYmVyLCBOZXR3b3JrSW5mbz4gPSB7XG4gICAqICAgMDogdGVzdG5ldCxcbiAgICogICAxOiBtYWlubmV0LFxuICAgKiB9XG4gICAqXG4gICAqIDxXYWxsZXRQcm92aWRlciB3YWxsZXRDb25uZWN0Q2hhaW5JZHM9e3dhbGxldENvbm5lY3RDaGFpbklkc30+XG4gICAqIGBgYFxuICAgKi9cbiAgd2FsbGV0Q29ubmVjdENoYWluSWRzOiBSZWNvcmQ8bnVtYmVyLCBOZXR3b3JrSW5mbz47XG5cbiAgLyoqXG4gICAqIHJ1biBhdCBleGVjdXRpbmcgdGhlIGBjb25uZWN0KENvbm5lY3RUeXBlLlJFQURPTkxZKWBcbiAgICovXG4gIGNyZWF0ZVJlYWRvbmx5V2FsbGV0U2Vzc2lvbj86IChcbiAgICBuZXR3b3JrczogTmV0d29ya0luZm9bXSxcbiAgKSA9PiBQcm9taXNlPFJlYWRvbmx5V2FsbGV0U2Vzc2lvbiB8IG51bGw+O1xuXG4gIC8qKlxuICAgKiBydW4gYXQgZXhlY3V0aW5nIHRoZSBgY29ubmVjdCgpYCAtIG9ubHkgdXNlZCB3aGVuIGRvZXMgbm90IGlucHV0IENvbm5lY3RUeXBlXG4gICAqL1xuICBzZWxlY3RDb25uZWN0aW9uPzogKFxuICAgIGNvbm5lY3Rpb25zOiBDb25uZWN0aW9uW10sXG4gICkgPT4gUHJvbWlzZTxbdHlwZTogQ29ubmVjdFR5cGUsIGlkZW50aWZpZXI6IHN0cmluZyB8IHVuZGVmaW5lZF0gfCBudWxsPjtcblxuICAvKipcbiAgICogcnVuIGF0IGV4ZWN1dGluZyB0aGUgYGNvbm5lY3QoQ29ubmVjdFR5cGUuRVhURU5TSU9OKWBcbiAgICogaWYgdXNlciBpbnN0YWxsZWQgbXVsdGlwbGUgd2FsbGV0c1xuICAgKi9cbiAgc2VsZWN0RXh0ZW5zaW9uPzogKFxuICAgIGV4dGVuc2lvbkluZm9zOiBFeHRlbnNpb25JbmZvW10sXG4gICkgPT4gUHJvbWlzZTxFeHRlbnNpb25JbmZvIHwgbnVsbD47XG5cbiAgLyoqXG4gICAqIG1pbGxpc2Vjb25kcyB0byB3YWl0IGNoZWNraW5nIGNocm9tZSBleHRlbnNpb24gaXMgaW5zdGFsbGVkXG4gICAqXG4gICAqIEBkZWZhdWx0IDEwMDAgKiAzIG1pbGlzZWNvbmRzXG4gICAqL1xuICB3YWl0aW5nQ2hyb21lRXh0ZW5zaW9uSW5zdGFsbENoZWNrPzogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiDimqDvuI8gVGhpcyBBUEkgaXMgYW4gb3B0aW9uIGZvciB3YWxsZXQgZGV2ZWxvcGVycy4gUGxlYXNlIGRvbid0IHVzZSBkQXBwIGRldmVsb3BlcnMuXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqIGBgYFxuICAgKiA8V2FsbGV0UHJvdmlkZXIgZGFuZ2Vyb3VzbHlfX2Nocm9tZUV4dGVuc2lvbkNvbXBhdGlibGVCcm93c2VyQ2hlY2s9eyh1c2VyQWdlbnQ6IHN0cmluZykgPT4ge1xuICAgKiAgIHJldHVybiAvTXlXYWxsZXRcXC8vLnRlc3QodXNlckFnZW50KTtcbiAgICogfX0+XG4gICAqIGBgYFxuICAgKi9cbiAgZGFuZ2Vyb3VzbHlfX2Nocm9tZUV4dGVuc2lvbkNvbXBhdGlibGVCcm93c2VyQ2hlY2s/OiAoXG4gICAgdXNlckFnZW50OiBzdHJpbmcsXG4gICkgPT4gYm9vbGVhbjtcbn1cblxuY29uc3QgQ09OTkVDVElPTlMgPSB7XG4gIFtDb25uZWN0VHlwZS5SRUFET05MWV06IHtcbiAgICB0eXBlOiBDb25uZWN0VHlwZS5SRUFET05MWSxcbiAgICBuYW1lOiAnVmlldyBhbiBhZGRyZXNzJyxcbiAgICBpY29uOiAnaHR0cHM6Ly9hc3NldHMueHBsYS5pby9pY29uL3dhbGxldC1wcm92aWRlci9yZWFkb25seS5zdmcnLFxuICB9IGFzIENvbm5lY3Rpb24sXG4gIFtDb25uZWN0VHlwZS5XQUxMRVRDT05ORUNUXToge1xuICAgIHR5cGU6IENvbm5lY3RUeXBlLldBTExFVENPTk5FQ1QsXG4gICAgbmFtZTogJ1dhbGxldCBDb25uZWN0JyxcbiAgICBpY29uOiAnaHR0cHM6Ly9hc3NldHMueHBsYS5pby9pY29uL3dhbGxldC1wcm92aWRlci93YWxsZXRjb25uZWN0LnN2ZycsXG4gIH0gYXMgQ29ubmVjdGlvbixcbn0gYXMgY29uc3Q7XG5cbmNvbnN0IERFRkFVTFRfV0FJVElOR19DSFJPTUVfRVhURU5TSU9OX0lOU1RBTExfQ0hFQ0sgPSAxMDAwICogMztcblxuY29uc3QgV0FMTEVUQ09OTkVDVF9TVVBQT1JUX0ZFQVRVUkVTID0gbmV3IFNldDxYcGxhV2ViRXh0ZW5zaW9uRmVhdHVyZXM+KFtcbiAgJ3Bvc3QnLCAnc2lnbicsICdzaWduLWJ5dGVzJ1xuXSk7XG5cbmNvbnN0IEVNUFRZX1NVUFBPUlRfRkVBVFVSRVMgPSBuZXcgU2V0PFhwbGFXZWJFeHRlbnNpb25GZWF0dXJlcz4oKTtcblxuLy9ub2luc3BlY3Rpb24gRVM2TWlzc2luZ0F3YWl0XG5leHBvcnQgY2xhc3MgV2FsbGV0Q29udHJvbGxlciB7XG4gIHByaXZhdGUgZXh0ZW5zaW9uOiBFeHRlbnNpb25Sb3V0ZXIgfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSB3YWxsZXRDb25uZWN0OiBXYWxsZXRDb25uZWN0Q29udHJvbGxlciB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIHJlYWRvbmx5V2FsbGV0OiBSZWFkb25seVdhbGxldENvbnRyb2xsZXIgfCBudWxsID0gbnVsbDtcblxuICBwcml2YXRlIF9hdmFpbGFibGVDb25uZWN0VHlwZXM6IEJlaGF2aW9yU3ViamVjdDxDb25uZWN0VHlwZVtdPjtcbiAgcHJpdmF0ZSBfYXZhaWxhYmxlSW5zdGFsbFR5cGVzOiBCZWhhdmlvclN1YmplY3Q8Q29ubmVjdFR5cGVbXT47XG4gIHByaXZhdGUgX3N0YXRlczogQmVoYXZpb3JTdWJqZWN0PFdhbGxldFN0YXRlcz47XG5cbiAgcHJpdmF0ZSBkaXNhYmxlUmVhZG9ubHlXYWxsZXQ6ICgoKSA9PiB2b2lkKSB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIGRpc2FibGVFeHRlbnNpb246ICgoKSA9PiB2b2lkKSB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIGRpc2FibGVXYWxsZXRDb25uZWN0OiAoKCkgPT4gdm9pZCkgfCBudWxsID0gbnVsbDtcblxuICBwcml2YXRlIHJlYWRvbmx5IF9ub3RDb25uZWN0ZWQ6IFdhbGxldFN0YXRlcztcbiAgcHJpdmF0ZSByZWFkb25seSBfaW5pdGlhbGl6aW5nOiBXYWxsZXRTdGF0ZXM7XG5cbiAgY29uc3RydWN0b3IocmVhZG9ubHkgb3B0aW9uczogV2FsbGV0Q29udHJvbGxlck9wdGlvbnMpIHtcbiAgICB0aGlzLl9ub3RDb25uZWN0ZWQgPSB7XG4gICAgICBzdGF0dXM6IFdhbGxldFN0YXR1cy5XQUxMRVRfTk9UX0NPTk5FQ1RFRCxcbiAgICAgIG5ldHdvcms6IG9wdGlvbnMuZGVmYXVsdE5ldHdvcmssXG4gICAgfTtcblxuICAgIHRoaXMuX2luaXRpYWxpemluZyA9IHtcbiAgICAgIHN0YXR1czogV2FsbGV0U3RhdHVzLklOSVRJQUxJWklORyxcbiAgICAgIG5ldHdvcms6IG9wdGlvbnMuZGVmYXVsdE5ldHdvcmssXG4gICAgfTtcblxuICAgIHRoaXMuX2F2YWlsYWJsZUNvbm5lY3RUeXBlcyA9IG5ldyBCZWhhdmlvclN1YmplY3Q8Q29ubmVjdFR5cGVbXT4oW1xuICAgICAgQ29ubmVjdFR5cGUuUkVBRE9OTFksXG4gICAgICBDb25uZWN0VHlwZS5XQUxMRVRDT05ORUNULFxuICAgIF0pO1xuXG4gICAgdGhpcy5fYXZhaWxhYmxlSW5zdGFsbFR5cGVzID0gbmV3IEJlaGF2aW9yU3ViamVjdDxDb25uZWN0VHlwZVtdPihbXSk7XG5cbiAgICB0aGlzLl9zdGF0ZXMgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PFdhbGxldFN0YXRlcz4odGhpcy5faW5pdGlhbGl6aW5nKTtcblxuICAgIGxldCBudW1TZXNzaW9uQ2hlY2s6IG51bWJlciA9IDA7XG5cbiAgICAvLyB3YWl0IGNoZWNraW5nIHRoZSBhdmFpbGFiaWxpdHkgb2YgdGhlIGNocm9tZSBleHRlbnNpb25cbiAgICAvLyAwLiBjaGVjayBpZiBleHRlbnNpb24gd2FsbGV0IHNlc3Npb24gaXMgZXhpc3RzXG4gICAgY2hlY2tFeHRlbnNpb25SZWFkeShcbiAgICAgIG9wdGlvbnMud2FpdGluZ0Nocm9tZUV4dGVuc2lvbkluc3RhbGxDaGVjayA/P1xuICAgICAgICBERUZBVUxUX1dBSVRJTkdfQ0hST01FX0VYVEVOU0lPTl9JTlNUQUxMX0NIRUNLLFxuICAgICAgdGhpcy5pc0Nocm9tZUV4dGVuc2lvbkNvbXBhdGlibGVCcm93c2VyKCksXG4gICAgKS50aGVuKChyZWFkeTogYm9vbGVhbikgPT4ge1xuICAgICAgaWYgKHJlYWR5KSB7XG4gICAgICAgIHRoaXMuX2F2YWlsYWJsZUNvbm5lY3RUeXBlcy5uZXh0KFtcbiAgICAgICAgICBDb25uZWN0VHlwZS5FWFRFTlNJT04sXG4gICAgICAgICAgQ29ubmVjdFR5cGUuV0FMTEVUQ09OTkVDVCxcbiAgICAgICAgICBDb25uZWN0VHlwZS5SRUFET05MWSxcbiAgICAgICAgXSk7XG5cbiAgICAgICAgdGhpcy5leHRlbnNpb24gPSBuZXcgRXh0ZW5zaW9uUm91dGVyKHtcbiAgICAgICAgICBob3N0V2luZG93OiB3aW5kb3csXG4gICAgICAgICAgc2VsZWN0RXh0ZW5zaW9uOiBvcHRpb25zLnNlbGVjdEV4dGVuc2lvbixcbiAgICAgICAgICBkYW5nZXJvdXNseV9fY2hyb21lRXh0ZW5zaW9uQ29tcGF0aWJsZUJyb3dzZXJDaGVjazpcbiAgICAgICAgICAgIG9wdGlvbnMuZGFuZ2Vyb3VzbHlfX2Nocm9tZUV4dGVuc2lvbkNvbXBhdGlibGVCcm93c2VyQ2hlY2sgPz9cbiAgICAgICAgICAgIERFRkFVTFRfQ0hST01FX0VYVEVOU0lPTl9DT01QQVRJQkxFX0JST1dTRVJfQ0hFQ0ssXG4gICAgICAgICAgZGVmYXVsdE5ldHdvcms6IG9wdGlvbnMuZGVmYXVsdE5ldHdvcmssXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IHN1YnNjcmlwdGlvbiA9IHRoaXMuZXh0ZW5zaW9uXG4gICAgICAgICAgLnN0YXRlcygpXG4gICAgICAgICAgLnBpcGUoXG4gICAgICAgICAgICBmaWx0ZXIoKHsgdHlwZSB9KSA9PiB0eXBlICE9PSBFeHRlbnNpb25Sb3V0ZXJTdGF0dXMuSU5JVElBTElaSU5HKSxcbiAgICAgICAgICApXG4gICAgICAgICAgLnN1YnNjcmliZSgoZXh0ZW5zaW9uU3RhdGVzKSA9PiB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICBzdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcbiAgICAgICAgICAgIH0gY2F0Y2gge31cblxuICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICBleHRlbnNpb25TdGF0ZXMudHlwZSA9PT0gRXh0ZW5zaW9uUm91dGVyU3RhdHVzLldBTExFVF9DT05ORUNURUQgJiZcbiAgICAgICAgICAgICAgIXRoaXMuZGlzYWJsZVdhbGxldENvbm5lY3QgJiZcbiAgICAgICAgICAgICAgIXRoaXMuZGlzYWJsZVJlYWRvbmx5V2FsbGV0XG4gICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgdGhpcy5lbmFibGVFeHRlbnNpb24oKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAobnVtU2Vzc2lvbkNoZWNrID09PSAwKSB7XG4gICAgICAgICAgICAgIG51bVNlc3Npb25DaGVjayArPSAxO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgdGhpcy51cGRhdGVTdGF0ZXModGhpcy5fbm90Q29ubmVjdGVkKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmIChpc0Rlc2t0b3BDaHJvbWUodGhpcy5pc0Nocm9tZUV4dGVuc2lvbkNvbXBhdGlibGVCcm93c2VyKCkpKSB7XG4gICAgICAgICAgdGhpcy5fYXZhaWxhYmxlSW5zdGFsbFR5cGVzLm5leHQoW0Nvbm5lY3RUeXBlLkVYVEVOU0lPTl0pO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKG51bVNlc3Npb25DaGVjayA9PT0gMCkge1xuICAgICAgICAgIG51bVNlc3Npb25DaGVjayArPSAxO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRoaXMudXBkYXRlU3RhdGVzKHRoaXMuX25vdENvbm5lY3RlZCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcblxuICAgIC8vIDEuIGNoZWNrIGlmIHJlYWRvbmx5IHdhbGxldCBzZXNzaW9uIGlzIGV4aXN0c1xuICAgIGNvbnN0IGRyYWZ0UmVhZG9ubHlXYWxsZXQgPSByZUNvbm5lY3RJZlNlc3Npb25FeGlzdHMoKTtcblxuICAgIGlmIChkcmFmdFJlYWRvbmx5V2FsbGV0KSB7XG4gICAgICB0aGlzLmVuYWJsZVJlYWRvbmx5V2FsbGV0KGRyYWZ0UmVhZG9ubHlXYWxsZXQpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIDIuIGNoZWNrIGlmIHdhbGxldGNvbm5lY3Qgc2VzaXNvbiBpcyBleGlzdHNcbiAgICBjb25zdCBkcmFmdFdhbGxldENvbm5lY3QgPSB3Y0Nvbm5lY3RJZlNlc3Npb25FeGlzdHMob3B0aW9ucyk7XG5cbiAgICBpZiAoXG4gICAgICBkcmFmdFdhbGxldENvbm5lY3QgJiZcbiAgICAgIGRyYWZ0V2FsbGV0Q29ubmVjdC5nZXRMYXRlc3RTZXNzaW9uKCkuc3RhdHVzID09PVxuICAgICAgICBXYWxsZXRDb25uZWN0U2Vzc2lvblN0YXR1cy5DT05ORUNURURcbiAgICApIHtcbiAgICAgIHRoaXMuZW5hYmxlV2FsbGV0Q29ubmVjdChkcmFmdFdhbGxldENvbm5lY3QpO1xuICAgIH0gZWxzZSBpZiAobnVtU2Vzc2lvbkNoZWNrID09PSAwKSB7XG4gICAgICBudW1TZXNzaW9uQ2hlY2sgKz0gMTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy51cGRhdGVTdGF0ZXModGhpcy5fbm90Q29ubmVjdGVkKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogU29tZSBtb2JpbGUgd2FsbGV0IGVtdWxhdGVzIHRoZSBiZWhhdmlvciBvZiBjaHJvbWUgZXh0ZW5zaW9uLlxuICAgKiBJdCBjb25maXJtcyB0aGF0IHRoZSBjdXJyZW50IGNvbm5lY3Rpb24gZW52aXJvbm1lbnQgaXMgc3VjaCBhIHdhbGxldC5cbiAgICogKElmIHlvdSBhcmUgcnVubmluZyBjb25uZWN0KCkgYnkgY2hlY2tpbmcgYXZhaWxhYmxlQ29ubmVjdFR5cGUsIHlvdSBkbyBub3QgbmVlZCB0byB1c2UgdGhpcyBBUEkuKVxuICAgKlxuICAgKiBAc2VlIFdhbGxldCNpc0Nocm9tZUV4dGVuc2lvbkNvbXBhdGlibGVCcm93c2VyXG4gICAqL1xuICBpc0Nocm9tZUV4dGVuc2lvbkNvbXBhdGlibGVCcm93c2VyID0gKCk6IGJvb2xlYW4gPT4ge1xuICAgIHJldHVybiAoXG4gICAgICB0aGlzLm9wdGlvbnMuZGFuZ2Vyb3VzbHlfX2Nocm9tZUV4dGVuc2lvbkNvbXBhdGlibGVCcm93c2VyQ2hlY2sgPz9cbiAgICAgIERFRkFVTFRfQ0hST01FX0VYVEVOU0lPTl9DT01QQVRJQkxFX0JST1dTRVJfQ0hFQ0tcbiAgICApKG5hdmlnYXRvci51c2VyQWdlbnQpO1xuICB9O1xuXG4gIC8qKlxuICAgKiBhdmFpbGFibGUgY29ubmVjdCB0eXBlcyBvbiB0aGUgYnJvd3NlclxuICAgKlxuICAgKiBAc2VlIFdhbGxldCNhdmFpbGFibGVDb25uZWN0VHlwZXNcbiAgICovXG4gIGF2YWlsYWJsZUNvbm5lY3RUeXBlcyA9ICgpOiBPYnNlcnZhYmxlPENvbm5lY3RUeXBlW10+ID0+IHtcbiAgICByZXR1cm4gdGhpcy5fYXZhaWxhYmxlQ29ubmVjdFR5cGVzLmFzT2JzZXJ2YWJsZSgpO1xuICB9O1xuXG4gIC8qKlxuICAgKiBhdmFpbGFibGUgY29ubmVjdGlvbnMgaW5jbHVkZXMgaWRlbnRpZmllciwgbmFtZSwgaWNvblxuICAgKlxuICAgKiBAc2VlIFdhbGxldCNhdmFpbGFibGVDb25uZWN0aW9uc1xuICAgKi9cbiAgYXZhaWxhYmxlQ29ubmVjdGlvbnMgPSAoKTogT2JzZXJ2YWJsZTxDb25uZWN0aW9uW10+ID0+IHtcbiAgICByZXR1cm4gdGhpcy5fYXZhaWxhYmxlQ29ubmVjdFR5cGVzLnBpcGUoXG4gICAgICBtYXAoKGNvbm5lY3RUeXBlcykgPT4ge1xuICAgICAgICBjb25zdCBjb25uZWN0aW9uczogQ29ubmVjdGlvbltdID0gW107XG5cbiAgICAgICAgZm9yIChjb25zdCBjb25uZWN0VHlwZSBvZiBjb25uZWN0VHlwZXMpIHtcbiAgICAgICAgICBpZiAoY29ubmVjdFR5cGUgPT09IENvbm5lY3RUeXBlLkVYVEVOU0lPTikge1xuICAgICAgICAgICAgY29uc3QgeHBsYUV4dGVuc2lvbnMgPSBnZXRYcGxhRXh0ZW5zaW9ucygpO1xuXG4gICAgICAgICAgICBmb3IgKGNvbnN0IHhwbGFFeHRlbnNpb24gb2YgeHBsYUV4dGVuc2lvbnMpIHtcbiAgICAgICAgICAgICAgY29ubmVjdGlvbnMucHVzaChcbiAgICAgICAgICAgICAgICBtZW1vQ29ubmVjdGlvbihcbiAgICAgICAgICAgICAgICAgIENvbm5lY3RUeXBlLkVYVEVOU0lPTixcbiAgICAgICAgICAgICAgICAgIHhwbGFFeHRlbnNpb24ubmFtZSxcbiAgICAgICAgICAgICAgICAgIHhwbGFFeHRlbnNpb24uaWNvbixcbiAgICAgICAgICAgICAgICAgIHhwbGFFeHRlbnNpb24uaWRlbnRpZmllcixcbiAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25uZWN0aW9ucy5wdXNoKENPTk5FQ1RJT05TW2Nvbm5lY3RUeXBlXSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHNvcnRDb25uZWN0aW9ucyhjb25uZWN0aW9ucyk7XG4gICAgICB9KSxcbiAgICApO1xuICB9O1xuXG4gIC8qKlxuICAgKiBhdmFpbGFibGUgaW5zdGFsbCB0eXBlcyBvbiB0aGUgYnJvd3NlclxuICAgKlxuICAgKiBpbiB0aGlzIHRpbWUsIHRoaXMgb25seSBjb250YWlucyBbQ29ubmVjdFR5cGUuRVhURU5TSU9OXVxuICAgKlxuICAgKiBAc2VlIFdhbGxldCNhdmFpbGFibGVJbnN0YWxsVHlwZXNcbiAgICovXG4gIGF2YWlsYWJsZUluc3RhbGxUeXBlcyA9ICgpOiBPYnNlcnZhYmxlPENvbm5lY3RUeXBlW10+ID0+IHtcbiAgICByZXR1cm4gdGhpcy5fYXZhaWxhYmxlSW5zdGFsbFR5cGVzLmFzT2JzZXJ2YWJsZSgpO1xuICB9O1xuXG4gIC8qKlxuICAgKiBhdmFpbGFibGUgaW5zdGFsbGF0aW9ucyBpbmNsdWRlcyBpZGVudGlmaWVyLCBuYW1lLCBpY29uLCB1cmxcbiAgICpcbiAgICogQHNlZSBXYWxsZXQjYXZhaWxhYmxlSW5zdGFsbGF0aW9uc1xuICAgKi9cbiAgYXZhaWxhYmxlSW5zdGFsbGF0aW9ucyA9ICgpOiBPYnNlcnZhYmxlPEluc3RhbGxhdGlvbltdPiA9PiB7XG4gICAgcmV0dXJuIGNvbWJpbmVMYXRlc3QoW3RoaXMuYXZhaWxhYmxlQ29ubmVjdGlvbnMoKSwgZ2V0RXh0ZW5zaW9ucygpXSkucGlwZShcbiAgICAgIG1hcCgoW2Nvbm5lY3Rpb25zLCBleHRlbnNpb25zXSkgPT4ge1xuICAgICAgICBjb25zdCBpbnN0YWxsZWRJZGVudGlmaWVycyA9IG5ldyBTZXQ8c3RyaW5nPihcbiAgICAgICAgICBjb25uZWN0aW9uc1xuICAgICAgICAgICAgLmZpbHRlcigoeyB0eXBlLCBpZGVudGlmaWVyIH0pID0+IHtcbiAgICAgICAgICAgICAgcmV0dXJuIHR5cGUgPT09IENvbm5lY3RUeXBlLkVYVEVOU0lPTiAmJiAhIWlkZW50aWZpZXI7XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLm1hcCgoeyBpZGVudGlmaWVyIH0pID0+IHtcbiAgICAgICAgICAgICAgcmV0dXJuIGlkZW50aWZpZXIhO1xuICAgICAgICAgICAgfSksXG4gICAgICAgICk7XG5cbiAgICAgICAgcmV0dXJuIGV4dGVuc2lvbnNcbiAgICAgICAgICAuZmlsdGVyKCh7IGlkZW50aWZpZXIgfSkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuICFpbnN0YWxsZWRJZGVudGlmaWVycy5oYXMoaWRlbnRpZmllcik7XG4gICAgICAgICAgfSlcbiAgICAgICAgICAubWFwKCh7IG5hbWUsIGlkZW50aWZpZXIsIGljb24sIHVybCB9KSA9PiB7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICB0eXBlOiBDb25uZWN0VHlwZS5FWFRFTlNJT04sXG4gICAgICAgICAgICAgIGlkZW50aWZpZXIsXG4gICAgICAgICAgICAgIG5hbWUsXG4gICAgICAgICAgICAgIGljb24sXG4gICAgICAgICAgICAgIHVybCxcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgfSk7XG4gICAgICB9KSxcbiAgICApO1xuICB9O1xuXG4gIC8qKlxuICAgKiBAc2VlIFdhbGxldCNzdGF0dXNcbiAgICogQHNlZSBXYWxsZXQjbmV0d29ya1xuICAgKiBAc2VlIFdhbGxldCN3YWxsZXRzXG4gICAqL1xuICBzdGF0ZXMgPSAoKTogT2JzZXJ2YWJsZTxXYWxsZXRTdGF0ZXM+ID0+IHtcbiAgICByZXR1cm4gdGhpcy5fc3RhdGVzLmFzT2JzZXJ2YWJsZSgpO1xuICB9O1xuXG4gIC8qKiBnZXQgY29ubmVjdGVkV2FsbGV0ICovXG4gIGNvbm5lY3RlZFdhbGxldCA9ICgpOiBPYnNlcnZhYmxlPENvbm5lY3RlZFdhbGxldCB8IHVuZGVmaW5lZD4gPT4ge1xuICAgIHJldHVybiB0aGlzLl9zdGF0ZXMucGlwZSh0b0Nvbm5lY3RlZFdhbGxldCh0aGlzKSk7XG4gIH07XG5cbiAgLyoqIGdldCBsY2RDbGllbnQgKi9cbiAgbGNkQ2xpZW50ID0gKFxuICAgIGxjZENsaWVudENvbmZpZz86IFdhbGxldExDRENsaWVudENvbmZpZyxcbiAgKTogT2JzZXJ2YWJsZTxMQ0RDbGllbnQ+ID0+IHtcbiAgICByZXR1cm4gdGhpcy5fc3RhdGVzLnBpcGUodG9MY2RDbGllbnQobGNkQ2xpZW50Q29uZmlnKSk7XG4gIH07XG5cbiAgLyoqXG4gICAqIHJlbG9hZCB0aGUgY29ubmVjdGVkIHdhbGxldCBzdGF0ZXNcbiAgICpcbiAgICogaW4gdGhpcyB0aW1lLCB0aGlzIG9ubHkgd29yayBvbiB0aGUgQ29ubmVjdFR5cGUuRVhURU5TSU9OXG4gICAqXG4gICAqIEBzZWUgV2FsbGV0I3JlY2hlY2tTdGF0dXNcbiAgICovXG4gIHJlZmV0Y2hTdGF0ZXMgPSAoKSA9PiB7XG4gICAgaWYgKHRoaXMuZGlzYWJsZUV4dGVuc2lvbikge1xuICAgICAgdGhpcy5leHRlbnNpb24/LnJlZmV0Y2hTdGF0ZXMoKTtcbiAgICB9XG4gIH07XG5cbiAgLyoqXG4gICAqIEBkZXByZWNhdGVkIFBsZWFzZSB1c2UgYXZhaWxhYmxlSW5zdGFsbGF0aW9uc1xuICAgKlxuICAgKiBpbnN0YWxsIGZvciB0aGUgY29ubmVjdCB0eXBlXG4gICAqXG4gICAqIEBzZWUgV2FsbGV0I2luc3RhbGxcbiAgICovXG4gIGluc3RhbGwgPSAodHlwZTogQ29ubmVjdFR5cGUpID0+IHtcbiAgICBpZiAodHlwZSA9PT0gQ29ubmVjdFR5cGUuRVhURU5TSU9OKSB7XG4gICAgICAvLyBUT0RPIHNlcGFyYXRlIGluc3RhbGwgbGlua3MgYnkgYnJvd3NlciB0eXBlc1xuICAgICAgd2luZG93Lm9wZW4oQ0hST01FX0VYVEVOU0lPTl9JTlNUQUxMX1VSTCwgJ19ibGFuaycpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zb2xlLndhcm4oXG4gICAgICAgIGBbV2FsbGV0Q29udHJvbGxlcl0gQ29ubmVjdFR5cGUgXCIke3R5cGV9XCIgZG9lcyBub3Qgc3VwcG9ydCBpbnN0YWxsKCkgZnVuY3Rpb25gLFxuICAgICAgKTtcbiAgICB9XG4gIH07XG5cbiAgLyoqXG4gICAqIGNvbm5lY3QgdG8gd2FsbGV0XG4gICAqXG4gICAqIEBzZWUgV2FsbGV0I2Nvbm5lY3RcbiAgICovXG4gIGNvbm5lY3QgPSBhc3luYyAoX3R5cGU/OiBDb25uZWN0VHlwZSwgX2lkZW50aWZpZXI/OiBzdHJpbmcsIF93YWxsZXRBcHA/OiBXYWxsZXRBcHAgfCBib29sZWFuKSA9PiB7XG4gICAgbGV0IHR5cGU6IENvbm5lY3RUeXBlO1xuICAgIGxldCBpZGVudGlmaWVyOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG5cbiAgICBpZiAoISFfdHlwZSkge1xuICAgICAgdHlwZSA9IF90eXBlO1xuICAgICAgaWRlbnRpZmllciA9IF9pZGVudGlmaWVyO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBjb25uZWN0aW9ucyA9IGF3YWl0IGZpcnN0VmFsdWVGcm9tKHRoaXMuYXZhaWxhYmxlQ29ubmVjdGlvbnMoKSk7XG4gICAgICBjb25zdCBzZWxlY3RvciA9IHRoaXMub3B0aW9ucy5zZWxlY3RDb25uZWN0aW9uID8/IHNlbGVjdENvbm5lY3Rpb247XG4gICAgICBjb25zdCBzZWxlY3RlZCA9IGF3YWl0IHNlbGVjdG9yKGNvbm5lY3Rpb25zKTtcblxuICAgICAgaWYgKCFzZWxlY3RlZCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHR5cGUgPSBzZWxlY3RlZFswXTtcbiAgICAgIGlkZW50aWZpZXIgPSBzZWxlY3RlZFsxXTtcbiAgICB9XG5cbiAgICBzd2l0Y2ggKHR5cGUpIHtcbiAgICAgIGNhc2UgQ29ubmVjdFR5cGUuUkVBRE9OTFk6XG4gICAgICAgIGNvbnN0IG5ldHdvcmtzOiBOZXR3b3JrSW5mb1tdID0gT2JqZWN0LmtleXMoXG4gICAgICAgICAgdGhpcy5vcHRpb25zLndhbGxldENvbm5lY3RDaGFpbklkcyxcbiAgICAgICAgKS5tYXAoKGNoYWluSWQpID0+IHRoaXMub3B0aW9ucy53YWxsZXRDb25uZWN0Q2hhaW5JZHNbK2NoYWluSWRdKTtcblxuICAgICAgICBjb25zdCBjcmVhdGVSZWFkb25seVdhbGxldFNlc3Npb24gPVxuICAgICAgICAgIHRoaXMub3B0aW9ucy5jcmVhdGVSZWFkb25seVdhbGxldFNlc3Npb24/LihuZXR3b3JrcykgPz9cbiAgICAgICAgICByZWFkb25seVdhbGxldE1vZGFsKHsgbmV0d29ya3MgfSk7XG5cbiAgICAgICAgY29uc3QgcmVhZG9ubHlXYWxsZXRTZXNzaW9uID0gYXdhaXQgY3JlYXRlUmVhZG9ubHlXYWxsZXRTZXNzaW9uO1xuXG4gICAgICAgIGlmIChyZWFkb25seVdhbGxldFNlc3Npb24pIHtcbiAgICAgICAgICB0aGlzLmVuYWJsZVJlYWRvbmx5V2FsbGV0KHJlQ29ubmVjdChyZWFkb25seVdhbGxldFNlc3Npb24pKTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgQ29ubmVjdFR5cGUuV0FMTEVUQ09OTkVDVDpcbiAgICAgICAgdGhpcy5lbmFibGVXYWxsZXRDb25uZWN0KHdjQ29ubmVjdCh0aGlzLm9wdGlvbnMsIGZhbHNlLCBfd2FsbGV0QXBwKSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBDb25uZWN0VHlwZS5FWFRFTlNJT046XG4gICAgICAgIGlmICghdGhpcy5leHRlbnNpb24pIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYGV4dGVuc2lvbiBpbnN0YW5jZSBpcyBub3QgY3JlYXRlZCFgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuZXh0ZW5zaW9uLmNvbm5lY3QoaWRlbnRpZmllcik7XG4gICAgICAgIHRoaXMuZW5hYmxlRXh0ZW5zaW9uKCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmtub3duIENvbm5lY3RUeXBlIWApO1xuICAgIH1cbiAgfTtcblxuICAvKipcbiAgICogbWFudWFsIGNvbm5lY3QgdG8gcmVhZCBvbmx5IHNlc3Npb25cbiAgICpcbiAgICogQHNlZSBXYWxsZXQjY29ubmVjdFJlYWRvbmx5XG4gICAqL1xuICBjb25uZWN0UmVhZG9ubHkgPSAoeHBsYUFkZHJlc3M6IHN0cmluZywgbmV0d29yazogTmV0d29ya0luZm8pID0+IHtcbiAgICB0aGlzLmVuYWJsZVJlYWRvbmx5V2FsbGV0KFxuICAgICAgcmVDb25uZWN0KHtcbiAgICAgICAgeHBsYUFkZHJlc3MsXG4gICAgICAgIG5ldHdvcmssXG4gICAgICB9KSxcbiAgICApO1xuICB9O1xuXG4gIC8qKiBAc2VlIFdhbGxldCNkaXNjb25uZWN0ICovXG4gIGRpc2Nvbm5lY3QgPSAoKSA9PiB7XG4gICAgdGhpcy5kaXNhYmxlUmVhZG9ubHlXYWxsZXQ/LigpO1xuICAgIHRoaXMuZGlzYWJsZVJlYWRvbmx5V2FsbGV0ID0gbnVsbDtcblxuICAgIHRoaXMuZGlzYWJsZUV4dGVuc2lvbj8uKCk7XG4gICAgdGhpcy5kaXNhYmxlRXh0ZW5zaW9uID0gbnVsbDtcblxuICAgIHRoaXMuZGlzYWJsZVdhbGxldENvbm5lY3Q/LigpO1xuICAgIHRoaXMuZGlzYWJsZVdhbGxldENvbm5lY3QgPSBudWxsO1xuXG4gICAgdGhpcy51cGRhdGVTdGF0ZXModGhpcy5fbm90Q29ubmVjdGVkKTtcbiAgfTtcblxuICAvKipcbiAgICogQHNlZSBXYWxsZXQjcG9zdFxuICAgKiBAcGFyYW0gdHhcbiAgICogQHBhcmFtIHhwbGFBZGRyZXNzIG9ubHkgYXZhaWxhYmxlIG5ldyBleHRlbnNpb25cbiAgICovXG4gIHBvc3QgPSBhc3luYyAoXG4gICAgdHg6IENyZWF0ZVR4T3B0aW9ucyxcbiAgICB4cGxhQWRkcmVzcz86IHN0cmluZyxcbiAgICB3YWxsZXRBcHA/OiBXYWxsZXRBcHAgfCBib29sZWFuLFxuICApOiBQcm9taXNlPFR4UmVzdWx0PiA9PiB7XG4gICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLy8gZXh0ZW5zaW9uXG4gICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgaWYgKHRoaXMuZGlzYWJsZUV4dGVuc2lvbikge1xuICAgICAgcmV0dXJuIG5ldyBQcm9taXNlPFR4UmVzdWx0PigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgIGlmICghdGhpcy5leHRlbnNpb24pIHtcbiAgICAgICAgICByZWplY3QobmV3IEVycm9yKGBleHRlbnNpb24gaW5zdGFuY2Ugbm90IGNyZWF0ZWQhYCkpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHN1YnNjcmlwdGlvbiA9IHRoaXMuZXh0ZW5zaW9uLnBvc3QodHgsIHhwbGFBZGRyZXNzKS5zdWJzY3JpYmUoe1xuICAgICAgICAgIG5leHQ6ICh0eFJlc3VsdCkgPT4ge1xuICAgICAgICAgICAgaWYgKHR4UmVzdWx0LnN0YXR1cyA9PT0gV2ViRXh0ZW5zaW9uVHhTdGF0dXMuU1VDQ0VFRCkge1xuICAgICAgICAgICAgICByZXNvbHZlKHtcbiAgICAgICAgICAgICAgICAuLi50eCxcbiAgICAgICAgICAgICAgICByZXN1bHQ6IHR4UmVzdWx0LnBheWxvYWQsXG4gICAgICAgICAgICAgICAgc3VjY2VzczogdHJ1ZSxcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgIHN1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0sXG4gICAgICAgICAgZXJyb3I6IChlcnJvcikgPT4ge1xuICAgICAgICAgICAgcmVqZWN0KG1hcEV4dGVuc2lvblR4RXJyb3IodHgsIGVycm9yKSk7XG4gICAgICAgICAgICBzdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcbiAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH1cbiAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvLyB3YWxsZXQgY29ubmVjdFxuICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIGVsc2UgaWYgKHRoaXMud2FsbGV0Q29ubmVjdCkge1xuICAgICAgcmV0dXJuIHRoaXMud2FsbGV0Q29ubmVjdFxuICAgICAgICAucG9zdCh0eCwgd2FsbGV0QXBwKVxuICAgICAgICAudGhlbihcbiAgICAgICAgICAocmVzdWx0KSA9PlxuICAgICAgICAgICAgKHtcbiAgICAgICAgICAgICAgLi4udHgsXG4gICAgICAgICAgICAgIHJlc3VsdCxcbiAgICAgICAgICAgICAgc3VjY2VzczogdHJ1ZSxcbiAgICAgICAgICAgIH0gYXMgVHhSZXN1bHQpLFxuICAgICAgICApXG4gICAgICAgIC5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICAgICAgICB0aHJvdyBtYXBXYWxsZXRDb25uZWN0RXJyb3IodHgsIGVycm9yKTtcbiAgICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgVGhlcmUgYXJlIG5vIGNvbm5lY3Rpb25zIHRoYXQgY2FuIGJlIHBvc3RpbmcgdHghYCk7XG4gICAgfVxuICB9O1xuXG4gIC8qKlxuICAgKiBAc2VlIFdhbGxldCNzaWduXG4gICAqIEBwYXJhbSB0eFxuICAgKiBAcGFyYW0geHBsYUFkZHJlc3Mgb25seSBhdmFpbGFibGUgbmV3IGV4dGVuc2lvblxuICAgKi9cbiAgc2lnbiA9IGFzeW5jIChcbiAgICB0eDogQ3JlYXRlVHhPcHRpb25zICYge1xuICAgICAgc2VxdWVuY2U/OiBudW1iZXI7XG4gICAgICBhY2NvdW50TnVtYmVyPzogbnVtYmVyO1xuICAgICAgc2lnbk1vZGU/OiBTaWduTW9kZTtcbiAgICB9LFxuICAgIHhwbGFBZGRyZXNzPzogc3RyaW5nLFxuICAgIHdhbGxldEFwcD86IFdhbGxldEFwcCB8IGJvb2xlYW4sXG4gICk6IFByb21pc2U8U2lnblJlc3VsdD4gPT4ge1xuICAgIGlmICh0aGlzLmRpc2FibGVFeHRlbnNpb24pIHtcbiAgICAgIHJldHVybiBuZXcgUHJvbWlzZTxTaWduUmVzdWx0PigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgIGlmICghdGhpcy5leHRlbnNpb24pIHtcbiAgICAgICAgICByZWplY3QobmV3IEVycm9yKGBleHRlbnNpb24gaW5zdGFuY2UgaXMgbm90IGNyZWF0ZWQhYCkpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHN1YnNjcmlwdGlvbiA9IHRoaXMuZXh0ZW5zaW9uLnNpZ24odHgsIHhwbGFBZGRyZXNzKS5zdWJzY3JpYmUoe1xuICAgICAgICAgIG5leHQ6ICh0eFJlc3VsdCkgPT4ge1xuICAgICAgICAgICAgaWYgKHR4UmVzdWx0LnN0YXR1cyA9PT0gV2ViRXh0ZW5zaW9uVHhTdGF0dXMuU1VDQ0VFRCkge1xuICAgICAgICAgICAgICByZXNvbHZlKHtcbiAgICAgICAgICAgICAgICAuLi50eCxcbiAgICAgICAgICAgICAgICByZXN1bHQ6IFR4LmZyb21EYXRhKHR4UmVzdWx0LnBheWxvYWQpLFxuICAgICAgICAgICAgICAgIHN1Y2Nlc3M6IHRydWUsXG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICBzdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9LFxuICAgICAgICAgIGVycm9yOiAoZXJyb3IpID0+IHtcbiAgICAgICAgICAgIHJlamVjdChtYXBFeHRlbnNpb25UeEVycm9yKHR4LCBlcnJvcikpO1xuICAgICAgICAgICAgc3Vic2NyaXB0aW9uLnVuc3Vic2NyaWJlKCk7XG4gICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9XG4gICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLy8gd2FsbGV0IGNvbm5lY3RcbiAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICBlbHNlIGlmICh0aGlzLndhbGxldENvbm5lY3QpIHtcbiAgICAgIGlmICh3YWxsZXRBcHAgJiYgd2FsbGV0QXBwID09PSBXYWxsZXRBcHAuWFBMQV9HQU1FUykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFRoZXJlIGFyZSBubyBjb25uZWN0aW9ucyB0aGF0IGNhbiBiZSBzaWduaW5nIWApO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gdGhpcy53YWxsZXRDb25uZWN0XG4gICAgICAgIC5zaWduKHR4LCB3YWxsZXRBcHApXG4gICAgICAgIC50aGVuKFxuICAgICAgICAgIChyZXN1bHQpID0+IHtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgLi4udHgsXG4gICAgICAgICAgICAgICAgcmVzdWx0OiBUeC5mcm9tRGF0YShyZXN1bHQsIGZhbHNlKSxcbiAgICAgICAgICAgICAgICBzdWNjZXNzOiB0cnVlLFxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgKVxuICAgICAgICAuY2F0Y2goKGVycm9yKSA9PiB7XG4gICAgICAgICAgdGhyb3cgbWFwV2FsbGV0Q29ubmVjdFNpZ25FcnJvcih0eCwgZXJyb3IpO1xuICAgICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBUaGVyZSBhcmUgbm8gY29ubmVjdGlvbnMgdGhhdCBjYW4gYmUgc2lnbmluZyFgKTtcbiAgICB9XG4gIH07XG5cbiAgLyoqXG4gICAqIEBzZWUgV2FsbGV0I3NpZ25CeXRlc1xuICAgKiBAcGFyYW0gYnl0ZXNcbiAgICogQHBhcmFtIHhwbGFBZGRyZXNzIG9ubHkgYXZhaWxhYmxlIG5ldyBleHRlbnNpb25cbiAgICovXG4gIHNpZ25CeXRlcyA9IGFzeW5jIChcbiAgICBieXRlczogQnVmZmVyLFxuICAgIHhwbGFBZGRyZXNzPzogc3RyaW5nLFxuICAgIHdhbGxldEFwcD86IFdhbGxldEFwcCB8IGJvb2xlYW4sXG4gICk6IFByb21pc2U8U2lnbkJ5dGVzUmVzdWx0PiA9PiB7XG4gICAgaWYgKHRoaXMuZGlzYWJsZUV4dGVuc2lvbikge1xuICAgICAgcmV0dXJuIG5ldyBQcm9taXNlPFNpZ25CeXRlc1Jlc3VsdD4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICBpZiAoIXRoaXMuZXh0ZW5zaW9uKSB7XG4gICAgICAgICAgcmVqZWN0KG5ldyBFcnJvcihgZXh0ZW5zaW9uIGluc3RhbmNlIGlzIG5vdCBjcmVhdGVkIWApKTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBzdWJzY3JpcHRpb24gPSB0aGlzLmV4dGVuc2lvblxuICAgICAgICAgIC5zaWduQnl0ZXMoYnl0ZXMsIHhwbGFBZGRyZXNzKVxuICAgICAgICAgIC5zdWJzY3JpYmUoe1xuICAgICAgICAgICAgbmV4dDogKHR4UmVzdWx0KSA9PiB7XG4gICAgICAgICAgICAgIGlmICh0eFJlc3VsdC5zdGF0dXMgPT09IFdlYkV4dGVuc2lvblR4U3RhdHVzLlNVQ0NFRUQpIHtcbiAgICAgICAgICAgICAgICByZXNvbHZlKHtcbiAgICAgICAgICAgICAgICAgIHJlc3VsdDoge1xuICAgICAgICAgICAgICAgICAgICByZWNpZDogdHhSZXN1bHQucGF5bG9hZC5yZWNpZCxcbiAgICAgICAgICAgICAgICAgICAgc2lnbmF0dXJlOiBVaW50OEFycmF5LmZyb20oXG4gICAgICAgICAgICAgICAgICAgICAgQnVmZmVyLmZyb20odHhSZXN1bHQucGF5bG9hZC5zaWduYXR1cmUsICdiYXNlNjQnKSxcbiAgICAgICAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICAgICAgICAgcHVibGljX2tleTogdHhSZXN1bHQucGF5bG9hZC5wdWJsaWNfa2V5XG4gICAgICAgICAgICAgICAgICAgICAgPyBQdWJsaWNLZXkuZnJvbURhdGEodHhSZXN1bHQucGF5bG9hZC5wdWJsaWNfa2V5KVxuICAgICAgICAgICAgICAgICAgICAgIDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgIHN1Y2Nlc3M6IHRydWUsXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgc3Vic2NyaXB0aW9uLnVuc3Vic2NyaWJlKCk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBlcnJvcjogKGVycm9yKSA9PiB7XG4gICAgICAgICAgICAgIHJlamVjdChtYXBFeHRlbnNpb25TaWduQnl0ZXNFcnJvcihieXRlcywgZXJyb3IpKTtcbiAgICAgICAgICAgICAgc3Vic2NyaXB0aW9uLnVuc3Vic2NyaWJlKCk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgfVxuICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8vIHdhbGxldCBjb25uZWN0XG4gICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgZWxzZSBpZiAodGhpcy53YWxsZXRDb25uZWN0KSB7XG4gICAgICBpZiAod2FsbGV0QXBwICYmIHdhbGxldEFwcCA9PT0gV2FsbGV0QXBwLlhQTEFfR0FNRVMpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBUaGVyZSBhcmUgbm8gY29ubmVjdGlvbnMgdGhhdCBjYW4gYmUgc2lnbmluZyBieXRlcyFgKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRoaXMud2FsbGV0Q29ubmVjdFxuICAgICAgICAuc2lnbkJ5dGVzKGJ5dGVzLCB3YWxsZXRBcHApXG4gICAgICAgIC50aGVuKFxuICAgICAgICAgIChyZXN1bHQpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGtleSA9IG5ldyBTaW1wbGVQdWJsaWNLZXkoU3RyaW5nKHJlc3VsdC5wdWJsaWNfa2V5KSkudG9EYXRhKClcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgIHJlc3VsdDoge1xuICAgICAgICAgICAgICAgIHJlY2lkOiByZXN1bHQucmVjaWQsXG4gICAgICAgICAgICAgICAgc2lnbmF0dXJlOiBVaW50OEFycmF5LmZyb20oXG4gICAgICAgICAgICAgICAgICBCdWZmZXIuZnJvbShyZXN1bHQuc2lnbmF0dXJlLCAnYmFzZTY0JyksXG4gICAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICAgICBwdWJsaWNfa2V5OiBrZXlcbiAgICAgICAgICAgICAgICAgID8gUHVibGljS2V5LmZyb21EYXRhKGtleSlcbiAgICAgICAgICAgICAgICAgIDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBzdWNjZXNzOiB0cnVlLFxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgKVxuICAgICAgICAuY2F0Y2goKGVycm9yKSA9PiB7XG4gICAgICAgICAgdGhyb3cgbWFwV2FsbGV0Q29ubmVjdFNpZ25CeXRlc0Vycm9yKGJ5dGVzLCBlcnJvcik7XG4gICAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFRoZXJlIGFyZSBubyBjb25uZWN0aW9ucyB0aGF0IGNhbiBiZSBzaWduaW5nIGJ5dGVzIWApO1xuICAgIH1cbiAgfTtcblxuICAvKipcbiAgICogQHNlZSBXYWxsZXQjaGFzQ1cyMFRva2Vuc1xuICAgKiBAcGFyYW0gY2hhaW5JRFxuICAgKiBAcGFyYW0gdG9rZW5BZGRycyBUb2tlbiBhZGRyZXNzZXNcbiAgICovXG4gIGhhc0NXMjBUb2tlbnMgPSBhc3luYyAoXG4gICAgY2hhaW5JRDogc3RyaW5nLFxuICAgIC4uLnRva2VuQWRkcnM6IHN0cmluZ1tdXG4gICk6IFByb21pc2U8eyBbdG9rZW5BZGRyOiBzdHJpbmddOiBib29sZWFuIH0+ID0+IHtcbiAgICBpZiAodGhpcy5hdmFpbGFibGVFeHRlbnNpb25GZWF0dXJlKCdjdzIwLXRva2VuJykpIHtcbiAgICAgIHJldHVybiB0aGlzLmV4dGVuc2lvbiEuaGFzQ1cyMFRva2VucyhjaGFpbklELCAuLi50b2tlbkFkZHJzKTtcbiAgICB9XG5cbiAgICB0aHJvdyBuZXcgRXJyb3IoYERvZXMgbm90IHN1cHBvcnQgaGFzQ1cyMFRva2VucygpIG9uIHRoaXMgY29ubmVjdGlvbmApO1xuICB9O1xuXG4gIC8qKlxuICAgKiBAc2VlIFdhbGxldCNhZGRDVzIwVG9rZW5zXG4gICAqIEBwYXJhbSBjaGFpbklEXG4gICAqIEBwYXJhbSB0b2tlbkFkZHJzIFRva2VuIGFkZHJlc3Nlc1xuICAgKi9cbiAgYWRkQ1cyMFRva2VucyA9IGFzeW5jIChcbiAgICBjaGFpbklEOiBzdHJpbmcsXG4gICAgLi4udG9rZW5BZGRyczogc3RyaW5nW11cbiAgKTogUHJvbWlzZTx7IFt0b2tlbkFkZHI6IHN0cmluZ106IGJvb2xlYW4gfT4gPT4ge1xuICAgIGlmICh0aGlzLmF2YWlsYWJsZUV4dGVuc2lvbkZlYXR1cmUoJ2N3MjAtdG9rZW4nKSkge1xuICAgICAgcmV0dXJuIHRoaXMuZXh0ZW5zaW9uIS5hZGRDVzIwVG9rZW5zKGNoYWluSUQsIC4uLnRva2VuQWRkcnMpO1xuICAgIH1cblxuICAgIHRocm93IG5ldyBFcnJvcihgRG9lcyBub3Qgc3VwcG9ydCBhZGRDVzIwVG9rZW5zKCkgb24gdGhpcyBjb25uZWN0aW9uYCk7XG4gIH07XG5cbiAgLyoqXG4gICAqIEBzZWUgV2FsbGV0I2hhc05ldHdvcmtcbiAgICogQHBhcmFtIG5ldHdvcmtcbiAgICovXG4gIGhhc05ldHdvcmsgPSAobmV0d29yazogT21pdDxOZXR3b3JrSW5mbywgJ25hbWUnPik6IFByb21pc2U8Ym9vbGVhbj4gPT4ge1xuICAgIGlmICh0aGlzLmF2YWlsYWJsZUV4dGVuc2lvbkZlYXR1cmUoJ25ldHdvcmsnKSkge1xuICAgICAgcmV0dXJuIHRoaXMuZXh0ZW5zaW9uIS5oYXNOZXR3b3JrKG5ldHdvcmspO1xuICAgIH1cblxuICAgIHRocm93IG5ldyBFcnJvcihgRG9lcyBub3Qgc3VwcG9ydCBoYXNOZXR3b3JrKCkgb24gdGhpcyBjb25uZWN0aW9uYCk7XG4gIH07XG5cbiAgLyoqXG4gICAqIEBzZWUgV2FsbGV0I2hhc05ldHdvcmtcbiAgICogQHBhcmFtIG5ldHdvcmtcbiAgICovXG4gIGFkZE5ldHdvcmsgPSAobmV0d29yazogTmV0d29ya0luZm8pOiBQcm9taXNlPGJvb2xlYW4+ID0+IHtcbiAgICBpZiAodGhpcy5hdmFpbGFibGVFeHRlbnNpb25GZWF0dXJlKCduZXR3b3JrJykpIHtcbiAgICAgIHJldHVybiB0aGlzLmV4dGVuc2lvbiEuYWRkTmV0d29yayhuZXR3b3JrKTtcbiAgICB9XG5cbiAgICB0aHJvdyBuZXcgRXJyb3IoYERvZXMgbm90IHN1cHBvcnQgYWRkTmV0d29yaygpIG9uIHRoaXMgY29ubmVjdGlvbmApO1xuICB9O1xuXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgLy8gaW50ZXJuYWxcbiAgLy8gY29ubmVjdCB0eXBlIGNoYW5naW5nXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgcHJpdmF0ZSBhdmFpbGFibGVFeHRlbnNpb25GZWF0dXJlID0gKGZlYXR1cmU6IFhwbGFXZWJFeHRlbnNpb25GZWF0dXJlcykgPT4ge1xuICAgIGlmICh0aGlzLmRpc2FibGVFeHRlbnNpb24gJiYgdGhpcy5leHRlbnNpb24pIHtcbiAgICAgIGNvbnN0IHN0YXRlcyA9IHRoaXMuZXh0ZW5zaW9uLmdldExhc3RTdGF0ZXMoKTtcblxuICAgICAgcmV0dXJuIChcbiAgICAgICAgc3RhdGVzLnR5cGUgPT09IEV4dGVuc2lvblJvdXRlclN0YXR1cy5XQUxMRVRfQ09OTkVDVEVEICYmXG4gICAgICAgIHN0YXRlcy5zdXBwb3J0RmVhdHVyZXMuaGFzKGZlYXR1cmUpXG4gICAgICApO1xuICAgIH1cbiAgfTtcblxuICBwcml2YXRlIHVwZGF0ZVN0YXRlcyA9IChuZXh0OiBXYWxsZXRTdGF0ZXMpID0+IHtcbiAgICBjb25zdCBwcmV2ID0gdGhpcy5fc3RhdGVzLmdldFZhbHVlKCk7XG5cbiAgICBpZiAoXG4gICAgICBuZXh0LnN0YXR1cyA9PT0gV2FsbGV0U3RhdHVzLldBTExFVF9DT05ORUNURUQgJiZcbiAgICAgIG5leHQud2FsbGV0cy5sZW5ndGggPT09IDBcbiAgICApIHtcbiAgICAgIG5leHQgPSB7XG4gICAgICAgIHN0YXR1czogV2FsbGV0U3RhdHVzLldBTExFVF9OT1RfQ09OTkVDVEVELFxuICAgICAgICBuZXR3b3JrOiBuZXh0Lm5ldHdvcmssXG4gICAgICB9O1xuICAgIH1cblxuICAgIGlmIChwcmV2LnN0YXR1cyAhPT0gbmV4dC5zdGF0dXMgfHwgIWRlZXBFcXVhbChwcmV2LCBuZXh0KSkge1xuICAgICAgdGhpcy5fc3RhdGVzLm5leHQobmV4dCk7XG4gICAgfVxuICB9O1xuXG4gIHByaXZhdGUgZW5hYmxlUmVhZG9ubHlXYWxsZXQgPSAocmVhZG9ubHlXYWxsZXQ6IFJlYWRvbmx5V2FsbGV0Q29udHJvbGxlcikgPT4ge1xuICAgIHRoaXMuZGlzYWJsZVdhbGxldENvbm5lY3Q/LigpO1xuICAgIHRoaXMuZGlzYWJsZUV4dGVuc2lvbj8uKCk7XG5cbiAgICBpZiAoXG4gICAgICB0aGlzLnJlYWRvbmx5V2FsbGV0ID09PSByZWFkb25seVdhbGxldCB8fFxuICAgICAgKHRoaXMucmVhZG9ubHlXYWxsZXQ/LnhwbGFBZGRyZXNzID09PSByZWFkb25seVdhbGxldC54cGxhQWRkcmVzcyAmJlxuICAgICAgICB0aGlzLnJlYWRvbmx5V2FsbGV0Lm5ldHdvcmsgPT09IHJlYWRvbmx5V2FsbGV0Lm5ldHdvcmspXG4gICAgKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKHRoaXMucmVhZG9ubHlXYWxsZXQpIHtcbiAgICAgIHRoaXMucmVhZG9ubHlXYWxsZXQuZGlzY29ubmVjdCgpO1xuICAgIH1cblxuICAgIHRoaXMucmVhZG9ubHlXYWxsZXQgPSByZWFkb25seVdhbGxldDtcblxuICAgIHRoaXMudXBkYXRlU3RhdGVzKHtcbiAgICAgIHN0YXR1czogV2FsbGV0U3RhdHVzLldBTExFVF9DT05ORUNURUQsXG4gICAgICBuZXR3b3JrOiByZWFkb25seVdhbGxldC5uZXR3b3JrLFxuICAgICAgd2FsbGV0czogW1xuICAgICAgICB7XG4gICAgICAgICAgY29ubmVjdFR5cGU6IENvbm5lY3RUeXBlLlJFQURPTkxZLFxuICAgICAgICAgIHhwbGFBZGRyZXNzOiByZWFkb25seVdhbGxldC54cGxhQWRkcmVzcyxcbiAgICAgICAgICBkZXNpZ246ICdyZWFkb25seScsXG4gICAgICAgIH0sXG4gICAgICBdLFxuICAgICAgc3VwcG9ydEZlYXR1cmVzOiBFTVBUWV9TVVBQT1JUX0ZFQVRVUkVTLFxuICAgICAgY29ubmVjdGlvbjogQ09OTkVDVElPTlMuUkVBRE9OTFksXG4gICAgfSk7XG5cbiAgICB0aGlzLmRpc2FibGVSZWFkb25seVdhbGxldCA9ICgpID0+IHtcbiAgICAgIHJlYWRvbmx5V2FsbGV0LmRpc2Nvbm5lY3QoKTtcbiAgICAgIHRoaXMucmVhZG9ubHlXYWxsZXQgPSBudWxsO1xuICAgICAgdGhpcy5kaXNhYmxlUmVhZG9ubHlXYWxsZXQgPSBudWxsO1xuICAgIH07XG4gIH07XG5cbiAgcHJpdmF0ZSBlbmFibGVFeHRlbnNpb24gPSAoKSA9PiB7XG4gICAgdGhpcy5kaXNhYmxlUmVhZG9ubHlXYWxsZXQ/LigpO1xuICAgIHRoaXMuZGlzYWJsZVdhbGxldENvbm5lY3Q/LigpO1xuXG4gICAgaWYgKHRoaXMuZGlzYWJsZUV4dGVuc2lvbiB8fCAhdGhpcy5leHRlbnNpb24pIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBleHRlbnNpb25TdWJzY3JpcHRpb24gPSB0aGlzLmV4dGVuc2lvbi5zdGF0ZXMoKS5zdWJzY3JpYmUoe1xuICAgICAgbmV4dDogKGV4dGVuc2lvblN0YXRlcykgPT4ge1xuICAgICAgICBpZiAoXG4gICAgICAgICAgZXh0ZW5zaW9uU3RhdGVzLnR5cGUgPT09IEV4dGVuc2lvblJvdXRlclN0YXR1cy5XQUxMRVRfQ09OTkVDVEVEICYmXG4gICAgICAgICAgQWNjQWRkcmVzcy52YWxpZGF0ZShleHRlbnNpb25TdGF0ZXMud2FsbGV0LnhwbGFBZGRyZXNzKVxuICAgICAgICApIHtcbiAgICAgICAgICB0aGlzLnVwZGF0ZVN0YXRlcyh7XG4gICAgICAgICAgICBzdGF0dXM6IFdhbGxldFN0YXR1cy5XQUxMRVRfQ09OTkVDVEVELFxuICAgICAgICAgICAgbmV0d29yazogZXh0ZW5zaW9uU3RhdGVzLm5ldHdvcmssXG4gICAgICAgICAgICB3YWxsZXRzOiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBjb25uZWN0VHlwZTogQ29ubmVjdFR5cGUuRVhURU5TSU9OLFxuICAgICAgICAgICAgICAgIHhwbGFBZGRyZXNzOiBleHRlbnNpb25TdGF0ZXMud2FsbGV0LnhwbGFBZGRyZXNzLFxuICAgICAgICAgICAgICAgIGRlc2lnbjogZXh0ZW5zaW9uU3RhdGVzLndhbGxldC5kZXNpZ24sXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgICAgc3VwcG9ydEZlYXR1cmVzOiBleHRlbnNpb25TdGF0ZXMuc3VwcG9ydEZlYXR1cmVzLFxuICAgICAgICAgICAgY29ubmVjdGlvbjogbWVtb0Nvbm5lY3Rpb24oXG4gICAgICAgICAgICAgIENvbm5lY3RUeXBlLkVYVEVOU0lPTixcbiAgICAgICAgICAgICAgZXh0ZW5zaW9uU3RhdGVzLmV4dGVuc2lvbkluZm8ubmFtZSxcbiAgICAgICAgICAgICAgZXh0ZW5zaW9uU3RhdGVzLmV4dGVuc2lvbkluZm8uaWNvbixcbiAgICAgICAgICAgICAgZXh0ZW5zaW9uU3RhdGVzLmV4dGVuc2lvbkluZm8uaWRlbnRpZmllcixcbiAgICAgICAgICAgICksXG4gICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhpcy51cGRhdGVTdGF0ZXModGhpcy5fbm90Q29ubmVjdGVkKTtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICB9KTtcblxuICAgIHRoaXMuZGlzYWJsZUV4dGVuc2lvbiA9ICgpID0+IHtcbiAgICAgIHRoaXMuZXh0ZW5zaW9uPy5kaXNjb25uZWN0KCk7XG4gICAgICBleHRlbnNpb25TdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcbiAgICAgIHRoaXMuZGlzYWJsZUV4dGVuc2lvbiA9IG51bGw7XG4gICAgfTtcbiAgfTtcblxuICBwcml2YXRlIGVuYWJsZVdhbGxldENvbm5lY3QgPSAod2FsbGV0Q29ubmVjdDogV2FsbGV0Q29ubmVjdENvbnRyb2xsZXIpID0+IHtcbiAgICB0aGlzLmRpc2FibGVSZWFkb25seVdhbGxldD8uKCk7XG4gICAgdGhpcy5kaXNhYmxlRXh0ZW5zaW9uPy4oKTtcblxuICAgIGlmICh0aGlzLndhbGxldENvbm5lY3QgPT09IHdhbGxldENvbm5lY3QpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAodGhpcy53YWxsZXRDb25uZWN0KSB7XG4gICAgICB0aGlzLndhbGxldENvbm5lY3QuZGlzY29ubmVjdCgpO1xuICAgIH1cblxuICAgIHRoaXMud2FsbGV0Q29ubmVjdCA9IHdhbGxldENvbm5lY3Q7XG5cbiAgICBjb25zdCBzdWJzY3JpYmVXYWxsZXRDb25uZWN0ID0gKFxuICAgICAgd2M6IFdhbGxldENvbm5lY3RDb250cm9sbGVyLFxuICAgICk6IFN1YnNjcmlwdGlvbiA9PiB7XG4gICAgICByZXR1cm4gd2Muc2Vzc2lvbigpLnN1YnNjcmliZSh7XG4gICAgICAgIG5leHQ6IChzdGF0dXMpID0+IHtcbiAgICAgICAgICBzd2l0Y2ggKHN0YXR1cy5zdGF0dXMpIHtcbiAgICAgICAgICAgIGNhc2UgV2FsbGV0Q29ubmVjdFNlc3Npb25TdGF0dXMuQ09OTkVDVEVEOlxuICAgICAgICAgICAgICB0aGlzLnVwZGF0ZVN0YXRlcyh7XG4gICAgICAgICAgICAgICAgc3RhdHVzOiBXYWxsZXRTdGF0dXMuV0FMTEVUX0NPTk5FQ1RFRCxcbiAgICAgICAgICAgICAgICBuZXR3b3JrOlxuICAgICAgICAgICAgICAgICAgdGhpcy5vcHRpb25zLndhbGxldENvbm5lY3RDaGFpbklkc1tzdGF0dXMuY2hhaW5JZF0gPz9cbiAgICAgICAgICAgICAgICAgIHRoaXMub3B0aW9ucy5kZWZhdWx0TmV0d29yayxcbiAgICAgICAgICAgICAgICB3YWxsZXRzOiBbXG4gICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbm5lY3RUeXBlOiBDb25uZWN0VHlwZS5XQUxMRVRDT05ORUNULFxuICAgICAgICAgICAgICAgICAgICB4cGxhQWRkcmVzczogc3RhdHVzLnhwbGFBZGRyZXNzLFxuICAgICAgICAgICAgICAgICAgICBkZXNpZ246ICd3YWxsZXRjb25uZWN0JyxcbiAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgXSxcbiAgICAgICAgICAgICAgICBzdXBwb3J0RmVhdHVyZXM6IFdBTExFVENPTk5FQ1RfU1VQUE9SVF9GRUFUVVJFUyxcbiAgICAgICAgICAgICAgICBjb25uZWN0aW9uOiBDT05ORUNUSU9OUy5XQUxMRVRDT05ORUNULFxuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICB0aGlzLnVwZGF0ZVN0YXRlcyh0aGlzLl9ub3RDb25uZWN0ZWQpO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICB9O1xuXG4gICAgY29uc3Qgd2FsbGV0Q29ubmVjdFNlc3Npb25TdWJzY3JpcHRpb24gPVxuICAgICAgc3Vic2NyaWJlV2FsbGV0Q29ubmVjdCh3YWxsZXRDb25uZWN0KTtcblxuICAgIHRoaXMuZGlzYWJsZVdhbGxldENvbm5lY3QgPSAoKSA9PiB7XG4gICAgICB0aGlzLndhbGxldENvbm5lY3Q/LmRpc2Nvbm5lY3QoKTtcbiAgICAgIHRoaXMud2FsbGV0Q29ubmVjdCA9IG51bGw7XG4gICAgICB3YWxsZXRDb25uZWN0U2Vzc2lvblN1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpO1xuICAgICAgdGhpcy5kaXNhYmxlV2FsbGV0Q29ubmVjdCA9IG51bGw7XG4gICAgfTtcbiAgfTtcbn1cblxuY29uc3QgbWVtb2l6ZWRDb25uZWN0aW9ucyA9IG5ldyBNYXA8c3RyaW5nLCBDb25uZWN0aW9uPigpO1xuXG5mdW5jdGlvbiBtZW1vQ29ubmVjdGlvbihcbiAgY29ubmVjdFR5cGU6IENvbm5lY3RUeXBlLFxuICBuYW1lOiBzdHJpbmcsXG4gIGljb246IHN0cmluZyxcbiAgaWRlbnRpZmllcjogc3RyaW5nIHwgdW5kZWZpbmVkID0gJycsXG4pOiBDb25uZWN0aW9uIHtcbiAgY29uc3Qga2V5ID0gW2Nvbm5lY3RUeXBlLCBuYW1lLCBpY29uLCBpZGVudGlmaWVyXS5qb2luKCc7Jyk7XG5cbiAgaWYgKG1lbW9pemVkQ29ubmVjdGlvbnMuaGFzKGtleSkpIHtcbiAgICByZXR1cm4gbWVtb2l6ZWRDb25uZWN0aW9ucy5nZXQoa2V5KSE7XG4gIH1cblxuICBjb25zdCBjb25uZWN0aW9uOiBDb25uZWN0aW9uID0ge1xuICAgIHR5cGU6IGNvbm5lY3RUeXBlLFxuICAgIG5hbWUsXG4gICAgaWNvbixcbiAgICBpZGVudGlmaWVyLFxuICB9O1xuXG4gIG1lbW9pemVkQ29ubmVjdGlvbnMuc2V0KGtleSwgY29ubmVjdGlvbik7XG5cbiAgcmV0dXJuIGNvbm5lY3Rpb247XG59XG4iXX0=