israeli-bank-scrapers-core
Version:
Provide scrapers for all major Israeli banks and credit card companies
242 lines (240 loc) • 40.5 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _moment = _interopRequireDefault(require("moment"));
var _constants = require("../constants");
var _elementsInteractions = require("../helpers/elements-interactions");
var _navigation = require("../helpers/navigation");
var _transactions = require("../transactions");
var _baseScraperWithBrowser = require("./base-scraper-with-browser");
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
const BASE_URL = 'https://hb.unionbank.co.il';
const TRANSACTIONS_URL = `${BASE_URL}/eBanking/Accounts/ExtendedActivity.aspx#/`;
const DATE_FORMAT = 'DD/MM/YY';
const NO_TRANSACTION_IN_DATE_RANGE_TEXT = 'לא קיימות תנועות מתאימות על פי הסינון שהוגדר';
const DATE_HEADER = 'תאריך';
const DESCRIPTION_HEADER = 'תיאור';
const REFERENCE_HEADER = 'אסמכתא';
const DEBIT_HEADER = 'חובה';
const CREDIT_HEADER = 'זכות';
const PENDING_TRANSACTIONS_TABLE_ID = 'trTodayActivityNapaTableUpper';
const COMPLETED_TRANSACTIONS_TABLE_ID = 'ctlActivityTable';
const ERROR_MESSAGE_CLASS = 'errInfo';
const ACCOUNTS_DROPDOWN_SELECTOR = 'select#ddlAccounts_m_ddl';
function getPossibleLoginResults() {
const urls = {};
urls[_baseScraperWithBrowser.LoginResults.Success] = [/eBanking\/Accounts/];
urls[_baseScraperWithBrowser.LoginResults.InvalidPassword] = [/InternalSite\/CustomUpdate\/leumi\/LoginPage.ASP/];
return urls;
}
function createLoginFields(credentials) {
return [{
selector: '#uid',
value: credentials.username
}, {
selector: '#password',
value: credentials.password
}];
}
function getAmountData(amountStr) {
const amountStrCopy = amountStr.replace(',', '');
return parseFloat(amountStrCopy);
}
function getTxnAmount(txn) {
const credit = getAmountData(txn.credit);
const debit = getAmountData(txn.debit);
return (Number.isNaN(credit) ? 0 : credit) - (Number.isNaN(debit) ? 0 : debit);
}
function convertTransactions(txns) {
return txns.map(txn => {
const convertedDate = (0, _moment.default)(txn.date, DATE_FORMAT).toISOString();
const convertedAmount = getTxnAmount(txn);
return {
type: _transactions.TransactionTypes.Normal,
identifier: txn.reference ? parseInt(txn.reference, 10) : undefined,
date: convertedDate,
processedDate: convertedDate,
originalAmount: convertedAmount,
originalCurrency: _constants.SHEKEL_CURRENCY,
chargedAmount: convertedAmount,
status: txn.status,
description: txn.description,
memo: txn.memo
};
});
}
function getTransactionDate(tds, txnsTableHeaders) {
return (tds[txnsTableHeaders[DATE_HEADER]] || '').trim();
}
function getTransactionDescription(tds, txnsTableHeaders) {
return (tds[txnsTableHeaders[DESCRIPTION_HEADER]] || '').trim();
}
function getTransactionReference(tds, txnsTableHeaders) {
return (tds[txnsTableHeaders[REFERENCE_HEADER]] || '').trim();
}
function getTransactionDebit(tds, txnsTableHeaders) {
return (tds[txnsTableHeaders[DEBIT_HEADER]] || '').trim();
}
function getTransactionCredit(tds, txnsTableHeaders) {
return (tds[txnsTableHeaders[CREDIT_HEADER]] || '').trim();
}
function extractTransactionDetails(txnRow, txnsTableHeaders, txnStatus) {
const tds = txnRow.innerTds;
return {
status: txnStatus,
date: getTransactionDate(tds, txnsTableHeaders),
description: getTransactionDescription(tds, txnsTableHeaders),
reference: getTransactionReference(tds, txnsTableHeaders),
debit: getTransactionDebit(tds, txnsTableHeaders),
credit: getTransactionCredit(tds, txnsTableHeaders),
memo: ''
};
}
function isExpandedDescRow(txnRow) {
return txnRow.id === 'rowAdded';
}
/* eslint-disable no-param-reassign */
function editLastTransactionDesc(txnRow, lastTxn) {
lastTxn.description = `${lastTxn.description} ${txnRow.innerTds[0]}`;
return lastTxn;
}
function handleTransactionRow(txns, txnsTableHeaders, txnRow, txnType) {
if (isExpandedDescRow(txnRow)) {
const lastTransaction = txns.pop();
if (lastTransaction) {
txns.push(editLastTransactionDesc(txnRow, lastTransaction));
} else {
throw new Error('internal union-bank error');
}
} else {
txns.push(extractTransactionDetails(txnRow, txnsTableHeaders, txnType));
}
}
async function getTransactionsTableHeaders(page, tableTypeId) {
const headersMap = [];
const headersObjs = await (0, _elementsInteractions.pageEvalAll)(page, `#WorkSpaceBox #${tableTypeId} tr[class='header'] th`, null, ths => {
return ths.map((th, index) => ({
text: th.innerText.trim(),
index
}));
});
for (const headerObj of headersObjs) {
headersMap[headerObj.text] = headerObj.index;
}
return headersMap;
}
async function extractTransactionsFromTable(page, tableTypeId, txnType) {
const txns = [];
const transactionsTableHeaders = await getTransactionsTableHeaders(page, tableTypeId);
const transactionsRows = await (0, _elementsInteractions.pageEvalAll)(page, `#WorkSpaceBox #${tableTypeId} tr[class]:not([class='header'])`, [], trs => {
return trs.map(tr => ({
id: tr.getAttribute('id') || '',
innerTds: Array.from(tr.getElementsByTagName('td')).map(td => td.innerText)
}));
});
for (const txnRow of transactionsRows) {
handleTransactionRow(txns, transactionsTableHeaders, txnRow, txnType);
}
return txns;
}
async function isNoTransactionInDateRangeError(page) {
const hasErrorInfoElement = await (0, _elementsInteractions.elementPresentOnPage)(page, `.${ERROR_MESSAGE_CLASS}`);
if (hasErrorInfoElement) {
const errorText = await page.$eval(`.${ERROR_MESSAGE_CLASS}`, errorElement => {
return errorElement.innerText;
});
return errorText.trim() === NO_TRANSACTION_IN_DATE_RANGE_TEXT;
}
return false;
}
async function chooseAccount(page, accountId) {
const hasDropDownList = await (0, _elementsInteractions.elementPresentOnPage)(page, ACCOUNTS_DROPDOWN_SELECTOR);
if (hasDropDownList) {
await (0, _elementsInteractions.dropdownSelect)(page, ACCOUNTS_DROPDOWN_SELECTOR, accountId);
}
}
async function searchByDates(page, startDate) {
await (0, _elementsInteractions.dropdownSelect)(page, 'select#ddlTransactionPeriod', '004');
await (0, _elementsInteractions.waitUntilElementFound)(page, 'select#ddlTransactionPeriod');
await (0, _elementsInteractions.fillInput)(page, 'input#dtFromDate_textBox', startDate.format(DATE_FORMAT));
await (0, _elementsInteractions.clickButton)(page, 'input#btnDisplayDates');
await (0, _navigation.waitForNavigation)(page);
}
async function getAccountNumber(page) {
const selectedSnifAccount = await page.$eval('#ddlAccounts_m_ddl option[selected="selected"]', option => {
return option.innerText;
});
return selectedSnifAccount.replace('/', '_');
}
async function expandTransactionsTable(page) {
const hasExpandAllButton = await (0, _elementsInteractions.elementPresentOnPage)(page, "a[id*='lnkCtlExpandAll']");
if (hasExpandAllButton) {
await (0, _elementsInteractions.clickButton)(page, "a[id*='lnkCtlExpandAll']");
}
}
async function scrapeTransactionsFromTable(page) {
const pendingTxns = await extractTransactionsFromTable(page, PENDING_TRANSACTIONS_TABLE_ID, _transactions.TransactionStatuses.Pending);
const completedTxns = await extractTransactionsFromTable(page, COMPLETED_TRANSACTIONS_TABLE_ID, _transactions.TransactionStatuses.Completed);
const txns = [...pendingTxns, ...completedTxns];
return convertTransactions(txns);
}
async function getAccountTransactions(page) {
await Promise.race([(0, _elementsInteractions.waitUntilElementFound)(page, `#${COMPLETED_TRANSACTIONS_TABLE_ID}`, false), (0, _elementsInteractions.waitUntilElementFound)(page, `.${ERROR_MESSAGE_CLASS}`, false)]);
const noTransactionInRangeError = await isNoTransactionInDateRangeError(page);
if (noTransactionInRangeError) {
return [];
}
await expandTransactionsTable(page);
return scrapeTransactionsFromTable(page);
}
async function fetchAccountData(page, startDate, accountId) {
await chooseAccount(page, accountId);
await searchByDates(page, startDate);
const accountNumber = await getAccountNumber(page);
const txns = await getAccountTransactions(page);
return {
accountNumber,
txns
};
}
async function fetchAccounts(page, startDate) {
const accounts = [];
const accountsList = await (0, _elementsInteractions.dropdownElements)(page, ACCOUNTS_DROPDOWN_SELECTOR);
for (const account of accountsList) {
if (account.value !== '-1') {
// Skip "All accounts" option
const accountData = await fetchAccountData(page, startDate, account.value);
accounts.push(accountData);
}
}
return accounts;
}
async function waitForPostLogin(page) {
return Promise.race([(0, _elementsInteractions.waitUntilElementFound)(page, '#signoff', true), (0, _elementsInteractions.waitUntilElementFound)(page, '#restore', true)]);
}
class UnionBankScraper extends _baseScraperWithBrowser.BaseScraperWithBrowser {
getLoginOptions(credentials) {
return {
loginUrl: `${BASE_URL}`,
fields: createLoginFields(credentials),
submitButtonSelector: '#enter',
postAction: async () => waitForPostLogin(this.page),
possibleResults: getPossibleLoginResults()
};
}
async fetchData() {
const defaultStartMoment = (0, _moment.default)().subtract(1, 'years').add(1, 'day');
const startDate = this.options.startDate || defaultStartMoment.toDate();
const startMoment = _moment.default.max(defaultStartMoment, (0, _moment.default)(startDate));
await this.navigateTo(TRANSACTIONS_URL);
const accounts = await fetchAccounts(this.page, startMoment);
return {
success: true,
accounts
};
}
}
var _default = exports.default = UnionBankScraper;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfbW9tZW50IiwiX2ludGVyb3BSZXF1aXJlRGVmYXVsdCIsInJlcXVpcmUiLCJfY29uc3RhbnRzIiwiX2VsZW1lbnRzSW50ZXJhY3Rpb25zIiwiX25hdmlnYXRpb24iLCJfdHJhbnNhY3Rpb25zIiwiX2Jhc2VTY3JhcGVyV2l0aEJyb3dzZXIiLCJlIiwiX19lc01vZHVsZSIsImRlZmF1bHQiLCJCQVNFX1VSTCIsIlRSQU5TQUNUSU9OU19VUkwiLCJEQVRFX0ZPUk1BVCIsIk5PX1RSQU5TQUNUSU9OX0lOX0RBVEVfUkFOR0VfVEVYVCIsIkRBVEVfSEVBREVSIiwiREVTQ1JJUFRJT05fSEVBREVSIiwiUkVGRVJFTkNFX0hFQURFUiIsIkRFQklUX0hFQURFUiIsIkNSRURJVF9IRUFERVIiLCJQRU5ESU5HX1RSQU5TQUNUSU9OU19UQUJMRV9JRCIsIkNPTVBMRVRFRF9UUkFOU0FDVElPTlNfVEFCTEVfSUQiLCJFUlJPUl9NRVNTQUdFX0NMQVNTIiwiQUNDT1VOVFNfRFJPUERPV05fU0VMRUNUT1IiLCJnZXRQb3NzaWJsZUxvZ2luUmVzdWx0cyIsInVybHMiLCJMb2dpblJlc3VsdHMiLCJTdWNjZXNzIiwiSW52YWxpZFBhc3N3b3JkIiwiY3JlYXRlTG9naW5GaWVsZHMiLCJjcmVkZW50aWFscyIsInNlbGVjdG9yIiwidmFsdWUiLCJ1c2VybmFtZSIsInBhc3N3b3JkIiwiZ2V0QW1vdW50RGF0YSIsImFtb3VudFN0ciIsImFtb3VudFN0ckNvcHkiLCJyZXBsYWNlIiwicGFyc2VGbG9hdCIsImdldFR4bkFtb3VudCIsInR4biIsImNyZWRpdCIsImRlYml0IiwiTnVtYmVyIiwiaXNOYU4iLCJjb252ZXJ0VHJhbnNhY3Rpb25zIiwidHhucyIsIm1hcCIsImNvbnZlcnRlZERhdGUiLCJtb21lbnQiLCJkYXRlIiwidG9JU09TdHJpbmciLCJjb252ZXJ0ZWRBbW91bnQiLCJ0eXBlIiwiVHJhbnNhY3Rpb25UeXBlcyIsIk5vcm1hbCIsImlkZW50aWZpZXIiLCJyZWZlcmVuY2UiLCJwYXJzZUludCIsInVuZGVmaW5lZCIsInByb2Nlc3NlZERhdGUiLCJvcmlnaW5hbEFtb3VudCIsIm9yaWdpbmFsQ3VycmVuY3kiLCJTSEVLRUxfQ1VSUkVOQ1kiLCJjaGFyZ2VkQW1vdW50Iiwic3RhdHVzIiwiZGVzY3JpcHRpb24iLCJtZW1vIiwiZ2V0VHJhbnNhY3Rpb25EYXRlIiwidGRzIiwidHhuc1RhYmxlSGVhZGVycyIsInRyaW0iLCJnZXRUcmFuc2FjdGlvbkRlc2NyaXB0aW9uIiwiZ2V0VHJhbnNhY3Rpb25SZWZlcmVuY2UiLCJnZXRUcmFuc2FjdGlvbkRlYml0IiwiZ2V0VHJhbnNhY3Rpb25DcmVkaXQiLCJleHRyYWN0VHJhbnNhY3Rpb25EZXRhaWxzIiwidHhuUm93IiwidHhuU3RhdHVzIiwiaW5uZXJUZHMiLCJpc0V4cGFuZGVkRGVzY1JvdyIsImlkIiwiZWRpdExhc3RUcmFuc2FjdGlvbkRlc2MiLCJsYXN0VHhuIiwiaGFuZGxlVHJhbnNhY3Rpb25Sb3ciLCJ0eG5UeXBlIiwibGFzdFRyYW5zYWN0aW9uIiwicG9wIiwicHVzaCIsIkVycm9yIiwiZ2V0VHJhbnNhY3Rpb25zVGFibGVIZWFkZXJzIiwicGFnZSIsInRhYmxlVHlwZUlkIiwiaGVhZGVyc01hcCIsImhlYWRlcnNPYmpzIiwicGFnZUV2YWxBbGwiLCJ0aHMiLCJ0aCIsImluZGV4IiwidGV4dCIsImlubmVyVGV4dCIsImhlYWRlck9iaiIsImV4dHJhY3RUcmFuc2FjdGlvbnNGcm9tVGFibGUiLCJ0cmFuc2FjdGlvbnNUYWJsZUhlYWRlcnMiLCJ0cmFuc2FjdGlvbnNSb3dzIiwidHJzIiwidHIiLCJnZXRBdHRyaWJ1dGUiLCJBcnJheSIsImZyb20iLCJnZXRFbGVtZW50c0J5VGFnTmFtZSIsInRkIiwiaXNOb1RyYW5zYWN0aW9uSW5EYXRlUmFuZ2VFcnJvciIsImhhc0Vycm9ySW5mb0VsZW1lbnQiLCJlbGVtZW50UHJlc2VudE9uUGFnZSIsImVycm9yVGV4dCIsIiRldmFsIiwiZXJyb3JFbGVtZW50IiwiY2hvb3NlQWNjb3VudCIsImFjY291bnRJZCIsImhhc0Ryb3BEb3duTGlzdCIsImRyb3Bkb3duU2VsZWN0Iiwic2VhcmNoQnlEYXRlcyIsInN0YXJ0RGF0ZSIsIndhaXRVbnRpbEVsZW1lbnRGb3VuZCIsImZpbGxJbnB1dCIsImZvcm1hdCIsImNsaWNrQnV0dG9uIiwid2FpdEZvck5hdmlnYXRpb24iLCJnZXRBY2NvdW50TnVtYmVyIiwic2VsZWN0ZWRTbmlmQWNjb3VudCIsIm9wdGlvbiIsImV4cGFuZFRyYW5zYWN0aW9uc1RhYmxlIiwiaGFzRXhwYW5kQWxsQnV0dG9uIiwic2NyYXBlVHJhbnNhY3Rpb25zRnJvbVRhYmxlIiwicGVuZGluZ1R4bnMiLCJUcmFuc2FjdGlvblN0YXR1c2VzIiwiUGVuZGluZyIsImNvbXBsZXRlZFR4bnMiLCJDb21wbGV0ZWQiLCJnZXRBY2NvdW50VHJhbnNhY3Rpb25zIiwiUHJvbWlzZSIsInJhY2UiLCJub1RyYW5zYWN0aW9uSW5SYW5nZUVycm9yIiwiZmV0Y2hBY2NvdW50RGF0YSIsImFjY291bnROdW1iZXIiLCJmZXRjaEFjY291bnRzIiwiYWNjb3VudHMiLCJhY2NvdW50c0xpc3QiLCJkcm9wZG93bkVsZW1lbnRzIiwiYWNjb3VudCIsImFjY291bnREYXRhIiwid2FpdEZvclBvc3RMb2dpbiIsIlVuaW9uQmFua1NjcmFwZXIiLCJCYXNlU2NyYXBlcldpdGhCcm93c2VyIiwiZ2V0TG9naW5PcHRpb25zIiwibG9naW5VcmwiLCJmaWVsZHMiLCJzdWJtaXRCdXR0b25TZWxlY3RvciIsInBvc3RBY3Rpb24iLCJwb3NzaWJsZVJlc3VsdHMiLCJmZXRjaERhdGEiLCJkZWZhdWx0U3RhcnRNb21lbnQiLCJzdWJ0cmFjdCIsImFkZCIsIm9wdGlvbnMiLCJ0b0RhdGUiLCJzdGFydE1vbWVudCIsIm1heCIsIm5hdmlnYXRlVG8iLCJzdWNjZXNzIiwiX2RlZmF1bHQiLCJleHBvcnRzIl0sInNvdXJjZXMiOlsiLi4vLi4vc3JjL3NjcmFwZXJzL3VuaW9uLWJhbmsudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IG1vbWVudCwgeyB0eXBlIE1vbWVudCB9IGZyb20gJ21vbWVudCc7XG5pbXBvcnQgeyB0eXBlIFBhZ2UgfSBmcm9tICdwdXBwZXRlZXItY29yZSc7XG5pbXBvcnQgeyBTSEVLRUxfQ1VSUkVOQ1kgfSBmcm9tICcuLi9jb25zdGFudHMnO1xuaW1wb3J0IHtcbiAgY2xpY2tCdXR0b24sXG4gIGRyb3Bkb3duRWxlbWVudHMsXG4gIGRyb3Bkb3duU2VsZWN0LFxuICBlbGVtZW50UHJlc2VudE9uUGFnZSxcbiAgZmlsbElucHV0LFxuICBwYWdlRXZhbEFsbCxcbiAgd2FpdFVudGlsRWxlbWVudEZvdW5kLFxufSBmcm9tICcuLi9oZWxwZXJzL2VsZW1lbnRzLWludGVyYWN0aW9ucyc7XG5pbXBvcnQgeyB3YWl0Rm9yTmF2aWdhdGlvbiB9IGZyb20gJy4uL2hlbHBlcnMvbmF2aWdhdGlvbic7XG5pbXBvcnQgeyBUcmFuc2FjdGlvblN0YXR1c2VzLCBUcmFuc2FjdGlvblR5cGVzLCB0eXBlIFRyYW5zYWN0aW9uLCB0eXBlIFRyYW5zYWN0aW9uc0FjY291bnQgfSBmcm9tICcuLi90cmFuc2FjdGlvbnMnO1xuaW1wb3J0IHsgQmFzZVNjcmFwZXJXaXRoQnJvd3NlciwgTG9naW5SZXN1bHRzLCB0eXBlIFBvc3NpYmxlTG9naW5SZXN1bHRzIH0gZnJvbSAnLi9iYXNlLXNjcmFwZXItd2l0aC1icm93c2VyJztcblxuY29uc3QgQkFTRV9VUkwgPSAnaHR0cHM6Ly9oYi51bmlvbmJhbmsuY28uaWwnO1xuY29uc3QgVFJBTlNBQ1RJT05TX1VSTCA9IGAke0JBU0VfVVJMfS9lQmFua2luZy9BY2NvdW50cy9FeHRlbmRlZEFjdGl2aXR5LmFzcHgjL2A7XG5jb25zdCBEQVRFX0ZPUk1BVCA9ICdERC9NTS9ZWSc7XG5jb25zdCBOT19UUkFOU0FDVElPTl9JTl9EQVRFX1JBTkdFX1RFWFQgPSAn15zXkCDXp9eZ15nXnteV16og16rXoNeV16LXldeqINee16rXkNeZ157XldeqINei15wg16TXmSDXlNeh15nXoNeV158g16nXlNeV15LXk9eoJztcbmNvbnN0IERBVEVfSEVBREVSID0gJ9eq15DXqNeZ15onO1xuY29uc3QgREVTQ1JJUFRJT05fSEVBREVSID0gJ9eq15nXkNeV16gnO1xuY29uc3QgUkVGRVJFTkNFX0hFQURFUiA9ICfXkNeh157Xm9eq15AnO1xuY29uc3QgREVCSVRfSEVBREVSID0gJ9eX15XXkdeUJztcbmNvbnN0IENSRURJVF9IRUFERVIgPSAn15bXm9eV16onO1xuY29uc3QgUEVORElOR19UUkFOU0FDVElPTlNfVEFCTEVfSUQgPSAndHJUb2RheUFjdGl2aXR5TmFwYVRhYmxlVXBwZXInO1xuY29uc3QgQ09NUExFVEVEX1RSQU5TQUNUSU9OU19UQUJMRV9JRCA9ICdjdGxBY3Rpdml0eVRhYmxlJztcbmNvbnN0IEVSUk9SX01FU1NBR0VfQ0xBU1MgPSAnZXJySW5mbyc7XG5jb25zdCBBQ0NPVU5UU19EUk9QRE9XTl9TRUxFQ1RPUiA9ICdzZWxlY3QjZGRsQWNjb3VudHNfbV9kZGwnO1xuXG5mdW5jdGlvbiBnZXRQb3NzaWJsZUxvZ2luUmVzdWx0cygpIHtcbiAgY29uc3QgdXJsczogUG9zc2libGVMb2dpblJlc3VsdHMgPSB7fTtcbiAgdXJsc1tMb2dpblJlc3VsdHMuU3VjY2Vzc10gPSBbL2VCYW5raW5nXFwvQWNjb3VudHMvXTtcbiAgdXJsc1tMb2dpblJlc3VsdHMuSW52YWxpZFBhc3N3b3JkXSA9IFsvSW50ZXJuYWxTaXRlXFwvQ3VzdG9tVXBkYXRlXFwvbGV1bWlcXC9Mb2dpblBhZ2UuQVNQL107XG4gIHJldHVybiB1cmxzO1xufVxuXG5mdW5jdGlvbiBjcmVhdGVMb2dpbkZpZWxkcyhjcmVkZW50aWFsczogU2NyYXBlclNwZWNpZmljQ3JlZGVudGlhbHMpIHtcbiAgcmV0dXJuIFtcbiAgICB7IHNlbGVjdG9yOiAnI3VpZCcsIHZhbHVlOiBjcmVkZW50aWFscy51c2VybmFtZSB9LFxuICAgIHsgc2VsZWN0b3I6ICcjcGFzc3dvcmQnLCB2YWx1ZTogY3JlZGVudGlhbHMucGFzc3dvcmQgfSxcbiAgXTtcbn1cblxuZnVuY3Rpb24gZ2V0QW1vdW50RGF0YShhbW91bnRTdHI6IHN0cmluZykge1xuICBjb25zdCBhbW91bnRTdHJDb3B5ID0gYW1vdW50U3RyLnJlcGxhY2UoJywnLCAnJyk7XG4gIHJldHVybiBwYXJzZUZsb2F0KGFtb3VudFN0ckNvcHkpO1xufVxuXG5pbnRlcmZhY2UgU2NyYXBlZFRyYW5zYWN0aW9uIHtcbiAgY3JlZGl0OiBzdHJpbmc7XG4gIGRlYml0OiBzdHJpbmc7XG4gIGRhdGU6IHN0cmluZztcbiAgcmVmZXJlbmNlPzogc3RyaW5nO1xuICBkZXNjcmlwdGlvbjogc3RyaW5nO1xuICBtZW1vOiBzdHJpbmc7XG4gIHN0YXR1czogVHJhbnNhY3Rpb25TdGF0dXNlcztcbn1cblxuZnVuY3Rpb24gZ2V0VHhuQW1vdW50KHR4bjogU2NyYXBlZFRyYW5zYWN0aW9uKSB7XG4gIGNvbnN0IGNyZWRpdCA9IGdldEFtb3VudERhdGEodHhuLmNyZWRpdCk7XG4gIGNvbnN0IGRlYml0ID0gZ2V0QW1vdW50RGF0YSh0eG4uZGViaXQpO1xuICByZXR1cm4gKE51bWJlci5pc05hTihjcmVkaXQpID8gMCA6IGNyZWRpdCkgLSAoTnVtYmVyLmlzTmFOKGRlYml0KSA/IDAgOiBkZWJpdCk7XG59XG5cbmZ1bmN0aW9uIGNvbnZlcnRUcmFuc2FjdGlvbnModHhuczogU2NyYXBlZFRyYW5zYWN0aW9uW10pOiBUcmFuc2FjdGlvbltdIHtcbiAgcmV0dXJuIHR4bnMubWFwKHR4biA9PiB7XG4gICAgY29uc3QgY29udmVydGVkRGF0ZSA9IG1vbWVudCh0eG4uZGF0ZSwgREFURV9GT1JNQVQpLnRvSVNPU3RyaW5nKCk7XG4gICAgY29uc3QgY29udmVydGVkQW1vdW50ID0gZ2V0VHhuQW1vdW50KHR4bik7XG4gICAgcmV0dXJuIHtcbiAgICAgIHR5cGU6IFRyYW5zYWN0aW9uVHlwZXMuTm9ybWFsLFxuICAgICAgaWRlbnRpZmllcjogdHhuLnJlZmVyZW5jZSA/IHBhcnNlSW50KHR4bi5yZWZlcmVuY2UsIDEwKSA6IHVuZGVmaW5lZCxcbiAgICAgIGRhdGU6IGNvbnZlcnRlZERhdGUsXG4gICAgICBwcm9jZXNzZWREYXRlOiBjb252ZXJ0ZWREYXRlLFxuICAgICAgb3JpZ2luYWxBbW91bnQ6IGNvbnZlcnRlZEFtb3VudCxcbiAgICAgIG9yaWdpbmFsQ3VycmVuY3k6IFNIRUtFTF9DVVJSRU5DWSxcbiAgICAgIGNoYXJnZWRBbW91bnQ6IGNvbnZlcnRlZEFtb3VudCxcbiAgICAgIHN0YXR1czogdHhuLnN0YXR1cyxcbiAgICAgIGRlc2NyaXB0aW9uOiB0eG4uZGVzY3JpcHRpb24sXG4gICAgICBtZW1vOiB0eG4ubWVtbyxcbiAgICB9O1xuICB9KTtcbn1cblxudHlwZSBUcmFuc2FjdGlvbnNUciA9IHsgaWQ6IHN0cmluZzsgaW5uZXJUZHM6IFRyYW5zYWN0aW9uc1RyVGRzIH07XG50eXBlIFRyYW5zYWN0aW9uVGFibGVIZWFkZXJzID0gUmVjb3JkPHN0cmluZywgbnVtYmVyPjtcbnR5cGUgVHJhbnNhY3Rpb25zVHJUZHMgPSBzdHJpbmdbXTtcblxuZnVuY3Rpb24gZ2V0VHJhbnNhY3Rpb25EYXRlKHRkczogVHJhbnNhY3Rpb25zVHJUZHMsIHR4bnNUYWJsZUhlYWRlcnM6IFRyYW5zYWN0aW9uVGFibGVIZWFkZXJzKSB7XG4gIHJldHVybiAodGRzW3R4bnNUYWJsZUhlYWRlcnNbREFURV9IRUFERVJdXSB8fCAnJykudHJpbSgpO1xufVxuXG5mdW5jdGlvbiBnZXRUcmFuc2FjdGlvbkRlc2NyaXB0aW9uKHRkczogVHJhbnNhY3Rpb25zVHJUZHMsIHR4bnNUYWJsZUhlYWRlcnM6IFRyYW5zYWN0aW9uVGFibGVIZWFkZXJzKSB7XG4gIHJldHVybiAodGRzW3R4bnNUYWJsZUhlYWRlcnNbREVTQ1JJUFRJT05fSEVBREVSXV0gfHwgJycpLnRyaW0oKTtcbn1cblxuZnVuY3Rpb24gZ2V0VHJhbnNhY3Rpb25SZWZlcmVuY2UodGRzOiBUcmFuc2FjdGlvbnNUclRkcywgdHhuc1RhYmxlSGVhZGVyczogVHJhbnNhY3Rpb25UYWJsZUhlYWRlcnMpIHtcbiAgcmV0dXJuICh0ZHNbdHhuc1RhYmxlSGVhZGVyc1tSRUZFUkVOQ0VfSEVBREVSXV0gfHwgJycpLnRyaW0oKTtcbn1cblxuZnVuY3Rpb24gZ2V0VHJhbnNhY3Rpb25EZWJpdCh0ZHM6IFRyYW5zYWN0aW9uc1RyVGRzLCB0eG5zVGFibGVIZWFkZXJzOiBUcmFuc2FjdGlvblRhYmxlSGVhZGVycykge1xuICByZXR1cm4gKHRkc1t0eG5zVGFibGVIZWFkZXJzW0RFQklUX0hFQURFUl1dIHx8ICcnKS50cmltKCk7XG59XG5cbmZ1bmN0aW9uIGdldFRyYW5zYWN0aW9uQ3JlZGl0KHRkczogVHJhbnNhY3Rpb25zVHJUZHMsIHR4bnNUYWJsZUhlYWRlcnM6IFRyYW5zYWN0aW9uVGFibGVIZWFkZXJzKSB7XG4gIHJldHVybiAodGRzW3R4bnNUYWJsZUhlYWRlcnNbQ1JFRElUX0hFQURFUl1dIHx8ICcnKS50cmltKCk7XG59XG5cbmZ1bmN0aW9uIGV4dHJhY3RUcmFuc2FjdGlvbkRldGFpbHMoXG4gIHR4blJvdzogVHJhbnNhY3Rpb25zVHIsXG4gIHR4bnNUYWJsZUhlYWRlcnM6IFRyYW5zYWN0aW9uVGFibGVIZWFkZXJzLFxuICB0eG5TdGF0dXM6IFRyYW5zYWN0aW9uU3RhdHVzZXMsXG4pOiBTY3JhcGVkVHJhbnNhY3Rpb24ge1xuICBjb25zdCB0ZHMgPSB0eG5Sb3cuaW5uZXJUZHM7XG4gIHJldHVybiB7XG4gICAgc3RhdHVzOiB0eG5TdGF0dXMsXG4gICAgZGF0ZTogZ2V0VHJhbnNhY3Rpb25EYXRlKHRkcywgdHhuc1RhYmxlSGVhZGVycyksXG4gICAgZGVzY3JpcHRpb246IGdldFRyYW5zYWN0aW9uRGVzY3JpcHRpb24odGRzLCB0eG5zVGFibGVIZWFkZXJzKSxcbiAgICByZWZlcmVuY2U6IGdldFRyYW5zYWN0aW9uUmVmZXJlbmNlKHRkcywgdHhuc1RhYmxlSGVhZGVycyksXG4gICAgZGViaXQ6IGdldFRyYW5zYWN0aW9uRGViaXQodGRzLCB0eG5zVGFibGVIZWFkZXJzKSxcbiAgICBjcmVkaXQ6IGdldFRyYW5zYWN0aW9uQ3JlZGl0KHRkcywgdHhuc1RhYmxlSGVhZGVycyksXG4gICAgbWVtbzogJycsXG4gIH07XG59XG5cbmZ1bmN0aW9uIGlzRXhwYW5kZWREZXNjUm93KHR4blJvdzogVHJhbnNhY3Rpb25zVHIpIHtcbiAgcmV0dXJuIHR4blJvdy5pZCA9PT0gJ3Jvd0FkZGVkJztcbn1cblxuLyogZXNsaW50LWRpc2FibGUgbm8tcGFyYW0tcmVhc3NpZ24gKi9cbmZ1bmN0aW9uIGVkaXRMYXN0VHJhbnNhY3Rpb25EZXNjKHR4blJvdzogVHJhbnNhY3Rpb25zVHIsIGxhc3RUeG46IFNjcmFwZWRUcmFuc2FjdGlvbik6IFNjcmFwZWRUcmFuc2FjdGlvbiB7XG4gIGxhc3RUeG4uZGVzY3JpcHRpb24gPSBgJHtsYXN0VHhuLmRlc2NyaXB0aW9ufSAke3R4blJvdy5pbm5lclRkc1swXX1gO1xuICByZXR1cm4gbGFzdFR4bjtcbn1cblxuZnVuY3Rpb24gaGFuZGxlVHJhbnNhY3Rpb25Sb3coXG4gIHR4bnM6IFNjcmFwZWRUcmFuc2FjdGlvbltdLFxuICB0eG5zVGFibGVIZWFkZXJzOiBUcmFuc2FjdGlvblRhYmxlSGVhZGVycyxcbiAgdHhuUm93OiBUcmFuc2FjdGlvbnNUcixcbiAgdHhuVHlwZTogVHJhbnNhY3Rpb25TdGF0dXNlcyxcbikge1xuICBpZiAoaXNFeHBhbmRlZERlc2NSb3codHhuUm93KSkge1xuICAgIGNvbnN0IGxhc3RUcmFuc2FjdGlvbiA9IHR4bnMucG9wKCk7XG4gICAgaWYgKGxhc3RUcmFuc2FjdGlvbikge1xuICAgICAgdHhucy5wdXNoKGVkaXRMYXN0VHJhbnNhY3Rpb25EZXNjKHR4blJvdywgbGFzdFRyYW5zYWN0aW9uKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignaW50ZXJuYWwgdW5pb24tYmFuayBlcnJvcicpO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICB0eG5zLnB1c2goZXh0cmFjdFRyYW5zYWN0aW9uRGV0YWlscyh0eG5Sb3csIHR4bnNUYWJsZUhlYWRlcnMsIHR4blR5cGUpKTtcbiAgfVxufVxuXG5hc3luYyBmdW5jdGlvbiBnZXRUcmFuc2FjdGlvbnNUYWJsZUhlYWRlcnMocGFnZTogUGFnZSwgdGFibGVUeXBlSWQ6IHN0cmluZykge1xuICBjb25zdCBoZWFkZXJzTWFwOiBSZWNvcmQ8c3RyaW5nLCBhbnk+ID0gW107XG4gIGNvbnN0IGhlYWRlcnNPYmpzID0gYXdhaXQgcGFnZUV2YWxBbGwocGFnZSwgYCNXb3JrU3BhY2VCb3ggIyR7dGFibGVUeXBlSWR9IHRyW2NsYXNzPSdoZWFkZXInXSB0aGAsIG51bGwsIHRocyA9PiB7XG4gICAgcmV0dXJuIHRocy5tYXAoKHRoLCBpbmRleCkgPT4gKHtcbiAgICAgIHRleHQ6ICh0aCBhcyBIVE1MRWxlbWVudCkuaW5uZXJUZXh0LnRyaW0oKSxcbiAgICAgIGluZGV4LFxuICAgIH0pKTtcbiAgfSk7XG5cbiAgZm9yIChjb25zdCBoZWFkZXJPYmogb2YgaGVhZGVyc09ianMpIHtcbiAgICBoZWFkZXJzTWFwW2hlYWRlck9iai50ZXh0XSA9IGhlYWRlck9iai5pbmRleDtcbiAgfVxuICByZXR1cm4gaGVhZGVyc01hcDtcbn1cblxuYXN5bmMgZnVuY3Rpb24gZXh0cmFjdFRyYW5zYWN0aW9uc0Zyb21UYWJsZShcbiAgcGFnZTogUGFnZSxcbiAgdGFibGVUeXBlSWQ6IHN0cmluZyxcbiAgdHhuVHlwZTogVHJhbnNhY3Rpb25TdGF0dXNlcyxcbik6IFByb21pc2U8U2NyYXBlZFRyYW5zYWN0aW9uW10+IHtcbiAgY29uc3QgdHhuczogU2NyYXBlZFRyYW5zYWN0aW9uW10gPSBbXTtcbiAgY29uc3QgdHJhbnNhY3Rpb25zVGFibGVIZWFkZXJzID0gYXdhaXQgZ2V0VHJhbnNhY3Rpb25zVGFibGVIZWFkZXJzKHBhZ2UsIHRhYmxlVHlwZUlkKTtcblxuICBjb25zdCB0cmFuc2FjdGlvbnNSb3dzID0gYXdhaXQgcGFnZUV2YWxBbGw8VHJhbnNhY3Rpb25zVHJbXT4oXG4gICAgcGFnZSxcbiAgICBgI1dvcmtTcGFjZUJveCAjJHt0YWJsZVR5cGVJZH0gdHJbY2xhc3NdOm5vdChbY2xhc3M9J2hlYWRlciddKWAsXG4gICAgW10sXG4gICAgdHJzID0+IHtcbiAgICAgIHJldHVybiAodHJzIGFzIEhUTUxFbGVtZW50W10pLm1hcCh0ciA9PiAoe1xuICAgICAgICBpZDogdHIuZ2V0QXR0cmlidXRlKCdpZCcpIHx8ICcnLFxuICAgICAgICBpbm5lclRkczogQXJyYXkuZnJvbSh0ci5nZXRFbGVtZW50c0J5VGFnTmFtZSgndGQnKSkubWFwKHRkID0+ICh0ZCBhcyBIVE1MRWxlbWVudCkuaW5uZXJUZXh0KSxcbiAgICAgIH0pKTtcbiAgICB9LFxuICApO1xuXG4gIGZvciAoY29uc3QgdHhuUm93IG9mIHRyYW5zYWN0aW9uc1Jvd3MpIHtcbiAgICBoYW5kbGVUcmFuc2FjdGlvblJvdyh0eG5zLCB0cmFuc2FjdGlvbnNUYWJsZUhlYWRlcnMsIHR4blJvdywgdHhuVHlwZSk7XG4gIH1cbiAgcmV0dXJuIHR4bnM7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGlzTm9UcmFuc2FjdGlvbkluRGF0ZVJhbmdlRXJyb3IocGFnZTogUGFnZSkge1xuICBjb25zdCBoYXNFcnJvckluZm9FbGVtZW50ID0gYXdhaXQgZWxlbWVudFByZXNlbnRPblBhZ2UocGFnZSwgYC4ke0VSUk9SX01FU1NBR0VfQ0xBU1N9YCk7XG4gIGlmIChoYXNFcnJvckluZm9FbGVtZW50KSB7XG4gICAgY29uc3QgZXJyb3JUZXh0ID0gYXdhaXQgcGFnZS4kZXZhbChgLiR7RVJST1JfTUVTU0FHRV9DTEFTU31gLCBlcnJvckVsZW1lbnQgPT4ge1xuICAgICAgcmV0dXJuIChlcnJvckVsZW1lbnQgYXMgSFRNTEVsZW1lbnQpLmlubmVyVGV4dDtcbiAgICB9KTtcbiAgICByZXR1cm4gZXJyb3JUZXh0LnRyaW0oKSA9PT0gTk9fVFJBTlNBQ1RJT05fSU5fREFURV9SQU5HRV9URVhUO1xuICB9XG4gIHJldHVybiBmYWxzZTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gY2hvb3NlQWNjb3VudChwYWdlOiBQYWdlLCBhY2NvdW50SWQ6IHN0cmluZykge1xuICBjb25zdCBoYXNEcm9wRG93bkxpc3QgPSBhd2FpdCBlbGVtZW50UHJlc2VudE9uUGFnZShwYWdlLCBBQ0NPVU5UU19EUk9QRE9XTl9TRUxFQ1RPUik7XG4gIGlmIChoYXNEcm9wRG93bkxpc3QpIHtcbiAgICBhd2FpdCBkcm9wZG93blNlbGVjdChwYWdlLCBBQ0NPVU5UU19EUk9QRE9XTl9TRUxFQ1RPUiwgYWNjb3VudElkKTtcbiAgfVxufVxuXG5hc3luYyBmdW5jdGlvbiBzZWFyY2hCeURhdGVzKHBhZ2U6IFBhZ2UsIHN0YXJ0RGF0ZTogTW9tZW50KSB7XG4gIGF3YWl0IGRyb3Bkb3duU2VsZWN0KHBhZ2UsICdzZWxlY3QjZGRsVHJhbnNhY3Rpb25QZXJpb2QnLCAnMDA0Jyk7XG4gIGF3YWl0IHdhaXRVbnRpbEVsZW1lbnRGb3VuZChwYWdlLCAnc2VsZWN0I2RkbFRyYW5zYWN0aW9uUGVyaW9kJyk7XG4gIGF3YWl0IGZpbGxJbnB1dChwYWdlLCAnaW5wdXQjZHRGcm9tRGF0ZV90ZXh0Qm94Jywgc3RhcnREYXRlLmZvcm1hdChEQVRFX0ZPUk1BVCkpO1xuICBhd2FpdCBjbGlja0J1dHRvbihwYWdlLCAnaW5wdXQjYnRuRGlzcGxheURhdGVzJyk7XG4gIGF3YWl0IHdhaXRGb3JOYXZpZ2F0aW9uKHBhZ2UpO1xufVxuXG5hc3luYyBmdW5jdGlvbiBnZXRBY2NvdW50TnVtYmVyKHBhZ2U6IFBhZ2UpIHtcbiAgY29uc3Qgc2VsZWN0ZWRTbmlmQWNjb3VudCA9IGF3YWl0IHBhZ2UuJGV2YWwoJyNkZGxBY2NvdW50c19tX2RkbCBvcHRpb25bc2VsZWN0ZWQ9XCJzZWxlY3RlZFwiXScsIG9wdGlvbiA9PiB7XG4gICAgcmV0dXJuIChvcHRpb24gYXMgSFRNTEVsZW1lbnQpLmlubmVyVGV4dDtcbiAgfSk7XG5cbiAgcmV0dXJuIHNlbGVjdGVkU25pZkFjY291bnQucmVwbGFjZSgnLycsICdfJyk7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGV4cGFuZFRyYW5zYWN0aW9uc1RhYmxlKHBhZ2U6IFBhZ2UpIHtcbiAgY29uc3QgaGFzRXhwYW5kQWxsQnV0dG9uID0gYXdhaXQgZWxlbWVudFByZXNlbnRPblBhZ2UocGFnZSwgXCJhW2lkKj0nbG5rQ3RsRXhwYW5kQWxsJ11cIik7XG4gIGlmIChoYXNFeHBhbmRBbGxCdXR0b24pIHtcbiAgICBhd2FpdCBjbGlja0J1dHRvbihwYWdlLCBcImFbaWQqPSdsbmtDdGxFeHBhbmRBbGwnXVwiKTtcbiAgfVxufVxuXG5hc3luYyBmdW5jdGlvbiBzY3JhcGVUcmFuc2FjdGlvbnNGcm9tVGFibGUocGFnZTogUGFnZSk6IFByb21pc2U8VHJhbnNhY3Rpb25bXT4ge1xuICBjb25zdCBwZW5kaW5nVHhucyA9IGF3YWl0IGV4dHJhY3RUcmFuc2FjdGlvbnNGcm9tVGFibGUoXG4gICAgcGFnZSxcbiAgICBQRU5ESU5HX1RSQU5TQUNUSU9OU19UQUJMRV9JRCxcbiAgICBUcmFuc2FjdGlvblN0YXR1c2VzLlBlbmRpbmcsXG4gICk7XG4gIGNvbnN0IGNvbXBsZXRlZFR4bnMgPSBhd2FpdCBleHRyYWN0VHJhbnNhY3Rpb25zRnJvbVRhYmxlKFxuICAgIHBhZ2UsXG4gICAgQ09NUExFVEVEX1RSQU5TQUNUSU9OU19UQUJMRV9JRCxcbiAgICBUcmFuc2FjdGlvblN0YXR1c2VzLkNvbXBsZXRlZCxcbiAgKTtcbiAgY29uc3QgdHhucyA9IFsuLi5wZW5kaW5nVHhucywgLi4uY29tcGxldGVkVHhuc107XG4gIHJldHVybiBjb252ZXJ0VHJhbnNhY3Rpb25zKHR4bnMpO1xufVxuXG5hc3luYyBmdW5jdGlvbiBnZXRBY2NvdW50VHJhbnNhY3Rpb25zKHBhZ2U6IFBhZ2UpOiBQcm9taXNlPFRyYW5zYWN0aW9uW10+IHtcbiAgYXdhaXQgUHJvbWlzZS5yYWNlKFtcbiAgICB3YWl0VW50aWxFbGVtZW50Rm91bmQocGFnZSwgYCMke0NPTVBMRVRFRF9UUkFOU0FDVElPTlNfVEFCTEVfSUR9YCwgZmFsc2UpLFxuICAgIHdhaXRVbnRpbEVsZW1lbnRGb3VuZChwYWdlLCBgLiR7RVJST1JfTUVTU0FHRV9DTEFTU31gLCBmYWxzZSksXG4gIF0pO1xuXG4gIGNvbnN0IG5vVHJhbnNhY3Rpb25JblJhbmdlRXJyb3IgPSBhd2FpdCBpc05vVHJhbnNhY3Rpb25JbkRhdGVSYW5nZUVycm9yKHBhZ2UpO1xuICBpZiAobm9UcmFuc2FjdGlvbkluUmFuZ2VFcnJvcikge1xuICAgIHJldHVybiBbXTtcbiAgfVxuXG4gIGF3YWl0IGV4cGFuZFRyYW5zYWN0aW9uc1RhYmxlKHBhZ2UpO1xuICByZXR1cm4gc2NyYXBlVHJhbnNhY3Rpb25zRnJvbVRhYmxlKHBhZ2UpO1xufVxuXG5hc3luYyBmdW5jdGlvbiBmZXRjaEFjY291bnREYXRhKHBhZ2U6IFBhZ2UsIHN0YXJ0RGF0ZTogTW9tZW50LCBhY2NvdW50SWQ6IHN0cmluZyk6IFByb21pc2U8VHJhbnNhY3Rpb25zQWNjb3VudD4ge1xuICBhd2FpdCBjaG9vc2VBY2NvdW50KHBhZ2UsIGFjY291bnRJZCk7XG4gIGF3YWl0IHNlYXJjaEJ5RGF0ZXMocGFnZSwgc3RhcnREYXRlKTtcbiAgY29uc3QgYWNjb3VudE51bWJlciA9IGF3YWl0IGdldEFjY291bnROdW1iZXIocGFnZSk7XG4gIGNvbnN0IHR4bnMgPSBhd2FpdCBnZXRBY2NvdW50VHJhbnNhY3Rpb25zKHBhZ2UpO1xuICByZXR1cm4ge1xuICAgIGFjY291bnROdW1iZXIsXG4gICAgdHhucyxcbiAgfTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gZmV0Y2hBY2NvdW50cyhwYWdlOiBQYWdlLCBzdGFydERhdGU6IE1vbWVudCkge1xuICBjb25zdCBhY2NvdW50czogVHJhbnNhY3Rpb25zQWNjb3VudFtdID0gW107XG4gIGNvbnN0IGFjY291bnRzTGlzdCA9IGF3YWl0IGRyb3Bkb3duRWxlbWVudHMocGFnZSwgQUNDT1VOVFNfRFJPUERPV05fU0VMRUNUT1IpO1xuICBmb3IgKGNvbnN0IGFjY291bnQgb2YgYWNjb3VudHNMaXN0KSB7XG4gICAgaWYgKGFjY291bnQudmFsdWUgIT09ICctMScpIHtcbiAgICAgIC8vIFNraXAgXCJBbGwgYWNjb3VudHNcIiBvcHRpb25cbiAgICAgIGNvbnN0IGFjY291bnREYXRhID0gYXdhaXQgZmV0Y2hBY2NvdW50RGF0YShwYWdlLCBzdGFydERhdGUsIGFjY291bnQudmFsdWUpO1xuICAgICAgYWNjb3VudHMucHVzaChhY2NvdW50RGF0YSk7XG4gICAgfVxuICB9XG4gIHJldHVybiBhY2NvdW50cztcbn1cblxuYXN5bmMgZnVuY3Rpb24gd2FpdEZvclBvc3RMb2dpbihwYWdlOiBQYWdlKSB7XG4gIHJldHVybiBQcm9taXNlLnJhY2UoW3dhaXRVbnRpbEVsZW1lbnRGb3VuZChwYWdlLCAnI3NpZ25vZmYnLCB0cnVlKSwgd2FpdFVudGlsRWxlbWVudEZvdW5kKHBhZ2UsICcjcmVzdG9yZScsIHRydWUpXSk7XG59XG5cbnR5cGUgU2NyYXBlclNwZWNpZmljQ3JlZGVudGlhbHMgPSB7IHVzZXJuYW1lOiBzdHJpbmc7IHBhc3N3b3JkOiBzdHJpbmcgfTtcblxuY2xhc3MgVW5pb25CYW5rU2NyYXBlciBleHRlbmRzIEJhc2VTY3JhcGVyV2l0aEJyb3dzZXI8U2NyYXBlclNwZWNpZmljQ3JlZGVudGlhbHM+IHtcbiAgZ2V0TG9naW5PcHRpb25zKGNyZWRlbnRpYWxzOiBTY3JhcGVyU3BlY2lmaWNDcmVkZW50aWFscykge1xuICAgIHJldHVybiB7XG4gICAgICBsb2dpblVybDogYCR7QkFTRV9VUkx9YCxcbiAgICAgIGZpZWxkczogY3JlYXRlTG9naW5GaWVsZHMoY3JlZGVudGlhbHMpLFxuICAgICAgc3VibWl0QnV0dG9uU2VsZWN0b3I6ICcjZW50ZXInLFxuICAgICAgcG9zdEFjdGlvbjogYXN5bmMgKCkgPT4gd2FpdEZvclBvc3RMb2dpbih0aGlzLnBhZ2UpLFxuICAgICAgcG9zc2libGVSZXN1bHRzOiBnZXRQb3NzaWJsZUxvZ2luUmVzdWx0cygpLFxuICAgIH07XG4gIH1cblxuICBhc3luYyBmZXRjaERhdGEoKSB7XG4gICAgY29uc3QgZGVmYXVsdFN0YXJ0TW9tZW50ID0gbW9tZW50KCkuc3VidHJhY3QoMSwgJ3llYXJzJykuYWRkKDEsICdkYXknKTtcbiAgICBjb25zdCBzdGFydERhdGUgPSB0aGlzLm9wdGlvbnMuc3RhcnREYXRlIHx8IGRlZmF1bHRTdGFydE1vbWVudC50b0RhdGUoKTtcbiAgICBjb25zdCBzdGFydE1vbWVudCA9IG1vbWVudC5tYXgoZGVmYXVsdFN0YXJ0TW9tZW50LCBtb21lbnQoc3RhcnREYXRlKSk7XG5cbiAgICBhd2FpdCB0aGlzLm5hdmlnYXRlVG8oVFJBTlNBQ1RJT05TX1VSTCk7XG5cbiAgICBjb25zdCBhY2NvdW50cyA9IGF3YWl0IGZldGNoQWNjb3VudHModGhpcy5wYWdlLCBzdGFydE1vbWVudCk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgc3VjY2VzczogdHJ1ZSxcbiAgICAgIGFjY291bnRzLFxuICAgIH07XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgVW5pb25CYW5rU2NyYXBlcjtcbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQUEsSUFBQUEsT0FBQSxHQUFBQyxzQkFBQSxDQUFBQyxPQUFBO0FBRUEsSUFBQUMsVUFBQSxHQUFBRCxPQUFBO0FBQ0EsSUFBQUUscUJBQUEsR0FBQUYsT0FBQTtBQVNBLElBQUFHLFdBQUEsR0FBQUgsT0FBQTtBQUNBLElBQUFJLGFBQUEsR0FBQUosT0FBQTtBQUNBLElBQUFLLHVCQUFBLEdBQUFMLE9BQUE7QUFBOEcsU0FBQUQsdUJBQUFPLENBQUEsV0FBQUEsQ0FBQSxJQUFBQSxDQUFBLENBQUFDLFVBQUEsR0FBQUQsQ0FBQSxLQUFBRSxPQUFBLEVBQUFGLENBQUE7QUFFOUcsTUFBTUcsUUFBUSxHQUFHLDRCQUE0QjtBQUM3QyxNQUFNQyxnQkFBZ0IsR0FBRyxHQUFHRCxRQUFRLDRDQUE0QztBQUNoRixNQUFNRSxXQUFXLEdBQUcsVUFBVTtBQUM5QixNQUFNQyxpQ0FBaUMsR0FBRyw4Q0FBOEM7QUFDeEYsTUFBTUMsV0FBVyxHQUFHLE9B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