@nowzoo/ngx-firebase-auth
Version:
Angular components for Firebase email-first sign in and out-of-band (oob) actions (reset password, etc).
190 lines (189 loc) • 26.2 kB
JavaScript
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
import { Component, Input, Output, EventEmitter, ViewChild, ElementRef } from '@angular/core';
import { FormControl, FormGroup, Validators } from '@angular/forms';
import { AngularFireAuth } from 'angularfire2/auth';
import { NgxFirebaseAuthFormHelper } from '../../form-helper';
import { NgxFirebaseAuthService } from '../../ngx-firebase-auth.service';
import { getOAuthProviderIcon, getOAuthProviderName, fadeInOutAnimation } from '../../shared';
var SignInFormComponent = /** @class */ (function () {
function SignInFormComponent(_afAuth, _authService) {
this._afAuth = _afAuth;
this._authService = _authService;
this.rememberChange = new EventEmitter();
this.success = new EventEmitter();
this.error = new EventEmitter();
this.formId = 'ngx-firebase-auth-sign-in-form-';
this.submitting = false;
this.methodsForEmail = [];
this.getOAuthProviderIcon = getOAuthProviderIcon;
this.getOAuthProviderName = getOAuthProviderName;
}
Object.defineProperty(SignInFormComponent.prototype, "auth", {
get: /**
* @return {?}
*/
function () {
return this._afAuth.auth;
},
enumerable: true,
configurable: true
});
Object.defineProperty(SignInFormComponent.prototype, "authService", {
get: /**
* @return {?}
*/
function () {
return this._authService;
},
enumerable: true,
configurable: true
});
/**
* @return {?}
*/
SignInFormComponent.prototype.ngOnInit = /**
* @return {?}
*/
function () {
var _this = this;
this.emailFc = new FormControl(this.email, { validators: [Validators.required, Validators.email] });
this.passwordFc = new FormControl('', { validators: [Validators.required] });
this.rememberFc = new FormControl(this.remember);
this.rememberFc.valueChanges.subscribe(function (val) { return _this.rememberChange.emit(val); });
this.fg = new FormGroup({
email: this.emailFc,
password: this.passwordFc,
remember: this.rememberFc
});
};
/**
* @return {?}
*/
SignInFormComponent.prototype.ngAfterViewInit = /**
* @return {?}
*/
function () {
this.passwordInput.nativeElement.focus();
};
/**
* @return {?}
*/
SignInFormComponent.prototype.submit = /**
* @return {?}
*/
function () {
var _this = this;
/** @type {?} */
var email = this.emailFc.value.trim();
this.submitting = true;
this.methodsForEmail = [];
/** @type {?} */
var cred;
this.auth.fetchSignInMethodsForEmail(email)
.then(function (results) {
_this.methodsForEmail = results;
if (results.length === 0) {
return Promise.reject({
code: 'auth/user-not-found'
});
}
if (results.indexOf('password') === -1) {
return Promise.reject({
code: 'ngx-firebase-auth/no-password',
});
}
return _this.auth.signInWithEmailAndPassword(email, _this.passwordFc.value);
})
.then(function (result) {
cred = result;
return _this.authService.setRemembered(_this.rememberFc.value === true, email);
})
.then(function () {
_this.success.emit(cred);
})
.catch(function (error) {
_this.submitting = false;
_this.emailFc.markAsDirty();
_this.emailFc.markAsTouched();
_this.passwordFc.markAsDirty();
_this.passwordFc.markAsTouched();
switch (error.code) {
case 'auth/invalid-email':
case 'auth/user-not-found':
case 'auth/user-disabled':
case 'ngx-firebase-auth/no-password':
NgxFirebaseAuthFormHelper.setErrorUntilChanged(_this.emailFc, error.code);
break;
case 'auth/wrong-password':
NgxFirebaseAuthFormHelper.setErrorUntilChanged(_this.passwordFc, error.code);
break;
default:
_this.error.emit(error);
break;
}
});
};
SignInFormComponent.decorators = [
{ type: Component, args: [{
selector: 'ngx-firebase-auth-sign-in-form',
template: "<form [formGroup]=\"fg\" (ngSubmit)=\"submit()\">\n\n <div class=\"form-group\">\n <label [attr.for]=\"formId + 'email'\">Email Address</label>\n\n <input\n readonly\n #emailInput\n [attr.id]=\"formId + 'email'\"\n [attr.aria-describedby]=\"formId + 'email'\"\n type=\"email\"\n autocomplete=\"email\"\n placeholder=\"Email Address\"\n formControlName=\"email\"\n class=\"form-control\">\n <div class=\"invalid-feedback\" [@fadeInOut]=\"'in'\"\n *ngIf=\"emailFc.hasError('required')\">\n Required.\n </div>\n <div class=\"invalid-feedback\" [@fadeInOut]=\"'in'\"\n *ngIf=\"emailFc.hasError('email')\">\n Invalid email.\n </div>\n <div class=\"invalid-feedback\" [@fadeInOut]=\"'in'\"\n *ngIf=\"emailFc.hasError('auth/invalid-email')\">\n Invalid email.\n </div>\n <div class=\"invalid-feedback\" [@fadeInOut]=\"'in'\"\n *ngIf=\"emailFc.hasError('auth/user-not-found')\">\n We could not find an account with that email address.\n <a routerLink=\".\" [queryParams]=\"{action: 'signIn'}\">Create Account</a>\n </div>\n <div class=\"invalid-feedback\" [@fadeInOut]=\"'in'\"\n *ngIf=\"emailFc.hasError('auth/user-disabled')\">\n The account with that email address has been disabled.\n </div>\n <div class=\"invalid-feedback\" [@fadeInOut]=\"'in'\"\n *ngIf=\"emailFc.hasError('ngx-firebase-auth/no-password')\">\n The account with that email address does not have a password.\n Please sign in using:\n <span *ngFor=\"let id of methodsForEmail; let isLast = last\">\n <a routerLink=\".\" [queryParams]=\"{action: 'signInOAuth', providerId: id}\">{{getOAuthProviderName(id)}}</a>\n <span *ngIf=\"!isLast\">\n |\n </span>\n </span>\n </div>\n\n <small class=\"text-muted form-text\" [attr.id]=\"formId + 'email'\" >\n Not your email address?\n <a routerLink=\".\" [queryParams]=\"{action: 'signIn'}\">Start Over</a>\n </small>\n </div>\n\n\n <div class=\"form-group\">\n <div class=\"d-flex justify-content-between align-items-end\">\n <label [attr.for]=\"formId + 'password'\">Password</label>\n <small>\n <a (click)=\"$event.preventDefault(); passwordInput.type = 'password' === passwordInput.type ? 'text' : 'password'\"\n href=\"#\" tabindex=\"-1\" class=\"d-inline-block\">\n <span *ngIf=\"'password' === passwordInput.type\">Show</span>\n <span *ngIf=\"'text' === passwordInput.type\">Hide</span>\n </a>\n </small>\n </div>\n <input\n #passwordInput\n [attr.id]=\"formId + 'password'\"\n [attr.aria-describedby]=\"formId + 'password-help'\"\n type=\"password\"\n formControlName=\"password\"\n placeholder=\"Password\"\n autocomplete=\"password\"\n class=\"form-control\"\n [class.is-invalid]=\"passwordFc.touched && passwordFc.invalid\">\n <div class=\"invalid-feedback\"\n *ngIf=\"passwordFc.touched && passwordFc.hasError('required')\"\n [@fadeInOut]=\"'in'\">\n Required.\n </div>\n <div class=\"invalid-feedback\"\n *ngIf=\"passwordFc.touched && passwordFc.hasError('auth/wrong-password')\"\n [@fadeInOut]=\"'in'\">\n Wrong password.\n </div>\n <small [attr.id]=\"formId + 'password-help'\" class=\"form-text text-muted\">\n Forgot? <a routerLink=\".\" [queryParams]=\"{action: 'resetPassword'}\">Reset Password</a>\n </small>\n </div>\n <div class=\"form-group\">\n <div class=\"form-check\">\n <input\n class=\"form-check-input\"\n type=\"checkbox\"\n [value]=\"true\"\n formControlName=\"remember\"\n [attr.id]=\"formId + 'remember'\">\n <label class=\"form-check-label\" [attr.for]=\"formId + 'remember'\">\n Remember me on this device.\n </label>\n </div>\n </div>\n <div class=\"form-group\">\n <button type=\"submit\"\n class=\"btn btn-success btn-block\"\n [disabled]=\"fg.invalid || submitting\">\n <i class=\"fas fa-lock fa-fw\" aria-hidden=\"true\"></i>\n Sign In\n </button>\n </div>\n</form>\n",
styles: [""],
animations: [fadeInOutAnimation]
},] },
];
/** @nocollapse */
SignInFormComponent.ctorParameters = function () { return [
{ type: AngularFireAuth },
{ type: NgxFirebaseAuthService }
]; };
SignInFormComponent.propDecorators = {
passwordInput: [{ type: ViewChild, args: ['passwordInput',] }],
email: [{ type: Input }],
remember: [{ type: Input }],
rememberChange: [{ type: Output }],
success: [{ type: Output }],
error: [{ type: Output }]
};
return SignInFormComponent;
}());
export { SignInFormComponent };
if (false) {
/** @type {?} */
SignInFormComponent.prototype.passwordInput;
/** @type {?} */
SignInFormComponent.prototype.email;
/** @type {?} */
SignInFormComponent.prototype.remember;
/** @type {?} */
SignInFormComponent.prototype.rememberChange;
/** @type {?} */
SignInFormComponent.prototype.success;
/** @type {?} */
SignInFormComponent.prototype.error;
/** @type {?} */
SignInFormComponent.prototype.formId;
/** @type {?} */
SignInFormComponent.prototype.submitting;
/** @type {?} */
SignInFormComponent.prototype.fg;
/** @type {?} */
SignInFormComponent.prototype.emailFc;
/** @type {?} */
SignInFormComponent.prototype.passwordFc;
/** @type {?} */
SignInFormComponent.prototype.rememberFc;
/** @type {?} */
SignInFormComponent.prototype.methodsForEmail;
/** @type {?} */
SignInFormComponent.prototype.getOAuthProviderIcon;
/** @type {?} */
SignInFormComponent.prototype.getOAuthProviderName;
/** @type {?} */
SignInFormComponent.prototype._afAuth;
/** @type {?} */
SignInFormComponent.prototype._authService;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2lnbi1pbi1mb3JtLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiJuZzovL0Bub3d6b28vbmd4LWZpcmViYXNlLWF1dGgvIiwic291cmNlcyI6WyJsaWIvc2lnbi1pbi9zaWduLWluLWZvcm0vc2lnbi1pbi1mb3JtLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7O0FBQUEsT0FBTyxFQUFFLFNBQVMsRUFBeUIsS0FBSyxFQUFFLE1BQU0sRUFBRSxZQUFZLEVBQUUsU0FBUyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNySCxPQUFPLEVBQUUsV0FBVyxFQUFFLFNBQVMsRUFBRSxVQUFVLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUNwRSxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFHcEQsT0FBTyxFQUFFLHlCQUF5QixFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFDOUQsT0FBTyxFQUFFLHNCQUFzQixFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFDekUsT0FBTyxFQUFFLG9CQUFvQixFQUFFLG9CQUFvQixFQUFFLGtCQUFrQixFQUFFLE1BQU0sY0FBYyxDQUFDOztJQTJJNUYsNkJBQ1UsU0FDQTtRQURBLFlBQU8sR0FBUCxPQUFPO1FBQ1AsaUJBQVksR0FBWixZQUFZOzhCQWY0QixJQUFJLFlBQVksRUFBRTt1QkFDYixJQUFJLFlBQVksRUFBRTtxQkFDN0IsSUFBSSxZQUFZLEVBQUU7c0JBRXJELGlDQUFpQzswQkFDN0IsS0FBSzsrQkFLVSxFQUFFO29DQUNQLG9CQUFvQjtvQ0FDcEIsb0JBQW9CO0tBSXRDO0lBRUwsc0JBQUkscUNBQUk7Ozs7UUFBUjtZQUNFLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQztTQUMxQjs7O09BQUE7SUFFRCxzQkFBSSw0Q0FBVzs7OztRQUFmO1lBQ0UsTUFBTSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUM7U0FDMUI7OztPQUFBOzs7O0lBR0Qs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LFVBQVUsQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUM5QixLQUFJLENBQUMsVUFBVSxDQUFDLGFBQWEsRUFBRSxDQUFDO1lBQ2hDLE1BQU0sQ0FBQyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO2dCQUNuQixLQUFLLG9CQUFvQixDQUFDO2dCQUMxQixLQUFLLHFCQUFxQixDQUFDO2dCQUMzQixLQUFLLG9CQUFvQixDQUFDO2dCQUMxQixLQUFLLCtCQUErQjtvQkFDbEMseUJBQXlCLENBQUMsb0JBQW9CLENBQUMsS0FBSSxDQUFDLE9BQU8sRUFBRSxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUM7b0JBQ3pFLEtBQUssQ0FBQztnQkFDUixLQUFLLHFCQUFxQjtvQkFDeEIseUJBQXlCLENBQUMsb0JBQW9CLENBQUMsS0FBSSxDQUFDLFVBQVUsRUFBRSxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUM7b0JBQzVFLEtBQUssQ0FBQztnQkFDUjtvQkFDRSxLQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztvQkFDdkIsS0FBSyxDQUFDO2FBQ1Q7U0FDRixDQUFDLENBQUM7S0FDTjs7Z0JBMU5GLFNBQVMsU0FBQztvQkFDVCxRQUFRLEVBQUUsZ0NBQWdDO29CQUMxQyxRQUFRLEVBQUUseWxJQWdIWDtvQkFDQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLENBQUM7b0JBQ1osVUFBVSxFQUFFLENBQUMsa0JBQWtCLENBQUM7aUJBQ2pDOzs7O2dCQTdIUSxlQUFlO2dCQUlmLHNCQUFzQjs7O2dDQTRINUIsU0FBUyxTQUFDLGVBQWU7d0JBQ3pCLEtBQUs7MkJBQ0wsS0FBSztpQ0FDTCxNQUFNOzBCQUNOLE1BQU07d0JBQ04sTUFBTTs7OEJBdklUOztTQWdJYSxtQkFBbUIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIE9uSW5pdCwgQWZ0ZXJWaWV3SW5pdCwgSW5wdXQsIE91dHB1dCwgRXZlbnRFbWl0dGVyLCBWaWV3Q2hpbGQsIEVsZW1lbnRSZWYgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEZvcm1Db250cm9sLCBGb3JtR3JvdXAsIFZhbGlkYXRvcnMgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQgeyBBbmd1bGFyRmlyZUF1dGggfSBmcm9tICdhbmd1bGFyZmlyZTIvYXV0aCc7XG5pbXBvcnQgeyBhdXRoIH0gZnJvbSAnZmlyZWJhc2UvYXBwJztcblxuaW1wb3J0IHsgTmd4RmlyZWJhc2VBdXRoRm9ybUhlbHBlciB9IGZyb20gJy4uLy4uL2Zvcm0taGVscGVyJztcbmltcG9ydCB7IE5neEZpcmViYXNlQXV0aFNlcnZpY2UgfSBmcm9tICcuLi8uLi9uZ3gtZmlyZWJhc2UtYXV0aC5zZXJ2aWNlJztcbmltcG9ydCB7IGdldE9BdXRoUHJvdmlkZXJJY29uLCBnZXRPQXV0aFByb3ZpZGVyTmFtZSwgZmFkZUluT3V0QW5pbWF0aW9uIH0gZnJvbSAnLi4vLi4vc2hhcmVkJztcblxuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICduZ3gtZmlyZWJhc2UtYXV0aC1zaWduLWluLWZvcm0nLFxuICB0ZW1wbGF0ZTogYDxmb3JtIFtmb3JtR3JvdXBdPVwiZmdcIiAobmdTdWJtaXQpPVwic3VibWl0KClcIj5cblxuICA8ZGl2IGNsYXNzPVwiZm9ybS1ncm91cFwiPlxuICAgIDxsYWJlbCBbYXR0ci5mb3JdPVwiZm9ybUlkICsgJ2VtYWlsJ1wiPkVtYWlsIEFkZHJlc3M8L2xhYmVsPlxuXG4gICAgPGlucHV0XG4gICAgICByZWFkb25seVxuICAgICAgI2VtYWlsSW5wdXRcbiAgICAgIFthdHRyLmlkXT1cImZvcm1JZCArICdlbWFpbCdcIlxuICAgICAgW2F0dHIuYXJpYS1kZXNjcmliZWRieV09XCJmb3JtSWQgKyAnZW1haWwnXCJcbiAgICAgIHR5cGU9XCJlbWFpbFwiXG4gICAgICBhdXRvY29tcGxldGU9XCJlbWFpbFwiXG4gICAgICBwbGFjZWhvbGRlcj1cIkVtYWlsIEFkZHJlc3NcIlxuICAgICAgZm9ybUNvbnRyb2xOYW1lPVwiZW1haWxcIlxuICAgICAgY2xhc3M9XCJmb3JtLWNvbnRyb2xcIj5cbiAgICA8ZGl2IGNsYXNzPVwiaW52YWxpZC1mZWVkYmFja1wiIFtAZmFkZUluT3V0XT1cIidpbidcIlxuICAgICAgKm5nSWY9XCJlbWFpbEZjLmhhc0Vycm9yKCdyZXF1aXJlZCcpXCI+XG4gICAgICBSZXF1aXJlZC5cbiAgICA8L2Rpdj5cbiAgICA8ZGl2IGNsYXNzPVwiaW52YWxpZC1mZWVkYmFja1wiIFtAZmFkZUluT3V0XT1cIidpbidcIlxuICAgICAgKm5nSWY9XCJlbWFpbEZjLmhhc0Vycm9yKCdlbWFpbCcpXCI+XG4gICAgICBJbnZhbGlkIGVtYWlsLlxuICAgIDwvZGl2PlxuICAgIDxkaXYgY2xhc3M9XCJpbnZhbGlkLWZlZWRiYWNrXCIgW0BmYWRlSW5PdXRdPVwiJ2luJ1wiXG4gICAgICAqbmdJZj1cImVtYWlsRmMuaGFzRXJyb3IoJ2F1dGgvaW52YWxpZC1lbWFpbCcpXCI+XG4gICAgICBJbnZhbGlkIGVtYWlsLlxuICAgIDwvZGl2PlxuICAgIDxkaXYgY2xhc3M9XCJpbnZhbGlkLWZlZWRiYWNrXCIgW0BmYWRlSW5PdXRdPVwiJ2luJ1wiXG4gICAgICAqbmdJZj1cImVtYWlsRmMuaGFzRXJyb3IoJ2F1dGgvdXNlci1ub3QtZm91bmQnKVwiPlxuICAgICAgV2UgY291bGQgbm90IGZpbmQgYW4gYWNjb3VudCB3aXRoIHRoYXQgZW1haWwgYWRkcmVzcy5cbiAgICAgIDxhIHJvdXRlckxpbms9XCIuXCIgW3F1ZXJ5UGFyYW1zXT1cInthY3Rpb246ICdzaWduSW4nfVwiPkNyZWF0ZSBBY2NvdW50PC9hPlxuICAgIDwvZGl2PlxuICAgIDxkaXYgY2xhc3M9XCJpbnZhbGlkLWZlZWRiYWNrXCIgW0BmYWRlSW5PdXRdPVwiJ2luJ1wiXG4gICAgICAqbmdJZj1cImVtYWlsRmMuaGFzRXJyb3IoJ2F1dGgvdXNlci1kaXNhYmxlZCcpXCI+XG4gICAgICBUaGUgYWNjb3VudCB3aXRoIHRoYXQgZW1haWwgYWRkcmVzcyBoYXMgYmVlbiBkaXNhYmxlZC5cbiAgICA8L2Rpdj5cbiAgICA8ZGl2IGNsYXNzPVwiaW52YWxpZC1mZWVkYmFja1wiIFtAZmFkZUluT3V0XT1cIidpbidcIlxuICAgICAgKm5nSWY9XCJlbWFpbEZjLmhhc0Vycm9yKCduZ3gtZmlyZWJhc2UtYXV0aC9uby1wYXNzd29yZCcpXCI+XG4gICAgICBUaGUgYWNjb3VudCB3aXRoIHRoYXQgZW1haWwgYWRkcmVzcyBkb2VzIG5vdCBoYXZlIGEgcGFzc3dvcmQuXG4gICAgICBQbGVhc2Ugc2lnbiBpbiB1c2luZzpcbiAgICAgIDxzcGFuICpuZ0Zvcj1cImxldCBpZCBvZiBtZXRob2RzRm9yRW1haWw7IGxldCBpc0xhc3QgPSBsYXN0XCI+XG4gICAgICAgIDxhIHJvdXRlckxpbms9XCIuXCIgW3F1ZXJ5UGFyYW1zXT1cInthY3Rpb246ICdzaWduSW5PQXV0aCcsIHByb3ZpZGVySWQ6IGlkfVwiPnt7Z2V0T0F1dGhQcm92aWRlck5hbWUoaWQpfX08L2E+XG4gICAgICAgIDxzcGFuICpuZ0lmPVwiIWlzTGFzdFwiPlxuICAgICAgICAgIHxcbiAgICAgICAgPC9zcGFuPlxuICAgICAgPC9zcGFuPlxuICAgIDwvZGl2PlxuXG4gICAgPHNtYWxsIGNsYXNzPVwidGV4dC1tdXRlZCBmb3JtLXRleHRcIiBbYXR0ci5pZF09XCJmb3JtSWQgKyAnZW1haWwnXCIgPlxuICAgICAgTm90IHlvdXIgZW1haWwgYWRkcmVzcz9cbiAgICAgIDxhIHJvdXRlckxpbms9XCIuXCIgW3F1ZXJ5UGFyYW1zXT1cInthY3Rpb246ICdzaWduSW4nfVwiPlN0YXJ0IE92ZXI8L2E+XG4gICAgPC9zbWFsbD5cbiAgPC9kaXY+XG5cblxuICA8ZGl2IGNsYXNzPVwiZm9ybS1ncm91cFwiPlxuICAgIDxkaXYgY2xhc3M9XCJkLWZsZXgganVzdGlmeS1jb250ZW50LWJldHdlZW4gYWxpZ24taXRlbXMtZW5kXCI+XG4gICAgICA8bGFiZWwgW2F0dHIuZm9yXT1cImZvcm1JZCArICdwYXNzd29yZCdcIj5QYXNzd29yZDwvbGFiZWw+XG4gICAgICA8c21hbGw+XG4gICAgICAgIDxhIChjbGljayk9XCIkZXZlbnQucHJldmVudERlZmF1bHQoKTsgcGFzc3dvcmRJbnB1dC50eXBlID0gJ3Bhc3N3b3JkJyA9PT0gcGFzc3dvcmRJbnB1dC50eXBlICA/ICd0ZXh0JyA6ICdwYXNzd29yZCdcIlxuICAgICAgICAgIGhyZWY9XCIjXCIgdGFiaW5kZXg9XCItMVwiIGNsYXNzPVwiZC1pbmxpbmUtYmxvY2tcIj5cbiAgICAgICAgICA8c3BhbiAqbmdJZj1cIidwYXNzd29yZCcgPT09IHBhc3N3b3JkSW5wdXQudHlwZVwiPlNob3c8L3NwYW4+XG4gICAgICAgICAgPHNwYW4gKm5nSWY9XCIndGV4dCcgPT09IHBhc3N3b3JkSW5wdXQudHlwZVwiPkhpZGU8L3NwYW4+XG4gICAgICAgIDwvYT5cbiAgICAgIDwvc21hbGw+XG4gICAgPC9kaXY+XG4gICAgPGlucHV0XG4gICAgICAjcGFzc3dvcmRJbnB1dFxuICAgICAgW2F0dHIuaWRdPVwiZm9ybUlkICsgJ3Bhc3N3b3JkJ1wiXG4gICAgICBbYXR0ci5hcmlhLWRlc2NyaWJlZGJ5XT1cImZvcm1JZCArICdwYXNzd29yZC1oZWxwJ1wiXG4gICAgICB0eXBlPVwicGFzc3dvcmRcIlxuICAgICAgZm9ybUNvbnRyb2xOYW1lPVwicGFzc3dvcmRcIlxuICAgICAgcGxhY2Vob2xkZXI9XCJQYXNzd29yZFwiXG4gICAgICBhdXRvY29tcGxldGU9XCJwYXNzd29yZFwiXG4gICAgICBjbGFzcz1cImZvcm0tY29udHJvbFwiXG4gICAgICBbY2xhc3MuaXMtaW52YWxpZF09XCJwYXNzd29yZEZjLnRvdWNoZWQgJiYgcGFzc3dvcmRGYy5pbnZhbGlkXCI+XG4gICAgPGRpdiBjbGFzcz1cImludmFsaWQtZmVlZGJhY2tcIlxuICAgICAgKm5nSWY9XCJwYXNzd29yZEZjLnRvdWNoZWQgJiYgcGFzc3dvcmRGYy5oYXNFcnJvcigncmVxdWlyZWQnKVwiXG4gICAgICBbQGZhZGVJbk91dF09XCInaW4nXCI+XG4gICAgICBSZXF1aXJlZC5cbiAgICA8L2Rpdj5cbiAgICA8ZGl2IGNsYXNzPVwiaW52YWxpZC1mZWVkYmFja1wiXG4gICAgICAqbmdJZj1cInBhc3N3b3JkRmMudG91Y2hlZCAmJiBwYXNzd29yZEZjLmhhc0Vycm9yKCdhdXRoL3dyb25nLXBhc3N3b3JkJylcIlxuICAgICAgW0BmYWRlSW5PdXRdPVwiJ2luJ1wiPlxuICAgICAgV3JvbmcgcGFzc3dvcmQuXG4gICAgPC9kaXY+XG4gICAgPHNtYWxsIFthdHRyLmlkXT1cImZvcm1JZCArICdwYXNzd29yZC1oZWxwJ1wiIGNsYXNzPVwiZm9ybS10ZXh0IHRleHQtbXV0ZWRcIj5cbiAgICAgIEZvcmdvdD8gPGEgcm91dGVyTGluaz1cIi5cIiBbcXVlcnlQYXJhbXNdPVwie2FjdGlvbjogJ3Jlc2V0UGFzc3dvcmQnfVwiPlJlc2V0IFBhc3N3b3JkPC9hPlxuICAgIDwvc21hbGw+XG4gIDwvZGl2PlxuICA8ZGl2IGNsYXNzPVwiZm9ybS1ncm91cFwiPlxuICAgIDxkaXYgY2xhc3M9XCJmb3JtLWNoZWNrXCI+XG4gICAgICA8aW5wdXRcbiAgICAgICAgY2xhc3M9XCJmb3JtLWNoZWNrLWlucHV0XCJcbiAgICAgICAgdHlwZT1cImNoZWNrYm94XCJcbiAgICAgICAgW3ZhbHVlXT1cInRydWVcIlxuICAgICAgICBmb3JtQ29udHJvbE5hbWU9XCJyZW1lbWJlclwiXG4gICAgICAgIFthdHRyLmlkXT1cImZvcm1JZCArICdyZW1lbWJlcidcIj5cbiAgICAgIDxsYWJlbCBjbGFzcz1cImZvcm0tY2hlY2stbGFiZWxcIiBbYXR0ci5mb3JdPVwiZm9ybUlkICsgJ3JlbWVtYmVyJ1wiPlxuICAgICAgICBSZW1lbWJlciBtZSBvbiB0aGlzIGRldmljZS5cbiAgICAgIDwvbGFiZWw+XG4gICAgPC9kaXY+XG4gIDwvZGl2PlxuICA8ZGl2IGNsYXNzPVwiZm9ybS1ncm91cFwiPlxuICAgIDxidXR0b24gdHlwZT1cInN1Ym1pdFwiXG4gICAgICBjbGFzcz1cImJ0biBidG4tc3VjY2VzcyBidG4tYmxvY2tcIlxuICAgICAgW2Rpc2FibGVkXT1cImZnLmludmFsaWQgfHwgc3VibWl0dGluZ1wiPlxuICAgICAgPGkgY2xhc3M9XCJmYXMgZmEtbG9jayBmYS1md1wiIGFyaWEtaGlkZGVuPVwidHJ1ZVwiPjwvaT5cbiAgICAgIFNpZ24gSW5cbiAgICA8L2J1dHRvbj5cbiAgPC9kaXY+XG48L2Zvcm0+XG5gLFxuICBzdHlsZXM6IFtgYF0sXG4gIGFuaW1hdGlvbnM6IFtmYWRlSW5PdXRBbmltYXRpb25dXG59KVxuZXhwb3J0IGNsYXNzIFNpZ25JbkZvcm1Db21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIEFmdGVyVmlld0luaXQge1xuXG4gIEBWaWV3Q2hpbGQoJ3Bhc3N3b3JkSW5wdXQnKSBwYXNzd29yZElucHV0OiBFbGVtZW50UmVmO1xuICBASW5wdXQoKSBlbWFpbDogc3RyaW5nO1xuICBASW5wdXQoKSByZW1lbWJlcjogYm9vbGVhbjtcbiAgQE91dHB1dCgpIHJlbWVtYmVyQ2hhbmdlOiBFdmVudEVtaXR0ZXI8Ym9vbGVhbj4gPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG4gIEBPdXRwdXQoKSBzdWNjZXNzOiBFdmVudEVtaXR0ZXI8YXV0aC5Vc2VyQ3JlZGVudGlhbD4gPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG4gIEBPdXRwdXQoKSBlcnJvcjogRXZlbnRFbWl0dGVyPGF1dGguRXJyb3I+ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuXG4gIGZvcm1JZCA9ICduZ3gtZmlyZWJhc2UtYXV0aC1zaWduLWluLWZvcm0tJztcbiAgc3VibWl0dGluZyA9IGZhbHNlO1xuICBmZzogRm9ybUdyb3VwO1xuICBlbWFpbEZjOiBGb3JtQ29udHJvbDtcbiAgcGFzc3dvcmRGYzogRm9ybUNvbnRyb2w7XG4gIHJlbWVtYmVyRmM6IEZvcm1Db250cm9sO1xuICBtZXRob2RzRm9yRW1haWw6IHN0cmluZ1tdID0gW107XG4gIGdldE9BdXRoUHJvdmlkZXJJY29uID0gZ2V0T0F1dGhQcm92aWRlckljb247XG4gIGdldE9BdXRoUHJvdmlkZXJOYW1lID0gZ2V0T0F1dGhQcm92aWRlck5hbWU7XG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgX2FmQXV0aDogQW5ndWxhckZpcmVBdXRoLFxuICAgIHByaXZhdGUgX2F1dGhTZXJ2aWNlOiBOZ3hGaXJlYmFzZUF1dGhTZXJ2aWNlXG4gICkgeyB9XG5cbiAgZ2V0IGF1dGgoKTogYXV0aC5BdXRoIHtcbiAgICByZXR1cm4gdGhpcy5fYWZBdXRoLmF1dGg7XG4gIH1cblxuICBnZXQgYXV0aFNlcnZpY2UoKTogTmd4RmlyZWJhc2VBdXRoU2VydmljZSB7XG4gICAgcmV0dXJuIHRoaXMuX2F1dGhTZXJ2aWNlO1xuICB9XG5cblxuICBuZ09uSW5pdCgpIHtcbiAgICB0aGlzLmVtYWlsRmMgPSBuZXcgRm9ybUNvbnRyb2woXG4gICAgICB0aGlzLmVtYWlsLFxuICAgICAge3ZhbGlkYXRvcnM6IFtWYWxpZGF0b3JzLnJlcXVpcmVkLCBWYWxpZGF0b3JzLmVtYWlsXX1cbiAgICApO1xuICAgIHRoaXMucGFzc3dvcmRGYyA9IG5ldyBGb3JtQ29udHJvbCgnJywge3ZhbGlkYXRvcnM6IFtWYWxpZGF0b3JzLnJlcXVpcmVkXX0pO1xuICAgIHRoaXMucmVtZW1iZXJGYyA9IG5ldyBGb3JtQ29udHJvbCh0aGlzLnJlbWVtYmVyKTtcbiAgICB0aGlzLnJlbWVtYmVyRmMudmFsdWVDaGFuZ2VzLnN1YnNjcmliZSh2YWwgPT4gdGhpcy5yZW1lbWJlckNoYW5nZS5lbWl0KHZhbCkpO1xuICAgIHRoaXMuZmcgPSBuZXcgRm9ybUdyb3VwKHtcbiAgICAgIGVtYWlsOiB0aGlzLmVtYWlsRmMsXG4gICAgICBwYXNzd29yZDogdGhpcy5wYXNzd29yZEZjLFxuICAgICAgcmVtZW1iZXI6IHRoaXMucmVtZW1iZXJGY1xuICAgIH0pO1xuICB9XG4gIG5nQWZ0ZXJWaWV3SW5pdCgpIHtcbiAgICB0aGlzLnBhc3N3b3JkSW5wdXQubmF0aXZlRWxlbWVudC5mb2N1cygpO1xuICB9XG5cblxuXG4gIHN1Ym1pdCgpIHtcbiAgICBjb25zdCBlbWFpbCA9IHRoaXMuZW1haWxGYy52YWx1ZS50cmltKCk7XG4gICAgdGhpcy5zdWJtaXR0aW5nID0gdHJ1ZTtcbiAgICB0aGlzLm1ldGhvZHNGb3JFbWFpbCA9IFtdO1xuICAgIGxldCBjcmVkOiBhdXRoLlVzZXJDcmVkZW50aWFsO1xuICAgIHRoaXMuYXV0aC5mZXRjaFNpZ25Jbk1ldGhvZHNGb3JFbWFpbChlbWFpbClcbiAgICAgIC50aGVuKHJlc3VsdHMgPT4ge1xuICAgICAgICB0aGlzLm1ldGhvZHNGb3JFbWFpbCA9IHJlc3VsdHM7XG4gICAgICAgIGlmIChyZXN1bHRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdCh7XG4gICAgICAgICAgICBjb2RlOiAnYXV0aC91c2VyLW5vdC1mb3VuZCdcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocmVzdWx0cy5pbmRleE9mKCdwYXNzd29yZCcpID09PSAtMSkge1xuICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdCh7XG4gICAgICAgICAgICBjb2RlOiAnbmd4LWZpcmViYXNlLWF1dGgvbm8tcGFzc3dvcmQnLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLmF1dGguc2lnbkluV2l0aEVtYWlsQW5kUGFzc3dvcmQoZW1haWwsIHRoaXMucGFzc3dvcmRGYy52YWx1ZSk7XG4gICAgICB9KVxuICAgICAgLnRoZW4ocmVzdWx0ID0+IHtcbiAgICAgICAgY3JlZCA9IHJlc3VsdDtcbiAgICAgICAgcmV0dXJuIHRoaXMuYXV0aFNlcnZpY2Uuc2V0UmVtZW1iZXJlZCh0aGlzLnJlbWVtYmVyRmMudmFsdWUgPT09IHRydWUsIGVtYWlsKTtcbiAgICAgIH0pXG4gICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgIHRoaXMuc3VjY2Vzcy5lbWl0KGNyZWQpO1xuICAgICAgfSlcbiAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgIHRoaXMuc3VibWl0dGluZyA9IGZhbHNlO1xuICAgICAgICB0aGlzLmVtYWlsRmMubWFya0FzRGlydHkoKTtcbiAgICAgICAgdGhpcy5lbWFpbEZjLm1hcmtBc1RvdWNoZWQoKTtcbiAgICAgICAgdGhpcy5wYXNzd29yZEZjLm1hcmtBc0RpcnR5KCk7XG4gICAgICAgIHRoaXMucGFzc3dvcmRGYy5tYXJrQXNUb3VjaGVkKCk7XG4gICAgICAgIHN3aXRjaCAoZXJyb3IuY29kZSkge1xuICAgICAgICAgIGNhc2UgJ2F1dGgvaW52YWxpZC1lbWFpbCc6XG4gICAgICAgICAgY2FzZSAnYXV0aC91c2VyLW5vdC1mb3VuZCc6XG4gICAgICAgICAgY2FzZSAnYXV0aC91c2VyLWRpc2FibGVkJzpcbiAgICAgICAgICBjYXNlICduZ3gtZmlyZWJhc2UtYXV0aC9uby1wYXNzd29yZCc6XG4gICAgICAgICAgICBOZ3hGaXJlYmFzZUF1dGhGb3JtSGVscGVyLnNldEVycm9yVW50aWxDaGFuZ2VkKHRoaXMuZW1haWxGYywgZXJyb3IuY29kZSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBjYXNlICdhdXRoL3dyb25nLXBhc3N3b3JkJzpcbiAgICAgICAgICAgIE5neEZpcmViYXNlQXV0aEZvcm1IZWxwZXIuc2V0RXJyb3JVbnRpbENoYW5nZWQodGhpcy5wYXNzd29yZEZjLCBlcnJvci5jb2RlKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICB0aGlzLmVycm9yLmVtaXQoZXJyb3IpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICB9XG5cbn1cbiJdfQ==