diff.worker-D37lkEH1.js 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996
  1. (function () {
  2. 'use strict';
  3. /**
  4. * @license
  5. * Copyright 2019 Google LLC
  6. * SPDX-License-Identifier: Apache-2.0
  7. */
  8. const proxyMarker = Symbol("Comlink.proxy");
  9. const createEndpoint = Symbol("Comlink.endpoint");
  10. const releaseProxy = Symbol("Comlink.releaseProxy");
  11. const finalizer = Symbol("Comlink.finalizer");
  12. const throwMarker = Symbol("Comlink.thrown");
  13. const isObject = (val) => (typeof val === "object" && val !== null) || typeof val === "function";
  14. /**
  15. * Internal transfer handle to handle objects marked to proxy.
  16. */
  17. const proxyTransferHandler = {
  18. canHandle: (val) => isObject(val) && val[proxyMarker],
  19. serialize(obj) {
  20. const { port1, port2 } = new MessageChannel();
  21. expose(obj, port1);
  22. return [port2, [port2]];
  23. },
  24. deserialize(port) {
  25. port.start();
  26. return wrap(port);
  27. },
  28. };
  29. /**
  30. * Internal transfer handler to handle thrown exceptions.
  31. */
  32. const throwTransferHandler = {
  33. canHandle: (value) => isObject(value) && throwMarker in value,
  34. serialize({ value }) {
  35. let serialized;
  36. if (value instanceof Error) {
  37. serialized = {
  38. isError: true,
  39. value: {
  40. message: value.message,
  41. name: value.name,
  42. stack: value.stack,
  43. },
  44. };
  45. }
  46. else {
  47. serialized = { isError: false, value };
  48. }
  49. return [serialized, []];
  50. },
  51. deserialize(serialized) {
  52. if (serialized.isError) {
  53. throw Object.assign(new Error(serialized.value.message), serialized.value);
  54. }
  55. throw serialized.value;
  56. },
  57. };
  58. /**
  59. * Allows customizing the serialization of certain values.
  60. */
  61. const transferHandlers = new Map([
  62. ["proxy", proxyTransferHandler],
  63. ["throw", throwTransferHandler],
  64. ]);
  65. function isAllowedOrigin(allowedOrigins, origin) {
  66. for (const allowedOrigin of allowedOrigins) {
  67. if (origin === allowedOrigin || allowedOrigin === "*") {
  68. return true;
  69. }
  70. if (allowedOrigin instanceof RegExp && allowedOrigin.test(origin)) {
  71. return true;
  72. }
  73. }
  74. return false;
  75. }
  76. function expose(obj, ep = globalThis, allowedOrigins = ["*"]) {
  77. ep.addEventListener("message", function callback(ev) {
  78. if (!ev || !ev.data) {
  79. return;
  80. }
  81. if (!isAllowedOrigin(allowedOrigins, ev.origin)) {
  82. console.warn(`Invalid origin '${ev.origin}' for comlink proxy`);
  83. return;
  84. }
  85. const { id, type, path } = Object.assign({ path: [] }, ev.data);
  86. const argumentList = (ev.data.argumentList || []).map(fromWireValue);
  87. let returnValue;
  88. try {
  89. const parent = path.slice(0, -1).reduce((obj, prop) => obj[prop], obj);
  90. const rawValue = path.reduce((obj, prop) => obj[prop], obj);
  91. switch (type) {
  92. case "GET" /* MessageType.GET */:
  93. {
  94. returnValue = rawValue;
  95. }
  96. break;
  97. case "SET" /* MessageType.SET */:
  98. {
  99. parent[path.slice(-1)[0]] = fromWireValue(ev.data.value);
  100. returnValue = true;
  101. }
  102. break;
  103. case "APPLY" /* MessageType.APPLY */:
  104. {
  105. returnValue = rawValue.apply(parent, argumentList);
  106. }
  107. break;
  108. case "CONSTRUCT" /* MessageType.CONSTRUCT */:
  109. {
  110. const value = new rawValue(...argumentList);
  111. returnValue = proxy(value);
  112. }
  113. break;
  114. case "ENDPOINT" /* MessageType.ENDPOINT */:
  115. {
  116. const { port1, port2 } = new MessageChannel();
  117. expose(obj, port2);
  118. returnValue = transfer(port1, [port1]);
  119. }
  120. break;
  121. case "RELEASE" /* MessageType.RELEASE */:
  122. {
  123. returnValue = undefined;
  124. }
  125. break;
  126. default:
  127. return;
  128. }
  129. }
  130. catch (value) {
  131. returnValue = { value, [throwMarker]: 0 };
  132. }
  133. Promise.resolve(returnValue)
  134. .catch((value) => {
  135. return { value, [throwMarker]: 0 };
  136. })
  137. .then((returnValue) => {
  138. const [wireValue, transferables] = toWireValue(returnValue);
  139. ep.postMessage(Object.assign(Object.assign({}, wireValue), { id }), transferables);
  140. if (type === "RELEASE" /* MessageType.RELEASE */) {
  141. // detach and deactive after sending release response above.
  142. ep.removeEventListener("message", callback);
  143. closeEndPoint(ep);
  144. if (finalizer in obj && typeof obj[finalizer] === "function") {
  145. obj[finalizer]();
  146. }
  147. }
  148. })
  149. .catch((error) => {
  150. // Send Serialization Error To Caller
  151. const [wireValue, transferables] = toWireValue({
  152. value: new TypeError("Unserializable return value"),
  153. [throwMarker]: 0,
  154. });
  155. ep.postMessage(Object.assign(Object.assign({}, wireValue), { id }), transferables);
  156. });
  157. });
  158. if (ep.start) {
  159. ep.start();
  160. }
  161. }
  162. function isMessagePort(endpoint) {
  163. return endpoint.constructor.name === "MessagePort";
  164. }
  165. function closeEndPoint(endpoint) {
  166. if (isMessagePort(endpoint))
  167. endpoint.close();
  168. }
  169. function wrap(ep, target) {
  170. const pendingListeners = new Map();
  171. ep.addEventListener("message", function handleMessage(ev) {
  172. const { data } = ev;
  173. if (!data || !data.id) {
  174. return;
  175. }
  176. const resolver = pendingListeners.get(data.id);
  177. if (!resolver) {
  178. return;
  179. }
  180. try {
  181. resolver(data);
  182. }
  183. finally {
  184. pendingListeners.delete(data.id);
  185. }
  186. });
  187. return createProxy(ep, pendingListeners, [], target);
  188. }
  189. function throwIfProxyReleased(isReleased) {
  190. if (isReleased) {
  191. throw new Error("Proxy has been released and is not useable");
  192. }
  193. }
  194. function releaseEndpoint(ep) {
  195. return requestResponseMessage(ep, new Map(), {
  196. type: "RELEASE" /* MessageType.RELEASE */,
  197. }).then(() => {
  198. closeEndPoint(ep);
  199. });
  200. }
  201. const proxyCounter = new WeakMap();
  202. const proxyFinalizers = "FinalizationRegistry" in globalThis &&
  203. new FinalizationRegistry((ep) => {
  204. const newCount = (proxyCounter.get(ep) || 0) - 1;
  205. proxyCounter.set(ep, newCount);
  206. if (newCount === 0) {
  207. releaseEndpoint(ep);
  208. }
  209. });
  210. function registerProxy(proxy, ep) {
  211. const newCount = (proxyCounter.get(ep) || 0) + 1;
  212. proxyCounter.set(ep, newCount);
  213. if (proxyFinalizers) {
  214. proxyFinalizers.register(proxy, ep, proxy);
  215. }
  216. }
  217. function unregisterProxy(proxy) {
  218. if (proxyFinalizers) {
  219. proxyFinalizers.unregister(proxy);
  220. }
  221. }
  222. function createProxy(ep, pendingListeners, path = [], target = function () { }) {
  223. let isProxyReleased = false;
  224. const proxy = new Proxy(target, {
  225. get(_target, prop) {
  226. throwIfProxyReleased(isProxyReleased);
  227. if (prop === releaseProxy) {
  228. return () => {
  229. unregisterProxy(proxy);
  230. releaseEndpoint(ep);
  231. pendingListeners.clear();
  232. isProxyReleased = true;
  233. };
  234. }
  235. if (prop === "then") {
  236. if (path.length === 0) {
  237. return { then: () => proxy };
  238. }
  239. const r = requestResponseMessage(ep, pendingListeners, {
  240. type: "GET" /* MessageType.GET */,
  241. path: path.map((p) => p.toString()),
  242. }).then(fromWireValue);
  243. return r.then.bind(r);
  244. }
  245. return createProxy(ep, pendingListeners, [...path, prop]);
  246. },
  247. set(_target, prop, rawValue) {
  248. throwIfProxyReleased(isProxyReleased);
  249. // FIXME: ES6 Proxy Handler `set` methods are supposed to return a
  250. // boolean. To show good will, we return true asynchronously ¯\_(ツ)_/¯
  251. const [value, transferables] = toWireValue(rawValue);
  252. return requestResponseMessage(ep, pendingListeners, {
  253. type: "SET" /* MessageType.SET */,
  254. path: [...path, prop].map((p) => p.toString()),
  255. value,
  256. }, transferables).then(fromWireValue);
  257. },
  258. apply(_target, _thisArg, rawArgumentList) {
  259. throwIfProxyReleased(isProxyReleased);
  260. const last = path[path.length - 1];
  261. if (last === createEndpoint) {
  262. return requestResponseMessage(ep, pendingListeners, {
  263. type: "ENDPOINT" /* MessageType.ENDPOINT */,
  264. }).then(fromWireValue);
  265. }
  266. // We just pretend that `bind()` didn’t happen.
  267. if (last === "bind") {
  268. return createProxy(ep, pendingListeners, path.slice(0, -1));
  269. }
  270. const [argumentList, transferables] = processArguments(rawArgumentList);
  271. return requestResponseMessage(ep, pendingListeners, {
  272. type: "APPLY" /* MessageType.APPLY */,
  273. path: path.map((p) => p.toString()),
  274. argumentList,
  275. }, transferables).then(fromWireValue);
  276. },
  277. construct(_target, rawArgumentList) {
  278. throwIfProxyReleased(isProxyReleased);
  279. const [argumentList, transferables] = processArguments(rawArgumentList);
  280. return requestResponseMessage(ep, pendingListeners, {
  281. type: "CONSTRUCT" /* MessageType.CONSTRUCT */,
  282. path: path.map((p) => p.toString()),
  283. argumentList,
  284. }, transferables).then(fromWireValue);
  285. },
  286. });
  287. registerProxy(proxy, ep);
  288. return proxy;
  289. }
  290. function myFlat(arr) {
  291. return Array.prototype.concat.apply([], arr);
  292. }
  293. function processArguments(argumentList) {
  294. const processed = argumentList.map(toWireValue);
  295. return [processed.map((v) => v[0]), myFlat(processed.map((v) => v[1]))];
  296. }
  297. const transferCache = new WeakMap();
  298. function transfer(obj, transfers) {
  299. transferCache.set(obj, transfers);
  300. return obj;
  301. }
  302. function proxy(obj) {
  303. return Object.assign(obj, { [proxyMarker]: true });
  304. }
  305. function toWireValue(value) {
  306. for (const [name, handler] of transferHandlers) {
  307. if (handler.canHandle(value)) {
  308. const [serializedValue, transferables] = handler.serialize(value);
  309. return [
  310. {
  311. type: "HANDLER" /* WireValueType.HANDLER */,
  312. name,
  313. value: serializedValue,
  314. },
  315. transferables,
  316. ];
  317. }
  318. }
  319. return [
  320. {
  321. type: "RAW" /* WireValueType.RAW */,
  322. value,
  323. },
  324. transferCache.get(value) || [],
  325. ];
  326. }
  327. function fromWireValue(value) {
  328. switch (value.type) {
  329. case "HANDLER" /* WireValueType.HANDLER */:
  330. return transferHandlers.get(value.name).deserialize(value.value);
  331. case "RAW" /* WireValueType.RAW */:
  332. return value.value;
  333. }
  334. }
  335. function requestResponseMessage(ep, pendingListeners, msg, transfers) {
  336. return new Promise((resolve) => {
  337. const id = generateUUID();
  338. pendingListeners.set(id, resolve);
  339. if (ep.start) {
  340. ep.start();
  341. }
  342. ep.postMessage(Object.assign({ id }, msg), transfers);
  343. });
  344. }
  345. function generateUUID() {
  346. return new Array(4)
  347. .fill(0)
  348. .map(() => Math.floor(Math.random() * Number.MAX_SAFE_INTEGER).toString(16))
  349. .join("-");
  350. }
  351. const defaultOptions = /* @__PURE__ */ Object.freeze({
  352. diffTimeout: 1,
  353. diffEditCost: 4,
  354. matchThreshold: 0.5,
  355. matchDistance: 1e3,
  356. patchDeleteThreshold: 0.5,
  357. patchMargin: 4,
  358. matchMaxBits: 32
  359. });
  360. function resolveOptions(options) {
  361. if (options?.__resolved)
  362. return options;
  363. const resolved = {
  364. ...defaultOptions,
  365. ...options
  366. };
  367. Object.defineProperty(resolved, "__resolved", { value: true, enumerable: false });
  368. return resolved;
  369. }
  370. const DIFF_DELETE = -1;
  371. const DIFF_INSERT = 1;
  372. const DIFF_EQUAL = 0;
  373. function createDiff(op, text) {
  374. return [op, text];
  375. }
  376. function diffMain(text1, text2, options, opt_checklines = true, opt_deadline) {
  377. const resolved = resolveOptions(options);
  378. if (typeof opt_deadline == "undefined") {
  379. if (resolved.diffTimeout <= 0)
  380. opt_deadline = Number.MAX_VALUE;
  381. else
  382. opt_deadline = (/* @__PURE__ */ new Date()).getTime() + resolved.diffTimeout * 1e3;
  383. }
  384. const deadline = opt_deadline;
  385. if (text1 == null || text2 == null)
  386. throw new Error("Null input. (diff_main)");
  387. if (text1 === text2) {
  388. if (text1)
  389. return [createDiff(DIFF_EQUAL, text1)];
  390. return [];
  391. }
  392. const checklines = opt_checklines;
  393. let commonlength = diffCommonPrefix(text1, text2);
  394. const commonprefix = text1.substring(0, commonlength);
  395. text1 = text1.substring(commonlength);
  396. text2 = text2.substring(commonlength);
  397. commonlength = diffCommonSuffix(text1, text2);
  398. const commonsuffix = text1.substring(text1.length - commonlength);
  399. text1 = text1.substring(0, text1.length - commonlength);
  400. text2 = text2.substring(0, text2.length - commonlength);
  401. const diffs = diffCompute(text1, text2, resolved, checklines, deadline);
  402. if (commonprefix)
  403. diffs.unshift(createDiff(DIFF_EQUAL, commonprefix));
  404. if (commonsuffix)
  405. diffs.push(createDiff(DIFF_EQUAL, commonsuffix));
  406. diffCleanupMerge(diffs);
  407. return diffs;
  408. }
  409. function diffCompute(text1, text2, options, checklines, deadline) {
  410. let diffs;
  411. if (!text1) {
  412. return [createDiff(DIFF_INSERT, text2)];
  413. }
  414. if (!text2) {
  415. return [createDiff(DIFF_DELETE, text1)];
  416. }
  417. const longtext = text1.length > text2.length ? text1 : text2;
  418. const shorttext = text1.length > text2.length ? text2 : text1;
  419. const i = longtext.indexOf(shorttext);
  420. if (i !== -1) {
  421. diffs = [createDiff(DIFF_INSERT, longtext.substring(0, i)), createDiff(DIFF_EQUAL, shorttext), createDiff(DIFF_INSERT, longtext.substring(i + shorttext.length))];
  422. if (text1.length > text2.length)
  423. diffs[0][0] = diffs[2][0] = DIFF_DELETE;
  424. return diffs;
  425. }
  426. if (shorttext.length === 1) {
  427. return [createDiff(DIFF_DELETE, text1), createDiff(DIFF_INSERT, text2)];
  428. }
  429. const hm = diffHalfMatch(text1, text2, options);
  430. if (hm) {
  431. const text1_a = hm[0];
  432. const text1_b = hm[1];
  433. const text2_a = hm[2];
  434. const text2_b = hm[3];
  435. const mid_common = hm[4];
  436. const diffs_a = diffMain(text1_a, text2_a, options, checklines, deadline);
  437. const diffs_b = diffMain(text1_b, text2_b, options, checklines, deadline);
  438. return diffs_a.concat([createDiff(DIFF_EQUAL, mid_common)], diffs_b);
  439. }
  440. if (checklines && text1.length > 100 && text2.length > 100)
  441. return diffLineMode(text1, text2, options, deadline);
  442. return diffBisect(text1, text2, options, deadline);
  443. }
  444. function diffLineMode(text1, text2, options, deadline) {
  445. const a = diffLinesToChars(text1, text2);
  446. text1 = a.chars1;
  447. text2 = a.chars2;
  448. const linearray = a.lineArray;
  449. const diffs = diffMain(text1, text2, options, false, deadline);
  450. diffCharsToLines(diffs, linearray);
  451. diffCleanupSemantic(diffs);
  452. diffs.push(createDiff(DIFF_EQUAL, ""));
  453. let pointer = 0;
  454. let count_delete = 0;
  455. let count_insert = 0;
  456. let text_delete = "";
  457. let text_insert = "";
  458. while (pointer < diffs.length) {
  459. switch (diffs[pointer][0]) {
  460. case DIFF_INSERT:
  461. count_insert++;
  462. text_insert += diffs[pointer][1];
  463. break;
  464. case DIFF_DELETE:
  465. count_delete++;
  466. text_delete += diffs[pointer][1];
  467. break;
  468. case DIFF_EQUAL:
  469. if (count_delete >= 1 && count_insert >= 1) {
  470. diffs.splice(pointer - count_delete - count_insert, count_delete + count_insert);
  471. pointer = pointer - count_delete - count_insert;
  472. const subDiff = diffMain(text_delete, text_insert, options, false, deadline);
  473. for (let j = subDiff.length - 1; j >= 0; j--)
  474. diffs.splice(pointer, 0, subDiff[j]);
  475. pointer = pointer + subDiff.length;
  476. }
  477. count_insert = 0;
  478. count_delete = 0;
  479. text_delete = "";
  480. text_insert = "";
  481. break;
  482. }
  483. pointer++;
  484. }
  485. diffs.pop();
  486. return diffs;
  487. }
  488. function diffBisect(text1, text2, options, deadline) {
  489. const text1_length = text1.length;
  490. const text2_length = text2.length;
  491. const max_d = Math.ceil((text1_length + text2_length) / 2);
  492. const v_offset = max_d;
  493. const v_length = 2 * max_d;
  494. const v1 = new Array(v_length);
  495. const v2 = new Array(v_length);
  496. for (let x = 0; x < v_length; x++) {
  497. v1[x] = -1;
  498. v2[x] = -1;
  499. }
  500. v1[v_offset + 1] = 0;
  501. v2[v_offset + 1] = 0;
  502. const delta = text1_length - text2_length;
  503. const front = delta % 2 !== 0;
  504. let k1start = 0;
  505. let k1end = 0;
  506. let k2start = 0;
  507. let k2end = 0;
  508. for (let d = 0; d < max_d; d++) {
  509. if ((/* @__PURE__ */ new Date()).getTime() > deadline)
  510. break;
  511. for (let k1 = -d + k1start; k1 <= d - k1end; k1 += 2) {
  512. const k1_offset = v_offset + k1;
  513. let x1;
  514. if (k1 === -d || k1 !== d && v1[k1_offset - 1] < v1[k1_offset + 1])
  515. x1 = v1[k1_offset + 1];
  516. else
  517. x1 = v1[k1_offset - 1] + 1;
  518. let y1 = x1 - k1;
  519. while (x1 < text1_length && y1 < text2_length && text1.charAt(x1) === text2.charAt(y1)) {
  520. x1++;
  521. y1++;
  522. }
  523. v1[k1_offset] = x1;
  524. if (x1 > text1_length) {
  525. k1end += 2;
  526. } else if (y1 > text2_length) {
  527. k1start += 2;
  528. } else if (front) {
  529. const k2_offset = v_offset + delta - k1;
  530. if (k2_offset >= 0 && k2_offset < v_length && v2[k2_offset] !== -1) {
  531. const x2 = text1_length - v2[k2_offset];
  532. if (x1 >= x2) {
  533. return diffBisectSplit(text1, text2, options, x1, y1, deadline);
  534. }
  535. }
  536. }
  537. }
  538. for (let k2 = -d + k2start; k2 <= d - k2end; k2 += 2) {
  539. const k2_offset = v_offset + k2;
  540. let x2;
  541. if (k2 === -d || k2 !== d && v2[k2_offset - 1] < v2[k2_offset + 1])
  542. x2 = v2[k2_offset + 1];
  543. else
  544. x2 = v2[k2_offset - 1] + 1;
  545. let y2 = x2 - k2;
  546. while (x2 < text1_length && y2 < text2_length && text1.charAt(text1_length - x2 - 1) === text2.charAt(text2_length - y2 - 1)) {
  547. x2++;
  548. y2++;
  549. }
  550. v2[k2_offset] = x2;
  551. if (x2 > text1_length) {
  552. k2end += 2;
  553. } else if (y2 > text2_length) {
  554. k2start += 2;
  555. } else if (!front) {
  556. const k1_offset = v_offset + delta - k2;
  557. if (k1_offset >= 0 && k1_offset < v_length && v1[k1_offset] !== -1) {
  558. const x1 = v1[k1_offset];
  559. const y1 = v_offset + x1 - k1_offset;
  560. x2 = text1_length - x2;
  561. if (x1 >= x2) {
  562. return diffBisectSplit(text1, text2, options, x1, y1, deadline);
  563. }
  564. }
  565. }
  566. }
  567. }
  568. return [createDiff(DIFF_DELETE, text1), createDiff(DIFF_INSERT, text2)];
  569. }
  570. function diffBisectSplit(text1, text2, options, x, y, deadline) {
  571. const text1a = text1.substring(0, x);
  572. const text2a = text2.substring(0, y);
  573. const text1b = text1.substring(x);
  574. const text2b = text2.substring(y);
  575. const diffs = diffMain(text1a, text2a, options, false, deadline);
  576. const diffsb = diffMain(text1b, text2b, options, false, deadline);
  577. return diffs.concat(diffsb);
  578. }
  579. function diffLinesToChars(text1, text2) {
  580. const lineArray = [];
  581. const lineHash = {};
  582. let maxLines = 4e4;
  583. lineArray[0] = "";
  584. function diffLinesToCharsMunge(text) {
  585. let chars = "";
  586. let lineStart = 0;
  587. let lineEnd = -1;
  588. let lineArrayLength = lineArray.length;
  589. while (lineEnd < text.length - 1) {
  590. lineEnd = text.indexOf("\n", lineStart);
  591. if (lineEnd === -1)
  592. lineEnd = text.length - 1;
  593. let line = text.substring(lineStart, lineEnd + 1);
  594. if (lineHash.hasOwnProperty ? Object.prototype.hasOwnProperty.call(lineHash, line) : lineHash[line] !== void 0) {
  595. chars += String.fromCharCode(lineHash[line]);
  596. } else {
  597. if (lineArrayLength === maxLines) {
  598. line = text.substring(lineStart);
  599. lineEnd = text.length;
  600. }
  601. chars += String.fromCharCode(lineArrayLength);
  602. lineHash[line] = lineArrayLength;
  603. lineArray[lineArrayLength++] = line;
  604. }
  605. lineStart = lineEnd + 1;
  606. }
  607. return chars;
  608. }
  609. const chars1 = diffLinesToCharsMunge(text1);
  610. maxLines = 65535;
  611. const chars2 = diffLinesToCharsMunge(text2);
  612. return { chars1, chars2, lineArray };
  613. }
  614. function diffCharsToLines(diffs, lineArray) {
  615. for (let i = 0; i < diffs.length; i++) {
  616. const chars = diffs[i][1];
  617. const text = [];
  618. for (let j = 0; j < chars.length; j++)
  619. text[j] = lineArray[chars.charCodeAt(j)];
  620. diffs[i][1] = text.join("");
  621. }
  622. }
  623. function diffCommonPrefix(text1, text2) {
  624. if (!text1 || !text2 || text1.charAt(0) !== text2.charAt(0))
  625. return 0;
  626. let pointermin = 0;
  627. let pointermax = Math.min(text1.length, text2.length);
  628. let pointermid = pointermax;
  629. let pointerstart = 0;
  630. while (pointermin < pointermid) {
  631. if (text1.substring(pointerstart, pointermid) === text2.substring(pointerstart, pointermid)) {
  632. pointermin = pointermid;
  633. pointerstart = pointermin;
  634. } else {
  635. pointermax = pointermid;
  636. }
  637. pointermid = Math.floor((pointermax - pointermin) / 2 + pointermin);
  638. }
  639. return pointermid;
  640. }
  641. function diffCommonSuffix(text1, text2) {
  642. if (!text1 || !text2 || text1.charAt(text1.length - 1) !== text2.charAt(text2.length - 1)) {
  643. return 0;
  644. }
  645. let pointermin = 0;
  646. let pointermax = Math.min(text1.length, text2.length);
  647. let pointermid = pointermax;
  648. let pointerend = 0;
  649. while (pointermin < pointermid) {
  650. if (text1.substring(text1.length - pointermid, text1.length - pointerend) === text2.substring(text2.length - pointermid, text2.length - pointerend)) {
  651. pointermin = pointermid;
  652. pointerend = pointermin;
  653. } else {
  654. pointermax = pointermid;
  655. }
  656. pointermid = Math.floor((pointermax - pointermin) / 2 + pointermin);
  657. }
  658. return pointermid;
  659. }
  660. function diffCommonOverlap(text1, text2) {
  661. const text1_length = text1.length;
  662. const text2_length = text2.length;
  663. if (text1_length === 0 || text2_length === 0)
  664. return 0;
  665. if (text1_length > text2_length)
  666. text1 = text1.substring(text1_length - text2_length);
  667. else if (text1_length < text2_length)
  668. text2 = text2.substring(0, text1_length);
  669. const text_length = Math.min(text1_length, text2_length);
  670. if (text1 === text2)
  671. return text_length;
  672. let best = 0;
  673. let length = 1;
  674. while (true) {
  675. const pattern = text1.substring(text_length - length);
  676. const found = text2.indexOf(pattern);
  677. if (found === -1)
  678. return best;
  679. length += found;
  680. if (found === 0 || text1.substring(text_length - length) === text2.substring(0, length)) {
  681. best = length;
  682. length++;
  683. }
  684. }
  685. }
  686. function diffHalfMatch(text1, text2, options) {
  687. if (options.diffTimeout <= 0) {
  688. return null;
  689. }
  690. const longtext = text1.length > text2.length ? text1 : text2;
  691. const shorttext = text1.length > text2.length ? text2 : text1;
  692. if (longtext.length < 4 || shorttext.length * 2 < longtext.length)
  693. return null;
  694. function diffHalfMatchI(longtext2, shorttext2, i) {
  695. const seed = longtext2.substring(i, i + Math.floor(longtext2.length / 4));
  696. let j = -1;
  697. let best_common = "";
  698. let best_longtext_a, best_longtext_b, best_shorttext_a, best_shorttext_b;
  699. while ((j = shorttext2.indexOf(seed, j + 1)) !== -1) {
  700. const prefixLength = diffCommonPrefix(longtext2.substring(i), shorttext2.substring(j));
  701. const suffixLength = diffCommonSuffix(longtext2.substring(0, i), shorttext2.substring(0, j));
  702. if (best_common.length < suffixLength + prefixLength) {
  703. best_common = shorttext2.substring(j - suffixLength, j) + shorttext2.substring(j, j + prefixLength);
  704. best_longtext_a = longtext2.substring(0, i - suffixLength);
  705. best_longtext_b = longtext2.substring(i + prefixLength);
  706. best_shorttext_a = shorttext2.substring(0, j - suffixLength);
  707. best_shorttext_b = shorttext2.substring(j + prefixLength);
  708. }
  709. }
  710. if (best_common.length * 2 >= longtext2.length)
  711. return [best_longtext_a, best_longtext_b, best_shorttext_a, best_shorttext_b, best_common];
  712. else
  713. return null;
  714. }
  715. const hm1 = diffHalfMatchI(longtext, shorttext, Math.ceil(longtext.length / 4));
  716. const hm2 = diffHalfMatchI(longtext, shorttext, Math.ceil(longtext.length / 2));
  717. let hm;
  718. if (!hm1 && !hm2) {
  719. return null;
  720. } else if (!hm2) {
  721. hm = hm1;
  722. } else if (!hm1) {
  723. hm = hm2;
  724. } else {
  725. hm = hm1[4].length > hm2[4].length ? hm1 : hm2;
  726. }
  727. let text1_a, text1_b, text2_a, text2_b;
  728. if (text1.length > text2.length) {
  729. text1_a = hm[0];
  730. text1_b = hm[1];
  731. text2_a = hm[2];
  732. text2_b = hm[3];
  733. } else {
  734. text2_a = hm[0];
  735. text2_b = hm[1];
  736. text1_a = hm[2];
  737. text1_b = hm[3];
  738. }
  739. const mid_common = hm[4];
  740. return [text1_a, text1_b, text2_a, text2_b, mid_common];
  741. }
  742. function diffCleanupSemantic(diffs) {
  743. let changes = false;
  744. const equalities = [];
  745. let equalitiesLength = 0;
  746. let lastEquality = null;
  747. let pointer = 0;
  748. let length_insertions1 = 0;
  749. let length_deletions1 = 0;
  750. let length_insertions2 = 0;
  751. let length_deletions2 = 0;
  752. while (pointer < diffs.length) {
  753. if (diffs[pointer][0] === DIFF_EQUAL) {
  754. equalities[equalitiesLength++] = pointer;
  755. length_insertions1 = length_insertions2;
  756. length_deletions1 = length_deletions2;
  757. length_insertions2 = 0;
  758. length_deletions2 = 0;
  759. lastEquality = diffs[pointer][1];
  760. } else {
  761. if (diffs[pointer][0] === DIFF_INSERT)
  762. length_insertions2 += diffs[pointer][1].length;
  763. else
  764. length_deletions2 += diffs[pointer][1].length;
  765. if (lastEquality && lastEquality.length <= Math.max(length_insertions1, length_deletions1) && lastEquality.length <= Math.max(length_insertions2, length_deletions2)) {
  766. diffs.splice(equalities[equalitiesLength - 1], 0, createDiff(DIFF_DELETE, lastEquality));
  767. diffs[equalities[equalitiesLength - 1] + 1][0] = DIFF_INSERT;
  768. equalitiesLength--;
  769. equalitiesLength--;
  770. pointer = equalitiesLength > 0 ? equalities[equalitiesLength - 1] : -1;
  771. length_insertions1 = 0;
  772. length_deletions1 = 0;
  773. length_insertions2 = 0;
  774. length_deletions2 = 0;
  775. lastEquality = null;
  776. changes = true;
  777. }
  778. }
  779. pointer++;
  780. }
  781. if (changes)
  782. diffCleanupMerge(diffs);
  783. diffCleanupSemanticLossless(diffs);
  784. pointer = 1;
  785. while (pointer < diffs.length) {
  786. if (diffs[pointer - 1][0] === DIFF_DELETE && diffs[pointer][0] === DIFF_INSERT) {
  787. const deletion = diffs[pointer - 1][1];
  788. const insertion = diffs[pointer][1];
  789. const overlap_length1 = diffCommonOverlap(deletion, insertion);
  790. const overlap_length2 = diffCommonOverlap(insertion, deletion);
  791. if (overlap_length1 >= overlap_length2) {
  792. if (overlap_length1 >= deletion.length / 2 || overlap_length1 >= insertion.length / 2) {
  793. diffs.splice(pointer, 0, createDiff(DIFF_EQUAL, insertion.substring(0, overlap_length1)));
  794. diffs[pointer - 1][1] = deletion.substring(0, deletion.length - overlap_length1);
  795. diffs[pointer + 1][1] = insertion.substring(overlap_length1);
  796. pointer++;
  797. }
  798. } else {
  799. if (overlap_length2 >= deletion.length / 2 || overlap_length2 >= insertion.length / 2) {
  800. diffs.splice(pointer, 0, createDiff(DIFF_EQUAL, deletion.substring(0, overlap_length2)));
  801. diffs[pointer - 1][0] = DIFF_INSERT;
  802. diffs[pointer - 1][1] = insertion.substring(0, insertion.length - overlap_length2);
  803. diffs[pointer + 1][0] = DIFF_DELETE;
  804. diffs[pointer + 1][1] = deletion.substring(overlap_length2);
  805. pointer++;
  806. }
  807. }
  808. pointer++;
  809. }
  810. pointer++;
  811. }
  812. }
  813. const nonAlphaNumericRegex_ = /[^a-z0-9]/i;
  814. const whitespaceRegex_ = /\s/;
  815. const linebreakRegex_ = /[\r\n]/;
  816. const blanklineEndRegex_ = /\n\r?\n$/;
  817. const blanklineStartRegex_ = /^\r?\n\r?\n/;
  818. function diffCleanupSemanticLossless(diffs) {
  819. function diffCleanupSemanticScore(one, two) {
  820. if (!one || !two) {
  821. return 6;
  822. }
  823. const char1 = one.charAt(one.length - 1);
  824. const char2 = two.charAt(0);
  825. const nonAlphaNumeric1 = char1.match(nonAlphaNumericRegex_);
  826. const nonAlphaNumeric2 = char2.match(nonAlphaNumericRegex_);
  827. const whitespace1 = nonAlphaNumeric1 && char1.match(whitespaceRegex_);
  828. const whitespace2 = nonAlphaNumeric2 && char2.match(whitespaceRegex_);
  829. const lineBreak1 = whitespace1 && char1.match(linebreakRegex_);
  830. const lineBreak2 = whitespace2 && char2.match(linebreakRegex_);
  831. const blankLine1 = lineBreak1 && one.match(blanklineEndRegex_);
  832. const blankLine2 = lineBreak2 && two.match(blanklineStartRegex_);
  833. if (blankLine1 || blankLine2) {
  834. return 5;
  835. } else if (lineBreak1 || lineBreak2) {
  836. return 4;
  837. } else if (nonAlphaNumeric1 && !whitespace1 && whitespace2) {
  838. return 3;
  839. } else if (whitespace1 || whitespace2) {
  840. return 2;
  841. } else if (nonAlphaNumeric1 || nonAlphaNumeric2) {
  842. return 1;
  843. }
  844. return 0;
  845. }
  846. let pointer = 1;
  847. while (pointer < diffs.length - 1) {
  848. if (diffs[pointer - 1][0] === DIFF_EQUAL && diffs[pointer + 1][0] === DIFF_EQUAL) {
  849. let equality1 = diffs[pointer - 1][1];
  850. let edit = diffs[pointer][1];
  851. let equality2 = diffs[pointer + 1][1];
  852. const commonOffset = diffCommonSuffix(equality1, edit);
  853. if (commonOffset) {
  854. const commonString = edit.substring(edit.length - commonOffset);
  855. equality1 = equality1.substring(0, equality1.length - commonOffset);
  856. edit = commonString + edit.substring(0, edit.length - commonOffset);
  857. equality2 = commonString + equality2;
  858. }
  859. let bestEquality1 = equality1;
  860. let bestEdit = edit;
  861. let bestEquality2 = equality2;
  862. let bestScore = diffCleanupSemanticScore(equality1, edit) + diffCleanupSemanticScore(edit, equality2);
  863. while (edit.charAt(0) === equality2.charAt(0)) {
  864. equality1 += edit.charAt(0);
  865. edit = edit.substring(1) + equality2.charAt(0);
  866. equality2 = equality2.substring(1);
  867. const score = diffCleanupSemanticScore(equality1, edit) + diffCleanupSemanticScore(edit, equality2);
  868. if (score >= bestScore) {
  869. bestScore = score;
  870. bestEquality1 = equality1;
  871. bestEdit = edit;
  872. bestEquality2 = equality2;
  873. }
  874. }
  875. if (diffs[pointer - 1][1] !== bestEquality1) {
  876. if (bestEquality1) {
  877. diffs[pointer - 1][1] = bestEquality1;
  878. } else {
  879. diffs.splice(pointer - 1, 1);
  880. pointer--;
  881. }
  882. diffs[pointer][1] = bestEdit;
  883. if (bestEquality2) {
  884. diffs[pointer + 1][1] = bestEquality2;
  885. } else {
  886. diffs.splice(pointer + 1, 1);
  887. pointer--;
  888. }
  889. }
  890. }
  891. pointer++;
  892. }
  893. }
  894. function diffCleanupMerge(diffs) {
  895. diffs.push(createDiff(DIFF_EQUAL, ""));
  896. let pointer = 0;
  897. let count_delete = 0;
  898. let count_insert = 0;
  899. let text_delete = "";
  900. let text_insert = "";
  901. let commonlength;
  902. while (pointer < diffs.length) {
  903. switch (diffs[pointer][0]) {
  904. case DIFF_INSERT:
  905. count_insert++;
  906. text_insert += diffs[pointer][1];
  907. pointer++;
  908. break;
  909. case DIFF_DELETE:
  910. count_delete++;
  911. text_delete += diffs[pointer][1];
  912. pointer++;
  913. break;
  914. case DIFF_EQUAL:
  915. if (count_delete + count_insert > 1) {
  916. if (count_delete !== 0 && count_insert !== 0) {
  917. commonlength = diffCommonPrefix(text_insert, text_delete);
  918. if (commonlength !== 0) {
  919. if (pointer - count_delete - count_insert > 0 && diffs[pointer - count_delete - count_insert - 1][0] === DIFF_EQUAL) {
  920. diffs[pointer - count_delete - count_insert - 1][1] += text_insert.substring(0, commonlength);
  921. } else {
  922. diffs.splice(0, 0, createDiff(DIFF_EQUAL, text_insert.substring(0, commonlength)));
  923. pointer++;
  924. }
  925. text_insert = text_insert.substring(commonlength);
  926. text_delete = text_delete.substring(commonlength);
  927. }
  928. commonlength = diffCommonSuffix(text_insert, text_delete);
  929. if (commonlength !== 0) {
  930. diffs[pointer][1] = text_insert.substring(text_insert.length - commonlength) + diffs[pointer][1];
  931. text_insert = text_insert.substring(0, text_insert.length - commonlength);
  932. text_delete = text_delete.substring(0, text_delete.length - commonlength);
  933. }
  934. }
  935. pointer -= count_delete + count_insert;
  936. diffs.splice(pointer, count_delete + count_insert);
  937. if (text_delete.length) {
  938. diffs.splice(pointer, 0, createDiff(DIFF_DELETE, text_delete));
  939. pointer++;
  940. }
  941. if (text_insert.length) {
  942. diffs.splice(pointer, 0, createDiff(DIFF_INSERT, text_insert));
  943. pointer++;
  944. }
  945. pointer++;
  946. } else if (pointer !== 0 && diffs[pointer - 1][0] === DIFF_EQUAL) {
  947. diffs[pointer - 1][1] += diffs[pointer][1];
  948. diffs.splice(pointer, 1);
  949. } else {
  950. pointer++;
  951. }
  952. count_insert = 0;
  953. count_delete = 0;
  954. text_delete = "";
  955. text_insert = "";
  956. break;
  957. }
  958. }
  959. if (diffs[diffs.length - 1][1] === "")
  960. diffs.pop();
  961. let changes = false;
  962. pointer = 1;
  963. while (pointer < diffs.length - 1) {
  964. if (diffs[pointer - 1][0] === DIFF_EQUAL && diffs[pointer + 1][0] === DIFF_EQUAL) {
  965. if (diffs[pointer][1].substring(diffs[pointer][1].length - diffs[pointer - 1][1].length) === diffs[pointer - 1][1]) {
  966. diffs[pointer][1] = diffs[pointer - 1][1] + diffs[pointer][1].substring(0, diffs[pointer][1].length - diffs[pointer - 1][1].length);
  967. diffs[pointer + 1][1] = diffs[pointer - 1][1] + diffs[pointer + 1][1];
  968. diffs.splice(pointer - 1, 1);
  969. changes = true;
  970. } else if (diffs[pointer][1].substring(0, diffs[pointer + 1][1].length) === diffs[pointer + 1][1]) {
  971. diffs[pointer - 1][1] += diffs[pointer + 1][1];
  972. diffs[pointer][1] = diffs[pointer][1].substring(diffs[pointer + 1][1].length) + diffs[pointer + 1][1];
  973. diffs.splice(pointer + 1, 1);
  974. changes = true;
  975. }
  976. }
  977. pointer++;
  978. }
  979. if (changes)
  980. diffCleanupMerge(diffs);
  981. }
  982. function calculateDiff(left, right) {
  983. const changes = diffMain(left, right);
  984. diffCleanupSemantic(changes);
  985. return changes;
  986. }
  987. const exports$1 = {
  988. calculateDiff
  989. };
  990. expose(exports$1);
  991. })();