@true-directive/grid
Version:
Angular Data Grid from Yopsilon.
377 lines • 49.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 { Directive, ElementRef, Input, Output, HostListener, EventEmitter, Renderer2, forwardRef } from '@angular/core';
import { NG_VALUE_ACCESSOR } from '@angular/forms';
import { InternationalizationService } from '../internationalization/internationalization.service';
import { Keys, KeyInfo } from '@true-directive/base';
import { MaskState } from '@true-directive/base';
import { MaskSectionAction, MaskResult } from '@true-directive/base';
import { NumberParserFormatter } from '@true-directive/base';
var MaskNumberDirective = /** @class */ (function () {
function MaskNumberDirective(_renderer, _elementRef, intl) {
var _this = this;
this._renderer = _renderer;
this._elementRef = _elementRef;
this.intl = intl;
this.onChange = function (_) { };
this.onTouched = function () { };
this._undo = [];
this._redo = [];
// Текущее числовое значение
this._numValue = null;
// Текущее текстовое значение
this._txtValue = '';
// Смена состояния
this.stateChange = new EventEmitter();
// Состояние директивы
this._state = null;
this._separators = ['.', ','];
this._format = '{1.2}';
this.android_behavior = false;
// Format change can follow locale change
this._localeSubscription = this.intl.onLocaleChanged.subscribe(function (locale) { return _this.setLocale(locale); });
}
MaskNumberDirective_1 = MaskNumberDirective;
MaskNumberDirective.prototype.registerOnChange = function (fn) { this.onChange = fn; };
MaskNumberDirective.prototype.registerOnTouched = function (fn) { this.onTouched = fn; };
MaskNumberDirective.prototype.blur = function () {
// Очищаем, если формат неверен
var value = NumberParserFormatter.parse(this._txtValue, this.format, this._separators);
if (value === null || isNaN(value)) {
this.setText('');
}
else {
this.setText(NumberParserFormatter.format(value, this.format, this._separators));
}
this.onTouched();
};
Object.defineProperty(MaskNumberDirective.prototype, "state", {
get: function () {
return this._state;
},
set: function (v) {
if (this._state !== v) {
this._state = v;
this.stateChange.emit(this._state); // Излучаем событие
}
},
enumerable: true,
configurable: true
});
// Обновляем состояние
MaskNumberDirective.prototype.updateState = function () {
if (this._numValue === null) {
this.state = MaskState.EMPTY; // Пустое значение
}
else {
if (isNaN(this._numValue)) {
this.state = MaskState.TYPING; // Считаем, что пользователь не завершил ввод
}
else {
this.state = MaskState.OK;
}
}
};
// Sending a value to model
MaskNumberDirective.prototype.toModel = function () {
// Retrieving value
if (this._txtValue === '') {
this._numValue = null;
}
else {
this._numValue = NumberParserFormatter.parse(this._txtValue, this.format, this._separators);
}
// Sending to model
this.onChange(this._numValue);
// Updating the state
this.updateState();
};
MaskNumberDirective.prototype.processAndroid = function (txt) {
//
var res = this.currentRes();
// Теоретически положение курсора у нас есть..
var key = Keys.whichKeyHasBeenPressed(this.last_res.newValue, txt, this.last_res.selStart, res.selStart, this.last_res.selLength);
var selStart = this.last_res.selStart;
var selEnd = this.last_res.selStart;
// Если текст вдруг стёрся
if (this.last_res.newValue !== '' && txt.length <= 1) {
if (txt === '') {
key = new KeyInfo(Keys.DELETE);
}
else {
key = new KeyInfo(0, txt);
}
selStart = 0;
selEnd = this.last_res.newValue.length;
}
var r = this.processKey({
keyCode: -1,
key: key.code,
char: key.char,
shiftKey: false,
ctrlKey: false,
target: { selectionStart: selStart, selectionEnd: selEnd },
preventDefault: function (_) { }
});
if (!r) {
this.setRes(this.last_res); // Не приняли, вернули всё назад
}
// Зачем это здесь?.. А вдруг..
this.android_behavior = false;
return;
};
// Пользователь вносит значение. Parser: View --> Ctrl
MaskNumberDirective.prototype.input = function (txt) {
if (this.android_behavior) {
this.processAndroid(txt);
return;
}
// Поэтому пытаемся применить формат к введенному значению.
var value = NumberParserFormatter.parse(txt, this.format, this._separators);
if (value === null) {
this.setText('');
}
else {
if (!isNaN(value)) {
this.setText(NumberParserFormatter.format(value, this.format, this._separators), true);
}
}
};
// Formatter: Ctrl --> View
MaskNumberDirective.prototype.writeValue = function (value) {
this._numValue = value;
var txt = '';
if (value !== null) {
txt = NumberParserFormatter.format(value, this.format, this._separators);
}
if (txt !== this._txtValue) {
this.setText(txt, false);
}
// No need to send to model, because this processor is called on model change
// but state still needs to be updated
this.updateState();
};
Object.defineProperty(MaskNumberDirective.prototype, "format", {
get: function () {
if (this._format === 'currency') {
return this.intl.locale.currency;
}
return this._format;
},
set: function (f) {
if (this._txtValue !== '' && this._format !== f) {
// По сложному пути
var res = this.currentRes();
this._format = f;
var state = NumberParserFormatter.reformat(this._txtValue, this.format, this._separators, res.selStart, res.selStart + res.selLength, true // Convert to format
);
this.setRes(this.getRes(state.value, state.selStart, state.selEnd));
}
else {
this._format = f;
}
},
enumerable: true,
configurable: true
});
MaskNumberDirective.prototype.keyDown = function (e) {
return this.processKey(e);
};
MaskNumberDirective.prototype.processKey = function (e) {
if (e.keyCode === 229 || e.keyCode === 0 || e.keyCode === undefined) { // test: if (e.keyCode >= 0) ...
// Android detected
this.android_behavior = true;
this.last_res = this.currentRes();
return;
}
var c = Keys.keyChar(e);
var selStart = e.target.selectionStart;
var selEnd = e.target.selectionEnd;
var s = this._txtValue;
var state0 = this.getRes(s, selStart, selEnd);
if (Keys.isFunctional(e.keyCode)) {
return true;
}
if (e.keyCode === Keys.TAB || e.keyCode === Keys.ESCAPE) {
return true;
}
if (e.keyCode === Keys.HOME || e.keyCode === Keys.END) {
return true;
}
if (e.shiftKey && (e.keyCode === Keys.DELETE || e.keyCode === Keys.INSERT)) {
return true;
}
if (e.ctrlKey && e.keyCode === Keys.Z) {
// UNDO
var undoRes = this._undo.pop();
if (undoRes) {
this._redo.push(this.getRes(s, selStart, selEnd));
this.setRes(undoRes);
}
e.preventDefault();
return false;
}
if (e.ctrlKey && e.keyCode === Keys.Y) {
// REDO
var redoRes = this._redo.pop();
if (redoRes) {
this._undo.push(this.getRes(s, selStart, selEnd));
this.setRes(redoRes);
}
e.preventDefault();
return false;
}
if (e.ctrlKey) {
return true;
}
if (selStart === 0 && selEnd === this._txtValue.length) {
s = '';
selStart = 0;
selEnd = 0;
}
var leadToFormat = false;
var applied = false;
if (e.keyCode === Keys.BACKSPACE || e.keyCode === Keys.DELETE) {
var canAccept = NumberParserFormatter.canAcceptKey(s, e.keyCode, c, this.format, this._separators, selStart, selEnd);
if (selStart === selEnd) {
// Ничего не выделено
if (e.keyCode === Keys.BACKSPACE && selStart > 0) {
if (canAccept)
s = s.substring(0, selStart - 1) + s.substring(selEnd);
selStart--;
selEnd--;
}
if (e.keyCode === Keys.DELETE) {
if (canAccept)
s = s.substring(0, selStart) + s.substring(selEnd + 1);
else {
selStart++;
selEnd++;
}
}
applied = true;
}
if (selStart < selEnd) {
// Выделено один или более символов
var fragmentToDelete = s.substring(selStart, selEnd);
if (canAccept) {
if (fragmentToDelete.indexOf(this._separators[0]) >= 0) {
s = s.substring(0, selStart) + this._separators[0] + s.substring(selEnd);
}
else {
s = s.substring(0, selStart) + s.substring(selEnd);
}
}
selEnd = selStart;
applied = true;
}
}
if (c.length === 1) {
s = s.substring(0, selStart) + s.substring(selEnd);
if (NumberParserFormatter.canAcceptKey(s, e.keyCode, c, this.format, this._separators, selStart)) {
s = s.substring(0, selStart) + c + s.substring(selStart);
selStart++;
selEnd = selStart;
applied = true;
}
else {
e.preventDefault();
return false;
}
}
if (applied) {
// При изменении значения внесем в стэк undo
if (s !== state0.newValue) {
this._undo.push(state0);
this._redo = [];
}
var state3 = NumberParserFormatter.reformat(s, this.format, this._separators, selStart, selEnd, leadToFormat);
this.setRes(this.getRes(state3.value, state3.selStart, state3.selEnd));
if (this.android_behavior) {
return true;
}
e.preventDefault();
return false;
}
return true;
};
// Установить значение и положение курсора
MaskNumberDirective.prototype.setRes = function (res) {
if (this.android_behavior)
res.selLength = 0;
this.setText(res.newValue);
this._renderer.setProperty(this._elementRef.nativeElement, 'selectionStart', res.selStart);
this._renderer.setProperty(this._elementRef.nativeElement, 'selectionEnd', res.selStart + res.selLength);
};
MaskNumberDirective.prototype.currentRes = function () {
var res = new MaskResult(this._txtValue, MaskSectionAction.APPLY, 0);
res.selStart = this._elementRef.nativeElement.selectionStart;
res.selLength = this._elementRef.nativeElement.selectionEnd - res.selStart;
return res;
};
// Получить текущее значение маски и положение курсора
MaskNumberDirective.prototype.getRes = function (s, selStart, selEnd) {
var res = new MaskResult(s, MaskSectionAction.APPLY, 0);
res.selStart = selStart;
res.selLength = selEnd - selStart;
return res;
};
// Записывает текст в контрол
MaskNumberDirective.prototype.setText = function (displayedValue, toModel) {
if (toModel === void 0) { toModel = true; }
// Отображаем
this._txtValue = displayedValue;
this._renderer.setProperty(this._elementRef.nativeElement, 'value', this._txtValue);
// Отправляем в модель
if (toModel) {
this.toModel();
}
};
MaskNumberDirective.prototype.setLocale = function (locale) {
this._separators[0] = locale.separators[0];
this._separators[1] = locale.separators[1];
// Updating view
this.writeValue(this._numValue);
};
MaskNumberDirective.prototype.ngOnDestroy = function () {
// Unsubscribing
this._localeSubscription.unsubscribe();
};
var MaskNumberDirective_1;
tslib_1.__decorate([
Output('ynStateChange'),
tslib_1.__metadata("design:type", Object)
], MaskNumberDirective.prototype, "stateChange", void 0);
tslib_1.__decorate([
Input('true-mask-number'),
tslib_1.__metadata("design:type", String),
tslib_1.__metadata("design:paramtypes", [String])
], MaskNumberDirective.prototype, "format", null);
tslib_1.__decorate([
HostListener('keydown', ['$event']),
tslib_1.__metadata("design:type", Function),
tslib_1.__metadata("design:paramtypes", [Object]),
tslib_1.__metadata("design:returntype", void 0)
], MaskNumberDirective.prototype, "keyDown", null);
MaskNumberDirective = MaskNumberDirective_1 = tslib_1.__decorate([
Directive({
selector: '[true-mask-number]',
host: { '(input)': 'input($event.target.value)', '(blur)': 'blur()' },
providers: [{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(function () { return MaskNumberDirective_1; }),
multi: true
}]
}),
tslib_1.__metadata("design:paramtypes", [Renderer2,
ElementRef,
InternationalizationService])
], MaskNumberDirective);
return MaskNumberDirective;
}());
export { MaskNumberDirective };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFzay1udW1iZXIuZGlyZWN0aXZlLmpzIiwic291cmNlUm9vdCI6Im5nOi8vQHRydWUtZGlyZWN0aXZlL2dyaWQvIiwic291cmNlcyI6WyJzcmMvbWFzay9tYXNrLW51bWJlci5kaXJlY3RpdmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOzs7O0VBSUU7QUFDRixPQUFPLEVBQUUsU0FBUyxFQUFFLFVBQVUsRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLFlBQVksRUFBRSxZQUFZLEVBQUUsU0FBUyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUN4SCxPQUFPLEVBQXdCLGlCQUFpQixFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFekUsT0FBTyxFQUFFLDJCQUEyQixFQUFFLE1BQU0sc0RBQXNELENBQUM7QUFFbkcsT0FBTyxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUVyRCxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFFakQsT0FBTyxFQUFFLGlCQUFpQixFQUFFLFVBQVUsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBRXJFLE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBWTdEO0lBMFlFLDZCQUFzQixTQUFvQixFQUM1QixXQUF1QixFQUN2QixJQUFpQztRQUYvQyxpQkFLQztRQUxxQixjQUFTLEdBQVQsU0FBUyxDQUFXO1FBQzVCLGdCQUFXLEdBQVgsV0FBVyxDQUFZO1FBQ3ZCLFNBQUksR0FBSixJQUFJLENBQTZCO1FBeFl2QyxhQUFRLEdBQUcsVUFBQyxDQUFNLElBQU0sQ0FBQyxDQUFDO1FBQzFCLGNBQVMsR0FBRyxjQUFPLENBQUMsQ0FBQztRQWdCckIsVUFBSyxHQUFzQixFQUFFLENBQUM7UUFDOUIsVUFBSyxHQUFzQixFQUFFLENBQUM7UUFFdEMsNEJBQTRCO1FBQ3BCLGNBQVMsR0FBVyxJQUFJLENBQUM7UUFFakMsNkJBQTZCO1FBQ25CLGNB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LFlBQVksQ0FBQyxTQUFTLEVBQUUsQ0FBQyxRQUFRLENBQUMsQ0FBQzs7OztzREFHbkM7SUFoTVUsbUJBQW1CO1FBVC9CLFNBQVMsQ0FBQztZQUNQLFFBQVEsRUFBRSxvQkFBb0I7WUFDOUIsSUFBSSxFQUFFLEVBQUMsU0FBUyxFQUFFLDRCQUE0QixFQUFFLFFBQVEsRUFBRSxRQUFRLEVBQUM7WUFDbkUsU0FBUyxFQUFFLENBQUM7b0JBQ1IsT0FBTyxFQUFFLGlCQUFpQjtvQkFDMUIsV0FBVyxFQUFFLFVBQVUsQ0FBQyxjQUFNLE9BQUEscUJBQW1CLEVBQW5CLENBQW1CLENBQUM7b0JBQ2xELEtBQUssRUFBRSxJQUFJO2lCQUNaLENBQUM7U0FDUCxDQUFDO2lEQTJZaUMsU0FBUztZQUNmLFVBQVU7WUFDakIsMkJBQTJCO09BNVlwQyxtQkFBbUIsQ0FnWi9CO0lBQUQsMEJBQUM7Q0FBQSxBQWhaRCxJQWdaQztTQWhaWSxtQkFBbUIiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcclxuICogQ29weXJpZ2h0IChjKSAyMDE4LTIwMTkgQWxla3NleSBNZWxuaWtvdiwgVHJ1ZSBEaXJlY3RpdmUgQ29tcGFueS5cclxuICogQGxpbmsgaHR0cHM6Ly90cnVlZGlyZWN0aXZlLmNvbS9cclxuICogQGxpY2Vuc2UgTUlUXHJcbiovXHJcbmltcG9ydCB7IERpcmVjdGl2ZSwgRWxlbWVudFJlZiwgSW5wdXQsIE91dHB1dCwgSG9zdExpc3RlbmVyLCBFdmVudEVtaXR0ZXIsIFJlbmRlcmVyMiwgZm9yd2FyZFJlZiB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBDb250cm9sVmFsdWVBY2Nlc3NvciwgTkdfVkFMVUVfQUNDRVNTT1IgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XHJcblxyXG5pbXBvcnQgeyBJbnRlcm5hdGlvbmFsaXphdGlvblNlcnZpY2UgfSBmcm9tICcuLi9pbnRlcm5hdGlvbmFsaXphdGlvbi9pbnRlcm5hdGlvbmFsaXphdGlvbi5zZXJ2aWNlJztcclxuXHJcbmltcG9ydCB7IEtleXMsIEtleUluZm8gfSBmcm9tICdAdHJ1ZS1kaXJlY3RpdmUvYmFzZSc7XHJcblxyXG5pbXBvcnQgeyBNYXNrU3RhdGUgfSBmcm9tICdAdHJ1ZS1kaXJlY3RpdmUvYmFzZSc7XHJcbmltcG9ydCB7IE1hc2tTZXR0aW5ncyB9IGZyb20gJ0B0cnVlLWRpcmVjdGl2ZS9iYXNlJztcclxuaW1wb3J0IHsgTWFza1NlY3Rpb25BY3Rpb24sIE1hc2tSZXN1bHQgfSBmcm9tICdAdHJ1ZS1kaXJlY3RpdmUvYmFzZSc7XHJcblxyXG5pbXBvcnQgeyBOdW1iZXJQYXJzZXJGb3JtYXR0ZXIgfSBmcm9tICdAdHJ1ZS1kaXJlY3RpdmUvYmFzZSc7XHJcbmltcG9ydCB7IExvY2FsZSB9IGZyb20gJ0B0cnVlLWRpcmVjdGl2ZS9iYXNlJztcclxuXHJcbkBEaXJlY3RpdmUoe1xyXG4gICAgc2VsZWN0b3I6ICdbdHJ1ZS1tYXNrLW51bWJlcl0nLFxyXG4gICAgaG9zdDogeycoaW5wdXQpJzogJ2lucHV0KCRldmVudC50YXJnZXQudmFsdWUpJywgJyhibHVyKSc6ICdibHVyKCknfSxcclxuICAgIHByb3ZpZGVyczogW3tcclxuICAgICAgICBwcm92aWRlOiBOR19WQUxVRV9BQ0NFU1NPUixcclxuICAgICAgICB1c2VFeGlzdGluZzogZm9yd2FyZFJlZigoKSA9PiBNYXNrTnVtYmVyRGlyZWN0aXZlKSxcclxuICAgICAgICBtdWx0aTogdHJ1ZVxyXG4gICAgICB9XVxyXG59KVxyXG5leHBvcnQgY2xhc3MgTWFza051bWJlckRpcmVjdGl2ZSB7XHJcblxyXG4gIF9sb2NhbGVTdWJzY3JpcHRpb246IGFueTtcclxuXHJcbiAgcHJpdmF0ZSBvbkNoYW5nZSA9IChfOiBhbnkpID0+IHt9O1xyXG4gIHByaXZhdGUgb25Ub3VjaGVkID0gKCkgPT4ge307XHJcblxyXG4gIHJlZ2lzdGVyT25DaGFuZ2UoZm46IChfOiBhbnkpID0+IHZvaWQpOiB2b2lkIHsgdGhpcy5vbkNoYW5nZSA9IGZuOyB9XHJcbiAgcmVnaXN0ZXJPblRvdWNoZWQoZm46ICgpID0+IHZvaWQpOiB2b2lkIHsgdGhpcy5vblRvdWNoZWQgPSBmbjsgfVxyXG5cclxuICBibHVyKCkge1xyXG4gICAgLy8g0J7Rh9C40YnQsNC10LwsINC10YHQu9C4INGE0L7RgNC80LDRgiDQvdC10LLQtdGA0LXQvVxyXG4gICAgbGV0IHZhbHVlID0gTnVtYmVyUGFyc2VyRm9ybWF0dGVyLnBhcnNlKHRoaXMuX3R4dFZhbHVlLCB0aGlzLmZvcm1hdCwgdGhpcy5fc2VwYXJhdG9ycyk7XHJcbiAgICBpZiAodmFsdWUgPT09IG51bGwgfHwgaXNOYU4odmFsdWUpKSB7XHJcbiAgICAgIHRoaXMuc2V0VGV4dCgnJyk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICB0aGlzLnNldFRleHQoTnVtYmVyUGFyc2VyRm9ybWF0dGVyLmZvcm1hdCh2YWx1ZSwgdGhpcy5mb3JtYXQsIHRoaXMuX3NlcGFyYXRvcnMpKTtcclxuICAgIH1cclxuICAgIHRoaXMub25Ub3VjaGVkKCk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIF91bmRvOiBBcnJheTxNYXNrUmVzdWx0PiA9IFtdO1xyXG4gIHByaXZhdGUgX3JlZG86IEFycmF5PE1hc2tSZXN1bHQ+ID0gW107XHJcblxyXG4gIC8vINCi0LXQutGD0YnQtdC1INGH0LjRgdC70L7QstC+0LUg0LfQvdCw0YfQtdC90LjQtVxyXG4gIHByaXZhdGUgX251bVZhbHVlOiBudW1iZXIgPSBudWxsO1xyXG5cclxuICAvLyDQotC10LrRg9GJ0LXQtSDRgtC10LrRgdGC0L7QstC+0LUg0LfQvdCw0YfQtdC90LjQtVxyXG4gIHByb3RlY3RlZCBfdHh0VmFsdWU6IHN0cmluZyA9ICcnO1xyXG5cclxuICAvLyDQodC80LXQvdCwINGB0L7RgdGC0L7Rj9C90LjRj1xyXG4gIEBPdXRwdXQoJ3luU3RhdGVDaGFuZ2UnKVxyXG4gIHN0YXRlQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxNYXNrU3RhdGU+KCk7XHJcblxyXG4gIC8vINCh0L7RgdGC0L7Rj9C90LjQtSDQtNC40YDQtdC60YLQuNCy0YtcclxuICBwcml2YXRlIF9zdGF0ZTogTWFza1N0YXRlID0gbnVsbDtcclxuXHJcbiAgcHVibGljIGdldCBzdGF0ZSgpOiBNYXNrU3RhdGUge1xyXG4gICAgcmV0dXJuIHRoaXMuX3N0YXRlO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIHNldCBzdGF0ZSh2OiBNYXNrU3RhdGUpIHtcclxuICAgIGlmICh0aGlzLl9zdGF0ZSAhPT0gdikge1xyXG4gICAgICB0aGlzLl9zdGF0ZSA9IHY7XHJcbiAgICAgIHRoaXMuc3RhdGVDaGFuZ2UuZW1pdCh0aGlzLl9zdGF0ZSk7IC8vINCY0LfQu9GD0YfQsNC10Lwg0YHQvtCx0YvRgtC40LVcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8vINCe0LHQvdC+0LLQu9GP0LXQvCDRgdC+0YHRgtC+0Y/QvdC40LVcclxuICBwcm90ZWN0ZWQgdXBkYXRlU3RhdGUoKSB7XHJcbiAgICBpZiAodGhpcy5fbnVtVmFsdWUgPT09IG51bGwpIHtcclxuICAgICAgdGhpcy5zdGF0ZSA9IE1hc2tTdGF0ZS5FTVBUWTsgICAgICAgICAgIC8vINCf0YPRgdGC0L7QtSDQt9C90LDRh9C10L3QuNC1XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBpZiAoaXNOYU4odGhpcy5fbnVtVmFsdWUpKSB7XHJcbiAgICAgICAgdGhpcy5zdGF0ZSA9IE1hc2tTdGF0ZS5UWVBJTkc7ICAgICAgIC8vINCh0YfQuNGC0LDQtdC8LCDRh9GC0L4g0L/QvtC70YzQt9C+0LLQsNGC0LXQu9GMINC90LUg0LfQsNCy0LXRgNGI0LjQuyDQstCy0L7QtFxyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIHRoaXMuc3RhdGUgPSBNYXNrU3RhdGUuT0s7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8vIFNlbmRpbmcgYSB2YWx1ZSB0byBtb2RlbFxyXG4gIHByb3RlY3RlZCB0b01vZGVsKCkge1xyXG4gICAgLy8gUmV0cmlldmluZyB2YWx1ZVxyXG4gICAgaWYgKHRoaXMuX3R4dFZhbHVlID09PSAnJykge1xyXG4gICAgICB0aGlzLl9udW1WYWx1ZSA9IG51bGw7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICB0aGlzLl9udW1WYWx1ZSA9IE51bWJlclBhcnNlckZvcm1hdHRlci5wYXJzZSh0aGlzLl90eHRWYWx1ZSwgdGhpcy5mb3JtYXQsIHRoaXMuX3NlcGFyYXRvcnMpO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIFNlbmRpbmcgdG8gbW9kZWxcclxuICAgIHRoaXMub25DaGFuZ2UodGhpcy5fbnVtVmFsdWUpO1xyXG4gICAgLy8gVXBkYXRpbmcgdGhlIHN0YXRlXHJcbiAgICB0aGlzLnVwZGF0ZVN0YXRlKCk7XHJcbiAgfVxyXG5cclxuICBwcm9jZXNzQW5kcm9pZCh0eHQ6IGFueSkge1xyXG4gICAgLy9cclxuICAgIGxldCByZXMgPSB0aGlzLmN1cnJlbnRSZXMoKTtcclxuXHJcbiAgICAvLyDQotC10L7RgNC10YLQuNGH0LXRgdC60Lgg0L/QvtC70L7QttC10L3QuNC1INC60YPRgNGB0L7RgNCwINGDINC90LDRgSDQtdGB0YLRjC4uXHJcbiAgICBsZXQga2V5OiBLZXlJbmZvID0gS2V5cy53aGljaEtleUhhc0JlZW5QcmVzc2VkKHRoaXMubGFzdF9yZXMubmV3VmFsdWUsIHR4dCxcclxuICAgICAgICB0aGlzLmxhc3RfcmVzLnNlbFN0YXJ0LCByZXMuc2VsU3RhcnQsIHRoaXMubGFzdF9yZXMuc2VsTGVuZ3RoKTtcclxuXHJcbiAgICBsZXQgc2VsU3RhcnQgPSB0aGlzLmxhc3RfcmVzLnNlbFN0YXJ0O1xyXG4gICAgbGV0IHNlbEVuZCA9IHRoaXMubGFzdF9yZXMuc2VsU3RhcnQ7XHJcblxyXG4gICAgLy8g0JXRgdC70Lgg0YLQtdC60YHRgiDQstC00YDRg9CzINGB0YLRkdGA0YHRj1xyXG4gICAgaWYgKHRoaXMubGFzdF9yZXMubmV3VmFsdWUgIT09ICcnICYmIHR4dC5sZW5ndGggPD0gMSkge1xyXG5cclxuICAgICAgaWYgKHR4dCA9PT0gJycpIHtcclxuICAgICAgICBrZXkgPSBuZXcgS2V5SW5mbyhLZXlzLkRFTEVURSk7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAga2V5ID0gbmV3IEtleUluZm8oMCwgdHh0KTtcclxuICAgICAgfVxyXG5cclxuICAgICAgc2VsU3RhcnQgPSAwO1xyXG4gICAgICBzZWxFbmQgPSB0aGlzLmxhc3RfcmVzLm5ld1ZhbHVlLmxlbmd0aDtcclxuICAgIH1cclxuXHJcbiAgICBsZXQgciA9IHRoaXMucHJvY2Vzc0tleShcclxuICAgICAge1xyXG4gICAgICAgIGtleUNvZGU6IC0xLFxyXG4gICAgICAgIGtleToga2V5LmNvZGUsXHJcbiAgICAgICAgY2hhcjoga2V5LmNoYXIsXHJcbiAgICAgICAgc2hpZnRLZXk6IGZhbHNlLFxyXG4gICAgICAgIGN0cmxLZXk6IGZhbHNlLFxyXG4gICAgICAgIHRhcmdldDogeyBzZWxlY3Rpb25TdGFydDogc2VsU3RhcnQsIHNlbGVjdGlvbkVuZDogc2VsRW5kIH0sXHJcbiAgICAgICAgcHJldmVudERlZmF1bHQ6IChfOiBhbnkpID0+IHt9XHJcbiAgICAgIH0pO1xyXG5cclxuICAgIGlmICghcikge1xyXG4gICAgICB0aGlzLnNldFJlcyh0aGlzLmxhc3RfcmVzKTsgLy8g0J3QtSDQv9GA0LjQvdGP0LvQuCwg0LLQtdGA0L3Rg9C70Lgg0LLRgdGRINC90LDQt9Cw0LRcclxuICAgIH1cclxuXHJcbiAgICAvLyDQl9Cw0YfQtdC8INGN0YLQviDQt9C00LXRgdGMPy4uINCQINCy0LTRgNGD0LMuLlxyXG4gICAgdGhpcy5hbmRyb2lkX2JlaGF2aW9yID0gZmFsc2U7XHJcbiAgICByZXR1cm47XHJcbiAgfVxyXG5cclxuICAvLyDQn9C+0LvRjNC30L7QstCw0YLQtdC70Ywg0LLQvdC+0YHQuNGCINC30L3QsNGH0LXQvdC40LUuIFBhcnNlcjogVmlldyAtLT4gQ3RybFxyXG4gIGlucHV0KHR4dDogYW55KSB7XHJcbiAgICBpZiAodGhpcy5hbmRyb2lkX2JlaGF2aW9yKSB7XHJcbiAgICAgIHRoaXMucHJvY2Vzc0FuZHJvaWQodHh0KTtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG4gICAgLy8g0J/QvtGN0YLQvtC80YMg0L/Ri9GC0LDQtdC80YHRjyDQv9GA0LjQvNC10L3QuNGC0Ywg0YTQvtGA0LzQsNGCINC6INCy0LLQtdC00LXQvdC90L7QvNGDINC30L3QsNGH0LXQvdC40Y4uXHJcbiAgICBsZXQgdmFsdWUgPSBOdW1iZXJQYXJzZXJGb3JtYXR0ZXIucGFyc2UodHh0LCB0aGlzLmZvcm1hdCwgdGhpcy5fc2VwYXJhdG9ycyk7XHJcbiAgICBpZiAodmFsdWUgPT09IG51bGwpIHtcclxuICAgICAgdGhpcy5zZXRUZXh0KCcnKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIGlmICghaXNOYU4odmFsdWUpKSB7XHJcbiAgICAgICAgdGhpcy5zZXRUZXh0KE51bWJlclBhcnNlckZvcm1hdHRlci5mb3JtYXQodmFsdWUsIHRoaXMuZm9ybWF0LCB0aGlzLl9zZXBhcmF0b3JzKSwgdHJ1ZSk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8vIEZvcm1hdHRlcjogQ3RybCAtLT4gVmlld1xyXG4gIHdyaXRlVmFsdWUodmFsdWU6IGFueSkge1xyXG5cclxuICAgIHRoaXMuX251bVZhbHVlID0gdmFsdWU7XHJcbiAgICBsZXQgdHh0ID0gJyc7XHJcbiAgICBpZiAodmFsdWUgIT09IG51bGwpIHtcclxuICAgICAgdHh0ID0gTnVtYmVyUGFyc2VyRm9ybWF0dGVyLmZvcm1hdCh2YWx1ZSwgdGhpcy5mb3JtYXQsIHRoaXMuX3NlcGFyYXRvcnMpO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0eHQgIT09IHRoaXMuX3R4dFZhbHVlKSB7XHJcbiAgICAgIHRoaXMuc2V0VGV4dCh0eHQsIGZhbHNlKTtcclxuICAgIH1cclxuXHJcbiAgICAvLyBObyBuZWVkIHRvIHNlbmQgdG8gbW9kZWwsIGJlY2F1c2UgdGhpcyBwcm9jZXNzb3IgaXMgY2FsbGVkIG9uIG1vZGVsIGNoYW5nZVxyXG4gICAgLy8gYnV0IHN0YXRlIHN0aWxsIG5lZWRzIHRvIGJlIHVwZGF0ZWRcclxuICAgIHRoaXMudXBkYXRlU3RhdGUoKTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgX3NlcGFyYXRvcnM6IEFycmF5PHN0cmluZz4gPSBbJy4nLCAnLCddO1xyXG4gIHByaXZhdGUgX2Zvcm1hdDogc3RyaW5nID0gJ3sxLjJ9JztcclxuXHJcbiAgQElucHV0KCd0cnVlLW1hc2stbnVtYmVyJylcclxuICBwdWJsaWMgc2V0IGZvcm1hdChmOiBzdHJpbmcpIHtcclxuXHJcbiAgICBpZiAodGhpcy5fdHh0VmFsdWUgIT09ICcnICYmIHRoaXMuX2Zvcm1hdCAhPT0gZikge1xyXG4gICAgICAvLyDQn9C+INGB0LvQvtC20L3QvtC80YMg0L/Rg9GC0LhcclxuICAgICAgbGV0IHJlcyA9IHRoaXMuY3VycmVudFJlcygpO1xyXG4gICAgICB0aGlzLl9mb3JtYXQgPSBmO1xyXG5cclxuICAgICAgbGV0IHN0YXRlID0gTnVtYmVyUGFyc2VyRm9ybWF0dGVyLnJlZm9ybWF0KHRoaXMuX3R4dFZhbHVlLFxyXG4gICAgICAgIHRoaXMuZm9ybWF0LCB0aGlzLl9zZXBhcmF0b3JzLFxyXG4gICAgICAgIHJlcy5zZWxTdGFydCwgcmVzLnNlbFN0YXJ0ICsgcmVzLnNlbExlbmd0aCxcclxuICAgICAgICB0cnVlIC8vIENvbnZlcnQgdG8gZm9ybWF0XHJcbiAgICAgICk7XHJcblxyXG4gICAgICB0aGlzLnNldFJlcyh0aGlzLmdldFJlcyhzdGF0ZS52YWx1ZSwgc3RhdGUuc2VsU3RhcnQsIHN0YXRlLnNlbEVuZCkpO1xyXG5cclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRoaXMuX2Zvcm1hdCA9IGY7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgZ2V0IGZvcm1hdCgpOiBzdHJpbmcge1xyXG4gICAgaWYgKHRoaXMuX2Zvcm1hdCA9PT0gJ2N1cnJlbmN5Jykge1xyXG4gICAgICByZXR1cm4gdGhpcy5pbnRsLmxvY2FsZS5jdXJyZW5jeTtcclxuICAgIH1cclxuICAgIHJldHVybiB0aGlzLl9mb3JtYXQ7XHJcbiAgfVxyXG5cclxuICBhbmRyb2lkX2JlaGF2aW9yOiBib29sZWFuID0gZmFsc2U7XHJcbiAgbGFzdF9yZXM6IE1hc2tSZXN1bHQ7XHJcblxyXG4gIEBIb3N0TGlzdGVuZXIoJ2tleWRvd24nLCBbJyRldmVudCddKVxyXG4gIGtleURvd24oZTogYW55KSB7XHJcbiAgICByZXR1cm4gdGhpcy5wcm9jZXNzS2V5KGUpO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIHByb2Nlc3NLZXkoZTogYW55KTogYm9vbGVhbiB7XHJcblxyXG4gICAgaWYgKGUua2V5Q29kZSA9PT0gMjI5IHx8IGUua2V5Q29kZSA9PT0gMCB8fCBlLmtleUNvZGUgPT09IHVuZGVmaW5lZCkgeyAvLyB0ZXN0OiBpZiAoZS5rZXlDb2RlID49IDApIC4uLlxyXG4gICAgICAvLyBBbmRyb2lkIGRldGVjdGVkXHJcbiAgICAgIHRoaXMuYW5kcm9pZF9iZWhhdmlvciA9IHRydWU7XHJcbiAgICAgIHRoaXMubGFzdF9yZXMgPSB0aGlzLmN1cnJlbnRSZXMoKTtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IGMgPSBLZXlzLmtleUNoYXIoZSk7XHJcblxyXG4gICAgbGV0IHNlbFN0YXJ0OiBudW1iZXIgPSBlLnRhcmdldC5zZWxlY3Rpb25TdGFydDtcclxuICAgIGxldCBzZWxFbmQ6IG51bWJlciA9IGUudGFyZ2V0LnNlbGVjdGlvbkVuZDtcclxuICAgIGxldCBzOiBzdHJpbmcgPSB0aGlzLl90eHRWYWx1ZTtcclxuXHJcbiAgICBjb25zdCBzdGF0ZTA6IGFueSA9IHRoaXMuZ2V0UmVzKHMsIHNlbFN0YXJ0LCBzZWxFbmQpO1xyXG5cclxuICAgIGlmIChLZXlzLmlzRnVuY3Rpb25hbChlLmtleUNvZGUpKSB7XHJcbiAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChlLmtleUNvZGUgPT09IEtleXMuVEFCIHx8IGUua2V5Q29kZSA9PT0gS2V5cy5FU0NBUEUpIHtcclxuICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKGUua2V5Q29kZSA9PT0gS2V5cy5IT01FIHx8IGUua2V5Q29kZSA9PT0gS2V5cy5FTkQpIHtcclxuICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKGUuc2hpZnRLZXkgJiYgKGUua2V5Q29kZSA9PT0gS2V5cy5ERUxFVEUgfHwgZS5rZXlDb2RlID09PSBLZXlzLklOU0VSVCkpIHtcclxuICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKGUuY3RybEtleSAmJiBlLmtleUNvZGUgPT09IEtleXMuWikge1xyXG4gICAgICAvLyBVTkRPXHJcbiAgICAgIGxldCB1bmRvUmVzID0gdGhpcy5fdW5kby5wb3AoKTtcclxuICAgICAgaWYgKHVuZG9SZXMpIHtcclxuICAgICAgICB0aGlzLl9yZWRvLnB1c2godGhpcy5nZXRSZXMocywgc2VsU3RhcnQsIHNlbEVuZCkpO1xyXG4gICAgICAgIHRoaXMuc2V0UmVzKHVuZG9SZXMpO1xyXG4gICAgICB9XHJcbiAgICAgIGUucHJldmVudERlZmF1bHQoKTtcclxuICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChlLmN0cmxLZXkgJiYgZS5rZXlDb2RlID09PSBLZXlzLlkpIHtcclxuICAgICAgLy8gUkVET1xyXG4gICAgICBsZXQgcmVkb1JlcyA9IHRoaXMuX3JlZG8ucG9wKCk7XHJcbiAgICAgIGlmIChyZWRvUmVzKSB7XHJcbiAgICAgICAgdGhpcy5fdW5kby5wdXNoKHRoaXMuZ2V0UmVzKHMsIHNlbFN0YXJ0LCBzZWxFbmQpKTtcclxuICAgICAgICB0aGlzLnNldFJlcyhyZWRvUmVzKTtcclxuICAgICAgfVxyXG4gICAgICBlLnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoZS5jdHJsS2V5KSB7XHJcbiAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChzZWxTdGFydCA9PT0gMCAmJiBzZWxFbmQgPT09IHRoaXMuX3R4dFZhbHVlLmxlbmd0aCkge1xyXG4gICAgICBzID0gJyc7XHJcbiAgICAgIHNlbFN0YXJ0ID0gMDtcclxuICAgICAgc2VsRW5kID0gMDtcclxuICAgIH1cclxuXHJcbiAgICBsZXQgbGVhZFRvRm9ybWF0ID0gZmFsc2U7XHJcbiAgICBsZXQgYXBwbGllZCA9IGZhbHNlO1xyXG5cclxuICAgIGlmIChlLmtleUNvZGUgPT09IEtleXMuQkFDS1NQQUNFIHx8IGUua2V5Q29kZSA9PT0gS2V5cy5ERUxFVEUpIHtcclxuXHJcbiAgICAgIGxldCBjYW5BY2NlcHQgPSBOdW1iZXJQYXJzZXJGb3JtYXR0ZXIuY2FuQWNjZXB0S2V5KHMsIGUua2V5Q29kZSwgYywgdGhpcy5mb3JtYXQsIHRoaXMuX3NlcGFyYXRvcnMsIHNlbFN0YXJ0LCBzZWxFbmQpO1xyXG5cclxuICAgICAgaWYgKHNlbFN0YXJ0ID09PSBzZWxFbmQpIHtcclxuICAgICAgICAvLyDQndC40YfQtdCz0L4g0L3QtSDQstGL0LTQtdC70LXQvdC+XHJcbiAgICAgICAgaWYgKGUua2V5Q29kZSA9PT0gS2V5cy5CQUNLU1BBQ0UgJiYgc2VsU3RhcnQgPiAwKSB7XHJcbiAgICAgICAgICBpZiAoY2FuQWNjZXB0KVxyXG4gICAgICAgICAgICBzID0gcy5zdWJzdHJpbmcoMCwgc2VsU3RhcnQgLSAxKSArIHMuc3Vic3RyaW5nKHNlbEVuZCk7XHJcblxyXG4gICAgICAgICAgc2VsU3RhcnQtLTtcclxuICAgICAgICAgIHNlbEVuZC0tO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKGUua2V5Q29kZSA9PT0gS2V5cy5ERUxFVEUpIHtcclxuICAgICAgICAgIGlmIChjYW5BY2NlcHQpXHJcbiAgICAgICAgICAgIHMgPSBzLnN1YnN0cmluZygwLCBzZWxTdGFydCkgKyBzLnN1YnN0cmluZyhzZWxFbmQgKyAxKTtcclxuICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICBzZWxTdGFydCsrO1xyXG4gICAgICAgICAgICBzZWxFbmQrKztcclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGFwcGxpZWQgPSB0cnVlO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBpZiAoc2VsU3RhcnQgPCBzZWxFbmQpIHtcclxuICAgICAgICAvLyDQktGL0LTQtdC70LXQvdC+INC+0LTQuNC9INC40LvQuCDQsdC+0LvQtdC1INGB0LjQvNCy0L7Qu9C+0LJcclxuICAgICAgICBsZXQgZnJhZ21lbnRUb0RlbGV0ZSA9IHMuc3Vic3RyaW5nKHNlbFN0YXJ0LCBzZWxFbmQpO1xyXG5cclxuICAgICAgICBpZiAoY2FuQWNjZXB0KSB7XHJcbiAgICAgICAgICBpZiAoZnJhZ21lbnRUb0RlbGV0ZS5pbmRleE9mKHRoaXMuX3NlcGFyYXRvcnNbMF0pID49IDApIHtcclxuICAgICAgICAgICAgcyA9IHMuc3Vic3RyaW5nKDAsIHNlbFN0YXJ0KSArIHRoaXMuX3NlcGFyYXRvcnNbMF0gKyBzLnN1YnN0cmluZyhzZWxFbmQpO1xyXG4gICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgcyA9IHMuc3Vic3RyaW5nKDAsIHNlbFN0YXJ0KSArIHMuc3Vic3RyaW5nKHNlbEVuZCk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBzZWxFbmQgPSBzZWxTdGFydDtcclxuICAgICAgICBhcHBsaWVkID0gdHJ1ZTtcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGlmIChjLmxlbmd0aCA9PT0gMSkge1xyXG4gICAgICBzID0gcy5zdWJzdHJpbmcoMCwgc2VsU3RhcnQpICsgcy5zdWJzdHJpbmcoc2VsRW5kKTtcclxuXHJcbiAgICAgIGlmIChOdW1iZXJQYXJzZXJGb3JtYXR0ZXIuY2FuQWNjZXB0S2V5KHMsIGUua2V5Q29kZSwgYywgdGhpcy5mb3JtYXQsIHRoaXMuX3NlcGFyYXRvcnMsIHNlbFN0YXJ0KSkge1xyXG5cclxuICAgICAgICBzID0gcy5zdWJzdHJpbmcoMCwgc2VsU3RhcnQpICsgYyArIHMuc3Vic3RyaW5nKHNlbFN0YXJ0KTtcclxuICAgICAgICBzZWxTdGFydCsrO1xyXG4gICAgICAgIHNlbEVuZCA9IHNlbFN0YXJ0O1xyXG4gICAgICAgIGFwcGxpZWQgPSB0cnVlO1xyXG5cclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKGFwcGxpZWQpIHtcclxuICAgICAgLy8g0J/RgNC4INC40LfQvNC10L3QtdC90LjQuCDQt9C90LDRh9C10L3QuNGPINCy0L3QtdGB0LXQvCDQsiDRgdGC0Y3QuiB1bmRvXHJcbiAgICAgIGlmIChzICE9PSBzdGF0ZTAubmV3VmFsdWUpIHtcclxuICAgICAgICB0aGlzLl91bmRvLnB1c2goc3RhdGUwKTtcclxuICAgICAgICB0aGlzLl9yZWRvID0gW107XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGNvbnN0IHN0YXRlMyA9IE51bWJlclBhcnNlckZvcm1hdHRlci5yZWZvcm1hdChzLCB0aGlzLmZvcm1hdCwgdGhpcy5fc2VwYXJhdG9ycywgc2VsU3RhcnQsIHNlbEVuZCwgbGVhZFRvRm9ybWF0KTtcclxuICAgICAgdGhpcy5zZXRSZXModGhpcy5nZXRSZXMoc3RhdGUzLnZhbHVlLCBzdGF0ZTMuc2VsU3RhcnQsIHN0YXRlMy5zZWxFbmQpKTtcclxuXHJcbiAgICAgIGlmICh0aGlzLmFuZHJvaWRfYmVoYXZpb3IpIHtcclxuICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgfVxyXG5cclxuICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHRydWU7XHJcbiAgfVxyXG5cclxuICAvLyDQo9GB0YLQsNC90L7QstC40YLRjCDQt9C90LDRh9C10L3QuNC1INC4INC/0L7Qu9C+0LbQtdC90LjQtSDQutGD0YDRgdC+0YDQsFxyXG4gIHByb3RlY3RlZCBzZXRSZXMocmVzOiBNYXNrUmVzdWx0KSB7XHJcblxyXG4gICAgaWYgKHRoaXMuYW5kcm9pZF9iZWhhdmlvcilcclxuICAgICAgcmVzLnNlbExlbmd0aCA9IDA7XHJcblxyXG4gICAgdGhpcy5zZXRUZXh0KHJlcy5uZXdWYWx1ZSk7XHJcbiAgICB0aGlzLl9yZW5kZXJlci5zZXRQcm9wZXJ0eSh0aGlzLl9lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQsICdzZWxlY3Rpb25TdGFydCcsIHJlcy5zZWxTdGFydCk7XHJcbiAgICB0aGlzLl9yZW5kZXJlci5zZXRQcm9wZXJ0eSh0aGlzLl9lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQsICdzZWxlY3Rpb25FbmQnLCByZXMuc2VsU3RhcnQgKyByZXMuc2VsTGVuZ3RoKTtcclxuICB9XHJcblxyXG4gIHByb3RlY3RlZCBjdXJyZW50UmVzKCkge1xyXG4gICAgbGV0IHJlcyA9IG5ldyBNYXNrUmVzdWx0KHRoaXMuX3R4dFZhbHVlLCBNYXNrU2VjdGlvbkFjdGlvbi5BUFBMWSwgMCk7XHJcbiAgICByZXMuc2VsU3RhcnQgPSB0aGlzLl9lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQuc2VsZWN0aW9uU3RhcnQ7XHJcbiAgICByZXMuc2VsTGVuZ3RoID0gdGhpcy5fZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LnNlbGVjdGlvbkVuZCAtIHJlcy5zZWxTdGFydDtcclxuICAgIHJldHVybiByZXM7XHJcbiAgfVxyXG5cclxuICAvLyDQn9C+0LvRg9GH0LjRgtGMINGC0LXQutGD0YnQtdC1INC30L3QsNGH0LXQvdC40LUg0LzQsNGB0LrQuCDQuCDQv9C+0LvQvtC20LXQvdC40LUg0LrRg9GA0YHQvtGA0LBcclxuICBwcm90ZWN0ZWQgZ2V0UmVzKHM6IHN0cmluZywgc2VsU3RhcnQ6IG51bWJlciwgc2VsRW5kOiBudW1iZXIpOiBNYXNrUmVzdWx0IHtcclxuICAgIGxldCByZXMgPSBuZXcgTWFza1Jlc3VsdChzLCBNYXNrU2VjdGlvbkFjdGlvbi5BUFBMWSwgMCk7XHJcbiAgICByZXMuc2VsU3RhcnQgPSBzZWxTdGFydDtcclxuICAgIHJlcy5zZWxMZW5ndGggPSBzZWxFbmQgLSBzZWxTdGFydDtcclxuICAgIHJldHVybiByZXM7XHJcbiAgfVxyXG5cclxuICAvLyDQl9Cw0L/QuNGB0YvQstCw0LXRgiDRgtC10LrRgdGCINCyINC60L7QvdGC0YDQvtC7XHJcbiAgcHJvdGVjdGVkIHNldFRleHQoZGlzcGxheWVkVmFsdWU6IHN0cmluZywgdG9Nb2RlbDogYm9vbGVhbiA9IHRydWUpIHtcclxuXHJcbiAgICAvLyDQntGC0L7QsdGA0LDQttCw0LXQvFxyXG4gICAgdGhpcy5fdHh0VmFsdWUgPSBkaXNwbGF5ZWRWYWx1ZTtcclxuICAgIHRoaXMuX3JlbmRlcmVyLnNldFByb3BlcnR5KHRoaXMuX2VsZW1lbnRSZWYubmF0aXZlRWxlbWVudCwgJ3ZhbHVlJywgdGhpcy5fdHh0VmFsdWUpO1xyXG5cclxuICAgIC8vINCe0YLQv9GA0LDQstC70Y/QtdC8INCyINC80L7QtNC10LvRjFxyXG4gICAgaWYgKHRvTW9kZWwpIHtcclxuICAgICAgdGhpcy50b01vZGVsKCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBzZXRMb2NhbGUobG9jYWxlOiBMb2NhbGUpIHtcclxuICAgIHRoaXMuX3NlcGFyYXRvcnNbMF0gPSBsb2NhbGUuc2VwYXJhdG9yc1swXTtcclxuICAgIHRoaXMuX3NlcGFyYXRvcnNbMV0gPSBsb2NhbGUuc2VwYXJhdG9yc1sxXTtcclxuXHJcbiAgICAvLyBVcGRhdGluZyB2aWV3XHJcbiAgICB0aGlzLndyaXRlVmFsdWUodGhpcy5fbnVtVmFsdWUpO1xyXG4gIH1cclxuXHJcbiAgbmdPbkRlc3Ryb3koKSB7XHJcbiAgICAvLyBVbnN1YnNjcmliaW5nXHJcbiAgICB0aGlzLl9sb2NhbGVTdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcclxuICB9XHJcblxyXG4gIGNvbnN0cnVjdG9yKHByb3RlY3RlZCBfcmVuZGVyZXI6IFJlbmRlcmVyMixcclxuICAgICAgcHJvdGVjdGVkIF9lbGVtZW50UmVmOiBFbGVtZW50UmVmLFxyXG4gICAgICBwcm90ZWN0ZWQgaW50bDogSW50ZXJuYXRpb25hbGl6YXRpb25TZXJ2aWNlKSB7XHJcbiAgICAvLyBGb3JtYXQgY2hhbmdlIGNhbiBmb2xsb3cgbG9jYWxlIGNoYW5nZVxyXG4gICAgdGhpcy5fbG9jYWxlU3Vic2NyaXB0aW9uID0gdGhpcy5pbnRsLm9uTG9jYWxlQ2hhbmdlZC5zdWJzY3JpYmUobG9jYWxlID0+IHRoaXMuc2V0TG9jYWxlKGxvY2FsZSkpO1xyXG4gIH1cclxufVxyXG4iXX0=