ngx-gem-spaas
Version:
This library contains services, components, images and styles to provide a unified look and way-of-working throughout GEM SPaaS.
189 lines • 26.4 kB
JavaScript
import { Directive, EventEmitter, HostListener, Input, Output } from '@angular/core';
import { Subject } from 'rxjs';
import * as i0 from "@angular/core";
export class TableSelectionFreeDirective {
constructor() {
this.freeSelectionMatrix = [];
this.freeSelectionLockAxis = '';
this.selectionChanged = new EventEmitter(); // will emit the last selected row and column
this.isSelecting = false;
this.selectionId = 1;
// set the from/to variables to public because it's very handy to be able to access these directly in the template
this.fromCol = 0;
this.fromRow = 0;
this.toCol = 0;
this.toRow = 0;
this.onDestroy = new Subject();
}
mouseDown(e) {
const mouseData = this.checkMouseData(e);
if (mouseData.valid) {
this.onClickCell(e, mouseData.rowIdx, mouseData.colIdx);
}
}
mouseMove(e) {
const mouseData = this.checkMouseData(e);
if (this.isSelecting &&
mouseData.valid &&
(mouseData.rowIdx !== this.toRow || mouseData.colIdx !== this.toCol)) {
this.onSelecting(mouseData.rowIdx, mouseData.colIdx);
}
}
mouseUp() {
this.onStopSelect('mouseup');
}
mouseLeave() {
this.onStopSelect('mouseleave');
}
sort() {
this.resetSelectionRange(true, true);
this.emitNewSelection();
}
ngOnDestroy() {
this.onDestroy.next();
this.onDestroy.complete();
}
checkMouseData(e) {
const target = (e.target);
let dataset = target?.dataset;
if (!dataset?.rowIdx) {
// also check the offsetParent, for cells with sub-divs
dataset = (target?.offsetParent).dataset;
}
let rowIdx = -1, colIdx = -1;
if (dataset?.rowIdx && dataset.colIdx) {
rowIdx = Number.isNaN((Number(dataset.rowIdx))) ? -1 : Number(dataset.rowIdx);
colIdx = Number.isNaN((Number(dataset.colIdx))) ? -1 : Number(dataset.colIdx);
}
return {
valid: rowIdx > -1 && colIdx > -1,
rowIdx: rowIdx,
colIdx: colIdx
};
}
onClickCell(e, rowIdx, colIdx) {
if (!e) {
return;
}
this.isSelecting = true;
if (!e.shiftKey && !e.ctrlKey) {
// normal click: update all selection variables
++this.selectionId;
this.fromRow = rowIdx;
this.fromCol = colIdx;
this.toRow = rowIdx;
this.toCol = colIdx;
this.resetSelectionRange(true);
}
else if (e.shiftKey) {
// shift click: set last variables for range selection
document.getSelection()?.removeAllRanges();
this.setTo(rowIdx, colIdx);
this.updateSelectionRange();
}
else if (e.ctrlKey) {
// ctrl-click in non-origin row/col and lock-axis is active: reset all (considered a regular click in this case)
if ((this.freeSelectionLockAxis === 'x' && rowIdx !== this.fromRow) ||
(this.freeSelectionLockAxis === 'y' && colIdx !== this.fromCol)) {
this.resetSelectionRange(true);
}
// ctrl key: just set for cell itself
++this.selectionId;
this.freeSelectionMatrix[rowIdx][colIdx] = !this.freeSelectionMatrix[rowIdx][colIdx] ? this.selectionId : 0;
if (this.freeSelectionMatrix[rowIdx][colIdx]) {
this.fromRow = rowIdx;
this.fromCol = colIdx;
this.setTo(rowIdx, colIdx);
}
else {
// it's a deselection: search for last selected cell to put focus on
for (let row = 0; row < this.freeSelectionMatrix.length; row++) {
for (let col = 0; col < this.freeSelectionMatrix[row].length; col++) {
if (this.freeSelectionMatrix[row][col]) {
this.toRow = row;
this.toCol = col;
}
}
}
}
}
}
onSelecting(rowIdx, colIdx) {
if (this.isSelecting) {
document.getSelection()?.removeAllRanges();
this.setTo(rowIdx, colIdx);
this.resetSelectionRange();
this.updateSelectionRange();
}
}
onStopSelect(fromMouseEvent) {
if (this.isSelecting) {
this.isSelecting = false;
if (fromMouseEvent === 'mouseup') {
this.emitNewSelection();
}
}
}
emitNewSelection() {
this.selectionChanged.emit(this.freeSelectionMatrix[this.toRow][this.toCol] > 0 ?
{ row: this.toRow, column: this.toCol } :
{ row: -1, column: -1 });
}
setTo(rowIdx, colIdx) {
this.toRow = this.freeSelectionLockAxis === 'x' ? this.fromRow : rowIdx;
this.toCol = this.freeSelectionLockAxis === 'y' ? this.fromCol : colIdx;
}
resetSelectionRange(fullReset = false, fromSort = false) {
const wasSelected = this.freeSelectionMatrix[this.toRow][this.toCol] > 0;
for (let rowIdx = 0; rowIdx < this.freeSelectionMatrix.length; rowIdx++) {
for (let colIdx = 0; colIdx < this.freeSelectionMatrix[rowIdx].length; colIdx++) {
if (fullReset || this.freeSelectionMatrix[rowIdx][colIdx] === this.selectionId) {
this.freeSelectionMatrix[rowIdx][colIdx] = 0;
}
}
}
this.freeSelectionMatrix[this.toRow][this.toCol] = fromSort || wasSelected ? 0 : this.selectionId;
}
updateSelectionRange() {
const fromRow = Math.min(this.fromRow, this.toRow);
const toRow = Math.max(this.fromRow, this.toRow);
const fromCol = Math.min(this.fromCol, this.toCol);
const toCol = Math.max(this.fromCol, this.toCol);
for (let rowIdx = fromRow; rowIdx <= toRow; rowIdx++) {
for (let colIdx = fromCol; colIdx <= toCol; colIdx++) {
this.freeSelectionMatrix[rowIdx][colIdx] = this.selectionId;
}
}
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: TableSelectionFreeDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.12", type: TableSelectionFreeDirective, selector: "[spaasTableSelectionFree]", inputs: { freeSelectionMatrix: "freeSelectionMatrix", freeSelectionLockAxis: "freeSelectionLockAxis" }, outputs: { selectionChanged: "selectionChanged" }, host: { listeners: { "mousedown": "mouseDown($event)", "mousemove": "mouseMove($event)", "mouseup": "mouseUp($event)", "mouseleave": "mouseLeave($event)", "tableSortedOrFiltered": "sort($event)" } }, exportAs: ["spaasTableSelectionFree"], ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: TableSelectionFreeDirective, decorators: [{
type: Directive,
args: [{
selector: '[spaasTableSelectionFree]',
exportAs: 'spaasTableSelectionFree'
}]
}], propDecorators: { freeSelectionMatrix: [{
type: Input
}], freeSelectionLockAxis: [{
type: Input
}], selectionChanged: [{
type: Output
}], mouseDown: [{
type: HostListener,
args: ['mousedown', ['$event']]
}], mouseMove: [{
type: HostListener,
args: ['mousemove', ['$event']]
}], mouseUp: [{
type: HostListener,
args: ['mouseup', ['$event']]
}], mouseLeave: [{
type: HostListener,
args: ['mouseleave', ['$event']]
}], sort: [{
type: HostListener,
args: ['tableSortedOrFiltered', ['$event']]
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFibGUtc2VsZWN0aW9uLWZyZWUuZGlyZWN0aXZlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LWdlbS1zcGFhcy90YWJsZS9zcmMvX2RpcmVjdGl2ZXMvdGFibGUtc2VsZWN0aW9uLWZyZWUuZGlyZWN0aXZlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBQyxTQUFTLEVBQUUsWUFBWSxFQUFFLFlBQVksRUFBRSxLQUFLLEVBQWEsTUFBTSxFQUFDLE1BQU0sZUFBZSxDQUFDO0FBQzlGLE9BQU8sRUFBQyxPQUFPLEVBQUMsTUFBTSxNQUFNLENBQUM7O0FBTTdCLE1BQU0sT0FBTywyQkFBMkI7SUFKeEM7UUFNVyx3QkFBbUIsR0FBZSxFQUFFLENBQUM7UUFDckMsMEJBQXFCLEdBQW1CLEVBQUUsQ0FBQztRQUUxQyxxQkFBZ0IsR0FBRyxJQUFJLFlBQVksRUFBbUMsQ0FBQyxDQUFDLDZDQUE2QztRQUUvSCxnQkFBVyxHQUFHLEtBQUssQ0FBQztRQUNaLGdCQUFXLEdBQUcsQ0FBQyxDQUFDO1FBRXhCLGtIQUFrSDtRQUNsSCxZQUFPLEdBQUcsQ0FBQyxDQUFDO1FBQ1osWUFBTyxHQUFHLENBQUMsQ0FBQztRQUNaLFVBQUssR0FBVyxDQUFDLENBQUM7UUFDbEIsVUFBSyxHQUFXLENBQUMsQ0FBQztRQUVWLGNBQVMsR0FBRyxJQUFJLE9BQU8sRUFBUSxDQUFDO0tBb0t6QztJQWpLQyxTQUFTLENBQUMsQ0FBYTtRQUNyQixNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3pDLElBQUksU0FBUyxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ3BCLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQyxFQUFFLFNBQVMsQ0FBQyxNQUFNLEVBQUUsU0FBUyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQzFELENBQUM7SUFDSCxDQUFDO0lBR0QsU0FBUyxDQUFDLENBQWE7UUFDckIsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN6QyxJQUNFLElBQUksQ0FBQyxXQUFXO1lBQ2hCLFNBQVMsQ0FBQyxLQUFLO1lBQ2YsQ0FBQyxTQUFTLENBQUMsTUFBTSxLQUFLLElBQUksQ0FBQyxLQUFLLElBQUksU0FBUyxDQUFDLE1BQU0sS0FBSyxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQ3BFLENBQUM7WUFDRCxJQUFJLENBQUMsV0FBVyxDQUFDLFNBQVMsQ0FBQyxNQUFNLEVBQUUsU0FBUyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ3ZELENBQUM7SUFDSCxDQUFDO0lBR0QsT0FBTztRQUNMLElBQUksQ0FBQyxZQUFZLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDL0IsQ0FBQztJQUdELFVBQVU7UUFDUixJQUFJLENBQUMsWUFBWSxDQUFDLFlBQVksQ0FBQyxDQUFDO0lBQ2xDLENBQUM7SUFHRCxJQUFJO1FBQ0YsSUFBSSxDQUFDLG1CQUFtQixDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQztRQUNyQyxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztJQUMxQixDQUFDO0lBRUQsV0FBVztRQUNULElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDdEIsSUFBSSxDQUFDLFNBQVMsQ0FBQyxRQUFRLEVBQUUsQ0FBQztJQUM1QixDQUFDO0lBRU8sY0FBYyxDQUFDLENBQWE7UUFDbEMsTUFBTSxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFnQixDQUFDO1FBQ3pDLElBQUksT0FBTyxHQUFRLE1BQU0sRUFBRSxPQUFPLENBQUM7UUFDbkMsSUFBSSxDQUFDLE9BQU8sRUFBRSxNQUFNLEVBQUUsQ0FBQztZQUNyQix1REFBdUQ7WUFDdkQsT0FBTyxHQUFJLENBQUMsTUFBTSxFQUFFLFlBQVksQ0FBaUIsQ0FBQyxPQUFPLENBQUM7UUFDNUQsQ0FBQztRQUNELElBQUksTUFBTSxHQUFHLENBQUMsQ0FBQyxFQUFFLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQztRQUM3QixJQUFJLE9BQU8sRUFBRSxNQUFNLElBQUksT0FBTyxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQ3RDLE1BQU0sR0FBRyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQzlFLE1BQU0sR0FBRyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ2hGLENBQUM7UUFDRCxPQUFPO1lBQ0wsS0FBSyxFQUFFLE1BQU0sR0FBRyxDQUFDLENBQUMsSUFBSSxNQUFNLEdBQUcsQ0FBQyxDQUFDO1lBQ2pDLE1BQU0sRUFBRSxNQUFNO1lBQ2QsTUFBTSxFQUFFLE1BQU07U0FDZixDQUFDO0lBQ0osQ0FBQztJQUVPLFdBQVcsQ0FBQyxDQUFhLEVBQUUsTUFBYyxFQUFFLE1BQWM7UUFDL0QsSUFBSSxDQUFDLENBQUMsRUFBRSxDQUFDO1lBQ1AsT0FBTztRQUNULENBQUM7UUFDRCxJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQztRQUN4QixJQUFJLENBQUMsQ0FBQyxDQUFDLFFBQVEsSUFBSSxDQUFDLENBQUMsQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUM5QiwrQ0FBK0M7WUFDL0MsRUFBRSxJQUFJLENBQUMsV0FBVyxDQUFDO1lBQ25CLElBQUksQ0FBQyxPQUFPLEdBQUcsTUFBTSxDQUFDO1lBQ3RCLElBQUksQ0FBQyxPQUFPLEdBQUcsTUFBTSxDQUFDO1lBQ3RCLElBQUksQ0FBQyxLQUFLLEdBQUcsTUFBTSxDQUFDO1lBQ3BCLElBQUksQ0FBQyxLQUFLLEdBQUcsTUFBTSxDQUFDO1lBQ3BCLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNqQyxDQUFDO2FBQU0sSUFBSSxDQUFDLENBQUMsUUFBUSxFQUFFLENBQUM7WUFDdEIsc0RBQXNEO1lBQ3RELFFBQVEsQ0FBQyxZQUFZLEVBQUUsRUFBRSxlQUFlLEVBQUUsQ0FBQztZQUMzQyxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sRUFBRSxNQUFNLENBQUMsQ0FBQztZQUMzQixJQUFJLENBQUMsb0JBQW9CLEVBQUUsQ0FBQztRQUM5QixDQUFDO2FBQU0sSUFBSSxDQUFDLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDckIsZ0hBQWdIO1lBQ2hILElBQ0UsQ0FBQyxJQUFJLENBQUMscUJBQXFCLEtBQUssR0FBRyxJQUFJLE1BQU0sS0FBSyxJQUFJLENBQUMsT0FBTyxDQUFDO2dCQUMvRCxDQUFDLElBQUksQ0FBQyxxQkFBcUIsS0FBSyxHQUFHLElBQUksTUFBTSxLQUFLLElBQUksQ0FBQyxPQUFPLENBQUMsRUFDL0QsQ0FBQztnQkFDRCxJQUFJLENBQUMsbUJBQW1CLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDakMsQ0FBQztZQUNELHFDQUFxQztZQUNyQyxFQUFFLElBQUksQ0FBQyxXQUFXLENBQUM7WUFDbkIsSUFBSSxDQUFDLG1CQUFtQixDQUFDLE1BQU0sQ0FBQyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLG1CQUFtQixDQUFDLE1BQU0sQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDNUcsSUFBSSxJQUFJLENBQUMsbUJBQW1CLENBQUMsTUFBTSxDQUFDLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQztnQkFDN0MsSUFBSSxDQUFDLE9BQU8sR0FBRyxNQUFNLENBQUM7Z0JBQ3RCLElBQUksQ0FBQyxPQUFPLEdBQUcsTUFBTSxDQUFDO2dCQUN0QixJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sRUFBRSxNQUFNLENBQUMsQ0FBQztZQUM3QixDQUFDO2lCQUFNLENBQUM7Z0JBQ04sb0VBQW9FO2dCQUNwRSxLQUFLLElBQUksR0FBRyxHQUFHLENBQUMsRUFBRSxHQUFHLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixDQUFDLE1BQU0sRUFBRSxHQUFHLEVBQUUsRUFBRSxDQUFDO29CQUMvRCxLQUFLLElBQUksR0FBRyxHQUFHLENBQUMsRUFBRSxHQUFHLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixDQUFDLEdBQUcsQ0FBQyxDQUFDLE1BQU0sRUFBRSxHQUFHLEVBQUUsRUFBRSxDQUFDO3dCQUNwRSxJQUFJLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDOzRCQUN2QyxJQUFJLENBQUMsS0FBSyxHQUFHLEdBQUcsQ0FBQzs0QkFDakIsSUFBSSxDQUFDLEtBQUssR0FBRyxHQUFHLENBQUM7d0JBQ25CLENBQUM7b0JBQ0gsQ0FBQztnQkFDSCxDQUFDO1lBQ0gsQ0FBQztRQUNILENBQUM7SUFDSCxDQUFDO0lBRU8sV0FBVyxDQUFDLE1BQWMsRUFBRSxNQUFjO1FBQ2hELElBQUksSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO1lBQ3JCLFFBQVEsQ0FBQyxZQUFZLEVBQUUsRUFBRSxlQUFlLEVBQUUsQ0FBQztZQUMzQyxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sRUFBRSxNQUFNLENBQUMsQ0FBQztZQUMzQixJQUFJLENBQUMsbUJBQW1CLEVBQUUsQ0FBQztZQUMzQixJQUFJLENBQUMsb0JBQW9CLEVBQUUsQ0FBQztRQUM5QixDQUFDO0lBQ0gsQ0FBQztJQUVPLFlBQVksQ0FBQyxjQUF3QztRQUMzRCxJQUFJLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUNyQixJQUFJLENBQUMsV0FBVyxHQUFHLEtBQUssQ0FBQztZQUN6QixJQUFJLGNBQWMsS0FBSyxTQUFTLEVBQUUsQ0FBQztnQkFDakMsSUFBSSxDQUFDLGdCQUFnQixFQUFFLENBQUM7WUFDMUIsQ0FBQztRQUNILENBQUM7SUFDSCxDQUFDO0lBRU8sZ0JBQWdCO1FBQ3RCLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQ3hCLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO1lBQ3BELEVBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxLQUFLLEVBQUUsTUFBTSxFQUFFLElBQUksQ0FBQyxLQUFLLEVBQUMsQ0FBQyxDQUFDO1lBQ3ZDLEVBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQyxFQUFFLE1BQU0sRUFBRSxDQUFDLENBQUMsRUFBQyxDQUN4QixDQUFDO0lBQ0osQ0FBQztJQUVPLEtBQUssQ0FBQyxNQUFjLEVBQUUsTUFBYztRQUMxQyxJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxxQkFBcUIsS0FBSyxHQUFHLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQztRQUN4RSxJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxxQkFBcUIsS0FBSyxHQUFHLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQztJQUMxRSxDQUFDO0lBRU8sbUJBQW1CLENBQUMsU0FBUyxHQUFHLEtBQUssRUFBRSxRQUFRLEdBQUcsS0FBSztRQUM3RCxNQUFNLFdBQVcsR0FBRyxJQUFJLENBQUMsbUJBQW1CLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDekUsS0FBSyxJQUFJLE1BQU0sR0FBRyxDQUFDLEVBQUUsTUFBTSxHQUFHLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxNQUFNLEVBQUUsTUFBTSxFQUFFLEVBQUUsQ0FBQztZQUN4RSxLQUFLLElBQUksTUFBTSxHQUFHLENBQUMsRUFBRSxNQUFNLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixDQUFDLE1BQU0sQ0FBQyxDQUFDLE1BQU0sRUFBRSxNQUFNLEVBQUUsRUFBRSxDQUFDO2dCQUNoRixJQUFJLFNBQVMsSUFBSSxJQUFJLENBQUMsbUJBQW1CLENBQUMsTUFBTSxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO29CQUMvRSxJQUFJLENBQUMsbUJBQW1CLENBQUMsTUFBTSxDQUFDLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDO2dCQUMvQyxDQUFDO1lBQ0gsQ0FBQztRQUNILENBQUM7UUFDRCxJQUFJLENBQUMsbUJBQW1CLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxRQUFRLElBQUksV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUM7SUFDcEcsQ0FBQztJQUVPLG9CQUFvQjtRQUMxQixNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ25ELE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDakQsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNuRCxNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ2pELEtBQUssSUFBSSxNQUFNLEdBQUcsT0FBTyxFQUFFLE1BQU0sSUFBSSxLQUFLLEVBQUUsTUFBTSxFQUFFLEVBQUUsQ0FBQztZQUNyRCxLQUFLLElBQUksTUFBTSxHQUFHLE9BQU8sRUFBRSxNQUFNLElBQUksS0FBSyxFQUFFLE1BQU0sRUFBRSxFQUFFLENBQUM7Z0JBQ3JELElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxNQUFNLENBQUMsQ0FBQyxNQUFNLENBQUMsR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDO1lBQzlELENBQUM7UUFDSCxDQUFDO0lBQ0gsQ0FBQzsrR0FsTFUsMkJBQTJCO21HQUEzQiwyQkFBMkI7OzRGQUEzQiwyQkFBMkI7a0JBSnZDLFNBQVM7bUJBQUM7b0JBQ1QsUUFBUSxFQUFFLDJCQUEyQjtvQkFDckMsUUFBUSxFQUFFLHlCQUF5QjtpQkFDcEM7OEJBR1UsbUJBQW1CO3NCQUEzQixLQUFLO2dCQUNHLHFCQUFxQjtzQkFBN0IsS0FBSztnQkFFSSxnQkFBZ0I7c0JBQXpCLE1BQU07Z0JBY1AsU0FBUztzQkFEUixZQUFZO3VCQUFDLFdBQVcsRUFBRSxDQUFDLFFBQVEsQ0FBQztnQkFTckMsU0FBUztzQkFEUixZQUFZO3VCQUFDLFdBQVcsRUFBRSxDQUFDLFFBQVEsQ0FBQztnQkFhckMsT0FBTztzQkFETixZQUFZO3VCQUFDLFNBQVMsRUFBRSxDQUFDLFFBQVEsQ0FBQztnQkFNbkMsVUFBVTtzQkFEVCxZQUFZO3VCQUFDLFlBQVksRUFBRSxDQUFDLFFBQVEsQ0FBQztnQkFNdEMsSUFBSTtzQkFESCxZQUFZO3VCQUFDLHVCQUF1QixFQUFFLENBQUMsUUFBUSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtEaXJlY3RpdmUsIEV2ZW50RW1pdHRlciwgSG9zdExpc3RlbmVyLCBJbnB1dCwgT25EZXN0cm95LCBPdXRwdXR9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQge1N1YmplY3R9IGZyb20gJ3J4anMnO1xyXG5cclxuQERpcmVjdGl2ZSh7XHJcbiAgc2VsZWN0b3I6ICdbc3BhYXNUYWJsZVNlbGVjdGlvbkZyZWVdJyxcclxuICBleHBvcnRBczogJ3NwYWFzVGFibGVTZWxlY3Rpb25GcmVlJ1xyXG59KVxyXG5leHBvcnQgY2xhc3MgVGFibGVTZWxlY3Rpb25GcmVlRGlyZWN0aXZlIGltcGxlbWVudHMgT25EZXN0cm95IHtcclxuXHJcbiAgQElucHV0KCkgZnJlZVNlbGVjdGlvbk1hdHJpeDogbnVtYmVyW11bXSA9IFtdO1xyXG4gIEBJbnB1dCgpIGZyZWVTZWxlY3Rpb25Mb2NrQXhpczogJycgfCAneCcgfCAneScgPSAnJztcclxuXHJcbiAgQE91dHB1dCgpIHNlbGVjdGlvbkNoYW5nZWQgPSBuZXcgRXZlbnRFbWl0dGVyPHsgcm93OiBudW1iZXIsIGNvbHVtbjogbnVtYmVyIH0+KCk7IC8vIHdpbGwgZW1pdCB0aGUgbGFzdCBzZWxlY3RlZCByb3cgYW5kIGNvbHVtblxyXG5cclxuICBpc1NlbGVjdGluZyA9IGZhbHNlO1xyXG4gIHByaXZhdGUgc2VsZWN0aW9uSWQgPSAxO1xyXG5cclxuICAvLyBzZXQgdGhlIGZyb20vdG8gdmFyaWFibGVzIHRvIHB1YmxpYyBiZWNhdXNlIGl0J3MgdmVyeSBoYW5keSB0byBiZSBhYmxlIHRvIGFjY2VzcyB0aGVzZSBkaXJlY3RseSBpbiB0aGUgdGVtcGxhdGVcclxuICBmcm9tQ29sID0gMDtcclxuICBmcm9tUm93ID0gMDtcclxuICB0b0NvbDogbnVtYmVyID0gMDtcclxuICB0b1JvdzogbnVtYmVyID0gMDtcclxuXHJcbiAgcHJpdmF0ZSBvbkRlc3Ryb3kgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xyXG5cclxuICBASG9zdExpc3RlbmVyKCdtb3VzZWRvd24nLCBbJyRldmVudCddKVxyXG4gIG1vdXNlRG93bihlOiBNb3VzZUV2ZW50KSB7XHJcbiAgICBjb25zdCBtb3VzZURhdGEgPSB0aGlzLmNoZWNrTW91c2VEYXRhKGUpO1xyXG4gICAgaWYgKG1vdXNlRGF0YS52YWxpZCkge1xyXG4gICAgICB0aGlzLm9uQ2xpY2tDZWxsKGUsIG1vdXNlRGF0YS5yb3dJZHgsIG1vdXNlRGF0YS5jb2xJZHgpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgQEhvc3RMaXN0ZW5lcignbW91c2Vtb3ZlJywgWyckZXZlbnQnXSlcclxuICBtb3VzZU1vdmUoZTogTW91c2VFdmVudCkge1xyXG4gICAgY29uc3QgbW91c2VEYXRhID0gdGhpcy5jaGVja01vdXNlRGF0YShlKTtcclxuICAgIGlmIChcclxuICAgICAgdGhpcy5pc1NlbGVjdGluZyAmJlxyXG4gICAgICBtb3VzZURhdGEudmFsaWQgJiZcclxuICAgICAgKG1vdXNlRGF0YS5yb3dJZHggIT09IHRoaXMudG9Sb3cgfHwgbW91c2VEYXRhLmNvbElkeCAhPT0gdGhpcy50b0NvbClcclxuICAgICkge1xyXG4gICAgICB0aGlzLm9uU2VsZWN0aW5nKG1vdXNlRGF0YS5yb3dJZHgsIG1vdXNlRGF0YS5jb2xJZHgpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgQEhvc3RMaXN0ZW5lcignbW91c2V1cCcsIFsnJGV2ZW50J10pXHJcbiAgbW91c2VVcCgpIHtcclxuICAgIHRoaXMub25TdG9wU2VsZWN0KCdtb3VzZXVwJyk7XHJcbiAgfVxyXG5cclxuICBASG9zdExpc3RlbmVyKCdtb3VzZWxlYXZlJywgWyckZXZlbnQnXSlcclxuICBtb3VzZUxlYXZlKCkge1xyXG4gICAgdGhpcy5vblN0b3BTZWxlY3QoJ21vdXNlbGVhdmUnKTtcclxuICB9XHJcblxyXG4gIEBIb3N0TGlzdGVuZXIoJ3RhYmxlU29ydGVkT3JGaWx0ZXJlZCcsIFsnJGV2ZW50J10pXHJcbiAgc29ydCgpIHtcclxuICAgIHRoaXMucmVzZXRTZWxlY3Rpb25SYW5nZSh0cnVlLCB0cnVlKTtcclxuICAgIHRoaXMuZW1pdE5ld1NlbGVjdGlvbigpO1xyXG4gIH1cclxuXHJcbiAgbmdPbkRlc3Ryb3koKSB7XHJcbiAgICB0aGlzLm9uRGVzdHJveS5uZXh0KCk7XHJcbiAgICB0aGlzLm9uRGVzdHJveS5jb21wbGV0ZSgpO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBjaGVja01vdXNlRGF0YShlOiBNb3VzZUV2ZW50KTogeyB2YWxpZDogYm9vbGVhbiwgcm93SWR4OiBudW1iZXIsIGNvbElkeDogbnVtYmVyIH0ge1xyXG4gICAgY29uc3QgdGFyZ2V0ID0gKGUudGFyZ2V0KSBhcyBIVE1MRWxlbWVudDtcclxuICAgIGxldCBkYXRhc2V0OiBhbnkgPSB0YXJnZXQ/LmRhdGFzZXQ7XHJcbiAgICBpZiAoIWRhdGFzZXQ/LnJvd0lkeCkge1xyXG4gICAgICAvLyBhbHNvIGNoZWNrIHRoZSBvZmZzZXRQYXJlbnQsIGZvciBjZWxscyB3aXRoIHN1Yi1kaXZzXHJcbiAgICAgIGRhdGFzZXQgPSAoKHRhcmdldD8ub2Zmc2V0UGFyZW50KSBhcyBIVE1MRWxlbWVudCkuZGF0YXNldDtcclxuICAgIH1cclxuICAgIGxldCByb3dJZHggPSAtMSwgY29sSWR4ID0gLTE7XHJcbiAgICBpZiAoZGF0YXNldD8ucm93SWR4ICYmIGRhdGFzZXQuY29sSWR4KSB7XHJcbiAgICAgIHJvd0lkeCA9IE51bWJlci5pc05hTigoTnVtYmVyKGRhdGFzZXQucm93SWR4KSkpID8gLTEgOiBOdW1iZXIoZGF0YXNldC5yb3dJZHgpO1xyXG4gICAgICBjb2xJZHggPSBOdW1iZXIuaXNOYU4oKE51bWJlcihkYXRhc2V0LmNvbElkeCkpKSA/IC0xIDogTnVtYmVyKGRhdGFzZXQuY29sSWR4KTtcclxuICAgIH1cclxuICAgIHJldHVybiB7XHJcbiAgICAgIHZhbGlkOiByb3dJZHggPiAtMSAmJiBjb2xJZHggPiAtMSxcclxuICAgICAgcm93SWR4OiByb3dJZHgsXHJcbiAgICAgIGNvbElkeDogY29sSWR4XHJcbiAgICB9O1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBvbkNsaWNrQ2VsbChlOiBNb3VzZUV2ZW50LCByb3dJZHg6IG51bWJlciwgY29sSWR4OiBudW1iZXIpOiB2b2lkIHtcclxuICAgIGlmICghZSkge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcbiAgICB0aGlzLmlzU2VsZWN0aW5nID0gdHJ1ZTtcclxuICAgIGlmICghZS5zaGlmdEtleSAmJiAhZS5jdHJsS2V5KSB7XHJcbiAgICAgIC8vIG5vcm1hbCBjbGljazogdXBkYXRlIGFsbCBzZWxlY3Rpb24gdmFyaWFibGVzXHJcbiAgICAgICsrdGhpcy5zZWxlY3Rpb25JZDtcclxuICAgICAgdGhpcy5mcm9tUm93ID0gcm93SWR4O1xyXG4gICAgICB0aGlzLmZyb21Db2wgPSBjb2xJZHg7XHJcbiAgICAgIHRoaXMudG9Sb3cgPSByb3dJZHg7XHJcbiAgICAgIHRoaXMudG9Db2wgPSBjb2xJZHg7XHJcbiAgICAgIHRoaXMucmVzZXRTZWxlY3Rpb25SYW5nZSh0cnVlKTtcclxuICAgIH0gZWxzZSBpZiAoZS5zaGlmdEtleSkge1xyXG4gICAgICAvLyBzaGlmdCBjbGljazogc2V0IGxhc3QgdmFyaWFibGVzIGZvciByYW5nZSBzZWxlY3Rpb25cclxuICAgICAgZG9jdW1lbnQuZ2V0U2VsZWN0aW9uKCk/LnJlbW92ZUFsbFJhbmdlcygpO1xyXG4gICAgICB0aGlzLnNldFRvKHJvd0lkeCwgY29sSWR4KTtcclxuICAgICAgdGhpcy51cGRhdGVTZWxlY3Rpb25SYW5nZSgpO1xyXG4gICAgfSBlbHNlIGlmIChlLmN0cmxLZXkpIHtcclxuICAgICAgLy8gY3RybC1jbGljayBpbiBub24tb3JpZ2luIHJvdy9jb2wgYW5kIGxvY2stYXhpcyBpcyBhY3RpdmU6IHJlc2V0IGFsbCAoY29uc2lkZXJlZCBhIHJlZ3VsYXIgY2xpY2sgaW4gdGhpcyBjYXNlKVxyXG4gICAgICBpZiAoXHJcbiAgICAgICAgKHRoaXMuZnJlZVNlbGVjdGlvbkxvY2tBeGlzID09PSAneCcgJiYgcm93SWR4ICE9PSB0aGlzLmZyb21Sb3cpIHx8XHJcbiAgICAgICAgKHRoaXMuZnJlZVNlbGVjdGlvbkxvY2tBeGlzID09PSAneScgJiYgY29sSWR4ICE9PSB0aGlzLmZyb21Db2wpXHJcbiAgICAgICkge1xyXG4gICAgICAgIHRoaXMucmVzZXRTZWxlY3Rpb25SYW5nZSh0cnVlKTtcclxuICAgICAgfVxyXG4gICAgICAvLyBjdHJsIGtleToganVzdCBzZXQgZm9yIGNlbGwgaXRzZWxmXHJcbiAgICAgICsrdGhpcy5zZWxlY3Rpb25JZDtcclxuICAgICAgdGhpcy5mcmVlU2VsZWN0aW9uTWF0cml4W3Jvd0lkeF1bY29sSWR4XSA9ICF0aGlzLmZyZWVTZWxlY3Rpb25NYXRyaXhbcm93SWR4XVtjb2xJZHhdID8gdGhpcy5zZWxlY3Rpb25JZCA6IDA7XHJcbiAgICAgIGlmICh0aGlzLmZyZWVTZWxlY3Rpb25NYXRyaXhbcm93SWR4XVtjb2xJZHhdKSB7XHJcbiAgICAgICAgdGhpcy5mcm9tUm93ID0gcm93SWR4O1xyXG4gICAgICAgIHRoaXMuZnJvbUNvbCA9IGNvbElkeDtcclxuICAgICAgICB0aGlzLnNldFRvKHJvd0lkeCwgY29sSWR4KTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICAvLyBpdCdzIGEgZGVzZWxlY3Rpb246IHNlYXJjaCBmb3IgbGFzdCBzZWxlY3RlZCBjZWxsIHRvIHB1dCBmb2N1cyBvblxyXG4gICAgICAgIGZvciAobGV0IHJvdyA9IDA7IHJvdyA8IHRoaXMuZnJlZVNlbGVjdGlvbk1hdHJpeC5sZW5ndGg7IHJvdysrKSB7XHJcbiAgICAgICAgICBmb3IgKGxldCBjb2wgPSAwOyBjb2wgPCB0aGlzLmZyZWVTZWxlY3Rpb25NYXRyaXhbcm93XS5sZW5ndGg7IGNvbCsrKSB7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLmZyZWVTZWxlY3Rpb25NYXRyaXhbcm93XVtjb2xdKSB7XHJcbiAgICAgICAgICAgICAgdGhpcy50b1JvdyA9IHJvdztcclxuICAgICAgICAgICAgICB0aGlzLnRvQ29sID0gY29sO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIG9uU2VsZWN0aW5nKHJvd0lkeDogbnVtYmVyLCBjb2xJZHg6IG51bWJlcik6IHZvaWQge1xyXG4gICAgaWYgKHRoaXMuaXNTZWxlY3RpbmcpIHtcclxuICAgICAgZG9jdW1lbnQuZ2V0U2VsZWN0aW9uKCk/LnJlbW92ZUFsbFJhbmdlcygpO1xyXG4gICAgICB0aGlzLnNldFRvKHJvd0lkeCwgY29sSWR4KTtcclxuICAgICAgdGhpcy5yZXNldFNlbGVjdGlvblJhbmdlKCk7XHJcbiAgICAgIHRoaXMudXBkYXRlU2VsZWN0aW9uUmFuZ2UoKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHByaXZhdGUgb25TdG9wU2VsZWN0KGZyb21Nb3VzZUV2ZW50OiAnbW91c2V1cCcgfCAnbW91c2VsZWF2ZScpOiB2b2lkIHtcclxuICAgIGlmICh0aGlzLmlzU2VsZWN0aW5nKSB7XHJcbiAgICAgIHRoaXMuaXNTZWxlY3RpbmcgPSBmYWxzZTtcclxuICAgICAgaWYgKGZyb21Nb3VzZUV2ZW50ID09PSAnbW91c2V1cCcpIHtcclxuICAgICAgICB0aGlzLmVtaXROZXdTZWxlY3Rpb24oKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBlbWl0TmV3U2VsZWN0aW9uKCk6IHZvaWQge1xyXG4gICAgdGhpcy5zZWxlY3Rpb25DaGFuZ2VkLmVtaXQoXHJcbiAgICAgIHRoaXMuZnJlZVNlbGVjdGlvbk1hdHJpeFt0aGlzLnRvUm93XVt0aGlzLnRvQ29sXSA+IDAgP1xyXG4gICAgICAgIHtyb3c6IHRoaXMudG9Sb3csIGNvbHVtbjogdGhpcy50b0NvbH0gOlxyXG4gICAgICAgIHtyb3c6IC0xLCBjb2x1bW46IC0xfVxyXG4gICAgKTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgc2V0VG8ocm93SWR4OiBudW1iZXIsIGNvbElkeDogbnVtYmVyKTogdm9pZCB7XHJcbiAgICB0aGlzLnRvUm93ID0gdGhpcy5mcmVlU2VsZWN0aW9uTG9ja0F4aXMgPT09ICd4JyA/IHRoaXMuZnJvbVJvdyA6IHJvd0lkeDtcclxuICAgIHRoaXMudG9Db2wgPSB0aGlzLmZyZWVTZWxlY3Rpb25Mb2NrQXhpcyA9PT0gJ3knID8gdGhpcy5mcm9tQ29sIDogY29sSWR4O1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSByZXNldFNlbGVjdGlvblJhbmdlKGZ1bGxSZXNldCA9IGZhbHNlLCBmcm9tU29ydCA9IGZhbHNlKTogdm9pZCB7XHJcbiAgICBjb25zdCB3YXNTZWxlY3RlZCA9IHRoaXMuZnJlZVNlbGVjdGlvbk1hdHJpeFt0aGlzLnRvUm93XVt0aGlzLnRvQ29sXSA+IDA7XHJcbiAgICBmb3IgKGxldCByb3dJZHggPSAwOyByb3dJZHggPCB0aGlzLmZyZWVTZWxlY3Rpb25NYXRyaXgubGVuZ3RoOyByb3dJZHgrKykge1xyXG4gICAgICBmb3IgKGxldCBjb2xJZHggPSAwOyBjb2xJZHggPCB0aGlzLmZyZWVTZWxlY3Rpb25NYXRyaXhbcm93SWR4XS5sZW5ndGg7IGNvbElkeCsrKSB7XHJcbiAgICAgICAgaWYgKGZ1bGxSZXNldCB8fCB0aGlzLmZyZWVTZWxlY3Rpb25NYXRyaXhbcm93SWR4XVtjb2xJZHhdID09PSB0aGlzLnNlbGVjdGlvbklkKSB7XHJcbiAgICAgICAgICB0aGlzLmZyZWVTZWxlY3Rpb25NYXRyaXhbcm93SWR4XVtjb2xJZHhdID0gMDtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIHRoaXMuZnJlZVNlbGVjdGlvbk1hdHJpeFt0aGlzLnRvUm93XVt0aGlzLnRvQ29sXSA9IGZyb21Tb3J0IHx8IHdhc1NlbGVjdGVkID8gMCA6IHRoaXMuc2VsZWN0aW9uSWQ7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIHVwZGF0ZVNlbGVjdGlvblJhbmdlKCk6IHZvaWQge1xyXG4gICAgY29uc3QgZnJvbVJvdyA9IE1hdGgubWluKHRoaXMuZnJvbVJvdywgdGhpcy50b1Jvdyk7XHJcbiAgICBjb25zdCB0b1JvdyA9IE1hdGgubWF4KHRoaXMuZnJvbVJvdywgdGhpcy50b1Jvdyk7XHJcbiAgICBjb25zdCBmcm9tQ29sID0gTWF0aC5taW4odGhpcy5mcm9tQ29sLCB0aGlzLnRvQ29sKTtcclxuICAgIGNvbnN0IHRvQ29sID0gTWF0aC5tYXgodGhpcy5mcm9tQ29sLCB0aGlzLnRvQ29sKTtcclxuICAgIGZvciAobGV0IHJvd0lkeCA9IGZyb21Sb3c7IHJvd0lkeCA8PSB0b1Jvdzsgcm93SWR4KyspIHtcclxuICAgICAgZm9yIChsZXQgY29sSWR4ID0gZnJvbUNvbDsgY29sSWR4IDw9IHRvQ29sOyBjb2xJZHgrKykge1xyXG4gICAgICAgIHRoaXMuZnJlZVNlbGVjdGlvbk1hdHJpeFtyb3dJZHhdW2NvbElkeF0gPSB0aGlzLnNlbGVjdGlvbklkO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfVxyXG5cclxufVxyXG4iXX0=