pager.component.js 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514
  1. /**
  2. * @fileoverview added by tsickle
  3. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  4. */
  5. import { ChangeDetectorRef, Component, ElementRef, EventEmitter, forwardRef, Input, Output } from '@angular/core';
  6. import { NG_VALUE_ACCESSOR } from '@angular/forms';
  7. import { PaginationConfig } from './pagination.config';
  8. /** @type {?} */
  9. export var PAGER_CONTROL_VALUE_ACCESSOR = {
  10. provide: NG_VALUE_ACCESSOR,
  11. /* tslint:disable-next-line: no-use-before-declare */
  12. useExisting: forwardRef((/**
  13. * @return {?}
  14. */
  15. function () { return PagerComponent; })),
  16. multi: true
  17. };
  18. var PagerComponent = /** @class */ (function () {
  19. function PagerComponent(elementRef, paginationConfig, changeDetection) {
  20. this.elementRef = elementRef;
  21. this.changeDetection = changeDetection;
  22. /**
  23. * fired when total pages count changes, $event:number equals to total pages count
  24. */
  25. this.numPages = new EventEmitter();
  26. /**
  27. * fired when page was changed, $event:{page, itemsPerPage} equals to
  28. * object with current page index and number of items per page
  29. */
  30. this.pageChanged = new EventEmitter();
  31. this.onChange = Function.prototype;
  32. this.onTouched = Function.prototype;
  33. this.inited = false;
  34. this._page = 1;
  35. this.elementRef = elementRef;
  36. if (!this.config) {
  37. this.configureOptions(Object.assign({}, paginationConfig.main, paginationConfig.pager));
  38. }
  39. }
  40. Object.defineProperty(PagerComponent.prototype, "itemsPerPage", {
  41. /** maximum number of items per page. If value less than 1 will display all items on one page */
  42. get: /**
  43. * maximum number of items per page. If value less than 1 will display all items on one page
  44. * @return {?}
  45. */
  46. function () {
  47. return this._itemsPerPage;
  48. },
  49. set: /**
  50. * @param {?} v
  51. * @return {?}
  52. */
  53. function (v) {
  54. this._itemsPerPage = v;
  55. this.totalPages = this.calculateTotalPages();
  56. },
  57. enumerable: true,
  58. configurable: true
  59. });
  60. Object.defineProperty(PagerComponent.prototype, "totalItems", {
  61. /** total number of items in all pages */
  62. get: /**
  63. * total number of items in all pages
  64. * @return {?}
  65. */
  66. function () {
  67. return this._totalItems;
  68. },
  69. set: /**
  70. * @param {?} v
  71. * @return {?}
  72. */
  73. function (v) {
  74. this._totalItems = v;
  75. this.totalPages = this.calculateTotalPages();
  76. },
  77. enumerable: true,
  78. configurable: true
  79. });
  80. Object.defineProperty(PagerComponent.prototype, "totalPages", {
  81. get: /**
  82. * @return {?}
  83. */
  84. function () {
  85. return this._totalPages;
  86. },
  87. set: /**
  88. * @param {?} v
  89. * @return {?}
  90. */
  91. function (v) {
  92. this._totalPages = v;
  93. this.numPages.emit(v);
  94. if (this.inited) {
  95. this.selectPage(this.page);
  96. }
  97. },
  98. enumerable: true,
  99. configurable: true
  100. });
  101. Object.defineProperty(PagerComponent.prototype, "page", {
  102. get: /**
  103. * @return {?}
  104. */
  105. function () {
  106. return this._page;
  107. },
  108. set: /**
  109. * @param {?} value
  110. * @return {?}
  111. */
  112. function (value) {
  113. /** @type {?} */
  114. var _previous = this._page;
  115. this._page = value > this.totalPages ? this.totalPages : value || 1;
  116. this.changeDetection.markForCheck();
  117. if (_previous === this._page || typeof _previous === 'undefined') {
  118. return;
  119. }
  120. this.pageChanged.emit({
  121. page: this._page,
  122. itemsPerPage: this.itemsPerPage
  123. });
  124. },
  125. enumerable: true,
  126. configurable: true
  127. });
  128. /**
  129. * @param {?} config
  130. * @return {?}
  131. */
  132. PagerComponent.prototype.configureOptions = /**
  133. * @param {?} config
  134. * @return {?}
  135. */
  136. function (config) {
  137. this.config = Object.assign({}, config);
  138. };
  139. /**
  140. * @return {?}
  141. */
  142. PagerComponent.prototype.ngOnInit = /**
  143. * @return {?}
  144. */
  145. function () {
  146. if (typeof window !== 'undefined') {
  147. this.classMap = this.elementRef.nativeElement.getAttribute('class') || '';
  148. }
  149. // watch for maxSize
  150. this.maxSize =
  151. typeof this.maxSize !== 'undefined' ? this.maxSize : this.config.maxSize;
  152. this.rotate =
  153. typeof this.rotate !== 'undefined' ? this.rotate : this.config.rotate;
  154. this.boundaryLinks =
  155. typeof this.boundaryLinks !== 'undefined'
  156. ? this.boundaryLinks
  157. : this.config.boundaryLinks;
  158. this.directionLinks =
  159. typeof this.directionLinks !== 'undefined'
  160. ? this.directionLinks
  161. : this.config.directionLinks;
  162. this.pageBtnClass =
  163. typeof this.pageBtnClass !== 'undefined'
  164. ? this.pageBtnClass
  165. : this.config.pageBtnClass;
  166. // base class
  167. this.itemsPerPage =
  168. typeof this.itemsPerPage !== 'undefined'
  169. ? this.itemsPerPage
  170. : this.config.itemsPerPage;
  171. this.totalPages = this.calculateTotalPages();
  172. // this class
  173. this.pages = this.getPages(this.page, this.totalPages);
  174. this.inited = true;
  175. };
  176. /**
  177. * @param {?} value
  178. * @return {?}
  179. */
  180. PagerComponent.prototype.writeValue = /**
  181. * @param {?} value
  182. * @return {?}
  183. */
  184. function (value) {
  185. this.page = value;
  186. this.pages = this.getPages(this.page, this.totalPages);
  187. };
  188. /**
  189. * @param {?} key
  190. * @return {?}
  191. */
  192. PagerComponent.prototype.getText = /**
  193. * @param {?} key
  194. * @return {?}
  195. */
  196. function (key) {
  197. // tslint:disable-next-line:no-any
  198. return ((/** @type {?} */ (this)))[key + "Text"] || ((/** @type {?} */ (this))).config[key + "Text"];
  199. };
  200. /**
  201. * @return {?}
  202. */
  203. PagerComponent.prototype.noPrevious = /**
  204. * @return {?}
  205. */
  206. function () {
  207. return this.page === 1;
  208. };
  209. /**
  210. * @return {?}
  211. */
  212. PagerComponent.prototype.noNext = /**
  213. * @return {?}
  214. */
  215. function () {
  216. return this.page === this.totalPages;
  217. };
  218. /**
  219. * @param {?} fn
  220. * @return {?}
  221. */
  222. PagerComponent.prototype.registerOnChange = /**
  223. * @param {?} fn
  224. * @return {?}
  225. */
  226. function (fn) {
  227. this.onChange = fn;
  228. };
  229. /**
  230. * @param {?} fn
  231. * @return {?}
  232. */
  233. PagerComponent.prototype.registerOnTouched = /**
  234. * @param {?} fn
  235. * @return {?}
  236. */
  237. function (fn) {
  238. this.onTouched = fn;
  239. };
  240. /**
  241. * @param {?} page
  242. * @param {?=} event
  243. * @return {?}
  244. */
  245. PagerComponent.prototype.selectPage = /**
  246. * @param {?} page
  247. * @param {?=} event
  248. * @return {?}
  249. */
  250. function (page, event) {
  251. if (event) {
  252. event.preventDefault();
  253. }
  254. if (!this.disabled) {
  255. if (event && event.target) {
  256. // tslint:disable-next-line:no-any
  257. /** @type {?} */
  258. var target = event.target;
  259. target.blur();
  260. }
  261. this.writeValue(page);
  262. this.onChange(this.page);
  263. }
  264. };
  265. // Create page object used in template
  266. // Create page object used in template
  267. /**
  268. * @protected
  269. * @param {?} num
  270. * @param {?} text
  271. * @param {?} active
  272. * @return {?}
  273. */
  274. PagerComponent.prototype.makePage =
  275. // Create page object used in template
  276. /**
  277. * @protected
  278. * @param {?} num
  279. * @param {?} text
  280. * @param {?} active
  281. * @return {?}
  282. */
  283. function (num, text, active) {
  284. return { text: text, number: num, active: active };
  285. };
  286. /**
  287. * @protected
  288. * @param {?} currentPage
  289. * @param {?} totalPages
  290. * @return {?}
  291. */
  292. PagerComponent.prototype.getPages = /**
  293. * @protected
  294. * @param {?} currentPage
  295. * @param {?} totalPages
  296. * @return {?}
  297. */
  298. function (currentPage, totalPages) {
  299. /** @type {?} */
  300. var pages = [];
  301. // Default page limits
  302. /** @type {?} */
  303. var startPage = 1;
  304. /** @type {?} */
  305. var endPage = totalPages;
  306. /** @type {?} */
  307. var isMaxSized = typeof this.maxSize !== 'undefined' && this.maxSize < totalPages;
  308. // recompute if maxSize
  309. if (isMaxSized) {
  310. if (this.rotate) {
  311. // Current page is displayed in the middle of the visible ones
  312. startPage = Math.max(currentPage - Math.floor(this.maxSize / 2), 1);
  313. endPage = startPage + this.maxSize - 1;
  314. // Adjust if limit is exceeded
  315. if (endPage > totalPages) {
  316. endPage = totalPages;
  317. startPage = endPage - this.maxSize + 1;
  318. }
  319. }
  320. else {
  321. // Visible pages are paginated with maxSize
  322. startPage =
  323. (Math.ceil(currentPage / this.maxSize) - 1) * this.maxSize + 1;
  324. // Adjust last page if limit is exceeded
  325. endPage = Math.min(startPage + this.maxSize - 1, totalPages);
  326. }
  327. }
  328. // Add page number links
  329. for (var num = startPage; num <= endPage; num++) {
  330. /** @type {?} */
  331. var page = this.makePage(num, num.toString(), num === currentPage);
  332. pages.push(page);
  333. }
  334. // Add links to move between page sets
  335. if (isMaxSized && !this.rotate) {
  336. if (startPage > 1) {
  337. /** @type {?} */
  338. var previousPageSet = this.makePage(startPage - 1, '...', false);
  339. pages.unshift(previousPageSet);
  340. }
  341. if (endPage < totalPages) {
  342. /** @type {?} */
  343. var nextPageSet = this.makePage(endPage + 1, '...', false);
  344. pages.push(nextPageSet);
  345. }
  346. }
  347. return pages;
  348. };
  349. // base class
  350. // base class
  351. /**
  352. * @protected
  353. * @return {?}
  354. */
  355. PagerComponent.prototype.calculateTotalPages =
  356. // base class
  357. /**
  358. * @protected
  359. * @return {?}
  360. */
  361. function () {
  362. /** @type {?} */
  363. var totalPages = this.itemsPerPage < 1
  364. ? 1
  365. : Math.ceil(this.totalItems / this.itemsPerPage);
  366. return Math.max(totalPages || 0, 1);
  367. };
  368. PagerComponent.decorators = [
  369. { type: Component, args: [{
  370. selector: 'pager',
  371. template: "<ul class=\"pager\">\n <li [class.disabled]=\"noPrevious()\" [class.previous]=\"align\"\n [ngClass]=\"{'pull-right': align, 'float-right': align}\"\n class=\"{{ pageBtnClass }}\">\n <a href (click)=\"selectPage(page - 1, $event)\">{{ getText('previous') }}</a>\n </li>\n <li [class.disabled]=\"noNext()\" [class.next]=\"align\"\n [ngClass]=\"{'pull-right': align, 'float-right': align}\"\n class=\"{{ pageBtnClass }}\">\n <a href (click)=\"selectPage(page + 1, $event)\">{{ getText('next') }}</a>\n </li>\n</ul>\n",
  372. providers: [PAGER_CONTROL_VALUE_ACCESSOR]
  373. }] }
  374. ];
  375. /** @nocollapse */
  376. PagerComponent.ctorParameters = function () { return [
  377. { type: ElementRef },
  378. { type: PaginationConfig },
  379. { type: ChangeDetectorRef }
  380. ]; };
  381. PagerComponent.propDecorators = {
  382. align: [{ type: Input }],
  383. maxSize: [{ type: Input }],
  384. boundaryLinks: [{ type: Input }],
  385. directionLinks: [{ type: Input }],
  386. firstText: [{ type: Input }],
  387. previousText: [{ type: Input }],
  388. nextText: [{ type: Input }],
  389. lastText: [{ type: Input }],
  390. rotate: [{ type: Input }],
  391. pageBtnClass: [{ type: Input }],
  392. disabled: [{ type: Input }],
  393. numPages: [{ type: Output }],
  394. pageChanged: [{ type: Output }],
  395. itemsPerPage: [{ type: Input }],
  396. totalItems: [{ type: Input }]
  397. };
  398. return PagerComponent;
  399. }());
  400. export { PagerComponent };
  401. if (false) {
  402. /** @type {?} */
  403. PagerComponent.prototype.config;
  404. /**
  405. * if `true` aligns each link to the sides of pager
  406. * @type {?}
  407. */
  408. PagerComponent.prototype.align;
  409. /**
  410. * limit number for page links in pager
  411. * @type {?}
  412. */
  413. PagerComponent.prototype.maxSize;
  414. /**
  415. * if false first and last buttons will be hidden
  416. * @type {?}
  417. */
  418. PagerComponent.prototype.boundaryLinks;
  419. /**
  420. * if false previous and next buttons will be hidden
  421. * @type {?}
  422. */
  423. PagerComponent.prototype.directionLinks;
  424. /**
  425. * first button text
  426. * @type {?}
  427. */
  428. PagerComponent.prototype.firstText;
  429. /**
  430. * previous button text
  431. * @type {?}
  432. */
  433. PagerComponent.prototype.previousText;
  434. /**
  435. * next button text
  436. * @type {?}
  437. */
  438. PagerComponent.prototype.nextText;
  439. /**
  440. * last button text
  441. * @type {?}
  442. */
  443. PagerComponent.prototype.lastText;
  444. /**
  445. * if true current page will in the middle of pages list
  446. * @type {?}
  447. */
  448. PagerComponent.prototype.rotate;
  449. /**
  450. * add class to <code><li\></code>
  451. * @type {?}
  452. */
  453. PagerComponent.prototype.pageBtnClass;
  454. /**
  455. * if true pagination component will be disabled
  456. * @type {?}
  457. */
  458. PagerComponent.prototype.disabled;
  459. /**
  460. * fired when total pages count changes, $event:number equals to total pages count
  461. * @type {?}
  462. */
  463. PagerComponent.prototype.numPages;
  464. /**
  465. * fired when page was changed, $event:{page, itemsPerPage} equals to
  466. * object with current page index and number of items per page
  467. * @type {?}
  468. */
  469. PagerComponent.prototype.pageChanged;
  470. /** @type {?} */
  471. PagerComponent.prototype.onChange;
  472. /** @type {?} */
  473. PagerComponent.prototype.onTouched;
  474. /** @type {?} */
  475. PagerComponent.prototype.classMap;
  476. /** @type {?} */
  477. PagerComponent.prototype.pages;
  478. /**
  479. * @type {?}
  480. * @protected
  481. */
  482. PagerComponent.prototype._itemsPerPage;
  483. /**
  484. * @type {?}
  485. * @protected
  486. */
  487. PagerComponent.prototype._totalItems;
  488. /**
  489. * @type {?}
  490. * @protected
  491. */
  492. PagerComponent.prototype._totalPages;
  493. /**
  494. * @type {?}
  495. * @protected
  496. */
  497. PagerComponent.prototype.inited;
  498. /**
  499. * @type {?}
  500. * @protected
  501. */
  502. PagerComponent.prototype._page;
  503. /**
  504. * @type {?}
  505. * @private
  506. */
  507. PagerComponent.prototype.elementRef;
  508. /**
  509. * @type {?}
  510. * @private
  511. */
  512. PagerComponent.prototype.changeDetection;
  513. }
  514. //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFnZXIuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6Im5nOi8vbmd4LWJvb3RzdHJhcC9wYWdpbmF0aW9uLyIsInNvdXJjZXMiOlsicGFnZXIuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7QUFBQSxPQUFPLEVBQ0wsaUJBQWlCLEVBQ2pCLFNBQVMsRUFDVCxVQUFVLEVBQ1YsWUFBWSxFQUNaLFVBQVUsRUFDVixLQUFLLEVBRUwsTUFBTSxFQUVQLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBd0IsaUJBQWlCLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUd6RSxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQzs7QUFJdkQsTUFBTSxLQUFPLDRCQUE0QixHQUFhO0lBQ3BELE9BQU8sRUFBRSxpQkFBaUI7O0lBRTFCLFdBQVcsRUFBRSxVQUFVOzs7SUFBQyxjQUFNLE9BQUEsY0FBYyxFQUFkLENBQWMsRUFBQztJQUM3QyxLQUFLLEVBQUUsSUFBSTtDQUNaO0FBRUQ7SUEwR0Usd0JBQW9CLFVBQXNCLEVBQzlCLGdCQUFrQyxFQUMxQixlQUFrQztRQUZsQyxlQUFVLEdBQVYsVUFBVSxDQUFZO1FBRXRCLG9CQUFlLEdBQWYsZUFBZSxDQUFtQjs7OztRQTFFNUMsYUFBUSxHQUF5QixJQUFJLFlBQVksRUFBVSxDQUFDOzs7OztRQUt0RSxnQkFBVyxHQUFtQyxJQUFJLFlBQVksRUFBb0IsQ0FBQztRQXVEbkYsYUFBUSxHQUFHLFFBQVEsQ0FBQyxTQUFTLENBQUM7UUFDOUIsY0FBUyxHQUFHLFFBQVEsQ0FBQyxTQUFTLENBQUM7UUFRckIsV0FBTSxHQUFHLEtBQUssQ0FBQztRQUNmLFVBQUssR0FBRyxDQUFDLENBQUM7UUFLbEIsSUFBSSxDQUFDLFVBQVUsR0FBRyxVQUFVLENBQUM7UUFDN0IsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUU7WUFDaEIsSUFBSSxDQUFDLGdCQUFnQixDQUNuQixNQUFNLENBQUMs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bXBvbmVudCxcbiAgRWxlbWVudFJlZixcbiAgRXZlbnRFbWl0dGVyLFxuICBmb3J3YXJkUmVmLFxuICBJbnB1dCxcbiAgT25Jbml0LFxuICBPdXRwdXQsXG4gIFByb3ZpZGVyXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQ29udHJvbFZhbHVlQWNjZXNzb3IsIE5HX1ZBTFVFX0FDQ0VTU09SIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuXG5pbXBvcnQgeyBQYWdlQ2hhbmdlZEV2ZW50IH0gZnJvbSAnLi9wYWdpbmF0aW9uLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBQYWdpbmF0aW9uQ29uZmlnIH0gZnJvbSAnLi9wYWdpbmF0aW9uLmNvbmZpZyc7XG5cbmltcG9ydCB7IENvbmZpZ01vZGVsLCBQYWdlc01vZGVsIH0gZnJvbSAnLi9tb2RlbHMnO1xuXG5leHBvcnQgY29uc3QgUEFHRVJfQ09OVFJPTF9WQUxVRV9BQ0NFU1NPUjogUHJvdmlkZXIgPSB7XG4gIHByb3ZpZGU6IE5HX1ZBTFVFX0FDQ0VTU09SLFxuICAvKiB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6IG5vLXVzZS1iZWZvcmUtZGVjbGFyZSAqL1xuICB1c2VFeGlzdGluZzogZm9yd2FyZFJlZigoKSA9PiBQYWdlckNvbXBvbmVudCksXG4gIG11bHRpOiB0cnVlXG59O1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdwYWdlcicsXG4gIHRlbXBsYXRlVXJsOiAnLi9wYWdlci5jb21wb25lbnQuaHRtbCcsXG4gIHByb3ZpZGVyczogW1BBR0VSX0NPTlRST0xfVkFMVUVfQUNDRVNTT1JdXG59KVxuZXhwb3J0IGNsYXNzIFBhZ2VyQ29tcG9uZW50IGltcGxlbWVudHMgQ29udHJvbFZhbHVlQWNjZXNzb3IsIE9uSW5pdCB7XG4gIGNvbmZpZzogQ29uZmlnTW9kZWw7XG4gIC8qKiBpZiBgdHJ1ZWAgYWxpZ25zIGVhY2ggbGluayB0byB0aGUgc2lkZXMgb2YgcGFnZXIgKi9cbiAgQElucHV0KCkgYWxpZ246IGJvb2xlYW47XG4gIC8qKiBsaW1pdCBudW1iZXIgZm9yIHBhZ2UgbGlua3MgaW4gcGFnZXIgKi9cbiAgQElucHV0KCkgbWF4U2l6ZTogbnVtYmVyO1xuICAvKiogaWYgZmFsc2UgZmlyc3QgYW5kIGxhc3QgYnV0dG9ucyB3aWxsIGJlIGhpZGRlbiAqL1xuICBASW5wdXQoKSBib3VuZGFyeUxpbmtzOiBib29sZWFuO1xuICAvKiogaWYgZmFsc2UgcHJldmlvdXMgYW5kIG5leHQgYnV0dG9ucyB3aWxsIGJlIGhpZGRlbiAqL1xuICBASW5wdXQoKSBkaXJlY3Rpb25MaW5rczogYm9vbGVhbjtcbiAgLy8gbGFiZWxzXG4gIC8qKiBmaXJzdCBidXR0b24gdGV4dCAqL1xuICBASW5wdXQoKSBmaXJzdFRleHQ6IHN0cmluZztcbiAgLyoqIHByZXZpb3VzIGJ1dHRvbiB0ZXh0ICovXG4gIEBJbnB1dCgpIHByZXZpb3VzVGV4dDogc3RyaW5nO1xuICAvKiogbmV4dCBidXR0b24gdGV4dCAqL1xuICBASW5wdXQoKSBuZXh0VGV4dDogc3RyaW5nO1xuICAvKiogbGFzdCBidXR0b24gdGV4dCAqL1xuICBASW5wdXQoKSBsYXN0VGV4dDogc3RyaW5nO1xuICAvKiogaWYgdHJ1ZSBjdXJyZW50IHBhZ2Ugd2lsbCBpbiB0aGUgbWlkZGxlIG9mIHBhZ2VzIGxpc3QgKi9cbiAgQElucHV0KCkgcm90YXRlOiBib29sZWFuO1xuICAvLyBjc3NcbiAgLyoqIGFkZCBjbGFzcyB0byA8Y29kZT48bGlcXD48L2NvZGU+ICovXG4gIEBJbnB1dCgpIHBhZ2VCdG5DbGFzczogc3RyaW5nO1xuXG4gIC8qKiBpZiB0cnVlIHBhZ2luYXRpb24gY29tcG9uZW50IHdpbGwgYmUgZGlzYWJsZWQgKi9cbiAgQElucHV0KCkgZGlzYWJsZWQ6IGJvb2xlYW47XG5cbiAgLyoqIGZpcmVkIHdoZW4gdG90YWwgcGFnZXMgY291bnQgY2hhbmdlcywgJGV2ZW50Om51bWJlciBlcXVhbHMgdG8gdG90YWwgcGFnZXMgY291bnQgKi9cbiAgQE91dHB1dCgpIG51bVBhZ2VzOiBFdmVudEVtaXR0ZXI8bnVtYmVyPiA9IG5ldyBFdmVudEVtaXR0ZXI8bnVtYmVyPigpO1xuICAvKiogZmlyZWQgd2hlbiBwYWdlIHdhcyBjaGFuZ2VkLCAkZXZlbnQ6e3BhZ2UsIGl0ZW1zUGVyUGFnZX0gZXF1YWxzIHRvXG4gICAqIG9iamVjdCB3aXRoIGN1cnJlbnQgcGFnZSBpbmRleCBhbmQgbnVtYmVyIG9mIGl0ZW1zIHBlciBwYWdlXG4gICAqL1xuICBAT3V0cHV0KClcbiAgcGFnZUNoYW5nZWQ6IEV2ZW50RW1pdHRlcjxQYWdlQ2hhbmdlZEV2ZW50PiA9IG5ldyBFdmVudEVtaXR0ZXI8UGFnZUNoYW5nZWRFdmVudD4oKTtcblxuICAvKiogbWF4aW11bSBudW1iZXIgb2YgaXRlbXMgcGVyIHBhZ2UuIElmIHZhbHVlIGxlc3MgdGhhbiAxIHdpbGwgZGlzcGxheSBhbGwgaXRlbXMgb24gb25lIHBhZ2UgKi9cbiAgQElucHV0KClcbiAgZ2V0IGl0ZW1zUGVyUGFnZSgpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLl9pdGVtc1BlclBhZ2U7XG4gIH1cblxuICBzZXQgaXRlbXNQZXJQYWdlKHY6IG51bWJlcikge1xuICAgIHRoaXMuX2l0ZW1zUGVyUGFnZSA9IHY7XG4gICAgdGhpcy50b3RhbFBhZ2VzID0gdGhpcy5jYWxjdWxhdGVUb3RhbFBhZ2VzKCk7XG4gIH1cblxuICAvKiogdG90YWwgbnVtYmVyIG9mIGl0ZW1zIGluIGFsbCBwYWdlcyAqL1xuICBASW5wdXQoKVxuICBnZXQgdG90YWxJdGVtcygpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLl90b3RhbEl0ZW1zO1xuICB9XG5cbiAgc2V0IHRvdGFsSXRlbXModjogbnVtYmVyKSB7XG4gICAgdGhpcy5fdG90YWxJdGVtcyA9IHY7XG4gICAgdGhpcy50b3RhbFBhZ2VzID0gdGhpcy5jYWxjdWxhdGVUb3RhbFBhZ2VzKCk7XG4gIH1cblxuICBnZXQgdG90YWxQYWdlcygpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLl90b3RhbFBhZ2VzO1xuICB9XG5cbiAgc2V0IHRvdGFsUGFnZXModjogbnVtYmVyKSB7XG4gICAgdGhpcy5fdG90YWxQYWdlcyA9IHY7XG4gICAgdGhpcy5udW1QYWdlcy5lbWl0KHYpO1xuICAgIGlmICh0aGlzLmluaXRlZCkge1xuICAgICAgdGhpcy5zZWxlY3RQYWdlKHRoaXMucGFnZSk7XG4gICAgfVxuICB9XG5cbiAgc2V0IHBhZ2UodmFsdWU6IG51bWJlcikge1xuICAgIGNvbnN0IF9wcmV2aW91cyA9IHRoaXMuX3BhZ2U7XG4gICAgdGhpcy5fcGFnZSA9IHZhbHVlID4gdGhpcy50b3RhbFBhZ2VzID8gdGhpcy50b3RhbFBhZ2VzIDogdmFsdWUgfHwgMTtcbiAgICB0aGlzLmNoYW5nZURldGVjdGlvbi5tYXJrRm9yQ2hlY2soKTtcblxuICAgIGlmIChfcHJldmlvdXMgPT09IHRoaXMuX3BhZ2UgfHwgdHlwZW9mIF9wcmV2aW91cyA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLnBhZ2VDaGFuZ2VkLmVtaXQoe1xuICAgICAgcGFnZTogdGhpcy5fcGFnZSxcbiAgICAgIGl0ZW1zUGVyUGFnZTogdGhpcy5pdGVtc1BlclBhZ2VcbiAgICB9KTtcbiAgfVxuXG4gIGdldCBwYWdlKCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMuX3BhZ2U7XG4gIH1cblxuICBvbkNoYW5nZSA9IEZ1bmN0aW9uLnByb3RvdHlwZTtcbiAgb25Ub3VjaGVkID0gRnVuY3Rpb24ucHJvdG90eXBlO1xuXG4gIGNsYXNzTWFwOiBzdHJpbmc7XG4gIHBhZ2VzOiBQYWdlc01vZGVsW107XG5cbiAgcHJvdGVjdGVkIF9pdGVtc1BlclBhZ2U6IG51bWJlcjtcbiAgcHJvdGVjdGVkIF90b3RhbEl0ZW1zOiBudW1iZXI7XG4gIHByb3RlY3RlZCBfdG90YWxQYWdlczogbnVtYmVyO1xuICBwcm90ZWN0ZWQgaW5pdGVkID0gZmFsc2U7XG4gIHByb3RlY3RlZCBfcGFnZSA9IDE7XG5cbiAgY29uc3RydWN0b3IocHJpdmF0ZSBlbGVtZW50UmVmOiBFbGVtZW50UmVmLFxuICAgICAgICAgICAgICBwYWdpbmF0aW9uQ29uZmlnOiBQYWdpbmF0aW9uQ29uZmlnLFxuICAgICAgICAgICAgICBwcml2YXRlIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0b3JSZWYpIHtcbiAgICB0aGlzLmVsZW1lbnRSZWYgPSBlbGVtZW50UmVmO1xuICAgIGlmICghdGhpcy5jb25maWcpIHtcbiAgICAgIHRoaXMuY29uZmlndXJlT3B0aW9ucyhcbiAgICAgICAgT2JqZWN0LmFzc2lnbih7fSwgcGFnaW5hdGlvbkNvbmZpZy5tYWluLCBwYWdpbmF0aW9uQ29uZmlnLnBhZ2VyKVxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICBjb25maWd1cmVPcHRpb25zKGNvbmZpZzogQ29uZmlnTW9kZWwpOiB2b2lkIHtcbiAgICB0aGlzLmNvbmZpZyA9IE9iamVjdC5hc3NpZ24oe30sIGNvbmZpZyk7XG4gIH1cblxuICBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICBpZiAodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIHRoaXMuY2xhc3NNYXAgPSB0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5nZXRBdHRyaWJ1dGUoJ2NsYXNzJykgfHwgJyc7XG4gICAgfVxuICAgIC8vIHdhdGNoIGZvciBtYXhTaXplXG4gICAgdGhpcy5tYXhTaXplID1cbiAgICAgIHR5cGVvZiB0aGlzLm1heFNpemUgIT09ICd1bmRlZmluZWQnID8gdGhpcy5tYXhTaXplIDogdGhpcy5jb25maWcubWF4U2l6ZTtcbiAgICB0aGlzLnJvdGF0ZSA9XG4gICAgICB0eXBlb2YgdGhpcy5yb3RhdGUgIT09ICd1bmRlZmluZWQnID8gdGhpcy5yb3RhdGUgOiB0aGlzLmNvbmZpZy5yb3RhdGU7XG4gICAgdGhpcy5ib3VuZGFyeUxpbmtzID1cbiAgICAgIHR5cGVvZiB0aGlzLmJvdW5kYXJ5TGlua3MgIT09ICd1bmRlZmluZWQnXG4gICAgICAgID8gdGhpcy5ib3VuZGFyeUxpbmtzXG4gICAgICAgIDogdGhpcy5jb25maWcuYm91bmRhcnlMaW5rcztcbiAgICB0aGlzLmRpcmVjdGlvbkxpbmtzID1cbiAgICAgIHR5cGVvZiB0aGlzLmRpcmVjdGlvbkxpbmtzICE9PSAndW5kZWZpbmVkJ1xuICAgICAgICA/IHRoaXMuZGlyZWN0aW9uTGlua3NcbiAgICAgICAgOiB0aGlzLmNvbmZpZy5kaXJlY3Rpb25MaW5rcztcbiAgICB0aGlzLnBhZ2VCdG5DbGFzcyA9XG4gICAgICB0eXBlb2YgdGhpcy5wYWdlQnRuQ2xhc3MgIT09ICd1bmRlZmluZWQnXG4gICAgICAgID8gdGhpcy5wYWdlQnRuQ2xhc3NcbiAgICAgICAgOiB0aGlzLmNvbmZpZy5wYWdlQnRuQ2xhc3M7XG5cbiAgICAvLyBiYXNlIGNsYXNzXG4gICAgdGhpcy5pdGVtc1BlclBhZ2UgPVxuICAgICAgdHlwZW9mIHRoaXMuaXRlbXNQZXJQYWdlICE9PSAndW5kZWZpbmVkJ1xuICAgICAgICA/IHRoaXMuaXRlbXNQZXJQYWdlXG4gICAgICAgIDogdGhpcy5jb25maWcuaXRlbXNQZXJQYWdlO1xuICAgIHRoaXMudG90YWxQYWdlcyA9IHRoaXMuY2FsY3VsYXRlVG90YWxQYWdlcygpO1xuICAgIC8vIHRoaXMgY2xhc3NcbiAgICB0aGlzLnBhZ2VzID0gdGhpcy5nZXRQYWdlcyh0aGlzLnBhZ2UsIHRoaXMudG90YWxQYWdlcyk7XG4gICAgdGhpcy5pbml0ZWQgPSB0cnVlO1xuICB9XG5cbiAgd3JpdGVWYWx1ZSh2YWx1ZTogbnVtYmVyKTogdm9pZCB7XG4gICAgdGhpcy5wYWdlID0gdmFsdWU7XG4gICAgdGhpcy5wYWdlcyA9IHRoaXMuZ2V0UGFnZXModGhpcy5wYWdlLCB0aGlzLnRvdGFsUGFnZXMpO1xuICB9XG5cbiAgZ2V0VGV4dChrZXk6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWFueVxuICAgIHJldHVybiAodGhpcyBhcyBhbnkpW2Ake2tleX1UZXh0YF0gfHwgKHRoaXMgYXMgYW55KS5jb25maWdbYCR7a2V5fVRleHRgXTtcbiAgfVxuXG4gIG5vUHJldmlvdXMoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMucGFnZSA9PT0gMTtcbiAgfVxuXG4gIG5vTmV4dCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5wYWdlID09PSB0aGlzLnRvdGFsUGFnZXM7XG4gIH1cblxuICByZWdpc3Rlck9uQ2hhbmdlKGZuOiAoKSA9PiB7fSk6IHZvaWQge1xuICAgIHRoaXMub25DaGFuZ2UgPSBmbjtcbiAgfVxuXG4gIHJlZ2lzdGVyT25Ub3VjaGVkKGZuOiAoKSA9PiB7fSk6IHZvaWQge1xuICAgIHRoaXMub25Ub3VjaGVkID0gZm47XG4gIH1cblxuICBzZWxlY3RQYWdlKHBhZ2U6IG51bWJlciwgZXZlbnQ/OiBFdmVudCk6IHZvaWQge1xuICAgIGlmIChldmVudCkge1xuICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICB9XG5cbiAgICBpZiAoIXRoaXMuZGlzYWJsZWQpIHtcbiAgICAgIGlmIChldmVudCAmJiBldmVudC50YXJnZXQpIHtcbiAgICAgICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWFueVxuICAgICAgICBjb25zdCB0YXJnZXQ6IGFueSA9IGV2ZW50LnRhcmdldDtcbiAgICAgICAgdGFyZ2V0LmJsdXIoKTtcbiAgICAgIH1cbiAgICAgIHRoaXMud3JpdGVWYWx1ZShwYWdlKTtcbiAgICAgIHRoaXMub25DaGFuZ2UodGhpcy5wYWdlKTtcbiAgICB9XG4gIH1cblxuICAvLyBDcmVhdGUgcGFnZSBvYmplY3QgdXNlZCBpbiB0ZW1wbGF0ZVxuICBwcm90ZWN0ZWQgbWFrZVBhZ2UobnVtOiBudW1iZXIsXG4gICAgICAgICAgICAgICAgICAgICB0ZXh0OiBzdHJpbmcsXG4gICAgICAgICAgICAgICAgICAgICBhY3RpdmU6IGJvb2xlYW4pOiB7IG51bWJlcjogbnVtYmVyOyB0ZXh0OiBzdHJpbmc7IGFjdGl2ZTogYm9vbGVhbiB9IHtcbiAgICByZXR1cm4ge3RleHQsIG51bWJlcjogbnVtLCBhY3RpdmV9O1xuICB9XG5cbiAgcHJvdGVjdGVkIGdldFBhZ2VzKGN1cnJlbnRQYWdlOiBudW1iZXIsIHRvdGFsUGFnZXM6IG51bWJlcik6IFBhZ2VzTW9kZWxbXSB7XG4gICAgY29uc3QgcGFnZXM6IFBhZ2VzTW9kZWxbXSA9IFtdO1xuXG4gICAgLy8gRGVmYXVsdCBwYWdlIGxpbWl0c1xuICAgIGxldCBzdGFydFBhZ2UgPSAxO1xuICAgIGxldCBlbmRQYWdlID0gdG90YWxQYWdlcztcbiAgICBjb25zdCBpc01heFNpemVkID1cbiAgICAgIHR5cGVvZiB0aGlzLm1heFNpemUgIT09ICd1bmRlZmluZWQnICYmIHRoaXMubWF4U2l6ZSA8IHRvdGFsUGFnZXM7XG5cbiAgICAvLyByZWNvbXB1dGUgaWYgbWF4U2l6ZVxuICAgIGlmIChpc01heFNpemVkKSB7XG4gICAgICBpZiAodGhpcy5yb3RhdGUpIHtcbiAgICAgICAgLy8gQ3VycmVudCBwYWdlIGlzIGRpc3BsYXllZCBpbiB0aGUgbWlkZGxlIG9mIHRoZSB2aXNpYmxlIG9uZXNcbiAgICAgICAgc3RhcnRQYWdlID0gTWF0aC5tYXgoY3VycmVudFBhZ2UgLSBNYXRoLmZsb29yKHRoaXMubWF4U2l6ZSAvIDIpLCAxKTtcbiAgICAgICAgZW5kUGFnZSA9IHN0YXJ0UGFnZSArIHRoaXMubWF4U2l6ZSAtIDE7XG5cbiAgICAgICAgLy8gQWRqdXN0IGlmIGxpbWl0IGlzIGV4Y2VlZGVkXG4gICAgICAgIGlmIChlbmRQYWdlID4gdG90YWxQYWdlcykge1xuICAgICAgICAgIGVuZFBhZ2UgPSB0b3RhbFBhZ2VzO1xuICAgICAgICAgIHN0YXJ0UGFnZSA9IGVuZFBhZ2UgLSB0aGlzLm1heFNpemUgKyAxO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBWaXNpYmxlIHBhZ2VzIGFyZSBwYWdpbmF0ZWQgd2l0aCBtYXhTaXplXG4gICAgICAgIHN0YXJ0UGFnZSA9XG4gICAgICAgICAgKE1hdGguY2VpbChjdXJyZW50UGFnZSAvIHRoaXMubWF4U2l6ZSkgLSAxKSAqIHRoaXMubWF4U2l6ZSArIDE7XG5cbiAgICAgICAgLy8gQWRqdXN0IGxhc3QgcGFnZSBpZiBsaW1pdCBpcyBleGNlZWRlZFxuICAgICAgICBlbmRQYWdlID0gTWF0aC5taW4oc3RhcnRQYWdlICsgdGhpcy5tYXhTaXplIC0gMSwgdG90YWxQYWdlcyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gQWRkIHBhZ2UgbnVtYmVyIGxpbmtzXG4gICAgZm9yIChsZXQgbnVtID0gc3RhcnRQYWdlOyBudW0gPD0gZW5kUGFnZTsgbnVtKyspIHtcbiAgICAgIGNvbnN0IHBhZ2UgPSB0aGlzLm1ha2VQYWdlKG51bSwgbnVtLnRvU3RyaW5nKCksIG51bSA9PT0gY3VycmVudFBhZ2UpO1xuICAgICAgcGFnZXMucHVzaChwYWdlKTtcbiAgICB9XG5cbiAgICAvLyBBZGQgbGlua3MgdG8gbW92ZSBiZXR3ZWVuIHBhZ2Ugc2V0c1xuICAgIGlmIChpc01heFNpemVkICYmICF0aGlzLnJvdGF0ZSkge1xuICAgICAgaWYgKHN0YXJ0UGFnZSA+IDEpIHtcbiAgICAgICAgY29uc3QgcHJldmlvdXNQYWdlU2V0ID0gdGhpcy5tYWtlUGFnZShzdGFydFBhZ2UgLSAxLCAnLi4uJywgZmFsc2UpO1xuICAgICAgICBwYWdlcy51bnNoaWZ0KHByZXZpb3VzUGFnZVNldCk7XG4gICAgICB9XG5cbiAgICAgIGlmIChlbmRQYWdlIDwgdG90YWxQYWdlcykge1xuICAgICAgICBjb25zdCBuZXh0UGFnZVNldCA9IHRoaXMubWFrZVBhZ2UoZW5kUGFnZSArIDEsICcuLi4nLCBmYWxzZSk7XG4gICAgICAgIHBhZ2VzLnB1c2gobmV4dFBhZ2VTZXQpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBwYWdlcztcbiAgfVxuXG4gIC8vIGJhc2UgY2xhc3NcbiAgcHJvdGVjdGVkIGNhbGN1bGF0ZVRvdGFsUGFnZXMoKTogbnVtYmVyIHtcbiAgICBjb25zdCB0b3RhbFBhZ2VzID1cbiAgICAgIHRoaXMuaXRlbXNQZXJQYWdlIDwgMVxuICAgICAgICA/IDFcbiAgICAgICAgOiBNYXRoLmNlaWwodGhpcy50b3RhbEl0ZW1zIC8gdGhpcy5pdGVtc1BlclBhZ2UpO1xuXG4gICAgcmV0dXJuIE1hdGgubWF4KHRvdGFsUGFnZXMgfHwgMCwgMSk7XG4gIH1cbn1cbiJdfQ==