UNPKG

sb-dashlets

Version:

A Simple extensible angular library to render JSON data into different chart formats

222 lines 29.8 kB
import * as tslib_1 from "tslib"; import { Component, Inject, ViewChild } from '@angular/core'; import { DataService } from '../../services/index'; import { BaseChartDirective, ThemeService } from 'ng2-charts'; import { IReportType, ReportState } from '../../types/index'; import { BaseComponent } from '../base/base.component'; import { get, groupBy, mapValues, sumBy, remove } from 'lodash-es'; import { DEFAULT_CONFIG, DASHLET_CONSTANTS } from '../../tokens/index'; import { CHART_DEFAULT_CONFIG } from './defaultConfiguration'; const ɵ0 = CHART_DEFAULT_CONFIG; /** * @dynamic */ let ChartJsComponent = class ChartJsComponent extends BaseComponent { constructor(dataService, defaultConfig, CONSTANTS) { super(dataService); this.dataService = dataService; this.CONSTANTS = CONSTANTS; this.reportType = IReportType.CHART; this.inputParameters = {}; this.exportOptions = ['png', 'csv', 'jpg']; this._defaultConfig = defaultConfig; } /** * @description initializes the component with the passed config and data * @param {InputParams} { config, type, data } * @return {*} {Promise<any>} * @memberof ChartJsComponent */ initialize({ config, type, data }) { return tslib_1.__awaiter(this, void 0, void 0, function* () { if (!(config && type && data)) throw new SyntaxError(this.CONSTANTS.INVALID_INPUT); this.config = config = Object.assign({}, config, { type }); const fetchedJSON = this.data = yield this.fetchData(data).toPromise().catch(err => []); this.builder(config, fetchedJSON); this._isInitialized = true; this.state.emit(ReportState.DONE); }); } /** * @description It's a high order function responsible for getting labels and datasets, addition and removal of data. * @private * @param {string} labelExpr * @param {IDataset[]} datasets * @return {*} * @memberof ChartJsComponent */ getLabelsAndDatasetsClosure(labelExpr, datasets) { return (data) => { const getDataGroupedByLabelExpr = data => groupBy(data, val => { const value = get(val, labelExpr); return value && typeof value === 'string' ? value.toLowerCase().trim() : ''; }); const getLabels = (data) => Object.keys(data); const getDatasets = (data) => datasets.map(dataset => { return Object.assign({}, dataset, (dataset.dataExpr && { data: Object.values(mapValues(data, rows => sumBy(rows, row => +(row[dataset.dataExpr] || 0)))) })); }); const findDataByLabelPredicate = (label) => (row) => row[labelExpr] === label; return { addData(newData) { data = data.concat(newData); return this.getData(data); }, getData(overriddenData) { data = overriddenData || data; const groupedData = getDataGroupedByLabelExpr(data); return { labels: getLabels(groupedData), datasets: getDatasets(groupedData) }; }, removeData(label) { remove(data, findDataByLabelPredicate(label)); return this.getData(data); } }; }; } /** * @description prepared the chart data using the configuration passed * @param {Partial<IChartOptions>} config * @param {*} data * @memberof ChartJsComponent */ builder(config, data) { let { labels = [], labelExpr = null, type = null, legend = true, colors = [], datasets = [], options = {} } = config, others = tslib_1.__rest(config, ["labels", "labelExpr", "type", "legend", "colors", "datasets", "options"]); options = Object.assign({}, others, options); if (labelExpr) { this._labelsAndDatasetsClosure = this.getLabelsAndDatasetsClosure(labelExpr, datasets)(data); const { getData } = this._labelsAndDatasetsClosure; ({ labels, datasets } = getData()); } this.setChartData({ labels, datasets, options, type, legend, colors }); } setChartData(config = {}) { this.inputParameters = Object.assign({}, this._defaultConfig, this.inputParameters, config); this.$context = { data: this.data, config: this.config, inputParameters: this.inputParameters, exportOptions: this.exportOptions }; } reset() { // throw new Error('Method not implemented.'); } destroy() { this.baseChartDirective.chart.destroy(); } ngOnDestroy() { this.destroy(); } /** * @description updates the type, data or Dashlet configuration * @param {InputParams} input * @memberof ChartJsComponent */ update(input) { this.checkIfInitialized(); if (!input) throw new Error(this.CONSTANTS.INVALID_INPUT); const { type = null, config = {}, data = null } = input; let labels, datasets; if (data) { const { labelExpr, datasets: datasetsConfig } = config; if (labelExpr || datasets) { this._labelsAndDatasetsClosure = this.getLabelsAndDatasetsClosure(labelExpr || this.getConfigValue(labelExpr), datasetsConfig || this.getConfigValue(datasets))(data); } ({ labels, datasets } = this._labelsAndDatasetsClosure.getData(data)); } this.setChartData(Object.assign({}, config, (type && { type }), (labels && datasets && { labels, datasets }))); this.baseChartDirective.update(); } addData(data) { this.checkIfInitialized(); if (!data) throw new Error(this.CONSTANTS.INVALID_INPUT); if (this._labelsAndDatasetsClosure) { data = Array.isArray(data) ? data : [data]; const { labels, datasets } = this._labelsAndDatasetsClosure.addData(data); this.setChartData({ labels, datasets }); } } refreshChart() { throw new Error(this.CONSTANTS.METHOD_NOT_IMPLEMENTED); } /** * @description Removes data associated with a label * @param {string} label * @memberof ChartJsComponent */ removeData(label) { this.checkIfInitialized(); const { labels, datasets } = this._labelsAndDatasetsClosure.removeData(label); this.setChartData({ labels, datasets }); } getTelemetry() { throw new Error(this.CONSTANTS.METHOD_NOT_IMPLEMENTED); } getCurrentSelection() { throw new Error(this.CONSTANTS.METHOD_NOT_IMPLEMENTED); } getDatasetAtIndex(index) { throw new Error(this.CONSTANTS.METHOD_NOT_IMPLEMENTED); } onChartClicked(event) { this.events.emit({ type: 'CLICK', event }); } onChartHovered(event) { this.events.emit({ type: 'HOVER', event }); } exportAsImage(format = 'jpg') { const dataUrl = document.getElementById(this.id).toDataURL(`image/${format}`, 1); const fileName = `image.${format}`; this._downloadFile(dataUrl, fileName); } exportAs(format) { if (!this.exportOptions.includes(format)) { throw new Error('given type not supported'); } switch (format) { case 'csv': { this.exportAsCsv(); break; } default: { this.exportAsImage(format); break; } } } }; ChartJsComponent.ctorParameters = () => [ { type: DataService }, { type: Object, decorators: [{ type: Inject, args: [DEFAULT_CONFIG,] }] }, { type: undefined, decorators: [{ type: Inject, args: [DASHLET_CONSTANTS,] }] } ]; tslib_1.__decorate([ ViewChild(BaseChartDirective, { static: false }) ], ChartJsComponent.prototype, "baseChartDirective", void 0); ChartJsComponent = tslib_1.__decorate([ Component({ selector: 'sb-chart-js', template: "<ng-template #defaultFilterTemplate let-context>\n <sb-dashlets-filters [data]=\"context?.data\" [config]=\"context?.config?.filters\"\n (filteredData)=\"update({data: $event})\">\n </sb-dashlets-filters>\n</ng-template>\n\n<ng-container *ngIf=\"$context?.config?.filters\" [ngTemplateOutlet]=\"templateRefs?.filter || defaultFilterTemplate\"\n [ngTemplateOutletContext]=\"{'$implicit': $context}\">\n</ng-container>\n\n<ng-container *ngIf=\"templateRefs?.header && $context\" [ngTemplateOutlet]=\"templateRefs?.header\"\n [ngTemplateOutletContext]=\"{'$implicit': $context}\">\n</ng-container>\n\n<div *ngIf=\"$context?.inputParameters as data\">\n <canvas [id]=\"id\" baseChart width=\"400\" height=\"400\" [datasets]=\"data?.datasets\" [labels]=\"data?.labels\"\n [options]=\"data?.options\" [colors]=\"data?.colors\" [legend]=\"data?.legend\" [chartType]=\"data?.type\"\n (chartClick)=\"onChartClicked($event)\" (chartHover)=\"onChartHovered($event)\"></canvas>\n</div>\n\n<ng-container *ngIf=\"templateRefs?.footer && $context\" [ngTemplateOutlet]=\"templateRefs?.footer\"\n [ngTemplateOutletContext]=\"{'$implicit': $context}\">\n</ng-container>", providers: [ ThemeService, { provide: DEFAULT_CONFIG, useValue: ɵ0 } ], styles: [""] }), tslib_1.__param(1, Inject(DEFAULT_CONFIG)), tslib_1.__param(2, Inject(DASHLET_CONSTANTS)) ], ChartJsComponent); export { ChartJsComponent }; export { ɵ0 }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2hhcnQtanMuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6Im5nOi8vc2ItZGFzaGxldHMvIiwic291cmNlcyI6WyJsaWIvY29tcG9uZW50cy9jaGFydC1qcy9jaGFydC1qcy5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxFQUFhLFNBQVMsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUN4RSxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDbkQsT0FBTyxFQUFFLGtCQUFrQixFQUFFLFlBQVksRUFBRSxNQUFNLFlBQVksQ0FBQztBQUM5RCxPQUFPLEVBQWUsV0FBVyxFQUFrQyxXQUFXLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUMxRyxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFFdkQsT0FBTyxFQUFFLEdBQUcsRUFBRSxPQUFPLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFDbkUsT0FBTyxFQUFFLGNBQWMsRUFBRSxpQkFBaUIsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQ3ZFLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLHdCQUF3QixDQUFBO1dBYTdDLG9CQUFvQjtBQVhwQzs7R0FFRztBQWFILElBQWEsZ0JBQWdCLEdBQTdCLE1BQWEsZ0JBQWlCLFNBQVEsYUFBYTtJQVlqRCxZQUFzQixXQUF3QixFQUEwQixhQUFxQixFQUFxQyxTQUF1QjtRQUN2SixLQUFLLENBQUMsV0FBVyxDQUFDLENBQUM7UUFEQyxnQkFBVyxHQUFYLFdBQVcsQ0FBYTtRQUFvRixjQUFTLEdBQVQsU0FBUyxDQUFjO1FBVGhKLGVBQVUsR0FBZ0IsV0FBVyxDQUFDLEtBQUssQ0FBQztRQUs5QyxvQkFBZSxHQUEyQixFQUFFLENBQUM7UUFFN0Msa0JBQWEsR0FBRyxDQUFDLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FB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QUMsTUFBYztRQUNyQixJQUFJLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLEVBQUU7WUFDeEMsTUFBTSxJQUFJLEtBQUssQ0FBQywwQkFBMEIsQ0FBQyxDQUFDO1NBQzdDO1FBQ0QsUUFBUSxNQUFNLEVBQUU7WUFDZCxLQUFLLEtBQUssQ0FBQyxDQUFDO2dCQUNWLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztnQkFDbkIsTUFBTTthQUNQO1lBQ0QsT0FBTyxDQUFDLENBQUM7Z0JBQ1AsSUFBSSxDQUFDLGFBQWEsQ0FBQyxNQUFNLENBQUMsQ0FBQztnQkFDM0IsTUFBTTthQUNQO1NBQ0Y7SUFDSCxDQUFDO0NBQ0YsQ0FBQTs7WUFoTW9DLFdBQVc7eUNBQUcsTUFBTSxTQUFDLGNBQWM7NENBQTBCLE1BQU0sU0FBQyxpQkFBaUI7O0FBVnRFO0lBQWpELFNBQVMsQ0FBQyxrQkFBa0IsRUFBRSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsQ0FBQzs0REFBd0M7QUFGOUUsZ0JBQWdCO0lBWjVCLFNBQVMsQ0FBQztRQUNULFFBQVEsRUFBRSxhQUFhO1FBQ3ZCLDBwQ0FBd0M7UUFFeEMsU0FBUyxFQUFFO1lBQ1QsWUFBWTtZQUNaO2dCQUNFLE9BQU8sRUFBRSxjQUFjO2dCQUN2QixRQUFRLElBQXNCO2FBQy9CO1NBQ0Y7O0tBQ0YsQ0FBQztJQWFpRCxtQkFBQSxNQUFNLENBQUMsY0FBYyxDQUFDLENBQUEsRUFBeUIsbUJBQUEsTUFBTSxDQUFDLGlCQUFpQixDQUFDLENBQUE7R0FaOUcsZ0JBQWdCLENBNE01QjtTQTVNWSxnQkFBZ0IiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIEluamVjdCwgT25EZXN0cm95LCBWaWV3Q2hpbGQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IERhdGFTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc2VydmljZXMvaW5kZXgnO1xuaW1wb3J0IHsgQmFzZUNoYXJ0RGlyZWN0aXZlLCBUaGVtZVNlcnZpY2UgfSBmcm9tICduZzItY2hhcnRzJztcbmltcG9ydCB7IElucHV0UGFyYW1zLCBJUmVwb3J0VHlwZSwgSURhdGFzZXQsIElDaGFydCwgU3RyaW5nT2JqZWN0LCBSZXBvcnRTdGF0ZSB9IGZyb20gJy4uLy4uL3R5cGVzL2luZGV4JztcbmltcG9ydCB7IEJhc2VDb21wb25lbnQgfSBmcm9tICcuLi9iYXNlL2Jhc2UuY29tcG9uZW50JztcbmltcG9ydCB7IElDaGFydE9wdGlvbnMsIENoYXJ0VHlwZSwgVXBkYXRlSW5wdXRQYXJhbXMgfSBmcm9tICcuLi8uLi90eXBlcy9pbmRleCc7XG5pbXBvcnQgeyBnZXQsIGdyb3VwQnksIG1hcFZhbHVlcywgc3VtQnksIHJlbW92ZSB9IGZyb20gJ2xvZGFzaC1lcyc7XG5pbXBvcnQgeyBERUZBVUxUX0NPTkZJRywgREFTSExFVF9DT05TVEFOVFMgfSBmcm9tICcuLi8uLi90b2tlbnMvaW5kZXgnO1xuaW1wb3J0IHsgQ0hBUlRfREVGQVVMVF9DT05GSUcgfSBmcm9tICcuL2RlZmF1bHRDb25maWd1cmF0aW9uJ1xuXG4vKipcbiAqIEBkeW5hbWljXG4gKi9cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ3NiLWNoYXJ0LWpzJyxcbiAgdGVtcGxhdGVVcmw6ICcuL2NoYXJ0LWpzLmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vY2hhcnQtanMuY29tcG9uZW50LmNzcyddLFxuICBwcm92aWRlcnM6IFtcbiAgICBUaGVtZVNlcnZpY2UsXG4gICAge1xuICAgICAgcHJvdmlkZTogREVGQVVMVF9DT05GSUcsXG4gICAgICB1c2VWYWx1ZTogQ0hBUlRfREVGQVVMVF9DT05GSUdcbiAgICB9XG4gIF1cbn0pXG5leHBvcnQgY2xhc3MgQ2hhcnRKc0NvbXBvbmVudCBleHRlbmRzIEJhc2VDb21wb25lbnQgaW1wbGVtZW50cyBJQ2hhcnQsIE9uRGVzdHJveSB7XG5cbiAgQFZpZXdDaGlsZChCYXNlQ2hhcnREaXJlY3RpdmUsIHsgc3RhdGljOiBmYWxzZSB9KSBiYXNlQ2hhcnREaXJlY3RpdmU6IEJhc2VDaGFydERpcmVjdGl2ZTtcbiAgcmVhZG9ubHkgcmVwb3J0VHlwZTogSVJlcG9ydFR5cGUgPSBJUmVwb3J0VHlwZS5DSEFSVDtcblxuICBwdWJsaWMgX2RlZmF1bHRDb25maWc6IFBhcnRpYWw8SUNoYXJ0T3B0aW9ucz47XG4gIHB1YmxpYyBjb25maWc6IFBhcnRpYWw8SUNoYXJ0T3B0aW9ucz47XG4gIHB1YmxpYyB0eXBlOiBDaGFydFR5cGU7XG4gIHB1YmxpYyBpbnB1dFBhcmFtZXRlcnM6IFBhcnRpYWw8SUNoYXJ0T3B0aW9ucz4gPSB7fTtcbiAgcHVibGljIF9sYWJlbHNBbmREYXRhc2V0c0Nsb3N1cmU6IGFueTtcbiAgcHVibGljIGV4cG9ydE9wdGlvbnMgPSBbJ3BuZycsICdjc3YnLCAnanBnJ107XG5cbiAgY29uc3RydWN0b3IocHJvdGVjdGVkIGRhdGFTZXJ2aWNlOiBEYXRhU2VydmljZSwgQEluamVjdChERUZBVUxUX0NPTkZJRykgZGVmYXVsdENvbmZpZzogb2JqZWN0LCBASW5qZWN0KERBU0hMRVRfQ09OU1RBTlRTKSBwcml2YXRlIENPTlNUQU5UUzogU3RyaW5nT2JqZWN0KSB7XG4gICAgc3VwZXIoZGF0YVNlcnZpY2UpO1xuICAgIHRoaXMuX2RlZmF1bHRDb25maWcgPSBkZWZhdWx0Q29uZmlnO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBpbml0aWFsaXplcyB0aGUgY29tcG9uZW50IHdpdGggdGhlIHBhc3NlZCBjb25maWcgYW5kIGRhdGFcbiAgICogQHBhcmFtIHtJbnB1dFBhcmFtc30geyBjb25maWcsIHR5cGUsIGRhdGEgfVxuICAgKiBAcmV0dXJuIHsqfSAge1Byb21pc2U8YW55Pn1cbiAgICogQG1lbWJlcm9mIENoYXJ0SnNDb21wb25lbnRcbiAgICovXG4gIGFzeW5jIGluaXRpYWxpemUoeyBjb25maWcsIHR5cGUsIGRhdGEgfTogSW5wdXRQYXJhbXMpOiBQcm9taXNlPGFueT4ge1xuICAgIGlmICghKGNvbmZpZyAmJiB0eXBlICYmIGRhdGEpKSB0aHJvdyBuZXcgU3ludGF4RXJyb3IodGhpcy5DT05TVEFOVFMuSU5WQUxJRF9JTlBVVCk7XG4gICAgdGhpcy5jb25maWcgPSBjb25maWcgPSB7IC4uLmNvbmZpZywgdHlwZSB9O1xuICAgIGNvbnN0IGZldGNoZWRKU09OID0gdGhpcy5kYXRhID0gYXdhaXQgdGhpcy5mZXRjaERhdGEoZGF0YSkudG9Qcm9taXNlKCkuY2F0Y2goZXJyID0+IFtdKTtcbiAgICB0aGlzLmJ1aWxkZXIoY29uZmlnLCBmZXRjaGVkSlNPTik7XG4gICAgdGhpcy5faXNJbml0aWFsaXplZCA9IHRydWU7XG4gICAgdGhpcy5zdGF0ZS5lbWl0KFJlcG9ydFN0YXRlLkRPTkUpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBJdCdzIGEgaGlnaCBvcmRlciBmdW5jdGlvbiByZXNwb25zaWJsZSBmb3IgZ2V0dGluZyBsYWJlbHMgYW5kIGRhdGFzZXRzLCBhZGRpdGlvbiBhbmQgcmVtb3ZhbCBvZiBkYXRhLlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gbGFiZWxFeHByXG4gICAqIEBwYXJhbSB7SURhdGFzZXRbXX0gZGF0YXNldHNcbiAgICogQHJldHVybiB7Kn1cbiAgICogQG1lbWJlcm9mIENoYXJ0SnNDb21wb25lbnRcbiAgICovXG4gIHByaXZhdGUgZ2V0TGFiZWxzQW5kRGF0YXNldHNDbG9zdXJlKGxhYmVsRXhwcjogc3RyaW5nLCBkYXRhc2V0czogSURhdGFzZXRbXSkge1xuICAgIHJldHVybiAoZGF0YTogb2JqZWN0W10pID0+IHtcbiAgICAgIGNvbnN0IGdldERhdGFHcm91cGVkQnlMYWJlbEV4cHIgPSBkYXRhID0+IGdyb3VwQnkoZGF0YSwgdmFsID0+IHtcbiAgICAgICAgY29uc3QgdmFsdWUgPSBnZXQodmFsLCBsYWJlbEV4cHIpO1xuICAgICAgICByZXR1cm4gdmFsdWUgJiYgdHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJyA/IHZhbHVlLnRvTG93ZXJDYXNlKCkudHJpbSgpIDogJyc7XG4gICAgICB9KTtcbiAgICAgIGNvbnN0IGdldExhYmVscyA9IChkYXRhOiBvYmplY3QpID0+IE9iamVjdC5rZXlzKGRhdGEpO1xuICAgICAgY29uc3QgZ2V0RGF0YXNldHMgPSAoZGF0YTogb2JqZWN0KSA9PiBkYXRhc2V0cy5tYXAoZGF0YXNldCA9PiB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgLi4uZGF0YXNldCxcbiAgICAgICAgICAuLi4oZGF0YXNldC5kYXRhRXhwciAmJiB7XG4gICAgICAgICAgICBkYXRhOiBPYmplY3QudmFsdWVzKG1hcFZhbHVlcyhkYXRhLCByb3dzID0+IHN1bUJ5KHJvd3MsIHJvdyA9PiArKHJvd1tkYXRhc2V0LmRhdGFFeHByXSB8fCAwKSkpKVxuICAgICAgICAgIH0pXG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgY29uc3QgZmluZERhdGFCeUxhYmVsUHJlZGljYXRlID0gKGxhYmVsOiBzdHJpbmcpID0+IChyb3c6IG9iamVjdCkgPT4gcm93W2xhYmVsRXhwcl0gPT09IGxhYmVsO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgYWRkRGF0YShuZXdEYXRhOiBvYmplY3RbXSkge1xuICAgICAgICAgIGRhdGEgPSBkYXRhLmNvbmNhdChuZXdEYXRhKTtcbiAgICAgICAgICByZXR1cm4gdGhpcy5nZXREYXRhKGRhdGEpO1xuICAgICAgICB9LFxuICAgICAgICBnZXREYXRhKG92ZXJyaWRkZW5EYXRhPzogb2JqZWN0W10pIHtcbiAgICAgICAgICBkYXRhID0gb3ZlcnJpZGRlbkRhdGEgfHwgZGF0YTtcbiAgICAgICAgICBjb25zdCBncm91cGVkRGF0YSA9IGdldERhdGFHcm91cGVkQnlMYWJlbEV4cHIoZGF0YSk7XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGxhYmVsczogZ2V0TGFiZWxzKGdyb3VwZWREYXRhKSxcbiAgICAgICAgICAgIGRhdGFzZXRzOiBnZXREYXRhc2V0cyhncm91cGVkRGF0YSlcbiAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIHJlbW92ZURhdGEobGFiZWw6IHN0cmluZykge1xuICAgICAgICAgIHJlbW92ZShkYXRhLCBmaW5kRGF0YUJ5TGFiZWxQcmVkaWNhdGUobGFiZWwpKTtcbiAgICAgICAgICByZXR1cm4gdGhpcy5nZXREYXRhKGRhdGEpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBwcmVwYXJlZCB0aGUgY2hhcnQgZGF0YSB1c2luZyB0aGUgY29uZmlndXJhdGlvbiBwYXNzZWRcbiAgICogQHBhcmFtIHtQYXJ0aWFsPElDaGFydE9wdGlvbnM+fSBjb25maWdcbiAgICogQHBhcmFtIHsqfSBkYXRhXG4gICAqIEBtZW1iZXJvZiBDaGFydEpzQ29tcG9uZW50XG4gICAqL1xuICBidWlsZGVyKGNvbmZpZzogUGFydGlhbDxJQ2hhcnRPcHRpb25zPiwgZGF0YSkge1xuICAgIGxldCB7IGxhYmVscyA9IFtdLCBsYWJlbEV4cHIgPSBudWxsLCB0eXBlID0gbnVsbCwgbGVnZW5kID0gdHJ1ZSwgY29sb3JzID0gW10sIGRhdGFzZXRzID0gW10sIG9wdGlvbnMgPSB7fSwgLi4ub3RoZXJzIH0gPSBjb25maWc7XG4gICAgb3B0aW9ucyA9IHsgLi4ub3RoZXJzLCAuLi5vcHRpb25zIH07XG4gICAgaWYgKGxhYmVsRXhwcikge1xuICAgICAgdGhpcy5fbGFiZWxzQW5kRGF0YXNldHNDbG9zdXJlID0gdGhpcy5nZXRMYWJlbHNBbmREYXRhc2V0c0Nsb3N1cmUobGFiZWxFeHByLCBkYXRhc2V0cykoZGF0YSk7XG4gICAgICBjb25zdCB7IGdldERhdGEgfSA9IHRoaXMuX2xhYmVsc0FuZERhdGFzZXRzQ2xvc3VyZTtcbiAgICAgICh7IGxhYmVscywgZGF0YXNldHMgfSA9IGdldERhdGEoKSk7XG4gICAgfVxuICAgIHRoaXMuc2V0Q2hhcnREYXRhKHsgbGFiZWxzLCBkYXRhc2V0cywgb3B0aW9ucywgdHlwZSwgbGVnZW5kLCBjb2xvcnMgfSk7XG4gIH1cblxuICBwcml2YXRlIHNldENoYXJ0RGF0YShjb25maWc6IFBhcnRpYWw8SUNoYXJ0T3B0aW9ucz4gPSB7fSkge1xuICAgIHRoaXMuaW5wdXRQYXJhbWV0ZXJzID0geyAuLi50aGlzLl9kZWZhdWx0Q29uZmlnLCAuLi50aGlzLmlucHV0UGFyYW1ldGVycywgLi4uY29uZmlnIH07XG4gICAgdGhpcy4kY29udGV4dCA9IHsgZGF0YTogdGhpcy5kYXRhLCBjb25maWc6IHRoaXMuY29uZmlnLCBpbnB1dFBhcmFtZXRlcnM6IHRoaXMuaW5wdXRQYXJhbWV0ZXJzLCBleHBvcnRPcHRpb25zOiB0aGlzLmV4cG9ydE9wdGlvbnMgfTtcbiAgfVxuXG4gIHJlc2V0KCk6IHZvaWQge1xuICAgIC8vIHRocm93IG5ldyBFcnJvcignTWV0aG9kIG5vdCBpbXBsZW1lbnRlZC4nKTtcbiAgfVxuXG4gIGRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy5iYXNlQ2hhcnREaXJlY3RpdmUuY2hhcnQuZGVzdHJveSgpO1xuICB9XG5cbiAgbmdPbkRlc3Ryb3koKSB7XG4gICAgdGhpcy5kZXN0cm95KCk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIHVwZGF0ZXMgdGhlIHR5cGUsIGRhdGEgb3IgRGFzaGxldCBjb25maWd1cmF0aW9uXG4gICAqIEBwYXJhbSB7SW5wdXRQYXJhbXN9IGlucHV0XG4gICAqIEBtZW1iZXJvZiBDaGFydEpzQ29tcG9uZW50XG4gICAqL1xuICB1cGRhdGUoaW5wdXQ6IFBhcnRpYWw8VXBkYXRlSW5wdXRQYXJhbXM+KSB7XG4gICAgdGhpcy5jaGVja0lmSW5pdGlhbGl6ZWQoKTtcbiAgICBpZiAoIWlucHV0KSB0aHJvdyBuZXcgRXJyb3IodGhpcy5DT05TVEFOVFMuSU5WQUxJRF9JTlBVVCk7XG4gICAgY29uc3QgeyB0eXBlID0gbnVsbCwgY29uZmlnID0ge30sIGRhdGEgPSBudWxsIH0gPSBpbnB1dDtcbiAgICBsZXQgbGFiZWxzLCBkYXRhc2V0cztcbiAgICBpZiAoZGF0YSkge1xuICAgICAgY29uc3QgeyBsYWJlbEV4cHIsIGRhdGFzZXRzOiBkYXRhc2V0c0NvbmZpZyB9ID0gY29uZmlnIGFzIHsgbGFiZWxFeHByOiBzdHJpbmcsIGRhdGFzZXRzOiBJRGF0YXNldFtdIH07XG4gICAgICBpZiAobGFiZWxFeHByIHx8IGRhdGFzZXRzKSB7XG4gICAgICAgIHRoaXMuX2xhYmVsc0FuZERhdGFzZXRzQ2xvc3VyZSA9IHRoaXMuZ2V0TGFiZWxzQW5kRGF0YXNldHNDbG9zdXJlKGxhYmVsRXhwciB8fCB0aGlzLmdldENvbmZpZ1ZhbHVlKGxhYmVsRXhwciksIGRhdGFzZXRzQ29uZmlnIHx8IHRoaXMuZ2V0Q29uZmlnVmFsdWUoZGF0YXNldHMpKShkYXRhKTtcbiAgICAgIH1cbiAgICAgICh7IGxhYmVscywgZGF0YXNldHMgfSA9IHRoaXMuX2xhYmVsc0FuZERhdGFzZXRzQ2xvc3VyZS5nZXREYXRhKGRhdGEpKTtcbiAgICB9XG4gICAgdGhpcy5zZXRDaGFydERhdGEoeyAuLi5jb25maWcsIC4uLih0eXBlICYmIHsgdHlwZSB9KSwgLi4uKGxhYmVscyAmJiBkYXRhc2V0cyAmJiB7IGxhYmVscywgZGF0YXNldHMgfSkgfSk7XG4gICAgdGhpcy5iYXNlQ2hhcnREaXJlY3RpdmUudXBkYXRlKCk7XG4gIH1cblxuICBhZGREYXRhKGRhdGE6IG9iamVjdFtdIHwgb2JqZWN0KSB7XG4gICAgdGhpcy5jaGVja0lmSW5pdGlhbGl6ZWQoKTtcbiAgICBpZiAoIWRhdGEpIHRocm93IG5ldyBFcnJvcih0aGlzLkNPTlNUQU5UUy5JTlZBTElEX0lOUFVUKTtcbiAgICBpZiAodGhpcy5fbGFiZWxzQW5kRGF0YXNldHNDbG9zdXJlKSB7XG4gICAgICBkYXRhID0gQXJyYXkuaXNBcnJheShkYXRhKSA/IGRhdGEgOiBbZGF0YV07XG4gICAgICBjb25zdCB7IGxhYmVscywgZGF0YXNldHMgfSA9IHRoaXMuX2xhYmVsc0FuZERhdGFzZXRzQ2xvc3VyZS5hZGREYXRhKGRhdGEpO1xuICAgICAgdGhpcy5zZXRDaGFydERhdGEoeyBsYWJlbHMsIGRhdGFzZXRzIH0pO1xuICAgIH1cbiAgfVxuXG4gIHJlZnJlc2hDaGFydCgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IodGhpcy5DT05TVEFOVFMuTUVUSE9EX05PVF9JTVBMRU1FTlRFRCk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFJlbW92ZXMgZGF0YSBhc3NvY2lhdGVkIHdpdGggYSBsYWJlbFxuICAgKiBAcGFyYW0ge3N0cmluZ30gbGFiZWxcbiAgICogQG1lbWJlcm9mIENoYXJ0SnNDb21wb25lbnRcbiAgICovXG4gIHJlbW92ZURhdGEobGFiZWw6IHN0cmluZykge1xuICAgIHRoaXMuY2hlY2tJZkluaXRpYWxpemVkKCk7XG4gICAgY29uc3QgeyBsYWJlbHMsIGRhdGFzZXRzIH0gPSB0aGlzLl9sYWJlbHNBbmREYXRhc2V0c0Nsb3N1cmUucmVtb3ZlRGF0YShsYWJlbCk7XG4gICAgdGhpcy5zZXRDaGFydERhdGEoeyBsYWJlbHMsIGRhdGFzZXRzIH0pO1xuICB9XG5cbiAgZ2V0VGVsZW1ldHJ5KCkge1xuICAgIHRocm93IG5ldyBFcnJvcih0aGlzLkNPTlNUQU5UUy5NRVRIT0RfTk9UX0lNUExFTUVOVEVEKTtcbiAgfVxuXG4gIGdldEN1cnJlbnRTZWxlY3Rpb24oKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKHRoaXMuQ09OU1RBTlRTLk1FVEhPRF9OT1RfSU1QTEVNRU5URUQpO1xuICB9XG5cbiAgZ2V0RGF0YXNldEF0SW5kZXgoaW5kZXg6IG51bWJlcikge1xuICAgIHRocm93IG5ldyBFcnJvcih0aGlzLkNPTlNUQU5UUy5NRVRIT0RfTk9UX0lNUExFTUVOVEVEKTtcbiAgfVxuXG4gIG9uQ2hhcnRDbGlja2VkKGV2ZW50KSB7XG4gICAgdGhpcy5ldmVudHMuZW1pdCh7XG4gICAgICB0eXBlOiAnQ0xJQ0snLFxuICAgICAgZXZlbnRcbiAgICB9KVxuICB9XG5cbiAgb25DaGFydEhvdmVyZWQoZXZlbnQpIHtcbiAgICB0aGlzLmV2ZW50cy5lbWl0KHtcbiAgICAgIHR5cGU6ICdIT1ZFUicsXG4gICAgICBldmVudFxuICAgIH0pXG4gIH1cblxuICBleHBvcnRBc0ltYWdlKGZvcm1hdCA9ICdqcGcnKSB7XG4gICAgY29uc3QgZGF0YVVybCA9IChkb2N1bWVudC5nZXRFbGVtZW50QnlJZCh0aGlzLmlkKSBhcyBhbnkpLnRvRGF0YVVSTChgaW1hZ2UvJHtmb3JtYXR9YCwgMSk7XG4gICAgY29uc3QgZmlsZU5hbWUgPSBgaW1hZ2UuJHtmb3JtYXR9YDtcbiAgICB0aGlzLl9kb3dubG9hZEZpbGUoZGF0YVVybCwgZmlsZU5hbWUpO1xuICB9XG5cbiAgZXhwb3J0QXMoZm9ybWF0OiBzdHJpbmcpIHtcbiAgICBpZiAoIXRoaXMuZXhwb3J0T3B0aW9ucy5pbmNsdWRlcyhmb3JtYXQpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2dpdmVuIHR5cGUgbm90IHN1cHBvcnRlZCcpO1xuICAgIH1cbiAgICBzd2l0Y2ggKGZvcm1hdCkge1xuICAgICAgY2FzZSAnY3N2Jzoge1xuICAgICAgICB0aGlzLmV4cG9ydEFzQ3N2KCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgZGVmYXVsdDoge1xuICAgICAgICB0aGlzLmV4cG9ydEFzSW1hZ2UoZm9ybWF0KTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG4iXX0=