UNPKG

79.9 kBJavaScriptView Raw
1'use strict';
2
3Object.defineProperty(exports, '__esModule', { value: true });
4
5function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
6
7var dmp = _interopDefault(require('diff-match-patch'));
8var chalk = _interopDefault(require('chalk'));
9
10var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) {
11 return typeof obj;
12} : function (obj) {
13 return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
14};
15
16
17
18
19
20
21
22
23
24
25
26var classCallCheck = function (instance, Constructor) {
27 if (!(instance instanceof Constructor)) {
28 throw new TypeError("Cannot call a class as a function");
29 }
30};
31
32var createClass = function () {
33 function defineProperties(target, props) {
34 for (var i = 0; i < props.length; i++) {
35 var descriptor = props[i];
36 descriptor.enumerable = descriptor.enumerable || false;
37 descriptor.configurable = true;
38 if ("value" in descriptor) descriptor.writable = true;
39 Object.defineProperty(target, descriptor.key, descriptor);
40 }
41 }
42
43 return function (Constructor, protoProps, staticProps) {
44 if (protoProps) defineProperties(Constructor.prototype, protoProps);
45 if (staticProps) defineProperties(Constructor, staticProps);
46 return Constructor;
47 };
48}();
49
50
51
52
53
54
55
56var get = function get(object, property, receiver) {
57 if (object === null) object = Function.prototype;
58 var desc = Object.getOwnPropertyDescriptor(object, property);
59
60 if (desc === undefined) {
61 var parent = Object.getPrototypeOf(object);
62
63 if (parent === null) {
64 return undefined;
65 } else {
66 return get(parent, property, receiver);
67 }
68 } else if ("value" in desc) {
69 return desc.value;
70 } else {
71 var getter = desc.get;
72
73 if (getter === undefined) {
74 return undefined;
75 }
76
77 return getter.call(receiver);
78 }
79};
80
81var inherits = function (subClass, superClass) {
82 if (typeof superClass !== "function" && superClass !== null) {
83 throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);
84 }
85
86 subClass.prototype = Object.create(superClass && superClass.prototype, {
87 constructor: {
88 value: subClass,
89 enumerable: false,
90 writable: true,
91 configurable: true
92 }
93 });
94 if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
95};
96
97
98
99
100
101
102
103
104
105
106
107var possibleConstructorReturn = function (self, call) {
108 if (!self) {
109 throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
110 }
111
112 return call && (typeof call === "object" || typeof call === "function") ? call : self;
113};
114
115
116
117
118
119var slicedToArray = function () {
120 function sliceIterator(arr, i) {
121 var _arr = [];
122 var _n = true;
123 var _d = false;
124 var _e = undefined;
125
126 try {
127 for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {
128 _arr.push(_s.value);
129
130 if (i && _arr.length === i) break;
131 }
132 } catch (err) {
133 _d = true;
134 _e = err;
135 } finally {
136 try {
137 if (!_n && _i["return"]) _i["return"]();
138 } finally {
139 if (_d) throw _e;
140 }
141 }
142
143 return _arr;
144 }
145
146 return function (arr, i) {
147 if (Array.isArray(arr)) {
148 return arr;
149 } else if (Symbol.iterator in Object(arr)) {
150 return sliceIterator(arr, i);
151 } else {
152 throw new TypeError("Invalid attempt to destructure non-iterable instance");
153 }
154 };
155}();
156
157var Processor = function () {
158 function Processor(options) {
159 classCallCheck(this, Processor);
160
161 this.selfOptions = options || {};
162 this.pipes = {};
163 }
164
165 createClass(Processor, [{
166 key: 'options',
167 value: function options(_options) {
168 if (_options) {
169 this.selfOptions = _options;
170 }
171 return this.selfOptions;
172 }
173 }, {
174 key: 'pipe',
175 value: function pipe(name, pipeArg) {
176 var pipe = pipeArg;
177 if (typeof name === 'string') {
178 if (typeof pipe === 'undefined') {
179 return this.pipes[name];
180 } else {
181 this.pipes[name] = pipe;
182 }
183 }
184 if (name && name.name) {
185 pipe = name;
186 if (pipe.processor === this) {
187 return pipe;
188 }
189 this.pipes[pipe.name] = pipe;
190 }
191 pipe.processor = this;
192 return pipe;
193 }
194 }, {
195 key: 'process',
196 value: function process(input, pipe) {
197 var context = input;
198 context.options = this.options();
199 var nextPipe = pipe || input.pipe || 'default';
200 var lastPipe = void 0;
201 var lastContext = void 0;
202 while (nextPipe) {
203 if (typeof context.nextAfterChildren !== 'undefined') {
204 // children processed and coming back to parent
205 context.next = context.nextAfterChildren;
206 context.nextAfterChildren = null;
207 }
208
209 if (typeof nextPipe === 'string') {
210 nextPipe = this.pipe(nextPipe);
211 }
212 nextPipe.process(context);
213 lastContext = context;
214 lastPipe = nextPipe;
215 nextPipe = null;
216 if (context) {
217 if (context.next) {
218 context = context.next;
219 nextPipe = lastContext.nextPipe || context.pipe || lastPipe;
220 }
221 }
222 }
223 return context.hasResult ? context.result : undefined;
224 }
225 }]);
226 return Processor;
227}();
228
229var Pipe = function () {
230 function Pipe(name) {
231 classCallCheck(this, Pipe);
232
233 this.name = name;
234 this.filters = [];
235 }
236
237 createClass(Pipe, [{
238 key: 'process',
239 value: function process(input) {
240 if (!this.processor) {
241 throw new Error('add this pipe to a processor before using it');
242 }
243 var debug = this.debug;
244 var length = this.filters.length;
245 var context = input;
246 for (var index = 0; index < length; index++) {
247 var filter = this.filters[index];
248 if (debug) {
249 this.log('filter: ' + filter.filterName);
250 }
251 filter(context);
252 if ((typeof context === 'undefined' ? 'undefined' : _typeof(context)) === 'object' && context.exiting) {
253 context.exiting = false;
254 break;
255 }
256 }
257 if (!context.next && this.resultCheck) {
258 this.resultCheck(context);
259 }
260 }
261 }, {
262 key: 'log',
263 value: function log(msg) {
264 console.log('[jsondiffpatch] ' + this.name + ' pipe, ' + msg);
265 }
266 }, {
267 key: 'append',
268 value: function append() {
269 var _filters;
270
271 (_filters = this.filters).push.apply(_filters, arguments);
272 return this;
273 }
274 }, {
275 key: 'prepend',
276 value: function prepend() {
277 var _filters2;
278
279 (_filters2 = this.filters).unshift.apply(_filters2, arguments);
280 return this;
281 }
282 }, {
283 key: 'indexOf',
284 value: function indexOf(filterName) {
285 if (!filterName) {
286 throw new Error('a filter name is required');
287 }
288 for (var index = 0; index < this.filters.length; index++) {
289 var filter = this.filters[index];
290 if (filter.filterName === filterName) {
291 return index;
292 }
293 }
294 throw new Error('filter not found: ' + filterName);
295 }
296 }, {
297 key: 'list',
298 value: function list() {
299 var names = [];
300
301 var _iteratorNormalCompletion = true;
302 var _didIteratorError = false;
303 var _iteratorError = undefined;
304
305 try {
306 for (var _iterator = this.filters[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
307 var filter = _step.value;
308
309 names.push(filter.filterName);
310 }
311 } catch (err) {
312 _didIteratorError = true;
313 _iteratorError = err;
314 } finally {
315 try {
316 if (!_iteratorNormalCompletion && _iterator.return) {
317 _iterator.return();
318 }
319 } finally {
320 if (_didIteratorError) {
321 throw _iteratorError;
322 }
323 }
324 }
325
326 return names;
327 }
328 }, {
329 key: 'after',
330 value: function after(filterName) {
331 var index = this.indexOf(filterName);
332 var params = Array.prototype.slice.call(arguments, 1);
333 if (!params.length) {
334 throw new Error('a filter is required');
335 }
336 params.unshift(index + 1, 0);
337 Array.prototype.splice.apply(this.filters, params);
338 return this;
339 }
340 }, {
341 key: 'before',
342 value: function before(filterName) {
343 var index = this.indexOf(filterName);
344 var params = Array.prototype.slice.call(arguments, 1);
345 if (!params.length) {
346 throw new Error('a filter is required');
347 }
348 params.unshift(index, 0);
349 Array.prototype.splice.apply(this.filters, params);
350 return this;
351 }
352 }, {
353 key: 'replace',
354 value: function replace(filterName) {
355 var index = this.indexOf(filterName);
356 var params = Array.prototype.slice.call(arguments, 1);
357 if (!params.length) {
358 throw new Error('a filter is required');
359 }
360 params.unshift(index, 1);
361 Array.prototype.splice.apply(this.filters, params);
362 return this;
363 }
364 }, {
365 key: 'remove',
366 value: function remove(filterName) {
367 var index = this.indexOf(filterName);
368 this.filters.splice(index, 1);
369 return this;
370 }
371 }, {
372 key: 'clear',
373 value: function clear() {
374 this.filters.length = 0;
375 return this;
376 }
377 }, {
378 key: 'shouldHaveResult',
379 value: function shouldHaveResult(should) {
380 if (should === false) {
381 this.resultCheck = null;
382 return;
383 }
384 if (this.resultCheck) {
385 return;
386 }
387 var pipe = this;
388 this.resultCheck = function (context) {
389 if (!context.hasResult) {
390 console.log(context);
391 var error = new Error(pipe.name + ' failed');
392 error.noResult = true;
393 throw error;
394 }
395 };
396 return this;
397 }
398 }]);
399 return Pipe;
400}();
401
402var Context = function () {
403 function Context() {
404 classCallCheck(this, Context);
405 }
406
407 createClass(Context, [{
408 key: 'setResult',
409 value: function setResult(result) {
410 this.result = result;
411 this.hasResult = true;
412 return this;
413 }
414 }, {
415 key: 'exit',
416 value: function exit() {
417 this.exiting = true;
418 return this;
419 }
420 }, {
421 key: 'switchTo',
422 value: function switchTo(next, pipe) {
423 if (typeof next === 'string' || next instanceof Pipe) {
424 this.nextPipe = next;
425 } else {
426 this.next = next;
427 if (pipe) {
428 this.nextPipe = pipe;
429 }
430 }
431 return this;
432 }
433 }, {
434 key: 'push',
435 value: function push(child, name) {
436 child.parent = this;
437 if (typeof name !== 'undefined') {
438 child.childName = name;
439 }
440 child.root = this.root || this;
441 child.options = child.options || this.options;
442 if (!this.children) {
443 this.children = [child];
444 this.nextAfterChildren = this.next || null;
445 this.next = child;
446 } else {
447 this.children[this.children.length - 1].next = child;
448 this.children.push(child);
449 }
450 child.next = this;
451 return this;
452 }
453 }]);
454 return Context;
455}();
456
457var isArray = typeof Array.isArray === 'function' ? Array.isArray : function (a) {
458 return a instanceof Array;
459};
460
461function cloneRegExp(re) {
462 var regexMatch = /^\/(.*)\/([gimyu]*)$/.exec(re.toString());
463 return new RegExp(regexMatch[1], regexMatch[2]);
464}
465
466function clone(arg) {
467 if ((typeof arg === 'undefined' ? 'undefined' : _typeof(arg)) !== 'object') {
468 return arg;
469 }
470 if (arg === null) {
471 return null;
472 }
473 if (isArray(arg)) {
474 return arg.map(clone);
475 }
476 if (arg instanceof Date) {
477 return new Date(arg.getTime());
478 }
479 if (arg instanceof RegExp) {
480 return cloneRegExp(arg);
481 }
482 var cloned = {};
483 for (var name in arg) {
484 if (Object.prototype.hasOwnProperty.call(arg, name)) {
485 cloned[name] = clone(arg[name]);
486 }
487 }
488 return cloned;
489}
490
491var DiffContext = function (_Context) {
492 inherits(DiffContext, _Context);
493
494 function DiffContext(left, right) {
495 classCallCheck(this, DiffContext);
496
497 var _this = possibleConstructorReturn(this, (DiffContext.__proto__ || Object.getPrototypeOf(DiffContext)).call(this));
498
499 _this.left = left;
500 _this.right = right;
501 _this.pipe = 'diff';
502 return _this;
503 }
504
505 createClass(DiffContext, [{
506 key: 'setResult',
507 value: function setResult(result) {
508 if (this.options.cloneDiffValues && (typeof result === 'undefined' ? 'undefined' : _typeof(result)) === 'object') {
509 var clone$$1 = typeof this.options.cloneDiffValues === 'function' ? this.options.cloneDiffValues : clone;
510 if (_typeof(result[0]) === 'object') {
511 result[0] = clone$$1(result[0]);
512 }
513 if (_typeof(result[1]) === 'object') {
514 result[1] = clone$$1(result[1]);
515 }
516 }
517 return Context.prototype.setResult.apply(this, arguments);
518 }
519 }]);
520 return DiffContext;
521}(Context);
522
523var PatchContext = function (_Context) {
524 inherits(PatchContext, _Context);
525
526 function PatchContext(left, delta) {
527 classCallCheck(this, PatchContext);
528
529 var _this = possibleConstructorReturn(this, (PatchContext.__proto__ || Object.getPrototypeOf(PatchContext)).call(this));
530
531 _this.left = left;
532 _this.delta = delta;
533 _this.pipe = 'patch';
534 return _this;
535 }
536
537 return PatchContext;
538}(Context);
539
540var ReverseContext = function (_Context) {
541 inherits(ReverseContext, _Context);
542
543 function ReverseContext(delta) {
544 classCallCheck(this, ReverseContext);
545
546 var _this = possibleConstructorReturn(this, (ReverseContext.__proto__ || Object.getPrototypeOf(ReverseContext)).call(this));
547
548 _this.delta = delta;
549 _this.pipe = 'reverse';
550 return _this;
551 }
552
553 return ReverseContext;
554}(Context);
555
556var isArray$1 = typeof Array.isArray === 'function' ? Array.isArray : function (a) {
557 return a instanceof Array;
558};
559
560var diffFilter = function trivialMatchesDiffFilter(context) {
561 if (context.left === context.right) {
562 context.setResult(undefined).exit();
563 return;
564 }
565 if (typeof context.left === 'undefined') {
566 if (typeof context.right === 'function') {
567 throw new Error('functions are not supported');
568 }
569 context.setResult([context.right]).exit();
570 return;
571 }
572 if (typeof context.right === 'undefined') {
573 context.setResult([context.left, 0, 0]).exit();
574 return;
575 }
576 if (typeof context.left === 'function' || typeof context.right === 'function') {
577 throw new Error('functions are not supported');
578 }
579 context.leftType = context.left === null ? 'null' : _typeof(context.left);
580 context.rightType = context.right === null ? 'null' : _typeof(context.right);
581 if (context.leftType !== context.rightType) {
582 context.setResult([context.left, context.right]).exit();
583 return;
584 }
585 if (context.leftType === 'boolean' || context.leftType === 'number') {
586 context.setResult([context.left, context.right]).exit();
587 return;
588 }
589 if (context.leftType === 'object') {
590 context.leftIsArray = isArray$1(context.left);
591 }
592 if (context.rightType === 'object') {
593 context.rightIsArray = isArray$1(context.right);
594 }
595 if (context.leftIsArray !== context.rightIsArray) {
596 context.setResult([context.left, context.right]).exit();
597 return;
598 }
599
600 if (context.left instanceof RegExp) {
601 if (context.right instanceof RegExp) {
602 context.setResult([context.left.toString(), context.right.toString()]).exit();
603 } else {
604 context.setResult([context.left, context.right]).exit();
605 }
606 }
607};
608diffFilter.filterName = 'trivial';
609
610var patchFilter = function trivialMatchesPatchFilter(context) {
611 if (typeof context.delta === 'undefined') {
612 context.setResult(context.left).exit();
613 return;
614 }
615 context.nested = !isArray$1(context.delta);
616 if (context.nested) {
617 return;
618 }
619 if (context.delta.length === 1) {
620 context.setResult(context.delta[0]).exit();
621 return;
622 }
623 if (context.delta.length === 2) {
624 if (context.left instanceof RegExp) {
625 var regexArgs = /^\/(.*)\/([gimyu]+)$/.exec(context.delta[1]);
626 if (regexArgs) {
627 context.setResult(new RegExp(regexArgs[1], regexArgs[2])).exit();
628 return;
629 }
630 }
631 context.setResult(context.delta[1]).exit();
632 return;
633 }
634 if (context.delta.length === 3 && context.delta[2] === 0) {
635 context.setResult(undefined).exit();
636 }
637};
638patchFilter.filterName = 'trivial';
639
640var reverseFilter = function trivialReferseFilter(context) {
641 if (typeof context.delta === 'undefined') {
642 context.setResult(context.delta).exit();
643 return;
644 }
645 context.nested = !isArray$1(context.delta);
646 if (context.nested) {
647 return;
648 }
649 if (context.delta.length === 1) {
650 context.setResult([context.delta[0], 0, 0]).exit();
651 return;
652 }
653 if (context.delta.length === 2) {
654 context.setResult([context.delta[1], context.delta[0]]).exit();
655 return;
656 }
657 if (context.delta.length === 3 && context.delta[2] === 0) {
658 context.setResult([context.delta[0]]).exit();
659 }
660};
661reverseFilter.filterName = 'trivial';
662
663function collectChildrenDiffFilter(context) {
664 if (!context || !context.children) {
665 return;
666 }
667 var length = context.children.length;
668 var child = void 0;
669 var result = context.result;
670 for (var index = 0; index < length; index++) {
671 child = context.children[index];
672 if (typeof child.result === 'undefined') {
673 continue;
674 }
675 result = result || {};
676 result[child.childName] = child.result;
677 }
678 if (result && context.leftIsArray) {
679 result._t = 'a';
680 }
681 context.setResult(result).exit();
682}
683collectChildrenDiffFilter.filterName = 'collectChildren';
684
685function objectsDiffFilter(context) {
686 if (context.leftIsArray || context.leftType !== 'object') {
687 return;
688 }
689
690 var name = void 0;
691 var child = void 0;
692 var propertyFilter = context.options.propertyFilter;
693 for (name in context.left) {
694 if (!Object.prototype.hasOwnProperty.call(context.left, name)) {
695 continue;
696 }
697 if (propertyFilter && !propertyFilter(name, context)) {
698 continue;
699 }
700 child = new DiffContext(context.left[name], context.right[name]);
701 context.push(child, name);
702 }
703 for (name in context.right) {
704 if (!Object.prototype.hasOwnProperty.call(context.right, name)) {
705 continue;
706 }
707 if (propertyFilter && !propertyFilter(name, context)) {
708 continue;
709 }
710 if (typeof context.left[name] === 'undefined') {
711 child = new DiffContext(undefined, context.right[name]);
712 context.push(child, name);
713 }
714 }
715
716 if (!context.children || context.children.length === 0) {
717 context.setResult(undefined).exit();
718 return;
719 }
720 context.exit();
721}
722objectsDiffFilter.filterName = 'objects';
723
724var patchFilter$1 = function nestedPatchFilter(context) {
725 if (!context.nested) {
726 return;
727 }
728 if (context.delta._t) {
729 return;
730 }
731 var name = void 0;
732 var child = void 0;
733 for (name in context.delta) {
734 child = new PatchContext(context.left[name], context.delta[name]);
735 context.push(child, name);
736 }
737 context.exit();
738};
739patchFilter$1.filterName = 'objects';
740
741var collectChildrenPatchFilter = function collectChildrenPatchFilter(context) {
742 if (!context || !context.children) {
743 return;
744 }
745 if (context.delta._t) {
746 return;
747 }
748 var length = context.children.length;
749 var child = void 0;
750 for (var index = 0; index < length; index++) {
751 child = context.children[index];
752 if (Object.prototype.hasOwnProperty.call(context.left, child.childName) && child.result === undefined) {
753 delete context.left[child.childName];
754 } else if (context.left[child.childName] !== child.result) {
755 context.left[child.childName] = child.result;
756 }
757 }
758 context.setResult(context.left).exit();
759};
760collectChildrenPatchFilter.filterName = 'collectChildren';
761
762var reverseFilter$1 = function nestedReverseFilter(context) {
763 if (!context.nested) {
764 return;
765 }
766 if (context.delta._t) {
767 return;
768 }
769 var name = void 0;
770 var child = void 0;
771 for (name in context.delta) {
772 child = new ReverseContext(context.delta[name]);
773 context.push(child, name);
774 }
775 context.exit();
776};
777reverseFilter$1.filterName = 'objects';
778
779function collectChildrenReverseFilter(context) {
780 if (!context || !context.children) {
781 return;
782 }
783 if (context.delta._t) {
784 return;
785 }
786 var length = context.children.length;
787 var child = void 0;
788 var delta = {};
789 for (var index = 0; index < length; index++) {
790 child = context.children[index];
791 if (delta[child.childName] !== child.result) {
792 delta[child.childName] = child.result;
793 }
794 }
795 context.setResult(delta).exit();
796}
797collectChildrenReverseFilter.filterName = 'collectChildren';
798
799/*
800
801LCS implementation that supports arrays or strings
802
803reference: http://en.wikipedia.org/wiki/Longest_common_subsequence_problem
804
805*/
806
807var defaultMatch = function defaultMatch(array1, array2, index1, index2) {
808 return array1[index1] === array2[index2];
809};
810
811var lengthMatrix = function lengthMatrix(array1, array2, match, context) {
812 var len1 = array1.length;
813 var len2 = array2.length;
814 var x = void 0,
815 y = void 0;
816
817 // initialize empty matrix of len1+1 x len2+1
818 var matrix = [len1 + 1];
819 for (x = 0; x < len1 + 1; x++) {
820 matrix[x] = [len2 + 1];
821 for (y = 0; y < len2 + 1; y++) {
822 matrix[x][y] = 0;
823 }
824 }
825 matrix.match = match;
826 // save sequence lengths for each coordinate
827 for (x = 1; x < len1 + 1; x++) {
828 for (y = 1; y < len2 + 1; y++) {
829 if (match(array1, array2, x - 1, y - 1, context)) {
830 matrix[x][y] = matrix[x - 1][y - 1] + 1;
831 } else {
832 matrix[x][y] = Math.max(matrix[x - 1][y], matrix[x][y - 1]);
833 }
834 }
835 }
836 return matrix;
837};
838
839var backtrack = function backtrack(matrix, array1, array2, index1, index2, context) {
840 if (index1 === 0 || index2 === 0) {
841 return {
842 sequence: [],
843 indices1: [],
844 indices2: []
845 };
846 }
847
848 if (matrix.match(array1, array2, index1 - 1, index2 - 1, context)) {
849 var subsequence = backtrack(matrix, array1, array2, index1 - 1, index2 - 1, context);
850 subsequence.sequence.push(array1[index1 - 1]);
851 subsequence.indices1.push(index1 - 1);
852 subsequence.indices2.push(index2 - 1);
853 return subsequence;
854 }
855
856 if (matrix[index1][index2 - 1] > matrix[index1 - 1][index2]) {
857 return backtrack(matrix, array1, array2, index1, index2 - 1, context);
858 } else {
859 return backtrack(matrix, array1, array2, index1 - 1, index2, context);
860 }
861};
862
863var get$1 = function get(array1, array2, match, context) {
864 var innerContext = context || {};
865 var matrix = lengthMatrix(array1, array2, match || defaultMatch, innerContext);
866 var result = backtrack(matrix, array1, array2, array1.length, array2.length, innerContext);
867 if (typeof array1 === 'string' && typeof array2 === 'string') {
868 result.sequence = result.sequence.join('');
869 }
870 return result;
871};
872
873var lcs = {
874 get: get$1
875};
876
877var ARRAY_MOVE = 3;
878
879var isArray$2 = typeof Array.isArray === 'function' ? Array.isArray : function (a) {
880 return a instanceof Array;
881};
882
883var arrayIndexOf = typeof Array.prototype.indexOf === 'function' ? function (array, item) {
884 return array.indexOf(item);
885} : function (array, item) {
886 var length = array.length;
887 for (var i = 0; i < length; i++) {
888 if (array[i] === item) {
889 return i;
890 }
891 }
892 return -1;
893};
894
895function arraysHaveMatchByRef(array1, array2, len1, len2) {
896 for (var index1 = 0; index1 < len1; index1++) {
897 var val1 = array1[index1];
898 for (var index2 = 0; index2 < len2; index2++) {
899 var val2 = array2[index2];
900 if (index1 !== index2 && val1 === val2) {
901 return true;
902 }
903 }
904 }
905}
906
907function matchItems(array1, array2, index1, index2, context) {
908 var value1 = array1[index1];
909 var value2 = array2[index2];
910 if (value1 === value2) {
911 return true;
912 }
913 if ((typeof value1 === 'undefined' ? 'undefined' : _typeof(value1)) !== 'object' || (typeof value2 === 'undefined' ? 'undefined' : _typeof(value2)) !== 'object') {
914 return false;
915 }
916 var objectHash = context.objectHash;
917 if (!objectHash) {
918 // no way to match objects was provided, try match by position
919 return context.matchByPosition && index1 === index2;
920 }
921 var hash1 = void 0;
922 var hash2 = void 0;
923 if (typeof index1 === 'number') {
924 context.hashCache1 = context.hashCache1 || [];
925 hash1 = context.hashCache1[index1];
926 if (typeof hash1 === 'undefined') {
927 context.hashCache1[index1] = hash1 = objectHash(value1, index1);
928 }
929 } else {
930 hash1 = objectHash(value1);
931 }
932 if (typeof hash1 === 'undefined') {
933 return false;
934 }
935 if (typeof index2 === 'number') {
936 context.hashCache2 = context.hashCache2 || [];
937 hash2 = context.hashCache2[index2];
938 if (typeof hash2 === 'undefined') {
939 context.hashCache2[index2] = hash2 = objectHash(value2, index2);
940 }
941 } else {
942 hash2 = objectHash(value2);
943 }
944 if (typeof hash2 === 'undefined') {
945 return false;
946 }
947 return hash1 === hash2;
948}
949
950var diffFilter$1 = function arraysDiffFilter(context) {
951 if (!context.leftIsArray) {
952 return;
953 }
954
955 var matchContext = {
956 objectHash: context.options && context.options.objectHash,
957 matchByPosition: context.options && context.options.matchByPosition
958 };
959 var commonHead = 0;
960 var commonTail = 0;
961 var index = void 0;
962 var index1 = void 0;
963 var index2 = void 0;
964 var array1 = context.left;
965 var array2 = context.right;
966 var len1 = array1.length;
967 var len2 = array2.length;
968
969 var child = void 0;
970
971 if (len1 > 0 && len2 > 0 && !matchContext.objectHash && typeof matchContext.matchByPosition !== 'boolean') {
972 matchContext.matchByPosition = !arraysHaveMatchByRef(array1, array2, len1, len2);
973 }
974
975 // separate common head
976 while (commonHead < len1 && commonHead < len2 && matchItems(array1, array2, commonHead, commonHead, matchContext)) {
977 index = commonHead;
978 child = new DiffContext(context.left[index], context.right[index]);
979 context.push(child, index);
980 commonHead++;
981 }
982 // separate common tail
983 while (commonTail + commonHead < len1 && commonTail + commonHead < len2 && matchItems(array1, array2, len1 - 1 - commonTail, len2 - 1 - commonTail, matchContext)) {
984 index1 = len1 - 1 - commonTail;
985 index2 = len2 - 1 - commonTail;
986 child = new DiffContext(context.left[index1], context.right[index2]);
987 context.push(child, index2);
988 commonTail++;
989 }
990 var result = void 0;
991 if (commonHead + commonTail === len1) {
992 if (len1 === len2) {
993 // arrays are identical
994 context.setResult(undefined).exit();
995 return;
996 }
997 // trivial case, a block (1 or more consecutive items) was added
998 result = result || {
999 _t: 'a'
1000 };
1001 for (index = commonHead; index < len2 - commonTail; index++) {
1002 result[index] = [array2[index]];
1003 }
1004 context.setResult(result).exit();
1005 return;
1006 }
1007 if (commonHead + commonTail === len2) {
1008 // trivial case, a block (1 or more consecutive items) was removed
1009 result = result || {
1010 _t: 'a'
1011 };
1012 for (index = commonHead; index < len1 - commonTail; index++) {
1013 result['_' + index] = [array1[index], 0, 0];
1014 }
1015 context.setResult(result).exit();
1016 return;
1017 }
1018 // reset hash cache
1019 delete matchContext.hashCache1;
1020 delete matchContext.hashCache2;
1021
1022 // diff is not trivial, find the LCS (Longest Common Subsequence)
1023 var trimmed1 = array1.slice(commonHead, len1 - commonTail);
1024 var trimmed2 = array2.slice(commonHead, len2 - commonTail);
1025 var seq = lcs.get(trimmed1, trimmed2, matchItems, matchContext);
1026 var removedItems = [];
1027 result = result || {
1028 _t: 'a'
1029 };
1030 for (index = commonHead; index < len1 - commonTail; index++) {
1031 if (arrayIndexOf(seq.indices1, index - commonHead) < 0) {
1032 // removed
1033 result['_' + index] = [array1[index], 0, 0];
1034 removedItems.push(index);
1035 }
1036 }
1037
1038 var detectMove = true;
1039 if (context.options && context.options.arrays && context.options.arrays.detectMove === false) {
1040 detectMove = false;
1041 }
1042 var includeValueOnMove = false;
1043 if (context.options && context.options.arrays && context.options.arrays.includeValueOnMove) {
1044 includeValueOnMove = true;
1045 }
1046
1047 var removedItemsLength = removedItems.length;
1048 for (index = commonHead; index < len2 - commonTail; index++) {
1049 var indexOnArray2 = arrayIndexOf(seq.indices2, index - commonHead);
1050 if (indexOnArray2 < 0) {
1051 // added, try to match with a removed item and register as position move
1052 var isMove = false;
1053 if (detectMove && removedItemsLength > 0) {
1054 for (var removeItemIndex1 = 0; removeItemIndex1 < removedItemsLength; removeItemIndex1++) {
1055 index1 = removedItems[removeItemIndex1];
1056 if (matchItems(trimmed1, trimmed2, index1 - commonHead, index - commonHead, matchContext)) {
1057 // store position move as: [originalValue, newPosition, ARRAY_MOVE]
1058 result['_' + index1].splice(1, 2, index, ARRAY_MOVE);
1059 if (!includeValueOnMove) {
1060 // don't include moved value on diff, to save bytes
1061 result['_' + index1][0] = '';
1062 }
1063
1064 index2 = index;
1065 child = new DiffContext(context.left[index1], context.right[index2]);
1066 context.push(child, index2);
1067 removedItems.splice(removeItemIndex1, 1);
1068 isMove = true;
1069 break;
1070 }
1071 }
1072 }
1073 if (!isMove) {
1074 // added
1075 result[index] = [array2[index]];
1076 }
1077 } else {
1078 // match, do inner diff
1079 index1 = seq.indices1[indexOnArray2] + commonHead;
1080 index2 = seq.indices2[indexOnArray2] + commonHead;
1081 child = new DiffContext(context.left[index1], context.right[index2]);
1082 context.push(child, index2);
1083 }
1084 }
1085
1086 context.setResult(result).exit();
1087};
1088diffFilter$1.filterName = 'arrays';
1089
1090var compare = {
1091 numerically: function numerically(a, b) {
1092 return a - b;
1093 },
1094 numericallyBy: function numericallyBy(name) {
1095 return function (a, b) {
1096 return a[name] - b[name];
1097 };
1098 }
1099};
1100
1101var patchFilter$2 = function nestedPatchFilter(context) {
1102 if (!context.nested) {
1103 return;
1104 }
1105 if (context.delta._t !== 'a') {
1106 return;
1107 }
1108 var index = void 0;
1109 var index1 = void 0;
1110
1111 var delta = context.delta;
1112 var array = context.left;
1113
1114 // first, separate removals, insertions and modifications
1115 var toRemove = [];
1116 var toInsert = [];
1117 var toModify = [];
1118 for (index in delta) {
1119 if (index !== '_t') {
1120 if (index[0] === '_') {
1121 // removed item from original array
1122 if (delta[index][2] === 0 || delta[index][2] === ARRAY_MOVE) {
1123 toRemove.push(parseInt(index.slice(1), 10));
1124 } else {
1125 throw new Error('only removal or move can be applied at original array indices,' + (' invalid diff type: ' + delta[index][2]));
1126 }
1127 } else {
1128 if (delta[index].length === 1) {
1129 // added item at new array
1130 toInsert.push({
1131 index: parseInt(index, 10),
1132 value: delta[index][0]
1133 });
1134 } else {
1135 // modified item at new array
1136 toModify.push({
1137 index: parseInt(index, 10),
1138 delta: delta[index]
1139 });
1140 }
1141 }
1142 }
1143 }
1144
1145 // remove items, in reverse order to avoid sawing our own floor
1146 toRemove = toRemove.sort(compare.numerically);
1147 for (index = toRemove.length - 1; index >= 0; index--) {
1148 index1 = toRemove[index];
1149 var indexDiff = delta['_' + index1];
1150 var removedValue = array.splice(index1, 1)[0];
1151 if (indexDiff[2] === ARRAY_MOVE) {
1152 // reinsert later
1153 toInsert.push({
1154 index: indexDiff[1],
1155 value: removedValue
1156 });
1157 }
1158 }
1159
1160 // insert items, in reverse order to avoid moving our own floor
1161 toInsert = toInsert.sort(compare.numericallyBy('index'));
1162 var toInsertLength = toInsert.length;
1163 for (index = 0; index < toInsertLength; index++) {
1164 var insertion = toInsert[index];
1165 array.splice(insertion.index, 0, insertion.value);
1166 }
1167
1168 // apply modifications
1169 var toModifyLength = toModify.length;
1170 var child = void 0;
1171 if (toModifyLength > 0) {
1172 for (index = 0; index < toModifyLength; index++) {
1173 var modification = toModify[index];
1174 child = new PatchContext(context.left[modification.index], modification.delta);
1175 context.push(child, modification.index);
1176 }
1177 }
1178
1179 if (!context.children) {
1180 context.setResult(context.left).exit();
1181 return;
1182 }
1183 context.exit();
1184};
1185patchFilter$2.filterName = 'arrays';
1186
1187var collectChildrenPatchFilter$1 = function collectChildrenPatchFilter(context) {
1188 if (!context || !context.children) {
1189 return;
1190 }
1191 if (context.delta._t !== 'a') {
1192 return;
1193 }
1194 var length = context.children.length;
1195 var child = void 0;
1196 for (var index = 0; index < length; index++) {
1197 child = context.children[index];
1198 context.left[child.childName] = child.result;
1199 }
1200 context.setResult(context.left).exit();
1201};
1202collectChildrenPatchFilter$1.filterName = 'arraysCollectChildren';
1203
1204var reverseFilter$2 = function arraysReverseFilter(context) {
1205 if (!context.nested) {
1206 if (context.delta[2] === ARRAY_MOVE) {
1207 context.newName = '_' + context.delta[1];
1208 context.setResult([context.delta[0], parseInt(context.childName.substr(1), 10), ARRAY_MOVE]).exit();
1209 }
1210 return;
1211 }
1212 if (context.delta._t !== 'a') {
1213 return;
1214 }
1215 var name = void 0;
1216 var child = void 0;
1217 for (name in context.delta) {
1218 if (name === '_t') {
1219 continue;
1220 }
1221 child = new ReverseContext(context.delta[name]);
1222 context.push(child, name);
1223 }
1224 context.exit();
1225};
1226reverseFilter$2.filterName = 'arrays';
1227
1228var reverseArrayDeltaIndex = function reverseArrayDeltaIndex(delta, index, itemDelta) {
1229 if (typeof index === 'string' && index[0] === '_') {
1230 return parseInt(index.substr(1), 10);
1231 } else if (isArray$2(itemDelta) && itemDelta[2] === 0) {
1232 return '_' + index;
1233 }
1234
1235 var reverseIndex = +index;
1236 for (var deltaIndex in delta) {
1237 var deltaItem = delta[deltaIndex];
1238 if (isArray$2(deltaItem)) {
1239 if (deltaItem[2] === ARRAY_MOVE) {
1240 var moveFromIndex = parseInt(deltaIndex.substr(1), 10);
1241 var moveToIndex = deltaItem[1];
1242 if (moveToIndex === +index) {
1243 return moveFromIndex;
1244 }
1245 if (moveFromIndex <= reverseIndex && moveToIndex > reverseIndex) {
1246 reverseIndex++;
1247 } else if (moveFromIndex >= reverseIndex && moveToIndex < reverseIndex) {
1248 reverseIndex--;
1249 }
1250 } else if (deltaItem[2] === 0) {
1251 var deleteIndex = parseInt(deltaIndex.substr(1), 10);
1252 if (deleteIndex <= reverseIndex) {
1253 reverseIndex++;
1254 }
1255 } else if (deltaItem.length === 1 && deltaIndex <= reverseIndex) {
1256 reverseIndex--;
1257 }
1258 }
1259 }
1260
1261 return reverseIndex;
1262};
1263
1264function collectChildrenReverseFilter$1(context) {
1265 if (!context || !context.children) {
1266 return;
1267 }
1268 if (context.delta._t !== 'a') {
1269 return;
1270 }
1271 var length = context.children.length;
1272 var child = void 0;
1273 var delta = {
1274 _t: 'a'
1275 };
1276
1277 for (var index = 0; index < length; index++) {
1278 child = context.children[index];
1279 var name = child.newName;
1280 if (typeof name === 'undefined') {
1281 name = reverseArrayDeltaIndex(context.delta, child.childName, child.result);
1282 }
1283 if (delta[name] !== child.result) {
1284 delta[name] = child.result;
1285 }
1286 }
1287 context.setResult(delta).exit();
1288}
1289collectChildrenReverseFilter$1.filterName = 'arraysCollectChildren';
1290
1291var diffFilter$2 = function datesDiffFilter(context) {
1292 if (context.left instanceof Date) {
1293 if (context.right instanceof Date) {
1294 if (context.left.getTime() !== context.right.getTime()) {
1295 context.setResult([context.left, context.right]);
1296 } else {
1297 context.setResult(undefined);
1298 }
1299 } else {
1300 context.setResult([context.left, context.right]);
1301 }
1302 context.exit();
1303 } else if (context.right instanceof Date) {
1304 context.setResult([context.left, context.right]).exit();
1305 }
1306};
1307diffFilter$2.filterName = 'dates';
1308
1309/* global diff_match_patch */
1310var TEXT_DIFF = 2;
1311var DEFAULT_MIN_LENGTH = 60;
1312var cachedDiffPatch = null;
1313
1314var getDiffMatchPatch = function getDiffMatchPatch(required) {
1315 /* jshint camelcase: false */
1316
1317 if (!cachedDiffPatch) {
1318 var instance = void 0;
1319 /* eslint-disable camelcase, new-cap */
1320 if (typeof diff_match_patch !== 'undefined') {
1321 // already loaded, probably a browser
1322 instance = typeof diff_match_patch === 'function' ? new diff_match_patch() : new diff_match_patch.diff_match_patch();
1323 } else if (dmp) {
1324 try {
1325 instance = dmp && new dmp();
1326 } catch (err) {
1327 instance = null;
1328 }
1329 }
1330 /* eslint-enable camelcase, new-cap */
1331 if (!instance) {
1332 if (!required) {
1333 return null;
1334 }
1335 var error = new Error('text diff_match_patch library not found');
1336 // eslint-disable-next-line camelcase
1337 error.diff_match_patch_not_found = true;
1338 throw error;
1339 }
1340 cachedDiffPatch = {
1341 diff: function diff(txt1, txt2) {
1342 return instance.patch_toText(instance.patch_make(txt1, txt2));
1343 },
1344 patch: function patch(txt1, _patch) {
1345 var results = instance.patch_apply(instance.patch_fromText(_patch), txt1);
1346 for (var i = 0; i < results[1].length; i++) {
1347 if (!results[1][i]) {
1348 var _error = new Error('text patch failed');
1349 _error.textPatchFailed = true;
1350 }
1351 }
1352 return results[0];
1353 }
1354 };
1355 }
1356 return cachedDiffPatch;
1357};
1358
1359var diffFilter$3 = function textsDiffFilter(context) {
1360 if (context.leftType !== 'string') {
1361 return;
1362 }
1363 var minLength = context.options && context.options.textDiff && context.options.textDiff.minLength || DEFAULT_MIN_LENGTH;
1364 if (context.left.length < minLength || context.right.length < minLength) {
1365 context.setResult([context.left, context.right]).exit();
1366 return;
1367 }
1368 // large text, try to use a text-diff algorithm
1369 var diffMatchPatch = getDiffMatchPatch();
1370 if (!diffMatchPatch) {
1371 // diff-match-patch library not available,
1372 // fallback to regular string replace
1373 context.setResult([context.left, context.right]).exit();
1374 return;
1375 }
1376 var diff = diffMatchPatch.diff;
1377 context.setResult([diff(context.left, context.right), 0, TEXT_DIFF]).exit();
1378};
1379diffFilter$3.filterName = 'texts';
1380
1381var patchFilter$3 = function textsPatchFilter(context) {
1382 if (context.nested) {
1383 return;
1384 }
1385 if (context.delta[2] !== TEXT_DIFF) {
1386 return;
1387 }
1388
1389 // text-diff, use a text-patch algorithm
1390 var patch = getDiffMatchPatch(true).patch;
1391 context.setResult(patch(context.left, context.delta[0])).exit();
1392};
1393patchFilter$3.filterName = 'texts';
1394
1395var textDeltaReverse = function textDeltaReverse(delta) {
1396 var i = void 0;
1397 var l = void 0;
1398 var lines = void 0;
1399 var line = void 0;
1400 var lineTmp = void 0;
1401 var header = null;
1402 var headerRegex = /^@@ +-(\d+),(\d+) +\+(\d+),(\d+) +@@$/;
1403 var lineHeader = void 0;
1404 lines = delta.split('\n');
1405 for (i = 0, l = lines.length; i < l; i++) {
1406 line = lines[i];
1407 var lineStart = line.slice(0, 1);
1408 if (lineStart === '@') {
1409 header = headerRegex.exec(line);
1410 lineHeader = i;
1411
1412 // fix header
1413 lines[lineHeader] = '@@ -' + header[3] + ',' + header[4] + ' +' + header[1] + ',' + header[2] + ' @@';
1414 } else if (lineStart === '+') {
1415 lines[i] = '-' + lines[i].slice(1);
1416 if (lines[i - 1].slice(0, 1) === '+') {
1417 // swap lines to keep default order (-+)
1418 lineTmp = lines[i];
1419 lines[i] = lines[i - 1];
1420 lines[i - 1] = lineTmp;
1421 }
1422 } else if (lineStart === '-') {
1423 lines[i] = '+' + lines[i].slice(1);
1424 }
1425 }
1426 return lines.join('\n');
1427};
1428
1429var reverseFilter$3 = function textsReverseFilter(context) {
1430 if (context.nested) {
1431 return;
1432 }
1433 if (context.delta[2] !== TEXT_DIFF) {
1434 return;
1435 }
1436
1437 // text-diff, use a text-diff algorithm
1438 context.setResult([textDeltaReverse(context.delta[0]), 0, TEXT_DIFF]).exit();
1439};
1440reverseFilter$3.filterName = 'texts';
1441
1442var DiffPatcher = function () {
1443 function DiffPatcher(options) {
1444 classCallCheck(this, DiffPatcher);
1445
1446 this.processor = new Processor(options);
1447 this.processor.pipe(new Pipe('diff').append(collectChildrenDiffFilter, diffFilter, diffFilter$2, diffFilter$3, objectsDiffFilter, diffFilter$1).shouldHaveResult());
1448 this.processor.pipe(new Pipe('patch').append(collectChildrenPatchFilter, collectChildrenPatchFilter$1, patchFilter, patchFilter$3, patchFilter$1, patchFilter$2).shouldHaveResult());
1449 this.processor.pipe(new Pipe('reverse').append(collectChildrenReverseFilter, collectChildrenReverseFilter$1, reverseFilter, reverseFilter$3, reverseFilter$1, reverseFilter$2).shouldHaveResult());
1450 }
1451
1452 createClass(DiffPatcher, [{
1453 key: 'options',
1454 value: function options() {
1455 var _processor;
1456
1457 return (_processor = this.processor).options.apply(_processor, arguments);
1458 }
1459 }, {
1460 key: 'diff',
1461 value: function diff(left, right) {
1462 return this.processor.process(new DiffContext(left, right));
1463 }
1464 }, {
1465 key: 'patch',
1466 value: function patch(left, delta) {
1467 return this.processor.process(new PatchContext(left, delta));
1468 }
1469 }, {
1470 key: 'reverse',
1471 value: function reverse(delta) {
1472 return this.processor.process(new ReverseContext(delta));
1473 }
1474 }, {
1475 key: 'unpatch',
1476 value: function unpatch(right, delta) {
1477 return this.patch(right, this.reverse(delta));
1478 }
1479 }, {
1480 key: 'clone',
1481 value: function clone$$1(value) {
1482 return clone(value);
1483 }
1484 }]);
1485 return DiffPatcher;
1486}();
1487
1488var isArray$3 = typeof Array.isArray === 'function' ? Array.isArray : function (a) {
1489 return a instanceof Array;
1490};
1491
1492var getObjectKeys = typeof Object.keys === 'function' ? function (obj) {
1493 return Object.keys(obj);
1494} : function (obj) {
1495 var names = [];
1496 for (var property in obj) {
1497 if (Object.prototype.hasOwnProperty.call(obj, property)) {
1498 names.push(property);
1499 }
1500 }
1501 return names;
1502};
1503
1504var trimUnderscore = function trimUnderscore(str) {
1505 if (str.substr(0, 1) === '_') {
1506 return str.slice(1);
1507 }
1508 return str;
1509};
1510
1511var arrayKeyToSortNumber = function arrayKeyToSortNumber(key) {
1512 if (key === '_t') {
1513 return -1;
1514 } else {
1515 if (key.substr(0, 1) === '_') {
1516 return parseInt(key.slice(1), 10);
1517 } else {
1518 return parseInt(key, 10) + 0.1;
1519 }
1520 }
1521};
1522
1523var arrayKeyComparer = function arrayKeyComparer(key1, key2) {
1524 return arrayKeyToSortNumber(key1) - arrayKeyToSortNumber(key2);
1525};
1526
1527var BaseFormatter = function () {
1528 function BaseFormatter() {
1529 classCallCheck(this, BaseFormatter);
1530 }
1531
1532 createClass(BaseFormatter, [{
1533 key: 'format',
1534 value: function format(delta, left) {
1535 var context = {};
1536 this.prepareContext(context);
1537 this.recurse(context, delta, left);
1538 return this.finalize(context);
1539 }
1540 }, {
1541 key: 'prepareContext',
1542 value: function prepareContext(context) {
1543 context.buffer = [];
1544 context.out = function () {
1545 var _buffer;
1546
1547 (_buffer = this.buffer).push.apply(_buffer, arguments);
1548 };
1549 }
1550 }, {
1551 key: 'typeFormattterNotFound',
1552 value: function typeFormattterNotFound(context, deltaType) {
1553 throw new Error('cannot format delta type: ' + deltaType);
1554 }
1555 }, {
1556 key: 'typeFormattterErrorFormatter',
1557 value: function typeFormattterErrorFormatter(context, err) {
1558 return err.toString();
1559 }
1560 }, {
1561 key: 'finalize',
1562 value: function finalize(_ref) {
1563 var buffer = _ref.buffer;
1564
1565 if (isArray$3(buffer)) {
1566 return buffer.join('');
1567 }
1568 }
1569 }, {
1570 key: 'recurse',
1571 value: function recurse(context, delta, left, key, leftKey, movedFrom, isLast) {
1572 var useMoveOriginHere = delta && movedFrom;
1573 var leftValue = useMoveOriginHere ? movedFrom.value : left;
1574
1575 if (typeof delta === 'undefined' && typeof key === 'undefined') {
1576 return undefined;
1577 }
1578
1579 var type = this.getDeltaType(delta, movedFrom);
1580 var nodeType = type === 'node' ? delta._t === 'a' ? 'array' : 'object' : '';
1581
1582 if (typeof key !== 'undefined') {
1583 this.nodeBegin(context, key, leftKey, type, nodeType, isLast);
1584 } else {
1585 this.rootBegin(context, type, nodeType);
1586 }
1587
1588 var typeFormattter = void 0;
1589 try {
1590 typeFormattter = this['format_' + type] || this.typeFormattterNotFound(context, type);
1591 typeFormattter.call(this, context, delta, leftValue, key, leftKey, movedFrom);
1592 } catch (err) {
1593 this.typeFormattterErrorFormatter(context, err, delta, leftValue, key, leftKey, movedFrom);
1594 if (typeof console !== 'undefined' && console.error) {
1595 console.error(err.stack);
1596 }
1597 }
1598
1599 if (typeof key !== 'undefined') {
1600 this.nodeEnd(context, key, leftKey, type, nodeType, isLast);
1601 } else {
1602 this.rootEnd(context, type, nodeType);
1603 }
1604 }
1605 }, {
1606 key: 'formatDeltaChildren',
1607 value: function formatDeltaChildren(context, delta, left) {
1608 var self = this;
1609 this.forEachDeltaKey(delta, left, function (key, leftKey, movedFrom, isLast) {
1610 self.recurse(context, delta[key], left ? left[leftKey] : undefined, key, leftKey, movedFrom, isLast);
1611 });
1612 }
1613 }, {
1614 key: 'forEachDeltaKey',
1615 value: function forEachDeltaKey(delta, left, fn) {
1616 var keys = getObjectKeys(delta);
1617 var arrayKeys = delta._t === 'a';
1618 var moveDestinations = {};
1619 var name = void 0;
1620 if (typeof left !== 'undefined') {
1621 for (name in left) {
1622 if (Object.prototype.hasOwnProperty.call(left, name)) {
1623 if (typeof delta[name] === 'undefined' && (!arrayKeys || typeof delta['_' + name] === 'undefined')) {
1624 keys.push(name);
1625 }
1626 }
1627 }
1628 }
1629 // look for move destinations
1630 for (name in delta) {
1631 if (Object.prototype.hasOwnProperty.call(delta, name)) {
1632 var value = delta[name];
1633 if (isArray$3(value) && value[2] === 3) {
1634 moveDestinations[value[1].toString()] = {
1635 key: name,
1636 value: left && left[parseInt(name.substr(1))]
1637 };
1638 if (this.includeMoveDestinations !== false) {
1639 if (typeof left === 'undefined' && typeof delta[value[1]] === 'undefined') {
1640 keys.push(value[1].toString());
1641 }
1642 }
1643 }
1644 }
1645 }
1646 if (arrayKeys) {
1647 keys.sort(arrayKeyComparer);
1648 } else {
1649 keys.sort();
1650 }
1651 for (var index = 0, length = keys.length; index < length; index++) {
1652 var key = keys[index];
1653 if (arrayKeys && key === '_t') {
1654 continue;
1655 }
1656 var leftKey = arrayKeys ? typeof key === 'number' ? key : parseInt(trimUnderscore(key), 10) : key;
1657 var isLast = index === length - 1;
1658 fn(key, leftKey, moveDestinations[leftKey], isLast);
1659 }
1660 }
1661 }, {
1662 key: 'getDeltaType',
1663 value: function getDeltaType(delta, movedFrom) {
1664 if (typeof delta === 'undefined') {
1665 if (typeof movedFrom !== 'undefined') {
1666 return 'movedestination';
1667 }
1668 return 'unchanged';
1669 }
1670 if (isArray$3(delta)) {
1671 if (delta.length === 1) {
1672 return 'added';
1673 }
1674 if (delta.length === 2) {
1675 return 'modified';
1676 }
1677 if (delta.length === 3 && delta[2] === 0) {
1678 return 'deleted';
1679 }
1680 if (delta.length === 3 && delta[2] === 2) {
1681 return 'textdiff';
1682 }
1683 if (delta.length === 3 && delta[2] === 3) {
1684 return 'moved';
1685 }
1686 } else if ((typeof delta === 'undefined' ? 'undefined' : _typeof(delta)) === 'object') {
1687 return 'node';
1688 }
1689 return 'unknown';
1690 }
1691 }, {
1692 key: 'parseTextDiff',
1693 value: function parseTextDiff(value) {
1694 var output = [];
1695 var lines = value.split('\n@@ ');
1696 for (var i = 0, l = lines.length; i < l; i++) {
1697 var line = lines[i];
1698 var lineOutput = {
1699 pieces: []
1700 };
1701 var location = /^(?:@@ )?[-+]?(\d+),(\d+)/.exec(line).slice(1);
1702 lineOutput.location = {
1703 line: location[0],
1704 chr: location[1]
1705 };
1706 var pieces = line.split('\n').slice(1);
1707 for (var pieceIndex = 0, piecesLength = pieces.length; pieceIndex < piecesLength; pieceIndex++) {
1708 var piece = pieces[pieceIndex];
1709 if (!piece.length) {
1710 continue;
1711 }
1712 var pieceOutput = {
1713 type: 'context'
1714 };
1715 if (piece.substr(0, 1) === '+') {
1716 pieceOutput.type = 'added';
1717 } else if (piece.substr(0, 1) === '-') {
1718 pieceOutput.type = 'deleted';
1719 }
1720 pieceOutput.text = piece.slice(1);
1721 lineOutput.pieces.push(pieceOutput);
1722 }
1723 output.push(lineOutput);
1724 }
1725 return output;
1726 }
1727 }]);
1728 return BaseFormatter;
1729}();
1730
1731
1732
1733var base = Object.freeze({
1734 default: BaseFormatter
1735});
1736
1737var HtmlFormatter = function (_BaseFormatter) {
1738 inherits(HtmlFormatter, _BaseFormatter);
1739
1740 function HtmlFormatter() {
1741 classCallCheck(this, HtmlFormatter);
1742 return possibleConstructorReturn(this, (HtmlFormatter.__proto__ || Object.getPrototypeOf(HtmlFormatter)).apply(this, arguments));
1743 }
1744
1745 createClass(HtmlFormatter, [{
1746 key: 'typeFormattterErrorFormatter',
1747 value: function typeFormattterErrorFormatter(context, err) {
1748 context.out('<pre class="jsondiffpatch-error">' + err + '</pre>');
1749 }
1750 }, {
1751 key: 'formatValue',
1752 value: function formatValue(context, value) {
1753 context.out('<pre>' + htmlEscape(JSON.stringify(value, null, 2)) + '</pre>');
1754 }
1755 }, {
1756 key: 'formatTextDiffString',
1757 value: function formatTextDiffString(context, value) {
1758 var lines = this.parseTextDiff(value);
1759 context.out('<ul class="jsondiffpatch-textdiff">');
1760 for (var i = 0, l = lines.length; i < l; i++) {
1761 var line = lines[i];
1762 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">'));
1763 var pieces = line.pieces;
1764 for (var pieceIndex = 0, piecesLength = pieces.length; pieceIndex < piecesLength; pieceIndex++) {
1765 /* global unescape */
1766 var piece = pieces[pieceIndex];
1767 context.out('<span class="jsondiffpatch-textdiff-' + piece.type + '">' + htmlEscape(unescape(piece.text)) + '</span>');
1768 }
1769 context.out('</div></li>');
1770 }
1771 context.out('</ul>');
1772 }
1773 }, {
1774 key: 'rootBegin',
1775 value: function rootBegin(context, type, nodeType) {
1776 var nodeClass = 'jsondiffpatch-' + type + (nodeType ? ' jsondiffpatch-child-node-type-' + nodeType : '');
1777 context.out('<div class="jsondiffpatch-delta ' + nodeClass + '">');
1778 }
1779 }, {
1780 key: 'rootEnd',
1781 value: function rootEnd(context) {
1782 context.out('</div>' + (context.hasArrows ? '<script type="text/javascript">setTimeout(' + (adjustArrows.toString() + ',10);</script>') : ''));
1783 }
1784 }, {
1785 key: 'nodeBegin',
1786 value: function nodeBegin(context, key, leftKey, type, nodeType) {
1787 var nodeClass = 'jsondiffpatch-' + type + (nodeType ? ' jsondiffpatch-child-node-type-' + nodeType : '');
1788 context.out('<li class="' + nodeClass + '" data-key="' + leftKey + '">' + ('<div class="jsondiffpatch-property-name">' + leftKey + '</div>'));
1789 }
1790 }, {
1791 key: 'nodeEnd',
1792 value: function nodeEnd(context) {
1793 context.out('</li>');
1794 }
1795
1796 /* jshint camelcase: false */
1797 /* eslint-disable camelcase */
1798
1799 }, {
1800 key: 'format_unchanged',
1801 value: function format_unchanged(context, delta, left) {
1802 if (typeof left === 'undefined') {
1803 return;
1804 }
1805 context.out('<div class="jsondiffpatch-value">');
1806 this.formatValue(context, left);
1807 context.out('</div>');
1808 }
1809 }, {
1810 key: 'format_movedestination',
1811 value: function format_movedestination(context, delta, left) {
1812 if (typeof left === 'undefined') {
1813 return;
1814 }
1815 context.out('<div class="jsondiffpatch-value">');
1816 this.formatValue(context, left);
1817 context.out('</div>');
1818 }
1819 }, {
1820 key: 'format_node',
1821 value: function format_node(context, delta, left) {
1822 // recurse
1823 var nodeType = delta._t === 'a' ? 'array' : 'object';
1824 context.out('<ul class="jsondiffpatch-node jsondiffpatch-node-type-' + nodeType + '">');
1825 this.formatDeltaChildren(context, delta, left);
1826 context.out('</ul>');
1827 }
1828 }, {
1829 key: 'format_added',
1830 value: function format_added(context, delta) {
1831 context.out('<div class="jsondiffpatch-value">');
1832 this.formatValue(context, delta[0]);
1833 context.out('</div>');
1834 }
1835 }, {
1836 key: 'format_modified',
1837 value: function format_modified(context, delta) {
1838 context.out('<div class="jsondiffpatch-value jsondiffpatch-left-value">');
1839 this.formatValue(context, delta[0]);
1840 context.out('</div>' + '<div class="jsondiffpatch-value jsondiffpatch-right-value">');
1841 this.formatValue(context, delta[1]);
1842 context.out('</div>');
1843 }
1844 }, {
1845 key: 'format_deleted',
1846 value: function format_deleted(context, delta) {
1847 context.out('<div class="jsondiffpatch-value">');
1848 this.formatValue(context, delta[0]);
1849 context.out('</div>');
1850 }
1851 }, {
1852 key: 'format_moved',
1853 value: function format_moved(context, delta) {
1854 context.out('<div class="jsondiffpatch-value">');
1855 this.formatValue(context, delta[0]);
1856 context.out('</div><div class="jsondiffpatch-moved-destination">' + delta[1] + '</div>');
1857
1858 // draw an SVG arrow from here to move destination
1859 context.out(
1860 /* jshint multistr: true */
1861 '<div class="jsondiffpatch-arrow" ' + 'style="position: relative; left: -34px;">\n <svg width="30" height="60" ' + 'style="position: absolute; display: none;">\n <defs>\n <marker id="markerArrow" markerWidth="8" markerHeight="8"\n refx="2" refy="4"\n orient="auto" markerUnits="userSpaceOnUse">\n <path d="M1,1 L1,7 L7,4 L1,1" style="fill: #339;" />\n </marker>\n </defs>\n <path d="M30,0 Q-10,25 26,50"\n style="stroke: #88f; stroke-width: 2px; fill: none; ' + 'stroke-opacity: 0.5; marker-end: url(#markerArrow);"\n ></path>\n </svg>\n </div>');
1862 context.hasArrows = true;
1863 }
1864 }, {
1865 key: 'format_textdiff',
1866 value: function format_textdiff(context, delta) {
1867 context.out('<div class="jsondiffpatch-value">');
1868 this.formatTextDiffString(context, delta[0]);
1869 context.out('</div>');
1870 }
1871 }]);
1872 return HtmlFormatter;
1873}(BaseFormatter);
1874
1875function htmlEscape(text) {
1876 var html = text;
1877 var replacements = [[/&/g, '&amp;'], [/</g, '&lt;'], [/>/g, '&gt;'], [/'/g, '&apos;'], [/"/g, '&quot;']];
1878 for (var i = 0; i < replacements.length; i++) {
1879 html = html.replace(replacements[i][0], replacements[i][1]);
1880 }
1881 return html;
1882}
1883
1884var adjustArrows = function jsondiffpatchHtmlFormatterAdjustArrows(nodeArg) {
1885 var node = nodeArg || document;
1886 var getElementText = function getElementText(_ref) {
1887 var textContent = _ref.textContent,
1888 innerText = _ref.innerText;
1889 return textContent || innerText;
1890 };
1891 var eachByQuery = function eachByQuery(el, query, fn) {
1892 var elems = el.querySelectorAll(query);
1893 for (var i = 0, l = elems.length; i < l; i++) {
1894 fn(elems[i]);
1895 }
1896 };
1897 var eachChildren = function eachChildren(_ref2, fn) {
1898 var children = _ref2.children;
1899
1900 for (var i = 0, l = children.length; i < l; i++) {
1901 fn(children[i], i);
1902 }
1903 };
1904 eachByQuery(node, '.jsondiffpatch-arrow', function (_ref3) {
1905 var parentNode = _ref3.parentNode,
1906 children = _ref3.children,
1907 style = _ref3.style;
1908
1909 var arrowParent = parentNode;
1910 var svg = children[0];
1911 var path = svg.children[1];
1912 svg.style.display = 'none';
1913 var destination = getElementText(arrowParent.querySelector('.jsondiffpatch-moved-destination'));
1914 var container = arrowParent.parentNode;
1915 var destinationElem = void 0;
1916 eachChildren(container, function (child) {
1917 if (child.getAttribute('data-key') === destination) {
1918 destinationElem = child;
1919 }
1920 });
1921 if (!destinationElem) {
1922 return;
1923 }
1924 try {
1925 var distance = destinationElem.offsetTop - arrowParent.offsetTop;
1926 svg.setAttribute('height', Math.abs(distance) + 6);
1927 style.top = -8 + (distance > 0 ? 0 : distance) + 'px';
1928 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';
1929 path.setAttribute('d', curve);
1930 svg.style.display = '';
1931 } catch (err) {}
1932 });
1933};
1934
1935/* jshint camelcase: true */
1936/* eslint-enable camelcase */
1937
1938var showUnchanged = function showUnchanged(show, node, delay) {
1939 var el = node || document.body;
1940 var prefix = 'jsondiffpatch-unchanged-';
1941 var classes = {
1942 showing: prefix + 'showing',
1943 hiding: prefix + 'hiding',
1944 visible: prefix + 'visible',
1945 hidden: prefix + 'hidden'
1946 };
1947 var list = el.classList;
1948 if (!list) {
1949 return;
1950 }
1951 if (!delay) {
1952 list.remove(classes.showing);
1953 list.remove(classes.hiding);
1954 list.remove(classes.visible);
1955 list.remove(classes.hidden);
1956 if (show === false) {
1957 list.add(classes.hidden);
1958 }
1959 return;
1960 }
1961 if (show === false) {
1962 list.remove(classes.showing);
1963 list.add(classes.visible);
1964 setTimeout(function () {
1965 list.add(classes.hiding);
1966 }, 10);
1967 } else {
1968 list.remove(classes.hiding);
1969 list.add(classes.showing);
1970 list.remove(classes.hidden);
1971 }
1972 var intervalId = setInterval(function () {
1973 adjustArrows(el);
1974 }, 100);
1975 setTimeout(function () {
1976 list.remove(classes.showing);
1977 list.remove(classes.hiding);
1978 if (show === false) {
1979 list.add(classes.hidden);
1980 list.remove(classes.visible);
1981 } else {
1982 list.add(classes.visible);
1983 list.remove(classes.hidden);
1984 }
1985 setTimeout(function () {
1986 list.remove(classes.visible);
1987 clearInterval(intervalId);
1988 }, delay + 400);
1989 }, delay);
1990};
1991
1992var hideUnchanged = function hideUnchanged(node, delay) {
1993 return showUnchanged(false, node, delay);
1994};
1995
1996var defaultInstance = void 0;
1997
1998function format(delta, left) {
1999 if (!defaultInstance) {
2000 defaultInstance = new HtmlFormatter();
2001 }
2002 return defaultInstance.format(delta, left);
2003}
2004
2005
2006
2007var html = Object.freeze({
2008 showUnchanged: showUnchanged,
2009 hideUnchanged: hideUnchanged,
2010 default: HtmlFormatter,
2011 format: format
2012});
2013
2014var AnnotatedFormatter = function (_BaseFormatter) {
2015 inherits(AnnotatedFormatter, _BaseFormatter);
2016
2017 function AnnotatedFormatter() {
2018 classCallCheck(this, AnnotatedFormatter);
2019
2020 var _this = possibleConstructorReturn(this, (AnnotatedFormatter.__proto__ || Object.getPrototypeOf(AnnotatedFormatter)).call(this));
2021
2022 _this.includeMoveDestinations = false;
2023 return _this;
2024 }
2025
2026 createClass(AnnotatedFormatter, [{
2027 key: 'prepareContext',
2028 value: function prepareContext(context) {
2029 get(AnnotatedFormatter.prototype.__proto__ || Object.getPrototypeOf(AnnotatedFormatter.prototype), 'prepareContext', this).call(this, context);
2030 context.indent = function (levels) {
2031 this.indentLevel = (this.indentLevel || 0) + (typeof levels === 'undefined' ? 1 : levels);
2032 this.indentPad = new Array(this.indentLevel + 1).join('&nbsp;&nbsp;');
2033 };
2034 context.row = function (json, htmlNote) {
2035 context.out('<tr><td style="white-space: nowrap;">' + '<pre class="jsondiffpatch-annotated-indent"' + ' style="display: inline-block">');
2036 context.out(context.indentPad);
2037 context.out('</pre><pre style="display: inline-block">');
2038 context.out(json);
2039 context.out('</pre></td><td class="jsondiffpatch-delta-note"><div>');
2040 context.out(htmlNote);
2041 context.out('</div></td></tr>');
2042 };
2043 }
2044 }, {
2045 key: 'typeFormattterErrorFormatter',
2046 value: function typeFormattterErrorFormatter(context, err) {
2047 context.row('', '<pre class="jsondiffpatch-error">' + err + '</pre>');
2048 }
2049 }, {
2050 key: 'formatTextDiffString',
2051 value: function formatTextDiffString(context, value) {
2052 var lines = this.parseTextDiff(value);
2053 context.out('<ul class="jsondiffpatch-textdiff">');
2054 for (var i = 0, l = lines.length; i < l; i++) {
2055 var line = lines[i];
2056 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">'));
2057 var pieces = line.pieces;
2058 for (var pieceIndex = 0, piecesLength = pieces.length; pieceIndex < piecesLength; pieceIndex++) {
2059 var piece = pieces[pieceIndex];
2060 context.out('<span class="jsondiffpatch-textdiff-' + piece.type + '">' + piece.text + '</span>');
2061 }
2062 context.out('</div></li>');
2063 }
2064 context.out('</ul>');
2065 }
2066 }, {
2067 key: 'rootBegin',
2068 value: function rootBegin(context, type, nodeType) {
2069 context.out('<table class="jsondiffpatch-annotated-delta">');
2070 if (type === 'node') {
2071 context.row('{');
2072 context.indent();
2073 }
2074 if (nodeType === 'array') {
2075 context.row('"_t": "a",', 'Array delta (member names indicate array indices)');
2076 }
2077 }
2078 }, {
2079 key: 'rootEnd',
2080 value: function rootEnd(context, type) {
2081 if (type === 'node') {
2082 context.indent(-1);
2083 context.row('}');
2084 }
2085 context.out('</table>');
2086 }
2087 }, {
2088 key: 'nodeBegin',
2089 value: function nodeBegin(context, key, leftKey, type, nodeType) {
2090 context.row('&quot;' + key + '&quot;: {');
2091 if (type === 'node') {
2092 context.indent();
2093 }
2094 if (nodeType === 'array') {
2095 context.row('"_t": "a",', 'Array delta (member names indicate array indices)');
2096 }
2097 }
2098 }, {
2099 key: 'nodeEnd',
2100 value: function nodeEnd(context, key, leftKey, type, nodeType, isLast) {
2101 if (type === 'node') {
2102 context.indent(-1);
2103 }
2104 context.row('}' + (isLast ? '' : ','));
2105 }
2106
2107 /* jshint camelcase: false */
2108
2109 /* eslint-disable camelcase */
2110
2111 }, {
2112 key: 'format_unchanged',
2113 value: function format_unchanged() {}
2114 }, {
2115 key: 'format_movedestination',
2116 value: function format_movedestination() {}
2117 }, {
2118 key: 'format_node',
2119 value: function format_node(context, delta, left) {
2120 // recurse
2121 this.formatDeltaChildren(context, delta, left);
2122 }
2123 }]);
2124 return AnnotatedFormatter;
2125}(BaseFormatter);
2126
2127/* eslint-enable camelcase */
2128
2129var wrapPropertyName = function wrapPropertyName(name) {
2130 return '<pre style="display:inline-block">&quot;' + name + '&quot;</pre>';
2131};
2132
2133var deltaAnnotations = {
2134 added: function added(delta, left, key, leftKey) {
2135 var formatLegend = ' <pre>([newValue])</pre>';
2136 if (typeof leftKey === 'undefined') {
2137 return 'new value' + formatLegend;
2138 }
2139 if (typeof leftKey === 'number') {
2140 return 'insert at index ' + leftKey + formatLegend;
2141 }
2142 return 'add property ' + wrapPropertyName(leftKey) + formatLegend;
2143 },
2144 modified: function modified(delta, left, key, leftKey) {
2145 var formatLegend = ' <pre>([previousValue, newValue])</pre>';
2146 if (typeof leftKey === 'undefined') {
2147 return 'modify value' + formatLegend;
2148 }
2149 if (typeof leftKey === 'number') {
2150 return 'modify at index ' + leftKey + formatLegend;
2151 }
2152 return 'modify property ' + wrapPropertyName(leftKey) + formatLegend;
2153 },
2154 deleted: function deleted(delta, left, key, leftKey) {
2155 var formatLegend = ' <pre>([previousValue, 0, 0])</pre>';
2156 if (typeof leftKey === 'undefined') {
2157 return 'delete value' + formatLegend;
2158 }
2159 if (typeof leftKey === 'number') {
2160 return 'remove index ' + leftKey + formatLegend;
2161 }
2162 return 'delete property ' + wrapPropertyName(leftKey) + formatLegend;
2163 },
2164 moved: function moved(delta, left, key, leftKey) {
2165 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>');
2166 },
2167 textdiff: function textdiff(delta, left, key, leftKey) {
2168 var location = typeof leftKey === 'undefined' ? '' : typeof leftKey === 'number' ? ' at index ' + leftKey : ' at property ' + wrapPropertyName(leftKey);
2169 return 'text diff' + location + ', format is <a href="https://code.google.com/' + 'p/google-diff-match-patch/wiki/Unidiff">a variation of Unidiff</a>';
2170 }
2171};
2172
2173var formatAnyChange = function formatAnyChange(context, delta) {
2174 var deltaType = this.getDeltaType(delta);
2175 var annotator = deltaAnnotations[deltaType];
2176 var htmlNote = annotator && annotator.apply(annotator, Array.prototype.slice.call(arguments, 1));
2177 var json = JSON.stringify(delta, null, 2);
2178 if (deltaType === 'textdiff') {
2179 // split text diffs lines
2180 json = json.split('\\n').join('\\n"+\n "');
2181 }
2182 context.indent();
2183 context.row(json, htmlNote);
2184 context.indent(-1);
2185};
2186
2187/* eslint-disable camelcase */
2188AnnotatedFormatter.prototype.format_added = formatAnyChange;
2189AnnotatedFormatter.prototype.format_modified = formatAnyChange;
2190AnnotatedFormatter.prototype.format_deleted = formatAnyChange;
2191AnnotatedFormatter.prototype.format_moved = formatAnyChange;
2192AnnotatedFormatter.prototype.format_textdiff = formatAnyChange;
2193var defaultInstance$1 = void 0;
2194
2195function format$1(delta, left) {
2196 if (!defaultInstance$1) {
2197 defaultInstance$1 = new AnnotatedFormatter();
2198 }
2199 return defaultInstance$1.format(delta, left);
2200}
2201
2202
2203
2204var annotated = Object.freeze({
2205 default: AnnotatedFormatter,
2206 format: format$1
2207});
2208
2209var OPERATIONS = {
2210 add: 'add',
2211 remove: 'remove',
2212 replace: 'replace',
2213 move: 'move'
2214};
2215
2216var JSONFormatter = function (_BaseFormatter) {
2217 inherits(JSONFormatter, _BaseFormatter);
2218
2219 function JSONFormatter() {
2220 classCallCheck(this, JSONFormatter);
2221
2222 var _this = possibleConstructorReturn(this, (JSONFormatter.__proto__ || Object.getPrototypeOf(JSONFormatter)).call(this));
2223
2224 _this.includeMoveDestinations = true;
2225 return _this;
2226 }
2227
2228 createClass(JSONFormatter, [{
2229 key: 'prepareContext',
2230 value: function prepareContext(context) {
2231 get(JSONFormatter.prototype.__proto__ || Object.getPrototypeOf(JSONFormatter.prototype), 'prepareContext', this).call(this, context);
2232 context.result = [];
2233 context.path = [];
2234 context.pushCurrentOp = function (obj) {
2235 var op = obj.op,
2236 value = obj.value;
2237
2238 var val = {
2239 op: op,
2240 path: this.currentPath()
2241 };
2242 if (typeof value !== 'undefined') {
2243 val.value = value;
2244 }
2245 this.result.push(val);
2246 };
2247
2248 context.pushMoveOp = function (to) {
2249 var finalTo = '/' + to;
2250 var from = this.currentPath();
2251 this.result.push({ op: OPERATIONS.move, from: from, path: finalTo });
2252 };
2253
2254 context.currentPath = function () {
2255 return '/' + this.path.join('/');
2256 };
2257 }
2258 }, {
2259 key: 'typeFormattterErrorFormatter',
2260 value: function typeFormattterErrorFormatter(context, err) {
2261 context.out('[ERROR] ' + err);
2262 }
2263 }, {
2264 key: 'rootBegin',
2265 value: function rootBegin() {}
2266 }, {
2267 key: 'rootEnd',
2268 value: function rootEnd() {}
2269 }, {
2270 key: 'nodeBegin',
2271 value: function nodeBegin(_ref, key, leftKey) {
2272 var path = _ref.path;
2273
2274 path.push(leftKey);
2275 }
2276 }, {
2277 key: 'nodeEnd',
2278 value: function nodeEnd(_ref2) {
2279 var path = _ref2.path;
2280
2281 path.pop();
2282 }
2283
2284 /* jshint camelcase: false */
2285 /* eslint-disable camelcase */
2286
2287 }, {
2288 key: 'format_unchanged',
2289 value: function format_unchanged() {}
2290 }, {
2291 key: 'format_movedestination',
2292 value: function format_movedestination() {}
2293 }, {
2294 key: 'format_node',
2295 value: function format_node(context, delta, left) {
2296 this.formatDeltaChildren(context, delta, left);
2297 }
2298 }, {
2299 key: 'format_added',
2300 value: function format_added(context, delta) {
2301 context.pushCurrentOp({ op: OPERATIONS.add, value: delta[0] });
2302 }
2303 }, {
2304 key: 'format_modified',
2305 value: function format_modified(context, delta) {
2306 context.pushCurrentOp({ op: OPERATIONS.replace, value: delta[1] });
2307 }
2308 }, {
2309 key: 'format_deleted',
2310 value: function format_deleted(context) {
2311 context.pushCurrentOp({ op: OPERATIONS.remove });
2312 }
2313 }, {
2314 key: 'format_moved',
2315 value: function format_moved(context, delta) {
2316 var to = delta[1];
2317 context.pushMoveOp(to);
2318 }
2319 }, {
2320 key: 'format_textdiff',
2321 value: function format_textdiff() {
2322 throw new Error('Not implemented');
2323 }
2324 }, {
2325 key: 'format',
2326 value: function format(delta, left) {
2327 var context = {};
2328 this.prepareContext(context);
2329 this.recurse(context, delta, left);
2330 return context.result;
2331 }
2332 }]);
2333 return JSONFormatter;
2334}(BaseFormatter);
2335
2336var last = function last(arr) {
2337 return arr[arr.length - 1];
2338};
2339
2340var sortBy = function sortBy(arr, pred) {
2341 arr.sort(pred);
2342 return arr;
2343};
2344
2345var compareByIndexDesc = function compareByIndexDesc(indexA, indexB) {
2346 var lastA = parseInt(indexA, 10);
2347 var lastB = parseInt(indexB, 10);
2348 if (!(isNaN(lastA) || isNaN(lastB))) {
2349 return lastB - lastA;
2350 } else {
2351 return 0;
2352 }
2353};
2354
2355var opsByDescendingOrder = function opsByDescendingOrder(removeOps) {
2356 return sortBy(removeOps, function (a, b) {
2357 var splitA = a.path.split('/');
2358 var splitB = b.path.split('/');
2359 if (splitA.length !== splitB.length) {
2360 return splitA.length - splitB.length;
2361 } else {
2362 return compareByIndexDesc(last(splitA), last(splitB));
2363 }
2364 });
2365};
2366
2367var partition = function partition(arr, pred) {
2368 var left = [];
2369 var right = [];
2370
2371 arr.forEach(function (el) {
2372 var coll = pred(el) ? left : right;
2373 coll.push(el);
2374 });
2375 return [left, right];
2376};
2377
2378var partitionRemovedOps = function partitionRemovedOps(jsonFormattedDiff) {
2379 var isRemoveOp = function isRemoveOp(_ref3) {
2380 var op = _ref3.op;
2381 return op === 'remove';
2382 };
2383 var removeOpsOtherOps = partition(jsonFormattedDiff, isRemoveOp);
2384 return removeOpsOtherOps;
2385};
2386
2387var reorderOps = function reorderOps(jsonFormattedDiff) {
2388 var _partitionRemovedOps = partitionRemovedOps(jsonFormattedDiff),
2389 _partitionRemovedOps2 = slicedToArray(_partitionRemovedOps, 2),
2390 removeOps = _partitionRemovedOps2[0],
2391 otherOps = _partitionRemovedOps2[1];
2392
2393 var removeOpsReverse = opsByDescendingOrder(removeOps);
2394 return removeOpsReverse.concat(otherOps);
2395};
2396
2397var defaultInstance$2 = void 0;
2398
2399var format$2 = function format(delta, left) {
2400 if (!defaultInstance$2) {
2401 defaultInstance$2 = new JSONFormatter();
2402 }
2403 return reorderOps(defaultInstance$2.format(delta, left));
2404};
2405
2406var log = function log(delta, left) {
2407 console.log(format$2(delta, left));
2408};
2409
2410
2411
2412var jsonpatch = Object.freeze({
2413 default: JSONFormatter,
2414 format: format$2,
2415 log: log
2416});
2417
2418function chalkColor(name) {
2419 return chalk && chalk[name] || function () {
2420 for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
2421 args[_key] = arguments[_key];
2422 }
2423
2424 return args;
2425 };
2426}
2427
2428var colors = {
2429 added: chalkColor('green'),
2430 deleted: chalkColor('red'),
2431 movedestination: chalkColor('gray'),
2432 moved: chalkColor('yellow'),
2433 unchanged: chalkColor('gray'),
2434 error: chalkColor('white.bgRed'),
2435 textDiffLine: chalkColor('gray')
2436};
2437
2438var ConsoleFormatter = function (_BaseFormatter) {
2439 inherits(ConsoleFormatter, _BaseFormatter);
2440
2441 function ConsoleFormatter() {
2442 classCallCheck(this, ConsoleFormatter);
2443
2444 var _this = possibleConstructorReturn(this, (ConsoleFormatter.__proto__ || Object.getPrototypeOf(ConsoleFormatter)).call(this));
2445
2446 _this.includeMoveDestinations = false;
2447 return _this;
2448 }
2449
2450 createClass(ConsoleFormatter, [{
2451 key: 'prepareContext',
2452 value: function prepareContext(context) {
2453 get(ConsoleFormatter.prototype.__proto__ || Object.getPrototypeOf(ConsoleFormatter.prototype), 'prepareContext', this).call(this, context);
2454 context.indent = function (levels) {
2455 this.indentLevel = (this.indentLevel || 0) + (typeof levels === 'undefined' ? 1 : levels);
2456 this.indentPad = new Array(this.indentLevel + 1).join(' ');
2457 this.outLine();
2458 };
2459 context.outLine = function () {
2460 this.buffer.push('\n' + (this.indentPad || ''));
2461 };
2462 context.out = function () {
2463 for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
2464 args[_key2] = arguments[_key2];
2465 }
2466
2467 for (var i = 0, l = args.length; i < l; i++) {
2468 var lines = args[i].split('\n');
2469 var text = lines.join('\n' + (this.indentPad || ''));
2470 if (this.color && this.color[0]) {
2471 text = this.color[0](text);
2472 }
2473 this.buffer.push(text);
2474 }
2475 };
2476 context.pushColor = function (color) {
2477 this.color = this.color || [];
2478 this.color.unshift(color);
2479 };
2480 context.popColor = function () {
2481 this.color = this.color || [];
2482 this.color.shift();
2483 };
2484 }
2485 }, {
2486 key: 'typeFormattterErrorFormatter',
2487 value: function typeFormattterErrorFormatter(context, err) {
2488 context.pushColor(colors.error);
2489 context.out('[ERROR]' + err);
2490 context.popColor();
2491 }
2492 }, {
2493 key: 'formatValue',
2494 value: function formatValue(context, value) {
2495 context.out(JSON.stringify(value, null, 2));
2496 }
2497 }, {
2498 key: 'formatTextDiffString',
2499 value: function formatTextDiffString(context, value) {
2500 var lines = this.parseTextDiff(value);
2501 context.indent();
2502 for (var i = 0, l = lines.length; i < l; i++) {
2503 var line = lines[i];
2504 context.pushColor(colors.textDiffLine);
2505 context.out(line.location.line + ',' + line.location.chr + ' ');
2506 context.popColor();
2507 var pieces = line.pieces;
2508 for (var pieceIndex = 0, piecesLength = pieces.length; pieceIndex < piecesLength; pieceIndex++) {
2509 var piece = pieces[pieceIndex];
2510 context.pushColor(colors[piece.type]);
2511 context.out(piece.text);
2512 context.popColor();
2513 }
2514 if (i < l - 1) {
2515 context.outLine();
2516 }
2517 }
2518 context.indent(-1);
2519 }
2520 }, {
2521 key: 'rootBegin',
2522 value: function rootBegin(context, type, nodeType) {
2523 context.pushColor(colors[type]);
2524 if (type === 'node') {
2525 context.out(nodeType === 'array' ? '[' : '{');
2526 context.indent();
2527 }
2528 }
2529 }, {
2530 key: 'rootEnd',
2531 value: function rootEnd(context, type, nodeType) {
2532 if (type === 'node') {
2533 context.indent(-1);
2534 context.out(nodeType === 'array' ? ']' : '}');
2535 }
2536 context.popColor();
2537 }
2538 }, {
2539 key: 'nodeBegin',
2540 value: function nodeBegin(context, key, leftKey, type, nodeType) {
2541 context.pushColor(colors[type]);
2542 context.out(leftKey + ': ');
2543 if (type === 'node') {
2544 context.out(nodeType === 'array' ? '[' : '{');
2545 context.indent();
2546 }
2547 }
2548 }, {
2549 key: 'nodeEnd',
2550 value: function nodeEnd(context, key, leftKey, type, nodeType, isLast) {
2551 if (type === 'node') {
2552 context.indent(-1);
2553 context.out(nodeType === 'array' ? ']' : '}' + (isLast ? '' : ','));
2554 }
2555 if (!isLast) {
2556 context.outLine();
2557 }
2558 context.popColor();
2559 }
2560
2561 /* jshint camelcase: false */
2562 /* eslint-disable camelcase */
2563
2564 }, {
2565 key: 'format_unchanged',
2566 value: function format_unchanged(context, delta, left) {
2567 if (typeof left === 'undefined') {
2568 return;
2569 }
2570 this.formatValue(context, left);
2571 }
2572 }, {
2573 key: 'format_movedestination',
2574 value: function format_movedestination(context, delta, left) {
2575 if (typeof left === 'undefined') {
2576 return;
2577 }
2578 this.formatValue(context, left);
2579 }
2580 }, {
2581 key: 'format_node',
2582 value: function format_node(context, delta, left) {
2583 // recurse
2584 this.formatDeltaChildren(context, delta, left);
2585 }
2586 }, {
2587 key: 'format_added',
2588 value: function format_added(context, delta) {
2589 this.formatValue(context, delta[0]);
2590 }
2591 }, {
2592 key: 'format_modified',
2593 value: function format_modified(context, delta) {
2594 context.pushColor(colors.deleted);
2595 this.formatValue(context, delta[0]);
2596 context.popColor();
2597 context.out(' => ');
2598 context.pushColor(colors.added);
2599 this.formatValue(context, delta[1]);
2600 context.popColor();
2601 }
2602 }, {
2603 key: 'format_deleted',
2604 value: function format_deleted(context, delta) {
2605 this.formatValue(context, delta[0]);
2606 }
2607 }, {
2608 key: 'format_moved',
2609 value: function format_moved(context, delta) {
2610 context.out('==> ' + delta[1]);
2611 }
2612 }, {
2613 key: 'format_textdiff',
2614 value: function format_textdiff(context, delta) {
2615 this.formatTextDiffString(context, delta[0]);
2616 }
2617 }]);
2618 return ConsoleFormatter;
2619}(BaseFormatter);
2620
2621var defaultInstance$3 = void 0;
2622
2623var format$3 = function format(delta, left) {
2624 if (!defaultInstance$3) {
2625 defaultInstance$3 = new ConsoleFormatter();
2626 }
2627 return defaultInstance$3.format(delta, left);
2628};
2629
2630function log$1(delta, left) {
2631 console.log(format$3(delta, left));
2632}
2633
2634
2635
2636var console$1 = Object.freeze({
2637 default: ConsoleFormatter,
2638 format: format$3,
2639 log: log$1
2640});
2641
2642
2643
2644var index = Object.freeze({
2645 base: base,
2646 html: html,
2647 annotated: annotated,
2648 jsonpatch: jsonpatch,
2649 console: console$1
2650});
2651
2652// use as 2nd parameter for JSON.parse to revive Date instances
2653function dateReviver(key, value) {
2654 var parts = void 0;
2655 if (typeof value === 'string') {
2656 // eslint-disable-next-line max-len
2657 parts = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(?:\.(\d*))?(Z|([+-])(\d{2}):(\d{2}))$/.exec(value);
2658 if (parts) {
2659 return new Date(Date.UTC(+parts[1], +parts[2] - 1, +parts[3], +parts[4], +parts[5], +parts[6], +(parts[7] || 0)));
2660 }
2661 }
2662 return value;
2663}
2664
2665function create(options) {
2666 return new DiffPatcher(options);
2667}
2668
2669var defaultInstance$4 = void 0;
2670
2671function diff() {
2672 if (!defaultInstance$4) {
2673 defaultInstance$4 = new DiffPatcher();
2674 }
2675 return defaultInstance$4.diff.apply(defaultInstance$4, arguments);
2676}
2677
2678function patch() {
2679 if (!defaultInstance$4) {
2680 defaultInstance$4 = new DiffPatcher();
2681 }
2682 return defaultInstance$4.patch.apply(defaultInstance$4, arguments);
2683}
2684
2685function unpatch() {
2686 if (!defaultInstance$4) {
2687 defaultInstance$4 = new DiffPatcher();
2688 }
2689 return defaultInstance$4.unpatch.apply(defaultInstance$4, arguments);
2690}
2691
2692function reverse() {
2693 if (!defaultInstance$4) {
2694 defaultInstance$4 = new DiffPatcher();
2695 }
2696 return defaultInstance$4.reverse.apply(defaultInstance$4, arguments);
2697}
2698
2699function clone$1() {
2700 if (!defaultInstance$4) {
2701 defaultInstance$4 = new DiffPatcher();
2702 }
2703 return defaultInstance$4.clone.apply(defaultInstance$4, arguments);
2704}
2705
2706exports.DiffPatcher = DiffPatcher;
2707exports.formatters = index;
2708exports.console = console$1;
2709exports.create = create;
2710exports.dateReviver = dateReviver;
2711exports.diff = diff;
2712exports.patch = patch;
2713exports.unpatch = unpatch;
2714exports.reverse = reverse;
2715exports.clone = clone$1;
2716//# sourceMappingURL=jsondiffpatch.cjs.js.map