angular-material-css-vars-legacy
Version:
Little library to use css variables for @angular/material for legacy components
328 lines • 44.8 kB
JavaScript
import { Inject, Injectable, RendererStyleFlags2 } from '@angular/core';
import { TinyColor } from '@ctrl/tinycolor';
import { MatCssPalettePrefix } from './model';
import { DOCUMENT } from '@angular/common';
import { DEFAULT_MAT_CSS_CFG } from './default-cfg.const';
import { MATERIAL_CSS_VARS_CFG } from '../mat-css-config-token.const';
import * as i0 from "@angular/core";
// @see: https://github.com/angular/angular/issues/20351
/** @dynamic */
class MaterialCssVarsService {
static { this.CONTRAST_PREFIX = 'contrast-'; }
static { this.DARK_TEXT_VAR = '--dark-primary-text'; }
static { this.LIGHT_TEXT_VAR = '--light-primary-text'; }
constructor(rendererFactory, document, cfg) {
this.document = document;
this.contrastColorThresholdPrimary = '400';
this.contrastColorThresholdAccent = '400';
this.contrastColorThresholdWarn = '400';
this.isAutoContrast = false;
this.renderer = rendererFactory.createRenderer(null, null);
this.ROOT = this.document.documentElement;
this.cfg = {
...DEFAULT_MAT_CSS_CFG,
...cfg,
};
this.isAutoContrast = this.cfg.isAutoContrast;
if (this.cfg.isDarkTheme) {
this.setDarkTheme(this.cfg.isDarkTheme);
}
if (this.cfg.primary) {
this.setPrimaryColor(this.cfg.primary);
}
if (this.cfg.accent) {
this.setAccentColor(this.cfg.accent);
}
if (this.cfg.warn) {
this.setWarnColor(this.cfg.warn);
}
}
setPrimaryColor(hex) {
this.primary = hex;
const varPrefix = MatCssPalettePrefix.Primary;
const stylePrimary = this._computePaletteColors(varPrefix, this.primary);
this._setStyle(stylePrimary);
if (this.isAutoContrast) {
this._recalculateAndSetContrastColor(varPrefix);
}
}
setAccentColor(hex) {
this.accent = hex;
const varPrefix = MatCssPalettePrefix.Accent;
const styleAccent = this._computePaletteColors(varPrefix, this.accent);
this._setStyle(styleAccent);
if (this.isAutoContrast) {
this._recalculateAndSetContrastColor(varPrefix);
}
}
setWarnColor(hex) {
this.warn = hex;
const varPrefix = MatCssPalettePrefix.Warn;
const styleWarn = this._computePaletteColors(varPrefix, this.warn);
this._setStyle(styleWarn);
if (this.isAutoContrast) {
this._recalculateAndSetContrastColor(varPrefix);
}
}
setVariable(cssVarName, value) {
this._setStyle([{
name: cssVarName,
val: value,
}]);
}
setDarkTheme(isDark) {
if (isDark) {
this.document.body.classList.remove(this.cfg.lightThemeClass);
this.document.body.classList.add(this.cfg.darkThemeClass);
}
else {
this.document.body.classList.remove(this.cfg.darkThemeClass);
this.document.body.classList.add(this.cfg.lightThemeClass);
}
this.isDarkTheme = isDark;
}
setAutoContrastEnabled(val) {
this.isAutoContrast = val;
if (val) {
this._recalculateAndSetContrastColor(MatCssPalettePrefix.Primary);
this._recalculateAndSetContrastColor(MatCssPalettePrefix.Accent);
this._recalculateAndSetContrastColor(MatCssPalettePrefix.Warn);
}
else {
this.setContrastColorThresholdPrimary(this.contrastColorThresholdPrimary);
this.setContrastColorThresholdAccent(this.contrastColorThresholdAccent);
this.setContrastColorThresholdWarn(this.contrastColorThresholdWarn);
}
}
setContrastColorThresholdPrimary(threshold) {
this.contrastColorThresholdPrimary = threshold;
this.setContrastColorThreshold(threshold, MatCssPalettePrefix.Primary);
}
setContrastColorThresholdAccent(threshold) {
this.contrastColorThresholdAccent = threshold;
this.setContrastColorThreshold(threshold, MatCssPalettePrefix.Accent);
}
setContrastColorThresholdWarn(threshold) {
this.contrastColorThresholdWarn = threshold;
this.setContrastColorThreshold(threshold, MatCssPalettePrefix.Warn);
}
setContrastColorThreshold(threshold, palettePrefix) {
let color = MaterialCssVarsService.DARK_TEXT_VAR;
const updates = this.cfg.sortedHues.map((hue) => {
if (hue === threshold) {
color = MaterialCssVarsService.LIGHT_TEXT_VAR;
}
return {
val: this._getCssVarValue(color),
name: `${palettePrefix + MaterialCssVarsService.CONTRAST_PREFIX}${hue}-rgb`,
};
});
this._setStyle(updates);
}
/**
* Generate palette color based on traditional values
*/
setAlternativeColorAlgorithm(traditional) {
this.cfg.isAlternativeColorAlgorithm = traditional;
this.setPrimaryColor(this.primary);
this.setAccentColor(this.accent);
this.setWarnColor(this.warn);
}
/** @deprecated use setContrastColorThresholdPrimary instead */
changeContrastColorThresholdPrimary(threshold) {
this.setContrastColorThresholdPrimary(threshold);
}
/** @deprecated use setContrastColorThresholdAccent instead */
changeContrastColorThresholdAccent(threshold) {
this.setContrastColorThresholdAccent(threshold);
}
/** @deprecated use setContrastColorThresholdWarn instead */
changeContrastColorThresholdWarn(threshold) {
this.setContrastColorThresholdWarn(threshold);
}
/** @deprecated use setContrastColorThreshold instead */
changeContrastColorThreshold(threshold, palettePrefix) {
this.setContrastColorThreshold(threshold, palettePrefix);
}
getPaletteForColor(hex) {
if (this.cfg.isAlternativeColorAlgorithm) {
return this.getTraditionalPaletteForColor(hex);
}
else {
return this.getConstantinPaletteForColor(hex);
}
}
getTraditionalPaletteForColor(hex) {
return this.cfg.colorMap.map(item => {
const mappedColor = new TinyColor(hex)
.lighten(item.map[0])
.darken(item.map[1])
.saturate(item.map[2]);
const c = new TinyColor(mappedColor);
return {
hue: item.name,
isLight: c.isLight(),
color: {
...c.toRgb(),
str: `rgb(${c.toRgb().r},${c.toRgb().g},${c.toRgb().b})`
}
};
});
}
getConstantinPaletteForColor(hex) {
return this.cfg.colorMap.map((item) => {
const c = this.computePalletTriad(hex, item.name);
return {
hue: item.name,
isLight: c.isLight,
color: {
...c.rgb,
str: `rgb(${c.rgb.r},${c.rgb.g},${c.rgb.b})`
}
};
});
}
getPaletteWithContrastForColor(hex) {
const lightText = this._getCssVarValue(MaterialCssVarsService.LIGHT_TEXT_VAR);
const darkText = this._getCssVarValue(MaterialCssVarsService.DARK_TEXT_VAR);
const palette = this.getPaletteForColor(hex);
// TODO handle non auto case
return palette.map((item) => {
const contrastStr = item.isLight
? lightText
: darkText;
const sLight = contrastStr.split(',').map(v => +v);
const cco = { r: sLight[0], g: sLight[1], b: sLight[2], a: 1 };
return {
...item,
contrast: {
...cco,
str: `${cco.r},${cco.g},${cco.b}`
},
};
});
}
_computePaletteColors(prefix, hex) {
return this.getPaletteForColor(hex).map(item => {
const c = item.color;
return {
name: `${prefix}${item.hue}`,
val: `${c.r}, ${c.g}, ${c.b}`
};
});
}
_recalculateAndSetContrastColor(palettePrefix) {
const updates = this._calculateContrastColorsForCurrentValues(palettePrefix)
.map(({ contrastColorVar, hue }) => {
return {
val: this._getCssVarValue(contrastColorVar),
name: `${palettePrefix + MaterialCssVarsService.CONTRAST_PREFIX}${hue}-rgb`,
};
});
this._setStyle(updates);
}
_calculateContrastColorsForCurrentValues(palettePrefix) {
return this.cfg.sortedHues.map((hue) => {
const hueVarVal = this._getCssVarValue(`${palettePrefix}${hue}`);
const c = new TinyColor(`rgb(${hueVarVal})`);
const contrastColorVar = c.isDark()
? MaterialCssVarsService.LIGHT_TEXT_VAR
: MaterialCssVarsService.DARK_TEXT_VAR;
return {
contrastColorVar,
hue,
};
});
}
_setStyle(vars) {
vars.forEach(s => {
this.renderer.setStyle(this.ROOT, s.name, s.val, RendererStyleFlags2.DashCase);
});
}
_getCssVarValue(v) {
return getComputedStyle(this.ROOT).getPropertyValue(v);
}
/**
* Compute pallet colors based on a Triad (Constantin)
* see: https://github.com/mbitson/mcg
*/
computePalletTriad(hex, hue) {
const baseLight = new TinyColor('#ffffff');
const baseDark = this.multiply(new TinyColor(hex).toRgb(), new TinyColor(hex).toRgb());
const baseTriad = new TinyColor(hex).tetrad();
let color;
switch (hue) {
case '50':
color = this.getColorObject(baseLight.mix(hex, 12));
break;
case '100':
color = this.getColorObject(baseLight.mix(hex, 30));
break;
case '200':
color = this.getColorObject(baseLight.mix(hex, 50));
break;
case '300':
color = this.getColorObject(baseLight.mix(hex, 70));
break;
case '400':
color = this.getColorObject(baseLight.mix(hex, 85));
break;
case '500':
color = this.getColorObject(baseLight.mix(hex, 100));
break;
case '600':
color = this.getColorObject(baseDark.mix(hex, 87));
break;
case '700':
color = this.getColorObject(baseDark.mix(hex, 70));
break;
case '800':
color = this.getColorObject(baseDark.mix(hex, 54));
break;
case '900':
color = this.getColorObject(baseDark.mix(hex, 25));
break;
case 'A100':
color = this.getColorObject(baseDark.mix(baseTriad[4], 15).saturate(80).lighten(65));
break;
case 'A200':
color = this.getColorObject(baseDark.mix(baseTriad[4], 15).saturate(80).lighten(55));
break;
case 'A400':
color = this.getColorObject(baseDark.mix(baseTriad[4], 15).saturate(100).lighten(45));
break;
case 'A700':
color = this.getColorObject(baseDark.mix(baseTriad[4], 15).saturate(100).lighten(40));
break;
default:
break;
}
return color;
}
multiply(rgb1, rgb2) {
rgb1.b = Math.floor(rgb1.b * rgb2.b / 255);
rgb1.g = Math.floor(rgb1.g * rgb2.g / 255);
rgb1.r = Math.floor(rgb1.r * rgb2.r / 255);
return new TinyColor('rgb ' + rgb1.r + ' ' + rgb1.g + ' ' + rgb1.b);
}
getColorObject(value) {
const c = new TinyColor(value);
return { rgb: c.toRgb(), isLight: c.isLight() };
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: MaterialCssVarsService, deps: [{ token: i0.RendererFactory2 }, { token: DOCUMENT }, { token: MATERIAL_CSS_VARS_CFG }], target: i0.ɵɵFactoryTarget.Injectable }); }
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: MaterialCssVarsService, providedIn: 'root' }); }
}
export { MaterialCssVarsService };
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: MaterialCssVarsService, decorators: [{
type: Injectable,
args: [{
providedIn: 'root'
}]
}], ctorParameters: function () { return [{ type: i0.RendererFactory2 }, { type: Document, decorators: [{
type: Inject,
args: [DOCUMENT]
}] }, { type: undefined, decorators: [{
type: Inject,
args: [MATERIAL_CSS_VARS_CFG]
}] }]; } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWF0ZXJpYWwtY3NzLXZhcnMuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL21hdGVyaWFsLWNzcy12YXJzL3NyYy9saWIvbWF0ZXJpYWwtY3NzLXZhcnMuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUMsTUFBTSxFQUFFLFVBQVUsRUFBK0IsbUJBQW1CLEVBQUMsTUFBTSxlQUFlLENBQUM7QUFDbkcsT0FBTyxFQUFrQixTQUFTLEVBQUMsTUFBTSxpQkFBaUIsQ0FBQztBQUMzRCxPQUFPLEVBSUwsbUJBQW1CLEVBR3BCLE1BQU0sU0FBUyxDQUFDO0FBQ2pCLE9BQU8sRUFBQyxRQUFRLEVBQUMsTUFBTSxpQkFBaUIsQ0FBQztBQUN6QyxPQUFPLEVBQUMsbUJBQW1CLEVBQUMsTUFBTSxxQkFBcUIsQ0FBQztBQUN4RCxPQUFPLEVBQUMscUJBQXFCLEVBQUMsTUFBTSwrQkFBK0IsQ0FBQzs7QUFPcEUsd0RBQXdEO0FBQ3hELGVBQWU7QUFDZixNQUdhLHNCQUFzQjthQUNsQixvQkFBZSxHQUFHLFdBQVcsQUFBZCxDQUFlO2FBQzlCLGtCQUFhLEdBQUcscUJBQXFCLEFBQXhCLENBQXlCO2FBQ3RDLG1CQUFjLEdBQUcsc0JBQXNCLEFBQXpCLENBQTBCO0lBZ0J2RCxZQUNFLGVBQWlDLEVBQ1AsUUFBa0IsRUFDYixHQUErQjtRQURwQyxhQUFRLEdBQVIsUUFBUSxDQUFVO1FBUDlDLGtDQUE2QixHQUFhLEtBQUssQ0FBQztRQUNoRCxpQ0FBNEIsR0FBYSxLQUFLLENBQUM7UUFDL0MsK0JBQTBCLEdBQWEsS0FBSyxDQUFDO1FBQzdDLG1CQUFjLEdBQUcsS0FBSyxDQUFDO1FBT3JCLElBQUksQ0FBQyxRQUFRLEdBQUcsZUFBZSxDQUFDLGNBQWMsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDM0QsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLGVBQWUsQ0FBQztRQUUxQyxJQUFJLENBQUMsR0FBRyxHQUFHO1lBQ1QsR0FBRyxtQkFBbUI7WUFDdEIsR0FBRyxHQUFHO1NBQ1AsQ0FBQztRQUNGLElBQUksQ0FBQyxjQUFjLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxjQUFjLENBQUM7UUFFOUMsSUFBSSxJQUFJLENBQUMsR0FBRyxDQUFDLFdBQVcsRUFBRTtZQUN4QixJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsV0FBVyxDQUFDLENBQUM7U0FDekM7UUFDRCxJQUFJLElBQUksQ0FBQyxHQUFHLENBQUMsT0FBTyxFQUFFO1lBQ3BCLElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsQ0FBQztTQUN4QztRQUNELElBQUksSUFBSSxDQUFDLEdBQUcsQ0FBQyxNQUFNLEVBQUU7WUFDbkIsSUFBSSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1NBQ3RDO1FBQ0QsSUFBSSxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksRUFBRTtZQUNqQixJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUM7U0FDbEM7SUFDSCxDQUFDO0lBRUQsZUFBZSxDQUFDLEdBQVc7UUFDekIsSUFBSSxDQUFDLE9BQU8sR0FBRyxHQUFHLENBQUM7UUFDbkIsTUFBTSxTQUFTLEdBQUcsbUJBQW1CLENBQUMsT0FBTyxDQUFDO1FBQzlDLE1BQU0sWUFBWSxHQUFHLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxTQUFTLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ3pFLElBQUksQ0FBQyxTQUFTLENBQUMsWUFBWSxDQUFDLENBQUM7UUFFN0IsSUFBSSxJQUFJLENBQUMsY0FBYyxFQUFFO1lBQ3ZCLElBQUksQ0FBQywrQkFBK0IsQ0FBQyxTQUFTLENBQUMsQ0FBQztTQUNqRDtJQUNILENBQUM7SUFFRCxjQUFjLENBQUMsR0FBVztRQUN4QixJQUFJLENBQUMsTUFBTSxHQUFHLEdBQUcsQ0FBQztRQUNsQixNQUFNLFNBQVMsR0FBRyxtQkFBbUIsQ0FBQyxNQUFNLENBQUM7UUFDN0MsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLHFCQUFxQixDQUFDLFNBQVMsRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDdkUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUU1QixJQUFJLElBQUksQ0FBQyxjQUFjLEVBQUU7WUFDdkIsSUFBSSxDQUFDLCtCQUErQixDQUFDLFNBQVMsQ0FBQyxDQUFDO1NBQ2pEO0lBQ0gsQ0FBQztJQUVELFlBQVksQ0FBQyxHQUFXO1FBQ3RCLElBQUksQ0FBQyxJQUFJLEdBQUcsR0FBRyxDQUFDO1FBQ2hCLE1BQU0sU0FBUyxHQUFHLG1CQUFtQixDQUFDLElBQUksQ0FBQztRQUMzQyxNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMscUJBQXFCLENBQUMsU0FBUyxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNuRSxJQUFJLENBQUMsU0FBUyxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBRTFCLElBQUksSUFBSSxDQUFDLGNBQWMsRUFBRTtZQUN2QixJQUFJLENBQUMsK0JBQStCLENBQUMsU0FBUyxDQUFDLENBQUM7U0FDakQ7SUFDSCxDQUFDO0lBRUQsV0FBVyxDQUFDLFVBQWdDLEVBQUUsS0FBYTtRQUN6RCxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7Z0JBQ2QsSUFBSSxFQUFFLFVBQVU7Z0JBQ2hCLEdBQUcsRUFBRSxLQUFLO2FBQ1gsQ0FBQyxDQUFDLENBQUM7SUFDTixDQUFDO0lBRUQsWUFBWSxDQUFDLE1BQWU7UUFDMUIsSUFBSSxNQUFNLEVBQUU7WUFDVixJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsZUFBZSxDQUFDLENBQUM7WUFDOUQsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLGNBQWMsQ0FBQyxDQUFDO1NBQzNEO2FBQU07WUFDTCxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsY0FBYyxDQUFDLENBQUM7WUFDN0QsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLGVBQWUsQ0FBQyxDQUFDO1NBQzVEO1FBQ0QsSUFBSSxDQUFDLFdBQVcsR0FBRyxNQUFNLENBQUM7SUFDNUIsQ0FBQztJQUVELHNCQUFzQixDQUFDLEdBQVk7UUFDakMsSUFBSSxDQUFDLGNBQWMsR0FBRyxHQUFHLENBQUM7UUFDMUIsSUFBSSxHQUFHLEVBQUU7WUFDUCxJQUFJLENBQUMsK0JBQStCLENBQUMsbUJBQW1CLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDbEUsSUFBSSxDQUFDLCtCQUErQixDQUFDLG1CQUFtQixDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQ2pFLElBQUksQ0FBQywrQkFBK0IsQ0FBQyxtQkFBbUIsQ0FBQyxJQUFJLENBQUMsQ0FBQztTQUNoRTthQUFNO1lBQ0wsSUFBSSxDQUFDLGdDQUFnQyxDQUFDLElBQUksQ0FBQyw2QkFBNkIsQ0FBQyxDQUFDO1lBQzFFLElBQUksQ0FBQywrQkFBK0IsQ0FBQyxJQUFJLENBQUMsNEJBQTRCLENBQUMsQ0FBQztZQUN4RSxJQUFJLENBQUMsNkJBQTZCLENBQUMsSUFBSSxDQUFDLDBCQUEwQixDQUFDLENBQUM7U0FDckU7SUFDSCxDQUFDO0lBRUQsZ0NBQWdDLENBQUMsU0FBbUI7UUFDbEQsSUFBSSxDQUFDLDZCQUE2QixHQUFHLFNBQVMsQ0FBQztRQUMvQyxJQUFJLENBQUMseUJBQXlCLENBQUMsU0FBUyxFQUFFLG1CQUFtQixDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQ3pFLENBQUM7SUFFRCwrQkFBK0IsQ0FBQyxTQUFtQjtRQUNqRCxJQUFJLENBQUMsNEJBQTRCLEdBQUcsU0FBUyxDQUFDO1FBQzlDLElBQUksQ0FBQyx5QkFBeUIsQ0FBQyxTQUFTLEVBQUUsbUJBQW1CLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDeEUsQ0FBQztJQUVELDZCQUE2QixDQUFDLFNBQW1CO1FBQy9DLElBQUksQ0FBQywwQkFBMEIsR0FBRyxTQUFTLENBQUM7UUFDNUMsSUFBSSxDQUFDLHlCQUF5QixDQUFDLFNBQVMsRUFBRSxtQkFBbUIsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUN0RSxDQUFDO0lBRUQseUJBQXlCLENBQUMsU0FBbUIsRUFBRSxhQUFrQztRQUMvRSxJQUFJLEtBQUssR0FBRyxzQkFBc0IsQ0FBQyxhQUFhLENBQUM7UUFDakQsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLEVBQUU7WUFDOUMsSUFBSSxHQUFHLEtBQUssU0FBUyxFQUFFO2dCQUNyQixLQUFLLEdBQUcsc0JBQXNCLENBQUMsY0FBYyxDQUFDO2FBQy9DO1lBQ0QsT0FBTztnQkFDTCxHQUFHLEVBQUUsSUFBSSxDQUFDLGVBQWUsQ0FBQyxLQUFLLENBQUM7Z0JBQ2hDLElBQUksRUFBRSxHQUFHLGFBQWEsR0FBRyxzQkFBc0IsQ0FBQyxlQUFlLEdBQUcsR0FBRyxNQUFNO2FBQzVFLENBQUM7UUFDSixDQUFDLENBQUMsQ0FBQztRQUNILElBQUksQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDMUIsQ0FBQztJQUVEOztPQUVHO0lBQ0gsNEJBQTRCLENBQUMsV0FBb0I7UUFDL0MsSUFBSSxDQUFDLEdBQUcsQ0FBQywyQkFBMkIsR0FBRyxXQUFXLENBQUM7UUFDbkQsSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDbkMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDakMsSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDL0IsQ0FBQztJQUVELCtEQUErRDtJQUMvRCxtQ0FBbUMsQ0FBQyxTQUFtQjtRQUNyRCxJQUFJLENBQUMsZ0NBQWdDLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDbkQsQ0FBQztJQUVELDhEQUE4RDtJQUM5RCxrQ0FBa0MsQ0FBQyxTQUFtQjtRQUNwRCxJQUFJLENBQUMsK0JBQStCLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDbEQsQ0FBQztJQUVELDREQUE0RDtJQUM1RCxnQ0FBZ0MsQ0FBQyxTQUFtQjtRQUNsRCxJQUFJLENBQUMsNkJBQTZCLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDaEQsQ0FBQztJQUVELHdEQUF3RDtJQUN4RCw0QkFBNEIsQ0FBQyxTQUFtQixFQUFFLGFBQWtDO1FBQ2xGLElBQUksQ0FBQyx5QkFBeUIsQ0FBQyxTQUFTLEVBQUUsYUFBYSxDQUFDLENBQUM7SUFDM0QsQ0FBQztJQUVELGtCQUFrQixDQUFDLEdBQVc7UUFDNUIsSUFBSSxJQUFJLENBQUMsR0FBRyxDQUFDLDJCQUEyQixFQUFFO1lBQ3hDLE9BQU8sSUFBSSxDQUFDLDZCQUE2QixDQUFDLEdBQUcsQ0FBQyxDQUFDO1NBQ2hEO2FBQU07WUFDTCxPQUFPLElBQUksQ0FBQyw0QkFBNEIsQ0FBQyxHQUFHLENBQUMsQ0FBQztTQUMvQztJQUNILENBQUM7SUFFTyw2QkFBNkIsQ0FBQyxHQUFXO1FBQy9DLE9BQU8sSUFBSSxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxFQUFFO1lBQ2xDLE1BQU0sV0FBVyxHQUFHLElBQUksU0FBUyxDQUFDLEdBQUcsQ0FBQztpQkFDbkMsT0FBTyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7aUJBQ3BCLE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO2lCQUNuQixRQUFRLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ3pCLE1BQU0sQ0FBQyxHQUFHLElBQUksU0FBUyxDQUFDLFdBQVcsQ0FBQyxDQUFDO1lBQ3JDLE9BQU87Z0JBQ0wsR0FBRyxFQUFFLElBQUksQ0FBQyxJQUFJO2dCQUNkLE9BQU8sRUFBRSxDQUFDLENBQUMsT0FBTyxFQUFFO2dCQUNwQixLQUFLLEVBQUU7b0JBQ0wsR0FBRyxDQUFDLENBQUMsS0FBSyxFQUFFO29CQUNaLEdBQUcsRUFBRSxPQUFPLENBQUMsQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQyxHQUFHO2lCQUN6RDthQUNGLENBQUM7UUFDSixDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFTyw0QkFBNEIsQ0FBQyxHQUFXO1FBQzlDLE9BQU8sSUFBSSxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUU7WUFDcEMsTUFBTSxDQUFDLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDbEQsT0FBTztnQkFDTCxHQUFHLEVBQUUsSUFBSSxDQUFDLElBQUk7Z0JBQ2QsT0FBTyxFQUFFLENBQUMsQ0FBQyxPQUFPO2dCQUNsQixLQUFLLEVBQUU7b0JBQ0wsR0FBRyxDQUFDLENBQUMsR0FBRztvQkFDUixHQUFHLEVBQUUsT0FBTyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRztpQkFDN0M7YUFDRixDQUFDO1FBQ0osQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQsOEJBQThCLENBQUMsR0FBVztRQUN4QyxNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDLHNCQUFzQixDQUFDLGNBQWMsQ0FBQyxDQUFDO1FBQzlFLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUMsc0JBQXNCLENBQUMsYUFBYSxDQUFDLENBQUM7UUFDNUUsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBRTdDLDRCQUE0QjtRQUM1QixPQUFPLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRTtZQUMxQixNQUFNLFdBQVcsR0FBRyxJQUFJLENBQUMsT0FBTztnQkFDOUIsQ0FBQyxDQUFDLFNBQVM7Z0JBQ1gsQ0FBQyxDQUFDLFFBQVEsQ0FBQztZQUViLE1BQU0sTUFBTSxHQUFHLFdBQVcsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUNuRCxNQUFNLEdBQUcsR0FBRyxFQUFDLENBQUMsRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUMsQ0FBQztZQUM3RCxPQUFPO2dCQUNMLEdBQUcsSUFBSTtnQkFDUCxRQUFRLEVBQUU7b0JBQ1IsR0FBRyxHQUFHO29CQUNOLEdBQUcsRUFBRSxHQUFHLEdBQUcsQ0FBQyxDQUFDLElBQUksR0FBRyxDQUFDLENBQUMsSUFBSSxHQUFHLENBQUMsQ0FBQyxFQUFFO2lCQUNsQzthQUNGLENBQUM7UUFDSixDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFTyxxQkFBcUIsQ0FBQyxNQUEyQixFQUFFLEdBQVc7UUFDcEUsT0FBTyxJQUFJLENBQUMsa0JBQWtCLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxFQUFFO1lBQzdDLE1BQU0sQ0FBQyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUM7WUFDckIsT0FBTztnQkFDTCxJQUFJLEVBQUUsR0FBRyxNQUFNLEdBQUcsSUFBSSxDQUFDLEdBQUcsRUFBRTtnQkFDNUIsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQUU7YUFDOUIsQ0FBQztRQUNKLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVPLCtCQUErQixDQUFDLGFBQWtDO1FBQ3hFLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyx3Q0FBd0MsQ0FBQyxhQUFhLENBQUM7YUFDekUsR0FBRyxDQUFDLENBQUMsRUFBQyxnQkFBZ0IsRUFBRSxHQUFHLEVBQUMsRUFBRSxFQUFFO1lBQy9CLE9BQU87Z0JBQ0wsR0FBRyxFQUFFLElBQUksQ0FBQyxlQUFlLENBQUMsZ0JBQWdCLENBQUM7Z0JBQzNDLElBQUksRUFBRSxHQUFHLGFBQWEsR0FBRyxzQkFBc0IsQ0FBQyxlQUFlLEdBQUcsR0FBRyxNQUFNO2FBQzVFLENBQUM7UUFDSixDQUFDLENBQUMsQ0FBQztRQUNMLElBQUksQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDMUIsQ0FBQztJQUVPLHdDQUF3QyxDQUFDLGFBQWtDO1FBRWpGLE9BQU8sSUFBSSxDQUFDLEdBQUcsQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLEVBQUU7WUFDckMsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQyxHQUFHLGFBQWEsR0FBRyxHQUFHLEVBQUUsQ0FBQyxDQUFDO1lBQ2pFLE1BQU0sQ0FBQyxHQUFHLElBQUksU0FBUyxDQUFDLE9BQU8sU0FBUyxHQUFHLENBQUMsQ0FBQztZQUM3QyxNQUFNLGdCQUFnQixHQUFHLENBQUMsQ0FBQyxNQUFNLEVBQUU7Z0JBQ2pDLENBQUMsQ0FBQyxzQkFBc0IsQ0FBQyxjQUFjO2dCQUN2QyxDQUFDLENBQUMsc0JBQXNCLENBQUMsYUFBYSxDQUFDO1lBQ3pDLE9BQU87Z0JBQ0wsZ0JBQWdCO2dCQUNoQixHQUFHO2FBQ0osQ0FBQztRQUNKLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVPLFNBQVMsQ0FBQyxJQUFtQjtRQUNuQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFO1lBQ2YsSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQyxHQUFHLEVBQUUsbUJBQW1CLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDakYsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRU8sZUFBZSxDQUFDLENBQVM7UUFDL0IsT0FBTyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDekQsQ0FBQztJQUVEOzs7T0FHRztJQUNLLGtCQUFrQixDQUFDLEdBQVcsRUFBRSxHQUFhO1FBQ25ELE1BQU0sU0FBUyxHQUFHLElBQUksU0FBUyxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQzNDLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxTQUFTLENBQUMsR0FBRyxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUUsSUFBSSxTQUFTLENBQUMsR0FBRyxDQUFDLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQztRQUN2RixNQUFNLFNBQVMsR0FBRyxJQUFJLFNBQVMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUM5QyxJQUFJLEtBQWlELENBQUM7UUFFdEQsUUFBUSxHQUFHLEVBQUU7WUFDWCxLQUFLLElBQUk7Z0JBQ1AsS0FBSyxHQUFHLElBQUksQ0FBQyxjQUFjLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQztnQkFDcEQsTUFBTTtZQUNSLEtBQUssS0FBSztnQkFDUixLQUFLLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDO2dCQUNwRCxNQUFNO1lBQ1IsS0FBSyxLQUFLO2dCQUNSLEtBQUssR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUM7Z0JBQ3BELE1BQU07WUFDUixLQUFLLEtBQUs7Z0JBQ1IsS0FBSyxHQUFHLElBQUksQ0FBQyxjQUFjLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQztnQkFDcEQsTUFBTTtZQUNSLEtBQUssS0FBSztnQkFDUixLQUFLLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDO2dCQUNwRCxNQUFNO1lBQ1IsS0FBSyxLQUFLO2dCQUNSLEtBQUssR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUM7Z0JBQ3JELE1BQU07WUFDUixLQUFLLEtBQUs7Z0JBQ1IsS0FBSyxHQUFHLElBQUksQ0FBQyxjQUFjLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQztnQkFDbkQsTUFBTTtZQUNSLEtBQUssS0FBSztnQkFDUixLQUFLLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDO2dCQUNuRCxNQUFNO1lBQ1IsS0FBSyxLQUFLO2dCQUNSLEtBQUssR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUM7Z0JBQ25ELE1BQU07WUFDUixLQUFLLEtBQUs7Z0JBQ1IsS0FBSyxHQUFHLElBQUksQ0FBQyxjQUFjLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQztnQkFDbkQsTUFBTTtZQUNSLEtBQUssTUFBTTtnQkFDVCxLQUFLLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7Z0JBQ3JGLE1BQU07WUFDUixLQUFLLE1BQU07Z0JBQ1QsS0FBSyxHQUFHLElBQUksQ0FBQyxjQUFjLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO2dCQUNyRixNQUFNO1lBQ1IsS0FBSyxNQUFNO2dCQUNULEtBQUssR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztnQkFDdEYsTUFBTTtZQUNSLEtBQUssTUFBTTtnQkFDVCxLQUFLLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7Z0JBQ3RGLE1BQU07WUFDUjtnQkFDRSxNQUFNO1NBQ1Q7UUFDRCxPQUFPLEtBQUssQ0FBQztJQUNmLENBQUM7SUFFTyxRQUFRLENBQUMsSUFBcUIsRUFBRSxJQUFxQjtRQUMzRCxJQUFJLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxDQUFDO1FBQzNDLElBQUksQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDLENBQUM7UUFDM0MsSUFBSSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQztRQUMzQyxPQUFPLElBQUksU0FBUyxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUMsQ0FBQyxHQUFHLEdBQUcsR0FBRyxJQUFJLENBQUMsQ0FBQyxHQUFHLEdBQUcsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDdEUsQ0FBQztJQUVPLGNBQWMsQ0FBQyxLQUFnQjtRQUNyQyxNQUFNLENBQUMsR0FBRyxJQUFJLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUMvQixPQUFPLEVBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRSxPQUFPLEVBQUUsQ0FBQyxDQUFDLE9BQU8sRUFBRSxFQUFDLENBQUM7SUFDaEQsQ0FBQzsrR0E1VlUsc0JBQXNCLGtEQXFCdkIsUUFBUSxhQUNSLHFCQUFxQjttSEF0QnBCLHNCQUFzQixjQUZyQixNQUFNOztTQUVQLHNCQUFzQjs0RkFBdEIsc0JBQXNCO2tCQUhsQyxVQUFVO21CQUFDO29CQUNWLFVBQVUsRUFBRSxNQUFNO2lCQUNuQjs7MEJBc0JJLE1BQU07MkJBQUMsUUFBUTs7MEJBQ2YsTUFBTTsyQkFBQyxxQkFBcUIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge0luamVjdCwgSW5qZWN0YWJsZSwgUmVuZGVyZXIyLCBSZW5kZXJlckZhY3RvcnkyLCBSZW5kZXJlclN0eWxlRmxhZ3MyfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7TnVtYmVyaWZ5LCBSR0JBLCBUaW55Q29sb3J9IGZyb20gJ0BjdHJsL3Rpbnljb2xvcic7XG5pbXBvcnQge1xuICBIdWVWYWx1ZSxcbiAgTWF0Q3NzSHVlQ29sb3JDb250cmFzdE1hcEl0ZW0sXG4gIE1hdENzc0h1ZUNvbG9yTWFwSXRlbSxcbiAgTWF0Q3NzUGFsZXR0ZVByZWZpeCxcbiAgTWF0ZXJpYWxDc3NWYXJpYWJsZXMsXG4gIE1hdGVyaWFsQ3NzVmFyaWFibGVzQ29uZmlnXG59IGZyb20gJy4vbW9kZWwnO1xuaW1wb3J0IHtET0NVTUVOVH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7REVGQVVMVF9NQVRfQ1NTX0NGR30gZnJvbSAnLi9kZWZhdWx0LWNmZy5jb25zdCc7XG5pbXBvcnQge01BVEVSSUFMX0NTU19WQVJTX0NGR30gZnJvbSAnLi4vbWF0LWNzcy1jb25maWctdG9rZW4uY29uc3QnO1xuXG5pbnRlcmZhY2UgQ3NzVmFyaWFibGUge1xuICBuYW1lOiBzdHJpbmc7XG4gIHZhbDogc3RyaW5nO1xufVxuXG4vLyBAc2VlOiBodHRwczovL2dpdGh1Yi5jb20vYW5ndWxhci9hbmd1bGFyL2lzc3Vlcy8yMDM1MVxuLyoqIEBkeW5hbWljICovXG5ASW5qZWN0YWJsZSh7XG4gIHByb3ZpZGVkSW46ICdyb290J1xufSlcbmV4cG9ydCBjbGFzcyBNYXRlcmlhbENzc1ZhcnNTZXJ2aWNlIHtcbiAgcHJpdmF0ZSBzdGF0aWMgQ09OVFJBU1RfUFJFRklYID0gJ2NvbnRyYXN0LSc7XG4gIHByaXZhdGUgc3RhdGljIERBUktfVEVYVF9WQVIgPSAnLS1kYXJrLXByaW1hcnktdGV4dCc7XG4gIHByaXZhdGUgc3RhdGljIExJR0hUX1RFWFRfVkFSID0gJy0tbGlnaHQtcHJpbWFyeS10ZXh0JztcblxuICBwcml2YXRlIHJlbmRlcmVyOiBSZW5kZXJlcjI7XG4gIHByaXZhdGUgUk9PVDogSFRNTEVsZW1lbnQ7XG5cbiAgLy8gVGhpcyBzaG91bGQgYmUgcmVhZG9ubHkgZnJvbSB0aGUgb3V0c2lkZVxuICBjZmc6IE1hdGVyaWFsQ3NzVmFyaWFibGVzQ29uZmlnO1xuICBwcmltYXJ5OiBzdHJpbmc7XG4gIGFjY2VudDogc3RyaW5nO1xuICB3YXJuOiBzdHJpbmc7XG4gIGlzRGFya1RoZW1lOiBib29sZWFuO1xuICBjb250cmFzdENvbG9yVGhyZXNob2xkUHJpbWFyeTogSHVlVmFsdWUgPSAnNDAwJztcbiAgY29udHJhc3RDb2xvclRocmVzaG9sZEFjY2VudDogSHVlVmFsdWUgPSAnNDAwJztcbiAgY29udHJhc3RDb2xvclRocmVzaG9sZFdhcm46IEh1ZVZhbHVlID0gJzQwMCc7XG4gIGlzQXV0b0NvbnRyYXN0ID0gZmFsc2U7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcmVuZGVyZXJGYWN0b3J5OiBSZW5kZXJlckZhY3RvcnkyLFxuICAgIEBJbmplY3QoRE9DVU1FTlQpIHByaXZhdGUgZG9jdW1lbnQ6IERvY3VtZW50LFxuICAgIEBJbmplY3QoTUFURVJJQUxfQ1NTX1ZBUlNfQ0ZHKSBjZmc6IE1hdGVyaWFsQ3NzVmFyaWFibGVzQ29uZmlnLFxuICApIHtcbiAgICB0aGlzLnJlbmRlcmVyID0gcmVuZGVyZXJGYWN0b3J5LmNyZWF0ZVJlbmRlcmVyKG51bGwsIG51bGwpO1xuICAgIHRoaXMuUk9PVCA9IHRoaXMuZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50O1xuXG4gICAgdGhpcy5jZmcgPSB7XG4gICAgICAuLi5ERUZBVUxUX01BVF9DU1NfQ0ZHLFxuICAgICAgLi4uY2ZnLFxuICAgIH07XG4gICAgdGhpcy5pc0F1dG9Db250cmFzdCA9IHRoaXMuY2ZnLmlzQXV0b0NvbnRyYXN0O1xuXG4gICAgaWYgKHRoaXMuY2ZnLmlzRGFya1RoZW1lKSB7XG4gICAgICB0aGlzLnNldERhcmtUaGVtZSh0aGlzLmNmZy5pc0RhcmtUaGVtZSk7XG4gICAgfVxuICAgIGlmICh0aGlzLmNmZy5wcmltYXJ5KSB7XG4gICAgICB0aGlzLnNldFByaW1hcnlDb2xvcih0aGlzLmNmZy5wcmltYXJ5KTtcbiAgICB9XG4gICAgaWYgKHRoaXMuY2ZnLmFjY2VudCkge1xuICAgICAgdGhpcy5zZXRBY2NlbnRDb2xvcih0aGlzLmNmZy5hY2NlbnQpO1xuICAgIH1cbiAgICBpZiAodGhpcy5jZmcud2Fybikge1xuICAgICAgdGhpcy5zZXRXYXJuQ29sb3IodGhpcy5jZmcud2Fybik7XG4gICAgfVxuICB9XG5cbiAgc2V0UHJpbWFyeUNvbG9yKGhleDogc3RyaW5nKSB7XG4gICAgdGhpcy5wcmltYXJ5ID0gaGV4O1xuICAgIGNvbnN0IHZhclByZWZpeCA9IE1hdENzc1BhbGV0dGVQcmVmaXguUHJpbWFyeTtcbiAgICBjb25zdCBzdHlsZVByaW1hcnkgPSB0aGlzLl9jb21wdXRlUGFsZXR0ZUNvbG9ycyh2YXJQcmVmaXgsIHRoaXMucHJpbWFyeSk7XG4gICAgdGhpcy5fc2V0U3R5bGUoc3R5bGVQcmltYXJ5KTtcblxuICAgIGlmICh0aGlzLmlzQXV0b0NvbnRyYXN0KSB7XG4gICAgICB0aGlzLl9yZWNhbGN1bGF0ZUFuZFNldENvbnRyYXN0Q29sb3IodmFyUHJlZml4KTtcbiAgICB9XG4gIH1cblxuICBzZXRBY2NlbnRDb2xvcihoZXg6IHN0cmluZykge1xuICAgIHRoaXMuYWNjZW50ID0gaGV4O1xuICAgIGNvbnN0IHZhclByZWZpeCA9IE1hdENzc1BhbGV0dGVQcmVmaXguQWNjZW50O1xuICAgIGNvbnN0IHN0eWxlQWNjZW50ID0gdGhpcy5fY29tcHV0ZVBhbGV0dGVDb2xvcnModmFyUHJlZml4LCB0aGlzLmFjY2VudCk7XG4gICAgdGhpcy5fc2V0U3R5bGUoc3R5bGVBY2NlbnQpO1xuXG4gICAgaWYgKHRoaXMuaXNBdXRvQ29udHJhc3QpIHtcbiAgICAgIHRoaXMuX3JlY2FsY3VsYXRlQW5kU2V0Q29udHJhc3RDb2xvcih2YXJQcmVmaXgpO1xuICAgIH1cbiAgfVxuXG4gIHNldFdhcm5Db2xvcihoZXg6IHN0cmluZykge1xuICAgIHRoaXMud2FybiA9IGhleDtcbiAgICBjb25zdCB2YXJQcmVmaXggPSBNYXRDc3NQYWxldHRlUHJlZml4Lldhcm47XG4gICAgY29uc3Qgc3R5bGVXYXJuID0gdGhpcy5fY29tcHV0ZVBhbGV0dGVDb2xvcnModmFyUHJlZml4LCB0aGlzLndhcm4pO1xuICAgIHRoaXMuX3NldFN0eWxlKHN0eWxlV2Fybik7XG5cbiAgICBpZiAodGhpcy5pc0F1dG9Db250cmFzdCkge1xuICAgICAgdGhpcy5fcmVjYWxjdWxhdGVBbmRTZXRDb250cmFzdENvbG9yKHZhclByZWZpeCk7XG4gICAgfVxuICB9XG5cbiAgc2V0VmFyaWFibGUoY3NzVmFyTmFtZTogTWF0ZXJpYWxDc3NWYXJpYWJsZXMsIHZhbHVlOiBzdHJpbmcpIHtcbiAgICB0aGlzLl9zZXRTdHlsZShbe1xuICAgICAgbmFtZTogY3NzVmFyTmFtZSxcbiAgICAgIHZhbDogdmFsdWUsXG4gICAgfV0pO1xuICB9XG5cbiAgc2V0RGFya1RoZW1lKGlzRGFyazogYm9vbGVhbikge1xuICAgIGlmIChpc0RhcmspIHtcbiAgICAgIHRoaXMuZG9jdW1lbnQuYm9keS5jbGFzc0xpc3QucmVtb3ZlKHRoaXMuY2ZnLmxpZ2h0VGhlbWVDbGFzcyk7XG4gICAgICB0aGlzLmRvY3VtZW50LmJvZHkuY2xhc3NMaXN0LmFkZCh0aGlzLmNmZy5kYXJrVGhlbWVDbGFzcyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuZG9jdW1lbnQuYm9keS5jbGFzc0xpc3QucmVtb3ZlKHRoaXMuY2ZnLmRhcmtUaGVtZUNsYXNzKTtcbiAgICAgIHRoaXMuZG9jdW1lbnQuYm9keS5jbGFzc0xpc3QuYWRkKHRoaXMuY2ZnLmxpZ2h0VGhlbWVDbGFzcyk7XG4gICAgfVxuICAgIHRoaXMuaXNEYXJrVGhlbWUgPSBpc0Rhcms7XG4gIH1cblxuICBzZXRBdXRvQ29udHJhc3RFbmFibGVkKHZhbDogYm9vbGVhbikge1xuICAgIHRoaXMuaXNBdXRvQ29udHJhc3QgPSB2YWw7XG4gICAgaWYgKHZhbCkge1xuICAgICAgdGhpcy5fcmVjYWxjdWxhdGVBbmRTZXRDb250cmFzdENvbG9yKE1hdENzc1BhbGV0dGVQcmVmaXguUHJpbWFyeSk7XG4gICAgICB0aGlzLl9yZWNhbGN1bGF0ZUFuZFNldENvbnRyYXN0Q29sb3IoTWF0Q3NzUGFsZXR0ZVByZWZpeC5BY2NlbnQpO1xuICAgICAgdGhpcy5fcmVjYWxjdWxhdGVBbmRTZXRDb250cmFzdENvbG9yKE1hdENzc1BhbGV0dGVQcmVmaXguV2Fybik7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuc2V0Q29udHJhc3RDb2xvclRocmVzaG9sZFByaW1hcnkodGhpcy5jb250cmFzdENvbG9yVGhyZXNob2xkUHJpbWFyeSk7XG4gICAgICB0aGlzLnNldENvbnRyYXN0Q29sb3JUaHJlc2hvbGRBY2NlbnQodGhpcy5jb250cmFzdENvbG9yVGhyZXNob2xkQWNjZW50KTtcbiAgICAgIHRoaXMuc2V0Q29udHJhc3RDb2xvclRocmVzaG9sZFdhcm4odGhpcy5jb250cmFzdENvbG9yVGhyZXNob2xkV2Fybik7XG4gICAgfVxuICB9XG5cbiAgc2V0Q29udHJhc3RDb2xvclRocmVzaG9sZFByaW1hcnkodGhyZXNob2xkOiBIdWVWYWx1ZSkge1xuICAgIHRoaXMuY29udHJhc3RDb2xvclRocmVzaG9sZFByaW1hcnkgPSB0aHJlc2hvbGQ7XG4gICAgdGhpcy5zZXRDb250cmFzdENvbG9yVGhyZXNob2xkKHRocmVzaG9sZCwgTWF0Q3NzUGFsZXR0ZVByZWZpeC5QcmltYXJ5KTtcbiAgfVxuXG4gIHNldENvbnRyYXN0Q29sb3JUaHJlc2hvbGRBY2NlbnQodGhyZXNob2xkOiBIdWVWYWx1ZSkge1xuICAgIHRoaXMuY29udHJhc3RDb2xvclRocmVzaG9sZEFjY2VudCA9IHRocmVzaG9sZDtcbiAgICB0aGlzLnNldENvbnRyYXN0Q29sb3JUaHJlc2hvbGQodGhyZXNob2xkLCBNYXRDc3NQYWxldHRlUHJlZml4LkFjY2VudCk7XG4gIH1cblxuICBzZXRDb250cmFzdENvbG9yVGhyZXNob2xkV2Fybih0aHJlc2hvbGQ6IEh1ZVZhbHVlKSB7XG4gICAgdGhpcy5jb250cmFzdENvbG9yVGhyZXNob2xkV2FybiA9IHRocmVzaG9sZDtcbiAgICB0aGlzLnNldENvbnRyYXN0Q29sb3JUaHJlc2hvbGQodGhyZXNob2xkLCBNYXRDc3NQYWxldHRlUHJlZml4Lldhcm4pO1xuICB9XG5cbiAgc2V0Q29udHJhc3RDb2xvclRocmVzaG9sZCh0aHJlc2hvbGQ6IEh1ZVZhbHVlLCBwYWxldHRlUHJlZml4OiBNYXRDc3NQYWxldHRlUHJlZml4KSB7XG4gICAgbGV0IGNvbG9yID0gTWF0ZXJpYWxDc3NWYXJzU2VydmljZS5EQVJLX1RFWFRfVkFSO1xuICAgIGNvbnN0IHVwZGF0ZXMgPSB0aGlzLmNmZy5zb3J0ZWRIdWVzLm1hcCgoaHVlKSA9PiB7XG4gICAgICBpZiAoaHVlID09PSB0aHJlc2hvbGQpIHtcbiAgICAgICAgY29sb3IgPSBNYXRlcmlhbENzc1ZhcnNTZXJ2aWNlLkxJR0hUX1RFWFRfVkFSO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdmFsOiB0aGlzLl9nZXRDc3NWYXJWYWx1ZShjb2xvciksXG4gICAgICAgIG5hbWU6IGAke3BhbGV0dGVQcmVmaXggKyBNYXRlcmlhbENzc1ZhcnNTZXJ2aWNlLkNPTlRSQVNUX1BSRUZJWH0ke2h1ZX0tcmdiYCxcbiAgICAgIH07XG4gICAgfSk7XG4gICAgdGhpcy5fc2V0U3R5bGUodXBkYXRlcyk7XG4gIH1cblxuICAvKipcbiAgICogR2VuZXJhdGUgcGFsZXR0ZSBjb2xvciBiYXNlZCBvbiB0cmFkaXRpb25hbCB2YWx1ZXNcbiAgICovXG4gIHNldEFsdGVybmF0aXZlQ29sb3JBbGdvcml0aG0odHJhZGl0aW9uYWw6IGJvb2xlYW4pOiB2b2lkIHtcbiAgICB0aGlzLmNmZy5pc0FsdGVybmF0aXZlQ29sb3JBbGdvcml0aG0gPSB0cmFkaXRpb25hbDtcbiAgICB0aGlzLnNldFByaW1hcnlDb2xvcih0aGlzLnByaW1hcnkpO1xuICAgIHRoaXMuc2V0QWNjZW50Q29sb3IodGhpcy5hY2NlbnQpO1xuICAgIHRoaXMuc2V0V2FybkNvbG9yKHRoaXMud2Fybik7XG4gIH1cblxuICAvKiogQGRlcHJlY2F0ZWQgdXNlIHNldENvbnRyYXN0Q29sb3JUaHJlc2hvbGRQcmltYXJ5IGluc3RlYWQgKi9cbiAgY2hhbmdlQ29udHJhc3RDb2xvclRocmVzaG9sZFByaW1hcnkodGhyZXNob2xkOiBIdWVWYWx1ZSkge1xuICAgIHRoaXMuc2V0Q29udHJhc3RDb2xvclRocmVzaG9sZFByaW1hcnkodGhyZXNob2xkKTtcbiAgfVxuXG4gIC8qKiBAZGVwcmVjYXRlZCB1c2Ugc2V0Q29udHJhc3RDb2xvclRocmVzaG9sZEFjY2VudCBpbnN0ZWFkICovXG4gIGNoYW5nZUNvbnRyYXN0Q29sb3JUaHJlc2hvbGRBY2NlbnQodGhyZXNob2xkOiBIdWVWYWx1ZSkge1xuICAgIHRoaXMuc2V0Q29udHJhc3RDb2xvclRocmVzaG9sZEFjY2VudCh0aHJlc2hvbGQpO1xuICB9XG5cbiAgLyoqIEBkZXByZWNhdGVkIHVzZSBzZXRDb250cmFzdENvbG9yVGhyZXNob2xkV2FybiBpbnN0ZWFkICovXG4gIGNoYW5nZUNvbnRyYXN0Q29sb3JUaHJlc2hvbGRXYXJuKHRocmVzaG9sZDogSHVlVmFsdWUpIHtcbiAgICB0aGlzLnNldENvbnRyYXN0Q29sb3JUaHJlc2hvbGRXYXJuKHRocmVzaG9sZCk7XG4gIH1cblxuICAvKiogQGRlcHJlY2F0ZWQgdXNlIHNldENvbnRyYXN0Q29sb3JUaHJlc2hvbGQgaW5zdGVhZCAqL1xuICBjaGFuZ2VDb250cmFzdENvbG9yVGhyZXNob2xkKHRocmVzaG9sZDogSHVlVmFsdWUsIHBhbGV0dGVQcmVmaXg6IE1hdENzc1BhbGV0dGVQcmVmaXgpIHtcbiAgICB0aGlzLnNldENvbnRyYXN0Q29sb3JUaHJlc2hvbGQodGhyZXNob2xkLCBwYWxldHRlUHJlZml4KTtcbiAgfVxuXG4gIGdldFBhbGV0dGVGb3JDb2xvcihoZXg6IHN0cmluZyk6IE1hdENzc0h1ZUNvbG9yTWFwSXRlbVtdIHtcbiAgICBpZiAodGhpcy5jZmcuaXNBbHRlcm5hdGl2ZUNvbG9yQWxnb3JpdGhtKSB7XG4gICAgICByZXR1cm4gdGhpcy5nZXRUcmFkaXRpb25hbFBhbGV0dGVGb3JDb2xvcihoZXgpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gdGhpcy5nZXRDb25zdGFudGluUGFsZXR0ZUZvckNvbG9yKGhleCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBnZXRUcmFkaXRpb25hbFBhbGV0dGVGb3JDb2xvcihoZXg6IHN0cmluZyk6IE1hdENzc0h1ZUNvbG9yTWFwSXRlbVtdIHtcbiAgICByZXR1cm4gdGhpcy5jZmcuY29sb3JNYXAubWFwKGl0ZW0gPT4ge1xuICAgICAgY29uc3QgbWFwcGVkQ29sb3IgPSBuZXcgVGlueUNvbG9yKGhleClcbiAgICAgICAgLmxpZ2h0ZW4oaXRlbS5tYXBbMF0pXG4gICAgICAgIC5kYXJrZW4oaXRlbS5tYXBbMV0pXG4gICAgICAgIC5zYXR1cmF0ZShpdGVtLm1hcFsyXSk7XG4gICAgICBjb25zdCBjID0gbmV3IFRpbnlDb2xvcihtYXBwZWRDb2xvcik7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBodWU6IGl0ZW0ubmFtZSxcbiAgICAgICAgaXNMaWdodDogYy5pc0xpZ2h0KCksXG4gICAgICAgIGNvbG9yOiB7XG4gICAgICAgICAgLi4uYy50b1JnYigpLFxuICAgICAgICAgIHN0cjogYHJnYigke2MudG9SZ2IoKS5yfSwke2MudG9SZ2IoKS5nfSwke2MudG9SZ2IoKS5ifSlgXG4gICAgICAgIH1cbiAgICAgIH07XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGdldENvbnN0YW50aW5QYWxldHRlRm9yQ29sb3IoaGV4OiBzdHJpbmcpOiBNYXRDc3NIdWVDb2xvck1hcEl0ZW1bXSB7XG4gICAgcmV0dXJuIHRoaXMuY2ZnLmNvbG9yTWFwLm1hcCgoaXRlbSkgPT4ge1xuICAgICAgY29uc3QgYyA9IHRoaXMuY29tcHV0ZVBhbGxldFRyaWFkKGhleCwgaXRlbS5uYW1lKTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGh1ZTogaXRlbS5uYW1lLFxuICAgICAgICBpc0xpZ2h0OiBjLmlzTGlnaHQsXG4gICAgICAgIGNvbG9yOiB7XG4gICAgICAgICAgLi4uYy5yZ2IsXG4gICAgICAgICAgc3RyOiBgcmdiKCR7Yy5yZ2Iucn0sJHtjLnJnYi5nfSwke2MucmdiLmJ9KWBcbiAgICAgICAgfVxuICAgICAgfTtcbiAgICB9KTtcbiAgfVxuXG4gIGdldFBhbGV0dGVXaXRoQ29udHJhc3RGb3JDb2xvcihoZXg6IHN0cmluZyk6IE1hdENzc0h1ZUNvbG9yQ29udHJhc3RNYXBJdGVtW10ge1xuICAgIGNvbnN0IGxpZ2h0VGV4dCA9IHRoaXMuX2dldENzc1ZhclZhbHVlKE1hdGVyaWFsQ3NzVmFyc1NlcnZpY2UuTElHSFRfVEVYVF9WQVIpO1xuICAgIGNvbnN0IGRhcmtUZXh0ID0gdGhpcy5fZ2V0Q3NzVmFyVmFsdWUoTWF0ZXJpYWxDc3NWYXJzU2VydmljZS5EQVJLX1RFWFRfVkFSKTtcbiAgICBjb25zdCBwYWxldHRlID0gdGhpcy5nZXRQYWxldHRlRm9yQ29sb3IoaGV4KTtcblxuICAgIC8vIFRPRE8gaGFuZGxlIG5vbiBhdXRvIGNhc2VcbiAgICByZXR1cm4gcGFsZXR0ZS5tYXAoKGl0ZW0pID0+IHtcbiAgICAgIGNvbnN0IGNvbnRyYXN0U3RyID0gaXRlbS5pc0xpZ2h0XG4gICAgICAgID8gbGlnaHRUZXh0XG4gICAgICAgIDogZGFya1RleHQ7XG5cbiAgICAgIGNvbnN0IHNMaWdodCA9IGNvbnRyYXN0U3RyLnNwbGl0KCcsJykubWFwKHYgPT4gK3YpO1xuICAgICAgY29uc3QgY2NvID0ge3I6IHNMaWdodFswXSwgZzogc0xpZ2h0WzFdLCBiOiBzTGlnaHRbMl0sIGE6IDF9O1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgLi4uaXRlbSxcbiAgICAgICAgY29udHJhc3Q6IHtcbiAgICAgICAgICAuLi5jY28sXG4gICAgICAgICAgc3RyOiBgJHtjY28ucn0sJHtjY28uZ30sJHtjY28uYn1gXG4gICAgICAgIH0sXG4gICAgICB9O1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBfY29tcHV0ZVBhbGV0dGVDb2xvcnMocHJlZml4OiBNYXRDc3NQYWxldHRlUHJlZml4LCBoZXg6IHN0cmluZyk6IENzc1ZhcmlhYmxlW10ge1xuICAgIHJldHVybiB0aGlzLmdldFBhbGV0dGVGb3JDb2xvcihoZXgpLm1hcChpdGVtID0+IHtcbiAgICAgIGNvbnN0IGMgPSBpdGVtLmNvbG9yO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgbmFtZTogYCR7cHJlZml4fSR7aXRlbS5odWV9YCxcbiAgICAgICAgdmFsOiBgJHtjLnJ9LCAke2MuZ30sICR7Yy5ifWBcbiAgICAgIH07XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIF9yZWNhbGN1bGF0ZUFuZFNldENvbnRyYXN0Q29sb3IocGFsZXR0ZVByZWZpeDogTWF0Q3NzUGFsZXR0ZVByZWZpeCkge1xuICAgIGNvbnN0IHVwZGF0ZXMgPSB0aGlzLl9jYWxjdWxhdGVDb250cmFzdENvbG9yc0ZvckN1cnJlbnRWYWx1ZXMocGFsZXR0ZVByZWZpeClcbiAgICAgIC5tYXAoKHtjb250cmFzdENvbG9yVmFyLCBodWV9KSA9PiB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgdmFsOiB0aGlzLl9nZXRDc3NWYXJWYWx1ZShjb250cmFzdENvbG9yVmFyKSxcbiAgICAgICAgICBuYW1lOiBgJHtwYWxldHRlUHJlZml4ICsgTWF0ZXJpYWxDc3NWYXJzU2VydmljZS5DT05UUkFTVF9QUkVGSVh9JHtodWV9LXJnYmAsXG4gICAgICAgIH07XG4gICAgICB9KTtcbiAgICB0aGlzLl9zZXRTdHlsZSh1cGRhdGVzKTtcbiAgfVxuXG4gIHByaXZhdGUgX2NhbGN1bGF0ZUNvbnRyYXN0Q29sb3JzRm9yQ3VycmVudFZhbHVlcyhwYWxldHRlUHJlZml4OiBNYXRDc3NQYWxldHRlUHJlZml4KTpcbiAgICB7IGNvbnRyYXN0Q29sb3JWYXI6IHN0cmluZywgaHVlOiBIdWVWYWx1ZSB9W10ge1xuICAgIHJldHVybiB0aGlzLmNmZy5zb3J0ZWRIdWVzLm1hcCgoaHVlKSA9PiB7XG4gICAgICBjb25zdCBodWVWYXJWYWwgPSB0aGlzLl9nZXRDc3NWYXJWYWx1ZShgJHtwYWxldHRlUHJlZml4fSR7aHVlfWApO1xuICAgICAgY29uc3QgYyA9IG5ldyBUaW55Q29sb3IoYHJnYigke2h1ZVZhclZhbH0pYCk7XG4gICAgICBjb25zdCBjb250cmFzdENvbG9yVmFyID0gYy5pc0RhcmsoKVxuICAgICAgICA/IE1hdGVyaWFsQ3NzVmFyc1NlcnZpY2UuTElHSFRfVEVYVF9WQVJcbiAgICAgICAgOiBNYXRlcmlhbENzc1ZhcnNTZXJ2aWNlLkRBUktfVEVYVF9WQVI7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBjb250cmFzdENvbG9yVmFyLFxuICAgICAgICBodWUsXG4gICAgICB9O1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBfc2V0U3R5bGUodmFyczogQ3NzVmFyaWFibGVbXSkge1xuICAgIHZhcnMuZm9yRWFjaChzID0+IHtcbiAgICAgIHRoaXMucmVuZGVyZXIuc2V0U3R5bGUodGhpcy5ST09ULCBzLm5hbWUsIHMudmFsLCBSZW5kZXJlclN0eWxlRmxhZ3MyLkRhc2hDYXNlKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgX2dldENzc1ZhclZhbHVlKHY6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgcmV0dXJuIGdldENvbXB1dGVkU3R5bGUodGhpcy5ST09UKS5nZXRQcm9wZXJ0eVZhbHVlKHYpO1xuICB9XG5cbiAgLyoqXG4gICAqIENvbXB1dGUgcGFsbGV0IGNvbG9ycyBiYXNlZCBvbiBhIFRyaWFkIChDb25zdGFudGluKVxuICAgKiBzZWU6IGh0dHBzOi8vZ2l0aHViLmNvbS9tYml0c29uL21jZ1xuICAgKi9cbiAgcHJpdmF0ZSBjb21wdXRlUGFsbGV0VHJpYWQoaGV4OiBzdHJpbmcsIGh1ZTogSHVlVmFsdWUpIHtcbiAgICBjb25zdCBiYXNlTGlnaHQgPSBuZXcgVGlueUNvbG9yKCcjZmZmZmZmJyk7XG4gICAgY29uc3QgYmFzZURhcmsgPSB0aGlzLm11bHRpcGx5KG5ldyBUaW55Q29sb3IoaGV4KS50b1JnYigpLCBuZXcgVGlueUNvbG9yKGhleCkudG9SZ2IoKSk7XG4gICAgY29uc3QgYmFzZVRyaWFkID0gbmV3IFRpbnlDb2xvcihoZXgpLnRldHJhZCgpO1xuICAgIGxldCBjb2xvcjogeyByZ2I6IE51bWJlcmlmeTxSR0JBPiwgaXNMaWdodDogYm9vbGVhbiB9O1xuXG4gICAgc3dpdGNoIChodWUpIHtcbiAgICAgIGNhc2UgJzUwJzpcbiAgICAgICAgY29sb3IgPSB0aGlzLmdldENvbG9yT2JqZWN0KGJhc2VMaWdodC5taXgoaGV4LCAxMikpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJzEwMCc6XG4gICAgICAgIGNvbG9yID0gdGhpcy5nZXRDb2xvck9iamVjdChiYXNlTGlnaHQubWl4KGhleCwgMzApKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICcyMDAnOlxuICAgICAgICBjb2xvciA9IHRoaXMuZ2V0Q29sb3JPYmplY3QoYmFzZUxpZ2h0Lm1peChoZXgsIDUwKSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnMzAwJzpcbiAgICAgICAgY29sb3IgPSB0aGlzLmdldENvbG9yT2JqZWN0KGJhc2VMaWdodC5taXgoaGV4LCA3MCkpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJzQwMCc6XG4gICAgICAgIGNvbG9yID0gdGhpcy5nZXRDb2xvck9iamVjdChiYXNlTGlnaHQubWl4KGhleCwgODUpKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICc1MDAnOlxuICAgICAgICBjb2xvciA9IHRoaXMuZ2V0Q29sb3JPYmplY3QoYmFzZUxpZ2h0Lm1peChoZXgsIDEwMCkpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJzYwMCc6XG4gICAgICAgIGNvbG9yID0gdGhpcy5nZXRDb2xvck9iamVjdChiYXNlRGFyay5taXgoaGV4LCA4NykpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJzcwMCc6XG4gICAgICAgIGNvbG9yID0gdGhpcy5nZXRDb2xvck9iamVjdChiYXNlRGFyay5taXgoaGV4LCA3MCkpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJzgwMCc6XG4gICAgICAgIGNvbG9yID0gdGhpcy5nZXRDb2xvck9iamVjdChiYXNlRGFyay5taXgoaGV4LCA1NCkpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJzkwMCc6XG4gICAgICAgIGNvbG9yID0gdGhpcy5nZXRDb2xvck9iamVjdChiYXNlRGFyay5taXgoaGV4LCAyNSkpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ0ExMDAnOlxuICAgICAgICBjb2xvciA9IHRoaXMuZ2V0Q29sb3JPYmplY3QoYmFzZURhcmsubWl4KGJhc2VUcmlhZFs0XSwgMTUpLnNhdHVyYXRlKDgwKS5saWdodGVuKDY1KSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnQTIwMCc6XG4gICAgICAgIGNvbG9yID0gdGhpcy5nZXRDb2xvck9iamVjdChiYXNlRGFyay5taXgoYmFzZVRyaWFkWzRdLCAxNSkuc2F0dXJhdGUoODApLmxpZ2h0ZW4oNTUpKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdBNDAwJzpcbiAgICAgICAgY29sb3IgPSB0aGlzLmdldENvbG9yT2JqZWN0KGJhc2VEYXJrLm1peChiYXNlVHJpYWRbNF0sIDE1KS5zYXR1cmF0ZSgxMDApLmxpZ2h0ZW4oNDUpKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdBNzAwJzpcbiAgICAgICAgY29sb3IgPSB0aGlzLmdldENvbG9yT2JqZWN0KGJhc2VEYXJrLm1peChiYXNlVHJpYWRbNF0sIDE1KS5zYXR1cmF0ZSgxMDApLmxpZ2h0ZW4oNDApKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICBicmVhaztcbiAgICB9XG4gICAgcmV0dXJuIGNvbG9yO1xuICB9XG5cbiAgcHJpdmF0ZSBtdWx0aXBseShyZ2IxOiBOdW1iZXJpZnk8UkdCQT4sIHJnYjI6IE51bWJlcmlmeTxSR0JBPik6IFRpbnlDb2xvciB7XG4gICAgcmdiMS5iID0gTWF0aC5mbG9vcihyZ2IxLmIgKiByZ2IyLmIgLyAyNTUpO1xuICAgIHJnYjEuZyA9IE1hdGguZmxvb3IocmdiMS5nICogcmdiMi5nIC8gMjU1KTtcbiAgICByZ2IxLnIgPSBNYXRoLmZsb29yKHJnYjEuciAqIHJnYjIuciAvIDI1NSk7XG4gICAgcmV0dXJuIG5ldyBUaW55Q29sb3IoJ3JnYsKgJyArIHJnYjEuciArICfCoCcgKyByZ2IxLmcgKyAnwqAnICsgcmdiMS5iKTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0Q29sb3JPYmplY3QodmFsdWU6IFRpbnlDb2xvcikge1xuICAgIGNvbnN0IGMgPSBuZXcgVGlueUNvbG9yKHZhbHVlKTtcbiAgICByZXR1cm4ge3JnYjogYy50b1JnYigpLCBpc0xpZ2h0OiBjLmlzTGlnaHQoKX07XG4gIH1cblxufVxuIl19