UNPKG

@gocredible/angular-password-strength-meter

Version:

[![CI](https://github.com/GoCredible/password-strength-meter/actions/workflows/ci-workflow.yml/badge.svg)](https://github.com/GoCredible/password-strength-meter/actions/workflows/ci-workflow.yml) [![npm version](https://badge.fury.io/js/angular-password-s

102 lines 17.9 kB
/* eslint-disable @angular-eslint/component-selector */ import { Component, Input, Output, EventEmitter, HostBinding, inject, booleanAttribute, } from '@angular/core'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { Subject, debounceTime, distinctUntilChanged, of, switchMap, } from 'rxjs'; import { IPasswordStrengthMeterService, } from './password-strength-meter-service'; import { PSMProgressBarDirective } from './psm-progress-bar.directive'; import * as i0 from "@angular/core"; export class PasswordStrengthMeterComponent { constructor() { 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==