UNPKG

ng-materialgrammi

Version:

An Angular framework which follows

378 lines 58 kB
import { Component, EventEmitter, Input, Output } from '@angular/core'; import * as i0 from "@angular/core"; import * as i1 from "../../dater.service"; import * as i2 from "../../materialgrammi.service"; import * as i3 from "../dropable/dropable.component"; import * as i4 from "../dragable/dragable.component"; import * as i5 from "../overlay/overlay.component"; import * as i6 from "../input/input.component"; import * as i7 from "../text-input/text-input.component"; import * as i8 from "../button/button.component"; import * as i9 from "@angular/common"; export class CalendarComponent { constructor(dater, service) { this.dater = dater; this.service = service; this.abbreviation = false; this.bookEvents = false; this.theme = "primary"; this.disabled = []; this.size = 1; this.disabledRange = { before: false, after: false }; // "31 January 2022" this.events = [{ name: "Meeting with Ali", date: "17 January 2022 08:00 PM", description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.", buzz: true }, { name: "PUBG", date: "17 January 2022 10:00 PM", description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.", buzz: true }, { name: "PHP", date: "18 January 2022 10:00 PM", description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.", buzz: false }, { name: "Birthday Party", date: "20 February 2022 10:00 PM", description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.", buzz: true }]; this.format = "dd-MM-yyyy"; this.icons = { month: { next: `<i class="fas fa-angle-right"></i>`, previous: `<i class="fas fa-angle-left"></i>` }, year: { next: `<i class="fas fa-angle-double-right"></i>`, previous: `<i class="fas fa-angle-double-left"></i>` } }; this.controls = true; this.class = ""; this.dayIsClicked = new EventEmitter(); this.dayDrop = new EventEmitter(); this.newEvent = new EventEmitter(); this.weekDays = [ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ]; this.days = []; this.toggleEvent = false; this.current = {}; this.inView = {}; this.toggleSelect = false; this.isHoveredWithData = ""; this.id = ""; this.activateNewEvent = false; this.clickedOn = ""; this.bookEvent = { name: "", description: "", on: {} }; this.droppedData = {}; this.dropOnDate = {}; } ngOnInit() { this.executeAll(); this.id = this.service.makeid(4, "createNewEventOverlay"); } ngOnChanges() { console.log("Disabled? ", this.disabledRange); this.executeAll(); } executeAll() { this.initializeStates(); this.updateDays(this.inView.year); this.formatEventDates(); } initializeStates() { this.current = { month: this.dater.getMonth(), monthInWords: this.dater.getMonths(this.dater.getMonth()), date: this.dater.getDate(), year: this.dater.getYear(), dayInNum: this.dater.getDay(), weekDay: this.dater.getWeekDay(), hour: this.dater.getHour(), min: this.dater.getMinute(), sec: this.dater.getSeconds() }; this.months_long = this.dater.getMonthsLong(); this.months_short = this.dater.getMonths(); this.months = this.abbreviation ? this.months_short : this.months_long; this.inView = { month: this.current.month, year: this.current.year }; } formatEventDates() { for (let i = 0; i < this.events.length; i++) { this.events[i].dateObject = { date: this.dater.getDate(this.dater.dater(this.events[i].date)), month: this.dater.getMonth(this.dater.dater(this.events[i].date)), year: this.dater.getYear(this.dater.dater(this.events[i].date)) }; } } isDisabled(d, m, y) { for (let i = 0; i < this.disabled.length; i++) { let disabled_date = this.dater.dater(this.disabled[i]); if (d == this.dater.getDate(disabled_date) && (m - 1) == this.dater.getMonth(disabled_date) && y == this.dater.getYear(disabled_date)) { return true; } } return false; } pushDisabled(d, m, y) { let date = `${d} ${this.months[m - 1]} ${y}`; if (typeof this.disabledRange.after == "string" && this.dater.isGreater(date, this.disabledRange.after) && !this.disabled.includes(date)) { this.disabled.push(date); } if (typeof this.disabledRange.before == "string" && this.dater.isLessThan(date, this.disabledRange.before) && !this.disabled.includes(date)) { this.disabled.push(date); } } updateDays(year = this.current.year) { this.days = []; for (let i = 1; i < this.months.length + 1; i++) { let onMonth = {}; let firstDate = this.dater.dater(`1-${this.months[i - 1]}-${year}`); onMonth.totalDays = this.dater.daysInMonth(i, year); onMonth.name = this.months[i - 1]; onMonth.month = i; onMonth.dates = []; onMonth.startDay = this.dater.getDay(firstDate); for (let k = 0; k < onMonth.startDay; k++) { let myDaY = { num: 0, weekday: this.weekDays[k], weekDayNum: k, month: i, disabled: false }; onMonth.dates.push(myDaY); } for (let j = 1; j <= onMonth.totalDays; j++) { this.pushDisabled(j, i, year); let mydate = this.dater.dater(`${j} ${this.months[i - 1]} ${year}`); let myDaY = { num: j, weekday: this.weekDays[this.dater.getDay(mydate)], weekDayNum: this.dater.getDay(mydate), month: i, disabled: this.isDisabled(j, i, year) }; onMonth.dates.push(myDaY); } this.days.push(onMonth); } } isEvented(d, m, y) { let allEvents = []; for (let i = 0; i < this.events.length; i++) { if (d === this.events[i].dateObject.date && (m - 1) === this.events[i].dateObject.month && y === this.events[i].dateObject.year) { allEvents.push(this.events[i]); } } return allEvents.length > 0 ? allEvents : false; } doBuzz(eventDetails = []) { for (let i = 0; i < eventDetails.length; i++) { if (eventDetails[i].buzz) { return true; } } return false; } getSize() { if (this.size === 1) { return "padV-10"; } else if (this.size === 2) { return "padV-20"; } else if (this.size === 3) { return "padV-30"; } else if (this.size === 4) { return "padV-40"; } else { return "padV-50"; } } dayClass(d, m, y, disabled = false) { let results = ""; results += ` ${this.getSize()}`; results += this.dropzoneClass(d, m, y) ? " scale-3 shadow-3 outline-grey10" : ""; results += d == 0 ? " day-disabled" : ""; results += d == this.current.date && m - 1 == this.current.month && y == this.current.year ? " active-day" : ""; let eventdetails = this.isEvented(d, m, y); results += !disabled && eventdetails ? " haveEvent" : ""; results += !disabled && this.doBuzz(eventdetails) ? " buzz" : ""; results += disabled ? " day-diabled" : ""; return results; } nextMonth() { if (this.inView.month >= 11) { this.inView.month = 0; this.nextYear(); } else { this.inView.month++; } } prevMonth() { if (this.inView.month <= 0) { this.inView.month = 11; this.prevYear(); } else { this.inView.month--; } } nextYear() { this.inView.year++; this.updateDays(this.inView.year); } prevYear() { this.inView.year--; this.updateDays(this.inView.year); } clickOnDay(d, m, y, disabled = false) { if (!disabled) { let date = new Date(`${d} ${this.months[m - 1]} ${y}`); let dateTobeSent = this.dater.format(date, this.format); this.dayIsClicked.emit({ date: d, month: m, year: y, dateFormatted: dateTobeSent }); this.eventDetailsToggle(d, m, y); if (!this.toggleEvent) { if (this.bookEvents) { this.openNewEvent(); this.bookEvent.on.date = d; this.bookEvent.on.month = m; this.bookEvent.on.year = y; } this.clickedOn = this.dater.format(date, "dd-MM-yyyy"); } } } setBookEvent(event, type) { if (type == "name") { this.bookEvent.name = event.target.value; } if (type == "desc") { this.bookEvent.description = event.target.value; } } createNewEvent() { this.newEvent.emit(this.bookEvent); this.activateNewEvent = false; } openNewEvent() { this.activateNewEvent = true; } closeNewEvent() { this.activateNewEvent = false; } updateOnDay(event) { this.droppedData = event; this.dayDrop.emit({ data: this.droppedData, dropon: this.dropOnDate }); } handleDropZone(event, obj = {}) { if (event && !event.dropped && event.dragEntered) { this.isHoveredWithData = obj && obj.date && obj.month && obj.year ? `${obj.date}-${obj.month}-${obj.year}` : ""; } else if (event && event.dragLeft) { this.isHoveredWithData = ""; } else if (event.dropped) { this.isHoveredWithData = ""; this.dropOnDate = obj; } } dropzoneClass(d, m, y) { if (`${d}-${m}-${y}` === this.isHoveredWithData) { return true; } return false; } eventDetailsToggle(d, m, y) { if ((!this.toggleSelect) || !(this.toggleSelect.date == d && this.toggleSelect.month == m && this.toggleSelect.year == y)) { let eventdetail = this.isEvented(d, m, y); this.toggleSelect = { date: d, month: m, year: y, data: eventdetail }; if (eventdetail) { this.toggleEvent = true; this.toggleSelect.data = eventdetail; } else { this.toggleEvent = false; } } } } CalendarComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.0.3", ngImport: i0, type: CalendarComponent, deps: [{ token: i1.DaterService }, { token: i2.MaterialgrammiService }], target: i0.ɵɵFactoryTarget.Component }); CalendarComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.0.3", type: CalendarComponent, selector: "mg-calendar", inputs: { abbreviation: "abbreviation", bookEvents: "bookEvents", theme: "theme", disabled: "disabled", size: "size", disabledRange: "disabledRange", events: "events", format: "format", icons: "icons", controls: "controls", class: "class" }, outputs: { dayIsClicked: "dayIsClicked", dayDrop: "dayDrop", newEvent: "newEvent" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"calendar\" [ngClass]=\"(toggleEvent == true ? theme + ' activatedEvent' : theme) + ' ' + class\">\n <div class=\"month-wrapper\">\n <div class=\"month\" *ngFor=\"let month of months; let i = index\" [ngClass]=\"i == inView.month ? 'active': ''\">\n <div class=\"calendar-info\" *ngIf=\"controls\">\n <div class=\"previous-year\">\n <a (click)=\"prevYear()\" [innerHtml]=\"icons.year.previous\"></a>\n </div>\n <div class=\"previous-month\">\n <a (click)=\"prevMonth()\" [innerHtml]=\"icons.month.previous\"></a>\n </div>\n <div class=\"month-name\">\n <span class=\"monthSpan\">{{month}}</span><span class=\"yearName\">{{inView.year}}</span>\n </div>\n <div class=\"next-month\">\n <a (click)=\"nextMonth()\" [innerHtml]=\"icons.month.next\"></a>\n </div>\n <div class=\"next-year\">\n <a (click)=\"nextYear() \" [innerHtml]=\"icons.year.next\"></a>\n </div>\n </div>\n <div class=\"weekdays\">\n <p *ngFor=\"let wkday of weekDays\">{{wkday}}</p>\n </div>\n <div class=\"month-days\">\n <ng-container *ngFor=\"let d of days[i].dates\">\n <mg-dropable (dataRecieved)=\"updateOnDay($event)\" (onEvent)=\"handleDropZone($event, {date: d.num, month: d.month, year: inView.year})\">\n <div class=\"day\" [ngClass]=\"dayClass(d.num, d.month, inView.year, d.disabled)\"\n (click)=\"clickOnDay(d.num, d.month, inView.year, d.disabled)\">\n <ng-container *ngIf=\"d.num == 0\"></ng-container>\n <ng-container *ngIf=\"d.num != 0\">{{d.num}}</ng-container>\n </div>\n </mg-dropable>\n </ng-container>\n </div>\n </div>\n </div>\n <div class=\"event-details\">\n <ng-container *ngIf=\"toggleSelect.data\">\n <ng-container *ngFor=\"let eventData of toggleSelect.data\">\n <div class=\"event-info-wrapper\">\n <mg-dragable [draggable]=\"true\" [data]=\"eventData\">\n <div class=\"event-detail-title\" [innerHtml]=\"eventData.name\"></div>\n <div class=\"event-detail-date\" [innerHtml]=\"eventData.date\"></div>\n </mg-dragable>\n \n <div class=\"event-detail-description\" [innerHtml]=\"eventData.description\"></div>\n </div>\n </ng-container>\n </ng-container>\n </div>\n </div>\n\n <mg-overlay bgClass=\"grey2\" [id]=\"id\" canvasPosition=\"bottom\" offSize=\"2\" [active]=\"activateNewEvent\" (isClosed)=\"closeNewEvent()\">\n <div class=\"pad-10\">\n <h2 class=\"text-grey8 marginV-15\">Book an event on <small class=\"font-15 text-red8\">{{ clickedOn }}</small> </h2>\n <div class=\"row col m12 l12 s12\">\n <mg-input label=\"Event Name\" fStyle=\"material\" class=\"marginT-5\" (keyup)=\"setBookEvent($event, 'name')\"></mg-input>\n </div>\n <div class=\"row col m12 l12 s12\">\n <mg-text label=\"Event Description\" fStyle=\"material\" class=\"margin-5\" (keyup)=\"setBookEvent($event, 'desc')\"></mg-text>\n </div>\n <div class=\"col m12 l12 s12 text-right\">\n <mg-button (click)=\"createNewEvent()\" theme=\"success\">Book an event <i class=\"fas fa-angle-double-right\"></i></mg-button>\n </div>\n </div>\n </mg-overlay>", styles: [""], components: [{ type: i3.DropableComponent, selector: "mg-dropable", inputs: ["dropFiles", "class"], outputs: ["onEvent", "dataRecieved"] }, { type: i4.DragableComponent, selector: "mg-dragable", inputs: ["dragable", "data", "class"], outputs: ["onEvent"] }, { type: i5.OverlayComponent, selector: "mg-overlay", inputs: ["bgClass", "overlayClass", "offSize", "canvasPosition", "id", "active"], outputs: ["isClosed"] }, { type: i6.InputComponent, selector: "mg-input", inputs: ["theme", "form", "placeholder", "control", "type", "dark", "class", "value", "rounded", "filled", "info"], outputs: ["data", "isFocused", "keyup"] }, { type: i7.TextInputComponent, selector: "mg-text", inputs: ["theme", "form", "dark", "value", "control", "filled", "info"], outputs: ["data", "isFocused", "keyup"] }, { type: i8.ButtonComponent, selector: "mg-button", inputs: ["taskType", "btnStyle", "task", "target", "theme", "class", "btnSize", "isBlock", "round", "allowMargin", "allowShrink", "options", "isExternalLink", "newTab"], outputs: ["clicked", "active"] }], directives: [{ type: i9.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { type: i9.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i9.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.3", ngImport: i0, type: CalendarComponent, decorators: [{ type: Component, args: [{ selector: 'mg-calendar', template: "<div class=\"calendar\" [ngClass]=\"(toggleEvent == true ? theme + ' activatedEvent' : theme) + ' ' + class\">\n <div class=\"month-wrapper\">\n <div class=\"month\" *ngFor=\"let month of months; let i = index\" [ngClass]=\"i == inView.month ? 'active': ''\">\n <div class=\"calendar-info\" *ngIf=\"controls\">\n <div class=\"previous-year\">\n <a (click)=\"prevYear()\" [innerHtml]=\"icons.year.previous\"></a>\n </div>\n <div class=\"previous-month\">\n <a (click)=\"prevMonth()\" [innerHtml]=\"icons.month.previous\"></a>\n </div>\n <div class=\"month-name\">\n <span class=\"monthSpan\">{{month}}</span><span class=\"yearName\">{{inView.year}}</span>\n </div>\n <div class=\"next-month\">\n <a (click)=\"nextMonth()\" [innerHtml]=\"icons.month.next\"></a>\n </div>\n <div class=\"next-year\">\n <a (click)=\"nextYear() \" [innerHtml]=\"icons.year.next\"></a>\n </div>\n </div>\n <div class=\"weekdays\">\n <p *ngFor=\"let wkday of weekDays\">{{wkday}}</p>\n </div>\n <div class=\"month-days\">\n <ng-container *ngFor=\"let d of days[i].dates\">\n <mg-dropable (dataRecieved)=\"updateOnDay($event)\" (onEvent)=\"handleDropZone($event, {date: d.num, month: d.month, year: inView.year})\">\n <div class=\"day\" [ngClass]=\"dayClass(d.num, d.month, inView.year, d.disabled)\"\n (click)=\"clickOnDay(d.num, d.month, inView.year, d.disabled)\">\n <ng-container *ngIf=\"d.num == 0\"></ng-container>\n <ng-container *ngIf=\"d.num != 0\">{{d.num}}</ng-container>\n </div>\n </mg-dropable>\n </ng-container>\n </div>\n </div>\n </div>\n <div class=\"event-details\">\n <ng-container *ngIf=\"toggleSelect.data\">\n <ng-container *ngFor=\"let eventData of toggleSelect.data\">\n <div class=\"event-info-wrapper\">\n <mg-dragable [draggable]=\"true\" [data]=\"eventData\">\n <div class=\"event-detail-title\" [innerHtml]=\"eventData.name\"></div>\n <div class=\"event-detail-date\" [innerHtml]=\"eventData.date\"></div>\n </mg-dragable>\n \n <div class=\"event-detail-description\" [innerHtml]=\"eventData.description\"></div>\n </div>\n </ng-container>\n </ng-container>\n </div>\n </div>\n\n <mg-overlay bgClass=\"grey2\" [id]=\"id\" canvasPosition=\"bottom\" offSize=\"2\" [active]=\"activateNewEvent\" (isClosed)=\"closeNewEvent()\">\n <div class=\"pad-10\">\n <h2 class=\"text-grey8 marginV-15\">Book an event on <small class=\"font-15 text-red8\">{{ clickedOn }}</small> </h2>\n <div class=\"row col m12 l12 s12\">\n <mg-input label=\"Event Name\" fStyle=\"material\" class=\"marginT-5\" (keyup)=\"setBookEvent($event, 'name')\"></mg-input>\n </div>\n <div class=\"row col m12 l12 s12\">\n <mg-text label=\"Event Description\" fStyle=\"material\" class=\"margin-5\" (keyup)=\"setBookEvent($event, 'desc')\"></mg-text>\n </div>\n <div class=\"col m12 l12 s12 text-right\">\n <mg-button (click)=\"createNewEvent()\" theme=\"success\">Book an event <i class=\"fas fa-angle-double-right\"></i></mg-button>\n </div>\n </div>\n </mg-overlay>", styles: [""] }] }], ctorParameters: function () { return [{ type: i1.DaterService }, { type: i2.MaterialgrammiService }]; }, propDecorators: { abbreviation: [{ type: Input }], bookEvents: [{ type: Input }], theme: [{ type: Input }], disabled: [{ type: Input }], size: [{ type: Input }], disabledRange: [{ type: Input }], events: [{ type: Input }], format: [{ type: Input }], icons: [{ type: Input }], controls: [{ type: Input }], class: [{ type: Input }], dayIsClicked: [{ type: Output }], dayDrop: [{ type: Output }], newEvent: [{ type: Output }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FsZW5kYXIuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbWF0ZXJpYWxncmFtbWkvc3JjL2xpYi9jb21wb25lbnRzL2NhbGVuZGFyL2NhbGVuZGFyLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL21hdGVyaWFsZ3JhbW1pL3NyYy9saWIvY29tcG9uZW50cy9jYWxlbmRhci9jYWxlbmRhci5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLFlBQVksRUFBRSxLQUFLLEVBQXFCLE1BQU0sRUFBaUIsTUFBTSxlQUFlLENBQUM7Ozs7Ozs7Ozs7O0FBV3pHLE1BQU0sT0FBTyxpQkFBaUI7SUE4RjVCLFlBQW9CLEtBQW1CLEVBQVUsT0FBOEI7UUFBM0QsVUFBSyxHQUFMLEtBQUssQ0FBYztRQUFVLFlBQU8sR0FBUCxPQUFPLENBQXVCO1FBNUZ0RSxpQkFBWSxHQUFHLEtBQUssQ0FBQztRQUNyQixlQUFVLEdBQUcsS0FBSyxDQUFDO1FBQ25CLFVBQUssR0FBVSxTQUFTLENBQUM7UUFDekIsYUFBUSxHQUFhLEVBQUUsQ0FBQztRQUN4QixTQUFJLEdBQUcsQ0FBQyxDQUFDO1FBQ1Qsa0JBQWEsR0FBa0I7WUFDdEMsTUFBTSxFQUFFLEtBQUs7WUFDYixLQUFLLEVBQUUsS0FBSztTQUNiLENBQUM7UUFDRixvQkFBb0I7UUFDWCxXQUFNLEdBQVEsQ0FBQztnQkFDdEIsSUFBSSxFQUFFLGtCQUFrQjtnQkFDeEIsSUFBSSxFQUFFLDBCQUEwQjtnQkFDaEMsV0FBVyxFQUFFLDZIQUE2SDtnQkFDMUksSUFBSSxFQUFFLElBQUk7YUFDWCxFQUFFO2dCQUNELElBQUksRUFBRSxNQUFNO2dCQUNaLElBQUksRUFBRSwwQkFBMEI7Z0JBQ2hDLFdBQVcsRUFBRSw2SEFBNkg7Z0JBQzFJLElBQUksRUFBRSxJQUFJO2FB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bEIsQ0FBQztZQUNGLElBQUksV0FBVyxFQUFFO2dCQUNmLElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDO2dCQUN4QixJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksR0FBRyxXQUFXLENBQUM7YUFDdEM7aUJBQU07Z0JBQ0wsSUFBSSxDQUFDLFdBQVcsR0FBRyxLQUFLLENBQUM7YUFDMUI7U0FDRjtJQUNILENBQUM7OzhHQTVYVSxpQkFBaUI7a0dBQWpCLGlCQUFpQiwrWUNYOUIsKzNHQWlFZTsyRkR0REYsaUJBQWlCO2tCQUw3QixTQUFTOytCQUNFLGFBQWE7dUlBTWQsWUFBWTtzQkFBcEIsS0FBSztnQkFDRyxVQUFVO3NCQUFsQixLQUFLO2dCQUNHLEtBQUs7c0JBQWIsS0FBSztnQkFDRyxRQUFRO3NCQUFoQixLQUFLO2dCQUNHLElBQUk7c0JBQVosS0FBSztnQkFDRyxhQUFhO3NCQUFyQixLQUFLO2dCQUtHLE1BQU07c0JBQWQsS0FBSztnQkFxQkcsTUFBTTtzQkFBZCxLQUFLO2dCQUNHLEtBQUs7c0JBQWIsS0FBSztnQkFVRyxRQUFRO3NCQUFoQixLQUFLO2dCQUNHLEtBQUs7c0JBQWIsS0FBSztnQkFFSSxZQUFZO3NCQUFyQixNQUFNO2dCQUNHLE9BQU87c0JBQWhCLE1BQU07Z0JBQ0csUUFBUTtzQkFBakIsTUFBTSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgRXZlbnRFbWl0dGVyLCBJbnB1dCwgT25DaGFuZ2VzLCBPbkluaXQsIE91dHB1dCwgU2ltcGxlQ2hhbmdlcyB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgRGF0ZXJTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vZGF0ZXIuc2VydmljZSc7XG5pbXBvcnQgeyBEaXNhYmxlZFJhbmdlIH0gZnJvbSAnLi4vLi4vaW50ZXJmYWNlcyc7XG5pbXBvcnQgeyBNYXRlcmlhbGdyYW1taVNlcnZpY2UgfSBmcm9tICcuLi8uLi9tYXRlcmlhbGdyYW1taS5zZXJ2aWNlJztcbmltcG9ydCB7IFRoZW1lIH0gZnJvbSAnLi4vLi4vdHlwZXMnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdtZy1jYWxlbmRhcicsXG4gIHRlbXBsYXRlVXJsOiAnLi9jYWxlbmRhci5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL2NhbGVuZGFyLmNvbXBvbmVudC5jc3MnXVxufSlcbmV4cG9ydCBjbGFzcyBDYWxlbmRhckNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgT25DaGFuZ2VzIHtcblxuICBASW5wdXQoKSBhYmJyZXZpYXRpb24gPSBmYWxzZTtcbiAgQElucHV0KCkgYm9va0V2ZW50cyA9IGZhbHNlO1xuICBASW5wdXQoKSB0aGVtZTogVGhlbWUgPSBcInByaW1hcnlcIjtcbiAgQElucHV0KCkgZGlzYWJsZWQ6IHN0cmluZ1tdID0gW107XG4gIEBJbnB1dCgpIHNpemUgPSAxO1xuICBASW5wdXQoKSBkaXNhYmxlZFJhbmdlOiBEaXNhYmxlZFJhbmdlID0ge1xuICAgIGJlZm9yZTogZmFsc2UsXG4gICAgYWZ0ZXI6IGZhbHNlXG4gIH07XG4gIC8vIFwiMzEgSmFudWFyeSAyMDIyXCJcbiAgQElucHV0KCkgZXZlbnRzOiBhbnkgPSBbe1xuICAgIG5hbWU6IFwiTWVldGluZyB3aXRoIEFsaVwiLFxuICAgIGRhdGU6IFwiMTcgSmFudWFyeSAyMDIyIDA4OjAwIFBNXCIsXG4gICAgZGVzY3JpcHRpb246IFwiTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVyIGFkaXBpc2NpbmcgZWxpdCwgc2VkIGRvIGVpdXNtb2QgdGVtcG9yIGluY2lkaWR1bnQgdXQgbGFib3JlIGV0IGRvbG9yZSBtYWduYSBhbGlxdWEuXCIsXG4gICAgYnV6ejogdHJ1ZVxuICB9LCB7XG4gICAgbmFtZTogXCJQVUJHXCIsXG4gICAgZGF0ZTogXCIxNyBKYW51YXJ5IDIwMjIgMTA6MDAgUE1cIixcbiAgICBkZXNjcmlwdGlvbjogXCJMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2VjdGV0dXIgYWRpcGlzY2luZyBlbGl0LCBzZWQgZG8gZWl1c21vZCB0ZW1wb3IgaW5jaWRpZHVudCB1dCBsYWJvcmUgZXQgZG9sb3JlIG1hZ25hIGFsaXF1YS5cIixcbiAgICBidXp6OiB0cnVlXG4gIH0sIHtcbiAgICBuYW1lOiBcIlBIUFwiLFxuICAgIGRhdGU6IFwiMTggSmFudWFyeSAyMDIyIDEwOjAwIFBNXCIsXG4gICAgZGVzY3JpcHRpb246IFwiTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVyIGFkaXBpc2NpbmcgZWxpdCwgc2VkIGRvIGVpdXNtb2QgdGVtcG9yIGluY2lkaWR1bnQgdXQgbGFib3JlIGV0IGRvbG9yZSBtYWduYSBhbGlxdWEuXCIsXG4gICAgYnV6ejogZmFsc2VcbiAgfSwge1xuICAgIG5hbWU6IFwiQmlydGhkYXkgUGFydHlcIixcbiAgICBkYXRlOiBcIjIwIEZlYnJ1YXJ5IDIwMjIgMTA6MDAgUE1cIixcbiAgICBkZXNjcmlwdGlvbjogXCJMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2VjdGV0dXIgYWRpcGlzY2luZyBlbGl0LCBzZWQgZG8gZWl1c21vZCB0ZW1wb3IgaW5jaWRpZHVudCB1dCBsYWJvcmUgZXQgZG9sb3JlIG1hZ25hIGFsaXF1YS5cIixcbiAgICBidXp6OiB0cnVlXG4gIH1dO1xuICBASW5wdXQoKSBmb3JtYXQgPSBcImRkLU1NLXl5eXlcIjtcbiAgQElucHV0KCkgaWNvbnMgPSB7XG4gICAgbW9udGg6IHtcbiAgICAgIG5leHQ6IGA8aSBjbGFzcz1cImZhcyBmYS1hbmdsZS1yaWdodFwiPjwvaT5gLFxuICAgICAgcHJldmlvdXM6IGA8aSBjbGFzcz1cImZhcyBmYS1hbmdsZS1sZWZ0XCI+PC9pPmBcbiAgICB9LFxuICAgIHllYXI6IHtcbiAgICAgIG5leHQ6IGA8aSBjbGFzcz1cImZhcyBmYS1hbmdsZS1kb3VibGUtcmlnaHRcIj48L2k+YCxcbiAgICAgIHByZXZpb3VzOiBgPGkgY2xhc3M9XCJmYXMgZmEtYW5nbGUtZG91YmxlLWxlZnRcIj48L2k+YFxuICAgIH1cbiAgfTtcbiAgQElucHV0KCkgY29udHJvbHMgPSB0cnVlO1xuICBASW5wdXQoKSBjbGFzcyA9IFwiXCI7XG5cbiAgQE91dHB1dCgpIGRheUlzQ2xpY2tlZCA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcbiAgQE91dHB1dCgpIGRheURyb3AgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG4gIEBPdXRwdXQoKSBuZXdFdmVudCA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcblxuICBtb250aHNfbG9uZzogYW55O1xuICBtb250aHNfc2hvcnQ6IGFueTtcblxuICBtb250aHM6IGFueTtcblxuICB3ZWVrRGF5cyA9IFtcbiAgICBcIlN1blwiLFxuICAgIFwiTW9uXCIsXG4gICAgXCJUdWVcIixcbiAgICBcIldlZFwiLFxuICAgIFwiVGh1XCIsXG4gICAgXCJGcmlcIixcbiAgICBcIlNhdFwiXG4gIF07XG5cbiAgZGF5czogYW55ID0gW107XG4gIHRvZ2dsZUV2ZW50ID0gZmFsc2U7XG5cblxuICBjdXJyZW50OiBhbnkgPSB7fVxuXG4gIGluVmlldzogYW55ID0ge307XG5cbiAgdG9nZ2xlU2VsZWN0OiBhbnkgPSBmYWxzZTtcblxuICBpc0hvdmVyZWRXaXRoRGF0YSA9IFwiXCI7XG5cbiAgaWQgPSBcIlwiO1xuXG4gIGFjdGl2YXRlTmV3RXZlbnQgPSBmYWxzZTtcblxuICBjbGlja2VkT24gPSBcIlwiO1xuXG4gIGJvb2tFdmVudCA9IHtcbiAgICBuYW1lOiBcIlwiLFxuICAgIGRlc2NyaXB0aW9uOiBcIlwiLFxuICAgIG9uOiA8YW55Pnt9XG4gIH07XG5cbiAgZHJvcHBlZERhdGE6IGFueSA9IHt9O1xuXG4gIGRyb3BPbkRhdGU6IGFueSA9IHt9O1xuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgZGF0ZXI6IERhdGVyU2VydmljZSwgcHJpdmF0ZSBzZXJ2aWNlOiBNYXRlcmlhbGdyYW1taVNlcnZpY2UpIHsgfVxuXG4gIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIHRoaXMuZXhlY3V0ZUFsbCgpO1xuICAgIHRoaXMuaWQgPSB0aGlzLnNlcnZpY2UubWFrZWlkKDQsIFwiY3JlYXRlTmV3RXZlbnRPdmVybGF5XCIpO1xuICB9XG5cbiAgbmdPbkNoYW5nZXMoKTogdm9pZCB7XG4gICAgY29uc29sZS5sb2coXCJEaXNhYmxlZD8gXCIsIHRoaXMuZGlzYWJsZWRSYW5nZSk7XG4gICAgdGhpcy5leGVjdXRlQWxsKCk7XG4gIH1cblxuICBleGVjdXRlQWxsKCkge1xuICAgIHRoaXMuaW5pdGlhbGl6ZVN0YXRlcygpO1xuICAgIHRoaXMudXBkYXRlRGF5cyh0aGlzLmluVmlldy55ZWFyKTtcbiAgICB0aGlzLmZvcm1hdEV2ZW50RGF0ZXMoKTtcbiAgfVxuXG4gIGluaXRpYWxpemVTdGF0ZXMoKSB7XG4gICAgdGhpcy5jdXJyZW50ID0ge1xuICAgICAgbW9udGg6IHRoaXMuZGF0ZXIuZ2V0TW9udGgoKSxcbiAgICAgIG1vbnRoSW5Xb3JkczogdGhpcy5kYXRlci5nZXRNb250aHModGhpcy5kYXRlci5nZXRNb250aCgpKSxcbiAgICAgIGRhdGU6IHRoaXMuZGF0ZXIuZ2V0RGF0ZSgpLFxuICAgICAgeWVhcjogdGhpcy5kYXRlci5nZXRZZWFyKCksXG4gICAgICBkYXlJbk51bTogdGhpcy5kYXRlci5nZXREYXkoKSxcbiAgICAgIHdlZWtEYXk6IHRoaXMuZGF0ZXIuZ2V0V2Vla0RheSgpLFxuICAgICAgaG91cjogdGhpcy5kYXRlci5nZXRIb3VyKCksXG4gICAgICBtaW46IHRoaXMuZGF0ZXIuZ2V0TWludXRlKCksXG4gICAgICBzZWM6IHRoaXMuZGF0ZXIuZ2V0U2Vjb25kcygpXG4gICAgfTtcbiAgICB0aGlzLm1vbnRoc19sb25nID0gdGhpcy5kYXRlci5nZXRNb250aHNMb25nKCk7XG4gICAgdGhpcy5tb250aHNfc2hvcnQgPSB0aGlzLmRhdGVyLmdldE1vbnRocygpO1xuXG4gICAgdGhpcy5tb250aHMgPSB0aGlzLmFiYnJldmlhdGlvbiA/IHRoaXMubW9udGhzX3Nob3J0IDogdGhpcy5tb250aHNfbG9uZztcbiAgICB0aGlzLmluVmlldyA9IHtcbiAgICAgIG1vbnRoOiB0aGlzLmN1cnJlbnQubW9udGgsXG4gICAgICB5ZWFyOiB0aGlzLmN1cnJlbnQueWVhclxuICAgIH07XG4gIH1cblxuICBmb3JtYXRFdmVudERhdGVzKCkge1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5ldmVudHMubGVuZ3RoOyBpKyspIHtcbiAgICAgIHRoaXMuZXZlbnRzW2ldLmRhdGVPYmplY3QgPSB7XG4gICAgICAgIGRhdGU6IHRoaXMuZGF0ZXIuZ2V0RGF0ZSh0aGlzLmRhdGVyLmRhdGVyKHRoaXMuZXZlbnRzW2ldLmRhdGUpKSxcbiAgICAgICAgbW9udGg6IHRoaXMuZGF0ZXIuZ2V0TW9udGgodGhpcy5kYXRlci5kYXRlcih0aGlzLmV2ZW50c1tpXS5kYXRlKSksXG4gICAgICAgIHllYXI6IHRoaXMuZGF0ZXIuZ2V0WWVhcih0aGlzLmRhdGVyLmRhdGVyKHRoaXMuZXZlbnRzW2ldLmRhdGUpKVxuICAgICAgfTtcbiAgICB9XG4gIH1cblxuICBpc0Rpc2FibGVkKGQ6IG51bWJlciwgbTogbnVtYmVyLCB5OiBudW1iZXIpIHtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuZGlzYWJsZWQubGVuZ3RoOyBpKyspIHtcbiAgICAgIGxldCBkaXNhYmxlZF9kYXRlID0gdGhpcy5kYXRlci5kYXRlcih0aGlzLmRpc2FibGVkW2ldKTtcbiAgICAgIGlmIChkID09IHRoaXMuZGF0ZXIuZ2V0RGF0ZShkaXNhYmxlZF9kYXRlKSAmJiAobSAtIDEpID09IHRoaXMuZGF0ZXIuZ2V0TW9udGgoZGlzYWJsZWRfZGF0ZSkgJiYgeSA9PSB0aGlzLmRhdGVyLmdldFllYXIoZGlzYWJsZWRfZGF0ZSkpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgcHVzaERpc2FibGVkKGQ6IG51bWJlciwgbTogbnVtYmVyLCB5OiBudW1iZXIpIHtcbiAgICBsZXQgZGF0ZSA9IGAke2R9ICR7dGhpcy5tb250aHNbbSAtIDFdfSAke3l9YDtcbiAgICBpZiAodHlwZW9mIHRoaXMuZGlzYWJsZWRSYW5nZS5hZnRlciA9PSBcInN0cmluZ1wiICYmXG4gICAgICB0aGlzLmRhdGVyLmlzR3JlYXRlcihkYXRlLCB0aGlzLmRpc2FibGVkUmFuZ2UuYWZ0ZXIpICYmXG4gICAgICAhdGhpcy5kaXNhYmxlZC5pbmNsdWRlcyhkYXRlKSkge1xuICAgICAgdGhpcy5kaXNhYmxlZC5wdXNoKGRhdGUpO1xuICAgIH1cbiAgICBpZiAodHlwZW9mIHRoaXMuZGlzYWJsZWRSYW5nZS5iZWZvcmUgPT0gXCJzdHJpbmdcIiAmJlxuICAgICAgdGhpcy5kYXRlci5pc0xlc3NUaGFuKGRhdGUsIHRoaXMuZGlzYWJsZWRSYW5nZS5iZWZvcmUpICYmXG4gICAgICAhdGhpcy5kaXNhYmxlZC5pbmNsdWRlcyhkYXRlKSkge1xuICAgICAgdGhpcy5kaXNhYmxlZC5wdXNoKGRhdGUpO1xuICAgIH1cbiAgfVxuXG5cbiAgdXBkYXRlRGF5cyh5ZWFyOiBudW1iZXIgPSB0aGlzLmN1cnJlbnQueWVhcikge1xuICAgIHRoaXMuZGF5cyA9IFtdO1xuICAgIGZvciAobGV0IGkgPSAxOyBpIDwgdGhpcy5tb250aHMubGVuZ3RoICsgMTsgaSsrKSB7XG4gICAgICBsZXQgb25Nb250aDogYW55ID0ge307XG4gICAgICBsZXQgZmlyc3REYXRlID0gdGhpcy5kYXRlci5kYXRlcihgMS0ke3RoaXMubW9udGhzW2kgLSAxXX0tJHt5ZWFyfWApO1xuICAgICAgb25Nb250aC50b3RhbERheXMgPSB0aGlzLmRhdGVyLmRheXNJbk1vbnRoKGksIHllYXIpO1xuICAgICAgb25Nb250aC5uYW1lID0gdGhpcy5tb250aHNbaSAtIDFdO1xuICAgICAgb25Nb250aC5tb250aCA9IGk7XG4gICAgICBvbk1vbnRoLmRhdGVzID0gW107XG4gICAgICBvbk1vbnRoLnN0YXJ0RGF5ID0gdGhpcy5kYXRlci5nZXREYXkoZmlyc3REYXRlKTtcblxuICAgICAgZm9yIChsZXQgayA9IDA7IGsgPCBvbk1vbnRoLnN0YXJ0RGF5OyBrKyspIHtcbiAgICAgICAgbGV0IG15RGFZID0ge1xuICAgICAgICAgIG51bTogMCxcbiAgICAgICAgICB3ZWVrZGF5OiB0aGlzLndlZWtEYXlzW2tdLFxuICAgICAgICAgIHdlZWtEYXlOdW06IGssXG4gICAgICAgICAgbW9udGg6IGksXG4gICAgICAgICAgZGlzYWJsZWQ6IGZhbHNlXG4gICAgICAgIH07XG4gICAgICAgIG9uTW9udGguZGF0ZXMucHVzaChteURhWSk7XG5cbiAgICAgIH1cbiAgICAgIGZvciAobGV0IGogPSAxOyBqIDw9IG9uTW9udGgudG90YWxEYXlzOyBqKyspIHtcbiAgICAgICAgdGhpcy5wdXNoRGlzYWJsZWQoaiwgaSwgeWVhcik7XG4gICAgICAgIGxldCBteWRhdGUgPSB0aGlzLmRhdGVyLmRhdGVyKGAke2p9ICR7dGhpcy5tb250aHNbaSAtIDFdfSAke3llYXJ9YCk7XG4gICAgICAgIGxldCBteURhWSA9IHtcbiAgICAgICAgICBudW06IGosXG4gICAgICAgICAgd2Vla2RheTogdGhpcy53ZWVrRGF5c1t0aGlzLmRhdGVyLmdldERheShteWRhdGUpXSxcbiAgICAgICAgICB3ZWVrRGF5TnVtOiB0aGlzLmRhdGVyLmdldERheShteWRhdGUpLFxuICAgICAgICAgIG1vbnRoOiBpLFxuICAgICAgICAgIGRpc2FibGVkOiB0aGlzLmlzRGlzYWJsZWQoaiwgaSwgeWVhcilcbiAgICAgICAgfTtcbiAgICAgICAgb25Nb250aC5kYXRlcy5wdXNoKG15RGFZKTtcbiAgICAgIH1cbiAgICAgIHRoaXMuZGF5cy5wdXNoKG9uTW9udGgpO1xuICAgIH1cbiAgfVxuXG4gIGlzRXZlbnRlZChkOiBudW1iZXIsIG06IG51bWJlciwgeTogbnVtYmVyKSB7XG4gICAgbGV0IGFsbEV2ZW50czogYW55ID0gW107XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLmV2ZW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgaWYgKGQgPT09IHRoaXMuZXZlbnRzW2ldLmRhdGVPYmplY3QuZGF0ZSAmJiAobSAtIDEpID09PSB0aGlzLmV2ZW50c1tpXS5kYXRlT2JqZWN0Lm1vbnRoICYmIHkgPT09IHRoaXMuZXZlbnRzW2ldLmRhdGVPYmplY3QueWVhcikge1xuICAgICAgICBhbGxFdmVudHMucHVzaCh0aGlzLmV2ZW50c1tpXSk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBhbGxFdmVudHMubGVuZ3RoID4gMCA/IGFsbEV2ZW50cyA6IGZhbHNlO1xuICB9XG5cbiAgZG9CdXp6KGV2ZW50RGV0YWlsczogYW55ID0gW10pIHtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGV2ZW50RGV0YWlscy5sZW5ndGg7IGkrKykge1xuICAgICAgaWYgKGV2ZW50RGV0YWlsc1tpXS5idXp6KSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBnZXRTaXplKCkge1xuICAgIGlmICh0aGlzLnNpemUgPT09IDEpIHtcbiAgICAgIHJldHVybiBcInBhZFYtMTBcIjtcbiAgICB9IGVsc2UgaWYgKHRoaXMuc2l6ZSA9PT0gMikge1xuICAgICAgcmV0dXJuIFwicGFkVi0yMFwiO1xuICAgIH0gZWxzZSBpZiAodGhpcy5zaXplID09PSAzKSB7XG4gICAgICByZXR1cm4gXCJwYWRWLTMwXCI7XG4gICAgfSBlbHNlIGlmICh0aGlzLnNpemUgPT09IDQpIHtcbiAgICAgIHJldHVybiBcInBhZFYtNDBcIjtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIFwicGFkVi01MFwiO1xuICAgIH1cbiAgfVxuXG4gIGRheUNsYXNzKGQ6IG51bWJlciwgbTogbnVtYmVyLCB5OiBudW1iZXIsIGRpc2FibGVkID0gZmFsc2UpIHtcbiAgICBsZXQgcmVzdWx0cyA9IFwiXCI7XG4gICAgcmVzdWx0cyArPSBgICR7dGhpcy5nZXRTaXplKCl9YDtcbiAgICByZXN1bHRzICs9IHRoaXMuZHJvcHpvbmVDbGFzcyhkLCBtLCB5KSA/IFwiIHNjYWxlLTMgc2hhZG93LTMgb3V0bGluZS1ncmV5MTBcIiA6IFwiXCI7XG4gICAgcmVzdWx0cyArPSBkID09IDAgPyBcIiBkYXktZGlzYWJsZWRcIiA6IFwiXCI7XG4gICAgcmVzdWx0cyArPSBkID09IHRoaXMuY3VycmVudC5kYXRlICYmIG0gLSAxID09IHRoaXMuY3VycmVudC5tb250aCAmJiB5ID09IHRoaXMuY3VycmVudC55ZWFyID8gXCIgYWN0aXZlLWRheVwiIDogXCJcIjtcbiAgICBsZXQgZXZlbnRkZXRhaWxzID0gdGhpcy5pc0V2ZW50ZWQoZCwgbSwgeSk7XG4gICAgcmVzdWx0cyArPSAhZGlzYWJsZWQgJiYgZXZlbnRkZXRhaWxzID8gXCIgaGF2ZUV2ZW50XCIgOiBcIlwiO1xuICAgIHJlc3VsdHMgKz0gIWRpc2FibGVkICYmIHRoaXMuZG9CdXp6KGV2ZW50ZGV0YWlscykgPyBcIiBidXp6XCIgOiBcIlwiO1xuICAgIHJlc3VsdHMgKz0gZGlzYWJsZWQgPyBcIiBkYXktZGlhYmxlZFwiIDogXCJcIjtcbiAgICByZXR1cm4gcmVzdWx0cztcbiAgfVxuXG5cblxuICBuZXh0TW9udGgoKSB7XG4gICAgaWYgKHRoaXMuaW5WaWV3Lm1vbnRoID49IDExKSB7XG4gICAgICB0aGlzLmluVmlldy5tb250aCA9IDA7XG4gICAgICB0aGlzLm5leHRZZWFyKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuaW5WaWV3Lm1vbnRoKys7XG4gICAgfVxuICB9XG5cbiAgcHJldk1vbnRoKCkge1xuICAgIGlmICh0aGlzLmluVmlldy5tb250aCA8PSAwKSB7XG4gICAgICB0aGlzLmluVmlldy5tb250aCA9IDExO1xuICAgICAgdGhpcy5wcmV2WWVhcigpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmluVmlldy5tb250aC0tO1xuICAgIH1cbiAgfVxuXG5cblxuICBuZXh0WWVhcigpIHtcbiAgICB0aGlzLmluVmlldy55ZWFyKys7XG4gICAgdGhpcy51cGRhdGVEYXlzKHRoaXMuaW5WaWV3LnllYXIpO1xuICB9XG5cbiAgcHJldlllYXIoKSB7XG4gICAgdGhpcy5pblZpZXcueWVhci0tO1xuICAgIHRoaXMudXBkYXRlRGF5cyh0