ngx-mat-lib
Version:
A bunch of utilities and components to use in your Angular 7+ apps!
587 lines (586 loc) • 57.4 kB
JavaScript
/**
* @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