israeli-bank-scrapers
Version:
Provide scrapers for all major Israeli banks and credit card companies
290 lines • 55.7 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _moment = _interopRequireDefault(require("moment"));
var _debug = require("../helpers/debug");
var _elementsInteractions = require("../helpers/elements-interactions");
var _fetch = require("../helpers/fetch");
var _navigation = require("../helpers/navigation");
var _storage = require("../helpers/storage");
var _transactions = require("../helpers/transactions");
var _waiting = require("../helpers/waiting");
var _transactions2 = require("../transactions");
var _baseScraperWithBrowser = require("./base-scraper-with-browser");
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
const LOGIN_URL = 'https://www.cal-online.co.il/';
const TRANSACTIONS_REQUEST_ENDPOINT = 'https://api.cal-online.co.il/Transactions/api/transactionsDetails/getCardTransactionsDetails';
const PENDING_TRANSACTIONS_REQUEST_ENDPOINT = 'https://api.cal-online.co.il/Transactions/api/approvals/getClearanceRequests';
const SSO_AUTHORIZATION_REQUEST_ENDPOINT = 'https://connect.cal-online.co.il/col-rest/calconnect/authentication/SSO';
const InvalidPasswordMessage = 'שם המשתמש או הסיסמה שהוזנו שגויים';
const debug = (0, _debug.getDebug)('visa-cal');
var TrnTypeCode = /*#__PURE__*/function (TrnTypeCode) {
TrnTypeCode["regular"] = "5";
TrnTypeCode["credit"] = "6";
TrnTypeCode["installments"] = "8";
TrnTypeCode["standingOrder"] = "9";
return TrnTypeCode;
}(TrnTypeCode || {});
function isPending(transaction) {
return transaction.debCrdDate === undefined; // an arbitrary field that only appears in a completed transaction
}
function isCardTransactionDetails(result) {
return result.result !== undefined;
}
function isCardPendingTransactionDetails(result) {
return result.result !== undefined;
}
async function getLoginFrame(page) {
let frame = null;
debug('wait until login frame found');
await (0, _waiting.waitUntil)(() => {
frame = page.frames().find(f => f.url().includes('connect')) || null;
return Promise.resolve(!!frame);
}, 'wait for iframe with login form', 10000, 1000);
if (!frame) {
debug('failed to find login frame for 10 seconds');
throw new Error('failed to extract login iframe');
}
return frame;
}
async function hasInvalidPasswordError(page) {
const frame = await getLoginFrame(page);
const errorFound = await (0, _elementsInteractions.elementPresentOnPage)(frame, 'div.general-error > div');
const errorMessage = errorFound ? await (0, _elementsInteractions.pageEval)(frame, 'div.general-error > div', '', item => {
return item.innerText;
}) : '';
return errorMessage === InvalidPasswordMessage;
}
async function hasChangePasswordForm(page) {
const frame = await getLoginFrame(page);
const errorFound = await (0, _elementsInteractions.elementPresentOnPage)(frame, '.change-password-subtitle');
return errorFound;
}
function getPossibleLoginResults() {
debug('return possible login results');
const urls = {
[_baseScraperWithBrowser.LoginResults.Success]: [/dashboard/i],
[_baseScraperWithBrowser.LoginResults.InvalidPassword]: [async options => {
const page = options?.page;
if (!page) {
return false;
}
return hasInvalidPasswordError(page);
}],
// [LoginResults.AccountBlocked]: [], // TODO add when reaching this scenario
[_baseScraperWithBrowser.LoginResults.ChangePassword]: [async options => {
const page = options?.page;
if (!page) {
return false;
}
return hasChangePasswordForm(page);
}]
};
return urls;
}
function createLoginFields(credentials) {
debug('create login fields for username and password');
return [{
selector: '[formcontrolname="userName"]',
value: credentials.username
}, {
selector: '[formcontrolname="password"]',
value: credentials.password
}];
}
function convertParsedDataToTransactions(data, pendingData) {
const pendingTransactions = pendingData?.result ? pendingData.result.cardsList.flatMap(card => card.authDetalisList) : [];
const bankAccounts = data.flatMap(monthData => monthData.result.bankAccounts);
const regularDebitDays = bankAccounts.flatMap(accounts => accounts.debitDates);
const immediateDebitDays = bankAccounts.flatMap(accounts => accounts.immidiateDebits.debitDays);
const completedTransactions = [...regularDebitDays, ...immediateDebitDays].flatMap(debitDate => debitDate.transactions);
const all = [...pendingTransactions, ...completedTransactions];
return all.map(transaction => {
const numOfPayments = isPending(transaction) ? transaction.numberOfPayments : transaction.numOfPayments;
const installments = numOfPayments ? {
number: isPending(transaction) ? 1 : transaction.curPaymentNum,
total: numOfPayments
} : undefined;
const date = (0, _moment.default)(transaction.trnPurchaseDate);
let chargedAmount = isPending(transaction) ? transaction.trnAmt * -1 : transaction.amtBeforeConvAndIndex * -1;
let originalAmount = transaction.trnAmt * -1;
if (transaction.trnTypeCode === TrnTypeCode.credit) {
chargedAmount = isPending(transaction) ? transaction.trnAmt : transaction.amtBeforeConvAndIndex;
originalAmount = transaction.trnAmt;
}
const result = {
identifier: !isPending(transaction) ? transaction.trnIntId : undefined,
type: [TrnTypeCode.regular, TrnTypeCode.standingOrder].includes(transaction.trnTypeCode) ? _transactions2.TransactionTypes.Normal : _transactions2.TransactionTypes.Installments,
status: isPending(transaction) ? _transactions2.TransactionStatuses.Pending : _transactions2.TransactionStatuses.Completed,
date: installments ? date.add(installments.number - 1, 'month').toISOString() : date.toISOString(),
processedDate: isPending(transaction) ? date.toISOString() : new Date(transaction.debCrdDate).toISOString(),
originalAmount,
originalCurrency: transaction.trnCurrencySymbol,
chargedAmount,
chargedCurrency: !isPending(transaction) ? transaction.debCrdCurrencySymbol : undefined,
description: transaction.merchantName,
memo: transaction.transTypeCommentDetails.toString(),
category: transaction.branchCodeDesc
};
if (installments) {
result.installments = installments;
}
return result;
});
}
class VisaCalScraper extends _baseScraperWithBrowser.BaseScraperWithBrowser {
authorization = undefined;
openLoginPopup = async () => {
debug('open login popup, wait until login button available');
await (0, _elementsInteractions.waitUntilElementFound)(this.page, '#ccLoginDesktopBtn', true);
debug('click on the login button');
await (0, _elementsInteractions.clickButton)(this.page, '#ccLoginDesktopBtn');
debug('get the frame that holds the login');
const frame = await getLoginFrame(this.page);
debug('wait until the password login tab header is available');
await (0, _elementsInteractions.waitUntilElementFound)(frame, '#regular-login');
debug('navigate to the password login tab');
await (0, _elementsInteractions.clickButton)(frame, '#regular-login');
debug('wait until the password login tab is active');
await (0, _elementsInteractions.waitUntilElementFound)(frame, 'regular-login');
return frame;
};
async getCards() {
const initData = await (0, _waiting.waitUntil)(() => (0, _storage.getFromSessionStorage)(this.page, 'init'), 'get init data in session storage', 10000, 1000);
if (!initData) {
throw new Error("could not find 'init' data in session storage");
}
return initData?.result.cards.map(({
cardUniqueId,
last4Digits
}) => ({
cardUniqueId,
last4Digits
}));
}
async getAuthorizationHeader() {
if (!this.authorization) {
const authModule = await (0, _storage.getFromSessionStorage)(this.page, 'auth-module');
if (authModule?.auth.calConnectToken) {
return `CALAuthScheme ${authModule.auth.calConnectToken}`;
}
throw new Error('could not retrieve authorization header');
}
return this.authorization;
}
async getXSiteId() {
/*
I don't know if the constant below will change in the feature.
If so, use the next code:
return this.page.evaluate(() => new Ut().xSiteId);
To get the classname search for 'xSiteId' in the page source
class Ut {
constructor(_e, on, yn) {
this.store = _e,
this.config = on,
this.eventBusService = yn,
this.xSiteId = "09031987-273E-2311-906C-8AF85B17C8D9",
*/
return Promise.resolve('09031987-273E-2311-906C-8AF85B17C8D9');
}
getLoginOptions(credentials) {
this.authRequestPromise = this.page.waitForRequest(SSO_AUTHORIZATION_REQUEST_ENDPOINT, {
timeout: 10_000
}).catch(e => {
debug('error while waiting for the token request', e);
return undefined;
});
return {
loginUrl: `${LOGIN_URL}`,
fields: createLoginFields(credentials),
submitButtonSelector: 'button[type="submit"]',
possibleResults: getPossibleLoginResults(),
checkReadiness: async () => (0, _elementsInteractions.waitUntilElementFound)(this.page, '#ccLoginDesktopBtn'),
preAction: this.openLoginPopup,
postAction: async () => {
try {
await (0, _navigation.waitForNavigation)(this.page);
const currentUrl = await (0, _navigation.getCurrentUrl)(this.page);
if (currentUrl.endsWith('site-tutorial')) {
await (0, _elementsInteractions.clickButton)(this.page, 'button.btn-close');
}
const request = await this.authRequestPromise;
this.authorization = request?.headers()?.authorization;
} catch (e) {
const currentUrl = await (0, _navigation.getCurrentUrl)(this.page);
if (currentUrl.endsWith('dashboard')) return;
const requiresChangePassword = await hasChangePasswordForm(this.page);
if (requiresChangePassword) return;
throw e;
}
},
userAgent: 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36'
};
}
async fetchData() {
const defaultStartMoment = (0, _moment.default)().subtract(1, 'years').subtract(6, 'months').add(1, 'day');
const startDate = this.options.startDate || defaultStartMoment.toDate();
const startMoment = _moment.default.max(defaultStartMoment, (0, _moment.default)(startDate));
debug(`fetch transactions starting ${startMoment.format()}`);
const Authorization = await this.getAuthorizationHeader();
const cards = await this.getCards();
const xSiteId = await this.getXSiteId();
const futureMonthsToScrape = this.options.futureMonthsToScrape ?? 1;
const accounts = await Promise.all(cards.map(async card => {
const finalMonthToFetchMoment = (0, _moment.default)().add(futureMonthsToScrape, 'month');
const months = finalMonthToFetchMoment.diff(startMoment, 'months');
const allMonthsData = [];
debug(`fetch pending transactions for card ${card.cardUniqueId}`);
let pendingData = await (0, _fetch.fetchPostWithinPage)(this.page, PENDING_TRANSACTIONS_REQUEST_ENDPOINT, {
cardUniqueIDArray: [card.cardUniqueId]
}, {
Authorization,
'X-Site-Id': xSiteId,
'Content-Type': 'application/json'
});
debug(`fetch completed transactions for card ${card.cardUniqueId}`);
for (let i = 0; i <= months; i += 1) {
const month = finalMonthToFetchMoment.clone().subtract(i, 'months');
const monthData = await (0, _fetch.fetchPostWithinPage)(this.page, TRANSACTIONS_REQUEST_ENDPOINT, {
cardUniqueId: card.cardUniqueId,
month: month.format('M'),
year: month.format('YYYY')
}, {
Authorization,
'X-Site-Id': xSiteId,
'Content-Type': 'application/json'
});
if (monthData?.statusCode !== 1) throw new Error(`failed to fetch transactions for card ${card.last4Digits}. Message: ${monthData?.title || ''}`);
if (!isCardTransactionDetails(monthData)) {
throw new Error('monthData is not of type CardTransactionDetails');
}
allMonthsData.push(monthData);
}
if (pendingData?.statusCode !== 1 && pendingData?.statusCode !== 96) {
debug(`failed to fetch pending transactions for card ${card.last4Digits}. Message: ${pendingData?.title || ''}`);
pendingData = null;
} else if (!isCardPendingTransactionDetails(pendingData)) {
debug('pendingData is not of type CardTransactionDetails');
pendingData = null;
}
const transactions = convertParsedDataToTransactions(allMonthsData, pendingData);
debug('filer out old transactions');
const txns = this.options.outputData?.enableTransactionsFilterByDate ?? true ? (0, _transactions.filterOldTransactions)(transactions, (0, _moment.default)(startDate), this.options.combineInstallments || false) : transactions;
return {
txns,
accountNumber: card.last4Digits
};
}));
debug('return the scraped accounts');
debug(JSON.stringify(accounts, null, 2));
return {
success: true,
accounts
};
}
}
var _default = exports.default = VisaCalScraper;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfbW9tZW50IiwiX2ludGVyb3BSZXF1aXJlRGVmYXVsdCIsInJlcXVpcmUiLCJfZGVidWciLCJfZWxlbWVudHNJbnRlcmFjdGlvbnMiLCJfZmV0Y2giLCJfbmF2aWdhdGlvbiIsIl9zdG9yYWdlIiwiX3RyYW5zYWN0aW9ucyIsIl93YWl0aW5nIiwiX3RyYW5zYWN0aW9uczIiLCJfYmFzZVNjcmFwZXJXaXRoQnJvd3NlciIsImUiLCJfX2VzTW9kdWxlIiwiZGVmYXVsdCIsIkxPR0lOX1VSTCIsIlRSQU5TQUNUSU9OU19SRVFVRVNUX0VORFBPSU5UIiwiUEVORElOR19UUkFOU0FDVElPTlNfUkVRVUVTVF9FTkRQT0lOVCIsIlNTT19BVVRIT1JJWkFUSU9OX1JFUVVFU1RfRU5EUE9JTlQiLCJJbnZhbGlkUGFzc3dvcmRNZXNzYWdlIiwiZGVidWciLCJnZXREZWJ1ZyIsIlRyblR5cGVDb2RlIiwiaXNQZW5kaW5nIiwidHJhbnNhY3Rpb24iLCJkZWJDcmREYXRlIiwidW5kZWZpbmVkIiwiaXNDYXJkVHJhbnNhY3Rpb25EZXRhaWxzIiwicmVzdWx0IiwiaXNDYXJkUGVuZGluZ1RyYW5zYWN0aW9uRGV0YWlscyIsImdldExvZ2luRnJhbWUiLCJwYWdlIiwiZnJhbWUiLCJ3YWl0VW50aWwiLCJmcmFtZXMiLCJmaW5kIiwiZiIsInVybCIsImluY2x1ZGVzIiwiUHJvbWlzZSIsInJlc29sdmUiLCJFcnJvciIsImhhc0ludmFsaWRQYXNzd29yZEVycm9yIiwiZXJyb3JGb3VuZCIsImVsZW1lbnRQcmVzZW50T25QYWdlIiwiZXJyb3JNZXNzYWdlIiwicGFnZUV2YWwiLCJpdGVtIiwiaW5uZXJUZXh0IiwiaGFzQ2hhbmdlUGFzc3dvcmRGb3JtIiwiZ2V0UG9zc2libGVMb2dpblJlc3VsdHMiLCJ1cmxzIiwiTG9naW5SZXN1bHRzIiwiU3VjY2VzcyIsIkludmFsaWRQYXNzd29yZCIsIm9wdGlvbnMiLCJDaGFuZ2VQYXNzd29yZCIsImNyZWF0ZUxvZ2luRmllbGRzIiwiY3JlZGVudGlhbHMiLCJzZWxlY3RvciIsInZhbHVlIiwidXNlcm5hbWUiLCJwYXNzd29yZCIsImNvbnZlcnRQYXJzZWREYXRhVG9UcmFuc2FjdGlvbnMiLCJkYXRhIiwicGVuZGluZ0RhdGEiLCJwZW5kaW5nVHJhbnNhY3Rpb25zIiwiY2FyZHNMaXN0IiwiZmxhdE1hcCIsImNhcmQiLCJhdXRoRGV0YWxpc0xpc3QiLCJiYW5rQWNjb3VudHMiLCJtb250aERhdGEiLCJyZWd1bGFyRGViaXREYXlzIiwiYWNjb3VudHMiLCJkZWJpdERhdGVzIiwiaW1tZWRpYXRlRGViaXREYXlzIiwiaW1taWRpYXRlRGViaXRzIiwiZGViaXREYXlzIiwiY29tcGxldGVkVHJhbnNhY3Rpb25zIiwiZGViaXREYXRlIiwidHJhbnNhY3Rpb25zIiwiYWxsIiwibWFwIiwibnVtT2ZQYXltZW50cyIsIm51bWJlck9mUGF5bWVudHMiLCJpbnN0YWxsbWVudHMiLCJudW1iZXIiLCJjdXJQYXltZW50TnVtIiwidG90YWwiLCJkYXRlIiwibW9tZW50IiwidHJuUHVyY2hhc2VEYXRlIiwiY2hhcmdlZEFtb3VudCIsInRybkFtdCIsImFtdEJlZm9yZUNvbnZBbmRJbmRleCIsIm9yaWdpbmFsQW1vdW50IiwidHJuVHlwZUNvZGUiLCJjcmVkaXQiLCJpZGVudGlmaWVyIiwidHJuSW50SWQiLCJ0eXBlIiwicmVndWxhciIsInN0YW5kaW5nT3JkZXIiLCJUcmFuc2FjdGlvblR5cGVzIiwiTm9ybWFsIiwiSW5zdGFsbG1lbnRzIiwic3RhdHVzIiwiVHJhbnNhY3Rpb25TdGF0dXNlcyIsIlBlbmRpbmciLCJDb21wbGV0ZWQiLCJhZGQiLCJ0b0lTT1N0cmluZyIsInByb2Nlc3NlZERhdGUiLCJEYXRlIiwib3JpZ2luYWxDdXJyZW5jeSIsInRybkN1cnJlbmN5U3ltYm9sIiwiY2hhcmdlZEN1cnJlbmN5IiwiZGViQ3JkQ3VycmVuY3lTeW1ib2wiLCJkZXNjcmlwdGlvbiIsIm1lcmNoYW50TmFtZSIsIm1lbW8iLCJ0cmFuc1R5cGVDb21tZW50RGV0YWlscyIsInRvU3RyaW5nIiwiY2F0ZWdvcnkiLCJicmFuY2hDb2RlRGVzYyIsIlZpc2FDYWxTY3JhcGVyIiwiQmFzZVNjcmFwZXJXaXRoQnJvd3NlciIsImF1dGhvcml6YXRpb24iLCJvcGVuTG9naW5Qb3B1cCIsIndhaXRVbnRpbEVsZW1lbnRGb3VuZCIsImNsaWNrQnV0dG9uIiwiZ2V0Q2FyZHMiLCJpbml0RGF0YSIsImdldEZyb21TZXNzaW9uU3RvcmFnZSIsImNhcmRzIiwiY2FyZFVuaXF1ZUlkIiwibGFzdDREaWdpdHMiLCJnZXRBdXRob3JpemF0aW9uSGVhZGVyIiwiYXV0aE1vZHVsZSIsImF1dGgiLCJjYWxDb25uZWN0VG9rZW4iLCJnZXRYU2l0ZUlkIiwiZ2V0TG9naW5PcHRpb25zIiwiYXV0aFJlcXVlc3RQcm9taXNlIiwid2FpdEZvclJlcXVlc3QiLCJ0aW1lb3V0IiwiY2F0Y2giLCJsb2dpblVybCIsImZpZWxkcyIsInN1Ym1pdEJ1dHRvblNlbGVjdG9yIiwicG9zc2libGVSZXN1bHRzIiwiY2hlY2tSZWFkaW5lc3MiLCJwcmVBY3Rpb24iLCJwb3N0QWN0aW9uIiwid2FpdEZvck5hdmlnYXRpb24iLCJjdXJyZW50VXJsIiwiZ2V0Q3VycmVudFVybCIsImVuZHNXaXRoIiwicmVxdWVzdCIsImhlYWRlcnMiLCJyZXF1aXJlc0NoYW5nZVBhc3N3b3JkIiwidXNlckFnZW50IiwiZmV0Y2hEYXRhIiwiZGVmYXVsdFN0YXJ0TW9tZW50Iiwic3VidHJhY3QiLCJzdGFydERhdGUiLCJ0b0RhdGUiLCJzdGFydE1vbWVudCIsIm1heCIsImZvcm1hdCIsIkF1dGhvcml6YXRpb24iLCJ4U2l0ZUlkIiwiZnV0dXJlTW9udGhzVG9TY3JhcGUiLCJmaW5hbE1vbnRoVG9GZXRjaE1vbWVudCIsIm1vbnRocyIsImRpZmYiLCJhbGxNb250aHNEYXRhIiwiZmV0Y2hQb3N0V2l0aGluUGFnZSIsImNhcmRVbmlxdWVJREFycmF5IiwiaSIsIm1vbnRoIiwiY2xvbmUiLCJ5ZWFyIiwic3RhdHVzQ29kZSIsInRpdGxlIiwicHVzaCIsInR4bnMiLCJvdXRwdXREYXRhIiwiZW5hYmxlVHJhbnNhY3Rpb25zRmlsdGVyQnlEYXRlIiwiZmlsdGVyT2xkVHJhbnNhY3Rpb25zIiwiY29tYmluZUluc3RhbGxtZW50cyIsImFjY291bnROdW1iZXIiLCJKU09OIiwic3RyaW5naWZ5Iiwic3VjY2VzcyIsIl9kZWZhdWx0IiwiZXhwb3J0cyJdLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zY3JhcGVycy92aXNhLWNhbC50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgbW9tZW50IGZyb20gJ21vbWVudCc7XG5pbXBvcnQgeyB0eXBlIEhUVFBSZXF1ZXN0LCB0eXBlIEZyYW1lLCB0eXBlIFBhZ2UgfSBmcm9tICdwdXBwZXRlZXInO1xuaW1wb3J0IHsgZ2V0RGVidWcgfSBmcm9tICcuLi9oZWxwZXJzL2RlYnVnJztcbmltcG9ydCB7IGNsaWNrQnV0dG9uLCBlbGVtZW50UHJlc2VudE9uUGFnZSwgcGFnZUV2YWwsIHdhaXRVbnRpbEVsZW1lbnRGb3VuZCB9IGZyb20gJy4uL2hlbHBlcnMvZWxlbWVudHMtaW50ZXJhY3Rpb25zJztcbmltcG9ydCB7IGZldGNoUG9zdFdpdGhpblBhZ2UgfSBmcm9tICcuLi9oZWxwZXJzL2ZldGNoJztcbmltcG9ydCB7IGdldEN1cnJlbnRVcmwsIHdhaXRGb3JOYXZpZ2F0aW9uIH0gZnJvbSAnLi4vaGVscGVycy9uYXZpZ2F0aW9uJztcbmltcG9ydCB7IGdldEZyb21TZXNzaW9uU3RvcmFnZSB9IGZyb20gJy4uL2hlbHBlcnMvc3RvcmFnZSc7XG5pbXBvcnQgeyBmaWx0ZXJPbGRUcmFuc2FjdGlvbnMgfSBmcm9tICcuLi9oZWxwZXJzL3RyYW5zYWN0aW9ucyc7XG5pbXBvcnQgeyB3YWl0VW50aWwgfSBmcm9tICcuLi9oZWxwZXJzL3dhaXRpbmcnO1xuaW1wb3J0IHsgVHJhbnNhY3Rpb25TdGF0dXNlcywgVHJhbnNhY3Rpb25UeXBlcywgdHlwZSBUcmFuc2FjdGlvbiwgdHlwZSBUcmFuc2FjdGlvbnNBY2NvdW50IH0gZnJvbSAnLi4vdHJhbnNhY3Rpb25zJztcbmltcG9ydCB7IEJhc2VTY3JhcGVyV2l0aEJyb3dzZXIsIExvZ2luUmVzdWx0cywgdHlwZSBMb2dpbk9wdGlvbnMgfSBmcm9tICcuL2Jhc2Utc2NyYXBlci13aXRoLWJyb3dzZXInO1xuaW1wb3J0IHsgdHlwZSBTY3JhcGVyU2NyYXBpbmdSZXN1bHQgfSBmcm9tICcuL2ludGVyZmFjZSc7XG5cbmNvbnN0IExPR0lOX1VSTCA9ICdodHRwczovL3d3dy5jYWwtb25saW5lLmNvLmlsLyc7XG5jb25zdCBUUkFOU0FDVElPTlNfUkVRVUVTVF9FTkRQT0lOVCA9XG4gICdodHRwczovL2FwaS5jYWwtb25saW5lLmNvLmlsL1RyYW5zYWN0aW9ucy9hcGkvdHJhbnNhY3Rpb25zRGV0YWlscy9nZXRDYXJkVHJhbnNhY3Rpb25zRGV0YWlscyc7XG5jb25zdCBQRU5ESU5HX1RSQU5TQUNUSU9OU19SRVFVRVNUX0VORFBPSU5UID1cbiAgJ2h0dHBzOi8vYXBpLmNhbC1vbmxpbmUuY28uaWwvVHJhbnNhY3Rpb25zL2FwaS9hcHByb3ZhbHMvZ2V0Q2xlYXJhbmNlUmVxdWVzdHMnO1xuY29uc3QgU1NPX0FVVEhPUklaQVRJT05fUkVRVUVTVF9FTkRQT0lOVCA9ICdodHRwczovL2Nvbm5lY3QuY2FsLW9ubGluZS5jby5pbC9jb2wtcmVzdC9jYWxjb25uZWN0L2F1dGhlbnRpY2F0aW9uL1NTTyc7XG5cbmNvbnN0IEludmFsaWRQYXNzd29yZE1lc3NhZ2UgPSAn16nXnSDXlNee16nXqtee16kg15DXlSDXlNeh15nXodee15Qg16nXlNeV15bXoNeVINep15LXldeZ15nXnSc7XG5cbmNvbnN0IGRlYnVnID0gZ2V0RGVidWcoJ3Zpc2EtY2FsJyk7XG5cbmVudW0gVHJuVHlwZUNvZGUge1xuICByZWd1bGFyID0gJzUnLFxuICBjcmVkaXQgPSAnNicsXG4gIGluc3RhbGxtZW50cyA9ICc4JyxcbiAgc3RhbmRpbmdPcmRlciA9ICc5Jyxcbn1cblxuaW50ZXJmYWNlIFNjcmFwZWRUcmFuc2FjdGlvbiB7XG4gIGFtdEJlZm9yZUNvbnZBbmRJbmRleDogbnVtYmVyO1xuICBicmFuY2hDb2RlRGVzYzogc3RyaW5nO1xuICBjYXNoQWNjTWFuYWdlck5hbWU6IG51bGw7XG4gIGNhc2hBY2NvdW50TWFuYWdlcjogbnVsbDtcbiAgY2FzaEFjY291bnRUcm5BbXQ6IG51bWJlcjtcbiAgY2hhcmdlRXh0ZXJuYWxUb0NhcmRDb21tZW50OiBzdHJpbmc7XG4gIGNvbW1lbnRzOiBbXTtcbiAgY3VyUGF5bWVudE51bTogbnVtYmVyO1xuICBkZWJDcmRDdXJyZW5jeVN5bWJvbDogQ3VycmVuY3lTeW1ib2w7XG4gIGRlYkNyZERhdGU6IHN0cmluZztcbiAgZGViaXRTcHJlYWRJbmQ6IGJvb2xlYW47XG4gIGRpc2NvdW50QW1vdW50OiB1bmtub3duO1xuICBkaXNjb3VudFJlYXNvbjogdW5rbm93bjtcbiAgaW1tZWRpYXRlQ29tbWVudHM6IFtdO1xuICBpc0ltbWVkaWF0ZUNvbW1lbnRJbmQ6IGJvb2xlYW47XG4gIGlzSW1tZWRpYXRlSEhLSW5kOiBib29sZWFuO1xuICBpc01hcmdhcml0YTogYm9vbGVhbjtcbiAgaXNTcHJlYWRQYXltZW5zdEFicm9hZDogYm9vbGVhbjtcbiAgbGlua2VkQ29tbWVudHM6IFtdO1xuICBtZXJjaGFudEFkZHJlc3M6IHN0cmluZztcbiAgbWVyY2hhbnROYW1lOiBzdHJpbmc7XG4gIG1lcmNoYW50UGhvbmVObzogc3RyaW5nO1xuICBudW1PZlBheW1lbnRzOiBudW1iZXI7XG4gIG9uR29pbmdUcmFuc2FjdGlvbnNDb21tZW50OiBzdHJpbmc7XG4gIHJlZnVuZEluZDogYm9vbGVhbjtcbiAgcm91bmRpbmdBbW91bnQ6IHVua25vd247XG4gIHJvdW5kaW5nUmVhc29uOiB1bmtub3duO1xuICB0b2tlbkluZDogMDtcbiAgdG9rZW5OdW1iZXJQYXJ0NDogJyc7XG4gIHRyYW5zQ2FyZFByZXNlbnRJbmQ6IGJvb2xlYW47XG4gIHRyYW5zVHlwZUNvbW1lbnREZXRhaWxzOiBbXTtcbiAgdHJuQW10OiBudW1iZXI7XG4gIHRybkN1cnJlbmN5U3ltYm9sOiBDdXJyZW5jeVN5bWJvbDtcbiAgdHJuRXhhY1dheTogbnVtYmVyO1xuICB0cm5JbnRJZDogc3RyaW5nO1xuICB0cm5OdW1hcmV0b3I6IG51bWJlcjtcbiAgdHJuUHVyY2hhc2VEYXRlOiBzdHJpbmc7XG4gIHRyblR5cGU6IHN0cmluZztcbiAgdHJuVHlwZUNvZGU6IFRyblR5cGVDb2RlO1xuICB3YWxsZXRQcm92aWRlckNvZGU6IDA7XG4gIHdhbGxldFByb3ZpZGVyRGVzYzogJyc7XG4gIGVhcmx5UGF5bWVudEluZDogYm9vbGVhbjtcbn1cbmludGVyZmFjZSBTY3JhcGVkUGVuZGluZ1RyYW5zYWN0aW9uIHtcbiAgbWVyY2hhbnRJRDogc3RyaW5nO1xuICBtZXJjaGFudE5hbWU6IHN0cmluZztcbiAgdHJuUHVyY2hhc2VEYXRlOiBzdHJpbmc7XG4gIHdhbGxldFRyYW5JbmQ6IG51bWJlcjtcbiAgdHJhbnNhY3Rpb25zT3JpZ2luOiBudW1iZXI7XG4gIHRybkFtdDogbnVtYmVyO1xuICB0cGFBcHByb3ZhbEFtb3VudDogdW5rbm93bjtcbiAgdHJuQ3VycmVuY3lTeW1ib2w6IEN1cnJlbmN5U3ltYm9sO1xuICB0cm5UeXBlQ29kZTogVHJuVHlwZUNvZGU7XG4gIHRyblR5cGU6IHN0cmluZztcbiAgYnJhbmNoQ29kZURlc2M6IHN0cmluZztcbiAgdHJhbnNDYXJkUHJlc2VudEluZDogYm9vbGVhbjtcbiAgajVJbmRpY2F0b3I6IHN0cmluZztcbiAgbnVtYmVyT2ZQYXltZW50czogbnVtYmVyO1xuICBmaXJzdFBheW1lbnRBbW91bnQ6IG51bWJlcjtcbiAgdHJhbnNUeXBlQ29tbWVudERldGFpbHM6IFtdO1xufVxuaW50ZXJmYWNlIEluaXRSZXNwb25zZSB7XG4gIHJlc3VsdDoge1xuICAgIGNhcmRzOiB7XG4gICAgICBjYXJkVW5pcXVlSWQ6IHN0cmluZztcbiAgICAgIGxhc3Q0RGlnaXRzOiBzdHJpbmc7XG4gICAgICBba2V5OiBzdHJpbmddOiB1bmtub3duO1xuICAgIH1bXTtcbiAgfTtcbn1cbnR5cGUgQ3VycmVuY3lTeW1ib2wgPSBzdHJpbmc7XG5pbnRlcmZhY2UgQ2FyZFRyYW5zYWN0aW9uRGV0YWlsc0Vycm9yIHtcbiAgdGl0bGU6IHN0cmluZztcbiAgc3RhdHVzQ29kZTogbnVtYmVyO1xufVxuaW50ZXJmYWNlIENhcmRUcmFuc2FjdGlvbkRldGFpbHMgZXh0ZW5kcyBDYXJkVHJhbnNhY3Rpb25EZXRhaWxzRXJyb3Ige1xuICByZXN1bHQ6IHtcbiAgICBiYW5rQWNjb3VudHM6IHtcbiAgICAgIGJhbmtBY2NvdW50TnVtOiBzdHJpbmc7XG4gICAgICBiYW5rTmFtZTogc3RyaW5nO1xuICAgICAgY2hvaWNlRXh0ZXJuYWxUcmFuc2FjdGlvbnM6IGFueTtcbiAgICAgIGN1cnJlbnRCYW5rQWNjb3VudEluZDogYm9vbGVhbjtcbiAgICAgIGRlYml0RGF0ZXM6IHtcbiAgICAgICAgYmFza2V0QW1vdW50Q29tbWVudDogdW5rbm93bjtcbiAgICAgICAgY2hvaWNlSEhLRGViaXQ6IG51bWJlcjtcbiAgICAgICAgZGF0ZTogc3RyaW5nO1xuICAgICAgICBkZWJpdFJlYXNvbjogdW5rbm93bjtcbiAgICAgICAgZml4RGViaXRBbW91bnQ6IG51bWJlcjtcbiAgICAgICAgZnJvbVB1cmNoYXNlRGF0ZTogc3RyaW5nO1xuICAgICAgICBpc0Nob2ljZVJlcGFpbWVudDogYm9vbGVhbjtcbiAgICAgICAgdG9QdXJjaGFzZURhdGU6IHN0cmluZztcbiAgICAgICAgdG90YWxCYXNrZXRBbW91bnQ6IG51bWJlcjtcbiAgICAgICAgdG90YWxEZWJpdHM6IHtcbiAgICAgICAgICBjdXJyZW5jeVN5bWJvbDogQ3VycmVuY3lTeW1ib2w7XG4gICAgICAgICAgYW1vdW50OiBudW1iZXI7XG4gICAgICAgIH1bXTtcbiAgICAgICAgdHJhbnNhY3Rpb25zOiBTY3JhcGVkVHJhbnNhY3Rpb25bXTtcbiAgICAgIH1bXTtcbiAgICAgIGltbWlkaWF0ZURlYml0czogeyB0b3RhbERlYml0czogW107IGRlYml0RGF5czogW10gfTtcbiAgICB9W107XG4gICAgYmxvY2tlZENhcmRJbmQ6IGJvb2xlYW47XG4gIH07XG4gIHN0YXR1c0NvZGU6IDE7XG4gIHN0YXR1c0Rlc2NyaXB0aW9uOiBzdHJpbmc7XG4gIHN0YXR1c1RpdGxlOiBzdHJpbmc7XG59XG5pbnRlcmZhY2UgQ2FyZFBlbmRpbmdUcmFuc2FjdGlvbkRldGFpbHMgZXh0ZW5kcyBDYXJkVHJhbnNhY3Rpb25EZXRhaWxzRXJyb3Ige1xuICByZXN1bHQ6IHtcbiAgICBjYXJkc0xpc3Q6IHtcbiAgICAgIGNhcmRVbmlxdWVJRDogc3RyaW5nO1xuICAgICAgYXV0aERldGFsaXNMaXN0OiBTY3JhcGVkUGVuZGluZ1RyYW5zYWN0aW9uW107XG4gICAgfVtdO1xuICB9O1xuICBzdGF0dXNDb2RlOiAxO1xuICBzdGF0dXNEZXNjcmlwdGlvbjogc3RyaW5nO1xuICBzdGF0dXNUaXRsZTogc3RyaW5nO1xufVxuXG5mdW5jdGlvbiBpc1BlbmRpbmcoXG4gIHRyYW5zYWN0aW9uOiBTY3JhcGVkVHJhbnNhY3Rpb24gfCBTY3JhcGVkUGVuZGluZ1RyYW5zYWN0aW9uLFxuKTogdHJhbnNhY3Rpb24gaXMgU2NyYXBlZFBlbmRpbmdUcmFuc2FjdGlvbiB7XG4gIHJldHVybiAodHJhbnNhY3Rpb24gYXMgU2NyYXBlZFRyYW5zYWN0aW9uKS5kZWJDcmREYXRlID09PSB1bmRlZmluZWQ7IC8vIGFuIGFyYml0cmFyeSBmaWVsZCB0aGF0IG9ubHkgYXBwZWFycyBpbiBhIGNvbXBsZXRlZCB0cmFuc2FjdGlvblxufVxuXG5mdW5jdGlvbiBpc0NhcmRUcmFuc2FjdGlvbkRldGFpbHMoXG4gIHJlc3VsdDogQ2FyZFRyYW5zYWN0aW9uRGV0YWlscyB8IENhcmRUcmFuc2FjdGlvbkRldGFpbHNFcnJvcixcbik6IHJlc3VsdCBpcyBDYXJkVHJhbnNhY3Rpb25EZXRhaWxzIHtcbiAgcmV0dXJuIChyZXN1bHQgYXMgQ2FyZFRyYW5zYWN0aW9uRGV0YWlscykucmVzdWx0ICE9PSB1bmRlZmluZWQ7XG59XG5cbmZ1bmN0aW9uIGlzQ2FyZFBlbmRpbmdUcmFuc2FjdGlvbkRldGFpbHMoXG4gIHJlc3VsdDogQ2FyZFBlbmRpbmdUcmFuc2FjdGlvbkRldGFpbHMgfCBDYXJkVHJhbnNhY3Rpb25EZXRhaWxzRXJyb3IsXG4pOiByZXN1bHQgaXMgQ2FyZFBlbmRpbmdUcmFuc2FjdGlvbkRldGFpbHMge1xuICByZXR1cm4gKHJlc3VsdCBhcyBDYXJkUGVuZGluZ1RyYW5zYWN0aW9uRGV0YWlscykucmVzdWx0ICE9PSB1bmRlZmluZWQ7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGdldExvZ2luRnJhbWUocGFnZTogUGFnZSkge1xuICBsZXQgZnJhbWU6IEZyYW1lIHwgbnVsbCA9IG51bGw7XG4gIGRlYnVnKCd3YWl0IHVudGlsIGxvZ2luIGZyYW1lIGZvdW5kJyk7XG4gIGF3YWl0IHdhaXRVbnRpbChcbiAgICAoKSA9PiB7XG4gICAgICBmcmFtZSA9IHBhZ2UuZnJhbWVzKCkuZmluZChmID0+IGYudXJsKCkuaW5jbHVkZXMoJ2Nvbm5lY3QnKSkgfHwgbnVsbDtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoISFmcmFtZSk7XG4gICAgfSxcbiAgICAnd2FpdCBmb3IgaWZyYW1lIHdpdGggbG9naW4gZm9ybScsXG4gICAgMTAwMDAsXG4gICAgMTAwMCxcbiAgKTtcblxuICBpZiAoIWZyYW1lKSB7XG4gICAgZGVidWcoJ2ZhaWxlZCB0byBmaW5kIGxvZ2luIGZyYW1lIGZvciAxMCBzZWNvbmRzJyk7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdmYWlsZWQgdG8gZXh0cmFjdCBsb2dpbiBpZnJhbWUnKTtcbiAgfVxuXG4gIHJldHVybiBmcmFtZTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gaGFzSW52YWxpZFBhc3N3b3JkRXJyb3IocGFnZTogUGFnZSkge1xuICBjb25zdCBmcmFtZSA9IGF3YWl0IGdldExvZ2luRnJhbWUocGFnZSk7XG4gIGNvbnN0IGVycm9yRm91bmQgPSBhd2FpdCBlbGVtZW50UHJlc2VudE9uUGFnZShmcmFtZSwgJ2Rpdi5nZW5lcmFsLWVycm9yID4gZGl2Jyk7XG4gIGNvbnN0IGVycm9yTWVzc2FnZSA9IGVycm9yRm91bmRcbiAgICA/IGF3YWl0IHBhZ2VFdmFsKGZyYW1lLCAnZGl2LmdlbmVyYWwtZXJyb3IgPiBkaXYnLCAnJywgaXRlbSA9PiB7XG4gICAgICAgIHJldHVybiAoaXRlbSBhcyBIVE1MRGl2RWxlbWVudCkuaW5uZXJUZXh0O1xuICAgICAgfSlcbiAgICA6ICcnO1xuICByZXR1cm4gZXJyb3JNZXNzYWdlID09PSBJbnZhbGlkUGFzc3dvcmRNZXNzYWdlO1xufVxuXG5hc3luYyBmdW5jdGlvbiBoYXNDaGFuZ2VQYXNzd29yZEZvcm0ocGFnZTogUGFnZSkge1xuICBjb25zdCBmcmFtZSA9IGF3YWl0IGdldExvZ2luRnJhbWUocGFnZSk7XG4gIGNvbnN0IGVycm9yRm91bmQgPSBhd2FpdCBlbGVtZW50UHJlc2VudE9uUGFnZShmcmFtZSwgJy5jaGFuZ2UtcGFzc3dvcmQtc3VidGl0bGUnKTtcbiAgcmV0dXJuIGVycm9yRm91bmQ7XG59XG5cbmZ1bmN0aW9uIGdldFBvc3NpYmxlTG9naW5SZXN1bHRzKCkge1xuICBkZWJ1ZygncmV0dXJuIHBvc3NpYmxlIGxvZ2luIHJlc3VsdHMnKTtcbiAgY29uc3QgdXJsczogTG9naW5PcHRpb25zWydwb3NzaWJsZVJlc3VsdHMnXSA9IHtcbiAgICBbTG9naW5SZXN1bHRzLlN1Y2Nlc3NdOiBbL2Rhc2hib2FyZC9pXSxcbiAgICBbTG9naW5SZXN1bHRzLkludmFsaWRQYXNzd29yZF06IFtcbiAgICAgIGFzeW5jIChvcHRpb25zPzogeyBwYWdlPzogUGFnZSB9KSA9PiB7XG4gICAgICAgIGNvbnN0IHBhZ2UgPSBvcHRpb25zPy5wYWdlO1xuICAgICAgICBpZiAoIXBhZ2UpIHtcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGhhc0ludmFsaWRQYXNzd29yZEVycm9yKHBhZ2UpO1xuICAgICAgfSxcbiAgICBdLFxuICAgIC8vIFtMb2dpblJlc3VsdHMuQWNjb3VudEJsb2NrZWRdOiBbXSwgLy8gVE9ETyBhZGQgd2hlbiByZWFjaGluZyB0aGlzIHNjZW5hcmlvXG4gICAgW0xvZ2luUmVzdWx0cy5DaGFuZ2VQYXNzd29yZF06IFtcbiAgICAgIGFzeW5jIChvcHRpb25zPzogeyBwYWdlPzogUGFnZSB9KSA9PiB7XG4gICAgICAgIGNvbnN0IHBhZ2UgPSBvcHRpb25zPy5wYWdlO1xuICAgICAgICBpZiAoIXBhZ2UpIHtcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGhhc0NoYW5nZVBhc3N3b3JkRm9ybShwYWdlKTtcbiAgICAgIH0sXG4gICAgXSxcbiAgfTtcbiAgcmV0dXJuIHVybHM7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZUxvZ2luRmllbGRzKGNyZWRlbnRpYWxzOiBTY3JhcGVyU3BlY2lmaWNDcmVkZW50aWFscykge1xuICBkZWJ1ZygnY3JlYXRlIGxvZ2luIGZpZWxkcyBmb3IgdXNlcm5hbWUgYW5kIHBhc3N3b3JkJyk7XG4gIHJldHVybiBbXG4gICAgeyBzZWxlY3RvcjogJ1tmb3JtY29udHJvbG5hbWU9XCJ1c2VyTmFtZVwiXScsIHZhbHVlOiBjcmVkZW50aWFscy51c2VybmFtZSB9LFxuICAgIHsgc2VsZWN0b3I6ICdbZm9ybWNvbnRyb2xuYW1lPVwicGFzc3dvcmRcIl0nLCB2YWx1ZTogY3JlZGVudGlhbHMucGFzc3dvcmQgfSxcbiAgXTtcbn1cblxuZnVuY3Rpb24gY29udmVydFBhcnNlZERhdGFUb1RyYW5zYWN0aW9ucyhcbiAgZGF0YTogQ2FyZFRyYW5zYWN0aW9uRGV0YWlsc1tdLFxuICBwZW5kaW5nRGF0YT86IENhcmRQZW5kaW5nVHJhbnNhY3Rpb25EZXRhaWxzIHwgbnVsbCxcbik6IFRyYW5zYWN0aW9uW10ge1xuICBjb25zdCBwZW5kaW5nVHJhbnNhY3Rpb25zID0gcGVuZGluZ0RhdGE/LnJlc3VsdFxuICAgID8gcGVuZGluZ0RhdGEucmVzdWx0LmNhcmRzTGlzdC5mbGF0TWFwKGNhcmQgPT4gY2FyZC5hdXRoRGV0YWxpc0xpc3QpXG4gICAgOiBbXTtcblxuICBjb25zdCBiYW5rQWNjb3VudHMgPSBkYXRhLmZsYXRNYXAobW9udGhEYXRhID0+IG1vbnRoRGF0YS5yZXN1bHQuYmFua0FjY291bnRzKTtcbiAgY29uc3QgcmVndWxhckRlYml0RGF5cyA9IGJhbmtBY2NvdW50cy5mbGF0TWFwKGFjY291bnRzID0+IGFjY291bnRzLmRlYml0RGF0ZXMpO1xuICBjb25zdCBpbW1lZGlhdGVEZWJpdERheXMgPSBiYW5rQWNjb3VudHMuZmxhdE1hcChhY2NvdW50cyA9PiBhY2NvdW50cy5pbW1pZGlhdGVEZWJpdHMuZGViaXREYXlzKTtcbiAgY29uc3QgY29tcGxldGVkVHJhbnNhY3Rpb25zID0gWy4uLnJlZ3VsYXJEZWJpdERheXMsIC4uLmltbWVkaWF0ZURlYml0RGF5c10uZmxhdE1hcChcbiAgICBkZWJpdERhdGUgPT4gZGViaXREYXRlLnRyYW5zYWN0aW9ucyxcbiAgKTtcblxuICBjb25zdCBhbGw6IChTY3JhcGVkVHJhbnNhY3Rpb24gfCBTY3JhcGVkUGVuZGluZ1RyYW5zYWN0aW9uKVtdID0gWy4uLnBlbmRpbmdUcmFuc2FjdGlvbnMsIC4uLmNvbXBsZXRlZFRyYW5zYWN0aW9uc107XG5cbiAgcmV0dXJuIGFsbC5tYXAodHJhbnNhY3Rpb24gPT4ge1xuICAgIGNvbnN0IG51bU9mUGF5bWVudHMgPSBpc1BlbmRpbmcodHJhbnNhY3Rpb24pID8gdHJhbnNhY3Rpb24ubnVtYmVyT2ZQYXltZW50cyA6IHRyYW5zYWN0aW9uLm51bU9mUGF5bWVudHM7XG4gICAgY29uc3QgaW5zdGFsbG1lbnRzID0gbnVtT2ZQYXltZW50c1xuICAgICAgPyB7XG4gICAgICAgICAgbnVtYmVyOiBpc1BlbmRpbmcodHJhbnNhY3Rpb24pID8gMSA6IHRyYW5zYWN0aW9uLmN1clBheW1lbnROdW0sXG4gICAgICAgICAgdG90YWw6IG51bU9mUGF5bWVudHMsXG4gICAgICAgIH1cbiAgICAgIDogdW5kZWZpbmVkO1xuXG4gICAgY29uc3QgZGF0ZSA9IG1vbWVudCh0cmFuc2FjdGlvbi50cm5QdXJjaGFzZURhdGUpO1xuXG4gICAgbGV0IGNoYXJnZWRBbW91bnQgPSBpc1BlbmRpbmcodHJhbnNhY3Rpb24pID8gdHJhbnNhY3Rpb24udHJuQW10ICogLTEgOiB0cmFuc2FjdGlvbi5hbXRCZWZvcmVDb252QW5kSW5kZXggKiAtMTtcbiAgICBsZXQgb3JpZ2luYWxBbW91bnQgPSB0cmFuc2FjdGlvbi50cm5BbXQgKiAtMTtcblxuICAgIGlmICh0cmFuc2FjdGlvbi50cm5UeXBlQ29kZSA9PT0gVHJuVHlwZUNvZGUuY3JlZGl0KSB7XG4gICAgICBjaGFyZ2VkQW1vdW50ID0gaXNQZW5kaW5nKHRyYW5zYWN0aW9uKSA/IHRyYW5zYWN0aW9uLnRybkFtdCA6IHRyYW5zYWN0aW9uLmFtdEJlZm9yZUNvbnZBbmRJbmRleDtcbiAgICAgIG9yaWdpbmFsQW1vdW50ID0gdHJhbnNhY3Rpb24udHJuQW10O1xuICAgIH1cblxuICAgIGNvbnN0IHJlc3VsdDogVHJhbnNhY3Rpb24gPSB7XG4gICAgICBpZGVudGlmaWVyOiAhaXNQZW5kaW5nKHRyYW5zYWN0aW9uKSA/IHRyYW5zYWN0aW9uLnRybkludElkIDogdW5kZWZpbmVkLFxuICAgICAgdHlwZTogW1RyblR5cGVDb2RlLnJlZ3VsYXIsIFRyblR5cGVDb2RlLnN0YW5kaW5nT3JkZXJdLmluY2x1ZGVzKHRyYW5zYWN0aW9uLnRyblR5cGVDb2RlKVxuICAgICAgICA/IFRyYW5zYWN0aW9uVHlwZXMuTm9ybWFsXG4gICAgICAgIDogVHJhbnNhY3Rpb25UeXBlcy5JbnN0YWxsbWVudHMsXG4gICAgICBzdGF0dXM6IGlzUGVuZGluZyh0cmFuc2FjdGlvbikgPyBUcmFuc2FjdGlvblN0YXR1c2VzLlBlbmRpbmcgOiBUcmFuc2FjdGlvblN0YXR1c2VzLkNvbXBsZXRlZCxcbiAgICAgIGRhdGU6IGluc3RhbGxtZW50cyA/IGRhdGUuYWRkKGluc3RhbGxtZW50cy5udW1iZXIgLSAxLCAnbW9udGgnKS50b0lTT1N0cmluZygpIDogZGF0ZS50b0lTT1N0cmluZygpLFxuICAgICAgcHJvY2Vzc2VkRGF0ZTogaXNQZW5kaW5nKHRyYW5zYWN0aW9uKSA/IGRhdGUudG9JU09TdHJpbmcoKSA6IG5ldyBEYXRlKHRyYW5zYWN0aW9uLmRlYkNyZERhdGUpLnRvSVNPU3RyaW5nKCksXG4gICAgICBvcmlnaW5hbEFtb3VudCxcbiAgICAgIG9yaWdpbmFsQ3VycmVuY3k6IHRyYW5zYWN0aW9uLnRybkN1cnJlbmN5U3ltYm9sLFxuICAgICAgY2hhcmdlZEFtb3VudCxcbiAgICAgIGNoYXJnZWRDdXJyZW5jeTogIWlzUGVuZGluZyh0cmFuc2FjdGlvbikgPyB0cmFuc2FjdGlvbi5kZWJDcmRDdXJyZW5jeVN5bWJvbCA6IHVuZGVmaW5lZCxcbiAgICAgIGRlc2NyaXB0aW9uOiB0cmFuc2FjdGlvbi5tZXJjaGFudE5hbWUsXG4gICAgICBtZW1vOiB0cmFuc2FjdGlvbi50cmFuc1R5cGVDb21tZW50RGV0YWlscy50b1N0cmluZygpLFxuICAgICAgY2F0ZWdvcnk6IHRyYW5zYWN0aW9uLmJyYW5jaENvZGVEZXNjLFxuICAgIH07XG5cbiAgICBpZiAoaW5zdGFsbG1lbnRzKSB7XG4gICAgICByZXN1bHQuaW5zdGFsbG1lbnRzID0gaW5zdGFsbG1lbnRzO1xuICAgIH1cblxuICAgIHJldHVybiByZXN1bHQ7XG4gIH0pO1xufVxuXG50eXBlIFNjcmFwZXJTcGVjaWZpY0NyZWRlbnRpYWxzID0geyB1c2VybmFtZTogc3RyaW5nOyBwYXNzd29yZDogc3RyaW5nIH07XG5cbmNsYXNzIFZpc2FDYWxTY3JhcGVyIGV4dGVuZHMgQmFzZVNjcmFwZXJXaXRoQnJvd3NlcjxTY3JhcGVyU3BlY2lmaWNDcmVkZW50aWFscz4ge1xuICBwcml2YXRlIGF1dGhvcml6YXRpb246IHN0cmluZyB8IHVuZGVmaW5lZCA9IHVuZGVmaW5lZDtcblxuICBwcml2YXRlIGF1dGhSZXF1ZXN0UHJvbWlzZTogUHJvbWlzZTxIVFRQUmVxdWVzdCB8IHVuZGVmaW5lZD4gfCB1bmRlZmluZWQ7XG5cbiAgb3BlbkxvZ2luUG9wdXAgPSBhc3luYyAoKSA9PiB7XG4gICAgZGVidWcoJ29wZW4gbG9naW4gcG9wdXAsIHdhaXQgdW50aWwgbG9naW4gYnV0dG9uIGF2YWlsYWJsZScpO1xuICAgIGF3YWl0IHdhaXRVbnRpbEVsZW1lbnRGb3VuZCh0aGlzLnBhZ2UsICcjY2NMb2dpbkRlc2t0b3BCdG4nLCB0cnVlKTtcbiAgICBkZWJ1ZygnY2xpY2sgb24gdGhlIGxvZ2luIGJ1dHRvbicpO1xuICAgIGF3YWl0IGNsaWNrQnV0dG9uKHRoaXMucGFnZSwgJyNjY0xvZ2luRGVza3RvcEJ0bicpO1xuICAgIGRlYnVnKCdnZXQgdGhlIGZyYW1lIHRoYXQgaG9sZHMgdGhlIGxvZ2luJyk7XG4gICAgY29uc3QgZnJhbWUgPSBhd2FpdCBnZXRMb2dpbkZyYW1lKHRoaXMucGFnZSk7XG4gICAgZGVidWcoJ3dhaXQgdW50aWwgdGhlIHBhc3N3b3JkIGxvZ2luIHRhYiBoZWFkZXIgaXMgYXZhaWxhYmxlJyk7XG4gICAgYXdhaXQgd2FpdFVudGlsRWxlbWVudEZvdW5kKGZyYW1lLCAnI3JlZ3VsYXItbG9naW4nKTtcbiAgICBkZWJ1ZygnbmF2aWdhdGUgdG8gdGhlIHBhc3N3b3JkIGxvZ2luIHRhYicpO1xuICAgIGF3YWl0IGNsaWNrQnV0dG9uKGZyYW1lLCAnI3JlZ3VsYXItbG9naW4nKTtcbiAgICBkZWJ1Zygnd2FpdCB1bnRpbCB0aGUgcGFzc3dvcmQgbG9naW4gdGFiIGlzIGFjdGl2ZScpO1xuICAgIGF3YWl0IHdhaXRVbnRpbEVsZW1lbnRGb3VuZChmcmFtZSwgJ3JlZ3VsYXItbG9naW4nKTtcblxuICAgIHJldHVybiBmcmFtZTtcbiAgfTtcblxuICBhc3luYyBnZXRDYXJkcygpIHtcbiAgICBjb25zdCBpbml0RGF0YSA9IGF3YWl0IHdhaXRVbnRpbChcbiAgICAgICgpID0+IGdldEZyb21TZXNzaW9uU3RvcmFnZTxJbml0UmVzcG9uc2U+KHRoaXMucGFnZSwgJ2luaXQnKSxcbiAgICAgICdnZXQgaW5pdCBkYXRhIGluIHNlc3Npb24gc3RvcmFnZScsXG4gICAgICAxMDAwMCxcbiAgICAgIDEwMDAsXG4gICAgKTtcbiAgICBpZiAoIWluaXREYXRhKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJjb3VsZCBub3QgZmluZCAnaW5pdCcgZGF0YSBpbiBzZXNzaW9uIHN0b3JhZ2VcIik7XG4gICAgfVxuICAgIHJldHVybiBpbml0RGF0YT8ucmVzdWx0LmNhcmRzLm1hcCgoeyBjYXJkVW5pcXVlSWQsIGxhc3Q0RGlnaXRzIH0pID0+ICh7IGNhcmRVbmlxdWVJZCwgbGFzdDREaWdpdHMgfSkpO1xuICB9XG5cbiAgYXN5bmMgZ2V0QXV0aG9yaXphdGlvbkhlYWRlcigpIHtcbiAgICBpZiAoIXRoaXMuYXV0aG9yaXphdGlvbikge1xuICAgICAgY29uc3QgYXV0aE1vZHVsZSA9IGF3YWl0IGdldEZyb21TZXNzaW9uU3RvcmFnZTx7IGF1dGg6IHsgY2FsQ29ubmVjdFRva2VuOiBzdHJpbmcgfCBudWxsIH0gfT4oXG4gICAgICAgIHRoaXMucGFnZSxcbiAgICAgICAgJ2F1dGgtbW9kdWxlJyxcbiAgICAgICk7XG4gICAgICBpZiAoYXV0aE1vZHVsZT8uYXV0aC5jYWxDb25uZWN0VG9rZW4pIHtcbiAgICAgICAgcmV0dXJuIGBDQUxBdXRoU2NoZW1lICR7YXV0aE1vZHVsZS5hdXRoLmNhbENvbm5lY3RUb2tlbn1gO1xuICAgICAgfVxuICAgICAgdGhyb3cgbmV3IEVycm9yKCdjb3VsZCBub3QgcmV0cmlldmUgYXV0aG9yaXphdGlvbiBoZWFkZXInKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuYXV0aG9yaXphdGlvbjtcbiAgfVxuXG4gIGFzeW5jIGdldFhTaXRlSWQoKSB7XG4gICAgLypcbiAgICAgIEkgZG9uJ3Qga25vdyBpZiB0aGUgY29uc3RhbnQgYmVsb3cgd2lsbCBjaGFuZ2UgaW4gdGhlIGZlYXR1cmUuXG4gICAgICBJZiBzbywgdXNlIHRoZSBuZXh0IGNvZGU6XG5cbiAgICAgIHJldHVybiB0aGlzLnBhZ2UuZXZhbHVhdGUoKCkgPT4gbmV3IFV0KCkueFNpdGVJZCk7XG5cbiAgICAgIFRvIGdldCB0aGUgY2xhc3NuYW1lIHNlYXJjaCBmb3IgJ3hTaXRlSWQnIGluIHRoZSBwYWdlIHNvdXJjZVxuICAgICAgY2xhc3MgVXQge1xuICAgICAgICBjb25zdHJ1Y3RvcihfZSwgb24sIHluKSB7XG4gICAgICAgICAgICB0aGlzLnN0b3JlID0gX2UsXG4gICAgICAgICAgICB0aGlzLmNvbmZpZyA9IG9uLFxuICAgICAgICAgICAgdGhpcy5ldmVudEJ1c1NlcnZpY2UgPSB5bixcbiAgICAgICAgICAgIHRoaXMueFNpdGVJZCA9IFwiMDkwMzE5ODctMjczRS0yMzExLTkwNkMtOEFGODVCMTdDOEQ5XCIsXG4gICAgKi9cbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCcwOTAzMTk4Ny0yNzNFLTIzMTEtOTA2Qy04QUY4NUIxN0M4RDknKTtcbiAgfVxuXG4gIGdldExvZ2luT3B0aW9ucyhjcmVkZW50aWFsczogU2NyYXBlclNwZWNpZmljQ3JlZGVudGlhbHMpOiBMb2dpbk9wdGlvbnMge1xuICAgIHRoaXMuYXV0aFJlcXVlc3RQcm9taXNlID0gdGhpcy5wYWdlXG4gICAgICAud2FpdEZvclJlcXVlc3QoU1NPX0FVVEhPUklaQVRJT05fUkVRVUVTVF9FTkRQT0lOVCwgeyB0aW1lb3V0OiAxMF8wMDAgfSlcbiAgICAgIC5jYXRjaChlID0+IHtcbiAgICAgICAgZGVidWcoJ2Vycm9yIHdoaWxlIHdhaXRpbmcgZm9yIHRoZSB0b2tlbiByZXF1ZXN0JywgZSk7XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICB9KTtcbiAgICByZXR1cm4ge1xuICAgICAgbG9naW5Vcmw6IGAke0xPR0lOX1VSTH1gLFxuICAgICAgZmllbGRzOiBjcmVhdGVMb2dpbkZpZWxkcyhjcmVkZW50aWFscyksXG4gICAgICBzdWJtaXRCdXR0b25TZWxlY3RvcjogJ2J1dHRvblt0eXBlPVwic3VibWl0XCJdJyxcbiAgICAgIHBvc3NpYmxlUmVzdWx0czogZ2V0UG9zc2libGVMb2dpblJlc3VsdHMoKSxcbiAgICAgIGNoZWNrUmVhZGluZXNzOiBhc3luYyAoKSA9PiB3YWl0VW50aWxFbGVtZW50Rm91bmQodGhpcy5wYWdlLCAnI2NjTG9naW5EZXNrdG9wQnRuJyksXG4gICAgICBwcmVBY3Rpb246IHRoaXMub3BlbkxvZ2luUG9wdXAsXG4gICAgICBwb3N0QWN0aW9uOiBhc3luYyAoKSA9PiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgYXdhaXQgd2FpdEZvck5hdmlnYXRpb24odGhpcy5wYWdlKTtcbiAgICAgICAgICBjb25zdCBjdXJyZW50VXJsID0gYXdhaXQgZ2V0Q3VycmVudFVybCh0aGlzLnBhZ2UpO1xuICAgICAgICAgIGlmIChjdXJyZW50VXJsLmVuZHNXaXRoKCdzaXRlLXR1dG9yaWFsJykpIHtcbiAgICAgICAgICAgIGF3YWl0IGNsaWNrQnV0dG9uKHRoaXMucGFnZSwgJ2J1dHRvbi5idG4tY2xvc2UnKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgY29uc3QgcmVxdWVzdCA9IGF3YWl0IHRoaXMuYXV0aFJlcXVlc3RQcm9taXNlO1xuICAgICAgICAgIHRoaXMuYXV0aG9yaXphdGlvbiA9IHJlcXVlc3Q/LmhlYWRlcnMoKT8uYXV0aG9yaXphdGlvbjtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgIGNvbnN0IGN1cnJlbnRVcmwgPSBhd2FpdCBnZXRDdXJyZW50VXJsKHRoaXMucGFnZSk7XG4gICAgICAgICAgaWYgKGN1cnJlbnRVcmwuZW5kc1dpdGgoJ2Rhc2hib2FyZCcpKSByZXR1cm47XG4gICAgICAgICAgY29uc3QgcmVxdWlyZXNDaGFuZ2VQYXNzd29yZCA9IGF3YWl0IGhhc0NoYW5nZVBhc3N3b3JkRm9ybSh0aGlzLnBhZ2UpO1xuICAgICAgICAgIGlmIChyZXF1aXJlc0NoYW5nZVBhc3N3b3JkKSByZXR1cm47XG4gICAgICAgICAgdGhyb3cgZTtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIHVzZXJBZ2VudDpcbiAgICAgICAgJ01vemlsbGEvNS4wIChYMTE7IExpbnV4IHg4Nl82NCkgQXBwbGVXZWJLaXQvNTM3LjM2IChLSFRNTCwgbGlrZSBHZWNrbykgQ2hyb21lLzc4LjAuMzkwNC4xMDggU2FmYXJpLzUzNy4zNicsXG4gICAgfTtcbiAgfVxuXG4gIGFzeW5jIGZldGNoRGF0YSgpOiBQcm9taXNlPFNjcmFwZXJTY3JhcGluZ1Jlc3VsdD4ge1xuICAgIGNvbnN0IGRlZmF1bHRTdGFydE1vbWVudCA9IG1vbWVudCgpLnN1YnRyYWN0KDEsICd5ZWFycycpLnN1YnRyYWN0KDYsICdtb250aHMnKS5hZGQoMSwgJ2RheScpO1xuICAgIGNvbnN0IHN0YXJ0RGF0ZSA9IHRoaXMub3B0aW9ucy5zdGFydERhdGUgfHwgZGVmYXVsdFN0YXJ0TW9tZW50LnRvRGF0ZSgpO1xuICAgIGNvbnN0IHN0YXJ0TW9tZW50ID0gbW9tZW50Lm1heChkZWZhdWx0U3RhcnRNb21lbnQsIG1vbWVudChzdGFydERhdGUpKTtcbiAgICBkZWJ1ZyhgZmV0Y2ggdHJhbnNhY3Rpb25zIHN0YXJ0aW5nICR7c3RhcnRNb21lbnQuZm9ybWF0KCl9YCk7XG5cbiAgICBjb25zdCBBdXRob3JpemF0aW9uID0gYXdhaXQgdGhpcy5nZXRBdXRob3JpemF0aW9uSGVhZGVyKCk7XG4gICAgY29uc3QgY2FyZHMgPSBhd2FpdCB0aGlzLmdldENhcmRzKCk7XG4gICAgY29uc3QgeFNpdGVJZCA9IGF3YWl0IHRoaXMuZ2V0WFNpdGVJZCgpO1xuICAgIGNvbnN0IGZ1dHVyZU1vbnRoc1RvU2NyYXBlID0gdGhpcy5vcHRpb25zLmZ1dHVyZU1vbnRoc1RvU2NyYXBlID8/IDE7XG5cbiAgICBjb25zdCBhY2NvdW50cyA9IGF3YWl0IFByb21pc2UuYWxsKFxuICAgICAgY2FyZHMubWFwKGFzeW5jIGNhcmQgPT4ge1xuICAgICAgICBjb25zdCBmaW5hbE1vbnRoVG9GZXRjaE1vbWVudCA9IG1vbWVudCgpLmFkZChmdXR1cmVNb250aHNUb1NjcmFwZSwgJ21vbnRoJyk7XG4gICAgICAgIGNvbnN0IG1vbnRocyA9IGZpbmFsTW9udGhUb0ZldGNoTW9tZW50LmRpZmYoc3RhcnRNb21lbnQsICdtb250aHMnKTtcblxuICAgICAgICBjb25zdCBhbGxNb250aHNEYXRhOiBDYXJkVHJhbnNhY3Rpb25EZXRhaWxzW10gPSBbXTtcblxuICAgICAgICBkZWJ1ZyhgZmV0Y2ggcGVuZGluZyB0cmFuc2FjdGlvbnMgZm9yIGNhcmQgJHtjYXJkLmNhcmRVbmlxdWVJZH1gKTtcbiAgICAgICAgbGV0IHBlbmRpbmdEYXRhID0gYXdhaXQgZmV0Y2hQb3N0V2l0aGluUGFnZTxDYXJkUGVuZGluZ1RyYW5zYWN0aW9uRGV0YWlscyB8IENhcmRUcmFuc2FjdGlvbkRldGFpbHNFcnJvcj4oXG4gICAgICAgICAgdGhpcy5wYWdlLFxuICAgICAgICAgIFBFTkRJTkdfVFJBTlNBQ1RJT05TX1JFUVVFU1RfRU5EUE9JTlQsXG4gICAgICAgICAgeyBjYXJkVW5pcXVlSURBcnJheTogW2NhcmQuY2FyZFVuaXF1ZUlkXSB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIEF1dGhvcml6YXRpb24sXG4gICAgICAgICAgICAnWC1TaXRlLUlkJzogeFNpdGVJZCxcbiAgICAgICAgICAgICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicsXG4gICAgICAgICAgfSxcbiAgICAgICAgKTtcblxuICAgICAgICBkZWJ1ZyhgZmV0Y2ggY29tcGxldGVkIHRyYW5zYWN0aW9ucyBmb3IgY2FyZCAke2NhcmQuY2FyZFVuaXF1ZUlkfWApO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8PSBtb250aHM7IGkgKz0gMSkge1xuICAgICAgICAgIGNvbnN0IG1vbnRoID0gZmluYWxNb250aFRvRmV0Y2hNb21lbnQuY2xvbmUoKS5zdWJ0cmFjdChpLCAnbW9udGhzJyk7XG4gICAgICAgICAgY29uc3QgbW9udGhEYXRhID0gYXdhaXQgZmV0Y2hQb3N0V2l0aGluUGFnZTxDYXJkVHJhbnNhY3Rpb25EZXRhaWxzIHwgQ2FyZFRyYW5zYWN0aW9uRGV0YWlsc0Vycm9yPihcbiAgICAgICAgICAgIHRoaXMucGFnZSxcbiAgICAgICAgICAgIFRSQU5TQUNUSU9OU19SRVFVRVNUX0VORFBPSU5ULFxuICAgICAgICAgICAgeyBjYXJkVW5pcXVlSWQ6IGNhcmQuY2FyZFVuaXF1ZUlkLCBtb250aDogbW9udGguZm9ybWF0KCdNJyksIHllYXI6IG1vbnRoLmZvcm1hdCgnWVlZWScpIH0sXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIEF1dGhvcml6YXRpb24sXG4gICAgICAgICAgICAgICdYLVNpdGUtSWQnOiB4U2l0ZUlkLFxuICAgICAgICAgICAgICAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICApO1xuXG4gICAgICAgICAgaWYgKG1vbnRoRGF0YT8uc3RhdHVzQ29kZSAhPT0gMSlcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICAgICAgYGZhaWxlZCB0byBmZXRjaCB0cmFuc2FjdGlvbnMgZm9yIGNhcmQgJHtjYXJkLmxhc3Q0RGlnaXRzfS4gTWVzc2FnZTogJHttb250aERhdGE/LnRpdGxlIHx8ICcnfWAsXG4gICAgICAgICAgICApO1xuXG4gICAgICAgICAgaWYgKCFpc0NhcmRUcmFuc2FjdGlvbkRldGFpbHMobW9udGhEYXRhKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdtb250aERhdGEgaXMgbm90IG9mIHR5cGUgQ2FyZFRyYW5zYWN0aW9uRGV0YWlscycpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGFsbE1vbnRoc0RhdGEucHVzaChtb250aERhdGEpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHBlbmRpbmdEYXRhPy5zdGF0dXNDb2RlICE9PSAxICYmIHBlbmRpbmdEYXRhPy5zdGF0dXNDb2RlICE9PSA5Nikge1xuICAgICAgICAgIGRlYnVnKFxuICAgICAgICAgICAgYGZhaWxlZCB0byBmZXRjaCBwZW5kaW5nIHRyYW5zYWN0aW9ucyBmb3IgY2FyZCAke2NhcmQubGFzdDREaWdpdHN9LiBNZXNzYWdlOiAke3BlbmRpbmdEYXRhPy50aXRsZSB8fCAnJ31gLFxuICAgICAgICAgICk7XG4gICAgICAgICAgcGVuZGluZ0RhdGEgPSBudWxsO1xuICAgICAgICB9IGVsc2UgaWYgKCFpc0NhcmRQZW5kaW5nVHJhbnNhY3Rpb25EZXRhaWxzKHBlbmRpbmdEYXRhKSkge1xuICAgICAgICAgIGRlYnVnKCdwZW5kaW5nRGF0YSBpcyBub3Qgb2YgdHlwZSBDYXJkVHJhbnNhY3Rpb25EZXRhaWxzJyk7XG4gICAgICAgICAgcGVuZGluZ0RhdGEgPSBudWxsO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgdHJhbnNhY3Rpb25zID0gY29udmVydFBhcnNlZERhdGFUb1RyYW5zYWN0aW9ucyhhbGxNb250aHNEYXRhLCBwZW5kaW5nRGF0YSk7XG5cbiAgICAgICAgZGVidWcoJ2ZpbGVyIG91dCBvbGQgdHJhbnNhY3Rpb25zJyk7XG4gICAgICAgIGNvbnN0IHR4bnMgPVxuICAgICAgICAgICh0aGlzLm9wdGlvbnMub3V0cHV0RGF0YT8uZW5hYmxlVHJhbnNhY3Rpb25zRmlsdGVyQnlEYXRlID8/IHRydWUpXG4gICAgICAgICAgICA/IGZpbHRlck9sZFRyYW5zYWN0aW9ucyh0cmFuc2FjdGlvbnMsIG1vbWVudChzdGFydERhdGUpLCB0aGlzLm9wdGlvbnMuY29tYmluZUluc3RhbGxtZW50cyB8fCBmYWxzZSlcbiAgICAgICAgICAgIDogdHJhbnNhY3Rpb25zO1xuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgdHhucyxcbiAgICAgICAgICBhY2NvdW50TnVtYmVyOiBjYXJkLmxhc3Q0RGlnaXRzLFxuICAgICAgICB9IGFzIFRyYW5zYWN0aW9uc0FjY291bnQ7XG4gICAgICB9KSxcbiAgICApO1xuXG4gICAgZGVidWcoJ3JldHVybiB0aGUgc2NyYXBlZCBhY2NvdW50cycpO1xuXG4gICAgZGVidWcoSlNPTi5zdHJpbmdpZnkoYWNjb3VudHMsIG51bGwsIDIpKTtcbiAgICByZXR1cm4ge1xuICAgICAgc3VjY2VzczogdHJ1ZSxcbiAgICAgIGFjY291bnRzLFxuICAgIH07XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgVmlzYUNhbFNjcmFwZXI7XG4iXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBLElBQUFBLE9BQUEsR0FBQUMsc0JBQUEsQ0FBQUMsT0FBQTtBQUVBLElBQUFDLE1BQUEsR0FBQUQsT0FBQTtBQUNBLElBQUFFLHFCQUFBLEdBQUFGLE9BQUE7QUFDQSxJQUFBRyxNQUFBLEdBQUFILE9BQUE7QUFDQSxJQUFBSSxXQUFBLEdBQUFKLE9BQUE7QUFDQSxJQUFBSyxRQUFBLEdBQUFMLE9BQUE7QUFDQSxJQUFBTSxhQUFBLEdBQUFOLE9BQUE7QUFDQSxJQUFBTyxRQUFBLEdBQUFQLE9BQUE7QUFDQSxJQUFBUSxjQUFBLEdBQUFSLE9BQUE7QUFDQSxJQUFBUyx1QkFBQSxHQUFBVCxPQUFBO0FBQXNHLFNBQUFELHVCQUFBVyxDQUFBLFdBQUFBLENBQUEsSUFBQUEsQ0FBQSxDQUFBQyxVQUFBLEdBQUFELENBQUEsS0FBQUUsT0FBQSxFQUFBRixDQUFBO0FBR3RHLE1BQU1HLFNBQVMsR0FBRywrQkFBK0I7QUFDakQsTUFBTUMsNkJBQTZCLEdBQ2pDLDhGQUE4RjtBQUNoRyxNQUFNQyxxQ0FBcUMsR0FDekMsOEVBQThFO0FBQ2hGLE1BQU1DLGtDQUFrQyxHQUFHLHlFQUF5RTtBQUVwSCxNQUFNQyxzQkFBc0IsR0FBRyxtQ0FBbUM7QUFFbEUsTUFBTUMsS0FBSyxHQUFHLElBQUFDLGVBQVEsRUFBQyxVQUFVLENBQUM7QUFBQyxJQUU5QkMsV0FBVywwQkFBWEEsV0FBVztFQUFYQSxXQUFXO0VBQVhBLFdBQVc7RUFBWEEsV0FBVztFQUFYQSxXQUFXO0VBQUEsT0FBWEEsV0FBVztBQUFBLEVBQVhBLFdBQVc7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