UNPKG

ngx-stars

Version:
172 lines 28.1 kB
import { Component, EventEmitter, Input, Output } from '@angular/core'; export class NgxStarsComponent { constructor() { this.maxStars = 5; this.initialStars = 0; this.animationSpeed = 100; this.wholeStars = false; this.ratingOutput = new EventEmitter(); this.customClassIdentifier = Math.random().toString(36).substring(2); this.safeSize = () => (Number.isInteger(this.size) && this.size > 0 && this.size < 6) ? this.size : 1; } ngOnInit() { this.setupStarImages(); this.editableStars = Array.from(new Array(this.maxStars)).map((elem, index) => new EditableStar(index)); this.setRating(this.initialStars); if (this.animation) { this.animationInterval = setInterval(this.starAnimation.bind(this), this.animationSpeed); } } ngOnDestroy() { // remove the three custom classes we created if custom image urls were provided if (this.customCssClasses) { this.customCssClasses.forEach(style => { if (style && style.parentNode) { style.parentNode.removeChild(style); } }); } } setupStarImages() { if (this.customStarIcons) { this.customCssClasses = []; Object.keys(this.customStarIcons).map(key => key).forEach(starType => { const classname = this.getStarClass(starType); this.createCssClass(classname, starType); }); } } createCssClass(classname, starType) { const clazz = document.createElement('style'); clazz.type = 'text/css'; clazz.innerHTML = `.${classname} { -webkit-mask-image: url(${this.customStarIcons[starType]}); mask-image: url(${this.customStarIcons[starType]}); }`; document.getElementsByTagName('head')[0].appendChild(clazz); this.customCssClasses.push(clazz); } starPadding() { return { 'margin-right': this.customPadding || `calc(${this.starSize().width} / 10)` }; } starColorAndSize() { return Object.assign({}, this.starColor(), this.starSize()); } starColor() { return { 'background-color': this.color || 'crimson' }; } starSize() { return { height: this.customSize || `${15 * this.safeSize()}px`, width: this.customSize || `${16 * this.safeSize()}px`, }; } starAnimation() { this.animationRunning = true; if (this.rating < this.maxStars) { this.setRating(this.rating += 0.5); } else { this.setRating(0); } } cancelStarAnimation() { if (this.animationRunning) { clearInterval(this.animationInterval); this.rating = 0; this.animationRunning = false; } } setRating(rating) { this.rating = Math.round(rating * 2) / 2; this.onStarsUnhover(); } onStarHover(event, clickedStar) { this.cancelStarAnimation(); const clickedInFirstHalf = this.clickedInFirstHalf(event); // fill in either a half or whole star depending on where user clicked clickedStar.classname = (!this.wholeStars && clickedInFirstHalf) ? this.getStarClass('half') : this.getStarClass('full'); // fill in all stars in previous positions and clear all in later ones this.editableStars.forEach(star => { if (star.position > clickedStar.position) { star.classname = this.getStarClass('empty'); } else if (star.position < clickedStar.position) { star.classname = this.getStarClass('full'); } }); } onStarClick(event, clickedStar) { this.cancelStarAnimation(); // lock in current rating const clickedInFirstHalf = this.clickedInFirstHalf(event); this.rating = clickedStar.position + ((!this.wholeStars && clickedInFirstHalf) ? 0.5 : 1); this.ratingOutput.emit(this.rating); } // hidden star to left of first star lets user click there to set to 0 onZeroStarClick() { this.setRating(0); this.ratingOutput.emit(this.rating); } onZeroStarHover() { // clear all stars this.editableStars.forEach(star => star.classname = this.getStarClass('empty')); } onStarsUnhover() { // when user stops hovering we want to make stars reflect the last rating applied by clicking this.editableStars.forEach(star => { const starNumber = star.position + 1; if (this.rating >= starNumber) { star.classname = this.getStarClass('full'); } else if (this.rating > starNumber - 1 && this.rating < starNumber) { star.classname = this.getStarClass('half'); } else { star.classname = this.getStarClass('empty'); } }); } clickedInFirstHalf(event) { const starIcon = event.target; return event.pageX < starIcon.getBoundingClientRect().left + starIcon.offsetWidth / 2; } noop() { } getStarClass(starType) { if (this.customCssClasses) { return `ngx-stars-star-${starType}-${this.customClassIdentifier}`; } return `star-${starType}`; } // this and the aria-labels and role in the html inspired by https://stackoverflow.com/q/55966205 getAriaLabel() { return `Rating: ${this.rating} out of ${this.maxStars} stars ${this.readonly ? '' : '. Can be edited.'}`; } } NgxStarsComponent.decorators = [ { type: Component, args: [{ selector: 'ngx-stars', template: "<div class=\"stars-line\" (mouseleave)=\"readonly ? noop() : onStarsUnhover()\" role=\"img\" [attr.aria-label]=\"getAriaLabel()\">\n <span class=\"star zero-star\" [ngStyle]=\"starSize()\" aria-hidden=\"true\" (click)=\"onZeroStarClick()\" (mousemove)=\"readonly ? noop() : onZeroStarHover()\"></span>\n <div *ngFor=\"let star of editableStars;\" [ngStyle]=\"starPadding()\" aria-hidden=\"true\" (click)=\"readonly ? noop() : onStarClick($event, star)\" (mousemove)=\"readonly ? noop() : onStarHover($event, star)\">\n <span class=\"star\" [ngClass]=\"star.classname\" [ngStyle]=\"starColorAndSize()\" aria-hidden=\"true\"></span>\n </div>\n</div>\n", styles: [".stars-line{display:flex;align-items:center;position:relative}.stars-line>div{z-index:999}.zero-star{color:transparent;position:absolute;left:-16px}.star{display:inline-block;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat}.star-empty{-webkit-mask-image:url(\"data:image/svg+xml,%3Csvg aria-hidden='true' focusable='false' data-prefix='far' data-icon='star' class='svg-inline--fa fa-star fa-w-18' role='img' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 576 512'%3E%3Cpath fill='currentColor' d='M528.1 171.5L382 150.2 316.7 17.8c-11.7-23.6-45.6-23.9-57.4 0L194 150.2 47.9 171.5c-26.2 3.8-36.7 36.1-17.7 54.6l105.7 103-25 145.5c-4.5 26.3 23.2 46 46.4 33.7L288 439.6l130.7 68.7c23.2 12.2 50.9-7.4 46.4-33.7l-25-145.5 105.7-103c19-18.5 8.5-50.8-17.7-54.6zM388.6 312.3l23.7 138.4L288 385.4l-124.3 65.3 23.7-138.4-100.6-98 139-20.2 62.2-126 62.2 126 139 20.2-100.6 98z'%3E%3C/path%3E%3C/svg%3E%0A\");mask-image:url(\"data:image/svg+xml,%3Csvg aria-hidden='true' focusable='false' data-prefix='far' data-icon='star' class='svg-inline--fa fa-star fa-w-18' role='img' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 576 512'%3E%3Cpath fill='currentColor' d='M528.1 171.5L382 150.2 316.7 17.8c-11.7-23.6-45.6-23.9-57.4 0L194 150.2 47.9 171.5c-26.2 3.8-36.7 36.1-17.7 54.6l105.7 103-25 145.5c-4.5 26.3 23.2 46 46.4 33.7L288 439.6l130.7 68.7c23.2 12.2 50.9-7.4 46.4-33.7l-25-145.5 105.7-103c19-18.5 8.5-50.8-17.7-54.6zM388.6 312.3l23.7 138.4L288 385.4l-124.3 65.3 23.7-138.4-100.6-98 139-20.2 62.2-126 62.2 126 139 20.2-100.6 98z'%3E%3C/path%3E%3C/svg%3E%0A\")}.star-half{-webkit-mask-image:url(\"data:image/svg+xml,%3C!-- had to hack this one's viewbox otherwise it didn't line up with the other two --%3E%3C!-- changed viewbox from '0 0 536 512' to '-20 0 576 512' --%3E%3Csvg aria-hidden='true' focusable='false' data-prefix='fas' data-icon='star-half-alt' class='svg-inline--fa fa-star-half-alt fa-w-17' role='img' xmlns='http://www.w3.org/2000/svg' viewBox='-20 0 576 512'%3E%3Cpath fill='currentColor' d='M508.55 171.51L362.18 150.2 296.77 17.81C290.89 5.98 279.42 0 267.95 0c-11.4 0-22.79 5.9-28.69 17.81l-65.43 132.38-146.38 21.29c-26.25 3.8-36.77 36.09-17.74 54.59l105.89 103-25.06 145.48C86.98 495.33 103.57 512 122.15 512c4.93 0 10-1.17 14.87-3.75l130.95-68.68 130.94 68.7c4.86 2.55 9.92 3.71 14.83 3.71 18.6 0 35.22-16.61 31.66-37.4l-25.03-145.49 105.91-102.98c19.04-18.5 8.52-50.8-17.73-54.6zm-121.74 123.2l-18.12 17.62 4.28 24.88 19.52 113.45-102.13-53.59-22.38-11.74.03-317.19 51.03 103.29 11.18 22.63 25.01 3.64 114.23 16.63-82.65 80.38z'%3E%3C/path%3E%3C/svg%3E\");mask-image:url(\"data:image/svg+xml,%3C!-- had to hack this one's viewbox otherwise it didn't line up with the other two --%3E%3C!-- changed viewbox from '0 0 536 512' to '-20 0 576 512' --%3E%3Csvg aria-hidden='true' focusable='false' data-prefix='fas' data-icon='star-half-alt' class='svg-inline--fa fa-star-half-alt fa-w-17' role='img' xmlns='http://www.w3.org/2000/svg' viewBox='-20 0 576 512'%3E%3Cpath fill='currentColor' d='M508.55 171.51L362.18 150.2 296.77 17.81C290.89 5.98 279.42 0 267.95 0c-11.4 0-22.79 5.9-28.69 17.81l-65.43 132.38-146.38 21.29c-26.25 3.8-36.77 36.09-17.74 54.59l105.89 103-25.06 145.48C86.98 495.33 103.57 512 122.15 512c4.93 0 10-1.17 14.87-3.75l130.95-68.68 130.94 68.7c4.86 2.55 9.92 3.71 14.83 3.71 18.6 0 35.22-16.61 31.66-37.4l-25.03-145.49 105.91-102.98c19.04-18.5 8.52-50.8-17.73-54.6zm-121.74 123.2l-18.12 17.62 4.28 24.88 19.52 113.45-102.13-53.59-22.38-11.74.03-317.19 51.03 103.29 11.18 22.63 25.01 3.64 114.23 16.63-82.65 80.38z'%3E%3C/path%3E%3C/svg%3E\")}.star-full{-webkit-mask-image:url(\"data:image/svg+xml,%3Csvg aria-hidden='true' focusable='false' data-prefix='fas' data-icon='star' class='svg-inline--fa fa-star fa-w-18' role='img' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 576 512'%3E%3Cpath fill='currentColor' d='M259.3 17.8L194 150.2 47.9 171.5c-26.2 3.8-36.7 36.1-17.7 54.6l105.7 103-25 145.5c-4.5 26.3 23.2 46 46.4 33.7L288 439.6l130.7 68.7c23.2 12.2 50.9-7.4 46.4-33.7l-25-145.5 105.7-103c19-18.5 8.5-50.8-17.7-54.6L382 150.2 316.7 17.8c-11.7-23.6-45.6-23.9-57.4 0z'%3E%3C/path%3E%3C/svg%3E\");mask-image:url(\"data:image/svg+xml,%3Csvg aria-hidden='true' focusable='false' data-prefix='fas' data-icon='star' class='svg-inline--fa fa-star fa-w-18' role='img' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 576 512'%3E%3Cpath fill='currentColor' d='M259.3 17.8L194 150.2 47.9 171.5c-26.2 3.8-36.7 36.1-17.7 54.6l105.7 103-25 145.5c-4.5 26.3 23.2 46 46.4 33.7L288 439.6l130.7 68.7c23.2 12.2 50.9-7.4 46.4-33.7l-25-145.5 105.7-103c19-18.5 8.5-50.8-17.7-54.6L382 150.2 316.7 17.8c-11.7-23.6-45.6-23.9-57.4 0z'%3E%3C/path%3E%3C/svg%3E\")}"] },] } ]; NgxStarsComponent.propDecorators = { maxStars: [{ type: Input }], initialStars: [{ type: Input }], readonly: [{ type: Input }], size: [{ type: Input }], customSize: [{ type: Input }], color: [{ type: Input }], animation: [{ type: Input }], animationSpeed: [{ type: Input }], customPadding: [{ type: Input }], wholeStars: [{ type: Input }], customStarIcons: [{ type: Input }], ratingOutput: [{ type: Output }] }; export class EditableStar { constructor(position) { this.position = position; } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmd4LXN0YXJzLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL25neC1zdGFycy9zcmMvbGliL25neC1zdGFycy5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxZQUFZLEVBQUUsS0FBSyxFQUFxQixNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFPMUYsTUFBTSxPQUFPLGlCQUFpQjtJQUw5QjtRQVFFLGFBQVEsR0FBVyxDQUFDLENBQUM7UUFHckIsaUJBQVksR0FBVyxDQUFDLENBQUM7UUFrQnpCLG1CQUFjLEdBQVcsR0FBRyxDQUFDO1FBTTdCLGVBQVUsR0FBWSxLQUFLLENBQUM7UUFNNUIsaUJBQVksR0FBeUIsSUFBSSxZQUFZLEVBQUUsQ0FBQztRQVFoRCwwQkFBcUIsR0FBRyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQStEaEUsYUFBUSxHQUFHLEdBQUcsRUFBRSxDQUFDLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksSUFBSSxDQUFDLElBQUksR0FBRyxDQUFDLElBQUksSUFBSSxDQUFDLElBQUksR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBa0czRyxDQUFDO0lBL0pDLFFBQVE7UUFDTixJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7UUFDdkIsSUFBSSxDQUFDLGFBQWEsR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksS0FBSyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksRUFBRSxLQUFLLEVBQUUsRUFBRSxDQUFDLElBQUksWUFBWSxDQUFDLEtB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QUFFLENBQUM7SUFDM0csQ0FBQzs7O1lBak5GLFNBQVMsU0FBQztnQkFDVCxRQUFRLEVBQUUsV0FBVztnQkFDckIsMnBCQUF5Qzs7YUFFMUM7Ozt1QkFHRSxLQUFLOzJCQUdMLEtBQUs7dUJBR0wsS0FBSzttQkFHTCxLQUFLO3lCQUdMLEtBQUs7b0JBR0wsS0FBSzt3QkFHTCxLQUFLOzZCQUdMLEtBQUs7NEJBR0wsS0FBSzt5QkFHTCxLQUFLOzhCQUdMLEtBQUs7MkJBR0wsTUFBTTs7QUE4S1QsTUFBTSxPQUFPLFlBQVk7SUFJdkIsWUFBWSxRQUFnQjtRQUMxQixJQUFJLENBQUMsUUFBUSxHQUFHLFFBQVEsQ0FBQztJQUMzQixDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIEV2ZW50RW1pdHRlciwgSW5wdXQsIE9uRGVzdHJveSwgT25Jbml0LCBPdXRwdXQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnbmd4LXN0YXJzJyxcbiAgdGVtcGxhdGVVcmw6ICcuL25neC1zdGFycy5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWyAnLi9uZ3gtc3RhcnMuY29tcG9uZW50LmNzcycgXSxcbn0pXG5leHBvcnQgY2xhc3MgTmd4U3RhcnNDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIE9uRGVzdHJveSB7XG5cbiAgQElucHV0KClcbiAgbWF4U3RhcnM6IG51bWJlciA9IDU7XG5cbiAgQElucHV0KClcbiAgaW5pdGlhbFN0YXJzOiBudW1iZXIgPSAwO1xuXG4gIEBJbnB1dCgpXG4gIHJlYWRvbmx5OiBib29sZWFuO1xuXG4gIEBJbnB1dCgpXG4gIHNpemU6IG51bWJlcjtcblxuICBASW5wdXQoKVxuICBjdXN0b21TaXplOiBzdHJpbmc7XG5cbiAgQElucHV0KClcbiAgY29sb3I6IHN0cmluZztcblxuICBASW5wdXQoKVxuICBhbmltYXRpb246IGJvb2xlYW47XG5cbiAgQElucHV0KClcbiAgYW5pbWF0aW9uU3BlZWQ6IG51bWJlciA9IDEwMDtcblxuICBASW5wdXQoKVxuICBjdXN0b21QYWRkaW5nOiBzdHJpbmc7XG5cbiAgQElucHV0KClcbiAgd2hvbGVTdGFyczogYm9vbGVhbiA9IGZhbHNlO1xuXG4gIEBJbnB1dCgpXG4gIGN1c3RvbVN0YXJJY29uczogeyBlbXB0eTogc3RyaW5nLCBoYWxmOiBzdHJpbmcsIGZ1bGw6IHN0cmluZyB9O1xuXG4gIEBPdXRwdXQoKVxuICByYXRpbmdPdXRwdXQ6IEV2ZW50RW1pdHRlcjxudW1iZXI+ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuXG4gIHJhdGluZzogbnVtYmVyO1xuICBlZGl0YWJsZVN0YXJzOiBFZGl0YWJsZVN0YXJbXTtcbiAgYW5pbWF0aW9uSW50ZXJ2YWw6IGFueTtcbiAgYW5pbWF0aW9uUnVubmluZzogYm9vbGVhbjtcblxuICBwcml2YXRlIGN1c3RvbUNzc0NsYXNzZXM6IEhUTUxTdHlsZUVsZW1lbnRbXTtcbiAgcHJpdmF0ZSBjdXN0b21DbGFzc0lkZW50aWZpZXIgPSBNYXRoLnJhbmRvbSgpLnRvU3RyaW5nKDM2KS5zdWJzdHJpbmcoMik7XG5cbiAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgdGhpcy5zZXR1cFN0YXJJbWFnZXMoKTtcbiAgICB0aGlzLmVkaXRhYmxlU3RhcnMgPSBBcnJheS5mcm9tKG5ldyBBcnJheSh0aGlzLm1heFN0YXJzKSkubWFwKChlbGVtLCBpbmRleCkgPT4gbmV3IEVkaXRhYmxlU3RhcihpbmRleCkpO1xuICAgIHRoaXMuc2V0UmF0aW5nKHRoaXMuaW5pdGlhbFN0YXJzKTtcblxuICAgIGlmICh0aGlzLmFuaW1hdGlvbikge1xuICAgICAgdGhpcy5hbmltYXRpb25JbnRlcnZhbCA9IHNldEludGVydmFsKHRoaXMuc3RhckFuaW1hdGlvbi5iaW5kKHRoaXMpLCB0aGlzLmFuaW1hdGlvblNwZWVkKTtcbiAgICB9XG4gIH1cblxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICAvLyByZW1vdmUgdGhlIHRocmVlIGN1c3RvbSBjbGFzc2VzIHdlIGNyZWF0ZWQgaWYgY3VzdG9tIGltYWdlIHVybHMgd2VyZSBwcm92aWRlZFxuICAgIGlmICh0aGlzLmN1c3RvbUNzc0NsYXNzZXMpIHtcbiAgICAgIHRoaXMuY3VzdG9tQ3NzQ2xhc3Nlcy5mb3JFYWNoKHN0eWxlID0+IHtcbiAgICAgICAgaWYgKHN0eWxlICYmIHN0eWxlLnBhcmVudE5vZGUpIHtcbiAgICAgICAgICBzdHlsZS5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKHN0eWxlKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBzZXR1cFN0YXJJbWFnZXMoKSB7XG4gICAgaWYgKHRoaXMuY3VzdG9tU3Rhckljb25zKSB7XG4gICAgICB0aGlzLmN1c3RvbUNzc0NsYXNzZXMgPSBbXTtcbiAgICAgIE9iamVjdC5rZXlzKHRoaXMuY3VzdG9tU3Rhckljb25zKS5tYXAoa2V5ID0+IGtleSBhcyBTdGFyVHlwZSkuZm9yRWFjaChzdGFyVHlwZSA9PiB7XG4gICAgICAgIGNvbnN0IGNsYXNzbmFtZSA9IHRoaXMuZ2V0U3RhckNsYXNzKHN0YXJUeXBlKTtcbiAgICAgICAgdGhpcy5jcmVhdGVDc3NDbGFzcyhjbGFzc25hbWUsIHN0YXJUeXBlKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlQ3NzQ2xhc3MoY2xhc3NuYW1lOiBzdHJpbmcsIHN0YXJUeXBlOiBTdGFyVHlwZSkge1xuICAgIGNvbnN0IGNsYXp6ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc3R5bGUnKTtcbiAgICBjbGF6ei50eXBlID0gJ3RleHQvY3NzJztcbiAgICBjbGF6ei5pbm5lckhUTUwgPSBgLiR7Y2xhc3NuYW1lfSB7XG4gICAgICAtd2Via2l0LW1hc2staW1hZ2U6IHVybCgke3RoaXMuY3VzdG9tU3Rhckljb25zW3N0YXJUeXBlXX0pO1xuICAgICAgbWFzay1pbWFnZTogdXJsKCR7dGhpcy5jdXN0b21TdGFySWNvbnNbc3RhclR5cGVdfSk7XG4gICAgfWA7XG4gICAgZG9jdW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoJ2hlYWQnKVswXS5hcHBlbmRDaGlsZChjbGF6eik7XG4gICAgdGhpcy5jdXN0b21Dc3NDbGFzc2VzLnB1c2goY2xhenopO1xuICB9XG5cbiAgc3RhclBhZGRpbmcoKTogeyBbcDogc3RyaW5nXTogc3RyaW5nIH0ge1xuICAgIHJldHVybiB7ICdtYXJnaW4tcmlnaHQnOiB0aGlzLmN1c3RvbVBhZGRpbmcgfHwgYGNhbGMoJHt0aGlzLnN0YXJTaXplKCkud2lkdGh9IC8gMTApYCB9O1xuICB9XG5cbiAgc3RhckNvbG9yQW5kU2l6ZSgpOiB7IFtwOiBzdHJpbmddOiBzdHJpbmcgfSB7XG4gICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe30sIHRoaXMuc3RhckNvbG9yKCksIHRoaXMuc3RhclNpemUoKSk7XG4gIH1cblxuICBwcml2YXRlIHN0YXJDb2xvcigpOiB7IFtwOiBzdHJpbmddOiBzdHJpbmcgfSB7XG4gICAgcmV0dXJuIHsgJ2JhY2tncm91bmQtY29sb3InOiB0aGlzLmNvbG9yIHx8ICdjcmltc29uJyB9O1xuICB9XG5cbiAgc3RhclNpemUoKTogeyBbcDogc3RyaW5nXTogc3RyaW5nIH0ge1xuICAgIHJldHVybiB7XG4gICAgICBoZWlnaHQ6IHRoaXMuY3VzdG9tU2l6ZSB8fCBgJHsxNSAqIHRoaXMuc2FmZVNpemUoKX1weGAsXG4gICAgICB3aWR0aDogdGhpcy5jdXN0b21TaXplIHx8IGAkezE2ICogdGhpcy5zYWZlU2l6ZSgpfXB4YCxcbiAgICB9O1xuICB9XG5cbiAgcHJpdmF0ZSBzYWZlU2l6ZSA9ICgpID0+IChOdW1iZXIuaXNJbnRlZ2VyKHRoaXMuc2l6ZSkgJiYgdGhpcy5zaXplID4gMCAmJiB0aGlzLnNpemUgPCA2KSA/IHRoaXMuc2l6ZSA6IDE7XG5cbiAgc3RhckFuaW1hdGlvbigpOiB2b2lkIHtcbiAgICB0aGlzLmFuaW1hdGlvblJ1bm5pbmcgPSB0cnVlO1xuICAgIGlmICh0aGlzLnJhdGluZyA8IHRoaXMubWF4U3RhcnMpIHtcbiAgICAgIHRoaXMuc2V0UmF0aW5nKHRoaXMucmF0aW5nICs9IDAuNSk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgdGhpcy5zZXRSYXRpbmcoMCk7XG4gICAgfVxuICB9XG5cbiAgY2FuY2VsU3RhckFuaW1hdGlvbigpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5hbmltYXRpb25SdW5uaW5nKSB7XG4gICAgICBjbGVhckludGVydmFsKHRoaXMuYW5pbWF0aW9uSW50ZXJ2YWwpO1xuICAgICAgdGhpcy5yYXRpbmcgPSAwO1xuICAgICAgdGhpcy5hbmltYXRpb25SdW5uaW5nID0gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgc2V0UmF0aW5nKHJhdGluZzogbnVtYmVyKSB7XG4gICAgdGhpcy5yYXRpbmcgPSBNYXRoLnJvdW5kKHJhdGluZyAqIDIpIC8gMjtcbiAgICB0aGlzLm9uU3RhcnNVbmhvdmVyKCk7XG4gIH1cblxuICBvblN0YXJIb3ZlcihldmVudDogTW91c2VFdmVudCwgY2xpY2tlZFN0YXI6IEVkaXRhYmxlU3Rhcik6IHZvaWQge1xuICAgIHRoaXMuY2FuY2VsU3RhckFuaW1hdGlvbigpO1xuXG4gICAgY29uc3QgY2xpY2tlZEluRmlyc3RIYWxmID0gdGhpcy5jbGlja2VkSW5GaXJzdEhhbGYoZXZlbnQpO1xuXG4gICAgLy8gZmlsbCBpbiBlaXRoZXIgYSBoYWxmIG9yIHdob2xlIHN0YXIgZGVwZW5kaW5nIG9uIHdoZXJlIHVzZXIgY2xpY2tlZFxuICAgIGNsaWNrZWRTdGFyLmNsYXNzbmFtZSA9ICghdGhpcy53aG9sZVN0YXJzICYmIGNsaWNrZWRJbkZpcnN0SGFsZikgPyB0aGlzLmdldFN0YXJDbGFzcygnaGFsZicpIDogdGhpcy5nZXRTdGFyQ2xhc3MoJ2Z1bGwnKTtcblxuICAgIC8vIGZpbGwgaW4gYWxsIHN0YXJzIGluIHByZXZpb3VzIHBvc2l0aW9ucyBhbmQgY2xlYXIgYWxsIGluIGxhdGVyIG9uZXNcbiAgICB0aGlzLmVkaXRhYmxlU3RhcnMuZm9yRWFjaChzdGFyID0+IHtcbiAgICAgIGlmIChzdGFyLnBvc2l0aW9uID4gY2xpY2tlZFN0YXIucG9zaXRpb24pIHtcbiAgICAgICAgc3Rhci5jbGFzc25hbWUgPSB0aGlzLmdldFN0YXJDbGFzcygnZW1wdHknKTtcbiAgICAgIH1cbiAgICAgIGVsc2UgaWYgKHN0YXIucG9zaXRpb24gPCBjbGlja2VkU3Rhci5wb3NpdGlvbikge1xuICAgICAgICBzdGFyLmNsYXNzbmFtZSA9IHRoaXMuZ2V0U3RhckNsYXNzKCdmdWxsJyk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBvblN0YXJDbGljayhldmVudDogTW91c2VFdmVudCwgY2xpY2tlZFN0YXI6IEVkaXRhYmxlU3Rhcik6IHZvaWQge1xuICAgIHRoaXMuY2FuY2VsU3RhckFuaW1hdGlvbigpO1xuXG4gICAgLy8gbG9jayBpbiBjdXJyZW50IHJhdGluZ1xuICAgIGNvbnN0IGNsaWNrZWRJbkZpcnN0SGFsZiA9IHRoaXMuY2xpY2tlZEluRmlyc3RIYWxmKGV2ZW50KTtcbiAgICB0aGlzLnJhdGluZyA9IGNsaWNrZWRTdGFyLnBvc2l0aW9uICsgKCghdGhpcy53aG9sZVN0YXJzICYmIGNsaWNrZWRJbkZpcnN0SGFsZikgPyAwLjUgOiAxKTtcbiAgICB0aGlzLnJhdGluZ091dHB1dC5lbWl0KHRoaXMucmF0aW5nKTtcbiAgfVxuXG4gIC8vIGhpZGRlbiBzdGFyIHRvIGxlZnQgb2YgZmlyc3Qgc3RhciBsZXRzIHVzZXIgY2xpY2sgdGhlcmUgdG8gc2V0IHRvIDBcbiAgb25aZXJvU3RhckNsaWNrKCk6IHZvaWQge1xuICAgIHRoaXMuc2V0UmF0aW5nKDApO1xuICAgIHRoaXMucmF0aW5nT3V0cHV0LmVtaXQodGhpcy5yYXRpbmcpO1xuICB9XG5cbiAgb25aZXJvU3RhckhvdmVyKCk6IHZvaWQge1xuICAgIC8vIGNsZWFyIGFsbCBzdGFyc1xuICAgIHRoaXMuZWRpdGFibGVTdGFycy5mb3JFYWNoKHN0YXIgPT4gc3Rhci5jbGFzc25hbWUgPSB0aGlzLmdldFN0YXJDbGFzcygnZW1wdHknKSk7XG4gIH1cblxuICBvblN0YXJzVW5ob3ZlcigpIHtcbiAgICAvLyB3aGVuIHVzZXIgc3RvcHMgaG92ZXJpbmcgd2Ugd2FudCB0byBtYWtlIHN0YXJzIHJlZmxlY3QgdGhlIGxhc3QgcmF0aW5nIGFwcGxpZWQgYnkgY2xpY2tpbmdcbiAgICB0aGlzLmVkaXRhYmxlU3RhcnMuZm9yRWFjaChzdGFyID0+IHtcbiAgICAgIGNvbnN0IHN0YXJOdW1iZXIgPSBzdGFyLnBvc2l0aW9uICsgMTtcbiAgICAgIGlmICh0aGlzLnJhdGluZyA+PSBzdGFyTnVtYmVyKSB7XG4gICAgICAgIHN0YXIuY2xhc3NuYW1lID0gdGhpcy5nZXRTdGFyQ2xhc3MoJ2Z1bGwnKTtcbiAgICAgIH1cbiAgICAgIGVsc2UgaWYgKHRoaXMucmF0aW5nID4gc3Rhck51bWJlciAtIDEgJiYgdGhpcy5yYXRpbmcgPCBzdGFyTnVtYmVyKSB7XG4gICAgICAgIHN0YXIuY2xhc3NuYW1lID0gdGhpcy5nZXRTdGFyQ2xhc3MoJ2hhbGYnKTtcbiAgICAgIH1cbiAgICAgIGVsc2Uge1xuICAgICAgICBzdGFyLmNsYXNzbmFtZSA9IHRoaXMuZ2V0U3RhckNsYXNzKCdlbXB0eScpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBjbGlja2VkSW5GaXJzdEhhbGYoZXZlbnQ6IE1vdXNlRXZlbnQpOiBib29sZWFuIHtcbiAgICBjb25zdCBzdGFySWNvbiA9IGV2ZW50LnRhcmdldCBhcyBIVE1MRWxlbWVudDtcbiAgICByZXR1cm4gZXZlbnQucGFnZVggPCBzdGFySWNvbi5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS5sZWZ0ICsgc3Rhckljb24ub2Zmc2V0V2lkdGggLyAyO1xuICB9XG5cbiAgbm9vcCgpOiB2b2lkIHt9XG5cbiAgcHJpdmF0ZSBnZXRTdGFyQ2xhc3Moc3RhclR5cGU6IFN0YXJUeXBlKSB7XG4gICAgaWYgKHRoaXMuY3VzdG9tQ3NzQ2xhc3Nlcykge1xuICAgICAgcmV0dXJuIGBuZ3gtc3RhcnMtc3Rhci0ke3N0YXJUeXBlfS0ke3RoaXMuY3VzdG9tQ2xhc3NJZGVudGlmaWVyfWA7XG4gICAgfVxuICAgIHJldHVybiBgc3Rhci0ke3N0YXJUeXBlfWA7XG4gIH1cblxuICAvLyB0aGlzIGFuZCB0aGUgYXJpYS1sYWJlbHMgYW5kIHJvbGUgaW4gdGhlIGh0bWwgaW5zcGlyZWQgYnkgaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xLzU1OTY2MjA1XG4gIGdldEFyaWFMYWJlbCgpOiBzdHJpbmcge1xuICAgIHJldHVybiBgUmF0aW5nOiAke3RoaXMucmF0aW5nfSBvdXQgb2YgJHt0aGlzLm1heFN0YXJzfSBzdGFycyAke3RoaXMucmVhZG9ubHkgPyAnJyA6ICcuIENhbiBiZSBlZGl0ZWQuJ31gO1xuICB9XG59XG5cbmV4cG9ydCB0eXBlIFN0YXJUeXBlID0gJ2VtcHR5JyB8ICdoYWxmJyB8ICdmdWxsJztcblxuZXhwb3J0IGNsYXNzIEVkaXRhYmxlU3RhciB7XG4gIHBvc2l0aW9uOiBudW1iZXI7XG4gIGNsYXNzbmFtZTogc3RyaW5nO1xuXG4gIGNvbnN0cnVjdG9yKHBvc2l0aW9uOiBudW1iZXIpIHtcbiAgICB0aGlzLnBvc2l0aW9uID0gcG9zaXRpb247XG4gIH1cbn1cbiJdfQ==