diff --git a/pagure/lib/git.py b/pagure/lib/git.py
index d4a3ff7..91bd240 100644
--- a/pagure/lib/git.py
+++ b/pagure/lib/git.py
@@ -43,7 +43,8 @@ from pagure.lib import tasks
 _log = logging.getLogger(__name__)
 
 
-def commit_to_patch(repo_obj, commits, diff_view=False):
+def commit_to_patch(repo_obj, commits,
+                    diff_view=False, find_similar=False):
     ''' For a given commit (PyGit2 commit object) of a specified git repo,
     returns a string representation of the changes the commit did in a
     format that allows it to be used as patch.
@@ -56,6 +57,9 @@ def commit_to_patch(repo_obj, commits, diff_view=False):
     :kwarg diff_view: a boolean specifying if what is returned is a git
         patch or a git diff
     :type diff_view: boolean
+    :kwarg find_similar: a boolean specifying if what we run find_similar
+        on the diff to group renamed files
+    :type find_similar: boolean
     :return: the patch or diff representation of the provided commits
     :rtype: str
 
@@ -70,6 +74,10 @@ def commit_to_patch(repo_obj, commits, diff_view=False):
         else:
             # First commit in the repo
             diff = commit.tree.diff_to_tree(swap=True)
+
+        if find_similar and diff:
+            diff.find_similar()
+
         if diff_view:
             patch.append(diff.patch)
         else:
diff --git a/pagure/static/pagure.css b/pagure/static/pagure.css
index b0287f4..314b01a 100644
--- a/pagure/static/pagure.css
+++ b/pagure/static/pagure.css
@@ -455,6 +455,7 @@ color: #bbb;
   font-family: "Open Sans";
   background: transparent;
   padding: 0;
+  font-size: 100%;
 }
 
 .card pre
@@ -862,5 +863,11 @@ a.nav-link.btn{
   border:0;
 }
 
- 
+.diff2html-output .d2h-file-header{
+  display: none;
+}
 
+.diff2html-output .d2h-file-wrapper{
+  border: 0;
+  margin: 0;
+}
diff --git a/pagure/static/vendor/diff2html/INFO b/pagure/static/vendor/diff2html/INFO
new file mode 100644
index 0000000..19dfa49
--- /dev/null
+++ b/pagure/static/vendor/diff2html/INFO
@@ -0,0 +1,4 @@
+The version of diff2html in this directory is 2.4.0
+
+This was downloaded from:
+https://github.com/rtfpessoa/diff2html/releases/tag/v2.4.0
diff --git a/pagure/static/vendor/diff2html/diff2html-ui.js b/pagure/static/vendor/diff2html/diff2html-ui.js
new file mode 100644
index 0000000..1a38db7
--- /dev/null
+++ b/pagure/static/vendor/diff2html/diff2html-ui.js
@@ -0,0 +1,366 @@
+(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
+(function (global){
+/*
+ *
+ * Diff to HTML (diff2html-ui.js)
+ * Author: rtfpessoa
+ *
+ * Depends on: [ jQuery ]
+ * Optional dependencies on: [ highlight.js ]
+ *
+ */
+
+/*global $, hljs, Diff2Html*/
+
+(function() {
+  var highlightJS = require('./highlight.js-internals.js').HighlightJS;
+
+  var diffJson = null;
+  var defaultTarget = 'body';
+  var currentSelectionColumnId = -1;
+
+  function Diff2HtmlUI(config) {
+    var cfg = config || {};
+
+    if (cfg.diff) {
+      diffJson = Diff2Html.getJsonFromDiff(cfg.diff);
+    } else if (cfg.json) {
+      diffJson = cfg.json;
+    }
+
+    this._initSelection();
+  }
+
+  Diff2HtmlUI.prototype.draw = function(targetId, config) {
+    var cfg = config || {};
+    cfg.inputFormat = 'json';
+    var $target = this._getTarget(targetId);
+    $target.html(Diff2Html.getPrettyHtml(diffJson, cfg));
+
+    if (cfg.synchronisedScroll) {
+      this.synchronisedScroll($target, cfg);
+    }
+  };
+
+  Diff2HtmlUI.prototype.synchronisedScroll = function(targetId) {
+    var $target = this._getTarget(targetId);
+    $target.find('.d2h-file-side-diff').scroll(function() {
+      var $this = $(this);
+      $this.closest('.d2h-file-wrapper').find('.d2h-file-side-diff')
+        .scrollLeft($this.scrollLeft());
+    });
+  };
+
+  Diff2HtmlUI.prototype.fileListCloseable = function(targetId, startVisible) {
+    var $target = this._getTarget(targetId);
+
+    var hashTag = this._getHashTag();
+
+    var $showBtn = $target.find('.d2h-show');
+    var $hideBtn = $target.find('.d2h-hide');
+    var $fileList = $target.find('.d2h-file-list');
+
+    if (hashTag === 'files-summary-show') show();
+    else if (hashTag === 'files-summary-hide') hide();
+    else if (startVisible) show();
+    else hide();
+
+    $showBtn.click(show);
+    $hideBtn.click(hide);
+
+    function show() {
+      $showBtn.hide();
+      $hideBtn.show();
+      $fileList.show();
+    }
+
+    function hide() {
+      $hideBtn.hide();
+      $showBtn.show();
+      $fileList.hide();
+    }
+  };
+
+  Diff2HtmlUI.prototype.highlightCode = function(targetId) {
+    var that = this;
+
+    var $target = that._getTarget(targetId);
+
+    // collect all the diff files and execute the highlight on their lines
+    var $files = $target.find('.d2h-file-wrapper');
+    $files.map(function(_i, file) {
+      var oldLinesState;
+      var newLinesState;
+      var $file = $(file);
+      var language = $file.data('lang');
+
+      // collect all the code lines and execute the highlight on them
+      var $codeLines = $file.find('.d2h-code-line-ctn');
+      $codeLines.map(function(_j, line) {
+        var $line = $(line);
+        var text = line.textContent;
+        var lineParent = line.parentNode;
+
+        var lineState;
+        if (lineParent.className.indexOf('d2h-del') !== -1) {
+          lineState = oldLinesState;
+        } else {
+          lineState = newLinesState;
+        }
+
+        var result = hljs.getLanguage(language) ? hljs.highlight(language, text, true, lineState) : hljs.highlightAuto(text);
+
+        if (lineParent.className.indexOf('d2h-del') !== -1) {
+          oldLinesState = result.top;
+        } else if (lineParent.className.indexOf('d2h-ins') !== -1) {
+          newLinesState = result.top;
+        } else {
+          oldLinesState = result.top;
+          newLinesState = result.top;
+        }
+
+        var originalStream = highlightJS.nodeStream(line);
+        if (originalStream.length) {
+          var resultNode = document.createElementNS('http://www.w3.org/1999/xhtml', 'div');
+          resultNode.innerHTML = result.value;
+          result.value = highlightJS.mergeStreams(originalStream, highlightJS.nodeStream(resultNode), text);
+        }
+
+        $line.addClass('hljs');
+        $line.addClass(result.language);
+        $line.html(result.value);
+      });
+    });
+  };
+
+  Diff2HtmlUI.prototype._getTarget = function(targetId) {
+    var $target;
+
+    if (typeof targetId === 'object' && targetId instanceof jQuery) {
+      $target = targetId;
+    } else if (typeof targetId === 'string') {
+      $target = $(targetId);
+    } else {
+      console.error("Wrong target provided! Falling back to default value 'body'.");
+      console.log('Please provide a jQuery object or a valid DOM query string.');
+      $target = $(defaultTarget);
+    }
+
+    return $target;
+  };
+
+  Diff2HtmlUI.prototype._getHashTag = function() {
+    var docUrl = document.URL;
+    var hashTagIndex = docUrl.indexOf('#');
+
+    var hashTag = null;
+    if (hashTagIndex !== -1) {
+      hashTag = docUrl.substr(hashTagIndex + 1);
+    }
+
+    return hashTag;
+  };
+
+  Diff2HtmlUI.prototype._distinct = function(collection) {
+    return collection.filter(function(v, i) {
+      return collection.indexOf(v) === i;
+    });
+  };
+
+  Diff2HtmlUI.prototype._initSelection = function() {
+    var body = $('body');
+    var that = this;
+
+    body.on('mousedown', '.d2h-diff-table', function(event) {
+      var target = $(event.target);
+      var table = target.closest('.d2h-diff-table');
+
+      if (target.closest('.d2h-code-line,.d2h-code-side-line').length) {
+        table.removeClass('selecting-left');
+        table.addClass('selecting-right');
+        currentSelectionColumnId = 1;
+      } else if (target.closest('.d2h-code-linenumber,.d2h-code-side-linenumber').length) {
+        table.removeClass('selecting-right');
+        table.addClass('selecting-left');
+        currentSelectionColumnId = 0;
+      }
+    });
+
+    body.on('copy', '.d2h-diff-table', function(event) {
+      var clipboardData = event.originalEvent.clipboardData;
+      var text = that._getSelectedText();
+      clipboardData.setData('text', text);
+      event.preventDefault();
+    });
+  };
+
+  Diff2HtmlUI.prototype._getSelectedText = function() {
+    var sel = window.getSelection();
+    var range = sel.getRangeAt(0);
+    var doc = range.cloneContents();
+    var nodes = doc.querySelectorAll('tr');
+    var text = '';
+    var idx = currentSelectionColumnId;
+
+    if (nodes.length === 0) {
+      text = doc.textContent;
+    } else {
+      [].forEach.call(nodes, function(tr, i) {
+        var td = tr.cells[tr.cells.length === 1 ? 0 : idx];
+        text += (i ? '\n' : '') + td.textContent.replace(/(?:\r\n|\r|\n)/g, '');
+      });
+    }
+
+    return text;
+  };
+
+  module.exports.Diff2HtmlUI = Diff2HtmlUI;
+
+  // Expose diff2html in the browser
+  global.Diff2HtmlUI = Diff2HtmlUI;
+})();
+
+}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+},{"./highlight.js-internals.js":2}],2:[function(require,module,exports){
+/*
+ *
+ * highlight.js
+ * Author: isagalaev
+ *
+ */
+
+(function() {
+  function HighlightJS() {
+  }
+
+  /*
+   * Copied from Highlight.js Private API
+   * Will be removed when this part of the API is exposed
+   */
+
+  /* Utility vars */
+
+  var ArrayProto = [];
+
+  /* Utility functions */
+
+  function escape(value) {
+    return value.replace(/&/gm, '&amp;').replace(/</gm, '&lt;').replace(/>/gm, '&gt;');
+  }
+
+  function tag(node) {
+    return node.nodeName.toLowerCase();
+  }
+
+  /* Stream merging */
+
+  HighlightJS.prototype.nodeStream = function(node) {
+    var result = [];
+    (function _nodeStream(node, offset) {
+      for (var child = node.firstChild; child; child = child.nextSibling) {
+        if (child.nodeType === 3) {
+          offset += child.nodeValue.length;
+        } else if (child.nodeType === 1) {
+          result.push({
+            event: 'start',
+            offset: offset,
+            node: child
+          });
+          offset = _nodeStream(child, offset);
+          // Prevent void elements from having an end tag that would actually
+          // double them in the output. There are more void elements in HTML
+          // but we list only those realistically expected in code display.
+          if (!tag(child).match(/br|hr|img|input/)) {
+            result.push({
+              event: 'stop',
+              offset: offset,
+              node: child
+            });
+          }
+        }
+      }
+      return offset;
+    })(node, 0);
+    return result;
+  };
+
+  HighlightJS.prototype.mergeStreams = function(original, highlighted, value) {
+    var processed = 0;
+    var result = '';
+    var nodeStack = [];
+
+    function selectStream() {
+      if (!original.length || !highlighted.length) {
+        return original.length ? original : highlighted;
+      }
+      if (original[0].offset !== highlighted[0].offset) {
+        return (original[0].offset < highlighted[0].offset) ? original : highlighted;
+      }
+
+      /*
+       To avoid starting the stream just before it should stop the order is
+       ensured that original always starts first and closes last:
+       if (event1 == 'start' && event2 == 'start')
+       return original;
+       if (event1 == 'start' && event2 == 'stop')
+       return highlighted;
+       if (event1 == 'stop' && event2 == 'start')
+       return original;
+       if (event1 == 'stop' && event2 == 'stop')
+       return highlighted;
+       ... which is collapsed to:
+       */
+      return highlighted[0].event === 'start' ? original : highlighted;
+    }
+
+    function open(node) {
+      function attr_str(a) {
+        return ' ' + a.nodeName + '="' + escape(a.value) + '"';
+      }
+
+      result += '<' + tag(node) + ArrayProto.map.call(node.attributes, attr_str).join('') + '>';
+    }
+
+    function close(node) {
+      result += '</' + tag(node) + '>';
+    }
+
+    function render(event) {
+      (event.event === 'start' ? open : close)(event.node);
+    }
+
+    while (original.length || highlighted.length) {
+      var stream = selectStream();
+      result += escape(value.substring(processed, stream[0].offset));
+      processed = stream[0].offset;
+      if (stream === original) {
+        /*
+         On any opening or closing tag of the original markup we first close
+         the entire highlighted node stack, then render the original tag along
+         with all the following original tags at the same offset and then
+         reopen all the tags on the highlighted stack.
+         */
+        nodeStack.reverse().forEach(close);
+        do {
+          render(stream.splice(0, 1)[0]);
+          stream = selectStream();
+        } while (stream === original && stream.length && stream[0].offset === processed);
+        nodeStack.reverse().forEach(open);
+      } else {
+        if (stream[0].event === 'start') {
+          nodeStack.push(stream[0].node);
+        } else {
+          nodeStack.pop();
+        }
+        render(stream.splice(0, 1)[0]);
+      }
+    }
+    return result + escape(value.substr(processed));
+  };
+
+  /* **** Highlight.js Private API **** */
+
+  module.exports.HighlightJS = new HighlightJS();
+})();
+
+},{}]},{},[1]);
diff --git a/pagure/static/vendor/diff2html/diff2html-ui.min.js b/pagure/static/vendor/diff2html/diff2html-ui.min.js
new file mode 100644
index 0000000..3e049cb
--- /dev/null
+++ b/pagure/static/vendor/diff2html/diff2html-ui.min.js
@@ -0,0 +1 @@
+!function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a="function"==typeof require&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n||e)},l,l.exports,e,t,n,r)}return n[o].exports}for(var i="function"==typeof require&&require,o=0;o<r.length;o++)s(r[o]);return s}({1:[function(require,module,exports){(function(global){!function(){var highlightJS=require("./highlight.js-internals.js").HighlightJS,diffJson=null,currentSelectionColumnId=-1;function Diff2HtmlUI(config){var cfg=config||{};cfg.diff?diffJson=Diff2Html.getJsonFromDiff(cfg.diff):cfg.json&&(diffJson=cfg.json),this._initSelection()}Diff2HtmlUI.prototype.draw=function(targetId,config){var cfg=config||{};cfg.inputFormat="json";var $target=this._getTarget(targetId);$target.html(Diff2Html.getPrettyHtml(diffJson,cfg)),cfg.synchronisedScroll&&this.synchronisedScroll($target,cfg)},Diff2HtmlUI.prototype.synchronisedScroll=function(targetId){this._getTarget(targetId).find(".d2h-file-side-diff").scroll(function(){var $this=$(this);$this.closest(".d2h-file-wrapper").find(".d2h-file-side-diff").scrollLeft($this.scrollLeft())})},Diff2HtmlUI.prototype.fileListCloseable=function(targetId,startVisible){var $target=this._getTarget(targetId),hashTag=this._getHashTag(),$showBtn=$target.find(".d2h-show"),$hideBtn=$target.find(".d2h-hide"),$fileList=$target.find(".d2h-file-list");function show(){$showBtn.hide(),$hideBtn.show(),$fileList.show()}function hide(){$hideBtn.hide(),$showBtn.show(),$fileList.hide()}"files-summary-show"===hashTag?show():"files-summary-hide"===hashTag?hide():startVisible?show():hide(),$showBtn.click(show),$hideBtn.click(hide)},Diff2HtmlUI.prototype.highlightCode=function(targetId){this._getTarget(targetId).find(".d2h-file-wrapper").map(function(_i,file){var oldLinesState,newLinesState,$file=$(file),language=$file.data("lang");$file.find(".d2h-code-line-ctn").map(function(_j,line){var lineState,$line=$(line),text=line.textContent,lineParent=line.parentNode;lineState=-1!==lineParent.className.indexOf("d2h-del")?oldLinesState:newLinesState;var result=hljs.getLanguage(language)?hljs.highlight(language,text,!0,lineState):hljs.highlightAuto(text);-1!==lineParent.className.indexOf("d2h-del")?oldLinesState=result.top:(-1!==lineParent.className.indexOf("d2h-ins")||(oldLinesState=result.top),newLinesState=result.top);var originalStream=highlightJS.nodeStream(line);if(originalStream.length){var resultNode=document.createElementNS("http://www.w3.org/1999/xhtml","div");resultNode.innerHTML=result.value,result.value=highlightJS.mergeStreams(originalStream,highlightJS.nodeStream(resultNode),text)}$line.addClass("hljs"),$line.addClass(result.language),$line.html(result.value)})})},Diff2HtmlUI.prototype._getTarget=function(targetId){var $target;return"object"==typeof targetId&&targetId instanceof jQuery?$target=targetId:"string"==typeof targetId?$target=$(targetId):(console.error("Wrong target provided! Falling back to default value 'body'."),console.log("Please provide a jQuery object or a valid DOM query string."),$target=$("body")),$target},Diff2HtmlUI.prototype._getHashTag=function(){var docUrl=document.URL,hashTagIndex=docUrl.indexOf("#"),hashTag=null;return-1!==hashTagIndex&&(hashTag=docUrl.substr(hashTagIndex+1)),hashTag},Diff2HtmlUI.prototype._distinct=function(collection){return collection.filter(function(v,i){return collection.indexOf(v)===i})},Diff2HtmlUI.prototype._initSelection=function(){var body=$("body"),that=this;body.on("mousedown",".d2h-diff-table",function(event){var target=$(event.target),table=target.closest(".d2h-diff-table");target.closest(".d2h-code-line,.d2h-code-side-line").length?(table.removeClass("selecting-left"),table.addClass("selecting-right"),currentSelectionColumnId=1):target.closest(".d2h-code-linenumber,.d2h-code-side-linenumber").length&&(table.removeClass("selecting-right"),table.addClass("selecting-left"),currentSelectionColumnId=0)}),body.on("copy",".d2h-diff-table",function(event){var clipboardData=event.originalEvent.clipboardData,text=that._getSelectedText();clipboardData.setData("text",text),event.preventDefault()})},Diff2HtmlUI.prototype._getSelectedText=function(){var doc=window.getSelection().getRangeAt(0).cloneContents(),nodes=doc.querySelectorAll("tr"),text="",idx=currentSelectionColumnId;return 0===nodes.length?text=doc.textContent:[].forEach.call(nodes,function(tr,i){var td=tr.cells[1===tr.cells.length?0:idx];text+=(i?"\n":"")+td.textContent.replace(/(?:\r\n|\r|\n)/g,"")}),text},module.exports.Diff2HtmlUI=Diff2HtmlUI,global.Diff2HtmlUI=Diff2HtmlUI}()}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./highlight.js-internals.js":2}],2:[function(require,module,exports){!function(){function HighlightJS(){}var ArrayProto=[];function escape(value){return value.replace(/&/gm,"&amp;").replace(/</gm,"&lt;").replace(/>/gm,"&gt;")}function tag(node){return node.nodeName.toLowerCase()}HighlightJS.prototype.nodeStream=function(node){var result=[];return function _nodeStream(node,offset){for(var child=node.firstChild;child;child=child.nextSibling)3===child.nodeType?offset+=child.nodeValue.length:1===child.nodeType&&(result.push({event:"start",offset:offset,node:child}),offset=_nodeStream(child,offset),tag(child).match(/br|hr|img|input/)||result.push({event:"stop",offset:offset,node:child}));return offset}(node,0),result},HighlightJS.prototype.mergeStreams=function(original,highlighted,value){var processed=0,result="",nodeStack=[];function selectStream(){return original.length&&highlighted.length?original[0].offset!==highlighted[0].offset?original[0].offset<highlighted[0].offset?original:highlighted:"start"===highlighted[0].event?original:highlighted:original.length?original:highlighted}function open(node){result+="<"+tag(node)+ArrayProto.map.call(node.attributes,function(a){return" "+a.nodeName+'="'+escape(a.value)+'"'}).join("")+">"}function close(node){result+="</"+tag(node)+">"}function render(event){("start"===event.event?open:close)(event.node)}for(;original.length||highlighted.length;){var stream=selectStream();if(result+=escape(value.substring(processed,stream[0].offset)),processed=stream[0].offset,stream===original){for(nodeStack.reverse().forEach(close);render(stream.splice(0,1)[0]),(stream=selectStream())===original&&stream.length&&stream[0].offset===processed;);nodeStack.reverse().forEach(open)}else"start"===stream[0].event?nodeStack.push(stream[0].node):nodeStack.pop(),render(stream.splice(0,1)[0])}return result+escape(value.substr(processed))},module.exports.HighlightJS=new HighlightJS}()},{}]},{},[1]);
\ No newline at end of file
diff --git a/pagure/static/vendor/diff2html/diff2html.css b/pagure/static/vendor/diff2html/diff2html.css
new file mode 100644
index 0000000..9edb2e1
--- /dev/null
+++ b/pagure/static/vendor/diff2html/diff2html.css
@@ -0,0 +1,363 @@
+/*
+ *
+ * Diff to HTML (diff2html.css)
+ * Author: rtfpessoa
+ *
+ */
+
+.d2h-wrapper {
+  text-align: left;
+}
+
+.d2h-file-header {
+  padding: 5px 10px;
+  border-bottom: 1px solid #d8d8d8;
+  background-color: #f7f7f7;
+}
+
+.d2h-file-stats {
+  display: flex;
+  margin-left: auto;
+  font-size: 14px;
+}
+
+.d2h-lines-added {
+  text-align: right;
+  border: 1px solid #b4e2b4;
+  border-radius: 5px 0 0 5px;
+  color: #399839;
+  padding: 2px;
+  vertical-align: middle;
+}
+
+.d2h-lines-deleted {
+  text-align: left;
+  border: 1px solid #e9aeae;
+  border-radius: 0 5px 5px 0;
+  color: #c33;
+  padding: 2px;
+  vertical-align: middle;
+  margin-left: 1px;
+}
+
+.d2h-file-name-wrapper {
+  display: flex;
+  align-items: center;
+  width: 100%;
+  font-family: "Source Sans Pro", "Helvetica Neue", Helvetica, Arial, sans-serif;
+  font-size: 15px;
+}
+
+.d2h-file-name {
+  white-space: nowrap;
+  text-overflow: ellipsis;
+  overflow-x: hidden;
+  line-height: 21px;
+}
+
+.d2h-file-wrapper {
+  border: 1px solid #ddd;
+  border-radius: 3px;
+  margin-bottom: 1em;
+}
+
+.d2h-diff-table {
+  width: 100%;
+  border-collapse: collapse;
+  font-family: "Menlo", "Consolas", monospace;
+  font-size: 13px;
+}
+
+.d2h-diff-tbody > tr > td {
+  height: 20px;
+  line-height: 20px;
+}
+
+.d2h-files-diff {
+  display: block;
+  width: 100%;
+  height: 100%;
+}
+
+.d2h-file-diff {
+  overflow-x: scroll;
+  overflow-y: hidden;
+}
+
+.d2h-file-side-diff {
+  display: inline-block;
+  overflow-x: scroll;
+  overflow-y: hidden;
+  width: 50%;
+  margin-right: -4px;
+  margin-bottom: -8px;
+}
+
+.d2h-code-line {
+  display: inline-block;
+  white-space: nowrap;
+  padding: 0 10px;
+  margin-left: 80px;
+}
+
+.d2h-code-side-line {
+  display: inline-block;
+  white-space: nowrap;
+  padding: 0 10px;
+  margin-left: 50px;
+}
+
+.d2h-code-line del,
+.d2h-code-side-line del {
+  display: inline-block;
+  margin-top: -1px;
+  text-decoration: none;
+  background-color: #ffb6ba;
+  border-radius: 0.2em;
+}
+
+.d2h-code-line ins,
+.d2h-code-side-line ins {
+  display: inline-block;
+  margin-top: -1px;
+  text-decoration: none;
+  background-color: #97f295;
+  border-radius: 0.2em;
+  text-align: left;
+}
+
+.d2h-code-line-prefix {
+  display: inline;
+  background: none;
+  padding: 0;
+  word-wrap: normal;
+  white-space: pre;
+}
+
+.d2h-code-line-ctn {
+  display: inline;
+  background: none;
+  padding: 0;
+  word-wrap: normal;
+  white-space: pre;
+}
+
+.line-num1 {
+  box-sizing: border-box;
+  float: left;
+  width: 40px;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  padding-left: 3px;
+}
+
+.line-num2 {
+  box-sizing: border-box;
+  float: right;
+  width: 40px;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  padding-left: 3px;
+}
+
+.d2h-code-linenumber {
+  box-sizing: border-box;
+  position: absolute;
+  width: 86px;
+  padding-left: 2px;
+  padding-right: 2px;
+  background-color: #fff;
+  color: rgba(0, 0, 0, 0.3);
+  text-align: right;
+  border: solid #eeeeee;
+  border-width: 0 1px 0 1px;
+  cursor: pointer;
+}
+
+.d2h-code-side-linenumber {
+  box-sizing: border-box;
+  position: absolute;
+  width: 56px;
+  padding-left: 5px;
+  padding-right: 5px;
+  background-color: #fff;
+  color: rgba(0, 0, 0, 0.3);
+  text-align: right;
+  border: solid #eeeeee;
+  border-width: 0 1px 0 1px;
+  cursor: pointer;
+  overflow: hidden;
+  text-overflow: ellipsis;
+}
+
+/*
+ * Changes Highlight
+ */
+
+.d2h-del {
+  background-color: #fee8e9;
+  border-color: #e9aeae;
+}
+
+.d2h-ins {
+  background-color: #dfd;
+  border-color: #b4e2b4;
+}
+
+.d2h-info {
+  background-color: #f8fafd;
+  color: rgba(0, 0, 0, 0.3);
+  border-color: #d5e4f2;
+}
+
+.d2h-file-diff .d2h-del.d2h-change {
+  background-color: #fdf2d0;
+}
+
+.d2h-file-diff .d2h-ins.d2h-change {
+  background-color: #ded;
+}
+
+/*
+ * File Summary List
+ */
+
+.d2h-file-list-wrapper {
+  margin-bottom: 10px;
+}
+
+.d2h-file-list-wrapper a {
+  text-decoration: none;
+  color: #3572b0;
+}
+
+.d2h-file-list-wrapper a:visited {
+  color: #3572b0;
+}
+
+.d2h-file-list-header {
+  text-align: left;
+}
+
+.d2h-file-list-title {
+  font-weight: bold;
+}
+
+.d2h-file-list-line {
+  display: flex;
+  text-align: left;
+}
+
+.d2h-file-list {
+  display: block;
+  list-style: none;
+  padding: 0;
+  margin: 0;
+}
+
+.d2h-file-list > li {
+  border-bottom: #ddd solid 1px;
+  padding: 5px 10px;
+  margin: 0;
+}
+
+.d2h-file-list > li:last-child {
+  border-bottom: none;
+}
+
+.d2h-file-switch {
+  display: none;
+  font-size: 10px;
+  cursor: pointer;
+}
+
+.d2h-icon-wrapper {
+  line-height: 31px;
+}
+
+.d2h-icon {
+  vertical-align: middle;
+  margin-right: 10px;
+  fill: currentColor;
+}
+
+.d2h-deleted {
+  color: #c33;
+}
+
+.d2h-added {
+  color: #399839;
+}
+
+.d2h-changed {
+  color: #d0b44c;
+}
+
+.d2h-moved {
+  color: #3572b0;
+}
+
+.d2h-tag {
+  display: flex;
+  font-size: 10px;
+  margin-left: 5px;
+  padding: 0 2px;
+  background-color: #fff;
+}
+
+.d2h-deleted-tag {
+  border: #c33 1px solid;
+}
+
+.d2h-added-tag {
+  border: #399839 1px solid;
+}
+
+.d2h-changed-tag {
+  border: #d0b44c 1px solid;
+}
+
+.d2h-moved-tag {
+  border: #3572b0 1px solid;
+}
+
+/*
+ * Selection util.
+ */
+
+.selecting-left .d2h-code-line,
+.selecting-left .d2h-code-line *,
+.selecting-right td.d2h-code-linenumber,
+.selecting-right td.d2h-code-linenumber *,
+.selecting-left .d2h-code-side-line,
+.selecting-left .d2h-code-side-line *,
+.selecting-right td.d2h-code-side-linenumber,
+.selecting-right td.d2h-code-side-linenumber * {
+  -webkit-touch-callout: none;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+}
+
+.selecting-left .d2h-code-line::-moz-selection,
+.selecting-left .d2h-code-line *::-moz-selection,
+.selecting-right td.d2h-code-linenumber::-moz-selection,
+.selecting-left .d2h-code-side-line::-moz-selection,
+.selecting-left .d2h-code-side-line *::-moz-selection,
+.selecting-right td.d2h-code-side-linenumber::-moz-selection,
+.selecting-right td.d2h-code-side-linenumber *::-moz-selection {
+  background: transparent;
+}
+
+.selecting-left .d2h-code-line::selection,
+.selecting-left .d2h-code-line *::selection,
+.selecting-right td.d2h-code-linenumber::selection,
+.selecting-left .d2h-code-side-line::selection,
+.selecting-left .d2h-code-side-line *::selection,
+.selecting-right td.d2h-code-side-linenumber::selection,
+.selecting-right td.d2h-code-side-linenumber *::selection {
+  background: transparent;
+}
+
+/*# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy91aS9jc3MvZGlmZjJodG1sLmNzcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7R0FLRzs7QUFFSDtFQUNFLGlCQUFpQjtDQUNsQjs7QUFFRDtFQUNFLGtCQUFrQjtFQUNsQixpQ0FBaUM7RUFDakMsMEJBQTBCO0NBQzNCOztBQUVEO0VBR0UsY0FBYztFQUNkLGtCQUFrQjtFQUNsQixnQkFBZ0I7Q0FDakI7O0FBRUQ7RUFDRSxrQkFBa0I7RUFDbEIsMEJBQTBCO0VBQzFCLDJCQUEyQjtFQUMzQixlQUFlO0VBQ2YsYUFBYTtFQUNiLHVCQUF1QjtDQUN4Qjs7QUFFRDtFQUNFLGlCQUFpQjtFQUNqQiwwQkFBMEI7RUFDMUIsMkJBQTJCO0VBQzNCLFlBQVk7RUFDWixhQUFhO0VBQ2IsdUJBQXVCO0VBQ3ZCLGlCQUFpQjtDQUNsQjs7QUFFRDtFQUdFLGNBQWM7RUFHZCxvQkFBb0I7RUFDcEIsWUFBWTtFQUNaLCtFQUErRTtFQUMvRSxnQkFBZ0I7Q0FDakI7O0FBRUQ7RUFDRSxvQkFBb0I7RUFDcEIsd0JBQXdCO0VBQ3hCLG1CQUFtQjtFQUNuQixrQkFBa0I7Q0FDbkI7O0FBRUQ7RUFDRSx1QkFBdUI7RUFDdkIsbUJBQW1CO0VBQ25CLG1CQUFtQjtDQUNwQjs7QUFFRDtFQUNFLFlBQVk7RUFDWiwwQkFBMEI7RUFDMUIsNENBQTRDO0VBQzVDLGdCQUFnQjtDQUNqQjs7QUFFRDtFQUNFLGFBQWE7RUFDYixrQkFBa0I7Q0FDbkI7O0FBRUQ7RUFDRSxlQUFlO0VBQ2YsWUFBWTtFQUNaLGFBQWE7Q0FDZDs7QUFFRDtFQUNFLG1CQUFtQjtFQUNuQixtQkFBbUI7Q0FDcEI7O0FBRUQ7RUFDRSxzQkFBc0I7RUFDdEIsbUJBQW1CO0VBQ25CLG1CQUFtQjtFQUNuQixXQUFXO0VBQ1gsbUJBQW1CO0VBQ25CLG9CQUFvQjtDQUNyQjs7QUFFRDtFQUNFLHNCQUFzQjtFQUN0QixvQkFBb0I7RUFDcEIsZ0JBQWdCO0VBQ2hCLGtCQUFrQjtDQUNuQjs7QUFFRDtFQUNFLHNCQUFzQjtFQUN0QixvQkFBb0I7RUFDcEIsZ0JBQWdCO0VBQ2hCLGtCQUFrQjtDQUNuQjs7QUFFRDs7RUFFRSxzQkFBc0I7RUFDdEIsaUJBQWlCO0VBQ2pCLHNCQUFzQjtFQUN0QiwwQkFBMEI7RUFDMUIscUJBQXFCO0NBQ3RCOztBQUVEOztFQUVFLHNCQUFzQjtFQUN0QixpQkFBaUI7RUFDakIsc0JBQXNCO0VBQ3RCLDBCQUEwQjtFQUMxQixxQkFBcUI7RUFDckIsaUJBQWlCO0NBQ2xCOztBQUVEO0VBQ0UsZ0JBQWdCO0VBQ2hCLGlCQUFpQjtFQUNqQixXQUFXO0VBQ1gsa0JBQWtCO0VBQ2xCLGlCQUFpQjtDQUNsQjs7QUFFRDtFQUNFLGdCQUFnQjtFQUNoQixpQkFBaUI7RUFDakIsV0FBVztFQUNYLGtCQUFrQjtFQUNsQixpQkFBaUI7Q0FDbEI7O0FBRUQ7RUFDRSx1QkFBdUI7RUFDdkIsWUFBWTtFQUNaLFlBQVk7RUFDWixpQkFBaUI7RUFDakIsd0JBQXdCO0VBQ3hCLGtCQUFrQjtDQUNuQjs7QUFFRDtFQUNFLHVCQUF1QjtFQUN2QixhQUFhO0VBQ2IsWUFBWTtFQUNaLGlCQUFpQjtFQUNqQix3QkFBd0I7RUFDeEIsa0JBQWtCO0NBQ25COztBQUVEO0VBQ0UsdUJBQXVCO0VBQ3ZCLG1CQUFtQjtFQUNuQixZQUFZO0VBQ1osa0JBQWtCO0VBQ2xCLG1CQUFtQjtFQUNuQix1QkFBdUI7RUFDdkIsMEJBQTBCO0VBQzFCLGtCQUFrQjtFQUNsQixzQkFBc0I7RUFDdEIsMEJBQTBCO0VBQzFCLGdCQUFnQjtDQUNqQjs7QUFFRDtFQUNFLHVCQUF1QjtFQUN2QixtQkFBbUI7RUFDbkIsWUFBWTtFQUNaLGtCQUFrQjtFQUNsQixtQkFBbUI7RUFDbkIsdUJBQXVCO0VBQ3ZCLDBCQUEwQjtFQUMxQixrQkFBa0I7RUFDbEIsc0JBQXNCO0VBQ3RCLDBCQUEwQjtFQUMxQixnQkFBZ0I7RUFDaEIsaUJBQWlCO0VBQ2pCLHdCQUF3QjtDQUN6Qjs7QUFFRDs7R0FFRzs7QUFFSDtFQUNFLDBCQUEwQjtFQUMxQixzQkFBc0I7Q0FDdkI7O0FBRUQ7RUFDRSx1QkFBdUI7RUFDdkIsc0JBQXNCO0NBQ3ZCOztBQUVEO0VBQ0UsMEJBQTBCO0VBQzFCLDBCQUEwQjtFQUMxQixzQkFBc0I7Q0FDdkI7O0FBRUQ7RUFDRSwwQkFBMEI7Q0FDM0I7O0FBRUQ7RUFDRSx1QkFBdUI7Q0FDeEI7O0FBRUQ7O0dBRUc7O0FBRUg7RUFDRSxvQkFBb0I7Q0FDckI7O0FBRUQ7RUFDRSxzQkFBc0I7RUFDdEIsZUFBZTtDQUNoQjs7QUFFRDtFQUNFLGVBQWU7Q0FDaEI7O0FBRUQ7RUFDRSxpQkFBaUI7Q0FDbEI7O0FBRUQ7RUFDRSxrQkFBa0I7Q0FDbkI7O0FBRUQ7RUFHRSxjQUFjO0VBQ2QsaUJBQWlCO0NBQ2xCOztBQUVEO0VBQ0UsZUFBZTtFQUNmLGlCQUFpQjtFQUNqQixXQUFXO0VBQ1gsVUFBVTtDQUNYOztBQUVEO0VBQ0UsOEJBQThCO0VBQzlCLGtCQUFrQjtFQUNsQixVQUFVO0NBQ1g7O0FBRUQ7RUFDRSxvQkFBb0I7Q0FDckI7O0FBRUQ7RUFDRSxjQUFjO0VBQ2QsZ0JBQWdCO0VBQ2hCLGdCQUFnQjtDQUNqQjs7QUFFRDtFQUNFLGtCQUFrQjtDQUNuQjs7QUFFRDtFQUNFLHVCQUF1QjtFQUN2QixtQkFBbUI7RUFDbkIsbUJBQW1CO0NBQ3BCOztBQUVEO0VBQ0UsWUFBWTtDQUNiOztBQUVEO0VBQ0UsZUFBZTtDQUNoQjs7QUFFRDtFQUNFLGVBQWU7Q0FDaEI7O0FBRUQ7RUFDRSxlQUFlO0NBQ2hCOztBQUVEO0VBR0UsY0FBYztFQUNkLGdCQUFnQjtFQUNoQixpQkFBaUI7RUFDakIsZUFBZTtFQUNmLHVCQUF1QjtDQUN4Qjs7QUFFRDtFQUNFLHVCQUF1QjtDQUN4Qjs7QUFFRDtFQUNFLDBCQUEwQjtDQUMzQjs7QUFFRDtFQUNFLDBCQUEwQjtDQUMzQjs7QUFFRDtFQUNFLDBCQUEwQjtDQUMzQjs7QUFFRDs7R0FFRzs7QUFFSDs7Ozs7Ozs7RUFRRSw0QkFBNEI7RUFDNUIsMEJBQTBCO0VBQzFCLHVCQUF1QjtFQUN2QixzQkFBc0I7RUFDdEIsa0JBQWtCO0NBQ25COztBQUVEOzs7Ozs7O0VBT0Usd0JBQXdCO0NBQ3pCOztBQUVEOzs7Ozs7O0VBT0Usd0JBQXdCO0NBQ3pCIiwiZmlsZSI6ImRpZmYyaHRtbC5jc3MiLCJzb3VyY2VzQ29udGVudCI6WyIvKlxuICpcbiAqIERpZmYgdG8gSFRNTCAoZGlmZjJodG1sLmNzcylcbiAqIEF1dGhvcjogcnRmcGVzc29hXG4gKlxuICovXG5cbi5kMmgtd3JhcHBlciB7XG4gIHRleHQtYWxpZ246IGxlZnQ7XG59XG5cbi5kMmgtZmlsZS1oZWFkZXIge1xuICBwYWRkaW5nOiA1cHggMTBweDtcbiAgYm9yZGVyLWJvdHRvbTogMXB4IHNvbGlkICNkOGQ4ZDg7XG4gIGJhY2tncm91bmQtY29sb3I6ICNmN2Y3Zjc7XG59XG5cbi5kMmgtZmlsZS1zdGF0cyB7XG4gIGRpc3BsYXk6IC13ZWJraXQtYm94O1xuICBkaXNwbGF5OiAtbXMtZmxleGJveDtcbiAgZGlzcGxheTogZmxleDtcbiAgbWFyZ2luLWxlZnQ6IGF1dG87XG4gIGZvbnQtc2l6ZTogMTRweDtcbn1cblxuLmQyaC1saW5lcy1hZGRlZCB7XG4gIHRleHQtYWxpZ246IHJpZ2h0O1xuICBib3JkZXI6IDFweCBzb2xpZCAjYjRlMmI0O1xuICBib3JkZXItcmFkaXVzOiA1cHggMCAwIDVweDtcbiAgY29sb3I6ICMzOTk4Mzk7XG4gIHBhZGRpbmc6IDJweDtcbiAgdmVydGljYWwtYWxpZ246IG1pZGRsZTtcbn1cblxuLmQyaC1saW5lcy1kZWxldGVkIHtcbiAgdGV4dC1hbGlnbjogbGVmdDtcbiAgYm9yZGVyOiAxcHggc29saWQgI2U5YWVhZTtcbiAgYm9yZGVyLXJhZGl1czogMCA1cHggNXB4IDA7XG4gIGNvbG9yOiAjYzMzO1xuICBwYWRkaW5nOiAycHg7XG4gIHZlcnRpY2FsLWFsaWduOiBtaWRkbGU7XG4gIG1hcmdpbi1sZWZ0OiAxcHg7XG59XG5cbi5kMmgtZmlsZS1uYW1lLXdyYXBwZXIge1xuICBkaXNwbGF5OiAtd2Via2l0LWJveDtcbiAgZGlzcGxheTogLW1zLWZsZXhib3g7XG4gIGRpc3BsYXk6IGZsZXg7XG4gIC13ZWJraXQtYm94LWFsaWduOiBjZW50ZXI7XG4gIC1tcy1mbGV4LWFsaWduOiBjZW50ZXI7XG4gIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gIHdpZHRoOiAxMDAlO1xuICBmb250LWZhbWlseTogXCJTb3VyY2UgU2FucyBQcm9cIiwgXCJIZWx2ZXRpY2EgTmV1ZVwiLCBIZWx2ZXRpY2EsIEFyaWFsLCBzYW5zLXNlcmlmO1xuICBmb250LXNpemU6IDE1cHg7XG59XG5cbi5kMmgtZmlsZS1uYW1lIHtcbiAgd2hpdGUtc3BhY2U6IG5vd3JhcDtcbiAgdGV4dC1vdmVyZmxvdzogZWxsaXBzaXM7XG4gIG92ZXJmbG93LXg6IGhpZGRlbjtcbiAgbGluZS1oZWlnaHQ6IDIxcHg7XG59XG5cbi5kMmgtZmlsZS13cmFwcGVyIHtcbiAgYm9yZGVyOiAxcHggc29saWQgI2RkZDtcbiAgYm9yZGVyLXJhZGl1czogM3B4O1xuICBtYXJnaW4tYm90dG9tOiAxZW07XG59XG5cbi5kMmgtZGlmZi10YWJsZSB7XG4gIHdpZHRoOiAxMDAlO1xuICBib3JkZXItY29sbGFwc2U6IGNvbGxhcHNlO1xuICBmb250LWZhbWlseTogXCJNZW5sb1wiLCBcIkNvbnNvbGFzXCIsIG1vbm9zcGFjZTtcbiAgZm9udC1zaXplOiAxM3B4O1xufVxuXG4uZDJoLWRpZmYtdGJvZHkgPiB0ciA+IHRkIHtcbiAgaGVpZ2h0OiAyMHB4O1xuICBsaW5lLWhlaWdodDogMjBweDtcbn1cblxuLmQyaC1maWxlcy1kaWZmIHtcbiAgZGlzcGxheTogYmxvY2s7XG4gIHdpZHRoOiAxMDAlO1xuICBoZWlnaHQ6IDEwMCU7XG59XG5cbi5kMmgtZmlsZS1kaWZmIHtcbiAgb3ZlcmZsb3cteDogc2Nyb2xsO1xuICBvdmVyZmxvdy15OiBoaWRkZW47XG59XG5cbi5kMmgtZmlsZS1zaWRlLWRpZmYge1xuICBkaXNwbGF5OiBpbmxpbmUtYmxvY2s7XG4gIG92ZXJmbG93LXg6IHNjcm9sbDtcbiAgb3ZlcmZsb3cteTogaGlkZGVuO1xuICB3aWR0aDogNTAlO1xuICBtYXJnaW4tcmlnaHQ6IC00cHg7XG4gIG1hcmdpbi1ib3R0b206IC04cHg7XG59XG5cbi5kMmgtY29kZS1saW5lIHtcbiAgZGlzcGxheTogaW5saW5lLWJsb2NrO1xuICB3aGl0ZS1zcGFjZTogbm93cmFwO1xuICBwYWRkaW5nOiAwIDEwcHg7XG4gIG1hcmdpbi1sZWZ0OiA4MHB4O1xufVxuXG4uZDJoLWNvZGUtc2lkZS1saW5lIHtcbiAgZGlzcGxheTogaW5saW5lLWJsb2NrO1xuICB3aGl0ZS1zcGFjZTogbm93cmFwO1xuICBwYWRkaW5nOiAwIDEwcHg7XG4gIG1hcmdpbi1sZWZ0OiA1MHB4O1xufVxuXG4uZDJoLWNvZGUtbGluZSBkZWwsXG4uZDJoLWNvZGUtc2lkZS1saW5lIGRlbCB7XG4gIGRpc3BsYXk6IGlubGluZS1ibG9jaztcbiAgbWFyZ2luLXRvcDogLTFweDtcbiAgdGV4dC1kZWNvcmF0aW9uOiBub25lO1xuICBiYWNrZ3JvdW5kLWNvbG9yOiAjZmZiNmJhO1xuICBib3JkZXItcmFkaXVzOiAwLjJlbTtcbn1cblxuLmQyaC1jb2RlLWxpbmUgaW5zLFxuLmQyaC1jb2RlLXNpZGUtbGluZSBpbnMge1xuICBkaXNwbGF5OiBpbmxpbmUtYmxvY2s7XG4gIG1hcmdpbi10b3A6IC0xcHg7XG4gIHRleHQtZGVjb3JhdGlvbjogbm9uZTtcbiAgYmFja2dyb3VuZC1jb2xvcjogIzk3ZjI5NTtcbiAgYm9yZGVyLXJhZGl1czogMC4yZW07XG4gIHRleHQtYWxpZ246IGxlZnQ7XG59XG5cbi5kMmgtY29kZS1saW5lLXByZWZpeCB7XG4gIGRpc3BsYXk6IGlubGluZTtcbiAgYmFja2dyb3VuZDogbm9uZTtcbiAgcGFkZGluZzogMDtcbiAgd29yZC13cmFwOiBub3JtYWw7XG4gIHdoaXRlLXNwYWNlOiBwcmU7XG59XG5cbi5kMmgtY29kZS1saW5lLWN0biB7XG4gIGRpc3BsYXk6IGlubGluZTtcbiAgYmFja2dyb3VuZDogbm9uZTtcbiAgcGFkZGluZzogMDtcbiAgd29yZC13cmFwOiBub3JtYWw7XG4gIHdoaXRlLXNwYWNlOiBwcmU7XG59XG5cbi5saW5lLW51bTEge1xuICBib3gtc2l6aW5nOiBib3JkZXItYm94O1xuICBmbG9hdDogbGVmdDtcbiAgd2lkdGg6IDQwcHg7XG4gIG92ZXJmbG93OiBoaWRkZW47XG4gIHRleHQtb3ZlcmZsb3c6IGVsbGlwc2lzO1xuICBwYWRkaW5nLWxlZnQ6IDNweDtcbn1cblxuLmxpbmUtbnVtMiB7XG4gIGJveC1zaXppbmc6IGJvcmRlci1ib3g7XG4gIGZsb2F0OiByaWdodDtcbiAgd2lkdGg6IDQwcHg7XG4gIG92ZXJmbG93OiBoaWRkZW47XG4gIHRleHQtb3ZlcmZsb3c6IGVsbGlwc2lzO1xuICBwYWRkaW5nLWxlZnQ6IDNweDtcbn1cblxuLmQyaC1jb2RlLWxpbmVudW1iZXIge1xuICBib3gtc2l6aW5nOiBib3JkZXItYm94O1xuICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gIHdpZHRoOiA4NnB4O1xuICBwYWRkaW5nLWxlZnQ6IDJweDtcbiAgcGFkZGluZy1yaWdodDogMnB4O1xuICBiYWNrZ3JvdW5kLWNvbG9yOiAjZmZmO1xuICBjb2xvcjogcmdiYSgwLCAwLCAwLCAwLjMpO1xuICB0ZXh0LWFsaWduOiByaWdodDtcbiAgYm9yZGVyOiBzb2xpZCAjZWVlZWVlO1xuICBib3JkZXItd2lkdGg6IDAgMXB4IDAgMXB4O1xuICBjdXJzb3I6IHBvaW50ZXI7XG59XG5cbi5kMmgtY29kZS1zaWRlLWxpbmVudW1iZXIge1xuICBib3gtc2l6aW5nOiBib3JkZXItYm94O1xuICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gIHdpZHRoOiA1NnB4O1xuICBwYWRkaW5nLWxlZnQ6IDVweDtcbiAgcGFkZGluZy1yaWdodDogNXB4O1xuICBiYWNrZ3JvdW5kLWNvbG9yOiAjZmZmO1xuICBjb2xvcjogcmdiYSgwLCAwLCAwLCAwLjMpO1xuICB0ZXh0LWFsaWduOiByaWdodDtcbiAgYm9yZGVyOiBzb2xpZCAjZWVlZWVlO1xuICBib3JkZXItd2lkdGg6IDAgMXB4IDAgMXB4O1xuICBjdXJzb3I6IHBvaW50ZXI7XG4gIG92ZXJmbG93OiBoaWRkZW47XG4gIHRleHQtb3ZlcmZsb3c6IGVsbGlwc2lzO1xufVxuXG4vKlxuICogQ2hhbmdlcyBIaWdobGlnaHRcbiAqL1xuXG4uZDJoLWRlbCB7XG4gIGJhY2tncm91bmQtY29sb3I6ICNmZWU4ZTk7XG4gIGJvcmRlci1jb2xvcjogI2U5YWVhZTtcbn1cblxuLmQyaC1pbnMge1xuICBiYWNrZ3JvdW5kLWNvbG9yOiAjZGZkO1xuICBib3JkZXItY29sb3I6ICNiNGUyYjQ7XG59XG5cbi5kMmgtaW5mbyB7XG4gIGJhY2tncm91bmQtY29sb3I6ICNmOGZhZmQ7XG4gIGNvbG9yOiByZ2JhKDAsIDAsIDAsIDAuMyk7XG4gIGJvcmRlci1jb2xvcjogI2Q1ZTRmMjtcbn1cblxuLmQyaC1maWxlLWRpZmYgLmQyaC1kZWwuZDJoLWNoYW5nZSB7XG4gIGJhY2tncm91bmQtY29sb3I6ICNmZGYyZDA7XG59XG5cbi5kMmgtZmlsZS1kaWZmIC5kMmgtaW5zLmQyaC1jaGFuZ2Uge1xuICBiYWNrZ3JvdW5kLWNvbG9yOiAjZGVkO1xufVxuXG4vKlxuICogRmlsZSBTdW1tYXJ5IExpc3RcbiAqL1xuXG4uZDJoLWZpbGUtbGlzdC13cmFwcGVyIHtcbiAgbWFyZ2luLWJvdHRvbTogMTBweDtcbn1cblxuLmQyaC1maWxlLWxpc3Qtd3JhcHBlciBhIHtcbiAgdGV4dC1kZWNvcmF0aW9uOiBub25lO1xuICBjb2xvcjogIzM1NzJiMDtcbn1cblxuLmQyaC1maWxlLWxpc3Qtd3JhcHBlciBhOnZpc2l0ZWQge1xuICBjb2xvcjogIzM1NzJiMDtcbn1cblxuLmQyaC1maWxlLWxpc3QtaGVhZGVyIHtcbiAgdGV4dC1hbGlnbjogbGVmdDtcbn1cblxuLmQyaC1maWxlLWxpc3QtdGl0bGUge1xuICBmb250LXdlaWdodDogYm9sZDtcbn1cblxuLmQyaC1maWxlLWxpc3QtbGluZSB7XG4gIGRpc3BsYXk6IC13ZWJraXQtYm94O1xuICBkaXNwbGF5OiAtbXMtZmxleGJveDtcbiAgZGlzcGxheTogZmxleDtcbiAgdGV4dC1hbGlnbjogbGVmdDtcbn1cblxuLmQyaC1maWxlLWxpc3Qge1xuICBkaXNwbGF5OiBibG9jaztcbiAgbGlzdC1zdHlsZTogbm9uZTtcbiAgcGFkZGluZzogMDtcbiAgbWFyZ2luOiAwO1xufVxuXG4uZDJoLWZpbGUtbGlzdCA+IGxpIHtcbiAgYm9yZGVyLWJvdHRvbTogI2RkZCBzb2xpZCAxcHg7XG4gIHBhZGRpbmc6IDVweCAxMHB4O1xuICBtYXJnaW46IDA7XG59XG5cbi5kMmgtZmlsZS1saXN0ID4gbGk6bGFzdC1jaGlsZCB7XG4gIGJvcmRlci1ib3R0b206IG5vbmU7XG59XG5cbi5kMmgtZmlsZS1zd2l0Y2gge1xuICBkaXNwbGF5OiBub25lO1xuICBmb250LXNpemU6IDEwcHg7XG4gIGN1cnNvcjogcG9pbnRlcjtcbn1cblxuLmQyaC1pY29uLXdyYXBwZXIge1xuICBsaW5lLWhlaWdodDogMzFweDtcbn1cblxuLmQyaC1pY29uIHtcbiAgdmVydGljYWwtYWxpZ246IG1pZGRsZTtcbiAgbWFyZ2luLXJpZ2h0OiAxMHB4O1xuICBmaWxsOiBjdXJyZW50Q29sb3I7XG59XG5cbi5kMmgtZGVsZXRlZCB7XG4gIGNvbG9yOiAjYzMzO1xufVxuXG4uZDJoLWFkZGVkIHtcbiAgY29sb3I6ICMzOTk4Mzk7XG59XG5cbi5kMmgtY2hhbmdlZCB7XG4gIGNvbG9yOiAjZDBiNDRjO1xufVxuXG4uZDJoLW1vdmVkIHtcbiAgY29sb3I6ICMzNTcyYjA7XG59XG5cbi5kMmgtdGFnIHtcbiAgZGlzcGxheTogLXdlYmtpdC1ib3g7XG4gIGRpc3BsYXk6IC1tcy1mbGV4Ym94O1xuICBkaXNwbGF5OiBmbGV4O1xuICBmb250LXNpemU6IDEwcHg7XG4gIG1hcmdpbi1sZWZ0OiA1cHg7XG4gIHBhZGRpbmc6IDAgMnB4O1xuICBiYWNrZ3JvdW5kLWNvbG9yOiAjZmZmO1xufVxuXG4uZDJoLWRlbGV0ZWQtdGFnIHtcbiAgYm9yZGVyOiAjYzMzIDFweCBzb2xpZDtcbn1cblxuLmQyaC1hZGRlZC10YWcge1xuICBib3JkZXI6ICMzOTk4MzkgMXB4IHNvbGlkO1xufVxuXG4uZDJoLWNoYW5nZWQtdGFnIHtcbiAgYm9yZGVyOiAjZDBiNDRjIDFweCBzb2xpZDtcbn1cblxuLmQyaC1tb3ZlZC10YWcge1xuICBib3JkZXI6ICMzNTcyYjAgMXB4IHNvbGlkO1xufVxuXG4vKlxuICogU2VsZWN0aW9uIHV0aWwuXG4gKi9cblxuLnNlbGVjdGluZy1sZWZ0IC5kMmgtY29kZS1saW5lLFxuLnNlbGVjdGluZy1sZWZ0IC5kMmgtY29kZS1saW5lICosXG4uc2VsZWN0aW5nLXJpZ2h0IHRkLmQyaC1jb2RlLWxpbmVudW1iZXIsXG4uc2VsZWN0aW5nLXJpZ2h0IHRkLmQyaC1jb2RlLWxpbmVudW1iZXIgKixcbi5zZWxlY3RpbmctbGVmdCAuZDJoLWNvZGUtc2lkZS1saW5lLFxuLnNlbGVjdGluZy1sZWZ0IC5kMmgtY29kZS1zaWRlLWxpbmUgKixcbi5zZWxlY3RpbmctcmlnaHQgdGQuZDJoLWNvZGUtc2lkZS1saW5lbnVtYmVyLFxuLnNlbGVjdGluZy1yaWdodCB0ZC5kMmgtY29kZS1zaWRlLWxpbmVudW1iZXIgKiB7XG4gIC13ZWJraXQtdG91Y2gtY2FsbG91dDogbm9uZTtcbiAgLXdlYmtpdC11c2VyLXNlbGVjdDogbm9uZTtcbiAgLW1vei11c2VyLXNlbGVjdDogbm9uZTtcbiAgLW1zLXVzZXItc2VsZWN0OiBub25lO1xuICB1c2VyLXNlbGVjdDogbm9uZTtcbn1cblxuLnNlbGVjdGluZy1sZWZ0IC5kMmgtY29kZS1saW5lOjotbW96LXNlbGVjdGlvbixcbi5zZWxlY3RpbmctbGVmdCAuZDJoLWNvZGUtbGluZSAqOjotbW96LXNlbGVjdGlvbixcbi5zZWxlY3RpbmctcmlnaHQgdGQuZDJoLWNvZGUtbGluZW51bWJlcjo6LW1vei1zZWxlY3Rpb24sXG4uc2VsZWN0aW5nLWxlZnQgLmQyaC1jb2RlLXNpZGUtbGluZTo6LW1vei1zZWxlY3Rpb24sXG4uc2VsZWN0aW5nLWxlZnQgLmQyaC1jb2RlLXNpZGUtbGluZSAqOjotbW96LXNlbGVjdGlvbixcbi5zZWxlY3RpbmctcmlnaHQgdGQuZDJoLWNvZGUtc2lkZS1saW5lbnVtYmVyOjotbW96LXNlbGVjdGlvbixcbi5zZWxlY3RpbmctcmlnaHQgdGQuZDJoLWNvZGUtc2lkZS1saW5lbnVtYmVyICo6Oi1tb3otc2VsZWN0aW9uIHtcbiAgYmFja2dyb3VuZDogdHJhbnNwYXJlbnQ7XG59XG5cbi5zZWxlY3RpbmctbGVmdCAuZDJoLWNvZGUtbGluZTo6c2VsZWN0aW9uLFxuLnNlbGVjdGluZy1sZWZ0IC5kMmgtY29kZS1saW5lICo6OnNlbGVjdGlvbixcbi5zZWxlY3RpbmctcmlnaHQgdGQuZDJoLWNvZGUtbGluZW51bWJlcjo6c2VsZWN0aW9uLFxuLnNlbGVjdGluZy1sZWZ0IC5kMmgtY29kZS1zaWRlLWxpbmU6OnNlbGVjdGlvbixcbi5zZWxlY3RpbmctbGVmdCAuZDJoLWNvZGUtc2lkZS1saW5lICo6OnNlbGVjdGlvbixcbi5zZWxlY3RpbmctcmlnaHQgdGQuZDJoLWNvZGUtc2lkZS1saW5lbnVtYmVyOjpzZWxlY3Rpb24sXG4uc2VsZWN0aW5nLXJpZ2h0IHRkLmQyaC1jb2RlLXNpZGUtbGluZW51bWJlciAqOjpzZWxlY3Rpb24ge1xuICBiYWNrZ3JvdW5kOiB0cmFuc3BhcmVudDtcbn1cbiJdfQ== */
\ No newline at end of file
diff --git a/pagure/static/vendor/diff2html/diff2html.js b/pagure/static/vendor/diff2html/diff2html.js
new file mode 100644
index 0000000..78151b6
--- /dev/null
+++ b/pagure/static/vendor/diff2html/diff2html.js
@@ -0,0 +1,7351 @@
+(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
+
+},{}],2:[function(require,module,exports){
+/*!
+
+ diff v3.5.0
+
+Software License Agreement (BSD License)
+
+Copyright (c) 2009-2015, Kevin Decker <kpdecker@gmail.com>
+
+All rights reserved.
+
+Redistribution and use of this software in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above
+  copyright notice, this list of conditions and the
+  following disclaimer.
+
+* Redistributions in binary form must reproduce the above
+  copyright notice, this list of conditions and the
+  following disclaimer in the documentation and/or other
+  materials provided with the distribution.
+
+* Neither the name of Kevin Decker nor the names of its
+  contributors may be used to endorse or promote products
+  derived from this software without specific prior
+  written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@license
+*/
+(function webpackUniversalModuleDefinition(root, factory) {
+	if(typeof exports === 'object' && typeof module === 'object')
+		module.exports = factory();
+	else if(typeof define === 'function' && define.amd)
+		define([], factory);
+	else if(typeof exports === 'object')
+		exports["JsDiff"] = factory();
+	else
+		root["JsDiff"] = factory();
+})(this, function() {
+return /******/ (function(modules) { // webpackBootstrap
+/******/ 	// The module cache
+/******/ 	var installedModules = {};
+
+/******/ 	// The require function
+/******/ 	function __webpack_require__(moduleId) {
+
+/******/ 		// Check if module is in cache
+/******/ 		if(installedModules[moduleId])
+/******/ 			return installedModules[moduleId].exports;
+
+/******/ 		// Create a new module (and put it into the cache)
+/******/ 		var module = installedModules[moduleId] = {
+/******/ 			exports: {},
+/******/ 			id: moduleId,
+/******/ 			loaded: false
+/******/ 		};
+
+/******/ 		// Execute the module function
+/******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
+
+/******/ 		// Flag the module as loaded
+/******/ 		module.loaded = true;
+
+/******/ 		// Return the exports of the module
+/******/ 		return module.exports;
+/******/ 	}
+
+
+/******/ 	// expose the modules object (__webpack_modules__)
+/******/ 	__webpack_require__.m = modules;
+
+/******/ 	// expose the module cache
+/******/ 	__webpack_require__.c = installedModules;
+
+/******/ 	// __webpack_public_path__
+/******/ 	__webpack_require__.p = "";
+
+/******/ 	// Load entry module and return exports
+/******/ 	return __webpack_require__(0);
+/******/ })
+/************************************************************************/
+/******/ ([
+/* 0 */
+/***/ (function(module, exports, __webpack_require__) {
+
+	/*istanbul ignore start*/'use strict';
+
+	exports.__esModule = true;
+	exports.canonicalize = exports.convertChangesToXML = exports.convertChangesToDMP = exports.merge = exports.parsePatch = exports.applyPatches = exports.applyPatch = exports.createPatch = exports.createTwoFilesPatch = exports.structuredPatch = exports.diffArrays = exports.diffJson = exports.diffCss = exports.diffSentences = exports.diffTrimmedLines = exports.diffLines = exports.diffWordsWithSpace = exports.diffWords = exports.diffChars = exports.Diff = undefined;
+
+	/*istanbul ignore end*/var /*istanbul ignore start*/_base = __webpack_require__(1) /*istanbul ignore end*/;
+
+	/*istanbul ignore start*/var _base2 = _interopRequireDefault(_base);
+
+	/*istanbul ignore end*/var /*istanbul ignore start*/_character = __webpack_require__(2) /*istanbul ignore end*/;
+
+	var /*istanbul ignore start*/_word = __webpack_require__(3) /*istanbul ignore end*/;
+
+	var /*istanbul ignore start*/_line = __webpack_require__(5) /*istanbul ignore end*/;
+
+	var /*istanbul ignore start*/_sentence = __webpack_require__(6) /*istanbul ignore end*/;
+
+	var /*istanbul ignore start*/_css = __webpack_require__(7) /*istanbul ignore end*/;
+
+	var /*istanbul ignore start*/_json = __webpack_require__(8) /*istanbul ignore end*/;
+
+	var /*istanbul ignore start*/_array = __webpack_require__(9) /*istanbul ignore end*/;
+
+	var /*istanbul ignore start*/_apply = __webpack_require__(10) /*istanbul ignore end*/;
+
+	var /*istanbul ignore start*/_parse = __webpack_require__(11) /*istanbul ignore end*/;
+
+	var /*istanbul ignore start*/_merge = __webpack_require__(13) /*istanbul ignore end*/;
+
+	var /*istanbul ignore start*/_create = __webpack_require__(14) /*istanbul ignore end*/;
+
+	var /*istanbul ignore start*/_dmp = __webpack_require__(16) /*istanbul ignore end*/;
+
+	var /*istanbul ignore start*/_xml = __webpack_require__(17) /*istanbul ignore end*/;
+
+	/*istanbul ignore start*/function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
+
+	/* See LICENSE file for terms of use */
+
+	/*
+	 * Text diff implementation.
+	 *
+	 * This library supports the following APIS:
+	 * JsDiff.diffChars: Character by character diff
+	 * JsDiff.diffWords: Word (as defined by \b regex) diff which ignores whitespace
+	 * JsDiff.diffLines: Line based diff
+	 *
+	 * JsDiff.diffCss: Diff targeted at CSS content
+	 *
+	 * These methods are based on the implementation proposed in
+	 * "An O(ND) Difference Algorithm and its Variations" (Myers, 1986).
+	 * http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.4.6927
+	 */
+	exports. /*istanbul ignore end*/Diff = _base2['default'];
+	/*istanbul ignore start*/exports. /*istanbul ignore end*/diffChars = _character.diffChars;
+	/*istanbul ignore start*/exports. /*istanbul ignore end*/diffWords = _word.diffWords;
+	/*istanbul ignore start*/exports. /*istanbul ignore end*/diffWordsWithSpace = _word.diffWordsWithSpace;
+	/*istanbul ignore start*/exports. /*istanbul ignore end*/diffLines = _line.diffLines;
+	/*istanbul ignore start*/exports. /*istanbul ignore end*/diffTrimmedLines = _line.diffTrimmedLines;
+	/*istanbul ignore start*/exports. /*istanbul ignore end*/diffSentences = _sentence.diffSentences;
+	/*istanbul ignore start*/exports. /*istanbul ignore end*/diffCss = _css.diffCss;
+	/*istanbul ignore start*/exports. /*istanbul ignore end*/diffJson = _json.diffJson;
+	/*istanbul ignore start*/exports. /*istanbul ignore end*/diffArrays = _array.diffArrays;
+	/*istanbul ignore start*/exports. /*istanbul ignore end*/structuredPatch = _create.structuredPatch;
+	/*istanbul ignore start*/exports. /*istanbul ignore end*/createTwoFilesPatch = _create.createTwoFilesPatch;
+	/*istanbul ignore start*/exports. /*istanbul ignore end*/createPatch = _create.createPatch;
+	/*istanbul ignore start*/exports. /*istanbul ignore end*/applyPatch = _apply.applyPatch;
+	/*istanbul ignore start*/exports. /*istanbul ignore end*/applyPatches = _apply.applyPatches;
+	/*istanbul ignore start*/exports. /*istanbul ignore end*/parsePatch = _parse.parsePatch;
+	/*istanbul ignore start*/exports. /*istanbul ignore end*/merge = _merge.merge;
+	/*istanbul ignore start*/exports. /*istanbul ignore end*/convertChangesToDMP = _dmp.convertChangesToDMP;
+	/*istanbul ignore start*/exports. /*istanbul ignore end*/convertChangesToXML = _xml.convertChangesToXML;
+	/*istanbul ignore start*/exports. /*istanbul ignore end*/canonicalize = _json.canonicalize;
+
+
+
+/***/ }),
+/* 1 */
+/***/ (function(module, exports) {
+
+	/*istanbul ignore start*/'use strict';
+
+	exports.__esModule = true;
+	exports['default'] = /*istanbul ignore end*/Diff;
+	function Diff() {}
+
+	Diff.prototype = {
+	  /*istanbul ignore start*/ /*istanbul ignore end*/diff: function diff(oldString, newString) {
+	    /*istanbul ignore start*/var /*istanbul ignore end*/options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
+
+	    var callback = options.callback;
+	    if (typeof options === 'function') {
+	      callback = options;
+	      options = {};
+	    }
+	    this.options = options;
+
+	    var self = this;
+
+	    function done(value) {
+	      if (callback) {
+	        setTimeout(function () {
+	          callback(undefined, value);
+	        }, 0);
+	        return true;
+	      } else {
+	        return value;
+	      }
+	    }
+
+	    // Allow subclasses to massage the input prior to running
+	    oldString = this.castInput(oldString);
+	    newString = this.castInput(newString);
+
+	    oldString = this.removeEmpty(this.tokenize(oldString));
+	    newString = this.removeEmpty(this.tokenize(newString));
+
+	    var newLen = newString.length,
+	        oldLen = oldString.length;
+	    var editLength = 1;
+	    var maxEditLength = newLen + oldLen;
+	    var bestPath = [{ newPos: -1, components: [] }];
+
+	    // Seed editLength = 0, i.e. the content starts with the same values
+	    var oldPos = this.extractCommon(bestPath[0], newString, oldString, 0);
+	    if (bestPath[0].newPos + 1 >= newLen && oldPos + 1 >= oldLen) {
+	      // Identity per the equality and tokenizer
+	      return done([{ value: this.join(newString), count: newString.length }]);
+	    }
+
+	    // Main worker method. checks all permutations of a given edit length for acceptance.
+	    function execEditLength() {
+	      for (var diagonalPath = -1 * editLength; diagonalPath <= editLength; diagonalPath += 2) {
+	        var basePath = /*istanbul ignore start*/void 0 /*istanbul ignore end*/;
+	        var addPath = bestPath[diagonalPath - 1],
+	            removePath = bestPath[diagonalPath + 1],
+	            _oldPos = (removePath ? removePath.newPos : 0) - diagonalPath;
+	        if (addPath) {
+	          // No one else is going to attempt to use this value, clear it
+	          bestPath[diagonalPath - 1] = undefined;
+	        }
+
+	        var canAdd = addPath && addPath.newPos + 1 < newLen,
+	            canRemove = removePath && 0 <= _oldPos && _oldPos < oldLen;
+	        if (!canAdd && !canRemove) {
+	          // If this path is a terminal then prune
+	          bestPath[diagonalPath] = undefined;
+	          continue;
+	        }
+
+	        // Select the diagonal that we want to branch from. We select the prior
+	        // path whose position in the new string is the farthest from the origin
+	        // and does not pass the bounds of the diff graph
+	        if (!canAdd || canRemove && addPath.newPos < removePath.newPos) {
+	          basePath = clonePath(removePath);
+	          self.pushComponent(basePath.components, undefined, true);
+	        } else {
+	          basePath = addPath; // No need to clone, we've pulled it from the list
+	          basePath.newPos++;
+	          self.pushComponent(basePath.components, true, undefined);
+	        }
+
+	        _oldPos = self.extractCommon(basePath, newString, oldString, diagonalPath);
+
+	        // If we have hit the end of both strings, then we are done
+	        if (basePath.newPos + 1 >= newLen && _oldPos + 1 >= oldLen) {
+	          return done(buildValues(self, basePath.components, newString, oldString, self.useLongestToken));
+	        } else {
+	          // Otherwise track this path as a potential candidate and continue.
+	          bestPath[diagonalPath] = basePath;
+	        }
+	      }
+
+	      editLength++;
+	    }
+
+	    // Performs the length of edit iteration. Is a bit fugly as this has to support the
+	    // sync and async mode which is never fun. Loops over execEditLength until a value
+	    // is produced.
+	    if (callback) {
+	      (function exec() {
+	        setTimeout(function () {
+	          // This should not happen, but we want to be safe.
+	          /* istanbul ignore next */
+	          if (editLength > maxEditLength) {
+	            return callback();
+	          }
+
+	          if (!execEditLength()) {
+	            exec();
+	          }
+	        }, 0);
+	      })();
+	    } else {
+	      while (editLength <= maxEditLength) {
+	        var ret = execEditLength();
+	        if (ret) {
+	          return ret;
+	        }
+	      }
+	    }
+	  },
+	  /*istanbul ignore start*/ /*istanbul ignore end*/pushComponent: function pushComponent(components, added, removed) {
+	    var last = components[components.length - 1];
+	    if (last && last.added === added && last.removed === removed) {
+	      // We need to clone here as the component clone operation is just
+	      // as shallow array clone
+	      components[components.length - 1] = { count: last.count + 1, added: added, removed: removed };
+	    } else {
+	      components.push({ count: 1, added: added, removed: removed });
+	    }
+	  },
+	  /*istanbul ignore start*/ /*istanbul ignore end*/extractCommon: function extractCommon(basePath, newString, oldString, diagonalPath) {
+	    var newLen = newString.length,
+	        oldLen = oldString.length,
+	        newPos = basePath.newPos,
+	        oldPos = newPos - diagonalPath,
+	        commonCount = 0;
+	    while (newPos + 1 < newLen && oldPos + 1 < oldLen && this.equals(newString[newPos + 1], oldString[oldPos + 1])) {
+	      newPos++;
+	      oldPos++;
+	      commonCount++;
+	    }
+
+	    if (commonCount) {
+	      basePath.components.push({ count: commonCount });
+	    }
+
+	    basePath.newPos = newPos;
+	    return oldPos;
+	  },
+	  /*istanbul ignore start*/ /*istanbul ignore end*/equals: function equals(left, right) {
+	    if (this.options.comparator) {
+	      return this.options.comparator(left, right);
+	    } else {
+	      return left === right || this.options.ignoreCase && left.toLowerCase() === right.toLowerCase();
+	    }
+	  },
+	  /*istanbul ignore start*/ /*istanbul ignore end*/removeEmpty: function removeEmpty(array) {
+	    var ret = [];
+	    for (var i = 0; i < array.length; i++) {
+	      if (array[i]) {
+	        ret.push(array[i]);
+	      }
+	    }
+	    return ret;
+	  },
+	  /*istanbul ignore start*/ /*istanbul ignore end*/castInput: function castInput(value) {
+	    return value;
+	  },
+	  /*istanbul ignore start*/ /*istanbul ignore end*/tokenize: function tokenize(value) {
+	    return value.split('');
+	  },
+	  /*istanbul ignore start*/ /*istanbul ignore end*/join: function join(chars) {
+	    return chars.join('');
+	  }
+	};
+
+	function buildValues(diff, components, newString, oldString, useLongestToken) {
+	  var componentPos = 0,
+	      componentLen = components.length,
+	      newPos = 0,
+	      oldPos = 0;
+
+	  for (; componentPos < componentLen; componentPos++) {
+	    var component = components[componentPos];
+	    if (!component.removed) {
+	      if (!component.added && useLongestToken) {
+	        var value = newString.slice(newPos, newPos + component.count);
+	        value = value.map(function (value, i) {
+	          var oldValue = oldString[oldPos + i];
+	          return oldValue.length > value.length ? oldValue : value;
+	        });
+
+	        component.value = diff.join(value);
+	      } else {
+	        component.value = diff.join(newString.slice(newPos, newPos + component.count));
+	      }
+	      newPos += component.count;
+
+	      // Common case
+	      if (!component.added) {
+	        oldPos += component.count;
+	      }
+	    } else {
+	      component.value = diff.join(oldString.slice(oldPos, oldPos + component.count));
+	      oldPos += component.count;
+
+	      // Reverse add and remove so removes are output first to match common convention
+	      // The diffing algorithm is tied to add then remove output and this is the simplest
+	      // route to get the desired output with minimal overhead.
+	      if (componentPos && components[componentPos - 1].added) {
+	        var tmp = components[componentPos - 1];
+	        components[componentPos - 1] = components[componentPos];
+	        components[componentPos] = tmp;
+	      }
+	    }
+	  }
+
+	  // Special case handle for when one terminal is ignored (i.e. whitespace).
+	  // For this case we merge the terminal into the prior string and drop the change.
+	  // This is only available for string mode.
+	  var lastComponent = components[componentLen - 1];
+	  if (componentLen > 1 && typeof lastComponent.value === 'string' && (lastComponent.added || lastComponent.removed) && diff.equals('', lastComponent.value)) {
+	    components[componentLen - 2].value += lastComponent.value;
+	    components.pop();
+	  }
+
+	  return components;
+	}
+
+	function clonePath(path) {
+	  return { newPos: path.newPos, components: path.components.slice(0) };
+	}
+
+
+
+/***/ }),
+/* 2 */
+/***/ (function(module, exports, __webpack_require__) {
+
+	/*istanbul ignore start*/'use strict';
+
+	exports.__esModule = true;
+	exports.characterDiff = undefined;
+	exports. /*istanbul ignore end*/diffChars = diffChars;
+
+	var /*istanbul ignore start*/_base = __webpack_require__(1) /*istanbul ignore end*/;
+
+	/*istanbul ignore start*/var _base2 = _interopRequireDefault(_base);
+
+	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
+
+	/*istanbul ignore end*/var characterDiff = /*istanbul ignore start*/exports. /*istanbul ignore end*/characterDiff = new /*istanbul ignore start*/_base2['default'] /*istanbul ignore end*/();
+	function diffChars(oldStr, newStr, options) {
+	  return characterDiff.diff(oldStr, newStr, options);
+	}
+
+
+
+/***/ }),
+/* 3 */
+/***/ (function(module, exports, __webpack_require__) {
+
+	/*istanbul ignore start*/'use strict';
+
+	exports.__esModule = true;
+	exports.wordDiff = undefined;
+	exports. /*istanbul ignore end*/diffWords = diffWords;
+	/*istanbul ignore start*/exports. /*istanbul ignore end*/diffWordsWithSpace = diffWordsWithSpace;
+
+	var /*istanbul ignore start*/_base = __webpack_require__(1) /*istanbul ignore end*/;
+
+	/*istanbul ignore start*/var _base2 = _interopRequireDefault(_base);
+
+	/*istanbul ignore end*/var /*istanbul ignore start*/_params = __webpack_require__(4) /*istanbul ignore end*/;
+
+	/*istanbul ignore start*/function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
+
+	/*istanbul ignore end*/ // Based on https://en.wikipedia.org/wiki/Latin_script_in_Unicode
+	//
+	// Ranges and exceptions:
+	// Latin-1 Supplement, 0080–00FF
+	//  - U+00D7  × Multiplication sign
+	//  - U+00F7  ÷ Division sign
+	// Latin Extended-A, 0100–017F
+	// Latin Extended-B, 0180–024F
+	// IPA Extensions, 0250–02AF
+	// Spacing Modifier Letters, 02B0–02FF
+	//  - U+02C7  ˇ &#711;  Caron
+	//  - U+02D8  ˘ &#728;  Breve
+	//  - U+02D9  ˙ &#729;  Dot Above
+	//  - U+02DA  ˚ &#730;  Ring Above
+	//  - U+02DB  ˛ &#731;  Ogonek
+	//  - U+02DC  ˜ &#732;  Small Tilde
+	//  - U+02DD  ˝ &#733;  Double Acute Accent
+	// Latin Extended Additional, 1E00–1EFF
+	var extendedWordChars = /^[A-Za-z\xC0-\u02C6\u02C8-\u02D7\u02DE-\u02FF\u1E00-\u1EFF]+$/;
+
+	var reWhitespace = /\S/;
+
+	var wordDiff = /*istanbul ignore start*/exports. /*istanbul ignore end*/wordDiff = new /*istanbul ignore start*/_base2['default'] /*istanbul ignore end*/();
+	wordDiff.equals = function (left, right) {
+	  if (this.options.ignoreCase) {
+	    left = left.toLowerCase();
+	    right = right.toLowerCase();
+	  }
+	  return left === right || this.options.ignoreWhitespace && !reWhitespace.test(left) && !reWhitespace.test(right);
+	};
+	wordDiff.tokenize = function (value) {
+	  var tokens = value.split(/(\s+|\b)/);
+
+	  // Join the boundary splits that we do not consider to be boundaries. This is primarily the extended Latin character set.
+	  for (var i = 0; i < tokens.length - 1; i++) {
+	    // If we have an empty string in the next field and we have only word chars before and after, merge
+	    if (!tokens[i + 1] && tokens[i + 2] && extendedWordChars.test(tokens[i]) && extendedWordChars.test(tokens[i + 2])) {
+	      tokens[i] += tokens[i + 2];
+	      tokens.splice(i + 1, 2);
+	      i--;
+	    }
+	  }
+
+	  return tokens;
+	};
+
+	function diffWords(oldStr, newStr, options) {
+	  options = /*istanbul ignore start*/(0, _params.generateOptions) /*istanbul ignore end*/(options, { ignoreWhitespace: true });
+	  return wordDiff.diff(oldStr, newStr, options);
+	}
+
+	function diffWordsWithSpace(oldStr, newStr, options) {
+	  return wordDiff.diff(oldStr, newStr, options);
+	}
+
+
+
+/***/ }),
+/* 4 */
+/***/ (function(module, exports) {
+
+	/*istanbul ignore start*/'use strict';
+
+	exports.__esModule = true;
+	exports. /*istanbul ignore end*/generateOptions = generateOptions;
+	function generateOptions(options, defaults) {
+	  if (typeof options === 'function') {
+	    defaults.callback = options;
+	  } else if (options) {
+	    for (var name in options) {
+	      /* istanbul ignore else */
+	      if (options.hasOwnProperty(name)) {
+	        defaults[name] = options[name];
+	      }
+	    }
+	  }
+	  return defaults;
+	}
+
+
+
+/***/ }),
+/* 5 */
+/***/ (function(module, exports, __webpack_require__) {
+
+	/*istanbul ignore start*/'use strict';
+
+	exports.__esModule = true;
+	exports.lineDiff = undefined;
+	exports. /*istanbul ignore end*/diffLines = diffLines;
+	/*istanbul ignore start*/exports. /*istanbul ignore end*/diffTrimmedLines = diffTrimmedLines;
+
+	var /*istanbul ignore start*/_base = __webpack_require__(1) /*istanbul ignore end*/;
+
+	/*istanbul ignore start*/var _base2 = _interopRequireDefault(_base);
+
+	/*istanbul ignore end*/var /*istanbul ignore start*/_params = __webpack_require__(4) /*istanbul ignore end*/;
+
+	/*istanbul ignore start*/function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
+
+	/*istanbul ignore end*/var lineDiff = /*istanbul ignore start*/exports. /*istanbul ignore end*/lineDiff = new /*istanbul ignore start*/_base2['default'] /*istanbul ignore end*/();
+	lineDiff.tokenize = function (value) {
+	  var retLines = [],
+	      linesAndNewlines = value.split(/(\n|\r\n)/);
+
+	  // Ignore the final empty token that occurs if the string ends with a new line
+	  if (!linesAndNewlines[linesAndNewlines.length - 1]) {
+	    linesAndNewlines.pop();
+	  }
+
+	  // Merge the content and line separators into single tokens
+	  for (var i = 0; i < linesAndNewlines.length; i++) {
+	    var line = linesAndNewlines[i];
+
+	    if (i % 2 && !this.options.newlineIsToken) {
+	      retLines[retLines.length - 1] += line;
+	    } else {
+	      if (this.options.ignoreWhitespace) {
+	        line = line.trim();
+	      }
+	      retLines.push(line);
+	    }
+	  }
+
+	  return retLines;
+	};
+
+	function diffLines(oldStr, newStr, callback) {
+	  return lineDiff.diff(oldStr, newStr, callback);
+	}
+	function diffTrimmedLines(oldStr, newStr, callback) {
+	  var options = /*istanbul ignore start*/(0, _params.generateOptions) /*istanbul ignore end*/(callback, { ignoreWhitespace: true });
+	  return lineDiff.diff(oldStr, newStr, options);
+	}
+
+
+
+/***/ }),
+/* 6 */
+/***/ (function(module, exports, __webpack_require__) {
+
+	/*istanbul ignore start*/'use strict';
+
+	exports.__esModule = true;
+	exports.sentenceDiff = undefined;
+	exports. /*istanbul ignore end*/diffSentences = diffSentences;
+
+	var /*istanbul ignore start*/_base = __webpack_require__(1) /*istanbul ignore end*/;
+
+	/*istanbul ignore start*/var _base2 = _interopRequireDefault(_base);
+
+	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
+
+	/*istanbul ignore end*/var sentenceDiff = /*istanbul ignore start*/exports. /*istanbul ignore end*/sentenceDiff = new /*istanbul ignore start*/_base2['default'] /*istanbul ignore end*/();
+	sentenceDiff.tokenize = function (value) {
+	  return value.split(/(\S.+?[.!?])(?=\s+|$)/);
+	};
+
+	function diffSentences(oldStr, newStr, callback) {
+	  return sentenceDiff.diff(oldStr, newStr, callback);
+	}
+
+
+
+/***/ }),
+/* 7 */
+/***/ (function(module, exports, __webpack_require__) {
+
+	/*istanbul ignore start*/'use strict';
+
+	exports.__esModule = true;
+	exports.cssDiff = undefined;
+	exports. /*istanbul ignore end*/diffCss = diffCss;
+
+	var /*istanbul ignore start*/_base = __webpack_require__(1) /*istanbul ignore end*/;
+
+	/*istanbul ignore start*/var _base2 = _interopRequireDefault(_base);
+
+	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
+
+	/*istanbul ignore end*/var cssDiff = /*istanbul ignore start*/exports. /*istanbul ignore end*/cssDiff = new /*istanbul ignore start*/_base2['default'] /*istanbul ignore end*/();
+	cssDiff.tokenize = function (value) {
+	  return value.split(/([{}:;,]|\s+)/);
+	};
+
+	function diffCss(oldStr, newStr, callback) {
+	  return cssDiff.diff(oldStr, newStr, callback);
+	}
+
+
+
+/***/ }),
+/* 8 */
+/***/ (function(module, exports, __webpack_require__) {
+
+	/*istanbul ignore start*/'use strict';
+
+	exports.__esModule = true;
+	exports.jsonDiff = undefined;
+
+	var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
+
+	exports. /*istanbul ignore end*/diffJson = diffJson;
+	/*istanbul ignore start*/exports. /*istanbul ignore end*/canonicalize = canonicalize;
+
+	var /*istanbul ignore start*/_base = __webpack_require__(1) /*istanbul ignore end*/;
+
+	/*istanbul ignore start*/var _base2 = _interopRequireDefault(_base);
+
+	/*istanbul ignore end*/var /*istanbul ignore start*/_line = __webpack_require__(5) /*istanbul ignore end*/;
+
+	/*istanbul ignore start*/function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
+
+	/*istanbul ignore end*/var objectPrototypeToString = Object.prototype.toString;
+
+	var jsonDiff = /*istanbul ignore start*/exports. /*istanbul ignore end*/jsonDiff = new /*istanbul ignore start*/_base2['default'] /*istanbul ignore end*/();
+	// Discriminate between two lines of pretty-printed, serialized JSON where one of them has a
+	// dangling comma and the other doesn't. Turns out including the dangling comma yields the nicest output:
+	jsonDiff.useLongestToken = true;
+
+	jsonDiff.tokenize = /*istanbul ignore start*/_line.lineDiff /*istanbul ignore end*/.tokenize;
+	jsonDiff.castInput = function (value) {
+	  /*istanbul ignore start*/var _options = /*istanbul ignore end*/this.options,
+	      undefinedReplacement = _options.undefinedReplacement,
+	      _options$stringifyRep = _options.stringifyReplacer,
+	      stringifyReplacer = _options$stringifyRep === undefined ? function (k, v) /*istanbul ignore start*/{
+	    return (/*istanbul ignore end*/typeof v === 'undefined' ? undefinedReplacement : v
+	    );
+	  } : _options$stringifyRep;
+
+
+	  return typeof value === 'string' ? value : JSON.stringify(canonicalize(value, null, null, stringifyReplacer), stringifyReplacer, '  ');
+	};
+	jsonDiff.equals = function (left, right) {
+	  return (/*istanbul ignore start*/_base2['default'] /*istanbul ignore end*/.prototype.equals.call(jsonDiff, left.replace(/,([\r\n])/g, '$1'), right.replace(/,([\r\n])/g, '$1'))
+	  );
+	};
+
+	function diffJson(oldObj, newObj, options) {
+	  return jsonDiff.diff(oldObj, newObj, options);
+	}
+
+	// This function handles the presence of circular references by bailing out when encountering an
+	// object that is already on the "stack" of items being processed. Accepts an optional replacer
+	function canonicalize(obj, stack, replacementStack, replacer, key) {
+	  stack = stack || [];
+	  replacementStack = replacementStack || [];
+
+	  if (replacer) {
+	    obj = replacer(key, obj);
+	  }
+
+	  var i = /*istanbul ignore start*/void 0 /*istanbul ignore end*/;
+
+	  for (i = 0; i < stack.length; i += 1) {
+	    if (stack[i] === obj) {
+	      return replacementStack[i];
+	    }
+	  }
+
+	  var canonicalizedObj = /*istanbul ignore start*/void 0 /*istanbul ignore end*/;
+
+	  if ('[object Array]' === objectPrototypeToString.call(obj)) {
+	    stack.push(obj);
+	    canonicalizedObj = new Array(obj.length);
+	    replacementStack.push(canonicalizedObj);
+	    for (i = 0; i < obj.length; i += 1) {
+	      canonicalizedObj[i] = canonicalize(obj[i], stack, replacementStack, replacer, key);
+	    }
+	    stack.pop();
+	    replacementStack.pop();
+	    return canonicalizedObj;
+	  }
+
+	  if (obj && obj.toJSON) {
+	    obj = obj.toJSON();
+	  }
+
+	  if ( /*istanbul ignore start*/(typeof /*istanbul ignore end*/obj === 'undefined' ? 'undefined' : _typeof(obj)) === 'object' && obj !== null) {
+	    stack.push(obj);
+	    canonicalizedObj = {};
+	    replacementStack.push(canonicalizedObj);
+	    var sortedKeys = [],
+	        _key = /*istanbul ignore start*/void 0 /*istanbul ignore end*/;
+	    for (_key in obj) {
+	      /* istanbul ignore else */
+	      if (obj.hasOwnProperty(_key)) {
+	        sortedKeys.push(_key);
+	      }
+	    }
+	    sortedKeys.sort();
+	    for (i = 0; i < sortedKeys.length; i += 1) {
+	      _key = sortedKeys[i];
+	      canonicalizedObj[_key] = canonicalize(obj[_key], stack, replacementStack, replacer, _key);
+	    }
+	    stack.pop();
+	    replacementStack.pop();
+	  } else {
+	    canonicalizedObj = obj;
+	  }
+	  return canonicalizedObj;
+	}
+
+
+
+/***/ }),
+/* 9 */
+/***/ (function(module, exports, __webpack_require__) {
+
+	/*istanbul ignore start*/'use strict';
+
+	exports.__esModule = true;
+	exports.arrayDiff = undefined;
+	exports. /*istanbul ignore end*/diffArrays = diffArrays;
+
+	var /*istanbul ignore start*/_base = __webpack_require__(1) /*istanbul ignore end*/;
+
+	/*istanbul ignore start*/var _base2 = _interopRequireDefault(_base);
+
+	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
+
+	/*istanbul ignore end*/var arrayDiff = /*istanbul ignore start*/exports. /*istanbul ignore end*/arrayDiff = new /*istanbul ignore start*/_base2['default'] /*istanbul ignore end*/();
+	arrayDiff.tokenize = function (value) {
+	  return value.slice();
+	};
+	arrayDiff.join = arrayDiff.removeEmpty = function (value) {
+	  return value;
+	};
+
+	function diffArrays(oldArr, newArr, callback) {
+	  return arrayDiff.diff(oldArr, newArr, callback);
+	}
+
+
+
+/***/ }),
+/* 10 */
+/***/ (function(module, exports, __webpack_require__) {
+
+	/*istanbul ignore start*/'use strict';
+
+	exports.__esModule = true;
+	exports. /*istanbul ignore end*/applyPatch = applyPatch;
+	/*istanbul ignore start*/exports. /*istanbul ignore end*/applyPatches = applyPatches;
+
+	var /*istanbul ignore start*/_parse = __webpack_require__(11) /*istanbul ignore end*/;
+
+	var /*istanbul ignore start*/_distanceIterator = __webpack_require__(12) /*istanbul ignore end*/;
+
+	/*istanbul ignore start*/var _distanceIterator2 = _interopRequireDefault(_distanceIterator);
+
+	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
+
+	/*istanbul ignore end*/function applyPatch(source, uniDiff) {
+	  /*istanbul ignore start*/var /*istanbul ignore end*/options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
+
+	  if (typeof uniDiff === 'string') {
+	    uniDiff = /*istanbul ignore start*/(0, _parse.parsePatch) /*istanbul ignore end*/(uniDiff);
+	  }
+
+	  if (Array.isArray(uniDiff)) {
+	    if (uniDiff.length > 1) {
+	      throw new Error('applyPatch only works with a single input.');
+	    }
+
+	    uniDiff = uniDiff[0];
+	  }
+
+	  // Apply the diff to the input
+	  var lines = source.split(/\r\n|[\n\v\f\r\x85]/),
+	      delimiters = source.match(/\r\n|[\n\v\f\r\x85]/g) || [],
+	      hunks = uniDiff.hunks,
+	      compareLine = options.compareLine || function (lineNumber, line, operation, patchContent) /*istanbul ignore start*/{
+	    return (/*istanbul ignore end*/line === patchContent
+	    );
+	  },
+	      errorCount = 0,
+	      fuzzFactor = options.fuzzFactor || 0,
+	      minLine = 0,
+	      offset = 0,
+	      removeEOFNL = /*istanbul ignore start*/void 0 /*istanbul ignore end*/,
+	      addEOFNL = /*istanbul ignore start*/void 0 /*istanbul ignore end*/;
+
+	  /**
+	   * Checks if the hunk exactly fits on the provided location
+	   */
+	  function hunkFits(hunk, toPos) {
+	    for (var j = 0; j < hunk.lines.length; j++) {
+	      var line = hunk.lines[j],
+	          operation = line.length > 0 ? line[0] : ' ',
+	          content = line.length > 0 ? line.substr(1) : line;
+
+	      if (operation === ' ' || operation === '-') {
+	        // Context sanity check
+	        if (!compareLine(toPos + 1, lines[toPos], operation, content)) {
+	          errorCount++;
+
+	          if (errorCount > fuzzFactor) {
+	            return false;
+	          }
+	        }
+	        toPos++;
+	      }
+	    }
+
+	    return true;
+	  }
+
+	  // Search best fit offsets for each hunk based on the previous ones
+	  for (var i = 0; i < hunks.length; i++) {
+	    var hunk = hunks[i],
+	        maxLine = lines.length - hunk.oldLines,
+	        localOffset = 0,
+	        toPos = offset + hunk.oldStart - 1;
+
+	    var iterator = /*istanbul ignore start*/(0, _distanceIterator2['default']) /*istanbul ignore end*/(toPos, minLine, maxLine);
+
+	    for (; localOffset !== undefined; localOffset = iterator()) {
+	      if (hunkFits(hunk, toPos + localOffset)) {
+	        hunk.offset = offset += localOffset;
+	        break;
+	      }
+	    }
+
+	    if (localOffset === undefined) {
+	      return false;
+	    }
+
+	    // Set lower text limit to end of the current hunk, so next ones don't try
+	    // to fit over already patched text
+	    minLine = hunk.offset + hunk.oldStart + hunk.oldLines;
+	  }
+
+	  // Apply patch hunks
+	  var diffOffset = 0;
+	  for (var _i = 0; _i < hunks.length; _i++) {
+	    var _hunk = hunks[_i],
+	        _toPos = _hunk.oldStart + _hunk.offset + diffOffset - 1;
+	    diffOffset += _hunk.newLines - _hunk.oldLines;
+
+	    if (_toPos < 0) {
+	      // Creating a new file
+	      _toPos = 0;
+	    }
+
+	    for (var j = 0; j < _hunk.lines.length; j++) {
+	      var line = _hunk.lines[j],
+	          operation = line.length > 0 ? line[0] : ' ',
+	          content = line.length > 0 ? line.substr(1) : line,
+	          delimiter = _hunk.linedelimiters[j];
+
+	      if (operation === ' ') {
+	        _toPos++;
+	      } else if (operation === '-') {
+	        lines.splice(_toPos, 1);
+	        delimiters.splice(_toPos, 1);
+	        /* istanbul ignore else */
+	      } else if (operation === '+') {
+	        lines.splice(_toPos, 0, content);
+	        delimiters.splice(_toPos, 0, delimiter);
+	        _toPos++;
+	      } else if (operation === '\\') {
+	        var previousOperation = _hunk.lines[j - 1] ? _hunk.lines[j - 1][0] : null;
+	        if (previousOperation === '+') {
+	          removeEOFNL = true;
+	        } else if (previousOperation === '-') {
+	          addEOFNL = true;
+	        }
+	      }
+	    }
+	  }
+
+	  // Handle EOFNL insertion/removal
+	  if (removeEOFNL) {
+	    while (!lines[lines.length - 1]) {
+	      lines.pop();
+	      delimiters.pop();
+	    }
+	  } else if (addEOFNL) {
+	    lines.push('');
+	    delimiters.push('\n');
+	  }
+	  for (var _k = 0; _k < lines.length - 1; _k++) {
+	    lines[_k] = lines[_k] + delimiters[_k];
+	  }
+	  return lines.join('');
+	}
+
+	// Wrapper that supports multiple file patches via callbacks.
+	function applyPatches(uniDiff, options) {
+	  if (typeof uniDiff === 'string') {
+	    uniDiff = /*istanbul ignore start*/(0, _parse.parsePatch) /*istanbul ignore end*/(uniDiff);
+	  }
+
+	  var currentIndex = 0;
+	  function processIndex() {
+	    var index = uniDiff[currentIndex++];
+	    if (!index) {
+	      return options.complete();
+	    }
+
+	    options.loadFile(index, function (err, data) {
+	      if (err) {
+	        return options.complete(err);
+	      }
+
+	      var updatedContent = applyPatch(data, index, options);
+	      options.patched(index, updatedContent, function (err) {
+	        if (err) {
+	          return options.complete(err);
+	        }
+
+	        processIndex();
+	      });
+	    });
+	  }
+	  processIndex();
+	}
+
+
+
+/***/ }),
+/* 11 */
+/***/ (function(module, exports) {
+
+	/*istanbul ignore start*/'use strict';
+
+	exports.__esModule = true;
+	exports. /*istanbul ignore end*/parsePatch = parsePatch;
+	function parsePatch(uniDiff) {
+	  /*istanbul ignore start*/var /*istanbul ignore end*/options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
+
+	  var diffstr = uniDiff.split(/\r\n|[\n\v\f\r\x85]/),
+	      delimiters = uniDiff.match(/\r\n|[\n\v\f\r\x85]/g) || [],
+	      list = [],
+	      i = 0;
+
+	  function parseIndex() {
+	    var index = {};
+	    list.push(index);
+
+	    // Parse diff metadata
+	    while (i < diffstr.length) {
+	      var line = diffstr[i];
+
+	      // File header found, end parsing diff metadata
+	      if (/^(\-\-\-|\+\+\+|@@)\s/.test(line)) {
+	        break;
+	      }
+
+	      // Diff index
+	      var header = /^(?:Index:|diff(?: -r \w+)+)\s+(.+?)\s*$/.exec(line);
+	      if (header) {
+	        index.index = header[1];
+	      }
+
+	      i++;
+	    }
+
+	    // Parse file headers if they are defined. Unified diff requires them, but
+	    // there's no technical issues to have an isolated hunk without file header
+	    parseFileHeader(index);
+	    parseFileHeader(index);
+
+	    // Parse hunks
+	    index.hunks = [];
+
+	    while (i < diffstr.length) {
+	      var _line = diffstr[i];
+
+	      if (/^(Index:|diff|\-\-\-|\+\+\+)\s/.test(_line)) {
+	        break;
+	      } else if (/^@@/.test(_line)) {
+	        index.hunks.push(parseHunk());
+	      } else if (_line && options.strict) {
+	        // Ignore unexpected content unless in strict mode
+	        throw new Error('Unknown line ' + (i + 1) + ' ' + JSON.stringify(_line));
+	      } else {
+	        i++;
+	      }
+	    }
+	  }
+
+	  // Parses the --- and +++ headers, if none are found, no lines
+	  // are consumed.
+	  function parseFileHeader(index) {
+	    var fileHeader = /^(---|\+\+\+)\s+(.*)$/.exec(diffstr[i]);
+	    if (fileHeader) {
+	      var keyPrefix = fileHeader[1] === '---' ? 'old' : 'new';
+	      var data = fileHeader[2].split('\t', 2);
+	      var fileName = data[0].replace(/\\\\/g, '\\');
+	      if (/^".*"$/.test(fileName)) {
+	        fileName = fileName.substr(1, fileName.length - 2);
+	      }
+	      index[keyPrefix + 'FileName'] = fileName;
+	      index[keyPrefix + 'Header'] = (data[1] || '').trim();
+
+	      i++;
+	    }
+	  }
+
+	  // Parses a hunk
+	  // This assumes that we are at the start of a hunk.
+	  function parseHunk() {
+	    var chunkHeaderIndex = i,
+	        chunkHeaderLine = diffstr[i++],
+	        chunkHeader = chunkHeaderLine.split(/@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@/);
+
+	    var hunk = {
+	      oldStart: +chunkHeader[1],
+	      oldLines: +chunkHeader[2] || 1,
+	      newStart: +chunkHeader[3],
+	      newLines: +chunkHeader[4] || 1,
+	      lines: [],
+	      linedelimiters: []
+	    };
+
+	    var addCount = 0,
+	        removeCount = 0;
+	    for (; i < diffstr.length; i++) {
+	      // Lines starting with '---' could be mistaken for the "remove line" operation
+	      // But they could be the header for the next file. Therefore prune such cases out.
+	      if (diffstr[i].indexOf('--- ') === 0 && i + 2 < diffstr.length && diffstr[i + 1].indexOf('+++ ') === 0 && diffstr[i + 2].indexOf('@@') === 0) {
+	        break;
+	      }
+	      var operation = diffstr[i].length == 0 && i != diffstr.length - 1 ? ' ' : diffstr[i][0];
+
+	      if (operation === '+' || operation === '-' || operation === ' ' || operation === '\\') {
+	        hunk.lines.push(diffstr[i]);
+	        hunk.linedelimiters.push(delimiters[i] || '\n');
+
+	        if (operation === '+') {
+	          addCount++;
+	        } else if (operation === '-') {
+	          removeCount++;
+	        } else if (operation === ' ') {
+	          addCount++;
+	          removeCount++;
+	        }
+	      } else {
+	        break;
+	      }
+	    }
+
+	    // Handle the empty block count case
+	    if (!addCount && hunk.newLines === 1) {
+	      hunk.newLines = 0;
+	    }
+	    if (!removeCount && hunk.oldLines === 1) {
+	      hunk.oldLines = 0;
+	    }
+
+	    // Perform optional sanity checking
+	    if (options.strict) {
+	      if (addCount !== hunk.newLines) {
+	        throw new Error('Added line count did not match for hunk at line ' + (chunkHeaderIndex + 1));
+	      }
+	      if (removeCount !== hunk.oldLines) {
+	        throw new Error('Removed line count did not match for hunk at line ' + (chunkHeaderIndex + 1));
+	      }
+	    }
+
+	    return hunk;
+	  }
+
+	  while (i < diffstr.length) {
+	    parseIndex();
+	  }
+
+	  return list;
+	}
+
+
+
+/***/ }),
+/* 12 */
+/***/ (function(module, exports) {
+
+	/*istanbul ignore start*/"use strict";
+
+	exports.__esModule = true;
+
+	exports["default"] = /*istanbul ignore end*/function (start, minLine, maxLine) {
+	  var wantForward = true,
+	      backwardExhausted = false,
+	      forwardExhausted = false,
+	      localOffset = 1;
+
+	  return function iterator() {
+	    if (wantForward && !forwardExhausted) {
+	      if (backwardExhausted) {
+	        localOffset++;
+	      } else {
+	        wantForward = false;
+	      }
+
+	      // Check if trying to fit beyond text length, and if not, check it fits
+	      // after offset location (or desired location on first iteration)
+	      if (start + localOffset <= maxLine) {
+	        return localOffset;
+	      }
+
+	      forwardExhausted = true;
+	    }
+
+	    if (!backwardExhausted) {
+	      if (!forwardExhausted) {
+	        wantForward = true;
+	      }
+
+	      // Check if trying to fit before text beginning, and if not, check it fits
+	      // before offset location
+	      if (minLine <= start - localOffset) {
+	        return -localOffset++;
+	      }
+
+	      backwardExhausted = true;
+	      return iterator();
+	    }
+
+	    // We tried to fit hunk before text beginning and beyond text length, then
+	    // hunk can't fit on the text. Return undefined
+	  };
+	};
+
+
+
+/***/ }),
+/* 13 */
+/***/ (function(module, exports, __webpack_require__) {
+
+	/*istanbul ignore start*/'use strict';
+
+	exports.__esModule = true;
+	exports. /*istanbul ignore end*/calcLineCount = calcLineCount;
+	/*istanbul ignore start*/exports. /*istanbul ignore end*/merge = merge;
+
+	var /*istanbul ignore start*/_create = __webpack_require__(14) /*istanbul ignore end*/;
+
+	var /*istanbul ignore start*/_parse = __webpack_require__(11) /*istanbul ignore end*/;
+
+	var /*istanbul ignore start*/_array = __webpack_require__(15) /*istanbul ignore end*/;
+
+	/*istanbul ignore start*/function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
+
+	/*istanbul ignore end*/function calcLineCount(hunk) {
+	  /*istanbul ignore start*/var _calcOldNewLineCount = /*istanbul ignore end*/calcOldNewLineCount(hunk.lines),
+	      oldLines = _calcOldNewLineCount.oldLines,
+	      newLines = _calcOldNewLineCount.newLines;
+
+	  if (oldLines !== undefined) {
+	    hunk.oldLines = oldLines;
+	  } else {
+	    delete hunk.oldLines;
+	  }
+
+	  if (newLines !== undefined) {
+	    hunk.newLines = newLines;
+	  } else {
+	    delete hunk.newLines;
+	  }
+	}
+
+	function merge(mine, theirs, base) {
+	  mine = loadPatch(mine, base);
+	  theirs = loadPatch(theirs, base);
+
+	  var ret = {};
+
+	  // For index we just let it pass through as it doesn't have any necessary meaning.
+	  // Leaving sanity checks on this to the API consumer that may know more about the
+	  // meaning in their own context.
+	  if (mine.index || theirs.index) {
+	    ret.index = mine.index || theirs.index;
+	  }
+
+	  if (mine.newFileName || theirs.newFileName) {
+	    if (!fileNameChanged(mine)) {
+	      // No header or no change in ours, use theirs (and ours if theirs does not exist)
+	      ret.oldFileName = theirs.oldFileName || mine.oldFileName;
+	      ret.newFileName = theirs.newFileName || mine.newFileName;
+	      ret.oldHeader = theirs.oldHeader || mine.oldHeader;
+	      ret.newHeader = theirs.newHeader || mine.newHeader;
+	    } else if (!fileNameChanged(theirs)) {
+	      // No header or no change in theirs, use ours
+	      ret.oldFileName = mine.oldFileName;
+	      ret.newFileName = mine.newFileName;
+	      ret.oldHeader = mine.oldHeader;
+	      ret.newHeader = mine.newHeader;
+	    } else {
+	      // Both changed... figure it out
+	      ret.oldFileName = selectField(ret, mine.oldFileName, theirs.oldFileName);
+	      ret.newFileName = selectField(ret, mine.newFileName, theirs.newFileName);
+	      ret.oldHeader = selectField(ret, mine.oldHeader, theirs.oldHeader);
+	      ret.newHeader = selectField(ret, mine.newHeader, theirs.newHeader);
+	    }
+	  }
+
+	  ret.hunks = [];
+
+	  var mineIndex = 0,
+	      theirsIndex = 0,
+	      mineOffset = 0,
+	      theirsOffset = 0;
+
+	  while (mineIndex < mine.hunks.length || theirsIndex < theirs.hunks.length) {
+	    var mineCurrent = mine.hunks[mineIndex] || { oldStart: Infinity },
+	        theirsCurrent = theirs.hunks[theirsIndex] || { oldStart: Infinity };
+
+	    if (hunkBefore(mineCurrent, theirsCurrent)) {
+	      // This patch does not overlap with any of the others, yay.
+	      ret.hunks.push(cloneHunk(mineCurrent, mineOffset));
+	      mineIndex++;
+	      theirsOffset += mineCurrent.newLines - mineCurrent.oldLines;
+	    } else if (hunkBefore(theirsCurrent, mineCurrent)) {
+	      // This patch does not overlap with any of the others, yay.
+	      ret.hunks.push(cloneHunk(theirsCurrent, theirsOffset));
+	      theirsIndex++;
+	      mineOffset += theirsCurrent.newLines - theirsCurrent.oldLines;
+	    } else {
+	      // Overlap, merge as best we can
+	      var mergedHunk = {
+	        oldStart: Math.min(mineCurrent.oldStart, theirsCurrent.oldStart),
+	        oldLines: 0,
+	        newStart: Math.min(mineCurrent.newStart + mineOffset, theirsCurrent.oldStart + theirsOffset),
+	        newLines: 0,
+	        lines: []
+	      };
+	      mergeLines(mergedHunk, mineCurrent.oldStart, mineCurrent.lines, theirsCurrent.oldStart, theirsCurrent.lines);
+	      theirsIndex++;
+	      mineIndex++;
+
+	      ret.hunks.push(mergedHunk);
+	    }
+	  }
+
+	  return ret;
+	}
+
+	function loadPatch(param, base) {
+	  if (typeof param === 'string') {
+	    if (/^@@/m.test(param) || /^Index:/m.test(param)) {
+	      return (/*istanbul ignore start*/(0, _parse.parsePatch) /*istanbul ignore end*/(param)[0]
+	      );
+	    }
+
+	    if (!base) {
+	      throw new Error('Must provide a base reference or pass in a patch');
+	    }
+	    return (/*istanbul ignore start*/(0, _create.structuredPatch) /*istanbul ignore end*/(undefined, undefined, base, param)
+	    );
+	  }
+
+	  return param;
+	}
+
+	function fileNameChanged(patch) {
+	  return patch.newFileName && patch.newFileName !== patch.oldFileName;
+	}
+
+	function selectField(index, mine, theirs) {
+	  if (mine === theirs) {
+	    return mine;
+	  } else {
+	    index.conflict = true;
+	    return { mine: mine, theirs: theirs };
+	  }
+	}
+
+	function hunkBefore(test, check) {
+	  return test.oldStart < check.oldStart && test.oldStart + test.oldLines < check.oldStart;
+	}
+
+	function cloneHunk(hunk, offset) {
+	  return {
+	    oldStart: hunk.oldStart, oldLines: hunk.oldLines,
+	    newStart: hunk.newStart + offset, newLines: hunk.newLines,
+	    lines: hunk.lines
+	  };
+	}
+
+	function mergeLines(hunk, mineOffset, mineLines, theirOffset, theirLines) {
+	  // This will generally result in a conflicted hunk, but there are cases where the context
+	  // is the only overlap where we can successfully merge the content here.
+	  var mine = { offset: mineOffset, lines: mineLines, index: 0 },
+	      their = { offset: theirOffset, lines: theirLines, index: 0 };
+
+	  // Handle any leading content
+	  insertLeading(hunk, mine, their);
+	  insertLeading(hunk, their, mine);
+
+	  // Now in the overlap content. Scan through and select the best changes from each.
+	  while (mine.index < mine.lines.length && their.index < their.lines.length) {
+	    var mineCurrent = mine.lines[mine.index],
+	        theirCurrent = their.lines[their.index];
+
+	    if ((mineCurrent[0] === '-' || mineCurrent[0] === '+') && (theirCurrent[0] === '-' || theirCurrent[0] === '+')) {
+	      // Both modified ...
+	      mutualChange(hunk, mine, their);
+	    } else if (mineCurrent[0] === '+' && theirCurrent[0] === ' ') {
+	      /*istanbul ignore start*/var _hunk$lines;
+
+	      /*istanbul ignore end*/ // Mine inserted
+	      /*istanbul ignore start*/(_hunk$lines = /*istanbul ignore end*/hunk.lines).push. /*istanbul ignore start*/apply /*istanbul ignore end*/( /*istanbul ignore start*/_hunk$lines /*istanbul ignore end*/, /*istanbul ignore start*/_toConsumableArray( /*istanbul ignore end*/collectChange(mine)));
+	    } else if (theirCurrent[0] === '+' && mineCurrent[0] === ' ') {
+	      /*istanbul ignore start*/var _hunk$lines2;
+
+	      /*istanbul ignore end*/ // Theirs inserted
+	      /*istanbul ignore start*/(_hunk$lines2 = /*istanbul ignore end*/hunk.lines).push. /*istanbul ignore start*/apply /*istanbul ignore end*/( /*istanbul ignore start*/_hunk$lines2 /*istanbul ignore end*/, /*istanbul ignore start*/_toConsumableArray( /*istanbul ignore end*/collectChange(their)));
+	    } else if (mineCurrent[0] === '-' && theirCurrent[0] === ' ') {
+	      // Mine removed or edited
+	      removal(hunk, mine, their);
+	    } else if (theirCurrent[0] === '-' && mineCurrent[0] === ' ') {
+	      // Their removed or edited
+	      removal(hunk, their, mine, true);
+	    } else if (mineCurrent === theirCurrent) {
+	      // Context identity
+	      hunk.lines.push(mineCurrent);
+	      mine.index++;
+	      their.index++;
+	    } else {
+	      // Context mismatch
+	      conflict(hunk, collectChange(mine), collectChange(their));
+	    }
+	  }
+
+	  // Now push anything that may be remaining
+	  insertTrailing(hunk, mine);
+	  insertTrailing(hunk, their);
+
+	  calcLineCount(hunk);
+	}
+
+	function mutualChange(hunk, mine, their) {
+	  var myChanges = collectChange(mine),
+	      theirChanges = collectChange(their);
+
+	  if (allRemoves(myChanges) && allRemoves(theirChanges)) {
+	    // Special case for remove changes that are supersets of one another
+	    if ( /*istanbul ignore start*/(0, _array.arrayStartsWith) /*istanbul ignore end*/(myChanges, theirChanges) && skipRemoveSuperset(their, myChanges, myChanges.length - theirChanges.length)) {
+	      /*istanbul ignore start*/var _hunk$lines3;
+
+	      /*istanbul ignore end*/ /*istanbul ignore start*/(_hunk$lines3 = /*istanbul ignore end*/hunk.lines).push. /*istanbul ignore start*/apply /*istanbul ignore end*/( /*istanbul ignore start*/_hunk$lines3 /*istanbul ignore end*/, /*istanbul ignore start*/_toConsumableArray( /*istanbul ignore end*/myChanges));
+	      return;
+	    } else if ( /*istanbul ignore start*/(0, _array.arrayStartsWith) /*istanbul ignore end*/(theirChanges, myChanges) && skipRemoveSuperset(mine, theirChanges, theirChanges.length - myChanges.length)) {
+	      /*istanbul ignore start*/var _hunk$lines4;
+
+	      /*istanbul ignore end*/ /*istanbul ignore start*/(_hunk$lines4 = /*istanbul ignore end*/hunk.lines).push. /*istanbul ignore start*/apply /*istanbul ignore end*/( /*istanbul ignore start*/_hunk$lines4 /*istanbul ignore end*/, /*istanbul ignore start*/_toConsumableArray( /*istanbul ignore end*/theirChanges));
+	      return;
+	    }
+	  } else if ( /*istanbul ignore start*/(0, _array.arrayEqual) /*istanbul ignore end*/(myChanges, theirChanges)) {
+	    /*istanbul ignore start*/var _hunk$lines5;
+
+	    /*istanbul ignore end*/ /*istanbul ignore start*/(_hunk$lines5 = /*istanbul ignore end*/hunk.lines).push. /*istanbul ignore start*/apply /*istanbul ignore end*/( /*istanbul ignore start*/_hunk$lines5 /*istanbul ignore end*/, /*istanbul ignore start*/_toConsumableArray( /*istanbul ignore end*/myChanges));
+	    return;
+	  }
+
+	  conflict(hunk, myChanges, theirChanges);
+	}
+
+	function removal(hunk, mine, their, swap) {
+	  var myChanges = collectChange(mine),
+	      theirChanges = collectContext(their, myChanges);
+	  if (theirChanges.merged) {
+	    /*istanbul ignore start*/var _hunk$lines6;
+
+	    /*istanbul ignore end*/ /*istanbul ignore start*/(_hunk$lines6 = /*istanbul ignore end*/hunk.lines).push. /*istanbul ignore start*/apply /*istanbul ignore end*/( /*istanbul ignore start*/_hunk$lines6 /*istanbul ignore end*/, /*istanbul ignore start*/_toConsumableArray( /*istanbul ignore end*/theirChanges.merged));
+	  } else {
+	    conflict(hunk, swap ? theirChanges : myChanges, swap ? myChanges : theirChanges);
+	  }
+	}
+
+	function conflict(hunk, mine, their) {
+	  hunk.conflict = true;
+	  hunk.lines.push({
+	    conflict: true,
+	    mine: mine,
+	    theirs: their
+	  });
+	}
+
+	function insertLeading(hunk, insert, their) {
+	  while (insert.offset < their.offset && insert.index < insert.lines.length) {
+	    var line = insert.lines[insert.index++];
+	    hunk.lines.push(line);
+	    insert.offset++;
+	  }
+	}
+	function insertTrailing(hunk, insert) {
+	  while (insert.index < insert.lines.length) {
+	    var line = insert.lines[insert.index++];
+	    hunk.lines.push(line);
+	  }
+	}
+
+	function collectChange(state) {
+	  var ret = [],
+	      operation = state.lines[state.index][0];
+	  while (state.index < state.lines.length) {
+	    var line = state.lines[state.index];
+
+	    // Group additions that are immediately after subtractions and treat them as one "atomic" modify change.
+	    if (operation === '-' && line[0] === '+') {
+	      operation = '+';
+	    }
+
+	    if (operation === line[0]) {
+	      ret.push(line);
+	      state.index++;
+	    } else {
+	      break;
+	    }
+	  }
+
+	  return ret;
+	}
+	function collectContext(state, matchChanges) {
+	  var changes = [],
+	      merged = [],
+	      matchIndex = 0,
+	      contextChanges = false,
+	      conflicted = false;
+	  while (matchIndex < matchChanges.length && state.index < state.lines.length) {
+	    var change = state.lines[state.index],
+	        match = matchChanges[matchIndex];
+
+	    // Once we've hit our add, then we are done
+	    if (match[0] === '+') {
+	      break;
+	    }
+
+	    contextChanges = contextChanges || change[0] !== ' ';
+
+	    merged.push(match);
+	    matchIndex++;
+
+	    // Consume any additions in the other block as a conflict to attempt
+	    // to pull in the remaining context after this
+	    if (change[0] === '+') {
+	      conflicted = true;
+
+	      while (change[0] === '+') {
+	        changes.push(change);
+	        change = state.lines[++state.index];
+	      }
+	    }
+
+	    if (match.substr(1) === change.substr(1)) {
+	      changes.push(change);
+	      state.index++;
+	    } else {
+	      conflicted = true;
+	    }
+	  }
+
+	  if ((matchChanges[matchIndex] || '')[0] === '+' && contextChanges) {
+	    conflicted = true;
+	  }
+
+	  if (conflicted) {
+	    return changes;
+	  }
+
+	  while (matchIndex < matchChanges.length) {
+	    merged.push(matchChanges[matchIndex++]);
+	  }
+
+	  return {
+	    merged: merged,
+	    changes: changes
+	  };
+	}
+
+	function allRemoves(changes) {
+	  return changes.reduce(function (prev, change) {
+	    return prev && change[0] === '-';
+	  }, true);
+	}
+	function skipRemoveSuperset(state, removeChanges, delta) {
+	  for (var i = 0; i < delta; i++) {
+	    var changeContent = removeChanges[removeChanges.length - delta + i].substr(1);
+	    if (state.lines[state.index + i] !== ' ' + changeContent) {
+	      return false;
+	    }
+	  }
+
+	  state.index += delta;
+	  return true;
+	}
+
+	function calcOldNewLineCount(lines) {
+	  var oldLines = 0;
+	  var newLines = 0;
+
+	  lines.forEach(function (line) {
+	    if (typeof line !== 'string') {
+	      var myCount = calcOldNewLineCount(line.mine);
+	      var theirCount = calcOldNewLineCount(line.theirs);
+
+	      if (oldLines !== undefined) {
+	        if (myCount.oldLines === theirCount.oldLines) {
+	          oldLines += myCount.oldLines;
+	        } else {
+	          oldLines = undefined;
+	        }
+	      }
+
+	      if (newLines !== undefined) {
+	        if (myCount.newLines === theirCount.newLines) {
+	          newLines += myCount.newLines;
+	        } else {
+	          newLines = undefined;
+	        }
+	      }
+	    } else {
+	      if (newLines !== undefined && (line[0] === '+' || line[0] === ' ')) {
+	        newLines++;
+	      }
+	      if (oldLines !== undefined && (line[0] === '-' || line[0] === ' ')) {
+	        oldLines++;
+	      }
+	    }
+	  });
+
+	  return { oldLines: oldLines, newLines: newLines };
+	}
+
+
+
+/***/ }),
+/* 14 */
+/***/ (function(module, exports, __webpack_require__) {
+
+	/*istanbul ignore start*/'use strict';
+
+	exports.__esModule = true;
+	exports. /*istanbul ignore end*/structuredPatch = structuredPatch;
+	/*istanbul ignore start*/exports. /*istanbul ignore end*/createTwoFilesPatch = createTwoFilesPatch;
+	/*istanbul ignore start*/exports. /*istanbul ignore end*/createPatch = createPatch;
+
+	var /*istanbul ignore start*/_line = __webpack_require__(5) /*istanbul ignore end*/;
+
+	/*istanbul ignore start*/function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
+
+	/*istanbul ignore end*/function structuredPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, options) {
+	  if (!options) {
+	    options = {};
+	  }
+	  if (typeof options.context === 'undefined') {
+	    options.context = 4;
+	  }
+
+	  var diff = /*istanbul ignore start*/(0, _line.diffLines) /*istanbul ignore end*/(oldStr, newStr, options);
+	  diff.push({ value: '', lines: [] }); // Append an empty value to make cleanup easier
+
+	  function contextLines(lines) {
+	    return lines.map(function (entry) {
+	      return ' ' + entry;
+	    });
+	  }
+
+	  var hunks = [];
+	  var oldRangeStart = 0,
+	      newRangeStart = 0,
+	      curRange = [],
+	      oldLine = 1,
+	      newLine = 1;
+
+	  /*istanbul ignore start*/var _loop = function _loop( /*istanbul ignore end*/i) {
+	    var current = diff[i],
+	        lines = current.lines || current.value.replace(/\n$/, '').split('\n');
+	    current.lines = lines;
+
+	    if (current.added || current.removed) {
+	      /*istanbul ignore start*/var _curRange;
+
+	      /*istanbul ignore end*/ // If we have previous context, start with that
+	      if (!oldRangeStart) {
+	        var prev = diff[i - 1];
+	        oldRangeStart = oldLine;
+	        newRangeStart = newLine;
+
+	        if (prev) {
+	          curRange = options.context > 0 ? contextLines(prev.lines.slice(-options.context)) : [];
+	          oldRangeStart -= curRange.length;
+	          newRangeStart -= curRange.length;
+	        }
+	      }
+
+	      // Output our changes
+	      /*istanbul ignore start*/(_curRange = /*istanbul ignore end*/curRange).push. /*istanbul ignore start*/apply /*istanbul ignore end*/( /*istanbul ignore start*/_curRange /*istanbul ignore end*/, /*istanbul ignore start*/_toConsumableArray( /*istanbul ignore end*/lines.map(function (entry) {
+	        return (current.added ? '+' : '-') + entry;
+	      })));
+
+	      // Track the updated file position
+	      if (current.added) {
+	        newLine += lines.length;
+	      } else {
+	        oldLine += lines.length;
+	      }
+	    } else {
+	      // Identical context lines. Track line changes
+	      if (oldRangeStart) {
+	        // Close out any changes that have been output (or join overlapping)
+	        if (lines.length <= options.context * 2 && i < diff.length - 2) {
+	          /*istanbul ignore start*/var _curRange2;
+
+	          /*istanbul ignore end*/ // Overlapping
+	          /*istanbul ignore start*/(_curRange2 = /*istanbul ignore end*/curRange).push. /*istanbul ignore start*/apply /*istanbul ignore end*/( /*istanbul ignore start*/_curRange2 /*istanbul ignore end*/, /*istanbul ignore start*/_toConsumableArray( /*istanbul ignore end*/contextLines(lines)));
+	        } else {
+	          /*istanbul ignore start*/var _curRange3;
+
+	          /*istanbul ignore end*/ // end the range and output
+	          var contextSize = Math.min(lines.length, options.context);
+	          /*istanbul ignore start*/(_curRange3 = /*istanbul ignore end*/curRange).push. /*istanbul ignore start*/apply /*istanbul ignore end*/( /*istanbul ignore start*/_curRange3 /*istanbul ignore end*/, /*istanbul ignore start*/_toConsumableArray( /*istanbul ignore end*/contextLines(lines.slice(0, contextSize))));
+
+	          var hunk = {
+	            oldStart: oldRangeStart,
+	            oldLines: oldLine - oldRangeStart + contextSize,
+	            newStart: newRangeStart,
+	            newLines: newLine - newRangeStart + contextSize,
+	            lines: curRange
+	          };
+	          if (i >= diff.length - 2 && lines.length <= options.context) {
+	            // EOF is inside this hunk
+	            var oldEOFNewline = /\n$/.test(oldStr);
+	            var newEOFNewline = /\n$/.test(newStr);
+	            if (lines.length == 0 && !oldEOFNewline) {
+	              // special case: old has no eol and no trailing context; no-nl can end up before adds
+	              curRange.splice(hunk.oldLines, 0, '\\ No newline at end of file');
+	            } else if (!oldEOFNewline || !newEOFNewline) {
+	              curRange.push('\\ No newline at end of file');
+	            }
+	          }
+	          hunks.push(hunk);
+
+	          oldRangeStart = 0;
+	          newRangeStart = 0;
+	          curRange = [];
+	        }
+	      }
+	      oldLine += lines.length;
+	      newLine += lines.length;
+	    }
+	  };
+
+	  for (var i = 0; i < diff.length; i++) {
+	    /*istanbul ignore start*/_loop( /*istanbul ignore end*/i);
+	  }
+
+	  return {
+	    oldFileName: oldFileName, newFileName: newFileName,
+	    oldHeader: oldHeader, newHeader: newHeader,
+	    hunks: hunks
+	  };
+	}
+
+	function createTwoFilesPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, options) {
+	  var diff = structuredPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, options);
+
+	  var ret = [];
+	  if (oldFileName == newFileName) {
+	    ret.push('Index: ' + oldFileName);
+	  }
+	  ret.push('===================================================================');
+	  ret.push('--- ' + diff.oldFileName + (typeof diff.oldHeader === 'undefined' ? '' : '\t' + diff.oldHeader));
+	  ret.push('+++ ' + diff.newFileName + (typeof diff.newHeader === 'undefined' ? '' : '\t' + diff.newHeader));
+
+	  for (var i = 0; i < diff.hunks.length; i++) {
+	    var hunk = diff.hunks[i];
+	    ret.push('@@ -' + hunk.oldStart + ',' + hunk.oldLines + ' +' + hunk.newStart + ',' + hunk.newLines + ' @@');
+	    ret.push.apply(ret, hunk.lines);
+	  }
+
+	  return ret.join('\n') + '\n';
+	}
+
+	function createPatch(fileName, oldStr, newStr, oldHeader, newHeader, options) {
+	  return createTwoFilesPatch(fileName, fileName, oldStr, newStr, oldHeader, newHeader, options);
+	}
+
+
+
+/***/ }),
+/* 15 */
+/***/ (function(module, exports) {
+
+	/*istanbul ignore start*/"use strict";
+
+	exports.__esModule = true;
+	exports. /*istanbul ignore end*/arrayEqual = arrayEqual;
+	/*istanbul ignore start*/exports. /*istanbul ignore end*/arrayStartsWith = arrayStartsWith;
+	function arrayEqual(a, b) {
+	  if (a.length !== b.length) {
+	    return false;
+	  }
+
+	  return arrayStartsWith(a, b);
+	}
+
+	function arrayStartsWith(array, start) {
+	  if (start.length > array.length) {
+	    return false;
+	  }
+
+	  for (var i = 0; i < start.length; i++) {
+	    if (start[i] !== array[i]) {
+	      return false;
+	    }
+	  }
+
+	  return true;
+	}
+
+
+
+/***/ }),
+/* 16 */
+/***/ (function(module, exports) {
+
+	/*istanbul ignore start*/"use strict";
+
+	exports.__esModule = true;
+	exports. /*istanbul ignore end*/convertChangesToDMP = convertChangesToDMP;
+	// See: http://code.google.com/p/google-diff-match-patch/wiki/API
+	function convertChangesToDMP(changes) {
+	  var ret = [],
+	      change = /*istanbul ignore start*/void 0 /*istanbul ignore end*/,
+	      operation = /*istanbul ignore start*/void 0 /*istanbul ignore end*/;
+	  for (var i = 0; i < changes.length; i++) {
+	    change = changes[i];
+	    if (change.added) {
+	      operation = 1;
+	    } else if (change.removed) {
+	      operation = -1;
+	    } else {
+	      operation = 0;
+	    }
+
+	    ret.push([operation, change.value]);
+	  }
+	  return ret;
+	}
+
+
+
+/***/ }),
+/* 17 */
+/***/ (function(module, exports) {
+
+	/*istanbul ignore start*/'use strict';
+
+	exports.__esModule = true;
+	exports. /*istanbul ignore end*/convertChangesToXML = convertChangesToXML;
+	function convertChangesToXML(changes) {
+	  var ret = [];
+	  for (var i = 0; i < changes.length; i++) {
+	    var change = changes[i];
+	    if (change.added) {
+	      ret.push('<ins>');
+	    } else if (change.removed) {
+	      ret.push('<del>');
+	    }
+
+	    ret.push(escapeHTML(change.value));
+
+	    if (change.added) {
+	      ret.push('</ins>');
+	    } else if (change.removed) {
+	      ret.push('</del>');
+	    }
+	  }
+	  return ret.join('');
+	}
+
+	function escapeHTML(s) {
+	  var n = s;
+	  n = n.replace(/&/g, '&amp;');
+	  n = n.replace(/</g, '&lt;');
+	  n = n.replace(/>/g, '&gt;');
+	  n = n.replace(/"/g, '&quot;');
+
+	  return n;
+	}
+
+
+
+/***/ })
+/******/ ])
+});
+;
+},{}],3:[function(require,module,exports){
+/*
+ *  Copyright 2011 Twitter, Inc.
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+(function (Hogan) {
+  // Setup regex  assignments
+  // remove whitespace according to Mustache spec
+  var rIsWhitespace = /\S/,
+      rQuot = /\"/g,
+      rNewline =  /\n/g,
+      rCr = /\r/g,
+      rSlash = /\\/g,
+      rLineSep = /\u2028/,
+      rParagraphSep = /\u2029/;
+
+  Hogan.tags = {
+    '#': 1, '^': 2, '<': 3, '$': 4,
+    '/': 5, '!': 6, '>': 7, '=': 8, '_v': 9,
+    '{': 10, '&': 11, '_t': 12
+  };
+
+  Hogan.scan = function scan(text, delimiters) {
+    var len = text.length,
+        IN_TEXT = 0,
+        IN_TAG_TYPE = 1,
+        IN_TAG = 2,
+        state = IN_TEXT,
+        tagType = null,
+        tag = null,
+        buf = '',
+        tokens = [],
+        seenTag = false,
+        i = 0,
+        lineStart = 0,
+        otag = '{{',
+        ctag = '}}';
+
+    function addBuf() {
+      if (buf.length > 0) {
+        tokens.push({tag: '_t', text: new String(buf)});
+        buf = '';
+      }
+    }
+
+    function lineIsWhitespace() {
+      var isAllWhitespace = true;
+      for (var j = lineStart; j < tokens.length; j++) {
+        isAllWhitespace =
+          (Hogan.tags[tokens[j].tag] < Hogan.tags['_v']) ||
+          (tokens[j].tag == '_t' && tokens[j].text.match(rIsWhitespace) === null);
+        if (!isAllWhitespace) {
+          return false;
+        }
+      }
+
+      return isAllWhitespace;
+    }
+
+    function filterLine(haveSeenTag, noNewLine) {
+      addBuf();
+
+      if (haveSeenTag && lineIsWhitespace()) {
+        for (var j = lineStart, next; j < tokens.length; j++) {
+          if (tokens[j].text) {
+            if ((next = tokens[j+1]) && next.tag == '>') {
+              // set indent to token value
+              next.indent = tokens[j].text.toString()
+            }
+            tokens.splice(j, 1);
+          }
+        }
+      } else if (!noNewLine) {
+        tokens.push({tag:'\n'});
+      }
+
+      seenTag = false;
+      lineStart = tokens.length;
+    }
+
+    function changeDelimiters(text, index) {
+      var close = '=' + ctag,
+          closeIndex = text.indexOf(close, index),
+          delimiters = trim(
+            text.substring(text.indexOf('=', index) + 1, closeIndex)
+          ).split(' ');
+
+      otag = delimiters[0];
+      ctag = delimiters[delimiters.length - 1];
+
+      return closeIndex + close.length - 1;
+    }
+
+    if (delimiters) {
+      delimiters = delimiters.split(' ');
+      otag = delimiters[0];
+      ctag = delimiters[1];
+    }
+
+    for (i = 0; i < len; i++) {
+      if (state == IN_TEXT) {
+        if (tagChange(otag, text, i)) {
+          --i;
+          addBuf();
+          state = IN_TAG_TYPE;
+        } else {
+          if (text.charAt(i) == '\n') {
+            filterLine(seenTag);
+          } else {
+            buf += text.charAt(i);
+          }
+        }
+      } else if (state == IN_TAG_TYPE) {
+        i += otag.length - 1;
+        tag = Hogan.tags[text.charAt(i + 1)];
+        tagType = tag ? text.charAt(i + 1) : '_v';
+        if (tagType == '=') {
+          i = changeDelimiters(text, i);
+          state = IN_TEXT;
+        } else {
+          if (tag) {
+            i++;
+          }
+          state = IN_TAG;
+        }
+        seenTag = i;
+      } else {
+        if (tagChange(ctag, text, i)) {
+          tokens.push({tag: tagType, n: trim(buf), otag: otag, ctag: ctag,
+                       i: (tagType == '/') ? seenTag - otag.length : i + ctag.length});
+          buf = '';
+          i += ctag.length - 1;
+          state = IN_TEXT;
+          if (tagType == '{') {
+            if (ctag == '}}') {
+              i++;
+            } else {
+              cleanTripleStache(tokens[tokens.length - 1]);
+            }
+          }
+        } else {
+          buf += text.charAt(i);
+        }
+      }
+    }
+
+    filterLine(seenTag, true);
+
+    return tokens;
+  }
+
+  function cleanTripleStache(token) {
+    if (token.n.substr(token.n.length - 1) === '}') {
+      token.n = token.n.substring(0, token.n.length - 1);
+    }
+  }
+
+  function trim(s) {
+    if (s.trim) {
+      return s.trim();
+    }
+
+    return s.replace(/^\s*|\s*$/g, '');
+  }
+
+  function tagChange(tag, text, index) {
+    if (text.charAt(index) != tag.charAt(0)) {
+      return false;
+    }
+
+    for (var i = 1, l = tag.length; i < l; i++) {
+      if (text.charAt(index + i) != tag.charAt(i)) {
+        return false;
+      }
+    }
+
+    return true;
+  }
+
+  // the tags allowed inside super templates
+  var allowedInSuper = {'_t': true, '\n': true, '$': true, '/': true};
+
+  function buildTree(tokens, kind, stack, customTags) {
+    var instructions = [],
+        opener = null,
+        tail = null,
+        token = null;
+
+    tail = stack[stack.length - 1];
+
+    while (tokens.length > 0) {
+      token = tokens.shift();
+
+      if (tail && tail.tag == '<' && !(token.tag in allowedInSuper)) {
+        throw new Error('Illegal content in < super tag.');
+      }
+
+      if (Hogan.tags[token.tag] <= Hogan.tags['$'] || isOpener(token, customTags)) {
+        stack.push(token);
+        token.nodes = buildTree(tokens, token.tag, stack, customTags);
+      } else if (token.tag == '/') {
+        if (stack.length === 0) {
+          throw new Error('Closing tag without opener: /' + token.n);
+        }
+        opener = stack.pop();
+        if (token.n != opener.n && !isCloser(token.n, opener.n, customTags)) {
+          throw new Error('Nesting error: ' + opener.n + ' vs. ' + token.n);
+        }
+        opener.end = token.i;
+        return instructions;
+      } else if (token.tag == '\n') {
+        token.last = (tokens.length == 0) || (tokens[0].tag == '\n');
+      }
+
+      instructions.push(token);
+    }
+
+    if (stack.length > 0) {
+      throw new Error('missing closing tag: ' + stack.pop().n);
+    }
+
+    return instructions;
+  }
+
+  function isOpener(token, tags) {
+    for (var i = 0, l = tags.length; i < l; i++) {
+      if (tags[i].o == token.n) {
+        token.tag = '#';
+        return true;
+      }
+    }
+  }
+
+  function isCloser(close, open, tags) {
+    for (var i = 0, l = tags.length; i < l; i++) {
+      if (tags[i].c == close && tags[i].o == open) {
+        return true;
+      }
+    }
+  }
+
+  function stringifySubstitutions(obj) {
+    var items = [];
+    for (var key in obj) {
+      items.push('"' + esc(key) + '": function(c,p,t,i) {' + obj[key] + '}');
+    }
+    return "{ " + items.join(",") + " }";
+  }
+
+  function stringifyPartials(codeObj) {
+    var partials = [];
+    for (var key in codeObj.partials) {
+      partials.push('"' + esc(key) + '":{name:"' + esc(codeObj.partials[key].name) + '", ' + stringifyPartials(codeObj.partials[key]) + "}");
+    }
+    return "partials: {" + partials.join(",") + "}, subs: " + stringifySubstitutions(codeObj.subs);
+  }
+
+  Hogan.stringify = function(codeObj, text, options) {
+    return "{code: function (c,p,i) { " + Hogan.wrapMain(codeObj.code) + " }," + stringifyPartials(codeObj) +  "}";
+  }
+
+  var serialNo = 0;
+  Hogan.generate = function(tree, text, options) {
+    serialNo = 0;
+    var context = { code: '', subs: {}, partials: {} };
+    Hogan.walk(tree, context);
+
+    if (options.asString) {
+      return this.stringify(context, text, options);
+    }
+
+    return this.makeTemplate(context, text, options);
+  }
+
+  Hogan.wrapMain = function(code) {
+    return 'var t=this;t.b(i=i||"");' + code + 'return t.fl();';
+  }
+
+  Hogan.template = Hogan.Template;
+
+  Hogan.makeTemplate = function(codeObj, text, options) {
+    var template = this.makePartials(codeObj);
+    template.code = new Function('c', 'p', 'i', this.wrapMain(codeObj.code));
+    return new this.template(template, text, this, options);
+  }
+
+  Hogan.makePartials = function(codeObj) {
+    var key, template = {subs: {}, partials: codeObj.partials, name: codeObj.name};
+    for (key in template.partials) {
+      template.partials[key] = this.makePartials(template.partials[key]);
+    }
+    for (key in codeObj.subs) {
+      template.subs[key] = new Function('c', 'p', 't', 'i', codeObj.subs[key]);
+    }
+    return template;
+  }
+
+  function esc(s) {
+    return s.replace(rSlash, '\\\\')
+            .replace(rQuot, '\\\"')
+            .replace(rNewline, '\\n')
+            .replace(rCr, '\\r')
+            .replace(rLineSep, '\\u2028')
+            .replace(rParagraphSep, '\\u2029');
+  }
+
+  function chooseMethod(s) {
+    return (~s.indexOf('.')) ? 'd' : 'f';
+  }
+
+  function createPartial(node, context) {
+    var prefix = "<" + (context.prefix || "");
+    var sym = prefix + node.n + serialNo++;
+    context.partials[sym] = {name: node.n, partials: {}};
+    context.code += 't.b(t.rp("' +  esc(sym) + '",c,p,"' + (node.indent || '') + '"));';
+    return sym;
+  }
+
+  Hogan.codegen = {
+    '#': function(node, context) {
+      context.code += 'if(t.s(t.' + chooseMethod(node.n) + '("' + esc(node.n) + '",c,p,1),' +
+                      'c,p,0,' + node.i + ',' + node.end + ',"' + node.otag + " " + node.ctag + '")){' +
+                      't.rs(c,p,' + 'function(c,p,t){';
+      Hogan.walk(node.nodes, context);
+      context.code += '});c.pop();}';
+    },
+
+    '^': function(node, context) {
+      context.code += 'if(!t.s(t.' + chooseMethod(node.n) + '("' + esc(node.n) + '",c,p,1),c,p,1,0,0,"")){';
+      Hogan.walk(node.nodes, context);
+      context.code += '};';
+    },
+
+    '>': createPartial,
+    '<': function(node, context) {
+      var ctx = {partials: {}, code: '', subs: {}, inPartial: true};
+      Hogan.walk(node.nodes, ctx);
+      var template = context.partials[createPartial(node, context)];
+      template.subs = ctx.subs;
+      template.partials = ctx.partials;
+    },
+
+    '$': function(node, context) {
+      var ctx = {subs: {}, code: '', partials: context.partials, prefix: node.n};
+      Hogan.walk(node.nodes, ctx);
+      context.subs[node.n] = ctx.code;
+      if (!context.inPartial) {
+        context.code += 't.sub("' + esc(node.n) + '",c,p,i);';
+      }
+    },
+
+    '\n': function(node, context) {
+      context.code += write('"\\n"' + (node.last ? '' : ' + i'));
+    },
+
+    '_v': function(node, context) {
+      context.code += 't.b(t.v(t.' + chooseMethod(node.n) + '("' + esc(node.n) + '",c,p,0)));';
+    },
+
+    '_t': function(node, context) {
+      context.code += write('"' + esc(node.text) + '"');
+    },
+
+    '{': tripleStache,
+
+    '&': tripleStache
+  }
+
+  function tripleStache(node, context) {
+    context.code += 't.b(t.t(t.' + chooseMethod(node.n) + '("' + esc(node.n) + '",c,p,0)));';
+  }
+
+  function write(s) {
+    return 't.b(' + s + ');';
+  }
+
+  Hogan.walk = function(nodelist, context) {
+    var func;
+    for (var i = 0, l = nodelist.length; i < l; i++) {
+      func = Hogan.codegen[nodelist[i].tag];
+      func && func(nodelist[i], context);
+    }
+    return context;
+  }
+
+  Hogan.parse = function(tokens, text, options) {
+    options = options || {};
+    return buildTree(tokens, '', [], options.sectionTags || []);
+  }
+
+  Hogan.cache = {};
+
+  Hogan.cacheKey = function(text, options) {
+    return [text, !!options.asString, !!options.disableLambda, options.delimiters, !!options.modelGet].join('||');
+  }
+
+  Hogan.compile = function(text, options) {
+    options = options || {};
+    var key = Hogan.cacheKey(text, options);
+    var template = this.cache[key];
+
+    if (template) {
+      var partials = template.partials;
+      for (var name in partials) {
+        delete partials[name].instance;
+      }
+      return template;
+    }
+
+    template = this.generate(this.parse(this.scan(text, options.delimiters), text, options), text, options);
+    return this.cache[key] = template;
+  }
+})(typeof exports !== 'undefined' ? exports : Hogan);
+
+},{}],4:[function(require,module,exports){
+/*
+ *  Copyright 2011 Twitter, Inc.
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+// This file is for use with Node.js. See dist/ for browser files.
+
+var Hogan = require('./compiler');
+Hogan.Template = require('./template').Template;
+Hogan.template = Hogan.Template;
+module.exports = Hogan;
+
+},{"./compiler":3,"./template":5}],5:[function(require,module,exports){
+/*
+ *  Copyright 2011 Twitter, Inc.
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+var Hogan = {};
+
+(function (Hogan) {
+  Hogan.Template = function (codeObj, text, compiler, options) {
+    codeObj = codeObj || {};
+    this.r = codeObj.code || this.r;
+    this.c = compiler;
+    this.options = options || {};
+    this.text = text || '';
+    this.partials = codeObj.partials || {};
+    this.subs = codeObj.subs || {};
+    this.buf = '';
+  }
+
+  Hogan.Template.prototype = {
+    // render: replaced by generated code.
+    r: function (context, partials, indent) { return ''; },
+
+    // variable escaping
+    v: hoganEscape,
+
+    // triple stache
+    t: coerceToString,
+
+    render: function render(context, partials, indent) {
+      return this.ri([context], partials || {}, indent);
+    },
+
+    // render internal -- a hook for overrides that catches partials too
+    ri: function (context, partials, indent) {
+      return this.r(context, partials, indent);
+    },
+
+    // ensurePartial
+    ep: function(symbol, partials) {
+      var partial = this.partials[symbol];
+
+      // check to see that if we've instantiated this partial before
+      var template = partials[partial.name];
+      if (partial.instance && partial.base == template) {
+        return partial.instance;
+      }
+
+      if (typeof template == 'string') {
+        if (!this.c) {
+          throw new Error("No compiler available.");
+        }
+        template = this.c.compile(template, this.options);
+      }
+
+      if (!template) {
+        return null;
+      }
+
+      // We use this to check whether the partials dictionary has changed
+      this.partials[symbol].base = template;
+
+      if (partial.subs) {
+        // Make sure we consider parent template now
+        if (!partials.stackText) partials.stackText = {};
+        for (key in partial.subs) {
+          if (!partials.stackText[key]) {
+            partials.stackText[key] = (this.activeSub !== undefined && partials.stackText[this.activeSub]) ? partials.stackText[this.activeSub] : this.text;
+          }
+        }
+        template = createSpecializedPartial(template, partial.subs, partial.partials,
+          this.stackSubs, this.stackPartials, partials.stackText);
+      }
+      this.partials[symbol].instance = template;
+
+      return template;
+    },
+
+    // tries to find a partial in the current scope and render it
+    rp: function(symbol, context, partials, indent) {
+      var partial = this.ep(symbol, partials);
+      if (!partial) {
+        return '';
+      }
+
+      return partial.ri(context, partials, indent);
+    },
+
+    // render a section
+    rs: function(context, partials, section) {
+      var tail = context[context.length - 1];
+
+      if (!isArray(tail)) {
+        section(context, partials, this);
+        return;
+      }
+
+      for (var i = 0; i < tail.length; i++) {
+        context.push(tail[i]);
+        section(context, partials, this);
+        context.pop();
+      }
+    },
+
+    // maybe start a section
+    s: function(val, ctx, partials, inverted, start, end, tags) {
+      var pass;
+
+      if (isArray(val) && val.length === 0) {
+        return false;
+      }
+
+      if (typeof val == 'function') {
+        val = this.ms(val, ctx, partials, inverted, start, end, tags);
+      }
+
+      pass = !!val;
+
+      if (!inverted && pass && ctx) {
+        ctx.push((typeof val == 'object') ? val : ctx[ctx.length - 1]);
+      }
+
+      return pass;
+    },
+
+    // find values with dotted names
+    d: function(key, ctx, partials, returnFound) {
+      var found,
+          names = key.split('.'),
+          val = this.f(names[0], ctx, partials, returnFound),
+          doModelGet = this.options.modelGet,
+          cx = null;
+
+      if (key === '.' && isArray(ctx[ctx.length - 2])) {
+        val = ctx[ctx.length - 1];
+      } else {
+        for (var i = 1; i < names.length; i++) {
+          found = findInScope(names[i], val, doModelGet);
+          if (found !== undefined) {
+            cx = val;
+            val = found;
+          } else {
+            val = '';
+          }
+        }
+      }
+
+      if (returnFound && !val) {
+        return false;
+      }
+
+      if (!returnFound && typeof val == 'function') {
+        ctx.push(cx);
+        val = this.mv(val, ctx, partials);
+        ctx.pop();
+      }
+
+      return val;
+    },
+
+    // find values with normal names
+    f: function(key, ctx, partials, returnFound) {
+      var val = false,
+          v = null,
+          found = false,
+          doModelGet = this.options.modelGet;
+
+      for (var i = ctx.length - 1; i >= 0; i--) {
+        v = ctx[i];
+        val = findInScope(key, v, doModelGet);
+        if (val !== undefined) {
+          found = true;
+          break;
+        }
+      }
+
+      if (!found) {
+        return (returnFound) ? false : "";
+      }
+
+      if (!returnFound && typeof val == 'function') {
+        val = this.mv(val, ctx, partials);
+      }
+
+      return val;
+    },
+
+    // higher order templates
+    ls: function(func, cx, partials, text, tags) {
+      var oldTags = this.options.delimiters;
+
+      this.options.delimiters = tags;
+      this.b(this.ct(coerceToString(func.call(cx, text)), cx, partials));
+      this.options.delimiters = oldTags;
+
+      return false;
+    },
+
+    // compile text
+    ct: function(text, cx, partials) {
+      if (this.options.disableLambda) {
+        throw new Error('Lambda features disabled.');
+      }
+      return this.c.compile(text, this.options).render(cx, partials);
+    },
+
+    // template result buffering
+    b: function(s) { this.buf += s; },
+
+    fl: function() { var r = this.buf; this.buf = ''; return r; },
+
+    // method replace section
+    ms: function(func, ctx, partials, inverted, start, end, tags) {
+      var textSource,
+          cx = ctx[ctx.length - 1],
+          result = func.call(cx);
+
+      if (typeof result == 'function') {
+        if (inverted) {
+          return true;
+        } else {
+          textSource = (this.activeSub && this.subsText && this.subsText[this.activeSub]) ? this.subsText[this.activeSub] : this.text;
+          return this.ls(result, cx, partials, textSource.substring(start, end), tags);
+        }
+      }
+
+      return result;
+    },
+
+    // method replace variable
+    mv: function(func, ctx, partials) {
+      var cx = ctx[ctx.length - 1];
+      var result = func.call(cx);
+
+      if (typeof result == 'function') {
+        return this.ct(coerceToString(result.call(cx)), cx, partials);
+      }
+
+      return result;
+    },
+
+    sub: function(name, context, partials, indent) {
+      var f = this.subs[name];
+      if (f) {
+        this.activeSub = name;
+        f(context, partials, this, indent);
+        this.activeSub = false;
+      }
+    }
+
+  };
+
+  //Find a key in an object
+  function findInScope(key, scope, doModelGet) {
+    var val;
+
+    if (scope && typeof scope == 'object') {
+
+      if (scope[key] !== undefined) {
+        val = scope[key];
+
+      // try lookup with get for backbone or similar model data
+      } else if (doModelGet && scope.get && typeof scope.get == 'function') {
+        val = scope.get(key);
+      }
+    }
+
+    return val;
+  }
+
+  function createSpecializedPartial(instance, subs, partials, stackSubs, stackPartials, stackText) {
+    function PartialTemplate() {};
+    PartialTemplate.prototype = instance;
+    function Substitutions() {};
+    Substitutions.prototype = instance.subs;
+    var key;
+    var partial = new PartialTemplate();
+    partial.subs = new Substitutions();
+    partial.subsText = {};  //hehe. substext.
+    partial.buf = '';
+
+    stackSubs = stackSubs || {};
+    partial.stackSubs = stackSubs;
+    partial.subsText = stackText;
+    for (key in subs) {
+      if (!stackSubs[key]) stackSubs[key] = subs[key];
+    }
+    for (key in stackSubs) {
+      partial.subs[key] = stackSubs[key];
+    }
+
+    stackPartials = stackPartials || {};
+    partial.stackPartials = stackPartials;
+    for (key in partials) {
+      if (!stackPartials[key]) stackPartials[key] = partials[key];
+    }
+    for (key in stackPartials) {
+      partial.partials[key] = stackPartials[key];
+    }
+
+    return partial;
+  }
+
+  var rAmp = /&/g,
+      rLt = /</g,
+      rGt = />/g,
+      rApos = /\'/g,
+      rQuot = /\"/g,
+      hChars = /[&<>\"\']/;
+
+  function coerceToString(val) {
+    return String((val === null || val === undefined) ? '' : val);
+  }
+
+  function hoganEscape(str) {
+    str = coerceToString(str);
+    return hChars.test(str) ?
+      str
+        .replace(rAmp, '&amp;')
+        .replace(rLt, '&lt;')
+        .replace(rGt, '&gt;')
+        .replace(rApos, '&#39;')
+        .replace(rQuot, '&quot;') :
+      str;
+  }
+
+  var isArray = Array.isArray || function(a) {
+    return Object.prototype.toString.call(a) === '[object Array]';
+  };
+
+})(typeof exports !== 'undefined' ? exports : Hogan);
+
+},{}],6:[function(require,module,exports){
+var hashClear = require('./_hashClear'),
+    hashDelete = require('./_hashDelete'),
+    hashGet = require('./_hashGet'),
+    hashHas = require('./_hashHas'),
+    hashSet = require('./_hashSet');
+
+/**
+ * Creates a hash object.
+ *
+ * @private
+ * @constructor
+ * @param {Array} [entries] The key-value pairs to cache.
+ */
+function Hash(entries) {
+  var index = -1,
+      length = entries == null ? 0 : entries.length;
+
+  this.clear();
+  while (++index < length) {
+    var entry = entries[index];
+    this.set(entry[0], entry[1]);
+  }
+}
+
+// Add methods to `Hash`.
+Hash.prototype.clear = hashClear;
+Hash.prototype['delete'] = hashDelete;
+Hash.prototype.get = hashGet;
+Hash.prototype.has = hashHas;
+Hash.prototype.set = hashSet;
+
+module.exports = Hash;
+
+},{"./_hashClear":47,"./_hashDelete":48,"./_hashGet":49,"./_hashHas":50,"./_hashSet":51}],7:[function(require,module,exports){
+var listCacheClear = require('./_listCacheClear'),
+    listCacheDelete = require('./_listCacheDelete'),
+    listCacheGet = require('./_listCacheGet'),
+    listCacheHas = require('./_listCacheHas'),
+    listCacheSet = require('./_listCacheSet');
+
+/**
+ * Creates an list cache object.
+ *
+ * @private
+ * @constructor
+ * @param {Array} [entries] The key-value pairs to cache.
+ */
+function ListCache(entries) {
+  var index = -1,
+      length = entries == null ? 0 : entries.length;
+
+  this.clear();
+  while (++index < length) {
+    var entry = entries[index];
+    this.set(entry[0], entry[1]);
+  }
+}
+
+// Add methods to `ListCache`.
+ListCache.prototype.clear = listCacheClear;
+ListCache.prototype['delete'] = listCacheDelete;
+ListCache.prototype.get = listCacheGet;
+ListCache.prototype.has = listCacheHas;
+ListCache.prototype.set = listCacheSet;
+
+module.exports = ListCache;
+
+},{"./_listCacheClear":58,"./_listCacheDelete":59,"./_listCacheGet":60,"./_listCacheHas":61,"./_listCacheSet":62}],8:[function(require,module,exports){
+var getNative = require('./_getNative'),
+    root = require('./_root');
+
+/* Built-in method references that are verified to be native. */
+var Map = getNative(root, 'Map');
+
+module.exports = Map;
+
+},{"./_getNative":43,"./_root":74}],9:[function(require,module,exports){
+var mapCacheClear = require('./_mapCacheClear'),
+    mapCacheDelete = require('./_mapCacheDelete'),
+    mapCacheGet = require('./_mapCacheGet'),
+    mapCacheHas = require('./_mapCacheHas'),
+    mapCacheSet = require('./_mapCacheSet');
+
+/**
+ * Creates a map cache object to store key-value pairs.
+ *
+ * @private
+ * @constructor
+ * @param {Array} [entries] The key-value pairs to cache.
+ */
+function MapCache(entries) {
+  var index = -1,
+      length = entries == null ? 0 : entries.length;
+
+  this.clear();
+  while (++index < length) {
+    var entry = entries[index];
+    this.set(entry[0], entry[1]);
+  }
+}
+
+// Add methods to `MapCache`.
+MapCache.prototype.clear = mapCacheClear;
+MapCache.prototype['delete'] = mapCacheDelete;
+MapCache.prototype.get = mapCacheGet;
+MapCache.prototype.has = mapCacheHas;
+MapCache.prototype.set = mapCacheSet;
+
+module.exports = MapCache;
+
+},{"./_mapCacheClear":63,"./_mapCacheDelete":64,"./_mapCacheGet":65,"./_mapCacheHas":66,"./_mapCacheSet":67}],10:[function(require,module,exports){
+var ListCache = require('./_ListCache'),
+    stackClear = require('./_stackClear'),
+    stackDelete = require('./_stackDelete'),
+    stackGet = require('./_stackGet'),
+    stackHas = require('./_stackHas'),
+    stackSet = require('./_stackSet');
+
+/**
+ * Creates a stack cache object to store key-value pairs.
+ *
+ * @private
+ * @constructor
+ * @param {Array} [entries] The key-value pairs to cache.
+ */
+function Stack(entries) {
+  var data = this.__data__ = new ListCache(entries);
+  this.size = data.size;
+}
+
+// Add methods to `Stack`.
+Stack.prototype.clear = stackClear;
+Stack.prototype['delete'] = stackDelete;
+Stack.prototype.get = stackGet;
+Stack.prototype.has = stackHas;
+Stack.prototype.set = stackSet;
+
+module.exports = Stack;
+
+},{"./_ListCache":7,"./_stackClear":78,"./_stackDelete":79,"./_stackGet":80,"./_stackHas":81,"./_stackSet":82}],11:[function(require,module,exports){
+var root = require('./_root');
+
+/** Built-in value references. */
+var Symbol = root.Symbol;
+
+module.exports = Symbol;
+
+},{"./_root":74}],12:[function(require,module,exports){
+var root = require('./_root');
+
+/** Built-in value references. */
+var Uint8Array = root.Uint8Array;
+
+module.exports = Uint8Array;
+
+},{"./_root":74}],13:[function(require,module,exports){
+/**
+ * A faster alternative to `Function#apply`, this function invokes `func`
+ * with the `this` binding of `thisArg` and the arguments of `args`.
+ *
+ * @private
+ * @param {Function} func The function to invoke.
+ * @param {*} thisArg The `this` binding of `func`.
+ * @param {Array} args The arguments to invoke `func` with.
+ * @returns {*} Returns the result of `func`.
+ */
+function apply(func, thisArg, args) {
+  switch (args.length) {
+    case 0: return func.call(thisArg);
+    case 1: return func.call(thisArg, args[0]);
+    case 2: return func.call(thisArg, args[0], args[1]);
+    case 3: return func.call(thisArg, args[0], args[1], args[2]);
+  }
+  return func.apply(thisArg, args);
+}
+
+module.exports = apply;
+
+},{}],14:[function(require,module,exports){
+var baseTimes = require('./_baseTimes'),
+    isArguments = require('./isArguments'),
+    isArray = require('./isArray'),
+    isBuffer = require('./isBuffer'),
+    isIndex = require('./_isIndex'),
+    isTypedArray = require('./isTypedArray');
+
+/** Used for built-in method references. */
+var objectProto = Object.prototype;
+
+/** Used to check objects for own properties. */
+var hasOwnProperty = objectProto.hasOwnProperty;
+
+/**
+ * Creates an array of the enumerable property names of the array-like `value`.
+ *
+ * @private
+ * @param {*} value The value to query.
+ * @param {boolean} inherited Specify returning inherited property names.
+ * @returns {Array} Returns the array of property names.
+ */
+function arrayLikeKeys(value, inherited) {
+  var isArr = isArray(value),
+      isArg = !isArr && isArguments(value),
+      isBuff = !isArr && !isArg && isBuffer(value),
+      isType = !isArr && !isArg && !isBuff && isTypedArray(value),
+      skipIndexes = isArr || isArg || isBuff || isType,
+      result = skipIndexes ? baseTimes(value.length, String) : [],
+      length = result.length;
+
+  for (var key in value) {
+    if ((inherited || hasOwnProperty.call(value, key)) &&
+        !(skipIndexes && (
+           // Safari 9 has enumerable `arguments.length` in strict mode.
+           key == 'length' ||
+           // Node.js 0.10 has enumerable non-index properties on buffers.
+           (isBuff && (key == 'offset' || key == 'parent')) ||
+           // PhantomJS 2 has enumerable non-index properties on typed arrays.
+           (isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) ||
+           // Skip index properties.
+           isIndex(key, length)
+        ))) {
+      result.push(key);
+    }
+  }
+  return result;
+}
+
+module.exports = arrayLikeKeys;
+
+},{"./_baseTimes":30,"./_isIndex":53,"./isArguments":87,"./isArray":88,"./isBuffer":91,"./isTypedArray":97}],15:[function(require,module,exports){
+var baseAssignValue = require('./_baseAssignValue'),
+    eq = require('./eq');
+
+/**
+ * This function is like `assignValue` except that it doesn't assign
+ * `undefined` values.
+ *
+ * @private
+ * @param {Object} object The object to modify.
+ * @param {string} key The key of the property to assign.
+ * @param {*} value The value to assign.
+ */
+function assignMergeValue(object, key, value) {
+  if ((value !== undefined && !eq(object[key], value)) ||
+      (value === undefined && !(key in object))) {
+    baseAssignValue(object, key, value);
+  }
+}
+
+module.exports = assignMergeValue;
+
+},{"./_baseAssignValue":18,"./eq":85}],16:[function(require,module,exports){
+var baseAssignValue = require('./_baseAssignValue'),
+    eq = require('./eq');
+
+/** Used for built-in method references. */
+var objectProto = Object.prototype;
+
+/** Used to check objects for own properties. */
+var hasOwnProperty = objectProto.hasOwnProperty;
+
+/**
+ * Assigns `value` to `key` of `object` if the existing value is not equivalent
+ * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
+ * for equality comparisons.
+ *
+ * @private
+ * @param {Object} object The object to modify.
+ * @param {string} key The key of the property to assign.
+ * @param {*} value The value to assign.
+ */
+function assignValue(object, key, value) {
+  var objValue = object[key];
+  if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) ||
+      (value === undefined && !(key in object))) {
+    baseAssignValue(object, key, value);
+  }
+}
+
+module.exports = assignValue;
+
+},{"./_baseAssignValue":18,"./eq":85}],17:[function(require,module,exports){
+var eq = require('./eq');
+
+/**
+ * Gets the index at which the `key` is found in `array` of key-value pairs.
+ *
+ * @private
+ * @param {Array} array The array to inspect.
+ * @param {*} key The key to search for.
+ * @returns {number} Returns the index of the matched value, else `-1`.
+ */
+function assocIndexOf(array, key) {
+  var length = array.length;
+  while (length--) {
+    if (eq(array[length][0], key)) {
+      return length;
+    }
+  }
+  return -1;
+}
+
+module.exports = assocIndexOf;
+
+},{"./eq":85}],18:[function(require,module,exports){
+var defineProperty = require('./_defineProperty');
+
+/**
+ * The base implementation of `assignValue` and `assignMergeValue` without
+ * value checks.
+ *
+ * @private
+ * @param {Object} object The object to modify.
+ * @param {string} key The key of the property to assign.
+ * @param {*} value The value to assign.
+ */
+function baseAssignValue(object, key, value) {
+  if (key == '__proto__' && defineProperty) {
+    defineProperty(object, key, {
+      'configurable': true,
+      'enumerable': true,
+      'value': value,
+      'writable': true
+    });
+  } else {
+    object[key] = value;
+  }
+}
+
+module.exports = baseAssignValue;
+
+},{"./_defineProperty":40}],19:[function(require,module,exports){
+var isObject = require('./isObject');
+
+/** Built-in value references. */
+var objectCreate = Object.create;
+
+/**
+ * The base implementation of `_.create` without support for assigning
+ * properties to the created object.
+ *
+ * @private
+ * @param {Object} proto The object to inherit from.
+ * @returns {Object} Returns the new object.
+ */
+var baseCreate = (function() {
+  function object() {}
+  return function(proto) {
+    if (!isObject(proto)) {
+      return {};
+    }
+    if (objectCreate) {
+      return objectCreate(proto);
+    }
+    object.prototype = proto;
+    var result = new object;
+    object.prototype = undefined;
+    return result;
+  };
+}());
+
+module.exports = baseCreate;
+
+},{"./isObject":94}],20:[function(require,module,exports){
+var createBaseFor = require('./_createBaseFor');
+
+/**
+ * The base implementation of `baseForOwn` which iterates over `object`
+ * properties returned by `keysFunc` and invokes `iteratee` for each property.
+ * Iteratee functions may exit iteration early by explicitly returning `false`.
+ *
+ * @private
+ * @param {Object} object The object to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @param {Function} keysFunc The function to get the keys of `object`.
+ * @returns {Object} Returns `object`.
+ */
+var baseFor = createBaseFor();
+
+module.exports = baseFor;
+
+},{"./_createBaseFor":39}],21:[function(require,module,exports){
+var Symbol = require('./_Symbol'),
+    getRawTag = require('./_getRawTag'),
+    objectToString = require('./_objectToString');
+
+/** `Object#toString` result references. */
+var nullTag = '[object Null]',
+    undefinedTag = '[object Undefined]';
+
+/** Built-in value references. */
+var symToStringTag = Symbol ? Symbol.toStringTag : undefined;
+
+/**
+ * The base implementation of `getTag` without fallbacks for buggy environments.
+ *
+ * @private
+ * @param {*} value The value to query.
+ * @returns {string} Returns the `toStringTag`.
+ */
+function baseGetTag(value) {
+  if (value == null) {
+    return value === undefined ? undefinedTag : nullTag;
+  }
+  return (symToStringTag && symToStringTag in Object(value))
+    ? getRawTag(value)
+    : objectToString(value);
+}
+
+module.exports = baseGetTag;
+
+},{"./_Symbol":11,"./_getRawTag":45,"./_objectToString":71}],22:[function(require,module,exports){
+var baseGetTag = require('./_baseGetTag'),
+    isObjectLike = require('./isObjectLike');
+
+/** `Object#toString` result references. */
+var argsTag = '[object Arguments]';
+
+/**
+ * The base implementation of `_.isArguments`.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is an `arguments` object,
+ */
+function baseIsArguments(value) {
+  return isObjectLike(value) && baseGetTag(value) == argsTag;
+}
+
+module.exports = baseIsArguments;
+
+},{"./_baseGetTag":21,"./isObjectLike":95}],23:[function(require,module,exports){
+var isFunction = require('./isFunction'),
+    isMasked = require('./_isMasked'),
+    isObject = require('./isObject'),
+    toSource = require('./_toSource');
+
+/**
+ * Used to match `RegExp`
+ * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).
+ */
+var reRegExpChar = /[\\^$.*+?()[\]{}|]/g;
+
+/** Used to detect host constructors (Safari). */
+var reIsHostCtor = /^\[object .+?Constructor\]$/;
+
+/** Used for built-in method references. */
+var funcProto = Function.prototype,
+    objectProto = Object.prototype;
+
+/** Used to resolve the decompiled source of functions. */
+var funcToString = funcProto.toString;
+
+/** Used to check objects for own properties. */
+var hasOwnProperty = objectProto.hasOwnProperty;
+
+/** Used to detect if a method is native. */
+var reIsNative = RegExp('^' +
+  funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&')
+  .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
+);
+
+/**
+ * The base implementation of `_.isNative` without bad shim checks.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a native function,
+ *  else `false`.
+ */
+function baseIsNative(value) {
+  if (!isObject(value) || isMasked(value)) {
+    return false;
+  }
+  var pattern = isFunction(value) ? reIsNative : reIsHostCtor;
+  return pattern.test(toSource(value));
+}
+
+module.exports = baseIsNative;
+
+},{"./_isMasked":56,"./_toSource":83,"./isFunction":92,"./isObject":94}],24:[function(require,module,exports){
+var baseGetTag = require('./_baseGetTag'),
+    isLength = require('./isLength'),
+    isObjectLike = require('./isObjectLike');
+
+/** `Object#toString` result references. */
+var argsTag = '[object Arguments]',
+    arrayTag = '[object Array]',
+    boolTag = '[object Boolean]',
+    dateTag = '[object Date]',
+    errorTag = '[object Error]',
+    funcTag = '[object Function]',
+    mapTag = '[object Map]',
+    numberTag = '[object Number]',
+    objectTag = '[object Object]',
+    regexpTag = '[object RegExp]',
+    setTag = '[object Set]',
+    stringTag = '[object String]',
+    weakMapTag = '[object WeakMap]';
+
+var arrayBufferTag = '[object ArrayBuffer]',
+    dataViewTag = '[object DataView]',
+    float32Tag = '[object Float32Array]',
+    float64Tag = '[object Float64Array]',
+    int8Tag = '[object Int8Array]',
+    int16Tag = '[object Int16Array]',
+    int32Tag = '[object Int32Array]',
+    uint8Tag = '[object Uint8Array]',
+    uint8ClampedTag = '[object Uint8ClampedArray]',
+    uint16Tag = '[object Uint16Array]',
+    uint32Tag = '[object Uint32Array]';
+
+/** Used to identify `toStringTag` values of typed arrays. */
+var typedArrayTags = {};
+typedArrayTags[float32Tag] = typedArrayTags[float64Tag] =
+typedArrayTags[int8Tag] = typedArrayTags[int16Tag] =
+typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =
+typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =
+typedArrayTags[uint32Tag] = true;
+typedArrayTags[argsTag] = typedArrayTags[arrayTag] =
+typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =
+typedArrayTags[dataViewTag] = typedArrayTags[dateTag] =
+typedArrayTags[errorTag] = typedArrayTags[funcTag] =
+typedArrayTags[mapTag] = typedArrayTags[numberTag] =
+typedArrayTags[objectTag] = typedArrayTags[regexpTag] =
+typedArrayTags[setTag] = typedArrayTags[stringTag] =
+typedArrayTags[weakMapTag] = false;
+
+/**
+ * The base implementation of `_.isTypedArray` without Node.js optimizations.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
+ */
+function baseIsTypedArray(value) {
+  return isObjectLike(value) &&
+    isLength(value.length) && !!typedArrayTags[baseGetTag(value)];
+}
+
+module.exports = baseIsTypedArray;
+
+},{"./_baseGetTag":21,"./isLength":93,"./isObjectLike":95}],25:[function(require,module,exports){
+var isObject = require('./isObject'),
+    isPrototype = require('./_isPrototype'),
+    nativeKeysIn = require('./_nativeKeysIn');
+
+/** Used for built-in method references. */
+var objectProto = Object.prototype;
+
+/** Used to check objects for own properties. */
+var hasOwnProperty = objectProto.hasOwnProperty;
+
+/**
+ * The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @returns {Array} Returns the array of property names.
+ */
+function baseKeysIn(object) {
+  if (!isObject(object)) {
+    return nativeKeysIn(object);
+  }
+  var isProto = isPrototype(object),
+      result = [];
+
+  for (var key in object) {
+    if (!(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {
+      result.push(key);
+    }
+  }
+  return result;
+}
+
+module.exports = baseKeysIn;
+
+},{"./_isPrototype":57,"./_nativeKeysIn":69,"./isObject":94}],26:[function(require,module,exports){
+var Stack = require('./_Stack'),
+    assignMergeValue = require('./_assignMergeValue'),
+    baseFor = require('./_baseFor'),
+    baseMergeDeep = require('./_baseMergeDeep'),
+    isObject = require('./isObject'),
+    keysIn = require('./keysIn'),
+    safeGet = require('./_safeGet');
+
+/**
+ * The base implementation of `_.merge` without support for multiple sources.
+ *
+ * @private
+ * @param {Object} object The destination object.
+ * @param {Object} source The source object.
+ * @param {number} srcIndex The index of `source`.
+ * @param {Function} [customizer] The function to customize merged values.
+ * @param {Object} [stack] Tracks traversed source values and their merged
+ *  counterparts.
+ */
+function baseMerge(object, source, srcIndex, customizer, stack) {
+  if (object === source) {
+    return;
+  }
+  baseFor(source, function(srcValue, key) {
+    if (isObject(srcValue)) {
+      stack || (stack = new Stack);
+      baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack);
+    }
+    else {
+      var newValue = customizer
+        ? customizer(safeGet(object, key), srcValue, (key + ''), object, source, stack)
+        : undefined;
+
+      if (newValue === undefined) {
+        newValue = srcValue;
+      }
+      assignMergeValue(object, key, newValue);
+    }
+  }, keysIn);
+}
+
+module.exports = baseMerge;
+
+},{"./_Stack":10,"./_assignMergeValue":15,"./_baseFor":20,"./_baseMergeDeep":27,"./_safeGet":75,"./isObject":94,"./keysIn":98}],27:[function(require,module,exports){
+var assignMergeValue = require('./_assignMergeValue'),
+    cloneBuffer = require('./_cloneBuffer'),
+    cloneTypedArray = require('./_cloneTypedArray'),
+    copyArray = require('./_copyArray'),
+    initCloneObject = require('./_initCloneObject'),
+    isArguments = require('./isArguments'),
+    isArray = require('./isArray'),
+    isArrayLikeObject = require('./isArrayLikeObject'),
+    isBuffer = require('./isBuffer'),
+    isFunction = require('./isFunction'),
+    isObject = require('./isObject'),
+    isPlainObject = require('./isPlainObject'),
+    isTypedArray = require('./isTypedArray'),
+    safeGet = require('./_safeGet'),
+    toPlainObject = require('./toPlainObject');
+
+/**
+ * A specialized version of `baseMerge` for arrays and objects which performs
+ * deep merges and tracks traversed objects enabling objects with circular
+ * references to be merged.
+ *
+ * @private
+ * @param {Object} object The destination object.
+ * @param {Object} source The source object.
+ * @param {string} key The key of the value to merge.
+ * @param {number} srcIndex The index of `source`.
+ * @param {Function} mergeFunc The function to merge values.
+ * @param {Function} [customizer] The function to customize assigned values.
+ * @param {Object} [stack] Tracks traversed source values and their merged
+ *  counterparts.
+ */
+function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) {
+  var objValue = safeGet(object, key),
+      srcValue = safeGet(source, key),
+      stacked = stack.get(srcValue);
+
+  if (stacked) {
+    assignMergeValue(object, key, stacked);
+    return;
+  }
+  var newValue = customizer
+    ? customizer(objValue, srcValue, (key + ''), object, source, stack)
+    : undefined;
+
+  var isCommon = newValue === undefined;
+
+  if (isCommon) {
+    var isArr = isArray(srcValue),
+        isBuff = !isArr && isBuffer(srcValue),
+        isTyped = !isArr && !isBuff && isTypedArray(srcValue);
+
+    newValue = srcValue;
+    if (isArr || isBuff || isTyped) {
+      if (isArray(objValue)) {
+        newValue = objValue;
+      }
+      else if (isArrayLikeObject(objValue)) {
+        newValue = copyArray(objValue);
+      }
+      else if (isBuff) {
+        isCommon = false;
+        newValue = cloneBuffer(srcValue, true);
+      }
+      else if (isTyped) {
+        isCommon = false;
+        newValue = cloneTypedArray(srcValue, true);
+      }
+      else {
+        newValue = [];
+      }
+    }
+    else if (isPlainObject(srcValue) || isArguments(srcValue)) {
+      newValue = objValue;
+      if (isArguments(objValue)) {
+        newValue = toPlainObject(objValue);
+      }
+      else if (!isObject(objValue) || (srcIndex && isFunction(objValue))) {
+        newValue = initCloneObject(srcValue);
+      }
+    }
+    else {
+      isCommon = false;
+    }
+  }
+  if (isCommon) {
+    // Recursively merge objects and arrays (susceptible to call stack limits).
+    stack.set(srcValue, newValue);
+    mergeFunc(newValue, srcValue, srcIndex, customizer, stack);
+    stack['delete'](srcValue);
+  }
+  assignMergeValue(object, key, newValue);
+}
+
+module.exports = baseMergeDeep;
+
+},{"./_assignMergeValue":15,"./_cloneBuffer":33,"./_cloneTypedArray":34,"./_copyArray":35,"./_initCloneObject":52,"./_safeGet":75,"./isArguments":87,"./isArray":88,"./isArrayLikeObject":90,"./isBuffer":91,"./isFunction":92,"./isObject":94,"./isPlainObject":96,"./isTypedArray":97,"./toPlainObject":101}],28:[function(require,module,exports){
+var identity = require('./identity'),
+    overRest = require('./_overRest'),
+    setToString = require('./_setToString');
+
+/**
+ * The base implementation of `_.rest` which doesn't validate or coerce arguments.
+ *
+ * @private
+ * @param {Function} func The function to apply a rest parameter to.
+ * @param {number} [start=func.length-1] The start position of the rest parameter.
+ * @returns {Function} Returns the new function.
+ */
+function baseRest(func, start) {
+  return setToString(overRest(func, start, identity), func + '');
+}
+
+module.exports = baseRest;
+
+},{"./_overRest":73,"./_setToString":76,"./identity":86}],29:[function(require,module,exports){
+var constant = require('./constant'),
+    defineProperty = require('./_defineProperty'),
+    identity = require('./identity');
+
+/**
+ * The base implementation of `setToString` without support for hot loop shorting.
+ *
+ * @private
+ * @param {Function} func The function to modify.
+ * @param {Function} string The `toString` result.
+ * @returns {Function} Returns `func`.
+ */
+var baseSetToString = !defineProperty ? identity : function(func, string) {
+  return defineProperty(func, 'toString', {
+    'configurable': true,
+    'enumerable': false,
+    'value': constant(string),
+    'writable': true
+  });
+};
+
+module.exports = baseSetToString;
+
+},{"./_defineProperty":40,"./constant":84,"./identity":86}],30:[function(require,module,exports){
+/**
+ * The base implementation of `_.times` without support for iteratee shorthands
+ * or max array length checks.
+ *
+ * @private
+ * @param {number} n The number of times to invoke `iteratee`.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @returns {Array} Returns the array of results.
+ */
+function baseTimes(n, iteratee) {
+  var index = -1,
+      result = Array(n);
+
+  while (++index < n) {
+    result[index] = iteratee(index);
+  }
+  return result;
+}
+
+module.exports = baseTimes;
+
+},{}],31:[function(require,module,exports){
+/**
+ * The base implementation of `_.unary` without support for storing metadata.
+ *
+ * @private
+ * @param {Function} func The function to cap arguments for.
+ * @returns {Function} Returns the new capped function.
+ */
+function baseUnary(func) {
+  return function(value) {
+    return func(value);
+  };
+}
+
+module.exports = baseUnary;
+
+},{}],32:[function(require,module,exports){
+var Uint8Array = require('./_Uint8Array');
+
+/**
+ * Creates a clone of `arrayBuffer`.
+ *
+ * @private
+ * @param {ArrayBuffer} arrayBuffer The array buffer to clone.
+ * @returns {ArrayBuffer} Returns the cloned array buffer.
+ */
+function cloneArrayBuffer(arrayBuffer) {
+  var result = new arrayBuffer.constructor(arrayBuffer.byteLength);
+  new Uint8Array(result).set(new Uint8Array(arrayBuffer));
+  return result;
+}
+
+module.exports = cloneArrayBuffer;
+
+},{"./_Uint8Array":12}],33:[function(require,module,exports){
+var root = require('./_root');
+
+/** Detect free variable `exports`. */
+var freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports;
+
+/** Detect free variable `module`. */
+var freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module;
+
+/** Detect the popular CommonJS extension `module.exports`. */
+var moduleExports = freeModule && freeModule.exports === freeExports;
+
+/** Built-in value references. */
+var Buffer = moduleExports ? root.Buffer : undefined,
+    allocUnsafe = Buffer ? Buffer.allocUnsafe : undefined;
+
+/**
+ * Creates a clone of  `buffer`.
+ *
+ * @private
+ * @param {Buffer} buffer The buffer to clone.
+ * @param {boolean} [isDeep] Specify a deep clone.
+ * @returns {Buffer} Returns the cloned buffer.
+ */
+function cloneBuffer(buffer, isDeep) {
+  if (isDeep) {
+    return buffer.slice();
+  }
+  var length = buffer.length,
+      result = allocUnsafe ? allocUnsafe(length) : new buffer.constructor(length);
+
+  buffer.copy(result);
+  return result;
+}
+
+module.exports = cloneBuffer;
+
+},{"./_root":74}],34:[function(require,module,exports){
+var cloneArrayBuffer = require('./_cloneArrayBuffer');
+
+/**
+ * Creates a clone of `typedArray`.
+ *
+ * @private
+ * @param {Object} typedArray The typed array to clone.
+ * @param {boolean} [isDeep] Specify a deep clone.
+ * @returns {Object} Returns the cloned typed array.
+ */
+function cloneTypedArray(typedArray, isDeep) {
+  var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer;
+  return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length);
+}
+
+module.exports = cloneTypedArray;
+
+},{"./_cloneArrayBuffer":32}],35:[function(require,module,exports){
+/**
+ * Copies the values of `source` to `array`.
+ *
+ * @private
+ * @param {Array} source The array to copy values from.
+ * @param {Array} [array=[]] The array to copy values to.
+ * @returns {Array} Returns `array`.
+ */
+function copyArray(source, array) {
+  var index = -1,
+      length = source.length;
+
+  array || (array = Array(length));
+  while (++index < length) {
+    array[index] = source[index];
+  }
+  return array;
+}
+
+module.exports = copyArray;
+
+},{}],36:[function(require,module,exports){
+var assignValue = require('./_assignValue'),
+    baseAssignValue = require('./_baseAssignValue');
+
+/**
+ * Copies properties of `source` to `object`.
+ *
+ * @private
+ * @param {Object} source The object to copy properties from.
+ * @param {Array} props The property identifiers to copy.
+ * @param {Object} [object={}] The object to copy properties to.
+ * @param {Function} [customizer] The function to customize copied values.
+ * @returns {Object} Returns `object`.
+ */
+function copyObject(source, props, object, customizer) {
+  var isNew = !object;
+  object || (object = {});
+
+  var index = -1,
+      length = props.length;
+
+  while (++index < length) {
+    var key = props[index];
+
+    var newValue = customizer
+      ? customizer(object[key], source[key], key, object, source)
+      : undefined;
+
+    if (newValue === undefined) {
+      newValue = source[key];
+    }
+    if (isNew) {
+      baseAssignValue(object, key, newValue);
+    } else {
+      assignValue(object, key, newValue);
+    }
+  }
+  return object;
+}
+
+module.exports = copyObject;
+
+},{"./_assignValue":16,"./_baseAssignValue":18}],37:[function(require,module,exports){
+var root = require('./_root');
+
+/** Used to detect overreaching core-js shims. */
+var coreJsData = root['__core-js_shared__'];
+
+module.exports = coreJsData;
+
+},{"./_root":74}],38:[function(require,module,exports){
+var baseRest = require('./_baseRest'),
+    isIterateeCall = require('./_isIterateeCall');
+
+/**
+ * Creates a function like `_.assign`.
+ *
+ * @private
+ * @param {Function} assigner The function to assign values.
+ * @returns {Function} Returns the new assigner function.
+ */
+function createAssigner(assigner) {
+  return baseRest(function(object, sources) {
+    var index = -1,
+        length = sources.length,
+        customizer = length > 1 ? sources[length - 1] : undefined,
+        guard = length > 2 ? sources[2] : undefined;
+
+    customizer = (assigner.length > 3 && typeof customizer == 'function')
+      ? (length--, customizer)
+      : undefined;
+
+    if (guard && isIterateeCall(sources[0], sources[1], guard)) {
+      customizer = length < 3 ? undefined : customizer;
+      length = 1;
+    }
+    object = Object(object);
+    while (++index < length) {
+      var source = sources[index];
+      if (source) {
+        assigner(object, source, index, customizer);
+      }
+    }
+    return object;
+  });
+}
+
+module.exports = createAssigner;
+
+},{"./_baseRest":28,"./_isIterateeCall":54}],39:[function(require,module,exports){
+/**
+ * Creates a base function for methods like `_.forIn` and `_.forOwn`.
+ *
+ * @private
+ * @param {boolean} [fromRight] Specify iterating from right to left.
+ * @returns {Function} Returns the new base function.
+ */
+function createBaseFor(fromRight) {
+  return function(object, iteratee, keysFunc) {
+    var index = -1,
+        iterable = Object(object),
+        props = keysFunc(object),
+        length = props.length;
+
+    while (length--) {
+      var key = props[fromRight ? length : ++index];
+      if (iteratee(iterable[key], key, iterable) === false) {
+        break;
+      }
+    }
+    return object;
+  };
+}
+
+module.exports = createBaseFor;
+
+},{}],40:[function(require,module,exports){
+var getNative = require('./_getNative');
+
+var defineProperty = (function() {
+  try {
+    var func = getNative(Object, 'defineProperty');
+    func({}, '', {});
+    return func;
+  } catch (e) {}
+}());
+
+module.exports = defineProperty;
+
+},{"./_getNative":43}],41:[function(require,module,exports){
+(function (global){
+/** Detect free variable `global` from Node.js. */
+var freeGlobal = typeof global == 'object' && global && global.Object === Object && global;
+
+module.exports = freeGlobal;
+
+}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+},{}],42:[function(require,module,exports){
+var isKeyable = require('./_isKeyable');
+
+/**
+ * Gets the data for `map`.
+ *
+ * @private
+ * @param {Object} map The map to query.
+ * @param {string} key The reference key.
+ * @returns {*} Returns the map data.
+ */
+function getMapData(map, key) {
+  var data = map.__data__;
+  return isKeyable(key)
+    ? data[typeof key == 'string' ? 'string' : 'hash']
+    : data.map;
+}
+
+module.exports = getMapData;
+
+},{"./_isKeyable":55}],43:[function(require,module,exports){
+var baseIsNative = require('./_baseIsNative'),
+    getValue = require('./_getValue');
+
+/**
+ * Gets the native function at `key` of `object`.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @param {string} key The key of the method to get.
+ * @returns {*} Returns the function if it's native, else `undefined`.
+ */
+function getNative(object, key) {
+  var value = getValue(object, key);
+  return baseIsNative(value) ? value : undefined;
+}
+
+module.exports = getNative;
+
+},{"./_baseIsNative":23,"./_getValue":46}],44:[function(require,module,exports){
+var overArg = require('./_overArg');
+
+/** Built-in value references. */
+var getPrototype = overArg(Object.getPrototypeOf, Object);
+
+module.exports = getPrototype;
+
+},{"./_overArg":72}],45:[function(require,module,exports){
+var Symbol = require('./_Symbol');
+
+/** Used for built-in method references. */
+var objectProto = Object.prototype;
+
+/** Used to check objects for own properties. */
+var hasOwnProperty = objectProto.hasOwnProperty;
+
+/**
+ * Used to resolve the
+ * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
+ * of values.
+ */
+var nativeObjectToString = objectProto.toString;
+
+/** Built-in value references. */
+var symToStringTag = Symbol ? Symbol.toStringTag : undefined;
+
+/**
+ * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.
+ *
+ * @private
+ * @param {*} value The value to query.
+ * @returns {string} Returns the raw `toStringTag`.
+ */
+function getRawTag(value) {
+  var isOwn = hasOwnProperty.call(value, symToStringTag),
+      tag = value[symToStringTag];
+
+  try {
+    value[symToStringTag] = undefined;
+    var unmasked = true;
+  } catch (e) {}
+
+  var result = nativeObjectToString.call(value);
+  if (unmasked) {
+    if (isOwn) {
+      value[symToStringTag] = tag;
+    } else {
+      delete value[symToStringTag];
+    }
+  }
+  return result;
+}
+
+module.exports = getRawTag;
+
+},{"./_Symbol":11}],46:[function(require,module,exports){
+/**
+ * Gets the value at `key` of `object`.
+ *
+ * @private
+ * @param {Object} [object] The object to query.
+ * @param {string} key The key of the property to get.
+ * @returns {*} Returns the property value.
+ */
+function getValue(object, key) {
+  return object == null ? undefined : object[key];
+}
+
+module.exports = getValue;
+
+},{}],47:[function(require,module,exports){
+var nativeCreate = require('./_nativeCreate');
+
+/**
+ * Removes all key-value entries from the hash.
+ *
+ * @private
+ * @name clear
+ * @memberOf Hash
+ */
+function hashClear() {
+  this.__data__ = nativeCreate ? nativeCreate(null) : {};
+  this.size = 0;
+}
+
+module.exports = hashClear;
+
+},{"./_nativeCreate":68}],48:[function(require,module,exports){
+/**
+ * Removes `key` and its value from the hash.
+ *
+ * @private
+ * @name delete
+ * @memberOf Hash
+ * @param {Object} hash The hash to modify.
+ * @param {string} key The key of the value to remove.
+ * @returns {boolean} Returns `true` if the entry was removed, else `false`.
+ */
+function hashDelete(key) {
+  var result = this.has(key) && delete this.__data__[key];
+  this.size -= result ? 1 : 0;
+  return result;
+}
+
+module.exports = hashDelete;
+
+},{}],49:[function(require,module,exports){
+var nativeCreate = require('./_nativeCreate');
+
+/** Used to stand-in for `undefined` hash values. */
+var HASH_UNDEFINED = '__lodash_hash_undefined__';
+
+/** Used for built-in method references. */
+var objectProto = Object.prototype;
+
+/** Used to check objects for own properties. */
+var hasOwnProperty = objectProto.hasOwnProperty;
+
+/**
+ * Gets the hash value for `key`.
+ *
+ * @private
+ * @name get
+ * @memberOf Hash
+ * @param {string} key The key of the value to get.
+ * @returns {*} Returns the entry value.
+ */
+function hashGet(key) {
+  var data = this.__data__;
+  if (nativeCreate) {
+    var result = data[key];
+    return result === HASH_UNDEFINED ? undefined : result;
+  }
+  return hasOwnProperty.call(data, key) ? data[key] : undefined;
+}
+
+module.exports = hashGet;
+
+},{"./_nativeCreate":68}],50:[function(require,module,exports){
+var nativeCreate = require('./_nativeCreate');
+
+/** Used for built-in method references. */
+var objectProto = Object.prototype;
+
+/** Used to check objects for own properties. */
+var hasOwnProperty = objectProto.hasOwnProperty;
+
+/**
+ * Checks if a hash value for `key` exists.
+ *
+ * @private
+ * @name has
+ * @memberOf Hash
+ * @param {string} key The key of the entry to check.
+ * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
+ */
+function hashHas(key) {
+  var data = this.__data__;
+  return nativeCreate ? (data[key] !== undefined) : hasOwnProperty.call(data, key);
+}
+
+module.exports = hashHas;
+
+},{"./_nativeCreate":68}],51:[function(require,module,exports){
+var nativeCreate = require('./_nativeCreate');
+
+/** Used to stand-in for `undefined` hash values. */
+var HASH_UNDEFINED = '__lodash_hash_undefined__';
+
+/**
+ * Sets the hash `key` to `value`.
+ *
+ * @private
+ * @name set
+ * @memberOf Hash
+ * @param {string} key The key of the value to set.
+ * @param {*} value The value to set.
+ * @returns {Object} Returns the hash instance.
+ */
+function hashSet(key, value) {
+  var data = this.__data__;
+  this.size += this.has(key) ? 0 : 1;
+  data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value;
+  return this;
+}
+
+module.exports = hashSet;
+
+},{"./_nativeCreate":68}],52:[function(require,module,exports){
+var baseCreate = require('./_baseCreate'),
+    getPrototype = require('./_getPrototype'),
+    isPrototype = require('./_isPrototype');
+
+/**
+ * Initializes an object clone.
+ *
+ * @private
+ * @param {Object} object The object to clone.
+ * @returns {Object} Returns the initialized clone.
+ */
+function initCloneObject(object) {
+  return (typeof object.constructor == 'function' && !isPrototype(object))
+    ? baseCreate(getPrototype(object))
+    : {};
+}
+
+module.exports = initCloneObject;
+
+},{"./_baseCreate":19,"./_getPrototype":44,"./_isPrototype":57}],53:[function(require,module,exports){
+/** Used as references for various `Number` constants. */
+var MAX_SAFE_INTEGER = 9007199254740991;
+
+/** Used to detect unsigned integer values. */
+var reIsUint = /^(?:0|[1-9]\d*)$/;
+
+/**
+ * Checks if `value` is a valid array-like index.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
+ * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
+ */
+function isIndex(value, length) {
+  var type = typeof value;
+  length = length == null ? MAX_SAFE_INTEGER : length;
+
+  return !!length &&
+    (type == 'number' ||
+      (type != 'symbol' && reIsUint.test(value))) &&
+        (value > -1 && value % 1 == 0 && value < length);
+}
+
+module.exports = isIndex;
+
+},{}],54:[function(require,module,exports){
+var eq = require('./eq'),
+    isArrayLike = require('./isArrayLike'),
+    isIndex = require('./_isIndex'),
+    isObject = require('./isObject');
+
+/**
+ * Checks if the given arguments are from an iteratee call.
+ *
+ * @private
+ * @param {*} value The potential iteratee value argument.
+ * @param {*} index The potential iteratee index or key argument.
+ * @param {*} object The potential iteratee object argument.
+ * @returns {boolean} Returns `true` if the arguments are from an iteratee call,
+ *  else `false`.
+ */
+function isIterateeCall(value, index, object) {
+  if (!isObject(object)) {
+    return false;
+  }
+  var type = typeof index;
+  if (type == 'number'
+        ? (isArrayLike(object) && isIndex(index, object.length))
+        : (type == 'string' && index in object)
+      ) {
+    return eq(object[index], value);
+  }
+  return false;
+}
+
+module.exports = isIterateeCall;
+
+},{"./_isIndex":53,"./eq":85,"./isArrayLike":89,"./isObject":94}],55:[function(require,module,exports){
+/**
+ * Checks if `value` is suitable for use as unique object key.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is suitable, else `false`.
+ */
+function isKeyable(value) {
+  var type = typeof value;
+  return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')
+    ? (value !== '__proto__')
+    : (value === null);
+}
+
+module.exports = isKeyable;
+
+},{}],56:[function(require,module,exports){
+var coreJsData = require('./_coreJsData');
+
+/** Used to detect methods masquerading as native. */
+var maskSrcKey = (function() {
+  var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || '');
+  return uid ? ('Symbol(src)_1.' + uid) : '';
+}());
+
+/**
+ * Checks if `func` has its source masked.
+ *
+ * @private
+ * @param {Function} func The function to check.
+ * @returns {boolean} Returns `true` if `func` is masked, else `false`.
+ */
+function isMasked(func) {
+  return !!maskSrcKey && (maskSrcKey in func);
+}
+
+module.exports = isMasked;
+
+},{"./_coreJsData":37}],57:[function(require,module,exports){
+/** Used for built-in method references. */
+var objectProto = Object.prototype;
+
+/**
+ * Checks if `value` is likely a prototype object.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.
+ */
+function isPrototype(value) {
+  var Ctor = value && value.constructor,
+      proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;
+
+  return value === proto;
+}
+
+module.exports = isPrototype;
+
+},{}],58:[function(require,module,exports){
+/**
+ * Removes all key-value entries from the list cache.
+ *
+ * @private
+ * @name clear
+ * @memberOf ListCache
+ */
+function listCacheClear() {
+  this.__data__ = [];
+  this.size = 0;
+}
+
+module.exports = listCacheClear;
+
+},{}],59:[function(require,module,exports){
+var assocIndexOf = require('./_assocIndexOf');
+
+/** Used for built-in method references. */
+var arrayProto = Array.prototype;
+
+/** Built-in value references. */
+var splice = arrayProto.splice;
+
+/**
+ * Removes `key` and its value from the list cache.
+ *
+ * @private
+ * @name delete
+ * @memberOf ListCache
+ * @param {string} key The key of the value to remove.
+ * @returns {boolean} Returns `true` if the entry was removed, else `false`.
+ */
+function listCacheDelete(key) {
+  var data = this.__data__,
+      index = assocIndexOf(data, key);
+
+  if (index < 0) {
+    return false;
+  }
+  var lastIndex = data.length - 1;
+  if (index == lastIndex) {
+    data.pop();
+  } else {
+    splice.call(data, index, 1);
+  }
+  --this.size;
+  return true;
+}
+
+module.exports = listCacheDelete;
+
+},{"./_assocIndexOf":17}],60:[function(require,module,exports){
+var assocIndexOf = require('./_assocIndexOf');
+
+/**
+ * Gets the list cache value for `key`.
+ *
+ * @private
+ * @name get
+ * @memberOf ListCache
+ * @param {string} key The key of the value to get.
+ * @returns {*} Returns the entry value.
+ */
+function listCacheGet(key) {
+  var data = this.__data__,
+      index = assocIndexOf(data, key);
+
+  return index < 0 ? undefined : data[index][1];
+}
+
+module.exports = listCacheGet;
+
+},{"./_assocIndexOf":17}],61:[function(require,module,exports){
+var assocIndexOf = require('./_assocIndexOf');
+
+/**
+ * Checks if a list cache value for `key` exists.
+ *
+ * @private
+ * @name has
+ * @memberOf ListCache
+ * @param {string} key The key of the entry to check.
+ * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
+ */
+function listCacheHas(key) {
+  return assocIndexOf(this.__data__, key) > -1;
+}
+
+module.exports = listCacheHas;
+
+},{"./_assocIndexOf":17}],62:[function(require,module,exports){
+var assocIndexOf = require('./_assocIndexOf');
+
+/**
+ * Sets the list cache `key` to `value`.
+ *
+ * @private
+ * @name set
+ * @memberOf ListCache
+ * @param {string} key The key of the value to set.
+ * @param {*} value The value to set.
+ * @returns {Object} Returns the list cache instance.
+ */
+function listCacheSet(key, value) {
+  var data = this.__data__,
+      index = assocIndexOf(data, key);
+
+  if (index < 0) {
+    ++this.size;
+    data.push([key, value]);
+  } else {
+    data[index][1] = value;
+  }
+  return this;
+}
+
+module.exports = listCacheSet;
+
+},{"./_assocIndexOf":17}],63:[function(require,module,exports){
+var Hash = require('./_Hash'),
+    ListCache = require('./_ListCache'),
+    Map = require('./_Map');
+
+/**
+ * Removes all key-value entries from the map.
+ *
+ * @private
+ * @name clear
+ * @memberOf MapCache
+ */
+function mapCacheClear() {
+  this.size = 0;
+  this.__data__ = {
+    'hash': new Hash,
+    'map': new (Map || ListCache),
+    'string': new Hash
+  };
+}
+
+module.exports = mapCacheClear;
+
+},{"./_Hash":6,"./_ListCache":7,"./_Map":8}],64:[function(require,module,exports){
+var getMapData = require('./_getMapData');
+
+/**
+ * Removes `key` and its value from the map.
+ *
+ * @private
+ * @name delete
+ * @memberOf MapCache
+ * @param {string} key The key of the value to remove.
+ * @returns {boolean} Returns `true` if the entry was removed, else `false`.
+ */
+function mapCacheDelete(key) {
+  var result = getMapData(this, key)['delete'](key);
+  this.size -= result ? 1 : 0;
+  return result;
+}
+
+module.exports = mapCacheDelete;
+
+},{"./_getMapData":42}],65:[function(require,module,exports){
+var getMapData = require('./_getMapData');
+
+/**
+ * Gets the map value for `key`.
+ *
+ * @private
+ * @name get
+ * @memberOf MapCache
+ * @param {string} key The key of the value to get.
+ * @returns {*} Returns the entry value.
+ */
+function mapCacheGet(key) {
+  return getMapData(this, key).get(key);
+}
+
+module.exports = mapCacheGet;
+
+},{"./_getMapData":42}],66:[function(require,module,exports){
+var getMapData = require('./_getMapData');
+
+/**
+ * Checks if a map value for `key` exists.
+ *
+ * @private
+ * @name has
+ * @memberOf MapCache
+ * @param {string} key The key of the entry to check.
+ * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
+ */
+function mapCacheHas(key) {
+  return getMapData(this, key).has(key);
+}
+
+module.exports = mapCacheHas;
+
+},{"./_getMapData":42}],67:[function(require,module,exports){
+var getMapData = require('./_getMapData');
+
+/**
+ * Sets the map `key` to `value`.
+ *
+ * @private
+ * @name set
+ * @memberOf MapCache
+ * @param {string} key The key of the value to set.
+ * @param {*} value The value to set.
+ * @returns {Object} Returns the map cache instance.
+ */
+function mapCacheSet(key, value) {
+  var data = getMapData(this, key),
+      size = data.size;
+
+  data.set(key, value);
+  this.size += data.size == size ? 0 : 1;
+  return this;
+}
+
+module.exports = mapCacheSet;
+
+},{"./_getMapData":42}],68:[function(require,module,exports){
+var getNative = require('./_getNative');
+
+/* Built-in method references that are verified to be native. */
+var nativeCreate = getNative(Object, 'create');
+
+module.exports = nativeCreate;
+
+},{"./_getNative":43}],69:[function(require,module,exports){
+/**
+ * This function is like
+ * [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
+ * except that it includes inherited enumerable properties.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @returns {Array} Returns the array of property names.
+ */
+function nativeKeysIn(object) {
+  var result = [];
+  if (object != null) {
+    for (var key in Object(object)) {
+      result.push(key);
+    }
+  }
+  return result;
+}
+
+module.exports = nativeKeysIn;
+
+},{}],70:[function(require,module,exports){
+var freeGlobal = require('./_freeGlobal');
+
+/** Detect free variable `exports`. */
+var freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports;
+
+/** Detect free variable `module`. */
+var freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module;
+
+/** Detect the popular CommonJS extension `module.exports`. */
+var moduleExports = freeModule && freeModule.exports === freeExports;
+
+/** Detect free variable `process` from Node.js. */
+var freeProcess = moduleExports && freeGlobal.process;
+
+/** Used to access faster Node.js helpers. */
+var nodeUtil = (function() {
+  try {
+    // Use `util.types` for Node.js 10+.
+    var types = freeModule && freeModule.require && freeModule.require('util').types;
+
+    if (types) {
+      return types;
+    }
+
+    // Legacy `process.binding('util')` for Node.js < 10.
+    return freeProcess && freeProcess.binding && freeProcess.binding('util');
+  } catch (e) {}
+}());
+
+module.exports = nodeUtil;
+
+},{"./_freeGlobal":41}],71:[function(require,module,exports){
+/** Used for built-in method references. */
+var objectProto = Object.prototype;
+
+/**
+ * Used to resolve the
+ * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
+ * of values.
+ */
+var nativeObjectToString = objectProto.toString;
+
+/**
+ * Converts `value` to a string using `Object.prototype.toString`.
+ *
+ * @private
+ * @param {*} value The value to convert.
+ * @returns {string} Returns the converted string.
+ */
+function objectToString(value) {
+  return nativeObjectToString.call(value);
+}
+
+module.exports = objectToString;
+
+},{}],72:[function(require,module,exports){
+/**
+ * Creates a unary function that invokes `func` with its argument transformed.
+ *
+ * @private
+ * @param {Function} func The function to wrap.
+ * @param {Function} transform The argument transform.
+ * @returns {Function} Returns the new function.
+ */
+function overArg(func, transform) {
+  return function(arg) {
+    return func(transform(arg));
+  };
+}
+
+module.exports = overArg;
+
+},{}],73:[function(require,module,exports){
+var apply = require('./_apply');
+
+/* Built-in method references for those with the same name as other `lodash` methods. */
+var nativeMax = Math.max;
+
+/**
+ * A specialized version of `baseRest` which transforms the rest array.
+ *
+ * @private
+ * @param {Function} func The function to apply a rest parameter to.
+ * @param {number} [start=func.length-1] The start position of the rest parameter.
+ * @param {Function} transform The rest array transform.
+ * @returns {Function} Returns the new function.
+ */
+function overRest(func, start, transform) {
+  start = nativeMax(start === undefined ? (func.length - 1) : start, 0);
+  return function() {
+    var args = arguments,
+        index = -1,
+        length = nativeMax(args.length - start, 0),
+        array = Array(length);
+
+    while (++index < length) {
+      array[index] = args[start + index];
+    }
+    index = -1;
+    var otherArgs = Array(start + 1);
+    while (++index < start) {
+      otherArgs[index] = args[index];
+    }
+    otherArgs[start] = transform(array);
+    return apply(func, this, otherArgs);
+  };
+}
+
+module.exports = overRest;
+
+},{"./_apply":13}],74:[function(require,module,exports){
+var freeGlobal = require('./_freeGlobal');
+
+/** Detect free variable `self`. */
+var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
+
+/** Used as a reference to the global object. */
+var root = freeGlobal || freeSelf || Function('return this')();
+
+module.exports = root;
+
+},{"./_freeGlobal":41}],75:[function(require,module,exports){
+/**
+ * Gets the value at `key`, unless `key` is "__proto__".
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @param {string} key The key of the property to get.
+ * @returns {*} Returns the property value.
+ */
+function safeGet(object, key) {
+  return key == '__proto__'
+    ? undefined
+    : object[key];
+}
+
+module.exports = safeGet;
+
+},{}],76:[function(require,module,exports){
+var baseSetToString = require('./_baseSetToString'),
+    shortOut = require('./_shortOut');
+
+/**
+ * Sets the `toString` method of `func` to return `string`.
+ *
+ * @private
+ * @param {Function} func The function to modify.
+ * @param {Function} string The `toString` result.
+ * @returns {Function} Returns `func`.
+ */
+var setToString = shortOut(baseSetToString);
+
+module.exports = setToString;
+
+},{"./_baseSetToString":29,"./_shortOut":77}],77:[function(require,module,exports){
+/** Used to detect hot functions by number of calls within a span of milliseconds. */
+var HOT_COUNT = 800,
+    HOT_SPAN = 16;
+
+/* Built-in method references for those with the same name as other `lodash` methods. */
+var nativeNow = Date.now;
+
+/**
+ * Creates a function that'll short out and invoke `identity` instead
+ * of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN`
+ * milliseconds.
+ *
+ * @private
+ * @param {Function} func The function to restrict.
+ * @returns {Function} Returns the new shortable function.
+ */
+function shortOut(func) {
+  var count = 0,
+      lastCalled = 0;
+
+  return function() {
+    var stamp = nativeNow(),
+        remaining = HOT_SPAN - (stamp - lastCalled);
+
+    lastCalled = stamp;
+    if (remaining > 0) {
+      if (++count >= HOT_COUNT) {
+        return arguments[0];
+      }
+    } else {
+      count = 0;
+    }
+    return func.apply(undefined, arguments);
+  };
+}
+
+module.exports = shortOut;
+
+},{}],78:[function(require,module,exports){
+var ListCache = require('./_ListCache');
+
+/**
+ * Removes all key-value entries from the stack.
+ *
+ * @private
+ * @name clear
+ * @memberOf Stack
+ */
+function stackClear() {
+  this.__data__ = new ListCache;
+  this.size = 0;
+}
+
+module.exports = stackClear;
+
+},{"./_ListCache":7}],79:[function(require,module,exports){
+/**
+ * Removes `key` and its value from the stack.
+ *
+ * @private
+ * @name delete
+ * @memberOf Stack
+ * @param {string} key The key of the value to remove.
+ * @returns {boolean} Returns `true` if the entry was removed, else `false`.
+ */
+function stackDelete(key) {
+  var data = this.__data__,
+      result = data['delete'](key);
+
+  this.size = data.size;
+  return result;
+}
+
+module.exports = stackDelete;
+
+},{}],80:[function(require,module,exports){
+/**
+ * Gets the stack value for `key`.
+ *
+ * @private
+ * @name get
+ * @memberOf Stack
+ * @param {string} key The key of the value to get.
+ * @returns {*} Returns the entry value.
+ */
+function stackGet(key) {
+  return this.__data__.get(key);
+}
+
+module.exports = stackGet;
+
+},{}],81:[function(require,module,exports){
+/**
+ * Checks if a stack value for `key` exists.
+ *
+ * @private
+ * @name has
+ * @memberOf Stack
+ * @param {string} key The key of the entry to check.
+ * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
+ */
+function stackHas(key) {
+  return this.__data__.has(key);
+}
+
+module.exports = stackHas;
+
+},{}],82:[function(require,module,exports){
+var ListCache = require('./_ListCache'),
+    Map = require('./_Map'),
+    MapCache = require('./_MapCache');
+
+/** Used as the size to enable large array optimizations. */
+var LARGE_ARRAY_SIZE = 200;
+
+/**
+ * Sets the stack `key` to `value`.
+ *
+ * @private
+ * @name set
+ * @memberOf Stack
+ * @param {string} key The key of the value to set.
+ * @param {*} value The value to set.
+ * @returns {Object} Returns the stack cache instance.
+ */
+function stackSet(key, value) {
+  var data = this.__data__;
+  if (data instanceof ListCache) {
+    var pairs = data.__data__;
+    if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) {
+      pairs.push([key, value]);
+      this.size = ++data.size;
+      return this;
+    }
+    data = this.__data__ = new MapCache(pairs);
+  }
+  data.set(key, value);
+  this.size = data.size;
+  return this;
+}
+
+module.exports = stackSet;
+
+},{"./_ListCache":7,"./_Map":8,"./_MapCache":9}],83:[function(require,module,exports){
+/** Used for built-in method references. */
+var funcProto = Function.prototype;
+
+/** Used to resolve the decompiled source of functions. */
+var funcToString = funcProto.toString;
+
+/**
+ * Converts `func` to its source code.
+ *
+ * @private
+ * @param {Function} func The function to convert.
+ * @returns {string} Returns the source code.
+ */
+function toSource(func) {
+  if (func != null) {
+    try {
+      return funcToString.call(func);
+    } catch (e) {}
+    try {
+      return (func + '');
+    } catch (e) {}
+  }
+  return '';
+}
+
+module.exports = toSource;
+
+},{}],84:[function(require,module,exports){
+/**
+ * Creates a function that returns `value`.
+ *
+ * @static
+ * @memberOf _
+ * @since 2.4.0
+ * @category Util
+ * @param {*} value The value to return from the new function.
+ * @returns {Function} Returns the new constant function.
+ * @example
+ *
+ * var objects = _.times(2, _.constant({ 'a': 1 }));
+ *
+ * console.log(objects);
+ * // => [{ 'a': 1 }, { 'a': 1 }]
+ *
+ * console.log(objects[0] === objects[1]);
+ * // => true
+ */
+function constant(value) {
+  return function() {
+    return value;
+  };
+}
+
+module.exports = constant;
+
+},{}],85:[function(require,module,exports){
+/**
+ * Performs a
+ * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
+ * comparison between two values to determine if they are equivalent.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Lang
+ * @param {*} value The value to compare.
+ * @param {*} other The other value to compare.
+ * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
+ * @example
+ *
+ * var object = { 'a': 1 };
+ * var other = { 'a': 1 };
+ *
+ * _.eq(object, object);
+ * // => true
+ *
+ * _.eq(object, other);
+ * // => false
+ *
+ * _.eq('a', 'a');
+ * // => true
+ *
+ * _.eq('a', Object('a'));
+ * // => false
+ *
+ * _.eq(NaN, NaN);
+ * // => true
+ */
+function eq(value, other) {
+  return value === other || (value !== value && other !== other);
+}
+
+module.exports = eq;
+
+},{}],86:[function(require,module,exports){
+/**
+ * This method returns the first argument it receives.
+ *
+ * @static
+ * @since 0.1.0
+ * @memberOf _
+ * @category Util
+ * @param {*} value Any value.
+ * @returns {*} Returns `value`.
+ * @example
+ *
+ * var object = { 'a': 1 };
+ *
+ * console.log(_.identity(object) === object);
+ * // => true
+ */
+function identity(value) {
+  return value;
+}
+
+module.exports = identity;
+
+},{}],87:[function(require,module,exports){
+var baseIsArguments = require('./_baseIsArguments'),
+    isObjectLike = require('./isObjectLike');
+
+/** Used for built-in method references. */
+var objectProto = Object.prototype;
+
+/** Used to check objects for own properties. */
+var hasOwnProperty = objectProto.hasOwnProperty;
+
+/** Built-in value references. */
+var propertyIsEnumerable = objectProto.propertyIsEnumerable;
+
+/**
+ * Checks if `value` is likely an `arguments` object.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is an `arguments` object,
+ *  else `false`.
+ * @example
+ *
+ * _.isArguments(function() { return arguments; }());
+ * // => true
+ *
+ * _.isArguments([1, 2, 3]);
+ * // => false
+ */
+var isArguments = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) {
+  return isObjectLike(value) && hasOwnProperty.call(value, 'callee') &&
+    !propertyIsEnumerable.call(value, 'callee');
+};
+
+module.exports = isArguments;
+
+},{"./_baseIsArguments":22,"./isObjectLike":95}],88:[function(require,module,exports){
+/**
+ * Checks if `value` is classified as an `Array` object.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is an array, else `false`.
+ * @example
+ *
+ * _.isArray([1, 2, 3]);
+ * // => true
+ *
+ * _.isArray(document.body.children);
+ * // => false
+ *
+ * _.isArray('abc');
+ * // => false
+ *
+ * _.isArray(_.noop);
+ * // => false
+ */
+var isArray = Array.isArray;
+
+module.exports = isArray;
+
+},{}],89:[function(require,module,exports){
+var isFunction = require('./isFunction'),
+    isLength = require('./isLength');
+
+/**
+ * Checks if `value` is array-like. A value is considered array-like if it's
+ * not a function and has a `value.length` that's an integer greater than or
+ * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is array-like, else `false`.
+ * @example
+ *
+ * _.isArrayLike([1, 2, 3]);
+ * // => true
+ *
+ * _.isArrayLike(document.body.children);
+ * // => true
+ *
+ * _.isArrayLike('abc');
+ * // => true
+ *
+ * _.isArrayLike(_.noop);
+ * // => false
+ */
+function isArrayLike(value) {
+  return value != null && isLength(value.length) && !isFunction(value);
+}
+
+module.exports = isArrayLike;
+
+},{"./isFunction":92,"./isLength":93}],90:[function(require,module,exports){
+var isArrayLike = require('./isArrayLike'),
+    isObjectLike = require('./isObjectLike');
+
+/**
+ * This method is like `_.isArrayLike` except that it also checks if `value`
+ * is an object.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is an array-like object,
+ *  else `false`.
+ * @example
+ *
+ * _.isArrayLikeObject([1, 2, 3]);
+ * // => true
+ *
+ * _.isArrayLikeObject(document.body.children);
+ * // => true
+ *
+ * _.isArrayLikeObject('abc');
+ * // => false
+ *
+ * _.isArrayLikeObject(_.noop);
+ * // => false
+ */
+function isArrayLikeObject(value) {
+  return isObjectLike(value) && isArrayLike(value);
+}
+
+module.exports = isArrayLikeObject;
+
+},{"./isArrayLike":89,"./isObjectLike":95}],91:[function(require,module,exports){
+var root = require('./_root'),
+    stubFalse = require('./stubFalse');
+
+/** Detect free variable `exports`. */
+var freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports;
+
+/** Detect free variable `module`. */
+var freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module;
+
+/** Detect the popular CommonJS extension `module.exports`. */
+var moduleExports = freeModule && freeModule.exports === freeExports;
+
+/** Built-in value references. */
+var Buffer = moduleExports ? root.Buffer : undefined;
+
+/* Built-in method references for those with the same name as other `lodash` methods. */
+var nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined;
+
+/**
+ * Checks if `value` is a buffer.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.3.0
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a buffer, else `false`.
+ * @example
+ *
+ * _.isBuffer(new Buffer(2));
+ * // => true
+ *
+ * _.isBuffer(new Uint8Array(2));
+ * // => false
+ */
+var isBuffer = nativeIsBuffer || stubFalse;
+
+module.exports = isBuffer;
+
+},{"./_root":74,"./stubFalse":100}],92:[function(require,module,exports){
+var baseGetTag = require('./_baseGetTag'),
+    isObject = require('./isObject');
+
+/** `Object#toString` result references. */
+var asyncTag = '[object AsyncFunction]',
+    funcTag = '[object Function]',
+    genTag = '[object GeneratorFunction]',
+    proxyTag = '[object Proxy]';
+
+/**
+ * Checks if `value` is classified as a `Function` object.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a function, else `false`.
+ * @example
+ *
+ * _.isFunction(_);
+ * // => true
+ *
+ * _.isFunction(/abc/);
+ * // => false
+ */
+function isFunction(value) {
+  if (!isObject(value)) {
+    return false;
+  }
+  // The use of `Object#toString` avoids issues with the `typeof` operator
+  // in Safari 9 which returns 'object' for typed arrays and other constructors.
+  var tag = baseGetTag(value);
+  return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag;
+}
+
+module.exports = isFunction;
+
+},{"./_baseGetTag":21,"./isObject":94}],93:[function(require,module,exports){
+/** Used as references for various `Number` constants. */
+var MAX_SAFE_INTEGER = 9007199254740991;
+
+/**
+ * Checks if `value` is a valid array-like length.
+ *
+ * **Note:** This method is loosely based on
+ * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
+ * @example
+ *
+ * _.isLength(3);
+ * // => true
+ *
+ * _.isLength(Number.MIN_VALUE);
+ * // => false
+ *
+ * _.isLength(Infinity);
+ * // => false
+ *
+ * _.isLength('3');
+ * // => false
+ */
+function isLength(value) {
+  return typeof value == 'number' &&
+    value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
+}
+
+module.exports = isLength;
+
+},{}],94:[function(require,module,exports){
+/**
+ * Checks if `value` is the
+ * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
+ * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is an object, else `false`.
+ * @example
+ *
+ * _.isObject({});
+ * // => true
+ *
+ * _.isObject([1, 2, 3]);
+ * // => true
+ *
+ * _.isObject(_.noop);
+ * // => true
+ *
+ * _.isObject(null);
+ * // => false
+ */
+function isObject(value) {
+  var type = typeof value;
+  return value != null && (type == 'object' || type == 'function');
+}
+
+module.exports = isObject;
+
+},{}],95:[function(require,module,exports){
+/**
+ * Checks if `value` is object-like. A value is object-like if it's not `null`
+ * and has a `typeof` result of "object".
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
+ * @example
+ *
+ * _.isObjectLike({});
+ * // => true
+ *
+ * _.isObjectLike([1, 2, 3]);
+ * // => true
+ *
+ * _.isObjectLike(_.noop);
+ * // => false
+ *
+ * _.isObjectLike(null);
+ * // => false
+ */
+function isObjectLike(value) {
+  return value != null && typeof value == 'object';
+}
+
+module.exports = isObjectLike;
+
+},{}],96:[function(require,module,exports){
+var baseGetTag = require('./_baseGetTag'),
+    getPrototype = require('./_getPrototype'),
+    isObjectLike = require('./isObjectLike');
+
+/** `Object#toString` result references. */
+var objectTag = '[object Object]';
+
+/** Used for built-in method references. */
+var funcProto = Function.prototype,
+    objectProto = Object.prototype;
+
+/** Used to resolve the decompiled source of functions. */
+var funcToString = funcProto.toString;
+
+/** Used to check objects for own properties. */
+var hasOwnProperty = objectProto.hasOwnProperty;
+
+/** Used to infer the `Object` constructor. */
+var objectCtorString = funcToString.call(Object);
+
+/**
+ * Checks if `value` is a plain object, that is, an object created by the
+ * `Object` constructor or one with a `[[Prototype]]` of `null`.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.8.0
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
+ * @example
+ *
+ * function Foo() {
+ *   this.a = 1;
+ * }
+ *
+ * _.isPlainObject(new Foo);
+ * // => false
+ *
+ * _.isPlainObject([1, 2, 3]);
+ * // => false
+ *
+ * _.isPlainObject({ 'x': 0, 'y': 0 });
+ * // => true
+ *
+ * _.isPlainObject(Object.create(null));
+ * // => true
+ */
+function isPlainObject(value) {
+  if (!isObjectLike(value) || baseGetTag(value) != objectTag) {
+    return false;
+  }
+  var proto = getPrototype(value);
+  if (proto === null) {
+    return true;
+  }
+  var Ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor;
+  return typeof Ctor == 'function' && Ctor instanceof Ctor &&
+    funcToString.call(Ctor) == objectCtorString;
+}
+
+module.exports = isPlainObject;
+
+},{"./_baseGetTag":21,"./_getPrototype":44,"./isObjectLike":95}],97:[function(require,module,exports){
+var baseIsTypedArray = require('./_baseIsTypedArray'),
+    baseUnary = require('./_baseUnary'),
+    nodeUtil = require('./_nodeUtil');
+
+/* Node.js helper references. */
+var nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray;
+
+/**
+ * Checks if `value` is classified as a typed array.
+ *
+ * @static
+ * @memberOf _
+ * @since 3.0.0
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
+ * @example
+ *
+ * _.isTypedArray(new Uint8Array);
+ * // => true
+ *
+ * _.isTypedArray([]);
+ * // => false
+ */
+var isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray;
+
+module.exports = isTypedArray;
+
+},{"./_baseIsTypedArray":24,"./_baseUnary":31,"./_nodeUtil":70}],98:[function(require,module,exports){
+var arrayLikeKeys = require('./_arrayLikeKeys'),
+    baseKeysIn = require('./_baseKeysIn'),
+    isArrayLike = require('./isArrayLike');
+
+/**
+ * Creates an array of the own and inherited enumerable property names of `object`.
+ *
+ * **Note:** Non-object values are coerced to objects.
+ *
+ * @static
+ * @memberOf _
+ * @since 3.0.0
+ * @category Object
+ * @param {Object} object The object to query.
+ * @returns {Array} Returns the array of property names.
+ * @example
+ *
+ * function Foo() {
+ *   this.a = 1;
+ *   this.b = 2;
+ * }
+ *
+ * Foo.prototype.c = 3;
+ *
+ * _.keysIn(new Foo);
+ * // => ['a', 'b', 'c'] (iteration order is not guaranteed)
+ */
+function keysIn(object) {
+  return isArrayLike(object) ? arrayLikeKeys(object, true) : baseKeysIn(object);
+}
+
+module.exports = keysIn;
+
+},{"./_arrayLikeKeys":14,"./_baseKeysIn":25,"./isArrayLike":89}],99:[function(require,module,exports){
+var baseMerge = require('./_baseMerge'),
+    createAssigner = require('./_createAssigner');
+
+/**
+ * This method is like `_.assign` except that it recursively merges own and
+ * inherited enumerable string keyed properties of source objects into the
+ * destination object. Source properties that resolve to `undefined` are
+ * skipped if a destination value exists. Array and plain object properties
+ * are merged recursively. Other objects and value types are overridden by
+ * assignment. Source objects are applied from left to right. Subsequent
+ * sources overwrite property assignments of previous sources.
+ *
+ * **Note:** This method mutates `object`.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.5.0
+ * @category Object
+ * @param {Object} object The destination object.
+ * @param {...Object} [sources] The source objects.
+ * @returns {Object} Returns `object`.
+ * @example
+ *
+ * var object = {
+ *   'a': [{ 'b': 2 }, { 'd': 4 }]
+ * };
+ *
+ * var other = {
+ *   'a': [{ 'c': 3 }, { 'e': 5 }]
+ * };
+ *
+ * _.merge(object, other);
+ * // => { 'a': [{ 'b': 2, 'c': 3 }, { 'd': 4, 'e': 5 }] }
+ */
+var merge = createAssigner(function(object, source, srcIndex) {
+  baseMerge(object, source, srcIndex);
+});
+
+module.exports = merge;
+
+},{"./_baseMerge":26,"./_createAssigner":38}],100:[function(require,module,exports){
+/**
+ * This method returns `false`.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.13.0
+ * @category Util
+ * @returns {boolean} Returns `false`.
+ * @example
+ *
+ * _.times(2, _.stubFalse);
+ * // => [false, false]
+ */
+function stubFalse() {
+  return false;
+}
+
+module.exports = stubFalse;
+
+},{}],101:[function(require,module,exports){
+var copyObject = require('./_copyObject'),
+    keysIn = require('./keysIn');
+
+/**
+ * Converts `value` to a plain object flattening inherited enumerable string
+ * keyed properties of `value` to own properties of the plain object.
+ *
+ * @static
+ * @memberOf _
+ * @since 3.0.0
+ * @category Lang
+ * @param {*} value The value to convert.
+ * @returns {Object} Returns the converted plain object.
+ * @example
+ *
+ * function Foo() {
+ *   this.b = 2;
+ * }
+ *
+ * Foo.prototype.c = 3;
+ *
+ * _.assign({ 'a': 1 }, new Foo);
+ * // => { 'a': 1, 'b': 2 }
+ *
+ * _.assign({ 'a': 1 }, _.toPlainObject(new Foo));
+ * // => { 'a': 1, 'b': 2, 'c': 3 }
+ */
+function toPlainObject(value) {
+  return copyObject(value, keysIn(value));
+}
+
+module.exports = toPlainObject;
+
+},{"./_copyObject":36,"./keysIn":98}],102:[function(require,module,exports){
+(function (process){
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+// resolves . and .. elements in a path array with directory names there
+// must be no slashes, empty elements, or device names (c:\) in the array
+// (so also no leading and trailing slashes - it does not distinguish
+// relative and absolute paths)
+function normalizeArray(parts, allowAboveRoot) {
+  // if the path tries to go above the root, `up` ends up > 0
+  var up = 0;
+  for (var i = parts.length - 1; i >= 0; i--) {
+    var last = parts[i];
+    if (last === '.') {
+      parts.splice(i, 1);
+    } else if (last === '..') {
+      parts.splice(i, 1);
+      up++;
+    } else if (up) {
+      parts.splice(i, 1);
+      up--;
+    }
+  }
+
+  // if the path is allowed to go above the root, restore leading ..s
+  if (allowAboveRoot) {
+    for (; up--; up) {
+      parts.unshift('..');
+    }
+  }
+
+  return parts;
+}
+
+// Split a filename into [root, dir, basename, ext], unix version
+// 'root' is just a slash, or nothing.
+var splitPathRe =
+    /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;
+var splitPath = function(filename) {
+  return splitPathRe.exec(filename).slice(1);
+};
+
+// path.resolve([from ...], to)
+// posix version
+exports.resolve = function() {
+  var resolvedPath = '',
+      resolvedAbsolute = false;
+
+  for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) {
+    var path = (i >= 0) ? arguments[i] : process.cwd();
+
+    // Skip empty and invalid entries
+    if (typeof path !== 'string') {
+      throw new TypeError('Arguments to path.resolve must be strings');
+    } else if (!path) {
+      continue;
+    }
+
+    resolvedPath = path + '/' + resolvedPath;
+    resolvedAbsolute = path.charAt(0) === '/';
+  }
+
+  // At this point the path should be resolved to a full absolute path, but
+  // handle relative paths to be safe (might happen when process.cwd() fails)
+
+  // Normalize the path
+  resolvedPath = normalizeArray(filter(resolvedPath.split('/'), function(p) {
+    return !!p;
+  }), !resolvedAbsolute).join('/');
+
+  return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.';
+};
+
+// path.normalize(path)
+// posix version
+exports.normalize = function(path) {
+  var isAbsolute = exports.isAbsolute(path),
+      trailingSlash = substr(path, -1) === '/';
+
+  // Normalize the path
+  path = normalizeArray(filter(path.split('/'), function(p) {
+    return !!p;
+  }), !isAbsolute).join('/');
+
+  if (!path && !isAbsolute) {
+    path = '.';
+  }
+  if (path && trailingSlash) {
+    path += '/';
+  }
+
+  return (isAbsolute ? '/' : '') + path;
+};
+
+// posix version
+exports.isAbsolute = function(path) {
+  return path.charAt(0) === '/';
+};
+
+// posix version
+exports.join = function() {
+  var paths = Array.prototype.slice.call(arguments, 0);
+  return exports.normalize(filter(paths, function(p, index) {
+    if (typeof p !== 'string') {
+      throw new TypeError('Arguments to path.join must be strings');
+    }
+    return p;
+  }).join('/'));
+};
+
+
+// path.relative(from, to)
+// posix version
+exports.relative = function(from, to) {
+  from = exports.resolve(from).substr(1);
+  to = exports.resolve(to).substr(1);
+
+  function trim(arr) {
+    var start = 0;
+    for (; start < arr.length; start++) {
+      if (arr[start] !== '') break;
+    }
+
+    var end = arr.length - 1;
+    for (; end >= 0; end--) {
+      if (arr[end] !== '') break;
+    }
+
+    if (start > end) return [];
+    return arr.slice(start, end - start + 1);
+  }
+
+  var fromParts = trim(from.split('/'));
+  var toParts = trim(to.split('/'));
+
+  var length = Math.min(fromParts.length, toParts.length);
+  var samePartsLength = length;
+  for (var i = 0; i < length; i++) {
+    if (fromParts[i] !== toParts[i]) {
+      samePartsLength = i;
+      break;
+    }
+  }
+
+  var outputParts = [];
+  for (var i = samePartsLength; i < fromParts.length; i++) {
+    outputParts.push('..');
+  }
+
+  outputParts = outputParts.concat(toParts.slice(samePartsLength));
+
+  return outputParts.join('/');
+};
+
+exports.sep = '/';
+exports.delimiter = ':';
+
+exports.dirname = function(path) {
+  var result = splitPath(path),
+      root = result[0],
+      dir = result[1];
+
+  if (!root && !dir) {
+    // No dirname whatsoever
+    return '.';
+  }
+
+  if (dir) {
+    // It has a dirname, strip trailing slash
+    dir = dir.substr(0, dir.length - 1);
+  }
+
+  return root + dir;
+};
+
+
+exports.basename = function(path, ext) {
+  var f = splitPath(path)[2];
+  // TODO: make this comparison case-insensitive on windows?
+  if (ext && f.substr(-1 * ext.length) === ext) {
+    f = f.substr(0, f.length - ext.length);
+  }
+  return f;
+};
+
+
+exports.extname = function(path) {
+  return splitPath(path)[3];
+};
+
+function filter (xs, f) {
+    if (xs.filter) return xs.filter(f);
+    var res = [];
+    for (var i = 0; i < xs.length; i++) {
+        if (f(xs[i], i, xs)) res.push(xs[i]);
+    }
+    return res;
+}
+
+// String.prototype.substr - negative index don't work in IE8
+var substr = 'ab'.substr(-1) === 'b'
+    ? function (str, start, len) { return str.substr(start, len) }
+    : function (str, start, len) {
+        if (start < 0) start = str.length + start;
+        return str.substr(start, len);
+    }
+;
+
+}).call(this,require('_process'))
+},{"_process":103}],103:[function(require,module,exports){
+// shim for using process in browser
+var process = module.exports = {};
+
+// cached from whatever global is present so that test runners that stub it
+// don't break things.  But we need to wrap it in a try catch in case it is
+// wrapped in strict mode code which doesn't define any globals.  It's inside a
+// function because try/catches deoptimize in certain engines.
+
+var cachedSetTimeout;
+var cachedClearTimeout;
+
+function defaultSetTimout() {
+    throw new Error('setTimeout has not been defined');
+}
+function defaultClearTimeout () {
+    throw new Error('clearTimeout has not been defined');
+}
+(function () {
+    try {
+        if (typeof setTimeout === 'function') {
+            cachedSetTimeout = setTimeout;
+        } else {
+            cachedSetTimeout = defaultSetTimout;
+        }
+    } catch (e) {
+        cachedSetTimeout = defaultSetTimout;
+    }
+    try {
+        if (typeof clearTimeout === 'function') {
+            cachedClearTimeout = clearTimeout;
+        } else {
+            cachedClearTimeout = defaultClearTimeout;
+        }
+    } catch (e) {
+        cachedClearTimeout = defaultClearTimeout;
+    }
+} ())
+function runTimeout(fun) {
+    if (cachedSetTimeout === setTimeout) {
+        //normal enviroments in sane situations
+        return setTimeout(fun, 0);
+    }
+    // if setTimeout wasn't available but was latter defined
+    if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {
+        cachedSetTimeout = setTimeout;
+        return setTimeout(fun, 0);
+    }
+    try {
+        // when when somebody has screwed with setTimeout but no I.E. maddness
+        return cachedSetTimeout(fun, 0);
+    } catch(e){
+        try {
+            // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
+            return cachedSetTimeout.call(null, fun, 0);
+        } catch(e){
+            // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error
+            return cachedSetTimeout.call(this, fun, 0);
+        }
+    }
+
+
+}
+function runClearTimeout(marker) {
+    if (cachedClearTimeout === clearTimeout) {
+        //normal enviroments in sane situations
+        return clearTimeout(marker);
+    }
+    // if clearTimeout wasn't available but was latter defined
+    if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {
+        cachedClearTimeout = clearTimeout;
+        return clearTimeout(marker);
+    }
+    try {
+        // when when somebody has screwed with setTimeout but no I.E. maddness
+        return cachedClearTimeout(marker);
+    } catch (e){
+        try {
+            // When we are in I.E. but the script has been evaled so I.E. doesn't  trust the global object when called normally
+            return cachedClearTimeout.call(null, marker);
+        } catch (e){
+            // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.
+            // Some versions of I.E. have different rules for clearTimeout vs setTimeout
+            return cachedClearTimeout.call(this, marker);
+        }
+    }
+
+
+
+}
+var queue = [];
+var draining = false;
+var currentQueue;
+var queueIndex = -1;
+
+function cleanUpNextTick() {
+    if (!draining || !currentQueue) {
+        return;
+    }
+    draining = false;
+    if (currentQueue.length) {
+        queue = currentQueue.concat(queue);
+    } else {
+        queueIndex = -1;
+    }
+    if (queue.length) {
+        drainQueue();
+    }
+}
+
+function drainQueue() {
+    if (draining) {
+        return;
+    }
+    var timeout = runTimeout(cleanUpNextTick);
+    draining = true;
+
+    var len = queue.length;
+    while(len) {
+        currentQueue = queue;
+        queue = [];
+        while (++queueIndex < len) {
+            if (currentQueue) {
+                currentQueue[queueIndex].run();
+            }
+        }
+        queueIndex = -1;
+        len = queue.length;
+    }
+    currentQueue = null;
+    draining = false;
+    runClearTimeout(timeout);
+}
+
+process.nextTick = function (fun) {
+    var args = new Array(arguments.length - 1);
+    if (arguments.length > 1) {
+        for (var i = 1; i < arguments.length; i++) {
+            args[i - 1] = arguments[i];
+        }
+    }
+    queue.push(new Item(fun, args));
+    if (queue.length === 1 && !draining) {
+        runTimeout(drainQueue);
+    }
+};
+
+// v8 likes predictible objects
+function Item(fun, array) {
+    this.fun = fun;
+    this.array = array;
+}
+Item.prototype.run = function () {
+    this.fun.apply(null, this.array);
+};
+process.title = 'browser';
+process.browser = true;
+process.env = {};
+process.argv = [];
+process.version = ''; // empty string to avoid regexp issues
+process.versions = {};
+
+function noop() {}
+
+process.on = noop;
+process.addListener = noop;
+process.once = noop;
+process.off = noop;
+process.removeListener = noop;
+process.removeAllListeners = noop;
+process.emit = noop;
+process.prependListener = noop;
+process.prependOnceListener = noop;
+
+process.listeners = function (name) { return [] }
+
+process.binding = function (name) {
+    throw new Error('process.binding is not supported');
+};
+
+process.cwd = function () { return '/' };
+process.chdir = function (dir) {
+    throw new Error('process.chdir is not supported');
+};
+process.umask = function() { return 0; };
+
+},{}],104:[function(require,module,exports){
+/*
+ *
+ * Diff Parser (diff-parser.js)
+ * Author: rtfpessoa
+ *
+ */
+
+(function() {
+  var utils = require('./utils.js').Utils;
+
+  var LINE_TYPE = {
+    INSERTS: 'd2h-ins',
+    DELETES: 'd2h-del',
+    INSERT_CHANGES: 'd2h-ins d2h-change',
+    DELETE_CHANGES: 'd2h-del d2h-change',
+    CONTEXT: 'd2h-cntx',
+    INFO: 'd2h-info'
+  };
+
+  function DiffParser() {
+  }
+
+  DiffParser.prototype.LINE_TYPE = LINE_TYPE;
+
+  DiffParser.prototype.generateDiffJson = function(diffInput, configuration) {
+    var config = configuration || {};
+
+    var files = [];
+    var currentFile = null;
+    var currentBlock = null;
+    var oldLine = null;
+    var oldLine2 = null; // Used for combined diff
+    var newLine = null;
+
+    var possibleOldName;
+    var possibleNewName;
+
+    /* Diff Header */
+    var oldFileNameHeader = '--- ';
+    var newFileNameHeader = '+++ ';
+    var hunkHeaderPrefix = '@@';
+
+    /* Add previous block(if exists) before start a new file */
+    function saveBlock() {
+      if (currentBlock) {
+        currentFile.blocks.push(currentBlock);
+        currentBlock = null;
+      }
+    }
+
+    /*
+     * Add previous file(if exists) before start a new one
+     * if it has name (to avoid binary files errors)
+     */
+    function saveFile() {
+      if (currentFile) {
+        if (!currentFile.oldName) {
+          currentFile.oldName = possibleOldName;
+        }
+
+        if (!currentFile.newName) {
+          currentFile.newName = possibleNewName;
+        }
+
+        if (currentFile.newName) {
+          files.push(currentFile);
+          currentFile = null;
+        }
+      }
+
+      possibleOldName = undefined;
+      possibleNewName = undefined;
+    }
+
+    /* Create file structure */
+    function startFile() {
+      saveBlock();
+      saveFile();
+
+      currentFile = {};
+      currentFile.blocks = [];
+      currentFile.deletedLines = 0;
+      currentFile.addedLines = 0;
+    }
+
+    function startBlock(line) {
+      saveBlock();
+
+      var values;
+
+      /**
+       * From Range:
+       * -<start line>[,<number of lines>]
+       *
+       * To Range:
+       * +<start line>[,<number of lines>]
+       *
+       * @@ from-file-range to-file-range @@
+       *
+       * @@@ from-file-range from-file-range to-file-range @@@
+       *
+       * number of lines is optional, if omited consider 0
+       */
+
+      if ((values = /^@@ -(\d+)(?:,\d+)? \+(\d+)(?:,\d+)? @@.*/.exec(line))) {
+        currentFile.isCombined = false;
+        oldLine = values[1];
+        newLine = values[2];
+      } else if ((values = /^@@@ -(\d+)(?:,\d+)? -(\d+)(?:,\d+)? \+(\d+)(?:,\d+)? @@@.*/.exec(line))) {
+        currentFile.isCombined = true;
+        oldLine = values[1];
+        oldLine2 = values[2];
+        newLine = values[3];
+      } else {
+        if (utils.startsWith(line, hunkHeaderPrefix)) {
+          console.error('Failed to parse lines, starting in 0!');
+        }
+
+        oldLine = 0;
+        newLine = 0;
+        currentFile.isCombined = false;
+      }
+
+      /* Create block metadata */
+      currentBlock = {};
+      currentBlock.lines = [];
+      currentBlock.oldStartLine = oldLine;
+      currentBlock.oldStartLine2 = oldLine2;
+      currentBlock.newStartLine = newLine;
+      currentBlock.header = line;
+    }
+
+    function createLine(line) {
+      var currentLine = {};
+      currentLine.content = line;
+
+      var newLinePrefixes = !currentFile.isCombined ? ['+'] : ['+', ' +'];
+      var delLinePrefixes = !currentFile.isCombined ? ['-'] : ['-', ' -'];
+
+      /* Fill the line data */
+      if (utils.startsWith(line, newLinePrefixes)) {
+        currentFile.addedLines++;
+
+        currentLine.type = LINE_TYPE.INSERTS;
+        currentLine.oldNumber = null;
+        currentLine.newNumber = newLine++;
+
+        currentBlock.lines.push(currentLine);
+      } else if (utils.startsWith(line, delLinePrefixes)) {
+        currentFile.deletedLines++;
+
+        currentLine.type = LINE_TYPE.DELETES;
+        currentLine.oldNumber = oldLine++;
+        currentLine.newNumber = null;
+
+        currentBlock.lines.push(currentLine);
+      } else {
+        currentLine.type = LINE_TYPE.CONTEXT;
+        currentLine.oldNumber = oldLine++;
+        currentLine.newNumber = newLine++;
+
+        currentBlock.lines.push(currentLine);
+      }
+    }
+
+    /*
+     * Checks if there is a hunk header coming before a new file starts
+     *
+     * Hunk header is a group of three lines started by ( `--- ` , `+++ ` , `@@` )
+     */
+    function existHunkHeader(line, lineIdx) {
+      var idx = lineIdx;
+
+      while (idx < diffLines.length - 3) {
+        if (utils.startsWith(line, 'diff')) {
+          return false;
+        }
+
+        if (
+          utils.startsWith(diffLines[idx], oldFileNameHeader) &&
+          utils.startsWith(diffLines[idx + 1], newFileNameHeader) &&
+          utils.startsWith(diffLines[idx + 2], hunkHeaderPrefix)
+        ) {
+          return true;
+        }
+
+        idx++;
+      }
+
+      return false;
+    }
+
+    var diffLines =
+      diffInput.replace(/\\ No newline at end of file/g, '')
+        .replace(/\r\n?/g, '\n')
+        .split('\n');
+
+    /* Diff */
+    var oldMode = /^old mode (\d{6})/;
+    var newMode = /^new mode (\d{6})/;
+    var deletedFileMode = /^deleted file mode (\d{6})/;
+    var newFileMode = /^new file mode (\d{6})/;
+
+    var copyFrom = /^copy from "?(.+)"?/;
+    var copyTo = /^copy to "?(.+)"?/;
+
+    var renameFrom = /^rename from "?(.+)"?/;
+    var renameTo = /^rename to "?(.+)"?/;
+
+    var similarityIndex = /^similarity index (\d+)%/;
+    var dissimilarityIndex = /^dissimilarity index (\d+)%/;
+    var index = /^index ([0-9a-z]+)\.\.([0-9a-z]+)\s*(\d{6})?/;
+
+    var binaryFiles = /^Binary files (.*) and (.*) differ/;
+    var binaryDiff = /^GIT binary patch/;
+
+    /* Combined Diff */
+    var combinedIndex = /^index ([0-9a-z]+),([0-9a-z]+)\.\.([0-9a-z]+)/;
+    var combinedMode = /^mode (\d{6}),(\d{6})\.\.(\d{6})/;
+    var combinedNewFile = /^new file mode (\d{6})/;
+    var combinedDeletedFile = /^deleted file mode (\d{6}),(\d{6})/;
+
+    diffLines.forEach(function(line, lineIndex) {
+      // Unmerged paths, and possibly other non-diffable files
+      // https://github.com/scottgonzalez/pretty-diff/issues/11
+      // Also, remove some useless lines
+      if (!line || utils.startsWith(line, '*')) {
+        return;
+      }
+
+      // Used to store regex capture groups
+      var values;
+
+      var prevLine = diffLines[lineIndex - 1];
+      var nxtLine = diffLines[lineIndex + 1];
+      var afterNxtLine = diffLines[lineIndex + 2];
+
+      if (utils.startsWith(line, 'diff')) {
+        startFile();
+
+        // diff --git a/blocked_delta_results.png b/blocked_delta_results.png
+        var gitDiffStart = /^diff --git "?(.+)"? "?(.+)"?/;
+        if ((values = gitDiffStart.exec(line))) {
+          possibleOldName = _getFilename(null, values[1], config.dstPrefix);
+          possibleNewName = _getFilename(null, values[2], config.srcPrefix);
+        }
+
+        currentFile.isGitDiff = true;
+        return;
+      }
+
+      if (!currentFile || // If we do not have a file yet, we should crete one
+        (
+          !currentFile.isGitDiff && currentFile && // If we already have some file in progress and
+          (
+            utils.startsWith(line, oldFileNameHeader) && // If we get to an old file path header line
+            // And is followed by the new file path header line and the hunk header line
+            utils.startsWith(nxtLine, newFileNameHeader) && utils.startsWith(afterNxtLine, hunkHeaderPrefix)
+          )
+        )
+      ) {
+        startFile();
+      }
+
+      /*
+       * We need to make sure that we have the three lines of the header.
+       * This avoids cases like the ones described in:
+       *   - https://github.com/rtfpessoa/diff2html/issues/87
+       */
+      if (
+        (utils.startsWith(line, oldFileNameHeader) &&
+        utils.startsWith(nxtLine, newFileNameHeader)) ||
+
+        (utils.startsWith(line, newFileNameHeader) &&
+        utils.startsWith(prevLine, oldFileNameHeader))
+      ) {
+        /*
+         * --- Date Timestamp[FractionalSeconds] TimeZone
+         * --- 2002-02-21 23:30:39.942229878 -0800
+         */
+        if (currentFile && !currentFile.oldName &&
+          utils.startsWith(line, '--- ') && (values = getSrcFilename(line, config))) {
+          currentFile.oldName = values;
+          currentFile.language = getExtension(currentFile.oldName, currentFile.language);
+          return;
+        }
+
+        /*
+         * +++ Date Timestamp[FractionalSeconds] TimeZone
+         * +++ 2002-02-21 23:30:39.942229878 -0800
+         */
+        if (currentFile && !currentFile.newName &&
+          utils.startsWith(line, '+++ ') && (values = getDstFilename(line, config))) {
+          currentFile.newName = values;
+          currentFile.language = getExtension(currentFile.newName, currentFile.language);
+          return;
+        }
+      }
+
+      if (
+        (currentFile && utils.startsWith(line, hunkHeaderPrefix)) ||
+        (currentFile.isGitDiff && currentFile && currentFile.oldName && currentFile.newName && !currentBlock)
+      ) {
+        startBlock(line);
+        return;
+      }
+
+      /*
+       * There are three types of diff lines. These lines are defined by the way they start.
+       * 1. New line     starts with: +
+       * 2. Old line     starts with: -
+       * 3. Context line starts with: <SPACE>
+       */
+      if (currentBlock && (utils.startsWith(line, '+') || utils.startsWith(line, '-') || utils.startsWith(line, ' '))) {
+        createLine(line);
+        return;
+      }
+
+      var doesNotExistHunkHeader = !existHunkHeader(line, lineIndex);
+
+      /*
+       * Git diffs provide more information regarding files modes, renames, copies,
+       * commits between changes and similarity indexes
+       */
+      if ((values = oldMode.exec(line))) {
+        currentFile.oldMode = values[1];
+      } else if ((values = newMode.exec(line))) {
+        currentFile.newMode = values[1];
+      } else if ((values = deletedFileMode.exec(line))) {
+        currentFile.deletedFileMode = values[1];
+        currentFile.isDeleted = true;
+      } else if ((values = newFileMode.exec(line))) {
+        currentFile.newFileMode = values[1];
+        currentFile.isNew = true;
+      } else if ((values = copyFrom.exec(line))) {
+        if (doesNotExistHunkHeader) {
+          currentFile.oldName = values[1];
+        }
+        currentFile.isCopy = true;
+      } else if ((values = copyTo.exec(line))) {
+        if (doesNotExistHunkHeader) {
+          currentFile.newName = values[1];
+        }
+        currentFile.isCopy = true;
+      } else if ((values = renameFrom.exec(line))) {
+        if (doesNotExistHunkHeader) {
+          currentFile.oldName = values[1];
+        }
+        currentFile.isRename = true;
+      } else if ((values = renameTo.exec(line))) {
+        if (doesNotExistHunkHeader) {
+          currentFile.newName = values[1];
+        }
+        currentFile.isRename = true;
+      } else if ((values = binaryFiles.exec(line))) {
+        currentFile.isBinary = true;
+        currentFile.oldName = _getFilename(null, values[1], config.srcPrefix);
+        currentFile.newName = _getFilename(null, values[2], config.dstPrefix);
+        startBlock('Binary file');
+      } else if ((values = binaryDiff.exec(line))) {
+        currentFile.isBinary = true;
+        startBlock(line);
+      } else if ((values = similarityIndex.exec(line))) {
+        currentFile.unchangedPercentage = values[1];
+      } else if ((values = dissimilarityIndex.exec(line))) {
+        currentFile.changedPercentage = values[1];
+      } else if ((values = index.exec(line))) {
+        currentFile.checksumBefore = values[1];
+        currentFile.checksumAfter = values[2];
+        values[3] && (currentFile.mode = values[3]);
+      } else if ((values = combinedIndex.exec(line))) {
+        currentFile.checksumBefore = [values[2], values[3]];
+        currentFile.checksumAfter = values[1];
+      } else if ((values = combinedMode.exec(line))) {
+        currentFile.oldMode = [values[2], values[3]];
+        currentFile.newMode = values[1];
+      } else if ((values = combinedNewFile.exec(line))) {
+        currentFile.newFileMode = values[1];
+        currentFile.isNew = true;
+      } else if ((values = combinedDeletedFile.exec(line))) {
+        currentFile.deletedFileMode = values[1];
+        currentFile.isDeleted = true;
+      }
+    });
+
+    saveBlock();
+    saveFile();
+
+    return files;
+  };
+
+  function getExtension(filename, language) {
+    var nameSplit = filename.split('.');
+    if (nameSplit.length > 1) {
+      return nameSplit[nameSplit.length - 1];
+    }
+
+    return language;
+  }
+
+  function getSrcFilename(line, cfg) {
+    return _getFilename('---', line, cfg.srcPrefix);
+  }
+
+  function getDstFilename(line, cfg) {
+    return _getFilename('\\+\\+\\+', line, cfg.dstPrefix);
+  }
+
+  function _getFilename(linePrefix, line, extraPrefix) {
+    var prefixes = ['a/', 'b/', 'i/', 'w/', 'c/', 'o/'];
+    if (extraPrefix) {
+      prefixes.push(extraPrefix);
+    }
+
+    var FilenameRegExp;
+    if (linePrefix) {
+      FilenameRegExp = new RegExp('^' + linePrefix + ' "?(.+?)"?$');
+    } else {
+      FilenameRegExp = new RegExp('^"?(.+?)"?$');
+    }
+
+    var filename;
+    var values = FilenameRegExp.exec(line);
+    if (values && values[1]) {
+      filename = values[1];
+      var matchingPrefixes = prefixes.filter(function(p) {
+        return filename.indexOf(p) === 0;
+      });
+
+      if (matchingPrefixes[0]) {
+        // Remove prefix if exists
+        filename = filename.slice(matchingPrefixes[0].length);
+      }
+
+      // Cleanup timestamps generated by the unified diff (diff command) as specified in
+      // https://www.gnu.org/software/diffutils/manual/html_node/Detailed-Unified.html
+      // Ie: 2016-10-25 11:37:14.000000000 +0200
+      filename = filename.replace(/\s+\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}(?:\.\d+)? [-+]\d{4}.*$/, '');
+    }
+
+    return filename;
+  }
+
+  module.exports.DiffParser = new DiffParser();
+})();
+
+},{"./utils.js":114}],105:[function(require,module,exports){
+(function (global){
+/*
+ *
+ * Diff to HTML (diff2html.js)
+ * Author: rtfpessoa
+ *
+ */
+
+(function() {
+  var diffParser = require('./diff-parser.js').DiffParser;
+  var htmlPrinter = require('./html-printer.js').HtmlPrinter;
+  var utils = require('./utils.js').Utils;
+
+  function Diff2Html() {
+  }
+
+  var defaultConfig = {
+    wordByWord: true,
+    outputFormat: 'line-by-line',
+    matching: 'none',
+    matchWordsThreshold: 0.25,
+    matchingMaxComparisons: 2500,
+    maxLineLengthHighlight: 10000
+  };
+
+  /*
+   * Generates json object from string diff input
+   */
+  Diff2Html.prototype.getJsonFromDiff = function(diffInput, config) {
+    var cfg = utils.safeConfig(config, defaultConfig);
+    return diffParser.generateDiffJson(diffInput, cfg);
+  };
+
+  /*
+   * Generates the html diff. The config parameter configures the output/input formats and other options
+   */
+  Diff2Html.prototype.getPrettyHtml = function(diffInput, config) {
+    var cfg = utils.safeConfig(config, defaultConfig);
+
+    var diffJson = diffInput;
+    if (!cfg.inputFormat || cfg.inputFormat === 'diff') {
+      diffJson = diffParser.generateDiffJson(diffInput, cfg);
+    }
+
+    var fileList = '';
+    if (cfg.showFiles === true) {
+      fileList = htmlPrinter.generateFileListSummary(diffJson, cfg);
+    }
+
+    var diffOutput = '';
+    if (cfg.outputFormat === 'side-by-side') {
+      diffOutput = htmlPrinter.generateSideBySideJsonHtml(diffJson, cfg);
+    } else {
+      diffOutput = htmlPrinter.generateLineByLineJsonHtml(diffJson, cfg);
+    }
+
+    return fileList + diffOutput;
+  };
+
+  /*
+   * Deprecated methods - The following methods exist only to maintain compatibility with previous versions
+   */
+
+  /*
+   * Generates pretty html from string diff input
+   */
+  Diff2Html.prototype.getPrettyHtmlFromDiff = function(diffInput, config) {
+    var cfg = utils.safeConfig(config, defaultConfig);
+    cfg.inputFormat = 'diff';
+    cfg.outputFormat = 'line-by-line';
+    return this.getPrettyHtml(diffInput, cfg);
+  };
+
+  /*
+   * Generates pretty html from a json object
+   */
+  Diff2Html.prototype.getPrettyHtmlFromJson = function(diffJson, config) {
+    var cfg = utils.safeConfig(config, defaultConfig);
+    cfg.inputFormat = 'json';
+    cfg.outputFormat = 'line-by-line';
+    return this.getPrettyHtml(diffJson, cfg);
+  };
+
+  /*
+   * Generates pretty side by side html from string diff input
+   */
+  Diff2Html.prototype.getPrettySideBySideHtmlFromDiff = function(diffInput, config) {
+    var cfg = utils.safeConfig(config, defaultConfig);
+    cfg.inputFormat = 'diff';
+    cfg.outputFormat = 'side-by-side';
+    return this.getPrettyHtml(diffInput, cfg);
+  };
+
+  /*
+   * Generates pretty side by side html from a json object
+   */
+  Diff2Html.prototype.getPrettySideBySideHtmlFromJson = function(diffJson, config) {
+    var cfg = utils.safeConfig(config, defaultConfig);
+    cfg.inputFormat = 'json';
+    cfg.outputFormat = 'side-by-side';
+    return this.getPrettyHtml(diffJson, cfg);
+  };
+
+  var diffObject = new Diff2Html();
+  module.exports.Diff2Html = diffObject;
+
+  // Expose diff2html in the browser
+  global.Diff2Html = diffObject;
+})();
+
+}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+},{"./diff-parser.js":104,"./html-printer.js":108,"./utils.js":114}],106:[function(require,module,exports){
+/*
+ *
+ * FileListPrinter (file-list-printer.js)
+ * Author: nmatpt
+ *
+ */
+
+(function() {
+  var printerUtils = require('./printer-utils.js').PrinterUtils;
+
+  var hoganUtils;
+
+  var baseTemplatesPath = 'file-summary';
+  var iconsBaseTemplatesPath = 'icon';
+
+  function FileListPrinter(config) {
+    this.config = config;
+
+    var HoganJsUtils = require('./hoganjs-utils.js').HoganJsUtils;
+    hoganUtils = new HoganJsUtils(config);
+  }
+
+  FileListPrinter.prototype.generateFileList = function(diffFiles) {
+    var lineTemplate = hoganUtils.template(baseTemplatesPath, 'line');
+
+    var files = diffFiles.map(function(file) {
+      var fileTypeName = printerUtils.getFileTypeIcon(file);
+      var iconTemplate = hoganUtils.template(iconsBaseTemplatesPath, fileTypeName);
+
+      return lineTemplate.render({
+        fileHtmlId: printerUtils.getHtmlId(file),
+        fileName: printerUtils.getDiffName(file),
+        deletedLines: '-' + file.deletedLines,
+        addedLines: '+' + file.addedLines
+      }, {
+        fileIcon: iconTemplate
+      });
+    }).join('\n');
+
+    return hoganUtils.render(baseTemplatesPath, 'wrapper', {
+      filesNumber: diffFiles.length,
+      files: files
+    });
+  };
+
+  module.exports.FileListPrinter = FileListPrinter;
+})();
+
+},{"./hoganjs-utils.js":107,"./printer-utils.js":110}],107:[function(require,module,exports){
+(function (__dirname){
+/*
+ *
+ * Utils (hoganjs-utils.js)
+ * Author: rtfpessoa
+ *
+ */
+
+(function() {
+  var fs = require('fs');
+  var path = require('path');
+  var hogan = require('hogan.js');
+
+  var hoganTemplates = require('./templates/diff2html-templates.js');
+
+  var extraTemplates;
+
+  function HoganJsUtils(configuration) {
+    this.config = configuration || {};
+    extraTemplates = this.config.templates || {};
+
+    var rawTemplates = this.config.rawTemplates || {};
+    for (var templateName in rawTemplates) {
+      if (rawTemplates.hasOwnProperty(templateName)) {
+        if (!extraTemplates[templateName]) extraTemplates[templateName] = this.compile(rawTemplates[templateName]);
+      }
+    }
+  }
+
+  HoganJsUtils.prototype.render = function(namespace, view, params) {
+    var template = this.template(namespace, view);
+    if (template) {
+      return template.render(params);
+    }
+
+    return null;
+  };
+
+  HoganJsUtils.prototype.template = function(namespace, view) {
+    var templateKey = this._templateKey(namespace, view);
+
+    return this._getTemplate(templateKey);
+  };
+
+  HoganJsUtils.prototype._getTemplate = function(templateKey) {
+    var template;
+
+    if (!this.config.noCache) {
+      template = this._readFromCache(templateKey);
+    }
+
+    if (!template) {
+      template = this._loadTemplate(templateKey);
+    }
+
+    return template;
+  };
+
+  HoganJsUtils.prototype._loadTemplate = function(templateKey) {
+    var template;
+
+    try {
+      if (fs.readFileSync) {
+        var templatesPath = path.resolve(__dirname, 'templates');
+        var templatePath = path.join(templatesPath, templateKey);
+        var templateContent = fs.readFileSync(templatePath + '.mustache', 'utf8');
+        template = hogan.compile(templateContent);
+        hoganTemplates[templateKey] = template;
+      }
+    } catch (e) {
+      console.error('Failed to read (template: ' + templateKey + ') from fs: ' + e.message);
+    }
+
+    return template;
+  };
+
+  HoganJsUtils.prototype._readFromCache = function(templateKey) {
+    return extraTemplates[templateKey] || hoganTemplates[templateKey];
+  };
+
+  HoganJsUtils.prototype._templateKey = function(namespace, view) {
+    return namespace + '-' + view;
+  };
+
+  HoganJsUtils.prototype.compile = function(templateStr) {
+    return hogan.compile(templateStr);
+  };
+
+  module.exports.HoganJsUtils = HoganJsUtils;
+})();
+
+}).call(this,"/src")
+},{"./templates/diff2html-templates.js":113,"fs":1,"hogan.js":4,"path":102}],108:[function(require,module,exports){
+/*
+ *
+ * HtmlPrinter (html-printer.js)
+ * Author: rtfpessoa
+ *
+ */
+
+(function() {
+  var LineByLinePrinter = require('./line-by-line-printer.js').LineByLinePrinter;
+  var SideBySidePrinter = require('./side-by-side-printer.js').SideBySidePrinter;
+  var FileListPrinter = require('./file-list-printer.js').FileListPrinter;
+
+  function HtmlPrinter() {
+  }
+
+  HtmlPrinter.prototype.generateLineByLineJsonHtml = function(diffFiles, config) {
+    var lineByLinePrinter = new LineByLinePrinter(config);
+    return lineByLinePrinter.generateLineByLineJsonHtml(diffFiles);
+  };
+
+  HtmlPrinter.prototype.generateSideBySideJsonHtml = function(diffFiles, config) {
+    var sideBySidePrinter = new SideBySidePrinter(config);
+    return sideBySidePrinter.generateSideBySideJsonHtml(diffFiles);
+  };
+
+  HtmlPrinter.prototype.generateFileListSummary = function(diffJson, config) {
+    var fileListPrinter = new FileListPrinter(config);
+    return fileListPrinter.generateFileList(diffJson);
+  };
+
+  module.exports.HtmlPrinter = new HtmlPrinter();
+})();
+
+},{"./file-list-printer.js":106,"./line-by-line-printer.js":109,"./side-by-side-printer.js":112}],109:[function(require,module,exports){
+/*
+ *
+ * LineByLinePrinter (line-by-line-printer.js)
+ * Author: rtfpessoa
+ *
+ */
+
+(function() {
+  var diffParser = require('./diff-parser.js').DiffParser;
+  var printerUtils = require('./printer-utils.js').PrinterUtils;
+  var utils = require('./utils.js').Utils;
+  var Rematch = require('./rematch.js').Rematch;
+
+  var hoganUtils;
+
+  var genericTemplatesPath = 'generic';
+  var baseTemplatesPath = 'line-by-line';
+  var iconsBaseTemplatesPath = 'icon';
+  var tagsBaseTemplatesPath = 'tag';
+
+  function LineByLinePrinter(config) {
+    this.config = config;
+
+    var HoganJsUtils = require('./hoganjs-utils.js').HoganJsUtils;
+    hoganUtils = new HoganJsUtils(config);
+  }
+
+  LineByLinePrinter.prototype.makeFileDiffHtml = function(file, diffs) {
+    var fileDiffTemplate = hoganUtils.template(baseTemplatesPath, 'file-diff');
+    var filePathTemplate = hoganUtils.template(genericTemplatesPath, 'file-path');
+    var fileIconTemplate = hoganUtils.template(iconsBaseTemplatesPath, 'file');
+    var fileTagTemplate = hoganUtils.template(tagsBaseTemplatesPath, printerUtils.getFileTypeIcon(file));
+
+    return fileDiffTemplate.render({
+      file: file,
+      fileHtmlId: printerUtils.getHtmlId(file),
+      diffs: diffs,
+      filePath: filePathTemplate.render({
+        fileDiffName: printerUtils.getDiffName(file)
+      }, {
+        fileIcon: fileIconTemplate,
+        fileTag: fileTagTemplate
+      })
+    });
+  };
+
+  LineByLinePrinter.prototype.makeLineByLineHtmlWrapper = function(content) {
+    return hoganUtils.render(genericTemplatesPath, 'wrapper', {'content': content});
+  };
+
+  LineByLinePrinter.prototype.generateLineByLineJsonHtml = function(diffFiles) {
+    var that = this;
+    var htmlDiffs = diffFiles.map(function(file) {
+      var diffs;
+      if (file.blocks.length) {
+        diffs = that._generateFileHtml(file);
+      } else {
+        diffs = that._generateEmptyDiff();
+      }
+      return that.makeFileDiffHtml(file, diffs);
+    });
+
+    return this.makeLineByLineHtmlWrapper(htmlDiffs.join('\n'));
+  };
+
+  var matcher = Rematch.rematch(function(a, b) {
+    var amod = a.content.substr(1);
+    var bmod = b.content.substr(1);
+
+    return Rematch.distance(amod, bmod);
+  });
+
+  LineByLinePrinter.prototype.makeColumnLineNumberHtml = function(block) {
+    return hoganUtils.render(genericTemplatesPath, 'column-line-number', {
+      diffParser: diffParser,
+      blockHeader: utils.escape(block.header),
+      lineClass: 'd2h-code-linenumber',
+      contentClass: 'd2h-code-line'
+    });
+  };
+
+  LineByLinePrinter.prototype._generateFileHtml = function(file) {
+    var that = this;
+    return file.blocks.map(function(block) {
+      var lines = that.makeColumnLineNumberHtml(block);
+      var oldLines = [];
+      var newLines = [];
+
+      function processChangeBlock() {
+        var matches;
+        var insertType;
+        var deleteType;
+
+        var comparisons = oldLines.length * newLines.length;
+        var maxComparisons = that.config.matchingMaxComparisons || 2500;
+        var doMatching = comparisons < maxComparisons && (that.config.matching === 'lines' ||
+          that.config.matching === 'words');
+
+        if (doMatching) {
+          matches = matcher(oldLines, newLines);
+          insertType = diffParser.LINE_TYPE.INSERT_CHANGES;
+          deleteType = diffParser.LINE_TYPE.DELETE_CHANGES;
+        } else {
+          matches = [[oldLines, newLines]];
+          insertType = diffParser.LINE_TYPE.INSERTS;
+          deleteType = diffParser.LINE_TYPE.DELETES;
+        }
+
+        matches.forEach(function(match) {
+          oldLines = match[0];
+          newLines = match[1];
+
+          var processedOldLines = [];
+          var processedNewLines = [];
+
+          var common = Math.min(oldLines.length, newLines.length);
+
+          var oldLine, newLine;
+          for (var j = 0; j < common; j++) {
+            oldLine = oldLines[j];
+            newLine = newLines[j];
+
+            that.config.isCombined = file.isCombined;
+            var diff = printerUtils.diffHighlight(oldLine.content, newLine.content, that.config);
+
+            processedOldLines +=
+              that.makeLineHtml(file.isCombined, deleteType, oldLine.oldNumber, oldLine.newNumber,
+                diff.first.line, diff.first.prefix);
+            processedNewLines +=
+              that.makeLineHtml(file.isCombined, insertType, newLine.oldNumber, newLine.newNumber,
+                diff.second.line, diff.second.prefix);
+          }
+
+          lines += processedOldLines + processedNewLines;
+          lines += that._processLines(file.isCombined, oldLines.slice(common), newLines.slice(common));
+        });
+
+        oldLines = [];
+        newLines = [];
+      }
+
+      for (var i = 0; i < block.lines.length; i++) {
+        var line = block.lines[i];
+        var escapedLine = utils.escape(line.content);
+
+        if (line.type !== diffParser.LINE_TYPE.INSERTS &&
+          (newLines.length > 0 || (line.type !== diffParser.LINE_TYPE.DELETES && oldLines.length > 0))) {
+          processChangeBlock();
+        }
+
+        if (line.type === diffParser.LINE_TYPE.CONTEXT) {
+          lines += that.makeLineHtml(file.isCombined, line.type, line.oldNumber, line.newNumber, escapedLine);
+        } else if (line.type === diffParser.LINE_TYPE.INSERTS && !oldLines.length) {
+          lines += that.makeLineHtml(file.isCombined, line.type, line.oldNumber, line.newNumber, escapedLine);
+        } else if (line.type === diffParser.LINE_TYPE.DELETES) {
+          oldLines.push(line);
+        } else if (line.type === diffParser.LINE_TYPE.INSERTS && Boolean(oldLines.length)) {
+          newLines.push(line);
+        } else {
+          console.error('Unknown state in html line-by-line generator');
+          processChangeBlock();
+        }
+      }
+
+      processChangeBlock();
+
+      return lines;
+    }).join('\n');
+  };
+
+  LineByLinePrinter.prototype._processLines = function(isCombined, oldLines, newLines) {
+    var lines = '';
+
+    for (var i = 0; i < oldLines.length; i++) {
+      var oldLine = oldLines[i];
+      var oldEscapedLine = utils.escape(oldLine.content);
+      lines += this.makeLineHtml(isCombined, oldLine.type, oldLine.oldNumber, oldLine.newNumber, oldEscapedLine);
+    }
+
+    for (var j = 0; j < newLines.length; j++) {
+      var newLine = newLines[j];
+      var newEscapedLine = utils.escape(newLine.content);
+      lines += this.makeLineHtml(isCombined, newLine.type, newLine.oldNumber, newLine.newNumber, newEscapedLine);
+    }
+
+    return lines;
+  };
+
+  LineByLinePrinter.prototype.makeLineHtml = function(isCombined, type, oldNumber, newNumber, content, possiblePrefix) {
+    var lineNumberTemplate = hoganUtils.render(baseTemplatesPath, 'numbers', {
+      oldNumber: utils.valueOrEmpty(oldNumber),
+      newNumber: utils.valueOrEmpty(newNumber)
+    });
+
+    var lineWithoutPrefix = content;
+    var prefix = possiblePrefix;
+
+    if (!prefix) {
+      var lineWithPrefix = printerUtils.separatePrefix(isCombined, content);
+      prefix = lineWithPrefix.prefix;
+      lineWithoutPrefix = lineWithPrefix.line;
+    }
+
+    return hoganUtils.render(genericTemplatesPath, 'line',
+      {
+        type: type,
+        lineClass: 'd2h-code-linenumber',
+        contentClass: 'd2h-code-line',
+        prefix: prefix,
+        content: lineWithoutPrefix,
+        lineNumber: lineNumberTemplate
+      });
+  };
+
+  LineByLinePrinter.prototype._generateEmptyDiff = function() {
+    return hoganUtils.render(genericTemplatesPath, 'empty-diff', {
+      contentClass: 'd2h-code-line',
+      diffParser: diffParser
+    });
+  };
+
+  module.exports.LineByLinePrinter = LineByLinePrinter;
+})();
+
+},{"./diff-parser.js":104,"./hoganjs-utils.js":107,"./printer-utils.js":110,"./rematch.js":111,"./utils.js":114}],110:[function(require,module,exports){
+/*
+ *
+ * PrinterUtils (printer-utils.js)
+ * Author: rtfpessoa
+ *
+ */
+
+(function() {
+  var jsDiff = require('diff');
+  var utils = require('./utils.js').Utils;
+  var Rematch = require('./rematch.js').Rematch;
+
+  var separator = '/';
+
+  function PrinterUtils() {
+  }
+
+  PrinterUtils.prototype.separatePrefix = function(isCombined, line) {
+    var prefix;
+    var lineWithoutPrefix;
+
+    if (isCombined) {
+      prefix = line.substring(0, 2);
+      lineWithoutPrefix = line.substring(2);
+    } else {
+      prefix = line.substring(0, 1);
+      lineWithoutPrefix = line.substring(1);
+    }
+
+    return {
+      'prefix': prefix,
+      'line': lineWithoutPrefix
+    };
+  };
+
+  PrinterUtils.prototype.getHtmlId = function(file) {
+    var hashCode = function(text) {
+      var i, chr, len;
+      var hash = 0;
+
+      for (i = 0, len = text.length; i < len; i++) {
+        chr = text.charCodeAt(i);
+        hash = ((hash << 5) - hash) + chr;
+        hash |= 0; // Convert to 32bit integer
+      }
+
+      return hash;
+    };
+
+    return 'd2h-' + hashCode(this.getDiffName(file)).toString().slice(-6);
+  };
+
+  PrinterUtils.prototype.getDiffName = function(file) {
+    var oldFilename = unifyPath(file.oldName);
+    var newFilename = unifyPath(file.newName);
+
+    if (oldFilename && newFilename && oldFilename !== newFilename && !isDevNullName(oldFilename) && !isDevNullName(newFilename)) {
+      var prefixPaths = [];
+      var suffixPaths = [];
+
+      var oldFilenameParts = oldFilename.split(separator);
+      var newFilenameParts = newFilename.split(separator);
+
+      var oldFilenamePartsSize = oldFilenameParts.length;
+      var newFilenamePartsSize = newFilenameParts.length;
+
+      var i = 0;
+      var j = oldFilenamePartsSize - 1;
+      var k = newFilenamePartsSize - 1;
+
+      while (i < j && i < k) {
+        if (oldFilenameParts[i] === newFilenameParts[i]) {
+          prefixPaths.push(newFilenameParts[i]);
+          i += 1;
+        } else {
+          break;
+        }
+      }
+
+      while (j > i && k > i) {
+        if (oldFilenameParts[j] === newFilenameParts[k]) {
+          suffixPaths.unshift(newFilenameParts[k]);
+          j -= 1;
+          k -= 1;
+        } else {
+          break;
+        }
+      }
+
+      var finalPrefix = prefixPaths.join(separator);
+      var finalSuffix = suffixPaths.join(separator);
+
+      var oldRemainingPath = oldFilenameParts.slice(i, j + 1).join(separator);
+      var newRemainingPath = newFilenameParts.slice(i, k + 1).join(separator);
+
+      if (finalPrefix.length && finalSuffix.length) {
+        return finalPrefix + separator + '{' + oldRemainingPath + ' → ' + newRemainingPath + '}' + separator + finalSuffix;
+      } else if (finalPrefix.length) {
+        return finalPrefix + separator + '{' + oldRemainingPath + ' → ' + newRemainingPath + '}';
+      } else if (finalSuffix.length) {
+        return '{' + oldRemainingPath + ' → ' + newRemainingPath + '}' + separator + finalSuffix;
+      }
+
+      return oldFilename + ' → ' + newFilename;
+    } else if (newFilename && !isDevNullName(newFilename)) {
+      return newFilename;
+    } else if (oldFilename) {
+      return oldFilename;
+    }
+
+    return 'unknown/file/path';
+  };
+
+  PrinterUtils.prototype.getFileTypeIcon = function(file) {
+    var templateName = 'file-changed';
+
+    if (file.isRename) {
+      templateName = 'file-renamed';
+    } else if (file.isCopy) {
+      templateName = 'file-renamed';
+    } else if (file.isNew) {
+      templateName = 'file-added';
+    } else if (file.isDeleted) {
+      templateName = 'file-deleted';
+    } else if (file.newName !== file.oldName) {
+      // If file is not Added, not Deleted and the names changed it must be a rename :)
+      templateName = 'file-renamed';
+    }
+
+    return templateName;
+  };
+
+  PrinterUtils.prototype.diffHighlight = function(diffLine1, diffLine2, config) {
+    var linePrefix1, linePrefix2, unprefixedLine1, unprefixedLine2;
+
+    var prefixSize = 1;
+
+    if (config.isCombined) {
+      prefixSize = 2;
+    }
+
+    linePrefix1 = diffLine1.substr(0, prefixSize);
+    linePrefix2 = diffLine2.substr(0, prefixSize);
+    unprefixedLine1 = diffLine1.substr(prefixSize);
+    unprefixedLine2 = diffLine2.substr(prefixSize);
+
+    if (unprefixedLine1.length > config.maxLineLengthHighlight ||
+      unprefixedLine2.length > config.maxLineLengthHighlight) {
+      return {
+        first: {
+          prefix: linePrefix1,
+          line: utils.escape(unprefixedLine1)
+        },
+        second: {
+          prefix: linePrefix2,
+          line: utils.escape(unprefixedLine2)
+        }
+      };
+    }
+
+    var diff;
+    if (config.charByChar) {
+      diff = jsDiff.diffChars(unprefixedLine1, unprefixedLine2);
+    } else {
+      diff = jsDiff.diffWordsWithSpace(unprefixedLine1, unprefixedLine2);
+    }
+
+    var highlightedLine = '';
+
+    var changedWords = [];
+    if (!config.charByChar && config.matching === 'words') {
+      var treshold = 0.25;
+
+      if (typeof (config.matchWordsThreshold) !== 'undefined') {
+        treshold = config.matchWordsThreshold;
+      }
+
+      var matcher = Rematch.rematch(function(a, b) {
+        var amod = a.value;
+        var bmod = b.value;
+
+        return Rematch.distance(amod, bmod);
+      });
+
+      var removed = diff.filter(function isRemoved(element) {
+        return element.removed;
+      });
+
+      var added = diff.filter(function isAdded(element) {
+        return element.added;
+      });
+
+      var chunks = matcher(added, removed);
+      chunks.forEach(function(chunk) {
+        if (chunk[0].length === 1 && chunk[1].length === 1) {
+          var dist = Rematch.distance(chunk[0][0].value, chunk[1][0].value);
+          if (dist < treshold) {
+            changedWords.push(chunk[0][0]);
+            changedWords.push(chunk[1][0]);
+          }
+        }
+      });
+    }
+
+    diff.forEach(function(part) {
+      var addClass = changedWords.indexOf(part) > -1 ? ' class="d2h-change"' : '';
+      var elemType = part.added ? 'ins' : part.removed ? 'del' : null;
+      var escapedValue = utils.escape(part.value);
+
+      if (elemType !== null) {
+        highlightedLine += '<' + elemType + addClass + '>' + escapedValue + '</' + elemType + '>';
+      } else {
+        highlightedLine += escapedValue;
+      }
+    });
+
+    return {
+      first: {
+        prefix: linePrefix1,
+        line: removeIns(highlightedLine)
+      },
+      second: {
+        prefix: linePrefix2,
+        line: removeDel(highlightedLine)
+      }
+    };
+  };
+
+  function unifyPath(path) {
+    if (path) {
+      return path.replace('\\', '/');
+    }
+
+    return path;
+  }
+
+  function isDevNullName(name) {
+    return name.indexOf('dev/null') !== -1;
+  }
+
+  function removeIns(line) {
+    return line.replace(/(<ins[^>]*>((.|\n)*?)<\/ins>)/g, '');
+  }
+
+  function removeDel(line) {
+    return line.replace(/(<del[^>]*>((.|\n)*?)<\/del>)/g, '');
+  }
+
+  module.exports.PrinterUtils = new PrinterUtils();
+})();
+
+},{"./rematch.js":111,"./utils.js":114,"diff":2}],111:[function(require,module,exports){
+/*
+ *
+ * Rematch (rematch.js)
+ * Matching two sequences of objects by similarity
+ * Author: W. Illmeyer, Nexxar GmbH
+ *
+ */
+
+(function() {
+  var Rematch = {};
+
+  /*
+   Copyright (c) 2011 Andrei Mackenzie
+   Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+   documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+   the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
+   and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+   The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
+   THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+   */
+  function levenshtein(a, b) {
+    if (a.length === 0) {
+      return b.length;
+    }
+    if (b.length === 0) {
+      return a.length;
+    }
+
+    var matrix = [];
+
+    // Increment along the first column of each row
+    var i;
+    for (i = 0; i <= b.length; i++) {
+      matrix[i] = [i];
+    }
+
+    // Increment each column in the first row
+    var j;
+    for (j = 0; j <= a.length; j++) {
+      matrix[0][j] = j;
+    }
+
+    // Fill in the rest of the matrix
+    for (i = 1; i <= b.length; i++) {
+      for (j = 1; j <= a.length; j++) {
+        if (b.charAt(i - 1) === a.charAt(j - 1)) {
+          matrix[i][j] = matrix[i - 1][j - 1];
+        } else {
+          matrix[i][j] = Math.min(matrix[i - 1][j - 1] + 1, // Substitution
+            Math.min(matrix[i][j - 1] + 1, // Insertion
+              matrix[i - 1][j] + 1)); // Deletion
+        }
+      }
+    }
+
+    return matrix[b.length][a.length];
+  }
+
+  Rematch.levenshtein = levenshtein;
+
+  Rematch.distance = function distance(x, y) {
+    x = x.trim();
+    y = y.trim();
+    var lev = levenshtein(x, y);
+    var score = lev / (x.length + y.length);
+
+    return score;
+  };
+
+  Rematch.rematch = function rematch(distanceFunction) {
+    function findBestMatch(a, b, cache) {
+      var bestMatchDist = Infinity;
+      var bestMatch;
+      for (var i = 0; i < a.length; ++i) {
+        for (var j = 0; j < b.length; ++j) {
+          var cacheKey = JSON.stringify([a[i], b[j]]);
+          var md;
+          if (cache.hasOwnProperty(cacheKey)) {
+            md = cache[cacheKey];
+          } else {
+            md = distanceFunction(a[i], b[j]);
+            cache[cacheKey] = md;
+          }
+          if (md < bestMatchDist) {
+            bestMatchDist = md;
+            bestMatch = {indexA: i, indexB: j, score: bestMatchDist};
+          }
+        }
+      }
+
+      return bestMatch;
+    }
+
+    function group(a, b, level, cache) {
+      if (typeof (cache) === 'undefined') {
+        cache = {};
+      }
+
+      var bm = findBestMatch(a, b, cache);
+
+      if (!level) {
+        level = 0;
+      }
+
+      if (!bm || (a.length + b.length < 3)) {
+        return [[a, b]];
+      }
+
+      var a1 = a.slice(0, bm.indexA);
+      var b1 = b.slice(0, bm.indexB);
+      var aMatch = [a[bm.indexA]];
+      var bMatch = [b[bm.indexB]];
+      var tailA = bm.indexA + 1;
+      var tailB = bm.indexB + 1;
+      var a2 = a.slice(tailA);
+      var b2 = b.slice(tailB);
+
+      var group1 = group(a1, b1, level + 1, cache);
+      var groupMatch = group(aMatch, bMatch, level + 1, cache);
+      var group2 = group(a2, b2, level + 1, cache);
+      var result = groupMatch;
+
+      if (bm.indexA > 0 || bm.indexB > 0) {
+        result = group1.concat(result);
+      }
+
+      if (a.length > tailA || b.length > tailB) {
+        result = result.concat(group2);
+      }
+
+      return result;
+    }
+
+    return group;
+  };
+
+  module.exports.Rematch = Rematch;
+})();
+
+},{}],112:[function(require,module,exports){
+/*
+ *
+ * HtmlPrinter (html-printer.js)
+ * Author: rtfpessoa
+ *
+ */
+
+(function() {
+  var diffParser = require('./diff-parser.js').DiffParser;
+  var printerUtils = require('./printer-utils.js').PrinterUtils;
+  var utils = require('./utils.js').Utils;
+  var Rematch = require('./rematch.js').Rematch;
+
+  var hoganUtils;
+
+  var genericTemplatesPath = 'generic';
+  var baseTemplatesPath = 'side-by-side';
+  var iconsBaseTemplatesPath = 'icon';
+  var tagsBaseTemplatesPath = 'tag';
+
+  var matcher = Rematch.rematch(function(a, b) {
+    var amod = a.content.substr(1);
+    var bmod = b.content.substr(1);
+
+    return Rematch.distance(amod, bmod);
+  });
+
+  function SideBySidePrinter(config) {
+    this.config = config;
+
+    var HoganJsUtils = require('./hoganjs-utils.js').HoganJsUtils;
+    hoganUtils = new HoganJsUtils(config);
+  }
+
+  SideBySidePrinter.prototype.makeDiffHtml = function(file, diffs) {
+    var fileDiffTemplate = hoganUtils.template(baseTemplatesPath, 'file-diff');
+    var filePathTemplate = hoganUtils.template(genericTemplatesPath, 'file-path');
+    var fileIconTemplate = hoganUtils.template(iconsBaseTemplatesPath, 'file');
+    var fileTagTemplate = hoganUtils.template(tagsBaseTemplatesPath, printerUtils.getFileTypeIcon(file));
+
+    return fileDiffTemplate.render({
+      file: file,
+      fileHtmlId: printerUtils.getHtmlId(file),
+      diffs: diffs,
+      filePath: filePathTemplate.render({
+        fileDiffName: printerUtils.getDiffName(file)
+      }, {
+        fileIcon: fileIconTemplate,
+        fileTag: fileTagTemplate
+      })
+    });
+  };
+
+  SideBySidePrinter.prototype.generateSideBySideJsonHtml = function(diffFiles) {
+    var that = this;
+
+    var content = diffFiles.map(function(file) {
+      var diffs;
+      if (file.blocks.length) {
+        diffs = that.generateSideBySideFileHtml(file);
+      } else {
+        diffs = that.generateEmptyDiff();
+      }
+
+      return that.makeDiffHtml(file, diffs);
+    }).join('\n');
+
+    return hoganUtils.render(genericTemplatesPath, 'wrapper', {'content': content});
+  };
+
+  SideBySidePrinter.prototype.makeSideHtml = function(blockHeader) {
+    return hoganUtils.render(genericTemplatesPath, 'column-line-number', {
+      diffParser: diffParser,
+      blockHeader: utils.escape(blockHeader),
+      lineClass: 'd2h-code-side-linenumber',
+      contentClass: 'd2h-code-side-line'
+    });
+  };
+
+  SideBySidePrinter.prototype.generateSideBySideFileHtml = function(file) {
+    var that = this;
+    var fileHtml = {};
+    fileHtml.left = '';
+    fileHtml.right = '';
+
+    file.blocks.forEach(function(block) {
+      fileHtml.left += that.makeSideHtml(block.header);
+      fileHtml.right += that.makeSideHtml('');
+
+      var oldLines = [];
+      var newLines = [];
+
+      function processChangeBlock() {
+        var matches;
+        var insertType;
+        var deleteType;
+
+        var comparisons = oldLines.length * newLines.length;
+        var maxComparisons = that.config.matchingMaxComparisons || 2500;
+        var doMatching = comparisons < maxComparisons && (that.config.matching === 'lines' ||
+          that.config.matching === 'words');
+
+        if (doMatching) {
+          matches = matcher(oldLines, newLines);
+          insertType = diffParser.LINE_TYPE.INSERT_CHANGES;
+          deleteType = diffParser.LINE_TYPE.DELETE_CHANGES;
+        } else {
+          matches = [[oldLines, newLines]];
+          insertType = diffParser.LINE_TYPE.INSERTS;
+          deleteType = diffParser.LINE_TYPE.DELETES;
+        }
+
+        matches.forEach(function(match) {
+          oldLines = match[0];
+          newLines = match[1];
+
+          var common = Math.min(oldLines.length, newLines.length);
+          var max = Math.max(oldLines.length, newLines.length);
+
+          for (var j = 0; j < common; j++) {
+            var oldLine = oldLines[j];
+            var newLine = newLines[j];
+
+            that.config.isCombined = file.isCombined;
+
+            var diff = printerUtils.diffHighlight(oldLine.content, newLine.content, that.config);
+
+            fileHtml.left +=
+              that.generateSingleLineHtml(file.isCombined, deleteType, oldLine.oldNumber,
+                diff.first.line, diff.first.prefix);
+            fileHtml.right +=
+              that.generateSingleLineHtml(file.isCombined, insertType, newLine.newNumber,
+                diff.second.line, diff.second.prefix);
+          }
+
+          if (max > common) {
+            var oldSlice = oldLines.slice(common);
+            var newSlice = newLines.slice(common);
+
+            var tmpHtml = that.processLines(file.isCombined, oldSlice, newSlice);
+            fileHtml.left += tmpHtml.left;
+            fileHtml.right += tmpHtml.right;
+          }
+        });
+
+        oldLines = [];
+        newLines = [];
+      }
+
+      for (var i = 0; i < block.lines.length; i++) {
+        var line = block.lines[i];
+        var prefix = line.content[0];
+        var escapedLine = utils.escape(line.content.substr(1));
+
+        if (line.type !== diffParser.LINE_TYPE.INSERTS &&
+          (newLines.length > 0 || (line.type !== diffParser.LINE_TYPE.DELETES && oldLines.length > 0))) {
+          processChangeBlock();
+        }
+
+        if (line.type === diffParser.LINE_TYPE.CONTEXT) {
+          fileHtml.left += that.generateSingleLineHtml(file.isCombined, line.type, line.oldNumber, escapedLine, prefix);
+          fileHtml.right += that.generateSingleLineHtml(file.isCombined, line.type, line.newNumber, escapedLine, prefix);
+        } else if (line.type === diffParser.LINE_TYPE.INSERTS && !oldLines.length) {
+          fileHtml.left += that.generateSingleLineHtml(file.isCombined, diffParser.LINE_TYPE.CONTEXT, '', '', '');
+          fileHtml.right += that.generateSingleLineHtml(file.isCombined, line.type, line.newNumber, escapedLine, prefix);
+        } else if (line.type === diffParser.LINE_TYPE.DELETES) {
+          oldLines.push(line);
+        } else if (line.type === diffParser.LINE_TYPE.INSERTS && Boolean(oldLines.length)) {
+          newLines.push(line);
+        } else {
+          console.error('unknown state in html side-by-side generator');
+          processChangeBlock();
+        }
+      }
+
+      processChangeBlock();
+    });
+
+    return fileHtml;
+  };
+
+  SideBySidePrinter.prototype.processLines = function(isCombined, oldLines, newLines) {
+    var that = this;
+    var fileHtml = {};
+    fileHtml.left = '';
+    fileHtml.right = '';
+
+    var maxLinesNumber = Math.max(oldLines.length, newLines.length);
+    for (var i = 0; i < maxLinesNumber; i++) {
+      var oldLine = oldLines[i];
+      var newLine = newLines[i];
+      var oldContent;
+      var newContent;
+      var oldPrefix;
+      var newPrefix;
+
+      if (oldLine) {
+        oldContent = utils.escape(oldLine.content.substr(1));
+        oldPrefix = oldLine.content[0];
+      }
+
+      if (newLine) {
+        newContent = utils.escape(newLine.content.substr(1));
+        newPrefix = newLine.content[0];
+      }
+
+      if (oldLine && newLine) {
+        fileHtml.left += that.generateSingleLineHtml(isCombined, oldLine.type, oldLine.oldNumber, oldContent, oldPrefix);
+        fileHtml.right += that.generateSingleLineHtml(isCombined, newLine.type, newLine.newNumber, newContent, newPrefix);
+      } else if (oldLine) {
+        fileHtml.left += that.generateSingleLineHtml(isCombined, oldLine.type, oldLine.oldNumber, oldContent, oldPrefix);
+        fileHtml.right += that.generateSingleLineHtml(isCombined, diffParser.LINE_TYPE.CONTEXT, '', '', '');
+      } else if (newLine) {
+        fileHtml.left += that.generateSingleLineHtml(isCombined, diffParser.LINE_TYPE.CONTEXT, '', '', '');
+        fileHtml.right += that.generateSingleLineHtml(isCombined, newLine.type, newLine.newNumber, newContent, newPrefix);
+      } else {
+        console.error('How did it get here?');
+      }
+    }
+
+    return fileHtml;
+  };
+
+  SideBySidePrinter.prototype.generateSingleLineHtml = function(isCombined, type, number, content, possiblePrefix) {
+    var lineWithoutPrefix = content;
+    var prefix = possiblePrefix;
+
+    if (!prefix) {
+      var lineWithPrefix = printerUtils.separatePrefix(isCombined, content);
+      prefix = lineWithPrefix.prefix;
+      lineWithoutPrefix = lineWithPrefix.line;
+    }
+
+    return hoganUtils.render(genericTemplatesPath, 'line',
+      {
+        type: type,
+        lineClass: 'd2h-code-side-linenumber',
+        contentClass: 'd2h-code-side-line',
+        prefix: prefix,
+        content: lineWithoutPrefix,
+        lineNumber: number
+      });
+  };
+
+  SideBySidePrinter.prototype.generateEmptyDiff = function() {
+    var fileHtml = {};
+    fileHtml.right = '';
+
+    fileHtml.left = hoganUtils.render(genericTemplatesPath, 'empty-diff', {
+      contentClass: 'd2h-code-side-line',
+      diffParser: diffParser
+    });
+
+    return fileHtml;
+  };
+
+  module.exports.SideBySidePrinter = SideBySidePrinter;
+})();
+
+},{"./diff-parser.js":104,"./hoganjs-utils.js":107,"./printer-utils.js":110,"./rematch.js":111,"./utils.js":114}],113:[function(require,module,exports){
+(function (global){
+(function() {
+if (!!!global.browserTemplates) global.browserTemplates = {};
+var Hogan = require("hogan.js");global.browserTemplates["file-summary-line"] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("<li class=\"d2h-file-list-line\">");t.b("\n" + i);t.b("    <span class=\"d2h-file-name-wrapper\">");t.b("\n" + i);t.b("      <span>");t.b(t.rp("<fileIcon0",c,p,""));t.b("</span>");t.b("\n" + i);t.b("      <a href=\"#");t.b(t.v(t.f("fileHtmlId",c,p,0)));t.b("\" class=\"d2h-file-name\">");t.b(t.v(t.f("fileName",c,p,0)));t.b("</a>");t.b("\n" + i);t.b("      <span class=\"d2h-file-stats\">");t.b("\n" + i);t.b("          <span class=\"d2h-lines-added\">");t.b(t.v(t.f("addedLines",c,p,0)));t.b("</span>");t.b("\n" + i);t.b("          <span class=\"d2h-lines-deleted\">");t.b(t.v(t.f("deletedLines",c,p,0)));t.b("</span>");t.b("\n" + i);t.b("      </span>");t.b("\n" + i);t.b("    </span>");t.b("\n" + i);t.b("</li>");return t.fl(); },partials: {"<fileIcon0":{name:"fileIcon", partials: {}, subs: {  }}}, subs: {  }});
+global.browserTemplates["file-summary-wrapper"] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("<div class=\"d2h-file-list-wrapper\">");t.b("\n" + i);t.b("    <div class=\"d2h-file-list-header\">");t.b("\n" + i);t.b("        <span class=\"d2h-file-list-title\">Files changed (");t.b(t.v(t.f("filesNumber",c,p,0)));t.b(")</span>");t.b("\n" + i);t.b("        <a class=\"d2h-file-switch d2h-hide\">hide</a>");t.b("\n" + i);t.b("        <a class=\"d2h-file-switch d2h-show\">show</a>");t.b("\n" + i);t.b("    </div>");t.b("\n" + i);t.b("    <ol class=\"d2h-file-list\">");t.b("\n" + i);t.b("    ");t.b(t.t(t.f("files",c,p,0)));t.b("\n" + i);t.b("    </ol>");t.b("\n" + i);t.b("</div>");return t.fl(); },partials: {}, subs: {  }});
+global.browserTemplates["generic-column-line-number"] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("<tr>");t.b("\n" + i);t.b("    <td class=\"");t.b(t.v(t.f("lineClass",c,p,0)));t.b(" ");t.b(t.v(t.d("diffParser.LINE_TYPE.INFO",c,p,0)));t.b("\"></td>");t.b("\n" + i);t.b("    <td class=\"");t.b(t.v(t.d("diffParser.LINE_TYPE.INFO",c,p,0)));t.b("\">");t.b("\n" + i);t.b("        <div class=\"");t.b(t.v(t.f("contentClass",c,p,0)));t.b(" ");t.b(t.v(t.d("diffParser.LINE_TYPE.INFO",c,p,0)));t.b("\">");t.b(t.t(t.f("blockHeader",c,p,0)));t.b("</div>");t.b("\n" + i);t.b("    </td>");t.b("\n" + i);t.b("</tr>");return t.fl(); },partials: {}, subs: {  }});
+global.browserTemplates["generic-empty-diff"] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("<tr>");t.b("\n" + i);t.b("    <td class=\"");t.b(t.v(t.d("diffParser.LINE_TYPE.INFO",c,p,0)));t.b("\">");t.b("\n" + i);t.b("        <div class=\"");t.b(t.v(t.f("contentClass",c,p,0)));t.b(" ");t.b(t.v(t.d("diffParser.LINE_TYPE.INFO",c,p,0)));t.b("\">");t.b("\n" + i);t.b("            File without changes");t.b("\n" + i);t.b("        </div>");t.b("\n" + i);t.b("    </td>");t.b("\n" + i);t.b("</tr>");return t.fl(); },partials: {}, subs: {  }});
+global.browserTemplates["generic-file-path"] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("<span class=\"d2h-file-name-wrapper\">");t.b("\n" + i);t.b("    <span class=\"d2h-icon-wrapper\">");t.b(t.rp("<fileIcon0",c,p,""));t.b("</span>");t.b("\n" + i);t.b("    <span class=\"d2h-file-name\">");t.b(t.v(t.f("fileDiffName",c,p,0)));t.b("</span>");t.b("\n" + i);t.b(t.rp("<fileTag1",c,p,"    "));t.b("</span>");return t.fl(); },partials: {"<fileIcon0":{name:"fileIcon", partials: {}, subs: {  }},"<fileTag1":{name:"fileTag", partials: {}, subs: {  }}}, subs: {  }});
+global.browserTemplates["generic-line"] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("<tr>");t.b("\n" + i);t.b("    <td class=\"");t.b(t.v(t.f("lineClass",c,p,0)));t.b(" ");t.b(t.v(t.f("type",c,p,0)));t.b("\">");t.b("\n" + i);t.b("      ");t.b(t.t(t.f("lineNumber",c,p,0)));t.b("\n" + i);t.b("    </td>");t.b("\n" + i);t.b("    <td class=\"");t.b(t.v(t.f("type",c,p,0)));t.b("\">");t.b("\n" + i);t.b("        <div class=\"");t.b(t.v(t.f("contentClass",c,p,0)));t.b(" ");t.b(t.v(t.f("type",c,p,0)));t.b("\">");t.b("\n" + i);if(t.s(t.f("prefix",c,p,1),c,p,0,171,247,"{{ }}")){t.rs(c,p,function(c,p,t){t.b("            <span class=\"d2h-code-line-prefix\">");t.b(t.t(t.f("prefix",c,p,0)));t.b("</span>");t.b("\n" + i);});c.pop();}if(t.s(t.f("content",c,p,1),c,p,0,279,353,"{{ }}")){t.rs(c,p,function(c,p,t){t.b("            <span class=\"d2h-code-line-ctn\">");t.b(t.t(t.f("content",c,p,0)));t.b("</span>");t.b("\n" + i);});c.pop();}t.b("        </div>");t.b("\n" + i);t.b("    </td>");t.b("\n" + i);t.b("</tr>");return t.fl(); },partials: {}, subs: {  }});
+global.browserTemplates["generic-wrapper"] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("<div class=\"d2h-wrapper\">");t.b("\n" + i);t.b("    ");t.b(t.t(t.f("content",c,p,0)));t.b("\n" + i);t.b("</div>");return t.fl(); },partials: {}, subs: {  }});
+global.browserTemplates["icon-file-added"] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("<svg aria-hidden=\"true\" class=\"d2h-icon d2h-added\" height=\"16\" title=\"added\" version=\"1.1\" viewBox=\"0 0 14 16\"");t.b("\n" + i);t.b("     width=\"14\">");t.b("\n" + i);t.b("    <path d=\"M13 1H1C0.45 1 0 1.45 0 2v12c0 0.55 0.45 1 1 1h12c0.55 0 1-0.45 1-1V2c0-0.55-0.45-1-1-1z m0 13H1V2h12v12zM6 9H3V7h3V4h2v3h3v2H8v3H6V9z\"></path>");t.b("\n" + i);t.b("</svg>");return t.fl(); },partials: {}, subs: {  }});
+global.browserTemplates["icon-file-changed"] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("<svg aria-hidden=\"true\" class=\"d2h-icon d2h-changed\" height=\"16\" title=\"modified\" version=\"1.1\"");t.b("\n" + i);t.b("     viewBox=\"0 0 14 16\" width=\"14\">");t.b("\n" + i);t.b("    <path d=\"M13 1H1C0.45 1 0 1.45 0 2v12c0 0.55 0.45 1 1 1h12c0.55 0 1-0.45 1-1V2c0-0.55-0.45-1-1-1z m0 13H1V2h12v12zM4 8c0-1.66 1.34-3 3-3s3 1.34 3 3-1.34 3-3 3-3-1.34-3-3z\"></path>");t.b("\n" + i);t.b("</svg>");return t.fl(); },partials: {}, subs: {  }});
+global.browserTemplates["icon-file-deleted"] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("<svg aria-hidden=\"true\" class=\"d2h-icon d2h-deleted\" height=\"16\" title=\"removed\" version=\"1.1\"");t.b("\n" + i);t.b("     viewBox=\"0 0 14 16\" width=\"14\">");t.b("\n" + i);t.b("    <path d=\"M13 1H1C0.45 1 0 1.45 0 2v12c0 0.55 0.45 1 1 1h12c0.55 0 1-0.45 1-1V2c0-0.55-0.45-1-1-1z m0 13H1V2h12v12zM11 9H3V7h8v2z\"></path>");t.b("\n" + i);t.b("</svg>");return t.fl(); },partials: {}, subs: {  }});
+global.browserTemplates["icon-file-renamed"] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("<svg aria-hidden=\"true\" class=\"d2h-icon d2h-moved\" height=\"16\" title=\"renamed\" version=\"1.1\"");t.b("\n" + i);t.b("     viewBox=\"0 0 14 16\" width=\"14\">");t.b("\n" + i);t.b("    <path d=\"M6 9H3V7h3V4l5 4-5 4V9z m8-7v12c0 0.55-0.45 1-1 1H1c-0.55 0-1-0.45-1-1V2c0-0.55 0.45-1 1-1h12c0.55 0 1 0.45 1 1z m-1 0H1v12h12V2z\"></path>");t.b("\n" + i);t.b("</svg>");return t.fl(); },partials: {}, subs: {  }});
+global.browserTemplates["icon-file"] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("<svg aria-hidden=\"true\" class=\"d2h-icon\" height=\"16\" version=\"1.1\" viewBox=\"0 0 12 16\" width=\"12\">");t.b("\n" + i);t.b("    <path d=\"M6 5H2v-1h4v1zM2 8h7v-1H2v1z m0 2h7v-1H2v1z m0 2h7v-1H2v1z m10-7.5v9.5c0 0.55-0.45 1-1 1H1c-0.55 0-1-0.45-1-1V2c0-0.55 0.45-1 1-1h7.5l3.5 3.5z m-1 0.5L8 2H1v12h10V5z\"></path>");t.b("\n" + i);t.b("</svg>");return t.fl(); },partials: {}, subs: {  }});
+global.browserTemplates["line-by-line-file-diff"] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("<div id=\"");t.b(t.v(t.f("fileHtmlId",c,p,0)));t.b("\" class=\"d2h-file-wrapper\" data-lang=\"");t.b(t.v(t.d("file.language",c,p,0)));t.b("\">");t.b("\n" + i);t.b("    <div class=\"d2h-file-header\">");t.b("\n" + i);t.b("    ");t.b(t.t(t.f("filePath",c,p,0)));t.b("\n" + i);t.b("    </div>");t.b("\n" + i);t.b("    <div class=\"d2h-file-diff\">");t.b("\n" + i);t.b("        <div class=\"d2h-code-wrapper\">");t.b("\n" + i);t.b("            <table class=\"d2h-diff-table\">");t.b("\n" + i);t.b("                <tbody class=\"d2h-diff-tbody\">");t.b("\n" + i);t.b("                ");t.b(t.t(t.f("diffs",c,p,0)));t.b("\n" + i);t.b("                </tbody>");t.b("\n" + i);t.b("            </table>");t.b("\n" + i);t.b("        </div>");t.b("\n" + i);t.b("    </div>");t.b("\n" + i);t.b("</div>");return t.fl(); },partials: {}, subs: {  }});
+global.browserTemplates["line-by-line-numbers"] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("<div class=\"line-num1\">");t.b(t.v(t.f("oldNumber",c,p,0)));t.b("</div>");t.b("\n" + i);t.b("<div class=\"line-num2\">");t.b(t.v(t.f("newNumber",c,p,0)));t.b("</div>");return t.fl(); },partials: {}, subs: {  }});
+global.browserTemplates["side-by-side-file-diff"] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("<div id=\"");t.b(t.v(t.f("fileHtmlId",c,p,0)));t.b("\" class=\"d2h-file-wrapper\" data-lang=\"");t.b(t.v(t.d("file.language",c,p,0)));t.b("\">");t.b("\n" + i);t.b("    <div class=\"d2h-file-header\">");t.b("\n" + i);t.b("      ");t.b(t.t(t.f("filePath",c,p,0)));t.b("\n" + i);t.b("    </div>");t.b("\n" + i);t.b("    <div class=\"d2h-files-diff\">");t.b("\n" + i);t.b("        <div class=\"d2h-file-side-diff\">");t.b("\n" + i);t.b("            <div class=\"d2h-code-wrapper\">");t.b("\n" + i);t.b("                <table class=\"d2h-diff-table\">");t.b("\n" + i);t.b("                    <tbody class=\"d2h-diff-tbody\">");t.b("\n" + i);t.b("                    ");t.b(t.t(t.d("diffs.left",c,p,0)));t.b("\n" + i);t.b("                    </tbody>");t.b("\n" + i);t.b("                </table>");t.b("\n" + i);t.b("            </div>");t.b("\n" + i);t.b("        </div>");t.b("\n" + i);t.b("        <div class=\"d2h-file-side-diff\">");t.b("\n" + i);t.b("            <div class=\"d2h-code-wrapper\">");t.b("\n" + i);t.b("                <table class=\"d2h-diff-table\">");t.b("\n" + i);t.b("                    <tbody class=\"d2h-diff-tbody\">");t.b("\n" + i);t.b("                    ");t.b(t.t(t.d("diffs.right",c,p,0)));t.b("\n" + i);t.b("                    </tbody>");t.b("\n" + i);t.b("                </table>");t.b("\n" + i);t.b("            </div>");t.b("\n" + i);t.b("        </div>");t.b("\n" + i);t.b("    </div>");t.b("\n" + i);t.b("</div>");return t.fl(); },partials: {}, subs: {  }});
+global.browserTemplates["tag-file-added"] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("<span class=\"d2h-tag d2h-added d2h-added-tag\">ADDED</span>");return t.fl(); },partials: {}, subs: {  }});
+global.browserTemplates["tag-file-changed"] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("<span class=\"d2h-tag d2h-changed d2h-changed-tag\">CHANGED</span>");return t.fl(); },partials: {}, subs: {  }});
+global.browserTemplates["tag-file-deleted"] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("<span class=\"d2h-tag d2h-deleted d2h-deleted-tag\">DELETED</span>");return t.fl(); },partials: {}, subs: {  }});
+global.browserTemplates["tag-file-renamed"] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("<span class=\"d2h-tag d2h-moved d2h-moved-tag\">RENAMED</span>");return t.fl(); },partials: {}, subs: {  }});
+module.exports = global.browserTemplates;
+})();
+
+}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+},{"hogan.js":4}],114:[function(require,module,exports){
+/*
+ *
+ * Utils (utils.js)
+ * Author: rtfpessoa
+ *
+ */
+
+(function() {
+  var merge = require('lodash/merge');
+
+  function Utils() {
+  }
+
+  Utils.prototype.escape = function(str) {
+    return str.slice(0)
+      .replace(/&/g, '&amp;')
+      .replace(/</g, '&lt;')
+      .replace(/>/g, '&gt;')
+      .replace(/"/g, '&quot;')
+      .replace(/'/g, '&#x27;')
+      .replace(/\//g, '&#x2F;')
+      .replace(/\t/g, '    ');
+  };
+
+  Utils.prototype.startsWith = function(str, start) {
+    if (typeof start === 'object') {
+      var result = false;
+      start.forEach(function(s) {
+        if (str.indexOf(s) === 0) {
+          result = true;
+        }
+      });
+
+      return result;
+    }
+
+    return str && str.indexOf(start) === 0;
+  };
+
+  Utils.prototype.valueOrEmpty = function(value) {
+    return value || '';
+  };
+
+  Utils.prototype.safeConfig = function(cfg, defaultConfig) {
+    var newCfg = {};
+    merge(newCfg, defaultConfig, cfg);
+    return newCfg;
+  };
+
+  module.exports.Utils = new Utils();
+})();
+
+},{"lodash/merge":99}]},{},[105]);
diff --git a/pagure/static/vendor/diff2html/diff2html.min.css b/pagure/static/vendor/diff2html/diff2html.min.css
new file mode 100644
index 0000000..a3dcea0
--- /dev/null
+++ b/pagure/static/vendor/diff2html/diff2html.min.css
@@ -0,0 +1 @@
+.d2h-wrapper{text-align:left}.d2h-file-header{padding:5px 10px;border-bottom:1px solid #d8d8d8;background-color:#f7f7f7}.d2h-file-stats{display:flex;margin-left:auto;font-size:14px}.d2h-lines-added{text-align:right;border:1px solid #b4e2b4;border-radius:5px 0 0 5px;color:#399839;padding:2px;vertical-align:middle}.d2h-lines-deleted{text-align:left;border:1px solid #e9aeae;border-radius:0 5px 5px 0;color:#c33;padding:2px;vertical-align:middle;margin-left:1px}.d2h-file-name-wrapper{display:flex;align-items:center;width:100%;font-family:"Source Sans Pro","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:15px}.d2h-file-name{white-space:nowrap;text-overflow:ellipsis;overflow-x:hidden;line-height:21px}.d2h-file-wrapper{border:1px solid #ddd;border-radius:3px;margin-bottom:1em}.d2h-diff-table{width:100%;border-collapse:collapse;font-family:Menlo,Consolas,monospace;font-size:13px}.d2h-diff-tbody>tr>td{height:20px;line-height:20px}.d2h-files-diff{display:block;width:100%;height:100%}.d2h-file-diff{overflow-x:scroll;overflow-y:hidden}.d2h-file-side-diff{display:inline-block;overflow-x:scroll;overflow-y:hidden;width:50%;margin-right:-4px;margin-bottom:-8px}.d2h-code-line{display:inline-block;white-space:nowrap;padding:0 10px;margin-left:80px}.d2h-code-side-line{display:inline-block;white-space:nowrap;padding:0 10px;margin-left:50px}.d2h-code-line del,.d2h-code-side-line del{display:inline-block;margin-top:-1px;text-decoration:none;background-color:#ffb6ba;border-radius:.2em}.d2h-code-line ins,.d2h-code-side-line ins{display:inline-block;margin-top:-1px;text-decoration:none;background-color:#97f295;border-radius:.2em;text-align:left}.d2h-code-line-prefix{display:inline;background:0 0;padding:0;word-wrap:normal;white-space:pre}.d2h-code-line-ctn{display:inline;background:0 0;padding:0;word-wrap:normal;white-space:pre}.line-num1{box-sizing:border-box;float:left;width:40px;overflow:hidden;text-overflow:ellipsis;padding-left:3px}.line-num2{box-sizing:border-box;float:right;width:40px;overflow:hidden;text-overflow:ellipsis;padding-left:3px}.d2h-code-linenumber{box-sizing:border-box;position:absolute;width:86px;padding-left:2px;padding-right:2px;background-color:#fff;color:rgba(0,0,0,.3);text-align:right;border:solid #eee;border-width:0 1px 0 1px;cursor:pointer}.d2h-code-side-linenumber{box-sizing:border-box;position:absolute;width:56px;padding-left:5px;padding-right:5px;background-color:#fff;color:rgba(0,0,0,.3);text-align:right;border:solid #eee;border-width:0 1px 0 1px;cursor:pointer;overflow:hidden;text-overflow:ellipsis}.d2h-del{background-color:#fee8e9;border-color:#e9aeae}.d2h-ins{background-color:#dfd;border-color:#b4e2b4}.d2h-info{background-color:#f8fafd;color:rgba(0,0,0,.3);border-color:#d5e4f2}.d2h-file-diff .d2h-del.d2h-change{background-color:#fdf2d0}.d2h-file-diff .d2h-ins.d2h-change{background-color:#ded}.d2h-file-list-wrapper{margin-bottom:10px}.d2h-file-list-wrapper a{text-decoration:none;color:#3572b0}.d2h-file-list-wrapper a:visited{color:#3572b0}.d2h-file-list-header{text-align:left}.d2h-file-list-title{font-weight:700}.d2h-file-list-line{display:flex;text-align:left}.d2h-file-list{display:block;list-style:none;padding:0;margin:0}.d2h-file-list>li{border-bottom:#ddd solid 1px;padding:5px 10px;margin:0}.d2h-file-list>li:last-child{border-bottom:none}.d2h-file-switch{display:none;font-size:10px;cursor:pointer}.d2h-icon-wrapper{line-height:31px}.d2h-icon{vertical-align:middle;margin-right:10px;fill:currentColor}.d2h-deleted{color:#c33}.d2h-added{color:#399839}.d2h-changed{color:#d0b44c}.d2h-moved{color:#3572b0}.d2h-tag{display:flex;font-size:10px;margin-left:5px;padding:0 2px;background-color:#fff}.d2h-deleted-tag{border:#c33 1px solid}.d2h-added-tag{border:#399839 1px solid}.d2h-changed-tag{border:#d0b44c 1px solid}.d2h-moved-tag{border:#3572b0 1px solid}.selecting-left .d2h-code-line,.selecting-left .d2h-code-line *,.selecting-left .d2h-code-side-line,.selecting-left .d2h-code-side-line *,.selecting-right td.d2h-code-linenumber,.selecting-right td.d2h-code-linenumber *,.selecting-right td.d2h-code-side-linenumber,.selecting-right td.d2h-code-side-linenumber *{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.selecting-left .d2h-code-line ::-moz-selection,.selecting-left .d2h-code-line::-moz-selection,.selecting-left .d2h-code-side-line ::-moz-selection,.selecting-left .d2h-code-side-line::-moz-selection,.selecting-right td.d2h-code-linenumber::-moz-selection,.selecting-right td.d2h-code-side-linenumber ::-moz-selection,.selecting-right td.d2h-code-side-linenumber::-moz-selection{background:0 0}.selecting-left .d2h-code-line ::selection,.selecting-left .d2h-code-line::selection,.selecting-left .d2h-code-side-line ::selection,.selecting-left .d2h-code-side-line::selection,.selecting-right td.d2h-code-linenumber::selection,.selecting-right td.d2h-code-side-linenumber ::selection,.selecting-right td.d2h-code-side-linenumber::selection{background:0 0}
\ No newline at end of file
diff --git a/pagure/static/vendor/diff2html/diff2html.min.js b/pagure/static/vendor/diff2html/diff2html.min.js
new file mode 100644
index 0000000..acf2da4
--- /dev/null
+++ b/pagure/static/vendor/diff2html/diff2html.min.js
@@ -0,0 +1 @@
+!function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a="function"==typeof require&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n||e)},l,l.exports,e,t,n,r)}return n[o].exports}for(var i="function"==typeof require&&require,o=0;o<r.length;o++)s(r[o]);return s}({1:[function(require,module,exports){},{}],2:[function(require,module,exports){var root,factory;root=this,factory=function(){return function(modules){var installedModules={};function __webpack_require__(moduleId){if(installedModules[moduleId])return installedModules[moduleId].exports;var module=installedModules[moduleId]={exports:{},id:moduleId,loaded:!1};return modules[moduleId].call(module.exports,module,module.exports,__webpack_require__),module.loaded=!0,module.exports}return __webpack_require__.m=modules,__webpack_require__.c=installedModules,__webpack_require__.p="",__webpack_require__(0)}([function(module,exports,__webpack_require__){"use strict";exports.__esModule=!0,exports.canonicalize=exports.convertChangesToXML=exports.convertChangesToDMP=exports.merge=exports.parsePatch=exports.applyPatches=exports.applyPatch=exports.createPatch=exports.createTwoFilesPatch=exports.structuredPatch=exports.diffArrays=exports.diffJson=exports.diffCss=exports.diffSentences=exports.diffTrimmedLines=exports.diffLines=exports.diffWordsWithSpace=exports.diffWords=exports.diffChars=exports.Diff=void 0;var obj,_base=__webpack_require__(1),_base2=(obj=_base)&&obj.__esModule?obj:{default:obj},_character=__webpack_require__(2),_word=__webpack_require__(3),_line=__webpack_require__(5),_sentence=__webpack_require__(6),_css=__webpack_require__(7),_json=__webpack_require__(8),_array=__webpack_require__(9),_apply=__webpack_require__(10),_parse=__webpack_require__(11),_merge=__webpack_require__(13),_create=__webpack_require__(14),_dmp=__webpack_require__(16),_xml=__webpack_require__(17);exports.Diff=_base2.default,exports.diffChars=_character.diffChars,exports.diffWords=_word.diffWords,exports.diffWordsWithSpace=_word.diffWordsWithSpace,exports.diffLines=_line.diffLines,exports.diffTrimmedLines=_line.diffTrimmedLines,exports.diffSentences=_sentence.diffSentences,exports.diffCss=_css.diffCss,exports.diffJson=_json.diffJson,exports.diffArrays=_array.diffArrays,exports.structuredPatch=_create.structuredPatch,exports.createTwoFilesPatch=_create.createTwoFilesPatch,exports.createPatch=_create.createPatch,exports.applyPatch=_apply.applyPatch,exports.applyPatches=_apply.applyPatches,exports.parsePatch=_parse.parsePatch,exports.merge=_merge.merge,exports.convertChangesToDMP=_dmp.convertChangesToDMP,exports.convertChangesToXML=_xml.convertChangesToXML,exports.canonicalize=_json.canonicalize},function(module,exports){"use strict";function Diff(){}function buildValues(diff,components,newString,oldString,useLongestToken){for(var componentPos=0,componentLen=components.length,newPos=0,oldPos=0;componentPos<componentLen;componentPos++){var component=components[componentPos];if(component.removed){if(component.value=diff.join(oldString.slice(oldPos,oldPos+component.count)),oldPos+=component.count,componentPos&&components[componentPos-1].added){var tmp=components[componentPos-1];components[componentPos-1]=components[componentPos],components[componentPos]=tmp}}else{if(!component.added&&useLongestToken){var value=newString.slice(newPos,newPos+component.count);value=value.map(function(value,i){var oldValue=oldString[oldPos+i];return oldValue.length>value.length?oldValue:value}),component.value=diff.join(value)}else component.value=diff.join(newString.slice(newPos,newPos+component.count));newPos+=component.count,component.added||(oldPos+=component.count)}}var lastComponent=components[componentLen-1];return 1<componentLen&&"string"==typeof lastComponent.value&&(lastComponent.added||lastComponent.removed)&&diff.equals("",lastComponent.value)&&(components[componentLen-2].value+=lastComponent.value,components.pop()),components}exports.__esModule=!0,(exports.default=Diff).prototype={diff:function(oldString,newString){var options=2<arguments.length&&void 0!==arguments[2]?arguments[2]:{},callback=options.callback;"function"==typeof options&&(callback=options,options={}),this.options=options;var self=this;function done(value){return callback?(setTimeout(function(){callback(void 0,value)},0),!0):value}oldString=this.castInput(oldString),newString=this.castInput(newString),oldString=this.removeEmpty(this.tokenize(oldString));var newLen=(newString=this.removeEmpty(this.tokenize(newString))).length,oldLen=oldString.length,editLength=1,maxEditLength=newLen+oldLen,bestPath=[{newPos:-1,components:[]}],oldPos=this.extractCommon(bestPath[0],newString,oldString,0);if(bestPath[0].newPos+1>=newLen&&oldLen<=oldPos+1)return done([{value:this.join(newString),count:newString.length}]);function execEditLength(){for(var diagonalPath=-1*editLength;diagonalPath<=editLength;diagonalPath+=2){var basePath=void 0,addPath=bestPath[diagonalPath-1],removePath=bestPath[diagonalPath+1],_oldPos=(removePath?removePath.newPos:0)-diagonalPath;addPath&&(bestPath[diagonalPath-1]=void 0);var canAdd=addPath&&addPath.newPos+1<newLen,canRemove=removePath&&0<=_oldPos&&_oldPos<oldLen;if(canAdd||canRemove){if(!canAdd||canRemove&&addPath.newPos<removePath.newPos?(basePath={newPos:(path=removePath).newPos,components:path.components.slice(0)},self.pushComponent(basePath.components,void 0,!0)):((basePath=addPath).newPos++,self.pushComponent(basePath.components,!0,void 0)),_oldPos=self.extractCommon(basePath,newString,oldString,diagonalPath),basePath.newPos+1>=newLen&&oldLen<=_oldPos+1)return done(buildValues(self,basePath.components,newString,oldString,self.useLongestToken));bestPath[diagonalPath]=basePath}else bestPath[diagonalPath]=void 0}var path;editLength++}if(callback)!function exec(){setTimeout(function(){if(maxEditLength<editLength)return callback();execEditLength()||exec()},0)}();else for(;editLength<=maxEditLength;){var ret=execEditLength();if(ret)return ret}},pushComponent:function(components,added,removed){var last=components[components.length-1];last&&last.added===added&&last.removed===removed?components[components.length-1]={count:last.count+1,added:added,removed:removed}:components.push({count:1,added:added,removed:removed})},extractCommon:function(basePath,newString,oldString,diagonalPath){for(var newLen=newString.length,oldLen=oldString.length,newPos=basePath.newPos,oldPos=newPos-diagonalPath,commonCount=0;newPos+1<newLen&&oldPos+1<oldLen&&this.equals(newString[newPos+1],oldString[oldPos+1]);)newPos++,oldPos++,commonCount++;return commonCount&&basePath.components.push({count:commonCount}),basePath.newPos=newPos,oldPos},equals:function(left,right){return this.options.comparator?this.options.comparator(left,right):left===right||this.options.ignoreCase&&left.toLowerCase()===right.toLowerCase()},removeEmpty:function(array){for(var ret=[],i=0;i<array.length;i++)array[i]&&ret.push(array[i]);return ret},castInput:function(value){return value},tokenize:function(value){return value.split("")},join:function(chars){return chars.join("")}}},function(module,exports,__webpack_require__){"use strict";exports.__esModule=!0,exports.characterDiff=void 0,exports.diffChars=function(oldStr,newStr,options){return characterDiff.diff(oldStr,newStr,options)};var obj,_base=__webpack_require__(1),_base2=(obj=_base)&&obj.__esModule?obj:{default:obj};var characterDiff=exports.characterDiff=new _base2.default},function(module,exports,__webpack_require__){"use strict";exports.__esModule=!0,exports.wordDiff=void 0,exports.diffWords=function(oldStr,newStr,options){return options=(0,_params.generateOptions)(options,{ignoreWhitespace:!0}),wordDiff.diff(oldStr,newStr,options)},exports.diffWordsWithSpace=function(oldStr,newStr,options){return wordDiff.diff(oldStr,newStr,options)};var obj,_base=__webpack_require__(1),_base2=(obj=_base)&&obj.__esModule?obj:{default:obj},_params=__webpack_require__(4);var extendedWordChars=/^[A-Za-z\xC0-\u02C6\u02C8-\u02D7\u02DE-\u02FF\u1E00-\u1EFF]+$/,reWhitespace=/\S/,wordDiff=exports.wordDiff=new _base2.default;wordDiff.equals=function(left,right){return this.options.ignoreCase&&(left=left.toLowerCase(),right=right.toLowerCase()),left===right||this.options.ignoreWhitespace&&!reWhitespace.test(left)&&!reWhitespace.test(right)},wordDiff.tokenize=function(value){for(var tokens=value.split(/(\s+|\b)/),i=0;i<tokens.length-1;i++)!tokens[i+1]&&tokens[i+2]&&extendedWordChars.test(tokens[i])&&extendedWordChars.test(tokens[i+2])&&(tokens[i]+=tokens[i+2],tokens.splice(i+1,2),i--);return tokens}},function(module,exports){"use strict";exports.__esModule=!0,exports.generateOptions=function(options,defaults){if("function"==typeof options)defaults.callback=options;else if(options)for(var name in options)options.hasOwnProperty(name)&&(defaults[name]=options[name]);return defaults}},function(module,exports,__webpack_require__){"use strict";exports.__esModule=!0,exports.lineDiff=void 0,exports.diffLines=function(oldStr,newStr,callback){return lineDiff.diff(oldStr,newStr,callback)},exports.diffTrimmedLines=function(oldStr,newStr,callback){var options=(0,_params.generateOptions)(callback,{ignoreWhitespace:!0});return lineDiff.diff(oldStr,newStr,options)};var obj,_base=__webpack_require__(1),_base2=(obj=_base)&&obj.__esModule?obj:{default:obj},_params=__webpack_require__(4);var lineDiff=exports.lineDiff=new _base2.default;lineDiff.tokenize=function(value){var retLines=[],linesAndNewlines=value.split(/(\n|\r\n)/);linesAndNewlines[linesAndNewlines.length-1]||linesAndNewlines.pop();for(var i=0;i<linesAndNewlines.length;i++){var line=linesAndNewlines[i];i%2&&!this.options.newlineIsToken?retLines[retLines.length-1]+=line:(this.options.ignoreWhitespace&&(line=line.trim()),retLines.push(line))}return retLines}},function(module,exports,__webpack_require__){"use strict";exports.__esModule=!0,exports.sentenceDiff=void 0,exports.diffSentences=function(oldStr,newStr,callback){return sentenceDiff.diff(oldStr,newStr,callback)};var obj,_base=__webpack_require__(1),_base2=(obj=_base)&&obj.__esModule?obj:{default:obj};var sentenceDiff=exports.sentenceDiff=new _base2.default;sentenceDiff.tokenize=function(value){return value.split(/(\S.+?[.!?])(?=\s+|$)/)}},function(module,exports,__webpack_require__){"use strict";exports.__esModule=!0,exports.cssDiff=void 0,exports.diffCss=function(oldStr,newStr,callback){return cssDiff.diff(oldStr,newStr,callback)};var obj,_base=__webpack_require__(1),_base2=(obj=_base)&&obj.__esModule?obj:{default:obj};var cssDiff=exports.cssDiff=new _base2.default;cssDiff.tokenize=function(value){return value.split(/([{}:;,]|\s+)/)}},function(module,exports,__webpack_require__){"use strict";exports.__esModule=!0,exports.jsonDiff=void 0;var _typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(obj){return typeof obj}:function(obj){return obj&&"function"==typeof Symbol&&obj.constructor===Symbol&&obj!==Symbol.prototype?"symbol":typeof obj};exports.diffJson=function(oldObj,newObj,options){return jsonDiff.diff(oldObj,newObj,options)},exports.canonicalize=canonicalize;var obj,_base=__webpack_require__(1),_base2=(obj=_base)&&obj.__esModule?obj:{default:obj},_line=__webpack_require__(5);var objectPrototypeToString=Object.prototype.toString,jsonDiff=exports.jsonDiff=new _base2.default;function canonicalize(obj,stack,replacementStack,replacer,key){stack=stack||[],replacementStack=replacementStack||[],replacer&&(obj=replacer(key,obj));var i=void 0;for(i=0;i<stack.length;i+=1)if(stack[i]===obj)return replacementStack[i];var canonicalizedObj=void 0;if("[object Array]"===objectPrototypeToString.call(obj)){for(stack.push(obj),canonicalizedObj=new Array(obj.length),replacementStack.push(canonicalizedObj),i=0;i<obj.length;i+=1)canonicalizedObj[i]=canonicalize(obj[i],stack,replacementStack,replacer,key);return stack.pop(),replacementStack.pop(),canonicalizedObj}if(obj&&obj.toJSON&&(obj=obj.toJSON()),"object"===(void 0===obj?"undefined":_typeof(obj))&&null!==obj){stack.push(obj),canonicalizedObj={},replacementStack.push(canonicalizedObj);var sortedKeys=[],_key=void 0;for(_key in obj)obj.hasOwnProperty(_key)&&sortedKeys.push(_key);for(sortedKeys.sort(),i=0;i<sortedKeys.length;i+=1)canonicalizedObj[_key=sortedKeys[i]]=canonicalize(obj[_key],stack,replacementStack,replacer,_key);stack.pop(),replacementStack.pop()}else canonicalizedObj=obj;return canonicalizedObj}jsonDiff.useLongestToken=!0,jsonDiff.tokenize=_line.lineDiff.tokenize,jsonDiff.castInput=function(value){var _options=this.options,undefinedReplacement=_options.undefinedReplacement,_options$stringifyRep=_options.stringifyReplacer,stringifyReplacer=void 0===_options$stringifyRep?function(k,v){return void 0===v?undefinedReplacement:v}:_options$stringifyRep;return"string"==typeof value?value:JSON.stringify(canonicalize(value,null,null,stringifyReplacer),stringifyReplacer,"  ")},jsonDiff.equals=function(left,right){return _base2.default.prototype.equals.call(jsonDiff,left.replace(/,([\r\n])/g,"$1"),right.replace(/,([\r\n])/g,"$1"))}},function(module,exports,__webpack_require__){"use strict";exports.__esModule=!0,exports.arrayDiff=void 0,exports.diffArrays=function(oldArr,newArr,callback){return arrayDiff.diff(oldArr,newArr,callback)};var obj,_base=__webpack_require__(1),_base2=(obj=_base)&&obj.__esModule?obj:{default:obj};var arrayDiff=exports.arrayDiff=new _base2.default;arrayDiff.tokenize=function(value){return value.slice()},arrayDiff.join=arrayDiff.removeEmpty=function(value){return value}},function(module,exports,__webpack_require__){"use strict";exports.__esModule=!0,exports.applyPatch=applyPatch,exports.applyPatches=function(uniDiff,options){"string"==typeof uniDiff&&(uniDiff=(0,_parse.parsePatch)(uniDiff));var currentIndex=0;!function processIndex(){var index=uniDiff[currentIndex++];if(!index)return options.complete();options.loadFile(index,function(err,data){if(err)return options.complete(err);var updatedContent=applyPatch(data,index,options);options.patched(index,updatedContent,function(err){if(err)return options.complete(err);processIndex()})})}()};var obj,_parse=__webpack_require__(11),_distanceIterator=__webpack_require__(12),_distanceIterator2=(obj=_distanceIterator)&&obj.__esModule?obj:{default:obj};function applyPatch(source,uniDiff){var options=2<arguments.length&&void 0!==arguments[2]?arguments[2]:{};if("string"==typeof uniDiff&&(uniDiff=(0,_parse.parsePatch)(uniDiff)),Array.isArray(uniDiff)){if(1<uniDiff.length)throw new Error("applyPatch only works with a single input.");uniDiff=uniDiff[0]}var lines=source.split(/\r\n|[\n\v\f\r\x85]/),delimiters=source.match(/\r\n|[\n\v\f\r\x85]/g)||[],hunks=uniDiff.hunks,compareLine=options.compareLine||function(lineNumber,line,operation,patchContent){return line===patchContent},errorCount=0,fuzzFactor=options.fuzzFactor||0,minLine=0,offset=0,removeEOFNL=void 0,addEOFNL=void 0;function hunkFits(hunk,toPos){for(var j=0;j<hunk.lines.length;j++){var line=hunk.lines[j],operation=0<line.length?line[0]:" ",content=0<line.length?line.substr(1):line;if(" "===operation||"-"===operation){if(!compareLine(toPos+1,lines[toPos],operation,content)&&fuzzFactor<++errorCount)return!1;toPos++}}return!0}for(var i=0;i<hunks.length;i++){for(var hunk=hunks[i],maxLine=lines.length-hunk.oldLines,localOffset=0,toPos=offset+hunk.oldStart-1,iterator=(0,_distanceIterator2.default)(toPos,minLine,maxLine);void 0!==localOffset;localOffset=iterator())if(hunkFits(hunk,toPos+localOffset)){hunk.offset=offset+=localOffset;break}if(void 0===localOffset)return!1;minLine=hunk.offset+hunk.oldStart+hunk.oldLines}for(var diffOffset=0,_i=0;_i<hunks.length;_i++){var _hunk=hunks[_i],_toPos=_hunk.oldStart+_hunk.offset+diffOffset-1;diffOffset+=_hunk.newLines-_hunk.oldLines,_toPos<0&&(_toPos=0);for(var j=0;j<_hunk.lines.length;j++){var line=_hunk.lines[j],operation=0<line.length?line[0]:" ",content=0<line.length?line.substr(1):line,delimiter=_hunk.linedelimiters[j];if(" "===operation)_toPos++;else if("-"===operation)lines.splice(_toPos,1),delimiters.splice(_toPos,1);else if("+"===operation)lines.splice(_toPos,0,content),delimiters.splice(_toPos,0,delimiter),_toPos++;else if("\\"===operation){var previousOperation=_hunk.lines[j-1]?_hunk.lines[j-1][0]:null;"+"===previousOperation?removeEOFNL=!0:"-"===previousOperation&&(addEOFNL=!0)}}}if(removeEOFNL)for(;!lines[lines.length-1];)lines.pop(),delimiters.pop();else addEOFNL&&(lines.push(""),delimiters.push("\n"));for(var _k=0;_k<lines.length-1;_k++)lines[_k]=lines[_k]+delimiters[_k];return lines.join("")}},function(module,exports){"use strict";exports.__esModule=!0,exports.parsePatch=function(uniDiff){var options=1<arguments.length&&void 0!==arguments[1]?arguments[1]:{},diffstr=uniDiff.split(/\r\n|[\n\v\f\r\x85]/),delimiters=uniDiff.match(/\r\n|[\n\v\f\r\x85]/g)||[],list=[],i=0;function parseIndex(){var index={};for(list.push(index);i<diffstr.length;){var line=diffstr[i];if(/^(\-\-\-|\+\+\+|@@)\s/.test(line))break;var header=/^(?:Index:|diff(?: -r \w+)+)\s+(.+?)\s*$/.exec(line);header&&(index.index=header[1]),i++}for(parseFileHeader(index),parseFileHeader(index),index.hunks=[];i<diffstr.length;){var _line=diffstr[i];if(/^(Index:|diff|\-\-\-|\+\+\+)\s/.test(_line))break;if(/^@@/.test(_line))index.hunks.push(parseHunk());else{if(_line&&options.strict)throw new Error("Unknown line "+(i+1)+" "+JSON.stringify(_line));i++}}}function parseFileHeader(index){var fileHeader=/^(---|\+\+\+)\s+(.*)$/.exec(diffstr[i]);if(fileHeader){var keyPrefix="---"===fileHeader[1]?"old":"new",data=fileHeader[2].split("\t",2),fileName=data[0].replace(/\\\\/g,"\\");/^".*"$/.test(fileName)&&(fileName=fileName.substr(1,fileName.length-2)),index[keyPrefix+"FileName"]=fileName,index[keyPrefix+"Header"]=(data[1]||"").trim(),i++}}function parseHunk(){for(var chunkHeaderIndex=i,chunkHeaderLine=diffstr[i++],chunkHeader=chunkHeaderLine.split(/@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@/),hunk={oldStart:+chunkHeader[1],oldLines:+chunkHeader[2]||1,newStart:+chunkHeader[3],newLines:+chunkHeader[4]||1,lines:[],linedelimiters:[]},addCount=0,removeCount=0;i<diffstr.length&&!(0===diffstr[i].indexOf("--- ")&&i+2<diffstr.length&&0===diffstr[i+1].indexOf("+++ ")&&0===diffstr[i+2].indexOf("@@"));i++){var operation=0==diffstr[i].length&&i!=diffstr.length-1?" ":diffstr[i][0];if("+"!==operation&&"-"!==operation&&" "!==operation&&"\\"!==operation)break;hunk.lines.push(diffstr[i]),hunk.linedelimiters.push(delimiters[i]||"\n"),"+"===operation?addCount++:"-"===operation?removeCount++:" "===operation&&(addCount++,removeCount++)}if(addCount||1!==hunk.newLines||(hunk.newLines=0),removeCount||1!==hunk.oldLines||(hunk.oldLines=0),options.strict){if(addCount!==hunk.newLines)throw new Error("Added line count did not match for hunk at line "+(chunkHeaderIndex+1));if(removeCount!==hunk.oldLines)throw new Error("Removed line count did not match for hunk at line "+(chunkHeaderIndex+1))}return hunk}for(;i<diffstr.length;)parseIndex();return list}},function(module,exports){"use strict";exports.__esModule=!0,exports.default=function(start,minLine,maxLine){var wantForward=!0,backwardExhausted=!1,forwardExhausted=!1,localOffset=1;return function iterator(){if(wantForward&&!forwardExhausted){if(backwardExhausted?localOffset++:wantForward=!1,start+localOffset<=maxLine)return localOffset;forwardExhausted=!0}if(!backwardExhausted)return forwardExhausted||(wantForward=!0),minLine<=start-localOffset?-localOffset++:(backwardExhausted=!0,iterator())}}},function(module,exports,__webpack_require__){"use strict";exports.__esModule=!0,exports.calcLineCount=calcLineCount,exports.merge=function(mine,theirs,base){mine=loadPatch(mine,base),theirs=loadPatch(theirs,base);var ret={};(mine.index||theirs.index)&&(ret.index=mine.index||theirs.index);(mine.newFileName||theirs.newFileName)&&(fileNameChanged(mine)?fileNameChanged(theirs)?(ret.oldFileName=selectField(ret,mine.oldFileName,theirs.oldFileName),ret.newFileName=selectField(ret,mine.newFileName,theirs.newFileName),ret.oldHeader=selectField(ret,mine.oldHeader,theirs.oldHeader),ret.newHeader=selectField(ret,mine.newHeader,theirs.newHeader)):(ret.oldFileName=mine.oldFileName,ret.newFileName=mine.newFileName,ret.oldHeader=mine.oldHeader,ret.newHeader=mine.newHeader):(ret.oldFileName=theirs.oldFileName||mine.oldFileName,ret.newFileName=theirs.newFileName||mine.newFileName,ret.oldHeader=theirs.oldHeader||mine.oldHeader,ret.newHeader=theirs.newHeader||mine.newHeader));ret.hunks=[];var mineIndex=0,theirsIndex=0,mineOffset=0,theirsOffset=0;for(;mineIndex<mine.hunks.length||theirsIndex<theirs.hunks.length;){var mineCurrent=mine.hunks[mineIndex]||{oldStart:1/0},theirsCurrent=theirs.hunks[theirsIndex]||{oldStart:1/0};if(hunkBefore(mineCurrent,theirsCurrent))ret.hunks.push(cloneHunk(mineCurrent,mineOffset)),mineIndex++,theirsOffset+=mineCurrent.newLines-mineCurrent.oldLines;else if(hunkBefore(theirsCurrent,mineCurrent))ret.hunks.push(cloneHunk(theirsCurrent,theirsOffset)),theirsIndex++,mineOffset+=theirsCurrent.newLines-theirsCurrent.oldLines;else{var mergedHunk={oldStart:Math.min(mineCurrent.oldStart,theirsCurrent.oldStart),oldLines:0,newStart:Math.min(mineCurrent.newStart+mineOffset,theirsCurrent.oldStart+theirsOffset),newLines:0,lines:[]};mergeLines(mergedHunk,mineCurrent.oldStart,mineCurrent.lines,theirsCurrent.oldStart,theirsCurrent.lines),theirsIndex++,mineIndex++,ret.hunks.push(mergedHunk)}}return ret};var _create=__webpack_require__(14),_parse=__webpack_require__(11),_array=__webpack_require__(15);function _toConsumableArray(arr){if(Array.isArray(arr)){for(var i=0,arr2=Array(arr.length);i<arr.length;i++)arr2[i]=arr[i];return arr2}return Array.from(arr)}function calcLineCount(hunk){var _calcOldNewLineCount=function calcOldNewLineCount(lines){var oldLines=0;var newLines=0;lines.forEach(function(line){if("string"!=typeof line){var myCount=calcOldNewLineCount(line.mine),theirCount=calcOldNewLineCount(line.theirs);void 0!==oldLines&&(myCount.oldLines===theirCount.oldLines?oldLines+=myCount.oldLines:oldLines=void 0),void 0!==newLines&&(myCount.newLines===theirCount.newLines?newLines+=myCount.newLines:newLines=void 0)}else void 0===newLines||"+"!==line[0]&&" "!==line[0]||newLines++,void 0===oldLines||"-"!==line[0]&&" "!==line[0]||oldLines++});return{oldLines:oldLines,newLines:newLines}}(hunk.lines),oldLines=_calcOldNewLineCount.oldLines,newLines=_calcOldNewLineCount.newLines;void 0!==oldLines?hunk.oldLines=oldLines:delete hunk.oldLines,void 0!==newLines?hunk.newLines=newLines:delete hunk.newLines}function loadPatch(param,base){if("string"==typeof param){if(/^@@/m.test(param)||/^Index:/m.test(param))return(0,_parse.parsePatch)(param)[0];if(!base)throw new Error("Must provide a base reference or pass in a patch");return(0,_create.structuredPatch)(void 0,void 0,base,param)}return param}function fileNameChanged(patch){return patch.newFileName&&patch.newFileName!==patch.oldFileName}function selectField(index,mine,theirs){return mine===theirs?mine:(index.conflict=!0,{mine:mine,theirs:theirs})}function hunkBefore(test,check){return test.oldStart<check.oldStart&&test.oldStart+test.oldLines<check.oldStart}function cloneHunk(hunk,offset){return{oldStart:hunk.oldStart,oldLines:hunk.oldLines,newStart:hunk.newStart+offset,newLines:hunk.newLines,lines:hunk.lines}}function mergeLines(hunk,mineOffset,mineLines,theirOffset,theirLines){var mine={offset:mineOffset,lines:mineLines,index:0},their={offset:theirOffset,lines:theirLines,index:0};for(insertLeading(hunk,mine,their),insertLeading(hunk,their,mine);mine.index<mine.lines.length&&their.index<their.lines.length;){var mineCurrent=mine.lines[mine.index],theirCurrent=their.lines[their.index];if("-"!==mineCurrent[0]&&"+"!==mineCurrent[0]||"-"!==theirCurrent[0]&&"+"!==theirCurrent[0])if("+"===mineCurrent[0]&&" "===theirCurrent[0]){var _hunk$lines;(_hunk$lines=hunk.lines).push.apply(_hunk$lines,_toConsumableArray(collectChange(mine)))}else if("+"===theirCurrent[0]&&" "===mineCurrent[0]){var _hunk$lines2;(_hunk$lines2=hunk.lines).push.apply(_hunk$lines2,_toConsumableArray(collectChange(their)))}else"-"===mineCurrent[0]&&" "===theirCurrent[0]?removal(hunk,mine,their):"-"===theirCurrent[0]&&" "===mineCurrent[0]?removal(hunk,their,mine,!0):mineCurrent===theirCurrent?(hunk.lines.push(mineCurrent),mine.index++,their.index++):conflict(hunk,collectChange(mine),collectChange(their));else mutualChange(hunk,mine,their)}insertTrailing(hunk,mine),insertTrailing(hunk,their),calcLineCount(hunk)}function mutualChange(hunk,mine,their){var myChanges=collectChange(mine),theirChanges=collectChange(their);if(allRemoves(myChanges)&&allRemoves(theirChanges)){var _hunk$lines3,_hunk$lines4;if((0,_array.arrayStartsWith)(myChanges,theirChanges)&&skipRemoveSuperset(their,myChanges,myChanges.length-theirChanges.length))return void(_hunk$lines3=hunk.lines).push.apply(_hunk$lines3,_toConsumableArray(myChanges));if((0,_array.arrayStartsWith)(theirChanges,myChanges)&&skipRemoveSuperset(mine,theirChanges,theirChanges.length-myChanges.length))return void(_hunk$lines4=hunk.lines).push.apply(_hunk$lines4,_toConsumableArray(theirChanges))}else if((0,_array.arrayEqual)(myChanges,theirChanges)){var _hunk$lines5;return void(_hunk$lines5=hunk.lines).push.apply(_hunk$lines5,_toConsumableArray(myChanges))}conflict(hunk,myChanges,theirChanges)}function removal(hunk,mine,their,swap){var _hunk$lines6,myChanges=collectChange(mine),theirChanges=function(state,matchChanges){var changes=[],merged=[],matchIndex=0,contextChanges=!1,conflicted=!1;for(;matchIndex<matchChanges.length&&state.index<state.lines.length;){var change=state.lines[state.index],match=matchChanges[matchIndex];if("+"===match[0])break;if(contextChanges=contextChanges||" "!==change[0],merged.push(match),matchIndex++,"+"===change[0])for(conflicted=!0;"+"===change[0];)changes.push(change),change=state.lines[++state.index];match.substr(1)===change.substr(1)?(changes.push(change),state.index++):conflicted=!0}"+"===(matchChanges[matchIndex]||"")[0]&&contextChanges&&(conflicted=!0);if(conflicted)return changes;for(;matchIndex<matchChanges.length;)merged.push(matchChanges[matchIndex++]);return{merged:merged,changes:changes}}(their,myChanges);theirChanges.merged?(_hunk$lines6=hunk.lines).push.apply(_hunk$lines6,_toConsumableArray(theirChanges.merged)):conflict(hunk,swap?theirChanges:myChanges,swap?myChanges:theirChanges)}function conflict(hunk,mine,their){hunk.conflict=!0,hunk.lines.push({conflict:!0,mine:mine,theirs:their})}function insertLeading(hunk,insert,their){for(;insert.offset<their.offset&&insert.index<insert.lines.length;){var line=insert.lines[insert.index++];hunk.lines.push(line),insert.offset++}}function insertTrailing(hunk,insert){for(;insert.index<insert.lines.length;){var line=insert.lines[insert.index++];hunk.lines.push(line)}}function collectChange(state){for(var ret=[],operation=state.lines[state.index][0];state.index<state.lines.length;){var line=state.lines[state.index];if("-"===operation&&"+"===line[0]&&(operation="+"),operation!==line[0])break;ret.push(line),state.index++}return ret}function allRemoves(changes){return changes.reduce(function(prev,change){return prev&&"-"===change[0]},!0)}function skipRemoveSuperset(state,removeChanges,delta){for(var i=0;i<delta;i++){var changeContent=removeChanges[removeChanges.length-delta+i].substr(1);if(state.lines[state.index+i]!==" "+changeContent)return!1}return state.index+=delta,!0}},function(module,exports,__webpack_require__){"use strict";exports.__esModule=!0,exports.structuredPatch=structuredPatch,exports.createTwoFilesPatch=createTwoFilesPatch,exports.createPatch=function(fileName,oldStr,newStr,oldHeader,newHeader,options){return createTwoFilesPatch(fileName,fileName,oldStr,newStr,oldHeader,newHeader,options)};var _line=__webpack_require__(5);function _toConsumableArray(arr){if(Array.isArray(arr)){for(var i=0,arr2=Array(arr.length);i<arr.length;i++)arr2[i]=arr[i];return arr2}return Array.from(arr)}function structuredPatch(oldFileName,newFileName,oldStr,newStr,oldHeader,newHeader,options){options||(options={}),void 0===options.context&&(options.context=4);var diff=(0,_line.diffLines)(oldStr,newStr,options);function contextLines(lines){return lines.map(function(entry){return" "+entry})}diff.push({value:"",lines:[]});for(var hunks=[],oldRangeStart=0,newRangeStart=0,curRange=[],oldLine=1,newLine=1,_loop=function(i){var current=diff[i],lines=current.lines||current.value.replace(/\n$/,"").split("\n");if(current.lines=lines,current.added||current.removed){var _curRange;if(!oldRangeStart){var prev=diff[i-1];oldRangeStart=oldLine,newRangeStart=newLine,prev&&(curRange=0<options.context?contextLines(prev.lines.slice(-options.context)):[],oldRangeStart-=curRange.length,newRangeStart-=curRange.length)}(_curRange=curRange).push.apply(_curRange,_toConsumableArray(lines.map(function(entry){return(current.added?"+":"-")+entry}))),current.added?newLine+=lines.length:oldLine+=lines.length}else{if(oldRangeStart)if(lines.length<=2*options.context&&i<diff.length-2){var _curRange2;(_curRange2=curRange).push.apply(_curRange2,_toConsumableArray(contextLines(lines)))}else{var _curRange3,contextSize=Math.min(lines.length,options.context);(_curRange3=curRange).push.apply(_curRange3,_toConsumableArray(contextLines(lines.slice(0,contextSize))));var hunk={oldStart:oldRangeStart,oldLines:oldLine-oldRangeStart+contextSize,newStart:newRangeStart,newLines:newLine-newRangeStart+contextSize,lines:curRange};if(i>=diff.length-2&&lines.length<=options.context){var oldEOFNewline=/\n$/.test(oldStr),newEOFNewline=/\n$/.test(newStr);0!=lines.length||oldEOFNewline?oldEOFNewline&&newEOFNewline||curRange.push("\\ No newline at end of file"):curRange.splice(hunk.oldLines,0,"\\ No newline at end of file")}hunks.push(hunk),newRangeStart=oldRangeStart=0,curRange=[]}oldLine+=lines.length,newLine+=lines.length}},i=0;i<diff.length;i++)_loop(i);return{oldFileName:oldFileName,newFileName:newFileName,oldHeader:oldHeader,newHeader:newHeader,hunks:hunks}}function createTwoFilesPatch(oldFileName,newFileName,oldStr,newStr,oldHeader,newHeader,options){var diff=structuredPatch(oldFileName,newFileName,oldStr,newStr,oldHeader,newHeader,options),ret=[];oldFileName==newFileName&&ret.push("Index: "+oldFileName),ret.push("==================================================================="),ret.push("--- "+diff.oldFileName+(void 0===diff.oldHeader?"":"\t"+diff.oldHeader)),ret.push("+++ "+diff.newFileName+(void 0===diff.newHeader?"":"\t"+diff.newHeader));for(var i=0;i<diff.hunks.length;i++){var hunk=diff.hunks[i];ret.push("@@ -"+hunk.oldStart+","+hunk.oldLines+" +"+hunk.newStart+","+hunk.newLines+" @@"),ret.push.apply(ret,hunk.lines)}return ret.join("\n")+"\n"}},function(module,exports){"use strict";function arrayStartsWith(array,start){if(start.length>array.length)return!1;for(var i=0;i<start.length;i++)if(start[i]!==array[i])return!1;return!0}exports.__esModule=!0,exports.arrayEqual=function(a,b){if(a.length!==b.length)return!1;return arrayStartsWith(a,b)},exports.arrayStartsWith=arrayStartsWith},function(module,exports){"use strict";exports.__esModule=!0,exports.convertChangesToDMP=function(changes){for(var ret=[],change=void 0,operation=void 0,i=0;i<changes.length;i++)change=changes[i],operation=change.added?1:change.removed?-1:0,ret.push([operation,change.value]);return ret}},function(module,exports){"use strict";function escapeHTML(s){var n=s;return n=(n=(n=(n=n.replace(/&/g,"&amp;")).replace(/</g,"&lt;")).replace(/>/g,"&gt;")).replace(/"/g,"&quot;")}exports.__esModule=!0,exports.convertChangesToXML=function(changes){for(var ret=[],i=0;i<changes.length;i++){var change=changes[i];change.added?ret.push("<ins>"):change.removed&&ret.push("<del>"),ret.push(escapeHTML(change.value)),change.added?ret.push("</ins>"):change.removed&&ret.push("</del>")}return ret.join("")}}])},"object"==typeof exports&&"object"==typeof module?module.exports=factory():"function"==typeof define&&define.amd?define([],factory):"object"==typeof exports?exports.JsDiff=factory():root.JsDiff=factory()},{}],3:[function(require,module,exports){!function(Hogan){var rIsWhitespace=/\S/,rQuot=/\"/g,rNewline=/\n/g,rCr=/\r/g,rSlash=/\\/g,rLineSep=/\u2028/,rParagraphSep=/\u2029/;function cleanTripleStache(token){"}"===token.n.substr(token.n.length-1)&&(token.n=token.n.substring(0,token.n.length-1))}function trim(s){return s.trim?s.trim():s.replace(/^\s*|\s*$/g,"")}function tagChange(tag,text,index){if(text.charAt(index)!=tag.charAt(0))return!1;for(var i=1,l=tag.length;i<l;i++)if(text.charAt(index+i)!=tag.charAt(i))return!1;return!0}Hogan.tags={"#":1,"^":2,"<":3,$:4,"/":5,"!":6,">":7,"=":8,_v:9,"{":10,"&":11,_t:12},Hogan.scan=function(text,delimiters){var len=text.length,state=0,tagType=null,tag=null,buf="",tokens=[],seenTag=!1,i=0,lineStart=0,otag="{{",ctag="}}";function addBuf(){0<buf.length&&(tokens.push({tag:"_t",text:new String(buf)}),buf="")}function filterLine(haveSeenTag,noNewLine){if(addBuf(),haveSeenTag&&function(){for(var isAllWhitespace=!0,j=lineStart;j<tokens.length;j++)if(!(isAllWhitespace=Hogan.tags[tokens[j].tag]<Hogan.tags._v||"_t"==tokens[j].tag&&null===tokens[j].text.match(rIsWhitespace)))return!1;return isAllWhitespace}())for(var next,j=lineStart;j<tokens.length;j++)tokens[j].text&&((next=tokens[j+1])&&">"==next.tag&&(next.indent=tokens[j].text.toString()),tokens.splice(j,1));else noNewLine||tokens.push({tag:"\n"});seenTag=!1,lineStart=tokens.length}function changeDelimiters(text,index){var close="="+ctag,closeIndex=text.indexOf(close,index),delimiters=trim(text.substring(text.indexOf("=",index)+1,closeIndex)).split(" ");return otag=delimiters[0],ctag=delimiters[delimiters.length-1],closeIndex+close.length-1}for(delimiters&&(delimiters=delimiters.split(" "),otag=delimiters[0],ctag=delimiters[1]),i=0;i<len;i++)0==state?tagChange(otag,text,i)?(--i,addBuf(),state=1):"\n"==text.charAt(i)?filterLine(seenTag):buf+=text.charAt(i):1==state?(i+=otag.length-1,"="==(tagType=(tag=Hogan.tags[text.charAt(i+1)])?text.charAt(i+1):"_v")?(i=changeDelimiters(text,i),state=0):(tag&&i++,state=2),seenTag=i):tagChange(ctag,text,i)?(tokens.push({tag:tagType,n:trim(buf),otag:otag,ctag:ctag,i:"/"==tagType?seenTag-otag.length:i+ctag.length}),buf="",i+=ctag.length-1,state=0,"{"==tagType&&("}}"==ctag?i++:cleanTripleStache(tokens[tokens.length-1]))):buf+=text.charAt(i);return filterLine(seenTag,!0),tokens};var allowedInSuper={_t:!0,"\n":!0,$:!0,"/":!0};function isOpener(token,tags){for(var i=0,l=tags.length;i<l;i++)if(tags[i].o==token.n)return token.tag="#",!0}function isCloser(close,open,tags){for(var i=0,l=tags.length;i<l;i++)if(tags[i].c==close&&tags[i].o==open)return!0}function stringifyPartials(codeObj){var partials=[];for(var key in codeObj.partials)partials.push('"'+esc(key)+'":{name:"'+esc(codeObj.partials[key].name)+'", '+stringifyPartials(codeObj.partials[key])+"}");return"partials: {"+partials.join(",")+"}, subs: "+function(obj){var items=[];for(var key in obj)items.push('"'+esc(key)+'": function(c,p,t,i) {'+obj[key]+"}");return"{ "+items.join(",")+" }"}(codeObj.subs)}Hogan.stringify=function(codeObj,text,options){return"{code: function (c,p,i) { "+Hogan.wrapMain(codeObj.code)+" },"+stringifyPartials(codeObj)+"}"};var serialNo=0;function esc(s){return s.replace(rSlash,"\\\\").replace(rQuot,'\\"').replace(rNewline,"\\n").replace(rCr,"\\r").replace(rLineSep,"\\u2028").replace(rParagraphSep,"\\u2029")}function chooseMethod(s){return~s.indexOf(".")?"d":"f"}function createPartial(node,context){var sym="<"+(context.prefix||"")+node.n+serialNo++;return context.partials[sym]={name:node.n,partials:{}},context.code+='t.b(t.rp("'+esc(sym)+'",c,p,"'+(node.indent||"")+'"));',sym}function tripleStache(node,context){context.code+="t.b(t.t(t."+chooseMethod(node.n)+'("'+esc(node.n)+'",c,p,0)));'}function write(s){return"t.b("+s+");"}Hogan.generate=function(tree,text,options){serialNo=0;var context={code:"",subs:{},partials:{}};return Hogan.walk(tree,context),options.asString?this.stringify(context,text,options):this.makeTemplate(context,text,options)},Hogan.wrapMain=function(code){return'var t=this;t.b(i=i||"");'+code+"return t.fl();"},Hogan.template=Hogan.Template,Hogan.makeTemplate=function(codeObj,text,options){var template=this.makePartials(codeObj);return template.code=new Function("c","p","i",this.wrapMain(codeObj.code)),new this.template(template,text,this,options)},Hogan.makePartials=function(codeObj){var key,template={subs:{},partials:codeObj.partials,name:codeObj.name};for(key in template.partials)template.partials[key]=this.makePartials(template.partials[key]);for(key in codeObj.subs)template.subs[key]=new Function("c","p","t","i",codeObj.subs[key]);return template},Hogan.codegen={"#":function(node,context){context.code+="if(t.s(t."+chooseMethod(node.n)+'("'+esc(node.n)+'",c,p,1),c,p,0,'+node.i+","+node.end+',"'+node.otag+" "+node.ctag+'")){t.rs(c,p,function(c,p,t){',Hogan.walk(node.nodes,context),context.code+="});c.pop();}"},"^":function(node,context){context.code+="if(!t.s(t."+chooseMethod(node.n)+'("'+esc(node.n)+'",c,p,1),c,p,1,0,0,"")){',Hogan.walk(node.nodes,context),context.code+="};"},">":createPartial,"<":function(node,context){var ctx={partials:{},code:"",subs:{},inPartial:!0};Hogan.walk(node.nodes,ctx);var template=context.partials[createPartial(node,context)];template.subs=ctx.subs,template.partials=ctx.partials},$:function(node,context){var ctx={subs:{},code:"",partials:context.partials,prefix:node.n};Hogan.walk(node.nodes,ctx),context.subs[node.n]=ctx.code,context.inPartial||(context.code+='t.sub("'+esc(node.n)+'",c,p,i);')},"\n":function(node,context){context.code+=write('"\\n"'+(node.last?"":" + i"))},_v:function(node,context){context.code+="t.b(t.v(t."+chooseMethod(node.n)+'("'+esc(node.n)+'",c,p,0)));'},_t:function(node,context){context.code+=write('"'+esc(node.text)+'"')},"{":tripleStache,"&":tripleStache},Hogan.walk=function(nodelist,context){for(var func,i=0,l=nodelist.length;i<l;i++)(func=Hogan.codegen[nodelist[i].tag])&&func(nodelist[i],context);return context},Hogan.parse=function(tokens,text,options){return function buildTree(tokens,kind,stack,customTags){var tail,instructions=[],opener=null,token=null;for(tail=stack[stack.length-1];0<tokens.length;){if(token=tokens.shift(),tail&&"<"==tail.tag&&!(token.tag in allowedInSuper))throw new Error("Illegal content in < super tag.");if(Hogan.tags[token.tag]<=Hogan.tags.$||isOpener(token,customTags))stack.push(token),token.nodes=buildTree(tokens,token.tag,stack,customTags);else{if("/"==token.tag){if(0===stack.length)throw new Error("Closing tag without opener: /"+token.n);if(opener=stack.pop(),token.n!=opener.n&&!isCloser(token.n,opener.n,customTags))throw new Error("Nesting error: "+opener.n+" vs. "+token.n);return opener.end=token.i,instructions}"\n"==token.tag&&(token.last=0==tokens.length||"\n"==tokens[0].tag)}instructions.push(token)}if(0<stack.length)throw new Error("missing closing tag: "+stack.pop().n);return instructions}(tokens,0,[],(options=options||{}).sectionTags||[])},Hogan.cache={},Hogan.cacheKey=function(text,options){return[text,!!options.asString,!!options.disableLambda,options.delimiters,!!options.modelGet].join("||")},Hogan.compile=function(text,options){options=options||{};var key=Hogan.cacheKey(text,options),template=this.cache[key];if(template){var partials=template.partials;for(var name in partials)delete partials[name].instance;return template}return template=this.generate(this.parse(this.scan(text,options.delimiters),text,options),text,options),this.cache[key]=template}}(void 0!==exports?exports:Hogan)},{}],4:[function(require,module,exports){var Hogan=require("./compiler");Hogan.Template=require("./template").Template,Hogan.template=Hogan.Template,module.exports=Hogan},{"./compiler":3,"./template":5}],5:[function(require,module,exports){!function(Hogan){function findInScope(key,scope,doModelGet){var val;return scope&&"object"==typeof scope&&(void 0!==scope[key]?val=scope[key]:doModelGet&&scope.get&&"function"==typeof scope.get&&(val=scope.get(key))),val}Hogan.Template=function(codeObj,text,compiler,options){codeObj=codeObj||{},this.r=codeObj.code||this.r,this.c=compiler,this.options=options||{},this.text=text||"",this.partials=codeObj.partials||{},this.subs=codeObj.subs||{},this.buf=""},Hogan.Template.prototype={r:function(context,partials,indent){return""},v:function(str){return str=coerceToString(str),hChars.test(str)?str.replace(rAmp,"&amp;").replace(rLt,"&lt;").replace(rGt,"&gt;").replace(rApos,"&#39;").replace(rQuot,"&quot;"):str},t:coerceToString,render:function(context,partials,indent){return this.ri([context],partials||{},indent)},ri:function(context,partials,indent){return this.r(context,partials,indent)},ep:function(symbol,partials){var partial=this.partials[symbol],template=partials[partial.name];if(partial.instance&&partial.base==template)return partial.instance;if("string"==typeof template){if(!this.c)throw new Error("No compiler available.");template=this.c.compile(template,this.options)}if(!template)return null;if(this.partials[symbol].base=template,partial.subs){for(key in partials.stackText||(partials.stackText={}),partial.subs)partials.stackText[key]||(partials.stackText[key]=void 0!==this.activeSub&&partials.stackText[this.activeSub]?partials.stackText[this.activeSub]:this.text);template=function(instance,subs,partials,stackSubs,stackPartials,stackText){function PartialTemplate(){}function Substitutions(){}var key;Substitutions.prototype=(PartialTemplate.prototype=instance).subs;var partial=new PartialTemplate;for(key in partial.subs=new Substitutions,partial.subsText={},partial.buf="",stackSubs=stackSubs||{},partial.stackSubs=stackSubs,partial.subsText=stackText,subs)stackSubs[key]||(stackSubs[key]=subs[key]);for(key in stackSubs)partial.subs[key]=stackSubs[key];for(key in stackPartials=stackPartials||{},partial.stackPartials=stackPartials,partials)stackPartials[key]||(stackPartials[key]=partials[key]);for(key in stackPartials)partial.partials[key]=stackPartials[key];return partial}(template,partial.subs,partial.partials,this.stackSubs,this.stackPartials,partials.stackText)}return this.partials[symbol].instance=template},rp:function(symbol,context,partials,indent){var partial=this.ep(symbol,partials);return partial?partial.ri(context,partials,indent):""},rs:function(context,partials,section){var tail=context[context.length-1];if(isArray(tail))for(var i=0;i<tail.length;i++)context.push(tail[i]),section(context,partials,this),context.pop();else section(context,partials,this)},s:function(val,ctx,partials,inverted,start,end,tags){var pass;return(!isArray(val)||0!==val.length)&&("function"==typeof val&&(val=this.ms(val,ctx,partials,inverted,start,end,tags)),pass=!!val,!inverted&&pass&&ctx&&ctx.push("object"==typeof val?val:ctx[ctx.length-1]),pass)},d:function(key,ctx,partials,returnFound){var found,names=key.split("."),val=this.f(names[0],ctx,partials,returnFound),doModelGet=this.options.modelGet,cx=null;if("."===key&&isArray(ctx[ctx.length-2]))val=ctx[ctx.length-1];else for(var i=1;i<names.length;i++)void 0!==(found=findInScope(names[i],val,doModelGet))?(cx=val,val=found):val="";return!(returnFound&&!val)&&(returnFound||"function"!=typeof val||(ctx.push(cx),val=this.mv(val,ctx,partials),ctx.pop()),val)},f:function(key,ctx,partials,returnFound){for(var val=!1,found=!1,doModelGet=this.options.modelGet,i=ctx.length-1;0<=i;i--)if(void 0!==(val=findInScope(key,ctx[i],doModelGet))){found=!0;break}return found?(returnFound||"function"!=typeof val||(val=this.mv(val,ctx,partials)),val):!returnFound&&""},ls:function(func,cx,partials,text,tags){var oldTags=this.options.delimiters;return this.options.delimiters=tags,this.b(this.ct(coerceToString(func.call(cx,text)),cx,partials)),this.options.delimiters=oldTags,!1},ct:function(text,cx,partials){if(this.options.disableLambda)throw new Error("Lambda features disabled.");return this.c.compile(text,this.options).render(cx,partials)},b:function(s){this.buf+=s},fl:function(){var r=this.buf;return this.buf="",r},ms:function(func,ctx,partials,inverted,start,end,tags){var textSource,cx=ctx[ctx.length-1],result=func.call(cx);return"function"==typeof result?!!inverted||(textSource=this.activeSub&&this.subsText&&this.subsText[this.activeSub]?this.subsText[this.activeSub]:this.text,this.ls(result,cx,partials,textSource.substring(start,end),tags)):result},mv:function(func,ctx,partials){var cx=ctx[ctx.length-1],result=func.call(cx);return"function"==typeof result?this.ct(coerceToString(result.call(cx)),cx,partials):result},sub:function(name,context,partials,indent){var f=this.subs[name];f&&(this.activeSub=name,f(context,partials,this,indent),this.activeSub=!1)}};var rAmp=/&/g,rLt=/</g,rGt=/>/g,rApos=/\'/g,rQuot=/\"/g,hChars=/[&<>\"\']/;function coerceToString(val){return String(null==val?"":val)}var isArray=Array.isArray||function(a){return"[object Array]"===Object.prototype.toString.call(a)}}(void 0!==exports?exports:{})},{}],6:[function(require,module,exports){var hashClear=require("./_hashClear"),hashDelete=require("./_hashDelete"),hashGet=require("./_hashGet"),hashHas=require("./_hashHas"),hashSet=require("./_hashSet");function Hash(entries){var index=-1,length=null==entries?0:entries.length;for(this.clear();++index<length;){var entry=entries[index];this.set(entry[0],entry[1])}}Hash.prototype.clear=hashClear,Hash.prototype.delete=hashDelete,Hash.prototype.get=hashGet,Hash.prototype.has=hashHas,Hash.prototype.set=hashSet,module.exports=Hash},{"./_hashClear":47,"./_hashDelete":48,"./_hashGet":49,"./_hashHas":50,"./_hashSet":51}],7:[function(require,module,exports){var listCacheClear=require("./_listCacheClear"),listCacheDelete=require("./_listCacheDelete"),listCacheGet=require("./_listCacheGet"),listCacheHas=require("./_listCacheHas"),listCacheSet=require("./_listCacheSet");function ListCache(entries){var index=-1,length=null==entries?0:entries.length;for(this.clear();++index<length;){var entry=entries[index];this.set(entry[0],entry[1])}}ListCache.prototype.clear=listCacheClear,ListCache.prototype.delete=listCacheDelete,ListCache.prototype.get=listCacheGet,ListCache.prototype.has=listCacheHas,ListCache.prototype.set=listCacheSet,module.exports=ListCache},{"./_listCacheClear":58,"./_listCacheDelete":59,"./_listCacheGet":60,"./_listCacheHas":61,"./_listCacheSet":62}],8:[function(require,module,exports){var Map=require("./_getNative")(require("./_root"),"Map");module.exports=Map},{"./_getNative":43,"./_root":74}],9:[function(require,module,exports){var mapCacheClear=require("./_mapCacheClear"),mapCacheDelete=require("./_mapCacheDelete"),mapCacheGet=require("./_mapCacheGet"),mapCacheHas=require("./_mapCacheHas"),mapCacheSet=require("./_mapCacheSet");function MapCache(entries){var index=-1,length=null==entries?0:entries.length;for(this.clear();++index<length;){var entry=entries[index];this.set(entry[0],entry[1])}}MapCache.prototype.clear=mapCacheClear,MapCache.prototype.delete=mapCacheDelete,MapCache.prototype.get=mapCacheGet,MapCache.prototype.has=mapCacheHas,MapCache.prototype.set=mapCacheSet,module.exports=MapCache},{"./_mapCacheClear":63,"./_mapCacheDelete":64,"./_mapCacheGet":65,"./_mapCacheHas":66,"./_mapCacheSet":67}],10:[function(require,module,exports){var ListCache=require("./_ListCache"),stackClear=require("./_stackClear"),stackDelete=require("./_stackDelete"),stackGet=require("./_stackGet"),stackHas=require("./_stackHas"),stackSet=require("./_stackSet");function Stack(entries){var data=this.__data__=new ListCache(entries);this.size=data.size}Stack.prototype.clear=stackClear,Stack.prototype.delete=stackDelete,Stack.prototype.get=stackGet,Stack.prototype.has=stackHas,Stack.prototype.set=stackSet,module.exports=Stack},{"./_ListCache":7,"./_stackClear":78,"./_stackDelete":79,"./_stackGet":80,"./_stackHas":81,"./_stackSet":82}],11:[function(require,module,exports){var Symbol=require("./_root").Symbol;module.exports=Symbol},{"./_root":74}],12:[function(require,module,exports){var Uint8Array=require("./_root").Uint8Array;module.exports=Uint8Array},{"./_root":74}],13:[function(require,module,exports){module.exports=function(func,thisArg,args){switch(args.length){case 0:return func.call(thisArg);case 1:return func.call(thisArg,args[0]);case 2:return func.call(thisArg,args[0],args[1]);case 3:return func.call(thisArg,args[0],args[1],args[2])}return func.apply(thisArg,args)}},{}],14:[function(require,module,exports){var baseTimes=require("./_baseTimes"),isArguments=require("./isArguments"),isArray=require("./isArray"),isBuffer=require("./isBuffer"),isIndex=require("./_isIndex"),isTypedArray=require("./isTypedArray"),hasOwnProperty=Object.prototype.hasOwnProperty;module.exports=function(value,inherited){var isArr=isArray(value),isArg=!isArr&&isArguments(value),isBuff=!isArr&&!isArg&&isBuffer(value),isType=!isArr&&!isArg&&!isBuff&&isTypedArray(value),skipIndexes=isArr||isArg||isBuff||isType,result=skipIndexes?baseTimes(value.length,String):[],length=result.length;for(var key in value)!inherited&&!hasOwnProperty.call(value,key)||skipIndexes&&("length"==key||isBuff&&("offset"==key||"parent"==key)||isType&&("buffer"==key||"byteLength"==key||"byteOffset"==key)||isIndex(key,length))||result.push(key);return result}},{"./_baseTimes":30,"./_isIndex":53,"./isArguments":87,"./isArray":88,"./isBuffer":91,"./isTypedArray":97}],15:[function(require,module,exports){var baseAssignValue=require("./_baseAssignValue"),eq=require("./eq");module.exports=function(object,key,value){(void 0===value||eq(object[key],value))&&(void 0!==value||key in object)||baseAssignValue(object,key,value)}},{"./_baseAssignValue":18,"./eq":85}],16:[function(require,module,exports){var baseAssignValue=require("./_baseAssignValue"),eq=require("./eq"),hasOwnProperty=Object.prototype.hasOwnProperty;module.exports=function(object,key,value){var objValue=object[key];hasOwnProperty.call(object,key)&&eq(objValue,value)&&(void 0!==value||key in object)||baseAssignValue(object,key,value)}},{"./_baseAssignValue":18,"./eq":85}],17:[function(require,module,exports){var eq=require("./eq");module.exports=function(array,key){for(var length=array.length;length--;)if(eq(array[length][0],key))return length;return-1}},{"./eq":85}],18:[function(require,module,exports){var defineProperty=require("./_defineProperty");module.exports=function(object,key,value){"__proto__"==key&&defineProperty?defineProperty(object,key,{configurable:!0,enumerable:!0,value:value,writable:!0}):object[key]=value}},{"./_defineProperty":40}],19:[function(require,module,exports){var isObject=require("./isObject"),objectCreate=Object.create,baseCreate=function(){function object(){}return function(proto){if(!isObject(proto))return{};if(objectCreate)return objectCreate(proto);object.prototype=proto;var result=new object;return object.prototype=void 0,result}}();module.exports=baseCreate},{"./isObject":94}],20:[function(require,module,exports){var baseFor=require("./_createBaseFor")();module.exports=baseFor},{"./_createBaseFor":39}],21:[function(require,module,exports){var Symbol=require("./_Symbol"),getRawTag=require("./_getRawTag"),objectToString=require("./_objectToString"),symToStringTag=Symbol?Symbol.toStringTag:void 0;module.exports=function(value){return null==value?void 0===value?"[object Undefined]":"[object Null]":symToStringTag&&symToStringTag in Object(value)?getRawTag(value):objectToString(value)}},{"./_Symbol":11,"./_getRawTag":45,"./_objectToString":71}],22:[function(require,module,exports){var baseGetTag=require("./_baseGetTag"),isObjectLike=require("./isObjectLike");module.exports=function(value){return isObjectLike(value)&&"[object Arguments]"==baseGetTag(value)}},{"./_baseGetTag":21,"./isObjectLike":95}],23:[function(require,module,exports){var isFunction=require("./isFunction"),isMasked=require("./_isMasked"),isObject=require("./isObject"),toSource=require("./_toSource"),reIsHostCtor=/^\[object .+?Constructor\]$/,funcProto=Function.prototype,objectProto=Object.prototype,funcToString=funcProto.toString,hasOwnProperty=objectProto.hasOwnProperty,reIsNative=RegExp("^"+funcToString.call(hasOwnProperty).replace(/[\\^$.*+?()[\]{}|]/g,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$");module.exports=function(value){return!(!isObject(value)||isMasked(value))&&(isFunction(value)?reIsNative:reIsHostCtor).test(toSource(value))}},{"./_isMasked":56,"./_toSource":83,"./isFunction":92,"./isObject":94}],24:[function(require,module,exports){var baseGetTag=require("./_baseGetTag"),isLength=require("./isLength"),isObjectLike=require("./isObjectLike"),typedArrayTags={};typedArrayTags["[object Float32Array]"]=typedArrayTags["[object Float64Array]"]=typedArrayTags["[object Int8Array]"]=typedArrayTags["[object Int16Array]"]=typedArrayTags["[object Int32Array]"]=typedArrayTags["[object Uint8Array]"]=typedArrayTags["[object Uint8ClampedArray]"]=typedArrayTags["[object Uint16Array]"]=typedArrayTags["[object Uint32Array]"]=!0,typedArrayTags["[object Arguments]"]=typedArrayTags["[object Array]"]=typedArrayTags["[object ArrayBuffer]"]=typedArrayTags["[object Boolean]"]=typedArrayTags["[object DataView]"]=typedArrayTags["[object Date]"]=typedArrayTags["[object Error]"]=typedArrayTags["[object Function]"]=typedArrayTags["[object Map]"]=typedArrayTags["[object Number]"]=typedArrayTags["[object Object]"]=typedArrayTags["[object RegExp]"]=typedArrayTags["[object Set]"]=typedArrayTags["[object String]"]=typedArrayTags["[object WeakMap]"]=!1,module.exports=function(value){return isObjectLike(value)&&isLength(value.length)&&!!typedArrayTags[baseGetTag(value)]}},{"./_baseGetTag":21,"./isLength":93,"./isObjectLike":95}],25:[function(require,module,exports){var isObject=require("./isObject"),isPrototype=require("./_isPrototype"),nativeKeysIn=require("./_nativeKeysIn"),hasOwnProperty=Object.prototype.hasOwnProperty;module.exports=function(object){if(!isObject(object))return nativeKeysIn(object);var isProto=isPrototype(object),result=[];for(var key in object)("constructor"!=key||!isProto&&hasOwnProperty.call(object,key))&&result.push(key);return result}},{"./_isPrototype":57,"./_nativeKeysIn":69,"./isObject":94}],26:[function(require,module,exports){var Stack=require("./_Stack"),assignMergeValue=require("./_assignMergeValue"),baseFor=require("./_baseFor"),baseMergeDeep=require("./_baseMergeDeep"),isObject=require("./isObject"),keysIn=require("./keysIn"),safeGet=require("./_safeGet");module.exports=function baseMerge(object,source,srcIndex,customizer,stack){object!==source&&baseFor(source,function(srcValue,key){if(isObject(srcValue))stack||(stack=new Stack),baseMergeDeep(object,source,key,srcIndex,baseMerge,customizer,stack);else{var newValue=customizer?customizer(safeGet(object,key),srcValue,key+"",object,source,stack):void 0;void 0===newValue&&(newValue=srcValue),assignMergeValue(object,key,newValue)}},keysIn)}},{"./_Stack":10,"./_assignMergeValue":15,"./_baseFor":20,"./_baseMergeDeep":27,"./_safeGet":75,"./isObject":94,"./keysIn":98}],27:[function(require,module,exports){var assignMergeValue=require("./_assignMergeValue"),cloneBuffer=require("./_cloneBuffer"),cloneTypedArray=require("./_cloneTypedArray"),copyArray=require("./_copyArray"),initCloneObject=require("./_initCloneObject"),isArguments=require("./isArguments"),isArray=require("./isArray"),isArrayLikeObject=require("./isArrayLikeObject"),isBuffer=require("./isBuffer"),isFunction=require("./isFunction"),isObject=require("./isObject"),isPlainObject=require("./isPlainObject"),isTypedArray=require("./isTypedArray"),safeGet=require("./_safeGet"),toPlainObject=require("./toPlainObject");module.exports=function(object,source,key,srcIndex,mergeFunc,customizer,stack){var objValue=safeGet(object,key),srcValue=safeGet(source,key),stacked=stack.get(srcValue);if(stacked)assignMergeValue(object,key,stacked);else{var newValue=customizer?customizer(objValue,srcValue,key+"",object,source,stack):void 0,isCommon=void 0===newValue;if(isCommon){var isArr=isArray(srcValue),isBuff=!isArr&&isBuffer(srcValue),isTyped=!isArr&&!isBuff&&isTypedArray(srcValue);newValue=srcValue,isArr||isBuff||isTyped?newValue=isArray(objValue)?objValue:isArrayLikeObject(objValue)?copyArray(objValue):isBuff?cloneBuffer(srcValue,!(isCommon=!1)):isTyped?cloneTypedArray(srcValue,!(isCommon=!1)):[]:isPlainObject(srcValue)||isArguments(srcValue)?isArguments(newValue=objValue)?newValue=toPlainObject(objValue):(!isObject(objValue)||srcIndex&&isFunction(objValue))&&(newValue=initCloneObject(srcValue)):isCommon=!1}isCommon&&(stack.set(srcValue,newValue),mergeFunc(newValue,srcValue,srcIndex,customizer,stack),stack.delete(srcValue)),assignMergeValue(object,key,newValue)}}},{"./_assignMergeValue":15,"./_cloneBuffer":33,"./_cloneTypedArray":34,"./_copyArray":35,"./_initCloneObject":52,"./_safeGet":75,"./isArguments":87,"./isArray":88,"./isArrayLikeObject":90,"./isBuffer":91,"./isFunction":92,"./isObject":94,"./isPlainObject":96,"./isTypedArray":97,"./toPlainObject":101}],28:[function(require,module,exports){var identity=require("./identity"),overRest=require("./_overRest"),setToString=require("./_setToString");module.exports=function(func,start){return setToString(overRest(func,start,identity),func+"")}},{"./_overRest":73,"./_setToString":76,"./identity":86}],29:[function(require,module,exports){var constant=require("./constant"),defineProperty=require("./_defineProperty"),identity=require("./identity"),baseSetToString=defineProperty?function(func,string){return defineProperty(func,"toString",{configurable:!0,enumerable:!1,value:constant(string),writable:!0})}:identity;module.exports=baseSetToString},{"./_defineProperty":40,"./constant":84,"./identity":86}],30:[function(require,module,exports){module.exports=function(n,iteratee){for(var index=-1,result=Array(n);++index<n;)result[index]=iteratee(index);return result}},{}],31:[function(require,module,exports){module.exports=function(func){return function(value){return func(value)}}},{}],32:[function(require,module,exports){var Uint8Array=require("./_Uint8Array");module.exports=function(arrayBuffer){var result=new arrayBuffer.constructor(arrayBuffer.byteLength);return new Uint8Array(result).set(new Uint8Array(arrayBuffer)),result}},{"./_Uint8Array":12}],33:[function(require,module,exports){var root=require("./_root"),freeExports="object"==typeof exports&&exports&&!exports.nodeType&&exports,freeModule=freeExports&&"object"==typeof module&&module&&!module.nodeType&&module,Buffer=freeModule&&freeModule.exports===freeExports?root.Buffer:void 0,allocUnsafe=Buffer?Buffer.allocUnsafe:void 0;module.exports=function(buffer,isDeep){if(isDeep)return buffer.slice();var length=buffer.length,result=allocUnsafe?allocUnsafe(length):new buffer.constructor(length);return buffer.copy(result),result}},{"./_root":74}],34:[function(require,module,exports){var cloneArrayBuffer=require("./_cloneArrayBuffer");module.exports=function(typedArray,isDeep){var buffer=isDeep?cloneArrayBuffer(typedArray.buffer):typedArray.buffer;return new typedArray.constructor(buffer,typedArray.byteOffset,typedArray.length)}},{"./_cloneArrayBuffer":32}],35:[function(require,module,exports){module.exports=function(source,array){var index=-1,length=source.length;for(array||(array=Array(length));++index<length;)array[index]=source[index];return array}},{}],36:[function(require,module,exports){var assignValue=require("./_assignValue"),baseAssignValue=require("./_baseAssignValue");module.exports=function(source,props,object,customizer){var isNew=!object;object||(object={});for(var index=-1,length=props.length;++index<length;){var key=props[index],newValue=customizer?customizer(object[key],source[key],key,object,source):void 0;void 0===newValue&&(newValue=source[key]),isNew?baseAssignValue(object,key,newValue):assignValue(object,key,newValue)}return object}},{"./_assignValue":16,"./_baseAssignValue":18}],37:[function(require,module,exports){var coreJsData=require("./_root")["__core-js_shared__"];module.exports=coreJsData},{"./_root":74}],38:[function(require,module,exports){var baseRest=require("./_baseRest"),isIterateeCall=require("./_isIterateeCall");module.exports=function(assigner){return baseRest(function(object,sources){var index=-1,length=sources.length,customizer=1<length?sources[length-1]:void 0,guard=2<length?sources[2]:void 0;for(customizer=3<assigner.length&&"function"==typeof customizer?(length--,customizer):void 0,guard&&isIterateeCall(sources[0],sources[1],guard)&&(customizer=length<3?void 0:customizer,length=1),object=Object(object);++index<length;){var source=sources[index];source&&assigner(object,source,index,customizer)}return object})}},{"./_baseRest":28,"./_isIterateeCall":54}],39:[function(require,module,exports){module.exports=function(fromRight){return function(object,iteratee,keysFunc){for(var index=-1,iterable=Object(object),props=keysFunc(object),length=props.length;length--;){var key=props[fromRight?length:++index];if(!1===iteratee(iterable[key],key,iterable))break}return object}}},{}],40:[function(require,module,exports){var getNative=require("./_getNative"),defineProperty=function(){try{var func=getNative(Object,"defineProperty");return func({},"",{}),func}catch(e){}}();module.exports=defineProperty},{"./_getNative":43}],41:[function(require,module,exports){(function(global){var freeGlobal="object"==typeof global&&global&&global.Object===Object&&global;module.exports=freeGlobal}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],42:[function(require,module,exports){var isKeyable=require("./_isKeyable");module.exports=function(map,key){var data=map.__data__;return isKeyable(key)?data["string"==typeof key?"string":"hash"]:data.map}},{"./_isKeyable":55}],43:[function(require,module,exports){var baseIsNative=require("./_baseIsNative"),getValue=require("./_getValue");module.exports=function(object,key){var value=getValue(object,key);return baseIsNative(value)?value:void 0}},{"./_baseIsNative":23,"./_getValue":46}],44:[function(require,module,exports){var getPrototype=require("./_overArg")(Object.getPrototypeOf,Object);module.exports=getPrototype},{"./_overArg":72}],45:[function(require,module,exports){var Symbol=require("./_Symbol"),objectProto=Object.prototype,hasOwnProperty=objectProto.hasOwnProperty,nativeObjectToString=objectProto.toString,symToStringTag=Symbol?Symbol.toStringTag:void 0;module.exports=function(value){var isOwn=hasOwnProperty.call(value,symToStringTag),tag=value[symToStringTag];try{var unmasked=!(value[symToStringTag]=void 0)}catch(e){}var result=nativeObjectToString.call(value);return unmasked&&(isOwn?value[symToStringTag]=tag:delete value[symToStringTag]),result}},{"./_Symbol":11}],46:[function(require,module,exports){module.exports=function(object,key){return null==object?void 0:object[key]}},{}],47:[function(require,module,exports){var nativeCreate=require("./_nativeCreate");module.exports=function(){this.__data__=nativeCreate?nativeCreate(null):{},this.size=0}},{"./_nativeCreate":68}],48:[function(require,module,exports){module.exports=function(key){var result=this.has(key)&&delete this.__data__[key];return this.size-=result?1:0,result}},{}],49:[function(require,module,exports){var nativeCreate=require("./_nativeCreate"),hasOwnProperty=Object.prototype.hasOwnProperty;module.exports=function(key){var data=this.__data__;if(nativeCreate){var result=data[key];return"__lodash_hash_undefined__"===result?void 0:result}return hasOwnProperty.call(data,key)?data[key]:void 0}},{"./_nativeCreate":68}],50:[function(require,module,exports){var nativeCreate=require("./_nativeCreate"),hasOwnProperty=Object.prototype.hasOwnProperty;module.exports=function(key){var data=this.__data__;return nativeCreate?void 0!==data[key]:hasOwnProperty.call(data,key)}},{"./_nativeCreate":68}],51:[function(require,module,exports){var nativeCreate=require("./_nativeCreate");module.exports=function(key,value){var data=this.__data__;return this.size+=this.has(key)?0:1,data[key]=nativeCreate&&void 0===value?"__lodash_hash_undefined__":value,this}},{"./_nativeCreate":68}],52:[function(require,module,exports){var baseCreate=require("./_baseCreate"),getPrototype=require("./_getPrototype"),isPrototype=require("./_isPrototype");module.exports=function(object){return"function"!=typeof object.constructor||isPrototype(object)?{}:baseCreate(getPrototype(object))}},{"./_baseCreate":19,"./_getPrototype":44,"./_isPrototype":57}],53:[function(require,module,exports){var reIsUint=/^(?:0|[1-9]\d*)$/;module.exports=function(value,length){var type=typeof value;return!!(length=null==length?9007199254740991:length)&&("number"==type||"symbol"!=type&&reIsUint.test(value))&&-1<value&&value%1==0&&value<length}},{}],54:[function(require,module,exports){var eq=require("./eq"),isArrayLike=require("./isArrayLike"),isIndex=require("./_isIndex"),isObject=require("./isObject");module.exports=function(value,index,object){if(!isObject(object))return!1;var type=typeof index;return!!("number"==type?isArrayLike(object)&&isIndex(index,object.length):"string"==type&&index in object)&&eq(object[index],value)}},{"./_isIndex":53,"./eq":85,"./isArrayLike":89,"./isObject":94}],55:[function(require,module,exports){module.exports=function(value){var type=typeof value;return"string"==type||"number"==type||"symbol"==type||"boolean"==type?"__proto__"!==value:null===value}},{}],56:[function(require,module,exports){var uid,coreJsData=require("./_coreJsData"),maskSrcKey=(uid=/[^.]+$/.exec(coreJsData&&coreJsData.keys&&coreJsData.keys.IE_PROTO||""))?"Symbol(src)_1."+uid:"";module.exports=function(func){return!!maskSrcKey&&maskSrcKey in func}},{"./_coreJsData":37}],57:[function(require,module,exports){var objectProto=Object.prototype;module.exports=function(value){var Ctor=value&&value.constructor;return value===("function"==typeof Ctor&&Ctor.prototype||objectProto)}},{}],58:[function(require,module,exports){module.exports=function(){this.__data__=[],this.size=0}},{}],59:[function(require,module,exports){var assocIndexOf=require("./_assocIndexOf"),splice=Array.prototype.splice;module.exports=function(key){var data=this.__data__,index=assocIndexOf(data,key);return!(index<0||(index==data.length-1?data.pop():splice.call(data,index,1),--this.size,0))}},{"./_assocIndexOf":17}],60:[function(require,module,exports){var assocIndexOf=require("./_assocIndexOf");module.exports=function(key){var data=this.__data__,index=assocIndexOf(data,key);return index<0?void 0:data[index][1]}},{"./_assocIndexOf":17}],61:[function(require,module,exports){var assocIndexOf=require("./_assocIndexOf");module.exports=function(key){return-1<assocIndexOf(this.__data__,key)}},{"./_assocIndexOf":17}],62:[function(require,module,exports){var assocIndexOf=require("./_assocIndexOf");module.exports=function(key,value){var data=this.__data__,index=assocIndexOf(data,key);return index<0?(++this.size,data.push([key,value])):data[index][1]=value,this}},{"./_assocIndexOf":17}],63:[function(require,module,exports){var Hash=require("./_Hash"),ListCache=require("./_ListCache"),Map=require("./_Map");module.exports=function(){this.size=0,this.__data__={hash:new Hash,map:new(Map||ListCache),string:new Hash}}},{"./_Hash":6,"./_ListCache":7,"./_Map":8}],64:[function(require,module,exports){var getMapData=require("./_getMapData");module.exports=function(key){var result=getMapData(this,key).delete(key);return this.size-=result?1:0,result}},{"./_getMapData":42}],65:[function(require,module,exports){var getMapData=require("./_getMapData");module.exports=function(key){return getMapData(this,key).get(key)}},{"./_getMapData":42}],66:[function(require,module,exports){var getMapData=require("./_getMapData");module.exports=function(key){return getMapData(this,key).has(key)}},{"./_getMapData":42}],67:[function(require,module,exports){var getMapData=require("./_getMapData");module.exports=function(key,value){var data=getMapData(this,key),size=data.size;return data.set(key,value),this.size+=data.size==size?0:1,this}},{"./_getMapData":42}],68:[function(require,module,exports){var nativeCreate=require("./_getNative")(Object,"create");module.exports=nativeCreate},{"./_getNative":43}],69:[function(require,module,exports){module.exports=function(object){var result=[];if(null!=object)for(var key in Object(object))result.push(key);return result}},{}],70:[function(require,module,exports){var freeGlobal=require("./_freeGlobal"),freeExports="object"==typeof exports&&exports&&!exports.nodeType&&exports,freeModule=freeExports&&"object"==typeof module&&module&&!module.nodeType&&module,freeProcess=freeModule&&freeModule.exports===freeExports&&freeGlobal.process,nodeUtil=function(){try{var types=freeModule&&freeModule.require&&freeModule.require("util").types;return types||freeProcess&&freeProcess.binding&&freeProcess.binding("util")}catch(e){}}();module.exports=nodeUtil},{"./_freeGlobal":41}],71:[function(require,module,exports){var nativeObjectToString=Object.prototype.toString;module.exports=function(value){return nativeObjectToString.call(value)}},{}],72:[function(require,module,exports){module.exports=function(func,transform){return function(arg){return func(transform(arg))}}},{}],73:[function(require,module,exports){var apply=require("./_apply"),nativeMax=Math.max;module.exports=function(func,start,transform){return start=nativeMax(void 0===start?func.length-1:start,0),function(){for(var args=arguments,index=-1,length=nativeMax(args.length-start,0),array=Array(length);++index<length;)array[index]=args[start+index];index=-1;for(var otherArgs=Array(start+1);++index<start;)otherArgs[index]=args[index];return otherArgs[start]=transform(array),apply(func,this,otherArgs)}}},{"./_apply":13}],74:[function(require,module,exports){var freeGlobal=require("./_freeGlobal"),freeSelf="object"==typeof self&&self&&self.Object===Object&&self,root=freeGlobal||freeSelf||Function("return this")();module.exports=root},{"./_freeGlobal":41}],75:[function(require,module,exports){module.exports=function(object,key){return"__proto__"==key?void 0:object[key]}},{}],76:[function(require,module,exports){var baseSetToString=require("./_baseSetToString"),setToString=require("./_shortOut")(baseSetToString);module.exports=setToString},{"./_baseSetToString":29,"./_shortOut":77}],77:[function(require,module,exports){var nativeNow=Date.now;module.exports=function(func){var count=0,lastCalled=0;return function(){var stamp=nativeNow(),remaining=16-(stamp-lastCalled);if(lastCalled=stamp,0<remaining){if(800<=++count)return arguments[0]}else count=0;return func.apply(void 0,arguments)}}},{}],78:[function(require,module,exports){var ListCache=require("./_ListCache");module.exports=function(){this.__data__=new ListCache,this.size=0}},{"./_ListCache":7}],79:[function(require,module,exports){module.exports=function(key){var data=this.__data__,result=data.delete(key);return this.size=data.size,result}},{}],80:[function(require,module,exports){module.exports=function(key){return this.__data__.get(key)}},{}],81:[function(require,module,exports){module.exports=function(key){return this.__data__.has(key)}},{}],82:[function(require,module,exports){var ListCache=require("./_ListCache"),Map=require("./_Map"),MapCache=require("./_MapCache");module.exports=function(key,value){var data=this.__data__;if(data instanceof ListCache){var pairs=data.__data__;if(!Map||pairs.length<199)return pairs.push([key,value]),this.size=++data.size,this;data=this.__data__=new MapCache(pairs)}return data.set(key,value),this.size=data.size,this}},{"./_ListCache":7,"./_Map":8,"./_MapCache":9}],83:[function(require,module,exports){var funcToString=Function.prototype.toString;module.exports=function(func){if(null!=func){try{return funcToString.call(func)}catch(e){}try{return func+""}catch(e){}}return""}},{}],84:[function(require,module,exports){module.exports=function(value){return function(){return value}}},{}],85:[function(require,module,exports){module.exports=function(value,other){return value===other||value!=value&&other!=other}},{}],86:[function(require,module,exports){module.exports=function(value){return value}},{}],87:[function(require,module,exports){var baseIsArguments=require("./_baseIsArguments"),isObjectLike=require("./isObjectLike"),objectProto=Object.prototype,hasOwnProperty=objectProto.hasOwnProperty,propertyIsEnumerable=objectProto.propertyIsEnumerable,isArguments=baseIsArguments(function(){return arguments}())?baseIsArguments:function(value){return isObjectLike(value)&&hasOwnProperty.call(value,"callee")&&!propertyIsEnumerable.call(value,"callee")};module.exports=isArguments},{"./_baseIsArguments":22,"./isObjectLike":95}],88:[function(require,module,exports){var isArray=Array.isArray;module.exports=isArray},{}],89:[function(require,module,exports){var isFunction=require("./isFunction"),isLength=require("./isLength");module.exports=function(value){return null!=value&&isLength(value.length)&&!isFunction(value)}},{"./isFunction":92,"./isLength":93}],90:[function(require,module,exports){var isArrayLike=require("./isArrayLike"),isObjectLike=require("./isObjectLike");module.exports=function(value){return isObjectLike(value)&&isArrayLike(value)}},{"./isArrayLike":89,"./isObjectLike":95}],91:[function(require,module,exports){var root=require("./_root"),stubFalse=require("./stubFalse"),freeExports="object"==typeof exports&&exports&&!exports.nodeType&&exports,freeModule=freeExports&&"object"==typeof module&&module&&!module.nodeType&&module,Buffer=freeModule&&freeModule.exports===freeExports?root.Buffer:void 0,isBuffer=(Buffer?Buffer.isBuffer:void 0)||stubFalse;module.exports=isBuffer},{"./_root":74,"./stubFalse":100}],92:[function(require,module,exports){var baseGetTag=require("./_baseGetTag"),isObject=require("./isObject");module.exports=function(value){if(!isObject(value))return!1;var tag=baseGetTag(value);return"[object Function]"==tag||"[object GeneratorFunction]"==tag||"[object AsyncFunction]"==tag||"[object Proxy]"==tag}},{"./_baseGetTag":21,"./isObject":94}],93:[function(require,module,exports){module.exports=function(value){return"number"==typeof value&&-1<value&&value%1==0&&value<=9007199254740991}},{}],94:[function(require,module,exports){module.exports=function(value){var type=typeof value;return null!=value&&("object"==type||"function"==type)}},{}],95:[function(require,module,exports){module.exports=function(value){return null!=value&&"object"==typeof value}},{}],96:[function(require,module,exports){var baseGetTag=require("./_baseGetTag"),getPrototype=require("./_getPrototype"),isObjectLike=require("./isObjectLike"),funcProto=Function.prototype,objectProto=Object.prototype,funcToString=funcProto.toString,hasOwnProperty=objectProto.hasOwnProperty,objectCtorString=funcToString.call(Object);module.exports=function(value){if(!isObjectLike(value)||"[object Object]"!=baseGetTag(value))return!1;var proto=getPrototype(value);if(null===proto)return!0;var Ctor=hasOwnProperty.call(proto,"constructor")&&proto.constructor;return"function"==typeof Ctor&&Ctor instanceof Ctor&&funcToString.call(Ctor)==objectCtorString}},{"./_baseGetTag":21,"./_getPrototype":44,"./isObjectLike":95}],97:[function(require,module,exports){var baseIsTypedArray=require("./_baseIsTypedArray"),baseUnary=require("./_baseUnary"),nodeUtil=require("./_nodeUtil"),nodeIsTypedArray=nodeUtil&&nodeUtil.isTypedArray,isTypedArray=nodeIsTypedArray?baseUnary(nodeIsTypedArray):baseIsTypedArray;module.exports=isTypedArray},{"./_baseIsTypedArray":24,"./_baseUnary":31,"./_nodeUtil":70}],98:[function(require,module,exports){var arrayLikeKeys=require("./_arrayLikeKeys"),baseKeysIn=require("./_baseKeysIn"),isArrayLike=require("./isArrayLike");module.exports=function(object){return isArrayLike(object)?arrayLikeKeys(object,!0):baseKeysIn(object)}},{"./_arrayLikeKeys":14,"./_baseKeysIn":25,"./isArrayLike":89}],99:[function(require,module,exports){var baseMerge=require("./_baseMerge"),merge=require("./_createAssigner")(function(object,source,srcIndex){baseMerge(object,source,srcIndex)});module.exports=merge},{"./_baseMerge":26,"./_createAssigner":38}],100:[function(require,module,exports){module.exports=function(){return!1}},{}],101:[function(require,module,exports){var copyObject=require("./_copyObject"),keysIn=require("./keysIn");module.exports=function(value){return copyObject(value,keysIn(value))}},{"./_copyObject":36,"./keysIn":98}],102:[function(require,module,exports){(function(process){function normalizeArray(parts,allowAboveRoot){for(var up=0,i=parts.length-1;0<=i;i--){var last=parts[i];"."===last?parts.splice(i,1):".."===last?(parts.splice(i,1),up++):up&&(parts.splice(i,1),up--)}if(allowAboveRoot)for(;up--;up)parts.unshift("..");return parts}var splitPathRe=/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/,splitPath=function(filename){return splitPathRe.exec(filename).slice(1)};function filter(xs,f){if(xs.filter)return xs.filter(f);for(var res=[],i=0;i<xs.length;i++)f(xs[i],i,xs)&&res.push(xs[i]);return res}exports.resolve=function(){for(var resolvedPath="",resolvedAbsolute=!1,i=arguments.length-1;-1<=i&&!resolvedAbsolute;i--){var path=0<=i?arguments[i]:process.cwd();if("string"!=typeof path)throw new TypeError("Arguments to path.resolve must be strings");path&&(resolvedPath=path+"/"+resolvedPath,resolvedAbsolute="/"===path.charAt(0))}return(resolvedAbsolute?"/":"")+(resolvedPath=normalizeArray(filter(resolvedPath.split("/"),function(p){return!!p}),!resolvedAbsolute).join("/"))||"."},exports.normalize=function(path){var isAbsolute=exports.isAbsolute(path),trailingSlash="/"===substr(path,-1);return(path=normalizeArray(filter(path.split("/"),function(p){return!!p}),!isAbsolute).join("/"))||isAbsolute||(path="."),path&&trailingSlash&&(path+="/"),(isAbsolute?"/":"")+path},exports.isAbsolute=function(path){return"/"===path.charAt(0)},exports.join=function(){var paths=Array.prototype.slice.call(arguments,0);return exports.normalize(filter(paths,function(p,index){if("string"!=typeof p)throw new TypeError("Arguments to path.join must be strings");return p}).join("/"))},exports.relative=function(from,to){function trim(arr){for(var start=0;start<arr.length&&""===arr[start];start++);for(var end=arr.length-1;0<=end&&""===arr[end];end--);return end<start?[]:arr.slice(start,end-start+1)}from=exports.resolve(from).substr(1),to=exports.resolve(to).substr(1);for(var fromParts=trim(from.split("/")),toParts=trim(to.split("/")),length=Math.min(fromParts.length,toParts.length),samePartsLength=length,i=0;i<length;i++)if(fromParts[i]!==toParts[i]){samePartsLength=i;break}var outputParts=[];for(i=samePartsLength;i<fromParts.length;i++)outputParts.push("..");return(outputParts=outputParts.concat(toParts.slice(samePartsLength))).join("/")},exports.sep="/",exports.delimiter=":",exports.dirname=function(path){var result=splitPath(path),root=result[0],dir=result[1];return root||dir?(dir&&(dir=dir.substr(0,dir.length-1)),root+dir):"."},exports.basename=function(path,ext){var f=splitPath(path)[2];return ext&&f.substr(-1*ext.length)===ext&&(f=f.substr(0,f.length-ext.length)),f},exports.extname=function(path){return splitPath(path)[3]};var substr="b"==="ab".substr(-1)?function(str,start,len){return str.substr(start,len)}:function(str,start,len){return start<0&&(start=str.length+start),str.substr(start,len)}}).call(this,require("_process"))},{_process:103}],103:[function(require,module,exports){var cachedSetTimeout,cachedClearTimeout,process=module.exports={};function defaultSetTimout(){throw new Error("setTimeout has not been defined")}function defaultClearTimeout(){throw new Error("clearTimeout has not been defined")}function runTimeout(fun){if(cachedSetTimeout===setTimeout)return setTimeout(fun,0);if((cachedSetTimeout===defaultSetTimout||!cachedSetTimeout)&&setTimeout)return cachedSetTimeout=setTimeout,setTimeout(fun,0);try{return cachedSetTimeout(fun,0)}catch(e){try{return cachedSetTimeout.call(null,fun,0)}catch(e){return cachedSetTimeout.call(this,fun,0)}}}!function(){try{cachedSetTimeout="function"==typeof setTimeout?setTimeout:defaultSetTimout}catch(e){cachedSetTimeout=defaultSetTimout}try{cachedClearTimeout="function"==typeof clearTimeout?clearTimeout:defaultClearTimeout}catch(e){cachedClearTimeout=defaultClearTimeout}}();var currentQueue,queue=[],draining=!1,queueIndex=-1;function cleanUpNextTick(){draining&&currentQueue&&(draining=!1,currentQueue.length?queue=currentQueue.concat(queue):queueIndex=-1,queue.length&&drainQueue())}function drainQueue(){if(!draining){var timeout=runTimeout(cleanUpNextTick);draining=!0;for(var len=queue.length;len;){for(currentQueue=queue,queue=[];++queueIndex<len;)currentQueue&&currentQueue[queueIndex].run();queueIndex=-1,len=queue.length}currentQueue=null,draining=!1,function(marker){if(cachedClearTimeout===clearTimeout)return clearTimeout(marker);if((cachedClearTimeout===defaultClearTimeout||!cachedClearTimeout)&&clearTimeout)return cachedClearTimeout=clearTimeout,clearTimeout(marker);try{cachedClearTimeout(marker)}catch(e){try{return cachedClearTimeout.call(null,marker)}catch(e){return cachedClearTimeout.call(this,marker)}}}(timeout)}}function Item(fun,array){this.fun=fun,this.array=array}function noop(){}process.nextTick=function(fun){var args=new Array(arguments.length-1);if(1<arguments.length)for(var i=1;i<arguments.length;i++)args[i-1]=arguments[i];queue.push(new Item(fun,args)),1!==queue.length||draining||runTimeout(drainQueue)},Item.prototype.run=function(){this.fun.apply(null,this.array)},process.title="browser",process.browser=!0,process.env={},process.argv=[],process.version="",process.versions={},process.on=noop,process.addListener=noop,process.once=noop,process.off=noop,process.removeListener=noop,process.removeAllListeners=noop,process.emit=noop,process.prependListener=noop,process.prependOnceListener=noop,process.listeners=function(name){return[]},process.binding=function(name){throw new Error("process.binding is not supported")},process.cwd=function(){return"/"},process.chdir=function(dir){throw new Error("process.chdir is not supported")},process.umask=function(){return 0}},{}],104:[function(require,module,exports){!function(){var utils=require("./utils.js").Utils,LINE_TYPE={INSERTS:"d2h-ins",DELETES:"d2h-del",INSERT_CHANGES:"d2h-ins d2h-change",DELETE_CHANGES:"d2h-del d2h-change",CONTEXT:"d2h-cntx",INFO:"d2h-info"};function DiffParser(){}function getExtension(filename,language){var nameSplit=filename.split(".");return 1<nameSplit.length?nameSplit[nameSplit.length-1]:language}function _getFilename(linePrefix,line,extraPrefix){var filename,prefixes=["a/","b/","i/","w/","c/","o/"];extraPrefix&&prefixes.push(extraPrefix);var values=(linePrefix?new RegExp("^"+linePrefix+' "?(.+?)"?$'):new RegExp('^"?(.+?)"?$')).exec(line);if(values&&values[1]){filename=values[1];var matchingPrefixes=prefixes.filter(function(p){return 0===filename.indexOf(p)});matchingPrefixes[0]&&(filename=filename.slice(matchingPrefixes[0].length)),filename=filename.replace(/\s+\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}(?:\.\d+)? [-+]\d{4}.*$/,"")}return filename}DiffParser.prototype.LINE_TYPE=LINE_TYPE,DiffParser.prototype.generateDiffJson=function(diffInput,configuration){var possibleOldName,possibleNewName,config=configuration||{},files=[],currentFile=null,currentBlock=null,oldLine=null,oldLine2=null,newLine=null;function saveBlock(){currentBlock&&(currentFile.blocks.push(currentBlock),currentBlock=null)}function saveFile(){currentFile&&(currentFile.oldName||(currentFile.oldName=possibleOldName),currentFile.newName||(currentFile.newName=possibleNewName),currentFile.newName&&(files.push(currentFile),currentFile=null)),possibleNewName=possibleOldName=void 0}function startFile(){saveBlock(),saveFile(),currentFile={blocks:[],deletedLines:0,addedLines:0}}function startBlock(line){var values;saveBlock(),(values=/^@@ -(\d+)(?:,\d+)? \+(\d+)(?:,\d+)? @@.*/.exec(line))?(currentFile.isCombined=!1,oldLine=values[1],newLine=values[2]):(values=/^@@@ -(\d+)(?:,\d+)? -(\d+)(?:,\d+)? \+(\d+)(?:,\d+)? @@@.*/.exec(line))?(currentFile.isCombined=!0,oldLine=values[1],oldLine2=values[2],newLine=values[3]):(utils.startsWith(line,"@@")&&console.error("Failed to parse lines, starting in 0!"),newLine=oldLine=0,currentFile.isCombined=!1),(currentBlock={lines:[]}).oldStartLine=oldLine,currentBlock.oldStartLine2=oldLine2,currentBlock.newStartLine=newLine,currentBlock.header=line}var diffLines=diffInput.replace(/\\ No newline at end of file/g,"").replace(/\r\n?/g,"\n").split("\n"),oldMode=/^old mode (\d{6})/,newMode=/^new mode (\d{6})/,deletedFileMode=/^deleted file mode (\d{6})/,newFileMode=/^new file mode (\d{6})/,copyFrom=/^copy from "?(.+)"?/,copyTo=/^copy to "?(.+)"?/,renameFrom=/^rename from "?(.+)"?/,renameTo=/^rename to "?(.+)"?/,similarityIndex=/^similarity index (\d+)%/,dissimilarityIndex=/^dissimilarity index (\d+)%/,index=/^index ([0-9a-z]+)\.\.([0-9a-z]+)\s*(\d{6})?/,binaryFiles=/^Binary files (.*) and (.*) differ/,binaryDiff=/^GIT binary patch/,combinedIndex=/^index ([0-9a-z]+),([0-9a-z]+)\.\.([0-9a-z]+)/,combinedMode=/^mode (\d{6}),(\d{6})\.\.(\d{6})/,combinedNewFile=/^new file mode (\d{6})/,combinedDeletedFile=/^deleted file mode (\d{6}),(\d{6})/;return diffLines.forEach(function(line,lineIndex){if(line&&!utils.startsWith(line,"*")){var values,prevLine=diffLines[lineIndex-1],nxtLine=diffLines[lineIndex+1],afterNxtLine=diffLines[lineIndex+2];if(utils.startsWith(line,"diff")){startFile();return(values=/^diff --git "?(.+)"? "?(.+)"?/.exec(line))&&(possibleOldName=_getFilename(null,values[1],config.dstPrefix),possibleNewName=_getFilename(null,values[2],config.srcPrefix)),void(currentFile.isGitDiff=!0)}if((!currentFile||!currentFile.isGitDiff&&currentFile&&utils.startsWith(line,"--- ")&&utils.startsWith(nxtLine,"+++ ")&&utils.startsWith(afterNxtLine,"@@"))&&startFile(),utils.startsWith(line,"--- ")&&utils.startsWith(nxtLine,"+++ ")||utils.startsWith(line,"+++ ")&&utils.startsWith(prevLine,"--- ")){if(currentFile&&!currentFile.oldName&&utils.startsWith(line,"--- ")&&(values=function(line,cfg){return _getFilename("---",line,cfg.srcPrefix)}(line,config)))return currentFile.oldName=values,void(currentFile.language=getExtension(currentFile.oldName,currentFile.language));if(currentFile&&!currentFile.newName&&utils.startsWith(line,"+++ ")&&(values=function(line,cfg){return _getFilename("\\+\\+\\+",line,cfg.dstPrefix)}(line,config)))return currentFile.newName=values,void(currentFile.language=getExtension(currentFile.newName,currentFile.language))}if(currentFile&&utils.startsWith(line,"@@")||currentFile.isGitDiff&&currentFile&&currentFile.oldName&&currentFile.newName&&!currentBlock)startBlock(line);else if(currentBlock&&(utils.startsWith(line,"+")||utils.startsWith(line,"-")||utils.startsWith(line," ")))!function(line){var currentLine={};currentLine.content=line;var newLinePrefixes=currentFile.isCombined?["+"," +"]:["+"],delLinePrefixes=currentFile.isCombined?["-"," -"]:["-"];utils.startsWith(line,newLinePrefixes)?(currentFile.addedLines++,currentLine.type=LINE_TYPE.INSERTS,currentLine.oldNumber=null,currentLine.newNumber=newLine++):utils.startsWith(line,delLinePrefixes)?(currentFile.deletedLines++,currentLine.type=LINE_TYPE.DELETES,currentLine.oldNumber=oldLine++,currentLine.newNumber=null):(currentLine.type=LINE_TYPE.CONTEXT,currentLine.oldNumber=oldLine++,currentLine.newNumber=newLine++),currentBlock.lines.push(currentLine)}(line);else{var doesNotExistHunkHeader=!function(line,lineIdx){for(var idx=lineIdx;idx<diffLines.length-3;){if(utils.startsWith(line,"diff"))return!1;if(utils.startsWith(diffLines[idx],"--- ")&&utils.startsWith(diffLines[idx+1],"+++ ")&&utils.startsWith(diffLines[idx+2],"@@"))return!0;idx++}return!1}(line,lineIndex);(values=oldMode.exec(line))?currentFile.oldMode=values[1]:(values=newMode.exec(line))?currentFile.newMode=values[1]:(values=deletedFileMode.exec(line))?(currentFile.deletedFileMode=values[1],currentFile.isDeleted=!0):(values=newFileMode.exec(line))?(currentFile.newFileMode=values[1],currentFile.isNew=!0):(values=copyFrom.exec(line))?(doesNotExistHunkHeader&&(currentFile.oldName=values[1]),currentFile.isCopy=!0):(values=copyTo.exec(line))?(doesNotExistHunkHeader&&(currentFile.newName=values[1]),currentFile.isCopy=!0):(values=renameFrom.exec(line))?(doesNotExistHunkHeader&&(currentFile.oldName=values[1]),currentFile.isRename=!0):(values=renameTo.exec(line))?(doesNotExistHunkHeader&&(currentFile.newName=values[1]),currentFile.isRename=!0):(values=binaryFiles.exec(line))?(currentFile.isBinary=!0,currentFile.oldName=_getFilename(null,values[1],config.srcPrefix),currentFile.newName=_getFilename(null,values[2],config.dstPrefix),startBlock("Binary file")):(values=binaryDiff.exec(line))?(currentFile.isBinary=!0,startBlock(line)):(values=similarityIndex.exec(line))?currentFile.unchangedPercentage=values[1]:(values=dissimilarityIndex.exec(line))?currentFile.changedPercentage=values[1]:(values=index.exec(line))?(currentFile.checksumBefore=values[1],currentFile.checksumAfter=values[2],values[3]&&(currentFile.mode=values[3])):(values=combinedIndex.exec(line))?(currentFile.checksumBefore=[values[2],values[3]],currentFile.checksumAfter=values[1]):(values=combinedMode.exec(line))?(currentFile.oldMode=[values[2],values[3]],currentFile.newMode=values[1]):(values=combinedNewFile.exec(line))?(currentFile.newFileMode=values[1],currentFile.isNew=!0):(values=combinedDeletedFile.exec(line))&&(currentFile.deletedFileMode=values[1],currentFile.isDeleted=!0)}}}),saveBlock(),saveFile(),files},module.exports.DiffParser=new DiffParser}()},{"./utils.js":114}],105:[function(require,module,exports){(function(global){!function(){var diffParser=require("./diff-parser.js").DiffParser,htmlPrinter=require("./html-printer.js").HtmlPrinter,utils=require("./utils.js").Utils;function Diff2Html(){}var defaultConfig={wordByWord:!0,outputFormat:"line-by-line",matching:"none",matchWordsThreshold:.25,matchingMaxComparisons:2500,maxLineLengthHighlight:1e4};Diff2Html.prototype.getJsonFromDiff=function(diffInput,config){var cfg=utils.safeConfig(config,defaultConfig);return diffParser.generateDiffJson(diffInput,cfg)},Diff2Html.prototype.getPrettyHtml=function(diffInput,config){var cfg=utils.safeConfig(config,defaultConfig),diffJson=diffInput;cfg.inputFormat&&"diff"!==cfg.inputFormat||(diffJson=diffParser.generateDiffJson(diffInput,cfg));var fileList="";!0===cfg.showFiles&&(fileList=htmlPrinter.generateFileListSummary(diffJson,cfg));return fileList+("side-by-side"===cfg.outputFormat?htmlPrinter.generateSideBySideJsonHtml(diffJson,cfg):htmlPrinter.generateLineByLineJsonHtml(diffJson,cfg))},Diff2Html.prototype.getPrettyHtmlFromDiff=function(diffInput,config){var cfg=utils.safeConfig(config,defaultConfig);return cfg.inputFormat="diff",cfg.outputFormat="line-by-line",this.getPrettyHtml(diffInput,cfg)},Diff2Html.prototype.getPrettyHtmlFromJson=function(diffJson,config){var cfg=utils.safeConfig(config,defaultConfig);return cfg.inputFormat="json",cfg.outputFormat="line-by-line",this.getPrettyHtml(diffJson,cfg)},Diff2Html.prototype.getPrettySideBySideHtmlFromDiff=function(diffInput,config){var cfg=utils.safeConfig(config,defaultConfig);return cfg.inputFormat="diff",cfg.outputFormat="side-by-side",this.getPrettyHtml(diffInput,cfg)},Diff2Html.prototype.getPrettySideBySideHtmlFromJson=function(diffJson,config){var cfg=utils.safeConfig(config,defaultConfig);return cfg.inputFormat="json",cfg.outputFormat="side-by-side",this.getPrettyHtml(diffJson,cfg)};var diffObject=new Diff2Html;module.exports.Diff2Html=diffObject,global.Diff2Html=diffObject}()}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./diff-parser.js":104,"./html-printer.js":108,"./utils.js":114}],106:[function(require,module,exports){!function(){var hoganUtils,printerUtils=require("./printer-utils.js").PrinterUtils;function FileListPrinter(config){this.config=config;var HoganJsUtils=require("./hoganjs-utils.js").HoganJsUtils;hoganUtils=new HoganJsUtils(config)}FileListPrinter.prototype.generateFileList=function(diffFiles){var lineTemplate=hoganUtils.template("file-summary","line"),files=diffFiles.map(function(file){var fileTypeName=printerUtils.getFileTypeIcon(file),iconTemplate=hoganUtils.template("icon",fileTypeName);return lineTemplate.render({fileHtmlId:printerUtils.getHtmlId(file),fileName:printerUtils.getDiffName(file),deletedLines:"-"+file.deletedLines,addedLines:"+"+file.addedLines},{fileIcon:iconTemplate})}).join("\n");return hoganUtils.render("file-summary","wrapper",{filesNumber:diffFiles.length,files:files})},module.exports.FileListPrinter=FileListPrinter}()},{"./hoganjs-utils.js":107,"./printer-utils.js":110}],107:[function(require,module,exports){(function(__dirname){!function(){var extraTemplates,fs=require("fs"),path=require("path"),hogan=require("hogan.js"),hoganTemplates=require("./templates/diff2html-templates.js");function HoganJsUtils(configuration){this.config=configuration||{},extraTemplates=this.config.templates||{};var rawTemplates=this.config.rawTemplates||{};for(var templateName in rawTemplates)rawTemplates.hasOwnProperty(templateName)&&(extraTemplates[templateName]||(extraTemplates[templateName]=this.compile(rawTemplates[templateName])))}HoganJsUtils.prototype.render=function(namespace,view,params){var template=this.template(namespace,view);return template?template.render(params):null},HoganJsUtils.prototype.template=function(namespace,view){var templateKey=this._templateKey(namespace,view);return this._getTemplate(templateKey)},HoganJsUtils.prototype._getTemplate=function(templateKey){var template;return this.config.noCache||(template=this._readFromCache(templateKey)),template||(template=this._loadTemplate(templateKey)),template},HoganJsUtils.prototype._loadTemplate=function(templateKey){var template;try{if(fs.readFileSync){var templatesPath=path.resolve(__dirname,"templates"),templatePath=path.join(templatesPath,templateKey),templateContent=fs.readFileSync(templatePath+".mustache","utf8");template=hogan.compile(templateContent),hoganTemplates[templateKey]=template}}catch(e){console.error("Failed to read (template: "+templateKey+") from fs: "+e.message)}return template},HoganJsUtils.prototype._readFromCache=function(templateKey){return extraTemplates[templateKey]||hoganTemplates[templateKey]},HoganJsUtils.prototype._templateKey=function(namespace,view){return namespace+"-"+view},HoganJsUtils.prototype.compile=function(templateStr){return hogan.compile(templateStr)},module.exports.HoganJsUtils=HoganJsUtils}()}).call(this,"/src")},{"./templates/diff2html-templates.js":113,fs:1,"hogan.js":4,path:102}],108:[function(require,module,exports){!function(){var LineByLinePrinter=require("./line-by-line-printer.js").LineByLinePrinter,SideBySidePrinter=require("./side-by-side-printer.js").SideBySidePrinter,FileListPrinter=require("./file-list-printer.js").FileListPrinter;function HtmlPrinter(){}HtmlPrinter.prototype.generateLineByLineJsonHtml=function(diffFiles,config){return new LineByLinePrinter(config).generateLineByLineJsonHtml(diffFiles)},HtmlPrinter.prototype.generateSideBySideJsonHtml=function(diffFiles,config){return new SideBySidePrinter(config).generateSideBySideJsonHtml(diffFiles)},HtmlPrinter.prototype.generateFileListSummary=function(diffJson,config){return new FileListPrinter(config).generateFileList(diffJson)},module.exports.HtmlPrinter=new HtmlPrinter}()},{"./file-list-printer.js":106,"./line-by-line-printer.js":109,"./side-by-side-printer.js":112}],109:[function(require,module,exports){!function(){var hoganUtils,diffParser=require("./diff-parser.js").DiffParser,printerUtils=require("./printer-utils.js").PrinterUtils,utils=require("./utils.js").Utils,Rematch=require("./rematch.js").Rematch;function LineByLinePrinter(config){this.config=config;var HoganJsUtils=require("./hoganjs-utils.js").HoganJsUtils;hoganUtils=new HoganJsUtils(config)}LineByLinePrinter.prototype.makeFileDiffHtml=function(file,diffs){var fileDiffTemplate=hoganUtils.template("line-by-line","file-diff"),filePathTemplate=hoganUtils.template("generic","file-path"),fileIconTemplate=hoganUtils.template("icon","file"),fileTagTemplate=hoganUtils.template("tag",printerUtils.getFileTypeIcon(file));return fileDiffTemplate.render({file:file,fileHtmlId:printerUtils.getHtmlId(file),diffs:diffs,filePath:filePathTemplate.render({fileDiffName:printerUtils.getDiffName(file)},{fileIcon:fileIconTemplate,fileTag:fileTagTemplate})})},LineByLinePrinter.prototype.makeLineByLineHtmlWrapper=function(content){return hoganUtils.render("generic","wrapper",{content:content})},LineByLinePrinter.prototype.generateLineByLineJsonHtml=function(diffFiles){var that=this,htmlDiffs=diffFiles.map(function(file){var diffs;return diffs=file.blocks.length?that._generateFileHtml(file):that._generateEmptyDiff(),that.makeFileDiffHtml(file,diffs)});return this.makeLineByLineHtmlWrapper(htmlDiffs.join("\n"))};var matcher=Rematch.rematch(function(a,b){var amod=a.content.substr(1),bmod=b.content.substr(1);return Rematch.distance(amod,bmod)});LineByLinePrinter.prototype.makeColumnLineNumberHtml=function(block){return hoganUtils.render("generic","column-line-number",{diffParser:diffParser,blockHeader:utils.escape(block.header),lineClass:"d2h-code-linenumber",contentClass:"d2h-code-line"})},LineByLinePrinter.prototype._generateFileHtml=function(file){var that=this;return file.blocks.map(function(block){var lines=that.makeColumnLineNumberHtml(block),oldLines=[],newLines=[];function processChangeBlock(){var matches,insertType,deleteType;oldLines.length*newLines.length<(that.config.matchingMaxComparisons||2500)&&("lines"===that.config.matching||"words"===that.config.matching)?(matches=matcher(oldLines,newLines),insertType=diffParser.LINE_TYPE.INSERT_CHANGES,deleteType=diffParser.LINE_TYPE.DELETE_CHANGES):(matches=[[oldLines,newLines]],insertType=diffParser.LINE_TYPE.INSERTS,deleteType=diffParser.LINE_TYPE.DELETES),matches.forEach(function(match){oldLines=match[0],newLines=match[1];for(var oldLine,newLine,processedOldLines=[],processedNewLines=[],common=Math.min(oldLines.length,newLines.length),j=0;j<common;j++){oldLine=oldLines[j],newLine=newLines[j],that.config.isCombined=file.isCombined;var diff=printerUtils.diffHighlight(oldLine.content,newLine.content,that.config);processedOldLines+=that.makeLineHtml(file.isCombined,deleteType,oldLine.oldNumber,oldLine.newNumber,diff.first.line,diff.first.prefix),processedNewLines+=that.makeLineHtml(file.isCombined,insertType,newLine.oldNumber,newLine.newNumber,diff.second.line,diff.second.prefix)}lines+=processedOldLines+processedNewLines,lines+=that._processLines(file.isCombined,oldLines.slice(common),newLines.slice(common))}),oldLines=[],newLines=[]}for(var i=0;i<block.lines.length;i++){var line=block.lines[i],escapedLine=utils.escape(line.content);line.type!==diffParser.LINE_TYPE.INSERTS&&(0<newLines.length||line.type!==diffParser.LINE_TYPE.DELETES&&0<oldLines.length)&&processChangeBlock(),line.type===diffParser.LINE_TYPE.CONTEXT?lines+=that.makeLineHtml(file.isCombined,line.type,line.oldNumber,line.newNumber,escapedLine):line.type!==diffParser.LINE_TYPE.INSERTS||oldLines.length?line.type===diffParser.LINE_TYPE.DELETES?oldLines.push(line):line.type===diffParser.LINE_TYPE.INSERTS&&Boolean(oldLines.length)?newLines.push(line):(console.error("Unknown state in html line-by-line generator"),processChangeBlock()):lines+=that.makeLineHtml(file.isCombined,line.type,line.oldNumber,line.newNumber,escapedLine)}return processChangeBlock(),lines}).join("\n")},LineByLinePrinter.prototype._processLines=function(isCombined,oldLines,newLines){for(var lines="",i=0;i<oldLines.length;i++){var oldLine=oldLines[i],oldEscapedLine=utils.escape(oldLine.content);lines+=this.makeLineHtml(isCombined,oldLine.type,oldLine.oldNumber,oldLine.newNumber,oldEscapedLine)}for(var j=0;j<newLines.length;j++){var newLine=newLines[j],newEscapedLine=utils.escape(newLine.content);lines+=this.makeLineHtml(isCombined,newLine.type,newLine.oldNumber,newLine.newNumber,newEscapedLine)}return lines},LineByLinePrinter.prototype.makeLineHtml=function(isCombined,type,oldNumber,newNumber,content,possiblePrefix){var lineNumberTemplate=hoganUtils.render("line-by-line","numbers",{oldNumber:utils.valueOrEmpty(oldNumber),newNumber:utils.valueOrEmpty(newNumber)}),lineWithoutPrefix=content,prefix=possiblePrefix;if(!prefix){var lineWithPrefix=printerUtils.separatePrefix(isCombined,content);prefix=lineWithPrefix.prefix,lineWithoutPrefix=lineWithPrefix.line}return hoganUtils.render("generic","line",{type:type,lineClass:"d2h-code-linenumber",contentClass:"d2h-code-line",prefix:prefix,content:lineWithoutPrefix,lineNumber:lineNumberTemplate})},LineByLinePrinter.prototype._generateEmptyDiff=function(){return hoganUtils.render("generic","empty-diff",{contentClass:"d2h-code-line",diffParser:diffParser})},module.exports.LineByLinePrinter=LineByLinePrinter}()},{"./diff-parser.js":104,"./hoganjs-utils.js":107,"./printer-utils.js":110,"./rematch.js":111,"./utils.js":114}],110:[function(require,module,exports){!function(){var jsDiff=require("diff"),utils=require("./utils.js").Utils,Rematch=require("./rematch.js").Rematch;function PrinterUtils(){}function unifyPath(path){return path?path.replace("\\","/"):path}function isDevNullName(name){return-1!==name.indexOf("dev/null")}PrinterUtils.prototype.separatePrefix=function(isCombined,line){var prefix,lineWithoutPrefix;return isCombined?(prefix=line.substring(0,2),lineWithoutPrefix=line.substring(2)):(prefix=line.substring(0,1),lineWithoutPrefix=line.substring(1)),{prefix:prefix,line:lineWithoutPrefix}},PrinterUtils.prototype.getHtmlId=function(file){return"d2h-"+function(text){var i,len,hash=0;for(i=0,len=text.length;i<len;i++)hash=(hash<<5)-hash+text.charCodeAt(i),hash|=0;return hash}(this.getDiffName(file)).toString().slice(-6)},PrinterUtils.prototype.getDiffName=function(file){var oldFilename=unifyPath(file.oldName),newFilename=unifyPath(file.newName);if(oldFilename&&newFilename&&oldFilename!==newFilename&&!isDevNullName(oldFilename)&&!isDevNullName(newFilename)){for(var prefixPaths=[],suffixPaths=[],oldFilenameParts=oldFilename.split("/"),newFilenameParts=newFilename.split("/"),i=0,j=oldFilenameParts.length-1,k=newFilenameParts.length-1;i<j&&i<k&&oldFilenameParts[i]===newFilenameParts[i];)prefixPaths.push(newFilenameParts[i]),i+=1;for(;i<j&&i<k&&oldFilenameParts[j]===newFilenameParts[k];)suffixPaths.unshift(newFilenameParts[k]),j-=1,k-=1;var finalPrefix=prefixPaths.join("/"),finalSuffix=suffixPaths.join("/"),oldRemainingPath=oldFilenameParts.slice(i,j+1).join("/"),newRemainingPath=newFilenameParts.slice(i,k+1).join("/");return finalPrefix.length&&finalSuffix.length?finalPrefix+"/{"+oldRemainingPath+" → "+newRemainingPath+"}/"+finalSuffix:finalPrefix.length?finalPrefix+"/{"+oldRemainingPath+" → "+newRemainingPath+"}":finalSuffix.length?"{"+oldRemainingPath+" → "+newRemainingPath+"}/"+finalSuffix:oldFilename+" → "+newFilename}return newFilename&&!isDevNullName(newFilename)?newFilename:oldFilename||"unknown/file/path"},PrinterUtils.prototype.getFileTypeIcon=function(file){var templateName="file-changed";return file.isRename?templateName="file-renamed":file.isCopy?templateName="file-renamed":file.isNew?templateName="file-added":file.isDeleted?templateName="file-deleted":file.newName!==file.oldName&&(templateName="file-renamed"),templateName},PrinterUtils.prototype.diffHighlight=function(diffLine1,diffLine2,config){var linePrefix1,linePrefix2,unprefixedLine1,unprefixedLine2,diff,prefixSize=1;if(config.isCombined&&(prefixSize=2),linePrefix1=diffLine1.substr(0,prefixSize),linePrefix2=diffLine2.substr(0,prefixSize),unprefixedLine1=diffLine1.substr(prefixSize),unprefixedLine2=diffLine2.substr(prefixSize),unprefixedLine1.length>config.maxLineLengthHighlight||unprefixedLine2.length>config.maxLineLengthHighlight)return{first:{prefix:linePrefix1,line:utils.escape(unprefixedLine1)},second:{prefix:linePrefix2,line:utils.escape(unprefixedLine2)}};diff=config.charByChar?jsDiff.diffChars(unprefixedLine1,unprefixedLine2):jsDiff.diffWordsWithSpace(unprefixedLine1,unprefixedLine2);var line,highlightedLine="",changedWords=[];if(!config.charByChar&&"words"===config.matching){var treshold=.25;void 0!==config.matchWordsThreshold&&(treshold=config.matchWordsThreshold);var matcher=Rematch.rematch(function(a,b){var amod=a.value,bmod=b.value;return Rematch.distance(amod,bmod)}),removed=diff.filter(function(element){return element.removed});matcher(diff.filter(function(element){return element.added}),removed).forEach(function(chunk){1===chunk[0].length&&1===chunk[1].length&&(Rematch.distance(chunk[0][0].value,chunk[1][0].value)<treshold&&(changedWords.push(chunk[0][0]),changedWords.push(chunk[1][0])))})}return diff.forEach(function(part){var addClass=-1<changedWords.indexOf(part)?' class="d2h-change"':"",elemType=part.added?"ins":part.removed?"del":null,escapedValue=utils.escape(part.value);highlightedLine+=null!==elemType?"<"+elemType+addClass+">"+escapedValue+"</"+elemType+">":escapedValue}),{first:{prefix:linePrefix1,line:(line=highlightedLine,line.replace(/(<ins[^>]*>((.|\n)*?)<\/ins>)/g,""))},second:{prefix:linePrefix2,line:function(line){return line.replace(/(<del[^>]*>((.|\n)*?)<\/del>)/g,"")}(highlightedLine)}}},module.exports.PrinterUtils=new PrinterUtils}()},{"./rematch.js":111,"./utils.js":114,diff:2}],111:[function(require,module,exports){!function(){var Rematch={};function levenshtein(a,b){if(0===a.length)return b.length;if(0===b.length)return a.length;var i,j,matrix=[];for(i=0;i<=b.length;i++)matrix[i]=[i];for(j=0;j<=a.length;j++)matrix[0][j]=j;for(i=1;i<=b.length;i++)for(j=1;j<=a.length;j++)b.charAt(i-1)===a.charAt(j-1)?matrix[i][j]=matrix[i-1][j-1]:matrix[i][j]=Math.min(matrix[i-1][j-1]+1,Math.min(matrix[i][j-1]+1,matrix[i-1][j]+1));return matrix[b.length][a.length]}Rematch.levenshtein=levenshtein,Rematch.distance=function(x,y){return levenshtein(x=x.trim(),y=y.trim())/(x.length+y.length)},Rematch.rematch=function(distanceFunction){return function group(a,b,level,cache){void 0===cache&&(cache={});var bm=function(a,b,cache){for(var bestMatch,bestMatchDist=1/0,i=0;i<a.length;++i)for(var j=0;j<b.length;++j){var md,cacheKey=JSON.stringify([a[i],b[j]]);cache.hasOwnProperty(cacheKey)?md=cache[cacheKey]:(md=distanceFunction(a[i],b[j]),cache[cacheKey]=md),md<bestMatchDist&&(bestMatch={indexA:i,indexB:j,score:bestMatchDist=md})}return bestMatch}(a,b,cache);if(level||(level=0),!bm||a.length+b.length<3)return[[a,b]];var a1=a.slice(0,bm.indexA),b1=b.slice(0,bm.indexB),aMatch=[a[bm.indexA]],bMatch=[b[bm.indexB]],tailA=bm.indexA+1,tailB=bm.indexB+1,a2=a.slice(tailA),b2=b.slice(tailB),group1=group(a1,b1,level+1,cache),groupMatch=group(aMatch,bMatch,level+1,cache),group2=group(a2,b2,level+1,cache),result=groupMatch;return(0<bm.indexA||0<bm.indexB)&&(result=group1.concat(result)),(a.length>tailA||b.length>tailB)&&(result=result.concat(group2)),result}},module.exports.Rematch=Rematch}()},{}],112:[function(require,module,exports){!function(){var hoganUtils,diffParser=require("./diff-parser.js").DiffParser,printerUtils=require("./printer-utils.js").PrinterUtils,utils=require("./utils.js").Utils,Rematch=require("./rematch.js").Rematch,matcher=Rematch.rematch(function(a,b){var amod=a.content.substr(1),bmod=b.content.substr(1);return Rematch.distance(amod,bmod)});function SideBySidePrinter(config){this.config=config;var HoganJsUtils=require("./hoganjs-utils.js").HoganJsUtils;hoganUtils=new HoganJsUtils(config)}SideBySidePrinter.prototype.makeDiffHtml=function(file,diffs){var fileDiffTemplate=hoganUtils.template("side-by-side","file-diff"),filePathTemplate=hoganUtils.template("generic","file-path"),fileIconTemplate=hoganUtils.template("icon","file"),fileTagTemplate=hoganUtils.template("tag",printerUtils.getFileTypeIcon(file));return fileDiffTemplate.render({file:file,fileHtmlId:printerUtils.getHtmlId(file),diffs:diffs,filePath:filePathTemplate.render({fileDiffName:printerUtils.getDiffName(file)},{fileIcon:fileIconTemplate,fileTag:fileTagTemplate})})},SideBySidePrinter.prototype.generateSideBySideJsonHtml=function(diffFiles){var that=this,content=diffFiles.map(function(file){var diffs;return diffs=file.blocks.length?that.generateSideBySideFileHtml(file):that.generateEmptyDiff(),that.makeDiffHtml(file,diffs)}).join("\n");return hoganUtils.render("generic","wrapper",{content:content})},SideBySidePrinter.prototype.makeSideHtml=function(blockHeader){return hoganUtils.render("generic","column-line-number",{diffParser:diffParser,blockHeader:utils.escape(blockHeader),lineClass:"d2h-code-side-linenumber",contentClass:"d2h-code-side-line"})},SideBySidePrinter.prototype.generateSideBySideFileHtml=function(file){var that=this,fileHtml={left:"",right:""};return file.blocks.forEach(function(block){fileHtml.left+=that.makeSideHtml(block.header),fileHtml.right+=that.makeSideHtml("");var oldLines=[],newLines=[];function processChangeBlock(){var matches,insertType,deleteType;oldLines.length*newLines.length<(that.config.matchingMaxComparisons||2500)&&("lines"===that.config.matching||"words"===that.config.matching)?(matches=matcher(oldLines,newLines),insertType=diffParser.LINE_TYPE.INSERT_CHANGES,deleteType=diffParser.LINE_TYPE.DELETE_CHANGES):(matches=[[oldLines,newLines]],insertType=diffParser.LINE_TYPE.INSERTS,deleteType=diffParser.LINE_TYPE.DELETES),matches.forEach(function(match){oldLines=match[0],newLines=match[1];for(var common=Math.min(oldLines.length,newLines.length),max=Math.max(oldLines.length,newLines.length),j=0;j<common;j++){var oldLine=oldLines[j],newLine=newLines[j];that.config.isCombined=file.isCombined;var diff=printerUtils.diffHighlight(oldLine.content,newLine.content,that.config);fileHtml.left+=that.generateSingleLineHtml(file.isCombined,deleteType,oldLine.oldNumber,diff.first.line,diff.first.prefix),fileHtml.right+=that.generateSingleLineHtml(file.isCombined,insertType,newLine.newNumber,diff.second.line,diff.second.prefix)}if(common<max){var oldSlice=oldLines.slice(common),newSlice=newLines.slice(common),tmpHtml=that.processLines(file.isCombined,oldSlice,newSlice);fileHtml.left+=tmpHtml.left,fileHtml.right+=tmpHtml.right}}),oldLines=[],newLines=[]}for(var i=0;i<block.lines.length;i++){var line=block.lines[i],prefix=line.content[0],escapedLine=utils.escape(line.content.substr(1));line.type!==diffParser.LINE_TYPE.INSERTS&&(0<newLines.length||line.type!==diffParser.LINE_TYPE.DELETES&&0<oldLines.length)&&processChangeBlock(),line.type===diffParser.LINE_TYPE.CONTEXT?(fileHtml.left+=that.generateSingleLineHtml(file.isCombined,line.type,line.oldNumber,escapedLine,prefix),fileHtml.right+=that.generateSingleLineHtml(file.isCombined,line.type,line.newNumber,escapedLine,prefix)):line.type!==diffParser.LINE_TYPE.INSERTS||oldLines.length?line.type===diffParser.LINE_TYPE.DELETES?oldLines.push(line):line.type===diffParser.LINE_TYPE.INSERTS&&Boolean(oldLines.length)?newLines.push(line):(console.error("unknown state in html side-by-side generator"),processChangeBlock()):(fileHtml.left+=that.generateSingleLineHtml(file.isCombined,diffParser.LINE_TYPE.CONTEXT,"","",""),fileHtml.right+=that.generateSingleLineHtml(file.isCombined,line.type,line.newNumber,escapedLine,prefix))}processChangeBlock()}),fileHtml},SideBySidePrinter.prototype.processLines=function(isCombined,oldLines,newLines){for(var fileHtml={left:"",right:""},maxLinesNumber=Math.max(oldLines.length,newLines.length),i=0;i<maxLinesNumber;i++){var oldContent,newContent,oldPrefix,newPrefix,oldLine=oldLines[i],newLine=newLines[i];oldLine&&(oldContent=utils.escape(oldLine.content.substr(1)),oldPrefix=oldLine.content[0]),newLine&&(newContent=utils.escape(newLine.content.substr(1)),newPrefix=newLine.content[0]),oldLine&&newLine?(fileHtml.left+=this.generateSingleLineHtml(isCombined,oldLine.type,oldLine.oldNumber,oldContent,oldPrefix),fileHtml.right+=this.generateSingleLineHtml(isCombined,newLine.type,newLine.newNumber,newContent,newPrefix)):oldLine?(fileHtml.left+=this.generateSingleLineHtml(isCombined,oldLine.type,oldLine.oldNumber,oldContent,oldPrefix),fileHtml.right+=this.generateSingleLineHtml(isCombined,diffParser.LINE_TYPE.CONTEXT,"","","")):newLine?(fileHtml.left+=this.generateSingleLineHtml(isCombined,diffParser.LINE_TYPE.CONTEXT,"","",""),fileHtml.right+=this.generateSingleLineHtml(isCombined,newLine.type,newLine.newNumber,newContent,newPrefix)):console.error("How did it get here?")}return fileHtml},SideBySidePrinter.prototype.generateSingleLineHtml=function(isCombined,type,number,content,possiblePrefix){var lineWithoutPrefix=content,prefix=possiblePrefix;if(!prefix){var lineWithPrefix=printerUtils.separatePrefix(isCombined,content);prefix=lineWithPrefix.prefix,lineWithoutPrefix=lineWithPrefix.line}return hoganUtils.render("generic","line",{type:type,lineClass:"d2h-code-side-linenumber",contentClass:"d2h-code-side-line",prefix:prefix,content:lineWithoutPrefix,lineNumber:number})},SideBySidePrinter.prototype.generateEmptyDiff=function(){var fileHtml={right:""};return fileHtml.left=hoganUtils.render("generic","empty-diff",{contentClass:"d2h-code-side-line",diffParser:diffParser}),fileHtml},module.exports.SideBySidePrinter=SideBySidePrinter}()},{"./diff-parser.js":104,"./hoganjs-utils.js":107,"./printer-utils.js":110,"./rematch.js":111,"./utils.js":114}],113:[function(require,module,exports){(function(global){!function(){global.browserTemplates||(global.browserTemplates={});var Hogan=require("hogan.js");global.browserTemplates["file-summary-line"]=new Hogan.Template({code:function(c,p,i){var t=this;return t.b(i=i||""),t.b('<li class="d2h-file-list-line">'),t.b("\n"+i),t.b('    <span class="d2h-file-name-wrapper">'),t.b("\n"+i),t.b("      <span>"),t.b(t.rp("<fileIcon0",c,p,"")),t.b("</span>"),t.b("\n"+i),t.b('      <a href="#'),t.b(t.v(t.f("fileHtmlId",c,p,0))),t.b('" class="d2h-file-name">'),t.b(t.v(t.f("fileName",c,p,0))),t.b("</a>"),t.b("\n"+i),t.b('      <span class="d2h-file-stats">'),t.b("\n"+i),t.b('          <span class="d2h-lines-added">'),t.b(t.v(t.f("addedLines",c,p,0))),t.b("</span>"),t.b("\n"+i),t.b('          <span class="d2h-lines-deleted">'),t.b(t.v(t.f("deletedLines",c,p,0))),t.b("</span>"),t.b("\n"+i),t.b("      </span>"),t.b("\n"+i),t.b("    </span>"),t.b("\n"+i),t.b("</li>"),t.fl()},partials:{"<fileIcon0":{name:"fileIcon",partials:{},subs:{}}},subs:{}}),global.browserTemplates["file-summary-wrapper"]=new Hogan.Template({code:function(c,p,i){var t=this;return t.b(i=i||""),t.b('<div class="d2h-file-list-wrapper">'),t.b("\n"+i),t.b('    <div class="d2h-file-list-header">'),t.b("\n"+i),t.b('        <span class="d2h-file-list-title">Files changed ('),t.b(t.v(t.f("filesNumber",c,p,0))),t.b(")</span>"),t.b("\n"+i),t.b('        <a class="d2h-file-switch d2h-hide">hide</a>'),t.b("\n"+i),t.b('        <a class="d2h-file-switch d2h-show">show</a>'),t.b("\n"+i),t.b("    </div>"),t.b("\n"+i),t.b('    <ol class="d2h-file-list">'),t.b("\n"+i),t.b("    "),t.b(t.t(t.f("files",c,p,0))),t.b("\n"+i),t.b("    </ol>"),t.b("\n"+i),t.b("</div>"),t.fl()},partials:{},subs:{}}),global.browserTemplates["generic-column-line-number"]=new Hogan.Template({code:function(c,p,i){var t=this;return t.b(i=i||""),t.b("<tr>"),t.b("\n"+i),t.b('    <td class="'),t.b(t.v(t.f("lineClass",c,p,0))),t.b(" "),t.b(t.v(t.d("diffParser.LINE_TYPE.INFO",c,p,0))),t.b('"></td>'),t.b("\n"+i),t.b('    <td class="'),t.b(t.v(t.d("diffParser.LINE_TYPE.INFO",c,p,0))),t.b('">'),t.b("\n"+i),t.b('        <div class="'),t.b(t.v(t.f("contentClass",c,p,0))),t.b(" "),t.b(t.v(t.d("diffParser.LINE_TYPE.INFO",c,p,0))),t.b('">'),t.b(t.t(t.f("blockHeader",c,p,0))),t.b("</div>"),t.b("\n"+i),t.b("    </td>"),t.b("\n"+i),t.b("</tr>"),t.fl()},partials:{},subs:{}}),global.browserTemplates["generic-empty-diff"]=new Hogan.Template({code:function(c,p,i){var t=this;return t.b(i=i||""),t.b("<tr>"),t.b("\n"+i),t.b('    <td class="'),t.b(t.v(t.d("diffParser.LINE_TYPE.INFO",c,p,0))),t.b('">'),t.b("\n"+i),t.b('        <div class="'),t.b(t.v(t.f("contentClass",c,p,0))),t.b(" "),t.b(t.v(t.d("diffParser.LINE_TYPE.INFO",c,p,0))),t.b('">'),t.b("\n"+i),t.b("            File without changes"),t.b("\n"+i),t.b("        </div>"),t.b("\n"+i),t.b("    </td>"),t.b("\n"+i),t.b("</tr>"),t.fl()},partials:{},subs:{}}),global.browserTemplates["generic-file-path"]=new Hogan.Template({code:function(c,p,i){var t=this;return t.b(i=i||""),t.b('<span class="d2h-file-name-wrapper">'),t.b("\n"+i),t.b('    <span class="d2h-icon-wrapper">'),t.b(t.rp("<fileIcon0",c,p,"")),t.b("</span>"),t.b("\n"+i),t.b('    <span class="d2h-file-name">'),t.b(t.v(t.f("fileDiffName",c,p,0))),t.b("</span>"),t.b("\n"+i),t.b(t.rp("<fileTag1",c,p,"    ")),t.b("</span>"),t.fl()},partials:{"<fileIcon0":{name:"fileIcon",partials:{},subs:{}},"<fileTag1":{name:"fileTag",partials:{},subs:{}}},subs:{}}),global.browserTemplates["generic-line"]=new Hogan.Template({code:function(c,p,i){var t=this;return t.b(i=i||""),t.b("<tr>"),t.b("\n"+i),t.b('    <td class="'),t.b(t.v(t.f("lineClass",c,p,0))),t.b(" "),t.b(t.v(t.f("type",c,p,0))),t.b('">'),t.b("\n"+i),t.b("      "),t.b(t.t(t.f("lineNumber",c,p,0))),t.b("\n"+i),t.b("    </td>"),t.b("\n"+i),t.b('    <td class="'),t.b(t.v(t.f("type",c,p,0))),t.b('">'),t.b("\n"+i),t.b('        <div class="'),t.b(t.v(t.f("contentClass",c,p,0))),t.b(" "),t.b(t.v(t.f("type",c,p,0))),t.b('">'),t.b("\n"+i),t.s(t.f("prefix",c,p,1),c,p,0,171,247,"{{ }}")&&(t.rs(c,p,function(c,p,t){t.b('            <span class="d2h-code-line-prefix">'),t.b(t.t(t.f("prefix",c,p,0))),t.b("</span>"),t.b("\n"+i)}),c.pop()),t.s(t.f("content",c,p,1),c,p,0,279,353,"{{ }}")&&(t.rs(c,p,function(c,p,t){t.b('            <span class="d2h-code-line-ctn">'),t.b(t.t(t.f("content",c,p,0))),t.b("</span>"),t.b("\n"+i)}),c.pop()),t.b("        </div>"),t.b("\n"+i),t.b("    </td>"),t.b("\n"+i),t.b("</tr>"),t.fl()},partials:{},subs:{}}),global.browserTemplates["generic-wrapper"]=new Hogan.Template({code:function(c,p,i){var t=this;return t.b(i=i||""),t.b('<div class="d2h-wrapper">'),t.b("\n"+i),t.b("    "),t.b(t.t(t.f("content",c,p,0))),t.b("\n"+i),t.b("</div>"),t.fl()},partials:{},subs:{}}),global.browserTemplates["icon-file-added"]=new Hogan.Template({code:function(c,p,i){var t=this;return t.b(i=i||""),t.b('<svg aria-hidden="true" class="d2h-icon d2h-added" height="16" title="added" version="1.1" viewBox="0 0 14 16"'),t.b("\n"+i),t.b('     width="14">'),t.b("\n"+i),t.b('    <path d="M13 1H1C0.45 1 0 1.45 0 2v12c0 0.55 0.45 1 1 1h12c0.55 0 1-0.45 1-1V2c0-0.55-0.45-1-1-1z m0 13H1V2h12v12zM6 9H3V7h3V4h2v3h3v2H8v3H6V9z"></path>'),t.b("\n"+i),t.b("</svg>"),t.fl()},partials:{},subs:{}}),global.browserTemplates["icon-file-changed"]=new Hogan.Template({code:function(c,p,i){var t=this;return t.b(i=i||""),t.b('<svg aria-hidden="true" class="d2h-icon d2h-changed" height="16" title="modified" version="1.1"'),t.b("\n"+i),t.b('     viewBox="0 0 14 16" width="14">'),t.b("\n"+i),t.b('    <path d="M13 1H1C0.45 1 0 1.45 0 2v12c0 0.55 0.45 1 1 1h12c0.55 0 1-0.45 1-1V2c0-0.55-0.45-1-1-1z m0 13H1V2h12v12zM4 8c0-1.66 1.34-3 3-3s3 1.34 3 3-1.34 3-3 3-3-1.34-3-3z"></path>'),t.b("\n"+i),t.b("</svg>"),t.fl()},partials:{},subs:{}}),global.browserTemplates["icon-file-deleted"]=new Hogan.Template({code:function(c,p,i){var t=this;return t.b(i=i||""),t.b('<svg aria-hidden="true" class="d2h-icon d2h-deleted" height="16" title="removed" version="1.1"'),t.b("\n"+i),t.b('     viewBox="0 0 14 16" width="14">'),t.b("\n"+i),t.b('    <path d="M13 1H1C0.45 1 0 1.45 0 2v12c0 0.55 0.45 1 1 1h12c0.55 0 1-0.45 1-1V2c0-0.55-0.45-1-1-1z m0 13H1V2h12v12zM11 9H3V7h8v2z"></path>'),t.b("\n"+i),t.b("</svg>"),t.fl()},partials:{},subs:{}}),global.browserTemplates["icon-file-renamed"]=new Hogan.Template({code:function(c,p,i){var t=this;return t.b(i=i||""),t.b('<svg aria-hidden="true" class="d2h-icon d2h-moved" height="16" title="renamed" version="1.1"'),t.b("\n"+i),t.b('     viewBox="0 0 14 16" width="14">'),t.b("\n"+i),t.b('    <path d="M6 9H3V7h3V4l5 4-5 4V9z m8-7v12c0 0.55-0.45 1-1 1H1c-0.55 0-1-0.45-1-1V2c0-0.55 0.45-1 1-1h12c0.55 0 1 0.45 1 1z m-1 0H1v12h12V2z"></path>'),t.b("\n"+i),t.b("</svg>"),t.fl()},partials:{},subs:{}}),global.browserTemplates["icon-file"]=new Hogan.Template({code:function(c,p,i){var t=this;return t.b(i=i||""),t.b('<svg aria-hidden="true" class="d2h-icon" height="16" version="1.1" viewBox="0 0 12 16" width="12">'),t.b("\n"+i),t.b('    <path d="M6 5H2v-1h4v1zM2 8h7v-1H2v1z m0 2h7v-1H2v1z m0 2h7v-1H2v1z m10-7.5v9.5c0 0.55-0.45 1-1 1H1c-0.55 0-1-0.45-1-1V2c0-0.55 0.45-1 1-1h7.5l3.5 3.5z m-1 0.5L8 2H1v12h10V5z"></path>'),t.b("\n"+i),t.b("</svg>"),t.fl()},partials:{},subs:{}}),global.browserTemplates["line-by-line-file-diff"]=new Hogan.Template({code:function(c,p,i){var t=this;return t.b(i=i||""),t.b('<div id="'),t.b(t.v(t.f("fileHtmlId",c,p,0))),t.b('" class="d2h-file-wrapper" data-lang="'),t.b(t.v(t.d("file.language",c,p,0))),t.b('">'),t.b("\n"+i),t.b('    <div class="d2h-file-header">'),t.b("\n"+i),t.b("    "),t.b(t.t(t.f("filePath",c,p,0))),t.b("\n"+i),t.b("    </div>"),t.b("\n"+i),t.b('    <div class="d2h-file-diff">'),t.b("\n"+i),t.b('        <div class="d2h-code-wrapper">'),t.b("\n"+i),t.b('            <table class="d2h-diff-table">'),t.b("\n"+i),t.b('                <tbody class="d2h-diff-tbody">'),t.b("\n"+i),t.b("                "),t.b(t.t(t.f("diffs",c,p,0))),t.b("\n"+i),t.b("                </tbody>"),t.b("\n"+i),t.b("            </table>"),t.b("\n"+i),t.b("        </div>"),t.b("\n"+i),t.b("    </div>"),t.b("\n"+i),t.b("</div>"),t.fl()},partials:{},subs:{}}),global.browserTemplates["line-by-line-numbers"]=new Hogan.Template({code:function(c,p,i){var t=this;return t.b(i=i||""),t.b('<div class="line-num1">'),t.b(t.v(t.f("oldNumber",c,p,0))),t.b("</div>"),t.b("\n"+i),t.b('<div class="line-num2">'),t.b(t.v(t.f("newNumber",c,p,0))),t.b("</div>"),t.fl()},partials:{},subs:{}}),global.browserTemplates["side-by-side-file-diff"]=new Hogan.Template({code:function(c,p,i){var t=this;return t.b(i=i||""),t.b('<div id="'),t.b(t.v(t.f("fileHtmlId",c,p,0))),t.b('" class="d2h-file-wrapper" data-lang="'),t.b(t.v(t.d("file.language",c,p,0))),t.b('">'),t.b("\n"+i),t.b('    <div class="d2h-file-header">'),t.b("\n"+i),t.b("      "),t.b(t.t(t.f("filePath",c,p,0))),t.b("\n"+i),t.b("    </div>"),t.b("\n"+i),t.b('    <div class="d2h-files-diff">'),t.b("\n"+i),t.b('        <div class="d2h-file-side-diff">'),t.b("\n"+i),t.b('            <div class="d2h-code-wrapper">'),t.b("\n"+i),t.b('                <table class="d2h-diff-table">'),t.b("\n"+i),t.b('                    <tbody class="d2h-diff-tbody">'),t.b("\n"+i),t.b("                    "),t.b(t.t(t.d("diffs.left",c,p,0))),t.b("\n"+i),t.b("                    </tbody>"),t.b("\n"+i),t.b("                </table>"),t.b("\n"+i),t.b("            </div>"),t.b("\n"+i),t.b("        </div>"),t.b("\n"+i),t.b('        <div class="d2h-file-side-diff">'),t.b("\n"+i),t.b('            <div class="d2h-code-wrapper">'),t.b("\n"+i),t.b('                <table class="d2h-diff-table">'),t.b("\n"+i),t.b('                    <tbody class="d2h-diff-tbody">'),t.b("\n"+i),t.b("                    "),t.b(t.t(t.d("diffs.right",c,p,0))),t.b("\n"+i),t.b("                    </tbody>"),t.b("\n"+i),t.b("                </table>"),t.b("\n"+i),t.b("            </div>"),t.b("\n"+i),t.b("        </div>"),t.b("\n"+i),t.b("    </div>"),t.b("\n"+i),t.b("</div>"),t.fl()},partials:{},subs:{}}),global.browserTemplates["tag-file-added"]=new Hogan.Template({code:function(c,p,i){var t=this;return t.b(i=i||""),t.b('<span class="d2h-tag d2h-added d2h-added-tag">ADDED</span>'),t.fl()},partials:{},subs:{}}),global.browserTemplates["tag-file-changed"]=new Hogan.Template({code:function(c,p,i){var t=this;return t.b(i=i||""),t.b('<span class="d2h-tag d2h-changed d2h-changed-tag">CHANGED</span>'),t.fl()},partials:{},subs:{}}),global.browserTemplates["tag-file-deleted"]=new Hogan.Template({code:function(c,p,i){var t=this;return t.b(i=i||""),t.b('<span class="d2h-tag d2h-deleted d2h-deleted-tag">DELETED</span>'),t.fl()},partials:{},subs:{}}),global.browserTemplates["tag-file-renamed"]=new Hogan.Template({code:function(c,p,i){var t=this;return t.b(i=i||""),t.b('<span class="d2h-tag d2h-moved d2h-moved-tag">RENAMED</span>'),t.fl()},partials:{},subs:{}}),module.exports=global.browserTemplates}()}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"hogan.js":4}],114:[function(require,module,exports){!function(){var merge=require("lodash/merge");function Utils(){}Utils.prototype.escape=function(str){return str.slice(0).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#x27;").replace(/\//g,"&#x2F;").replace(/\t/g,"    ")},Utils.prototype.startsWith=function(str,start){if("object"==typeof start){var result=!1;return start.forEach(function(s){0===str.indexOf(s)&&(result=!0)}),result}return str&&0===str.indexOf(start)},Utils.prototype.valueOrEmpty=function(value){return value||""},Utils.prototype.safeConfig=function(cfg,defaultConfig){var newCfg={};return merge(newCfg,defaultConfig,cfg),newCfg},module.exports.Utils=new Utils}()},{"lodash/merge":99}]},{},[105]);
\ No newline at end of file
diff --git a/pagure/static/vendor/highlight.js/INFO b/pagure/static/vendor/highlight.js/INFO
new file mode 100644
index 0000000..5d17bc8
--- /dev/null
+++ b/pagure/static/vendor/highlight.js/INFO
@@ -0,0 +1,36 @@
+The version of highlight.js in this directory is v9.12.0
+
+The styles that we are not using in pagure were also removed.
+
+This bundle was downloaded from:
+https://highlightjs.org/download/
+
+With all the common languages:
+* Apache
+* Bash
+* C#
+* C++
+* CSS
+* CoffeeScript
+* Diff
+* HTML, XML
+* HTTP
+* Ini
+* JSON
+* Java
+* JavaScript
+* Makefile
+* Markdown
+* Nginx
+* Objective-C
+* PHP
+* Perl
+* Python
+* Ruby
+* SQL
+* Shell Session
+
+and the following additional languages:
+* asciidoc
+* dockerfile
+* lua
diff --git a/pagure/static/vendor/highlight.js/LICENSE b/pagure/static/vendor/highlight.js/LICENSE
new file mode 100644
index 0000000..422deb7
--- /dev/null
+++ b/pagure/static/vendor/highlight.js/LICENSE
@@ -0,0 +1,24 @@
+Copyright (c) 2006, Ivan Sagalaev
+All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in the
+      documentation and/or other materials provided with the distribution.
+    * Neither the name of highlight.js nor the names of its contributors 
+      may be used to endorse or promote products derived from this software 
+      without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/pagure/static/vendor/highlight.js/highlight.pack.js b/pagure/static/vendor/highlight.js/highlight.pack.js
new file mode 100644
index 0000000..bcee588
--- /dev/null
+++ b/pagure/static/vendor/highlight.js/highlight.pack.js
@@ -0,0 +1,2 @@
+/*! highlight.js v9.12.0 | BSD3 License | git.io/hljslicense */
+!function(e){var n="object"==typeof window&&window||"object"==typeof self&&self;"undefined"!=typeof exports?e(exports):n&&(n.hljs=e({}),"function"==typeof define&&define.amd&&define([],function(){return n.hljs}))}(function(e){function n(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function t(e){return e.nodeName.toLowerCase()}function r(e,n){var t=e&&e.exec(n);return t&&0===t.index}function a(e){return k.test(e)}function i(e){var n,t,r,i,o=e.className+" ";if(o+=e.parentNode?e.parentNode.className:"",t=B.exec(o))return w(t[1])?t[1]:"no-highlight";for(o=o.split(/\s+/),n=0,r=o.length;r>n;n++)if(i=o[n],a(i)||w(i))return i}function o(e){var n,t={},r=Array.prototype.slice.call(arguments,1);for(n in e)t[n]=e[n];return r.forEach(function(e){for(n in e)t[n]=e[n]}),t}function u(e){var n=[];return function r(e,a){for(var i=e.firstChild;i;i=i.nextSibling)3===i.nodeType?a+=i.nodeValue.length:1===i.nodeType&&(n.push({event:"start",offset:a,node:i}),a=r(i,a),t(i).match(/br|hr|img|input/)||n.push({event:"stop",offset:a,node:i}));return a}(e,0),n}function c(e,r,a){function i(){return e.length&&r.length?e[0].offset!==r[0].offset?e[0].offset<r[0].offset?e:r:"start"===r[0].event?e:r:e.length?e:r}function o(e){function r(e){return" "+e.nodeName+'="'+n(e.value).replace('"',"&quot;")+'"'}s+="<"+t(e)+E.map.call(e.attributes,r).join("")+">"}function u(e){s+="</"+t(e)+">"}function c(e){("start"===e.event?o:u)(e.node)}for(var l=0,s="",f=[];e.length||r.length;){var g=i();if(s+=n(a.substring(l,g[0].offset)),l=g[0].offset,g===e){f.reverse().forEach(u);do c(g.splice(0,1)[0]),g=i();while(g===e&&g.length&&g[0].offset===l);f.reverse().forEach(o)}else"start"===g[0].event?f.push(g[0].node):f.pop(),c(g.splice(0,1)[0])}return s+n(a.substr(l))}function l(e){return e.v&&!e.cached_variants&&(e.cached_variants=e.v.map(function(n){return o(e,{v:null},n)})),e.cached_variants||e.eW&&[o(e)]||[e]}function s(e){function n(e){return e&&e.source||e}function t(t,r){return new RegExp(n(t),"m"+(e.cI?"i":"")+(r?"g":""))}function r(a,i){if(!a.compiled){if(a.compiled=!0,a.k=a.k||a.bK,a.k){var o={},u=function(n,t){e.cI&&(t=t.toLowerCase()),t.split(" ").forEach(function(e){var t=e.split("|");o[t[0]]=[n,t[1]?Number(t[1]):1]})};"string"==typeof a.k?u("keyword",a.k):x(a.k).forEach(function(e){u(e,a.k[e])}),a.k=o}a.lR=t(a.l||/\w+/,!0),i&&(a.bK&&(a.b="\\b("+a.bK.split(" ").join("|")+")\\b"),a.b||(a.b=/\B|\b/),a.bR=t(a.b),a.e||a.eW||(a.e=/\B|\b/),a.e&&(a.eR=t(a.e)),a.tE=n(a.e)||"",a.eW&&i.tE&&(a.tE+=(a.e?"|":"")+i.tE)),a.i&&(a.iR=t(a.i)),null==a.r&&(a.r=1),a.c||(a.c=[]),a.c=Array.prototype.concat.apply([],a.c.map(function(e){return l("self"===e?a:e)})),a.c.forEach(function(e){r(e,a)}),a.starts&&r(a.starts,i);var c=a.c.map(function(e){return e.bK?"\\.?("+e.b+")\\.?":e.b}).concat([a.tE,a.i]).map(n).filter(Boolean);a.t=c.length?t(c.join("|"),!0):{exec:function(){return null}}}}r(e)}function f(e,t,a,i){function o(e,n){var t,a;for(t=0,a=n.c.length;a>t;t++)if(r(n.c[t].bR,e))return n.c[t]}function u(e,n){if(r(e.eR,n)){for(;e.endsParent&&e.parent;)e=e.parent;return e}return e.eW?u(e.parent,n):void 0}function c(e,n){return!a&&r(n.iR,e)}function l(e,n){var t=N.cI?n[0].toLowerCase():n[0];return e.k.hasOwnProperty(t)&&e.k[t]}function p(e,n,t,r){var a=r?"":I.classPrefix,i='<span class="'+a,o=t?"":C;return i+=e+'">',i+n+o}function h(){var e,t,r,a;if(!E.k)return n(k);for(a="",t=0,E.lR.lastIndex=0,r=E.lR.exec(k);r;)a+=n(k.substring(t,r.index)),e=l(E,r),e?(B+=e[1],a+=p(e[0],n(r[0]))):a+=n(r[0]),t=E.lR.lastIndex,r=E.lR.exec(k);return a+n(k.substr(t))}function d(){var e="string"==typeof E.sL;if(e&&!y[E.sL])return n(k);var t=e?f(E.sL,k,!0,x[E.sL]):g(k,E.sL.length?E.sL:void 0);return E.r>0&&(B+=t.r),e&&(x[E.sL]=t.top),p(t.language,t.value,!1,!0)}function b(){L+=null!=E.sL?d():h(),k=""}function v(e){L+=e.cN?p(e.cN,"",!0):"",E=Object.create(e,{parent:{value:E}})}function m(e,n){if(k+=e,null==n)return b(),0;var t=o(n,E);if(t)return t.skip?k+=n:(t.eB&&(k+=n),b(),t.rB||t.eB||(k=n)),v(t,n),t.rB?0:n.length;var r=u(E,n);if(r){var a=E;a.skip?k+=n:(a.rE||a.eE||(k+=n),b(),a.eE&&(k=n));do E.cN&&(L+=C),E.skip||(B+=E.r),E=E.parent;while(E!==r.parent);return r.starts&&v(r.starts,""),a.rE?0:n.length}if(c(n,E))throw new Error('Illegal lexeme "'+n+'" for mode "'+(E.cN||"<unnamed>")+'"');return k+=n,n.length||1}var N=w(e);if(!N)throw new Error('Unknown language: "'+e+'"');s(N);var R,E=i||N,x={},L="";for(R=E;R!==N;R=R.parent)R.cN&&(L=p(R.cN,"",!0)+L);var k="",B=0;try{for(var M,j,O=0;;){if(E.t.lastIndex=O,M=E.t.exec(t),!M)break;j=m(t.substring(O,M.index),M[0]),O=M.index+j}for(m(t.substr(O)),R=E;R.parent;R=R.parent)R.cN&&(L+=C);return{r:B,value:L,language:e,top:E}}catch(T){if(T.message&&-1!==T.message.indexOf("Illegal"))return{r:0,value:n(t)};throw T}}function g(e,t){t=t||I.languages||x(y);var r={r:0,value:n(e)},a=r;return t.filter(w).forEach(function(n){var t=f(n,e,!1);t.language=n,t.r>a.r&&(a=t),t.r>r.r&&(a=r,r=t)}),a.language&&(r.second_best=a),r}function p(e){return I.tabReplace||I.useBR?e.replace(M,function(e,n){return I.useBR&&"\n"===e?"<br>":I.tabReplace?n.replace(/\t/g,I.tabReplace):""}):e}function h(e,n,t){var r=n?L[n]:t,a=[e.trim()];return e.match(/\bhljs\b/)||a.push("hljs"),-1===e.indexOf(r)&&a.push(r),a.join(" ").trim()}function d(e){var n,t,r,o,l,s=i(e);a(s)||(I.useBR?(n=document.createElementNS("http://www.w3.org/1999/xhtml","div"),n.innerHTML=e.innerHTML.replace(/\n/g,"").replace(/<br[ \/]*>/g,"\n")):n=e,l=n.textContent,r=s?f(s,l,!0):g(l),t=u(n),t.length&&(o=document.createElementNS("http://www.w3.org/1999/xhtml","div"),o.innerHTML=r.value,r.value=c(t,u(o),l)),r.value=p(r.value),e.innerHTML=r.value,e.className=h(e.className,s,r.language),e.result={language:r.language,re:r.r},r.second_best&&(e.second_best={language:r.second_best.language,re:r.second_best.r}))}function b(e){I=o(I,e)}function v(){if(!v.called){v.called=!0;var e=document.querySelectorAll("pre code");E.forEach.call(e,d)}}function m(){addEventListener("DOMContentLoaded",v,!1),addEventListener("load",v,!1)}function N(n,t){var r=y[n]=t(e);r.aliases&&r.aliases.forEach(function(e){L[e]=n})}function R(){return x(y)}function w(e){return e=(e||"").toLowerCase(),y[e]||y[L[e]]}var E=[],x=Object.keys,y={},L={},k=/^(no-?highlight|plain|text)$/i,B=/\blang(?:uage)?-([\w-]+)\b/i,M=/((^(<[^>]+>|\t|)+|(?:\n)))/gm,C="</span>",I={classPrefix:"hljs-",tabReplace:null,useBR:!1,languages:void 0};return e.highlight=f,e.highlightAuto=g,e.fixMarkup=p,e.highlightBlock=d,e.configure=b,e.initHighlighting=v,e.initHighlightingOnLoad=m,e.registerLanguage=N,e.listLanguages=R,e.getLanguage=w,e.inherit=o,e.IR="[a-zA-Z]\\w*",e.UIR="[a-zA-Z_]\\w*",e.NR="\\b\\d+(\\.\\d+)?",e.CNR="(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",e.BNR="\\b(0b[01]+)",e.RSR="!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~",e.BE={b:"\\\\[\\s\\S]",r:0},e.ASM={cN:"string",b:"'",e:"'",i:"\\n",c:[e.BE]},e.QSM={cN:"string",b:'"',e:'"',i:"\\n",c:[e.BE]},e.PWM={b:/\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\b/},e.C=function(n,t,r){var a=e.inherit({cN:"comment",b:n,e:t,c:[]},r||{});return a.c.push(e.PWM),a.c.push({cN:"doctag",b:"(?:TODO|FIXME|NOTE|BUG|XXX):",r:0}),a},e.CLCM=e.C("//","$"),e.CBCM=e.C("/\\*","\\*/"),e.HCM=e.C("#","$"),e.NM={cN:"number",b:e.NR,r:0},e.CNM={cN:"number",b:e.CNR,r:0},e.BNM={cN:"number",b:e.BNR,r:0},e.CSSNM={cN:"number",b:e.NR+"(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?",r:0},e.RM={cN:"regexp",b:/\//,e:/\/[gimuy]*/,i:/\n/,c:[e.BE,{b:/\[/,e:/\]/,r:0,c:[e.BE]}]},e.TM={cN:"title",b:e.IR,r:0},e.UTM={cN:"title",b:e.UIR,r:0},e.METHOD_GUARD={b:"\\.\\s*"+e.UIR,r:0},e});hljs.registerLanguage("bash",function(e){var t={cN:"variable",v:[{b:/\$[\w\d#@][\w\d_]*/},{b:/\$\{(.*?)}/}]},s={cN:"string",b:/"/,e:/"/,c:[e.BE,t,{cN:"variable",b:/\$\(/,e:/\)/,c:[e.BE]}]},a={cN:"string",b:/'/,e:/'/};return{aliases:["sh","zsh"],l:/\b-?[a-z\._]+\b/,k:{keyword:"if then else elif fi for while in do done case esac function",literal:"true false",built_in:"break cd continue eval exec exit export getopts hash pwd readonly return shift test times trap umask unset alias bind builtin caller command declare echo enable help let local logout mapfile printf read readarray source type typeset ulimit unalias set shopt autoload bg bindkey bye cap chdir clone comparguments compcall compctl compdescribe compfiles compgroups compquote comptags comptry compvalues dirs disable disown echotc echoti emulate fc fg float functions getcap getln history integer jobs kill limit log noglob popd print pushd pushln rehash sched setcap setopt stat suspend ttyctl unfunction unhash unlimit unsetopt vared wait whence where which zcompile zformat zftp zle zmodload zparseopts zprof zpty zregexparse zsocket zstyle ztcp",_:"-ne -eq -lt -gt -f -d -e -s -l -a"},c:[{cN:"meta",b:/^#![^\n]+sh\s*$/,r:10},{cN:"function",b:/\w[\w\d_]*\s*\(\s*\)\s*\{/,rB:!0,c:[e.inherit(e.TM,{b:/\w[\w\d_]*/})],r:0},e.HCM,s,a,t]}});hljs.registerLanguage("dockerfile",function(e){return{aliases:["docker"],cI:!0,k:"from maintainer expose env arg user onbuild stopsignal",c:[e.HCM,e.ASM,e.QSM,e.NM,{bK:"run cmd entrypoint volume add copy workdir label healthcheck shell",starts:{e:/[^\\]\n/,sL:"bash"}}],i:"</"}});hljs.registerLanguage("java",function(e){var a="[À-ʸa-zA-Z_$][À-ʸa-zA-Z_$0-9]*",t=a+"(<"+a+"(\\s*,\\s*"+a+")*>)?",r="false synchronized int abstract float private char boolean static null if const for true while long strictfp finally protected import native final void enum else break transient catch instanceof byte super volatile case assert short package default double public try this switch continue throws protected public private module requires exports do",s="\\b(0[bB]([01]+[01_]+[01]+|[01]+)|0[xX]([a-fA-F0-9]+[a-fA-F0-9_]+[a-fA-F0-9]+|[a-fA-F0-9]+)|(([\\d]+[\\d_]+[\\d]+|[\\d]+)(\\.([\\d]+[\\d_]+[\\d]+|[\\d]+))?|\\.([\\d]+[\\d_]+[\\d]+|[\\d]+))([eE][-+]?\\d+)?)[lLfF]?",c={cN:"number",b:s,r:0};return{aliases:["jsp"],k:r,i:/<\/|#/,c:[e.C("/\\*\\*","\\*/",{r:0,c:[{b:/\w+@/,r:0},{cN:"doctag",b:"@[A-Za-z]+"}]}),e.CLCM,e.CBCM,e.ASM,e.QSM,{cN:"class",bK:"class interface",e:/[{;=]/,eE:!0,k:"class interface",i:/[:"\[\]]/,c:[{bK:"extends implements"},e.UTM]},{bK:"new throw return else",r:0},{cN:"function",b:"("+t+"\\s+)+"+e.UIR+"\\s*\\(",rB:!0,e:/[{;=]/,eE:!0,k:r,c:[{b:e.UIR+"\\s*\\(",rB:!0,r:0,c:[e.UTM]},{cN:"params",b:/\(/,e:/\)/,k:r,r:0,c:[e.ASM,e.QSM,e.CNM,e.CBCM]},e.CLCM,e.CBCM]},c,{cN:"meta",b:"@[A-Za-z]+"}]}});hljs.registerLanguage("python",function(e){var r={keyword:"and elif is global as in if from raise for except finally print import pass return exec else break not with class assert yield try while continue del or def lambda async await nonlocal|10 None True False",built_in:"Ellipsis NotImplemented"},b={cN:"meta",b:/^(>>>|\.\.\.) /},c={cN:"subst",b:/\{/,e:/\}/,k:r,i:/#/},a={cN:"string",c:[e.BE],v:[{b:/(u|b)?r?'''/,e:/'''/,c:[b],r:10},{b:/(u|b)?r?"""/,e:/"""/,c:[b],r:10},{b:/(fr|rf|f)'''/,e:/'''/,c:[b,c]},{b:/(fr|rf|f)"""/,e:/"""/,c:[b,c]},{b:/(u|r|ur)'/,e:/'/,r:10},{b:/(u|r|ur)"/,e:/"/,r:10},{b:/(b|br)'/,e:/'/},{b:/(b|br)"/,e:/"/},{b:/(fr|rf|f)'/,e:/'/,c:[c]},{b:/(fr|rf|f)"/,e:/"/,c:[c]},e.ASM,e.QSM]},s={cN:"number",r:0,v:[{b:e.BNR+"[lLjJ]?"},{b:"\\b(0o[0-7]+)[lLjJ]?"},{b:e.CNR+"[lLjJ]?"}]},i={cN:"params",b:/\(/,e:/\)/,c:["self",b,s,a]};return c.c=[a,s,b],{aliases:["py","gyp"],k:r,i:/(<\/|->|\?)|=>/,c:[b,s,a,e.HCM,{v:[{cN:"function",bK:"def"},{cN:"class",bK:"class"}],e:/:/,i:/[${=;\n,]/,c:[e.UTM,i,{b:/->/,eW:!0,k:"None"}]},{cN:"meta",b:/^[\t ]*@/,e:/$/},{b:/\b(print|exec)\(/}]}});hljs.registerLanguage("css",function(e){var c="[a-zA-Z-][a-zA-Z0-9_-]*",t={b:/[A-Z\_\.\-]+\s*:/,rB:!0,e:";",eW:!0,c:[{cN:"attribute",b:/\S/,e:":",eE:!0,starts:{eW:!0,eE:!0,c:[{b:/[\w-]+\(/,rB:!0,c:[{cN:"built_in",b:/[\w-]+/},{b:/\(/,e:/\)/,c:[e.ASM,e.QSM]}]},e.CSSNM,e.QSM,e.ASM,e.CBCM,{cN:"number",b:"#[0-9A-Fa-f]+"},{cN:"meta",b:"!important"}]}}]};return{cI:!0,i:/[=\/|'\$]/,c:[e.CBCM,{cN:"selector-id",b:/#[A-Za-z0-9_-]+/},{cN:"selector-class",b:/\.[A-Za-z0-9_-]+/},{cN:"selector-attr",b:/\[/,e:/\]/,i:"$"},{cN:"selector-pseudo",b:/:(:)?[a-zA-Z0-9\_\-\+\(\)"'.]+/},{b:"@(font-face|page)",l:"[a-z-]+",k:"font-face page"},{b:"@",e:"[{;]",i:/:/,c:[{cN:"keyword",b:/\w+/},{b:/\s/,eW:!0,eE:!0,r:0,c:[e.ASM,e.QSM,e.CSSNM]}]},{cN:"selector-tag",b:c,r:0},{b:"{",e:"}",i:/\S/,c:[e.CBCM,t]}]}});hljs.registerLanguage("xml",function(s){var e="[A-Za-z0-9\\._:-]+",t={eW:!0,i:/</,r:0,c:[{cN:"attr",b:e,r:0},{b:/=\s*/,r:0,c:[{cN:"string",endsParent:!0,v:[{b:/"/,e:/"/},{b:/'/,e:/'/},{b:/[^\s"'=<>`]+/}]}]}]};return{aliases:["html","xhtml","rss","atom","xjb","xsd","xsl","plist"],cI:!0,c:[{cN:"meta",b:"<!DOCTYPE",e:">",r:10,c:[{b:"\\[",e:"\\]"}]},s.C("<!--","-->",{r:10}),{b:"<\\!\\[CDATA\\[",e:"\\]\\]>",r:10},{b:/<\?(php)?/,e:/\?>/,sL:"php",c:[{b:"/\\*",e:"\\*/",skip:!0}]},{cN:"tag",b:"<style(?=\\s|>|$)",e:">",k:{name:"style"},c:[t],starts:{e:"</style>",rE:!0,sL:["css","xml"]}},{cN:"tag",b:"<script(?=\\s|>|$)",e:">",k:{name:"script"},c:[t],starts:{e:"</script>",rE:!0,sL:["actionscript","javascript","handlebars","xml"]}},{cN:"meta",v:[{b:/<\?xml/,e:/\?>/,r:10},{b:/<\?\w+/,e:/\?>/}]},{cN:"tag",b:"</?",e:"/?>",c:[{cN:"name",b:/[^\/><\s]+/,r:0},t]}]}});hljs.registerLanguage("asciidoc",function(e){return{aliases:["adoc"],c:[e.C("^/{4,}\\n","\\n/{4,}$",{r:10}),e.C("^//","$",{r:0}),{cN:"title",b:"^\\.\\w.*$"},{b:"^[=\\*]{4,}\\n",e:"\\n^[=\\*]{4,}$",r:10},{cN:"section",r:10,v:[{b:"^(={1,5}) .+?( \\1)?$"},{b:"^[^\\[\\]\\n]+?\\n[=\\-~\\^\\+]{2,}$"}]},{cN:"meta",b:"^:.+?:",e:"\\s",eE:!0,r:10},{cN:"meta",b:"^\\[.+?\\]$",r:0},{cN:"quote",b:"^_{4,}\\n",e:"\\n_{4,}$",r:10},{cN:"code",b:"^[\\-\\.]{4,}\\n",e:"\\n[\\-\\.]{4,}$",r:10},{b:"^\\+{4,}\\n",e:"\\n\\+{4,}$",c:[{b:"<",e:">",sL:"xml",r:0}],r:10},{cN:"bullet",b:"^(\\*+|\\-+|\\.+|[^\\n]+?::)\\s+"},{cN:"symbol",b:"^(NOTE|TIP|IMPORTANT|WARNING|CAUTION):\\s+",r:10},{cN:"strong",b:"\\B\\*(?![\\*\\s])",e:"(\\n{2}|\\*)",c:[{b:"\\\\*\\w",r:0}]},{cN:"emphasis",b:"\\B'(?!['\\s])",e:"(\\n{2}|')",c:[{b:"\\\\'\\w",r:0}],r:0},{cN:"emphasis",b:"_(?![_\\s])",e:"(\\n{2}|_)",r:0},{cN:"string",v:[{b:"``.+?''"},{b:"`.+?'"}]},{cN:"code",b:"(`.+?`|\\+.+?\\+)",r:0},{cN:"code",b:"^[ \\t]",e:"$",r:0},{b:"^'{3,}[ \\t]*$",r:10},{b:"(link:)?(http|https|ftp|file|irc|image:?):\\S+\\[.*?\\]",rB:!0,c:[{b:"(link|image:?):",r:0},{cN:"link",b:"\\w",e:"[^\\[]+",r:0},{cN:"string",b:"\\[",e:"\\]",eB:!0,eE:!0,r:0}],r:10}]}});hljs.registerLanguage("http",function(e){var t="HTTP/[0-9\\.]+";return{aliases:["https"],i:"\\S",c:[{b:"^"+t,e:"$",c:[{cN:"number",b:"\\b\\d{3}\\b"}]},{b:"^[A-Z]+ (.*?) "+t+"$",rB:!0,e:"$",c:[{cN:"string",b:" ",e:" ",eB:!0,eE:!0},{b:t},{cN:"keyword",b:"[A-Z]+"}]},{cN:"attribute",b:"^\\w",e:": ",eE:!0,i:"\\n|\\s|=",starts:{e:"$",r:0}},{b:"\\n\\n",starts:{sL:[],eW:!0}}]}});hljs.registerLanguage("shell",function(s){return{aliases:["console"],c:[{cN:"meta",b:"^\\s{0,3}[\\w\\d\\[\\]()@-]*[>%$#]",starts:{e:"$",sL:"bash"}}]}});hljs.registerLanguage("json",function(e){var i={literal:"true false null"},n=[e.QSM,e.CNM],r={e:",",eW:!0,eE:!0,c:n,k:i},t={b:"{",e:"}",c:[{cN:"attr",b:/"/,e:/"/,c:[e.BE],i:"\\n"},e.inherit(r,{b:/:/})],i:"\\S"},c={b:"\\[",e:"\\]",c:[e.inherit(r)],i:"\\S"};return n.splice(n.length,0,t,c),{c:n,k:i,i:"\\S"}});hljs.registerLanguage("ini",function(e){var b={cN:"string",c:[e.BE],v:[{b:"'''",e:"'''",r:10},{b:'"""',e:'"""',r:10},{b:'"',e:'"'},{b:"'",e:"'"}]};return{aliases:["toml"],cI:!0,i:/\S/,c:[e.C(";","$"),e.HCM,{cN:"section",b:/^\s*\[+/,e:/\]+/},{b:/^[a-z0-9\[\]_-]+\s*=\s*/,e:"$",rB:!0,c:[{cN:"attr",b:/[a-z0-9\[\]_-]+/},{b:/=/,eW:!0,r:0,c:[{cN:"literal",b:/\bon|off|true|false|yes|no\b/},{cN:"variable",v:[{b:/\$[\w\d"][\w\d_]*/},{b:/\$\{(.*?)}/}]},b,{cN:"number",b:/([\+\-]+)?[\d]+_[\d_]+/},e.NM]}]}]}});hljs.registerLanguage("coffeescript",function(e){var c={keyword:"in if for while finally new do return else break catch instanceof throw try this switch continue typeof delete debugger super yield import export from as default await then unless until loop of by when and or is isnt not",literal:"true false null undefined yes no on off",built_in:"npm require console print module global window document"},n="[A-Za-z$_][0-9A-Za-z$_]*",r={cN:"subst",b:/#\{/,e:/}/,k:c},i=[e.BNM,e.inherit(e.CNM,{starts:{e:"(\\s*/)?",r:0}}),{cN:"string",v:[{b:/'''/,e:/'''/,c:[e.BE]},{b:/'/,e:/'/,c:[e.BE]},{b:/"""/,e:/"""/,c:[e.BE,r]},{b:/"/,e:/"/,c:[e.BE,r]}]},{cN:"regexp",v:[{b:"///",e:"///",c:[r,e.HCM]},{b:"//[gim]*",r:0},{b:/\/(?![ *])(\\\/|.)*?\/[gim]*(?=\W|$)/}]},{b:"@"+n},{sL:"javascript",eB:!0,eE:!0,v:[{b:"```",e:"```"},{b:"`",e:"`"}]}];r.c=i;var s=e.inherit(e.TM,{b:n}),t="(\\(.*\\))?\\s*\\B[-=]>",o={cN:"params",b:"\\([^\\(]",rB:!0,c:[{b:/\(/,e:/\)/,k:c,c:["self"].concat(i)}]};return{aliases:["coffee","cson","iced"],k:c,i:/\/\*/,c:i.concat([e.C("###","###"),e.HCM,{cN:"function",b:"^\\s*"+n+"\\s*=\\s*"+t,e:"[-=]>",rB:!0,c:[s,o]},{b:/[:\(,=]\s*/,r:0,c:[{cN:"function",b:t,e:"[-=]>",rB:!0,c:[o]}]},{cN:"class",bK:"class",e:"$",i:/[:="\[\]]/,c:[{bK:"extends",eW:!0,i:/[:="\[\]]/,c:[s]},s]},{b:n+":",e:":",rB:!0,rE:!0,r:0}])}});hljs.registerLanguage("lua",function(e){var t="\\[=*\\[",a="\\]=*\\]",r={b:t,e:a,c:["self"]},n=[e.C("--(?!"+t+")","$"),e.C("--"+t,a,{c:[r],r:10})];return{l:e.UIR,k:{literal:"true false nil",keyword:"and break do else elseif end for goto if in local not or repeat return then until while",built_in:"_G _ENV _VERSION __index __newindex __mode __call __metatable __tostring __len __gc __add __sub __mul __div __mod __pow __concat __unm __eq __lt __le assert collectgarbage dofile error getfenv getmetatable ipairs load loadfile loadstringmodule next pairs pcall print rawequal rawget rawset require select setfenvsetmetatable tonumber tostring type unpack xpcall arg selfcoroutine resume yield status wrap create running debug getupvalue debug sethook getmetatable gethook setmetatable setlocal traceback setfenv getinfo setupvalue getlocal getregistry getfenv io lines write close flush open output type read stderr stdin input stdout popen tmpfile math log max acos huge ldexp pi cos tanh pow deg tan cosh sinh random randomseed frexp ceil floor rad abs sqrt modf asin min mod fmod log10 atan2 exp sin atan os exit setlocale date getenv difftime remove time clock tmpname rename execute package preload loadlib loaded loaders cpath config path seeall string sub upper len gfind rep find match char dump gmatch reverse byte format gsub lower table setn insert getn foreachi maxn foreach concat sort remove"},c:n.concat([{cN:"function",bK:"function",e:"\\)",c:[e.inherit(e.TM,{b:"([_a-zA-Z]\\w*\\.)*([_a-zA-Z]\\w*:)?[_a-zA-Z]\\w*"}),{cN:"params",b:"\\(",eW:!0,c:n}].concat(n)},e.CNM,e.ASM,e.QSM,{cN:"string",b:t,e:a,c:[r],r:5}])}});hljs.registerLanguage("nginx",function(e){var r={cN:"variable",v:[{b:/\$\d+/},{b:/\$\{/,e:/}/},{b:"[\\$\\@]"+e.UIR}]},b={eW:!0,l:"[a-z/_]+",k:{literal:"on off yes no true false none blocked debug info notice warn error crit select break last permanent redirect kqueue rtsig epoll poll /dev/poll"},r:0,i:"=>",c:[e.HCM,{cN:"string",c:[e.BE,r],v:[{b:/"/,e:/"/},{b:/'/,e:/'/}]},{b:"([a-z]+):/",e:"\\s",eW:!0,eE:!0,c:[r]},{cN:"regexp",c:[e.BE,r],v:[{b:"\\s\\^",e:"\\s|{|;",rE:!0},{b:"~\\*?\\s+",e:"\\s|{|;",rE:!0},{b:"\\*(\\.[a-z\\-]+)+"},{b:"([a-z\\-]+\\.)+\\*"}]},{cN:"number",b:"\\b\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}(:\\d{1,5})?\\b"},{cN:"number",b:"\\b\\d+[kKmMgGdshdwy]*\\b",r:0},r]};return{aliases:["nginxconf"],c:[e.HCM,{b:e.UIR+"\\s+{",rB:!0,e:"{",c:[{cN:"section",b:e.UIR}],r:0},{b:e.UIR+"\\s",e:";|{",rB:!0,c:[{cN:"attribute",b:e.UIR,starts:b}],r:0}],i:"[^\\s\\}]"}});hljs.registerLanguage("javascript",function(e){var r="[A-Za-z$_][0-9A-Za-z$_]*",t={keyword:"in of if for while finally var new function do return void else break catch instanceof with throw case default try this switch continue typeof delete let yield const export super debugger as async await static import from as",literal:"true false null undefined NaN Infinity",built_in:"eval isFinite isNaN parseFloat parseInt decodeURI decodeURIComponent encodeURI encodeURIComponent escape unescape Object Function Boolean Error EvalError InternalError RangeError ReferenceError StopIteration SyntaxError TypeError URIError Number Math Date String RegExp Array Float32Array Float64Array Int16Array Int32Array Int8Array Uint16Array Uint32Array Uint8Array Uint8ClampedArray ArrayBuffer DataView JSON Intl arguments require module console window document Symbol Set Map WeakSet WeakMap Proxy Reflect Promise"},a={cN:"number",v:[{b:"\\b(0[bB][01]+)"},{b:"\\b(0[oO][0-7]+)"},{b:e.CNR}],r:0},n={cN:"subst",b:"\\$\\{",e:"\\}",k:t,c:[]},c={cN:"string",b:"`",e:"`",c:[e.BE,n]};n.c=[e.ASM,e.QSM,c,a,e.RM];var s=n.c.concat([e.CBCM,e.CLCM]);return{aliases:["js","jsx"],k:t,c:[{cN:"meta",r:10,b:/^\s*['"]use (strict|asm)['"]/},{cN:"meta",b:/^#!/,e:/$/},e.ASM,e.QSM,c,e.CLCM,e.CBCM,a,{b:/[{,]\s*/,r:0,c:[{b:r+"\\s*:",rB:!0,r:0,c:[{cN:"attr",b:r,r:0}]}]},{b:"("+e.RSR+"|\\b(case|return|throw)\\b)\\s*",k:"return throw case",c:[e.CLCM,e.CBCM,e.RM,{cN:"function",b:"(\\(.*?\\)|"+r+")\\s*=>",rB:!0,e:"\\s*=>",c:[{cN:"params",v:[{b:r},{b:/\(\s*\)/},{b:/\(/,e:/\)/,eB:!0,eE:!0,k:t,c:s}]}]},{b:/</,e:/(\/\w+|\w+\/)>/,sL:"xml",c:[{b:/<\w+\s*\/>/,skip:!0},{b:/<\w+/,e:/(\/\w+|\w+\/)>/,skip:!0,c:[{b:/<\w+\s*\/>/,skip:!0},"self"]}]}],r:0},{cN:"function",bK:"function",e:/\{/,eE:!0,c:[e.inherit(e.TM,{b:r}),{cN:"params",b:/\(/,e:/\)/,eB:!0,eE:!0,c:s}],i:/\[|%/},{b:/\$[(.]/},e.METHOD_GUARD,{cN:"class",bK:"class",e:/[{;=]/,eE:!0,i:/[:"\[\]]/,c:[{bK:"extends"},e.UTM]},{bK:"constructor",e:/\{/,eE:!0}],i:/#(?!!)/}});hljs.registerLanguage("apache",function(e){var r={cN:"number",b:"[\\$%]\\d+"};return{aliases:["apacheconf"],cI:!0,c:[e.HCM,{cN:"section",b:"</?",e:">"},{cN:"attribute",b:/\w+/,r:0,k:{nomarkup:"order deny allow setenv rewriterule rewriteengine rewritecond documentroot sethandler errordocument loadmodule options header listen serverroot servername"},starts:{e:/$/,r:0,k:{literal:"on off all"},c:[{cN:"meta",b:"\\s\\[",e:"\\]$"},{cN:"variable",b:"[\\$%]\\{",e:"\\}",c:["self",r]},r,e.QSM]}}],i:/\S/}});hljs.registerLanguage("makefile",function(e){var i={cN:"variable",v:[{b:"\\$\\("+e.UIR+"\\)",c:[e.BE]},{b:/\$[@%<?\^\+\*]/}]},r={cN:"string",b:/"/,e:/"/,c:[e.BE,i]},a={cN:"variable",b:/\$\([\w-]+\s/,e:/\)/,k:{built_in:"subst patsubst strip findstring filter filter-out sort word wordlist firstword lastword dir notdir suffix basename addsuffix addprefix join wildcard realpath abspath error warning shell origin flavor foreach if or and call eval file value"},c:[i]},n={b:"^"+e.UIR+"\\s*[:+?]?=",i:"\\n",rB:!0,c:[{b:"^"+e.UIR,e:"[:+?]?=",eE:!0}]},t={cN:"meta",b:/^\.PHONY:/,e:/$/,k:{"meta-keyword":".PHONY"},l:/[\.\w]+/},l={cN:"section",b:/^[^\s]+:/,e:/$/,c:[i]};return{aliases:["mk","mak"],k:"define endef undefine ifdef ifndef ifeq ifneq else endif include -include sinclude override export unexport private vpath",l:/[\w-]+/,c:[e.HCM,i,r,a,n,t,l]}});hljs.registerLanguage("php",function(e){var c={b:"\\$+[a-zA-Z_-ÿ][a-zA-Z0-9_-ÿ]*"},i={cN:"meta",b:/<\?(php)?|\?>/},t={cN:"string",c:[e.BE,i],v:[{b:'b"',e:'"'},{b:"b'",e:"'"},e.inherit(e.ASM,{i:null}),e.inherit(e.QSM,{i:null})]},a={v:[e.BNM,e.CNM]};return{aliases:["php3","php4","php5","php6"],cI:!0,k:"and include_once list abstract global private echo interface as static endswitch array null if endwhile or const for endforeach self var while isset public protected exit foreach throw elseif include __FILE__ empty require_once do xor return parent clone use __CLASS__ __LINE__ else break print eval new catch __METHOD__ case exception default die require __FUNCTION__ enddeclare final try switch continue endfor endif declare unset true false trait goto instanceof insteadof __DIR__ __NAMESPACE__ yield finally",c:[e.HCM,e.C("//","$",{c:[i]}),e.C("/\\*","\\*/",{c:[{cN:"doctag",b:"@[A-Za-z]+"}]}),e.C("__halt_compiler.+?;",!1,{eW:!0,k:"__halt_compiler",l:e.UIR}),{cN:"string",b:/<<<['"]?\w+['"]?$/,e:/^\w+;?$/,c:[e.BE,{cN:"subst",v:[{b:/\$\w+/},{b:/\{\$/,e:/\}/}]}]},i,{cN:"keyword",b:/\$this\b/},c,{b:/(::|->)+[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/},{cN:"function",bK:"function",e:/[;{]/,eE:!0,i:"\\$|\\[|%",c:[e.UTM,{cN:"params",b:"\\(",e:"\\)",c:["self",c,e.CBCM,t,a]}]},{cN:"class",bK:"class interface",e:"{",eE:!0,i:/[:\(\$"]/,c:[{bK:"extends implements"},e.UTM]},{bK:"namespace",e:";",i:/[\.']/,c:[e.UTM]},{bK:"use",e:";",c:[e.UTM]},{b:"=>"},t,a]}});hljs.registerLanguage("perl",function(e){var t="getpwent getservent quotemeta msgrcv scalar kill dbmclose undef lc ma syswrite tr send umask sysopen shmwrite vec qx utime local oct semctl localtime readpipe do return format read sprintf dbmopen pop getpgrp not getpwnam rewinddir qqfileno qw endprotoent wait sethostent bless s|0 opendir continue each sleep endgrent shutdown dump chomp connect getsockname die socketpair close flock exists index shmgetsub for endpwent redo lstat msgctl setpgrp abs exit select print ref gethostbyaddr unshift fcntl syscall goto getnetbyaddr join gmtime symlink semget splice x|0 getpeername recv log setsockopt cos last reverse gethostbyname getgrnam study formline endhostent times chop length gethostent getnetent pack getprotoent getservbyname rand mkdir pos chmod y|0 substr endnetent printf next open msgsnd readdir use unlink getsockopt getpriority rindex wantarray hex system getservbyport endservent int chr untie rmdir prototype tell listen fork shmread ucfirst setprotoent else sysseek link getgrgid shmctl waitpid unpack getnetbyname reset chdir grep split require caller lcfirst until warn while values shift telldir getpwuid my getprotobynumber delete and sort uc defined srand accept package seekdir getprotobyname semop our rename seek if q|0 chroot sysread setpwent no crypt getc chown sqrt write setnetent setpriority foreach tie sin msgget map stat getlogin unless elsif truncate exec keys glob tied closedirioctl socket readlink eval xor readline binmode setservent eof ord bind alarm pipe atan2 getgrent exp time push setgrent gt lt or ne m|0 break given say state when",r={cN:"subst",b:"[$@]\\{",e:"\\}",k:t},s={b:"->{",e:"}"},n={v:[{b:/\$\d/},{b:/[\$%@](\^\w\b|#\w+(::\w+)*|{\w+}|\w+(::\w*)*)/},{b:/[\$%@][^\s\w{]/,r:0}]},i=[e.BE,r,n],o=[n,e.HCM,e.C("^\\=\\w","\\=cut",{eW:!0}),s,{cN:"string",c:i,v:[{b:"q[qwxr]?\\s*\\(",e:"\\)",r:5},{b:"q[qwxr]?\\s*\\[",e:"\\]",r:5},{b:"q[qwxr]?\\s*\\{",e:"\\}",r:5},{b:"q[qwxr]?\\s*\\|",e:"\\|",r:5},{b:"q[qwxr]?\\s*\\<",e:"\\>",r:5},{b:"qw\\s+q",e:"q",r:5},{b:"'",e:"'",c:[e.BE]},{b:'"',e:'"'},{b:"`",e:"`",c:[e.BE]},{b:"{\\w+}",c:[],r:0},{b:"-?\\w+\\s*\\=\\>",c:[],r:0}]},{cN:"number",b:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",r:0},{b:"(\\/\\/|"+e.RSR+"|\\b(split|return|print|reverse|grep)\\b)\\s*",k:"split return print reverse grep",r:0,c:[e.HCM,{cN:"regexp",b:"(s|tr|y)/(\\\\.|[^/])*/(\\\\.|[^/])*/[a-z]*",r:10},{cN:"regexp",b:"(m|qr)?/",e:"/[a-z]*",c:[e.BE],r:0}]},{cN:"function",bK:"sub",e:"(\\s*\\(.*?\\))?[;{]",eE:!0,r:5,c:[e.TM]},{b:"-\\w\\b",r:0},{b:"^__DATA__$",e:"^__END__$",sL:"mojolicious",c:[{b:"^@@.*",e:"$",cN:"comment"}]}];return r.c=o,s.c=o,{aliases:["pl","pm"],l:/[\w\.]+/,k:t,c:o}});hljs.registerLanguage("objectivec",function(e){var t={cN:"built_in",b:"\\b(AV|CA|CF|CG|CI|CL|CM|CN|CT|MK|MP|MTK|MTL|NS|SCN|SK|UI|WK|XC)\\w+"},_={keyword:"int float while char export sizeof typedef const struct for union unsigned long volatile static bool mutable if do return goto void enum else break extern asm case short default double register explicit signed typename this switch continue wchar_t inline readonly assign readwrite self @synchronized id typeof nonatomic super unichar IBOutlet IBAction strong weak copy in out inout bycopy byref oneway __strong __weak __block __autoreleasing @private @protected @public @try @property @end @throw @catch @finally @autoreleasepool @synthesize @dynamic @selector @optional @required @encode @package @import @defs @compatibility_alias __bridge __bridge_transfer __bridge_retained __bridge_retain __covariant __contravariant __kindof _Nonnull _Nullable _Null_unspecified __FUNCTION__ __PRETTY_FUNCTION__ __attribute__ getter setter retain unsafe_unretained nonnull nullable null_unspecified null_resettable class instancetype NS_DESIGNATED_INITIALIZER NS_UNAVAILABLE NS_REQUIRES_SUPER NS_RETURNS_INNER_POINTER NS_INLINE NS_AVAILABLE NS_DEPRECATED NS_ENUM NS_OPTIONS NS_SWIFT_UNAVAILABLE NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_END NS_REFINED_FOR_SWIFT NS_SWIFT_NAME NS_SWIFT_NOTHROW NS_DURING NS_HANDLER NS_ENDHANDLER NS_VALUERETURN NS_VOIDRETURN",literal:"false true FALSE TRUE nil YES NO NULL",built_in:"BOOL dispatch_once_t dispatch_queue_t dispatch_sync dispatch_async dispatch_once"},i=/[a-zA-Z@][a-zA-Z0-9_]*/,n="@interface @class @protocol @implementation";return{aliases:["mm","objc","obj-c"],k:_,l:i,i:"</",c:[t,e.CLCM,e.CBCM,e.CNM,e.QSM,{cN:"string",v:[{b:'@"',e:'"',i:"\\n",c:[e.BE]},{b:"'",e:"[^\\\\]'",i:"[^\\\\][^']"}]},{cN:"meta",b:"#",e:"$",c:[{cN:"meta-string",v:[{b:'"',e:'"'},{b:"<",e:">"}]}]},{cN:"class",b:"("+n.split(" ").join("|")+")\\b",e:"({|$)",eE:!0,k:n,l:i,c:[e.UTM]},{b:"\\."+e.UIR,r:0}]}});hljs.registerLanguage("markdown",function(e){return{aliases:["md","mkdown","mkd"],c:[{cN:"section",v:[{b:"^#{1,6}",e:"$"},{b:"^.+?\\n[=-]{2,}$"}]},{b:"<",e:">",sL:"xml",r:0},{cN:"bullet",b:"^([*+-]|(\\d+\\.))\\s+"},{cN:"strong",b:"[*_]{2}.+?[*_]{2}"},{cN:"emphasis",v:[{b:"\\*.+?\\*"},{b:"_.+?_",r:0}]},{cN:"quote",b:"^>\\s+",e:"$"},{cN:"code",v:[{b:"^```w*s*$",e:"^```s*$"},{b:"`.+?`"},{b:"^( {4}|	)",e:"$",r:0}]},{b:"^[-\\*]{3,}",e:"$"},{b:"\\[.+?\\][\\(\\[].*?[\\)\\]]",rB:!0,c:[{cN:"string",b:"\\[",e:"\\]",eB:!0,rE:!0,r:0},{cN:"link",b:"\\]\\(",e:"\\)",eB:!0,eE:!0},{cN:"symbol",b:"\\]\\[",e:"\\]",eB:!0,eE:!0}],r:10},{b:/^\[[^\n]+\]:/,rB:!0,c:[{cN:"symbol",b:/\[/,e:/\]/,eB:!0,eE:!0},{cN:"link",b:/:\s*/,e:/$/,eB:!0}]}]}});hljs.registerLanguage("diff",function(e){return{aliases:["patch"],c:[{cN:"meta",r:10,v:[{b:/^@@ +\-\d+,\d+ +\+\d+,\d+ +@@$/},{b:/^\*\*\* +\d+,\d+ +\*\*\*\*$/},{b:/^\-\-\- +\d+,\d+ +\-\-\-\-$/}]},{cN:"comment",v:[{b:/Index: /,e:/$/},{b:/={3,}/,e:/$/},{b:/^\-{3}/,e:/$/},{b:/^\*{3} /,e:/$/},{b:/^\+{3}/,e:/$/},{b:/\*{5}/,e:/\*{5}$/}]},{cN:"addition",b:"^\\+",e:"$"},{cN:"deletion",b:"^\\-",e:"$"},{cN:"addition",b:"^\\!",e:"$"}]}});hljs.registerLanguage("cs",function(e){var i={keyword:"abstract as base bool break byte case catch char checked const continue decimal default delegate do double enum event explicit extern finally fixed float for foreach goto if implicit in int interface internal is lock long nameof object operator out override params private protected public readonly ref sbyte sealed short sizeof stackalloc static string struct switch this try typeof uint ulong unchecked unsafe ushort using virtual void volatile while add alias ascending async await by descending dynamic equals from get global group into join let on orderby partial remove select set value var where yield",literal:"null false true"},t={cN:"string",b:'@"',e:'"',c:[{b:'""'}]},r=e.inherit(t,{i:/\n/}),a={cN:"subst",b:"{",e:"}",k:i},c=e.inherit(a,{i:/\n/}),n={cN:"string",b:/\$"/,e:'"',i:/\n/,c:[{b:"{{"},{b:"}}"},e.BE,c]},s={cN:"string",b:/\$@"/,e:'"',c:[{b:"{{"},{b:"}}"},{b:'""'},a]},o=e.inherit(s,{i:/\n/,c:[{b:"{{"},{b:"}}"},{b:'""'},c]});a.c=[s,n,t,e.ASM,e.QSM,e.CNM,e.CBCM],c.c=[o,n,r,e.ASM,e.QSM,e.CNM,e.inherit(e.CBCM,{i:/\n/})];var l={v:[s,n,t,e.ASM,e.QSM]},b=e.IR+"(<"+e.IR+"(\\s*,\\s*"+e.IR+")*>)?(\\[\\])?";return{aliases:["csharp"],k:i,i:/::/,c:[e.C("///","$",{rB:!0,c:[{cN:"doctag",v:[{b:"///",r:0},{b:"<!--|-->"},{b:"</?",e:">"}]}]}),e.CLCM,e.CBCM,{cN:"meta",b:"#",e:"$",k:{"meta-keyword":"if else elif endif define undef warning error line region endregion pragma checksum"}},l,e.CNM,{bK:"class interface",e:/[{;=]/,i:/[^\s:]/,c:[e.TM,e.CLCM,e.CBCM]},{bK:"namespace",e:/[{;=]/,i:/[^\s:]/,c:[e.inherit(e.TM,{b:"[a-zA-Z](\\.?\\w)*"}),e.CLCM,e.CBCM]},{cN:"meta",b:"^\\s*\\[",eB:!0,e:"\\]",eE:!0,c:[{cN:"meta-string",b:/"/,e:/"/}]},{bK:"new return throw await else",r:0},{cN:"function",b:"("+b+"\\s+)+"+e.IR+"\\s*\\(",rB:!0,e:/[{;=]/,eE:!0,k:i,c:[{b:e.IR+"\\s*\\(",rB:!0,c:[e.TM],r:0},{cN:"params",b:/\(/,e:/\)/,eB:!0,eE:!0,k:i,r:0,c:[l,e.CNM,e.CBCM]},e.CLCM,e.CBCM]}]}});hljs.registerLanguage("sql",function(e){var t=e.C("--","$");return{cI:!0,i:/[<>{}*#]/,c:[{bK:"begin end start commit rollback savepoint lock alter create drop rename call delete do handler insert load replace select truncate update set show pragma grant merge describe use explain help declare prepare execute deallocate release unlock purge reset change stop analyze cache flush optimize repair kill install uninstall checksum restore check backup revoke comment",e:/;/,eW:!0,l:/[\w\.]+/,k:{keyword:"abort abs absolute acc acce accep accept access accessed accessible account acos action activate add addtime admin administer advanced advise aes_decrypt aes_encrypt after agent aggregate ali alia alias allocate allow alter always analyze ancillary and any anydata anydataset anyschema anytype apply archive archived archivelog are as asc ascii asin assembly assertion associate asynchronous at atan atn2 attr attri attrib attribu attribut attribute attributes audit authenticated authentication authid authors auto autoallocate autodblink autoextend automatic availability avg backup badfile basicfile before begin beginning benchmark between bfile bfile_base big bigfile bin binary_double binary_float binlog bit_and bit_count bit_length bit_or bit_xor bitmap blob_base block blocksize body both bound buffer_cache buffer_pool build bulk by byte byteordermark bytes cache caching call calling cancel capacity cascade cascaded case cast catalog category ceil ceiling chain change changed char_base char_length character_length characters characterset charindex charset charsetform charsetid check checksum checksum_agg child choose chr chunk class cleanup clear client clob clob_base clone close cluster_id cluster_probability cluster_set clustering coalesce coercibility col collate collation collect colu colum column column_value columns columns_updated comment commit compact compatibility compiled complete composite_limit compound compress compute concat concat_ws concurrent confirm conn connec connect connect_by_iscycle connect_by_isleaf connect_by_root connect_time connection consider consistent constant constraint constraints constructor container content contents context contributors controlfile conv convert convert_tz corr corr_k corr_s corresponding corruption cos cost count count_big counted covar_pop covar_samp cpu_per_call cpu_per_session crc32 create creation critical cross cube cume_dist curdate current current_date current_time current_timestamp current_user cursor curtime customdatum cycle data database databases datafile datafiles datalength date_add date_cache date_format date_sub dateadd datediff datefromparts datename datepart datetime2fromparts day day_to_second dayname dayofmonth dayofweek dayofyear days db_role_change dbtimezone ddl deallocate declare decode decompose decrement decrypt deduplicate def defa defau defaul default defaults deferred defi defin define degrees delayed delegate delete delete_all delimited demand dense_rank depth dequeue des_decrypt des_encrypt des_key_file desc descr descri describ describe descriptor deterministic diagnostics difference dimension direct_load directory disable disable_all disallow disassociate discardfile disconnect diskgroup distinct distinctrow distribute distributed div do document domain dotnet double downgrade drop dumpfile duplicate duration each edition editionable editions element ellipsis else elsif elt empty enable enable_all enclosed encode encoding encrypt end end-exec endian enforced engine engines enqueue enterprise entityescaping eomonth error errors escaped evalname evaluate event eventdata events except exception exceptions exchange exclude excluding execu execut execute exempt exists exit exp expire explain export export_set extended extent external external_1 external_2 externally extract failed failed_login_attempts failover failure far fast feature_set feature_value fetch field fields file file_name_convert filesystem_like_logging final finish first first_value fixed flash_cache flashback floor flush following follows for forall force form forma format found found_rows freelist freelists freepools fresh from from_base64 from_days ftp full function general generated get get_format get_lock getdate getutcdate global global_name globally go goto grant grants greatest group group_concat group_id grouping grouping_id groups gtid_subtract guarantee guard handler hash hashkeys having hea head headi headin heading heap help hex hierarchy high high_priority hosts hour http id ident_current ident_incr ident_seed identified identity idle_time if ifnull ignore iif ilike ilm immediate import in include including increment index indexes indexing indextype indicator indices inet6_aton inet6_ntoa inet_aton inet_ntoa infile initial initialized initially initrans inmemory inner innodb input insert install instance instantiable instr interface interleaved intersect into invalidate invisible is is_free_lock is_ipv4 is_ipv4_compat is_not is_not_null is_used_lock isdate isnull isolation iterate java join json json_exists keep keep_duplicates key keys kill language large last last_day last_insert_id last_value lax lcase lead leading least leaves left len lenght length less level levels library like like2 like4 likec limit lines link list listagg little ln load load_file lob lobs local localtime localtimestamp locate locator lock locked log log10 log2 logfile logfiles logging logical logical_reads_per_call logoff logon logs long loop low low_priority lower lpad lrtrim ltrim main make_set makedate maketime managed management manual map mapping mask master master_pos_wait match matched materialized max maxextents maximize maxinstances maxlen maxlogfiles maxloghistory maxlogmembers maxsize maxtrans md5 measures median medium member memcompress memory merge microsecond mid migration min minextents minimum mining minus minute minvalue missing mod mode model modification modify module monitoring month months mount move movement multiset mutex name name_const names nan national native natural nav nchar nclob nested never new newline next nextval no no_write_to_binlog noarchivelog noaudit nobadfile nocheck nocompress nocopy nocycle nodelay nodiscardfile noentityescaping noguarantee nokeep nologfile nomapping nomaxvalue nominimize nominvalue nomonitoring none noneditionable nonschema noorder nopr nopro noprom nopromp noprompt norely noresetlogs noreverse normal norowdependencies noschemacheck noswitch not nothing notice notrim novalidate now nowait nth_value nullif nulls num numb numbe nvarchar nvarchar2 object ocicoll ocidate ocidatetime ociduration ociinterval ociloblocator ocinumber ociref ocirefcursor ocirowid ocistring ocitype oct octet_length of off offline offset oid oidindex old on online only opaque open operations operator optimal optimize option optionally or oracle oracle_date oradata ord ordaudio orddicom orddoc order ordimage ordinality ordvideo organization orlany orlvary out outer outfile outline output over overflow overriding package pad parallel parallel_enable parameters parent parse partial partition partitions pascal passing password password_grace_time password_lock_time password_reuse_max password_reuse_time password_verify_function patch path patindex pctincrease pctthreshold pctused pctversion percent percent_rank percentile_cont percentile_disc performance period period_add period_diff permanent physical pi pipe pipelined pivot pluggable plugin policy position post_transaction pow power pragma prebuilt precedes preceding precision prediction prediction_cost prediction_details prediction_probability prediction_set prepare present preserve prior priority private private_sga privileges procedural procedure procedure_analyze processlist profiles project prompt protection public publishingservername purge quarter query quick quiesce quota quotename radians raise rand range rank raw read reads readsize rebuild record records recover recovery recursive recycle redo reduced ref reference referenced references referencing refresh regexp_like register regr_avgx regr_avgy regr_count regr_intercept regr_r2 regr_slope regr_sxx regr_sxy reject rekey relational relative relaylog release release_lock relies_on relocate rely rem remainder rename repair repeat replace replicate replication required reset resetlogs resize resource respect restore restricted result result_cache resumable resume retention return returning returns reuse reverse revoke right rlike role roles rollback rolling rollup round row row_count rowdependencies rowid rownum rows rtrim rules safe salt sample save savepoint sb1 sb2 sb4 scan schema schemacheck scn scope scroll sdo_georaster sdo_topo_geometry search sec_to_time second section securefile security seed segment select self sequence sequential serializable server servererror session session_user sessions_per_user set sets settings sha sha1 sha2 share shared shared_pool short show shrink shutdown si_averagecolor si_colorhistogram si_featurelist si_positionalcolor si_stillimage si_texture siblings sid sign sin size size_t sizes skip slave sleep smalldatetimefromparts smallfile snapshot some soname sort soundex source space sparse spfile split sql sql_big_result sql_buffer_result sql_cache sql_calc_found_rows sql_small_result sql_variant_property sqlcode sqldata sqlerror sqlname sqlstate sqrt square standalone standby start starting startup statement static statistics stats_binomial_test stats_crosstab stats_ks_test stats_mode stats_mw_test stats_one_way_anova stats_t_test_ stats_t_test_indep stats_t_test_one stats_t_test_paired stats_wsr_test status std stddev stddev_pop stddev_samp stdev stop storage store stored str str_to_date straight_join strcmp strict string struct stuff style subdate subpartition subpartitions substitutable substr substring subtime subtring_index subtype success sum suspend switch switchoffset switchover sync synchronous synonym sys sys_xmlagg sysasm sysaux sysdate sysdatetimeoffset sysdba sysoper system system_user sysutcdatetime table tables tablespace tan tdo template temporary terminated tertiary_weights test than then thread through tier ties time time_format time_zone timediff timefromparts timeout timestamp timestampadd timestampdiff timezone_abbr timezone_minute timezone_region to to_base64 to_date to_days to_seconds todatetimeoffset trace tracking transaction transactional translate translation treat trigger trigger_nestlevel triggers trim truncate try_cast try_convert try_parse type ub1 ub2 ub4 ucase unarchived unbounded uncompress under undo unhex unicode uniform uninstall union unique unix_timestamp unknown unlimited unlock unpivot unrecoverable unsafe unsigned until untrusted unusable unused update updated upgrade upped upper upsert url urowid usable usage use use_stored_outlines user user_data user_resources users using utc_date utc_timestamp uuid uuid_short validate validate_password_strength validation valist value values var var_samp varcharc vari varia variab variabl variable variables variance varp varraw varrawc varray verify version versions view virtual visible void wait wallet warning warnings week weekday weekofyear wellformed when whene whenev wheneve whenever where while whitespace with within without work wrapped xdb xml xmlagg xmlattributes xmlcast xmlcolattval xmlelement xmlexists xmlforest xmlindex xmlnamespaces xmlpi xmlquery xmlroot xmlschema xmlserialize xmltable xmltype xor year year_to_month years yearweek",literal:"true false null",built_in:"array bigint binary bit blob boolean char character date dec decimal float int int8 integer interval number numeric real record serial serial8 smallint text varchar varying void"},c:[{cN:"string",b:"'",e:"'",c:[e.BE,{b:"''"}]},{cN:"string",b:'"',e:'"',c:[e.BE,{b:'""'}]},{cN:"string",b:"`",e:"`",c:[e.BE]},e.CNM,e.CBCM,t]},e.CBCM,t]}});hljs.registerLanguage("cpp",function(t){var e={cN:"keyword",b:"\\b[a-z\\d_]*_t\\b"},r={cN:"string",v:[{b:'(u8?|U)?L?"',e:'"',i:"\\n",c:[t.BE]},{b:'(u8?|U)?R"',e:'"',c:[t.BE]},{b:"'\\\\?.",e:"'",i:"."}]},s={cN:"number",v:[{b:"\\b(0b[01']+)"},{b:"(-?)\\b([\\d']+(\\.[\\d']*)?|\\.[\\d']+)(u|U|l|L|ul|UL|f|F|b|B)"},{b:"(-?)(\\b0[xX][a-fA-F0-9']+|(\\b[\\d']+(\\.[\\d']*)?|\\.[\\d']+)([eE][-+]?[\\d']+)?)"}],r:0},i={cN:"meta",b:/#\s*[a-z]+\b/,e:/$/,k:{"meta-keyword":"if else elif endif define undef warning error line pragma ifdef ifndef include"},c:[{b:/\\\n/,r:0},t.inherit(r,{cN:"meta-string"}),{cN:"meta-string",b:/<[^\n>]*>/,e:/$/,i:"\\n"},t.CLCM,t.CBCM]},a=t.IR+"\\s*\\(",c={keyword:"int float while private char catch import module export virtual operator sizeof dynamic_cast|10 typedef const_cast|10 const for static_cast|10 union namespace unsigned long volatile static protected bool template mutable if public friend do goto auto void enum else break extern using asm case typeid short reinterpret_cast|10 default double register explicit signed typename try this switch continue inline delete alignof constexpr decltype noexcept static_assert thread_local restrict _Bool complex _Complex _Imaginary atomic_bool atomic_char atomic_schar atomic_uchar atomic_short atomic_ushort atomic_int atomic_uint atomic_long atomic_ulong atomic_llong atomic_ullong new throw return and or not",built_in:"std string cin cout cerr clog stdin stdout stderr stringstream istringstream ostringstream auto_ptr deque list queue stack vector map set bitset multiset multimap unordered_set unordered_map unordered_multiset unordered_multimap array shared_ptr abort abs acos asin atan2 atan calloc ceil cosh cos exit exp fabs floor fmod fprintf fputs free frexp fscanf isalnum isalpha iscntrl isdigit isgraph islower isprint ispunct isspace isupper isxdigit tolower toupper labs ldexp log10 log malloc realloc memchr memcmp memcpy memset modf pow printf putchar puts scanf sinh sin snprintf sprintf sqrt sscanf strcat strchr strcmp strcpy strcspn strlen strncat strncmp strncpy strpbrk strrchr strspn strstr tanh tan vfprintf vprintf vsprintf endl initializer_list unique_ptr",literal:"true false nullptr NULL"},n=[e,t.CLCM,t.CBCM,s,r];return{aliases:["c","cc","h","c++","h++","hpp"],k:c,i:"</",c:n.concat([i,{b:"\\b(deque|list|queue|stack|vector|map|set|bitset|multiset|multimap|unordered_map|unordered_set|unordered_multiset|unordered_multimap|array)\\s*<",e:">",k:c,c:["self",e]},{b:t.IR+"::",k:c},{v:[{b:/=/,e:/;/},{b:/\(/,e:/\)/},{bK:"new throw return else",e:/;/}],k:c,c:n.concat([{b:/\(/,e:/\)/,k:c,c:n.concat(["self"]),r:0}]),r:0},{cN:"function",b:"("+t.IR+"[\\*&\\s]+)+"+a,rB:!0,e:/[{;=]/,eE:!0,k:c,i:/[^\w\s\*&]/,c:[{b:a,rB:!0,c:[t.TM],r:0},{cN:"params",b:/\(/,e:/\)/,k:c,r:0,c:[t.CLCM,t.CBCM,r,s,e]},t.CLCM,t.CBCM,i]},{cN:"class",bK:"class struct",e:/[{;:]/,c:[{b:/</,e:/>/,c:["self"]},t.TM]}]),exports:{preprocessor:i,strings:r,k:c}}});hljs.registerLanguage("ruby",function(e){var b="[a-zA-Z_]\\w*[!?=]?|[-+~]\\@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\]=?",r={keyword:"and then defined module in return redo if BEGIN retry end for self when next until do begin unless END rescue else break undef not super class case require yield alias while ensure elsif or include attr_reader attr_writer attr_accessor",literal:"true false nil"},c={cN:"doctag",b:"@[A-Za-z]+"},a={b:"#<",e:">"},s=[e.C("#","$",{c:[c]}),e.C("^\\=begin","^\\=end",{c:[c],r:10}),e.C("^__END__","\\n$")],n={cN:"subst",b:"#\\{",e:"}",k:r},t={cN:"string",c:[e.BE,n],v:[{b:/'/,e:/'/},{b:/"/,e:/"/},{b:/`/,e:/`/},{b:"%[qQwWx]?\\(",e:"\\)"},{b:"%[qQwWx]?\\[",e:"\\]"},{b:"%[qQwWx]?{",e:"}"},{b:"%[qQwWx]?<",e:">"},{b:"%[qQwWx]?/",e:"/"},{b:"%[qQwWx]?%",e:"%"},{b:"%[qQwWx]?-",e:"-"},{b:"%[qQwWx]?\\|",e:"\\|"},{b:/\B\?(\\\d{1,3}|\\x[A-Fa-f0-9]{1,2}|\\u[A-Fa-f0-9]{4}|\\?\S)\b/},{b:/<<(-?)\w+$/,e:/^\s*\w+$/}]},i={cN:"params",b:"\\(",e:"\\)",endsParent:!0,k:r},d=[t,a,{cN:"class",bK:"class module",e:"$|;",i:/=/,c:[e.inherit(e.TM,{b:"[A-Za-z_]\\w*(::\\w+)*(\\?|\\!)?"}),{b:"<\\s*",c:[{b:"("+e.IR+"::)?"+e.IR}]}].concat(s)},{cN:"function",bK:"def",e:"$|;",c:[e.inherit(e.TM,{b:b}),i].concat(s)},{b:e.IR+"::"},{cN:"symbol",b:e.UIR+"(\\!|\\?)?:",r:0},{cN:"symbol",b:":(?!\\s)",c:[t,{b:b}],r:0},{cN:"number",b:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",r:0},{b:"(\\$\\W)|((\\$|\\@\\@?)(\\w+))"},{cN:"params",b:/\|/,e:/\|/,k:r},{b:"("+e.RSR+"|unless)\\s*",k:"unless",c:[a,{cN:"regexp",c:[e.BE,n],i:/\n/,v:[{b:"/",e:"/[a-z]*"},{b:"%r{",e:"}[a-z]*"},{b:"%r\\(",e:"\\)[a-z]*"},{b:"%r!",e:"![a-z]*"},{b:"%r\\[",e:"\\][a-z]*"}]}].concat(s),r:0}].concat(s);n.c=d,i.c=d;var l="[>?]>",o="[\\w#]+\\(\\w+\\):\\d+:\\d+>",u="(\\w+-)?\\d+\\.\\d+\\.\\d(p\\d+)?[^>]+>",w=[{b:/^\s*=>/,starts:{e:"$",c:d}},{cN:"meta",b:"^("+l+"|"+o+"|"+u+")",starts:{e:"$",c:d}}];return{aliases:["rb","gemspec","podspec","thor","irb"],k:r,i:/\/\*/,c:s.concat(w).concat(d)}});
\ No newline at end of file
diff --git a/pagure/static/vendor/highlight.js/styles/github.css b/pagure/static/vendor/highlight.js/styles/github.css
new file mode 100644
index 0000000..791932b
--- /dev/null
+++ b/pagure/static/vendor/highlight.js/styles/github.css
@@ -0,0 +1,99 @@
+/*
+
+github.com style (c) Vasily Polovnyov <vast@whiteants.net>
+
+*/
+
+.hljs {
+  display: block;
+  overflow-x: auto;
+  padding: 0.5em;
+  color: #333;
+  background: #f8f8f8;
+}
+
+.hljs-comment,
+.hljs-quote {
+  color: #998;
+  font-style: italic;
+}
+
+.hljs-keyword,
+.hljs-selector-tag,
+.hljs-subst {
+  color: #333;
+  font-weight: bold;
+}
+
+.hljs-number,
+.hljs-literal,
+.hljs-variable,
+.hljs-template-variable,
+.hljs-tag .hljs-attr {
+  color: #008080;
+}
+
+.hljs-string,
+.hljs-doctag {
+  color: #d14;
+}
+
+.hljs-title,
+.hljs-section,
+.hljs-selector-id {
+  color: #900;
+  font-weight: bold;
+}
+
+.hljs-subst {
+  font-weight: normal;
+}
+
+.hljs-type,
+.hljs-class .hljs-title {
+  color: #458;
+  font-weight: bold;
+}
+
+.hljs-tag,
+.hljs-name,
+.hljs-attribute {
+  color: #000080;
+  font-weight: normal;
+}
+
+.hljs-regexp,
+.hljs-link {
+  color: #009926;
+}
+
+.hljs-symbol,
+.hljs-bullet {
+  color: #990073;
+}
+
+.hljs-built_in,
+.hljs-builtin-name {
+  color: #0086b3;
+}
+
+.hljs-meta {
+  color: #999;
+  font-weight: bold;
+}
+
+.hljs-deletion {
+  background: #fdd;
+}
+
+.hljs-addition {
+  background: #dfd;
+}
+
+.hljs-emphasis {
+  font-style: italic;
+}
+
+.hljs-strong {
+  font-weight: bold;
+}
diff --git a/pagure/templates/commit.html b/pagure/templates/commit.html
index 875a62f..a1d9353 100644
--- a/pagure/templates/commit.html
+++ b/pagure/templates/commit.html
@@ -3,116 +3,210 @@
 {% block title %}Commit - {{
     repo.namespace + '/' if repo.namespace }}{{ repo.name }} - {{ commitid }}{% endblock %}
 {% set tag = "commit"%}
-
+{% block header %}
+<link href="{{ url_for('static', filename='vendor/highlight.js/styles/github.css') }}"
+  rel="stylesheet" />
+<link href="{{ url_for('static', filename='vendor/diff2html/diff2html.css') }}"
+  rel="stylesheet" />
+  {% if splitview %}
+  <style>
+      .repo-body-container{max-width:100%!important}
+  </style>
+  {% endif %}
+{% endblock %}
 {% block repo %}
-
 {% set splitted_message = commit.message.split('\n') %}
 <div class="row">
   <div class="col">
       {% block overviewtabs %}{{ super() }}{% endblock %}
   </div>
   <div class="col-10">
-    <div class="header">
-      <h4>
-        <span class="label label-default" title="{{ commitid }}">Commit {{ commitid|short }}</span>
+    <div class="d-flex">
+      <div>
+        <h4 class="font-weight-bold">
+        <span title="{{ commitid }}"><code class="text-white bg-primary">{{ commitid|short }}</code></span>
         <span>{{ splitted_message[0] }}</span>
-        <div class="pull-xs-right btn-group">
-          <a class="btn btn-secondary btn-sm" href="{{ url_for(
-            'ui_ns.view_raw_file',
-            repo=repo.name,
-            username=username,
-            namespace=repo.namespace,
-            identifier=commitid) }}" title="View as raw">raw</a>
-          <a class="btn btn-secondary btn-sm" href="{{ url_for(
-            'ui_ns.view_commit_patch',
-            repo=repo.name,
-            username=username,
-            namespace=repo.namespace,
-            commitid=commitid) }}">patch</a>
-          <a class="btn btn-secondary btn-sm" href="{{ url_for(
-            'ui_ns.view_tree', username=username, namespace=repo.namespace,
-            repo=repo.name, identifier=commitid) }}">tree</a>
-          {% if commit.parents|length == 1 %}
-          <a class="btn btn-secondary btn-sm" title={{commit.parents[0].oid.hex}} href="{{ url_for(
-            'ui_ns.view_commit',
-            repo=repo.name,
-            username=username,
-            namespace=repo.namespace,
-            commitid=commit.parents[0].oid.hex) }}">parent</a>
-          {% elif commit.parents|length > 1 %}
-          <div class="btn-group" role="group">
-            <button id="parentsDrop" type="button" class="btn btn-secondary btn-sm dropdown-toggle"
-                data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
-              parents
-            </button>
-            <div class="dropdown-menu dropdown-menu-right" aria-labelledby="parentsDrop">
-              {% for parent in commit.parents %}
-                <a class="dropdown-item" href="{{ url_for(
-                    'ui_ns.view_commit',
-                    repo=repo.name,
-                    username=username,
-                    namespace=repo.namespace,
-                    commitid=parent.oid.hex)
-                }}" class="commitid">{{parent.oid.hex}}</a>
-              {% endfor %}
+        </h4>
+        <h5 class="text-muted pt-1 mb-0">
+            {% if commit.author| author2user == commit.committer| author2user %}
+              {% if commit.parents | length == 1 %}
+                Authored and Committed by {{ commit.author | author2user |safe }}
+              {% else %}
+                Merged and Committed by {{ commit.author | author2user |safe }}
+              {% endif %}
+              <span data-toggle="tooltip" title="{{ commit.commit_time | format_ts }}">
+                {{ commit.commit_time | humanize }}
+              </span>
+            {% else %}
+              <a href="#" id="diff_list_link">{{ diff|count}} file{{'s' if diff|count > 1 }}</a>
+              {% if commit.parents | length == 1 %}
+                Authored by {{ commit.author | author2user |safe }}
+              {% else %}
+                Merged by {{ commit.author | author2user |safe }}
+              {% endif %}
+              <span data-toggle="tooltip" title="{{ commit.commit_time | format_ts }}">
+                {{ commit.commit_time | humanize }}
+              </span>,
+              Committed by {{ commit.committer | author2user |safe }}
+              <span data-toggle="tooltip" title="{{ commit.commit_time | format_ts }}">
+                {{ commit.commit_time | humanize }}
+              </span>,
+            {% endif%}
+          </h5>
+      </div>
+      <div class="ml-auto">
+          <div class="btn-group">
+              <a class="btn btn-outline-primary btn-sm" href="{{ url_for(
+                'ui_ns.view_raw_file',
+                repo=repo.name,
+                username=username,
+                namespace=repo.namespace,
+                identifier=commitid) }}" title="View as raw">raw</a>
+              <a class="btn btn-outline-primary btn-sm" href="{{ url_for(
+                'ui_ns.view_commit_patch',
+                repo=repo.name,
+                username=username,
+                namespace=repo.namespace,
+                commitid=commitid) }}">patch</a>
+              <a class="btn btn-outline-primary  btn-sm" href="{{ url_for(
+                'ui_ns.view_tree', username=username, namespace=repo.namespace,
+                repo=repo.name, identifier=commitid) }}">tree</a>
+              {% if commit.parents|length == 1 %}
+              <a class="btn btn-outline-primary btn-sm" title={{commit.parents[0].oid.hex}} href="{{ url_for(
+                'ui_ns.view_commit',
+                repo=repo.name,
+                username=username,
+                namespace=repo.namespace,
+                commitid=commit.parents[0].oid.hex) }}">parent</a>
+              {% elif commit.parents|length > 1 %}
+              <div class="btn-group" role="group">
+                <button id="parentsDrop" type="button" class="btn btn-secondary btn-sm dropdown-toggle"
+                    data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
+                  parents
+                </button>
+                <div class="dropdown-menu dropdown-menu-right" aria-labelledby="parentsDrop">
+                  {% for parent in commit.parents %}
+                    <a class="dropdown-item" href="{{ url_for(
+                        'ui_ns.view_commit',
+                        repo=repo.name,
+                        username=username,
+                        namespace=repo.namespace,
+                        commitid=parent.oid.hex)
+                    }}" class="commitid">{{parent.oid.hex}}</a>
+                  {% endfor %}
+                </div>
+              </div>
+              {% endif%}
             </div>
-          </div>
-          {% endif%}
-        </div>
-      </h4>
-      <h5 class="text-muted">
-        {% if commit.author| author2user == commit.committer| author2user %}
-          <a href="#" id="diff_list_link">{{ diff|count}} file{{'s' if diff|count > 1 }}</a>
-          {% if commit.parents | length == 1 %}
-            Authored and Committed by {{ commit.author | author2user |safe }}
-          {% else %}
-            Merged and Committed by {{ commit.author | author2user |safe }}
-          {% endif %}
-          <span data-toggle="tooltip" title="{{ commit.commit_time | format_ts }}">
-            {{ commit.commit_time | humanize }}
-          </span>
-        {% else %}
-          <a href="#" id="diff_list_link">{{ diff|count}} file{{'s' if diff|count > 1 }}</a>
-          {% if commit.parents | length == 1 %}
-            Authored by {{ commit.author | author2user |safe }}
-          {% else %}
-            Merged by {{ commit.author | author2user |safe }}
-          {% endif %}
-          <span data-toggle="tooltip" title="{{ commit.commit_time | format_ts }}">
-            {{ commit.commit_time | humanize }}
-          </span>,
-          Committed by {{ commit.committer | author2user |safe }}
-          <span data-toggle="tooltip" title="{{ commit.commit_time | format_ts }}">
-            {{ commit.commit_time | humanize }}
-          </span>,
-        {% endif%}
-      </h5>
+      </div>
     </div>
 
-    <div class="list-group" id="diff_list" style="display:none;">
-      {% set filecount = 0 %}
-      {% for patch in diff %}
-          {% set filecount = filecount + 1 %}
-            <a class="list-group-item" href="#diff-file-{{filecount}}">
-              {{  patch.delta.new_file.path | unicode }}
-          <div class="pull-xs-right">
-            {% if not patch.is_binary  %}
-            {% if (patch.line_stats[1] + patch.line_stats[2]) %}
-              <span style="width: {{ (100.0 * patch.line_stats[1] / (patch.line_stats[1] + patch.line_stats[2]))|round|int }}%">
-                {% if patch.line_stats[1] > 0 %}<span class="label label-success">+{{ patch.line_stats[1] }}</span>{% endif %}
-                {% if patch.line_stats[2] > 0 %}<span class="label label-danger">-{{ patch.line_stats[2] }}</span>{% endif %}
-              </span>
-            {% endif %}
-            {% endif %}
+    {% macro changeschangedfile(filepath, added, removed, diffanchor) -%}
+    <a href="#_{{diffanchor}}" class="list-group-item list-group-item-action">
+      <div class="d-flex">
+          <div class="font-weight-bold">
+            {{ filepath | unicode }}
           </div>
-          {% if patch | hasattr('new_file_path') %}
-            {{ patch.new_file_path | unicode }}
-          {% elif patch | hasattr('delta') %}
-            {{  patch.delta.new_file.path | unicode }}
-          {% endif %}
-        </a>
-      {% endfor %}
-    </div>
+          <div class="ml-auto font-weight-bold">
+              <span class="font-weight-bold btn btn-sm btn-outline-secondary border-0 disabled opacity-100">file modified</span>
+              <div class="btn-group">
+                  <span class="font-weight-bold btn btn-sm btn-success disabled opacity-100">+{{added}}</span>
+                  <span class="font-weight-bold btn btn-sm btn-danger disabled opacity-100">-{{removed}}</span>
+                </div>
+          </div>
+      </div>
+    </a>
+    {%- endmacro %}
+    {% macro changesrenamedfile(oldfilepath, newfilepath, added, removed, diffanchor) -%}
+    <a href="#_{{diffanchor}}" class="list-group-item list-group-item-action">
+        <div class="d-flex">
+            <div class="font-weight-bold">
+                {{ newfilepath | unicode }}<strike>{{ oldfilepath | unicode }}</strike> 
+            </div>
+            <div class="ml-auto font-weight-bold">
+                <span class="font-weight-bold btn btn-sm btn-outline-info border-0 disabled opacity-100">file renamed</span>
+                <div class="btn-group">
+                  <span class="font-weight-bold btn btn-sm btn-success disabled opacity-100">+{{added}}</span>
+                  <span class="font-weight-bold btn btn-sm btn-danger disabled opacity-100">-{{removed}}</span>
+                </div>
+            </div>
+        </div>
+      </a>
+    {%- endmacro %}
+    {% macro changesdeletedfile(filepath, added, removed, diffanchor) -%}
+    <a href="#_{{diffanchor}}" class="list-group-item list-group-item-action">
+        <div class="d-flex">
+            <div class="font-weight-bold">
+                {{filepath | unicode }}
+            </div>
+            <div class="ml-auto font-weight-bold">
+                <span class="font-weight-bold btn btn-sm btn-outline-danger border-0 disabled opacity-100">file removed</span>
+                <div class="btn-group">
+                    <span class="font-weight-bold btn btn-sm btn-danger disabled opacity-100">-{{removed}}</span>
+                  </div>
+            </div>
+        </div>
+    </a>
+    {%- endmacro %}
+    {% macro changesaddedfile(filepath, added, removed, diffanchor) -%}
+    <a href="#_{{diffanchor}}" class="list-group-item list-group-item-action">
+        <div class="d-flex">
+            <div class="font-weight-bold">
+                {{filepath | unicode }}
+            </div>
+            <div class="ml-auto font-weight-bold">
+                <span class="font-weight-bold btn btn-sm btn-outline-success border-0 disabled opacity-100">file added</span>
+                <div class="btn-group">
+                  <span class="font-weight-bold btn btn-sm btn-success disabled opacity-100">+{{added}}</span>
+                </div>
+            </div>
+        </div>
+    </a>
+    {%- endmacro %}
+    <div class="card border-0 mb-3">
+        <div class="card-header border-0 bg-white font-weight-bold p-0">
+            <a href="#commit-overview-collapse" data-toggle="collapse" data-target="#commit-overview-collapse">{{diff.stats.files_changed}} file{{'s' if diff.stats.files_changed > 1 }} changed.</a>
+            <span class="text-success">{{diff.stats.insertions}} lines added</span>.
+            <span class="text-danger">{{diff.stats.deletions}} lines removed</span>.
+        </div>
+        <div class="card-body p-0 collapse" id="commit-overview-collapse">
+            <div class="list-group ">
+                {% for patch in diff %}
+                      {% set linesadded = patch.line_stats[1] %}
+                      {% set linesremoved = patch.line_stats[2] %}
+                      {% if patch | hasattr('new_file_path') %}
+                        {%- if patch.new_file_path == patch.old_file_path -%}
+                          {%- if patch.status == 'D' -%}
+                            {{ changesdeletedfile(patch.new_file_path, linesadded, linesremoved, loop.index) }}
+                          {%- elif patch.status == 'A' -%}
+                            {{ changesaddedfile(patch.new_file_path | string, linesadded, linesremoved, loop.index) }}
+                          {%- elif patch.status == 'M' -%}
+                            {{ changeschangedfile(patch.new_file_path, linesadded, linesremoved, loop.index) }}
+                          {%-endif-%}
+                        {%- else -%}
+                          {{changesrenamedfile(patch.old_file_path, patch.new_file_path, linesadded, linesremoved, loop.index)}}
+                        {%- endif -%}
+                      {%- elif patch | hasattr('delta') -%}
+                        {%- if patch.delta.new_file.path == patch.delta.old_file.path -%}
+                          {%- if patch.delta.new_file.mode == 0
+                              and patch.delta.old_file.mode in [33188, 33261] -%}
+                            {{ changesdeletedfile(patch.delta.new_file.path, linesadded, linesremoved, loop.index) }}
+                          {%- elif patch.delta.new_file.mode in [33188, 33261]
+                               and patch.delta.old_file.mode == 0 -%}
+                            {{ changesaddedfile( patch.delta.new_file.path, linesadded, linesremoved, loop.index) }}
+                          {%- elif patch.delta.new_file.mode in [33188, 33261]
+                               and patch.delta.old_file.mode in [33188, 33261] -%}
+                            {{ changeschangedfile(patch.delta.new_file.path, linesadded, linesremoved, loop.index) }}
+                          {%-endif-%}
+                        {%- else -%}
+                          {{changesrenamedfile(patch.delta.old_file.path, patch.delta.new_file.path, linesadded, linesremoved, loop.index)}}
+                        {%- endif -%}
+                      {%- endif -%}
+                {% endfor %}
+                  </div>
+        </div>
+      </div>
+
 
     <div class="m-y-1">
         {% if splitted_message|length > 1 %}
@@ -124,6 +218,8 @@
         {% endif %}
     </div>
 
+    
+    {% if flags %}
     <section class="list-group" id="flag_list">
       <div class="card" id="pr_flags">
           <ul class="list-group list-group-flush">
@@ -151,37 +247,230 @@
           </ul>
         </div>
     </section>
+    {% endif %}
 
-    {% set filecount = 0 %}
-    {% for patch in diff %}
-      {% set filecount = filecount + 1 %}
-    <div class="card mb-3" id="diff-file-{{filecount}}">
-      <div class="card-header">
-          <a href="{{ url_for(
-              'ui_ns.view_file', username=username, namespace=repo.namespace,
-              repo=repo.name, identifier=commitid,
-              filename=patch.delta.new_file.path) }}" title="View file as of {{ commitid|short }}">
-            {{  patch.delta.new_file.path | unicode }}
-          </a>
-            {% if not patch.is_binary  %}
-              {% if (patch.line_stats[1] + patch.line_stats[2]) %}
-                <span style="width: {{ (100.0 * patch.line_stats[1] / (patch.line_stats[1] + patch.line_stats[2]))|round|int }}%">
-                  {% if patch.line_stats[1] > 0 %}<span class="label label-success">+{{ patch.line_stats[1] }}</span> {% endif %}
-                  {% if patch.line_stats[2] > 0 %}<span class="label label-danger">-{{ patch.line_stats[2] }}</span>{% endif %}
-                </span>
-              {% endif %}
-              {% endif %}
-      </div>
+    {% if diff %}
+      {% for patch in diff %}
+        {% if patch |hasattr('new_id') %}
+          {% set patch_new_id = patch.new_id %}
+        {% elif patch |hasattr('delta') %}
+          {% set patch_new_id = patch.delta.new_file.id %}
+        {% else %}
+          {% set patch_new_id = patch.new_oid %}
+        {% endif %}
 
-        {% if patch.is_binary %}
-            <p class="noresult">Binary diffs cannot be rendered.</p>
+        {% if patch |hasattr('old_id') %}
+          {% set patch_old_id = patch.old_id %}
+        {% elif patch |hasattr('delta') %}
+          {% set patch_old_id = patch.delta.old_file.id %}
         {% else %}
-            {% autoescape false %}
-            {{ patch|patch_to_diff|html_diff}}
-            {% endautoescape %}
+          {% set patch_old_id = patch.old_oid %}
         {% endif %}
-    </div>
-    {% endfor %}
+
+        {% if patch | hasattr('new_file_path') %}
+          {% set patch_new_file_path = patch.new_file_path -%}
+          {% if patch.new_file_path != patch.old_file_path %}
+            {% set patch_old_file_path = patch.old_file_path %}
+          {%- endif -%}
+        {%- elif patch | hasattr('delta') -%}
+          {% set patch_new_file_path = patch.delta.new_file.path -%}
+          {%- if patch.delta.new_file.path != patch.delta.old_file.path -%}
+            {% set patch_old_file_path = patch.delta.old_file.path %}
+          {%- endif -%}
+        {%- endif -%}
+
+
+    <section class="commit_diff">
+      <div class="card mt-3" id="_{{loop.index}}">
+        <div class="card-header">
+            <div class="d-flex align-items-center">
+              {% set linesadded = patch.line_stats[1] %}
+              {% set linesremoved = patch.line_stats[2] %}
+
+              {% macro lineschanged(added, removed) -%}
+                <div class="btn-group">
+                {%if added%}
+                  <span class="btn btn-success btn-sm font-weight-bold disabled opacity-100">+{{linesadded}}</span>
+                {%endif%}
+                {%if removed%}
+                  <span class="btn btn-danger btn-sm font-weight-bold disabled opacity-100">-{{linesremoved}}</span>
+                {%endif%}
+                </div>
+              {%endmacro%}
+
+              {% macro viewfilelink(filepath)%}
+                    <a class="font-weight-bold text-semimuted ml-2" href="{{
+                      url_for(
+                          'ui_ns.view_file',
+                          repo=repo.name,
+                          username=username,
+                          namespace=repo.namespace,
+                          identifier=commitid,
+                          filename=filepath) }}"
+                      title="View file as of {{ commitid|short }}">{{
+                      filepath | unicode }}</a>
+              {% endmacro %}
+
+              {% macro viewfilelinkbutton(filepath, disabled=False)%}
+              <a class="btn btn-outline-primary {{'disabled' if disabled}} btn-sm ml-2" href="{{
+                url_for(
+                    'ui_ns.view_file',
+                    repo=repo.name,
+                    username=username,
+                    namespace=repo.namespace,
+                    identifier=commitid,
+                    filename=filepath) }}"
+                title="View file as of {{ commitid|short }}">
+                <i class="fa fa-file-code-o fa-fw"></i>
+              </a>
+              {% endmacro %}
+
+              {% macro changedlabel(thelabel, thecolor)%}
+                <div class="btn btn-outline-{{thecolor}} disabled opacity-100 border-0 font-weight-bold">
+                  {{thelabel}}
+                </div>
+              {% endmacro %}
+
+
+              {% macro diffcollapsebtn()%}
+                <a href="diff2html_{{loop.index}}" class="btn btn-sm btn-outline-primary diffcollapse ml-2" data-toggle="collapse" data-target="#diff2html_{{loop.index}}">
+                  <i class="fa fa-fw fa-caret-up"></i>
+                </a>
+              {% endmacro %}
+
+              {% if patch | hasattr('new_file_path') %}
+                {%- if patch.new_file_path == patch.old_file_path -%}
+                  {%- if patch.status == 'D' -%}
+                    {% set patchtype = "removed"%}
+                    <div>
+                        {{ viewfilelink(patch.new_file.path) }}
+                    </div>
+                    <div class="d-flex align-items-center ml-auto">
+                      {{ changedlabel("file removed", "danger")}}
+                      {{ lineschanged(False, True) }}
+                      {{ viewfilelinkbutton(patch.new_file.path, disabled=True) }}
+                      {{ diffcollapsebtn() }}
+                    </div>
+                  {%-elif patch.status == 'A' -%}
+                    {% set patchtype = "added"%}
+                    <div>
+                        {{ viewfilelink(patch.new_file.path) }}
+                    </div>
+                    <div class="d-flex align-items-center ml-auto">
+                      {{ changedlabel("file changed", "success")}}
+                      {{ lineschanged(True, False) }}
+                      {{ viewfilelinkbutton(patch.new_file.path) }}
+                      {% if linesadded != 0%}
+                        {{ diffcollapsebtn() }}
+                      {% endif %}
+                    </div>
+                  {%-elif patch.status == 'M' -%}
+                    {% set patchtype = "changed"%}
+                    <div>
+                        {{ viewfilelink(patch.new_file.path) }}
+                    </div>
+                    <div class="d-flex align-items-center ml-auto">
+                      {{ changedlabel("file modified", "secondary")}}
+                      {{ lineschanged(True, True) }}
+                      {{ viewfilelinkbutton(patch.new_file.path) }}
+                      {{ diffcollapsebtn() }}
+                    </div>
+                  {%-endif-%}
+                {%- else -%}
+                  {% set patchtype = "moved"%}
+                  <div>
+                      {{ viewfilelink(patch.new_file.path) }}<strike>{{patch.old_file.path}}</strike> 
+                  </div>
+                  <div class="d-flex align-items-center ml-auto">
+                    {{ changedlabel("file renamed", "info")}}
+                    {% if linesadded != 0 and linesremoved != 0%}
+                      {{ lineschanged(True, True) }}
+                    {% endif %}
+                    {{ viewfilelinkbutton(patch.new_file.path) }}
+                    {% if linesadded != 0 and linesremoved != 0%}
+                      {{ diffcollapsebtn() }}
+                    {% endif %}
+                  </div>
+                {%- endif -%}
+              {%- elif patch | hasattr('delta') -%}
+                {%- if patch.delta.new_file.path == patch.delta.old_file.path -%}
+                  {%- if patch.delta.new_file.mode == 0
+                      and patch.delta.old_file.mode in [33188, 33261] -%}
+                    {% set patchtype = "removed"%}
+                    <div>
+                        {{ viewfilelink(patch.delta.new_file.path) }}
+                    </div>
+                    <div class="d-flex align-items-center ml-auto">
+                      {{ changedlabel("file removed", "danger")}}
+                      {{ lineschanged(False, True) }}
+                      {{ viewfilelinkbutton(patch.delta.new_file.path, disabled=True) }}
+                      {{ diffcollapsebtn() }}
+                    </div>
+                  {%-elif patch.delta.new_file.mode in [33188, 33261]
+                      and patch.delta.old_file.mode == 0 -%}
+                    {% set patchtype = "added"%}
+                      <div>
+                          {{ viewfilelink(patch.delta.new_file.path) }}
+                      </div>
+                      <div class="d-flex align-items-center ml-auto">
+                        {{ changedlabel("file changed", "success")}}
+                        {{ lineschanged(True, False) }}
+                        {{ viewfilelinkbutton(patch.delta.new_file.path) }}
+                        {% if linesadded != 0%}
+                          {{ diffcollapsebtn() }}
+                        {% endif %}
+                      </div>
+                  {%-elif patch.delta.new_file.mode in [33188, 33261]
+                      and patch.delta.old_file.mode in [33188, 33261] -%}
+                    {% set patchtype = "changed"%}
+                    <div>
+                        {{ viewfilelink(patch.delta.new_file.path) }}
+                    </div>
+                    <div class="d-flex align-items-center ml-auto">
+                      {{ changedlabel("file modified", "secondary")}}
+                      {{ lineschanged(True, True) }}
+                      {{ viewfilelinkbutton(patch.delta.new_file.path) }}
+                      {{ diffcollapsebtn() }}
+                    </div>
+                  {%-endif-%}
+
+                {%- else -%}
+                  {% set patchtype = "moved"%}
+                  <div>
+                      {{ viewfilelink(patch.delta.new_file.path) }}<strike>{{patch.delta.old_file.path}}</strike> 
+                  </div>
+                  <div class="d-flex align-items-center ml-auto">
+                    {{ changedlabel("file renamed", "info")}}
+                    {% if linesadded != 0 and linesremoved != 0%}
+                      {{ lineschanged(True, True) }}
+                    {% endif %}
+                    {{ viewfilelinkbutton(patch.delta.new_file.path) }}
+                    {% if linesadded != 0 and linesremoved != 0%}
+                      {{ diffcollapsebtn() }}
+                    {% endif %}
+                  </div>
+                {%- endif -%}
+              {%- endif -%}
+          </div>
+        </div>
+      {% if patchtype == "moved" and linesadded == 0 and linesremoved == 0%}
+        <div class="card-block">
+          <div class="text-muted text-center my-4 font-weight-bold">file was renamed with no change to the file</div>
+        </div>
+      {% elif patchtype == "added" and linesadded == 0 %}
+        <div class="card-block">
+          <div class="text-muted text-center">empty file added</div>
+        </div>
+      {% else %}
+        <div class="diff2html-output collapse show" data-diffno="{{loop.index}}" id="diff2html_{{loop.index}}"></div>
+      {% endif %}
+
+      </div>
+      </section>
+      {% endfor %}
+      {% endif %}
+
+
   </div>
 </div>
 
@@ -192,13 +481,48 @@
 
 {% block jscripts %}
     {{ super() }}
+    
+    <script type="text/javascript"
+    src="{{ url_for('static', filename='vendor/diff2html/diff2html.min.js') }}">
+</script>
+    <script type="text/javascript"
+    src="{{ url_for('static', filename='vendor/highlight.js/highlight.pack.js') }}">
+</script>
+    <script type="text/javascript"
+    src="{{ url_for('static', filename='vendor/diff2html/diff2html-ui.min.js') }}">
+</script>
+
     <script type="text/javascript">
+      $(document).ready(function() {
+        $(".diffcollapse").click(function(e){
+          $(this).find("i").toggleClass("fa-caret-down fa-caret-up")
+        });
+      });
       $(function(){
         $('#diff_list_link').click(function(){
           $('#diff_list').toggle();
         });
       });
       $.ajax({
+        url: '{{ url_for("ui_ns.view_commit_diff", repo=repo.name,username=username,namespace=repo.namespace,commitid=commitid,js=True ) }}' ,
+        type: 'GET',
+        dataType: 'json',
+        success: function(res) {
+          $(".diff2html-output").each(function(){
+          var diffString = res[$(this).attr("data-diffno")];
+          var diff2htmlUi = new Diff2HtmlUI({diff: diffString});
+          {% if splitview %}
+            diff2htmlUi.draw('#diff2html_'+$(this).attr("data-diffno"), {inputFormat: 'diff', outputFormat: 'side-by-side'});
+          {% else %}
+            diff2htmlUi.draw('#diff2html_'+$(this).attr("data-diffno"), {inputFormat: 'diff'});
+          {% endif %}
+          diff2htmlUi.highlightCode('#diff2html_'+$(this).attr("data-diffno"));
+          
+          });
+        }
+      });
+
+      $.ajax({
         url: '{{ url_for("internal_ns.get_branches_of_commit") }}' ,
         type: 'POST',
         data: {
diff --git a/pagure/templates/repo_master.html b/pagure/templates/repo_master.html
index c838965..f71b2cc 100644
--- a/pagure/templates/repo_master.html
+++ b/pagure/templates/repo_master.html
@@ -353,7 +353,7 @@
   </div>
 </div>
 
-<div class="container pt-5">
+<div class="container pt-5 repo-body-container">
     {% if repo.read_only %}
     <div class="container pt-2">
         <div class="alert alert-danger alert-dismissible" role="alert">
diff --git a/pagure/ui/repo.py b/pagure/ui/repo.py
index 19d22d9..0857179 100644
--- a/pagure/ui/repo.py
+++ b/pagure/ui/repo.py
@@ -794,6 +794,13 @@ def view_commit(repo, commitid, username=None, namespace=None):
 
     branchname = flask.request.args.get('branch', None)
 
+    splitview = flask.request.args.get('splitview', False)
+
+    if 'splitview' in flask.request.args:
+        splitview = True
+    else:
+        splitview = False
+
     if branchname and branchname not in repo_obj.listall_branches():
         branchname = None
 
@@ -814,6 +821,9 @@ def view_commit(repo, commitid, username=None, namespace=None):
         # First commit in the repo
         diff = commit.tree.diff_to_tree(swap=True)
 
+    if diff:
+        diff.find_similar()
+
     return flask.render_template(
         'commit.html',
         select='commits',
@@ -823,6 +833,7 @@ def view_commit(repo, commitid, username=None, namespace=None):
         commitid=commitid,
         commit=commit,
         diff=diff,
+        splitview=splitview,
         flags=pagure.lib.get_commit_flag(flask.g.session, repo, commitid),
     )
 
@@ -845,28 +856,76 @@ def view_commit_patch(repo, commitid, username=None, namespace=None):
 def view_commit_diff(repo, commitid, username=None, namespace=None):
     """ Render a commit in a repo as diff
     """
+
+    is_js = is_true(flask.request.args.get('js'))
+
     return view_commit_patch_or_diff(
-        repo, commitid, username, namespace, diff=True)
+        repo, commitid, username, namespace, diff=True, is_js=is_js)
 
 
 def view_commit_patch_or_diff(
-        repo, commitid, username=None, namespace=None, diff=False):
+        repo, commitid, username=None, namespace=None,
+        diff=False, is_js=False):
     """ Renders a commit either as a patch or as a diff. """
 
     repo_obj = flask.g.repo_obj
 
+    if is_js:
+        errorresponse = flask.jsonify({
+            'code': 'ERROR',
+            'message': 'Commit not found'})
+        errorresponse.status_code = 404
+
     try:
         commit = repo_obj.get(commitid)
     except ValueError:
-        flask.abort(404, 'Commit not found')
+        if is_js:
+            return errorresponse
+        else:
+            flask.abort(404, 'Commit not found')
 
     if commit is None:
-        flask.abort(404, 'Commit not found')
+        if is_js:
+            return errorresponse
+        else:
+            flask.abort(404, 'Commit not found')
+
+    if is_js:
+        if commit.parents:
+            diff_obj = repo_obj.diff(commit.parents[0], commit)
+        else:
+            diff_obj = commit.tree.diff_to_tree(swap=True)
+
+        # Patch.patch was introduced in pygit 0.26.2 so
+        # check that the Patch Object has this
+        if hasattr(diff_obj[0], "patch"):
+            if diff_obj:
+                diff_obj.find_similar()
+            diffs = {}
+            count = 0
+            for patch in diff_obj:
+                count = count + 1
+                diffs[str(count)] = patch.patch
+        else:
+            # since we can't get a individual patch item for each
+            # file, we get the whole diff, and manually split the
+            # string.
+            patch = pagure.lib.git.commit_to_patch(
+                repo_obj, commit, diff_view=diff, find_similar=True)
 
-    patch = pagure.lib.git.commit_to_patch(
-        repo_obj, commit, diff_view=diff)
+            patches = filter(None, patch.split("diff --git a/"))
 
-    return flask.Response(patch, content_type="text/plain;charset=UTF-8")
+            diffs = {}
+            count = 0
+            for p in patches:
+                count = count + 1
+                diffs[str(count)] = "diff --git a/" + p
+
+        return flask.jsonify(diffs)
+    else:
+        patch = pagure.lib.git.commit_to_patch(
+            repo_obj, commit, diff_view=diff)
+        return flask.Response(patch, content_type="text/plain;charset=UTF-8")
 
 
 @UI_NS.route('/<repo>/tree/')
diff --git a/tests/test_pagure_flask_ui_old_commit.py b/tests/test_pagure_flask_ui_old_commit.py
index c20ef87..0bbbf33 100644
--- a/tests/test_pagure_flask_ui_old_commit.py
+++ b/tests/test_pagure_flask_ui_old_commit.py
@@ -70,21 +70,11 @@ class PagureFlaskRepoOldUrltests(tests.SimplePagureTest):
             '/test/%s' % commit.oid.hex, follow_redirects=True)
         self.assertEqual(output.status_code, 200)
         self.assertTrue(
-            '<div class="list-group" id="diff_list" style="display:none;">'
+            'href="#commit-overview-collapse"'
             in output.get_data(as_text=True))
-        self.assertTrue('  Merged by Alice Author\n' in output.get_data(as_text=True))
-        self.assertTrue('  Committed by Cecil Committer\n' in output.get_data(as_text=True))
+        self.assertTrue('Merged by Alice Author' in output.get_data(as_text=True))
+        self.assertTrue('Committed by Cecil Committer' in output.get_data(as_text=True))
 
-        self.assertTrue(
-            '<span style="background-color: #f0f0f0; padding: 0 5px 0 5px">' +
-            ' 2 </span><span style="color: #00A000; background-color: ' +
-            '#ddffdd">+ Pagure</span>' in output.get_data(as_text=True))
-        self.assertTrue(
-            '<span style="background-color: #f0f0f0; padding: 0 5px 0 5px">' +
-            ' 3 </span><span style="color: #00A000; background-color: ' +
-            '#ddffdd">+ ======</span>' in output.get_data(as_text=True))
-        self.assertTrue(
-            '<span class="label label-success">+16</span>' in output.get_data(as_text=True))
         self.assertTrue('title="View file as of %s"' % commit.oid.hex[0:6]
                         in output.get_data(as_text=True))
 
@@ -93,19 +83,11 @@ class PagureFlaskRepoOldUrltests(tests.SimplePagureTest):
             '/test/%s' % commit.oid.hex, follow_redirects=True)
         self.assertEqual(output.status_code, 200)
         self.assertTrue(
-            '<div class="list-group" id="diff_list" style="display:none;">'
+            'href="#commit-overview-collapse"'
             in output.get_data(as_text=True))
-        self.assertTrue('  Merged by Alice Author\n' in output.get_data(as_text=True))
-        self.assertTrue('  Committed by Cecil Committer\n' in output.get_data(as_text=True))
+        self.assertTrue('Merged by Alice Author' in output.get_data(as_text=True))
+        self.assertTrue('Committed by Cecil Committer' in output.get_data(as_text=True))
 
-        self.assertTrue(
-            '<span style="background-color: #f0f0f0; padding: 0 5px 0 5px"> 2' +
-            ' </span><span style="color: #00A000; background-color: #ddffdd">' +
-            '+ Pagure</span>' in output.get_data(as_text=True))
-        self.assertTrue(
-            '<span style="background-color: #f0f0f0; padding: 0 5px 0 5px">' +
-            ' 3 </span><span style="color: #00A000; background-color: ' +
-            '#ddffdd">+ ======</span>' in output.get_data(as_text=True))
 
         # Add some content to the git repo
         tests.add_content_git_repo(os.path.join(self.path, 'repos',
@@ -119,23 +101,10 @@ class PagureFlaskRepoOldUrltests(tests.SimplePagureTest):
             '/test/%s' % commit.oid.hex, follow_redirects=True)
         self.assertEqual(output.status_code, 200)
         self.assertTrue(
-            '<div class="list-group" id="diff_list" style="display:none;">'
+            'href="#commit-overview-collapse"'
             in output.get_data(as_text=True))
-        self.assertTrue('  Authored by Alice Author\n' in output.get_data(as_text=True))
-        self.assertTrue('  Committed by Cecil Committer\n' in output.get_data(as_text=True))
-        self.assertTrue(
-            # new version of pygments
-            '<div class="highlight" style="background: #f8f8f8"><pre style' +
-            '="line-height: 125%"><span></span><span style="background-color' +
-            ': #f0f0f0; padding: 0 5px 0 5px">1 </span><span style="color: ' +
-            '#800080; font-weight: bold">@@ -0,0 +1,3 @@</span>' in
-            output.get_data(as_text=True)
-            or
-            # old version of pygments
-            '<div class="highlight" style="background: #f8f8f8">' +
-            '<pre style="line-height: 125%">' +
-            '<span style="color: #800080; font-weight: bold">' +
-            '@@ -0,0 +1,3 @@</span>' in output.get_data(as_text=True))
+        self.assertTrue('Authored by Alice Author' in output.get_data(as_text=True))
+        self.assertTrue('Committed by Cecil Committer' in output.get_data(as_text=True))
 
         # Add a fork of a fork
         item = pagure.lib.model.Project(
@@ -167,20 +136,11 @@ class PagureFlaskRepoOldUrltests(tests.SimplePagureTest):
             '/fork/pingou/test3/%s' % commit.oid.hex, follow_redirects=True)
         self.assertEqual(output.status_code, 200)
         self.assertTrue(
-            '<div class="list-group" id="diff_list" style="display:none;">'
+            'href="#commit-overview-collapse"'
             in output.get_data(as_text=True))
         self.assertTrue('  Authored by Alice Author\n' in output.get_data(as_text=True))
         self.assertTrue('  Committed by Cecil Committer\n' in output.get_data(as_text=True))
-        self.assertTrue(
-            '<span style="background-color: #f0f0f0; padding: 0 5px 0 5px"> 2' +
-            ' </span><span style="color: #00A000; background-color: #ddffdd">' +
-            '+ Pagure</span>' in output.get_data(as_text=True))
-        self.assertTrue(
-            '<span style="background-color: #f0f0f0; padding: 0 5px 0 5px"> 3' +
-            ' </span><span style="color: #00A000; background-color: #ddffdd">' +
-            '+ ======</span>' in output.get_data(as_text=True))
-        self.assertTrue(
-            '<span class="label label-success">+16</span>' in output.get_data(as_text=True))
+
         self.assertTrue('title="View file as of %s"' % commit.oid.hex[0:6]
                         in output.get_data(as_text=True))
 
@@ -189,18 +149,10 @@ class PagureFlaskRepoOldUrltests(tests.SimplePagureTest):
             '/fork/pingou/test3/%s' % commit.oid.hex, follow_redirects=True)
         self.assertEqual(output.status_code, 200)
         self.assertTrue(
-            '<div class="list-group" id="diff_list" style="display:none;">'
+            'href="#commit-overview-collapse"'
             in output.get_data(as_text=True))
-        self.assertTrue('  Authored by Alice Author\n' in output.get_data(as_text=True))
-        self.assertTrue('  Committed by Cecil Committer\n' in output.get_data(as_text=True))
-        self.assertTrue(
-            '<span style="background-color: #f0f0f0; padding: 0 5px 0 5px"> 2' +
-            ' </span><span style="color: #00A000; background-color: #ddffdd">' +
-            '+ Pagure</span>' in output.get_data(as_text=True))
-        self.assertTrue(
-            '<span style="background-color: #f0f0f0; padding: 0 5px 0 5px"> 3' +
-            ' </span><span style="color: #00A000; background-color: #ddffdd">' +
-            '+ ======</span>' in output.get_data(as_text=True))
+        self.assertTrue('Authored by Alice Author' in output.get_data(as_text=True))
+        self.assertTrue('Committed by Cecil Committer' in output.get_data(as_text=True))
 
         # Try the old URL scheme with a short hash
         output = self.app.get(
diff --git a/tests/test_pagure_flask_ui_repo.py b/tests/test_pagure_flask_ui_repo.py
index 73b1259..1339f3c 100644
--- a/tests/test_pagure_flask_ui_repo.py
+++ b/tests/test_pagure_flask_ui_repo.py
@@ -2741,10 +2741,10 @@ class PagureFlaskRepotests(tests.Modeltests):
         self.assertEqual(output.status_code, 200)
         output_text = output.get_data(as_text=True)
         self.assertIn(
-            '<div class="list-group" id="diff_list" style="display:none;">',
+            '#commit-overview-collapse',
             output_text)
-        self.assertIn('  Merged by Alice Author\n', output_text)
-        self.assertIn('  Committed by Cecil Committer\n', output_text)
+        self.assertIn('Merged by Alice Author', output_text)
+        self.assertIn('Committed by Cecil Committer', output_text)
 
         # View first commit - with the old URL scheme disabled - default
         output = self.app.get(
@@ -2765,12 +2765,10 @@ class PagureFlaskRepotests(tests.Modeltests):
         self.assertEqual(output.status_code, 200)
         output_text = output.get_data(as_text=True)
         self.assertIn(
-            '<div class="list-group" id="diff_list" style="display:none;">',
+            '#commit-overview-collapse',
             output_text)
-        self.assertIn('  Authored by Alice Author\n', output_text)
-        self.assertIn('  Committed by Cecil Committer\n', output_text)
-        self.assertIn(
-            '<span style="background-color: #f0f0f0', output_text)
+        self.assertIn('Authored by Alice Author', output_text)
+        self.assertIn('Committed by Cecil Committer', output_text)
 
         #View the commit when branch name is provided
         output = self.app.get('/test/c/%s?branch=master' % commit.oid.hex)
@@ -2822,18 +2820,11 @@ class PagureFlaskRepotests(tests.Modeltests):
         self.assertEqual(output.status_code, 200)
         output_text = output.get_data(as_text=True)
         self.assertIn(
-            '<div class="list-group" id="diff_list" style="display:none;">',
+            '#commit-overview-collapse',
             output_text)
-        self.assertIn('  Authored by Alice Author\n', output_text)
-        self.assertIn('  Committed by Cecil Committer\n', output_text)
-        self.assertIn(
-            '<span style="background-color: #f0f0f0; padding: 0 5px 0 5px"> 2' +
-            ' </span><span style="color: #00A000; background-color: #ddffdd">' +
-            '+ Pagure</span>', output_text)
-        self.assertIn(
-            '<span style="background-color: #f0f0f0; padding: 0 5px 0 5px"> 3' +
-            ' </span><span style="color: #00A000; background-color: #ddffdd">' +
-            '+ ======</span>', output_text)
+        self.assertIn('Authored by Alice Author', output_text)
+        self.assertIn('Committed by Cecil Committer', output_text)
+
 
         # Try the old URL scheme with a short hash
         output = self.app.get(
diff --git a/tests/test_pagure_flask_ui_repo_flag_commit.py b/tests/test_pagure_flask_ui_repo_flag_commit.py
index e804c43..4e6d552 100644
--- a/tests/test_pagure_flask_ui_repo_flag_commit.py
+++ b/tests/test_pagure_flask_ui_repo_flag_commit.py
@@ -50,16 +50,10 @@ class ViewCommitFlagtests(tests.SimplePagureTest):
             '<title>Commit - test - %s - Pagure</title>' % self.commit.oid.hex,
             output.get_data(as_text=True))
         self.assertIn(
-            '<div class="list-group" id="diff_list" style="display:none;">',
+            '#commit-overview-collapse',
             output.get_data(as_text=True))
-        self.assertIn('  Merged by Alice Author\n', output.get_data(as_text=True))
-        self.assertIn('  Committed by Cecil Committer\n', output.get_data(as_text=True))
-        self.assertIn('''<section class="list-group" id="flag_list">
-      <div class="card" id="pr_flags">
-          <ul class="list-group list-group-flush">
-          </ul>
-        </div>
-    </section>''', output.get_data(as_text=True))
+        self.assertIn('Merged by Alice Author', output.get_data(as_text=True))
+        self.assertIn('Committed by Cecil Committer', output.get_data(as_text=True))
 
     def test_view_commit_pending_flag(self):
         """ Test the view_commit endpoint with a pending flag. """
@@ -89,10 +83,10 @@ class ViewCommitFlagtests(tests.SimplePagureTest):
             '<title>Commit - test - %s - Pagure</title>' % self.commit.oid.hex,
             output_text)
         self.assertIn(
-            '<div class="list-group" id="diff_list" style="display:none;">',
+            '#commit-overview-collapse',
             output_text)
-        self.assertIn('  Merged by Alice Author\n', output_text)
-        self.assertIn('  Committed by Cecil Committer\n', output_text)
+        self.assertIn('Merged by Alice Author', output_text)
+        self.assertIn('Committed by Cecil Committer', output_text)
         self.assertIn(
             '<span>\n                    <a '
             'href="https://koji.fp.o/koji...">simple-koji-ci</a>'
@@ -132,10 +126,10 @@ class ViewCommitFlagtests(tests.SimplePagureTest):
             '<title>Commit - test - %s - Pagure</title>' % self.commit.oid.hex,
             output_text)
         self.assertIn(
-            '<div class="list-group" id="diff_list" style="display:none;">',
+            '#commit-overview-collapse',
             output_text)
-        self.assertIn('  Merged by Alice Author\n', output_text)
-        self.assertIn('  Committed by Cecil Committer\n', output_text)
+        self.assertIn('Merged by Alice Author', output_text)
+        self.assertIn('Committed by Cecil Committer', output_text)
         self.assertIn(
             '<span>\n                    <a '
             'href="https://koji.fp.o/koji...">simple-koji-ci</a>'
@@ -175,10 +169,10 @@ class ViewCommitFlagtests(tests.SimplePagureTest):
             '<title>Commit - test - %s - Pagure</title>' % self.commit.oid.hex,
             output_text)
         self.assertIn(
-            '<div class="list-group" id="diff_list" style="display:none;">',
+            '#commit-overview-collapse',
             output_text)
-        self.assertIn('  Merged by Alice Author\n', output_text)
-        self.assertIn('  Committed by Cecil Committer\n', output_text)
+        self.assertIn('Merged by Alice Author', output_text)
+        self.assertIn('Committed by Cecil Committer', output_text)
         self.assertIn(
             '<span>\n                    <a '
             'href="https://koji.fp.o/koji...">simple-koji-ci</a>'
@@ -218,10 +212,10 @@ class ViewCommitFlagtests(tests.SimplePagureTest):
             '<title>Commit - test - %s - Pagure</title>' % self.commit.oid.hex,
             output_text)
         self.assertIn(
-            '<div class="list-group" id="diff_list" style="display:none;">',
+            '#commit-overview-collapse',
             output_text)
-        self.assertIn('  Merged by Alice Author\n', output_text)
-        self.assertIn('  Committed by Cecil Committer\n', output_text)
+        self.assertIn('Merged by Alice Author', output_text)
+        self.assertIn('Committed by Cecil Committer', output_text)
         self.assertIn(
             '<span>\n                    <a href="https://koji.fp.o/koji...">'
             'simple-koji-ci</a>\n                  </span>', output_text)
@@ -260,10 +254,10 @@ class ViewCommitFlagtests(tests.SimplePagureTest):
             '<title>Commit - test - %s - Pagure</title>' % self.commit.oid.hex,
             output_text)
         self.assertIn(
-            '<div class="list-group" id="diff_list" style="display:none;">',
+            '#commit-overview-collapse',
             output_text)
-        self.assertIn('  Merged by Alice Author\n', output_text)
-        self.assertIn('  Committed by Cecil Committer\n', output_text)
+        self.assertIn('Merged by Alice Author', output_text)
+        self.assertIn('Committed by Cecil Committer', output_text)
         self.assertIn(
             '<span>\n                    <a href="https://koji.fp.o/koji...">'
             'simple-koji-ci</a>\n                  </span>', output_text)
@@ -310,10 +304,10 @@ class ViewCommitFlagtests(tests.SimplePagureTest):
             '<title>Commit - test - %s - Pagure</title>' % self.commit.oid.hex,
             output_text)
         self.assertIn(
-            '<div class="list-group" id="diff_list" style="display:none;">',
+            '#commit-overview-collapse',
             output_text)
-        self.assertIn('  Merged by Alice Author\n', output_text)
-        self.assertIn('  Committed by Cecil Committer\n', output_text)
+        self.assertIn('Merged by Alice Author', output_text)
+        self.assertIn('Committed by Cecil Committer', output_text)
         self.assertIn(
             '<span>\n                    <a href="https://koji.fp.o/koji...">'
             'simple-koji-ci</a>\n                  </span>', output_text)