PHP WebShell
Текущая директория: /opt/BitGoJS/modules/sdk-core/dist/src/bitgo/internal
Просмотр файла: keycard.js
"use strict";
/**
* @hidden
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.drawKeycard = drawKeycard;
/**
*/
const lodash_1 = require("lodash");
/**
* Return the list of questions that will appear on the second page of the keycard
* @param coin name of the coin
*/
const generateQuestions = (coin) => {
return [
{
q: 'What is the KeyCard?',
a: [
`The KeyCard contains important information which can be used to recover the ${coin} `,
'from your wallet in several situations. Each BitGo wallet' + ' has its own, unique KeyCard. ',
'If you have created multiple wallets, you should retain the KeyCard for each of them.',
],
},
{
q: 'What should I do with it?',
a: [
'You should print the KeyCard and/or save the PDF to an offline storage device. The print-out ',
"or USB stick should be kept in a safe place, such as a bank vault or home safe. It's a good idea ",
'to keep a second copy in a different location.',
'',
"Important: If you haven't provided an external backup key, then the original PDF should be ",
'deleted from any machine where the wallet will be regularly accessed to prevent malware from ',
'capturing both the KeyCard and your wallet passcode.',
],
},
{
q: 'What should I do if I lose it?',
a: [
`If you have lost or damaged all copies of your KeyCard, your ${coin} is still safe, but this `,
'wallet should be considered at risk for loss. As soon as is convenient, you should use BitGo ',
'to empty the wallet into a new wallet',
', and discontinue use of the old wallet.',
],
},
{
q: 'What if someone sees my KeyCard?',
a: [
"Don't panic! All sensitive information on the KeyCard is encrypted with your passcode, or with a",
'key which only BitGo has. But, in general, you should make best efforts to keep your ',
'KeyCard private. If your KeyCard does get exposed or copied in a way that makes you ',
'uncomfortable, the best course of action is to empty the corresponding wallet into another ',
'wallet and discontinue use of the old wallet.',
],
},
{
q: 'What if I forget or lose my wallet password?',
a: [
'BitGo can use the information in QR Code D to help you recover access to your wallet. ',
'Without the KeyCard, BitGo is not able to recover funds from a wallet with a lost password.',
],
},
{
q: 'What if BitGo becomes inaccessible for an extended period?',
a: [
'Your KeyCard and wallet passcode can be used together with BitGo’s published open ',
`source tools at https://github.com/bitgo to recover your ${coin}. Note: You should never enter `,
'information from your KeyCard into tools other than the tools BitGo has published, or your ',
'funds may be at risk for theft.',
],
},
{
q: 'Should I write my wallet password on my KeyCard?',
a: [
'No! BitGo’s multi-signature approach to security depends on there not being a single point ',
'of attack. But if your wallet password is on your KeyCard, then anyone who gains access to ',
`your KeyCard will be able to steal your ${coin}. We recommend keeping your wallet password `,
'safe in a secure password manager such as LastPass, 1Password or KeePass.',
],
},
];
};
/**
* Collect all data which will go onto the keycard
* @param options
*/
function getKeyData(options) {
const { encrypt, userKeychain, bitgoKeychain, backupKeychain, coinShortName, passphrase, passcodeEncryptionCode, walletKeyID, backupKeyID, } = options;
// When using just 'generateWallet', we get back an unencrypted prv for the backup keychain
// If the user passes in their passphrase, we can encrypt it
if (backupKeychain.prv && passphrase) {
backupKeychain.encryptedPrv = encrypt({
input: backupKeychain.prv,
password: passphrase,
});
}
// If we have the passcode encryption code, create a box D with the encryptedWalletPasscode
let encryptedWalletPasscode;
if (passphrase && passcodeEncryptionCode) {
encryptedWalletPasscode = encrypt({
input: passphrase,
password: passcodeEncryptionCode,
});
}
// PDF QR Code data
const qrData = {
user: {
title: 'A: User Key',
desc: 'This is your private key, encrypted with your passcode.',
data: userKeychain.encryptedPrv,
},
backup: {
title: 'B: Backup Key',
desc: 'This is your backup private key, encrypted with your passcode.',
data: backupKeychain.encryptedPrv,
},
bitgo: {
title: 'C: BitGo Public Key',
desc: 'This is the public part of the key that BitGo will use to ' +
'co-sign transactions\r\nwith you on your wallet.',
data: bitgoKeychain.pub,
},
passcode: {
title: 'D: Encrypted Wallet Password',
desc: 'This is the wallet password, encrypted client-side ' + 'with a key held by\r\nBitGo.',
data: encryptedWalletPasscode,
},
};
if (walletKeyID) {
qrData.user.keyID = walletKeyID;
}
if (backupKeyID) {
qrData.backup.keyID = backupKeyID;
}
if ((0, lodash_1.isUndefined)(userKeychain.encryptedPrv)) {
// User provided their own key - this is a cold wallet
qrData.user.title = 'A: Provided User Key';
qrData.user.desc = 'This is the public key you provided for your wallet.';
qrData.user.data = userKeychain.pub;
// The user provided their own public key, we can remove box D
delete qrData.passcode;
}
else if ((0, lodash_1.isUndefined)(encryptedWalletPasscode)) {
delete qrData.passcode;
}
if (!(0, lodash_1.isUndefined)(backupKeychain.provider)) {
const backupKeyProviderName = backupKeychain.provider;
// Backup key held with KRS
qrData.backup = {
title: 'B: Backup Key',
desc: `This is the public key held at ${backupKeyProviderName}` +
`, an ${coinShortName} recovery service. If you lose\r\nyour key, ${backupKeyProviderName}` +
' will be able to sign transactions to recover funds.',
data: backupKeychain.pub,
};
}
else if ((0, lodash_1.isUndefined)(backupKeychain.encryptedPrv)) {
// User supplied the xpub
qrData.backup = {
title: 'B: Backup Key',
desc: 'This is the public portion of your backup key, which you provided.',
data: backupKeychain.pub,
};
}
return qrData;
}
/**
* Draw a keycard into a new pdf document object
* @param options
*/
function drawKeycard(options) {
const { jsPDF, QRCode, coinShortName, activationCode, walletLabel, coinName } = options;
const margin = 30;
const font = {
header: 24,
subheader: 15,
body: 12,
};
const color = {
black: '#000000',
darkgray: '#4c4c4c',
gray: '#9b9b9b',
red: '#e21e1e',
};
// document details
const width = 8.5 * 72;
let y = 0;
// Helpers for data formatting / positioning on the paper
const left = (x) => margin + x;
const moveDown = (yDelta) => {
y += yDelta;
};
const doc = new jsPDF('portrait', 'pt', 'letter');
doc.setFont('helvetica');
// PDF Header Area - includes the logo and company name
// This is data for the BitGo logo in the top left of the PDF
moveDown(30);
// We don't currently add an image, since that path is dependent on BitGo frontend
// doc.addImage(coinUtility.getSelectedCoinObj().keyCardImage, left(0), y + 10);
// Activation Code
moveDown(8);
doc.setFontSize(font.body).setTextColor(color.gray);
doc.text('Activation Code', left(460), y);
doc.setFontSize(font.header).setTextColor(color.black);
moveDown(25);
doc.text('Your BitGo KeyCard', left(150), y);
doc.setFontSize(font.header).setTextColor(color.gray);
doc.text(activationCode.toString(), left(460), y);
// Subheader
// titles
moveDown(margin);
doc.setFontSize(font.body).setTextColor(color.gray);
doc.text(`Created on ${new Date().toDateString()} by ${window.location.hostname} for wallet named ${walletLabel}`, left(0), y);
// copy
moveDown(25);
doc.setFontSize(font.subheader).setTextColor(color.black);
doc.text(walletLabel, left(0), y);
// Red Bar
moveDown(20);
doc.setFillColor(255, 230, 230);
doc.rect(left(0), y, width - 2 * margin, 32, 'F');
// warning message
moveDown(20);
doc.setFontSize(font.body).setTextColor(color.red);
doc.text('Print this document, or keep it securely offline. See second page for FAQ.', left(75), y);
const { encrypt, passphrase, passcodeEncryptionCode, walletKeyID, backupKeyID, userKeychain, bitgoKeychain, backupKeychain, } = options;
// Get the data for the first page (qr codes)
const keyData = getKeyData({
encrypt,
coinShortName,
passphrase,
passcodeEncryptionCode,
walletKeyID,
backupKeyID,
userKeychain,
bitgoKeychain,
backupKeychain,
});
// Generate the first page's data for the backup PDF
moveDown(35);
const qrSize = 130;
// Draw each Box with QR code and description
Object.keys(keyData).forEach(function (keyType) {
const key = keyData[keyType];
const topY = y;
// Don't indent if we're not producing QR codes
const textLeft = !!QRCode ? left(qrSize + 15) : left(15);
// Draw a QR code if library is available
if (QRCode) {
const dataURL = new QRCode({ value: key.data, size: qrSize }).toDataURL('image/jpeg');
doc.addImage(dataURL, left(0), y, qrSize, qrSize);
}
doc.setFontSize(font.subheader).setTextColor(color.black);
moveDown(10);
doc.text(key.title, textLeft, y);
moveDown(15);
doc.setFontSize(font.body).setTextColor(color.darkgray);
doc.text(key.desc, textLeft, y);
moveDown(30);
doc.setFontSize(font.body - 2);
doc.text('Data:', textLeft, y);
moveDown(15);
const innerWidth = 72 * 8.5 - textLeft - 30;
doc.setFont('courier').setFontSize(9).setTextColor(color.black);
const lines = doc.splitTextToSize(key.data, innerWidth);
doc.text(lines, textLeft, y);
// Add key ID (derivation string) if it exists
if (key.keyID) {
const text = 'Key Id: ' + key.keyID;
// Gray bar
moveDown(45);
doc.setFillColor(247, 249, 249); // Gray background
doc.setDrawColor(0, 0, 0); // Border
doc.rect(textLeft, y, width, 15, 'FD');
doc.text(text, textLeft + 5, y + 10);
}
doc.setFont('helvetica');
// Move down the size of the QR code minus accumulated height on the right side, plus buffer
moveDown(qrSize - (y - topY) + 15);
});
// Add a new page (Q + A page)
doc.addPage();
// 2nd page title
y = 0;
moveDown(55);
doc.setFontSize(font.header).setTextColor(color.black);
doc.text('BitGo KeyCard FAQ', left(0), y);
const questions = generateQuestions(coinName);
// Draw the Q + A data on the second page
moveDown(30);
questions.forEach(function (q) {
doc.setFontSize(font.subheader).setTextColor(color.black);
doc.text(q.q, left(0), y);
moveDown(20);
doc.setFontSize(font.body).setTextColor(color.darkgray);
q.a.forEach(function (line) {
doc.text(line, left(0), y);
moveDown(font.body + 3);
});
moveDown(22);
});
return doc;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoia2V5Y2FyZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9iaXRnby9pbnRlcm5hbC9rZXljYXJkLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTs7R0FFRzs7QUFpTkgsa0NBNEtDO0FBM1hEO0dBQ0c7QUFDSCxtQ0FBcUM7QUFHckM7OztHQUdHO0FBQ0gsTUFBTSxpQkFBaUIsR0FBRyxDQUFDLElBQVksRUFBRSxFQUFFO0lBQ3pDLE9BQU87UUFDTDtZQUNFLENBQUMsRUFBRSxzQkFBc0I7WUFDekIsQ0FBQyxFQUFFO2dCQUNELCtFQUErRSxJQUFJLEdBQUc7Z0JBQ3RGLDJEQUEyRCxHQUFHLGdDQUFnQztnQkFDOUYsdUZBQXVGO2FBQ3hGO1NBQ0Y7UUFDRDtZQUNFLENBQUMsRUFBRSwyQkFBMkI7WUFDOUIsQ0FBQyxFQUFFO2dCQUNELCtGQUErRjtnQkFDL0YsbUdBQW1HO2dCQUNuRyxnREFBZ0Q7Z0JBQ2hELEVBQUU7Z0JBQ0YsNkZBQTZGO2dCQUM3RiwrRkFBK0Y7Z0JBQy9GLHNEQUFzRDthQUN2RDtTQUNGO1FBQ0Q7WUFDRSxDQUFDLEVBQUUsZ0NBQWdDO1lBQ25DLENBQUMsRUFBRTtnQkFDRCxnRUFBZ0UsSUFBSSwyQkFBMkI7Z0JBQy9GLCtGQUErRjtnQkFDL0YsdUNBQXVDO2dCQUN2QywwQ0FBMEM7YUFDM0M7U0FDRjtRQUNEO1lBQ0UsQ0FBQyxFQUFFLGtDQUFrQztZQUNyQyxDQUFDLEVBQUU7Z0JBQ0Qsa0dBQWtHO2dCQUNsRyx1RkFBdUY7Z0JBQ3ZGLHNGQUFzRjtnQkFDdEYsNkZBQTZGO2dCQUM3RiwrQ0FBK0M7YUFDaEQ7U0FDRjtRQUNEO1lBQ0UsQ0FBQyxFQUFFLDhDQUE4QztZQUNqRCxDQUFDLEVBQUU7Z0JBQ0Qsd0ZBQXdGO2dCQUN4Riw2RkFBNkY7YUFDOUY7U0FDRjtRQUNEO1lBQ0UsQ0FBQyxFQUFFLDREQUE0RDtZQUMvRCxDQUFDLEVBQUU7Z0JBQ0Qsb0ZBQW9GO2dCQUNwRiw0REFB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UUFBUSxDQUFDLEVBQUUsQ0FBQyxDQUFDO0lBQ2IsU0FBUyxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUM7UUFDM0IsR0FBRyxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUMsWUFBWSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUMxRCxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQzFCLFFBQVEsQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUNiLEdBQUcsQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLFlBQVksQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDeEQsQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsVUFBVSxJQUFJO1lBQ3hCLEdBQUcsQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztZQUMzQixRQUFRLENBQUMsSUFBSSxDQUFDLElBQUksR0FBRyxDQUFDLENBQUMsQ0FBQztRQUMxQixDQUFDLENBQUMsQ0FBQztRQUNILFFBQVEsQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUNmLENBQUMsQ0FBQyxDQUFDO0lBRUgsT0FBTyxHQUFHLENBQUM7QUFDYixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAaGlkZGVuXG4gKi9cblxuLyoqXG4gKi9cbmltcG9ydCB7IGlzVW5kZWZpbmVkIH0gZnJvbSAnbG9kYXNoJztcbmltcG9ydCB7IEtleWNoYWluIH0gZnJvbSAnLi4va2V5Y2hhaW4nO1xuXG4vKipcbiAqIFJldHVybiB0aGUgbGlzdCBvZiBxdWVzdGlvbnMgdGhhdCB3aWxsIGFwcGVhciBvbiB0aGUgc2Vjb25kIHBhZ2Ugb2YgdGhlIGtleWNhcmRcbiAqIEBwYXJhbSBjb2luIG5hbWUgb2YgdGhlIGNvaW5cbiAqL1xuY29uc3QgZ2VuZXJhdGVRdWVzdGlvbnMgPSAoY29pbjogc3RyaW5nKSA9PiB7XG4gIHJldHVybiBbXG4gICAge1xuICAgICAgcTogJ1doYXQgaXMgdGhlIEtleUNhcmQ/JyxcbiAgICAgIGE6IFtcbiAgICAgICAgYFRoZSBLZXlDYXJkIGNvbnRhaW5zIGltcG9ydGFudCBpbmZvcm1hdGlvbiB3aGljaCBjYW4gYmUgdXNlZCB0byByZWNvdmVyIHRoZSAke2NvaW59IGAsXG4gICAgICAgICdmcm9tIHlvdXIgd2FsbGV0IGluIHNldmVyYWwgc2l0dWF0aW9ucy4gRWFjaCBCaXRHbyB3YWxsZXQnICsgJyBoYXMgaXRzIG93biwgdW5pcXVlIEtleUNhcmQuICcsXG4gICAgICAgICdJZiB5b3UgaGF2ZSBjcmVhdGVkIG11bHRpcGxlIHdhbGxldHMsIHlvdSBzaG91bGQgcmV0YWluIHRoZSBLZXlDYXJkIGZvciBlYWNoIG9mIHRoZW0uJyxcbiAgICAgIF0sXG4gICAgfSxcbiAgICB7XG4gICAgICBxOiAnV2hhdCBzaG91bGQgSSBkbyB3aXRoIGl0PycsXG4gICAgICBhOiBbXG4gICAgICAgICdZb3Ugc2hvdWxkIHByaW50IHRoZSBLZXlDYXJkIGFuZC9vciBzYXZlIHRoZSBQREYgdG8gYW4gb2ZmbGluZSBzdG9yYWdlIGRldmljZS4gVGhlIHByaW50LW91dCAnLFxuICAgICAgICBcIm9yIFVTQiBzdGljayBzaG91bGQgYmUga2VwdCBpbiBhIHNhZmUgcGxhY2UsIHN1Y2ggYXMgYSBiYW5rIHZhdWx0IG9yIGhvbWUgc2FmZS4gSXQncyBhIGdvb2QgaWRlYSBcIixcbiAgICAgICAgJ3RvIGtlZXAgYSBzZWNvbmQgY29weSBpbiBhIGRpZmZlcmVudCBsb2NhdGlvbi4nLFxuICAgICAgICAnJyxcbiAgICAgICAgXCJJbXBvcnRhbnQ6IElmIHlvdSBoYXZlbid0IHByb3ZpZGVkIGFuIGV4dGVybmFsIGJhY2t1cCBrZXksIHRoZW4gdGhlIG9yaWdpbmFsIFBERiBzaG91bGQgYmUgXCIsXG4gICAgICAgICdkZWxldGVkIGZyb20gYW55IG1hY2hpbmUgd2hlcmUgdGhlIHdhbGxldCB3aWxsIGJlIHJlZ3VsYXJseSBhY2Nlc3NlZCB0byBwcmV2ZW50IG1hbHdhcmUgZnJvbSAnLFxuICAgICAgICAnY2FwdHVyaW5nIGJvdGggdGhlIEtleUNhcmQgYW5kIHlvdXIgd2FsbGV0IHBhc3Njb2RlLicsXG4gICAgICBdLFxuICAgIH0sXG4gICAge1xuICAgICAgcTogJ1doYXQgc2hvdWxkIEkgZG8gaWYgSSBsb3NlIGl0PycsXG4gICAgICBhOiBbXG4gICAgICAgIGBJZiB5b3UgaGF2ZSBsb3N0IG9yIGRhbWFnZWQgYWxsIGNvcGllcyBvZiB5b3VyIEtleUNhcmQsIHlvdXIgJHtjb2lufSBpcyBzdGlsbCBzYWZlLCBidXQgdGhpcyBgLFxuICAgICAgICAnd2FsbGV0IHNob3VsZCBiZSBjb25zaWRlcmVkIGF0IHJpc2sgZm9yIGxvc3MuIEFzIHNvb24gYXMgaXMgY29udmVuaWVudCwgeW91IHNob3VsZCB1c2UgQml0R28gJyxcbiAgICAgICAgJ3RvIGVtcHR5IHRoZSB3YWxsZXQgaW50byBhIG5ldyB3YWxsZXQnLFxuICAgICAgICAnLCBhbmQgZGlzY29udGludWUgdXNlIG9mIHRoZSBvbGQgd2FsbGV0LicsXG4gICAgICBdLFxuICAgIH0sXG4gICAge1xuICAgICAgcTogJ1doYXQgaWYgc29tZW9uZSBzZWVzIG15IEtleUNhcmQ/JyxcbiAgICAgIGE6IFtcbiAgICAgICAgXCJEb24ndCBwYW5pYyEgQWxsIHNlbnNpdGl2ZSBpbmZvcm1hdGlvbiBvbiB0aGUgS2V5Q2FyZCBpcyBlbmNyeXB0ZWQgd2l0aCB5b3VyIHBhc3Njb2RlLCBvciB3aXRoIGFcIixcbiAgICAgICAgJ2tleSB3aGljaCBvbmx5IEJpdEdvIGhhcy4gQnV0LCBpbiBnZW5lcmFsLCB5b3Ugc2hvdWxkIG1ha2UgYmVzdCBlZmZvcnRzIHRvIGtlZXAgeW91ciAnLFxuICAgICAgICAnS2V5Q2FyZCBwcml2YXRlLiBJZiB5b3VyIEtleUNhcmQgZG9lcyBnZXQgZXhwb3NlZCBvciBjb3BpZWQgaW4gYSB3YXkgdGhhdCBtYWtlcyB5b3UgJyxcbiAgICAgICAgJ3VuY29tZm9ydGFibGUsIHRoZSBiZXN0IGNvdXJzZSBvZiBhY3Rpb24gaXMgdG8gZW1wdHkgdGhlIGNvcnJlc3BvbmRpbmcgd2FsbGV0IGludG8gYW5vdGhlciAnLFxuICAgICAgICAnd2FsbGV0IGFuZCBkaXNjb250aW51ZSB1c2Ugb2YgdGhlIG9sZCB3YWxsZXQuJyxcbiAgICAgIF0sXG4gICAgfSxcbiAgICB7XG4gICAgICBxOiAnV2hhdCBpZiBJIGZvcmdldCBvciBsb3NlIG15IHdhbGxldCBwYXNzd29yZD8nLFxuICAgICAgYTogW1xuICAgICAgICAnQml0R28gY2FuIHVzZSB0aGUgaW5mb3JtYXRpb24gaW4gUVIgQ29kZSBEIHRvIGhlbHAgeW91IHJlY292ZXIgYWNjZXNzIHRvIHlvdXIgd2FsbGV0LiAnLFxuICAgICAgICAnV2l0aG91dCB0aGUgS2V5Q2FyZCwgQml0R28gaXMgbm90IGFibGUgdG8gcmVjb3ZlciBmdW5kcyBmcm9tIGEgd2FsbGV0IHdpdGggYSBsb3N0IHBhc3N3b3JkLicsXG4gICAgICBdLFxuICAgIH0sXG4gICAge1xuICAgICAgcTogJ1doYXQgaWYgQml0R28gYmVjb21lcyBpbmFjY2Vzc2libGUgZm9yIGFuIGV4dGVuZGVkIHBlcmlvZD8nLFxuICAgICAgYTogW1xuICAgICAgICAnWW91ciBLZXlDYXJkIGFuZCB3YWxsZXQgcGFzc2NvZGUgY2FuIGJlIHVzZWQgdG9nZXRoZXIgd2l0aCBCaXRHb+KAmXMgcHVibGlzaGVkIG9wZW4gJyxcbiAgICAgICAgYHNvdXJjZSB0b29scyBhdCBodHRwczovL2dpdGh1Yi5jb20vYml0Z28gdG8gcmVjb3ZlciB5b3VyICR7Y29pbn0uIE5vdGU6IFlvdSBzaG91bGQgbmV2ZXIgZW50ZXIgYCxcbiAgICAgICAgJ2luZm9ybWF0aW9uIGZyb20geW91ciBLZXlDYXJkIGludG8gdG9vbHMgb3RoZXIgdGhhbiB0aGUgdG9vbHMgQml0R28gaGFzIHB1Ymxpc2hlZCwgb3IgeW91ciAnLFxuICAgICAgICAnZnVuZHMgbWF5IGJlIGF0IHJpc2sgZm9yIHRoZWZ0LicsXG4gICAgICBdLFxuICAgIH0sXG4gICAge1xuICAgICAgcTogJ1Nob3VsZCBJIHdyaXRlIG15IHdhbGxldCBwYXNzd29yZCBvbiBteSBLZXlDYXJkPycsXG4gICAgICBhOiBbXG4gICAgICAgICdObyEgQml0R2/igJlzIG11bHRpLXNpZ25hdHVyZSBhcHByb2FjaCB0byBzZWN1cml0eSBkZXBlbmRzIG9uIHRoZXJlIG5vdCBiZWluZyBhIHNpbmdsZSBwb2ludCAnLFxuICAgICAgICAnb2YgYXR0YWNrLiBCdXQgaWYgeW91ciB3YWxsZXQgcGFzc3dvcmQgaXMgb24geW91ciBLZXlDYXJkLCB0aGVuIGFueW9uZSB3aG8gZ2FpbnMgYWNjZXNzIHRvICcsXG4gICAgICAgIGB5b3VyIEtleUNhcmQgd2lsbCBiZSBhYmxlIHRvIHN0ZWFsIHlvdXIgJHtjb2lufS4gV2UgcmVjb21tZW5kIGtlZXBpbmcgeW91ciB3YWxsZXQgcGFzc3dvcmQgYCxcbiAgICAgICAgJ3NhZmUgaW4gYSBzZWN1cmUgcGFzc3dvcmQgbWFuYWdlciBzdWNoIGFzIExhc3RQYXNzLCAxUGFzc3dvcmQgb3IgS2VlUGFzcy4nLFxuICAgICAgXSxcbiAgICB9LFxuICBdO1xufTtcblxuaW50ZXJmYWNlIEdldEtleURhdGFPcHRpb25zIHtcbiAgZW5jcnlwdDogKHBhcmFtczogeyBpbnB1dDogc3RyaW5nOyBwYXNzd29yZDogc3RyaW5nIH0pID0+IHN0cmluZztcbiAgdXNlcktleWNoYWluOiBLZXljaGFpbjtcbiAgYml0Z29LZXljaGFpbjogS2V5Y2hhaW47XG4gIGJhY2t1cEtleWNoYWluOiBLZXljaGFpbjtcbiAgY29pblNob3J0TmFtZTogc3RyaW5nO1xuICBwYXNzcGhyYXNlPzogc3RyaW5nO1xuICBwYXNzY29kZUVuY3J5cHRpb25Db2RlPzogc3RyaW5nO1xuICB3YWxsZXRLZXlJRD86IHN0cmluZztcbiAgYmFja3VwS2V5SUQ/OiBzdHJpbmc7XG59XG5cbi8qKlxuICogQ29sbGVjdCBhbGwgZGF0YSB3aGljaCB3aWxsIGdvIG9udG8gdGhlIGtleWNhcmRcbiAqIEBwYXJhbSBvcHRpb25zXG4gKi9cbmZ1bmN0aW9uIGdldEtleURhdGEob3B0aW9uczogR2V0S2V5RGF0YU9wdGlvbnMpOiBhbnkge1xuICBjb25zdCB7XG4gICAgZW5jcnlwdCxcbiAgICB1c2VyS2V5Y2hhaW4sXG4gICAgYml0Z29LZXljaGFpbixcbiAgICBiYWNrdXBLZXljaGFpbixcbiAgICBjb2luU2hvcnROYW1lLFxuICAgIHBhc3NwaHJhc2UsXG4gICAgcGFzc2NvZGVFbmNyeXB0aW9uQ29kZSxcbiAgICB3YWxsZXRLZXlJRCxcbiAgICBiYWNrdXBLZXlJRCxcbiAgfSA9IG9wdGlvbnM7XG5cbiAgLy8gV2hlbiB1c2luZyBqdXN0ICdnZW5lcmF0ZVdhbGxldCcsIHdlIGdldCBiYWNrIGFuIHVuZW5jcnlwdGVkIHBydiBmb3IgdGhlIGJhY2t1cCBrZXljaGFpblxuICAvLyBJZiB0aGUgdXNlciBwYXNzZXMgaW4gdGhlaXIgcGFzc3BocmFzZSwgd2UgY2FuIGVuY3J5cHQgaXRcbiAgaWYgKGJhY2t1cEtleWNoYWluLnBydiAmJiBwYXNzcGhyYXNlKSB7XG4gICAgYmFja3VwS2V5Y2hhaW4uZW5jcnlwdGVkUHJ2ID0gZW5jcnlwdCh7XG4gICAgICBpbnB1dDogYmFja3VwS2V5Y2hhaW4ucHJ2LFxuICAgICAgcGFzc3dvcmQ6IHBhc3NwaHJhc2UsXG4gICAgfSk7XG4gIH1cblxuICAvLyBJZiB3ZSBoYXZlIHRoZSBwYXNzY29kZSBlbmNyeXB0aW9uIGNvZGUsIGNyZWF0ZSBhIGJveCBEIHdpdGggdGhlIGVuY3J5cHRlZFdhbGxldFBhc3Njb2RlXG4gIGxldCBlbmNyeXB0ZWRXYWxsZXRQYXNzY29kZTtcbiAgaWYgKHBhc3NwaHJhc2UgJiYgcGFzc2NvZGVFbmNyeXB0aW9uQ29kZSkge1xuICAgIGVuY3J5cHRlZFdhbGxldFBhc3Njb2RlID0gZW5jcnlwdCh7XG4gICAgICBpbnB1dDogcGFzc3BocmFzZSxcbiAgICAgIHBhc3N3b3JkOiBwYXNzY29kZUVuY3J5cHRpb25Db2RlLFxuICAgIH0pO1xuICB9XG5cbiAgLy8gUERGIFFSIENvZGUgZGF0YVxuICBjb25zdCBxckRhdGE6IGFueSA9IHtcbiAgICB1c2VyOiB7XG4gICAgICB0aXRsZTogJ0E6IFVzZXIgS2V5JyxcbiAgICAgIGRlc2M6ICdUaGlzIGlzIHlvdXIgcHJpdmF0ZSBrZXksIGVuY3J5cHRlZCB3aXRoIHlvdXIgcGFzc2NvZGUuJyxcbiAgICAgIGRhdGE6IHVzZXJLZXljaGFpbi5lbmNyeXB0ZWRQcnYsXG4gICAgfSxcbiAgICBiYWNrdXA6IHtcbiAgICAgIHRpdGxlOiAnQjogQmFja3VwIEtleScsXG4gICAgICBkZXNjOiAnVGhpcyBpcyB5b3VyIGJhY2t1cCBwcml2YXRlIGtleSwgZW5jcnlwdGVkIHdpdGggeW91ciBwYXNzY29kZS4nLFxuICAgICAgZGF0YTogYmFja3VwS2V5Y2hhaW4uZW5jcnlwdGVkUHJ2LFxuICAgIH0sXG4gICAgYml0Z286IHtcbiAgICAgIHRpdGxlOiAnQzogQml0R28gUHVibGljIEtleScsXG4gICAgICBkZXNjOlxuICAgICAgICAnVGhpcyBpcyB0aGUgcHVibGljIHBhcnQgb2YgdGhlIGtleSB0aGF0IEJpdEdvIHdpbGwgdXNlIHRvICcgK1xuICAgICAgICAnY28tc2lnbiB0cmFuc2FjdGlvbnNcXHJcXG53aXRoIHlvdSBvbiB5b3VyIHdhbGxldC4nLFxuICAgICAgZGF0YTogYml0Z29LZXljaGFpbi5wdWIsXG4gICAgfSxcbiAgICBwYXNzY29kZToge1xuICAgICAgdGl0bGU6ICdEOiBFbmNyeXB0ZWQgV2FsbGV0IFBhc3N3b3JkJyxcbiAgICAgIGRlc2M6ICdUaGlzIGlzIHRoZSB3YWxsZXQgIHBhc3N3b3JkLCBlbmNyeXB0ZWQgY2xpZW50LXNpZGUgJyArICd3aXRoIGEga2V5IGhlbGQgYnlcXHJcXG5CaXRHby4nLFxuICAgICAgZGF0YTogZW5jcnlwdGVkV2FsbGV0UGFzc2NvZGUsXG4gICAgfSxcbiAgfTtcblxuICBpZiAod2FsbGV0S2V5SUQpIHtcbiAgICBxckRhdGEudXNlci5rZXlJRCA9IHdhbGxldEtleUlEO1xuICB9XG5cbiAgaWYgKGJhY2t1cEtleUlEKSB7XG4gICAgcXJEYXRhLmJhY2t1cC5rZXlJRCA9IGJhY2t1cEtleUlEO1xuICB9XG5cbiAgaWYgKGlzVW5kZWZpbmVkKHVzZXJLZXljaGFpbi5lbmNyeXB0ZWRQcnYpKSB7XG4gICAgLy8gVXNlciBwcm92aWRlZCB0aGVpciBvd24ga2V5IC0gdGhpcyBpcyBhIGNvbGQgd2FsbGV0XG4gICAgcXJEYXRhLnVzZXIudGl0bGUgPSAnQTogUHJvdmlkZWQgVXNlciBLZXknO1xuICAgIHFyRGF0YS51c2VyLmRlc2MgPSAnVGhpcyBpcyB0aGUgcHVibGljIGtleSB5b3UgcHJvdmlkZWQgZm9yIHlvdXIgd2FsbGV0Lic7XG4gICAgcXJEYXRhLnVzZXIuZGF0YSA9IHVzZXJLZXljaGFpbi5wdWI7XG5cbiAgICAvLyBUaGUgdXNlciBwcm92aWRlZCB0aGVpciBvd24gcHVibGljIGtleSwgd2UgY2FuIHJlbW92ZSBib3ggRFxuICAgIGRlbGV0ZSBxckRhdGEucGFzc2NvZGU7XG4gIH0gZWxzZSBpZiAoaXNVbmRlZmluZWQoZW5jcnlwdGVkV2FsbGV0UGFzc2NvZGUpKSB7XG4gICAgZGVsZXRlIHFyRGF0YS5wYXNzY29kZTtcbiAgfVxuXG4gIGlmICghaXNVbmRlZmluZWQoYmFja3VwS2V5Y2hhaW4ucHJvdmlkZXIpKSB7XG4gICAgY29uc3QgYmFja3VwS2V5UHJvdmlkZXJOYW1lID0gYmFja3VwS2V5Y2hhaW4ucHJvdmlkZXI7XG4gICAgLy8gQmFja3VwIGtleSBoZWxkIHdpdGggS1JTXG4gICAgcXJEYXRhLmJhY2t1cCA9IHtcbiAgICAgIHRpdGxlOiAnQjogQmFja3VwIEtleScsXG4gICAgICBkZXNjOlxuICAgICAgICBgVGhpcyBpcyB0aGUgcHVibGljIGtleSBoZWxkIGF0ICR7YmFja3VwS2V5UHJvdmlkZXJOYW1lfWAgK1xuICAgICAgICBgLCBhbiAke2NvaW5TaG9ydE5hbWV9IHJlY292ZXJ5IHNlcnZpY2UuIElmIHlvdSBsb3NlXFxyXFxueW91ciBrZXksICR7YmFja3VwS2V5UHJvdmlkZXJOYW1lfWAgK1xuICAgICAgICAnIHdpbGwgYmUgYWJsZSB0byBzaWduIHRyYW5zYWN0aW9ucyB0byByZWNvdmVyIGZ1bmRzLicsXG4gICAgICBkYXRhOiBiYWNrdXBLZXljaGFpbi5wdWIsXG4gICAgfTtcbiAgfSBlbHNlIGlmIChpc1VuZGVmaW5lZChiYWNrdXBLZXljaGFpbi5lbmNyeXB0ZWRQcnYpKSB7XG4gICAgLy8gVXNlciBzdXBwbGllZCB0aGUgeHB1YlxuICAgIHFyRGF0YS5iYWNrdXAgPSB7XG4gICAgICB0aXRsZTogJ0I6IEJhY2t1cCBLZXknLFxuICAgICAgZGVzYzogJ1RoaXMgaXMgdGhlIHB1YmxpYyBwb3J0aW9uIG9mIHlvdXIgYmFja3VwIGtleSwgd2hpY2ggeW91IHByb3ZpZGVkLicsXG4gICAgICBkYXRhOiBiYWNrdXBLZXljaGFpbi5wdWIsXG4gICAgfTtcbiAgfVxuXG4gIHJldHVybiBxckRhdGE7XG59XG5cbmludGVyZmFjZSBEcmF3S2V5Y2FyZE9wdGlvbnMgZXh0ZW5kcyBHZXRLZXlEYXRhT3B0aW9ucyB7XG4gIGpzUERGOiBhbnk7XG4gIFFSQ29kZTogYW55O1xuICBjb2luU2hvcnROYW1lOiBzdHJpbmc7XG4gIGFjdGl2YXRpb25Db2RlOiBzdHJpbmc7XG4gIHdhbGxldExhYmVsOiBzdHJpbmc7XG4gIGNvaW5OYW1lOiBzdHJpbmc7XG59XG5cbi8qKlxuICogRHJhdyBhIGtleWNhcmQgaW50byBhIG5ldyBwZGYgZG9jdW1lbnQgb2JqZWN0XG4gKiBAcGFyYW0gb3B0aW9uc1xuICovXG5leHBvcnQgZnVuY3Rpb24gZHJhd0tleWNhcmQob3B0aW9uczogRHJhd0tleWNhcmRPcHRpb25zKTogYW55IHtcbiAgY29uc3QgeyBqc1BERiwgUVJDb2RlLCBjb2luU2hvcnROYW1lLCBhY3RpdmF0aW9uQ29kZSwgd2FsbGV0TGFiZWwsIGNvaW5OYW1lIH0gPSBvcHRpb25zO1xuXG4gIGNvbnN0IG1hcmdpbiA9IDMwO1xuXG4gIGNvbnN0IGZvbnQgPSB7XG4gICAgaGVhZGVyOiAyNCxcbiAgICBzdWJoZWFkZXI6IDE1LFxuICAgIGJvZHk6IDEyLFxuICB9O1xuXG4gIGNvbnN0IGNvbG9yID0ge1xuICAgIGJsYWNrOiAnIzAwMDAwMCcsXG4gICAgZGFya2dyYXk6ICcjNGM0YzRjJyxcbiAgICBncmF5OiAnIzliOWI5YicsXG4gICAgcmVkOiAnI2UyMWUxZScsXG4gIH07XG5cbiAgLy8gZG9jdW1lbnQgZGV0YWlsc1xuICBjb25zdCB3aWR0aCA9IDguNSAqIDcyO1xuICBsZXQgeSA9IDA7XG5cbiAgLy8gSGVscGVycyBmb3IgZGF0YSBmb3JtYXR0aW5nIC8gcG9zaXRpb25pbmcgb24gdGhlIHBhcGVyXG4gIGNvbnN0IGxlZnQgPSAoeCkgPT4gbWFyZ2luICsgeDtcbiAgY29uc3QgbW92ZURvd24gPSAoeURlbHRhKSA9PiB7XG4gICAgeSArPSB5RGVsdGE7XG4gIH07XG5cbiAgY29uc3QgZG9jID0gbmV3IGpzUERGKCdwb3J0cmFpdCcsICdwdCcsICdsZXR0ZXInKTtcbiAgZG9jLnNldEZvbnQoJ2hlbHZldGljYScpO1xuXG4gIC8vIFBERiBIZWFkZXIgQXJlYSAtIGluY2x1ZGVzIHRoZSBsb2dvIGFuZCBjb21wYW55IG5hbWVcbiAgLy8gVGhpcyBpcyBkYXRhIGZvciB0aGUgQml0R28gbG9nbyBpbiB0aGUgdG9wIGxlZnQgb2YgdGhlIFBERlxuICBtb3ZlRG93bigzMCk7XG5cbiAgLy8gV2UgZG9uJ3QgY3VycmVudGx5IGFkZCBhbiBpbWFnZSwgc2luY2UgdGhhdCBwYXRoIGlzIGRlcGVuZGVudCBvbiBCaXRHbyBmcm9udGVuZFxuICAvLyBkb2MuYWRkSW1hZ2UoY29pblV0aWxpdHkuZ2V0U2VsZWN0ZWRDb2luT2JqKCkua2V5Q2FyZEltYWdlLCBsZWZ0KDApLCB5ICsgMTApO1xuXG4gIC8vIEFjdGl2YXRpb24gQ29kZVxuICBtb3ZlRG93big4KTtcbiAgZG9jLnNldEZvbnRTaXplKGZvbnQuYm9keSkuc2V0VGV4dENvbG9yKGNvbG9yLmdyYXkpO1xuICBkb2MudGV4dCgnQWN0aXZhdGlvbiBDb2RlJywgbGVmdCg0NjApLCB5KTtcblxuICBkb2Muc2V0Rm9udFNpemUoZm9udC5oZWFkZXIpLnNldFRleHRDb2xvcihjb2xvci5ibGFjayk7XG4gIG1vdmVEb3duKDI1KTtcbiAgZG9jLnRleHQoJ1lvdXIgQml0R28gS2V5Q2FyZCcsIGxlZnQoMTUwKSwgeSk7XG4gIGRvYy5zZXRGb250U2l6ZShmb250LmhlYWRlcikuc2V0VGV4dENvbG9yKGNvbG9yLmdyYXkpO1xuICBkb2MudGV4dChhY3RpdmF0aW9uQ29kZS50b1N0cmluZygpLCBsZWZ0KDQ2MCksIHkpO1xuXG4gIC8vIFN1YmhlYWRlclxuICAvLyB0aXRsZXNcbiAgbW92ZURvd24obWFyZ2luKTtcbiAgZG9jLnNldEZvbnRTaXplKGZvbnQuYm9keSkuc2V0VGV4dENvbG9yKGNvbG9yLmdyYXkpO1xuICBkb2MudGV4dChcbiAgICBgQ3JlYXRlZCBvbiAke25ldyBEYXRlKCkudG9EYXRlU3RyaW5nKCl9IGJ5ICR7d2luZG93LmxvY2F0aW9uLmhvc3RuYW1lfSBmb3Igd2FsbGV0IG5hbWVkICR7d2FsbGV0TGFiZWx9YCxcbiAgICBsZWZ0KDApLFxuICAgIHlcbiAgKTtcbiAgLy8gY29weVxuICBtb3ZlRG93bigyNSk7XG4gIGRvYy5zZXRGb250U2l6ZShmb250LnN1YmhlYWRlcikuc2V0VGV4dENvbG9yKGNvbG9yLmJsYWNrKTtcbiAgZG9jLnRleHQod2FsbGV0TGFiZWwsIGxlZnQoMCksIHkpO1xuICAvLyBSZWQgQmFyXG4gIG1vdmVEb3duKDIwKTtcbiAgZG9jLnNldEZpbGxDb2xvcigyNTUsIDIzMCwgMjMwKTtcbiAgZG9jLnJlY3QobGVmdCgwKSwgeSwgd2lkdGggLSAyICogbWFyZ2luLCAzMiwgJ0YnKTtcblxuICAvLyB3YXJuaW5nIG1lc3NhZ2VcbiAgbW92ZURvd24oMjApO1xuICBkb2Muc2V0Rm9udFNpemUoZm9udC5ib2R5KS5zZXRUZXh0Q29sb3IoY29sb3IucmVkKTtcbiAgZG9jLnRleHQoJ1ByaW50IHRoaXMgZG9jdW1lbnQsIG9yIGtlZXAgaXQgc2VjdXJlbHkgb2ZmbGluZS4gU2VlIHNlY29uZCBwYWdlIGZvciBGQVEuJywgbGVmdCg3NSksIHkpO1xuXG4gIGNvbnN0IHtcbiAgICBlbmNyeXB0LFxuICAgIHBhc3NwaHJhc2UsXG4gICAgcGFzc2NvZGVFbmNyeXB0aW9uQ29kZSxcbiAgICB3YWxsZXRLZXlJRCxcbiAgICBiYWNrdXBLZXlJRCxcbiAgICB1c2VyS2V5Y2hhaW4sXG4gICAgYml0Z29LZXljaGFpbixcbiAgICBiYWNrdXBLZXljaGFpbixcbiAgfSA9IG9wdGlvbnM7XG5cbiAgLy8gR2V0IHRoZSBkYXRhIGZvciB0aGUgZmlyc3QgcGFnZSAocXIgY29kZXMpXG4gIGNvbnN0IGtleURhdGEgPSBnZXRLZXlEYXRhKHtcbiAgICBlbmNyeXB0LFxuICAgIGNvaW5TaG9ydE5hbWUsXG4gICAgcGFzc3BocmFzZSxcbiAgICBwYXNzY29kZUVuY3J5cHRpb25Db2RlLFxuICAgIHdhbGxldEtleUlELFxuICAgIGJhY2t1cEtleUlELFxuICAgIHVzZXJLZXljaGFpbixcbiAgICBiaXRnb0tleWNoYWluLFxuICAgIGJhY2t1cEtleWNoYWluLFxuICB9KTtcblxuICAvLyBHZW5lcmF0ZSB0aGUgZmlyc3QgcGFnZSdzIGRhdGEgZm9yIHRoZSBiYWNrdXAgUERGXG4gIG1vdmVEb3duKDM1KTtcbiAgY29uc3QgcXJTaXplID0gMTMwO1xuXG4gIC8vIERyYXcgZWFjaCBCb3ggd2l0aCBRUiBjb2RlIGFuZCBkZXNjcmlwdGlvblxuICBPYmplY3Qua2V5cyhrZXlEYXRhKS5mb3JFYWNoKGZ1bmN0aW9uIChrZXlUeXBlKSB7XG4gICAgY29uc3Qga2V5ID0ga2V5RGF0YVtrZXlUeXBlXTtcbiAgICBjb25zdCB0b3BZID0geTtcblxuICAgIC8vIERvbid0IGluZGVudCBpZiB3ZSdyZSBub3QgcHJvZHVjaW5nIFFSIGNvZGVzXG4gICAgY29uc3QgdGV4dExlZnQgPSAhIVFSQ29kZSA/IGxlZnQocXJTaXplICsgMTUpIDogbGVmdCgxNSk7XG5cbiAgICAvLyBEcmF3IGEgUVIgY29kZSBpZiBsaWJyYXJ5IGlzIGF2YWlsYWJsZVxuICAgIGlmIChRUkNvZGUpIHtcbiAgICAgIGNvbnN0IGRhdGFVUkwgPSBuZXcgUVJDb2RlKHsgdmFsdWU6IGtleS5kYXRhLCBzaXplOiBxclNpemUgfSkudG9EYXRhVVJMKCdpbWFnZS9qcGVnJyk7XG4gICAgICBkb2MuYWRkSW1hZ2UoZGF0YVVSTCwgbGVmdCgwKSwgeSwgcXJTaXplLCBxclNpemUpO1xuICAgIH1cblxuICAgIGRvYy5zZXRGb250U2l6ZShmb250LnN1YmhlYWRlcikuc2V0VGV4dENvbG9yKGNvbG9yLmJsYWNrKTtcbiAgICBtb3ZlRG93bigxMCk7XG4gICAgZG9jLnRleHQoa2V5LnRpdGxlLCB0ZXh0TGVmdCwgeSk7XG4gICAgbW92ZURvd24oMTUpO1xuICAgIGRvYy5zZXRGb250U2l6ZShmb250LmJvZHkpLnNldFRleHRDb2xvcihjb2xvci5kYXJrZ3JheSk7XG4gICAgZG9jLnRleHQoa2V5LmRlc2MsIHRleHRMZWZ0LCB5KTtcbiAgICBtb3ZlRG93bigzMCk7XG4gICAgZG9jLnNldEZvbnRTaXplKGZvbnQuYm9keSAtIDIpO1xuICAgIGRvYy50ZXh0KCdEYXRhOicsIHRleHRMZWZ0LCB5KTtcbiAgICBtb3ZlRG93bigxNSk7XG4gICAgY29uc3QgaW5uZXJXaWR0aCA9IDcyICogOC41IC0gdGV4dExlZnQgLSAzMDtcbiAgICBkb2Muc2V0Rm9udCgnY291cmllcicpLnNldEZvbnRTaXplKDkpLnNldFRleHRDb2xvcihjb2xvci5ibGFjayk7XG4gICAgY29uc3QgbGluZXMgPSBkb2Muc3BsaXRUZXh0VG9TaXplKGtleS5kYXRhLCBpbm5lcldpZHRoKTtcbiAgICBkb2MudGV4dChsaW5lcywgdGV4dExlZnQsIHkpO1xuXG4gICAgLy8gQWRkIGtleSBJRCAoZGVyaXZhdGlvbiBzdHJpbmcpIGlmIGl0IGV4aXN0c1xuICAgIGlmIChrZXkua2V5SUQpIHtcbiAgICAgIGNvbnN0IHRleHQgPSAnS2V5IElkOiAnICsga2V5LmtleUlEO1xuICAgICAgLy8gR3JheSBiYXJcbiAgICAgIG1vdmVEb3duKDQ1KTtcbiAgICAgIGRvYy5zZXRGaWxsQ29sb3IoMjQ3LCAyNDksIDI0OSk7IC8vIEdyYXkgYmFja2dyb3VuZFxuICAgICAgZG9jLnNldERyYXdDb2xvcigwLCAwLCAwKTsgLy8gQm9yZGVyXG4gICAgICBkb2MucmVjdCh0ZXh0TGVmdCwgeSwgd2lkdGgsIDE1LCAnRkQnKTtcblxuICAgICAgZG9jLnRleHQodGV4dCwgdGV4dExlZnQgKyA1LCB5ICsgMTApO1xuICAgIH1cblxuICAgIGRvYy5zZXRGb250KCdoZWx2ZXRpY2EnKTtcbiAgICAvLyBNb3ZlIGRvd24gdGhlIHNpemUgb2YgdGhlIFFSIGNvZGUgbWludXMgYWNjdW11bGF0ZWQgaGVpZ2h0IG9uIHRoZSByaWdodCBzaWRlLCBwbHVzIGJ1ZmZlclxuICAgIG1vdmVEb3duKHFyU2l6ZSAtICh5IC0gdG9wWSkgKyAxNSk7XG4gIH0pO1xuXG4gIC8vIEFkZCBhIG5ldyBwYWdlIChRICsgQSBwYWdlKVxuICBkb2MuYWRkUGFnZSgpO1xuXG4gIC8vIDJuZCBwYWdlIHRpdGxlXG4gIHkgPSAwO1xuICBtb3ZlRG93big1NSk7XG4gIGRvYy5zZXRGb250U2l6ZShmb250LmhlYWRlcikuc2V0VGV4dENvbG9yKGNvbG9yLmJsYWNrKTtcbiAgZG9jLnRleHQoJ0JpdEdvIEtleUNhcmQgRkFRJywgbGVmdCgwKSwgeSk7XG5cbiAgY29uc3QgcXVlc3Rpb25zID0gZ2VuZXJhdGVRdWVzdGlvbnMoY29pbk5hbWUpO1xuXG4gIC8vIERyYXcgdGhlIFEgKyBBIGRhdGEgb24gdGhlIHNlY29uZCBwYWdlXG4gIG1vdmVEb3duKDMwKTtcbiAgcXVlc3Rpb25zLmZvckVhY2goZnVuY3Rpb24gKHEpIHtcbiAgICBkb2Muc2V0Rm9udFNpemUoZm9udC5zdWJoZWFkZXIpLnNldFRleHRDb2xvcihjb2xvci5ibGFjayk7XG4gICAgZG9jLnRleHQocS5xLCBsZWZ0KDApLCB5KTtcbiAgICBtb3ZlRG93bigyMCk7XG4gICAgZG9jLnNldEZvbnRTaXplKGZvbnQuYm9keSkuc2V0VGV4dENvbG9yKGNvbG9yLmRhcmtncmF5KTtcbiAgICBxLmEuZm9yRWFjaChmdW5jdGlvbiAobGluZSkge1xuICAgICAgZG9jLnRleHQobGluZSwgbGVmdCgwKSwgeSk7XG4gICAgICBtb3ZlRG93bihmb250LmJvZHkgKyAzKTtcbiAgICB9KTtcbiAgICBtb3ZlRG93bigyMik7XG4gIH0pO1xuXG4gIHJldHVybiBkb2M7XG59XG4iXX0=Выполнить команду
Для локальной разработки. Не используйте в интернете!