linked-list.class.js 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490
  1. /**
  2. * @fileoverview added by tsickle
  3. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  4. */
  5. /**
  6. * @template T
  7. */
  8. var /**
  9. * @template T
  10. */
  11. LinkedList = /** @class */ (function () {
  12. function LinkedList() {
  13. this.length = 0;
  14. this.asArray = [];
  15. // Array methods overriding END
  16. }
  17. /**
  18. * @param {?} position
  19. * @return {?}
  20. */
  21. LinkedList.prototype.get = /**
  22. * @param {?} position
  23. * @return {?}
  24. */
  25. function (position) {
  26. if (this.length === 0 || position < 0 || position >= this.length) {
  27. return void 0;
  28. }
  29. /** @type {?} */
  30. var current = this.head;
  31. for (var index = 0; index < position; index++) {
  32. current = current.next;
  33. }
  34. return current.value;
  35. };
  36. /**
  37. * @param {?} value
  38. * @param {?=} position
  39. * @return {?}
  40. */
  41. LinkedList.prototype.add = /**
  42. * @param {?} value
  43. * @param {?=} position
  44. * @return {?}
  45. */
  46. function (value, position) {
  47. if (position === void 0) { position = this.length; }
  48. if (position < 0 || position > this.length) {
  49. throw new Error('Position is out of the list');
  50. }
  51. /* tslint:disable-next-line: no-any*/
  52. /** @type {?} */
  53. var node = {
  54. value: value,
  55. next: undefined,
  56. previous: undefined
  57. };
  58. if (this.length === 0) {
  59. this.head = node;
  60. this.tail = node;
  61. this.current = node;
  62. }
  63. else {
  64. if (position === 0) {
  65. // first node
  66. node.next = this.head;
  67. this.head.previous = node;
  68. this.head = node;
  69. }
  70. else if (position === this.length) {
  71. // last node
  72. this.tail.next = node;
  73. node.previous = this.tail;
  74. this.tail = node;
  75. }
  76. else {
  77. // node in middle
  78. /** @type {?} */
  79. var currentPreviousNode = this.getNode(position - 1);
  80. /** @type {?} */
  81. var currentNextNode = currentPreviousNode.next;
  82. currentPreviousNode.next = node;
  83. currentNextNode.previous = node;
  84. node.previous = currentPreviousNode;
  85. node.next = currentNextNode;
  86. }
  87. }
  88. this.length++;
  89. this.createInternalArrayRepresentation();
  90. };
  91. /**
  92. * @param {?=} position
  93. * @return {?}
  94. */
  95. LinkedList.prototype.remove = /**
  96. * @param {?=} position
  97. * @return {?}
  98. */
  99. function (position) {
  100. if (position === void 0) { position = 0; }
  101. if (this.length === 0 || position < 0 || position >= this.length) {
  102. throw new Error('Position is out of the list');
  103. }
  104. if (position === 0) {
  105. // first node
  106. this.head = this.head.next;
  107. if (this.head) {
  108. // there is no second node
  109. this.head.previous = undefined;
  110. }
  111. else {
  112. // there is no second node
  113. this.tail = undefined;
  114. }
  115. }
  116. else if (position === this.length - 1) {
  117. // last node
  118. this.tail = this.tail.previous;
  119. this.tail.next = undefined;
  120. }
  121. else {
  122. // middle node
  123. /** @type {?} */
  124. var removedNode = this.getNode(position);
  125. removedNode.next.previous = removedNode.previous;
  126. removedNode.previous.next = removedNode.next;
  127. }
  128. this.length--;
  129. this.createInternalArrayRepresentation();
  130. };
  131. /**
  132. * @param {?} position
  133. * @param {?} value
  134. * @return {?}
  135. */
  136. LinkedList.prototype.set = /**
  137. * @param {?} position
  138. * @param {?} value
  139. * @return {?}
  140. */
  141. function (position, value) {
  142. if (this.length === 0 || position < 0 || position >= this.length) {
  143. throw new Error('Position is out of the list');
  144. }
  145. /** @type {?} */
  146. var node = this.getNode(position);
  147. node.value = value;
  148. this.createInternalArrayRepresentation();
  149. };
  150. /**
  151. * @return {?}
  152. */
  153. LinkedList.prototype.toArray = /**
  154. * @return {?}
  155. */
  156. function () {
  157. return this.asArray;
  158. };
  159. /* tslint:disable-next-line: no-any*/
  160. /* tslint:disable-next-line: no-any*/
  161. /**
  162. * @param {?} fn
  163. * @return {?}
  164. */
  165. LinkedList.prototype.findAll = /* tslint:disable-next-line: no-any*/
  166. /**
  167. * @param {?} fn
  168. * @return {?}
  169. */
  170. function (fn) {
  171. /** @type {?} */
  172. var current = this.head;
  173. /* tslint:disable-next-line: no-any*/
  174. /** @type {?} */
  175. var result = [];
  176. for (var index = 0; index < this.length; index++) {
  177. if (fn(current.value, index)) {
  178. result.push({ index: index, value: current.value });
  179. }
  180. current = current.next;
  181. }
  182. return result;
  183. };
  184. // Array methods overriding start
  185. // Array methods overriding start
  186. /**
  187. * @param {...?} args
  188. * @return {?}
  189. */
  190. LinkedList.prototype.push =
  191. // Array methods overriding start
  192. /**
  193. * @param {...?} args
  194. * @return {?}
  195. */
  196. function () {
  197. var _this = this;
  198. var args = [];
  199. for (var _i = 0; _i < arguments.length; _i++) {
  200. args[_i] = arguments[_i];
  201. }
  202. /* tslint:disable-next-line: no-any*/
  203. args.forEach((/**
  204. * @param {?} arg
  205. * @return {?}
  206. */
  207. function (arg) {
  208. _this.add(arg);
  209. }));
  210. return this.length;
  211. };
  212. /**
  213. * @return {?}
  214. */
  215. LinkedList.prototype.pop = /**
  216. * @return {?}
  217. */
  218. function () {
  219. if (this.length === 0) {
  220. return undefined;
  221. }
  222. /** @type {?} */
  223. var last = this.tail;
  224. this.remove(this.length - 1);
  225. return last.value;
  226. };
  227. /**
  228. * @param {...?} args
  229. * @return {?}
  230. */
  231. LinkedList.prototype.unshift = /**
  232. * @param {...?} args
  233. * @return {?}
  234. */
  235. function () {
  236. var _this = this;
  237. var args = [];
  238. for (var _i = 0; _i < arguments.length; _i++) {
  239. args[_i] = arguments[_i];
  240. }
  241. args.reverse();
  242. /* tslint:disable-next-line: no-any*/
  243. args.forEach((/**
  244. * @param {?} arg
  245. * @return {?}
  246. */
  247. function (arg) {
  248. _this.add(arg, 0);
  249. }));
  250. return this.length;
  251. };
  252. /**
  253. * @return {?}
  254. */
  255. LinkedList.prototype.shift = /**
  256. * @return {?}
  257. */
  258. function () {
  259. if (this.length === 0) {
  260. return undefined;
  261. }
  262. /** @type {?} */
  263. var lastItem = this.head.value;
  264. this.remove();
  265. return lastItem;
  266. };
  267. /* tslint:disable-next-line: no-any*/
  268. /* tslint:disable-next-line: no-any*/
  269. /**
  270. * @param {?} fn
  271. * @return {?}
  272. */
  273. LinkedList.prototype.forEach = /* tslint:disable-next-line: no-any*/
  274. /**
  275. * @param {?} fn
  276. * @return {?}
  277. */
  278. function (fn) {
  279. /** @type {?} */
  280. var current = this.head;
  281. for (var index = 0; index < this.length; index++) {
  282. fn(current.value, index);
  283. current = current.next;
  284. }
  285. };
  286. /**
  287. * @param {?} value
  288. * @return {?}
  289. */
  290. LinkedList.prototype.indexOf = /**
  291. * @param {?} value
  292. * @return {?}
  293. */
  294. function (value) {
  295. /** @type {?} */
  296. var current = this.head;
  297. /** @type {?} */
  298. var position = 0;
  299. for (var index = 0; index < this.length; index++) {
  300. if (current.value === value) {
  301. position = index;
  302. break;
  303. }
  304. current = current.next;
  305. }
  306. return position;
  307. };
  308. /* tslint:disable-next-line: no-any*/
  309. /* tslint:disable-next-line: no-any*/
  310. /**
  311. * @param {?} fn
  312. * @return {?}
  313. */
  314. LinkedList.prototype.some = /* tslint:disable-next-line: no-any*/
  315. /**
  316. * @param {?} fn
  317. * @return {?}
  318. */
  319. function (fn) {
  320. /** @type {?} */
  321. var current = this.head;
  322. /** @type {?} */
  323. var result = false;
  324. while (current && !result) {
  325. if (fn(current.value)) {
  326. result = true;
  327. break;
  328. }
  329. current = current.next;
  330. }
  331. return result;
  332. };
  333. /* tslint:disable-next-line: no-any*/
  334. /* tslint:disable-next-line: no-any*/
  335. /**
  336. * @param {?} fn
  337. * @return {?}
  338. */
  339. LinkedList.prototype.every = /* tslint:disable-next-line: no-any*/
  340. /**
  341. * @param {?} fn
  342. * @return {?}
  343. */
  344. function (fn) {
  345. /** @type {?} */
  346. var current = this.head;
  347. /** @type {?} */
  348. var result = true;
  349. while (current && result) {
  350. if (!fn(current.value)) {
  351. result = false;
  352. }
  353. current = current.next;
  354. }
  355. return result;
  356. };
  357. /**
  358. * @return {?}
  359. */
  360. LinkedList.prototype.toString = /**
  361. * @return {?}
  362. */
  363. function () {
  364. return '[Linked List]';
  365. };
  366. /* tslint:disable-next-line: no-any*/
  367. /* tslint:disable-next-line: no-any*/
  368. /**
  369. * @param {?} fn
  370. * @return {?}
  371. */
  372. LinkedList.prototype.find = /* tslint:disable-next-line: no-any*/
  373. /**
  374. * @param {?} fn
  375. * @return {?}
  376. */
  377. function (fn) {
  378. /** @type {?} */
  379. var current = this.head;
  380. /** @type {?} */
  381. var result;
  382. for (var index = 0; index < this.length; index++) {
  383. if (fn(current.value, index)) {
  384. result = current.value;
  385. break;
  386. }
  387. current = current.next;
  388. }
  389. return result;
  390. };
  391. /* tslint:disable-next-line: no-any*/
  392. /* tslint:disable-next-line: no-any*/
  393. /**
  394. * @param {?} fn
  395. * @return {?}
  396. */
  397. LinkedList.prototype.findIndex = /* tslint:disable-next-line: no-any*/
  398. /**
  399. * @param {?} fn
  400. * @return {?}
  401. */
  402. function (fn) {
  403. /** @type {?} */
  404. var current = this.head;
  405. /** @type {?} */
  406. var result;
  407. for (var index = 0; index < this.length; index++) {
  408. if (fn(current.value, index)) {
  409. result = index;
  410. break;
  411. }
  412. current = current.next;
  413. }
  414. return result;
  415. };
  416. /* tslint:disable-next-line: no-any*/
  417. /* tslint:disable-next-line: no-any*/
  418. /**
  419. * @protected
  420. * @param {?} position
  421. * @return {?}
  422. */
  423. LinkedList.prototype.getNode = /* tslint:disable-next-line: no-any*/
  424. /**
  425. * @protected
  426. * @param {?} position
  427. * @return {?}
  428. */
  429. function (position) {
  430. if (this.length === 0 || position < 0 || position >= this.length) {
  431. throw new Error('Position is out of the list');
  432. }
  433. /** @type {?} */
  434. var current = this.head;
  435. for (var index = 0; index < position; index++) {
  436. current = current.next;
  437. }
  438. return current;
  439. };
  440. /**
  441. * @protected
  442. * @return {?}
  443. */
  444. LinkedList.prototype.createInternalArrayRepresentation = /**
  445. * @protected
  446. * @return {?}
  447. */
  448. function () {
  449. /* tslint:disable-next-line: no-any*/
  450. /** @type {?} */
  451. var outArray = [];
  452. /** @type {?} */
  453. var current = this.head;
  454. while (current) {
  455. outArray.push(current.value);
  456. current = current.next;
  457. }
  458. this.asArray = outArray;
  459. };
  460. return LinkedList;
  461. }());
  462. /**
  463. * @template T
  464. */
  465. export { LinkedList };
  466. if (false) {
  467. /** @type {?} */
  468. LinkedList.prototype.length;
  469. /**
  470. * @type {?}
  471. * @protected
  472. */
  473. LinkedList.prototype.head;
  474. /**
  475. * @type {?}
  476. * @protected
  477. */
  478. LinkedList.prototype.tail;
  479. /**
  480. * @type {?}
  481. * @protected
  482. */
  483. LinkedList.prototype.current;
  484. /**
  485. * @type {?}
  486. * @protected
  487. */
  488. LinkedList.prototype.asArray;
  489. }
  490. //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGlua2VkLWxpc3QuY2xhc3MuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9uZ3gtYm9vdHN0cmFwL3V0aWxzLyIsInNvdXJjZXMiOlsibGlua2VkLWxpc3QuY2xhc3MudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOzs7O0lBQUE7UUFDRSxXQUFNLEdBQUcsQ0FBQyxDQUFDO1FBT0QsWUFBTyxHQUFRLEVBQUUsQ0FBQztRQWlSNUIsK0JBQStCO0lBQ2pDLENBQUM7Ozs7O0lBaFJDLHdCQUFHOzs7O0lBQUgsVUFBSSxRQUFnQjtRQUNsQixJQUFJLElBQUksQ0FBQyxNQUFNLEtBQUssQ0FBQyxJQUFJLFFBQVEsR0FBRyxDQUFDLElBQUksUUFBUSxJQUFJLElBQUksQ0FBQyxNQUFNLEVBQUU7WUFDaEUsT0FBTyxLQUFLLENBQUMsQ0FBQztTQUNmOztZQUVHLE9BQU8sR0FBRyxJQUFJLENBQUMsSUFBSTtRQUV2QixLQUFLLElBQUksS0FBSyxHQUFHLENBQUMsRUFBRSxLQUFLLEdBQUcsUUFBUSxFQUFFLEtBQUssRUFBRSxFQUFFO1lBQzdDLE9BQU8sR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDO1NBQ3hCO1FBRUQsT0FBTyxPQUFPLENBQUMsS0FBSyxDQUFDO0lBQ3ZCLENBQUM7Ozs7OztJQUVELHdCQUFHOzs7OztJQUFILFVBQUksS0FBUSxFQUFFLFFBQThCO1FBQTlCLHlCQUFBLEVBQUEsV0FBbUIsSUFBSSxDQUFDLE1BQU07UUFDMUMsSUFBSSxRQUFRLEdBQUcsQ0FBQyxJQUFJLFFBQVEsR0FBRyxJQUFJLENBQUMsTUFBTSxFQUFFO1lBQzFDLE1BQU0sSUFBSSxLQUFLLENBQUMsNkJBQTZCLENBQUMsQ0FBQztTQUNoRDs7O1lBR0ssSUFBSSxHQUFRO1lBQ2hCLEtBQUssT0FBQTtZQUNMLElBQUksRUFBRSxTQUFTO1lBQ2YsUUFBUSxFQUFFLFNBQVM7U0FDcEI7UUFFRCxJQUFJLElBQUksQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFO1lBQ3JCLElB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LENBQUMsTUFBTSxLQUFLLENBQUMsSUFBSSxRQUFRLEdBQUcsQ0FBQyxJQUFJLFFBQVEsSUFBSSxJQUFJLENBQUMsTUFBTSxFQUFFO1lBQ2hFLE1BQU0sSUFBSSxLQUFLLENBQUMsNkJBQTZCLENBQUMsQ0FBQztTQUNoRDs7WUFFRyxPQUFPLEdBQUcsSUFBSSxDQUFDLElBQUk7UUFFdkIsS0FBSyxJQUFJLEtBQUssR0FBRyxDQUFDLEVBQUUsS0FBSyxHQUFHLFFBQVEsRUFBRSxLQUFLLEVBQUUsRUFBRTtZQUM3QyxPQUFPLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQztTQUN4QjtRQUVELE9BQU8sT0FBTyxDQUFDO0lBQ2pCLENBQUM7Ozs7O0lBRVMsc0RBQWlDOzs7O0lBQTNDOzs7WUFFUSxRQUFRLEdBQVUsRUFBRTs7WUFDdEIsT0FBTyxHQUFHLElBQUksQ0FBQyxJQUFJO1FBRXZCLE9BQU8sT0FBTyxFQUFFO1lBQ2QsUUFBUSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDN0IsT0FBTyxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUM7U0FDeEI7UUFDRCxJQUFJLENBQUMsT0FBTyxHQUFHLFFBQVEsQ0FBQztJQUMxQixDQUFDO0lBR0gsaUJBQUM7QUFBRCxDQUFDLEFBMVJELElBMFJDOzs7Ozs7O0lBelJDLDRCQUFXOzs7OztJQUVYLDBCQUFvQjs7Ozs7SUFFcEIsMEJBQW9COzs7OztJQUVwQiw2QkFBdUI7Ozs7O0lBQ3ZCLDZCQUE0QiIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCBjbGFzcyBMaW5rZWRMaXN0PFQ+IHtcbiAgbGVuZ3RoID0gMDtcbiAgLyogdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOiBuby1hbnkqL1xuICBwcm90ZWN0ZWQgaGVhZDogYW55O1xuICAvKiB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6IG5vLWFueSovXG4gIHByb3RlY3RlZCB0YWlsOiBhbnk7XG4gIC8qIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTogbm8tYW55Ki9cbiAgcHJvdGVjdGVkIGN1cnJlbnQ6IGFueTtcbiAgcHJvdGVjdGVkIGFzQXJyYXk6IFRbXSA9IFtdO1xuXG4gIGdldChwb3NpdGlvbjogbnVtYmVyKTogVCB7XG4gICAgaWYgKHRoaXMubGVuZ3RoID09PSAwIHx8IHBvc2l0aW9uIDwgMCB8fCBwb3NpdGlvbiA+PSB0aGlzLmxlbmd0aCkge1xuICAgICAgcmV0dXJuIHZvaWQgMDtcbiAgICB9XG5cbiAgICBsZXQgY3VycmVudCA9IHRoaXMuaGVhZDtcblxuICAgIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCBwb3NpdGlvbjsgaW5kZXgrKykge1xuICAgICAgY3VycmVudCA9IGN1cnJlbnQubmV4dDtcbiAgICB9XG5cbiAgICByZXR1cm4gY3VycmVudC52YWx1ZTtcbiAgfVxuXG4gIGFkZCh2YWx1ZTogVCwgcG9zaXRpb246IG51bWJlciA9IHRoaXMubGVuZ3RoKTogdm9pZCB7XG4gICAgaWYgKHBvc2l0aW9uIDwgMCB8fCBwb3NpdGlvbiA+IHRoaXMubGVuZ3RoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1Bvc2l0aW9uIGlzIG91dCBvZiB0aGUgbGlzdCcpO1xuICAgIH1cblxuICAgIC8qIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTogbm8tYW55Ki9cbiAgICBjb25zdCBub2RlOiBhbnkgPSB7XG4gICAgICB2YWx1ZSxcbiAgICAgIG5leHQ6IHVuZGVmaW5lZCxcbiAgICAgIHByZXZpb3VzOiB1bmRlZmluZWRcbiAgICB9O1xuXG4gICAgaWYgKHRoaXMubGVuZ3RoID09PSAwKSB7XG4gICAgICB0aGlzLmhlYWQgPSBub2RlO1xuICAgICAgdGhpcy50YWlsID0gbm9kZTtcbiAgICAgIHRoaXMuY3VycmVudCA9IG5vZGU7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChwb3NpdGlvbiA9PT0gMCkge1xuICAgICAgICAvLyBmaXJzdCBub2RlXG4gICAgICAgIG5vZGUubmV4dCA9IHRoaXMuaGVhZDtcbiAgICAgICAgdGhpcy5oZWFkLnByZXZpb3VzID0gbm9kZTtcbiAgICAgICAgdGhpcy5oZWFkID0gbm9kZTtcbiAgICAgIH0gZWxzZSBpZiAocG9zaXRpb24gPT09IHRoaXMubGVuZ3RoKSB7XG4gICAgICAgIC8vIGxhc3Qgbm9kZVxuICAgICAgICB0aGlzLnRhaWwubmV4dCA9IG5vZGU7XG4gICAgICAgIG5vZGUucHJldmlvdXMgPSB0aGlzLnRhaWw7XG4gICAgICAgIHRoaXMudGFpbCA9IG5vZGU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBub2RlIGluIG1pZGRsZVxuICAgICAgICBjb25zdCBjdXJyZW50UHJldmlvdXNOb2RlID0gdGhpcy5nZXROb2RlKHBvc2l0aW9uIC0gMSk7XG4gICAgICAgIGNvbnN0IGN1cnJlbnROZXh0Tm9kZSA9IGN1cnJlbnRQcmV2aW91c05vZGUubmV4dDtcblxuICAgICAgICBjdXJyZW50UHJldmlvdXNOb2RlLm5leHQgPSBub2RlO1xuICAgICAgICBjdXJyZW50TmV4dE5vZGUucHJldmlvdXMgPSBub2RlO1xuXG4gICAgICAgIG5vZGUucHJldmlvdXMgPSBjdXJyZW50UHJldmlvdXNOb2RlO1xuICAgICAgICBub2RlLm5leHQgPSBjdXJyZW50TmV4dE5vZGU7XG4gICAgICB9XG4gICAgfVxuICAgIHRoaXMubGVuZ3RoKys7XG4gICAgdGhpcy5jcmVhdGVJbnRlcm5hbEFycmF5UmVwcmVzZW50YXRpb24oKTtcbiAgfVxuXG4gIHJlbW92ZShwb3NpdGlvbiA9IDApOiB2b2lkIHtcbiAgICBpZiAodGhpcy5sZW5ndGggPT09IDAgfHwgcG9zaXRpb24gPCAwIHx8IHBvc2l0aW9uID49IHRoaXMubGVuZ3RoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1Bvc2l0aW9uIGlzIG91dCBvZiB0aGUgbGlzdCcpO1xuICAgIH1cblxuICAgIGlmIChwb3NpdGlvbiA9PT0gMCkge1xuICAgICAgLy8gZmlyc3Qgbm9kZVxuICAgICAgdGhpcy5oZWFkID0gdGhpcy5oZWFkLm5leHQ7XG5cbiAgICAgIGlmICh0aGlzLmhlYWQpIHtcbiAgICAgICAgLy8gdGhlcmUgaXMgbm8gc2Vjb25kIG5vZGVcbiAgICAgICAgdGhpcy5oZWFkLnByZXZpb3VzID0gdW5kZWZpbmVkO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gdGhlcmUgaXMgbm8gc2Vjb25kIG5vZGVcbiAgICAgICAgdGhpcy50YWlsID0gdW5kZWZpbmVkO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAocG9zaXRpb24gPT09IHRoaXMubGVuZ3RoIC0gMSkge1xuICAgICAgLy8gbGFzdCBub2RlXG4gICAgICB0aGlzLnRhaWwgPSB0aGlzLnRhaWwucHJldmlvdXM7XG4gICAgICB0aGlzLnRhaWwubmV4dCA9IHVuZGVmaW5lZDtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gbWlkZGxlIG5vZGVcbiAgICAgIGNvbnN0IHJlbW92ZWROb2RlID0gdGhpcy5nZXROb2RlKHBvc2l0aW9uKTtcbiAgICAgIHJlbW92ZWROb2RlLm5leHQucHJldmlvdXMgPSByZW1vdmVkTm9kZS5wcmV2aW91cztcbiAgICAgIHJlbW92ZWROb2RlLnByZXZpb3VzLm5leHQgPSByZW1vdmVkTm9kZS5uZXh0O1xuICAgIH1cblxuICAgIHRoaXMubGVuZ3RoLS07XG4gICAgdGhpcy5jcmVhdGVJbnRlcm5hbEFycmF5UmVwcmVzZW50YXRpb24oKTtcbiAgfVxuXG4gIHNldChwb3NpdGlvbjogbnVtYmVyLCB2YWx1ZTogVCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmxlbmd0aCA9PT0gMCB8fCBwb3NpdGlvbiA8IDAgfHwgcG9zaXRpb24gPj0gdGhpcy5sZW5ndGgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignUG9zaXRpb24gaXMgb3V0IG9mIHRoZSBsaXN0Jyk7XG4gICAgfVxuXG4gICAgY29uc3Qgbm9kZSA9IHRoaXMuZ2V0Tm9kZShwb3NpdGlvbik7XG4gICAgbm9kZS52YWx1ZSA9IHZhbHVlO1xuICAgIHRoaXMuY3JlYXRlSW50ZXJuYWxBcnJheVJlcHJlc2VudGF0aW9uKCk7XG4gIH1cblxuICB0b0FycmF5KCk6IFRbXSB7XG4gICAgcmV0dXJuIHRoaXMuYXNBcnJheTtcbiAgfVxuXG4gIC8qIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTogbm8tYW55Ki9cbiAgZmluZEFsbChmbjogYW55KTogYW55W10ge1xuICAgIGxldCBjdXJyZW50ID0gdGhpcy5oZWFkO1xuICAgIC8qIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTogbm8tYW55Ki9cbiAgICBjb25zdCByZXN1bHQ6IGFueVtdID0gW107XG4gICAgZm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IHRoaXMubGVuZ3RoOyBpbmRleCsrKSB7XG4gICAgICBpZiAoZm4oY3VycmVudC52YWx1ZSwgaW5kZXgpKSB7XG4gICAgICAgIHJlc3VsdC5wdXNoKHtpbmRleCwgdmFsdWU6IGN1cnJlbnQudmFsdWV9KTtcbiAgICAgIH1cbiAgICAgIGN1cnJlbnQgPSBjdXJyZW50Lm5leHQ7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIC8vIEFycmF5IG1ldGhvZHMgb3ZlcnJpZGluZyBzdGFydFxuICBwdXNoKC4uLmFyZ3M6IFRbXSk6IG51bWJlciB7XG4gICAgLyogdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOiBuby1hbnkqL1xuICAgIGFyZ3MuZm9yRWFjaCgoYXJnOiBhbnkpID0+IHtcbiAgICAgIHRoaXMuYWRkKGFyZyk7XG4gICAgfSk7XG5cbiAgICByZXR1cm4gdGhpcy5sZW5ndGg7XG4gIH1cblxuICBwb3AoKTogVCB7XG4gICAgaWYgKHRoaXMubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cbiAgICBjb25zdCBsYXN0ID0gdGhpcy50YWlsO1xuICAgIHRoaXMucmVtb3ZlKHRoaXMubGVuZ3RoIC0gMSk7XG5cbiAgICByZXR1cm4gbGFzdC52YWx1ZTtcbiAgfVxuXG4gIHVuc2hpZnQoLi4uYXJnczogVFtdKTogbnVtYmVyIHtcbiAgICBhcmdzLnJldmVyc2UoKTtcbiAgICAvKiB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6IG5vLWFueSovXG4gICAgYXJncy5mb3JFYWNoKChhcmc6IGFueSkgPT4ge1xuICAgICAgdGhpcy5hZGQoYXJnLCAwKTtcbiAgICB9KTtcblxuICAgIHJldHVybiB0aGlzLmxlbmd0aDtcbiAgfVxuXG4gIHNoaWZ0KCk6IFQge1xuICAgIGlmICh0aGlzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gICAgY29uc3QgbGFzdEl0ZW0gPSB0aGlzLmhlYWQudmFsdWU7XG4gICAgdGhpcy5yZW1vdmUoKTtcblxuICAgIHJldHVybiBsYXN0SXRlbTtcbiAgfVxuXG4gIC8qIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTogbm8tYW55Ki9cbiAgZm9yRWFjaChmbjogYW55KTogdm9pZCB7XG4gICAgbGV0IGN1cnJlbnQgPSB0aGlzLmhlYWQ7XG4gICAgZm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IHRoaXMubGVuZ3RoOyBpbmRleCsrKSB7XG4gICAgICBmbihjdXJyZW50LnZhbHVlLCBpbmRleCk7XG4gICAgICBjdXJyZW50ID0gY3VycmVudC5uZXh0O1xuICAgIH1cbiAgfVxuXG4gIGluZGV4T2YodmFsdWU6IFQpOiBudW1iZXIge1xuICAgIGxldCBjdXJyZW50ID0gdGhpcy5oZWFkO1xuICAgIGxldCBwb3NpdGlvbiA9IDA7XG5cbiAgICBmb3IgKGxldCBpbmRleCA9IDA7IGluZGV4IDwgdGhpcy5sZW5ndGg7IGluZGV4KyspIHtcbiAgICAgIGlmIChjdXJyZW50LnZhbHVlID09PSB2YWx1ZSkge1xuICAgICAgICBwb3NpdGlvbiA9IGluZGV4O1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGN1cnJlbnQgPSBjdXJyZW50Lm5leHQ7XG4gICAgfVxuXG4gICAgcmV0dXJuIHBvc2l0aW9uO1xuICB9XG5cbiAgLyogdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOiBuby1hbnkqL1xuICBzb21lKGZuOiBhbnkpOiBib29sZWFuIHtcbiAgICBsZXQgY3VycmVudCA9IHRoaXMuaGVhZDtcbiAgICBsZXQgcmVzdWx0ID0gZmFsc2U7XG4gICAgd2hpbGUgKGN1cnJlbnQgJiYgIXJlc3VsdCkge1xuICAgICAgaWYgKGZuKGN1cnJlbnQudmFsdWUpKSB7XG4gICAgICAgIHJlc3VsdCA9IHRydWU7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgY3VycmVudCA9IGN1cnJlbnQubmV4dDtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgLyogdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOiBuby1hbnkqL1xuICBldmVyeShmbjogYW55KTogYm9vbGVhbiB7XG4gICAgbGV0IGN1cnJlbnQgPSB0aGlzLmhlYWQ7XG4gICAgbGV0IHJlc3VsdCA9IHRydWU7XG4gICAgd2hpbGUgKGN1cnJlbnQgJiYgcmVzdWx0KSB7XG4gICAgICBpZiAoIWZuKGN1cnJlbnQudmFsdWUpKSB7XG4gICAgICAgIHJlc3VsdCA9IGZhbHNlO1xuICAgICAgfVxuICAgICAgY3VycmVudCA9IGN1cnJlbnQubmV4dDtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgdG9TdHJpbmcoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gJ1tMaW5rZWQgTGlzdF0nO1xuICB9XG5cbiAgLyogdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOiBuby1hbnkqL1xuICBmaW5kKGZuOiBhbnkpOiBUIHtcbiAgICBsZXQgY3VycmVudCA9IHRoaXMuaGVhZDtcbiAgICBsZXQgcmVzdWx0OiBUO1xuICAgIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCB0aGlzLmxlbmd0aDsgaW5kZXgrKykge1xuICAgICAgaWYgKGZuKGN1cnJlbnQudmFsdWUsIGluZGV4KSkge1xuICAgICAgICByZXN1bHQgPSBjdXJyZW50LnZhbHVlO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGN1cnJlbnQgPSBjdXJyZW50Lm5leHQ7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIC8qIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTogbm8tYW55Ki9cbiAgZmluZEluZGV4KGZuOiBhbnkpOiBudW1iZXIge1xuICAgIGxldCBjdXJyZW50ID0gdGhpcy5oZWFkO1xuICAgIGxldCByZXN1bHQ6IG51bWJlcjtcbiAgICBmb3IgKGxldCBpbmRleCA9IDA7IGluZGV4IDwgdGhpcy5sZW5ndGg7IGluZGV4KyspIHtcbiAgICAgIGlmIChmbihjdXJyZW50LnZhbHVlLCBpbmRleCkpIHtcbiAgICAgICAgcmVzdWx0ID0gaW5kZXg7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgY3VycmVudCA9IGN1cnJlbnQubmV4dDtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgLyogdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOiBuby1hbnkqL1xuICBwcm90ZWN0ZWQgZ2V0Tm9kZShwb3NpdGlvbjogbnVtYmVyKTogYW55IHtcbiAgICBpZiAodGhpcy5sZW5ndGggPT09IDAgfHwgcG9zaXRpb24gPCAwIHx8IHBvc2l0aW9uID49IHRoaXMubGVuZ3RoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1Bvc2l0aW9uIGlzIG91dCBvZiB0aGUgbGlzdCcpO1xuICAgIH1cblxuICAgIGxldCBjdXJyZW50ID0gdGhpcy5oZWFkO1xuXG4gICAgZm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IHBvc2l0aW9uOyBpbmRleCsrKSB7XG4gICAgICBjdXJyZW50ID0gY3VycmVudC5uZXh0O1xuICAgIH1cblxuICAgIHJldHVybiBjdXJyZW50O1xuICB9XG5cbiAgcHJvdGVjdGVkIGNyZWF0ZUludGVybmFsQXJyYXlSZXByZXNlbnRhdGlvbigpOiB2b2lkIHtcbiAgICAvKiB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6IG5vLWFueSovXG4gICAgY29uc3Qgb3V0QXJyYXk6IGFueVtdID0gW107XG4gICAgbGV0IGN1cnJlbnQgPSB0aGlzLmhlYWQ7XG5cbiAgICB3aGlsZSAoY3VycmVudCkge1xuICAgICAgb3V0QXJyYXkucHVzaChjdXJyZW50LnZhbHVlKTtcbiAgICAgIGN1cnJlbnQgPSBjdXJyZW50Lm5leHQ7XG4gICAgfVxuICAgIHRoaXMuYXNBcnJheSA9IG91dEFycmF5O1xuICB9XG5cbiAgLy8gQXJyYXkgbWV0aG9kcyBvdmVycmlkaW5nIEVORFxufVxuIl19