").append(m.parseHTML(a)).find(d):a)}).complete(c&&function(a,b){g.each(c,e||[a.responseText,b,a])}),this},m.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(a,b){m.fn[b]=function(a){return this.on(b,a)}}),m.expr.filters.animated=function(a){return m.grep(m.timers,function(b){return a===b.elem}).length};var cd=a.document.documentElement;function dd(a){return m.isWindow(a)?a:9===a.nodeType?a.defaultView||a.parentWindow:!1}m.offset={setOffset:function(a,b,c){var d,e,f,g,h,i,j,k=m.css(a,"position"),l=m(a),n={};"static"===k&&(a.style.position="relative"),h=l.offset(),f=m.css(a,"top"),i=m.css(a,"left"),j=("absolute"===k||"fixed"===k)&&m.inArray("auto",[f,i])>-1,j?(d=l.position(),g=d.top,e=d.left):(g=parseFloat(f)||0,e=parseFloat(i)||0),m.isFunction(b)&&(b=b.call(a,c,h)),null!=b.top&&(n.top=b.top-h.top+g),null!=b.left&&(n.left=b.left-h.left+e),"using"in b?b.using.call(a,n):l.css(n)}},m.fn.extend({offset:function(a){if(arguments.length)return void 0===a?this:this.each(function(b){m.offset.setOffset(this,a,b)});var b,c,d={top:0,left:0},e=this[0],f=e&&e.ownerDocument;if(f)return b=f.documentElement,m.contains(b,e)?(typeof e.getBoundingClientRect!==K&&(d=e.getBoundingClientRect()),c=dd(f),{top:d.top+(c.pageYOffset||b.scrollTop)-(b.clientTop||0),left:d.left+(c.pageXOffset||b.scrollLeft)-(b.clientLeft||0)}):d},position:function(){if(this[0]){var a,b,c={top:0,left:0},d=this[0];return"fixed"===m.css(d,"position")?b=d.getBoundingClientRect():(a=this.offsetParent(),b=this.offset(),m.nodeName(a[0],"html")||(c=a.offset()),c.top+=m.css(a[0],"borderTopWidth",!0),c.left+=m.css(a[0],"borderLeftWidth",!0)),{top:b.top-c.top-m.css(d,"marginTop",!0),left:b.left-c.left-m.css(d,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||cd;while(a&&!m.nodeName(a,"html")&&"static"===m.css(a,"position"))a=a.offsetParent;return a||cd})}}),m.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,b){var c=/Y/.test(b);m.fn[a]=function(d){return V(this,function(a,d,e){var f=dd(a);return void 0===e?f?b in f?f[b]:f.document.documentElement[d]:a[d]:void(f?f.scrollTo(c?m(f).scrollLeft():e,c?e:m(f).scrollTop()):a[d]=e)},a,d,arguments.length,null)}}),m.each(["top","left"],function(a,b){m.cssHooks[b]=Lb(k.pixelPosition,function(a,c){return c?(c=Jb(a,b),Hb.test(c)?m(a).position()[b]+"px":c):void 0})}),m.each({Height:"height",Width:"width"},function(a,b){m.each({padding:"inner"+a,content:b,"":"outer"+a},function(c,d){m.fn[d]=function(d,e){var f=arguments.length&&(c||"boolean"!=typeof d),g=c||(d===!0||e===!0?"margin":"border");return V(this,function(b,c,d){var e;return m.isWindow(b)?b.document.documentElement["client"+a]:9===b.nodeType?(e=b.documentElement,Math.max(b.body["scroll"+a],e["scroll"+a],b.body["offset"+a],e["offset"+a],e["client"+a])):void 0===d?m.css(b,c,g):m.style(b,c,d,g)},b,f?d:void 0,f,null)}})}),m.fn.size=function(){return this.length},m.fn.andSelf=m.fn.addBack,"function"==typeof define&&define.amd&&define("jquery",[],function(){return m});var ed=a.jQuery,fd=a.$;return m.noConflict=function(b){return a.$===m&&(a.$=fd),b&&a.jQuery===m&&(a.jQuery=ed),m},typeof b===K&&(a.jQuery=a.$=m),m});
+//# sourceMappingURL=jquery.min.map
+!function a(b,c,d){function e(g,h){if(!c[g]){if(!b[g]){var i="function"==typeof require&&require;if(!h&&i)return i(g,!0);if(f)return f(g,!0);var j=new Error("Cannot find module '"+g+"'");throw j.code="MODULE_NOT_FOUND",j}var k=c[g]={exports:{}};b[g][0].call(k.exports,function(a){var c=b[g][1][a];return e(c?c:a)},k,k.exports,a,b,c,d)}return c[g].exports}for(var f="function"==typeof require&&require,g=0;g
1&&c[1]||""}function d(b){var c=a.match(b);return c&&c.length>1&&c[2]||""}var e,f=c(/(ipod|iphone|ipad)/i).toLowerCase(),g=/like android/i.test(a),h=!g&&/android/i.test(a),i=/CrOS/.test(a),j=c(/edge\/(\d+(\.\d+)?)/i),k=c(/version\/(\d+(\.\d+)?)/i),l=/tablet/i.test(a),m=!l&&/[^-]mobi/i.test(a);/opera|opr/i.test(a)?e={name:"Opera",opera:b,version:k||c(/(?:opera|opr)[\s\/](\d+(\.\d+)?)/i)}:/yabrowser/i.test(a)?e={name:"Yandex Browser",yandexbrowser:b,version:k||c(/(?:yabrowser)[\s\/](\d+(\.\d+)?)/i)}:/windows phone/i.test(a)?(e={name:"Windows Phone",windowsphone:b},j?(e.msedge=b,e.version=j):(e.msie=b,e.version=c(/iemobile\/(\d+(\.\d+)?)/i))):/msie|trident/i.test(a)?e={name:"Internet Explorer",msie:b,version:c(/(?:msie |rv:)(\d+(\.\d+)?)/i)}:i?e={name:"Chrome",chromeBook:b,chrome:b,version:c(/(?:chrome|crios|crmo)\/(\d+(\.\d+)?)/i)}:/chrome.+? edge/i.test(a)?e={name:"Microsoft Edge",msedge:b,version:j}:/chrome|crios|crmo/i.test(a)?e={name:"Chrome",chrome:b,version:c(/(?:chrome|crios|crmo)\/(\d+(\.\d+)?)/i)}:f?(e={name:"iphone"==f?"iPhone":"ipad"==f?"iPad":"iPod"},k&&(e.version=k)):/sailfish/i.test(a)?e={name:"Sailfish",sailfish:b,version:c(/sailfish\s?browser\/(\d+(\.\d+)?)/i)}:/seamonkey\//i.test(a)?e={name:"SeaMonkey",seamonkey:b,version:c(/seamonkey\/(\d+(\.\d+)?)/i)}:/firefox|iceweasel/i.test(a)?(e={name:"Firefox",firefox:b,version:c(/(?:firefox|iceweasel)[ \/](\d+(\.\d+)?)/i)},/\((mobile|tablet);[^\)]*rv:[\d\.]+\)/i.test(a)&&(e.firefoxos=b)):/silk/i.test(a)?e={name:"Amazon Silk",silk:b,version:c(/silk\/(\d+(\.\d+)?)/i)}:h?e={name:"Android",version:k}:/phantom/i.test(a)?e={name:"PhantomJS",phantom:b,version:c(/phantomjs\/(\d+(\.\d+)?)/i)}:/blackberry|\bbb\d+/i.test(a)||/rim\stablet/i.test(a)?e={name:"BlackBerry",blackberry:b,version:k||c(/blackberry[\d]+\/(\d+(\.\d+)?)/i)}:/(web|hpw)os/i.test(a)?(e={name:"WebOS",webos:b,version:k||c(/w(?:eb)?osbrowser\/(\d+(\.\d+)?)/i)},/touchpad\//i.test(a)&&(e.touchpad=b)):e=/bada/i.test(a)?{name:"Bada",bada:b,version:c(/dolfin\/(\d+(\.\d+)?)/i)}:/tizen/i.test(a)?{name:"Tizen",tizen:b,version:c(/(?:tizen\s?)?browser\/(\d+(\.\d+)?)/i)||k}:/safari/i.test(a)?{name:"Safari",safari:b,version:k}:{name:c(/^(.*)\/(.*) /),version:d(/^(.*)\/(.*) /)},!e.msedge&&/(apple)?webkit/i.test(a)?(e.name=e.name||"Webkit",e.webkit=b,!e.version&&k&&(e.version=k)):!e.opera&&/gecko\//i.test(a)&&(e.name=e.name||"Gecko",e.gecko=b,e.version=e.version||c(/gecko\/(\d+(\.\d+)?)/i)),e.msedge||!h&&!e.silk?f&&(e[f]=b,e.ios=b):e.android=b;var n="";e.windowsphone?n=c(/windows phone (?:os)?\s?(\d+(\.\d+)*)/i):f?(n=c(/os (\d+([_\s]\d+)*) like mac os x/i),n=n.replace(/[_\s]/g,".")):h?n=c(/android[ \/-](\d+(\.\d+)*)/i):e.webos?n=c(/(?:web|hpw)os\/(\d+(\.\d+)*)/i):e.blackberry?n=c(/rim\stablet\sos\s(\d+(\.\d+)*)/i):e.bada?n=c(/bada\/(\d+(\.\d+)*)/i):e.tizen&&(n=c(/tizen[\/\s](\d+(\.\d+)*)/i)),n&&(e.osversion=n);var o=n.split(".")[0];return l||"ipad"==f||h&&(3==o||4==o&&!m)||e.silk?e.tablet=b:(m||"iphone"==f||"ipod"==f||h||e.blackberry||e.webos||e.bada)&&(e.mobile=b),e.msedge||e.msie&&e.version>=10||e.yandexbrowser&&e.version>=15||e.chrome&&e.version>=20||e.firefox&&e.version>=20||e.safari&&e.version>=6||e.opera&&e.version>=10||e.ios&&e.osversion&&e.osversion.split(".")[0]>=6||e.blackberry&&e.version>=10.1?e.a=b:e.msie&&e.version<10||e.chrome&&e.version<20||e.firefox&&e.version<20||e.safari&&e.version<6||e.opera&&e.version<10||e.ios&&e.osversion&&e.osversion.split(".")[0]<6?e.c=b:e.x=b,e}var b=!0,c=a("undefined"!=typeof navigator?navigator.userAgent:"");return c.test=function(a){for(var b=0;b=43?!0:!1;if(d.firefox)return d.version>=41?!0:!1}return e.apply(this,arguments)}},{bowser:1}]},{},[2]);
+(function() {
+ "use strict";
+
+ var diffcount;
+
+ var Diff = function (options) {
+ var diff = this;
+ Object.keys(options).forEach(function(option) {
+ diff[option] = options[option];
+ });
+ };
+
+ Diff.prototype = {
+ toString: function() {
+ return JSON.stringify(this);
+ }
+
+ // TODO: compress diff output by replacing these keys with numbers or alike:
+ /* 'addAttribute' = 0,
+ 'modifyAttribute' = 1,
+ 'removeAttribute' = 2,
+ 'modifyTextElement' = 3,
+ 'relocateGroup' = 4,
+ 'removeElement' = 5,
+ 'addElement' = 6,
+ 'removeTextElement' = 7,
+ 'addTextElement' = 8,
+ 'replaceElement' = 9,
+ 'modifyValue' = 10,
+ 'modifyChecked' = 11,
+ 'modifySelected' = 12,
+ 'modifyComment' = 13,
+ 'action' = 14,
+ 'route' = 15,
+ 'oldValue' = 16,
+ 'newValue' = 17,
+ 'element' = 18,
+ 'group' = 19,
+ 'from' = 20,
+ 'to' = 21,
+ 'name' = 22,
+ 'value' = 23,
+ 'data' = 24,
+ 'attributes' = 25,
+ 'nodeName' = 26,
+ 'childNodes' = 27,
+ 'checked' = 28,
+ 'selected' = 29;*/
+ };
+
+ var SubsetMapping = function SubsetMapping(a, b) {
+ this.oldValue = a;
+ this.newValue = b;
+ };
+
+ SubsetMapping.prototype = {
+ contains: function contains(subset) {
+ if (subset.length < this.length) {
+ return subset.newValue >= this.newValue && subset.newValue < this.newValue + this.length;
+ }
+ return false;
+ },
+ toString: function toString() {
+ return this.length + " element subset, first mapping: old " + this.oldValue + " → new " + this.newValue;
+ }
+ };
+
+ var elementDescriptors = function(el) {
+ var output = [];
+ if (el.nodeName !== '#text' && el.nodeName !== '#comment') {
+ output.push(el.nodeName);
+ if (el.attributes) {
+ if (el.attributes['class']) {
+ output.push(el.nodeName + '.' + el.attributes['class'].replace(/ /g, '.'));
+ }
+ if (el.attributes.id) {
+ output.push(el.nodeName + '#' + el.attributes.id);
+ }
+ }
+
+ }
+ return output;
+ };
+
+ var findUniqueDescriptors = function(li) {
+ var uniqueDescriptors = {},
+ duplicateDescriptors = {};
+
+ li.forEach(function(node) {
+ elementDescriptors(node).forEach(function(descriptor) {
+ var inUnique = descriptor in uniqueDescriptors,
+ inDupes = descriptor in duplicateDescriptors;
+ if (!inUnique && !inDupes) {
+ uniqueDescriptors[descriptor] = true;
+ } else if (inUnique) {
+ delete uniqueDescriptors[descriptor];
+ duplicateDescriptors[descriptor] = true;
+ }
+ });
+
+ });
+
+ return uniqueDescriptors;
+ };
+
+ var uniqueInBoth = function(l1, l2) {
+ var l1Unique = findUniqueDescriptors(l1),
+ l2Unique = findUniqueDescriptors(l2),
+ inBoth = {};
+
+ Object.keys(l1Unique).forEach(function(key) {
+ if (l2Unique[key]) {
+ inBoth[key] = true;
+ }
+ });
+
+ return inBoth;
+ };
+
+ var removeDone = function(tree) {
+ delete tree.outerDone;
+ delete tree.innerDone;
+ delete tree.valueDone;
+ if (tree.childNodes) {
+ return tree.childNodes.every(removeDone);
+ } else {
+ return true;
+ }
+ };
+
+ var isEqual = function(e1, e2) {
+
+ var e1Attributes, e2Attributes;
+
+ if (!['nodeName', 'value', 'checked', 'selected', 'data'].every(function(element) {
+ if (e1[element] !== e2[element]) {
+ return false;
+ }
+ return true;
+ })) {
+ return false;
+ }
+
+ if (Boolean(e1.attributes) !== Boolean(e2.attributes)) {
+ return false;
+ }
+
+ if (Boolean(e1.childNodes) !== Boolean(e2.childNodes)) {
+ return false;
+ }
+
+ if (e1.attributes) {
+ e1Attributes = Object.keys(e1.attributes);
+ e2Attributes = Object.keys(e2.attributes);
+
+ if (e1Attributes.length !== e2Attributes.length) {
+ return false;
+ }
+ if (!e1Attributes.every(function(attribute) {
+ if (e1.attributes[attribute] !== e2.attributes[attribute]) {
+ return false;
+ }
+ })) {
+ return false;
+ }
+ }
+
+ if (e1.childNodes) {
+ if (e1.childNodes.length !== e2.childNodes.length) {
+ return false;
+ }
+ if (!e1.childNodes.every(function(childNode, index) {
+ return isEqual(childNode, e2.childNodes[index]);
+ })) {
+
+ return false;
+ }
+
+ }
+
+ return true;
+
+ };
+
+
+ var roughlyEqual = function(e1, e2, uniqueDescriptors, sameSiblings, preventRecursion) {
+ var childUniqueDescriptors, nodeList1, nodeList2;
+
+ if (!e1 || !e2) {
+ return false;
+ }
+
+ if (e1.nodeName !== e2.nodeName) {
+ return false;
+ }
+
+ if (e1.nodeName === '#text') {
+ // Note that we initially don't care what the text content of a node is,
+ // the mere fact that it's the same tag and "has text" means it's roughly
+ // equal, and then we can find out the true text difference later.
+ return preventRecursion ? true : e1.data === e2.data;
+ }
+
+
+ if (e1.nodeName in uniqueDescriptors) {
+ return true;
+ }
+
+ if (e1.attributes && e2.attributes) {
+
+ if (e1.attributes.id && e1.attributes.id === e2.attributes.id) {
+ var idDescriptor = e1.nodeName + '#' + e1.attributes.id;
+ if (idDescriptor in uniqueDescriptors) {
+ return true;
+ }
+ }
+ if (e1.attributes['class'] && e1.attributes['class'] === e2.attributes['class']) {
+ var classDescriptor = e1.nodeName + '.' + e1.attributes['class'].replace(/ /g, '.');
+ if (classDescriptor in uniqueDescriptors) {
+ return true;
+ }
+ }
+ }
+
+ if (sameSiblings) {
+ return true;
+ }
+
+ nodeList1 = e1.childNodes ? e1.childNodes.slice().reverse() : [];
+ nodeList2 = e2.childNodes ? e2.childNodes.slice().reverse() : [];
+
+ if (nodeList1.length !== nodeList2.length) {
+ return false;
+ }
+
+ if (preventRecursion) {
+ return nodeList1.every(function(element, index) {
+ return element.nodeName === nodeList2[index].nodeName;
+ });
+ } else {
+ // note: we only allow one level of recursion at any depth. If 'preventRecursion'
+ // was not set, we must explicitly force it to true for child iterations.
+ childUniqueDescriptors = uniqueInBoth(nodeList1, nodeList2);
+ return nodeList1.every(function(element, index) {
+ return roughlyEqual(element, nodeList2[index], childUniqueDescriptors, true, true);
+ });
+ }
+ };
+
+
+ var cloneObj = function(obj) {
+ // TODO: Do we really need to clone here? Is it not enough to just return the original object?
+ return JSON.parse(JSON.stringify(obj));
+ //return obj;
+ };
+
+ /**
+ * based on https://en.wikibooks.org/wiki/Algorithm_implementation/Strings/Longest_common_substring#JavaScript
+ */
+ var findCommonSubsets = function(c1, c2, marked1, marked2) {
+ var lcsSize = 0,
+ index = [],
+ matches = Array.apply(null, new Array(c1.length + 1)).map(function() {
+ return [];
+ }), // set up the matching table
+ uniqueDescriptors = uniqueInBoth(c1, c2),
+ // If all of the elements are the same tag, id and class, then we can
+ // consider them roughly the same even if they have a different number of
+ // children. This will reduce removing and re-adding similar elements.
+ subsetsSame = c1.length === c2.length,
+ origin, ret;
+
+ if (subsetsSame) {
+
+ c1.some(function(element, i) {
+ var c1Desc = elementDescriptors(element),
+ c2Desc = elementDescriptors(c2[i]);
+ if (c1Desc.length !== c2Desc.length) {
+ subsetsSame = false;
+ return true;
+ }
+ c1Desc.some(function(description, i) {
+ if (description !== c2Desc[i]) {
+ subsetsSame = false;
+ return true;
+ }
+ });
+ if (!subsetsSame) {
+ return true;
+ }
+
+ });
+ }
+
+ // fill the matches with distance values
+ c1.forEach(function(c1Element, c1Index) {
+ c2.forEach(function(c2Element, c2Index) {
+ if (!marked1[c1Index] && !marked2[c2Index] && roughlyEqual(c1Element, c2Element, uniqueDescriptors, subsetsSame)) {
+ matches[c1Index + 1][c2Index + 1] = (matches[c1Index][c2Index] ? matches[c1Index][c2Index] + 1 : 1);
+ if (matches[c1Index + 1][c2Index + 1] >= lcsSize) {
+ lcsSize = matches[c1Index + 1][c2Index + 1];
+ index = [c1Index + 1, c2Index + 1];
+ }
+ } else {
+ matches[c1Index + 1][c2Index + 1] = 0;
+ }
+ });
+ });
+ if (lcsSize === 0) {
+ return false;
+ }
+ origin = [index[0] - lcsSize, index[1] - lcsSize];
+ ret = new SubsetMapping(origin[0], origin[1]);
+ ret.length = lcsSize;
+
+ return ret;
+ };
+
+ /**
+ * This should really be a predefined function in Array...
+ */
+ var makeArray = function(n, v) {
+ return Array.apply(null, new Array(n)).map(function() {
+ return v;
+ });
+ };
+
+ /**
+ * Generate arrays that indicate which node belongs to which subset,
+ * or whether it's actually an orphan node, existing in only one
+ * of the two trees, rather than somewhere in both.
+ *
+ * So if t1 = ![]()