@bitgo/sdk-core 38.18.0 → 38.20.0
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/account-lib/baseCoin/enum.d.ts +2 -1
- package/dist/src/account-lib/baseCoin/enum.d.ts.map +1 -1
- package/dist/src/account-lib/baseCoin/enum.js +4 -1
- package/dist/src/bitgo/baseCoin/iBaseCoin.d.ts +5 -0
- package/dist/src/bitgo/baseCoin/iBaseCoin.d.ts.map +1 -1
- package/dist/src/bitgo/baseCoin/iBaseCoin.js +1 -1
- package/dist/src/bitgo/coinFactory.d.ts +7 -0
- package/dist/src/bitgo/coinFactory.d.ts.map +1 -1
- package/dist/src/bitgo/coinFactory.js +10 -1
- package/dist/src/bitgo/environments.js +2 -2
- package/dist/src/bitgo/index.d.ts +1 -0
- package/dist/src/bitgo/index.d.ts.map +1 -1
- package/dist/src/bitgo/index.js +2 -1
- package/dist/src/bitgo/keychain/iKeychains.d.ts +28 -0
- package/dist/src/bitgo/keychain/iKeychains.d.ts.map +1 -1
- package/dist/src/bitgo/keychain/iKeychains.js +1 -1
- package/dist/src/bitgo/keychain/keychains.d.ts +51 -6
- package/dist/src/bitgo/keychain/keychains.d.ts.map +1 -1
- package/dist/src/bitgo/keychain/keychains.js +104 -24
- package/dist/src/bitgo/safe/iSafe.d.ts +32 -3
- package/dist/src/bitgo/safe/iSafe.d.ts.map +1 -1
- package/dist/src/bitgo/safe/iSafe.js +1 -1
- package/dist/src/bitgo/safe/rootCoin.d.ts +15 -0
- package/dist/src/bitgo/safe/rootCoin.d.ts.map +1 -0
- package/dist/src/bitgo/safe/rootCoin.js +47 -0
- package/dist/src/bitgo/safe/safe.d.ts +17 -1
- package/dist/src/bitgo/safe/safe.d.ts.map +1 -1
- package/dist/src/bitgo/safe/safe.js +129 -14
- package/dist/src/bitgo/safe/safes.d.ts +0 -5
- package/dist/src/bitgo/safe/safes.d.ts.map +1 -1
- package/dist/src/bitgo/safe/safes.js +6 -42
- package/dist/src/bitgo/utils/messageTypes.d.ts +6 -0
- package/dist/src/bitgo/utils/messageTypes.d.ts.map +1 -1
- package/dist/src/bitgo/utils/messageTypes.js +8 -2
- package/dist/src/bitgo/utils/mpcUtils.d.ts.map +1 -1
- package/dist/src/bitgo/utils/mpcUtils.js +19 -1
- package/dist/src/bitgo/utils/tss/baseTSSUtils.d.ts.map +1 -1
- package/dist/src/bitgo/utils/tss/baseTSSUtils.js +6 -1
- package/dist/src/bitgo/utils/tss/baseTypes.d.ts +17 -0
- package/dist/src/bitgo/utils/tss/baseTypes.d.ts.map +1 -1
- package/dist/src/bitgo/utils/tss/baseTypes.js +1 -1
- package/dist/src/bitgo/utils/tss/ecdsa/ecdsaMPCv2.d.ts +6 -2
- package/dist/src/bitgo/utils/tss/ecdsa/ecdsaMPCv2.d.ts.map +1 -1
- package/dist/src/bitgo/utils/tss/ecdsa/ecdsaMPCv2.js +18 -14
- package/dist/src/bitgo/utils/tss/ecdsa/ecdsaVrfMPCv2.d.ts +0 -19
- package/dist/src/bitgo/utils/tss/ecdsa/ecdsaVrfMPCv2.d.ts.map +1 -1
- package/dist/src/bitgo/utils/tss/ecdsa/ecdsaVrfMPCv2.js +4 -64
- package/dist/src/bitgo/utils/tss/eddsa/SMC/utils.d.ts +2 -2
- package/dist/src/bitgo/utils/tss/eddsa/SMC/utils.d.ts.map +1 -1
- package/dist/src/bitgo/utils/tss/eddsa/SMC/utils.js +5 -4
- package/dist/src/bitgo/utils/tss/eddsa/eddsaMPCv2.d.ts +32 -6
- package/dist/src/bitgo/utils/tss/eddsa/eddsaMPCv2.d.ts.map +1 -1
- package/dist/src/bitgo/utils/tss/eddsa/eddsaMPCv2.js +56 -13
- package/dist/src/bitgo/utils/tss/eddsa/eddsaMPCv2KeyGenSender.d.ts +7 -2
- package/dist/src/bitgo/utils/tss/eddsa/eddsaMPCv2KeyGenSender.d.ts.map +1 -1
- package/dist/src/bitgo/utils/tss/eddsa/eddsaMPCv2KeyGenSender.js +11 -1
- package/dist/src/bitgo/utils/tss/eddsa/eddsaVrfMPCv2.d.ts +20 -9
- package/dist/src/bitgo/utils/tss/eddsa/eddsaVrfMPCv2.d.ts.map +1 -1
- package/dist/src/bitgo/utils/tss/eddsa/eddsaVrfMPCv2.js +58 -23
- package/dist/src/bitgo/utils/tss/eddsa/types.d.ts +3 -0
- package/dist/src/bitgo/utils/tss/eddsa/types.d.ts.map +1 -1
- package/dist/src/bitgo/utils/tss/eddsa/types.js +1 -1
- package/dist/src/bitgo/utils/tss/eddsa/typesEddsaMPCv2.d.ts +3 -0
- package/dist/src/bitgo/utils/tss/eddsa/typesEddsaMPCv2.d.ts.map +1 -1
- package/dist/src/bitgo/utils/tss/eddsa/typesEddsaMPCv2.js +1 -1
- package/dist/src/bitgo/utils/tss/index.d.ts +1 -0
- package/dist/src/bitgo/utils/tss/index.d.ts.map +1 -1
- package/dist/src/bitgo/utils/tss/index.js +2 -1
- package/dist/src/bitgo/utils/tss/keyShareEnvelope.d.ts +40 -0
- package/dist/src/bitgo/utils/tss/keyShareEnvelope.d.ts.map +1 -0
- package/dist/src/bitgo/utils/tss/keyShareEnvelope.js +103 -0
- package/dist/src/bitgo/utils/tss/recipientUtils.d.ts +2 -1
- package/dist/src/bitgo/utils/tss/recipientUtils.d.ts.map +1 -1
- package/dist/src/bitgo/utils/tss/recipientUtils.js +9 -3
- package/dist/src/bitgo/wallet/BuildParams.d.ts +1 -0
- package/dist/src/bitgo/wallet/BuildParams.d.ts.map +1 -1
- package/dist/src/bitgo/wallet/BuildParams.js +3 -1
- package/dist/src/bitgo/wallet/iWallet.d.ts +24 -0
- package/dist/src/bitgo/wallet/iWallet.d.ts.map +1 -1
- package/dist/src/bitgo/wallet/iWallet.js +1 -1
- package/dist/src/bitgo/wallet/wallet.d.ts.map +1 -1
- package/dist/src/bitgo/wallet/wallet.js +33 -4
- package/dist/src/bitgo/webauthn/base64url.d.ts +16 -0
- package/dist/src/bitgo/webauthn/base64url.d.ts.map +1 -0
- package/dist/src/bitgo/webauthn/base64url.js +27 -0
- package/dist/src/bitgo/webauthn/deriveEnterpriseSalt.d.ts +18 -0
- package/dist/src/bitgo/webauthn/deriveEnterpriseSalt.d.ts.map +1 -0
- package/dist/src/bitgo/webauthn/deriveEnterpriseSalt.js +26 -0
- package/dist/src/bitgo/webauthn/derivePassword.d.ts +11 -0
- package/dist/src/bitgo/webauthn/derivePassword.d.ts.map +1 -0
- package/dist/src/bitgo/webauthn/derivePassword.js +16 -0
- package/dist/src/bitgo/webauthn/index.d.ts +5 -0
- package/dist/src/bitgo/webauthn/index.d.ts.map +1 -0
- package/dist/src/bitgo/webauthn/index.js +21 -0
- package/dist/src/bitgo/webauthn/types.d.ts +18 -0
- package/dist/src/bitgo/webauthn/types.d.ts.map +1 -0
- package/dist/src/bitgo/webauthn/types.js +3 -0
- package/dist/test/unit/bitgo/keychain/keychains.js +261 -1
- package/dist/test/unit/bitgo/recovery/initiate.js +30 -1
- package/dist/test/unit/bitgo/safe/safe.js +185 -2
- package/dist/test/unit/bitgo/utils/mpcUtils.unwrap.d.ts +2 -0
- package/dist/test/unit/bitgo/utils/mpcUtils.unwrap.d.ts.map +1 -0
- package/dist/test/unit/bitgo/utils/mpcUtils.unwrap.js +109 -0
- package/dist/test/unit/bitgo/utils/tss/eddsa/eddsaMPCv2.js +76 -1
- package/dist/test/unit/bitgo/utils/tss/eddsa/eddsaVrfMPCv2.js +227 -20
- package/dist/test/unit/bitgo/utils/tss/eddsa/smcUtil.js +66 -1
- package/dist/test/unit/bitgo/utils/tss/keyShareEnvelope.d.ts +2 -0
- package/dist/test/unit/bitgo/utils/tss/keyShareEnvelope.d.ts.map +1 -0
- package/dist/test/unit/bitgo/utils/tss/keyShareEnvelope.js +83 -0
- package/dist/test/unit/bitgo/utils/tss/recipientUtils.js +29 -1
- package/dist/test/unit/bitgo/wallet/BuildParams.js +14 -1
- package/dist/test/unit/bitgo/wallet/tokenApproval.js +10 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +6 -6
|
@@ -37,12 +37,18 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
37
37
|
};
|
|
38
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
39
|
const assert_1 = __importDefault(require("assert"));
|
|
40
|
+
const pgp = __importStar(require("openpgp"));
|
|
41
|
+
const sinon = __importStar(require("sinon"));
|
|
42
|
+
const sdk_lib_mpc_1 = require("@bitgo/sdk-lib-mpc");
|
|
43
|
+
const public_types_1 = require("@bitgo/public-types");
|
|
40
44
|
const cbor_x_1 = require("cbor-x");
|
|
41
45
|
const t = __importStar(require("io-ts"));
|
|
42
46
|
const src_1 = require("../../../../../../src");
|
|
43
47
|
const codecs_1 = require("../../../../../../src/bitgo/utils/codecs");
|
|
48
|
+
const keyShareEnvelope_1 = require("../../../../../../src/bitgo/utils/tss/keyShareEnvelope");
|
|
44
49
|
const eddsaVrfMPCv2_1 = require("../../../../../../src/bitgo/utils/tss/eddsa/eddsaVrfMPCv2");
|
|
45
50
|
const typesMPCv2_1 = require("../../../../../../src/bitgo/utils/tss/ecdsa/typesMPCv2");
|
|
51
|
+
const opengpgUtils_1 = require("../../../../../../src/bitgo/utils/opengpgUtils");
|
|
46
52
|
const Uint8ArrayCodec = new t.Type('Uint8Array', (value) => value instanceof Uint8Array, (value, context) => (value instanceof Uint8Array ? t.success(value) : t.failure(value, context)), t.identity);
|
|
47
53
|
const VrfEnvelope = t.type({
|
|
48
54
|
version: t.literal(1),
|
|
@@ -52,12 +58,36 @@ const VrfEnvelope = t.type({
|
|
|
52
58
|
function decodeVrfEnvelope(encoded) {
|
|
53
59
|
return (0, codecs_1.decodeWithCodec)(VrfEnvelope, (0, cbor_x_1.decode)(encoded), 'VRF key envelope');
|
|
54
60
|
}
|
|
61
|
+
function createKeychainFixture() {
|
|
62
|
+
const encryptedInputs = [];
|
|
63
|
+
const addedKeychains = [];
|
|
64
|
+
const post = sinon.stub();
|
|
65
|
+
const bitgo = {
|
|
66
|
+
getEnv: () => 'dev',
|
|
67
|
+
url: (path) => path,
|
|
68
|
+
post,
|
|
69
|
+
encrypt: async (params) => {
|
|
70
|
+
encryptedInputs.push(params.input);
|
|
71
|
+
return `encrypted:${params.input}`;
|
|
72
|
+
},
|
|
73
|
+
};
|
|
74
|
+
const keychains = {
|
|
75
|
+
add: async (params) => {
|
|
76
|
+
addedKeychains.push(params);
|
|
77
|
+
return { id: `${params.source}-child`, type: 'tss', encryptedPrv: params.encryptedPrv };
|
|
78
|
+
},
|
|
79
|
+
};
|
|
80
|
+
const baseCoin = {
|
|
81
|
+
keychains: () => keychains,
|
|
82
|
+
};
|
|
83
|
+
return { bitgo, baseCoin, post, encryptedInputs, addedKeychains };
|
|
84
|
+
}
|
|
55
85
|
describe('EdDSA MPCv2 VRF root material', function () {
|
|
56
86
|
it('encodes signing and VRF shares in both full and reduced envelopes', function () {
|
|
57
87
|
const privateMaterial = Buffer.from('signing-share');
|
|
58
88
|
const reducedPrivateMaterial = Buffer.from('reduced-signing-share');
|
|
59
89
|
const vrfKeyShare = Buffer.from('vrf-share');
|
|
60
|
-
const { envelope, reducedEnvelope } = (0,
|
|
90
|
+
const { envelope, reducedEnvelope } = (0, keyShareEnvelope_1.buildSafeMpcKeyEnvelopes)(privateMaterial, reducedPrivateMaterial, vrfKeyShare);
|
|
61
91
|
const decodedEnvelope = decodeVrfEnvelope(envelope);
|
|
62
92
|
const decodedReducedEnvelope = decodeVrfEnvelope(reducedEnvelope);
|
|
63
93
|
assert_1.default.deepStrictEqual(Buffer.from(decodedEnvelope.prvKeyShare), privateMaterial);
|
|
@@ -66,23 +96,7 @@ describe('EdDSA MPCv2 VRF root material', function () {
|
|
|
66
96
|
assert_1.default.deepStrictEqual(Buffer.from(decodedReducedEnvelope.vrf), vrfKeyShare);
|
|
67
97
|
});
|
|
68
98
|
it('keeps ordinary MPCv2 participant material as bare base64', async function () {
|
|
69
|
-
const encryptedInputs =
|
|
70
|
-
const addedKeychains = [];
|
|
71
|
-
const bitgo = {
|
|
72
|
-
encrypt: async (params) => {
|
|
73
|
-
encryptedInputs.push(params.input);
|
|
74
|
-
return `encrypted:${params.input}`;
|
|
75
|
-
},
|
|
76
|
-
};
|
|
77
|
-
const keychains = {
|
|
78
|
-
add: async (params) => {
|
|
79
|
-
addedKeychains.push(params);
|
|
80
|
-
return { id: 'user-key' };
|
|
81
|
-
},
|
|
82
|
-
};
|
|
83
|
-
const baseCoin = {
|
|
84
|
-
keychains: () => keychains,
|
|
85
|
-
};
|
|
99
|
+
const { bitgo, baseCoin, encryptedInputs, addedKeychains } = createKeychainFixture();
|
|
86
100
|
const utils = new src_1.EddsaMPCv2Utils(bitgo, baseCoin);
|
|
87
101
|
const privateMaterial = Buffer.from('signing-share');
|
|
88
102
|
const reducedPrivateMaterial = Buffer.from('reduced-signing-share');
|
|
@@ -94,6 +108,13 @@ describe('EdDSA MPCv2 VRF root material', function () {
|
|
|
94
108
|
assert_1.default.strictEqual(addedKeychains[0].encryptedPrv, `encrypted:${privateMaterial.toString('base64')}`);
|
|
95
109
|
assert_1.default.strictEqual(addedKeychains[0].safeId, undefined);
|
|
96
110
|
});
|
|
111
|
+
it('rejects a public-only backup outside a safe child derivation', async function () {
|
|
112
|
+
const { bitgo, baseCoin, encryptedInputs, addedKeychains } = createKeychainFixture();
|
|
113
|
+
const utils = new src_1.EddsaMPCv2Utils(bitgo, baseCoin);
|
|
114
|
+
await assert_1.default.rejects(utils.createParticipantKeychain(typesMPCv2_1.MPCv2PartiesEnum.BACKUP, 'common-keychain', undefined, undefined, 'passphrase'), /Private material is required for backup keychain/);
|
|
115
|
+
assert_1.default.deepStrictEqual(encryptedInputs, []);
|
|
116
|
+
assert_1.default.deepStrictEqual(addedKeychains, []);
|
|
117
|
+
});
|
|
97
118
|
it('encrypts the VRF envelope and tags the keychain with safeId', async function () {
|
|
98
119
|
const encryptedInputs = [];
|
|
99
120
|
const addedKeychains = [];
|
|
@@ -113,7 +134,7 @@ describe('EdDSA MPCv2 VRF root material', function () {
|
|
|
113
134
|
keychains: () => keychains,
|
|
114
135
|
};
|
|
115
136
|
const utils = new src_1.EddsaMPCv2Utils(bitgo, baseCoin);
|
|
116
|
-
const { envelope, reducedEnvelope } = (0,
|
|
137
|
+
const { envelope, reducedEnvelope } = (0, keyShareEnvelope_1.buildSafeMpcKeyEnvelopes)(Buffer.from('signing-share'), Buffer.from('reduced-signing-share'), Buffer.from('vrf-share'));
|
|
117
138
|
await utils.createParticipantKeychain(typesMPCv2_1.MPCv2PartiesEnum.USER, 'common-keychain', envelope, reducedEnvelope, 'passphrase', undefined, undefined, undefined, undefined, 'safe-id');
|
|
118
139
|
assert_1.default.deepStrictEqual(encryptedInputs[0], envelope.toString('base64'));
|
|
119
140
|
assert_1.default.strictEqual(addedKeychains[0].safeId, 'safe-id');
|
|
@@ -170,4 +191,190 @@ describe('EdDSA MPCv2 VRF root material', function () {
|
|
|
170
191
|
assert_1.default.throws(() => (0, eddsaVrfMPCv2_1.deserializeVrfMessages)(badParty, typesMPCv2_1.MPCv2PartiesEnum.USER), /VRF DKG message blob/);
|
|
171
192
|
});
|
|
172
193
|
});
|
|
173
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWRkc2FWcmZNUEN2Mi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Rlc3QvdW5pdC9iaXRnby91dGlscy90c3MvZWRkc2EvZWRkc2FWcmZNUEN2Mi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLG9EQUE0QjtBQUM1QixtQ0FBZ0M7QUFDaEMseUNBQTJCO0FBRTNCLCtDQUF3RjtBQUN4RixxRUFBMkU7QUFDM0UsNkZBSW1FO0FBQ25FLHVGQUEwRjtBQUUxRixNQUFNLGVBQWUsR0FBRyxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQ2hDLFlBQVksRUFDWixDQUFDLEtBQUssRUFBdUIsRUFBRSxDQUFDLEtBQUssWUFBWSxVQUFVLEVBQzNELENBQUMsS0FBSyxFQUFFLE9BQU8sRUFBRSxFQUFFLENBQUMsQ0FBQyxLQUFLLFlBQVksVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLEtBQUssRUFBRSxPQUFPLENBQUMsQ0FBQyxFQUNoRyxDQUFDLENBQUMsUUFBUSxDQUNYLENBQUM7QUFFRixNQUFNLFdBQVcsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDO0lBQ3pCLE9BQU8sRUFBRSxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQztJQUNyQixXQUFXLEVBQUUsZUFBZTtJQUM1QixHQUFHLEVBQUUsZUFBZTtDQUNyQixDQUFDLENBQUM7QUFRSCxTQUFTLGlCQUFpQixDQUFDLE9BQWU7SUFDeEMsT0FBTyxJQUFBLHdCQUFlLEVBQUMsV0FBVyxFQUFFLElBQUEsZUFBTSxFQUFDLE9BQU8sQ0FBQyxFQUFFLGtCQUFrQixDQUFDLENBQUM7QUFDM0UsQ0FBQztBQUVELFFBQVEsQ0FBQywrQkFBK0IsRUFBRTtJQUN4QyxFQUFFLENBQUMsbUVBQW1F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dCBmcm9tICdhc3NlcnQnO1xuaW1wb3J0IHsgZGVjb2RlIH0gZnJvbSAnY2Jvci14JztcbmltcG9ydCAqIGFzIHQgZnJvbSAnaW8tdHMnO1xuXG5pbXBvcnQgeyBFZGRzYU1QQ3YyVXRpbHMsIEJpdEdvQmFzZSwgSUJhc2VDb2luLCBLZXljaGFpbiB9IGZyb20gJy4uLy4uLy4uLy4uLy4uLy4uL3NyYyc7XG5pbXBvcnQgeyBkZWNvZGVXaXRoQ29kZWMgfSBmcm9tICcuLi8uLi8uLi8uLi8uLi8uLi9zcmMvYml0Z28vdXRpbHMvY29kZWNzJztcbmltcG9ydCB7XG4gIGJ1aWxkVnJmS2V5RW52ZWxvcGVzLFxuICBkZXNlcmlhbGl6ZVZyZk1lc3NhZ2VzLFxuICBzZXJpYWxpemVWcmZNZXNzYWdlcyxcbn0gZnJvbSAnLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2JpdGdvL3V0aWxzL3Rzcy9lZGRzYS9lZGRzYVZyZk1QQ3YyJztcbmltcG9ydCB7IE1QQ3YyUGFydGllc0VudW0gfSBmcm9tICcuLi8uLi8uLi8uLi8uLi8uLi9zcmMvYml0Z28vdXRpbHMvdHNzL2VjZHNhL3R5cGVzTVBDdjInO1xuXG5jb25zdCBVaW50OEFycmF5Q29kZWMgPSBuZXcgdC5UeXBlPFVpbnQ4QXJyYXksIFVpbnQ4QXJyYXksIHVua25vd24+KFxuICAnVWludDhBcnJheScsXG4gICh2YWx1ZSk6IHZhbHVlIGlzIFVpbnQ4QXJyYXkgPT4gdmFsdWUgaW5zdGFuY2VvZiBVaW50OEFycmF5LFxuICAodmFsdWUsIGNvbnRleHQpID0+ICh2YWx1ZSBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkgPyB0LnN1Y2Nlc3ModmFsdWUpIDogdC5mYWlsdXJlKHZhbHVlLCBjb250ZXh0KSksXG4gIHQuaWRlbnRpdHlcbik7XG5cbmNvbnN0IFZyZkVudmVsb3BlID0gdC50eXBlKHtcbiAgdmVyc2lvbjogdC5saXRlcmFsKDEpLFxuICBwcnZLZXlTaGFyZTogVWludDhBcnJheUNvZGVjLFxuICB2cmY6IFVpbnQ4QXJyYXlDb2RlYyxcbn0pO1xuXG50eXBlIEFkZGVkS2V5Y2hhaW5QYXJhbXMgPSB7XG4gIHNvdXJjZT86IHN0cmluZztcbiAgZW5jcnlwdGVkUHJ2Pzogc3RyaW5nO1xuICBzYWZlSWQ/OiBzdHJpbmc7XG59O1xuXG5mdW5jdGlvbiBkZWNvZGVWcmZFbnZlbG9wZShlbmNvZGVkOiBCdWZmZXIpOiB0LlR5cGVPZjx0eXBlb2YgVnJmRW52ZWxvcGU+IHtcbiAgcmV0dXJuIGRlY29kZVdpdGhDb2RlYyhWcmZFbnZlbG9wZSwgZGVjb2RlKGVuY29kZWQpLCAnVlJGIGtleSBlbnZlbG9wZScpO1xufVxuXG5kZXNjcmliZSgnRWREU0EgTVBDdjIgVlJGIHJvb3QgbWF0ZXJpYWwnLCBmdW5jdGlvbiAoKSB7XG4gIGl0KCdlbmNvZGVzIHNpZ25pbmcgYW5kIFZSRiBzaGFyZXMgaW4gYm90aCBmdWxsIGFuZCByZWR1Y2VkIGVudmVsb3BlcycsIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCBwcml2YXRlTWF0ZXJpYWwgPSBCdWZmZXIuZnJvbSgnc2lnbmluZy1zaGFyZScpO1xuICAgIGNvbnN0IHJlZHVjZWRQcml2YXRlTWF0ZXJpYWwgPSBCdWZmZXIuZnJvbSgncmVkdWNlZC1zaWduaW5nLXNoYXJlJyk7XG4gICAgY29uc3QgdnJmS2V5U2hhcmUgPSBCdWZmZXIuZnJvbSgndnJmLXNoYXJlJyk7XG5cbiAgICBjb25zdCB7IGVudmVsb3BlLCByZWR1Y2VkRW52ZWxvcGUgfSA9IGJ1aWxkVnJmS2V5RW52ZWxvcGVzKHByaXZhdGVNYXRlcmlhbCwgcmVkdWNlZFByaXZhdGVNYXRlcmlhbCwgdnJmS2V5U2hhcmUpO1xuICAgIGNvbnN0IGRlY29kZWRFbnZlbG9wZSA9IGRlY29kZVZyZkVudmVsb3BlKGVudmVsb3BlKTtcbiAgICBjb25zdCBkZWNvZGVkUmVkdWNlZEVudmVsb3BlID0gZGVjb2RlVnJmRW52ZWxvcGUocmVkdWNlZEVudmVsb3BlKTtcblxuICAgIGFzc2VydC5kZWVwU3RyaWN0RXF1YWwoQnVmZmVyLmZyb20oZGVjb2RlZEVudmVsb3BlLnBydktleVNoYXJlKSwgcHJpdmF0ZU1hdGVyaWFsKTtcbiAgICBhc3NlcnQuZGVlcFN0cmljdEVxdWFsKEJ1ZmZlci5mcm9tKGRlY29kZWRFbnZlbG9wZS52cmYpLCB2cmZLZXlTaGFyZSk7XG4gICAgYXNzZXJ0LmRlZXBTdHJpY3RFcXVhbChCdWZmZXIuZnJvbShkZWNvZGVkUmVkdWNlZEVudmVsb3BlLnBydktleVNoYXJlKSwgcmVkdWNlZFByaXZhdGVNYXRlcmlhbCk7XG4gICAgYXNzZXJ0LmRlZXBTdHJpY3RFcXVhbChCdWZmZXIuZnJvbShkZWNvZGVkUmVkdWNlZEVudmVsb3BlLnZyZiksIHZyZktleVNoYXJlKTtcbiAgfSk7XG5cbiAgaXQoJ2tlZXBzIG9yZGluYXJ5IE1QQ3YyIHBhcnRpY2lwYW50IG1hdGVyaWFsIGFzIGJhcmUgYmFzZTY0JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IGVuY3J5cHRlZElucHV0czogc3RyaW5nW10gPSBbXTtcbiAgICBjb25zdCBhZGRlZEtleWNoYWluczogQWRkZWRLZXljaGFpblBhcmFtc1tdID0gW107XG4gICAgY29uc3QgYml0Z28gPSB7XG4gICAgICBlbmNyeXB0OiBhc3luYyAocGFyYW1zOiB7IGlucHV0OiBzdHJpbmcgfSk6IFByb21pc2U8c3RyaW5nPiA9PiB7XG4gICAgICAgIGVuY3J5cHRlZElucHV0cy5wdXNoKHBhcmFtcy5pbnB1dCk7XG4gICAgICAgIHJldHVybiBgZW5jcnlwdGVkOiR7cGFyYW1zLmlucHV0fWA7XG4gICAgICB9LFxuICAgIH0gYXMgdW5rbm93biBhcyBCaXRHb0Jhc2U7XG4gICAgY29uc3Qga2V5Y2hhaW5zID0ge1xuICAgICAgYWRkOiBhc3luYyAocGFyYW1zOiBBZGRlZEtleWNoYWluUGFyYW1zKTogUHJvbWlzZTxLZXljaGFpbj4gPT4ge1xuICAgICAgICBhZGRlZEtleWNoYWlucy5wdXNoKHBhcmFtcyk7XG4gICAgICAgIHJldHVybiB7IGlkOiAndXNlci1rZXknIH0gYXMgdW5rbm93biBhcyBLZXljaGFpbjtcbiAgICAgIH0sXG4gICAgfTtcbiAgICBjb25zdCBiYXNlQ29pbiA9IHtcbiAgICAgIGtleWNoYWluczogKCkgPT4ga2V5Y2hhaW5zLFxuICAgIH0gYXMgdW5rbm93biBhcyBJQmFzZUNvaW47XG4gICAgY29uc3QgdXRpbHMgPSBuZXcgRWRkc2FNUEN2MlV0aWxzKGJpdGdvLCBiYXNlQ29pbik7XG4gICAgY29uc3QgcHJpdmF0ZU1hdGVyaWFsID0gQnVmZmVyLmZyb20oJ3NpZ25pbmctc2hhcmUnKTtcbiAgICBjb25zdCByZWR1Y2VkUHJpdmF0ZU1hdGVyaWFsID0gQnVmZmVyLmZyb20oJ3JlZHVjZWQtc2lnbmluZy1zaGFyZScpO1xuXG4gICAgYXdhaXQgdXRpbHMuY3JlYXRlUGFydGljaXBhbnRLZXljaGFpbihcbiAgICAgIE1QQ3YyUGFydGllc0VudW0uVVNFUixcbiAgICAgICdjb21tb24ta2V5Y2hhaW4nLFxuICAgICAgcHJpdmF0ZU1hdGVyaWFsLFxuICAgICAgcmVkdWNlZFByaXZhdGVNYXRlcmlhbCxcbiAgICAgICdwYXNzcGhyYXNlJ1xuICAgICk7XG5cbiAgICBhc3NlcnQuZGVlcFN0cmljdEVxdWFsKGVuY3J5cHRlZElucHV0cywgW1xuICAgICAgcHJpdmF0ZU1hdGVyaWFsLnRvU3RyaW5nKCdiYXNlNjQnKSxcbiAgICAgIHJlZHVjZWRQcml2YXRlTWF0ZXJpYWwudG9TdHJpbmcoJ2Jhc2U2NCcpLFxuICAgIF0pO1xuICAgIGFzc2VydC5zdHJpY3RFcXVhbChhZGRlZEtleWNoYWluc1swXS5lbmNyeXB0ZWRQcnYsIGBlbmNyeXB0ZWQ6JHtwcml2YXRlTWF0ZXJpYWwudG9TdHJpbmcoJ2Jhc2U2NCcpfWApO1xuICAgIGFzc2VydC5zdHJpY3RFcXVhbChhZGRlZEtleWNoYWluc1swXS5zYWZlSWQsIHVuZGVmaW5lZCk7XG4gIH0pO1xuXG4gIGl0KCdlbmNyeXB0cyB0aGUgVlJGIGVudmVsb3BlIGFuZCB0YWdzIHRoZSBrZXljaGFpbiB3aXRoIHNhZmVJZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCBlbmNyeXB0ZWRJbnB1dHM6IHN0cmluZ1tdID0gW107XG4gICAgY29uc3QgYWRkZWRLZXljaGFpbnM6IEFkZGVkS2V5Y2hhaW5QYXJhbXNbXSA9IFtdO1xuICAgIGNvbnN0IGJpdGdvID0ge1xuICAgICAgZW5jcnlwdDogYXN5bmMgKHBhcmFtczogeyBpbnB1dDogc3RyaW5nIH0pOiBQcm9taXNlPHN0cmluZz4gPT4ge1xuICAgICAgICBlbmNyeXB0ZWRJbnB1dHMucHVzaChwYXJhbXMuaW5wdXQpO1xuICAgICAgICByZXR1cm4gYGVuY3J5cHRlZDoke3BhcmFtcy5pbnB1dH1gO1xuICAgICAgfSxcbiAgICB9IGFzIHVua25vd24gYXMgQml0R29CYXNlO1xuICAgIGNvbnN0IGtleWNoYWlucyA9IHtcbiAgICAgIGFkZDogYXN5bmMgKHBhcmFtczogQWRkZWRLZXljaGFpblBhcmFtcyk6IFByb21pc2U8S2V5Y2hhaW4+ID0+IHtcbiAgICAgICAgYWRkZWRLZXljaGFpbnMucHVzaChwYXJhbXMpO1xuICAgICAgICByZXR1cm4geyBpZDogJ3VzZXIta2V5JyB9IGFzIHVua25vd24gYXMgS2V5Y2hhaW47XG4gICAgICB9LFxuICAgIH07XG4gICAgY29uc3QgYmFzZUNvaW4gPSB7XG4gICAgICBrZXljaGFpbnM6ICgpID0+IGtleWNoYWlucyxcbiAgICB9IGFzIHVua25vd24gYXMgSUJhc2VDb2luO1xuICAgIGNvbnN0IHV0aWxzID0gbmV3IEVkZHNhTVBDdjJVdGlscyhiaXRnbywgYmFzZUNvaW4pO1xuICAgIGNvbnN0IHsgZW52ZWxvcGUsIHJlZHVjZWRFbnZlbG9wZSB9ID0gYnVpbGRWcmZLZXlFbnZlbG9wZXMoXG4gICAgICBCdWZmZXIuZnJvbSgnc2lnbmluZy1zaGFyZScpLFxuICAgICAgQnVmZmVyLmZyb20oJ3JlZHVjZWQtc2lnbmluZy1zaGFyZScpLFxuICAgICAgQnVmZmVyLmZyb20oJ3ZyZi1zaGFyZScpXG4gICAgKTtcblxuICAgIGF3YWl0IHV0aWxzLmNyZWF0ZVBhcnRpY2lwYW50S2V5Y2hhaW4oXG4gICAgICBNUEN2MlBhcnRpZXNFbnVtLlVTRVIsXG4gICAgICAnY29tbW9uLWtleWNoYWluJyxcbiAgICAgIGVudmVsb3BlLFxuICAgICAgcmVkdWNlZEVudmVsb3BlLFxuICAgICAgJ3Bhc3NwaHJhc2UnLFxuICAgICAgdW5kZWZpbmVkLFxuICAgICAgdW5kZWZpbmVkLFxuICAgICAgdW5kZWZpbmVkLFxuICAgICAgdW5kZWZpbmVkLFxuICAgICAgJ3NhZmUtaWQnXG4gICAgKTtcblxuICAgIGFzc2VydC5kZWVwU3RyaWN0RXF1YWwoZW5jcnlwdGVkSW5wdXRzWzBdLCBlbnZlbG9wZS50b1N0cmluZygnYmFzZTY0JykpO1xuICAgIGFzc2VydC5zdHJpY3RFcXVhbChhZGRlZEtleWNoYWluc1swXS5zYWZlSWQsICdzYWZlLWlkJyk7XG4gICAgY29uc3QgZGVjb2RlZCA9IGRlY29kZVZyZkVudmVsb3BlKEJ1ZmZlci5mcm9tKGVuY3J5cHRlZElucHV0c1swXSwgJ2Jhc2U2NCcpKTtcbiAgICBhc3NlcnQuZGVlcFN0cmljdEVxdWFsKEJ1ZmZlci5mcm9tKGRlY29kZWQudnJmKSwgQnVmZmVyLmZyb20oJ3ZyZi1zaGFyZScpKTtcbiAgfSk7XG5cbiAgaXQoJ3RhZ3MgdGhlIEJpdEdvIGtleWNoYWluIHdpdGggc2FmZUlkIGFuZCBkb2VzIG5vdCBlbmNyeXB0JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IGVuY3J5cHRlZElucHV0czogc3RyaW5nW10gPSBbXTtcbiAgICBjb25zdCBhZGRlZEtleWNoYWluczogQWRkZWRLZXljaGFpblBhcmFtc1tdID0gW107XG4gICAgY29uc3QgYml0Z28gPSB7XG4gICAgICBlbmNyeXB0OiBhc3luYyAocGFyYW1zOiB7IGlucHV0OiBzdHJpbmcgfSk6IFByb21pc2U8c3RyaW5nPiA9PiB7XG4gICAgICAgIGVuY3J5cHRlZElucHV0cy5wdXNoKHBhcmFtcy5pbnB1dCk7XG4gICAgICAgIHJldHVybiBgZW5jcnlwdGVkOiR7cGFyYW1zLmlucHV0fWA7XG4gICAgICB9LFxuICAgIH0gYXMgdW5rbm93biBhcyBCaXRHb0Jhc2U7XG4gICAgY29uc3Qga2V5Y2hhaW5zID0ge1xuICAgICAgYWRkOiBhc3luYyAocGFyYW1zOiBBZGRlZEtleWNoYWluUGFyYW1zKTogUHJvbWlzZTxLZXljaGFpbj4gPT4ge1xuICAgICAgICBhZGRlZEtleWNoYWlucy5wdXNoKHBhcmFtcyk7XG4gICAgICAgIHJldHVybiB7IGlkOiAnYml0Z28ta2V5JyB9IGFzIHVua25vd24gYXMgS2V5Y2hhaW47XG4gICAgICB9LFxuICAgIH07XG4gICAgY29uc3QgYmFzZUNvaW4gPSB7XG4gICAgICBrZXljaGFpbnM6ICgpID0+IGtleWNoYWlucyxcbiAgICB9IGFzIHVua25vd24gYXMgSUJhc2VDb2luO1xuICAgIGNvbnN0IHV0aWxzID0gbmV3IEVkZHNhTVBDdjJVdGlscyhiaXRnbywgYmFzZUNvaW4pO1xuXG4gICAgYXdhaXQgdXRpbHMuY3JlYXRlUGFydGljaXBhbnRLZXljaGFpbihcbiAgICAgIE1QQ3YyUGFydGllc0VudW0uQklUR08sXG4gICAgICAnY29tbW9uLWtleWNoYWluJyxcbiAgICAgIHVuZGVmaW5lZCxcbiAgICAgIHVuZGVmaW5lZCxcbiAgICAgIHVuZGVmaW5lZCxcbiAgICAgIHVuZGVmaW5lZCxcbiAgICAgIHVuZGVmaW5lZCxcbiAgICAgIHVuZGVmaW5lZCxcbiAgICAgIHVuZGVmaW5lZCxcbiAgICAgICdzYWZlLWlkJ1xuICAgICk7XG5cbiAgICBhc3NlcnQuZGVlcFN0cmljdEVxdWFsKGVuY3J5cHRlZElucHV0cywgW10pO1xuICAgIGFzc2VydC5zdHJpY3RFcXVhbChhZGRlZEtleWNoYWluc1swXS5zb3VyY2UsICdiaXRnbycpO1xuICAgIGFzc2VydC5zdHJpY3RFcXVhbChhZGRlZEtleWNoYWluc1swXS5zYWZlSWQsICdzYWZlLWlkJyk7XG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKGFkZGVkS2V5Y2hhaW5zWzBdLmVuY3J5cHRlZFBydiwgdW5kZWZpbmVkKTtcbiAgfSk7XG5cbiAgaXQoJ3JvdW5kLXRyaXBzIG9wYXF1ZSBWUkYgYmxvYnMgYW5kIGtlZXBzIG9ubHkgdGhlIHJlY2lwaWVudCBwMnAgbWVzc2FnZXMnLCBmdW5jdGlvbiAoKSB7XG4gICAgY29uc3QgYmxvYiA9IHNlcmlhbGl6ZVZyZk1lc3NhZ2VzKHtcbiAgICAgIGJyb2FkY2FzdE1lc3NhZ2VzOiBbeyBmcm9tOiBNUEN2MlBhcnRpZXNFbnVtLkJJVEdPLCBwYXlsb2FkOiBuZXcgVWludDhBcnJheShbMSwgMiwgM10pIH1dLFxuICAgICAgcDJwTWVzc2FnZXM6IFtcbiAgICAgICAgeyBmcm9tOiBNUEN2MlBhcnRpZXNFbnVtLkJJVEdPLCB0bzogTVBDdjJQYXJ0aWVzRW51bS5VU0VSLCBwYXlsb2FkOiBuZXcgVWludDhBcnJheShbNF0pIH0sXG4gICAgICAgIHsgZnJvbTogTVBDdjJQYXJ0aWVzRW51bS5CSVRHTywgdG86IE1QQ3YyUGFydGllc0VudW0uQkFDS1VQLCBwYXlsb2FkOiBuZXcgVWludDhBcnJheShbNV0pIH0sXG4gICAgICBdLFxuICAgIH0pO1xuXG4gICAgY29uc3QgZm9yVXNlciA9IGRlc2VyaWFsaXplVnJmTWVzc2FnZXMoYmxvYiwgTVBDdjJQYXJ0aWVzRW51bS5VU0VSKTtcbiAgICBhc3NlcnQuZGVlcFN0cmljdEVxdWFsKEJ1ZmZlci5mcm9tKGZvclVzZXIuYnJvYWRjYXN0TWVzc2FnZXNbMF0ucGF5bG9hZCksIEJ1ZmZlci5mcm9tKFsxLCAyLCAzXSkpO1xuICAgIGFzc2VydC5zdHJpY3RFcXVhbChmb3JVc2VyLnAycE1lc3NhZ2VzLmxlbmd0aCwgMSk7XG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKGZvclVzZXIucDJwTWVzc2FnZXNbMF0udG8sIE1QQ3YyUGFydGllc0VudW0uVVNFUik7XG4gICAgYXNzZXJ0LmRlZXBTdHJpY3RFcXVhbChCdWZmZXIuZnJvbShmb3JVc2VyLnAycE1lc3NhZ2VzWzBdLnBheWxvYWQpLCBCdWZmZXIuZnJvbShbNF0pKTtcblxuICAgIGNvbnN0IGZvckJhY2t1cCA9IGRlc2VyaWFsaXplVnJmTWVzc2FnZXMoYmxvYiwgTVBDdjJQYXJ0aWVzRW51bS5CQUNLVVApO1xuICAgIGFzc2VydC5zdHJpY3RFcXVhbChmb3JCYWNrdXAucDJwTWVzc2FnZXMubGVuZ3RoLCAxKTtcbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwoZm9yQmFja3VwLnAycE1lc3NhZ2VzWzBdLnRvLCBNUEN2MlBhcnRpZXNFbnVtLkJBQ0tVUCk7XG4gIH0pO1xuXG4gIGl0KCdyZWplY3RzIG1hbGZvcm1lZCBWUkYgREtHIG1lc3NhZ2UgYmxvYnMnLCBmdW5jdGlvbiAoKSB7XG4gICAgYXNzZXJ0LnRocm93cygoKSA9PiBkZXNlcmlhbGl6ZVZyZk1lc3NhZ2VzKCclJSUnLCBNUEN2MlBhcnRpZXNFbnVtLlVTRVIpLCAvSW52YWxpZCBWUkYgREtHIG1lc3NhZ2UgYmxvYi8pO1xuICAgIGNvbnN0IG5vdEFuQXJyYXkgPSBCdWZmZXIuZnJvbShKU09OLnN0cmluZ2lmeSh7IGZyb206IDAgfSkpLnRvU3RyaW5nKCdiYXNlNjQnKTtcbiAgICBhc3NlcnQudGhyb3dzKCgpID0+IGRlc2VyaWFsaXplVnJmTWVzc2FnZXMobm90QW5BcnJheSwgTVBDdjJQYXJ0aWVzRW51bS5VU0VSKSwgL1ZSRiBES0cgbWVzc2FnZSBibG9iLyk7XG4gICAgY29uc3QgYmFkUGFydHkgPSBCdWZmZXIuZnJvbShKU09OLnN0cmluZ2lmeShbeyBmcm9tOiA5LCBwYXlsb2FkOiBCdWZmZXIuZnJvbShbMV0pLnRvU3RyaW5nKCdiYXNlNjQnKSB9XSkpLnRvU3RyaW5nKFxuICAgICAgJ2Jhc2U2NCdcbiAgICApO1xuICAgIGFzc2VydC50aHJvd3MoKCkgPT4gZGVzZXJpYWxpemVWcmZNZXNzYWdlcyhiYWRQYXJ0eSwgTVBDdjJQYXJ0aWVzRW51bS5VU0VSKSwgL1ZSRiBES0cgbWVzc2FnZSBibG9iLyk7XG4gIH0pO1xufSk7XG4iXX0=
|
|
194
|
+
describe('EdDSA safe-child MPS derivation', function () {
|
|
195
|
+
let userSigningShare;
|
|
196
|
+
let userVrfShare;
|
|
197
|
+
let bitgoSigningShare;
|
|
198
|
+
let bitgoVrfShare;
|
|
199
|
+
let bitgoPrivateKey;
|
|
200
|
+
let bitgoPublicKey;
|
|
201
|
+
const sessionId = 'derive-session';
|
|
202
|
+
const derivationIndex = 7;
|
|
203
|
+
const path = "m/7'";
|
|
204
|
+
const Request = t.intersection([
|
|
205
|
+
t.type({ enterprise: t.string, type: t.string, curveType: t.string, round: t.string, payload: t.unknown }),
|
|
206
|
+
t.partial({ safeId: t.string }),
|
|
207
|
+
]);
|
|
208
|
+
before(async function () {
|
|
209
|
+
const signing = await sdk_lib_mpc_1.MPSUtil.generateEdDsaDKGKeyShares();
|
|
210
|
+
const vrf = await sdk_lib_mpc_1.MpsVrfUtils.generateVrfDKGKeyShares();
|
|
211
|
+
userSigningShare = signing[typesMPCv2_1.MPCv2PartiesEnum.USER].getKeyShare();
|
|
212
|
+
bitgoSigningShare = signing[typesMPCv2_1.MPCv2PartiesEnum.BITGO].getKeyShare();
|
|
213
|
+
userVrfShare = vrf[typesMPCv2_1.MPCv2PartiesEnum.USER].getKeyShare();
|
|
214
|
+
bitgoVrfShare = vrf[typesMPCv2_1.MPCv2PartiesEnum.BITGO].getKeyShare();
|
|
215
|
+
const bitgoGpg = await (0, opengpgUtils_1.generateGPGKeyPair)('ed25519');
|
|
216
|
+
bitgoPrivateKey = await pgp.readPrivateKey({ armoredKey: bitgoGpg.privateKey });
|
|
217
|
+
bitgoPublicKey = await pgp.readKey({ armoredKey: bitgoGpg.publicKey });
|
|
218
|
+
});
|
|
219
|
+
async function deriveWithPeer(fault, recordedKeychains) {
|
|
220
|
+
const { bitgo, baseCoin, post, encryptedInputs, addedKeychains } = createKeychainFixture();
|
|
221
|
+
const utils = new eddsaVrfMPCv2_1.EddsaVrfMPCv2Utils(bitgo, baseCoin);
|
|
222
|
+
sinon.stub(utils, 'getBitgoGpgPubkeyBasedOnFeatureFlags').resolves({
|
|
223
|
+
mpcv2PublicKey: bitgoPublicKey,
|
|
224
|
+
eddsaMpcv2PublicKey: bitgoPublicKey,
|
|
225
|
+
redpallasMpcv2PublicKey: undefined,
|
|
226
|
+
});
|
|
227
|
+
const bitgoPeer = new sdk_lib_mpc_1.MpsDerive.Derive(3, 2, typesMPCv2_1.MPCv2PartiesEnum.BITGO, bitgoSigningShare, bitgoVrfShare, path);
|
|
228
|
+
let bitgoMsg2;
|
|
229
|
+
let userGpgPublicKey = '';
|
|
230
|
+
let rounds = 0;
|
|
231
|
+
post.callsFake((_url) => ({
|
|
232
|
+
send: (rawBody) => ({
|
|
233
|
+
result: async () => {
|
|
234
|
+
const body = (0, codecs_1.decodeWithCodec)(Request, rawBody, 'EdDSA derive request');
|
|
235
|
+
assert_1.default.strictEqual(_url, '/mpc/generatekey');
|
|
236
|
+
assert_1.default.strictEqual(body.enterprise, 'enterprise-id');
|
|
237
|
+
assert_1.default.strictEqual(body.type, public_types_1.KeyGenTypeEnum.MPCv2);
|
|
238
|
+
assert_1.default.strictEqual(body.curveType, public_types_1.KeyCurveEnum.EdDSA);
|
|
239
|
+
if (rounds++ === 0) {
|
|
240
|
+
assert_1.default.strictEqual(body.round, public_types_1.MPCv2KeyGenStateEnum['MPCv2Derive-R1']);
|
|
241
|
+
assert_1.default.strictEqual(body.safeId, 'safe-id');
|
|
242
|
+
const request = (0, codecs_1.decodeWithCodec)(public_types_1.EddsaMPCv2DeriveRound1Request, body.payload, 'EdDSA derive round 1');
|
|
243
|
+
assert_1.default.deepStrictEqual(Object.keys(request).sort(), [
|
|
244
|
+
'derivationIndex',
|
|
245
|
+
'parentKeyId',
|
|
246
|
+
'userGpgPublicKey',
|
|
247
|
+
'userMsg1',
|
|
248
|
+
]);
|
|
249
|
+
assert_1.default.strictEqual(request.parentKeyId, 'bitgo-root-id');
|
|
250
|
+
assert_1.default.strictEqual(request.derivationIndex, derivationIndex);
|
|
251
|
+
userGpgPublicKey = request.userGpgPublicKey;
|
|
252
|
+
const userGpgKey = await pgp.readKey({ armoredKey: request.userGpgPublicKey });
|
|
253
|
+
const userPayload = await sdk_lib_mpc_1.MPSComms.verifyMpsMessage(request.userMsg1, userGpgKey);
|
|
254
|
+
const bitgoFirst = await bitgoPeer.initDerive();
|
|
255
|
+
const [outgoing] = bitgoPeer.handleIncomingMessages([
|
|
256
|
+
{ from: typesMPCv2_1.MPCv2PartiesEnum.USER, payload: new Uint8Array(userPayload) },
|
|
257
|
+
]);
|
|
258
|
+
assert_1.default.ok(outgoing);
|
|
259
|
+
bitgoMsg2 = outgoing.payload;
|
|
260
|
+
const signed = await sdk_lib_mpc_1.MPSComms.detachSignMpsMessage(Buffer.from(bitgoFirst.payload), bitgoPrivateKey);
|
|
261
|
+
return {
|
|
262
|
+
sessionId,
|
|
263
|
+
bitgoMsg1: fault === 'r1-signature' ? { ...signed, message: Buffer.from('tampered').toString('base64') } : signed,
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
assert_1.default.strictEqual(rounds, 2);
|
|
267
|
+
assert_1.default.strictEqual(body.round, public_types_1.MPCv2KeyGenStateEnum['MPCv2Derive-R2']);
|
|
268
|
+
assert_1.default.strictEqual(body.safeId, 'safe-id');
|
|
269
|
+
const request = (0, codecs_1.decodeWithCodec)(public_types_1.EddsaMPCv2DeriveRound2Request, body.payload, 'EdDSA derive round 2');
|
|
270
|
+
assert_1.default.deepStrictEqual(Object.keys(request).sort(), ['sessionId', 'userMsg2']);
|
|
271
|
+
assert_1.default.strictEqual(request.sessionId, sessionId);
|
|
272
|
+
const userPayload = await sdk_lib_mpc_1.MPSComms.verifyMpsMessage(request.userMsg2, await pgp.readKey({ armoredKey: userGpgPublicKey }));
|
|
273
|
+
assert_1.default.deepStrictEqual(bitgoPeer.handleIncomingMessages([{ from: typesMPCv2_1.MPCv2PartiesEnum.USER, payload: new Uint8Array(userPayload) }]), []);
|
|
274
|
+
assert_1.default.ok(bitgoMsg2);
|
|
275
|
+
const signed = await sdk_lib_mpc_1.MPSComms.detachSignMpsMessage(Buffer.from(bitgoMsg2), bitgoPrivateKey);
|
|
276
|
+
const commonPublicKeychain = bitgoPeer.getCommonKeychain();
|
|
277
|
+
return {
|
|
278
|
+
sessionId: fault === 'session' ? 'different-session' : sessionId,
|
|
279
|
+
commonPublicKeychain: fault === 'commonKeychain'
|
|
280
|
+
? `${commonPublicKeychain.slice(0, -1)}${commonPublicKeychain.endsWith('0') ? '1' : '0'}`
|
|
281
|
+
: commonPublicKeychain,
|
|
282
|
+
bitgoMsg2: fault === 'r2-signature' ? { ...signed, message: Buffer.from('tampered').toString('base64') } : signed,
|
|
283
|
+
};
|
|
284
|
+
},
|
|
285
|
+
}),
|
|
286
|
+
}));
|
|
287
|
+
try {
|
|
288
|
+
const result = await utils.createSafeChildKeychains({
|
|
289
|
+
passphrase: 'passphrase',
|
|
290
|
+
enterprise: 'enterprise-id',
|
|
291
|
+
safeId: 'safe-id',
|
|
292
|
+
parentKeyId: 'bitgo-root-id',
|
|
293
|
+
derivationIndex,
|
|
294
|
+
userRootKeyId: 'user-root-id',
|
|
295
|
+
backupRootKeyId: 'backup-root-id',
|
|
296
|
+
userRootKeyShare: userSigningShare,
|
|
297
|
+
userRootVrfKeyShare: userVrfShare,
|
|
298
|
+
});
|
|
299
|
+
return { result, encryptedInputs, addedKeychains, bitgoPeer, rounds };
|
|
300
|
+
}
|
|
301
|
+
finally {
|
|
302
|
+
recordedKeychains?.push(...addedKeychains);
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
afterEach(function () {
|
|
306
|
+
sinon.restore();
|
|
307
|
+
});
|
|
308
|
+
it('registers the child signing share and two public-only placeholders after the signed ceremony', async function () {
|
|
309
|
+
const { result, encryptedInputs, addedKeychains, bitgoPeer, rounds } = await deriveWithPeer();
|
|
310
|
+
assert_1.default.strictEqual(rounds, 2);
|
|
311
|
+
assert_1.default.deepStrictEqual(addedKeychains.map(({ source }) => source).sort(), ['backup', 'bitgo', 'user']);
|
|
312
|
+
assert_1.default.deepStrictEqual([result.userKeychain.id, result.backupKeychain.id, result.bitgoKeychain.id], ['user-child', 'backup-child', 'bitgo-child']);
|
|
313
|
+
for (const keychain of addedKeychains) {
|
|
314
|
+
assert_1.default.strictEqual(keychain.safeId, 'safe-id');
|
|
315
|
+
assert_1.default.strictEqual(keychain.derivedFromParentWithPath, path);
|
|
316
|
+
assert_1.default.strictEqual(keychain.commonKeychain, bitgoPeer.getCommonKeychain());
|
|
317
|
+
assert_1.default.strictEqual(keychain.keyType, 'tss');
|
|
318
|
+
assert_1.default.strictEqual(keychain.isMPCv2, true);
|
|
319
|
+
}
|
|
320
|
+
const userChild = addedKeychains.find(({ source }) => source === 'user');
|
|
321
|
+
const backupChild = addedKeychains.find(({ source }) => source === 'backup');
|
|
322
|
+
const bitgoChild = addedKeychains.find(({ source }) => source === 'bitgo');
|
|
323
|
+
assert_1.default.ok(userChild);
|
|
324
|
+
assert_1.default.ok(backupChild);
|
|
325
|
+
assert_1.default.ok(bitgoChild);
|
|
326
|
+
assert_1.default.strictEqual(userChild.parent, 'user-root-id');
|
|
327
|
+
assert_1.default.strictEqual(backupChild.parent, 'backup-root-id');
|
|
328
|
+
assert_1.default.strictEqual(bitgoChild.parent, 'bitgo-root-id');
|
|
329
|
+
assert_1.default.strictEqual(encryptedInputs.length, 2);
|
|
330
|
+
assert_1.default.strictEqual(userChild.encryptedPrv, `encrypted:${encryptedInputs[0]}`);
|
|
331
|
+
const signingShare = Buffer.from(result.userKeychain.encryptedPrv?.slice('encrypted:'.length) ?? '', 'base64');
|
|
332
|
+
assert_1.default.deepStrictEqual(signingShare, Buffer.from(encryptedInputs[0], 'base64'));
|
|
333
|
+
assert_1.default.notDeepStrictEqual(signingShare, userSigningShare);
|
|
334
|
+
assert_1.default.notDeepStrictEqual(signingShare, bitgoPeer.getKeyShare());
|
|
335
|
+
assert_1.default.strictEqual(userChild.reducedEncryptedPrv, undefined);
|
|
336
|
+
const reduced = result.userKeychain.reducedEncryptedPrv;
|
|
337
|
+
assert_1.default.ok(reduced);
|
|
338
|
+
const reducedShare = sdk_lib_mpc_1.MPSTypes.getDecodedReducedKeyShare(Buffer.from(reduced.slice('encrypted:'.length), 'base64'));
|
|
339
|
+
assert_1.default.deepStrictEqual(Buffer.from(reducedShare.keyShare), signingShare);
|
|
340
|
+
assert_1.default.strictEqual(Buffer.from(reducedShare.pub).toString('hex'), bitgoPeer.getCommonKeychain().slice(0, 64));
|
|
341
|
+
assert_1.default.throws(() => decodeVrfEnvelope(signingShare));
|
|
342
|
+
assert_1.default.strictEqual(backupChild.encryptedPrv, undefined);
|
|
343
|
+
assert_1.default.strictEqual(bitgoChild.encryptedPrv, undefined);
|
|
344
|
+
});
|
|
345
|
+
it('rejects indexes outside the hardened Safe range before contacting WP', async function () {
|
|
346
|
+
const { bitgo, baseCoin, post, addedKeychains } = createKeychainFixture();
|
|
347
|
+
const utils = new eddsaVrfMPCv2_1.EddsaVrfMPCv2Utils(bitgo, baseCoin);
|
|
348
|
+
await assert_1.default.rejects(utils.createSafeChildKeychains({
|
|
349
|
+
passphrase: 'passphrase',
|
|
350
|
+
enterprise: 'enterprise-id',
|
|
351
|
+
safeId: 'safe-id',
|
|
352
|
+
parentKeyId: 'bitgo-root-id',
|
|
353
|
+
derivationIndex: 0x80000000,
|
|
354
|
+
userRootKeyId: 'user-root-id',
|
|
355
|
+
backupRootKeyId: 'backup-root-id',
|
|
356
|
+
userRootKeyShare: userSigningShare,
|
|
357
|
+
userRootVrfKeyShare: userVrfShare,
|
|
358
|
+
}), /derivedFromParentWithPath/);
|
|
359
|
+
assert_1.default.strictEqual(post.called, false);
|
|
360
|
+
assert_1.default.deepStrictEqual(addedKeychains, []);
|
|
361
|
+
});
|
|
362
|
+
const faults = [
|
|
363
|
+
'r1-signature',
|
|
364
|
+
'r2-signature',
|
|
365
|
+
'session',
|
|
366
|
+
'commonKeychain',
|
|
367
|
+
];
|
|
368
|
+
for (const fault of faults) {
|
|
369
|
+
it(`rejects ${fault} before registering any child`, async function () {
|
|
370
|
+
const recordedKeychains = [];
|
|
371
|
+
await assert_1.default.rejects(() => deriveWithPeer(fault, recordedKeychains), fault === 'session'
|
|
372
|
+
? /session id/i
|
|
373
|
+
: fault === 'commonKeychain'
|
|
374
|
+
? /common keychain/i
|
|
375
|
+
: /signature|verification|signed/i);
|
|
376
|
+
assert_1.default.deepStrictEqual(recordedKeychains, []);
|
|
377
|
+
});
|
|
378
|
+
}
|
|
379
|
+
});
|
|
380
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWRkc2FWcmZNUEN2Mi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Rlc3QvdW5pdC9iaXRnby91dGlscy90c3MvZWRkc2EvZWRkc2FWcmZNUEN2Mi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLG9EQUE0QjtBQUM1Qiw2Q0FBK0I7QUFDL0IsNkNBQStCO0FBQy9CLG9EQUF5RjtBQUN6RixzREFNNkI7QUFDN0IsbUNBQWdDO0FBQ2hDLHlDQUEyQjtBQUUzQiwrQ0FBd0Y7QUFDeEYscUVBQTJFO0FBQzNFLDZGQUFrRztBQUNsRyw2RkFJbUU7QUFDbkUsdUZBQTBGO0FBQzFGLGlGQUFvRjtBQUVwRixNQUFNLGVBQWUsR0FBRyxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQ2hDLFlBQVksRUFDWixDQUFDLEtBQUssRUFBdUIsRUFBRSxDQUFDLEtBQUssWUFBWSxVQUFVLEVBQzNELENBQUMsS0FBSyxFQUFFLE9BQU8sRUFBRSxFQUFFLENBQUMsQ0FBQyxLQUFLLFlBQVksVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLEtBQUssRUFBRSxPQUFPLENBQUMsQ0FBQyxFQUNoRyxDQUFDLENBQUMsUUFBUSxDQUNYLENBQUM7QUFFRixNQUFNLFdBQVcsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDO0lBQ3pCLE9BQU8sRUFBRSxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQztJQUNyQixXQUFXLEVBQUUsZUFBZTtJQUM1QixHQUFHLEVBQUUsZUFBZTtDQUNyQixDQUFDLENBQUM7QUFjSCxTQUFTLGlCQUFpQixDQUFDLE9BQWU7SUFDeEMsT0FBTyxJQUFBLHdCQUFlLEVBQUMsV0FBVyxFQUFFLElBQUEsZUFBTSxFQUFDLE9BQU8sQ0FBQyxFQUFFLGtCQUFrQixDQUFDLENBQUM7QUFDM0UsQ0FBQztBQUVELFNBQVMscUJBQXFCO0lBQzVCLE1BQU0sZUFBZSxHQUFhLEVBQUUsQ0FBQztJQUNyQyxNQUFNLGNBQWMsR0FBMEIsRUFBRSxDQUFDO0lBQ2pELE1BQU0sSUFBSSxHQUFHLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQztJQUMxQixNQUFNLEtBQUssR0FBRztRQUNaLE1BQU0sRUFBRSxHQUFHLEVBQUUsQ0FBQyxLQUFLO1FBQ25CLEdBQUcsRUFBRSxDQUFDLElBQVksRUFBRSxFQUFFLENBQUMsSUFBSTtRQUMzQixJQUFJO1FBQ0osT0FBTyxFQUFFLEtBQUssRUFBRSxNQUF5QixFQUFtQixFQUFFO1lBQzVELGVBQWUsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ25DLE9BQU8sYUFBYSxNQUFNLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDckMsQ0FBQztLQUNzQixDQUFDO0lBQzFCLE1BQU0sU0FBUyxHQUFHO1FBQ2hCLEdBQUcsRUFBRSxLQUFLLEVBQUUsTUFBMkIsRUFBcUIsRUFBRTtZQUM1RCxjQUFjLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQzVCLE9BQU8sRUFBRSxFQUFFLEVBQUUsR0FBRyxNQUFNLENBQUMsTUFBTSxRQUFRLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxZQUFZLEVBQUUsTUFBTSxDQUFDLFlBQVksRUFBRSxDQUFDO1FBQzFGLENBQUM7S0FDRixDQUFDO0lBQ0YsTUFBTSxRQUFRLEdBQUc7UUFDZixTQUFTLEVBQUUsR0FBRyxFQUFFLENBQUMsU0FBUztLQUNILENBQUM7SUFDMUIsT0FBTyxFQUFFLEtBQUssRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFFLGVBQWUsRUFBRSxjQUFjLEVBQUUsQ0FBQztBQUNwRSxDQUFDO0FBRUQsUUFBUSxDQUFDLCtCQUErQixFQUFFO0lBQ3hDLEVBQUUsQ0FBQyxtRUFBbUUsRUFBRTtRQUN0RSxNQUFNLGVBQWUsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFDO1FBQ3JELE1BQU0sc0JBQXNCLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxDQUFDO1FBQ3BFLE1BQU0sV0FBVyxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7UUFFN0MsTUFBTSxFQUFFLFFBQVEsRUFBRSxlQUFlLEVBQUUsR0FBRyxJQUFBLDJDQUF3QixFQUM1RCxlQUFlLEVBQ2Ysc0JBQXNCLEVBQ3RCLFdBQVcsQ0FDWixDQUFDO1FBQ0YsTUFBTSxlQUFlLEdBQUcsaUJBQWlCLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDcEQsTUFBTSxzQkFBc0IsR0FBRyxpQkFBaUIsQ0FBQyxlQUFlLENBQUMsQ0FBQztRQUVsRSxnQkFBTSxDQUFDLGVBQWUsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxXQUFXLENBQUMsRUFBRSxlQUFlLENBQUMsQ0FBQztRQUNsRixnQkFBTSxDQUFDLGVBQWUsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxHQUFHLENBQUMsRUFBRSxXQUFXLENBQUMsQ0FBQztRQUN0RSxnQkFBTSxDQUFDLGVBQWUsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLHNCQUFzQixDQUFDLFdBQVcsQ0FBQyxFQUFFLHNCQUFzQixDQUFDLENBQUM7UUFDaEcsZ0JBQU0sQ0FBQyxlQUFlLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxHQUFHLENBQUMsRUFBRSxXQUFXLENBQUMsQ0FBQztJQUMvRSxDQUFDLENBQUMsQ0FBQztJQUVILEVBQUUsQ0FBQywwREFBMEQsRUFBRSxLQUFLO1FBQ2xFLE1BQU0sRUFBRSxLQUFLLEVBQUUsUUFBUSxFQUFFLGVBQWUsRUFBRSxjQUFjLEVBQUUsR0FBRyxxQkFBcUIsRUFBRSxDQUFDO1FBQ3JGLE1BQU0sS0FBSyxHQUFHLElBQUkscUJBQWUsQ0FBQyxLQUFLLEVBQUUsUUFBUSxDQUFDLENBQUM7UUFDbkQsTUFBTSxlQUFlLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsQ0FBQztRQUNyRCxNQUFNLHNCQUFzQixHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsdUJBQXVCLENBQUMsQ0FBQztRQUVwRSxNQUFNLEtBQUssQ0FBQyx5QkFBeUIsQ0FDbkMsNkJBQWdCLENBQUMsSUFBSSxFQUNyQixpQkFBaUIsRUFDakIsZUFBZSxFQUNmLHNCQUFzQixFQUN0QixZQUFZLENBQ2IsQ0FBQztRQUVGLGdCQUFNLENBQUMsZUFBZSxDQUFDLGVBQWUsRUFBRTtZQUN0QyxlQUFlLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQztZQUNsQyxzQkFBc0IsQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDO1NBQzFDLENBQUMsQ0FBQztRQUNILGdCQUFNLENBQUMsV0FBVyxDQUFDLGNBQWMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxZQUFZLEVBQUUsYUFBYSxlQUFlLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUN0RyxnQkFBTSxDQUFDLFdBQVcsQ0FBQyxjQUFjLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxFQUFFLFNBQVMsQ0FBQyxDQUFDO0lBQzFELENBQUMsQ0FBQyxDQUFDO0lBRUgsRUFBRSxDQUFDLDhEQUE4RCxFQUFFLEtBQUs7UUFDdEUsTUFBTSxFQUFFLEtBQUssRUFBRSxRQUFRLEVBQUUsZUFBZSxFQUFFLGNBQWMsRUFBRSxHQUFHLHFCQUFxQixFQUFFLENBQUM7UUFDckYsTUFBTSxLQUFLLEdBQUcsSUFBSSxxQkFBZSxDQUFDLEtBQUssRUFBRSxRQUFRLENBQUMsQ0FBQztRQUVuRCxNQUFNLGdCQUFNLENBQUMsT0FBTyxDQUNsQixLQUFLLENBQUMseUJBQXlCLENBQUMsNkJBQWdCLENBQUMsTUFBTSxFQUFFLGlCQUFpQixFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsWUFBWSxDQUFDLEVBQy9HLGtEQUFrRCxDQUNuRCxDQUFDO1FBQ0YsZ0JBQU0sQ0FBQyxlQUFlLENBQUMsZUFBZSxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBQzVDLGdCQUFNLENBQUMsZUFBZSxDQUFDLGNBQWMsRUFBRSxFQUFFLENBQUMsQ0FBQztJQUM3QyxDQUFDLENBQUMsQ0FBQztJQUVILEVBQUUsQ0FBQyw2REFBNkQsRUFBRSxLQUFLO1FBQ3JFLE1BQU0sZUFBZSxHQUFhLEVBQUUsQ0FBQztRQUNyQyxNQUFNLGNBQWMsR0FBMEIsRUFBRSxDQUFDO1FBQ2pELE1BQU0sS0FBSyxHQUFHO1lBQ1osT0FBTyxFQUFFLEtBQUssRUFBRSxNQUF5QixFQUFtQixFQUFFO2dCQUM1RCxlQUFlLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztnQkFDbkMsT0FBTyxhQUFhLE1BQU0sQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUNyQyxDQUFDO1NBQ3NCLENBQUM7UUFDMUIsTUFBTSxTQUFTLEdBQUc7WUFDaEIsR0FBRyxFQUFFLEtBQUssRUFBRSxNQUEyQixFQUFxQixFQUFFO2dCQUM1RCxjQUFjLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO2dCQUM1QixPQUFPLEVBQUUsRUFBRSxFQUFFLFVBQVUsRUFBeUIsQ0FBQztZQUNuRCxDQUFDO1NBQ0YsQ0FBQztRQUNGLE1BQU0sUUFBUSxHQUFHO1lBQ2YsU0FBUyxFQUFFLEdBQUcsRUFBRSxDQUFDLFNBQVM7U0FDSCxDQUFDO1FBQzFCLE1BQU0sS0FBSyxHQUFHLElBQUkscUJBQWUsQ0FBQyxLQUFLLEVBQUUsUUFBUSxDQUFDLENBQUM7UUFDbkQsTUFBTSxFQUFFLFFBQVEsRUFBRSxlQUFlLEVBQUUsR0FBRyxJQUFBLDJDQUF3QixFQUM1RCxNQUFNLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxFQUM1QixNQUFNLENBQUMsSUFBSSxDQUFDLHVCQUF1QixDQUFDLEVBQ3BDLE1BQU0sQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQ3pCLENBQUM7UUFFRixNQUFNLEtBQUssQ0FBQyx5QkFBeUIsQ0FDbkMsNkJBQWdCLENBQUMsSUFBSSxFQUNyQixpQkFBaUIsRUFDakIsUUFBUSxFQUNSLGVBQWUsRUFDZixZQUFZLEVBQ1osU0FBUyxFQUNULFNBQVMsRUFDVCxTQUFTLEVBQ1QsU0FBUyxFQUNULFNBQVMsQ0FDVixDQUFDO1FBRUYsZ0JBQU0sQ0FBQyxlQUFlLENBQUMsZUFBZSxDQUFDLENBQUMsQ0FBQyxFQUFFLFFBQVEsQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQztRQUN4RSxnQkFBTSxDQUFDLFdBQVcsQ0FBQyxjQUFjLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxFQUFFLFNBQVMsQ0FBQyxDQUFDO1FBQ3hELE1BQU0sT0FBTyxHQUFHLGlCQUFpQixDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLENBQUMsQ0FBQyxFQUFFLFFBQVEsQ0FBQyxDQUFDLENBQUM7UUFDN0UsZ0JBQU0sQ0FBQyxlQUFlLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLEVBQUUsTUFBTSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDO0lBQzdFLENBQUMsQ0FBQyxDQUFDO0lBRUgsRUFBRSxDQUFDLDBEQUEwRCxFQUFFLEtBQUs7UUFDbEUsTUFBTSxlQUFlLEdBQWEsRUFBRSxDQUFDO1FBQ3JDLE1BQU0sY0FBYyxHQUEwQixFQUFFLENBQUM7UUFDakQsTUFBTSxLQUFLLEdBQUc7WUFDWixPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQXlCLEVBQW1CLEVBQUU7Z0JBQzVELGVBQWUsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO2dCQUNuQyxPQUFPLGFBQWEsTUFBTSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ3JDLENBQUM7U0FDc0IsQ0FBQztRQUMxQixNQUFNLFNBQVMsR0FBRztZQUNoQixHQUFHLEVBQUUsS0FBSyxFQUFFLE1BQTJCLEVBQXFCLEVBQUU7Z0JBQzVELGNBQWMsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7Z0JBQzVCLE9BQU8sRUFBRSxFQUFFLEVBQUUsV0FBVyxFQUF5QixDQUFDO1lBQ3BELENBQUM7U0FDRixDQUFDO1FBQ0YsTUFBTSxRQUFRLEdBQUc7WUFDZixTQUFTLEVBQUUsR0FBRyxFQUFFLENBQUMsU0FBUztTQUNILENBQUM7UUFDMUIsTUFBTSxLQUFLLEdBQUcsSUFBSSxxQkFBZSxDQUFDLEtBQUssRUFBRSxRQUFRLENBQUMsQ0FBQztRQUVuRCxNQUFNLEtBQUssQ0FBQyx5QkFBeUIsQ0FDbkMsNkJBQWdCLENBQUMsS0FBSyxFQUN0QixpQkFBaUIsRUFDakIsU0FBUyxFQUNULFNBQVMsRUFDVCxTQUFTLEVBQ1QsU0FBUyxFQUNULFNBQVMsRUFDVCxTQUFTLEVBQ1QsU0FBUyxFQUNULFNBQVMsQ0FDVixDQUFDO1FBRUYsZ0JBQU0sQ0FBQyxlQUFlLENBQUMsZUFBZSxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBQzVDLGdCQUFNLENBQUMsV0FBVyxDQUFDLGNBQWMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFDdEQsZ0JBQU0sQ0FBQyxXQUFXLENBQUMsY0FBYyxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sRUFBRSxTQUFTLENBQUMsQ0FBQztRQUN4RCxnQkFBTSxDQUFDLFdBQVcsQ0FBQyxjQUFjLENBQUMsQ0FBQyxDQUFDLENBQUMsWUFBWSxFQUFFLFNBQVMsQ0FBQyxDQUFDO0lBQ2hFLENBQUMsQ0FBQyxDQUFDO0lBRUgsRUFBRSxDQUFDLHdFQUF3RSxFQUFFO1FBQzNFLE1BQU0sSUFBSSxHQUFHLElBQUEsb0NBQW9CLEVBQUM7WUFDaEMsaUJBQWlCLEVBQUUsQ0FBQyxFQUFFLElBQUksRUFBRSw2QkFBZ0IsQ0FBQyxLQUFLLEVBQUUsT0FBTyxFQUFFLElBQUksVUFBVSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7WUFDekYsV0FBVyxFQUFFO2dCQUNYLEVBQUUsSUFBSSxFQUFFLDZCQUFnQixDQUFDLEtBQUssRUFBRSxFQUFFLEVBQUUsNkJBQWdCLENBQUMsSUFBSSxFQUFFLE9BQU8sRUFBRSxJQUFJLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUU7Z0JBQ3pGLEVBQUUsSUFBSSxFQUFFLDZCQUFnQixDQUFDLEtBQUssRUFBRSxFQUFFLEVBQUUsNkJBQWdCLENBQUMsTUFBTSxFQUFFLE9BQU8sRUFBRSxJQUFJLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUU7YUFDNUY7U0FDRixDQUFDLENBQUM7UUFFSCxNQUFNLE9BQU8sR0FBRyxJQUFBLHNDQUFzQixFQUFDLElBQUksRUFBRSw2QkFBZ0IsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNwRSxnQkFBTSxDQUFDLGVBQWUsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsRUFBRSxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDbEcsZ0JBQU0sQ0FBQyxXQUFXLENBQUMsT0FBTyxDQUFDLFdBQVcsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDbEQsZ0JBQU0sQ0FBQyxXQUFXLENBQUMsT0FBTyxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsNkJBQWdCLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDckUsZ0JBQU0sQ0FBQyxlQUFlLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxFQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFFdEYsTUFBTSxTQUFTLEdBQUcsSUFBQSxzQ0FBc0IsRUFBQyxJQUFJLEVBQUUsNkJBQWdCLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDeEUsZ0JBQU0sQ0FBQyxXQUFXLENBQUMsU0FBUyxDQUFDLFdBQVcsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDcEQsZ0JBQU0sQ0FBQyxXQUFXLENBQUMsU0FBUyxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsNkJBQWdCLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDM0UsQ0FBQyxDQUFDLENBQUM7SUFFSCxFQUFFLENBQUMseUNBQXlDLEVBQUU7UUFDNUMsZ0JBQU0sQ0FBQyxNQUFNLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBQSxzQ0FBc0IsRUFBQyxLQUFLLEVBQUUsNkJBQWdCLENBQUMsSUFBSSxDQUFDLEVBQUUsOEJBQThCLENBQUMsQ0FBQztRQUMxRyxNQUFNLFVBQVUsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsRUFBRSxJQUFJLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUMvRSxnQkFBTSxDQUFDLE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFBLHNDQUFzQixFQUFDLFVBQVUsRUFBRSw2QkFBZ0IsQ0FBQyxJQUFJLENBQUMsRUFBRSxzQkFBc0IsQ0FBQyxDQUFDO1FBQ3ZHLE1BQU0sUUFBUSxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLEVBQUUsSUFBSSxFQUFFLENBQUMsRUFBRSxPQUFPLEVBQUUsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUNoSCxRQUFRLENBQ1QsQ0FBQztRQUNGLGdCQUFNLENBQUMsTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUEsc0NBQXNCLEVBQUMsUUFBUSxFQUFFLDZCQUFnQixDQUFDLElBQUksQ0FBQyxFQUFFLHNCQUFzQixDQUFDLENBQUM7SUFDdkcsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQztBQUVILFFBQVEsQ0FBQyxpQ0FBaUMsRUFBRTtJQUMxQyxJQUFJLGdCQUF3QixDQUFDO0lBQzdCLElBQUksWUFBb0IsQ0FBQztJQUN6QixJQUFJLGlCQUF5QixDQUFDO0lBQzlCLElBQUksYUFBcUIsQ0FBQztJQUMxQixJQUFJLGVBQStCLENBQUM7SUFDcEMsSUFBSSxjQUF1QixDQUFDO0lBRTVCLE1BQU0sU0FBUyxHQUFHLGdCQUFnQixDQUFDO0lBQ25DLE1BQU0sZUFBZSxHQUFHLENBQUMsQ0FBQztJQUMxQixNQUFNLElBQUksR0FBRyxNQUFNLENBQUM7SUFDcEIsTUFBTSxPQUFPLEdBQUcsQ0FBQyxDQUFDLFlBQVksQ0FBQztRQUM3QixDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsVUFBVSxFQUFFLENBQUMsQ0FBQyxNQUFNLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQyxNQUFNLEVBQUUsU0FBUyxFQUFFLENBQUMsQ0FBQyxNQUFNLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQyxNQUFNLEVBQUUsT0FBTyxFQUFFLENBQUMsQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUMxRyxDQUFDLENBQUMsT0FBTyxDQUFDLEVBQUUsTUFBTSxFQUFFLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQztLQUNoQyxDQUFDLENBQUM7SUFFSCxNQUFNLENBQUMsS0FBSztRQUNWLE1BQU0sT0FBTyxHQUFHLE1BQU0scUJBQU8sQ0FBQyx5QkFBeUIsRUFBRSxDQUFDO1FBQzFELE1BQU0sR0FBRyxHQUFHLE1BQU0seUJBQVcsQ0FBQyx1QkFBdUIsRUFBRSxDQUFDO1FBQ3hELGdCQUFnQixHQUFHLE9BQU8sQ0FBQyw2QkFBZ0IsQ0FBQyxJQUFJLENBQUMsQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUNoRSxpQkFBaUIsR0FBRyxPQUFPLENBQUMsNkJBQWdCLENBQUMsS0FBSyxDQUFDLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDbEUsWUFBWSxHQUFHLEdBQUcsQ0FBQyw2QkFBZ0IsQ0FBQyxJQUFJLENBQUMsQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUN4RCxhQUFhLEdBQUcsR0FBRyxDQUFDLDZCQUFnQixDQUFDLEtBQUssQ0FBQyxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQzFELE1BQU0sUUFBUSxHQUFHLE1BQU0sSUFBQSxpQ0FBa0IsRUFBQyxTQUFTLENBQUMsQ0FBQztRQUNyRCxlQUFlLEdBQUcsTUFBTSxHQUFHLENBQUMsY0FBYyxDQUFDLEVBQUUsVUFBVSxFQUFFLFFBQVEsQ0FBQyxVQUFVLEVBQUUsQ0FBQyxDQUFDO1FBQ2hGLGNBQWMsR0FBRyxNQUFNLEdBQUcsQ0FBQyxPQUFPLENBQUMsRUFBRSxVQUFVLEVBQUUsUUFBUSxDQUFDLFNBQVMsRUFBRSxDQUFDLENBQUM7SUFDekUsQ0FBQyxDQUFDLENBQUM7SUFFSCxLQUFLLFVBQVUsY0FBYyxDQUMzQixLQUFzRSxFQUN0RSxpQkFBeUM7UUFFekMsTUFBTSxFQUFFLEtBQUssRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFFLGVBQWUsRUFBRSxjQUFjLEVBQUUsR0FBRyxxQkFBcUIsRUFBRSxDQUFDO1FBQzNGLE1BQU0sS0FBSyxHQUFHLElBQUksa0NBQWtCLENBQUMsS0FBSyxFQUFFLFFBQVEsQ0FBQyxDQUFDO1FBQ3RELEtBQUssQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLHNDQUFzQyxDQUFDLENBQUMsUUFBUSxDQUFDO1lBQ2pFLGNBQWMsRUFBRSxjQUFjO1lBQzlCLG1CQUFtQixFQUFFLGNBQWM7WUFDbkMsdUJBQXVCLEVBQUUsU0FBUztTQUNuQyxDQUFDLENBQUM7UUFDSCxNQUFNLFNBQVMsR0FBRyxJQUFJLHVCQUFTLENBQUMsTUFBTSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsNkJBQWdCLENBQUMsS0FBSyxFQUFFLGlCQUFpQixFQUFFLGFBQWEsRUFBRSxJQUFJLENBQUMsQ0FBQztRQUM3RyxJQUFJLFNBQWlDLENBQUM7UUFDdEMsSUFBSSxnQkFBZ0IsR0FBRyxFQUFFLENBQUM7UUFDMUIsSUFBSSxNQUFNLEdBQUcsQ0FBQyxDQUFDO1FBQ2YsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLElBQVksRUFBRSxFQUFFLENBQUMsQ0FBQztZQUNoQyxJQUFJLEVBQUUsQ0FBQyxPQUFnQixFQUFFLEVBQUUsQ0FBQyxDQUFDO2dCQUMzQixNQUFNLEVBQUUsS0FBSyxJQUFJLEVBQUU7b0JBQ2pCLE1BQU0sSUFBSSxHQUFHLElBQUEsd0JBQWUsRUFBQyxPQUFPLEVBQUUsT0FBTyxFQUFFLHNCQUFzQixDQUFDLENBQUM7b0JBQ3ZFLGdCQUFNLENBQUMsV0FBVyxDQUFDLElBQUksRUFBRSxrQkFBa0IsQ0FBQyxDQUFDO29CQUM3QyxnQkFBTSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsVUFBVSxFQUFFLGVBQWUsQ0FBQyxDQUFDO29CQUNyRCxnQkFBTSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLDZCQUFjLENBQUMsS0FBSyxDQUFDLENBQUM7b0JBQ3BELGdCQUFNLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsMkJBQVksQ0FBQyxLQUFLLENBQUMsQ0FBQztvQkFDdkQsSUFBSSxNQUFNLEVBQUUsS0FBSyxDQUFDLEVBQUUsQ0FBQzt3QkFDbkIsZ0JBQU0sQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxtQ0FBb0IsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLENBQUM7d0JBQ3ZFLGdCQUFNLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsU0FBUyxDQUFDLENBQUM7d0JBQzNDLE1BQU0sT0FBTyxHQUFHLElBQUEsd0JBQWUsRUFBQyw0Q0FBNkIsRUFBRSxJQUFJLENBQUMsT0FBTyxFQUFFLHNCQUFzQixDQUFDLENBQUM7d0JBQ3JHLGdCQUFNLENBQUMsZUFBZSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUU7NEJBQ2xELGlCQUFpQjs0QkFDakIsYUFBYTs0QkFDYixrQkFBa0I7NEJBQ2xCLFVBQVU7eUJBQ1gsQ0FBQyxDQUFDO3dCQUNILGdCQUFNLENBQUMsV0FBVyxDQUFDLE9BQU8sQ0FBQyxXQUFXLEVBQUUsZUFBZSxDQUFDLENBQUM7d0JBQ3pELGdCQUFNLENBQUMsV0FBVyxDQUFDLE9BQU8sQ0FBQyxlQUFlLEVBQUUsZUFBZSxDQUFDLENBQUM7d0JBQzdELGdCQUFnQixHQUFHLE9BQU8sQ0FBQyxnQkFBZ0IsQ0FBQzt3QkFDNUMsTUFBTSxVQUFVLEdBQUcsTUFBTSxHQUFHLENBQUMsT0FBTyxDQUFDLEVBQUUsVUFBVSxFQUFFLE9BQU8sQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDLENBQUM7d0JBQy9FLE1BQU0sV0FBVyxHQUFHLE1BQU0sc0JBQVEsQ0FBQyxnQkFBZ0IsQ0FBQyxPQUFPLENBQUMsUUFBUSxFQUFFLFVBQVUsQ0FBQyxDQUFDO3dCQUNsRixNQUFNLFVBQVUsR0FBRyxNQUFNLFNBQVMsQ0FBQyxVQUFVLEVBQUUsQ0FBQzt3QkFDaEQsTUFBTSxDQUFDLFFBQVEsQ0FBQyxHQUFHLFNBQVMsQ0FBQyxzQkFBc0IsQ0FBQzs0QkFDbEQsRUFBRSxJQUFJLEVBQUUsNkJBQWdCLENBQUMsSUFBSSxFQUFFLE9BQU8sRUFBRSxJQUFJLFVBQVUsQ0FBQyxXQUFXLENBQUMsRUFBRTt5QkFDdEUsQ0FBQyxDQUFDO3dCQUNILGdCQUFNLENBQUMsRUFBRSxDQUFDLFFBQVEsQ0FBQyxDQUFDO3dCQUNwQixTQUFTLEdBQUcsUUFBUSxDQUFDLE9BQU8sQ0FBQzt3QkFDN0IsTUFBTSxNQUFNLEdBQUcsTUFBTSxzQkFBUSxDQUFDLG9CQUFvQixDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLE9BQU8sQ0FBQyxFQUFFLGVBQWUsQ0FBQyxDQUFDO3dCQUNyRyxPQUFPOzRCQUNMLFNBQVM7NEJBQ1QsU0FBUyxFQUNQLEtBQUssS0FBSyxjQUFjLENBQUMsQ0FBQyxDQUFDLEVBQUUsR0FBRyxNQUFNLEVBQUUsT0FBTyxFQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLE1BQU07eUJBQ3pHLENBQUM7b0JBQ0osQ0FBQztvQkFDRCxnQkFBTSxDQUFDLFdBQVcsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLENBQUM7b0JBQzlCLGdCQUFNLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsbUNBQW9CLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxDQUFDO29CQUN2RSxnQkFBTSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLFNBQVMsQ0FBQyxDQUFDO29CQUMzQyxNQUFNLE9BQU8sR0FBRyxJQUFBLHdCQUFlLEVBQUMsNENBQTZCLEVBQUUsSUFBSSxDQUFDLE9BQU8sRUFBRSxzQkFBc0IsQ0FBQyxDQUFDO29CQUNyRyxnQkFBTSxDQUFDLGVBQWUsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsV0FBVyxFQUFFLFVBQVUsQ0FBQyxDQUFDLENBQUM7b0JBQy9FLGdCQUFNLENBQUMsV0FBVyxDQUFDLE9BQU8sQ0FBQyxTQUFTLEVBQUUsU0FBUyxDQUFDLENBQUM7b0JBQ2pELE1BQU0sV0FBVyxHQUFHLE1BQU0sc0JBQVEsQ0FBQyxnQkFBZ0IsQ0FDakQsT0FBTyxDQUFDLFFBQVEsRUFDaEIsTUFBTSxHQUFHLENBQUMsT0FBTyxDQUFDLEVBQUUsVUFBVSxFQUFFLGdCQUFnQixFQUFFLENBQUMsQ0FDcEQsQ0FBQztvQkFDRixnQkFBTSxDQUFDLGVBQWUsQ0FDcEIsU0FBUyxDQUFDLHNCQUFzQixDQUFDLENBQUMsRUFBRSxJQUFJLEVBQUUsNkJBQWdCLENBQUMsSUFBSSxFQUFFLE9BQU8sRUFBRSxJQUFJLFVBQVUsQ0FBQyxXQUFXLENBQUMsRUFBRSxDQUFDLENBQUMsRUFDekcsRUFBRSxDQUNILENBQUM7b0JBQ0YsZ0JBQU0sQ0FBQyxFQUFFLENBQUMsU0FBUyxDQUFDLENBQUM7b0JBQ3JCLE1BQU0sTUFBTSxHQUFHLE1BQU0sc0JBQVEsQ0FBQyxvQkFBb0IsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxFQUFFLGVBQWUsQ0FBQyxDQUFDO29CQUM1RixNQUFNLG9CQUFvQixHQUFHLFNBQVMsQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO29CQUMzRCxPQUFPO3dCQUNMLFNBQVMsRUFBRSxLQUFLLEtBQUssU0FBUyxDQUFDLENBQUMsQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDLENBQUMsU0FBUzt3QkFDaEUsb0JBQW9CLEVBQ2xCLEtBQUssS0FBSyxnQkFBZ0I7NEJBQ3hCLENBQUMsQ0FBQyxHQUFHLG9CQUFvQixDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxvQkFBb0IsQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFOzRCQUN6RixDQUFDLENBQUMsb0JBQW9CO3dCQUMxQixTQUFTLEVBQ1AsS0FBSyxLQUFLLGNBQWMsQ0FBQyxDQUFDLENBQUMsRUFBRSxHQUFHLE1BQU0sRUFBRSxPQUFPLEVBQUUsTUFBTSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsTUFBTTtxQkFDekcsQ0FBQztnQkFDSixDQUFDO2FBQ0YsQ0FBQztTQUNILENBQUMsQ0FBQyxDQUFDO1FBRUosSUFBSSxDQUFDO1lBQ0gsTUFBTSxNQUFNLEdBQUcsTUFBTSxLQUFLLENBQUMsd0JBQXdCLENBQUM7Z0JBQ2xELFVBQVUsRUFBRSxZQUFZO2dCQUN4QixVQUFVLEVBQUUsZUFBZTtnQkFDM0IsTUFBTSxFQUFFLFNBQVM7Z0JBQ2pCLFdBQVcsRUFBRSxlQUFlO2dCQUM1QixlQUFlO2dCQUNmLGFBQWEsRUFBRSxjQUFjO2dCQUM3QixlQUFlLEVBQUUsZ0JBQWdCO2dCQUNqQyxnQkFBZ0IsRUFBRSxnQkFBZ0I7Z0JBQ2xDLG1CQUFtQixFQUFFLFlBQVk7YUFDbEMsQ0FBQyxDQUFDO1lBQ0gsT0FBTyxFQUFFLE1BQU0sRUFBRSxlQUFlLEVBQUUsY0FBYyxFQUFFLFNBQVMsRUFBRSxNQUFNLEVBQUUsQ0FBQztRQUN4RSxDQUFDO2dCQUFTLENBQUM7WUFDVCxpQkFBaUIsRUFBRSxJQUFJLENBQUMsR0FBRyxjQUFjLENBQUMsQ0FBQztRQUM3QyxDQUFDO0lBQ0gsQ0FBQztJQUVELFNBQVMsQ0FBQztRQUNSLEtBQUssQ0FBQyxPQUFPLEVBQUUsQ0FBQztJQUNsQixDQUFDLENBQUMsQ0FBQztJQUVILEVBQUUsQ0FBQyw4RkFBOEYsRUFBRSxLQUFLO1FBQ3RHLE1BQU0sRUFBRSxNQUFNLEVBQUUsZUFBZSxFQUFFLGNBQWMsRUFBRSxTQUFTLEVBQUUsTUFBTSxFQUFFLEdBQUcsTUFBTSxjQUFjLEVBQUUsQ0FBQztRQUM5RixnQkFBTSxDQUFDLFdBQVcsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDOUIsZ0JBQU0sQ0FBQyxlQUFlLENBQUMsY0FBYyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsTUFBTSxFQUFFLEVBQUUsRUFBRSxDQUFDLE1BQU0sQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsUUFBUSxFQUFFLE9BQU8sRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDO1FBQ3ZHLGdCQUFNLENBQUMsZUFBZSxDQUNwQixDQUFDLE1BQU0sQ0FBQyxZQUFZLENBQUMsRUFBRSxFQUFFLE1BQU0sQ0FBQyxjQUFjLENBQUMsRUFBRSxFQUFFLE1BQU0sQ0FBQyxhQUFhLENBQUMsRUFBRSxDQUFDLEVBQzNFLENBQUMsWUFBWSxFQUFFLGNBQWMsRUFBRSxhQUFhLENBQUMsQ0FDOUMsQ0FBQztRQUNGLEtBQUssTUFBTSxRQUFRLElBQUksY0FBYyxFQUFFLENBQUM7WUFDdEMsZ0JBQU0sQ0FBQyxXQUFXLENBQUMsUUFBUSxDQUFDLE1BQU0sRUFBRSxTQUFTLENBQUMsQ0FBQztZQUMvQyxnQkFBTSxDQUFDLFdBQVcsQ0FBQyxRQUFRLENBQUMseUJBQXlCLEVBQUUsSUFBSSxDQUFDLENBQUM7WUFDN0QsZ0JBQU0sQ0FBQyxXQUFXLENBQUMsUUFBUSxDQUFDLGNBQWMsRUFBRSxTQUFTLENBQUMsaUJBQWlCLEVBQUUsQ0FBQyxDQUFDO1lBQzNFLGdCQUFNLENBQUMsV0FBVyxDQUFDLFFBQVEsQ0FBQyxPQUFPLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFDNUMsZ0JBQU0sQ0FBQyxXQUFXLENBQUMsUUFBUSxDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUMsQ0FBQztRQUM3QyxDQUFDO1FBQ0QsTUFBTSxTQUFTLEdBQUcsY0FBYyxDQUFDLElBQUksQ0FBQyxDQUFDLEVBQUUsTUFBTSxFQUFFLEVBQUUsRUFBRSxDQUFDLE1BQU0sS0FBSyxNQUFNLENBQUMsQ0FBQztRQUN6RSxNQUFNLFdBQVcsR0FBRyxjQUFjLENBQUMsSUFBSSxDQUFDLENBQUMsRUFBRSxNQUFNLEVBQUUsRUFBRSxFQUFFLENBQUMsTUFBTSxLQUFLLFFBQVEsQ0FBQyxDQUFDO1FBQzdFLE1BQU0sVUFBVSxHQUFHLGNBQWMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxFQUFFLE1BQU0sRUFBRSxFQUFFLEVBQUUsQ0FBQyxNQUFNLEtBQUssT0FBTyxDQUFDLENBQUM7UUFDM0UsZ0JBQU0sQ0FBQyxFQUFFLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDckIsZ0JBQU0sQ0FBQyxFQUFFLENBQUMsV0FBVyxDQUFDLENBQUM7UUFDdkIsZ0JBQU0sQ0FBQyxFQUFFLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDdEIsZ0JBQU0sQ0FBQyxXQUFXLENBQUMsU0FBUyxDQUFDLE1BQU0sRUFBRSxjQUFjLENBQUMsQ0FBQztRQUNyRCxnQkFBTSxDQUFDLFdBQVcsQ0FBQyxXQUFXLENBQUMsTUFBTSxFQUFFLGdCQUFnQixDQUFDLENBQUM7UUFDekQsZ0JBQU0sQ0FBQyxXQUFXLENBQUMsVUFBVSxDQUFDLE1BQU0sRUFBRSxlQUFlLENBQUMsQ0FBQztRQUN2RCxnQkFBTSxDQUFDLFdBQVcsQ0FBQyxlQUFlLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQzlDLGdCQUFNLENBQUMsV0FBVyxDQUFDLFNBQVMsQ0FBQyxZQUFZLEVBQUUsYUFBYSxlQUFlLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQzlFLE1BQU0sWUFBWSxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLFlBQVksQ0FBQyxZQUFZLEVBQUUsS0FBSyxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsSUFBSSxFQUFFLEVBQUUsUUFBUSxDQUFDLENBQUM7UUFDL0csZ0JBQU0sQ0FBQyxlQUFlLENBQUMsWUFBWSxFQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLENBQUMsQ0FBQyxFQUFFLFFBQVEsQ0FBQyxDQUFDLENBQUM7UUFDaEYsZ0JBQU0sQ0FBQyxrQkFBa0IsQ0FBQyxZQUFZLEVBQUUsZ0JBQWdCLENBQUMsQ0FBQztRQUMxRCxnQkFBTSxDQUFDLGtCQUFrQixDQUFDLFlBQVksRUFBRSxTQUFTLENBQUMsV0FBVyxFQUFFLENBQUMsQ0FBQztRQUNqRSxnQkFBTSxDQUFDLFdBQVcsQ0FBQyxTQUFTLENBQUMsbUJBQW1CLEVBQUUsU0FBUyxDQUFDLENBQUM7UUFDN0QsTUFBTSxPQUFPLEdBQUcsTUFBTSxDQUFDLFlBQVksQ0FBQyxtQkFBbUIsQ0FBQztRQUN4RCxnQkFBTSxDQUFDLEVBQUUsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUNuQixNQUFNLFlBQVksR0FBRyxzQkFBUSxDQUFDLHlCQUF5QixDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUFDLEVBQUUsUUFBUSxDQUFDLENBQUMsQ0FBQztRQUNuSCxnQkFBTSxDQUFDLGVBQWUsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxRQUFRLENBQUMsRUFBRSxZQUFZLENBQUMsQ0FBQztRQUN6RSxnQkFBTSxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxHQUFHLENBQUMsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLEVBQUUsU0FBUyxDQUFDLGlCQUFpQixFQUFFLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQzlHLGdCQUFNLENBQUMsTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFDLGlCQUFpQixDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUM7UUFDckQsZ0JBQU0sQ0FBQyxXQUFXLENBQUMsV0FBVyxDQUFDLFlBQVksRUFBRSxTQUFTLENBQUMsQ0FBQztRQUN4RCxnQkFBTSxDQUFDLFdBQVcsQ0FBQyxVQUFVLENBQUMsWUFBWSxFQUFFLFNBQVMsQ0FBQyxDQUFDO0lBQ3pELENBQUMsQ0FBQyxDQUFDO0lBRUgsRUFBRSxDQUFDLHNFQUFzRSxFQUFFLEtBQUs7UUFDOUUsTUFBTSxFQUFFLEtBQUssRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFFLGNBQWMsRUFBRSxHQUFHLHFCQUFxQixFQUFFLENBQUM7UUFDMUUsTUFBTSxLQUFLLEdBQUcsSUFBSSxrQ0FBa0IsQ0FBQyxLQUFLLEVBQUUsUUFBUSxDQUFDLENBQUM7UUFFdEQsTUFBTSxnQkFBTSxDQUFDLE9BQU8sQ0FDbEIsS0FBSyxDQUFDLHdCQUF3QixDQUFDO1lBQzdCLFVBQVUsRUFBRSxZQUFZO1lBQ3hCLFVBQVUsRUFBRSxlQUFlO1lBQzNCLE1BQU0sRUFBRSxTQUFTO1lBQ2pCLFdBQVcsRUFBRSxlQUFlO1lBQzVCLGVBQWUsRUFBRSxVQUFVO1lBQzNCLGFBQWEsRUFBRSxjQUFjO1lBQzdCLGVBQWUsRUFBRSxnQkFBZ0I7WUFDakMsZ0JBQWdCLEVBQUUsZ0JBQWdCO1lBQ2xDLG1CQUFtQixFQUFFLFlBQVk7U0FDbEMsQ0FBQyxFQUNGLDJCQUEyQixDQUM1QixDQUFDO1FBQ0YsZ0JBQU0sQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxLQUFLLENBQUMsQ0FBQztRQUN2QyxnQkFBTSxDQUFDLGVBQWUsQ0FBQyxjQUFjLEVBQUUsRUFBRSxDQUFDLENBQUM7SUFDN0MsQ0FBQyxDQUFDLENBQUM7SUFFSCxNQUFNLE1BQU0sR0FBMEU7UUFDcEYsY0FBYztRQUNkLGNBQWM7UUFDZCxTQUFTO1FBQ1QsZ0JBQWdCO0tBQ2pCLENBQUM7SUFDRixLQUFLLE1BQU0sS0FBSyxJQUFJLE1BQU0sRUFBRSxDQUFDO1FBQzNCLEVBQUUsQ0FBQyxXQUFXLEtBQUssK0JBQStCLEVBQUUsS0FBSztZQUN2RCxNQUFNLGlCQUFpQixHQUEwQixFQUFFLENBQUM7WUFDcEQsTUFBTSxnQkFBTSxDQUFDLE9BQU8sQ0FDbEIsR0FBRyxFQUFFLENBQUMsY0FBYyxDQUFDLEtBQUssRUFBRSxpQkFBaUIsQ0FBQyxFQUM5QyxLQUFLLEtBQUssU0FBUztnQkFDakIsQ0FBQyxDQUFDLGFBQWE7Z0JBQ2YsQ0FBQyxDQUFDLEtBQUssS0FBSyxnQkFBZ0I7b0JBQzVCLENBQUMsQ0FBQyxrQkFBa0I7b0JBQ3BCLENBQUMsQ0FBQyxnQ0FBZ0MsQ0FDckMsQ0FBQztZQUNGLGdCQUFNLENBQUMsZUFBZSxDQUFDLGlCQUFpQixFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBQ2hELENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztBQUNILENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGFzc2VydCBmcm9tICdhc3NlcnQnO1xuaW1wb3J0ICogYXMgcGdwIGZyb20gJ29wZW5wZ3AnO1xuaW1wb3J0ICogYXMgc2lub24gZnJvbSAnc2lub24nO1xuaW1wb3J0IHsgTVBTQ29tbXMsIE1QU1V0aWwsIE1QU1R5cGVzLCBNcHNEZXJpdmUsIE1wc1ZyZlV0aWxzIH0gZnJvbSAnQGJpdGdvL3Nkay1saWItbXBjJztcbmltcG9ydCB7XG4gIEVkZHNhTVBDdjJEZXJpdmVSb3VuZDFSZXF1ZXN0LFxuICBFZGRzYU1QQ3YyRGVyaXZlUm91bmQyUmVxdWVzdCxcbiAgS2V5Q3VydmVFbnVtLFxuICBLZXlHZW5UeXBlRW51bSxcbiAgTVBDdjJLZXlHZW5TdGF0ZUVudW0sXG59IGZyb20gJ0BiaXRnby9wdWJsaWMtdHlwZXMnO1xuaW1wb3J0IHsgZGVjb2RlIH0gZnJvbSAnY2Jvci14JztcbmltcG9ydCAqIGFzIHQgZnJvbSAnaW8tdHMnO1xuXG5pbXBvcnQgeyBFZGRzYU1QQ3YyVXRpbHMsIEJpdEdvQmFzZSwgSUJhc2VDb2luLCBLZXljaGFpbiB9IGZyb20gJy4uLy4uLy4uLy4uLy4uLy4uL3NyYyc7XG5pbXBvcnQgeyBkZWNvZGVXaXRoQ29kZWMgfSBmcm9tICcuLi8uLi8uLi8uLi8uLi8uLi9zcmMvYml0Z28vdXRpbHMvY29kZWNzJztcbmltcG9ydCB7IGJ1aWxkU2FmZU1wY0tleUVudmVsb3BlcyB9IGZyb20gJy4uLy4uLy4uLy4uLy4uLy4uL3NyYy9iaXRnby91dGlscy90c3Mva2V5U2hhcmVFbnZlbG9wZSc7XG5pbXBvcnQge1xuICBFZGRzYVZyZk1QQ3YyVXRpbHMsXG4gIGRlc2VyaWFsaXplVnJmTWVzc2FnZXMsXG4gIHNlcmlhbGl6ZVZyZk1lc3NhZ2VzLFxufSBmcm9tICcuLi8uLi8uLi8uLi8uLi8uLi9zcmMvYml0Z28vdXRpbHMvdHNzL2VkZHNhL2VkZHNhVnJmTVBDdjInO1xuaW1wb3J0IHsgTVBDdjJQYXJ0aWVzRW51bSB9IGZyb20gJy4uLy4uLy4uLy4uLy4uLy4uL3NyYy9iaXRnby91dGlscy90c3MvZWNkc2EvdHlwZXNNUEN2Mic7XG5pbXBvcnQgeyBnZW5lcmF0ZUdQR0tleVBhaXIgfSBmcm9tICcuLi8uLi8uLi8uLi8uLi8uLi9zcmMvYml0Z28vdXRpbHMvb3BlbmdwZ1V0aWxzJztcblxuY29uc3QgVWludDhBcnJheUNvZGVjID0gbmV3IHQuVHlwZTxVaW50OEFycmF5LCBVaW50OEFycmF5LCB1bmtub3duPihcbiAgJ1VpbnQ4QXJyYXknLFxuICAodmFsdWUpOiB2YWx1ZSBpcyBVaW50OEFycmF5ID0+IHZhbHVlIGluc3RhbmNlb2YgVWludDhBcnJheSxcbiAgKHZhbHVlLCBjb250ZXh0KSA9PiAodmFsdWUgaW5zdGFuY2VvZiBVaW50OEFycmF5ID8gdC5zdWNjZXNzKHZhbHVlKSA6IHQuZmFpbHVyZSh2YWx1ZSwgY29udGV4dCkpLFxuICB0LmlkZW50aXR5XG4pO1xuXG5jb25zdCBWcmZFbnZlbG9wZSA9IHQudHlwZSh7XG4gIHZlcnNpb246IHQubGl0ZXJhbCgxKSxcbiAgcHJ2S2V5U2hhcmU6IFVpbnQ4QXJyYXlDb2RlYyxcbiAgdnJmOiBVaW50OEFycmF5Q29kZWMsXG59KTtcblxudHlwZSBBZGRlZEtleWNoYWluUGFyYW1zID0ge1xuICBzb3VyY2U/OiBzdHJpbmc7XG4gIGVuY3J5cHRlZFBydj86IHN0cmluZztcbiAgcmVkdWNlZEVuY3J5cHRlZFBydj86IHN0cmluZztcbiAgc2FmZUlkPzogc3RyaW5nO1xuICBwYXJlbnQ/OiBzdHJpbmc7XG4gIGRlcml2ZWRGcm9tUGFyZW50V2l0aFBhdGg/OiBzdHJpbmc7XG4gIGNvbW1vbktleWNoYWluPzogc3RyaW5nO1xuICBpc01QQ3YyPzogYm9vbGVhbjtcbiAga2V5VHlwZT86IHN0cmluZztcbn07XG5cbmZ1bmN0aW9uIGRlY29kZVZyZkVudmVsb3BlKGVuY29kZWQ6IEJ1ZmZlcik6IHQuVHlwZU9mPHR5cGVvZiBWcmZFbnZlbG9wZT4ge1xuICByZXR1cm4gZGVjb2RlV2l0aENvZGVjKFZyZkVudmVsb3BlLCBkZWNvZGUoZW5jb2RlZCksICdWUkYga2V5IGVudmVsb3BlJyk7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZUtleWNoYWluRml4dHVyZSgpIHtcbiAgY29uc3QgZW5jcnlwdGVkSW5wdXRzOiBzdHJpbmdbXSA9IFtdO1xuICBjb25zdCBhZGRlZEtleWNoYWluczogQWRkZWRLZXljaGFpblBhcmFtc1tdID0gW107XG4gIGNvbnN0IHBvc3QgPSBzaW5vbi5zdHViKCk7XG4gIGNvbnN0IGJpdGdvID0ge1xuICAgIGdldEVudjogKCkgPT4gJ2RldicsXG4gICAgdXJsOiAocGF0aDogc3RyaW5nKSA9PiBwYXRoLFxuICAgIHBvc3QsXG4gICAgZW5jcnlwdDogYXN5bmMgKHBhcmFtczogeyBpbnB1dDogc3RyaW5nIH0pOiBQcm9taXNlPHN0cmluZz4gPT4ge1xuICAgICAgZW5jcnlwdGVkSW5wdXRzLnB1c2gocGFyYW1zLmlucHV0KTtcbiAgICAgIHJldHVybiBgZW5jcnlwdGVkOiR7cGFyYW1zLmlucHV0fWA7XG4gICAgfSxcbiAgfSBhcyB1bmtub3duIGFzIEJpdEdvQmFzZTtcbiAgY29uc3Qga2V5Y2hhaW5zID0ge1xuICAgIGFkZDogYXN5bmMgKHBhcmFtczogQWRkZWRLZXljaGFpblBhcmFtcyk6IFByb21pc2U8S2V5Y2hhaW4+ID0+IHtcbiAgICAgIGFkZGVkS2V5Y2hhaW5zLnB1c2gocGFyYW1zKTtcbiAgICAgIHJldHVybiB7IGlkOiBgJHtwYXJhbXMuc291cmNlfS1jaGlsZGAsIHR5cGU6ICd0c3MnLCBlbmNyeXB0ZWRQcnY6IHBhcmFtcy5lbmNyeXB0ZWRQcnYgfTtcbiAgICB9LFxuICB9O1xuICBjb25zdCBiYXNlQ29pbiA9IHtcbiAgICBrZXljaGFpbnM6ICgpID0+IGtleWNoYWlucyxcbiAgfSBhcyB1bmtub3duIGFzIElCYXNlQ29pbjtcbiAgcmV0dXJuIHsgYml0Z28sIGJhc2VDb2luLCBwb3N0LCBlbmNyeXB0ZWRJbnB1dHMsIGFkZGVkS2V5Y2hhaW5zIH07XG59XG5cbmRlc2NyaWJlKCdFZERTQSBNUEN2MiBWUkYgcm9vdCBtYXRlcmlhbCcsIGZ1bmN0aW9uICgpIHtcbiAgaXQoJ2VuY29kZXMgc2lnbmluZyBhbmQgVlJGIHNoYXJlcyBpbiBib3RoIGZ1bGwgYW5kIHJlZHVjZWQgZW52ZWxvcGVzJywgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IHByaXZhdGVNYXRlcmlhbCA9IEJ1ZmZlci5mcm9tKCdzaWduaW5nLXNoYXJlJyk7XG4gICAgY29uc3QgcmVkdWNlZFByaXZhdGVNYXRlcmlhbCA9IEJ1ZmZlci5mcm9tKCdyZWR1Y2VkLXNpZ25pbmctc2hhcmUnKTtcbiAgICBjb25zdCB2cmZLZXlTaGFyZSA9IEJ1ZmZlci5mcm9tKCd2cmYtc2hhcmUnKTtcblxuICAgIGNvbnN0IHsgZW52ZWxvcGUsIHJlZHVjZWRFbnZlbG9wZSB9ID0gYnVpbGRTYWZlTXBjS2V5RW52ZWxvcGVzKFxuICAgICAgcHJpdmF0ZU1hdGVyaWFsLFxuICAgICAgcmVkdWNlZFByaXZhdGVNYXRlcmlhbCxcbiAgICAgIHZyZktleVNoYXJlXG4gICAgKTtcbiAgICBjb25zdCBkZWNvZGVkRW52ZWxvcGUgPSBkZWNvZGVWcmZFbnZlbG9wZShlbnZlbG9wZSk7XG4gICAgY29uc3QgZGVjb2RlZFJlZHVjZWRFbnZlbG9wZSA9IGRlY29kZVZyZkVudmVsb3BlKHJlZHVjZWRFbnZlbG9wZSk7XG5cbiAgICBhc3NlcnQuZGVlcFN0cmljdEVxdWFsKEJ1ZmZlci5mcm9tKGRlY29kZWRFbnZlbG9wZS5wcnZLZXlTaGFyZSksIHByaXZhdGVNYXRlcmlhbCk7XG4gICAgYXNzZXJ0LmRlZXBTdHJpY3RFcXVhbChCdWZmZXIuZnJvbShkZWNvZGVkRW52ZWxvcGUudnJmKSwgdnJmS2V5U2hhcmUpO1xuICAgIGFzc2VydC5kZWVwU3RyaWN0RXF1YWwoQnVmZmVyLmZyb20oZGVjb2RlZFJlZHVjZWRFbnZlbG9wZS5wcnZLZXlTaGFyZSksIHJlZHVjZWRQcml2YXRlTWF0ZXJpYWwpO1xuICAgIGFzc2VydC5kZWVwU3RyaWN0RXF1YWwoQnVmZmVyLmZyb20oZGVjb2RlZFJlZHVjZWRFbnZlbG9wZS52cmYpLCB2cmZLZXlTaGFyZSk7XG4gIH0pO1xuXG4gIGl0KCdrZWVwcyBvcmRpbmFyeSBNUEN2MiBwYXJ0aWNpcGFudCBtYXRlcmlhbCBhcyBiYXJlIGJhc2U2NCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCB7IGJpdGdvLCBiYXNlQ29pbiwgZW5jcnlwdGVkSW5wdXRzLCBhZGRlZEtleWNoYWlucyB9ID0gY3JlYXRlS2V5Y2hhaW5GaXh0dXJlKCk7XG4gICAgY29uc3QgdXRpbHMgPSBuZXcgRWRkc2FNUEN2MlV0aWxzKGJpdGdvLCBiYXNlQ29pbik7XG4gICAgY29uc3QgcHJpdmF0ZU1hdGVyaWFsID0gQnVmZmVyLmZyb20oJ3NpZ25pbmctc2hhcmUnKTtcbiAgICBjb25zdCByZWR1Y2VkUHJpdmF0ZU1hdGVyaWFsID0gQnVmZmVyLmZyb20oJ3JlZHVjZWQtc2lnbmluZy1zaGFyZScpO1xuXG4gICAgYXdhaXQgdXRpbHMuY3JlYXRlUGFydGljaXBhbnRLZXljaGFpbihcbiAgICAgIE1QQ3YyUGFydGllc0VudW0uVVNFUixcbiAgICAgICdjb21tb24ta2V5Y2hhaW4nLFxuICAgICAgcHJpdmF0ZU1hdGVyaWFsLFxuICAgICAgcmVkdWNlZFByaXZhdGVNYXRlcmlhbCxcbiAgICAgICdwYXNzcGhyYXNlJ1xuICAgICk7XG5cbiAgICBhc3NlcnQuZGVlcFN0cmljdEVxdWFsKGVuY3J5cHRlZElucHV0cywgW1xuICAgICAgcHJpdmF0ZU1hdGVyaWFsLnRvU3RyaW5nKCdiYXNlNjQnKSxcbiAgICAgIHJlZHVjZWRQcml2YXRlTWF0ZXJpYWwudG9TdHJpbmcoJ2Jhc2U2NCcpLFxuICAgIF0pO1xuICAgIGFzc2VydC5zdHJpY3RFcXVhbChhZGRlZEtleWNoYWluc1swXS5lbmNyeXB0ZWRQcnYsIGBlbmNyeXB0ZWQ6JHtwcml2YXRlTWF0ZXJpYWwudG9TdHJpbmcoJ2Jhc2U2NCcpfWApO1xuICAgIGFzc2VydC5zdHJpY3RFcXVhbChhZGRlZEtleWNoYWluc1swXS5zYWZlSWQsIHVuZGVmaW5lZCk7XG4gIH0pO1xuXG4gIGl0KCdyZWplY3RzIGEgcHVibGljLW9ubHkgYmFja3VwIG91dHNpZGUgYSBzYWZlIGNoaWxkIGRlcml2YXRpb24nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgY29uc3QgeyBiaXRnbywgYmFzZUNvaW4sIGVuY3J5cHRlZElucHV0cywgYWRkZWRLZXljaGFpbnMgfSA9IGNyZWF0ZUtleWNoYWluRml4dHVyZSgpO1xuICAgIGNvbnN0IHV0aWxzID0gbmV3IEVkZHNhTVBDdjJVdGlscyhiaXRnbywgYmFzZUNvaW4pO1xuXG4gICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoXG4gICAgICB1dGlscy5jcmVhdGVQYXJ0aWNpcGFudEtleWNoYWluKE1QQ3YyUGFydGllc0VudW0uQkFDS1VQLCAnY29tbW9uLWtleWNoYWluJywgdW5kZWZpbmVkLCB1bmRlZmluZWQsICdwYXNzcGhyYXNlJyksXG4gICAgICAvUHJpdmF0ZSBtYXRlcmlhbCBpcyByZXF1aXJlZCBmb3IgYmFja3VwIGtleWNoYWluL1xuICAgICk7XG4gICAgYXNzZXJ0LmRlZXBTdHJpY3RFcXVhbChlbmNyeXB0ZWRJbnB1dHMsIFtdKTtcbiAgICBhc3NlcnQuZGVlcFN0cmljdEVxdWFsKGFkZGVkS2V5Y2hhaW5zLCBbXSk7XG4gIH0pO1xuXG4gIGl0KCdlbmNyeXB0cyB0aGUgVlJGIGVudmVsb3BlIGFuZCB0YWdzIHRoZSBrZXljaGFpbiB3aXRoIHNhZmVJZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCBlbmNyeXB0ZWRJbnB1dHM6IHN0cmluZ1tdID0gW107XG4gICAgY29uc3QgYWRkZWRLZXljaGFpbnM6IEFkZGVkS2V5Y2hhaW5QYXJhbXNbXSA9IFtdO1xuICAgIGNvbnN0IGJpdGdvID0ge1xuICAgICAgZW5jcnlwdDogYXN5bmMgKHBhcmFtczogeyBpbnB1dDogc3RyaW5nIH0pOiBQcm9taXNlPHN0cmluZz4gPT4ge1xuICAgICAgICBlbmNyeXB0ZWRJbnB1dHMucHVzaChwYXJhbXMuaW5wdXQpO1xuICAgICAgICByZXR1cm4gYGVuY3J5cHRlZDoke3BhcmFtcy5pbnB1dH1gO1xuICAgICAgfSxcbiAgICB9IGFzIHVua25vd24gYXMgQml0R29CYXNlO1xuICAgIGNvbnN0IGtleWNoYWlucyA9IHtcbiAgICAgIGFkZDogYXN5bmMgKHBhcmFtczogQWRkZWRLZXljaGFpblBhcmFtcyk6IFByb21pc2U8S2V5Y2hhaW4+ID0+IHtcbiAgICAgICAgYWRkZWRLZXljaGFpbnMucHVzaChwYXJhbXMpO1xuICAgICAgICByZXR1cm4geyBpZDogJ3VzZXIta2V5JyB9IGFzIHVua25vd24gYXMgS2V5Y2hhaW47XG4gICAgICB9LFxuICAgIH07XG4gICAgY29uc3QgYmFzZUNvaW4gPSB7XG4gICAgICBrZXljaGFpbnM6ICgpID0+IGtleWNoYWlucyxcbiAgICB9IGFzIHVua25vd24gYXMgSUJhc2VDb2luO1xuICAgIGNvbnN0IHV0aWxzID0gbmV3IEVkZHNhTVBDdjJVdGlscyhiaXRnbywgYmFzZUNvaW4pO1xuICAgIGNvbnN0IHsgZW52ZWxvcGUsIHJlZHVjZWRFbnZlbG9wZSB9ID0gYnVpbGRTYWZlTXBjS2V5RW52ZWxvcGVzKFxuICAgICAgQnVmZmVyLmZyb20oJ3NpZ25pbmctc2hhcmUnKSxcbiAgICAgIEJ1ZmZlci5mcm9tKCdyZWR1Y2VkLXNpZ25pbmctc2hhcmUnKSxcbiAgICAgIEJ1ZmZlci5mcm9tKCd2cmYtc2hhcmUnKVxuICAgICk7XG5cbiAgICBhd2FpdCB1dGlscy5jcmVhdGVQYXJ0aWNpcGFudEtleWNoYWluKFxuICAgICAgTVBDdjJQYXJ0aWVzRW51bS5VU0VSLFxuICAgICAgJ2NvbW1vbi1rZXljaGFpbicsXG4gICAgICBlbnZlbG9wZSxcbiAgICAgIHJlZHVjZWRFbnZlbG9wZSxcbiAgICAgICdwYXNzcGhyYXNlJyxcbiAgICAgIHVuZGVmaW5lZCxcbiAgICAgIHVuZGVmaW5lZCxcbiAgICAgIHVuZGVmaW5lZCxcbiAgICAgIHVuZGVmaW5lZCxcbiAgICAgICdzYWZlLWlkJ1xuICAgICk7XG5cbiAgICBhc3NlcnQuZGVlcFN0cmljdEVxdWFsKGVuY3J5cHRlZElucHV0c1swXSwgZW52ZWxvcGUudG9TdHJpbmcoJ2Jhc2U2NCcpKTtcbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwoYWRkZWRLZXljaGFpbnNbMF0uc2FmZUlkLCAnc2FmZS1pZCcpO1xuICAgIGNvbnN0IGRlY29kZWQgPSBkZWNvZGVWcmZFbnZlbG9wZShCdWZmZXIuZnJvbShlbmNyeXB0ZWRJbnB1dHNbMF0sICdiYXNlNjQnKSk7XG4gICAgYXNzZXJ0LmRlZXBTdHJpY3RFcXVhbChCdWZmZXIuZnJvbShkZWNvZGVkLnZyZiksIEJ1ZmZlci5mcm9tKCd2cmYtc2hhcmUnKSk7XG4gIH0pO1xuXG4gIGl0KCd0YWdzIHRoZSBCaXRHbyBrZXljaGFpbiB3aXRoIHNhZmVJZCBhbmQgZG9lcyBub3QgZW5jcnlwdCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCBlbmNyeXB0ZWRJbnB1dHM6IHN0cmluZ1tdID0gW107XG4gICAgY29uc3QgYWRkZWRLZXljaGFpbnM6IEFkZGVkS2V5Y2hhaW5QYXJhbXNbXSA9IFtdO1xuICAgIGNvbnN0IGJpdGdvID0ge1xuICAgICAgZW5jcnlwdDogYXN5bmMgKHBhcmFtczogeyBpbnB1dDogc3RyaW5nIH0pOiBQcm9taXNlPHN0cmluZz4gPT4ge1xuICAgICAgICBlbmNyeXB0ZWRJbnB1dHMucHVzaChwYXJhbXMuaW5wdXQpO1xuICAgICAgICByZXR1cm4gYGVuY3J5cHRlZDoke3BhcmFtcy5pbnB1dH1gO1xuICAgICAgfSxcbiAgICB9IGFzIHVua25vd24gYXMgQml0R29CYXNlO1xuICAgIGNvbnN0IGtleWNoYWlucyA9IHtcbiAgICAgIGFkZDogYXN5bmMgKHBhcmFtczogQWRkZWRLZXljaGFpblBhcmFtcyk6IFByb21pc2U8S2V5Y2hhaW4+ID0+IHtcbiAgICAgICAgYWRkZWRLZXljaGFpbnMucHVzaChwYXJhbXMpO1xuICAgICAgICByZXR1cm4geyBpZDogJ2JpdGdvLWtleScgfSBhcyB1bmtub3duIGFzIEtleWNoYWluO1xuICAgICAgfSxcbiAgICB9O1xuICAgIGNvbnN0IGJhc2VDb2luID0ge1xuICAgICAga2V5Y2hhaW5zOiAoKSA9PiBrZXljaGFpbnMsXG4gICAgfSBhcyB1bmtub3duIGFzIElCYXNlQ29pbjtcbiAgICBjb25zdCB1dGlscyA9IG5ldyBFZGRzYU1QQ3YyVXRpbHMoYml0Z28sIGJhc2VDb2luKTtcblxuICAgIGF3YWl0IHV0aWxzLmNyZWF0ZVBhcnRpY2lwYW50S2V5Y2hhaW4oXG4gICAgICBNUEN2MlBhcnRpZXNFbnVtLkJJVEdPLFxuICAgICAgJ2NvbW1vbi1rZXljaGFpbicsXG4gICAgICB1bmRlZmluZWQsXG4gICAgICB1bmRlZmluZWQsXG4gICAgICB1bmRlZmluZWQsXG4gICAgICB1bmRlZmluZWQsXG4gICAgICB1bmRlZmluZWQsXG4gICAgICB1bmRlZmluZWQsXG4gICAgICB1bmRlZmluZWQsXG4gICAgICAnc2FmZS1pZCdcbiAgICApO1xuXG4gICAgYXNzZXJ0LmRlZXBTdHJpY3RFcXVhbChlbmNyeXB0ZWRJbnB1dHMsIFtdKTtcbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwoYWRkZWRLZXljaGFpbnNbMF0uc291cmNlLCAnYml0Z28nKTtcbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwoYWRkZWRLZXljaGFpbnNbMF0uc2FmZUlkLCAnc2FmZS1pZCcpO1xuICAgIGFzc2VydC5zdHJpY3RFcXVhbChhZGRlZEtleWNoYWluc1swXS5lbmNyeXB0ZWRQcnYsIHVuZGVmaW5lZCk7XG4gIH0pO1xuXG4gIGl0KCdyb3VuZC10cmlwcyBvcGFxdWUgVlJGIGJsb2JzIGFuZCBrZWVwcyBvbmx5IHRoZSByZWNpcGllbnQgcDJwIG1lc3NhZ2VzJywgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IGJsb2IgPSBzZXJpYWxpemVWcmZNZXNzYWdlcyh7XG4gICAgICBicm9hZGNhc3RNZXNzYWdlczogW3sgZnJvbTogTVBDdjJQYXJ0aWVzRW51bS5CSVRHTywgcGF5bG9hZDogbmV3IFVpbnQ4QXJyYXkoWzEsIDIsIDNdKSB9XSxcbiAgICAgIHAycE1lc3NhZ2VzOiBbXG4gICAgICAgIHsgZnJvbTogTVBDdjJQYXJ0aWVzRW51bS5CSVRHTywgdG86IE1QQ3YyUGFydGllc0VudW0uVVNFUiwgcGF5bG9hZDogbmV3IFVpbnQ4QXJyYXkoWzRdKSB9LFxuICAgICAgICB7IGZyb206IE1QQ3YyUGFydGllc0VudW0uQklUR08sIHRvOiBNUEN2MlBhcnRpZXNFbnVtLkJBQ0tVUCwgcGF5bG9hZDogbmV3IFVpbnQ4QXJyYXkoWzVdKSB9LFxuICAgICAgXSxcbiAgICB9KTtcblxuICAgIGNvbnN0IGZvclVzZXIgPSBkZXNlcmlhbGl6ZVZyZk1lc3NhZ2VzKGJsb2IsIE1QQ3YyUGFydGllc0VudW0uVVNFUik7XG4gICAgYXNzZXJ0LmRlZXBTdHJpY3RFcXVhbChCdWZmZXIuZnJvbShmb3JVc2VyLmJyb2FkY2FzdE1lc3NhZ2VzWzBdLnBheWxvYWQpLCBCdWZmZXIuZnJvbShbMSwgMiwgM10pKTtcbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwoZm9yVXNlci5wMnBNZXNzYWdlcy5sZW5ndGgsIDEpO1xuICAgIGFzc2VydC5zdHJpY3RFcXVhbChmb3JVc2VyLnAycE1lc3NhZ2VzWzBdLnRvLCBNUEN2MlBhcnRpZXNFbnVtLlVTRVIpO1xuICAgIGFzc2VydC5kZWVwU3RyaWN0RXF1YWwoQnVmZmVyLmZyb20oZm9yVXNlci5wMnBNZXNzYWdlc1swXS5wYXlsb2FkKSwgQnVmZmVyLmZyb20oWzRdKSk7XG5cbiAgICBjb25zdCBmb3JCYWNrdXAgPSBkZXNlcmlhbGl6ZVZyZk1lc3NhZ2VzKGJsb2IsIE1QQ3YyUGFydGllc0VudW0uQkFDS1VQKTtcbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwoZm9yQmFja3VwLnAycE1lc3NhZ2VzLmxlbmd0aCwgMSk7XG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKGZvckJhY2t1cC5wMnBNZXNzYWdlc1swXS50bywgTVBDdjJQYXJ0aWVzRW51bS5CQUNLVVApO1xuICB9KTtcblxuICBpdCgncmVqZWN0cyBtYWxmb3JtZWQgVlJGIERLRyBtZXNzYWdlIGJsb2JzJywgZnVuY3Rpb24gKCkge1xuICAgIGFzc2VydC50aHJvd3MoKCkgPT4gZGVzZXJpYWxpemVWcmZNZXNzYWdlcygnJSUlJywgTVBDdjJQYXJ0aWVzRW51bS5VU0VSKSwgL0ludmFsaWQgVlJGIERLRyBtZXNzYWdlIGJsb2IvKTtcbiAgICBjb25zdCBub3RBbkFycmF5ID0gQnVmZmVyLmZyb20oSlNPTi5zdHJpbmdpZnkoeyBmcm9tOiAwIH0pKS50b1N0cmluZygnYmFzZTY0Jyk7XG4gICAgYXNzZXJ0LnRocm93cygoKSA9PiBkZXNlcmlhbGl6ZVZyZk1lc3NhZ2VzKG5vdEFuQXJyYXksIE1QQ3YyUGFydGllc0VudW0uVVNFUiksIC9WUkYgREtHIG1lc3NhZ2UgYmxvYi8pO1xuICAgIGNvbnN0IGJhZFBhcnR5ID0gQnVmZmVyLmZyb20oSlNPTi5zdHJpbmdpZnkoW3sgZnJvbTogOSwgcGF5bG9hZDogQnVmZmVyLmZyb20oWzFdKS50b1N0cmluZygnYmFzZTY0JykgfV0pKS50b1N0cmluZyhcbiAgICAgICdiYXNlNjQnXG4gICAgKTtcbiAgICBhc3NlcnQudGhyb3dzKCgpID0+IGRlc2VyaWFsaXplVnJmTWVzc2FnZXMoYmFkUGFydHksIE1QQ3YyUGFydGllc0VudW0uVVNFUiksIC9WUkYgREtHIG1lc3NhZ2UgYmxvYi8pO1xuICB9KTtcbn0pO1xuXG5kZXNjcmliZSgnRWREU0Egc2FmZS1jaGlsZCBNUFMgZGVyaXZhdGlvbicsIGZ1bmN0aW9uICgpIHtcbiAgbGV0IHVzZXJTaWduaW5nU2hhcmU6IEJ1ZmZlcjtcbiAgbGV0IHVzZXJWcmZTaGFyZTogQnVmZmVyO1xuICBsZXQgYml0Z29TaWduaW5nU2hhcmU6IEJ1ZmZlcjtcbiAgbGV0IGJpdGdvVnJmU2hhcmU6IEJ1ZmZlcjtcbiAgbGV0IGJpdGdvUHJpdmF0ZUtleTogcGdwLlByaXZhdGVLZXk7XG4gIGxldCBiaXRnb1B1YmxpY0tleTogcGdwLktleTtcblxuICBjb25zdCBzZXNzaW9uSWQgPSAnZGVyaXZlLXNlc3Npb24nO1xuICBjb25zdCBkZXJpdmF0aW9uSW5kZXggPSA3O1xuICBjb25zdCBwYXRoID0gXCJtLzcnXCI7XG4gIGNvbnN0IFJlcXVlc3QgPSB0LmludGVyc2VjdGlvbihbXG4gICAgdC50eXBlKHsgZW50ZXJwcmlzZTogdC5zdHJpbmcsIHR5cGU6IHQuc3RyaW5nLCBjdXJ2ZVR5cGU6IHQuc3RyaW5nLCByb3VuZDogdC5zdHJpbmcsIHBheWxvYWQ6IHQudW5rbm93biB9KSxcbiAgICB0LnBhcnRpYWwoeyBzYWZlSWQ6IHQuc3RyaW5nIH0pLFxuICBdKTtcblxuICBiZWZvcmUoYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IHNpZ25pbmcgPSBhd2FpdCBNUFNVdGlsLmdlbmVyYXRlRWREc2FES0dLZXlTaGFyZXMoKTtcbiAgICBjb25zdCB2cmYgPSBhd2FpdCBNcHNWcmZVdGlscy5nZW5lcmF0ZVZyZkRLR0tleVNoYXJlcygpO1xuICAgIHVzZXJTaWduaW5nU2hhcmUgPSBzaWduaW5nW01QQ3YyUGFydGllc0VudW0uVVNFUl0uZ2V0S2V5U2hhcmUoKTtcbiAgICBiaXRnb1NpZ25pbmdTaGFyZSA9IHNpZ25pbmdbTVBDdjJQYXJ0aWVzRW51bS5CSVRHT10uZ2V0S2V5U2hhcmUoKTtcbiAgICB1c2VyVnJmU2hhcmUgPSB2cmZbTVBDdjJQYXJ0aWVzRW51bS5VU0VSXS5nZXRLZXlTaGFyZSgpO1xuICAgIGJpdGdvVnJmU2hhcmUgPSB2cmZbTVBDdjJQYXJ0aWVzRW51bS5CSVRHT10uZ2V0S2V5U2hhcmUoKTtcbiAgICBjb25zdCBiaXRnb0dwZyA9IGF3YWl0IGdlbmVyYXRlR1BHS2V5UGFpcignZWQyNTUxOScpO1xuICAgIGJpdGdvUHJpdmF0ZUtleSA9IGF3YWl0IHBncC5yZWFkUHJpdmF0ZUtleSh7IGFybW9yZWRLZXk6IGJpdGdvR3BnLnByaXZhdGVLZXkgfSk7XG4gICAgYml0Z29QdWJsaWNLZXkgPSBhd2FpdCBwZ3AucmVhZEtleSh7IGFybW9yZWRLZXk6IGJpdGdvR3BnLnB1YmxpY0tleSB9KTtcbiAgfSk7XG5cbiAgYXN5bmMgZnVuY3Rpb24gZGVyaXZlV2l0aFBlZXIoXG4gICAgZmF1bHQ/OiAncjEtc2lnbmF0dXJlJyB8ICdyMi1zaWduYXR1cmUnIHwgJ3Nlc3Npb24nIHwgJ2NvbW1vbktleWNoYWluJyxcbiAgICByZWNvcmRlZEtleWNoYWlucz86IEFkZGVkS2V5Y2hhaW5QYXJhbXNbXVxuICApIHtcbiAgICBjb25zdCB7IGJpdGdvLCBiYXNlQ29pbiwgcG9zdCwgZW5jcnlwdGVkSW5wdXRzLCBhZGRlZEtleWNoYWlucyB9ID0gY3JlYXRlS2V5Y2hhaW5GaXh0dXJlKCk7XG4gICAgY29uc3QgdXRpbHMgPSBuZXcgRWRkc2FWcmZNUEN2MlV0aWxzKGJpdGdvLCBiYXNlQ29pbik7XG4gICAgc2lub24uc3R1Yih1dGlscywgJ2dldEJpdGdvR3BnUHVia2V5QmFzZWRPbkZlYXR1cmVGbGFncycpLnJlc29sdmVzKHtcbiAgICAgIG1wY3YyUHVibGljS2V5OiBiaXRnb1B1YmxpY0tleSxcbiAgICAgIGVkZHNhTXBjdjJQdWJsaWNLZXk6IGJpdGdvUHVibGljS2V5LFxuICAgICAgcmVkcGFsbGFzTXBjdjJQdWJsaWNLZXk6IHVuZGVmaW5lZCxcbiAgICB9KTtcbiAgICBjb25zdCBiaXRnb1BlZXIgPSBuZXcgTXBzRGVyaXZlLkRlcml2ZSgzLCAyLCBNUEN2MlBhcnRpZXNFbnVtLkJJVEdPLCBiaXRnb1NpZ25pbmdTaGFyZSwgYml0Z29WcmZTaGFyZSwgcGF0aCk7XG4gICAgbGV0IGJpdGdvTXNnMjogVWludDhBcnJheSB8IHVuZGVmaW5lZDtcbiAgICBsZXQgdXNlckdwZ1B1YmxpY0tleSA9ICcnO1xuICAgIGxldCByb3VuZHMgPSAwO1xuICAgIHBvc3QuY2FsbHNGYWtlKChfdXJsOiBzdHJpbmcpID0+ICh7XG4gICAgICBzZW5kOiAocmF3Qm9keTogdW5rbm93bikgPT4gKHtcbiAgICAgICAgcmVzdWx0OiBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgY29uc3QgYm9keSA9IGRlY29kZVdpdGhDb2RlYyhSZXF1ZXN0LCByYXdCb2R5LCAnRWREU0EgZGVyaXZlIHJlcXVlc3QnKTtcbiAgICAgICAgICBhc3NlcnQuc3RyaWN0RXF1YWwoX3VybCwgJy9tcGMvZ2VuZXJhdGVrZXknKTtcbiAgICAgICAgICBhc3NlcnQuc3RyaWN0RXF1YWwoYm9keS5lbnRlcnByaXNlLCAnZW50ZXJwcmlzZS1pZCcpO1xuICAgICAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChib2R5LnR5cGUsIEtleUdlblR5cGVFbnVtLk1QQ3YyKTtcbiAgICAgICAgICBhc3NlcnQuc3RyaWN0RXF1YWwoYm9keS5jdXJ2ZVR5cGUsIEtleUN1cnZlRW51bS5FZERTQSk7XG4gICAgICAgICAgaWYgKHJvdW5kcysrID09PSAwKSB7XG4gICAgICAgICAgICBhc3NlcnQuc3RyaWN0RXF1YWwoYm9keS5yb3VuZCwgTVBDdjJLZXlHZW5TdGF0ZUVudW1bJ01QQ3YyRGVyaXZlLVIxJ10pO1xuICAgICAgICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKGJvZHkuc2FmZUlkLCAnc2FmZS1pZCcpO1xuICAgICAgICAgICAgY29uc3QgcmVxdWVzdCA9IGRlY29kZVdpdGhDb2RlYyhFZGRzYU1QQ3YyRGVyaXZlUm91bmQxUmVxdWVzdCwgYm9keS5wYXlsb2FkLCAnRWREU0EgZGVyaXZlIHJvdW5kIDEnKTtcbiAgICAgICAgICAgIGFzc2VydC5kZWVwU3RyaWN0RXF1YWwoT2JqZWN0LmtleXMocmVxdWVzdCkuc29ydCgpLCBbXG4gICAgICAgICAgICAgICdkZXJpdmF0aW9uSW5kZXgnLFxuICAgICAgICAgICAgICAncGFyZW50S2V5SWQnLFxuICAgICAgICAgICAgICAndXNlckdwZ1B1YmxpY0tleScsXG4gICAgICAgICAgICAgICd1c2VyTXNnMScsXG4gICAgICAgICAgICBdKTtcbiAgICAgICAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChyZXF1ZXN0LnBhcmVudEtleUlkLCAnYml0Z28tcm9vdC1pZCcpO1xuICAgICAgICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHJlcXVlc3QuZGVyaXZhdGlvbkluZGV4LCBkZXJpdmF0aW9uSW5kZXgpO1xuICAgICAgICAgICAgdXNlckdwZ1B1YmxpY0tleSA9IHJlcXVlc3QudXNlckdwZ1B1YmxpY0tleTtcbiAgICAgICAgICAgIGNvbnN0IHVzZXJHcGdLZXkgPSBhd2FpdCBwZ3AucmVhZEtleSh7IGFybW9yZWRLZXk6IHJlcXVlc3QudXNlckdwZ1B1YmxpY0tleSB9KTtcbiAgICAgICAgICAgIGNvbnN0IHVzZXJQYXlsb2FkID0gYXdhaXQgTVBTQ29tbXMudmVyaWZ5TXBzTWVzc2FnZShyZXF1ZXN0LnVzZXJNc2cxLCB1c2VyR3BnS2V5KTtcbiAgICAgICAgICAgIGNvbnN0IGJpdGdvRmlyc3QgPSBhd2FpdCBiaXRnb1BlZXIuaW5pdERlcml2ZSgpO1xuICAgICAgICAgICAgY29uc3QgW291dGdvaW5nXSA9IGJpdGdvUGVlci5oYW5kbGVJbmNvbWluZ01lc3NhZ2VzKFtcbiAgICAgICAgICAgICAgeyBmcm9tOiBNUEN2MlBhcnRpZXNFbnVtLlVTRVIsIHBheWxvYWQ6IG5ldyBVaW50OEFycmF5KHVzZXJQYXlsb2FkKSB9LFxuICAgICAgICAgICAgXSk7XG4gICAgICAgICAgICBhc3NlcnQub2sob3V0Z29pbmcpO1xuICAgICAgICAgICAgYml0Z29Nc2cyID0gb3V0Z29pbmcucGF5bG9hZDtcbiAgICAgICAgICAgIGNvbnN0IHNpZ25lZCA9IGF3YWl0IE1QU0NvbW1zLmRldGFjaFNpZ25NcHNNZXNzYWdlKEJ1ZmZlci5mcm9tKGJpdGdvRmlyc3QucGF5bG9hZCksIGJpdGdvUHJpdmF0ZUtleSk7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICBzZXNzaW9uSWQsXG4gICAgICAgICAgICAgIGJpdGdvTXNnMTpcbiAgICAgICAgICAgICAgICBmYXVsdCA9PT0gJ3IxLXNpZ25hdHVyZScgPyB7IC4uLnNpZ25lZCwgbWVzc2FnZTogQnVmZmVyLmZyb20oJ3RhbXBlcmVkJykudG9TdHJpbmcoJ2Jhc2U2NCcpIH0gOiBzaWduZWQsXG4gICAgICAgICAgICB9O1xuICAgICAgICAgIH1cbiAgICAgICAgICBhc3NlcnQuc3RyaWN0RXF1YWwocm91bmRzLCAyKTtcbiAgICAgICAgICBhc3NlcnQuc3RyaWN0RXF1YWwoYm9keS5yb3VuZCwgTVBDdjJLZXlHZW5TdGF0ZUVudW1bJ01QQ3YyRGVyaXZlLVIyJ10pO1xuICAgICAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChib2R5LnNhZmVJZCwgJ3NhZmUtaWQnKTtcbiAgICAgICAgICBjb25zdCByZXF1ZXN0ID0gZGVjb2RlV2l0aENvZGVjKEVkZHNhTVBDdjJEZXJpdmVSb3VuZDJSZXF1ZXN0LCBib2R5LnBheWxvYWQsICdFZERTQSBkZXJpdmUgcm91bmQgMicpO1xuICAgICAgICAgIGFzc2VydC5kZWVwU3RyaWN0RXF1YWwoT2JqZWN0LmtleXMocmVxdWVzdCkuc29ydCgpLCBbJ3Nlc3Npb25JZCcsICd1c2VyTXNnMiddKTtcbiAgICAgICAgICBhc3NlcnQuc3RyaWN0RXF1YWwocmVxdWVzdC5zZXNzaW9uSWQsIHNlc3Npb25JZCk7XG4gICAgICAgICAgY29uc3QgdXNlclBheWxvYWQgPSBhd2FpdCBNUFNDb21tcy52ZXJpZnlNcHNNZXNzYWdlKFxuICAgICAgICAgICAgcmVxdWVzdC51c2VyTXNnMixcbiAgICAgICAgICAgIGF3YWl0IHBncC5yZWFkS2V5KHsgYXJtb3JlZEtleTogdXNlckdwZ1B1YmxpY0tleSB9KVxuICAgICAgICAgICk7XG4gICAgICAgICAgYXNzZXJ0LmRlZXBTdHJpY3RFcXVhbChcbiAgICAgICAgICAgIGJpdGdvUGVlci5oYW5kbGVJbmNvbWluZ01lc3NhZ2VzKFt7IGZyb206IE1QQ3YyUGFydGllc0VudW0uVVNFUiwgcGF5bG9hZDogbmV3IFVpbnQ4QXJyYXkodXNlclBheWxvYWQpIH1dKSxcbiAgICAgICAgICAgIFtdXG4gICAgICAgICAgKTtcbiAgICAgICAgICBhc3NlcnQub2soYml0Z29Nc2cyKTtcbiAgICAgICAgICBjb25zdCBzaWduZWQgPSBhd2FpdCBNUFNDb21tcy5kZXRhY2hTaWduTXBzTWVzc2FnZShCdWZmZXIuZnJvbShiaXRnb01zZzIpLCBiaXRnb1ByaXZhdGVLZXkpO1xuICAgICAgICAgIGNvbnN0IGNvbW1vblB1YmxpY0tleWNoYWluID0gYml0Z29QZWVyLmdldENvbW1vbktleWNoYWluKCk7XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHNlc3Npb25JZDogZmF1bHQgPT09ICdzZXNzaW9uJyA/ICdkaWZmZXJlbnQtc2Vzc2lvbicgOiBzZXNzaW9uSWQsXG4gICAgICAgICAgICBjb21tb25QdWJsaWNLZXljaGFpbjpcbiAgICAgICAgICAgICAgZmF1bHQgPT09ICdjb21tb25LZXljaGFpbidcbiAgICAgICAgICAgICAgICA/IGAke2NvbW1vblB1YmxpY0tleWNoYWluLnNsaWNlKDAsIC0xKX0ke2NvbW1vblB1YmxpY0tleWNoYWluLmVuZHNXaXRoKCcwJykgPyAnMScgOiAnMCd9YFxuICAgICAgICAgICAgICAgIDogY29tbW9uUHVibGljS2V5Y2hhaW4sXG4gICAgICAgICAgICBiaXRnb01zZzI6XG4gICAgICAgICAgICAgIGZhdWx0ID09PSAncjItc2lnbmF0dXJlJyA/IHsgLi4uc2lnbmVkLCBtZXNzYWdlOiBCdWZmZXIuZnJvbSgndGFtcGVyZWQnKS50b1N0cmluZygnYmFzZTY0JykgfSA6IHNpZ25lZCxcbiAgICAgICAgICB9O1xuICAgICAgICB9LFxuICAgICAgfSksXG4gICAgfSkpO1xuXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHV0aWxzLmNyZWF0ZVNhZmVDaGlsZEtleWNoYWlucyh7XG4gICAgICAgIHBhc3NwaHJhc2U6ICdwYXNzcGhyYXNlJyxcbiAgICAgICAgZW50ZXJwcmlzZTogJ2VudGVycHJpc2UtaWQnLFxuICAgICAgICBzYWZlSWQ6ICdzYWZlLWlkJyxcbiAgICAgICAgcGFyZW50S2V5SWQ6ICdiaXRnby1yb290LWlkJyxcbiAgICAgICAgZGVyaXZhdGlvbkluZGV4LFxuICAgICAgICB1c2VyUm9vdEtleUlkOiAndXNlci1yb290LWlkJyxcbiAgICAgICAgYmFja3VwUm9vdEtleUlkOiAnYmFja3VwLXJvb3QtaWQnLFxuICAgICAgICB1c2VyUm9vdEtleVNoYXJlOiB1c2VyU2lnbmluZ1NoYXJlLFxuICAgICAgICB1c2VyUm9vdFZyZktleVNoYXJlOiB1c2VyVnJmU2hhcmUsXG4gICAgICB9KTtcbiAgICAgIHJldHVybiB7IHJlc3VsdCwgZW5jcnlwdGVkSW5wdXRzLCBhZGRlZEtleWNoYWlucywgYml0Z29QZWVyLCByb3VuZHMgfTtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgcmVjb3JkZWRLZXljaGFpbnM/LnB1c2goLi4uYWRkZWRLZXljaGFpbnMpO1xuICAgIH1cbiAgfVxuXG4gIGFmdGVyRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgc2lub24ucmVzdG9yZSgpO1xuICB9KTtcblxuICBpdCgncmVnaXN0ZXJzIHRoZSBjaGlsZCBzaWduaW5nIHNoYXJlIGFuZCB0d28gcHVibGljLW9ubHkgcGxhY2Vob2xkZXJzIGFmdGVyIHRoZSBzaWduZWQgY2VyZW1vbnknLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgY29uc3QgeyByZXN1bHQsIGVuY3J5cHRlZElucHV0cywgYWRkZWRLZXljaGFpbnMsIGJpdGdvUGVlciwgcm91bmRzIH0gPSBhd2FpdCBkZXJpdmVXaXRoUGVlcigpO1xuICAgIGFzc2VydC5zdHJpY3RFcXVhbChyb3VuZHMsIDIpO1xuICAgIGFzc2VydC5kZWVwU3RyaWN0RXF1YWwoYWRkZWRLZXljaGFpbnMubWFwKCh7IHNvdXJjZSB9KSA9PiBzb3VyY2UpLnNvcnQoKSwgWydiYWNrdXAnLCAnYml0Z28nLCAndXNlciddKTtcbiAgICBhc3NlcnQuZGVlcFN0cmljdEVxdWFsKFxuICAgICAgW3Jlc3VsdC51c2VyS2V5Y2hhaW4uaWQsIHJlc3VsdC5iYWNrdXBLZXljaGFpbi5pZCwgcmVzdWx0LmJpdGdvS2V5Y2hhaW4uaWRdLFxuICAgICAgWyd1c2VyLWNoaWxkJywgJ2JhY2t1cC1jaGlsZCcsICdiaXRnby1jaGlsZCddXG4gICAgKTtcbiAgICBmb3IgKGNvbnN0IGtleWNoYWluIG9mIGFkZGVkS2V5Y2hhaW5zKSB7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwoa2V5Y2hhaW4uc2FmZUlkLCAnc2FmZS1pZCcpO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKGtleWNoYWluLmRlcml2ZWRGcm9tUGFyZW50V2l0aFBhdGgsIHBhdGgpO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKGtleWNoYWluLmNvbW1vbktleWNoYWluLCBiaXRnb1BlZXIuZ2V0Q29tbW9uS2V5Y2hhaW4oKSk7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwoa2V5Y2hhaW4ua2V5VHlwZSwgJ3RzcycpO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKGtleWNoYWluLmlzTVBDdjIsIHRydWUpO1xuICAgIH1cbiAgICBjb25zdCB1c2VyQ2hpbGQgPSBhZGRlZEtleWNoYWlucy5maW5kKCh7IHNvdXJjZSB9KSA9PiBzb3VyY2UgPT09ICd1c2VyJyk7XG4gICAgY29uc3QgYmFja3VwQ2hpbGQgPSBhZGRlZEtleWNoYWlucy5maW5kKCh7IHNvdXJjZSB9KSA9PiBzb3VyY2UgPT09ICdiYWNrdXAnKTtcbiAgICBjb25zdCBiaXRnb0NoaWxkID0gYWRkZWRLZXljaGFpbnMuZmluZCgoeyBzb3VyY2UgfSkgPT4gc291cmNlID09PSAnYml0Z28nKTtcbiAgICBhc3NlcnQub2sodXNlckNoaWxkKTtcbiAgICBhc3NlcnQub2soYmFja3VwQ2hpbGQpO1xuICAgIGFzc2VydC5vayhiaXRnb0NoaWxkKTtcbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwodXNlckNoaWxkLnBhcmVudCwgJ3VzZXItcm9vdC1pZCcpO1xuICAgIGFzc2VydC5zdHJpY3RFcXVhbChiYWNrdXBDaGlsZC5wYXJlbnQsICdiYWNrdXAtcm9vdC1pZCcpO1xuICAgIGFzc2VydC5zdHJpY3RFcXVhbChiaXRnb0NoaWxkLnBhcmVudCwgJ2JpdGdvLXJvb3QtaWQnKTtcbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwoZW5jcnlwdGVkSW5wdXRzLmxlbmd0aCwgMik7XG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKHVzZXJDaGlsZC5lbmNyeXB0ZWRQcnYsIGBlbmNyeXB0ZWQ6JHtlbmNyeXB0ZWRJbnB1dHNbMF19YCk7XG4gICAgY29uc3Qgc2lnbmluZ1NoYXJlID0gQnVmZmVyLmZyb20ocmVzdWx0LnVzZXJLZXljaGFpbi5lbmNyeXB0ZWRQcnY/LnNsaWNlKCdlbmNyeXB0ZWQ6Jy5sZW5ndGgpID8/ICcnLCAnYmFzZTY0Jyk7XG4gICAgYXNzZXJ0LmRlZXBTdHJpY3RFcXVhbChzaWduaW5nU2hhcmUsIEJ1ZmZlci5mcm9tKGVuY3J5cHRlZElucHV0c1swXSwgJ2Jhc2U2NCcpKTtcbiAgICBhc3NlcnQubm90RGVlcFN0cmljdEVxdWFsKHNpZ25pbmdTaGFyZSwgdXNlclNpZ25pbmdTaGFyZSk7XG4gICAgYXNzZXJ0Lm5vdERlZXBTdHJpY3RFcXVhbChzaWduaW5nU2hhcmUsIGJpdGdvUGVlci5nZXRLZXlTaGFyZSgpKTtcbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwodXNlckNoaWxkLnJlZHVjZWRFbmNyeXB0ZWRQcnYsIHVuZGVmaW5lZCk7XG4gICAgY29uc3QgcmVkdWNlZCA9IHJlc3VsdC51c2VyS2V5Y2hhaW4ucmVkdWNlZEVuY3J5cHRlZFBydjtcbiAgICBhc3NlcnQub2socmVkdWNlZCk7XG4gICAgY29uc3QgcmVkdWNlZFNoYXJlID0gTVBTVHlwZXMuZ2V0RGVjb2RlZFJlZHVjZWRLZXlTaGFyZShCdWZmZXIuZnJvbShyZWR1Y2VkLnNsaWNlKCdlbmNyeXB0ZWQ6Jy5sZW5ndGgpLCAnYmFzZTY0JykpO1xuICAgIGFzc2VydC5kZWVwU3RyaWN0RXF1YWwoQnVmZmVyLmZyb20ocmVkdWNlZFNoYXJlLmtleVNoYXJlKSwgc2lnbmluZ1NoYXJlKTtcbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwoQnVmZmVyLmZyb20ocmVkdWNlZFNoYXJlLnB1YikudG9TdHJpbmcoJ2hleCcpLCBiaXRnb1BlZXIuZ2V0Q29tbW9uS2V5Y2hhaW4oKS5zbGljZSgwLCA2NCkpO1xuICAgIGFzc2VydC50aHJvd3MoKCkgPT4gZGVjb2RlVnJmRW52ZWxvcGUoc2lnbmluZ1NoYXJlKSk7XG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKGJhY2t1cENoaWxkLmVuY3J5cHRlZFBydiwgdW5kZWZpbmVkKTtcbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwoYml0Z29DaGlsZC5lbmNyeXB0ZWRQcnYsIHVuZGVmaW5lZCk7XG4gIH0pO1xuXG4gIGl0KCdyZWplY3RzIGluZGV4ZXMgb3V0c2lkZSB0aGUgaGFyZGVuZWQgU2FmZSByYW5nZSBiZWZvcmUgY29udGFjdGluZyBXUCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCB7IGJpdGdvLCBiYXNlQ29pbiwgcG9zdCwgYWRkZWRLZXljaGFpbnMgfSA9IGNyZWF0ZUtleWNoYWluRml4dHVyZSgpO1xuICAgIGNvbnN0IHV0aWxzID0gbmV3IEVkZHNhVnJmTVBDdjJVdGlscyhiaXRnbywgYmFzZUNvaW4pO1xuXG4gICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoXG4gICAgICB1dGlscy5jcmVhdGVTYWZlQ2hpbGRLZXljaGFpbnMoe1xuICAgICAgICBwYXNzcGhyYXNlOiAncGFzc3BocmFzZScsXG4gICAgICAgIGVudGVycHJpc2U6ICdlbnRlcnByaXNlLWlkJyxcbiAgICAgICAgc2FmZUlkOiAnc2FmZS1pZCcsXG4gICAgICAgIHBhcmVudEtleUlkOiAnYml0Z28tcm9vdC1pZCcsXG4gICAgICAgIGRlcml2YXRpb25JbmRleDogMHg4MDAwMDAwMCxcbiAgICAgICAgdXNlclJvb3RLZXlJZDogJ3VzZXItcm9vdC1pZCcsXG4gICAgICAgIGJhY2t1cFJvb3RLZXlJZDogJ2JhY2t1cC1yb290LWlkJyxcbiAgICAgICAgdXNlclJvb3RLZXlTaGFyZTogdXNlclNpZ25pbmdTaGFyZSxcbiAgICAgICAgdXNlclJvb3RWcmZLZXlTaGFyZTogdXNlclZyZlNoYXJlLFxuICAgICAgfSksXG4gICAgICAvZGVyaXZlZEZyb21QYXJlbnRXaXRoUGF0aC9cbiAgICApO1xuICAgIGFzc2VydC5zdHJpY3RFcXVhbChwb3N0LmNhbGxlZCwgZmFsc2UpO1xuICAgIGFzc2VydC5kZWVwU3RyaWN0RXF1YWwoYWRkZWRLZXljaGFpbnMsIFtdKTtcbiAgfSk7XG5cbiAgY29uc3QgZmF1bHRzOiBBcnJheTwncjEtc2lnbmF0dXJlJyB8ICdyMi1zaWduYXR1cmUnIHwgJ3Nlc3Npb24nIHwgJ2NvbW1vbktleWNoYWluJz4gPSBbXG4gICAgJ3IxLXNpZ25hdHVyZScsXG4gICAgJ3IyLXNpZ25hdHVyZScsXG4gICAgJ3Nlc3Npb24nLFxuICAgICdjb21tb25LZXljaGFpbicsXG4gIF07XG4gIGZvciAoY29uc3QgZmF1bHQgb2YgZmF1bHRzKSB7XG4gICAgaXQoYHJlamVjdHMgJHtmYXVsdH0gYmVmb3JlIHJlZ2lzdGVyaW5nIGFueSBjaGlsZGAsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHJlY29yZGVkS2V5Y2hhaW5zOiBBZGRlZEtleWNoYWluUGFyYW1zW10gPSBbXTtcbiAgICAgIGF3YWl0IGFzc2VydC5yZWplY3RzKFxuICAgICAgICAoKSA9PiBkZXJpdmVXaXRoUGVlcihmYXVsdCwgcmVjb3JkZWRLZXljaGFpbnMpLFxuICAgICAgICBmYXVsdCA9PT0gJ3Nlc3Npb24nXG4gICAgICAgICAgPyAvc2Vzc2lvbiBpZC9pXG4gICAgICAgICAgOiBmYXVsdCA9PT0gJ2NvbW1vbktleWNoYWluJ1xuICAgICAgICAgID8gL2NvbW1vbiBrZXljaGFpbi9pXG4gICAgICAgICAgOiAvc2lnbmF0dXJlfHZlcmlmaWNhdGlvbnxzaWduZWQvaVxuICAgICAgKTtcbiAgICAgIGFzc2VydC5kZWVwU3RyaWN0RXF1YWwocmVjb3JkZWRLZXljaGFpbnMsIFtdKTtcbiAgICB9KTtcbiAgfVxufSk7XG4iXX0=
|