@nowzoo/ngx-firebase-auth
Version:
Angular components for Firebase email-first sign in and out-of-band (oob) actions (reset password, etc).
346 lines (333 loc) • 28.5 kB
JavaScript
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
import { Component, Input, Output, EventEmitter } from '@angular/core';
import { AngularFireAuth } from 'angularfire2/auth';
import { ActivatedRoute, Router } from '@angular/router';
import { auth } from 'firebase/app';
import { FormGroup, FormControl } from '@angular/forms';
import { getOAuthProviderIcon, getOAuthProviderName } from '../../shared';
import { NgxFirebaseAuthService } from '../../ngx-firebase-auth.service';
import { screenAnimation } from '../../shared';
export class SignInOauthComponent {
/**
* @param {?} _afAuth
* @param {?} _svc
* @param {?} _route
* @param {?} _router
*/
constructor(_afAuth, _svc, _route, _router) {
this._afAuth = _afAuth;
this._svc = _svc;
this._route = _route;
this._router = _router;
this.success = new EventEmitter();
this.emailChange = new EventEmitter();
this.rememberChange = new EventEmitter();
this.error = new EventEmitter();
this.screen = 'wait';
this.methodError = null;
this.getOAuthProviderIcon = getOAuthProviderIcon;
this.getOAuthProviderName = getOAuthProviderName;
this.formId = 'ngx-firebase-auth-sign-in-oauth-';
}
/**
* @return {?}
*/
get auth() {
return this._afAuth.auth;
}
/**
* @return {?}
*/
get authService() {
return this._svc;
}
/**
* @return {?}
*/
get route() {
return this._route;
}
/**
* @return {?}
*/
get router() {
return this._router;
}
/**
* @return {?}
*/
ngOnInit() {
this.rememberFc = new FormControl(this.remember);
this.rememberFc.valueChanges.subscribe(val => this.rememberChange.emit(val));
this.fg = new FormGroup({
remember: this.rememberFc
});
if (this.initialError) {
this.handleOAuthError(this.initialError);
}
else {
this.oAuthSignIn(this.providerId);
}
}
/**
* @param {?} id
* @param {?=} forceRedirect
* @return {?}
*/
oAuthSignIn(id, forceRedirect) {
this.methodError = null;
/** @type {?} */
let cred;
if (this.useOAuthPopup && forceRedirect !== true) {
this.getOAuthProvider(id)
.then(provider => {
return this.auth.signInWithPopup(provider);
})
.then((result) => {
cred = result;
return this.authService.setRemembered(this.rememberFc.value === true, result.user.email);
})
.then(() => {
this.success.emit(cred);
})
.catch(error => this.handleOAuthError(error, id));
}
else {
this.router.navigate(['.'], { relativeTo: this.route, queryParams: { remember: this.rememberFc.value === true } })
.then(() => {
return this.getOAuthProvider(id);
})
.then(provider => {
return this.auth.signInWithRedirect(provider);
})
.catch(error => this.handleOAuthError(error, id));
}
}
/**
* @param {?} error
* @param {?=} providerId
* @return {?}
*/
handleOAuthError(error, providerId) {
if (error['email'] && error['credential']) {
this.emailChange.emit(error['email']);
this.auth.fetchSignInMethodsForEmail(error['email'])
.then(results => {
error['methods'] = results;
error['accountHasPassword'] = results.indexOf('password') !== -1;
error['accountOAuthMethods'] = results.filter(id => id !== 'password');
this.methodError = error;
this.screen = 'methodError';
});
return;
}
switch (error.code) {
case 'auth/cancelled-popup-request':
case 'auth/popup-closed-by-user':
this.screen = 'retry';
break;
case 'auth/popup-blocked':
this.oAuthSignIn(providerId, true);
break;
default:
this.error.emit(error);
break;
}
}
/**
* @param {?} id
* @return {?}
*/
getOAuthProvider(id) {
/** @type {?} */
let provider = null;
if (this.oAuthProviderFactory) {
provider = this.oAuthProviderFactory(id);
}
if (!provider) {
switch (id) {
case 'twitter.com':
provider = new auth.TwitterAuthProvider();
break;
case 'facebook.com':
provider = new auth.FacebookAuthProvider();
break;
case 'google.com':
provider = new auth.GoogleAuthProvider();
break;
case 'github.com':
provider = new auth.GithubAuthProvider();
break;
}
}
if (provider) {
return Promise.resolve(provider);
}
else {
return Promise.reject({
code: 'ngx-firebase-auth/no-provider-found',
message: `We could not create an OAuth provider for provider id "${id}".`
});
}
}
}
SignInOauthComponent.decorators = [
{ type: Component, args: [{
selector: 'ngx-firebase-auth-sign-in-oauth',
template: `<div *ngIf="'wait' === screen" []="'in'">
<div class="alert alert-secondary">
<i class="fas fa-spin fa-spinner fa-fw" aria-hidden="true"></i>
Please wait...
</div>
</div>
<div *ngIf="'methodError' === screen" []="'in'">
<div class="alert alert-danger">
<i class="fas fa-exclamation-triangle fa-fw" aria-hidden="true"></i>
We could not sign you in with {{methodError.credential.providerId}}.
</div>
<p class="text-muted">
Please sign in with one of the methods associated with
{{methodError.email}}:
</p>
<div class="list-group">
<a
*ngIf="methodError.accountHasPassword"
routerLink="."
[queryParams]="{action: 'signInPassword'}"
class="list-group-item list-group-item-action">
<i class="fas fa-unlock" aria-hidden="true"></i>
<span class="ml-2">Sign In with Your Password</span>
</a>
<button
*ngFor="let id of methodError.accountOAuthMethods"
(click)="oAuthSignIn(id)"
class="list-group-item list-group-item-action">
<i [attr.class]="getOAuthProviderIcon(id)" aria-hidden="true"></i>
<span class="ml-2">Sign In with {{getOAuthProviderName(id)}}</span>
</button>
</div>
<form [formGroup]="fg">
<div class="form-group">
<div class="form-check">
<input
class="form-check-input"
type="checkbox"
[value]="true"
formControlName="remember"
[attr.id]="formId + 'remember'">
<label class="form-check-label" [attr.for]="formId + 'remember'">
Remember me on this device.
</label>
</div>
</div>
</form>
<p class="text-muted">
Is {{methodError.email}} not your email address?
<a routerLink="." [queryParams]="{action: 'signIn'}">Start Over</a>
</p>
</div>
<div *ngIf="'retry' === screen" []="'in'">
<div class="alert alert-danger">
<i class="fas fa-exclamation-triangle fa-fw" aria-hidden="true"></i>
It looks like you cancelled signing in with
{{getOAuthProviderName(providerId)}}. Try again:
</div>
<div class="list-group">
<button
(click)="oAuthSignIn(providerId)"
class="list-group-item list-group-item-action">
<i [attr.class]="getOAuthProviderIcon(providerId)" aria-hidden="true"></i>
<span class="ml-2">Sign In with {{getOAuthProviderName(providerId)}}</span>
</button>
</div>
<form [formGroup]="fg">
<div class="form-group">
<div class="form-check">
<input
class="form-check-input"
type="checkbox"
[value]="true"
formControlName="remember"
[attr.id]="formId + 'remember'">
<label class="form-check-label" [attr.for]="formId + 'remember'">
Remember me on this device.
</label>
</div>
</div>
</form>
<p class="text-muted">
<a routerLink="." [queryParams]="{action: 'signIn'}">Start Over</a>
</p>
</div>
`,
styles: [``],
animations: [screenAnimation]
},] },
];
/** @nocollapse */
SignInOauthComponent.ctorParameters = () => [
{ type: AngularFireAuth },
{ type: NgxFirebaseAuthService },
{ type: ActivatedRoute },
{ type: Router }
];
SignInOauthComponent.propDecorators = {
providerId: [{ type: Input }],
initialError: [{ type: Input }],
useOAuthPopup: [{ type: Input }],
oAuthProviderFactory: [{ type: Input }],
email: [{ type: Input }],
remember: [{ type: Input }],
success: [{ type: Output }],
emailChange: [{ type: Output }],
rememberChange: [{ type: Output }],
error: [{ type: Output }]
};
if (false) {
/** @type {?} */
SignInOauthComponent.prototype.providerId;
/** @type {?} */
SignInOauthComponent.prototype.initialError;
/** @type {?} */
SignInOauthComponent.prototype.useOAuthPopup;
/** @type {?} */
SignInOauthComponent.prototype.oAuthProviderFactory;
/** @type {?} */
SignInOauthComponent.prototype.email;
/** @type {?} */
SignInOauthComponent.prototype.remember;
/** @type {?} */
SignInOauthComponent.prototype.success;
/** @type {?} */
SignInOauthComponent.prototype.emailChange;
/** @type {?} */
SignInOauthComponent.prototype.rememberChange;
/** @type {?} */
SignInOauthComponent.prototype.error;
/** @type {?} */
SignInOauthComponent.prototype.screen;
/** @type {?} */
SignInOauthComponent.prototype.methodError;
/** @type {?} */
SignInOauthComponent.prototype.getOAuthProviderIcon;
/** @type {?} */
SignInOauthComponent.prototype.getOAuthProviderName;
/** @type {?} */
SignInOauthComponent.prototype.fg;
/** @type {?} */
SignInOauthComponent.prototype.rememberFc;
/** @type {?} */
SignInOauthComponent.prototype.formId;
/** @type {?} */
SignInOauthComponent.prototype._afAuth;
/** @type {?} */
SignInOauthComponent.prototype._svc;
/** @type {?} */
SignInOauthComponent.prototype._route;
/** @type {?} */
SignInOauthComponent.prototype._router;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2lnbi1pbi1vYXV0aC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9Abm93em9vL25neC1maXJlYmFzZS1hdXRoLyIsInNvdXJjZXMiOlsibGliL3NpZ24taW4vc2lnbi1pbi1vYXV0aC9zaWduLWluLW9hdXRoLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7O0FBQUEsT0FBTyxFQUFFLFNBQVMsRUFBVSxLQUFLLEVBQUUsTUFBTSxFQUFFLFlBQVksRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMvRSxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFDcEQsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUN6RCxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sY0FBYyxDQUFDO0FBQ3BDLE9BQU8sRUFBRSxTQUFTLEVBQUUsV0FBVyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFeEQsT0FBTyxFQUFFLG9CQUFvQixFQUFFLG9CQUFvQixFQUFFLE1BQU0sY0FBYyxDQUFDO0FBQzFFLE9BQU8sRUFBRSxzQkFBc0IsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBQ3pFLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxjQUFjLENBQUM7QUEwRy9DLE1BQU07Ozs7Ozs7SUFzQkosWUFDVSxTQUNBLE1BQ0EsUUFDQTtRQUhBLFlBQU8sR0FBUCxPQUFPO1FBQ1AsU0FBSSxHQUFKLElBQUk7UUFDSixXQUFNLEdBQU4sTUFBTTtRQUNOLFlBQU8sR0FBUCxPQUFPO3VCQWxCc0MsSUFBSSxZQUFZLEVBQUU7MkJBQzNCLElBQUksWUFBWSxFQUFFOzhCQUNkLElBQUksWUFBWSxFQUFFO3FCQUN4QixJQUFJLFlBQVksRUFBRTtzQkFHbkIsTUFBTTsyQkFDbkIsSUFBSTtvQ0FDWCxvQkFBb0I7b0NBQ3BCLG9CQUFvQjtzQkFHbEMsa0NBQWtDO0tBT3RDOzs7O0lBRUwsSUFBSSxJQUFJO1FBQ04sTUFB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QUFDO1NBQ0o7S0FDRjs7O1lBdFBGLFNBQVMsU0FBQztnQkFDVCxRQUFRLEVBQUUsaUNBQWlDO2dCQUMzQyxRQUFRLEVBQUU7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Q0FpR1g7Z0JBQ0MsTUFBTSxFQUFFLENBQUMsRUFBRSxDQUFDO2dCQUNaLFVBQVUsRUFBRSxDQUFFLGVBQWUsQ0FBRTthQUNoQzs7OztZQWhIUSxlQUFlO1lBTWYsc0JBQXNCO1lBTHRCLGNBQWM7WUFBRSxNQUFNOzs7eUJBa0g1QixLQUFLOzJCQUNMLEtBQUs7NEJBQ0wsS0FBSzttQ0FDTCxLQUFLO29CQUNMLEtBQUs7dUJBQ0wsS0FBSztzQkFDTCxNQUFNOzBCQUNOLE1BQU07NkJBQ04sTUFBTTtvQkFDTixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBPbkluaXQsIElucHV0LCBPdXRwdXQsIEV2ZW50RW1pdHRlciB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQW5ndWxhckZpcmVBdXRoIH0gZnJvbSAnYW5ndWxhcmZpcmUyL2F1dGgnO1xuaW1wb3J0IHsgQWN0aXZhdGVkUm91dGUsIFJvdXRlciB9IGZyb20gJ0Bhbmd1bGFyL3JvdXRlcic7XG5pbXBvcnQgeyBhdXRoIH0gZnJvbSAnZmlyZWJhc2UvYXBwJztcbmltcG9ydCB7IEZvcm1Hcm91cCwgRm9ybUNvbnRyb2wgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5cbmltcG9ydCB7IGdldE9BdXRoUHJvdmlkZXJJY29uLCBnZXRPQXV0aFByb3ZpZGVyTmFtZSB9IGZyb20gJy4uLy4uL3NoYXJlZCc7XG5pbXBvcnQgeyBOZ3hGaXJlYmFzZUF1dGhTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vbmd4LWZpcmViYXNlLWF1dGguc2VydmljZSc7XG5pbXBvcnQgeyBzY3JlZW5BbmltYXRpb24gfSBmcm9tICcuLi8uLi9zaGFyZWQnO1xuXG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ25neC1maXJlYmFzZS1hdXRoLXNpZ24taW4tb2F1dGgnLFxuICB0ZW1wbGF0ZTogYDxkaXYgKm5nSWY9XCInd2FpdCcgPT09IHNjcmVlblwiIFtAc2NyZWVuXT1cIidpbidcIj5cbiAgPGRpdiBjbGFzcz1cImFsZXJ0IGFsZXJ0LXNlY29uZGFyeVwiPlxuICAgIDxpIGNsYXNzPVwiZmFzIGZhLXNwaW4gZmEtc3Bpbm5lciBmYS1md1wiIGFyaWEtaGlkZGVuPVwidHJ1ZVwiPjwvaT5cbiAgICBQbGVhc2Ugd2FpdC4uLlxuICA8L2Rpdj5cbjwvZGl2PlxuXG48ZGl2ICpuZ0lmPVwiJ21ldGhvZEVycm9yJyA9PT0gc2NyZWVuXCIgW0BzY3JlZW5dPVwiJ2luJ1wiPlxuICA8ZGl2IGNsYXNzPVwiYWxlcnQgYWxlcnQtZGFuZ2VyXCI+XG4gICAgPGkgY2xhc3M9XCJmYXMgZmEtZXhjbGFtYXRpb24tdHJpYW5nbGUgZmEtZndcIiBhcmlhLWhpZGRlbj1cInRydWVcIj48L2k+XG4gICAgV2UgY291bGQgbm90IHNpZ24geW91IGluIHdpdGgge3ttZXRob2RFcnJvci5jcmVkZW50aWFsLnByb3ZpZGVySWR9fS5cbiAgPC9kaXY+XG5cbiAgPHAgY2xhc3M9XCJ0ZXh0LW11dGVkXCI+XG4gICAgUGxlYXNlIHNpZ24gaW4gd2l0aCBvbmUgb2YgdGhlIG1ldGhvZHMgYXNzb2NpYXRlZCB3aXRoXG4gICAge3ttZXRob2RFcnJvci5lbWFpbH19OlxuICA8L3A+XG5cbiAgPGRpdiBjbGFzcz1cImxpc3QtZ3JvdXBcIj5cbiAgICA8YVxuICAgICAgKm5nSWY9XCJtZXRob2RFcnJvci5hY2NvdW50SGFzUGFzc3dvcmRcIlxuICAgICAgcm91dGVyTGluaz1cIi5cIlxuICAgICAgW3F1ZXJ5UGFyYW1zXT1cInthY3Rpb246ICdzaWduSW5QYXNzd29yZCd9XCJcbiAgICAgIGNsYXNzPVwibGlzdC1ncm91cC1pdGVtIGxpc3QtZ3JvdXAtaXRlbS1hY3Rpb25cIj5cbiAgICAgIDxpIGNsYXNzPVwiZmFzIGZhLXVubG9ja1wiIGFyaWEtaGlkZGVuPVwidHJ1ZVwiPjwvaT5cbiAgICAgIDxzcGFuIGNsYXNzPVwibWwtMlwiPlNpZ24gSW4gd2l0aCBZb3VyIFBhc3N3b3JkPC9zcGFuPlxuICAgIDwvYT5cbiAgICA8YnV0dG9uXG4gICAgICAqbmdGb3I9XCJsZXQgaWQgb2YgbWV0aG9kRXJyb3IuYWNjb3VudE9BdXRoTWV0aG9kc1wiXG4gICAgICAoY2xpY2spPVwib0F1dGhTaWduSW4oaWQpXCJcbiAgICAgIGNsYXNzPVwibGlzdC1ncm91cC1pdGVtIGxpc3QtZ3JvdXAtaXRlbS1hY3Rpb25cIj5cbiAgICAgIDxpIFthdHRyLmNsYXNzXT1cImdldE9BdXRoUHJvdmlkZXJJY29uKGlkKVwiIGFyaWEtaGlkZGVuPVwidHJ1ZVwiPjwvaT5cbiAgICAgIDxzcGFuIGNsYXNzPVwibWwtMlwiPlNpZ24gSW4gd2l0aCB7e2dldE9BdXRoUHJvdmlkZXJOYW1lKGlkKX19PC9zcGFuPlxuICAgIDwvYnV0dG9uPlxuICA8L2Rpdj5cblxuICA8Zm9ybSBbZm9ybUdyb3VwXT1cImZnXCI+XG4gICAgPGRpdiBjbGFzcz1cImZvcm0tZ3JvdXBcIj5cbiAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLWNoZWNrXCI+XG4gICAgICAgIDxpbnB1dFxuICAgICAgICAgIGNsYXNzPVwiZm9ybS1jaGVjay1pbnB1dFwiXG4gICAgICAgICAgdHlwZT1cImNoZWNrYm94XCJcbiAgICAgICAgICBbdmFsdWVdPVwidHJ1ZVwiXG4gICAgICAgICAgZm9ybUNvbnRyb2xOYW1lPVwicmVtZW1iZXJcIlxuICAgICAgICAgIFthdHRyLmlkXT1cImZvcm1JZCArICdyZW1lbWJlcidcIj5cbiAgICAgICAgPGxhYmVsIGNsYXNzPVwiZm9ybS1jaGVjay1sYWJlbFwiIFthdHRyLmZvcl09XCJmb3JtSWQgKyAncmVtZW1iZXInXCI+XG4gICAgICAgICAgUmVtZW1iZXIgbWUgb24gdGhpcyBkZXZpY2UuXG4gICAgICAgIDwvbGFiZWw+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgPC9mb3JtPlxuXG4gIDxwIGNsYXNzPVwidGV4dC1tdXRlZFwiPlxuICAgIElzIHt7bWV0aG9kRXJyb3IuZW1haWx9fSBub3QgeW91ciBlbWFpbCBhZGRyZXNzP1xuICAgIDxhIHJvdXRlckxpbms9XCIuXCIgW3F1ZXJ5UGFyYW1zXT1cInthY3Rpb246ICdzaWduSW4nfVwiPlN0YXJ0IE92ZXI8L2E+XG4gIDwvcD5cblxuPC9kaXY+XG5cbjxkaXYgKm5nSWY9XCIncmV0cnknID09PSBzY3JlZW5cIiBbQHNjcmVlbl09XCInaW4nXCI+XG4gIDxkaXYgY2xhc3M9XCJhbGVydCBhbGVydC1kYW5nZXJcIj5cbiAgICA8aSBjbGFzcz1cImZhcyBmYS1leGNsYW1hdGlvbi10cmlhbmdsZSBmYS1md1wiIGFyaWEtaGlkZGVuPVwidHJ1ZVwiPjwvaT5cbiAgICBJdCBsb29rcyBsaWtlIHlvdSBjYW5jZWxsZWQgc2lnbmluZyBpbiB3aXRoXG4gICAge3tnZXRPQXV0aFByb3ZpZGVyTmFtZShwcm92aWRlcklkKX19LiBUcnkgYWdhaW46XG4gIDwvZGl2PlxuXG4gIDxkaXYgY2xhc3M9XCJsaXN0LWdyb3VwXCI+XG4gICAgPGJ1dHRvblxuICAgICAgKGNsaWNrKT1cIm9BdXRoU2lnbkluKHByb3ZpZGVySWQpXCJcbiAgICAgIGNsYXNzPVwibGlzdC1ncm91cC1pdGVtIGxpc3QtZ3JvdXAtaXRlbS1hY3Rpb25cIj5cbiAgICAgIDxpIFthdHRyLmNsYXNzXT1cImdldE9BdXRoUHJvdmlkZXJJY29uKHByb3ZpZGVySWQpXCIgYXJpYS1oaWRkZW49XCJ0cnVlXCI+PC9pPlxuICAgICAgPHNwYW4gY2xhc3M9XCJtbC0yXCI+U2lnbiBJbiB3aXRoIHt7Z2V0T0F1dGhQcm92aWRlck5hbWUocHJvdmlkZXJJZCl9fTwvc3Bhbj5cbiAgICA8L2J1dHRvbj5cbiAgPC9kaXY+XG5cbiAgPGZvcm0gW2Zvcm1Hcm91cF09XCJmZ1wiPlxuICAgIDxkaXYgY2xhc3M9XCJmb3JtLWdyb3VwXCI+XG4gICAgICA8ZGl2IGNsYXNzPVwiZm9ybS1jaGVja1wiPlxuICAgICAgICA8aW5wdXRcbiAgICAgICAgICBjbGFzcz1cImZvcm0tY2hlY2staW5wdXRcIlxuICAgICAgICAgIHR5cGU9XCJjaGVja2JveFwiXG4gICAgICAgICAgW3ZhbHVlXT1cInRydWVcIlxuICAgICAgICAgIGZvcm1Db250cm9sTmFtZT1cInJlbWVtYmVyXCJcbiAgICAgICAgICBbYXR0ci5pZF09XCJmb3JtSWQgKyAncmVtZW1iZXInXCI+XG4gICAgICAgIDxsYWJlbCBjbGFzcz1cImZvcm0tY2hlY2stbGFiZWxcIiBbYXR0ci5mb3JdPVwiZm9ybUlkICsgJ3JlbWVtYmVyJ1wiPlxuICAgICAgICAgIFJlbWVtYmVyIG1lIG9uIHRoaXMgZGV2aWNlLlxuICAgICAgICA8L2xhYmVsPlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG4gIDwvZm9ybT5cblxuXG4gIDxwIGNsYXNzPVwidGV4dC1tdXRlZFwiPlxuICAgIDxhIHJvdXRlckxpbms9XCIuXCIgW3F1ZXJ5UGFyYW1zXT1cInthY3Rpb246ICdzaWduSW4nfVwiPlN0YXJ0IE92ZXI8L2E+XG4gIDwvcD5cblxuPC9kaXY+XG5gLFxuICBzdHlsZXM6IFtgYF0sXG4gIGFuaW1hdGlvbnM6IFsgc2NyZWVuQW5pbWF0aW9uIF1cbn0pXG5leHBvcnQgY2xhc3MgU2lnbkluT2F1dGhDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQge1xuXG4gIEBJbnB1dCgpIHByb3ZpZGVySWQ6IHN0cmluZztcbiAgQElucHV0KCkgaW5pdGlhbEVycm9yOiBhdXRoLkVycm9yO1xuICBASW5wdXQoKSB1c2VPQXV0aFBvcHVwOiBib29sZWFuO1xuICBASW5wdXQoKSBvQXV0aFByb3ZpZGVyRmFjdG9yeTogKHByb3ZpZGVySWQ6IHN0cmluZykgPT4gYXV0aC5BdXRoUHJvdmlkZXI7XG4gIEBJbnB1dCgpIGVtYWlsOiBzdHJpbmc7XG4gIEBJbnB1dCgpIHJlbWVtYmVyOiBib29sZWFuO1xuICBAT3V0cHV0KCkgc3VjY2VzczogRXZlbnRFbWl0dGVyPGF1dGguVXNlckNyZWRlbnRpYWw+ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuICBAT3V0cHV0KCkgZW1haWxDaGFuZ2U6IEV2ZW50RW1pdHRlcjxzdHJpbmc+ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuICBAT3V0cHV0KCkgcmVtZW1iZXJDaGFuZ2U6IEV2ZW50RW1pdHRlcjxib29sZWFuPiA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcbiAgQE91dHB1dCgpIGVycm9yOiBFdmVudEVtaXR0ZXI8YXV0aC5FcnJvcj4gPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG5cblxuICBzY3JlZW46ICd3YWl0JyB8ICdtZXRob2RFcnJvcicgfCAncmV0cnknID0gJ3dhaXQnO1xuICBtZXRob2RFcnJvcjogYXV0aC5FcnJvcnxhbnkgPSBudWxsO1xuICBnZXRPQXV0aFByb3ZpZGVySWNvbiA9IGdldE9BdXRoUHJvdmlkZXJJY29uO1xuICBnZXRPQXV0aFByb3ZpZGVyTmFtZSA9IGdldE9BdXRoUHJvdmlkZXJOYW1lO1xuICBmZzogRm9ybUdyb3VwO1xuICByZW1lbWJlckZjOiBGb3JtQ29udHJvbDtcbiAgZm9ybUlkID0gJ25neC1maXJlYmFzZS1hdXRoLXNpZ24taW4tb2F1dGgtJztcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIF9hZkF1dGg6IEFuZ3VsYXJGaXJlQXV0aCxcbiAgICBwcml2YXRlIF9zdmM6IE5neEZpcmViYXNlQXV0aFNlcnZpY2UsXG4gICAgcHJpdmF0ZSBfcm91dGU6IEFjdGl2YXRlZFJvdXRlLFxuICAgIHByaXZhdGUgX3JvdXRlcjogUm91dGVyXG4gICkgeyB9XG5cbiAgZ2V0IGF1dGgoKTogYXV0aC5BdXRoIHtcbiAgICByZXR1cm4gdGhpcy5fYWZBdXRoLmF1dGg7XG4gIH1cblxuICBnZXQgYXV0aFNlcnZpY2UoKTogTmd4RmlyZWJhc2VBdXRoU2VydmljZSB7XG4gICAgcmV0dXJuIHRoaXMuX3N2YztcbiAgfVxuXG4gIGdldCByb3V0ZSgpOiBBY3RpdmF0ZWRSb3V0ZSB7XG4gICAgcmV0dXJuIHRoaXMuX3JvdXRlO1xuICB9XG5cbiAgZ2V0IHJvdXRlcigpOiBSb3V0ZXIge1xuICAgIHJldHVybiB0aGlzLl9yb3V0ZXI7XG4gIH1cblxuICBuZ09uSW5pdCgpIHtcbiAgICB0aGlzLnJlbWVtYmVyRmMgPSBuZXcgRm9ybUNvbnRyb2wodGhpcy5yZW1lbWJlcik7XG4gICAgdGhpcy5yZW1lbWJlckZjLnZhbHVlQ2hhbmdlcy5zdWJzY3JpYmUodmFsID0+IHRoaXMucmVtZW1iZXJDaGFuZ2UuZW1pdCh2YWwpKTtcbiAgICB0aGlzLmZnID0gbmV3IEZvcm1Hcm91cCh7XG4gICAgICByZW1lbWJlcjogdGhpcy5yZW1lbWJlckZjXG4gICAgfSk7XG4gICAgaWYgKHRoaXMuaW5pdGlhbEVycm9yKSB7XG4gICAgICB0aGlzLmhhbmRsZU9BdXRoRXJyb3IodGhpcy5pbml0aWFsRXJyb3IpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLm9BdXRoU2lnbkluKHRoaXMucHJvdmlkZXJJZCk7XG4gICAgfVxuICB9XG5cblxuICBvQXV0aFNpZ25JbihpZDogc3RyaW5nLCBmb3JjZVJlZGlyZWN0PzogYm9vbGVhbikge1xuICAgIHRoaXMubWV0aG9kRXJyb3IgPSBudWxsO1xuICAgIGxldCBjcmVkOiBhdXRoLlVzZXJDcmVkZW50aWFsO1xuICAgIGlmICh0aGlzLnVzZU9BdXRoUG9wdXAgICYmIGZvcmNlUmVkaXJlY3QgIT09IHRydWUpIHtcbiAgICAgIHRoaXMuZ2V0T0F1dGhQcm92aWRlcihpZClcbiAgICAgICAgLnRoZW4ocHJvdmlkZXIgPT4ge1xuICAgICAgICAgIHJldHVybiB0aGlzLmF1dGguc2lnbkluV2l0aFBvcHVwKHByb3ZpZGVyKTtcbiAgICAgICAgfSlcbiAgICAgICAgLnRoZW4oKHJlc3VsdDogYXV0aC5Vc2VyQ3JlZGVudGlhbCkgPT4ge1xuICAgICAgICAgIGNyZWQgPSByZXN1bHQ7XG4gICAgICAgICAgcmV0dXJuIHRoaXMuYXV0aFNlcnZpY2Uuc2V0UmVtZW1iZXJlZCh0aGlzLnJlbWVtYmVyRmMudmFsdWUgPT09IHRydWUsIHJlc3VsdC51c2VyLmVtYWlsKTtcbiAgICAgICAgfSlcbiAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgIHRoaXMuc3VjY2Vzcy5lbWl0KGNyZWQpO1xuICAgICAgICB9KVxuICAgICAgICAuY2F0Y2goZXJyb3IgPT4gdGhpcy5oYW5kbGVPQXV0aEVycm9yKGVycm9yLCBpZCkpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnJvdXRlci5uYXZpZ2F0ZShbJy4nXSwge3JlbGF0aXZlVG86IHRoaXMucm91dGUsIHF1ZXJ5UGFyYW1zOiB7cmVtZW1iZXI6IHRoaXMucmVtZW1iZXJGYy52YWx1ZSA9PT0gdHJ1ZX19KVxuICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T0F1dGhQcm92aWRlcihpZCk7XG4gICAgICAgIH0pXG4gICAgICAgIC50aGVuKHByb3ZpZGVyID0+IHtcbiAgICAgICAgICByZXR1cm4gdGhpcy5hdXRoLnNpZ25JbldpdGhSZWRpcmVjdChwcm92aWRlcik7XG4gICAgICAgIH0pXG4gICAgICAgIC5jYXRjaChlcnJvciA9PiB0aGlzLmhhbmRsZU9BdXRoRXJyb3IoZXJyb3IsIGlkKSk7XG4gICAgfVxuICB9XG5cbiAgaGFuZGxlT0F1dGhFcnJvcihlcnJvcjogYXV0aC5FcnJvciwgcHJvdmlkZXJJZD86IHN0cmluZykge1xuICAgIGlmIChlcnJvclsnZW1haWwnXSAmJiBlcnJvclsnY3JlZGVudGlhbCddKSB7XG4gICAgICB0aGlzLmVtYWlsQ2hhbmdlLmVtaXQoZXJyb3JbJ2VtYWlsJ10pO1xuICAgICAgdGhpcy5hdXRoLmZldGNoU2lnbkluTWV0aG9kc0ZvckVtYWlsKGVycm9yWydlbWFpbCddKVxuICAgICAgICAudGhlbihyZXN1bHRzID0+IHtcbiAgICAgICAgICBlcnJvclsnbWV0aG9kcyddID0gcmVzdWx0cztcbiAgICAgICAgICBlcnJvclsnYWNjb3VudEhhc1Bhc3N3b3JkJ10gPSByZXN1bHRzLmluZGV4T2YoJ3Bhc3N3b3JkJykgIT09IC0xO1xuICAgICAgICAgIGVycm9yWydhY2NvdW50T0F1dGhNZXRob2RzJ10gPSByZXN1bHRzLmZpbHRlcihpZCA9PiBpZCAhPT0gJ3Bhc3N3b3JkJyk7XG4gICAgICAgICAgdGhpcy5tZXRob2RFcnJvciA9IGVycm9yO1xuICAgICAgICAgIHRoaXMuc2NyZWVuID0gJ21ldGhvZEVycm9yJztcbiAgICAgICAgfSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHN3aXRjaCAoZXJyb3IuY29kZSkge1xuICAgICAgY2FzZSAnYXV0aC9jYW5jZWxsZWQtcG9wdXAtcmVxdWVzdCc6XG4gICAgICBjYXNlICdhdXRoL3BvcHVwLWNsb3NlZC1ieS11c2VyJzpcbiAgICAgICAgdGhpcy5zY3JlZW4gPSAncmV0cnknO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ2F1dGgvcG9wdXAtYmxvY2tlZCc6XG4gICAgICAgIHRoaXMub0F1dGhTaWduSW4ocHJvdmlkZXJJZCwgdHJ1ZSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhpcy5lcnJvci5lbWl0KGVycm9yKTtcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG5cbiAgZ2V0T0F1dGhQcm92aWRlcihpZDogc3RyaW5nKTogUHJvbWlzZTxhdXRoLkF1dGhQcm92aWRlcj4ge1xuICAgIGxldCBwcm92aWRlcjogYXV0aC5BdXRoUHJvdmlkZXIgPSBudWxsO1xuICAgIGlmICh0aGlzLm9BdXRoUHJvdmlkZXJGYWN0b3J5KSB7XG4gICAgICBwcm92aWRlciA9IHRoaXMub0F1dGhQcm92aWRlckZhY3RvcnkoaWQpO1xuICAgIH1cbiAgICBpZiAoISBwcm92aWRlcikge1xuICAgICAgc3dpdGNoIChpZCkge1xuICAgICAgICBjYXNlICd0d2l0dGVyLmNvbSc6XG4gICAgICAgICAgcHJvdmlkZXIgPSBuZXcgYXV0aC5Ud2l0dGVyQXV0aFByb3ZpZGVyKCk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ2ZhY2Vib29rLmNvbSc6XG4gICAgICAgICAgcHJvdmlkZXIgPSBuZXcgYXV0aC5GYWNlYm9va0F1dGhQcm92aWRlcigpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdnb29nbGUuY29tJzpcbiAgICAgICAgICBwcm92aWRlciA9IG5ldyBhdXRoLkdvb2dsZUF1dGhQcm92aWRlcigpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdnaXRodWIuY29tJzpcbiAgICAgICAgICBwcm92aWRlciA9IG5ldyBhdXRoLkdpdGh1YkF1dGhQcm92aWRlcigpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAocHJvdmlkZXIpIHtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUocHJvdmlkZXIpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3Qoe1xuICAgICAgICBjb2RlOiAnbmd4LWZpcmViYXNlLWF1dGgvbm8tcHJvdmlkZXItZm91bmQnLFxuICAgICAgICBtZXNzYWdlOiBgV2UgY291bGQgbm90IGNyZWF0ZSBhbiBPQXV0aCBwcm92aWRlciBmb3IgcHJvdmlkZXIgaWQgXCIke2lkfVwiLmBcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG59XG4iXX0=