UNPKG

ng-payment-card

Version:

Customizable component with zero external dependencies.

340 lines 36.4 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc */ import { Component, EventEmitter, Output, Input, ViewEncapsulation } from '@angular/core'; import { FormBuilder, Validators } from '@angular/forms'; import { CardValidator } from './validator/card-validator'; import { PaymentCardService } from './service/payment-card.service'; /** * NgPaymentCard without any dependencies other then ReactiveFormsModule */ export class PaymentCardComponent { /** * @param {?} _ccService * @param {?} _fb */ constructor(_ccService, _fb) { this._ccService = _ccService; this._fb = _fb; /** * List of months */ this.months = []; /** * List of years */ this.years = []; /** * Validation message for missing payment card number */ this.ccNumMissingTxt = 'Card number is required'; /** * Validation message for too short payment card number */ this.ccNumTooShortTxt = 'Card number is too short'; /** * Validation message for too long payment card number */ this.ccNumTooLongTxt = 'Card number is too long'; /** * Validation message for payment card number that contains characters other than digits */ this.ccNumContainsLettersTxt = 'Card number can contain digits only'; /** * Validation message for invalid payment card number (Luhn's validation) */ this.ccNumChecksumInvalidTxt = 'Provided card number is invalid'; /** * Validation message for missing card holder name */ this.cardHolderMissingTxt = 'Card holder name is required'; /** * Validation message for too long card holder name */ this.cardHolderTooLongTxt = 'Card holder name is too long'; /** * Validation message for missing expiration month */ this.expirationMonthMissingTxt = 'Expiration month is required'; /** * Validation message for missing expiration year */ this.expirationYearMissingTxt = 'Expiration year is required'; /** * Validation message for missing CCV number */ this.ccvMissingTxt = 'CCV number is required'; /** * Validation message for too short CCV number */ this.ccvNumTooShortTxt = 'CCV number is too short'; /** * Validation message for too long CCV number */ this.ccvNumTooLongTxt = 'CCV number is too long'; /** * Validation message for incorrect CCV number containing characters other than digits */ this.ccvContainsLettersTxt = 'CCV number can contain digits only'; /** * Validation message for expired card */ this.cardExpiredTxt = 'Card has expired'; /** * Switch validation of the payment card number */ this.validateCCNum = true; /** * Switch validation of the payment card holder */ this.validateCardHolder = true; /** * Switch validation of the payment card expiration month */ this.validateExpirationMonth = true; /** * Switch validation of the payment card expiration year */ this.validateExpirationYear = true; /** * Switch validation of the payment card expiration */ this.validateCardExpiration = true; /** * Switch validation of the payment card CCV number */ this.validateCCV = true; /** * EventEmitter for payment card object */ this.formSaved = new EventEmitter(); } /** * @return {?} */ ngOnInit() { this.buildForm(); this.assignDateValues(); } /** * Populate months and years * @return {?} */ assignDateValues() { this.months = PaymentCardService.getMonths(); this.years = PaymentCardService.getYears(); } /** * Build reactive form * @return {?} */ buildForm() { this.ccForm = this._fb.group({ cardNumber: [ '', Validators.compose([ Validators.required, Validators.minLength(12), Validators.maxLength(19), CardValidator.numbersOnly, CardValidator.checksum, ]), ], cardHolder: ['', Validators.compose([Validators.required, Validators.maxLength(22)])], expirationMonth: ['', Validators.required], expirationYear: ['', Validators.required], ccv: [ '', Validators.compose([ Validators.required, Validators.minLength(3), Validators.maxLength(4), CardValidator.numbersOnly, ]), ], }, { validator: CardValidator.expiration, }); } /** * Returns payment card type based on payment card number * @param {?} ccNum * @return {?} */ getCardType(ccNum) { return PaymentCardService.getCardType(ccNum); } /** * Callback function that emits payment card details after user clicks submit, or press enter * @return {?} */ emitSavedCard() { /** @type {?} */ const cardDetails = (/** @type {?} */ (this.ccForm.value)); this.formSaved.emit(cardDetails); } } PaymentCardComponent.decorators = [ { type: Component, args: [{ selector: 'ng-payment-card', template: "<section class=\"cc-wrapper\">\r\n <div class=\"cc-box\">\r\n <div #ccBoxFlip class=\"cc-box--flip\">\r\n <div class=\"cc-box__front\">\r\n <div class=\"cc-box__logo\">\r\n <p>{{getCardType(ccNumber.value) | uppercase}}</p>\r\n </div>\r\n <div class=\"cc-box__element\">\r\n <label class=\"cc-form__label\" for=\"cc-card-number-display\"></label>\r\n <input class=\"cc-form__input cc-form__input--transparent cc-form__input--embosed\" id=\"cc-card-number-display\"\r\n aria-label=\"Payment card number\" disabled=\"disabled\"\r\n [value]=\"ccForm.get('cardNumber').value | paymentCardNumber\">\r\n </div>\r\n <div class=\"cc-box__element\">\r\n <label class=\"cc-form__label\" for=\"cc-holder-display\">CARD HOLDER</label>\r\n <input class=\"cc-form__input cc-form__input--transparent cc-form__input--embosed\" id=\"cc-holder-display\"\r\n aria-label=\"Card holder\" disabled=\"disabled\" [value]=\"ccForm.get('cardHolder').value | uppercase\">\r\n </div>\r\n <div class=\"cc-box__element\">\r\n <label class=\"cc-form__label\" for=\"cc-valid-date-display\">VALID THRU</label>\r\n <input class=\"cc-form__input cc-form__input--left-align cc-form__input--transparent cc-form__input--embosed\"\r\n id=\"cc-valid-date-display\" aria-label=\"Card holder\" disabled=\"disabled\"\r\n [value]=\"ccForm.get('expirationMonth').value + '/' + ccForm.get('expirationYear').value | validThru\">\r\n </div>\r\n <div class=\"cc-box__chip\"></div>\r\n </div>\r\n <div class=\"cc-box__back\">\r\n <div class=\"cc-box__strip\">&nbsp;</div>\r\n <div class=\"cc-box__element\">\r\n <input class=\"cc-form__input cc-form__input--cursive cc-form__input--right-align\" id=\"cc-ccv-display\"\r\n aria-label=\"CCV\" disabled=\"disabled\"\r\n [value]=\"'CCV: ' + ccForm.get('ccv').value\" title=\"CCV\">\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <form class=\"cc-form\" [formGroup]=\"ccForm\" autocomplete=\"off\">\r\n <div class=\"cc-form__wrapper--long\">\r\n <label for=\"cc-number\" class=\"cc-form__label cc-form__label--first\">Card number</label>\r\n <input #ccNumber class=\"cc-form__input\" id=\"cc-number\" aria-label=\"Card number\"\r\n type=\"text\" title=\"Card number\" maxlength=\"19\" formControlName=\"cardNumber\"\r\n (focus)=\"ccBoxFlip.classList.remove('hover')\">\r\n <div class=\"cc-form__error\"\r\n *ngIf=\"validateCCNum && ccForm.get('cardNumber').touched && ccForm.get('cardNumber').hasError('required')\">\r\n {{ccNumMissingTxt}}\r\n </div>\r\n <div class=\"cc-form__error\"\r\n *ngIf=\"validateCCNum && ccForm.get('cardNumber').touched && ccForm.get('cardNumber').hasError('minlength')\">\r\n {{ccNumTooShortTxt}}\r\n </div>\r\n <div class=\"cc-form__error\"\r\n *ngIf=\"validateCCNum && ccForm.get('cardNumber').touched && ccForm.get('cardNumber').hasError('maxlength')\">\r\n {{ccNumTooLongTxt}}\r\n </div>\r\n <div class=\"cc-form__error\"\r\n *ngIf=\"validateCCNum && ccForm.get('cardNumber').touched && ccForm.get('cardNumber').hasError('numbersOnly')\">\r\n {{ccNumContainsLettersTxt}}\r\n </div>\r\n <div class=\"cc-form__error\"\r\n *ngIf=\"validateCCNum && ccForm.get('cardNumber').touched && ccForm.get('cardNumber').hasError('checksum')\">\r\n {{ccNumChecksumInvalidTxt}}\r\n </div>\r\n </div>\r\n <div class=\"cc-form__wrapper--long\">\r\n <label for=\"cc-holder-name\" class=\"cc-form__label\">Card Holder name</label>\r\n <input class=\"cc-form__input\" id=\"cc-holder-name\" aria-label=\"Card holder name\" type=\"text\"\r\n title=\"Card holder name\" maxlength=\"22\" formControlName=\"cardHolder\"\r\n (focus)=\"ccBoxFlip.classList.remove('hover')\">\r\n <div class=\"cc-form__error\"\r\n *ngIf=\"validateCardHolder && ccForm.get('cardHolder').touched &&\r\n ccForm.get('cardHolder').hasError('required')\">\r\n {{cardHolderMissingTxt}}\r\n </div>\r\n <div class=\"cc-form__error\"\r\n *ngIf=\"validateCardHolder && ccForm.get('cardHolder').touched &&\r\n ccForm.get('cardHolder').hasError('maxlength')\">\r\n {{cardHolderTooLongTxt}}\r\n </div>\r\n </div>\r\n <div class=\"cc-form--inline\">\r\n <div class=\"cc-form__wrapper cc-form__wrapper--short\">\r\n <label for=\"cc-expiration-month\" class=\"cc-form__label\">Expiration month</label>\r\n <select id=\"cc-expiration-month\" class=\"cc-form__select\" aria-label=\"Expiration month\"\r\n formControlName=\"expirationMonth\">\r\n <option *ngFor=\"let month of months\" value=\"{{month}}\"\r\n (click)=\"ccBoxFlip.classList.remove('hover')\">{{month}}\r\n </option>\r\n </select>\r\n </div>\r\n <div class=\"cc-form__wrapper cc-form__wrapper--short\">\r\n <label for=\"cc-expiration-year\" class=\"cc-form__label\">Expiration year</label>\r\n <select id=\"cc-expiration-year\" class=\"cc-form__select\" aria-label=\"Expiration year\"\r\n formControlName=\"expirationYear\">\r\n <option *ngFor=\"let year of years\" value=\"{{year}}\"\r\n (click)=\"ccBoxFlip.classList.remove('hover')\">{{year}}\r\n </option>\r\n </select>\r\n </div>\r\n <div class=\"cc-form__wrapper cc-form__wrapper--short cc-form__wrapper--last\">\r\n <label for=\"cc-ccv\" class=\"cc-form__label\">ccv</label>\r\n <input class=\"cc-form__input cc-form__input--short\" id=\"cc-ccv\" aria-label=\"CCV\" type=\"text\" title=\"CCV\"\r\n minlength=\"3\" maxlength=\"4\" formControlName=\"ccv\" (focus)=\"ccBoxFlip.classList.add('hover')\">\r\n </div>\r\n </div>\r\n <div class=\"cc-form__error\"\r\n *ngIf=\"validateExpirationMonth && ccForm.get('expirationMonth').touched &&\r\n ccForm.get('expirationMonth').hasError('required')\">\r\n {{expirationMonthMissingTxt}}\r\n </div>\r\n <div class=\"cc-form__error\"\r\n *ngIf=\"validateExpirationMonth && ccForm.get('expirationYear').touched &&\r\n ccForm.get('expirationYear').hasError('required')\">\r\n {{expirationYearMissingTxt}}\r\n </div>\r\n <div class=\"cc-form__error\" *ngIf=\"validateCardExpiration && ccForm.get('expirationMonth').touched &&\r\n ccForm.get('expirationYear').touched && ccForm.hasError('expiration')\">\r\n {{cardExpiredTxt}}\r\n </div>\r\n <div class=\"cc-form__error\"\r\n *ngIf=\"validateCCV && ccForm.get('ccv').touched && ccForm.get('ccv').hasError('required')\">\r\n {{ccvMissingTxt}}\r\n </div>\r\n <div class=\"cc-form__error\"\r\n *ngIf=\"validateCCV && ccForm.get('ccv').touched && ccForm.get('ccv').hasError('minlength')\">\r\n {{ccvNumTooShortTxt}}\r\n </div>\r\n <div class=\"cc-form__error\"\r\n *ngIf=\"validateCCV && ccForm.get('ccv').touched && ccForm.get('ccv').hasError('maxlength')\">\r\n {{ccvNumTooLongTxt}}\r\n </div>\r\n <div class=\"cc-form__error\"\r\n *ngIf=\"validateCCV && ccForm.get('ccv').touched && ccForm.get('ccv').hasError('numbersOnly')\">\r\n {{ccvContainsLettersTxt}}\r\n </div>\r\n <button type=\"submit\" class=\"cc-form__button cc-form__button--ripple\" aria-label=\"submit\" (click)=\"emitSavedCard()\"\r\n (keydown.enter)=\"emitSavedCard()\">Submit\r\n </button>\r\n </form>\r\n</section>\r\n", encapsulation: ViewEncapsulation.None, styles: ["@import url(https://fonts.googleapis.com/css?family=Inconsolata);.cc-form{align-items:center;display:flex;flex-flow:column;flex-wrap:wrap;height:100%;justify-content:center;width:100%}.cc-form--inline{align-items:inherit;display:inherit;flex-flow:row;flex-wrap:inherit;height:100%;justify-content:flex-end;margin-bottom:5%;width:100%}@media only screen and (max-width:1279px){.cc-form--inline{align-items:inherit;display:inherit;flex-flow:row;flex-wrap:inherit;height:100%;justify-content:flex-end;margin-bottom:5%;width:100%}}@media only screen and (max-width:599px){.cc-form--inline{align-items:center;display:inherit;flex-flow:column;flex-wrap:wrap;height:100%;justify-content:center;width:100%}}input[type=number]{-moz-appearance:textfield}input::-webkit-inner-spin-button,input::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}@media only screen and (max-width:1919px){.cc-form__wrapper{margin-right:5%;margin-top:5%}.cc-form__wrapper--long{width:60%}.cc-form__wrapper--short{width:15%}.cc-form__wrapper--last{margin-left:5%;margin-right:20%;margin-top:30px}}@media only screen and (max-width:1279px){.cc-form__wrapper{margin-right:5%;margin-top:5%}.cc-form__wrapper--long{width:60%}.cc-form__wrapper--short{width:15%}.cc-form__wrapper--last{margin-left:5%;margin-right:20%}}@media only screen and (max-width:599px){.cc-form__wrapper{margin-right:0;margin-top:0}.cc-form__wrapper--long,.cc-form__wrapper--short{width:80%}.cc-form__wrapper--last{margin-left:0;margin-right:0}}.cc-form__label{color:rgba(0,0,0,.6);display:block;font-family:Inconsolata,Serif,serif;font-size:.7em;font-weight:400;letter-spacing:1px;line-height:10px;margin-bottom:5px;margin-top:5%;text-align:left;text-shadow:none;text-transform:uppercase;width:100%}.cc-form__label--first{margin-top:20%}.cc-form__select{-webkit-appearance:listbox;-moz-appearance:listbox;appearance:listbox}.cc-form__input,.cc-form__select{border:1px solid rgba(0,0,0,.3);border-radius:5px;box-shadow:inset 0 1px 4px rgba(0,0,0,.2);color:#333;display:block;font-size:1.2em;height:38px;margin:0;outline:0;padding:0;text-align:left;width:100%}.cc-form__input--transparent{background:0 0;border:none;border-radius:0;box-shadow:none}.cc-form__input--embosed{color:#fff;font-family:Inconsolata,monospace;font-size:2vw;text-shadow:0 2px 1px rgba(0,0,0,.3)}@media only screen and (max-width:1279px){.cc-form__input--embosed{font-size:2.5vw}}@media only screen and (max-width:599px){.cc-form__input--embosed{font-size:3vw}}.cc-form__input--cursive{font-size:.7em;font-style:italic;left:0;margin:0 auto;position:absolute}.cc-form__input--right-align{padding-right:5%;text-align:right}.cc-form__input--left-align{text-align:left}.cc-form__input:focus,.cc-form__select:focus{border-color:#41acf4}.cc-form__error{color:#ff5b5f;font-size:.7em}.cc-form__button{background:#41acf4;border:0;border-radius:3px;color:#fff;cursor:pointer;margin-bottom:5%;margin-top:1%;outline:0;overflow:hidden;padding:1%;position:relative;text-align:center;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;vertical-align:middle;white-space:nowrap;width:60%}.cc-form__button:hover{box-shadow:0 6px 8px -3px rgba(0,0,0,.3)}.cc-form__button:focus{background:#0e91ea}.cc-form__button--ripple{overflow:hidden;position:relative}.cc-form__button--ripple:after{background:rgba(255,255,255,.3);border-radius:80%;content:'';display:block;height:120px;left:50%;margin-left:-50%;margin-top:-60px;position:absolute;top:50%;-webkit-transform:scale(0);transform:scale(0);width:100%}.cc-form__button--ripple:not(:active):after{-webkit-animation:2s ease-out button-ripple;animation:2s ease-out button-ripple}@-webkit-keyframes button-ripple{0%{-webkit-transform:scale(0);transform:scale(0)}20%{-webkit-transform:scale(1);transform:scale(1)}100%{opacity:0;-webkit-transform:scale(1);transform:scale(1)}}@keyframes button-ripple{0%{-webkit-transform:scale(0);transform:scale(0)}20%{-webkit-transform:scale(1);transform:scale(1)}100%{opacity:0;-webkit-transform:scale(1);transform:scale(1)}}.cc-wrapper{background-color:#fff;border-radius:20px;height:100%;margin:0;padding:0;width:100%}.cc-box{height:100px;margin:0 auto;padding:0;position:relative;-webkit-transform:translateY(-100%);transform:translateY(-100%);width:70%;z-index:1}@media only screen and (max-width:1279px){.cc-box{-webkit-transform:translateY(-115%);transform:translateY(-115%)}}@media only screen and (max-width:599px){.cc-box{-webkit-transform:translateY(-130%);transform:translateY(-130%)}}.cc-box--flip{-webkit-transform-style:preserve-3d;transform-style:preserve-3d;transition:.6s}.cc-box--flip.hover,.cc-box--flip:hover{-webkit-transform:rotateY(180deg);transform:rotateY(180deg)}.cc-box__element{padding:0;width:80%}.cc-box__logo{align-items:center;color:#fff;display:flex;flex-flow:row nowrap;font-size:1.2em;font-style:italic;font-weight:700;justify-content:flex-end;margin-right:10%;width:100%}.cc-box__strip{background:linear-gradient(135deg,#404040,#1a1a1a);font-size:1.7em;margin:0;padding:0;position:relative;-webkit-transform:translateY(-90%);transform:translateY(-90%);width:100%}.cc-box__back,.cc-box__front{align-items:center;-webkit-backface-visibility:hidden;backface-visibility:hidden;background:linear-gradient(135deg,#bd6772,#53223f);border-radius:15px;display:flex;flex-direction:column;flex-flow:column nowrap;height:250px;justify-content:center;left:0;position:absolute;top:0;width:100%}.cc-box__front{-webkit-transform:rotateY(0);transform:rotateY(0)}.cc-box__back{-webkit-transform:rotateY(180deg);transform:rotateY(180deg)}.ng-invalid.ng-touched{border-color:#ff5b5f}.ng-valid.ng-touched{border-color:#b2b2b2}"] }] } ]; /** @nocollapse */ PaymentCardComponent.ctorParameters = () => [ { type: PaymentCardService }, { type: FormBuilder } ]; PaymentCardComponent.propDecorators = { ccNumMissingTxt: [{ type: Input }], ccNumTooShortTxt: [{ type: Input }], ccNumTooLongTxt: [{ type: Input }], ccNumContainsLettersTxt: [{ type: Input }], ccNumChecksumInvalidTxt: [{ type: Input }], cardHolderMissingTxt: [{ type: Input }], cardHolderTooLongTxt: [{ type: Input }], expirationMonthMissingTxt: [{ type: Input }], expirationYearMissingTxt: [{ type: Input }], ccvMissingTxt: [{ type: Input }], ccvNumTooShortTxt: [{ type: Input }], ccvNumTooLongTxt: [{ type: Input }], ccvContainsLettersTxt: [{ type: Input }], cardExpiredTxt: [{ type: Input }], validateCCNum: [{ type: Input }], validateCardHolder: [{ type: Input }], validateExpirationMonth: [{ type: Input }], validateExpirationYear: [{ type: Input }], validateCardExpiration: [{ type: Input }], validateCCV: [{ type: Input }], formSaved: [{ type: Output }] }; if (false) { /** * FormGroup available publicly * @type {?} */ PaymentCardComponent.prototype.ccForm; /** * List of months * @type {?} */ PaymentCardComponent.prototype.months; /** * List of years * @type {?} */ PaymentCardComponent.prototype.years; /** * Validation message for missing payment card number * @type {?} */ PaymentCardComponent.prototype.ccNumMissingTxt; /** * Validation message for too short payment card number * @type {?} */ PaymentCardComponent.prototype.ccNumTooShortTxt; /** * Validation message for too long payment card number * @type {?} */ PaymentCardComponent.prototype.ccNumTooLongTxt; /** * Validation message for payment card number that contains characters other than digits * @type {?} */ PaymentCardComponent.prototype.ccNumContainsLettersTxt; /** * Validation message for invalid payment card number (Luhn's validation) * @type {?} */ PaymentCardComponent.prototype.ccNumChecksumInvalidTxt; /** * Validation message for missing card holder name * @type {?} */ PaymentCardComponent.prototype.cardHolderMissingTxt; /** * Validation message for too long card holder name * @type {?} */ PaymentCardComponent.prototype.cardHolderTooLongTxt; /** * Validation message for missing expiration month * @type {?} */ PaymentCardComponent.prototype.expirationMonthMissingTxt; /** * Validation message for missing expiration year * @type {?} */ PaymentCardComponent.prototype.expirationYearMissingTxt; /** * Validation message for missing CCV number * @type {?} */ PaymentCardComponent.prototype.ccvMissingTxt; /** * Validation message for too short CCV number * @type {?} */ PaymentCardComponent.prototype.ccvNumTooShortTxt; /** * Validation message for too long CCV number * @type {?} */ PaymentCardComponent.prototype.ccvNumTooLongTxt; /** * Validation message for incorrect CCV number containing characters other than digits * @type {?} */ PaymentCardComponent.prototype.ccvContainsLettersTxt; /** * Validation message for expired card * @type {?} */ PaymentCardComponent.prototype.cardExpiredTxt; /** * Switch validation of the payment card number * @type {?} */ PaymentCardComponent.prototype.validateCCNum; /** * Switch validation of the payment card holder * @type {?} */ PaymentCardComponent.prototype.validateCardHolder; /** * Switch validation of the payment card expiration month * @type {?} */ PaymentCardComponent.prototype.validateExpirationMonth; /** * Switch validation of the payment card expiration year * @type {?} */ PaymentCardComponent.prototype.validateExpirationYear; /** * Switch validation of the payment card expiration * @type {?} */ PaymentCardComponent.prototype.validateCardExpiration; /** * Switch validation of the payment card CCV number * @type {?} */ PaymentCardComponent.prototype.validateCCV; /** * EventEmitter for payment card object * @type {?} */ PaymentCardComponent.prototype.formSaved; /** @type {?} */ PaymentCardComponent.prototype._ccService; /** @type {?} */ PaymentCardComponent.prototype._fb; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGF5bWVudC1jYXJkLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiJuZzovL25nLXBheW1lbnQtY2FyZC8iLCJzb3VyY2VzIjpbImxpYi9wYXltZW50LWNhcmQuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7QUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLFlBQVksRUFBVSxNQUFNLEVBQUUsS0FBSyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ2xHLE9BQU8sRUFBRSxXQUFXLEVBQWEsVUFBVSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFcEUsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBRzNELE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLGdDQUFnQyxDQUFDOzs7O0FBV3BFLE1BQU0sT0FBTyxvQkFBb0I7Ozs7O0lBOEkvQixZQUFvQixVQUE4QixFQUFVLEdBQWdCO1FBQXhELGVBQVUsR0FBVixVQUFVLENBQW9CO1FBQVUsUUFBRyxHQUFILEdBQUcsQ0FBYTs7OztRQXJJckUsV0FBTSxHQUFrQixFQUFFLENBQUM7Ozs7UUFLM0IsVUFBSyxHQUFrQixFQUFFLENBQUM7Ozs7UUFNMUIsb0JBQWUsR0FBSSx5QkFBeUIsQ0FBQzs7OztRQU03QyxxQkFBZ0IsR0FBSSwwQkFBMEIsQ0FBQzs7OztRQU0vQyxvQkFBZSxHQUFJLHlCQUF5QixDQUFDOzs7O1FBTTdDLDRCQUF1QixHQUFJLHFDQUFxQyxDQUFDOzs7O1FBTWpFLDRCQUF1QixHQUFJLGlDQUFpQyxDQUFDOzs7O1FBTTdELHlCQUFvQixHQUFJLDhCQUE4QixDQUFDOzs7O1FBTXZELHlCQUFvQixHQUFJLDhCQUE4QixDQUFDOzs7O1FBTXZELDhCQUF5QixHQUFJLDhCQUE4QixDQUFDOzs7O1FBTTVELDZCQUF3QixHQUFJLDZCQUE2QixDQUFDOzs7O1FBTTFELGtCQUFhLEdBQUksd0JBQXdCLENBQUM7Ozs7UUFNMUMsc0JBQWlCLEdBQUkseUJBQXlCLENBQUM7Ozs7UUFNL0MscUJBQWdCLEdBQUksd0JBQXdCLENBQUM7Ozs7UUFNN0MsMEJBQXFCLEdBQUksb0NBQW9DLENBQUM7Ozs7UUFNOUQsbUJBQWMsR0FBSSxrQkFBa0IsQ0FBQzs7OztRQU1yQyxrQkFBYSxHQUFJLElBQUksQ0FBQzs7OztRQU10Qix1QkFBa0IsR0FBSSxJQUFJLENBQUM7Ozs7UUFNM0IsNEJBQXVCLEdBQUksSUFBSSxDQUFDOzs7O1FBTWhDLDJCQUFzQixHQUFJLElBQUksQ0FBQzs7OztRQU0vQiwyQkFBc0IsR0FBSSxJQUFJLENBQUM7Ozs7UUFNL0IsZ0JBQVcsR0FBSSxJQUFJLENBQUM7Ozs7UUFNcEIsY0FBUyxHQUErQixJQUFJLFlBQVksRUFBZSxDQUFDO0lBRUEsQ0FBQzs7OztJQUV6RSxRQUFRO1FBQ2IsSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDO1FBQ2pCLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO0lBQzFCLENBQUM7Ozs7O0lBS08sZ0JBQWdCO1FBQ3RCLElBQUksQ0FBQyxNQUFNLEdBQUcsa0JBQWtCLENBQUMsU0FBUyxFQUFFLENBQUM7UUFDN0MsSUFBSSxDQUFDLEtBQUssR0FBRyxrQkFBa0IsQ0FBQyxRQUFRLEVBQUUsQ0FBQztJQUM3QyxDQUFDOzs7OztJQUtPLFNBQVM7UUFDZixJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUMxQjtZQUNFLFVBQVUsRUFBRTtnQkFDVixFQUFFO2dCQUNGLFVBQVUsQ0FBQyxPQUFPLENBQUM7b0JBQ2pCLFVBQVUsQ0FBQyxRQUFRO29CQUNuQixVQUFVLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQztvQkFDeEIsVUFBVSxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUM7b0JBQ3hCLGFBQWEsQ0FBQyxXQUFXO29CQUN6QixhQUFhLENBQUMsUUFBUTtpQkFDdkIsQ0FBQzthQUNIO1lBQ0QsVUFBVSxFQUFFLENBQUMsRUFBRSxFQUFFLFVBQVUsQ0FBQyxPQUFPLENBQUMsQ0FBQyxVQUFVLENBQUMsUUFBUSxFQUFFLFVBQVUsQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ3JGLGVBQWUsRUFBRSxDQUFDLEVBQUUsRUFBRSxVQUFVLENBQUMsUUFBUSxDQUFDO1lBQzFDLGNBQWMsRUFBRSxDQUFDLEVBQUUsRUFBRSxVQUFVLENBQUMsUUFBUSxDQUFDO1lBQ3pDLEdBQUcsRUFBRTtnQkFDSCxFQUFFO2dCQUNGLFVBQVUsQ0FBQyxPQUFPLENBQUM7b0JBQ2pCLFVBQVUsQ0FBQyxRQUFRO29CQUNuQixVQUFVLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQztvQkFDdkIsVUFBVSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUM7b0JBQ3ZCLGFBQWEsQ0FBQyxXQUFXO2lCQUMxQixDQUFDO2FBQ0g7U0FDRixFQUNEO1lBQ0UsU0FBUyxFQUFFLGFBQWEsQ0FBQyxVQUFVO1NBQ3BDLENBQ0YsQ0FBQztJQUNKLENBQUM7Ozs7OztJQUtNLFdBQVcsQ0FBQyxLQUFhO1FBQzlCLE9BQU8sa0JBQWtCLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQy9DLENBQUM7Ozs7O0lBS00sYUFBYTs7Y0FDWixXQUFXLEdBQWlCLG1CQUFhLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxFQUFBO1FBQ2hFLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDO0lBQ25DLENBQUM7OztZQW5ORixTQUFTLFNBQUM7Z0JBQ1QsUUFBUSxFQUFFLGlCQUFpQjtnQkFDM0Isc3BQQUE0QztnQkFFNUMsYUFBYSxFQUFFLGlCQUFpQixDQUFDLElBQUk7O2FBQ3RDOzs7O1lBVlEsa0JBQWtCO1lBTGxCLFdBQVc7Ozs4QkFtQ2pCLEtBQUs7K0JBTUwsS0FBSzs4QkFNTCxLQUFLO3NDQU1MLEtBQUs7c0NBTUwsS0FBSzttQ0FNTCxLQUFLO21DQU1MLEtBQUs7d0NBTUwsS0FBSzt1Q0FNTCxLQUFLOzRCQU1MLEtBQUs7Z0NBTUwsS0FBSzsrQkFNTCxLQUFLO29DQU1MLEtBQUs7NkJBTUwsS0FBSzs0QkFNTCxLQUFLO2lDQU1MLEtBQUs7c0NBTUwsS0FBSztxQ0FNTCxLQUFLO3FDQU1MLEtBQUs7MEJBTUwsS0FBSzt3QkFNTCxNQUFNOzs7Ozs7O0lBdklQLHNDQUF5Qjs7Ozs7SUFLekIsc0NBQWtDOzs7OztJQUtsQyxxQ0FBaUM7Ozs7O0lBS2pDLCtDQUNvRDs7Ozs7SUFLcEQsZ0RBQ3NEOzs7OztJQUt0RCwrQ0FDb0Q7Ozs7O0lBS3BELHVEQUN3RTs7Ozs7SUFLeEUsdURBQ29FOzs7OztJQUtwRSxvREFDOEQ7Ozs7O0lBSzlELG9EQUM4RDs7Ozs7SUFLOUQseURBQ21FOzs7OztJQUtuRSx3REFDaUU7Ozs7O0lBS2pFLDZDQUNpRDs7Ozs7SUFLakQsaURBQ3NEOzs7OztJQUt0RCxnREFDb0Q7Ozs7O0lBS3BELHFEQUNxRTs7Ozs7SUFLckUsOENBQzRDOzs7OztJQUs1Qyw2Q0FDNkI7Ozs7O0lBSzdCLGtEQUNrQzs7Ozs7SUFLbEMsdURBQ3VDOzs7OztJQUt2QyxzREFDc0M7Ozs7O0lBS3RDLHNEQUNzQzs7Ozs7SUFLdEMsMkNBQzJCOzs7OztJQUszQix5Q0FDK0U7O0lBRW5FLDBDQUFzQzs7SUFBRSxtQ0FBd0IiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIEV2ZW50RW1pdHRlciwgT25Jbml0LCBPdXRwdXQsIElucHV0LCBWaWV3RW5jYXBzdWxhdGlvbiB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgRm9ybUJ1aWxkZXIsIEZvcm1Hcm91cCwgVmFsaWRhdG9ycyB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcblxuaW1wb3J0IHsgQ2FyZFZhbGlkYXRvciB9IGZyb20gJy4vdmFsaWRhdG9yL2NhcmQtdmFsaWRhdG9yJztcbmltcG9ydCB7IElDYXJkRGV0YWlscyB9IGZyb20gJy4vZG9tYWluL2ktY2FyZC1kZXRhaWxzJztcbmltcG9ydCB7IENhcmREZXRhaWxzIH0gZnJvbSAnLi9kb21haW4vY2FyZC1kZXRhaWxzJztcbmltcG9ydCB7IFBheW1lbnRDYXJkU2VydmljZSB9IGZyb20gJy4vc2VydmljZS9wYXltZW50LWNhcmQuc2VydmljZSc7XG5cbi8qKlxuICogTmdQYXltZW50Q2FyZCB3aXRob3V0IGFueSBkZXBlbmRlbmNpZXMgb3RoZXIgdGhlbiBSZWFjdGl2ZUZvcm1zTW9kdWxlXG4gKi9cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ25nLXBheW1lbnQtY2FyZCcsXG4gIHRlbXBsYXRlVXJsOiAnLi9wYXltZW50LWNhcmQuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi9wYXltZW50LWNhcmQuY29tcG9uZW50LnNjc3MnXSxcbiAgZW5jYXBzdWxhdGlvbjogVmlld0VuY2Fwc3VsYXRpb24uTm9uZSxcbn0pXG5leHBvcnQgY2xhc3MgUGF5bWVudENhcmRDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQge1xuICAvKipcbiAgICogRm9ybUdyb3VwIGF2YWlsYWJsZSBwdWJsaWNseVxuICAgKi9cbiAgcHVibGljIGNjRm9ybTogRm9ybUdyb3VwO1xuXG4gIC8qKlxuICAgKiBMaXN0IG9mIG1vbnRoc1xuICAgKi9cbiAgcHVibGljIG1vbnRoczogQXJyYXk8c3RyaW5nPiA9IFtdO1xuXG4gIC8qKlxuICAgKiBMaXN0IG9mIHllYXJzXG4gICAqL1xuICBwdWJsaWMgeWVhcnM6IEFycmF5PG51bWJlcj4gPSBbXTtcblxuICAvKipcbiAgICogVmFsaWRhdGlvbiBtZXNzYWdlIGZvciBtaXNzaW5nIHBheW1lbnQgY2FyZCBudW1iZXJcbiAgICovXG4gIEBJbnB1dCgpXG4gIHB1YmxpYyBjY051bU1pc3NpbmdUeHQ/ID0gJ0NhcmQgbnVtYmVyIGlzIHJlcXVpcmVkJztcblxuICAvKipcbiAgICogVmFsaWRhdGlvbiBtZXNzYWdlIGZvciB0b28gc2hvcnQgcGF5bWVudCBjYXJkIG51bWJlclxuICAgKi9cbiAgQElucHV0KClcbiAgcHVibGljIGNjTnVtVG9vU2hvcnRUeHQ/ID0gJ0NhcmQgbnVtYmVyIGlzIHRvbyBzaG9ydCc7XG5cbiAgLyoqXG4gICAqIFZhbGlkYXRpb24gbWVzc2FnZSBmb3IgdG9vIGxvbmcgcGF5bWVudCBjYXJkIG51bWJlclxuICAgKi9cbiAgQElucHV0KClcbiAgcHVibGljIGNjTnVtVG9vTG9uZ1R4dD8gPSAnQ2FyZCBudW1iZXIgaXMgdG9vIGxvbmcnO1xuXG4gIC8qKlxuICAgKiBWYWxpZGF0aW9uIG1lc3NhZ2UgZm9yIHBheW1lbnQgY2FyZCBudW1iZXIgdGhhdCBjb250YWlucyBjaGFyYWN0ZXJzIG90aGVyIHRoYW4gZGlnaXRzXG4gICAqL1xuICBASW5wdXQoKVxuICBwdWJsaWMgY2NOdW1Db250YWluc0xldHRlcnNUeHQ/ID0gJ0NhcmQgbnVtYmVyIGNhbiBjb250YWluIGRpZ2l0cyBvbmx5JztcblxuICAvKipcbiAgICogVmFsaWRhdGlvbiBtZXNzYWdlIGZvciBpbnZhbGlkIHBheW1lbnQgY2FyZCAgbnVtYmVyIChMdWhuJ3MgdmFsaWRhdGlvbilcbiAgICovXG4gIEBJbnB1dCgpXG4gIHB1YmxpYyBjY051bUNoZWNrc3VtSW52YWxpZFR4dD8gPSAnUHJvdmlkZWQgY2FyZCBudW1iZXIgaXMgaW52YWxpZCc7XG5cbiAgLyoqXG4gICAqIFZhbGlkYXRpb24gbWVzc2FnZSBmb3IgbWlzc2luZyBjYXJkIGhvbGRlciBuYW1lXG4gICAqL1xuICBASW5wdXQoKVxuICBwdWJsaWMgY2FyZEhvbGRlck1pc3NpbmdUeHQ/ID0gJ0NhcmQgaG9sZGVyIG5hbWUgaXMgcmVxdWlyZWQnO1xuXG4gIC8qKlxuICAgKiBWYWxpZGF0aW9uIG1lc3NhZ2UgZm9yIHRvbyBsb25nIGNhcmQgaG9sZGVyIG5hbWVcbiAgICovXG4gIEBJbnB1dCgpXG4gIHB1YmxpYyBjYXJkSG9sZGVyVG9vTG9uZ1R4dD8gPSAnQ2FyZCBob2xkZXIgbmFtZSBpcyB0b28gbG9uZyc7XG5cbiAgLyoqXG4gICAqIFZhbGlkYXRpb24gbWVzc2FnZSBmb3IgbWlzc2luZyBleHBpcmF0aW9uIG1vbnRoXG4gICAqL1xuICBASW5wdXQoKVxuICBwdWJsaWMgZXhwaXJhdGlvbk1vbnRoTWlzc2luZ1R4dD8gPSAnRXhwaXJhdGlvbiBtb250aCBpcyByZXF1aXJlZCc7XG5cbiAgLyoqXG4gICAqIFZhbGlkYXRpb24gbWVzc2FnZSBmb3IgbWlzc2luZyBleHBpcmF0aW9uIHllYXJcbiAgICovXG4gIEBJbnB1dCgpXG4gIHB1YmxpYyBleHBpcmF0aW9uWWVhck1pc3NpbmdUeHQ/ID0gJ0V4cGlyYXRpb24geWVhciBpcyByZXF1aXJlZCc7XG5cbiAgLyoqXG4gICAqIFZhbGlkYXRpb24gbWVzc2FnZSBmb3IgbWlzc2luZyBDQ1YgbnVtYmVyXG4gICAqL1xuICBASW5wdXQoKVxuICBwdWJsaWMgY2N2TWlzc2luZ1R4dD8gPSAnQ0NWIG51bWJlciBpcyByZXF1aXJlZCc7XG5cbiAgLyoqXG4gICAqIFZhbGlkYXRpb24gbWVzc2FnZSBmb3IgdG9vIHNob3J0IENDViBudW1iZXJcbiAgICovXG4gIEBJbnB1dCgpXG4gIHB1YmxpYyBjY3ZOdW1Ub29TaG9ydFR4dD8gPSAnQ0NWIG51bWJlciBpcyB0b28gc2hvcnQnO1xuXG4gIC8qKlxuICAgKiBWYWxpZGF0aW9uIG1lc3NhZ2UgZm9yIHRvbyBsb25nIENDViBudW1iZXJcbiAgICovXG4gIEBJbnB1dCgpXG4gIHB1YmxpYyBjY3ZOdW1Ub29Mb25nVHh0PyA9ICdDQ1YgbnVtYmVyIGlzIHRvbyBsb25nJztcblxuICAvKipcbiAgICogVmFsaWRhdGlvbiBtZXNzYWdlIGZvciBpbmNvcnJlY3QgQ0NWIG51bWJlciBjb250YWluaW5nIGNoYXJhY3RlcnMgb3RoZXIgdGhhbiBkaWdpdHNcbiAgICovXG4gIEBJbnB1dCgpXG4gIHB1YmxpYyBjY3ZDb250YWluc0xldHRlcnNUeHQ/ID0gJ0NDViBudW1iZXIgY2FuIGNvbnRhaW4gZGlnaXRzIG9ubHknO1xuXG4gIC8qKlxuICAgKiBWYWxpZGF0aW9uIG1lc3NhZ2UgZm9yIGV4cGlyZWQgY2FyZFxuICAgKi9cbiAgQElucHV0KClcbiAgcHVibGljIGNhcmRFeHBpcmVkVHh0PyA9ICdDYXJkIGhhcyBleHBpcmVkJztcblxuICAvKipcbiAgICogU3dpdGNoIHZhbGlkYXRpb24gb2YgdGhlIHBheW1lbnQgY2FyZCBudW1iZXJcbiAgICovXG4gIEBJbnB1dCgpXG4gIHB1YmxpYyB2YWxpZGF0ZUNDTnVtPyA9IHRydWU7XG5cbiAgLyoqXG4gICAqIFN3aXRjaCB2YWxpZGF0aW9uIG9mIHRoZSBwYXltZW50IGNhcmQgaG9sZGVyXG4gICAqL1xuICBASW5wdXQoKVxuICBwdWJsaWMgdmFsaWRhdGVDYXJkSG9sZGVyPyA9IHRydWU7XG5cbiAgLyoqXG4gICAqIFN3aXRjaCB2YWxpZGF0aW9uIG9mIHRoZSBwYXltZW50IGNhcmQgZXhwaXJhdGlvbiBtb250aFxuICAgKi9cbiAgQElucHV0KClcbiAgcHVibGljIHZhbGlkYXRlRXhwaXJhdGlvbk1vbnRoPyA9IHRydWU7XG5cbiAgLyoqXG4gICAqIFN3aXRjaCB2YWxpZGF0aW9uIG9mIHRoZSBwYXltZW50IGNhcmQgZXhwaXJhdGlvbiB5ZWFyXG4gICAqL1xuICBASW5wdXQoKVxuICBwdWJsaWMgdmFsaWRhdGVFeHBpcmF0aW9uWWVhcj8gPSB0cnVlO1xuXG4gIC8qKlxuICAgKiBTd2l0Y2ggdmFsaWRhdGlvbiBvZiB0aGUgcGF5bWVudCBjYXJkIGV4cGlyYXRpb25cbiAgICovXG4gIEBJbnB1dCgpXG4gIHB1YmxpYyB2YWxpZGF0ZUNhcmRFeHBpcmF0aW9uPyA9IHRydWU7XG5cbiAgLyoqXG4gICAqIFN3aXRjaCB2YWxpZGF0aW9uIG9mIHRoZSBwYXltZW50IGNhcmQgQ0NWIG51bWJlclxuICAgKi9cbiAgQElucHV0KClcbiAgcHVibGljIHZhbGlkYXRlQ0NWPyA9IHRydWU7XG5cbiAgLyoqXG4gICAqIEV2ZW50RW1pdHRlciBmb3IgcGF5bWVudCBjYXJkIG9iamVjdFxuICAgKi9cbiAgQE91dHB1dCgpXG4gIHB1YmxpYyBmb3JtU2F2ZWQ6IEV2ZW50RW1pdHRlcjxJQ2FyZERldGFpbHM+ID0gbmV3IEV2ZW50RW1pdHRlcjxDYXJkRGV0YWlscz4oKTtcblxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIF9jY1NlcnZpY2U6IFBheW1lbnRDYXJkU2VydmljZSwgcHJpdmF0ZSBfZmI6IEZvcm1CdWlsZGVyKSB7fVxuXG4gIHB1YmxpYyBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICB0aGlzLmJ1aWxkRm9ybSgpO1xuICAgIHRoaXMuYXNzaWduRGF0ZVZhbHVlcygpO1xuICB9XG5cbiAgLyoqXG4gICAqIFBvcHVsYXRlIG1vbnRocyBhbmQgeWVhcnNcbiAgICovXG4gIHByaXZhdGUgYXNzaWduRGF0ZVZhbHVlcygpOiB2b2lkIHtcbiAgICB0aGlzLm1vbnRocyA9IFBheW1lbnRDYXJkU2VydmljZS5nZXRNb250aHMoKTtcbiAgICB0aGlzLnllYXJzID0gUGF5bWVudENhcmRTZXJ2aWNlLmdldFllYXJzKCk7XG4gIH1cblxuICAvKipcbiAgICogQnVpbGQgcmVhY3RpdmUgZm9ybVxuICAgKi9cbiAgcHJpdmF0ZSBidWlsZEZvcm0oKTogdm9pZCB7XG4gICAgdGhpcy5jY0Zvcm0gPSB0aGlzLl9mYi5ncm91cChcbiAgICAgIHtcbiAgICAgICAgY2FyZE51bWJlcjogW1xuICAgICAgICAgICcnLFxuICAgICAgICAgIFZhbGlkYXRvcnMuY29tcG9zZShbXG4gICAgICAgICAgICBWYWxpZGF0b3JzLnJlcXVpcmVkLFxuICAgICAgICAgICAgVmFsaWRhdG9ycy5taW5MZW5ndGgoMTIpLFxuICAgICAgICAgICAgVmFsaWRhdG9ycy5tYXhMZW5ndGgoMTkpLFxuICAgICAgICAgICAgQ2FyZFZhbGlkYXRvci5udW1iZXJzT25seSxcbiAgICAgICAgICAgIENhcmRWYWxpZGF0b3IuY2hlY2tzdW0sXG4gICAgICAgICAgXSksXG4gICAgICAgIF0sXG4gICAgICAgIGNhcmRIb2xkZXI6IFsnJywgVmFsaWRhdG9ycy5jb21wb3NlKFtWYWxpZGF0b3JzLnJlcXVpcmVkLCBWYWxpZGF0b3JzLm1heExlbmd0aCgyMildKV0sXG4gICAgICAgIGV4cGlyYXRpb25Nb250aDogWycnLCBWYWxpZGF0b3JzLnJlcXVpcmVkXSxcbiAgICAgICAgZXhwaXJhdGlvblllYXI6IFsnJywgVmFsaWRhdG9ycy5yZXF1aXJlZF0sXG4gICAgICAgIGNjdjogW1xuICAgICAgICAgICcnLFxuICAgICAgICAgIFZhbGlkYXRvcnMuY29tcG9zZShbXG4gICAgICAgICAgICBWYWxpZGF0b3JzLnJlcXVpcmVkLFxuICAgICAgICAgICAgVmFsaWRhdG9ycy5taW5MZW5ndGgoMyksXG4gICAgICAgICAgICBWYWxpZGF0b3JzLm1heExlbmd0aCg0KSxcbiAgICAgICAgICAgIENhcmRWYWxpZGF0b3IubnVtYmVyc09ubHksXG4gICAgICAgICAgXSksXG4gICAgICAgIF0sXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICB2YWxpZGF0b3I6IENhcmRWYWxpZGF0b3IuZXhwaXJhdGlvbixcbiAgICAgIH1cbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgcGF5bWVudCBjYXJkIHR5cGUgYmFzZWQgb24gcGF5bWVudCBjYXJkIG51bWJlclxuICAgKi9cbiAgcHVibGljIGdldENhcmRUeXBlKGNjTnVtOiBzdHJpbmcpOiBzdHJpbmcgfCBudWxsIHtcbiAgICByZXR1cm4gUGF5bWVudENhcmRTZXJ2aWNlLmdldENhcmRUeXBlKGNjTnVtKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDYWxsYmFjayBmdW5jdGlvbiB0aGF0IGVtaXRzIHBheW1lbnQgY2FyZCBkZXRhaWxzIGFmdGVyIHVzZXIgY2xpY2tzIHN1Ym1pdCwgb3IgcHJlc3MgZW50ZXJcbiAgICovXG4gIHB1YmxpYyBlbWl0U2F2ZWRDYXJkKCk6IHZvaWQge1xuICAgIGNvbnN0IGNhcmREZXRhaWxzOiBJQ2FyZERldGFpbHMgPSA8Q2FyZERldGFpbHM+dGhpcy5jY0Zvcm0udmFsdWU7XG4gICAgdGhpcy5mb3JtU2F2ZWQuZW1pdChjYXJkRGV0YWlscyk7XG4gIH1cbn1cbiJdfQ==