PHP WebShell
Текущая директория: /opt/BitGoJS/modules/sdk-coin-cspr/dist/test/unit/lib
Просмотр файла: util.js
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const assert_1 = __importDefault(require("assert"));
const should = __importStar(require("should"));
const Utils = __importStar(require("../../../src/lib/utils"));
const keyPair_1 = require("../../../src/lib/keyPair");
const crypto_1 = require("crypto");
describe('CSPR util library', function () {
describe('validation', function () {
it('should fail to validate invalid private keys', function () {
const invalidPrvKeys = [
'xprv9s21ZrQH143K2J9hbmRNqDXo5aQ3RXvycz8VLchc4dus6r7QekaRWsPT6WPirE67Ps5jae2Ti3webhmFDarJG76h3jFqeg8u3WzeisjS2qwXYZ',
'xpub661MyMwAqRbcFjmMuHyjyZsQYGD6m8JZseFXpjAc1djoKvnMiJvqCeGu4cvxDNXstgPTsP1yeXewvUf6rUubvuG8mi9yPEb7hHVVCqRnhu7',
'02620C05D663B1585616C79A482B8F1F27ED9FC24719EEB358E6A085C285732632', // private key
'123',
];
for (const prv of invalidPrvKeys) {
should.doesNotThrow(() => Utils.isValidPrivateKey(prv));
Utils.isValidPrivateKey(prv).should.be.false();
}
});
it('should validate private keys', function () {
const validPrvKeys = [
'xprv9s21ZrQH143K2J9hbmRNqDXo5aQ3RXvycz8VLchc4dus6r7QekaRWsPT6WPirE67Ps5jae2Ti3webhmFDarJG76h3jFqeg8u3WzeisjS2qw',
'xprv9s21ZrQH143K2SDygJstGsPjHNztrAP6RxNH3YiBetww4WtA7hZxEaSFdkzjsE7kAik4c48Mp5q3Bgsaqv6wEyUZ6rB6odvw7Q2u1WF2RP9',
'1E7D588F5B3519FEE3B686E4A42E7275E4384DF807AE12165323B5FCEECB402A',
'DBDE50C2141EEE3B50F097DB4893BD20C42171813DF1B8B19ABA29A2028E3F51',
];
for (const prv of validPrvKeys) {
Utils.isValidPrivateKey(prv).should.be.true();
}
});
it('should fail to validate invalid public keys', function () {
const invalidPubKeys = [
'xpub661MyMwAqRbcFjmMuHyjyZsQYGD6m8JZseFXpjAc1djoKvnMiJvqCeGu4cvxDNXstgPTsP1yeXewvUf6rUubvuG8mi9yPEb7hHVVCqRnhu7XYZ',
'xprv9s21ZrQH143K2J9hbmRNqDXo5aQ3RXvycz8VLchc4dus6r7QekaRWsPT6WPirE67Ps5jae2Ti3webhmFDarJG76h3jFqeg8u3WzeisjS2qw',
'1E7D588F5B3519FEE3B686E4A42E7275E4384DF807AE12165323B5FCEECB402A', // private key
'123',
];
for (const pub of invalidPubKeys) {
should.doesNotThrow(() => Utils.isValidPublicKey(pub));
Utils.isValidPublicKey(pub).should.be.false();
}
});
it('should validate pub keys', function () {
const validPubKeys = [
'xpub661MyMwAqRbcGEkHtJzvg4PRy9i6YzYewjr6sqXhCU8gyrZtdH88BMrdzU3wo1Q3TodAyMU3aPaVAVTPvkgpA3aMvN9hQUu6x7xU2E68Drz',
'xpub661MyMwAqRbcFjmMuHyjyZsQYGD6m8JZseFXpjAc1djoKvnMiJvqCeGu4cvxDNXstgPTsP1yeXewvUf6rUubvuG8mi9yPEb7hHVVCqRnhu7',
'02620C05D663B1585616C79A482B8F1F27ED9FC24719EEB358E6A085C285732632',
'021E3BC1DE4255255BC799983F0A8384DAD84B3730BD95996AB95349C584B02B79',
];
for (const pub of validPubKeys) {
Utils.isValidPublicKey(pub).should.be.true();
}
});
it('should fail to validate invalid addresses', function () {
const invalidAddresses = [
'xpub661MyMwAqRbcFjmMuHyjyZsQYGD6m8JZseFXpjAc1djoKvnMiJvqCeGu4cvxDNXstgPTsP1yeXewvUf6rUubvuG8mi9yPEb7hHVVCqRnhu7',
'X03DC13CBBF29765C7745578D9E091280522F37684EF0E400B86B1C409BC454F1F3',
'abc',
];
for (const address of invalidAddresses) {
should.doesNotThrow(() => Utils.isValidAddress(address));
Utils.isValidAddress(address).should.be.false();
}
});
it('should validate addresses', function () {
const validAddresses = [
'0203DC13CBBF29765C7745578D9E091280522F37684EF0E400B86B1C409BC454F1F3',
'020385D724A9A3E7E32BADF40F3279AF5A190CB2CFCAB6639BF532A0069E0E3824D0',
'02029E23C8a1EDB0a0c5e78C086A4829611202A5cDEDF8aBeC45C72bA8e46f8A79e4',
'01513fa90c1a74c34a8958dd86055e9736edb1ead918bd4d4d750ca851946be7aa', // ed25519
];
for (const address of validAddresses) {
Utils.isValidAddress(address).should.be.true();
}
});
it('should fail to verify invalid message signature', function () {
const invalidSignature = '01d2e4736b8ff27a1d23be876950afb6991dad455ae351efcd036f95a1f7fe5a';
const data = '';
const publicKey = '018267d68f8d249b1430551ecc7b4c176d66f2ba2bf98d5547e7c3accc99375e53';
assert_1.default.throws(() => Utils.verifySignature(invalidSignature, data, publicKey));
});
it('should fail to verify invalid tx signature', function () {
const invalidSignature = '0201d2e4736b8ff27a1d23be876950afb6991dad455ae351efcd036f95a1f7fe5a01d2e4736b8ff27a1d23be876950afb6991dad455ae351efcd036f95a1f7fe5a';
const data = '';
const publicKey = '018267d68f8d249b1430551ecc7b4c176d66f2ba2bf98d5547e7c3accc99375e53';
assert_1.default.throws(() => Utils.verifySignature(invalidSignature, data, publicKey));
});
it('should verify valid message signature', function () {
const keyPair = new keyPair_1.KeyPair();
const messageToSign = Buffer.from((0, crypto_1.randomBytes)(32)).toString('hex');
const { signature } = Utils.signMessage(keyPair, messageToSign);
should.doesNotThrow(() => Utils.verifySignature(Buffer.from(signature).toString('hex'), messageToSign, keyPair.getKeys().pub));
});
it('should fail to validate invalid address with payment id', function () {
const invalidAddresses = [
'0203DC13CBBF29765C7745578D9E091280522F37684EF0E400B86B1C409BC454F1F3?transferId=x',
'0203DC13CBBF29765C7745578D9E091280522F37684EF0E400B86B1C409BC454F1F3?memoId=1',
'X0203DC13CBBF29765C7745578D9E091280522F37684EF0E400B86B1C409BC454F1F3?transferId=1',
];
for (const address of invalidAddresses) {
should.doesNotThrow(() => Utils.isValidAddress(address));
Utils.isValidAddressWithPaymentId(address).should.be.false();
}
});
it('should validate address with payment id', function () {
const validAddresses = [
'0203DC13CBBF29765C7745578D9E091280522F37684EF0E400B86B1C409BC454F1F3?transferId=0',
'020385D724A9A3E7E32BADF40F3279AF5A190CB2CFCAB6639BF532A0069E0E3824D0?transferId=1',
'01513fa90c1a74c34a8958dd86055e9736edb1ead918bd4d4d750ca851946be7aa?transferId=999999999', // ed25519
];
for (const address of validAddresses) {
Utils.isValidAddressWithPaymentId(address).should.be.true();
}
});
it('should validate hex strings', function () {
const validAddresses = [
'02029E23C8a1EDB0a0c5e78C086A4829611202A5cDEDF8aBeC45C72bA8e46f8A79e4', // mixed cased
'020385D724A9A3E7E32BADF40F3279AF5A190CB2CFCAB6639BF532A0069E0E3824D0', // uppercase
'020385d724a9a3e7e32badf40f3279af5a190cb2cfcab6639bf532a0069e0e3824d0', // lowercase
'01513fa90c1a74c34a8958dd86055e9736edb1ead918bd4d4d750ca851946be7aa', // ed25519
];
for (const address of validAddresses) {
Utils.isValidHex(address).should.be.true();
}
});
it('should fail to validate invalid hex strings', function () {
const validAddresses = [
'02029E23C8a1EDB0a0c5e78C086A48296112==G5cDEDF8aBeC45C72bA8e46f8A79e4',
'020385D724A9A3E7E32BADF40F3279AF5A190CB2HCFCAB6639BF532A0==9E0E3824D0',
'020385d724a9a3e7e32badf40f327tfcab6639bf532a0069e0e3824d0',
];
for (const address of validAddresses) {
Utils.isValidHex(address).should.be.false();
}
});
});
});
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Rlc3QvdW5pdC9saWIvdXRpbC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLG9EQUE0QjtBQUM1QiwrQ0FBaUM7QUFDakMsOERBQWdEO0FBQ2hELHNEQUFtRDtBQUNuRCxtQ0FBcUM7QUFFckMsUUFBUSxDQUFDLG1CQUFtQixFQUFFO0lBQzVCLFFBQVEsQ0FBQyxZQUFZLEVBQUU7UUFDckIsRUFBRSxDQUFDLDhDQUE4QyxFQUFFO1lBQ2pELE1BQU0sY0FBYyxHQUFHO2dCQUNyQixvSEFBb0g7Z0JBQ3BILGlIQUFpSDtnQkFDakgsb0VBQW9FLEVBQUUsY0FBYztnQkFDcEYsS0FBSzthQUNOLENBQUM7WUFFRixLQUFLLE1BQU0sR0FBRyxJQUFJLGNBQWMsRUFBRSxDQUFDO2dCQUNqQyxNQUFNLENBQUMsWUFBWSxDQUFDLEdBQUcsRUFBRSxDQUFDLEtBQUssQ0FBQyxpQkFBaUIsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO2dCQUN4RCxLQUFLLENBQUMsaUJBQWlCLENBQUMsR0FBRyxDQUFDLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUNqRCxDQUFDO1FBQ0gsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsOEJBQThCLEVBQUU7WUFDakMsTUFBTSxZQUFZLEdBQUc7Z0JBQ25CLGlIQUFpSDtnQkFDakgsaUhBQWlIO2dCQUNqSCxrRUFBa0U7Z0JBQ2xFLGtFQUFrRTthQUNuRSxDQUFDO1lBRUYsS0FBSyxNQUFNLEdBQUcsSUFBSSxZQUFZLEVBQUUsQ0FBQztnQkFDL0IsS0FBSyxDQUFDLGlCQUFpQixDQUFDLEdBQUcsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsSUFBSSxFQUFFLENBQUM7WUFDaEQsQ0FBQztRQUNILENBQUMsQ0FBQyxDQUFDO1FBRUgs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LE1BQU0sQ0FBQyxFQUFFLENBQUMsSUFBSSxFQUFFLENBQUM7WUFDOUQsQ0FBQztRQUNILENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLDZCQUE2QixFQUFFO1lBQ2hDLE1BQU0sY0FBYyxHQUFHO2dCQUNyQixzRUFBc0UsRUFBRSxjQUFjO2dCQUN0RixzRUFBc0UsRUFBRSxZQUFZO2dCQUNwRixzRUFBc0UsRUFBRSxZQUFZO2dCQUNwRixvRUFBb0UsRUFBRSxVQUFVO2FBQ2pGLENBQUM7WUFFRixLQUFLLE1BQU0sT0FBTyxJQUFJLGNBQWMsRUFBRSxDQUFDO2dCQUNyQyxLQUFLLENBQUMsVUFBVSxDQUFDLE9BQU8sQ0FBQyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsSUFBSSxFQUFFLENBQUM7WUFDN0MsQ0FBQztRQUNILENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLDZDQUE2QyxFQUFFO1lBQ2hELE1BQU0sY0FBYyxHQUFHO2dCQUNyQixzRUFBc0U7Z0JBQ3RFLHVFQUF1RTtnQkFDdkUsMkRBQTJEO2FBQzVELENBQUM7WUFFRixLQUFLLE1BQU0sT0FBTyxJQUFJLGNBQWMsRUFBRSxDQUFDO2dCQUNyQyxLQUFLLENBQUMsVUFBVSxDQUFDLE9BQU8sQ0FBQyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDOUMsQ0FBQztRQUNILENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBhc3NlcnQgZnJvbSAnYXNzZXJ0JztcbmltcG9ydCAqIGFzIHNob3VsZCBmcm9tICdzaG91bGQnO1xuaW1wb3J0ICogYXMgVXRpbHMgZnJvbSAnLi4vLi4vLi4vc3JjL2xpYi91dGlscyc7XG5pbXBvcnQgeyBLZXlQYWlyIH0gZnJvbSAnLi4vLi4vLi4vc3JjL2xpYi9rZXlQYWlyJztcbmltcG9ydCB7IHJhbmRvbUJ5dGVzIH0gZnJvbSAnY3J5cHRvJztcblxuZGVzY3JpYmUoJ0NTUFIgdXRpbCBsaWJyYXJ5JywgZnVuY3Rpb24gKCkge1xuICBkZXNjcmliZSgndmFsaWRhdGlvbicsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgnc2hvdWxkIGZhaWwgdG8gdmFsaWRhdGUgaW52YWxpZCBwcml2YXRlIGtleXMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBpbnZhbGlkUHJ2S2V5cyA9IFtcbiAgICAgICAgJ3hwcnY5czIxWnJRSDE0M0sySjloYm1STnFEWG81YVEzUlh2eWN6OFZMY2hjNGR1czZyN1Fla2FSV3NQVDZXUGlyRTY3UHM1amFlMlRpM3dlYmhtRkRhckpHNzZoM2pGcWVnOHUzV3plaXNqUzJxd1hZWicsXG4gICAgICAgICd4cHViNjYxTXlNd0FxUmJjRmptTXVIeWp5WnNRWUdENm04SlpzZUZYcGpBYzFkam9Ldm5NaUp2cUNlR3U0Y3Z4RE5Yc3RnUFRzUDF5ZVhld3ZVZjZyVXVidnVHOG1pOXlQRWI3aEhWVkNxUm5odTcnLFxuICAgICAgICAnMDI2MjBDMDVENjYzQjE1ODU2MTZDNzlBNDgyQjhGMUYyN0VEOUZDMjQ3MTlFRUIzNThFNkEwODVDMjg1NzMyNjMyJywgLy8gcHJpdmF0ZSBrZXlcbiAgICAgICAgJzEyMycsXG4gICAgICBdO1xuXG4gICAgICBmb3IgKGNvbnN0IHBydiBvZiBpbnZhbGlkUHJ2S2V5cykge1xuICAgICAgICBzaG91bGQuZG9lc05vdFRocm93KCgpID0+IFV0aWxzLmlzVmFsaWRQcml2YXRlS2V5KHBydikpO1xuICAgICAgICBVdGlscy5pc1ZhbGlkUHJpdmF0ZUtleShwcnYpLnNob3VsZC5iZS5mYWxzZSgpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB2YWxpZGF0ZSBwcml2YXRlIGtleXMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB2YWxpZFBydktleXMgPSBbXG4gICAgICAgICd4cHJ2OXMyMVpyUUgxNDNLMko5aGJtUk5xRFhvNWFRM1JYdnljejhWTGNoYzRkdXM2cjdRZWthUldzUFQ2V1BpckU2N1BzNWphZTJUaTN3ZWJobUZEYXJKRzc2aDNqRnFlZzh1M1d6ZWlzalMycXcnLFxuICAgICAgICAneHBydjlzMjFaclFIMTQzSzJTRHlnSnN0R3NQakhOenRyQVA2UnhOSDNZaUJldHd3NFd0QTdoWnhFYVNGZGt6anNFN2tBaWs0YzQ4TXA1cTNCZ3NhcXY2d0V5VVo2ckI2b2R2dzdRMnUxV0YyUlA5JyxcbiAgICAgICAgJzFFN0Q1ODhGNUIzNTE5RkVFM0I2ODZFNEE0MkU3Mjc1RTQzODRERjgwN0FFMTIxNjUzMjNCNUZDRUVDQjQwMkEnLFxuICAgICAgICAnREJERTUwQzIxNDFFRUUzQjUwRjA5N0RCNDg5M0JEMjBDNDIxNzE4MTNERjFCOEIxOUFCQTI5QTIwMjhFM0Y1MScsXG4gICAgICBdO1xuXG4gICAgICBmb3IgKGNvbnN0IHBydiBvZiB2YWxpZFBydktleXMpIHtcbiAgICAgICAgVXRpbHMuaXNWYWxpZFByaXZhdGVLZXkocHJ2KS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBmYWlsIHRvIHZhbGlkYXRlIGludmFsaWQgcHVibGljIGtleXMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBpbnZhbGlkUHViS2V5cyA9IFtcbiAgICAgICAgJ3hwdWI2NjFNeU13QXFSYmNGam1NdUh5anlac1FZR0Q2bThKWnNlRlhwakFjMWRqb0t2bk1pSnZxQ2VHdTRjdnhETlhzdGdQVHNQMXllWGV3dlVmNnJVdWJ2dUc4bWk5eVBFYjdoSFZWQ3FSbmh1N1hZWicsXG4gICAgICAgICd4cHJ2OXMyMVpyUUgxNDNLMko5aGJtUk5xRFhvNWFRM1JYdnljejhWTGNoYzRkdXM2cjdRZWthUldzUFQ2V1BpckU2N1BzNWphZTJUaTN3ZWJobUZEYXJKRzc2aDNqRnFlZzh1M1d6ZWlzalMycXcnLFxuICAgICAgICAnMUU3RDU4OEY1QjM1MTlGRUUzQjY4NkU0QTQyRTcyNzVFNDM4NERGODA3QUUxMjE2NTMyM0I1RkNFRUNCNDAyQScsIC8vIHByaXZhdGUga2V5XG4gICAgICAgICcxMjMnLFxuICAgICAgXTtcblxuICAgICAgZm9yIChjb25zdCBwdWIgb2YgaW52YWxpZFB1YktleXMpIHtcbiAgICAgICAgc2hvdWxkLmRvZXNOb3RUaHJvdygoKSA9PiBVdGlscy5pc1ZhbGlkUHVibGljS2V5KHB1YikpO1xuICAgICAgICBVdGlscy5pc1ZhbGlkUHVibGljS2V5KHB1Yikuc2hvdWxkLmJlLmZhbHNlKCk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHZhbGlkYXRlIHB1YiBrZXlzJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgdmFsaWRQdWJLZXlzID0gW1xuICAgICAgICAneHB1YjY2MU15TXdBcVJiY0dFa0h0Snp2ZzRQUnk5aTZZellld2pyNnNxWGhDVThneXJadGRIODhCTXJkelUzd28xUTNUb2RBeU1VM2FQYVZBVlRQdmtncEEzYU12TjloUVV1Nng3eFUyRTY4RHJ6JyxcbiAgICAgICAgJ3hwdWI2NjFNeU13QXFSYmNGam1NdUh5anlac1FZR0Q2bThKWnNlRlhwakFjMWRqb0t2bk1pSnZxQ2VHdTRjdnhETlhzdGdQVHNQMXllWGV3dlVmNnJVdWJ2dUc4bWk5eVBFYjdoSFZWQ3FSbmh1NycsXG4gICAgICAgICcwMjYyMEMwNUQ2NjNCMTU4NTYxNkM3OUE0ODJCOEYxRjI3RUQ5RkMyNDcxOUVFQjM1OEU2QTA4NUMyODU3MzI2MzInLFxuICAgICAgICAnMDIxRTNCQzFERTQyNTUyNTVCQzc5OTk4M0YwQTgzODREQUQ4NEIzNzMwQkQ5NTk5NkFCOTUzNDlDNTg0QjAyQjc5JyxcbiAgICAgIF07XG5cbiAgICAgIGZvciAoY29uc3QgcHViIG9mIHZhbGlkUHViS2V5cykge1xuICAgICAgICBVdGlscy5pc1ZhbGlkUHVibGljS2V5KHB1Yikuc2hvdWxkLmJlLnRydWUoKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZmFpbCB0byB2YWxpZGF0ZSBpbnZhbGlkIGFkZHJlc3NlcycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGludmFsaWRBZGRyZXNzZXMgPSBbXG4gICAgICAgICd4cHViNjYxTXlNd0FxUmJjRmptTXVIeWp5WnNRWUdENm04SlpzZUZYcGpBYzFkam9Ldm5NaUp2cUNlR3U0Y3Z4RE5Yc3RnUFRzUDF5ZVhld3ZVZjZyVXVidnVHOG1pOXlQRWI3aEhWVkNxUm5odTcnLFxuICAgICAgICAnWDAzREMxM0NCQkYyOTc2NUM3NzQ1NTc4RDlFMDkxMjgwNTIyRjM3Njg0RUYwRTQwMEI4NkIxQzQwOUJDNDU0RjFGMycsXG4gICAgICAgICdhYmMnLFxuICAgICAgXTtcblxuICAgICAgZm9yIChjb25zdCBhZGRyZXNzIG9mIGludmFsaWRBZGRyZXNzZXMpIHtcbiAgICAgICAgc2hvdWxkLmRvZXNOb3RUaHJvdygoKSA9PiBVdGlscy5pc1ZhbGlkQWRkcmVzcyhhZGRyZXNzKSk7XG4gICAgICAgIFV0aWxzLmlzVmFsaWRBZGRyZXNzKGFkZHJlc3MpLnNob3VsZC5iZS5mYWxzZSgpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB2YWxpZGF0ZSBhZGRyZXNzZXMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB2YWxpZEFkZHJlc3NlcyA9IFtcbiAgICAgICAgJzAyMDNEQzEzQ0JCRjI5NzY1Qzc3NDU1NzhEOUUwOTEyODA1MjJGMzc2ODRFRjBFNDAwQjg2QjFDNDA5QkM0NTRGMUYzJyxcbiAgICAgICAgJzAyMDM4NUQ3MjRBOUEzRTdFMzJCQURGNDBGMzI3OUFGNUExOTBDQjJDRkNBQjY2MzlCRjUzMkEwMDY5RTBFMzgyNEQwJyxcbiAgICAgICAgJzAyMDI5RTIzQzhhMUVEQjBhMGM1ZTc4QzA4NkE0ODI5NjExMjAyQTVjREVERjhhQmVDNDVDNzJiQThlNDZmOEE3OWU0JyxcbiAgICAgICAgJzAxNTEzZmE5MGMxYTc0YzM0YTg5NThkZDg2MDU1ZTk3MzZlZGIxZWFkOTE4YmQ0ZDRkNzUwY2E4NTE5NDZiZTdhYScsIC8vIGVkMjU1MTlcbiAgICAgIF07XG5cbiAgICAgIGZvciAoY29uc3QgYWRkcmVzcyBvZiB2YWxpZEFkZHJlc3Nlcykge1xuICAgICAgICBVdGlscy5pc1ZhbGlkQWRkcmVzcyhhZGRyZXNzKS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBmYWlsIHRvIHZlcmlmeSBpbnZhbGlkIG1lc3NhZ2Ugc2lnbmF0dXJlJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgaW52YWxpZFNpZ25hdHVyZSA9ICcwMWQyZTQ3MzZiOGZmMjdhMWQyM2JlODc2OTUwYWZiNjk5MWRhZDQ1NWFlMzUxZWZjZDAzNmY5NWExZjdmZTVhJztcbiAgICAgIGNvbnN0IGRhdGEgPSAnJztcbiAgICAgIGNvbnN0IHB1YmxpY0tleSA9ICcwMTgyNjdkNjhmOGQyNDliMTQzMDU1MWVjYzdiNGMxNzZkNjZmMmJhMmJmOThkNTU0N2U3YzNhY2NjOTkzNzVlNTMnO1xuXG4gICAgICBhc3NlcnQudGhyb3dzKCgpID0+IFV0aWxzLnZlcmlmeVNpZ25hdHVyZShpbnZhbGlkU2lnbmF0dXJlLCBkYXRhLCBwdWJsaWNLZXkpKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZmFpbCB0byB2ZXJpZnkgaW52YWxpZCB0eCBzaWduYXR1cmUnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBpbnZhbGlkU2lnbmF0dXJlID1cbiAgICAgICAgJzAyMDFkMmU0NzM2YjhmZjI3YTFkMjNiZTg3Njk1MGFmYjY5OTFkYWQ0NTVhZTM1MWVmY2QwMzZmOTVhMWY3ZmU1YTAxZDJlNDczNmI4ZmYyN2ExZDIzYmU4NzY5NTBhZmI2OTkxZGFkNDU1YWUzNTFlZmNkMDM2Zjk1YTFmN2ZlNWEnO1xuICAgICAgY29uc3QgZGF0YSA9ICcnO1xuICAgICAgY29uc3QgcHVibGljS2V5ID0gJzAxODI2N2Q2OGY4ZDI0OWIxNDMwNTUxZWNjN2I0YzE3NmQ2NmYyYmEyYmY5OGQ1NTQ3ZTdjM2FjY2M5OTM3NWU1Myc7XG5cbiAgICAgIGFzc2VydC50aHJvd3MoKCkgPT4gVXRpbHMudmVyaWZ5U2lnbmF0dXJlKGludmFsaWRTaWduYXR1cmUsIGRhdGEsIHB1YmxpY0tleSkpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB2ZXJpZnkgdmFsaWQgbWVzc2FnZSBzaWduYXR1cmUnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBrZXlQYWlyID0gbmV3IEtleVBhaXIoKTtcbiAgICAgIGNvbnN0IG1lc3NhZ2VUb1NpZ24gPSBCdWZmZXIuZnJvbShyYW5kb21CeXRlcygzMikpLnRvU3RyaW5nKCdoZXgnKTtcbiAgICAgIGNvbnN0IHsgc2lnbmF0dXJlIH0gPSBVdGlscy5zaWduTWVzc2FnZShrZXlQYWlyLCBtZXNzYWdlVG9TaWduKTtcbiAgICAgIHNob3VsZC5kb2VzTm90VGhyb3coKCkgPT5cbiAgICAgICAgVXRpbHMudmVyaWZ5U2lnbmF0dXJlKEJ1ZmZlci5mcm9tKHNpZ25hdHVyZSkudG9TdHJpbmcoJ2hleCcpLCBtZXNzYWdlVG9TaWduLCBrZXlQYWlyLmdldEtleXMoKS5wdWIpXG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBmYWlsIHRvIHZhbGlkYXRlIGludmFsaWQgYWRkcmVzcyB3aXRoIHBheW1lbnQgaWQnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBpbnZhbGlkQWRkcmVzc2VzID0gW1xuICAgICAgICAnMDIwM0RDMTNDQkJGMjk3NjVDNzc0NTU3OEQ5RTA5MTI4MDUyMkYzNzY4NEVGMEU0MDBCODZCMUM0MDlCQzQ1NEYxRjM/dHJhbnNmZXJJZD14JyxcbiAgICAgICAgJzAyMDNEQzEzQ0JCRjI5NzY1Qzc3NDU1NzhEOUUwOTEyODA1MjJGMzc2ODRFRjBFNDAwQjg2QjFDNDA5QkM0NTRGMUYzP21lbW9JZD0xJyxcbiAgICAgICAgJ1gwMjAzREMxM0NCQkYyOTc2NUM3NzQ1NTc4RDlFMDkxMjgwNTIyRjM3Njg0RUYwRTQwMEI4NkIxQzQwOUJDNDU0RjFGMz90cmFuc2ZlcklkPTEnLFxuICAgICAgXTtcblxuICAgICAgZm9yIChjb25zdCBhZGRyZXNzIG9mIGludmFsaWRBZGRyZXNzZXMpIHtcbiAgICAgICAgc2hvdWxkLmRvZXNOb3RUaHJvdygoKSA9PiBVdGlscy5pc1ZhbGlkQWRkcmVzcyhhZGRyZXNzKSk7XG4gICAgICAgIFV0aWxzLmlzVmFsaWRBZGRyZXNzV2l0aFBheW1lbnRJZChhZGRyZXNzKS5zaG91bGQuYmUuZmFsc2UoKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdmFsaWRhdGUgYWRkcmVzcyB3aXRoIHBheW1lbnQgaWQnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB2YWxpZEFkZHJlc3NlcyA9IFtcbiAgICAgICAgJzAyMDNEQzEzQ0JCRjI5NzY1Qzc3NDU1NzhEOUUwOTEyODA1MjJGMzc2ODRFRjBFNDAwQjg2QjFDNDA5QkM0NTRGMUYzP3RyYW5zZmVySWQ9MCcsXG4gICAgICAgICcwMjAzODVENzI0QTlBM0U3RTMyQkFERjQwRjMyNzlBRjVBMTkwQ0IyQ0ZDQUI2NjM5QkY1MzJBMDA2OUUwRTM4MjREMD90cmFuc2ZlcklkPTEnLFxuICAgICAgICAnMDE1MTNmYTkwYzFhNzRjMzRhODk1OGRkODYwNTVlOTczNmVkYjFlYWQ5MThiZDRkNGQ3NTBjYTg1MTk0NmJlN2FhP3RyYW5zZmVySWQ9OTk5OTk5OTk5JywgLy8gZWQyNTUxOVxuICAgICAgXTtcblxuICAgICAgZm9yIChjb25zdCBhZGRyZXNzIG9mIHZhbGlkQWRkcmVzc2VzKSB7XG4gICAgICAgIFV0aWxzLmlzVmFsaWRBZGRyZXNzV2l0aFBheW1lbnRJZChhZGRyZXNzKS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB2YWxpZGF0ZSBoZXggc3RyaW5ncycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHZhbGlkQWRkcmVzc2VzID0gW1xuICAgICAgICAnMDIwMjlFMjNDOGExRURCMGEwYzVlNzhDMDg2QTQ4Mjk2MTEyMDJBNWNERURGOGFCZUM0NUM3MmJBOGU0NmY4QTc5ZTQnLCAvLyBtaXhlZCBjYXNlZFxuICAgICAgICAnMDIwMzg1RDcyNEE5QTNFN0UzMkJBREY0MEYzMjc5QUY1QTE5MENCMkNGQ0FCNjYzOUJGNTMyQTAwNjlFMEUzODI0RDAnLCAvLyB1cHBlcmNhc2VcbiAgICAgICAgJzAyMDM4NWQ3MjRhOWEzZTdlMzJiYWRmNDBmMzI3OWFmNWExOTBjYjJjZmNhYjY2MzliZjUzMmEwMDY5ZTBlMzgyNGQwJywgLy8gbG93ZXJjYXNlXG4gICAgICAgICcwMTUxM2ZhOTBjMWE3NGMzNGE4OTU4ZGQ4NjA1NWU5NzM2ZWRiMWVhZDkxOGJkNGQ0ZDc1MGNhODUxOTQ2YmU3YWEnLCAvLyBlZDI1NTE5XG4gICAgICBdO1xuXG4gICAgICBmb3IgKGNvbnN0IGFkZHJlc3Mgb2YgdmFsaWRBZGRyZXNzZXMpIHtcbiAgICAgICAgVXRpbHMuaXNWYWxpZEhleChhZGRyZXNzKS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBmYWlsIHRvIHZhbGlkYXRlIGludmFsaWQgaGV4IHN0cmluZ3MnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB2YWxpZEFkZHJlc3NlcyA9IFtcbiAgICAgICAgJzAyMDI5RTIzQzhhMUVEQjBhMGM1ZTc4QzA4NkE0ODI5NjExMj09RzVjREVERjhhQmVDNDVDNzJiQThlNDZmOEE3OWU0JyxcbiAgICAgICAgJzAyMDM4NUQ3MjRBOUEzRTdFMzJCQURGNDBGMzI3OUFGNUExOTBDQjJIQ0ZDQUI2NjM5QkY1MzJBMD09OUUwRTM4MjREMCcsXG4gICAgICAgICcwMjAzODVkNzI0YTlhM2U3ZTMyYmFkZjQwZjMyN3RmY2FiNjYzOWJmNTMyYTAwNjllMGUzODI0ZDAnLFxuICAgICAgXTtcblxuICAgICAgZm9yIChjb25zdCBhZGRyZXNzIG9mIHZhbGlkQWRkcmVzc2VzKSB7XG4gICAgICAgIFV0aWxzLmlzVmFsaWRIZXgoYWRkcmVzcykuc2hvdWxkLmJlLmZhbHNlKCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH0pO1xufSk7XG4iXX0=Выполнить команду
Для локальной разработки. Не используйте в интернете!