@gocredible/angular-password-strength-meter
Version:
[](https://github.com/GoCredible/password-strength-meter/actions/workflows/ci-workflow.yml) [ {
this.minPasswordLength = 8;
this.enableFeedback = false;
this.enableAsync = false;
this.colors = [];
this.numberOfProgressBarItems = 5;
this.strengthChange = new EventEmitter();
this.baseClass = 'psm';
this.passwordStrengthMeterService = inject(IPasswordStrengthMeterService);
this.passwordStrength = null;
this.feedback = null;
this.prevPasswordStrength = null;
this.passwordChangeObservable$ = new Subject();
this.init();
}
ngOnChanges(changes) {
if (changes['password']) {
this.passwordChangeObservable$.next(this.password);
}
}
init() {
this.passwordChangeObservable$
.pipe(distinctUntilChanged(), debounceTime(100), switchMap((value) => {
if (!value) {
return of({ score: null, feedback: null });
}
if (value && value.length < this.minPasswordLength) {
return of({ score: 0, feedback: null });
}
if (this.enableAsync) {
return this.calculateScoreAsync(value);
}
const result = this.calculateScore(value);
return of(result);
}), takeUntilDestroyed())
.subscribe((result) => {
this.passwordStrength = result.score;
this.feedback = result.feedback;
// Only emit the passwordStrength if it changed
if (this.prevPasswordStrength !== this.passwordStrength) {
this.strengthChange.emit(this.passwordStrength);
this.prevPasswordStrength = this.passwordStrength;
}
});
}
calculateScore(value) {
if (this.enableFeedback) {
return this.passwordStrengthMeterService.scoreWithFeedback(value);
}
const feedbackResult = {
score: this.passwordStrengthMeterService.score(value),
feedback: null,
};
return feedbackResult;
}
calculateScoreAsync(value) {
if (this.enableFeedback) {
return this.passwordStrengthMeterService.scoreWithFeedbackAsync(value);
}
return this.passwordStrengthMeterService
.scoreAsync(value)
.then((result) => ({
score: result,
feedback: null,
}));
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: PasswordStrengthMeterComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.12", type: PasswordStrengthMeterComponent, isStandalone: true, selector: "password-strength-meter", inputs: { password: "password", minPasswordLength: "minPasswordLength", enableFeedback: ["enableFeedback", "enableFeedback", booleanAttribute], enableAsync: ["enableAsync", "enableAsync", booleanAttribute], colors: "colors", numberOfProgressBarItems: "numberOfProgressBarItems" }, outputs: { strengthChange: "strengthChange" }, host: { properties: { "class": "this.baseClass" } }, usesOnChanges: true, ngImport: i0, template: "<div\n class=\"psm__progress-bar\"\n role=\"progressbar\"\n [passwordStrength]=\"passwordStrength\"\n [numberOfProgressBarItems]=\"numberOfProgressBarItems\"\n [colors]=\"colors\"\n>\n <div class=\"psm__progress-bar-items\"></div>\n <div class=\"psm__progress-bar-overlay\"></div>\n</div>\n\n@if(enableFeedback && feedback) {\n\n @if(feedback.warning) {\n <small class=\"psm__feedback\">\n {{ feedback.warning }}\n </small>\n }\n\n @if(feedback.suggestions && feedback.suggestions.length) {\n <small class=\"psm__suggestion\">\n @for (suggestion of feedback.suggestions; track suggestion; let isLast = $last) {\n {{ suggestion }}{{ isLast ? '' : ' ' }}\n }\n </small>\n }\n}\n\n", styles: ["*,*:before,*:after{box-sizing:border-box}.psm__progress-bar{position:relative;height:3px;margin:10px auto;border-radius:3px;background:#fff}.psm__progress-bar-items{display:flex;justify-content:space-evenly;width:100%;height:100%;background:#ddd}.psm__progress-bar-item{height:100%;z-index:5;border-right:4px solid #fff}.psm__progress-bar-item:last-child{border-right:0px}.psm__progress-bar-overlay{position:absolute;background:red;border-radius:3px;height:3px;top:0;transition:width .5s ease-in-out,background .25s}.psm__feedback,.psm__suggestion{font-size:70%;font-weight:400;color:#6c757d!important;display:block;margin-top:.25rem}\n"], dependencies: [{ kind: "directive", type: PSMProgressBarDirective, selector: ".psm__progress-bar", inputs: ["numberOfProgressBarItems", "passwordStrength", "colors"] }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: PasswordStrengthMeterComponent, decorators: [{
type: Component,
args: [{ standalone: true, selector: 'password-strength-meter', imports: [PSMProgressBarDirective], template: "<div\n class=\"psm__progress-bar\"\n role=\"progressbar\"\n [passwordStrength]=\"passwordStrength\"\n [numberOfProgressBarItems]=\"numberOfProgressBarItems\"\n [colors]=\"colors\"\n>\n <div class=\"psm__progress-bar-items\"></div>\n <div class=\"psm__progress-bar-overlay\"></div>\n</div>\n\n@if(enableFeedback && feedback) {\n\n @if(feedback.warning) {\n <small class=\"psm__feedback\">\n {{ feedback.warning }}\n </small>\n }\n\n @if(feedback.suggestions && feedback.suggestions.length) {\n <small class=\"psm__suggestion\">\n @for (suggestion of feedback.suggestions; track suggestion; let isLast = $last) {\n {{ suggestion }}{{ isLast ? '' : ' ' }}\n }\n </small>\n }\n}\n\n", styles: ["*,*:before,*:after{box-sizing:border-box}.psm__progress-bar{position:relative;height:3px;margin:10px auto;border-radius:3px;background:#fff}.psm__progress-bar-items{display:flex;justify-content:space-evenly;width:100%;height:100%;background:#ddd}.psm__progress-bar-item{height:100%;z-index:5;border-right:4px solid #fff}.psm__progress-bar-item:last-child{border-right:0px}.psm__progress-bar-overlay{position:absolute;background:red;border-radius:3px;height:3px;top:0;transition:width .5s ease-in-out,background .25s}.psm__feedback,.psm__suggestion{font-size:70%;font-weight:400;color:#6c757d!important;display:block;margin-top:.25rem}\n"] }]
}], ctorParameters: () => [], propDecorators: { password: [{
type: Input,
args: [{ required: true }]
}], minPasswordLength: [{
type: Input
}], enableFeedback: [{
type: Input,
args: [{ transform: booleanAttribute }]
}], enableAsync: [{
type: Input,
args: [{ transform: booleanAttribute }]
}], colors: [{
type: Input
}], numberOfProgressBarItems: [{
type: Input
}], strengthChange: [{
type: Output
}], baseClass: [{
type: HostBinding,
args: ['class']
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFzc3dvcmQtc3RyZW5ndGgtbWV0ZXIuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcHJvamVjdHMvcGFzc3dvcmQtc3RyZW5ndGgtbWV0ZXIvc3JjL2xpYi9wYXNzd29yZC1zdHJlbmd0aC1tZXRlci5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi9wcm9qZWN0cy9wYXNzd29yZC1zdHJlbmd0aC1tZXRlci9zcmMvbGliL3Bhc3N3b3JkLXN0cmVuZ3RoLW1ldGVyLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLHVEQUF1RDtBQUN2RCxPQUFPLEVBQ0wsU0FBUyxFQUNULEtBQUssRUFHTCxNQUFNLEVBQ04sWUFBWSxFQUNaLFdBQVcsRUFDWCxNQUFNLEVBQ04sZ0JBQWdCLEdBQ2pCLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQ2hFLE9BQU8sRUFDTCxPQUFPLEVBQ1AsWUFBWSxFQUNaLG9CQUFvQixFQUNwQixFQUFFLEVBQ0YsU0FBUyxHQUNWLE1BQU0sTUFBTSxDQUFDO0FBRWQsT0FBTyxFQUdMLDZCQUE2QixHQUM5QixNQUFNLG1DQUFtQyxDQUFDO0FBQzNDLE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxNQUFNLDhCQUE4QixDQUFDOztBQVN2RSxNQUFNLE9BQU8sOEJBQThCO0lBMkJ6QztRQXhCUyxzQkFBaUIsR0FBRyxDQUFDLENBQUM7UUFFUyxtQkFBYyxHQUFHLEtBQUssQ0FBQztRQUV2QixnQkFBVyxHQUFHLEtBQUssQ0FBQztRQUVuRCxXQUFNLEdBQWEsRUFBRSxDQUFDO1FBRXRCLDZCQUF3QixHQUFHLENBQUMsQ0FBQztRQUU1QixtQkFBYyxHQUFHLElBQUksWUFBWSxFQUFpQixDQUFDO1FBRXZDLGNBQVMsR0FBRyxLQUFLLENBQUM7UUFFaEMsaUNBQTRCLEdBQWtDLE1BQU0sQ0FDMUUsNkJBQTZCLENB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QUssRUFBRSxNQUFNO1lBQ2IsUUFBUSxFQUFFLElBQUk7U0FDZixDQUFDLENBQUMsQ0FBQztJQUNSLENBQUM7K0dBaEdVLDhCQUE4QjttR0FBOUIsOEJBQThCLHdMQUtyQixnQkFBZ0IsK0NBRWhCLGdCQUFnQiw4TkMxQ3RDLHF0QkE0QkEsc3JCREtZLHVCQUF1Qjs7NEZBRXRCLDhCQUE4QjtrQkFQMUMsU0FBUztpQ0FDSSxJQUFJLFlBQ04seUJBQXlCLFdBRzFCLENBQUMsdUJBQXVCLENBQUM7d0RBR1AsUUFBUTtzQkFBbEMsS0FBSzt1QkFBQyxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUU7Z0JBRWhCLGlCQUFpQjtzQkFBekIsS0FBSztnQkFFa0MsY0FBYztzQkFBckQsS0FBSzt1QkFBQyxFQUFFLFNBQVMsRUFBRSxnQkFBZ0IsRUFBRTtnQkFFRSxXQUFXO3NCQUFsRCxLQUFLO3VCQUFDLEVBQUUsU0FBUyxFQUFFLGdCQUFnQixFQUFFO2dCQUU3QixNQUFNO3NCQUFkLEtBQUs7Z0JBRUcsd0JBQXdCO3NCQUFoQyxLQUFLO2dCQUVJLGNBQWM7c0JBQXZCLE1BQU07Z0JBRWUsU0FBUztzQkFBOUIsV0FBVzt1QkFBQyxPQUFPIiwic291cmNlc0NvbnRlbnQiOlsiLyogZXNsaW50LWRpc2FibGUgQGFuZ3VsYXItZXNsaW50L2NvbXBvbmVudC1zZWxlY3RvciAqL1xuaW1wb3J0IHtcbiAgQ29tcG9uZW50LFxuICBJbnB1dCxcbiAgT25DaGFuZ2VzLFxuICBTaW1wbGVDaGFuZ2VzLFxuICBPdXRwdXQsXG4gIEV2ZW50RW1pdHRlcixcbiAgSG9zdEJpbmRpbmcsXG4gIGluamVjdCxcbiAgYm9vbGVhbkF0dHJpYnV0ZSxcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyB0YWtlVW50aWxEZXN0cm95ZWQgfSBmcm9tICdAYW5ndWxhci9jb3JlL3J4anMtaW50ZXJvcCc7XG5pbXBvcnQge1xuICBTdWJqZWN0LFxuICBkZWJvdW5jZVRpbWUsXG4gIGRpc3RpbmN0VW50aWxDaGFuZ2VkLFxuICBvZixcbiAgc3dpdGNoTWFwLFxufSBmcm9tICdyeGpzJztcblxuaW1wb3J0IHtcbiAgRmVlZGJhY2ssXG4gIEZlZWRiYWNrUmVzdWx0LFxuICBJUGFzc3dvcmRTdHJlbmd0aE1ldGVyU2VydmljZSxcbn0gZnJvbSAnLi9wYXNzd29yZC1zdHJlbmd0aC1tZXRlci1zZXJ2aWNlJztcbmltcG9ydCB7IFBTTVByb2dyZXNzQmFyRGlyZWN0aXZlIH0gZnJvbSAnLi9wc20tcHJvZ3Jlc3MtYmFyLmRpcmVjdGl2ZSc7XG5cbkBDb21wb25lbnQoe1xuICBzdGFuZGFsb25lOiB0cnVlLFxuICBzZWxlY3RvcjogJ3Bhc3N3b3JkLXN0cmVuZ3RoLW1ldGVyJyxcbiAgdGVtcGxhdGVVcmw6ICcuL3Bhc3N3b3JkLXN0cmVuZ3RoLW1ldGVyLmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vcGFzc3dvcmQtc3RyZW5ndGgtbWV0ZXIuY29tcG9uZW50LnNjc3MnXSxcbiAgaW1wb3J0czogW1BTTVByb2dyZXNzQmFyRGlyZWN0aXZlXSxcbn0pXG5leHBvcnQgY2xhc3MgUGFzc3dvcmRTdHJlbmd0aE1ldGVyQ29tcG9uZW50IGltcGxlbWVudHMgT25DaGFuZ2VzIHtcbiAgQElucHV0KHsgcmVxdWlyZWQ6IHRydWUgfSkgcGFzc3dvcmQhOiBzdHJpbmc7XG5cbiAgQElucHV0KCkgbWluUGFzc3dvcmRMZW5ndGggPSA4O1xuXG4gIEBJbnB1dCh7IHRyYW5zZm9ybTogYm9vbGVhbkF0dHJpYnV0ZSB9KSBlbmFibGVGZWVkYmFjayA9IGZhbHNlO1xuXG4gIEBJbnB1dCh7IHRyYW5zZm9ybTogYm9vbGVhbkF0dHJpYnV0ZSB9KSBlbmFibGVBc3luYyA9IGZhbHNlO1xuXG4gIEBJbnB1dCgpIGNvbG9yczogc3RyaW5nW10gPSBbXTtcblxuICBASW5wdXQoKSBudW1iZXJPZlByb2dyZXNzQmFySXRlbXMgPSA1O1xuXG4gIEBPdXRwdXQoKSBzdHJlbmd0aENoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8bnVtYmVyIHwgbnVsbD4oKTtcblxuICBASG9zdEJpbmRpbmcoJ2NsYXNzJykgYmFzZUNsYXNzID0gJ3BzbSc7XG5cbiAgcHJpdmF0ZSBwYXNzd29yZFN0cmVuZ3RoTWV0ZXJTZXJ2aWNlOiBJUGFzc3dvcmRTdHJlbmd0aE1ldGVyU2VydmljZSA9IGluamVjdChcbiAgICBJUGFzc3dvcmRTdHJlbmd0aE1ldGVyU2VydmljZVxuICApO1xuXG4gIHBhc3N3b3JkU3RyZW5ndGg6IG51bWJlciB8IG51bGwgPSBudWxsO1xuICBmZWVkYmFjazogRmVlZGJhY2sgfCBudWxsID0gbnVsbDtcblxuICBwcml2YXRlIHByZXZQYXNzd29yZFN0cmVuZ3RoOiBudW1iZXIgfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBwYXNzd29yZENoYW5nZU9ic2VydmFibGUkID0gbmV3IFN1YmplY3Q8c3RyaW5nPigpO1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHRoaXMuaW5pdCgpO1xuICB9XG5cbiAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcykge1xuICAgIGlmIChjaGFuZ2VzWydwYXNzd29yZCddKSB7XG4gICAgICB0aGlzLnBhc3N3b3JkQ2hhbmdlT2JzZXJ2YWJsZSQubmV4dCh0aGlzLnBhc3N3b3JkKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGluaXQoKTogdm9pZCB7XG4gICAgdGhpcy5wYXNzd29yZENoYW5nZU9ic2VydmFibGUkXG4gICAgICAucGlwZShcbiAgICAgICAgZGlzdGluY3RVbnRpbENoYW5nZWQoKSxcbiAgICAgICAgZGVib3VuY2VUaW1lKDEwMCksXG4gICAgICAgIHN3aXRjaE1hcCgodmFsdWUpID0+IHtcbiAgICAgICAgICBpZiAoIXZhbHVlKSB7XG4gICAgICAgICAgICByZXR1cm4gb2YoeyBzY29yZTogbnVsbCwgZmVlZGJhY2s6IG51bGwgfSk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKHZhbHVlICYmIHZhbHVlLmxlbmd0aCA8IHRoaXMubWluUGFzc3dvcmRMZW5ndGgpIHtcbiAgICAgICAgICAgIHJldHVybiBvZih7IHNjb3JlOiAwLCBmZWVkYmFjazogbnVsbCB9KTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAodGhpcy5lbmFibGVBc3luYykge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuY2FsY3VsYXRlU2NvcmVBc3luYyh2YWx1ZSk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY29uc3QgcmVzdWx0ID0gdGhpcy5jYWxjdWxhdGVTY29yZSh2YWx1ZSk7XG4gICAgICAgICAgcmV0dXJuIG9mKHJlc3VsdCk7XG4gICAgICAgIH0pLFxuICAgICAgICB0YWtlVW50aWxEZXN0cm95ZWQoKVxuICAgICAgKVxuICAgICAgLnN1YnNjcmliZSgocmVzdWx0OiBGZWVkYmFja1Jlc3VsdCkgPT4ge1xuICAgICAgICB0aGlzLnBhc3N3b3JkU3RyZW5ndGggPSByZXN1bHQuc2NvcmU7XG4gICAgICAgIHRoaXMuZmVlZGJhY2sgPSByZXN1bHQuZmVlZGJhY2s7XG5cbiAgICAgICAgLy8gT25seSBlbWl0IHRoZSBwYXNzd29yZFN0cmVuZ3RoIGlmIGl0IGNoYW5nZWRcbiAgICAgICAgaWYgKHRoaXMucHJldlBhc3N3b3JkU3RyZW5ndGggIT09IHRoaXMucGFzc3dvcmRTdHJlbmd0aCkge1xuICAgICAgICAgIHRoaXMuc3RyZW5ndGhDaGFuZ2UuZW1pdCh0aGlzLnBhc3N3b3JkU3RyZW5ndGgpO1xuICAgICAgICAgIHRoaXMucHJldlBhc3N3b3JkU3RyZW5ndGggPSB0aGlzLnBhc3N3b3JkU3RyZW5ndGg7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBjYWxjdWxhdGVTY29yZSh2YWx1ZTogc3RyaW5nKTogRmVlZGJhY2tSZXN1bHQge1xuICAgIGlmICh0aGlzLmVuYWJsZUZlZWRiYWNrKSB7XG4gICAgICByZXR1cm4gdGhpcy5wYXNzd29yZFN0cmVuZ3RoTWV0ZXJTZXJ2aWNlLnNjb3JlV2l0aEZlZWRiYWNrKHZhbHVlKTtcbiAgICB9XG5cbiAgICBjb25zdCBmZWVkYmFja1Jlc3VsdCA9IHtcbiAgICAgIHNjb3JlOiB0aGlzLnBhc3N3b3JkU3RyZW5ndGhNZXRlclNlcnZpY2Uuc2NvcmUodmFsdWUpLFxuICAgICAgZmVlZGJhY2s6IG51bGwsXG4gICAgfTtcblxuICAgIHJldHVybiBmZWVkYmFja1Jlc3VsdDtcbiAgfVxuXG4gIHByaXZhdGUgY2FsY3VsYXRlU2NvcmVBc3luYyh2YWx1ZTogc3RyaW5nKTogUHJvbWlzZTxGZWVkYmFja1Jlc3VsdD4ge1xuICAgIGlmICh0aGlzLmVuYWJsZUZlZWRiYWNrKSB7XG4gICAgICByZXR1cm4gdGhpcy5wYXNzd29yZFN0cmVuZ3RoTWV0ZXJTZXJ2aWNlLnNjb3JlV2l0aEZlZWRiYWNrQXN5bmModmFsdWUpO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLnBhc3N3b3JkU3RyZW5ndGhNZXRlclNlcnZpY2VcbiAgICAgIC5zY29yZUFzeW5jKHZhbHVlKVxuICAgICAgLnRoZW4oKHJlc3VsdCkgPT4gKHtcbiAgICAgICAgc2NvcmU6IHJlc3VsdCxcbiAgICAgICAgZmVlZGJhY2s6IG51bGwsXG4gICAgICB9KSk7XG4gIH1cbn1cbiIsIjxkaXZcbiAgY2xhc3M9XCJwc21fX3Byb2dyZXNzLWJhclwiXG4gIHJvbGU9XCJwcm9ncmVzc2JhclwiXG4gIFtwYXNzd29yZFN0cmVuZ3RoXT1cInBhc3N3b3JkU3RyZW5ndGhcIlxuICBbbnVtYmVyT2ZQcm9ncmVzc0Jhckl0ZW1zXT1cIm51bWJlck9mUHJvZ3Jlc3NCYXJJdGVtc1wiXG4gIFtjb2xvcnNdPVwiY29sb3JzXCJcbj5cbiAgPGRpdiBjbGFzcz1cInBzbV9fcHJvZ3Jlc3MtYmFyLWl0ZW1zXCI+PC9kaXY+XG4gIDxkaXYgY2xhc3M9XCJwc21fX3Byb2dyZXNzLWJhci1vdmVybGF5XCI+PC9kaXY+XG48L2Rpdj5cblxuQGlmKGVuYWJsZUZlZWRiYWNrICYmIGZlZWRiYWNrKSB7XG5cbiAgQGlmKGZlZWRiYWNrLndhcm5pbmcpIHtcbiAgICA8c21hbGwgY2xhc3M9XCJwc21fX2ZlZWRiYWNrXCI+XG4gICAgICB7eyBmZWVkYmFjay53YXJuaW5nIH19XG4gICAgPC9zbWFsbD5cbiAgfVxuXG4gIEBpZihmZWVkYmFjay5zdWdnZXN0aW9ucyAmJiBmZWVkYmFjay5zdWdnZXN0aW9ucy5sZW5ndGgpIHtcbiAgICA8c21hbGwgY2xhc3M9XCJwc21fX3N1Z2dlc3Rpb25cIj5cbiAgICAgIEBmb3IgKHN1Z2dlc3Rpb24gb2YgZmVlZGJhY2suc3VnZ2VzdGlvbnM7IHRyYWNrIHN1Z2dlc3Rpb247IGxldCBpc0xhc3QgPSAkbGFzdCkge1xuICAgICAgICB7eyBzdWdnZXN0aW9uIH19e3sgaXNMYXN0ID8gJycgOiAnICcgfX1cbiAgICAgIH1cbiAgICA8L3NtYWxsPlxuICB9XG59XG5cbiJdfQ==