@schoolbelle/common
Version:
Demo library to showcase Angular packaging format
501 lines (489 loc) • 56.2 kB
JavaScript
import { Injectable, Optional, Component, ViewEncapsulation, NgModule, ApplicationRef, Injector, ComponentFactoryResolver } from '@angular/core';
import { Subscription } from 'rxjs/Subscription';
import { trigger, style, transition, animate } from '@angular/animations';
import { CommonModule } from '@angular/common';
import { Subject } from 'rxjs/Subject';
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
/**
* @file Busy Config
* @author yumao<yuzhang.lille@gmail.com>
*/
class BusyConfig {
/**
* @param {?=} config
*/
constructor(config = {}) {
for (let /** @type {?} */ option in BUSY_CONFIG_DEFAULTS) {
this[option] =
config[option] != null ? config[option] : BUSY_CONFIG_DEFAULTS[option];
}
}
}
const /** @type {?} */ BUSY_CONFIG_DEFAULTS = {
template: `
<div class="ng-busy-default-wrapper">
<div class="ng-busy-default-sign">
<div class="ng-busy-default-spinner">
<div class="bar1"></div>
<div class="bar2"></div>
<div class="bar3"></div>
<div class="bar4"></div>
<div class="bar5"></div>
<div class="bar6"></div>
<div class="bar7"></div>
<div class="bar8"></div>
<div class="bar9"></div>
<div class="bar10"></div>
<div class="bar11"></div>
<div class="bar12"></div>
</div>
<div class="ng-busy-default-text">{{message}}</div>
</div>
</div>
`,
delay: 0,
minDuration: 0,
backdrop: true,
message: 'Please wait...',
wrapperClass: 'ng-busy'
};
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
class BusyService {
/**
* @param {?} config
*/
constructor(config) {
this.config = config || new BusyConfig();
}
}
BusyService.decorators = [
{ type: Injectable },
];
/** @nocollapse */
BusyService.ctorParameters = () => [
{ type: BusyConfig, decorators: [{ type: Optional },] },
];
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
class PromiseTrackerService {
constructor() {
this.promiseList = [];
this.delayJustFinished = false;
}
/**
* @param {?} options
* @return {?}
*/
reset(options) {
this.minDuration = options.minDuration;
this.promiseList = [];
options.promiseList.forEach(promise => {
if (!promise || promise['busyFulfilled']) {
return;
}
this.addPromise(promise);
});
if (this.promiseList.length === 0) {
return;
}
this.delayJustFinished = false;
if (options.delay) {
this.delayPromise = setTimeout(() => {
this.delayPromise = null;
this.delayJustFinished = true;
}, options.delay);
}
if (options.minDuration) {
this.durationPromise = setTimeout(() => {
this.durationPromise = null;
}, options.minDuration + (options.delay || 0));
}
}
/**
* @param {?} promise
* @return {?}
*/
addPromise(promise) {
if (this.promiseList.indexOf(promise) !== -1) {
return;
}
this.promiseList.push(promise);
if (promise instanceof Promise) {
promise.then.call(promise, () => this.finishPromise(promise), () => this.finishPromise(promise));
}
else if (promise instanceof Subscription) {
promise.add(() => this.finishPromise(promise));
}
}
/**
* @param {?} promise
* @return {?}
*/
finishPromise(promise) {
promise['busyFulfilled'] = true;
const /** @type {?} */ index = this.promiseList.indexOf(promise);
if (index === -1) {
return;
}
this.promiseList.splice(index, 1);
}
/**
* @return {?}
*/
isActive() {
if (this.delayPromise) {
return false;
}
if (!this.delayJustFinished) {
if (this.durationPromise) {
return true;
}
return this.promiseList.length > 0;
}
this.delayJustFinished = false;
if (this.promiseList.length === 0) {
this.durationPromise = null;
}
return this.promiseList.length > 0;
}
}
PromiseTrackerService.decorators = [
{ type: Injectable },
];
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
const /** @type {?} */ inactiveStyle = style({
opacity: 0
});
const /** @type {?} */ timing = '.3s ease';
class BusyBackdropComponent {
/**
* @param {?} tracker
*/
constructor(tracker) {
this.tracker = tracker;
}
/**
* @return {?}
*/
isActive() {
return this.tracker.isActive();
}
}
BusyBackdropComponent.decorators = [
{ type: Component, args: [{
selector: 'ng-busy-backdrop',
template: `
<div class="ng-busy-backdrop"
@fadeInOut
*ngIf="isActive()">
</div>
`,
animations: [
trigger('fadeInOut', [
transition('void => *', [inactiveStyle, animate(timing)]),
transition('* => void', [animate(timing, inactiveStyle)])
])
]
},] },
];
/** @nocollapse */
BusyBackdropComponent.ctorParameters = () => [
{ type: PromiseTrackerService, },
];
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
//import { CustomCompiler } from './busy.compiler';
const /** @type {?} */ inactiveStyle$1 = style({
opacity: 0,
transform: 'translateY(-40px)'
});
const /** @type {?} */ timing$1 = '.3s ease';
class BusyComponent {
/**
* @param {?} tracker
*/
constructor(tracker // private compiler: CustomCompiler
) {
this.tracker = tracker;
}
/**
* @return {?}
*/
ngDoCheck() {
if (this.message === this.lastMessage) {
return;
}
this.lastMessage = this.message;
// this.clearDynamicTemplateCache();
// this.createDynamicTemplate();
}
/**
* @return {?}
*/
ngOnDestroy() {
// this.clearDynamicTemplateCache();
}
/**
* @return {?}
*/
isActive() {
return this.tracker.isActive();
}
}
BusyComponent.decorators = [
{ type: Component, args: [{
selector: 'ng-busy',
// template: `
// <div [class]="wrapperClass" *ngIf="isActive()" @flyInOut>
// <ng-container *ngComponentOutlet="TemplateComponent; ngModuleFactory: nmf;"></ng-container>
// </div>
// `,
template: `
<div [class]="wrapperClass" *ngIf="isActive()" @flyInOut>
<div class="ng-busy-default-wrapper">
<div class="ng-busy-default-sign">
<div class="ng-busy-default-spinner">
<div class="bar1"></div>
<div class="bar2"></div>
<div class="bar3"></div>
<div class="bar4"></div>
<div class="bar5"></div>
<div class="bar6"></div>
<div class="bar7"></div>
<div class="bar8"></div>
<div class="bar9"></div>
<div class="bar10"></div>
<div class="bar11"></div>
<div class="bar12"></div>
</div>
<div class="ng-busy-default-text">{{message}}</div>
</div>
</div>
</div>
`,
styles: [`.ng-busy{z-index:2002}.ng-busy,.ng-busy>*,.ng-busy>ng-component>*{position:absolute;top:0;left:0;right:0;bottom:0}.ng-busy-backdrop{position:fixed;top:0;left:0;right:0;bottom:0;z-index:1001;background:#fff;opacity:.7}.ng-busy-default-wrapper{text-align:center}.ng-busy-default-sign{position:fixed;top:50%;left:50%;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);display:inline-block;z-index:1003;padding:12px 14px;border:1px solid #d8d8d8;border-top:0;border-radius:0 0 4px 4px;box-shadow:0 1px 2px rgba(0,0,0,.05);background:#f8f8f8;color:#333;width:-webkit-max-content;width:-moz-max-content;width:max-content}.ng-busy-default-text{display:inline-block;margin-left:6px;max-width:400px;font-size:14px;text-align:left}.ng-busy-default-spinner{position:relative;display:inline-block;width:25px;height:25px;vertical-align:middle}.ng-busy-default-spinner div{position:absolute;left:44.5%;top:37%;width:10%;height:26%;background:#666;border-radius:50px;box-shadow:0 0 3px rgba(0,0,0,.2);opacity:0;-webkit-animation:1s linear infinite busy-spinner-anim;animation:1s linear infinite busy-spinner-anim}.ng-busy-default-spinner .bar1{-webkit-transform:rotate(0) translate(0,-142%);transform:rotate(0) translate(0,-142%);-webkit-animation-delay:-1s;animation-delay:-1s}.ng-busy-default-spinner .bar2{-webkit-transform:rotate(30deg) translate(0,-142%);transform:rotate(30deg) translate(0,-142%);-webkit-animation-delay:-.91666667s;animation-delay:-.91666667s}.ng-busy-default-spinner .bar3{-webkit-transform:rotate(60deg) translate(0,-142%);transform:rotate(60deg) translate(0,-142%);-webkit-animation-delay:-.83333333s;animation-delay:-.83333333s}.ng-busy-default-spinner .bar4{-webkit-transform:rotate(90deg) translate(0,-142%);transform:rotate(90deg) translate(0,-142%);-webkit-animation-delay:-.75s;animation-delay:-.75s}.ng-busy-default-spinner .bar5{-webkit-transform:rotate(120deg) translate(0,-142%);transform:rotate(120deg) translate(0,-142%);-webkit-animation-delay:-.66666667s;animation-delay:-.66666667s}.ng-busy-default-spinner .bar6{-webkit-transform:rotate(150deg) translate(0,-142%);transform:rotate(150deg) translate(0,-142%);-webkit-animation-delay:-.58333333s;animation-delay:-.58333333s}.ng-busy-default-spinner .bar7{-webkit-transform:rotate(180deg) translate(0,-142%);transform:rotate(180deg) translate(0,-142%);-webkit-animation-delay:-.5s;animation-delay:-.5s}.ng-busy-default-spinner .bar8{-webkit-transform:rotate(210deg) translate(0,-142%);transform:rotate(210deg) translate(0,-142%);-webkit-animation-delay:-.41666667s;animation-delay:-.41666667s}.ng-busy-default-spinner .bar9{-webkit-transform:rotate(240deg) translate(0,-142%);transform:rotate(240deg) translate(0,-142%);-webkit-animation-delay:-.33333333s;animation-delay:-.33333333s}.ng-busy-default-spinner .bar10{-webkit-transform:rotate(270deg) translate(0,-142%);transform:rotate(270deg) translate(0,-142%);-webkit-animation-delay:-.25s;animation-delay:-.25s}.ng-busy-default-spinner .bar11{-webkit-transform:rotate(300deg) translate(0,-142%);transform:rotate(300deg) translate(0,-142%);-webkit-animation-delay:-.16666667s;animation-delay:-.16666667s}.ng-busy-default-spinner .bar12{-webkit-transform:rotate(330deg) translate(0,-142%);transform:rotate(330deg) translate(0,-142%);-webkit-animation-delay:-83.33333ms;animation-delay:-83.33333ms}@-webkit-keyframes busy-spinner-anim{from{opacity:1}to{opacity:.25}}@keyframes busy-spinner-anim{from{opacity:1}to{opacity:.25}}`],
animations: [
trigger('flyInOut', [
transition('void => *', [inactiveStyle$1, animate(timing$1)]),
transition('* => void', [animate(timing$1, inactiveStyle$1)])
])
],
encapsulation: ViewEncapsulation.None
},] },
];
/** @nocollapse */
BusyComponent.ctorParameters = () => [
{ type: PromiseTrackerService, },
];
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
class BusyModule {
/**
* @param {?} config
* @return {?}
*/
static forRoot(config) {
return {
ngModule: BusyModule,
providers: [{ provide: BusyConfig, useValue: config }]
};
}
}
BusyModule.decorators = [
{ type: NgModule, args: [{
imports: [CommonModule],
declarations: [BusyComponent, BusyBackdropComponent],
providers: [
BusyService,
PromiseTrackerService
],
entryComponents: [BusyComponent, BusyBackdropComponent]
},] },
];
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
class LoadingService {
/**
* @param {?} _applicationRef
* @param {?} _injector
* @param {?} _componentFactoryResolver
* @param {?} tracker
*/
constructor(_applicationRef, _injector, _componentFactoryResolver, tracker) {
this._applicationRef = _applicationRef;
this._injector = _injector;
this._componentFactoryResolver = _componentFactoryResolver;
this.tracker = tracker;
this._backdropFactory = _componentFactoryResolver.resolveComponentFactory(BusyBackdropComponent);
this._loadingFactory = _componentFactoryResolver.resolveComponentFactory(BusyComponent);
let /** @type {?} */ options = this.normalizeOptions(null);
this.tracker.reset({
promiseList: options.busy,
delay: options.delay,
minDuration: options.minDuration
});
const /** @type {?} */ containerEl = document.querySelector('body');
let /** @type {?} */ backdropCmptRef;
let /** @type {?} */ loadingCmptRef;
// create backdrop
backdropCmptRef = this._backdropFactory.create(this._injector);
this._applicationRef.attachView(backdropCmptRef.hostView);
containerEl.appendChild(backdropCmptRef.location.nativeElement);
// create loading
loadingCmptRef = this._loadingFactory.create(this._injector);
this._applicationRef.attachView(loadingCmptRef.hostView);
containerEl.appendChild(loadingCmptRef.location.nativeElement);
const /** @type {?} */ instance = loadingCmptRef.instance;
instance.message = options.message;
instance.wrapperClass = options.wrapperClass;
instance.template = options.template;
this.backdropCmptRef = backdropCmptRef;
this.loadingCmptRef = loadingCmptRef;
this.backdropCmptRef.location.nativeElement.style.zIndex = 2000;
this.loadingCmptRef.location.nativeElement.style.zIndex = 2001;
}
/**
* @param {?=} options
* @return {?}
*/
open(options = undefined) {
options = this.normalizeOptions(options);
if (options.busy.length === 0) {
this._fakeBusy = new Subject().subscribe();
this._fakeBusy = new Promise(resolve => {
if (options.maxDuration)
setTimeout(() => resolve(), options.maxDuration);
});
options.busy.push(this._fakeBusy);
}
else if (this._fakeBusy) {
this._fakeBusy = null;
}
this.tracker.reset({
promiseList: options.busy,
delay: options.delay,
minDuration: options.minDuration
});
const /** @type {?} */ instance = this.loadingCmptRef.instance;
instance.message = options.message;
instance.wrapperClass = options.wrapperClass;
instance.template = options.template;
return this.loadingCmptRef;
}
/**
* @param {?} options
* @return {?}
*/
update(options) {
const /** @type {?} */ instance = this.loadingCmptRef.instance;
if (options.message)
instance.message = options.message;
if (options.wrapperClass)
instance.wrapperClass = options.wrapperClass;
if (options.template)
instance.template = options.template;
return this.loadingCmptRef;
}
/**
* @return {?}
*/
close() {
if (this._fakeBusy)
this._fakeBusy = null;
let /** @type {?} */ options = this.normalizeOptions(undefined);
this.tracker.reset({
promiseList: options.busy,
delay: options.delay,
minDuration: options.minDuration
});
const /** @type {?} */ instance = this.loadingCmptRef.instance;
instance.message = options.message;
instance.wrapperClass = options.wrapperClass;
instance.template = options.template;
return this.loadingCmptRef;
}
/**
* @param {?=} zIndex
* @return {?}
*/
zIndex(zIndex = 2000) {
let /** @type {?} */ ngBusyBackdrop = /** @type {?} */ (document.querySelector('div.ng-busy-backdrop'));
let /** @type {?} */ ngBusy = /** @type {?} */ (document.querySelector('div.ng-busy'));
if (ngBusyBackdrop) {
ngBusyBackdrop.style.zIndex = '' + zIndex;
}
if (ngBusy) {
ngBusy.style.zIndex = '' + (zIndex + 1);
}
}
/**
* @param {?} options
* @return {?}
*/
normalizeOptions(options) {
if (!options) {
options = { busy: null };
}
else if (Array.isArray(options) ||
options instanceof Promise ||
options instanceof Subscription) {
options = { busy: options };
}
options = Object.assign({}, new BusyConfig(), options);
if (!Array.isArray(options.busy)) {
options.busy = options.busy ? [options.busy] : [];
}
return options;
}
}
LoadingService.decorators = [
{ type: Injectable },
];
/** @nocollapse */
LoadingService.ctorParameters = () => [
{ type: ApplicationRef, },
{ type: Injector, },
{ type: ComponentFactoryResolver, },
{ type: PromiseTrackerService, },
];
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
class LoadingModule {
}
LoadingModule.decorators = [
{ type: NgModule, args: [{
imports: [BusyModule],
declarations: [],
providers: [LoadingService],
exports: [BusyModule]
},] },
];
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
export { LoadingModule, LoadingService, BusyBackdropComponent as ɵd, BusyConfig as ɵf, BusyComponent as ɵb, BusyModule as ɵa, BusyService as ɵe, PromiseTrackerService as ɵc };
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2Nob29sYmVsbGUtY29tbW9uLXNlcnZpY2VzLWxvYWRpbmcuanMubWFwIiwic291cmNlcyI6WyJuZzovL0BzY2hvb2xiZWxsZS9jb21tb24vc2VydmljZXMvbG9hZGluZy9idXN5LWNvbmZpZy50cyIsIm5nOi8vQHNjaG9vbGJlbGxlL2NvbW1vbi9zZXJ2aWNlcy9sb2FkaW5nL2J1c3kuc2VydmljZS50cyIsIm5nOi8vQHNjaG9vbGJlbGxlL2NvbW1vbi9zZXJ2aWNlcy9sb2FkaW5nL3Byb21pc2UtdHJhY2tlci5zZXJ2aWNlLnRzIiwibmc6Ly9Ac2Nob29sYmVsbGUvY29tbW9uL3NlcnZpY2VzL2xvYWRpbmcvYnVzeS1iYWNrZHJvcC5jb21wb25lbnQudHMiLCJuZzovL0BzY2hvb2xiZWxsZS9jb21tb24vc2VydmljZXMvbG9hZGluZy9idXN5LmNvbXBvbmVudC50cyIsIm5nOi8vQHNjaG9vbGJlbGxlL2NvbW1vbi9zZXJ2aWNlcy9sb2FkaW5nL2J1c3kubW9kdWxlLnRzIiwibmc6Ly9Ac2Nob29sYmVsbGUvY29tbW9uL3NlcnZpY2VzL2xvYWRpbmcvbG9hZGluZy5zZXJ2aWNlLnRzIiwibmc6Ly9Ac2Nob29sYmVsbGUvY29tbW9uL3NlcnZpY2VzL2xvYWRpbmcvbG9hZGluZy5tb2R1bGUudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAZmlsZSBCdXN5IENvbmZpZ1xuICogQGF1dGhvciB5dW1hbzx5dXpoYW5nLmxpbGxlQGdtYWlsLmNvbT5cbiAqL1xuXG5pbXBvcnQgeyBTdWJzY3JpcHRpb24gfSBmcm9tICdyeGpzL1N1YnNjcmlwdGlvbic7XG5cbmV4cG9ydCBjbGFzcyBCdXN5Q29uZmlnIGltcGxlbWVudHMgSUJ1c3lDb25maWcge1xuICB0ZW1wbGF0ZTogc3RyaW5nO1xuICBkZWxheTogbnVtYmVyO1xuICBtaW5EdXJhdGlvbjogbnVtYmVyO1xuICBiYWNrZHJvcDogYm9vbGVhbjtcbiAgbWVzc2FnZTogc3RyaW5nO1xuICB3cmFwcGVyQ2xhc3M6IHN0cmluZztcblxuICBjb25zdHJ1Y3Rvcihjb25maWc6IElCdXN5Q29uZmlnID0ge30pIHtcbiAgICBmb3IgKGxldCBvcHRpb24gaW4gQlVTWV9DT05GSUdfREVGQVVMVFMpIHtcbiAgICAgIHRoaXNbb3B0aW9uXSA9XG4gICAgICAgIGNvbmZpZ1tvcHRpb25dICE9IG51bGwgPyBjb25maWdbb3B0aW9uXSA6IEJVU1lfQ09ORklHX0RFRkFVTFRTW29wdGlvbl07XG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgSUJ1c3lDb25maWcge1xuICB0ZW1wbGF0ZT86IHN0cmluZztcbiAgZGVsYXk/OiBudW1iZXI7XG4gIG1pbkR1cmF0aW9uPzogbnVtYmVyO1xuICBiYWNrZHJvcD86IGJvb2xlYW47XG4gIG1lc3NhZ2U/OiBzdHJpbmc7XG4gIHdyYXBwZXJDbGFzcz86IHN0cmluZztcbiAgYnVzeT86IFByb21pc2U8YW55PiB8IFN1YnNjcmlwdGlvbiB8IEFycmF5PFByb21pc2U8YW55PiB8IFN1YnNjcmlwdGlvbj47XG59XG5cbmV4cG9ydCBjb25zdCBCVVNZX0NPTkZJR19ERUZBVUxUUyA9IHtcbiAgdGVtcGxhdGU6IGBcbiAgICAgICAgPGRpdiBjbGFzcz1cIm5nLWJ1c3ktZGVmYXVsdC13cmFwcGVyXCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwibmctYnVzeS1kZWZhdWx0LXNpZ25cIj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibmctYnVzeS1kZWZhdWx0LXNwaW5uZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImJhcjFcIj48L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImJhcjJcIj48L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImJhcjNcIj48L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImJhcjRcIj48L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImJhcjVcIj48L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImJhcjZcIj48L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImJhcjdcIj48L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImJhcjhcIj48L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImJhcjlcIj48L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImJhcjEwXCI+PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJiYXIxMVwiPjwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYmFyMTJcIj48L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibmctYnVzeS1kZWZhdWx0LXRleHRcIj57e21lc3NhZ2V9fTwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgIGAsXG4gIGRlbGF5OiAwLFxuICBtaW5EdXJhdGlvbjogMCxcbiAgYmFja2Ryb3A6IHRydWUsXG4gIG1lc3NhZ2U6ICdQbGVhc2Ugd2FpdC4uLicsXG4gIHdyYXBwZXJDbGFzczogJ25nLWJ1c3knXG59O1xuIiwiLyoqXG4gKiBAZmlsZSBTZXJ2aWNlOiBCdXN5XG4gKiBAYXV0aG9yIHl1bWFvPHl1emhhbmcubGlsbGVAZ21haWwuY29tPlxuICovXG5cbmltcG9ydCB7IEluamVjdGFibGUsIE9wdGlvbmFsIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbmltcG9ydCB7IEJ1c3lDb25maWcgfSBmcm9tICcuL2J1c3ktY29uZmlnJztcblxuQEluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIEJ1c3lTZXJ2aWNlIHtcbiAgY29uZmlnOiBCdXN5Q29uZmlnO1xuXG4gIGNvbnN0cnVjdG9yKEBPcHRpb25hbCgpIGNvbmZpZzogQnVzeUNvbmZpZykge1xuICAgIHRoaXMuY29uZmlnID0gY29uZmlnIHx8IG5ldyBCdXN5Q29uZmlnKCk7XG4gIH1cbn1cbiIsIi8qKlxuICogQGZpbGUgU2VydmljZTogUHJvbWlzZVRyYWNrZXJcbiAqIEBhdXRob3IgeXVtYW88eXV6aGFuZy5saWxsZUBnbWFpbC5jb20+XG4gKi9cblxuLy8gSW5zcGlyZWQgYnkgYW5ndWxhci1wcm9taXNlLXRyYWNrZXJcbi8vIEFkZCBPYnNlcnZhYmxlIFN1YnNjcmlwdGlvblxuXG5pbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBTdWJzY3JpcHRpb24gfSBmcm9tICdyeGpzL1N1YnNjcmlwdGlvbic7XG5cbkBJbmplY3RhYmxlKClcbmV4cG9ydCBjbGFzcyBQcm9taXNlVHJhY2tlclNlcnZpY2Uge1xuICBwcm9taXNlTGlzdDogQXJyYXk8UHJvbWlzZTxhbnk+IHwgU3Vic2NyaXB0aW9uPiA9IFtdO1xuICBkZWxheVByb21pc2U6IG51bWJlciB8IGFueTtcbiAgZHVyYXRpb25Qcm9taXNlOiBudW1iZXIgfCBhbnk7XG4gIGRlbGF5SnVzdEZpbmlzaGVkOiBib29sZWFuID0gZmFsc2U7XG4gIG1pbkR1cmF0aW9uOiBudW1iZXI7XG5cbiAgcmVzZXQob3B0aW9uczogSVByb21pc2VUcmFja2VyT3B0aW9ucykge1xuICAgIHRoaXMubWluRHVyYXRpb24gPSBvcHRpb25zLm1pbkR1cmF0aW9uO1xuXG4gICAgdGhpcy5wcm9taXNlTGlzdCA9IFtdO1xuICAgIG9wdGlvbnMucHJvbWlzZUxpc3QuZm9yRWFjaChwcm9taXNlID0+IHtcbiAgICAgIGlmICghcHJvbWlzZSB8fCBwcm9taXNlWydidXN5RnVsZmlsbGVkJ10pIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgdGhpcy5hZGRQcm9taXNlKHByb21pc2UpO1xuICAgIH0pO1xuXG4gICAgaWYgKHRoaXMucHJvbWlzZUxpc3QubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5kZWxheUp1c3RGaW5pc2hlZCA9IGZhbHNlO1xuICAgIGlmIChvcHRpb25zLmRlbGF5KSB7XG4gICAgICB0aGlzLmRlbGF5UHJvbWlzZSA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICB0aGlzLmRlbGF5UHJvbWlzZSA9IG51bGw7XG4gICAgICAgIHRoaXMuZGVsYXlKdXN0RmluaXNoZWQgPSB0cnVlO1xuICAgICAgfSwgb3B0aW9ucy5kZWxheSk7XG4gICAgfVxuICAgIGlmIChvcHRpb25zLm1pbkR1cmF0aW9uKSB7XG4gICAgICB0aGlzLmR1cmF0aW9uUHJvbWlzZSA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICB0aGlzLmR1cmF0aW9uUHJvbWlzZSA9IG51bGw7XG4gICAgICB9LCBvcHRpb25zLm1pbkR1cmF0aW9uICsgKG9wdGlvbnMuZGVsYXkgfHwgMCkpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgYWRkUHJvbWlzZShwcm9taXNlOiBQcm9taXNlPGFueT4gfCBTdWJzY3JpcHRpb24pIHtcbiAgICBpZiAodGhpcy5wcm9taXNlTGlzdC5pbmRleE9mKHByb21pc2UpICE9PSAtMSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMucHJvbWlzZUxpc3QucHVzaChwcm9taXNlKTtcblxuICAgIGlmIChwcm9taXNlIGluc3RhbmNlb2YgUHJvbWlzZSkge1xuICAgICAgcHJvbWlzZS50aGVuLmNhbGwoXG4gICAgICAgIHByb21pc2UsXG4gICAgICAgICgpID0+IHRoaXMuZmluaXNoUHJvbWlzZShwcm9taXNlKSxcbiAgICAgICAgKCkgPT4gdGhpcy5maW5pc2hQcm9taXNlKHByb21pc2UpXG4gICAgICApO1xuICAgIH0gZWxzZSBpZiAocHJvbWlzZSBpbnN0YW5jZW9mIFN1YnNjcmlwdGlvbikge1xuICAgICAgcHJvbWlzZS5hZGQoKCkgPT4gdGhpcy5maW5pc2hQcm9taXNlKHByb21pc2UpKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGZpbmlzaFByb21pc2UocHJvbWlzZTogUHJvbWlzZTxhbnk+IHwgU3Vic2NyaXB0aW9uKSB7XG4gICAgcHJvbWlzZVsnYnVzeUZ1bGZpbGxlZCddID0gdHJ1ZTtcbiAgICBjb25zdCBpbmRleCA9IHRoaXMucHJvbWlzZUxpc3QuaW5kZXhPZihwcm9taXNlKTtcbiAgICBpZiAoaW5kZXggPT09IC0xKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMucHJvbWlzZUxpc3Quc3BsaWNlKGluZGV4LCAxKTtcbiAgfVxuXG4gIGlzQWN0aXZlKCkge1xuICAgIGlmICh0aGlzLmRlbGF5UHJvbWlzZSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGlmICghdGhpcy5kZWxheUp1c3RGaW5pc2hlZCkge1xuICAgICAgaWYgKHRoaXMuZHVyYXRpb25Qcm9taXNlKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXMucHJvbWlzZUxpc3QubGVuZ3RoID4gMDtcbiAgICB9XG5cbiAgICB0aGlzLmRlbGF5SnVzdEZpbmlzaGVkID0gZmFsc2U7XG4gICAgaWYgKHRoaXMucHJvbWlzZUxpc3QubGVuZ3RoID09PSAwKSB7XG4gICAgICB0aGlzLmR1cmF0aW9uUHJvbWlzZSA9IG51bGw7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnByb21pc2VMaXN0Lmxlbmd0aCA+IDA7XG4gIH1cbn1cblxuZXhwb3J0IGludGVyZmFjZSBJUHJvbWlzZVRyYWNrZXJPcHRpb25zIHtcbiAgbWluRHVyYXRpb246IG51bWJlcjtcbiAgZGVsYXk6IG51bWJlcjtcbiAgcHJvbWlzZUxpc3Q6IFByb21pc2U8YW55PltdO1xufVxuIiwiLyoqXG4gKiBAZmlsZSBDb21wb25lbnQ6IEJ1c3lCYWNrZHJvcFxuICogQGF1dGhvciB5dW1hbzx5dXpoYW5nLmxpbGxlQGdtYWlsLmNvbT5cbiAqL1xuXG5pbXBvcnQgeyBDb21wb25lbnQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7XG4gIHRyaWdnZXIsXG4gIHN0YXRlLFxuICBzdHlsZSxcbiAgdHJhbnNpdGlvbixcbiAgYW5pbWF0ZVxufSBmcm9tICdAYW5ndWxhci9hbmltYXRpb25zJztcblxuaW1wb3J0IHsgUHJvbWlzZVRyYWNrZXJTZXJ2aWNlIH0gZnJvbSAnLi9wcm9taXNlLXRyYWNrZXIuc2VydmljZSc7XG5cbmNvbnN0IGluYWN0aXZlU3R5bGUgPSBzdHlsZSh7XG4gIG9wYWNpdHk6IDBcbn0pO1xuY29uc3QgdGltaW5nID0gJy4zcyBlYXNlJztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnbmctYnVzeS1iYWNrZHJvcCcsXG4gIHRlbXBsYXRlOiBgXG4gICAgICAgIDxkaXYgY2xhc3M9XCJuZy1idXN5LWJhY2tkcm9wXCJcbiAgICAgICAgICAgICBAZmFkZUluT3V0XG4gICAgICAgICAgICAgKm5nSWY9XCJpc0FjdGl2ZSgpXCI+XG4gICAgICAgIDwvZGl2PlxuICAgIGAsXG4gIGFuaW1hdGlvbnM6IFtcbiAgICB0cmlnZ2VyKCdmYWRlSW5PdXQnLCBbXG4gICAgICB0cmFuc2l0aW9uKCd2b2lkID0+IConLCBbaW5hY3RpdmVTdHlsZSwgYW5pbWF0ZSh0aW1pbmcpXSksXG4gICAgICB0cmFuc2l0aW9uKCcqID0+IHZvaWQnLCBbYW5pbWF0ZSh0aW1pbmcsIGluYWN0aXZlU3R5bGUpXSlcbiAgICBdKVxuICBdXG59KVxuZXhwb3J0IGNsYXNzIEJ1c3lCYWNrZHJvcENvbXBvbmVudCB7XG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgdHJhY2tlcjogUHJvbWlzZVRyYWNrZXJTZXJ2aWNlKSB7fVxuXG4gIGlzQWN0aXZlKCkge1xuICAgIHJldHVybiB0aGlzLnRyYWNrZXIuaXNBY3RpdmUoKTtcbiAgfVxufVxuIiwiLyoqXG4gKiBAZmlsZSBDb21wb25lbnQ6IEJ1c3lcbiAqIEBhdXRob3IgeXVtYW88eXV6aGFuZy5saWxsZUBnbWFpbC5jb20+XG4gKi9cblxuaW1wb3J0IHtcbiAgQ29tcG9uZW50LFxuICBOZ01vZHVsZSxcbiAgTmdNb2R1bGVGYWN0b3J5LFxuICBJbmplY3RhYmxlLFxuICBEb0NoZWNrLFxuICBPbkRlc3Ryb3ksXG4gIFZpZXdFbmNhcHN1bGF0aW9uXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtcbiAgdHJpZ2dlcixcbiAgc3RhdGUsXG4gIHN0eWxlLFxuICB0cmFuc2l0aW9uLFxuICBhbmltYXRlXG59IGZyb20gJ0Bhbmd1bGFyL2FuaW1hdGlvbnMnO1xuXG5pbXBvcnQgeyBQcm9taXNlVHJhY2tlclNlcnZpY2UgfSBmcm9tICcuL3Byb21pc2UtdHJhY2tlci5zZXJ2aWNlJztcbi8vaW1wb3J0IHsgQ3VzdG9tQ29tcGlsZXIgfSBmcm9tICcuL2J1c3kuY29tcGlsZXInO1xuXG5jb25zdCBpbmFjdGl2ZVN0eWxlID0gc3R5bGUoe1xuICBvcGFjaXR5OiAwLFxuICB0cmFuc2Zvcm06ICd0cmFuc2xhdGVZKC00MHB4KSdcbn0pO1xuY29uc3QgdGltaW5nID0gJy4zcyBlYXNlJztcblxuZXhwb3J0IGludGVyZmFjZSBJQnVzeUNvbnRleHQge1xuICBtZXNzYWdlOiBzdHJpbmc7XG59XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ25nLWJ1c3knLFxuICAvLyB0ZW1wbGF0ZTogYFxuICAvLyAgICAgPGRpdiBbY2xhc3NdPVwid3JhcHBlckNsYXNzXCIgKm5nSWY9XCJpc0FjdGl2ZSgpXCIgQGZseUluT3V0PlxuICAvLyAgICAgICAgIDxuZy1jb250YWluZXIgKm5nQ29tcG9uZW50T3V0bGV0PVwiVGVtcGxhdGVDb21wb25lbnQ7IG5nTW9kdWxlRmFjdG9yeTogbm1mO1wiPjwvbmctY29udGFpbmVyPlxuICAvLyAgICAgPC9kaXY+XG4gIC8vIGAsXG4gIHRlbXBsYXRlOiBgXG4gICAgICAgIDxkaXYgW2NsYXNzXT1cIndyYXBwZXJDbGFzc1wiICpuZ0lmPVwiaXNBY3RpdmUoKVwiIEBmbHlJbk91dD4gXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwibmctYnVzeS1kZWZhdWx0LXdyYXBwZXJcIj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibmctYnVzeS1kZWZhdWx0LXNpZ25cIj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm5nLWJ1c3ktZGVmYXVsdC1zcGlubmVyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYmFyMVwiPjwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImJhcjJcIj48L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJiYXIzXCI+PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYmFyNFwiPjwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImJhcjVcIj48L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJiYXI2XCI+PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYmFyN1wiPjwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImJhcjhcIj48L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJiYXI5XCI+PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYmFyMTBcIj48L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJiYXIxMVwiPjwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImJhcjEyXCI+PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibmctYnVzeS1kZWZhdWx0LXRleHRcIj57e21lc3NhZ2V9fTwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgIGAsXG4gIHN0eWxlczogW2AubmctYnVzeXt6LWluZGV4OjIwMDJ9Lm5nLWJ1c3ksLm5nLWJ1c3k+KiwubmctYnVzeT5uZy1jb21wb25lbnQ+Kntwb3NpdGlvbjphYnNvbHV0ZTt0b3A6MDtsZWZ0OjA7cmlnaHQ6MDtib3R0b206MH0ubmctYnVzeS1iYWNrZHJvcHtwb3NpdGlvbjpmaXhlZDt0b3A6MDtsZWZ0OjA7cmlnaHQ6MDtib3R0b206MDt6LWluZGV4OjEwMDE7YmFja2dyb3VuZDojZmZmO29wYWNpdHk6Ljd9Lm5nLWJ1c3ktZGVmYXVsdC13cmFwcGVye3RleHQtYWxpZ246Y2VudGVyfS5uZy1idXN5LWRlZmF1bHQtc2lnbntwb3NpdGlvbjpmaXhlZDt0b3A6NTAlO2xlZnQ6NTAlOy13ZWJraXQtdHJhbnNmb3JtOnRyYW5zbGF0ZSgtNTAlLC01MCUpO3RyYW5zZm9ybTp0cmFuc2xhdGUoLTUwJSwtNTAlKTtkaXNwbGF5OmlubGluZS1ibG9jazt6LWluZGV4OjEwMDM7cGFkZGluZzoxMnB4IDE0cHg7Ym9yZGVyOjFweCBzb2xpZCAjZDhkOGQ4O2JvcmRlci10b3A6MDtib3JkZXItcmFkaXVzOjAgMCA0cHggNHB4O2JveC1zaGFkb3c6MCAxcHggMnB4IHJnYmEoMCwwLDAsLjA1KTtiYWNrZ3JvdW5kOiNmOGY4Zjg7Y29sb3I6IzMzMzt3aWR0aDotd2Via2l0LW1heC1jb250ZW50O3dpZHRoOi1tb3otbWF4LWNvbnRlbnQ7d2lkdGg6bWF4LWNvbnRlbnR9Lm5nLWJ1c3ktZGVmYXVsdC10ZXh0e2Rpc3BsYXk6aW5saW5lLWJsb2NrO21hcmdpbi1sZWZ0OjZweDttYXgtd2lkdGg6NDAwcHg7Zm9udC1zaXplOjE0cHg7dGV4dC1hbGlnbjpsZWZ0fS5uZy1idXN5LWRlZmF1bHQtc3Bpbm5lcntwb3NpdGlvbjpyZWxhdGl2ZTtkaXNwbGF5OmlubGluZS1ibG9jazt3aWR0aDoyNXB4O2hlaWdodDoyNXB4O3ZlcnRpY2FsLWFsaWduOm1pZGRsZX0ubmctYnVzeS1kZWZhdWx0LXNwaW5uZXIgZGl2e3Bvc2l0aW9uOmFic29sdXRlO2xlZnQ6NDQuNSU7dG9wOjM3JTt3aWR0aDoxMCU7aGVpZ2h0OjI2JTtiYWNrZ3JvdW5kOiM2NjY7Ym9yZGVyLXJhZGl1czo1MHB4O2JveC1zaGFkb3c6MCAwIDNweCByZ2JhKDAsMCwwLC4yKTtvcGFjaXR5OjA7LXdlYmtpdC1hbmltYXRpb246MXMgbGluZWFyIGluZmluaXRlIGJ1c3ktc3Bpbm5lci1hbmltO2FuaW1hdGlvbjoxcyBsaW5lYXIgaW5maW5pdGUgYnVzeS1zcGlubmVyLWFuaW19Lm5nLWJ1c3ktZGVmYXVsdC1zcGlubmVyIC5iYXIxey13ZWJraXQtdHJhbnNmb3JtOnJvdGF0ZSgwKSB0cmFuc2xhdGUoMCwtMTQyJSk7dHJhbnNmb3JtOnJvdGF0ZSgwKSB0cmFuc2xhdGUoMCwtMTQyJSk7LXdlYmtpdC1hbmltYXRpb24tZGVsYXk6LTFzO2FuaW1hdGlvbi1kZWxheTotMXN9Lm5nLWJ1c3ktZGVmYXVsdC1zcGlubmVyIC5iYXIyey13ZWJraXQtdHJhbnNmb3JtOnJvdGF0ZSgzMGRlZykgdHJhbnNsYXRlKDAsLTE0MiUpO3RyYW5zZm9ybTpyb3RhdGUoMzBkZWcpIHRyYW5zbGF0ZSgwLC0xNDIlKTstd2Via2l0LWFuaW1hdGlvbi1kZWxheTotLjkxNjY2NjY3czthbmltYXRpb24tZGVsYXk6LS45MTY2NjY2N3N9Lm5nLWJ1c3ktZGVmYXVsdC1zcGlubmVyIC5iYXIzey13ZWJraXQtdHJhbnNmb3JtOnJvdGF0ZSg2MGRlZykgdHJhbnNsYXRlKDAsLTE0MiUpO3RyYW5zZm9ybTpyb3RhdGUoNjBkZWcpIHRyYW5zbGF0ZSgwLC0xNDIlKTstd2Via2l0LWFuaW1hdGlvbi1kZWxheTotLjgzMzMzMzMzczthbmltYXRpb24tZGVsYXk6LS44MzMzMzMzM3N9Lm5nLWJ1c3ktZGVmYXVsdC1zcGlubmVyIC5iYXI0ey13ZWJraXQtdHJhbnNmb3JtOnJvdGF0ZSg5MGRlZykgdHJhbnNsYXRlKDAsLTE0MiUpO3RyYW5zZm9ybTpyb3RhdGUoOTBkZWcpIHRyYW5zbGF0ZSgwLC0xNDIlKTstd2Via2l0LWFuaW1hdGlvbi1kZWxheTotLjc1czthbmltYXRpb24tZGVsYXk6LS43NXN9Lm5nLWJ1c3ktZGVmYXVsdC1zcGlubmVyIC5iYXI1ey13ZWJraXQtdHJhbnNmb3JtOnJvdGF0ZSgxMjBkZWcpIHRyYW5zbGF0ZSgwLC0xNDIlKTt0cmFuc2Zvcm06cm90YXRlKDEyMGRlZykgdHJhbnNsYXRlKDAsLTE0MiUpOy13ZWJraXQtYW5pbWF0aW9uLWRlbGF5Oi0uNjY2NjY2NjdzO2FuaW1hdGlvbi1kZWxheTotLjY2NjY2NjY3c30ubmctYnVzeS1kZWZhdWx0LXNwaW5uZXIgLmJhcjZ7LXdlYmtpdC10cmFuc2Zvcm06cm90YXRlKDE1MGRlZykgdHJhbnNsYXRlKDAsLTE0MiUpO3RyYW5zZm9ybTpyb3RhdGUoMTUwZGVnKSB0cmFuc2xhdGUoMCwtMTQyJSk7LXdlYmtpdC1hbmltYXRpb24tZGVsYXk6LS41ODMzMzMzM3M7YW5pbWF0aW9uLWRlbGF5Oi0uNTgzMzMzMzNzfS5uZy1idXN5LWRlZmF1bHQtc3Bpbm5lciAuYmFyN3std2Via2l0LXRyYW5zZm9ybTpyb3RhdGUoMTgwZGVnKSB0cmFuc2xhdGUoMCwtMTQyJSk7dHJhbnNmb3JtOnJvdGF0ZSgxODBkZWcpIHRyYW5zbGF0ZSgwLC0xNDIlKTstd2Via2l0LWFuaW1hdGlvbi1kZWxheTotLjVzO2FuaW1hdGlvbi1kZWxheTotLjVzfS5uZy1idXN5LWRlZmF1bHQtc3Bpbm5lciAuYmFyOHstd2Via2l0LXRyYW5zZm9ybTpyb3RhdGUoMjEwZGVnKSB0cmFuc2xhdGUoMCwtMTQyJSk7dHJhbnNmb3JtOnJvdGF0ZSgyMTBkZWcpIHRyYW5zbGF0ZSgwLC0xNDIlKTstd2Via2l0LWFuaW1hdGlvbi1kZWxheTotLjQxNjY2NjY3czthbmltYXRpb24tZGVsYXk6LS40MTY2NjY2N3N9Lm5nLWJ1c3ktZGVmYXVsdC1zcGlubmVyIC5iYXI5ey13ZWJraXQtdHJhbnNmb3JtOnJvdGF0ZSgyNDBkZWcpIHRyYW5zbGF0ZSgwLC0xNDIlKTt0cmFuc2Zvcm06cm90YXRlKDI0MGRlZykgdHJhbnNsYXRlKDAsLTE0MiUpOy13ZWJraXQtYW5pbWF0aW9uLWRlbGF5Oi0uMzMzMzMzMzNzO2FuaW1hdGlvbi1kZWxheTotLjMzMzMzMzMzc30ubmctYnVzeS1kZWZhdWx0LXNwaW5uZXIgLmJhcjEwey13ZWJraXQtdHJhbnNmb3JtOnJvdGF0ZSgyNzBkZWcpIHRyYW5zbGF0ZSgwLC0xNDIlKTt0cmFuc2Zvcm06cm90YXRlKDI3MGRlZykgdHJhbnNsYXRlKDAsLTE0MiUpOy13ZWJraXQtYW5pbWF0aW9uLWRlbGF5Oi0uMjVzO2FuaW1hdGlvbi1kZWxheTotLjI1c30ubmctYnVzeS1kZWZhdWx0LXNwaW5uZXIgLmJhcjExey13ZWJraXQtdHJhbnNmb3JtOnJvdGF0ZSgzMDBkZWcpIHRyYW5zbGF0ZSgwLC0xNDIlKTt0cmFuc2Zvcm06cm90YXRlKDMwMGRlZykgdHJhbnNsYXRlKDAsLTE0MiUpOy13ZWJraXQtYW5pbWF0aW9uLWRlbGF5Oi0uMTY2NjY2NjdzO2FuaW1hdGlvbi1kZWxheTotLjE2NjY2NjY3c30ubmctYnVzeS1kZWZhdWx0LXNwaW5uZXIgLmJhcjEyey13ZWJraXQtdHJhbnNmb3JtOnJvdGF0ZSgzMzBkZWcpIHRyYW5zbGF0ZSgwLC0xNDIlKTt0cmFuc2Zvcm06cm90YXRlKDMzMGRlZykgdHJhbnNsYXRlKDAsLTE0MiUpOy13ZWJraXQtYW5pbWF0aW9uLWRlbGF5Oi04My4zMzMzM21zO2FuaW1hdGlvbi1kZWxheTotODMuMzMzMzNtc31ALXdlYmtpdC1rZXlmcmFtZXMgYnVzeS1zcGlubmVyLWFuaW17ZnJvbXtvcGFjaXR5OjF9dG97b3BhY2l0eTouMjV9fUBrZXlmcmFtZXMgYnVzeS1zcGlubmVyLWFuaW17ZnJvbXtvcGFjaXR5OjF9dG97b3BhY2l0eTouMjV9fWBdLFxuICBhbmltYXRpb25zOiBbXG4gICAgdHJpZ2dlcignZmx5SW5PdXQnLCBbXG4gICAgICB0cmFuc2l0aW9uKCd2b2lkID0+IConLCBbaW5hY3RpdmVTdHlsZSwgYW5pbWF0ZSh0aW1pbmcpXSksXG4gICAgICB0cmFuc2l0aW9uKCcqID0+IHZvaWQnLCBbYW5pbWF0ZSh0aW1pbmcsIGluYWN0aXZlU3R5bGUpXSlcbiAgICBdKVxuICBdLFxuICBlbmNhcHN1bGF0aW9uOiBWaWV3RW5jYXBzdWxhdGlvbi5Ob25lXG59KVxuZXhwb3J0IGNsYXNzIEJ1c3lDb21wb25lbnQgaW1wbGVtZW50cyBEb0NoZWNrLCBPbkRlc3Ryb3kge1xuICAvLyBUZW1wbGF0ZUNvbXBvbmVudDtcbiAgLy8gcHJpdmF0ZSBubWY6IE5nTW9kdWxlRmFjdG9yeTxhbnk+O1xuICB3cmFwcGVyQ2xhc3M6IHN0cmluZztcbiAgdGVtcGxhdGU6IHN0cmluZztcbiAgbWVzc2FnZTogc3RyaW5nO1xuICBwcml2YXRlIGxhc3RNZXNzYWdlOiBzdHJpbmc7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSB0cmFja2VyOiBQcm9taXNlVHJhY2tlclNlcnZpY2UgLy8gcHJpdmF0ZSBjb21waWxlcjogQ3VzdG9tQ29tcGlsZXJcbiAgKSB7fVxuXG4gIG5nRG9DaGVjaygpIHtcbiAgICBpZiAodGhpcy5tZXNzYWdlID09PSB0aGlzLmxhc3RNZXNzYWdlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMubGFzdE1lc3NhZ2UgPSB0aGlzLm1lc3NhZ2U7XG4gICAgLy8gdGhpcy5jbGVhckR5bmFtaWNUZW1wbGF0ZUNhY2hlKCk7XG4gICAgLy8gdGhpcy5jcmVhdGVEeW5hbWljVGVtcGxhdGUoKTtcbiAgfVxuXG4gIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgIC8vIHRoaXMuY2xlYXJEeW5hbWljVGVtcGxhdGVDYWNoZSgpO1xuICB9XG5cbiAgLy8gY3JlYXRlRHluYW1pY1RlbXBsYXRlKCkge1xuICAvLyAgICAgY29uc3Qge3RlbXBsYXRlLCBtZXNzYWdlfSA9IHRoaXM7XG5cbiAgLy8gICAgIEBDb21wb25lbnQoe3RlbXBsYXRlfSlcbiAgLy8gICAgIGNsYXNzIFRlbXBsYXRlQ29tcG9uZW50IHtcbiAgLy8gICAgICAgICBtZXNzYWdlOiBzdHJpbmcgPSBtZXNzYWdlO1xuICAvLyAgICAgfVxuXG4gIC8vICAgICBATmdNb2R1bGUoe1xuICAvLyAgICAgICAgIGRlY2xhcmF0aW9uczogW1RlbXBsYXRlQ29tcG9uZW50XSxcbiAgLy8gICAgICAgICBlbnRyeUNvbXBvbmVudHM6IFtUZW1wbGF0ZUNvbXBvbmVudF1cbiAgLy8gICAgIH0pXG4gIC8vICAgICBjbGFzcyBUZW1wbGF0ZU1vZHVsZSB7fVxuXG4gIC8vICAgICB0aGlzLlRlbXBsYXRlQ29tcG9uZW50ID0gVGVtcGxhdGVDb21wb25lbnQ7XG4gIC8vICAgICB0aGlzLm5tZiA9IHRoaXMuY29tcGlsZXIuY29tcGlsZU1vZHVsZVN5bmMoVGVtcGxhdGVNb2R1bGUpO1xuICAvLyB9XG5cbiAgLy8gY2xlYXJEeW5hbWljVGVtcGxhdGVDYWNoZSgpIHtcbiAgLy8gICAgIGlmICghdGhpcy5ubWYpIHtcbiAgLy8gICAgICAgICByZXR1cm47XG4gIC8vICAgICB9XG5cbiAgLy8gICAgIHRoaXMuY29tcGlsZXIuY2xlYXJDYWNoZUZvcih0aGlzLm5tZi5tb2R1bGVUeXBlKTtcbiAgLy8gICAgIHRoaXMubm1mID0gbnVsbDtcbiAgLy8gfVxuXG4gIGlzQWN0aXZlKCkge1xuICAgIHJldHVybiB0aGlzLnRyYWNrZXIuaXNBY3RpdmUoKTtcbiAgfVxufVxuIiwiLyoqXG4gKiBAZmlsZSBNb2R1bGU6IEJ1c3lcbiAqIEBhdXRob3IgeXVtYW88eXV6aGFuZy5saWxsZUBnbWFpbC5jb20+XG4gKi9cblxuaW1wb3J0IHsgTmdNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IENvbW1vbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQgeyBNb2R1bGVXaXRoUHJvdmlkZXJzIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbmltcG9ydCB7IEJ1c3lTZXJ2aWNlIH0gZnJvbSAnLi9idXN5LnNlcnZpY2UnO1xuaW1wb3J0IHsgQnVzeUJhY2tkcm9wQ29tcG9uZW50IH0gZnJvbSAnLi9idXN5LWJhY2tkcm9wLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBCdXN5Q29tcG9uZW50IH0gZnJvbSAnLi9idXN5LmNvbXBvbmVudCc7XG5pbXBvcnQgeyBCdXN5Q29uZmlnIH0gZnJvbSAnLi9idXN5LWNvbmZpZyc7XG4vLyBpbXBvcnQge0N1c3RvbUNvbXBpbGVyLCBjcmVhdGVKaXRDb21waWxlcn0gZnJvbSAnLi9idXN5LmNvbXBpbGVyJztcbmltcG9ydCB7IFByb21pc2VUcmFja2VyU2VydmljZSB9IGZyb20gJy4vcHJvbWlzZS10cmFja2VyLnNlcnZpY2UnO1xuXG4vLyBXb3JrYXJvdW5kIGZvciBDb21waWxlciBpbiBBT1Rcbi8vIGh0dHBzOi8vZ2l0aHViLmNvbS9hbmd1bGFyL2FuZ3VsYXIvaXNzdWVzLzE1NTEwI2lzc3VlY29tbWVudC0yOTQzMDE3NThcbi8vXG5ATmdNb2R1bGUoe1xuICBpbXBvcnRzOiBbQ29tbW9uTW9kdWxlXSxcbiAgZGVjbGFyYXRpb25zOiBbQnVzeUNvbXBvbmVudCwgQnVzeUJhY2tkcm9wQ29tcG9uZW50XSxcbiAgcHJvdmlkZXJzOiBbXG4gICAgQnVzeVNlcnZpY2UsXG4gICAgUHJvbWlzZVRyYWNrZXJTZXJ2aWNlXG4gICAgLy8ge1xuICAgIC8vICAgICBwcm92aWRlOiBDdXN0b21Db21waWxlcixcbiAgICAvLyAgICAgdXNlRmFjdG9yeTogY3JlYXRlSml0Q29tcGlsZXJcbiAgICAvLyB9LFxuICBdLFxuICBlbnRyeUNvbXBvbmVudHM6IFtCdXN5Q29tcG9uZW50LCBCdXN5QmFja2Ryb3BDb21wb25lbnRdXG59KVxuZXhwb3J0IGNsYXNzIEJ1c3lNb2R1bGUge1xuICBzdGF0aWMgZm9yUm9vdChjb25maWc6IEJ1c3lDb25maWcpOiBNb2R1bGVXaXRoUHJvdmlkZXJzIHtcbiAgICByZXR1cm4ge1xuICAgICAgbmdNb2R1bGU6IEJ1c3lNb2R1bGUsXG4gICAgICBwcm92aWRlcnM6IFt7IHByb3ZpZGU6IEJ1c3lDb25maWcsIHVzZVZhbHVlOiBjb25maWcgfV1cbiAgICB9O1xuICB9XG59XG4iLCJpbXBvcnQge1xuICBBcHBsaWNhdGlvblJlZixcbiAgSW5qZWN0YWJsZSxcbiAgSW5qZWN0b3IsXG4gIENvbXBvbmVudEZhY3RvcnksXG4gIENvbXBvbmVudEZhY3RvcnlSZXNvbHZlcixcbiAgQ29tcG9uZW50UmVmLFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuaW1wb3J0IHsgQnVzeUJhY2tkcm9wQ29tcG9uZW50IH0gZnJvbSAnLi9idXN5LWJhY2tkcm9wLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBCdXN5Q29tcG9uZW50IH0gZnJvbSAnLi9idXN5LmNvbXBvbmVudCc7XG5cbmltcG9ydCB7IEJ1c3lDb25maWcgfSBmcm9tICcuL2J1c3ktY29uZmlnJztcbmltcG9ydCB7IFByb21pc2VUcmFja2VyU2VydmljZSB9IGZyb20gJy4vcHJvbWlzZS10cmFja2VyLnNlcnZpY2UnO1xuXG5pbXBvcnQgeyBTdWJqZWN0IH0gZnJvbSAncnhqcy9TdWJqZWN0JztcbmltcG9ydCB7IFN1YnNjcmlwdGlvbiB9IGZyb20gJ3J4anMvU3Vic2NyaXB0aW9uJztcblxuQEluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIExvYWRpbmdTZXJ2aWNlIHtcbiAgcHJpdmF0ZSBfYmFja2Ryb3BGYWN0b3J5OiBDb21wb25lbnRGYWN0b3J5PEJ1c3lCYWNrZHJvcENvbXBvbmVudD47XG4gIHByaXZhdGUgX2xvYWRpbmdGYWN0b3J5OiBDb21wb25lbnRGYWN0b3J5PEJ1c3lDb21wb25lbnQ+O1xuICBwcml2YXRlIF9mYWtlQnVzeTogU3Vic2NyaXB0aW9uIHwgUHJvbWlzZTxhbnk+O1xuICBwdWJsaWMgYmFja2Ryb3BDbXB0UmVmOiBDb21wb25lbnRSZWY8QnVzeUJhY2tkcm9wQ29tcG9uZW50PjtcbiAgcHVibGljIGxvYWRpbmdDbXB0UmVmOiBDb21wb25lbnRSZWY8QnVzeUNvbXBvbmVudD47XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBfYXBwbGljYXRpb25SZWY6IEFwcGxpY2F0aW9uUmVmLFxuICAgIHByaXZhdGUgX2luamVjdG9yOiBJbmplY3RvcixcbiAgICBwcml2YXRlIF9jb21wb25lbnRGYWN0b3J5UmVzb2x2ZXI6IENvbXBvbmVudEZhY3RvcnlSZXNvbHZlcixcbiAgICBwcml2YXRlIHRyYWNrZXI6IFByb21pc2VUcmFja2VyU2VydmljZVxuICApIHtcbiAgICB0aGlzLl9iYWNrZHJvcEZhY3RvcnkgPSBfY29tcG9uZW50RmFjdG9yeVJlc29sdmVyLnJlc29sdmVDb21wb25lbnRGYWN0b3J5KFxuICAgICAgQnVzeUJhY2tkcm9wQ29tcG9uZW50XG4gICAgKTtcbiAgICB0aGlzLl9sb2FkaW5nRmFjdG9yeSA9IF9jb21wb25lbnRGYWN0b3J5UmVzb2x2ZXIucmVzb2x2ZUNvbXBvbmVudEZhY3RvcnkoXG4gICAgICBCdXN5Q29tcG9uZW50XG4gICAgKTtcblxuICAgIGxldCBvcHRpb25zID0gdGhpcy5ub3JtYWxpemVPcHRpb25zKG51bGwpO1xuICAgIHRoaXMudHJhY2tlci5yZXNldCh7XG4gICAgICBwcm9taXNlTGlzdDogb3B0aW9ucy5idXN5LFxuICAgICAgZGVsYXk6IG9wdGlvbnMuZGVsYXksXG4gICAgICBtaW5EdXJhdGlvbjogb3B0aW9ucy5taW5EdXJhdGlvblxuICAgIH0pO1xuICAgIGNvbnN0IGNvbnRhaW5lckVsID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignYm9keScpO1xuXG4gICAgbGV0IGJhY2tkcm9wQ21wdFJlZjogQ29tcG9uZW50UmVmPEJ1c3lCYWNrZHJvcENvbXBvbmVudD47XG4gICAgbGV0IGxvYWRpbmdDbXB0UmVmOiBDb21wb25lbnRSZWY8QnVzeUNvbXBvbmVudD47XG5cbiAgICAvLyBjcmVhdGUgYmFja2Ryb3BcbiAgICBiYWNrZHJvcENtcHRSZWYgPSB0aGlzLl9iYWNrZHJvcEZhY3RvcnkuY3JlYXRlKHRoaXMuX2luamVjdG9yKTtcbiAgICB0aGlzLl9hcHBsaWNhdGlvblJlZi5hdHRhY2hWaWV3KGJhY2tkcm9wQ21wdFJlZi5ob3N0Vmlldyk7XG4gICAgY29udGFpbmVyRWwuYXBwZW5kQ2hpbGQoYmFja2Ryb3BDbXB0UmVmLmxvY2F0aW9uLm5hdGl2ZUVsZW1lbnQpO1xuXG4gICAgLy8gY3JlYXRlIGxvYWRpbmdcbiAgICBsb2FkaW5nQ21wdFJlZiA9IHRoaXMuX2xvYWRpbmdGYWN0b3J5LmNyZWF0ZSh0aGlzLl9pbmplY3Rvcik7XG4gICAgdGhpcy5fYXBwbGljYXRpb25SZWYuYXR0YWNoVmlldyhsb2FkaW5nQ21wdFJlZi5ob3N0Vmlldyk7XG4gICAgY29udGFpbmVyRWwuYXBwZW5kQ2hpbGQobG9hZGluZ0NtcHRSZWYubG9jYXRpb24ubmF0aXZlRWxlbWVudCk7XG4gICAgY29uc3QgaW5zdGFuY2UgPSBsb2FkaW5nQ21wdFJlZi5pbnN0YW5jZTtcbiAgICBpbnN0YW5jZS5tZXNzYWdlID0gb3B0aW9ucy5tZXNzYWdlO1xuICAgIGluc3RhbmNlLndyYXBwZXJDbGFzcyA9IG9wdGlvbnMud3JhcHBlckNsYXNzO1xuICAgIGluc3RhbmNlLnRlbXBsYXRlID0gb3B0aW9ucy50ZW1wbGF0ZTtcblxuICAgIHRoaXMuYmFja2Ryb3BDbXB0UmVmID0gYmFja2Ryb3BDbXB0UmVmO1xuICAgIHRoaXMubG9hZGluZ0NtcHRSZWYgPSBsb2FkaW5nQ21wdFJlZjtcblxuICAgIHRoaXMuYmFja2Ryb3BDbXB0UmVmLmxvY2F0aW9uLm5hdGl2ZUVsZW1lbnQuc3R5bGUuekluZGV4ID0gMjAwMDtcbiAgICB0aGlzLmxvYWRpbmdDbXB0UmVmLmxvY2F0aW9uLm5hdGl2ZUVsZW1lbnQuc3R5bGUuekluZGV4ID0gMjAwMTtcbiAgfVxuICBvcGVuKG9wdGlvbnMgPSB1bmRlZmluZWQpIHtcbiAgICBvcHRpb25zID0gdGhpcy5ub3JtYWxpemVPcHRpb25zKG9wdGlvbnMpO1xuICAgIGlmIChvcHRpb25zLmJ1c3kubGVuZ3RoID09PSAwKSB7XG4gICAgICB0aGlzLl9mYWtlQnVzeSA9IG5ldyBTdWJqZWN0KCkuc3Vic2NyaWJlKCk7XG4gICAgICB0aGlzLl9mYWtlQnVzeSA9IG5ldyBQcm9taXNlKHJlc29sdmUgPT4ge1xuICAgICAgICBpZiAob3B0aW9ucy5tYXhEdXJhdGlvbilcbiAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHJlc29sdmUoKSwgb3B0aW9ucy5tYXhEdXJhdGlvbik7XG4gICAgICB9KTtcbiAgICAgIG9wdGlvbnMuYnVzeS5wdXNoKHRoaXMuX2Zha2VCdXN5KTtcbiAgICB9IGVsc2UgaWYgKHRoaXMuX2Zha2VCdXN5KSB7XG4gICAgICB0aGlzLl9mYWtlQnVzeSA9IG51bGw7XG4gICAgfVxuICAgIHRoaXMudHJhY2tlci5yZXNldCh7XG4gICAgICBwcm9taXNlTGlzdDogb3B0aW9ucy5idXN5LFxuICAgICAgZGVsYXk6IG9wdGlvbnMuZGVsYXksXG4gICAgICBtaW5EdXJhdGlvbjogb3B0aW9ucy5taW5EdXJhdGlvblxuICAgIH0pO1xuICAgIGNvbnN0IGluc3RhbmNlID0gdGhpcy5sb2FkaW5nQ21wdFJlZi5pbnN0YW5jZTtcbiAgICBpbnN0YW5jZS5tZXNzYWdlID0gb3B0aW9ucy5tZXNzYWdlO1xuICAgIGluc3RhbmNlLndyYXBwZXJDbGFzcyA9IG9wdGlvbnMud3JhcHBlckNsYXNzO1xuICAgIGluc3RhbmNlLnRlbXBsYXRlID0gb3B0aW9ucy50ZW1wbGF0ZTtcbiAgICByZXR1cm4gdGhpcy5sb2FkaW5nQ21wdFJlZjtcbiAgfVxuICB1cGRhdGUob3B0aW9ucykge1xuICAgIGNvbnN0IGluc3RhbmNlID0gdGhpcy5sb2FkaW5nQ21wdFJlZi5pbnN0YW5jZTtcbiAgICBpZiAob3B0aW9ucy5tZXNzYWdlKSBpbnN0YW5jZS5tZXNzYWdlID0gb3B0aW9ucy5tZXNzYWdlO1xuICAgIGlmIChvcHRpb25zLndyYXBwZXJDbGFzcykgaW5zdGFuY2Uud3JhcHBlckNsYXNzID0gb3B0aW9ucy53cmFwcGVyQ2xhc3M7XG4gICAgaWYgKG9wdGlvbnMudGVtcGxhdGUpIGluc3RhbmNlLnRlbXBsYXRlID0gb3B0aW9ucy50ZW1wbGF0ZTtcbiAgICByZXR1cm4gdGhpcy5sb2FkaW5nQ21wdFJlZjtcbiAgfVxuICBjbG9zZSgpIHtcbiAgICBpZiAodGhpcy5fZmFrZUJ1c3kpIHRoaXMuX2Zha2VCdXN5ID0gbnVsbDtcbiAgICBsZXQgb3B0aW9ucyA9IHRoaXMubm9ybWFsaXplT3B0aW9ucyh1bmRlZmluZWQpO1xuICAgIHRoaXMudHJhY2tlci5yZXNldCh7XG4gICAgICBwcm9taXNlTGlzdDogb3B0aW9ucy5idXN5LFxuICAgICAgZGVsYXk6IG9wdGlvbnMuZGVsYXksXG4gICAgICBtaW5EdXJhdGlvbjogb3B0aW9ucy5taW5EdXJhdGlvblxuICAgIH0pO1xuICAgIGNvbnN0IGluc3RhbmNlID0gdGhpcy5sb2FkaW5nQ21wdFJlZi5pbnN0YW5jZTtcbiAgICBpbnN0YW5jZS5tZXNzYWdlID0gb3B0aW9ucy5tZXNzYWdlO1xuICAgIGluc3RhbmNlLndyYXBwZXJDbGFzcyA9IG9wdGlvbnMud3JhcHBlckNsYXNzO1xuICAgIGluc3RhbmNlLnRlbXBsYXRlID0gb3B0aW9ucy50ZW1wbGF0ZTtcbiAgICByZXR1cm4gdGhpcy5sb2FkaW5nQ21wdFJlZjtcbiAgfVxuICB6SW5kZXgoekluZGV4OiBudW1iZXIgPSAyMDAwKSB7XG4gICAgbGV0IG5nQnVzeUJhY2tkcm9wID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcbiAgICAgICdkaXYubmctYnVzeS1iYWNrZHJvcCdcbiAgICApIGFzIEhUTUxFbGVtZW50O1xuICAgIGxldCBuZ0J1c3kgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdkaXYubmctYnVzeScpIGFzIEhUTUxFbGVtZW50O1xuICAgIGlmIChuZ0J1c3lCYWNrZHJvcCkge1xuICAgICAgbmdCdXN5QmFja2Ryb3Auc3R5bGUuekluZGV4ID0gJycgKyB6SW5kZXg7XG4gICAgfVxuICAgIGlmIChuZ0J1c3kpIHtcbiAgICAgIG5nQnVzeS5zdHlsZS56SW5kZXggPSAnJyArICh6SW5kZXggKyAxKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIG5vcm1hbGl6ZU9wdGlvbnMob3B0aW9uczogYW55KSB7XG4gICAgaWYgKCFvcHRpb25zKSB7XG4gICAgICBvcHRpb25zID0geyBidXN5OiBudWxsIH07XG4gICAgfSBlbHNlIGlmIChcbiAgICAgIEFycmF5LmlzQXJyYXkob3B0aW9ucykgfHxcbiAgICAgIG9wdGlvbnMgaW5zdGFuY2VvZiBQcm9taXNlIHx8XG4gICAgICBvcHRpb25zIGluc3RhbmNlb2YgU3Vic2NyaXB0aW9uXG4gICAgKSB7XG4gICAgICBvcHRpb25zID0geyBidXN5OiBvcHRpb25zIH07XG4gICAgfVxuICAgIG9wdGlvbnMgPSBPYmplY3QuYXNzaWduKHt9LCBuZXcgQnVzeUNvbmZpZygpLCBvcHRpb25zKTtcbiAgICBpZiAoIUFycmF5LmlzQXJyYXkob3B0aW9ucy5idXN5KSkge1xuICAgICAgb3B0aW9ucy5idXN5ID0gb3B0aW9ucy5idXN5ID8gW29wdGlvbnMuYnVzeV0gOiBbXTtcbiAgICB9XG5cbiAgICByZXR1cm4gb3B0aW9ucztcbiAgfVxufVxuIiwiaW1wb3J0IHsgTmdNb2R1bGUsIFJlbmRlcmVyMiB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQnVzeU1vZHVsZSB9IGZyb20gJy4vYnVzeS5tb2R1bGUnO1xuaW1wb3J0IHsgTG9hZGluZ1NlcnZpY2UgfSBmcm9tICcuL2xvYWRpbmcuc2VydmljZSc7XG5cbkBOZ01vZHVsZSh7XG4gIGltcG9ydHM6IFtCdXN5TW9kdWxlXSxcbiAgZGVjbGFyYXRpb25zOiBbXSxcbiAgcHJvdmlkZXJzOiBbTG9hZGluZ1NlcnZpY2VdLFxuICBleHBvcnRzOiBbQnVzeU1vZHVsZV1cbn0pXG5leHBvcnQgY2xhc3MgTG9hZGluZ01vZHVsZSB7fVxuIl0sIm5hbWVzIjpbImluYWN0aXZlU3R5bGUiLCJ0aW1pbmciXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7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