@true-directive/grid
Version:
Angular Data Grid from Yopsilon.
330 lines • 37.8 kB
JavaScript
import * as tslib_1 from "tslib";
/**
* Copyright (c) 2018-2019 Aleksey Melnikov, True Directive Company.
* @link https://truedirective.com/
* @license MIT
*/
import { Component, Input, Output, ViewChild, ChangeDetectorRef, ElementRef, Renderer2, Inject, HostBinding, EventEmitter } from '@angular/core';
import { timer } from 'rxjs';
import { GridStateService } from './grid-state.service';
let ScrollerComponent = class ScrollerComponent {
constructor(state, elementRef, changeDetector, renderer) {
this.state = state;
this.elementRef = elementRef;
this.changeDetector = changeDetector;
this.renderer = renderer;
this.maxHeight = null;
this.autoscrollx = new EventEmitter();
this.scroll = new EventEmitter();
this.scrollX = 0;
this.scrollY = 0;
this.scrollTimer = null;
this.scrollSubscription = null;
this.autoScrollInProgress = false;
this.scrollSpeedX = 0;
this.scrollSpeedY = 0;
this._scrollRect = null;
}
get maxHeightU() {
if (this.maxHeight === null) {
return 'unset';
}
return this.maxHeight;
}
get autoWidth() {
return this.state.settings.columnAutoWidth;
}
get touchFix() {
return (this.state.iOS || this.state.android) && this.state.settings.enableTouchScroll;
}
get scrollerH() {
if (this.touchFix) {
return this.datah;
}
return this.data;
}
get scrollerV() {
if (this.touchFix) {
return this.dataArea;
}
return this.data;
}
get clientRect() {
return this.elementRef.nativeElement.getBoundingClientRect();
}
get centerRect() {
if (this.touchFix) {
return this.datah.nativeElement.getBoundingClientRect();
}
return this.data.nativeElement.getBoundingClientRect();
}
get headerRect() {
return this.header.nativeElement.getBoundingClientRect();
}
get headerRectLeft() {
return null;
}
get headerRectRight() {
return null;
}
dataScroll(e) {
this.doScroll(e);
this.scroll.emit(e);
}
dataScrollH(e) {
this.doScroll(e, true);
this.scroll.emit(e);
}
get isAutoScroll() {
return this.autoScrollInProgress;
}
get scrollTop() {
if (this.touchFix) {
return this.dataArea.nativeElement.scrollTop;
}
return this.data.nativeElement.scrollTop;
}
get scrollLeft() {
if (this.touchFix) {
return this.datah.nativeElement.scrollLeft;
}
return this.data.nativeElement.scrollLeft;
}
get scrollWidth() {
if (this.touchFix) {
return this.datah.nativeElement.scrollWidth;
}
return this.data.nativeElement.scrollWidth;
}
get scrollHeight() {
return this.data.nativeElement.scrollHeight;
}
get viewPortHeight() {
if (this.touchFix) {
return this.dataArea.nativeElement.clientHeight;
}
return this.data.nativeElement.clientHeight;
}
get viewPortWidth() {
if (this.touchFix) {
return this.dataArea.nativeElement.clientWidth;
}
else {
return this.data.nativeElement.clientWidth;
}
}
prepareAutoScroll() {
this._scrollRect = this.centerRect;
}
startAutoScroll() {
if (this.autoScrollInProgress) {
return;
}
if (!this.scrollTimer) {
this.scrollTimer = timer(this.state.st.autoScrollInterval, this.state.st.autoScrollInterval);
this.scrollSubscription = this.scrollTimer.subscribe((t) => this.scrollIfNeeded());
}
this.autoScrollInProgress = true;
}
stopAutoScroll() {
this._scrollRect = null;
this.scrollSpeedY = 0;
this.scrollSpeedX = 0;
if (this.scrollSubscription) {
this.scrollSubscription.unsubscribe();
this.scrollTimer = null;
}
this.autoScrollInProgress = false;
}
// Прокрутка при необходимости
scrollIfNeeded() {
const sl = this.scrollLeft;
const st = this.scrollTop;
const sw = this.scrollWidth;
const sh = this.scrollHeight;
let needSl = sl;
let needSt = st;
const r0 = this.elementRef.nativeElement.getBoundingClientRect();
if (this.scrollSpeedY < 0) {
// листаем влево
if (st >= -this.scrollSpeedY) {
needSt = st + this.scrollSpeedY;
}
else {
needSt = 0;
}
}
if (this.scrollSpeedY > 0) {
// листаем вправо
const maxScrollTop = sh - this.scrollerV.nativeElement.clientHeight;
if (sl <= (maxScrollTop - this.scrollSpeedY)) {
needSt = st + this.scrollSpeedY;
}
else {
needSt = maxScrollTop;
}
}
if (st !== needSt) {
this.scrollerV.nativeElement.scrollTop = needSt;
return; // По двум направлениям не будем это делать
}
if (this.scrollSpeedX < 0) {
// листаем влево
if (sl >= -this.scrollSpeedX) {
needSl = sl + this.scrollSpeedX;
}
else {
needSl = 0;
}
}
if (this.scrollSpeedX > 0) {
// листаем вправо
const maxScrollLeft = sw - this.scrollerH.nativeElement.clientWidth;
if (sl <= (maxScrollLeft - this.scrollSpeedX)) {
needSl = sl + this.scrollSpeedX;
}
else {
needSl = maxScrollLeft;
}
}
if (sl !== needSl) {
this.scrollerH.nativeElement.scrollLeft = needSl;
this.autoscrollx.emit(needSl - sl);
}
}
scrollTo(x, y = -1) {
if (y >= 0) {
this.scrollerV.nativeElement.scrollTop = y;
}
if (x >= 0) {
this.scrollerH.nativeElement.scrollLeft = x;
}
}
// После сжатия контента возможны отрицательные значения ScrollLeft. Здесь мы
// проверим и исправим это...
fixScroll() {
if (this.scrollerH.nativeElement.scrollLeft < 0) {
this.scrollerH.nativeElement.scrollLeft = 0;
}
}
checkAutoScrollX(xx, checkParts = false) {
const r0 = this._scrollRect;
if (!r0) {
return null;
}
if (xx <= r0.left) {
// листаем влево
this.scrollSpeedX = -this.state.st.autoScrollStep;
}
else {
if (xx >= r0.right) {
// вправо
this.scrollSpeedX = this.state.st.autoScrollStep;
}
else {
this.scrollSpeedX = 0;
}
}
if (this.scrollSpeedX !== 0) {
this.startAutoScroll();
}
return r0;
}
checkAutoScrollY(yy) {
const r0 = this._scrollRect;
if (!r0) {
return null;
}
if (yy < r0.top) {
// листаем вверх
this.scrollSpeedY = -this.state.st.autoScrollStep;
}
else {
if (yy > r0.bottom) {
// вниз
this.scrollSpeedY = this.state.st.autoScrollStep;
}
else {
this.scrollSpeedY = 0;
}
}
if (this.scrollSpeedY !== 0) {
this.startAutoScroll();
}
}
scrollParts() { }
doScroll(e, h = false) {
const l = e.target;
if ((!this.touchFix || h) && this.scrollX !== l.scrollLeft) {
this.scrollX = l.scrollLeft;
if (this.state.settings.showHeader) {
this.header.nativeElement.scrollLeft = this.scrollX;
}
if (this.state.settings.showFooter) {
this.footer.nativeElement.scrollLeft = this.scrollX;
}
}
if (this.scrollY !== l.scrollTop) {
this.scrollParts();
}
}
focus() {
this.elementRef.nativeElement.focus();
}
};
tslib_1.__decorate([
ViewChild('header', { static: false }),
tslib_1.__metadata("design:type", Object)
], ScrollerComponent.prototype, "header", void 0);
tslib_1.__decorate([
ViewChild('dataArea', { static: true }),
tslib_1.__metadata("design:type", Object)
], ScrollerComponent.prototype, "dataArea", void 0);
tslib_1.__decorate([
ViewChild('data', { static: true }),
tslib_1.__metadata("design:type", Object)
], ScrollerComponent.prototype, "data", void 0);
tslib_1.__decorate([
ViewChild('datah', { static: true }),
tslib_1.__metadata("design:type", Object)
], ScrollerComponent.prototype, "datah", void 0);
tslib_1.__decorate([
ViewChild('footer', { static: false }),
tslib_1.__metadata("design:type", Object)
], ScrollerComponent.prototype, "footer", void 0);
tslib_1.__decorate([
Input('maxHeight'),
tslib_1.__metadata("design:type", String)
], ScrollerComponent.prototype, "maxHeight", void 0);
tslib_1.__decorate([
Output(),
tslib_1.__metadata("design:type", EventEmitter)
], ScrollerComponent.prototype, "autoscrollx", void 0);
tslib_1.__decorate([
Output(),
tslib_1.__metadata("design:type", EventEmitter)
], ScrollerComponent.prototype, "scroll", void 0);
tslib_1.__decorate([
HostBinding('class.true-v-scroll'),
tslib_1.__metadata("design:type", Object),
tslib_1.__metadata("design:paramtypes", [])
], ScrollerComponent.prototype, "autoWidth", null);
tslib_1.__decorate([
HostBinding('class.true-fix-touch'),
tslib_1.__metadata("design:type", Object),
tslib_1.__metadata("design:paramtypes", [])
], ScrollerComponent.prototype, "touchFix", null);
ScrollerComponent = tslib_1.__decorate([
Component({
selector: 'true-scroller',
template: "<div class=\"true-scroller-header-area\" *ngIf=\"state.settings.showHeader\">\r\n <div #header class=\"true-scroller-header\" [ngClass]=\"state.settings.appearance.headerAreaClass\">\r\n <ng-content select=\"[true-header]\"></ng-content>\r\n </div>\r\n</div>\r\n\r\n<div #dataArea class=\"true-scroller-data-area-scroller\" (scroll)=\"dataScroll($event)\">\r\n <div class=\"true-scroller-data-area\" [style.max-height]=\"maxHeightU\">\r\n <div #data class=\"true-scroller-data\" [ngClass]=\"state.sta.scrollboxClass\" (scroll)=\"dataScroll($event)\">\r\n <div #datah class=\"true-scroller-data-h\" (scroll)=\"dataScrollH($event)\">\r\n <ng-content select=\"[true-data]\"></ng-content>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<div class=\"true-scroller-footer-area\" *ngIf=\"state.settings.showFooter\">\r\n <div #footer class=\"true-scroller-footer\"\r\n [ngClass]=\"state.settings.appearance.footerAreaClass\" >\r\n <ng-content select=\"[true-footer]\"></ng-content>\r\n </div>\r\n</div>\r\n",
styles: [":host{overflow-y:hidden;display:-webkit-box;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;flex-direction:column;-webkit-box-pack:justify;justify-content:space-between;height:100%}:host:focus{outline:0}.true-scroller-footer-area,.true-scroller-header-area{overflow-x:hidden;flex-shrink:0;-webkit-box-flex:0;flex-grow:0;display:-webkit-box;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;flex-direction:row;height:auto}.true-scroller-hidden{height:0!important}.true-scroller-header{overflow-x:hidden;-webkit-box-flex:1;flex-grow:1;box-sizing:border-box}.true-scroller-data-area-scroller{-webkit-box-flex:1;flex:1 1 auto;overflow-y:hidden;-ms-grid-row-align:stretch;align-self:stretch;height:100%}.true-scroller-data-area{height:100%;overflow-x:hidden;display:-webkit-box;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;flex-direction:row;-webkit-box-pack:justify;justify-content:space-between;-webkit-box-align:stretch;align-items:stretch}.true-scroller-data{-webkit-box-flex:1;flex:1 1 auto;overflow-y:auto;overflow-x:auto;box-sizing:border-box;max-width:100%}.true-scroller-data-h{overflow-x:visible;-webkit-overflow-scrolling:touch}:host.true-v-scroll .true-scroller-data{overflow-x:hidden!important;overflow-y:scroll!important;-webkit-overflow-scrolling:touch}:host.true-v-scroll .true-scroller-data .true-scroller-data-h{overflow-x:hidden!important}.true-scroller-footer{overflow-x:hidden;-webkit-box-flex:1;flex-grow:1}:host.true-fix-touch:not(.true-v-scroll) .true-scroller-data-area-scroller{height:1px;overflow-y:auto;-webkit-overflow-scrolling:touch}:host.true-fix-touch .true-scroller-data-area{height:auto;min-height:100%;display:-webkit-box;align-content:stretch;-webkit-overflow-scrolling:touch}:host.true-fix-touch .true-scroller-data{overflow-x:hidden!important;overflow-y:hidden!important;display:-webkit-box;display:flex;-webkit-box-align:stretch;align-items:stretch;-webkit-box-pack:center;justify-content:center;-webkit-box-orient:horizontal;-webkit-box-direction:normal;flex-direction:row}:host.true-fix-touch:not(.true-v-scroll) .true-scroller-data-h{overflow-x:auto;-webkit-overflow-scrolling:touch}:host.true-fix-touch.true-v-scroll .true-scroller-data-area-scroller{overflow-y:scroll!important;-webkit-overflow-scrolling:touch}"]
}),
tslib_1.__param(0, Inject('gridState')),
tslib_1.__metadata("design:paramtypes", [GridStateService,
ElementRef,
ChangeDetectorRef,
Renderer2])
], ScrollerComponent);
export { ScrollerComponent };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2Nyb2xsZXIuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6Im5nOi8vQHRydWUtZGlyZWN0aXZlL2dyaWQvIiwic291cmNlcyI6WyJzcmMvc2Nyb2xsZXIuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTs7OztFQUlFO0FBQ0YsT0FBTyxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLFNBQVMsRUFBRSxpQkFBaUIsRUFDdEQsVUFBVSxFQUFFLFNBQVMsRUFBRSxNQUFNLEVBQUUsV0FBVyxFQUMxQyxZQUFZLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDN0MsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUU3QixPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQU94RCxJQUFhLGlCQUFpQixHQUE5QixNQUFhLGlCQUFpQjtJQXlVNUIsWUFDOEIsS0FBdUIsRUFDekMsVUFBc0IsRUFDdEIsY0FBaUMsRUFDakMsUUFBbUI7UUFIRCxVQUFLLEdBQUwsS0FBSyxDQUFrQjtRQUN6QyxlQUFVLEdBQVYsVUFBVSxDQUFZO1FBQ3RCLG1CQUFjLEdBQWQsY0FBYyxDQUFtQjtRQUNqQyxhQUFRLEdBQVIsUUFBUSxDQUFXO1FBM1R4QixjQUFTLEdBQVcsSUFBSSxDQUFDO1FBVWhDLGdCQUFXLEdBQXlCLElBQUksWUFBWSxFQUFVLENBQUM7UUFHL0QsV0FBTSxHQUFzQixJQUFJLFlBQVksRUFBTyxDQUFDO1FBWTFDLFlBQU8sR0FBRyxDQUFDLENBQUM7UUFDWixZQUFPLEdBQUcsQ0FBQyxDQUFDO1FBQ2QsZ0JBQVcsR0FBUSxJQUFJLENBQUM7UUFDeEIsdUJBQWtCLEdBQVEsSUFBSSxDQUFDO1FBRS9CLHlCQUFvQixHQUFHLEtBQUssQ0FBQztRQUU3QixpQkFBWSxHQUFHLENBQUMsQ0FBQztRQUNqQixpQkFBWSxHQUFHLENBQUMsQ0FBQztRQUVmLGdCQUFXLEdBQVEsSUFBSSxDQUFDO0lBd1JD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c0IsQ0FBQzs7O2lEQUduQztBQXpDVSxpQkFBaUI7SUFMN0IsU0FBUyxDQUFDO1FBQ1QsUUFBUSxFQUFFLGVBQWU7UUFDekIsK2hDQUF3Qzs7S0FFekMsQ0FBQztJQTJVRyxtQkFBQSxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUE7NkNBQWUsZ0JBQWdCO1FBQzdCLFVBQVU7UUFDTixpQkFBaUI7UUFDdkIsU0FBUztHQTdVcEIsaUJBQWlCLENBOFU3QjtTQTlVWSxpQkFBaUIiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcclxuICogQ29weXJpZ2h0IChjKSAyMDE4LTIwMTkgQWxla3NleSBNZWxuaWtvdiwgVHJ1ZSBEaXJlY3RpdmUgQ29tcGFueS5cclxuICogQGxpbmsgaHR0cHM6Ly90cnVlZGlyZWN0aXZlLmNvbS9cclxuICogQGxpY2Vuc2UgTUlUXHJcbiovXHJcbmltcG9ydCB7IENvbXBvbmVudCwgSW5wdXQsIE91dHB1dCwgVmlld0NoaWxkLCBDaGFuZ2VEZXRlY3RvclJlZixcclxuICAgICAgICAgRWxlbWVudFJlZiwgUmVuZGVyZXIyLCBJbmplY3QsIEhvc3RCaW5kaW5nLFxyXG4gICAgICAgICBFdmVudEVtaXR0ZXIgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgdGltZXIgfSBmcm9tICdyeGpzJztcclxuXHJcbmltcG9ydCB7IEdyaWRTdGF0ZVNlcnZpY2UgfSBmcm9tICcuL2dyaWQtc3RhdGUuc2VydmljZSc7XHJcblxyXG5AQ29tcG9uZW50KHtcclxuICBzZWxlY3RvcjogJ3RydWUtc2Nyb2xsZXInLFxyXG4gIHRlbXBsYXRlVXJsOiAnLi9zY3JvbGxlci5jb21wb25lbnQuaHRtbCcsXHJcbiAgc3R5bGVVcmxzOiBbJy4vc3R5bGVzL3Njcm9sbGVyLmJlaGF2aW9yLnNjc3MnXVxyXG59KVxyXG5leHBvcnQgY2xhc3MgU2Nyb2xsZXJDb21wb25lbnQge1xyXG5cclxuICBAVmlld0NoaWxkKCdoZWFkZXInLCB7c3RhdGljOiBmYWxzZX0pXHJcbiAgcHVibGljIGhlYWRlcjogYW55O1xyXG5cclxuICBAVmlld0NoaWxkKCdkYXRhQXJlYScsIHtzdGF0aWM6IHRydWV9KVxyXG4gIHB1YmxpYyBkYXRhQXJlYTogYW55O1xyXG5cclxuICBAVmlld0NoaWxkKCdkYXRhJywge3N0YXRpYzogdHJ1ZX0pXHJcbiAgcHVibGljIGRhdGE6IGFueTtcclxuXHJcbiAgQFZpZXdDaGlsZCgnZGF0YWgnLCB7c3RhdGljOiB0cnVlfSlcclxuICBwdWJsaWMgZGF0YWg6IGFueTtcclxuXHJcbiAgQFZpZXdDaGlsZCgnZm9vdGVyJywge3N0YXRpYzogZmFsc2V9KVxyXG4gIHB1YmxpYyBmb290ZXI6IGFueTtcclxuXHJcbiAgQElucHV0KCdtYXhIZWlnaHQnKVxyXG4gIHB1YmxpYyBtYXhIZWlnaHQ6IHN0cmluZyA9IG51bGw7XHJcblxyXG4gIHB1YmxpYyBnZXQgbWF4SGVpZ2h0VSgpOiBzdHJpbmcge1xyXG4gICAgaWYgKHRoaXMubWF4SGVpZ2h0ID09PSBudWxsKSB7XHJcbiAgICAgIHJldHVybiAndW5zZXQnO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHRoaXMubWF4SGVpZ2h0O1xyXG4gIH1cclxuXHJcbiAgQE91dHB1dCgpXHJcbiAgYXV0b3Njcm9sbHg6IEV2ZW50RW1pdHRlcjxudW1iZXI+ID0gbmV3IEV2ZW50RW1pdHRlcjxudW1iZXI+KCk7XHJcblxyXG4gIEBPdXRwdXQoKVxyXG4gIHNjcm9sbDogRXZlbnRFbWl0dGVyPGFueT4gPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcclxuXHJcbiAgQEhvc3RCaW5kaW5nKCdjbGFzcy50cnVlLXYtc2Nyb2xsJylcclxuICBnZXQgYXV0b1dpZHRoKCkge1xyXG4gICAgcmV0dXJuIHRoaXMuc3RhdGUuc2V0dGluZ3MuY29sdW1uQXV0b1dpZHRoO1xyXG4gIH1cclxuXHJcbiAgQEhvc3RCaW5kaW5nKCdjbGFzcy50cnVlLWZpeC10b3VjaCcpXHJcbiAgZ2V0IHRvdWNoRml4KCkge1xyXG4gICAgcmV0dXJuICh0aGlzLnN0YXRlLmlPUyB8fCB0aGlzLnN0YXRlLmFuZHJvaWQpICYmIHRoaXMuc3RhdGUuc2V0dGluZ3MuZW5hYmxlVG91Y2hTY3JvbGw7XHJcbiAgfVxyXG5cclxuICBwcm90ZWN0ZWQgc2Nyb2xsWCA9IDA7XHJcbiAgcHJvdGVjdGVkIHNjcm9sbFkgPSAwO1xyXG4gIHByaXZhdGUgc2Nyb2xsVGltZXI6IGFueSA9IG51bGw7XHJcbiAgcHJpdmF0ZSBzY3JvbGxTdWJzY3JpcHRpb246IGFueSA9IG51bGw7XHJcblxyXG4gIHByaXZhdGUgYXV0b1Njcm9sbEluUHJvZ3Jlc3MgPSBmYWxzZTtcclxuXHJcbiAgcHVibGljICBzY3JvbGxTcGVlZFggPSAwO1xyXG4gIHB1YmxpYyAgc2Nyb2xsU3BlZWRZID0gMDtcclxuXHJcbiAgcHJvdGVjdGVkIF9zY3JvbGxSZWN0OiBhbnkgPSBudWxsO1xyXG5cclxuICBwdWJsaWMgZ2V0IHNjcm9sbGVySCgpIHtcclxuICAgIGlmICh0aGlzLnRvdWNoRml4KSB7XHJcbiAgICAgIHJldHVybiB0aGlzLmRhdGFoO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHRoaXMuZGF0YTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBnZXQgc2Nyb2xsZXJWKCkge1xyXG4gICAgaWYgKHRoaXMudG91Y2hGaXgpIHtcclxuICAgICAgcmV0dXJuIHRoaXMuZGF0YUFyZWE7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdGhpcy5kYXRhO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIGdldCBjbGllbnRSZWN0KCk6IGFueSB7XHJcbiAgICByZXR1cm4gdGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgZ2V0IGNlbnRlclJlY3QoKTogYW55IHtcclxuICAgIGlmICh0aGlzLnRvdWNoRml4KSB7XHJcbiAgICAgIHJldHVybiB0aGlzLmRhdGFoLm5hdGl2ZUVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdGhpcy5kYXRhLm5hdGl2ZUVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgZ2V0IGhlYWRlclJlY3QoKTogYW55IHtcclxuICAgIHJldHVybiB0aGlzLmhlYWRlci5uYXRpdmVFbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIGdldCBoZWFkZXJSZWN0TGVmdCgpOiBhbnkge1xyXG4gICAgcmV0dXJuIG51bGw7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgZ2V0IGhlYWRlclJlY3RSaWdodCgpOiBhbnkge1xyXG4gICAgcmV0dXJuIG51bGw7XHJcbiAgfVxyXG5cclxuICBkYXRhU2Nyb2xsKGU6IGFueSkge1xyXG4gICAgdGhpcy5kb1Njcm9sbChlKTtcclxuICAgIHRoaXMuc2Nyb2xsLmVtaXQoZSk7XHJcbiAgfVxyXG5cclxuICBkYXRhU2Nyb2xsSChlOiBhbnkpIHtcclxuICAgIHRoaXMuZG9TY3JvbGwoZSwgdHJ1ZSk7XHJcbiAgICB0aGlzLnNjcm9sbC5lbWl0KGUpO1xyXG4gIH1cclxuXHJcbiAgZ2V0IGlzQXV0b1Njcm9sbCgpIHtcclxuICAgIHJldHVybiB0aGlzLmF1dG9TY3JvbGxJblByb2dyZXNzO1xyXG4gIH1cclxuXHJcbiAgZ2V0IHNjcm9sbFRvcCgpIHtcclxuICAgIGlmICh0aGlzLnRvdWNoRml4KSB7XHJcbiAgICAgIHJldHVybiB0aGlzLmRhdGFBcmVhLm5hdGl2ZUVsZW1lbnQuc2Nyb2xsVG9wO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHRoaXMuZGF0YS5uYXRpdmVFbGVtZW50LnNjcm9sbFRvcDtcclxuICB9XHJcblxyXG4gIGdldCBzY3JvbGxMZWZ0KCkge1xyXG4gICAgaWYgKHRoaXMudG91Y2hGaXgpIHtcclxuICAgICAgcmV0dXJuIHRoaXMuZGF0YWgubmF0aXZlRWxlbWVudC5zY3JvbGxMZWZ0O1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHRoaXMuZGF0YS5uYXRpdmVFbGVtZW50LnNjcm9sbExlZnQ7XHJcbiAgfVxyXG5cclxuICBnZXQgc2Nyb2xsV2lkdGgoKSB7XHJcbiAgICBpZiAodGhpcy50b3VjaEZpeCkge1xyXG4gICAgICByZXR1cm4gdGhpcy5kYXRhaC5uYXRpdmVFbGVtZW50LnNjcm9sbFdpZHRoO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHRoaXMuZGF0YS5uYXRpdmVFbGVtZW50LnNjcm9sbFdpZHRoO1xyXG4gIH1cclxuXHJcbiAgZ2V0IHNjcm9sbEhlaWdodCgpIHtcclxuICAgIHJldHVybiB0aGlzLmRhdGEubmF0aXZlRWxlbWVudC5zY3JvbGxIZWlnaHQ7XHJcbiAgfVxyXG5cclxuICBnZXQgdmlld1BvcnRIZWlnaHQoKSB7XHJcbiAgICBpZiAodGhpcy50b3VjaEZpeCkge1xyXG4gICAgICByZXR1cm4gdGhpcy5kYXRhQXJlYS5uYXRpdmVFbGVtZW50LmNsaWVudEhlaWdodDtcclxuICAgIH1cclxuICAgIHJldHVybiB0aGlzLmRhdGEubmF0aXZlRWxlbWVudC5jbGllbnRIZWlnaHQ7XHJcbiAgfVxyXG5cclxuICBnZXQgdmlld1BvcnRXaWR0aCgpIHtcclxuICAgIGlmICh0aGlzLnRvdWNoRml4KSB7XHJcbiAgICAgIHJldHVybiB0aGlzLmRhdGFBcmVhLm5hdGl2ZUVsZW1lbnQuY2xpZW50V2lkdGg7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICByZXR1cm4gdGhpcy5kYXRhLm5hdGl2ZUVsZW1lbnQuY2xpZW50V2lkdGg7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgcHJlcGFyZUF1dG9TY3JvbGwoKSB7XHJcbiAgICB0aGlzLl9zY3JvbGxSZWN0ID0gdGhpcy5jZW50ZXJSZWN0O1xyXG4gIH1cclxuXHJcbiAgcHVibGljIHN0YXJ0QXV0b1Njcm9sbCgpIHtcclxuXHJcbiAgICBpZiAodGhpcy5hdXRvU2Nyb2xsSW5Qcm9ncmVzcykge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKCF0aGlzLnNjcm9sbFRpbWVyKSB7XHJcbiAgICAgIHRoaXMuc2Nyb2xsVGltZXIgPSB0aW1lcih0aGlzLnN0YXRlLnN0LmF1dG9TY3JvbGxJbnRlcnZhbCwgdGhpcy5zdGF0ZS5zdC5hdXRvU2Nyb2xsSW50ZXJ2YWwpO1xyXG4gICAgICB0aGlzLnNjcm9sbFN1YnNjcmlwdGlvbiA9IHRoaXMuc2Nyb2xsVGltZXIuc3Vic2NyaWJlKCh0OiBhbnkpID0+IHRoaXMuc2Nyb2xsSWZOZWVkZWQoKSk7XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy5hdXRvU2Nyb2xsSW5Qcm9ncmVzcyA9IHRydWU7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgc3RvcEF1dG9TY3JvbGwoKSB7XHJcbiAgICB0aGlzLl9zY3JvbGxSZWN0ID0gbnVsbDtcclxuICAgIHRoaXMuc2Nyb2xsU3BlZWRZID0gMDtcclxuICAgIHRoaXMuc2Nyb2xsU3BlZWRYID0gMDtcclxuICAgIGlmICh0aGlzLnNjcm9sbFN1YnNjcmlwdGlvbikge1xyXG4gICAgICB0aGlzLnNjcm9sbFN1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpO1xyXG4gICAgICB0aGlzLnNjcm9sbFRpbWVyID0gbnVsbDtcclxuICAgIH1cclxuXHJcbiAgICB0aGlzLmF1dG9TY3JvbGxJblByb2dyZXNzID0gZmFsc2U7XHJcbiAgfVxyXG5cclxuICAvLyDQn9GA0L7QutGA0YPRgtC60LAg0L/RgNC4INC90LXQvtCx0YXQvtC00LjQvNC+0YHRgtC4XHJcbiAgcHVibGljIHNjcm9sbElmTmVlZGVkKCkge1xyXG5cclxuICAgIGNvbnN0IHNsID0gdGhpcy5zY3JvbGxMZWZ0O1xyXG4gICAgY29uc3Qgc3QgPSB0aGlzLnNjcm9sbFRvcDtcclxuICAgIGNvbnN0IHN3ID0gdGhpcy5zY3JvbGxXaWR0aDtcclxuICAgIGNvbnN0IHNoID0gdGhpcy5zY3JvbGxIZWlnaHQ7XHJcblxyXG4gICAgbGV0IG5lZWRTbCA9IHNsO1xyXG4gICAgbGV0IG5lZWRTdCA9IHN0O1xyXG5cclxuICAgIGNvbnN0IHIwID0gdGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XHJcblxyXG4gICAgaWYgKHRoaXMuc2Nyb2xsU3BlZWRZIDwgMCkge1xyXG4gICAgICAvLyDQu9C40YHRgtCw0LXQvCDQstC70LXQstC+XHJcbiAgICAgIGlmIChzdCA+PSAtdGhpcy5zY3JvbGxTcGVlZFkpIHtcclxuICAgICAgICBuZWVkU3QgPSBzdCArIHRoaXMuc2Nyb2xsU3BlZWRZO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIG5lZWRTdCA9IDA7XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBpZiAodGhpcy5zY3JvbGxTcGVlZFkgPiAwKSB7XHJcbiAgICAgIC8vINC70LjRgdGC0LDQtdC8INCy0L/RgNCw0LLQvlxyXG4gICAgICBjb25zdCBtYXhTY3JvbGxUb3AgPSBzaCAtIHRoaXMuc2Nyb2xsZXJWLm5hdGl2ZUVsZW1lbnQuY2xpZW50SGVpZ2h0O1xyXG4gICAgICBpZiAoc2wgPD0gKG1heFNjcm9sbFRvcCAtIHRoaXMuc2Nyb2xsU3BlZWRZKSkge1xyXG4gICAgICAgIG5lZWRTdCA9IHN0ICsgdGhpcy5zY3JvbGxTcGVlZFk7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgbmVlZFN0ID0gbWF4U2Nyb2xsVG9wO1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHN0ICE9PSBuZWVkU3QpIHtcclxuICAgICAgdGhpcy5zY3JvbGxlclYubmF0aXZlRWxlbWVudC5zY3JvbGxUb3AgPSBuZWVkU3Q7XHJcbiAgICAgIHJldHVybjsgLy8g0J/QviDQtNCy0YPQvCDQvdCw0L/RgNCw0LLQu9C10L3QuNGP0Lwg0L3QtSDQsdGD0LTQtdC8INGN0YLQviDQtNC10LvQsNGC0YxcclxuICAgIH1cclxuXHJcbiAgICBpZiAodGhpcy5zY3JvbGxTcGVlZFggPCAwKSB7XHJcbiAgICAgIC8vINC70LjRgdGC0LDQtdC8INCy0LvQtdCy0L5cclxuICAgICAgaWYgKHNsID49IC10aGlzLnNjcm9sbFNwZWVkWCkge1xyXG4gICAgICAgIG5lZWRTbCA9IHNsICsgdGhpcy5zY3JvbGxTcGVlZFg7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgbmVlZFNsID0gMDtcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGlmICh0aGlzLnNjcm9sbFNwZWVkWCA+IDApIHtcclxuICAgICAgLy8g0LvQuNGB0YLQsNC10Lwg0LLQv9GA0LDQstC+XHJcbiAgICAgIGNvbnN0IG1heFNjcm9sbExlZnQgPSBzdyAtIHRoaXMuc2Nyb2xsZXJILm5hdGl2ZUVsZW1lbnQuY2xpZW50V2lkdGg7XHJcbiAgICAgIGlmIChzbCA8PSAobWF4U2Nyb2xsTGVmdCAtIHRoaXMuc2Nyb2xsU3BlZWRYKSkge1xyXG4gICAgICAgIG5lZWRTbCA9IHNsICsgdGhpcy5zY3JvbGxTcGVlZFg7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgbmVlZFNsID0gbWF4U2Nyb2xsTGVmdDtcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGlmIChzbCAhPT0gbmVlZFNsKSB7XHJcbiAgICAgIHRoaXMuc2Nyb2xsZXJILm5hdGl2ZUVsZW1lbnQuc2Nyb2xsTGVmdCA9IG5lZWRTbDtcclxuICAgICAgdGhpcy5hdXRvc2Nyb2xseC5lbWl0KG5lZWRTbCAtIHNsKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHB1YmxpYyBzY3JvbGxUbyh4OiBudW1iZXIsIHk6IG51bWJlciA9IC0xKSB7XHJcbiAgICBpZiAoeSA+PSAwKSB7XHJcbiAgICAgIHRoaXMuc2Nyb2xsZXJWLm5hdGl2ZUVsZW1lbnQuc2Nyb2xsVG9wID0geTtcclxuICAgIH1cclxuICAgIGlmICh4ID49IDApIHtcclxuICAgICAgdGhpcy5zY3JvbGxlckgubmF0aXZlRWxlbWVudC5zY3JvbGxMZWZ0ID0geDtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8vINCf0L7RgdC70LUg0YHQttCw0YLQuNGPINC60L7QvdGC0LXQvdGC0LAg0LLQvtC30LzQvtC20L3RiyDQvtGC0YDQuNGG0LDRgtC10LvRjNC90YvQtSDQt9C90LDRh9C10L3QuNGPIFNjcm9sbExlZnQuINCX0LTQtdGB0Ywg0LzRi1xyXG4gIC8vINC/0YDQvtCy0LXRgNC40Lwg0Lgg0LjRgdC/0YDQsNCy0LjQvCDRjdGC0L4uLi5cclxuICBwdWJsaWMgZml4U2Nyb2xsKCkge1xyXG4gICAgaWYgKHRoaXMuc2Nyb2xsZXJILm5hdGl2ZUVsZW1lbnQuc2Nyb2xsTGVmdCA8IDApIHtcclxuICAgICAgdGhpcy5zY3JvbGxlckgubmF0aXZlRWxlbWVudC5zY3JvbGxMZWZ0ID0gMDtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHB1YmxpYyBjaGVja0F1dG9TY3JvbGxYKHh4OiBudW1iZXIsIGNoZWNrUGFydHM6IGJvb2xlYW4gPSBmYWxzZSk6IGFueSB7XHJcblxyXG4gICAgY29uc3QgcjAgPSB0aGlzLl9zY3JvbGxSZWN0O1xyXG5cclxuICAgIGlmICghcjApIHtcclxuICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHh4IDw9IHIwLmxlZnQpIHtcclxuICAgICAgLy8g0LvQuNGB0YLQsNC10Lwg0LLQu9C10LLQvlxyXG4gICAgICB0aGlzLnNjcm9sbFNwZWVkWCA9IC10aGlzLnN0YXRlLnN0LmF1dG9TY3JvbGxTdGVwO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgaWYgKHh4ID49IHIwLnJpZ2h0KSB7XHJcbiAgICAgICAgLy8g0LLQv9GA0LDQstC+XHJcbiAgICAgICAgdGhpcy5zY3JvbGxTcGVlZFggPSB0aGlzLnN0YXRlLnN0LmF1dG9TY3JvbGxTdGVwO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIHRoaXMuc2Nyb2xsU3BlZWRYID0gMDtcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGlmICh0aGlzLnNjcm9sbFNwZWVkWCAhPT0gMCkge1xyXG4gICAgICB0aGlzLnN0YXJ0QXV0b1Njcm9sbCgpO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiByMDtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBjaGVja0F1dG9TY3JvbGxZKHl5OiBudW1iZXIpOiBhbnkge1xyXG4gICAgY29uc3QgcjAgPSB0aGlzLl9zY3JvbGxSZWN0O1xyXG4gICAgaWYgKCFyMCkge1xyXG4gICAgICByZXR1cm4gbnVsbDtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoeXkgPCByMC50b3ApIHtcclxuICAgICAgLy8g0LvQuNGB0YLQsNC10Lwg0LLQstC10YDRhVxyXG4gICAgICB0aGlzLnNjcm9sbFNwZWVkWSA9IC10aGlzLnN0YXRlLnN0LmF1dG9TY3JvbGxTdGVwO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgaWYgKHl5ID4gcjAuYm90dG9tKSB7XHJcbiAgICAgICAgLy8g0LLQvdC40LdcclxuICAgICAgICB0aGlzLnNjcm9sbFNwZWVkWSA9IHRoaXMuc3RhdGUuc3QuYXV0b1Njcm9sbFN0ZXA7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgdGhpcy5zY3JvbGxTcGVlZFkgPSAwO1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHRoaXMuc2Nyb2xsU3BlZWRZICE9PSAwKSB7XHJcbiAgICAgIHRoaXMuc3RhcnRBdXRvU2Nyb2xsKCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgc2Nyb2xsUGFydHMoKSB7IH1cclxuXHJcbiAgZG9TY3JvbGwoZTogYW55LCBoOiBib29sZWFuID0gZmFsc2UpIHtcclxuICAgIGNvbnN0IGwgPSBlLnRhcmdldDtcclxuXHJcbiAgICBpZiAoKCF0aGlzLnRvdWNoRml4IHx8IGgpICYmIHRoaXMuc2Nyb2xsWCAhPT0gbC5zY3JvbGxMZWZ0KSB7XHJcbiAgICAgIHRoaXMuc2Nyb2xsWCA9IGwuc2Nyb2xsTGVmdDtcclxuICAgICAgaWYgKHRoaXMuc3RhdGUuc2V0dGluZ3Muc2hvd0hlYWRlcikgeyAgICAgICAgXHJcbiAgICAgICAgdGhpcy5oZWFkZXIubmF0aXZlRWxlbWVudC5zY3JvbGxMZWZ0ID0gdGhpcy5zY3JvbGxYO1xyXG4gICAgICB9XHJcbiAgICAgIGlmICh0aGlzLnN0YXRlLnNldHRpbmdzLnNob3dGb290ZXIpIHtcclxuICAgICAgICB0aGlzLmZvb3Rlci5uYXRpdmVFbGVtZW50LnNjcm9sbExlZnQgPSB0aGlzLnNjcm9sbFg7XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBpZiAodGhpcy5zY3JvbGxZICE9PSBsLnNjcm9sbFRvcCkge1xyXG4gICAgICB0aGlzLnNjcm9sbFBhcnRzKCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgZm9jdXMoKSB7XHJcbiAgICB0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5mb2N1cygpO1xyXG4gIH1cclxuXHJcbiAgY29uc3RydWN0b3IoXHJcbiAgICBASW5qZWN0KCdncmlkU3RhdGUnKSBwdWJsaWMgc3RhdGU6IEdyaWRTdGF0ZVNlcnZpY2UsXHJcbiAgICBwcm90ZWN0ZWQgZWxlbWVudFJlZjogRWxlbWVudFJlZixcclxuICAgIHByb3RlY3RlZCBjaGFuZ2VEZXRlY3RvcjogQ2hhbmdlRGV0ZWN0b3JSZWYsXHJcbiAgICBwcm90ZWN0ZWQgcmVuZGVyZXI6IFJlbmRlcmVyMikgeyB9XHJcbn0iXX0=