You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
923 lines
70 KiB
923 lines
70 KiB
6 years ago
|
!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(' ');
|
||
|
};
|
||
|
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('"' + key + '": {');
|
||
|
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">"' + name + '"</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 (Object.prototype.hasOwnProperty.call(left, name)) {
|
||
|
if (typeof delta[name] === 'undefined' &&
|
||
|
((!arrayKeys) || typeof delta['_' + name] === 'undefined')) {
|
||
|
keys.push(name);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
// look for move destinations
|
||
|
for (name in delta) {
|
||
|
if (Object.prototype.hasOwnProperty.call(delta, name)) {
|
||
|
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, '&'],
|
||
|
[/</g, '<'],
|
||
|
[/>/g, '>'],
|
||
|
[/'/g, '''],
|
||
|
[/"/g, '"']
|
||
|
];
|
||
|
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,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9maWJlcmdsYXNzL25vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJzcmMvbWFpbi1mb3JtYXR0ZXJzLmpzIiwic3JjL2Vudmlyb25tZW50LmpzIiwic3JjL2Zvcm1hdHRlcnMvYW5ub3RhdGVkLmpzIiwic3JjL2Zvcm1hdHRlcnMvYmFzZS5qcyIsInNyYy9mb3JtYXR0ZXJzL2h0bWwuanMiLCJzcmMvZm9ybWF0dGVycy9pbmRleC5qcyIsInNyYy9mb3JtYXR0ZXJzL2pzb25wYXRjaC5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQ0FBO0FBQ0E7QUFDQTs7QUNGQTtBQUNBO0FBQ0E7O0FDRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JNQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxT0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO
|