bs-modal.service.js 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413
  1. /**
  2. * @fileoverview added by tsickle
  3. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  4. */
  5. import { Injectable, EventEmitter, RendererFactory2 } from '@angular/core';
  6. import { ComponentLoaderFactory } from 'ngx-bootstrap/component-loader';
  7. import { ModalBackdropComponent } from './modal-backdrop.component';
  8. import { ModalContainerComponent } from './modal-container.component';
  9. import { CLASS_NAME, modalConfigDefaults, ModalOptions, TRANSITION_DURATIONS } from './modal-options.class';
  10. import { BsModalRef } from './bs-modal-ref.service';
  11. var BsModalService = /** @class */ (function () {
  12. function BsModalService(rendererFactory, clf) {
  13. this.clf = clf;
  14. // constructor props
  15. this.config = modalConfigDefaults;
  16. // tslint:disable-next-line:no-any
  17. this.onShow = new EventEmitter();
  18. // tslint:disable-next-line:no-any
  19. this.onShown = new EventEmitter();
  20. // tslint:disable-next-line:no-any
  21. this.onHide = new EventEmitter();
  22. // tslint:disable-next-line:no-any
  23. this.onHidden = new EventEmitter();
  24. this.isBodyOverflowing = false;
  25. this.originalBodyPadding = 0;
  26. this.scrollbarWidth = 0;
  27. this.modalsCount = 0;
  28. this.lastDismissReason = '';
  29. this.loaders = [];
  30. this._backdropLoader = this.clf.createLoader(null, null, null);
  31. this._renderer = rendererFactory.createRenderer(null, null);
  32. }
  33. /** Shows a modal */
  34. // tslint:disable-next-line:no-any
  35. /**
  36. * Shows a modal
  37. * @param {?} content
  38. * @param {?=} config
  39. * @return {?}
  40. */
  41. // tslint:disable-next-line:no-any
  42. BsModalService.prototype.show = /**
  43. * Shows a modal
  44. * @param {?} content
  45. * @param {?=} config
  46. * @return {?}
  47. */
  48. // tslint:disable-next-line:no-any
  49. function (content, config) {
  50. this.modalsCount++;
  51. this._createLoaders();
  52. this.config = Object.assign({}, modalConfigDefaults, config);
  53. this._showBackdrop();
  54. this.lastDismissReason = null;
  55. return this._showModal(content);
  56. };
  57. /**
  58. * @param {?} level
  59. * @return {?}
  60. */
  61. BsModalService.prototype.hide = /**
  62. * @param {?} level
  63. * @return {?}
  64. */
  65. function (level) {
  66. var _this = this;
  67. if (this.modalsCount === 1) {
  68. this._hideBackdrop();
  69. this.resetScrollbar();
  70. }
  71. this.modalsCount = this.modalsCount >= 1 ? this.modalsCount - 1 : 0;
  72. setTimeout((/**
  73. * @return {?}
  74. */
  75. function () {
  76. _this._hideModal(level);
  77. _this.removeLoaders(level);
  78. }), this.config.animated ? TRANSITION_DURATIONS.BACKDROP : 0);
  79. };
  80. /**
  81. * @return {?}
  82. */
  83. BsModalService.prototype._showBackdrop = /**
  84. * @return {?}
  85. */
  86. function () {
  87. /** @type {?} */
  88. var isBackdropEnabled = this.config.backdrop || this.config.backdrop === 'static';
  89. /** @type {?} */
  90. var isBackdropInDOM = !this.backdropRef || !this.backdropRef.instance.isShown;
  91. if (this.modalsCount === 1) {
  92. this.removeBackdrop();
  93. if (isBackdropEnabled && isBackdropInDOM) {
  94. this._backdropLoader
  95. .attach(ModalBackdropComponent)
  96. .to('body')
  97. .show({ isAnimated: this.config.animated });
  98. this.backdropRef = this._backdropLoader._componentRef;
  99. }
  100. }
  101. };
  102. /**
  103. * @return {?}
  104. */
  105. BsModalService.prototype._hideBackdrop = /**
  106. * @return {?}
  107. */
  108. function () {
  109. var _this = this;
  110. if (!this.backdropRef) {
  111. return;
  112. }
  113. this.backdropRef.instance.isShown = false;
  114. /** @type {?} */
  115. var duration = this.config.animated ? TRANSITION_DURATIONS.BACKDROP : 0;
  116. setTimeout((/**
  117. * @return {?}
  118. */
  119. function () { return _this.removeBackdrop(); }), duration);
  120. };
  121. // tslint:disable-next-line:no-any
  122. // tslint:disable-next-line:no-any
  123. /**
  124. * @param {?} content
  125. * @return {?}
  126. */
  127. BsModalService.prototype._showModal =
  128. // tslint:disable-next-line:no-any
  129. /**
  130. * @param {?} content
  131. * @return {?}
  132. */
  133. function (content) {
  134. /** @type {?} */
  135. var modalLoader = this.loaders[this.loaders.length - 1];
  136. /** @type {?} */
  137. var bsModalRef = new BsModalRef();
  138. /** @type {?} */
  139. var modalContainerRef = modalLoader
  140. .provide({ provide: ModalOptions, useValue: this.config })
  141. .provide({ provide: BsModalRef, useValue: bsModalRef })
  142. .attach(ModalContainerComponent)
  143. .to('body')
  144. .show({ content: content, isAnimated: this.config.animated, initialState: this.config.initialState, bsModalService: this });
  145. modalContainerRef.instance.level = this.getModalsCount();
  146. bsModalRef.hide = (/**
  147. * @return {?}
  148. */
  149. function () {
  150. modalContainerRef.instance.hide();
  151. });
  152. bsModalRef.content = modalLoader.getInnerComponent() || null;
  153. bsModalRef.setClass = (/**
  154. * @param {?} newClass
  155. * @return {?}
  156. */
  157. function (newClass) {
  158. modalContainerRef.instance.config.class = newClass;
  159. });
  160. return bsModalRef;
  161. };
  162. /**
  163. * @param {?} level
  164. * @return {?}
  165. */
  166. BsModalService.prototype._hideModal = /**
  167. * @param {?} level
  168. * @return {?}
  169. */
  170. function (level) {
  171. /** @type {?} */
  172. var modalLoader = this.loaders[level - 1];
  173. if (modalLoader) {
  174. modalLoader.hide();
  175. }
  176. };
  177. /**
  178. * @return {?}
  179. */
  180. BsModalService.prototype.getModalsCount = /**
  181. * @return {?}
  182. */
  183. function () {
  184. return this.modalsCount;
  185. };
  186. /**
  187. * @param {?} reason
  188. * @return {?}
  189. */
  190. BsModalService.prototype.setDismissReason = /**
  191. * @param {?} reason
  192. * @return {?}
  193. */
  194. function (reason) {
  195. this.lastDismissReason = reason;
  196. };
  197. /**
  198. * @return {?}
  199. */
  200. BsModalService.prototype.removeBackdrop = /**
  201. * @return {?}
  202. */
  203. function () {
  204. this._backdropLoader.hide();
  205. this.backdropRef = null;
  206. };
  207. /** AFTER PR MERGE MODAL.COMPONENT WILL BE USING THIS CODE */
  208. /** Scroll bar tricks */
  209. /** @internal */
  210. /** AFTER PR MERGE MODAL.COMPONENT WILL BE USING THIS CODE */
  211. /** Scroll bar tricks */
  212. /**
  213. * \@internal
  214. * @return {?}
  215. */
  216. BsModalService.prototype.checkScrollbar = /** AFTER PR MERGE MODAL.COMPONENT WILL BE USING THIS CODE */
  217. /** Scroll bar tricks */
  218. /**
  219. * \@internal
  220. * @return {?}
  221. */
  222. function () {
  223. this.isBodyOverflowing = document.body.clientWidth < window.innerWidth;
  224. this.scrollbarWidth = this.getScrollbarWidth();
  225. };
  226. /**
  227. * @return {?}
  228. */
  229. BsModalService.prototype.setScrollbar = /**
  230. * @return {?}
  231. */
  232. function () {
  233. if (!document) {
  234. return;
  235. }
  236. this.originalBodyPadding = parseInt(window
  237. .getComputedStyle(document.body)
  238. .getPropertyValue('padding-right') || '0', 10);
  239. if (this.isBodyOverflowing) {
  240. document.body.style.paddingRight = this.originalBodyPadding +
  241. this.scrollbarWidth + "px";
  242. }
  243. };
  244. /**
  245. * @private
  246. * @return {?}
  247. */
  248. BsModalService.prototype.resetScrollbar = /**
  249. * @private
  250. * @return {?}
  251. */
  252. function () {
  253. document.body.style.paddingRight = this.originalBodyPadding + "px";
  254. };
  255. // thx d.walsh
  256. // thx d.walsh
  257. /**
  258. * @private
  259. * @return {?}
  260. */
  261. BsModalService.prototype.getScrollbarWidth =
  262. // thx d.walsh
  263. /**
  264. * @private
  265. * @return {?}
  266. */
  267. function () {
  268. /** @type {?} */
  269. var scrollDiv = this._renderer.createElement('div');
  270. this._renderer.addClass(scrollDiv, CLASS_NAME.SCROLLBAR_MEASURER);
  271. this._renderer.appendChild(document.body, scrollDiv);
  272. /** @type {?} */
  273. var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth;
  274. this._renderer.removeChild(document.body, scrollDiv);
  275. return scrollbarWidth;
  276. };
  277. /**
  278. * @private
  279. * @return {?}
  280. */
  281. BsModalService.prototype._createLoaders = /**
  282. * @private
  283. * @return {?}
  284. */
  285. function () {
  286. /** @type {?} */
  287. var loader = this.clf.createLoader(null, null, null);
  288. this.copyEvent(loader.onBeforeShow, this.onShow);
  289. this.copyEvent(loader.onShown, this.onShown);
  290. this.copyEvent(loader.onBeforeHide, this.onHide);
  291. this.copyEvent(loader.onHidden, this.onHidden);
  292. this.loaders.push(loader);
  293. };
  294. /**
  295. * @private
  296. * @param {?} level
  297. * @return {?}
  298. */
  299. BsModalService.prototype.removeLoaders = /**
  300. * @private
  301. * @param {?} level
  302. * @return {?}
  303. */
  304. function (level) {
  305. this.loaders.splice(level - 1, 1);
  306. this.loaders.forEach((/**
  307. * @param {?} loader
  308. * @param {?} i
  309. * @return {?}
  310. */
  311. function (loader, i) {
  312. loader.instance.level = i + 1;
  313. }));
  314. };
  315. // tslint:disable-next-line:no-any
  316. // tslint:disable-next-line:no-any
  317. /**
  318. * @private
  319. * @param {?} from
  320. * @param {?} to
  321. * @return {?}
  322. */
  323. BsModalService.prototype.copyEvent =
  324. // tslint:disable-next-line:no-any
  325. /**
  326. * @private
  327. * @param {?} from
  328. * @param {?} to
  329. * @return {?}
  330. */
  331. function (from, to) {
  332. var _this = this;
  333. from.subscribe((/**
  334. * @return {?}
  335. */
  336. function () {
  337. to.emit(_this.lastDismissReason);
  338. }));
  339. };
  340. BsModalService.decorators = [
  341. { type: Injectable }
  342. ];
  343. /** @nocollapse */
  344. BsModalService.ctorParameters = function () { return [
  345. { type: RendererFactory2 },
  346. { type: ComponentLoaderFactory }
  347. ]; };
  348. return BsModalService;
  349. }());
  350. export { BsModalService };
  351. if (false) {
  352. /** @type {?} */
  353. BsModalService.prototype.config;
  354. /** @type {?} */
  355. BsModalService.prototype.onShow;
  356. /** @type {?} */
  357. BsModalService.prototype.onShown;
  358. /** @type {?} */
  359. BsModalService.prototype.onHide;
  360. /** @type {?} */
  361. BsModalService.prototype.onHidden;
  362. /**
  363. * @type {?}
  364. * @protected
  365. */
  366. BsModalService.prototype.isBodyOverflowing;
  367. /**
  368. * @type {?}
  369. * @protected
  370. */
  371. BsModalService.prototype.originalBodyPadding;
  372. /**
  373. * @type {?}
  374. * @protected
  375. */
  376. BsModalService.prototype.scrollbarWidth;
  377. /**
  378. * @type {?}
  379. * @protected
  380. */
  381. BsModalService.prototype.backdropRef;
  382. /**
  383. * @type {?}
  384. * @private
  385. */
  386. BsModalService.prototype._backdropLoader;
  387. /**
  388. * @type {?}
  389. * @private
  390. */
  391. BsModalService.prototype.modalsCount;
  392. /**
  393. * @type {?}
  394. * @private
  395. */
  396. BsModalService.prototype.lastDismissReason;
  397. /**
  398. * @type {?}
  399. * @private
  400. */
  401. BsModalService.prototype.loaders;
  402. /**
  403. * @type {?}
  404. * @private
  405. */
  406. BsModalService.prototype._renderer;
  407. /**
  408. * @type {?}
  409. * @private
  410. */
  411. BsModalService.prototype.clf;
  412. }
  413. //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnMtbW9kYWwuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiJuZzovL25neC1ib290c3RyYXAvbW9kYWwvIiwic291cmNlcyI6WyJicy1tb2RhbC5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7QUFBQSxPQUFPLEVBRUwsVUFBVSxFQUVWLFlBQVksRUFFWixnQkFBZ0IsRUFDakIsTUFBTSxlQUFlLENBQUM7QUFFdkIsT0FBTyxFQUFtQixzQkFBc0IsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBQ3pGLE9BQU8sRUFBRSxzQkFBc0IsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQ3BFLE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBQ3RFLE9BQU8sRUFDTCxVQUFVLEVBQ1YsbUJBQW1CLEVBQ25CLFlBQVksRUFDWixvQkFBb0IsRUFDckIsTUFBTSx1QkFBdUIsQ0FBQztBQUMvQixPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFFcEQ7SUE0QkUsd0JBQVksZUFBaUMsRUFBVSxHQUEyQjtRQUEzQixRQUFHLEdBQUgsR0FBRyxDQUF3Qjs7UUF6QmxGLFdBQU0sR0FBaUIsbUJBQW1CLENBQUM7O1FBRzNDLFdBQU0sR0FBc0IsSUFBSSxZQUFZLEVBQUUsQ0FBQzs7UUFFL0MsWUFBTyxHQUFzQixJQUFJLFlBQVksRUFBRSxDQUFDOztRQUVoRCxXQUFNLEdBQXNCLElBQUksWUFBWSxFQUFFLENBQUM7O1FBRS9DLGFBQVEsR0FBc0IsSUFBSSxZQUFZLEVBQUUsQ0FBQztRQUV2QyxzQkFBaUIsR0FBRyxLQUFLLENBQUM7UUFDMUIsd0JBQW1CLEdBQUcsQ0FBQyxDQUFDO1FBRXhCLG1CQUFjLEdBQUcsQ0FBQyxDQUFDO1FBSXJCLGdCQUFXLEdBQUcsQ0FBQyxDQUFDO1FBQ2hCLHNCQUFpQixHQUFHLEVBQUUsQ0FBQztRQUV2QixZQUFPLEdBQStDLEVBQUUsQ0FBQztRQUsvRCxJQUFJLENBQUMsZUFBZSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsWUFBWSxDQUMxQyxJQUFJLEVBQ0osSUFBSSxFQUNKLElBQUksQ0FDTCxDQUFDO1FBQ0YsSUFBSSxDQUFDLFNBQVMsR0FBRyxlQUFlLENBQUMsY0FBYyxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQztJQUM5RCxDQUFDO0lBRUQsb0JBQW9CO0lBQ3BCLGtDQUFrQzs7Ozs7Ozs7SUFDbEMsNkJBQUk7Ozs7Ozs7SUFBSixVQUFLLE9BQXdDLEVBQUUsTUFBcUI7UUFDbEUsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQ25CLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztRQUN0QixJQUFJLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsRUFBRSxFQUFFLG1CQUFtQixFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBQzdELElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztRQUNyQixJQUFJLENBQUMsaUJBQWlCLEdBQUcsSUFBSSxDQUFDO1FBRTlCLE9BQU8sSUFBSSxDQUFDLFVBQVUsQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUNsQyxDQUFDOzs7OztJQUVELDZCQUFJOzs7O0lBQUosVUFBSyxLQUFhO1FBQWxCLGlCQVVDO1FBVEMsSUFBSSxJQUFJLENBQUMsV0FBVyxLQUFLLENBQUMsRUFBRTtZQUMxQixJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7WUFDckIsSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDO1NBQ3ZCO1FBQ0QsSUFBSSxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUMsV0FBVyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLFdBQVcsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNwRSxVQUFVOzs7UUFBQztZQUNULEtBQUksQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDdkIsS0FBSSxDQUFDLGFBQWEsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUM1QixDQUFDLEdBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLG9CQUFvQixDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDL0QsQ0FBQzs7OztJQUVELHNDQUFhOzs7SUFBYjs7WUFDUSxpQkFBaUIsR0FDckIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLEtBQUssUUFBUTs7WUFDckQsZUFBZSxHQUNuQixDQUFDLElBQUksQ0FBQyxXQUFXLElBQUksQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLFFBQVEsQ0FBQyxPQUFPO1FBRXpELElBQUksSUFBSSxDQUFDLFdBQVcsS0FBSyxDQUFDLEVBQUU7WUFDMUIsSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDO1lBRXRCLElBQUksaUJBQWlCLElBQUksZUFBZSxFQUFFO2dCQUN4QyxJQUFJLENBQUMsZUFBZTtxQkFDakIsTUFBTSxDQUFDLHNCQUFzQixDQUFDO3FCQUM5QixFQUFFLENBQUMsTUFBTSxDQUFDO3FCQUNWLElBQUksQ0FBQyxFQUFFLFVBQVUsRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUM7Z0JBQzlDLElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQyxhQUFhLENBQUM7YUFDdkQ7U0FDRjtJQUNILENBQUM7Ozs7SUFFRCxzQ0FBYTs7O0lBQWI7UUFBQSxpQkFPQztRQU5DLElBQUksQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFO1lBQ3JCLE9BQU87U0FDUjtRQUNELElBQUksQ0FBQyxXQUFXLENBQUMsUUFBUSxDQUFDLE9BQU8sR0FBRyxLQUFLLENBQUM7O1lBQ3BDLFFBQVEsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsb0JBQW9CLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3pFLFVBQVU7OztRQUFDLGNBQU0sT0FBQSxLQUFJLENBQUMsY0FBYyxFQUFFLEVBQXJCLENBQXFCLEdBQUUsUUFBUSxDQUFDLENBQUM7SUFDcEQsQ0FBQztJQUNELGtDQUFrQzs7Ozs7O0lBQ2xDLG1DQUFVOzs7Ozs7SUFBVixVQUFXLE9BQVk7O1lBQ2YsV0FBVyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDOztZQUNuRCxVQUFVLEdBQUcsSUFBSSxVQUFVLEVBQUU7O1lBQzdCLGlCQUFpQixHQUFHLFdBQVc7YUFDbEMsT0FBTyxDQUFDLEVBQUUsT0FBTyxFQUFFLFlBQVksRUFBRSxRQUFRLEVBQUUsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO2FBQ3pELE9BQU8sQ0FBQyxFQUFFLE9BQU8sRUFBRSxVQUFVLEVBQUUsUUFBUSxFQUFFLFVBQVUsRUFBRSxDQUFDO2FBQ3RELE1BQU0sQ0FBQyx1QkFBdUIsQ0FBQzthQUMvQixFQUFFLENBQUMsTUFBTSxDQUFDO2FBQ1YsSUFBSSxDQUFDLEVBQUMsT0FBTyxTQUFBLEVBQUUsVUFBVSxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxFQUFFLFlBQVksRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLFlBQVksRUFBRSxjQUFjLEVBQUUsSUFBSSxFQUFDLENBQUM7UUFDbEgsaUJBQWlCLENBQUMsUUFBUSxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsY0FBYyxFQUFFLENBQUM7UUFDekQsVUFBVSxDQUFDLElBQUk7OztRQUFHO1lBQ2hCLGlCQUFpQixDQUFDLFFBQVEsQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUNwQyxDQUFDLENBQUEsQ0FBQztRQUNGLFVBQVUsQ0FBQyxPQUFPLEdBQUcsV0FBVyxDQUFDLGlCQUFpQixFQUFFLElBQUksSUFBSSxDQUFDO1FBQzdELFVBQVUsQ0FBQyxRQUFROzs7O1FBQUcsVUFBQyxRQUFnQjtZQUNyQyxpQkFBaUIsQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLEtBQUssR0FBRyxRQUFRLENBQUM7UUFDckQsQ0FBQyxDQUFBLENBQUM7UUFFRixPQUFPLFVBQVUsQ0FBQztJQUNwQixDQUFDOzs7OztJQUVELG1DQUFVOzs7O0lBQVYsVUFBVyxLQUFhOztZQUNoQixXQUFXLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLEdBQUcsQ0FBQyxDQUFDO1FBQzNDLElBQUksV0FBVyxFQUFFO1lBQ2YsV0FBVyxDQUFDLElBQUksRUFBRSxDQUFDO1NBQ3BCO0lBQ0gsQ0FBQzs7OztJQUVELHVDQUFjOzs7SUFBZDtRQUNFLE9BQU8sSUFBSSxDQUFDLFdBQVcsQ0FBQztJQUMxQixDQUFDOzs7OztJQUVELHlDQUFnQjs7OztJQUFoQixVQUFpQixNQUFjO1FBQzdCLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxNQUFNLENBQUM7SUFDbEMsQ0FBQzs7OztJQUVELHVDQUFjOzs7SUFBZDtRQUNFLElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDNUIsSUFBSSxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUM7SUFDMUIsQ0FBQztJQUVELDZEQUE2RDtJQUM3RCx3QkFBd0I7SUFDeEIsZ0JBQWdCOzs7Ozs7O0lBQ2hCLHVDQUFjOzs7Ozs7SUFBZDtRQUNFLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxRQUFRLENBQUMsSUFBSSxDQUFDLFdBQVcsR0FBRyxNQUFNLENBQUMsVUFBVSxDQUFDO1FBQ3ZFLElBQUksQ0FBQyxjQUFjLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUM7SUFDakQsQ0FBQzs7OztJQUVELHFDQUFZOzs7SUFBWjtRQUNFLElBQUksQ0FBQyxRQUFRLEVBQUU7WUFDYixPQUFPO1NBQ1I7UUFFRCxJQUFJLENBQUMsbUJBQW1CLEdBQUcsUUFBUSxDQUNqQyxNQUFNO2FBQ0gsZ0JBQWdCLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQzthQUMvQixnQkFBZ0IsQ0FBQyxlQUFlLENBQUMsSUFBSSxHQUFHLEVBQzNDLEVBQUUsQ0FDSCxDQUFDO1FBRUYsSUFBSSxJQUFJLENBQUMsaUJBQWlCLEVBQUU7WUFDMUIsUUFBUSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsWUFBWSxHQUFNLElBQUksQ0FBQyxtQkFBbUI7Z0JBQzVELElBQUksQ0FBQyxjQUFjLE9BQUksQ0FBQztTQUMzQjtJQUNILENBQUM7Ozs7O0lBRU8sdUNBQWM7Ozs7SUFBdEI7UUFDRSxRQUFRLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxZQUFZLEdBQU0sSUFBSSxDQUFDLG1CQUFtQixPQUFJLENBQUM7SUFDckUsQ0FBQztJQUVELGNBQWM7Ozs7OztJQUNOLDBDQUFpQjs7Ozs7O0lBQXpCOztZQUNRLFNBQVMsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLGFBQWEsQ0FBQyxLQUFLLENBQUM7UUFDckQsSUFBSSxDQUFDLFNBQVMsQ0FBQyxRQUFRLENBQUMsU0FBUyxFQUFFLFVBQVUsQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO1FBQ2xFLElBQUksQ0FBQyxTQUFTLENBQUMsV0FBVyxDQUFDLFFBQVEsQ0FBQyxJQUFJLEVBQUUsU0FBUyxDQUFDLENBQUM7O1lBQy9DLGNBQWMsR0FBRyxTQUFTLENBQUMsV0FBVyxHQUFHLFNBQVMsQ0FBQyxXQUFXO1FBQ3BFLElBQUksQ0FBQyxTQUFTLENBQUMsV0FBVyxDQUFDLFFBQVEsQ0FBQyxJQUFJLEVBQUUsU0FBUyxDQUFDLENBQUM7UUFFckQsT0FBTyxjQUFjLENBQUM7SUFDeEIsQ0FBQzs7Ozs7SUFFTyx1Q0FBYzs7OztJQUF0Qjs7WUFDUSxNQUFNLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxZQUFZLENBQ2xDLElBQUksRUFDSixJQUFJLEVBQ0osSUFBSSxDQUNMO1FBQ0QsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsWUFBWSxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUNqRCxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQzdDLElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLFlBQVksRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDakQsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsUUFBUSxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUMvQyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUM1QixDQUFDOzs7Ozs7SUFFTyxzQ0FBYTs7Ozs7SUFBckIsVUFBc0IsS0FBYTtRQUNqQyxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxLQUFLLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQ2xDLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTzs7Ozs7UUFDbEIsVUFBQyxNQUFnRCxFQUFFLENBQVM7WUFDMUQsTUFBTSxDQUFDLFFBQVEsQ0FBQyxLQUFLLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUNoQyxDQUFDLEVBQ0YsQ0FBQztJQUNKLENBQUM7SUFFRCxrQ0FBa0M7Ozs7Ozs7O0lBQzFCLGtDQUFTOzs7Ozs7OztJQUFqQixVQUFrQixJQUF1QixFQUFFLEVBQXFCO1FBQWhFLGlCQUlDO1FBSEMsSUFBSSxDQUFDLFNBQVM7OztRQUFDO1lBQ2IsRUFBRSxDQUFDLElBQUksQ0FBQyxLQUFJLENBQUMsaUJBQWlCLENBQUMsQ0FBQztRQUNsQyxDQUFDLEVBQUMsQ0FBQztJQUNMLENBQUM7O2dCQXRNRixVQUFVOzs7O2dCQWRULGdCQUFnQjtnQkFHUSxzQkFBc0I7O0lBa05oRCxxQkFBQztDQUFBLEFBdk1ELElBdU1DO1NBdE1ZLGNBQWM7OztJQUV6QixnQ0FBMkM7O0lBRzNDLGdDQUErQzs7SUFFL0MsaUNBQWdEOztJQUVoRCxnQ0FBK0M7O0lBRS9DLGtDQUFpRDs7Ozs7SUFFakQsMkNBQW9DOzs7OztJQUNwQyw2Q0FBa0M7Ozs7O0lBRWxDLHdDQUE2Qjs7Ozs7SUFFN0IscUNBQTREOzs7OztJQUM1RCx5Q0FBaUU7Ozs7O0lBQ2pFLHFDQUF3Qjs7Ozs7SUFDeEIsMkNBQStCOzs7OztJQUUvQixpQ0FBaUU7Ozs7O0lBRWpFLG1DQUE2Qjs7Ozs7SUFFa0IsNkJBQW1DIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ29tcG9uZW50UmVmLFxuICBJbmplY3RhYmxlLFxuICBUZW1wbGF0ZVJlZixcbiAgRXZlbnRFbWl0dGVyLFxuICBSZW5kZXJlcjIsXG4gIFJlbmRlcmVyRmFjdG9yeTJcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbmltcG9ydCB7IENvbXBvbmVudExvYWRlciwgQ29tcG9uZW50TG9hZGVyRmFjdG9yeSB9IGZyb20gJ25neC1ib290c3RyYXAvY29tcG9uZW50LWxvYWRlcic7XG5pbXBvcnQgeyBNb2RhbEJhY2tkcm9wQ29tcG9uZW50IH0gZnJvbSAnLi9tb2RhbC1iYWNrZHJvcC5jb21wb25lbnQnO1xuaW1wb3J0IHsgTW9kYWxDb250YWluZXJDb21wb25lbnQgfSBmcm9tICcuL21vZGFsLWNvbnRhaW5lci5jb21wb25lbnQnO1xuaW1wb3J0IHtcbiAgQ0xBU1NfTkFNRSxcbiAgbW9kYWxDb25maWdEZWZhdWx0cyxcbiAgTW9kYWxPcHRpb25zLFxuICBUUkFOU0lUSU9OX0RVUkFUSU9OU1xufSBmcm9tICcuL21vZGFsLW9wdGlvbnMuY2xhc3MnO1xuaW1wb3J0IHsgQnNNb2RhbFJlZiB9IGZyb20gJy4vYnMtbW9kYWwtcmVmLnNlcnZpY2UnO1xuXG5ASW5qZWN0YWJsZSgpXG5leHBvcnQgY2xhc3MgQnNNb2RhbFNlcnZpY2Uge1xuICAvLyBjb25zdHJ1Y3RvciBwcm9wc1xuICBjb25maWc6IE1vZGFsT3B0aW9ucyA9IG1vZGFsQ29uZmlnRGVmYXVsdHM7XG5cbiAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWFueVxuICBvblNob3c6IEV2ZW50RW1pdHRlcjxhbnk+ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tYW55XG4gIG9uU2hvd246IEV2ZW50RW1pdHRlcjxhbnk+ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tYW55XG4gIG9uSGlkZTogRXZlbnRFbWl0dGVyPGFueT4gPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG4gIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1hbnlcbiAgb25IaWRkZW46IEV2ZW50RW1pdHRlcjxhbnk+ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuXG4gIHByb3RlY3RlZCBpc0JvZHlPdmVyZmxvd2luZyA9IGZhbHNlO1xuICBwcm90ZWN0ZWQgb3JpZ2luYWxCb2R5UGFkZGluZyA9IDA7XG5cbiAgcHJvdGVjdGVkIHNjcm9sbGJhcldpZHRoID0gMDtcblxuICBwcm90ZWN0ZWQgYmFja2Ryb3BSZWY6IENvbXBvbmVudFJlZjxNb2RhbEJhY2tkcm9wQ29tcG9uZW50PjtcbiAgcHJpdmF0ZSBfYmFja2Ryb3BMb2FkZXI6IENvbXBvbmVudExvYWRlcjxNb2RhbEJhY2tkcm9wQ29tcG9uZW50PjtcbiAgcHJpdmF0ZSBtb2RhbHNDb3VudCA9IDA7XG4gIHByaXZhdGUgbGFzdERpc21pc3NSZWFzb24gPSAnJztcblxuICBwcml2YXRlIGxvYWRlcnM6IENvbXBvbmVudExvYWRlcjxNb2RhbENvbnRhaW5lckNvbXBvbmVudD5bXSA9IFtdO1xuXG4gIHByaXZhdGUgX3JlbmRlcmVyOiBSZW5kZXJlcjI7XG5cbiAgY29uc3RydWN0b3IocmVuZGVyZXJGYWN0b3J5OiBSZW5kZXJlckZhY3RvcnkyLCBwcml2YXRlIGNsZjogQ29tcG9uZW50TG9hZGVyRmFjdG9yeSkge1xuICAgIHRoaXMuX2JhY2tkcm9wTG9hZGVyID0gdGhpcy5jbGYuY3JlYXRlTG9hZGVyPE1vZGFsQmFja2Ryb3BDb21wb25lbnQ+KFxuICAgICAgbnVsbCxcbiAgICAgIG51bGwsXG4gICAgICBudWxsXG4gICAgKTtcbiAgICB0aGlzLl9yZW5kZXJlciA9IHJlbmRlcmVyRmFjdG9yeS5jcmVhdGVSZW5kZXJlcihudWxsLCBudWxsKTtcbiAgfVxuXG4gIC8qKiBTaG93cyBhIG1vZGFsICovXG4gIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1hbnlcbiAgc2hvdyhjb250ZW50OiBzdHJpbmcgfCBUZW1wbGF0ZVJlZjxhbnk+IHwgYW55LCBjb25maWc/OiBNb2RhbE9wdGlvbnMpOiBCc01vZGFsUmVmIHtcbiAgICB0aGlzLm1vZGFsc0NvdW50Kys7XG4gICAgdGhpcy5fY3JlYXRlTG9hZGVycygpO1xuICAgIHRoaXMuY29uZmlnID0gT2JqZWN0LmFzc2lnbih7fSwgbW9kYWxDb25maWdEZWZhdWx0cywgY29uZmlnKTtcbiAgICB0aGlzLl9zaG93QmFja2Ryb3AoKTtcbiAgICB0aGlzLmxhc3REaXNtaXNzUmVhc29uID0gbnVsbDtcblxuICAgIHJldHVybiB0aGlzLl9zaG93TW9kYWwoY29udGVudCk7XG4gIH1cblxuICBoaWRlKGxldmVsOiBudW1iZXIpIHtcbiAgICBpZiAodGhpcy5tb2RhbHNDb3VudCA9PT0gMSkge1xuICAgICAgdGhpcy5faGlkZUJhY2tkcm9wKCk7XG4gICAgICB0aGlzLnJlc2V0U2Nyb2xsYmFyKCk7XG4gICAgfVxuICAgIHRoaXMubW9kYWxzQ291bnQgPSB0aGlzLm1vZGFsc0NvdW50ID49IDEgPyB0aGlzLm1vZGFsc0NvdW50IC0gMSA6IDA7XG4gICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICB0aGlzLl9oaWRlTW9kYWwobGV2ZWwpO1xuICAgICAgdGhpcy5yZW1vdmVMb2FkZXJzKGxldmVsKTtcbiAgICB9LCB0aGlzLmNvbmZpZy5hbmltYXRlZCA/IFRSQU5TSVRJT05fRFVSQVRJT05TLkJBQ0tEUk9QIDogMCk7XG4gIH1cblxuICBfc2hvd0JhY2tkcm9wKCk6IHZvaWQge1xuICAgIGNvbnN0IGlzQmFja2Ryb3BFbmFibGVkID1cbiAgICAgIHRoaXMuY29uZmlnLmJhY2tkcm9wIHx8IHRoaXMuY29uZmlnLmJhY2tkcm9wID09PSAnc3RhdGljJztcbiAgICBjb25zdCBpc0JhY2tkcm9wSW5ET00gPVxuICAgICAgIXRoaXMuYmFja2Ryb3BSZWYgfHwgIXRoaXMuYmFja2Ryb3BSZWYuaW5zdGFuY2UuaXNTaG93bjtcblxuICAgIGlmICh0aGlzLm1vZGFsc0NvdW50ID09PSAxKSB7XG4gICAgICB0aGlzLnJlbW92ZUJhY2tkcm9wKCk7XG5cbiAgICAgIGlmIChpc0JhY2tkcm9wRW5hYmxlZCAmJiBpc0JhY2tkcm9wSW5ET00pIHtcbiAgICAgICAgdGhpcy5fYmFja2Ryb3BMb2FkZXJcbiAgICAgICAgICAuYXR0YWNoKE1vZGFsQmFja2Ryb3BDb21wb25lbnQpXG4gICAgICAgICAgLnRvKCdib2R5JylcbiAgICAgICAgICAuc2hvdyh7IGlzQW5pbWF0ZWQ6IHRoaXMuY29uZmlnLmFuaW1hdGVkIH0pO1xuICAgICAgICB0aGlzLmJhY2tkcm9wUmVmID0gdGhpcy5fYmFja2Ryb3BMb2FkZXIuX2NvbXBvbmVudFJlZjtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBfaGlkZUJhY2tkcm9wKCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5iYWNrZHJvcFJlZikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmJhY2tkcm9wUmVmLmluc3RhbmNlLmlzU2hvd24gPSBmYWxzZTtcbiAgICBjb25zdCBkdXJhdGlvbiA9IHRoaXMuY29uZmlnLmFuaW1hdGVkID8gVFJBTlNJVElPTl9EVVJBVElPTlMuQkFDS0RST1AgOiAwO1xuICAgIHNldFRpbWVvdXQoKCkgPT4gdGhpcy5yZW1vdmVCYWNrZHJvcCgpLCBkdXJhdGlvbik7XG4gIH1cbiAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWFueVxuICBfc2hvd01vZGFsKGNvbnRlbnQ6IGFueSk6IEJzTW9kYWxSZWYge1xuICAgIGNvbnN0IG1vZGFsTG9hZGVyID0gdGhpcy5sb2FkZXJzW3RoaXMubG9hZGVycy5sZW5ndGggLSAxXTtcbiAgICBjb25zdCBic01vZGFsUmVmID0gbmV3IEJzTW9kYWxSZWYoKTtcbiAgICBjb25zdCBtb2RhbENvbnRhaW5lclJlZiA9IG1vZGFsTG9hZGVyXG4gICAgICAucHJvdmlkZSh7IHByb3ZpZGU6IE1vZGFsT3B0aW9ucywgdXNlVmFsdWU6IHRoaXMuY29uZmlnIH0pXG4gICAgICAucHJvdmlkZSh7IHByb3ZpZGU6IEJzTW9kYWxSZWYsIHVzZVZhbHVlOiBic01vZGFsUmVmIH0pXG4gICAgICAuYXR0YWNoKE1vZGFsQ29udGFpbmVyQ29tcG9uZW50KVxuICAgICAgLnRvKCdib2R5JylcbiAgICAgIC5zaG93KHtjb250ZW50LCBpc0FuaW1hdGVkOiB0aGlzLmNvbmZpZy5hbmltYXRlZCwgaW5pdGlhbFN0YXRlOiB0aGlzLmNvbmZpZy5pbml0aWFsU3RhdGUsIGJzTW9kYWxTZXJ2aWNlOiB0aGlzfSk7XG4gICAgbW9kYWxDb250YWluZXJSZWYuaW5zdGFuY2UubGV2ZWwgPSB0aGlzLmdldE1vZGFsc0NvdW50KCk7XG4gICAgYnNNb2RhbFJlZi5oaWRlID0gKCkgPT4ge1xuICAgICAgbW9kYWxDb250YWluZXJSZWYuaW5zdGFuY2UuaGlkZSgpO1xuICAgIH07XG4gICAgYnNNb2RhbFJlZi5jb250ZW50ID0gbW9kYWxMb2FkZXIuZ2V0SW5uZXJDb21wb25lbnQoKSB8fCBudWxsO1xuICAgIGJzTW9kYWxSZWYuc2V0Q2xhc3MgPSAobmV3Q2xhc3M6IHN0cmluZykgPT4ge1xuICAgICAgbW9kYWxDb250YWluZXJSZWYuaW5zdGFuY2UuY29uZmlnLmNsYXNzID0gbmV3Q2xhc3M7XG4gICAgfTtcblxuICAgIHJldHVybiBic01vZGFsUmVmO1xuICB9XG5cbiAgX2hpZGVNb2RhbChsZXZlbDogbnVtYmVyKTogdm9pZCB7XG4gICAgY29uc3QgbW9kYWxMb2FkZXIgPSB0aGlzLmxvYWRlcnNbbGV2ZWwgLSAxXTtcbiAgICBpZiAobW9kYWxMb2FkZXIpIHtcbiAgICAgIG1vZGFsTG9hZGVyLmhpZGUoKTtcbiAgICB9XG4gIH1cblxuICBnZXRNb2RhbHNDb3VudCgpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLm1vZGFsc0NvdW50O1xuICB9XG5cbiAgc2V0RGlzbWlzc1JlYXNvbihyZWFzb246IHN0cmluZykge1xuICAgIHRoaXMubGFzdERpc21pc3NSZWFzb24gPSByZWFzb247XG4gIH1cblxuICByZW1vdmVCYWNrZHJvcCgpOiB2b2lkIHtcbiAgICB0aGlzLl9iYWNrZHJvcExvYWRlci5oaWRlKCk7XG4gICAgdGhpcy5iYWNrZHJvcFJlZiA9IG51bGw7XG4gIH1cblxuICAvKiogQUZURVIgUFIgTUVSR0UgTU9EQUwuQ09NUE9ORU5UIFdJTEwgQkUgVVNJTkcgVEhJUyBDT0RFICovXG4gIC8qKiBTY3JvbGwgYmFyIHRyaWNrcyAqL1xuICAvKiogQGludGVybmFsICovXG4gIGNoZWNrU2Nyb2xsYmFyKCk6IHZvaWQge1xuICAgIHRoaXMuaXNCb2R5T3ZlcmZsb3dpbmcgPSBkb2N1bWVudC5ib2R5LmNsaWVudFdpZHRoIDwgd2luZG93LmlubmVyV2lkdGg7XG4gICAgdGhpcy5zY3JvbGxiYXJXaWR0aCA9IHRoaXMuZ2V0U2Nyb2xsYmFyV2lkdGgoKTtcbiAgfVxuXG4gIHNldFNjcm9sbGJhcigpOiB2b2lkIHtcbiAgICBpZiAoIWRvY3VtZW50KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5vcmlnaW5hbEJvZHlQYWRkaW5nID0gcGFyc2VJbnQoXG4gICAgICB3aW5kb3dcbiAgICAgICAgLmdldENvbXB1dGVkU3R5bGUoZG9jdW1lbnQuYm9keSlcbiAgICAgICAgLmdldFByb3BlcnR5VmFsdWUoJ3BhZGRpbmctcmlnaHQnKSB8fCAnMCcsXG4gICAgICAxMFxuICAgICk7XG5cbiAgICBpZiAodGhpcy5pc0JvZHlPdmVyZmxvd2luZykge1xuICAgICAgZG9jdW1lbnQuYm9keS5zdHlsZS5wYWRkaW5nUmlnaHQgPSBgJHt0aGlzLm9yaWdpbmFsQm9keVBhZGRpbmcgK1xuICAgICAgICB0aGlzLnNjcm9sbGJhcldpZHRofXB4YDtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHJlc2V0U2Nyb2xsYmFyKCk6IHZvaWQge1xuICAgIGRvY3VtZW50LmJvZHkuc3R5bGUucGFkZGluZ1JpZ2h0ID0gYCR7dGhpcy5vcmlnaW5hbEJvZHlQYWRkaW5nfXB4YDtcbiAgfVxuXG4gIC8vIHRoeCBkLndhbHNoXG4gIHByaXZhdGUgZ2V0U2Nyb2xsYmFyV2lkdGgoKTogbnVtYmVyIHtcbiAgICBjb25zdCBzY3JvbGxEaXYgPSB0aGlzLl9yZW5kZXJlci5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICB0aGlzLl9yZW5kZXJlci5hZGRDbGFzcyhzY3JvbGxEaXYsIENMQVNTX05BTUUuU0NST0xMQkFSX01FQVNVUkVSKTtcbiAgICB0aGlzLl9yZW5kZXJlci5hcHBlbmRDaGlsZChkb2N1bWVudC5ib2R5LCBzY3JvbGxEaXYpO1xuICAgIGNvbnN0IHNjcm9sbGJhcldpZHRoID0gc2Nyb2xsRGl2Lm9mZnNldFdpZHRoIC0gc2Nyb2xsRGl2LmNsaWVudFdpZHRoO1xuICAgIHRoaXMuX3JlbmRlcmVyLnJlbW92ZUNoaWxkKGRvY3VtZW50LmJvZHksIHNjcm9sbERpdik7XG5cbiAgICByZXR1cm4gc2Nyb2xsYmFyV2lkdGg7XG4gIH1cblxuICBwcml2YXRlIF9jcmVhdGVMb2FkZXJzKCk6IHZvaWQge1xuICAgIGNvbnN0IGxvYWRlciA9IHRoaXMuY2xmLmNyZWF0ZUxvYWRlcjxNb2RhbENvbnRhaW5lckNvbXBvbmVudD4oXG4gICAgICBudWxsLFxuICAgICAgbnVsbCxcbiAgICAgIG51bGxcbiAgICApO1xuICAgIHRoaXMuY29weUV2ZW50KGxvYWRlci5vbkJlZm9yZVNob3csIHRoaXMub25TaG93KTtcbiAgICB0aGlzLmNvcHlFdmVudChsb2FkZXIub25TaG93biwgdGhpcy5vblNob3duKTtcbiAgICB0aGlzLmNvcHlFdmVudChsb2FkZXIub25CZWZvcmVIaWRlLCB0aGlzLm9uSGlkZSk7XG4gICAgdGhpcy5jb3B5RXZlbnQobG9hZGVyLm9uSGlkZGVuLCB0aGlzLm9uSGlkZGVuKTtcbiAgICB0aGlzLmxvYWRlcnMucHVzaChsb2FkZXIpO1xuICB9XG5cbiAgcHJpdmF0ZSByZW1vdmVMb2FkZXJzKGxldmVsOiBudW1iZXIpOiB2b2lkIHtcbiAgICB0aGlzLmxvYWRlcnMuc3BsaWNlKGxldmVsIC0gMSwgMSk7XG4gICAgdGhpcy5sb2FkZXJzLmZvckVhY2goXG4gICAgICAobG9hZGVyOiBDb21wb25lbnRMb2FkZXI8TW9kYWxDb250YWluZXJDb21wb25lbnQ+LCBpOiBudW1iZXIpID0+IHtcbiAgICAgICAgbG9hZGVyLmluc3RhbmNlLmxldmVsID0gaSArIDE7XG4gICAgICB9XG4gICAgKTtcbiAgfVxuXG4gIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1hbnlcbiAgcHJpdmF0ZSBjb3B5RXZlbnQoZnJvbTogRXZlbnRFbWl0dGVyPGFueT4sIHRvOiBFdmVudEVtaXR0ZXI8YW55Pikge1xuICAgIGZyb20uc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgIHRvLmVtaXQodGhpcy5sYXN0RGlzbWlzc1JlYXNvbik7XG4gICAgfSk7XG4gIH1cbn1cbiJdfQ==