UNPKG

@visa/nova-angular

Version:

Visa Product Design System Nova Angular library

182 lines 23.9 kB
/** * Copyright (c) 2025 Visa, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * **/ import { coerceBooleanProperty, coerceNumberProperty } from '@angular/cdk/coercion'; import { CommonModule } from '@angular/common'; import { Component, computed, ContentChild, ElementRef, HostBinding, Input, signal, ViewChild } from '@angular/core'; import { AppReadyService } from '../_utilities/services/app-stable-check.service'; import { LabelDirective } from '../label/label.directive'; import * as i0 from "@angular/core"; import * as i1 from "../_utilities/services/app-stable-check.service"; import * as i2 from "@angular/common"; export class CircularProgressComponent { get hostClasses() { return [ this.class, 'v-progress', 'v-progress-circular', this.determinate ? '' : 'v-progress-indeterminate', this.small ? 'v-progress-circular-small' : '', this.determinate && this.percentage === 100 ? 'v-progress-complete' : '', this.invalid ? 'v-progress-error' : '' ].join(' '); } /** * Sets progress to determinate when true. * @default false */ get determinate() { return this._determinate; } set determinate(value) { this._determinate = coerceBooleanProperty(value); } /** * Sets progress to invalid when true. * @default false */ get invalid() { return this._invalid; } set invalid(value) { this._invalid = coerceBooleanProperty(value); } get hostRole() { // If role is set, use it if (this.role) { return this.role; } if (this._determinate) { return 'progressbar'; } return null; } /** * Sets the percentage for a <code>determinate</code> circular progress. * @default 0 */ get percentage() { return this._percentage; } set percentage(value) { this._percentage = coerceNumberProperty(value); this._percentageSignal.set(coerceNumberProperty(value)); } /** * Sets progress to small variant when true. * @default false */ get small() { return this._small; } set small(value) { this._small = coerceBooleanProperty(value); } get hostAriaLabelledby() { return this.ariaLabelledby; } constructor(appReadyService) { this.appReadyService = appReadyService; this._percentageSignal = signal(this.percentage); this._initialSize = signal(0); // circumference this._dashOffset = computed(() => { if (this._initialSize() > 0) { return this._initialSize() - this._initialSize() * (this._percentageSignal() * 0.01); } else return 0; }); /** * Provides custom class&#40;es&#41; for custom styling. * @default .v-progress.v-progress-circular */ this.class = ''; this._determinate = false; this._invalid = false; /** * Sets custom role. * @default 'progressbar' when determinate * @default null when indeterminate * @builtin true */ this.role = null; this._percentage = 0; this._small = false; } ngAfterContentInit() { if (this.label) { this.label.progressLabel = true; if (!this.ariaLabelledby && this.label.id) { this.ariaLabelledby = this.label.id; } } } ngAfterViewInit() { if (this.progressBar) { let radius; // default in case isPlatformBrowser fails // best guess of radius if radius is not available // by default, small size is 24 // by default, regular size is 48 const defaultSize = this.small ? 48 : 72; setTimeout(() => { // .getPropertyValue('r') not working outside of setTimeout if (this.appReadyService.checkIsPlatformBrowser()) { radius = parseInt(window.getComputedStyle(this.progressBar.nativeElement).getPropertyValue('r')); } // by default, radius is half of the default size minus 4 - the stroke width radius = isNaN(radius) ? (defaultSize - 4) / 2 : radius; this._initialSize.set(2 * Math.PI * radius); }, 0); } } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: CircularProgressComponent, deps: [{ token: i1.AppReadyService }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: CircularProgressComponent, isStandalone: true, selector: "[v-progress-circular], [v-circular-progress]", inputs: { class: "class", determinate: "determinate", invalid: "invalid", role: "role", percentage: "percentage", small: "small", ariaLabelledby: ["aria-labelledby", "ariaLabelledby"] }, host: { properties: { "class": "this.hostClasses", "attr.role": "this.hostRole", "attr.aria-labelledby": "this.hostAriaLabelledby" } }, queries: [{ propertyName: "label", first: true, predicate: LabelDirective, descendants: true }], viewQueries: [{ propertyName: "progressBar", first: true, predicate: ["progressBar"], descendants: true }], ngImport: i0, template: "<!--\n * Copyright (c) 2025 Visa, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n -->\n<svg\n class=\"v-progress-circular-track\"\n [ngClass]=\"{\n 'v-progress-complete': determinate && percentage === 100,\n}\"\n>\n <circle class=\"v-progress-circular-background\">\n </circle>\n <circle\n class=\"v-progress-circular-bar\"\n [style.stroke-dasharray]=\"determinate ? _initialSize() : null\"\n [style.stroke-dashoffset]=\"determinate ? _dashOffset() : null\"\n #progressBar\n >\n </circle>\n</svg>\n<ng-content></ng-content>", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: CircularProgressComponent, decorators: [{ type: Component, args: [{ standalone: true, imports: [CommonModule], selector: '[v-progress-circular], [v-circular-progress]', template: "<!--\n * Copyright (c) 2025 Visa, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n -->\n<svg\n class=\"v-progress-circular-track\"\n [ngClass]=\"{\n 'v-progress-complete': determinate && percentage === 100,\n}\"\n>\n <circle class=\"v-progress-circular-background\">\n </circle>\n <circle\n class=\"v-progress-circular-bar\"\n [style.stroke-dasharray]=\"determinate ? _initialSize() : null\"\n [style.stroke-dashoffset]=\"determinate ? _dashOffset() : null\"\n #progressBar\n >\n </circle>\n</svg>\n<ng-content></ng-content>" }] }], ctorParameters: () => [{ type: i1.AppReadyService }], propDecorators: { progressBar: [{ type: ViewChild, args: ['progressBar', { static: false }] }], label: [{ type: ContentChild, args: [LabelDirective] }], class: [{ type: Input }], hostClasses: [{ type: HostBinding, args: ['class'] }], determinate: [{ type: Input }], invalid: [{ type: Input }], role: [{ type: Input }], hostRole: [{ type: HostBinding, args: ['attr.role'] }], percentage: [{ type: Input }], small: [{ type: Input }], ariaLabelledby: [{ type: Input, args: ['aria-labelledby'] }], hostAriaLabelledby: [{ type: HostBinding, args: ['attr.aria-labelledby'] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2lyY3VsYXItcHJvZ3Jlc3MuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vbGlicy9ub3ZhLWxpYi9zcmMvbGliL2NpcmN1bGFyLXByb2dyZXNzL2NpcmN1bGFyLXByb2dyZXNzLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL2xpYnMvbm92YS1saWIvc3JjL2xpYi9jaXJjdWxhci1wcm9ncmVzcy9jaXJjdWxhci1wcm9ncmVzcy5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7O0lBZUk7QUFDSixPQUFPLEVBQWdCLHFCQUFxQixFQUFFLG9CQUFvQixFQUFlLE1BQU0sdUJBQXVCLENBQUM7QUFDL0csT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQy9DLE9BQU8sRUFHTCxTQUFTLEVBQ1QsUUFBUSxFQUNSLFlBQVksRUFDWixVQUFVLEVBQ1YsV0FBVyxFQUNYLEtBQUssRUFDTCxNQUFNLEVBQ04sU0FBUyxFQUNWLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxpREFBaUQsQ0FBQztBQUNsRixPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sMEJBQTBCLENBQUM7Ozs7QUFRMUQsTUFBTSxPQUFPLHlCQUF5QjtJQWlCcEMsSUFDSSxXQUFXO1FBQ2IsT0FBTztZQUNMLElBQUksQ0FBQyxLQUFLO1lBQ1YsWUFBWTtZQUNaLHFCQUFxQjtZQUNyQixJQUFJLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLDBCQUEwQjtZQUNsRCxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQywyQkFBMkIsQ0FBQyxDQUFDLENBQUMsRUFBRTtZQUM3QyxJQUFJLENBQUMsV0FBVyxJQUFJLElBQUksQ0FBQyxVQUFVLEtBQUssR0FBRyxDQUFDLENBQUMsQ0FBQyxxQkFB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eUJBQXlCO2tCQU5yQyxTQUFTO2lDQUNJLElBQUksV0FDUCxDQUFDLFlBQVksQ0FBQyxZQUNiLDhDQUE4QztvRkFZWCxXQUFXO3NCQUF2RCxTQUFTO3VCQUFDLGFBQWEsRUFBRSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUU7Z0JBQ2IsS0FBSztzQkFBbEMsWUFBWTt1QkFBQyxjQUFjO2dCQU1uQixLQUFLO3NCQUFiLEtBQUs7Z0JBRUYsV0FBVztzQkFEZCxXQUFXO3VCQUFDLE9BQU87Z0JBa0JoQixXQUFXO3NCQURkLEtBQUs7Z0JBY0YsT0FBTztzQkFEVixLQUFLO2dCQWVHLElBQUk7c0JBQVosS0FBSztnQkFFRixRQUFRO3NCQURYLFdBQVc7dUJBQUMsV0FBVztnQkFpQnBCLFVBQVU7c0JBRGIsS0FBSztnQkFlRixLQUFLO3NCQURSLEtBQUs7Z0JBY29CLGNBQWM7c0JBQXZDLEtBQUs7dUJBQUMsaUJBQWlCO2dCQUVwQixrQkFBa0I7c0JBRHJCLFdBQVc7dUJBQUMsc0JBQXNCIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiAgICAgICAgICAgICAgQ29weXJpZ2h0IChjKSAyMDI1IFZpc2EsIEluYy5cbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICAgICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqKi9cbmltcG9ydCB7IEJvb2xlYW5JbnB1dCwgY29lcmNlQm9vbGVhblByb3BlcnR5LCBjb2VyY2VOdW1iZXJQcm9wZXJ0eSwgTnVtYmVySW5wdXQgfSBmcm9tICdAYW5ndWxhci9jZGsvY29lcmNpb24nO1xuaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7XG4gIEFmdGVyQ29udGVudEluaXQsXG4gIEFmdGVyVmlld0luaXQsXG4gIENvbXBvbmVudCxcbiAgY29tcHV0ZWQsXG4gIENvbnRlbnRDaGlsZCxcbiAgRWxlbWVudFJlZixcbiAgSG9zdEJpbmRpbmcsXG4gIElucHV0LFxuICBzaWduYWwsXG4gIFZpZXdDaGlsZFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEFwcFJlYWR5U2VydmljZSB9IGZyb20gJy4uL191dGlsaXRpZXMvc2VydmljZXMvYXBwLXN0YWJsZS1jaGVjay5zZXJ2aWNlJztcbmltcG9ydCB7IExhYmVsRGlyZWN0aXZlIH0gZnJvbSAnLi4vbGFiZWwvbGFiZWwuZGlyZWN0aXZlJztcblxuQENvbXBvbmVudCh7XG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGltcG9ydHM6IFtDb21tb25Nb2R1bGVdLFxuICBzZWxlY3RvcjogJ1t2LXByb2dyZXNzLWNpcmN1bGFyXSwgW3YtY2lyY3VsYXItcHJvZ3Jlc3NdJyxcbiAgdGVtcGxhdGVVcmw6ICcuL2NpcmN1bGFyLXByb2dyZXNzLmNvbXBvbmVudC5odG1sJ1xufSlcbmV4cG9ydCBjbGFzcyBDaXJjdWxhclByb2dyZXNzQ29tcG9uZW50IGltcGxlbWVudHMgQWZ0ZXJDb250ZW50SW5pdCwgQWZ0ZXJWaWV3SW5pdCB7XG4gIF9wZXJjZW50YWdlU2lnbmFsID0gc2lnbmFsKHRoaXMucGVyY2VudGFnZSk7XG4gIF9pbml0aWFsU2l6ZSA9IHNpZ25hbCgwKTsgLy8gY2lyY3VtZmVyZW5jZVxuICBfZGFzaE9mZnNldCA9IGNvbXB1dGVkKCgpID0+IHtcbiAgICBpZiAodGhpcy5faW5pdGlhbFNpemUoKSA+IDApIHtcbiAgICAgIHJldHVybiB0aGlzLl9pbml0aWFsU2l6ZSgpIC0gdGhpcy5faW5pdGlhbFNpemUoKSAqICh0aGlzLl9wZXJjZW50YWdlU2lnbmFsKCkgKiAwLjAxKTtcbiAgICB9IGVsc2UgcmV0dXJuIDA7XG4gIH0pO1xuXG4gIEBWaWV3Q2hpbGQoJ3Byb2dyZXNzQmFyJywgeyBzdGF0aWM6IGZhbHNlIH0pIHByb2dyZXNzQmFyOiBFbGVtZW50UmVmO1xuICBAQ29udGVudENoaWxkKExhYmVsRGlyZWN0aXZlKSBsYWJlbDogTGFiZWxEaXJlY3RpdmU7XG5cbiAgLyoqXG4gICAqIFByb3ZpZGVzIGN1c3RvbSBjbGFzcyYjNDA7ZXMmIzQxOyBmb3IgY3VzdG9tIHN0eWxpbmcuXG4gICAqIEBkZWZhdWx0IC52LXByb2dyZXNzLnYtcHJvZ3Jlc3MtY2lyY3VsYXJcbiAgICovXG4gIEBJbnB1dCgpIGNsYXNzOiBzdHJpbmcgPSAnJztcbiAgQEhvc3RCaW5kaW5nKCdjbGFzcycpXG4gIGdldCBob3N0Q2xhc3NlcygpOiBzdHJpbmcge1xuICAgIHJldHVybiBbXG4gICAgICB0aGlzLmNsYXNzLFxuICAgICAgJ3YtcHJvZ3Jlc3MnLFxuICAgICAgJ3YtcHJvZ3Jlc3MtY2lyY3VsYXInLFxuICAgICAgdGhpcy5kZXRlcm1pbmF0ZSA/ICcnIDogJ3YtcHJvZ3Jlc3MtaW5kZXRlcm1pbmF0ZScsXG4gICAgICB0aGlzLnNtYWxsID8gJ3YtcHJvZ3Jlc3MtY2lyY3VsYXItc21hbGwnIDogJycsXG4gICAgICB0aGlzLmRldGVybWluYXRlICYmIHRoaXMucGVyY2VudGFnZSA9PT0gMTAwID8gJ3YtcHJvZ3Jlc3MtY29tcGxldGUnIDogJycsXG4gICAgICB0aGlzLmludmFsaWQgPyAndi1wcm9ncmVzcy1lcnJvcicgOiAnJ1xuICAgIF0uam9pbignICcpO1xuICB9XG5cbiAgLyoqXG4gICAqIFNldHMgcHJvZ3Jlc3MgdG8gZGV0ZXJtaW5hdGUgd2hlbiB0cnVlLlxuICAgKiBAZGVmYXVsdCBmYWxzZVxuICAgKi9cbiAgQElucHV0KClcbiAgZ2V0IGRldGVybWluYXRlKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLl9kZXRlcm1pbmF0ZTtcbiAgfVxuICBzZXQgZGV0ZXJtaW5hdGUodmFsdWU6IEJvb2xlYW5JbnB1dCkge1xuICAgIHRoaXMuX2RldGVybWluYXRlID0gY29lcmNlQm9vbGVhblByb3BlcnR5KHZhbHVlKTtcbiAgfVxuICBfZGV0ZXJtaW5hdGU6IGJvb2xlYW4gPSBmYWxzZTtcblxuICAvKipcbiAgICogU2V0cyBwcm9ncmVzcyB0byBpbnZhbGlkIHdoZW4gdHJ1ZS5cbiAgICogQGRlZmF1bHQgZmFsc2VcbiAgICovXG4gIEBJbnB1dCgpXG4gIGdldCBpbnZhbGlkKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLl9pbnZhbGlkO1xuICB9XG4gIHNldCBpbnZhbGlkKHZhbHVlOiBCb29sZWFuSW5wdXQpIHtcbiAgICB0aGlzLl9pbnZhbGlkID0gY29lcmNlQm9vbGVhblByb3BlcnR5KHZhbHVlKTtcbiAgfVxuICBfaW52YWxpZDogYm9vbGVhbiA9IGZhbHNlO1xuXG4gIC8qKlxuICAgKiBTZXRzIGN1c3RvbSByb2xlLlxuICAgKiBAZGVmYXVsdCAncHJvZ3Jlc3NiYXInIHdoZW4gZGV0ZXJtaW5hdGVcbiAgICogQGRlZmF1bHQgbnVsbCB3aGVuIGluZGV0ZXJtaW5hdGVcbiAgICogQGJ1aWx0aW4gdHJ1ZVxuICAgKi9cbiAgQElucHV0KCkgcm9sZTogc3RyaW5nIHwgdm9pZCB8IG51bGwgPSBudWxsO1xuICBASG9zdEJpbmRpbmcoJ2F0dHIucm9sZScpXG4gIGdldCBob3N0Um9sZSgpOiBzdHJpbmcgfCB2b2lkIHwgbnVsbCB7XG4gICAgLy8gSWYgcm9sZSBpcyBzZXQsIHVzZSBpdFxuICAgIGlmICh0aGlzLnJvbGUpIHtcbiAgICAgIHJldHVybiB0aGlzLnJvbGU7XG4gICAgfVxuICAgIGlmICh0aGlzLl9kZXRlcm1pbmF0ZSkge1xuICAgICAgcmV0dXJuICdwcm9ncmVzc2Jhcic7XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgLyoqXG4gICAqIFNldHMgdGhlIHBlcmNlbnRhZ2UgZm9yIGEgPGNvZGU+ZGV0ZXJtaW5hdGU8L2NvZGU+IGNpcmN1bGFyIHByb2dyZXNzLlxuICAgKiBAZGVmYXVsdCAwXG4gICAqL1xuICBASW5wdXQoKVxuICBnZXQgcGVyY2VudGFnZSgpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLl9wZXJjZW50YWdlO1xuICB9XG4gIHNldCBwZXJjZW50YWdlKHZhbHVlOiBOdW1iZXJJbnB1dCkge1xuICAgIHRoaXMuX3BlcmNlbnRhZ2UgPSBjb2VyY2VOdW1iZXJQcm9wZXJ0eSh2YWx1ZSk7XG4gICAgdGhpcy5fcGVyY2VudGFnZVNpZ25hbC5zZXQoY29lcmNlTnVtYmVyUHJvcGVydHkodmFsdWUpKTtcbiAgfVxuICBfcGVyY2VudGFnZTogbnVtYmVyID0gMDtcblxuICAvKipcbiAgICogU2V0cyBwcm9ncmVzcyB0byBzbWFsbCB2YXJpYW50IHdoZW4gdHJ1ZS5cbiAgICogQGRlZmF1bHQgZmFsc2VcbiAgICovXG4gIEBJbnB1dCgpXG4gIGdldCBzbWFsbCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5fc21hbGw7XG4gIH1cbiAgc2V0IHNtYWxsKHZhbHVlOiBCb29sZWFuSW5wdXQpIHtcbiAgICB0aGlzLl9zbWFsbCA9IGNvZXJjZUJvb2xlYW5Qcm9wZXJ0eSh2YWx1ZSk7XG4gIH1cbiAgX3NtYWxsOiBib29sZWFuID0gZmFsc2U7XG5cbiAgLyoqXG4gICAqIEFyaWEgYXR0cmlidXRlIHBvaW50aW5nIHRvIGlkIG9mIGxhYmVsbGluZyBlbGVtZW50LlxuICAgKiBAZGVmYXVsdCAmbHQ7Y2hpbGQtbGFiZWwtaWQmZ3Q7XG4gICAqIEBidWlsdGluIHRydWVcbiAgICovXG4gIEBJbnB1dCgnYXJpYS1sYWJlbGxlZGJ5JykgYXJpYUxhYmVsbGVkYnk6IHN0cmluZztcbiAgQEhvc3RCaW5kaW5nKCdhdHRyLmFyaWEtbGFiZWxsZWRieScpXG4gIGdldCBob3N0QXJpYUxhYmVsbGVkYnkoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5hcmlhTGFiZWxsZWRieTtcbiAgfVxuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgYXBwUmVhZHlTZXJ2aWNlOiBBcHBSZWFkeVNlcnZpY2UpIHt9XG5cbiAgbmdBZnRlckNvbnRlbnRJbml0KCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmxhYmVsKSB7XG4gICAgICB0aGlzLmxhYmVsLnByb2dyZXNzTGFiZWwgPSB0cnVlO1xuXG4gICAgICBpZiAoIXRoaXMuYXJpYUxhYmVsbGVkYnkgJiYgdGhpcy5sYWJlbC5pZCkge1xuICAgICAgICB0aGlzLmFyaWFMYWJlbGxlZGJ5ID0gdGhpcy5sYWJlbC5pZDtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBuZ0FmdGVyVmlld0luaXQoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMucHJvZ3Jlc3NCYXIpIHtcbiAgICAgIGxldCByYWRpdXM6IG51bWJlcjsgLy8gZGVmYXVsdCBpbiBjYXNlIGlzUGxhdGZvcm1Ccm93c2VyIGZhaWxzXG4gICAgICAvLyBiZXN0IGd1ZXNzIG9mIHJhZGl1cyBpZiByYWRpdXMgaXMgbm90IGF2YWlsYWJsZVxuICAgICAgLy8gYnkgZGVmYXVsdCwgc21hbGwgc2l6ZSBpcyAyNFxuICAgICAgLy8gYnkgZGVmYXVsdCwgcmVndWxhciBzaXplIGlzIDQ4XG4gICAgICBjb25zdCBkZWZhdWx0U2l6ZSA9IHRoaXMuc21hbGwgPyA0OCA6IDcyO1xuICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgIC8vIC5nZXRQcm9wZXJ0eVZhbHVlKCdyJykgbm90IHdvcmtpbmcgb3V0c2lkZSBvZiBzZXRUaW1lb3V0XG4gICAgICAgIGlmICh0aGlzLmFwcFJlYWR5U2VydmljZS5jaGVja0lzUGxhdGZvcm1Ccm93c2VyKCkpIHtcbiAgICAgICAgICByYWRpdXMgPSBwYXJzZUludCh3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZSh0aGlzLnByb2dyZXNzQmFyLm5hdGl2ZUVsZW1lbnQpLmdldFByb3BlcnR5VmFsdWUoJ3InKSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gYnkgZGVmYXVsdCwgcmFkaXVzIGlzIGhhbGYgb2YgdGhlIGRlZmF1bHQgc2l6ZSBtaW51cyA0IC0gdGhlIHN0cm9rZSB3aWR0aFxuICAgICAgICByYWRpdXMgPSBpc05hTihyYWRpdXMpID8gKGRlZmF1bHRTaXplIC0gNCkgLyAyIDogcmFkaXVzO1xuICAgICAgICB0aGlzLl9pbml0aWFsU2l6ZS5zZXQoMiAqIE1hdGguUEkgKiByYWRpdXMpO1xuICAgICAgfSwgMCk7XG4gICAgfVxuICB9XG59XG4iLCI8IS0tXG4gKiAgICAgICAgICAgICAgQ29weXJpZ2h0IChjKSAyMDI1IFZpc2EsIEluYy5cbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICAgICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAtLT5cbjxzdmdcbiAgY2xhc3M9XCJ2LXByb2dyZXNzLWNpcmN1bGFyLXRyYWNrXCJcbiAgW25nQ2xhc3NdPVwie1xuICAndi1wcm9ncmVzcy1jb21wbGV0ZSc6IGRldGVybWluYXRlICYmIHBlcmNlbnRhZ2UgPT09IDEwMCxcbn1cIlxuPlxuICA8Y2lyY2xlIGNsYXNzPVwidi1wcm9ncmVzcy1jaXJjdWxhci1iYWNrZ3JvdW5kXCI+XG4gIDwvY2lyY2xlPlxuICA8Y2lyY2xlXG4gICAgY2xhc3M9XCJ2LXByb2dyZXNzLWNpcmN1bGFyLWJhclwiXG4gICAgW3N0eWxlLnN0cm9rZS1kYXNoYXJyYXldPVwiZGV0ZXJtaW5hdGUgPyBfaW5pdGlhbFNpemUoKSA6IG51bGxcIlxuICAgIFtzdHlsZS5zdHJva2UtZGFzaG9mZnNldF09XCJkZXRlcm1pbmF0ZSA/IF9kYXNoT2Zmc2V0KCkgOiBudWxsXCJcbiAgICAjcHJvZ3Jlc3NCYXJcbiAgPlxuICA8L2NpcmNsZT5cbjwvc3ZnPlxuPG5nLWNvbnRlbnQ+PC9uZy1jb250ZW50PiJdfQ==