UNPKG

@circuitly/diff

Version:

A javascript text diff implementation.

247 lines (233 loc) 33.7 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.applyPatch = applyPatch; exports.applyPatches = applyPatches; var _string = require("../util/string"); var _lineEndings = require("./line-endings"); var _parse = require("./parse"); var _distanceIterator = _interopRequireDefault(require("../util/distance-iterator")); function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; } function applyPatch(source, uniDiff) { var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; if (typeof uniDiff === 'string') { uniDiff = (0, _parse.parsePatch)(uniDiff); } if (Array.isArray(uniDiff)) { if (uniDiff.length > 1) { throw new Error('applyPatch only works with a single input.'); } uniDiff = uniDiff[0]; } if (options.autoConvertLineEndings || options.autoConvertLineEndings == null) { if ((0, _string.hasOnlyWinLineEndings)(source) && (0, _lineEndings.isUnix)(uniDiff)) { uniDiff = (0, _lineEndings.unixToWin)(uniDiff); } else if ((0, _string.hasOnlyUnixLineEndings)(source) && (0, _lineEndings.isWin)(uniDiff)) { uniDiff = (0, _lineEndings.winToUnix)(uniDiff); } } // Apply the diff to the input var lines = source.split('\n'), hunks = uniDiff.hunks, compareLine = options.compareLine || function (lineNumber, line, operation, patchContent) { return line === patchContent; }, fuzzFactor = options.fuzzFactor || 0, minLine = 0; if (fuzzFactor < 0 || !Number.isInteger(fuzzFactor)) { throw new Error('fuzzFactor must be a non-negative integer'); } // Special case for empty patch. if (!hunks.length) { return source; } // Before anything else, handle EOFNL insertion/removal. If the patch tells us to make a change // to the EOFNL that is redundant/impossible - i.e. to remove a newline that's not there, or add a // newline that already exists - then we either return false and fail to apply the patch (if // fuzzFactor is 0) or simply ignore the problem and do nothing (if fuzzFactor is >0). // If we do need to remove/add a newline at EOF, this will always be in the final hunk: var prevLine = '', removeEOFNL = false, addEOFNL = false; for (var i = 0; i < hunks[hunks.length - 1].lines.length; i++) { var line = hunks[hunks.length - 1].lines[i]; if (line[0] == '\\') { if (prevLine[0] == '+') { removeEOFNL = true; } else if (prevLine[0] == '-') { addEOFNL = true; } } prevLine = line; } if (removeEOFNL) { if (addEOFNL) { // This means the final line gets changed but doesn't have a trailing newline in either the // original or patched version. In that case, we do nothing if fuzzFactor > 0, and if // fuzzFactor is 0, we simply validate that the source file has no trailing newline. if (!fuzzFactor && lines[lines.length - 1] == '') { return false; } } else if (lines[lines.length - 1] == '') { lines.pop(); } else if (!fuzzFactor) { return false; } } else if (addEOFNL) { if (lines[lines.length - 1] != '') { lines.push(''); } else if (!fuzzFactor) { return false; } } /** * Checks if the hunk can be made to fit at the provided location with at most `maxErrors` * insertions, substitutions, or deletions, while ensuring also that: * - lines deleted in the hunk match exactly, and * - wherever an insertion operation or block of insertion operations appears in the hunk, the * immediately preceding and following lines of context match exactly * * `toPos` should be set such that lines[toPos] is meant to match hunkLines[0]. * * If the hunk can be applied, returns an object with properties `oldLineLastI` and * `replacementLines`. Otherwise, returns null. */ function applyHunk(hunkLines, toPos, maxErrors) { var hunkLinesI = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 0; var lastContextLineMatched = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : true; var patchedLines = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : []; var patchedLinesLength = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : 0; var nConsecutiveOldContextLines = 0; var nextContextLineMustMatch = false; for (; hunkLinesI < hunkLines.length; hunkLinesI++) { var hunkLine = hunkLines[hunkLinesI], operation = hunkLine.length > 0 ? hunkLine[0] : ' ', content = hunkLine.length > 0 ? hunkLine.substr(1) : hunkLine; if (operation === '-') { if (compareLine(toPos + 1, lines[toPos], operation, content)) { toPos++; nConsecutiveOldContextLines = 0; } else { if (!maxErrors || lines[toPos] == null) { return null; } patchedLines[patchedLinesLength] = lines[toPos]; return applyHunk(hunkLines, toPos + 1, maxErrors - 1, hunkLinesI, false, patchedLines, patchedLinesLength + 1); } } if (operation === '+') { if (!lastContextLineMatched) { return null; } patchedLines[patchedLinesLength] = content; patchedLinesLength++; nConsecutiveOldContextLines = 0; nextContextLineMustMatch = true; } if (operation === ' ') { nConsecutiveOldContextLines++; patchedLines[patchedLinesLength] = lines[toPos]; if (compareLine(toPos + 1, lines[toPos], operation, content)) { patchedLinesLength++; lastContextLineMatched = true; nextContextLineMustMatch = false; toPos++; } else { if (nextContextLineMustMatch || !maxErrors) { return null; } // Consider 3 possibilities in sequence: // 1. lines contains a *substitution* not included in the patch context, or // 2. lines contains an *insertion* not included in the patch context, or // 3. lines contains a *deletion* not included in the patch context // The first two options are of course only possible if the line from lines is non-null - // i.e. only option 3 is possible if we've overrun the end of the old file. return lines[toPos] && (applyHunk(hunkLines, toPos + 1, maxErrors - 1, hunkLinesI + 1, false, patchedLines, patchedLinesLength + 1) || applyHunk(hunkLines, toPos + 1, maxErrors - 1, hunkLinesI, false, patchedLines, patchedLinesLength + 1)) || applyHunk(hunkLines, toPos, maxErrors - 1, hunkLinesI + 1, false, patchedLines, patchedLinesLength); } } } // Before returning, trim any unmodified context lines off the end of patchedLines and reduce // toPos (and thus oldLineLastI) accordingly. This allows later hunks to be applied to a region // that starts in this hunk's trailing context. patchedLinesLength -= nConsecutiveOldContextLines; toPos -= nConsecutiveOldContextLines; patchedLines.length = patchedLinesLength; return { patchedLines: patchedLines, oldLineLastI: toPos - 1 }; } var resultLines = []; // Search best fit offsets for each hunk based on the previous ones var prevHunkOffset = 0; for (var _i = 0; _i < hunks.length; _i++) { var hunk = hunks[_i]; var hunkResult = void 0; var maxLine = lines.length - hunk.oldLines + fuzzFactor; var toPos = void 0; for (var maxErrors = 0; maxErrors <= fuzzFactor; maxErrors++) { toPos = hunk.oldStart + prevHunkOffset - 1; var iterator = (0, _distanceIterator["default"])(toPos, minLine, maxLine); for (; toPos !== undefined; toPos = iterator()) { hunkResult = applyHunk(hunk.lines, toPos, maxErrors); if (hunkResult) { break; } } if (hunkResult) { break; } } if (!hunkResult) { return false; } // Copy everything from the end of where we applied the last hunk to the start of this hunk for (var _i2 = minLine; _i2 < toPos; _i2++) { resultLines.push(lines[_i2]); } // Add the lines produced by applying the hunk: for (var _i3 = 0; _i3 < hunkResult.patchedLines.length; _i3++) { var _line = hunkResult.patchedLines[_i3]; resultLines.push(_line); } // Set lower text limit to end of the current hunk, so next ones don't try // to fit over already patched text minLine = hunkResult.oldLineLastI + 1; // Note the offset between where the patch said the hunk should've applied and where we // applied it, so we can adjust future hunks accordingly: prevHunkOffset = toPos + 1 - hunk.oldStart; } // Copy over the rest of the lines from the old text for (var _i4 = minLine; _i4 < lines.length; _i4++) { resultLines.push(lines[_i4]); } return resultLines.join('\n'); } // Wrapper that supports multiple file patches via callbacks. function applyPatches(uniDiff, options) { if (typeof uniDiff === 'string') { uniDiff = (0, _parse.parsePatch)(uniDiff); } var currentIndex = 0; function processIndex() { var index = uniDiff[currentIndex++]; if (!index) { return options.complete(); } options.loadFile(index, function (err, data) { if (err) { return options.complete(err); } var updatedContent = applyPatch(data, index, options); options.patched(index, updatedContent, function (err) { if (err) { return options.complete(err); } processIndex(); }); }); } processIndex(); } //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfc3RyaW5nIiwicmVxdWlyZSIsIl9saW5lRW5kaW5ncyIsIl9wYXJzZSIsIl9kaXN0YW5jZUl0ZXJhdG9yIiwiX2ludGVyb3BSZXF1aXJlRGVmYXVsdCIsImUiLCJfX2VzTW9kdWxlIiwiYXBwbHlQYXRjaCIsInNvdXJjZSIsInVuaURpZmYiLCJvcHRpb25zIiwiYXJndW1lbnRzIiwibGVuZ3RoIiwidW5kZWZpbmVkIiwicGFyc2VQYXRjaCIsIkFycmF5IiwiaXNBcnJheSIsIkVycm9yIiwiYXV0b0NvbnZlcnRMaW5lRW5kaW5ncyIsImhhc09ubHlXaW5MaW5lRW5kaW5ncyIsImlzVW5peCIsInVuaXhUb1dpbiIsImhhc09ubHlVbml4TGluZUVuZGluZ3MiLCJpc1dpbiIsIndpblRvVW5peCIsImxpbmVzIiwic3BsaXQiLCJodW5rcyIsImNvbXBhcmVMaW5lIiwibGluZU51bWJlciIsImxpbmUiLCJvcGVyYXRpb24iLCJwYXRjaENvbnRlbnQiLCJmdXp6RmFjdG9yIiwibWluTGluZSIsIk51bWJlciIsImlzSW50ZWdlciIsInByZXZMaW5lIiwicmVtb3ZlRU9GTkwiLCJhZGRFT0ZOTCIsImkiLCJwb3AiLCJwdXNoIiwiYXBwbHlIdW5rIiwiaHVua0xpbmVzIiwidG9Qb3MiLCJtYXhFcnJvcnMiLCJodW5rTGluZXNJIiwibGFzdENvbnRleHRMaW5lTWF0Y2hlZCIsInBhdGNoZWRMaW5lcyIsInBhdGNoZWRMaW5lc0xlbmd0aCIsIm5Db25zZWN1dGl2ZU9sZENvbnRleHRMaW5lcyIsIm5leHRDb250ZXh0TGluZU11c3RNYXRjaCIsImh1bmtMaW5lIiwiY29udGVudCIsInN1YnN0ciIsIm9sZExpbmVMYXN0SSIsInJlc3VsdExpbmVzIiwicHJldkh1bmtPZmZzZXQiLCJodW5rIiwiaHVua1Jlc3VsdCIsIm1heExpbmUiLCJvbGRMaW5lcyIsIm9sZFN0YXJ0IiwiaXRlcmF0b3IiLCJkaXN0YW5jZUl0ZXJhdG9yIiwiam9pbiIsImFwcGx5UGF0Y2hlcyIsImN1cnJlbnRJbmRleCIsInByb2Nlc3NJbmRleCIsImluZGV4IiwiY29tcGxldGUiLCJsb2FkRmlsZSIsImVyciIsImRhdGEiLCJ1cGRhdGVkQ29udGVudCIsInBhdGNoZWQiXSwic291cmNlcyI6WyIuLi8uLi9zcmMvcGF0Y2gvYXBwbHkuanMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtoYXNPbmx5V2luTGluZUVuZGluZ3MsIGhhc09ubHlVbml4TGluZUVuZGluZ3N9IGZyb20gJy4uL3V0aWwvc3RyaW5nJztcbmltcG9ydCB7aXNXaW4sIGlzVW5peCwgdW5peFRvV2luLCB3aW5Ub1VuaXh9IGZyb20gJy4vbGluZS1lbmRpbmdzJztcbmltcG9ydCB7cGFyc2VQYXRjaH0gZnJvbSAnLi9wYXJzZSc7XG5pbXBvcnQgZGlzdGFuY2VJdGVyYXRvciBmcm9tICcuLi91dGlsL2Rpc3RhbmNlLWl0ZXJhdG9yJztcblxuZXhwb3J0IGZ1bmN0aW9uIGFwcGx5UGF0Y2goc291cmNlLCB1bmlEaWZmLCBvcHRpb25zID0ge30pIHtcbiAgaWYgKHR5cGVvZiB1bmlEaWZmID09PSAnc3RyaW5nJykge1xuICAgIHVuaURpZmYgPSBwYXJzZVBhdGNoKHVuaURpZmYpO1xuICB9XG5cbiAgaWYgKEFycmF5LmlzQXJyYXkodW5pRGlmZikpIHtcbiAgICBpZiAodW5pRGlmZi5sZW5ndGggPiAxKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2FwcGx5UGF0Y2ggb25seSB3b3JrcyB3aXRoIGEgc2luZ2xlIGlucHV0LicpO1xuICAgIH1cblxuICAgIHVuaURpZmYgPSB1bmlEaWZmWzBdO1xuICB9XG5cbiAgaWYgKG9wdGlvbnMuYXV0b0NvbnZlcnRMaW5lRW5kaW5ncyB8fCBvcHRpb25zLmF1dG9Db252ZXJ0TGluZUVuZGluZ3MgPT0gbnVsbCkge1xuICAgIGlmIChoYXNPbmx5V2luTGluZUVuZGluZ3Moc291cmNlKSAmJiBpc1VuaXgodW5pRGlmZikpIHtcbiAgICAgIHVuaURpZmYgPSB1bml4VG9XaW4odW5pRGlmZik7XG4gICAgfSBlbHNlIGlmIChoYXNPbmx5VW5peExpbmVFbmRpbmdzKHNvdXJjZSkgJiYgaXNXaW4odW5pRGlmZikpIHtcbiAgICAgIHVuaURpZmYgPSB3aW5Ub1VuaXgodW5pRGlmZik7XG4gICAgfVxuICB9XG5cbiAgLy8gQXBwbHkgdGhlIGRpZmYgdG8gdGhlIGlucHV0XG4gIGxldCBsaW5lcyA9IHNvdXJjZS5zcGxpdCgnXFxuJyksXG4gICAgICBodW5rcyA9IHVuaURpZmYuaHVua3MsXG5cbiAgICAgIGNvbXBhcmVMaW5lID0gb3B0aW9ucy5jb21wYXJlTGluZSB8fCAoKGxpbmVOdW1iZXIsIGxpbmUsIG9wZXJhdGlvbiwgcGF0Y2hDb250ZW50KSA9PiBsaW5lID09PSBwYXRjaENvbnRlbnQpLFxuICAgICAgZnV6ekZhY3RvciA9IG9wdGlvbnMuZnV6ekZhY3RvciB8fCAwLFxuICAgICAgbWluTGluZSA9IDA7XG5cbiAgaWYgKGZ1enpGYWN0b3IgPCAwIHx8ICFOdW1iZXIuaXNJbnRlZ2VyKGZ1enpGYWN0b3IpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdmdXp6RmFjdG9yIG11c3QgYmUgYSBub24tbmVnYXRpdmUgaW50ZWdlcicpO1xuICB9XG5cbiAgLy8gU3BlY2lhbCBjYXNlIGZvciBlbXB0eSBwYXRjaC5cbiAgaWYgKCFodW5rcy5sZW5ndGgpIHtcbiAgICByZXR1cm4gc291cmNlO1xuICB9XG5cbiAgLy8gQmVmb3JlIGFueXRoaW5nIGVsc2UsIGhhbmRsZSBFT0ZOTCBpbnNlcnRpb24vcmVtb3ZhbC4gSWYgdGhlIHBhdGNoIHRlbGxzIHVzIHRvIG1ha2UgYSBjaGFuZ2VcbiAgLy8gdG8gdGhlIEVPRk5MIHRoYXQgaXMgcmVkdW5kYW50L2ltcG9zc2libGUgLSBpLmUuIHRvIHJlbW92ZSBhIG5ld2xpbmUgdGhhdCdzIG5vdCB0aGVyZSwgb3IgYWRkIGFcbiAgLy8gbmV3bGluZSB0aGF0IGFscmVhZHkgZXhpc3RzIC0gdGhlbiB3ZSBlaXRoZXIgcmV0dXJuIGZhbHNlIGFuZCBmYWlsIHRvIGFwcGx5IHRoZSBwYXRjaCAoaWZcbiAgLy8gZnV6ekZhY3RvciBpcyAwKSBvciBzaW1wbHkgaWdub3JlIHRoZSBwcm9ibGVtIGFuZCBkbyBub3RoaW5nIChpZiBmdXp6RmFjdG9yIGlzID4wKS5cbiAgLy8gSWYgd2UgZG8gbmVlZCB0byByZW1vdmUvYWRkIGEgbmV3bGluZSBhdCBFT0YsIHRoaXMgd2lsbCBhbHdheXMgYmUgaW4gdGhlIGZpbmFsIGh1bms6XG4gIGxldCBwcmV2TGluZSA9ICcnLFxuICAgICAgcmVtb3ZlRU9GTkwgPSBmYWxzZSxcbiAgICAgIGFkZEVPRk5MID0gZmFsc2U7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgaHVua3NbaHVua3MubGVuZ3RoIC0gMV0ubGluZXMubGVuZ3RoOyBpKyspIHtcbiAgICBjb25zdCBsaW5lID0gaHVua3NbaHVua3MubGVuZ3RoIC0gMV0ubGluZXNbaV07XG4gICAgaWYgKGxpbmVbMF0gPT0gJ1xcXFwnKSB7XG4gICAgICBpZiAocHJldkxpbmVbMF0gPT0gJysnKSB7XG4gICAgICAgIHJlbW92ZUVPRk5MID0gdHJ1ZTtcbiAgICAgIH0gZWxzZSBpZiAocHJldkxpbmVbMF0gPT0gJy0nKSB7XG4gICAgICAgIGFkZEVPRk5MID0gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG4gICAgcHJldkxpbmUgPSBsaW5lO1xuICB9XG4gIGlmIChyZW1vdmVFT0ZOTCkge1xuICAgIGlmIChhZGRFT0ZOTCkge1xuICAgICAgLy8gVGhpcyBtZWFucyB0aGUgZmluYWwgbGluZSBnZXRzIGNoYW5nZWQgYnV0IGRvZXNuJ3QgaGF2ZSBhIHRyYWlsaW5nIG5ld2xpbmUgaW4gZWl0aGVyIHRoZVxuICAgICAgLy8gb3JpZ2luYWwgb3IgcGF0Y2hlZCB2ZXJzaW9uLiBJbiB0aGF0IGNhc2UsIHdlIGRvIG5vdGhpbmcgaWYgZnV6ekZhY3RvciA+IDAsIGFuZCBpZlxuICAgICAgLy8gZnV6ekZhY3RvciBpcyAwLCB3ZSBzaW1wbHkgdmFsaWRhdGUgdGhhdCB0aGUgc291cmNlIGZpbGUgaGFzIG5vIHRyYWlsaW5nIG5ld2xpbmUuXG4gICAgICBpZiAoIWZ1enpGYWN0b3IgJiYgbGluZXNbbGluZXMubGVuZ3RoIC0gMV0gPT0gJycpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAobGluZXNbbGluZXMubGVuZ3RoIC0gMV0gPT0gJycpIHtcbiAgICAgIGxpbmVzLnBvcCgpO1xuICAgIH0gZWxzZSBpZiAoIWZ1enpGYWN0b3IpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH0gZWxzZSBpZiAoYWRkRU9GTkwpIHtcbiAgICBpZiAobGluZXNbbGluZXMubGVuZ3RoIC0gMV0gIT0gJycpIHtcbiAgICAgIGxpbmVzLnB1c2goJycpO1xuICAgIH0gZWxzZSBpZiAoIWZ1enpGYWN0b3IpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2tzIGlmIHRoZSBodW5rIGNhbiBiZSBtYWRlIHRvIGZpdCBhdCB0aGUgcHJvdmlkZWQgbG9jYXRpb24gd2l0aCBhdCBtb3N0IGBtYXhFcnJvcnNgXG4gICAqIGluc2VydGlvbnMsIHN1YnN0aXR1dGlvbnMsIG9yIGRlbGV0aW9ucywgd2hpbGUgZW5zdXJpbmcgYWxzbyB0aGF0OlxuICAgKiAtIGxpbmVzIGRlbGV0ZWQgaW4gdGhlIGh1bmsgbWF0Y2ggZXhhY3RseSwgYW5kXG4gICAqIC0gd2hlcmV2ZXIgYW4gaW5zZXJ0aW9uIG9wZXJhdGlvbiBvciBibG9jayBvZiBpbnNlcnRpb24gb3BlcmF0aW9ucyBhcHBlYXJzIGluIHRoZSBodW5rLCB0aGVcbiAgICogICBpbW1lZGlhdGVseSBwcmVjZWRpbmcgYW5kIGZvbGxvd2luZyBsaW5lcyBvZiBjb250ZXh0IG1hdGNoIGV4YWN0bHlcbiAgICpcbiAgICogYHRvUG9zYCBzaG91bGQgYmUgc2V0IHN1Y2ggdGhhdCBsaW5lc1t0b1Bvc10gaXMgbWVhbnQgdG8gbWF0Y2ggaHVua0xpbmVzWzBdLlxuICAgKlxuICAgKiBJZiB0aGUgaHVuayBjYW4gYmUgYXBwbGllZCwgcmV0dXJucyBhbiBvYmplY3Qgd2l0aCBwcm9wZXJ0aWVzIGBvbGRMaW5lTGFzdElgIGFuZFxuICAgKiBgcmVwbGFjZW1lbnRMaW5lc2AuIE90aGVyd2lzZSwgcmV0dXJucyBudWxsLlxuICAgKi9cbiAgZnVuY3Rpb24gYXBwbHlIdW5rKFxuICAgIGh1bmtMaW5lcyxcbiAgICB0b1BvcyxcbiAgICBtYXhFcnJvcnMsXG4gICAgaHVua0xpbmVzSSA9IDAsXG4gICAgbGFzdENvbnRleHRMaW5lTWF0Y2hlZCA9IHRydWUsXG4gICAgcGF0Y2hlZExpbmVzID0gW10sXG4gICAgcGF0Y2hlZExpbmVzTGVuZ3RoID0gMFxuICApIHtcbiAgICBsZXQgbkNvbnNlY3V0aXZlT2xkQ29udGV4dExpbmVzID0gMDtcbiAgICBsZXQgbmV4dENvbnRleHRMaW5lTXVzdE1hdGNoID0gZmFsc2U7XG4gICAgZm9yICg7IGh1bmtMaW5lc0kgPCBodW5rTGluZXMubGVuZ3RoOyBodW5rTGluZXNJKyspIHtcbiAgICAgIGxldCBodW5rTGluZSA9IGh1bmtMaW5lc1todW5rTGluZXNJXSxcbiAgICAgICAgICBvcGVyYXRpb24gPSAoaHVua0xpbmUubGVuZ3RoID4gMCA/IGh1bmtMaW5lWzBdIDogJyAnKSxcbiAgICAgICAgICBjb250ZW50ID0gKGh1bmtMaW5lLmxlbmd0aCA+IDAgPyBodW5rTGluZS5zdWJzdHIoMSkgOiBodW5rTGluZSk7XG5cbiAgICAgIGlmIChvcGVyYXRpb24gPT09ICctJykge1xuICAgICAgICBpZiAoY29tcGFyZUxpbmUodG9Qb3MgKyAxLCBsaW5lc1t0b1Bvc10sIG9wZXJhdGlvbiwgY29udGVudCkpIHtcbiAgICAgICAgICB0b1BvcysrO1xuICAgICAgICAgIG5Db25zZWN1dGl2ZU9sZENvbnRleHRMaW5lcyA9IDA7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaWYgKCFtYXhFcnJvcnMgfHwgbGluZXNbdG9Qb3NdID09IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICAgIH1cbiAgICAgICAgICBwYXRjaGVkTGluZXNbcGF0Y2hlZExpbmVzTGVuZ3RoXSA9IGxpbmVzW3RvUG9zXTtcbiAgICAgICAgICByZXR1cm4gYXBwbHlIdW5rKFxuICAgICAgICAgICAgaHVua0xpbmVzLFxuICAgICAgICAgICAgdG9Qb3MgKyAxLFxuICAgICAgICAgICAgbWF4RXJyb3JzIC0gMSxcbiAgICAgICAgICAgIGh1bmtMaW5lc0ksXG4gICAgICAgICAgICBmYWxzZSxcbiAgICAgICAgICAgIHBhdGNoZWRMaW5lcyxcbiAgICAgICAgICAgIHBhdGNoZWRMaW5lc0xlbmd0aCArIDFcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmIChvcGVyYXRpb24gPT09ICcrJykge1xuICAgICAgICBpZiAoIWxhc3RDb250ZXh0TGluZU1hdGNoZWQpIHtcbiAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBwYXRjaGVkTGluZXNbcGF0Y2hlZExpbmVzTGVuZ3RoXSA9IGNvbnRlbnQ7XG4gICAgICAgIHBhdGNoZWRMaW5lc0xlbmd0aCsrO1xuICAgICAgICBuQ29uc2VjdXRpdmVPbGRDb250ZXh0TGluZXMgPSAwO1xuICAgICAgICBuZXh0Q29udGV4dExpbmVNdXN0TWF0Y2ggPSB0cnVlO1xuICAgICAgfVxuXG4gICAgICBpZiAob3BlcmF0aW9uID09PSAnICcpIHtcbiAgICAgICAgbkNvbnNlY3V0aXZlT2xkQ29udGV4dExpbmVzKys7XG4gICAgICAgIHBhdGNoZWRMaW5lc1twYXRjaGVkTGluZXNMZW5ndGhdID0gbGluZXNbdG9Qb3NdO1xuICAgICAgICBpZiAoY29tcGFyZUxpbmUodG9Qb3MgKyAxLCBsaW5lc1t0b1Bvc10sIG9wZXJhdGlvbiwgY29udGVudCkpIHtcbiAgICAgICAgICBwYXRjaGVkTGluZXNMZW5ndGgrKztcbiAgICAgICAgICBsYXN0Q29udGV4dExpbmVNYXRjaGVkID0gdHJ1ZTtcbiAgICAgICAgICBuZXh0Q29udGV4dExpbmVNdXN0TWF0Y2ggPSBmYWxzZTtcbiAgICAgICAgICB0b1BvcysrO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGlmIChuZXh0Q29udGV4dExpbmVNdXN0TWF0Y2ggfHwgIW1heEVycm9ycykge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLy8gQ29uc2lkZXIgMyBwb3NzaWJpbGl0aWVzIGluIHNlcXVlbmNlOlxuICAgICAgICAgIC8vIDEuIGxpbmVzIGNvbnRhaW5zIGEgKnN1YnN0aXR1dGlvbiogbm90IGluY2x1ZGVkIGluIHRoZSBwYXRjaCBjb250ZXh0LCBvclxuICAgICAgICAgIC8vIDIuIGxpbmVzIGNvbnRhaW5zIGFuICppbnNlcnRpb24qIG5vdCBpbmNsdWRlZCBpbiB0aGUgcGF0Y2ggY29udGV4dCwgb3JcbiAgICAgICAgICAvLyAzLiBsaW5lcyBjb250YWlucyBhICpkZWxldGlvbiogbm90IGluY2x1ZGVkIGluIHRoZSBwYXRjaCBjb250ZXh0XG4gICAgICAgICAgLy8gVGhlIGZpcnN0IHR3byBvcHRpb25zIGFyZSBvZiBjb3Vyc2Ugb25seSBwb3NzaWJsZSBpZiB0aGUgbGluZSBmcm9tIGxpbmVzIGlzIG5vbi1udWxsIC1cbiAgICAgICAgICAvLyBpLmUuIG9ubHkgb3B0aW9uIDMgaXMgcG9zc2libGUgaWYgd2UndmUgb3ZlcnJ1biB0aGUgZW5kIG9mIHRoZSBvbGQgZmlsZS5cbiAgICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgbGluZXNbdG9Qb3NdICYmIChcbiAgICAgICAgICAgICAgYXBwbHlIdW5rKFxuICAgICAgICAgICAgICAgIGh1bmtMaW5lcyxcbiAgICAgICAgICAgICAgICB0b1BvcyArIDEsXG4gICAgICAgICAgICAgICAgbWF4RXJyb3JzIC0gMSxcbiAgICAgICAgICAgICAgICBodW5rTGluZXNJICsgMSxcbiAgICAgICAgICAgICAgICBmYWxzZSxcbiAgICAgICAgICAgICAgICBwYXRjaGVkTGluZXMsXG4gICAgICAgICAgICAgICAgcGF0Y2hlZExpbmVzTGVuZ3RoICsgMVxuICAgICAgICAgICAgICApIHx8IGFwcGx5SHVuayhcbiAgICAgICAgICAgICAgICBodW5rTGluZXMsXG4gICAgICAgICAgICAgICAgdG9Qb3MgKyAxLFxuICAgICAgICAgICAgICAgIG1heEVycm9ycyAtIDEsXG4gICAgICAgICAgICAgICAgaHVua0xpbmVzSSxcbiAgICAgICAgICAgICAgICBmYWxzZSxcbiAgICAgICAgICAgICAgICBwYXRjaGVkTGluZXMsXG4gICAgICAgICAgICAgICAgcGF0Y2hlZExpbmVzTGVuZ3RoICsgMVxuICAgICAgICAgICAgICApXG4gICAgICAgICAgICApIHx8IGFwcGx5SHVuayhcbiAgICAgICAgICAgICAgaHVua0xpbmVzLFxuICAgICAgICAgICAgICB0b1BvcyxcbiAgICAgICAgICAgICAgbWF4RXJyb3JzIC0gMSxcbiAgICAgICAgICAgICAgaHVua0xpbmVzSSArIDEsXG4gICAgICAgICAgICAgIGZhbHNlLFxuICAgICAgICAgICAgICBwYXRjaGVkTGluZXMsXG4gICAgICAgICAgICAgIHBhdGNoZWRMaW5lc0xlbmd0aFxuICAgICAgICAgICAgKVxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBCZWZvcmUgcmV0dXJuaW5nLCB0cmltIGFueSB1bm1vZGlmaWVkIGNvbnRleHQgbGluZXMgb2ZmIHRoZSBlbmQgb2YgcGF0Y2hlZExpbmVzIGFuZCByZWR1Y2VcbiAgICAvLyB0b1BvcyAoYW5kIHRodXMgb2xkTGluZUxhc3RJKSBhY2NvcmRpbmdseS4gVGhpcyBhbGxvd3MgbGF0ZXIgaHVua3MgdG8gYmUgYXBwbGllZCB0byBhIHJlZ2lvblxuICAgIC8vIHRoYXQgc3RhcnRzIGluIHRoaXMgaHVuaydzIHRyYWlsaW5nIGNvbnRleHQuXG4gICAgcGF0Y2hlZExpbmVzTGVuZ3RoIC09IG5Db25zZWN1dGl2ZU9sZENvbnRleHRMaW5lcztcbiAgICB0b1BvcyAtPSBuQ29uc2VjdXRpdmVPbGRDb250ZXh0TGluZXM7XG4gICAgcGF0Y2hlZExpbmVzLmxlbmd0aCA9IHBhdGNoZWRMaW5lc0xlbmd0aDtcbiAgICByZXR1cm4ge1xuICAgICAgcGF0Y2hlZExpbmVzLFxuICAgICAgb2xkTGluZUxhc3RJOiB0b1BvcyAtIDFcbiAgICB9O1xuICB9XG5cbiAgY29uc3QgcmVzdWx0TGluZXMgPSBbXTtcblxuICAvLyBTZWFyY2ggYmVzdCBmaXQgb2Zmc2V0cyBmb3IgZWFjaCBodW5rIGJhc2VkIG9uIHRoZSBwcmV2aW91cyBvbmVzXG4gIGxldCBwcmV2SHVua09mZnNldCA9IDA7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgaHVua3MubGVuZ3RoOyBpKyspIHtcbiAgICBjb25zdCBodW5rID0gaHVua3NbaV07XG4gICAgbGV0IGh1bmtSZXN1bHQ7XG4gICAgbGV0IG1heExpbmUgPSBsaW5lcy5sZW5ndGggLSBodW5rLm9sZExpbmVzICsgZnV6ekZhY3RvcjtcbiAgICBsZXQgdG9Qb3M7XG4gICAgZm9yIChsZXQgbWF4RXJyb3JzID0gMDsgbWF4RXJyb3JzIDw9IGZ1enpGYWN0b3I7IG1heEVycm9ycysrKSB7XG4gICAgICB0b1BvcyA9IGh1bmsub2xkU3RhcnQgKyBwcmV2SHVua09mZnNldCAtIDE7XG4gICAgICBsZXQgaXRlcmF0b3IgPSBkaXN0YW5jZUl0ZXJhdG9yKHRvUG9zLCBtaW5MaW5lLCBtYXhMaW5lKTtcbiAgICAgIGZvciAoOyB0b1BvcyAhPT0gdW5kZWZpbmVkOyB0b1BvcyA9IGl0ZXJhdG9yKCkpIHtcbiAgICAgICAgaHVua1Jlc3VsdCA9IGFwcGx5SHVuayhodW5rLmxpbmVzLCB0b1BvcywgbWF4RXJyb3JzKTtcbiAgICAgICAgaWYgKGh1bmtSZXN1bHQpIHtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGh1bmtSZXN1bHQpIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKCFodW5rUmVzdWx0KSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgLy8gQ29weSBldmVyeXRoaW5nIGZyb20gdGhlIGVuZCBvZiB3aGVyZSB3ZSBhcHBsaWVkIHRoZSBsYXN0IGh1bmsgdG8gdGhlIHN0YXJ0IG9mIHRoaXMgaHVua1xuICAgIGZvciAobGV0IGkgPSBtaW5MaW5lOyBpIDwgdG9Qb3M7IGkrKykge1xuICAgICAgcmVzdWx0TGluZXMucHVzaChsaW5lc1tpXSk7XG4gICAgfVxuXG4gICAgLy8gQWRkIHRoZSBsaW5lcyBwcm9kdWNlZCBieSBhcHBseWluZyB0aGUgaHVuazpcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGh1bmtSZXN1bHQucGF0Y2hlZExpbmVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBsaW5lID0gaHVua1Jlc3VsdC5wYXRjaGVkTGluZXNbaV07XG4gICAgICByZXN1bHRMaW5lcy5wdXNoKGxpbmUpO1xuICAgIH1cblxuICAgIC8vIFNldCBsb3dlciB0ZXh0IGxpbWl0IHRvIGVuZCBvZiB0aGUgY3VycmVudCBodW5rLCBzbyBuZXh0IG9uZXMgZG9uJ3QgdHJ5XG4gICAgLy8gdG8gZml0IG92ZXIgYWxyZWFkeSBwYXRjaGVkIHRleHRcbiAgICBtaW5MaW5lID0gaHVua1Jlc3VsdC5vbGRMaW5lTGFzdEkgKyAxO1xuXG4gICAgLy8gTm90ZSB0aGUgb2Zmc2V0IGJldHdlZW4gd2hlcmUgdGhlIHBhdGNoIHNhaWQgdGhlIGh1bmsgc2hvdWxkJ3ZlIGFwcGxpZWQgYW5kIHdoZXJlIHdlXG4gICAgLy8gYXBwbGllZCBpdCwgc28gd2UgY2FuIGFkanVzdCBmdXR1cmUgaHVua3MgYWNjb3JkaW5nbHk6XG4gICAgcHJldkh1bmtPZmZzZXQgPSB0b1BvcyArIDEgLSBodW5rLm9sZFN0YXJ0O1xuICB9XG5cbiAgLy8gQ29weSBvdmVyIHRoZSByZXN0IG9mIHRoZSBsaW5lcyBmcm9tIHRoZSBvbGQgdGV4dFxuICBmb3IgKGxldCBpID0gbWluTGluZTsgaSA8IGxpbmVzLmxlbmd0aDsgaSsrKSB7XG4gICAgcmVzdWx0TGluZXMucHVzaChsaW5lc1tpXSk7XG4gIH1cblxuICByZXR1cm4gcmVzdWx0TGluZXMuam9pbignXFxuJyk7XG59XG5cbi8vIFdyYXBwZXIgdGhhdCBzdXBwb3J0cyBtdWx0aXBsZSBmaWxlIHBhdGNoZXMgdmlhIGNhbGxiYWNrcy5cbmV4cG9ydCBmdW5jdGlvbiBhcHBseVBhdGNoZXModW5pRGlmZiwgb3B0aW9ucykge1xuICBpZiAodHlwZW9mIHVuaURpZmYgPT09ICdzdHJpbmcnKSB7XG4gICAgdW5pRGlmZiA9IHBhcnNlUGF0Y2godW5pRGlmZik7XG4gIH1cblxuICBsZXQgY3VycmVudEluZGV4ID0gMDtcbiAgZnVuY3Rpb24gcHJvY2Vzc0luZGV4KCkge1xuICAgIGxldCBpbmRleCA9IHVuaURpZmZbY3VycmVudEluZGV4KytdO1xuICAgIGlmICghaW5kZXgpIHtcbiAgICAgIHJldHVybiBvcHRpb25zLmNvbXBsZXRlKCk7XG4gICAgfVxuXG4gICAgb3B0aW9ucy5sb2FkRmlsZShpbmRleCwgZnVuY3Rpb24oZXJyLCBkYXRhKSB7XG4gICAgICBpZiAoZXJyKSB7XG4gICAgICAgIHJldHVybiBvcHRpb25zLmNvbXBsZXRlKGVycik7XG4gICAgICB9XG5cbiAgICAgIGxldCB1cGRhdGVkQ29udGVudCA9IGFwcGx5UGF0Y2goZGF0YSwgaW5kZXgsIG9wdGlvbnMpO1xuICAgICAgb3B0aW9ucy5wYXRjaGVkKGluZGV4LCB1cGRhdGVkQ29udGVudCwgZnVuY3Rpb24oZXJyKSB7XG4gICAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgICByZXR1cm4gb3B0aW9ucy5jb21wbGV0ZShlcnIpO1xuICAgICAgICB9XG5cbiAgICAgICAgcHJvY2Vzc0luZGV4KCk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuICBwcm9jZXNzSW5kZXgoKTtcbn1cbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBLElB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