UNPKG

israeli-bank-scrapers-core

Version:

Provide scrapers for all major Israeli banks and credit card companies

318 lines 54.7 kB
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;
var _buildUrl = _interopRequireDefault(require("build-url"));
var _lodash = _interopRequireDefault(require("lodash"));
var _moment = _interopRequireDefault(require("moment"));
var _constants = require("../constants");
var _definitions = require("../definitions");
var _dates = _interopRequireDefault(require("../helpers/dates"));
var _debug = require("../helpers/debug");
var _fetch = require("../helpers/fetch");
var _transactions = require("../helpers/transactions");
var _waiting = require("../helpers/waiting");
var _transactions2 = require("../transactions");
var _baseScraperWithBrowser = require("./base-scraper-with-browser");
var _errors = require("./errors");
var _browser = require("../helpers/browser");
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
const COUNTRY_CODE = '212';
const ID_TYPE = '1';
const INSTALLMENTS_KEYWORD = 'תשלום';
const DATE_FORMAT = 'DD/MM/YYYY';
const debug = (0, _debug.getDebug)('base-isracard-amex');
function getAccountsUrl(servicesUrl, monthMoment) {
  const billingDate = monthMoment.format('YYYY-MM-DD');
  return (0, _buildUrl.default)(servicesUrl, {
    queryParams: {
      reqName: 'DashboardMonth',
      actionCode: '0',
      billingDate,
      format: 'Json'
    }
  });
}
async function fetchAccounts(page, servicesUrl, monthMoment) {
  const dataUrl = getAccountsUrl(servicesUrl, monthMoment);
  const dataResult = await (0, _fetch.fetchGetWithinPage)(page, dataUrl);
  if (dataResult && _lodash.default.get(dataResult, 'Header.Status') === '1' && dataResult.DashboardMonthBean) {
    const {
      cardsCharges
    } = dataResult.DashboardMonthBean;
    if (cardsCharges) {
      return cardsCharges.map(cardCharge => {
        return {
          index: parseInt(cardCharge.cardIndex, 10),
          accountNumber: cardCharge.cardNumber,
          processedDate: (0, _moment.default)(cardCharge.billingDate, DATE_FORMAT).toISOString()
        };
      });
    }
  }
  return [];
}
function getTransactionsUrl(servicesUrl, monthMoment) {
  const month = monthMoment.month() + 1;
  const year = monthMoment.year();
  const monthStr = month < 10 ? `0${month}` : month.toString();
  return (0, _buildUrl.default)(servicesUrl, {
    queryParams: {
      reqName: 'CardsTransactionsList',
      month: monthStr,
      year: `${year}`,
      requiredDate: 'N'
    }
  });
}
function convertCurrency(currencyStr) {
  if (currencyStr === _constants.SHEKEL_CURRENCY_KEYWORD || currencyStr === _constants.ALT_SHEKEL_CURRENCY) {
    return _constants.SHEKEL_CURRENCY;
  }
  return currencyStr;
}
function getInstallmentsInfo(txn) {
  if (!txn.moreInfo || !txn.moreInfo.includes(INSTALLMENTS_KEYWORD)) {
    return undefined;
  }
  const matches = txn.moreInfo.match(/\d+/g);
  if (!matches || matches.length < 2) {
    return undefined;
  }
  return {
    number: parseInt(matches[0], 10),
    total: parseInt(matches[1], 10)
  };
}
function getTransactionType(txn) {
  return getInstallmentsInfo(txn) ? _transactions2.TransactionTypes.Installments : _transactions2.TransactionTypes.Normal;
}
function convertTransactions(txns, processedDate) {
  const filteredTxns = txns.filter(txn => txn.dealSumType !== '1' && txn.voucherNumberRatz !== '000000000' && txn.voucherNumberRatzOutbound !== '000000000');
  return filteredTxns.map(txn => {
    const isOutbound = txn.dealSumOutbound;
    const txnDateStr = isOutbound ? txn.fullPurchaseDateOutbound : txn.fullPurchaseDate;
    const txnMoment = (0, _moment.default)(txnDateStr, DATE_FORMAT);
    const currentProcessedDate = txn.fullPaymentDate ? (0, _moment.default)(txn.fullPaymentDate, DATE_FORMAT).toISOString() : processedDate;
    const result = {
      type: getTransactionType(txn),
      identifier: parseInt(isOutbound ? txn.voucherNumberRatzOutbound : txn.voucherNumberRatz, 10),
      date: txnMoment.toISOString(),
      processedDate: currentProcessedDate,
      originalAmount: isOutbound ? -txn.dealSumOutbound : -txn.dealSum,
      originalCurrency: convertCurrency(txn.currentPaymentCurrency ?? txn.currencyId),
      chargedAmount: isOutbound ? -txn.paymentSumOutbound : -txn.paymentSum,
      chargedCurrency: convertCurrency(txn.currencyId),
      description: isOutbound ? txn.fullSupplierNameOutbound : txn.fullSupplierNameHeb,
      memo: txn.moreInfo || '',
      installments: getInstallmentsInfo(txn) || undefined,
      status: _transactions2.TransactionStatuses.Completed
    };
    return result;
  });
}
async function fetchTransactions(page, options, companyServiceOptions, startMoment, monthMoment) {
  const accounts = await fetchAccounts(page, companyServiceOptions.servicesUrl, monthMoment);
  const dataUrl = getTransactionsUrl(companyServiceOptions.servicesUrl, monthMoment);
  const dataResult = await (0, _fetch.fetchGetWithinPage)(page, dataUrl);
  if (dataResult && _lodash.default.get(dataResult, 'Header.Status') === '1' && dataResult.CardsTransactionsListBean) {
    const accountTxns = {};
    accounts.forEach(account => {
      const txnGroups = _lodash.default.get(dataResult, `CardsTransactionsListBean.Index${account.index}.CurrentCardTransactions`);
      if (txnGroups) {
        let allTxns = [];
        txnGroups.forEach(txnGroup => {
          if (txnGroup.txnIsrael) {
            const txns = convertTransactions(txnGroup.txnIsrael, account.processedDate);
            allTxns.push(...txns);
          }
          if (txnGroup.txnAbroad) {
            const txns = convertTransactions(txnGroup.txnAbroad, account.processedDate);
            allTxns.push(...txns);
          }
        });
        if (!options.combineInstallments) {
          allTxns = (0, _transactions.fixInstallments)(allTxns);
        }
        if (options.outputData?.enableTransactionsFilterByDate ?? true) {
          allTxns = (0, _transactions.filterOldTransactions)(allTxns, startMoment, options.combineInstallments || false);
        }
        accountTxns[account.accountNumber] = {
          accountNumber: account.accountNumber,
          index: account.index,
          txns: allTxns
        };
      }
    });
    return accountTxns;
  }
  return {};
}
function getTransactionExtraDetails(servicesUrl, month, accountIndex, transaction) {
  const moedChiuv = month.format('MMYYYY');
  return (0, _buildUrl.default)(servicesUrl, {
    queryParams: {
      reqName: 'PirteyIska_204',
      CardIndex: accountIndex.toString(),
      shovarRatz: transaction.identifier.toString(),
      moedChiuv
    }
  });
}
async function getExtraScrapTransaction(page, options, month, accountIndex, transaction) {
  const dataUrl = getTransactionExtraDetails(options.servicesUrl, month, accountIndex, transaction);
  const data = await (0, _fetch.fetchGetWithinPage)(page, dataUrl);
  if (!data) {
    return transaction;
  }
  const rawCategory = _lodash.default.get(data, 'PirteyIska_204Bean.sector') ?? '';
  return {
    ...transaction,
    category: rawCategory.trim()
  };
}
function getExtraScrapTransactions(accountWithIndex, page, options, month) {
  const promises = accountWithIndex.txns.map(t => getExtraScrapTransaction(page, options, month, accountWithIndex.index, t));
  return Promise.all(promises);
}
async function getExtraScrapAccount(page, options, accountMap, month) {
  const promises = Object.keys(accountMap).map(async a => ({
    ...accountMap[a],
    txns: await getExtraScrapTransactions(accountMap[a], page, options, month)
  }));
  const accounts = await Promise.all(promises);
  return accounts.reduce((m, x) => ({
    ...m,
    [x.accountNumber]: x
  }), {});
}
function getExtraScrap(accountsWithIndex, page, options, allMonths) {
  const actions = accountsWithIndex.map((a, i) => () => getExtraScrapAccount(page, options, a, allMonths[i]));
  return (0, _waiting.runSerial)(actions);
}
async function fetchAllTransactions(page, options, companyServiceOptions, startMoment) {
  const futureMonthsToScrape = options.futureMonthsToScrape ?? 1;
  const allMonths = (0, _dates.default)(startMoment, futureMonthsToScrape);
  const results = await Promise.all(allMonths.map(async monthMoment => {
    return fetchTransactions(page, options, companyServiceOptions, startMoment, monthMoment);
  }));
  const finalResult = options.additionalTransactionInformation ? await getExtraScrap(results, page, companyServiceOptions, allMonths) : results;
  const combinedTxns = {};
  finalResult.forEach(result => {
    Object.keys(result).forEach(accountNumber => {
      let txnsForAccount = combinedTxns[accountNumber];
      if (!txnsForAccount) {
        txnsForAccount = [];
        combinedTxns[accountNumber] = txnsForAccount;
      }
      const toBeAddedTxns = result[accountNumber].txns;
      combinedTxns[accountNumber].push(...toBeAddedTxns);
    });
  });
  const accounts = Object.keys(combinedTxns).map(accountNumber => {
    return {
      accountNumber,
      txns: combinedTxns[accountNumber]
    };
  });
  return {
    success: true,
    accounts
  };
}
class IsracardAmexBaseScraper extends _baseScraperWithBrowser.BaseScraperWithBrowser {
  constructor(options, baseUrl, companyCode) {
    super(options);
    this.baseUrl = baseUrl;
    this.companyCode = companyCode;
    this.servicesUrl = `${baseUrl}/services/ProxyRequestHandler.ashx`;
  }
  async login(credentials) {
    await this.page.setRequestInterception(true);
    this.page.on('request', request => {
      if (request.url().includes('detector-dom.min.js')) {
        debug('force abort for request do download detector-dom.min.js resource');
        void request.abort(undefined, _browser.interceptionPriorities.abort);
      } else {
        void request.continue(undefined, _browser.interceptionPriorities.continue);
      }
    });
    await (0, _browser.maskHeadlessUserAgent)(this.page);
    await this.navigateTo(`${this.baseUrl}/personalarea/Login`);
    this.emitProgress(_definitions.ScraperProgressTypes.LoggingIn);
    const validateUrl = `${this.servicesUrl}?reqName=ValidateIdData`;
    const validateRequest = {
      id: credentials.id,
      cardSuffix: credentials.card6Digits,
      countryCode: COUNTRY_CODE,
      idType: ID_TYPE,
      checkLevel: '1',
      companyCode: this.companyCode
    };
    const validateResult = await (0, _fetch.fetchPostWithinPage)(this.page, validateUrl, validateRequest);
    if (!validateResult || !validateResult.Header || validateResult.Header.Status !== '1' || !validateResult.ValidateIdDataBean) {
      throw new Error('unknown error during login');
    }
    const validateReturnCode = validateResult.ValidateIdDataBean.returnCode;
    debug(`user validate with return code '${validateReturnCode}'`);
    if (validateReturnCode === '1') {
      const {
        userName
      } = validateResult.ValidateIdDataBean;
      const loginUrl = `${this.servicesUrl}?reqName=performLogonI`;
      const request = {
        KodMishtamesh: userName,
        MisparZihuy: credentials.id,
        Sisma: credentials.password,
        cardSuffix: credentials.card6Digits,
        countryCode: COUNTRY_CODE,
        idType: ID_TYPE
      };
      const loginResult = await (0, _fetch.fetchPostWithinPage)(this.page, loginUrl, request);
      debug(`user login with status '${loginResult?.status}'`);
      if (loginResult && loginResult.status === '1') {
        this.emitProgress(_definitions.ScraperProgressTypes.LoginSuccess);
        return {
          success: true
        };
      }
      if (loginResult && loginResult.status === '3') {
        this.emitProgress(_definitions.ScraperProgressTypes.ChangePassword);
        return {
          success: false,
          errorType: _errors.ScraperErrorTypes.ChangePassword
        };
      }
      this.emitProgress(_definitions.ScraperProgressTypes.LoginFailed);
      return {
        success: false,
        errorType: _errors.ScraperErrorTypes.InvalidPassword
      };
    }
    if (validateReturnCode === '4') {
      this.emitProgress(_definitions.ScraperProgressTypes.ChangePassword);
      return {
        success: false,
        errorType: _errors.ScraperErrorTypes.ChangePassword
      };
    }
    this.emitProgress(_definitions.ScraperProgressTypes.LoginFailed);
    return {
      success: false,
      errorType: _errors.ScraperErrorTypes.InvalidPassword
    };
  }
  async fetchData() {
    const defaultStartMoment = (0, _moment.default)().subtract(1, 'years');
    const startDate = this.options.startDate || defaultStartMoment.toDate();
    const startMoment = _moment.default.max(defaultStartMoment, (0, _moment.default)(startDate));
    return fetchAllTransactions(this.page, this.options, {
      servicesUrl: this.servicesUrl,
      companyCode: this.companyCode
    }, startMoment);
  }
}
var _default = exports.default = IsracardAmexBaseScraper;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfYnVpbGRVcmwiLCJfaW50ZXJvcFJlcXVpcmVEZWZhdWx0IiwicmVxdWlyZSIsIl9sb2Rhc2giLCJfbW9tZW50IiwiX2NvbnN0YW50cyIsIl9kZWZpbml0aW9ucyIsIl9kYXRlcyIsIl9kZWJ1ZyIsIl9mZXRjaCIsIl90cmFuc2FjdGlvbnMiLCJfd2FpdGluZyIsIl90cmFuc2FjdGlvbnMyIiwiX2Jhc2VTY3JhcGVyV2l0aEJyb3dzZXIiLCJfZXJyb3JzIiwiX2Jyb3dzZXIiLCJlIiwiX19lc01vZHVsZSIsImRlZmF1bHQiLCJDT1VOVFJZX0NPREUiLCJJRF9UWVBFIiwiSU5TVEFMTE1FTlRTX0tFWVdPUkQiLCJEQVRFX0ZPUk1BVCIsImRlYnVnIiwiZ2V0RGVidWciLCJnZXRBY2NvdW50c1VybCIsInNlcnZpY2VzVXJsIiwibW9udGhNb21lbnQiLCJiaWxsaW5nRGF0ZSIsImZvcm1hdCIsImJ1aWxkVXJsIiwicXVlcnlQYXJhbXMiLCJyZXFOYW1lIiwiYWN0aW9uQ29kZSIsImZldGNoQWNjb3VudHMiLCJwYWdlIiwiZGF0YVVybCIsImRhdGFSZXN1bHQiLCJmZXRjaEdldFdpdGhpblBhZ2UiLCJfIiwiZ2V0IiwiRGFzaGJvYXJkTW9udGhCZWFuIiwiY2FyZHNDaGFyZ2VzIiwibWFwIiwiY2FyZENoYXJnZSIsImluZGV4IiwicGFyc2VJbnQiLCJjYXJkSW5kZXgiLCJhY2NvdW50TnVtYmVyIiwiY2FyZE51bWJlciIsInByb2Nlc3NlZERhdGUiLCJtb21lbnQiLCJ0b0lTT1N0cmluZyIsImdldFRyYW5zYWN0aW9uc1VybCIsIm1vbnRoIiwieWVhciIsIm1vbnRoU3RyIiwidG9TdHJpbmciLCJyZXF1aXJlZERhdGUiLCJjb252ZXJ0Q3VycmVuY3kiLCJjdXJyZW5jeVN0ciIsIlNIRUtFTF9DVVJSRU5DWV9LRVlXT1JEIiwiQUxUX1NIRUtFTF9DVVJSRU5DWSIsIlNIRUtFTF9DVVJSRU5DWSIsImdldEluc3RhbGxtZW50c0luZm8iLCJ0eG4iLCJtb3JlSW5mbyIsImluY2x1ZGVzIiwidW5kZWZpbmVkIiwibWF0Y2hlcyIsIm1hdGNoIiwibGVuZ3RoIiwibnVtYmVyIiwidG90YWwiLCJnZXRUcmFuc2FjdGlvblR5cGUiLCJUcmFuc2FjdGlvblR5cGVzIiwiSW5zdGFsbG1lbnRzIiwiTm9ybWFsIiwiY29udmVydFRyYW5zYWN0aW9ucyIsInR4bnMiLCJmaWx0ZXJlZFR4bnMiLCJmaWx0ZXIiLCJkZWFsU3VtVHlwZSIsInZvdWNoZXJOdW1iZXJSYXR6Iiwidm91Y2hlck51bWJlclJhdHpPdXRib3VuZCIsImlzT3V0Ym91bmQiLCJkZWFsU3VtT3V0Ym91bmQiLCJ0eG5EYXRlU3RyIiwiZnVsbFB1cmNoYXNlRGF0ZU91dGJvdW5kIiwiZnVsbFB1cmNoYXNlRGF0ZSIsInR4bk1vbWVudCIsImN1cnJlbnRQcm9jZXNzZWREYXRlIiwiZnVsbFBheW1lbnREYXRlIiwicmVzdWx0IiwidHlwZSIsImlkZW50aWZpZXIiLCJkYXRlIiwib3JpZ2luYWxBbW91bnQiLCJkZWFsU3VtIiwib3JpZ2luYWxDdXJyZW5jeSIsImN1cnJlbnRQYXltZW50Q3VycmVuY3kiLCJjdXJyZW5jeUlkIiwiY2hhcmdlZEFtb3VudCIsInBheW1lbnRTdW1PdXRib3VuZCIsInBheW1lbnRTdW0iLCJjaGFyZ2VkQ3VycmVuY3kiLCJkZXNjcmlwdGlvbiIsImZ1bGxTdXBwbGllck5hbWVPdXRib3VuZCIsImZ1bGxTdXBwbGllck5hbWVIZWIiLCJtZW1vIiwiaW5zdGFsbG1lbnRzIiwic3RhdHVzIiwiVHJhbnNhY3Rpb25TdGF0dXNlcyIsIkNvbXBsZXRlZCIsImZldGNoVHJhbnNhY3Rpb25zIiwib3B0aW9ucyIsImNvbXBhbnlTZXJ2aWNlT3B0aW9ucyIsInN0YXJ0TW9tZW50IiwiYWNjb3VudHMiLCJDYXJkc1RyYW5zYWN0aW9uc0xpc3RCZWFuIiwiYWNjb3VudFR4bnMiLCJmb3JFYWNoIiwiYWNjb3VudCIsInR4bkdyb3VwcyIsImFsbFR4bnMiLCJ0eG5Hcm91cCIsInR4bklzcmFlbCIsInB1c2giLCJ0eG5BYnJvYWQiLCJjb21iaW5lSW5zdGFsbG1lbnRzIiwiZml4SW5zdGFsbG1lbnRzIiwib3V0cHV0RGF0YSIsImVuYWJsZVRyYW5zYWN0aW9uc0ZpbHRlckJ5RGF0ZSIsImZpbHRlck9sZFRyYW5zYWN0aW9ucyIsImdldFRyYW5zYWN0aW9uRXh0cmFEZXRhaWxzIiwiYWNjb3VudEluZGV4IiwidHJhbnNhY3Rpb24iLCJtb2VkQ2hpdXYiLCJDYXJkSW5kZXgiLCJzaG92YXJSYXR6IiwiZ2V0RXh0cmFTY3JhcFRyYW5zYWN0aW9uIiwiZGF0YSIsInJhd0NhdGVnb3J5IiwiY2F0ZWdvcnkiLCJ0cmltIiwiZ2V0RXh0cmFTY3JhcFRyYW5zYWN0aW9ucyIsImFjY291bnRXaXRoSW5kZXgiLCJwcm9taXNlcyIsInQiLCJQcm9taXNlIiwiYWxsIiwiZ2V0RXh0cmFTY3JhcEFjY291bnQiLCJhY2NvdW50TWFwIiwiT2JqZWN0Iiwia2V5cyIsImEiLCJyZWR1Y2UiLCJtIiwieCIsImdldEV4dHJhU2NyYXAiLCJhY2NvdW50c1dpdGhJbmRleCIsImFsbE1vbnRocyIsImFjdGlvbnMiLCJpIiwicnVuU2VyaWFsIiwiZmV0Y2hBbGxUcmFuc2FjdGlvbnMiLCJmdXR1cmVNb250aHNUb1NjcmFwZSIsImdldEFsbE1vbnRoTW9tZW50cyIsInJlc3VsdHMiLCJmaW5hbFJlc3VsdCIsImFkZGl0aW9uYWxUcmFuc2FjdGlvbkluZm9ybWF0aW9uIiwiY29tYmluZWRUeG5zIiwidHhuc0ZvckFjY291bnQiLCJ0b0JlQWRkZWRUeG5zIiwic3VjY2VzcyIsIklzcmFjYXJkQW1leEJhc2VTY3JhcGVyIiwiQmFzZVNjcmFwZXJXaXRoQnJvd3NlciIsImNvbnN0cnVjdG9yIiwiYmFzZVVybCIsImNvbXBhbnlDb2RlIiwibG9naW4iLCJjcmVkZW50aWFscyIsInNldFJlcXVlc3RJbnRlcmNlcHRpb24iLCJvbiIsInJlcXVlc3QiLCJ1cmwiLCJhYm9ydCIsImludGVyY2VwdGlvblByaW9yaXRpZXMiLCJjb250aW51ZSIsIm1hc2tIZWFkbGVzc1VzZXJBZ2VudCIsIm5hdmlnYXRlVG8iLCJlbWl0UHJvZ3Jlc3MiLCJTY3JhcGVyUHJvZ3Jlc3NUeXBlcyIsIkxvZ2dpbmdJbiIsInZhbGlkYXRlVXJsIiwidmFsaWRhdGVSZXF1ZXN0IiwiaWQiLCJjYXJkU3VmZml4IiwiY2FyZDZEaWdpdHMiLCJjb3VudHJ5Q29kZSIsImlkVHlwZSIsImNoZWNrTGV2ZWwiLCJ2YWxpZGF0ZVJlc3VsdCIsImZldGNoUG9zdFdpdGhpblBhZ2UiLCJIZWFkZXIiLCJTdGF0dXMiLCJWYWxpZGF0ZUlkRGF0YUJlYW4iLCJFcnJvciIsInZhbGlkYXRlUmV0dXJuQ29kZSIsInJldHVybkNvZGUiLCJ1c2VyTmFtZSIsImxvZ2luVXJsIiwiS29kTWlzaHRhbWVzaCIsIk1pc3BhclppaHV5IiwiU2lzbWEiLCJwYXNzd29yZCIsImxvZ2luUmVzdWx0IiwiTG9naW5TdWNjZXNzIiwiQ2hhbmdlUGFzc3dvcmQiLCJlcnJvclR5cGUiLCJTY3JhcGVyRXJyb3JUeXBlcyIsIkxvZ2luRmFpbGVkIiwiSW52YWxpZFBhc3N3b3JkIiwiZmV0Y2hEYXRhIiwiZGVmYXVsdFN0YXJ0TW9tZW50Iiwic3VidHJhY3QiLCJzdGFydERhdGUiLCJ0b0RhdGUiLCJtYXgiLCJfZGVmYXVsdCIsImV4cG9ydHMiXSwic291cmNlcyI6WyIuLi8uLi9zcmMvc2NyYXBlcnMvYmFzZS1pc3JhY2FyZC1hbWV4LnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBidWlsZFVybCBmcm9tICdidWlsZC11cmwnO1xuaW1wb3J0IF8gZnJvbSAnbG9kYXNoJztcbmltcG9ydCBtb21lbnQsIHsgdHlwZSBNb21lbnQgfSBmcm9tICdtb21lbnQnO1xuaW1wb3J0IHsgdHlwZSBQYWdlIH0gZnJvbSAncHVwcGV0ZWVyLWNvcmUnO1xuaW1wb3J0IHsgQUxUX1NIRUtFTF9DVVJSRU5DWSwgU0hFS0VMX0NVUlJFTkNZLCBTSEVLRUxfQ1VSUkVOQ1lfS0VZV09SRCB9IGZyb20gJy4uL2NvbnN0YW50cyc7XG5pbXBvcnQgeyBTY3JhcGVyUHJvZ3Jlc3NUeXBlcyB9IGZyb20gJy4uL2RlZmluaXRpb25zJztcbmltcG9ydCBnZXRBbGxNb250aE1vbWVudHMgZnJvbSAnLi4vaGVscGVycy9kYXRlcyc7XG5pbXBvcnQgeyBnZXREZWJ1ZyB9IGZyb20gJy4uL2hlbHBlcnMvZGVidWcnO1xuaW1wb3J0IHsgZmV0Y2hHZXRXaXRoaW5QYWdlLCBmZXRjaFBvc3RXaXRoaW5QYWdlIH0gZnJvbSAnLi4vaGVscGVycy9mZXRjaCc7XG5pbXBvcnQgeyBmaWx0ZXJPbGRUcmFuc2FjdGlvbnMsIGZpeEluc3RhbGxtZW50cyB9IGZyb20gJy4uL2hlbHBlcnMvdHJhbnNhY3Rpb25zJztcbmltcG9ydCB7IHJ1blNlcmlhbCB9IGZyb20gJy4uL2hlbHBlcnMvd2FpdGluZyc7XG5pbXBvcnQge1xuICBUcmFuc2FjdGlvblN0YXR1c2VzLFxuICBUcmFuc2FjdGlvblR5cGVzLFxuICB0eXBlIFRyYW5zYWN0aW9uLFxuICB0eXBlIFRyYW5zYWN0aW9uSW5zdGFsbG1lbnRzLFxuICB0eXBlIFRyYW5zYWN0aW9uc0FjY291bnQsXG59IGZyb20gJy4uL3RyYW5zYWN0aW9ucyc7XG5pbXBvcnQgeyBCYXNlU2NyYXBlcldpdGhCcm93c2VyIH0gZnJvbSAnLi9iYXNlLXNjcmFwZXItd2l0aC1icm93c2VyJztcbmltcG9ydCB7IFNjcmFwZXJFcnJvclR5cGVzIH0gZnJvbSAnLi9lcnJvcnMnO1xuaW1wb3J0IHsgdHlwZSBTY3JhcGVyT3B0aW9ucywgdHlwZSBTY3JhcGVyU2NyYXBpbmdSZXN1bHQgfSBmcm9tICcuL2ludGVyZmFjZSc7XG5pbXBvcnQgeyBpbnRlcmNlcHRpb25Qcmlvcml0aWVzLCBtYXNrSGVhZGxlc3NVc2VyQWdlbnQgfSBmcm9tICcuLi9oZWxwZXJzL2Jyb3dzZXInO1xuXG5jb25zdCBDT1VOVFJZX0NPREUgPSAnMjEyJztcbmNvbnN0IElEX1RZUEUgPSAnMSc7XG5jb25zdCBJTlNUQUxMTUVOVFNfS0VZV09SRCA9ICfXqtep15zXldedJztcblxuY29uc3QgREFURV9GT1JNQVQgPSAnREQvTU0vWVlZWSc7XG5cbmNvbnN0IGRlYnVnID0gZ2V0RGVidWcoJ2Jhc2UtaXNyYWNhcmQtYW1leCcpO1xuXG50eXBlIENvbXBhbnlTZXJ2aWNlT3B0aW9ucyA9IHtcbiAgc2VydmljZXNVcmw6IHN0cmluZztcbiAgY29tcGFueUNvZGU6IHN0cmluZztcbn07XG5cbnR5cGUgU2NyYXBlZEFjY291bnRzV2l0aEluZGV4ID0gUmVjb3JkPHN0cmluZywgVHJhbnNhY3Rpb25zQWNjb3VudCAmIHsgaW5kZXg6IG51bWJlciB9PjtcblxuaW50ZXJmYWNlIFNjcmFwZWRUcmFuc2FjdGlvbiB7XG4gIGRlYWxTdW1UeXBlOiBzdHJpbmc7XG4gIHZvdWNoZXJOdW1iZXJSYXR6T3V0Ym91bmQ6IHN0cmluZztcbiAgdm91Y2hlck51bWJlclJhdHo6IHN0cmluZztcbiAgbW9yZUluZm8/OiBzdHJpbmc7XG4gIGRlYWxTdW1PdXRib3VuZDogYm9vbGVhbjtcbiAgY3VycmVuY3lJZDogc3RyaW5nO1xuICBjdXJyZW50UGF5bWVudEN1cnJlbmN5OiBzdHJpbmc7XG4gIGRlYWxTdW06IG51bWJlcjtcbiAgZnVsbFBheW1lbnREYXRlPzogc3RyaW5nO1xuICBmdWxsUHVyY2hhc2VEYXRlPzogc3RyaW5nO1xuICBmdWxsUHVyY2hhc2VEYXRlT3V0Ym91bmQ/OiBzdHJpbmc7XG4gIGZ1bGxTdXBwbGllck5hbWVIZWI6IHN0cmluZztcbiAgZnVsbFN1cHBsaWVyTmFtZU91dGJvdW5kOiBzdHJpbmc7XG4gIHBheW1lbnRTdW06IG51bWJlcjtcbiAgcGF5bWVudFN1bU91dGJvdW5kOiBudW1iZXI7XG59XG5cbmludGVyZmFjZSBTY3JhcGVkQWNjb3VudCB7XG4gIGluZGV4OiBudW1iZXI7XG4gIGFjY291bnROdW1iZXI6IHN0cmluZztcbiAgcHJvY2Vzc2VkRGF0ZTogc3RyaW5nO1xufVxuXG5pbnRlcmZhY2UgU2NyYXBlZExvZ2luVmFsaWRhdGlvbiB7XG4gIEhlYWRlcjoge1xuICAgIFN0YXR1czogc3RyaW5nO1xuICB9O1xuICBWYWxpZGF0ZUlkRGF0YUJlYW4/OiB7XG4gICAgdXNlck5hbWU/OiBzdHJpbmc7XG4gICAgcmV0dXJuQ29kZTogc3RyaW5nO1xuICB9O1xufVxuXG5pbnRlcmZhY2UgU2NyYXBlZEFjY291bnRzV2l0aGluUGFnZVJlc3BvbnNlIHtcbiAgSGVhZGVyOiB7XG4gICAgU3RhdHVzOiBzdHJpbmc7XG4gIH07XG4gIERhc2hib2FyZE1vbnRoQmVhbj86IHtcbiAgICBjYXJkc0NoYXJnZXM6IHtcbiAgICAgIGNhcmRJbmRleDogc3RyaW5nO1xuICAgICAgY2FyZE51bWJlcjogc3RyaW5nO1xuICAgICAgYmlsbGluZ0RhdGU6IHN0cmluZztcbiAgICB9W107XG4gIH07XG59XG5cbmludGVyZmFjZSBTY3JhcGVkQ3VycmVudENhcmRUcmFuc2FjdGlvbnMge1xuICB0eG5Jc3JhZWw/OiBTY3JhcGVkVHJhbnNhY3Rpb25bXTtcbiAgdHhuQWJyb2FkPzogU2NyYXBlZFRyYW5zYWN0aW9uW107XG59XG5cbmludGVyZmFjZSBTY3JhcGVkVHJhbnNhY3Rpb25EYXRhIHtcbiAgSGVhZGVyPzoge1xuICAgIFN0YXR1czogc3RyaW5nO1xuICB9O1xuICBQaXJ0ZXlJc2thXzIwNEJlYW4/OiB7XG4gICAgc2VjdG9yOiBzdHJpbmc7XG4gIH07XG5cbiAgQ2FyZHNUcmFuc2FjdGlvbnNMaXN0QmVhbj86IFJlY29yZDxcbiAgICBzdHJpbmcsXG4gICAge1xuICAgICAgQ3VycmVudENhcmRUcmFuc2FjdGlvbnM6IFNjcmFwZWRDdXJyZW50Q2FyZFRyYW5zYWN0aW9uc1tdO1xuICAgIH1cbiAgPjtcbn1cblxuZnVuY3Rpb24gZ2V0QWNjb3VudHNVcmwoc2VydmljZXNVcmw6IHN0cmluZywgbW9udGhNb21lbnQ6IE1vbWVudCkge1xuICBjb25zdCBiaWxsaW5nRGF0ZSA9IG1vbnRoTW9tZW50LmZvcm1hdCgnWVlZWS1NTS1ERCcpO1xuICByZXR1cm4gYnVpbGRVcmwoc2VydmljZXNVcmwsIHtcbiAgICBxdWVyeVBhcmFtczoge1xuICAgICAgcmVxTmFtZTogJ0Rhc2hib2FyZE1vbnRoJyxcbiAgICAgIGFjdGlvbkNvZGU6ICcwJyxcbiAgICAgIGJpbGxpbmdEYXRlLFxuICAgICAgZm9ybWF0OiAnSnNvbicsXG4gICAgfSxcbiAgfSk7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGZldGNoQWNjb3VudHMocGFnZTogUGFnZSwgc2VydmljZXNVcmw6IHN0cmluZywgbW9udGhNb21lbnQ6IE1vbWVudCk6IFByb21pc2U8U2NyYXBlZEFjY291bnRbXT4ge1xuICBjb25zdCBkYXRhVXJsID0gZ2V0QWNjb3VudHNVcmwoc2VydmljZXNVcmwsIG1vbnRoTW9tZW50KTtcbiAgY29uc3QgZGF0YVJlc3VsdCA9IGF3YWl0IGZldGNoR2V0V2l0aGluUGFnZTxTY3JhcGVkQWNjb3VudHNXaXRoaW5QYWdlUmVzcG9uc2U+KHBhZ2UsIGRhdGFVcmwpO1xuICBpZiAoZGF0YVJlc3VsdCAmJiBfLmdldChkYXRhUmVzdWx0LCAnSGVhZGVyLlN0YXR1cycpID09PSAnMScgJiYgZGF0YVJlc3VsdC5EYXNoYm9hcmRNb250aEJlYW4pIHtcbiAgICBjb25zdCB7IGNhcmRzQ2hhcmdlcyB9ID0gZGF0YVJlc3VsdC5EYXNoYm9hcmRNb250aEJlYW47XG4gICAgaWYgKGNhcmRzQ2hhcmdlcykge1xuICAgICAgcmV0dXJuIGNhcmRzQ2hhcmdlcy5tYXAoY2FyZENoYXJnZSA9PiB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgaW5kZXg6IHBhcnNlSW50KGNhcmRDaGFyZ2UuY2FyZEluZGV4LCAxMCksXG4gICAgICAgICAgYWNjb3VudE51bWJlcjogY2FyZENoYXJnZS5jYXJkTnVtYmVyLFxuICAgICAgICAgIHByb2Nlc3NlZERhdGU6IG1vbWVudChjYXJkQ2hhcmdlLmJpbGxpbmdEYXRlLCBEQVRFX0ZPUk1BVCkudG9JU09TdHJpbmcoKSxcbiAgICAgICAgfTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuICByZXR1cm4gW107XG59XG5cbmZ1bmN0aW9uIGdldFRyYW5zYWN0aW9uc1VybChzZXJ2aWNlc1VybDogc3RyaW5nLCBtb250aE1vbWVudDogTW9tZW50KSB7XG4gIGNvbnN0IG1vbnRoID0gbW9udGhNb21lbnQubW9udGgoKSArIDE7XG4gIGNvbnN0IHllYXIgPSBtb250aE1vbWVudC55ZWFyKCk7XG4gIGNvbnN0IG1vbnRoU3RyID0gbW9udGggPCAxMCA/IGAwJHttb250aH1gIDogbW9udGgudG9TdHJpbmcoKTtcbiAgcmV0dXJuIGJ1aWxkVXJsKHNlcnZpY2VzVXJsLCB7XG4gICAgcXVlcnlQYXJhbXM6IHtcbiAgICAgIHJlcU5hbWU6ICdDYXJkc1RyYW5zYWN0aW9uc0xpc3QnLFxuICAgICAgbW9udGg6IG1vbnRoU3RyLFxuICAgICAgeWVhcjogYCR7eWVhcn1gLFxuICAgICAgcmVxdWlyZWREYXRlOiAnTicsXG4gICAgfSxcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIGNvbnZlcnRDdXJyZW5jeShjdXJyZW5jeVN0cjogc3RyaW5nKSB7XG4gIGlmIChjdXJyZW5jeVN0ciA9PT0gU0hFS0VMX0NVUlJFTkNZX0tFWVdPUkQgfHwgY3VycmVuY3lTdHIgPT09IEFMVF9TSEVLRUxfQ1VSUkVOQ1kpIHtcbiAgICByZXR1cm4gU0hFS0VMX0NVUlJFTkNZO1xuICB9XG4gIHJldHVybiBjdXJyZW5jeVN0cjtcbn1cblxuZnVuY3Rpb24gZ2V0SW5zdGFsbG1lbnRzSW5mbyh0eG46IFNjcmFwZWRUcmFuc2FjdGlvbik6IFRyYW5zYWN0aW9uSW5zdGFsbG1lbnRzIHwgdW5kZWZpbmVkIHtcbiAgaWYgKCF0eG4ubW9yZUluZm8gfHwgIXR4bi5tb3JlSW5mby5pbmNsdWRlcyhJTlNUQUxMTUVOVFNfS0VZV09SRCkpIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG4gIGNvbnN0IG1hdGNoZXMgPSB0eG4ubW9yZUluZm8ubWF0Y2goL1xcZCsvZyk7XG4gIGlmICghbWF0Y2hlcyB8fCBtYXRjaGVzLmxlbmd0aCA8IDIpIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBudW1iZXI6IHBhcnNlSW50KG1hdGNoZXNbMF0sIDEwKSxcbiAgICB0b3RhbDogcGFyc2VJbnQobWF0Y2hlc1sxXSwgMTApLFxuICB9O1xufVxuXG5mdW5jdGlvbiBnZXRUcmFuc2FjdGlvblR5cGUodHhuOiBTY3JhcGVkVHJhbnNhY3Rpb24pIHtcbiAgcmV0dXJuIGdldEluc3RhbGxtZW50c0luZm8odHhuKSA/IFRyYW5zYWN0aW9uVHlwZXMuSW5zdGFsbG1lbnRzIDogVHJhbnNhY3Rpb25UeXBlcy5Ob3JtYWw7XG59XG5cbmZ1bmN0aW9uIGNvbnZlcnRUcmFuc2FjdGlvbnModHhuczogU2NyYXBlZFRyYW5zYWN0aW9uW10sIHByb2Nlc3NlZERhdGU6IHN0cmluZyk6IFRyYW5zYWN0aW9uW10ge1xuICBjb25zdCBmaWx0ZXJlZFR4bnMgPSB0eG5zLmZpbHRlcihcbiAgICB0eG4gPT5cbiAgICAgIHR4bi5kZWFsU3VtVHlwZSAhPT0gJzEnICYmIHR4bi52b3VjaGVyTnVtYmVyUmF0eiAhPT0gJzAwMDAwMDAwMCcgJiYgdHhuLnZvdWNoZXJOdW1iZXJSYXR6T3V0Ym91bmQgIT09ICcwMDAwMDAwMDAnLFxuICApO1xuXG4gIHJldHVybiBmaWx0ZXJlZFR4bnMubWFwKHR4biA9PiB7XG4gICAgY29uc3QgaXNPdXRib3VuZCA9IHR4bi5kZWFsU3VtT3V0Ym91bmQ7XG4gICAgY29uc3QgdHhuRGF0ZVN0ciA9IGlzT3V0Ym91bmQgPyB0eG4uZnVsbFB1cmNoYXNlRGF0ZU91dGJvdW5kIDogdHhuLmZ1bGxQdXJjaGFzZURhdGU7XG4gICAgY29uc3QgdHhuTW9tZW50ID0gbW9tZW50KHR4bkRhdGVTdHIsIERBVEVfRk9STUFUKTtcblxuICAgIGNvbnN0IGN1cnJlbnRQcm9jZXNzZWREYXRlID0gdHhuLmZ1bGxQYXltZW50RGF0ZVxuICAgICAgPyBtb21lbnQodHhuLmZ1bGxQYXltZW50RGF0ZSwgREFURV9GT1JNQVQpLnRvSVNPU3RyaW5nKClcbiAgICAgIDogcHJvY2Vzc2VkRGF0ZTtcbiAgICBjb25zdCByZXN1bHQ6IFRyYW5zYWN0aW9uID0ge1xuICAgICAgdHlwZTogZ2V0VHJhbnNhY3Rpb25UeXBlKHR4biksXG4gICAgICBpZGVudGlmaWVyOiBwYXJzZUludChpc091dGJvdW5kID8gdHhuLnZvdWNoZXJOdW1iZXJSYXR6T3V0Ym91bmQgOiB0eG4udm91Y2hlck51bWJlclJhdHosIDEwKSxcbiAgICAgIGRhdGU6IHR4bk1vbWVudC50b0lTT1N0cmluZygpLFxuICAgICAgcHJvY2Vzc2VkRGF0ZTogY3VycmVudFByb2Nlc3NlZERhdGUsXG4gICAgICBvcmlnaW5hbEFtb3VudDogaXNPdXRib3VuZCA/IC10eG4uZGVhbFN1bU91dGJvdW5kIDogLXR4bi5kZWFsU3VtLFxuICAgICAgb3JpZ2luYWxDdXJyZW5jeTogY29udmVydEN1cnJlbmN5KHR4bi5jdXJyZW50UGF5bWVudEN1cnJlbmN5ID8/IHR4bi5jdXJyZW5jeUlkKSxcbiAgICAgIGNoYXJnZWRBbW91bnQ6IGlzT3V0Ym91bmQgPyAtdHhuLnBheW1lbnRTdW1PdXRib3VuZCA6IC10eG4ucGF5bWVudFN1bSxcbiAgICAgIGNoYXJnZWRDdXJyZW5jeTogY29udmVydEN1cnJlbmN5KHR4bi5jdXJyZW5jeUlkKSxcbiAgICAgIGRlc2NyaXB0aW9uOiBpc091dGJvdW5kID8gdHhuLmZ1bGxTdXBwbGllck5hbWVPdXRib3VuZCA6IHR4bi5mdWxsU3VwcGxpZXJOYW1lSGViLFxuICAgICAgbWVtbzogdHhuLm1vcmVJbmZvIHx8ICcnLFxuICAgICAgaW5zdGFsbG1lbnRzOiBnZXRJbnN0YWxsbWVudHNJbmZvKHR4bikgfHwgdW5kZWZpbmVkLFxuICAgICAgc3RhdHVzOiBUcmFuc2FjdGlvblN0YXR1c2VzLkNvbXBsZXRlZCxcbiAgICB9O1xuXG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfSk7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGZldGNoVHJhbnNhY3Rpb25zKFxuICBwYWdlOiBQYWdlLFxuICBvcHRpb25zOiBTY3JhcGVyT3B0aW9ucyxcbiAgY29tcGFueVNlcnZpY2VPcHRpb25zOiBDb21wYW55U2VydmljZU9wdGlvbnMsXG4gIHN0YXJ0TW9tZW50OiBNb21lbnQsXG4gIG1vbnRoTW9tZW50OiBNb21lbnQsXG4pOiBQcm9taXNlPFNjcmFwZWRBY2NvdW50c1dpdGhJbmRleD4ge1xuICBjb25zdCBhY2NvdW50cyA9IGF3YWl0IGZldGNoQWNjb3VudHMocGFnZSwgY29tcGFueVNlcnZpY2VPcHRpb25zLnNlcnZpY2VzVXJsLCBtb250aE1vbWVudCk7XG4gIGNvbnN0IGRhdGFVcmwgPSBnZXRUcmFuc2FjdGlvbnNVcmwoY29tcGFueVNlcnZpY2VPcHRpb25zLnNlcnZpY2VzVXJsLCBtb250aE1vbWVudCk7XG4gIGNvbnN0IGRhdGFSZXN1bHQgPSBhd2FpdCBmZXRjaEdldFdpdGhpblBhZ2U8U2NyYXBlZFRyYW5zYWN0aW9uRGF0YT4ocGFnZSwgZGF0YVVybCk7XG4gIGlmIChkYXRhUmVzdWx0ICYmIF8uZ2V0KGRhdGFSZXN1bHQsICdIZWFkZXIuU3RhdHVzJykgPT09ICcxJyAmJiBkYXRhUmVzdWx0LkNhcmRzVHJhbnNhY3Rpb25zTGlzdEJlYW4pIHtcbiAgICBjb25zdCBhY2NvdW50VHhuczogU2NyYXBlZEFjY291bnRzV2l0aEluZGV4ID0ge307XG4gICAgYWNjb3VudHMuZm9yRWFjaChhY2NvdW50ID0+IHtcbiAgICAgIGNvbnN0IHR4bkdyb3VwczogU2NyYXBlZEN1cnJlbnRDYXJkVHJhbnNhY3Rpb25zW10gfCB1bmRlZmluZWQgPSBfLmdldChcbiAgICAgICAgZGF0YVJlc3VsdCxcbiAgICAgICAgYENhcmRzVHJhbnNhY3Rpb25zTGlzdEJlYW4uSW5kZXgke2FjY291bnQuaW5kZXh9LkN1cnJlbnRDYXJkVHJhbnNhY3Rpb25zYCxcbiAgICAgICk7XG4gICAgICBpZiAodHhuR3JvdXBzKSB7XG4gICAgICAgIGxldCBhbGxUeG5zOiBUcmFuc2FjdGlvbltdID0gW107XG4gICAgICAgIHR4bkdyb3Vwcy5mb3JFYWNoKHR4bkdyb3VwID0+IHtcbiAgICAgICAgICBpZiAodHhuR3JvdXAudHhuSXNyYWVsKSB7XG4gICAgICAgICAgICBjb25zdCB0eG5zID0gY29udmVydFRyYW5zYWN0aW9ucyh0eG5Hcm91cC50eG5Jc3JhZWwsIGFjY291bnQucHJvY2Vzc2VkRGF0ZSk7XG4gICAgICAgICAgICBhbGxUeG5zLnB1c2goLi4udHhucyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmICh0eG5Hcm91cC50eG5BYnJvYWQpIHtcbiAgICAgICAgICAgIGNvbnN0IHR4bnMgPSBjb252ZXJ0VHJhbnNhY3Rpb25zKHR4bkdyb3VwLnR4bkFicm9hZCwgYWNjb3VudC5wcm9jZXNzZWREYXRlKTtcbiAgICAgICAgICAgIGFsbFR4bnMucHVzaCguLi50eG5zKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGlmICghb3B0aW9ucy5jb21iaW5lSW5zdGFsbG1lbnRzKSB7XG4gICAgICAgICAgYWxsVHhucyA9IGZpeEluc3RhbGxtZW50cyhhbGxUeG5zKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAob3B0aW9ucy5vdXRwdXREYXRhPy5lbmFibGVUcmFuc2FjdGlvbnNGaWx0ZXJCeURhdGUgPz8gdHJ1ZSkge1xuICAgICAgICAgIGFsbFR4bnMgPSBmaWx0ZXJPbGRUcmFuc2FjdGlvbnMoYWxsVHhucywgc3RhcnRNb21lbnQsIG9wdGlvbnMuY29tYmluZUluc3RhbGxtZW50cyB8fCBmYWxzZSk7XG4gICAgICAgIH1cbiAgICAgICAgYWNjb3VudFR4bnNbYWNjb3VudC5hY2NvdW50TnVtYmVyXSA9IHtcbiAgICAgICAgICBhY2NvdW50TnVtYmVyOiBhY2NvdW50LmFjY291bnROdW1iZXIsXG4gICAgICAgICAgaW5kZXg6IGFjY291bnQuaW5kZXgsXG4gICAgICAgICAgdHhuczogYWxsVHhucyxcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gYWNjb3VudFR4bnM7XG4gIH1cblxuICByZXR1cm4ge307XG59XG5cbmZ1bmN0aW9uIGdldFRyYW5zYWN0aW9uRXh0cmFEZXRhaWxzKFxuICBzZXJ2aWNlc1VybDogc3RyaW5nLFxuICBtb250aDogTW9tZW50LFxuICBhY2NvdW50SW5kZXg6IG51bWJlcixcbiAgdHJhbnNhY3Rpb246IFRyYW5zYWN0aW9uLFxuKTogc3RyaW5nIHtcbiAgY29uc3QgbW9lZENoaXV2ID0gbW9udGguZm9ybWF0KCdNTVlZWVknKTtcbiAgcmV0dXJuIGJ1aWxkVXJsKHNlcnZpY2VzVXJsLCB7XG4gICAgcXVlcnlQYXJhbXM6IHtcbiAgICAgIHJlcU5hbWU6ICdQaXJ0ZXlJc2thXzIwNCcsXG4gICAgICBDYXJkSW5kZXg6IGFjY291bnRJbmRleC50b1N0cmluZygpLFxuICAgICAgc2hvdmFyUmF0ejogdHJhbnNhY3Rpb24uaWRlbnRpZmllciEudG9TdHJpbmcoKSxcbiAgICAgIG1vZWRDaGl1dixcbiAgICB9LFxuICB9KTtcbn1cbmFzeW5jIGZ1bmN0aW9uIGdldEV4dHJhU2NyYXBUcmFuc2FjdGlvbihcbiAgcGFnZTogUGFnZSxcbiAgb3B0aW9uczogQ29tcGFueVNlcnZpY2VPcHRpb25zLFxuICBtb250aDogTW9tZW50LFxuICBhY2NvdW50SW5kZXg6IG51bWJlcixcbiAgdHJhbnNhY3Rpb246IFRyYW5zYWN0aW9uLFxuKTogUHJvbWlzZTxUcmFuc2FjdGlvbj4ge1xuICBjb25zdCBkYXRhVXJsID0gZ2V0VHJhbnNhY3Rpb25FeHRyYURldGFpbHMob3B0aW9ucy5zZXJ2aWNlc1VybCwgbW9udGgsIGFjY291bnRJbmRleCwgdHJhbnNhY3Rpb24pO1xuICBjb25zdCBkYXRhID0gYXdhaXQgZmV0Y2hHZXRXaXRoaW5QYWdlPFNjcmFwZWRUcmFuc2FjdGlvbkRhdGE+KHBhZ2UsIGRhdGFVcmwpO1xuXG4gIGlmICghZGF0YSkge1xuICAgIHJldHVybiB0cmFuc2FjdGlvbjtcbiAgfVxuXG4gIGNvbnN0IHJhd0NhdGVnb3J5ID0gXy5nZXQoZGF0YSwgJ1BpcnRleUlza2FfMjA0QmVhbi5zZWN0b3InKSA/PyAnJztcbiAgcmV0dXJuIHtcbiAgICAuLi50cmFuc2FjdGlvbixcbiAgICBjYXRlZ29yeTogcmF3Q2F0ZWdvcnkudHJpbSgpLFxuICB9O1xufVxuXG5mdW5jdGlvbiBnZXRFeHRyYVNjcmFwVHJhbnNhY3Rpb25zKFxuICBhY2NvdW50V2l0aEluZGV4OiBUcmFuc2FjdGlvbnNBY2NvdW50ICYgeyBpbmRleDogbnVtYmVyIH0sXG4gIHBhZ2U6IFBhZ2UsXG4gIG9wdGlvbnM6IENvbXBhbnlTZXJ2aWNlT3B0aW9ucyxcbiAgbW9udGg6IG1vbWVudC5Nb21lbnQsXG4pOiBQcm9taXNlPFRyYW5zYWN0aW9uW10+IHtcbiAgY29uc3QgcHJvbWlzZXMgPSBhY2NvdW50V2l0aEluZGV4LnR4bnMubWFwKHQgPT5cbiAgICBnZXRFeHRyYVNjcmFwVHJhbnNhY3Rpb24ocGFnZSwgb3B0aW9ucywgbW9udGgsIGFjY291bnRXaXRoSW5kZXguaW5kZXgsIHQpLFxuICApO1xuICByZXR1cm4gUHJvbWlzZS5hbGwocHJvbWlzZXMpO1xufVxuXG5hc3luYyBmdW5jdGlvbiBnZXRFeHRyYVNjcmFwQWNjb3VudChcbiAgcGFnZTogUGFnZSxcbiAgb3B0aW9uczogQ29tcGFueVNlcnZpY2VPcHRpb25zLFxuICBhY2NvdW50TWFwOiBTY3JhcGVkQWNjb3VudHNXaXRoSW5kZXgsXG4gIG1vbnRoOiBtb21lbnQuTW9tZW50LFxuKTogUHJvbWlzZTxTY3JhcGVkQWNjb3VudHNXaXRoSW5kZXg+IHtcbiAgY29uc3QgcHJvbWlzZXMgPSBPYmplY3Qua2V5cyhhY2NvdW50TWFwKS5tYXAoYXN5bmMgYSA9PiAoe1xuICAgIC4uLmFjY291bnRNYXBbYV0sXG4gICAgdHhuczogYXdhaXQgZ2V0RXh0cmFTY3JhcFRyYW5zYWN0aW9ucyhhY2NvdW50TWFwW2FdLCBwYWdlLCBvcHRpb25zLCBtb250aCksXG4gIH0pKTtcbiAgY29uc3QgYWNjb3VudHMgPSBhd2FpdCBQcm9taXNlLmFsbChwcm9taXNlcyk7XG4gIHJldHVybiBhY2NvdW50cy5yZWR1Y2UoKG0sIHgpID0+ICh7IC4uLm0sIFt4LmFjY291bnROdW1iZXJdOiB4IH0pLCB7fSk7XG59XG5cbmZ1bmN0aW9uIGdldEV4dHJhU2NyYXAoXG4gIGFjY291bnRzV2l0aEluZGV4OiBTY3JhcGVkQWNjb3VudHNXaXRoSW5kZXhbXSxcbiAgcGFnZTogUGFnZSxcbiAgb3B0aW9uczogQ29tcGFueVNlcnZpY2VPcHRpb25zLFxuICBhbGxNb250aHM6IG1vbWVudC5Nb21lbnRbXSxcbik6IFByb21pc2U8U2NyYXBlZEFjY291bnRzV2l0aEluZGV4W10+IHtcbiAgY29uc3QgYWN0aW9ucyA9IGFjY291bnRzV2l0aEluZGV4Lm1hcCgoYSwgaSkgPT4gKCkgPT4gZ2V0RXh0cmFTY3JhcEFjY291bnQocGFnZSwgb3B0aW9ucywgYSwgYWxsTW9udGhzW2ldKSk7XG4gIHJldHVybiBydW5TZXJpYWwoYWN0aW9ucyk7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGZldGNoQWxsVHJhbnNhY3Rpb25zKFxuICBwYWdlOiBQYWdlLFxuICBvcHRpb25zOiBTY3JhcGVyT3B0aW9ucyxcbiAgY29tcGFueVNlcnZpY2VPcHRpb25zOiBDb21wYW55U2VydmljZU9wdGlvbnMsXG4gIHN0YXJ0TW9tZW50OiBNb21lbnQsXG4pIHtcbiAgY29uc3QgZnV0dXJlTW9udGhzVG9TY3JhcGUgPSBvcHRpb25zLmZ1dHVyZU1vbnRoc1RvU2NyYXBlID8/IDE7XG4gIGNvbnN0IGFsbE1vbnRocyA9IGdldEFsbE1vbnRoTW9tZW50cyhzdGFydE1vbWVudCwgZnV0dXJlTW9udGhzVG9TY3JhcGUpO1xuICBjb25zdCByZXN1bHRzOiBTY3JhcGVkQWNjb3VudHNXaXRoSW5kZXhbXSA9IGF3YWl0IFByb21pc2UuYWxsKFxuICAgIGFsbE1vbnRocy5tYXAoYXN5bmMgbW9udGhNb21lbnQgPT4ge1xuICAgICAgcmV0dXJuIGZldGNoVHJhbnNhY3Rpb25zKHBhZ2UsIG9wdGlvbnMsIGNvbXBhbnlTZXJ2aWNlT3B0aW9ucywgc3RhcnRNb21lbnQsIG1vbnRoTW9tZW50KTtcbiAgICB9KSxcbiAgKTtcblxuICBjb25zdCBmaW5hbFJlc3VsdCA9IG9wdGlvbnMuYWRkaXRpb25hbFRyYW5zYWN0aW9uSW5mb3JtYXRpb25cbiAgICA/IGF3YWl0IGdldEV4dHJhU2NyYXAocmVzdWx0cywgcGFnZSwgY29tcGFueVNlcnZpY2VPcHRpb25zLCBhbGxNb250aHMpXG4gICAgOiByZXN1bHRzO1xuXG4gIGNvbnN0IGNvbWJpbmVkVHhuczogUmVjb3JkPHN0cmluZywgVHJhbnNhY3Rpb25bXT4gPSB7fTtcblxuICBmaW5hbFJlc3VsdC5mb3JFYWNoKHJlc3VsdCA9PiB7XG4gICAgT2JqZWN0LmtleXMocmVzdWx0KS5mb3JFYWNoKGFjY291bnROdW1iZXIgPT4ge1xuICAgICAgbGV0IHR4bnNGb3JBY2NvdW50ID0gY29tYmluZWRUeG5zW2FjY291bnROdW1iZXJdO1xuICAgICAgaWYgKCF0eG5zRm9yQWNjb3VudCkge1xuICAgICAgICB0eG5zRm9yQWNjb3VudCA9IFtdO1xuICAgICAgICBjb21iaW5lZFR4bnNbYWNjb3VudE51bWJlcl0gPSB0eG5zRm9yQWNjb3VudDtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHRvQmVBZGRlZFR4bnMgPSByZXN1bHRbYWNjb3VudE51bWJlcl0udHhucztcbiAgICAgIGNvbWJpbmVkVHhuc1thY2NvdW50TnVtYmVyXS5wdXNoKC4uLnRvQmVBZGRlZFR4bnMpO1xuICAgIH0pO1xuICB9KTtcblxuICBjb25zdCBhY2NvdW50cyA9IE9iamVjdC5rZXlzKGNvbWJpbmVkVHhucykubWFwKGFjY291bnROdW1iZXIgPT4ge1xuICAgIHJldHVybiB7XG4gICAgICBhY2NvdW50TnVtYmVyLFxuICAgICAgdHhuczogY29tYmluZWRUeG5zW2FjY291bnROdW1iZXJdLFxuICAgIH07XG4gIH0pO1xuXG4gIHJldHVybiB7XG4gICAgc3VjY2VzczogdHJ1ZSxcbiAgICBhY2NvdW50cyxcbiAgfTtcbn1cblxudHlwZSBTY3JhcGVyU3BlY2lmaWNDcmVkZW50aWFscyA9IHsgaWQ6IHN0cmluZzsgcGFzc3dvcmQ6IHN0cmluZzsgY2FyZDZEaWdpdHM6IHN0cmluZyB9O1xuY2xhc3MgSXNyYWNhcmRBbWV4QmFzZVNjcmFwZXIgZXh0ZW5kcyBCYXNlU2NyYXBlcldpdGhCcm93c2VyPFNjcmFwZXJTcGVjaWZpY0NyZWRlbnRpYWxzPiB7XG4gIHByaXZhdGUgYmFzZVVybDogc3RyaW5nO1xuXG4gIHByaXZhdGUgY29tcGFueUNvZGU6IHN0cmluZztcblxuICBwcml2YXRlIHNlcnZpY2VzVXJsOiBzdHJpbmc7XG5cbiAgY29uc3RydWN0b3Iob3B0aW9uczogU2NyYXBlck9wdGlvbnMsIGJhc2VVcmw6IHN0cmluZywgY29tcGFueUNvZGU6IHN0cmluZykge1xuICAgIHN1cGVyKG9wdGlvbnMpO1xuXG4gICAgdGhpcy5iYXNlVXJsID0gYmFzZVVybDtcbiAgICB0aGlzLmNvbXBhbnlDb2RlID0gY29tcGFueUNvZGU7XG4gICAgdGhpcy5zZXJ2aWNlc1VybCA9IGAke2Jhc2VVcmx9L3NlcnZpY2VzL1Byb3h5UmVxdWVzdEhhbmRsZXIuYXNoeGA7XG4gIH1cblxuICBhc3luYyBsb2dpbihjcmVkZW50aWFsczogU2NyYXBlclNwZWNpZmljQ3JlZGVudGlhbHMpOiBQcm9taXNlPFNjcmFwZXJTY3JhcGluZ1Jlc3VsdD4ge1xuICAgIGF3YWl0IHRoaXMucGFnZS5zZXRSZXF1ZXN0SW50ZXJjZXB0aW9uKHRydWUpO1xuICAgIHRoaXMucGFnZS5vbigncmVxdWVzdCcsIHJlcXVlc3QgPT4ge1xuICAgICAgaWYgKHJlcXVlc3QudXJsKCkuaW5jbHVkZXMoJ2RldGVjdG9yLWRvbS5taW4uanMnKSkge1xuICAgICAgICBkZWJ1ZygnZm9yY2UgYWJvcnQgZm9yIHJlcXVlc3QgZG8gZG93bmxvYWQgZGV0ZWN0b3ItZG9tLm1pbi5qcyByZXNvdXJjZScpO1xuICAgICAgICB2b2lkIHJlcXVlc3QuYWJvcnQodW5kZWZpbmVkLCBpbnRlcmNlcHRpb25Qcmlvcml0aWVzLmFib3J0KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHZvaWQgcmVxdWVzdC5jb250aW51ZSh1bmRlZmluZWQsIGludGVyY2VwdGlvblByaW9yaXRpZXMuY29udGludWUpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgYXdhaXQgbWFza0hlYWRsZXNzVXNlckFnZW50KHRoaXMucGFnZSk7XG5cbiAgICBhd2FpdCB0aGlzLm5hdmlnYXRlVG8oYCR7dGhpcy5iYXNlVXJsfS9wZXJzb25hbGFyZWEvTG9naW5gKTtcblxuICAgIHRoaXMuZW1pdFByb2dyZXNzKFNjcmFwZXJQcm9ncmVzc1R5cGVzLkxvZ2dpbmdJbik7XG5cbiAgICBjb25zdCB2YWxpZGF0ZVVybCA9IGAke3RoaXMuc2VydmljZXNVcmx9P3JlcU5hbWU9VmFsaWRhdGVJZERhdGFgO1xuICAgIGNvbnN0IHZhbGlkYXRlUmVxdWVzdCA9IHtcbiAgICAgIGlkOiBjcmVkZW50aWFscy5pZCxcbiAgICAgIGNhcmRTdWZmaXg6IGNyZWRlbnRpYWxzLmNhcmQ2RGlnaXRzLFxuICAgICAgY291bnRyeUNvZGU6IENPVU5UUllfQ09ERSxcbiAgICAgIGlkVHlwZTogSURfVFlQRSxcbiAgICAgIGNoZWNrTGV2ZWw6ICcxJyxcbiAgICAgIGNvbXBhbnlDb2RlOiB0aGlzLmNvbXBhbnlDb2RlLFxuICAgIH07XG4gICAgY29uc3QgdmFsaWRhdGVSZXN1bHQgPSBhd2FpdCBmZXRjaFBvc3RXaXRoaW5QYWdlPFNjcmFwZWRMb2dpblZhbGlkYXRpb24+KHRoaXMucGFnZSwgdmFsaWRhdGVVcmwsIHZhbGlkYXRlUmVxdWVzdCk7XG4gICAgaWYgKFxuICAgICAgIXZhbGlkYXRlUmVzdWx0IHx8XG4gICAgICAhdmFsaWRhdGVSZXN1bHQuSGVhZGVyIHx8XG4gICAgICB2YWxpZGF0ZVJlc3VsdC5IZWFkZXIuU3RhdHVzICE9PSAnMScgfHxcbiAgICAgICF2YWxpZGF0ZVJlc3VsdC5WYWxpZGF0ZUlkRGF0YUJlYW5cbiAgICApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcigndW5rbm93biBlcnJvciBkdXJpbmcgbG9naW4nKTtcbiAgICB9XG5cbiAgICBjb25zdCB2YWxpZGF0ZVJldHVybkNvZGUgPSB2YWxpZGF0ZVJlc3VsdC5WYWxpZGF0ZUlkRGF0YUJlYW4ucmV0dXJuQ29kZTtcbiAgICBkZWJ1ZyhgdXNlciB2YWxpZGF0ZSB3aXRoIHJldHVybiBjb2RlICcke3ZhbGlkYXRlUmV0dXJuQ29kZX0nYCk7XG4gICAgaWYgKHZhbGlkYXRlUmV0dXJuQ29kZSA9PT0gJzEnKSB7XG4gICAgICBjb25zdCB7IHVzZXJOYW1lIH0gPSB2YWxpZGF0ZVJlc3VsdC5WYWxpZGF0ZUlkRGF0YUJlYW47XG5cbiAgICAgIGNvbnN0IGxvZ2luVXJsID0gYCR7dGhpcy5zZXJ2aWNlc1VybH0/cmVxTmFtZT1wZXJmb3JtTG9nb25JYDtcbiAgICAgIGNvbnN0IHJlcXVlc3QgPSB7XG4gICAgICAgIEtvZE1pc2h0YW1lc2g6IHVzZXJOYW1lLFxuICAgICAgICBNaXNwYXJaaWh1eTogY3JlZGVudGlhbHMuaWQsXG4gICAgICAgIFNpc21hOiBjcmVkZW50aWFscy5wYXNzd29yZCxcbiAgICAgICAgY2FyZFN1ZmZpeDogY3JlZGVudGlhbHMuY2FyZDZEaWdpdHMsXG4gICAgICAgIGNvdW50cnlDb2RlOiBDT1VOVFJZX0NPREUsXG4gICAgICAgIGlkVHlwZTogSURfVFlQRSxcbiAgICAgIH07XG4gICAgICBjb25zdCBsb2dpblJlc3VsdCA9IGF3YWl0IGZldGNoUG9zdFdpdGhpblBhZ2U8eyBzdGF0dXM6IHN0cmluZyB9Pih0aGlzLnBhZ2UsIGxvZ2luVXJsLCByZXF1ZXN0KTtcbiAgICAgIGRlYnVnKGB1c2VyIGxvZ2luIHdpdGggc3RhdHVzICcke2xvZ2luUmVzdWx0Py5zdGF0dXN9J2ApO1xuXG4gICAgICBpZiAobG9naW5SZXN1bHQgJiYgbG9naW5SZXN1bHQuc3RhdHVzID09PSAnMScpIHtcbiAgICAgICAgdGhpcy5lbWl0UHJvZ3Jlc3MoU2NyYXBlclByb2dyZXNzVHlwZXMuTG9naW5TdWNjZXNzKTtcbiAgICAgICAgcmV0dXJuIHsgc3VjY2VzczogdHJ1ZSB9O1xuICAgICAgfVxuXG4gICAgICBpZiAobG9naW5SZXN1bHQgJiYgbG9naW5SZXN1bHQuc3RhdHVzID09PSAnMycpIHtcbiAgICAgICAgdGhpcy5lbWl0UHJvZ3Jlc3MoU2NyYXBlclByb2dyZXNzVHlwZXMuQ2hhbmdlUGFzc3dvcmQpO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIHN1Y2Nlc3M6IGZhbHNlLFxuICAgICAgICAgIGVycm9yVHlwZTogU2NyYXBlckVycm9yVHlwZXMuQ2hhbmdlUGFzc3dvcmQsXG4gICAgICAgIH07XG4gICAgICB9XG5cbiAgICAgIHRoaXMuZW1pdFByb2dyZXNzKFNjcmFwZXJQcm9ncmVzc1R5cGVzLkxvZ2luRmFpbGVkKTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHN1Y2Nlc3M6IGZhbHNlLFxuICAgICAgICBlcnJvclR5cGU6IFNjcmFwZXJFcnJvclR5cGVzLkludmFsaWRQYXNzd29yZCxcbiAgICAgIH07XG4gICAgfVxuXG4gICAgaWYgKHZhbGlkYXRlUmV0dXJuQ29kZSA9PT0gJzQnKSB7XG4gICAgICB0aGlzLmVtaXRQcm9ncmVzcyhTY3JhcGVyUHJvZ3Jlc3NUeXBlcy5DaGFuZ2VQYXNzd29yZCk7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBzdWNjZXNzOiBmYWxzZSxcbiAgICAgICAgZXJyb3JUeXBlOiBTY3JhcGVyRXJyb3JUeXBlcy5DaGFuZ2VQYXNzd29yZCxcbiAgICAgIH07XG4gICAgfVxuXG4gICAgdGhpcy5lbWl0UHJvZ3Jlc3MoU2NyYXBlclByb2dyZXNzVHlwZXMuTG9naW5GYWlsZWQpO1xuICAgIHJldHVybiB7XG4gICAgICBzdWNjZXNzOiBmYWxzZSxcbiAgICAgIGVycm9yVHlwZTogU2NyYXBlckVycm9yVHlwZXMuSW52YWxpZFBhc3N3b3JkLFxuICAgIH07XG4gIH1cblxuICBhc3luYyBmZXRjaERhdGEoKSB7XG4gICAgY29uc3QgZGVmYXVsdFN0YXJ0TW9tZW50ID0gbW9tZW50KCkuc3VidHJhY3QoMSwgJ3llYXJzJyk7XG4gICAgY29uc3Qgc3RhcnREYXRlID0gdGhpcy5vcHRpb25zLnN0YXJ0RGF0ZSB8fCBkZWZhdWx0U3RhcnRNb21lbnQudG9EYXRlKCk7XG4gICAgY29uc3Qgc3RhcnRNb21lbnQgPSBtb21lbnQubWF4KGRlZmF1bHRTdGFydE1vbWVudCwgbW9tZW50KHN0YXJ0RGF0ZSkpO1xuXG4gICAgcmV0dXJuIGZldGNoQWxsVHJhbnNhY3Rpb25zKFxuICAgICAgdGhpcy5wYWdlLFxuICAgICAgdGhpcy5vcHRpb25zLFxuICAgICAge1xuICAgICAgICBzZXJ2aWNlc1VybDogdGhpcy5zZXJ2aWNlc1VybCxcbiAgICAgICAgY29tcGFueUNvZGU6IHRoaXMuY29tcGFueUNvZGUsXG4gICAgICB9LFxuICAgICAgc3RhcnRNb21lbnQsXG4gICAgKTtcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBJc3JhY2FyZEFtZXhCYXNlU2NyYXBlcjtcbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQUEsSUFBQUEsU0FBQSxHQUFBQyxzQkFBQSxDQUFBQyxPQUFBO0FBQ0EsSUFBQUMsT0FBQSxHQUFBRixzQkFBQSxDQUFBQyxPQUFBO0FBQ0EsSUFBQUUsT0FBQSxHQUFBSCxzQkFBQSxDQUFBQyxPQUFBO0FBRUEsSUFBQUcsVUFBQSxHQUFBSCxPQUFBO0FBQ0EsSUFBQUksWUFBQSxHQUFBSixPQUFBO0FBQ0EsSUFBQUssTUFBQSxHQUFBTixzQkFBQSxDQUFBQyxPQUFBO0FBQ0EsSUFBQU0sTUFBQSxHQUFBTixPQUFBO0FBQ0EsSUFBQU8sTUFBQSxHQUFBUCxPQUFBO0FBQ0EsSUFBQVEsYUFBQSxHQUFBUixPQUFBO0FBQ0EsSUFBQVMsUUFBQSxHQUFBVCxPQUFBO0FBQ0EsSUFBQVUsY0FBQSxHQUFBVixPQUFBO0FBT0EsSUFBQVcsdUJBQUEsR0FBQVgsT0FBQTtBQUNBLElBQUFZLE9BQUEsR0FBQVosT0FBQTtBQUVBLElBQUFh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