UNPKG

jsondiffpatch

Version:
918 lines (799 loc) 71.7 kB
!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),(f.jsondiffpatch||(f.jsondiffpatch={})).formatters=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){ module.exports = require('./formatters'); },{"./formatters":6}],2:[function(require,module,exports){ exports.isBrowser = typeof window !== 'undefined'; },{}],3:[function(require,module,exports){ var base = require('./base'); var BaseFormatter = base.BaseFormatter; var AnnotatedFormatter = function AnnotatedFormatter() { this.includeMoveDestinations = false; }; AnnotatedFormatter.prototype = new BaseFormatter(); AnnotatedFormatter.prototype.prepareContext = function(context) { BaseFormatter.prototype.prepareContext.call(this, context); context.indent = function(levels) { this.indentLevel = (this.indentLevel || 0) + (typeof levels === 'undefined' ? 1 : levels); this.indentPad = new Array(this.indentLevel + 1).join('&nbsp;&nbsp;'); }; context.row = function(json, htmlNote) { context.out('<tr><td style="white-space: nowrap;">' + '<pre class="jsondiffpatch-annotated-indent" style="display: inline-block">'); context.out(context.indentPad); context.out('</pre><pre style="display: inline-block">'); context.out(json); context.out('</pre></td><td class="jsondiffpatch-delta-note"><div>'); context.out(htmlNote); context.out('</div></td></tr>'); }; }; AnnotatedFormatter.prototype.typeFormattterErrorFormatter = function(context, err) { context.row('', '<pre class="jsondiffpatch-error">' + err + '</pre>'); }; AnnotatedFormatter.prototype.formatTextDiffString = function(context, value) { var lines = this.parseTextDiff(value); context.out('<ul class="jsondiffpatch-textdiff">'); for (var i = 0, l = lines.length; i < l; i++) { var line = lines[i]; context.out('<li>' + '<div class="jsondiffpatch-textdiff-location">' + '<span class="jsondiffpatch-textdiff-line-number">' + line.location.line + '</span>' + '<span class="jsondiffpatch-textdiff-char">' + line.location.chr + '</span>' + '</div>' + '<div class="jsondiffpatch-textdiff-line">'); var pieces = line.pieces; for (var pieceIndex = 0, piecesLength = pieces.length; pieceIndex < piecesLength; pieceIndex++) { var piece = pieces[pieceIndex]; context.out('<span class="jsondiffpatch-textdiff-' + piece.type + '">' + piece.text + '</span>'); } context.out('</div></li>'); } context.out('</ul>'); }; AnnotatedFormatter.prototype.rootBegin = function(context, type, nodeType) { context.out('<table class="jsondiffpatch-annotated-delta">'); if (type === 'node') { context.row('{'); context.indent(); } if (nodeType === 'array') { context.row('"_t": "a",', 'Array delta (member names indicate array indices)'); } }; AnnotatedFormatter.prototype.rootEnd = function(context, type) { if (type === 'node') { context.indent(-1); context.row('}'); } context.out('</table>'); }; AnnotatedFormatter.prototype.nodeBegin = function(context, key, leftKey, type, nodeType) { context.row('&quot;' + key + '&quot;: {'); if (type === 'node') { context.indent(); } if (nodeType === 'array') { context.row('"_t": "a",', 'Array delta (member names indicate array indices)'); } }; AnnotatedFormatter.prototype.nodeEnd = function(context, key, leftKey, type, nodeType, isLast) { if (type === 'node') { context.indent(-1); } context.row('}' + (isLast ? '' : ',')); }; /* jshint camelcase: false */ AnnotatedFormatter.prototype.format_unchanged = function() { return; }; AnnotatedFormatter.prototype.format_movedestination = function() { return; }; AnnotatedFormatter.prototype.format_node = function(context, delta, left) { // recurse this.formatDeltaChildren(context, delta, left); }; var wrapPropertyName = function(name) { return '<pre style="display:inline-block">&quot;' + name + '&quot;</pre>'; }; var deltaAnnotations = { added: function(delta, left, key, leftKey) { var formatLegend = ' <pre>([newValue])</pre>'; if (typeof leftKey === 'undefined') { return 'new value' + formatLegend; } if (typeof leftKey === 'number') { return 'insert at index ' + leftKey + formatLegend; } return 'add property ' + wrapPropertyName(leftKey) + formatLegend; }, modified: function(delta, left, key, leftKey) { var formatLegend = ' <pre>([previousValue, newValue])</pre>'; if (typeof leftKey === 'undefined') { return 'modify value' + formatLegend; } if (typeof leftKey === 'number') { return 'modify at index ' + leftKey + formatLegend; } return 'modify property ' + wrapPropertyName(leftKey) + formatLegend; }, deleted: function(delta, left, key, leftKey) { var formatLegend = ' <pre>([previousValue, 0, 0])</pre>'; if (typeof leftKey === 'undefined') { return 'delete value' + formatLegend; } if (typeof leftKey === 'number') { return 'remove index ' + leftKey + formatLegend; } return 'delete property ' + wrapPropertyName(leftKey) + formatLegend; }, moved: function(delta, left, key, leftKey) { return 'move from <span title="(position to remove at original state)">index ' + leftKey + '</span> to ' + '<span title="(position to insert at final state)">index ' + delta[1] + '</span>'; }, textdiff: function(delta, left, key, leftKey) { var location = (typeof leftKey === 'undefined') ? '' : ( (typeof leftKey === 'number') ? ' at index ' + leftKey : ' at property ' + wrapPropertyName(leftKey) ); return 'text diff' + location + ', format is ' + '<a href="https://code.google.com/p/google-diff-match-patch/wiki/Unidiff">' + 'a variation of Unidiff</a>'; } }; var formatAnyChange = function(context, delta) { var deltaType = this.getDeltaType(delta); var annotator = deltaAnnotations[deltaType]; var htmlNote = annotator && annotator.apply(annotator, Array.prototype.slice.call(arguments, 1)); var json = JSON.stringify(delta, null, 2); if (deltaType === 'textdiff') { // split text diffs lines json = json.split('\\n').join('\\n"+\n "'); } context.indent(); context.row(json, htmlNote); context.indent(-1); }; AnnotatedFormatter.prototype.format_added = formatAnyChange; AnnotatedFormatter.prototype.format_modified = formatAnyChange; AnnotatedFormatter.prototype.format_deleted = formatAnyChange; AnnotatedFormatter.prototype.format_moved = formatAnyChange; AnnotatedFormatter.prototype.format_textdiff = formatAnyChange; /* jshint camelcase: true */ exports.AnnotatedFormatter = AnnotatedFormatter; var defaultInstance; exports.format = function(delta, left) { if (!defaultInstance) { defaultInstance = new AnnotatedFormatter(); } return defaultInstance.format(delta, left); }; },{"./base":4}],4:[function(require,module,exports){ var isArray = (typeof Array.isArray === 'function') ? // use native function Array.isArray : // use instanceof operator function(a) { return a instanceof Array; }; var getObjectKeys = typeof Object.keys === 'function' ? function(obj) { return Object.keys(obj); } : function(obj) { var names = []; for (var property in obj) { if (Object.prototype.hasOwnProperty.call(obj, property)) { names.push(property); } } return names; }; var trimUnderscore = function(str) { if (str.substr(0, 1) === '_') { return str.slice(1); } return str; }; var arrayKeyToSortNumber = function(key) { if (key === '_t') { return -1; } else { if (key.substr(0, 1) === '_') { return parseInt(key.slice(1), 10); } else { return parseInt(key, 10) + 0.1; } } }; var arrayKeyComparer = function(key1, key2) { return arrayKeyToSortNumber(key1) - arrayKeyToSortNumber(key2); }; var BaseFormatter = function BaseFormatter() {}; BaseFormatter.prototype.format = function(delta, left) { var context = {}; this.prepareContext(context); this.recurse(context, delta, left); return this.finalize(context); }; BaseFormatter.prototype.prepareContext = function(context) { context.buffer = []; context.out = function() { this.buffer.push.apply(this.buffer, arguments); }; }; BaseFormatter.prototype.typeFormattterNotFound = function(context, deltaType) { throw new Error('cannot format delta type: ' + deltaType); }; BaseFormatter.prototype.typeFormattterErrorFormatter = function(context, err) { return err.toString(); }; BaseFormatter.prototype.finalize = function(context) { if (isArray(context.buffer)) { return context.buffer.join(''); } }; BaseFormatter.prototype.recurse = function(context, delta, left, key, leftKey, movedFrom, isLast) { var useMoveOriginHere = delta && movedFrom; var leftValue = useMoveOriginHere ? movedFrom.value : left; if (typeof delta === 'undefined' && typeof key === 'undefined') { return undefined; } var type = this.getDeltaType(delta, movedFrom); var nodeType = type === 'node' ? (delta._t === 'a' ? 'array' : 'object') : ''; if (typeof key !== 'undefined') { this.nodeBegin(context, key, leftKey, type, nodeType, isLast); } else { this.rootBegin(context, type, nodeType); } var typeFormattter; try { typeFormattter = this['format_' + type] || this.typeFormattterNotFound(context, type); typeFormattter.call(this, context, delta, leftValue, key, leftKey, movedFrom); } catch (err) { this.typeFormattterErrorFormatter(context, err, delta, leftValue, key, leftKey, movedFrom); if (typeof console !== 'undefined' && console.error) { console.error(err.stack); } } if (typeof key !== 'undefined') { this.nodeEnd(context, key, leftKey, type, nodeType, isLast); } else { this.rootEnd(context, type, nodeType); } }; BaseFormatter.prototype.formatDeltaChildren = function(context, delta, left) { var self = this; this.forEachDeltaKey(delta, left, function(key, leftKey, movedFrom, isLast) { self.recurse(context, delta[key], left ? left[leftKey] : undefined, key, leftKey, movedFrom, isLast); }); }; BaseFormatter.prototype.forEachDeltaKey = function(delta, left, fn) { var keys = getObjectKeys(delta); var arrayKeys = delta._t === 'a'; var moveDestinations = {}; var name; if (typeof left !== 'undefined') { for (name in left) { if (typeof delta[name] === 'undefined' && ((!arrayKeys) || typeof delta['_' + name] === 'undefined')) { keys.push(name); } } } // look for move destinations for (name in delta) { var value = delta[name]; if (isArray(value) && value[2] === 3) { moveDestinations[value[1].toString()] = { key: name, value: left && left[parseInt(name.substr(1))] }; if (this.includeMoveDestinations !== false) { if ((typeof left === 'undefined') && (typeof delta[value[1]] === 'undefined')) { keys.push(value[1].toString()); } } } } if (arrayKeys) { keys.sort(arrayKeyComparer); } else { keys.sort(); } for (var index = 0, length = keys.length; index < length; index++) { var key = keys[index]; if (arrayKeys && key === '_t') { continue; } var leftKey = arrayKeys ? (typeof key === 'number' ? key : parseInt(trimUnderscore(key), 10)) : key; var isLast = (index === length - 1); fn(key, leftKey, moveDestinations[leftKey], isLast); } }; BaseFormatter.prototype.getDeltaType = function(delta, movedFrom) { if (typeof delta === 'undefined') { if (typeof movedFrom !== 'undefined') { return 'movedestination'; } return 'unchanged'; } if (isArray(delta)) { if (delta.length === 1) { return 'added'; } if (delta.length === 2) { return 'modified'; } if (delta.length === 3 && delta[2] === 0) { return 'deleted'; } if (delta.length === 3 && delta[2] === 2) { return 'textdiff'; } if (delta.length === 3 && delta[2] === 3) { return 'moved'; } } else if (typeof delta === 'object') { return 'node'; } return 'unknown'; }; BaseFormatter.prototype.parseTextDiff = function(value) { var output = []; var lines = value.split('\n@@ '); for (var i = 0, l = lines.length; i < l; i++) { var line = lines[i]; var lineOutput = { pieces: [] }; var location = /^(?:@@ )?[-+]?(\d+),(\d+)/.exec(line).slice(1); lineOutput.location = { line: location[0], chr: location[1] }; var pieces = line.split('\n').slice(1); for (var pieceIndex = 0, piecesLength = pieces.length; pieceIndex < piecesLength; pieceIndex++) { var piece = pieces[pieceIndex]; if (!piece.length) { continue; } var pieceOutput = { type: 'context' }; if (piece.substr(0, 1) === '+') { pieceOutput.type = 'added'; } else if (piece.substr(0, 1) === '-') { pieceOutput.type = 'deleted'; } pieceOutput.text = piece.slice(1); lineOutput.pieces.push(pieceOutput); } output.push(lineOutput); } return output; }; exports.BaseFormatter = BaseFormatter; },{}],5:[function(require,module,exports){ var base = require('./base'); var BaseFormatter = base.BaseFormatter; var HtmlFormatter = function HtmlFormatter() {}; HtmlFormatter.prototype = new BaseFormatter(); function htmlEscape(text) { var html = text; var replacements = [ [/&/g, '&amp;'], [/</g, '&lt;'], [/>/g, '&gt;'], [/'/g, '&apos;'], [/"/g, '&quot;'] ]; for (var i = 0; i < replacements.length; i++) { html = html.replace(replacements[i][0], replacements[i][1]); } return html; } HtmlFormatter.prototype.typeFormattterErrorFormatter = function(context, err) { context.out('<pre class="jsondiffpatch-error">' + err + '</pre>'); }; HtmlFormatter.prototype.formatValue = function(context, value) { context.out('<pre>' + htmlEscape(JSON.stringify(value, null, 2)) + '</pre>'); }; HtmlFormatter.prototype.formatTextDiffString = function(context, value) { var lines = this.parseTextDiff(value); context.out('<ul class="jsondiffpatch-textdiff">'); for (var i = 0, l = lines.length; i < l; i++) { var line = lines[i]; context.out('<li>' + '<div class="jsondiffpatch-textdiff-location">' + '<span class="jsondiffpatch-textdiff-line-number">' + line.location.line + '</span>' + '<span class="jsondiffpatch-textdiff-char">' + line.location.chr + '</span>' + '</div>' + '<div class="jsondiffpatch-textdiff-line">'); var pieces = line.pieces; for (var pieceIndex = 0, piecesLength = pieces.length; pieceIndex < piecesLength; pieceIndex++) { /* global unescape */ var piece = pieces[pieceIndex]; context.out('<span class="jsondiffpatch-textdiff-' + piece.type + '">' + htmlEscape(unescape(piece.text)) + '</span>'); } context.out('</div></li>'); } context.out('</ul>'); }; var adjustArrows = function jsondiffpatchHtmlFormatterAdjustArrows(node) { node = node || document; var getElementText = function(el) { return el.textContent || el.innerText; }; var eachByQuery = function(el, query, fn) { var elems = el.querySelectorAll(query); for (var i = 0, l = elems.length; i < l; i++) { fn(elems[i]); } }; var eachChildren = function(el, fn) { for (var i = 0, l = el.children.length; i < l; i++) { fn(el.children[i], i); } }; eachByQuery(node, '.jsondiffpatch-arrow', function(arrow) { var arrowParent = arrow.parentNode; var svg = arrow.children[0], path = svg.children[1]; svg.style.display = 'none'; var destination = getElementText(arrowParent.querySelector('.jsondiffpatch-moved-destination')); var container = arrowParent.parentNode; var destinationElem; eachChildren(container, function(child) { if (child.getAttribute('data-key') === destination) { destinationElem = child; } }); if (!destinationElem) { return; } try { var distance = destinationElem.offsetTop - arrowParent.offsetTop; svg.setAttribute('height', Math.abs(distance) + 6); arrow.style.top = (-8 + (distance > 0 ? 0 : distance)) + 'px'; var curve = distance > 0 ? 'M30,0 Q-10,' + Math.round(distance / 2) + ' 26,' + (distance - 4) : 'M30,' + (-distance) + ' Q-10,' + Math.round(-distance / 2) + ' 26,4'; path.setAttribute('d', curve); svg.style.display = ''; } catch (err) { return; } }); }; HtmlFormatter.prototype.rootBegin = function(context, type, nodeType) { var nodeClass = 'jsondiffpatch-' + type + (nodeType ? ' jsondiffpatch-child-node-type-' + nodeType : ''); context.out('<div class="jsondiffpatch-delta ' + nodeClass + '">'); }; HtmlFormatter.prototype.rootEnd = function(context) { context.out('</div>' + (context.hasArrows ? ('<script type="text/javascript">setTimeout(' + adjustArrows.toString() + ',10);</script>') : '')); }; HtmlFormatter.prototype.nodeBegin = function(context, key, leftKey, type, nodeType) { var nodeClass = 'jsondiffpatch-' + type + (nodeType ? ' jsondiffpatch-child-node-type-' + nodeType : ''); context.out('<li class="' + nodeClass + '" data-key="' + leftKey + '">' + '<div class="jsondiffpatch-property-name">' + leftKey + '</div>'); }; HtmlFormatter.prototype.nodeEnd = function(context) { context.out('</li>'); }; /* jshint camelcase: false */ HtmlFormatter.prototype.format_unchanged = function(context, delta, left) { if (typeof left === 'undefined') { return; } context.out('<div class="jsondiffpatch-value">'); this.formatValue(context, left); context.out('</div>'); }; HtmlFormatter.prototype.format_movedestination = function(context, delta, left) { if (typeof left === 'undefined') { return; } context.out('<div class="jsondiffpatch-value">'); this.formatValue(context, left); context.out('</div>'); }; HtmlFormatter.prototype.format_node = function(context, delta, left) { // recurse var nodeType = (delta._t === 'a') ? 'array' : 'object'; context.out('<ul class="jsondiffpatch-node jsondiffpatch-node-type-' + nodeType + '">'); this.formatDeltaChildren(context, delta, left); context.out('</ul>'); }; HtmlFormatter.prototype.format_added = function(context, delta) { context.out('<div class="jsondiffpatch-value">'); this.formatValue(context, delta[0]); context.out('</div>'); }; HtmlFormatter.prototype.format_modified = function(context, delta) { context.out('<div class="jsondiffpatch-value jsondiffpatch-left-value">'); this.formatValue(context, delta[0]); context.out('</div>' + '<div class="jsondiffpatch-value jsondiffpatch-right-value">'); this.formatValue(context, delta[1]); context.out('</div>'); }; HtmlFormatter.prototype.format_deleted = function(context, delta) { context.out('<div class="jsondiffpatch-value">'); this.formatValue(context, delta[0]); context.out('</div>'); }; HtmlFormatter.prototype.format_moved = function(context, delta) { context.out('<div class="jsondiffpatch-value">'); this.formatValue(context, delta[0]); context.out('</div><div class="jsondiffpatch-moved-destination">' + delta[1] + '</div>'); // draw an SVG arrow from here to move destination context.out( /*jshint multistr: true */ '<div class="jsondiffpatch-arrow" style="position: relative; left: -34px;">\ <svg width="30" height="60" style="position: absolute; display: none;">\ <defs>\ <marker id="markerArrow" markerWidth="8" markerHeight="8" refx="2" refy="4"\ orient="auto" markerUnits="userSpaceOnUse">\ <path d="M1,1 L1,7 L7,4 L1,1" style="fill: #339;" />\ </marker>\ </defs>\ <path d="M30,0 Q-10,25 26,50" style="stroke: #88f; stroke-width: 2px; fill: none;\ stroke-opacity: 0.5; marker-end: url(#markerArrow);"></path>\ </svg>\ </div>'); context.hasArrows = true; }; HtmlFormatter.prototype.format_textdiff = function(context, delta) { context.out('<div class="jsondiffpatch-value">'); this.formatTextDiffString(context, delta[0]); context.out('</div>'); }; /* jshint camelcase: true */ var showUnchanged = function(show, node, delay) { var el = node || document.body; var prefix = 'jsondiffpatch-unchanged-'; var classes = { showing: prefix + 'showing', hiding: prefix + 'hiding', visible: prefix + 'visible', hidden: prefix + 'hidden', }; var list = el.classList; if (!list) { return; } if (!delay) { list.remove(classes.showing); list.remove(classes.hiding); list.remove(classes.visible); list.remove(classes.hidden); if (show === false) { list.add(classes.hidden); } return; } if (show === false) { list.remove(classes.showing); list.add(classes.visible); setTimeout(function() { list.add(classes.hiding); }, 10); } else { list.remove(classes.hiding); list.add(classes.showing); list.remove(classes.hidden); } var intervalId = setInterval(function() { adjustArrows(el); }, 100); setTimeout(function() { list.remove(classes.showing); list.remove(classes.hiding); if (show === false) { list.add(classes.hidden); list.remove(classes.visible); } else { list.add(classes.visible); list.remove(classes.hidden); } setTimeout(function() { list.remove(classes.visible); clearInterval(intervalId); }, delay + 400); }, delay); }; var hideUnchanged = function(node, delay) { return showUnchanged(false, node, delay); }; exports.HtmlFormatter = HtmlFormatter; exports.showUnchanged = showUnchanged; exports.hideUnchanged = hideUnchanged; var defaultInstance; exports.format = function(delta, left) { if (!defaultInstance) { defaultInstance = new HtmlFormatter(); } return defaultInstance.format(delta, left); }; },{"./base":4}],6:[function(require,module,exports){ var environment = require('../environment'); exports.base = require('./base'); exports.html = require('./html'); exports.annotated = require('./annotated'); exports.jsonpatch = require('./jsonpatch'); if (!environment.isBrowser) { var consoleModuleName = './console'; exports.console = require(consoleModuleName); } },{"../environment":2,"./annotated":3,"./base":4,"./html":5,"./jsonpatch":7}],7:[function(require,module,exports){ (function () { var base = require('./base'); var BaseFormatter = base.BaseFormatter; var named = { added: 'add', deleted: 'remove', modified: 'replace', moved: 'moved', movedestination: 'movedestination', unchanged: 'unchanged', error: 'error', textDiffLine: 'textDiffLine' }; function JSONFormatter() { this.includeMoveDestinations = false; } JSONFormatter.prototype = new BaseFormatter(); JSONFormatter.prototype.prepareContext = function (context) { BaseFormatter.prototype.prepareContext.call(this, context); context.result = []; context.path = []; context.pushCurrentOp = function (op, value) { var val = { op: op, path: this.currentPath() }; if (typeof value !== 'undefined') { val.value = value; } this.result.push(val); }; context.currentPath = function () { return '/' + this.path.join('/'); }; }; JSONFormatter.prototype.typeFormattterErrorFormatter = function (context, err) { context.out('[ERROR]' + err); }; JSONFormatter.prototype.rootBegin = function () { }; JSONFormatter.prototype.rootEnd = function () { }; JSONFormatter.prototype.nodeBegin = function (context, key, leftKey) { context.path.push(leftKey); }; JSONFormatter.prototype.nodeEnd = function (context) { context.path.pop(); }; /* jshint camelcase: false */ JSONFormatter.prototype.format_unchanged = function (context, delta, left) { if (typeof left === 'undefined') { return; } context.pushCurrentOp(named.unchanged, left); }; JSONFormatter.prototype.format_movedestination = function (context, delta, left) { if (typeof left === 'undefined') { return; } context.pushCurrentOp(named.movedestination, left); }; JSONFormatter.prototype.format_node = function (context, delta, left) { this.formatDeltaChildren(context, delta, left); }; JSONFormatter.prototype.format_added = function (context, delta) { context.pushCurrentOp(named.added, delta[0]); }; JSONFormatter.prototype.format_modified = function (context, delta) { context.pushCurrentOp(named.modified, delta[1]); }; JSONFormatter.prototype.format_deleted = function (context) { context.pushCurrentOp(named.deleted); }; JSONFormatter.prototype.format_moved = function (context, delta) { context.pushCurrentOp(named.moved, delta[1]); }; JSONFormatter.prototype.format_textdiff = function () { throw 'not implimented'; }; JSONFormatter.prototype.format = function (delta, left) { var context = {}; this.prepareContext(context); this.recurse(context, delta, left); return context.result; }; /* jshint camelcase: true */ exports.JSONFormatter = JSONFormatter; var defaultInstance; function last(arr) { return arr[arr.length - 1]; } function sortBy(arr, pred) { arr.sort(pred); return arr; } var compareByIndexDesc = function (indexA, indexB) { var lastA = parseInt(indexA, 10); var lastB = parseInt(indexB, 10); if (!(isNaN(lastA) || isNaN(lastB))) { return lastB - lastA; } else { return 0; } }; function opsByDescendingOrder(removeOps) { return sortBy(removeOps, function (a, b) { var splitA = a.path.split('/'); var splitB = b.path.split('/'); if (splitA.length !== splitB.length) { return splitA.length - splitB.length; } else { return compareByIndexDesc(last(splitA), last(splitB)); } }); } function partition(arr, pred) { var left = []; var right = []; arr.forEach(function (el) { var coll = pred(el) ? left : right; coll.push(el); }); return [left, right]; } function reorderOps(jsonFormattedDiff) { var removeOpsOtherOps = partition(jsonFormattedDiff, function (operation) { return operation.op === 'remove'; }); var removeOps = removeOpsOtherOps[0]; var otherOps = removeOpsOtherOps[1]; var removeOpsReverse = opsByDescendingOrder(removeOps); return removeOpsReverse.concat(otherOps); } var format = function (delta, left) { if (!defaultInstance) { defaultInstance = new JSONFormatter(); } return reorderOps(defaultInstance.format(delta, left)); }; exports.log = function (delta, left) { console.log(format(delta, left)); }; exports.format = format; })(); },{"./base":4}]},{},[1])(1) }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9maWJlcmdsYXNzL25vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJzcmMvbWFpbi1mb3JtYXR0ZXJzLmpzIiwic3JjL2Vudmlyb25tZW50LmpzIiwic3JjL2Zvcm1hdHRlcnMvYW5ub3RhdGVkLmpzIiwic3JjL2Zvcm1hdHRlcnMvYmFzZS5qcyIsInNyYy9mb3JtYXR0ZXJzL2h0bWwuanMiLCJzcmMvZm9ybWF0dGVycy9pbmRleC5qcyIsInNyYy9mb3JtYXR0ZXJzL2pzb25wYXRjaC5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQ0FBO0FBQ0E7QUFDQTs7QUNGQTtBQUNBO0FBQ0E7O0FDRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JNQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdE9BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6UkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1hBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJmaWxlIjoiZ2VuZXJhdGVkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXNDb250ZW50IjpbIihmdW5jdGlvbiBlKHQsbixyKXtmdW5jdGlvbiBzKG8sdSl7aWYoIW5bb10pe2lmKCF0W29dKXt2YXIgYT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2lmKCF1JiZhKXJldHVybiBhKG8sITApO2lmKGkpcmV0dXJuIGkobywhMCk7dmFyIGY9bmV3IEVycm9yKFwiQ2Fubm90IGZpbmQgbW9kdWxlICdcIitvK1wiJ1wiKTt0aHJvdyBmLmNvZGU9XCJNT0RVTEVfTk9UX0ZPVU5EXCIsZn12YXIgbD1uW29dPXtleHBvcnRzOnt9fTt0W29dWzBdLmNhbGwobC5leHBvcnRzLGZ1bmN0aW9uKGUpe3ZhciBuPXRbb11bMV1bZV07cmV0dXJuIHMobj9uOmUpfSxsLGwuZXhwb3J0cyxlLHQsbixyKX1yZXR1cm4gbltvXS5leHBvcnRzfXZhciBpPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7Zm9yKHZhciBvPTA7bzxyLmxlbmd0aDtvKyspcyhyW29dKTtyZXR1cm4gc30pIiwiXG5tb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vZm9ybWF0dGVycycpO1xuIiwiXG5leHBvcnRzLmlzQnJvd3NlciA9IHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnO1xuIiwidmFyIGJhc2UgPSByZXF1aXJlKCcuL2Jhc2UnKTtcbnZhciBCYXNlRm9ybWF0dGVyID0gYmFzZS5CYXNlRm9ybWF0dGVyO1xuXG52YXIgQW5ub3RhdGVkRm9ybWF0dGVyID0gZnVuY3Rpb24gQW5ub3RhdGVkRm9ybWF0dGVyKCkge1xuICB0aGlzLmluY2x1ZGVNb3ZlRGVzdGluYXRpb25zID0gZmFsc2U7XG59O1xuXG5Bbm5vdGF0ZWRGb3JtYXR0ZXIucHJvdG90eXBlID0gbmV3IEJhc2VGb3JtYXR0ZXIoKTtcblxuQW5ub3RhdGVkRm9ybWF0dGVyLnByb3RvdHlwZS5wcmVwYXJlQ29udGV4dCA9IGZ1bmN0aW9uKGNvbnRleHQpIHtcbiAgQmFzZUZvcm1hdHRlci5wcm90b3R5cGUucHJlcGFyZUNvbnRleHQuY2FsbCh0aGlzLCBjb250ZXh0KTtcbiAgY29udGV4dC5pbmRlbnQgPSBmdW5jdGlvbihsZXZlbHMpIHtcbiAgICB0aGlzLmluZGVudExldmVsID0gKHRoaXMuaW5kZW50TGV2ZWwgfHwgMCkgK1xuICAgICAgKHR5cGVvZiBsZXZlbHMgPT09ICd1bmRlZmluZWQnID8gMSA6IGxldmVscyk7XG4gICAgdGhpcy5pbmRlbnRQYWQgPSBuZXcgQXJyYXkodGhpcy5pbmRlbnRMZXZlbCArIDEpLmpvaW4oJyZuYnNwOyZuYnNwOycpO1xuICB9O1xuICBjb250ZXh0LnJvdyA9IGZ1bmN0aW9uKGpzb24sIGh0bWxOb3RlKSB7XG4gICAgY29udGV4dC5vdXQoJzx0cj48dGQgc3R5bGU9XCJ3aGl0ZS1zcGFjZTogbm93cmFwO1wiPicgK1xuICAgICAgJzxwcmUgY2xhc3M9XCJqc29uZGlmZnBhdGNoLWFubm90YXRlZC1pbmRlbnRcIiBzdHlsZT1cImRpc3BsYXk6IGlubGluZS1ibG9ja1wiPicpO1xuICAgIGNvbnRleHQub3V0KGNvbnRleHQuaW5kZW50UGFkKTtcbiAgICBjb250ZXh0Lm91dCgnPC9wcmU+PHByZSBzdHlsZT1cImRpc3BsYXk6IGlubGluZS1ibG9ja1wiPicpO1xuICAgIGNvbnRleHQub3V0KGpzb24pO1xuICAgIGNvbnRleHQub3V0KCc8L3ByZT48L3RkPjx0ZCBjbGFzcz1cImpzb25kaWZmcGF0Y2gtZGVsdGEtbm90ZVwiPjxkaXY+Jyk7XG4gICAgY29udGV4dC5vdXQoaHRtbE5vdGUpO1xuICAgIGNvbnRleHQub3V0KCc8L2Rpdj48L3RkPjwvdHI+Jyk7XG4gIH07XG59O1xuXG5Bbm5vdGF0ZWRGb3JtYXR0ZXIucHJvdG90eXBlLnR5cGVGb3JtYXR0dGVyRXJyb3JGb3JtYXR0ZXIgPSBmdW5jdGlvbihjb250ZXh0LCBlcnIpIHtcbiAgY29udGV4dC5yb3coJycsICc8cHJlIGNsYXNzPVwianNvbmRpZmZwYXRjaC1lcnJvclwiPicgKyBlcnIgKyAnPC9wcmU+Jyk7XG59O1xuXG5Bbm5vdGF0ZWRGb3JtYXR0ZXIucHJvdG90eXBlLmZvcm1hdFRleHREaWZmU3RyaW5nID0gZnVuY3Rpb24oY29udGV4dCwgdmFsdWUpIHtcbiAgdmFyIGxpbmVzID0gdGhpcy5wYXJzZVRleHREaWZmKHZhbHVlKTtcbiAgY29udGV4dC5vdXQoJzx1bCBjbGFzcz1cImpzb25kaWZmcGF0Y2gtdGV4dGRpZmZcIj4nKTtcbiAgZm9yICh2YXIgaSA9IDAsIGwgPSBsaW5lcy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICB2YXIgbGluZSA9IGxpbmVzW2ldO1xuICAgIGNvbnRleHQub3V0KCc8bGk+JyArXG4gICAgICAnPGRpdiBjbGFzcz1cImpzb25kaWZmcGF0Y2gtdGV4dGRpZmYtbG9jYXRpb25cIj4nICtcbiAgICAgICc8c3BhbiBjbGFzcz1cImpzb25kaWZmcGF0Y2gtdGV4dGRpZmYtbGluZS1udW1iZXJcIj4nICtcbiAgICAgIGxpbmUubG9jYXRpb24ubGluZSArXG4gICAgICAnPC9zcGFuPicgK1xuICAgICAgJzxzcGFuIGNsYXNzPVwianNvbmRpZmZwYXRjaC10ZXh0ZGlmZi1jaGFyXCI+JyArXG4gICAgICBsaW5lLmxvY2F0aW9uLmNociArXG4gICAgICAnPC9zcGFuPicgK1xuICAgICAgJzwvZGl2PicgK1xuICAgICAgJzxkaXYgY2xhc3M9XCJqc29uZGlmZnBhdGNoLXRleHRkaWZmLWxpbmVcIj4nKTtcbiAgICB2YXIgcGllY2VzID0gbGluZS5waWVjZXM7XG4gICAgZm9yICh2YXIgcGllY2VJbmRleCA9IDAsIHBpZWNlc0xlbmd0aCA9IHBpZWNlcy5sZW5ndGg7IHBpZWNlSW5kZXggPCBwaWVjZXNMZW5ndGg7IHBpZWNlSW5kZXgrKykge1xuICAgICAgdmFyIHBpZWNlID0gcGllY2VzW3BpZWNlSW5kZXhdO1xuICAgICAgY29udGV4dC5vdXQoJzxzcGFuIGNsYXNzPVwianNvbmRpZmZwYXRjaC10ZXh0ZGlmZi0nICsgcGllY2UudHlwZSArICdcIj4nICtcbiAgICAgICAgcGllY2UudGV4dCArICc8L3NwYW4+Jyk7XG4gICAgfVxuICAgIGNvbnRleHQub3V0KCc8L2Rpdj48L2xpPicpO1xuICB9XG4gIGNvbnRleHQub3V0KCc8L3VsPicpO1xufTtcblxuQW5ub3RhdGVkRm9ybWF0dGVyLnByb3RvdHlwZS5yb290QmVnaW4gPSBmdW5jdGlvbihjb250ZXh0LCB0eXBlLCBub2RlVHlwZSkge1xuICBjb250ZXh0Lm91dCgnPHRhYmxlIGNsYXNzPVwianNvbmRpZmZwYXRjaC1hbm5vdGF0ZWQtZGVsdGFcIj4nKTtcbiAgaWYgKHR5cGUgPT09ICdub2RlJykge1xuICAgIGNvbnRleHQucm93KCd7Jyk7XG4gICAgY29udGV4dC5pbmRlbnQoKTtcbiAgfVxuICBpZiAobm9kZVR5cGUgPT09ICdhcnJheScpIHtcbiAgICBjb250ZXh0LnJvdygnXCJfdFwiOiBcImFcIiwnLCAnQXJyYXkgZGVsdGEgKG1lbWJlciBuYW1lcyBpbmRpY2F0ZSBhcnJheSBpbmRpY2VzKScpO1xuICB9XG59O1xuXG5Bbm5vdGF0ZWRGb3JtYXR0ZXIucHJvdG90eXBlLnJvb3RFbmQgPSBmdW5jdGlvbihjb250ZXh0LCB0eXBlKSB7XG4gIGlmICh0eXBlID09PSAnbm9kZScpIHtcbiAgICBjb250ZXh0LmluZGVudCgtMSk7XG4gICAgY29udGV4dC5yb3coJ30nKTtcbiAgfVxuICBjb250ZXh0Lm91dCgnPC90YWJsZT4nKTtcbn07XG5cbkFubm90YXRlZEZvcm1hdHRlci5wcm90b3R5cGUubm9kZUJlZ2luID0gZnVuY3Rpb24oY29udGV4dCwga2V5LCBsZWZ0S2V5LCB0eXBlLCBub2RlVHlwZSkge1xuICBjb250ZXh0LnJvdygnJnF1b3Q7JyArIGtleSArICcmcXVvdDs6IHsnKTtcbiAgaWYgKHR5cGUgPT09ICdub2RlJykge1xuICAgIGNvbnRleHQuaW5kZW50KCk7XG4gIH1cbiAgaWYgKG5vZGVUeXBlID09PSAnYXJyYXknKSB7XG4gICAgY29udGV4dC5yb3coJ1wiX3RcIjogXCJhXCIsJywgJ0FycmF5IGRlbHRhIChtZW1iZXIgbmFtZXMgaW5kaWNhdGUgYXJyYXkgaW5kaWNlcyknKTtcbiAgfVxufTtcblxuQW5ub3RhdGVkRm9ybWF0dGVyLnByb3RvdHlwZS5ub2RlRW5kID0gZnVuY3Rpb24oY29udGV4dCwga2V5LCBsZWZ0S2V5LCB0eXBlLCBub2RlVHlwZSwgaXNMYXN0KSB7XG4gIGlmICh0eXBlID09PSAnbm9kZScpIHtcbiAgICBjb250ZXh0LmluZGVudCgtMSk7XG4gIH1cbiAgY29udGV4dC5yb3coJ30nICsgKGlzTGFzdCA/ICcnIDogJywnKSk7XG59O1xuXG4vKiBqc2hpbnQgY2FtZWxjYXNlOiBmYWxzZSAqL1xuXG5Bbm5vdGF0ZWRGb3JtYXR0ZXIucHJvdG90eXBlLmZvcm1hdF91bmNoYW5nZWQgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuO1xufTtcblxuQW5ub3RhdGVkRm9ybWF0dGVyLnByb3RvdHlwZS5mb3JtYXRfbW92ZWRlc3RpbmF0aW9uID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybjtcbn07XG5cblxuQW5ub3RhdGVkRm9ybWF0dGVyLnByb3RvdHlwZS5mb3JtYXRfbm9kZSA9IGZ1bmN0aW9uKGNvbnRleHQsIGRlbHRhLCBsZWZ0KSB7XG4gIC8vIHJlY3Vyc2VcbiAgdGhpcy5mb3JtYXREZWx0YUNoaWxkcmVuKGNvbnRleHQsIGRlbHRhLCBsZWZ0KTtcbn07XG5cbnZhciB3cmFwUHJvcGVydHlOYW1lID0gZnVuY3Rpb24obmFtZSkge1xuICByZXR1cm4gJzxwcmUgc3R5bGU9XCJkaXNwbGF5OmlubGluZS1ibG9ja1wiPiZxdW90OycgKyBuYW1lICsgJyZxdW90OzwvcHJlPic7XG59O1xuXG52YXIgZGVsdGFBbm5vdGF0aW9ucyA9IHtcbiAgYWRkZWQ6IGZ1bmN0aW9uKGRlbHRhLCBsZWZ0LCBrZXksIGxlZnRLZXkpIHtcbiAgICB2YXIgZm9ybWF0TGVnZW5kID0gJyA8cHJlPihbbmV3VmFsdWVdKTwvcHJlPic7XG4gICAgaWYgKHR5cGVvZiBsZWZ0S2V5ID09PSAndW5kZWZpbmVkJykge1xuICAgICAgcmV0dXJuICduZXcgdmFsdWUnICsgZm9ybWF0TGVnZW5kO1xuICAgIH1cbiAgICBpZiAodHlwZW9mIGxlZnRLZXkgPT09ICdudW1iZXInKSB7XG4gICAgICByZXR1cm4gJ2luc2VydCBhdCBpbmRleCAnICsgbGVmdEtleSArIGZvcm1hdExlZ2VuZDtcbiAgICB9XG4gICAgcmV0dXJuICdhZGQgcHJvcGVydHkgJyArIHdyYXBQcm9wZXJ0eU5hbWUobGVmdEtleSkgKyBmb3JtYXRMZWdlbmQ7XG4gIH0sXG4gIG1vZGlmaWVkOiBmdW5jdGlvbihkZWx0YSwgbGVmdCwga2V5LCBsZWZ0S2V5KSB7XG4gICAgdmFyIGZvcm1hdExlZ2VuZCA9ICcgPHByZT4oW3ByZXZpb3VzVmFsdWUsIG5ld1ZhbHVlXSk8L3ByZT4nO1xuICAgIGlmICh0eXBlb2YgbGVmdEtleSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIHJldHVybiAnbW9kaWZ5IHZhbHVlJyArIGZvcm1hdExlZ2VuZDtcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBsZWZ0S2V5ID09PSAnbnVtYmVyJykge1xuICAgICAgcmV0dXJuICdtb2RpZnkgYXQgaW5kZXggJyArIGxlZnRLZXkgKyBmb3JtYXRMZWdlbmQ7XG4gICAgfVxuICAgIHJldHVybiAnbW9kaWZ5IHByb3BlcnR5ICcgKyB3cmFwUHJvcGVydHlOYW1lKGxlZnRLZXkpICsgZm9ybWF0TGVnZW5kO1xuICB9LFxuICBkZWxldGVkOiBmdW5jdGlvbihkZWx0YSwgbGVmdCwga2V5LCBsZWZ0S2V5KSB7XG4gICAgdmFyIGZvcm1hdExlZ2VuZCA9ICcgPHByZT4oW3ByZXZpb3VzVmFsdWUsIDAsIDBdKTwvcHJlPic7XG4gICAgaWYgKHR5cGVvZiBsZWZ0S2V5ID09PSAndW5kZWZpbmVkJykge1xuICAgICAgcmV0dXJuICdkZWxldGUgdmFsdWUnICsgZm9ybWF0TGVnZW5kO1xuICAgIH1cbiAgICBpZiAodHlwZW9mIGxlZnRLZXkgPT09ICdudW1iZXInKSB7XG4gICAgICByZXR1cm4gJ3JlbW92ZSBpbmRleCAnICsgbGVmdEtleSArIGZvcm1hdExlZ2VuZDtcbiAgICB9XG4gICAgcmV0dXJuICdkZWxldGUgcHJvcGVydHkgJyArIHdyYXBQcm9wZXJ0eU5hbWUobGVmdEtleSkgKyBmb3JtYXRMZWdlbmQ7XG4gIH0sXG4gIG1vdmVkOiBmdW5jdGlvbihkZWx0YSwgbGVmdCwga2V5LCBsZWZ0S2V5KSB7XG4gICAgcmV0dXJuICdtb3ZlIGZyb20gPHNwYW4gdGl0bGU9XCIocG9zaXRpb24gdG8gcmVtb3ZlIGF0IG9yaWdpbmFsIHN0YXRlKVwiPmluZGV4ICcgK1xuICAgICAgbGVmdEtleSArICc8L3NwYW4+IHRvICcgK1xuICAgICAgJzxzcGFuIHRpdGxlPVwiKHBvc2l0aW9uIHRvIGluc2VydCBhdCBmaW5hbCBzdGF0ZSlcIj5pbmRleCAnICtcbiAgICAgIGRlbHRhWzFdICsgJzwvc3Bhbj4nO1xuICB9LFxuICB0ZXh0ZGlmZjogZnVuY3Rpb24oZGVsdGEsIGxlZnQsIGtleSwgbGVmdEtleSkge1xuICAgIHZhciBsb2NhdGlvbiA9ICh0eXBlb2YgbGVmdEtleSA9PT0gJ3VuZGVmaW5lZCcpID9cbiAgICAgICcnIDogKFxuICAgICAgICAodHlwZW9mIGxlZnRLZXkgPT09ICdudW1iZXInKSA/XG4gICAgICAgICcgYXQgaW5kZXggJyArIGxlZnRLZXkgOlxuICAgICAgICAnIGF0IHByb3BlcnR5ICcgKyB3cmFwUHJvcGVydHlOYW1lKGxlZnRLZXkpXG4gICAgICApO1xuICAgIHJldHVybiAndGV4dCBkaWZmJyArIGxvY2F0aW9uICsgJywgZm9ybWF0IGlzICcgK1xuICAgICAgJzxhIGhyZWY9XCJodHRwczovL2NvZGUuZ29vZ2xlLmNvbS9wL2dvb2dsZS1kaWZmLW1hdGNoLXBhdGNoL3dpa2kvVW5pZGlmZlwiPicgK1xuICAgICAgJ2EgdmFyaWF0aW9uIG9mIFVuaWRpZmY8L2E+JztcbiAgfVxufTtcblxudmFyIGZvcm1hdEFueUNoYW5nZSA9IGZ1bmN0aW9uKGNvbnRleHQsIGRlbHRhKSB7XG4gIHZhciBkZWx0YVR5cGUgPSB0aGlzLmdldERlbHRhVHlwZShkZWx0YSk7XG4gIHZhciBhbm5vdGF0b3IgPSBkZWx0YUFubm90YXRpb25zW2RlbHRhVHlwZV07XG4gIHZhciBodG1sTm90ZSA9IGFubm90YXRvciAmJiBhbm5vdGF0b3IuYXBwbHkoYW5ub3RhdG9yLFxuICAgIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMSkpO1xuICB2YXIganNvbiA9IEpTT04uc3RyaW5naWZ5KGRlbHRhLCBudWxsLCAyKTtcbiAgaWYgKGRlbHRhVHlwZSA9PT0gJ3RleHRkaWZmJykge1xuICAgIC8vIHNwbGl0IHRleHQgZGlmZnMgbGluZXNcbiAgICBqc29uID0ganNvbi5zcGxpdCgnXFxcXG4nKS5qb2luKCdcXFxcblwiK1xcbiAgIFwiJyk7XG4gIH1cbiAgY29udGV4dC5pbmRlbnQoKTtcbiAgY29udGV4dC5yb3coanNvbiwgaHRtbE5vdGUpO1xuICBjb250ZXh0LmluZGVudCgtMSk7XG59O1xuXG5Bbm5vdGF0ZWRGb3JtYXR0ZXIucHJvdG90eXBlLmZvcm1hdF9hZGRlZCA9IGZvcm1hdEFueUNoYW5nZTtcbkFubm90YXRlZEZvcm1hdHRlci5wcm90b3R5cGUuZm9ybWF0X21vZGlmaWVkID0gZm9ybWF0QW55Q2hhbmdlO1xuQW5ub3RhdGVkRm9ybWF0dGVyLnByb3RvdHlwZS5mb3JtYXRfZGVsZXRlZCA9IGZvcm1hdEFueUNoYW5nZTtcbkFubm90YXRlZEZvcm1hdHRlci5wcm90b3R5cGUuZm9ybWF0X21vdmVkID0gZm9ybWF0QW55Q2hhbmdlO1xuQW5ub3RhdGVkRm9ybWF0dGVyLnByb3RvdHlwZS5mb3JtYXRfdGV4dGRpZmYgPSBmb3JtYXRBbnlDaGFuZ2U7XG5cbi8qIGpzaGludCBjYW1lbGNhc2U6IHRydWUgKi9cblxuZXhwb3J0cy5Bbm5vdGF0ZWRGb3JtYXR0ZXIgPSBBbm5vdGF0ZWRGb3JtYXR0ZXI7XG5cbnZhciBkZWZhdWx0SW5zdGFuY2U7XG5cbmV4cG9ydHMuZm9ybWF0ID0gZnVuY3Rpb24oZGVsdGEsIGxlZnQpIHtcbiAgaWYgKCFkZWZhdWx0SW5zdGFuY2UpIHtcbiAgICBkZWZhdWx0SW5zdGFuY2UgPSBuZXcgQW5ub3RhdGVkRm9ybWF0dGVyKCk7XG4gIH1cbiAgcmV0dXJuIGRlZmF1bHRJbnN0YW5jZS5mb3JtYXQoZGVsdGEsIGxlZnQpO1xufTtcbiIsInZhciBpc0FycmF5ID0gKHR5cGVvZiBBcnJheS5pc0FycmF5ID09PSAnZnVuY3Rpb24nKSA/XG4gIC8vIHVzZSBuYXRpdmUgZnVuY3Rpb25cbiAgQXJyYXkuaXNBcnJheSA6XG4gIC8vIHVzZSBpbnN0YW5jZW9mIG9wZXJhdG9yXG4gIGZ1bmN0aW9uKGEpIHtcbiAgICByZXR1cm4gYSBpbnN0YW5jZW9mIEFycmF5O1xuICB9O1xuXG52YXIgZ2V0T2JqZWN0S2V5cyA9IHR5cGVvZiBPYmplY3Qua2V5cyA9PT0gJ2Z1bmN0aW9uJyA/XG4gIGZ1bmN0aW9uKG9iaikge1xuICAgIHJldHVybiBPYmplY3Qua2V5cyhvYmopO1xuICB9IDogZnVuY3Rpb24ob2JqKSB7XG4gICAgdmFyIG5hbWVzID0gW107XG4gICAgZm9yICh2YXIgcHJvcGVydHkgaW4gb2JqKSB7XG4gICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwgcHJvcGVydHkpKSB7XG4gICAgICAgIG5hbWVzLnB1c2gocHJvcGVydHkpO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gbmFtZXM7XG4gIH07XG5cbnZhciB0cmltVW5kZXJzY29yZSA9IGZ1bmN0aW9uKHN0cikge1xuICBpZiAoc3RyLnN1YnN0cigwLCAxKSA9PT0gJ18nKSB7XG4gICAgcmV0dXJuIHN0ci5zbGljZSgxKTtcbiAgfVxuICByZXR1cm4gc3RyO1xufTtcblxudmFyIGFycmF5S2V5VG9Tb3J0TnVtYmVyID0gZnVuY3Rpb24oa2V5KSB7XG4gIGlmIChrZXkgPT09ICdfdCcpIHtcbiAgICByZXR1cm4gLTE7XG4gIH0gZWxzZSB7XG4gICAgaWYgKGtleS5zdWJzdHIoMCwgMSkgPT09ICdfJykge1xuICAgICAgcmV0dXJuIHBhcnNlSW50KGtleS5zbGljZSgxKSwgMTApO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gcGFyc2VJbnQoa2V5LCAxMCkgKyAwLjE7XG4gICAgfVxuICB9XG59O1xuXG52YXIgYXJyYXlLZXlDb21wYXJlciA9IGZ1bmN0aW9uKGtleTEsIGtleTIpIHtcbiAgcmV0dXJuIGFycmF5S2V5VG9Tb3J0TnVtYmVyKGtleTEpIC0gYXJyYXlLZXlUb1NvcnROdW1iZXIoa2V5Mik7XG59O1xuXG52YXIgQmFzZUZvcm1hdHRlciA9IGZ1bmN0aW9uIEJhc2VGb3JtYXR0ZXIoKSB7fTtcblxuQmFzZUZvcm1hdHRlci5wcm90b3R5cGUuZm9ybWF0ID0gZnVuY3Rpb24oZGVsdGEsIGxlZnQpIHtcbiAgdmFyIGNvbnRleHQgPSB7fTtcbiAgdGhpcy5wcmVwYXJlQ29udGV4dChjb250ZXh0KTtcbiAgdGhpcy5yZWN1cnNlKGNvbnRleHQsIGRlbHRhLCBsZWZ0KTtcbiAgcmV0dXJuIHRoaXMuZmluYWxpemUoY29udGV4dCk7XG59O1xuXG5CYXNlRm9ybWF0dGVyLnByb3RvdHlwZS5wcmVwYXJlQ29udGV4dCA9IGZ1bmN0aW9uKGNvbnRleHQpIHtcbiAgY29udGV4dC5idWZmZXIgPSBbXTtcbiAgY29udGV4dC5vdXQgPSBmdW5jdGlvbigpIHtcbiAgICB0aGlzLmJ1ZmZlci5wdXNoLmFwcGx5KHRoaXMuYnVmZmVyLCBhcmd1bWVudHMpO1xuICB9O1xufTtcblxuQmFzZUZvcm1hdHRlci5wcm90b3R5cGUudHlwZUZvcm1hdHR0ZXJOb3RGb3VuZCA9IGZ1bmN0aW9uKGNvbnRleHQsIGRlbHRhVHlwZSkge1xuICB0aHJvdyBuZXcgRXJyb3IoJ2Nhbm5vdCBmb3JtYXQgZGVsdGEgdHlwZTogJyArIGRlbHRhVHlwZSk7XG59O1xuXG5CYXNlRm9ybWF0dGVyLnByb3RvdHlwZS50eXBlRm9ybWF0dHRlckVycm9yRm9ybWF0dGVyID0gZnVuY3Rpb24oY29udGV4dCwgZXJyKSB7XG4gIHJldHVybiBlcnIudG9TdHJpbmcoKTtcbn07XG5cbkJhc2VGb3JtYXR0ZXIucHJvdG90eXBlLmZpbmFsaXplID0gZnVuY3Rpb24oY29udGV4dCkge1xuICBpZiAoaXNBcnJheShjb250ZXh0LmJ1ZmZlcikpIHtcbiAgICByZXR1cm4gY29udGV4dC5idWZmZXIuam9pbignJyk7XG4gIH1cbn07XG5cbkJhc2VGb3JtYXR0ZXIucHJvdG90eXBlLnJlY3Vyc2UgPSBmdW5jdGlvbihjb250ZXh0LCBkZWx0YSwgbGVmdCwga2V5LCBsZWZ0S2V5LCBtb3ZlZEZyb20sIGlzTGFzdCkge1xuXG4gIHZhciB1c2VNb3ZlT3JpZ2luSGVyZSA9IGRlbHRhICYmIG1vdmVkRnJvbTtcbiAgdmFyIGxlZnRWYWx1ZSA9IHVzZU1vdmVPcmlnaW5IZXJlID8gbW92ZWRGcm9tLnZhbHVlIDogbGVmdDtcblxuICBpZiAodHlwZW9mIGRlbHRhID09PSAndW5kZWZpbmVkJyAmJiB0eXBlb2Yga2V5ID09PSAndW5kZWZpbmVkJykge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICB2YXIgdHlwZSA9IHRoaXMuZ2V0RGVsdGFUeXBlKGRlbHRhLCBtb3ZlZEZyb20pO1xuICB2YXIgbm9kZVR5cGUgPSB0eXBlID09PSAnbm9kZScgPyAoZGVsdGEuX3QgPT09ICdhJyA/ICdhcnJheScgOiAnb2JqZWN0JykgOiAnJztcblxuICBpZiAodHlwZW9mIGtleSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICB0aGlzLm5vZGVCZWdpbihjb250ZXh0LCBrZXksIGxlZnRLZXksIHR5cGUsIG5vZGVUeXBlLCBpc0xhc3QpO1xuICB9IGVsc2Uge1xuICAgIHRoaXMucm9vdEJlZ2luKGNvbnRleHQsIHR5cGUsIG5vZGVUeXBlKTtcbiAgfVxuXG4gIHZhciB0eXBlRm9ybWF0dHRlcjtcbiAgdHJ5IHtcbiAgICB0eXBlRm9ybWF0dHRlciA9IHRoaXNbJ2Zvcm1hdF8nICsgdHlwZV0gfHwgdGhpcy50eXBlRm9ybWF0dHRlck5vdEZvdW5kKGNvbnRleHQsIHR5cGUpO1xuICAgIHR5cGVGb3JtYXR0dGVyLmNhbGwodGhpcywgY29udGV4dCwgZGVsdGEsIGxlZnRWYWx1ZSwga2V5LCBsZWZ0S2V5LCBtb3ZlZEZyb20pO1xuICB9IGNhdGNoIChlcnIpIHtcbiAgICB0aGlzLnR5cGVGb3JtYXR0dGVyRXJyb3JGb3JtYXR0ZXIoY29udGV4dCwgZXJyLCBkZWx0YSwgbGVmdFZhbHVlLCBrZXksIGxlZnRLZXksIG1vdmVkRnJvbSk7XG4gICAgaWYgKHR5cGVvZiBjb25zb2xlICE9PSAndW5kZWZpbmVkJyAmJiBjb25zb2xlLmVycm9yKSB7XG4gICAgICBjb25zb2xlLmVycm9yKGVyci5zdGFjayk7XG4gICAgfVxuICB9XG5cbiAgaWYgKHR5cGVvZiBrZXkgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgdGhpcy5ub2RlRW5kKGNvbnRleHQsIGtleSwgbGVmdEtleSwgdHlwZSwgbm9kZVR5cGUsIGlzTGFzdCk7XG4gIH0gZWxzZSB7XG4gICAgdGhpcy5yb290RW5kKGNvbnRleHQsIHR5cGUsIG5vZGVUeXBlKTtcbiAgfVxufTtcblxuQmFzZUZvcm1hdHRlci5wcm90b3R5cGUuZm9ybWF0RGVsdGFDaGlsZHJlbiA9IGZ1bmN0aW9uKGNvbnRleHQsIGRlbHRhLCBsZWZ0KSB7XG4gIHZhciBzZWxmID0gdGhpcztcbiAgdGhpcy5mb3JFYWNoRGVsdGFLZXkoZGVsdGEsIGxlZnQsIGZ1bmN0aW9uKGtleSwgbGVmdEtleSwgbW92ZWRGcm9tLCBpc0xhc3QpIHtcbiAgICBzZWxmLnJlY3Vyc2UoY29udGV4dCwgZGVsdGFba2V5XSwgbGVmdCA/IGxlZnRbbGVmdEtleV0gOiB1bmRlZmluZWQsXG4gICAgICBrZXksIGxlZnRLZXksIG1vdmVkRnJvbSwgaXNMYXN0KTtcbiAgfSk7XG59O1xuXG5CYXNlRm9ybWF0dGVyLnByb3RvdHlwZS5mb3JFYWNoRGVsdGFLZXkgPSBmdW5jdGlvbihkZWx0YSwgbGVmdCwgZm4pIHtcbiAgdmFyIGtleXMgPSBnZXRPYmplY3RLZXlzKGRlbHRhKTtcbiAgdmFyIGFycmF5S2V5cyA9IGRlbHRhLl90ID09PSAnYSc7XG4gIHZhciBtb3ZlRGVzdGluYXRpb25zID0ge307XG4gIHZhciBuYW1lO1xuICBpZiAodHlwZW9mIGxlZnQgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgZm9yIChuYW1lIGluIGxlZnQpIHtcbiAgICAgIGlmICh0eXBlb2YgZGVsdGFbbmFtZV0gPT09ICd1bmRlZmluZWQnICYmXG4gICAgICAgICgoIWFycmF5S2V5cykgfHwgdHlwZW9mIGRlbHRhWydfJyArIG5hbWVdID09PSAndW5kZWZpbmVkJykpIHtcbiAgICAgICAga2V5cy5wdXNoKG5hbWUpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICAvLyBsb29rIGZvciBtb3ZlIGRlc3RpbmF0aW9uc1xuICBmb3IgKG5hbWUgaW4gZGVsdGEpIHtcbiAgICB2YXIgdmFsdWUgPSBkZWx0YVtuYW1lXTtcbiAgICBpZiAoaXNBcnJheSh2YWx1ZSkgJiYgdmFsdWVbMl0gPT09IDMpIHtcbiAgICAgIG1vdmVEZXN0aW5hdGlvbnNbdmFsdWVbMV0udG9TdHJpbmcoKV0gPSB7XG4gICAgICAgIGtleTogbmFtZSxcbiAgICAgICAgdmFsdWU6IGxlZnQgJiYgbGVmdFtwYXJzZUludChuYW1lLnN1YnN0cigxKSldXG4gICAgICB9O1xuICAgICAgaWYgKHRoaXMuaW5jbHVkZU1vdmVEZXN0aW5hdGlvbnMgIT09IGZhbHNlKSB7XG4gICAgICAgIGlmICgodHlwZW9mIGxlZnQgPT09ICd1bmRlZmluZWQnKSAmJlxuICAgICAgICAgICh0eXBlb2YgZGVsdGFbdmFsdWVbMV1dID09PSAndW5kZWZpbmVkJykpIHtcbiAgICAgICAgICBrZXlzLnB1c2godmFsdWVbMV0udG9TdHJpbmcoKSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgaWYgKGFycmF5S2V5cykge1xuICAgIGtleXMuc29ydChhcnJheUtleUNvbXBhcmVyKTtcbiAgfSBlbHNlIHtcbiAgICBrZXlzLnNvcnQoKTtcbiAgfVxuICBmb3IgKHZhciBpbmRleCA9IDAsIGxlbmd0aCA9I