ng-dynami-social-login
Version:
This is social login API for Angular 7.0.3 (Facebook, Google and Linkedin)
530 lines (514 loc) • 45.7 kB
JavaScript
import { __extends } from 'tslib';
import { Injectable, NgModule } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
import { CommonModule } from '@angular/common';
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
*/
/**
* @abstract
*/
var /**
* @abstract
*/
BaseLoginProvider = /** @class */ (function () {
function BaseLoginProvider() {
}
/**
* @param {?} obj
* @param {?} onload
* @return {?}
*/
BaseLoginProvider.prototype.loadScript = /**
* @param {?} obj
* @param {?} onload
* @return {?}
*/
function (obj, onload) {
if (document.getElementById(obj.name)) {
return;
}
/** @type {?} */
var signInJS = document.createElement('script');
signInJS.async = true;
signInJS.src = obj.url;
signInJS.onload = onload;
if (obj.name === 'LINKEDIN') {
signInJS.async = false;
signInJS.text = ('api_key: ' + obj.id).replace('\'', '');
}
document.head.appendChild(signInJS);
};
return BaseLoginProvider;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
*/
var LinkedInResponseModel = /** @class */ (function () {
function LinkedInResponseModel() {
}
return LinkedInResponseModel;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
*/
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
*/
var LoginProviderClassModel = /** @class */ (function () {
function LoginProviderClassModel() {
}
return LoginProviderClassModel;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
*/
var SocialUserModel = /** @class */ (function () {
function SocialUserModel() {
}
return SocialUserModel;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
*/
var FacebookLoginProvider = /** @class */ (function (_super) {
__extends(FacebookLoginProvider, _super);
function FacebookLoginProvider(clientId) {
var _this = _super.call(this) || this;
_this.clientId = clientId;
_this.loginProviderObj = new LoginProviderClassModel();
_this.loginProviderObj.id = clientId;
_this.loginProviderObj.name = 'facebook';
_this.loginProviderObj.url = 'https://connect.facebook.net/en_US/sdk.js';
return _this;
}
/**
* @return {?}
*/
FacebookLoginProvider.prototype.initialize = /**
* @return {?}
*/
function () {
var _this = this;
return new Promise(function (resolve, reject) {
_this.loadScript(_this.loginProviderObj, function () {
FB.init({
appId: _this.clientId,
autoLogAppEvents: true,
cookie: true,
xfbml: true,
version: 'v2.10'
});
FB.AppEvents.logPageView();
FB.getLoginStatus(function (response) {
if (response.status === 'connected') {
/** @type {?} */
var accessToken_1 = FB.getAuthResponse()['accessToken'];
FB.api('/me?fields=name,email,picture', function (res) {
resolve(FacebookLoginProvider.drawUser(Object.assign({}, { token: accessToken_1 }, res)));
});
}
});
});
});
};
/**
* @param {?} response
* @return {?}
*/
FacebookLoginProvider.drawUser = /**
* @param {?} response
* @return {?}
*/
function (response) {
/** @type {?} */
var user = new SocialUserModel();
user.id = response.id;
user.name = response.name;
user.email = response.email;
user.token = response.token;
user.image = 'https://graph.facebook.com/' + response.id + '/picture?type=normal';
return user;
};
/**
* @return {?}
*/
FacebookLoginProvider.prototype.signIn = /**
* @return {?}
*/
function () {
return new Promise(function (resolve, reject) {
FB.login(function (response) {
if (response.authResponse) {
/** @type {?} */
var accessToken_2 = FB.getAuthResponse()['accessToken'];
FB.api('/me?fields=name,email,picture', function (res) {
resolve(FacebookLoginProvider.drawUser(Object.assign({}, { token: accessToken_2 }, res)));
});
}
}, { scope: 'email,public_profile' });
});
};
/**
* @return {?}
*/
FacebookLoginProvider.prototype.signOut = /**
* @return {?}
*/
function () {
return new Promise(function (resolve, reject) {
FB.logout(function (response) {
resolve();
});
});
};
FacebookLoginProvider.PROVIDER_ID = 'facebook';
return FacebookLoginProvider;
}(BaseLoginProvider));
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
*/
var GoogleLoginProvider = /** @class */ (function (_super) {
__extends(GoogleLoginProvider, _super);
function GoogleLoginProvider(clientId) {
var _this = _super.call(this) || this;
_this.clientId = clientId;
_this.loginProviderObj = new LoginProviderClassModel();
_this.loginProviderObj.id = clientId;
_this.loginProviderObj.name = 'google';
_this.loginProviderObj.url = 'https://apis.google.com/js/platform.js';
return _this;
}
/**
* @return {?}
*/
GoogleLoginProvider.prototype.initialize = /**
* @return {?}
*/
function () {
var _this = this;
return new Promise(function (resolve, reject) {
_this.loadScript(_this.loginProviderObj, function () {
gapi.load('auth2', function () {
_this.auth2 = gapi.auth2.init({
client_id: _this.clientId,
scope: 'email'
});
_this.auth2.then(function () {
if (_this.auth2.isSignedIn.get()) {
resolve(_this.drawUser());
}
});
});
});
});
};
/**
* @return {?}
*/
GoogleLoginProvider.prototype.drawUser = /**
* @return {?}
*/
function () {
/** @type {?} */
var user = new SocialUserModel();
/** @type {?} */
var profile = this.auth2.currentUser.get().getBasicProfile();
/** @type {?} */
var authResponseObj = this.auth2.currentUser.get().getAuthResponse(true);
user.id = profile.getId();
user.name = profile.getName();
user.email = profile.getEmail();
user.image = profile.getImageUrl();
user.token = authResponseObj.access_token;
user.idToken = authResponseObj.id_token;
return user;
};
/**
* @return {?}
*/
GoogleLoginProvider.prototype.signIn = /**
* @return {?}
*/
function () {
var _this = this;
return new Promise(function (resolve, reject) {
/** @type {?} */
var promise = _this.auth2.signIn();
promise.then(function () {
resolve(_this.drawUser());
});
});
};
/**
* @return {?}
*/
GoogleLoginProvider.prototype.signOut = /**
* @return {?}
*/
function () {
var _this = this;
return new Promise(function (resolve, reject) {
_this.auth2.signOut().then(function (err) {
if (err) {
reject(err);
}
else {
resolve();
}
});
});
};
GoogleLoginProvider.PROVIDER_ID = 'google';
return GoogleLoginProvider;
}(BaseLoginProvider));
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
*/
var LinkedinLoginProvider = /** @class */ (function (_super) {
__extends(LinkedinLoginProvider, _super);
function LinkedinLoginProvider(clientId) {
var _this = _super.call(this) || this;
_this.clientId = clientId;
_this.loginProviderObj = new LoginProviderClassModel();
_this.loginProviderObj.id = clientId;
_this.loginProviderObj.name = 'linkedin';
_this.loginProviderObj.url = 'https://platform.linkedin.com/in.js';
return _this;
}
/**
* @return {?}
*/
LinkedinLoginProvider.prototype.initialize = /**
* @return {?}
*/
function () {
var _this = this;
return new Promise(function (resolve, reject) {
_this.loadScript(_this.loginProviderObj, function () {
IN.init({
api_key: _this.clientId,
authorize: true,
onLoad: _this.onLinkedInLoad()
});
IN.Event.on(IN, 'auth', function () {
if (IN.User.isAuthorized()) {
IN.API.Raw('/people/~:(id,first-name,last-name,email-address,picture-url)').result(function (res) {
resolve(_this.drawUser(res));
});
}
});
});
});
};
/**
* @return {?}
*/
LinkedinLoginProvider.prototype.onLinkedInLoad = /**
* @return {?}
*/
function () {
IN.Event.on(IN, 'systemReady', function () {
IN.User.refresh();
});
};
/**
* @param {?} response
* @return {?}
*/
LinkedinLoginProvider.prototype.drawUser = /**
* @param {?} response
* @return {?}
*/
function (response) {
/** @type {?} */
var user = new SocialUserModel();
user.id = response.emailAddress;
user.name = response.firstName + ' ' + response.lastName;
user.email = response.emailAddress;
user.image = response.pictureUrl;
user.token = IN.ENV.auth.oauth_token;
return user;
};
/**
* @return {?}
*/
LinkedinLoginProvider.prototype.signIn = /**
* @return {?}
*/
function () {
var _this = this;
return new Promise(function (resolve, reject) {
IN.User.authorize(function () {
IN.API.Raw('/people/~:(id,first-name,last-name,email-address,picture-url)').result(function (res) {
resolve(_this.drawUser(res));
});
});
});
};
/**
* @return {?}
*/
LinkedinLoginProvider.prototype.signOut = /**
* @return {?}
*/
function () {
return new Promise(function (resolve, reject) {
IN.User.logout(function (response) {
resolve();
}, function (err) {
reject(err);
});
});
};
LinkedinLoginProvider.PROVIDER_ID = 'linkedin';
return LinkedinLoginProvider;
}(BaseLoginProvider));
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
*/
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
*/
var AuthServiceConfig = /** @class */ (function () {
function AuthServiceConfig(providers) {
this.providers = new Map();
for (var i = 0; i < providers.length; i++) {
/** @type {?} */
var element = providers[i];
this.providers.set(element.id, element.provider);
}
}
return AuthServiceConfig;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
*/
var AuthService = /** @class */ (function () {
function AuthService(config) {
var _this = this;
this._user = null;
this._authState = new BehaviorSubject(null);
this.providers = config.providers;
this.providers.forEach(function (provider, key) {
provider.initialize().then(function (user) {
user.provider = key;
_this._user = user;
_this._authState.next(user);
}).catch(function (err) {
// this._authState.next(null);
});
});
}
Object.defineProperty(AuthService.prototype, "authState", {
get: /**
* @return {?}
*/
function () {
return this._authState.asObservable();
},
enumerable: true,
configurable: true
});
/**
* @param {?} providerId
* @return {?}
*/
AuthService.prototype.signIn = /**
* @param {?} providerId
* @return {?}
*/
function (providerId) {
var _this = this;
return new Promise(function (resolve, reject) {
/** @type {?} */
var providerObject = _this.providers.get(providerId);
if (providerObject) {
providerObject.signIn().then(function (user) {
user.provider = providerId;
resolve(user);
_this._user = user;
_this._authState.next(user);
});
}
else {
reject(AuthService.LOGIN_PROVIDER_NOT_FOUND);
}
});
};
/**
* @return {?}
*/
AuthService.prototype.signOut = /**
* @return {?}
*/
function () {
var _this = this;
return new Promise(function (resolve, reject) {
if (_this._user && _this._user.provider) {
/** @type {?} */
var providerId = _this._user.provider;
/** @type {?} */
var providerObject = _this.providers.get(providerId);
providerObject.signOut().then(function () {
_this._user = null;
_this._authState.next(null);
resolve();
}).catch(function (err) {
_this._authState.next(null);
});
}
else {
reject(AuthService.LOGIN_PROVIDER_NOT_FOUND);
}
});
};
AuthService.LOGIN_PROVIDER_NOT_FOUND = 'Login provider not found';
AuthService.decorators = [
{ type: Injectable }
];
/** @nocollapse */
AuthService.ctorParameters = function () { return [
{ type: AuthServiceConfig }
]; };
return AuthService;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
*/
var DynamiSocialLoginModule = /** @class */ (function () {
function DynamiSocialLoginModule() {
}
DynamiSocialLoginModule.decorators = [
{ type: NgModule, args: [{
imports: [
CommonModule
],
declarations: [],
providers: [AuthService],
},] }
];
return DynamiSocialLoginModule;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
*/
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
*/
export { BaseLoginProvider, LinkedInResponseModel, LoginProviderClassModel, SocialUserModel, FacebookLoginProvider, GoogleLoginProvider, LinkedinLoginProvider, AuthServiceConfig, AuthService, DynamiSocialLoginModule };
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmctZHluYW1pLXNvY2lhbC1sb2dpbi5qcy5tYXAiLCJzb3VyY2VzIjpbIm5nOi8vbmctZHluYW1pLXNvY2lhbC1sb2dpbi9saWIvZHluYW1pLXNvY2lhbC1sb2dpbi9tb2RlbHMvYmFzZS5sb2dpbi5wcm92aWRlci50cyIsIm5nOi8vbmctZHluYW1pLXNvY2lhbC1sb2dpbi9saWIvZHluYW1pLXNvY2lhbC1sb2dpbi9tb2RlbHMvbGlua2VkaW4ucmVzcG9uc2UubW9kZWwudHMiLCJuZzovL25nLWR5bmFtaS1zb2NpYWwtbG9naW4vbGliL2R5bmFtaS1zb2NpYWwtbG9naW4vbW9kZWxzL2xvZ2luLnByb3ZpZGVyLmNsYXNzLm1vZGVsLnRzIiwibmc6Ly9uZy1keW5hbWktc29jaWFsLWxvZ2luL2xpYi9keW5hbWktc29jaWFsLWxvZ2luL21vZGVscy9zb2NpYWwudXNlci5tb2RlbC50cyIsIm5nOi8vbmctZHluYW1pLXNvY2lhbC1sb2dpbi9saWIvZHluYW1pLXNvY2lhbC1sb2dpbi9wcm92aWRlcnMvZmFjZWJvb2subG9naW4ucHJvdmlkZXIudHMiLCJuZzovL25nLWR5bmFtaS1zb2NpYWwtbG9naW4vbGliL2R5bmFtaS1zb2NpYWwtbG9naW4vcHJvdmlkZXJzL2dvb2dsZS5sb2dpbi5wcm92aWRlci50cyIsIm5nOi8vbmctZHluYW1pLXNvY2lhbC1sb2dpbi9saWIvZHluYW1pLXNvY2lhbC1sb2dpbi9wcm92aWRlcnMvbGlua2VkaW4ubG9naW4ucHJvdmlkZXIudHMiLCJuZzovL25nLWR5bmFtaS1zb2NpYWwtbG9naW4vbGliL2R5bmFtaS1zb2NpYWwtbG9naW4vc2VydmljZXMvYXV0aC5zZXJ2aWNlLmNvbmZpZy50cyIsIm5nOi8vbmctZHluYW1pLXNvY2lhbC1sb2dpbi9saWIvZHluYW1pLXNvY2lhbC1sb2dpbi9zZXJ2aWNlcy9hdXRoLnNlcnZpY2UudHMiLCJuZzovL25nLWR5bmFtaS1zb2NpYWwtbG9naW4vbGliL2R5bmFtaS1zb2NpYWwtbG9naW4vZHluYW1pLXNvY2lhbC1sb2dpbi5tb2R1bGUudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgU29jaWFsVXNlck1vZGVsIH0gZnJvbSBcIi4vc29jaWFsLnVzZXIubW9kZWxcIjtcclxuaW1wb3J0IHsgTG9naW5Qcm92aWRlciB9IGZyb20gXCIuL2xvZ2luLnByb3ZpZGVyXCI7XHJcbmltcG9ydCB7IExvZ2luUHJvdmlkZXJDbGFzc01vZGVsIH0gZnJvbSBcIi4vbG9naW4ucHJvdmlkZXIuY2xhc3MubW9kZWxcIjtcclxuXHJcblxyXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgQmFzZUxvZ2luUHJvdmlkZXIgaW1wbGVtZW50cyBMb2dpblByb3ZpZGVyIHtcclxuICBjb25zdHJ1Y3RvcigpIHt9XHJcblxyXG4gIGFic3RyYWN0IGluaXRpYWxpemUoKTogUHJvbWlzZTxTb2NpYWxVc2VyTW9kZWw+O1xyXG4gIGFic3RyYWN0IHNpZ25JbigpOiBQcm9taXNlPFNvY2lhbFVzZXJNb2RlbD47XHJcbiAgYWJzdHJhY3Qgc2lnbk91dCgpOiBQcm9taXNlPGFueT47XHJcblxyXG4gIGxvYWRTY3JpcHQob2JqOiBMb2dpblByb3ZpZGVyQ2xhc3NNb2RlbCwgb25sb2FkOiBhbnkpOiB2b2lkIHtcclxuICAgIGlmIChkb2N1bWVudC5nZXRFbGVtZW50QnlJZChvYmoubmFtZSkpIHsgcmV0dXJuOyB9XHJcbiAgICBsZXQgc2lnbkluSlMgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzY3JpcHQnKTtcclxuICAgIHNpZ25JbkpTLmFzeW5jID0gdHJ1ZTtcclxuICAgIHNpZ25JbkpTLnNyYyA9IG9iai51cmw7XHJcbiAgICBzaWduSW5KUy5vbmxvYWQgPSBvbmxvYWQ7XHJcbiAgICBpZiAob2JqLm5hbWUgPT09ICdMSU5LRURJTicpIHtcclxuICAgICAgc2lnbkluSlMuYXN5bmMgPSBmYWxzZTtcclxuICAgICAgc2lnbkluSlMudGV4dCA9ICgnYXBpX2tleTogJyArIG9iai5pZCkucmVwbGFjZSgnXFwnJywgJycpO1xyXG4gICAgfVxyXG4gICAgZG9jdW1lbnQuaGVhZC5hcHBlbmRDaGlsZChzaWduSW5KUyk7XHJcbiAgfVxyXG59IiwiZXhwb3J0IGNsYXNzIExpbmtlZEluUmVzcG9uc2VNb2RlbCB7XHJcbiAgICBlbWFpbEFkZHJlc3M6IHN0cmluZztcclxuICAgIGZpcnN0TmFtZTogc3RyaW5nO1xyXG4gICAgaWQ6IHN0cmluZztcclxuICAgIGxhc3ROYW1lOiBzdHJpbmc7XHJcbiAgICBwaWN0dXJlVXJsOiBzdHJpbmc7XHJcbiAgfSIsImV4cG9ydCBjbGFzcyBMb2dpblByb3ZpZGVyQ2xhc3NNb2RlbCB7XHJcbiAgICBuYW1lOiBzdHJpbmc7XHJcbiAgICBpZDogc3RyaW5nO1xyXG4gICAgdXJsOiBzdHJpbmc7XHJcbiAgfSIsImV4cG9ydCBjbGFzcyBTb2NpYWxVc2VyTW9kZWwge1xyXG4gICAgcHJvdmlkZXI6IHN0cmluZztcclxuICAgIGlkOiBzdHJpbmc7XHJcbiAgICBlbWFpbDogc3RyaW5nO1xyXG4gICAgbmFtZTogc3RyaW5nO1xyXG4gICAgaW1hZ2U6IHN0cmluZztcclxuICAgIHRva2VuPzogc3RyaW5nO1xyXG4gICAgaWRUb2tlbj86IHN0cmluZ1xyXG4gIH1cclxuICBcclxuXHJcbiAgXHJcbiIsImltcG9ydCB7IEJhc2VMb2dpblByb3ZpZGVyIH0gZnJvbSBcIi4uL21vZGVscy9iYXNlLmxvZ2luLnByb3ZpZGVyXCI7XHJcbmltcG9ydCB7IExvZ2luUHJvdmlkZXJDbGFzc01vZGVsIH0gZnJvbSBcIi4uL21vZGVscy9sb2dpbi5wcm92aWRlci5jbGFzcy5tb2RlbFwiO1xyXG5pbXBvcnQgeyBTb2NpYWxVc2VyTW9kZWwgfSBmcm9tIFwiLi4vbW9kZWxzL3NvY2lhbC51c2VyLm1vZGVsXCI7XHJcblxyXG5cclxuZGVjbGFyZSBsZXQgRkI6IGFueTtcclxuXHJcbmV4cG9ydCBjbGFzcyBGYWNlYm9va0xvZ2luUHJvdmlkZXIgZXh0ZW5kcyBCYXNlTG9naW5Qcm92aWRlciB7XHJcblxyXG4gIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgUFJPVklERVJfSUQgPSAnZmFjZWJvb2snO1xyXG4gIHB1YmxpYyBsb2dpblByb3ZpZGVyT2JqOiBMb2dpblByb3ZpZGVyQ2xhc3NNb2RlbCA9IG5ldyBMb2dpblByb3ZpZGVyQ2xhc3NNb2RlbCgpO1xyXG5cclxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIGNsaWVudElkOiBzdHJpbmcpIHtcclxuICAgIHN1cGVyKCk7XHJcbiAgICB0aGlzLmxvZ2luUHJvdmlkZXJPYmouaWQgPSBjbGllbnRJZDtcclxuICAgIHRoaXMubG9naW5Qcm92aWRlck9iai5uYW1lID0gJ2ZhY2Vib29rJztcclxuICAgIHRoaXMubG9naW5Qcm92aWRlck9iai51cmwgPSAnaHR0cHM6Ly9jb25uZWN0LmZhY2Vib29rLm5ldC9lbl9VUy9zZGsuanMnO1xyXG4gIH1cclxuXHJcbiAgaW5pdGlhbGl6ZSgpOiBQcm9taXNlPFNvY2lhbFVzZXJNb2RlbD4ge1xyXG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcclxuICAgICAgdGhpcy5sb2FkU2NyaXB0KHRoaXMubG9naW5Qcm92aWRlck9iaiwgKCkgPT4ge1xyXG4gICAgICAgICAgRkIuaW5pdCh7XHJcbiAgICAgICAgICAgIGFwcElkOiB0aGlzLmNsaWVudElkLFxyXG4gICAgICAgICAgICBhdXRvTG9nQXBwRXZlbnRzOiB0cnVlLFxyXG4gICAgICAgICAgICBjb29raWU6IHRydWUsXHJcbiAgICAgICAgICAgIHhmYm1sOiB0cnVlLFxyXG4gICAgICAgICAgICB2ZXJzaW9uOiAndjIuMTAnXHJcbiAgICAgICAgICB9KTtcclxuICAgICAgICAgIEZCLkFwcEV2ZW50cy5sb2dQYWdlVmlldygpO1xyXG5cclxuICAgICAgICAgIEZCLmdldExvZ2luU3RhdHVzKGZ1bmN0aW9uIChyZXNwb25zZTogYW55KSB7XHJcbiAgICAgICAgICAgIGlmIChyZXNwb25zZS5zdGF0dXMgPT09ICdjb25uZWN0ZWQnKSB7XHJcbiAgICAgICAgICAgICAgY29uc3QgYWNjZXNzVG9rZW4gPSBGQi5nZXRBdXRoUmVzcG9uc2UoKVsnYWNjZXNzVG9rZW4nXTtcclxuICAgICAgICAgICAgICBGQi5hcGkoJy9tZT9maWVsZHM9bmFtZSxlbWFpbCxwaWN0dXJlJywgKHJlczogYW55KSA9PiB7XHJcbiAgICAgICAgICAgICAgICByZXNvbHZlKEZhY2Vib29rTG9naW5Qcm92aWRlci5kcmF3VXNlcihPYmplY3QuYXNzaWduKHt9LCB7dG9rZW46IGFjY2Vzc1Rva2VufSwgcmVzKSkpO1xyXG4gICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICB9KTtcclxuICAgICAgICB9KTtcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgc3RhdGljIGRyYXdVc2VyKHJlc3BvbnNlOiBhbnkpOiBTb2NpYWxVc2VyTW9kZWwge1xyXG4gICAgbGV0IHVzZXI6IFNvY2lhbFVzZXJNb2RlbCA9IG5ldyBTb2NpYWxVc2VyTW9kZWwoKTtcclxuICAgIHVzZXIuaWQgPSByZXNwb25zZS5pZDtcclxuICAgIHVzZXIubmFtZSA9IHJlc3BvbnNlLm5hbWU7XHJcbiAgICB1c2VyLmVtYWlsID0gcmVzcG9uc2UuZW1haWw7XHJcbiAgICB1c2VyLnRva2VuID0gcmVzcG9uc2UudG9rZW47XHJcbiAgICB1c2VyLmltYWdlID0gJ2h0dHBzOi8vZ3JhcGguZmFjZWJvb2suY29tLycgKyByZXNwb25zZS5pZCArICcvcGljdHVyZT90eXBlPW5vcm1hbCc7XHJcbiAgICByZXR1cm4gdXNlcjtcclxuICB9XHJcblxyXG4gIHNpZ25JbigpOiBQcm9taXNlPFNvY2lhbFVzZXJNb2RlbD4ge1xyXG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcclxuICAgICAgRkIubG9naW4oKHJlc3BvbnNlOiBhbnkpID0+IHtcclxuICAgICAgICBpZiAocmVzcG9uc2UuYXV0aFJlc3BvbnNlKSB7XHJcbiAgICAgICAgICBjb25zdCBhY2Nlc3NUb2tlbiA9IEZCLmdldEF1dGhSZXNwb25zZSgpWydhY2Nlc3NUb2tlbiddO1xyXG4gICAgICAgICAgRkIuYXBpKCcvbWU/ZmllbGRzPW5hbWUsZW1haWwscGljdHVyZScsIChyZXM6IGFueSkgPT4ge1xyXG4gICAgICAgICAgICByZXNvbHZlKEZhY2Vib29rTG9naW5Qcm92aWRlci5kcmF3VXNlcihPYmplY3QuYXNzaWduKHt9LCB7dG9rZW46IGFjY2Vzc1Rva2VufSwgcmVzKSkpO1xyXG4gICAgICAgICAgfSk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9LCB7IHNjb3BlOiAnZW1haWwscHVibGljX3Byb2ZpbGUnIH0pO1xyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICBzaWduT3V0KCk6IFByb21pc2U8YW55PiB7XHJcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xyXG4gICAgICBGQi5sb2dvdXQoKHJlc3BvbnNlOiBhbnkpID0+IHtcclxuICAgICAgICByZXNvbHZlKCk7XHJcbiAgICAgIH0pO1xyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxufVxyXG4iLCJpbXBvcnQgeyBCYXNlTG9naW5Qcm92aWRlciB9IGZyb20gXCIuLi9tb2RlbHMvYmFzZS5sb2dpbi5wcm92aWRlclwiO1xyXG5pbXBvcnQgeyBMb2dpblByb3ZpZGVyQ2xhc3NNb2RlbCB9IGZyb20gXCIuLi9tb2RlbHMvbG9naW4ucHJvdmlkZXIuY2xhc3MubW9kZWxcIjtcclxuaW1wb3J0IHsgU29jaWFsVXNlck1vZGVsIH0gZnJvbSBcIi4uL21vZGVscy9zb2NpYWwudXNlci5tb2RlbFwiO1xyXG5cclxuXHJcbmRlY2xhcmUgbGV0IGdhcGk6IGFueTtcclxuXHJcbmV4cG9ydCBjbGFzcyBHb29nbGVMb2dpblByb3ZpZGVyIGV4dGVuZHMgQmFzZUxvZ2luUHJvdmlkZXIge1xyXG5cclxuICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IFBST1ZJREVSX0lEID0gJ2dvb2dsZSc7XHJcbiAgcHVibGljIGxvZ2luUHJvdmlkZXJPYmo6IExvZ2luUHJvdmlkZXJDbGFzc01vZGVsID0gbmV3IExvZ2luUHJvdmlkZXJDbGFzc01vZGVsKCk7XHJcbiAgcHJpdmF0ZSBhdXRoMjogYW55O1xyXG5cclxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIGNsaWVudElkOiBzdHJpbmcpIHtcclxuICAgIHN1cGVyKCk7XHJcbiAgICB0aGlzLmxvZ2luUHJvdmlkZXJPYmouaWQgPSBjbGllbnRJZDtcclxuICAgIHRoaXMubG9naW5Qcm92aWRlck9iai5uYW1lID0gJ2dvb2dsZSc7XHJcbiAgICB0aGlzLmxvZ2luUHJvdmlkZXJPYmoudXJsID0gJ2h0dHBzOi8vYXBpcy5nb29nbGUuY29tL2pzL3BsYXRmb3JtLmpzJztcclxuICB9XHJcblxyXG4gIGluaXRpYWxpemUoKTogUHJvbWlzZTxTb2NpYWxVc2VyTW9kZWw+IHtcclxuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XHJcbiAgICAgIHRoaXMubG9hZFNjcmlwdCh0aGlzLmxvZ2luUHJvdmlkZXJPYmosICgpID0+IHtcclxuICAgICAgICAgIGdhcGkubG9hZCgnYXV0aDInLCAoKSA9PiB7XHJcbiAgICAgICAgICAgIHRoaXMuYXV0aDIgPSBnYXBpLmF1dGgyLmluaXQoe1xyXG4gICAgICAgICAgICAgIGNsaWVudF9pZDogdGhpcy5jbGllbnRJZCxcclxuICAgICAgICAgICAgICBzY29wZTogJ2VtYWlsJ1xyXG4gICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgICAgIHRoaXMuYXV0aDIudGhlbigoKSA9PiB7XHJcbiAgICAgICAgICAgICAgaWYgKHRoaXMuYXV0aDIuaXNTaWduZWRJbi5nZXQoKSkge1xyXG4gICAgICAgICAgICAgICAgcmVzb2x2ZSh0aGlzLmRyYXdVc2VyKCkpO1xyXG4gICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICB9KTtcclxuICAgICAgfSk7XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIGRyYXdVc2VyKCk6IFNvY2lhbFVzZXJNb2RlbCB7XHJcbiAgICBsZXQgdXNlcjogU29jaWFsVXNlck1vZGVsID0gbmV3IFNvY2lhbFVzZXJNb2RlbCgpO1xyXG4gICAgbGV0IHByb2ZpbGUgPSB0aGlzLmF1dGgyLmN1cnJlbnRVc2VyLmdldCgpLmdldEJhc2ljUHJvZmlsZSgpO1xyXG4gICAgbGV0IGF1dGhSZXNwb25zZU9iaiA9IHRoaXMuYXV0aDIuY3VycmVudFVzZXIuZ2V0KCkuZ2V0QXV0aFJlc3BvbnNlKHRydWUpO1xyXG4gICAgdXNlci5pZCA9IHByb2ZpbGUuZ2V0SWQoKTtcclxuICAgIHVzZXIubmFtZSA9IHByb2ZpbGUuZ2V0TmFtZSgpO1xyXG4gICAgdXNlci5lbWFpbCA9IHByb2ZpbGUuZ2V0RW1haWwoKTtcclxuICAgIHVzZXIuaW1hZ2UgPSBwcm9maWxlLmdldEltYWdlVXJsKCk7XHJcbiAgICB1c2VyLnRva2VuID0gYXV0aFJlc3BvbnNlT2JqLmFjY2Vzc190b2tlbjtcclxuICAgIHVzZXIuaWRUb2tlbiA9IGF1dGhSZXNwb25zZU9iai5pZF90b2tlbjtcclxuICAgIHJldHVybiB1c2VyO1xyXG4gIH1cclxuXHJcbiAgc2lnbkluKCk6IFByb21pc2U8U29jaWFsVXNlck1vZGVsPiB7XHJcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xyXG4gICAgICBsZXQgcHJvbWlzZSA9IHRoaXMuYXV0aDIuc2lnbkluKCk7XHJcbiAgICAgIHByb21pc2UudGhlbigoKSA9PiB7XHJcbiAgICAgICAgcmVzb2x2ZSh0aGlzLmRyYXdVc2VyKCkpO1xyXG4gICAgICB9KTtcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgc2lnbk91dCgpOiBQcm9taXNlPGFueT4ge1xyXG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcclxuICAgICAgdGhpcy5hdXRoMi5zaWduT3V0KCkudGhlbigoZXJyOiBhbnkpID0+IHtcclxuICAgICAgICBpZiAoZXJyKSB7XHJcbiAgICAgICAgICByZWplY3QoZXJyKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgcmVzb2x2ZSgpO1xyXG4gICAgICAgIH1cclxuICAgICAgfSk7XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG59XHJcbiIsImltcG9ydCB7IEJhc2VMb2dpblByb3ZpZGVyIH0gZnJvbSBcIi4uL21vZGVscy9iYXNlLmxvZ2luLnByb3ZpZGVyXCI7XHJcbmltcG9ydCB7IExvZ2luUHJvdmlkZXJDbGFzc01vZGVsIH0gZnJvbSBcIi4uL21vZGVscy9sb2dpbi5wcm92aWRlci5jbGFzcy5tb2RlbFwiO1xyXG5pbXBvcnQgeyBTb2NpYWxVc2VyTW9kZWwgfSBmcm9tIFwiLi4vbW9kZWxzL3NvY2lhbC51c2VyLm1vZGVsXCI7XHJcbmltcG9ydCB7IExpbmtlZEluUmVzcG9uc2VNb2RlbCB9IGZyb20gXCIuLi9tb2RlbHMvbGlua2VkaW4ucmVzcG9uc2UubW9kZWxcIjtcclxuXHJcblxyXG5kZWNsYXJlIGxldCBJTjogYW55O1xyXG5cclxuZXhwb3J0IGNsYXNzIExpbmtlZGluTG9naW5Qcm92aWRlciBleHRlbmRzIEJhc2VMb2dpblByb3ZpZGVyIHtcclxuXHJcbiAgcHVibGljIHN0YXRpYyByZWFkb25seSBQUk9WSURFUl9JRCA9ICdsaW5rZWRpbic7XHJcbiAgcHVibGljIGxvZ2luUHJvdmlkZXJPYmo6IExvZ2luUHJvdmlkZXJDbGFzc01vZGVsID0gbmV3IExvZ2luUHJvdmlkZXJDbGFzc01vZGVsKCk7XHJcblxyXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgY2xpZW50SWQ6IHN0cmluZykge1xyXG4gICAgc3VwZXIoKTtcclxuICAgIHRoaXMubG9naW5Qcm92aWRlck9iai5pZCA9IGNsaWVudElkO1xyXG4gICAgdGhpcy5sb2dpblByb3ZpZGVyT2JqLm5hbWUgPSAnbGlua2VkaW4nO1xyXG4gICAgdGhpcy5sb2dpblByb3ZpZGVyT2JqLnVybCA9ICdodHRwczovL3BsYXRmb3JtLmxpbmtlZGluLmNvbS9pbi5qcyc7XHJcbiAgfVxyXG5cclxuICBpbml0aWFsaXplKCk6IFByb21pc2U8U29jaWFsVXNlck1vZGVsPiB7XHJcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xyXG4gICAgICB0aGlzLmxvYWRTY3JpcHQodGhpcy5sb2dpblByb3ZpZGVyT2JqLCAoKSA9PiB7XHJcbiAgICAgICAgICBJTi5pbml0KHtcclxuICAgICAgICAgICAgYXBpX2tleTogdGhpcy5jbGllbnRJZCxcclxuICAgICAgICAgICAgYXV0aG9yaXplOiB0cnVlLFxyXG4gICAgICAgICAgICBvbkxvYWQ6IHRoaXMub25MaW5rZWRJbkxvYWQoKVxyXG4gICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgSU4uRXZlbnQub24oSU4sICdhdXRoJywgKCkgPT4ge1xyXG4gICAgICAgICAgICBpZiAoSU4uVXNlci5pc0F1dGhvcml6ZWQoKSkge1xyXG4gICAgICAgICAgICAgIElOLkFQSS5SYXcoXHJcbiAgICAgICAgICAgICAgICAnL3Blb3BsZS9+OihpZCxmaXJzdC1uYW1lLGxhc3QtbmFtZSxlbWFpbC1hZGRyZXNzLHBpY3R1cmUtdXJsKSdcclxuICAgICAgICAgICAgICApLnJlc3VsdCggKHJlczogTGlua2VkSW5SZXNwb25zZU1vZGVsKSA9PiB7XHJcbiAgICAgICAgICAgICAgICByZXNvbHZlKHRoaXMuZHJhd1VzZXIocmVzKSk7XHJcbiAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICB9KTtcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgb25MaW5rZWRJbkxvYWQoKSB7XHJcbiAgICBJTi5FdmVudC5vbihJTiwgJ3N5c3RlbVJlYWR5JywgKCkgPT4ge1xyXG4gICAgICBJTi5Vc2VyLnJlZnJlc2goKTtcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgZHJhd1VzZXIocmVzcG9uc2U6IExpbmtlZEluUmVzcG9uc2VNb2RlbCk6IFNvY2lhbFVzZXJNb2RlbCB7XHJcbiAgICBsZXQgdXNlcjogU29jaWFsVXNlck1vZGVsID0gbmV3IFNvY2lhbFVzZXJNb2RlbCgpO1xyXG4gICAgdXNlci5pZCA9IHJlc3BvbnNlLmVtYWlsQWRkcmVzcztcclxuICAgIHVzZXIubmFtZSA9IHJlc3BvbnNlLmZpcnN0TmFtZSArICcgJyArIHJlc3BvbnNlLmxhc3ROYW1lO1xyXG4gICAgdXNlci5lbWFpbCA9IHJlc3BvbnNlLmVtYWlsQWRkcmVzcztcclxuICAgIHVzZXIuaW1hZ2UgPSByZXNwb25zZS5waWN0dXJlVXJsO1xyXG4gICAgdXNlci50b2tlbiA9IElOLkVOVi5hdXRoLm9hdXRoX3Rva2VuO1xyXG4gICAgcmV0dXJuIHVzZXI7XHJcbiAgfVxyXG5cclxuICBzaWduSW4oKTogUHJvbWlzZTxTb2NpYWxVc2VyTW9kZWw+IHtcclxuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XHJcbiAgICAgIElOLlVzZXIuYXV0aG9yaXplKCAoKSA9PiB7XHJcbiAgICAgICAgSU4uQVBJLlJhdygnL3Blb3BsZS9+OihpZCxmaXJzdC1uYW1lLGxhc3QtbmFtZSxlbWFpbC1hZGRyZXNzLHBpY3R1cmUtdXJsKScpLnJlc3VsdCggKHJlczogTGlua2VkSW5SZXNwb25zZU1vZGVsKSA9PiB7XHJcbiAgICAgICAgICByZXNvbHZlKHRoaXMuZHJhd1VzZXIocmVzKSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgIH0pO1xyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICBzaWduT3V0KCk6IFByb21pc2U8YW55PiB7XHJcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xyXG4gICAgICBJTi5Vc2VyLmxvZ291dCgocmVzcG9uc2U6IGFueSkgPT4ge1xyXG4gICAgICAgIHJlc29sdmUoKTtcclxuICAgICAgfSwgKGVycjogYW55KSA9PiB7XHJcbiAgICAgICAgcmVqZWN0KGVycik7XHJcbiAgICAgIH0pO1xyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxufVxyXG4iLCJpbXBvcnQgeyBMb2dpblByb3ZpZGVyIH0gZnJvbSBcIi4uL21vZGVscy9sb2dpbi5wcm92aWRlclwiO1xyXG5pbXBvcnQgeyBBdXRoU2VydmljZUNvbmZpZ0l0ZW0gfSBmcm9tIFwiLi9hdXRoLnNlcnZpY2UuY29uZmlnLml0ZW1cIjtcclxuXHJcbmV4cG9ydCBjbGFzcyBBdXRoU2VydmljZUNvbmZpZyB7XHJcbiAgICBwcm92aWRlcnM6IE1hcDxzdHJpbmcsIExvZ2luUHJvdmlkZXI+ID0gbmV3IE1hcDxzdHJpbmcsIExvZ2luUHJvdmlkZXI+KCk7XHJcbiAgXHJcbiAgICBjb25zdHJ1Y3Rvcihwcm92aWRlcnM6IEF1dGhTZXJ2aWNlQ29uZmlnSXRlbVtdKSB7XHJcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcHJvdmlkZXJzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgbGV0IGVsZW1lbnQgPSBwcm92aWRlcnNbaV07XHJcbiAgICAgICAgdGhpcy5wcm92aWRlcnMuc2V0KGVsZW1lbnQuaWQsIGVsZW1lbnQucHJvdmlkZXIpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfSIsImltcG9ydCB7IEluamVjdGFibGUgfSBmcm9tIFwiQGFuZ3VsYXIvY29yZVwiO1xyXG5pbXBvcnQgeyBCZWhhdmlvclN1YmplY3QsIE9ic2VydmFibGUgfSBmcm9tIFwicnhqc1wiO1xyXG5pbXBvcnQgeyBMb2dpblByb3ZpZGVyIH0gZnJvbSBcIi4uL21vZGVscy9sb2dpbi5wcm92aWRlclwiO1xyXG5pbXBvcnQgeyBTb2NpYWxVc2VyTW9kZWwgfSBmcm9tIFwiLi4vbW9kZWxzL3NvY2lhbC51c2VyLm1vZGVsXCI7XHJcbmltcG9ydCB7IEF1dGhTZXJ2aWNlQ29uZmlnIH0gZnJvbSBcIi4vYXV0aC5zZXJ2aWNlLmNvbmZpZ1wiO1xyXG5cclxuXHJcbkBJbmplY3RhYmxlKClcclxuZXhwb3J0IGNsYXNzIEF1dGhTZXJ2aWNlIHtcclxuXHJcbiAgcHJpdmF0ZSBzdGF0aWMgcmVhZG9ubHkgTE9HSU5fUFJPVklERVJfTk9UX0ZPVU5EID0gJ0xvZ2luIHByb3ZpZGVyIG5vdCBmb3VuZCc7XHJcblxyXG4gIHByaXZhdGUgcHJvdmlkZXJzOiBNYXA8c3RyaW5nLCBMb2dpblByb3ZpZGVyPjtcclxuXHJcbiAgcHJpdmF0ZSBfdXNlcjogU29jaWFsVXNlck1vZGVsID0gbnVsbDtcclxuICBwcml2YXRlIF9hdXRoU3RhdGU6IEJlaGF2aW9yU3ViamVjdDxTb2NpYWxVc2VyTW9kZWw+ID0gbmV3IEJlaGF2aW9yU3ViamVjdChudWxsKTtcclxuXHJcbiAgZ2V0IGF1dGhTdGF0ZSgpOiBPYnNlcnZhYmxlPFNvY2lhbFVzZXJNb2RlbD4ge1xyXG4gICAgcmV0dXJuIHRoaXMuX2F1dGhTdGF0ZS5hc09ic2VydmFibGUoKTtcclxuICB9XHJcblxyXG4gIGNvbnN0cnVjdG9yKGNvbmZpZzogQXV0aFNlcnZpY2VDb25maWcpIHtcclxuICAgIHRoaXMucHJvdmlkZXJzID0gY29uZmlnLnByb3ZpZGVycztcclxuICAgIHRoaXMucHJvdmlkZXJzLmZvckVhY2goKHByb3ZpZGVyOiBMb2dpblByb3ZpZGVyLCBrZXk6IHN0cmluZykgPT4ge1xyXG4gICAgICBwcm92aWRlci5pbml0aWFsaXplKCkudGhlbigodXNlcjogU29jaWFsVXNlck1vZGVsKSA9PiB7XHJcbiAgICAgICAgdXNlci5wcm92aWRlciA9IGtleTtcclxuICAgICAgICB0aGlzLl91c2VyID0gdXNlcjtcclxuICAgICAgICB0aGlzLl9hdXRoU3RhdGUubmV4dCh1c2VyKTtcclxuICAgICAgfSkuY2F0Y2goKGVycikgPT4ge1xyXG4gICAgICAgIC8vIHRoaXMuX2F1dGhTdGF0ZS5uZXh0KG51bGwpO1xyXG4gICAgICB9KTtcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgc2lnbkluKHByb3ZpZGVySWQ6IHN0cmluZyk6IFByb21pc2U8U29jaWFsVXNlck1vZGVsPiB7XHJcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xyXG4gICAgICBsZXQgcHJvdmlkZXJPYmplY3QgPSB0aGlzLnByb3ZpZGVycy5nZXQocHJvdmlkZXJJZCk7XHJcbiAgICAgIGlmIChwcm92aWRlck9iamVjdCkge1xyXG4gICAgICAgIHByb3ZpZGVyT2JqZWN0LnNpZ25JbigpLnRoZW4oKHVzZXI6IFNvY2lhbFVzZXJNb2RlbCkgPT4ge1xyXG4gICAgICAgICAgdXNlci5wcm92aWRlciA9IHByb3ZpZGVySWQ7XHJcbiAgICAgICAgICByZXNvbHZlKHVzZXIpO1xyXG4gICAgICAgICAgdGhpcy5fdXNlciA9IHVzZXI7XHJcbiAgICAgICAgICB0aGlzLl9hdXRoU3RhdGUubmV4dCh1c2VyKTtcclxuICAgICAgICB9KTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICByZWplY3QoQXV0aFNlcnZpY2UuTE9HSU5fUFJPVklERVJfTk9UX0ZPVU5EKTtcclxuICAgICAgfVxyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICBzaWduT3V0KCk6IFByb21pc2U8YW55PiB7XHJcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xyXG4gICAgICBpZiAodGhpcy5fdXNlciAmJiB0aGlzLl91c2VyLnByb3ZpZGVyKSB7XHJcbiAgICAgICAgbGV0IHByb3ZpZGVySWQgPSB0aGlzLl91c2VyLnByb3ZpZGVyO1xyXG4gICAgICAgIGxldCBwcm92aWRlck9iamVjdCA9IHRoaXMucHJvdmlkZXJzLmdldChwcm92aWRlcklkKTtcclxuICAgICAgICBwcm92aWRlck9iamVjdC5zaWduT3V0KCkudGhlbigoKSA9PiB7XHJcbiAgICAgICAgICB0aGlzLl91c2VyID0gbnVsbDtcclxuICAgICAgICAgIHRoaXMuX2F1dGhTdGF0ZS5uZXh0KG51bGwpO1xyXG4gICAgICAgICAgcmVzb2x2ZSgpO1xyXG4gICAgICAgIH0pLmNhdGNoKChlcnIpID0+IHtcclxuICAgICAgICAgIHRoaXMuX2F1dGhTdGF0ZS5uZXh0KG51bGwpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIHJlamVjdChBdXRoU2VydmljZS5MT0dJTl9QUk9WSURFUl9OT1RfRk9VTkQpO1xyXG4gICAgICB9XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG59IiwiaW1wb3J0IHsgTmdNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IENvbW1vbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQgeyBBdXRoU2VydmljZSB9IGZyb20gJy4vc2VydmljZXMvYXV0aC5zZXJ2aWNlJztcblxuQE5nTW9kdWxlKHtcbiAgaW1wb3J0czogW1xuICAgIENvbW1vbk1vZHVsZVxuICBdLFxuICBkZWNsYXJhdGlvbnM6IFtdLFxuICBwcm92aWRlcnM6IFtBdXRoU2VydmljZV0sXG59KVxuZXhwb3J0IGNsYXNzIER5bmFtaVNvY2lhbExvZ2luTW9kdWxlIHsgfVxuIl0sIm5hbWVzIjpbInRzbGliXzEuX19leHRlbmRzIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7QUFLQTs7OztJQUNFO0tBQWdCOzs7Ozs7SUFNaEIsc0NBQVU7Ozs7O0lBQVYsVUFBVyxHQUE0QixFQUFFLE1BQVc7UUFDbEQsSUFBSSxRQUFRLENBQUMsY0FBYyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRTtZQUFFLE9BQU87U0FBRTs7WUFDOUMsUUFBUSxHQUFHLFFBQVEsQ0FBQyxhQUFhLENBQUMsUUFBUSxDQUFDO1FBQy9DLFFBQVEsQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDO1FBQ3RCLFFBQVEsQ0FBQyxHQUFHLEdBQUcsR0FBRyxDQUFDLEdBQUcsQ0FBQztRQUN2QixRQUFRLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQztRQUN6QixJQUFJLEdBQUcsQ0FBQyxJQUFJLEtBQUssVUFBVSxFQUFFO1lBQzNCLFFBQVEsQ0FBQyxLQUFLLEdBQUcsS0FBSyxDQUFDO1lBQ3ZCLFFBQVEsQ0FBQyxJQUFJLEdBQUcsQ0FBQyxXQUFXLEdBQUcsR0FBRyxDQUFDLEVBQUUsRUFBRSxPQUFPLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxDQUFDO1NBQzFEO1FBQ0QsUUFBUSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsUUFBUSxDQUFDLENBQUM7S0FDckM7SUFDSCx3QkFBQztDQUFBOzs7Ozs7QUN4QkQ7SUFBQTtLQU1HO0lBQUQsNEJBQUM7Q0FBQTs7Ozs7Ozs7Ozs7QUNOSDtJQUFBO0tBSUc7SUFBRCw4QkFBQztDQUFBOzs7Ozs7QUNKSDtJQUFBO0tBUUc7SUFBRCxzQkFBQztDQUFBOzs7Ozs7O0lDRHdDQSx5Q0FBaUI7SUFLMUQsK0JBQW9CLFFBQWdCO1FBQXBDLFlBQ0UsaUJBQU8sU0FJUjtRQUxtQixjQUFRLEdBQVIsUUFBUSxDQUFRO1FBRjdCLHNCQUFnQixHQUE0QixJQUFJLHVCQUF1QixFQUFFLENBQUM7UUFJL0UsS0FBSSxDQUFDLGdCQUFnQixDQUFDLEVBQUUsR0FBRyxRQUFRLENBQUM7UUFDcEMsS0FBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksR0FBRyxVQUFVLENBQUM7UUFDeEMsS0FBSSxDQUFDLGdCQUFnQixDQUFDLEdBQUcsR0FBRywyQ0FBMkMsQ0FBQzs7S0FDekU7Ozs7SUFFRCwwQ0FBVTs7O0lBQVY7UUFBQSxpQkFzQkM7UUFyQkMsT0FBTyxJQUFJLE9BQU8sQ0FBQyxVQUFDLE9BQU8sRUFBRSxNQUFNO1lBQ2pDLEtBQUksQ0FBQyxVQUFVLENBQUMsS0FBSSxDQUFDLGdCQUFnQixFQUFFO2dCQUNuQyxFQUFFLENBQUMsSUFBSSxDQUFDO29CQUNOLEtBQUssRUFBRSxLQUFJLENBQUMsUUFBUTtvQkFDcEIsZ0JBQWdCLEVBQUUsSUFBSTtvQkFDdEIsTUFBTSxFQUFFLElBQUk7b0JBQ1osS0FBSyxFQUFFLElBQUk7b0JBQ1gsT0FBTyxFQUFFLE9BQU87aUJBQ2pCLENBQUMsQ0FBQztnQkFDSCxFQUFFLENBQUMsU0FBUyxDQUFDLFdBQVcsRUFBRSxDQUFDO2dCQUUzQixFQUFFLENBQUMsY0FBYyxDQUFDLFVBQVUsUUFBYTtvQkFDdkMsSUFBSSxRQUFRLENBQUMsTUFBTSxLQUFLLFdBQVcsRUFBRTs7NEJBQzdCLGFBQVcsR0FBRyxFQUFFLENBQUMsZUFBZSxFQUFFLENBQUMsYUFBYSxDQUFDO3dCQUN2RCxFQUFFLENBQUMsR0FBRyxDQUFDLCtCQUErQixFQUFFLFVBQUMsR0FBUTs0QkFDL0MsT0FBTyxDQUFDLHFCQUFxQixDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLEVBQUUsRUFBRSxFQUFDLEtBQUssRUFBRSxhQUFXLEVBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7eUJBQ3ZGLENBQUMsQ0FBQztxQkFDSjtpQkFDRixDQUFDLENBQUM7YUFDSixDQUFDLENBQUM7U0FDTixDQUFDLENBQUM7S0FDSjs7Ozs7SUFFTSw4QkFBUTs7OztJQUFmLFVBQWdCLFFBQWE7O1lBQ3ZCLElBQUksR0FBb0IsSUFBSSxlQUFlLEVBQUU7UUFDakQsSUFBSSxDQUFDLEVBQUUsR0FBRyxRQUFRLENBQUMsRUFBRSxDQUFDO1FBQ3RCLElBQUksQ0FBQyxJQUFJLEdBQUcsUUFBUSxDQUFDLElBQUksQ0FBQztRQUMxQixJQUFJLENBQUMsS0FBSyxHQUFHLFFBQVEsQ0FBQyxLQUFLLENBQUM7UUFDNUIsSUFBSSxDQUFDLEtBQUssR0FBRyxRQUFRLENBQUMsS0FBSyxDQUFDO1FBQzVCLElBQUksQ0FBQyxLQUFLLEdBQUcsNkJBQTZCLEdBQUcsUUFBUSxDQUFDLEVBQUUsR0FBRyxzQkFBc0IsQ0FBQztRQUNsRixPQUFPLElBQUksQ0FBQztLQUNiOzs7O0lBRUQsc0NBQU07OztJQUFOO1FBQ0UsT0FBTyxJQUFJLE9BQU8sQ0FBQyxVQUFDLE9BQU8sRUFBRSxNQUFNO1lBQ2pDLEVBQUUsQ0FBQyxLQUFLLENBQUMsVUFBQyxRQUFhO2dCQUNyQixJQUFJLFFBQVEsQ0FBQyxZQUFZLEVBQUU7O3dCQUNuQixhQUFXLEdBQUcsRUFBRSxDQUFDLGVBQWUsRUFBRSxDQUFDLGFBQWEsQ0FBQztvQkFDdkQsRUFBRSxDQUFDLEdBQUcsQ0FBQywrQkFBK0IsRUFBRSxVQUFDLEdBQVE7d0JBQy9DLE9BQU8sQ0FBQyxxQkFBcUIsQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEVBQUUsRUFBQyxLQUFLLEVBQUUsYUFBVyxFQUFDLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO3FCQUN2RixDQUFDLENBQUM7aUJBQ0o7YUFDRixFQUFFLEVBQUUsS0FBSyxFQUFFLHNCQUFzQixFQUFFLENBQUMsQ0FBQztTQUN2QyxDQUFDLENBQUM7S0FDSjs7OztJQUVELHVDQUFPOzs7SUFBUDtRQUNFLE9BQU8sSUFBSSxPQUFPLENBQUMsVUFBQyxPQUFPLEVBQUUsTUFBTTtZQUNqQyxFQUFFLENBQUMsTUFBTSxDQUFDLFVBQUMsUUFBYTtnQkFDdEIsT0FBTyxFQUFFLENBQUM7YUFDWCxDQUFDLENBQUM7U0FDSixDQUFDLENBQUM7S0FDSjtJQS9Ec0IsaUNBQVcsR0FBRyxVQUFVLENBQUM7SUFpRWxELDRCQUFDO0NBQUEsQ0FuRTBDLGlCQUFpQjs7Ozs7OztJQ0FuQkEsdUNBQWlCO0lBTXhELDZCQUFvQixRQUFnQjtRQUFwQyxZQUNFLGlCQUFPLFNBSVI7UUFMbUIsY0FBUSxHQUFSLFFBQVEsQ0FBUTtRQUg3QixzQkFBZ0IsR0FBNEIsSUFBSSx1QkFBdUIsRUFBRSxDQUFDO1FBSy9FLEtBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxFQUFFLEdBQUcsUUFBUSxDQUFDO1FBQ3BDLEtBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLEdBQUcsUUFBUSxDQUFDO1FBQ3RDLEtBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxHQUFHLEdBQUcsd0NBQXdDLENBQUM7O0tBQ3RFOzs7O0lBRUQsd0NBQVU7OztJQUFWO1FBQUEsaUJBaUJDO1FBaEJDLE9BQU8sSUFBSSxPQUFPLENBQUMsVUFBQyxPQUFPLEVBQUUsTUFBTTtZQUNqQyxLQUFJLENBQUMsVUFBVSxDQUFDLEtBQUksQ0FBQyxnQkFBZ0IsRUFBRTtnQkFDbkMsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUU7b0JBQ2pCLEtBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUM7d0JBQzNCLFNBQVMsRUFBRSxLQUFJLENBQUMsUUFBUTt3QkFDeEIsS0FBSyxFQUFFLE9BQU87cUJBQ2YsQ0FBQyxDQUFDO29CQUVILEtBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDO3dCQUNkLElBQUksS0FBSSxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUMsR0FBRyxFQUFFLEVBQUU7NEJBQy9CLE9BQU8sQ0FBQyxLQUFJLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQzt5QkFDMUI7cUJBQ0YsQ0FBQyxDQUFDO2lCQUNKLENBQUMsQ0FBQzthQUNOLENBQUMsQ0FBQztTQUNKLENBQUMsQ0FBQztLQUNKOzs7O0lBRUQsc0NBQVE7OztJQUFSOztZQUNNLElBQUksR0FBb0IsSUFBSSxlQUFlLEVBQUU7O1lBQzdDLE9BQU8sR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxlQUFlLEVBQUU7O1lBQ3hELGVBQWUsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDO1FBQ3hFLElBQUksQ0FBQyxFQUFFLEdBQUcsT0FBTyxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQzFCLElBQUksQ0FBQyxJQUFJLEdBQUcsT0FBTyxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQzlCLElBQUksQ0FBQyxLQUFLLEdBQUcsT0FBTyxDQUFDLFFBQVEsRUFBRSxDQUFDO1FBQ2hDLElBQUksQ0FBQyxLQUFLLEdBQUcsT0FBTyxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQ25DLElBQUksQ0FBQyxLQUFLLEdBQUcsZUFBZSxDQUFDLFlBQVksQ0FBQztRQUMxQyxJQUFJLENBQUMsT0FBTyxHQUFHLGVBQWUsQ0FBQyxRQUFRLENBQUM7UUFDeEMsT0FBTyxJQUFJLENBQUM7S0FDYjs7OztJQUVELG9DQUFNOzs7SUFBTjtRQUFBLGlCQU9DO1FBTkMsT0FBTyxJQUFJLE9BQU8sQ0FBQyxVQUFDLE9BQU8sRUFBRSxNQUFNOztnQkFDN0IsT0FBTyxHQUFHLEtBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxFQUFFO1lBQ2pDLE9BQU8sQ0FBQyxJQUFJLENBQUM7Z0JBQ1gsT0FBTyxDQUFDLEtBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDO2FBQzFCLENBQUMsQ0FBQztTQUNKLENBQUMsQ0FBQztLQUNKOzs7O0lBRUQscUNBQU87OztJQUFQO1FBQUEsaUJBVUM7UUFUQyxPQUFPLElBQUksT0FBTyxDQUFDLFVBQUMsT0FBTyxFQUFFLE1BQU07WUFDakMsS0FBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLEVBQUUsQ0FBQyxJQUFJLENBQUMsVUFBQyxHQUFRO2dCQUNqQyxJQUFJLEdBQUcsRUFBRTtvQkFDUCxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUM7aUJBQ2I7cUJBQU07b0JBQ0wsT0FBTyxFQUFFLENBQUM7aUJBQ1g7YUFDRixDQUFDLENBQUM7U0FDSixDQUFDLENBQUM7S0FDSjtJQTlEc0IsK0JBQVcsR0FBRyxRQUFRLENBQUM7SUFnRWhELDBCQUFDO0NBQUEsQ0FsRXdDLGlCQUFpQjs7Ozs7OztJQ0NmQSx5Q0FBaUI7SUFLMUQsK0JBQW9CLFFBQWdCO1FBQXBDLFlBQ0UsaUJBQU8sU0FJUjtRQUxtQixjQUFRLEdBQVIsUUFBUSxDQUFRO1FBRjdCLHNCQUFnQixHQUE0QixJQUFJLHVCQUF1QixFQUFFLENBQUM7UUFJL0UsS0FBSSxDQUFDLGdCQUFnQixDQUFDLEVBQUUsR0FBRyxRQUFRLENBQUM7UUFDcEMsS0FBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksR0FBRyxVQUFVLENBQUM7UUFDeEMsS0FBSSxDQUFDLGdCQUFnQixDQUFDLEdBQUcsR0FBRyxxQ0FBcUMsQ0FBQzs7S0FDbkU7Ozs7SUFFRCwwQ0FBVTs7O0lBQVY7UUFBQSxpQkFxQkM7UUFwQkMsT0FBTyxJQUFJLE9BQU8sQ0FBQyxVQUFDLE9BQU8sRUFBRSxNQUFNO1lBQ2pDLEtBQUksQ0FBQyxVQUFVLENBQUMsS0FBSSxDQUFDLGdCQUFnQixFQUFFO2dCQUNuQyxFQUFFLENBQUMsSUFBSSxDQUFDO29CQUNOLE9BQU8sRUFBRSxLQUFJLENBQUMsUUFBUTtvQkFDdEIsU0FBUyxFQUFFLElBQUk7b0JBQ2YsTUFBTSxFQUFFLEtBQUksQ0FBQyxjQUFjLEVBQUU7aUJBQzlCLENBQUMsQ0FBQztnQkFFSCxFQUFFLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsTUFBTSxFQUFFO29CQUN0QixJQUFJLEVBQUUsQ0FBQyxJQUFJLENBQUMsWUFBWSxFQUFFLEVBQUU7d0JBQzFCLEVBQUUsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUNSLCtEQUErRCxDQUNoRSxDQUFDLE1BQU0sQ0FBRSxVQUFDLEdBQTBCOzRCQUNuQyxPQUFPLENBQUMsS0FBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO3lCQUM3QixDQUFDLENBQUM7cUJBQ0o7aUJBQ0YsQ0FBQyxDQUFDO2FBRUosQ0FBQyxDQUFDO1NBQ04sQ0FBQyxDQUFDO0tBQ0o7Ozs7SUFFRCw4Q0FBYzs7O0lBQWQ7UUFDRSxFQUFFLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsYUFBYSxFQUFFO1lBQzdCLEVBQUUsQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7U0FDbkIsQ0FBQyxDQUFDO0tBQ0o7Ozs7O0lBRUQsd0NBQVE7Ozs7SUFBUixVQUFTLFFBQStCOztZQUNsQyxJQUFJLEdBQW9CLElBQUksZUFBZSxFQUFFO1FBQ2pELElBQUksQ0FBQyxFQUFFLEdBQUcsUUFBUSxDQUFDLFlBQVksQ0FBQztRQUNoQyxJQUFJLENBQUMsSUFBSSxHQUFHLFFBQVEsQ0FBQyxTQUFTLEdBQUcsR0FBRyxHQUFHLFFBQVEsQ0FBQyxRQUFRLENBQUM7UUFDekQsSUFBSSxDQUFDLEtBQUssR0FBRyxRQUFRLENBQUMsWUFBWSxDQUFDO1FBQ25DLElBQUksQ0FBQyxLQUFLLEdBQUcsUUFBUSxDQUFDLFVBQVUsQ0FBQztRQUNqQyxJQUFJLENBQUMsS0FBSyxHQUFHLEVBQUUsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQztRQUNyQyxPQUFPLElBQUksQ0FBQztLQUNiOzs7O0lBRUQsc0NBQU07OztJQUFOO1FBQUEsaUJBUUM7UUFQQyxPQUFPLElBQUksT0FBTyxDQUFDLFVBQUMsT0FBTyxFQUFFLE1BQU07WUFDakMsRUFBRSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUU7Z0JBQ2pCLEVBQUUsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLCtEQUErRCxDQUFDLENBQUMsTUFBTSxDQUFFLFVBQUMsR0FBMEI7b0JBQzdHLE9BQU8sQ0FBQyxLQUFJLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7aUJBQzdCLENBQUMsQ0FBQzthQUNKLENBQUMsQ0FBQztTQUNKLENBQUMsQ0FBQztLQUNKOzs7O0lBRUQsdUNBQU87OztJQUFQO1FBQ0UsT0FBTyxJQUFJLE9BQU8sQ0FBQyxVQUFDLE9BQU8sRUFBRSxNQUFNO1lBQ2pDLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLFVBQUMsUUFBYTtnQkFDM0IsT0FBTyxFQUFFLENBQUM7YUFDWCxFQUFFLFVBQUMsR0FBUTtnQkFDVixNQUFNLENBQUMsR0FBRyxDQUFDLENBQUM7YUFDYixDQUFDLENBQUM7U0FDSixDQUFDLENBQUM7S0FDSjtJQW5Fc0IsaUNBQVcsR0FBRyxVQUFVLENBQUM7SUFxRWxELDRCQUFDO0NBQUEsQ0F2RTBDLGlCQUFpQjs7Ozs7Ozs7Ozs7QUNMNUQ7SUFHSSwyQkFBWSxTQUFrQztRQUY5QyxjQUFTLEdBQStCLElBQUksR0FBRyxFQUF5QixDQUFDO1FBR3ZFLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxTQUFTLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFOztnQkFDckMsT0FBTyxHQUFHLFNBQVMsQ0FBQyxDQUFDLENBQUM7WUFDMUIsSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLEVBQUUsRUFBRSxPQUFPLENBQUMsUUFBUSxDQUFDLENBQUM7U0FDbEQ7S0FDRjtJQUNILHdCQUFDO0NBQUE7Ozs7OztBQ1pIO0lBcUJFLHFCQUFZLE1BQXlCO1FBQXJDLGlCQVdDO1FBbEJPLFVBQUssR0FBb0IsSUFBSSxDQUFDO1FBQzlCLGVBQVUsR0FBcUMsSUFBSSxlQUFlLENBQUMsSUFBSSxDQUFDLENBQUM7UUFPL0UsSUFBSSxDQUFDLFNBQVMsR0FBRyxNQUFNLENBQUMsU0FBUyxDQUFDO1FBQ2xDLElBQUksQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLFVBQUMsUUFBdUIsRUFBRSxHQUFXO1lBQzFELFFBQVEsQ0FBQyxVQUFVLEVBQUUsQ0FBQyxJQUFJLENBQUMsVUFBQyxJQUFxQjtnQkFDL0MsSUFBSSxDQUFDLFFBQVEsR0FBRyxHQUFHLENBQUM7Z0JBQ3BCLEtBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDO2dCQUNsQixLQUFJLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQzthQUM1QixDQUFDLENBQUMsS0FBSyxDQUFDLFVBQUMsR0FBRzs7YUFFWixDQUFDLENBQUM7U0FDSixDQUFDLENBQUM7S0FDSjtJQWZELHNCQUFJLGtDQUFTOzs7O1FBQWI7WUFDRSxPQUFPLElBQUksQ0FBQyxVQUFVLENBQUMsWUFBWSxFQUFFLENBQUM7U0FDdkM7OztPQUFBOzs7OztJQWVELDRCQUFNOzs7O0lBQU4sVUFBTyxVQUFrQjtRQUF6QixpQkFjQztRQWJDLE9BQU8sSUFBSSxPQUFPLENBQUMsVUFBQyxPQUFPLEVBQUUsTUFBTTs7Z0JBQzdCLGNBQWMsR0FBRyxLQUFJLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxVQUFVLENBQUM7WUFDbkQsSUFBSSxjQUFjLEVBQUU7Z0JBQ2xCLGNBQWMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxJQUFJLENBQUMsVUFBQyxJQUFxQjtvQkFDakQsSUFBSSxDQUFDLFFBQVEsR0FBRyxVQUFVLENBQUM7b0JBQzNCLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQztvQkFDZCxLQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQztvQkFDbEIsS0FBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7aUJBQzVCLENBQUMsQ0FBQzthQUNKO2lCQUFNO2dCQUNMLE1BQU0sQ0FBQyxXQUFXLENBQUMsd0JBQXdCLENBQUMsQ0FBQzthQUM5QztTQUNGLENBQUMsQ0FBQztLQUNKOzs7O0lBRUQsNkJBQU87OztJQUFQO1FBQUEsaUJBZ0JDO1FBZkMsT0FBTyxJQUFJLE9BQU8sQ0FBQyxVQUFDLE9BQU8sRUFBRSxNQUFNO1lBQ2pDLElBQUksS0FBSSxDQUFDLEtBQUssSUFBSSxLQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsRUFBRTs7b0JBQ2pDLFVBQVUsR0FBRyxLQUFJLENBQUMsS0FBSyxDQUFDLFFBQVE7O29CQUNoQyxjQUFjLEdBQUcsS0FBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDO2dCQUNuRCxjQUFjLENBQUMsT0FBTyxFQUFFLENBQUMsSUFBSSxDQUFDO29CQUM1QixLQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQztvQkFDbEIsS0FBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7b0JBQzNCLE9BQU8sRUFBRSxDQUFDO2lCQUNYLENBQUMsQ0FBQyxLQUFLLENBQUMsVUFBQyxHQUFHO29CQUNYLEtBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO2lCQUM1QixDQUFDLENBQUM7YUFDSjtpQkFBTTtnQkFDTCxNQUFNLENBQUMsV0FBVyxDQUFDLHdCQUF3QixDQUFDLENBQUM7YUFDOUM7U0FDRixDQUFDLENBQUM7S0FDSjtJQXhEdUIsb0NBQXdCLEdBQUcsMEJBQTBCLENBQUM7O2dCQUgvRSxVQUFVOzs7O2dCQUhGLGlCQUFpQjs7SUFnRTFCLGtCQUFDO0NBN0REOzs7Ozs7QUNQQTtJQUlBO0tBT3dDOztnQkFQdkMsUUFBUSxTQUFDO29CQUNSLE9BQU8sRUFBRTt3QkFDUCxZQUFZO3FCQUNiO29CQUNELFlBQVksRUFBRSxFQUFFO29CQUNoQixTQUFTLEVBQUUsQ0FBQyxXQUFXLENBQUM7aUJBQ3pCOztJQUNzQyw4QkFBQztDQVB4Qzs7Ozs7Ozs7Ozs7Ozs7In0=