tabset.js 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317
  1. /**
  2. * @fileoverview added by tsickle
  3. * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  4. */
  5. import { Component, ContentChildren, Directive, EventEmitter, Input, Output, QueryList, TemplateRef, ViewEncapsulation } from '@angular/core';
  6. import { NgbTabsetConfig } from './tabset-config';
  7. /** @type {?} */
  8. var nextId = 0;
  9. /**
  10. * A directive to wrap tab titles that need to contain HTML markup or other directives.
  11. *
  12. * Alternatively you could use the `NgbTab.title` input for string titles.
  13. */
  14. var NgbTabTitle = /** @class */ (function () {
  15. function NgbTabTitle(templateRef) {
  16. this.templateRef = templateRef;
  17. }
  18. NgbTabTitle.decorators = [
  19. { type: Directive, args: [{ selector: 'ng-template[ngbTabTitle]' },] }
  20. ];
  21. /** @nocollapse */
  22. NgbTabTitle.ctorParameters = function () { return [
  23. { type: TemplateRef }
  24. ]; };
  25. return NgbTabTitle;
  26. }());
  27. export { NgbTabTitle };
  28. if (false) {
  29. /** @type {?} */
  30. NgbTabTitle.prototype.templateRef;
  31. }
  32. /**
  33. * A directive to wrap content to be displayed in a tab.
  34. */
  35. var NgbTabContent = /** @class */ (function () {
  36. function NgbTabContent(templateRef) {
  37. this.templateRef = templateRef;
  38. }
  39. NgbTabContent.decorators = [
  40. { type: Directive, args: [{ selector: 'ng-template[ngbTabContent]' },] }
  41. ];
  42. /** @nocollapse */
  43. NgbTabContent.ctorParameters = function () { return [
  44. { type: TemplateRef }
  45. ]; };
  46. return NgbTabContent;
  47. }());
  48. export { NgbTabContent };
  49. if (false) {
  50. /** @type {?} */
  51. NgbTabContent.prototype.templateRef;
  52. }
  53. /**
  54. * A directive representing an individual tab.
  55. */
  56. var NgbTab = /** @class */ (function () {
  57. function NgbTab() {
  58. /**
  59. * The tab identifier.
  60. *
  61. * Must be unique for the entire document for proper accessibility support.
  62. */
  63. this.id = "ngb-tab-" + nextId++;
  64. /**
  65. * If `true`, the current tab is disabled and can't be toggled.
  66. */
  67. this.disabled = false;
  68. }
  69. /**
  70. * @return {?}
  71. */
  72. NgbTab.prototype.ngAfterContentChecked = /**
  73. * @return {?}
  74. */
  75. function () {
  76. // We are using @ContentChildren instead of @ContentChild as in the Angular version being used
  77. // only @ContentChildren allows us to specify the {descendants: false} option.
  78. // Without {descendants: false} we are hitting bugs described in:
  79. // https://github.com/ng-bootstrap/ng-bootstrap/issues/2240
  80. this.titleTpl = this.titleTpls.first;
  81. this.contentTpl = this.contentTpls.first;
  82. };
  83. NgbTab.decorators = [
  84. { type: Directive, args: [{ selector: 'ngb-tab' },] }
  85. ];
  86. NgbTab.propDecorators = {
  87. id: [{ type: Input }],
  88. title: [{ type: Input }],
  89. disabled: [{ type: Input }],
  90. titleTpls: [{ type: ContentChildren, args: [NgbTabTitle, { descendants: false },] }],
  91. contentTpls: [{ type: ContentChildren, args: [NgbTabContent, { descendants: false },] }]
  92. };
  93. return NgbTab;
  94. }());
  95. export { NgbTab };
  96. if (false) {
  97. /**
  98. * The tab identifier.
  99. *
  100. * Must be unique for the entire document for proper accessibility support.
  101. * @type {?}
  102. */
  103. NgbTab.prototype.id;
  104. /**
  105. * The tab title.
  106. *
  107. * Use the [`NgbTabTitle`](#/components/tabset/api#NgbTabTitle) directive for non-string titles.
  108. * @type {?}
  109. */
  110. NgbTab.prototype.title;
  111. /**
  112. * If `true`, the current tab is disabled and can't be toggled.
  113. * @type {?}
  114. */
  115. NgbTab.prototype.disabled;
  116. /** @type {?} */
  117. NgbTab.prototype.titleTpl;
  118. /** @type {?} */
  119. NgbTab.prototype.contentTpl;
  120. /** @type {?} */
  121. NgbTab.prototype.titleTpls;
  122. /** @type {?} */
  123. NgbTab.prototype.contentTpls;
  124. }
  125. /**
  126. * The payload of the change event fired right before the tab change.
  127. * @record
  128. */
  129. export function NgbTabChangeEvent() { }
  130. if (false) {
  131. /**
  132. * The id of the currently active tab.
  133. * @type {?}
  134. */
  135. NgbTabChangeEvent.prototype.activeId;
  136. /**
  137. * The id of the newly selected tab.
  138. * @type {?}
  139. */
  140. NgbTabChangeEvent.prototype.nextId;
  141. /**
  142. * Calling this function will prevent tab switching.
  143. * @type {?}
  144. */
  145. NgbTabChangeEvent.prototype.preventDefault;
  146. }
  147. /**
  148. * A component that makes it easy to create tabbed interface.
  149. */
  150. var NgbTabset = /** @class */ (function () {
  151. function NgbTabset(config) {
  152. /**
  153. * If `true`, non-visible tabs content will be removed from DOM. Otherwise it will just be hidden.
  154. */
  155. this.destroyOnHide = true;
  156. /**
  157. * A tab change event emitted right before the tab change happens.
  158. *
  159. * See [`NgbTabChangeEvent`](#/components/tabset/api#NgbTabChangeEvent) for payload details.
  160. */
  161. this.tabChange = new EventEmitter();
  162. this.type = config.type;
  163. this.justify = config.justify;
  164. this.orientation = config.orientation;
  165. }
  166. Object.defineProperty(NgbTabset.prototype, "justify", {
  167. /**
  168. * The horizontal alignment of the tabs with flexbox utilities.
  169. */
  170. set: /**
  171. * The horizontal alignment of the tabs with flexbox utilities.
  172. * @param {?} className
  173. * @return {?}
  174. */
  175. function (className) {
  176. if (className === 'fill' || className === 'justified') {
  177. this.justifyClass = "nav-" + className;
  178. }
  179. else {
  180. this.justifyClass = "justify-content-" + className;
  181. }
  182. },
  183. enumerable: true,
  184. configurable: true
  185. });
  186. /**
  187. * Selects the tab with the given id and shows its associated content panel.
  188. *
  189. * Any other tab that was previously selected becomes unselected and its associated pane is removed from DOM or
  190. * hidden depending on the `destroyOnHide` value.
  191. */
  192. /**
  193. * Selects the tab with the given id and shows its associated content panel.
  194. *
  195. * Any other tab that was previously selected becomes unselected and its associated pane is removed from DOM or
  196. * hidden depending on the `destroyOnHide` value.
  197. * @param {?} tabId
  198. * @return {?}
  199. */
  200. NgbTabset.prototype.select = /**
  201. * Selects the tab with the given id and shows its associated content panel.
  202. *
  203. * Any other tab that was previously selected becomes unselected and its associated pane is removed from DOM or
  204. * hidden depending on the `destroyOnHide` value.
  205. * @param {?} tabId
  206. * @return {?}
  207. */
  208. function (tabId) {
  209. /** @type {?} */
  210. var selectedTab = this._getTabById(tabId);
  211. if (selectedTab && !selectedTab.disabled && this.activeId !== selectedTab.id) {
  212. /** @type {?} */
  213. var defaultPrevented_1 = false;
  214. this.tabChange.emit({ activeId: this.activeId, nextId: selectedTab.id, preventDefault: (/**
  215. * @return {?}
  216. */
  217. function () { defaultPrevented_1 = true; }) });
  218. if (!defaultPrevented_1) {
  219. this.activeId = selectedTab.id;
  220. }
  221. }
  222. };
  223. /**
  224. * @return {?}
  225. */
  226. NgbTabset.prototype.ngAfterContentChecked = /**
  227. * @return {?}
  228. */
  229. function () {
  230. // auto-correct activeId that might have been set incorrectly as input
  231. /** @type {?} */
  232. var activeTab = this._getTabById(this.activeId);
  233. this.activeId = activeTab ? activeTab.id : (this.tabs.length ? this.tabs.first.id : null);
  234. };
  235. /**
  236. * @private
  237. * @param {?} id
  238. * @return {?}
  239. */
  240. NgbTabset.prototype._getTabById = /**
  241. * @private
  242. * @param {?} id
  243. * @return {?}
  244. */
  245. function (id) {
  246. /** @type {?} */
  247. var tabsWithId = this.tabs.filter((/**
  248. * @param {?} tab
  249. * @return {?}
  250. */
  251. function (tab) { return tab.id === id; }));
  252. return tabsWithId.length ? tabsWithId[0] : null;
  253. };
  254. NgbTabset.decorators = [
  255. { type: Component, args: [{
  256. selector: 'ngb-tabset',
  257. exportAs: 'ngbTabset',
  258. encapsulation: ViewEncapsulation.None,
  259. template: "\n <ul [class]=\"'nav nav-' + type + (orientation == 'horizontal'? ' ' + justifyClass : ' flex-column')\" role=\"tablist\">\n <li class=\"nav-item\" *ngFor=\"let tab of tabs\">\n <a [id]=\"tab.id\" class=\"nav-link\" [class.active]=\"tab.id === activeId\" [class.disabled]=\"tab.disabled\"\n href (click)=\"select(tab.id); $event.preventDefault()\" role=\"tab\" [attr.tabindex]=\"(tab.disabled ? '-1': undefined)\"\n [attr.aria-controls]=\"(!destroyOnHide || tab.id === activeId ? tab.id + '-panel' : null)\"\n [attr.aria-selected]=\"tab.id === activeId\" [attr.aria-disabled]=\"tab.disabled\">\n {{tab.title}}<ng-template [ngTemplateOutlet]=\"tab.titleTpl?.templateRef\"></ng-template>\n </a>\n </li>\n </ul>\n <div class=\"tab-content\">\n <ng-template ngFor let-tab [ngForOf]=\"tabs\">\n <div\n class=\"tab-pane {{tab.id === activeId ? 'active' : null}}\"\n *ngIf=\"!destroyOnHide || tab.id === activeId\"\n role=\"tabpanel\"\n [attr.aria-labelledby]=\"tab.id\" id=\"{{tab.id}}-panel\">\n <ng-template [ngTemplateOutlet]=\"tab.contentTpl?.templateRef\"></ng-template>\n </div>\n </ng-template>\n </div>\n "
  260. }] }
  261. ];
  262. /** @nocollapse */
  263. NgbTabset.ctorParameters = function () { return [
  264. { type: NgbTabsetConfig }
  265. ]; };
  266. NgbTabset.propDecorators = {
  267. tabs: [{ type: ContentChildren, args: [NgbTab,] }],
  268. activeId: [{ type: Input }],
  269. destroyOnHide: [{ type: Input }],
  270. justify: [{ type: Input }],
  271. orientation: [{ type: Input }],
  272. type: [{ type: Input }],
  273. tabChange: [{ type: Output }]
  274. };
  275. return NgbTabset;
  276. }());
  277. export { NgbTabset };
  278. if (false) {
  279. /** @type {?} */
  280. NgbTabset.prototype.justifyClass;
  281. /** @type {?} */
  282. NgbTabset.prototype.tabs;
  283. /**
  284. * The identifier of the tab that should be opened **initially**.
  285. *
  286. * For subsequent tab switches use the `.select()` method and the `(tabChange)` event.
  287. * @type {?}
  288. */
  289. NgbTabset.prototype.activeId;
  290. /**
  291. * If `true`, non-visible tabs content will be removed from DOM. Otherwise it will just be hidden.
  292. * @type {?}
  293. */
  294. NgbTabset.prototype.destroyOnHide;
  295. /**
  296. * The orientation of the tabset.
  297. * @type {?}
  298. */
  299. NgbTabset.prototype.orientation;
  300. /**
  301. * Type of navigation to be used for tabs.
  302. *
  303. * Currently Bootstrap supports only `"tabs"` and `"pills"`.
  304. *
  305. * Since `3.0.0` can also be an arbitrary string (ex. for custom themes).
  306. * @type {?}
  307. */
  308. NgbTabset.prototype.type;
  309. /**
  310. * A tab change event emitted right before the tab change happens.
  311. *
  312. * See [`NgbTabChangeEvent`](#/components/tabset/api#NgbTabChangeEvent) for payload details.
  313. * @type {?}
  314. */
  315. NgbTabset.prototype.tabChange;
  316. }
  317. //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFic2V0LmpzIiwic291cmNlUm9vdCI6Im5nOi8vQG5nLWJvb3RzdHJhcC9uZy1ib290c3RyYXAvIiwic291cmNlcyI6WyJ0YWJzZXQvdGFic2V0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7QUFBQSxPQUFPLEVBRUwsU0FBUyxFQUNULGVBQWUsRUFDZixTQUFTLEVBQ1QsWUFBWSxFQUNaLEtBQUssRUFDTCxNQUFNLEVBQ04sU0FBUyxFQUNULFdBQVcsRUFDWCxpQkFBaUIsRUFDbEIsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFDLGVBQWUsRUFBQyxNQUFNLGlCQUFpQixDQUFDOztJQUU1QyxNQUFNLEdBQUcsQ0FBQzs7Ozs7O0FBT2Q7SUFFRSxxQkFBbUIsV0FBNkI7UUFBN0IsZ0JBQVcsR0FBWCxXQUFXLENBQWtCO0lBQUcsQ0FBQzs7Z0JBRnJELFNBQVMsU0FBQyxFQUFDLFFBQVEsRUFBRSwwQkFBMEIsRUFBQzs7OztnQkFaL0MsV0FBVzs7SUFlYixrQkFBQztDQUFBLEFBSEQsSUFHQztTQUZZLFdBQVc7OztJQUNWLGtDQUFvQzs7Ozs7QUFNbEQ7SUFFRSx1QkFBbUIsV0FBNkI7UUFBN0IsZ0JBQVcsR0FBWCxXQUFXLENBQWtCO0lBQUcsQ0FBQzs7Z0JBRnJELFNBQVMsU0FBQyxFQUFDLFFBQVEsRUFBRSw0QkFBNEIsRUFBQzs7OztnQkFwQmpELFdBQVc7O0lBdUJiLG9CQUFDO0NBQUEsQUFIRCxJQUdDO1NBRlksYUFBYTs7O0lBQ1osb0NBQW9DOzs7OztBQU1sRDtJQUFBOzs7Ozs7UUFPVyxPQUFFLEdBQUcsYUFBVyxNQUFNLEVBQUksQ0FBQzs7OztRQVkzQixhQUFRLEdBQUcsS0FBSyxDQUFDO0lBZ0I1QixDQUFDOzs7O0lBUkMsc0NBQXFCOzs7SUFBckI7UUFDRSw4RkFBOEY7UUFDOUYsOEVBQThFO1FBQzlFLGlFQUFpRTtRQUNqRSwyREFBMkQ7UUFDM0QsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLEtB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LElBQUksT0FBQSxHQUFHLENBQUMsRUFBRSxLQUFLLEVBQUUsRUFBYixDQUFhLEVBQUM7UUFDakUsT0FBTyxVQUFVLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQztJQUNsRCxDQUFDOztnQkFqSEYsU0FBUyxTQUFDO29CQUNULFFBQVEsRUFBRSxZQUFZO29CQUN0QixRQUFRLEVBQUUsV0FBVztvQkFDckIsYUFBYSxFQUFFLGlCQUFpQixDQUFDLElBQUk7b0JBQ3JDLFFBQVEsRUFBRSxxdUNBc0JUO2lCQUNGOzs7O2dCQWhITyxlQUFlOzs7dUJBb0hwQixlQUFlLFNBQUMsTUFBTTsyQkFPdEIsS0FBSztnQ0FLTCxLQUFLOzBCQUtMLEtBQUs7OEJBWUwsS0FBSzt1QkFTTCxLQUFLOzRCQU9MLE1BQU07O0lBc0NULGdCQUFDO0NBQUEsQUFsSEQsSUFrSEM7U0F0RlksU0FBUzs7O0lBQ3BCLGlDQUFxQjs7SUFFckIseUJBQWlEOzs7Ozs7O0lBT2pELDZCQUEwQjs7Ozs7SUFLMUIsa0NBQThCOzs7OztJQWlCOUIsZ0NBQWdEOzs7Ozs7Ozs7SUFTaEQseUJBQXlDOzs7Ozs7O0lBT3pDLDhCQUE0RCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIEFmdGVyQ29udGVudENoZWNrZWQsXG4gIENvbXBvbmVudCxcbiAgQ29udGVudENoaWxkcmVuLFxuICBEaXJlY3RpdmUsXG4gIEV2ZW50RW1pdHRlcixcbiAgSW5wdXQsXG4gIE91dHB1dCxcbiAgUXVlcnlMaXN0LFxuICBUZW1wbGF0ZVJlZixcbiAgVmlld0VuY2Fwc3VsYXRpb25cbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQge05nYlRhYnNldENvbmZpZ30gZnJvbSAnLi90YWJzZXQtY29uZmlnJztcblxubGV0IG5leHRJZCA9IDA7XG5cbi8qKlxuICogQSBkaXJlY3RpdmUgdG8gd3JhcCB0YWIgdGl0bGVzIHRoYXQgbmVlZCB0byBjb250YWluIEhUTUwgbWFya3VwIG9yIG90aGVyIGRpcmVjdGl2ZXMuXG4gKlxuICogQWx0ZXJuYXRpdmVseSB5b3UgY291bGQgdXNlIHRoZSBgTmdiVGFiLnRpdGxlYCBpbnB1dCBmb3Igc3RyaW5nIHRpdGxlcy5cbiAqL1xuQERpcmVjdGl2ZSh7c2VsZWN0b3I6ICduZy10ZW1wbGF0ZVtuZ2JUYWJUaXRsZV0nfSlcbmV4cG9ydCBjbGFzcyBOZ2JUYWJUaXRsZSB7XG4gIGNvbnN0cnVjdG9yKHB1YmxpYyB0ZW1wbGF0ZVJlZjogVGVtcGxhdGVSZWY8YW55Pikge31cbn1cblxuLyoqXG4gKiBBIGRpcmVjdGl2ZSB0byB3cmFwIGNvbnRlbnQgdG8gYmUgZGlzcGxheWVkIGluIGEgdGFiLlxuICovXG5ARGlyZWN0aXZlKHtzZWxlY3RvcjogJ25nLXRlbXBsYXRlW25nYlRhYkNvbnRlbnRdJ30pXG5leHBvcnQgY2xhc3MgTmdiVGFiQ29udGVudCB7XG4gIGNvbnN0cnVjdG9yKHB1YmxpYyB0ZW1wbGF0ZVJlZjogVGVtcGxhdGVSZWY8YW55Pikge31cbn1cblxuLyoqXG4gKiBBIGRpcmVjdGl2ZSByZXByZXNlbnRpbmcgYW4gaW5kaXZpZHVhbCB0YWIuXG4gKi9cbkBEaXJlY3RpdmUoe3NlbGVjdG9yOiAnbmdiLXRhYid9KVxuZXhwb3J0IGNsYXNzIE5nYlRhYiBpbXBsZW1lbnRzIEFmdGVyQ29udGVudENoZWNrZWQge1xuICAvKipcbiAgICogVGhlIHRhYiBpZGVudGlmaWVyLlxuICAgKlxuICAgKiBNdXN0IGJlIHVuaXF1ZSBmb3IgdGhlIGVudGlyZSBkb2N1bWVudCBmb3IgcHJvcGVyIGFjY2Vzc2liaWxpdHkgc3VwcG9ydC5cbiAgICovXG4gIEBJbnB1dCgpIGlkID0gYG5nYi10YWItJHtuZXh0SWQrK31gO1xuXG4gIC8qKlxuICAgKiBUaGUgdGFiIHRpdGxlLlxuICAgKlxuICAgKiBVc2UgdGhlIFtgTmdiVGFiVGl0bGVgXSgjL2NvbXBvbmVudHMvdGFic2V0L2FwaSNOZ2JUYWJUaXRsZSkgZGlyZWN0aXZlIGZvciBub24tc3RyaW5nIHRpdGxlcy5cbiAgICovXG4gIEBJbnB1dCgpIHRpdGxlOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIElmIGB0cnVlYCwgdGhlIGN1cnJlbnQgdGFiIGlzIGRpc2FibGVkIGFuZCBjYW4ndCBiZSB0b2dnbGVkLlxuICAgKi9cbiAgQElucHV0KCkgZGlzYWJsZWQgPSBmYWxzZTtcblxuICB0aXRsZVRwbDogTmdiVGFiVGl0bGUgfCBudWxsO1xuICBjb250ZW50VHBsOiBOZ2JUYWJDb250ZW50IHwgbnVsbDtcblxuICBAQ29udGVudENoaWxkcmVuKE5nYlRhYlRpdGxlLCB7ZGVzY2VuZGFudHM6IGZhbHNlfSkgdGl0bGVUcGxzOiBRdWVyeUxpc3Q8TmdiVGFiVGl0bGU+O1xuICBAQ29udGVudENoaWxkcmVuKE5nYlRhYkNvbnRlbnQsIHtkZXNjZW5kYW50czogZmFsc2V9KSBjb250ZW50VHBsczogUXVlcnlMaXN0PE5nYlRhYkNvbnRlbnQ+O1xuXG4gIG5nQWZ0ZXJDb250ZW50Q2hlY2tlZCgpIHtcbiAgICAvLyBXZSBhcmUgdXNpbmcgQENvbnRlbnRDaGlsZHJlbiBpbnN0ZWFkIG9mIEBDb250ZW50Q2hpbGQgYXMgaW4gdGhlIEFuZ3VsYXIgdmVyc2lvbiBiZWluZyB1c2VkXG4gICAgLy8gb25seSBAQ29udGVudENoaWxkcmVuIGFsbG93cyB1cyB0byBzcGVjaWZ5IHRoZSB7ZGVzY2VuZGFudHM6IGZhbHNlfSBvcHRpb24uXG4gICAgLy8gV2l0aG91dCB7ZGVzY2VuZGFudHM6IGZhbHNlfSB3ZSBhcmUgaGl0dGluZyBidWdzIGRlc2NyaWJlZCBpbjpcbiAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vbmctYm9vdHN0cmFwL25nLWJvb3RzdHJhcC9pc3N1ZXMvMjI0MFxuICAgIHRoaXMudGl0bGVUcGwgPSB0aGlzLnRpdGxlVHBscy5maXJzdDtcbiAgICB0aGlzLmNvbnRlbnRUcGwgPSB0aGlzLmNvbnRlbnRUcGxzLmZpcnN0O1xuICB9XG59XG5cbi8qKlxuICogVGhlIHBheWxvYWQgb2YgdGhlIGNoYW5nZSBldmVudCBmaXJlZCByaWdodCBiZWZvcmUgdGhlIHRhYiBjaGFuZ2UuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgTmdiVGFiQ2hhbmdlRXZlbnQge1xuICAvKipcbiAgICogVGhlIGlkIG9mIHRoZSBjdXJyZW50bHkgYWN0aXZlIHRhYi5cbiAgICovXG4gIGFjdGl2ZUlkOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBpZCBvZiB0aGUgbmV3bHkgc2VsZWN0ZWQgdGFiLlxuICAgKi9cbiAgbmV4dElkOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIENhbGxpbmcgdGhpcyBmdW5jdGlvbiB3aWxsIHByZXZlbnQgdGFiIHN3aXRjaGluZy5cbiAgICovXG4gIHByZXZlbnREZWZhdWx0OiAoKSA9PiB2b2lkO1xufVxuXG4vKipcbiAqIEEgY29tcG9uZW50IHRoYXQgbWFrZXMgaXQgZWFzeSB0byBjcmVhdGUgdGFiYmVkIGludGVyZmFjZS5cbiAqL1xuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnbmdiLXRhYnNldCcsXG4gIGV4cG9ydEFzOiAnbmdiVGFic2V0JyxcbiAgZW5jYXBzdWxhdGlvbjogVmlld0VuY2Fwc3VsYXRpb24uTm9uZSxcbiAgdGVtcGxhdGU6IGBcbiAgICA8dWwgW2NsYXNzXT1cIiduYXYgbmF2LScgKyB0eXBlICsgKG9yaWVudGF0aW9uID09ICdob3Jpem9udGFsJz8gICcgJyArIGp1c3RpZnlDbGFzcyA6ICcgZmxleC1jb2x1bW4nKVwiIHJvbGU9XCJ0YWJsaXN0XCI+XG4gICAgICA8bGkgY2xhc3M9XCJuYXYtaXRlbVwiICpuZ0Zvcj1cImxldCB0YWIgb2YgdGFic1wiPlxuICAgICAgICA8YSBbaWRdPVwidGFiLmlkXCIgY2xhc3M9XCJuYXYtbGlua1wiIFtjbGFzcy5hY3RpdmVdPVwidGFiLmlkID09PSBhY3RpdmVJZFwiIFtjbGFzcy5kaXNhYmxlZF09XCJ0YWIuZGlzYWJsZWRcIlxuICAgICAgICAgIGhyZWYgKGNsaWNrKT1cInNlbGVjdCh0YWIuaWQpOyAkZXZlbnQucHJldmVudERlZmF1bHQoKVwiIHJvbGU9XCJ0YWJcIiBbYXR0ci50YWJpbmRleF09XCIodGFiLmRpc2FibGVkID8gJy0xJzogdW5kZWZpbmVkKVwiXG4gICAgICAgICAgW2F0dHIuYXJpYS1jb250cm9sc109XCIoIWRlc3Ryb3lPbkhpZGUgfHwgdGFiLmlkID09PSBhY3RpdmVJZCA/IHRhYi5pZCArICctcGFuZWwnIDogbnVsbClcIlxuICAgICAgICAgIFthdHRyLmFyaWEtc2VsZWN0ZWRdPVwidGFiLmlkID09PSBhY3RpdmVJZFwiIFthdHRyLmFyaWEtZGlzYWJsZWRdPVwidGFiLmRpc2FibGVkXCI+XG4gICAgICAgICAge3t0YWIudGl0bGV9fTxuZy10ZW1wbGF0ZSBbbmdUZW1wbGF0ZU91dGxldF09XCJ0YWIudGl0bGVUcGw/LnRlbXBsYXRlUmVmXCI+PC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgPC9hPlxuICAgICAgPC9saT5cbiAgICA8L3VsPlxuICAgIDxkaXYgY2xhc3M9XCJ0YWItY29udGVudFwiPlxuICAgICAgPG5nLXRlbXBsYXRlIG5nRm9yIGxldC10YWIgW25nRm9yT2ZdPVwidGFic1wiPlxuICAgICAgICA8ZGl2XG4gICAgICAgICAgY2xhc3M9XCJ0YWItcGFuZSB7e3RhYi5pZCA9PT0gYWN0aXZlSWQgPyAnYWN0aXZlJyA6IG51bGx9fVwiXG4gICAgICAgICAgKm5nSWY9XCIhZGVzdHJveU9uSGlkZSB8fCB0YWIuaWQgPT09IGFjdGl2ZUlkXCJcbiAgICAgICAgICByb2xlPVwidGFicGFuZWxcIlxuICAgICAgICAgIFthdHRyLmFyaWEtbGFiZWxsZWRieV09XCJ0YWIuaWRcIiBpZD1cInt7dGFiLmlkfX0tcGFuZWxcIj5cbiAgICAgICAgICA8bmctdGVtcGxhdGUgW25nVGVtcGxhdGVPdXRsZXRdPVwidGFiLmNvbnRlbnRUcGw/LnRlbXBsYXRlUmVmXCI+PC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L25nLXRlbXBsYXRlPlxuICAgIDwvZGl2PlxuICBgXG59KVxuZXhwb3J0IGNsYXNzIE5nYlRhYnNldCBpbXBsZW1lbnRzIEFmdGVyQ29udGVudENoZWNrZWQge1xuICBqdXN0aWZ5Q2xhc3M6IHN0cmluZztcblxuICBAQ29udGVudENoaWxkcmVuKE5nYlRhYikgdGFiczogUXVlcnlMaXN0PE5nYlRhYj47XG5cbiAgLyoqXG4gICAqIFRoZSBpZGVudGlmaWVyIG9mIHRoZSB0YWIgdGhhdCBzaG91bGQgYmUgb3BlbmVkICoqaW5pdGlhbGx5KiouXG4gICAqXG4gICAqIEZvciBzdWJzZXF1ZW50IHRhYiBzd2l0Y2hlcyB1c2UgdGhlIGAuc2VsZWN0KClgIG1ldGhvZCBhbmQgdGhlIGAodGFiQ2hhbmdlKWAgZXZlbnQuXG4gICAqL1xuICBASW5wdXQoKSBhY3RpdmVJZDogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBJZiBgdHJ1ZWAsIG5vbi12aXNpYmxlIHRhYnMgY29udGVudCB3aWxsIGJlIHJlbW92ZWQgZnJvbSBET00uIE90aGVyd2lzZSBpdCB3aWxsIGp1c3QgYmUgaGlkZGVuLlxuICAgKi9cbiAgQElucHV0KCkgZGVzdHJveU9uSGlkZSA9IHRydWU7XG5cbiAgLyoqXG4gICAqIFRoZSBob3Jpem9udGFsIGFsaWdubWVudCBvZiB0aGUgdGFicyB3aXRoIGZsZXhib3ggdXRpbGl0aWVzLlxuICAgKi9cbiAgQElucHV0KClcbiAgc2V0IGp1c3RpZnkoY2xhc3NOYW1lOiAnc3RhcnQnIHwgJ2NlbnRlcicgfCAnZW5kJyB8ICdmaWxsJyB8ICdqdXN0aWZpZWQnKSB7XG4gICAgaWYgKGNsYXNzTmFtZSA9PT0gJ2ZpbGwnIHx8IGNsYXNzTmFtZSA9PT0gJ2p1c3RpZmllZCcpIHtcbiAgICAgIHRoaXMuanVzdGlmeUNsYXNzID0gYG5hdi0ke2NsYXNzTmFtZX1gO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmp1c3RpZnlDbGFzcyA9IGBqdXN0aWZ5LWNvbnRlbnQtJHtjbGFzc05hbWV9YDtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogVGhlIG9yaWVudGF0aW9uIG9mIHRoZSB0YWJzZXQuXG4gICAqL1xuICBASW5wdXQoKSBvcmllbnRhdGlvbjogJ2hvcml6b250YWwnIHwgJ3ZlcnRpY2FsJztcblxuICAvKipcbiAgICogVHlwZSBvZiBuYXZpZ2F0aW9uIHRvIGJlIHVzZWQgZm9yIHRhYnMuXG4gICAqXG4gICAqIEN1cnJlbnRseSBCb290c3RyYXAgc3VwcG9ydHMgb25seSBgXCJ0YWJzXCJgIGFuZCBgXCJwaWxsc1wiYC5cbiAgICpcbiAgICogU2luY2UgYDMuMC4wYCBjYW4gYWxzbyBiZSBhbiBhcmJpdHJhcnkgc3RyaW5nIChleC4gZm9yIGN1c3RvbSB0aGVtZXMpLlxuICAgKi9cbiAgQElucHV0KCkgdHlwZTogJ3RhYnMnIHwgJ3BpbGxzJyB8IHN0cmluZztcblxuICAvKipcbiAgICogQSB0YWIgY2hhbmdlIGV2ZW50IGVtaXR0ZWQgcmlnaHQgYmVmb3JlIHRoZSB0YWIgY2hhbmdlIGhhcHBlbnMuXG4gICAqXG4gICAqIFNlZSBbYE5nYlRhYkNoYW5nZUV2ZW50YF0oIy9jb21wb25lbnRzL3RhYnNldC9hcGkjTmdiVGFiQ2hhbmdlRXZlbnQpIGZvciBwYXlsb2FkIGRldGFpbHMuXG4gICAqL1xuICBAT3V0cHV0KCkgdGFiQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxOZ2JUYWJDaGFuZ2VFdmVudD4oKTtcblxuICBjb25zdHJ1Y3Rvcihjb25maWc6IE5nYlRhYnNldENvbmZpZykge1xuICAgIHRoaXMudHlwZSA9IGNvbmZpZy50eXBlO1xuICAgIHRoaXMuanVzdGlmeSA9IGNvbmZpZy5qdXN0aWZ5O1xuICAgIHRoaXMub3JpZW50YXRpb24gPSBjb25maWcub3JpZW50YXRpb247XG4gIH1cblxuICAvKipcbiAgICogU2VsZWN0cyB0aGUgdGFiIHdpdGggdGhlIGdpdmVuIGlkIGFuZCBzaG93cyBpdHMgYXNzb2NpYXRlZCBjb250ZW50IHBhbmVsLlxuICAgKlxuICAgKiBBbnkgb3RoZXIgdGFiIHRoYXQgd2FzIHByZXZpb3VzbHkgc2VsZWN0ZWQgYmVjb21lcyB1bnNlbGVjdGVkIGFuZCBpdHMgYXNzb2NpYXRlZCBwYW5lIGlzIHJlbW92ZWQgZnJvbSBET00gb3JcbiAgICogaGlkZGVuIGRlcGVuZGluZyBvbiB0aGUgYGRlc3Ryb3lPbkhpZGVgIHZhbHVlLlxuICAgKi9cbiAgc2VsZWN0KHRhYklkOiBzdHJpbmcpIHtcbiAgICBsZXQgc2VsZWN0ZWRUYWIgPSB0aGlzLl9nZXRUYWJCeUlkKHRhYklkKTtcbiAgICBpZiAoc2VsZWN0ZWRUYWIgJiYgIXNlbGVjdGVkVGFiLmRpc2FibGVkICYmIHRoaXMuYWN0aXZlSWQgIT09IHNlbGVjdGVkVGFiLmlkKSB7XG4gICAgICBsZXQgZGVmYXVsdFByZXZlbnRlZCA9IGZhbHNlO1xuXG4gICAgICB0aGlzLnRhYkNoYW5nZS5lbWl0KFxuICAgICAgICAgIHthY3RpdmVJZDogdGhpcy5hY3RpdmVJZCwgbmV4dElkOiBzZWxlY3RlZFRhYi5pZCwgcHJldmVudERlZmF1bHQ6ICgpID0+IHsgZGVmYXVsdFByZXZlbnRlZCA9IHRydWU7IH19KTtcblxuICAgICAgaWYgKCFkZWZhdWx0UHJldmVudGVkKSB7XG4gICAgICAgIHRoaXMuYWN0aXZlSWQgPSBzZWxlY3RlZFRhYi5pZDtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBuZ0FmdGVyQ29udGVudENoZWNrZWQoKSB7XG4gICAgLy8gYXV0by1jb3JyZWN0IGFjdGl2ZUlkIHRoYXQgbWlnaHQgaGF2ZSBiZWVuIHNldCBpbmNvcnJlY3RseSBhcyBpbnB1dFxuICAgIGxldCBhY3RpdmVUYWIgPSB0aGlzLl9nZXRUYWJCeUlkKHRoaXMuYWN0aXZlSWQpO1xuICAgIHRoaXMuYWN0aXZlSWQgPSBhY3RpdmVUYWIgPyBhY3RpdmVUYWIuaWQgOiAodGhpcy50YWJzLmxlbmd0aCA/IHRoaXMudGFicy5maXJzdC5pZCA6IG51bGwpO1xuICB9XG5cbiAgcHJpdmF0ZSBfZ2V0VGFiQnlJZChpZDogc3RyaW5nKTogTmdiVGFiIHtcbiAgICBsZXQgdGFic1dpdGhJZDogTmdiVGFiW10gPSB0aGlzLnRhYnMuZmlsdGVyKHRhYiA9PiB0YWIuaWQgPT09IGlkKTtcbiAgICByZXR1cm4gdGFic1dpdGhJZC5sZW5ndGggPyB0YWJzV2l0aElkWzBdIDogbnVsbDtcbiAgfVxufVxuIl19