ng-payment-card
Version:
Customizable component with zero external dependencies.
340 lines • 36.4 kB
JavaScript
/**
* @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\"> </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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGF5bWVudC1jYXJkLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiJuZzovL25nLXBheW1lbnQtY2FyZC8iLCJzb3VyY2VzIjpbImxpYi9wYXltZW50LWNhcmQuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7QUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLFlBQVksRUFBVSxNQUFNLEVBQUUsS0FBSyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ2xHLE9BQU8sRUFBRSxXQUFXLEVBQWEsVUFBVSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFcEUsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBRzNELE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLGdDQUFnQyxDQUFDOzs7O0FBV3BFLE1BQU0sT0FBTyxvQkFBb0I7Ozs7O0lBOEkvQixZQUFvQixVQUE4QixFQUFVLEdBQWdCO1FBQXhELGVBQVUsR0FBVixVQUFVLENBQW9CO1FBQVUsUUFBRyxHQUFILEdBQUcsQ0FBYTs7OztRQXJJckUsV0FBTSxHQUFrQixFQUFFLENBQUM7Ozs7UUFLM0IsVUFBSyxHQUFrQixFQUFFLENBQUM7Ozs7UUFNMUIsb0JBQWUsR0FBSSx5QkFBeUIsQ0FBQzs7OztRQU03QyxxQkFBZ0IsR0FBSSwwQkFBMEIsQ0FBQzs7OztRQU0vQyxvQkFBZSxHQUFJLHlCQUF5QixDQUFDOzs7O1FBTTdDLDRCQUF1QixHQUFJLHFDQUFxQyxDQUFDOzs7O1FBTWpFLDRCQUF1QixHQUFJLGlDQUFpQyxDQUFDOzs7O1FBTTdELHlCQUFvQixHQUFJLDhCQUE4QixDQUFDOzs7O1FBTXZELHlCQUFvQixHQUFJLDhCQUE4QixDQUFDOzs7O1FBTXZELDhCQUF5QixHQUFJLDhCQUE4QixDQUFDOzs7O1FBTTVELDZCQUF3QixHQUFJLDZCQUE2QixDQUFDOzs7O1FBTTFELGtCQUFhLEdBQUksd0JBQXdCLENBQUM7Ozs7UUFNMUMsc0JBQWlCLEdBQUks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QUs7NkJBTUwsS0FBSzs0QkFNTCxLQUFLO2lDQU1MLEtBQUs7c0NBTUwsS0FBSztxQ0FNTCxLQUFLO3FDQU1MLEtBQUs7MEJBTUwsS0FBSzt3QkFNTCxNQUFNOzs7Ozs7O0lBdklQLHNDQUF5Qjs7Ozs7SUFLekIsc0NBQWtDOzs7OztJQUtsQyxxQ0FBaUM7Ozs7O0lBS2pDLCtDQUNvRDs7Ozs7SUFLcEQsZ0RBQ3NEOzs7OztJQUt0RCwrQ0FDb0Q7Ozs7O0lBS3BELHVEQUN3RTs7Ozs7SUFLeEUsdURBQ29FOzs7OztJQUtwRSxvREFDOEQ7Ozs7O0lBSzlELG9EQUM4RDs7Ozs7SUFLOUQseURBQ21FOzs7OztJQUtuRSx3REFDaUU7Ozs7O0lBS2pFLDZDQUNpRDs7Ozs7SUFLakQsaURBQ3NEOzs7OztJQUt0RCxnREFDb0Q7Ozs7O0lBS3BELHFEQUNxRTs7Ozs7SUFLckUsOENBQzRDOzs7OztJQUs1Qyw2Q0FDNkI7Ozs7O0lBSzdCLGtEQUNrQzs7Ozs7SUFLbEMsdURBQ3VDOzs7OztJQUt2QyxzREFDc0M7Ozs7O0lBS3RDLHNEQUNzQzs7Ozs7SUFLdEMsMkNBQzJCOzs7OztJQUszQix5Q0FDK0U7O0lBRW5FLDBDQUFzQzs7SUFBRSxtQ0FBd0IiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIEV2ZW50RW1pdHRlciwgT25Jbml0LCBPdXRwdXQsIElucHV0LCBWaWV3RW5jYXBzdWxhdGlvbiB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgRm9ybUJ1aWxkZXIsIEZvcm1Hcm91cCwgVmFsaWRhdG9ycyB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcblxuaW1wb3J0IHsgQ2FyZFZhbGlkYXRvciB9IGZyb20gJy4vdmFsaWRhdG9yL2NhcmQtdmFsaWRhdG9yJztcbmltcG9ydCB7IElDYXJkRGV0YWlscyB9IGZyb20gJy4vZG9tYWluL2ktY2FyZC1kZXRhaWxzJztcbmltcG9ydCB7IENhcmREZXRhaWxzIH0gZnJvbSAnLi9kb21haW4vY2FyZC1kZXRhaWxzJztcbmltcG9ydCB7IFBheW1lbnRDYXJkU2VydmljZSB9IGZyb20gJy4vc2VydmljZS9wYXltZW50LWNhcmQuc2VydmljZSc7XG5cbi8qKlxuICogTmdQYXltZW50Q2FyZCB3aXRob3V0IGFueSBkZXBlbmRlbmNpZXMgb3RoZXIgdGhlbiBSZWFjdGl2ZUZvcm1zTW9kdWxlXG4gKi9cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ25nLXBheW1lbnQtY2FyZCcsXG4gIHRlbXBsYXRlVXJsOiAnLi9wYXltZW50LWNhcmQuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi9wYXltZW50LWNhcmQuY29tcG9uZW50LnNjc3MnXSxcbiAgZW5jYXBzdWxhdGlvbjogVmlld0VuY2Fwc3VsYXRpb24uTm9uZSxcbn0pXG5leHBvcnQgY2xhc3MgUGF5bWVudENhcmRDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQge1xuICAvKipcbiAgICogRm9ybUdyb3VwIGF2YWlsYWJsZSBwdWJsaWNseVxuICAgKi9cbiAgcHVibGljIGNjRm9ybTogRm9ybUdyb3VwO1xuXG4gIC8qKlxuICAgKiBMaXN0IG9mIG1vbnRoc1xuICAgKi9cbiAgcHVibGljIG1vbnRoczogQXJyYXk8c3RyaW5nPiA9IFtdO1xuXG4gIC8qKlxuICAgKiBMaXN0IG9mIHllYXJzXG4gICAqL1xuICBwdWJsaWMgeWVhcnM6IEFycmF5PG51bWJlcj4gPSBbXTtcblxuICAvKipcbiAgICogVmFsaWRhdGlvbiBtZXNzYWdlIGZvciBtaXNzaW5nIHBheW1lbnQgY2FyZCBudW1iZXJcbiAgICovXG4gIEBJbnB1dCgpXG4gIHB1YmxpYyBjY051bU1pc3NpbmdUeHQ/ID0gJ0NhcmQgbnVtYmVyIGlzIHJlcXVpcmVkJztcblxuICAvKipcbiAgICogVmFsaWRhdGlvbiBtZXNzYWdlIGZvciB0b28gc2hvcnQgcGF5bWVudCBjYXJkIG51bWJlclxuICAgKi9cbiAgQElucHV0KClcbiAgcHVibGljIGNjTnVtVG9vU2hvcnRUeHQ/ID0gJ0NhcmQgbnVtYmVyIGlzIHRvbyBzaG9ydCc7XG5cbiAgLyoqXG4gICAqIFZhbGlkYXRpb24gbWVzc2FnZSBmb3IgdG9vIGxvbmcgcGF5bWVudCBjYXJkIG51bWJlclxuICAgKi9cbiAgQElucHV0KClcbiAgcHVibGljIGNjTnVtVG9vTG9uZ1R4dD8gPSAnQ2FyZCBudW1iZXIgaXMgdG9vIGxvbmcnO1xuXG4gIC8qKlxuICAgKiBWYWxpZGF0aW9uIG1lc3NhZ2UgZm9yIHBheW1lbnQgY2FyZCBudW1iZXIgdGhhdCBjb250YWlucyBjaGFyYWN0ZXJzIG90aGVyIHRoYW4gZGlnaXRzXG4gICAqL1xuICBASW5wdXQoKVxuICBwdWJsaWMgY2NOdW1Db250YWluc0xldHRlcnNUeHQ/ID0gJ0NhcmQgbnVtYmVyIGNhbiBjb250YWluIGRpZ2l0cyBvbmx5JztcblxuICAvKipcbiAgICogVmFsaWRhdGlvbiBtZXNzYWdlIGZvciBpbnZhbGlkIHBheW1lbnQgY2FyZCAgbnVtYmVyIChMdWhuJ3MgdmFsaWRhdGlvbilcbiAgICovXG4gIEBJbnB1dCgpXG4gIHB1YmxpYyBjY051bUNoZWNrc3VtSW52YWxpZFR4dD8gPSAnUHJvdmlkZWQgY2FyZCBudW1iZXIgaXMgaW52YWxpZCc7XG5cbiAgLyoqXG4gICAqIFZhbGlkYXRpb24gbWVzc2FnZSBmb3IgbWlzc2luZyBjYXJkIGhvbGRlciBuYW1lXG4gICAqL1xuICBASW5wdXQoKVxuICBwdWJsaWMgY2FyZEhvbGRlck1pc3NpbmdUeHQ/ID0gJ0NhcmQgaG9sZGVyIG5hbWUgaXMgcmVxdWlyZWQnO1xuXG4gIC8qKlxuICAgKiBWYWxpZGF0aW9uIG1lc3NhZ2UgZm9yIHRvbyBsb25nIGNhcmQgaG9sZGVyIG5hbWVcbiAgICovXG4gIEBJbnB1dCgpXG4gIHB1YmxpYyBjYXJkSG9sZGVyVG9vTG9uZ1R4dD8gPSAnQ2FyZCBob2xkZXIgbmFtZSBpcyB0b28gbG9uZyc7XG5cbiAgLyoqXG4gICAqIFZhbGlkYXRpb24gbWVzc2FnZSBmb3IgbWlzc2luZyBleHBpcmF0aW9uIG1vbnRoXG4gICAqL1xuICBASW5wdXQoKVxuICBwdWJsaWMgZXhwaXJhdGlvbk1vbnRoTWlzc2luZ1R4dD8gPSAnRXhwaXJhdGlvbiBtb250aCBpcyByZXF1aXJlZCc7XG5cbiAgLyoqXG4gICAqIFZhbGlkYXRpb24gbWVzc2FnZSBmb3IgbWlzc2luZyBleHBpcmF0aW9uIHllYXJcbiAgICovXG4gIEBJbnB1dCgpXG4gIHB1YmxpYyBleHBpcmF0aW9uWWVhck1pc3NpbmdUeHQ/ID0gJ0V4cGlyYXRpb24geWVhciBpcyByZXF1aXJlZCc7XG5cbiAgLyoqXG4gICAqIFZhbGlkYXRpb24gbWVzc2FnZSBmb3IgbWlzc2luZyBDQ1YgbnVtYmVyXG4gICAqL1xuICBASW5wdXQoKVxuICBwdWJsaWMgY2N2TWlzc2luZ1R4dD8gPSAnQ0NWIG51bWJlciBpcyByZXF1aXJlZCc7XG5cbiAgLyoqXG4gICAqIFZhbGlkYXRpb24gbWVzc2FnZSBmb3IgdG9vIHNob3J0IENDViBudW1iZXJcbiAgICovXG4gIEBJbnB1dCgpXG4gIHB1YmxpYyBjY3ZOdW1Ub29TaG9ydFR4dD8gPSAnQ0NWIG51bWJlciBpcyB0b28gc2hvcnQnO1xuXG4gIC8qKlxuICAgKiBWYWxpZGF0aW9uIG1lc3NhZ2UgZm9yIHRvbyBsb25nIENDViBudW1iZXJcbiAgICovXG4gIEBJbnB1dCgpXG4gIHB1YmxpYyBjY3ZOdW1Ub29Mb25nVHh0PyA9ICdDQ1YgbnVtYmVyIGlzIHRvbyBsb25nJztcblxuICAvKipcbiAgICogVmFsaWRhdGlvbiBtZXNzYWdlIGZvciBpbmNvcnJlY3QgQ0NWIG51bWJlciBjb250YWluaW5nIGNoYXJhY3RlcnMgb3RoZXIgdGhhbiBkaWdpdHNcbiAgICovXG4gIEBJbnB1dCgpXG4gIHB1YmxpYyBjY3ZDb250YWluc0xldHRlcnNUeHQ/ID0gJ0NDViBudW1iZXIgY2FuIGNvbnRhaW4gZGlnaXRzIG9ubHknO1xuXG4gIC8qKlxuICAgKiBWYWxpZGF0aW9uIG1lc3NhZ2UgZm9yIGV4cGlyZWQgY2FyZFxuICAgKi9cbiAgQElucHV0KClcbiAgcHVibGljIGNhcmRFeHBpcmVkVHh0PyA9ICdDYXJkIGhhcyBleHBpcmVkJztcblxuICAvKipcbiAgICogU3dpdGNoIHZhbGlkYXRpb24gb2YgdGhlIHBheW1lbnQgY2FyZCBudW1iZXJcbiAgICovXG4gIEBJbnB1dCgpXG4gIHB1YmxpYyB2YWxpZGF0ZUNDTnVtPyA9IHRydWU7XG5cbiAgLyoqXG4gICAqIFN3aXRjaCB2YWxpZGF0aW9uIG9mIHRoZSBwYXltZW50IGNhcmQgaG9sZGVyXG4gICAqL1xuICBASW5wdXQoKVxuICBwdWJsaWMgdmFsaWRhdGVDYXJkSG9sZGVyPyA9IHRydWU7XG5cbiAgLyoqXG4gICAqIFN3aXRjaCB2YWxpZGF0aW9uIG9mIHRoZSBwYXltZW50IGNhcmQgZXhwaXJhdGlvbiBtb250aFxuICAgKi9cbiAgQElucHV0KClcbiAgcHVibGljIHZhbGlkYXRlRXhwaXJhdGlvbk1vbnRoPyA9IHRydWU7XG5cbiAgLyoqXG4gICAqIFN3aXRjaCB2YWxpZGF0aW9uIG9mIHRoZSBwYXltZW50IGNhcmQgZXhwaXJhdGlvbiB5ZWFyXG4gICAqL1xuICBASW5wdXQoKVxuICBwdWJsaWMgdmFsaWRhdGVFeHBpcmF0aW9uWWVhcj8gPSB0cnVlO1xuXG4gIC8qKlxuICAgKiBTd2l0Y2ggdmFsaWRhdGlvbiBvZiB0aGUgcGF5bWVudCBjYXJkIGV4cGlyYXRpb25cbiAgICovXG4gIEBJbnB1dCgpXG4gIHB1YmxpYyB2YWxpZGF0ZUNhcmRFeHBpcmF0aW9uPyA9IHRydWU7XG5cbiAgLyoqXG4gICAqIFN3aXRjaCB2YWxpZGF0aW9uIG9mIHRoZSBwYXltZW50IGNhcmQgQ0NWIG51bWJlclxuICAgKi9cbiAgQElucHV0KClcbiAgcHVibGljIHZhbGlkYXRlQ0NWPyA9IHRydWU7XG5cbiAgLyoqXG4gICAqIEV2ZW50RW1pdHRlciBmb3IgcGF5bWVudCBjYXJkIG9iamVjdFxuICAgKi9cbiAgQE91dHB1dCgpXG4gIHB1YmxpYyBmb3JtU2F2ZWQ6IEV2ZW50RW1pdHRlcjxJQ2FyZERldGFpbHM+ID0gbmV3IEV2ZW50RW1pdHRlcjxDYXJkRGV0YWlscz4oKTtcblxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIF9jY1NlcnZpY2U6IFBheW1lbnRDYXJkU2VydmljZSwgcHJpdmF0ZSBfZmI6IEZvcm1CdWlsZGVyKSB7fVxuXG4gIHB1YmxpYyBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICB0aGlzLmJ1aWxkRm9ybSgpO1xuICAgIHRoaXMuYXNzaWduRGF0ZVZhbHVlcygpO1xuICB9XG5cbiAgLyoqXG4gICAqIFBvcHVsYXRlIG1vbnRocyBhbmQgeWVhcnNcbiAgICovXG4gIHByaXZhdGUgYXNzaWduRGF0ZVZhbHVlcygpOiB2b2lkIHtcbiAgICB0aGlzLm1vbnRocyA9IFBheW1lbnRDYXJkU2VydmljZS5nZXRNb250aHMoKTtcbiAgICB0aGlzLnllYXJzID0gUGF5bWVudENhcmRTZXJ2aWNlLmdldFllYXJzKCk7XG4gIH1cblxuICAvKipcbiAgICogQnVpbGQgcmVhY3RpdmUgZm9ybVxuICAgKi9cbiAgcHJpdmF0ZSBidWlsZEZvcm0oKTogdm9pZCB7XG4gICAgdGhpcy5jY0Zvcm0gPSB0aGlzLl9mYi5ncm91cChcbiAgICAgIHtcbiAgICAgICAgY2FyZE51bWJlcjogW1xuICAgICAgICAgICcnLFxuICAgICAgICAgIFZhbGlkYXRvcnMuY29tcG9zZShbXG4gICAgICAgICAgICBWYWxpZGF0b3JzLnJlcXVpcmVkLFxuICAgICAgICAgICAgVmFsaWRhdG9ycy5taW5MZW5ndGgoMTIpLFxuICAgICAgICAgICAgVmFsaWRhdG9ycy5tYXhMZW5ndGgoMTkpLFxuICAgICAgICAgICAgQ2FyZFZhbGlkYXRvci5udW1iZXJzT25seSxcbiAgICAgICAgICAgIENhcmRWYWxpZGF0b3IuY2hlY2tzdW0sXG4gICAgICAgICAgXSksXG4gICAgICAgIF0sXG4gICAgICAgIGNhcmRIb2xkZXI6IFsnJywgVmFsaWRhdG9ycy5jb21wb3NlKFtWYWxpZGF0b3JzLnJlcXVpcmVkLCBWYWxpZGF0b3JzLm1heExlbmd0aCgyMildKV0sXG4gICAgICAgIGV4cGlyYXRpb25Nb250aDogWycnLCBWYWxpZGF0b3JzLnJlcXVpcmVkXSxcbiAgICAgICAgZXhwaXJhdGlvblllYXI6IFsnJywgVmFsaWRhdG9ycy5yZXF1aXJlZF0sXG4gICAgICAgIGNjdjogW1xuICAgICAgICAgICcnLFxuICAgICAgICAgIFZhbGlkYXRvcnMuY29tcG9zZShbXG4gICAgICAgICAgICBWYWxpZGF0b3JzLnJlcXVpcmVkLFxuICAgICAgICAgICAgVmFsaWRhdG9ycy5taW5MZW5ndGgoMyksXG4gICAgICAgICAgICBWYWxpZGF0b3JzLm1heExlbmd0aCg0KSxcbiAgICAgICAgICAgIENhcmRWYWxpZGF0b3IubnVtYmVyc09ubHksXG4gICAgICAgICAgXSksXG4gICAgICAgIF0sXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICB2YWxpZGF0b3I6IENhcmRWYWxpZGF0b3IuZXhwaXJhdGlvbixcbiAgICAgIH1cbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgcGF5bWVudCBjYXJkIHR5cGUgYmFzZWQgb24gcGF5bWVudCBjYXJkIG51bWJlclxuICAgKi9cbiAgcHVibGljIGdldENhcmRUeXBlKGNjTnVtOiBzdHJpbmcpOiBzdHJpbmcgfCBudWxsIHtcbiAgICByZXR1cm4gUGF5bWVudENhcmRTZXJ2aWNlLmdldENhcmRUeXBlKGNjTnVtKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDYWxsYmFjayBmdW5jdGlvbiB0aGF0IGVtaXRzIHBheW1lbnQgY2FyZCBkZXRhaWxzIGFmdGVyIHVzZXIgY2xpY2tzIHN1Ym1pdCwgb3IgcHJlc3MgZW50ZXJcbiAgICovXG4gIHB1YmxpYyBlbWl0U2F2ZWRDYXJkKCk6IHZvaWQge1xuICAgIGNvbnN0IGNhcmREZXRhaWxzOiBJQ2FyZERldGFpbHMgPSA8Q2FyZERldGFpbHM+dGhpcy5jY0Zvcm0udmFsdWU7XG4gICAgdGhpcy5mb3JtU2F2ZWQuZW1pdChjYXJkRGV0YWlscyk7XG4gIH1cbn1cbiJdfQ==