@greg-md/ng-facebook
Version:
Using Facebook SDK with Angular.
577 lines (567 loc) • 50.4 kB
JavaScript
import { Inject, Injectable, NgZone, PLATFORM_ID, Component, Input, ElementRef, Renderer2, Optional, ChangeDetectionStrategy, NgModule, Directive, InjectionToken, defineInjectable, inject } from '@angular/core';
import { isPlatformServer, isPlatformBrowser, CommonModule } from '@angular/common';
import { Observable, ReplaySubject } from 'rxjs';
import { tap, map } from 'rxjs/operators';
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
const /** @type {?} */ FACEBOOK_DEFAULTS = {
xfbml: false,
version: 'v3.0'
};
class FacebookService {
/**
* @param {?} ngZone
* @param {?} platformId
*/
constructor(ngZone, platformId) {
this.ngZone = ngZone;
this.platformId = platformId;
this.sdk = new ReplaySubject(1);
}
/**
* @param {?=} locale
* @return {?}
*/
load(locale = 'en_US') {
return Observable.create(subscriber => {
if (isPlatformServer(this.platformId)) {
return;
}
this.ngZone.runOutsideAngular(() => {
delete window.FB;
let /** @type {?} */ jsSdk, /** @type {?} */ fbRoot;
if (jsSdk = document.getElementById('facebook-jssdk')) {
jsSdk.parentNode.removeChild(jsSdk);
}
if (fbRoot = document.getElementById('fb-root')) {
fbRoot.parentNode.removeChild(fbRoot);
}
const /** @type {?} */ script = document.createElement('script');
script.id = 'facebook-jssdk';
script.src = '//connect.facebook.net/' + (locale || 'en_US') + '/sdk.js';
script.onload = () => {
this.ngZone.run(() => {
subscriber.next(FB);
subscriber.complete();
});
};
script.onerror = () => {
this.ngZone.run(() => {
subscriber.error('Facebook SDK could not be loaded.');
subscriber.complete();
});
};
document.head.appendChild(script);
});
}).pipe(map((sdk) => {
this.sdk.next(sdk);
return sdk;
}));
}
/**
* @param {?=} params
* @param {?=} locale
* @return {?}
*/
init(params = {}, locale = 'en_US') {
return this.load(locale).pipe(tap(sdk => {
params = Object.assign({}, FACEBOOK_DEFAULTS, params);
sdk.init(params);
this.reloadRenderedElements().subscribe();
}));
}
/**
* @param {?=} options
* @return {?}
*/
login(options) {
return Observable.create(subscriber => {
this.sdk.subscribe(sdk => {
this.ngZone.runOutsideAngular(() => {
sdk.login(response => {
this.ngZone.run(() => {
if (response.authResponse) {
subscriber.next(response.authResponse);
}
else {
subscriber.error(response);
}
subscriber.complete();
});
}, options);
});
});
});
}
/**
* @param {?} path
* @param {?=} method
* @param {?=} params
* @return {?}
*/
api(path, method, params) {
return Observable.create(subscriber => {
this.sdk.subscribe(sdk => {
this.ngZone.runOutsideAngular(() => {
sdk.api(path, method, params, response => {
this.ngZone.run(() => {
if (response && !response.error) {
subscriber.next(response);
}
else {
subscriber.error(response ? response.error : null);
}
subscriber.complete();
});
});
});
});
});
}
/**
* @param {?} element
* @return {?}
*/
parse(element) {
return Observable.create(subscriber => {
this.sdk.subscribe(sdk => {
this.ngZone.runOutsideAngular(() => {
sdk.XFBML.parse(element, () => {
this.ngZone.run(() => {
subscriber.next(element);
subscriber.complete();
});
});
});
});
});
}
/**
* @return {?}
*/
reloadRenderedElements() {
return Observable.create(subscriber => {
this.sdk.subscribe(sdk => {
const /** @type {?} */ elements = document.querySelectorAll('[fb-xfbml-state="rendered"]');
let /** @type {?} */ processing = elements.length;
Array.from(elements).forEach(node => {
this.ngZone.runOutsideAngular(() => {
sdk.XFBML.parse(node.parentElement, () => {
this.ngZone.run(() => {
--processing;
subscriber.next(node.parentElement);
if (processing <= 0) {
subscriber.complete();
}
});
});
});
});
});
});
}
}
FacebookService.decorators = [
{ type: Injectable, args: [{
providedIn: 'root'
},] },
];
/** @nocollapse */
FacebookService.ctorParameters = () => [
{ 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" });
/**
* @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 };
}
let /** @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 (!element) {
return false;
}
let /** @type {?} */ fold;
const /** @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 (!element) {
return false;
}
let /** @type {?} */ fold;
const /** @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 (!element) {
return false;
}
let /** @type {?} */ fold;
const /** @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 (!element) {
return false;
}
let /** @type {?} */ fold;
const /** @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 = {}) {
return !belowTheFold(element, settings)
&& !aboveTheTop(element, settings)
&& !leftOfBegin(element, settings)
&& !rightOfFold(element, settings);
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
const /** @type {?} */ FB_PARSE_LAZY_LOAD = new InjectionToken('fb_parse_lazy_load');
class FacebookParseDirective {
/**
* @param {?} elementRef
* @param {?} facebook
* @param {?} renderer
* @param {?} platformId
* @param {?} threshold
*/
constructor(elementRef, facebook, renderer, platformId, threshold) {
this.elementRef = elementRef;
this.facebook = facebook;
this.renderer = renderer;
this.platformId = platformId;
this.threshold = threshold;
}
/**
* @param {?} threshold
* @return {?}
*/
set lazyLoad(threshold) {
this.threshold = threshold;
}
/**
* @return {?}
*/
ngAfterViewInit() {
if (this.threshold === null) {
this.load();
}
else {
this.initListeners();
this.tryLoading();
}
}
/**
* @return {?}
*/
ngOnDestroy() {
this.unloadListeners();
}
/**
* @return {?}
*/
initListeners() {
this.scrollUnload = this.renderer.listen('window', 'scroll', () => {
this.tryLoading();
});
this.resizeUnload = this.renderer.listen('window', 'resize', () => {
this.tryLoading();
});
}
/**
* @return {?}
*/
tryLoading() {
if (isPlatformBrowser(this.platformId) && inViewport(this.elementRef.nativeElement, {
threshold: this.threshold,
container: this.container
})) {
this.load();
this.unloadListeners();
}
}
/**
* @return {?}
*/
load() {
this.facebook.parse(this.elementRef.nativeElement).subscribe();
}
/**
* @return {?}
*/
unloadListeners() {
if (this.scrollUnload) {
this.scrollUnload();
}
if (this.resizeUnload) {
this.resizeUnload();
}
}
}
FacebookParseDirective.decorators = [
{ type: Directive, args: [{
selector: '[fbParse]',
},] },
];
/** @nocollapse */
FacebookParseDirective.ctorParameters = () => [
{ 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 },],
};
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
class FacebookLikeComponent extends FacebookParseDirective {
/**
* @param {?} elementRef
* @param {?} facebook
* @param {?} renderer
* @param {?} platformId
* @param {?} threshold
*/
constructor(elementRef, facebook, renderer, platformId, threshold) {
super(elementRef, facebook, renderer, platformId, threshold);
this.action = 'like';
this.colorscheme = 'light';
this.kidDirectedSite = false;
this.layout = 'standard';
this.share = false;
this.showFaces = false;
this.size = 'small';
}
}
FacebookLikeComponent.decorators = [
{ type: Component, args: [{
selector: 'fb-like',
styles: [],
template: `
<div class="fb-like"
[attr.data-action]="action"
[attr.data-colorscheme]="colorscheme"
[attr.data-href]="href"
[attr.data-kid-directed-site]="kidDirectedSite"
[attr.data-layout]="layout"
[attr.data-ref]="ref"
[attr.data-share]="share"
[attr.data-show-faces]="showFaces"
[attr.data-size]="size"
[attr.data-width]="width"
>
<ng-content></ng-content>
</div>
`,
changeDetection: ChangeDetectionStrategy.OnPush,
},] },
];
/** @nocollapse */
FacebookLikeComponent.ctorParameters = () => [
{ 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 },],
};
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
class FacebookPageComponent extends FacebookParseDirective {
/**
* @param {?} elementRef
* @param {?} facebook
* @param {?} renderer
* @param {?} platformId
* @param {?} threshold
*/
constructor(elementRef, facebook, renderer, platformId, threshold) {
super(elementRef, facebook, renderer, platformId, threshold);
this.width = 340;
this.height = 500;
this.tabs = 'timeline';
this.hideCover = false;
this.showFacepile = true;
this.hideCta = false;
this.smallHeader = false;
this.adaptContainerWidth = true;
}
}
FacebookPageComponent.decorators = [
{ type: Component, args: [{
selector: 'fb-page',
styles: [],
template: `
<div class="fb-page"
[attr.data-href]="href"
[attr.data-width]="width"
[attr.data-height]="height"
[attr.data-tabs]="tabs"
[attr.data-hide-cover]="hideCover"
[attr.data-show-facepile]="showFacepile"
[attr.data-hide-cta]="hideCta"
[attr.data-small-header]="smallHeader"
[attr.data-adapt-container-width]="adaptContainerWidth"
>
<blockquote [attr.cite]="href" class="fb-xfbml-parse-ignore">
<a [href]="href">
<ng-content></ng-content>
</a>
</blockquote>
</div>
`,
changeDetection: ChangeDetectionStrategy.OnPush,
},] },
];
/** @nocollapse */
FacebookPageComponent.ctorParameters = () => [
{ 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 },],
};
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
class FacebookModule {
}
FacebookModule.decorators = [
{ type: NgModule, args: [{
imports: [
CommonModule,
],
declarations: [
FacebookParseDirective,
FacebookPageComponent,
FacebookLikeComponent,
],
exports: [
FacebookParseDirective,
FacebookPageComponent,
FacebookLikeComponent,
],
},] },
];
/**
* @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+PC9uZy1jb250ZW50PlxuICAgIDwvZGl2PlxuICBgLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbn0pXG5leHBvcnQgY2xhc3MgRmFjZWJvb2tMaWtlQ29tcG9uZW50IGV4dGVuZHMgRmFjZWJvb2tQYXJzZURpcmVjdGl2ZSB7XG4gIEBJbnB1dCgpIGFjdGlvbjogJ2xpa2UnIHwgJ3JlY29tbWVuZCcgPSAnbGlrZSc7XG4gIEBJbnB1dCgpIGNvbG9yc2NoZW1lOiAnbGlnaHQnIHwgJ2RhcmsnID0gJ2xpZ2h0JztcbiAgQElucHV0KCkgaHJlZjogc3RyaW5nO1xuICBASW5wdXQoKSBraWREaXJlY3RlZFNpdGUgPSBmYWxzZTtcbiAgQElucHV0KCkgbGF5b3V0OiAnc3RhbmRhcmQnIHwgJ2J1dHRvbl9jb3VudCcgfCAnYnV0dG9uJyB8ICdib3hfY291bnQnID0gJ3N0YW5kYXJkJztcbiAgQElucHV0KCkgcmVmOiBzdHJpbmc7XG4gIEBJbnB1dCgpIHNoYXJlID0gZmFsc2U7XG4gIEBJbnB1dCgpIHNob3dGYWNlcyA9IGZhbHNlO1xuICBASW5wdXQoKSBzaXplOiAnbGFyZ2UnIHwgJ3NtYWxsJyA9ICdzbWFsbCc7XG4gIEBJbnB1dCgpIHdpZHRoOiBudW1iZXI7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgZWxlbWVudFJlZjogRWxlbWVudFJlZixcbiAgICBmYWNlYm9vazogRmFjZWJvb2tTZXJ2aWNlLFxuICAgIHJlbmRlcmVyOiBSZW5kZXJlcjIsXG4gICAgQEluamVjdChQTEFURk9STV9JRCkgcGxhdGZvcm1JZDogT2JqZWN0LFxuICAgIEBPcHRpb25hbCgpIEBJbmplY3QoRkJfUEFSU0VfTEFaWV9MT0FEKSB0aHJlc2hvbGQ6IG51bWJlclxuICApIHtcbiAgICBzdXBlcihlbGVtZW50UmVmLCBmYWNlYm9vaywgcmVuZGVyZXIsIHBsYXRmb3JtSWQsIHRocmVzaG9sZCk7XG4gIH1cbn1cbiIsImltcG9ydCB7XG4gIENvbXBvbmVudCwgSW5wdXQsIEVsZW1lbnRSZWYsIFJlbmRlcmVyMiwgSW5qZWN0LCBPcHRpb25hbCwgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gIFBMQVRGT1JNX0lEXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuXG5pbXBvcnQgeyBGYWNlYm9va1NlcnZpY2UgfSBmcm9tICcuL2ZhY2Vib29rLnNlcnZpY2UnO1xuXG5pbXBvcnQgeyBGYWNlYm9va1BhcnNlRGlyZWN0aXZlLCBGQl9QQVJTRV9MQVpZX0xPQUQgfSBmcm9tICcuL3BhcnNlLmRpcmVjdGl2ZSc7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2ZiLXBhZ2UnLFxuICBzdHlsZXM6IFtdLFxuICB0ZW1wbGF0ZTogYFxuICAgIDxkaXYgY2xhc3M9XCJmYi1wYWdlXCJcbiAgICAgICAgIFthdHRyLmRhdGEtaHJlZl09XCJocmVmXCJcbiAgICAgICAgIFthdHRyLmRhdGEtd2lkdGhdPVwid2lkdGhcIlxuICAgICAgICAgW2F0dHIuZGF0YS1oZWlnaHRdPVwiaGVpZ2h0XCJcbiAgICAgICAgIFthdHRyLmRhdGEtdGFic109XCJ0YWJzXCJcbiAgICAgICAgIFthdHRyLmRhdGEtaGlkZS1jb3Zlcl09XCJoaWRlQ292ZXJcIlxuICAgICAgICAgW2F0dHIuZGF0YS1zaG93LWZhY2VwaWxlXT1cInNob3dGYWNlcGlsZVwiXG4gICAgICAgICBbYXR0ci5kYXRhLWhpZGUtY3RhXT1cImhpZGVDdGFcIlxuICAgICAgICAgW2F0dHIuZGF0YS1zbWFsbC1oZWFkZXJdPVwic21hbGxIZWFkZXJcIlxuICAgICAgICAgW2F0dHIuZGF0YS1hZGFwdC1jb250YWluZXItd2lkdGhdPVwiYWRhcHRDb250YWluZXJXaWR0aFwiXG4gICAgPlxuICAgICAgPGJsb2NrcXVvdGUgW2F0dHIuY2l0ZV09XCJocmVmXCIgY2xhc3M9XCJmYi14ZmJtbC1wYXJzZS1pZ25vcmVcIj5cbiAgICAgICAgPGEgW2hyZWZdPVwiaHJlZlwiPlxuICAgICAgICAgIDxuZy1jb250ZW50PjwvbmctY29udGVudD5cbiAgICAgICAgPC9hPlxuICAgICAgPC9ibG9ja3F1b3RlPlxuICAgIDwvZGl2PlxuICBgLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbn0pXG5leHBvcnQgY2xhc3MgRmFjZWJvb2tQYWdlQ29tcG9uZW50IGV4dGVuZHMgRmFjZWJvb2tQYXJzZURpcmVjdGl2ZSB7XG4gIEBJbnB1dCgpIGhyZWY6IHN0cmluZztcbiAgQElucHV0KCkgd2lkdGggPSAzNDA7XG4gIEBJbnB1dCgpIGhlaWdodCA9IDUwMDtcbiAgQElucHV0KCkgdGFicyA9ICd0aW1lbGluZSc7XG4gIEBJbnB1dCgpIGhpZGVDb3ZlciA9IGZhbHNlO1xuICBASW5wdXQoKSBzaG93RmFjZXBpbGUgPSB0cnVlO1xuICBASW5wdXQoKSBoaWRlQ3RhID0gZmFsc2U7XG4gIEBJbnB1dCgpIHNtYWxsSGVhZGVyID0gZmFsc2U7XG4gIEBJbnB1dCgpIGFkYXB0Q29udGFpbmVyV2lkdGggPSB0cnVlO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIGVsZW1lbnRSZWY6IEVsZW1lbnRSZWYsXG4gICAgZmFjZWJvb2s6IEZhY2Vib29rU2VydmljZSxcbiAgICByZW5kZXJlcjogUmVuZGVyZXIyLFxuICAgIEBJbmplY3QoUExBVEZPUk1fSUQpIHBsYXRmb3JtSWQ6IE9iamVjdCxcbiAgICBAT3B0aW9uYWwoKSBASW5qZWN0KEZCX1BBUlNFX0xBWllfTE9BRCkgdGhyZXNob2xkOiBudW1iZXJcbiAgKSB7XG4gICAgc3VwZXIoZWxlbWVudFJlZiwgZmFjZWJvb2ssIHJlbmRlcmVyLCBwbGF0Zm9ybUlkLCB0aHJlc2hvbGQpO1xuICB9XG59XG4iLCJpbXBvcnQgeyBOZ01vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcblxuaW1wb3J0IHsgRmFjZWJvb2tQYXJzZURpcmVjdGl2ZSB9IGZyb20gJy4vcGFyc2UuZGlyZWN0aXZlJztcbmltcG9ydCB7IEZhY2Vib29rUGFnZUNvbXBvbmVudCB9IGZyb20gJy4vcGFnZS5jb21wb25lbnQnO1xuaW1wb3J0IHsgRmFjZWJvb2tMaWtlQ29tcG9uZW50IH0gZnJvbSAnLi9saWtlLmNvbXBvbmVudCc7XG5cbkBOZ01vZHVsZSh7XG4gIGltcG9ydHM6IFtcbiAgICBDb21tb25Nb2R1bGUsXG4gIF0sXG4gIGRlY2xhcmF0aW9uczogW1xuICAgIEZhY2Vib29rUGFyc2VEaXJlY3RpdmUsXG4gICAgRmFjZWJvb2tQYWdlQ29tcG9uZW50LFxuICAgIEZhY2Vib29rTGlrZUNvbXBvbmVudCxcbiAgXSxcbiAgZXhwb3J0czogW1xuICAgIEZhY2Vib29rUGFyc2VEaXJlY3RpdmUsXG4gICAgRmFjZWJvb2tQYWdlQ29tcG9uZW50LFxuICAgIEZhY2Vib29rTGlrZUNvbXBvbmVudCxcbiAgXSxcbn0pXG5leHBvcnQgY2xhc3MgRmFjZWJvb2tNb2R1bGUgeyB9XG4iXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7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