angular-otp-box
Version:
Angular otp input field component for web applications. Easy to integrate and use.
150 lines • 19.5 kB
JavaScript
import { Component, Input, Output, EventEmitter, ViewChildren } from '@angular/core';
import { FormGroup, FormControl } from '@angular/forms';
import { KeysPipe } from '../pipes/keys.pipe';
import { CounterDirective } from '../directives/timer.directive';
export class OtpInputComponent {
constructor(keysPipe) {
this.keysPipe = keysPipe;
this.setting = {
length: 4,
timer: 0,
timerType: 0
};
this.onValueChange = new EventEmitter();
this.inputControls = new Array(this.setting.length);
this.componentKey = Math.random().toString(36).substring(2) + (new Date()).getTime().toString(36);
}
ngOnInit() {
console.log(this.setting);
this.otpForm = new FormGroup({});
for (let index = 0; index < this.setting.length; index++) {
this.otpForm.addControl(this.getControlName(index), new FormControl());
}
}
ngAfterViewInit() {
let containerItem = document.getElementById(`c_${this.componentKey}`);
if (containerItem) {
let ele = containerItem.getElementsByClassName('.otp-input')[0];
if (ele && ele.focus) {
ele.focus();
}
}
}
getControlName(idx) {
return `ctrl_${idx}`;
}
isLeftArrow(e) {
return this.isKeyCode(e, 37);
}
isRightArrow(e) {
return this.isKeyCode(e, 39);
}
isBackspaceOrDelete(e) {
return e.key === "Backspace" || e.key === "Delete" || this.isKeyCode(e, 8) || this.isKeyCode(e, 46);
}
isKeyCode(e, targetCode) {
var key = e.keyCode || e.charCode;
if (key == targetCode) {
return true;
}
return false;
}
keyUp(e, inputIdx) {
let nextInputId = this.appendKey(`otp_${inputIdx + 1}`);
let prevInputId = this.appendKey(`otp_${inputIdx - 1}`);
if (this.isRightArrow(e)) {
this.setSelected(nextInputId);
return;
}
if (this.isLeftArrow(e)) {
this.setSelected(prevInputId);
return;
}
let isBackspace = this.isBackspaceOrDelete(e);
if (isBackspace && !e.target.value) {
this.setSelected(prevInputId);
this.rebuildValue();
return;
}
if (!e.target.value) {
return;
}
if (this.isValidEntry(e)) {
this.focusTo(nextInputId);
}
this.rebuildValue();
}
appendKey(id) {
return `${id}_${this.componentKey}`;
}
setSelected(eleId) {
this.focusTo(eleId);
let ele = document.getElementById(eleId);
if (ele && ele.setSelectionRange) {
setTimeout(() => {
ele.setSelectionRange(0, 1);
}, 0);
}
}
isValidEntry(e) {
var inp = String.fromCharCode(e.keyCode);
var isMobile = /iPhone|iPad|iPod|Android/i.test(navigator.userAgent);
return isMobile || /[a-zA-Z0-9-_]/.test(inp) || (this.setting.allowKeyCodes && this.setting.allowKeyCodes.includes(e.keyCode)) || (e.keyCode >= 96 && e.keyCode <= 105);
}
focusTo(eleId) {
let ele = document.getElementById(eleId);
if (ele) {
ele.focus();
ele.selectionStart = ele.selectionEnd = 100;
}
}
rebuildValue() {
let val = '';
this.keysPipe.transform(this.otpForm.controls).forEach(k => {
if (this.otpForm.controls[k].value) {
val += this.otpForm.controls[k].value;
}
});
this.onValueChange.emit(val);
}
onCounterChange(e) {
this.counter = e;
if (this.counter == 0) {
this.onValueChange.emit(-1);
}
}
ressendOtp() {
this.CounterDirective.first.startTimer();
this.onValueChange.emit(-2);
}
formatSecsToMins(time) {
// Hours, minutes and seconds
var hrs = ~~(time / 3600);
var mins = ~~((time % 3600) / 60);
var secs = ~~time % 60;
// Output like "1:01" or "4:03:59" or "123:03:59"
var ret = "";
if (hrs > 0) {
ret += "" + hrs + ":" + (mins < 10 ? "0" : "");
}
ret += "" + mins + ":" + (secs < 10 ? "0" : "");
ret += "" + secs;
return ret;
}
}
OtpInputComponent.decorators = [
{ type: Component, args: [{
selector: 'otp',
template: "<div class=\"otp-container {{setting.wrapperClass}}\" id=\"c_{{componentKey}}\" *ngIf=\"otpForm?.controls\"\n [ngStyle]=\"setting.wrapperStyles\">\n <input \n [type]=\"setting.numbersOnly ? 'tel' : 'text'\" \n numberOnly [disabledNumberOnly]=\"!setting.numbersOnly\"\n [ngStyle]=\"setting.inputStyles\" \n maxlength=\"1\" \n class=\"otp-input {{setting.inputClass}}\" \n autocomplete=\"off\"\n *ngFor=\"let item of otpForm?.controls | keys; let i = index\" \n [formControl]=\"otpForm.controls[item]\"\n id=\"otp_{{i}}_{{componentKey}}\" \n (keyup)=\"keyUp($event, i)\"\n >\n <ng-container counter [counter]=\"setting.timer\" (value)=\"onCounterChange($event)\">\n <div>\n <button class=\"btn {{setting.btnClass}}\" [disabled]=\"counter != 0\" (click)=\"ressendOtp()\">\n Resend OTP \n <span *ngIf=\"counter != 0\">\n <ng-container *ngIf=\"!setting.timerType\">\n in {{ counter }} seconds.\n </ng-container>\n <ng-container *ngIf=\"setting.timerType\">\n in {{ formatSecsToMins(counter) }} minutes.\n </ng-container>\n </span>\n </button>\n </div>\n </ng-container>\n</div>",
styles: [".otp-input{width:2em;height:2em;border-radius:4px;border:1px solid #c5c5c5;text-align:center;font-size:28px}.otp-input:focus{outline-offset:0;outline-color:#2b91e2;outline-style:auto;outline-width:5px}.otp-container .otp-input:not(:last-child){margin-right:8px}@media screen and (max-width:767px){.otp-input{font-size:24px}}@media screen and (max-width:420px){.otp-input{font-size:18px}}"]
},] }
];
OtpInputComponent.ctorParameters = () => [
{ type: KeysPipe }
];
OtpInputComponent.propDecorators = {
setting: [{ type: Input }],
onValueChange: [{ type: Output }],
CounterDirective: [{ type: ViewChildren, args: [CounterDirective,] }]
};
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYW5ndWxhci1vdHAtaW5wdXQuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvYW5ndWxhci1vdHAtYm94L3NyYy9saWIvY29tcG9uZW50cy9hbmd1bGFyLW90cC1pbnB1dC5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBVSxLQUFLLEVBQUUsTUFBTSxFQUFFLFlBQVksRUFBRSxZQUFZLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDN0YsT0FBTyxFQUFFLFNBQVMsRUFBRSxXQUFXLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUN4RCxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFFOUMsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFRakUsTUFBTSxPQUFPLGlCQUFpQjtJQWE3QixZQUFvQixRQUFrQjtRQUFsQixhQUFRLEdBQVIsUUFBUSxDQUFVO1FBWjdCLFlBQU8sR0FBWTtZQUMzQixNQUFNLEVBQUUsQ0FBQztZQUNULEtBQUssRUFBRSxDQUFDO1lBQ1IsU0FBUyxFQUFFLENBQUM7U0FDWixDQUFDO1FBQ1Esa0JBQWEsR0FBRyxJQUFJLFlBQVksRUFBTyxDQUFDO1FBR2xELGtCQUFhLEdBQWtCLElBQUksS0FBSyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDOUQsaUJBQVksR0FBRyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLElBQUksSUFBSSxFQUFFLENBQUMsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDLENBQUM7SUFLN0YsQ0FBQztJQUVNLFFBQVE7UUFDZCxPQUFPLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxPQUFPLENB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LENBQUMsQ0FBQyxDQUFDLElBQUksR0FBRyxJQUFJLENBQUMsQ0FBQztRQUMxQixJQUFJLElBQUksR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksR0FBRyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQztRQUNsQyxJQUFJLElBQUksR0FBRyxDQUFDLENBQUMsSUFBSSxHQUFHLEVBQUUsQ0FBQztRQUV2QixpREFBaUQ7UUFDakQsSUFBSSxHQUFHLEdBQUcsRUFBRSxDQUFDO1FBQ2IsSUFBSSxHQUFHLEdBQUcsQ0FBQyxFQUFFO1lBQ1osR0FBRyxJQUFJLEVBQUUsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUMsSUFBSSxHQUFHLEVBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQztTQUMvQztRQUNELEdBQUcsSUFBSSxFQUFFLEdBQUcsSUFBSSxHQUFHLEdBQUcsR0FBRyxDQUFDLElBQUksR0FBRyxFQUFFLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDaEQsR0FBRyxJQUFJLEVBQUUsR0FBRyxJQUFJLENBQUM7UUFDakIsT0FBTyxHQUFHLENBQUM7SUFDWixDQUFDOzs7WUF6SkQsU0FBUyxTQUFDO2dCQUNWLFFBQVEsRUFBRSxLQUFLO2dCQUNmLDQxQ0FBaUQ7O2FBRWpEOzs7WUFSUSxRQUFROzs7c0JBV2YsS0FBSzs0QkFLTCxNQUFNOytCQUNOLFlBQVksU0FBQyxnQkFBZ0IiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIE9uSW5pdCwgSW5wdXQsIE91dHB1dCwgRXZlbnRFbWl0dGVyLCBWaWV3Q2hpbGRyZW4gfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEZvcm1Hcm91cCwgRm9ybUNvbnRyb2wgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQgeyBLZXlzUGlwZSB9IGZyb20gJy4uL3BpcGVzL2tleXMucGlwZSc7XG5pbXBvcnQgeyBTZXR0aW5nIH0gZnJvbSAnLi4vbW9kZWxzL3NldHRpbmcnO1xuaW1wb3J0IHsgQ291bnRlckRpcmVjdGl2ZSB9IGZyb20gJy4uL2RpcmVjdGl2ZXMvdGltZXIuZGlyZWN0aXZlJztcblxuQENvbXBvbmVudCh7XG5cdHNlbGVjdG9yOiAnb3RwJyxcblx0dGVtcGxhdGVVcmw6ICcuL2FuZ3VsYXItb3RwLWlucHV0LmNvbXBvbmVudC5odG1sJyxcblx0c3R5bGVVcmxzOiBbJy4vYW5ndWxhci1vdHAtaW5wdXQuY29tcG9uZW50LnNjc3MnXVxufSlcblxuZXhwb3J0IGNsYXNzIE90cElucHV0Q29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0IHtcblx0QElucHV0KCkgc2V0dGluZzogU2V0dGluZyA9IHsgXG5cdFx0bGVuZ3RoOiA0LCBcblx0XHR0aW1lcjogMCxcblx0XHR0aW1lclR5cGU6IDBcblx0fTtcblx0QE91dHB1dCgpIG9uVmFsdWVDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcblx0QFZpZXdDaGlsZHJlbihDb3VudGVyRGlyZWN0aXZlKSBDb3VudGVyRGlyZWN0aXZlO1xuXHRvdHBGb3JtOiBGb3JtR3JvdXA7XG5cdGlucHV0Q29udHJvbHM6IEZvcm1Db250cm9sW10gPSBuZXcgQXJyYXkodGhpcy5zZXR0aW5nLmxlbmd0aCk7XG5cdGNvbXBvbmVudEtleSA9IE1hdGgucmFuZG9tKCkudG9TdHJpbmcoMzYpLnN1YnN0cmluZygyKSArIChuZXcgRGF0ZSgpKS5nZXRUaW1lKCkudG9TdHJpbmcoMzYpO1xuXHRwdWJsaWMgY291bnRlcjogbnVtYmVyO1xuXHRcblx0Y29uc3RydWN0b3IocHJpdmF0ZSBrZXlzUGlwZTogS2V5c1BpcGUpIHtcblx0XHRcblx0fVxuXG5cdHB1YmxpYyBuZ09uSW5pdCgpOiB2b2lkIHtcblx0XHRjb25zb2xlLmxvZyh0aGlzLnNldHRpbmcpO1xuXHRcdHRoaXMub3RwRm9ybSA9IG5ldyBGb3JtR3JvdXAoe30pXG5cdFx0Zm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IHRoaXMuc2V0dGluZy5sZW5ndGg7IGluZGV4KyspIHtcblx0XHRcdHRoaXMub3RwRm9ybS5hZGRDb250cm9sKHRoaXMuZ2V0Q29udHJvbE5hbWUoaW5kZXgpLCBuZXcgRm9ybUNvbnRyb2woKSlcblx0XHR9XG5cdH1cblx0XG5cdHB1YmxpYyBuZ0FmdGVyVmlld0luaXQoKTogdm9pZCB7XG5cdFx0bGV0IGNvbnRhaW5lckl0ZW0gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChgY18ke3RoaXMuY29tcG9uZW50S2V5fWApO1xuXHRcdGlmIChjb250YWluZXJJdGVtKSB7XG5cdFx0XHRsZXQgZWxlOiBhbnkgPSBjb250YWluZXJJdGVtLmdldEVsZW1lbnRzQnlDbGFzc05hbWUoJy5vdHAtaW5wdXQnKVswXVxuXHRcdFx0aWYgKGVsZSAmJiBlbGUuZm9jdXMpIHtcblx0XHRcdFx0ZWxlLmZvY3VzKCk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0cHJpdmF0ZSBnZXRDb250cm9sTmFtZShpZHgpIHtcblx0XHRyZXR1cm4gYGN0cmxfJHtpZHh9YDtcblx0fVxuXG5cdGlzTGVmdEFycm93KGUpIHtcblx0XHRyZXR1cm4gdGhpcy5pc0tleUNvZGUoZSwgMzcpO1xuXHR9XG5cblx0aXNSaWdodEFycm93KGUpIHtcblx0XHRyZXR1cm4gdGhpcy5pc0tleUNvZGUoZSwgMzkpO1xuXHR9XG5cblx0aXNCYWNrc3BhY2VPckRlbGV0ZShlKSB7XG5cdFx0cmV0dXJuIGUua2V5ID09PSBcIkJhY2tzcGFjZVwiIHx8IGUua2V5ID09PSBcIkRlbGV0ZVwiIHx8IHRoaXMuaXNLZXlDb2RlKGUsIDgpIHx8IHRoaXMuaXNLZXlDb2RlKGUsIDQ2KTtcblx0fVxuXG5cdGlzS2V5Q29kZShlLCB0YXJnZXRDb2RlKSB7XG5cdFx0dmFyIGtleSA9IGUua2V5Q29kZSB8fCBlLmNoYXJDb2RlO1xuXHRcdGlmKGtleSA9PSB0YXJnZXRDb2RlKSB7IHJldHVybiB0cnVlOyB9XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG5cblx0a2V5VXAoZSwgaW5wdXRJZHg6IG51bWJlcikge1xuXHRcdGxldCBuZXh0SW5wdXRJZCA9IHRoaXMuYXBwZW5kS2V5KGBvdHBfJHtpbnB1dElkeCArIDF9YCk7XG5cdFx0bGV0IHByZXZJbnB1dElkID0gdGhpcy5hcHBlbmRLZXkoYG90cF8ke2lucHV0SWR4IC0gMX1gKTtcblx0XHRpZiAodGhpcy5pc1JpZ2h0QXJyb3coZSkpIHtcblx0XHRcdHRoaXMuc2V0U2VsZWN0ZWQobmV4dElucHV0SWQpO1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblx0XHRpZiAodGhpcy5pc0xlZnRBcnJvdyhlKSkge1xuXHRcdFx0dGhpcy5zZXRTZWxlY3RlZChwcmV2SW5wdXRJZCk7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXHRcdGxldCBpc0JhY2tzcGFjZSA9IHRoaXMuaXNCYWNrc3BhY2VPckRlbGV0ZShlKTtcblx0XHRpZiAoaXNCYWNrc3BhY2UgJiYgIWUudGFyZ2V0LnZhbHVlKSB7XG5cdFx0XHR0aGlzLnNldFNlbGVjdGVkKHByZXZJbnB1dElkKTtcblx0XHRcdHRoaXMucmVidWlsZFZhbHVlKCk7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXHRcdGlmICghZS50YXJnZXQudmFsdWUpIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cdFx0aWYgKHRoaXMuaXNWYWxpZEVudHJ5KGUpKSB7XG5cdFx0XHR0aGlzLmZvY3VzVG8obmV4dElucHV0SWQpO1xuXHRcdH1cblx0XHR0aGlzLnJlYnVpbGRWYWx1ZSgpO1xuXHR9XG5cblx0YXBwZW5kS2V5KGlkKSB7XG5cdFx0cmV0dXJuIGAke2lkfV8ke3RoaXMuY29tcG9uZW50S2V5fWA7XG5cdH1cblxuXHRzZXRTZWxlY3RlZChlbGVJZCkge1xuXHRcdHRoaXMuZm9jdXNUbyhlbGVJZCk7XG5cdFx0bGV0IGVsZTogYW55ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoZWxlSWQpO1xuXHRcdGlmIChlbGUgJiYgZWxlLnNldFNlbGVjdGlvblJhbmdlKSB7XG5cdFx0XHRzZXRUaW1lb3V0KCgpID0+IHtcblx0XHRcdFx0ZWxlLnNldFNlbGVjdGlvblJhbmdlKDAsIDEpO1xuXHRcdFx0fSwgMCk7XG5cdFx0fVxuXHR9XG5cblx0aXNWYWxpZEVudHJ5KGUpIHtcblx0XHR2YXIgaW5wID0gU3RyaW5nLmZyb21DaGFyQ29kZShlLmtleUNvZGUpO1xuXHRcdHZhciBpc01vYmlsZSA9IC9pUGhvbmV8aVBhZHxpUG9kfEFuZHJvaWQvaS50ZXN0KG5hdmlnYXRvci51c2VyQWdlbnQpO1xuXHRcdHJldHVybiBpc01vYmlsZSB8fCAvW2EtekEtWjAtOS1fXS8udGVzdChpbnApIHx8ICh0aGlzLnNldHRpbmcuYWxsb3dLZXlDb2RlcyAmJiB0aGlzLnNldHRpbmcuYWxsb3dLZXlDb2Rlcy5pbmNsdWRlcyhlLmtleUNvZGUpKSB8fCAoZS5rZXlDb2RlID49IDk2ICYmIGUua2V5Q29kZSA8PSAxMDUpO1xuXHR9XG5cblx0Zm9jdXNUbyhlbGVJZCkge1xuXHRcdGxldCBlbGU6IGFueSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGVsZUlkKTtcblx0XHRpZiAoZWxlKSB7XG5cdFx0XHRlbGUuZm9jdXMoKTtcblx0XHRcdGVsZS5zZWxlY3Rpb25TdGFydCA9IGVsZS5zZWxlY3Rpb25FbmQgPSAxMDA7XG5cdFx0fVxuXHR9XG5cblx0cmVidWlsZFZhbHVlKCkge1xuXHRcdGxldCB2YWwgPSAnJztcblx0XHR0aGlzLmtleXNQaXBlLnRyYW5zZm9ybSh0aGlzLm90cEZvcm0uY29udHJvbHMpLmZvckVhY2goayA9PiB7XG5cdFx0XHRpZiAodGhpcy5vdHBGb3JtLmNvbnRyb2xzW2tdLnZhbHVlKSB7XG5cdFx0XHRcdHZhbCArPSB0aGlzLm90cEZvcm0uY29udHJvbHNba10udmFsdWU7XG5cdFx0XHR9XG5cdFx0fSk7XG5cdFx0dGhpcy5vblZhbHVlQ2hhbmdlLmVtaXQodmFsKTtcblx0fVxuXG5cdHB1YmxpYyBvbkNvdW50ZXJDaGFuZ2UoZSk6IHZvaWQge1xuXHRcdHRoaXMuY291bnRlciA9IGU7XG5cdFx0aWYodGhpcy5jb3VudGVyID09IDApIHtcblx0XHRcdHRoaXMub25WYWx1ZUNoYW5nZS5lbWl0KC0xKTtcblx0XHR9XG5cdH1cblxuXHRyZXNzZW5kT3RwKCk6IHZvaWQge1xuXHRcdHRoaXMuQ291bnRlckRpcmVjdGl2ZS5maXJzdC5zdGFydFRpbWVyKCk7XG5cdFx0dGhpcy5vblZhbHVlQ2hhbmdlLmVtaXQoLTIpO1xuXHR9XG5cblx0cHVibGljIGZvcm1hdFNlY3NUb01pbnModGltZSkgeyAgIFxuXHRcdC8vIEhvdXJzLCBtaW51dGVzIGFuZCBzZWNvbmRzXG5cdFx0dmFyIGhycyA9IH5+KHRpbWUgLyAzNjAwKTtcblx0XHR2YXIgbWlucyA9IH5+KCh0aW1lICUgMzYwMCkgLyA2MCk7XG5cdFx0dmFyIHNlY3MgPSB+fnRpbWUgJSA2MDtcblx0XG5cdFx0Ly8gT3V0cHV0IGxpa2UgXCIxOjAxXCIgb3IgXCI0OjAzOjU5XCIgb3IgXCIxMjM6MDM6NTlcIlxuXHRcdHZhciByZXQgPSBcIlwiO1xuXHRcdGlmIChocnMgPiAwKSB7XG5cdFx0XHRyZXQgKz0gXCJcIiArIGhycyArIFwiOlwiICsgKG1pbnMgPCAxMCA/IFwiMFwiIDogXCJcIik7XG5cdFx0fVxuXHRcdHJldCArPSBcIlwiICsgbWlucyArIFwiOlwiICsgKHNlY3MgPCAxMCA/IFwiMFwiIDogXCJcIik7XG5cdFx0cmV0ICs9IFwiXCIgKyBzZWNzO1xuXHRcdHJldHVybiByZXQ7XG5cdH1cbn0iXX0=