@bitgo/sdk-coin-rune 1.3.3 → 1.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.mocharc.yml +1 -1
- package/CHANGELOG.md +10 -0
- package/LICENSE +191 -0
- package/dist/src/index.d.ts +5 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +21 -0
- package/dist/src/lib/constants.d.ts +12 -0
- package/dist/src/lib/constants.d.ts.map +1 -0
- package/dist/src/lib/constants.js +17 -0
- package/dist/src/lib/iface.d.ts +6 -0
- package/dist/src/lib/iface.d.ts.map +1 -0
- package/dist/src/lib/iface.js +3 -0
- package/dist/src/lib/index.d.ts +7 -0
- package/dist/src/lib/index.d.ts.map +1 -0
- package/dist/src/lib/index.js +48 -0
- package/dist/src/lib/keyPair.d.ts +11 -0
- package/dist/src/lib/keyPair.d.ts.map +1 -0
- package/dist/src/lib/keyPair.js +26 -0
- package/dist/src/lib/transactionBuilderFactory.d.ts +28 -0
- package/dist/src/lib/transactionBuilderFactory.d.ts.map +1 -0
- package/dist/src/lib/transactionBuilderFactory.js +74 -0
- package/dist/src/lib/transferBuilder.d.ts +11 -0
- package/dist/src/lib/transferBuilder.d.ts.map +1 -0
- package/dist/src/lib/transferBuilder.js +27 -0
- package/dist/src/lib/utils.d.ts +68 -0
- package/dist/src/lib/utils.d.ts.map +1 -0
- package/dist/src/lib/utils.js +221 -0
- package/dist/src/register.d.ts +3 -0
- package/dist/src/register.d.ts.map +1 -0
- package/dist/src/register.js +11 -0
- package/dist/src/rune.d.ts +40 -0
- package/dist/src/rune.d.ts.map +1 -0
- package/dist/src/rune.js +218 -0
- package/dist/src/trune.d.ts +20 -0
- package/dist/src/trune.d.ts.map +1 -0
- package/dist/src/trune.js +36 -0
- package/package.json +7 -7
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { Coin } from '@cosmjs/stargate';
|
|
2
|
+
import { CosmosLikeTransaction, CosmosUtils, FeeData } from '@bitgo/abstract-cosmos';
|
|
3
|
+
import { MessageData } from './iface';
|
|
4
|
+
import { NetworkType } from '@bitgo/statics';
|
|
5
|
+
import { DecodedTxRaw } from '@cosmjs/proto-signing';
|
|
6
|
+
export declare class RuneUtils extends CosmosUtils {
|
|
7
|
+
private networkType;
|
|
8
|
+
constructor(networkType?: NetworkType);
|
|
9
|
+
getSendMessageDataFromDecodedTx(decodedTx: DecodedTxRaw): MessageData[];
|
|
10
|
+
/** @inheritdoc */
|
|
11
|
+
isValidAddress(address: string | Uint8Array): boolean;
|
|
12
|
+
/**
|
|
13
|
+
* Validates a decoded address in `Uint8Array` form by encoding it and
|
|
14
|
+
* checking if the encoded version is valid
|
|
15
|
+
*
|
|
16
|
+
* @param address - The decoded address as a `Uint8Array`.
|
|
17
|
+
* @returns `true` if the encoded address is valid, `false` otherwise.
|
|
18
|
+
*/
|
|
19
|
+
private isValidDecodedAddress;
|
|
20
|
+
/**
|
|
21
|
+
* Validates an encoded address string against network-specific criteria.
|
|
22
|
+
*
|
|
23
|
+
* @param address - The encoded address as a `string`.
|
|
24
|
+
* @returns `true` if the address meets network-specific validation criteria, `false` otherwise.
|
|
25
|
+
*/
|
|
26
|
+
private isValidEncodedAddress;
|
|
27
|
+
/**
|
|
28
|
+
* Encodes a given address `Uint8Array` into a bech32 string format, based on the current network type.
|
|
29
|
+
* Primarily serves as a utility to convert a `Uint8Array`-type address to a bech32 encoded string
|
|
30
|
+
*
|
|
31
|
+
* @param address - The address to be encoded, provided as a `Uint8Array`.
|
|
32
|
+
* @returns A bech32-encoded string representing the address.
|
|
33
|
+
* @throws Error - Throws an error if encoding fails
|
|
34
|
+
*/
|
|
35
|
+
getEncodedAddress(address: Uint8Array): string;
|
|
36
|
+
/**
|
|
37
|
+
* Decodes a bech32-encoded address string back into a `Uint8Array`.
|
|
38
|
+
* Primarily serves as a utility to convert a string-type address into its binary representation,
|
|
39
|
+
*
|
|
40
|
+
* @param address - The bech32-encoded address as a `string`.
|
|
41
|
+
* @returns The decoded address as a `Uint8Array`.
|
|
42
|
+
* @throws Error - Throws an error if decoding fails
|
|
43
|
+
*/
|
|
44
|
+
getDecodedAddress(address: string): Uint8Array;
|
|
45
|
+
/** @inheritdoc */
|
|
46
|
+
isValidValidatorAddress(address: string): boolean;
|
|
47
|
+
/** @inheritdoc */
|
|
48
|
+
validateAmount(amount: Coin): void;
|
|
49
|
+
/**
|
|
50
|
+
* Validates the gas limit and gas amount for a transaction.
|
|
51
|
+
* @param {FeeData} gasBudget - The gas budget to validate.
|
|
52
|
+
* @throws {InvalidTransactionError} Throws an error if the gas budget is invalid.
|
|
53
|
+
*/
|
|
54
|
+
validateGasBudget(gasBudget: FeeData): void;
|
|
55
|
+
/**
|
|
56
|
+
* Validates an array of coin amounts.
|
|
57
|
+
* @param {Coin[]} amountArray - The array of coin amounts to validate.
|
|
58
|
+
*/
|
|
59
|
+
validateGasAmountData(amountArray: Coin[]): void;
|
|
60
|
+
validateGasAmount(amount: Coin): void;
|
|
61
|
+
validateDenomination(amountDenom: string): void;
|
|
62
|
+
convertMessageAddressToUint8Array(messages: MessageData[]): MessageData[];
|
|
63
|
+
createTransaction(sequence: number, messages: MessageData[], gasBudget: FeeData, publicKey?: string, memo?: string): CosmosLikeTransaction;
|
|
64
|
+
getNetworkPrefix(): "thor" | "sthor";
|
|
65
|
+
}
|
|
66
|
+
declare const runeUtils: RuneUtils;
|
|
67
|
+
export default runeUtils;
|
|
68
|
+
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/lib/utils.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAGxC,OAAO,EAAE,qBAAqB,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACrF,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAEtC,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAIrD,qBAAa,SAAU,SAAQ,WAAW;IACxC,OAAO,CAAC,WAAW,CAAc;gBACrB,WAAW,GAAE,WAAiC;IAK1D,+BAA+B,CAAC,SAAS,EAAE,YAAY,GAAG,WAAW,EAAE;IAcvE,kBAAkB;IAClB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU,GAAG,OAAO;IAarD;;;;;;OAMG;IACH,OAAO,CAAC,qBAAqB;IAK7B;;;;;OAKG;IACH,OAAO,CAAC,qBAAqB;IAO7B;;;;;;;OAOG;IACH,iBAAiB,CAAC,OAAO,EAAE,UAAU,GAAG,MAAM;IAU9C;;;;;;;OAOG;IACH,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU;IAQ9C,kBAAkB;IAClB,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAOjD,kBAAkB;IAClB,cAAc,CAAC,MAAM,EAAE,IAAI,GAAG,IAAI;IAQlC;;;;OAIG;IACH,iBAAiB,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI;IAO3C;;;OAGG;IACH,qBAAqB,CAAC,WAAW,EAAE,IAAI,EAAE,GAAG,IAAI;IAMhD,iBAAiB,CAAC,MAAM,EAAE,IAAI,GAAG,IAAI;IAQrC,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI;IAM/C,iCAAiC,CAAC,QAAQ,EAAE,WAAW,EAAE,GAAG,WAAW,EAAE;IA0BzE,iBAAiB,CACf,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,WAAW,EAAE,EACvB,SAAS,EAAE,OAAO,EAClB,SAAS,CAAC,EAAE,MAAM,EAClB,IAAI,CAAC,EAAE,MAAM,GACZ,qBAAqB;IAaxB,gBAAgB;CAGjB;AAED,QAAA,MAAM,SAAS,WAAkB,CAAC;AAElC,eAAe,SAAS,CAAC"}
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.RuneUtils = void 0;
|
|
40
|
+
const sdk_core_1 = require("@bitgo/sdk-core");
|
|
41
|
+
const bignumber_js_1 = __importDefault(require("bignumber.js"));
|
|
42
|
+
const abstract_cosmos_1 = require("@bitgo/abstract-cosmos");
|
|
43
|
+
const constants = __importStar(require("./constants"));
|
|
44
|
+
const statics_1 = require("@bitgo/statics");
|
|
45
|
+
const constants_1 = require("./constants");
|
|
46
|
+
const bech32 = require('bech32-buffer');
|
|
47
|
+
class RuneUtils extends abstract_cosmos_1.CosmosUtils {
|
|
48
|
+
constructor(networkType = statics_1.NetworkType.MAINNET) {
|
|
49
|
+
super();
|
|
50
|
+
this.networkType = networkType;
|
|
51
|
+
}
|
|
52
|
+
getSendMessageDataFromDecodedTx(decodedTx) {
|
|
53
|
+
return decodedTx.body.messages.map((message) => {
|
|
54
|
+
const value = this.registry.decode(message);
|
|
55
|
+
return {
|
|
56
|
+
value: {
|
|
57
|
+
fromAddress: this.getEncodedAddress(value.fromAddress),
|
|
58
|
+
toAddress: this.getEncodedAddress(value.toAddress),
|
|
59
|
+
amount: value.amount,
|
|
60
|
+
},
|
|
61
|
+
typeUrl: message.typeUrl,
|
|
62
|
+
};
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
/** @inheritdoc */
|
|
66
|
+
isValidAddress(address) {
|
|
67
|
+
if (address === undefined || address === null) {
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
if (address instanceof Uint8Array) {
|
|
71
|
+
return this.isValidDecodedAddress(address);
|
|
72
|
+
}
|
|
73
|
+
if (typeof address === 'string') {
|
|
74
|
+
return this.isValidEncodedAddress(address);
|
|
75
|
+
}
|
|
76
|
+
return false;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Validates a decoded address in `Uint8Array` form by encoding it and
|
|
80
|
+
* checking if the encoded version is valid
|
|
81
|
+
*
|
|
82
|
+
* @param address - The decoded address as a `Uint8Array`.
|
|
83
|
+
* @returns `true` if the encoded address is valid, `false` otherwise.
|
|
84
|
+
*/
|
|
85
|
+
isValidDecodedAddress(address) {
|
|
86
|
+
const encodedAddress = this.getEncodedAddress(address);
|
|
87
|
+
return this.isValidEncodedAddress(encodedAddress);
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Validates an encoded address string against network-specific criteria.
|
|
91
|
+
*
|
|
92
|
+
* @param address - The encoded address as a `string`.
|
|
93
|
+
* @returns `true` if the address meets network-specific validation criteria, `false` otherwise.
|
|
94
|
+
*/
|
|
95
|
+
isValidEncodedAddress(address) {
|
|
96
|
+
if (this.networkType === statics_1.NetworkType.TESTNET) {
|
|
97
|
+
return this.isValidCosmosLikeAddressWithMemoId(address, constants.testnetAccountAddressRegex);
|
|
98
|
+
}
|
|
99
|
+
return this.isValidCosmosLikeAddressWithMemoId(address, constants.mainnetAccountAddressRegex);
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Encodes a given address `Uint8Array` into a bech32 string format, based on the current network type.
|
|
103
|
+
* Primarily serves as a utility to convert a `Uint8Array`-type address to a bech32 encoded string
|
|
104
|
+
*
|
|
105
|
+
* @param address - The address to be encoded, provided as a `Uint8Array`.
|
|
106
|
+
* @returns A bech32-encoded string representing the address.
|
|
107
|
+
* @throws Error - Throws an error if encoding fails
|
|
108
|
+
*/
|
|
109
|
+
getEncodedAddress(address) {
|
|
110
|
+
try {
|
|
111
|
+
return this.networkType === statics_1.NetworkType.TESTNET
|
|
112
|
+
? bech32.encode(constants_1.TESTNET_ADDRESS_PREFIX, address)
|
|
113
|
+
: bech32.encode(constants_1.MAINNET_ADDRESS_PREFIX, address);
|
|
114
|
+
}
|
|
115
|
+
catch (error) {
|
|
116
|
+
throw new Error(`Failed to encode address: ${error instanceof Error ? error.message : String(error)}`);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Decodes a bech32-encoded address string back into a `Uint8Array`.
|
|
121
|
+
* Primarily serves as a utility to convert a string-type address into its binary representation,
|
|
122
|
+
*
|
|
123
|
+
* @param address - The bech32-encoded address as a `string`.
|
|
124
|
+
* @returns The decoded address as a `Uint8Array`.
|
|
125
|
+
* @throws Error - Throws an error if decoding fails
|
|
126
|
+
*/
|
|
127
|
+
getDecodedAddress(address) {
|
|
128
|
+
try {
|
|
129
|
+
return bech32.decode(address).data;
|
|
130
|
+
}
|
|
131
|
+
catch (error) {
|
|
132
|
+
throw new Error(`Failed to decode address: ${error instanceof Error ? error.message : String(error)}`);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
/** @inheritdoc */
|
|
136
|
+
isValidValidatorAddress(address) {
|
|
137
|
+
if (this.networkType === statics_1.NetworkType.TESTNET) {
|
|
138
|
+
return this.isValidBech32AddressMatchingRegex(address, constants.testnetValidatorAddressRegex);
|
|
139
|
+
}
|
|
140
|
+
return this.isValidBech32AddressMatchingRegex(address, constants.mainnetValidatorAddressRegex);
|
|
141
|
+
}
|
|
142
|
+
/** @inheritdoc */
|
|
143
|
+
validateAmount(amount) {
|
|
144
|
+
const amountBig = (0, bignumber_js_1.default)(amount.amount);
|
|
145
|
+
if (amountBig.isNaN() || amountBig.isLessThanOrEqualTo(0)) {
|
|
146
|
+
throw new sdk_core_1.InvalidTransactionError('transactionBuilder: validateAmount: Invalid amount: ' + amount.amount);
|
|
147
|
+
}
|
|
148
|
+
this.validateDenomination(amount.denom);
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Validates the gas limit and gas amount for a transaction.
|
|
152
|
+
* @param {FeeData} gasBudget - The gas budget to validate.
|
|
153
|
+
* @throws {InvalidTransactionError} Throws an error if the gas budget is invalid.
|
|
154
|
+
*/
|
|
155
|
+
validateGasBudget(gasBudget) {
|
|
156
|
+
if (gasBudget.gasLimit <= 0) {
|
|
157
|
+
throw new sdk_core_1.InvalidTransactionError('Invalid gas limit ' + gasBudget.gasLimit);
|
|
158
|
+
}
|
|
159
|
+
this.validateGasAmountData(gasBudget.amount);
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Validates an array of coin amounts.
|
|
163
|
+
* @param {Coin[]} amountArray - The array of coin amounts to validate.
|
|
164
|
+
*/
|
|
165
|
+
validateGasAmountData(amountArray) {
|
|
166
|
+
amountArray.forEach((coinAmount) => {
|
|
167
|
+
this.validateGasAmount(coinAmount);
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
validateGasAmount(amount) {
|
|
171
|
+
const amountBig = (0, bignumber_js_1.default)(amount.amount);
|
|
172
|
+
if (amountBig.isNaN() || amountBig.isLessThan(0)) {
|
|
173
|
+
throw new sdk_core_1.InvalidTransactionError('transactionBuilder: validateAmount: Invalid amount: ' + amount.amount);
|
|
174
|
+
}
|
|
175
|
+
this.validateDenomination(amount.denom);
|
|
176
|
+
}
|
|
177
|
+
validateDenomination(amountDenom) {
|
|
178
|
+
if (!constants.validDenoms.find((denom) => denom === amountDenom)) {
|
|
179
|
+
throw new sdk_core_1.InvalidTransactionError('transactionBuilder: validateAmount: Invalid denom: ' + amountDenom);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
convertMessageAddressToUint8Array(messages) {
|
|
183
|
+
return messages.map((message) => {
|
|
184
|
+
if ('fromAddress' in message.value && 'toAddress' in message.value) {
|
|
185
|
+
const sendMessage = message.value;
|
|
186
|
+
const decodedFrom = typeof sendMessage.fromAddress === 'string'
|
|
187
|
+
? bech32.decode(sendMessage.fromAddress).data
|
|
188
|
+
: sendMessage.fromAddress;
|
|
189
|
+
const decodedTo = typeof sendMessage.toAddress === 'string' ? bech32.decode(sendMessage.toAddress).data : sendMessage.toAddress;
|
|
190
|
+
return {
|
|
191
|
+
...message,
|
|
192
|
+
value: {
|
|
193
|
+
...sendMessage,
|
|
194
|
+
fromAddress: decodedFrom,
|
|
195
|
+
toAddress: decodedTo,
|
|
196
|
+
},
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
return message;
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
createTransaction(sequence, messages, gasBudget, publicKey, memo) {
|
|
203
|
+
messages = this.convertMessageAddressToUint8Array(messages);
|
|
204
|
+
const cosmosLikeTxn = {
|
|
205
|
+
sequence: sequence,
|
|
206
|
+
sendMessages: messages,
|
|
207
|
+
gasBudget: gasBudget,
|
|
208
|
+
publicKey: publicKey,
|
|
209
|
+
memo: memo,
|
|
210
|
+
};
|
|
211
|
+
this.validateTransaction(cosmosLikeTxn);
|
|
212
|
+
return cosmosLikeTxn;
|
|
213
|
+
}
|
|
214
|
+
getNetworkPrefix() {
|
|
215
|
+
return this.networkType === statics_1.NetworkType.TESTNET ? constants_1.TESTNET_ADDRESS_PREFIX : constants_1.MAINNET_ADDRESS_PREFIX;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
exports.RuneUtils = RuneUtils;
|
|
219
|
+
const runeUtils = new RuneUtils();
|
|
220
|
+
exports.default = runeUtils;
|
|
221
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvbGliL3V0aWxzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLDhDQUEwRDtBQUUxRCxnRUFBcUM7QUFFckMsNERBQXFGO0FBRXJGLHVEQUF5QztBQUN6Qyw0Q0FBNkM7QUFFN0MsMkNBQTZFO0FBQzdFLE1BQU0sTUFBTSxHQUFHLE9BQU8sQ0FBQyxlQUFlLENBQUMsQ0FBQztBQUV4QyxNQUFhLFNBQVUsU0FBUSw2QkFBVztJQUV4QyxZQUFZLGNBQTJCLHFCQUFXLENBQUMsT0FBTztRQUN4RCxLQUFLLEVBQUUsQ0FBQztRQUNSLElBQUksQ0FBQyxXQUFXLEdBQUcsV0FBVyxDQUFDO0lBQ2pDLENBQUM7SUFFRCwrQkFBK0IsQ0FBQyxTQUF1QjtRQUNyRCxPQUFPLFNBQVMsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDLE9BQU8sRUFBRSxFQUFFO1lBQzdDLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQzVDLE9BQU87Z0JBQ0wsS0FBSyxFQUFFO29CQUNMLFdBQVcsRUFBRSxJQUFJLENBQUMsaUJBQWlCLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQztvQkFDdEQsU0FBUyxFQUFFLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDO29CQUNsRCxNQUFNLEVBQUUsS0FBSyxDQUFDLE1BQU07aUJBQ3JCO2dCQUNELE9BQU8sRUFBRSxPQUFPLENBQUMsT0FBTzthQUN6QixDQUFDO1FBQ0osQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQsa0JBQWtCO0lBQ2xCLGNBQWMsQ0FBQyxPQUE0QjtRQUN6QyxJQUFJLE9BQU8sS0FBSyxTQUFTLElBQUksT0FBTyxLQUFLLElBQUksRUFBRSxD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USxDQUFDLENBQUM7UUFDNUQsTUFBTSxhQUFhLEdBQUc7WUFDcEIsUUFBUSxFQUFFLFFBQVE7WUFDbEIsWUFBWSxFQUFFLFFBQVE7WUFDdEIsU0FBUyxFQUFFLFNBQVM7WUFDcEIsU0FBUyxFQUFFLFNBQVM7WUFDcEIsSUFBSSxFQUFFLElBQUk7U0FDWCxDQUFDO1FBQ0YsSUFBSSxDQUFDLG1CQUFtQixDQUFDLGFBQWEsQ0FBQyxDQUFDO1FBQ3hDLE9BQU8sYUFBYSxDQUFDO0lBQ3ZCLENBQUM7SUFFRCxnQkFBZ0I7UUFDZCxPQUFPLElBQUksQ0FBQyxXQUFXLEtBQUsscUJBQVcsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLGtDQUFzQixDQUFDLENBQUMsQ0FBQyxrQ0FBc0IsQ0FBQztJQUNwRyxDQUFDO0NBQ0Y7QUFuTUQsOEJBbU1DO0FBRUQsTUFBTSxTQUFTLEdBQUcsSUFBSSxTQUFTLEVBQUUsQ0FBQztBQUVsQyxrQkFBZSxTQUFTLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbnZhbGlkVHJhbnNhY3Rpb25FcnJvciB9IGZyb20gJ0BiaXRnby9zZGstY29yZSc7XG5pbXBvcnQgeyBDb2luIH0gZnJvbSAnQGNvc21qcy9zdGFyZ2F0ZSc7XG5pbXBvcnQgQmlnTnVtYmVyIGZyb20gJ2JpZ251bWJlci5qcyc7XG5cbmltcG9ydCB7IENvc21vc0xpa2VUcmFuc2FjdGlvbiwgQ29zbW9zVXRpbHMsIEZlZURhdGEgfSBmcm9tICdAYml0Z28vYWJzdHJhY3QtY29zbW9zJztcbmltcG9ydCB7IE1lc3NhZ2VEYXRhIH0gZnJvbSAnLi9pZmFjZSc7XG5pbXBvcnQgKiBhcyBjb25zdGFudHMgZnJvbSAnLi9jb25zdGFudHMnO1xuaW1wb3J0IHsgTmV0d29ya1R5cGUgfSBmcm9tICdAYml0Z28vc3RhdGljcyc7XG5pbXBvcnQgeyBEZWNvZGVkVHhSYXcgfSBmcm9tICdAY29zbWpzL3Byb3RvLXNpZ25pbmcnO1xuaW1wb3J0IHsgTUFJTk5FVF9BRERSRVNTX1BSRUZJWCwgVEVTVE5FVF9BRERSRVNTX1BSRUZJWCB9IGZyb20gJy4vY29uc3RhbnRzJztcbmNvbnN0IGJlY2gzMiA9IHJlcXVpcmUoJ2JlY2gzMi1idWZmZXInKTtcblxuZXhwb3J0IGNsYXNzIFJ1bmVVdGlscyBleHRlbmRzIENvc21vc1V0aWxzIHtcbiAgcHJpdmF0ZSBuZXR3b3JrVHlwZTogTmV0d29ya1R5cGU7XG4gIGNvbnN0cnVjdG9yKG5ldHdvcmtUeXBlOiBOZXR3b3JrVHlwZSA9IE5ldHdvcmtUeXBlLk1BSU5ORVQpIHtcbiAgICBzdXBlcigpO1xuICAgIHRoaXMubmV0d29ya1R5cGUgPSBuZXR3b3JrVHlwZTtcbiAgfVxuXG4gIGdldFNlbmRNZXNzYWdlRGF0YUZyb21EZWNvZGVkVHgoZGVjb2RlZFR4OiBEZWNvZGVkVHhSYXcpOiBNZXNzYWdlRGF0YVtdIHtcbiAgICByZXR1cm4gZGVjb2RlZFR4LmJvZHkubWVzc2FnZXMubWFwKChtZXNzYWdlKSA9PiB7XG4gICAgICBjb25zdCB2YWx1ZSA9IHRoaXMucmVnaXN0cnkuZGVjb2RlKG1lc3NhZ2UpO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdmFsdWU6IHtcbiAgICAgICAgICBmcm9tQWRkcmVzczogdGhpcy5nZXRFbmNvZGVkQWRkcmVzcyh2YWx1ZS5mcm9tQWRkcmVzcyksXG4gICAgICAgICAgdG9BZGRyZXNzOiB0aGlzLmdldEVuY29kZWRBZGRyZXNzKHZhbHVlLnRvQWRkcmVzcyksXG4gICAgICAgICAgYW1vdW50OiB2YWx1ZS5hbW91bnQsXG4gICAgICAgIH0sXG4gICAgICAgIHR5cGVVcmw6IG1lc3NhZ2UudHlwZVVybCxcbiAgICAgIH07XG4gICAgfSk7XG4gIH1cblxuICAvKiogQGluaGVyaXRkb2MgKi9cbiAgaXNWYWxpZEFkZHJlc3MoYWRkcmVzczogc3RyaW5nIHwgVWludDhBcnJheSk6IGJvb2xlYW4ge1xuICAgIGlmIChhZGRyZXNzID09PSB1bmRlZmluZWQgfHwgYWRkcmVzcyA9PT0gbnVsbCkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBpZiAoYWRkcmVzcyBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpIHtcbiAgICAgIHJldHVybiB0aGlzLmlzVmFsaWREZWNvZGVkQWRkcmVzcyhhZGRyZXNzKTtcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBhZGRyZXNzID09PSAnc3RyaW5nJykge1xuICAgICAgcmV0dXJuIHRoaXMuaXNWYWxpZEVuY29kZWRBZGRyZXNzKGFkZHJlc3MpO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICAvKipcbiAgICogVmFsaWRhdGVzIGEgZGVjb2RlZCBhZGRyZXNzIGluIGBVaW50OEFycmF5YCBmb3JtIGJ5IGVuY29kaW5nIGl0IGFuZFxuICAgKiBjaGVja2luZyBpZiB0aGUgZW5jb2RlZCB2ZXJzaW9uIGlzIHZhbGlkXG4gICAqXG4gICAqIEBwYXJhbSBhZGRyZXNzIC0gVGhlIGRlY29kZWQgYWRkcmVzcyBhcyBhIGBVaW50OEFycmF5YC5cbiAgICogQHJldHVybnMgYHRydWVgIGlmIHRoZSBlbmNvZGVkIGFkZHJlc3MgaXMgdmFsaWQsIGBmYWxzZWAgb3RoZXJ3aXNlLlxuICAgKi9cbiAgcHJpdmF0ZSBpc1ZhbGlkRGVjb2RlZEFkZHJlc3MoYWRkcmVzczogVWludDhBcnJheSk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IGVuY29kZWRBZGRyZXNzID0gdGhpcy5nZXRFbmNvZGVkQWRkcmVzcyhhZGRyZXNzKTtcbiAgICByZXR1cm4gdGhpcy5pc1ZhbGlkRW5jb2RlZEFkZHJlc3MoZW5jb2RlZEFkZHJlc3MpO1xuICB9XG5cbiAgLyoqXG4gICAqIFZhbGlkYXRlcyBhbiBlbmNvZGVkIGFkZHJlc3Mgc3RyaW5nIGFnYWluc3QgbmV0d29yay1zcGVjaWZpYyBjcml0ZXJpYS5cbiAgICpcbiAgICogQHBhcmFtIGFkZHJlc3MgLSBUaGUgZW5jb2RlZCBhZGRyZXNzIGFzIGEgYHN0cmluZ2AuXG4gICAqIEByZXR1cm5zIGB0cnVlYCBpZiB0aGUgYWRkcmVzcyBtZWV0cyBuZXR3b3JrLXNwZWNpZmljIHZhbGlkYXRpb24gY3JpdGVyaWEsIGBmYWxzZWAgb3RoZXJ3aXNlLlxuICAgKi9cbiAgcHJpdmF0ZSBpc1ZhbGlkRW5jb2RlZEFkZHJlc3MoYWRkcmVzczogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgaWYgKHRoaXMubmV0d29ya1R5cGUgPT09IE5ldHdvcmtUeXBlLlRFU1RORVQpIHtcbiAgICAgIHJldHVybiB0aGlzLmlzVmFsaWRDb3Ntb3NMaWtlQWRkcmVzc1dpdGhNZW1vSWQoYWRkcmVzcywgY29uc3RhbnRzLnRlc3RuZXRBY2NvdW50QWRkcmVzc1JlZ2V4KTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuaXNWYWxpZENvc21vc0xpa2VBZGRyZXNzV2l0aE1lbW9JZChhZGRyZXNzLCBjb25zdGFudHMubWFpbm5ldEFjY291bnRBZGRyZXNzUmVnZXgpO1xuICB9XG5cbiAgLyoqXG4gICAqIEVuY29kZXMgYSBnaXZlbiBhZGRyZXNzIGBVaW50OEFycmF5YCBpbnRvIGEgYmVjaDMyIHN0cmluZyBmb3JtYXQsIGJhc2VkIG9uIHRoZSBjdXJyZW50IG5ldHdvcmsgdHlwZS5cbiAgICogUHJpbWFyaWx5IHNlcnZlcyBhcyBhIHV0aWxpdHkgdG8gY29udmVydCBhIGBVaW50OEFycmF5YC10eXBlIGFkZHJlc3MgdG8gYSBiZWNoMzIgZW5jb2RlZCBzdHJpbmdcbiAgICpcbiAgICogQHBhcmFtIGFkZHJlc3MgLSBUaGUgYWRkcmVzcyB0byBiZSBlbmNvZGVkLCBwcm92aWRlZCBhcyBhIGBVaW50OEFycmF5YC5cbiAgICogQHJldHVybnMgQSBiZWNoMzItZW5jb2RlZCBzdHJpbmcgcmVwcmVzZW50aW5nIHRoZSBhZGRyZXNzLlxuICAgKiBAdGhyb3dzIEVycm9yIC0gVGhyb3dzIGFuIGVycm9yIGlmIGVuY29kaW5nIGZhaWxzXG4gICAqL1xuICBnZXRFbmNvZGVkQWRkcmVzcyhhZGRyZXNzOiBVaW50OEFycmF5KTogc3RyaW5nIHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIHRoaXMubmV0d29ya1R5cGUgPT09IE5ldHdvcmtUeXBlLlRFU1RORVRcbiAgICAgICAgPyBiZWNoMzIuZW5jb2RlKFRFU1RORVRfQUREUkVTU19QUkVGSVgsIGFkZHJlc3MpXG4gICAgICAgIDogYmVjaDMyLmVuY29kZShNQUlOTkVUX0FERFJFU1NfUFJFRklYLCBhZGRyZXNzKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBGYWlsZWQgdG8gZW5jb2RlIGFkZHJlc3M6ICR7ZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UgOiBTdHJpbmcoZXJyb3IpfWApO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBEZWNvZGVzIGEgYmVjaDMyLWVuY29kZWQgYWRkcmVzcyBzdHJpbmcgYmFjayBpbnRvIGEgYFVpbnQ4QXJyYXlgLlxuICAgKiBQcmltYXJpbHkgc2VydmVzIGFzIGEgdXRpbGl0eSB0byBjb252ZXJ0IGEgc3RyaW5nLXR5cGUgYWRkcmVzcyBpbnRvIGl0cyBiaW5hcnkgcmVwcmVzZW50YXRpb24sXG4gICAqXG4gICAqIEBwYXJhbSBhZGRyZXNzIC0gVGhlIGJlY2gzMi1lbmNvZGVkIGFkZHJlc3MgYXMgYSBgc3RyaW5nYC5cbiAgICogQHJldHVybnMgVGhlIGRlY29kZWQgYWRkcmVzcyBhcyBhIGBVaW50OEFycmF5YC5cbiAgICogQHRocm93cyBFcnJvciAtIFRocm93cyBhbiBlcnJvciBpZiBkZWNvZGluZyBmYWlsc1xuICAgKi9cbiAgZ2V0RGVjb2RlZEFkZHJlc3MoYWRkcmVzczogc3RyaW5nKTogVWludDhBcnJheSB7XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiBiZWNoMzIuZGVjb2RlKGFkZHJlc3MpLmRhdGE7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgRmFpbGVkIHRvIGRlY29kZSBhZGRyZXNzOiAke2Vycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvci5tZXNzYWdlIDogU3RyaW5nKGVycm9yKX1gKTtcbiAgICB9XG4gIH1cblxuICAvKiogQGluaGVyaXRkb2MgKi9cbiAgaXNWYWxpZFZhbGlkYXRvckFkZHJlc3MoYWRkcmVzczogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgaWYgKHRoaXMubmV0d29ya1R5cGUgPT09IE5ldHdvcmtUeXBlLlRFU1RORVQpIHtcbiAgICAgIHJldHVybiB0aGlzLmlzVmFsaWRCZWNoMzJBZGRyZXNzTWF0Y2hpbmdSZWdleChhZGRyZXNzLCBjb25zdGFudHMudGVzdG5ldFZhbGlkYXRvckFkZHJlc3NSZWdleCk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmlzVmFsaWRCZWNoMzJBZGRyZXNzTWF0Y2hpbmdSZWdleChhZGRyZXNzLCBjb25zdGFudHMubWFpbm5ldFZhbGlkYXRvckFkZHJlc3NSZWdleCk7XG4gIH1cblxuICAvKiogQGluaGVyaXRkb2MgKi9cbiAgdmFsaWRhdGVBbW91bnQoYW1vdW50OiBDb2luKTogdm9pZCB7XG4gICAgY29uc3QgYW1vdW50QmlnID0gQmlnTnVtYmVyKGFtb3VudC5hbW91bnQpO1xuICAgIGlmIChhbW91bnRCaWcuaXNOYU4oKSB8fCBhbW91bnRCaWcuaXNMZXNzVGhhbk9yRXF1YWxUbygwKSkge1xuICAgICAgdGhyb3cgbmV3IEludmFsaWRUcmFuc2FjdGlvbkVycm9yKCd0cmFuc2FjdGlvbkJ1aWxkZXI6IHZhbGlkYXRlQW1vdW50OiBJbnZhbGlkIGFtb3VudDogJyArIGFtb3VudC5hbW91bnQpO1xuICAgIH1cbiAgICB0aGlzLnZhbGlkYXRlRGVub21pbmF0aW9uKGFtb3VudC5kZW5vbSk7XG4gIH1cblxuICAvKipcbiAgICogVmFsaWRhdGVzIHRoZSBnYXMgbGltaXQgYW5kIGdhcyBhbW91bnQgZm9yIGEgdHJhbnNhY3Rpb24uXG4gICAqIEBwYXJhbSB7RmVlRGF0YX0gZ2FzQnVkZ2V0IC0gVGhlIGdhcyBidWRnZXQgdG8gdmFsaWRhdGUuXG4gICAqIEB0aHJvd3Mge0ludmFsaWRUcmFuc2FjdGlvbkVycm9yfSBUaHJvd3MgYW4gZXJyb3IgaWYgdGhlIGdhcyBidWRnZXQgaXMgaW52YWxpZC5cbiAgICovXG4gIHZhbGlkYXRlR2FzQnVkZ2V0KGdhc0J1ZGdldDogRmVlRGF0YSk6IHZvaWQge1xuICAgIGlmIChnYXNCdWRnZXQuZ2FzTGltaXQgPD0gMCkge1xuICAgICAgdGhyb3cgbmV3IEludmFsaWRUcmFuc2FjdGlvbkVycm9yKCdJbnZhbGlkIGdhcyBsaW1pdCAnICsgZ2FzQnVkZ2V0Lmdhc0xpbWl0KTtcbiAgICB9XG4gICAgdGhpcy52YWxpZGF0ZUdhc0Ftb3VudERhdGEoZ2FzQnVkZ2V0LmFtb3VudCk7XG4gIH1cblxuICAvKipcbiAgICogVmFsaWRhdGVzIGFuIGFycmF5IG9mIGNvaW4gYW1vdW50cy5cbiAgICogQHBhcmFtIHtDb2luW119IGFtb3VudEFycmF5IC0gVGhlIGFycmF5IG9mIGNvaW4gYW1vdW50cyB0byB2YWxpZGF0ZS5cbiAgICovXG4gIHZhbGlkYXRlR2FzQW1vdW50RGF0YShhbW91bnRBcnJheTogQ29pbltdKTogdm9pZCB7XG4gICAgYW1vdW50QXJyYXkuZm9yRWFjaCgoY29pbkFtb3VudCkgPT4ge1xuICAgICAgdGhpcy52YWxpZGF0ZUdhc0Ftb3VudChjb2luQW1vdW50KTtcbiAgICB9KTtcbiAgfVxuXG4gIHZhbGlkYXRlR2FzQW1vdW50KGFtb3VudDogQ29pbik6IHZvaWQge1xuICAgIGNvbnN0IGFtb3VudEJpZyA9IEJpZ051bWJlcihhbW91bnQuYW1vdW50KTtcbiAgICBpZiAoYW1vdW50QmlnLmlzTmFOKCkgfHwgYW1vdW50QmlnLmlzTGVzc1RoYW4oMCkpIHtcbiAgICAgIHRocm93IG5ldyBJbnZhbGlkVHJhbnNhY3Rpb25FcnJvcigndHJhbnNhY3Rpb25CdWlsZGVyOiB2YWxpZGF0ZUFtb3VudDogSW52YWxpZCBhbW91bnQ6ICcgKyBhbW91bnQuYW1vdW50KTtcbiAgICB9XG4gICAgdGhpcy52YWxpZGF0ZURlbm9taW5hdGlvbihhbW91bnQuZGVub20pO1xuICB9XG5cbiAgdmFsaWRhdGVEZW5vbWluYXRpb24oYW1vdW50RGVub206IHN0cmluZyk6IHZvaWQge1xuICAgIGlmICghY29uc3RhbnRzLnZhbGlkRGVub21zLmZpbmQoKGRlbm9tKSA9PiBkZW5vbSA9PT0gYW1vdW50RGVub20pKSB7XG4gICAgICB0aHJvdyBuZXcgSW52YWxpZFRyYW5zYWN0aW9uRXJyb3IoJ3RyYW5zYWN0aW9uQnVpbGRlcjogdmFsaWRhdGVBbW91bnQ6IEludmFsaWQgZGVub206ICcgKyBhbW91bnREZW5vbSk7XG4gICAgfVxuICB9XG5cbiAgY29udmVydE1lc3NhZ2VBZGRyZXNzVG9VaW50OEFycmF5KG1lc3NhZ2VzOiBNZXNzYWdlRGF0YVtdKTogTWVzc2FnZURhdGFbXSB7XG4gICAgcmV0dXJuIG1lc3NhZ2VzLm1hcCgobWVzc2FnZSkgPT4ge1xuICAgICAgaWYgKCdmcm9tQWRkcmVzcycgaW4gbWVzc2FnZS52YWx1ZSAmJiAndG9BZGRyZXNzJyBpbiBtZXNzYWdlLnZhbHVlKSB7XG4gICAgICAgIGNvbnN0IHNlbmRNZXNzYWdlID0gbWVzc2FnZS52YWx1ZTtcblxuICAgICAgICBjb25zdCBkZWNvZGVkRnJvbSA9XG4gICAgICAgICAgdHlwZW9mIHNlbmRNZXNzYWdlLmZyb21BZGRyZXNzID09PSAnc3RyaW5nJ1xuICAgICAgICAgICAgPyBiZWNoMzIuZGVjb2RlKHNlbmRNZXNzYWdlLmZyb21BZGRyZXNzKS5kYXRhXG4gICAgICAgICAgICA6IHNlbmRNZXNzYWdlLmZyb21BZGRyZXNzO1xuICAgICAgICBjb25zdCBkZWNvZGVkVG8gPVxuICAgICAgICAgIHR5cGVvZiBzZW5kTWVzc2FnZS50b0FkZHJlc3MgPT09ICdzdHJpbmcnID8gYmVjaDMyLmRlY29kZShzZW5kTWVzc2FnZS50b0FkZHJlc3MpLmRhdGEgOiBzZW5kTWVzc2FnZS50b0FkZHJlc3M7XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAuLi5tZXNzYWdlLFxuICAgICAgICAgIHZhbHVlOiB7XG4gICAgICAgICAgICAuLi5zZW5kTWVzc2FnZSxcbiAgICAgICAgICAgIGZyb21BZGRyZXNzOiBkZWNvZGVkRnJvbSxcbiAgICAgICAgICAgIHRvQWRkcmVzczogZGVjb2RlZFRvLFxuICAgICAgICAgIH0sXG4gICAgICAgIH07XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBtZXNzYWdlO1xuICAgIH0pO1xuICB9XG5cbiAgY3JlYXRlVHJhbnNhY3Rpb24oXG4gICAgc2VxdWVuY2U6IG51bWJlcixcbiAgICBtZXNzYWdlczogTWVzc2FnZURhdGFbXSxcbiAgICBnYXNCdWRnZXQ6IEZlZURhdGEsXG4gICAgcHVibGljS2V5Pzogc3RyaW5nLFxuICAgIG1lbW8/OiBzdHJpbmdcbiAgKTogQ29zbW9zTGlrZVRyYW5zYWN0aW9uIHtcbiAgICBtZXNzYWdlcyA9IHRoaXMuY29udmVydE1lc3NhZ2VBZGRyZXNzVG9VaW50OEFycmF5KG1lc3NhZ2VzKTtcbiAgICBjb25zdCBjb3Ntb3NMaWtlVHhuID0ge1xuICAgICAgc2VxdWVuY2U6IHNlcXVlbmNlLFxuICAgICAgc2VuZE1lc3NhZ2VzOiBtZXNzYWdlcyxcbiAgICAgIGdhc0J1ZGdldDogZ2FzQnVkZ2V0LFxuICAgICAgcHVibGljS2V5OiBwdWJsaWNLZXksXG4gICAgICBtZW1vOiBtZW1vLFxuICAgIH07XG4gICAgdGhpcy52YWxpZGF0ZVRyYW5zYWN0aW9uKGNvc21vc0xpa2VUeG4pO1xuICAgIHJldHVybiBjb3Ntb3NMaWtlVHhuO1xuICB9XG5cbiAgZ2V0TmV0d29ya1ByZWZpeCgpIHtcbiAgICByZXR1cm4gdGhpcy5uZXR3b3JrVHlwZSA9PT0gTmV0d29ya1R5cGUuVEVTVE5FVCA/IFRFU1RORVRfQUREUkVTU19QUkVGSVggOiBNQUlOTkVUX0FERFJFU1NfUFJFRklYO1xuICB9XG59XG5cbmNvbnN0IHJ1bmVVdGlscyA9IG5ldyBSdW5lVXRpbHMoKTtcblxuZXhwb3J0IGRlZmF1bHQgcnVuZVV0aWxzO1xuIl19
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"register.d.ts","sourceRoot":"","sources":["../../src/register.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAI5C,eAAO,MAAM,QAAQ,QAAS,SAAS,KAAG,IAGzC,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.register = void 0;
|
|
4
|
+
const rune_1 = require("./rune");
|
|
5
|
+
const trune_1 = require("./trune");
|
|
6
|
+
const register = (sdk) => {
|
|
7
|
+
sdk.register('thorchain:rune', rune_1.Rune.createInstance);
|
|
8
|
+
sdk.register('tthorchain:rune', trune_1.Trune.createInstance);
|
|
9
|
+
};
|
|
10
|
+
exports.register = register;
|
|
11
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVnaXN0ZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvcmVnaXN0ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQ0EsaUNBQThCO0FBQzlCLG1DQUFnQztBQUV6QixNQUFNLFFBQVEsR0FBRyxDQUFDLEdBQWMsRUFBUSxFQUFFO0lBQy9DLEdBQUcsQ0FBQyxRQUFRLENBQUMsZ0JBQWdCLEVBQUUsV0FBSSxDQUFDLGNBQWMsQ0FBQyxDQUFDO0lBQ3BELEdBQUcsQ0FBQyxRQUFRLENBQUMsaUJBQWlCLEVBQUUsYUFBSyxDQUFDLGNBQWMsQ0FBQyxDQUFDO0FBQ3hELENBQUMsQ0FBQztBQUhXLFFBQUEsUUFBUSxZQUduQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEJpdEdvQmFzZSB9IGZyb20gJ0BiaXRnby9zZGstY29yZSc7XG5pbXBvcnQgeyBSdW5lIH0gZnJvbSAnLi9ydW5lJztcbmltcG9ydCB7IFRydW5lIH0gZnJvbSAnLi90cnVuZSc7XG5cbmV4cG9ydCBjb25zdCByZWdpc3RlciA9IChzZGs6IEJpdEdvQmFzZSk6IHZvaWQgPT4ge1xuICBzZGsucmVnaXN0ZXIoJ3Rob3JjaGFpbjpydW5lJywgUnVuZS5jcmVhdGVJbnN0YW5jZSk7XG4gIHNkay5yZWdpc3RlcigndHRob3JjaGFpbjpydW5lJywgVHJ1bmUuY3JlYXRlSW5zdGFuY2UpO1xufTtcbiJdfQ==
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { CosmosCoin, CosmosKeyPair, CosmosLikeCoinRecoveryOutput, GasAmountDetails, RecoveryOptions } from '@bitgo/abstract-cosmos';
|
|
2
|
+
import { BaseCoin, BitGoBase, VerifyTransactionOptions } from '@bitgo/sdk-core';
|
|
3
|
+
import { BaseCoin as StaticsBaseCoin } from '@bitgo/statics';
|
|
4
|
+
import { TransactionBuilderFactory } from './lib';
|
|
5
|
+
import { RuneUtils } from './lib/utils';
|
|
6
|
+
export declare class Rune extends CosmosCoin {
|
|
7
|
+
protected readonly _utils: RuneUtils;
|
|
8
|
+
protected readonly _staticsCoin: Readonly<StaticsBaseCoin>;
|
|
9
|
+
protected constructor(bitgo: BitGoBase, staticsCoin?: Readonly<StaticsBaseCoin>);
|
|
10
|
+
static createInstance(bitgo: BitGoBase, staticsCoin?: Readonly<StaticsBaseCoin>): BaseCoin;
|
|
11
|
+
/** @inheritDoc **/
|
|
12
|
+
getBuilder(): TransactionBuilderFactory;
|
|
13
|
+
/**
|
|
14
|
+
* Factor between the coin's base unit and its smallest subdivison
|
|
15
|
+
*/
|
|
16
|
+
getBaseFactor(): number;
|
|
17
|
+
isValidAddress(address: string): boolean;
|
|
18
|
+
/** @inheritDoc **/
|
|
19
|
+
protected getPublicNodeUrl(): string;
|
|
20
|
+
/** @inheritDoc **/
|
|
21
|
+
getDenomination(): string;
|
|
22
|
+
/** @inheritDoc **/
|
|
23
|
+
getGasAmountDetails(): GasAmountDetails;
|
|
24
|
+
/** @inheritDoc **/
|
|
25
|
+
getKeyPair(publicKey: string): CosmosKeyPair;
|
|
26
|
+
/** @inheritDoc **/
|
|
27
|
+
getAddressFromPublicKey(publicKey: string): string;
|
|
28
|
+
verifyTransaction(params: VerifyTransactionOptions): Promise<boolean>;
|
|
29
|
+
getNativeRuneTxnFees(): string;
|
|
30
|
+
/**
|
|
31
|
+
* This function is overridden from CosmosCoin class' recover function due to the difference in fees handling in thorchain
|
|
32
|
+
* @param {RecoveryOptions} params parameters needed to construct and
|
|
33
|
+
* (maybe) sign the transaction
|
|
34
|
+
*
|
|
35
|
+
* @returns {CosmosLikeCoinRecoveryOutput} the serialized transaction hex string and index
|
|
36
|
+
* of the address being swept
|
|
37
|
+
*/
|
|
38
|
+
recover(params: RecoveryOptions): Promise<CosmosLikeCoinRecoveryOutput>;
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=rune.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rune.d.ts","sourceRoot":"","sources":["../../src/rune.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EACV,aAAa,EACb,4BAA4B,EAG5B,gBAAgB,EAChB,eAAe,EAEhB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,QAAQ,EACR,SAAS,EAKT,wBAAwB,EACzB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,QAAQ,IAAI,eAAe,EAAmB,MAAM,gBAAgB,CAAC;AAC9E,OAAO,EAAW,yBAAyB,EAAE,MAAM,OAAO,CAAC;AAE3D,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAOxC,qBAAa,IAAK,SAAQ,UAAU;IAClC,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;IACrC,SAAS,CAAC,QAAQ,CAAC,YAAY,EAAE,QAAQ,CAAC,eAAe,CAAC,CAAC;IAC3D,SAAS,aAAa,KAAK,EAAE,SAAS,EAAE,WAAW,CAAC,EAAE,QAAQ,CAAC,eAAe,CAAC;IAS/E,MAAM,CAAC,cAAc,CAAC,KAAK,EAAE,SAAS,EAAE,WAAW,CAAC,EAAE,QAAQ,CAAC,eAAe,CAAC,GAAG,QAAQ;IAI1F,mBAAmB;IACnB,UAAU,IAAI,yBAAyB;IAIvC;;OAEG;IACI,aAAa,IAAI,MAAM;IAI9B,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAIxC,mBAAmB;IACnB,SAAS,CAAC,gBAAgB,IAAI,MAAM;IAIpC,mBAAmB;IACnB,eAAe,IAAI,MAAM;IAIzB,mBAAmB;IACnB,mBAAmB,IAAI,gBAAgB;IAOvC,mBAAmB;IACnB,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,aAAa;IAI5C,mBAAmB;IACnB,uBAAuB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM;IAI5C,iBAAiB,CAAC,MAAM,EAAE,wBAAwB,GAAG,OAAO,CAAC,OAAO,CAAC;IA0C3E,oBAAoB,IAAI,MAAM;IAI9B;;;;;;;OAOG;IACG,OAAO,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,4BAA4B,CAAC;CA0F9E"}
|
package/dist/src/rune.js
ADDED
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.Rune = void 0;
|
|
37
|
+
const abstract_cosmos_1 = require("@bitgo/abstract-cosmos");
|
|
38
|
+
const sdk_core_1 = require("@bitgo/sdk-core");
|
|
39
|
+
const statics_1 = require("@bitgo/statics");
|
|
40
|
+
const lib_1 = require("./lib");
|
|
41
|
+
const constants_1 = require("./lib/constants");
|
|
42
|
+
const utils_1 = require("./lib/utils");
|
|
43
|
+
const bignumber_js_1 = require("bignumber.js");
|
|
44
|
+
const bech32 = require('bech32-buffer');
|
|
45
|
+
const _ = __importStar(require("lodash"));
|
|
46
|
+
const crypto_1 = require("crypto");
|
|
47
|
+
class Rune extends abstract_cosmos_1.CosmosCoin {
|
|
48
|
+
constructor(bitgo, staticsCoin) {
|
|
49
|
+
super(bitgo, staticsCoin);
|
|
50
|
+
if (!staticsCoin) {
|
|
51
|
+
throw new Error('missing required constructor parameter staticsCoin');
|
|
52
|
+
}
|
|
53
|
+
this._staticsCoin = staticsCoin;
|
|
54
|
+
this._utils = new utils_1.RuneUtils();
|
|
55
|
+
}
|
|
56
|
+
static createInstance(bitgo, staticsCoin) {
|
|
57
|
+
return new Rune(bitgo, staticsCoin);
|
|
58
|
+
}
|
|
59
|
+
/** @inheritDoc **/
|
|
60
|
+
getBuilder() {
|
|
61
|
+
return new lib_1.TransactionBuilderFactory(statics_1.coins.get(this.getChain()));
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Factor between the coin's base unit and its smallest subdivison
|
|
65
|
+
*/
|
|
66
|
+
getBaseFactor() {
|
|
67
|
+
return 1e8;
|
|
68
|
+
}
|
|
69
|
+
isValidAddress(address) {
|
|
70
|
+
return this._utils.isValidAddress(address) || this._utils.isValidValidatorAddress(address);
|
|
71
|
+
}
|
|
72
|
+
/** @inheritDoc **/
|
|
73
|
+
getPublicNodeUrl() {
|
|
74
|
+
return sdk_core_1.Environments[this.bitgo.getEnv()].runeNodeUrl;
|
|
75
|
+
}
|
|
76
|
+
/** @inheritDoc **/
|
|
77
|
+
getDenomination() {
|
|
78
|
+
return statics_1.BaseUnit.RUNE;
|
|
79
|
+
}
|
|
80
|
+
/** @inheritDoc **/
|
|
81
|
+
getGasAmountDetails() {
|
|
82
|
+
return {
|
|
83
|
+
gasAmount: constants_1.GAS_AMOUNT,
|
|
84
|
+
gasLimit: constants_1.GAS_LIMIT,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
/** @inheritDoc **/
|
|
88
|
+
getKeyPair(publicKey) {
|
|
89
|
+
return new lib_1.KeyPair({ pub: publicKey });
|
|
90
|
+
}
|
|
91
|
+
/** @inheritDoc **/
|
|
92
|
+
getAddressFromPublicKey(publicKey) {
|
|
93
|
+
return new lib_1.KeyPair({ pub: publicKey }).getAddress();
|
|
94
|
+
}
|
|
95
|
+
async verifyTransaction(params) {
|
|
96
|
+
let totalAmount = new bignumber_js_1.BigNumber(0);
|
|
97
|
+
const { txPrebuild, txParams } = params;
|
|
98
|
+
const rawTx = txPrebuild.txHex;
|
|
99
|
+
if (!rawTx) {
|
|
100
|
+
throw new Error('missing required tx prebuild property txHex');
|
|
101
|
+
}
|
|
102
|
+
const transaction = await this.getBuilder().from(rawTx).build();
|
|
103
|
+
const explainedTx = transaction.explainTransaction();
|
|
104
|
+
if (txParams.recipients && txParams.recipients.length > 0) {
|
|
105
|
+
const filteredRecipients = txParams.recipients.map((recipient) => ({
|
|
106
|
+
address: this.getAddressDetails(recipient.address).address,
|
|
107
|
+
amount: recipient.amount,
|
|
108
|
+
}));
|
|
109
|
+
let filteredOutputs = explainedTx.outputs.map((output) => _.pick(output, ['address', 'amount']));
|
|
110
|
+
filteredOutputs = filteredOutputs.map((output) => {
|
|
111
|
+
const prefix = this._utils.getNetworkPrefix();
|
|
112
|
+
const convertedAddress = bech32.encode(prefix, output.address);
|
|
113
|
+
return {
|
|
114
|
+
...output,
|
|
115
|
+
address: convertedAddress,
|
|
116
|
+
};
|
|
117
|
+
});
|
|
118
|
+
if (!_.isEqual(filteredOutputs, filteredRecipients)) {
|
|
119
|
+
throw new Error('Tx outputs does not match with expected txParams recipients');
|
|
120
|
+
}
|
|
121
|
+
// WithdrawDelegatorRewards and ContractCall transaction don't have amount
|
|
122
|
+
if (transaction.type !== sdk_core_1.TransactionType.StakingWithdraw && transaction.type !== sdk_core_1.TransactionType.ContractCall) {
|
|
123
|
+
for (const recipients of txParams.recipients) {
|
|
124
|
+
totalAmount = totalAmount.plus(recipients.amount);
|
|
125
|
+
}
|
|
126
|
+
if (!totalAmount.isEqualTo(explainedTx.outputAmount)) {
|
|
127
|
+
throw new Error('Tx total amount does not match with expected total amount field');
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
return true;
|
|
132
|
+
}
|
|
133
|
+
getNativeRuneTxnFees() {
|
|
134
|
+
return constants_1.RUNE_FEES;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* This function is overridden from CosmosCoin class' recover function due to the difference in fees handling in thorchain
|
|
138
|
+
* @param {RecoveryOptions} params parameters needed to construct and
|
|
139
|
+
* (maybe) sign the transaction
|
|
140
|
+
*
|
|
141
|
+
* @returns {CosmosLikeCoinRecoveryOutput} the serialized transaction hex string and index
|
|
142
|
+
* of the address being swept
|
|
143
|
+
*/
|
|
144
|
+
async recover(params) {
|
|
145
|
+
// Step 1: Check if params contains the required parameters
|
|
146
|
+
if (!params.recoveryDestination || !this.isValidAddress(params.recoveryDestination)) {
|
|
147
|
+
throw new Error('invalid recoveryDestination');
|
|
148
|
+
}
|
|
149
|
+
if (!params.userKey) {
|
|
150
|
+
throw new Error('missing userKey');
|
|
151
|
+
}
|
|
152
|
+
if (!params.backupKey) {
|
|
153
|
+
throw new Error('missing backupKey');
|
|
154
|
+
}
|
|
155
|
+
if (!params.walletPassphrase) {
|
|
156
|
+
throw new Error('missing wallet passphrase');
|
|
157
|
+
}
|
|
158
|
+
// Step 2: Fetch the bitgo key from params
|
|
159
|
+
const userKey = params.userKey.replace(/\s/g, '');
|
|
160
|
+
const backupKey = params.backupKey.replace(/\s/g, '');
|
|
161
|
+
const { userKeyShare, backupKeyShare, commonKeyChain } = await sdk_core_1.ECDSAUtils.getMpcV2RecoveryKeyShares(userKey, backupKey, params.walletPassphrase); // baseAddress is not extracted
|
|
162
|
+
// Step 3: Instantiate the ECDSA signer and fetch the address details
|
|
163
|
+
const MPC = new sdk_core_1.Ecdsa();
|
|
164
|
+
const chainId = await this.getChainId();
|
|
165
|
+
const publicKey = MPC.deriveUnhardened(commonKeyChain, constants_1.ROOT_PATH).slice(0, 66);
|
|
166
|
+
const senderAddress = this.getAddressFromPublicKey(publicKey);
|
|
167
|
+
// Step 4: Fetch account details such as accountNo, balance and check for sufficient funds once gasAmount has been deducted
|
|
168
|
+
const [accountNumber, sequenceNo] = await this.getAccountDetails(senderAddress);
|
|
169
|
+
const balance = new bignumber_js_1.BigNumber(await this.getAccountBalance(senderAddress));
|
|
170
|
+
const gasBudget = {
|
|
171
|
+
amount: [{ denom: this.getDenomination(), amount: this.getGasAmountDetails().gasAmount }],
|
|
172
|
+
gasLimit: this.getGasAmountDetails().gasLimit,
|
|
173
|
+
};
|
|
174
|
+
const actualBalance = balance.minus(this.getNativeRuneTxnFees());
|
|
175
|
+
if (actualBalance.isLessThanOrEqualTo(0)) {
|
|
176
|
+
throw new Error('Did not have enough funds to recover');
|
|
177
|
+
}
|
|
178
|
+
// Step 5: Once sufficient funds are present, construct the recover tx messsage
|
|
179
|
+
const amount = [
|
|
180
|
+
{
|
|
181
|
+
denom: this.getDenomination(),
|
|
182
|
+
amount: actualBalance.toFixed(),
|
|
183
|
+
},
|
|
184
|
+
];
|
|
185
|
+
const sendMessage = [
|
|
186
|
+
{
|
|
187
|
+
fromAddress: senderAddress,
|
|
188
|
+
toAddress: params.recoveryDestination,
|
|
189
|
+
amount: amount,
|
|
190
|
+
},
|
|
191
|
+
];
|
|
192
|
+
// Step 6: Build the unsigned tx using the constructed message
|
|
193
|
+
const txnBuilder = this.getBuilder().getTransferBuilder();
|
|
194
|
+
txnBuilder
|
|
195
|
+
.messages(sendMessage)
|
|
196
|
+
.gasBudget(gasBudget)
|
|
197
|
+
.publicKey(publicKey)
|
|
198
|
+
.sequence(Number(sequenceNo))
|
|
199
|
+
.accountNumber(Number(accountNumber))
|
|
200
|
+
.chainId(chainId);
|
|
201
|
+
const unsignedTransaction = (await txnBuilder.build());
|
|
202
|
+
let serializedTx = unsignedTransaction.toBroadcastFormat();
|
|
203
|
+
const signableHex = unsignedTransaction.signablePayload.toString('hex');
|
|
204
|
+
// Step 7: Sign the tx
|
|
205
|
+
const message = unsignedTransaction.signablePayload;
|
|
206
|
+
const messageHash = (0, crypto_1.createHash)('sha256').update(message).digest();
|
|
207
|
+
const signature = await sdk_core_1.ECDSAUtils.signRecoveryMpcV2(messageHash, userKeyShare, backupKeyShare, commonKeyChain);
|
|
208
|
+
const signableBuffer = Buffer.from(signableHex, 'hex');
|
|
209
|
+
MPC.verify(signableBuffer, signature, this.getHashFunction());
|
|
210
|
+
const cosmosKeyPair = this.getKeyPair(publicKey);
|
|
211
|
+
txnBuilder.addSignature({ pub: cosmosKeyPair.getKeys().pub }, Buffer.from(signature.r + signature.s, 'hex'));
|
|
212
|
+
const signedTransaction = await txnBuilder.build();
|
|
213
|
+
serializedTx = signedTransaction.toBroadcastFormat();
|
|
214
|
+
return { serializedTx: serializedTx };
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
exports.Rune = Rune;
|
|
218
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicnVuZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9ydW5lLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLDREQVNnQztBQUNoQyw4Q0FReUI7QUFDekIsNENBQThFO0FBQzlFLCtCQUEyRDtBQUMzRCwrQ0FBOEU7QUFDOUUsdUNBQXdDO0FBQ3hDLCtDQUF5QztBQUN6QyxNQUFNLE1BQU0sR0FBRyxPQUFPLENBQUMsZUFBZSxDQUFDLENBQUM7QUFDeEMsMENBQTRCO0FBRTVCLG1DQUFvQztBQUVwQyxNQUFhLElBQUssU0FBUSw0QkFBVTtJQUdsQyxZQUFzQixLQUFnQixFQUFFLFdBQXVDO1FBQzdFLEtBQUssQ0FBQyxLQUFLLEVBQUUsV0FBVyxDQUFDLENBQUM7UUFDMUIsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO1lBQ2pCLE1BQU0sSUFBSSxLQUFLLENBQUMsb0RBQW9ELENBQUMsQ0FBQztRQUN4RSxDQUFDO1FBQ0QsSUFBSSxDQUFDLFlBQVksR0FBRyxXQUFXLENBQUM7UUFDaEMsSUFBSSxDQUFDLE1BQU0sR0FBRyxJQUFJLGlCQUFTLEVBQUUsQ0FBQztJQUNoQyxDQUFDO0lBRUQsTUFBTSxDQUFDLGNBQWMsQ0FBQyxLQUFnQixFQUFFLFdBQXVDO1FBQzdFLE9BQU8sSUFBSSxJQUFJLENBQUMsS0FBSyxFQUFFLFdBQVcsQ0FBQyxDQUFDO0lBQ3RDLENBQUM7SUFFRCxtQkFBbUI7SUFDbkIsVUFBVTtRQUNSLE9BQU8sSUFBSSwrQkFBeUIsQ0FBQyxlQUFLLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDbkUsQ0FBQztJQUVEOztPQUVHO0lBQ0ksYUFBYTtRQUNsQixPQUFPLEdBQUcsQ0FBQztJQUNiLENBQUM7SUFFRCxjQUFjLENBQUMsT0FBZTtRQUM1QixPQUFPLElBQUksQ0FBQyxNQUFNLENBQUMsY0FB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b3NLZXlQYWlyLFxuICBDb3Ntb3NMaWtlQ29pblJlY292ZXJ5T3V0cHV0LFxuICBDb3Ntb3NUcmFuc2FjdGlvbixcbiAgRmVlRGF0YSxcbiAgR2FzQW1vdW50RGV0YWlscyxcbiAgUmVjb3ZlcnlPcHRpb25zLFxuICBTZW5kTWVzc2FnZSxcbn0gZnJvbSAnQGJpdGdvL2Fic3RyYWN0LWNvc21vcyc7XG5pbXBvcnQge1xuICBCYXNlQ29pbixcbiAgQml0R29CYXNlLFxuICBFY2RzYSxcbiAgRUNEU0FVdGlscyxcbiAgRW52aXJvbm1lbnRzLFxuICBUcmFuc2FjdGlvblR5cGUsXG4gIFZlcmlmeVRyYW5zYWN0aW9uT3B0aW9ucyxcbn0gZnJvbSAnQGJpdGdvL3Nkay1jb3JlJztcbmltcG9ydCB7IEJhc2VDb2luIGFzIFN0YXRpY3NCYXNlQ29pbiwgQmFzZVVuaXQsIGNvaW5zIH0gZnJvbSAnQGJpdGdvL3N0YXRpY3MnO1xuaW1wb3J0IHsgS2V5UGFpciwgVHJhbnNhY3Rpb25CdWlsZGVyRmFjdG9yeSB9IGZyb20gJy4vbGliJztcbmltcG9ydCB7IEdBU19BTU9VTlQsIEdBU19MSU1JVCwgUlVORV9GRUVTLCBST09UX1BBVEggfSBmcm9tICcuL2xpYi9jb25zdGFudHMnO1xuaW1wb3J0IHsgUnVuZVV0aWxzIH0gZnJvbSAnLi9saWIvdXRpbHMnO1xuaW1wb3J0IHsgQmlnTnVtYmVyIH0gZnJvbSAnYmlnbnVtYmVyLmpzJztcbmNvbnN0IGJlY2gzMiA9IHJlcXVpcmUoJ2JlY2gzMi1idWZmZXInKTtcbmltcG9ydCAqIGFzIF8gZnJvbSAnbG9kYXNoJztcbmltcG9ydCB7IENvaW4gfSBmcm9tICdAY29zbWpzL3N0YXJnYXRlJztcbmltcG9ydCB7IGNyZWF0ZUhhc2ggfSBmcm9tICdjcnlwdG8nO1xuXG5leHBvcnQgY2xhc3MgUnVuZSBleHRlbmRzIENvc21vc0NvaW4ge1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgX3V0aWxzOiBSdW5lVXRpbHM7XG4gIHByb3RlY3RlZCByZWFkb25seSBfc3RhdGljc0NvaW46IFJlYWRvbmx5PFN0YXRpY3NCYXNlQ29pbj47XG4gIHByb3RlY3RlZCBjb25zdHJ1Y3RvcihiaXRnbzogQml0R29CYXNlLCBzdGF0aWNzQ29pbj86IFJlYWRvbmx5PFN0YXRpY3NCYXNlQ29pbj4pIHtcbiAgICBzdXBlcihiaXRnbywgc3RhdGljc0NvaW4pO1xuICAgIGlmICghc3RhdGljc0NvaW4pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignbWlzc2luZyByZXF1aXJlZCBjb25zdHJ1Y3RvciBwYXJhbWV0ZXIgc3RhdGljc0NvaW4nKTtcbiAgICB9XG4gICAgdGhpcy5fc3RhdGljc0NvaW4gPSBzdGF0aWNzQ29pbjtcbiAgICB0aGlzLl91dGlscyA9IG5ldyBSdW5lVXRpbHMoKTtcbiAgfVxuXG4gIHN0YXRpYyBjcmVhdGVJbnN0YW5jZShiaXRnbzogQml0R29CYXNlLCBzdGF0aWNzQ29pbj86IFJlYWRvbmx5PFN0YXRpY3NCYXNlQ29pbj4pOiBCYXNlQ29pbiB7XG4gICAgcmV0dXJuIG5ldyBSdW5lKGJpdGdvLCBzdGF0aWNzQ29pbik7XG4gIH1cblxuICAvKiogQGluaGVyaXREb2MgKiovXG4gIGdldEJ1aWxkZXIoKTogVHJhbnNhY3Rpb25CdWlsZGVyRmFjdG9yeSB7XG4gICAgcmV0dXJuIG5ldyBUcmFuc2FjdGlvbkJ1aWxkZXJGYWN0b3J5KGNvaW5zLmdldCh0aGlzLmdldENoYWluKCkpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGYWN0b3IgYmV0d2VlbiB0aGUgY29pbidzIGJhc2UgdW5pdCBhbmQgaXRzIHNtYWxsZXN0IHN1YmRpdmlzb25cbiAgICovXG4gIHB1YmxpYyBnZXRCYXNlRmFjdG9yKCk6IG51bWJlciB7XG4gICAgcmV0dXJuIDFlODtcbiAgfVxuXG4gIGlzVmFsaWRBZGRyZXNzKGFkZHJlc3M6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLl91dGlscy5pc1ZhbGlkQWRkcmVzcyhhZGRyZXNzKSB8fCB0aGlzLl91dGlscy5pc1ZhbGlkVmFsaWRhdG9yQWRkcmVzcyhhZGRyZXNzKTtcbiAgfVxuXG4gIC8qKiBAaW5oZXJpdERvYyAqKi9cbiAgcHJvdGVjdGVkIGdldFB1YmxpY05vZGVVcmwoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gRW52aXJvbm1lbnRzW3RoaXMuYml0Z28uZ2V0RW52KCldLnJ1bmVOb2RlVXJsO1xuICB9XG5cbiAgLyoqIEBpbmhlcml0RG9jICoqL1xuICBnZXREZW5vbWluYXRpb24oKTogc3RyaW5nIHtcbiAgICByZXR1cm4gQmFzZVVuaXQuUlVORTtcbiAgfVxuXG4gIC8qKiBAaW5oZXJpdERvYyAqKi9cbiAgZ2V0R2FzQW1vdW50RGV0YWlscygpOiBHYXNBbW91bnREZXRhaWxzIHtcbiAgICByZXR1cm4ge1xuICAgICAgZ2FzQW1vdW50OiBHQVNfQU1PVU5ULFxuICAgICAgZ2FzTGltaXQ6IEdBU19MSU1JVCxcbiAgICB9O1xuICB9XG5cbiAgLyoqIEBpbmhlcml0RG9jICoqL1xuICBnZXRLZXlQYWlyKHB1YmxpY0tleTogc3RyaW5nKTogQ29zbW9zS2V5UGFpciB7XG4gICAgcmV0dXJuIG5ldyBLZXlQYWlyKHsgcHViOiBwdWJsaWNLZXkgfSk7XG4gIH1cblxuICAvKiogQGluaGVyaXREb2MgKiovXG4gIGdldEFkZHJlc3NGcm9tUHVibGljS2V5KHB1YmxpY0tleTogc3RyaW5nKTogc3RyaW5nIHtcbiAgICByZXR1cm4gbmV3IEtleVBhaXIoeyBwdWI6IHB1YmxpY0tleSB9KS5nZXRBZGRyZXNzKCk7XG4gIH1cblxuICBhc3luYyB2ZXJpZnlUcmFuc2FjdGlvbihwYXJhbXM6IFZlcmlmeVRyYW5zYWN0aW9uT3B0aW9ucyk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIGxldCB0b3RhbEFtb3VudCA9IG5ldyBCaWdOdW1iZXIoMCk7XG4gICAgY29uc3QgeyB0eFByZWJ1aWxkLCB0eFBhcmFtcyB9ID0gcGFyYW1zO1xuICAgIGNvbnN0IHJhd1R4ID0gdHhQcmVidWlsZC50eEhleDtcbiAgICBpZiAoIXJhd1R4KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ21pc3NpbmcgcmVxdWlyZWQgdHggcHJlYnVpbGQgcHJvcGVydHkgdHhIZXgnKTtcbiAgICB9XG4gICAgY29uc3QgdHJhbnNhY3Rpb24gPSBhd2FpdCB0aGlzLmdldEJ1aWxkZXIoKS5mcm9tKHJhd1R4KS5idWlsZCgpO1xuICAgIGNvbnN0IGV4cGxhaW5lZFR4ID0gdHJhbnNhY3Rpb24uZXhwbGFpblRyYW5zYWN0aW9uKCk7XG5cbiAgICBpZiAodHhQYXJhbXMucmVjaXBpZW50cyAmJiB0eFBhcmFtcy5yZWNpcGllbnRzLmxlbmd0aCA+IDApIHtcbiAgICAgIGNvbnN0IGZpbHRlcmVkUmVjaXBpZW50cyA9IHR4UGFyYW1zLnJlY2lwaWVudHMubWFwKChyZWNpcGllbnQpID0+ICh7XG4gICAgICAgIGFkZHJlc3M6IHRoaXMuZ2V0QWRkcmVzc0RldGFpbHMocmVjaXBpZW50LmFkZHJlc3MpLmFkZHJlc3MsXG4gICAgICAgIGFtb3VudDogcmVjaXBpZW50LmFtb3VudCxcbiAgICAgIH0pKTtcbiAgICAgIGxldCBmaWx0ZXJlZE91dHB1dHMgPSBleHBsYWluZWRUeC5vdXRwdXRzLm1hcCgob3V0cHV0KSA9PiBfLnBpY2sob3V0cHV0LCBbJ2FkZHJlc3MnLCAnYW1vdW50J10pKTtcblxuICAgICAgZmlsdGVyZWRPdXRwdXRzID0gZmlsdGVyZWRPdXRwdXRzLm1hcCgob3V0cHV0KSA9PiB7XG4gICAgICAgIGNvbnN0IHByZWZpeCA9IHRoaXMuX3V0aWxzLmdldE5ldHdvcmtQcmVmaXgoKTtcbiAgICAgICAgY29uc3QgY29udmVydGVkQWRkcmVzcyA9IGJlY2gzMi5lbmNvZGUocHJlZml4LCBvdXRwdXQuYWRkcmVzcyk7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgLi4ub3V0cHV0LFxuICAgICAgICAgIGFkZHJlc3M6IGNvbnZlcnRlZEFkZHJlc3MsXG4gICAgICAgIH07XG4gICAgICB9KTtcblxuICAgICAgaWYgKCFfLmlzRXF1YWwoZmlsdGVyZWRPdXRwdXRzLCBmaWx0ZXJlZFJlY2lwaWVudHMpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignVHggb3V0cHV0cyBkb2VzIG5vdCBtYXRjaCB3aXRoIGV4cGVjdGVkIHR4UGFyYW1zIHJlY2lwaWVudHMnKTtcbiAgICAgIH1cbiAgICAgIC8vIFdpdGhkcmF3RGVsZWdhdG9yUmV3YXJkcyBhbmQgQ29udHJhY3RDYWxsIHRyYW5zYWN0aW9uIGRvbid0IGhhdmUgYW1vdW50XG4gICAgICBpZiAodHJhbnNhY3Rpb24udHlwZSAhPT0gVHJhbnNhY3Rpb25UeXBlLlN0YWtpbmdXaXRoZHJhdyAmJiB0cmFuc2FjdGlvbi50eXBlICE9PSBUcmFuc2FjdGlvblR5cGUuQ29udHJhY3RDYWxsKSB7XG4gICAgICAgIGZvciAoY29uc3QgcmVjaXBpZW50cyBvZiB0eFBhcmFtcy5yZWNpcGllbnRzKSB7XG4gICAgICAgICAgdG90YWxBbW91bnQgPSB0b3RhbEFtb3VudC5wbHVzKHJlY2lwaWVudHMuYW1vdW50KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIXRvdGFsQW1vdW50LmlzRXF1YWxUbyhleHBsYWluZWRUeC5vdXRwdXRBbW91bnQpKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdUeCB0b3RhbCBhbW91bnQgZG9lcyBub3QgbWF0Y2ggd2l0aCBleHBlY3RlZCB0b3RhbCBhbW91bnQgZmllbGQnKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIGdldE5hdGl2ZVJ1bmVUeG5GZWVzKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIFJVTkVfRkVFUztcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGlzIGZ1bmN0aW9uIGlzIG92ZXJyaWRkZW4gZnJvbSBDb3Ntb3NDb2luIGNsYXNzJyByZWNvdmVyIGZ1bmN0aW9uIGR1ZSB0byB0aGUgZGlmZmVyZW5jZSBpbiBmZWVzIGhhbmRsaW5nIGluIHRob3JjaGFpblxuICAgKiBAcGFyYW0ge1JlY292ZXJ5T3B0aW9uc30gcGFyYW1zIHBhcmFtZXRlcnMgbmVlZGVkIHRvIGNvbnN0cnVjdCBhbmRcbiAgICogKG1heWJlKSBzaWduIHRoZSB0cmFuc2FjdGlvblxuICAgKlxuICAgKiBAcmV0dXJucyB7Q29zbW9zTGlrZUNvaW5SZWNvdmVyeU91dHB1dH0gdGhlIHNlcmlhbGl6ZWQgdHJhbnNhY3Rpb24gaGV4IHN0cmluZyBhbmQgaW5kZXhcbiAgICogb2YgdGhlIGFkZHJlc3MgYmVpbmcgc3dlcHRcbiAgICovXG4gIGFzeW5jIHJlY292ZXIocGFyYW1zOiBSZWNvdmVyeU9wdGlvbnMpOiBQcm9taXNlPENvc21vc0xpa2VDb2luUmVjb3ZlcnlPdXRwdXQ+IHtcbiAgICAvLyBTdGVwIDE6IENoZWNrIGlmIHBhcmFtcyBjb250YWlucyB0aGUgcmVxdWlyZWQgcGFyYW1ldGVyc1xuXG4gICAgaWYgKCFwYXJhbXMucmVjb3ZlcnlEZXN0aW5hdGlvbiB8fCAhdGhpcy5pc1ZhbGlkQWRkcmVzcyhwYXJhbXMucmVjb3ZlcnlEZXN0aW5hdGlvbikpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignaW52YWxpZCByZWNvdmVyeURlc3RpbmF0aW9uJyk7XG4gICAgfVxuXG4gICAgaWYgKCFwYXJhbXMudXNlcktleSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdtaXNzaW5nIHVzZXJLZXknKTtcbiAgICB9XG5cbiAgICBpZiAoIXBhcmFtcy5iYWNrdXBLZXkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignbWlzc2luZyBiYWNrdXBLZXknKTtcbiAgICB9XG5cbiAgICBpZiAoIXBhcmFtcy53YWxsZXRQYXNzcGhyYXNlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ21pc3Npbmcgd2FsbGV0IHBhc3NwaHJhc2UnKTtcbiAgICB9XG5cbiAgICAvLyBTdGVwIDI6IEZldGNoIHRoZSBiaXRnbyBrZXkgZnJvbSBwYXJhbXNcbiAgICBjb25zdCB1c2VyS2V5ID0gcGFyYW1zLnVzZXJLZXkucmVwbGFjZSgvXFxzL2csICcnKTtcbiAgICBjb25zdCBiYWNrdXBLZXkgPSBwYXJhbXMuYmFja3VwS2V5LnJlcGxhY2UoL1xccy9nLCAnJyk7XG5cbiAgICBjb25zdCB7IHVzZXJLZXlTaGFyZSwgYmFja3VwS2V5U2hhcmUsIGNvbW1vbktleUNoYWluIH0gPSBhd2FpdCBFQ0RTQVV0aWxzLmdldE1wY1YyUmVjb3ZlcnlLZXlTaGFyZXMoXG4gICAgICB1c2VyS2V5LFxuICAgICAgYmFja3VwS2V5LFxuICAgICAgcGFyYW1zLndhbGxldFBhc3NwaHJhc2VcbiAgICApOyAvLyBiYXNlQWRkcmVzcyBpcyBub3QgZXh0cmFjdGVkXG4gICAgLy8gU3RlcCAzOiBJbnN0YW50aWF0ZSB0aGUgRUNEU0Egc2lnbmVyIGFuZCBmZXRjaCB0aGUgYWRkcmVzcyBkZXRhaWxzXG4gICAgY29uc3QgTVBDID0gbmV3IEVjZHNhKCk7XG4gICAgY29uc3QgY2hhaW5JZCA9IGF3YWl0IHRoaXMuZ2V0Q2hhaW5JZCgpO1xuICAgIGNvbnN0IHB1YmxpY0tleSA9IE1QQy5kZXJpdmVVbmhhcmRlbmVkKGNvbW1vbktleUNoYWluLCBST09UX1BBVEgpLnNsaWNlKDAsIDY2KTtcbiAgICBjb25zdCBzZW5kZXJBZGRyZXNzID0gdGhpcy5nZXRBZGRyZXNzRnJvbVB1YmxpY0tleShwdWJsaWNLZXkpO1xuXG4gICAgLy8gU3RlcCA0OiBGZXRjaCBhY2NvdW50IGRldGFpbHMgc3VjaCBhcyBhY2NvdW50Tm8sIGJhbGFuY2UgYW5kIGNoZWNrIGZvciBzdWZmaWNpZW50IGZ1bmRzIG9uY2UgZ2FzQW1vdW50IGhhcyBiZWVuIGRlZHVjdGVkXG4gICAgY29uc3QgW2FjY291bnROdW1iZXIsIHNlcXVlbmNlTm9dID0gYXdhaXQgdGhpcy5nZXRBY2NvdW50RGV0YWlscyhzZW5kZXJBZGRyZXNzKTtcbiAgICBjb25zdCBiYWxhbmNlID0gbmV3IEJpZ051bWJlcihhd2FpdCB0aGlzLmdldEFjY291bnRCYWxhbmNlKHNlbmRlckFkZHJlc3MpKTtcbiAgICBjb25zdCBnYXNCdWRnZXQ6IEZlZURhdGEgPSB7XG4gICAgICBhbW91bnQ6IFt7IGRlbm9tOiB0aGlzLmdldERlbm9taW5hdGlvbigpLCBhbW91bnQ6IHRoaXMuZ2V0R2FzQW1vdW50RGV0YWlscygpLmdhc0Ftb3VudCB9XSxcbiAgICAgIGdhc0xpbWl0OiB0aGlzLmdldEdhc0Ftb3VudERldGFpbHMoKS5nYXNMaW1pdCxcbiAgICB9O1xuICAgIGNvbnN0IGFjdHVhbEJhbGFuY2UgPSBiYWxhbmNlLm1pbnVzKHRoaXMuZ2V0TmF0aXZlUnVuZVR4bkZlZXMoKSk7XG5cbiAgICBpZiAoYWN0dWFsQmFsYW5jZS5pc0xlc3NUaGFuT3JFcXVhbFRvKDApKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0RpZCBub3QgaGF2ZSBlbm91Z2ggZnVuZHMgdG8gcmVjb3ZlcicpO1xuICAgIH1cblxuICAgIC8vIFN0ZXAgNTogT25jZSBzdWZmaWNpZW50IGZ1bmRzIGFyZSBwcmVzZW50LCBjb25zdHJ1Y3QgdGhlIHJlY292ZXIgdHggbWVzc3NhZ2VcbiAgICBjb25zdCBhbW91bnQ6IENvaW5bXSA9IFtcbiAgICAgIHtcbiAgICAgICAgZGVub206IHRoaXMuZ2V0RGVub21pbmF0aW9uKCksXG4gICAgICAgIGFtb3VudDogYWN0dWFsQmFsYW5jZS50b0ZpeGVkKCksXG4gICAgICB9LFxuICAgIF07XG4gICAgY29uc3Qgc2VuZE1lc3NhZ2U6IFNlbmRNZXNzYWdlW10gPSBbXG4gICAgICB7XG4gICAgICAgIGZyb21BZGRyZXNzOiBzZW5kZXJBZGRyZXNzLFxuICAgICAgICB0b0FkZHJlc3M6IHBhcmFtcy5yZWNvdmVyeURlc3RpbmF0aW9uLFxuICAgICAgICBhbW91bnQ6IGFtb3VudCxcbiAgICAgIH0sXG4gICAgXTtcblxuICAgIC8vIFN0ZXAgNjogQnVpbGQgdGhlIHVuc2lnbmVkIHR4IHVzaW5nIHRoZSBjb25zdHJ1Y3RlZCBtZXNzYWdlXG4gICAgY29uc3QgdHhuQnVpbGRlciA9IHRoaXMuZ2V0QnVpbGRlcigpLmdldFRyYW5zZmVyQnVpbGRlcigpO1xuICAgIHR4bkJ1aWxkZXJcbiAgICAgIC5tZXNzYWdlcyhzZW5kTWVzc2FnZSlcbiAgICAgIC5nYXNCdWRnZXQoZ2FzQnVkZ2V0KVxuICAgICAgLnB1YmxpY0tleShwdWJsaWNLZXkpXG4gICAgICAuc2VxdWVuY2UoTnVtYmVyKHNlcXVlbmNlTm8pKVxuICAgICAgLmFjY291bnROdW1iZXIoTnVtYmVyKGFjY291bnROdW1iZXIpKVxuICAgICAgLmNoYWluSWQoY2hhaW5JZCk7XG4gICAgY29uc3QgdW5zaWduZWRUcmFuc2FjdGlvbiA9IChhd2FpdCB0eG5CdWlsZGVyLmJ1aWxkKCkpIGFzIENvc21vc1RyYW5zYWN0aW9uO1xuICAgIGxldCBzZXJpYWxpemVkVHggPSB1bnNpZ25lZFRyYW5zYWN0aW9uLnRvQnJvYWRjYXN0Rm9ybWF0KCk7XG4gICAgY29uc3Qgc2lnbmFibGVIZXggPSB1bnNpZ25lZFRyYW5zYWN0aW9uLnNpZ25hYmxlUGF5bG9hZC50b1N0cmluZygnaGV4Jyk7XG5cbiAgICAvLyBTdGVwIDc6IFNpZ24gdGhlIHR4XG4gICAgY29uc3QgbWVzc2FnZSA9IHVuc2lnbmVkVHJhbnNhY3Rpb24uc2lnbmFibGVQYXlsb2FkO1xuICAgIGNvbnN0IG1lc3NhZ2VIYXNoID0gY3JlYXRlSGFzaCgnc2hhMjU2JykudXBkYXRlKG1lc3NhZ2UpLmRpZ2VzdCgpO1xuXG4gICAgY29uc3Qgc2lnbmF0dXJlID0gYXdhaXQgRUNEU0FVdGlscy5zaWduUmVjb3ZlcnlNcGNWMihtZXNzYWdlSGFzaCwgdXNlcktleVNoYXJlLCBiYWNrdXBLZXlTaGFyZSwgY29tbW9uS2V5Q2hhaW4pO1xuXG4gICAgY29uc3Qgc2lnbmFibGVCdWZmZXIgPSBCdWZmZXIuZnJvbShzaWduYWJsZUhleCwgJ2hleCcpO1xuICAgIE1QQy52ZXJpZnkoc2lnbmFibGVCdWZmZXIsIHNpZ25hdHVyZSwgdGhpcy5nZXRIYXNoRnVuY3Rpb24oKSk7XG4gICAgY29uc3QgY29zbW9zS2V5UGFpciA9IHRoaXMuZ2V0S2V5UGFpcihwdWJsaWNLZXkpO1xuICAgIHR4bkJ1aWxkZXIuYWRkU2lnbmF0dXJlKHsgcHViOiBjb3Ntb3NLZXlQYWlyLmdldEtleXMoKS5wdWIgfSwgQnVmZmVyLmZyb20oc2lnbmF0dXJlLnIgKyBzaWduYXR1cmUucywgJ2hleCcpKTtcbiAgICBjb25zdCBzaWduZWRUcmFuc2FjdGlvbiA9IGF3YWl0IHR4bkJ1aWxkZXIuYnVpbGQoKTtcbiAgICBzZXJpYWxpemVkVHggPSBzaWduZWRUcmFuc2FjdGlvbi50b0Jyb2FkY2FzdEZvcm1hdCgpO1xuXG4gICAgcmV0dXJuIHsgc2VyaWFsaXplZFR4OiBzZXJpYWxpemVkVHggfTtcbiAgfVxufVxuIl19
|