UNPKG

ngx-mat-lib

Version:

A bunch of utilities and components to use in your Angular 7+ apps!

587 lines (586 loc) 57.4 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ import { Injectable } from "@angular/core"; import { convertToParamMap } from "@angular/router"; import { MatDialog, MatDialogConfig, MatSnackBar, MatSnackBarConfig } from "@angular/material"; import { XmatConfirmDialogComponent, XmatAlertDialogComponent } from "../components/xmat-dialog/index"; import { XmatAlertTypes, XmatSnackBarDataTypes } from "../models/index"; import { XmatConstantsService, XMAT_CONSTANT_LABELS } from "./xmat-constants.service"; import { XmatSnackBarComponent } from "../components/xmat-snack-bar/index"; import { Observable, forkJoin } from "rxjs"; import { map } from "rxjs/operators"; import { each, includes, extend } from "lodash"; import { parseZone as moment } from "moment"; /** @typedef {?} */ var XmatObservablesMap; /** @type {?} */ const colorParams = { center: 128, diversity: 10, width: 127 }; /** @type {?} */ const hexValues = "0123456789ABCDEF"; /** @type {?} */ const byte2Hex = (n) => { // tslint:disable-next-line:no-bitwise return String(hexValues.substr((n >> 4) & 0x0F, 1)) + hexValues.substr(n & 0x0F, 1); }; const ɵ0 = byte2Hex; /** @type {?} */ const rgb2Hex = (r, g, b) => { return "#" + byte2Hex(r) + byte2Hex(g) + byte2Hex(b); }; const ɵ1 = rgb2Hex; /** @type {?} */ const eachEnum = (srcEnum, iteratee) => { /** @type {?} */ const target = []; each(srcEnum, (key) => { // Continue if key is not a number if (typeof srcEnum[key] !== typeof 0) { return true; } target.push(srcEnum[key]); }); return each(target, iteratee); }; const ɵ2 = eachEnum; /** * THIS SERVICE REQUIRES 3 DEPENDENCIES: * XmatConstantsService, XmatSnackBarModule and XmatDialogModule */ export class XmatFunctionsService { /** * @param {?} _dialog * @param {?} _snackBar * @param {?} _xmatConstants */ constructor(_dialog, _snackBar, _xmatConstants) { this._dialog = _dialog; this._snackBar = _snackBar; this._xmatConstants = _xmatConstants; this._confirmDialogDefaults = { confirmText: XMAT_CONSTANT_LABELS.confirm, cancelText: XMAT_CONSTANT_LABELS.cancel, dialogContent: XMAT_CONSTANT_LABELS.proceed, hideCancelButton: false, confirmColor: "warn", title: XMAT_CONSTANT_LABELS.warningTitle }; this._colorDb = { factor: colorParams.width + colorParams.center, frequency: Math.PI * 2 / colorParams.diversity, generated: [] }; this._defaultAlertData = { type: XmatAlertTypes.warning, title: XMAT_CONSTANT_LABELS.warningTitle, confirmText: XMAT_CONSTANT_LABELS.confirm, cancelText: XMAT_CONSTANT_LABELS.cancel }; } /** * PUBLIC FUNCTIONS * @param {?} n * @return {?} */ addLeadingZeroes(n) { return ("0" + n).slice(-2); } /** * @param {?} source * @param {?=} level * @return {?} */ createReflectionModel(source, level = 0) { // For both arrays and objects if (!!source && typeof source === typeof {}) { /** @type {?} */ const target = Array.isArray(source) ? [] : {}; /** @type {?} */ const sourceKeys = Object.keys(source); // new Object(); for (let i = 0; i < sourceKeys.length; i++) { /** @type {?} */ const key = sourceKeys[i]; // Always create new key on the target, it will eventually be converted to object // For both arrays and objects return target[key] = this.createReflectionModel(source[key], level + 1); } return target; } else { return void 0; } } /** * @param {?=} date * @param {?=} months * @return {?} */ dateAddMonths(date = new Date(), months = 0) { /** @type {?} */ const day = date.getDate(); date.setMonth(date.getMonth() + +months); if (date.getDate() !== day) { date.setDate(0); } return date; } /** * @param {?} srcEnum * @param {?} iteratee * @return {?} */ eachEnum(srcEnum, iteratee) { return eachEnum(srcEnum, iteratee); } /** * @template T * @param {?} array * @param {?} index * @param {?} iteratee * @return {?} */ eachFrom(array, index, iteratee) { if (!Array.isArray(array)) { console.error(`eachFrom only accept arrays as source, found instead ${typeof array}`); return array; } /** @type {?} */ let _index = index == null ? -1 : index; /** @type {?} */ const length = array == null ? 0 : array.length; while (++_index < length) { if (iteratee(array[_index], _index, array) === false) { break; } } return array; } /** * @param {?=} queryString * @return {?} */ extractQueryParams(queryString = location.search) { /** @type {?} */ const query = {}; /** @type {?} */ const pairs = (queryString[0] === "?" ? queryString.substr(1) : queryString).split("&"); each(pairs, pair => { /** @type {?} */ const key = decodeURIComponent(pair.split("=")[0]); if (!!key) { query[key] = decodeURIComponent(pair.split("=")[1] || ""); } }); return convertToParamMap(query); } /** * @param {?} original * @param {?=} exclude * @return {?} */ filterProps(original, exclude = []) { if (original !== Object(original)) { console.error("TidUtils => Argument was not valid object", original); return; } if (Array.isArray(exclude) && exclude.length) { return Object.keys(original).reduce((obj, key) => { if (!includes(exclude, key)) { obj[key] = original[key]; } return obj; }, {}); } return original; } /** * This function generates vibrant, "evenly spaced" colours (i.e. no clustering). * This is ideal for creating easily distinguishable vibrant markers in Google Maps and other apps. * * @param {?=} steps * @param {?=} step * @return {?} */ getRainbow(steps = 10, step = 0) { /** @type {?} */ let r; /** @type {?} */ let g; /** @type {?} */ let b; /** @type {?} */ const h = step / steps; /** @type {?} */ const i = ~~(h * 6); /** @type {?} */ const f = h * 6 - i; /** @type {?} */ const q = 1 - f; switch (i % 6) { case 0: r = 1, g = f, b = 0; break; case 1: r = q, g = 1, b = 0; break; case 2: r = 0, g = 1, b = f; break; case 3: r = 0, g = q, b = 1; break; case 4: r = f, g = 0, b = 1; break; case 5: r = 1, g = 0, b = q; break; } /** @type {?} */ const red = ("00" + (~~(r * 255)).toString(16)).slice(-2); /** @type {?} */ const green = ("00" + (~~(g * 255)).toString(16)).slice(-2); /** @type {?} */ const blue = ("00" + (~~(b * 255)).toString(16)).slice(-2); return ("#" + red + green + blue); } /** * @param {?=} phase * @return {?} */ getRandomNonConsecutiveHex(phase = 10) { /** @type {?} */ const index = this._colorDb.generated.length + 1; /** @type {?} */ const red = Math.sin(this._colorDb.frequency * index + 2 + phase) * this._colorDb.factor; /** @type {?} */ const green = Math.sin(this._colorDb.frequency * index + phase) * this._colorDb.factor; /** @type {?} */ const blue = Math.sin(this._colorDb.frequency * index + 4 + phase) * this._colorDb.factor; /** @type {?} */ const result = rgb2Hex(red, green, blue); this._colorDb.generated.push(result); return result; } /** * @param {?} value * @return {?} */ isNumeric(value) { return !isNaN(parseInt(value, 10)); } /** * @param {?} value * @return {?} */ isValidLength(value) { return this.isNumeric(value) && value >= 0; } /** * @param {?} title * @param {?} msg * @param {?} color * @param {?} content * @return {?} */ logWithStyle(title, msg, color, content) { console.group(title || ""); console.log("%c" + msg, `color: ${color}`, content); console.groupEnd(); } /** * * @template T * @param {?} source the source object * @param {?=} keys allows to order the result and/or include only certain props * @param {?=} keepVoid * @return {?} */ objectToArray(source, keys = Object.keys(source), keepVoid = !1) { /** @type {?} */ const result = []; each(keys, (k) => { source[k] !== void 0 && result.push({ description: k, value: source[k] }); }); return result; } /** * @param {?=} data * @param {?=} returnRef * @return {?} */ openAlertDialog(data = this._defaultAlertData, // tslint:disable-next-line:max-line-length returnRef = false) { data = extend({}, this._defaultAlertData, data); /** @type {?} */ const dialogConfig = new MatDialogConfig(); extend(dialogConfig, { id: data.dialogId, width: this._xmatConstants.dialogOptions.defaultWidth, data: data, disableClose: true }); /** @type {?} */ const dialogRef = this._dialog.open(XmatAlertDialogComponent, dialogConfig); if (returnRef) { return dialogRef; } else { return new Observable(observer => { // Catch result dialogRef.afterClosed().subscribe((result) => { observer.next(result); observer.complete(); }); }); } } /** * @param {?=} data * @param {?=} disableClose * @param {?=} width * @param {?=} returnRef * @return {?} */ openConfirmDialog(data, disableClose = false, width = this._xmatConstants.dialogOptions.defaultWidth, // tslint:disable-next-line:max-line-length returnRef = false) { /** @type {?} */ const dialogConfig = new MatDialogConfig(); extend(dialogConfig, { id: data.dialogId, width: width, data: /** @type {?} */ (Object.assign({}, this._confirmDialogDefaults, data)), disableClose: disableClose }); /** @type {?} */ const dialogRef = this._dialog.open(XmatConfirmDialogComponent, dialogConfig); if (returnRef) { return dialogRef; } else { return new Observable(observer => { // Catch result dialogRef.afterClosed().subscribe((result) => { observer.next(result); observer.complete(); }); }); } } /** * @param {?} value * @return {?} */ parseDate(value) { if (!value) { return void 0; } /** @type {?} */ const momentDate = moment(value); if (!momentDate.isValid()) { return this._parseDateFallback(value); } return moment(momentDate).toDate(); } /** * @param {?} source * @return {?} */ readAsUrl(source) { return new Observable(observer => { /** @type {?} */ const reader = new FileReader(); reader.onload = (event) => { observer.next(event); observer.complete(); }; reader.onerror = reader.onabort = () => { observer.error(!1); }; reader.readAsDataURL(source); }); } /** * @param {?} haystack * @param {?} mapObj * @return {?} */ replaceAll(haystack, mapObj) { /** @type {?} */ const regExp = new RegExp(Object.keys(mapObj).join("|"), "gi"); return haystack.replace(regExp, function (matched) { return mapObj[matched.toLowerCase()]; }); } /** * @param {?=} data * @return {?} */ showSnackBar(data = { message: "-", showAction: false }) { return this._snackBar.openFromComponent(XmatSnackBarComponent, extend(new MatSnackBarConfig(), { data: data, duration: data.duration || 5000, panelClass: ["xmat-snack", data.type] })); } /** * Shortcut to open an XmatAlertDialog passing only an error message * @param {?=} msg * @param {?=} duration * @return {?} */ showErrorSnackBar(msg = this._xmatConstants.labels.genericError, duration = 5000) { return this.showSnackBar({ showAction: !1, message: msg, duration: duration, type: XmatSnackBarDataTypes.fail }); } /** * Shortcut to open an XmatAlertDialog passing only an error message * @param {?=} msg * @return {?} */ showErrorAlert(msg = this._xmatConstants.labels.genericError) { return this.openAlertDialog(/** @type {?} */ ({ type: XmatAlertTypes.error, title: this._xmatConstants.labels.errorTitle, dialogContent: msg, hideCancelButton: !0, hideConfirmButton: !1, confirmText: this._xmatConstants.labels.close })); } /** * Returns a formatted string using the first argument as a printf-like format. * * The first argument is a string that contains zero or more placeholders. * Each placeholder is replaced with the converted value from its corresponding argument. * * Supported placeholders are: * * %s - String. * %d - Number (both integer and float). * %% - single percent sign ('%'). This does not consume an argument. * @param {...?} args * @return {?} */ sprintf(...args) { /** @type {?} */ let index = 1; return (args[0] + "").replace(/%((\d)\$)?([sd%])/g, function (match, _group_, pos, _format_) { if (match === "%%") { return "%"; } if (typeof pos === "undefined") { pos = index++; } if (pos in args && pos > 0) { return args[pos]; } else { return match; } }); } /** * @param {?} str * @return {?} */ stripEmojis(str) { return str.replace(new RegExp(this._xmatConstants.regExps["emojis"], "g"), ""); } /** * @param {?} str * @return {?} */ stripSpecialChars(str) { return str.replace(new RegExp(this._xmatConstants.regExps["specialChars"], "g"), ""); } /** * @template T * @param {?} source * @return {?} */ $qMap(source) { /** @type {?} */ const queue = []; /** @type {?} */ const queueKeys = []; each(source, (o, key) => { queue.push(o); queueKeys.push(key); }); return forkJoin(queue) .pipe(map((raw) => { /** @type {?} */ const mapped = {}; each(raw, (value, index) => { mapped[queueKeys[index]] = value; }); return /** @type {?} */ (mapped); })); } /** * @template T * @param {?} source * @return {?} */ $qArray(source) { /** @type {?} */ const queue = []; each(source, (o) => { queue.push(o); }); return forkJoin(queue); } /** * @param {?} value * @return {?} */ _parseDateFallback(value) { if (typeof value === typeof 0 || !isNaN(+value)) { return new Date(+value); } else { return new Date(/** @type {?} */ (value)); } } } XmatFunctionsService.decorators = [ { type: Injectable } ]; /** @nocollapse */ XmatFunctionsService.ctorParameters = () => [ { type: MatDialog }, { type: MatSnackBar }, { type: XmatConstantsService } ]; if (false) { /** @type {?} */ XmatFunctionsService.prototype._confirmDialogDefaults; /** @type {?} */ XmatFunctionsService.prototype._colorDb; /** @type {?} */ XmatFunctionsService.prototype._defaultAlertData; /** @type {?} */ XmatFunctionsService.prototype._dialog; /** @type {?} */ XmatFunctionsService.prototype._snackBar; /** @type {?} */ XmatFunctionsService.prototype._xmatConstants; } export { ɵ0, ɵ1, ɵ2 }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoieG1hdC1mdW5jdGlvbnMuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiJuZzovL25neC1tYXQtbGliLyIsInNvdXJjZXMiOlsibGliL3NlcnZpY2VzL3htYXQtZnVuY3Rpb25zLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7OztBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDM0MsT0FBTyxFQUFvQixpQkFBaUIsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ3RFLE9BQU8sRUFDSCxTQUFTLEVBQ1QsZUFBZSxFQUNmLFdBQVcsRUFDWCxpQkFBaUIsRUFHcEIsTUFBTSxtQkFBbUIsQ0FBQztBQUUzQixPQUFPLEVBQ0gsMEJBQTBCLEVBQzFCLHdCQUF3QixFQUMzQixNQUFNLGlDQUFpQyxDQUFDO0FBQ3pDLE9BQU8sRUFFSCxjQUFjLEVBTWQscUJBQXFCLEVBRXhCLE1BQU0saUJBQWlCLENBQUM7QUFDekIsT0FBTyxFQUFFLG9CQUFvQixFQUFFLG9CQUFvQixFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDdEYsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sb0NBQW9DLENBQUM7QUFFM0UsT0FBTyxFQUFFLFVBQVUsRUFBRSxRQUFRLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDNUMsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ3JDLE9BQU8sRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxNQUFNLFFBQVEsQ0FBQztBQUNoRCxPQUFPLEVBQUUsU0FBUyxJQUFJLE1BQU0sRUFBRSxNQUFNLFFBQVEsQ0FBQzs7OztBQUk3QyxNQUFNLFdBQVcsR0FBRztJQUNoQixNQUFNLEVBQUUsR0FBRztJQUNYLFNBQVMsRUFBRSxFQUFFO0lBQ2IsS0FBSyxFQUFFLEdBQUc7Q0FDYixDQUFDOztBQUVGLE1BQU0sU0FBUyxHQUFXLGtCQUFrQixDQUFDOztBQUU3QyxNQUFNLFFBQVEsR0FBRyxDQUFD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RyxDQUFDLENBQUM7Z0JBQ3BCLE1BQU07WUFDVixLQUFLLENBQUM7Z0JBQ0YsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUM7Z0JBQ3BCLE1BQU07WUFDVixLQUFLLENBQUM7Z0JBQ0YsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUM7Z0JBQ3BCLE1BQU07WUFDVixLQUFLLENBQUM7Z0JBQ0YsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUM7Z0JBQ3BCLE1BQU07WUFDVixLQUFLLENBQUM7Z0JBQ0YsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUM7Z0JBQ3BCLE1BQU07U0FDYjs7UUFFRCxNQUFNLEdBQUcsR0FBRyxDQUFDLElBQUksR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDOztRQUUxRCxNQUFNLEtBQUssR0FBRyxDQUFDLElBQUksR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDOztRQUU1RCxNQUFNLElBQUksR0FBRyxDQUFDLElBQUksR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQzNELE9BQU8sQ0FBQyxHQUFHLEdBQUcsR0FBRyxHQUFHLEtBQUssR0FBRyxJQUFJLENBQUMsQ0FB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QUM7U0FDbEM7Ozs7WUFqYVIsVUFBVTs7OztZQWxFUCxTQUFTO1lBRVQsV0FBVztZQXFCTixvQkFBb0IiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSBcIkBhbmd1bGFyL2NvcmVcIjtcbmltcG9ydCB7IFBhcmFtTWFwLCBQYXJhbXMsIGNvbnZlcnRUb1BhcmFtTWFwIH0gZnJvbSBcIkBhbmd1bGFyL3JvdXRlclwiO1xuaW1wb3J0IHtcbiAgICBNYXREaWFsb2csXG4gICAgTWF0RGlhbG9nQ29uZmlnLFxuICAgIE1hdFNuYWNrQmFyLFxuICAgIE1hdFNuYWNrQmFyQ29uZmlnLFxuICAgIE1hdFNuYWNrQmFyUmVmLFxuICAgIE1hdERpYWxvZ1JlZlxufSBmcm9tIFwiQGFuZ3VsYXIvbWF0ZXJpYWxcIjtcbi8vXG5pbXBvcnQge1xuICAgIFhtYXRDb25maXJtRGlhbG9nQ29tcG9uZW50LFxuICAgIFhtYXRBbGVydERpYWxvZ0NvbXBvbmVudFxufSBmcm9tIFwiLi4vY29tcG9uZW50cy94bWF0LWRpYWxvZy9pbmRleFwiO1xuaW1wb3J0IHtcbiAgICBYbWF0QWxlcnREaWFsb2dEYXRhLFxuICAgIFhtYXRBbGVydFR5cGVzLFxuICAgIFhtYXRBbGVydERpYWxvZ0FjdGlvbnMsXG4gICAgWG1hdENvbmZpcm1EaWFsb2dEYXRhLFxuICAgIFhtYXRTbmFja0JhckRhdGEsXG4gICAgWG1hdEZpbGVSZWFkZXJFdmVudCxcbiAgICBYbWF0R2VuZXJpY09iamVjdCxcbiAgICBYbWF0U25hY2tCYXJEYXRhVHlwZXMsXG4gICAgWG1hdFNlbGVjdFxufSBmcm9tIFwiLi4vbW9kZWxzL2luZGV4XCI7XG5pbXBvcnQgeyBYbWF0Q29uc3RhbnRzU2VydmljZSwgWE1BVF9DT05TVEFOVF9MQUJFTFMgfSBmcm9tIFwiLi94bWF0LWNvbnN0YW50cy5zZXJ2aWNlXCI7XG5pbXBvcnQgeyBYbWF0U25hY2tCYXJDb21wb25lbnQgfSBmcm9tIFwiLi4vY29tcG9uZW50cy94bWF0LXNuYWNrLWJhci9pbmRleFwiO1xuLy9cbmltcG9ydCB7IE9ic2VydmFibGUsIGZvcmtKb2luIH0gZnJvbSBcInJ4anNcIjtcbmltcG9ydCB7IG1hcCB9IGZyb20gXCJyeGpzL29wZXJhdG9yc1wiO1xuaW1wb3J0IHsgZWFjaCwgaW5jbHVkZXMsIGV4dGVuZCB9IGZyb20gXCJsb2Rhc2hcIjtcbmltcG9ydCB7IHBhcnNlWm9uZSBhcyBtb21lbnQgfSBmcm9tIFwibW9tZW50XCI7XG5cbnR5cGUgWG1hdE9ic2VydmFibGVzTWFwID0gWG1hdEdlbmVyaWNPYmplY3Q8T2JzZXJ2YWJsZTxhbnk+PjtcblxuY29uc3QgY29sb3JQYXJhbXMgPSB7XG4gICAgY2VudGVyOiAxMjgsXG4gICAgZGl2ZXJzaXR5OiAxMCxcbiAgICB3aWR0aDogMTI3XG59O1xuXG5jb25zdCBoZXhWYWx1ZXM6IHN0cmluZyA9IFwiMDEyMzQ1Njc4OUFCQ0RFRlwiO1xuXG5jb25zdCBieXRlMkhleCA9IChuKSA9PiB7XG4gICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWJpdHdpc2VcbiAgICByZXR1cm4gU3RyaW5nKGhleFZhbHVlcy5zdWJzdHIoKG4gPj4gNCkgJiAweDBGLCAxKSkgKyBoZXhWYWx1ZXMuc3Vic3RyKG4gJiAweDBGLCAxKTtcbn07XG5cbmNvbnN0IHJnYjJIZXggPSAociwgZywgYikgPT4ge1xuICAgIHJldHVybiBcIiNcIiArIGJ5dGUySGV4KHIpICsgYnl0ZTJIZXgoZykgKyBieXRlMkhleChiKTtcbn07XG5cbmNvbnN0IGVhY2hFbnVtID0gKHNyY0VudW0sIGl0ZXJhdGVlKSA9PiB7XG4gICAgY29uc3QgdGFyZ2V0ID0gW107XG4gICAgZWFjaChzcmNFbnVtLCAoa2V5KSA9PiB7XG4gICAgICAgIC8vIENvbnRpbnVlIGlmIGtleSBpcyBub3QgYSBudW1iZXJcbiAgICAgICAgaWYgKHR5cGVvZiBzcmNFbnVtW2tleV0gIT09IHR5cGVvZiAwKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICB0YXJnZXQucHVzaChzcmNFbnVtW2tleV0pO1xuICAgIH0pO1xuICAgIHJldHVybiBlYWNoKHRhcmdldCwgaXRlcmF0ZWUpO1xufTtcblxuLyoqXG4gKiBUSElTIFNFUlZJQ0UgUkVRVUlSRVMgMyBERVBFTkRFTkNJRVM6XG4gKiBYbWF0Q29uc3RhbnRzU2VydmljZSwgWG1hdFNuYWNrQmFyTW9kdWxlIGFuZCBYbWF0RGlhbG9nTW9kdWxlXG4gKi9cbkBJbmplY3RhYmxlKClcbmV4cG9ydCBjbGFzcyBYbWF0RnVuY3Rpb25zU2VydmljZSB7XG5cbiAgICBwcm90ZWN0ZWQgX2NvbmZpcm1EaWFsb2dEZWZhdWx0czogWG1hdENvbmZpcm1EaWFsb2dEYXRhID0ge1xuICAgICAgICBjb25maXJtVGV4dDogWE1BVF9DT05TVEFOVF9MQUJFTFMuY29uZmlybSxcbiAgICAgICAgY2FuY2VsVGV4dDogWE1BVF9DT05TVEFOVF9MQUJFTFMuY2FuY2VsLFxuICAgICAgICBkaWFsb2dDb250ZW50OiBYTUFUX0NPTlNUQU5UX0xBQkVMUy5wcm9jZWVkLFxuICAgICAgICBoaWRlQ2FuY2VsQnV0dG9uOiBmYWxzZSxcbiAgICAgICAgY29uZmlybUNvbG9yOiBcIndhcm5cIixcbiAgICAgICAgdGl0bGU6IFhNQVRfQ09OU1RBTlRfTEFCRUxTLndhcm5pbmdUaXRsZVxuICAgIH07XG5cbiAgICBwcml2YXRlIF9jb2xvckRiID0ge1xuICAgICAgICBmYWN0b3I6IGNvbG9yUGFyYW1zLndpZHRoICsgY29sb3JQYXJhbXMuY2VudGVyLFxuICAgICAgICBmcmVxdWVuY3k6IE1hdGguUEkgKiAyIC8gY29sb3JQYXJhbXMuZGl2ZXJzaXR5LFxuICAgICAgICBnZW5lcmF0ZWQ6IFtdXG4gICAgfTtcblxuICAgIHByaXZhdGUgX2RlZmF1bHRBbGVydERhdGE6IFhtYXRBbGVydERpYWxvZ0RhdGEgPSB7XG4gICAgICAgIHR5cGU6IFhtYXRBbGVydFR5cGVzLndhcm5pbmcsXG4gICAgICAgIHRpdGxlOiBYTUFUX0NPTlNUQU5UX0xBQkVMUy53YXJuaW5nVGl0bGUsXG4gICAgICAgIGNvbmZpcm1UZXh0OiBYTUFUX0NPTlNUQU5UX0xBQkVMUy5jb25maXJtLFxuICAgICAgICBjYW5jZWxUZXh0OiBYTUFUX0NPTlNUQU5UX0xBQkVMUy5jYW5jZWxcbiAgICB9O1xuXG4gICAgY29uc3RydWN0b3IocHJvdGVjdGVkIF9kaWFsb2c6IE1hdERpYWxvZyxcbiAgICAgICAgcHJvdGVjdGVkIF9zbmFja0JhcjogTWF0U25hY2tCYXIsXG4gICAgICAgIHByb3RlY3RlZCBfeG1hdENvbnN0YW50czogWG1hdENvbnN0YW50c1NlcnZpY2UpIHtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQVUJMSUMgRlVOQ1RJT05TXG4gICAgICovXG4gICAgYWRkTGVhZGluZ1plcm9lcyhuOiBudW1iZXIgfCBzdHJpbmcpOiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gKFwiMFwiICsgbikuc2xpY2UoLTIpO1xuICAgIH1cblxuICAgIGNyZWF0ZVJlZmxlY3Rpb25Nb2RlbChzb3VyY2UsIGxldmVsID0gMCk6IGFueSB7XG4gICAgICAgIC8vIEZvciBib3RoIGFycmF5cyBhbmQgb2JqZWN0c1xuICAgICAgICBpZiAoISFzb3VyY2UgJiYgdHlwZW9mIHNvdXJjZSA9PT0gdHlwZW9mIHt9KSB7XG4gICAgICAgICAgICBjb25zdCB0YXJnZXQgPSBBcnJheS5pc0FycmF5KHNvdXJjZSkgPyBbXSA6IHt9O1xuICAgICAgICAgICAgY29uc3Qgc291cmNlS2V5cyA9IE9iamVjdC5rZXlzKHNvdXJjZSk7IC8vIG5ldyBPYmplY3QoKTtcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc291cmNlS2V5cy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIGNvbnN0IGtleSA9IHNvdXJjZUtleXNbaV07XG4gICAgICAgICAgICAgICAgLy8gQWx3YXlzIGNyZWF0ZSBuZXcga2V5IG9uIHRoZSB0YXJnZXQsIGl0IHdpbGwgZXZlbnR1YWxseSBiZSBjb252ZXJ0ZWQgdG8gb2JqZWN0XG4gICAgICAgICAgICAgICAgLy8gRm9yIGJvdGggYXJyYXlzIGFuZCBvYmplY3RzXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRhcmdldFtrZXldID0gdGhpcy5jcmVhdGVSZWZsZWN0aW9uTW9kZWwoc291cmNlW2tleV0sIGxldmVsICsgMSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdGFyZ2V0O1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHZvaWQgMDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGRhdGVBZGRNb250aHMoZGF0ZTogRGF0ZSA9IG5ldyBEYXRlKCksIG1vbnRoczogbnVtYmVyID0gMCk6IERhdGUge1xuICAgICAgICBjb25zdCBkYXkgPSBkYXRlLmdldERhdGUoKTtcbiAgICAgICAgZGF0ZS5zZXRNb250aChkYXRlLmdldE1vbnRoKCkgKyArbW9udGhzKTtcbiAgICAgICAgaWYgKGRhdGUuZ2V0RGF0ZSgpICE9PSBkYXkpIHtcbiAgICAgICAgICAgIGRhdGUuc2V0RGF0ZSgwKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZGF0ZTtcbiAgICB9XG5cbiAgICBlYWNoRW51bShzcmNFbnVtLCBpdGVyYXRlZSk6IGFueVtdIHtcbiAgICAgICAgcmV0dXJuIGVhY2hFbnVtKHNyY0VudW0sIGl0ZXJhdGVlKTtcbiAgICB9XG5cbiAgICBlYWNoRnJvbTxUID0gYW55PihhcnJheTogVFtdLCBpbmRleDogbnVtYmVyLCBpdGVyYXRlZTogKGl0ZW06IFQsIGluZGV4OiBudW1iZXIsIHNvdXJjZTogVFtdKSA9PiBhbnkpOiBUW10ge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkoYXJyYXkpKSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKGBlYWNoRnJvbSBvbmx5IGFjY2VwdCBhcnJheXMgYXMgc291cmNlLCBmb3VuZCBpbnN0ZWFkICR7dHlwZW9mIGFycmF5fWApO1xuICAgICAgICAgICAgcmV0dXJuIGFycmF5O1xuICAgICAgICB9XG4gICAgICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuYW1pbmctY29udmVudGlvblxuICAgICAgICBsZXQgX2luZGV4ID0gaW5kZXggPT0gbnVsbCA/IC0xIDogaW5kZXg7XG4gICAgICAgIGNvbnN0IGxlbmd0aCA9IGFycmF5ID09IG51bGwgPyAwIDogYXJyYXkubGVuZ3RoO1xuXG4gICAgICAgIHdoaWxlICgrK19pbmRleCA8IGxlbmd0aCkge1xuICAgICAgICAgICAgaWYgKGl0ZXJhdGVlKGFycmF5W19pbmRleF0sIF9pbmRleCwgYXJyYXkpID09PSBmYWxzZSkge1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBhcnJheTtcbiAgICB9XG5cbiAgICBleHRyYWN0UXVlcnlQYXJhbXMocXVlcnlTdHJpbmcgPSBsb2NhdGlvbi5zZWFyY2gpOiBQYXJhbU1hcCB7XG4gICAgICAgIGNvbnN0IHF1ZXJ5OiBQYXJhbXMgPSB7fTtcbiAgICAgICAgY29uc3QgcGFpcnMgPSAocXVlcnlTdHJpbmdbMF0gPT09IFwiP1wiID8gcXVlcnlTdHJpbmcuc3Vic3RyKDEpIDogcXVlcnlTdHJpbmcpLnNwbGl0KFwiJlwiKTtcbiAgICAgICAgZWFjaChwYWlycywgcGFpciA9PiB7XG4gICAgICAgICAgICBjb25zdCBrZXkgPSBkZWNvZGVVUklDb21wb25lbnQocGFpci5zcGxpdChcIj1cIilbMF0pO1xuICAgICAgICAgICAgaWYgKCEha2V5KSB7XG4gICAgICAgICAgICAgICAgcXVlcnlba2V5XSA9IGRlY29kZVVSSUNvbXBvbmVudChwYWlyLnNwbGl0KFwiPVwiKVsxXSB8fCBcIlwiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBjb252ZXJ0VG9QYXJhbU1hcChxdWVyeSk7XG4gICAgfVxuXG4gICAgZmlsdGVyUHJvcHMob3JpZ2luYWw6IFhtYXRHZW5lcmljT2JqZWN0LCBleGNsdWRlOiBzdHJpbmdbXSA9IFtdKTogWG1hdEdlbmVyaWNPYmplY3Qge1xuICAgICAgICBpZiAob3JpZ2luYWwgIT09IE9iamVjdChvcmlnaW5hbCkpIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoXCJUaWRVdGlscyA9PiBBcmd1bWVudCB3YXMgbm90IHZhbGlkIG9iamVjdFwiLCBvcmlnaW5hbCk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShleGNsdWRlKSAmJiBleGNsdWRlLmxlbmd0aCkge1xuICAgICAgICAgICAgcmV0dXJuIE9iamVjdC5rZXlzKG9yaWdpbmFsKS5yZWR1Y2UoKG9iaiwga2V5KSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKCFpbmNsdWRlcyhleGNsdWRlLCBrZXkpKSB7XG4gICAgICAgICAgICAgICAgICAgIG9ialtrZXldID0gb3JpZ2luYWxba2V5XTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICByZXR1cm4gb2JqO1xuICAgICAgICAgICAgfSwge30pO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG9yaWdpbmFsO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgZnVuY3Rpb24gZ2VuZXJhdGVzIHZpYnJhbnQsIFwiZXZlbmx5IHNwYWNlZFwiIGNvbG91cnMgKGkuZS4gbm8gY2x1c3RlcmluZykuXG4gICAgICogVGhpcyBpcyBpZGVhbCBmb3IgY3JlYXRpbmcgZWFzaWx5IGRpc3Rpbmd1aXNoYWJsZSB2aWJyYW50IG1hcmtlcnMgaW4gR29vZ2xlIE1hcHMgYW5kIG90aGVyIGFwcHMuXG4gICAgICogKi9cbiAgICBnZXRSYWluYm93KHN0ZXBzOiBudW1iZXIgPSAxMCwgc3RlcDogbnVtYmVyID0gMCk6IHN0cmluZyB7XG4gICAgICAgIGxldCByLCBnLCBiO1xuICAgICAgICBjb25zdCBoID0gc3RlcCAvIHN0ZXBzO1xuICAgICAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tYml0d2lzZVxuICAgICAgICBjb25zdCBpID0gfn4oaCAqIDYpO1xuICAgICAgICBjb25zdCBmID0gaCAqIDYgLSBpO1xuICAgICAgICBjb25zdCBxID0gMSAtIGY7XG4gICAgICAgIHN3aXRjaCAoaSAlIDYpIHtcbiAgICAgICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgICAgICByID0gMSwgZyA9IGYsIGIgPSAwO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAxOlxuICAgICAgICAgICAgICAgIHIgPSBxLCBnID0gMSwgYiA9IDA7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIDI6XG4gICAgICAgICAgICAgICAgciA9IDAsIGcgPSAxLCBiID0gZjtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgMzpcbiAgICAgICAgICAgICAgICByID0gMCwgZyA9IHEsIGIgPSAxO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSA0OlxuICAgICAgICAgICAgICAgIHIgPSBmLCBnID0gMCwgYiA9IDE7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIDU6XG4gICAgICAgICAgICAgICAgciA9IDEsIGcgPSAwLCBiID0gcTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tYml0d2lzZVxuICAgICAgICBjb25zdCByZWQgPSAoXCIwMFwiICsgKH5+KHIgKiAyNTUpKS50b1N0cmluZygxNikpLnNsaWNlKC0yKTtcbiAgICAgICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWJpdHdpc2VcbiAgICAgICAgY29uc3QgZ3JlZW4gPSAoXCIwMFwiICsgKH5+KGcgKiAyNTUpKS50b1N0cmluZygxNikpLnNsaWNlKC0yKTtcbiAgICAgICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWJpdHdpc2VcbiAgICAgICAgY29uc3QgYmx1ZSA9IChcIjAwXCIgKyAofn4oYiAqIDI1NSkpLnRvU3RyaW5nKDE2KSkuc2xpY2UoLTIpO1xuICAgICAgICByZXR1cm4gKFwiI1wiICsgcmVkICsgZ3JlZW4gKyBibHVlKTtcbiAgICB9XG5cbiAgICBnZXRSYW5kb21Ob25Db25zZWN1dGl2ZUhleChwaGFzZTogbnVtYmVyID0gMTApOiBzdHJpbmcge1xuICAgICAgICBjb25zdCBpbmRleCA9IHRoaXMuX2NvbG9yRGIuZ2VuZXJhdGVkLmxlbmd0aCArIDE7XG4gICAgICAgIGNvbnN0IHJlZCA9IE1hdGguc2luKHRoaXMuX2NvbG9yRGIuZnJlcXVlbmN5ICogaW5kZXggKyAyICsgcGhhc2UpICogdGhpcy5fY29sb3JEYi5mYWN0b3I7XG4gICAgICAgIGNvbnN0IGdyZWVuID0gTWF0aC5zaW4odGhpcy5fY29sb3JEYi5mcmVxdWVuY3kgKiBpbmRleCArIHBoYXNlKSAqIHRoaXMuX2NvbG9yRGIuZmFjdG9yO1xuICAgICAgICBjb25zdCBibHVlID0gTWF0aC5zaW4odGhpcy5fY29sb3JEYi5mcmVxdWVuY3kgKiBpbmRleCArIDQgKyBwaGFzZSkgKiB0aGlzLl9jb2xvckRiLmZhY3RvcjtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gcmdiMkhleChyZWQsIGdyZWVuLCBibHVlKTtcbiAgICAgICAgdGhpcy5fY29sb3JEYi5nZW5lcmF0ZWQucHVzaChyZXN1bHQpO1xuICAgICAgICByZXR1cm4gcmVzdWx0O1xuXG4gICAgfVxuXG4gICAgaXNOdW1lcmljKHZhbHVlOiBhbnkpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuICFpc05hTihwYXJzZUludCh2YWx1ZSwgMTApKTtcbiAgICB9XG5cbiAgICBpc1ZhbGlkTGVuZ3RoKHZhbHVlOiBhbnkpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaXNOdW1lcmljKHZhbHVlKSAmJiB2YWx1ZSA+PSAwO1xuICAgIH1cblxuICAgIGxvZ1dpdGhTdHlsZSh0aXRsZTogc3RyaW5nLCBtc2c6IHN0cmluZywgY29sb3I6IHN0cmluZywgY29udGVudDogYW55KSB7XG4gICAgICAgIGNvbnNvbGUuZ3JvdXAodGl0bGUgfHwgXCJcIik7XG4gICAgICAgIGNvbnNvbGUubG9nKFwiJWNcIiArIG1zZywgYGNvbG9yOiAke2NvbG9yfWAsIGNvbnRlbnQpO1xuICAgICAgICBjb25zb2xlLmdyb3VwRW5kKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICpcbiAgICAgKiBAcGFyYW0gc291cmNlIHRoZSBzb3VyY2Ugb2JqZWN0XG4gICAgICogQHBhcmFtIGtleXMgYWxsb3dzIHRvIG9yZGVyIHRoZSByZXN1bHQgYW5kL29yIGluY2x1ZGUgb25seSBjZXJ0YWluIHByb3BzXG4gICAgICovXG4gICAgb2JqZWN0VG9BcnJheTxUID0gYW55Pihzb3VyY2U6IFhtYXRHZW5lcmljT2JqZWN0PGFueT4sIGtleXMgPSBPYmplY3Qua2V5cyhzb3VyY2UpLCBrZWVwVm9pZDogYm9vbGVhbiA9ICExKTogWG1hdFNlbGVjdDxUPltdIHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gW107XG4gICAgICAgIGVhY2goa2V5cywgKGspID0+IHtcbiAgICAgICAgICAgIHNvdXJjZVtrXSAhPT0gdm9pZCAwICYmXG4gICAgICAgICAgICAgICAgcmVzdWx0LnB1c2goe1xuICAgICAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbjogayxcbiAgICAgICAgICAgICAgICAgICAgdmFsdWU6IHNvdXJjZVtrXVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICBvcGVuQWxlcnREaWFsb2coZGF0YTogWG1hdEFsZXJ0RGlhbG9nRGF0YSxcbiAgICAgICAgcmV0dXJuUmVmPzogZmFsc2UpOiBPYnNlcnZhYmxlPFhtYXRBbGVydERpYWxvZ0FjdGlvbnM+O1xuICAgIG9wZW5BbGVydERpYWxvZyhkYXRhOiBYbWF0QWxlcnREaWFsb2dEYXRhLFxuICAgICAgICByZXR1cm5SZWY6IHRydWUpOiBNYXREaWFsb2dSZWY8WG1hdEFsZXJ0RGlhbG9nQ29tcG9uZW50LCBYbWF0QWxlcnREaWFsb2dBY3Rpb25zPjtcbiAgICBvcGVuQWxlcnREaWFsb2coZGF0YTogWG1hdEFsZXJ0RGlhbG9nRGF0YSA9IHRoaXMuX2RlZmF1bHRBbGVydERhdGEsXG4gICAgICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTptYXgtbGluZS1sZW5ndGhcbiAgICAgICAgcmV0dXJuUmVmOiBib29sZWFuID0gZmFsc2UpOiBPYnNlcnZhYmxlPFhtYXRBbGVydERpYWxvZ0FjdGlvbnM+IHwgTWF0RGlhbG9nUmVmPFhtYXRBbGVydERpYWxvZ0NvbXBvbmVudCwgWG1hdEFsZXJ0RGlhbG9nQWN0aW9ucz4ge1xuICAgICAgICBkYXRhID0gZXh0ZW5kKHt9LCB0aGlzLl9kZWZhdWx0QWxlcnREYXRhLCBkYXRhKTtcbiAgICAgICAgY29uc3QgZGlhbG9nQ29uZmlnID0gbmV3IE1hdERpYWxvZ0NvbmZpZzxYbWF0QWxlcnREaWFsb2dEYXRhPigpO1xuICAgICAgICBleHRlbmQoZGlhbG9nQ29uZmlnLCB7XG4gICAgICAgICAgICBpZDogZGF0YS5kaWFsb2dJZCxcbiAgICAgICAgICAgIHdpZHRoOiB0aGlzLl94bWF0Q29uc3RhbnRzLmRpYWxvZ09wdGlvbnMuZGVmYXVsdFdpZHRoLFxuICAgICAgICAgICAgZGF0YTogZGF0YSxcbiAgICAgICAgICAgIGRpc2FibGVDbG9zZTogdHJ1ZVxuICAgICAgICB9KTtcbiAgICAgICAgLy8gT3BlbiBkaWFsb2cgYW5kIHBhc3MgZGF0YSBwbHVzIG9wdGlvbnNcbiAgICAgICAgY29uc3QgZGlhbG9nUmVmID0gdGhpcy5fZGlhbG9nLm9wZW4oWG1hdEFsZXJ0RGlhbG9nQ29tcG9uZW50LCBkaWFsb2dDb25maWcpO1xuICAgICAgICBpZiAocmV0dXJuUmVmKSB7XG4gICAgICAgICAgICByZXR1cm4gZGlhbG9nUmVmO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBPYnNlcnZhYmxlKG9ic2VydmVyID0+IHtcbiAgICAgICAgICAgICAgICAvLyBDYXRjaCByZXN1bHRcbiAgICAgICAgICAgICAgICBkaWFsb2dSZWYuYWZ0ZXJDbG9zZWQoKS5zdWJzY3JpYmUoKHJlc3VsdDogWG1hdEFsZXJ0RGlhbG9nQWN0aW9ucykgPT4ge1xuICAgICAgICAgICAgICAgICAgICBvYnNlcnZlci5uZXh0KHJlc3VsdCk7XG4gICAgICAgICAgICAgICAgICAgIG9ic2VydmVyLmNvbXBsZXRlKCk7XG4gICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgb3BlbkNvbmZpcm1EaWFsb2coZGF0YTogWG1hdENvbmZpcm1EaWFsb2dEYXRhLFxuICAgICAgICBkaXNhYmxlQ2xvc2U/OiBib29sZWFuLFxuICAgICAgICB3aWR0aD86IHN0cmluZyxcbiAgICAgICAgcmV0dXJuUmVmPzogZmFsc2UpOiBPYnNlcnZhYmxlPGJvb2xlYW4+O1xuICAgIG9wZW5Db25maXJtRGlhbG9nKGRhdGE6IFhtYXRDb25maXJtRGlhbG9nRGF0YSxcbiAgICAgICAgZGlzYWJsZUNsb3NlOiBib29sZWFuLFxuICAgICAgICB3aWR0aDogc3RyaW5nLFxuICAgICAgICByZXR1cm5SZWY6IHRydWUpOiBNYXREaWFsb2dSZWY8WG1hdENvbmZpcm1EaWFsb2dDb21wb25lbnQsIGJvb2xlYW4+O1xuICAgIG9wZW5Db25maXJtRGlhbG9nKGRhdGE/OiBYbWF0Q29uZmlybURpYWxvZ0RhdGEsXG4gICAgICAgIGRpc2FibGVDbG9zZTogYm9vbGVhbiA9IGZhbHNlLFxuICAgICAgICB3aWR0aDogc3RyaW5nID0gdGhpcy5feG1hdENvbnN0YW50cy5kaWFsb2dPcHRpb25zLmRlZmF1bHRXaWR0aCxcbiAgICAgICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm1heC1saW5lLWxlbmd0aFxuICAgICAgICByZXR1cm5SZWY6IGJvb2xlYW4gPSBmYWxzZSk6IE1hdERpYWxvZ1JlZjxYbWF0Q29uZmlybURpYWxvZ0NvbXBvbmVudCwgYm9vbGVhbj4gfCBPYnNlcnZhYmxlPGJvb2xlYW4+IHtcblxuICAgICAgICBjb25zdCBkaWFsb2dDb25maWcgPSBuZXcgTWF0RGlhbG9nQ29uZmlnPFhtYXRDb25maXJtRGlhbG9nRGF0YT4oKTtcbiAgICAgICAgZXh0ZW5kKGRpYWxvZ0NvbmZpZywge1xuICAgICAgICAgICAgaWQ6IGRhdGEuZGlhbG9nSWQsXG4gICAgICAgICAgICB3aWR0aDogd2lkdGgsXG4gICAgICAgICAgICBkYXRhOiB7XG4gICAgICAgICAgICAgICAgLi4udGhpcy5fY29uZmlybURpYWxvZ0RlZmF1bHRzLFxuICAgICAgICAgICAgICAgIC4uLmRhdGFcbiAgICAgICAgICAgIH0gYXMgWG1hdENvbmZpcm1EaWFsb2dEYXRhL