juvo-rafa-library
Version:
A comprehensive Angular component library featuring real-world components and validators extracted from the Juvo Rafa backoffice application. Now with improved select components and bug fixes.
138 lines • 21.2 kB
JavaScript
import { Component, Input, Output, EventEmitter } from '@angular/core';
import { CommonModule } from '@angular/common';
import * as i0 from "@angular/core";
import * as i1 from "@angular/common";
/**
* Notification Component
*
* @description
* A flexible notification system for displaying messages to users.
* Supports different types (success, error, warning, info) and positions.
* Originally designed for backoffice applications to provide user feedback.
*
* @example
* ```html
* <!-- Basic notification -->
* <juvo-notification
* type="success"
* title="Operation successful"
* message="The item was saved successfully."
* [duration]="5000"
* (onClose)="onNotificationClose()">
* </juvo-notification>
*
* <!-- Multiple notifications container -->
* <juvo-notification
* *ngFor="let notification of notifications"
* [type]="notification.type"
* [title]="notification.title"
* [message]="notification.message"
* [duration]="notification.duration"
* position="top-right"
* (onClose)="removeNotification(notification.id)">
* </juvo-notification>
* ```
*
* @selector juvo-notification
* @since 2.1.0
* @author Juvo Rafa Team
*/
export class JuvoNotificationComponent {
constructor() {
/** Notification type @default "info" */
this.type = 'info';
/** Notification title */
this.title = '';
/** Auto-dismiss duration in milliseconds. 0 means no auto-dismiss @default 5000 */
this.duration = 5000;
/** Whether the notification persists until manually closed @default false */
this.persistent = false;
/** Position of the notification @default "top-right" */
this.position = 'top-right';
/** Whether to show close button @default true */
this.closable = true;
/** Whether the notification is visible @default true */
this.visible = true;
/** Emitted when notification is closed */
this.onClose = new EventEmitter();
/** Emitted when notification is clicked */
this.onClick = new EventEmitter();
}
ngOnInit() {
if (!this.persistent && this.duration > 0) {
this.timeoutId = window.setTimeout(() => {
this.close();
}, this.duration);
}
}
ngOnDestroy() {
if (this.timeoutId) {
clearTimeout(this.timeoutId);
}
}
/**
* Gets the icon for the notification type
* @returns Icon string for the notification type
*/
get icon() {
switch (this.type) {
case 'success': return '✅';
case 'error': return '❌';
case 'warning': return '⚠️';
case 'info': return 'ℹ️';
default: return 'ℹ️';
}
}
/**
* Gets CSS classes for the notification
* @returns Combined CSS classes
*/
get notificationClasses() {
return `notification notification-${this.type} notification-${this.position}`;
}
/**
* Closes the notification
* @emits onClose
*/
close() {
this.visible = false;
this.onClose.emit();
if (this.timeoutId) {
clearTimeout(this.timeoutId);
}
}
/**
* Handles notification click
* @emits onClick
*/
handleClick() {
this.onClick.emit();
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: JuvoNotificationComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: JuvoNotificationComponent, isStandalone: true, selector: "juvo-notification", inputs: { type: "type", title: "title", message: "message", duration: "duration", persistent: "persistent", position: "position", closable: "closable", visible: "visible" }, outputs: { onClose: "onClose", onClick: "onClick" }, ngImport: i0, template: "<div class=\"notification-container\" \n [class]=\"notificationClasses\" \n *ngIf=\"visible\"\n (click)=\"handleClick()\">\n \n <div class=\"notification-content\">\n <div class=\"notification-icon\">\n {{ icon }}\n </div>\n \n <div class=\"notification-body\">\n <div class=\"notification-title\" *ngIf=\"title\">\n {{ title }}\n </div>\n <div class=\"notification-message\" *ngIf=\"message\">\n {{ message }}\n </div>\n </div>\n \n <button class=\"notification-close\" \n *ngIf=\"closable\"\n (click)=\"close(); $event.stopPropagation()\" \n type=\"button\"\n aria-label=\"Close notification\">\n \u2715\n </button>\n </div>\n \n <div class=\"notification-progress\" \n *ngIf=\"!persistent && duration > 0\"\n [style.animation-duration]=\"duration + 'ms'\">\n </div>\n</div> ", styles: [".notification-container{position:fixed;max-width:400px;min-width:300px;background:#fff;border-radius:.5rem;box-shadow:0 4px 12px #00000026;border-left:4px solid;overflow:hidden;z-index:1050;cursor:pointer;animation:slideIn .3s ease-out}.notification-top-right{top:1rem;right:1rem}.notification-top-left{top:1rem;left:1rem}.notification-bottom-right{bottom:1rem;right:1rem}.notification-bottom-left{bottom:1rem;left:1rem}.notification-top-center{top:1rem;left:50%;transform:translate(-50%)}.notification-bottom-center{bottom:1rem;left:50%;transform:translate(-50%)}.notification-success{border-left-color:#10b981}.notification-error{border-left-color:#ef4444}.notification-warning{border-left-color:#f59e0b}.notification-info{border-left-color:#3b82f6}.notification-content{display:flex;align-items:flex-start;padding:1rem;gap:.75rem}.notification-icon{font-size:1.25rem;flex-shrink:0;margin-top:.125rem}.notification-body{flex:1;min-width:0}.notification-title{font-weight:600;color:#374151;font-size:.875rem;margin-bottom:.25rem}.notification-message{color:#6b7280;font-size:.8125rem;line-height:1.5}.notification-close{background:none;border:none;color:#9ca3af;cursor:pointer;padding:.25rem;border-radius:.25rem;transition:all .15s;flex-shrink:0;font-size:.875rem}.notification-close:hover{background:#f3f4f6;color:#6b7280}.notification-progress{height:3px;background:linear-gradient(90deg,currentColor,currentColor);animation:progressShrink linear;transform-origin:left}.notification-success .notification-progress{color:#10b981}.notification-error .notification-progress{color:#ef4444}.notification-warning .notification-progress{color:#f59e0b}.notification-info .notification-progress{color:#3b82f6}@keyframes slideIn{0%{opacity:0;transform:translate(100%)}to{opacity:1;transform:translate(0)}}@keyframes progressShrink{0%{transform:scaleX(1)}to{transform:scaleX(0)}}@media (max-width: 640px){.notification-container{max-width:calc(100vw - 2rem);min-width:calc(100vw - 2rem);left:1rem!important;right:1rem!important;transform:none!important}.notification-top-center,.notification-bottom-center{left:1rem;transform:none}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: JuvoNotificationComponent, decorators: [{
type: Component,
args: [{ selector: 'juvo-notification', standalone: true, imports: [CommonModule], template: "<div class=\"notification-container\" \n [class]=\"notificationClasses\" \n *ngIf=\"visible\"\n (click)=\"handleClick()\">\n \n <div class=\"notification-content\">\n <div class=\"notification-icon\">\n {{ icon }}\n </div>\n \n <div class=\"notification-body\">\n <div class=\"notification-title\" *ngIf=\"title\">\n {{ title }}\n </div>\n <div class=\"notification-message\" *ngIf=\"message\">\n {{ message }}\n </div>\n </div>\n \n <button class=\"notification-close\" \n *ngIf=\"closable\"\n (click)=\"close(); $event.stopPropagation()\" \n type=\"button\"\n aria-label=\"Close notification\">\n \u2715\n </button>\n </div>\n \n <div class=\"notification-progress\" \n *ngIf=\"!persistent && duration > 0\"\n [style.animation-duration]=\"duration + 'ms'\">\n </div>\n</div> ", styles: [".notification-container{position:fixed;max-width:400px;min-width:300px;background:#fff;border-radius:.5rem;box-shadow:0 4px 12px #00000026;border-left:4px solid;overflow:hidden;z-index:1050;cursor:pointer;animation:slideIn .3s ease-out}.notification-top-right{top:1rem;right:1rem}.notification-top-left{top:1rem;left:1rem}.notification-bottom-right{bottom:1rem;right:1rem}.notification-bottom-left{bottom:1rem;left:1rem}.notification-top-center{top:1rem;left:50%;transform:translate(-50%)}.notification-bottom-center{bottom:1rem;left:50%;transform:translate(-50%)}.notification-success{border-left-color:#10b981}.notification-error{border-left-color:#ef4444}.notification-warning{border-left-color:#f59e0b}.notification-info{border-left-color:#3b82f6}.notification-content{display:flex;align-items:flex-start;padding:1rem;gap:.75rem}.notification-icon{font-size:1.25rem;flex-shrink:0;margin-top:.125rem}.notification-body{flex:1;min-width:0}.notification-title{font-weight:600;color:#374151;font-size:.875rem;margin-bottom:.25rem}.notification-message{color:#6b7280;font-size:.8125rem;line-height:1.5}.notification-close{background:none;border:none;color:#9ca3af;cursor:pointer;padding:.25rem;border-radius:.25rem;transition:all .15s;flex-shrink:0;font-size:.875rem}.notification-close:hover{background:#f3f4f6;color:#6b7280}.notification-progress{height:3px;background:linear-gradient(90deg,currentColor,currentColor);animation:progressShrink linear;transform-origin:left}.notification-success .notification-progress{color:#10b981}.notification-error .notification-progress{color:#ef4444}.notification-warning .notification-progress{color:#f59e0b}.notification-info .notification-progress{color:#3b82f6}@keyframes slideIn{0%{opacity:0;transform:translate(100%)}to{opacity:1;transform:translate(0)}}@keyframes progressShrink{0%{transform:scaleX(1)}to{transform:scaleX(0)}}@media (max-width: 640px){.notification-container{max-width:calc(100vw - 2rem);min-width:calc(100vw - 2rem);left:1rem!important;right:1rem!important;transform:none!important}.notification-top-center,.notification-bottom-center{left:1rem;transform:none}}\n"] }]
}], propDecorators: { type: [{
type: Input
}], title: [{
type: Input
}], message: [{
type: Input
}], duration: [{
type: Input
}], persistent: [{
type: Input
}], position: [{
type: Input
}], closable: [{
type: Input
}], visible: [{
type: Input
}], onClose: [{
type: Output
}], onClick: [{
type: Output
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoianV2by1ub3RpZmljYXRpb24uY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvdWktY29tcG9uZW50cy9zcmMvbGliL2p1dm8tbm90aWZpY2F0aW9uL2p1dm8tbm90aWZpY2F0aW9uLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3VpLWNvbXBvbmVudHMvc3JjL2xpYi9qdXZvLW5vdGlmaWNhdGlvbi9qdXZvLW5vdGlmaWNhdGlvbi5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsWUFBWSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3ZFLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQzs7O0FBOEIvQzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQWtDRztBQVFILE1BQU0sT0FBTyx5QkFBeUI7SUFQdEM7UUFRRSx3Q0FBd0M7UUFDL0IsU0FBSSxHQUFxQixNQUFNLENBQUM7UUFFekMseUJBQXlCO1FBQ2hCLFVBQUssR0FBVyxFQUFFLENBQUM7UUFLNUIsbUZBQW1GO1FBQzFFLGFBQVEsR0FBVyxJQUFJLENBQUM7UUFFakMsNkVBQTZFO1FBQ3BFLGVBQVUsR0FBWSxLQUFLLENBQUM7UUFFckMsd0RBQXdEO1FBQy9DLGFBQVEsR0FBeUIsV0FBVyxDQUFDO1FBRXRELGlEQUFpRDtRQUN4QyxhQUFRLEdBQVksSUFBSSxDQUFDO1FBRWxDLHdEQUF3RDtRQUMvQyxZQUFPLEdBQVksSUFBSSxDQUFDO1FBRWpDLDBDQUEwQztRQUNoQyxZQUFPLEdBQUcsSUFBSSxZQUFZLEVBQVEsQ0FBQztRQUU3QywyQ0FBMkM7UUFDakMsWUFBTyxHQUFHLElBQUksWUFBWSxFQUFRLENBQUM7S0E0RDlDO0lBeERDLFFBQVE7UUFDTixJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsSUFBSSxJQUFJLENBQUMsUUFBUSxHQUFHLENBQUMsRUFBRSxDQUFDO1lBQzFDLElBQUksQ0FBQyxTQUFTLEdBQUcsTUFBTSxDQUFDLFVBQVUsQ0FBQyxHQUFHLEVBQUU7Z0JBQ3RDLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUNmLENBQUMsRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDcEIsQ0FBQztJQUNILENBQUM7SUFFRCxXQUFXO1FBQ1QsSUFBSSxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7WUFDbkIsWUFBWSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUMvQixDQUFDO0lBQ0gsQ0FBQztJQUVEOzs7T0FHRztJQUNILElBQUksSUFBSTtRQUNOLFFBQVEsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDO1lBQ2xCLEtBQUssU0FBUyxDQUFDLENBQUMsT0FBTyxHQUFHLENBQUM7WUFDM0IsS0FBSyxPQUFPLENBQUMsQ0FBQyxPQUFPLEdBQUcsQ0FBQztZQUN6QixLQUFLLFNBQVMsQ0FBQyxDQUFDLE9BQU8sSUFBSSxDQUFDO1lBQzVCLEtBQUssTUFBTSxDQUFDLENBQUMsT0FBTyxJQUFJLENBQUM7WUFDekIsT0FBTyxDQUFDLENBQUMsT0FBTyxJQUFJLENBQUM7UUFDdkIsQ0FBQztJQUNILENBQUM7SUFFRDs7O09BR0c7SUFDSCxJQUFJLG1CQUFtQjtRQUNyQixPQUFPLDZCQUE2QixJQUFJLENBQUMsSUFBSSxpQkFBaUIsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDO0lBQ2hGLENBQUM7SUFFRDs7O09BR0c7SUFDSCxLQUFLO1FBQ0gsSUFBSSxDQUFDLE9BQU8sR0FBRyxLQUFLLENBQUM7UUFDckIsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUVwQixJQUFJLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztZQUNuQixZQUFZLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQy9CLENBQUM7SUFDSCxDQUFDO0lBRUQ7OztPQUdHO0lBQ0gsV0FBVztRQUNULElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLENBQUM7SUFDdEIsQ0FBQzsrR0F4RlUseUJBQXlCO21HQUF6Qix5QkFBeUIsZ1RDekV0Qyx5NUJBZ0NPLHdvRURxQ0ssWUFBWTs7NEZBSVgseUJBQXlCO2tCQVByQyxTQUFTOytCQUNFLG1CQUFtQixjQUNqQixJQUFJLFdBQ1AsQ0FBQyxZQUFZLENBQUM7OEJBTWQsSUFBSTtzQkFBWixLQUFLO2dCQUdHLEtBQUs7c0JBQWIsS0FBSztnQkFHRyxPQUFPO3NCQUFmLEtBQUs7Z0JBR0csUUFBUTtzQkFBaEIsS0FBSztnQkFHRyxVQUFVO3NCQUFsQixLQUFLO2dCQUdHLFFBQVE7c0JBQWhCLEtBQUs7Z0JBR0csUUFBUTtzQkFBaEIsS0FBSztnQkFHRyxPQUFPO3NCQUFmLEtBQUs7Z0JBR0ksT0FBTztzQkFBaEIsTUFBTTtnQkFHRyxPQUFPO3NCQUFoQixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBJbnB1dCwgT3V0cHV0LCBFdmVudEVtaXR0ZXIgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IENvbW1vbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5cbi8qKlxuICogTm90aWZpY2F0aW9uIHR5cGVzXG4gKiBAdHlwZSBOb3RpZmljYXRpb25UeXBlXG4gKiBAc2luY2UgMi4xLjBcbiAqL1xuZXhwb3J0IHR5cGUgTm90aWZpY2F0aW9uVHlwZSA9ICdzdWNjZXNzJyB8ICdlcnJvcicgfCAnd2FybmluZycgfCAnaW5mbyc7XG5cbi8qKlxuICogTm90aWZpY2F0aW9uIHBvc2l0aW9uIG9wdGlvbnNcbiAqIEB0eXBlIE5vdGlmaWNhdGlvblBvc2l0aW9uXG4gKiBAc2luY2UgMi4xLjBcbiAqL1xuZXhwb3J0IHR5cGUgTm90aWZpY2F0aW9uUG9zaXRpb24gPSAndG9wLXJpZ2h0JyB8ICd0b3AtbGVmdCcgfCAnYm90dG9tLXJpZ2h0JyB8ICdib3R0b20tbGVmdCcgfCAndG9wLWNlbnRlcicgfCAnYm90dG9tLWNlbnRlcic7XG5cbi8qKlxuICogTm90aWZpY2F0aW9uIGludGVyZmFjZVxuICogQGludGVyZmFjZSBOb3RpZmljYXRpb25cbiAqIEBzaW5jZSAyLjEuMFxuICovXG5leHBvcnQgaW50ZXJmYWNlIE5vdGlmaWNhdGlvbiB7XG4gIGlkPzogc3RyaW5nO1xuICB0eXBlOiBOb3RpZmljYXRpb25UeXBlO1xuICB0aXRsZTogc3RyaW5nO1xuICBtZXNzYWdlPzogc3RyaW5nO1xuICBkdXJhdGlvbj86IG51bWJlcjtcbiAgcGVyc2lzdGVudD86IGJvb2xlYW47XG59XG5cbi8qKlxuICogTm90aWZpY2F0aW9uIENvbXBvbmVudFxuICogXG4gKiBAZGVzY3JpcHRpb25cbiAqIEEgZmxleGlibGUgbm90aWZpY2F0aW9uIHN5c3RlbSBmb3IgZGlzcGxheWluZyBtZXNzYWdlcyB0byB1c2Vycy5cbiAqIFN1cHBvcnRzIGRpZmZlcmVudCB0eXBlcyAoc3VjY2VzcywgZXJyb3IsIHdhcm5pbmcsIGluZm8pIGFuZCBwb3NpdGlvbnMuXG4gKiBPcmlnaW5hbGx5IGRlc2lnbmVkIGZvciBiYWNrb2ZmaWNlIGFwcGxpY2F0aW9ucyB0byBwcm92aWRlIHVzZXIgZmVlZGJhY2suXG4gKiBcbiAqIEBleGFtcGxlXG4gKiBgYGBodG1sXG4gKiA8IS0tIEJhc2ljIG5vdGlmaWNhdGlvbiAtLT5cbiAqIDxqdXZvLW5vdGlmaWNhdGlvblxuICogICB0eXBlPVwic3VjY2Vzc1wiXG4gKiAgIHRpdGxlPVwiT3BlcmF0aW9uIHN1Y2Nlc3NmdWxcIlxuICogICBtZXNzYWdlPVwiVGhlIGl0ZW0gd2FzIHNhdmVkIHN1Y2Nlc3NmdWxseS5cIlxuICogICBbZHVyYXRpb25dPVwiNTAwMFwiXG4gKiAgIChvbkNsb3NlKT1cIm9uTm90aWZpY2F0aW9uQ2xvc2UoKVwiPlxuICogPC9qdXZvLW5vdGlmaWNhdGlvbj5cbiAqIFxuICogPCEtLSBNdWx0aXBsZSBub3RpZmljYXRpb25zIGNvbnRhaW5lciAtLT5cbiAqIDxqdXZvLW5vdGlmaWNhdGlvblxuICogICAqbmdGb3I9XCJsZXQgbm90aWZpY2F0aW9uIG9mIG5vdGlmaWNhdGlvbnNcIlxuICogICBbdHlwZV09XCJub3RpZmljYXRpb24udHlwZVwiXG4gKiAgIFt0aXRsZV09XCJub3RpZmljYXRpb24udGl0bGVcIlxuICogICBbbWVzc2FnZV09XCJub3RpZmljYXRpb24ubWVzc2FnZVwiXG4gKiAgIFtkdXJhdGlvbl09XCJub3RpZmljYXRpb24uZHVyYXRpb25cIlxuICogICBwb3NpdGlvbj1cInRvcC1yaWdodFwiXG4gKiAgIChvbkNsb3NlKT1cInJlbW92ZU5vdGlmaWNhdGlvbihub3RpZmljYXRpb24uaWQpXCI+XG4gKiA8L2p1dm8tbm90aWZpY2F0aW9uPlxuICogYGBgXG4gKiBcbiAqIEBzZWxlY3RvciBqdXZvLW5vdGlmaWNhdGlvblxuICogQHNpbmNlIDIuMS4wXG4gKiBAYXV0aG9yIEp1dm8gUmFmYSBUZWFtXG4gKi9cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2p1dm8tbm90aWZpY2F0aW9uJyxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW0NvbW1vbk1vZHVsZV0sXG4gIHRlbXBsYXRlVXJsOiAnLi9qdXZvLW5vdGlmaWNhdGlvbi5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsOiAnLi9qdXZvLW5vdGlmaWNhdGlvbi5jb21wb25lbnQuY3NzJ1xufSlcbmV4cG9ydCBjbGFzcyBKdXZvTm90aWZpY2F0aW9uQ29tcG9uZW50IHtcbiAgLyoqIE5vdGlmaWNhdGlvbiB0eXBlIEBkZWZhdWx0IFwiaW5mb1wiICovXG4gIEBJbnB1dCgpIHR5cGU6IE5vdGlmaWNhdGlvblR5cGUgPSAnaW5mbyc7XG4gIFxuICAvKiogTm90aWZpY2F0aW9uIHRpdGxlICovXG4gIEBJbnB1dCgpIHRpdGxlOiBzdHJpbmcgPSAnJztcbiAgXG4gIC8qKiBOb3RpZmljYXRpb24gbWVzc2FnZSBjb250ZW50ICovXG4gIEBJbnB1dCgpIG1lc3NhZ2U/OiBzdHJpbmc7XG4gIFxuICAvKiogQXV0by1kaXNtaXNzIGR1cmF0aW9uIGluIG1pbGxpc2Vjb25kcy4gMCBtZWFucyBubyBhdXRvLWRpc21pc3MgQGRlZmF1bHQgNTAwMCAqL1xuICBASW5wdXQoKSBkdXJhdGlvbjogbnVtYmVyID0gNTAwMDtcbiAgXG4gIC8qKiBXaGV0aGVyIHRoZSBub3RpZmljYXRpb24gcGVyc2lzdHMgdW50aWwgbWFudWFsbHkgY2xvc2VkIEBkZWZhdWx0IGZhbHNlICovXG4gIEBJbnB1dCgpIHBlcnNpc3RlbnQ6IGJvb2xlYW4gPSBmYWxzZTtcbiAgXG4gIC8qKiBQb3NpdGlvbiBvZiB0aGUgbm90aWZpY2F0aW9uIEBkZWZhdWx0IFwidG9wLXJpZ2h0XCIgKi9cbiAgQElucHV0KCkgcG9zaXRpb246IE5vdGlmaWNhdGlvblBvc2l0aW9uID0gJ3RvcC1yaWdodCc7XG4gIFxuICAvKiogV2hldGhlciB0byBzaG93IGNsb3NlIGJ1dHRvbiBAZGVmYXVsdCB0cnVlICovXG4gIEBJbnB1dCgpIGNsb3NhYmxlOiBib29sZWFuID0gdHJ1ZTtcbiAgXG4gIC8qKiBXaGV0aGVyIHRoZSBub3RpZmljYXRpb24gaXMgdmlzaWJsZSBAZGVmYXVsdCB0cnVlICovXG4gIEBJbnB1dCgpIHZpc2libGU6IGJvb2xlYW4gPSB0cnVlO1xuICBcbiAgLyoqIEVtaXR0ZWQgd2hlbiBub3RpZmljYXRpb24gaXMgY2xvc2VkICovXG4gIEBPdXRwdXQoKSBvbkNsb3NlID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuICBcbiAgLyoqIEVtaXR0ZWQgd2hlbiBub3RpZmljYXRpb24gaXMgY2xpY2tlZCAqL1xuICBAT3V0cHV0KCkgb25DbGljayA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcblxuICBwcml2YXRlIHRpbWVvdXRJZD86IG51bWJlcjtcblxuICBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMucGVyc2lzdGVudCAmJiB0aGlzLmR1cmF0aW9uID4gMCkge1xuICAgICAgdGhpcy50aW1lb3V0SWQgPSB3aW5kb3cuc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgIHRoaXMuY2xvc2UoKTtcbiAgICAgIH0sIHRoaXMuZHVyYXRpb24pO1xuICAgIH1cbiAgfVxuXG4gIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgIGlmICh0aGlzLnRpbWVvdXRJZCkge1xuICAgICAgY2xlYXJUaW1lb3V0KHRoaXMudGltZW91dElkKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogR2V0cyB0aGUgaWNvbiBmb3IgdGhlIG5vdGlmaWNhdGlvbiB0eXBlXG4gICAqIEByZXR1cm5zIEljb24gc3RyaW5nIGZvciB0aGUgbm90aWZpY2F0aW9uIHR5cGVcbiAgICovXG4gIGdldCBpY29uKCk6IHN0cmluZyB7XG4gICAgc3dpdGNoICh0aGlzLnR5cGUpIHtcbiAgICAgIGNhc2UgJ3N1Y2Nlc3MnOiByZXR1cm4gJ+KchSc7XG4gICAgICBjYXNlICdlcnJvcic6IHJldHVybiAn4p2MJztcbiAgICAgIGNhc2UgJ3dhcm5pbmcnOiByZXR1cm4gJ+KaoO+4jyc7XG4gICAgICBjYXNlICdpbmZvJzogcmV0dXJuICfihLnvuI8nO1xuICAgICAgZGVmYXVsdDogcmV0dXJuICfihLnvuI8nO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBHZXRzIENTUyBjbGFzc2VzIGZvciB0aGUgbm90aWZpY2F0aW9uXG4gICAqIEByZXR1cm5zIENvbWJpbmVkIENTUyBjbGFzc2VzXG4gICAqL1xuICBnZXQgbm90aWZpY2F0aW9uQ2xhc3NlcygpOiBzdHJpbmcge1xuICAgIHJldHVybiBgbm90aWZpY2F0aW9uIG5vdGlmaWNhdGlvbi0ke3RoaXMudHlwZX0gbm90aWZpY2F0aW9uLSR7dGhpcy5wb3NpdGlvbn1gO1xuICB9XG5cbiAgLyoqXG4gICAqIENsb3NlcyB0aGUgbm90aWZpY2F0aW9uXG4gICAqIEBlbWl0cyBvbkNsb3NlXG4gICAqL1xuICBjbG9zZSgpOiB2b2lkIHtcbiAgICB0aGlzLnZpc2libGUgPSBmYWxzZTtcbiAgICB0aGlzLm9uQ2xvc2UuZW1pdCgpO1xuICAgIFxuICAgIGlmICh0aGlzLnRpbWVvdXRJZCkge1xuICAgICAgY2xlYXJUaW1lb3V0KHRoaXMudGltZW91dElkKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogSGFuZGxlcyBub3RpZmljYXRpb24gY2xpY2tcbiAgICogQGVtaXRzIG9uQ2xpY2tcbiAgICovXG4gIGhhbmRsZUNsaWNrKCk6IHZvaWQge1xuICAgIHRoaXMub25DbGljay5lbWl0KCk7XG4gIH1cbn0gIiwiPGRpdiBjbGFzcz1cIm5vdGlmaWNhdGlvbi1jb250YWluZXJcIiBcbiAgICAgW2NsYXNzXT1cIm5vdGlmaWNhdGlvbkNsYXNzZXNcIiBcbiAgICAgKm5nSWY9XCJ2aXNpYmxlXCJcbiAgICAgKGNsaWNrKT1cImhhbmRsZUNsaWNrKClcIj5cbiAgXG4gIDxkaXYgY2xhc3M9XCJub3RpZmljYXRpb24tY29udGVudFwiPlxuICAgIDxkaXYgY2xhc3M9XCJub3RpZmljYXRpb24taWNvblwiPlxuICAgICAge3sgaWNvbiB9fVxuICAgIDwvZGl2PlxuICAgIFxuICAgIDxkaXYgY2xhc3M9XCJub3RpZmljYXRpb24tYm9keVwiPlxuICAgICAgPGRpdiBjbGFzcz1cIm5vdGlmaWNhdGlvbi10aXRsZVwiICpuZ0lmPVwidGl0bGVcIj5cbiAgICAgICAge3sgdGl0bGUgfX1cbiAgICAgIDwvZGl2PlxuICAgICAgPGRpdiBjbGFzcz1cIm5vdGlmaWNhdGlvbi1tZXNzYWdlXCIgKm5nSWY9XCJtZXNzYWdlXCI+XG4gICAgICAgIHt7IG1lc3NhZ2UgfX1cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuICAgIFxuICAgIDxidXR0b24gY2xhc3M9XCJub3RpZmljYXRpb24tY2xvc2VcIiBcbiAgICAgICAgICAgICpuZ0lmPVwiY2xvc2FibGVcIlxuICAgICAgICAgICAgKGNsaWNrKT1cImNsb3NlKCk7ICRldmVudC5zdG9wUHJvcGFnYXRpb24oKVwiIFxuICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICBhcmlhLWxhYmVsPVwiQ2xvc2Ugbm90aWZpY2F0aW9uXCI+XG4gICAgICDinJVcbiAgICA8L2J1dHRvbj5cbiAgPC9kaXY+XG4gIFxuICA8ZGl2IGNsYXNzPVwibm90aWZpY2F0aW9uLXByb2dyZXNzXCIgXG4gICAgICAgKm5nSWY9XCIhcGVyc2lzdGVudCAmJiBkdXJhdGlvbiA+IDBcIlxuICAgICAgIFtzdHlsZS5hbmltYXRpb24tZHVyYXRpb25dPVwiZHVyYXRpb24gKyAnbXMnXCI+XG4gIDwvZGl2PlxuPC9kaXY+ICJdfQ==