@bitgo-beta/sdk-coin-xdc 1.0.1-beta.886 → 1.0.1-beta.888
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/dist/src/lib/XDCValidatorABI.json +431 -0
- package/dist/src/lib/index.d.ts +2 -0
- package/dist/src/lib/index.d.ts.map +1 -1
- package/dist/src/lib/index.js +9 -2
- package/dist/src/lib/transactionBuilder.d.ts +22 -2
- package/dist/src/lib/transactionBuilder.d.ts.map +1 -1
- package/dist/src/lib/transactionBuilder.js +49 -1
- package/dist/src/lib/uploadKycBuilder.d.ts +73 -0
- package/dist/src/lib/uploadKycBuilder.d.ts.map +1 -0
- package/dist/src/lib/uploadKycBuilder.js +110 -0
- package/dist/src/lib/validatorContract.d.ts +136 -0
- package/dist/src/lib/validatorContract.d.ts.map +1 -0
- package/dist/src/lib/validatorContract.js +62 -0
- package/dist/test/unit/transactionBuilder/uploadKyc.d.ts +2 -0
- package/dist/test/unit/transactionBuilder/uploadKyc.d.ts.map +1 -0
- package/dist/test/unit/transactionBuilder/uploadKyc.js +215 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +6 -6
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"uploadKycBuilder.d.ts","sourceRoot":"","sources":["../../../src/lib/uploadKycBuilder.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,QAAQ,IAAI,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAE7D,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAGxD;;;GAGG;AACH,qBAAa,aAAc,SAAQ,YAAY;IAC7C,SAAgB,eAAe,EAAE,MAAM,CAAC;IACxC,SAAgB,QAAQ,EAAE,MAAM,CAAC;gBAErB,eAAe,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM;CAMtD;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,SAAS,CAAC,CAAS;IAC3B,OAAO,CAAC,gBAAgB,CAAC,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAuB;gBAEvC,UAAU,EAAE,QAAQ,CAAC,UAAU,CAAC;IAI5C;;;;;;OAMG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAgB5B;;;;;;;OAOG;IACH,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IActC;;;;;OAKG;IACH,KAAK,IAAI,aAAa;IAOtB;;;OAGG;IACH,OAAO,CAAC,uBAAuB;IAM/B;;;OAGG;IACH,OAAO,CAAC,yBAAyB;CAIlC"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.UploadKycBuilder = exports.UploadKycCall = void 0;
|
|
4
|
+
const sdk_core_1 = require("@bitgo-beta/sdk-core");
|
|
5
|
+
const abstract_eth_1 = require("@bitgo-beta/abstract-eth");
|
|
6
|
+
const validatorContract_1 = require("./validatorContract");
|
|
7
|
+
/**
|
|
8
|
+
* Represents an XDC uploadKYC contract call
|
|
9
|
+
* This is used to submit KYC document hashes (IPFS hashes) to the XDC Validator contract
|
|
10
|
+
*/
|
|
11
|
+
class UploadKycCall extends abstract_eth_1.ContractCall {
|
|
12
|
+
constructor(contractAddress, ipfsHash) {
|
|
13
|
+
// uploadKYC(string) - takes a single string parameter (the IPFS hash)
|
|
14
|
+
super(validatorContract_1.UPLOAD_KYC_METHOD_ID, ['string'], [ipfsHash]);
|
|
15
|
+
this.contractAddress = contractAddress;
|
|
16
|
+
this.ipfsHash = ipfsHash;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
exports.UploadKycCall = UploadKycCall;
|
|
20
|
+
/**
|
|
21
|
+
* Builder for XDC uploadKYC transactions
|
|
22
|
+
*
|
|
23
|
+
* This builder creates transactions that upload KYC document hashes to the XDC Validator contract.
|
|
24
|
+
* The flow is:
|
|
25
|
+
* 1. Upload KYC document to IPFS → get IPFS hash (e.g., "Qm...")
|
|
26
|
+
* 2. Use this builder to create a transaction that submits the hash to the validator contract
|
|
27
|
+
* 3. The transaction is signed using TSS/MPC
|
|
28
|
+
* 4. After successful upload, the address can propose a validator candidate
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* ```typescript
|
|
32
|
+
* const builder = new UploadKycBuilder(coinConfig);
|
|
33
|
+
* const call = builder
|
|
34
|
+
* .ipfsHash('QmRealIPFSHash...')
|
|
35
|
+
* .build();
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
class UploadKycBuilder {
|
|
39
|
+
constructor(coinConfig) {
|
|
40
|
+
this._coinConfig = coinConfig;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Set the IPFS hash of the uploaded KYC document
|
|
44
|
+
*
|
|
45
|
+
* @param {string} hash - The IPFS hash (e.g., "QmRealIPFSHash...")
|
|
46
|
+
* @returns {UploadKycBuilder} this builder instance
|
|
47
|
+
* @throws {InvalidParameterValueError} if the hash is invalid
|
|
48
|
+
*/
|
|
49
|
+
ipfsHash(hash) {
|
|
50
|
+
if (!hash || hash.trim().length === 0) {
|
|
51
|
+
throw new sdk_core_1.InvalidParameterValueError('IPFS hash cannot be empty');
|
|
52
|
+
}
|
|
53
|
+
// Basic IPFS hash validation (should start with 'Qm' for v0 or 'b' for v1)
|
|
54
|
+
if (!hash.startsWith('Qm') && !hash.startsWith('b')) {
|
|
55
|
+
throw new sdk_core_1.InvalidParameterValueError('Invalid IPFS hash format. Expected hash starting with "Qm" (v0) or "b" (v1)');
|
|
56
|
+
}
|
|
57
|
+
this._ipfsHash = hash;
|
|
58
|
+
return this;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Set a custom validator contract address
|
|
62
|
+
* If not set, the default address for the network will be used
|
|
63
|
+
*
|
|
64
|
+
* @param {string} address - The validator contract address
|
|
65
|
+
* @returns {UploadKycBuilder} this builder instance
|
|
66
|
+
* @throws {InvalidParameterValueError} if the address is invalid
|
|
67
|
+
*/
|
|
68
|
+
contractAddress(address) {
|
|
69
|
+
if (!address || address.trim().length === 0) {
|
|
70
|
+
throw new sdk_core_1.InvalidParameterValueError('Contract address cannot be empty');
|
|
71
|
+
}
|
|
72
|
+
// Basic Ethereum address validation
|
|
73
|
+
if (!/^(0x)?[0-9a-fA-F]{40}$/.test(address)) {
|
|
74
|
+
throw new sdk_core_1.InvalidParameterValueError('Invalid contract address format');
|
|
75
|
+
}
|
|
76
|
+
this._contractAddress = address.toLowerCase().startsWith('0x') ? address : `0x${address}`;
|
|
77
|
+
return this;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Build the uploadKYC contract call
|
|
81
|
+
*
|
|
82
|
+
* @returns {UploadKycCall} the constructed contract call
|
|
83
|
+
* @throws {BuildTransactionError} if required fields are missing
|
|
84
|
+
*/
|
|
85
|
+
build() {
|
|
86
|
+
this.validateMandatoryFields();
|
|
87
|
+
const contractAddress = this._contractAddress || this.getDefaultContractAddress();
|
|
88
|
+
const ipfsHash = this._ipfsHash; // validated by validateMandatoryFields
|
|
89
|
+
return new UploadKycCall(contractAddress, ipfsHash);
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Validate that all mandatory fields are set
|
|
93
|
+
* @private
|
|
94
|
+
*/
|
|
95
|
+
validateMandatoryFields() {
|
|
96
|
+
if (!this._ipfsHash) {
|
|
97
|
+
throw new sdk_core_1.BuildTransactionError('Missing IPFS hash for uploadKYC transaction');
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Get the default validator contract address for the current network
|
|
102
|
+
* @private
|
|
103
|
+
*/
|
|
104
|
+
getDefaultContractAddress() {
|
|
105
|
+
const isTestnet = this._coinConfig.name === 'txdc';
|
|
106
|
+
return (0, validatorContract_1.getValidatorContractAddress)(isTestnet);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
exports.UploadKycBuilder = UploadKycBuilder;
|
|
110
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXBsb2FkS3ljQnVpbGRlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9saWIvdXBsb2FkS3ljQnVpbGRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFJQSxtREFBeUY7QUFDekYsMkRBQXdEO0FBQ3hELDJEQUF3RjtBQUV4Rjs7O0dBR0c7QUFDSCxNQUFhLGFBQWMsU0FBUSwyQkFBWTtJQUk3QyxZQUFZLGVBQXVCLEVBQUUsUUFBZ0I7UUFDbkQsc0VBQXNFO1FBQ3RFLEtBQUssQ0FBQyx3Q0FBb0IsRUFBRSxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQztRQUNwRCxJQUFJLENBQUMsZUFBZSxHQUFHLGVBQWUsQ0FBQztRQUN2QyxJQUFJLENBQUMsUUFBUSxHQUFHLFFBQVEsQ0FBQztJQUMzQixDQUFDO0NBQ0Y7QUFWRCxzQ0FVQztBQUVEOzs7Ozs7Ozs7Ozs7Ozs7OztHQWlCRztBQUNILE1BQWEsZ0JBQWdCO0lBSzNCLFlBQVksVUFBZ0M7UUFDMUMsSUFBSSxDQUFDLFdBQVcsR0FBRyxVQUFVLENBQUM7SUFDaEMsQ0FBQztJQUVEOzs7Ozs7T0FNRztJQUNILFFBQVEsQ0FBQyxJQUFZO1FBQ25CLElBQUksQ0FBQyxJQUFJLElBQUksSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUN0QyxNQUFNLElBQUkscUNBQTBCLENBQUMsMkJBQTJCLENBQUMsQ0FBQztRQUNwRSxDQUFDO1FBRUQsMkVBQTJFO1FBQzNFLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDO1lBQ3BELE1BQU0sSUFBSSxxQ0FBMEIsQ0FDbEMsNkVBQTZFLENBQzlFLENBQUM7UUFDSixDQUFDO1FBRUQsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUM7UUFDdEIsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQ7Ozs7Ozs7T0FPRztJQUNILGVBQWUsQ0FBQyxPQUFlO1FBQzdCLElBQUksQ0FBQyxPQUFPLElBQUksT0FBTyxDQUFDLElBQUksRUFBRSxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUM1QyxNQUFNLElBQUkscUNBQTBCLENBQUMsa0NBQWtDLENBQUMsQ0FBQztRQUMzRSxDQUFDO1FBRUQsb0NBQW9DO1FBQ3BDLElBQUksQ0FBQyx3QkFBd0IsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztZQUM1QyxNQUFNLElBQUkscUNBQTBCLENBQUMsaUNBQWlDLENBQUMsQ0FBQztRQUMxRSxDQUFDO1FBRUQsSUFBSSxDQUFDLGdCQUFnQixHQUFHLE9BQU8sQ0FBQyxXQUFXLEVBQUUsQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsS0FBSyxPQUFPLEVBQUUsQ0FBQztRQUMxRixPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRDs7Ozs7T0FLRztJQUNILEtBQUs7UUFDSCxJQUFJLENBQUMsdUJBQXVCLEVBQUUsQ0FBQztRQUMvQixNQUFNLGVBQWUsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLElBQUksSUFBSSxDQUFDLHlCQUF5QixFQUFFLENBQUM7UUFDbEYsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLFNBQW1CLENBQUMsQ0FBQyx1Q0FBdUM7UUFDbEYsT0FBTyxJQUFJLGFBQWEsQ0FBQyxlQUFlLEVBQUUsUUFBUSxDQUFDLENBQUM7SUFDdEQsQ0FBQztJQUVEOzs7T0FHRztJQUNLLHVCQUF1QjtRQUM3QixJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDO1lBQ3BCLE1BQU0sSUFBSSxnQ0FBcUIsQ0FBQyw2Q0FBNkMsQ0FBQyxDQUFDO1FBQ2pGLENBQUM7SUFDSCxDQUFDO0lBRUQ7OztPQUdHO0lBQ0sseUJBQXlCO1FBQy9CLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxLQUFLLE1BQU0sQ0FBQztRQUNuRCxPQUFPLElBQUEsK0NBQTJCLEVBQUMsU0FBUyxDQUFDLENBQUM7SUFDaEQsQ0FBQztDQUNGO0FBckZELDRDQXFGQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQHByZXR0aWVyXG4gKi9cbmltcG9ydCB7IEJhc2VDb2luIGFzIENvaW5Db25maWcgfSBmcm9tICdAYml0Z28tYmV0YS9zdGF0aWNzJztcbmltcG9ydCB7IEJ1aWxkVHJhbnNhY3Rpb25FcnJvciwgSW52YWxpZFBhcmFtZXRlclZhbHVlRXJyb3IgfSBmcm9tICdAYml0Z28tYmV0YS9zZGstY29yZSc7XG5pbXBvcnQgeyBDb250cmFjdENhbGwgfSBmcm9tICdAYml0Z28tYmV0YS9hYnN0cmFjdC1ldGgnO1xuaW1wb3J0IHsgVVBMT0FEX0tZQ19NRVRIT0RfSUQsIGdldFZhbGlkYXRvckNvbnRyYWN0QWRkcmVzcyB9IGZyb20gJy4vdmFsaWRhdG9yQ29udHJhY3QnO1xuXG4vKipcbiAqIFJlcHJlc2VudHMgYW4gWERDIHVwbG9hZEtZQyBjb250cmFjdCBjYWxsXG4gKiBUaGlzIGlzIHVzZWQgdG8gc3VibWl0IEtZQyBkb2N1bWVudCBoYXNoZXMgKElQRlMgaGFzaGVzKSB0byB0aGUgWERDIFZhbGlkYXRvciBjb250cmFjdFxuICovXG5leHBvcnQgY2xhc3MgVXBsb2FkS3ljQ2FsbCBleHRlbmRzIENvbnRyYWN0Q2FsbCB7XG4gIHB1YmxpYyByZWFkb25seSBjb250cmFjdEFkZHJlc3M6IHN0cmluZztcbiAgcHVibGljIHJlYWRvbmx5IGlwZnNIYXNoOiBzdHJpbmc7XG5cbiAgY29uc3RydWN0b3IoY29udHJhY3RBZGRyZXNzOiBzdHJpbmcsIGlwZnNIYXNoOiBzdHJpbmcpIHtcbiAgICAvLyB1cGxvYWRLWUMoc3RyaW5nKSAtIHRha2VzIGEgc2luZ2xlIHN0cmluZyBwYXJhbWV0ZXIgKHRoZSBJUEZTIGhhc2gpXG4gICAgc3VwZXIoVVBMT0FEX0tZQ19NRVRIT0RfSUQsIFsnc3RyaW5nJ10sIFtpcGZzSGFzaF0pO1xuICAgIHRoaXMuY29udHJhY3RBZGRyZXNzID0gY29udHJhY3RBZGRyZXNzO1xuICAgIHRoaXMuaXBmc0hhc2ggPSBpcGZzSGFzaDtcbiAgfVxufVxuXG4vKipcbiAqIEJ1aWxkZXIgZm9yIFhEQyB1cGxvYWRLWUMgdHJhbnNhY3Rpb25zXG4gKlxuICogVGhpcyBidWlsZGVyIGNyZWF0ZXMgdHJhbnNhY3Rpb25zIHRoYXQgdXBsb2FkIEtZQyBkb2N1bWVudCBoYXNoZXMgdG8gdGhlIFhEQyBWYWxpZGF0b3IgY29udHJhY3QuXG4gKiBUaGUgZmxvdyBpczpcbiAqIDEuIFVwbG9hZCBLWUMgZG9jdW1lbnQgdG8gSVBGUyDihpIgZ2V0IElQRlMgaGFzaCAoZS5nLiwgXCJRbS4uLlwiKVxuICogMi4gVXNlIHRoaXMgYnVpbGRlciB0byBjcmVhdGUgYSB0cmFuc2FjdGlvbiB0aGF0IHN1Ym1pdHMgdGhlIGhhc2ggdG8gdGhlIHZhbGlkYXRvciBjb250cmFjdFxuICogMy4gVGhlIHRyYW5zYWN0aW9uIGlzIHNpZ25lZCB1c2luZyBUU1MvTVBDXG4gKiA0LiBBZnRlciBzdWNjZXNzZnVsIHVwbG9hZCwgdGhlIGFkZHJlc3MgY2FuIHByb3Bvc2UgYSB2YWxpZGF0b3IgY2FuZGlkYXRlXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGNvbnN0IGJ1aWxkZXIgPSBuZXcgVXBsb2FkS3ljQnVpbGRlcihjb2luQ29uZmlnKTtcbiAqIGNvbnN0IGNhbGwgPSBidWlsZGVyXG4gKiAgIC5pcGZzSGFzaCgnUW1SZWFsSVBGU0hhc2guLi4nKVxuICogICAuYnVpbGQoKTtcbiAqIGBgYFxuICovXG5leHBvcnQgY2xhc3MgVXBsb2FkS3ljQnVpbGRlciB7XG4gIHByaXZhdGUgX2lwZnNIYXNoPzogc3RyaW5nO1xuICBwcml2YXRlIF9jb250cmFjdEFkZHJlc3M/OiBzdHJpbmc7XG4gIHByaXZhdGUgcmVhZG9ubHkgX2NvaW5Db25maWc6IFJlYWRvbmx5PENvaW5Db25maWc+O1xuXG4gIGNvbnN0cnVjdG9yKGNvaW5Db25maWc6IFJlYWRvbmx5PENvaW5Db25maWc+KSB7XG4gICAgdGhpcy5fY29pbkNvbmZpZyA9IGNvaW5Db25maWc7XG4gIH1cblxuICAvKipcbiAgICogU2V0IHRoZSBJUEZTIGhhc2ggb2YgdGhlIHVwbG9hZGVkIEtZQyBkb2N1bWVudFxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gaGFzaCAtIFRoZSBJUEZTIGhhc2ggKGUuZy4sIFwiUW1SZWFsSVBGU0hhc2guLi5cIilcbiAgICogQHJldHVybnMge1VwbG9hZEt5Y0J1aWxkZXJ9IHRoaXMgYnVpbGRlciBpbnN0YW5jZVxuICAgKiBAdGhyb3dzIHtJbnZhbGlkUGFyYW1ldGVyVmFsdWVFcnJvcn0gaWYgdGhlIGhhc2ggaXMgaW52YWxpZFxuICAgKi9cbiAgaXBmc0hhc2goaGFzaDogc3RyaW5nKTogdGhpcyB7XG4gICAgaWYgKCFoYXNoIHx8IGhhc2gudHJpbSgpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhyb3cgbmV3IEludmFsaWRQYXJhbWV0ZXJWYWx1ZUVycm9yKCdJUEZTIGhhc2ggY2Fubm90IGJlIGVtcHR5Jyk7XG4gICAgfVxuXG4gICAgLy8gQmFzaWMgSVBGUyBoYXNoIHZhbGlkYXRpb24gKHNob3VsZCBzdGFydCB3aXRoICdRbScgZm9yIHYwIG9yICdiJyBmb3IgdjEpXG4gICAgaWYgKCFoYXNoLnN0YXJ0c1dpdGgoJ1FtJykgJiYgIWhhc2guc3RhcnRzV2l0aCgnYicpKSB7XG4gICAgICB0aHJvdyBuZXcgSW52YWxpZFBhcmFtZXRlclZhbHVlRXJyb3IoXG4gICAgICAgICdJbnZhbGlkIElQRlMgaGFzaCBmb3JtYXQuIEV4cGVjdGVkIGhhc2ggc3RhcnRpbmcgd2l0aCBcIlFtXCIgKHYwKSBvciBcImJcIiAodjEpJ1xuICAgICAgKTtcbiAgICB9XG5cbiAgICB0aGlzLl9pcGZzSGFzaCA9IGhhc2g7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKipcbiAgICogU2V0IGEgY3VzdG9tIHZhbGlkYXRvciBjb250cmFjdCBhZGRyZXNzXG4gICAqIElmIG5vdCBzZXQsIHRoZSBkZWZhdWx0IGFkZHJlc3MgZm9yIHRoZSBuZXR3b3JrIHdpbGwgYmUgdXNlZFxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gYWRkcmVzcyAtIFRoZSB2YWxpZGF0b3IgY29udHJhY3QgYWRkcmVzc1xuICAgKiBAcmV0dXJucyB7VXBsb2FkS3ljQnVpbGRlcn0gdGhpcyBidWlsZGVyIGluc3RhbmNlXG4gICAqIEB0aHJvd3Mge0ludmFsaWRQYXJhbWV0ZXJWYWx1ZUVycm9yfSBpZiB0aGUgYWRkcmVzcyBpcyBpbnZhbGlkXG4gICAqL1xuICBjb250cmFjdEFkZHJlc3MoYWRkcmVzczogc3RyaW5nKTogdGhpcyB7XG4gICAgaWYgKCFhZGRyZXNzIHx8IGFkZHJlc3MudHJpbSgpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhyb3cgbmV3IEludmFsaWRQYXJhbWV0ZXJWYWx1ZUVycm9yKCdDb250cmFjdCBhZGRyZXNzIGNhbm5vdCBiZSBlbXB0eScpO1xuICAgIH1cblxuICAgIC8vIEJhc2ljIEV0aGVyZXVtIGFkZHJlc3MgdmFsaWRhdGlvblxuICAgIGlmICghL14oMHgpP1swLTlhLWZBLUZdezQwfSQvLnRlc3QoYWRkcmVzcykpIHtcbiAgICAgIHRocm93IG5ldyBJbnZhbGlkUGFyYW1ldGVyVmFsdWVFcnJvcignSW52YWxpZCBjb250cmFjdCBhZGRyZXNzIGZvcm1hdCcpO1xuICAgIH1cblxuICAgIHRoaXMuX2NvbnRyYWN0QWRkcmVzcyA9IGFkZHJlc3MudG9Mb3dlckNhc2UoKS5zdGFydHNXaXRoKCcweCcpID8gYWRkcmVzcyA6IGAweCR7YWRkcmVzc31gO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqXG4gICAqIEJ1aWxkIHRoZSB1cGxvYWRLWUMgY29udHJhY3QgY2FsbFxuICAgKlxuICAgKiBAcmV0dXJucyB7VXBsb2FkS3ljQ2FsbH0gdGhlIGNvbnN0cnVjdGVkIGNvbnRyYWN0IGNhbGxcbiAgICogQHRocm93cyB7QnVpbGRUcmFuc2FjdGlvbkVycm9yfSBpZiByZXF1aXJlZCBmaWVsZHMgYXJlIG1pc3NpbmdcbiAgICovXG4gIGJ1aWxkKCk6IFVwbG9hZEt5Y0NhbGwge1xuICAgIHRoaXMudmFsaWRhdGVNYW5kYXRvcnlGaWVsZHMoKTtcbiAgICBjb25zdCBjb250cmFjdEFkZHJlc3MgPSB0aGlzLl9jb250cmFjdEFkZHJlc3MgfHwgdGhpcy5nZXREZWZhdWx0Q29udHJhY3RBZGRyZXNzKCk7XG4gICAgY29uc3QgaXBmc0hhc2ggPSB0aGlzLl9pcGZzSGFzaCBhcyBzdHJpbmc7IC8vIHZhbGlkYXRlZCBieSB2YWxpZGF0ZU1hbmRhdG9yeUZpZWxkc1xuICAgIHJldHVybiBuZXcgVXBsb2FkS3ljQ2FsbChjb250cmFjdEFkZHJlc3MsIGlwZnNIYXNoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBWYWxpZGF0ZSB0aGF0IGFsbCBtYW5kYXRvcnkgZmllbGRzIGFyZSBzZXRcbiAgICogQHByaXZhdGVcbiAgICovXG4gIHByaXZhdGUgdmFsaWRhdGVNYW5kYXRvcnlGaWVsZHMoKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLl9pcGZzSGFzaCkge1xuICAgICAgdGhyb3cgbmV3IEJ1aWxkVHJhbnNhY3Rpb25FcnJvcignTWlzc2luZyBJUEZTIGhhc2ggZm9yIHVwbG9hZEtZQyB0cmFuc2FjdGlvbicpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgdGhlIGRlZmF1bHQgdmFsaWRhdG9yIGNvbnRyYWN0IGFkZHJlc3MgZm9yIHRoZSBjdXJyZW50IG5ldHdvcmtcbiAgICogQHByaXZhdGVcbiAgICovXG4gIHByaXZhdGUgZ2V0RGVmYXVsdENvbnRyYWN0QWRkcmVzcygpOiBzdHJpbmcge1xuICAgIGNvbnN0IGlzVGVzdG5ldCA9IHRoaXMuX2NvaW5Db25maWcubmFtZSA9PT0gJ3R4ZGMnO1xuICAgIHJldHVybiBnZXRWYWxpZGF0b3JDb250cmFjdEFkZHJlc3MoaXNUZXN0bmV0KTtcbiAgfVxufVxuIl19
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* XDC Validator Contract Constants and ABI
|
|
3
|
+
*
|
|
4
|
+
* This file contains the contract address and ABI for the XDC Validator contract
|
|
5
|
+
* which handles KYC uploads and validator staking operations.
|
|
6
|
+
*
|
|
7
|
+
* Contract Address: 0x0000000000000000000000000000000000000088 (System Contract)
|
|
8
|
+
* Source: XDC Network Validator Contract
|
|
9
|
+
* Reference: https://github.com/XinFinOrg/XDPoSChain
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* XDC Validator Contract Address (Testnet)
|
|
13
|
+
* This is the deployed contract address on XDC Apothem testnet (chainId: 51)
|
|
14
|
+
*/
|
|
15
|
+
export declare const XDC_VALIDATOR_CONTRACT_ADDRESS_TESTNET = "0x0000000000000000000000000000000000000088";
|
|
16
|
+
/**
|
|
17
|
+
* XDC Validator Contract Address (Mainnet)
|
|
18
|
+
* This is the deployed contract address on XDC mainnet (chainId: 50)
|
|
19
|
+
*/
|
|
20
|
+
export declare const XDC_VALIDATOR_CONTRACT_ADDRESS_MAINNET = "0x0000000000000000000000000000000000000088";
|
|
21
|
+
/**
|
|
22
|
+
* uploadKYC method ID
|
|
23
|
+
* keccak256("uploadKYC(string)") = 0xf5c95125
|
|
24
|
+
*/
|
|
25
|
+
export declare const UPLOAD_KYC_METHOD_ID = "0xf5c95125";
|
|
26
|
+
/**
|
|
27
|
+
* propose method ID
|
|
28
|
+
* keccak256("propose(address)") = 0x01267951
|
|
29
|
+
*/
|
|
30
|
+
export declare const PROPOSE_METHOD_ID = "0x01267951";
|
|
31
|
+
/**
|
|
32
|
+
* Full XDC Validator Contract ABI
|
|
33
|
+
* Imported from JSON file for easy use with Web3/XDC3
|
|
34
|
+
*/
|
|
35
|
+
export declare const XDC_VALIDATOR_ABI: ({
|
|
36
|
+
constant: boolean;
|
|
37
|
+
inputs: {
|
|
38
|
+
name: string;
|
|
39
|
+
type: string;
|
|
40
|
+
}[];
|
|
41
|
+
name: string;
|
|
42
|
+
outputs: {
|
|
43
|
+
name: string;
|
|
44
|
+
type: string;
|
|
45
|
+
}[];
|
|
46
|
+
payable: boolean;
|
|
47
|
+
stateMutability: string;
|
|
48
|
+
type: string;
|
|
49
|
+
anonymous?: undefined;
|
|
50
|
+
} | {
|
|
51
|
+
anonymous: boolean;
|
|
52
|
+
inputs: {
|
|
53
|
+
indexed: boolean;
|
|
54
|
+
name: string;
|
|
55
|
+
type: string;
|
|
56
|
+
}[];
|
|
57
|
+
name: string;
|
|
58
|
+
type: string;
|
|
59
|
+
constant?: undefined;
|
|
60
|
+
outputs?: undefined;
|
|
61
|
+
payable?: undefined;
|
|
62
|
+
stateMutability?: undefined;
|
|
63
|
+
})[];
|
|
64
|
+
/**
|
|
65
|
+
* Get the uploadKYC function ABI
|
|
66
|
+
* Useful for encoding function calls
|
|
67
|
+
*/
|
|
68
|
+
export declare const UPLOAD_KYC_ABI: {
|
|
69
|
+
constant: boolean;
|
|
70
|
+
inputs: {
|
|
71
|
+
name: string;
|
|
72
|
+
type: string;
|
|
73
|
+
}[];
|
|
74
|
+
name: string;
|
|
75
|
+
outputs: {
|
|
76
|
+
name: string;
|
|
77
|
+
type: string;
|
|
78
|
+
}[];
|
|
79
|
+
payable: boolean;
|
|
80
|
+
stateMutability: string;
|
|
81
|
+
type: string;
|
|
82
|
+
anonymous?: undefined;
|
|
83
|
+
} | {
|
|
84
|
+
anonymous: boolean;
|
|
85
|
+
inputs: {
|
|
86
|
+
indexed: boolean;
|
|
87
|
+
name: string;
|
|
88
|
+
type: string;
|
|
89
|
+
}[];
|
|
90
|
+
name: string;
|
|
91
|
+
type: string;
|
|
92
|
+
constant?: undefined;
|
|
93
|
+
outputs?: undefined;
|
|
94
|
+
payable?: undefined;
|
|
95
|
+
stateMutability?: undefined;
|
|
96
|
+
} | undefined;
|
|
97
|
+
/**
|
|
98
|
+
* Get the propose function ABI
|
|
99
|
+
* Useful for encoding function calls
|
|
100
|
+
*/
|
|
101
|
+
export declare const PROPOSE_ABI: {
|
|
102
|
+
constant: boolean;
|
|
103
|
+
inputs: {
|
|
104
|
+
name: string;
|
|
105
|
+
type: string;
|
|
106
|
+
}[];
|
|
107
|
+
name: string;
|
|
108
|
+
outputs: {
|
|
109
|
+
name: string;
|
|
110
|
+
type: string;
|
|
111
|
+
}[];
|
|
112
|
+
payable: boolean;
|
|
113
|
+
stateMutability: string;
|
|
114
|
+
type: string;
|
|
115
|
+
anonymous?: undefined;
|
|
116
|
+
} | {
|
|
117
|
+
anonymous: boolean;
|
|
118
|
+
inputs: {
|
|
119
|
+
indexed: boolean;
|
|
120
|
+
name: string;
|
|
121
|
+
type: string;
|
|
122
|
+
}[];
|
|
123
|
+
name: string;
|
|
124
|
+
type: string;
|
|
125
|
+
constant?: undefined;
|
|
126
|
+
outputs?: undefined;
|
|
127
|
+
payable?: undefined;
|
|
128
|
+
stateMutability?: undefined;
|
|
129
|
+
} | undefined;
|
|
130
|
+
/**
|
|
131
|
+
* Get the validator contract address for the given network
|
|
132
|
+
* @param isTestnet - whether to use testnet or mainnet
|
|
133
|
+
* @returns the validator contract address
|
|
134
|
+
*/
|
|
135
|
+
export declare function getValidatorContractAddress(isTestnet: boolean): string;
|
|
136
|
+
//# sourceMappingURL=validatorContract.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validatorContract.d.ts","sourceRoot":"","sources":["../../../src/lib/validatorContract.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH;;;GAGG;AACH,eAAO,MAAM,sCAAsC,+CAA+C,CAAC;AAEnG;;;GAGG;AACH,eAAO,MAAM,sCAAsC,+CAA+C,CAAC;AAEnG;;;GAGG;AACH,eAAO,MAAM,oBAAoB,eAAe,CAAC;AAEjD;;;GAGG;AACH,eAAO,MAAM,iBAAiB,eAAe,CAAC;AAE9C;;;GAGG;AACH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAAkB,CAAC;AAEjD;;;GAGG;AACH,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;aAA4D,CAAC;AAExF;;;GAGG;AACH,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;aAA0D,CAAC;AAEnF;;;;GAIG;AACH,wBAAgB,2BAA2B,CAAC,SAAS,EAAE,OAAO,GAAG,MAAM,CAEtE"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* XDC Validator Contract Constants and ABI
|
|
4
|
+
*
|
|
5
|
+
* This file contains the contract address and ABI for the XDC Validator contract
|
|
6
|
+
* which handles KYC uploads and validator staking operations.
|
|
7
|
+
*
|
|
8
|
+
* Contract Address: 0x0000000000000000000000000000000000000088 (System Contract)
|
|
9
|
+
* Source: XDC Network Validator Contract
|
|
10
|
+
* Reference: https://github.com/XinFinOrg/XDPoSChain
|
|
11
|
+
*/
|
|
12
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
13
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
14
|
+
};
|
|
15
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
+
exports.PROPOSE_ABI = exports.UPLOAD_KYC_ABI = exports.XDC_VALIDATOR_ABI = exports.PROPOSE_METHOD_ID = exports.UPLOAD_KYC_METHOD_ID = exports.XDC_VALIDATOR_CONTRACT_ADDRESS_MAINNET = exports.XDC_VALIDATOR_CONTRACT_ADDRESS_TESTNET = void 0;
|
|
17
|
+
exports.getValidatorContractAddress = getValidatorContractAddress;
|
|
18
|
+
const XDCValidatorABI_json_1 = __importDefault(require("./XDCValidatorABI.json"));
|
|
19
|
+
/**
|
|
20
|
+
* XDC Validator Contract Address (Testnet)
|
|
21
|
+
* This is the deployed contract address on XDC Apothem testnet (chainId: 51)
|
|
22
|
+
*/
|
|
23
|
+
exports.XDC_VALIDATOR_CONTRACT_ADDRESS_TESTNET = '0x0000000000000000000000000000000000000088';
|
|
24
|
+
/**
|
|
25
|
+
* XDC Validator Contract Address (Mainnet)
|
|
26
|
+
* This is the deployed contract address on XDC mainnet (chainId: 50)
|
|
27
|
+
*/
|
|
28
|
+
exports.XDC_VALIDATOR_CONTRACT_ADDRESS_MAINNET = '0x0000000000000000000000000000000000000088';
|
|
29
|
+
/**
|
|
30
|
+
* uploadKYC method ID
|
|
31
|
+
* keccak256("uploadKYC(string)") = 0xf5c95125
|
|
32
|
+
*/
|
|
33
|
+
exports.UPLOAD_KYC_METHOD_ID = '0xf5c95125';
|
|
34
|
+
/**
|
|
35
|
+
* propose method ID
|
|
36
|
+
* keccak256("propose(address)") = 0x01267951
|
|
37
|
+
*/
|
|
38
|
+
exports.PROPOSE_METHOD_ID = '0x01267951';
|
|
39
|
+
/**
|
|
40
|
+
* Full XDC Validator Contract ABI
|
|
41
|
+
* Imported from JSON file for easy use with Web3/XDC3
|
|
42
|
+
*/
|
|
43
|
+
exports.XDC_VALIDATOR_ABI = XDCValidatorABI_json_1.default;
|
|
44
|
+
/**
|
|
45
|
+
* Get the uploadKYC function ABI
|
|
46
|
+
* Useful for encoding function calls
|
|
47
|
+
*/
|
|
48
|
+
exports.UPLOAD_KYC_ABI = XDCValidatorABI_json_1.default.find((item) => item.name === 'uploadKYC');
|
|
49
|
+
/**
|
|
50
|
+
* Get the propose function ABI
|
|
51
|
+
* Useful for encoding function calls
|
|
52
|
+
*/
|
|
53
|
+
exports.PROPOSE_ABI = XDCValidatorABI_json_1.default.find((item) => item.name === 'propose');
|
|
54
|
+
/**
|
|
55
|
+
* Get the validator contract address for the given network
|
|
56
|
+
* @param isTestnet - whether to use testnet or mainnet
|
|
57
|
+
* @returns the validator contract address
|
|
58
|
+
*/
|
|
59
|
+
function getValidatorContractAddress(isTestnet) {
|
|
60
|
+
return isTestnet ? exports.XDC_VALIDATOR_CONTRACT_ADDRESS_TESTNET : exports.XDC_VALIDATOR_CONTRACT_ADDRESS_MAINNET;
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmFsaWRhdG9yQ29udHJhY3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvbGliL3ZhbGlkYXRvckNvbnRyYWN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTs7Ozs7Ozs7O0dBU0c7Ozs7OztBQW1ESCxrRUFFQztBQW5ERCxrRkFBcUQ7QUFFckQ7OztHQUdHO0FBQ1UsUUFBQSxzQ0FBc0MsR0FBRyw0Q0FBNEMsQ0FBQztBQUVuRzs7O0dBR0c7QUFDVSxRQUFBLHNDQUFzQyxHQUFHLDRDQUE0QyxDQUFDO0FBRW5HOzs7R0FHRztBQUNVLFFBQUEsb0JBQW9CLEdBQUcsWUFBWSxDQUFDO0FBRWpEOzs7R0FHRztBQUNVLFFBQUEsaUJBQWlCLEdBQUcsWUFBWSxDQUFDO0FBRTlDOzs7R0FHRztBQUNVLFFBQUEsaUJBQWlCLEdBQUcsOEJBQWUsQ0FBQztBQUVqRDs7O0dBR0c7QUFDVSxRQUFBLGNBQWMsR0FBRyw4QkFBZSxDQUFDLElBQUksQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLElBQUksS0FBSyxXQUFXLENBQUMsQ0FBQztBQUV4Rjs7O0dBR0c7QUFDVSxRQUFBLFdBQVcsR0FBRyw4QkFBZSxDQUFDLElBQUksQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLElBQUksS0FBSyxTQUFTLENBQUMsQ0FBQztBQUVuRjs7OztHQUlHO0FBQ0gsU0FBZ0IsMkJBQTJCLENBQUMsU0FBa0I7SUFDNUQsT0FBTyxTQUFTLENBQUMsQ0FBQyxDQUFDLDhDQUFzQyxDQUFDLENBQUMsQ0FBQyw4Q0FBc0MsQ0FBQztBQUNyRyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBYREMgVmFsaWRhdG9yIENvbnRyYWN0IENvbnN0YW50cyBhbmQgQUJJXG4gKlxuICogVGhpcyBmaWxlIGNvbnRhaW5zIHRoZSBjb250cmFjdCBhZGRyZXNzIGFuZCBBQkkgZm9yIHRoZSBYREMgVmFsaWRhdG9yIGNvbnRyYWN0XG4gKiB3aGljaCBoYW5kbGVzIEtZQyB1cGxvYWRzIGFuZCB2YWxpZGF0b3Igc3Rha2luZyBvcGVyYXRpb25zLlxuICpcbiAqIENvbnRyYWN0IEFkZHJlc3M6IDB4MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDA4OCAoU3lzdGVtIENvbnRyYWN0KVxuICogU291cmNlOiBYREMgTmV0d29yayBWYWxpZGF0b3IgQ29udHJhY3RcbiAqIFJlZmVyZW5jZTogaHR0cHM6Ly9naXRodWIuY29tL1hpbkZpbk9yZy9YRFBvU0NoYWluXG4gKi9cblxuaW1wb3J0IFhEQ1ZhbGlkYXRvckFCSSBmcm9tICcuL1hEQ1ZhbGlkYXRvckFCSS5qc29uJztcblxuLyoqXG4gKiBYREMgVmFsaWRhdG9yIENvbnRyYWN0IEFkZHJlc3MgKFRlc3RuZXQpXG4gKiBUaGlzIGlzIHRoZSBkZXBsb3llZCBjb250cmFjdCBhZGRyZXNzIG9uIFhEQyBBcG90aGVtIHRlc3RuZXQgKGNoYWluSWQ6IDUxKVxuICovXG5leHBvcnQgY29uc3QgWERDX1ZBTElEQVRPUl9DT05UUkFDVF9BRERSRVNTX1RFU1RORVQgPSAnMHgwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDg4JztcblxuLyoqXG4gKiBYREMgVmFsaWRhdG9yIENvbnRyYWN0IEFkZHJlc3MgKE1haW5uZXQpXG4gKiBUaGlzIGlzIHRoZSBkZXBsb3llZCBjb250cmFjdCBhZGRyZXNzIG9uIFhEQyBtYWlubmV0IChjaGFpbklkOiA1MClcbiAqL1xuZXhwb3J0IGNvbnN0IFhEQ19WQUxJREFUT1JfQ09OVFJBQ1RfQUREUkVTU19NQUlOTkVUID0gJzB4MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDA4OCc7XG5cbi8qKlxuICogdXBsb2FkS1lDIG1ldGhvZCBJRFxuICoga2VjY2FrMjU2KFwidXBsb2FkS1lDKHN0cmluZylcIikgPSAweGY1Yzk1MTI1XG4gKi9cbmV4cG9ydCBjb25zdCBVUExPQURfS1lDX01FVEhPRF9JRCA9ICcweGY1Yzk1MTI1JztcblxuLyoqXG4gKiBwcm9wb3NlIG1ldGhvZCBJRFxuICoga2VjY2FrMjU2KFwicHJvcG9zZShhZGRyZXNzKVwiKSA9IDB4MDEyNjc5NTFcbiAqL1xuZXhwb3J0IGNvbnN0IFBST1BPU0VfTUVUSE9EX0lEID0gJzB4MDEyNjc5NTEnO1xuXG4vKipcbiAqIEZ1bGwgWERDIFZhbGlkYXRvciBDb250cmFjdCBBQklcbiAqIEltcG9ydGVkIGZyb20gSlNPTiBmaWxlIGZvciBlYXN5IHVzZSB3aXRoIFdlYjMvWERDM1xuICovXG5leHBvcnQgY29uc3QgWERDX1ZBTElEQVRPUl9BQkkgPSBYRENWYWxpZGF0b3JBQkk7XG5cbi8qKlxuICogR2V0IHRoZSB1cGxvYWRLWUMgZnVuY3Rpb24gQUJJXG4gKiBVc2VmdWwgZm9yIGVuY29kaW5nIGZ1bmN0aW9uIGNhbGxzXG4gKi9cbmV4cG9ydCBjb25zdCBVUExPQURfS1lDX0FCSSA9IFhEQ1ZhbGlkYXRvckFCSS5maW5kKChpdGVtKSA9PiBpdGVtLm5hbWUgPT09ICd1cGxvYWRLWUMnKTtcblxuLyoqXG4gKiBHZXQgdGhlIHByb3Bvc2UgZnVuY3Rpb24gQUJJXG4gKiBVc2VmdWwgZm9yIGVuY29kaW5nIGZ1bmN0aW9uIGNhbGxzXG4gKi9cbmV4cG9ydCBjb25zdCBQUk9QT1NFX0FCSSA9IFhEQ1ZhbGlkYXRvckFCSS5maW5kKChpdGVtKSA9PiBpdGVtLm5hbWUgPT09ICdwcm9wb3NlJyk7XG5cbi8qKlxuICogR2V0IHRoZSB2YWxpZGF0b3IgY29udHJhY3QgYWRkcmVzcyBmb3IgdGhlIGdpdmVuIG5ldHdvcmtcbiAqIEBwYXJhbSBpc1Rlc3RuZXQgLSB3aGV0aGVyIHRvIHVzZSB0ZXN0bmV0IG9yIG1haW5uZXRcbiAqIEByZXR1cm5zIHRoZSB2YWxpZGF0b3IgY29udHJhY3QgYWRkcmVzc1xuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0VmFsaWRhdG9yQ29udHJhY3RBZGRyZXNzKGlzVGVzdG5ldDogYm9vbGVhbik6IHN0cmluZyB7XG4gIHJldHVybiBpc1Rlc3RuZXQgPyBYRENfVkFMSURBVE9SX0NPTlRSQUNUX0FERFJFU1NfVEVTVE5FVCA6IFhEQ19WQUxJREFUT1JfQ09OVFJBQ1RfQUREUkVTU19NQUlOTkVUO1xufVxuIl19
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"uploadKyc.d.ts","sourceRoot":"","sources":["../../../../test/unit/transactionBuilder/uploadKyc.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,215 @@
|
|
|
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
|
+
const getBuilder_1 = require("../getBuilder");
|
|
7
|
+
const should_1 = __importDefault(require("should"));
|
|
8
|
+
const sdk_core_1 = require("@bitgo-beta/sdk-core");
|
|
9
|
+
const statics_1 = require("@bitgo-beta/statics");
|
|
10
|
+
const lib_1 = require("../../../src/lib");
|
|
11
|
+
describe('XDC Upload KYC Builder', () => {
|
|
12
|
+
const coinConfig = statics_1.coins.get('txdc');
|
|
13
|
+
describe('UploadKycBuilder', () => {
|
|
14
|
+
it('should build uploadKYC call with valid IPFS hash', () => {
|
|
15
|
+
const builder = new lib_1.UploadKycBuilder(coinConfig);
|
|
16
|
+
const ipfsHash = 'QmRealIPFSHashExample123456789012345678901234';
|
|
17
|
+
const call = builder.ipfsHash(ipfsHash).build();
|
|
18
|
+
should_1.default.exist(call);
|
|
19
|
+
call.should.be.instanceOf(lib_1.UploadKycCall);
|
|
20
|
+
call.ipfsHash.should.equal(ipfsHash);
|
|
21
|
+
call.contractAddress.should.equal(lib_1.XDC_VALIDATOR_CONTRACT_ADDRESS_TESTNET);
|
|
22
|
+
});
|
|
23
|
+
it('should build uploadKYC call with custom contract address', () => {
|
|
24
|
+
const builder = new lib_1.UploadKycBuilder(coinConfig);
|
|
25
|
+
const ipfsHash = 'QmCustomIPFSHash123456789012345678901234567';
|
|
26
|
+
const customAddress = '0x1234567890123456789012345678901234567890';
|
|
27
|
+
const call = builder.ipfsHash(ipfsHash).contractAddress(customAddress).build();
|
|
28
|
+
should_1.default.exist(call);
|
|
29
|
+
call.contractAddress.should.equal(customAddress);
|
|
30
|
+
});
|
|
31
|
+
it('should accept IPFS v1 hash format (starting with "b")', () => {
|
|
32
|
+
const builder = new lib_1.UploadKycBuilder(coinConfig);
|
|
33
|
+
const ipfsHash = 'bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi';
|
|
34
|
+
const call = builder.ipfsHash(ipfsHash).build();
|
|
35
|
+
should_1.default.exist(call);
|
|
36
|
+
call.ipfsHash.should.equal(ipfsHash);
|
|
37
|
+
});
|
|
38
|
+
it('should throw error when IPFS hash is empty', () => {
|
|
39
|
+
const builder = new lib_1.UploadKycBuilder(coinConfig);
|
|
40
|
+
(() => builder.ipfsHash('')).should.throw('IPFS hash cannot be empty');
|
|
41
|
+
});
|
|
42
|
+
it('should throw error when IPFS hash format is invalid', () => {
|
|
43
|
+
const builder = new lib_1.UploadKycBuilder(coinConfig);
|
|
44
|
+
(() => builder.ipfsHash('InvalidHash123')).should.throw('Invalid IPFS hash format. Expected hash starting with "Qm" (v0) or "b" (v1)');
|
|
45
|
+
});
|
|
46
|
+
it('should throw error when contract address is empty', () => {
|
|
47
|
+
const builder = new lib_1.UploadKycBuilder(coinConfig);
|
|
48
|
+
(() => builder.contractAddress('')).should.throw('Contract address cannot be empty');
|
|
49
|
+
});
|
|
50
|
+
it('should throw error when contract address format is invalid', () => {
|
|
51
|
+
const builder = new lib_1.UploadKycBuilder(coinConfig);
|
|
52
|
+
(() => builder.contractAddress('InvalidAddress')).should.throw('Invalid contract address format');
|
|
53
|
+
});
|
|
54
|
+
it('should throw error when building without IPFS hash', () => {
|
|
55
|
+
const builder = new lib_1.UploadKycBuilder(coinConfig);
|
|
56
|
+
(() => builder.build()).should.throw('Missing IPFS hash for uploadKYC transaction');
|
|
57
|
+
});
|
|
58
|
+
it('should normalize contract address with 0x prefix', () => {
|
|
59
|
+
const builder = new lib_1.UploadKycBuilder(coinConfig);
|
|
60
|
+
const ipfsHash = 'QmTestHash123456789012345678901234567890123';
|
|
61
|
+
const addressWithoutPrefix = '1234567890123456789012345678901234567890';
|
|
62
|
+
const call = builder.ipfsHash(ipfsHash).contractAddress(addressWithoutPrefix).build();
|
|
63
|
+
call.contractAddress.should.equal('0x' + addressWithoutPrefix);
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
describe('UploadKycCall', () => {
|
|
67
|
+
it('should serialize uploadKYC call correctly', () => {
|
|
68
|
+
const ipfsHash = 'QmTestIPFSHash1234567890123456789012345678';
|
|
69
|
+
const contractAddress = lib_1.XDC_VALIDATOR_CONTRACT_ADDRESS_TESTNET;
|
|
70
|
+
const call = new lib_1.UploadKycCall(contractAddress, ipfsHash);
|
|
71
|
+
const serialized = call.serialize();
|
|
72
|
+
should_1.default.exist(serialized);
|
|
73
|
+
serialized.should.be.type('string');
|
|
74
|
+
// Should start with the method ID
|
|
75
|
+
serialized.should.startWith(lib_1.UPLOAD_KYC_METHOD_ID);
|
|
76
|
+
});
|
|
77
|
+
it('should have correct properties', () => {
|
|
78
|
+
const ipfsHash = 'QmTestIPFSHash1234567890123456789012345678';
|
|
79
|
+
const contractAddress = '0x0000000000000000000000000000000000000088';
|
|
80
|
+
const call = new lib_1.UploadKycCall(contractAddress, ipfsHash);
|
|
81
|
+
call.contractAddress.should.equal(contractAddress);
|
|
82
|
+
call.ipfsHash.should.equal(ipfsHash);
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
describe('TransactionBuilder integration', () => {
|
|
86
|
+
it('should build uploadKYC transaction with TransactionBuilder', async () => {
|
|
87
|
+
const txBuilder = (0, getBuilder_1.getBuilder)('txdc');
|
|
88
|
+
const ipfsHash = 'QmTestIPFSHash1234567890123456789012345678';
|
|
89
|
+
txBuilder.type(sdk_core_1.TransactionType.ContractCall);
|
|
90
|
+
txBuilder.fee({
|
|
91
|
+
fee: '10000000000',
|
|
92
|
+
gasLimit: '100000',
|
|
93
|
+
});
|
|
94
|
+
txBuilder.counter(1);
|
|
95
|
+
txBuilder.uploadKyc().ipfsHash(ipfsHash);
|
|
96
|
+
const tx = await txBuilder.build();
|
|
97
|
+
should_1.default.exist(tx);
|
|
98
|
+
const txJson = tx.toJson();
|
|
99
|
+
should_1.default.exist(txJson.to);
|
|
100
|
+
txJson.to.should.equal(lib_1.XDC_VALIDATOR_CONTRACT_ADDRESS_TESTNET);
|
|
101
|
+
txJson.value.should.equal('0');
|
|
102
|
+
should_1.default.exist(txJson.data);
|
|
103
|
+
// Data should start with uploadKYC method ID
|
|
104
|
+
txJson.data.should.startWith(lib_1.UPLOAD_KYC_METHOD_ID);
|
|
105
|
+
});
|
|
106
|
+
it('should throw error when uploadKyc() is called on non-ContractCall transaction', () => {
|
|
107
|
+
const txBuilder = (0, getBuilder_1.getBuilder)('txdc');
|
|
108
|
+
txBuilder.type(sdk_core_1.TransactionType.Send);
|
|
109
|
+
(() => txBuilder.uploadKyc()).should.throw('uploadKYC can only be set for contract call transactions');
|
|
110
|
+
});
|
|
111
|
+
it('should build transaction with custom validator contract address', async () => {
|
|
112
|
+
const txBuilder = (0, getBuilder_1.getBuilder)('txdc');
|
|
113
|
+
const ipfsHash = 'QmCustomIPFSHash123456789012345678901234567';
|
|
114
|
+
const customAddress = '0x1234567890123456789012345678901234567890';
|
|
115
|
+
txBuilder.type(sdk_core_1.TransactionType.ContractCall);
|
|
116
|
+
txBuilder.fee({
|
|
117
|
+
fee: '10000000000',
|
|
118
|
+
gasLimit: '100000',
|
|
119
|
+
});
|
|
120
|
+
txBuilder.counter(1);
|
|
121
|
+
txBuilder.uploadKyc().ipfsHash(ipfsHash).contractAddress(customAddress);
|
|
122
|
+
const tx = await txBuilder.build();
|
|
123
|
+
should_1.default.exist(tx);
|
|
124
|
+
const txJson = tx.toJson();
|
|
125
|
+
should_1.default.exist(txJson.to);
|
|
126
|
+
txJson.to.should.equal(customAddress);
|
|
127
|
+
});
|
|
128
|
+
it('should build and serialize uploadKYC transaction', async () => {
|
|
129
|
+
const txBuilder = (0, getBuilder_1.getBuilder)('txdc');
|
|
130
|
+
const ipfsHash = 'QmRealIPFSHashForSerialization1234567890123';
|
|
131
|
+
txBuilder.type(sdk_core_1.TransactionType.ContractCall);
|
|
132
|
+
txBuilder.fee({
|
|
133
|
+
fee: '10000000000',
|
|
134
|
+
gasLimit: '100000',
|
|
135
|
+
});
|
|
136
|
+
txBuilder.counter(5);
|
|
137
|
+
txBuilder.uploadKyc().ipfsHash(ipfsHash);
|
|
138
|
+
const tx = await txBuilder.build();
|
|
139
|
+
const serialized = tx.toBroadcastFormat();
|
|
140
|
+
should_1.default.exist(serialized);
|
|
141
|
+
serialized.should.be.type('string');
|
|
142
|
+
// Should be a valid hex string
|
|
143
|
+
serialized.should.match(/^(0x)?[0-9a-f]+$/i);
|
|
144
|
+
});
|
|
145
|
+
it('should parse uploadKYC transaction from hex', async () => {
|
|
146
|
+
const txBuilder = (0, getBuilder_1.getBuilder)('txdc');
|
|
147
|
+
const ipfsHash = 'QmParseTestHash12345678901234567890123456';
|
|
148
|
+
// First build a transaction
|
|
149
|
+
txBuilder.type(sdk_core_1.TransactionType.ContractCall);
|
|
150
|
+
txBuilder.fee({
|
|
151
|
+
fee: '10000000000',
|
|
152
|
+
gasLimit: '100000',
|
|
153
|
+
});
|
|
154
|
+
txBuilder.counter(10);
|
|
155
|
+
txBuilder.uploadKyc().ipfsHash(ipfsHash);
|
|
156
|
+
const tx = await txBuilder.build();
|
|
157
|
+
const serialized = tx.toBroadcastFormat();
|
|
158
|
+
// Now parse it back
|
|
159
|
+
const txBuilder2 = (0, getBuilder_1.getBuilder)('txdc');
|
|
160
|
+
txBuilder2.from(serialized);
|
|
161
|
+
const parsedTx = await txBuilder2.build();
|
|
162
|
+
should_1.default.exist(parsedTx);
|
|
163
|
+
const parsedJson = parsedTx.toJson();
|
|
164
|
+
should_1.default.exist(parsedJson.to);
|
|
165
|
+
parsedJson.to.should.equal(lib_1.XDC_VALIDATOR_CONTRACT_ADDRESS_TESTNET);
|
|
166
|
+
parsedJson.nonce.should.equal(10);
|
|
167
|
+
});
|
|
168
|
+
});
|
|
169
|
+
describe('Real-world scenarios', () => {
|
|
170
|
+
it('should create transaction matching sandbox code pattern', async () => {
|
|
171
|
+
const txBuilder = (0, getBuilder_1.getBuilder)('txdc');
|
|
172
|
+
// Mock IPFS hash similar to what would be generated
|
|
173
|
+
const mockIPFSHash = 'Qm' + 'a'.repeat(44);
|
|
174
|
+
txBuilder.type(sdk_core_1.TransactionType.ContractCall);
|
|
175
|
+
txBuilder.fee({
|
|
176
|
+
fee: '20000000000',
|
|
177
|
+
gasLimit: '200000',
|
|
178
|
+
});
|
|
179
|
+
txBuilder.counter(0);
|
|
180
|
+
txBuilder.uploadKyc().ipfsHash(mockIPFSHash);
|
|
181
|
+
const tx = await txBuilder.build();
|
|
182
|
+
const txJson = tx.toJson();
|
|
183
|
+
// Verify transaction structure matches expected format
|
|
184
|
+
should_1.default.exist(txJson.to);
|
|
185
|
+
txJson.to.should.equal(lib_1.XDC_VALIDATOR_CONTRACT_ADDRESS_TESTNET);
|
|
186
|
+
txJson.value.should.equal('0');
|
|
187
|
+
should_1.default.exist(txJson.data);
|
|
188
|
+
txJson.data.should.startWith(lib_1.UPLOAD_KYC_METHOD_ID);
|
|
189
|
+
should_1.default.exist(txJson.gasLimit);
|
|
190
|
+
should_1.default.exist(txJson.nonce);
|
|
191
|
+
});
|
|
192
|
+
it('should handle multiple IPFS hash formats', async () => {
|
|
193
|
+
const testHashes = [
|
|
194
|
+
'QmRealIPFSHashExample123456789012345678901234', // v0
|
|
195
|
+
'bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi', // v1
|
|
196
|
+
'QmYwAPJzv5CZsnA625s3Xf2nemtYgPpHdWEz79ojWnPbdG', // real example
|
|
197
|
+
];
|
|
198
|
+
for (const hash of testHashes) {
|
|
199
|
+
const txBuilder = (0, getBuilder_1.getBuilder)('txdc');
|
|
200
|
+
txBuilder.type(sdk_core_1.TransactionType.ContractCall);
|
|
201
|
+
txBuilder.fee({
|
|
202
|
+
fee: '10000000000',
|
|
203
|
+
gasLimit: '100000',
|
|
204
|
+
});
|
|
205
|
+
txBuilder.counter(1);
|
|
206
|
+
txBuilder.uploadKyc().ipfsHash(hash);
|
|
207
|
+
const tx = await txBuilder.build();
|
|
208
|
+
should_1.default.exist(tx);
|
|
209
|
+
const txJson = tx.toJson();
|
|
210
|
+
txJson.data.should.startWith(lib_1.UPLOAD_KYC_METHOD_ID);
|
|
211
|
+
}
|
|
212
|
+
});
|
|
213
|
+
});
|
|
214
|
+
});
|
|
215
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXBsb2FkS3ljLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vdGVzdC91bml0L3RyYW5zYWN0aW9uQnVpbGRlci91cGxvYWRLeWMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSw4Q0FBMkM7QUFDM0Msb0RBQTRCO0FBQzVCLG1EQUF1RDtBQUN2RCxpREFBNEM7QUFDNUMsMENBSzBCO0FBRTFCLFFBQVEsQ0FBQyx3QkFBd0IsRUFBRSxHQUFHLEVBQUU7SUFDdEMsTUFBTSxVQUFVLEdBQUcsZUFBSyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUVyQyxRQUFRLENBQUMsa0JBQWtCLEVBQUUsR0FBRyxFQUFFO1FBQ2hDLEVBQUUsQ0FBQyxrREFBa0QsRUFBRSxHQUFHLEVBQUU7WUFDMUQsTUFBTSxPQUFPLEdBQUcsSUFBSSxzQkFBZ0IsQ0FBQyxVQUFVLENBQUMsQ0FBQztZQUNqRCxNQUFNLFFBQVEsR0FBRywrQ0FBK0MsQ0FBQztZQUVqRSxNQUFNLElBQUksR0FBRyxPQUFPLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxDQUFDLEtBQUssRUFBRSxDQUFDO1lBRWhELGdCQUFNLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ25CLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLFVBQVUsQ0FBQyxtQkFBYSxDQUFDLENBQUM7WUFDekMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQ3JDLElBQUksQ0FBQyxlQUFlLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyw0Q0FBc0MsQ0FBQyxDQUFDO1FBQzVFLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLDBEQUEwRCxFQUFFLEdBQUcsRUFBRTtZQUNsRSxNQUFNLE9BQU8sR0FBRyxJQUFJLHNCQUFnQixDQUFDLFVBQVUsQ0FBQyxDQUFDO1lBQ2pELE1BQU0sUUFBUSxHQUFHLDZDQUE2QyxDQUFDO1lBQy9ELE1BQU0sYUFBYSxHQUFHLDRDQUE0QyxDQUFDO1lBRW5FLE1BQU0sSUFBSSxHQUFHLE9BQU8sQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLENBQUMsZUFBZSxDQUFDLGFBQWEsQ0FBQyxDQUFDLEtBQUssRUFBRSxDQUFDO1lBRS9FLGdCQUFNLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ25CLElBQUksQ0FBQyxlQUFlLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxhQUFhLENBQUMsQ0FBQztRQUNuRCxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyx1REFBdUQsRUFBRSxHQUFHLEVBQUU7WUFDL0QsTUFBTSxPQUFPLEdBQUcsSUFBSSxzQkFBZ0IsQ0FBQyxVQUFVLENBQUMsQ0FBQztZQUNqRCxNQUFNLFFBQVEsR0FBRyw2REFBNkQsQ0FBQztZQUUvRSxNQUFNLElBQUksR0FBRyxPQUFPLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxDQUFDLEtBQUssRUFBRSxDQUFDO1lBRWhELGdCQUFNLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ25CLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUN2QyxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyw0Q0FBNEMsRUFBRSxHQUFHLEVBQUU7WUFDcEQsTUFBTSxPQUFPLEdBQUcsSUFBSSxzQkFBZ0IsQ0FBQyxVQUFVLENBQUMsQ0FBQztZQUVqRCxDQUFDLEdBQUcsRUFBRSxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLDJCQUEyQixDQUFDLENBQUM7UUFDekUsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMscURBQXFELEVBQUUsR0FBRyxFQUFFO1lBQzdELE1BQU0sT0FBTyxHQUFHLElBQUksc0JBQWdCLENBQUMsVUFBVSxDQUFDLENBQUM7WUFFakQsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLGdCQUFnQixDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUNyRCw2RUFBNkUsQ0FDOUUsQ0FBQztRQUNKLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLG1EQUFtRCxFQUFFLEdBQUcsRUFBRTtZQUMzRCxNQUFNLE9BQU8sR0FBRyxJQUFJLHNCQUFnQixDQUFDLFVBQVUsQ0FBQyxDQUFDO1lBRWpELENBQUMsR0FBRyxFQUFFLENBQUMsT0FBTyxDQUFDLGVBQWUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsa0NBQWtDLENBQUMsQ0FBQztRQUN2RixDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyw0REFBNEQsRUFBRSxHQUFHLEVBQUU7WUFDcEUsTUFBTSxPQUFPLEdBQUcsSUFBSSxzQkFBZ0IsQ0FBQyxVQUFVLENBQUMsQ0FBQztZQUVqRCxDQUFDLEdBQUcsRUFBRSxDQUFDLE9BQU8sQ0FBQyxlQUFlLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsaUNBQWlDLENBQUMsQ0FBQztRQUNwRyxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyxvREFBb0QsRUFBRSxHQUFHLEVBQUU7WUFDNUQsTUFBTSxPQUFPLEdBQUcsSUFBSSxzQkFBZ0IsQ0FBQyxVQUFVLENBQUMsQ0FBQztZQUVqRCxDQUFDLEdBQUcsRUFBRSxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsNkNBQTZDLENBQUMsQ0FBQztRQUN0RixDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyxrREFBa0QsRUFBRSxHQUFHLEVBQUU7WUFDMUQsTUFBTSxPQUFPLEdBQUcsSUFBSSxzQkFBZ0IsQ0FBQyxVQUFVLENBQUMsQ0FBQztZQUNqRCxNQUFNLFFBQVEsR0FBRyw2Q0FBNkMsQ0FBQztZQUMvRCxNQUFNLG9CQUFvQixHQUFHLDBDQUEwQyxDQUFDO1lBRXhFLE1BQU0sSUFBSSxHQUFHLE9BQU8sQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLENBQUMsZUFBZSxDQUFDLG9CQUFvQixDQUFDLENBQUMsS0FBSyxFQUFFLENBQUM7WUFFdEYsSUFBSSxDQUFDLGVBQWUsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLElBQUksR0FBRyxvQkFBb0IsQ0FBQyxDQUFDO1FBQ2pFLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7SUFFSCxRQUFRLENBQUMsZUFBZSxFQUFFLEdBQUcsRUFBRTtRQUM3QixFQUFFLENBQUMsMkNBQTJDLEVBQUUsR0FBRyxFQUFFO1lBQ25ELE1BQU0sUUFBUSxHQUFHLDRDQUE0QyxDQUFDO1lBQzlELE1BQU0sZUFBZSxHQUFHLDRDQUFzQyxDQUFDO1lBRS9ELE1BQU0sSUFBSSxHQUFHLElBQUksbUJBQWEsQ0FBQyxlQUFlLEVBQUUsUUFBUSxDQUFDLENBQUM7WUFDMUQsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDO1lBRXBDLGdCQUFNLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxDQUFDO1lBQ3pCLFVBQVUsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUNwQyxrQ0FBa0M7WUFDbEMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsMEJBQW9CLENBQUMsQ0FBQztRQUNwRCxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyxnQ0FBZ0MsRUFBRSxHQUFHLEVBQUU7WUFDeEMsTUFBTSxRQUFRLEdBQUcsNENBQTRDLENBQUM7WUFDOUQsTUFBTSxlQUFlLEdBQUcsNENBQTRDLENBQUM7WUFFckUsTUFBTSxJQUFJLEdBQUcsSUFBSSxtQkFBYSxDQUFDLGVBQWUsRUFBRSxRQUFRLENBQUMsQ0FBQztZQUUxRCxJQUFJLENBQUMsZUFBZSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsZUFBZSxDQUFDLENBQUM7WUFDbkQsSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQ3ZDLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7SUFFSCxRQUFRLENBQUMsZ0NBQWdDLEVBQUUsR0FBRyxFQUFFO1FBQzlDLEVBQUUsQ0FBQyw0REFBNEQsRUFBRSxLQUFLLElBQUksRUFBRTtZQUMxRSxNQUFNLFNBQVMsR0FBRyxJQUFBLHVCQUFVLEVBQUMsTUFBTSxDQUFDLENBQUM7WUFDckMsTUFBTSxRQUFRLEdBQUcsNENBQTRDLENBQUM7WUFFOUQsU0FBUyxDQUFDLElBQUksQ0FBQywwQkFBZSxDQUFDLFlBQVksQ0FBQyxDQUFDO1lBQzdDLFNBQVMsQ0FBQyxHQUFHLENBQUM7Z0JBQ1osR0FBRyxFQUFFLGFBQWE7Z0JBQ2xCLFFBQVEsRUFBRSxRQUFRO2FBQ25CLENBQUMsQ0FBQztZQUNILFNBQVMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDckIsU0FBUyxDQUFDLFNBQVMsRUFBRSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUV6QyxNQUFNLEVBQUUsR0FBRyxNQUFNLFNBQVMsQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUVuQyxnQkFBTSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUNqQixNQUFNLE1BQU0sR0FBRyxFQUFFLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDM0IsZ0JBQU0sQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBQ3hCLE1BQU0sQ0FBQyxFQUFHLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyw0Q0FBc0MsQ0FBQyxDQUFDO1lBQ2hFLE1BQU0sQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUMvQixnQkFBTSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDMUIsNkNBQTZDO1lBQzdDLE1BQU0sQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQywwQkFBb0IsQ0FBQyxDQUFDO1FBQ3JELENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLCtFQUErRSxFQUFFLEdBQUcsRUFBRTtZQUN2RixNQUFNLFNBQVMsR0FBRyxJQUFBLHVCQUFVLEVBQUMsTUFBTSxDQUFDLENBQUM7WUFFckMsU0FBUyxDQUFDLElBQUksQ0FBQywwQkFBZSxDQUFDLElBQUksQ0FBQyxDQUFDO1lBRXJDLENBQUMsR0FBRyxFQUFFLENBQUMsU0FBUyxDQUFDLFNBQVMsRUFBRSxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQywwREFBMEQsQ0FBQyxDQUFDO1FBQ3pHLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLGlFQUFpRSxFQUFFLEtBQUssSUFBSSxFQUFFO1lBQy9FLE1BQU0sU0FBUyxHQUFHLElBQUEsdUJBQVUsRUFBQyxNQUFNLENBQUMsQ0FBQztZQUNyQyxNQUFNLFFBQVEsR0FBRyw2Q0FBNkMsQ0FBQztZQUMvRCxNQUFNLGFBQWEsR0FBRyw0Q0FBNEMsQ0FBQztZQUVuRSxTQUFTLENBQUMsSUFBSSxDQUFDLDBCQUFlLENBQUMsWUFBWSxDQUFDLENBQUM7WUFDN0MsU0FBUyxDQUFDLEdBQUcsQ0FBQztnQkFDWixHQUFHLEVBQUUsYUFBYTtnQkFDbEIsUUFBUSxFQUFFLFFBQVE7YUFDbkIsQ0FBQyxDQUFDO1lBQ0gsU0FBUyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUNyQixTQUFTLENBQUMsU0FBUyxFQUFFLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxDQUFDLGVBQWUsQ0FBQyxhQUFhLENBQUMsQ0FBQztZQUV4RSxNQUFNLEVBQUUsR0FBRyxNQUFNLFNBQVMsQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUVuQyxnQkFBTSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUNqQixNQUFNLE1BQU0sR0FBRyxFQUFFLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDM0IsZ0JBQU0sQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBQ3hCLE1BQU0sQ0FBQyxFQUFHLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxhQUFhLENBQUMsQ0FBQztRQUN6QyxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyxrREFBa0QsRUFBRSxLQUFLLElBQUksRUFBRTtZQUNoRSxNQUFNLFNBQVMsR0FBRyxJQUFBLHVCQUFVLEVBQUMsTUFBTSxDQUFDLENBQUM7WUFDckMsTUFBTSxRQUFRLEdBQUcsNkNBQTZDLENBQUM7WUFFL0QsU0FBUyxDQUFDLElBQUksQ0FBQywwQkFBZSxDQUFDLFlBQVksQ0FBQyxDQUFDO1lBQzdDLFNBQVMsQ0FBQyxHQUFHLENBQUM7Z0JBQ1osR0FBRyxFQUFFLGFBQWE7Z0JBQ2xCLFFBQVEsRUFBRSxRQUFRO2FBQ25CLENBQUMsQ0FBQztZQUNILFNBQVMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDckIsU0FBUyxDQUFDLFNBQVMsRUFBRSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUV6QyxNQUFNLEVBQUUsR0FBRyxNQUFNLFNBQVMsQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUNuQyxNQUFNLFVBQVUsR0FBRyxFQUFFLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztZQUUxQyxnQkFBTSxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUMsQ0FBQztZQUN6QixVQUFVLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDcEMsK0JBQStCO1lBQy9CLFVBQVUsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLG1CQUFtQixDQUFDLENBQUM7UUFDL0MsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsNkNBQTZDLEVBQUUsS0FBSyxJQUFJLEVBQUU7WUFDM0QsTUFBTSxTQUFTLEdBQUcsSUFBQSx1QkFBVSxFQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQ3JDLE1BQU0sUUFBUSxHQUFHLDJDQUEyQyxDQUFDO1lBRTdELDRCQUE0QjtZQUM1QixTQUFTLENBQUMsSUFBSSxDQUFDLDBCQUFlLENBQUMsWUFBWSxDQUFDLENBQUM7WUFDN0MsU0FBUyxDQUFDLEdBQUcsQ0FBQztnQkFDWixHQUFHLEVBQUUsYUFBYTtnQkFDbEIsUUFBUSxFQUFFLFFBQVE7YUFDbkIsQ0FBQyxDQUFDO1lBQ0gsU0FBUyxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUN0QixTQUFTLENBQUMsU0FBUyxFQUFFLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBRXpDLE1BQU0sRUFBRSxHQUFHLE1BQU0sU0FBUyxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ25DLE1BQU0sVUFBVSxHQUFHLEVBQUUsQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO1lBRTFDLG9CQUFvQjtZQUNwQixNQUFNLFVBQVUsR0FBRyxJQUFBLHVCQUFVLEVBQUMsTUFBTSxDQUFDLENBQUM7WUFDdEMsVUFBVSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQztZQUM1QixNQUFNLFFBQVEsR0FBRyxNQUFNLFVBQVUsQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUUxQyxnQkFBTSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUN2QixNQUFNLFVBQVUsR0FBRyxRQUFRLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDckMsZ0JBQU0sQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBQzVCLFVBQVUsQ0FBQyxFQUFHLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyw0Q0FBc0MsQ0FBQyxDQUFDO1lBQ3BFLFVBQVUsQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUNwQyxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0lBRUgsUUFBUSxDQUFDLHNCQUFzQixFQUFFLEdBQUcsRUFBRTtRQUNwQyxFQUFFLENBQUMseURBQXlELEVBQUUsS0FBSyxJQUFJLEVBQUU7WUFDdkUsTUFBTSxTQUFTLEdBQUcsSUFBQSx1QkFBVSxFQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQ3JDLG9EQUFvRDtZQUNwRCxNQUFNLFlBQVksR0FBRyxJQUFJLEdBQUcsR0FBRyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUUzQyxTQUFTLENBQUMsSUFBSSxDQUFDLDBCQUFlLENBQUMsWUFBWSxDQUFDLENBQUM7WUFDN0MsU0FBUyxDQUFDLEdBQUcsQ0FBQztnQkFDWixHQUFHLEVBQUUsYUFBYTtnQkFDbEIsUUFBUSxFQUFFLFFBQVE7YUFDbkIsQ0FBQyxDQUFDO1lBQ0gsU0FBUyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUNyQixTQUFTLENBQUMsU0FBUyxFQUFFLENBQUMsUUFBUSxDQUFDLFlBQVksQ0FBQyxDQUFDO1lBRTdDLE1BQU0sRUFBRSxHQUFHLE1BQU0sU0FBUyxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ25DLE1BQU0sTUFBTSxHQUFHLEVBQUUsQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUUzQix1REFBdUQ7WUFDdkQsZ0JBQU0sQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBQ3hCLE1BQU0sQ0FBQyxFQUFHLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyw0Q0FBc0MsQ0FBQyxDQUFDO1lBQ2hFLE1BQU0sQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUMvQixnQkFBTSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDMUIsTUFBTSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLDBCQUFvQixDQUFDLENBQUM7WUFDbkQsZ0JBQU0sQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQzlCLGdCQUFNLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUM3QixDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQywwQ0FBMEMsRUFBRSxLQUFLLElBQUksRUFBRTtZQUN4RCxNQUFNLFVBQVUsR0FBRztnQkFDakIsK0NBQStDLEVBQUUsS0FBSztnQkFDdEQsNkRBQTZELEVBQUUsS0FBSztnQkFDcEUsZ0RBQWdELEVBQUUsZUFBZTthQUNsRSxDQUFDO1lBRUYsS0FBSyxNQUFNLElBQUksSUFBSSxVQUFVLEVBQUUsQ0FBQztnQkFDOUIsTUFBTSxTQUFTLEdBQUcsSUFBQSx1QkFBVSxFQUFDLE1BQU0sQ0FBQyxDQUFDO2dCQUVyQyxTQUFTLENBQUMsSUFBSSxDQUFDLDBCQUFlLENBQUMsWUFBWSxDQUFDLENBQUM7Z0JBQzdDLFNBQVMsQ0FBQyxHQUFHLENBQUM7b0JBQ1osR0FBRyxFQUFFLGFBQWE7b0JBQ2xCLFFBQVEsRUFBRSxRQUFRO2lCQUNuQixDQUFDLENBQUM7Z0JBQ0gsU0FBUyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDckIsU0FBUyxDQUFDLFNBQVMsRUFBRSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQztnQkFFckMsTUFBTSxFQUFFLEdBQUcsTUFBTSxTQUFTLENBQUMsS0FBSyxFQUFFLENBQUM7Z0JBQ25DLGdCQUFNLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxDQUFDO2dCQUVqQixNQUFNLE1BQU0sR0FBRyxFQUFFLENBQUMsTUFBTSxFQUFFLENBQUM7Z0JBQzNCLE1BQU0sQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQywwQkFBb0IsQ0FBQyxDQUFDO1lBQ3JELENBQUM7UUFDSCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBnZXRCdWlsZGVyIH0gZnJvbSAnLi4vZ2V0QnVpbGRlcic7XG5pbXBvcnQgc2hvdWxkIGZyb20gJ3Nob3VsZCc7XG5pbXBvcnQgeyBUcmFuc2FjdGlvblR5cGUgfSBmcm9tICdAYml0Z28tYmV0YS9zZGstY29yZSc7XG5pbXBvcnQgeyBjb2lucyB9IGZyb20gJ0BiaXRnby1iZXRhL3N0YXRpY3MnO1xuaW1wb3J0IHtcbiAgVXBsb2FkS3ljQnVpbGRlcixcbiAgVXBsb2FkS3ljQ2FsbCxcbiAgWERDX1ZBTElEQVRPUl9DT05UUkFDVF9BRERSRVNTX1RFU1RORVQsXG4gIFVQTE9BRF9LWUNfTUVUSE9EX0lELFxufSBmcm9tICcuLi8uLi8uLi9zcmMvbGliJztcblxuZGVzY3JpYmUoJ1hEQyBVcGxvYWQgS1lDIEJ1aWxkZXInLCAoKSA9PiB7XG4gIGNvbnN0IGNvaW5Db25maWcgPSBjb2lucy5nZXQoJ3R4ZGMnKTtcblxuICBkZXNjcmliZSgnVXBsb2FkS3ljQnVpbGRlcicsICgpID0+IHtcbiAgICBpdCgnc2hvdWxkIGJ1aWxkIHVwbG9hZEtZQyBjYWxsIHdpdGggdmFsaWQgSVBGUyBoYXNoJywgKCkgPT4ge1xuICAgICAgY29uc3QgYnVpbGRlciA9IG5ldyBVcGxvYWRLeWNCdWlsZGVyKGNvaW5Db25maWcpO1xuICAgICAgY29uc3QgaXBmc0hhc2ggPSAnUW1SZWFsSVBGU0hhc2hFeGFtcGxlMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0JztcblxuICAgICAgY29uc3QgY2FsbCA9IGJ1aWxkZXIuaXBmc0hhc2goaXBmc0hhc2gpLmJ1aWxkKCk7XG5cbiAgICAgIHNob3VsZC5leGlzdChjYWxsKTtcbiAgICAgIGNhbGwuc2hvdWxkLmJlLmluc3RhbmNlT2YoVXBsb2FkS3ljQ2FsbCk7XG4gICAgICBjYWxsLmlwZnNIYXNoLnNob3VsZC5lcXVhbChpcGZzSGFzaCk7XG4gICAgICBjYWxsLmNvbnRyYWN0QWRkcmVzcy5zaG91bGQuZXF1YWwoWERDX1ZBTElEQVRPUl9DT05UUkFDVF9BRERSRVNTX1RFU1RORVQpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBidWlsZCB1cGxvYWRLWUMgY2FsbCB3aXRoIGN1c3RvbSBjb250cmFjdCBhZGRyZXNzJywgKCkgPT4ge1xuICAgICAgY29uc3QgYnVpbGRlciA9IG5ldyBVcGxvYWRLeWNCdWlsZGVyKGNvaW5Db25maWcpO1xuICAgICAgY29uc3QgaXBmc0hhc2ggPSAnUW1DdXN0b21JUEZTSGFzaDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nyc7XG4gICAgICBjb25zdCBjdXN0b21BZGRyZXNzID0gJzB4MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MCc7XG5cbiAgICAgIGNvbnN0IGNhbGwgPSBidWlsZGVyLmlwZnNIYXNoKGlwZnNIYXNoKS5jb250cmFjdEFkZHJlc3MoY3VzdG9tQWRkcmVzcykuYnVpbGQoKTtcblxuICAgICAgc2hvdWxkLmV4aXN0KGNhbGwpO1xuICAgICAgY2FsbC5jb250cmFjdEFkZHJlc3Muc2hvdWxkLmVxdWFsKGN1c3RvbUFkZHJlc3MpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBhY2NlcHQgSVBGUyB2MSBoYXNoIGZvcm1hdCAoc3RhcnRpbmcgd2l0aCBcImJcIiknLCAoKSA9PiB7XG4gICAgICBjb25zdCBidWlsZGVyID0gbmV3IFVwbG9hZEt5Y0J1aWxkZXIoY29pbkNvbmZpZyk7XG4gICAgICBjb25zdCBpcGZzSGFzaCA9ICdiYWZ5YmVpZ2R5cnp0NXNmcDd1ZG03aHU3NnVoN3kyNm5mM2VmdXlscWFiZjNvY2xndHF5NTVmYnpkaSc7XG5cbiAgICAgIGNvbnN0IGNhbGwgPSBidWlsZGVyLmlwZnNIYXNoKGlwZnNIYXNoKS5idWlsZCgpO1xuXG4gICAgICBzaG91bGQuZXhpc3QoY2FsbCk7XG4gICAgICBjYWxsLmlwZnNIYXNoLnNob3VsZC5lcXVhbChpcGZzSGFzaCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IGVycm9yIHdoZW4gSVBGUyBoYXNoIGlzIGVtcHR5JywgKCkgPT4ge1xuICAgICAgY29uc3QgYnVpbGRlciA9IG5ldyBVcGxvYWRLeWNCdWlsZGVyKGNvaW5Db25maWcpO1xuXG4gICAgICAoKCkgPT4gYnVpbGRlci5pcGZzSGFzaCgnJykpLnNob3VsZC50aHJvdygnSVBGUyBoYXNoIGNhbm5vdCBiZSBlbXB0eScpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0aHJvdyBlcnJvciB3aGVuIElQRlMgaGFzaCBmb3JtYXQgaXMgaW52YWxpZCcsICgpID0+IHtcbiAgICAgIGNvbnN0IGJ1aWxkZXIgPSBuZXcgVXBsb2FkS3ljQnVpbGRlcihjb2luQ29uZmlnKTtcblxuICAgICAgKCgpID0+IGJ1aWxkZXIuaXBmc0hhc2goJ0ludmFsaWRIYXNoMTIzJykpLnNob3VsZC50aHJvdyhcbiAgICAgICAgJ0ludmFsaWQgSVBGUyBoYXNoIGZvcm1hdC4gRXhwZWN0ZWQgaGFzaCBzdGFydGluZyB3aXRoIFwiUW1cIiAodjApIG9yIFwiYlwiICh2MSknXG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0aHJvdyBlcnJvciB3aGVuIGNvbnRyYWN0IGFkZHJlc3MgaXMgZW1wdHknLCAoKSA9PiB7XG4gICAgICBjb25zdCBidWlsZGVyID0gbmV3IFVwbG9hZEt5Y0J1aWxkZXIoY29pbkNvbmZpZyk7XG5cbiAgICAgICgoKSA9PiBidWlsZGVyLmNvbnRyYWN0QWRkcmVzcygnJykpLnNob3VsZC50aHJvdygnQ29udHJhY3QgYWRkcmVzcyBjYW5ub3QgYmUgZW1wdHknKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdGhyb3cgZXJyb3Igd2hlbiBjb250cmFjdCBhZGRyZXNzIGZvcm1hdCBpcyBpbnZhbGlkJywgKCkgPT4ge1xuICAgICAgY29uc3QgYnVpbGRlciA9IG5ldyBVcGxvYWRLeWNCdWlsZGVyKGNvaW5Db25maWcpO1xuXG4gICAgICAoKCkgPT4gYnVpbGRlci5jb250cmFjdEFkZHJlc3MoJ0ludmFsaWRBZGRyZXNzJykpLnNob3VsZC50aHJvdygnSW52YWxpZCBjb250cmFjdCBhZGRyZXNzIGZvcm1hdCcpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0aHJvdyBlcnJvciB3aGVuIGJ1aWxkaW5nIHdpdGhvdXQgSVBGUyBoYXNoJywgKCkgPT4ge1xuICAgICAgY29uc3QgYnVpbGRlciA9IG5ldyBVcGxvYWRLeWNCdWlsZGVyKGNvaW5Db25maWcpO1xuXG4gICAgICAoKCkgPT4gYnVpbGRlci5idWlsZCgpKS5zaG91bGQudGhyb3coJ01pc3NpbmcgSVBGUyBoYXNoIGZvciB1cGxvYWRLWUMgdHJhbnNhY3Rpb24nKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgbm9ybWFsaXplIGNvbnRyYWN0IGFkZHJlc3Mgd2l0aCAweCBwcmVmaXgnLCAoKSA9PiB7XG4gICAgICBjb25zdCBidWlsZGVyID0gbmV3IFVwbG9hZEt5Y0J1aWxkZXIoY29pbkNvbmZpZyk7XG4gICAgICBjb25zdCBpcGZzSGFzaCA9ICdRbVRlc3RIYXNoMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzJztcbiAgICAgIGNvbnN0IGFkZHJlc3NXaXRob3V0UHJlZml4ID0gJzEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAnO1xuXG4gICAgICBjb25zdCBjYWxsID0gYnVpbGRlci5pcGZzSGFzaChpcGZzSGFzaCkuY29udHJhY3RBZGRyZXNzKGFkZHJlc3NXaXRob3V0UHJlZml4KS5idWlsZCgpO1xuXG4gICAgICBjYWxsLmNvbnRyYWN0QWRkcmVzcy5zaG91bGQuZXF1YWwoJzB4JyArIGFkZHJlc3NXaXRob3V0UHJlZml4KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ1VwbG9hZEt5Y0NhbGwnLCAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCBzZXJpYWxpemUgdXBsb2FkS1lDIGNhbGwgY29ycmVjdGx5JywgKCkgPT4ge1xuICAgICAgY29uc3QgaXBmc0hhc2ggPSAnUW1UZXN0SVBGU0hhc2gxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4JztcbiAgICAgIGNvbnN0IGNvbnRyYWN0QWRkcmVzcyA9IFhEQ19WQUxJREFUT1JfQ09OVFJBQ1RfQUREUkVTU19URVNUTkVUO1xuXG4gICAgICBjb25zdCBjYWxsID0gbmV3IFVwbG9hZEt5Y0NhbGwoY29udHJhY3RBZGRyZXNzLCBpcGZzSGFzaCk7XG4gICAgICBjb25zdCBzZXJpYWxpemVkID0gY2FsbC5zZXJpYWxpemUoKTtcblxuICAgICAgc2hvdWxkLmV4aXN0KHNlcmlhbGl6ZWQpO1xuICAgICAgc2VyaWFsaXplZC5zaG91bGQuYmUudHlwZSgnc3RyaW5nJyk7XG4gICAgICAvLyBTaG91bGQgc3RhcnQgd2l0aCB0aGUgbWV0aG9kIElEXG4gICAgICBzZXJpYWxpemVkLnNob3VsZC5zdGFydFdpdGgoVVBMT0FEX0tZQ19NRVRIT0RfSUQpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBoYXZlIGNvcnJlY3QgcHJvcGVydGllcycsICgpID0+IHtcbiAgICAgIGNvbnN0IGlwZnNIYXNoID0gJ1FtVGVzdElQRlNIYXNoMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3OCc7XG4gICAgICBjb25zdCBjb250cmFjdEFkZHJlc3MgPSAnMHgwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDg4JztcblxuICAgICAgY29uc3QgY2FsbCA9IG5ldyBVcGxvYWRLeWNDYWxsKGNvbnRyYWN0QWRkcmVzcywgaXBmc0hhc2gpO1xuXG4gICAgICBjYWxsLmNvbnRyYWN0QWRkcmVzcy5zaG91bGQuZXF1YWwoY29udHJhY3RBZGRyZXNzKTtcbiAgICAgIGNhbGwuaXBmc0hhc2guc2hvdWxkLmVxdWFsKGlwZnNIYXNoKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ1RyYW5zYWN0aW9uQnVpbGRlciBpbnRlZ3JhdGlvbicsICgpID0+IHtcbiAgICBpdCgnc2hvdWxkIGJ1aWxkIHVwbG9hZEtZQyB0cmFuc2FjdGlvbiB3aXRoIFRyYW5zYWN0aW9uQnVpbGRlcicsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHR4QnVpbGRlciA9IGdldEJ1aWxkZXIoJ3R4ZGMnKTtcbiAgICAgIGNvbnN0IGlwZnNIYXNoID0gJ1FtVGVzdElQRlNIYXNoMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3OCc7XG5cbiAgICAgIHR4QnVpbGRlci50eXBlKFRyYW5zYWN0aW9uVHlwZS5Db250cmFjdENhbGwpO1xuICAgICAgdHhCdWlsZGVyLmZlZSh7XG4gICAgICAgIGZlZTogJzEwMDAwMDAwMDAwJyxcbiAgICAgICAgZ2FzTGltaXQ6ICcxMDAwMDAnLFxuICAgICAgfSk7XG4gICAgICB0eEJ1aWxkZXIuY291bnRlcigxKTtcbiAgICAgIHR4QnVpbGRlci51cGxvYWRLeWMoKS5pcGZzSGFzaChpcGZzSGFzaCk7XG5cbiAgICAgIGNvbnN0IHR4ID0gYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCk7XG5cbiAgICAgIHNob3VsZC5leGlzdCh0eCk7XG4gICAgICBjb25zdCB0eEpzb24gPSB0eC50b0pzb24oKTtcbiAgICAgIHNob3VsZC5leGlzdCh0eEpzb24udG8pO1xuICAgICAgdHhKc29uLnRvIS5zaG91bGQuZXF1YWwoWERDX1ZBTElEQVRPUl9DT05UUkFDVF9BRERSRVNTX1RFU1RORVQpO1xuICAgICAgdHhKc29uLnZhbHVlLnNob3VsZC5lcXVhbCgnMCcpO1xuICAgICAgc2hvdWxkLmV4aXN0KHR4SnNvbi5kYXRhKTtcbiAgICAgIC8vIERhdGEgc2hvdWxkIHN0YXJ0IHdpdGggdXBsb2FkS1lDIG1ldGhvZCBJRFxuICAgICAgdHhKc29uLmRhdGEuc2hvdWxkLnN0YXJ0V2l0aChVUExPQURfS1lDX01FVEhPRF9JRCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IGVycm9yIHdoZW4gdXBsb2FkS3ljKCkgaXMgY2FsbGVkIG9uIG5vbi1Db250cmFjdENhbGwgdHJhbnNhY3Rpb24nLCAoKSA9PiB7XG4gICAgICBjb25zdCB0eEJ1aWxkZXIgPSBnZXRCdWlsZGVyKCd0eGRjJyk7XG5cbiAgICAgIHR4QnVpbGRlci50eXBlKFRyYW5zYWN0aW9uVHlwZS5TZW5kKTtcblxuICAgICAgKCgpID0+IHR4QnVpbGRlci51cGxvYWRLeWMoKSkuc2hvdWxkLnRocm93KCd1cGxvYWRLWUMgY2FuIG9ubHkgYmUgc2V0IGZvciBjb250cmFjdCBjYWxsIHRyYW5zYWN0aW9ucycpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBidWlsZCB0cmFuc2FjdGlvbiB3aXRoIGN1c3RvbSB2YWxpZGF0b3IgY29udHJhY3QgYWRkcmVzcycsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHR4QnVpbGRlciA9IGdldEJ1aWxkZXIoJ3R4ZGMnKTtcbiAgICAgIGNvbnN0IGlwZnNIYXNoID0gJ1FtQ3VzdG9tSVBGU0hhc2gxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1NjcnO1xuICAgICAgY29uc3QgY3VzdG9tQWRkcmVzcyA9ICcweDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAnO1xuXG4gICAgICB0eEJ1aWxkZXIudHlwZShUcmFuc2FjdGlvblR5cGUuQ29udHJhY3RDYWxsKTtcbiAgICAgIHR4QnVpbGRlci5mZWUoe1xuICAgICAgICBmZWU6ICcxMDAwMDAwMDAwMCcsXG4gICAgICAgIGdhc0xpbWl0OiAnMTAwMDAwJyxcbiAgICAgIH0pO1xuICAgICAgdHhCdWlsZGVyLmNvdW50ZXIoMSk7XG4gICAgICB0eEJ1aWxkZXIudXBsb2FkS3ljKCkuaXBmc0hhc2goaXBmc0hhc2gpLmNvbnRyYWN0QWRkcmVzcyhjdXN0b21BZGRyZXNzKTtcblxuICAgICAgY29uc3QgdHggPSBhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKTtcblxuICAgICAgc2hvdWxkLmV4aXN0KHR4KTtcbiAgICAgIGNvbnN0IHR4SnNvbiA9IHR4LnRvSnNvbigpO1xuICAgICAgc2hvdWxkLmV4aXN0KHR4SnNvbi50byk7XG4gICAgICB0eEpzb24udG8hLnNob3VsZC5lcXVhbChjdXN0b21BZGRyZXNzKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgYnVpbGQgYW5kIHNlcmlhbGl6ZSB1cGxvYWRLWUMgdHJhbnNhY3Rpb24nLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCB0eEJ1aWxkZXIgPSBnZXRCdWlsZGVyKCd0eGRjJyk7XG4gICAgICBjb25zdCBpcGZzSGFzaCA9ICdRbVJlYWxJUEZTSGFzaEZvclNlcmlhbGl6YXRpb24xMjM0NTY3ODkwMTIzJztcblxuICAgICAgdHhCdWlsZGVyLnR5cGUoVHJhbnNhY3Rpb25UeXBlLkNvbnRyYWN0Q2FsbCk7XG4gICAgICB0eEJ1aWxkZXIuZmVlKHtcbiAgICAgICAgZmVlOiAnMTAwMDAwMDAwMDAnLFxuICAgICAgICBnYXNMaW1pdDogJzEwMDAwMCcsXG4gICAgICB9KTtcbiAgICAgIHR4QnVpbGRlci5jb3VudGVyKDUpO1xuICAgICAgdHhCdWlsZGVyLnVwbG9hZEt5YygpLmlwZnNIYXNoKGlwZnNIYXNoKTtcblxuICAgICAgY29uc3QgdHggPSBhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKTtcbiAgICAgIGNvbnN0IHNlcmlhbGl6ZWQgPSB0eC50b0Jyb2FkY2FzdEZvcm1hdCgpO1xuXG4gICAgICBzaG91bGQuZXhpc3Qoc2VyaWFsaXplZCk7XG4gICAgICBzZXJpYWxpemVkLnNob3VsZC5iZS50eXBlKCdzdHJpbmcnKTtcbiAgICAgIC8vIFNob3VsZCBiZSBhIHZhbGlkIGhleCBzdHJpbmdcbiAgICAgIHNlcmlhbGl6ZWQuc2hvdWxkLm1hdGNoKC9eKDB4KT9bMC05YS1mXSskL2kpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBwYXJzZSB1cGxvYWRLWUMgdHJhbnNhY3Rpb24gZnJvbSBoZXgnLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCB0eEJ1aWxkZXIgPSBnZXRCdWlsZGVyKCd0eGRjJyk7XG4gICAgICBjb25zdCBpcGZzSGFzaCA9ICdRbVBhcnNlVGVzdEhhc2gxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Nic7XG5cbiAgICAgIC8vIEZpcnN0IGJ1aWxkIGEgdHJhbnNhY3Rpb25cbiAgICAgIHR4QnVpbGRlci50eXBlKFRyYW5zYWN0aW9uVHlwZS5Db250cmFjdENhbGwpO1xuICAgICAgdHhCdWlsZGVyLmZlZSh7XG4gICAgICAgIGZlZTogJzEwMDAwMDAwMDAwJyxcbiAgICAgICAgZ2FzTGltaXQ6ICcxMDAwMDAnLFxuICAgICAgfSk7XG4gICAgICB0eEJ1aWxkZXIuY291bnRlcigxMCk7XG4gICAgICB0eEJ1aWxkZXIudXBsb2FkS3ljKCkuaXBmc0hhc2goaXBmc0hhc2gpO1xuXG4gICAgICBjb25zdCB0eCA9IGF3YWl0IHR4QnVpbGRlci5idWlsZCgpO1xuICAgICAgY29uc3Qgc2VyaWFsaXplZCA9IHR4LnRvQnJvYWRjYXN0Rm9ybWF0KCk7XG5cbiAgICAgIC8vIE5vdyBwYXJzZSBpdCBiYWNrXG4gICAgICBjb25zdCB0eEJ1aWxkZXIyID0gZ2V0QnVpbGRlcigndHhkYycpO1xuICAgICAgdHhCdWlsZGVyMi5mcm9tKHNlcmlhbGl6ZWQpO1xuICAgICAgY29uc3QgcGFyc2VkVHggPSBhd2FpdCB0eEJ1aWxkZXIyLmJ1aWxkKCk7XG5cbiAgICAgIHNob3VsZC5leGlzdChwYXJzZWRUeCk7XG4gICAgICBjb25zdCBwYXJzZWRKc29uID0gcGFyc2VkVHgudG9Kc29uKCk7XG4gICAgICBzaG91bGQuZXhpc3QocGFyc2VkSnNvbi50byk7XG4gICAgICBwYXJzZWRKc29uLnRvIS5zaG91bGQuZXF1YWwoWERDX1ZBTElEQVRPUl9DT05UUkFDVF9BRERSRVNTX1RFU1RORVQpO1xuICAgICAgcGFyc2VkSnNvbi5ub25jZS5zaG91bGQuZXF1YWwoMTApO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnUmVhbC13b3JsZCBzY2VuYXJpb3MnLCAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCBjcmVhdGUgdHJhbnNhY3Rpb24gbWF0Y2hpbmcgc2FuZGJveCBjb2RlIHBhdHRlcm4nLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCB0eEJ1aWxkZXIgPSBnZXRCdWlsZGVyKCd0eGRjJyk7XG4gICAgICAvLyBNb2NrIElQRlMgaGFzaCBzaW1pbGFyIHRvIHdoYXQgd291bGQgYmUgZ2VuZXJhdGVkXG4gICAgICBjb25zdCBtb2NrSVBGU0hhc2ggPSAnUW0nICsgJ2EnLnJlcGVhdCg0NCk7XG5cbiAgICAgIHR4QnVpbGRlci50eXBlKFRyYW5zYWN0aW9uVHlwZS5Db250cmFjdENhbGwpO1xuICAgICAgdHhCdWlsZGVyLmZlZSh7XG4gICAgICAgIGZlZTogJzIwMDAwMDAwMDAwJyxcbiAgICAgICAgZ2FzTGltaXQ6ICcyMDAwMDAnLFxuICAgICAgfSk7XG4gICAgICB0eEJ1aWxkZXIuY291bnRlcigwKTtcbiAgICAgIHR4QnVpbGRlci51cGxvYWRLeWMoKS5pcGZzSGFzaChtb2NrSVBGU0hhc2gpO1xuXG4gICAgICBjb25zdCB0eCA9IGF3YWl0IHR4QnVpbGRlci5idWlsZCgpO1xuICAgICAgY29uc3QgdHhKc29uID0gdHgudG9Kc29uKCk7XG5cbiAgICAgIC8vIFZlcmlmeSB0cmFuc2FjdGlvbiBzdHJ1Y3R1cmUgbWF0Y2hlcyBleHBlY3RlZCBmb3JtYXRcbiAgICAgIHNob3VsZC5leGlzdCh0eEpzb24udG8pO1xuICAgICAgdHhKc29uLnRvIS5zaG91bGQuZXF1YWwoWERDX1ZBTElEQVRPUl9DT05UUkFDVF9BRERSRVNTX1RFU1RORVQpO1xuICAgICAgdHhKc29uLnZhbHVlLnNob3VsZC5lcXVhbCgnMCcpO1xuICAgICAgc2hvdWxkLmV4aXN0KHR4SnNvbi5kYXRhKTtcbiAgICAgIHR4SnNvbi5kYXRhLnNob3VsZC5zdGFydFdpdGgoVVBMT0FEX0tZQ19NRVRIT0RfSUQpO1xuICAgICAgc2hvdWxkLmV4aXN0KHR4SnNvbi5nYXNMaW1pdCk7XG4gICAgICBzaG91bGQuZXhpc3QodHhKc29uLm5vbmNlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgaGFuZGxlIG11bHRpcGxlIElQRlMgaGFzaCBmb3JtYXRzJywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgdGVzdEhhc2hlcyA9IFtcbiAgICAgICAgJ1FtUmVhbElQRlNIYXNoRXhhbXBsZTEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNCcsIC8vIHYwXG4gICAgICAgICdiYWZ5YmVpZ2R5cnp0NXNmcDd1ZG03aHU3NnVoN3kyNm5mM2VmdXlscWFiZjNvY2xndHF5NTVmYnpkaScsIC8vIHYxXG4gICAgICAgICdRbVl3QVBKenY1Q1pzbkE2MjVzM1hmMm5lbXRZZ1BwSGRXRXo3OW9qV25QYmRHJywgLy8gcmVhbCBleGFtcGxlXG4gICAgICBdO1xuXG4gICAgICBmb3IgKGNvbnN0IGhhc2ggb2YgdGVzdEhhc2hlcykge1xuICAgICAgICBjb25zdCB0eEJ1aWxkZXIgPSBnZXRCdWlsZGVyKCd0eGRjJyk7XG5cbiAgICAgICAgdHhCdWlsZGVyLnR5cGUoVHJhbnNhY3Rpb25UeXBlLkNvbnRyYWN0Q2FsbCk7XG4gICAgICAgIHR4QnVpbGRlci5mZWUoe1xuICAgICAgICAgIGZlZTogJzEwMDAwMDAwMDAwJyxcbiAgICAgICAgICBnYXNMaW1pdDogJzEwMDAwMCcsXG4gICAgICAgIH0pO1xuICAgICAgICB0eEJ1aWxkZXIuY291bnRlcigxKTtcbiAgICAgICAgdHhCdWlsZGVyLnVwbG9hZEt5YygpLmlwZnNIYXNoKGhhc2gpO1xuXG4gICAgICAgIGNvbnN0IHR4ID0gYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCk7XG4gICAgICAgIHNob3VsZC5leGlzdCh0eCk7XG5cbiAgICAgICAgY29uc3QgdHhKc29uID0gdHgudG9Kc29uKCk7XG4gICAgICAgIHR4SnNvbi5kYXRhLnNob3VsZC5zdGFydFdpdGgoVVBMT0FEX0tZQ19NRVRIT0RfSUQpO1xuICAgICAgfVxuICAgIH0pO1xuICB9KTtcbn0pO1xuIl19
|