dual-list.component.js 82 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970
  1. /**
  2. * @fileoverview added by tsickle
  3. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  4. */
  5. import { Component, EventEmitter, Input, IterableDiffers, Output } from '@angular/core';
  6. import { BasicList } from './basic-list';
  7. /** @type {?} */
  8. var nextId = 0;
  9. var DualListComponent = /** @class */ (function () {
  10. function DualListComponent(differs) {
  11. this.differs = differs;
  12. this.id = "dual-list-" + nextId++;
  13. this.key = '_id';
  14. this.display = '_name';
  15. this.height = '100px';
  16. this.filter = false;
  17. this.format = DualListComponent.DEFAULT_FORMAT;
  18. this.sort = false;
  19. this.disabled = false;
  20. this.destinationChange = new EventEmitter();
  21. this.sorter = (/**
  22. * @param {?} a
  23. * @param {?} b
  24. * @return {?}
  25. */
  26. function (a, b) { return (a._name < b._name) ? -1 : ((a._name > b._name) ? 1 : 0); });
  27. this.available = new BasicList(DualListComponent.AVAILABLE_LIST_NAME);
  28. this.confirmed = new BasicList(DualListComponent.CONFIRMED_LIST_NAME);
  29. }
  30. /**
  31. * @param {?} changeRecord
  32. * @return {?}
  33. */
  34. DualListComponent.prototype.ngOnChanges = /**
  35. * @param {?} changeRecord
  36. * @return {?}
  37. */
  38. function (changeRecord) {
  39. if (changeRecord['filter']) {
  40. if (changeRecord['filter'].currentValue === false) {
  41. this.clearFilter(this.available);
  42. this.clearFilter(this.confirmed);
  43. }
  44. }
  45. if (changeRecord['sort']) {
  46. if (changeRecord['sort'].currentValue === true && this.compare === undefined) {
  47. this.compare = this.sorter;
  48. }
  49. else if (changeRecord['sort'].currentValue === false) {
  50. this.compare = undefined;
  51. }
  52. }
  53. if (changeRecord['format']) {
  54. this.format = changeRecord['format'].currentValue;
  55. if (typeof (this.format.direction) === 'undefined') {
  56. this.format.direction = DualListComponent.LTR;
  57. }
  58. if (typeof (this.format.add) === 'undefined') {
  59. this.format.add = DualListComponent.DEFAULT_FORMAT.add;
  60. }
  61. if (typeof (this.format.remove) === 'undefined') {
  62. this.format.remove = DualListComponent.DEFAULT_FORMAT.remove;
  63. }
  64. if (typeof (this.format.all) === 'undefined') {
  65. this.format.all = DualListComponent.DEFAULT_FORMAT.all;
  66. }
  67. if (typeof (this.format.none) === 'undefined') {
  68. this.format.none = DualListComponent.DEFAULT_FORMAT.none;
  69. }
  70. if (typeof (this.format.draggable) === 'undefined') {
  71. this.format.draggable = DualListComponent.DEFAULT_FORMAT.draggable;
  72. }
  73. }
  74. if (changeRecord['source']) {
  75. this.available = new BasicList(DualListComponent.AVAILABLE_LIST_NAME);
  76. this.updatedSource();
  77. this.updatedDestination();
  78. }
  79. if (changeRecord['destination']) {
  80. this.confirmed = new BasicList(DualListComponent.CONFIRMED_LIST_NAME);
  81. this.updatedDestination();
  82. this.updatedSource();
  83. }
  84. };
  85. /**
  86. * @return {?}
  87. */
  88. DualListComponent.prototype.ngDoCheck = /**
  89. * @return {?}
  90. */
  91. function () {
  92. if (this.source && this.buildAvailable(this.source)) {
  93. this.onFilter(this.available);
  94. }
  95. if (this.destination && this.buildConfirmed(this.destination)) {
  96. this.onFilter(this.confirmed);
  97. }
  98. };
  99. /**
  100. * @param {?} source
  101. * @return {?}
  102. */
  103. DualListComponent.prototype.buildAvailable = /**
  104. * @param {?} source
  105. * @return {?}
  106. */
  107. function (source) {
  108. var _this = this;
  109. /** @type {?} */
  110. var sourceChanges = this.sourceDiffer.diff(source);
  111. if (sourceChanges) {
  112. sourceChanges.forEachRemovedItem((/**
  113. * @param {?} r
  114. * @return {?}
  115. */
  116. function (r) {
  117. /** @type {?} */
  118. var idx = _this.findItemIndex(_this.available.list, r.item, _this.key);
  119. if (idx !== -1) {
  120. _this.available.list.splice(idx, 1);
  121. }
  122. }));
  123. sourceChanges.forEachAddedItem((/**
  124. * @param {?} r
  125. * @return {?}
  126. */
  127. function (r) {
  128. // Do not add duplicates even if source has duplicates.
  129. if (_this.findItemIndex(_this.available.list, r.item, _this.key) === -1) {
  130. _this.available.list.push({ _id: _this.makeId(r.item), _name: _this.makeName(r.item) });
  131. }
  132. }));
  133. if (this.compare !== undefined) {
  134. this.available.list.sort(this.compare);
  135. }
  136. this.available.sift = this.available.list;
  137. return true;
  138. }
  139. return false;
  140. };
  141. /**
  142. * @param {?} destination
  143. * @return {?}
  144. */
  145. DualListComponent.prototype.buildConfirmed = /**
  146. * @param {?} destination
  147. * @return {?}
  148. */
  149. function (destination) {
  150. var _this = this;
  151. /** @type {?} */
  152. var moved = false;
  153. /** @type {?} */
  154. var destChanges = this.destinationDiffer.diff(destination);
  155. if (destChanges) {
  156. destChanges.forEachRemovedItem((/**
  157. * @param {?} r
  158. * @return {?}
  159. */
  160. function (r) {
  161. /** @type {?} */
  162. var idx = _this.findItemIndex(_this.confirmed.list, r.item, _this.key);
  163. if (idx !== -1) {
  164. if (!_this.isItemSelected(_this.confirmed.pick, _this.confirmed.list[idx])) {
  165. _this.selectItem(_this.confirmed.pick, _this.confirmed.list[idx]);
  166. }
  167. _this.moveItem(_this.confirmed, _this.available, _this.confirmed.list[idx], false);
  168. moved = true;
  169. }
  170. }));
  171. destChanges.forEachAddedItem((/**
  172. * @param {?} r
  173. * @return {?}
  174. */
  175. function (r) {
  176. /** @type {?} */
  177. var idx = _this.findItemIndex(_this.available.list, r.item, _this.key);
  178. if (idx !== -1) {
  179. if (!_this.isItemSelected(_this.available.pick, _this.available.list[idx])) {
  180. _this.selectItem(_this.available.pick, _this.available.list[idx]);
  181. }
  182. _this.moveItem(_this.available, _this.confirmed, _this.available.list[idx], false);
  183. moved = true;
  184. }
  185. }));
  186. if (this.compare !== undefined) {
  187. this.confirmed.list.sort(this.compare);
  188. }
  189. this.confirmed.sift = this.confirmed.list;
  190. if (moved) {
  191. this.trueUp();
  192. }
  193. return true;
  194. }
  195. return false;
  196. };
  197. /**
  198. * @return {?}
  199. */
  200. DualListComponent.prototype.updatedSource = /**
  201. * @return {?}
  202. */
  203. function () {
  204. this.available.list.length = 0;
  205. this.available.pick.length = 0;
  206. if (this.source !== undefined) {
  207. this.sourceDiffer = this.differs.find(this.source).create(null);
  208. }
  209. };
  210. /**
  211. * @return {?}
  212. */
  213. DualListComponent.prototype.updatedDestination = /**
  214. * @return {?}
  215. */
  216. function () {
  217. if (this.destination !== undefined) {
  218. this.destinationDiffer = this.differs.find(this.destination).create(null);
  219. }
  220. };
  221. /**
  222. * @return {?}
  223. */
  224. DualListComponent.prototype.direction = /**
  225. * @return {?}
  226. */
  227. function () {
  228. return this.format.direction === DualListComponent.LTR;
  229. };
  230. /**
  231. * @param {?=} list
  232. * @return {?}
  233. */
  234. DualListComponent.prototype.dragEnd = /**
  235. * @param {?=} list
  236. * @return {?}
  237. */
  238. function (list) {
  239. if (list === void 0) { list = null; }
  240. if (list) {
  241. list.dragStart = false;
  242. }
  243. else {
  244. this.available.dragStart = false;
  245. this.confirmed.dragStart = false;
  246. }
  247. return false;
  248. };
  249. /**
  250. * @param {?} event
  251. * @param {?} item
  252. * @param {?} list
  253. * @return {?}
  254. */
  255. DualListComponent.prototype.drag = /**
  256. * @param {?} event
  257. * @param {?} item
  258. * @param {?} list
  259. * @return {?}
  260. */
  261. function (event, item, list) {
  262. if (!this.isItemSelected(list.pick, item)) {
  263. this.selectItem(list.pick, item);
  264. }
  265. list.dragStart = true;
  266. // Set a custom type to be this dual-list's id.
  267. event.dataTransfer.setData(this.id, item['_id']);
  268. };
  269. /**
  270. * @param {?} event
  271. * @param {?} list
  272. * @return {?}
  273. */
  274. DualListComponent.prototype.allowDrop = /**
  275. * @param {?} event
  276. * @param {?} list
  277. * @return {?}
  278. */
  279. function (event, list) {
  280. if (event.dataTransfer.types.length && (event.dataTransfer.types[0] === this.id)) {
  281. event.preventDefault();
  282. if (!list.dragStart) {
  283. list.dragOver = true;
  284. }
  285. }
  286. return false;
  287. };
  288. /**
  289. * @return {?}
  290. */
  291. DualListComponent.prototype.dragLeave = /**
  292. * @return {?}
  293. */
  294. function () {
  295. this.available.dragOver = false;
  296. this.confirmed.dragOver = false;
  297. };
  298. /**
  299. * @param {?} event
  300. * @param {?} list
  301. * @return {?}
  302. */
  303. DualListComponent.prototype.drop = /**
  304. * @param {?} event
  305. * @param {?} list
  306. * @return {?}
  307. */
  308. function (event, list) {
  309. if (event.dataTransfer.types.length && (event.dataTransfer.types[0] === this.id)) {
  310. event.preventDefault();
  311. this.dragLeave();
  312. this.dragEnd();
  313. if (list === this.available) {
  314. this.moveItem(this.available, this.confirmed);
  315. }
  316. else {
  317. this.moveItem(this.confirmed, this.available);
  318. }
  319. }
  320. };
  321. /**
  322. * @private
  323. * @return {?}
  324. */
  325. DualListComponent.prototype.trueUp = /**
  326. * @private
  327. * @return {?}
  328. */
  329. function () {
  330. var _this = this;
  331. /** @type {?} */
  332. var changed = false;
  333. // Clear removed items.
  334. /** @type {?} */
  335. var pos = this.destination.length;
  336. while ((pos -= 1) >= 0) {
  337. /** @type {?} */
  338. var mv = this.confirmed.list.filter((/**
  339. * @param {?} conf
  340. * @return {?}
  341. */
  342. function (conf) {
  343. if (typeof _this.destination[pos] === 'object') {
  344. return conf._id === _this.destination[pos][_this.key];
  345. }
  346. else {
  347. return conf._id === _this.destination[pos];
  348. }
  349. }));
  350. if (mv.length === 0) {
  351. // Not found so remove.
  352. this.destination.splice(pos, 1);
  353. changed = true;
  354. }
  355. }
  356. var _loop_1 = function (i, len) {
  357. /** @type {?} */
  358. var mv = this_1.destination.filter((/**
  359. * @param {?} d
  360. * @return {?}
  361. */
  362. function (d) {
  363. if (typeof d === 'object') {
  364. return (d[_this.key] === _this.confirmed.list[i]._id);
  365. }
  366. else {
  367. return (d === _this.confirmed.list[i]._id);
  368. }
  369. }));
  370. if (mv.length === 0) {
  371. // Not found so add.
  372. mv = this_1.source.filter((/**
  373. * @param {?} o
  374. * @return {?}
  375. */
  376. function (o) {
  377. if (typeof o === 'object') {
  378. return (o[_this.key] === _this.confirmed.list[i]._id);
  379. }
  380. else {
  381. return (o === _this.confirmed.list[i]._id);
  382. }
  383. }));
  384. if (mv.length > 0) {
  385. this_1.destination.push(mv[0]);
  386. changed = true;
  387. }
  388. }
  389. };
  390. var this_1 = this;
  391. // Push added items.
  392. for (var i = 0, len = this.confirmed.list.length; i < len; i += 1) {
  393. _loop_1(i, len);
  394. }
  395. if (changed) {
  396. this.destinationChange.emit(this.destination);
  397. }
  398. };
  399. /**
  400. * @param {?} list
  401. * @param {?} item
  402. * @param {?=} key
  403. * @return {?}
  404. */
  405. DualListComponent.prototype.findItemIndex = /**
  406. * @param {?} list
  407. * @param {?} item
  408. * @param {?=} key
  409. * @return {?}
  410. */
  411. function (list, item, key) {
  412. if (key === void 0) { key = '_id'; }
  413. /** @type {?} */
  414. var idx = -1;
  415. /**
  416. * @param {?} e
  417. * @return {?}
  418. */
  419. function matchObject(e) {
  420. if (e._id === item[key]) {
  421. idx = list.indexOf(e);
  422. return true;
  423. }
  424. return false;
  425. }
  426. /**
  427. * @param {?} e
  428. * @return {?}
  429. */
  430. function match(e) {
  431. if (e._id === item) {
  432. idx = list.indexOf(e);
  433. return true;
  434. }
  435. return false;
  436. }
  437. // Assumption is that the arrays do not have duplicates.
  438. if (typeof item === 'object') {
  439. list.filter(matchObject);
  440. }
  441. else {
  442. list.filter(match);
  443. }
  444. return idx;
  445. };
  446. /**
  447. * @private
  448. * @param {?} source
  449. * @param {?} item
  450. * @return {?}
  451. */
  452. DualListComponent.prototype.makeUnavailable = /**
  453. * @private
  454. * @param {?} source
  455. * @param {?} item
  456. * @return {?}
  457. */
  458. function (source, item) {
  459. /** @type {?} */
  460. var idx = source.list.indexOf(item);
  461. if (idx !== -1) {
  462. source.list.splice(idx, 1);
  463. }
  464. };
  465. /**
  466. * @param {?} source
  467. * @param {?} target
  468. * @param {?=} item
  469. * @param {?=} trueup
  470. * @return {?}
  471. */
  472. DualListComponent.prototype.moveItem = /**
  473. * @param {?} source
  474. * @param {?} target
  475. * @param {?=} item
  476. * @param {?=} trueup
  477. * @return {?}
  478. */
  479. function (source, target, item, trueup) {
  480. var _this = this;
  481. if (item === void 0) { item = null; }
  482. if (trueup === void 0) { trueup = true; }
  483. /** @type {?} */
  484. var i = 0;
  485. /** @type {?} */
  486. var len = source.pick.length;
  487. if (item) {
  488. i = source.list.indexOf(item);
  489. len = i + 1;
  490. }
  491. var _loop_2 = function () {
  492. // Is the pick still in list?
  493. /** @type {?} */
  494. var mv = [];
  495. if (item) {
  496. /** @type {?} */
  497. var idx = this_2.findItemIndex(source.pick, item);
  498. if (idx !== -1) {
  499. mv[0] = source.pick[idx];
  500. }
  501. }
  502. else {
  503. mv = source.list.filter((/**
  504. * @param {?} src
  505. * @return {?}
  506. */
  507. function (src) {
  508. return (src._id === source.pick[i]._id);
  509. }));
  510. }
  511. // Should only ever be 1
  512. if (mv.length === 1) {
  513. // Add if not already in target.
  514. if (target.list.filter((/**
  515. * @param {?} trg
  516. * @return {?}
  517. */
  518. function (trg) { return trg._id === mv[0]._id; })).length === 0) {
  519. target.list.push(mv[0]);
  520. }
  521. this_2.makeUnavailable(source, mv[0]);
  522. }
  523. };
  524. var this_2 = this;
  525. for (; i < len; i += 1) {
  526. _loop_2();
  527. }
  528. if (this.compare !== undefined) {
  529. target.list.sort(this.compare);
  530. }
  531. source.pick.length = 0;
  532. // Update destination
  533. if (trueup) {
  534. this.trueUp();
  535. }
  536. // Delay ever-so-slightly to prevent race condition.
  537. setTimeout((/**
  538. * @return {?}
  539. */
  540. function () {
  541. _this.onFilter(source);
  542. _this.onFilter(target);
  543. }), 10);
  544. };
  545. /**
  546. * @param {?} list
  547. * @param {?} item
  548. * @return {?}
  549. */
  550. DualListComponent.prototype.isItemSelected = /**
  551. * @param {?} list
  552. * @param {?} item
  553. * @return {?}
  554. */
  555. function (list, item) {
  556. if (list.filter((/**
  557. * @param {?} e
  558. * @return {?}
  559. */
  560. function (e) { return Object.is(e, item); })).length > 0) {
  561. return true;
  562. }
  563. return false;
  564. };
  565. /**
  566. * @param {?} event
  567. * @param {?} index
  568. * @param {?} source
  569. * @param {?} item
  570. * @return {?}
  571. */
  572. DualListComponent.prototype.shiftClick = /**
  573. * @param {?} event
  574. * @param {?} index
  575. * @param {?} source
  576. * @param {?} item
  577. * @return {?}
  578. */
  579. function (event, index, source, item) {
  580. if (event.shiftKey && source.last && !Object.is(item, source.last)) {
  581. /** @type {?} */
  582. var idx = source.sift.indexOf(source.last);
  583. if (index > idx) {
  584. for (var i = (idx + 1); i < index; i += 1) {
  585. this.selectItem(source.pick, source.sift[i]);
  586. }
  587. }
  588. else if (idx !== -1) {
  589. for (var i = (index + 1); i < idx; i += 1) {
  590. this.selectItem(source.pick, source.sift[i]);
  591. }
  592. }
  593. }
  594. source.last = item;
  595. };
  596. /**
  597. * @param {?} list
  598. * @param {?} item
  599. * @return {?}
  600. */
  601. DualListComponent.prototype.selectItem = /**
  602. * @param {?} list
  603. * @param {?} item
  604. * @return {?}
  605. */
  606. function (list, item) {
  607. /** @type {?} */
  608. var pk = list.filter((/**
  609. * @param {?} e
  610. * @return {?}
  611. */
  612. function (e) {
  613. return Object.is(e, item);
  614. }));
  615. if (pk.length > 0) {
  616. // Already in list, so deselect.
  617. for (var i = 0, len = pk.length; i < len; i += 1) {
  618. /** @type {?} */
  619. var idx = list.indexOf(pk[i]);
  620. if (idx !== -1) {
  621. list.splice(idx, 1);
  622. }
  623. }
  624. }
  625. else {
  626. list.push(item);
  627. }
  628. };
  629. /**
  630. * @param {?} source
  631. * @return {?}
  632. */
  633. DualListComponent.prototype.selectAll = /**
  634. * @param {?} source
  635. * @return {?}
  636. */
  637. function (source) {
  638. source.pick.length = 0;
  639. source.pick = source.sift.slice(0);
  640. };
  641. /**
  642. * @param {?} source
  643. * @return {?}
  644. */
  645. DualListComponent.prototype.selectNone = /**
  646. * @param {?} source
  647. * @return {?}
  648. */
  649. function (source) {
  650. source.pick.length = 0;
  651. };
  652. /**
  653. * @param {?} source
  654. * @return {?}
  655. */
  656. DualListComponent.prototype.isAllSelected = /**
  657. * @param {?} source
  658. * @return {?}
  659. */
  660. function (source) {
  661. if (source.list.length === 0 || source.list.length === source.pick.length) {
  662. return true;
  663. }
  664. return false;
  665. };
  666. /**
  667. * @param {?} source
  668. * @return {?}
  669. */
  670. DualListComponent.prototype.isAnySelected = /**
  671. * @param {?} source
  672. * @return {?}
  673. */
  674. function (source) {
  675. if (source.pick.length > 0) {
  676. return true;
  677. }
  678. return false;
  679. };
  680. /**
  681. * @private
  682. * @param {?} source
  683. * @return {?}
  684. */
  685. DualListComponent.prototype.unpick = /**
  686. * @private
  687. * @param {?} source
  688. * @return {?}
  689. */
  690. function (source) {
  691. for (var i = source.pick.length - 1; i >= 0; i -= 1) {
  692. if (source.sift.indexOf(source.pick[i]) === -1) {
  693. source.pick.splice(i, 1);
  694. }
  695. }
  696. };
  697. /**
  698. * @param {?} source
  699. * @return {?}
  700. */
  701. DualListComponent.prototype.clearFilter = /**
  702. * @param {?} source
  703. * @return {?}
  704. */
  705. function (source) {
  706. if (source) {
  707. source.picker = '';
  708. this.onFilter(source);
  709. }
  710. };
  711. /**
  712. * @param {?} source
  713. * @return {?}
  714. */
  715. DualListComponent.prototype.onFilter = /**
  716. * @param {?} source
  717. * @return {?}
  718. */
  719. function (source) {
  720. var _this = this;
  721. if (source.picker.length > 0) {
  722. try {
  723. /** @type {?} */
  724. var filtered = source.list.filter((/**
  725. * @param {?} item
  726. * @return {?}
  727. */
  728. function (item) {
  729. if (Object.prototype.toString.call(item) === '[object Object]') {
  730. if (item._name !== undefined) {
  731. // @ts-ignore: remove when d.ts has locale as an argument.
  732. return item._name.toLocaleLowerCase(_this.format.locale).indexOf(source.picker.toLocaleLowerCase(_this.format.locale)) !== -1;
  733. }
  734. else {
  735. // @ts-ignore: remove when d.ts has locale as an argument.
  736. return JSON.stringify(item).toLocaleLowerCase(_this.format.locale).indexOf(source.picker.toLocaleLowerCase(_this.format.locale)) !== -1;
  737. }
  738. }
  739. else {
  740. // @ts-ignore: remove when d.ts has locale as an argument.
  741. return item.toLocaleLowerCase(_this.format.locale).indexOf(source.picker.toLocaleLowerCase(_this.format.locale)) !== -1;
  742. }
  743. }));
  744. source.sift = filtered;
  745. this.unpick(source);
  746. }
  747. catch (e) {
  748. if (e instanceof RangeError) {
  749. this.format.locale = undefined;
  750. }
  751. source.sift = source.list;
  752. }
  753. }
  754. else {
  755. source.sift = source.list;
  756. }
  757. };
  758. /**
  759. * @private
  760. * @param {?} item
  761. * @return {?}
  762. */
  763. DualListComponent.prototype.makeId = /**
  764. * @private
  765. * @param {?} item
  766. * @return {?}
  767. */
  768. function (item) {
  769. if (typeof item === 'object') {
  770. return item[this.key];
  771. }
  772. else {
  773. return item;
  774. }
  775. };
  776. // Allow for complex names by passing an array of strings.
  777. // Example: [display]="[ '_type.substring(0,1)', '_name' ]"
  778. // Allow for complex names by passing an array of strings.
  779. // Example: [display]="[ '_type.substring(0,1)', '_name' ]"
  780. /**
  781. * @protected
  782. * @param {?} item
  783. * @param {?=} separator
  784. * @return {?}
  785. */
  786. DualListComponent.prototype.makeName =
  787. // Allow for complex names by passing an array of strings.
  788. // Example: [display]="[ '_type.substring(0,1)', '_name' ]"
  789. /**
  790. * @protected
  791. * @param {?} item
  792. * @param {?=} separator
  793. * @return {?}
  794. */
  795. function (item, separator) {
  796. if (separator === void 0) { separator = '_'; }
  797. /** @type {?} */
  798. var display = this.display;
  799. /**
  800. * @param {?} itm
  801. * @return {?}
  802. */
  803. function fallback(itm) {
  804. switch (Object.prototype.toString.call(itm)) {
  805. case '[object Number]':
  806. return itm;
  807. case '[object String]':
  808. return itm;
  809. default:
  810. if (itm !== undefined) {
  811. return itm[display];
  812. }
  813. else {
  814. return 'undefined';
  815. }
  816. }
  817. }
  818. /** @type {?} */
  819. var str = '';
  820. if (this.display !== undefined) {
  821. switch (Object.prototype.toString.call(this.display)) {
  822. case '[object Function]':
  823. str = this.display(item);
  824. break;
  825. case '[object Array]':
  826. for (var i = 0, len = this.display.length; i < len; i += 1) {
  827. if (str.length > 0) {
  828. str = str + separator;
  829. }
  830. if (this.display[i].indexOf('.') === -1) {
  831. // Simple, just add to string.
  832. str = str + item[this.display[i]];
  833. }
  834. else {
  835. // Complex, some action needs to be performed
  836. /** @type {?} */
  837. var parts = this.display[i].split('.');
  838. /** @type {?} */
  839. var s = item[parts[0]];
  840. if (s) {
  841. // Use brute force
  842. if (parts[1].indexOf('substring') !== -1) {
  843. /** @type {?} */
  844. var nums = (parts[1].substring(parts[1].indexOf('(') + 1, parts[1].indexOf(')'))).split(',');
  845. switch (nums.length) {
  846. case 1:
  847. str = str + s.substring(parseInt(nums[0], 10));
  848. break;
  849. case 2:
  850. str = str + s.substring(parseInt(nums[0], 10), parseInt(nums[1], 10));
  851. break;
  852. default:
  853. str = str + s;
  854. break;
  855. }
  856. }
  857. else {
  858. // method not approved, so just add s.
  859. str = str + s;
  860. }
  861. }
  862. }
  863. }
  864. break;
  865. default:
  866. str = fallback(item);
  867. break;
  868. }
  869. }
  870. else {
  871. str = fallback(item);
  872. }
  873. return str;
  874. };
  875. DualListComponent.AVAILABLE_LIST_NAME = 'available';
  876. DualListComponent.CONFIRMED_LIST_NAME = 'confirmed';
  877. DualListComponent.LTR = 'left-to-right';
  878. DualListComponent.RTL = 'right-to-left';
  879. DualListComponent.DEFAULT_FORMAT = {
  880. add: 'Add',
  881. remove: 'Remove',
  882. all: 'All',
  883. none: 'None',
  884. direction: DualListComponent.LTR,
  885. draggable: true,
  886. locale: undefined
  887. };
  888. DualListComponent.decorators = [
  889. { type: Component, args: [{
  890. selector: 'dual-list',
  891. template: "<div class=\"dual-list\">\n\t<div class=\"listbox\" [ngStyle]=\"{ 'order' : direction() ? 1 : 2, 'margin-left' : direction() ? 0 : '10px' }\">\n\t\t<button type=\"button\" name=\"addBtn\" class=\"btn btn-primary btn-block\"\n\t\t\t(click)=\"moveItem(available, confirmed)\" [ngClass]=\"direction() ? 'point-right' : 'point-left'\"\n\t\t\t[disabled]=\"available.pick.length === 0\">{{format.add}}</button>\n\n\t\t<form *ngIf=\"filter\" class=\"filter\">\n\t\t\t<input class=\"form-control\" name=\"filterSource\" [(ngModel)]=\"available.picker\" (ngModelChange)=\"onFilter(available)\">\n\t\t</form>\n\n\t\t<div class=\"record-picker\">\n\t\t\t<ul [ngStyle]=\"{'max-height': height, 'min-height': height}\" [ngClass]=\"{over:available.dragOver}\"\n\t\t\t\t(drop)=\"drop($event, confirmed)\" (dragover)=\"allowDrop($event, available)\" (dragleave)=\"dragLeave()\">\n\t\t\t\t<li *ngFor=\"let item of available.sift; let idx=index;\"\n\t\t\t\t\t(click)=\"disabled ? null : selectItem(available.pick, item); shiftClick($event, idx, available, item)\"\n\t\t\t\t\t[ngClass]=\"{selected: isItemSelected(available.pick, item), disabled: disabled}\"\n\t\t\t\t\t[draggable]=\"!disabled && format.draggable\" (dragstart)=\"drag($event, item, available)\" (dragend)=\"dragEnd(available)\"\n\t\t\t\t><label>{{item._name}}</label></li>\n\t\t\t</ul>\n\t\t</div>\n\n\t\t<div class=\"button-bar\">\n\t\t\t<button type=\"button\" class=\"btn btn-primary pull-left\" (click)=\"selectAll(available)\"\n\t\t\t\t[disabled]=\"disabled || isAllSelected(available)\">{{format.all}}</button>\n\t\t\t<button type=\"button\" class=\"btn btn-default pull-right\" (click)=\"selectNone(available)\"\n\t\t\t\t[disabled]=\"!isAnySelected(available)\">{{format.none}}</button>\n\t\t</div>\n\t</div>\n\n\t<div class=\"listbox\" [ngStyle]=\"{ 'order' : direction() ? 2 : 1, 'margin-left' : direction() ? '10px' : 0 }\">\n\t\t<button type=\"button\" name=\"removeBtn\" class=\"btn btn-primary btn-block\"\n\t\t\t(click)=\"moveItem(confirmed, available)\" [ngClass]=\"direction() ? 'point-left' : 'point-right'\"\n\t\t\t[disabled]=\"confirmed.pick.length === 0\">{{format.remove}}</button>\n\n\t\t<form *ngIf=\"filter\" class=\"filter\">\n\t\t\t<input class=\"form-control\" name=\"filterDestination\" [(ngModel)]=\"confirmed.picker\" (ngModelChange)=\"onFilter(confirmed)\">\n\t\t</form>\n\n\t\t<div class=\"record-picker\">\n\t\t\t<ul [ngStyle]=\"{'max-height': height, 'min-height': height}\" [ngClass]=\"{over:confirmed.dragOver}\"\n\t\t\t\t(drop)=\"drop($event, available)\" (dragover)=\"allowDrop($event, confirmed)\" (dragleave)=\"dragLeave()\">\n\t\t\t\t<li #itmConf *ngFor=\"let item of confirmed.sift; let idx=index;\"\n\t\t\t\t\t(click)=\"disabled ? null : selectItem(confirmed.pick, item); shiftClick($event, idx, confirmed, item)\"\n\t\t\t\t\t[ngClass]=\"{selected: isItemSelected(confirmed.pick, item), disabled: disabled}\"\n\t\t\t\t\t[draggable]=\"!disabled && format.draggable\" (dragstart)=\"drag($event, item, confirmed)\" (dragend)=\"dragEnd(confirmed)\"\n\t\t\t\t><label>{{item._name}}</label></li>\n\t\t\t</ul>\n\t\t</div>\n\n\t\t<div class=\"button-bar\">\n\t\t\t<button type=\"button\" class=\"btn btn-primary pull-left\" (click)=\"selectAll(confirmed)\"\n\t\t\t\t[disabled]=\"disabled || isAllSelected(confirmed)\">{{format.all}}</button>\n\t\t\t<button type=\"button\" class=\"btn btn-default pull-right\" (click)=\"selectNone(confirmed)\"\n\t\t\t\t[disabled]=\"!isAnySelected(confirmed)\">{{format.none}}</button>\n\t\t</div>\n\t</div>\n</div>\n",
  892. styles: ["div.record-picker{overflow-x:hidden;overflow-y:auto;border:1px solid #ddd;border-radius:8px;position:relative;cursor:pointer;scrollbar-base-color:#337ab7;scrollbar-3dlight-color:#337ab7;scrollbar-highlight-color:#337ab7;scrollbar-track-color:#eee;scrollbar-arrow-color:gray;scrollbar-shadow-color:gray;scrollbar-dark-shadow-color:gray}div.record-picker::-webkit-scrollbar{width:12px}div.record-picker::-webkit-scrollbar-button{width:0;height:0}div.record-picker::-webkit-scrollbar-track{background:#eee;box-shadow:0 0 3px #dfdfdf inset;border-top-right-radius:8px;border-bottom-right-radius:8px}div.record-picker::-webkit-scrollbar-thumb{background:#337ab7;border:thin solid gray;border-top-right-radius:8px;border-bottom-right-radius:8px}div.record-picker::-webkit-scrollbar-thumb:hover{background:#286090}.record-picker ul{margin:0;padding:0 0 1px}.record-picker li{border-top:thin solid #ddd;border-bottom:1px solid #ddd;display:block;padding:2px 2px 2px 10px;margin-bottom:-1px;font-size:.85em;cursor:pointer;white-space:nowrap;min-height:16px}.record-picker li:hover{background-color:#f5f5f5}.record-picker li.selected{background-color:#d9edf7}.record-picker li.selected:hover{background-color:#c4e3f3}.record-picker li.disabled{opacity:.5;cursor:default;background-color:inherit}.record-picker li:first-child{border-top-left-radius:8px;border-top-right-radius:8px;border-top:none}.record-picker li:last-child{border-bottom-left-radius:8px;border-bottom-right-radius:8px;border-bottom:none}.record-picker label{cursor:pointer;font-weight:inherit;font-size:14px;padding:4px;margin-bottom:-1px;-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.record-picker ul.over{background-color:#d3d3d3}.dual-list{display:flex;flex-direction:row;align-content:flex-start}.dual-list .listbox{width:50%;margin:0}.dual-list .button-bar{margin-top:8px}.point-right::after{content:\"\\25B6\";padding-left:1em}.point-left::before{content:\"\\25C0\";padding-right:1em}.dual-list .button-bar button{width:47%}button.btn-block{display:block;width:100%;margin-bottom:8px}.filter{margin-bottom:-2.2em}.filter::after{content:\"o\";width:40px;color:transparent;font-size:2em;background-image:url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\"><path d=\"M0 64l192 192v192l128-32V256L512 64H0z\"/></svg>');background-repeat:no-repeat;background-position:center center;opacity:.2;top:-36px;left:calc(100% - 21px);position:relative}"]
  893. }] }
  894. ];
  895. /** @nocollapse */
  896. DualListComponent.ctorParameters = function () { return [
  897. { type: IterableDiffers }
  898. ]; };
  899. DualListComponent.propDecorators = {
  900. id: [{ type: Input }],
  901. key: [{ type: Input }],
  902. display: [{ type: Input }],
  903. height: [{ type: Input }],
  904. filter: [{ type: Input }],
  905. format: [{ type: Input }],
  906. sort: [{ type: Input }],
  907. compare: [{ type: Input }],
  908. disabled: [{ type: Input }],
  909. source: [{ type: Input }],
  910. destination: [{ type: Input }],
  911. destinationChange: [{ type: Output }]
  912. };
  913. return DualListComponent;
  914. }());
  915. export { DualListComponent };
  916. if (false) {
  917. /** @type {?} */
  918. DualListComponent.AVAILABLE_LIST_NAME;
  919. /** @type {?} */
  920. DualListComponent.CONFIRMED_LIST_NAME;
  921. /** @type {?} */
  922. DualListComponent.LTR;
  923. /** @type {?} */
  924. DualListComponent.RTL;
  925. /** @type {?} */
  926. DualListComponent.DEFAULT_FORMAT;
  927. /** @type {?} */
  928. DualListComponent.prototype.id;
  929. /** @type {?} */
  930. DualListComponent.prototype.key;
  931. /** @type {?} */
  932. DualListComponent.prototype.display;
  933. /** @type {?} */
  934. DualListComponent.prototype.height;
  935. /** @type {?} */
  936. DualListComponent.prototype.filter;
  937. /** @type {?} */
  938. DualListComponent.prototype.format;
  939. /** @type {?} */
  940. DualListComponent.prototype.sort;
  941. /** @type {?} */
  942. DualListComponent.prototype.compare;
  943. /** @type {?} */
  944. DualListComponent.prototype.disabled;
  945. /** @type {?} */
  946. DualListComponent.prototype.source;
  947. /** @type {?} */
  948. DualListComponent.prototype.destination;
  949. /** @type {?} */
  950. DualListComponent.prototype.destinationChange;
  951. /** @type {?} */
  952. DualListComponent.prototype.available;
  953. /** @type {?} */
  954. DualListComponent.prototype.confirmed;
  955. /** @type {?} */
  956. DualListComponent.prototype.sourceDiffer;
  957. /** @type {?} */
  958. DualListComponent.prototype.destinationDiffer;
  959. /**
  960. * @type {?}
  961. * @private
  962. */
  963. DualListComponent.prototype.sorter;
  964. /**
  965. * @type {?}
  966. * @private
  967. */
  968. DualListComponent.prototype.differs;
  969. }
  970. //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZHVhbC1saXN0LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiJuZzovL2FuZ3VsYXItZHVhbC1saXN0Ym94LyIsInNvdXJjZXMiOlsibGliL2R1YWwtbGlzdC5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7OztBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQVcsWUFBWSxFQUFFLEtBQUssRUFBRSxlQUFlLEVBQ2hFLE1BQU0sRUFBZ0IsTUFBTSxlQUFlLENBQUM7QUFFN0MsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLGNBQWMsQ0FBQzs7SUFJckMsTUFBTSxHQUFHLENBQUM7QUFFZDtJQTRDQywyQkFBb0IsT0FBd0I7UUFBeEIsWUFBTyxHQUFQLE9BQU8sQ0FBaUI7UUFyQm5DLE9BQUUsR0FBRyxlQUFhLE1BQU0sRUFBSSxDQUFDO1FBQzdCLFFBQUcsR0FBRyxLQUFLLENBQUM7UUFDWixZQUFPLEdBQVEsT0FBTyxDQUFDO1FBQ3ZCLFdBQU0sR0FBRyxPQUFPLENBQUM7UUFDakIsV0FBTSxHQUFHLEtBQUssQ0FBQztRQUNmLFdBQU0sR0FBRyxpQkFBaUIsQ0FBQyxjQUFjLENBQUM7UUFDMUMsU0FBSSxHQUFHLEtBQUssQ0FBQztRQUViLGFBQVEsR0FBRyxLQUFLLENBQUM7UUFHaEIsc0JBQWlCLEdBQUcsSUFBSSxZQUFZLEVBQUUsQ0FBQztRQVF6QyxXQUFNOzs7OztRQUFHLFVBQUMsQ0FBTSxFQUFFLENBQU0sSUFBTyxPQUFPLENBQUMsQ0FBQyxDQUFDLEtBQUssR0FBRyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssR0FBRyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUM7UUFHekcsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLFNB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LGlDQUFzQjs7SUFDdEIsb0NBQWtDOztJQUNsQyxxQ0FBMEI7O0lBQzFCLG1DQUE0Qjs7SUFDNUIsd0NBQWlDOztJQUNqQyw4Q0FBaUQ7O0lBRWpELHNDQUFxQjs7SUFDckIsc0NBQXFCOztJQUVyQix5Q0FBa0I7O0lBQ2xCLDhDQUF1Qjs7Ozs7SUFFdkIsbUNBQTBHOzs7OztJQUU5RixvQ0FBZ0MiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIERvQ2hlY2ssIEV2ZW50RW1pdHRlciwgSW5wdXQsIEl0ZXJhYmxlRGlmZmVycywgT25DaGFuZ2VzLFxuXHRPdXRwdXQsIFNpbXBsZUNoYW5nZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuXG5pbXBvcnQgeyBCYXNpY0xpc3QgfSBmcm9tICcuL2Jhc2ljLWxpc3QnO1xuXG5leHBvcnQgdHlwZSBjb21wYXJlRnVuY3Rpb24gPSAoYTogYW55LCBiOiBhbnkpID0+IG51bWJlcjtcblxudmFyIG5leHRJZCA9IDA7XG5cbkBDb21wb25lbnQoe1xuXHRzZWxlY3RvcjogJ2R1YWwtbGlzdCcsXG5cdHRlbXBsYXRlVXJsOiAnLi9kdWFsLWxpc3QuY29tcG9uZW50Lmh0bWwnLFxuXHRzdHlsZVVybHM6IFsgJy4vZHVhbC1saXN0LmNvbXBvbmVudC5jc3MnIF1cbn0pXG5cbmV4cG9ydCBjbGFzcyBEdWFsTGlzdENvbXBvbmVudCBpbXBsZW1lbnRzIERvQ2hlY2ssIE9uQ2hhbmdlcyB7XG5cdHN0YXRpYyBBVkFJTEFCTEVfTElTVF9OQU1FID0gJ2F2YWlsYWJsZSc7XG5cdHN0YXRpYyBDT05GSVJNRURfTElTVF9OQU1FID0gJ2NvbmZpcm1lZCc7XG5cblx0c3RhdGljIExUUiA9ICdsZWZ0LXRvLXJpZ2h0Jztcblx0c3RhdGljIFJUTCA9ICdyaWdodC10by1sZWZ0JztcblxuXHRzdGF0aWMgREVGQVVMVF9GT1JNQVQgPSB7XG5cdFx0YWRkOiAnQWRkJyxcblx0XHRyZW1vdmU6ICdSZW1vdmUnLFxuXHRcdGFsbDogJ0FsbCcsXG5cdFx0bm9uZTogJ05vbmUnLFxuXHRcdGRpcmVjdGlvbjogRHVhbExpc3RDb21wb25lbnQuTFRSLFxuXHRcdGRyYWdnYWJsZTogdHJ1ZSxcblx0XHRsb2NhbGU6IHVuZGVmaW5lZFxuXHR9O1xuXG5cdEBJbnB1dCgpIGlkID0gYGR1YWwtbGlzdC0ke25leHRJZCsrfWA7XG5cdEBJbnB1dCgpIGtleSA9ICdfaWQnO1xuXHRASW5wdXQoKSBkaXNwbGF5OiBhbnkgPSAnX25hbWUnO1xuXHRASW5wdXQoKSBoZWlnaHQgPSAnMTAwcHgnO1xuXHRASW5wdXQoKSBmaWx0ZXIgPSBmYWxzZTtcblx0QElucHV0KCkgZm9ybWF0ID0gRHVhbExpc3RDb21wb25lbnQuREVGQVVMVF9GT1JNQVQ7XG5cdEBJbnB1dCgpIHNvcnQgPSBmYWxzZTtcblx0QElucHV0KCkgY29tcGFyZTogY29tcGFyZUZ1bmN0aW9uO1xuXHRASW5wdXQoKSBkaXNhYmxlZCA9IGZhbHNlO1xuXHRASW5wdXQoKSBzb3VyY2U6IEFycmF5PGFueT47XG5cdEBJbnB1dCgpIGRlc3RpbmF0aW9uOiBBcnJheTxhbnk+O1xuXHRAT3V0cHV0KCkgZGVzdGluYXRpb25DaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG5cblx0YXZhaWxhYmxlOiBCYXNpY0xpc3Q7XG5cdGNvbmZpcm1lZDogQmFzaWNMaXN0O1xuXG5cdHNvdXJjZURpZmZlcjogYW55O1xuXHRkZXN0aW5hdGlvbkRpZmZlcjogYW55O1xuXG5cdHByaXZhdGUgc29ydGVyID0gKGE6IGFueSwgYjogYW55KSA9PiB7IHJldHVybiAoYS5fbmFtZSA8IGIuX25hbWUpID8gLTEgOiAoKGEuX25hbWUgPiBiLl9uYW1lKSA/IDEgOiAwKTsgfTtcblxuXHRjb25zdHJ1Y3Rvcihwcml2YXRlIGRpZmZlcnM6IEl0ZXJhYmxlRGlmZmVycykge1xuXHRcdHRoaXMuYXZhaWxhYmxlID0gbmV3IEJhc2ljTGlzdChEdWFsTGlzdENvbXBvbmVudC5BVkFJTEFCTEVfTElTVF9OQU1FKTtcblx0XHR0aGlzLmNvbmZpcm1lZCA9IG5ldyBCYXNpY0xpc3QoRHVhbExpc3RDb21wb25lbnQuQ09ORklSTUVEX0xJU1RfTkFNRSk7XG5cdH1cblxuXHRuZ09uQ2hhbmdlcyhjaGFuZ2VSZWNvcmQ6IHtba2V5OiBzdHJpbmddOiBTaW1wbGVDaGFuZ2V9KSB7XG5cdFx0aWYgKGNoYW5nZVJlY29yZFsnZmlsdGVyJ10pIHtcblx0XHRcdGlmIChjaGFuZ2VSZWNvcmRbJ2ZpbHRlciddLmN1cnJlbnRWYWx1ZSA9PT0gZmFsc2UpIHtcblx0XHRcdFx0dGhpcy5jbGVhckZpbHRlcih0aGlzLmF2YWlsYWJsZSk7XG5cdFx0XHRcdHRoaXMuY2xlYXJGaWx0ZXIodGhpcy5jb25maXJtZWQpO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdGlmIChjaGFuZ2VSZWNvcmRbJ3NvcnQnXSkge1xuXHRcdFx0aWYgKGNoYW5nZVJlY29yZFsnc29ydCddLmN1cnJlbnRWYWx1ZSA9PT0gdHJ1ZSAmJiB0aGlzLmNvbXBhcmUgPT09IHVuZGVmaW5lZCkge1xuXHRcdFx0XHR0aGlzLmNvbXBhcmUgPSB0aGlzLnNvcnRlcjtcblx0XHRcdH0gZWxzZSBpZiAoY2hhbmdlUmVjb3JkWydzb3J0J10uY3VycmVudFZhbHVlID09PSBmYWxzZSkge1xuXHRcdFx0XHR0aGlzLmNvbXBhcmUgPSB1bmRlZmluZWQ7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0aWYgKGNoYW5nZVJlY29yZFsnZm9ybWF0J10pIHtcblx0XHRcdHRoaXMuZm9ybWF0ID0gY2hhbmdlUmVjb3JkWydmb3JtYXQnXS5jdXJyZW50VmFsdWU7XG5cblx0XHRcdGlmICh0eXBlb2YodGhpcy5mb3JtYXQuZGlyZWN0aW9uKSA9PT0gJ3VuZGVmaW5lZCcpIHtcblx0XHRcdFx0dGhpcy5mb3JtYXQuZGlyZWN0aW9uID0gRHVhbExpc3RDb21wb25lbnQuTFRSO1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAodHlwZW9mKHRoaXMuZm9ybWF0LmFkZCkgPT09ICd1bmRlZmluZWQnKSB7XG5cdFx0XHRcdHRoaXMuZm9ybWF0LmFkZCA9IER1YWxMaXN0Q29tcG9uZW50LkRFRkFVTFRfRk9STUFULmFkZDtcblx0XHRcdH1cblxuXHRcdFx0aWYgKHR5cGVvZih0aGlzLmZvcm1hdC5yZW1vdmUpID09PSAndW5kZWZpbmVkJykge1xuXHRcdFx0XHR0aGlzLmZvcm1hdC5yZW1vdmUgPSBEdWFsTGlzdENvbXBvbmVudC5ERUZBVUxUX0ZPUk1BVC5yZW1vdmU7XG5cdFx0XHR9XG5cblx0XHRcdGlmICh0eXBlb2YodGhpcy5mb3JtYXQuYWxsKSA9PT0gJ3VuZGVmaW5lZCcpIHtcblx0XHRcdFx0dGhpcy5mb3JtYXQuYWxsID0gRHVhbExpc3RDb21wb25lbnQuREVGQVVMVF9GT1JNQVQuYWxsO1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAodHlwZW9mKHRoaXMuZm9ybWF0Lm5vbmUpID09PSAndW5kZWZpbmVkJykge1xuXHRcdFx0XHR0aGlzLmZvcm1hdC5ub25lID0gRHVhbExpc3RDb21wb25lbnQuREVGQVVMVF9GT1JNQVQubm9uZTtcblx0XHRcdH1cblxuXHRcdFx0aWYgKHR5cGVvZih0aGlzLmZvcm1hdC5kcmFnZ2FibGUpID09PSAndW5kZWZpbmVkJykge1xuXHRcdFx0XHR0aGlzLmZvcm1hdC5kcmFnZ2FibGUgPSBEdWFsTGlzdENvbXBvbmVudC5ERUZBVUxUX0ZPUk1BVC5kcmFnZ2FibGU7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0aWYgKGNoYW5nZVJlY29yZFsnc291cmNlJ10pIHtcblx0XHRcdHRoaXMuYXZhaWxhYmxlID0gbmV3IEJhc2ljTGlzdChEdWFsTGlzdENvbXBvbmVudC5BVkFJTEFCTEVfTElTVF9OQU1FKTtcblx0XHRcdHRoaXMudXBkYXRlZFNvdXJjZSgpO1xuXHRcdFx0dGhpcy51cGRhdGVkRGVzdGluYXRpb24oKTtcblx0XHR9XG5cblx0XHRpZiAoY2hhbmdlUmVjb3JkWydkZXN0aW5hdGlvbiddKSB7XG5cdFx0XHR0aGlzLmNvbmZpcm1lZCA9IG5ldyBCYXNpY0xpc3QoRHVhbExpc3RDb21wb25lbnQuQ09ORklSTUVEX0xJU1RfTkFNRSk7XG5cdFx0XHR0aGlzLnVwZGF0ZWREZXN0aW5hdGlvbigpO1xuXHRcdFx0dGhpcy51cGRhdGVkU291cmNlKCk7XG5cdFx0fVxuXHR9XG5cblx0bmdEb0NoZWNrKCkge1xuXHRcdGlmICh0aGlzLnNvdXJjZSAmJiB0aGlzLmJ1aWxkQXZhaWxhYmxlKHRoaXMuc291cmNlKSkge1xuXHRcdFx0dGhpcy5vbkZpbHRlcih0aGlzLmF2YWlsYWJsZSk7XG5cdFx0fVxuXHRcdGlmICh0aGlzLmRlc3RpbmF0aW9uICYmIHRoaXMuYnVpbGRDb25maXJtZWQodGhpcy5kZXN0aW5hdGlvbikpIHtcblx0XHRcdHRoaXMub25GaWx0ZXIodGhpcy5jb25maXJtZWQpO1xuXHRcdH1cblx0fVxuXG5cdGJ1aWxkQXZhaWxhYmxlKHNvdXJjZTogQXJyYXk8YW55Pik6IGJvb2xlYW4ge1xuXHRcdGNvbnN0IHNvdXJjZUNoYW5nZXMgPSB0aGlzLnNvdXJjZURpZmZlci5kaWZmKHNvdXJjZSk7XG5cdFx0aWYgKHNvdXJjZUNoYW5nZXMpIHtcblx0XHRcdHNvdXJjZUNoYW5nZXMuZm9yRWFjaFJlbW92ZWRJdGVtKChyOiBhbnkpID0+IHtcblx0XHRcdFx0Y29uc3QgaWR4ID0gdGhpcy5maW5kSXRlbUluZGV4KHRoaXMuYXZhaWxhYmxlLmxpc3QsIHIuaXRlbSwgdGhpcy5rZXkpO1xuXHRcdFx0XHRpZiAoaWR4ICE9PSAtMSkge1xuXHRcdFx0XHRcdHRoaXMuYXZhaWxhYmxlLmxpc3Quc3BsaWNlKGlkeCwgMSk7XG5cdFx0XHRcdH1cblx0XHRcdH0pO1xuXG5cdFx0XHRzb3VyY2VDaGFuZ2VzLmZvckVhY2hBZGRlZEl0ZW0oKHI6IGFueSkgPT4ge1xuXHRcdFx0XHQvLyBEbyBub3QgYWRkIGR1cGxpY2F0ZXMgZXZlbiBpZiBzb3VyY2UgaGFzIGR1cGxpY2F0ZXMuXG5cdFx0XHRcdGlmICh0aGlzLmZpbmRJdGVtSW5kZXgodGhpcy5hdmFpbGFibGUubGlzdCwgci5pdGVtLCB0aGlzLmtleSkgPT09IC0xKSB7XG5cdFx0XHRcdFx0dGhpcy5hdmFpbGFibGUubGlzdC5wdXNoKCB7IF9pZDogdGhpcy5tYWtlSWQoci5pdGVtKSwgX25hbWU6IHRoaXMubWFrZU5hbWUoci5pdGVtKSB9KTtcblx0XHRcdFx0fVxuXHRcdFx0fSk7XG5cblx0XHRcdGlmICh0aGlzLmNvbXBhcmUgIT09IHVuZGVmaW5lZCkge1xuXHRcdFx0XHR0aGlzLmF2YWlsYWJsZS5saXN0LnNvcnQodGhpcy5jb21wYXJlKTtcblx0XHRcdH1cblx0XHRcdHRoaXMuYXZhaWxhYmxlLnNpZnQgPSB0aGlzLmF2YWlsYWJsZS5saXN0O1xuXG5cdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHR9XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG5cblx0YnVpbGRDb25maXJtZWQoZGVzdGluYXRpb246IEFycmF5PGFueT4pOiBib29sZWFuIHtcblx0XHRsZXQgbW92ZWQgPSBmYWxzZTtcblx0XHRjb25zdCBkZXN0Q2hhbmdlcyA9IHRoaXMuZGVzdGluYXRpb25EaWZmZXIuZGlmZihkZXN0aW5hdGlvbik7XG5cdFx0aWYgKGRlc3RDaGFuZ2VzKSB7XG5cdFx0XHRkZXN0Q2hhbmdlcy5mb3JFYWNoUmVtb3ZlZEl0ZW0oKHI6IGFueSkgPT4ge1xuXHRcdFx0XHRjb25zdCBpZHggPSB0aGlzLmZpbmRJdGVtSW5kZXgodGhpcy5jb25maXJtZWQubGlzdCwgci5pdGVtLCB0aGlzLmtleSk7XG5cdFx0XHRcdGlmIChpZHggIT09IC0xKSB7XG5cdFx0XHRcdFx0aWYgKCF0aGlzLmlzSXRlbVNlbGVjdGVkKHRoaXMuY29uZmlybWVkLnBpY2ssIHRoaXMuY29uZmlybWVkLmxpc3RbaWR4XSkpIHtcblx0XHRcdFx0XHRcdHRoaXMuc2VsZWN0SXRlbSh0aGlzLmNvbmZpcm1lZC5waWNrLCB0aGlzLmNvbmZpcm1lZC5saXN0W2lkeF0pO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHR0aGlzLm1vdmVJdGVtKHRoaXMuY29uZmlybWVkLCB0aGlzLmF2YWlsYWJsZSwgdGhpcy5jb25maXJtZWQubGlzdFtpZHhdLCBmYWxzZSk7XG5cdFx0XHRcdFx0bW92ZWQgPSB0cnVlO1xuXHRcdFx0XHR9XG5cdFx0XHR9KTtcblxuXHRcdFx0ZGVzdENoYW5nZXMuZm9yRWFjaEFkZGVkSXRlbSgocjogYW55KSA9PiB7XG5cdFx0XHRcdGNvbnN0IGlkeCA9IHRoaXMuZmluZEl0ZW1JbmRleCh0aGlzLmF2YWlsYWJsZS5saXN0LCByLml0ZW0sIHRoaXMua2V5KTtcblx0XHRcdFx0aWYgKGlkeCAhPT0gLTEpIHtcblx0XHRcdFx0XHRpZiAoIXRoaXMuaXNJdGVtU2VsZWN0ZWQodGhpcy5hdmFpbGFibGUucGljaywgdGhpcy5hdmFpbGFibGUubGlzdFtpZHhdKSkge1xuXHRcdFx0XHRcdFx0dGhpcy5zZWxlY3RJdGVtKHRoaXMuYXZhaWxhYmxlLnBpY2ssIHRoaXMuYXZhaWxhYmxlLmxpc3RbaWR4XSk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdHRoaXMubW92ZUl0ZW0odGhpcy5hdmFpbGFibGUsIHRoaXMuY29uZmlybWVkLCB0aGlzLmF2YWlsYWJsZS5saXN0W2lkeF0sIGZhbHNlKTtcblx0XHRcdFx0XHRtb3ZlZCA9IHRydWU7XG5cdFx0XHRcdH1cblx0XHRcdH0pO1xuXG5cdFx0XHRpZiAodGhpcy5jb21wYXJlICE9PSB1bmRlZmluZWQpIHtcblx0XHRcdFx0dGhpcy5jb25maXJtZWQubGlzdC5zb3J0KHRoaXMuY29tcGFyZSk7XG5cdFx0XHR9XG5cdFx0XHR0aGlzLmNvbmZpcm1lZC5zaWZ0ID0gdGhpcy5jb25maXJtZWQubGlzdDtcblxuXHRcdFx0aWYgKG1vdmVkKSB7XG5cdFx0XHRcdHRoaXMudHJ1ZVVwKCk7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHR9XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG5cblx0dXBkYXRlZFNvdXJjZSgpIHtcblx0XHR0aGlzLmF2YWlsYWJsZS5saXN0Lmxlbmd0aCA9IDA7XG5cdFx0dGhpcy5hdmFpbGFibGUucGljay5sZW5ndGggPSAwO1xuXG5cdFx0aWYgKHRoaXMuc291cmNlICE9PSB1bmRlZmluZWQpIHtcblx0XHRcdHRoaXMuc291cmNlRGlmZmVyID0gdGhpcy5kaWZmZXJzLmZpbmQodGhpcy5zb3VyY2UpLmNyZWF0ZShudWxsKTtcblx0XHR9XG5cdH1cblxuXHR1cGRhdGVkRGVzdGluYXRpb24oKSB7XG5cdFx0aWYgKHRoaXMuZGVzdGluYXRpb24gIT09IHVuZGVmaW5lZCkge1xuXHRcdFx0dGhpcy5kZXN0aW5hdGlvbkRpZmZlciA9IHRoaXMuZGlmZmVycy5maW5kKHRoaXMuZGVzdGluYXRpb24pLmNyZWF0ZShudWxsKTtcblx0XHR9XG5cdH1cblxuXHRkaXJlY3Rpb24oKSB7XG5cdFx0cmV0dXJuIHRoaXMuZm9ybWF0LmRpcmVjdGlvbiA9PT0gRHVhbExpc3RDb21wb25lbnQuTFRSO1xuXHR9XG5cblx0ZHJhZ0VuZChsaXN0OiBCYXNpY0xpc3QgPSBudWxsKTogYm9vbGVhbiB7XG5cdFx0aWYgKGxpc3QpIHtcblx0XHRcdGxpc3QuZHJhZ1N0YXJ0ID0gZmFsc2U7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHRoaXMuYXZhaWxhYmxlLmRyYWdTdGFydCA9IGZhbHNlO1xuXHRcdFx0dGhpcy5jb25maXJtZWQuZHJhZ1N0YXJ0ID0gZmFsc2U7XG5cdFx0fVxuXHRcdHJldHVybiBmYWxzZTtcblx0fVxuXG5cdGRyYWcoZXZlbnQ6IERyYWdFdmVudCwgaXRlbTogYW55LCBsaXN0OiBCYXNpY0xpc3QpIHtcblx0XHRpZiAoIXRoaXMuaXNJdGVtU2VsZWN0ZWQobGlzdC5waWNrLCBpdGVtKSkge1xuXHRcdFx0dGhpcy5zZWxlY3RJdGVtKGxpc3QucGljaywgaXRlbSk7XG5cdFx0fVxuXHRcdGxpc3QuZHJhZ1N0YXJ0ID0gdHJ1ZTtcblxuXHRcdC8vIFNldCBhIGN1c3RvbSB0eXBlIHRvIGJlIHRoaXMgZHVhbC1saXN0J3MgaWQuXG5cdFx0ZXZlbnQuZGF0YVRyYW5zZmVyLnNldERhdGEodGhpcy5pZCwgaXRlbVsnX2lkJ10pO1xuXHR9XG5cblx0YWxsb3dEcm9wKGV2ZW50OiBEcmFnRXZlbnQsIGxpc3Q6IEJhc2ljTGlzdCk6IGJvb2xlYW4ge1xuXHRcdGlmIChldmVudC5kYXRhVHJhbnNmZXIudHlwZXMubGVuZ3RoICYmIChldmVudC5kYXRhVHJhbnNmZXIudHlwZXNbMF0gPT09IHRoaXMuaWQpKSB7XG5cdFx0XHRldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXHRcdFx0aWYgKCFsaXN0LmRyYWdTdGFydCkge1xuXHRcdFx0XHRsaXN0LmRyYWdPdmVyID0gdHJ1ZTtcblx0XHRcdH1cblx0XHR9XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG5cblx0ZHJhZ0xlYXZlKCkge1xuXHRcdHRoaXMuYXZhaWxhYmxlLmRyYWdPdmVyID0gZmFsc2U7XG5cdFx0dGhpcy5jb25maXJtZWQuZHJhZ092ZXIgPSBmYWxzZTtcblx0fVxuXG5cdGRyb3AoZXZlbnQ6IERyYWdFdmVudCwgbGlzdDogQmFzaWNMaXN0KSB7XG5cdFx0aWYgKGV2ZW50LmRhdGFUcmFuc2Zlci50eXBlcy5sZW5ndGggJiYgKGV2ZW50LmRhdGFUcmFuc2Zlci50eXBlc1swXSA9PT0gdGhpcy5pZCkpIHtcblx0XHRcdGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG5cdFx0XHR0aGlzLmRyYWdMZWF2ZSgpO1xuXHRcdFx0dGhpcy5kcmFnRW5kKCk7XG5cblx0XHRcdGlmIChsaXN0ID09PSB0aGlzLmF2YWlsYWJsZSkge1xuXHRcdFx0XHR0aGlzLm1vdmVJdGVtKHRoaXMuYXZhaWxhYmxlLCB0aGlzLmNvbmZpcm1lZCk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHR0aGlzLm1vdmVJdGVtKHRoaXMuY29uZmlybWVkLCB0aGlzLmF2YWlsYWJsZSk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0cHJpdmF0ZSB0cnVlVXAoKSB7XG5cdFx0bGV0IGNoYW5nZWQgPSBmYWxzZTtcblxuXHRcdC8vIENsZWFyIHJlbW92ZWQgaXRlbXMuXG5cdFx0bGV0IHBvcyA9IHRoaXMuZGVzdGluYXRpb24ubGVuZ3RoO1xuXHRcdHdoaWxlICgocG9zIC09IDEpID49IDApIHtcblx0XHRcdGNvbnN0IG12ID0gdGhpcy5jb25maXJtZWQubGlzdC5maWx0ZXIoIGNvbmYgPT4ge1xuXHRcdFx0XHRpZiAodHlwZW9mIHRoaXMuZGVzdGluYXRpb25bcG9zXSA9PT0gJ29iamVjdCcpIHtcblx0XHRcdFx0XHRyZXR1cm4gY29uZi5faWQgPT09IHRoaXMuZGVzdGluYXRpb25bcG9zXVt0aGlzLmtleV07XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0cmV0dXJuIGNvbmYuX2lkID09PSB0aGlzLmRlc3RpbmF0aW9uW3Bvc107XG5cdFx0XHRcdH1cblx0XHRcdH0pO1xuXHRcdFx0aWYgKG12Lmxlbmd0aCA9PT0gMCkge1xuXHRcdFx0XHQvLyBOb3QgZm91bmQgc28gcmVtb3ZlLlxuXHRcdFx0XHR0aGlzLmRlc3RpbmF0aW9uLnNwbGljZShwb3MsIDEpO1xuXHRcdFx0XHRjaGFuZ2VkID0gdHJ1ZTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyBQdXNoIGFkZGVkIGl0ZW1zLlxuXHRcdGZvciAobGV0IGkgPSAwLCBsZW4gPSB0aGlzLmNvbmZpcm1lZC5saXN0Lmxlbmd0aDsgaSA8IGxlbjsgaSArPSAxKSB7XG5cdFx0XHRsZXQgbXYgPSB0aGlzLmRlc3RpbmF0aW9uLmZpbHRlciggKGQ6IGFueSkgPT4ge1xuXHRcdFx0XHRpZiAodHlwZW9mIGQgPT09ICdvYmplY3QnKSB7XG5cdFx0XHRcdFx0cmV0dXJuIChkW3RoaXMua2V5XSA9PT0gdGhpcy5jb25maXJtZWQubGlzdFtpXS5faWQpO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdHJldHVybiAoZCA9PT0gdGhpcy5jb25maXJtZWQubGlzdFtpXS5faWQpO1xuXHRcdFx0XHR9XG5cdFx0XHR9KTtcblxuXHRcdFx0aWYgKG12Lmxlbmd0aCA9PT0gMCkge1xuXHRcdFx0XHQvLyBOb3QgZm91bmQgc28gYWRkLlxuXHRcdFx0XHRtdiA9IHRoaXMuc291cmNlLmZpbHRlciggKG86IGFueSkgPT4ge1xuXHRcdFx0XHRcdGlmICh0eXBlb2YgbyA9PT0gJ29iamVjdCcpIHtcblx0XHRcdFx0XHRcdHJldHVybiAob1t0aGlzLmtleV0gPT09IHRoaXMuY29uZmlybWVkLmxpc3RbaV0uX2lkKTtcblx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0cmV0dXJuIChvID09PSB0aGlzLmNvbmZpcm1lZC5saXN0W2ldLl9pZCk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9KTtcblxuXHRcdFx0XHRpZiAobXYubGVuZ3RoID4gMCkge1xuXHRcdFx0XHRcdHRoaXMuZGVzdGluYXRpb24ucHVzaChtdlswXSk7XG5cdFx0XHRcdFx0Y2hhbmdlZCA9IHRydWU7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cblx0XHRpZiAoY2hhbmdlZCkge1xuXHRcdFx0dGhpcy5kZXN0aW5hdGlvbkNoYW5nZS5lbWl0KHRoaXMuZGVzdGluYXRpb24pO1xuXHRcdH1cblx0fVxuXG5cdGZpbmRJdGVtSW5kZXgobGlzdDogQXJyYXk8YW55PiwgaXRlbTogYW55LCBrZXk6IGFueSA9ICdfaWQnKSB7XG5cdFx0bGV0IGlkeCA9IC0xO1xuXG5cdFx0ZnVuY3Rpb24gbWF0Y2hPYmplY3QoZTogYW55KSB7XG5cdFx0XHRpZiAoZS5faWQgPT09IGl0ZW1ba2V5XSkge1xuXHRcdFx0XHRpZHggPSBsaXN0LmluZGV4T2YoZSk7XG5cdFx0XHRcdHJldHVybiB0cnVlO1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblxuXHRcdGZ1bmN0aW9uIG1hdGNoKGU6IGFueSkge1xuXHRcdFx0aWYgKGUuX2lkID09PSBpdGVtKSB7XG5cdFx0XHRcdGlkeCA9IGxpc3QuaW5kZXhPZihlKTtcblx0XHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXG5cdFx0Ly8gQXNzdW1wdGlvbiBpcyB0aGF0IHRoZSBhcnJheXMgZG8gbm90IGhhdmUgZHVwbGljYXRlcy5cblx0XHRpZiAodHlwZW9mIGl0ZW0gPT09ICdvYmplY3QnKSB7XG5cdFx0XHRsaXN0LmZpbHRlcihtYXRjaE9iamVjdCk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGxpc3QuZmlsdGVyKG1hdGNoKTtcblx0XHR9XG5cblx0XHRyZXR1cm4gaWR4O1xuXHR9XG5cblx0cHJpdmF0ZSBtYWtlVW5hdmFpbGFibGUoc291cmNlOiBCYXNpY0xpc3QsIGl0ZW06IGFueSkge1xuXHRcdGNvbnN0IGlkeCA9IHNvdXJjZS5saXN0LmluZGV4T2YoaXRlbSk7XG5cdFx0aWYgKGlkeCAhPT0gLTEpIHtcblx0XHRcdHNvdXJjZS5saXN0LnNwbGljZShpZHgsIDEpO1xuXHRcdH1cblx0fVxuXG5cdG1vdmVJdGVtKHNvdXJjZTogQmFzaWNMaXN0LCB0YXJnZXQ6IEJhc2ljTGlzdCwgaXRlbTogYW55ID0gbnVsbCwgdHJ1ZXVwID0gdHJ1ZSkge1xuXHRcdGxldCBpID0gMDtcblx0XHRsZXQgbGVuID0gc291cmNlLnBpY2subGVuZ3RoO1xuXG5cdFx0aWYgKGl0ZW0pIHtcblx0XHRcdGkgPSBzb3VyY2UubGlzdC5pbmRleE9mKGl0ZW0pO1xuXHRcdFx0bGVuID0gaSArIDE7XG5cdFx0fVxuXG5cdFx0Zm9yICg7IGkgPCBsZW47IGkgKz0gMSkge1xuXHRcdFx0Ly8gSXMgdGhlIHBpY2sgc3RpbGwgaW4gbGlzdD9cblx0XHRcdGxldCBtdjogQXJyYXk8YW55PiA9IFtdO1xuXHRcdFx0aWYgKGl0ZW0pIHtcblx0XHRcdFx0Y29uc3QgaWR4ID0gdGhpcy5maW5kSXRlbUluZGV4KHNvdXJjZS5waWNrLCBpdGVtKTtcblx0XHRcdFx0aWYgKGlkeCAhPT0gLTEpIHtcblx0XHRcdFx0XHRtdlswXSA9IHNvdXJjZS5waWNrW2lkeF07XG5cdFx0XHRcdH1cblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdG12ID0gc291cmNlLmxpc3QuZmlsdGVyKCBzcmMgPT4ge1xuXHRcdFx0XHRcdHJldHVybiAoc3JjLl9pZCA9PT0gc291cmNlLnBpY2tbaV0uX2lkKTtcblx0XHRcdFx0fSk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIFNob3VsZCBvbmx5IGV2ZXIgYmUgMVxuXHRcdFx0aWYgKG12Lmxlbmd0aCA9PT0gMSkge1xuXHRcdFx0XHQvLyBBZGQgaWYgbm90IGFscmVhZHkgaW4gdGFyZ2V0LlxuXHRcdFx0XHRpZiAodGFyZ2V0Lmxpc3QuZmlsdGVyKHRyZyA9PiB0cmcuX2lkID09PSBtdlswXS5faWQpLmxlbmd0aCA9PT0gMCkge1xuXHRcdFx0XHRcdHRhcmdldC5saXN0LnB1c2goIG12WzBdICk7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHR0aGlzLm1ha2VVbmF2YWlsYWJsZShzb3VyY2UsIG12WzBdKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRpZiAodGhpcy5jb21wYXJlICE9PSB1bmRlZmluZWQpIHtcblx0XHRcdHRhcmdldC5saXN0LnNvcnQodGhpcy5jb21wYXJlKTtcblx0XHR9XG5cblx0XHRzb3VyY2UucGljay5sZW5ndGggPSAwO1xuXG5cdFx0Ly8gVXBkYXRlIGRlc3RpbmF0aW9uXG5cdFx0aWYgKHRydWV1cCkge1xuXHRcdFx0dGhpcy50cnVlVXAoKTtcblx0XHR9XG5cblx0XHQvLyBEZWxheSBldmVyLXNvLXNsaWdodGx5IHRvIHByZXZlbnQgcmFjZSBjb25kaXRpb24uXG5cdFx0c2V0VGltZW91dCggKCkgPT4ge1xuXHRcdFx0dGhpcy5vbkZpbHRlcihzb3VyY2UpO1xuXHRcdFx0dGhpcy5vbkZpbHRlcih0YXJnZXQpO1xuXHRcdH0sIDEwKTtcblx0fVxuXG5cdGlzSXRlbVNlbGVjdGVkKGxpc3Q6IEFycmF5PGFueT4sIGl0ZW06IGFueSk6IGJvb2xlYW4ge1xuXHRcdGlmIChsaXN0LmZpbHRlcihlID0+IE9iamVjdC5pcyhlLCBpdGVtKSkubGVuZ3RoID4gMCkge1xuXHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0fVxuXHRcdHJldHVybiBmYWxzZTtcblx0fVxuXG5cdHNoaWZ0Q2xpY2soZXZlbnQ6IE1vdXNlRXZlbnQsIGluZGV4OiBudW1iZXIsIHNvdXJjZTogQmFzaWNMaXN0LCBpdGVtOiBhbnkpIHtcblx0XHRpZiAoZXZlbnQuc2hpZnRLZXkgJiYgc291cmNlLmxhc3QgJiYgIU9iamVjdC5pcyhpdGVtLCBzb3VyY2UubGFzdCkpIHtcblx0XHRcdGNvbnN0IGlkeCA9IHNvdXJjZS5zaWZ0LmluZGV4T2Yoc291cmNlLmxhc3QpO1xuXHRcdFx0aWYgKGluZGV4ID4gaWR4KSB7XG5cdFx0XHRcdGZvciAobGV0IGkgPSAoaWR4ICsgMSk7IGkgPCBpbmRleDsgaSArPSAxKSB7XG5cdFx0XHRcdFx0dGhpcy5zZWxlY3RJdGVtKHNvdXJjZS5waWNrLCBzb3VyY2Uuc2lmdFtpXSk7XG5cdFx0XHRcdH1cblx0XHRcdH0gZWxzZSBpZiAoaWR4ICE9PSAtMSkge1xuXHRcdFx0XHRmb3IgKGxldCBpID0gKGluZGV4ICsgMSk7IGkgPCBpZHg7IGkgKz0gMSkgIHtcblx0XHRcdFx0XHR0aGlzLnNlbGVjdEl0ZW0oc291cmNlLnBpY2ssIHNvdXJjZS5zaWZ0W2ldKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0XHRzb3VyY2UubGFzdCA9IGl0ZW07XG5cdH1cblxuXHRzZWxlY3RJdGVtKGxpc3Q6IEFycmF5PGFueT4sIGl0ZW06IGFueSkge1xuXHRcdGNvbnN0IHBrID0gbGlzdC5maWx0ZXIoIChlOiBhbnkpID0+IHtcblx0XHRcdHJldHVybiBPYmplY3QuaXMoZSwgaXRlbSk7XG5cdFx0fSk7XG5cdFx0aWYgKHBrLmxlbmd0aCA+IDApIHtcblx0XHRcdC8vIEFscmVhZHkgaW4gbGlzdCwgc28gZGVzZWxlY3QuXG5cdFx0XHRmb3IgKGxldCBpID0gMCwgbGVuID0gcGsubGVuZ3RoOyBpIDwgbGVuOyBpICs9IDEpIHtcblx0XHRcdFx0Y29uc3QgaWR4ID0gbGlzdC5pbmRleE9mKHBrW2ldKTtcblx0XHRcdFx0aWYgKGlkeCAhPT0gLTEpIHtcblx0XHRcdFx0XHRsaXN0LnNwbGljZShpZHgsIDEpO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fSBlbHNlIHtcblx0XHRcdGxpc3QucHVzaChpdGVtKTtcblx0XHR9XG5cdH1cblxuXHRzZWxlY3RBbGwoc291cmNlOiBCYXNpY0xpc3QpIHtcblx0XHRzb3VyY2UucGljay5sZW5ndGggPSAwO1xuXHRcdHNvdXJjZS5waWNrID0gc291cmNlLnNpZnQuc2xpY2UoMCk7XG5cdH1cblxuXHRzZWxlY3ROb25lKHNvdXJjZTogQmFzaWNMaXN0KSB7XG5cdFx0c291cmNlLnBpY2subGVuZ3RoID0gMDtcblx0fVxuXG5cdGlzQWxsU2VsZWN0ZWQoc291cmNlOiBCYXNpY0xpc3QpOiBib29sZWFuIHtcblx0XHRpZiAoc291cmNlLmxpc3QubGVuZ3RoID09PSAwIHx8IHNvdXJjZS5saXN0Lmxlbmd0aCA9PT0gc291cmNlLnBpY2subGVuZ3RoKSB7XG5cdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHR9XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG5cblx0aXNBbnlTZWxlY3RlZChzb3VyY2U6IEJhc2ljTGlzdCk6IGJvb2xlYW4ge1xuXHRcdGlmIChzb3VyY2UucGljay5sZW5ndGggPiAwKSB7XG5cdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHR9XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG5cblx0cHJpdmF0ZSB1bnBpY2soc291cmNlOiBCYXNpY0xpc3QpIHtcblx0XHRmb3IgKGxldCBpID0gc291cmNlLnBpY2subGVuZ3RoIC0gMTsgaSA+PSAwOyBpIC09IDEpIHtcblx0XHRcdGlmIChzb3VyY2Uuc2lmdC5pbmRleE9mKHNvdXJjZS5waWNrW2ldKSA9PT0gLTEpIHtcblx0XHRcdFx0c291cmNlLnBpY2suc3BsaWNlKGksIDEpO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdGNsZWFyRmlsdGVyKHNvdXJjZTogQmFzaWNMaXN0KSB7XG5cdFx0aWYgKHNvdXJjZSkge1xuXHRcdFx0c291cmNlLnBpY2tlciA9ICcnO1xuXHRcdFx0dGhpcy5vbkZpbHRlcihzb3VyY2UpO1xuXHRcdH1cblx0fVxuXG5cdG9uRmlsdGVyKHNvdXJjZTogQmFzaWNMaXN0KSB7XG5cdFx0aWYgKHNvdXJjZS5waWNrZXIubGVuZ3RoID4gMCkge1xuXHRcdFx0dHJ5IHtcblx0XHRcdFx0Y29uc3QgZmlsdGVyZWQgPSBzb3VyY2UubGlzdC5maWx0ZXIoIChpdGVtOiBhbnkpID0+IHtcblx0XHRcdFx0XHRpZiAoT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKGl0ZW0pID09PSAnW29iamVjdCBPYmplY3RdJykge1xuXHRcdFx0XHRcdFx0aWYgKGl0ZW0uX25hbWUgIT09IHVuZGVmaW5lZCkge1xuXHRcdFx0XHRcdFx0XHQvLyBAdHMtaWdub3JlOiByZW1vdmUgd2hlbiBkLnRzIGhhcyBsb2NhbGUgYXMgYW4gYXJndW1lbnQuXG5cdFx0XHRcdFx0XHRcdHJldHVybiBpdGVtLl9uYW1lLnRvTG9jYWxlTG93ZXJDYXNlKHRoaXMuZm9ybWF0LmxvY2FsZSkuaW5kZXhPZihzb3VyY2UucGlja2VyLnRvTG9jYWxlTG93ZXJDYXNlKHRoaXMuZm9ybWF0LmxvY2FsZSkpICE9PSAtMTtcblx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRcdC8vIEB0cy1pZ25vcmU6IHJlbW92ZSB3aGVuIGQudHMgaGFzIGxvY2FsZSBhcyBhbiBhcmd1bWVudC5cblx0XHRcdFx0XHRcdFx0cmV0dXJuIEpTT04uc3RyaW5naWZ5KGl0ZW0pLnRvTG9jYWxlTG93ZXJDYXNlKHRoaXMuZm9ybWF0LmxvY2FsZSkuaW5kZXhPZihzb3VyY2UucGlja2VyLnRvTG9jYWxlTG93ZXJDYXNlKHRoaXMuZm9ybWF0LmxvY2FsZSkpICE9PSAtMTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0Ly8gQHRzLWlnbm9yZTogcmVtb3ZlIHdoZW4gZC50cyBoYXMgbG9jYWxlIGFzIGFuIGFyZ3VtZW50LlxuXHRcdFx0XHRcdFx0cmV0dXJuIGl0ZW0udG9Mb2NhbGVMb3dlckNhc2UodGhpcy5mb3JtYXQubG9jYWxlKS5pbmRleE9mKHNvdXJjZS5waWNrZXIudG9Mb2NhbGVMb3dlckNhc2UodGhpcy5mb3JtYXQubG9jYWxlKSkgIT09IC0xO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fSk7XG5cdFx0XHRcdHNvdXJjZS5zaWZ0ID0gZmlsdGVyZWQ7XG5cdFx0XHRcdHRoaXMudW5waWNrKHNvdXJjZSk7XG5cdFx0XHR9IGNhdGNoIChlKSB7XG5cdFx0XHRcdGlmIChlIGluc3RhbmNlb2YgUmFuZ2VFcnJvcikge1xuXHRcdFx0XHRcdHRoaXMuZm9ybWF0LmxvY2FsZSA9IHVuZGVmaW5lZDtcblx0XHRcdFx0fVxuXHRcdFx0XHRzb3VyY2Uuc2lmdCA9IHNvdXJjZS5saXN0O1xuXHRcdFx0fVxuXHRcdH0gZWxzZSB7XG5cdFx0XHRzb3VyY2Uuc2lmdCA9IHNvdXJjZS5saXN0O1xuXHRcdH1cblx0fVxuXG5cdHByaXZhdGUgbWFrZUlkKGl0ZW06IGFueSk6IHN0cmluZyB8IG51bWJlciB7XG5cdFx0aWYgKHR5cGVvZiBpdGVtID09PSAnb2JqZWN0Jykge1xuXHRcdFx0cmV0dXJuIGl0ZW1bdGhpcy5rZXldO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRyZXR1cm4gaXRlbTtcblx0XHR9XG5cdH1cblxuXHQvLyBBbGxvdyBmb3IgY29tcGxleCBuYW1lcyBieSBwYXNzaW5nIGFuIGFycmF5IG9mIHN0cmluZ3MuXG5cdC8vIEV4YW1wbGU6IFtkaXNwbGF5XT1cIlsgJ190eXBlLnN1YnN0cmluZygwLDEpJywgJ19uYW1lJyBdXCJcblx0cHJvdGVjdGVkIG1ha2VOYW1lKGl0ZW06IGFueSwgc2VwYXJhdG9yID0gJ18nKTogc3RyaW5nIHtcblx0XHRjb25zdCBkaXNwbGF5ID0gdGhpcy5kaXNwbGF5O1xuXG5cdFx0ZnVuY3Rpb24gZmFsbGJhY2soaXRtOiBhbnkpIHtcblx0XHRcdHN3aXRjaCAoT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKGl0bSkpIHtcblx0XHRcdGNhc2UgJ1tvYmplY3QgTnVtYmVyXSc6XG5cdFx0XHRcdHJldHVybiBpdG07XG5cdFx0XHRjYXNlICdbb2JqZWN0IFN0cmluZ10nOlxuXHRcdFx0XHRyZXR1cm4gaXRtO1xuXHRcdFx0ZGVmYXVsdDpcblx0XHRcdFx0aWYgKGl0bSAhPT0gdW5kZWZpbmVkKSB7XG5cdFx0XHRcdFx0cmV0dXJuIGl0bVtkaXNwbGF5XTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRyZXR1cm4gJ3VuZGVmaW5lZCc7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cblx0XHRsZXQgc3RyID0gJyc7XG5cblx0XHRpZiAodGhpcy5kaXNwbGF5ICE9PSB1bmRlZmluZWQpIHtcblx0XHRcdHN3aXRjaCAoT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHRoaXMuZGlzcGxheSkpIHtcblx0XHRcdGNhc2UgJ1tvYmplY3QgRnVuY3Rpb25dJzpcblx0XHRcdFx0c3RyID0gdGhpcy5kaXNwbGF5KGl0ZW0pO1xuXHRcdFx0XHRicmVhaztcblxuXHRcdFx0Y2FzZSAnW29iamVjdCBBcnJheV0nOlxuXHRcdFx0XHRmb3IgKGxldCBpID0gMCwgbGVuID0gdGhpcy5kaXNwbGF5Lmxlbmd0aDsgaSA8IGxlbjsgaSArPSAxKSB7XG5cdFx0XHRcdFx0aWYgKHN0ci5sZW5ndGggPiAwKSB7XG5cdFx0XHRcdFx0XHRzdHIgPSBzdHIgKyBzZXBhcmF0b3I7XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0aWYgKHRoaXMuZGlzcGxheVtpXS5pbmRleE9mKCcuJykgPT09IC0xKSB7XG5cdFx0XHRcdFx0XHQvLyBTaW1wbGUsIGp1c3QgYWRkIHRvIHN0cmluZy5cblx0XHRcdFx0XHRcdHN0ciA9IHN0ciArIGl0ZW1bdGhpcy5kaXNwbGF5W2ldXTtcblx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0Ly8gQ29tcGxleCwgc29tZSBhY3Rpb24gbmVlZHMgdG8gYmUgcGVyZm9ybWVkXG5cdFx0XHRcdFx0XHRjb25zdCBwYXJ0cyA9IHRoaXMuZGlzcGxheVtpXS5zcGxpdCgnLicpO1xuXG5cdFx0XHRcdFx0XHRjb25zdCBzID0gaXRlbVtwYXJ0c1swXV07XG5cdFx0XHRcdFx0XHRpZiAocykge1xuXHRcdFx0XHRcdFx0XHQvLyBVc2UgYnJ1dGUgZm9yY2Vcblx0XHRcdFx0XHRcdFx0aWYgKHBhcnRzWzFdLmluZGV4T2YoJ3N1YnN0cmluZycpICE9PSAtMSkge1xuXHRcdFx0XHRcdFx0XHRcdGNvbnN0IG51bXMgPSAocGFydHNbMV0uc3Vic3RyaW5nKHBhcnRzWzFdLmluZGV4T2YoJygnKSArIDEsIHBhcnRzWzFdLmluZGV4T2YoJyknKSkpLnNwbGl0KCcsJyk7XG5cblx0XHRcdFx0XHRcdFx0XHRzd2l0Y2ggKG51bXMubGVuZ3RoKSB7XG5cdFx0XHRcdFx0XHRcdFx0Y2FzZSAxOlxuXHRcdFx0XHRcdFx0XHRcdFx0c3RyID0gc3RyICsgcy5zdWJzdHJpbmcocGFyc2VJbnQobnVtc1swXSwgMTApKTtcblx0XHRcdFx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdFx0XHRcdGNhc2UgMjpcblx0XHRcdFx0XHRcdFx0XHRcdHN0ciA9IHN0ciArIHMuc3Vic3RyaW5nKHBhcnNlSW50KG51bXNbMF0sIDEwKSwgcGFyc2VJbnQobnVtc1sxXSwgMTApKTtcblx0XHRcdFx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdFx0XHRcdGRlZmF1bHQ6XG5cdFx0XHRcdFx0XHRcdFx0XHRzdHIgPSBzdHIgKyBzO1xuXHRcdFx0XHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0XHRcdC8vIG1ldGhvZCBub3QgYXBwcm92ZWQsIHNvIGp1c3QgYWRkIHMuXG5cdFx0XHRcdFx0XHRcdFx0c3RyID0gc3RyICsgcztcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0XHRicmVhaztcblx0XHRcdGRlZmF1bHQ6XG5cdFx0XHRcdHN0ciA9IGZhbGxiYWNrKGl0ZW0pO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdH1cblx0XHR9IGVsc2Uge1xuXHRcdFx0c3RyID0gZmFsbGJhY2soaXRlbSk7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHN0cjtcblx0fVxufVxuIl19