ng-diff-match-patch-att
Version:
A Diff-Match-Patch component for your Angular 6+ applications
285 lines (284 loc) • 28.4 kB
JavaScript
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
import { Component, Input } from '@angular/core';
import { DiffMatchPatchService } from './diffMatchPatch.service';
/** @typedef {?} */
var DiffCalculation;
export class LineCompareComponent {
/**
* @param {?} dmp
*/
constructor(dmp) {
this.dmp = dmp;
}
/**
* @return {?}
*/
ngOnInit() {
this.updateHtml();
}
/**
* @return {?}
*/
ngOnChanges() {
this.updateHtml();
}
/**
* @return {?}
*/
updateHtml() {
if (typeof this.left === 'number' || typeof this.left === 'boolean') {
this.left = this.left.toString();
}
if (typeof this.right === 'number' || typeof this.right === 'boolean') {
this.right = this.right.toString();
}
this.calculateLineDiff(this.dmp.getLineDiff(this.left, this.right));
}
/**
* @param {?} diffs
* @return {?}
*/
calculateLineDiff(diffs) {
/** @type {?} */
const diffCalculation = {
lines: [],
lineLeft: 1,
lineRight: 1
};
this.isContentEqual = diffs.length === 1 && diffs[0][0] === 0 /* Equal */;
if (this.isContentEqual) {
this.calculatedDiff = [];
return;
}
for (let i = 0; i < diffs.length; i++) {
/** @type {?} */
const diff = diffs[i];
/** @type {?} */
let diffLines = diff[1].split(/\r?\n/);
// If the original line had a \r\n at the end then remove the
// empty string after it.
if (diffLines[diffLines.length - 1].length == 0) {
diffLines.pop();
}
switch (diff[0]) {
case 0 /* Equal */: {
/** @type {?} */
const isFirstDiff = i === 0;
/** @type {?} */
const isLastDiff = i === diffs.length - 1;
this.outputEqualDiff(diffLines, diffCalculation, isFirstDiff, isLastDiff);
break;
}
case -1 /* Delete */: {
this.outputDeleteDiff(diffLines, diffCalculation);
break;
}
case 1 /* Insert */: {
this.outputInsertDiff(diffLines, diffCalculation);
break;
}
}
}
this.calculatedDiff = diffCalculation.lines;
}
/**
* @param {?} diffLines
* @param {?} diffCalculation
* @param {?} isFirstDiff
* @param {?} isLastDiff
* @return {?}
*/
outputEqualDiff(diffLines, diffCalculation, isFirstDiff, isLastDiff) {
if (this.lineContextSize && diffLines.length > this.lineContextSize) {
if (isFirstDiff) {
/** @type {?} */
const lineIncrement = diffLines.length - this.lineContextSize;
diffCalculation.lineLeft += lineIncrement;
diffCalculation.lineRight += lineIncrement;
diffLines = diffLines.slice(diffLines.length - this.lineContextSize, diffLines.length);
}
else if (isLastDiff) {
// Take only the first 'lineContextSize' lines from the final diff
diffLines = diffLines.slice(0, this.lineContextSize);
}
else if (diffLines.length > 2 * this.lineContextSize) {
// Take the first 'lineContextSize' lines from this diff to provide context for the last diff
this.outputEqualDiffLines(diffLines.slice(0, this.lineContextSize), diffCalculation);
// Output a special line indicating that some content is equal and has been skipped
diffCalculation.lines.push(['dmp-line-compare-equal', '...', '...', '...']);
/** @type {?} */
const numberOfSkippedLines = diffLines.length - (2 * this.lineContextSize);
diffCalculation.lineLeft += numberOfSkippedLines;
diffCalculation.lineRight += numberOfSkippedLines;
// Take the last 'lineContextSize' lines from this diff to provide context for the next diff
this.outputEqualDiffLines(diffLines.slice(diffLines.length - this.lineContextSize), diffCalculation);
// This if branch has already output the diff lines so we return early to avoid outputting the lines
// at the end of the method.
return;
}
}
this.outputEqualDiffLines(diffLines, diffCalculation);
}
/**
* @param {?} diffLines
* @param {?} diffCalculation
* @return {?}
*/
outputEqualDiffLines(diffLines, diffCalculation) {
for (const line of diffLines) {
diffCalculation.lines.push(['dmp-line-compare-equal', `${diffCalculation.lineLeft}`, `${diffCalculation.lineRight}`, line]);
diffCalculation.lineLeft++;
diffCalculation.lineRight++;
}
}
/**
* @param {?} diffLines
* @param {?} diffCalculation
* @return {?}
*/
outputDeleteDiff(diffLines, diffCalculation) {
for (const line of diffLines) {
diffCalculation.lines.push(['dmp-line-compare-delete', `${diffCalculation.lineLeft}`, '-', line]);
diffCalculation.lineLeft++;
}
}
/**
* @param {?} diffLines
* @param {?} diffCalculation
* @return {?}
*/
outputInsertDiff(diffLines, diffCalculation) {
for (const line of diffLines) {
diffCalculation.lines.push(['dmp-line-compare-insert', '-', `${diffCalculation.lineRight}`, line]);
diffCalculation.lineRight++;
}
}
}
LineCompareComponent.decorators = [
{ type: Component, args: [{
selector: 'dmp-line-compare',
styles: [`
div.dmp-line-compare {
display: flex;
flex-direction: row;
border: 1px solid #808080;
font-family: Consolas, Courier, monospace;
width: 911px;
}
div.dmp-line-compare-margin {
width: 101px;
}
div.dmp-line-compare-content {
position: relative;
top: 0px;
left: 0px;
flex-grow: 1;
overflow-x: scroll;
}
div.dmp-line-compare-content-wrapper {
position: absolute;
top: 0px;
left: 0px;
display: flex;
flex-direction: column;
align-items: stretch;
}
div.dmp-line-compare-left {
width: 50px;
text-align: center;
color: #484848;
}
div.dmp-line-compare-equal>div.dmp-line-compare-left,
div.dmp-line-compare-equal>div.dmp-line-compare-right {
background-color: #dedede;
}
div.dmp-line-compare-insert>div.dmp-line-compare-left,
div.dmp-line-compare-insert>div.dmp-line-compare-right {
background-color: #8bfb6f;
}
div.dmp-line-compare-delete>div.dmp-line-compare-left,
div.dmp-line-compare-delete>div.dmp-line-compare-right {
background-color: #f56868;
}
div.dmp-line-compare-right {
width: 50px;
text-align: center;
color: #484848;
border-right: 1px solid #888888;
}
div.dmp-line-compare-text {
white-space: pre;
padding-left: 10px;
min-width: 800px;
}
.dmp-line-compare-delete {
background-color: #ff8c8c;
}
.dmp-line-compare-insert {
background-color: #9dff97;
}
.dmp-line-compare-delete>div {
display: inline-block;
}
.dmp-line-compare-insert>div {
display: inline-block;
}
.dmp-line-compare-equal>div {
display: inline-block;
}
.dmp-margin-bottom-spacer {
height: 20px;
background-color: #dedede;
border-right: 1px solid #888888;
}
`],
template: `
<div class="dmp-line-compare-no-changes-text" *ngIf="isContentEqual">
There are no changes to display.
</div>
<div class="dmp-line-compare" *ngIf="!isContentEqual">
<div class="dmp-line-compare-margin">
<div [ngClass]="lineDiff[0]" *ngFor="let lineDiff of calculatedDiff">
<div class="dmp-line-compare-left">{{lineDiff[1]}}</div><!-- No space
--><div class="dmp-line-compare-right">{{lineDiff[2]}}</div>
</div>
<div class="dmp-margin-bottom-spacer"></div>
</div><!-- No space
--><div class="dmp-line-compare-content">
<div class="dmp-line-compare-content-wrapper">
<div [ngClass]="lineDiff[0]" *ngFor="let lineDiff of calculatedDiff">
<div class="dmp-line-compare-text">{{lineDiff[3]}}</div>
</div>
</div>
</div>
</div>
`
},] },
];
/** @nocollapse */
LineCompareComponent.ctorParameters = () => [
{ type: DiffMatchPatchService }
];
LineCompareComponent.propDecorators = {
left: [{ type: Input }],
right: [{ type: Input }],
lineContextSize: [{ type: Input }]
};
if (false) {
/** @type {?} */
LineCompareComponent.prototype.left;
/** @type {?} */
LineCompareComponent.prototype.right;
/** @type {?} */
LineCompareComponent.prototype.lineContextSize;
/** @type {?} */
LineCompareComponent.prototype.calculatedDiff;
/** @type {?} */
LineCompareComponent.prototype.isContentEqual;
/** @type {?} */
LineCompareComponent.prototype.dmp;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGluZUNvbXBhcmUuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6Im5nOi8vbmctZGlmZi1tYXRjaC1wYXRjaC1hdHQvIiwic291cmNlcyI6WyJsaWIvbGluZUNvbXBhcmUuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7QUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBcUIsTUFBTSxlQUFlLENBQUM7QUFFcEUsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sMEJBQTBCLENBQUM7OztBQWdIakUsTUFBTTs7OztnQkFjUTtRQUFBLFFBQUcsR0FBSCxHQUFHOzs7OztJQUVSLFFBQVE7UUFDYixJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7Ozs7O0lBR2IsV0FBVztRQUNoQixJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7Ozs7O0lBR1osVUFBVTtRQUNoQixFQUFFLENBQUMsQ0FBQyxPQUFPLElBQUksQ0FBQyxJQUFJLEtBQUssUUFBUSxJQUFJLE9BQU8sSUFBSSxDQUFDLElBQUksS0FBSyxTQUFTLENBQUMsQ0FBQyxDQUFDO1lBQ3BFLElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztTQUNsQztRQUNELEVBQUUsQ0FBQyxDQUFDLE9BQU8sSUFBSSxDQUFDLEtBQUssS0FBSyxRQUFRLElBQUksT0FBTyxJQUFJLENBQUMsS0FBSyxLQUFLLFNBQVMsQ0FBQyxDQUFDLENBQUM7WUFDdEUsSUFBSSxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsRUFBRSxDQUFDO1NBQ3BDO1FBQ0QsSUFBSSxDQUFDLGlCQUFpQixDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7Ozs7OztJQUc5RCxpQkFBaUIsQ0FBQyxLQUFrQjs7UUFDMUMsTUFBTSxlQUFlLEdBQW9CO1lB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QWdDO1FBQ2xDLEdBQUcsQ0FBQyxDQUFDLE1BQU0sSUFBSSxJQUFJLFNBQVMsQ0FBQyxDQUFDLENBQUM7WUFDN0IsZUFBZSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyx5QkFBeUIsRUFBRSxHQUFHLGVBQWUsQ0FBQyxRQUFRLEVBQUUsRUFBRSxHQUFHLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQztZQUNsRyxlQUFlLENBQUMsUUFBUSxFQUFFLENBQUM7U0FDNUI7Ozs7Ozs7SUFHSyxnQkFBZ0IsQ0FDcEIsU0FBbUIsRUFDbkIsZUFBZ0M7UUFDbEMsR0FBRyxDQUFDLENBQUMsTUFBTSxJQUFJLElBQUksU0FBUyxDQUFDLENBQUMsQ0FBQztZQUM3QixlQUFlLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDLHlCQUF5QixFQUFFLEdBQUcsRUFBRSxHQUFHLGVBQWUsQ0FBQyxTQUFTLEVBQUUsRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDO1lBQ25HLGVBQWUsQ0FBQyxTQUFTLEVBQUUsQ0FBQztTQUM3Qjs7OztZQTdQSixTQUFTLFNBQUM7Z0JBQ1QsUUFBUSxFQUFFLGtCQUFrQjtnQkFDNUIsTUFBTSxFQUFFLENBQUM7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBMEVSLENBQUM7Z0JBQ0YsUUFBUSxFQUFFOzs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQW9CVDthQUNGOzs7O1lBL0dRLHFCQUFxQjs7O21CQWlIM0IsS0FBSztvQkFFTCxLQUFLOzhCQUlMLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIElucHV0LCBPbkluaXQsIE9uQ2hhbmdlcyB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgRGlmZiwgRGlmZk9wIH0gZnJvbSAnLi9kaWZmTWF0Y2hQYXRjaCc7XG5pbXBvcnQgeyBEaWZmTWF0Y2hQYXRjaFNlcnZpY2UgfSBmcm9tICcuL2RpZmZNYXRjaFBhdGNoLnNlcnZpY2UnO1xuXG4vKiBIb2xkcyB0aGUgc3RhdGUgb2YgdGhlIGNhbGN1bGF0aW9uIG9mIHRoZSBkaWZmIHJlc3VsdCB3ZSBpbnRlbmQgdG8gZGlzcGxheS5cbiAqICA+IGxpbmVzIGNvbnRhaW5zIHRoZSBkYXRhIHRoYXQgd2lsbCBiZSBkaXNwbGF5ZWQgb24gc2NyZWVuLlxuICogID4gbGluZUxlZnQga2VlcHMgdHJhY2sgb2YgdGhlIGRvY3VtZW50IGxpbmUgbnVtYmVyIGluIHRoZSBbbGVmdF0gaW5wdXQuXG4gKiAgPiBsaW5lUmlnaHQga2VlcHMgdHJhY2sgb2YgdGhlIGRvY3VtZW50IGxpbmUgbnVtYmVyIGluIHRoZSBbcmlnaHRdIGlucHV0LlxuICovXG50eXBlIERpZmZDYWxjdWxhdGlvbiA9IHtcbiAgbGluZXM6IEFycmF5PFtzdHJpbmcsIHN0cmluZywgc3RyaW5nLCBzdHJpbmddPixcbiAgbGluZUxlZnQ6IG51bWJlcixcbiAgbGluZVJpZ2h0OiBudW1iZXJcbn07XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2RtcC1saW5lLWNvbXBhcmUnLFxuICBzdHlsZXM6IFtgXG4gICAgZGl2LmRtcC1saW5lLWNvbXBhcmUge1xuICAgICAgZGlzcGxheTogZmxleDtcbiAgICAgIGZsZXgtZGlyZWN0aW9uOiByb3c7XG4gICAgICBib3JkZXI6IDFweCBzb2xpZCAjODA4MDgwO1xuICAgICAgZm9udC1mYW1pbHk6IENvbnNvbGFzLCBDb3VyaWVyLCBtb25vc3BhY2U7XG4gICAgICB3aWR0aDogOTExcHg7XG4gICAgfVxuICAgIGRpdi5kbXAtbGluZS1jb21wYXJlLW1hcmdpbiB7XG4gICAgICB3aWR0aDogMTAxcHg7XG4gICAgfVxuICAgIGRpdi5kbXAtbGluZS1jb21wYXJlLWNvbnRlbnQge1xuICAgICAgcG9zaXRpb246IHJlbGF0aXZlO1xuICAgICAgdG9wOiAwcHg7XG4gICAgICBsZWZ0OiAwcHg7XG4gICAgICBmbGV4LWdyb3c6IDE7XG4gICAgICBvdmVyZmxvdy14OiBzY3JvbGw7XG4gICAgfVxuICAgIGRpdi5kbXAtbGluZS1jb21wYXJlLWNvbnRlbnQtd3JhcHBlciB7XG4gICAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgICB0b3A6IDBweDtcbiAgICAgIGxlZnQ6IDBweDtcbiAgICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgICBmbGV4LWRpcmVjdGlvbjogY29sdW1uO1xuICAgICAgYWxpZ24taXRlbXM6IHN0cmV0Y2g7XG4gICAgfVxuICAgIGRpdi5kbXAtbGluZS1jb21wYXJlLWxlZnQge1xuICAgICAgd2lkdGg6IDUwcHg7XG4gICAgICB0ZXh0LWFsaWduOiBjZW50ZXI7XG4gICAgICBjb2xvcjogIzQ4NDg0ODtcbiAgICB9XG4gICAgZGl2LmRtcC1saW5lLWNvbXBhcmUtZXF1YWw+ZGl2LmRtcC1saW5lLWNvbXBhcmUtbGVmdCxcbiAgICAgIGRpdi5kbXAtbGluZS1jb21wYXJlLWVxdWFsPmRpdi5kbXAtbGluZS1jb21wYXJlLXJpZ2h0IHtcbiAgICAgIGJhY2tncm91bmQtY29sb3I6ICNkZWRlZGU7XG4gICAgfVxuICAgIGRpdi5kbXAtbGluZS1jb21wYXJlLWluc2VydD5kaXYuZG1wLWxpbmUtY29tcGFyZS1sZWZ0LFxuICAgICAgZGl2LmRtcC1saW5lLWNvbXBhcmUtaW5zZXJ0PmRpdi5kbXAtbGluZS1jb21wYXJlLXJpZ2h0IHtcbiAgICAgIGJhY2tncm91bmQtY29sb3I6ICM4YmZiNmY7XG4gICAgfVxuICAgIGRpdi5kbXAtbGluZS1jb21wYXJlLWRlbGV0ZT5kaXYuZG1wLWxpbmUtY29tcGFyZS1sZWZ0LFxuICAgICAgZGl2LmRtcC1saW5lLWNvbXBhcmUtZGVsZXRlPmRpdi5kbXAtbGluZS1jb21wYXJlLXJpZ2h0IHtcbiAgICAgIGJhY2tncm91bmQtY29sb3I6ICNmNTY4Njg7XG4gICAgfVxuICAgIGRpdi5kbXAtbGluZS1jb21wYXJlLXJpZ2h0IHtcbiAgICAgIHdpZHRoOiA1MHB4O1xuICAgICAgdGV4dC1hbGlnbjogY2VudGVyO1xuICAgICAgY29sb3I6ICM0ODQ4NDg7XG4gICAgICBib3JkZXItcmlnaHQ6IDFweCBzb2xpZCAjODg4ODg4O1xuICAgIH1cbiAgICBkaXYuZG1wLWxpbmUtY29tcGFyZS10ZXh0IHtcbiAgICAgIHdoaXRlLXNwYWNlOiBwcmU7XG4gICAgICBwYWRkaW5nLWxlZnQ6IDEwcHg7XG4gICAgICBtaW4td2lkdGg6IDgwMHB4O1xuICAgIH1cbiAgICAuZG1wLWxpbmUtY29tcGFyZS1kZWxldGUge1xuICAgICAgYmFja2dyb3VuZC1jb2xvcjogI2ZmOGM4YztcbiAgICB9XG4gICAgLmRtcC1saW5lLWNvbXBhcmUtaW5zZXJ0IHtcbiAgICAgIGJhY2tncm91bmQtY29sb3I6ICM5ZGZmOTc7XG4gICAgfVxuICAgIC5kbXAtbGluZS1jb21wYXJlLWRlbGV0ZT5kaXYge1xuICAgICAgZGlzcGxheTogaW5saW5lLWJsb2NrO1xuICAgIH0gIFxuICAgIC5kbXAtbGluZS1jb21wYXJlLWluc2VydD5kaXYge1xuICAgICAgZGlzcGxheTogaW5saW5lLWJsb2NrO1xuICAgIH1cbiAgICAuZG1wLWxpbmUtY29tcGFyZS1lcXVhbD5kaXYge1xuICAgICAgZGlzcGxheTogaW5saW5lLWJsb2NrO1xuICAgIH1cbiAgICAuZG1wLW1hcmdpbi1ib3R0b20tc3BhY2VyIHtcbiAgICAgIGhlaWdodDogMjBweDtcbiAgICAgIGJhY2tncm91bmQtY29sb3I6ICNkZWRlZGU7XG4gICAgICBib3JkZXItcmlnaHQ6IDFweCBzb2xpZCAjODg4ODg4O1xuICAgIH1cbiAgYF0sXG4gIHRlbXBsYXRlOiBgXG4gICAgPGRpdiBjbGFzcz1cImRtcC1saW5lLWNvbXBhcmUtbm8tY2hhbmdlcy10ZXh0XCIgKm5nSWY9XCJpc0NvbnRlbnRFcXVhbFwiPlxuICAgICAgVGhlcmUgYXJlIG5vIGNoYW5nZXMgdG8gZGlzcGxheS5cbiAgICA8L2Rpdj4gICAgXG4gICAgPGRpdiBjbGFzcz1cImRtcC1saW5lLWNvbXBhcmVcIiAqbmdJZj1cIiFpc0NvbnRlbnRFcXVhbFwiPlxuICAgICAgPGRpdiBjbGFzcz1cImRtcC1saW5lLWNvbXBhcmUtbWFyZ2luXCI+XG4gICAgICAgIDxkaXYgW25nQ2xhc3NdPVwibGluZURpZmZbMF1cIiAqbmdGb3I9XCJsZXQgbGluZURpZmYgb2YgY2FsY3VsYXRlZERpZmZcIj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiZG1wLWxpbmUtY29tcGFyZS1sZWZ0XCI+e3tsaW5lRGlmZlsxXX19PC9kaXY+PCEtLSBObyBzcGFjZVxuICAgICAgICAtLT48ZGl2IGNsYXNzPVwiZG1wLWxpbmUtY29tcGFyZS1yaWdodFwiPnt7bGluZURpZmZbMl19fTwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImRtcC1tYXJnaW4tYm90dG9tLXNwYWNlclwiPjwvZGl2PlxuICAgICAgPC9kaXY+PCEtLSBObyBzcGFjZVxuICAgLS0+PGRpdiBjbGFzcz1cImRtcC1saW5lLWNvbXBhcmUtY29udGVudFwiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwiZG1wLWxpbmUtY29tcGFyZS1jb250ZW50LXdyYXBwZXJcIj5cbiAgICAgICAgICA8ZGl2IFtuZ0NsYXNzXT1cImxpbmVEaWZmWzBdXCIgKm5nRm9yPVwibGV0IGxpbmVEaWZmIG9mIGNhbGN1bGF0ZWREaWZmXCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZG1wLWxpbmUtY29tcGFyZS10ZXh0XCI+e3tsaW5lRGlmZlszXX19PC9kaXY+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG4gIGBcbn0pXG5leHBvcnQgY2xhc3MgTGluZUNvbXBhcmVDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIE9uQ2hhbmdlcyB7XG4gIEBJbnB1dCgpXG4gIHB1YmxpYyBsZWZ0OiBzdHJpbmcgfCBudW1iZXIgfCBib29sZWFuO1xuICBASW5wdXQoKVxuICBwdWJsaWMgcmlnaHQ6IHN0cmluZyB8IG51bWJlciB8IGJvb2xlYW47XG4gIC8vIFRoZSBudW1iZXIgb2YgbGluZXMgb2YgY29udGV4dCB0byBwcm92aWRlIGVpdGhlciBzaWRlIG9mIGEgRGlmZk9wLkluc2VydCBvciBEaWZmT3AuRGVsZXRlIGRpZmYuXG4gIC8vIENvbnRleHQgaXMgdGFrZW4gZnJvbSBhIERpZmZPcC5FcXVhbCBzZWN0aW9uLlxuICBASW5wdXQoKVxuICBwdWJsaWMgbGluZUNvbnRleHRTaXplOiBudW1iZXI7XG5cbiAgcHVibGljIGNhbGN1bGF0ZWREaWZmOiBBcnJheTxbc3RyaW5nLCBzdHJpbmcsIHN0cmluZywgc3RyaW5nXT47XG4gIHB1YmxpYyBpc0NvbnRlbnRFcXVhbDogYm9vbGVhbjtcblxuICBwdWJsaWMgY29uc3RydWN0b3IoXG4gICAgICBwcml2YXRlIGRtcDogRGlmZk1hdGNoUGF0Y2hTZXJ2aWNlKSB7fVxuXG4gIHB1YmxpYyBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICB0aGlzLnVwZGF0ZUh0bWwoKTtcbiAgfVxuXG4gIHB1YmxpYyBuZ09uQ2hhbmdlcygpOiB2b2lkIHtcbiAgICB0aGlzLnVwZGF0ZUh0bWwoKTtcbiAgfVxuXG4gIHByaXZhdGUgdXBkYXRlSHRtbCgpOiB2b2lkIHtcbiAgICBpZiAodHlwZW9mIHRoaXMubGVmdCA9PT0gJ251bWJlcicgfHwgdHlwZW9mIHRoaXMubGVmdCA9PT0gJ2Jvb2xlYW4nKSB7XG4gICAgICB0aGlzLmxlZnQgPSB0aGlzLmxlZnQudG9TdHJpbmcoKTtcbiAgICB9XG4gICAgaWYgKHR5cGVvZiB0aGlzLnJpZ2h0ID09PSAnbnVtYmVyJyB8fCB0eXBlb2YgdGhpcy5yaWdodCA9PT0gJ2Jvb2xlYW4nKSB7XG4gICAgICB0aGlzLnJpZ2h0ID0gdGhpcy5yaWdodC50b1N0cmluZygpO1xuICAgIH1cbiAgICB0aGlzLmNhbGN1bGF0ZUxpbmVEaWZmKHRoaXMuZG1wLmdldExpbmVEaWZmKHRoaXMubGVmdCwgdGhpcy5yaWdodCkpO1xuICB9XG5cbiAgcHJpdmF0ZSBjYWxjdWxhdGVMaW5lRGlmZihkaWZmczogQXJyYXk8RGlmZj4pOiB2b2lkIHtcbiAgICBjb25zdCBkaWZmQ2FsY3VsYXRpb246IERpZmZDYWxjdWxhdGlvbiA9IHtcbiAgICAgIGxpbmVzOiBbXSxcbiAgICAgIGxpbmVMZWZ0OiAxLFxuICAgICAgbGluZVJpZ2h0OiAxXG4gICAgfTtcblxuICAgIHRoaXMuaXNDb250ZW50RXF1YWwgPSBkaWZmcy5sZW5ndGggPT09IDEgJiYgZGlmZnNbMF1bMF0gPT09IERpZmZPcC5FcXVhbDtcbiAgICBpZiAodGhpcy5pc0NvbnRlbnRFcXVhbCkge1xuICAgICAgdGhpcy5jYWxjdWxhdGVkRGlmZiA9IFtdO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZGlmZnMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IGRpZmYgPSBkaWZmc1tpXTtcbiAgICAgIGxldCBkaWZmTGluZXM6IHN0cmluZ1tdID0gZGlmZlsxXS5zcGxpdCgvXFxyP1xcbi8pO1xuXG4gICAgICAvLyBJZiB0aGUgb3JpZ2luYWwgbGluZSBoYWQgYSBcXHJcXG4gYXQgdGhlIGVuZCB0aGVuIHJlbW92ZSB0aGVcbiAgICAgIC8vIGVtcHR5IHN0cmluZyBhZnRlciBpdC5cbiAgICAgIGlmIChkaWZmTGluZXNbZGlmZkxpbmVzLmxlbmd0aCAtIDFdLmxlbmd0aCA9PSAwKSB7XG4gICAgICAgIGRpZmZMaW5lcy5wb3AoKTtcbiAgICAgIH1cblxuICAgICAgc3dpdGNoIChkaWZmWzBdKSB7XG4gICAgICAgIGNhc2UgRGlmZk9wLkVxdWFsOiB7XG4gICAgICAgICAgY29uc3QgaXNGaXJzdERpZmYgPSBpID09PSAwO1xuICAgICAgICAgIGNvbnN0IGlzTGFzdERpZmYgPSBpID09PSBkaWZmcy5sZW5ndGggLSAxO1xuICAgICAgICAgIHRoaXMub3V0cHV0RXF1YWxEaWZmKGRpZmZMaW5lcywgZGlmZkNhbGN1bGF0aW9uLCBpc0ZpcnN0RGlmZiwgaXNMYXN0RGlmZik7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgY2FzZSBEaWZmT3AuRGVsZXRlOiB7XG4gICAgICAgICAgdGhpcy5vdXRwdXREZWxldGVEaWZmKGRpZmZMaW5lcywgZGlmZkNhbGN1bGF0aW9uKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBjYXNlIERpZmZPcC5JbnNlcnQ6IHtcbiAgICAgICAgICB0aGlzLm91dHB1dEluc2VydERpZmYoZGlmZkxpbmVzLCBkaWZmQ2FsY3VsYXRpb24pO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5jYWxjdWxhdGVkRGlmZiA9IGRpZmZDYWxjdWxhdGlvbi5saW5lcztcbiAgfVxuXG4gIC8qIElmIHRoZSBudW1iZXIgb2YgZGlmZkxpbmVzIGlzIGdyZWF0ZXIgdGhhbiBsaW5lQ29udGV4dFNpemUgdGhlbiB3ZSBtYXkgbmVlZCB0byBhZGp1c3QgdGhlIGRpZmZcbiAgICogdGhhdCBpcyBvdXRwdXQuXG4gICAqICAgPiBJZiB0aGUgZmlyc3QgZGlmZiBvZiBhIGRvY3VtZW50IGlzIERpZmZPcC5FcXVhbCB0aGVuIHRoZSBsZWFkaW5nIGxpbmVzIGNhbiBiZSBkcm9wcGVkXG4gICAqICAgICBsZWF2aW5nIHRoZSBsYXN0ICdsaW5lQ29udGV4dFNpemUnIGxpbmVzIGZvciBjb250ZXh0LlxuICAgKiAgID4gSWYgdGhlIGxhc3QgZGlmZiBvZiBhIGRvY3VtZW50IGlzIERpZmZPcC5FcXVhbCB0aGVuIHRoZSB0cmFpbGluZyBsaW5lcyBjYW4gYmUgZHJvcHBlZFxuICAgKiAgICAgbGVhdmluZyB0aGUgZmlyc3QgJ2xpbmVDb250ZXh0U2l6ZScgbGluZXMgZm9yIGNvbnRleHQuXG4gICAqICAgPiBJZiB0aGUgZGlmZiBpcyBhIERpZmZPcC5FcXVhbCBvY2N1cnMgaW4gdGhlIG1pZGRsZSB0aGVuIHRoZSBkaWZmcyBlaXRoZXIgc2lkZSBvZiBpdCBtdXN0IGJlXG4gICAqICAgICBEaWZmT3AuSW5zZXJ0IG9yIERpZmZPcC5EZWxldGUuIElmIGl0IGhhcyBtb3JlIHRoYW4gMiAqICdsaW5lQ29udGV4dFNpemUnIGxpbmVzIG9mIGNvbnRlbnRcbiAgICogICAgIHRoZW4gdGhlIG1pZGRsZSBsaW5lcyBhcmUgZHJvcHBlZCBsZWF2aW5nIHRoZSBmaXJzdCAnbGluZUNvbnRleHRTaXplJyBhbmQgbGFzdCAnbGluZUNvbnRleHRTaXplJ1xuICAgKiAgICAgbGluZXMgZm9yIGNvbnRleHQuIEEgc3BlY2lhbCBsaW5lIGlzIGluc2VydGVkIHdpdGggJy4uLicgaW5kaWNhdGluZyB0aGF0IGNvbnRlbnQgaXMgc2tpcHBlZC5cbiAgICpcbiAgICogQSBkb2N1bWVudCBjYW5ub3QgY29uc2lzdCBvZiBhIHNpbmdsZSBEaWZmIHdpdGggRGlmZk9wLkVxdWFsIGFuZCByZWFjaCB0aGlzIGZ1bmN0aW9uIGJlY2F1c2VcbiAgICogaW4gdGhpcyBjYXNlIHRoZSBjYWxjdWxhdGVMaW5lRGlmZiBtZXRob2QgcmV0dXJucyBlYXJseS5cbiAgICovXG4gIHByaXZhdGUgb3V0cHV0RXF1YWxEaWZmKFxuICAgICAgZGlmZkxpbmVzOiBzdHJpbmdbXSxcbiAgICAgIGRpZmZDYWxjdWxhdGlvbjogRGlmZkNhbGN1bGF0aW9uLFxuICAgICAgaXNGaXJzdERpZmY6IGJvb2xlYW4sXG4gICAgICBpc0xhc3REaWZmOiBib29sZWFuKTogdm9pZCB7XG4gICAgaWYgKHRoaXMubGluZUNvbnRleHRTaXplICYmIGRpZmZMaW5lcy5sZW5ndGggPiB0aGlzLmxpbmVDb250ZXh0U2l6ZSkge1xuICAgICAgaWYgKGlzRmlyc3REaWZmKSB7XG4gICAgICAgIC8vIFRha2UgdGhlIGxhc3QgJ2xpbmVDb250ZXh0U2l6ZScgbGluZXMgZnJvbSB0aGUgZmlyc3QgZGlmZlxuICAgICAgICBjb25zdCBsaW5lSW5jcmVtZW50ID0gZGlmZkxpbmVzLmxlbmd0aCAtIHRoaXMubGluZUNvbnRleHRTaXplO1xuICAgICAgICBkaWZmQ2FsY3VsYXRpb24ubGluZUxlZnQgKz0gbGluZUluY3JlbWVudDtcbiAgICAgICAgZGlmZkNhbGN1bGF0aW9uLmxpbmVSaWdodCArPSBsaW5lSW5jcmVtZW50O1xuICAgICAgICBkaWZmTGluZXMgPSBkaWZmTGluZXMuc2xpY2UoZGlmZkxpbmVzLmxlbmd0aCAtIHRoaXMubGluZUNvbnRleHRTaXplLCBkaWZmTGluZXMubGVuZ3RoKTtcbiAgICAgIH1cbiAgICAgIGVsc2UgaWYgKGlzTGFzdERpZmYpIHtcbiAgICAgICAgLy8gVGFrZSBvbmx5IHRoZSBmaXJzdCAnbGluZUNvbnRleHRTaXplJyBsaW5lcyBmcm9tIHRoZSBmaW5hbCBkaWZmXG4gICAgICAgIGRpZmZMaW5lcyA9IGRpZmZMaW5lcy5zbGljZSgwLCB0aGlzLmxpbmVDb250ZXh0U2l6ZSk7XG4gICAgICB9XG4gICAgICBlbHNlIGlmIChkaWZmTGluZXMubGVuZ3RoID4gMiAqIHRoaXMubGluZUNvbnRleHRTaXplKSB7XG4gICAgICAgIC8vIFRha2UgdGhlIGZpcnN0ICdsaW5lQ29udGV4dFNpemUnIGxpbmVzIGZyb20gdGhpcyBkaWZmIHRvIHByb3ZpZGUgY29udGV4dCBmb3IgdGhlIGxhc3QgZGlmZlxuICAgICAgICB0aGlzLm91dHB1dEVxdWFsRGlmZkxpbmVzKGRpZmZMaW5lcy5zbGljZSgwLCB0aGlzLmxpbmVDb250ZXh0U2l6ZSksIGRpZmZDYWxjdWxhdGlvbik7XG5cbiAgICAgICAgLy8gT3V0cHV0IGEgc3BlY2lhbCBsaW5lIGluZGljYXRpbmcgdGhhdCBzb21lIGNvbnRlbnQgaXMgZXF1YWwgYW5kIGhhcyBiZWVuIHNraXBwZWRcbiAgICAgICAgZGlmZkNhbGN1bGF0aW9uLmxpbmVzLnB1c2goWydkbXAtbGluZS1jb21wYXJlLWVxdWFsJywgJy4uLicsICcuLi4nLCAnLi4uJ10pO1xuICAgICAgICBjb25zdCBudW1iZXJPZlNraXBwZWRMaW5lcyA9IGRpZmZMaW5lcy5sZW5ndGggLSAoMiAqIHRoaXMubGluZUNvbnRleHRTaXplKTtcbiAgICAgICAgZGlmZkNhbGN1bGF0aW9uLmxpbmVMZWZ0ICs9IG51bWJlck9mU2tpcHBlZExpbmVzO1xuICAgICAgICBkaWZmQ2FsY3VsYXRpb24ubGluZVJpZ2h0ICs9IG51bWJlck9mU2tpcHBlZExpbmVzO1xuXG4gICAgICAgIC8vIFRha2UgdGhlIGxhc3QgJ2xpbmVDb250ZXh0U2l6ZScgbGluZXMgZnJvbSB0aGlzIGRpZmYgdG8gcHJvdmlkZSBjb250ZXh0IGZvciB0aGUgbmV4dCBkaWZmXG4gICAgICAgIHRoaXMub3V0cHV0RXF1YWxEaWZmTGluZXMoZGlmZkxpbmVzLnNsaWNlKGRpZmZMaW5lcy5sZW5ndGggLSB0aGlzLmxpbmVDb250ZXh0U2l6ZSksIGRpZmZDYWxjdWxhdGlvbik7XG4gICAgICAgIC8vIFRoaXMgaWYgYnJhbmNoIGhhcyBhbHJlYWR5IG91dHB1dCB0aGUgZGlmZiBsaW5lcyBzbyB3ZSByZXR1cm4gZWFybHkgdG8gYXZvaWQgb3V0cHV0dGluZyB0aGUgbGluZXNcbiAgICAgICAgLy8gYXQgdGhlIGVuZCBvZiB0aGUgbWV0aG9kLlxuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfVxuICAgIHRoaXMub3V0cHV0RXF1YWxEaWZmTGluZXMoZGlmZkxpbmVzLCBkaWZmQ2FsY3VsYXRpb24pO1xuICB9XG5cbiAgcHJpdmF0ZSBvdXRwdXRFcXVhbERpZmZMaW5lcyhcbiAgICAgIGRpZmZMaW5lczogc3RyaW5nW10sXG4gICAgICBkaWZmQ2FsY3VsYXRpb246IERpZmZDYWxjdWxhdGlvbik6IHZvaWQge1xuICAgIGZvciAoY29uc3QgbGluZSBvZiBkaWZmTGluZXMpIHtcbiAgICAgIGRpZmZDYWxjdWxhdGlvbi5saW5lcy5wdXNoKFsnZG1wLWxpbmUtY29tcGFyZS1lcXVhbCcsIGAke2RpZmZDYWxjdWxhdGlvbi5saW5lTGVmdH1gLCBgJHtkaWZmQ2FsY3VsYXRpb24ubGluZVJpZ2h0fWAsIGxpbmVdKTtcbiAgICAgIGRpZmZDYWxjdWxhdGlvbi5saW5lTGVmdCsrO1xuICAgICAgZGlmZkNhbGN1bGF0aW9uLmxpbmVSaWdodCsrO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgb3V0cHV0RGVsZXRlRGlmZihcbiAgICAgIGRpZmZMaW5lczogc3RyaW5nW10sXG4gICAgICBkaWZmQ2FsY3VsYXRpb246IERpZmZDYWxjdWxhdGlvbik6IHZvaWQge1xuICAgIGZvciAoY29uc3QgbGluZSBvZiBkaWZmTGluZXMpIHtcbiAgICAgIGRpZmZDYWxjdWxhdGlvbi5saW5lcy5wdXNoKFsnZG1wLWxpbmUtY29tcGFyZS1kZWxldGUnLCBgJHtkaWZmQ2FsY3VsYXRpb24ubGluZUxlZnR9YCwgJy0nLCBsaW5lXSk7XG4gICAgICBkaWZmQ2FsY3VsYXRpb24ubGluZUxlZnQrKztcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIG91dHB1dEluc2VydERpZmYoXG4gICAgICBkaWZmTGluZXM6IHN0cmluZ1tdLFxuICAgICAgZGlmZkNhbGN1bGF0aW9uOiBEaWZmQ2FsY3VsYXRpb24pOiB2b2lkIHtcbiAgICBmb3IgKGNvbnN0IGxpbmUgb2YgZGlmZkxpbmVzKSB7XG4gICAgICBkaWZmQ2FsY3VsYXRpb24ubGluZXMucHVzaChbJ2RtcC1saW5lLWNvbXBhcmUtaW5zZXJ0JywgJy0nLCBgJHtkaWZmQ2FsY3VsYXRpb24ubGluZVJpZ2h0fWAsIGxpbmVdKTtcbiAgICAgIGRpZmZDYWxjdWxhdGlvbi5saW5lUmlnaHQrKztcbiAgICB9XG4gIH1cbn1cbiJdfQ==