UNPKG

ngx-auth-firebaseui-updated

Version:

From ngx-auth-firbaseui but updated to fix dependency issues with Angular 16. Open Source Library for Angular Web Apps to integrate a material user interface for firebase authentication

197 lines 50.2 kB
import { Component, EventEmitter, forwardRef, Inject, Input, Output, PLATFORM_ID, ViewEncapsulation } from '@angular/core'; import { Validators } from '@angular/forms'; import { Subject } from 'rxjs'; import { takeUntil } from 'rxjs/operators'; import { NgxAuthFirebaseuiAnimations } from '../../animations'; import { isPlatformBrowser } from '@angular/common'; import { NgxAuthFirebaseUIConfigToken } from '../../tokens'; import * as i0 from "@angular/core"; import * as i1 from "@angular/forms"; import * as i2 from "../../services/auth-process.service"; import * as i3 from "@angular/common"; import * as i4 from "@angular/material/input"; import * as i5 from "@angular/material/form-field"; import * as i6 from "@angular/material/button"; import * as i7 from "@angular/material/icon"; import * as i8 from "@angular/material/checkbox"; export const confirmPasswordValidator = (control) => { if (!control.parent || !control) { return null; } const password = control.parent.get('password'); const passwordConfirm = control.parent.get('passwordConfirm'); if (!password || !passwordConfirm) { return null; } if (passwordConfirm.value === '') { return null; } if (password.value === passwordConfirm.value) { return null; } return { passwordsNotMatching: true }; }; export class NgxAuthFirebaseuiRegisterComponent { // eslint-disable-next-line @typescript-eslint/ban-types constructor(platformId, config, formBuilder, authProcess) { // Configure the layout this.platformId = platformId; this.config = config; this.formBuilder = formBuilder; this.authProcess = authProcess; // i18n common this.titleText = 'CREATE AN ACCOUNT'; this.termsAndConditionsText = 'I read and accept the'; this.termsAndConditionsLinkText = 'terms and conditions'; this.privacyPolicyText = 'I read and accept the'; this.privacyPolicyLinkText = 'privacy policy'; this.createAccountButtonText = 'CREATE AN ACCOUNT'; this.alreadyHaveAccountText = 'Already have an account?'; this.loginButtonText = 'LOGIN'; // i18n name this.nameText = 'Name'; this.nameErrorRequiredText = 'Name is required'; // i18n email this.emailText = 'Email'; this.emailErrorRequiredText = 'Email is required'; this.emailErrorPatternText = 'Please enter a valid email address'; // i18n password this.passwordText = 'Password'; this.passwordErrorRequiredText = 'Password is required'; this.passwordConfirmationText = 'Password Confirmation'; this.passwordConfirmationErrorRequiredText = 'Password confirmation is required'; this.passwordErrorMatchText = 'Password must match'; this.passwordErrorMinLengthText = "The password is too short!"; this.passwordErrorMaxLengthText = "The password is too long!"; // eslint-disable-next-line @angular-eslint/no-output-on-prefix this.onLoginRequested = new EventEmitter(); this.onCreateAccountButtonClicked = new EventEmitter(); this.authenticationError = false; // Set the private defaults this.unsubscribeAll = new Subject(); this.onSuccess = authProcess.onSuccessEmitter; this.onError = authProcess.onErrorEmitter; } get color() { return this.authenticationError ? 'warn' : 'primary'; } get colorAccent() { return this.authenticationError ? 'warn' : 'accent'; } ngOnInit() { if (isPlatformBrowser(this.platformId)) { this.onErrorSubscription = this.onError.subscribe(() => this.authenticationError = true); } this.registerForm = this.formBuilder.group({ name: ['', Validators.required], email: ['', [Validators.required, Validators.email]], password: ['', [Validators.required, Validators.minLength(this.config.passwordMinLength), Validators.maxLength(this.config.passwordMaxLength)]], passwordConfirm: ['', [Validators.required, confirmPasswordValidator]], tos: [''], privacyPolicy: [''] }); // If tos or privacy policy url set, ensure that the two form items are required if (this.tosUrl) { this.registerForm.controls.tos.setValidators(Validators.requiredTrue); } if (this.privacyPolicyUrl) { this.registerForm.controls.privacyPolicy.setValidators(Validators.requiredTrue); } // Update the validity of the 'passwordConfirm' field // when the 'password' field changes this.registerForm .controls .password .valueChanges.pipe(takeUntil(this.unsubscribeAll)) .subscribe(() => { this.registerForm.controls.passwordConfirm.updateValueAndValidity(); }); } /** * On destroy */ ngOnDestroy() { // Unsubscribe from all subscriptions this.unsubscribeAll.next(null); this.unsubscribeAll.complete(); } async createAccount() { // Emit the create account clicked event. this.onCreateAccountButtonClicked.emit(); return await this.authProcess.signUp(this.registerForm.controls.name.value, { email: this.registerForm.controls.email.value, password: this.registerForm.controls.password.value }); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NgxAuthFirebaseuiRegisterComponent, deps: [{ token: PLATFORM_ID }, { token: forwardRef(() => NgxAuthFirebaseUIConfigToken) }, { token: i1.UntypedFormBuilder }, { token: i2.AuthProcessService }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: NgxAuthFirebaseuiRegisterComponent, selector: "ngx-auth-firebaseui-register", inputs: { logoUrl: "logoUrl", appearance: "appearance", tosUrl: "tosUrl", privacyPolicyUrl: "privacyPolicyUrl", titleText: "titleText", termsAndConditionsText: "termsAndConditionsText", termsAndConditionsLinkText: "termsAndConditionsLinkText", privacyPolicyText: "privacyPolicyText", privacyPolicyLinkText: "privacyPolicyLinkText", createAccountButtonText: "createAccountButtonText", alreadyHaveAccountText: "alreadyHaveAccountText", loginButtonText: "loginButtonText", nameText: "nameText", nameErrorRequiredText: "nameErrorRequiredText", emailText: "emailText", emailErrorRequiredText: "emailErrorRequiredText", emailErrorPatternText: "emailErrorPatternText", passwordText: "passwordText", passwordErrorRequiredText: "passwordErrorRequiredText", passwordConfirmationText: "passwordConfirmationText", passwordConfirmationErrorRequiredText: "passwordConfirmationErrorRequiredText", passwordErrorMatchText: "passwordErrorMatchText", passwordErrorMinLengthText: "passwordErrorMinLengthText", passwordErrorMaxLengthText: "passwordErrorMaxLengthText" }, outputs: { onSuccess: "onSuccess", onError: "onError", onLoginRequested: "onLoginRequested", onCreateAccountButtonClicked: "onCreateAccountButtonClicked" }, ngImport: i0, template: "<div class=\"register-container\" id=\"register\">\n\n <div class=\"register-form-wrapper centered\">\n\n <div [@animateStagger]=\"{ value: '50' }\" id=\"register-form\">\n\n <div *ngIf=\"logoUrl\" class=\"logo\">\n <img [@animate]=\"{ value: '*', params: { x: '50px' } }\" [src]=\"logoUrl\" alt=\"logo\">\n </div>\n\n <div [@animate]=\"{ value: '*', params: { x: '-50px' } }\" class=\"title\">{{titleText}}</div>\n\n <form [@animate]=\"{value:'*',params:{duration:'300ms',y:'100px'}}\" [formGroup]=\"registerForm\" name=\"registerForm\" novalidate>\n\n <mat-form-field [@animate]=\"{ value: '*', params: { x: '50px' } }\" [appearance]=\"appearance\">\n <input [placeholder]=\"nameText\" formControlName=\"name\" matInput/>\n <mat-icon [color]=\"color\" matSuffix>person</mat-icon>\n <mat-error>\n {{nameErrorRequiredText}}\n </mat-error>\n </mat-form-field>\n\n <mat-form-field [@animate]=\"{ value: '*', params: { x: '50px' } }\" [appearance]=\"appearance\">\n <input [placeholder]=\"emailText\" formControlName=\"email\" matInput autocomplete=\"username\"/>\n <mat-icon [color]=\"color\" matSuffix>email</mat-icon>\n <mat-error *ngIf=\"registerForm.get('email')?.hasError('required')\">\n {{emailErrorRequiredText}}\n </mat-error>\n <mat-error *ngIf=\"registerForm.get('email')?.hasError('email')\">\n {{emailErrorPatternText}}\n </mat-error>\n </mat-form-field>\n\n <mat-form-field [@animate]=\"{ value: '*', params: { x: '50px' } }\" [appearance]=\"appearance\">\n <input [placeholder]=\"passwordText\" formControlName=\"password\" matInput type=\"password\" autocomplete=\"new-password\"/>\n <mat-icon [color]=\"color\" matSuffix>lock</mat-icon>\n <mat-error *ngIf=\"registerForm.get('password')?.hasError('required')\">\n {{passwordErrorRequiredText}}\n </mat-error>\n <mat-error *ngIf=\"registerForm.get('password')?.hasError('minlength')\">\n {{ passwordErrorMinLengthText }}\n </mat-error>\n <mat-error *ngIf=\"registerForm.get('password')?.hasError('maxlength')\">\n {{ passwordErrorMaxLengthText }}\n </mat-error>\n </mat-form-field>\n\n <mat-form-field [@animate]=\"{ value: '*', params: { x: '50px' } }\" [appearance]=\"appearance\">\n <input [placeholder]=\"passwordConfirmationText\" formControlName=\"passwordConfirm\" matInput type=\"password\" autocomplete=\"new-password\"/>\n <mat-icon [color]=\"color\" matSuffix>lock</mat-icon>\n <mat-error *ngIf=\"registerForm.get('passwordConfirm')?.hasError('required')\">\n {{passwordConfirmationErrorRequiredText}}\n </mat-error>\n <mat-error *ngIf=\"registerForm.get('passwordConfirm')?.hasError('passwordsNotMatching')\">\n {{passwordErrorMatchText}}\n </mat-error>\n </mat-form-field>\n\n <div *ngIf=\"this.tosUrl\">\n <mat-checkbox aria-label=\"{{termsAndConditionsText}}\" formControlName=\"tos\" required>\n <span>{{termsAndConditionsText}}</span>\n <a target=\"_blank\" [href]=\"this.tosUrl\">{{termsAndConditionsLinkText}}</a>\n </mat-checkbox>\n </div>\n\n <div *ngIf=\"this.privacyPolicyUrl\">\n <mat-checkbox aria-label=\"{{privacyPolicyText}}\" formControlName=\"privacyPolicy\" required>\n <span>{{privacyPolicyText}}</span>\n <a target=\"_blank\" [href]=\"this.privacyPolicyUrl\">{{privacyPolicyLinkText}}</a>\n </mat-checkbox>\n </div>\n\n <button (click)=\"createAccount()\" [color]=\"colorAccent\" [disabled]=\"registerForm.invalid\" aria-label=\"CREATE AN ACCOUNT\" class=\"submit-button\" id=\"createAccountButton\" mat-raised-button>\n {{createAccountButtonText}}\n </button>\n </form>\n\n <div [@animate]=\"{value:'*',params:{duration:'300ms',y:'100px'}}\" class=\"register\" class=\"centered\">\n <span [@animate]=\"{ value: '*', params: { x: '100px' } }\" class=\"text\">\n {{alreadyHaveAccountText}}\n </span>\n <button (click)=\"onLoginRequested.emit()\" [@animate]=\"{ value: '*', params: { x: '-100px' } }\" [color]=\"colorAccent\" id=\"loginButton\" mat-button type=\"button\">\n {{loginButtonText}}\n </button>\n </div>\n\n </div>\n </div>\n</div>\n", styles: ["ngx-auth-firebaseui-register #register{width:100%;background-size:cover}ngx-auth-firebaseui-register #register #register-form-wrapper{flex:1 0 auto;padding:32px}@media screen and (max-width: 599px){ngx-auth-firebaseui-register #register #register-form-wrapper{padding:16px}}ngx-auth-firebaseui-register #register #register-form-wrapper #register-form{width:384px;max-width:384px;padding:32px;text-align:center}@media screen and (max-width: 599px){ngx-auth-firebaseui-register #register #register-form-wrapper #register-form{padding:24px;width:100%}}ngx-auth-firebaseui-register #register #register-form-wrapper #register-form .logo{width:128px;margin:32px auto}ngx-auth-firebaseui-register #register #register-form-wrapper #register-form .title{font-size:20px;margin:16px 0 32px}ngx-auth-firebaseui-register #register #register-form-wrapper #register-form form{width:100%;text-align:left}ngx-auth-firebaseui-register #register #register-form-wrapper #register-form form mat-form-field{width:100%}ngx-auth-firebaseui-register #register #register-form-wrapper #register-form form mat-checkbox{margin:0}ngx-auth-firebaseui-register #register #register-form-wrapper #register-form form .terms{margin:16px 0 32px}ngx-auth-firebaseui-register #register #register-form-wrapper #register-form form .terms a{font-size:16px;margin-left:4px}ngx-auth-firebaseui-register #register #register-form-wrapper #register-form form .submit-button{width:220px;margin:16px auto;display:block}@media screen and (max-width: 599px){ngx-auth-firebaseui-register #register #register-form-wrapper #register-form form .submit-button{width:90%}}ngx-auth-firebaseui-register #register #register-form-wrapper #register-form .register{margin:32px auto 24px;font-weight:500}ngx-auth-firebaseui-register #register #register-form-wrapper #register-form .register .text{margin-right:8px}ngx-auth-firebaseui-register #register #register-form-wrapper #register-form .separator{font-size:15px;font-weight:600;margin:24px auto;position:relative;overflow:hidden;width:100px}ngx-auth-firebaseui-register #register #register-form-wrapper #register-form .separator .text{display:inline-flex;position:relative;padding:0 8px;z-index:9999}ngx-auth-firebaseui-register #register #register-form-wrapper #register-form .separator .text:before,ngx-auth-firebaseui-register #register #register-form-wrapper #register-form .separator .text:after{content:\"\";display:block;width:30px;position:absolute;top:10px;border-top:1px solid}ngx-auth-firebaseui-register #register #register-form-wrapper #register-form .separator .text:before{right:100%}ngx-auth-firebaseui-register #register #register-form-wrapper #register-form .separator .text:after{left:100%}ngx-auth-firebaseui-register #register #register-form-wrapper #register-form button.google,ngx-auth-firebaseui-register #register #register-form-wrapper #register-form button.facebook{width:192px;text-transform:none;color:#fff;font-size:13px}@media screen and (max-width: 599px){ngx-auth-firebaseui-register #register #register-form-wrapper #register-form button{width:80%}}ngx-auth-firebaseui-register #register #register-form-wrapper #register-form button.google{background-color:#d73d32;margin-bottom:8px}ngx-auth-firebaseui-register #register #register-form-wrapper #register-form button.facebook{background-color:#3f5c9a}ngx-auth-firebaseui-register ::ng-deep .mat-checkbox-label{display:flex;flex-wrap:wrap}\n"], dependencies: [{ kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i4.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i5.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i5.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i5.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "component", type: i6.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: i7.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i8.MatCheckbox, selector: "mat-checkbox", inputs: ["disableRipple", "color", "tabIndex"], exportAs: ["matCheckbox"] }, { kind: "directive", type: i8.MatCheckboxRequiredValidator, selector: "mat-checkbox[required][formControlName], mat-checkbox[required][formControl], mat-checkbox[required][ngModel]" }], animations: NgxAuthFirebaseuiAnimations, encapsulation: i0.ViewEncapsulation.None }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NgxAuthFirebaseuiRegisterComponent, decorators: [{ type: Component, args: [{ selector: 'ngx-auth-firebaseui-register', encapsulation: ViewEncapsulation.None, animations: NgxAuthFirebaseuiAnimations, template: "<div class=\"register-container\" id=\"register\">\n\n <div class=\"register-form-wrapper centered\">\n\n <div [@animateStagger]=\"{ value: '50' }\" id=\"register-form\">\n\n <div *ngIf=\"logoUrl\" class=\"logo\">\n <img [@animate]=\"{ value: '*', params: { x: '50px' } }\" [src]=\"logoUrl\" alt=\"logo\">\n </div>\n\n <div [@animate]=\"{ value: '*', params: { x: '-50px' } }\" class=\"title\">{{titleText}}</div>\n\n <form [@animate]=\"{value:'*',params:{duration:'300ms',y:'100px'}}\" [formGroup]=\"registerForm\" name=\"registerForm\" novalidate>\n\n <mat-form-field [@animate]=\"{ value: '*', params: { x: '50px' } }\" [appearance]=\"appearance\">\n <input [placeholder]=\"nameText\" formControlName=\"name\" matInput/>\n <mat-icon [color]=\"color\" matSuffix>person</mat-icon>\n <mat-error>\n {{nameErrorRequiredText}}\n </mat-error>\n </mat-form-field>\n\n <mat-form-field [@animate]=\"{ value: '*', params: { x: '50px' } }\" [appearance]=\"appearance\">\n <input [placeholder]=\"emailText\" formControlName=\"email\" matInput autocomplete=\"username\"/>\n <mat-icon [color]=\"color\" matSuffix>email</mat-icon>\n <mat-error *ngIf=\"registerForm.get('email')?.hasError('required')\">\n {{emailErrorRequiredText}}\n </mat-error>\n <mat-error *ngIf=\"registerForm.get('email')?.hasError('email')\">\n {{emailErrorPatternText}}\n </mat-error>\n </mat-form-field>\n\n <mat-form-field [@animate]=\"{ value: '*', params: { x: '50px' } }\" [appearance]=\"appearance\">\n <input [placeholder]=\"passwordText\" formControlName=\"password\" matInput type=\"password\" autocomplete=\"new-password\"/>\n <mat-icon [color]=\"color\" matSuffix>lock</mat-icon>\n <mat-error *ngIf=\"registerForm.get('password')?.hasError('required')\">\n {{passwordErrorRequiredText}}\n </mat-error>\n <mat-error *ngIf=\"registerForm.get('password')?.hasError('minlength')\">\n {{ passwordErrorMinLengthText }}\n </mat-error>\n <mat-error *ngIf=\"registerForm.get('password')?.hasError('maxlength')\">\n {{ passwordErrorMaxLengthText }}\n </mat-error>\n </mat-form-field>\n\n <mat-form-field [@animate]=\"{ value: '*', params: { x: '50px' } }\" [appearance]=\"appearance\">\n <input [placeholder]=\"passwordConfirmationText\" formControlName=\"passwordConfirm\" matInput type=\"password\" autocomplete=\"new-password\"/>\n <mat-icon [color]=\"color\" matSuffix>lock</mat-icon>\n <mat-error *ngIf=\"registerForm.get('passwordConfirm')?.hasError('required')\">\n {{passwordConfirmationErrorRequiredText}}\n </mat-error>\n <mat-error *ngIf=\"registerForm.get('passwordConfirm')?.hasError('passwordsNotMatching')\">\n {{passwordErrorMatchText}}\n </mat-error>\n </mat-form-field>\n\n <div *ngIf=\"this.tosUrl\">\n <mat-checkbox aria-label=\"{{termsAndConditionsText}}\" formControlName=\"tos\" required>\n <span>{{termsAndConditionsText}}</span>\n <a target=\"_blank\" [href]=\"this.tosUrl\">{{termsAndConditionsLinkText}}</a>\n </mat-checkbox>\n </div>\n\n <div *ngIf=\"this.privacyPolicyUrl\">\n <mat-checkbox aria-label=\"{{privacyPolicyText}}\" formControlName=\"privacyPolicy\" required>\n <span>{{privacyPolicyText}}</span>\n <a target=\"_blank\" [href]=\"this.privacyPolicyUrl\">{{privacyPolicyLinkText}}</a>\n </mat-checkbox>\n </div>\n\n <button (click)=\"createAccount()\" [color]=\"colorAccent\" [disabled]=\"registerForm.invalid\" aria-label=\"CREATE AN ACCOUNT\" class=\"submit-button\" id=\"createAccountButton\" mat-raised-button>\n {{createAccountButtonText}}\n </button>\n </form>\n\n <div [@animate]=\"{value:'*',params:{duration:'300ms',y:'100px'}}\" class=\"register\" class=\"centered\">\n <span [@animate]=\"{ value: '*', params: { x: '100px' } }\" class=\"text\">\n {{alreadyHaveAccountText}}\n </span>\n <button (click)=\"onLoginRequested.emit()\" [@animate]=\"{ value: '*', params: { x: '-100px' } }\" [color]=\"colorAccent\" id=\"loginButton\" mat-button type=\"button\">\n {{loginButtonText}}\n </button>\n </div>\n\n </div>\n </div>\n</div>\n", styles: ["ngx-auth-firebaseui-register #register{width:100%;background-size:cover}ngx-auth-firebaseui-register #register #register-form-wrapper{flex:1 0 auto;padding:32px}@media screen and (max-width: 599px){ngx-auth-firebaseui-register #register #register-form-wrapper{padding:16px}}ngx-auth-firebaseui-register #register #register-form-wrapper #register-form{width:384px;max-width:384px;padding:32px;text-align:center}@media screen and (max-width: 599px){ngx-auth-firebaseui-register #register #register-form-wrapper #register-form{padding:24px;width:100%}}ngx-auth-firebaseui-register #register #register-form-wrapper #register-form .logo{width:128px;margin:32px auto}ngx-auth-firebaseui-register #register #register-form-wrapper #register-form .title{font-size:20px;margin:16px 0 32px}ngx-auth-firebaseui-register #register #register-form-wrapper #register-form form{width:100%;text-align:left}ngx-auth-firebaseui-register #register #register-form-wrapper #register-form form mat-form-field{width:100%}ngx-auth-firebaseui-register #register #register-form-wrapper #register-form form mat-checkbox{margin:0}ngx-auth-firebaseui-register #register #register-form-wrapper #register-form form .terms{margin:16px 0 32px}ngx-auth-firebaseui-register #register #register-form-wrapper #register-form form .terms a{font-size:16px;margin-left:4px}ngx-auth-firebaseui-register #register #register-form-wrapper #register-form form .submit-button{width:220px;margin:16px auto;display:block}@media screen and (max-width: 599px){ngx-auth-firebaseui-register #register #register-form-wrapper #register-form form .submit-button{width:90%}}ngx-auth-firebaseui-register #register #register-form-wrapper #register-form .register{margin:32px auto 24px;font-weight:500}ngx-auth-firebaseui-register #register #register-form-wrapper #register-form .register .text{margin-right:8px}ngx-auth-firebaseui-register #register #register-form-wrapper #register-form .separator{font-size:15px;font-weight:600;margin:24px auto;position:relative;overflow:hidden;width:100px}ngx-auth-firebaseui-register #register #register-form-wrapper #register-form .separator .text{display:inline-flex;position:relative;padding:0 8px;z-index:9999}ngx-auth-firebaseui-register #register #register-form-wrapper #register-form .separator .text:before,ngx-auth-firebaseui-register #register #register-form-wrapper #register-form .separator .text:after{content:\"\";display:block;width:30px;position:absolute;top:10px;border-top:1px solid}ngx-auth-firebaseui-register #register #register-form-wrapper #register-form .separator .text:before{right:100%}ngx-auth-firebaseui-register #register #register-form-wrapper #register-form .separator .text:after{left:100%}ngx-auth-firebaseui-register #register #register-form-wrapper #register-form button.google,ngx-auth-firebaseui-register #register #register-form-wrapper #register-form button.facebook{width:192px;text-transform:none;color:#fff;font-size:13px}@media screen and (max-width: 599px){ngx-auth-firebaseui-register #register #register-form-wrapper #register-form button{width:80%}}ngx-auth-firebaseui-register #register #register-form-wrapper #register-form button.google{background-color:#d73d32;margin-bottom:8px}ngx-auth-firebaseui-register #register #register-form-wrapper #register-form button.facebook{background-color:#3f5c9a}ngx-auth-firebaseui-register ::ng-deep .mat-checkbox-label{display:flex;flex-wrap:wrap}\n"] }] }], ctorParameters: function () { return [{ type: Object, decorators: [{ type: Inject, args: [PLATFORM_ID] }] }, { type: undefined, decorators: [{ type: Inject, args: [forwardRef(() => NgxAuthFirebaseUIConfigToken)] }] }, { type: i1.UntypedFormBuilder }, { type: i2.AuthProcessService }]; }, propDecorators: { logoUrl: [{ type: Input }], appearance: [{ type: Input }], tosUrl: [{ type: Input }], privacyPolicyUrl: [{ type: Input }], titleText: [{ type: Input }], termsAndConditionsText: [{ type: Input }], termsAndConditionsLinkText: [{ type: Input }], privacyPolicyText: [{ type: Input }], privacyPolicyLinkText: [{ type: Input }], createAccountButtonText: [{ type: Input }], alreadyHaveAccountText: [{ type: Input }], loginButtonText: [{ type: Input }], nameText: [{ type: Input }], nameErrorRequiredText: [{ type: Input }], emailText: [{ type: Input }], emailErrorRequiredText: [{ type: Input }], emailErrorPatternText: [{ type: Input }], passwordText: [{ type: Input }], passwordErrorRequiredText: [{ type: Input }], passwordConfirmationText: [{ type: Input }], passwordConfirmationErrorRequiredText: [{ type: Input }], passwordErrorMatchText: [{ type: Input }], passwordErrorMinLengthText: [{ type: Input }], passwordErrorMaxLengthText: [{ type: Input }], onSuccess: [{ type: Output }], onError: [{ type: Output }], onLoginRequested: [{ type: Output }], onCreateAccountButtonClicked: [{ type: Output }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmd4LWF1dGgtZmlyZWJhc2V1aS1yZWdpc3Rlci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtYXV0aC1maXJlYmFzZXVpL3NyYy9saWIvY29tcG9uZW50cy9uZ3gtYXV0aC1maXJlYmFzZXVpLXJlZ2lzdGVyL25neC1hdXRoLWZpcmViYXNldWktcmVnaXN0ZXIuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LWF1dGgtZmlyZWJhc2V1aS9zcmMvbGliL2NvbXBvbmVudHMvbmd4LWF1dGgtZmlyZWJhc2V1aS1yZWdpc3Rlci9uZ3gtYXV0aC1maXJlYmFzZXVpLXJlZ2lzdGVyLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBQyxTQUFTLEVBQUUsWUFBWSxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFxQixNQUFNLEVBQUUsV0FBVyxFQUFFLGlCQUFpQixFQUFDLE1BQU0sZUFBZSxDQUFDO0FBQzVJLE9BQU8sRUFBdUYsVUFBVSxFQUFDLE1BQU0sZ0JBQWdCLENBQUM7QUFDaEksT0FBTyxFQUFDLE9BQU8sRUFBZSxNQUFNLE1BQU0sQ0FBQztBQUMzQyxPQUFPLEVBQUMsU0FBUyxFQUFDLE1BQU0sZ0JBQWdCLENBQUM7QUFFekMsT0FBTyxFQUFDLDJCQUEyQixFQUFDLE1BQU0sa0JBQWtCLENBQUM7QUFFN0QsT0FBTyxFQUFDLGlCQUFpQixFQUFDLE1BQU0saUJBQWlCLENBQUM7QUFHbEQsT0FBTyxFQUFFLDRCQUE0QixFQUFFLE1BQU0sY0FBYyxDQUFDOzs7Ozs7Ozs7O0FBRzVELE1BQU0sQ0FBQyxNQUFNLHdCQUF3QixHQUFnQixDQUFDLE9BQXdCLEVBQTJCLEVBQUU7SUFDekcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLElBQUksQ0FBQyxPQUFPLEVBQUU7UUFDL0IsT0FBTyxJQUFJ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QUFDLFVBQVUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyw0QkFBNEIsQ0FBQzs4R0FyRC9DLE9BQU87c0JBQWYsS0FBSztnQkFDRyxVQUFVO3NCQUFsQixLQUFLO2dCQUNHLE1BQU07c0JBQWQsS0FBSztnQkFDRyxnQkFBZ0I7c0JBQXhCLEtBQUs7Z0JBR0csU0FBUztzQkFBakIsS0FBSztnQkFDRyxzQkFBc0I7c0JBQTlCLEtBQUs7Z0JBQ0csMEJBQTBCO3NCQUFsQyxLQUFLO2dCQUNHLGlCQUFpQjtzQkFBekIsS0FBSztnQkFDRyxxQkFBcUI7c0JBQTdCLEtBQUs7Z0JBQ0csdUJBQXVCO3NCQUEvQixLQUFLO2dCQUNHLHNCQUFzQjtzQkFBOUIsS0FBSztnQkFDRyxlQUFlO3NCQUF2QixLQUFLO2dCQUdHLFFBQVE7c0JBQWhCLEtBQUs7Z0JBQ0cscUJBQXFCO3NCQUE3QixLQUFLO2dCQUdHLFNBQVM7c0JBQWpCLEtBQUs7Z0JBQ0csc0JBQXNCO3NCQUE5QixLQUFLO2dCQUNHLHFCQUFxQjtzQkFBN0IsS0FBSztnQkFHRyxZQUFZO3NCQUFwQixLQUFLO2dCQUNHLHlCQUF5QjtzQkFBakMsS0FBSztnQkFDRyx3QkFBd0I7c0JBQWhDLEtBQUs7Z0JBQ0cscUNBQXFDO3NCQUE3QyxLQUFLO2dCQUNHLHNCQUFzQjtzQkFBOUIsS0FBSztnQkFDRywwQkFBMEI7c0JBQWxDLEtBQUs7Z0JBQ0csMEJBQTBCO3NCQUFsQyxLQUFLO2dCQUlJLFNBQVM7c0JBQWxCLE1BQU07Z0JBRUcsT0FBTztzQkFBaEIsTUFBTTtnQkFFRyxnQkFBZ0I7c0JBQXpCLE1BQU07Z0JBRUcsNEJBQTRCO3NCQUFyQyxNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtDb21wb25lbnQsIEV2ZW50RW1pdHRlciwgZm9yd2FyZFJlZiwgSW5qZWN0LCBJbnB1dCwgT25EZXN0cm95LCBPbkluaXQsIE91dHB1dCwgUExBVEZPUk1fSUQsIFZpZXdFbmNhcHN1bGF0aW9ufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7QWJzdHJhY3RDb250cm9sLCBVbnR5cGVkRm9ybUJ1aWxkZXIsIFVudHlwZWRGb3JtR3JvdXAsIFZhbGlkYXRpb25FcnJvcnMsIFZhbGlkYXRvckZuLCBWYWxpZGF0b3JzfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQge1N1YmplY3QsIFN1YnNjcmlwdGlvbn0gZnJvbSAncnhqcyc7XG5pbXBvcnQge3Rha2VVbnRpbH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuXG5pbXBvcnQge05neEF1dGhGaXJlYmFzZXVpQW5pbWF0aW9uc30gZnJvbSAnLi4vLi4vYW5pbWF0aW9ucyc7XG5pbXBvcnQge0F1dGhQcm9jZXNzU2VydmljZX0gZnJvbSAnLi4vLi4vc2VydmljZXMvYXV0aC1wcm9jZXNzLnNlcnZpY2UnO1xuaW1wb3J0IHtpc1BsYXRmb3JtQnJvd3Nlcn0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7TWF0Rm9ybUZpZWxkQXBwZWFyYW5jZX0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvZm9ybS1maWVsZCc7XG5pbXBvcnQge1RoZW1lUGFsZXR0ZX0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvY29yZSc7XG5pbXBvcnQgeyBOZ3hBdXRoRmlyZWJhc2VVSUNvbmZpZ1Rva2VuIH0gZnJvbSAnLi4vLi4vdG9rZW5zJztcbmltcG9ydCB7IE5neEF1dGhGaXJlYmFzZVVJQ29uZmlnIH0gZnJvbSAnLi4vLi4vaW50ZXJmYWNlcyc7XG5cbmV4cG9ydCBjb25zdCBjb25maXJtUGFzc3dvcmRWYWxpZGF0b3I6IFZhbGlkYXRvckZuID0gKGNvbnRyb2w6IEFic3RyYWN0Q29udHJvbCk6IFZhbGlkYXRpb25FcnJvcnMgfCBudWxsID0+IHtcbiAgaWYgKCFjb250cm9sLnBhcmVudCB8fCAhY29udHJvbCkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgY29uc3QgcGFzc3dvcmQgPSBjb250cm9sLnBhcmVudC5nZXQoJ3Bhc3N3b3JkJyk7XG4gIGNvbnN0IHBhc3N3b3JkQ29uZmlybSA9IGNvbnRyb2wucGFyZW50LmdldCgncGFzc3dvcmRDb25maXJtJyk7XG5cbiAgaWYgKCFwYXNzd29yZCB8fCAhcGFzc3dvcmRDb25maXJtKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBpZiAocGFzc3dvcmRDb25maXJtLnZhbHVlID09PSAnJykge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgaWYgKHBhc3N3b3JkLnZhbHVlID09PSBwYXNzd29yZENvbmZpcm0udmFsdWUpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHJldHVybiB7cGFzc3dvcmRzTm90TWF0Y2hpbmc6IHRydWV9O1xufTtcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnbmd4LWF1dGgtZmlyZWJhc2V1aS1yZWdpc3RlcicsXG4gIHRlbXBsYXRlVXJsOiAnLi9uZ3gtYXV0aC1maXJlYmFzZXVpLXJlZ2lzdGVyLmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vbmd4LWF1dGgtZmlyZWJhc2V1aS1yZWdpc3Rlci5jb21wb25lbnQuc2NzcyddLFxuICBlbmNhcHN1bGF0aW9uOiBWaWV3RW5jYXBzdWxhdGlvbi5Ob25lLFxuICBhbmltYXRpb25zOiBOZ3hBdXRoRmlyZWJhc2V1aUFuaW1hdGlvbnNcbn0pXG5leHBvcnQgY2xhc3MgTmd4QXV0aEZpcmViYXNldWlSZWdpc3RlckNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgT25EZXN0cm95IHtcblxuICBASW5wdXQoKSBsb2dvVXJsOiBzdHJpbmc7XG4gIEBJbnB1dCgpIGFwcGVhcmFuY2U6IE1hdEZvcm1GaWVsZEFwcGVhcmFuY2U7XG4gIEBJbnB1dCgpIHRvc1VybDogc3RyaW5nO1xuICBASW5wdXQoKSBwcml2YWN5UG9saWN5VXJsOiBzdHJpbmc7XG5cbiAgLy8gaTE4biBjb21tb25cbiAgQElucHV0KCkgdGl0bGVUZXh0ID0gJ0NSRUFURSBBTiBBQ0NPVU5UJztcbiAgQElucHV0KCkgdGVybXNBbmRDb25kaXRpb25zVGV4dCA9ICdJIHJlYWQgYW5kIGFjY2VwdCB0aGUnO1xuICBASW5wdXQoKSB0ZXJtc0FuZENvbmRpdGlvbnNMaW5rVGV4dCA9ICd0ZXJtcyBhbmQgY29uZGl0aW9ucyc7XG4gIEBJbnB1dCgpIHByaXZhY3lQb2xpY3lUZXh0ID0gJ0kgcmVhZCBhbmQgYWNjZXB0IHRoZSc7XG4gIEBJbnB1dCgpIHByaXZhY3lQb2xpY3lMaW5rVGV4dCA9ICdwcml2YWN5IHBvbGljeSc7XG4gIEBJbnB1dCgpIGNyZWF0ZUFjY291bnRCdXR0b25UZXh0ID0gJ0NSRUFURSBBTiBBQ0NPVU5UJztcbiAgQElucHV0KCkgYWxyZWFkeUhhdmVBY2NvdW50VGV4dCA9ICdBbHJlYWR5IGhhdmUgYW4gYWNjb3VudD8nO1xuICBASW5wdXQoKSBsb2dpbkJ1dHRvblRleHQgPSAnTE9HSU4nO1xuXG4gIC8vIGkxOG4gbmFtZVxuICBASW5wdXQoKSBuYW1lVGV4dCA9ICdOYW1lJztcbiAgQElucHV0KCkgbmFtZUVycm9yUmVxdWlyZWRUZXh0ID0gJ05hbWUgaXMgcmVxdWlyZWQnO1xuXG4gIC8vIGkxOG4gZW1haWxcbiAgQElucHV0KCkgZW1haWxUZXh0ID0gJ0VtYWlsJztcbiAgQElucHV0KCkgZW1haWxFcnJvclJlcXVpcmVkVGV4dCA9ICdFbWFpbCBpcyByZXF1aXJlZCc7XG4gIEBJbnB1dCgpIGVtYWlsRXJyb3JQYXR0ZXJuVGV4dCA9ICdQbGVhc2UgZW50ZXIgYSB2YWxpZCBlbWFpbCBhZGRyZXNzJztcblxuICAvLyBpMThuIHBhc3N3b3JkXG4gIEBJbnB1dCgpIHBhc3N3b3JkVGV4dCA9ICdQYXNzd29yZCc7XG4gIEBJbnB1dCgpIHBhc3N3b3JkRXJyb3JSZXF1aXJlZFRleHQgPSAnUGFzc3dvcmQgaXMgcmVxdWlyZWQnO1xuICBASW5wdXQoKSBwYXNzd29yZENvbmZpcm1hdGlvblRleHQgPSAnUGFzc3dvcmQgQ29uZmlybWF0aW9uJztcbiAgQElucHV0KCkgcGFzc3dvcmRDb25maXJtYXRpb25FcnJvclJlcXVpcmVkVGV4dCA9ICdQYXNzd29yZCBjb25maXJtYXRpb24gaXMgcmVxdWlyZWQnO1xuICBASW5wdXQoKSBwYXNzd29yZEVycm9yTWF0Y2hUZXh0ID0gJ1Bhc3N3b3JkIG11c3QgbWF0Y2gnO1xuICBASW5wdXQoKSBwYXNzd29yZEVycm9yTWluTGVuZ3RoVGV4dCA9IFwiVGhlIHBhc3N3b3JkIGlzIHRvbyBzaG9ydCFcIjtcbiAgQElucHV0KCkgcGFzc3dvcmRFcnJvck1heExlbmd0aFRleHQgPSBcIlRoZSBwYXNzd29yZCBpcyB0b28gbG9uZyFcIjtcblxuICAvLyBFdmVudHNcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEBhbmd1bGFyLWVzbGludC9uby1vdXRwdXQtb24tcHJlZml4XG4gIEBPdXRwdXQoKSBvblN1Y2Nlc3M6IGFueTtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEBhbmd1bGFyLWVzbGludC9uby1vdXRwdXQtb24tcHJlZml4XG4gIEBPdXRwdXQoKSBvbkVycm9yOiBhbnk7XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAYW5ndWxhci1lc2xpbnQvbm8tb3V0cHV0LW9uLXByZWZpeFxuICBAT3V0cHV0KCkgb25Mb2dpblJlcXVlc3RlZDogRXZlbnRFbWl0dGVyPHZvaWQ+ID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuXG4gIEBPdXRwdXQoKSBvbkNyZWF0ZUFjY291bnRCdXR0b25DbGlja2VkOiBFdmVudEVtaXR0ZXI8dm9pZD4gPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG5cbiAgcmVnaXN0ZXJGb3JtOiBVbnR5cGVkRm9ybUdyb3VwO1xuICBvbkVycm9yU3Vic2NyaXB0aW9uOiBTdWJzY3JpcHRpb247XG4gIGF1dGhlbnRpY2F0aW9uRXJyb3IgPSBmYWxzZTtcblxuICAvLyBQcml2YXRlXG4gIHByaXZhdGUgdW5zdWJzY3JpYmVBbGw6IFN1YmplY3Q8YW55PjtcblxuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L2Jhbi10eXBlc1xuICBjb25zdHJ1Y3RvcihcbiAgICBASW5qZWN0KFBMQVRGT1JNX0lEKSBwcml2YXRlIHBsYXRmb3JtSWQ6IE9iamVjdCxcbiAgICBASW5qZWN0KGZvcndhcmRSZWYoKCkgPT4gTmd4QXV0aEZpcmViYXNlVUlDb25maWdUb2tlbikpXG4gICAgcHVibGljIGNvbmZpZzogTmd4QXV0aEZpcmViYXNlVUlDb25maWcsXG4gICAgcHJpdmF0ZSBmb3JtQnVpbGRlcjogVW50eXBlZEZvcm1CdWlsZGVyLFxuICAgIHB1YmxpYyBhdXRoUHJvY2VzczogQXV0aFByb2Nlc3NTZXJ2aWNlXG4gICkge1xuICAgIC8vIENvbmZpZ3VyZSB0aGUgbGF5b3V0XG5cbiAgICAvLyBTZXQgdGhlIHByaXZhdGUgZGVmYXVsdHNcbiAgICB0aGlzLnVuc3Vic2NyaWJlQWxsID0gbmV3IFN1YmplY3QoKTtcbiAgICB0aGlzLm9uU3VjY2VzcyA9IGF1dGhQcm9jZXNzLm9uU3VjY2Vzc0VtaXR0ZXI7XG4gICAgdGhpcy5vbkVycm9yID0gYXV0aFByb2Nlc3Mub25FcnJvckVtaXR0ZXI7XG4gIH1cblxuICBnZXQgY29sb3IoKTogc3RyaW5nIHwgVGhlbWVQYWxldHRlIHtcbiAgICByZXR1cm4gdGhpcy5hdXRoZW50aWNhdGlvbkVycm9yID8gJ3dhcm4nIDogJ3ByaW1hcnknO1xuICB9XG5cbiAgZ2V0IGNvbG9yQWNjZW50KCk6IHN0cmluZyB8IFRoZW1lUGFsZXR0ZSB7XG4gICAgcmV0dXJuIHRoaXMuYXV0aGVudGljYXRpb25FcnJvciA/ICd3YXJuJyA6ICdhY2NlbnQnO1xuICB9XG5cbiAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgaWYgKGlzUGxhdGZvcm1Ccm93c2VyKHRoaXMucGxhdGZvcm1JZCkpIHtcbiAgICAgIHRoaXMub25FcnJvclN1YnNjcmlwdGlvbiA9IHRoaXMub25FcnJvci5zdWJzY3JpYmUoKCkgPT4gdGhpcy5hdXRoZW50aWNhdGlvbkVycm9yID0gdHJ1ZSk7XG4gICAgfVxuICAgIHRoaXMucmVnaXN0ZXJGb3JtID0gdGhpcy5mb3JtQnVpbGRlci5ncm91cCh7XG4gICAgICBuYW1lOiBbJycsIFZhbGlkYXRvcnMucmVxdWlyZWRdLFxuICAgICAgZW1haWw6IFsnJywgW1ZhbGlkYXRvcnMucmVxdWlyZWQsIFZhbGlkYXRvcnMuZW1haWxdXSxcbiAgICAgIHBhc3N3b3JkOiBbJycsIFtWYWxpZGF0b3JzLnJlcXVpcmVkLFxuICAgICAgICAgICAgICAgICAgICAgVmFsaWRhdG9ycy5taW5MZW5ndGgodGhpcy5jb25maWcucGFzc3dvcmRNaW5MZW5ndGgpLFxuICAgICAgICAgICAgICAgICAgICAgVmFsaWRhdG9ycy5tYXhMZW5ndGgodGhpcy5jb25maWcucGFzc3dvcmRNYXhMZW5ndGgpXV0sXG4gICAgICBwYXNzd29yZENvbmZpcm06IFsnJywgW1ZhbGlkYXRvcnMucmVxdWlyZWQsIGNvbmZpcm1QYXNzd29yZFZhbGlkYXRvcl1dLFxuICAgICAgdG9zOiBbJyddLFxuICAgICAgcHJpdmFjeVBvbGljeTogWycnXVxuICAgIH0pO1xuXG4gICAgLy8gSWYgdG9zIG9yIHByaXZhY3kgcG9saWN5IHVybCBzZXQsIGVuc3VyZSB0aGF0IHRoZSB0d28gZm9ybSBpdGVtcyBhcmUgcmVxdWlyZWRcbiAgICBpZiAodGhpcy50b3NVcmwpIHtcbiAgICAgIHRoaXMucmVnaXN0ZXJGb3JtLmNvbnRyb2xzLnRvcy5zZXRWYWxpZGF0b3JzKFZhbGlkYXRvcnMucmVxdWlyZWRUcnVlKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5wcml2YWN5UG9saWN5VXJsKSB7XG4gICAgICB0aGlzLnJlZ2lzdGVyRm9ybS5jb250cm9scy5wcml2YWN5UG9saWN5LnNldFZhbGlkYXRvcnMoVmFsaWRhdG9ycy5yZXF1aXJlZFRydWUpO1xuICAgIH1cblxuICAgIC8vIFVwZGF0ZSB0aGUgdmFsaWRpdHkgb2YgdGhlICdwYXNzd29yZENvbmZpcm0nIGZpZWxkXG4gICAgLy8gd2hlbiB0aGUgJ3Bhc3N3b3JkJyBmaWVsZCBjaGFuZ2VzXG4gICAgdGhpcy5yZWdpc3RlckZvcm1cbiAgICAgIC5jb250cm9sc1xuICAgICAgLnBhc3N3b3JkXG4gICAgICAudmFsdWVDaGFuZ2VzLnBpcGUodGFrZVVudGlsKHRoaXMudW5zdWJzY3JpYmVBbGwpKVxuICAgICAgLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgIHRoaXMucmVnaXN0ZXJGb3JtLmNvbnRyb2xzLnBhc3N3b3JkQ29uZmlybS51cGRhdGVWYWx1ZUFuZFZhbGlkaXR5KCk7XG4gICAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBPbiBkZXN0cm95XG4gICAqL1xuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICAvLyBVbnN1YnNjcmliZSBmcm9tIGFsbCBzdWJzY3JpcHRpb25zXG4gICAgdGhpcy51bnN1YnNjcmliZUFsbC5uZXh0KG51bGwpO1xuICAgIHRoaXMudW5zdWJzY3JpYmVBbGwuY29tcGxldGUoKTtcbiAgfVxuXG4gIGFzeW5jIGNyZWF0ZUFjY291bnQoKSB7XG4gICAgLy8gRW1pdCB0aGUgY3JlYXRlIGFjY291bnQgY2xpY2tlZCBldmVudC5cbiAgICB0aGlzLm9uQ3JlYXRlQWNjb3VudEJ1dHRvbkNsaWNrZWQuZW1pdCgpO1xuXG5cbiAgICByZXR1cm4gYXdhaXQgdGhpcy5hdXRoUHJvY2Vzcy5zaWduVXAoXG4gICAgICB0aGlzLnJlZ2lzdGVyRm9ybS5jb250cm9scy5uYW1lLnZhbHVlLFxuICAgICAge1xuICAgICAgICBlbWFpbDogdGhpcy5yZWdpc3RlckZvcm0uY29udHJvbHMuZW1haWwudmFsdWUsXG4gICAgICAgIHBhc3N3b3JkOiB0aGlzLnJlZ2lzdGVyRm9ybS5jb250cm9scy5wYXNzd29yZC52YWx1ZVxuICAgICAgfVxuICAgICk7XG4gIH1cbn1cbiIsIjxkaXYgY2xhc3M9XCJyZWdpc3Rlci1jb250YWluZXJcIiBpZD1cInJlZ2lzdGVyXCI+XG5cbiAgPGRpdiBjbGFzcz1cInJlZ2lzdGVyLWZvcm0td3JhcHBlciBjZW50ZXJlZFwiPlxuXG4gICAgPGRpdiBbQGFuaW1hdGVTdGFnZ2VyXT1cInsgdmFsdWU6ICc1MCcgfVwiIGlkPVwicmVnaXN0ZXItZm9ybVwiPlxuXG4gICAgICA8ZGl2ICpuZ0lmPVwibG9nb1VybFwiIGNsYXNzPVwibG9nb1wiPlxuICAgICAgICA8aW1nIFtAYW5pbWF0ZV09XCJ7IHZhbHVlOiAnKicsIHBhcmFtczogeyB4OiAnNTBweCcgfSB9XCIgW3NyY109XCJsb2dvVXJsXCIgYWx0PVwibG9nb1wiPlxuICAgICAgPC9kaXY+XG5cbiAgICAgIDxkaXYgW0BhbmltYXRlXT1cInsgdmFsdWU6ICcqJywgcGFyYW1zOiB7IHg6ICctNTBweCcgfSB9XCIgY2xhc3M9XCJ0aXRsZVwiPnt7dGl0bGVUZXh0fX08L2Rpdj5cblxuICAgICAgPGZvcm0gW0BhbmltYXRlXT1cInt2YWx1ZTonKicscGFyYW1zOntkdXJhdGlvbjonMzAwbXMnLHk6JzEwMHB4J319XCIgW2Zvcm1Hcm91cF09XCJyZWdpc3RlckZvcm1cIiBuYW1lPVwicmVnaXN0ZXJGb3JtXCIgbm92YWxpZGF0ZT5cblxuICAgICAgICA8bWF0LWZvcm0tZmllbGQgW0BhbmltYXRlXT1cInsgdmFsdWU6ICcqJywgcGFyYW1zOiB7IHg6ICc1MHB4JyB9IH1cIiBbYXBwZWFyYW5jZV09XCJhcHBlYXJhbmNlXCI+XG4gICAgICAgICAgPGlucHV0IFtwbGFjZWhvbGRlcl09XCJuYW1lVGV4dFwiIGZvcm1Db250cm9sTmFtZT1cIm5hbWVcIiBtYXRJbnB1dC8+XG4gICAgICAgICAgPG1hdC1pY29uIFtjb2xvcl09XCJjb2xvclwiIG1hdFN1ZmZpeD5wZXJzb248L21hdC1pY29uPlxuICAgICAgICAgIDxtYXQtZXJyb3I+XG4gICAgICAgICAgICB7e25hbWVFcnJvclJlcXVpcmVkVGV4dH19XG4gICAgICAgICAgPC9tYXQtZXJyb3I+XG4gICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG5cbiAgICAgICAgPG1hdC1mb3JtLWZpZWxkIFtAYW5pbWF0ZV09XCJ7IHZhbHVlOiAnKicsIHBhcmFtczogeyB4OiAnNTBweCcgfSB9XCIgW2FwcGVhcmFuY2VdPVwiYXBwZWFyYW5jZVwiPlxuICAgICAgICAgIDxpbnB1dCBbcGxhY2Vob2xkZXJdPVwiZW1haWxUZXh0XCIgZm9ybUNvbnRyb2xOYW1lPVwiZW1haWxcIiBtYXRJbnB1dCBhdXRvY29tcGxldGU9XCJ1c2VybmFtZVwiLz5cbiAgICAgICAgICA8bWF0LWljb24gW2NvbG9yXT1cImNvbG9yXCIgbWF0U3VmZml4PmVtYWlsPC9tYXQtaWNvbj5cbiAgICAgICAgICA8bWF0LWVycm9yICpuZ0lmPVwicmVnaXN0ZXJGb3JtLmdldCgnZW1haWwnKT8uaGFzRXJyb3IoJ3JlcXVpcmVkJylcIj5cbiAgICAgICAgICAgIHt7ZW1haWxFcnJvclJlcXVpcmVkVGV4dH19XG4gICAgICAgICAgPC9tYXQtZXJyb3I+XG4gICAgICAgICAgPG1hdC1lcnJvciAqbmdJZj1cInJlZ2lzdGVyRm9ybS5nZXQoJ2VtYWlsJyk/Lmhhc0Vycm9yKCdlbWFpbCcpXCI+XG4gICAgICAgICAgICB7e2VtYWlsRXJyb3JQYXR0ZXJuVGV4dH19XG4gICAgICAgICAgPC9tYXQtZXJyb3I+XG4gICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG5cbiAgICAgICAgPG1hdC1mb3JtLWZpZWxkIFtAYW5pbWF0ZV09XCJ7IHZhbHVlOiAnKicsIHBhcmFtczogeyB4OiAnNTBweCcgfSB9XCIgW2FwcGVhcmFuY2VdPVwiYXBwZWFyYW5jZVwiPlxuICAgICAgICAgIDxpbnB1dCBbcGxhY2Vob2xkZXJdPVwicGFzc3dvcmRUZXh0XCIgZm9ybUNvbnRyb2xOYW1lPVwicGFzc3dvcmRcIiBtYXRJbnB1dCB0eXBlPVwicGFzc3dvcmRcIiBhdXRvY29tcGxldGU9XCJuZXctcGFzc3dvcmRcIi8+XG4gICAgICAgICAgPG1hdC1pY29uIFtjb2xvcl09XCJjb2xvclwiIG1hdFN1ZmZpeD5sb2NrPC9tYXQtaWNvbj5cbiAgICAgICAgICA8bWF0LWVycm9yICpuZ0lmPVwicmVnaXN0ZXJGb3JtLmdldCgncGFzc3dvcmQnKT8uaGFzRXJyb3IoJ3JlcXVpcmVkJylcIj5cbiAgICAgICAgICAgIHt7cGFzc3dvcmRFcnJvclJlcXVpcmVkVGV4dH19XG4gICAgICAgICAgPC9tYXQtZXJyb3I+XG4gICAgICAgICAgPG1hdC1lcnJvciAqbmdJZj1cInJlZ2lzdGVyRm9ybS5nZXQoJ3Bhc3N3b3JkJyk/Lmhhc0Vycm9yKCdtaW5sZW5ndGgnKVwiPlxuICAgICAgICAgICAge3sgcGFzc3dvcmRFcnJvck1pbkxlbmd0aFRleHQgfX1cbiAgICAgICAgICA8L21hdC1lcnJvcj5cbiAgICAgICAgICA8bWF0LWVycm9yICpuZ0lmPVwicmVnaXN0ZXJGb3JtLmdldCgncGFzc3dvcmQnKT8uaGFzRXJyb3IoJ21heGxlbmd0aCcpXCI+XG4gICAgICAgICAgICB7eyBwYXNzd29yZEVycm9yTWF4TGVuZ3RoVGV4dCB9fVxuICAgICAgICAgIDwvbWF0LWVycm9yPlxuICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxuXG4gICAgICAgIDxtYXQtZm9ybS1maWVsZCBbQGFuaW1hdGVdPVwieyB2YWx1ZTogJyonLCBwYXJhbXM6IHsgeDogJzUwcHgnIH0gfVwiIFthcHBlYXJhbmNlXT1cImFwcGVhcmFuY2VcIj5cbiAgICAgICAgICA8aW5wdXQgW3BsYWNlaG9sZGVyXT1cInBhc3N3b3JkQ29uZmlybWF0aW9uVGV4dFwiIGZvcm1Db250cm9sTmFtZT1cInBhc3N3b3JkQ29uZmlybVwiIG1hdElucHV0IHR5cGU9XCJwYXNzd29yZFwiIGF1dG9jb21wbGV0ZT1cIm5ldy1wYXNzd29yZFwiLz5cbiAgICAgICAgICA8bWF0LWljb24gW2NvbG9yXT1cImNvbG9yXCIgbWF0U3VmZml4PmxvY2s8L21hdC1pY29uPlxuICAgICAgICAgIDxtYXQtZXJyb3IgKm5nSWY9XCJyZWdpc3RlckZvcm0uZ2V0KCdwYXNzd29yZENvbmZpcm0nKT8uaGFzRXJyb3IoJ3JlcXVpcmVkJylcIj5cbiAgICAgICAgICAgIHt7cGFzc3dvcmRDb25maXJtYXRpb25FcnJvclJlcXVpcmVkVGV4dH19XG4gICAgICAgICAgPC9tYXQtZXJyb3I+XG4gICAgICAgICAgPG1hdC1lcnJvciAqbmdJZj1cInJlZ2lzdGVyRm9ybS5nZXQoJ3Bhc3N3b3JkQ29uZmlybScpPy5oYXNFcnJvcigncGFzc3dvcmRzTm90TWF0Y2hpbmcnKVwiPlxuICAgICAgICAgICAge3twYXNzd29yZEVycm9yTWF0Y2hUZXh0fX1cbiAgICAgICAgICA8L21hdC1lcnJvcj5cbiAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cblxuICAgICAgICA8ZGl2ICpuZ0lmPVwidGhpcy50b3NVcmxcIj5cbiAgICAgICAgICA8bWF0LWNoZWNrYm94IGFyaWEtbGFiZWw9XCJ7e3Rlcm1zQW5kQ29uZGl0aW9uc1RleHR9fVwiIGZvcm1Db250cm9sTmFtZT1cInRvc1wiIHJlcXVpcmVkPlxuICAgICAgICAgICAgPHNwYW4+e3t0ZXJtc0FuZENvbmRpdGlvbnNUZXh0fX08L3NwYW4+XG4gICAgICAgICAgICA8YSB0YXJnZXQ9XCJfYmxhbmtcIiBbaHJlZl09XCJ0aGlzLnRvc1VybFwiPnt7dGVybXNBbmRDb25kaXRpb25zTGlua1RleHR9fTwvYT5cbiAgICAgICAgICA8L21hdC1jaGVja2JveD5cbiAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgPGRpdiAqbmdJZj1cInRoaXMucHJpdmFjeVBvbGljeVVybFwiPlxuICAgICAgICAgIDxtYXQtY2hlY2tib3ggYXJpYS1sYWJlbD1cInt7cHJpdmFjeVBvbGljeVRleHR9fVwiIGZvcm1Db250cm9sTmFtZT1cInByaXZhY3lQb2xpY3lcIiByZXF1aXJlZD5cbiAgICAgICAgICAgIDxzcGFuPnt7cHJpdmFjeVBvbGljeVRleHR9fTwvc3Bhbj5cbiAgICAgICAgICAgIDxhIHRhcmdldD1cIl9ibGFua1wiIFtocmVmXT1cInRoaXMucHJpdmFjeVBvbGljeVVybFwiPnt7cHJpdmFjeVBvbGljeUxpbmtUZXh0fX08L2E+XG4gICAgICAgICAgPC9tYXQtY2hlY2tib3g+XG4gICAgICAgIDwvZGl2PlxuXG4gICAgICAgIDxidXR0b24gKGNsaWNrKT1cImNyZWF0ZUFjY291bnQoKVwiIFtjb2xvcl09XCJjb2xvckFjY2VudFwiIFtkaXNhYmxlZF09XCJyZWdpc3RlckZvcm0uaW52YWxpZFwiIGFyaWEtbGFiZWw9XCJDUkVBVEUgQU4gQUNDT1VOVFwiIGNsYXNzPVwic3VibWl0LWJ1dHRvblwiIGlkPVwiY3JlYXRlQWNjb3VudEJ1dHRvblwiIG1hdC1yYWlzZWQtYnV0dG9uPlxuICAgICAgICAgIHt7Y3JlYXRlQWNjb3VudEJ1dHRvblRleHR9fVxuICAgICAgICA8L2J1dHRvbj5cbiAgICAgIDwvZm9ybT5cblxuICAgICAgPGRpdiBbQGFuaW1hdGVdPVwie3ZhbHVlOicqJyxwYXJhbXM6e2R1cmF0aW9uOiczMDBtcycseTonMTAwcHgnfX1cIiBjbGFzcz1cInJlZ2lzdGVyXCIgY2xhc3M9XCJjZW50ZXJlZFwiPlxuICAgICAgICA8c3BhbiBbQGFuaW1hdGVdPVwieyB2YWx1ZTogJyonLCBwYXJhbXM6IHsgeDogJzEwMHB4JyB9IH1cIiBjbGFzcz1cInRleHRcIj5cbiAgICAgICAgICB7e2FscmVhZHlIYXZlQWNjb3VudFRleHR9fVxuICAgICAgICA8L3NwYW4+XG4gICAgICAgIDxidXR0b24gKGNsaWNrKT1cIm9uTG9naW5SZXF1ZXN0ZWQuZW1pdCgpXCIgW0BhbmltYXRlXT1cInsgdmFsdWU6ICcqJywgcGFyYW1zOiB7IHg6ICctMTAwcHgnIH0gfVwiIFtjb2xvcl09XCJjb2xvckFjY2VudFwiIGlkP