UNPKG

@biacsics/ng-canvas-gauges

Version:

Angular 15+ component wrapper for the canvas-gauges lib written by @Mikhus

255 lines 30.1 kB
/*! * The MIT License (MIT) * * Copyright (c) 2017 Vlad Martynenko <vladimir.martynenko.work@gmail.com> * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ import { ViewChild, Input, NgZone, ElementRef, Directive } from '@angular/core'; import * as CanvasGauges from 'canvas-gauges'; import * as Rx from 'rx-dom-html'; import * as i0 from "@angular/core"; const _c0 = ["gauge"]; // String utils const toCamelCase = (str) => str.replace(/(\-\w)/g, (matches) => matches[1].toUpperCase()); const toKebabCase = (str) => str.replace(/([a-z0-9])([A-Z])/g, '$1-$2').toLowerCase(); const attributeName2PropertyName = (attrName) => toCamelCase(attrName); /** * Base gauge component for the Gauges rendering * T - Type of the Gauge to be rendered (Currently RadialGauge, LinearGauge from the original library) * T2 - Type of config options used by the particular gauge (RadialGaugeOptions, LinearGaugeOptions) */ class BaseGauge { el; zone; /** * Canvas element on the template used by the library to draw gauge element */ canvas; /** * A gauge instance responsible for rendering and updates on the canvas. * Subclasses should initialize in their ngOnInit implementation. */ gauge; /** * Flag indicating that OnViewInit life-cycle has completed */ isInited = false; /** * value property of gauge prior to component view initialization */ preInitValue; /** * options property of gauge prior to component view initialization */ preInitOptions; /** * Listen for attribute changes, i.e., options properties that are stored * as attributes on this ElementRef */ domListener; /** * * @param el - reference to the element of the whole component, used to scrape options declared on the component itself * @param zone - required to redraw gauge outside of Angular, due to animation lags caused by the ovewritten function of the ngZone */ constructor(el, zone) { this.el = el; this.zone = zone; } /** * Returns gauges properties as an options object. * Option properties consist of the attribute-based properties and those * explicitly set. * @returns <T2> */ get options() { const options = {}; options.renderTo = this.canvas.nativeElement; // Map attribute-based options onto options. // Requries converting kebab style attribute names to camelCase property names for (const attr of this.el.nativeElement.attributes) { const prop = attributeName2PropertyName(attr.name); options[prop] = CanvasGauges.DomObserver.parse(attr.value); } // merge preOptons with attribute-based properties // tslint:disable-next-line:forin for (const prop in this.preInitOptions) { options[prop] = this.preInitOptions[prop]; } // clear the preInitOptions as they have already been merged // with the attribute-based properties if (this.isInited) { this.preInitOptions = null; } return options; } /** * Assign gauge options at anytime in the lifecycle. * @param newOptions - assign the style and size properties */ set options(newOptions) { // cache newOptions as preInitOptions until gauge is ready if (!this.isInited) { this.preInitOptions = newOptions; return; } this.update(newOptions); } /** * Assign the value of the gauge visual indicator such as a needle or pointer * @param newValue the guage new value */ set value(newValue) { // case new gauge value as preInitValue until the gauge is ready if (!this.isInited) { this.preInitValue = newValue; return; } this.zone.runOutsideAngular(() => { this.gauge.value = newValue; }); } /** * Update the gauge options. Do not use until after OnViewInit() before using. * * Special implementation note - options.properties are maintained as * attribute name->value on this component's elementRef. Thus this method * maps each newOptions property onto the property's corresponding attribute. * The attribute update triggers a DOM mutation event which "this" listens for. * See #listenForDOMEvents() * * @param newOptions - the options to update the gauge */ update(newOptions) { // map all options onto this element's attributes // Then attribute changes will be detected and pushed to the gauge.update() if (!newOptions) { return; } // tslint:disable-next-line:forin for (const prop in newOptions) { const val = newOptions[prop].toString(); if (prop === 'value') { // short circuit the value property update by calling // the gauge.value api directly for efficient animated update this.value = CanvasGauges.DomObserver.parse(val); } else { const attrName = toKebabCase(prop); this.el.nativeElement.setAttribute(attrName, val); } } } /** * Perform gauge initialization. * Subclasses that override this method must this super version * for proper operation. */ ngAfterViewInit() { // initial update of gauge properties this.initGauge(); this.listenForDOMEvents(); this.isInited = true; } /** * Listen for attribute-change events that are created when updating * the options of this gauge. */ listenForDOMEvents() { // Listen to gauge element for attribute changes // Convert all changed attribtues into a GenericOptions or subclass // Update the gauge with the new options. this.domListener = Rx.DOM.fromMutationObserver(this.el.nativeElement, { attributes: true }). subscribe(changes => { const newOptions = {}; changes.forEach(change => { if ('attributes' === change.type) { // console.log('DOM, change', change.attributeName); newOptions[attributeName2PropertyName(change.attributeName)] = CanvasGauges.DomObserver.parse(this.el.nativeElement.getAttribute(change.attributeName)); } }); this.basicUpdate(newOptions); }); } /** * Discontinue listening for attribute change events. */ stopListeningForDOMEvents() { if (this.domListener) { this.domListener.disconnect(); this.domListener = null; } } /** * Initalize the gauge with all options defined by attributes and * parent component options. */ initGauge() { const options = this.options; if (this.preInitValue) { options.value = this.preInitValue; } // init options.renderTo if needed if (!options.hasOwnProperty('renderTo') || !options.renderTo) { options.renderTo = this.canvas.nativeElement; } this.basicUpdate(options); } /** * Performs the gauge update using the current options * @param options The options for the guage */ basicUpdate(options) { // treat the value property special and update it through the // value getter. if (typeof options.value === 'number') { // use gauge api directly for most efficient update method this.value = options.value; // filter value property from options to avoid redundant // processing by gauge delete options.value; } // do nothing if no option properties to update if (Object.keys(options).length) { this.gauge.update(options); } } static ɵfac = function BaseGauge_Factory(t) { return new (t || BaseGauge)(i0.ɵɵdirectiveInject(i0.ElementRef), i0.ɵɵdirectiveInject(i0.NgZone)); }; static ɵdir = /*@__PURE__*/ i0.ɵɵdefineDirective({ type: BaseGauge, viewQuery: function BaseGauge_Query(rf, ctx) { if (rf & 1) { i0.ɵɵviewQuery(_c0, 7); } if (rf & 2) { let _t; i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.canvas = _t.first); } }, inputs: { options: "options", value: "value" } }); } export { BaseGauge }; (function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(BaseGauge, [{ type: Directive }], function () { return [{ type: i0.ElementRef }, { type: i0.NgZone }]; }, { canvas: [{ type: ViewChild, args: ['gauge', { static: true }] }], options: [{ type: Input }], value: [{ type: Input }] }); })(); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFzZS1nYXVnZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL25nLWNhbnZhcy1nYXVnZXMvc3JjL2xpYi9iYXNlLWdhdWdlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBc0JHO0FBRUgsT0FBTyxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLFVBQVUsRUFBeUIsU0FBUyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3ZHLE9BQU8sS0FBSyxZQUFZLE1BQU0sZUFBZSxDQUFDO0FBQzlDLE9BQU8sS0FBSyxFQUFFLE1BQU0sYUFBYSxDQUFDOzs7QUFJbEMsZUFBZTtBQUNmLE1BQU0sV0FBVyxHQUFHLENBQUMsR0FBVyxFQUFFLEVBQUUsQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLFNBQVMsRUFBRSxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLFdBQVcsRUFBRSxDQUFDLENBQUM7QUFFbkcsTUFBTSxXQUFXLEdBQUcsQ0FBQyxHQUFXLEVBQUUsRUFBRSxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsb0JBQW9CLEVBQUUsT0FBTyxDQUFDLENBQUMsV0FBVyxFQUFFLENBQUM7QUFFOUYsTUFBTSwwQkFBMEIsR0FBRyxDQUFDLFFBQWdCLEVBQUUsRUFBRSxDQUFDLFdBQVcsQ0FBQyxRQUFRLENBQUMsQ0FBQztBQUsvRTs7OztHQUlHO0FBQ0gsTUFDc0IsU0FBUztJQTRDUDtJQUF1QjtJQXpDM0M7O09BRUc7SUFFTyxNQUFNLENBQWE7SUFFN0I7OztPQUdHO0lBQ08sS0FBSyxDQUFJO0lBR25COztPQUVHO0lBQ0ssUUFBUSxHQUFHLEtBQUssQ0FBQztJQUV6Qjs7T0FFRztJQUNLLFlBQVksQ0FBUztJQUU3Qjs7T0FFRztJQUNLLGNBQWMsQ0FBSztJQUczQjs7O09BR0c7SUFDSyxXQUFXLENBQW1CO0lBR3RDOzs7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LFlBQVksQ0FBQztTQUNyQztRQUVELGtDQUFrQztRQUNsQyxJQUFJLENBQUMsT0FBTyxDQUFDLGNBQWMsQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLEVBQUU7WUFDMUQsT0FBTyxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLGFBQWEsQ0FBQztTQUNoRDtRQUVELElBQUksQ0FBQyxXQUFXLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDOUIsQ0FBQztJQUdEOzs7T0FHRztJQUNPLFdBQVcsQ0FBQyxPQUFXO1FBRTdCLDZEQUE2RDtRQUM3RCxnQkFBZ0I7UUFDaEIsSUFBSSxPQUFPLE9BQU8sQ0FBQyxLQUFLLEtBQUssUUFBUSxFQUFFO1lBRW5DLDBEQUEwRDtZQUMxRCxJQUFJLENBQUMsS0FBSyxHQUFHLE9BQU8sQ0FBQyxLQUFLLENBQUM7WUFFM0Isd0RBQXdEO1lBQ3hELHNCQUFzQjtZQUN0QixPQUFPLE9BQU8sQ0FBQyxLQUFLLENBQUM7U0FDeEI7UUFFRCwrQ0FBK0M7UUFDL0MsSUFBSSxNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLE1BQU0sRUFBRTtZQUM3QixJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQztTQUM5QjtJQUNMLENBQUM7bUVBM1BpQixTQUFTOzZEQUFULFNBQVM7Ozs7Ozs7U0FBVCxTQUFTO3VGQUFULFNBQVM7Y0FEOUIsU0FBUztrRkFRSSxNQUFNO2tCQURmLFNBQVM7bUJBQUMsT0FBTyxFQUFFLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRTtZQXVGekIsT0FBTztrQkFEakIsS0FBSztZQWtCSyxLQUFLO2tCQURmLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyIvKiFcclxuICogVGhlIE1JVCBMaWNlbnNlIChNSVQpXHJcbiAqXHJcbiAqIENvcHlyaWdodCAoYykgMjAxNyBWbGFkIE1hcnR5bmVua28gPHZsYWRpbWlyLm1hcnR5bmVua28ud29ya0BnbWFpbC5jb20+XHJcbiAqXHJcbiAqIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhIGNvcHlcclxuICogb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbFxyXG4gKiBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzXHJcbiAqIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGxcclxuICogY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzXHJcbiAqIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6XHJcbiAqXHJcbiAqIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluXHJcbiAqIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxyXG4gKlxyXG4gKiBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SXHJcbiAqIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLFxyXG4gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTiBOTyBFVkVOVCBTSEFMTCBUSEVcclxuICogQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUlxyXG4gKiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLFxyXG4gKiBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRVxyXG4gKiBTT0ZUV0FSRS5cclxuICovXHJcblxyXG5pbXBvcnQgeyBWaWV3Q2hpbGQsIElucHV0LCBOZ1pvbmUsIEVsZW1lbnRSZWYsIE9uSW5pdCwgQWZ0ZXJWaWV3SW5pdCwgRGlyZWN0aXZlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCAqIGFzIENhbnZhc0dhdWdlcyBmcm9tICdjYW52YXMtZ2F1Z2VzJztcclxuaW1wb3J0ICogYXMgUnggZnJvbSAncngtZG9tLWh0bWwnO1xyXG5cclxuXHJcblxyXG4vLyBTdHJpbmcgdXRpbHNcclxuY29uc3QgdG9DYW1lbENhc2UgPSAoc3RyOiBzdHJpbmcpID0+IHN0ci5yZXBsYWNlKC8oXFwtXFx3KS9nLCAobWF0Y2hlcykgPT4gbWF0Y2hlc1sxXS50b1VwcGVyQ2FzZSgpKTtcclxuXHJcbmNvbnN0IHRvS2ViYWJDYXNlID0gKHN0cjogc3RyaW5nKSA9PiBzdHIucmVwbGFjZSgvKFthLXowLTldKShbQS1aXSkvZywgJyQxLSQyJykudG9Mb3dlckNhc2UoKTtcclxuXHJcbmNvbnN0IGF0dHJpYnV0ZU5hbWUyUHJvcGVydHlOYW1lID0gKGF0dHJOYW1lOiBzdHJpbmcpID0+IHRvQ2FtZWxDYXNlKGF0dHJOYW1lKTtcclxuXHJcblxyXG5cclxuXHJcbi8qKlxyXG4gKiBCYXNlIGdhdWdlIGNvbXBvbmVudCBmb3IgdGhlIEdhdWdlcyByZW5kZXJpbmdcclxuICogVCAtIFR5cGUgb2YgdGhlIEdhdWdlIHRvIGJlIHJlbmRlcmVkIChDdXJyZW50bHkgUmFkaWFsR2F1Z2UsIExpbmVhckdhdWdlIGZyb20gdGhlIG9yaWdpbmFsIGxpYnJhcnkpXHJcbiAqIFQyIC0gVHlwZSBvZiBjb25maWcgb3B0aW9ucyB1c2VkIGJ5IHRoZSBwYXJ0aWN1bGFyIGdhdWdlIChSYWRpYWxHYXVnZU9wdGlvbnMsIExpbmVhckdhdWdlT3B0aW9ucylcclxuICovXHJcbkBEaXJlY3RpdmUoKVxyXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgQmFzZUdhdWdlPFQgZXh0ZW5kcyBDYW52YXNHYXVnZXMuQmFzZUdhdWdlLCBUMiBleHRlbmRzIENhbnZhc0dhdWdlcy5HZW5lcmljT3B0aW9ucz5cclxuICAgIGltcGxlbWVudHMgT25Jbml0LCBBZnRlclZpZXdJbml0IHtcclxuXHJcbiAgICAvKipcclxuICAgICAqIENhbnZhcyBlbGVtZW50IG9uIHRoZSB0ZW1wbGF0ZSB1c2VkIGJ5IHRoZSBsaWJyYXJ5IHRvIGRyYXcgZ2F1Z2UgZWxlbWVudFxyXG4gICAgICovXHJcbiAgICBAVmlld0NoaWxkKCdnYXVnZScsIHsgc3RhdGljOiB0cnVlIH0pXHJcbiAgICBwcm90ZWN0ZWQgY2FudmFzOiBFbGVtZW50UmVmO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQSBnYXVnZSBpbnN0YW5jZSByZXNwb25zaWJsZSBmb3IgcmVuZGVyaW5nIGFuZCB1cGRhdGVzIG9uIHRoZSBjYW52YXMuXHJcbiAgICAgKiBTdWJjbGFzc2VzIHNob3VsZCBpbml0aWFsaXplIGluIHRoZWlyIG5nT25Jbml0IGltcGxlbWVudGF0aW9uLlxyXG4gICAgICovXHJcbiAgICBwcm90ZWN0ZWQgZ2F1Z2U6IFQ7XHJcblxyXG5cclxuICAgIC8qKlxyXG4gICAgICogRmxhZyBpbmRpY2F0aW5nIHRoYXQgT25WaWV3SW5pdCBsaWZlLWN5Y2xlIGhhcyBjb21wbGV0ZWRcclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSBpc0luaXRlZCA9IGZhbHNlO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogdmFsdWUgcHJvcGVydHkgb2YgZ2F1Z2UgcHJpb3IgdG8gY29tcG9uZW50IHZpZXcgaW5pdGlhbGl6YXRpb25cclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSBwcmVJbml0VmFsdWU6IG51bWJlcjtcclxuXHJcbiAgICAvKipcclxuICAgICAqIG9wdGlvbnMgcHJvcGVydHkgb2YgZ2F1Z2UgcHJpb3IgdG8gY29tcG9uZW50IHZpZXcgaW5pdGlhbGl6YXRpb25cclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSBwcmVJbml0T3B0aW9uczogVDI7XHJcblxyXG5cclxuICAgIC8qKlxyXG4gICAgICogTGlzdGVuIGZvciBhdHRyaWJ1dGUgY2hhbmdlcywgaS5lLiwgb3B0aW9ucyBwcm9wZXJ0aWVzIHRoYXQgYXJlIHN0b3JlZFxyXG4gICAgICogYXMgYXR0cmlidXRlcyBvbiB0aGlzIEVsZW1lbnRSZWZcclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSBkb21MaXN0ZW5lcjogTXV0YXRpb25PYnNlcnZlcjtcclxuXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIGVsIC0gcmVmZXJlbmNlIHRvIHRoZSBlbGVtZW50IG9mIHRoZSB3aG9sZSBjb21wb25lbnQsIHVzZWQgdG8gc2NyYXBlIG9wdGlvbnMgZGVjbGFyZWQgb24gdGhlIGNvbXBvbmVudCBpdHNlbGZcclxuICAgICAqIEBwYXJhbSB6b25lIC0gcmVxdWlyZWQgdG8gcmVkcmF3IGdhdWdlIG91dHNpZGUgb2YgQW5ndWxhciwgZHVlIHRvIGFuaW1hdGlvbiBsYWdzIGNhdXNlZCBieSB0aGUgb3Zld3JpdHRlbiBmdW5jdGlvbiBvZiB0aGUgbmdab25lXHJcbiAgICAgKi9cclxuICAgIGNvbnN0cnVjdG9yKHByaXZhdGUgZWw6IEVsZW1lbnRSZWYsIHB1YmxpYyB6b25lOiBOZ1pvbmUpIHtcclxuICAgIH1cclxuXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBTdWJjbGFzc2VzIHNob3VsZCBpbnN0YW50aWF0ZSB0aGUgQ2FudmFzR2F1Z2Ugb2JqZWN0IGluIHRoZSBjaGlsZCBjb21wb25lbnRcclxuICAgICAqL1xyXG4gICAgYWJzdHJhY3QgbmdPbkluaXQoKTogdm9pZDtcclxuXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZXR1cm5zIGdhdWdlcyBwcm9wZXJ0aWVzIGFzIGFuIG9wdGlvbnMgb2JqZWN0LlxyXG4gICAgICogT3B0aW9uIHByb3BlcnRpZXMgY29uc2lzdCBvZiB0aGUgYXR0cmlidXRlLWJhc2VkIHByb3BlcnRpZXMgYW5kIHRob3NlXHJcbiAgICAgKiBleHBsaWNpdGx5IHNldC5cclxuICAgICAqIEByZXR1cm5zIDxUMj5cclxuICAgICAqL1xyXG4gICAgcHVibGljIGdldCBvcHRpb25zKCk6IFQyIHtcclxuXHJcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IHt9IGFzIFQyO1xyXG4gICAgICAgIG9wdGlvbnMucmVuZGVyVG8gPSB0aGlzLmNhbnZhcy5uYXRpdmVFbGVtZW50O1xyXG5cclxuICAgICAgICAvLyBNYXAgYXR0cmlidXRlLWJhc2VkIG9wdGlvbnMgb250byBvcHRpb25zLlxyXG4gICAgICAgIC8vIFJlcXVyaWVzIGNvbnZlcnRpbmcga2ViYWIgc3R5bGUgYXR0cmlidXRlIG5hbWVzIHRvIGNhbWVsQ2FzZSBwcm9wZXJ0eSBuYW1lc1xyXG4gICAgICAgIGZvciAoY29uc3QgYXR0ciBvZiB0aGlzLmVsLm5hdGl2ZUVsZW1lbnQuYXR0cmlidXRlcykge1xyXG4gICAgICAgICAgICBjb25zdCBwcm9wID0gYXR0cmlidXRlTmFtZTJQcm9wZXJ0eU5hbWUoYXR0ci5uYW1lKTtcclxuICAgICAgICAgICAgb3B0aW9uc1twcm9wXSA9IENhbnZhc0dhdWdlcy5Eb21PYnNlcnZlci5wYXJzZShhdHRyLnZhbHVlKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIG1lcmdlIHByZU9wdG9ucyB3aXRoIGF0dHJpYnV0ZS1iYXNlZCBwcm9wZXJ0aWVzXHJcbiAgICAgICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOmZvcmluXHJcbiAgICAgICAgZm9yIChjb25zdCBwcm9wIGluIHRoaXMucHJlSW5pdE9wdGlvbnMpIHtcclxuICAgICAgICAgICAgb3B0aW9uc1twcm9wXSA9IHRoaXMucHJlSW5pdE9wdGlvbnNbcHJvcF07XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBjbGVhciB0aGUgcHJlSW5pdE9wdGlvbnMgYXMgdGhleSBoYXZlIGFscmVhZHkgYmVlbiBtZXJnZWRcclxuICAgICAgICAvLyB3aXRoIHRoZSBhdHRyaWJ1dGUtYmFzZWQgcHJvcGVydGllc1xyXG4gICAgICAgIGlmICh0aGlzLmlzSW5pdGVkKSB7XHJcbiAgICAgICAgICAgIHRoaXMucHJlSW5pdE9wdGlvbnMgPSBudWxsO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIG9wdGlvbnM7XHJcbiAgICB9XHJcblxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQXNzaWduIGdhdWdlIG9wdGlvbnMgYXQgYW55dGltZSBpbiB0aGUgbGlmZWN5Y2xlLlxyXG4gICAgICogQHBhcmFtIG5ld09wdGlvbnMgLSBhc3NpZ24gdGhlIHN0eWxlIGFuZCBzaXplIHByb3BlcnRpZXNcclxuICAgICAqL1xyXG4gICAgQElucHV0KClcclxuICAgIHB1YmxpYyBzZXQgb3B0aW9ucyhuZXdPcHRpb25zOiBUMikge1xyXG5cclxuICAgICAgICAvLyBjYWNoZSBuZXdPcHRpb25zIGFzIHByZUluaXRPcHRpb25zIHVudGlsIGdhdWdlIGlzIHJlYWR5XHJcbiAgICAgICAgaWYgKCF0aGlzLmlzSW5pdGVkKSB7XHJcbiAgICAgICAgICAgIHRoaXMucHJlSW5pdE9wdGlvbnMgPSBuZXdPcHRpb25zO1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLnVwZGF0ZShuZXdPcHRpb25zKTtcclxuICAgIH1cclxuXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBBc3NpZ24gdGhlIHZhbHVlIG9mIHRoZSBnYXVnZSB2aXN1YWwgaW5kaWNhdG9yIHN1Y2ggYXMgYSBuZWVkbGUgb3IgcG9pbnRlclxyXG4gICAgICogQHBhcmFtIG5ld1ZhbHVlICB0aGUgZ3VhZ2UgbmV3IHZhbHVlXHJcbiAgICAgKi9cclxuICAgIEBJbnB1dCgpXHJcbiAgICBwdWJsaWMgc2V0IHZhbHVlKG5ld1ZhbHVlOiBudW1iZXIpIHtcclxuXHJcbiAgICAgICAgLy8gY2FzZSBuZXcgZ2F1Z2UgdmFsdWUgYXMgcHJlSW5pdFZhbHVlIHVudGlsIHRoZSBnYXVnZSBpcyByZWFkeVxyXG4gICAgICAgIGlmICghdGhpcy5pc0luaXRlZCkge1xyXG4gICAgICAgICAgICB0aGlzLnByZUluaXRWYWx1ZSA9IG5ld1ZhbHVlO1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLnpvbmUucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4ge1xyXG4gICAgICAgICAgICB0aGlzLmdhdWdlLnZhbHVlID0gbmV3VmFsdWU7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG5cclxuICAgIC8qKlxyXG4gICAgICogVXBkYXRlIHRoZSBnYXVnZSBvcHRpb25zLiBEbyBub3QgdXNlIHVudGlsIGFmdGVyIE9uVmlld0luaXQoKSBiZWZvcmUgdXNpbmcuXHJcbiAgICAgKlxyXG4gICAgICogU3BlY2lhbCBpbXBsZW1lbnRhdGlvbiBub3RlIC0gb3B0aW9ucy5wcm9wZXJ0aWVzIGFyZSBtYWludGFpbmVkIGFzXHJcbiAgICAgKiBhdHRyaWJ1dGUgbmFtZS0+dmFsdWUgb24gdGhpcyBjb21wb25lbnQncyBlbGVtZW50UmVmLiAgVGh1cyB0aGlzIG1ldGhvZFxyXG4gICAgICogbWFwcyBlYWNoIG5ld09wdGlvbnMgcHJvcGVydHkgb250byB0aGUgcHJvcGVydHkncyBjb3JyZXNwb25kaW5nIGF0dHJpYnV0ZS5cclxuICAgICAqIFRoZSBhdHRyaWJ1dGUgdXBkYXRlIHRyaWdnZXJzIGEgRE9NIG11dGF0aW9uIGV2ZW50IHdoaWNoICBcInRoaXNcIiBsaXN0ZW5zIGZvci5cclxuICAgICAqIFNlZSAjbGlzdGVuRm9yRE9NRXZlbnRzKClcclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0gbmV3T3B0aW9ucyAgLSB0aGUgb3B0aW9ucyB0byB1cGRhdGUgdGhlIGdhdWdlXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyB1cGRhdGUobmV3T3B0aW9uczogVDIgfCB7fSkge1xyXG5cclxuICAgICAgICAvLyBtYXAgYWxsIG9wdGlvbnMgb250byB0aGlzIGVsZW1lbnQncyBhdHRyaWJ1dGVzXHJcbiAgICAgICAgLy8gVGhlbiBhdHRyaWJ1dGUgY2hhbmdlcyB3aWxsIGJlIGRldGVjdGVkIGFuZCBwdXNoZWQgdG8gdGhlIGdhdWdlLnVwZGF0ZSgpXHJcbiAgICAgICAgaWYgKCFuZXdPcHRpb25zKSB7IHJldHVybjsgfVxyXG5cclxuICAgICAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6Zm9yaW5cclxuICAgICAgICBmb3IgKGNvbnN0IHByb3AgaW4gbmV3T3B0aW9ucykge1xyXG4gICAgICAgICAgICBjb25zdCB2YWwgPSBuZXdPcHRpb25zW3Byb3BdLnRvU3RyaW5nKCk7XHJcblxyXG4gICAgICAgICAgICBpZiAocHJvcCA9PT0gJ3ZhbHVlJykge1xyXG4gICAgICAgICAgICAgICAgLy8gc2hvcnQgY2lyY3VpdCB0aGUgdmFsdWUgcHJvcGVydHkgdXBkYXRlIGJ5IGNhbGxpbmdcclxuICAgICAgICAgICAgICAgIC8vIHRoZSBnYXVnZS52YWx1ZSBhcGkgZGlyZWN0bHkgZm9yIGVmZmljaWVudCBhbmltYXRlZCB1cGRhdGVcclxuICAgICAgICAgICAgICAgIHRoaXMudmFsdWUgPSBDYW52YXNHYXVnZXMuRG9tT2JzZXJ2ZXIucGFyc2UodmFsKTtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGF0dHJOYW1lID0gdG9LZWJhYkNhc2UocHJvcCk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmVsLm5hdGl2ZUVsZW1lbnQuc2V0QXR0cmlidXRlKGF0dHJOYW1lLCB2YWwpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuXHJcbiAgICAvKipcclxuICAgICAqIFBlcmZvcm0gZ2F1Z2UgaW5pdGlhbGl6YXRpb24uXHJcbiAgICAgKiBTdWJjbGFzc2VzIHRoYXQgb3ZlcnJpZGUgdGhpcyBtZXRob2QgbXVzdCB0aGlzIHN1cGVyIHZlcnNpb25cclxuICAgICAqIGZvciBwcm9wZXIgb3BlcmF0aW9uLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgbmdBZnRlclZpZXdJbml0KCkge1xyXG5cclxuICAgICAgICAvLyBpbml0aWFsIHVwZGF0ZSBvZiBnYXVnZSBwcm9wZXJ0aWVzXHJcbiAgICAgICAgdGhpcy5pbml0R2F1Z2UoKTtcclxuXHJcbiAgICAgICAgdGhpcy5saXN0ZW5Gb3JET01FdmVudHMoKTtcclxuXHJcbiAgICAgICAgdGhpcy5pc0luaXRlZCA9IHRydWU7XHJcbiAgICB9XHJcblxyXG5cclxuICAgIC8qKlxyXG4gICAgICogTGlzdGVuIGZvciBhdHRyaWJ1dGUtY2hhbmdlIGV2ZW50cyB0aGF0IGFyZSBjcmVhdGVkIHdoZW4gdXBkYXRpbmdcclxuICAgICAqIHRoZSBvcHRpb25zIG9mIHRoaXMgZ2F1Z2UuXHJcbiAgICAgKi9cclxuICAgIHByb3RlY3RlZCBsaXN0ZW5Gb3JET01FdmVudHMoKSB7XHJcbiAgICAgICAgLy8gTGlzdGVuIHRvIGdhdWdlIGVsZW1lbnQgZm9yIGF0dHJpYnV0ZSBjaGFuZ2VzXHJcbiAgICAgICAgLy8gQ29udmVydCBhbGwgY2hhbmdlZCBhdHRyaWJ0dWVzIGludG8gYSBHZW5lcmljT3B0aW9ucyBvciBzdWJjbGFzc1xyXG4gICAgICAgIC8vIFVwZGF0ZSB0aGUgZ2F1Z2Ugd2l0aCB0aGUgbmV3IG9wdGlvbnMuXHJcbiAgICAgICAgdGhpcy5kb21MaXN0ZW5lciA9XHJcbiAgICAgICAgICAgIFJ4LkRPTS5mcm9tTXV0YXRpb25PYnNlcnZlcih0aGlzLmVsLm5hdGl2ZUVsZW1lbnQsIHsgYXR0cmlidXRlczogdHJ1ZSB9KS5cclxuICAgICAgICAgICAgICAgIHN1YnNjcmliZShjaGFuZ2VzID0+IHtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCBuZXdPcHRpb25zID0ge30gYXMgVDI7XHJcbiAgICAgICAgICAgICAgICAgICAgY2hhbmdlcy5mb3JFYWNoKGNoYW5nZSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgnYXR0cmlidXRlcycgPT09IGNoYW5nZS50eXBlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBjb25zb2xlLmxvZygnRE9NLCBjaGFuZ2UnLCBjaGFuZ2UuYXR0cmlidXRlTmFtZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdPcHRpb25zW2F0dHJpYnV0ZU5hbWUyUHJvcGVydHlOYW1lKGNoYW5nZS5hdHRyaWJ1dGVOYW1lKV0gPVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENhbnZhc0dhdWdlcy5Eb21PYnNlcnZlci5wYXJzZShcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5lbC5uYXRpdmVFbGVtZW50LmdldEF0dHJpYnV0ZShjaGFuZ2UuYXR0cmlidXRlTmFtZSkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuYmFzaWNVcGRhdGUobmV3T3B0aW9ucyk7XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBEaXNjb250aW51ZSBsaXN0ZW5pbmcgZm9yIGF0dHJpYnV0ZSBjaGFuZ2UgZXZlbnRzLlxyXG4gICAgICovXHJcbiAgICBwcm90ZWN0ZWQgc3RvcExpc3RlbmluZ0ZvckRPTUV2ZW50cygpIHtcclxuICAgICAgICBpZiAodGhpcy5kb21MaXN0ZW5lcikge1xyXG4gICAgICAgICAgICB0aGlzLmRvbUxpc3RlbmVyLmRpc2Nvbm5lY3QoKTtcclxuICAgICAgICAgICAgdGhpcy5kb21MaXN0ZW5lciA9IG51bGw7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuXHJcbiAgICAvKipcclxuICAgICAqIEluaXRhbGl6ZSB0aGUgZ2F1Z2Ugd2l0aCBhbGwgb3B0aW9ucyBkZWZpbmVkIGJ5IGF0dHJpYnV0ZXMgYW5kXHJcbiAgICAgKiBwYXJlbnQgY29tcG9uZW50IG9wdGlvbnMuXHJcbiAgICAgKi9cclxuICAgIHByb3RlY3RlZCBpbml0R2F1Z2UoKSB7XHJcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IHRoaXMub3B0aW9ucztcclxuICAgICAgICBpZiAodGhpcy5wcmVJbml0VmFsdWUpIHtcclxuICAgICAgICAgICAgb3B0aW9ucy52YWx1ZSA9IHRoaXMucHJlSW5pdFZhbHVlO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gaW5pdCBvcHRpb25zLnJlbmRlclRvIGlmIG5lZWRlZFxyXG4gICAgICAgIGlmICghb3B0aW9ucy5oYXNPd25Qcm9wZXJ0eSgncmVuZGVyVG8nKSB8fCAhb3B0aW9ucy5yZW5kZXJUbykge1xyXG4gICAgICAgICAgICBvcHRpb25zLnJlbmRlclRvID0gdGhpcy5jYW52YXMubmF0aXZlRWxlbWVudDtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRoaXMuYmFzaWNVcGRhdGUob3B0aW9ucyk7XHJcbiAgICB9XHJcblxyXG5cclxuICAgIC8qKlxyXG4gICAgICogUGVyZm9ybXMgdGhlIGdhdWdlIHVwZGF0ZSB1c2luZyB0aGUgY3VycmVudCBvcHRpb25zXHJcbiAgICAgKiBAcGFyYW0gb3B0aW9ucyAgVGhlIG9wdGlvbnMgZm9yIHRoZSBndWFnZVxyXG4gICAgICovXHJcbiAgICBwcm90ZWN0ZWQgYmFzaWNVcGRhdGUob3B0aW9uczogVDIpIHtcclxuXHJcbiAgICAgICAgLy8gdHJlYXQgdGhlIHZhbHVlIHByb3BlcnR5IHNwZWNpYWwgYW5kIHVwZGF0ZSBpdCB0aHJvdWdoIHRoZVxyXG4gICAgICAgIC8vIHZhbHVlIGdldHRlci5cclxuICAgICAgICBpZiAodHlwZW9mIG9wdGlvbnMudmFsdWUgPT09ICdudW1iZXInKSB7XHJcblxyXG4gICAgICAgICAgICAvLyB1c2UgZ2F1Z2UgYXBpIGRpcmVjdGx5IGZvciBtb3N0IGVmZmljaWVudCB1cGRhdGUgbWV0aG9kXHJcbiAgICAgICAgICAgIHRoaXMudmFsdWUgPSBvcHRpb25zLnZhbHVlO1xyXG5cclxuICAgICAgICAgICAgLy8gZmlsdGVyIHZhbHVlIHByb3BlcnR5IGZyb20gb3B0aW9ucyB0byBhdm9pZCByZWR1bmRhbnRcclxuICAgICAgICAgICAgLy8gcHJvY2Vzc2luZyBieSBnYXVnZVxyXG4gICAgICAgICAgICBkZWxldGUgb3B0aW9ucy52YWx1ZTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIGRvIG5vdGhpbmcgaWYgbm8gb3B0aW9uIHByb3BlcnRpZXMgdG8gdXBkYXRlXHJcbiAgICAgICAgaWYgKE9iamVjdC5rZXlzKG9wdGlvbnMpLmxlbmd0aCkge1xyXG4gICAgICAgICAgICB0aGlzLmdhdWdlLnVwZGF0ZShvcHRpb25zKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG59XHJcblxyXG5cclxuXHJcbiJdfQ==