moh-common-lib
Version:
A library of Angular components, services, and styles for B.C. Government Ministry of Health (MoH).
213 lines • 19.9 kB
JavaScript
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
import { Component, EventEmitter, Input, Output, Optional, Self } from '@angular/core';
import { NUMBER, SPACE } from '../../models/mask.constants';
import { NgControl } from '@angular/forms';
import { LabelReplacementTag } from '../../models/error-message.interface';
import { AbstractFormControl } from '../../models/abstract-form-control';
export class PhnComponent extends AbstractFormControl {
/**
* @param {?} controlDir
*/
constructor(controlDir) {
super();
this.controlDir = controlDir;
this.label = 'Personal Health Number (PHN)';
this.placeholder = '1111 111 111';
this.labelforId = 'phn_' + this.objectId;
this.required = false;
// Self-Validation inputs
this.isBCPhn = true;
this._defaultErrMsg = {
required: `${LabelReplacementTag} is required.`,
invalid: `${LabelReplacementTag} is invalid.`,
duplicate: `${LabelReplacementTag} was already used for another family member.`,
};
this.valueChange = new EventEmitter();
this.blur = new EventEmitter();
this.phn = '';
if (controlDir) {
controlDir.valueAccessor = this;
}
this.mask =
[NUMBER, NUMBER, NUMBER, NUMBER, SPACE, NUMBER, NUMBER, NUMBER, SPACE, NUMBER, NUMBER, NUMBER];
}
/**
* @param {?} val
* @return {?}
*/
set value(val) {
if (val) {
this.phn = val;
}
}
/**
* @return {?}
*/
get value() {
return this.phn;
}
/**
* @return {?}
*/
ngOnInit() {
super.ngOnInit();
this.registerValidation(this.controlDir, this.validateSelf);
}
/**
* @param {?} value
* @return {?}
*/
onValueChange(value) {
if (value !== this.phn) { // IE fix when focus does not display required error
this.phn = value;
this._onChange(value);
this.valueChange.emit(value);
}
}
/**
* @param {?} event
* @return {?}
*/
onBlur(event) {
this._onTouched(event);
this.blur.emit(event);
}
/**
* @param {?} value
* @return {?}
*/
writeValue(value) {
if (value !== undefined) {
this.phn = value;
}
}
/**
* @private
* @return {?}
*/
validateSelf() {
/** @type {?} */
const validatePhnResult = this.validatePhn();
if (validatePhnResult) {
return validatePhnResult;
}
return null;
}
/**
* @private
* @return {?}
*/
validatePhn() {
if (this.phn && this.phn.trim().length > 0) {
// Init weights and other stuff
/** @type {?} */
const weights = [-1, 2, 4, 8, 5, 10, 9, 7, 3, -1];
/** @type {?} */
let sumOfRemainders = 0;
// Clean up string
/** @type {?} */
const value = this.phn.trim();
this.phn = value
.replace(/^0+/, '') // remove leading zeros
.replace(/_/g, '') // remove underlines
.replace(/\s/g, ''); // spaces
// Test for length
if (this.phn.length !== 10) {
return { 'invalid': true };
}
// Look for a number that starts with 9 if BC only
if (this.isBCPhn && this.phn[0] !== '9') {
return { 'invalid': true };
}
else if (!this.isBCPhn && this.phn[0] === '9') { // Number cannot have 9
return { 'invalid': true };
}
// Walk through each character
for (let i = 0; i < this.phn.length; i++) {
// pull out char
/** @type {?} */
const char = this.phn.charAt(i);
// parse the number
/** @type {?} */
const num = Number(char);
if (Number.isNaN(num)) {
return { 'invalid': true };
}
// Only use the multiplier if weight is greater than zero
/** @type {?} */
let result = 0;
if (weights[i] > 0) {
// multiply the value against the weight
result = num * weights[i];
// divide by 11 and save the remainder
result = result % 11;
// add it to our sum
sumOfRemainders += result;
}
}
// mod by 11
/** @type {?} */
const checkDigit = 11 - (sumOfRemainders % 11);
// if the result is 10 or 11, it is an invalid PHN
if (checkDigit === 10 || checkDigit === 11) {
return { 'invalid': true };
}
// Compare against 10th digitfinalDigit
/** @type {?} */
const finalDigit = Number(this.phn.substring(9, 10));
if (checkDigit !== finalDigit) {
return { 'invalid': true };
}
}
return null;
}
}
PhnComponent.decorators = [
{ type: Component, args: [{
selector: 'common-phn',
template: "\r\n<label for=\"{{labelforId}}\" class=\"control-label\">{{label}}</label>\r\n<input class=\"form-control\"\r\n spellcheck=\"false\"\r\n id=\"{{labelforId}}\"\r\n [ngModel]=\"phn\"\r\n (ngModelChange)=\"onValueChange($event)\"\r\n (blur)=\"onBlur($event)\"\r\n [placeholder]=\"placeholder\"\r\n [textMask]=\"{mask: mask}\"\r\n [disabled]=\"disabled\"\r\n [required]=\"required\"\r\n autocomplete=\"off\"/>\r\n\r\n\r\n <!-- Error messages for input -->\r\n <common-error-container\r\n [displayError]=\"controlDir && !disabled && (controlDir.touched || controlDir.dirty) && controlDir?.errors\">\r\n <div *ngIf=\"controlDir?.errors?.required\">\r\n {{_defaultErrMsg.required}}\r\n </div>\r\n <div *ngIf=\"controlDir?.errors?.invalid\">\r\n {{_defaultErrMsg.invalid}}\r\n </div>\r\n <div *ngIf=\"controlDir?.errors?.duplicate\">\r\n {{_defaultErrMsg.duplicate}}\r\n </div>\r\n </common-error-container>\r\n",
styles: [""]
}] }
];
/** @nocollapse */
PhnComponent.ctorParameters = () => [
{ type: NgControl, decorators: [{ type: Optional }, { type: Self }] }
];
PhnComponent.propDecorators = {
label: [{ type: Input }],
placeholder: [{ type: Input }],
labelforId: [{ type: Input }],
required: [{ type: Input }],
isBCPhn: [{ type: Input }],
value: [{ type: Input }],
valueChange: [{ type: Output }],
blur: [{ type: Output }]
};
if (false) {
/** @type {?} */
PhnComponent.prototype.label;
/** @type {?} */
PhnComponent.prototype.placeholder;
/** @type {?} */
PhnComponent.prototype.labelforId;
/** @type {?} */
PhnComponent.prototype.required;
/** @type {?} */
PhnComponent.prototype.isBCPhn;
/** @type {?} */
PhnComponent.prototype._defaultErrMsg;
/** @type {?} */
PhnComponent.prototype.valueChange;
/** @type {?} */
PhnComponent.prototype.blur;
/** @type {?} */
PhnComponent.prototype.phn;
/** @type {?} */
PhnComponent.prototype.mask;
/** @type {?} */
PhnComponent.prototype.controlDir;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGhuLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiJuZzovL21vaC1jb21tb24tbGliLyIsInNvdXJjZXMiOlsibGliL2NvbXBvbmVudHMvcGhuL3Bobi5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7OztBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBUyxNQUFNLGVBQWUsQ0FBQztBQUM5RixPQUFPLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBQzVELE9BQU8sRUFBd0IsU0FBUyxFQUFvQixNQUFNLGdCQUFnQixDQUFDO0FBQ25GLE9BQU8sRUFBZ0IsbUJBQW1CLEVBQUUsTUFBTSxzQ0FBc0MsQ0FBQztBQUN6RixPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxvQ0FBb0MsQ0FBQztBQU96RSxNQUFNLE9BQU8sWUFBYSxTQUFRLG1CQUFtQjs7OztJQWdDbkQsWUFBd0MsVUFBcUI7UUFDM0QsS0FBSyxFQUFFLENBQUM7UUFEOEIsZUFBVSxHQUFWLFVBQVUsQ0FBVztRQTlCcEQsVUFBSyxHQUFXLDhCQUE4QixDQUFDO1FBQy9DLGdCQUFXLEdBQVcsY0FBYyxDQUFDO1FBQ3JDLGVBQVUsR0FBVyxNQUFNLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQztRQUM1QyxhQUFRLEdBQVksS0FBSyxDQUFDOztRQUcxQixZQUFPLEdBQVksSUFBSSxDQUFDO1FBRWpDLG1CQUFjLEdBQWlCO1lBQzdCLFFBQVEsRUFBRSxHQUFHLG1CQUFtQixlQUFlO1lBQy9DLE9BQU8sRUFBRSxHQUFHLG1CQUFtQixjQUFjO1lBQzdDLFNBQVMsRUFBRSxHQUFHLG1CQUFtQiw4Q0FBOEM7U0FDaEYsQ0FBQztRQVlRLGdCQUFXLEdBQXlCLElBQUksWUFBWSxFQUFVLENBQUM7UUFDL0QsU0FBSSxHQUFzQixJQUFJLFlBQVksRUFBTyxDQUFDO1FBRTVELFFB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OztrQkFHSyxVQUFVLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsU0FBUyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQztZQUNwRCxJQUFJLFVBQVUsS0FBSyxVQUFVLEVBQUU7Z0JBQzdCLE9BQU8sRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLENBQUM7YUFDNUI7U0FDRjtRQUNELE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQzs7O1lBdEpGLFNBQVMsU0FBQztnQkFDVCxRQUFRLEVBQUUsWUFBWTtnQkFDdEIsdS9CQUFtQzs7YUFFcEM7Ozs7WUFSOEIsU0FBUyx1QkF5Q3hCLFFBQVEsWUFBSSxJQUFJOzs7b0JBOUI3QixLQUFLOzBCQUNMLEtBQUs7eUJBQ0wsS0FBSzt1QkFDTCxLQUFLO3NCQUdMLEtBQUs7b0JBUUwsS0FBSzswQkFVTCxNQUFNO21CQUNOLE1BQU07Ozs7SUF6QlAsNkJBQXdEOztJQUN4RCxtQ0FBOEM7O0lBQzlDLGtDQUFxRDs7SUFDckQsZ0NBQW1DOztJQUduQywrQkFBaUM7O0lBRWpDLHNDQUlFOztJQVlGLG1DQUF5RTs7SUFDekUsNEJBQTREOztJQUU1RCwyQkFBaUI7O0lBQ2pCLDRCQUFVOztJQUVHLGtDQUFnRCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgRXZlbnRFbWl0dGVyLCBJbnB1dCwgT3V0cHV0LCBPcHRpb25hbCwgU2VsZiwgT25Jbml0fSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgTlVNQkVSLCBTUEFDRSB9IGZyb20gJy4uLy4uL21vZGVscy9tYXNrLmNvbnN0YW50cyc7XHJcbmltcG9ydCB7IENvbnRyb2xWYWx1ZUFjY2Vzc29yLCBOZ0NvbnRyb2wsIFZhbGlkYXRpb25FcnJvcnMgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XHJcbmltcG9ydCB7IEVycm9yTWVzc2FnZSwgTGFiZWxSZXBsYWNlbWVudFRhZyB9IGZyb20gJy4uLy4uL21vZGVscy9lcnJvci1tZXNzYWdlLmludGVyZmFjZSc7XHJcbmltcG9ydCB7IEFic3RyYWN0Rm9ybUNvbnRyb2wgfSBmcm9tICcuLi8uLi9tb2RlbHMvYWJzdHJhY3QtZm9ybS1jb250cm9sJztcclxuXHJcbkBDb21wb25lbnQoe1xyXG4gIHNlbGVjdG9yOiAnY29tbW9uLXBobicsXHJcbiAgdGVtcGxhdGVVcmw6ICcuL3Bobi5jb21wb25lbnQuaHRtbCcsXHJcbiAgc3R5bGVVcmxzOiBbJy4vcGhuLmNvbXBvbmVudC5zY3NzJ11cclxufSlcclxuZXhwb3J0IGNsYXNzIFBobkNvbXBvbmVudCBleHRlbmRzIEFic3RyYWN0Rm9ybUNvbnRyb2wgaW1wbGVtZW50cyBPbkluaXQsIENvbnRyb2xWYWx1ZUFjY2Vzc29yIHtcclxuXHJcbiAgQElucHV0KCkgbGFiZWw6IHN0cmluZyA9ICdQZXJzb25hbCBIZWFsdGggTnVtYmVyIChQSE4pJztcclxuICBASW5wdXQoKSBwbGFjZWhvbGRlcjogc3RyaW5nID0gJzExMTEgMTExIDExMSc7XHJcbiAgQElucHV0KCkgbGFiZWxmb3JJZDogc3RyaW5nID0gJ3Bobl8nICsgdGhpcy5vYmplY3RJZDtcclxuICBASW5wdXQoKSByZXF1aXJlZDogYm9vbGVhbiA9IGZhbHNlO1xyXG5cclxuICAvLyBTZWxmLVZhbGlkYXRpb24gaW5wdXRzXHJcbiAgQElucHV0KCkgaXNCQ1BobjogYm9vbGVhbiA9IHRydWU7XHJcblxyXG4gIF9kZWZhdWx0RXJyTXNnOiBFcnJvck1lc3NhZ2UgPSB7XHJcbiAgICByZXF1aXJlZDogYCR7TGFiZWxSZXBsYWNlbWVudFRhZ30gaXMgcmVxdWlyZWQuYCxcclxuICAgIGludmFsaWQ6IGAke0xhYmVsUmVwbGFjZW1lbnRUYWd9IGlzIGludmFsaWQuYCxcclxuICAgIGR1cGxpY2F0ZTogYCR7TGFiZWxSZXBsYWNlbWVudFRhZ30gd2FzIGFscmVhZHkgdXNlZCBmb3IgYW5vdGhlciBmYW1pbHkgbWVtYmVyLmAsXHJcbiAgfTtcclxuXHJcbiAgQElucHV0KClcclxuICBzZXQgdmFsdWUoIHZhbDogc3RyaW5nICkge1xyXG4gICAgaWYgKCB2YWwpIHtcclxuICAgICAgdGhpcy5waG4gPSB2YWw7XHJcbiAgICB9XHJcbiAgfVxyXG4gIGdldCB2YWx1ZSgpIHtcclxuICAgIHJldHVybiB0aGlzLnBobjtcclxuICB9XHJcblxyXG4gIEBPdXRwdXQoKSB2YWx1ZUNoYW5nZTogRXZlbnRFbWl0dGVyPHN0cmluZz4gPSBuZXcgRXZlbnRFbWl0dGVyPHN0cmluZz4oKTtcclxuICBAT3V0cHV0KCkgYmx1cjogRXZlbnRFbWl0dGVyPGFueT4gPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcclxuXHJcbiAgcGhuOiBzdHJpbmcgPSAnJztcclxuICBtYXNrOiBhbnk7XHJcblxyXG4gIGNvbnN0cnVjdG9yKCBAT3B0aW9uYWwoKSBAU2VsZigpIHB1YmxpYyBjb250cm9sRGlyOiBOZ0NvbnRyb2wgKSB7XHJcbiAgICBzdXBlcigpO1xyXG4gICAgaWYgKCBjb250cm9sRGlyICkge1xyXG4gICAgICBjb250cm9sRGlyLnZhbHVlQWNjZXNzb3IgPSB0aGlzO1xyXG4gICAgfVxyXG5cclxuICAgIHRoaXMubWFzayA9XHJcbiAgICAgIFtOVU1CRVIsIE5VTUJFUiwgTlVNQkVSLCBOVU1CRVIsIFNQQUNFLCBOVU1CRVIsIE5VTUJFUiwgTlVNQkVSLCBTUEFDRSwgTlVNQkVSLCBOVU1CRVIsIE5VTUJFUl07XHJcbiAgfVxyXG5cclxuICBuZ09uSW5pdCgpIHtcclxuICAgIHN1cGVyLm5nT25Jbml0KCk7XHJcblxyXG4gICAgdGhpcy5yZWdpc3RlclZhbGlkYXRpb24oIHRoaXMuY29udHJvbERpciwgdGhpcy52YWxpZGF0ZVNlbGYgKTtcclxuICB9XHJcblxyXG4gIG9uVmFsdWVDaGFuZ2UoIHZhbHVlOiBhbnkgKSB7XHJcblxyXG4gICAgaWYgKCB2YWx1ZSAhPT0gdGhpcy5waG4gKSB7IC8vIElFIGZpeCB3aGVuIGZvY3VzIGRvZXMgbm90IGRpc3BsYXkgcmVxdWlyZWQgZXJyb3JcclxuICAgICAgdGhpcy5waG4gPSB2YWx1ZTtcclxuICAgICAgdGhpcy5fb25DaGFuZ2UoIHZhbHVlICk7XHJcbiAgICAgIHRoaXMudmFsdWVDaGFuZ2UuZW1pdCggdmFsdWUgKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIG9uQmx1ciggZXZlbnQ6IGFueSApIHtcclxuICAgIHRoaXMuX29uVG91Y2hlZCggZXZlbnQgKTtcclxuICAgIHRoaXMuYmx1ci5lbWl0KCBldmVudCApO1xyXG4gIH1cclxuXHJcbiAgd3JpdGVWYWx1ZSggdmFsdWU6IGFueSApOiB2b2lkIHtcclxuICAgIGlmICggdmFsdWUgIT09IHVuZGVmaW5lZCApIHtcclxuICAgICAgdGhpcy5waG4gPSB2YWx1ZTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHByaXZhdGUgdmFsaWRhdGVTZWxmKCk6IFZhbGlkYXRpb25FcnJvcnMgfCBudWxsIHtcclxuXHJcbiAgICBjb25zdCB2YWxpZGF0ZVBoblJlc3VsdCA9IHRoaXMudmFsaWRhdGVQaG4oKTtcclxuICAgIGlmICggdmFsaWRhdGVQaG5SZXN1bHQgKSB7XHJcbiAgICAgIHJldHVybiB2YWxpZGF0ZVBoblJlc3VsdDtcclxuICAgIH1cclxuICAgIHJldHVybiBudWxsO1xyXG4gICB9XHJcblxyXG4gIHByaXZhdGUgdmFsaWRhdGVQaG4oKTogVmFsaWRhdGlvbkVycm9ycyB8IG51bGwge1xyXG5cclxuICAgIGlmICggdGhpcy5waG4gJiYgdGhpcy5waG4udHJpbSgpLmxlbmd0aCA+IDAgKSB7XHJcblxyXG4gICAgICAvLyBJbml0IHdlaWdodHMgYW5kIG90aGVyIHN0dWZmXHJcbiAgICAgIGNvbnN0IHdlaWdodHM6IG51bWJlcltdID0gWy0xLCAyLCA0LCA4LCA1LCAxMCwgOSwgNywgMywgLTFdO1xyXG4gICAgICBsZXQgc3VtT2ZSZW1haW5kZXJzID0gMDtcclxuXHJcbiAgICAgIC8vIENsZWFuIHVwIHN0cmluZ1xyXG4gICAgICBjb25zdCB2YWx1ZSA9IHRoaXMucGhuLnRyaW0oKTtcclxuICAgICAgdGhpcy5waG4gPSB2YWx1ZVxyXG4gICAgICAgICAgICAgICAgICAucmVwbGFjZSggL14wKy8sICcnICkgLy8gcmVtb3ZlIGxlYWRpbmcgemVyb3NcclxuICAgICAgICAgICAgICAgICAgLnJlcGxhY2UoL18vZywgJycpIC8vIHJlbW92ZSB1bmRlcmxpbmVzXHJcbiAgICAgICAgICAgICAgICAgIC5yZXBsYWNlKC9cXHMvZywgJycpOyAvLyBzcGFjZXNcclxuXHJcbiAgICAgIC8vIFRlc3QgZm9yIGxlbmd0aFxyXG4gICAgICBpZiAodGhpcy5waG4ubGVuZ3RoICE9PSAxMCkge1xyXG4gICAgICAgIHJldHVybiB7ICdpbnZhbGlkJzogdHJ1ZSB9O1xyXG4gICAgICB9XHJcbiAgICAgIC8vIExvb2sgZm9yIGEgbnVtYmVyIHRoYXQgc3RhcnRzIHdpdGggOSBpZiBCQyBvbmx5XHJcbiAgICAgIGlmICh0aGlzLmlzQkNQaG4gJiYgdGhpcy5waG5bMF0gIT09ICc5Jykge1xyXG4gICAgICAgIHJldHVybiB7ICdpbnZhbGlkJzogdHJ1ZSB9O1xyXG4gICAgICB9IGVsc2UgaWYgKCF0aGlzLmlzQkNQaG4gJiYgdGhpcy5waG5bMF0gPT09ICc5JykgeyAvLyBOdW1iZXIgY2Fubm90IGhhdmUgOVxyXG4gICAgICAgIHJldHVybiB7ICdpbnZhbGlkJzogdHJ1ZSB9O1xyXG4gICAgICB9XHJcblxyXG4gICAgICAvLyBXYWxrIHRocm91Z2ggZWFjaCBjaGFyYWN0ZXJcclxuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLnBobi5sZW5ndGg7IGkrKykge1xyXG5cclxuICAgICAgICAvLyBwdWxsIG91dCBjaGFyXHJcbiAgICAgICAgY29uc3QgY2hhciA9IHRoaXMucGhuLmNoYXJBdChpKTtcclxuXHJcbiAgICAgICAgLy8gcGFyc2UgdGhlIG51bWJlclxyXG4gICAgICAgIGNvbnN0IG51bSA9IE51bWJlcihjaGFyKTtcclxuXHJcbiAgICAgICAgaWYgKE51bWJlci5pc05hTihudW0pKSB7XHJcbiAgICAgICAgICByZXR1cm4geyAnaW52YWxpZCc6IHRydWUgfTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIE9ubHkgdXNlIHRoZSBtdWx0aXBsaWVyIGlmIHdlaWdodCBpcyBncmVhdGVyIHRoYW4gemVyb1xyXG4gICAgICAgIGxldCByZXN1bHQgPSAwO1xyXG4gICAgICAgIGlmICh3ZWlnaHRzW2ldID4gMCkge1xyXG4gICAgICAgICAgLy8gbXVsdGlwbHkgdGhlIHZhbHVlIGFnYWluc3QgdGhlIHdlaWdodFxyXG4gICAgICAgICAgcmVzdWx0ID0gbnVtICogd2VpZ2h0c1tpXTtcclxuXHJcbiAgICAgICAgICAvLyBkaXZpZGUgYnkgMTEgYW5kIHNhdmUgdGhlIHJlbWFpbmRlclxyXG4gICAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICUgMTE7XHJcblxyXG4gICAgICAgICAgLy8gYWRkIGl0IHRvIG91ciBzdW1cclxuICAgICAgICAgIHN1bU9mUmVtYWluZGVycyArPSByZXN1bHQ7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcblxyXG4gICAgICAvLyBtb2QgYnkgMTFcclxuICAgICAgY29uc3QgY2hlY2tEaWdpdCA9IDExIC0gKHN1bU9mUmVtYWluZGVycyAlIDExKTtcclxuXHJcbiAgICAgIC8vIGlmIHRoZSByZXN1bHQgaXMgMTAgb3IgMTEsIGl0IGlzIGFuIGludmFsaWQgUEhOXHJcbiAgICAgIGlmIChjaGVja0RpZ2l0ID09PSAxMCB8fCBjaGVja0RpZ2l0ID09PSAxMSkge1xyXG4gICAgICAgIHJldHVybiB7ICdpbnZhbGlkJzogdHJ1ZSB9O1xyXG4gICAgICB9XHJcblxyXG4gICAgICAvLyBDb21wYXJlIGFnYWluc3QgMTB0aCBkaWdpdGZpbmFsRGlnaXRcclxuICAgICAgY29uc3QgZmluYWxEaWdpdCA9IE51bWJlcih0aGlzLnBobi5zdWJzdHJpbmcoOSwgMTApKTtcclxuICAgICAgaWYgKGNoZWNrRGlnaXQgIT09IGZpbmFsRGlnaXQpIHtcclxuICAgICAgICByZXR1cm4geyAnaW52YWxpZCc6IHRydWUgfTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIG51bGw7XHJcbiAgfVxyXG5cclxuXHJcbn1cclxuIl19