bgm-wiki-rev-diff

show diff between bgm.tv wiki versions

目前為 2020-04-25 提交的版本,檢視 最新版本

  1. // ==UserScript==
  2. // @name bgm-wiki-rev-diff
  3. // @namespace https://trim21.me/
  4. // @version 0.0.5
  5. // @author Trim21 <i@trim21.me>
  6. // @source https://github.com/Trim21/bgm-wiki-rev-diff
  7. // @license MIT
  8. // @match https://bgm.tv/subject/*/edit
  9. // @match https://bangumi.tv/subject/*/edit
  10. // @require https://cdn.jsdelivr.net/npm/jquery@3.5.0/dist/jquery.min.js
  11. // @grant GM_xmlhttpRequest
  12. // @connect bgm.tv
  13. // @run-at document-end
  14. // @description show diff between bgm.tv wiki versions
  15. // ==/UserScript==
  16.  
  17. /******/ (function(modules) { // webpackBootstrap
  18. /******/ // The module cache
  19. /******/ var installedModules = {};
  20. /******/
  21. /******/ // The require function
  22. /******/ function __webpack_require__(moduleId) {
  23. /******/
  24. /******/ // Check if module is in cache
  25. /******/ if(installedModules[moduleId]) {
  26. /******/ return installedModules[moduleId].exports;
  27. /******/ }
  28. /******/ // Create a new module (and put it into the cache)
  29. /******/ var module = installedModules[moduleId] = {
  30. /******/ i: moduleId,
  31. /******/ l: false,
  32. /******/ exports: {}
  33. /******/ };
  34. /******/
  35. /******/ // Execute the module function
  36. /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
  37. /******/
  38. /******/ // Flag the module as loaded
  39. /******/ module.l = true;
  40. /******/
  41. /******/ // Return the exports of the module
  42. /******/ return module.exports;
  43. /******/ }
  44. /******/
  45. /******/
  46. /******/ // expose the modules object (__webpack_modules__)
  47. /******/ __webpack_require__.m = modules;
  48. /******/
  49. /******/ // expose the module cache
  50. /******/ __webpack_require__.c = installedModules;
  51. /******/
  52. /******/ // define getter function for harmony exports
  53. /******/ __webpack_require__.d = function(exports, name, getter) {
  54. /******/ if(!__webpack_require__.o(exports, name)) {
  55. /******/ Object.defineProperty(exports, name, { enumerable: true, get: getter });
  56. /******/ }
  57. /******/ };
  58. /******/
  59. /******/ // define __esModule on exports
  60. /******/ __webpack_require__.r = function(exports) {
  61. /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
  62. /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
  63. /******/ }
  64. /******/ Object.defineProperty(exports, '__esModule', { value: true });
  65. /******/ };
  66. /******/
  67. /******/ // create a fake namespace object
  68. /******/ // mode & 1: value is a module id, require it
  69. /******/ // mode & 2: merge all properties of value into the ns
  70. /******/ // mode & 4: return value when already ns object
  71. /******/ // mode & 8|1: behave like require
  72. /******/ __webpack_require__.t = function(value, mode) {
  73. /******/ if(mode & 1) value = __webpack_require__(value);
  74. /******/ if(mode & 8) return value;
  75. /******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
  76. /******/ var ns = Object.create(null);
  77. /******/ __webpack_require__.r(ns);
  78. /******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value });
  79. /******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
  80. /******/ return ns;
  81. /******/ };
  82. /******/
  83. /******/ // getDefaultExport function for compatibility with non-harmony modules
  84. /******/ __webpack_require__.n = function(module) {
  85. /******/ var getter = module && module.__esModule ?
  86. /******/ function getDefault() { return module['default']; } :
  87. /******/ function getModuleExports() { return module; };
  88. /******/ __webpack_require__.d(getter, 'a', getter);
  89. /******/ return getter;
  90. /******/ };
  91. /******/
  92. /******/ // Object.prototype.hasOwnProperty.call
  93. /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
  94. /******/
  95. /******/ // __webpack_public_path__
  96. /******/ __webpack_require__.p = "";
  97. /******/
  98. /******/
  99. /******/ // Load entry module and return exports
  100. /******/ return __webpack_require__(__webpack_require__.s = "e6Wu");
  101. /******/ })
  102. /************************************************************************/
  103. /******/ ({
  104.  
  105. /***/ "PKsF":
  106. /***/ (function(module, exports, __webpack_require__) {
  107.  
  108. /*
  109. * Copyright 2011 Twitter, Inc.
  110. * Licensed under the Apache License, Version 2.0 (the "License");
  111. * you may not use this file except in compliance with the License.
  112. * You may obtain a copy of the License at
  113. *
  114. * http://www.apache.org/licenses/LICENSE-2.0
  115. *
  116. * Unless required by applicable law or agreed to in writing, software
  117. * distributed under the License is distributed on an "AS IS" BASIS,
  118. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  119. * See the License for the specific language governing permissions and
  120. * limitations under the License.
  121. */
  122.  
  123. (function (Hogan) {
  124. // Setup regex assignments
  125. // remove whitespace according to Mustache spec
  126. var rIsWhitespace = /\S/,
  127. rQuot = /\"/g,
  128. rNewline = /\n/g,
  129. rCr = /\r/g,
  130. rSlash = /\\/g,
  131. rLineSep = /\u2028/,
  132. rParagraphSep = /\u2029/;
  133.  
  134. Hogan.tags = {
  135. '#': 1, '^': 2, '<': 3, '$': 4,
  136. '/': 5, '!': 6, '>': 7, '=': 8, '_v': 9,
  137. '{': 10, '&': 11, '_t': 12
  138. };
  139.  
  140. Hogan.scan = function scan(text, delimiters) {
  141. var len = text.length,
  142. IN_TEXT = 0,
  143. IN_TAG_TYPE = 1,
  144. IN_TAG = 2,
  145. state = IN_TEXT,
  146. tagType = null,
  147. tag = null,
  148. buf = '',
  149. tokens = [],
  150. seenTag = false,
  151. i = 0,
  152. lineStart = 0,
  153. otag = '{{',
  154. ctag = '}}';
  155.  
  156. function addBuf() {
  157. if (buf.length > 0) {
  158. tokens.push({tag: '_t', text: new String(buf)});
  159. buf = '';
  160. }
  161. }
  162.  
  163. function lineIsWhitespace() {
  164. var isAllWhitespace = true;
  165. for (var j = lineStart; j < tokens.length; j++) {
  166. isAllWhitespace =
  167. (Hogan.tags[tokens[j].tag] < Hogan.tags['_v']) ||
  168. (tokens[j].tag == '_t' && tokens[j].text.match(rIsWhitespace) === null);
  169. if (!isAllWhitespace) {
  170. return false;
  171. }
  172. }
  173.  
  174. return isAllWhitespace;
  175. }
  176.  
  177. function filterLine(haveSeenTag, noNewLine) {
  178. addBuf();
  179.  
  180. if (haveSeenTag && lineIsWhitespace()) {
  181. for (var j = lineStart, next; j < tokens.length; j++) {
  182. if (tokens[j].text) {
  183. if ((next = tokens[j+1]) && next.tag == '>') {
  184. // set indent to token value
  185. next.indent = tokens[j].text.toString()
  186. }
  187. tokens.splice(j, 1);
  188. }
  189. }
  190. } else if (!noNewLine) {
  191. tokens.push({tag:'\n'});
  192. }
  193.  
  194. seenTag = false;
  195. lineStart = tokens.length;
  196. }
  197.  
  198. function changeDelimiters(text, index) {
  199. var close = '=' + ctag,
  200. closeIndex = text.indexOf(close, index),
  201. delimiters = trim(
  202. text.substring(text.indexOf('=', index) + 1, closeIndex)
  203. ).split(' ');
  204.  
  205. otag = delimiters[0];
  206. ctag = delimiters[delimiters.length - 1];
  207.  
  208. return closeIndex + close.length - 1;
  209. }
  210.  
  211. if (delimiters) {
  212. delimiters = delimiters.split(' ');
  213. otag = delimiters[0];
  214. ctag = delimiters[1];
  215. }
  216.  
  217. for (i = 0; i < len; i++) {
  218. if (state == IN_TEXT) {
  219. if (tagChange(otag, text, i)) {
  220. --i;
  221. addBuf();
  222. state = IN_TAG_TYPE;
  223. } else {
  224. if (text.charAt(i) == '\n') {
  225. filterLine(seenTag);
  226. } else {
  227. buf += text.charAt(i);
  228. }
  229. }
  230. } else if (state == IN_TAG_TYPE) {
  231. i += otag.length - 1;
  232. tag = Hogan.tags[text.charAt(i + 1)];
  233. tagType = tag ? text.charAt(i + 1) : '_v';
  234. if (tagType == '=') {
  235. i = changeDelimiters(text, i);
  236. state = IN_TEXT;
  237. } else {
  238. if (tag) {
  239. i++;
  240. }
  241. state = IN_TAG;
  242. }
  243. seenTag = i;
  244. } else {
  245. if (tagChange(ctag, text, i)) {
  246. tokens.push({tag: tagType, n: trim(buf), otag: otag, ctag: ctag,
  247. i: (tagType == '/') ? seenTag - otag.length : i + ctag.length});
  248. buf = '';
  249. i += ctag.length - 1;
  250. state = IN_TEXT;
  251. if (tagType == '{') {
  252. if (ctag == '}}') {
  253. i++;
  254. } else {
  255. cleanTripleStache(tokens[tokens.length - 1]);
  256. }
  257. }
  258. } else {
  259. buf += text.charAt(i);
  260. }
  261. }
  262. }
  263.  
  264. filterLine(seenTag, true);
  265.  
  266. return tokens;
  267. }
  268.  
  269. function cleanTripleStache(token) {
  270. if (token.n.substr(token.n.length - 1) === '}') {
  271. token.n = token.n.substring(0, token.n.length - 1);
  272. }
  273. }
  274.  
  275. function trim(s) {
  276. if (s.trim) {
  277. return s.trim();
  278. }
  279.  
  280. return s.replace(/^\s*|\s*$/g, '');
  281. }
  282.  
  283. function tagChange(tag, text, index) {
  284. if (text.charAt(index) != tag.charAt(0)) {
  285. return false;
  286. }
  287.  
  288. for (var i = 1, l = tag.length; i < l; i++) {
  289. if (text.charAt(index + i) != tag.charAt(i)) {
  290. return false;
  291. }
  292. }
  293.  
  294. return true;
  295. }
  296.  
  297. // the tags allowed inside super templates
  298. var allowedInSuper = {'_t': true, '\n': true, '$': true, '/': true};
  299.  
  300. function buildTree(tokens, kind, stack, customTags) {
  301. var instructions = [],
  302. opener = null,
  303. tail = null,
  304. token = null;
  305.  
  306. tail = stack[stack.length - 1];
  307.  
  308. while (tokens.length > 0) {
  309. token = tokens.shift();
  310.  
  311. if (tail && tail.tag == '<' && !(token.tag in allowedInSuper)) {
  312. throw new Error('Illegal content in < super tag.');
  313. }
  314.  
  315. if (Hogan.tags[token.tag] <= Hogan.tags['$'] || isOpener(token, customTags)) {
  316. stack.push(token);
  317. token.nodes = buildTree(tokens, token.tag, stack, customTags);
  318. } else if (token.tag == '/') {
  319. if (stack.length === 0) {
  320. throw new Error('Closing tag without opener: /' + token.n);
  321. }
  322. opener = stack.pop();
  323. if (token.n != opener.n && !isCloser(token.n, opener.n, customTags)) {
  324. throw new Error('Nesting error: ' + opener.n + ' vs. ' + token.n);
  325. }
  326. opener.end = token.i;
  327. return instructions;
  328. } else if (token.tag == '\n') {
  329. token.last = (tokens.length == 0) || (tokens[0].tag == '\n');
  330. }
  331.  
  332. instructions.push(token);
  333. }
  334.  
  335. if (stack.length > 0) {
  336. throw new Error('missing closing tag: ' + stack.pop().n);
  337. }
  338.  
  339. return instructions;
  340. }
  341.  
  342. function isOpener(token, tags) {
  343. for (var i = 0, l = tags.length; i < l; i++) {
  344. if (tags[i].o == token.n) {
  345. token.tag = '#';
  346. return true;
  347. }
  348. }
  349. }
  350.  
  351. function isCloser(close, open, tags) {
  352. for (var i = 0, l = tags.length; i < l; i++) {
  353. if (tags[i].c == close && tags[i].o == open) {
  354. return true;
  355. }
  356. }
  357. }
  358.  
  359. function stringifySubstitutions(obj) {
  360. var items = [];
  361. for (var key in obj) {
  362. items.push('"' + esc(key) + '": function(c,p,t,i) {' + obj[key] + '}');
  363. }
  364. return "{ " + items.join(",") + " }";
  365. }
  366.  
  367. function stringifyPartials(codeObj) {
  368. var partials = [];
  369. for (var key in codeObj.partials) {
  370. partials.push('"' + esc(key) + '":{name:"' + esc(codeObj.partials[key].name) + '", ' + stringifyPartials(codeObj.partials[key]) + "}");
  371. }
  372. return "partials: {" + partials.join(",") + "}, subs: " + stringifySubstitutions(codeObj.subs);
  373. }
  374.  
  375. Hogan.stringify = function(codeObj, text, options) {
  376. return "{code: function (c,p,i) { " + Hogan.wrapMain(codeObj.code) + " }," + stringifyPartials(codeObj) + "}";
  377. }
  378.  
  379. var serialNo = 0;
  380. Hogan.generate = function(tree, text, options) {
  381. serialNo = 0;
  382. var context = { code: '', subs: {}, partials: {} };
  383. Hogan.walk(tree, context);
  384.  
  385. if (options.asString) {
  386. return this.stringify(context, text, options);
  387. }
  388.  
  389. return this.makeTemplate(context, text, options);
  390. }
  391.  
  392. Hogan.wrapMain = function(code) {
  393. return 'var t=this;t.b(i=i||"");' + code + 'return t.fl();';
  394. }
  395.  
  396. Hogan.template = Hogan.Template;
  397.  
  398. Hogan.makeTemplate = function(codeObj, text, options) {
  399. var template = this.makePartials(codeObj);
  400. template.code = new Function('c', 'p', 'i', this.wrapMain(codeObj.code));
  401. return new this.template(template, text, this, options);
  402. }
  403.  
  404. Hogan.makePartials = function(codeObj) {
  405. var key, template = {subs: {}, partials: codeObj.partials, name: codeObj.name};
  406. for (key in template.partials) {
  407. template.partials[key] = this.makePartials(template.partials[key]);
  408. }
  409. for (key in codeObj.subs) {
  410. template.subs[key] = new Function('c', 'p', 't', 'i', codeObj.subs[key]);
  411. }
  412. return template;
  413. }
  414.  
  415. function esc(s) {
  416. return s.replace(rSlash, '\\\\')
  417. .replace(rQuot, '\\\"')
  418. .replace(rNewline, '\\n')
  419. .replace(rCr, '\\r')
  420. .replace(rLineSep, '\\u2028')
  421. .replace(rParagraphSep, '\\u2029');
  422. }
  423.  
  424. function chooseMethod(s) {
  425. return (~s.indexOf('.')) ? 'd' : 'f';
  426. }
  427.  
  428. function createPartial(node, context) {
  429. var prefix = "<" + (context.prefix || "");
  430. var sym = prefix + node.n + serialNo++;
  431. context.partials[sym] = {name: node.n, partials: {}};
  432. context.code += 't.b(t.rp("' + esc(sym) + '",c,p,"' + (node.indent || '') + '"));';
  433. return sym;
  434. }
  435.  
  436. Hogan.codegen = {
  437. '#': function(node, context) {
  438. context.code += 'if(t.s(t.' + chooseMethod(node.n) + '("' + esc(node.n) + '",c,p,1),' +
  439. 'c,p,0,' + node.i + ',' + node.end + ',"' + node.otag + " " + node.ctag + '")){' +
  440. 't.rs(c,p,' + 'function(c,p,t){';
  441. Hogan.walk(node.nodes, context);
  442. context.code += '});c.pop();}';
  443. },
  444.  
  445. '^': function(node, context) {
  446. context.code += 'if(!t.s(t.' + chooseMethod(node.n) + '("' + esc(node.n) + '",c,p,1),c,p,1,0,0,"")){';
  447. Hogan.walk(node.nodes, context);
  448. context.code += '};';
  449. },
  450.  
  451. '>': createPartial,
  452. '<': function(node, context) {
  453. var ctx = {partials: {}, code: '', subs: {}, inPartial: true};
  454. Hogan.walk(node.nodes, ctx);
  455. var template = context.partials[createPartial(node, context)];
  456. template.subs = ctx.subs;
  457. template.partials = ctx.partials;
  458. },
  459.  
  460. '$': function(node, context) {
  461. var ctx = {subs: {}, code: '', partials: context.partials, prefix: node.n};
  462. Hogan.walk(node.nodes, ctx);
  463. context.subs[node.n] = ctx.code;
  464. if (!context.inPartial) {
  465. context.code += 't.sub("' + esc(node.n) + '",c,p,i);';
  466. }
  467. },
  468.  
  469. '\n': function(node, context) {
  470. context.code += write('"\\n"' + (node.last ? '' : ' + i'));
  471. },
  472.  
  473. '_v': function(node, context) {
  474. context.code += 't.b(t.v(t.' + chooseMethod(node.n) + '("' + esc(node.n) + '",c,p,0)));';
  475. },
  476.  
  477. '_t': function(node, context) {
  478. context.code += write('"' + esc(node.text) + '"');
  479. },
  480.  
  481. '{': tripleStache,
  482.  
  483. '&': tripleStache
  484. }
  485.  
  486. function tripleStache(node, context) {
  487. context.code += 't.b(t.t(t.' + chooseMethod(node.n) + '("' + esc(node.n) + '",c,p,0)));';
  488. }
  489.  
  490. function write(s) {
  491. return 't.b(' + s + ');';
  492. }
  493.  
  494. Hogan.walk = function(nodelist, context) {
  495. var func;
  496. for (var i = 0, l = nodelist.length; i < l; i++) {
  497. func = Hogan.codegen[nodelist[i].tag];
  498. func && func(nodelist[i], context);
  499. }
  500. return context;
  501. }
  502.  
  503. Hogan.parse = function(tokens, text, options) {
  504. options = options || {};
  505. return buildTree(tokens, '', [], options.sectionTags || []);
  506. }
  507.  
  508. Hogan.cache = {};
  509.  
  510. Hogan.cacheKey = function(text, options) {
  511. return [text, !!options.asString, !!options.disableLambda, options.delimiters, !!options.modelGet].join('||');
  512. }
  513.  
  514. Hogan.compile = function(text, options) {
  515. options = options || {};
  516. var key = Hogan.cacheKey(text, options);
  517. var template = this.cache[key];
  518.  
  519. if (template) {
  520. var partials = template.partials;
  521. for (var name in partials) {
  522. delete partials[name].instance;
  523. }
  524. return template;
  525. }
  526.  
  527. template = this.generate(this.parse(this.scan(text, options.delimiters), text, options), text, options);
  528. return this.cache[key] = template;
  529. }
  530. })( true ? exports : undefined);
  531.  
  532.  
  533. /***/ }),
  534.  
  535. /***/ "Ruv9":
  536. /***/ (function(module, exports, __webpack_require__) {
  537.  
  538. /*
  539. * Copyright 2011 Twitter, Inc.
  540. * Licensed under the Apache License, Version 2.0 (the "License");
  541. * you may not use this file except in compliance with the License.
  542. * You may obtain a copy of the License at
  543. *
  544. * http://www.apache.org/licenses/LICENSE-2.0
  545. *
  546. * Unless required by applicable law or agreed to in writing, software
  547. * distributed under the License is distributed on an "AS IS" BASIS,
  548. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  549. * See the License for the specific language governing permissions and
  550. * limitations under the License.
  551. */
  552.  
  553. // This file is for use with Node.js. See dist/ for browser files.
  554.  
  555. var Hogan = __webpack_require__("PKsF");
  556. Hogan.Template = __webpack_require__("cK6b").Template;
  557. Hogan.template = Hogan.Template;
  558. module.exports = Hogan;
  559.  
  560.  
  561. /***/ }),
  562.  
  563. /***/ "cK6b":
  564. /***/ (function(module, exports, __webpack_require__) {
  565.  
  566. /*
  567. * Copyright 2011 Twitter, Inc.
  568. * Licensed under the Apache License, Version 2.0 (the "License");
  569. * you may not use this file except in compliance with the License.
  570. * You may obtain a copy of the License at
  571. *
  572. * http://www.apache.org/licenses/LICENSE-2.0
  573. *
  574. * Unless required by applicable law or agreed to in writing, software
  575. * distributed under the License is distributed on an "AS IS" BASIS,
  576. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  577. * See the License for the specific language governing permissions and
  578. * limitations under the License.
  579. */
  580.  
  581. var Hogan = {};
  582.  
  583. (function (Hogan) {
  584. Hogan.Template = function (codeObj, text, compiler, options) {
  585. codeObj = codeObj || {};
  586. this.r = codeObj.code || this.r;
  587. this.c = compiler;
  588. this.options = options || {};
  589. this.text = text || '';
  590. this.partials = codeObj.partials || {};
  591. this.subs = codeObj.subs || {};
  592. this.buf = '';
  593. }
  594.  
  595. Hogan.Template.prototype = {
  596. // render: replaced by generated code.
  597. r: function (context, partials, indent) { return ''; },
  598.  
  599. // variable escaping
  600. v: hoganEscape,
  601.  
  602. // triple stache
  603. t: coerceToString,
  604.  
  605. render: function render(context, partials, indent) {
  606. return this.ri([context], partials || {}, indent);
  607. },
  608.  
  609. // render internal -- a hook for overrides that catches partials too
  610. ri: function (context, partials, indent) {
  611. return this.r(context, partials, indent);
  612. },
  613.  
  614. // ensurePartial
  615. ep: function(symbol, partials) {
  616. var partial = this.partials[symbol];
  617.  
  618. // check to see that if we've instantiated this partial before
  619. var template = partials[partial.name];
  620. if (partial.instance && partial.base == template) {
  621. return partial.instance;
  622. }
  623.  
  624. if (typeof template == 'string') {
  625. if (!this.c) {
  626. throw new Error("No compiler available.");
  627. }
  628. template = this.c.compile(template, this.options);
  629. }
  630.  
  631. if (!template) {
  632. return null;
  633. }
  634.  
  635. // We use this to check whether the partials dictionary has changed
  636. this.partials[symbol].base = template;
  637.  
  638. if (partial.subs) {
  639. // Make sure we consider parent template now
  640. if (!partials.stackText) partials.stackText = {};
  641. for (key in partial.subs) {
  642. if (!partials.stackText[key]) {
  643. partials.stackText[key] = (this.activeSub !== undefined && partials.stackText[this.activeSub]) ? partials.stackText[this.activeSub] : this.text;
  644. }
  645. }
  646. template = createSpecializedPartial(template, partial.subs, partial.partials,
  647. this.stackSubs, this.stackPartials, partials.stackText);
  648. }
  649. this.partials[symbol].instance = template;
  650.  
  651. return template;
  652. },
  653.  
  654. // tries to find a partial in the current scope and render it
  655. rp: function(symbol, context, partials, indent) {
  656. var partial = this.ep(symbol, partials);
  657. if (!partial) {
  658. return '';
  659. }
  660.  
  661. return partial.ri(context, partials, indent);
  662. },
  663.  
  664. // render a section
  665. rs: function(context, partials, section) {
  666. var tail = context[context.length - 1];
  667.  
  668. if (!isArray(tail)) {
  669. section(context, partials, this);
  670. return;
  671. }
  672.  
  673. for (var i = 0; i < tail.length; i++) {
  674. context.push(tail[i]);
  675. section(context, partials, this);
  676. context.pop();
  677. }
  678. },
  679.  
  680. // maybe start a section
  681. s: function(val, ctx, partials, inverted, start, end, tags) {
  682. var pass;
  683.  
  684. if (isArray(val) && val.length === 0) {
  685. return false;
  686. }
  687.  
  688. if (typeof val == 'function') {
  689. val = this.ms(val, ctx, partials, inverted, start, end, tags);
  690. }
  691.  
  692. pass = !!val;
  693.  
  694. if (!inverted && pass && ctx) {
  695. ctx.push((typeof val == 'object') ? val : ctx[ctx.length - 1]);
  696. }
  697.  
  698. return pass;
  699. },
  700.  
  701. // find values with dotted names
  702. d: function(key, ctx, partials, returnFound) {
  703. var found,
  704. names = key.split('.'),
  705. val = this.f(names[0], ctx, partials, returnFound),
  706. doModelGet = this.options.modelGet,
  707. cx = null;
  708.  
  709. if (key === '.' && isArray(ctx[ctx.length - 2])) {
  710. val = ctx[ctx.length - 1];
  711. } else {
  712. for (var i = 1; i < names.length; i++) {
  713. found = findInScope(names[i], val, doModelGet);
  714. if (found !== undefined) {
  715. cx = val;
  716. val = found;
  717. } else {
  718. val = '';
  719. }
  720. }
  721. }
  722.  
  723. if (returnFound && !val) {
  724. return false;
  725. }
  726.  
  727. if (!returnFound && typeof val == 'function') {
  728. ctx.push(cx);
  729. val = this.mv(val, ctx, partials);
  730. ctx.pop();
  731. }
  732.  
  733. return val;
  734. },
  735.  
  736. // find values with normal names
  737. f: function(key, ctx, partials, returnFound) {
  738. var val = false,
  739. v = null,
  740. found = false,
  741. doModelGet = this.options.modelGet;
  742.  
  743. for (var i = ctx.length - 1; i >= 0; i--) {
  744. v = ctx[i];
  745. val = findInScope(key, v, doModelGet);
  746. if (val !== undefined) {
  747. found = true;
  748. break;
  749. }
  750. }
  751.  
  752. if (!found) {
  753. return (returnFound) ? false : "";
  754. }
  755.  
  756. if (!returnFound && typeof val == 'function') {
  757. val = this.mv(val, ctx, partials);
  758. }
  759.  
  760. return val;
  761. },
  762.  
  763. // higher order templates
  764. ls: function(func, cx, partials, text, tags) {
  765. var oldTags = this.options.delimiters;
  766.  
  767. this.options.delimiters = tags;
  768. this.b(this.ct(coerceToString(func.call(cx, text)), cx, partials));
  769. this.options.delimiters = oldTags;
  770.  
  771. return false;
  772. },
  773.  
  774. // compile text
  775. ct: function(text, cx, partials) {
  776. if (this.options.disableLambda) {
  777. throw new Error('Lambda features disabled.');
  778. }
  779. return this.c.compile(text, this.options).render(cx, partials);
  780. },
  781.  
  782. // template result buffering
  783. b: function(s) { this.buf += s; },
  784.  
  785. fl: function() { var r = this.buf; this.buf = ''; return r; },
  786.  
  787. // method replace section
  788. ms: function(func, ctx, partials, inverted, start, end, tags) {
  789. var textSource,
  790. cx = ctx[ctx.length - 1],
  791. result = func.call(cx);
  792.  
  793. if (typeof result == 'function') {
  794. if (inverted) {
  795. return true;
  796. } else {
  797. textSource = (this.activeSub && this.subsText && this.subsText[this.activeSub]) ? this.subsText[this.activeSub] : this.text;
  798. return this.ls(result, cx, partials, textSource.substring(start, end), tags);
  799. }
  800. }
  801.  
  802. return result;
  803. },
  804.  
  805. // method replace variable
  806. mv: function(func, ctx, partials) {
  807. var cx = ctx[ctx.length - 1];
  808. var result = func.call(cx);
  809.  
  810. if (typeof result == 'function') {
  811. return this.ct(coerceToString(result.call(cx)), cx, partials);
  812. }
  813.  
  814. return result;
  815. },
  816.  
  817. sub: function(name, context, partials, indent) {
  818. var f = this.subs[name];
  819. if (f) {
  820. this.activeSub = name;
  821. f(context, partials, this, indent);
  822. this.activeSub = false;
  823. }
  824. }
  825.  
  826. };
  827.  
  828. //Find a key in an object
  829. function findInScope(key, scope, doModelGet) {
  830. var val;
  831.  
  832. if (scope && typeof scope == 'object') {
  833.  
  834. if (scope[key] !== undefined) {
  835. val = scope[key];
  836.  
  837. // try lookup with get for backbone or similar model data
  838. } else if (doModelGet && scope.get && typeof scope.get == 'function') {
  839. val = scope.get(key);
  840. }
  841. }
  842.  
  843. return val;
  844. }
  845.  
  846. function createSpecializedPartial(instance, subs, partials, stackSubs, stackPartials, stackText) {
  847. function PartialTemplate() {};
  848. PartialTemplate.prototype = instance;
  849. function Substitutions() {};
  850. Substitutions.prototype = instance.subs;
  851. var key;
  852. var partial = new PartialTemplate();
  853. partial.subs = new Substitutions();
  854. partial.subsText = {}; //hehe. substext.
  855. partial.buf = '';
  856.  
  857. stackSubs = stackSubs || {};
  858. partial.stackSubs = stackSubs;
  859. partial.subsText = stackText;
  860. for (key in subs) {
  861. if (!stackSubs[key]) stackSubs[key] = subs[key];
  862. }
  863. for (key in stackSubs) {
  864. partial.subs[key] = stackSubs[key];
  865. }
  866.  
  867. stackPartials = stackPartials || {};
  868. partial.stackPartials = stackPartials;
  869. for (key in partials) {
  870. if (!stackPartials[key]) stackPartials[key] = partials[key];
  871. }
  872. for (key in stackPartials) {
  873. partial.partials[key] = stackPartials[key];
  874. }
  875.  
  876. return partial;
  877. }
  878.  
  879. var rAmp = /&/g,
  880. rLt = /</g,
  881. rGt = />/g,
  882. rApos = /\'/g,
  883. rQuot = /\"/g,
  884. hChars = /[&<>\"\']/;
  885.  
  886. function coerceToString(val) {
  887. return String((val === null || val === undefined) ? '' : val);
  888. }
  889.  
  890. function hoganEscape(str) {
  891. str = coerceToString(str);
  892. return hChars.test(str) ?
  893. str
  894. .replace(rAmp, '&amp;')
  895. .replace(rLt, '&lt;')
  896. .replace(rGt, '&gt;')
  897. .replace(rApos, '&#39;')
  898. .replace(rQuot, '&quot;') :
  899. str;
  900. }
  901.  
  902. var isArray = Array.isArray || function(a) {
  903. return Object.prototype.toString.call(a) === '[object Array]';
  904. };
  905.  
  906. })( true ? exports : undefined);
  907.  
  908.  
  909. /***/ }),
  910.  
  911. /***/ "e6Wu":
  912. /***/ (function(module, __webpack_exports__, __webpack_require__) {
  913.  
  914. "use strict";
  915. // ESM COMPAT FLAG
  916. __webpack_require__.r(__webpack_exports__);
  917.  
  918. // EXTERNAL MODULE: external "$"
  919. var external_$_ = __webpack_require__("xeH2");
  920.  
  921. // CONCATENATED MODULE: ./src/js/model.ts
  922. class RevDetail {
  923. constructor(title, rawInfo, description) {
  924. this.title = title;
  925. this.rawInfo = rawInfo;
  926. this.description = description;
  927. }
  928. }
  929. class Rev {
  930. }
  931. class Comment {
  932. constructor(rev, detail) {
  933. this.rev = rev;
  934. this.details = detail;
  935. }
  936. }
  937.  
  938. // CONCATENATED MODULE: ./src/js/parser.ts
  939.  
  940.  
  941. function parseRevDetails(html) {
  942. const jq = external_$_(html);
  943. const rawInfo = jq.find('#subject_infobox').val().toString();
  944. const title = jq.find('input[name="subject_title"]').val().toString();
  945. const description = jq.find('textarea#subject_summary').val().toString();
  946. return new RevDetail(title, rawInfo, description);
  947. }
  948. function parseRevEl(el) {
  949. const date = el.find('a').first().html();
  950. const revEL = el.find('a.l:contains("恢复")');
  951. const revCommentEl = el.find('span.comment');
  952. let comment = '';
  953. if (revCommentEl.length) {
  954. comment = revCommentEl.html();
  955. comment = comment.substring(1, comment.length - 1);
  956. }
  957. const revHref = revEL.attr('href');
  958. const revID = revHref.split('/').pop();
  959. return {
  960. id: revID,
  961. comment,
  962. date,
  963. url: revHref,
  964. };
  965. }
  966. function getRevs() {
  967. const revs = [];
  968. external_$_('#pagehistory li').each(function () {
  969. const el = external_$_(this);
  970. revs.push(parseRevEl(el));
  971. });
  972. return revs;
  973. }
  974. function getRevInfo(revID) {
  975. for (const rev of getRevs()) {
  976. if (rev.id === revID) {
  977. console.log(revID, rev);
  978. return rev;
  979. }
  980. }
  981. }
  982.  
  983. // CONCATENATED MODULE: ./src/js/utils.ts
  984. function request(url) {
  985. return new Promise((resolve) => {
  986. // @ts-ignore
  987. window.GM_xmlhttpRequest({
  988. url,
  989. // @ts-ignore
  990. onload: function ({ responseText, }) {
  991. resolve({ responseText });
  992. }
  993. });
  994. });
  995. }
  996.  
  997.  
  998. // EXTERNAL MODULE: ./node_modules/diff/dist/diff.js
  999. var dist_diff = __webpack_require__("v2jn");
  1000.  
  1001. // CONCATENATED MODULE: ./src/js/differ.ts
  1002.  
  1003. function differ_diff(rev1, rev2) {
  1004. return `${titleDiff(rev1, rev2)}\n${infoDiff(rev1, rev2)}\n${descriptionDiff(rev1, rev2)}`;
  1005. }
  1006. function titleDiff(rev1, rev2) {
  1007. if (rev1.details.title === rev2.details.title) {
  1008. return '';
  1009. }
  1010. return dist_diff["createTwoFilesPatch"]('title', 'title', rev1.details.title, rev2.details.title, rev1.rev.date, rev2.rev.date);
  1011. }
  1012. function infoDiff(rev1, rev2) {
  1013. if (rev1.details.rawInfo === rev2.details.rawInfo) {
  1014. return '';
  1015. }
  1016. return dist_diff["createTwoFilesPatch"]('info', 'info', rev1.details.rawInfo, rev2.details.rawInfo, rev1.rev.date, rev2.rev.date);
  1017. }
  1018. function descriptionDiff(rev1, rev2) {
  1019. return dist_diff["createTwoFilesPatch"]('description', 'description', rev1.details.description, rev2.details.description, rev1.rev.date, rev2.rev.date);
  1020. }
  1021.  
  1022. // CONCATENATED MODULE: ./node_modules/diff2html/lib-esm/types.js
  1023. var LineType;
  1024. (function (LineType) {
  1025. LineType["INSERT"] = "insert";
  1026. LineType["DELETE"] = "delete";
  1027. LineType["CONTEXT"] = "context";
  1028. })(LineType || (LineType = {}));
  1029. var OutputFormatType = {
  1030. LINE_BY_LINE: 'line-by-line',
  1031. SIDE_BY_SIDE: 'side-by-side',
  1032. };
  1033. var LineMatchingType = {
  1034. LINES: 'lines',
  1035. WORDS: 'words',
  1036. NONE: 'none',
  1037. };
  1038. var DiffStyleType = {
  1039. WORD: 'word',
  1040. CHAR: 'char',
  1041. };
  1042. //# sourceMappingURL=types.js.map
  1043. // CONCATENATED MODULE: ./node_modules/diff2html/lib-esm/utils.js
  1044. var specials = [
  1045. '-',
  1046. '[',
  1047. ']',
  1048. '/',
  1049. '{',
  1050. '}',
  1051. '(',
  1052. ')',
  1053. '*',
  1054. '+',
  1055. '?',
  1056. '.',
  1057. '\\',
  1058. '^',
  1059. '$',
  1060. '|',
  1061. ];
  1062. var regex = RegExp('[' + specials.join('\\') + ']', 'g');
  1063. function escapeForRegExp(str) {
  1064. return str.replace(regex, '\\$&');
  1065. }
  1066. function unifyPath(path) {
  1067. return path ? path.replace(/\\/g, '/') : path;
  1068. }
  1069. function hashCode(text) {
  1070. var i, chr, len;
  1071. var hash = 0;
  1072. for (i = 0, len = text.length; i < len; i++) {
  1073. chr = text.charCodeAt(i);
  1074. hash = (hash << 5) - hash + chr;
  1075. hash |= 0;
  1076. }
  1077. return hash;
  1078. }
  1079. //# sourceMappingURL=utils.js.map
  1080. // CONCATENATED MODULE: ./node_modules/diff2html/lib-esm/diff-parser.js
  1081. var __spreadArrays = (undefined && undefined.__spreadArrays) || function () {
  1082. for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
  1083. for (var r = Array(s), k = 0, i = 0; i < il; i++)
  1084. for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
  1085. r[k] = a[j];
  1086. return r;
  1087. };
  1088.  
  1089.  
  1090. function getExtension(filename, language) {
  1091. var filenameParts = filename.split('.');
  1092. return filenameParts.length > 1 ? filenameParts[filenameParts.length - 1] : language;
  1093. }
  1094. function startsWithAny(str, prefixes) {
  1095. return prefixes.reduce(function (startsWith, prefix) { return startsWith || str.startsWith(prefix); }, false);
  1096. }
  1097. var baseDiffFilenamePrefixes = ['a/', 'b/', 'i/', 'w/', 'c/', 'o/'];
  1098. function getFilename(line, linePrefix, extraPrefix) {
  1099. var prefixes = extraPrefix !== undefined ? __spreadArrays(baseDiffFilenamePrefixes, [extraPrefix]) : baseDiffFilenamePrefixes;
  1100. var FilenameRegExp = linePrefix
  1101. ? new RegExp("^" + escapeForRegExp(linePrefix) + " \"?(.+?)\"?$")
  1102. : new RegExp('^"?(.+?)"?$');
  1103. var _a = FilenameRegExp.exec(line) || [], _b = _a[1], filename = _b === void 0 ? '' : _b;
  1104. var matchingPrefix = prefixes.find(function (p) { return filename.indexOf(p) === 0; });
  1105. var fnameWithoutPrefix = matchingPrefix ? filename.slice(matchingPrefix.length) : filename;
  1106. return fnameWithoutPrefix.replace(/\s+\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}(?:\.\d+)? [+-]\d{4}.*$/, '');
  1107. }
  1108. function getSrcFilename(line, srcPrefix) {
  1109. return getFilename(line, '---', srcPrefix);
  1110. }
  1111. function getDstFilename(line, dstPrefix) {
  1112. return getFilename(line, '+++', dstPrefix);
  1113. }
  1114. function parse(diffInput, config) {
  1115. if (config === void 0) { config = {}; }
  1116. var files = [];
  1117. var currentFile = null;
  1118. var currentBlock = null;
  1119. var oldLine = null;
  1120. var oldLine2 = null;
  1121. var newLine = null;
  1122. var possibleOldName = null;
  1123. var possibleNewName = null;
  1124. var oldFileNameHeader = '--- ';
  1125. var newFileNameHeader = '+++ ';
  1126. var hunkHeaderPrefix = '@@';
  1127. var oldMode = /^old mode (\d{6})/;
  1128. var newMode = /^new mode (\d{6})/;
  1129. var deletedFileMode = /^deleted file mode (\d{6})/;
  1130. var newFileMode = /^new file mode (\d{6})/;
  1131. var copyFrom = /^copy from "?(.+)"?/;
  1132. var copyTo = /^copy to "?(.+)"?/;
  1133. var renameFrom = /^rename from "?(.+)"?/;
  1134. var renameTo = /^rename to "?(.+)"?/;
  1135. var similarityIndex = /^similarity index (\d+)%/;
  1136. var dissimilarityIndex = /^dissimilarity index (\d+)%/;
  1137. var index = /^index ([\da-z]+)\.\.([\da-z]+)\s*(\d{6})?/;
  1138. var binaryFiles = /^Binary files (.*) and (.*) differ/;
  1139. var binaryDiff = /^GIT binary patch/;
  1140. var combinedIndex = /^index ([\da-z]+),([\da-z]+)\.\.([\da-z]+)/;
  1141. var combinedMode = /^mode (\d{6}),(\d{6})\.\.(\d{6})/;
  1142. var combinedNewFile = /^new file mode (\d{6})/;
  1143. var combinedDeletedFile = /^deleted file mode (\d{6}),(\d{6})/;
  1144. var diffLines = diffInput
  1145. .replace(/\\ No newline at end of file/g, '')
  1146. .replace(/\r\n?/g, '\n')
  1147. .split('\n');
  1148. function saveBlock() {
  1149. if (currentBlock !== null && currentFile !== null) {
  1150. currentFile.blocks.push(currentBlock);
  1151. currentBlock = null;
  1152. }
  1153. }
  1154. function saveFile() {
  1155. if (currentFile !== null) {
  1156. if (!currentFile.oldName && possibleOldName !== null) {
  1157. currentFile.oldName = possibleOldName;
  1158. }
  1159. if (!currentFile.newName && possibleNewName !== null) {
  1160. currentFile.newName = possibleNewName;
  1161. }
  1162. if (currentFile.newName) {
  1163. files.push(currentFile);
  1164. currentFile = null;
  1165. }
  1166. }
  1167. possibleOldName = null;
  1168. possibleNewName = null;
  1169. }
  1170. function startFile() {
  1171. saveBlock();
  1172. saveFile();
  1173. currentFile = {
  1174. blocks: [],
  1175. deletedLines: 0,
  1176. addedLines: 0,
  1177. };
  1178. }
  1179. function startBlock(line) {
  1180. saveBlock();
  1181. var values;
  1182. if (currentFile !== null) {
  1183. if ((values = /^@@ -(\d+)(?:,\d+)? \+(\d+)(?:,\d+)? @@.*/.exec(line))) {
  1184. currentFile.isCombined = false;
  1185. oldLine = parseInt(values[1], 10);
  1186. newLine = parseInt(values[2], 10);
  1187. }
  1188. else if ((values = /^@@@ -(\d+)(?:,\d+)? -(\d+)(?:,\d+)? \+(\d+)(?:,\d+)? @@@.*/.exec(line))) {
  1189. currentFile.isCombined = true;
  1190. oldLine = parseInt(values[1], 10);
  1191. oldLine2 = parseInt(values[2], 10);
  1192. newLine = parseInt(values[3], 10);
  1193. }
  1194. else {
  1195. if (line.startsWith(hunkHeaderPrefix)) {
  1196. console.error('Failed to parse lines, starting in 0!');
  1197. }
  1198. oldLine = 0;
  1199. newLine = 0;
  1200. currentFile.isCombined = false;
  1201. }
  1202. }
  1203. currentBlock = {
  1204. lines: [],
  1205. oldStartLine: oldLine,
  1206. oldStartLine2: oldLine2,
  1207. newStartLine: newLine,
  1208. header: line,
  1209. };
  1210. }
  1211. function createLine(line) {
  1212. if (currentFile === null || currentBlock === null || oldLine === null || newLine === null)
  1213. return;
  1214. var currentLine = {
  1215. content: line,
  1216. };
  1217. var addedPrefixes = currentFile.isCombined ? ['+ ', ' +', '++'] : ['+'];
  1218. var deletedPrefixes = currentFile.isCombined ? ['- ', ' -', '--'] : ['-'];
  1219. if (startsWithAny(line, addedPrefixes)) {
  1220. currentFile.addedLines++;
  1221. currentLine.type = LineType.INSERT;
  1222. currentLine.oldNumber = undefined;
  1223. currentLine.newNumber = newLine++;
  1224. }
  1225. else if (startsWithAny(line, deletedPrefixes)) {
  1226. currentFile.deletedLines++;
  1227. currentLine.type = LineType.DELETE;
  1228. currentLine.oldNumber = oldLine++;
  1229. currentLine.newNumber = undefined;
  1230. }
  1231. else {
  1232. currentLine.type = LineType.CONTEXT;
  1233. currentLine.oldNumber = oldLine++;
  1234. currentLine.newNumber = newLine++;
  1235. }
  1236. currentBlock.lines.push(currentLine);
  1237. }
  1238. function existHunkHeader(line, lineIdx) {
  1239. var idx = lineIdx;
  1240. while (idx < diffLines.length - 3) {
  1241. if (line.startsWith('diff')) {
  1242. return false;
  1243. }
  1244. if (diffLines[idx].startsWith(oldFileNameHeader) &&
  1245. diffLines[idx + 1].startsWith(newFileNameHeader) &&
  1246. diffLines[idx + 2].startsWith(hunkHeaderPrefix)) {
  1247. return true;
  1248. }
  1249. idx++;
  1250. }
  1251. return false;
  1252. }
  1253. diffLines.forEach(function (line, lineIndex) {
  1254. if (!line || line.startsWith('*')) {
  1255. return;
  1256. }
  1257. var values;
  1258. var prevLine = diffLines[lineIndex - 1];
  1259. var nxtLine = diffLines[lineIndex + 1];
  1260. var afterNxtLine = diffLines[lineIndex + 2];
  1261. if (line.startsWith('diff')) {
  1262. startFile();
  1263. var gitDiffStart = /^diff --git "?(.+)"? "?(.+)"?/;
  1264. if ((values = gitDiffStart.exec(line))) {
  1265. possibleOldName = getFilename(values[1], undefined, config.dstPrefix);
  1266. possibleNewName = getFilename(values[2], undefined, config.srcPrefix);
  1267. }
  1268. if (currentFile === null) {
  1269. throw new Error('Where is my file !!!');
  1270. }
  1271. currentFile.isGitDiff = true;
  1272. return;
  1273. }
  1274. if (!currentFile ||
  1275. (!currentFile.isGitDiff &&
  1276. currentFile &&
  1277. line.startsWith(oldFileNameHeader) &&
  1278. nxtLine.startsWith(newFileNameHeader) &&
  1279. afterNxtLine.startsWith(hunkHeaderPrefix))) {
  1280. startFile();
  1281. }
  1282. if ((line.startsWith(oldFileNameHeader) && nxtLine.startsWith(newFileNameHeader)) ||
  1283. (line.startsWith(newFileNameHeader) && prevLine.startsWith(oldFileNameHeader))) {
  1284. if (currentFile &&
  1285. !currentFile.oldName &&
  1286. line.startsWith('--- ') &&
  1287. (values = getSrcFilename(line, config.srcPrefix))) {
  1288. currentFile.oldName = values;
  1289. currentFile.language = getExtension(currentFile.oldName, currentFile.language);
  1290. return;
  1291. }
  1292. if (currentFile &&
  1293. !currentFile.newName &&
  1294. line.startsWith('+++ ') &&
  1295. (values = getDstFilename(line, config.dstPrefix))) {
  1296. currentFile.newName = values;
  1297. currentFile.language = getExtension(currentFile.newName, currentFile.language);
  1298. return;
  1299. }
  1300. }
  1301. if (currentFile &&
  1302. (line.startsWith(hunkHeaderPrefix) ||
  1303. (currentFile.isGitDiff && currentFile.oldName && currentFile.newName && !currentBlock))) {
  1304. startBlock(line);
  1305. return;
  1306. }
  1307. if (currentBlock && (line.startsWith('+') || line.startsWith('-') || line.startsWith(' '))) {
  1308. createLine(line);
  1309. return;
  1310. }
  1311. var doesNotExistHunkHeader = !existHunkHeader(line, lineIndex);
  1312. if (currentFile === null) {
  1313. throw new Error('Where is my file !!!');
  1314. }
  1315. if ((values = oldMode.exec(line))) {
  1316. currentFile.oldMode = values[1];
  1317. }
  1318. else if ((values = newMode.exec(line))) {
  1319. currentFile.newMode = values[1];
  1320. }
  1321. else if ((values = deletedFileMode.exec(line))) {
  1322. currentFile.deletedFileMode = values[1];
  1323. currentFile.isDeleted = true;
  1324. }
  1325. else if ((values = newFileMode.exec(line))) {
  1326. currentFile.newFileMode = values[1];
  1327. currentFile.isNew = true;
  1328. }
  1329. else if ((values = copyFrom.exec(line))) {
  1330. if (doesNotExistHunkHeader) {
  1331. currentFile.oldName = values[1];
  1332. }
  1333. currentFile.isCopy = true;
  1334. }
  1335. else if ((values = copyTo.exec(line))) {
  1336. if (doesNotExistHunkHeader) {
  1337. currentFile.newName = values[1];
  1338. }
  1339. currentFile.isCopy = true;
  1340. }
  1341. else if ((values = renameFrom.exec(line))) {
  1342. if (doesNotExistHunkHeader) {
  1343. currentFile.oldName = values[1];
  1344. }
  1345. currentFile.isRename = true;
  1346. }
  1347. else if ((values = renameTo.exec(line))) {
  1348. if (doesNotExistHunkHeader) {
  1349. currentFile.newName = values[1];
  1350. }
  1351. currentFile.isRename = true;
  1352. }
  1353. else if ((values = binaryFiles.exec(line))) {
  1354. currentFile.isBinary = true;
  1355. currentFile.oldName = getFilename(values[1], undefined, config.srcPrefix);
  1356. currentFile.newName = getFilename(values[2], undefined, config.dstPrefix);
  1357. startBlock('Binary file');
  1358. }
  1359. else if (binaryDiff.test(line)) {
  1360. currentFile.isBinary = true;
  1361. startBlock(line);
  1362. }
  1363. else if ((values = similarityIndex.exec(line))) {
  1364. currentFile.unchangedPercentage = parseInt(values[1], 10);
  1365. }
  1366. else if ((values = dissimilarityIndex.exec(line))) {
  1367. currentFile.changedPercentage = parseInt(values[1], 10);
  1368. }
  1369. else if ((values = index.exec(line))) {
  1370. currentFile.checksumBefore = values[1];
  1371. currentFile.checksumAfter = values[2];
  1372. values[3] && (currentFile.mode = values[3]);
  1373. }
  1374. else if ((values = combinedIndex.exec(line))) {
  1375. currentFile.checksumBefore = [values[2], values[3]];
  1376. currentFile.checksumAfter = values[1];
  1377. }
  1378. else if ((values = combinedMode.exec(line))) {
  1379. currentFile.oldMode = [values[2], values[3]];
  1380. currentFile.newMode = values[1];
  1381. }
  1382. else if ((values = combinedNewFile.exec(line))) {
  1383. currentFile.newFileMode = values[1];
  1384. currentFile.isNew = true;
  1385. }
  1386. else if ((values = combinedDeletedFile.exec(line))) {
  1387. currentFile.deletedFileMode = values[1];
  1388. currentFile.isDeleted = true;
  1389. }
  1390. });
  1391. saveBlock();
  1392. saveFile();
  1393. return files;
  1394. }
  1395. //# sourceMappingURL=diff-parser.js.map
  1396. // CONCATENATED MODULE: ./node_modules/diff2html/lib-esm/rematch.js
  1397. function levenshtein(a, b) {
  1398. if (a.length === 0) {
  1399. return b.length;
  1400. }
  1401. if (b.length === 0) {
  1402. return a.length;
  1403. }
  1404. var matrix = [];
  1405. var i;
  1406. for (i = 0; i <= b.length; i++) {
  1407. matrix[i] = [i];
  1408. }
  1409. var j;
  1410. for (j = 0; j <= a.length; j++) {
  1411. matrix[0][j] = j;
  1412. }
  1413. for (i = 1; i <= b.length; i++) {
  1414. for (j = 1; j <= a.length; j++) {
  1415. if (b.charAt(i - 1) === a.charAt(j - 1)) {
  1416. matrix[i][j] = matrix[i - 1][j - 1];
  1417. }
  1418. else {
  1419. matrix[i][j] = Math.min(matrix[i - 1][j - 1] + 1, Math.min(matrix[i][j - 1] + 1, matrix[i - 1][j] + 1));
  1420. }
  1421. }
  1422. }
  1423. return matrix[b.length][a.length];
  1424. }
  1425. function newDistanceFn(str) {
  1426. return function (x, y) {
  1427. var xValue = str(x).trim();
  1428. var yValue = str(y).trim();
  1429. var lev = levenshtein(xValue, yValue);
  1430. return lev / (xValue.length + yValue.length);
  1431. };
  1432. }
  1433. function newMatcherFn(distance) {
  1434. function findBestMatch(a, b, cache) {
  1435. if (cache === void 0) { cache = new Map(); }
  1436. var bestMatchDist = Infinity;
  1437. var bestMatch;
  1438. for (var i = 0; i < a.length; ++i) {
  1439. for (var j = 0; j < b.length; ++j) {
  1440. var cacheKey = JSON.stringify([a[i], b[j]]);
  1441. var md = void 0;
  1442. if (!(cache.has(cacheKey) && (md = cache.get(cacheKey)))) {
  1443. md = distance(a[i], b[j]);
  1444. cache.set(cacheKey, md);
  1445. }
  1446. if (md < bestMatchDist) {
  1447. bestMatchDist = md;
  1448. bestMatch = { indexA: i, indexB: j, score: bestMatchDist };
  1449. }
  1450. }
  1451. }
  1452. return bestMatch;
  1453. }
  1454. function group(a, b, level, cache) {
  1455. if (level === void 0) { level = 0; }
  1456. if (cache === void 0) { cache = new Map(); }
  1457. var bm = findBestMatch(a, b, cache);
  1458. if (!bm || a.length + b.length < 3) {
  1459. return [[a, b]];
  1460. }
  1461. var a1 = a.slice(0, bm.indexA);
  1462. var b1 = b.slice(0, bm.indexB);
  1463. var aMatch = [a[bm.indexA]];
  1464. var bMatch = [b[bm.indexB]];
  1465. var tailA = bm.indexA + 1;
  1466. var tailB = bm.indexB + 1;
  1467. var a2 = a.slice(tailA);
  1468. var b2 = b.slice(tailB);
  1469. var group1 = group(a1, b1, level + 1, cache);
  1470. var groupMatch = group(aMatch, bMatch, level + 1, cache);
  1471. var group2 = group(a2, b2, level + 1, cache);
  1472. var result = groupMatch;
  1473. if (bm.indexA > 0 || bm.indexB > 0) {
  1474. result = group1.concat(result);
  1475. }
  1476. if (a.length > tailA || b.length > tailB) {
  1477. result = result.concat(group2);
  1478. }
  1479. return result;
  1480. }
  1481. return group;
  1482. }
  1483. //# sourceMappingURL=rematch.js.map
  1484. // CONCATENATED MODULE: ./node_modules/diff2html/lib-esm/render-utils.js
  1485. var __assign = (undefined && undefined.__assign) || function () {
  1486. __assign = Object.assign || function(t) {
  1487. for (var s, i = 1, n = arguments.length; i < n; i++) {
  1488. s = arguments[i];
  1489. for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
  1490. t[p] = s[p];
  1491. }
  1492. return t;
  1493. };
  1494. return __assign.apply(this, arguments);
  1495. };
  1496.  
  1497.  
  1498.  
  1499.  
  1500. var CSSLineClass = {
  1501. INSERTS: 'd2h-ins',
  1502. DELETES: 'd2h-del',
  1503. CONTEXT: 'd2h-cntx',
  1504. INFO: 'd2h-info',
  1505. INSERT_CHANGES: 'd2h-ins d2h-change',
  1506. DELETE_CHANGES: 'd2h-del d2h-change',
  1507. };
  1508. var defaultRenderConfig = {
  1509. matching: LineMatchingType.NONE,
  1510. matchWordsThreshold: 0.25,
  1511. maxLineLengthHighlight: 10000,
  1512. diffStyle: DiffStyleType.WORD,
  1513. };
  1514. var separator = '/';
  1515. var distance = newDistanceFn(function (change) { return change.value; });
  1516. var render_utils_matcher = newMatcherFn(distance);
  1517. function isDevNullName(name) {
  1518. return name.indexOf('dev/null') !== -1;
  1519. }
  1520. function removeInsElements(line) {
  1521. return line.replace(/(<ins[^>]*>((.|\n)*?)<\/ins>)/g, '');
  1522. }
  1523. function removeDelElements(line) {
  1524. return line.replace(/(<del[^>]*>((.|\n)*?)<\/del>)/g, '');
  1525. }
  1526. function toCSSClass(lineType) {
  1527. switch (lineType) {
  1528. case LineType.CONTEXT:
  1529. return CSSLineClass.CONTEXT;
  1530. case LineType.INSERT:
  1531. return CSSLineClass.INSERTS;
  1532. case LineType.DELETE:
  1533. return CSSLineClass.DELETES;
  1534. }
  1535. }
  1536. function prefixLength(isCombined) {
  1537. return isCombined ? 2 : 1;
  1538. }
  1539. function escapeForHtml(str) {
  1540. return str
  1541. .slice(0)
  1542. .replace(/&/g, '&amp;')
  1543. .replace(/</g, '&lt;')
  1544. .replace(/>/g, '&gt;')
  1545. .replace(/"/g, '&quot;')
  1546. .replace(/'/g, '&#x27;')
  1547. .replace(/\//g, '&#x2F;');
  1548. }
  1549. function deconstructLine(line, isCombined, escape) {
  1550. if (escape === void 0) { escape = true; }
  1551. var indexToSplit = prefixLength(isCombined);
  1552. return {
  1553. prefix: line.substring(0, indexToSplit),
  1554. content: escape ? escapeForHtml(line.substring(indexToSplit)) : line.substring(indexToSplit),
  1555. };
  1556. }
  1557. function filenameDiff(file) {
  1558. var oldFilename = unifyPath(file.oldName);
  1559. var newFilename = unifyPath(file.newName);
  1560. if (oldFilename !== newFilename && !isDevNullName(oldFilename) && !isDevNullName(newFilename)) {
  1561. var prefixPaths = [];
  1562. var suffixPaths = [];
  1563. var oldFilenameParts = oldFilename.split(separator);
  1564. var newFilenameParts = newFilename.split(separator);
  1565. var oldFilenamePartsSize = oldFilenameParts.length;
  1566. var newFilenamePartsSize = newFilenameParts.length;
  1567. var i = 0;
  1568. var j = oldFilenamePartsSize - 1;
  1569. var k = newFilenamePartsSize - 1;
  1570. while (i < j && i < k) {
  1571. if (oldFilenameParts[i] === newFilenameParts[i]) {
  1572. prefixPaths.push(newFilenameParts[i]);
  1573. i += 1;
  1574. }
  1575. else {
  1576. break;
  1577. }
  1578. }
  1579. while (j > i && k > i) {
  1580. if (oldFilenameParts[j] === newFilenameParts[k]) {
  1581. suffixPaths.unshift(newFilenameParts[k]);
  1582. j -= 1;
  1583. k -= 1;
  1584. }
  1585. else {
  1586. break;
  1587. }
  1588. }
  1589. var finalPrefix = prefixPaths.join(separator);
  1590. var finalSuffix = suffixPaths.join(separator);
  1591. var oldRemainingPath = oldFilenameParts.slice(i, j + 1).join(separator);
  1592. var newRemainingPath = newFilenameParts.slice(i, k + 1).join(separator);
  1593. if (finalPrefix.length && finalSuffix.length) {
  1594. return (finalPrefix + separator + '{' + oldRemainingPath + ' → ' + newRemainingPath + '}' + separator + finalSuffix);
  1595. }
  1596. else if (finalPrefix.length) {
  1597. return finalPrefix + separator + '{' + oldRemainingPath + ' → ' + newRemainingPath + '}';
  1598. }
  1599. else if (finalSuffix.length) {
  1600. return '{' + oldRemainingPath + ' → ' + newRemainingPath + '}' + separator + finalSuffix;
  1601. }
  1602. return oldFilename + ' → ' + newFilename;
  1603. }
  1604. else if (!isDevNullName(newFilename)) {
  1605. return newFilename;
  1606. }
  1607. else {
  1608. return oldFilename;
  1609. }
  1610. }
  1611. function getHtmlId(file) {
  1612. return "d2h-" + hashCode(filenameDiff(file))
  1613. .toString()
  1614. .slice(-6);
  1615. }
  1616. function getFileIcon(file) {
  1617. var templateName = 'file-changed';
  1618. if (file.isRename) {
  1619. templateName = 'file-renamed';
  1620. }
  1621. else if (file.isCopy) {
  1622. templateName = 'file-renamed';
  1623. }
  1624. else if (file.isNew) {
  1625. templateName = 'file-added';
  1626. }
  1627. else if (file.isDeleted) {
  1628. templateName = 'file-deleted';
  1629. }
  1630. else if (file.newName !== file.oldName) {
  1631. templateName = 'file-renamed';
  1632. }
  1633. return templateName;
  1634. }
  1635. function diffHighlight(diffLine1, diffLine2, isCombined, config) {
  1636. if (config === void 0) { config = {}; }
  1637. var _a = __assign(__assign({}, defaultRenderConfig), config), matching = _a.matching, maxLineLengthHighlight = _a.maxLineLengthHighlight, matchWordsThreshold = _a.matchWordsThreshold, diffStyle = _a.diffStyle;
  1638. var line1 = deconstructLine(diffLine1, isCombined, false);
  1639. var line2 = deconstructLine(diffLine2, isCombined, false);
  1640. if (line1.content.length > maxLineLengthHighlight || line2.content.length > maxLineLengthHighlight) {
  1641. return {
  1642. oldLine: {
  1643. prefix: line1.prefix,
  1644. content: line1.content,
  1645. },
  1646. newLine: {
  1647. prefix: line2.prefix,
  1648. content: line2.content,
  1649. },
  1650. };
  1651. }
  1652. var diff = diffStyle === 'char'
  1653. ? dist_diff["diffChars"](line1.content, line2.content)
  1654. : dist_diff["diffWordsWithSpace"](line1.content, line2.content);
  1655. var changedWords = [];
  1656. if (diffStyle === 'word' && matching === 'words') {
  1657. var removed = diff.filter(function (element) { return element.removed; });
  1658. var added = diff.filter(function (element) { return element.added; });
  1659. var chunks = render_utils_matcher(added, removed);
  1660. chunks.forEach(function (chunk) {
  1661. if (chunk[0].length === 1 && chunk[1].length === 1) {
  1662. var dist = distance(chunk[0][0], chunk[1][0]);
  1663. if (dist < matchWordsThreshold) {
  1664. changedWords.push(chunk[0][0]);
  1665. changedWords.push(chunk[1][0]);
  1666. }
  1667. }
  1668. });
  1669. }
  1670. var highlightedLine = diff.reduce(function (highlightedLine, part) {
  1671. var elemType = part.added ? 'ins' : part.removed ? 'del' : null;
  1672. var addClass = changedWords.indexOf(part) > -1 ? ' class="d2h-change"' : '';
  1673. var escapedValue = escapeForHtml(part.value);
  1674. return elemType !== null
  1675. ? highlightedLine + "<" + elemType + addClass + ">" + escapedValue + "</" + elemType + ">"
  1676. : "" + highlightedLine + escapedValue;
  1677. }, '');
  1678. return {
  1679. oldLine: {
  1680. prefix: line1.prefix,
  1681. content: removeInsElements(highlightedLine),
  1682. },
  1683. newLine: {
  1684. prefix: line2.prefix,
  1685. content: removeDelElements(highlightedLine),
  1686. },
  1687. };
  1688. }
  1689. //# sourceMappingURL=render-utils.js.map
  1690. // CONCATENATED MODULE: ./node_modules/diff2html/lib-esm/file-list-renderer.js
  1691.  
  1692. var baseTemplatesPath = 'file-summary';
  1693. var iconsBaseTemplatesPath = 'icon';
  1694. function render(diffFiles, hoganUtils) {
  1695. var files = diffFiles
  1696. .map(function (file) {
  1697. return hoganUtils.render(baseTemplatesPath, 'line', {
  1698. fileHtmlId: getHtmlId(file),
  1699. oldName: file.oldName,
  1700. newName: file.newName,
  1701. fileName: filenameDiff(file),
  1702. deletedLines: '-' + file.deletedLines,
  1703. addedLines: '+' + file.addedLines,
  1704. }, {
  1705. fileIcon: hoganUtils.template(iconsBaseTemplatesPath, getFileIcon(file)),
  1706. });
  1707. })
  1708. .join('\n');
  1709. return hoganUtils.render(baseTemplatesPath, 'wrapper', {
  1710. filesNumber: diffFiles.length,
  1711. files: files,
  1712. });
  1713. }
  1714. //# sourceMappingURL=file-list-renderer.js.map
  1715. // CONCATENATED MODULE: ./node_modules/diff2html/lib-esm/line-by-line-renderer.js
  1716. var line_by_line_renderer_assign = (undefined && undefined.__assign) || function () {
  1717. line_by_line_renderer_assign = Object.assign || function(t) {
  1718. for (var s, i = 1, n = arguments.length; i < n; i++) {
  1719. s = arguments[i];
  1720. for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
  1721. t[p] = s[p];
  1722. }
  1723. return t;
  1724. };
  1725. return line_by_line_renderer_assign.apply(this, arguments);
  1726. };
  1727.  
  1728.  
  1729.  
  1730. var defaultLineByLineRendererConfig = line_by_line_renderer_assign(line_by_line_renderer_assign({}, defaultRenderConfig), { renderNothingWhenEmpty: false, matchingMaxComparisons: 2500, maxLineSizeInBlockForComparison: 200 });
  1731. var genericTemplatesPath = 'generic';
  1732. var line_by_line_renderer_baseTemplatesPath = 'line-by-line';
  1733. var line_by_line_renderer_iconsBaseTemplatesPath = 'icon';
  1734. var tagsBaseTemplatesPath = 'tag';
  1735. var line_by_line_renderer_LineByLineRenderer = (function () {
  1736. function LineByLineRenderer(hoganUtils, config) {
  1737. if (config === void 0) { config = {}; }
  1738. this.hoganUtils = hoganUtils;
  1739. this.config = line_by_line_renderer_assign(line_by_line_renderer_assign({}, defaultLineByLineRendererConfig), config);
  1740. }
  1741. LineByLineRenderer.prototype.render = function (diffFiles) {
  1742. var _this = this;
  1743. var diffsHtml = diffFiles
  1744. .map(function (file) {
  1745. var diffs;
  1746. if (file.blocks.length) {
  1747. diffs = _this.generateFileHtml(file);
  1748. }
  1749. else {
  1750. diffs = _this.generateEmptyDiff();
  1751. }
  1752. return _this.makeFileDiffHtml(file, diffs);
  1753. })
  1754. .join('\n');
  1755. return this.hoganUtils.render(genericTemplatesPath, 'wrapper', { content: diffsHtml });
  1756. };
  1757. LineByLineRenderer.prototype.makeFileDiffHtml = function (file, diffs) {
  1758. if (this.config.renderNothingWhenEmpty && Array.isArray(file.blocks) && file.blocks.length === 0)
  1759. return '';
  1760. var fileDiffTemplate = this.hoganUtils.template(line_by_line_renderer_baseTemplatesPath, 'file-diff');
  1761. var filePathTemplate = this.hoganUtils.template(genericTemplatesPath, 'file-path');
  1762. var fileIconTemplate = this.hoganUtils.template(line_by_line_renderer_iconsBaseTemplatesPath, 'file');
  1763. var fileTagTemplate = this.hoganUtils.template(tagsBaseTemplatesPath, getFileIcon(file));
  1764. return fileDiffTemplate.render({
  1765. file: file,
  1766. fileHtmlId: getHtmlId(file),
  1767. diffs: diffs,
  1768. filePath: filePathTemplate.render({
  1769. fileDiffName: filenameDiff(file),
  1770. }, {
  1771. fileIcon: fileIconTemplate,
  1772. fileTag: fileTagTemplate,
  1773. }),
  1774. });
  1775. };
  1776. LineByLineRenderer.prototype.generateEmptyDiff = function () {
  1777. return this.hoganUtils.render(genericTemplatesPath, 'empty-diff', {
  1778. contentClass: 'd2h-code-line',
  1779. CSSLineClass: CSSLineClass,
  1780. });
  1781. };
  1782. LineByLineRenderer.prototype.generateFileHtml = function (file) {
  1783. var _this = this;
  1784. var matcher = newMatcherFn(newDistanceFn(function (e) { return deconstructLine(e.content, file.isCombined).content; }));
  1785. return file.blocks
  1786. .map(function (block) {
  1787. var lines = _this.hoganUtils.render(genericTemplatesPath, 'block-header', {
  1788. CSSLineClass: CSSLineClass,
  1789. blockHeader: block.header,
  1790. lineClass: 'd2h-code-linenumber',
  1791. contentClass: 'd2h-code-line',
  1792. });
  1793. _this.applyLineGroupping(block).forEach(function (_a) {
  1794. var contextLines = _a[0], oldLines = _a[1], newLines = _a[2];
  1795. if (oldLines.length && newLines.length && !contextLines.length) {
  1796. _this.applyRematchMatching(oldLines, newLines, matcher).map(function (_a) {
  1797. var oldLines = _a[0], newLines = _a[1];
  1798. var _b = _this.processChangedLines(file.isCombined, oldLines, newLines), left = _b.left, right = _b.right;
  1799. lines += left;
  1800. lines += right;
  1801. });
  1802. }
  1803. else if (contextLines.length) {
  1804. contextLines.forEach(function (line) {
  1805. var _a = deconstructLine(line.content, file.isCombined), prefix = _a.prefix, content = _a.content;
  1806. lines += _this.generateSingleLineHtml({
  1807. type: CSSLineClass.CONTEXT,
  1808. prefix: prefix,
  1809. content: content,
  1810. oldNumber: line.oldNumber,
  1811. newNumber: line.newNumber,
  1812. });
  1813. });
  1814. }
  1815. else if (oldLines.length || newLines.length) {
  1816. var _b = _this.processChangedLines(file.isCombined, oldLines, newLines), left = _b.left, right = _b.right;
  1817. lines += left;
  1818. lines += right;
  1819. }
  1820. else {
  1821. console.error('Unknown state reached while processing groups of lines', contextLines, oldLines, newLines);
  1822. }
  1823. });
  1824. return lines;
  1825. })
  1826. .join('\n');
  1827. };
  1828. LineByLineRenderer.prototype.applyLineGroupping = function (block) {
  1829. var blockLinesGroups = [];
  1830. var oldLines = [];
  1831. var newLines = [];
  1832. for (var i = 0; i < block.lines.length; i++) {
  1833. var diffLine = block.lines[i];
  1834. if ((diffLine.type !== LineType.INSERT && newLines.length) ||
  1835. (diffLine.type === LineType.CONTEXT && oldLines.length > 0)) {
  1836. blockLinesGroups.push([[], oldLines, newLines]);
  1837. oldLines = [];
  1838. newLines = [];
  1839. }
  1840. if (diffLine.type === LineType.CONTEXT) {
  1841. blockLinesGroups.push([[diffLine], [], []]);
  1842. }
  1843. else if (diffLine.type === LineType.INSERT && oldLines.length === 0) {
  1844. blockLinesGroups.push([[], [], [diffLine]]);
  1845. }
  1846. else if (diffLine.type === LineType.INSERT && oldLines.length > 0) {
  1847. newLines.push(diffLine);
  1848. }
  1849. else if (diffLine.type === LineType.DELETE) {
  1850. oldLines.push(diffLine);
  1851. }
  1852. }
  1853. if (oldLines.length || newLines.length) {
  1854. blockLinesGroups.push([[], oldLines, newLines]);
  1855. oldLines = [];
  1856. newLines = [];
  1857. }
  1858. return blockLinesGroups;
  1859. };
  1860. LineByLineRenderer.prototype.applyRematchMatching = function (oldLines, newLines, matcher) {
  1861. var comparisons = oldLines.length * newLines.length;
  1862. var maxLineSizeInBlock = Math.max.apply(null, [0].concat(oldLines.concat(newLines).map(function (elem) { return elem.content.length; })));
  1863. var doMatching = comparisons < this.config.matchingMaxComparisons &&
  1864. maxLineSizeInBlock < this.config.maxLineSizeInBlockForComparison &&
  1865. (this.config.matching === 'lines' || this.config.matching === 'words');
  1866. return doMatching ? matcher(oldLines, newLines) : [[oldLines, newLines]];
  1867. };
  1868. LineByLineRenderer.prototype.processChangedLines = function (isCombined, oldLines, newLines) {
  1869. var fileHtml = {
  1870. right: '',
  1871. left: '',
  1872. };
  1873. var maxLinesNumber = Math.max(oldLines.length, newLines.length);
  1874. for (var i = 0; i < maxLinesNumber; i++) {
  1875. var oldLine = oldLines[i];
  1876. var newLine = newLines[i];
  1877. var diff = oldLine !== undefined && newLine !== undefined
  1878. ? diffHighlight(oldLine.content, newLine.content, isCombined, this.config)
  1879. : undefined;
  1880. var preparedOldLine = oldLine !== undefined && oldLine.oldNumber !== undefined
  1881. ? line_by_line_renderer_assign(line_by_line_renderer_assign({}, (diff !== undefined
  1882. ? {
  1883. prefix: diff.oldLine.prefix,
  1884. content: diff.oldLine.content,
  1885. type: CSSLineClass.DELETE_CHANGES,
  1886. }
  1887. : line_by_line_renderer_assign(line_by_line_renderer_assign({}, deconstructLine(oldLine.content, isCombined)), { type: toCSSClass(oldLine.type) }))), { oldNumber: oldLine.oldNumber, newNumber: oldLine.newNumber }) : undefined;
  1888. var preparedNewLine = newLine !== undefined && newLine.newNumber !== undefined
  1889. ? line_by_line_renderer_assign(line_by_line_renderer_assign({}, (diff !== undefined
  1890. ? {
  1891. prefix: diff.newLine.prefix,
  1892. content: diff.newLine.content,
  1893. type: CSSLineClass.INSERT_CHANGES,
  1894. }
  1895. : line_by_line_renderer_assign(line_by_line_renderer_assign({}, deconstructLine(newLine.content, isCombined)), { type: toCSSClass(newLine.type) }))), { oldNumber: newLine.oldNumber, newNumber: newLine.newNumber }) : undefined;
  1896. var _a = this.generateLineHtml(preparedOldLine, preparedNewLine), left = _a.left, right = _a.right;
  1897. fileHtml.left += left;
  1898. fileHtml.right += right;
  1899. }
  1900. return fileHtml;
  1901. };
  1902. LineByLineRenderer.prototype.generateLineHtml = function (oldLine, newLine) {
  1903. return {
  1904. left: this.generateSingleLineHtml(oldLine),
  1905. right: this.generateSingleLineHtml(newLine),
  1906. };
  1907. };
  1908. LineByLineRenderer.prototype.generateSingleLineHtml = function (line) {
  1909. if (line === undefined)
  1910. return '';
  1911. var lineNumberHtml = this.hoganUtils.render(line_by_line_renderer_baseTemplatesPath, 'numbers', {
  1912. oldNumber: line.oldNumber || '',
  1913. newNumber: line.newNumber || '',
  1914. });
  1915. return this.hoganUtils.render(genericTemplatesPath, 'line', {
  1916. type: line.type,
  1917. lineClass: 'd2h-code-linenumber',
  1918. contentClass: 'd2h-code-line',
  1919. prefix: line.prefix === ' ' ? '&nbsp;' : line.prefix,
  1920. content: line.content,
  1921. lineNumber: lineNumberHtml,
  1922. });
  1923. };
  1924. return LineByLineRenderer;
  1925. }());
  1926. /* harmony default export */ var line_by_line_renderer = (line_by_line_renderer_LineByLineRenderer);
  1927. //# sourceMappingURL=line-by-line-renderer.js.map
  1928. // CONCATENATED MODULE: ./node_modules/diff2html/lib-esm/side-by-side-renderer.js
  1929. var side_by_side_renderer_assign = (undefined && undefined.__assign) || function () {
  1930. side_by_side_renderer_assign = Object.assign || function(t) {
  1931. for (var s, i = 1, n = arguments.length; i < n; i++) {
  1932. s = arguments[i];
  1933. for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
  1934. t[p] = s[p];
  1935. }
  1936. return t;
  1937. };
  1938. return side_by_side_renderer_assign.apply(this, arguments);
  1939. };
  1940.  
  1941.  
  1942.  
  1943. var defaultSideBySideRendererConfig = side_by_side_renderer_assign(side_by_side_renderer_assign({}, defaultRenderConfig), { renderNothingWhenEmpty: false, matchingMaxComparisons: 2500, maxLineSizeInBlockForComparison: 200 });
  1944. var side_by_side_renderer_genericTemplatesPath = 'generic';
  1945. var side_by_side_renderer_baseTemplatesPath = 'side-by-side';
  1946. var side_by_side_renderer_iconsBaseTemplatesPath = 'icon';
  1947. var side_by_side_renderer_tagsBaseTemplatesPath = 'tag';
  1948. var side_by_side_renderer_SideBySideRenderer = (function () {
  1949. function SideBySideRenderer(hoganUtils, config) {
  1950. if (config === void 0) { config = {}; }
  1951. this.hoganUtils = hoganUtils;
  1952. this.config = side_by_side_renderer_assign(side_by_side_renderer_assign({}, defaultSideBySideRendererConfig), config);
  1953. }
  1954. SideBySideRenderer.prototype.render = function (diffFiles) {
  1955. var _this = this;
  1956. var diffsHtml = diffFiles
  1957. .map(function (file) {
  1958. var diffs;
  1959. if (file.blocks.length) {
  1960. diffs = _this.generateFileHtml(file);
  1961. }
  1962. else {
  1963. diffs = _this.generateEmptyDiff();
  1964. }
  1965. return _this.makeFileDiffHtml(file, diffs);
  1966. })
  1967. .join('\n');
  1968. return this.hoganUtils.render(side_by_side_renderer_genericTemplatesPath, 'wrapper', { content: diffsHtml });
  1969. };
  1970. SideBySideRenderer.prototype.makeFileDiffHtml = function (file, diffs) {
  1971. if (this.config.renderNothingWhenEmpty && Array.isArray(file.blocks) && file.blocks.length === 0)
  1972. return '';
  1973. var fileDiffTemplate = this.hoganUtils.template(side_by_side_renderer_baseTemplatesPath, 'file-diff');
  1974. var filePathTemplate = this.hoganUtils.template(side_by_side_renderer_genericTemplatesPath, 'file-path');
  1975. var fileIconTemplate = this.hoganUtils.template(side_by_side_renderer_iconsBaseTemplatesPath, 'file');
  1976. var fileTagTemplate = this.hoganUtils.template(side_by_side_renderer_tagsBaseTemplatesPath, getFileIcon(file));
  1977. return fileDiffTemplate.render({
  1978. file: file,
  1979. fileHtmlId: getHtmlId(file),
  1980. diffs: diffs,
  1981. filePath: filePathTemplate.render({
  1982. fileDiffName: filenameDiff(file),
  1983. }, {
  1984. fileIcon: fileIconTemplate,
  1985. fileTag: fileTagTemplate,
  1986. }),
  1987. });
  1988. };
  1989. SideBySideRenderer.prototype.generateEmptyDiff = function () {
  1990. return {
  1991. right: '',
  1992. left: this.hoganUtils.render(side_by_side_renderer_genericTemplatesPath, 'empty-diff', {
  1993. contentClass: 'd2h-code-side-line',
  1994. CSSLineClass: CSSLineClass,
  1995. }),
  1996. };
  1997. };
  1998. SideBySideRenderer.prototype.generateFileHtml = function (file) {
  1999. var _this = this;
  2000. var matcher = newMatcherFn(newDistanceFn(function (e) { return deconstructLine(e.content, file.isCombined).content; }));
  2001. return file.blocks
  2002. .map(function (block) {
  2003. var fileHtml = {
  2004. left: _this.makeHeaderHtml(block.header),
  2005. right: _this.makeHeaderHtml(''),
  2006. };
  2007. _this.applyLineGroupping(block).forEach(function (_a) {
  2008. var contextLines = _a[0], oldLines = _a[1], newLines = _a[2];
  2009. if (oldLines.length && newLines.length && !contextLines.length) {
  2010. _this.applyRematchMatching(oldLines, newLines, matcher).map(function (_a) {
  2011. var oldLines = _a[0], newLines = _a[1];
  2012. var _b = _this.processChangedLines(file.isCombined, oldLines, newLines), left = _b.left, right = _b.right;
  2013. fileHtml.left += left;
  2014. fileHtml.right += right;
  2015. });
  2016. }
  2017. else if (contextLines.length) {
  2018. contextLines.forEach(function (line) {
  2019. var _a = deconstructLine(line.content, file.isCombined), prefix = _a.prefix, content = _a.content;
  2020. var _b = _this.generateLineHtml({
  2021. type: CSSLineClass.CONTEXT,
  2022. prefix: prefix,
  2023. content: content,
  2024. number: line.oldNumber,
  2025. }, {
  2026. type: CSSLineClass.CONTEXT,
  2027. prefix: prefix,
  2028. content: content,
  2029. number: line.newNumber,
  2030. }), left = _b.left, right = _b.right;
  2031. fileHtml.left += left;
  2032. fileHtml.right += right;
  2033. });
  2034. }
  2035. else if (oldLines.length || newLines.length) {
  2036. var _b = _this.processChangedLines(file.isCombined, oldLines, newLines), left = _b.left, right = _b.right;
  2037. fileHtml.left += left;
  2038. fileHtml.right += right;
  2039. }
  2040. else {
  2041. console.error('Unknown state reached while processing groups of lines', contextLines, oldLines, newLines);
  2042. }
  2043. });
  2044. return fileHtml;
  2045. })
  2046. .reduce(function (accomulated, html) {
  2047. return { left: accomulated.left + html.left, right: accomulated.right + html.right };
  2048. }, { left: '', right: '' });
  2049. };
  2050. SideBySideRenderer.prototype.applyLineGroupping = function (block) {
  2051. var blockLinesGroups = [];
  2052. var oldLines = [];
  2053. var newLines = [];
  2054. for (var i = 0; i < block.lines.length; i++) {
  2055. var diffLine = block.lines[i];
  2056. if ((diffLine.type !== LineType.INSERT && newLines.length) ||
  2057. (diffLine.type === LineType.CONTEXT && oldLines.length > 0)) {
  2058. blockLinesGroups.push([[], oldLines, newLines]);
  2059. oldLines = [];
  2060. newLines = [];
  2061. }
  2062. if (diffLine.type === LineType.CONTEXT) {
  2063. blockLinesGroups.push([[diffLine], [], []]);
  2064. }
  2065. else if (diffLine.type === LineType.INSERT && oldLines.length === 0) {
  2066. blockLinesGroups.push([[], [], [diffLine]]);
  2067. }
  2068. else if (diffLine.type === LineType.INSERT && oldLines.length > 0) {
  2069. newLines.push(diffLine);
  2070. }
  2071. else if (diffLine.type === LineType.DELETE) {
  2072. oldLines.push(diffLine);
  2073. }
  2074. }
  2075. if (oldLines.length || newLines.length) {
  2076. blockLinesGroups.push([[], oldLines, newLines]);
  2077. oldLines = [];
  2078. newLines = [];
  2079. }
  2080. return blockLinesGroups;
  2081. };
  2082. SideBySideRenderer.prototype.applyRematchMatching = function (oldLines, newLines, matcher) {
  2083. var comparisons = oldLines.length * newLines.length;
  2084. var maxLineSizeInBlock = Math.max.apply(null, [0].concat(oldLines.concat(newLines).map(function (elem) { return elem.content.length; })));
  2085. var doMatching = comparisons < this.config.matchingMaxComparisons &&
  2086. maxLineSizeInBlock < this.config.maxLineSizeInBlockForComparison &&
  2087. (this.config.matching === 'lines' || this.config.matching === 'words');
  2088. return doMatching ? matcher(oldLines, newLines) : [[oldLines, newLines]];
  2089. };
  2090. SideBySideRenderer.prototype.makeHeaderHtml = function (blockHeader) {
  2091. return this.hoganUtils.render(side_by_side_renderer_genericTemplatesPath, 'block-header', {
  2092. CSSLineClass: CSSLineClass,
  2093. blockHeader: blockHeader,
  2094. lineClass: 'd2h-code-side-linenumber',
  2095. contentClass: 'd2h-code-side-line',
  2096. });
  2097. };
  2098. SideBySideRenderer.prototype.processChangedLines = function (isCombined, oldLines, newLines) {
  2099. var fileHtml = {
  2100. right: '',
  2101. left: '',
  2102. };
  2103. var maxLinesNumber = Math.max(oldLines.length, newLines.length);
  2104. for (var i = 0; i < maxLinesNumber; i++) {
  2105. var oldLine = oldLines[i];
  2106. var newLine = newLines[i];
  2107. var diff = oldLine !== undefined && newLine !== undefined
  2108. ? diffHighlight(oldLine.content, newLine.content, isCombined, this.config)
  2109. : undefined;
  2110. var preparedOldLine = oldLine !== undefined && oldLine.oldNumber !== undefined
  2111. ? side_by_side_renderer_assign(side_by_side_renderer_assign({}, (diff !== undefined
  2112. ? {
  2113. prefix: diff.oldLine.prefix,
  2114. content: diff.oldLine.content,
  2115. type: CSSLineClass.DELETE_CHANGES,
  2116. }
  2117. : side_by_side_renderer_assign(side_by_side_renderer_assign({}, deconstructLine(oldLine.content, isCombined)), { type: toCSSClass(oldLine.type) }))), { number: oldLine.oldNumber }) : undefined;
  2118. var preparedNewLine = newLine !== undefined && newLine.newNumber !== undefined
  2119. ? side_by_side_renderer_assign(side_by_side_renderer_assign({}, (diff !== undefined
  2120. ? {
  2121. prefix: diff.newLine.prefix,
  2122. content: diff.newLine.content,
  2123. type: CSSLineClass.INSERT_CHANGES,
  2124. }
  2125. : side_by_side_renderer_assign(side_by_side_renderer_assign({}, deconstructLine(newLine.content, isCombined)), { type: toCSSClass(newLine.type) }))), { number: newLine.newNumber }) : undefined;
  2126. var _a = this.generateLineHtml(preparedOldLine, preparedNewLine), left = _a.left, right = _a.right;
  2127. fileHtml.left += left;
  2128. fileHtml.right += right;
  2129. }
  2130. return fileHtml;
  2131. };
  2132. SideBySideRenderer.prototype.generateLineHtml = function (oldLine, newLine) {
  2133. return {
  2134. left: this.generateSingleHtml(oldLine),
  2135. right: this.generateSingleHtml(newLine),
  2136. };
  2137. };
  2138. SideBySideRenderer.prototype.generateSingleHtml = function (line) {
  2139. var lineClass = 'd2h-code-side-linenumber';
  2140. var contentClass = 'd2h-code-side-line';
  2141. return this.hoganUtils.render(side_by_side_renderer_genericTemplatesPath, 'line', {
  2142. type: (line === null || line === void 0 ? void 0 : line.type) || CSSLineClass.CONTEXT + " d2h-emptyplaceholder",
  2143. lineClass: line !== undefined ? lineClass : lineClass + " d2h-code-side-emptyplaceholder",
  2144. contentClass: line !== undefined ? contentClass : contentClass + " d2h-code-side-emptyplaceholder",
  2145. prefix: (line === null || line === void 0 ? void 0 : line.prefix) === ' ' ? '&nbsp;' : line === null || line === void 0 ? void 0 : line.prefix,
  2146. content: line === null || line === void 0 ? void 0 : line.content,
  2147. lineNumber: line === null || line === void 0 ? void 0 : line.number,
  2148. });
  2149. };
  2150. return SideBySideRenderer;
  2151. }());
  2152. /* harmony default export */ var side_by_side_renderer = (side_by_side_renderer_SideBySideRenderer);
  2153. //# sourceMappingURL=side-by-side-renderer.js.map
  2154. // EXTERNAL MODULE: ./node_modules/hogan.js/lib/hogan.js
  2155. var hogan = __webpack_require__("Ruv9");
  2156.  
  2157. // CONCATENATED MODULE: ./node_modules/diff2html/lib-esm/diff2html-templates.js
  2158.  
  2159. var defaultTemplates = {};
  2160. defaultTemplates["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(t.rp("<fileIcon0", c, p, " ")); 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: {} });
  2161. defaultTemplates["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: {} });
  2162. defaultTemplates["generic-block-header"] = 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("CSSLineClass.INFO", c, p, 0))); t.b("\"></td>"); t.b("\n" + i); t.b(" <td class=\""); t.b(t.v(t.d("CSSLineClass.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("CSSLineClass.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: {} });
  2163. defaultTemplates["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("CSSLineClass.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("CSSLineClass.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: {} });
  2164. defaultTemplates["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(t.rp("<fileIcon0", c, p, " ")); 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: {} });
  2165. defaultTemplates["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, "{{ }}")) {
  2166. 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); });
  2167. c.pop();
  2168. } if (!t.s(t.f("prefix", c, p, 1), c, p, 1, 0, 0, "")) {
  2169. t.b(" <span class=\"d2h-code-line-prefix\">&nbsp;</span>");
  2170. t.b("\n" + i);
  2171. } ; if (t.s(t.f("content", c, p, 1), c, p, 0, 380, 454, "{{ }}")) {
  2172. 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); });
  2173. c.pop();
  2174. } if (!t.s(t.f("content", c, p, 1), c, p, 1, 0, 0, "")) {
  2175. t.b(" <span class=\"d2h-code-line-ctn\"><br></span>");
  2176. t.b("\n" + i);
  2177. } ; t.b(" </div>"); t.b("\n" + i); t.b(" </td>"); t.b("\n" + i); t.b("</tr>"); return t.fl(); }, partials: {}, subs: {} });
  2178. defaultTemplates["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: {} });
  2179. defaultTemplates["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: {} });
  2180. defaultTemplates["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: {} });
  2181. defaultTemplates["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: {} });
  2182. defaultTemplates["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: {} });
  2183. defaultTemplates["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: {} });
  2184. defaultTemplates["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: {} });
  2185. defaultTemplates["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: {} });
  2186. defaultTemplates["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: {} });
  2187. defaultTemplates["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: {} });
  2188. defaultTemplates["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: {} });
  2189. defaultTemplates["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: {} });
  2190. defaultTemplates["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: {} });
  2191. //# sourceMappingURL=diff2html-templates.js.map
  2192. // CONCATENATED MODULE: ./node_modules/diff2html/lib-esm/hoganjs-utils.js
  2193. var hoganjs_utils_assign = (undefined && undefined.__assign) || function () {
  2194. hoganjs_utils_assign = Object.assign || function(t) {
  2195. for (var s, i = 1, n = arguments.length; i < n; i++) {
  2196. s = arguments[i];
  2197. for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
  2198. t[p] = s[p];
  2199. }
  2200. return t;
  2201. };
  2202. return hoganjs_utils_assign.apply(this, arguments);
  2203. };
  2204.  
  2205.  
  2206. var hoganjs_utils_HoganJsUtils = (function () {
  2207. function HoganJsUtils(_a) {
  2208. var _b = _a.compiledTemplates, compiledTemplates = _b === void 0 ? {} : _b, _c = _a.rawTemplates, rawTemplates = _c === void 0 ? {} : _c;
  2209. var compiledRawTemplates = Object.entries(rawTemplates).reduce(function (previousTemplates, _a) {
  2210. var _b;
  2211. var name = _a[0], templateString = _a[1];
  2212. var compiledTemplate = hogan["compile"](templateString, { asString: false });
  2213. return hoganjs_utils_assign(hoganjs_utils_assign({}, previousTemplates), (_b = {}, _b[name] = compiledTemplate, _b));
  2214. }, {});
  2215. this.preCompiledTemplates = hoganjs_utils_assign(hoganjs_utils_assign(hoganjs_utils_assign({}, defaultTemplates), compiledTemplates), compiledRawTemplates);
  2216. }
  2217. HoganJsUtils.compile = function (templateString) {
  2218. return hogan["compile"](templateString, { asString: false });
  2219. };
  2220. HoganJsUtils.prototype.render = function (namespace, view, params, partials, indent) {
  2221. var templateKey = this.templateKey(namespace, view);
  2222. try {
  2223. var template = this.preCompiledTemplates[templateKey];
  2224. return template.render(params, partials, indent);
  2225. }
  2226. catch (e) {
  2227. throw new Error("Could not find template to render '" + templateKey + "'");
  2228. }
  2229. };
  2230. HoganJsUtils.prototype.template = function (namespace, view) {
  2231. return this.preCompiledTemplates[this.templateKey(namespace, view)];
  2232. };
  2233. HoganJsUtils.prototype.templateKey = function (namespace, view) {
  2234. return namespace + "-" + view;
  2235. };
  2236. return HoganJsUtils;
  2237. }());
  2238. /* harmony default export */ var hoganjs_utils = (hoganjs_utils_HoganJsUtils);
  2239. //# sourceMappingURL=hoganjs-utils.js.map
  2240. // CONCATENATED MODULE: ./node_modules/diff2html/lib-esm/diff2html.js
  2241. var diff2html_assign = (undefined && undefined.__assign) || function () {
  2242. diff2html_assign = Object.assign || function(t) {
  2243. for (var s, i = 1, n = arguments.length; i < n; i++) {
  2244. s = arguments[i];
  2245. for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
  2246. t[p] = s[p];
  2247. }
  2248. return t;
  2249. };
  2250. return diff2html_assign.apply(this, arguments);
  2251. };
  2252.  
  2253.  
  2254.  
  2255.  
  2256.  
  2257.  
  2258. var defaultDiff2HtmlConfig = diff2html_assign(diff2html_assign(diff2html_assign({}, defaultLineByLineRendererConfig), defaultSideBySideRendererConfig), { outputFormat: OutputFormatType.LINE_BY_LINE, drawFileList: true });
  2259. function diff2html_parse(diffInput, configuration) {
  2260. if (configuration === void 0) { configuration = {}; }
  2261. return parse(diffInput, diff2html_assign(diff2html_assign({}, defaultDiff2HtmlConfig), configuration));
  2262. }
  2263. function diff2html_html(diffInput, configuration) {
  2264. if (configuration === void 0) { configuration = {}; }
  2265. var config = diff2html_assign(diff2html_assign({}, defaultDiff2HtmlConfig), configuration);
  2266. var diffJson = typeof diffInput === 'string' ? parse(diffInput, config) : diffInput;
  2267. var hoganUtils = new hoganjs_utils(config);
  2268. var fileList = config.drawFileList ? render(diffJson, hoganUtils) : '';
  2269. var diffOutput = config.outputFormat === 'side-by-side'
  2270. ? new side_by_side_renderer(hoganUtils, config).render(diffJson)
  2271. : new line_by_line_renderer(hoganUtils, config).render(diffJson);
  2272. return fileList + diffOutput;
  2273. }
  2274. //# sourceMappingURL=diff2html.js.map
  2275. // CONCATENATED MODULE: ./src/js/ui.ts
  2276.  
  2277.  
  2278. function ui_render(diff) {
  2279. // @ts-ignore https://github.com/rtfpessoa/diff2html/issues/320
  2280. return diff2html_html(diff);
  2281. }
  2282. function show(html) {
  2283. external_$_('#show-trim21-cn').html(html);
  2284. }
  2285. function clear() {
  2286. external_$_('#show-trim21-cn').html('');
  2287. }
  2288.  
  2289. // CONCATENATED MODULE: ./src/js/compare.ts
  2290.  
  2291.  
  2292.  
  2293.  
  2294.  
  2295. function compare(revID1, revID2) {
  2296. clear();
  2297. show('<h2>loading versions...</h2>');
  2298. const rev1 = getRevInfo(revID1);
  2299. const rev2 = getRevInfo(revID2);
  2300. const p1 = request(rev1.url);
  2301. const p2 = request(rev2.url);
  2302. Promise.all([p1, p2]).then(values => {
  2303. const contents = [];
  2304. for (const page of values) {
  2305. contents.push(parseRevDetails(page.responseText));
  2306. }
  2307. const c1 = new Comment(rev1, contents[0]);
  2308. const c2 = new Comment(rev2, contents[1]);
  2309. const d = differ_diff(c1, c2);
  2310. const rendered = ui_render(d);
  2311. show(rendered);
  2312. }).catch(() => {
  2313. show('<h2 style="color:red">loading versions error</h2>');
  2314. });
  2315. }
  2316.  
  2317. // CONCATENATED MODULE: ./src/js/index.js
  2318.  
  2319.  
  2320.  
  2321.  
  2322. function main () {
  2323. console.log('start bgm wiki rev differ UserScript')
  2324. initUI()
  2325. }
  2326.  
  2327. function initUI () {
  2328. external_$_('#columnInSubjectA').prepend('<div id=show-trim21-cn></dev>')
  2329. external_$_('#pagehistory li').each(function () {
  2330. const el = external_$_(this)
  2331. const rev = parseRevEl(el)
  2332. el.prepend(`<input type="checkbox" class="rev-trim21-cn" name="rev" label="select to compare" value="${rev.id}">`)
  2333. })
  2334. external_$_('#columnInSubjectA span.text').append('<a href="#;" id="compare-trim21-cn" tar class="l"> > 比较选中的版本</a>')
  2335. external_$_('#compare-trim21-cn').on('click', function () {
  2336. const selectedRevs = getSelectedVersion()
  2337. compare(selectedRevs[0], selectedRevs[1])
  2338. })
  2339. external_$_('head').append('<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/diff2html/bundles/css/diff2html.min.css" />')
  2340. }
  2341.  
  2342. function getSelectedVersion () {
  2343. const selectedVersion = []
  2344. const selectedRev = external_$_('.rev-trim21-cn:checked')
  2345. if (selectedRev.length < 2) {
  2346. window.alert('请选中两个版本进行比较')
  2347. }
  2348. if (selectedRev.length > 2) {
  2349. window.alert('只能比较两个版本')
  2350. }
  2351. selectedRev.each(function () {
  2352. const el = external_$_(this)
  2353. selectedVersion.push(el.val())
  2354. })
  2355. selectedVersion.reverse()
  2356. return selectedVersion
  2357. }
  2358.  
  2359. main()
  2360.  
  2361.  
  2362. /***/ }),
  2363.  
  2364. /***/ "v2jn":
  2365. /***/ (function(module, exports, __webpack_require__) {
  2366.  
  2367. /*!
  2368.  
  2369. diff v4.0.1
  2370.  
  2371. Software License Agreement (BSD License)
  2372.  
  2373. Copyright (c) 2009-2015, Kevin Decker <kpdecker@gmail.com>
  2374.  
  2375. All rights reserved.
  2376.  
  2377. Redistribution and use of this software in source and binary forms, with or without modification,
  2378. are permitted provided that the following conditions are met:
  2379.  
  2380. * Redistributions of source code must retain the above
  2381. copyright notice, this list of conditions and the
  2382. following disclaimer.
  2383.  
  2384. * Redistributions in binary form must reproduce the above
  2385. copyright notice, this list of conditions and the
  2386. following disclaimer in the documentation and/or other
  2387. materials provided with the distribution.
  2388.  
  2389. * Neither the name of Kevin Decker nor the names of its
  2390. contributors may be used to endorse or promote products
  2391. derived from this software without specific prior
  2392. written permission.
  2393.  
  2394. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
  2395. IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
  2396. FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  2397. CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  2398. DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  2399. DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
  2400. IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  2401. OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  2402. @license
  2403. */
  2404. (function (global, factory) {
  2405. true ? factory(exports) :
  2406. undefined;
  2407. }(this, function (exports) { 'use strict';
  2408.  
  2409. function Diff() {}
  2410. Diff.prototype = {
  2411. diff: function diff(oldString, newString) {
  2412. var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
  2413. var callback = options.callback;
  2414.  
  2415. if (typeof options === 'function') {
  2416. callback = options;
  2417. options = {};
  2418. }
  2419.  
  2420. this.options = options;
  2421. var self = this;
  2422.  
  2423. function done(value) {
  2424. if (callback) {
  2425. setTimeout(function () {
  2426. callback(undefined, value);
  2427. }, 0);
  2428. return true;
  2429. } else {
  2430. return value;
  2431. }
  2432. } // Allow subclasses to massage the input prior to running
  2433.  
  2434.  
  2435. oldString = this.castInput(oldString);
  2436. newString = this.castInput(newString);
  2437. oldString = this.removeEmpty(this.tokenize(oldString));
  2438. newString = this.removeEmpty(this.tokenize(newString));
  2439. var newLen = newString.length,
  2440. oldLen = oldString.length;
  2441. var editLength = 1;
  2442. var maxEditLength = newLen + oldLen;
  2443. var bestPath = [{
  2444. newPos: -1,
  2445. components: []
  2446. }]; // Seed editLength = 0, i.e. the content starts with the same values
  2447.  
  2448. var oldPos = this.extractCommon(bestPath[0], newString, oldString, 0);
  2449.  
  2450. if (bestPath[0].newPos + 1 >= newLen && oldPos + 1 >= oldLen) {
  2451. // Identity per the equality and tokenizer
  2452. return done([{
  2453. value: this.join(newString),
  2454. count: newString.length
  2455. }]);
  2456. } // Main worker method. checks all permutations of a given edit length for acceptance.
  2457.  
  2458.  
  2459. function execEditLength() {
  2460. for (var diagonalPath = -1 * editLength; diagonalPath <= editLength; diagonalPath += 2) {
  2461. var basePath = void 0;
  2462.  
  2463. var addPath = bestPath[diagonalPath - 1],
  2464. removePath = bestPath[diagonalPath + 1],
  2465. _oldPos = (removePath ? removePath.newPos : 0) - diagonalPath;
  2466.  
  2467. if (addPath) {
  2468. // No one else is going to attempt to use this value, clear it
  2469. bestPath[diagonalPath - 1] = undefined;
  2470. }
  2471.  
  2472. var canAdd = addPath && addPath.newPos + 1 < newLen,
  2473. canRemove = removePath && 0 <= _oldPos && _oldPos < oldLen;
  2474.  
  2475. if (!canAdd && !canRemove) {
  2476. // If this path is a terminal then prune
  2477. bestPath[diagonalPath] = undefined;
  2478. continue;
  2479. } // Select the diagonal that we want to branch from. We select the prior
  2480. // path whose position in the new string is the farthest from the origin
  2481. // and does not pass the bounds of the diff graph
  2482.  
  2483.  
  2484. if (!canAdd || canRemove && addPath.newPos < removePath.newPos) {
  2485. basePath = clonePath(removePath);
  2486. self.pushComponent(basePath.components, undefined, true);
  2487. } else {
  2488. basePath = addPath; // No need to clone, we've pulled it from the list
  2489.  
  2490. basePath.newPos++;
  2491. self.pushComponent(basePath.components, true, undefined);
  2492. }
  2493.  
  2494. _oldPos = self.extractCommon(basePath, newString, oldString, diagonalPath); // If we have hit the end of both strings, then we are done
  2495.  
  2496. if (basePath.newPos + 1 >= newLen && _oldPos + 1 >= oldLen) {
  2497. return done(buildValues(self, basePath.components, newString, oldString, self.useLongestToken));
  2498. } else {
  2499. // Otherwise track this path as a potential candidate and continue.
  2500. bestPath[diagonalPath] = basePath;
  2501. }
  2502. }
  2503.  
  2504. editLength++;
  2505. } // Performs the length of edit iteration. Is a bit fugly as this has to support the
  2506. // sync and async mode which is never fun. Loops over execEditLength until a value
  2507. // is produced.
  2508.  
  2509.  
  2510. if (callback) {
  2511. (function exec() {
  2512. setTimeout(function () {
  2513. // This should not happen, but we want to be safe.
  2514.  
  2515. /* istanbul ignore next */
  2516. if (editLength > maxEditLength) {
  2517. return callback();
  2518. }
  2519.  
  2520. if (!execEditLength()) {
  2521. exec();
  2522. }
  2523. }, 0);
  2524. })();
  2525. } else {
  2526. while (editLength <= maxEditLength) {
  2527. var ret = execEditLength();
  2528.  
  2529. if (ret) {
  2530. return ret;
  2531. }
  2532. }
  2533. }
  2534. },
  2535. pushComponent: function pushComponent(components, added, removed) {
  2536. var last = components[components.length - 1];
  2537.  
  2538. if (last && last.added === added && last.removed === removed) {
  2539. // We need to clone here as the component clone operation is just
  2540. // as shallow array clone
  2541. components[components.length - 1] = {
  2542. count: last.count + 1,
  2543. added: added,
  2544. removed: removed
  2545. };
  2546. } else {
  2547. components.push({
  2548. count: 1,
  2549. added: added,
  2550. removed: removed
  2551. });
  2552. }
  2553. },
  2554. extractCommon: function extractCommon(basePath, newString, oldString, diagonalPath) {
  2555. var newLen = newString.length,
  2556. oldLen = oldString.length,
  2557. newPos = basePath.newPos,
  2558. oldPos = newPos - diagonalPath,
  2559. commonCount = 0;
  2560.  
  2561. while (newPos + 1 < newLen && oldPos + 1 < oldLen && this.equals(newString[newPos + 1], oldString[oldPos + 1])) {
  2562. newPos++;
  2563. oldPos++;
  2564. commonCount++;
  2565. }
  2566.  
  2567. if (commonCount) {
  2568. basePath.components.push({
  2569. count: commonCount
  2570. });
  2571. }
  2572.  
  2573. basePath.newPos = newPos;
  2574. return oldPos;
  2575. },
  2576. equals: function equals(left, right) {
  2577. if (this.options.comparator) {
  2578. return this.options.comparator(left, right);
  2579. } else {
  2580. return left === right || this.options.ignoreCase && left.toLowerCase() === right.toLowerCase();
  2581. }
  2582. },
  2583. removeEmpty: function removeEmpty(array) {
  2584. var ret = [];
  2585.  
  2586. for (var i = 0; i < array.length; i++) {
  2587. if (array[i]) {
  2588. ret.push(array[i]);
  2589. }
  2590. }
  2591.  
  2592. return ret;
  2593. },
  2594. castInput: function castInput(value) {
  2595. return value;
  2596. },
  2597. tokenize: function tokenize(value) {
  2598. return value.split('');
  2599. },
  2600. join: function join(chars) {
  2601. return chars.join('');
  2602. }
  2603. };
  2604.  
  2605. function buildValues(diff, components, newString, oldString, useLongestToken) {
  2606. var componentPos = 0,
  2607. componentLen = components.length,
  2608. newPos = 0,
  2609. oldPos = 0;
  2610.  
  2611. for (; componentPos < componentLen; componentPos++) {
  2612. var component = components[componentPos];
  2613.  
  2614. if (!component.removed) {
  2615. if (!component.added && useLongestToken) {
  2616. var value = newString.slice(newPos, newPos + component.count);
  2617. value = value.map(function (value, i) {
  2618. var oldValue = oldString[oldPos + i];
  2619. return oldValue.length > value.length ? oldValue : value;
  2620. });
  2621. component.value = diff.join(value);
  2622. } else {
  2623. component.value = diff.join(newString.slice(newPos, newPos + component.count));
  2624. }
  2625.  
  2626. newPos += component.count; // Common case
  2627.  
  2628. if (!component.added) {
  2629. oldPos += component.count;
  2630. }
  2631. } else {
  2632. component.value = diff.join(oldString.slice(oldPos, oldPos + component.count));
  2633. oldPos += component.count; // Reverse add and remove so removes are output first to match common convention
  2634. // The diffing algorithm is tied to add then remove output and this is the simplest
  2635. // route to get the desired output with minimal overhead.
  2636.  
  2637. if (componentPos && components[componentPos - 1].added) {
  2638. var tmp = components[componentPos - 1];
  2639. components[componentPos - 1] = components[componentPos];
  2640. components[componentPos] = tmp;
  2641. }
  2642. }
  2643. } // Special case handle for when one terminal is ignored (i.e. whitespace).
  2644. // For this case we merge the terminal into the prior string and drop the change.
  2645. // This is only available for string mode.
  2646.  
  2647.  
  2648. var lastComponent = components[componentLen - 1];
  2649.  
  2650. if (componentLen > 1 && typeof lastComponent.value === 'string' && (lastComponent.added || lastComponent.removed) && diff.equals('', lastComponent.value)) {
  2651. components[componentLen - 2].value += lastComponent.value;
  2652. components.pop();
  2653. }
  2654.  
  2655. return components;
  2656. }
  2657.  
  2658. function clonePath(path) {
  2659. return {
  2660. newPos: path.newPos,
  2661. components: path.components.slice(0)
  2662. };
  2663. }
  2664.  
  2665. var characterDiff = new Diff();
  2666. function diffChars(oldStr, newStr, options) {
  2667. return characterDiff.diff(oldStr, newStr, options);
  2668. }
  2669.  
  2670. function generateOptions(options, defaults) {
  2671. if (typeof options === 'function') {
  2672. defaults.callback = options;
  2673. } else if (options) {
  2674. for (var name in options) {
  2675. /* istanbul ignore else */
  2676. if (options.hasOwnProperty(name)) {
  2677. defaults[name] = options[name];
  2678. }
  2679. }
  2680. }
  2681.  
  2682. return defaults;
  2683. }
  2684.  
  2685. //
  2686. // Ranges and exceptions:
  2687. // Latin-1 Supplement, 0080–00FF
  2688. // - U+00D7 × Multiplication sign
  2689. // - U+00F7 ÷ Division sign
  2690. // Latin Extended-A, 0100–017F
  2691. // Latin Extended-B, 0180–024F
  2692. // IPA Extensions, 0250–02AF
  2693. // Spacing Modifier Letters, 02B0–02FF
  2694. // - U+02C7 ˇ &#711; Caron
  2695. // - U+02D8 ˘ &#728; Breve
  2696. // - U+02D9 ˙ &#729; Dot Above
  2697. // - U+02DA ˚ &#730; Ring Above
  2698. // - U+02DB ˛ &#731; Ogonek
  2699. // - U+02DC ˜ &#732; Small Tilde
  2700. // - U+02DD ˝ &#733; Double Acute Accent
  2701. // Latin Extended Additional, 1E00–1EFF
  2702.  
  2703. var extendedWordChars = /^[A-Za-z\xC0-\u02C6\u02C8-\u02D7\u02DE-\u02FF\u1E00-\u1EFF]+$/;
  2704. var reWhitespace = /\S/;
  2705. var wordDiff = new Diff();
  2706.  
  2707. wordDiff.equals = function (left, right) {
  2708. if (this.options.ignoreCase) {
  2709. left = left.toLowerCase();
  2710. right = right.toLowerCase();
  2711. }
  2712.  
  2713. return left === right || this.options.ignoreWhitespace && !reWhitespace.test(left) && !reWhitespace.test(right);
  2714. };
  2715.  
  2716. wordDiff.tokenize = function (value) {
  2717. 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.
  2718.  
  2719. for (var i = 0; i < tokens.length - 1; i++) {
  2720. // If we have an empty string in the next field and we have only word chars before and after, merge
  2721. if (!tokens[i + 1] && tokens[i + 2] && extendedWordChars.test(tokens[i]) && extendedWordChars.test(tokens[i + 2])) {
  2722. tokens[i] += tokens[i + 2];
  2723. tokens.splice(i + 1, 2);
  2724. i--;
  2725. }
  2726. }
  2727.  
  2728. return tokens;
  2729. };
  2730.  
  2731. function diffWords(oldStr, newStr, options) {
  2732. options = generateOptions(options, {
  2733. ignoreWhitespace: true
  2734. });
  2735. return wordDiff.diff(oldStr, newStr, options);
  2736. }
  2737. function diffWordsWithSpace(oldStr, newStr, options) {
  2738. return wordDiff.diff(oldStr, newStr, options);
  2739. }
  2740.  
  2741. var lineDiff = new Diff();
  2742.  
  2743. lineDiff.tokenize = function (value) {
  2744. var retLines = [],
  2745. linesAndNewlines = value.split(/(\n|\r\n)/); // Ignore the final empty token that occurs if the string ends with a new line
  2746.  
  2747. if (!linesAndNewlines[linesAndNewlines.length - 1]) {
  2748. linesAndNewlines.pop();
  2749. } // Merge the content and line separators into single tokens
  2750.  
  2751.  
  2752. for (var i = 0; i < linesAndNewlines.length; i++) {
  2753. var line = linesAndNewlines[i];
  2754.  
  2755. if (i % 2 && !this.options.newlineIsToken) {
  2756. retLines[retLines.length - 1] += line;
  2757. } else {
  2758. if (this.options.ignoreWhitespace) {
  2759. line = line.trim();
  2760. }
  2761.  
  2762. retLines.push(line);
  2763. }
  2764. }
  2765.  
  2766. return retLines;
  2767. };
  2768.  
  2769. function diffLines(oldStr, newStr, callback) {
  2770. return lineDiff.diff(oldStr, newStr, callback);
  2771. }
  2772. function diffTrimmedLines(oldStr, newStr, callback) {
  2773. var options = generateOptions(callback, {
  2774. ignoreWhitespace: true
  2775. });
  2776. return lineDiff.diff(oldStr, newStr, options);
  2777. }
  2778.  
  2779. var sentenceDiff = new Diff();
  2780.  
  2781. sentenceDiff.tokenize = function (value) {
  2782. return value.split(/(\S.+?[.!?])(?=\s+|$)/);
  2783. };
  2784.  
  2785. function diffSentences(oldStr, newStr, callback) {
  2786. return sentenceDiff.diff(oldStr, newStr, callback);
  2787. }
  2788.  
  2789. var cssDiff = new Diff();
  2790.  
  2791. cssDiff.tokenize = function (value) {
  2792. return value.split(/([{}:;,]|\s+)/);
  2793. };
  2794.  
  2795. function diffCss(oldStr, newStr, callback) {
  2796. return cssDiff.diff(oldStr, newStr, callback);
  2797. }
  2798.  
  2799. function _typeof(obj) {
  2800. if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
  2801. _typeof = function (obj) {
  2802. return typeof obj;
  2803. };
  2804. } else {
  2805. _typeof = function (obj) {
  2806. return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
  2807. };
  2808. }
  2809.  
  2810. return _typeof(obj);
  2811. }
  2812.  
  2813. function _toConsumableArray(arr) {
  2814. return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread();
  2815. }
  2816.  
  2817. function _arrayWithoutHoles(arr) {
  2818. if (Array.isArray(arr)) {
  2819. for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) arr2[i] = arr[i];
  2820.  
  2821. return arr2;
  2822. }
  2823. }
  2824.  
  2825. function _iterableToArray(iter) {
  2826. if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter);
  2827. }
  2828.  
  2829. function _nonIterableSpread() {
  2830. throw new TypeError("Invalid attempt to spread non-iterable instance");
  2831. }
  2832.  
  2833. var objectPrototypeToString = Object.prototype.toString;
  2834. var jsonDiff = new Diff(); // Discriminate between two lines of pretty-printed, serialized JSON where one of them has a
  2835. // dangling comma and the other doesn't. Turns out including the dangling comma yields the nicest output:
  2836.  
  2837. jsonDiff.useLongestToken = true;
  2838. jsonDiff.tokenize = lineDiff.tokenize;
  2839.  
  2840. jsonDiff.castInput = function (value) {
  2841. var _this$options = this.options,
  2842. undefinedReplacement = _this$options.undefinedReplacement,
  2843. _this$options$stringi = _this$options.stringifyReplacer,
  2844. stringifyReplacer = _this$options$stringi === void 0 ? function (k, v) {
  2845. return typeof v === 'undefined' ? undefinedReplacement : v;
  2846. } : _this$options$stringi;
  2847. return typeof value === 'string' ? value : JSON.stringify(canonicalize(value, null, null, stringifyReplacer), stringifyReplacer, ' ');
  2848. };
  2849.  
  2850. jsonDiff.equals = function (left, right) {
  2851. return Diff.prototype.equals.call(jsonDiff, left.replace(/,([\r\n])/g, '$1'), right.replace(/,([\r\n])/g, '$1'));
  2852. };
  2853.  
  2854. function diffJson(oldObj, newObj, options) {
  2855. return jsonDiff.diff(oldObj, newObj, options);
  2856. } // This function handles the presence of circular references by bailing out when encountering an
  2857. // object that is already on the "stack" of items being processed. Accepts an optional replacer
  2858.  
  2859. function canonicalize(obj, stack, replacementStack, replacer, key) {
  2860. stack = stack || [];
  2861. replacementStack = replacementStack || [];
  2862.  
  2863. if (replacer) {
  2864. obj = replacer(key, obj);
  2865. }
  2866.  
  2867. var i;
  2868.  
  2869. for (i = 0; i < stack.length; i += 1) {
  2870. if (stack[i] === obj) {
  2871. return replacementStack[i];
  2872. }
  2873. }
  2874.  
  2875. var canonicalizedObj;
  2876.  
  2877. if ('[object Array]' === objectPrototypeToString.call(obj)) {
  2878. stack.push(obj);
  2879. canonicalizedObj = new Array(obj.length);
  2880. replacementStack.push(canonicalizedObj);
  2881.  
  2882. for (i = 0; i < obj.length; i += 1) {
  2883. canonicalizedObj[i] = canonicalize(obj[i], stack, replacementStack, replacer, key);
  2884. }
  2885.  
  2886. stack.pop();
  2887. replacementStack.pop();
  2888. return canonicalizedObj;
  2889. }
  2890.  
  2891. if (obj && obj.toJSON) {
  2892. obj = obj.toJSON();
  2893. }
  2894.  
  2895. if (_typeof(obj) === 'object' && obj !== null) {
  2896. stack.push(obj);
  2897. canonicalizedObj = {};
  2898. replacementStack.push(canonicalizedObj);
  2899.  
  2900. var sortedKeys = [],
  2901. _key;
  2902.  
  2903. for (_key in obj) {
  2904. /* istanbul ignore else */
  2905. if (obj.hasOwnProperty(_key)) {
  2906. sortedKeys.push(_key);
  2907. }
  2908. }
  2909.  
  2910. sortedKeys.sort();
  2911.  
  2912. for (i = 0; i < sortedKeys.length; i += 1) {
  2913. _key = sortedKeys[i];
  2914. canonicalizedObj[_key] = canonicalize(obj[_key], stack, replacementStack, replacer, _key);
  2915. }
  2916.  
  2917. stack.pop();
  2918. replacementStack.pop();
  2919. } else {
  2920. canonicalizedObj = obj;
  2921. }
  2922.  
  2923. return canonicalizedObj;
  2924. }
  2925.  
  2926. var arrayDiff = new Diff();
  2927.  
  2928. arrayDiff.tokenize = function (value) {
  2929. return value.slice();
  2930. };
  2931.  
  2932. arrayDiff.join = arrayDiff.removeEmpty = function (value) {
  2933. return value;
  2934. };
  2935.  
  2936. function diffArrays(oldArr, newArr, callback) {
  2937. return arrayDiff.diff(oldArr, newArr, callback);
  2938. }
  2939.  
  2940. function parsePatch(uniDiff) {
  2941. var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  2942. var diffstr = uniDiff.split(/\r\n|[\n\v\f\r\x85]/),
  2943. delimiters = uniDiff.match(/\r\n|[\n\v\f\r\x85]/g) || [],
  2944. list = [],
  2945. i = 0;
  2946.  
  2947. function parseIndex() {
  2948. var index = {};
  2949. list.push(index); // Parse diff metadata
  2950.  
  2951. while (i < diffstr.length) {
  2952. var line = diffstr[i]; // File header found, end parsing diff metadata
  2953.  
  2954. if (/^(\-\-\-|\+\+\+|@@)\s/.test(line)) {
  2955. break;
  2956. } // Diff index
  2957.  
  2958.  
  2959. var header = /^(?:Index:|diff(?: -r \w+)+)\s+(.+?)\s*$/.exec(line);
  2960.  
  2961. if (header) {
  2962. index.index = header[1];
  2963. }
  2964.  
  2965. i++;
  2966. } // Parse file headers if they are defined. Unified diff requires them, but
  2967. // there's no technical issues to have an isolated hunk without file header
  2968.  
  2969.  
  2970. parseFileHeader(index);
  2971. parseFileHeader(index); // Parse hunks
  2972.  
  2973. index.hunks = [];
  2974.  
  2975. while (i < diffstr.length) {
  2976. var _line = diffstr[i];
  2977.  
  2978. if (/^(Index:|diff|\-\-\-|\+\+\+)\s/.test(_line)) {
  2979. break;
  2980. } else if (/^@@/.test(_line)) {
  2981. index.hunks.push(parseHunk());
  2982. } else if (_line && options.strict) {
  2983. // Ignore unexpected content unless in strict mode
  2984. throw new Error('Unknown line ' + (i + 1) + ' ' + JSON.stringify(_line));
  2985. } else {
  2986. i++;
  2987. }
  2988. }
  2989. } // Parses the --- and +++ headers, if none are found, no lines
  2990. // are consumed.
  2991.  
  2992.  
  2993. function parseFileHeader(index) {
  2994. var fileHeader = /^(---|\+\+\+)\s+(.*)$/.exec(diffstr[i]);
  2995.  
  2996. if (fileHeader) {
  2997. var keyPrefix = fileHeader[1] === '---' ? 'old' : 'new';
  2998. var data = fileHeader[2].split('\t', 2);
  2999. var fileName = data[0].replace(/\\\\/g, '\\');
  3000.  
  3001. if (/^".*"$/.test(fileName)) {
  3002. fileName = fileName.substr(1, fileName.length - 2);
  3003. }
  3004.  
  3005. index[keyPrefix + 'FileName'] = fileName;
  3006. index[keyPrefix + 'Header'] = (data[1] || '').trim();
  3007. i++;
  3008. }
  3009. } // Parses a hunk
  3010. // This assumes that we are at the start of a hunk.
  3011.  
  3012.  
  3013. function parseHunk() {
  3014. var chunkHeaderIndex = i,
  3015. chunkHeaderLine = diffstr[i++],
  3016. chunkHeader = chunkHeaderLine.split(/@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@/);
  3017. var hunk = {
  3018. oldStart: +chunkHeader[1],
  3019. oldLines: +chunkHeader[2] || 1,
  3020. newStart: +chunkHeader[3],
  3021. newLines: +chunkHeader[4] || 1,
  3022. lines: [],
  3023. linedelimiters: []
  3024. };
  3025. var addCount = 0,
  3026. removeCount = 0;
  3027.  
  3028. for (; i < diffstr.length; i++) {
  3029. // Lines starting with '---' could be mistaken for the "remove line" operation
  3030. // But they could be the header for the next file. Therefore prune such cases out.
  3031. if (diffstr[i].indexOf('--- ') === 0 && i + 2 < diffstr.length && diffstr[i + 1].indexOf('+++ ') === 0 && diffstr[i + 2].indexOf('@@') === 0) {
  3032. break;
  3033. }
  3034.  
  3035. var operation = diffstr[i].length == 0 && i != diffstr.length - 1 ? ' ' : diffstr[i][0];
  3036.  
  3037. if (operation === '+' || operation === '-' || operation === ' ' || operation === '\\') {
  3038. hunk.lines.push(diffstr[i]);
  3039. hunk.linedelimiters.push(delimiters[i] || '\n');
  3040.  
  3041. if (operation === '+') {
  3042. addCount++;
  3043. } else if (operation === '-') {
  3044. removeCount++;
  3045. } else if (operation === ' ') {
  3046. addCount++;
  3047. removeCount++;
  3048. }
  3049. } else {
  3050. break;
  3051. }
  3052. } // Handle the empty block count case
  3053.  
  3054.  
  3055. if (!addCount && hunk.newLines === 1) {
  3056. hunk.newLines = 0;
  3057. }
  3058.  
  3059. if (!removeCount && hunk.oldLines === 1) {
  3060. hunk.oldLines = 0;
  3061. } // Perform optional sanity checking
  3062.  
  3063.  
  3064. if (options.strict) {
  3065. if (addCount !== hunk.newLines) {
  3066. throw new Error('Added line count did not match for hunk at line ' + (chunkHeaderIndex + 1));
  3067. }
  3068.  
  3069. if (removeCount !== hunk.oldLines) {
  3070. throw new Error('Removed line count did not match for hunk at line ' + (chunkHeaderIndex + 1));
  3071. }
  3072. }
  3073.  
  3074. return hunk;
  3075. }
  3076.  
  3077. while (i < diffstr.length) {
  3078. parseIndex();
  3079. }
  3080.  
  3081. return list;
  3082. }
  3083.  
  3084. // Iterator that traverses in the range of [min, max], stepping
  3085. // by distance from a given start position. I.e. for [0, 4], with
  3086. // start of 2, this will iterate 2, 3, 1, 4, 0.
  3087. function distanceIterator (start, minLine, maxLine) {
  3088. var wantForward = true,
  3089. backwardExhausted = false,
  3090. forwardExhausted = false,
  3091. localOffset = 1;
  3092. return function iterator() {
  3093. if (wantForward && !forwardExhausted) {
  3094. if (backwardExhausted) {
  3095. localOffset++;
  3096. } else {
  3097. wantForward = false;
  3098. } // Check if trying to fit beyond text length, and if not, check it fits
  3099. // after offset location (or desired location on first iteration)
  3100.  
  3101.  
  3102. if (start + localOffset <= maxLine) {
  3103. return localOffset;
  3104. }
  3105.  
  3106. forwardExhausted = true;
  3107. }
  3108.  
  3109. if (!backwardExhausted) {
  3110. if (!forwardExhausted) {
  3111. wantForward = true;
  3112. } // Check if trying to fit before text beginning, and if not, check it fits
  3113. // before offset location
  3114.  
  3115.  
  3116. if (minLine <= start - localOffset) {
  3117. return -localOffset++;
  3118. }
  3119.  
  3120. backwardExhausted = true;
  3121. return iterator();
  3122. } // We tried to fit hunk before text beginning and beyond text length, then
  3123. // hunk can't fit on the text. Return undefined
  3124.  
  3125. };
  3126. }
  3127.  
  3128. function applyPatch(source, uniDiff) {
  3129. var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
  3130.  
  3131. if (typeof uniDiff === 'string') {
  3132. uniDiff = parsePatch(uniDiff);
  3133. }
  3134.  
  3135. if (Array.isArray(uniDiff)) {
  3136. if (uniDiff.length > 1) {
  3137. throw new Error('applyPatch only works with a single input.');
  3138. }
  3139.  
  3140. uniDiff = uniDiff[0];
  3141. } // Apply the diff to the input
  3142.  
  3143.  
  3144. var lines = source.split(/\r\n|[\n\v\f\r\x85]/),
  3145. delimiters = source.match(/\r\n|[\n\v\f\r\x85]/g) || [],
  3146. hunks = uniDiff.hunks,
  3147. compareLine = options.compareLine || function (lineNumber, line, operation, patchContent) {
  3148. return line === patchContent;
  3149. },
  3150. errorCount = 0,
  3151. fuzzFactor = options.fuzzFactor || 0,
  3152. minLine = 0,
  3153. offset = 0,
  3154. removeEOFNL,
  3155. addEOFNL;
  3156. /**
  3157. * Checks if the hunk exactly fits on the provided location
  3158. */
  3159.  
  3160.  
  3161. function hunkFits(hunk, toPos) {
  3162. for (var j = 0; j < hunk.lines.length; j++) {
  3163. var line = hunk.lines[j],
  3164. operation = line.length > 0 ? line[0] : ' ',
  3165. content = line.length > 0 ? line.substr(1) : line;
  3166.  
  3167. if (operation === ' ' || operation === '-') {
  3168. // Context sanity check
  3169. if (!compareLine(toPos + 1, lines[toPos], operation, content)) {
  3170. errorCount++;
  3171.  
  3172. if (errorCount > fuzzFactor) {
  3173. return false;
  3174. }
  3175. }
  3176.  
  3177. toPos++;
  3178. }
  3179. }
  3180.  
  3181. return true;
  3182. } // Search best fit offsets for each hunk based on the previous ones
  3183.  
  3184.  
  3185. for (var i = 0; i < hunks.length; i++) {
  3186. var hunk = hunks[i],
  3187. maxLine = lines.length - hunk.oldLines,
  3188. localOffset = 0,
  3189. toPos = offset + hunk.oldStart - 1;
  3190. var iterator = distanceIterator(toPos, minLine, maxLine);
  3191.  
  3192. for (; localOffset !== undefined; localOffset = iterator()) {
  3193. if (hunkFits(hunk, toPos + localOffset)) {
  3194. hunk.offset = offset += localOffset;
  3195. break;
  3196. }
  3197. }
  3198.  
  3199. if (localOffset === undefined) {
  3200. return false;
  3201. } // Set lower text limit to end of the current hunk, so next ones don't try
  3202. // to fit over already patched text
  3203.  
  3204.  
  3205. minLine = hunk.offset + hunk.oldStart + hunk.oldLines;
  3206. } // Apply patch hunks
  3207.  
  3208.  
  3209. var diffOffset = 0;
  3210.  
  3211. for (var _i = 0; _i < hunks.length; _i++) {
  3212. var _hunk = hunks[_i],
  3213. _toPos = _hunk.oldStart + _hunk.offset + diffOffset - 1;
  3214.  
  3215. diffOffset += _hunk.newLines - _hunk.oldLines;
  3216.  
  3217. if (_toPos < 0) {
  3218. // Creating a new file
  3219. _toPos = 0;
  3220. }
  3221.  
  3222. for (var j = 0; j < _hunk.lines.length; j++) {
  3223. var line = _hunk.lines[j],
  3224. operation = line.length > 0 ? line[0] : ' ',
  3225. content = line.length > 0 ? line.substr(1) : line,
  3226. delimiter = _hunk.linedelimiters[j];
  3227.  
  3228. if (operation === ' ') {
  3229. _toPos++;
  3230. } else if (operation === '-') {
  3231. lines.splice(_toPos, 1);
  3232. delimiters.splice(_toPos, 1);
  3233. /* istanbul ignore else */
  3234. } else if (operation === '+') {
  3235. lines.splice(_toPos, 0, content);
  3236. delimiters.splice(_toPos, 0, delimiter);
  3237. _toPos++;
  3238. } else if (operation === '\\') {
  3239. var previousOperation = _hunk.lines[j - 1] ? _hunk.lines[j - 1][0] : null;
  3240.  
  3241. if (previousOperation === '+') {
  3242. removeEOFNL = true;
  3243. } else if (previousOperation === '-') {
  3244. addEOFNL = true;
  3245. }
  3246. }
  3247. }
  3248. } // Handle EOFNL insertion/removal
  3249.  
  3250.  
  3251. if (removeEOFNL) {
  3252. while (!lines[lines.length - 1]) {
  3253. lines.pop();
  3254. delimiters.pop();
  3255. }
  3256. } else if (addEOFNL) {
  3257. lines.push('');
  3258. delimiters.push('\n');
  3259. }
  3260.  
  3261. for (var _k = 0; _k < lines.length - 1; _k++) {
  3262. lines[_k] = lines[_k] + delimiters[_k];
  3263. }
  3264.  
  3265. return lines.join('');
  3266. } // Wrapper that supports multiple file patches via callbacks.
  3267.  
  3268. function applyPatches(uniDiff, options) {
  3269. if (typeof uniDiff === 'string') {
  3270. uniDiff = parsePatch(uniDiff);
  3271. }
  3272.  
  3273. var currentIndex = 0;
  3274.  
  3275. function processIndex() {
  3276. var index = uniDiff[currentIndex++];
  3277.  
  3278. if (!index) {
  3279. return options.complete();
  3280. }
  3281.  
  3282. options.loadFile(index, function (err, data) {
  3283. if (err) {
  3284. return options.complete(err);
  3285. }
  3286.  
  3287. var updatedContent = applyPatch(data, index, options);
  3288. options.patched(index, updatedContent, function (err) {
  3289. if (err) {
  3290. return options.complete(err);
  3291. }
  3292.  
  3293. processIndex();
  3294. });
  3295. });
  3296. }
  3297.  
  3298. processIndex();
  3299. }
  3300.  
  3301. function structuredPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, options) {
  3302. if (!options) {
  3303. options = {};
  3304. }
  3305.  
  3306. if (typeof options.context === 'undefined') {
  3307. options.context = 4;
  3308. }
  3309.  
  3310. var diff = diffLines(oldStr, newStr, options);
  3311. diff.push({
  3312. value: '',
  3313. lines: []
  3314. }); // Append an empty value to make cleanup easier
  3315.  
  3316. function contextLines(lines) {
  3317. return lines.map(function (entry) {
  3318. return ' ' + entry;
  3319. });
  3320. }
  3321.  
  3322. var hunks = [];
  3323. var oldRangeStart = 0,
  3324. newRangeStart = 0,
  3325. curRange = [],
  3326. oldLine = 1,
  3327. newLine = 1;
  3328.  
  3329. var _loop = function _loop(i) {
  3330. var current = diff[i],
  3331. lines = current.lines || current.value.replace(/\n$/, '').split('\n');
  3332. current.lines = lines;
  3333.  
  3334. if (current.added || current.removed) {
  3335. var _curRange;
  3336.  
  3337. // If we have previous context, start with that
  3338. if (!oldRangeStart) {
  3339. var prev = diff[i - 1];
  3340. oldRangeStart = oldLine;
  3341. newRangeStart = newLine;
  3342.  
  3343. if (prev) {
  3344. curRange = options.context > 0 ? contextLines(prev.lines.slice(-options.context)) : [];
  3345. oldRangeStart -= curRange.length;
  3346. newRangeStart -= curRange.length;
  3347. }
  3348. } // Output our changes
  3349.  
  3350.  
  3351. (_curRange = curRange).push.apply(_curRange, _toConsumableArray(lines.map(function (entry) {
  3352. return (current.added ? '+' : '-') + entry;
  3353. }))); // Track the updated file position
  3354.  
  3355.  
  3356. if (current.added) {
  3357. newLine += lines.length;
  3358. } else {
  3359. oldLine += lines.length;
  3360. }
  3361. } else {
  3362. // Identical context lines. Track line changes
  3363. if (oldRangeStart) {
  3364. // Close out any changes that have been output (or join overlapping)
  3365. if (lines.length <= options.context * 2 && i < diff.length - 2) {
  3366. var _curRange2;
  3367.  
  3368. // Overlapping
  3369. (_curRange2 = curRange).push.apply(_curRange2, _toConsumableArray(contextLines(lines)));
  3370. } else {
  3371. var _curRange3;
  3372.  
  3373. // end the range and output
  3374. var contextSize = Math.min(lines.length, options.context);
  3375.  
  3376. (_curRange3 = curRange).push.apply(_curRange3, _toConsumableArray(contextLines(lines.slice(0, contextSize))));
  3377.  
  3378. var hunk = {
  3379. oldStart: oldRangeStart,
  3380. oldLines: oldLine - oldRangeStart + contextSize,
  3381. newStart: newRangeStart,
  3382. newLines: newLine - newRangeStart + contextSize,
  3383. lines: curRange
  3384. };
  3385.  
  3386. if (i >= diff.length - 2 && lines.length <= options.context) {
  3387. // EOF is inside this hunk
  3388. var oldEOFNewline = /\n$/.test(oldStr);
  3389. var newEOFNewline = /\n$/.test(newStr);
  3390. var noNlBeforeAdds = lines.length == 0 && curRange.length > hunk.oldLines;
  3391.  
  3392. if (!oldEOFNewline && noNlBeforeAdds) {
  3393. // special case: old has no eol and no trailing context; no-nl can end up before adds
  3394. curRange.splice(hunk.oldLines, 0, '\\ No newline at end of file');
  3395. }
  3396.  
  3397. if (!oldEOFNewline && !noNlBeforeAdds || !newEOFNewline) {
  3398. curRange.push('\\ No newline at end of file');
  3399. }
  3400. }
  3401.  
  3402. hunks.push(hunk);
  3403. oldRangeStart = 0;
  3404. newRangeStart = 0;
  3405. curRange = [];
  3406. }
  3407. }
  3408.  
  3409. oldLine += lines.length;
  3410. newLine += lines.length;
  3411. }
  3412. };
  3413.  
  3414. for (var i = 0; i < diff.length; i++) {
  3415. _loop(i);
  3416. }
  3417.  
  3418. return {
  3419. oldFileName: oldFileName,
  3420. newFileName: newFileName,
  3421. oldHeader: oldHeader,
  3422. newHeader: newHeader,
  3423. hunks: hunks
  3424. };
  3425. }
  3426. function createTwoFilesPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, options) {
  3427. var diff = structuredPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, options);
  3428. var ret = [];
  3429.  
  3430. if (oldFileName == newFileName) {
  3431. ret.push('Index: ' + oldFileName);
  3432. }
  3433.  
  3434. ret.push('===================================================================');
  3435. ret.push('--- ' + diff.oldFileName + (typeof diff.oldHeader === 'undefined' ? '' : '\t' + diff.oldHeader));
  3436. ret.push('+++ ' + diff.newFileName + (typeof diff.newHeader === 'undefined' ? '' : '\t' + diff.newHeader));
  3437.  
  3438. for (var i = 0; i < diff.hunks.length; i++) {
  3439. var hunk = diff.hunks[i];
  3440. ret.push('@@ -' + hunk.oldStart + ',' + hunk.oldLines + ' +' + hunk.newStart + ',' + hunk.newLines + ' @@');
  3441. ret.push.apply(ret, hunk.lines);
  3442. }
  3443.  
  3444. return ret.join('\n') + '\n';
  3445. }
  3446. function createPatch(fileName, oldStr, newStr, oldHeader, newHeader, options) {
  3447. return createTwoFilesPatch(fileName, fileName, oldStr, newStr, oldHeader, newHeader, options);
  3448. }
  3449.  
  3450. function arrayEqual(a, b) {
  3451. if (a.length !== b.length) {
  3452. return false;
  3453. }
  3454.  
  3455. return arrayStartsWith(a, b);
  3456. }
  3457. function arrayStartsWith(array, start) {
  3458. if (start.length > array.length) {
  3459. return false;
  3460. }
  3461.  
  3462. for (var i = 0; i < start.length; i++) {
  3463. if (start[i] !== array[i]) {
  3464. return false;
  3465. }
  3466. }
  3467.  
  3468. return true;
  3469. }
  3470.  
  3471. function calcLineCount(hunk) {
  3472. var _calcOldNewLineCount = calcOldNewLineCount(hunk.lines),
  3473. oldLines = _calcOldNewLineCount.oldLines,
  3474. newLines = _calcOldNewLineCount.newLines;
  3475.  
  3476. if (oldLines !== undefined) {
  3477. hunk.oldLines = oldLines;
  3478. } else {
  3479. delete hunk.oldLines;
  3480. }
  3481.  
  3482. if (newLines !== undefined) {
  3483. hunk.newLines = newLines;
  3484. } else {
  3485. delete hunk.newLines;
  3486. }
  3487. }
  3488. function merge(mine, theirs, base) {
  3489. mine = loadPatch(mine, base);
  3490. theirs = loadPatch(theirs, base);
  3491. var ret = {}; // For index we just let it pass through as it doesn't have any necessary meaning.
  3492. // Leaving sanity checks on this to the API consumer that may know more about the
  3493. // meaning in their own context.
  3494.  
  3495. if (mine.index || theirs.index) {
  3496. ret.index = mine.index || theirs.index;
  3497. }
  3498.  
  3499. if (mine.newFileName || theirs.newFileName) {
  3500. if (!fileNameChanged(mine)) {
  3501. // No header or no change in ours, use theirs (and ours if theirs does not exist)
  3502. ret.oldFileName = theirs.oldFileName || mine.oldFileName;
  3503. ret.newFileName = theirs.newFileName || mine.newFileName;
  3504. ret.oldHeader = theirs.oldHeader || mine.oldHeader;
  3505. ret.newHeader = theirs.newHeader || mine.newHeader;
  3506. } else if (!fileNameChanged(theirs)) {
  3507. // No header or no change in theirs, use ours
  3508. ret.oldFileName = mine.oldFileName;
  3509. ret.newFileName = mine.newFileName;
  3510. ret.oldHeader = mine.oldHeader;
  3511. ret.newHeader = mine.newHeader;
  3512. } else {
  3513. // Both changed... figure it out
  3514. ret.oldFileName = selectField(ret, mine.oldFileName, theirs.oldFileName);
  3515. ret.newFileName = selectField(ret, mine.newFileName, theirs.newFileName);
  3516. ret.oldHeader = selectField(ret, mine.oldHeader, theirs.oldHeader);
  3517. ret.newHeader = selectField(ret, mine.newHeader, theirs.newHeader);
  3518. }
  3519. }
  3520.  
  3521. ret.hunks = [];
  3522. var mineIndex = 0,
  3523. theirsIndex = 0,
  3524. mineOffset = 0,
  3525. theirsOffset = 0;
  3526.  
  3527. while (mineIndex < mine.hunks.length || theirsIndex < theirs.hunks.length) {
  3528. var mineCurrent = mine.hunks[mineIndex] || {
  3529. oldStart: Infinity
  3530. },
  3531. theirsCurrent = theirs.hunks[theirsIndex] || {
  3532. oldStart: Infinity
  3533. };
  3534.  
  3535. if (hunkBefore(mineCurrent, theirsCurrent)) {
  3536. // This patch does not overlap with any of the others, yay.
  3537. ret.hunks.push(cloneHunk(mineCurrent, mineOffset));
  3538. mineIndex++;
  3539. theirsOffset += mineCurrent.newLines - mineCurrent.oldLines;
  3540. } else if (hunkBefore(theirsCurrent, mineCurrent)) {
  3541. // This patch does not overlap with any of the others, yay.
  3542. ret.hunks.push(cloneHunk(theirsCurrent, theirsOffset));
  3543. theirsIndex++;
  3544. mineOffset += theirsCurrent.newLines - theirsCurrent.oldLines;
  3545. } else {
  3546. // Overlap, merge as best we can
  3547. var mergedHunk = {
  3548. oldStart: Math.min(mineCurrent.oldStart, theirsCurrent.oldStart),
  3549. oldLines: 0,
  3550. newStart: Math.min(mineCurrent.newStart + mineOffset, theirsCurrent.oldStart + theirsOffset),
  3551. newLines: 0,
  3552. lines: []
  3553. };
  3554. mergeLines(mergedHunk, mineCurrent.oldStart, mineCurrent.lines, theirsCurrent.oldStart, theirsCurrent.lines);
  3555. theirsIndex++;
  3556. mineIndex++;
  3557. ret.hunks.push(mergedHunk);
  3558. }
  3559. }
  3560.  
  3561. return ret;
  3562. }
  3563.  
  3564. function loadPatch(param, base) {
  3565. if (typeof param === 'string') {
  3566. if (/^@@/m.test(param) || /^Index:/m.test(param)) {
  3567. return parsePatch(param)[0];
  3568. }
  3569.  
  3570. if (!base) {
  3571. throw new Error('Must provide a base reference or pass in a patch');
  3572. }
  3573.  
  3574. return structuredPatch(undefined, undefined, base, param);
  3575. }
  3576.  
  3577. return param;
  3578. }
  3579.  
  3580. function fileNameChanged(patch) {
  3581. return patch.newFileName && patch.newFileName !== patch.oldFileName;
  3582. }
  3583.  
  3584. function selectField(index, mine, theirs) {
  3585. if (mine === theirs) {
  3586. return mine;
  3587. } else {
  3588. index.conflict = true;
  3589. return {
  3590. mine: mine,
  3591. theirs: theirs
  3592. };
  3593. }
  3594. }
  3595.  
  3596. function hunkBefore(test, check) {
  3597. return test.oldStart < check.oldStart && test.oldStart + test.oldLines < check.oldStart;
  3598. }
  3599.  
  3600. function cloneHunk(hunk, offset) {
  3601. return {
  3602. oldStart: hunk.oldStart,
  3603. oldLines: hunk.oldLines,
  3604. newStart: hunk.newStart + offset,
  3605. newLines: hunk.newLines,
  3606. lines: hunk.lines
  3607. };
  3608. }
  3609.  
  3610. function mergeLines(hunk, mineOffset, mineLines, theirOffset, theirLines) {
  3611. // This will generally result in a conflicted hunk, but there are cases where the context
  3612. // is the only overlap where we can successfully merge the content here.
  3613. var mine = {
  3614. offset: mineOffset,
  3615. lines: mineLines,
  3616. index: 0
  3617. },
  3618. their = {
  3619. offset: theirOffset,
  3620. lines: theirLines,
  3621. index: 0
  3622. }; // Handle any leading content
  3623.  
  3624. insertLeading(hunk, mine, their);
  3625. insertLeading(hunk, their, mine); // Now in the overlap content. Scan through and select the best changes from each.
  3626.  
  3627. while (mine.index < mine.lines.length && their.index < their.lines.length) {
  3628. var mineCurrent = mine.lines[mine.index],
  3629. theirCurrent = their.lines[their.index];
  3630.  
  3631. if ((mineCurrent[0] === '-' || mineCurrent[0] === '+') && (theirCurrent[0] === '-' || theirCurrent[0] === '+')) {
  3632. // Both modified ...
  3633. mutualChange(hunk, mine, their);
  3634. } else if (mineCurrent[0] === '+' && theirCurrent[0] === ' ') {
  3635. var _hunk$lines;
  3636.  
  3637. // Mine inserted
  3638. (_hunk$lines = hunk.lines).push.apply(_hunk$lines, _toConsumableArray(collectChange(mine)));
  3639. } else if (theirCurrent[0] === '+' && mineCurrent[0] === ' ') {
  3640. var _hunk$lines2;
  3641.  
  3642. // Theirs inserted
  3643. (_hunk$lines2 = hunk.lines).push.apply(_hunk$lines2, _toConsumableArray(collectChange(their)));
  3644. } else if (mineCurrent[0] === '-' && theirCurrent[0] === ' ') {
  3645. // Mine removed or edited
  3646. removal(hunk, mine, their);
  3647. } else if (theirCurrent[0] === '-' && mineCurrent[0] === ' ') {
  3648. // Their removed or edited
  3649. removal(hunk, their, mine, true);
  3650. } else if (mineCurrent === theirCurrent) {
  3651. // Context identity
  3652. hunk.lines.push(mineCurrent);
  3653. mine.index++;
  3654. their.index++;
  3655. } else {
  3656. // Context mismatch
  3657. conflict(hunk, collectChange(mine), collectChange(their));
  3658. }
  3659. } // Now push anything that may be remaining
  3660.  
  3661.  
  3662. insertTrailing(hunk, mine);
  3663. insertTrailing(hunk, their);
  3664. calcLineCount(hunk);
  3665. }
  3666.  
  3667. function mutualChange(hunk, mine, their) {
  3668. var myChanges = collectChange(mine),
  3669. theirChanges = collectChange(their);
  3670.  
  3671. if (allRemoves(myChanges) && allRemoves(theirChanges)) {
  3672. // Special case for remove changes that are supersets of one another
  3673. if (arrayStartsWith(myChanges, theirChanges) && skipRemoveSuperset(their, myChanges, myChanges.length - theirChanges.length)) {
  3674. var _hunk$lines3;
  3675.  
  3676. (_hunk$lines3 = hunk.lines).push.apply(_hunk$lines3, _toConsumableArray(myChanges));
  3677.  
  3678. return;
  3679. } else if (arrayStartsWith(theirChanges, myChanges) && skipRemoveSuperset(mine, theirChanges, theirChanges.length - myChanges.length)) {
  3680. var _hunk$lines4;
  3681.  
  3682. (_hunk$lines4 = hunk.lines).push.apply(_hunk$lines4, _toConsumableArray(theirChanges));
  3683.  
  3684. return;
  3685. }
  3686. } else if (arrayEqual(myChanges, theirChanges)) {
  3687. var _hunk$lines5;
  3688.  
  3689. (_hunk$lines5 = hunk.lines).push.apply(_hunk$lines5, _toConsumableArray(myChanges));
  3690.  
  3691. return;
  3692. }
  3693.  
  3694. conflict(hunk, myChanges, theirChanges);
  3695. }
  3696.  
  3697. function removal(hunk, mine, their, swap) {
  3698. var myChanges = collectChange(mine),
  3699. theirChanges = collectContext(their, myChanges);
  3700.  
  3701. if (theirChanges.merged) {
  3702. var _hunk$lines6;
  3703.  
  3704. (_hunk$lines6 = hunk.lines).push.apply(_hunk$lines6, _toConsumableArray(theirChanges.merged));
  3705. } else {
  3706. conflict(hunk, swap ? theirChanges : myChanges, swap ? myChanges : theirChanges);
  3707. }
  3708. }
  3709.  
  3710. function conflict(hunk, mine, their) {
  3711. hunk.conflict = true;
  3712. hunk.lines.push({
  3713. conflict: true,
  3714. mine: mine,
  3715. theirs: their
  3716. });
  3717. }
  3718.  
  3719. function insertLeading(hunk, insert, their) {
  3720. while (insert.offset < their.offset && insert.index < insert.lines.length) {
  3721. var line = insert.lines[insert.index++];
  3722. hunk.lines.push(line);
  3723. insert.offset++;
  3724. }
  3725. }
  3726.  
  3727. function insertTrailing(hunk, insert) {
  3728. while (insert.index < insert.lines.length) {
  3729. var line = insert.lines[insert.index++];
  3730. hunk.lines.push(line);
  3731. }
  3732. }
  3733.  
  3734. function collectChange(state) {
  3735. var ret = [],
  3736. operation = state.lines[state.index][0];
  3737.  
  3738. while (state.index < state.lines.length) {
  3739. var line = state.lines[state.index]; // Group additions that are immediately after subtractions and treat them as one "atomic" modify change.
  3740.  
  3741. if (operation === '-' && line[0] === '+') {
  3742. operation = '+';
  3743. }
  3744.  
  3745. if (operation === line[0]) {
  3746. ret.push(line);
  3747. state.index++;
  3748. } else {
  3749. break;
  3750. }
  3751. }
  3752.  
  3753. return ret;
  3754. }
  3755.  
  3756. function collectContext(state, matchChanges) {
  3757. var changes = [],
  3758. merged = [],
  3759. matchIndex = 0,
  3760. contextChanges = false,
  3761. conflicted = false;
  3762.  
  3763. while (matchIndex < matchChanges.length && state.index < state.lines.length) {
  3764. var change = state.lines[state.index],
  3765. match = matchChanges[matchIndex]; // Once we've hit our add, then we are done
  3766.  
  3767. if (match[0] === '+') {
  3768. break;
  3769. }
  3770.  
  3771. contextChanges = contextChanges || change[0] !== ' ';
  3772. merged.push(match);
  3773. matchIndex++; // Consume any additions in the other block as a conflict to attempt
  3774. // to pull in the remaining context after this
  3775.  
  3776. if (change[0] === '+') {
  3777. conflicted = true;
  3778.  
  3779. while (change[0] === '+') {
  3780. changes.push(change);
  3781. change = state.lines[++state.index];
  3782. }
  3783. }
  3784.  
  3785. if (match.substr(1) === change.substr(1)) {
  3786. changes.push(change);
  3787. state.index++;
  3788. } else {
  3789. conflicted = true;
  3790. }
  3791. }
  3792.  
  3793. if ((matchChanges[matchIndex] || '')[0] === '+' && contextChanges) {
  3794. conflicted = true;
  3795. }
  3796.  
  3797. if (conflicted) {
  3798. return changes;
  3799. }
  3800.  
  3801. while (matchIndex < matchChanges.length) {
  3802. merged.push(matchChanges[matchIndex++]);
  3803. }
  3804.  
  3805. return {
  3806. merged: merged,
  3807. changes: changes
  3808. };
  3809. }
  3810.  
  3811. function allRemoves(changes) {
  3812. return changes.reduce(function (prev, change) {
  3813. return prev && change[0] === '-';
  3814. }, true);
  3815. }
  3816.  
  3817. function skipRemoveSuperset(state, removeChanges, delta) {
  3818. for (var i = 0; i < delta; i++) {
  3819. var changeContent = removeChanges[removeChanges.length - delta + i].substr(1);
  3820.  
  3821. if (state.lines[state.index + i] !== ' ' + changeContent) {
  3822. return false;
  3823. }
  3824. }
  3825.  
  3826. state.index += delta;
  3827. return true;
  3828. }
  3829.  
  3830. function calcOldNewLineCount(lines) {
  3831. var oldLines = 0;
  3832. var newLines = 0;
  3833. lines.forEach(function (line) {
  3834. if (typeof line !== 'string') {
  3835. var myCount = calcOldNewLineCount(line.mine);
  3836. var theirCount = calcOldNewLineCount(line.theirs);
  3837.  
  3838. if (oldLines !== undefined) {
  3839. if (myCount.oldLines === theirCount.oldLines) {
  3840. oldLines += myCount.oldLines;
  3841. } else {
  3842. oldLines = undefined;
  3843. }
  3844. }
  3845.  
  3846. if (newLines !== undefined) {
  3847. if (myCount.newLines === theirCount.newLines) {
  3848. newLines += myCount.newLines;
  3849. } else {
  3850. newLines = undefined;
  3851. }
  3852. }
  3853. } else {
  3854. if (newLines !== undefined && (line[0] === '+' || line[0] === ' ')) {
  3855. newLines++;
  3856. }
  3857.  
  3858. if (oldLines !== undefined && (line[0] === '-' || line[0] === ' ')) {
  3859. oldLines++;
  3860. }
  3861. }
  3862. });
  3863. return {
  3864. oldLines: oldLines,
  3865. newLines: newLines
  3866. };
  3867. }
  3868.  
  3869. // See: http://code.google.com/p/google-diff-match-patch/wiki/API
  3870. function convertChangesToDMP(changes) {
  3871. var ret = [],
  3872. change,
  3873. operation;
  3874.  
  3875. for (var i = 0; i < changes.length; i++) {
  3876. change = changes[i];
  3877.  
  3878. if (change.added) {
  3879. operation = 1;
  3880. } else if (change.removed) {
  3881. operation = -1;
  3882. } else {
  3883. operation = 0;
  3884. }
  3885.  
  3886. ret.push([operation, change.value]);
  3887. }
  3888.  
  3889. return ret;
  3890. }
  3891.  
  3892. function convertChangesToXML(changes) {
  3893. var ret = [];
  3894.  
  3895. for (var i = 0; i < changes.length; i++) {
  3896. var change = changes[i];
  3897.  
  3898. if (change.added) {
  3899. ret.push('<ins>');
  3900. } else if (change.removed) {
  3901. ret.push('<del>');
  3902. }
  3903.  
  3904. ret.push(escapeHTML(change.value));
  3905.  
  3906. if (change.added) {
  3907. ret.push('</ins>');
  3908. } else if (change.removed) {
  3909. ret.push('</del>');
  3910. }
  3911. }
  3912.  
  3913. return ret.join('');
  3914. }
  3915.  
  3916. function escapeHTML(s) {
  3917. var n = s;
  3918. n = n.replace(/&/g, '&amp;');
  3919. n = n.replace(/</g, '&lt;');
  3920. n = n.replace(/>/g, '&gt;');
  3921. n = n.replace(/"/g, '&quot;');
  3922. return n;
  3923. }
  3924.  
  3925. /* See LICENSE file for terms of use */
  3926.  
  3927. exports.Diff = Diff;
  3928. exports.diffChars = diffChars;
  3929. exports.diffWords = diffWords;
  3930. exports.diffWordsWithSpace = diffWordsWithSpace;
  3931. exports.diffLines = diffLines;
  3932. exports.diffTrimmedLines = diffTrimmedLines;
  3933. exports.diffSentences = diffSentences;
  3934. exports.diffCss = diffCss;
  3935. exports.diffJson = diffJson;
  3936. exports.diffArrays = diffArrays;
  3937. exports.structuredPatch = structuredPatch;
  3938. exports.createTwoFilesPatch = createTwoFilesPatch;
  3939. exports.createPatch = createPatch;
  3940. exports.applyPatch = applyPatch;
  3941. exports.applyPatches = applyPatches;
  3942. exports.parsePatch = parsePatch;
  3943. exports.merge = merge;
  3944. exports.convertChangesToDMP = convertChangesToDMP;
  3945. exports.convertChangesToXML = convertChangesToXML;
  3946. exports.canonicalize = canonicalize;
  3947.  
  3948. Object.defineProperty(exports, '__esModule', { value: true });
  3949.  
  3950. }));
  3951.  
  3952.  
  3953. /***/ }),
  3954.  
  3955. /***/ "xeH2":
  3956. /***/ (function(module, exports) {
  3957.  
  3958. module.exports = $;
  3959.  
  3960. /***/ })
  3961.  
  3962. /******/ });