modal-stack.js 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521
  1. /**
  2. * @fileoverview added by tsickle
  3. * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  4. */
  5. import { DOCUMENT } from '@angular/common';
  6. import { ApplicationRef, Inject, Injectable, Injector, NgZone, RendererFactory2, TemplateRef } from '@angular/core';
  7. import { Subject } from 'rxjs';
  8. import { ngbFocusTrap } from '../util/focus-trap';
  9. import { ContentRef } from '../util/popup';
  10. import { ScrollBar } from '../util/scrollbar';
  11. import { isDefined, isString } from '../util/util';
  12. import { NgbModalBackdrop } from './modal-backdrop';
  13. import { NgbActiveModal, NgbModalRef } from './modal-ref';
  14. import { NgbModalWindow } from './modal-window';
  15. import * as i0 from "@angular/core";
  16. import * as i1 from "@angular/common";
  17. import * as i2 from "../util/scrollbar";
  18. var NgbModalStack = /** @class */ (function () {
  19. function NgbModalStack(_applicationRef, _injector, _document, _scrollBar, _rendererFactory, _ngZone) {
  20. var _this = this;
  21. this._applicationRef = _applicationRef;
  22. this._injector = _injector;
  23. this._document = _document;
  24. this._scrollBar = _scrollBar;
  25. this._rendererFactory = _rendererFactory;
  26. this._ngZone = _ngZone;
  27. this._activeWindowCmptHasChanged = new Subject();
  28. this._ariaHiddenValues = new Map();
  29. this._backdropAttributes = ['backdropClass'];
  30. this._modalRefs = [];
  31. this._windowAttributes = ['ariaLabelledBy', 'backdrop', 'centered', 'keyboard', 'scrollable', 'size', 'windowClass'];
  32. this._windowCmpts = [];
  33. // Trap focus on active WindowCmpt
  34. this._activeWindowCmptHasChanged.subscribe((/**
  35. * @return {?}
  36. */
  37. function () {
  38. if (_this._windowCmpts.length) {
  39. /** @type {?} */
  40. var activeWindowCmpt = _this._windowCmpts[_this._windowCmpts.length - 1];
  41. ngbFocusTrap(_this._ngZone, activeWindowCmpt.location.nativeElement, _this._activeWindowCmptHasChanged);
  42. _this._revertAriaHidden();
  43. _this._setAriaHidden(activeWindowCmpt.location.nativeElement);
  44. }
  45. }));
  46. }
  47. /**
  48. * @param {?} moduleCFR
  49. * @param {?} contentInjector
  50. * @param {?} content
  51. * @param {?} options
  52. * @return {?}
  53. */
  54. NgbModalStack.prototype.open = /**
  55. * @param {?} moduleCFR
  56. * @param {?} contentInjector
  57. * @param {?} content
  58. * @param {?} options
  59. * @return {?}
  60. */
  61. function (moduleCFR, contentInjector, content, options) {
  62. var _this = this;
  63. /** @type {?} */
  64. var containerEl = isDefined(options.container) ? this._document.querySelector(options.container) : this._document.body;
  65. /** @type {?} */
  66. var renderer = this._rendererFactory.createRenderer(null, null);
  67. /** @type {?} */
  68. var revertPaddingForScrollBar = this._scrollBar.compensate();
  69. /** @type {?} */
  70. var removeBodyClass = (/**
  71. * @return {?}
  72. */
  73. function () {
  74. if (!_this._modalRefs.length) {
  75. renderer.removeClass(_this._document.body, 'modal-open');
  76. _this._revertAriaHidden();
  77. }
  78. });
  79. if (!containerEl) {
  80. throw new Error("The specified modal container \"" + (options.container || 'body') + "\" was not found in the DOM.");
  81. }
  82. /** @type {?} */
  83. var activeModal = new NgbActiveModal();
  84. /** @type {?} */
  85. var contentRef = this._getContentRef(moduleCFR, options.injector || contentInjector, content, activeModal, options);
  86. /** @type {?} */
  87. var backdropCmptRef = options.backdrop !== false ? this._attachBackdrop(moduleCFR, containerEl) : null;
  88. /** @type {?} */
  89. var windowCmptRef = this._attachWindowComponent(moduleCFR, containerEl, contentRef);
  90. /** @type {?} */
  91. var ngbModalRef = new NgbModalRef(windowCmptRef, contentRef, backdropCmptRef, options.beforeDismiss);
  92. this._registerModalRef(ngbModalRef);
  93. this._registerWindowCmpt(windowCmptRef);
  94. ngbModalRef.result.then(revertPaddingForScrollBar, revertPaddingForScrollBar);
  95. ngbModalRef.result.then(removeBodyClass, removeBodyClass);
  96. activeModal.close = (/**
  97. * @param {?} result
  98. * @return {?}
  99. */
  100. function (result) { ngbModalRef.close(result); });
  101. activeModal.dismiss = (/**
  102. * @param {?} reason
  103. * @return {?}
  104. */
  105. function (reason) { ngbModalRef.dismiss(reason); });
  106. this._applyWindowOptions(windowCmptRef.instance, options);
  107. if (this._modalRefs.length === 1) {
  108. renderer.addClass(this._document.body, 'modal-open');
  109. }
  110. if (backdropCmptRef && backdropCmptRef.instance) {
  111. this._applyBackdropOptions(backdropCmptRef.instance, options);
  112. }
  113. return ngbModalRef;
  114. };
  115. /**
  116. * @param {?=} reason
  117. * @return {?}
  118. */
  119. NgbModalStack.prototype.dismissAll = /**
  120. * @param {?=} reason
  121. * @return {?}
  122. */
  123. function (reason) { this._modalRefs.forEach((/**
  124. * @param {?} ngbModalRef
  125. * @return {?}
  126. */
  127. function (ngbModalRef) { return ngbModalRef.dismiss(reason); })); };
  128. /**
  129. * @return {?}
  130. */
  131. NgbModalStack.prototype.hasOpenModals = /**
  132. * @return {?}
  133. */
  134. function () { return this._modalRefs.length > 0; };
  135. /**
  136. * @private
  137. * @param {?} moduleCFR
  138. * @param {?} containerEl
  139. * @return {?}
  140. */
  141. NgbModalStack.prototype._attachBackdrop = /**
  142. * @private
  143. * @param {?} moduleCFR
  144. * @param {?} containerEl
  145. * @return {?}
  146. */
  147. function (moduleCFR, containerEl) {
  148. /** @type {?} */
  149. var backdropFactory = moduleCFR.resolveComponentFactory(NgbModalBackdrop);
  150. /** @type {?} */
  151. var backdropCmptRef = backdropFactory.create(this._injector);
  152. this._applicationRef.attachView(backdropCmptRef.hostView);
  153. containerEl.appendChild(backdropCmptRef.location.nativeElement);
  154. return backdropCmptRef;
  155. };
  156. /**
  157. * @private
  158. * @param {?} moduleCFR
  159. * @param {?} containerEl
  160. * @param {?} contentRef
  161. * @return {?}
  162. */
  163. NgbModalStack.prototype._attachWindowComponent = /**
  164. * @private
  165. * @param {?} moduleCFR
  166. * @param {?} containerEl
  167. * @param {?} contentRef
  168. * @return {?}
  169. */
  170. function (moduleCFR, containerEl, contentRef) {
  171. /** @type {?} */
  172. var windowFactory = moduleCFR.resolveComponentFactory(NgbModalWindow);
  173. /** @type {?} */
  174. var windowCmptRef = windowFactory.create(this._injector, contentRef.nodes);
  175. this._applicationRef.attachView(windowCmptRef.hostView);
  176. containerEl.appendChild(windowCmptRef.location.nativeElement);
  177. return windowCmptRef;
  178. };
  179. /**
  180. * @private
  181. * @param {?} windowInstance
  182. * @param {?} options
  183. * @return {?}
  184. */
  185. NgbModalStack.prototype._applyWindowOptions = /**
  186. * @private
  187. * @param {?} windowInstance
  188. * @param {?} options
  189. * @return {?}
  190. */
  191. function (windowInstance, options) {
  192. this._windowAttributes.forEach((/**
  193. * @param {?} optionName
  194. * @return {?}
  195. */
  196. function (optionName) {
  197. if (isDefined(options[optionName])) {
  198. windowInstance[optionName] = options[optionName];
  199. }
  200. }));
  201. };
  202. /**
  203. * @private
  204. * @param {?} backdropInstance
  205. * @param {?} options
  206. * @return {?}
  207. */
  208. NgbModalStack.prototype._applyBackdropOptions = /**
  209. * @private
  210. * @param {?} backdropInstance
  211. * @param {?} options
  212. * @return {?}
  213. */
  214. function (backdropInstance, options) {
  215. this._backdropAttributes.forEach((/**
  216. * @param {?} optionName
  217. * @return {?}
  218. */
  219. function (optionName) {
  220. if (isDefined(options[optionName])) {
  221. backdropInstance[optionName] = options[optionName];
  222. }
  223. }));
  224. };
  225. /**
  226. * @private
  227. * @param {?} moduleCFR
  228. * @param {?} contentInjector
  229. * @param {?} content
  230. * @param {?} activeModal
  231. * @param {?} options
  232. * @return {?}
  233. */
  234. NgbModalStack.prototype._getContentRef = /**
  235. * @private
  236. * @param {?} moduleCFR
  237. * @param {?} contentInjector
  238. * @param {?} content
  239. * @param {?} activeModal
  240. * @param {?} options
  241. * @return {?}
  242. */
  243. function (moduleCFR, contentInjector, content, activeModal, options) {
  244. if (!content) {
  245. return new ContentRef([]);
  246. }
  247. else if (content instanceof TemplateRef) {
  248. return this._createFromTemplateRef(content, activeModal);
  249. }
  250. else if (isString(content)) {
  251. return this._createFromString(content);
  252. }
  253. else {
  254. return this._createFromComponent(moduleCFR, contentInjector, content, activeModal, options);
  255. }
  256. };
  257. /**
  258. * @private
  259. * @param {?} content
  260. * @param {?} activeModal
  261. * @return {?}
  262. */
  263. NgbModalStack.prototype._createFromTemplateRef = /**
  264. * @private
  265. * @param {?} content
  266. * @param {?} activeModal
  267. * @return {?}
  268. */
  269. function (content, activeModal) {
  270. /** @type {?} */
  271. var context = {
  272. $implicit: activeModal,
  273. close: /**
  274. * @param {?} result
  275. * @return {?}
  276. */
  277. function (result) { activeModal.close(result); },
  278. dismiss: /**
  279. * @param {?} reason
  280. * @return {?}
  281. */
  282. function (reason) { activeModal.dismiss(reason); }
  283. };
  284. /** @type {?} */
  285. var viewRef = content.createEmbeddedView(context);
  286. this._applicationRef.attachView(viewRef);
  287. return new ContentRef([viewRef.rootNodes], viewRef);
  288. };
  289. /**
  290. * @private
  291. * @param {?} content
  292. * @return {?}
  293. */
  294. NgbModalStack.prototype._createFromString = /**
  295. * @private
  296. * @param {?} content
  297. * @return {?}
  298. */
  299. function (content) {
  300. /** @type {?} */
  301. var component = this._document.createTextNode("" + content);
  302. return new ContentRef([[component]]);
  303. };
  304. /**
  305. * @private
  306. * @param {?} moduleCFR
  307. * @param {?} contentInjector
  308. * @param {?} content
  309. * @param {?} context
  310. * @param {?} options
  311. * @return {?}
  312. */
  313. NgbModalStack.prototype._createFromComponent = /**
  314. * @private
  315. * @param {?} moduleCFR
  316. * @param {?} contentInjector
  317. * @param {?} content
  318. * @param {?} context
  319. * @param {?} options
  320. * @return {?}
  321. */
  322. function (moduleCFR, contentInjector, content, context, options) {
  323. /** @type {?} */
  324. var contentCmptFactory = moduleCFR.resolveComponentFactory(content);
  325. /** @type {?} */
  326. var modalContentInjector = Injector.create({ providers: [{ provide: NgbActiveModal, useValue: context }], parent: contentInjector });
  327. /** @type {?} */
  328. var componentRef = contentCmptFactory.create(modalContentInjector);
  329. /** @type {?} */
  330. var componentNativeEl = componentRef.location.nativeElement;
  331. if (options.scrollable) {
  332. ((/** @type {?} */ (componentNativeEl))).classList.add('component-host-scrollable');
  333. }
  334. this._applicationRef.attachView(componentRef.hostView);
  335. // FIXME: we should here get rid of the component nativeElement
  336. // and use `[Array.from(componentNativeEl.childNodes)]` instead and remove the above CSS class.
  337. return new ContentRef([[componentNativeEl]], componentRef.hostView, componentRef);
  338. };
  339. /**
  340. * @private
  341. * @param {?} element
  342. * @return {?}
  343. */
  344. NgbModalStack.prototype._setAriaHidden = /**
  345. * @private
  346. * @param {?} element
  347. * @return {?}
  348. */
  349. function (element) {
  350. var _this = this;
  351. /** @type {?} */
  352. var parent = element.parentElement;
  353. if (parent && element !== this._document.body) {
  354. Array.from(parent.children).forEach((/**
  355. * @param {?} sibling
  356. * @return {?}
  357. */
  358. function (sibling) {
  359. if (sibling !== element && sibling.nodeName !== 'SCRIPT') {
  360. _this._ariaHiddenValues.set(sibling, sibling.getAttribute('aria-hidden'));
  361. sibling.setAttribute('aria-hidden', 'true');
  362. }
  363. }));
  364. this._setAriaHidden(parent);
  365. }
  366. };
  367. /**
  368. * @private
  369. * @return {?}
  370. */
  371. NgbModalStack.prototype._revertAriaHidden = /**
  372. * @private
  373. * @return {?}
  374. */
  375. function () {
  376. this._ariaHiddenValues.forEach((/**
  377. * @param {?} value
  378. * @param {?} element
  379. * @return {?}
  380. */
  381. function (value, element) {
  382. if (value) {
  383. element.setAttribute('aria-hidden', value);
  384. }
  385. else {
  386. element.removeAttribute('aria-hidden');
  387. }
  388. }));
  389. this._ariaHiddenValues.clear();
  390. };
  391. /**
  392. * @private
  393. * @param {?} ngbModalRef
  394. * @return {?}
  395. */
  396. NgbModalStack.prototype._registerModalRef = /**
  397. * @private
  398. * @param {?} ngbModalRef
  399. * @return {?}
  400. */
  401. function (ngbModalRef) {
  402. var _this = this;
  403. /** @type {?} */
  404. var unregisterModalRef = (/**
  405. * @return {?}
  406. */
  407. function () {
  408. /** @type {?} */
  409. var index = _this._modalRefs.indexOf(ngbModalRef);
  410. if (index > -1) {
  411. _this._modalRefs.splice(index, 1);
  412. }
  413. });
  414. this._modalRefs.push(ngbModalRef);
  415. ngbModalRef.result.then(unregisterModalRef, unregisterModalRef);
  416. };
  417. /**
  418. * @private
  419. * @param {?} ngbWindowCmpt
  420. * @return {?}
  421. */
  422. NgbModalStack.prototype._registerWindowCmpt = /**
  423. * @private
  424. * @param {?} ngbWindowCmpt
  425. * @return {?}
  426. */
  427. function (ngbWindowCmpt) {
  428. var _this = this;
  429. this._windowCmpts.push(ngbWindowCmpt);
  430. this._activeWindowCmptHasChanged.next();
  431. ngbWindowCmpt.onDestroy((/**
  432. * @return {?}
  433. */
  434. function () {
  435. /** @type {?} */
  436. var index = _this._windowCmpts.indexOf(ngbWindowCmpt);
  437. if (index > -1) {
  438. _this._windowCmpts.splice(index, 1);
  439. _this._activeWindowCmptHasChanged.next();
  440. }
  441. }));
  442. };
  443. NgbModalStack.decorators = [
  444. { type: Injectable, args: [{ providedIn: 'root' },] }
  445. ];
  446. /** @nocollapse */
  447. NgbModalStack.ctorParameters = function () { return [
  448. { type: ApplicationRef },
  449. { type: Injector },
  450. { type: undefined, decorators: [{ type: Inject, args: [DOCUMENT,] }] },
  451. { type: ScrollBar },
  452. { type: RendererFactory2 },
  453. { type: NgZone }
  454. ]; };
  455. /** @nocollapse */ NgbModalStack.ngInjectableDef = i0.ɵɵdefineInjectable({ factory: function NgbModalStack_Factory() { return new NgbModalStack(i0.ɵɵinject(i0.ApplicationRef), i0.ɵɵinject(i0.INJECTOR), i0.ɵɵinject(i1.DOCUMENT), i0.ɵɵinject(i2.ScrollBar), i0.ɵɵinject(i0.RendererFactory2), i0.ɵɵinject(i0.NgZone)); }, token: NgbModalStack, providedIn: "root" });
  456. return NgbModalStack;
  457. }());
  458. export { NgbModalStack };
  459. if (false) {
  460. /**
  461. * @type {?}
  462. * @private
  463. */
  464. NgbModalStack.prototype._activeWindowCmptHasChanged;
  465. /**
  466. * @type {?}
  467. * @private
  468. */
  469. NgbModalStack.prototype._ariaHiddenValues;
  470. /**
  471. * @type {?}
  472. * @private
  473. */
  474. NgbModalStack.prototype._backdropAttributes;
  475. /**
  476. * @type {?}
  477. * @private
  478. */
  479. NgbModalStack.prototype._modalRefs;
  480. /**
  481. * @type {?}
  482. * @private
  483. */
  484. NgbModalStack.prototype._windowAttributes;
  485. /**
  486. * @type {?}
  487. * @private
  488. */
  489. NgbModalStack.prototype._windowCmpts;
  490. /**
  491. * @type {?}
  492. * @private
  493. */
  494. NgbModalStack.prototype._applicationRef;
  495. /**
  496. * @type {?}
  497. * @private
  498. */
  499. NgbModalStack.prototype._injector;
  500. /**
  501. * @type {?}
  502. * @private
  503. */
  504. NgbModalStack.prototype._document;
  505. /**
  506. * @type {?}
  507. * @private
  508. */
  509. NgbModalStack.prototype._scrollBar;
  510. /**
  511. * @type {?}
  512. * @private
  513. */
  514. NgbModalStack.prototype._rendererFactory;
  515. /**
  516. * @type {?}
  517. * @private
  518. */
  519. NgbModalStack.prototype._ngZone;
  520. }
  521. //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9kYWwtc3RhY2suanMiLCJzb3VyY2VSb290Ijoibmc6Ly9AbmctYm9vdHN0cmFwL25nLWJvb3RzdHJhcC8iLCJzb3VyY2VzIjpbIm1vZGFsL21vZGFsLXN0YWNrLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7QUFBQSxPQUFPLEVBQUMsUUFBUSxFQUFDLE1BQU0saUJBQWlCLENBQUM7QUFDekMsT0FBTyxFQUNMLGNBQWMsRUFHZCxNQUFNLEVBQ04sVUFBVSxFQUNWLFFBQVEsRUFDUixNQUFNLEVBQ04sZ0JBQWdCLEVBQ2hCLFdBQVcsRUFDWixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUMsT0FBTyxFQUFDLE1BQU0sTUFBTSxDQUFDO0FBRTdCLE9BQU8sRUFBQyxZQUFZLEVBQUMsTUFBTSxvQkFBb0IsQ0FBQztBQUNoRCxPQUFPLEVBQUMsVUFBVSxFQUFDLE1BQU0sZUFBZSxDQUFDO0FBQ3pDLE9BQU8sRUFBQyxTQUFTLEVBQUMsTUFBTSxtQkFBbUIsQ0FBQztBQUM1QyxPQUFPLEVBQUMsU0FBUyxFQUFFLFFBQVEsRUFBQyxNQUFNLGNBQWMsQ0FBQztBQUNqRCxPQUFPLEVBQUMsZ0JBQWdCLEVBQUMsTUFBTSxrQkFBa0IsQ0FBQztBQUVsRCxPQUFPLEVBQUMsY0FBYyxFQUFFLFdBQVcsRUFBQyxNQUFNLGFBQWEsQ0FBQztBQUN4RCxPQUFPLEVBQUMsY0FBYyxFQUFDLE1BQU0sZ0JBQWdCLENBQUM7Ozs7QUFFOUM7SUFVRSx1QkFDWSxlQUErQixFQUFVLFNBQW1CLEVBQTRCLFNBQWMsRUFDdEcsVUFBcUIsRUFBVSxnQkFBa0MsRUFBVSxPQUFlO1FBRnRHLGlCQVlDO1FBWFcsb0JBQWUsR0FBZixlQUFlLENBQWdCO1FBQVUsY0FBUyxHQUFULFNBQVMsQ0FBVTtRQUE0QixjQUFTLEdBQVQsU0FBUyxDQUFLO1FBQ3RHLGVBQVUsR0FBVixVQUFVLENBQVc7UUFBVSxxQkFBZ0IsR0FBaEIsZ0JBQWdCLENBQWtCO1FBQVUsWUFBTyxHQUFQLE9BQU8s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LEVBQUUsTUFBTSxFQUFDOzs7O2dCQXJCOUIsY0FBYztnQkFLZCxRQUFRO2dEQTJCbUUsTUFBTSxTQUFDLFFBQVE7Z0JBbEJwRixTQUFTO2dCQVBmLGdCQUFnQjtnQkFEaEIsTUFBTTs7O3dCQVJSO0NBK05DLEFBeE1ELElBd01DO1NBdk1ZLGFBQWE7Ozs7OztJQUN4QixvREFBb0Q7Ozs7O0lBQ3BELDBDQUE0RDs7Ozs7SUFDNUQsNENBQWdEOzs7OztJQUNoRCxtQ0FBdUM7Ozs7O0lBQ3ZDLDBDQUNnRzs7Ozs7SUFDaEcscUNBQTBEOzs7OztJQUd0RCx3Q0FBdUM7Ozs7O0lBQUUsa0NBQTJCOzs7OztJQUFFLGtDQUF3Qzs7Ozs7SUFDOUcsbUNBQTZCOzs7OztJQUFFLHlDQUEwQzs7Ozs7SUFBRSxnQ0FBdUIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge0RPQ1VNRU5UfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHtcbiAgQXBwbGljYXRpb25SZWYsXG4gIENvbXBvbmVudEZhY3RvcnlSZXNvbHZlcixcbiAgQ29tcG9uZW50UmVmLFxuICBJbmplY3QsXG4gIEluamVjdGFibGUsXG4gIEluamVjdG9yLFxuICBOZ1pvbmUsXG4gIFJlbmRlcmVyRmFjdG9yeTIsXG4gIFRlbXBsYXRlUmVmXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtTdWJqZWN0fSBmcm9tICdyeGpzJztcblxuaW1wb3J0IHtuZ2JGb2N1c1RyYXB9IGZyb20gJy4uL3V0aWwvZm9jdXMtdHJhcCc7XG5pbXBvcnQge0NvbnRlbnRSZWZ9IGZyb20gJy4uL3V0aWwvcG9wdXAnO1xuaW1wb3J0IHtTY3JvbGxCYXJ9IGZyb20gJy4uL3V0aWwvc2Nyb2xsYmFyJztcbmltcG9ydCB7aXNEZWZpbmVkLCBpc1N0cmluZ30gZnJvbSAnLi4vdXRpbC91dGlsJztcbmltcG9ydCB7TmdiTW9kYWxCYWNrZHJvcH0gZnJvbSAnLi9tb2RhbC1iYWNrZHJvcCc7XG5pbXBvcnQge05nYk1vZGFsT3B0aW9uc30gZnJvbSAnLi9tb2RhbC1jb25maWcnO1xuaW1wb3J0IHtOZ2JBY3RpdmVNb2RhbCwgTmdiTW9kYWxSZWZ9IGZyb20gJy4vbW9kYWwtcmVmJztcbmltcG9ydCB7TmdiTW9kYWxXaW5kb3d9IGZyb20gJy4vbW9kYWwtd2luZG93JztcblxuQEluamVjdGFibGUoe3Byb3ZpZGVkSW46ICdyb290J30pXG5leHBvcnQgY2xhc3MgTmdiTW9kYWxTdGFjayB7XG4gIHByaXZhdGUgX2FjdGl2ZVdpbmRvd0NtcHRIYXNDaGFuZ2VkID0gbmV3IFN1YmplY3QoKTtcbiAgcHJpdmF0ZSBfYXJpYUhpZGRlblZhbHVlczogTWFwPEVsZW1lbnQsIHN0cmluZz4gPSBuZXcgTWFwKCk7XG4gIHByaXZhdGUgX2JhY2tkcm9wQXR0cmlidXRlcyA9IFsnYmFja2Ryb3BDbGFzcyddO1xuICBwcml2YXRlIF9tb2RhbFJlZnM6IE5nYk1vZGFsUmVmW10gPSBbXTtcbiAgcHJpdmF0ZSBfd2luZG93QXR0cmlidXRlcyA9XG4gICAgICBbJ2FyaWFMYWJlbGxlZEJ5JywgJ2JhY2tkcm9wJywgJ2NlbnRlcmVkJywgJ2tleWJvYXJkJywgJ3Njcm9sbGFibGUnLCAnc2l6ZScsICd3aW5kb3dDbGFzcyddO1xuICBwcml2YXRlIF93aW5kb3dDbXB0czogQ29tcG9uZW50UmVmPE5nYk1vZGFsV2luZG93PltdID0gW107XG5cbiAgY29uc3RydWN0b3IoXG4gICAgICBwcml2YXRlIF9hcHBsaWNhdGlvblJlZjogQXBwbGljYXRpb25SZWYsIHByaXZhdGUgX2luamVjdG9yOiBJbmplY3RvciwgQEluamVjdChET0NVTUVOVCkgcHJpdmF0ZSBfZG9jdW1lbnQ6IGFueSxcbiAgICAgIHByaXZhdGUgX3Njcm9sbEJhcjogU2Nyb2xsQmFyLCBwcml2YXRlIF9yZW5kZXJlckZhY3Rvcnk6IFJlbmRlcmVyRmFjdG9yeTIsIHByaXZhdGUgX25nWm9uZTogTmdab25lKSB7XG4gICAgLy8gVHJhcCBmb2N1cyBvbiBhY3RpdmUgV2luZG93Q21wdFxuICAgIHRoaXMuX2FjdGl2ZVdpbmRvd0NtcHRIYXNDaGFuZ2VkLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICBpZiAodGhpcy5fd2luZG93Q21wdHMubGVuZ3RoKSB7XG4gICAgICAgIGNvbnN0IGFjdGl2ZVdpbmRvd0NtcHQgPSB0aGlzLl93aW5kb3dDbXB0c1t0aGlzLl93aW5kb3dDbXB0cy5sZW5ndGggLSAxXTtcbiAgICAgICAgbmdiRm9jdXNUcmFwKHRoaXMuX25nWm9uZSwgYWN0aXZlV2luZG93Q21wdC5sb2NhdGlvbi5uYXRpdmVFbGVtZW50LCB0aGlzLl9hY3RpdmVXaW5kb3dDbXB0SGFzQ2hhbmdlZCk7XG4gICAgICAgIHRoaXMuX3JldmVydEFyaWFIaWRkZW4oKTtcbiAgICAgICAgdGhpcy5fc2V0QXJpYUhpZGRlbihhY3RpdmVXaW5kb3dDbXB0LmxvY2F0aW9uLm5hdGl2ZUVsZW1lbnQpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgb3Blbihtb2R1bGVDRlI6IENvbXBvbmVudEZhY3RvcnlSZXNvbHZlciwgY29udGVudEluamVjdG9yOiBJbmplY3RvciwgY29udGVudDogYW55LCBvcHRpb25zKTogTmdiTW9kYWxSZWYge1xuICAgIGNvbnN0IGNvbnRhaW5lckVsID1cbiAgICAgICAgaXNEZWZpbmVkKG9wdGlvbnMuY29udGFpbmVyKSA/IHRoaXMuX2RvY3VtZW50LnF1ZXJ5U2VsZWN0b3Iob3B0aW9ucy5jb250YWluZXIpIDogdGhpcy5fZG9jdW1lbnQuYm9keTtcbiAgICBjb25zdCByZW5kZXJlciA9IHRoaXMuX3JlbmRlcmVyRmFjdG9yeS5jcmVhdGVSZW5kZXJlcihudWxsLCBudWxsKTtcblxuICAgIGNvbnN0IHJldmVydFBhZGRpbmdGb3JTY3JvbGxCYXIgPSB0aGlzLl9zY3JvbGxCYXIuY29tcGVuc2F0ZSgpO1xuICAgIGNvbnN0IHJlbW92ZUJvZHlDbGFzcyA9ICgpID0+IHtcbiAgICAgIGlmICghdGhpcy5fbW9kYWxSZWZzLmxlbmd0aCkge1xuICAgICAgICByZW5kZXJlci5yZW1vdmVDbGFzcyh0aGlzLl9kb2N1bWVudC5ib2R5LCAnbW9kYWwtb3BlbicpO1xuICAgICAgICB0aGlzLl9yZXZlcnRBcmlhSGlkZGVuKCk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIGlmICghY29udGFpbmVyRWwpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgVGhlIHNwZWNpZmllZCBtb2RhbCBjb250YWluZXIgXCIke29wdGlvbnMuY29udGFpbmVyIHx8ICdib2R5J31cIiB3YXMgbm90IGZvdW5kIGluIHRoZSBET00uYCk7XG4gICAgfVxuXG4gICAgY29uc3QgYWN0aXZlTW9kYWwgPSBuZXcgTmdiQWN0aXZlTW9kYWwoKTtcbiAgICBjb25zdCBjb250ZW50UmVmID1cbiAgICAgICAgdGhpcy5fZ2V0Q29udGVudFJlZihtb2R1bGVDRlIsIG9wdGlvbnMuaW5qZWN0b3IgfHwgY29udGVudEluamVjdG9yLCBjb250ZW50LCBhY3RpdmVNb2RhbCwgb3B0aW9ucyk7XG5cbiAgICBsZXQgYmFja2Ryb3BDbXB0UmVmOiBDb21wb25lbnRSZWY8TmdiTW9kYWxCYWNrZHJvcD4gPVxuICAgICAgICBvcHRpb25zLmJhY2tkcm9wICE9PSBmYWxzZSA/IHRoaXMuX2F0dGFjaEJhY2tkcm9wKG1vZHVsZUNGUiwgY29udGFpbmVyRWwpIDogbnVsbDtcbiAgICBsZXQgd2luZG93Q21wdFJlZjogQ29tcG9uZW50UmVmPE5nYk1vZGFsV2luZG93PiA9IHRoaXMuX2F0dGFjaFdpbmRvd0NvbXBvbmVudChtb2R1bGVDRlIsIGNvbnRhaW5lckVsLCBjb250ZW50UmVmKTtcbiAgICBsZXQgbmdiTW9kYWxSZWY6IE5nYk1vZGFsUmVmID0gbmV3IE5nYk1vZGFsUmVmKHdpbmRvd0NtcHRSZWYsIGNvbnRlbnRSZWYsIGJhY2tkcm9wQ21wdFJlZiwgb3B0aW9ucy5iZWZvcmVEaXNtaXNzKTtcblxuICAgIHRoaXMuX3JlZ2lzdGVyTW9kYWxSZWYobmdiTW9kYWxSZWYpO1xuICAgIHRoaXMuX3JlZ2lzdGVyV2luZG93Q21wdCh3aW5kb3dDbXB0UmVmKTtcbiAgICBuZ2JNb2RhbFJlZi5yZXN1bHQudGhlbihyZXZlcnRQYWRkaW5nRm9yU2Nyb2xsQmFyLCByZXZlcnRQYWRkaW5nRm9yU2Nyb2xsQmFyKTtcbiAgICBuZ2JNb2RhbFJlZi5yZXN1bHQudGhlbihyZW1vdmVCb2R5Q2xhc3MsIHJlbW92ZUJvZHlDbGFzcyk7XG4gICAgYWN0aXZlTW9kYWwuY2xvc2UgPSAocmVzdWx0OiBhbnkpID0+IHsgbmdiTW9kYWxSZWYuY2xvc2UocmVzdWx0KTsgfTtcbiAgICBhY3RpdmVNb2RhbC5kaXNtaXNzID0gKHJlYXNvbjogYW55KSA9PiB7IG5nYk1vZGFsUmVmLmRpc21pc3MocmVhc29uKTsgfTtcblxuICAgIHRoaXMuX2FwcGx5V2luZG93T3B0aW9ucyh3aW5kb3dDbXB0UmVmLmluc3RhbmNlLCBvcHRpb25zKTtcbiAgICBpZiAodGhpcy5fbW9kYWxSZWZzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgcmVuZGVyZXIuYWRkQ2xhc3ModGhpcy5fZG9jdW1lbnQuYm9keSwgJ21vZGFsLW9wZW4nKTtcbiAgICB9XG5cbiAgICBpZiAoYmFja2Ryb3BDbXB0UmVmICYmIGJhY2tkcm9wQ21wdFJlZi5pbnN0YW5jZSkge1xuICAgICAgdGhpcy5fYXBwbHlCYWNrZHJvcE9wdGlvbnMoYmFja2Ryb3BDbXB0UmVmLmluc3RhbmNlLCBvcHRpb25zKTtcbiAgICB9XG4gICAgcmV0dXJuIG5nYk1vZGFsUmVmO1xuICB9XG5cbiAgZGlzbWlzc0FsbChyZWFzb24/OiBhbnkpIHsgdGhpcy5fbW9kYWxSZWZzLmZvckVhY2gobmdiTW9kYWxSZWYgPT4gbmdiTW9kYWxSZWYuZGlzbWlzcyhyZWFzb24pKTsgfVxuXG4gIGhhc09wZW5Nb2RhbHMoKTogYm9vbGVhbiB7IHJldHVybiB0aGlzLl9tb2RhbFJlZnMubGVuZ3RoID4gMDsgfVxuXG4gIHByaXZhdGUgX2F0dGFjaEJhY2tkcm9wKG1vZHVsZUNGUjogQ29tcG9uZW50RmFjdG9yeVJlc29sdmVyLCBjb250YWluZXJFbDogYW55KTogQ29tcG9uZW50UmVmPE5nYk1vZGFsQmFja2Ryb3A+IHtcbiAgICBsZXQgYmFja2Ryb3BGYWN0b3J5ID0gbW9kdWxlQ0ZSLnJlc29sdmVDb21wb25lbnRGYWN0b3J5KE5nYk1vZGFsQmFja2Ryb3ApO1xuICAgIGxldCBiYWNrZHJvcENtcHRSZWYgPSBiYWNrZHJvcEZhY3RvcnkuY3JlYXRlKHRoaXMuX2luamVjdG9yKTtcbiAgICB0aGlzLl9hcHBsaWNhdGlvblJlZi5hdHRhY2hWaWV3KGJhY2tkcm9wQ21wdFJlZi5ob3N0Vmlldyk7XG4gICAgY29udGFpbmVyRWwuYXBwZW5kQ2hpbGQoYmFja2Ryb3BDbXB0UmVmLmxvY2F0aW9uLm5hdGl2ZUVsZW1lbnQpO1xuICAgIHJldHVybiBiYWNrZHJvcENtcHRSZWY7XG4gIH1cblxuICBwcml2YXRlIF9hdHRhY2hXaW5kb3dDb21wb25lbnQobW9kdWxlQ0ZSOiBDb21wb25lbnRGYWN0b3J5UmVzb2x2ZXIsIGNvbnRhaW5lckVsOiBhbnksIGNvbnRlbnRSZWY6IGFueSk6XG4gICAgICBDb21wb25lbnRSZWY8TmdiTW9kYWxXaW5kb3c+IHtcbiAgICBsZXQgd2luZG93RmFjdG9yeSA9IG1vZHVsZUNGUi5yZXNvbHZlQ29tcG9uZW50RmFjdG9yeShOZ2JNb2RhbFdpbmRvdyk7XG4gICAgbGV0IHdpbmRvd0NtcHRSZWYgPSB3aW5kb3dGYWN0b3J5LmNyZWF0ZSh0aGlzLl9pbmplY3RvciwgY29udGVudFJlZi5ub2Rlcyk7XG4gICAgdGhpcy5fYXBwbGljYXRpb25SZWYuYXR0YWNoVmlldyh3aW5kb3dDbXB0UmVmLmhvc3RWaWV3KTtcbiAgICBjb250YWluZXJFbC5hcHBlbmRDaGlsZCh3aW5kb3dDbXB0UmVmLmxvY2F0aW9uLm5hdGl2ZUVsZW1lbnQpO1xuICAgIHJldHVybiB3aW5kb3dDbXB0UmVmO1xuICB9XG5cbiAgcHJpdmF0ZSBfYXBwbHlXaW5kb3dPcHRpb25zKHdpbmRvd0luc3RhbmNlOiBOZ2JNb2RhbFdpbmRvdywgb3B0aW9uczogT2JqZWN0KTogdm9pZCB7XG4gICAgdGhpcy5fd2luZG93QXR0cmlidXRlcy5mb3JFYWNoKChvcHRpb25OYW1lOiBzdHJpbmcpID0+IHtcbiAgICAgIGlmIChpc0RlZmluZWQob3B0aW9uc1tvcHRpb25OYW1lXSkpIHtcbiAgICAgICAgd2luZG93SW5zdGFuY2Vbb3B0aW9uTmFtZV0gPSBvcHRpb25zW29wdGlvbk5hbWVdO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBfYXBwbHlCYWNrZHJvcE9wdGlvbnMoYmFja2Ryb3BJbnN0YW5jZTogTmdiTW9kYWxCYWNrZHJvcCwgb3B0aW9uczogT2JqZWN0KTogdm9pZCB7XG4gICAgdGhpcy5fYmFja2Ryb3BBdHRyaWJ1dGVzLmZvckVhY2goKG9wdGlvbk5hbWU6IHN0cmluZykgPT4ge1xuICAgICAgaWYgKGlzRGVmaW5lZChvcHRpb25zW29wdGlvbk5hbWVdKSkge1xuICAgICAgICBiYWNrZHJvcEluc3RhbmNlW29wdGlvbk5hbWVdID0gb3B0aW9uc1tvcHRpb25OYW1lXTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgX2dldENvbnRlbnRSZWYoXG4gICAgICBtb2R1bGVDRlI6IENvbXBvbmVudEZhY3RvcnlSZXNvbHZlciwgY29udGVudEluamVjdG9yOiBJbmplY3RvciwgY29udGVudDogYW55LCBhY3RpdmVNb2RhbDogTmdiQWN0aXZlTW9kYWwsXG4gICAgICBvcHRpb25zOiBOZ2JNb2RhbE9wdGlvbnMpOiBDb250ZW50UmVmIHtcbiAgICBpZiAoIWNvbnRlbnQpIHtcbiAgICAgIHJldHVybiBuZXcgQ29udGVudFJlZihbXSk7XG4gICAgfSBlbHNlIGlmIChjb250ZW50IGluc3RhbmNlb2YgVGVtcGxhdGVSZWYpIHtcbiAgICAgIHJldHVybiB0aGlzLl9jcmVhdGVGcm9tVGVtcGxhdGVSZWYoY29udGVudCwgYWN0aXZlTW9kYWwpO1xuICAgIH0gZWxzZSBpZiAoaXNTdHJpbmcoY29udGVudCkpIHtcbiAgICAgIHJldHVybiB0aGlzLl9jcmVhdGVGcm9tU3RyaW5nKGNvbnRlbnQpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gdGhpcy5fY3JlYXRlRnJvbUNvbXBvbmVudChtb2R1bGVDRlIsIGNvbnRlbnRJbmplY3RvciwgY29udGVudCwgYWN0aXZlTW9kYWwsIG9wdGlvbnMpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgX2NyZWF0ZUZyb21UZW1wbGF0ZVJlZihjb250ZW50OiBUZW1wbGF0ZVJlZjxhbnk+LCBhY3RpdmVNb2RhbDogTmdiQWN0aXZlTW9kYWwpOiBDb250ZW50UmVmIHtcbiAgICBjb25zdCBjb250ZXh0ID0ge1xuICAgICAgJGltcGxpY2l0OiBhY3RpdmVNb2RhbCxcbiAgICAgIGNsb3NlKHJlc3VsdCkgeyBhY3RpdmVNb2RhbC5jbG9zZShyZXN1bHQpOyB9LFxuICAgICAgZGlzbWlzcyhyZWFzb24pIHsgYWN0aXZlTW9kYWwuZGlzbWlzcyhyZWFzb24pOyB9XG4gICAgfTtcbiAgICBjb25zdCB2aWV3UmVmID0gY29udGVudC5jcmVhdGVFbWJlZGRlZFZpZXcoY29udGV4dCk7XG4gICAgdGhpcy5fYXBwbGljYXRpb25SZWYuYXR0YWNoVmlldyh2aWV3UmVmKTtcbiAgICByZXR1cm4gbmV3IENvbnRlbnRSZWYoW3ZpZXdSZWYucm9vdE5vZGVzXSwgdmlld1JlZik7XG4gIH1cblxuICBwcml2YXRlIF9jcmVhdGVGcm9tU3RyaW5nKGNvbnRlbnQ6IHN0cmluZyk6IENvbnRlbnRSZWYge1xuICAgIGNvbnN0IGNvbXBvbmVudCA9IHRoaXMuX2RvY3VtZW50LmNyZWF0ZVRleHROb2RlKGAke2NvbnRlbnR9YCk7XG4gICAgcmV0dXJuIG5ldyBDb250ZW50UmVmKFtbY29tcG9uZW50XV0pO1xuICB9XG5cbiAgcHJpdmF0ZSBfY3JlYXRlRnJvbUNvbXBvbmVudChcbiAgICAgIG1vZHVsZUNGUjogQ29tcG9uZW50RmFjdG9yeVJlc29sdmVyLCBjb250ZW50SW5qZWN0b3I6IEluamVjdG9yLCBjb250ZW50OiBhbnksIGNvbnRleHQ6IE5nYkFjdGl2ZU1vZGFsLFxuICAgICAgb3B0aW9uczogTmdiTW9kYWxPcHRpb25zKTogQ29udGVudFJlZiB7XG4gICAgY29uc3QgY29udGVudENtcHRGYWN0b3J5ID0gbW9kdWxlQ0ZSLnJlc29sdmVDb21wb25lbnRGYWN0b3J5KGNvbnRlbnQpO1xuICAgIGNvbnN0IG1vZGFsQ29udGVudEluamVjdG9yID1cbiAgICAgICAgSW5qZWN0b3IuY3JlYXRlKHtwcm92aWRlcnM6IFt7cHJvdmlkZTogTmdiQWN0aXZlTW9kYWwsIHVzZVZhbHVlOiBjb250ZXh0fV0sIHBhcmVudDogY29udGVudEluamVjdG9yfSk7XG4gICAgY29uc3QgY29tcG9uZW50UmVmID0gY29udGVudENtcHRGYWN0b3J5LmNyZWF0ZShtb2RhbENvbnRlbnRJbmplY3Rvcik7XG4gICAgY29uc3QgY29tcG9uZW50TmF0aXZlRWwgPSBjb21wb25lbnRSZWYubG9jYXRpb24ubmF0aXZlRWxlbWVudDtcbiAgICBpZiAob3B0aW9ucy5zY3JvbGxhYmxlKSB7XG4gICAgICAoY29tcG9uZW50TmF0aXZlRWwgYXMgSFRNTEVsZW1lbnQpLmNsYXNzTGlzdC5hZGQoJ2NvbXBvbmVudC1ob3N0LXNjcm9sbGFibGUnKTtcbiAgICB9XG4gICAgdGhpcy5fYXBwbGljYXRpb25SZWYuYXR0YWNoVmlldyhjb21wb25lbnRSZWYuaG9zdFZpZXcpO1xuICAgIC8vIEZJWE1FOiB3ZSBzaG91bGQgaGVyZSBnZXQgcmlkIG9mIHRoZSBjb21wb25lbnQgbmF0aXZlRWxlbWVudFxuICAgIC8vIGFuZCB1c2UgYFtBcnJheS5mcm9tKGNvbXBvbmVudE5hdGl2ZUVsLmNoaWxkTm9kZXMpXWAgaW5zdGVhZCBhbmQgcmVtb3ZlIHRoZSBhYm92ZSBDU1MgY2xhc3MuXG4gICAgcmV0dXJuIG5ldyBDb250ZW50UmVmKFtbY29tcG9uZW50TmF0aXZlRWxdXSwgY29tcG9uZW50UmVmLmhvc3RWaWV3LCBjb21wb25lbnRSZWYpO1xuICB9XG5cbiAgcHJpdmF0ZSBfc2V0QXJpYUhpZGRlbihlbGVtZW50OiBFbGVtZW50KSB7XG4gICAgY29uc3QgcGFyZW50ID0gZWxlbWVudC5wYXJlbnRFbGVtZW50O1xuICAgIGlmIChwYXJlbnQgJiYgZWxlbWVudCAhPT0gdGhpcy5fZG9jdW1lbnQuYm9keSkge1xuICAgICAgQXJyYXkuZnJvbShwYXJlbnQuY2hpbGRyZW4pLmZvckVhY2goc2libGluZyA9PiB7XG4gICAgICAgIGlmIChzaWJsaW5nICE9PSBlbGVtZW50ICYmIHNpYmxpbmcubm9kZU5hbWUgIT09ICdTQ1JJUFQnKSB7XG4gICAgICAgICAgdGhpcy5fYXJpYUhpZGRlblZhbHVlcy5zZXQoc2libGluZywgc2libGluZy5nZXRBdHRyaWJ1dGUoJ2FyaWEtaGlkZGVuJykpO1xuICAgICAgICAgIHNpYmxpbmcuc2V0QXR0cmlidXRlKCdhcmlhLWhpZGRlbicsICd0cnVlJyk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICB0aGlzLl9zZXRBcmlhSGlkZGVuKHBhcmVudCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBfcmV2ZXJ0QXJpYUhpZGRlbigpIHtcbiAgICB0aGlzLl9hcmlhSGlkZGVuVmFsdWVzLmZvckVhY2goKHZhbHVlLCBlbGVtZW50KSA9PiB7XG4gICAgICBpZiAodmFsdWUpIHtcbiAgICAgICAgZWxlbWVudC5zZXRBdHRyaWJ1dGUoJ2FyaWEtaGlkZGVuJywgdmFsdWUpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZWxlbWVudC5yZW1vdmVBdHRyaWJ1dGUoJ2FyaWEtaGlkZGVuJyk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgdGhpcy5fYXJpYUhpZGRlblZhbHVlcy5jbGVhcigpO1xuICB9XG5cbiAgcHJpdmF0ZSBfcmVnaXN0ZXJNb2RhbFJlZihuZ2JNb2RhbFJlZjogTmdiTW9kYWxSZWYpIHtcbiAgICBjb25zdCB1bnJlZ2lzdGVyTW9kYWxSZWYgPSAoKSA9PiB7XG4gICAgICBjb25zdCBpbmRleCA9IHRoaXMuX21vZGFsUmVmcy5pbmRleE9mKG5nYk1vZGFsUmVmKTtcbiAgICAgIGlmIChpbmRleCA+IC0xKSB7XG4gICAgICAgIHRoaXMuX21vZGFsUmVmcy5zcGxpY2UoaW5kZXgsIDEpO1xuICAgICAgfVxuICAgIH07XG4gICAgdGhpcy5fbW9kYWxSZWZzLnB1c2gobmdiTW9kYWxSZWYpO1xuICAgIG5nYk1vZGFsUmVmLnJlc3VsdC50aGVuKHVucmVnaXN0ZXJNb2RhbFJlZiwgdW5yZWdpc3Rlck1vZGFsUmVmKTtcbiAgfVxuXG4gIHByaXZhdGUgX3JlZ2lzdGVyV2luZG93Q21wdChuZ2JXaW5kb3dDbXB0OiBDb21wb25lbnRSZWY8TmdiTW9kYWxXaW5kb3c+KSB7XG4gICAgdGhpcy5fd2luZG93Q21wdHMucHVzaChuZ2JXaW5kb3dDbXB0KTtcbiAgICB0aGlzLl9hY3RpdmVXaW5kb3dDbXB0SGFzQ2hhbmdlZC5uZXh0KCk7XG5cbiAgICBuZ2JXaW5kb3dDbXB0Lm9uRGVzdHJveSgoKSA9PiB7XG4gICAgICBjb25zdCBpbmRleCA9IHRoaXMuX3dpbmRvd0NtcHRzLmluZGV4T2YobmdiV2luZG93Q21wdCk7XG4gICAgICBpZiAoaW5kZXggPiAtMSkge1xuICAgICAgICB0aGlzLl93aW5kb3dDbXB0cy5zcGxpY2UoaW5kZXgsIDEpO1xuICAgICAgICB0aGlzLl9hY3RpdmVXaW5kb3dDbXB0SGFzQ2hhbmdlZC5uZXh0KCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cbn1cbiJdfQ==