UNPKG

ngx-avatar

Version:

A universal avatar component for Angular applications that fetches / generates avatar based on the information you have about the user.

250 lines 27.6 kB
import { Component, Input, Output, EventEmitter } from '@angular/core'; import { AsyncSource } from './sources/async-source'; import { SourceFactory } from './sources/source.factory'; import { AvatarService } from './avatar.service'; import { AvatarSource } from './sources/avatar-source.enum'; import { takeWhile, map } from 'rxjs/operators'; /** * Universal avatar component that * generates avatar from different sources * * export * class AvatarComponent * implements {OnChanges} */ export class AvatarComponent { constructor(sourceFactory, avatarService) { this.sourceFactory = sourceFactory; this.avatarService = avatarService; this.round = true; this.size = 50; this.textSizeRatio = 3; this.fgColor = '#FFF'; this.style = {}; this.cornerRadius = 0; this.initialsSize = 0; this.clickOnAvatar = new EventEmitter(); this.isAlive = true; this.avatarSrc = null; this.avatarText = null; this.avatarStyle = {}; this.hostStyle = {}; this.currentIndex = -1; this.sources = []; } onAvatarClicked() { this.clickOnAvatar.emit(this.sources[this.currentIndex]); } /** * Detect inputs change * * param {{ [propKey: string]: SimpleChange }} changes * * memberof AvatarComponent */ ngOnChanges(changes) { for (const propName in changes) { if (this.avatarService.isSource(propName)) { const sourceType = AvatarSource[propName.toUpperCase()]; const currentValue = changes[propName].currentValue; if (currentValue && typeof currentValue === 'string') { this.addSource(sourceType, currentValue); } else { this.removeSource(sourceType); } } } // reinitialize the avatar component when a source property value has changed // the fallback system must be re-invoked with the new values. this.initializeAvatar(); } /** * Fetch avatar source * * memberOf AvatarComponent */ fetchAvatarSource() { const previousSource = this.sources[this.currentIndex]; if (previousSource) { this.avatarService.markSourceAsFailed(previousSource); } const source = this.findNextSource(); if (!source) { return; } if (this.avatarService.isTextAvatar(source.sourceType)) { this.buildTextAvatar(source); this.avatarSrc = null; } else { this.buildImageAvatar(source); } } findNextSource() { while (++this.currentIndex < this.sources.length) { const source = this.sources[this.currentIndex]; if (source && !this.avatarService.sourceHasFailedBefore(source)) { return source; } } return null; } ngOnDestroy() { this.isAlive = false; } /** * Initialize the avatar component and its fallback system */ initializeAvatar() { this.currentIndex = -1; if (this.sources.length > 0) { this.sortAvatarSources(); this.fetchAvatarSource(); this.hostStyle = { width: this.size + 'px', height: this.size + 'px' }; } } sortAvatarSources() { this.sources.sort((source1, source2) => this.avatarService.compareSources(source1.sourceType, source2.sourceType)); } buildTextAvatar(avatarSource) { this.avatarText = avatarSource.getAvatar(+this.initialsSize); this.avatarStyle = this.getInitialsStyle(avatarSource.sourceId); } buildImageAvatar(avatarSource) { this.avatarStyle = this.getImageStyle(); if (avatarSource instanceof AsyncSource) { this.fetchAndProcessAsyncAvatar(avatarSource); } else { this.avatarSrc = avatarSource.getAvatar(+this.size); } } /** * * returns initials style * * memberOf AvatarComponent */ getInitialsStyle(avatarValue) { return Object.assign({ textAlign: 'center', borderRadius: this.round ? '100%' : this.cornerRadius + 'px', border: this.borderColor ? '1px solid ' + this.borderColor : '', textTransform: 'uppercase', color: this.fgColor, backgroundColor: this.bgColor ? this.bgColor : this.avatarService.getRandomColor(avatarValue), font: Math.floor(+this.size / this.textSizeRatio) + 'px Helvetica, Arial, sans-serif', lineHeight: this.size + 'px' }, this.style); } /** * * returns image style * * memberOf AvatarComponent */ getImageStyle() { return Object.assign({ maxWidth: '100%', borderRadius: this.round ? '50%' : this.cornerRadius + 'px', border: this.borderColor ? '1px solid ' + this.borderColor : '', width: this.size + 'px', height: this.size + 'px' }, this.style); } /** * Fetch avatar image asynchronously. * * param {Source} source represents avatar source * memberof AvatarComponent */ fetchAndProcessAsyncAvatar(source) { if (this.avatarService.sourceHasFailedBefore(source)) { return; } this.avatarService .fetchAvatar(source.getAvatar(+this.size)) .pipe(takeWhile(() => this.isAlive), map(response => source.processResponse(response, +this.size))) .subscribe(avatarSrc => (this.avatarSrc = avatarSrc), err => { this.fetchAvatarSource(); }); } /** * Add avatar source * * param sourceType avatar source type e.g facebook,twitter, etc. * param sourceValue source value e.g facebookId value, etc. */ addSource(sourceType, sourceValue) { const source = this.sources.find(s => s.sourceType === sourceType); if (source) { source.sourceId = sourceValue; } else { this.sources.push(this.sourceFactory.newInstance(sourceType, sourceValue)); } } /** * Remove avatar source * * param sourceType avatar source type e.g facebook,twitter, etc. */ removeSource(sourceType) { this.sources = this.sources.filter(source => source.sourceType !== sourceType); } } AvatarComponent.decorators = [ { type: Component, args: [{ // tslint:disable-next-line:component-selector selector: 'ngx-avatar', template: ` <div (click)="onAvatarClicked()" class="avatar-container" [ngStyle]="hostStyle" > <img *ngIf="avatarSrc; else textAvatar" [src]="avatarSrc" [width]="size" [height]="size" [ngStyle]="avatarStyle" (error)="fetchAvatarSource()" class="avatar-content" loading="lazy" /> <ng-template #textAvatar> <div *ngIf="avatarText" class="avatar-content" [ngStyle]="avatarStyle"> {{ avatarText }} </div> </ng-template> </div> `, styles: [` :host { border-radius: 50%; } `] },] } ]; AvatarComponent.ctorParameters = () => [ { type: SourceFactory }, { type: AvatarService } ]; AvatarComponent.propDecorators = { round: [{ type: Input }], size: [{ type: Input }], textSizeRatio: [{ type: Input }], bgColor: [{ type: Input }], fgColor: [{ type: Input }], borderColor: [{ type: Input }], style: [{ type: Input }], cornerRadius: [{ type: Input }], facebook: [{ type: Input, args: ['facebookId',] }], twitter: [{ type: Input, args: ['twitterId',] }], google: [{ type: Input, args: ['googleId',] }], instagram: [{ type: Input, args: ['instagramId',] }], vkontakte: [{ type: Input, args: ['vkontakteId',] }], skype: [{ type: Input, args: ['skypeId',] }], gravatar: [{ type: Input, args: ['gravatarId',] }], github: [{ type: Input, args: ['githubId',] }], custom: [{ type: Input, args: ['src',] }], initials: [{ type: Input, args: ['name',] }], value: [{ type: Input }], placeholder: [{ type: Input }], initialsSize: [{ type: Input }], clickOnAvatar: [{ type: Output }] }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXZhdGFyLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL25neC1hdmF0YXIvc3JjL2xpYi9hdmF0YXIuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTCxTQUFTLEVBQ1QsS0FBSyxFQUNMLE1BQU0sRUFDTixZQUFZLEVBSWIsTUFBTSxlQUFlLENBQUM7QUFHdkIsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQ3JELE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUN6RCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDakQsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBQzVELE9BQU8sRUFBRSxTQUFTLEVBQUUsR0FBRyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFJaEQ7Ozs7Ozs7R0FPRztBQW9DSCxNQUFNLE9BQU8sZUFBZTtJQXdEMUIsWUFDUyxhQUE0QixFQUMzQixhQUE0QjtRQUQ3QixrQkFBYSxHQUFiLGFBQWEsQ0FBZTtRQUMzQixrQkFBYSxHQUFiLGFBQWEsQ0FBZTtRQXhEL0IsVUFBSyxHQUFHLElBQUksQ0FBQztRQUViLFNBQUksR0FBb0IsRUFBRSxDQUFDO1FBRTNCLGtCQUFhLEdBQUcsQ0FBQyxDQUFDO1FBSWxCLFlBQU8sR0FBRyxNQUFNLENBQUM7UUFJakIsVUFBSyxHQUFVLEVBQUUsQ0FBQztRQUVsQixpQkFBWSxHQUFvQixDQUFDLENBQUM7UUEwQmxDLGlCQUFZLEdBQW9CLENBQUMsQ0FBQztRQUdsQyxrQkFBYSxHQUF5QixJQUFJLFlBQVksRUFBVSxDQUFDO1FBRWpFLFlBQU8sR0FBRyxJQUFJLENBQUM7UUFDZixjQUFTLEdBQWtCLElBQUksQ0FBQztRQUNoQyxlQUFVLEdBQWtCLElBQUksQ0FBQztRQUNqQyxnQkFBVyxHQUFVLEVBQUUs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O29CQWtEbkIsS0FBSzttQkFFTCxLQUFLOzRCQUVMLEtBQUs7c0JBRUwsS0FBSztzQkFFTCxLQUFLOzBCQUVMLEtBQUs7b0JBRUwsS0FBSzsyQkFFTCxLQUFLO3VCQUVMLEtBQUssU0FBQyxZQUFZO3NCQUVsQixLQUFLLFNBQUMsV0FBVztxQkFFakIsS0FBSyxTQUFDLFVBQVU7d0JBRWhCLEtBQUssU0FBQyxhQUFhO3dCQUVuQixLQUFLLFNBQUMsYUFBYTtvQkFFbkIsS0FBSyxTQUFDLFNBQVM7dUJBRWYsS0FBSyxTQUFDLFlBQVk7cUJBRWxCLEtBQUssU0FBQyxVQUFVO3FCQUVoQixLQUFLLFNBQUMsS0FBSzt1QkFFWCxLQUFLLFNBQUMsTUFBTTtvQkFFWixLQUFLOzBCQUVMLEtBQUs7MkJBRUwsS0FBSzs0QkFHTCxNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ29tcG9uZW50LFxuICBJbnB1dCxcbiAgT3V0cHV0LFxuICBFdmVudEVtaXR0ZXIsXG4gIE9uQ2hhbmdlcyxcbiAgU2ltcGxlQ2hhbmdlcyxcbiAgT25EZXN0cm95XG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuXG5pbXBvcnQgeyBTb3VyY2UgfSBmcm9tICcuL3NvdXJjZXMvc291cmNlJztcbmltcG9ydCB7IEFzeW5jU291cmNlIH0gZnJvbSAnLi9zb3VyY2VzL2FzeW5jLXNvdXJjZSc7XG5pbXBvcnQgeyBTb3VyY2VGYWN0b3J5IH0gZnJvbSAnLi9zb3VyY2VzL3NvdXJjZS5mYWN0b3J5JztcbmltcG9ydCB7IEF2YXRhclNlcnZpY2UgfSBmcm9tICcuL2F2YXRhci5zZXJ2aWNlJztcbmltcG9ydCB7IEF2YXRhclNvdXJjZSB9IGZyb20gJy4vc291cmNlcy9hdmF0YXItc291cmNlLmVudW0nO1xuaW1wb3J0IHsgdGFrZVdoaWxlLCBtYXAgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5cbnR5cGUgU3R5bGUgPSBQYXJ0aWFsPENTU1N0eWxlRGVjbGFyYXRpb24+O1xuXG4vKipcbiAqIFVuaXZlcnNhbCBhdmF0YXIgY29tcG9uZW50IHRoYXRcbiAqIGdlbmVyYXRlcyBhdmF0YXIgZnJvbSBkaWZmZXJlbnQgc291cmNlc1xuICpcbiAqIGV4cG9ydFxuICogY2xhc3MgQXZhdGFyQ29tcG9uZW50XG4gKiBpbXBsZW1lbnRzIHtPbkNoYW5nZXN9XG4gKi9cblxuQENvbXBvbmVudCh7XG4gIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpjb21wb25lbnQtc2VsZWN0b3JcbiAgc2VsZWN0b3I6ICduZ3gtYXZhdGFyJyxcbiAgc3R5bGVzOiBbXG4gICAgYFxuICAgICAgOmhvc3Qge1xuICAgICAgICBib3JkZXItcmFkaXVzOiA1MCU7XG4gICAgICB9XG4gICAgYFxuICBdLFxuICB0ZW1wbGF0ZTogYFxuICAgIDxkaXZcbiAgICAgIChjbGljayk9XCJvbkF2YXRhckNsaWNrZWQoKVwiXG4gICAgICBjbGFzcz1cImF2YXRhci1jb250YWluZXJcIlxuICAgICAgW25nU3R5bGVdPVwiaG9zdFN0eWxlXCJcbiAgICA+XG4gICAgICA8aW1nXG4gICAgICAgICpuZ0lmPVwiYXZhdGFyU3JjOyBlbHNlIHRleHRBdmF0YXJcIlxuICAgICAgICBbc3JjXT1cImF2YXRhclNyY1wiXG4gICAgICAgIFt3aWR0aF09XCJzaXplXCJcbiAgICAgICAgW2hlaWdodF09XCJzaXplXCJcbiAgICAgICAgW25nU3R5bGVdPVwiYXZhdGFyU3R5bGVcIlxuICAgICAgICAoZXJyb3IpPVwiZmV0Y2hBdmF0YXJTb3VyY2UoKVwiXG4gICAgICAgIGNsYXNzPVwiYXZhdGFyLWNvbnRlbnRcIlxuICAgICAgICBsb2FkaW5nPVwibGF6eVwiXG4gICAgICAvPlxuICAgICAgPG5nLXRlbXBsYXRlICN0ZXh0QXZhdGFyPlxuICAgICAgICA8ZGl2ICpuZ0lmPVwiYXZhdGFyVGV4dFwiIGNsYXNzPVwiYXZhdGFyLWNvbnRlbnRcIiBbbmdTdHlsZV09XCJhdmF0YXJTdHlsZVwiPlxuICAgICAgICAgIHt7IGF2YXRhclRleHQgfX1cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L25nLXRlbXBsYXRlPlxuICAgIDwvZGl2PlxuICBgXG59KVxuZXhwb3J0IGNsYXNzIEF2YXRhckNvbXBvbmVudCBpbXBsZW1lbnRzIE9uQ2hhbmdlcywgT25EZXN0cm95IHtcbiAgQElucHV0KClcbiAgcHVibGljIHJvdW5kID0gdHJ1ZTtcbiAgQElucHV0KClcbiAgcHVibGljIHNpemU6IHN0cmluZyB8IG51bWJlciA9IDUwO1xuICBASW5wdXQoKVxuICBwdWJsaWMgdGV4dFNpemVSYXRpbyA9IDM7XG4gIEBJbnB1dCgpXG4gIHB1YmxpYyBiZ0NvbG9yOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gIEBJbnB1dCgpXG4gIHB1YmxpYyBmZ0NvbG9yID0gJyNGRkYnO1xuICBASW5wdXQoKVxuICBwdWJsaWMgYm9yZGVyQ29sb3I6IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgQElucHV0KClcbiAgcHVibGljIHN0eWxlOiBTdHlsZSA9IHt9O1xuICBASW5wdXQoKVxuICBwdWJsaWMgY29ybmVyUmFkaXVzOiBzdHJpbmcgfCBudW1iZXIgPSAwO1xuICBASW5wdXQoJ2ZhY2Vib29rSWQnKVxuICBwdWJsaWMgZmFjZWJvb2s/OiBzdHJpbmcgfCBudWxsO1xuICBASW5wdXQoJ3R3aXR0ZXJJZCcpXG4gIHB1YmxpYyB0d2l0dGVyPzogc3RyaW5nIHwgbnVsbDtcbiAgQElucHV0KCdnb29nbGVJZCcpXG4gIHB1YmxpYyBnb29nbGU/OiBzdHJpbmcgfCBudWxsO1xuICBASW5wdXQoJ2luc3RhZ3JhbUlkJylcbiAgcHVibGljIGluc3RhZ3JhbT86IHN0cmluZyB8IG51bGw7XG4gIEBJbnB1dCgndmtvbnRha3RlSWQnKVxuICBwdWJsaWMgdmtvbnRha3RlPzogc3RyaW5nIHwgbnVsbDtcbiAgQElucHV0KCdza3lwZUlkJylcbiAgcHVibGljIHNreXBlPzogc3RyaW5nIHwgbnVsbDtcbiAgQElucHV0KCdncmF2YXRhcklkJylcbiAgcHVibGljIGdyYXZhdGFyPzogc3RyaW5nIHwgbnVsbDtcbiAgQElucHV0KCdnaXRodWJJZCcpXG4gIHB1YmxpYyBnaXRodWI/OiBzdHJpbmcgfCBudWxsO1xuICBASW5wdXQoJ3NyYycpXG4gIHB1YmxpYyBjdXN0b20/OiBzdHJpbmcgfCBudWxsO1xuICBASW5wdXQoJ25hbWUnKVxuICBwdWJsaWMgaW5pdGlhbHM/OiBzdHJpbmcgfCBudWxsO1xuICBASW5wdXQoKVxuICBwdWJsaWMgdmFsdWU/OiBzdHJpbmcgfCBudWxsO1xuICBASW5wdXQoKVxuICBwdWJsaWMgcGxhY2Vob2xkZXI/OiBzdHJpbmc7XG4gIEBJbnB1dCgpXG4gIHB1YmxpYyBpbml0aWFsc1NpemU6IHN0cmluZyB8IG51bWJlciA9IDA7XG5cbiAgQE91dHB1dCgpXG4gIHB1YmxpYyBjbGlja09uQXZhdGFyOiBFdmVudEVtaXR0ZXI8U291cmNlPiA9IG5ldyBFdmVudEVtaXR0ZXI8U291cmNlPigpO1xuXG4gIHB1YmxpYyBpc0FsaXZlID0gdHJ1ZTtcbiAgcHVibGljIGF2YXRhclNyYzogc3RyaW5nIHwgbnVsbCA9IG51bGw7XG4gIHB1YmxpYyBhdmF0YXJUZXh0OiBzdHJpbmcgfCBudWxsID0gbnVsbDtcbiAgcHVibGljIGF2YXRhclN0eWxlOiBTdHlsZSA9IHt9O1xuICBwdWJsaWMgaG9zdFN0eWxlOiBTdHlsZSA9IHt9O1xuXG4gIHByaXZhdGUgY3VycmVudEluZGV4ID0gLTE7XG4gIHByaXZhdGUgc291cmNlczogU291cmNlW10gPSBbXTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwdWJsaWMgc291cmNlRmFjdG9yeTogU291cmNlRmFjdG9yeSxcbiAgICBwcml2YXRlIGF2YXRhclNlcnZpY2U6IEF2YXRhclNlcnZpY2VcbiAgKSB7fVxuXG4gIHB1YmxpYyBvbkF2YXRhckNsaWNrZWQoKTogdm9pZCB7XG4gICAgdGhpcy5jbGlja09uQXZhdGFyLmVtaXQodGhpcy5zb3VyY2VzW3RoaXMuY3VycmVudEluZGV4XSk7XG4gIH1cblxuICAvKipcbiAgICogRGV0ZWN0IGlucHV0cyBjaGFuZ2VcbiAgICpcbiAgICogcGFyYW0ge3sgW3Byb3BLZXk6IHN0cmluZ106IFNpbXBsZUNoYW5nZSB9fSBjaGFuZ2VzXG4gICAqXG4gICAqIG1lbWJlcm9mIEF2YXRhckNvbXBvbmVudFxuICAgKi9cbiAgcHVibGljIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpOiB2b2lkIHtcbiAgICBmb3IgKGNvbnN0IHByb3BOYW1lIGluIGNoYW5nZXMpIHtcbiAgICAgIGlmICh0aGlzLmF2YXRhclNlcnZpY2UuaXNTb3VyY2UocHJvcE5hbWUpKSB7XG4gICAgICAgIGNvbnN0IHNvdXJjZVR5cGU6IEF2YXRhclNvdXJjZSA9IEF2YXRhclNvdXJjZVtwcm9wTmFtZS50b1VwcGVyQ2FzZSgpIGFzIGtleW9mIHR5cGVvZiBBdmF0YXJTb3VyY2VdIDtcbiAgICAgICAgY29uc3QgY3VycmVudFZhbHVlID0gY2hhbmdlc1twcm9wTmFtZV0uY3VycmVudFZhbHVlO1xuICAgICAgICBpZiAoY3VycmVudFZhbHVlICYmIHR5cGVvZiBjdXJyZW50VmFsdWUgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgdGhpcy5hZGRTb3VyY2Uoc291cmNlVHlwZSwgY3VycmVudFZhbHVlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLnJlbW92ZVNvdXJjZShzb3VyY2VUeXBlKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICAvLyByZWluaXRpYWxpemUgdGhlIGF2YXRhciBjb21wb25lbnQgd2hlbiBhIHNvdXJjZSBwcm9wZXJ0eSB2YWx1ZSBoYXMgY2hhbmdlZFxuICAgIC8vIHRoZSBmYWxsYmFjayBzeXN0ZW0gbXVzdCBiZSByZS1pbnZva2VkIHdpdGggdGhlIG5ldyB2YWx1ZXMuXG4gICAgdGhpcy5pbml0aWFsaXplQXZhdGFyKCk7XG4gIH1cblxuICAvKipcbiAgICogRmV0Y2ggYXZhdGFyIHNvdXJjZVxuICAgKlxuICAgKiBtZW1iZXJPZiBBdmF0YXJDb21wb25lbnRcbiAgICovXG4gIHB1YmxpYyBmZXRjaEF2YXRhclNvdXJjZSgpOiB2b2lkIHtcbiAgICBjb25zdCBwcmV2aW91c1NvdXJjZSA9IHRoaXMuc291cmNlc1t0aGlzLmN1cnJlbnRJbmRleF07XG4gICAgaWYgKHByZXZpb3VzU291cmNlKSB7XG4gICAgICB0aGlzLmF2YXRhclNlcnZpY2UubWFya1NvdXJjZUFzRmFpbGVkKHByZXZpb3VzU291cmNlKTtcbiAgICB9XG5cbiAgICBjb25zdCBzb3VyY2UgPSB0aGlzLmZpbmROZXh0U291cmNlKCk7XG4gICAgaWYgKCFzb3VyY2UpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5hdmF0YXJTZXJ2aWNlLmlzVGV4dEF2YXRhcihzb3VyY2Uuc291cmNlVHlwZSkpIHtcbiAgICAgIHRoaXMuYnVpbGRUZXh0QXZhdGFyKHNvdXJjZSk7XG4gICAgICB0aGlzLmF2YXRhclNyYyA9IG51bGw7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuYnVpbGRJbWFnZUF2YXRhcihzb3VyY2UpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgZmluZE5leHRTb3VyY2UoKTogU291cmNlIHwgbnVsbCB7XG4gICAgd2hpbGUgKCsrdGhpcy5jdXJyZW50SW5kZXggPCB0aGlzLnNvdXJjZXMubGVuZ3RoKSB7XG4gICAgICBjb25zdCBzb3VyY2UgPSB0aGlzLnNvdXJjZXNbdGhpcy5jdXJyZW50SW5kZXhdO1xuICAgICAgaWYgKHNvdXJjZSAmJiAhdGhpcy5hdmF0YXJTZXJ2aWNlLnNvdXJjZUhhc0ZhaWxlZEJlZm9yZShzb3VyY2UpKSB7XG4gICAgICAgIHJldHVybiBzb3VyY2U7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBwdWJsaWMgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy5pc0FsaXZlID0gZmFsc2U7XG4gIH1cblxuICAvKipcbiAgICogSW5pdGlhbGl6ZSB0aGUgYXZhdGFyIGNvbXBvbmVudCBhbmQgaXRzIGZhbGxiYWNrIHN5c3RlbVxuICAgKi9cbiAgcHJpdmF0ZSBpbml0aWFsaXplQXZhdGFyKCk6IHZvaWQge1xuICAgIHRoaXMuY3VycmVudEluZGV4ID0gLTE7XG4gICAgaWYgKHRoaXMuc291cmNlcy5sZW5ndGggPiAwKSB7XG4gICAgICB0aGlzLnNvcnRBdmF0YXJTb3VyY2VzKCk7XG4gICAgICB0aGlzLmZldGNoQXZhdGFyU291cmNlKCk7XG4gICAgICB0aGlzLmhvc3RTdHlsZSA9IHtcbiAgICAgICAgd2lkdGg6IHRoaXMuc2l6ZSArICdweCcsXG4gICAgICAgIGhlaWdodDogdGhpcy5zaXplICsgJ3B4J1xuICAgICAgfTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHNvcnRBdmF0YXJTb3VyY2VzKCk6IHZvaWQge1xuICAgIHRoaXMuc291cmNlcy5zb3J0KChzb3VyY2UxLCBzb3VyY2UyKSA9PlxuICAgICAgdGhpcy5hdmF0YXJTZXJ2aWNlLmNvbXBhcmVTb3VyY2VzKHNvdXJjZTEuc291cmNlVHlwZSwgc291cmNlMi5zb3VyY2VUeXBlKVxuICAgICk7XG4gIH1cblxuICBwcml2YXRlIGJ1aWxkVGV4dEF2YXRhcihhdmF0YXJTb3VyY2U6IFNvdXJjZSk6IHZvaWQge1xuICAgIHRoaXMuYXZhdGFyVGV4dCA9IGF2YXRhclNvdXJjZS5nZXRBdmF0YXIoK3RoaXMuaW5pdGlhbHNTaXplKTtcbiAgICB0aGlzLmF2YXRhclN0eWxlID0gdGhpcy5nZXRJbml0aWFsc1N0eWxlKGF2YXRhclNvdXJjZS5zb3VyY2VJZCk7XG4gIH1cblxuICBwcml2YXRlIGJ1aWxkSW1hZ2VBdmF0YXIoYXZhdGFyU291cmNlOiBTb3VyY2UpOiB2b2lkIHtcbiAgICB0aGlzLmF2YXRhclN0eWxlID0gdGhpcy5nZXRJbWFnZVN0eWxlKCk7XG4gICAgaWYgKGF2YXRhclNvdXJjZSBpbnN0YW5jZW9mIEFzeW5jU291cmNlKSB7XG4gICAgICB0aGlzLmZldGNoQW5kUHJvY2Vzc0FzeW5jQXZhdGFyKGF2YXRhclNvdXJjZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuYXZhdGFyU3JjID0gYXZhdGFyU291cmNlLmdldEF2YXRhcigrdGhpcy5zaXplKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICpcbiAgICogcmV0dXJucyBpbml0aWFscyBzdHlsZVxuICAgKlxuICAgKiBtZW1iZXJPZiBBdmF0YXJDb21wb25lbnRcbiAgICovXG4gIHByaXZhdGUgZ2V0SW5pdGlhbHNTdHlsZShhdmF0YXJWYWx1ZTogc3RyaW5nKTogU3R5bGUge1xuICAgIHJldHVybiB7XG4gICAgICB0ZXh0QWxpZ246ICdjZW50ZXInLFxuICAgICAgYm9yZGVyUmFkaXVzOiB0aGlzLnJvdW5kID8gJzEwMCUnIDogdGhpcy5jb3JuZXJSYWRpdXMgKyAncHgnLFxuICAgICAgYm9yZGVyOiB0aGlzLmJvcmRlckNvbG9yID8gJzFweCBzb2xpZCAnICsgdGhpcy5ib3JkZXJDb2xvciA6ICcnLFxuICAgICAgdGV4dFRyYW5zZm9ybTogJ3VwcGVyY2FzZScsXG4gICAgICBjb2xvcjogdGhpcy5mZ0NvbG9yLFxuICAgICAgYmFja2dyb3VuZENvbG9yOiB0aGlzLmJnQ29sb3JcbiAgICAgICAgPyB0aGlzLmJnQ29sb3JcbiAgICAgICAgOiB0aGlzLmF2YXRhclNlcnZpY2UuZ2V0UmFuZG9tQ29sb3IoYXZhdGFyVmFsdWUpLFxuICAgICAgZm9udDpcbiAgICAgICAgTWF0aC5mbG9vcigrdGhpcy5zaXplIC8gdGhpcy50ZXh0U2l6ZVJhdGlvKSArXG4gICAgICAgICdweCBIZWx2ZXRpY2EsIEFyaWFsLCBzYW5zLXNlcmlmJyxcbiAgICAgIGxpbmVIZWlnaHQ6IHRoaXMuc2l6ZSArICdweCcsXG4gICAgICAuLi50aGlzLnN0eWxlXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKlxuICAgKiByZXR1cm5zIGltYWdlIHN0eWxlXG4gICAqXG4gICAqIG1lbWJlck9mIEF2YXRhckNvbXBvbmVudFxuICAgKi9cbiAgcHJpdmF0ZSBnZXRJbWFnZVN0eWxlKCk6IFN0eWxlIHtcbiAgICByZXR1cm4ge1xuICAgICAgbWF4V2lkdGg6ICcxMDAlJyxcbiAgICAgIGJvcmRlclJhZGl1czogdGhpcy5yb3VuZCA/ICc1MCUnIDogdGhpcy5jb3JuZXJSYWRpdXMgKyAncHgnLFxuICAgICAgYm9yZGVyOiB0aGlzLmJvcmRlckNvbG9yID8gJzFweCBzb2xpZCAnICsgdGhpcy5ib3JkZXJDb2xvciA6ICcnLFxuICAgICAgd2lkdGg6IHRoaXMuc2l6ZSArICdweCcsXG4gICAgICBoZWlnaHQ6IHRoaXMuc2l6ZSArICdweCcsXG4gICAgICAuLi50aGlzLnN0eWxlLFxuICAgIH07XG4gIH1cbiAgLyoqXG4gICAqIEZldGNoIGF2YXRhciBpbWFnZSBhc3luY2hyb25vdXNseS5cbiAgICpcbiAgICogcGFyYW0ge1NvdXJjZX0gc291cmNlIHJlcHJlc2VudHMgYXZhdGFyIHNvdXJjZVxuICAgKiBtZW1iZXJvZiBBdmF0YXJDb21wb25lbnRcbiAgICovXG4gIHByaXZhdGUgZmV0Y2hBbmRQcm9jZXNzQXN5bmNBdmF0YXIoc291cmNlOiBBc3luY1NvdXJjZSk6IHZvaWQge1xuICAgIGlmICh0aGlzLmF2YXRhclNlcnZpY2Uuc291cmNlSGFzRmFpbGVkQmVmb3JlKHNvdXJjZSkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLmF2YXRhclNlcnZpY2VcbiAgICAgICAgLmZldGNoQXZhdGFyKHNvdXJjZS5nZXRBdmF0YXIoK3RoaXMuc2l6ZSkpXG4gICAgICAgIC5waXBlKFxuICAgICAgICAgICAgdGFrZVdoaWxlKCgpID0+IHRoaXMuaXNBbGl2ZSksXG4gICAgICAgICAgICBtYXAocmVzcG9uc2UgPT4gc291cmNlLnByb2Nlc3NSZXNwb25zZShyZXNwb25zZSwgK3RoaXMuc2l6ZSkpLFxuICAgICAgICApXG4gICAgICAgIC5zdWJzY3JpYmUoXG4gICAgICAgICAgICBhdmF0YXJTcmMgPT4gKHRoaXMuYXZhdGFyU3JjID0gYXZhdGFyU3JjKSxcbiAgICAgICAgICAgIGVyciA9PiB7XG4gICAgICAgICAgICAgIHRoaXMuZmV0Y2hBdmF0YXJTb3VyY2UoKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICk7XG4gIH1cblxuICAvKipcbiAgICogQWRkIGF2YXRhciBzb3VyY2VcbiAgICpcbiAgICogcGFyYW0gc291cmNlVHlwZSBhdmF0YXIgc291cmNlIHR5cGUgZS5nIGZhY2Vib29rLHR3aXR0ZXIsIGV0Yy5cbiAgICogcGFyYW0gc291cmNlVmFsdWUgIHNvdXJjZSB2YWx1ZSBlLmcgZmFjZWJvb2tJZCB2YWx1ZSwgZXRjLlxuICAgKi9cbiAgcHJpdmF0ZSBhZGRTb3VyY2Uoc291cmNlVHlwZTogQXZhdGFyU291cmNlLCBzb3VyY2VWYWx1ZTogc3RyaW5nKTogdm9pZCB7XG4gICAgY29uc3Qgc291cmNlID0gdGhpcy5zb3VyY2VzLmZpbmQocyA9PiBzLnNvdXJjZVR5cGUgPT09IHNvdXJjZVR5cGUpO1xuICAgIGlmIChzb3VyY2UpIHtcbiAgICAgIHNvdXJjZS5zb3VyY2VJZCA9IHNvdXJjZVZhbHVlO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnNvdXJjZXMucHVzaChcbiAgICAgICAgICB0aGlzLnNvdXJjZUZhY3RvcnkubmV3SW5zdGFuY2Uoc291cmNlVHlwZSwgc291cmNlVmFsdWUpLFxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUmVtb3ZlIGF2YXRhciBzb3VyY2VcbiAgICpcbiAgICogcGFyYW0gc291cmNlVHlwZSBhdmF0YXIgc291cmNlIHR5cGUgZS5nIGZhY2Vib29rLHR3aXR0ZXIsIGV0Yy5cbiAgICovXG4gIHByaXZhdGUgcmVtb3ZlU291cmNlKHNvdXJjZVR5cGU6IEF2YXRhclNvdXJjZSk6IHZvaWQge1xuICAgIHRoaXMuc291cmNlcyA9IHRoaXMuc291cmNlcy5maWx0ZXIoc291cmNlID0+IHNvdXJjZS5zb3VyY2VUeXBlICE9PSBzb3VyY2VUeXBlKTtcbiAgfVxufVxuIl19