ng-chartjs
Version:
This is a Angular chart.js library.
317 lines • 41 kB
JavaScript
import { EventEmitter, Input, Output, Directive } from '@angular/core';
// import { Chart, ChartConfiguration, ChartEvent, DefaultDataPoint, registerables } from 'chart.js';
import Chart from 'chart.js/auto';
import { deepCopyJson, mergeJson } from './ng-chartjs.service';
import { getColors } from './colors';
import * as i0 from "@angular/core";
import * as i1 from "./ng-chartjs.service";
import * as i2 from "./store.service";
/* tslint:disable-next-line */
export class NgChartjsDirective {
constructor(element, ngChartjsService, storeService, zone) {
this.ngChartjsService = ngChartjsService;
this.storeService = storeService;
this.zone = zone;
// x轴标签。这对图表来说是必要的:线,条和雷达。并且只是图表的标签(悬停):polarArea,pie和doughnut
this.labels = [];
this.noZone = true; // disable angular NgZone
// @ts-ignore
this.id = null; // chart instance id
// 鼠标点击图表所有的区域
this.chartClick = new EventEmitter();
// 鼠标悬浮在标签或者活跃的点上面时
this.chartHover = new EventEmitter();
this.initFlag = false;
this.hasChanges = false;
this.element = element; // 获取指令所在canvas元素
}
ngOnInit() {
this.ctx = this.element.nativeElement.getContext('2d'); // 获取元素的ctx
this.initFlag = true; // 是否初始化了的标志
if (this.data || this.datasets) { // 判断data和datasets有一个有数据就刷新
if (this.noZone) {
this.zone.runOutsideAngular(() => {
this.refresh();
});
}
else {
this.refresh();
}
}
}
ngOnChanges(changes) {
// TODO: 插件变化刷新,开放刷新按钮
if (this.initFlag) {
// Check if the changes are in the data or datasets
if (changes.hasOwnProperty('data') || changes.hasOwnProperty('datasets')) {
if (changes.data) {
this.updateChartData(changes.data.currentValue);
}
else {
this.updateChartData(changes.datasets.currentValue);
}
this.hasChanges = true;
}
if (changes.hasOwnProperty('labels')) {
this.chart.data.labels = changes.labels.currentValue;
this.hasChanges = true;
}
if (changes.hasOwnProperty('legend')) {
if (changes.legend.currentValue !== changes.legend.previousValue) {
// @ts-ignore
this.chart.options.plugins.legend.display = changes.legend.currentValue;
this.hasChanges = true;
}
}
if (changes.hasOwnProperty('adding')) {
this.addData_(changes.adding.currentValue.labels, changes.adding.currentValue.data);
this.hasChanges = true;
}
if (changes.hasOwnProperty('removing')) {
if (changes.removing.currentValue.orientation === 'oldest' || changes.removing.currentValue.orientation === 'latest') {
this.removeData_(changes.removing.currentValue.orientation);
this.hasChanges = true;
}
}
if (changes.hasOwnProperty('chartType')) {
this.refresh();
}
if (changes.hasOwnProperty('resetOption')) {
const resetOption = deepCopyJson(changes.resetOption.currentValue);
this.chart.options = mergeJson(resetOption, this.chart.options);
this.hasChanges = true;
}
if (this.hasChanges) {
this.chart.update();
this.hasChanges = false;
}
// change chart id
if (changes.hasOwnProperty('id')) {
this.removeChart(changes.id.previousValue);
this.addChart(changes.id.currentValue);
}
}
}
ngOnDestroy() {
if (this.chart) {
this.chart.destroy();
// @ts-ignore
this.chart = void 0;
this.removeChart(this.id);
}
}
// update chartjs
update() {
this.chart.update();
}
// Dynamic add data
addData(labels, data) {
this.addData_(labels, data);
this.update();
}
// Dynamic remove data, orientation is 'ildest' or 'latest'
removeData(orientation) {
this.removeData_(orientation);
this.update();
}
refresh() {
this.ngOnDestroy();
this.chart = this.getChartBuilder(this.ctx /*, data, this.options*/);
this.addChart(this.id);
}
removeChart(id) {
if (this.element.nativeElement.hasAttribute('id')) {
this.storeService.removeChart(this.element.nativeElement.id);
return;
}
if (id !== null && id !== undefined) {
this.storeService.removeChart(id); // delete chart instance.
}
}
addChart(id) {
if (this.element.nativeElement.hasAttribute('id')) {
this.storeService.addChart(this.element.nativeElement.id, this.chart);
return;
}
if (id !== null && id !== undefined) {
this.storeService.addChart(id, this.chart);
}
}
updateChartData(newDataValues) {
if (Array.isArray(newDataValues[0].data)) {
// @ts-ignore
// this.chart.data.datasets.forEach((dataset: ChartDataset, i: number) => {
// dataset.data = newDataValues[i].data;
// if (newDataValues[i].label) {
// dataset.label = newDataValues[i].label;
// }
// });
// @ts-ignore
this.chart.data.datasets = newDataValues;
}
else {
// @ts-ignore
this.chart.data.datasets[0].data = newDataValues;
}
// update colors
// @ts-ignore
this.chart.data.datasets = this.updateColors(this.chart.data.datasets);
}
getChartBuilder(ctx /*, data:Array<any>, options:any*/) {
const datasets = this.getDatasets();
let options = this.options || {};
options = Object.assign({}, this.options); // 深复制options
mergeJson(options, {
plugins: {
legend: {
display: this.legend
}
}
});
// hock for onHover and onClick events
options.hover = options.hover || {};
if (!options.onHover) {
options.onHover = (event, active) => {
if (active && !active.length) {
return;
}
this.chartHover.emit({ event, active });
};
}
if (!options.onClick) {
options.onClick = (event, active) => {
this.chartClick.emit({ event, active });
};
}
const inlinePlugins = this.inlinePlugins || [];
const opts = {
type: this.chartType,
data: {
labels: this.labels,
datasets: datasets // TODO: 后续更改这个属性名字,否则警告
},
options: options,
plugins: inlinePlugins
};
return new Chart(ctx, opts);
}
// 获取 chart.js的datasets数据
getDatasets() {
// @ts-ignore
let datasets = void 0;
// in case if datasets is not provided, but data is present
if (!this.datasets || !this.datasets.length && (this.data && this.data.length)) {
if (Array.isArray(this.data[0])) {
datasets = this.data.map((data, index) => {
return { data, label: this.labels[index] || `Label ${index}` };
});
}
else {
datasets = [{ data: this.data, label: `Label 0` }];
}
}
datasets = this.updateColors(datasets); // update colors
if (!datasets) {
throw new Error(`ng-chartjs configuration error,
data or datasets field are required to render char ${this.chartType}`);
}
return datasets;
}
// update dataset colors
updateColors(datasets) {
if (this.datasets && this.datasets.length || (datasets && datasets.length)) {
// fix elm type, pre type is number
datasets = (this.datasets || datasets).map((elm, index) => {
const newElm = Object.assign({}, elm);
if (this.colors && this.colors.length) {
Object.assign(newElm, this.colors[index]);
}
else {
// @ts-ignore
Object.assign(newElm, getColors(this.chartType, index, newElm.data.length));
}
return newElm;
});
}
return datasets;
}
addData_(labels, data) {
if (labels.length === 0 || data.length === 0) {
return;
}
// update labels
// @ts-ignore
labels.forEach((label) => { this.chart.data.labels.push(label); });
// @ts-ignore
this.chart.data.datasets.forEach((dataset, index) => {
if (data[index]) {
for (let i = 0; i < data[index].length; i++) {
// @ts-ignore
dataset.data.push(data[index][i]);
}
}
else {
console.log('The added data does not match the original data');
return;
}
});
}
removeData_(orientation) {
// fix: support to oldest feature
if (orientation === 'latest') {
// @ts-ignore
this.chart.data.labels.pop();
// @ts-ignore
this.chart.data.datasets.forEach((dataset) => {
// @ts-ignore
dataset.data.pop();
});
}
else if (orientation === 'oldest') {
// @ts-ignore
this.chart.data.labels.shift();
// @ts-ignore
this.chart.data.datasets.forEach((dataset) => {
// @ts-ignore
dataset.data.shift();
});
}
}
}
NgChartjsDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: NgChartjsDirective, deps: [{ token: i0.ElementRef }, { token: i1.NgChartjsService }, { token: i2.StoreService }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Directive });
NgChartjsDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.9", type: NgChartjsDirective, selector: "canvas[ngChartjs]", inputs: { data: "data", datasets: "datasets", labels: "labels", options: "options", inlinePlugins: "inlinePlugins", chartType: "chartType", colors: "colors", legend: "legend", adding: "adding", removing: "removing", resetOption: "resetOption", noZone: "noZone", id: "id" }, outputs: { chartClick: "chartClick", chartHover: "chartHover" }, exportAs: ["ngChartjs"], usesOnChanges: true, ngImport: i0 });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: NgChartjsDirective, decorators: [{
type: Directive,
args: [{ selector: 'canvas[ngChartjs]', exportAs: 'ngChartjs' }]
}], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i1.NgChartjsService }, { type: i2.StoreService }, { type: i0.NgZone }]; }, propDecorators: { data: [{
type: Input
}], datasets: [{
type: Input
}], labels: [{
type: Input
}], options: [{
type: Input
}], inlinePlugins: [{
type: Input
}], chartType: [{
type: Input
}], colors: [{
type: Input
}], legend: [{
type: Input
}], adding: [{
type: Input
}], removing: [{
type: Input
}], resetOption: [{
type: Input
}], noZone: [{
type: Input
}], id: [{
type: Input
}], chartClick: [{
type: Output
}], chartHover: [{
type: Output
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmctY2hhcnRqcy5kaXJlY3RpdmUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9uZy1jaGFydGpzL3NyYy9saWIvbmctY2hhcnRqcy5kaXJlY3RpdmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUlMLFlBQVksRUFFWixLQUFLLEVBQ0wsTUFBTSxFQUVOLFNBQVMsRUFFVixNQUFNLGVBQWUsQ0FBQztBQUN2QixxR0FBcUc7QUFDckcsT0FBTyxLQU9OLE1BQU0sZUFBZSxDQUFDO0FBRXZCLE9BQU8sRUFBRSxZQUFZLEVBQUUsU0FBUyxFQUFvQixNQUFNLHNCQUFzQixDQUFDO0FBQ2pGLE9BQU8sRUFBRSxTQUFTLEVBQVUsTUFBTSxVQUFVLENBQUM7Ozs7QUFNN0MsOEJBQThCO0FBRTlCLE1BQU0sT0FBTyxrQkFBa0I7SUFpRDdCLFlBQ0UsT0FBbUIsRUFDWCxnQkFBa0MsRUFDbEMsWUFBMEIsRUFDMUIsSUFBWTtRQUZaLHFCQUFnQixHQUFoQixnQkFBZ0IsQ0FBa0I7UUFDbEMsaUJBQVksR0FBWixZQUFZLENBQWM7UUFDMUIsU0FBSSxHQUFKLElBQUksQ0FBUTtRQTdDdEIsOERBQThEO1FBQ3JELFdBQU0sR0FBVyxFQUFFLENBQUM7UUFzQnBCLFdBQU0sR0FBRyxJQUFJLENBQUMsQ0FBQyx5QkFBeUI7UUFDakQsYUFBYTtRQUNKLE9BQUUsR0FBVyxJQUFJLENBQUMsQ0FBQyxvQkFBb0I7UUFFaEQsY0FBYztRQUNKLGVBQVUsR0FBaUMsSUFBSSxZQUFZLEVBQUUsQ0FBQztRQUN4RSxtQkFBbUI7UUFDVCxlQUFVLEdBQWlDLElBQUksWUFBWSxFQUFFLENBQUM7UUFNaEUsYUFBUSxHQUFHLEtBQUssQ0FBQztRQUNqQixlQUFVLEdBQUcsS0FBSyxDQUFDO1FBU3pCLElBQUksQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUFDLENBQUcsaUJBQWlCO0lBQzdDLENBQUM7SUFFRCxRQUFRO1FBQ04sSUFB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RDlCLFNBQVM7bUJBQUMsRUFBRSxRQUFRLEVBQUUsbUJBQW1CLEVBQUUsUUFBUSxFQUFFLFdBQVcsRUFBRTtnTEFLeEQsSUFBSTtzQkFBWixLQUFLO2dCQUdHLFFBQVE7c0JBQWhCLEtBQUs7Z0JBRUcsTUFBTTtzQkFBZCxLQUFLO2dCQUVHLE9BQU87c0JBQWYsS0FBSztnQkFFRyxhQUFhO3NCQUFyQixLQUFLO2dCQUdHLFNBQVM7c0JBQWpCLEtBQUs7Z0JBR0csTUFBTTtzQkFBZCxLQUFLO2dCQUdHLE1BQU07c0JBQWQsS0FBSztnQkFHRyxNQUFNO3NCQUFkLEtBQUs7Z0JBRUcsUUFBUTtzQkFBaEIsS0FBSztnQkFFRyxXQUFXO3NCQUFuQixLQUFLO2dCQUVHLE1BQU07c0JBQWQsS0FBSztnQkFFRyxFQUFFO3NCQUFWLEtBQUs7Z0JBR0ksVUFBVTtzQkFBbkIsTUFBTTtnQkFFRyxVQUFVO3NCQUFuQixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgT25EZXN0cm95LFxuICBPbkluaXQsXG4gIE9uQ2hhbmdlcyxcbiAgRXZlbnRFbWl0dGVyLFxuICBFbGVtZW50UmVmLFxuICBJbnB1dCxcbiAgT3V0cHV0LFxuICBTaW1wbGVDaGFuZ2VzLFxuICBEaXJlY3RpdmUsXG4gIE5nWm9uZVxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbi8vIGltcG9ydCB7IENoYXJ0LCBDaGFydENvbmZpZ3VyYXRpb24sIENoYXJ0RXZlbnQsIERlZmF1bHREYXRhUG9pbnQsIHJlZ2lzdGVyYWJsZXMgfSBmcm9tICdjaGFydC5qcyc7XG5pbXBvcnQgQ2hhcnQsIFxueyBcbiAgQ2hhcnRFdmVudCwgXG4gIENoYXJ0Q29uZmlndXJhdGlvbiwgXG4gIENoYXJ0T3B0aW9ucywgXG4gIENoYXJ0RGF0YXNldCwgXG4gIENoYXJ0RGF0YSBcbn0gZnJvbSAnY2hhcnQuanMvYXV0byc7XG5pbXBvcnQgeyBTdG9yZVNlcnZpY2UgfSBmcm9tICcuL3N0b3JlLnNlcnZpY2UnO1xuaW1wb3J0IHsgZGVlcENvcHlKc29uLCBtZXJnZUpzb24sIE5nQ2hhcnRqc1NlcnZpY2UgfSBmcm9tICcuL25nLWNoYXJ0anMuc2VydmljZSc7XG5pbXBvcnQgeyBnZXRDb2xvcnMsIENvbG9ycyB9IGZyb20gJy4vY29sb3JzJztcblxuZXhwb3J0IHR5cGUgTGFiZWxzID0gQXJyYXk8c3RyaW5nIHwgc3RyaW5nW10gfCBudW1iZXIgfCBudW1iZXJbXSB8IERhdGUgfCBEYXRlW10gfCBhbnkgfCBhbnlbXT47XG5leHBvcnQgdHlwZSBPcmllbnRhdGlvbiA9ICdvbGRlc3QnIHwgJ2xhdGVzdCc7XG5leHBvcnQgaW50ZXJmYWNlIE5nQ2hhcnRqc0V2ZW50IHsgZXZlbnQ6IENoYXJ0RXZlbnQ7IGFjdGl2ZTogQXJyYXk8e30+OyB9XG5cbi8qIHRzbGludDpkaXNhYmxlLW5leHQtbGluZSAqL1xuQERpcmVjdGl2ZSh7IHNlbGVjdG9yOiAnY2FudmFzW25nQ2hhcnRqc10nLCBleHBvcnRBczogJ25nQ2hhcnRqcycgfSlcbmV4cG9ydCBjbGFzcyBOZ0NoYXJ0anNEaXJlY3RpdmUgaW1wbGVtZW50cyBPbkRlc3Ryb3ksIE9uQ2hhbmdlcywgT25Jbml0IHtcblxuICAvLyDlm77ooajnmoTngrnpm4bvvIzlroPlupTor6XmmK/mlbDnu4Q8bnVtYmVyIFtdPuS7heeUqOS6jue6v++8jOadoeWSjOmbt+i+vu+8jOWQpuWImeaVsOWtl1tdO1xuICAvLyBAdHMtaWdub3JlXG4gIEBJbnB1dCgpIGRhdGE6IG51bWJlcltdIHwgYW55W107XG4gIC8vIOebuOW9k+S6jmNoYXJ0Lmpz5YaFIGRhdGE6IHtkYXRhc2V0czogW3suLi59XX1cbiAgLy8gQHRzLWlnbm9yZVxuICBASW5wdXQoKSBkYXRhc2V0czogQ2hhcnREYXRhWydkYXRhc2V0cyddO1xuICAvLyB46L205qCH562+44CC6L+Z5a+55Zu+6KGo5p2l6K+05piv5b+F6KaB55qE77ya57q/77yM5p2h5ZKM6Zu36L6+44CC5bm25LiU5Y+q5piv5Zu+6KGo55qE5qCH562+77yI5oKs5YGc77yJ77yacG9sYXJBcmVh77yMcGll5ZKMZG91Z2hudXRcbiAgQElucHV0KCkgbGFiZWxzOiBMYWJlbHMgPSBbXTtcbiAgLy8g55u45b2T5LqOY2hhcnQuanPnmoRvcHRpb25cbiAgQElucHV0KCkgb3B0aW9ucz86IENoYXJ0Q29uZmlndXJhdGlvblsnb3B0aW9ucyddO1xuICAvLyDlhoXogZTmj5Lku7blsZ7mgKdcbiAgQElucHV0KCkgaW5saW5lUGx1Z2lucz86IGFueVtdO1xuICAvLyBjaGFydFR5cGUgbGluZSwgYmFyLCByYWRhciwgcGllLCBwb2xhckFyZWEsIGRvdWdobnV0XG4gIC8vIEB0cy1pZ25vcmVcbiAgQElucHV0KCkgY2hhcnRUeXBlOiBDaGFydENvbmZpZ3VyYXRpb25bJ3R5cGUnXTtcbiAgLy8g5pWw5o2u6aKc6Imy77yM5aaC5p6c5rKh5pyJ5oyH5a6a77yM5bCG5L2/55So6buY6K6k5ZKMfOaIlumaj+acuuminOiJslxuICAvLyBAdHMtaWdub3JlXG4gIEBJbnB1dCgpIGNvbG9yczogQ29sb3JzW107XG4gIC8vIOaYr+WQpuaYvuekuuWbvuS+i1xuICAvLyBAdHMtaWdub3JlXG4gIEBJbnB1dCgpIGxlZ2VuZDogYm9vbGVhbjtcblxuICAvLyBAdHMtaWdub3JlXG4gIEBJbnB1dCgpIGFkZGluZzogeyBsYWJlbHM6IExhYmVsc1tdLCBkYXRhOiBhbnlbXVtdIH07XG4gIC8vIEB0cy1pZ25vcmVcbiAgQElucHV0KCkgcmVtb3Zpbmc6IHsgb3JpZW50YXRpb246IE9yaWVudGF0aW9uIH07ICAvLyBvcmllbnRhdGlvbiBpcyAnb2xkZXN0JyBvciAnbGF0ZXN0XG4gIC8vIEB0cy1pZ25vcmVcbiAgQElucHV0KCkgcmVzZXRPcHRpb24/OiBDaGFydENvbmZpZ3VyYXRpb25bJ29wdGlvbnMnXTtcblxuICBASW5wdXQoKSBub1pvbmUgPSB0cnVlOyAvLyBkaXNhYmxlIGFuZ3VsYXIgTmdab25lXG4gIC8vIEB0cy1pZ25vcmVcbiAgQElucHV0KCkgaWQ6IHN0cmluZyA9IG51bGw7IC8vIGNoYXJ0IGluc3RhbmNlIGlkXG5cbiAgLy8g6byg5qCH54K55Ye75Zu+6KGo5omA5pyJ55qE5Yy65Z+fXG4gIEBPdXRwdXQoKSBjaGFydENsaWNrOiBFdmVudEVtaXR0ZXI8TmdDaGFydGpzRXZlbnQ+ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuICAvLyDpvKDmoIfmgqzmta7lnKjmoIfnrb7miJbogIXmtLvot4PnmoTngrnkuIrpnaLml7ZcbiAgQE91dHB1dCgpIGNoYXJ0SG92ZXI6IEV2ZW50RW1pdHRlcjxOZ0NoYXJ0anNFdmVudD4gPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG5cbiAgLy8gZ2V0IENoYXJ0anMgb2JqZWN0XG4gIGNoYXJ0ITogQ2hhcnQ7XG4gIC8vIEB0cy1pZ25vcmVcbiAgcHJpdmF0ZSBjdHg6IENhbnZhc1JlbmRlcmluZ0NvbnRleHQyRDtcbiAgcHJpdmF0ZSBpbml0RmxhZyA9IGZhbHNlO1xuICBwcml2YXRlIGhhc0NoYW5nZXMgPSBmYWxzZTtcblxuICBwcml2YXRlIGVsZW1lbnQ6IEVsZW1lbnRSZWY7XG5cbiAgcHVibGljIGNvbnN0cnVjdG9yKFxuICAgIGVsZW1lbnQ6IEVsZW1lbnRSZWYsXG4gICAgcHJpdmF0ZSBuZ0NoYXJ0anNTZXJ2aWNlOiBOZ0NoYXJ0anNTZXJ2aWNlLFxuICAgIHByaXZhdGUgc3RvcmVTZXJ2aWNlOiBTdG9yZVNlcnZpY2UsXG4gICAgcHJpdmF0ZSB6b25lOiBOZ1pvbmUpIHtcbiAgICB0aGlzLmVsZW1lbnQgPSBlbGVtZW50OyAgIC8vIOiOt+WPluaMh+S7pOaJgOWcqGNhbnZhc+WFg+e0oFxuICB9XG5cbiAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgdGhpcy5jdHggPSB0aGlzLmVsZW1lbnQubmF0aXZlRWxlbWVudC5nZXRDb250ZXh0KCcyZCcpOyAvLyDojrflj5blhYPntKDnmoRjdHhcbiAgICB0aGlzLmluaXRGbGFnID0gdHJ1ZTsgLy8g5piv5ZCm5Yid5aeL5YyW5LqG55qE5qCH5b+XXG5cbiAgICBpZiAodGhpcy5kYXRhIHx8IHRoaXMuZGF0YXNldHMpIHsgLy8g5Yik5patZGF0YeWSjGRhdGFzZXRz5pyJ5LiA5Liq5pyJ5pWw5o2u5bCx5Yi35pawXG4gICAgICBpZiAodGhpcy5ub1pvbmUpIHtcbiAgICAgICAgdGhpcy56b25lLnJ1bk91dHNpZGVBbmd1bGFyKCgpID0+IHtcbiAgICAgICAgIHRoaXMucmVmcmVzaCgpO1xuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMucmVmcmVzaCgpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpOiB2b2lkIHtcbiAgICAvLyBUT0RPOiDmj5Lku7blj5jljJbliLfmlrDvvIzlvIDmlL7liLfmlrDmjInpkq5cbiAgICBpZiAodGhpcy5pbml0RmxhZykge1xuICAgICAgLy8gQ2hlY2sgaWYgdGhlIGNoYW5nZXMgYXJlIGluIHRoZSBkYXRhIG9yIGRhdGFzZXRzXG4gICAgICBpZiAoY2hhbmdlcy5oYXNPd25Qcm9wZXJ0eSgnZGF0YScpIHx8IGNoYW5nZXMuaGFzT3duUHJvcGVydHkoJ2RhdGFzZXRzJykpIHtcbiAgICAgICAgaWYgKGNoYW5nZXMuZGF0YSkge1xuICAgICAgICAgIHRoaXMudXBkYXRlQ2hhcnREYXRhKGNoYW5nZXMuZGF0YS5jdXJyZW50VmFsdWUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRoaXMudXBkYXRlQ2hhcnREYXRhKGNoYW5nZXMuZGF0YXNldHMuY3VycmVudFZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmhhc0NoYW5nZXMgPSB0cnVlO1xuICAgICAgfVxuXG4gICAgICBpZiAoY2hhbmdlcy5oYXNPd25Qcm9wZXJ0eSgnbGFiZWxzJykpIHtcbiAgICAgICAgdGhpcy5jaGFydC5kYXRhLmxhYmVscyA9IGNoYW5nZXMubGFiZWxzLmN1cnJlbnRWYWx1ZTtcbiAgICAgICAgdGhpcy5oYXNDaGFuZ2VzID0gdHJ1ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKGNoYW5nZXMuaGFzT3duUHJvcGVydHkoJ2xlZ2VuZCcpKSB7XG4gICAgICAgIGlmIChjaGFuZ2VzLmxlZ2VuZC5jdXJyZW50VmFsdWUgIT09IGNoYW5nZXMubGVnZW5kLnByZXZpb3VzVmFsdWUpIHtcbiAgICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgICAgdGhpcy5jaGFydC5vcHRpb25zLnBsdWdpbnMubGVnZW5kLmRpc3BsYXkgPSBjaGFuZ2VzLmxlZ2VuZC5jdXJyZW50VmFsdWU7XG4gICAgICAgICAgdGhpcy5oYXNDaGFuZ2VzID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoY2hhbmdlcy5oYXNPd25Qcm9wZXJ0eSgnYWRkaW5nJykpIHtcbiAgICAgICAgdGhpcy5hZGREYXRhXyhjaGFuZ2VzLmFkZGluZy5jdXJyZW50VmFsdWUubGFiZWxzLCBjaGFuZ2VzLmFkZGluZy5jdXJyZW50VmFsdWUuZGF0YSk7XG4gICAgICAgIHRoaXMuaGFzQ2hhbmdlcyA9IHRydWU7XG4gICAgICB9XG5cbiAgICAgIGlmIChjaGFuZ2VzLmhhc093blByb3BlcnR5KCdyZW1vdmluZycpKSB7XG4gICAgICAgIGlmIChjaGFuZ2VzLnJlbW92aW5nLmN1cnJlbnRWYWx1ZS5vcmllbnRhdGlvbiA9PT0gJ29sZGVzdCcgfHwgY2hhbmdlcy5yZW1vdmluZy5jdXJyZW50VmFsdWUub3JpZW50YXRpb24gPT09ICdsYXRlc3QnKSB7XG4gICAgICAgICAgdGhpcy5yZW1vdmVEYXRhXyhjaGFuZ2VzLnJlbW92aW5nLmN1cnJlbnRWYWx1ZS5vcmllbnRhdGlvbik7XG4gICAgICAgICAgdGhpcy5oYXNDaGFuZ2VzID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoY2hhbmdlcy5oYXNPd25Qcm9wZXJ0eSgnY2hhcnRUeXBlJykpIHtcbiAgICAgICAgdGhpcy5yZWZyZXNoKCk7XG4gICAgICB9XG5cbiAgICAgIGlmIChjaGFuZ2VzLmhhc093blByb3BlcnR5KCdyZXNldE9wdGlvbicpKSB7XG4gICAgICAgIGNvbnN0IHJlc2V0T3B0aW9uID0gZGVlcENvcHlKc29uKGNoYW5nZXMucmVzZXRPcHRpb24uY3VycmVudFZhbHVlKTtcbiAgICAgICAgdGhpcy5jaGFydC5vcHRpb25zID0gbWVyZ2VKc29uKHJlc2V0T3B0aW9uLCB0aGlzLmNoYXJ0Lm9wdGlvbnMpO1xuICAgICAgICB0aGlzLmhhc0NoYW5nZXMgPSB0cnVlO1xuICAgICAgfVxuXG4gICAgICBpZiAodGhpcy5oYXNDaGFuZ2VzKSB7XG4gICAgICAgIHRoaXMuY2hhcnQudXBkYXRlKCk7XG4gICAgICAgIHRoaXMuaGFzQ2hhbmdlcyA9IGZhbHNlO1xuICAgICAgfVxuXG4gICAgICAvLyBjaGFuZ2UgY2hhcnQgaWRcbiAgICAgIGlmIChjaGFuZ2VzLmhhc093blByb3BlcnR5KCdpZCcpKSB7XG4gICAgICAgIHRoaXMucmVtb3ZlQ2hhcnQoY2hhbmdlcy5pZC5wcmV2aW91c1ZhbHVlKTtcbiAgICAgICAgdGhpcy5hZGRDaGFydChjaGFuZ2VzLmlkLmN1cnJlbnRWYWx1ZSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuY2hhcnQpIHtcbiAgICAgIHRoaXMuY2hhcnQuZGVzdHJveSgpO1xuICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgdGhpcy5jaGFydCA9IHZvaWQgMDtcblxuICAgICAgdGhpcy5yZW1vdmVDaGFydCh0aGlzLmlkKTtcbiAgICB9XG4gIH1cblxuICAvLyB1cGRhdGUgY2hhcnRqc1xuICB1cGRhdGUoKTogdm9pZCB7XG4gICAgdGhpcy5jaGFydC51cGRhdGUoKTtcbiAgfVxuXG4gIC8vIER5bmFtaWMgYWRkIGRhdGFcbiAgYWRkRGF0YShsYWJlbHM6IExhYmVsc1tdLCBkYXRhOiBhbnlbXVtdKTogdm9pZCB7XG4gICAgdGhpcy5hZGREYXRhXyhsYWJlbHMsIGRhdGEpO1xuICAgIHRoaXMudXBkYXRlKCk7XG4gIH1cbiAgLy8gRHluYW1pYyByZW1vdmUgZGF0YSwgb3JpZW50YXRpb24gaXMgJ2lsZGVzdCcgb3IgJ2xhdGVzdCdcbiAgcmVtb3ZlRGF0YShvcmllbnRhdGlvbjogT3JpZW50YXRpb24pOiB2b2lkIHtcbiAgICB0aGlzLnJlbW92ZURhdGFfKG9yaWVudGF0aW9uKTtcbiAgICB0aGlzLnVwZGF0ZSgpO1xuICB9XG5cbiAgcHJpdmF0ZSByZWZyZXNoKCk6IHZvaWQge1xuICAgIHRoaXMubmdPbkRlc3Ryb3koKTtcbiAgICB0aGlzLmNoYXJ0ID0gdGhpcy5nZXRDaGFydEJ1aWxkZXIodGhpcy5jdHgvKiwgZGF0YSwgdGhpcy5vcHRpb25zKi8pO1xuICAgIHRoaXMuYWRkQ2hhcnQodGhpcy5pZCk7XG4gIH1cblxuICBwcml2YXRlIHJlbW92ZUNoYXJ0KGlkOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5lbGVtZW50Lm5hdGl2ZUVsZW1lbnQuaGFzQXR0cmlidXRlKCdpZCcpKSB7XG4gICAgICB0aGlzLnN0b3JlU2VydmljZS5yZW1vdmVDaGFydCh0aGlzLmVsZW1lbnQubmF0aXZlRWxlbWVudC5pZCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmIChpZCAhPT0gbnVsbCAmJiBpZCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aGlzLnN0b3JlU2VydmljZS5yZW1vdmVDaGFydChpZCk7ICAvLyBkZWxldGUgY2hhcnQgaW5zdGFuY2UuXG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBhZGRDaGFydChpZDogc3RyaW5nKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuZWxlbWVudC5uYXRpdmVFbGVtZW50Lmhhc0F0dHJpYnV0ZSgnaWQnKSkge1xuICAgICAgdGhpcy5zdG9yZVNlcnZpY2UuYWRkQ2hhcnQodGhpcy5lbGVtZW50Lm5hdGl2ZUVsZW1lbnQuaWQsIHRoaXMuY2hhcnQpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoaWQgIT09IG51bGwgJiYgaWQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhpcy5zdG9yZVNlcnZpY2UuYWRkQ2hhcnQoaWQsIHRoaXMuY2hhcnQpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgdXBkYXRlQ2hhcnREYXRhKG5ld0RhdGFWYWx1ZXM6IG51bWJlcltdIHwgYW55W10pOiB2b2lkIHtcbiAgICBpZiAoQXJyYXkuaXNBcnJheShuZXdEYXRhVmFsdWVzWzBdLmRhdGEpKSB7XG4gICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAvLyB0aGlzLmNoYXJ0LmRhdGEuZGF0YXNldHMuZm9yRWFjaCgoZGF0YXNldDogQ2hhcnREYXRhc2V0LCBpOiBudW1iZXIpID0+IHtcbiAgICAgIC8vICAgZGF0YXNldC5kYXRhID0gbmV3RGF0YVZhbHVlc1tpXS5kYXRhO1xuXG4gICAgICAvLyAgIGlmIChuZXdEYXRhVmFsdWVzW2ldLmxhYmVsKSB7XG4gICAgICAvLyAgICAgZGF0YXNldC5sYWJlbCA9IG5ld0RhdGFWYWx1ZXNbaV0ubGFiZWw7XG4gICAgICAvLyAgIH1cbiAgICAgIC8vIH0pO1xuXG4gICAgICAvLyBAdHMtaWdub3JlXG4gICAgICB0aGlzLmNoYXJ0LmRhdGEuZGF0YXNldHMgPSBuZXdEYXRhVmFsdWVzO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBAdHMtaWdub3JlXG4gICAgICB0aGlzLmNoYXJ0LmRhdGEuZGF0YXNldHNbMF0uZGF0YSA9IG5ld0RhdGFWYWx1ZXM7XG4gICAgfVxuICAgIC8vIHVwZGF0ZSBjb2xvcnNcbiAgICAvLyBAdHMtaWdub3JlXG4gICAgdGhpcy5jaGFydC5kYXRhLmRhdGFzZXRzID0gdGhpcy51cGRhdGVDb2xvcnModGhpcy5jaGFydC5kYXRhLmRhdGFzZXRzKTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0Q2hhcnRCdWlsZGVyKGN0eDogQ2FudmFzUmVuZGVyaW5nQ29udGV4dDJELyosIGRhdGE6QXJyYXk8YW55Piwgb3B0aW9uczphbnkqLyk6IENoYXJ0IHtcbiAgICBjb25zdCBkYXRhc2V0cyA9IHRoaXMuZ2V0RGF0YXNldHMoKTtcbiAgICBsZXQgb3B0aW9uczogQ2hhcnRPcHRpb25zID0gdGhpcy5vcHRpb25zIHx8IHt9O1xuICAgIG9wdGlvbnMgPSBPYmplY3QuYXNzaWduKHt9LCB0aGlzLm9wdGlvbnMpOyAvLyDmt7HlpI3liLZvcHRpb25zXG4gICAgbWVyZ2VKc29uKG9wdGlvbnMsIHtcbiAgICAgIHBsdWdpbnM6IHtcbiAgICAgICAgbGVnZW5kOiB7XG4gICAgICAgICAgZGlzcGxheTogdGhpcy5sZWdlbmRcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pXG5cbiAgICAvLyBob2NrIGZvciBvbkhvdmVyIGFuZCBvbkNsaWNrIGV2ZW50c1xuICAgIG9wdGlvbnMuaG92ZXIgPSBvcHRpb25zLmhvdmVyIHx8IHt9O1xuICAgIGlmICghb3B0aW9ucy5vbkhvdmVyKSB7XG4gICAgICBvcHRpb25zLm9uSG92ZXIgPSAoZXZlbnQ6IENoYXJ0RXZlbnQsIGFjdGl2ZTogQXJyYXk8e30+KSA9PiB7XG4gICAgICAgIGlmIChhY3RpdmUgJiYgIWFjdGl2ZS5sZW5ndGgpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5jaGFydEhvdmVyLmVtaXQoeyBldmVudCwgYWN0aXZlIH0pO1xuICAgICAgfTtcbiAgICB9XG5cbiAgICBpZiAoIW9wdGlvbnMub25DbGljaykge1xuICAgICAgb3B0aW9ucy5vbkNsaWNrID0gKGV2ZW50OiBDaGFydEV2ZW50LCBhY3RpdmU6IEFycmF5PHt9PikgPT4ge1xuICAgICAgICB0aGlzLmNoYXJ0Q2xpY2suZW1pdCh7IGV2ZW50LCBhY3RpdmUgfSk7XG4gICAgICB9O1xuICAgIH1cblxuICAgIGNvbnN0IGlubGluZVBsdWdpbnMgPSB0aGlzLmlubGluZVBsdWdpbnMgfHwgW107XG5cbiAgICBjb25zdCBvcHRzOiBDaGFydENvbmZpZ3VyYXRpb24gPSB7XG4gICAgICB0eXBlOiB0aGlzLmNoYXJ0VHlwZSxcbiAgICAgIGRhdGE6IHtcbiAgICAgICAgbGFiZWxzOiB0aGlzLmxhYmVscyxcbiAgICAgICAgZGF0YXNldHM6IGRhdGFzZXRzICAgLy8gVE9ETzog5ZCO57ut5pu05pS56L+Z5Liq5bGe5oCn5ZCN5a2X77yM5ZCm5YiZ6K2m5ZGKXG4gICAgICB9LFxuICAgICAgb3B0aW9uczogb3B0aW9ucywgICAvLyBUT0RPOiDlkI7nu63mm7TmlLnov5nkuKrlsZ7mgKflkI3lrZfvvIzlkKbliJnorablkYpcbiAgICAgIHBsdWdpbnM6IGlubGluZVBsdWdpbnNcbiAgICB9O1xuXG4gICAgcmV0dXJuIG5ldyBDaGFydChjdHgsIG9wdHMpO1xuICB9XG5cbiAgLy8g6I635Y+WIGNoYXJ0Lmpz55qEZGF0YXNldHPmlbDmja5cbiAgcHJpdmF0ZSBnZXREYXRhc2V0cygpOiBDaGFydERhdGFbJ2RhdGFzZXRzJ10ge1xuICAgIC8vIEB0cy1pZ25vcmVcbiAgICBsZXQgZGF0YXNldHM6IENoYXJ0RGF0YVsnZGF0YXNldHMnXSA9IHZvaWQgMDtcbiAgICAvLyBpbiBjYXNlIGlmIGRhdGFzZXRzIGlzIG5vdCBwcm92aWRlZCwgYnV0IGRhdGEgaXMgcHJlc2VudFxuICAgIGlmICghdGhpcy5kYXRhc2V0cyB8fCAhdGhpcy5kYXRhc2V0cy5sZW5ndGggJiYgKHRoaXMuZGF0YSAmJiB0aGlzLmRhdGEubGVuZ3RoKSkge1xuICAgICAgaWYgKEFycmF5LmlzQXJyYXkodGhpcy5kYXRhWzBdKSkge1xuICAgICAgICBkYXRhc2V0cyA9ICh0aGlzLmRhdGEgYXMgbnVtYmVyW11bXSkubWFwKChkYXRhOiBudW1iZXJbXSwgaW5kZXg6IG51bWJlcikgPT4ge1xuICAgICAgICAgIHJldHVybiB7IGRhdGEsIGxhYmVsOiB0aGlzLmxhYmVsc1tpbmRleF0gfHwgYExhYmVsICR7aW5kZXh9YCB9O1xuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGRhdGFzZXRzID0gW3sgZGF0YTogdGhpcy5kYXRhLCBsYWJlbDogYExhYmVsIDBgIH1dO1xuICAgICAgfVxuICAgIH1cblxuICAgIGRhdGFzZXRzID0gdGhpcy51cGRhdGVDb2xvcnMoZGF0YXNldHMpOyAvLyB1cGRhdGUgY29sb3JzXG5cbiAgICBpZiAoIWRhdGFzZXRzKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYG5nLWNoYXJ0anMgY29uZmlndXJhdGlvbiBlcnJvcixcbiAgICAgIGRhdGEgb3IgZGF0YXNldHMgZmllbGQgYXJlIHJlcXVpcmVkIHRvIHJlbmRlciBjaGFyICR7dGhpcy5jaGFydFR5cGV9YCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGRhdGFzZXRzO1xuICB9XG5cbiAgLy8gdXBkYXRlIGRhdGFzZXQgY29sb3JzXG4gIHByaXZhdGUgdXBkYXRlQ29sb3JzKGRhdGFzZXRzOiBDaGFydERhdGFbJ2RhdGFzZXRzJ10pOiBDaGFydERhdGFbJ2RhdGFzZXRzJ10ge1xuICAgIGlmICh0aGlzLmRhdGFzZXRzICYmIHRoaXMuZGF0YXNldHMubGVuZ3RoIHx8IChkYXRhc2V0cyAmJiBkYXRhc2V0cy5sZW5ndGgpKSB7XG4gICAgICAvLyBmaXggZWxtIHR5cGUsIHByZSB0eXBlIGlzIG51bWJlclxuICAgICAgZGF0YXNldHMgPSAodGhpcy5kYXRhc2V0cyB8fCBkYXRhc2V0cykubWFwKChlbG06IGFueSwgaW5kZXg6IG51bWJlcikgPT4ge1xuICAgICAgICBjb25zdCBuZXdFbG0gPSBPYmplY3QuYXNzaWduKHt9LCBlbG0pO1xuICAgICAgICBpZiAodGhpcy5jb2xvcnMgJiYgdGhpcy5jb2xvcnMubGVuZ3RoKSB7XG4gICAgICAgICAgT2JqZWN0LmFzc2lnbihuZXdFbG0sIHRoaXMuY29sb3JzW2luZGV4XSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICAgIE9iamVjdC5hc3NpZ24obmV3RWxtLCBnZXRDb2xvcnModGhpcy5jaGFydFR5cGUsIGluZGV4LCBuZXdFbG0uZGF0YS5sZW5ndGgpKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmV3RWxtO1xuICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiBkYXRhc2V0cztcbiAgfVxuXG4gIHByaXZhdGUgYWRkRGF0YV8obGFiZWxzOiBMYWJlbHNbXSwgZGF0YTogYW55W11bXSk6IHZvaWQge1xuICAgIGlmIChsYWJlbHMubGVuZ3RoID09PSAwIHx8IGRhdGEubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIC8vIHVwZGF0ZSBsYWJlbHNcbiAgICAvLyBAdHMtaWdub3JlXG4gICAgbGFiZWxzLmZvckVhY2goKGxhYmVsKSA9PiB7IHRoaXMuY2hhcnQuZGF0YS5sYWJlbHMucHVzaChsYWJlbCk7IH0pO1xuICAgIC8vIEB0cy1pZ25vcmVcbiAgICB0aGlzLmNoYXJ0LmRhdGEuZGF0YXNldHMuZm9yRWFjaCgoZGF0YXNldCwgaW5kZXgpID0+IHtcbiAgICAgIGlmIChkYXRhW2luZGV4XSkge1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGRhdGFbaW5kZXhdLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICAgIGRhdGFzZXQuZGF0YS5wdXNoKGRhdGFbaW5kZXhdW2ldKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc29sZS5sb2coJ1RoZSBhZGRlZCBkYXRhIGRvZXMgbm90IG1hdGNoIHRoZSBvcmlnaW5hbCBkYXRhJyk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgcmVtb3ZlRGF0YV8ob3JpZW50YXRpb246IE9yaWVudGF0aW9uKTogdm9pZCB7XG4gICAgLy8gZml4OiBzdXBwb3J0IHRvIG9sZGVzdCBmZWF0dXJlXG4gICAgaWYgKG9yaWVudGF0aW9uID09PSAnbGF0ZXN0Jykge1xuICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgdGhpcy5jaGFydC5kYXRhLmxhYmVscy5wb3AoKTtcbiAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgIHRoaXMuY2hhcnQuZGF0YS5kYXRhc2V0cy5mb3JFYWNoKChkYXRhc2V0OiBDaGFydERhdGFbJ2RhdGFzZXRzJ10pID0+IHtcbiAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICBkYXRhc2V0LmRhdGEucG9wKCk7XG4gICAgICB9KTtcbiAgICB9IGVsc2UgaWYgKG9yaWVudGF0aW9uID09PSAnb2xkZXN0Jykge1xuICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgdGhpcy5jaGFydC5kYXRhLmxhYmVscy5zaGlmdCgpO1xuICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgdGhpcy5jaGFydC5kYXRhLmRhdGFzZXRzLmZvckVhY2goKGRhdGFzZXQ6IENoYXJ0RGF0YVsnZGF0YXNldHMnXSkgPT4ge1xuICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgIGRhdGFzZXQuZGF0YS5zaGlmdCgpO1xuICAgICAgfSk7XG4gICAgfVxuICB9XG59XG4iXX0=