UNPKG

angular-material-css-vars-legacy

Version:

Little library to use css variables for @angular/material for legacy components

328 lines 44.8 kB
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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWF0ZXJpYWwtY3NzLXZhcnMuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL21hdGVyaWFsLWNzcy12YXJzL3NyYy9saWIvbWF0ZXJpYWwtY3NzLXZhcnMuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUMsTUFBTSxFQUFFLFVBQVUsRUFBK0IsbUJBQW1CLEVBQUMsTUFBTSxlQUFlLENBQUM7QUFDbkcsT0FBTyxFQUFrQixTQUFTLEVBQUMsTUFBTSxpQkFBaUIsQ0FBQztBQUMzRCxPQUFPLEVBSUwsbUJBQW1CLEVBR3BCLE1BQU0sU0FBUyxDQUFDO0FBQ2pCLE9BQU8sRUFBQyxRQUFRLEVBQUMsTUFBTSxpQkFBaUIsQ0FBQztBQUN6QyxPQUFPLEVBQUMsbUJBQW1CLEVBQUMsTUFBTSxxQkFBcUIsQ0FBQztBQUN4RCxPQUFPLEVBQUMscUJBQXFCLEVBQUMsTUFBTSwrQkFBK0IsQ0FBQzs7QUFPcEUsd0RBQXdEO0FBQ3hELGVBQWU7QUFDZixNQUdhLHNCQUFzQjthQUNsQixvQkFBZSxHQUFHLFdBQVcsQUFBZCxDQUFlO2FBQzlCLGtCQUFhLEdBQUcscUJBQXFCLEFBQXhCLENBQXlCO2FBQ3RDLG1CQUFjLEdBQUcsc0JBQXNCLEFBQXpCLENBQTBCO0lBZ0J2RCxZQUNFLGVBQWlDLEVBQ1AsUUFBa0IsRUFDYixHQUErQjtRQURwQyxhQUFRLEdBQVIsUUFBUSxDQUFVO1FBUDlDLGtDQUE2QixHQUFhLEtBQUssQ0FBQztRQUNoRCxpQ0FBNEIsR0FBYSxLQUFLLENBQUM7UUFDL0MsK0JBQTBCLEdBQWEsS0FBSyxDQUFDO1FBQzdDLG1CQUFjLEdBQUcsS0FBSyxDQUFDO1FBT3JCLElBQUksQ0FBQyxRQUFRLEdBQUcsZUFBZSxDQUFDLGNBQWMsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDM0QsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUMsUUFBUSxD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LEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDLENBQUM7UUFDM0MsSUFBSSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQztRQUMzQyxPQUFPLElBQUksU0FBUyxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUMsQ0FBQyxHQUFHLEdBQUcsR0FBRyxJQUFJLENBQUMsQ0FBQyxHQUFHLEdBQUcsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDdEUsQ0FBQztJQUVPLGNBQWMsQ0FBQyxLQUFnQjtRQUNyQyxNQUFNLENBQUMsR0FBRyxJQUFJLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUMvQixPQUFPLEVBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRSxPQUFPLEVBQUUsQ0FBQyxDQUFDLE9BQU8sRUFBRSxFQUFDLENBQUM7SUFDaEQsQ0FBQzsrR0E1VlUsc0JBQXNCLGtEQXFCdkIsUUFBUSxhQUNSLHFCQUFxQjttSEF0QnBCLHNCQUFzQixjQUZyQixNQUFNOztTQUVQLHNCQUFzQjs0RkFBdEIsc0JBQXNCO2tCQUhsQyxVQUFVO21CQUFDO29CQUNWLFVBQVUsRUFBRSxNQUFNO2lCQUNuQjs7MEJBc0JJLE1BQU07MkJBQUMsUUFBUTs7MEJBQ2YsTUFBTTsyQkFBQyxxQkFBcUIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge0luamVjdCwgSW5qZWN0YWJsZSwgUmVuZGVyZXIyLCBSZW5kZXJlckZhY3RvcnkyLCBSZW5kZXJlclN0eWxlRmxhZ3MyfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7TnVtYmVyaWZ5LCBSR0JBLCBUaW55Q29sb3J9IGZyb20gJ0BjdHJsL3Rpbnljb2xvcic7XG5pbXBvcnQge1xuICBIdWVWYWx1ZSxcbiAgTWF0Q3NzSHVlQ29sb3JDb250cmFzdE1hcEl0ZW0sXG4gIE1hdENzc0h1ZUNvbG9yTWFwSXRlbSxcbiAgTWF0Q3NzUGFsZXR0ZVByZWZpeCxcbiAgTWF0ZXJpYWxDc3NWYXJpYWJsZXMsXG4gIE1hdGVyaWFsQ3NzVmFyaWFibGVzQ29uZmlnXG59IGZyb20gJy4vbW9kZWwnO1xuaW1wb3J0IHtET0NVTUVOVH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7REVGQVVMVF9NQVRfQ1NTX0NGR30gZnJvbSAnLi9kZWZhdWx0LWNmZy5jb25zdCc7XG5pbXBvcnQge01BVEVSSUFMX0NTU19WQVJTX0NGR30gZnJvbSAnLi4vbWF0LWNzcy1jb25maWctdG9rZW4uY29uc3QnO1xuXG5pbnRlcmZhY2UgQ3NzVmFyaWFibGUge1xuICBuYW1lOiBzdHJpbmc7XG4gIHZhbDogc3RyaW5nO1xufVxuXG4vLyBAc2VlOiBodHRwczovL2dpdGh1Yi5jb20vYW5ndWxhci9hbmd1bGFyL2lzc3Vlcy8yMDM1MVxuLyoqIEBkeW5hbWljICovXG5ASW5qZWN0YWJsZSh7XG4gIHByb3ZpZGVkSW46ICdyb290J1xufSlcbmV4cG9ydCBjbGFzcyBNYXRlcmlhbENzc1ZhcnNTZXJ2aWNlIHtcbiAgcHJpdmF0ZSBzdGF0aWMgQ09OVFJBU1RfUFJFRklYID0gJ2NvbnRyYXN0LSc7XG4gIHByaXZhdGUgc3RhdGljIERBUktfVEVYVF9WQVIgPSAnLS1kYXJrLXByaW1hcnktdGV4dCc7XG4gIHByaXZhdGUgc3RhdGljIExJR0hUX1RFWFRfVkFSID0gJy0tbGlnaHQtcHJpbWFyeS10ZXh0JztcblxuICBwcml2YXRlIHJlbmRlcmVyOiBSZW5kZXJlcjI7XG4gIHByaXZhdGUgUk9PVDogSFRNTEVsZW1lbnQ7XG5cbiAgLy8gVGhpcyBzaG91bGQgYmUgcmVhZG9ubHkgZnJvbSB0aGUgb3V0c2lkZVxuICBjZmc6IE1hdGVyaWFsQ3NzVmFyaWFibGVzQ29uZmlnO1xuICBwcmltYXJ5OiBzdHJpbmc7XG4gIGFjY2VudDogc3RyaW5nO1xuICB3YXJuOiBzdHJpbmc7XG4gIGlzRGFya1RoZW1lOiBib29sZWFuO1xuICBjb250cmFzdENvbG9yVGhyZXNob2xkUHJpbWFyeTogSHVlVmFsdWUgPSAnNDAwJztcbiAgY29udHJhc3RDb2xvclRocmVzaG9sZEFjY2VudDogSHVlVmFsdWUgPSAnNDAwJztcbiAgY29udHJhc3RDb2xvclRocmVzaG9sZFdhcm46IEh1ZVZhbHVlID0gJzQwMCc7XG4gIGlzQXV0b0NvbnRyYXN0ID0gZmFsc2U7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcmVuZGVyZXJGYWN0b3J5OiBSZW5kZXJlckZhY3RvcnkyLFxuICAgIEBJbmplY3QoRE9DVU1FTlQpIHByaXZhdGUgZG9jdW1lbnQ6IERvY3VtZW50LFxuICAgIEBJbmplY3QoTUFURVJJQUxfQ1NTX1ZBUlNfQ0ZHKSBjZmc6IE1hdGVyaWFsQ3NzVmFyaWFibGVzQ29uZmlnLFxuICApIHtcbiAgICB0aGlzLnJlbmRlcmVyID0gcmVuZGVyZXJGYWN0b3J5LmNyZWF0ZVJlbmRlcmVyKG51bGwsIG51bGwpO1xuICAgIHRoaXMuUk9PVCA9IHRoaXMuZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50O1xuXG4gICAgdGhpcy5jZmcgPSB7XG4gICAgICAuLi5ERUZBVUxUX01BVF9DU1NfQ0ZHLFxuICAgICAgLi4uY2ZnLFxuICAgIH07XG4gICAgdGhpcy5pc0F1dG9Db250cmFzdCA9IHRoaXMuY2ZnLmlzQXV0b0NvbnRyYXN0O1xuXG4gICAgaWYgKHRoaXMuY2ZnLmlzRGFya1RoZW1lKSB7XG4gICAgICB0aGlzLnNldERhcmtUaGVtZSh0aGlzLmNmZy5pc0RhcmtUaGVtZSk7XG4gICAgfVxuICAgIGlmICh0aGlzLmNmZy5wcmltYXJ5KSB7XG4gICAgICB0aGlzLnNldFByaW1hcnlDb2xvcih0aGlzLmNmZy5wcmltYXJ5KTtcbiAgICB9XG4gICAgaWYgKHRoaXMuY2ZnLmFjY2VudCkge1xuICAgICAgdGhpcy5zZXRBY2NlbnRDb2xvcih0aGlzLmNmZy5hY2NlbnQpO1xuICAgIH1cbiAgICBpZiAodGhpcy5jZmcud2Fybikge1xuICAgICAgdGhpcy5zZXRXYXJuQ29sb3IodGhpcy5jZmcud2Fybik7XG4gICAgfVxuICB9XG5cbiAgc2V0UHJpbWFyeUNvbG9yKGhleDogc3RyaW5nKSB7XG4gICAgdGhpcy5wcmltYXJ5ID0gaGV4O1xuICAgIGNvbnN0IHZhclByZWZpeCA9IE1hdENzc1BhbGV0dGVQcmVmaXguUHJpbWFyeTtcbiAgICBjb25zdCBzdHlsZVByaW1hcnkgPSB0aGlzLl9jb21wdXRlUGFsZXR0ZUNvbG9ycyh2YXJQcmVmaXgsIHRoaXMucHJpbWFyeSk7XG4gICAgdGhpcy5fc2V0U3R5bGUoc3R5bGVQcmltYXJ5KTtcblxuICAgIGlmICh0aGlzLmlzQXV0b0NvbnRyYXN0KSB7XG4gICAgICB0aGlzLl9yZWNhbGN1bGF0ZUFuZFNldENvbnRyYXN0Q29sb3IodmFyUHJlZml4KTtcbiAgICB9XG4gIH1cblxuICBzZXRBY2NlbnRDb2xvcihoZXg6IHN0cmluZykge1xuICAgIHRoaXMuYWNjZW50ID0gaGV4O1xuICAgIGNvbnN0IHZhclByZWZpeCA9IE1hdENzc1BhbGV0dGVQcmVmaXguQWNjZW50O1xuICAgIGNvbnN0IHN0eWxlQWNjZW50ID0gdGhpcy5fY29tcHV0ZVBhbGV0dGVDb2xvcnModmFyUHJlZml4LCB0aGlzLmFjY2VudCk7XG4gICAgdGhpcy5fc2V0U3R5bGUoc3R5bGVBY2NlbnQpO1xuXG4gICAgaWYgKHRoaXMuaXNBdXRvQ29udHJhc3QpIHtcbiAgICAgIHRoaXMuX3JlY2FsY3VsYXRlQW5kU2V0Q29udHJhc3RDb2xvcih2YXJQcmVmaXgpO1xuICAgIH1cbiAgfVxuXG4gIHNldFdhcm5Db2xvcihoZXg6IHN0cmluZykge1xuICAgIHRoaXMud2FybiA9IGhleDtcbiAgICBjb25zdCB2YXJQcmVmaXggPSBNYXRDc3NQYWxldHRlUHJlZml4Lldhcm47XG4gICAgY29uc3Qgc3R5bGVXYXJuID0gdGhpcy5fY29tcHV0ZVBhbGV0dGVDb2xvcnModmFyUHJlZml4LCB0aGlzLndhcm4pO1xuICAgIHRoaXMuX3NldFN0eWxlKHN0eWxlV2Fybik7XG5cbiAgICBpZiAodGhpcy5pc0F1dG9Db250cmFzdCkge1xuICAgICAgdGhpcy5fcmVjYWxjdWxhdGVBbmRTZXRDb250cmFzdENvbG9yKHZhclByZWZpeCk7XG4gICAgfVxuICB9XG5cbiAgc2V0VmFyaWFibGUoY3NzVmFyTmFtZTogTWF0ZXJpYWxDc3NWYXJpYWJsZXMsIHZhbHVlOiBzdHJpbmcpIHtcbiAgICB0aGlzLl9zZXRTdHlsZShbe1xuICAgICAgbmFtZTogY3NzVmFyTmFtZSxcbiAgICAgIHZhbDogdmFsdWUsXG4gICAgfV0pO1xuICB9XG5cbiAgc2V0RGFya1RoZW1lKGlzRGFyazogYm9vbGVhbikge1xuICAgIGlmIChpc0RhcmspIHtcbiAgICAgIHRoaXMuZG9jdW1lbnQuYm9keS5jbGFzc0xpc3QucmVtb3ZlKHRoaXMuY2ZnLmxpZ2h0VGhlbWVDbGFzcyk7XG4gICAgICB0aGlzLmRvY3VtZW50LmJvZHkuY2xhc3NMaXN0LmFkZCh0aGlzLmNmZy5kYXJrVGhlbWVDbGFzcyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuZG9jdW1lbnQuYm9keS5jbGFzc0xpc3QucmVtb3ZlKHRoaXMuY2ZnLmRhcmtUaGVtZUNsYXNzKTtcbiAgICAgIHRoaXMuZG9jdW1lbnQuYm9keS5jbGFzc0xpc3QuYWRkKHRoaXMuY2ZnLmxpZ2h0VGhlbWVDbGFzcyk7XG4gICAgfVxuICAgIHRoaXMuaXNEYXJrVGhlbWUgPSBpc0Rhcms7XG4gIH1cblxuICBzZXRBdXRvQ29udHJhc3RFbmFibGVkKHZhbDogYm9vbGVhbikge1xuICAgIHRoaXMuaXNBdXRvQ29udHJhc3QgPSB2YWw7XG4gICAgaWYgKHZhbCkge1xuICAgICAgdGhpcy5fcmVjYWxjdWxhdGVBbmRTZXRDb250cmFzdENvbG9yKE1hdENzc1BhbGV0dGVQcmVmaXguUHJpbWFyeSk7XG4gICAgICB0aGlzLl9yZWNhbGN1bGF0ZUFuZFNldENvbnRyYXN0Q29sb3IoTWF0Q3NzUGFsZXR0ZVByZWZpeC5BY2NlbnQpO1xuICAgICAgdGhpcy5fcmVjYWxjdWxhdGVBbmRTZXRDb250cmFzdENvbG9yKE1hdENzc1BhbGV0dGVQcmVmaXguV2Fybik7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuc2V0Q29udHJhc3RDb2xvclRocmVzaG9sZFByaW1hcnkodGhpcy5jb250cmFzdENvbG9yVGhyZXNob2xkUHJpbWFyeSk7XG4gICAgICB0aGlzLnNldENvbnRyYXN0Q29sb3JUaHJlc2hvbGRBY2NlbnQodGhpcy5jb250cmFzdENvbG9yVGhyZXNob2xkQWNjZW50KTtcbiAgICAgIHRoaXMuc2V0Q29udHJhc3RDb2xvclRocmVzaG9sZFdhcm4odGhpcy5jb250cmFzdENvbG9yVGhyZXNob2xkV2Fybik7XG4gICAgfVxuICB9XG5cbiAgc2V0Q29udHJhc3RDb2xvclRocmVzaG9sZFByaW1hcnkodGhyZXNob2xkOiBIdWVWYWx1ZSkge1xuICAgIHRoaXMuY29udHJhc3RDb2xvclRocmVzaG9sZFByaW1hcnkgPSB0aHJlc2hvbGQ7XG4gICAgdGhpcy5zZXRDb250cmFzdENvbG9yVGhyZXNob2xkKHRocmVzaG9sZCwgTWF0Q3NzUGFsZXR0ZVByZWZpeC5QcmltYXJ5KTtcbiAgfVxuXG4gIHNldENvbnRyYXN0Q29sb3JUaHJlc2hvbGRBY2NlbnQodGhyZXNob2xkOiBIdWVWYWx1ZSkge1xuICAgIHRoaXMuY29udHJhc3RDb2xvclRocmVzaG9sZEFjY2VudCA9IHRocmVzaG9sZDtcbiAgICB0aGlzLnNldENvbnRyYXN0Q29sb3JUaHJlc2hvbGQodGhyZXNob2xkLCBNYXRDc3NQYWxldHRlUHJlZml4LkFjY2VudCk7XG4gIH1cblxuICBzZXRDb250cmFzdENvbG9yVGhyZXNob2xkV2Fybih0aHJlc2hvbGQ6IEh1ZVZhbHVlKSB7XG4gICAgdGhpcy5jb250cmFzdENvbG9yVGhyZXNob2xkV2FybiA9IHRocmVzaG9sZDtcbiAgICB0aGlzLnNldENvbnRyYXN0Q29sb3JUaHJlc2hvbGQodGhyZXNob2xkLCBNYXRDc3NQYWxldHRlUHJlZml4Lldhcm4pO1xuICB9XG5cbiAgc2V0Q29udHJhc3RDb2xvclRocmVzaG9sZCh0aHJlc2hvbGQ6IEh1ZVZhbHVlLCBwYWxldHRlUHJlZml4OiBNYXRDc3NQYWxldHRlUHJlZml4KSB7XG4gICAgbGV0IGNvbG9yID0gTWF0ZXJpYWxDc3NWYXJzU2VydmljZS5EQVJLX1RFWFRfVkFSO1xuICAgIGNvbnN0IHVwZGF0ZXMgPSB0aGlzLmNmZy5zb3J0ZWRIdWVzLm1hcCgoaHVlKSA9PiB7XG4gICAgICBpZiAoaHVlID09PSB0aHJlc2hvbGQpIHtcbiAgICAgICAgY29sb3IgPSBNYXRlcmlhbENzc1ZhcnNTZXJ2aWNlLkxJR0hUX1RFWFRfVkFSO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdmFsOiB0aGlzLl9nZXRDc3NWYXJWYWx1ZShjb2xvciksXG4gICAgICAgIG5hbWU6IGAke3BhbGV0dGVQcmVmaXggKyBNYXRlcmlhbENzc1ZhcnNTZXJ2aWNlLkNPTlRSQVNUX1BSRUZJWH0ke2h1ZX0tcmdiYCxcbiAgICAgIH07XG4gICAgfSk7XG4gICAgdGhpcy5fc2V0U3R5bGUodXBkYXRlcyk7XG4gIH1cblxuICAvKipcbiAgICogR2VuZXJhdGUgcGFsZXR0ZSBjb2xvciBiYXNlZCBvbiB0cmFkaXRpb25hbCB2YWx1ZXNcbiAgICovXG4gIHNldEFsdGVybmF0aXZlQ29sb3JBbGdvcml0aG0odHJhZGl0aW9uYWw6IGJvb2xlYW4pOiB2b2lkIHtcbiAgICB0aGlzLmNmZy5pc0FsdGVybmF0aXZlQ29sb3JBbGdvcml0aG0gPSB0cmFkaXRpb25hbDtcbiAgICB0aGlzLnNldFByaW1hcnlDb2xvcih0aGlzLnByaW1hcnkpO1xuICAgIHRoaXMuc2V0QWNjZW50Q29sb3IodGhpcy5hY2NlbnQpO1xuICAgIHRoaXMuc2V0V2FybkNvbG9yKHRoaXMud2Fybik7XG4gIH1cblxuICAvKiogQGRlcHJlY2F0ZWQgdXNlIHNldENvbnRyYXN0Q29sb3JUaHJlc2hvbGRQcmltYXJ5IGluc3RlYWQgKi9cbiAgY2hhbmdlQ29udHJhc3RDb2xvclRocmVzaG9sZFByaW1hcnkodGhyZXNob2xkOiBIdWVWYWx1ZSkge1xuICAgIHRoaXMuc2V0Q29udHJhc3RDb2xvclRocmVzaG9sZFByaW1hcnkodGhyZXNob2xkKTtcbiAgfVxuXG4gIC8qKiBAZGVwcmVjYXRlZCB1c2Ugc2V0Q29udHJhc3RDb2xvclRocmVzaG9sZEFjY2VudCBpbnN0ZWFkICovXG4gIGNoYW5nZUNvbnRyYXN0Q29sb3JUaHJlc2hvbGRBY2NlbnQodGhyZXNob2xkOiBIdWVWYWx1ZSkge1xuICAgIHRoaXMuc2V0Q29udHJhc3RDb2xvclRocmVzaG9sZEFjY2VudCh0aHJlc2hvbGQpO1xuICB9XG5cbiAgLyoqIEBkZXByZWNhdGVkIHVzZSBzZXRDb250cmFzdENvbG9yVGhyZXNob2xkV2FybiBpbnN0ZWFkICovXG4gIGNoYW5nZUNvbnRyYXN0Q29sb3JUaHJlc2hvbGRXYXJuKHRocmVzaG9sZDogSHVlVmFsdWUpIHtcbiAgICB0aGlzLnNldENvbnRyYXN0Q29sb3JUaHJlc2hvbGRXYXJuKHRocmVzaG9sZCk7XG4gIH1cblxuICAvKiogQGRlcHJlY2F0ZWQgdXNlIHNldENvbnRyYXN0Q29sb3JUaHJlc2hvbGQgaW5zdGVhZCAqL1xuICBjaGFuZ2VDb250cmFzdENvbG9yVGhyZXNob2xkKHRocmVzaG9sZDogSHVlVmFsdWUsIHBhbGV0dGVQcmVmaXg6IE1hdENzc1BhbGV0dGVQcmVmaXgpIHtcbiAgICB0aGlzLnNldENvbnRyYXN0Q29sb3JUaHJlc2hvbGQodGhyZXNob2xkLCBwYWxldHRlUHJlZml4KTtcbiAgfVxuXG4gIGdldFBhbGV0dGVGb3JDb2xvcihoZXg6IHN0cmluZyk6IE1hdENzc0h1ZUNvbG9yTWFwSXRlbVtdIHtcbiAgICBpZiAodGhpcy5jZmcuaXNBbHRlcm5hdGl2ZUNvbG9yQWxnb3JpdGhtKSB7XG4gICAgICByZXR1cm4gdGhpcy5nZXRUcmFkaXRpb25hbFBhbGV0dGVGb3JDb2xvcihoZXgpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gdGhpcy5nZXRDb25zdGFudGluUGFsZXR0ZUZvckNvbG9yKGhleCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBnZXRUcmFkaXRpb25hbFBhbGV0dGVGb3JDb2xvcihoZXg6IHN0cmluZyk6IE1hdENzc0h1ZUNvbG9yTWFwSXRlbVtdIHtcbiAgICByZXR1cm4gdGhpcy5jZmcuY29sb3JNYXAubWFwKGl0ZW0gPT4ge1xuICAgICAgY29uc3QgbWFwcGVkQ29sb3IgPSBuZXcgVGlueUNvbG9yKGhleClcbiAgICAgICAgLmxpZ2h0ZW4oaXRlbS5tYXBbMF0pXG4gICAgICAgIC5kYXJrZW4oaXRlbS5tYXBbMV0pXG4gICAgICAgIC5zYXR1cmF0ZShpdGVtLm1hcFsyXSk7XG4gICAgICBjb25zdCBjID0gbmV3IFRpbnlDb2xvcihtYXBwZWRDb2xvcik7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBodWU6IGl0ZW0ubmFtZSxcbiAgICAgICAgaXNMaWdodDogYy5pc0xpZ2h0KCksXG4gICAgICAgIGNvbG9yOiB7XG4gICAgICAgICAgLi4uYy50b1JnYigpLFxuICAgICAgICAgIHN0cjogYHJnYigke2MudG9SZ2IoKS5yfSwke2MudG9SZ2IoKS5nfSwke2MudG9SZ2IoKS5ifSlgXG4gICAgICAgIH1cbiAgICAgIH07XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGdldENvbnN0YW50aW5QYWxldHRlRm9yQ29sb3IoaGV4OiBzdHJpbmcpOiBNYXRDc3NIdWVDb2xvck1hcEl0ZW1bXSB7XG4gICAgcmV0dXJuIHRoaXMuY2ZnLmNvbG9yTWFwLm1hcCgoaXRlbSkgPT4ge1xuICAgICAgY29uc3QgYyA9IHRoaXMuY29tcHV0ZVBhbGxldFRyaWFkKGhleCwgaXRlbS5uYW1lKTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGh1ZTogaXRlbS5uYW1lLFxuICAgICAgICBpc0xpZ2h0OiBjLmlzTGlnaHQsXG4gICAgICAgIGNvbG9yOiB7XG4gICAgICAgICAgLi4uYy5yZ2IsXG4gICAgICAgICAgc3RyOiBgcmdiKCR7Yy5yZ2Iucn0sJHtjLnJnYi5nfSwke2MucmdiLmJ9KWBcbiAgICAgICAgfVxuICAgICAgfTtcbiAgICB9KTtcbiAgfVxuXG4gIGdldFBhbGV0dGVXaXRoQ29udHJhc3RGb3JDb2xvcihoZXg6IHN0cmluZyk6IE1hdENzc0h1ZUNvbG9yQ29udHJhc3RNYXBJdGVtW10ge1xuICAgIGNvbnN0IGxpZ2h0VGV4dCA9IHRoaXMuX2dldENzc1ZhclZhbHVlKE1hdGVyaWFsQ3NzVmFyc1NlcnZpY2UuTElHSFRfVEVYVF9WQVIpO1xuICAgIGNvbnN0IGRhcmtUZXh0ID0gdGhpcy5fZ2V0Q3NzVmFyVmFsdWUoTWF0ZXJpYWxDc3NWYXJzU2VydmljZS5EQVJLX1RFWFRfVkFSKTtcbiAgICBjb25zdCBwYWxldHRlID0gdGhpcy5nZXRQYWxldHRlRm9yQ29sb3IoaGV4KTtcblxuICAgIC8vIFRPRE8gaGFuZGxlIG5vbiBhdXRvIGNhc2VcbiAgICByZXR1cm4gcGFsZXR0ZS5tYXAoKGl0ZW0pID0+IHtcbiAgICAgIGNvbnN0IGNvbnRyYXN0U3RyID0gaXRlbS5pc0xpZ2h0XG4gICAgICAgID8gbGlnaHRUZXh0XG4gICAgICAgIDogZGFya1RleHQ7XG5cbiAgICAgIGNvbnN0IHNMaWdodCA9IGNvbnRyYXN0U3RyLnNwbGl0KCcsJykubWFwKHYgPT4gK3YpO1xuICAgICAgY29uc3QgY2NvID0ge3I6IHNMaWdodFswXSwgZzogc0xpZ2h0WzFdLCBiOiBzTGlnaHRbMl0sIGE6IDF9O1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgLi4uaXRlbSxcbiAgICAgICAgY29udHJhc3Q6IHtcbiAgICAgICAgICAuLi5jY28sXG4gICAgICAgICAgc3RyOiBgJHtjY28ucn0sJHtjY28uZ30sJHtjY28uYn1gXG4gICAgICAgIH0sXG4gICAgICB9O1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBfY29tcHV0ZVBhbGV0dGVDb2xvcnMocHJlZml4OiBNYXRDc3NQYWxldHRlUHJlZml4LCBoZXg6IHN0cmluZyk6IENzc1ZhcmlhYmxlW10ge1xuICAgIHJldHVybiB0aGlzLmdldFBhbGV0dGVGb3JDb2xvcihoZXgpLm1hcChpdGVtID0+IHtcbiAgICAgIGNvbnN0IGMgPSBpdGVtLmNvbG9yO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgbmFtZTogYCR7cHJlZml4fSR7aXRlbS5odWV9YCxcbiAgICAgICAgdmFsOiBgJHtjLnJ9LCAke2MuZ30sICR7Yy5ifWBcbiAgICAgIH07XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIF9yZWNhbGN1bGF0ZUFuZFNldENvbnRyYXN0Q29sb3IocGFsZXR0ZVByZWZpeDogTWF0Q3NzUGFsZXR0ZVByZWZpeCkge1xuICAgIGNvbnN0IHVwZGF0ZXMgPSB0aGlzLl9jYWxjdWxhdGVDb250cmFzdENvbG9yc0ZvckN1cnJlbnRWYWx1ZXMocGFsZXR0ZVByZWZpeClcbiAgICAgIC5tYXAoKHtjb250cmFzdENvbG9yVmFyLCBodWV9KSA9PiB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgdmFsOiB0aGlzLl9nZXRDc3NWYXJWYWx1ZShjb250cmFzdENvbG9yVmFyKSxcbiAgICAgICAgICBuYW1lOiBgJHtwYWxldHRlUHJlZml4ICsgTWF0ZXJpYWxDc3NWYXJzU2VydmljZS5DT05UUkFTVF9QUkVGSVh9JHtodWV9LXJnYmAsXG4gICAgICAgIH07XG4gICAgICB9KTtcbiAgICB0aGlzLl9zZXRTdHlsZSh1cGRhdGVzKTtcbiAgfVxuXG4gIHByaXZhdGUgX2NhbGN1bGF0ZUNvbnRyYXN0Q29sb3JzRm9yQ3VycmVudFZhbHVlcyhwYWxldHRlUHJlZml4OiBNYXRDc3NQYWxldHRlUHJlZml4KTpcbiAgICB7IGNvbnRyYXN0Q29sb3JWYXI6IHN0cmluZywgaHVlOiBIdWVWYWx1ZSB9W10ge1xuICAgIHJldHVybiB0aGlzLmNmZy5zb3J0ZWRIdWVzLm1hcCgoaHVlKSA9PiB7XG4gICAgICBjb25zdCBodWVWYXJWYWwgPSB0aGlzLl9nZXRDc3NWYXJWYWx1ZShgJHtwYWxldHRlUHJlZml4fSR7aHVlfWApO1xuICAgICAgY29uc3QgYyA9IG5ldyBUaW55Q29sb3IoYHJnYigke2h1ZVZhclZhbH0pYCk7XG4gICAgICBjb25zdCBjb250cmFzdENvbG9yVmFyID0gYy5pc0RhcmsoKVxuICAgICAgICA/IE1hdGVyaWFsQ3NzVmFyc1NlcnZpY2UuTElHSFRfVEVYVF9WQVJcbiAgICAgICAgOiBNYXRlcmlhbENzc1ZhcnNTZXJ2aWNlLkRBUktfVEVYVF9WQVI7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBjb250cmFzdENvbG9yVmFyLFxuICAgICAgICBodWUsXG4gICAgICB9O1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBfc2V0U3R5bGUodmFyczogQ3NzVmFyaWFibGVbXSkge1xuICAgIHZhcnMuZm9yRWFjaChzID0+IHtcbiAgICAgIHRoaXMucmVuZGVyZXIuc2V0U3R5bGUodGhpcy5ST09ULCBzLm5hbWUsIHMudmFsLCBSZW5kZXJlclN0eWxlRmxhZ3MyLkRhc2hDYXNlKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgX2dldENzc1ZhclZhbHVlKHY6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgcmV0dXJuIGdldENvbXB1dGVkU3R5bGUodGhpcy5ST09UKS5nZXRQcm9wZXJ0eVZhbHVlKHYpO1xuICB9XG5cbiAgLyoqXG4gICAqIENvbXB1dGUgcGFsbGV0IGNvbG9ycyBiYXNlZCBvbiBhIFRyaWFkIChDb25zdGFudGluKVxuICAgKiBzZWU6IGh0dHBzOi8vZ2l0aHViLmNvbS9tYml0c29uL21jZ1xuICAgKi9cbiAgcHJpdmF0ZSBjb21wdXRlUGFsbGV0VHJpYWQoaGV4OiBzdHJpbmcsIGh1ZTogSHVlVmFsdWUpIHtcbiAgICBjb25zdCBiYXNlTGlnaHQgPSBuZXcgVGlueUNvbG9yKCcjZmZmZmZmJyk7XG4gICAgY29uc3QgYmFzZURhcmsgPSB0aGlzLm11bHRpcGx5KG5ldyBUaW55Q29sb3IoaGV4KS50b1JnYigpLCBuZXcgVGlueUNvbG9yKGhleCkudG9SZ2IoKSk7XG4gICAgY29uc3QgYmFzZVRyaWFkID0gbmV3IFRpbnlDb2xvcihoZXgpLnRldHJhZCgpO1xuICAgIGxldCBjb2xvcjogeyByZ2I6IE51bWJlcmlmeTxSR0JBPiwgaXNMaWdodDogYm9vbGVhbiB9O1xuXG4gICAgc3dpdGNoIChodWUpIHtcbiAgICAgIGNhc2UgJzUwJzpcbiAgICAgICAgY29sb3IgPSB0aGlzLmdldENvbG9yT2JqZWN0KGJhc2VMaWdodC5taXgoaGV4LCAxMikpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJzEwMCc6XG4gICAgICAgIGNvbG9yID0gdGhpcy5nZXRDb2xvck9iamVjdChiYXNlTGlnaHQubWl4KGhleCwgMzApKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICcyMDAnOlxuICAgICAgICBjb2xvciA9IHRoaXMuZ2V0Q29sb3JPYmplY3QoYmFzZUxpZ2h0Lm1peChoZXgsIDUwKSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnMzAwJzpcbiAgICAgICAgY29sb3IgPSB0aGlzLmdldENvbG9yT2JqZWN0KGJhc2VMaWdodC5taXgoaGV4LCA3MCkpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJzQwMCc6XG4gICAgICAgIGNvbG9yID0gdGhpcy5nZXRDb2xvck9iamVjdChiYXNlTGlnaHQubWl4KGhleCwgODUpKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICc1MDAnOlxuICAgICAgICBjb2xvciA9IHRoaXMuZ2V0Q29sb3JPYmplY3QoYmFzZUxpZ2h0Lm1peChoZXgsIDEwMCkpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJzYwMCc6XG4gICAgICAgIGNvbG9yID0gdGhpcy5nZXRDb2xvck9iamVjdChiYXNlRGFyay5taXgoaGV4LCA4NykpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJzcwMCc6XG4gICAgICAgIGNvbG9yID0gdGhpcy5nZXRDb2xvck9iamVjdChiYXNlRGFyay5taXgoaGV4LCA3MCkpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJzgwMCc6XG4gICAgICAgIGNvbG9yID0gdGhpcy5nZXRDb2xvck9iamVjdChiYXNlRGFyay5taXgoaGV4LCA1NCkpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJzkwMCc6XG4gICAgICAgIGNvbG9yID0gdGhpcy5nZXRDb2xvck9iamVjdChiYXNlRGFyay5taXgoaGV4LCAyNSkpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ0ExMDAnOlxuICAgICAgICBjb2xvciA9IHRoaXMuZ2V0Q29sb3JPYmplY3QoYmFzZURhcmsubWl4KGJhc2VUcmlhZFs0XSwgMTUpLnNhdHVyYXRlKDgwKS5saWdodGVuKDY1KSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnQTIwMCc6XG4gICAgICAgIGNvbG9yID0gdGhpcy5nZXRDb2xvck9iamVjdChiYXNlRGFyay5taXgoYmFzZVRyaWFkWzRdLCAxNSkuc2F0dXJhdGUoODApLmxpZ2h0ZW4oNTUpKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdBNDAwJzpcbiAgICAgICAgY29sb3IgPSB0aGlzLmdldENvbG9yT2JqZWN0KGJhc2VEYXJrLm1peChiYXNlVHJpYWRbNF0sIDE1KS5zYXR1cmF0ZSgxMDApLmxpZ2h0ZW4oNDUpKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdBNzAwJzpcbiAgICAgICAgY29sb3IgPSB0aGlzLmdldENvbG9yT2JqZWN0KGJhc2VEYXJrLm1peChiYXNlVHJpYWRbNF0sIDE1KS5zYXR1cmF0ZSgxMDApLmxpZ2h0ZW4oNDApKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICBicmVhaztcbiAgICB9XG4gICAgcmV0dXJuIGNvbG9yO1xuICB9XG5cbiAgcHJpdmF0ZSBtdWx0aXBseShyZ2IxOiBOdW1iZXJpZnk8UkdCQT4sIHJnYjI6IE51bWJlcmlmeTxSR0JBPik6IFRpbnlDb2xvciB7XG4gICAgcmdiMS5iID0gTWF0aC5mbG9vcihyZ2IxLmIgKiByZ2IyLmIgLyAyNTUpO1xuICAgIHJnYjEuZyA9IE1hdGguZmxvb3IocmdiMS5nICogcmdiMi5nIC8gMjU1KTtcbiAgICByZ2IxLnIgPSBNYXRoLmZsb29yKHJnYjEuciAqIHJnYjIuciAvIDI1NSk7XG4gICAgcmV0dXJuIG5ldyBUaW55Q29sb3IoJ3JnYsKgJyArIHJnYjEuciArICfCoCcgKyByZ2IxLmcgKyAnwqAnICsgcmdiMS5iKTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0Q29sb3JPYmplY3QodmFsdWU6IFRpbnlDb2xvcikge1xuICAgIGNvbnN0IGMgPSBuZXcgVGlueUNvbG9yKHZhbHVlKTtcbiAgICByZXR1cm4ge3JnYjogYy50b1JnYigpLCBpc0xpZ2h0OiBjLmlzTGlnaHQoKX07XG4gIH1cblxufVxuIl19