UNPKG

@greg-md/ng-facebook

Version:
594 lines (584 loc) 53.7 kB
import { Inject, Injectable, NgZone, PLATFORM_ID, Directive, Input, ElementRef, Renderer2, InjectionToken, Optional, NgModule, Component, ChangeDetectionStrategy, defineInjectable, inject } from '@angular/core'; import { isPlatformServer, isPlatformBrowser, CommonModule } from '@angular/common'; import { Observable, ReplaySubject } from 'rxjs'; import { tap, map } from 'rxjs/operators'; import { __extends } from 'tslib'; /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ var /** @type {?} */ FACEBOOK_DEFAULTS = { xfbml: false, version: 'v3.0' }; var FacebookService = /** @class */ (function () { function FacebookService(ngZone, platformId) { this.ngZone = ngZone; this.platformId = platformId; this.sdk = new ReplaySubject(1); } /** * @param {?=} locale * @return {?} */ FacebookService.prototype.load = /** * @param {?=} locale * @return {?} */ function (locale) { var _this = this; if (locale === void 0) { locale = 'en_US'; } return Observable.create(function (subscriber) { if (isPlatformServer(_this.platformId)) { return; } _this.ngZone.runOutsideAngular(function () { delete window.FB; var /** @type {?} */ jsSdk, /** @type {?} */ fbRoot; if (jsSdk = document.getElementById('facebook-jssdk')) { jsSdk.parentNode.removeChild(jsSdk); } if (fbRoot = document.getElementById('fb-root')) { fbRoot.parentNode.removeChild(fbRoot); } var /** @type {?} */ script = document.createElement('script'); script.id = 'facebook-jssdk'; script.src = '//connect.facebook.net/' + (locale || 'en_US') + '/sdk.js'; script.onload = function () { _this.ngZone.run(function () { subscriber.next(FB); subscriber.complete(); }); }; script.onerror = function () { _this.ngZone.run(function () { subscriber.error('Facebook SDK could not be loaded.'); subscriber.complete(); }); }; document.head.appendChild(script); }); }).pipe(map(function (sdk) { _this.sdk.next(sdk); return sdk; })); }; /** * @param {?=} params * @param {?=} locale * @return {?} */ FacebookService.prototype.init = /** * @param {?=} params * @param {?=} locale * @return {?} */ function (params, locale) { var _this = this; if (params === void 0) { params = {}; } if (locale === void 0) { locale = 'en_US'; } return this.load(locale).pipe(tap(function (sdk) { params = Object.assign({}, FACEBOOK_DEFAULTS, params); sdk.init(params); _this.reloadRenderedElements().subscribe(); })); }; /** * @param {?=} options * @return {?} */ FacebookService.prototype.login = /** * @param {?=} options * @return {?} */ function (options) { var _this = this; return Observable.create(function (subscriber) { _this.sdk.subscribe(function (sdk) { _this.ngZone.runOutsideAngular(function () { sdk.login(function (response) { _this.ngZone.run(function () { if (response.authResponse) { subscriber.next(response.authResponse); } else { subscriber.error(response); } subscriber.complete(); }); }, options); }); }); }); }; /** * @param {?} path * @param {?=} method * @param {?=} params * @return {?} */ FacebookService.prototype.api = /** * @param {?} path * @param {?=} method * @param {?=} params * @return {?} */ function (path, method, params) { var _this = this; return Observable.create(function (subscriber) { _this.sdk.subscribe(function (sdk) { _this.ngZone.runOutsideAngular(function () { sdk.api(path, method, params, function (response) { _this.ngZone.run(function () { if (response && !response.error) { subscriber.next(response); } else { subscriber.error(response ? response.error : null); } subscriber.complete(); }); }); }); }); }); }; /** * @param {?} element * @return {?} */ FacebookService.prototype.parse = /** * @param {?} element * @return {?} */ function (element) { var _this = this; return Observable.create(function (subscriber) { _this.sdk.subscribe(function (sdk) { _this.ngZone.runOutsideAngular(function () { sdk.XFBML.parse(element, function () { _this.ngZone.run(function () { subscriber.next(element); subscriber.complete(); }); }); }); }); }); }; /** * @return {?} */ FacebookService.prototype.reloadRenderedElements = /** * @return {?} */ function () { var _this = this; return Observable.create(function (subscriber) { _this.sdk.subscribe(function (sdk) { var /** @type {?} */ elements = document.querySelectorAll('[fb-xfbml-state="rendered"]'); var /** @type {?} */ processing = elements.length; Array.from(elements).forEach(function (node) { _this.ngZone.runOutsideAngular(function () { sdk.XFBML.parse(node.parentElement, function () { _this.ngZone.run(function () { --processing; subscriber.next(node.parentElement); if (processing <= 0) { subscriber.complete(); } }); }); }); }); }); }); }; FacebookService.decorators = [ { type: Injectable, args: [{ providedIn: 'root' },] }, ]; /** @nocollapse */ FacebookService.ctorParameters = function () { return [ { type: NgZone, }, { type: undefined, decorators: [{ type: Inject, args: [PLATFORM_ID,] },] }, ]; }; /** @nocollapse */ FacebookService.ngInjectableDef = defineInjectable({ factory: function FacebookService_Factory() { return new FacebookService(inject(NgZone), inject(PLATFORM_ID)); }, token: FacebookService, providedIn: "root" }); return FacebookService; }()); /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ /** * @param {?} element * @return {?} */ function offset(element) { // Support: IE <=11 only // Running getBoundingClientRect on a // disconnected node in IE throws an error if (!element || !element.getClientRects().length) { return { top: 0, left: 0 }; } var /** @type {?} */ docElem, /** @type {?} */ rect, /** @type {?} */ doc; rect = element.getBoundingClientRect(); // Make sure element is not hidden (display: none) if (rect.width || rect.height) { doc = element.ownerDocument; docElem = doc.documentElement; return { top: rect.top + window.pageYOffset - docElem.clientTop, left: rect.left + window.pageXOffset - docElem.clientLeft }; } // Return zeros for disconnected and hidden elements (gh-2310) return rect; } /** * @param {?} element * @param {?=} settings * @return {?} */ function aboveTheTop(element, settings) { if (settings === void 0) { settings = {}; } if (!element) { return false; } var /** @type {?} */ fold; var /** @type {?} */ container = settings.container || window, /** @type {?} */ threshold = settings.threshold || 0; if (container instanceof HTMLElement) { fold = offset(container).top; } else { fold = window.scrollY; } return fold >= (offset(element).top + threshold + element.offsetHeight); } /** * @param {?} element * @param {?=} settings * @return {?} */ function rightOfFold(element, settings) { if (settings === void 0) { settings = {}; } if (!element) { return false; } var /** @type {?} */ fold; var /** @type {?} */ container = settings.container || window, /** @type {?} */ threshold = settings.threshold || 0; if (container instanceof HTMLElement) { fold = offset(container).left + container.offsetWidth; } else { fold = window.innerWidth + window.scrollX; } return fold <= offset(element).left - threshold; } /** * @param {?} element * @param {?=} settings * @return {?} */ function belowTheFold(element, settings) { if (settings === void 0) { settings = {}; } if (!element) { return false; } var /** @type {?} */ fold; var /** @type {?} */ container = settings.container || window, /** @type {?} */ threshold = settings.threshold || 0; if (container instanceof HTMLElement) { fold = offset(container).top + container.offsetHeight; } else { fold = window.innerHeight + window.scrollY; } return fold <= offset(element).top - threshold; } /** * @param {?} element * @param {?=} settings * @return {?} */ function leftOfBegin(element, settings) { if (settings === void 0) { settings = {}; } if (!element) { return false; } var /** @type {?} */ fold; var /** @type {?} */ container = settings.container || window, /** @type {?} */ threshold = settings.threshold || 0; if (container instanceof HTMLElement) { fold = offset(container).left; } else { fold = window.scrollX; } return fold >= offset(element).left + threshold + element.offsetWidth; } /** * @param {?} element * @param {?=} settings * @return {?} */ function inViewport(element, settings) { if (settings === void 0) { settings = {}; } return !belowTheFold(element, settings) && !aboveTheTop(element, settings) && !leftOfBegin(element, settings) && !rightOfFold(element, settings); } /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ var /** @type {?} */ FB_PARSE_LAZY_LOAD = new InjectionToken('fb_parse_lazy_load'); var FacebookParseDirective = /** @class */ (function () { function FacebookParseDirective(elementRef, facebook, renderer, platformId, threshold) { this.elementRef = elementRef; this.facebook = facebook; this.renderer = renderer; this.platformId = platformId; this.threshold = threshold; } Object.defineProperty(FacebookParseDirective.prototype, "lazyLoad", { set: /** * @param {?} threshold * @return {?} */ function (threshold) { this.threshold = threshold; }, enumerable: true, configurable: true }); /** * @return {?} */ FacebookParseDirective.prototype.ngAfterViewInit = /** * @return {?} */ function () { if (this.threshold === null) { this.load(); } else { this.initListeners(); this.tryLoading(); } }; /** * @return {?} */ FacebookParseDirective.prototype.ngOnDestroy = /** * @return {?} */ function () { this.unloadListeners(); }; /** * @return {?} */ FacebookParseDirective.prototype.initListeners = /** * @return {?} */ function () { var _this = this; this.scrollUnload = this.renderer.listen('window', 'scroll', function () { _this.tryLoading(); }); this.resizeUnload = this.renderer.listen('window', 'resize', function () { _this.tryLoading(); }); }; /** * @return {?} */ FacebookParseDirective.prototype.tryLoading = /** * @return {?} */ function () { if (isPlatformBrowser(this.platformId) && inViewport(this.elementRef.nativeElement, { threshold: this.threshold, container: this.container })) { this.load(); this.unloadListeners(); } }; /** * @return {?} */ FacebookParseDirective.prototype.load = /** * @return {?} */ function () { this.facebook.parse(this.elementRef.nativeElement).subscribe(); }; /** * @return {?} */ FacebookParseDirective.prototype.unloadListeners = /** * @return {?} */ function () { if (this.scrollUnload) { this.scrollUnload(); } if (this.resizeUnload) { this.resizeUnload(); } }; FacebookParseDirective.decorators = [ { type: Directive, args: [{ selector: '[fbParse]', },] }, ]; /** @nocollapse */ FacebookParseDirective.ctorParameters = function () { return [ { type: ElementRef, }, { type: FacebookService, }, { type: Renderer2, }, { type: Object, decorators: [{ type: Inject, args: [PLATFORM_ID,] },] }, { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [FB_PARSE_LAZY_LOAD,] },] }, ]; }; FacebookParseDirective.propDecorators = { "lazyLoad": [{ type: Input },], "container": [{ type: Input },], }; return FacebookParseDirective; }()); /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ var FacebookLikeComponent = /** @class */ (function (_super) { __extends(FacebookLikeComponent, _super); function FacebookLikeComponent(elementRef, facebook, renderer, platformId, threshold) { var _this = _super.call(this, elementRef, facebook, renderer, platformId, threshold) || this; _this.action = 'like'; _this.colorscheme = 'light'; _this.kidDirectedSite = false; _this.layout = 'standard'; _this.share = false; _this.showFaces = false; _this.size = 'small'; return _this; } FacebookLikeComponent.decorators = [ { type: Component, args: [{ selector: 'fb-like', styles: [], template: "\n <div class=\"fb-like\"\n [attr.data-action]=\"action\"\n [attr.data-colorscheme]=\"colorscheme\"\n [attr.data-href]=\"href\"\n [attr.data-kid-directed-site]=\"kidDirectedSite\"\n [attr.data-layout]=\"layout\"\n [attr.data-ref]=\"ref\"\n [attr.data-share]=\"share\"\n [attr.data-show-faces]=\"showFaces\"\n [attr.data-size]=\"size\"\n [attr.data-width]=\"width\"\n >\n <ng-content></ng-content>\n </div>\n ", changeDetection: ChangeDetectionStrategy.OnPush, },] }, ]; /** @nocollapse */ FacebookLikeComponent.ctorParameters = function () { return [ { type: ElementRef, }, { type: FacebookService, }, { type: Renderer2, }, { type: Object, decorators: [{ type: Inject, args: [PLATFORM_ID,] },] }, { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [FB_PARSE_LAZY_LOAD,] },] }, ]; }; FacebookLikeComponent.propDecorators = { "action": [{ type: Input },], "colorscheme": [{ type: Input },], "href": [{ type: Input },], "kidDirectedSite": [{ type: Input },], "layout": [{ type: Input },], "ref": [{ type: Input },], "share": [{ type: Input },], "showFaces": [{ type: Input },], "size": [{ type: Input },], "width": [{ type: Input },], }; return FacebookLikeComponent; }(FacebookParseDirective)); /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ var FacebookPageComponent = /** @class */ (function (_super) { __extends(FacebookPageComponent, _super); function FacebookPageComponent(elementRef, facebook, renderer, platformId, threshold) { var _this = _super.call(this, elementRef, facebook, renderer, platformId, threshold) || this; _this.width = 340; _this.height = 500; _this.tabs = 'timeline'; _this.hideCover = false; _this.showFacepile = true; _this.hideCta = false; _this.smallHeader = false; _this.adaptContainerWidth = true; return _this; } FacebookPageComponent.decorators = [ { type: Component, args: [{ selector: 'fb-page', styles: [], template: "\n <div class=\"fb-page\"\n [attr.data-href]=\"href\"\n [attr.data-width]=\"width\"\n [attr.data-height]=\"height\"\n [attr.data-tabs]=\"tabs\"\n [attr.data-hide-cover]=\"hideCover\"\n [attr.data-show-facepile]=\"showFacepile\"\n [attr.data-hide-cta]=\"hideCta\"\n [attr.data-small-header]=\"smallHeader\"\n [attr.data-adapt-container-width]=\"adaptContainerWidth\"\n >\n <blockquote [attr.cite]=\"href\" class=\"fb-xfbml-parse-ignore\">\n <a [href]=\"href\">\n <ng-content></ng-content>\n </a>\n </blockquote>\n </div>\n ", changeDetection: ChangeDetectionStrategy.OnPush, },] }, ]; /** @nocollapse */ FacebookPageComponent.ctorParameters = function () { return [ { type: ElementRef, }, { type: FacebookService, }, { type: Renderer2, }, { type: Object, decorators: [{ type: Inject, args: [PLATFORM_ID,] },] }, { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [FB_PARSE_LAZY_LOAD,] },] }, ]; }; FacebookPageComponent.propDecorators = { "href": [{ type: Input },], "width": [{ type: Input },], "height": [{ type: Input },], "tabs": [{ type: Input },], "hideCover": [{ type: Input },], "showFacepile": [{ type: Input },], "hideCta": [{ type: Input },], "smallHeader": [{ type: Input },], "adaptContainerWidth": [{ type: Input },], }; return FacebookPageComponent; }(FacebookParseDirective)); /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ var FacebookModule = /** @class */ (function () { function FacebookModule() { } FacebookModule.decorators = [ { type: NgModule, args: [{ imports: [ CommonModule, ], declarations: [ FacebookParseDirective, FacebookPageComponent, FacebookLikeComponent, ], exports: [ FacebookParseDirective, FacebookPageComponent, FacebookLikeComponent, ], },] }, ]; return FacebookModule; }()); /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ export { FACEBOOK_DEFAULTS, FacebookService, FacebookLikeComponent, FacebookPageComponent, FB_PARSE_LAZY_LOAD, FacebookParseDirective, FacebookModule }; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ3JlZy1tZC1uZy1mYWNlYm9vay5qcy5tYXAiLCJzb3VyY2VzIjpbIm5nOi8vQGdyZWctbWQvbmctZmFjZWJvb2svbGliL2ZhY2Vib29rLnNlcnZpY2UudHMiLCJuZzovL0BncmVnLW1kL25nLWZhY2Vib29rL2xpYi9kb20udHMiLCJuZzovL0BncmVnLW1kL25nLWZhY2Vib29rL2xpYi9wYXJzZS5kaXJlY3RpdmUudHMiLCJuZzovL0BncmVnLW1kL25nLWZhY2Vib29rL2xpYi9saWtlLmNvbXBvbmVudC50cyIsIm5nOi8vQGdyZWctbWQvbmctZmFjZWJvb2svbGliL3BhZ2UuY29tcG9uZW50LnRzIiwibmc6Ly9AZ3JlZy1tZC9uZy1mYWNlYm9vay9saWIvZmFjZWJvb2subW9kdWxlLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdCwgSW5qZWN0YWJsZSwgTmdab25lLCBQTEFURk9STV9JRCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgaXNQbGF0Zm9ybVNlcnZlciB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQgeyBPYnNlcnZhYmxlLCBSZXBsYXlTdWJqZWN0IH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyB0YXAsIG1hcCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcblxuZXhwb3J0IGludGVyZmFjZSBGYWNlYm9va0luaXRQYXJhbXMge1xuICBhcHBJZD86IHN0cmluZztcbiAgc3RhdHVzPzogYm9vbGVhbjtcbiAgeGZibWw/OiBib29sZWFuO1xuICB2ZXJzaW9uPzogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEZhY2Vib29rQXV0aCB7XG4gIGFjY2Vzc1Rva2VuOiBzdHJpbmc7XG4gIGV4cGlyZXNJbjogbnVtYmVyO1xuICBzaWduZWRSZXF1ZXN0OiBzdHJpbmc7XG4gIHVzZXJJRDogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEZhY2Vib29rTG9naW5SZXNwb25zZSB7XG4gIHN0YXR1czogc3RyaW5nO1xuICBhdXRoUmVzcG9uc2U6IEZhY2Vib29rQXV0aDtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBGYWNlYm9va0xvZ2luT3B0aW9ucyB7XG4gIGF1dGhfdHlwZT86ICdyZXJlcXVlc3QnO1xuICBzY29wZT86IHN0cmluZztcbiAgcmV0dXJuX3Njb3Blcz86IGJvb2xlYW47XG4gIGVuYWJsZV9wcm9maWxlX3NlbGVjdG9yPzogYm9vbGVhbjtcbiAgcHJvZmlsZV9zZWxlY3Rvcl9pZHM/OiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgRmFjZWJvb2tBcGlFcnJvciB7XG4gIG1lc3NhZ2U6IHN0cmluZztcbn1cblxuZXhwb3J0IGNvbnN0IGVudW0gRmFjZWJvb2tBcGlNZXRob2Qge1xuICBHZXQgPSAnZ2V0JyxcbiAgUG9zdCA9ICdwb3N0JyxcbiAgRGVsZXRlID0gJ2RlbGV0ZScsXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgRmFjZWJvb2tBcGlQYXJhbXMge1xuICBbcHJvcE5hbWU6IHN0cmluZ106IGFueTtcbn1cblxuZXhwb3J0IHR5cGUgRmFjZWJvb2tBcGlDYWxsYmFjayA9IChyZXNwb25zZT86IHtcbiAgICBlcnJvcj86IEZhY2Vib29rQXBpRXJyb3I7XG4gICAgW3Byb3BOYW1lOiBzdHJpbmddOiBhbnk7XG4gIH0pID0+IHZvaWQ7XG5cbmV4cG9ydCBpbnRlcmZhY2UgRmFjZWJvb2sge1xuICBYRkJNTDoge1xuICAgIHBhcnNlOiAoZWxlbWVudDogSFRNTEVsZW1lbnQsIGNiPzogKCkgPT4gdm9pZCkgPT4gdm9pZDtcbiAgfTtcblxuICBpbml0OiAocGFyYW1zOiBGYWNlYm9va0luaXRQYXJhbXMpID0+IHZvaWQ7XG5cbiAgbG9naW46IChjYWxsYmFjaz86IChyZXNwb25zZTogRmFjZWJvb2tMb2dpblJlc3BvbnNlKSA9PiB2b2lkLCBvcHRpb25zPzogRmFjZWJvb2tMb2dpbk9wdGlvbnMpID0+IHZvaWQ7XG5cbiAgYXBpOiAoXG4gICAgcGF0aDogc3RyaW5nLFxuICAgIG1ldGhvZD86IEZhY2Vib29rQXBpTWV0aG9kIHwgRmFjZWJvb2tBcGlQYXJhbXMgfCBGYWNlYm9va0FwaUNhbGxiYWNrLFxuICAgIHBhcmFtcz86IEZhY2Vib29rQXBpUGFyYW1zIHwgRmFjZWJvb2tBcGlDYWxsYmFjayxcbiAgICBjYWxsYmFjaz86IEZhY2Vib29rQXBpQ2FsbGJhY2tcbiAgKSA9PiB2b2lkO1xufVxuXG5leHBvcnQgY29uc3QgRkFDRUJPT0tfREVGQVVMVFM6IEZhY2Vib29rSW5pdFBhcmFtcyA9IHtcbiAgeGZibWw6IGZhbHNlLFxuICB2ZXJzaW9uOiAndjMuMCdcbn07XG5cbmRlY2xhcmUgY29uc3QgRkI6IEZhY2Vib29rO1xuXG5kZWNsYXJlIGNvbnN0IHdpbmRvdzoge1xuICBGQjogRmFjZWJvb2s7XG59O1xuXG5ASW5qZWN0YWJsZSh7XG4gIHByb3ZpZGVkSW46ICdyb290J1xufSlcbmV4cG9ydCBjbGFzcyBGYWNlYm9va1NlcnZpY2Uge1xuICBzZGsgPSBuZXcgUmVwbGF5U3ViamVjdDxGYWNlYm9vaz4oMSk7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBuZ1pvbmU6IE5nWm9uZSxcbiAgICBASW5qZWN0KFBMQVRGT1JNX0lEKSBwcml2YXRlIHBsYXRmb3JtSWQ6IHN0cmluZyxcbiAgKSB7XG4gIH1cblxuICBsb2FkKGxvY2FsZTogc3RyaW5nID0gJ2VuX1VTJyk6IE9ic2VydmFibGU8RmFjZWJvb2s+IHtcbiAgICByZXR1cm4gT2JzZXJ2YWJsZS5jcmVhdGUoc3Vic2NyaWJlciA9PiB7XG4gICAgICBpZiAoaXNQbGF0Zm9ybVNlcnZlcih0aGlzLnBsYXRmb3JtSWQpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgdGhpcy5uZ1pvbmUucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4ge1xuICAgICAgICBkZWxldGUgd2luZG93LkZCO1xuXG4gICAgICAgIGxldCBqc1NkazogSFRNTEVsZW1lbnQsIGZiUm9vdDogSFRNTEVsZW1lbnQ7XG5cbiAgICAgICAgaWYgKGpzU2RrID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2ZhY2Vib29rLWpzc2RrJykpIHtcbiAgICAgICAgICBqc1Nkay5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKGpzU2RrKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChmYlJvb3QgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZmItcm9vdCcpKSB7XG4gICAgICAgICAgZmJSb290LnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoZmJSb290KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHNjcmlwdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NjcmlwdCcpO1xuXG4gICAgICAgIHNjcmlwdC5pZCA9ICdmYWNlYm9vay1qc3Nkayc7XG5cbiAgICAgICAgc2NyaXB0LnNyYyA9ICcvL2Nvbm5lY3QuZmFjZWJvb2submV0LycgKyAobG9jYWxlIHx8ICdlbl9VUycpICsgJy9zZGsuanMnO1xuXG4gICAgICAgIHNjcmlwdC5vbmxvYWQgPSAoKSA9PiB7XG4gICAgICAgICAgdGhpcy5uZ1pvbmUucnVuKCgpID0+IHtcbiAgICAgICAgICAgIHN1YnNjcmliZXIubmV4dChGQik7XG5cbiAgICAgICAgICAgIHN1YnNjcmliZXIuY29tcGxldGUoKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfTtcblxuICAgICAgICBzY3JpcHQub25lcnJvciA9ICgpID0+IHtcbiAgICAgICAgICB0aGlzLm5nWm9uZS5ydW4oKCkgPT4ge1xuICAgICAgICAgICAgc3Vic2NyaWJlci5lcnJvcignRmFjZWJvb2sgU0RLIGNvdWxkIG5vdCBiZSBsb2FkZWQuJyk7XG5cbiAgICAgICAgICAgIHN1YnNjcmliZXIuY29tcGxldGUoKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfTtcblxuICAgICAgICBkb2N1bWVudC5oZWFkLmFwcGVuZENoaWxkKHNjcmlwdCk7XG4gICAgICB9KTtcbiAgICB9KS5waXBlKG1hcCgoc2RrOiBGYWNlYm9vaykgPT4ge1xuICAgICAgdGhpcy5zZGsubmV4dChzZGspO1xuXG4gICAgICByZXR1cm4gc2RrO1xuICAgIH0pKTtcbiAgfVxuXG4gIGluaXQocGFyYW1zOiBGYWNlYm9va0luaXRQYXJhbXMgPSB7fSwgbG9jYWxlOiBzdHJpbmcgPSAnZW5fVVMnKSB7XG4gICAgcmV0dXJuIHRoaXMubG9hZChsb2NhbGUpLnBpcGU8RmFjZWJvb2s+KHRhcDxGYWNlYm9vaz4oc2RrID0+IHtcbiAgICAgIHBhcmFtcyA9IE9iamVjdC5hc3NpZ24oe30sIEZBQ0VCT09LX0RFRkFVTFRTLCBwYXJhbXMpO1xuXG4gICAgICBzZGsuaW5pdChwYXJhbXMpO1xuXG4gICAgICB0aGlzLnJlbG9hZFJlbmRlcmVkRWxlbWVudHMoKS5zdWJzY3JpYmUoKTtcbiAgICB9KSk7XG4gIH1cblxuICBsb2dpbihvcHRpb25zPzogRmFjZWJvb2tMb2dpbk9wdGlvbnMpOiBPYnNlcnZhYmxlPEZhY2Vib29rQXV0aD4ge1xuICAgIHJldHVybiBPYnNlcnZhYmxlLmNyZWF0ZShzdWJzY3JpYmVyID0+IHtcbiAgICAgIHRoaXMuc2RrLnN1YnNjcmliZShzZGsgPT4ge1xuICAgICAgICB0aGlzLm5nWm9uZS5ydW5PdXRzaWRlQW5ndWxhcigoKSA9PiB7XG4gICAgICAgICAgc2RrLmxvZ2luKHJlc3BvbnNlID0+IHtcbiAgICAgICAgICAgIHRoaXMubmdab25lLnJ1bigoKSA9PiB7XG4gICAgICAgICAgICAgIGlmIChyZXNwb25zZS5hdXRoUmVzcG9uc2UpIHtcbiAgICAgICAgICAgICAgICBzdWJzY3JpYmVyLm5leHQocmVzcG9uc2UuYXV0aFJlc3BvbnNlKTtcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBzdWJzY3JpYmVyLmVycm9yKHJlc3BvbnNlKTtcbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIHN1YnNjcmliZXIuY29tcGxldGUoKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH0sIG9wdGlvbnMpO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgYXBpKHBhdGg6IHN0cmluZywgbWV0aG9kPzogRmFjZWJvb2tBcGlNZXRob2QgfCBGYWNlYm9va0FwaVBhcmFtcywgcGFyYW1zPzogRmFjZWJvb2tBcGlQYXJhbXMpOiBPYnNlcnZhYmxlPE9iamVjdD4ge1xuICAgIHJldHVybiBPYnNlcnZhYmxlLmNyZWF0ZShzdWJzY3JpYmVyID0+IHtcbiAgICAgIHRoaXMuc2RrLnN1YnNjcmliZShzZGsgPT4ge1xuICAgICAgICB0aGlzLm5nWm9uZS5ydW5PdXRzaWRlQW5ndWxhcigoKSA9PiB7XG4gICAgICAgICAgc2RrLmFwaShwYXRoLCBtZXRob2QsIHBhcmFtcywgcmVzcG9uc2UgPT4ge1xuICAgICAgICAgICAgdGhpcy5uZ1pvbmUucnVuKCgpID0+IHtcbiAgICAgICAgICAgICAgaWYgKHJlc3BvbnNlICYmICFyZXNwb25zZS5lcnJvcikge1xuICAgICAgICAgICAgICAgIHN1YnNjcmliZXIubmV4dChyZXNwb25zZSk7XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgc3Vic2NyaWJlci5lcnJvcihyZXNwb25zZSA/IHJlc3BvbnNlLmVycm9yIDogbnVsbCk7XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICBzdWJzY3JpYmVyLmNvbXBsZXRlKCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIHBhcnNlKGVsZW1lbnQ6IEhUTUxFbGVtZW50KTogT2JzZXJ2YWJsZTxIVE1MRWxlbWVudD4ge1xuICAgIHJldHVybiBPYnNlcnZhYmxlLmNyZWF0ZShzdWJzY3JpYmVyID0+IHtcbiAgICAgIHRoaXMuc2RrLnN1YnNjcmliZShzZGsgPT4ge1xuICAgICAgICB0aGlzLm5nWm9uZS5ydW5PdXRzaWRlQW5ndWxhcigoKSA9PiB7XG4gICAgICAgICAgc2RrLlhGQk1MLnBhcnNlKGVsZW1lbnQsICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMubmdab25lLnJ1bigoKSA9PiB7XG4gICAgICAgICAgICAgIHN1YnNjcmliZXIubmV4dChlbGVtZW50KTtcblxuICAgICAgICAgICAgICBzdWJzY3JpYmVyLmNvbXBsZXRlKCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIHJlbG9hZFJlbmRlcmVkRWxlbWVudHMoKTogT2JzZXJ2YWJsZTxIVE1MRWxlbWVudD4ge1xuICAgIHJldHVybiBPYnNlcnZhYmxlLmNyZWF0ZShzdWJzY3JpYmVyID0+IHtcbiAgICAgIHRoaXMuc2RrLnN1YnNjcmliZShzZGsgPT4ge1xuICAgICAgICBjb25zdCBlbGVtZW50cyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJ1tmYi14ZmJtbC1zdGF0ZT1cInJlbmRlcmVkXCJdJyk7XG5cbiAgICAgICAgbGV0IHByb2Nlc3NpbmcgPSBlbGVtZW50cy5sZW5ndGg7XG5cbiAgICAgICAgQXJyYXkuZnJvbShlbGVtZW50cykuZm9yRWFjaChub2RlID0+IHtcbiAgICAgICAgICB0aGlzLm5nWm9uZS5ydW5PdXRzaWRlQW5ndWxhcigoKSA9PiB7XG4gICAgICAgICAgICBzZGsuWEZCTUwucGFyc2Uobm9kZS5wYXJlbnRFbGVtZW50LCAoKSA9PiB7XG4gICAgICAgICAgICAgIHRoaXMubmdab25lLnJ1bigoKSA9PiB7XG4gICAgICAgICAgICAgICAgLS1wcm9jZXNzaW5nO1xuXG4gICAgICAgICAgICAgICAgc3Vic2NyaWJlci5uZXh0KG5vZGUucGFyZW50RWxlbWVudCk7XG5cbiAgICAgICAgICAgICAgICBpZiAocHJvY2Vzc2luZyA8PSAwKSB7XG4gICAgICAgICAgICAgICAgICBzdWJzY3JpYmVyLmNvbXBsZXRlKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG59XG4iLCJleHBvcnQgZnVuY3Rpb24gb2Zmc2V0KGVsZW1lbnQ6IEhUTUxFbGVtZW50KSB7XG4gIC8vIFN1cHBvcnQ6IElFIDw9MTEgb25seVxuICAvLyBSdW5uaW5nIGdldEJvdW5kaW5nQ2xpZW50UmVjdCBvbiBhXG4gIC8vIGRpc2Nvbm5lY3RlZCBub2RlIGluIElFIHRocm93cyBhbiBlcnJvclxuICBpZiAoIWVsZW1lbnQgfHwgIWVsZW1lbnQuZ2V0Q2xpZW50UmVjdHMoKS5sZW5ndGgpIHtcbiAgICByZXR1cm4ge3RvcDogMCwgbGVmdDogMH07XG4gIH1cblxuICBsZXQgZG9jRWxlbTogSFRNTEVsZW1lbnQsIHJlY3Q6IENsaWVudFJlY3QsIGRvYzogRG9jdW1lbnQ7XG5cbiAgcmVjdCA9IGVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG5cbiAgLy8gTWFrZSBzdXJlIGVsZW1lbnQgaXMgbm90IGhpZGRlbiAoZGlzcGxheTogbm9uZSlcbiAgaWYgKHJlY3Qud2lkdGggfHwgcmVjdC5oZWlnaHQpIHtcbiAgICBkb2MgPSBlbGVtZW50Lm93bmVyRG9jdW1lbnQ7XG4gICAgZG9jRWxlbSA9IGRvYy5kb2N1bWVudEVsZW1lbnQ7XG5cbiAgICByZXR1cm4ge1xuICAgICAgdG9wOiByZWN0LnRvcCArIHdpbmRvdy5wYWdlWU9mZnNldCAtIGRvY0VsZW0uY2xpZW50VG9wLFxuICAgICAgbGVmdDogcmVjdC5sZWZ0ICsgd2luZG93LnBhZ2VYT2Zmc2V0IC0gZG9jRWxlbS5jbGllbnRMZWZ0XG4gICAgfTtcbiAgfVxuXG4gIC8vIFJldHVybiB6ZXJvcyBmb3IgZGlzY29ubmVjdGVkIGFuZCBoaWRkZW4gZWxlbWVudHMgKGdoLTIzMTApXG4gIHJldHVybiByZWN0O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFZpZXdwb3J0U2V0dGluZ3Mge1xuICBjb250YWluZXI/OiBIVE1MRWxlbWVudCB8IFdpbmRvdztcbiAgdGhyZXNob2xkPzogbnVtYmVyO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gYWJvdmVUaGVUb3AoZWxlbWVudDogSFRNTEVsZW1lbnQsIHNldHRpbmdzOiBWaWV3cG9ydFNldHRpbmdzID0ge30pIHtcbiAgaWYgKCFlbGVtZW50KSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgbGV0IGZvbGQ6IG51bWJlcjtcblxuICBjb25zdCBjb250YWluZXIgPSBzZXR0aW5ncy5jb250YWluZXIgfHwgd2luZG93LFxuICAgIHRocmVzaG9sZCA9IHNldHRpbmdzLnRocmVzaG9sZCB8fCAwO1xuXG4gIGlmIChjb250YWluZXIgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCkge1xuICAgIGZvbGQgPSBvZmZzZXQoY29udGFpbmVyKS50b3A7XG4gIH0gZWxzZSB7XG4gICAgZm9sZCA9IHdpbmRvdy5zY3JvbGxZO1xuICB9XG5cbiAgcmV0dXJuIGZvbGQgPj0gKG9mZnNldChlbGVtZW50KS50b3AgKyB0aHJlc2hvbGQgKyBlbGVtZW50Lm9mZnNldEhlaWdodCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiByaWdodE9mRm9sZChlbGVtZW50OiBIVE1MRWxlbWVudCwgc2V0dGluZ3M6IFZpZXdwb3J0U2V0dGluZ3MgPSB7fSkge1xuICBpZiAoIWVsZW1lbnQpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBsZXQgZm9sZDogbnVtYmVyO1xuXG4gIGNvbnN0IGNvbnRhaW5lciA9IHNldHRpbmdzLmNvbnRhaW5lciB8fCB3aW5kb3csXG4gICAgdGhyZXNob2xkID0gc2V0dGluZ3MudGhyZXNob2xkIHx8IDA7XG5cbiAgaWYgKGNvbnRhaW5lciBpbnN0YW5jZW9mIEhUTUxFbGVtZW50KSB7XG4gICAgZm9sZCA9IG9mZnNldChjb250YWluZXIpLmxlZnQgKyBjb250YWluZXIub2Zmc2V0V2lkdGg7XG4gIH0gZWxzZSB7XG4gICAgZm9sZCA9IHdpbmRvdy5pbm5lcldpZHRoICsgd2luZG93LnNjcm9sbFg7XG4gIH1cblxuICByZXR1cm4gZm9sZCA8PSBvZmZzZXQoZWxlbWVudCkubGVmdCAtIHRocmVzaG9sZDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGJlbG93VGhlRm9sZChlbGVtZW50OiBIVE1MRWxlbWVudCwgc2V0dGluZ3M6IFZpZXdwb3J0U2V0dGluZ3MgPSB7fSkge1xuICBpZiAoIWVsZW1lbnQpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBsZXQgZm9sZDogbnVtYmVyO1xuXG4gIGNvbnN0IGNvbnRhaW5lciA9IHNldHRpbmdzLmNvbnRhaW5lciB8fCB3aW5kb3csXG4gICAgdGhyZXNob2xkID0gc2V0dGluZ3MudGhyZXNob2xkIHx8IDA7XG5cbiAgaWYgKGNvbnRhaW5lciBpbnN0YW5jZW9mIEhUTUxFbGVtZW50KSB7XG4gICAgZm9sZCA9IG9mZnNldChjb250YWluZXIpLnRvcCArIGNvbnRhaW5lci5vZmZzZXRIZWlnaHQ7XG4gIH0gZWxzZSB7XG4gICAgZm9sZCA9IHdpbmRvdy5pbm5lckhlaWdodCArIHdpbmRvdy5zY3JvbGxZO1xuICB9XG5cbiAgcmV0dXJuIGZvbGQgPD0gb2Zmc2V0KGVsZW1lbnQpLnRvcCAtIHRocmVzaG9sZDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGxlZnRPZkJlZ2luKGVsZW1lbnQ6IEhUTUxFbGVtZW50LCBzZXR0aW5nczogVmlld3BvcnRTZXR0aW5ncyA9IHt9KSB7XG4gIGlmICghZWxlbWVudCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGxldCBmb2xkOiBudW1iZXI7XG5cbiAgY29uc3QgY29udGFpbmVyID0gc2V0dGluZ3MuY29udGFpbmVyIHx8IHdpbmRvdyxcbiAgICB0aHJlc2hvbGQgPSBzZXR0aW5ncy50aHJlc2hvbGQgfHwgMDtcblxuICBpZiAoY29udGFpbmVyIGluc3RhbmNlb2YgSFRNTEVsZW1lbnQpIHtcbiAgICBmb2xkID0gb2Zmc2V0KGNvbnRhaW5lcikubGVmdDtcbiAgfSBlbHNlIHtcbiAgICBmb2xkID0gd2luZG93LnNjcm9sbFg7XG4gIH1cblxuICByZXR1cm4gZm9sZCA+PSBvZmZzZXQoZWxlbWVudCkubGVmdCArIHRocmVzaG9sZCArIGVsZW1lbnQub2Zmc2V0V2lkdGg7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpblZpZXdwb3J0KGVsZW1lbnQ6IEhUTUxFbGVtZW50LCBzZXR0aW5nczogVmlld3BvcnRTZXR0aW5ncyA9IHt9KSB7XG4gIHJldHVybiAhYmVsb3dUaGVGb2xkKGVsZW1lbnQsIHNldHRpbmdzKVxuICAgICYmICFhYm92ZVRoZVRvcChlbGVtZW50LCBzZXR0aW5ncylcbiAgICAmJiAhbGVmdE9mQmVnaW4oZWxlbWVudCwgc2V0dGluZ3MpXG4gICAgJiYgIXJpZ2h0T2ZGb2xkKGVsZW1lbnQsIHNldHRpbmdzKTtcbn1cbiIsImltcG9ydCB7XG4gIERpcmVjdGl2ZSwgSW5wdXQsIEVsZW1lbnRSZWYsIEFmdGVyVmlld0luaXQsIFJlbmRlcmVyMiwgSW5qZWN0aW9uVG9rZW4sIEluamVjdCwgT3B0aW9uYWwsXG4gIFBMQVRGT1JNX0lELCBPbkRlc3Ryb3lcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBpc1BsYXRmb3JtQnJvd3NlciB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5cbmltcG9ydCB7IGluVmlld3BvcnQgfSBmcm9tICcuL2RvbSc7XG5cbmltcG9ydCB7IEZhY2Vib29rU2VydmljZSB9IGZyb20gJy4vZmFjZWJvb2suc2VydmljZSc7XG5cbmV4cG9ydCBjb25zdCBGQl9QQVJTRV9MQVpZX0xPQUQgPSBuZXcgSW5qZWN0aW9uVG9rZW48c3RyaW5nPignZmJfcGFyc2VfbGF6eV9sb2FkJyk7XG5cbkBEaXJlY3RpdmUoe1xuICBzZWxlY3RvcjogJ1tmYlBhcnNlXScsXG59KVxuZXhwb3J0IGNsYXNzIEZhY2Vib29rUGFyc2VEaXJlY3RpdmUgaW1wbGVtZW50cyBBZnRlclZpZXdJbml0LCBPbkRlc3Ryb3kge1xuICBASW5wdXQoKVxuICBzZXQgbGF6eUxvYWQodGhyZXNob2xkOiBudW1iZXIpIHtcbiAgICB0aGlzLnRocmVzaG9sZCA9IHRocmVzaG9sZDtcbiAgfVxuXG4gIEBJbnB1dCgpXG4gIGNvbnRhaW5lcjogSFRNTEVsZW1lbnQgfCBXaW5kb3c7XG5cbiAgc2Nyb2xsVW5sb2FkOiAoKSA9PiB2b2lkO1xuICByZXNpemVVbmxvYWQ6ICgpID0+IHZvaWQ7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBlbGVtZW50UmVmOiBFbGVtZW50UmVmLFxuICAgIHByaXZhdGUgZmFjZWJvb2s6IEZhY2Vib29rU2VydmljZSxcbiAgICBwcml2YXRlIHJlbmRlcmVyOiBSZW5kZXJlcjIsXG4gICAgQEluamVjdChQTEFURk9STV9JRCkgcHJpdmF0ZSBwbGF0Zm9ybUlkOiBPYmplY3QsXG4gICAgQE9wdGlvbmFsKCkgQEluamVjdChGQl9QQVJTRV9MQVpZX0xPQUQpIHByaXZhdGUgdGhyZXNob2xkOiBudW1iZXIsXG4gICkge1xuICB9XG5cbiAgbmdBZnRlclZpZXdJbml0KCkge1xuICAgIGlmICh0aGlzLnRocmVzaG9sZCA9PT0gbnVsbCkge1xuICAgICAgdGhpcy5sb2FkKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuaW5pdExpc3RlbmVycygpO1xuXG4gICAgICB0aGlzLnRyeUxvYWRpbmcoKTtcbiAgICB9XG4gIH1cblxuICBuZ09uRGVzdHJveSgpIHtcbiAgICB0aGlzLnVubG9hZExpc3RlbmVycygpO1xuICB9XG5cbiAgaW5pdExpc3RlbmVycygpIHtcbiAgICB0aGlzLnNjcm9sbFVubG9hZCA9IHRoaXMucmVuZGVyZXIubGlzdGVuKCd3aW5kb3cnLCAnc2Nyb2xsJywgKCkgPT4ge1xuICAgICAgdGhpcy50cnlMb2FkaW5nKCk7XG4gICAgfSk7XG5cbiAgICB0aGlzLnJlc2l6ZVVubG9hZCA9IHRoaXMucmVuZGVyZXIubGlzdGVuKCd3aW5kb3cnLCAncmVzaXplJywgKCkgPT4ge1xuICAgICAgdGhpcy50cnlMb2FkaW5nKCk7XG4gICAgfSk7XG4gIH1cblxuICB0cnlMb2FkaW5nKCkge1xuICAgIGlmIChcbiAgICAgIGlzUGxhdGZvcm1Ccm93c2VyKHRoaXMucGxhdGZvcm1JZCkgJiYgaW5WaWV3cG9ydCh0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudCwge1xuICAgICAgICB0aHJlc2hvbGQ6IHRoaXMudGhyZXNob2xkLFxuICAgICAgICBjb250YWluZXI6IHRoaXMuY29udGFpbmVyXG4gICAgICB9KVxuICAgICkge1xuICAgICAgdGhpcy5sb2FkKCk7XG5cbiAgICAgIHRoaXMudW5sb2FkTGlzdGVuZXJzKCk7XG4gICAgfVxuICB9XG5cbiAgbG9hZCgpIHtcbiAgICB0aGlzLmZhY2Vib29rLnBhcnNlKHRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50KS5zdWJzY3JpYmUoKTtcbiAgfVxuXG4gIHVubG9hZExpc3RlbmVycygpIHtcbiAgICBpZiAodGhpcy5zY3JvbGxVbmxvYWQpIHtcbiAgICAgIHRoaXMuc2Nyb2xsVW5sb2FkKCk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMucmVzaXplVW5sb2FkKSB7XG4gICAgICB0aGlzLnJlc2l6ZVVubG9hZCgpO1xuICAgIH1cbiAgfVxufVxuIiwiaW1wb3J0IHtcbiAgQ29tcG9uZW50LCBJbnB1dCwgRWxlbWVudFJlZiwgUmVuZGVyZXIyLCBJbmplY3QsIE9wdGlvbmFsLCBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSxcbiAgUExBVEZPUk1fSURcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbmltcG9ydCB7IEZhY2Vib29rU2VydmljZSB9IGZyb20gJy4vZmFjZWJvb2suc2VydmljZSc7XG5cbmltcG9ydCB7IEZhY2Vib29rUGFyc2VEaXJlY3RpdmUsIEZCX1BBUlNFX0xBWllfTE9BRCB9IGZyb20gJy4vcGFyc2UuZGlyZWN0aXZlJztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnZmItbGlrZScsXG4gIHN0eWxlczogW10sXG4gIHRlbXBsYXRlOiBgXG4gICAgPGRpdiBjbGFzcz1cImZiLWxpa2VcIlxuICAgICAgICAgW2F0dHIuZGF0YS1hY3Rpb25dPVwiYWN0aW9uXCJcbiAgICAgICAgIFthdHRyLmRhdGEtY29sb3JzY2hlbWVdPVwiY29sb3JzY2hlbWVcIlxuICAgICAgICAgW2F0dHIuZGF0YS1ocmVmXT1cImhyZWZcIlxuICAgICAgICAgW2F0dHIuZGF0YS1raWQtZGlyZWN0ZWQtc2l0ZV09XCJraWREaXJlY3RlZFNpdGVcIlxuICAgICAgICAgW2F0dHIuZGF0YS1sYXlvdXRdPVwibGF5b3V0XCJcbiAgICAgICAgIFthdHRyLmRhdGEtcmVmXT1cInJlZlwiXG4gICAgICAgICBbYXR0ci5kYXRhLXNoYXJlXT1cInNoYXJlXCJcbiAgICAgICAgIFthdHRyLmRhdGEtc2hvdy1mYWNlc109XCJzaG93RmFjZXNcIlxuICAgICAgICAgW2F0dHIuZGF0YS1zaXplXT1cInNpemVcIlxuICAgICAgICAgW2F0dHIuZGF0YS13aWR0aF09XCJ3aWR0aFwiXG4gICAgPlxuICAgICAgPG5nLWNvbnRlbnQ+PC9uZy1jb250ZW50PlxuICAgIDwvZGl2PlxuICBgLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbn0pXG5leHBvcnQgY2xhc3MgRmFjZWJvb2tMaWtlQ29tcG9uZW50IGV4dGVuZHMgRmFjZWJvb2tQYXJzZURpcmVjdGl2ZSB7XG4gIEBJbnB1dCgpIGFjdGlvbjogJ2xpa2UnIHwgJ3JlY29tbWVuZCcgPSAnbGlrZSc7XG4gIEBJbnB1dCgpIGNvbG9yc2NoZW1lOiAnbGlnaHQnIHwgJ2RhcmsnID0gJ2xpZ2h0JztcbiAgQElucHV0KCkgaHJlZjogc3RyaW5nO1xuICBASW5wdXQoKSBraWREaXJlY3RlZFNpdGUgPSBmYWxzZTtcbiAgQElucHV0KCkgbGF5b3V0OiAnc3RhbmRhcmQnIHwgJ2J1dHRvbl9jb3VudCcgfCAnYnV0dG9uJyB8ICdib3hfY291bnQnID0gJ3N0YW5kYXJkJztcbiAgQElucHV0KCkgcmVmOiBzdHJpbmc7XG4gIEBJbnB1dCgpIHNoYXJlID0gZmFsc2U7XG4gIEBJbnB1dCgpIHNob3dGYWNlcyA9IGZhbHNlO1xuICBASW5wdXQoKSBzaXplOiAnbGFyZ2UnIHwgJ3NtYWxsJyA9ICdzbWFsbCc7XG4gIEBJbnB1dCgpIHdpZHRoOiBudW1iZXI7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgZWxlbWVudFJlZjogRWxlbWVudFJlZixcbiAgICBmYWNlYm9vazogRmFjZWJvb2tTZXJ2aWNlLFxuICAgIHJlbmRlcmVyOiBSZW5kZXJlcjIsXG4gICAgQEluamVjdChQTEFURk9STV9JRCkgcGxhdGZvcm1JZDogT2JqZWN0LFxuICAgIEBPcHRpb25hbCgpIEBJbmplY3QoRkJfUEFSU0VfTEFaWV9MT0FEKSB0aHJlc2hvbGQ6IG51bWJlclxuICApIHtcbiAgICBzdXBlcihlbGVtZW50UmVmLCBmYWNlYm9vaywgcmVuZGVyZXIsIHBsYXRmb3JtSWQsIHRocmVzaG9sZCk7XG4gIH1cbn1cbiIsImltcG9ydCB7XG4gIENvbXBvbmVudCwgSW5wdXQsIEVsZW1lbnRSZWYsIFJlbmRlcmVyMiwgSW5qZWN0LCBPcHRpb25hbCwgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gIFBMQVRGT1JNX0lEXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuXG5pbXBvcnQgeyBGYWNlYm9va1NlcnZpY2UgfSBmcm9tICcuL2ZhY2Vib29rLnNlcnZpY2UnO1xuXG5pbXBvcnQgeyBGYWNlYm9va1BhcnNlRGlyZWN0aXZlLCBGQl9QQVJTRV9MQVpZX0xPQUQgfSBmcm9tICcuL3BhcnNlLmRpcmVjdGl2ZSc7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2ZiLXBhZ2UnLFxuICBzdHlsZXM6IFtdLFxuICB0ZW1wbGF0ZTogYFxuICAgIDxkaXYgY2xhc3M9XCJmYi1wYWdlXCJcbiAgICAgICAgIFthdHRyLmRhdGEtaHJlZl09XCJocmVmXCJcbiAgICAgICAgIFthdHRyLmRhdGEtd2lkdGhdPVwid2lkdGhcIlxuICAgICAgICAgW2F0dHIuZGF0YS1oZWlnaHRdPVwiaGVpZ2h0XCJcbiAgICAgICAgIFthdHRyLmRhdGEtdGFic109XCJ0YWJzXCJcbiAgICAgICAgIFthdHRyLmRhdGEtaGlkZS1jb3Zlcl09XCJoaWRlQ292ZXJcIlxuICAgICAgICAgW2F0dHIuZGF0YS1zaG93LWZhY2VwaWxlXT1cInNob3dGYWNlcGlsZVwiXG4gICAgICAgICBbYXR0ci5kYXRhLWhpZGUtY3RhXT1cImhpZGVDdGFcIlxuICAgICAgICAgW2F0dHIuZGF0YS1zbWFsbC1oZWFkZXJdPVwic21hbGxIZWFkZXJcIlxuICAgICAgICAgW2F0dHIuZGF0YS1hZGFwdC1jb250YWluZXItd2lkdGhdPVwiYWRhcHRDb250YWluZXJXaWR0aFwiXG4gICAgPlxuICAgICAgPGJsb2NrcXVvdGUgW2F0dHIuY2l0ZV09XCJocmVmXCIgY2xhc3M9XCJmYi14ZmJtbC1wYXJzZS1pZ25vcmVcIj5cbiAgICAgICAgPGEgW2hyZWZdPVwiaHJlZlwiPlxuICAgICAgICAgIDxuZy1jb250ZW50PjwvbmctY29udGVudD5cbiAgICAgICAgPC9hPlxuICAgICAgPC9ibG9ja3F1b3RlPlxuICAgIDwvZGl2PlxuICBgLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbn0pXG5leHBvcnQgY2xhc3MgRmFjZWJvb2tQYWdlQ29tcG9uZW50IGV4dGVuZHMgRmFjZWJvb2tQYXJzZURpcmVjdGl2ZSB7XG4gIEBJbnB1dCgpIGhyZWY6IHN0cmluZztcbiAgQElucHV0KCkgd2lkdGggPSAzNDA7XG4gIEBJbnB1dCgpIGhlaWdodCA9IDUwMDtcbiAgQElucHV0KCkgdGFicyA9ICd0aW1lbGluZSc7XG4gIEBJbnB1dCgpIGhpZGVDb3ZlciA9IGZhbHNlO1xuICBASW5wdXQoKSBzaG93RmFjZXBpbGUgPSB0cnVlO1xuICBASW5wdXQoKSBoaWRlQ3RhID0gZmFsc2U7XG4gIEBJbnB1dCgpIHNtYWxsSGVhZGVyID0gZmFsc2U7XG4gIEBJbnB1dCgpIGFkYXB0Q29udGFpbmVyV2lkdGggPSB0cnVlO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIGVsZW1lbnRSZWY6IEVsZW1lbnRSZWYsXG4gICAgZmFjZWJvb2s6IEZhY2Vib29rU2VydmljZSxcbiAgICByZW5kZXJlcjogUmVuZGVyZXIyLFxuICAgIEBJbmplY3QoUExBVEZPUk1fSUQpIHBsYXRmb3JtSWQ6IE9iamVjdCxcbiAgICBAT3B0aW9uYWwoKSBASW5qZWN0KEZCX1BBUlNFX0xBWllfTE9BRCkgdGhyZXNob2xkOiBudW1iZXJcbiAgKSB7XG4gICAgc3VwZXIoZWxlbWVudFJlZiwgZmFjZWJvb2ssIHJlbmRlcmVyLCBwbGF0Zm9ybUlkLCB0aHJlc2hvbGQpO1xuICB9XG59XG4iLCJpbXBvcnQgeyBOZ01vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcblxuaW1wb3J0IHsgRmFjZWJvb2tQYXJzZURpcmVjdGl2ZSB9IGZyb20gJy4vcGFyc2UuZGlyZWN0aXZlJztcbmltcG9ydCB7IEZhY2Vib29rUGFnZUNvbXBvbmVudCB9IGZyb20gJy4vcGFnZS5jb21wb25lbnQnO1xuaW1wb3J0IHsgRmFjZWJvb2tMaWtlQ29tcG9uZW50IH0gZnJvbSAnLi9saWtlLmNvbXBvbmVudCc7XG5cbkBOZ01vZHVsZSh7XG4gIGltcG9ydHM6IFtcbiAgICBDb21tb25Nb2R1bGUsXG4gIF0sXG4gIGRlY2xhcmF0aW9uczogW1xuICAgIEZhY2Vib29rUGFyc2VEaXJlY3RpdmUsXG4gICAgRmFjZWJvb2tQYWdlQ29tcG9uZW50LFxuICAgIEZhY2Vib29rTGlrZUNvbXBvbmVudCxcbiAgXSxcbiAgZXhwb3J0czogW1xuICAgIEZhY2Vib29rUGFyc2VEaXJlY3RpdmUsXG4gICAgRmFjZWJvb2tQYWdlQ29tcG9uZW50LFxuICAgIEZhY2Vib29rTGlrZUNvbXBvbmVudCxcbiAgXSxcbn0pXG5leHBvcnQgY2xhc3MgRmFjZWJvb2tNb2R1bGUgeyB9XG4iXSwibmFtZXMiOlsidHNsaWJfMS5fX2V4dGVu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