ngx-amplify
Version:
An angular library for integration AWS cloud services (cognito, s3)
982 lines • 75 kB
JavaScript
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
import * as tslib_1 from "tslib";
import { Injectable, Inject } from '@angular/core';
import { NGX_AMPLIFY_CONFIG } from '../common/interfaces/ngx-amplify.config';
import * as AWS from 'aws-sdk';
import { CognitoUserPool, CognitoUser, AuthenticationDetails, CognitoUserAttribute } from 'amazon-cognito-identity-js';
import { BehaviorSubject } from 'rxjs';
import { CognitoException, CognitoProfile, AuthUser } from '../common/common.resource';
import * as i0 from "@angular/core";
import * as i1 from "../common/interfaces/ngx-amplify.config";
var AuthService = /** @class */ (function () {
function AuthService(config) {
this.config = config;
this.resetting = false;
this.authState = new BehaviorSubject({ state: 'signedOut', user: null });
this.authState$ = this.authState.asObservable();
this.authUserState = new BehaviorSubject({ state: 'signedOut', user: null });
this.authUserState$ = this.authUserState.asObservable();
this.cognitoUserSub = new BehaviorSubject(this.cognitoUser);
this.cognitoUser$ = this.cognitoUserSub.asObservable();
AWS.config.region = this.config.region;
AWS.config.credentials = new AWS.CognitoIdentityCredentials({
IdentityPoolId: this.config.identityPoolId
});
this.poolData = { UserPoolId: config.userPoolId, ClientId: this.config.appId };
this.userPool = new CognitoUserPool(this.poolData);
this.user = AuthUser.Factory();
// this.authUserState.next({ state: 'signedOut', user: this.user });
// this.refreshOrResetCreds();
// this.currentAuthUser = this.currentAuthUser.bind(this);
}
/**
* @private
* @param {?} creds
* @return {?}
*/
AuthService.prototype.authDetails = /**
* @private
* @param {?} creds
* @return {?}
*/
function (creds) {
return new AuthenticationDetails({ Username: creds.username, Password: creds.password });
};
/**
* @private
* @return {?}
*/
AuthService.prototype.buildCreds = /**
* @private
* @return {?}
*/
function () {
/** @type {?} */
var self = this;
/** @type {?} */
var json = self.buildLogins(self.session.getIdToken().getJwtToken());
return new AWS.CognitoIdentityCredentials(json);
};
/**
* @private
* @param {?} token
* @return {?}
*/
AuthService.prototype.buildLogins = /**
* @private
* @param {?} token
* @return {?}
*/
function (token) {
/** @type {?} */
var self = this;
/** @type {?} */
var key = self.config.idpUrl + "/" + self.config.userPoolId;
/** @type {?} */
var json = { IdentityPoolId: self.config.identityPoolId, Logins: {} };
json.Logins[key] = token;
return json;
};
/**
* @private
* @param {?} error
* @param {?} caller
* @return {?}
*/
AuthService.prototype.handleError = /**
* @private
* @param {?} error
* @param {?} caller
* @return {?}
*/
function (error, caller) {
/** @type {?} */
var exception = new CognitoException(error);
console.error("AWS Cognito Service::handleError callerMethod::" + caller, exception);
return exception;
};
/**
* @private
* @return {?}
*/
AuthService.prototype.getCurrentUser = /**
* @private
* @return {?}
*/
function () {
return this.userPool.getCurrentUser();
};
/**
* @private
* @param {?} profile
* @return {?}
*/
AuthService.prototype.getCognitoAttributes = /**
* @private
* @param {?} profile
* @return {?}
*/
function (profile) {
/** @type {?} */
var cognitoAttributes = [];
for (var key in profile) {
if (!key.includes("password") && !key.includes("confirmPassword")) {
/** @type {?} */
var attribute = void 0;
if (key.includes("username")) {
attribute = new CognitoUserAttribute({
Name: "preferred_username",
Value: profile[key]
});
}
else if (key.endsWith("__c")) {
/** @type {?} */
var k = key.substring(0, key.length - 3);
/** @type {?} */
var name_1 = "custom:" + k;
attribute = new CognitoUserAttribute({
Name: name_1,
Value: profile[key]
});
}
else {
attribute = new CognitoUserAttribute({
Name: key,
Value: profile[key]
});
}
cognitoAttributes.push(attribute);
}
}
return cognitoAttributes;
};
/**
* @private
* @param {?} creds
* @return {?}
*/
AuthService.prototype.getCognitoUser = /**
* @private
* @param {?} creds
* @return {?}
*/
function (creds) {
/** @type {?} */
var self = this;
/** @type {?} */
var result = new CognitoUser({ Username: creds.username, Pool: self.userPool });
return result;
};
/**
* @return {?}
*/
AuthService.prototype.getJwtToken = /**
* @return {?}
*/
function () {
/** @type {?} */
var self = this;
/** @type {?} */
var user = self.getCurrentUser();
/** @type {?} */
var token;
if (user !== null) {
token = user.getSignInUserSession().getAccessToken().getJwtToken();
}
return token;
};
/**
* @param {?} attributes
* @return {?}
*/
AuthService.prototype.getCognitoProfile = /**
* @param {?} attributes
* @return {?}
*/
function (attributes) {
/** @type {?} */
var dynObj = CognitoProfile.Factory();
/** @type {?} */
var values = attributes;
((/** @type {?} */ (values))).forEach((/**
* @param {?} attr
* @return {?}
*/
function (attr) {
if (attr.Name.startsWith('custom:')) {
/** @type {?} */
var attributeName = attr.Name.substring(7);
dynObj[attributeName + '__c'] = attr.Value;
}
else {
dynObj[attr.Name] = attr.Value;
}
}));
/** @type {?} */
var result = new CognitoProfile(dynObj);
return result;
};
/**
* @private
* @param {?} cognitoUser
* @return {?}
*/
AuthService.prototype.setCognitoProfile = /**
* @private
* @param {?} cognitoUser
* @return {?}
*/
function (cognitoUser) {
/** @type {?} */
var self = this;
return new Promise((/**
* @param {?} resolve
* @param {?} reject
* @return {?}
*/
function (resolve, reject) {
if (cognitoUser === null) {
reject(null);
}
else {
cognitoUser.getUserData((/**
* @param {?} err
* @param {?} result
* @return {?}
*/
function (err, result) {
if (err) {
reject(self.handleError(err, 'setCognitoProfile'));
}
/** @type {?} */
var dynObj = self.getCognitoProfile(result.UserAttributes);
if (dynObj.sub) {
self.user.identityId = dynObj.sub;
}
self.user.cognitoProfile = dynObj;
resolve(dynObj);
}));
}
}));
};
/**
* @param {?} attributes
* @return {?}
*/
AuthService.prototype.updateCognitoProfile = /**
* @param {?} attributes
* @return {?}
*/
function (attributes) {
var _this = this;
/** @type {?} */
var self = this;
return new Promise((/**
* @param {?} resolve
* @param {?} reject
* @return {?}
*/
function (resolve, reject) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
var _this = this;
return tslib_1.__generator(this, function (_a) {
try {
self.cognitoUser.updateAttributes(attributes, (/**
* @param {?} err
* @param {?} result
* @return {?}
*/
function (err, result) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
return tslib_1.__generator(this, function (_a) {
if (err) {
reject(self.handleError(err, 'updateAttributes'));
}
self.setCognitoProfile(self.cognitoUser)
.then((/**
* @param {?} profile
* @return {?}
*/
function (profile) {
resolve(profile);
}))
.catch((/**
* @param {?} error
* @return {?}
*/
function (error) {
reject(self.handleError(error, 'setCognitoProfile'));
}));
return [2 /*return*/];
});
}); }));
}
catch (error) {
reject(self.handleError(error, 'try/catch updateCognitoProfile'));
}
return [2 /*return*/];
});
}); }));
};
/**
* @private
* @param {?=} clearCache
* @return {?}
*/
AuthService.prototype.resetCreds = /**
* @private
* @param {?=} clearCache
* @return {?}
*/
function (clearCache) {
if (clearCache === void 0) { clearCache = false; }
// console.log('Resetting credentials for unauth access');
this.resetting = true;
AWS.config.region = this.config.region;
this.cognitoUser = null;
this.cognitoUserSub.next(null);
this.unauthCreds = this.unauthCreds || new AWS.CognitoIdentityCredentials({ IdentityPoolId: this.config.identityPoolId });
if (clearCache) {
this.unauthCreds.clearCachedId();
}
this.setCredentials(this.unauthCreds);
this.resetting = false;
};
/**
* @return {?}
*/
AuthService.prototype.currentAuthUser = /**
* @return {?}
*/
function () {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var self, user;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
self = this;
user = this.userPool.getCurrentUser();
if (!(user !== null)) return [3 /*break*/, 2];
return [4 /*yield*/, this.refreshSession(user)];
case 1:
_a.sent();
_a.label = 2;
case 2: /* else {
self.authState.next({state: 'signedOut', user: user });
self.cognitoUserSub.next(user);
self.authUserState.next({ state: 'signedOut', user: self.user });
} */ return [2 /*return*/, self.user];
}
});
});
};
/**
* @return {?}
*/
AuthService.prototype.refreshOrResetCreds = /**
* @return {?}
*/
function () {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var session;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
this.cognitoUser = this.userPool.getCurrentUser();
if (!(this.cognitoUser !== null)) return [3 /*break*/, 3];
if (!(this.cognitoUser.getSignInUserSession() === null)) return [3 /*break*/, 2];
return [4 /*yield*/, this.refreshSession()];
case 1:
session = _a.sent();
_a.label = 2;
case 2: return [3 /*break*/, 4];
case 3:
this.resetCreds();
_a.label = 4;
case 4: return [2 /*return*/];
}
});
});
};
/**
* @private
* @param {?=} user
* @return {?}
*/
AuthService.prototype.refreshSession = /**
* @private
* @param {?=} user
* @return {?}
*/
function (user) {
var _this = this;
/** @type {?} */
var self = this;
if (user === undefined) {
user = this.userPool.getCurrentUser();
}
self.cognitoUser = user; // Object.assign({},user, self.cognitoUser);
// console.log('self.user on refresh', self.cognitoUser);
// self.session = user.;
if (self.session && self.session.isValid) {
// console.log('using the current session already refreshed..');
self.cognitoUser.setSignInUserSession(self.session);
return new Promise((/**
* @param {?} resolve
* @return {?}
*/
function (resolve) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, self.saveCreds(self.cognitoUser, self.session)];
case 1:
_a.sent();
resolve(self.session);
return [2 /*return*/];
}
});
}); }));
}
else {
/* return self.cognitoUser.getSession(async (err, session: CognitoUserSession) => {
if (err) { console.log('Error refreshing user session', err); return err; }
console.log(`${new Date()} - Refreshed session for ${self.cognitoUser.getUsername()}. Valid?: `, session.isValid());
self.session = session;
self.cognitoUser.setSignInUserSession(session);
await self.saveCreds(self.cognitoUser, session);
return session;
}) */
return new Promise((/**
* @param {?} resolve
* @param {?} reject
* @return {?}
*/
function (resolve, reject) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
var _this = this;
return tslib_1.__generator(this, function (_a) {
self.cognitoUser.getSession((/**
* @param {?} err
* @param {?} session
* @return {?}
*/
function (err, session) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
if (err) {
console.log('Error refreshing user session', err);
reject(err);
}
// console.log(`${new Date()} - Refreshed session for ${self.cognitoUser.getUsername()}. Valid?: `, session.isValid());
self.session = session;
self.cognitoUser.setSignInUserSession(session);
return [4 /*yield*/, self.saveCreds(self.cognitoUser, session)];
case 1:
_a.sent();
resolve(session);
return [2 /*return*/];
}
});
}); }));
return [2 /*return*/];
});
}); }));
}
};
/**
* @param {?=} cognitoUser
* @param {?=} session
* @return {?}
*/
AuthService.prototype.saveCreds = /**
* @param {?=} cognitoUser
* @param {?=} session
* @return {?}
*/
function (cognitoUser, session) {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var self;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
self = this;
if (session) {
self.session = session;
self.user.authenticated = session.isValid();
self.authState.next({ state: 'signedIn', user: cognitoUser });
}
if (!cognitoUser) return [3 /*break*/, 2];
self.cognitoUser = cognitoUser;
self.user.cognitoUser = cognitoUser;
self.authState.next({ state: 'signedIn', user: cognitoUser });
self.cognitoUserSub.next(cognitoUser);
self.user.cognitoProfile = CognitoProfile.Factory();
return [4 /*yield*/, self.setCognitoProfile(cognitoUser)];
case 1:
_a.sent();
self.authUserState.next({ state: 'signedIn', user: self.user });
_a.label = 2;
case 2:
self.setCredentials(self.buildCreds());
return [2 /*return*/, self.user];
}
});
});
};
/**
* @private
* @param {?} creds
* @return {?}
*/
AuthService.prototype.setCredentials = /**
* @private
* @param {?} creds
* @return {?}
*/
function (creds) {
AWS.config.credentials = creds;
};
/**
* @param {?} creds
* @return {?}
*/
AuthService.prototype.signIn = /**
* @param {?} creds
* @return {?}
*/
function (creds) {
var _this = this;
/** @type {?} */
var self = this;
/** @type {?} */
var cognitoUser = self.getCognitoUser(creds);
return new Promise((/**
* @param {?} resolve
* @param {?} reject
* @return {?}
*/
function (resolve, reject) {
try {
cognitoUser.authenticateUser(self.authDetails(creds), {
onSuccess: (/**
* @param {?} session
* @return {?}
*/
function (session) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
var user;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
// console.log(`Signed in user ${cognitoUser.getUsername()}. Sessiong valid?: `, session.isValid());
return [4 /*yield*/, self.saveCreds(cognitoUser, session)];
case 1:
user = _a.sent();
resolve(user);
return [2 /*return*/];
}
});
}); }),
onFailure: (/**
* @param {?} err
* @return {?}
*/
function (err) {
reject(self.handleError(err, 'signIn'));
}),
newPasswordRequired: (/**
* @param {?} userAttributes
* @param {?} requiredAttributes
* @return {?}
*/
function (userAttributes, requiredAttributes) {
cognitoUser.completeNewPasswordChallenge(creds.password, requiredAttributes, {
onSuccess: (/**
* @param {?} session
* @return {?}
*/
function (session) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
var aws_creds, user;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
aws_creds = new AWS.CognitoIdentityCredentials(self.buildLogins(session.getIdToken().getJwtToken()));
return [4 /*yield*/, self.saveCreds(cognitoUser, session)];
case 1:
user = _a.sent();
resolve(user);
return [2 /*return*/];
}
});
}); }),
onFailure: (/**
* @param {?} err
* @return {?}
*/
function (err) {
reject(self.handleError(err, 'completeNewPasswordChallenge'));
})
});
}),
mfaRequired: (/**
* @param {?} challengeName
* @param {?} challengeParameters
* @return {?}
*/
function (challengeName, challengeParameters) { }),
customChallenge: (/**
* @param {?} challengeParameters
* @return {?}
*/
function (challengeParameters) { }),
});
}
catch (error) {
reject(error);
}
}));
};
/**
* @param {?} creds
* @return {?}
*/
AuthService.prototype.signUp = /**
* @param {?} creds
* @return {?}
*/
function (creds) {
/** @type {?} */
var self = this;
// creds.member_since__c = moment().year().toString();
return new Promise((/**
* @param {?} resolve
* @param {?} reject
* @return {?}
*/
function (resolve, reject) {
try {
/** @type {?} */
var attributes = [];
attributes = self.getCognitoAttributes(creds);
return self.userPool.signUp(creds.username, creds.password, attributes, null, (/**
* @param {?} err
* @param {?} result
* @return {?}
*/
function (err, result) {
if (err) {
reject(self.handleError(err, 'signUp'));
}
else {
// console.log('signUp registration successful', result);
resolve(result);
}
}));
}
catch (error) {
reject(self.handleError(error, 'try/catch signUp'));
}
}));
};
/**
* @param {?} username
* @param {?} code
* @return {?}
*/
AuthService.prototype.confirmSignUp = /**
* @param {?} username
* @param {?} code
* @return {?}
*/
function (username, code) {
var _this = this;
/** @type {?} */
var self = this;
/** @type {?} */
var userData = {
Username: username,
Pool: self.userPool
};
/** @type {?} */
var cognitoUser = new CognitoUser(userData);
return new Promise((/**
* @param {?} resolve
* @param {?} reject
* @return {?}
*/
function (resolve, reject) {
try {
cognitoUser.confirmRegistration(code, true, ((/**
* @param {?} err
* @param {?} result
* @return {?}
*/
function (err, result) {
if (err) {
reject(self.handleError(err, 'confirmRegistration'));
}
else {
// console.log('confirm registration successful', result);
resolve(result);
}
})));
}
catch (error) {
reject(_this.handleError(error, 'try/catch confirm signUp'));
}
}));
};
/**
* @param {?} username
* @param {?} verificationCode
* @param {?} password
* @return {?}
*/
AuthService.prototype.confirmPassword = /**
* @param {?} username
* @param {?} verificationCode
* @param {?} password
* @return {?}
*/
function (username, verificationCode, password) {
/** @type {?} */
var self = this;
/** @type {?} */
var userData = {
Username: username,
Pool: this.userPool
};
/** @type {?} */
var cognitoUser = new CognitoUser(userData);
return new Promise((/**
* @param {?} resolve
* @param {?} reject
* @return {?}
*/
function (resolve, reject) {
try {
cognitoUser.confirmPassword(verificationCode, password, {
onFailure: (/**
* @param {?} err
* @return {?}
*/
function (err) {
reject(self.handleError(err, 'confirmPassword'));
}),
onSuccess: (/**
* @return {?}
*/
function () {
resolve('Confirm Password SUCCESS');
})
});
}
catch (error) {
reject(self.handleError(error, 'try/catch confirmPassword'));
}
}));
};
/**
* @param {?} username
* @return {?}
*/
AuthService.prototype.forgotPassword = /**
* @param {?} username
* @return {?}
*/
function (username) {
/** @type {?} */
var self = this;
/** @type {?} */
var userData = {
Username: username,
Pool: this.userPool
};
/** @type {?} */
var cognitoUser = new CognitoUser(userData);
return new Promise((/**
* @param {?} resolve
* @param {?} reject
* @return {?}
*/
function (resolve, reject) {
try {
cognitoUser.forgotPassword({
onFailure: (/**
* @param {?} err
* @return {?}
*/
function (err) {
reject(self.handleError(err, 'forgotPassword'));
}),
onSuccess: (/**
* @return {?}
*/
function () {
resolve('Verification Code Sent');
}),
inputVerificationCode: (/**
* @return {?}
*/
function () {
resolve('Verification Code Sent');
})
});
}
catch (err) {
reject(self.handleError(err, 'try/catch forgotPassword'));
}
}));
};
/**
* @param {?} username
* @return {?}
*/
AuthService.prototype.resendConfirmationCode = /**
* @param {?} username
* @return {?}
*/
function (username) {
/** @type {?} */
var self = this;
/** @type {?} */
var userData = {
Username: username,
Pool: this.userPool
};
/** @type {?} */
var cognitoUser = new CognitoUser(userData);
return new Promise((/**
* @param {?} resolve
* @param {?} reject
* @return {?}
*/
function (resolve, reject) {
try {
cognitoUser.resendConfirmationCode((/**
* @param {?} err
* @param {?} result
* @return {?}
*/
function (err, result) {
if (err) {
// let exception: ICognitoException = self.handleError(err,'resendConfirmationCode');
// console.log('error occurred while confirming registration code', exception);
reject(self.handleError(err, 'resendConfirmationCode'));
}
else {
// console.log('confirm registration successful', result);
resolve(result);
}
}));
}
catch (error) {
// let exception: ICognitoException = self.handleError(error,'try/catch resendConfirmationCode');//new CognitoException(error);
reject(self.handleError(error, 'try/catch resendConfirmationCode'));
}
}));
};
/**
* @return {?}
*/
AuthService.prototype.signOut = /**
* @return {?}
*/
function () {
/** @type {?} */
var self = this;
if (self.cognitoUser) {
/** @type {?} */
var username = self.cognitoUser.getUsername();
return new Promise((/**
* @param {?} resolve
* @param {?} reject
* @return {?}
*/
function (resolve, reject) {
try {
self.cognitoUser.signOut();
self.cognitoUserSub.next(null);
self.authState.next({ state: 'signedOut', user: null });
self.resetCreds(true);
self.user = AuthUser.Factory();
self.authUserState.next({ state: 'signedOut', user: null });
resolve('signOut successful');
}
catch (error) {
reject(self.handleError(error, 'try/catch signOut'));
}
}));
}
};
AuthService.decorators = [
{ type: Injectable, args: [{
providedIn: 'root'
},] }
];
/** @nocollapse */
AuthService.ctorParameters = function () { return [
{ type: undefined, decorators: [{ type: Inject, args: [NGX_AMPLIFY_CONFIG,] }] }
]; };
/** @nocollapse */ AuthService.ngInjectableDef = i0.ɵɵdefineInjectable({ factory: function AuthService_Factory() { return new AuthService(i0.ɵɵinject(i1.NGX_AMPLIFY_CONFIG)); }, token: AuthService, providedIn: "root" });
return AuthService;
}());
export { AuthService };
if (false) {
/**
* @type {?}
* @private
*/
AuthService.prototype.poolData;
/**
* @type {?}
* @private
*/
AuthService.prototype.session;
/**
* @type {?}
* @private
*/
AuthService.prototype.userPool;
/**
* @type {?}
* @private
*/
AuthService.prototype.unauthCreds;
/**
* @type {?}
* @private
*/
AuthService.prototype.resetting;
/**
* @type {?}
* @private
*/
AuthService.prototype.authState;
/** @type {?} */
AuthService.prototype.authState$;
/**
* @type {?}
* @private
*/
AuthService.prototype.authUserState;
/** @type {?} */
AuthService.prototype.authUserState$;
/** @type {?} */
AuthService.prototype.cognitoUser;
/**
* @type {?}
* @private
*/
AuthService.prototype.cognitoUserSub;
/** @type {?} */
AuthService.prototype.cognitoUser$;
/** @type {?} */
AuthService.prototype.user;
/**
* @type {?}
* @private
*/
AuthService.prototype.config;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXV0aC5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6Im5nOi8vbmd4LWFtcGxpZnkvIiwic291cmNlcyI6WyJsaWIvc2VydmljZXMvYXV0aC5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDbkQsT0FBTyxFQUFvQixrQkFBa0IsRUFBRSxNQUFNLHlDQUF5QyxDQUFDO0FBQy9GLE9BQU8sS0FBSyxHQUFHLE1BQU0sU0FBUyxDQUFDO0FBQy9CLE9BQU8sRUFBd0IsZUFBZSxFQUFFLFdBQVcsRUFBRSxxQkFBcUIsRUFBc0Isb0JBQW9CLEVBQXNELE1BQU0sNEJBQTRCLENBQUM7QUFDck4sT0FBTyxFQUFFLGVBQWUsRUFBdUIsTUFBTSxNQUFNLENBQUM7QUFDNUQsT0FBTyxFQUFFLGdCQUFnQixFQUFFLGNBQWMsRUFBRSxRQUFRLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQzs7O0FBR3ZGO0lBc0JFLHFCQUNzQyxNQUF3QjtRQUF4QixXQUFNLEdBQU4sTUFBTSxDQUFrQjtRQWZ0RCxjQUFTLEdBQVksS0FBSyxDQUFDO1FBRTNCLGNBQVMsR0FBZ0MsSUFBSSxlQUFlLENBQUMsRUFBRSxLQUFLLEVBQUUsV0FBVyxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO1FBQ3pHLGVBQVUsR0FBMkIsSUFBSSxDQUFDLFNBQVMsQ0FBQyxZQUFZLEVBQUUsQ0FBQztRQUUzRCxrQkFBYSxHQUFvQyxJQUFJLGVBQWUsQ0FBQyxFQUFFLEtBQUssRUFBRSxXQUFXLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7UUFDakgsbUJBQWMsR0FBK0IsSUFBSSxDQUFDLGFBQWEsQ0FBQyxZQUFZLEVBQUUsQ0FBQztRQUl2RSxtQkFBYyxHQUFpQyxJQUFJLGVBQWUsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7UUFDN0YsaUJBQVksR0FBNEIsSUFB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