UNPKG

@spartacus/storefront

Version:

Spartacus Storefront is a package that you can include in your application, which allows you to add default storefront features.

81 lines 22.9 kB
import { Component, ElementRef, ViewChild } from '@angular/core'; import { FormControl, FormGroup } from '@angular/forms'; import { PromotionLocation, } from '@spartacus/core'; import { filter, map, shareReplay, startWith, switchMap, switchMapTo, tap, } from 'rxjs/operators'; import { ICON_TYPE } from '../../../../cms-components/misc/icon/icon.model'; import * as i0 from "@angular/core"; import * as i1 from "../../../../shared/components/modal/modal.service"; import * as i2 from "@spartacus/core"; import * as i3 from "../../../misc/icon/icon.component"; import * as i4 from "../../cart-shared/cart-item/cart-item.component"; import * as i5 from "../../../misc/promotions/promotions.component"; import * as i6 from "../../../../shared/components/spinner/spinner.component"; import * as i7 from "@angular/common"; import * as i8 from "../../../../shared/components/modal/modal.directive"; import * as i9 from "@angular/router"; export class AddedToCartDialogComponent { constructor(modalService, cartService) { this.modalService = modalService; this.cartService = cartService; this.iconTypes = ICON_TYPE; this.promotionLocation = PromotionLocation.ActiveCart; this.quantity = 0; this.modalIsOpen = false; this.form = new FormGroup({}); } /** * Returns an observable formControl with the quantity of the cartEntry, * but also updates the entry in case of a changed value. * The quantity can be set to zero in order to remove the entry. */ getQuantityControl() { if (!this.quantityControl$) { this.quantityControl$ = this.entry$.pipe(filter((e) => !!e), map((entry) => this.getQuantityFormControl(entry)), switchMap(() => this.form.valueChanges.pipe( // eslint-disable-next-line import/no-deprecated startWith(null), tap((valueChange) => { if (valueChange) { this.cartService.updateEntry(valueChange.entryNumber, valueChange.quantity); if (valueChange.quantity === 0) { this.dismissModal('Removed'); } } else { this.form.markAsPristine(); } }))), map(() => this.form.get('quantity')), shareReplay({ bufferSize: 1, refCount: true })); } return this.quantityControl$; } ngOnInit() { this.addedEntryWasMerged$ = this.loaded$.pipe(filter((loaded) => loaded), switchMapTo(this.cartService.getEntries()), map((entries) => entries.length === this.numberOfEntriesBeforeAdd)); } /** * Adds quantity and entryNumber form controls to the FormGroup. * Returns quantity form control. */ getQuantityFormControl(entry) { if (!this.form.get('quantity')) { const quantity = new FormControl(entry.quantity, { updateOn: 'blur' }); this.form.addControl('quantity', quantity); const entryNumber = new FormControl(entry.entryNumber); this.form.addControl('entryNumber', entryNumber); } return this.form.get('quantity'); } dismissModal(reason) { this.modalService.dismissActiveModal(reason); } } AddedToCartDialogComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.0.5", ngImport: i0, type: AddedToCartDialogComponent, deps: [{ token: i1.ModalService }, { token: i2.ActiveCartService }], target: i0.ɵɵFactoryTarget.Component }); AddedToCartDialogComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.0.5", type: AddedToCartDialogComponent, selector: "cx-added-to-cart-dialog", viewQueries: [{ propertyName: "dialog", first: true, predicate: ["dialog"], descendants: true, read: ElementRef }], ngImport: i0, template: "<div #dialog>\n <!-- Modal Header -->\n <ng-container *ngIf=\"(loaded$ | async) || modalIsOpen; else loading\">\n <div class=\"cx-dialog-header modal-header\">\n <div\n class=\"cx-dialog-title modal-title\"\n aria-live=\"polite\"\n aria-atomic=\"true\"\n >\n {{\n (addedEntryWasMerged$ | async)\n ? ('addToCart.itemsIncrementedInYourCart' | cxTranslate)\n : ('addToCart.itemsAddedToYourCart' | cxTranslate)\n }}\n </div>\n <button\n type=\"button\"\n class=\"close\"\n attr.aria-label=\"{{ 'addToCart.closeModal' | cxTranslate }}\"\n cxModal=\"dismiss\"\n cxModalReason=\"Cross click\"\n >\n <span aria-hidden=\"true\">\n <cx-icon [type]=\"iconTypes.CLOSE\"></cx-icon>\n </span>\n </button>\n </div>\n <!-- Modal Body -->\n <div class=\"cx-dialog-body modal-body\" *ngIf=\"entry$ | async as entry\">\n <div class=\"cx-dialog-row\">\n <div class=\"cx-dialog-item col-sm-12 col-md-6\">\n <cx-cart-item\n [item]=\"entry\"\n [compact]=\"true\"\n [quantityControl]=\"getQuantityControl() | async\"\n [promotionLocation]=\"promotionLocation\"\n ></cx-cart-item>\n </div>\n <!-- Separator -->\n <div\n class=\"cx-dialog-separator col-sm-12 d-xs-block d-sm-block d-md-none\"\n ></div>\n <!-- Total container -->\n <div\n class=\"cx-dialog-actions col-sm-12 col-md-6\"\n *ngIf=\"cart$ | async as cart\"\n >\n <div class=\"cx-dialog-total\">\n <div>\n {{\n 'cartItems.cartTotal'\n | cxTranslate: { count: cart.deliveryItemsQuantity }\n }}\n </div>\n\n <div>{{ cart.subTotal?.formattedValue }}</div>\n </div>\n\n <!-- Promotions -->\n <div class=\"cx-dialog-promotions\">\n <cx-promotions\n [promotions]=\"\n (cart.appliedOrderPromotions || []).concat(\n cart.potentialOrderPromotions || []\n )\n \"\n ></cx-promotions>\n </div>\n\n <!-- Actions -->\n <div class=\"cx-dialog-buttons\">\n <a\n [class.disabled]=\"form.dirty\"\n [routerLink]=\"{ cxRoute: 'cart' } | cxUrl\"\n cxModal=\"dismiss\"\n cxModalReason=\"View Cart click\"\n class=\"btn btn-primary\"\n autofocus\n >{{ 'addToCart.viewCart' | cxTranslate }}</a\n >\n <a\n [class.disabled]=\"form.dirty\"\n [routerLink]=\"{ cxRoute: 'checkout' } | cxUrl\"\n cxModal=\"dismiss\"\n cxModalReason=\"Proceed To Checkout click\"\n class=\"btn btn-secondary\"\n >{{ 'addToCart.proceedToCheckout' | cxTranslate }}</a\n >\n </div>\n </div>\n </div>\n </div>\n </ng-container>\n\n <ng-template #loading>\n <div class=\"cx-dialog-header modal-header\">\n <div class=\"cx-dialog-title modal-title\">\n {{ 'addToCart.updatingCart' | cxTranslate }}\n </div>\n <button\n type=\"button\"\n class=\"close\"\n [attr.aria-label]=\"'common.close' | cxTranslate\"\n cxModal=\"dismiss\"\n cxModalReason=\"Cross click\"\n >\n <span aria-hidden=\"true\">\n <cx-icon [type]=\"iconTypes.CLOSE\"></cx-icon>\n </span>\n </button>\n </div>\n <!-- Modal Body -->\n <div class=\"cx-dialog-body modal-body\">\n <div class=\"cx-dialog-row\">\n <div class=\"col-sm-12\"><cx-spinner></cx-spinner></div>\n </div>\n </div>\n </ng-template>\n</div>\n", components: [{ type: i3.IconComponent, selector: "cx-icon,[cxIcon]", inputs: ["cxIcon", "type"] }, { type: i4.CartItemComponent, selector: "cx-cart-item", inputs: ["compact", "item", "readonly", "quantityControl", "promotionLocation", "options"] }, { type: i5.PromotionsComponent, selector: "cx-promotions", inputs: ["promotions"] }, { type: i6.SpinnerComponent, selector: "cx-spinner" }], directives: [{ type: i7.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i8.ModalDirective, selector: "[cxModal]", inputs: ["cxModal", "cxModalReason"] }, { type: i9.RouterLinkWithHref, selector: "a[routerLink],area[routerLink]", inputs: ["routerLink", "target", "queryParams", "fragment", "queryParamsHandling", "preserveFragment", "skipLocationChange", "replaceUrl", "state", "relativeTo"] }], pipes: { "async": i7.AsyncPipe, "cxTranslate": i2.TranslatePipe, "cxUrl": i2.UrlPipe } }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.0.5", ngImport: i0, type: AddedToCartDialogComponent, decorators: [{ type: Component, args: [{ selector: 'cx-added-to-cart-dialog', templateUrl: './added-to-cart-dialog.component.html', }] }], ctorParameters: function () { return [{ type: i1.ModalService }, { type: i2.ActiveCartService }]; }, propDecorators: { dialog: [{ type: ViewChild, args: ['dialog', { read: ElementRef }] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWRkZWQtdG8tY2FydC1kaWFsb2cuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvc3RvcmVmcm9udGxpYi9jbXMtY29tcG9uZW50cy9jYXJ0L2FkZC10by1jYXJ0L2FkZGVkLXRvLWNhcnQtZGlhbG9nL2FkZGVkLXRvLWNhcnQtZGlhbG9nLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3N0b3JlZnJvbnRsaWIvY21zLWNvbXBvbmVudHMvY2FydC9hZGQtdG8tY2FydC9hZGRlZC10by1jYXJ0LWRpYWxvZy9hZGRlZC10by1jYXJ0LWRpYWxvZy5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLFVBQVUsRUFBVSxTQUFTLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDekUsT0FBTyxFQUFFLFdBQVcsRUFBRSxTQUFTLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUN4RCxPQUFPLEVBSUwsaUJBQWlCLEdBQ2xCLE1BQU0saUJBQWlCLENBQUM7QUFFekIsT0FBTyxFQUNMLE1BQU0sRUFDTixHQUFHLEVBQ0gsV0FBVyxFQUNYLFNBQVMsRUFDVCxTQUFTLEVBQ1QsV0FBVyxFQUNYLEdBQUcsR0FDSixNQUFNLGdCQUFnQixDQUFDO0FBQ3hCLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxpREFBaUQsQ0FBQzs7Ozs7Ozs7Ozs7QUFPNUUsTUFBTSxPQUFPLDBCQUEwQjtJQW9CckMsWUFDWSxZQUEwQixFQUMxQixXQUE4QjtRQUQ5QixpQkFBWSxHQUFaLFlBQVksQ0FBYztRQUMxQixnQkFBVyxHQUFYLFdBQVcsQ0FBbUI7UUFyQjFDLGNBQVMsR0FBRyxTQUFTLENBQUM7UUFPdEIsc0JBQWlCLEdBQXNCLGlCQUFpQixDQUFDLFVBQVUsQ0FBQztRQUVwRSxhQUFRLEdBQUcsQ0FBQyxDQUFDO1FBQ2IsZ0JB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QTsyRkQ5RmEsMEJBQTBCO2tCQUp0QyxTQUFTO21CQUFDO29CQUNULFFBQVEsRUFBRSx5QkFBeUI7b0JBQ25DLFdBQVcsRUFBRSx1Q0FBdUM7aUJBQ3JEO21JQWVDLE1BQU07c0JBREwsU0FBUzt1QkFBQyxRQUFRLEVBQUUsRUFBRSxJQUFJLEVBQUUsVUFBVSxFQUFFIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBFbGVtZW50UmVmLCBPbkluaXQsIFZpZXdDaGlsZCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgRm9ybUNvbnRyb2wsIEZvcm1Hcm91cCB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7XG4gIEFjdGl2ZUNhcnRTZXJ2aWNlLFxuICBDYXJ0LFxuICBPcmRlckVudHJ5LFxuICBQcm9tb3Rpb25Mb2NhdGlvbixcbn0gZnJvbSAnQHNwYXJ0YWN1cy9jb3JlJztcbmltcG9ydCB7IE9ic2VydmFibGUgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7XG4gIGZpbHRlcixcbiAgbWFwLFxuICBzaGFyZVJlcGxheSxcbiAgc3RhcnRXaXRoLFxuICBzd2l0Y2hNYXAsXG4gIHN3aXRjaE1hcFRvLFxuICB0YXAsXG59IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7IElDT05fVFlQRSB9IGZyb20gJy4uLy4uLy4uLy4uL2Ntcy1jb21wb25lbnRzL21pc2MvaWNvbi9pY29uLm1vZGVsJztcbmltcG9ydCB7IE1vZGFsU2VydmljZSB9IGZyb20gJy4uLy4uLy4uLy4uL3NoYXJlZC9jb21wb25lbnRzL21vZGFsL21vZGFsLnNlcnZpY2UnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdjeC1hZGRlZC10by1jYXJ0LWRpYWxvZycsXG4gIHRlbXBsYXRlVXJsOiAnLi9hZGRlZC10by1jYXJ0LWRpYWxvZy5jb21wb25lbnQuaHRtbCcsXG59KVxuZXhwb3J0IGNsYXNzIEFkZGVkVG9DYXJ0RGlhbG9nQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0IHtcbiAgaWNvblR5cGVzID0gSUNPTl9UWVBFO1xuXG4gIGVudHJ5JDogT2JzZXJ2YWJsZTxPcmRlckVudHJ5PjtcbiAgY2FydCQ6IE9ic2VydmFibGU8Q2FydD47XG4gIGxvYWRlZCQ6IE9ic2VydmFibGU8Ym9vbGVhbj47XG4gIGFkZGVkRW50cnlXYXNNZXJnZWQkOiBPYnNlcnZhYmxlPGJvb2xlYW4+O1xuICBudW1iZXJPZkVudHJpZXNCZWZvcmVBZGQ6IG51bWJlcjtcbiAgcHJvbW90aW9uTG9jYXRpb246IFByb21vdGlvbkxvY2F0aW9uID0gUHJvbW90aW9uTG9jYXRpb24uQWN0aXZlQ2FydDtcblxuICBxdWFudGl0eSA9IDA7XG4gIG1vZGFsSXNPcGVuID0gZmFsc2U7XG5cbiAgQFZpZXdDaGlsZCgnZGlhbG9nJywgeyByZWFkOiBFbGVtZW50UmVmIH0pXG4gIGRpYWxvZzogRWxlbWVudFJlZjtcblxuICBmb3JtOiBGb3JtR3JvdXAgPSBuZXcgRm9ybUdyb3VwKHt9KTtcblxuICBwcm90ZWN0ZWQgcXVhbnRpdHlDb250cm9sJDogT2JzZXJ2YWJsZTxGb3JtQ29udHJvbD47XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJvdGVjdGVkIG1vZGFsU2VydmljZTogTW9kYWxTZXJ2aWNlLFxuICAgIHByb3RlY3RlZCBjYXJ0U2VydmljZTogQWN0aXZlQ2FydFNlcnZpY2VcbiAgKSB7fVxuICAvKipcbiAgICogUmV0dXJucyBhbiBvYnNlcnZhYmxlIGZvcm1Db250cm9sIHdpdGggdGhlIHF1YW50aXR5IG9mIHRoZSBjYXJ0RW50cnksXG4gICAqIGJ1dCBhbHNvIHVwZGF0ZXMgdGhlIGVudHJ5IGluIGNhc2Ugb2YgYSBjaGFuZ2VkIHZhbHVlLlxuICAgKiBUaGUgcXVhbnRpdHkgY2FuIGJlIHNldCB0byB6ZXJvIGluIG9yZGVyIHRvIHJlbW92ZSB0aGUgZW50cnkuXG4gICAqL1xuICBnZXRRdWFudGl0eUNvbnRyb2woKTogT2JzZXJ2YWJsZTxGb3JtQ29udHJvbD4ge1xuICAgIGlmICghdGhpcy5xdWFudGl0eUNvbnRyb2wkKSB7XG4gICAgICB0aGlzLnF1YW50aXR5Q29udHJvbCQgPSB0aGlzLmVudHJ5JC5waXBlKFxuICAgICAgICBmaWx0ZXIoKGUpID0+ICEhZSksXG4gICAgICAgIG1hcCgoZW50cnkpID0+IHRoaXMuZ2V0UXVhbnRpdHlGb3JtQ29udHJvbChlbnRyeSkpLFxuICAgICAgICBzd2l0Y2hNYXAoKCkgPT5cbiAgICAgICAgICB0aGlzLmZvcm0udmFsdWVDaGFuZ2VzLnBpcGUoXG4gICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgaW1wb3J0L25vLWRlcHJlY2F0ZWRcbiAgICAgICAgICAgIHN0YXJ0V2l0aChudWxsKSxcbiAgICAgICAgICAgIHRhcCgodmFsdWVDaGFuZ2UpID0+IHtcbiAgICAgICAgICAgICAgaWYgKHZhbHVlQ2hhbmdlKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5jYXJ0U2VydmljZS51cGRhdGVFbnRyeShcbiAgICAgICAgICAgICAgICAgIHZhbHVlQ2hhbmdlLmVudHJ5TnVtYmVyLFxuICAgICAgICAgICAgICAgICAgdmFsdWVDaGFuZ2UucXVhbnRpdHlcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIGlmICh2YWx1ZUNoYW5nZS5xdWFudGl0eSA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgdGhpcy5kaXNtaXNzTW9kYWwoJ1JlbW92ZWQnKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5mb3JtLm1hcmtBc1ByaXN0aW5lKCk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgKVxuICAgICAgICApLFxuICAgICAgICBtYXAoKCkgPT4gPEZvcm1Db250cm9sPnRoaXMuZm9ybS5nZXQoJ3F1YW50aXR5JykpLFxuICAgICAgICBzaGFyZVJlcGxheSh7IGJ1ZmZlclNpemU6IDEsIHJlZkNvdW50OiB0cnVlIH0pXG4gICAgICApO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5xdWFudGl0eUNvbnRyb2wkO1xuICB9XG5cbiAgbmdPbkluaXQoKSB7XG4gICAgdGhpcy5hZGRlZEVudHJ5V2FzTWVyZ2VkJCA9IHRoaXMubG9hZGVkJC5waXBlKFxuICAgICAgZmlsdGVyKChsb2FkZWQpID0+IGxvYWRlZCksXG4gICAgICBzd2l0Y2hNYXBUbyh0aGlzLmNhcnRTZXJ2aWNlLmdldEVudHJpZXMoKSksXG4gICAgICBtYXAoKGVudHJpZXMpID0+IGVudHJpZXMubGVuZ3RoID09PSB0aGlzLm51bWJlck9mRW50cmllc0JlZm9yZUFkZClcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZHMgcXVhbnRpdHkgYW5kIGVudHJ5TnVtYmVyIGZvcm0gY29udHJvbHMgdG8gdGhlIEZvcm1Hcm91cC5cbiAgICogUmV0dXJucyBxdWFudGl0eSBmb3JtIGNvbnRyb2wuXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0UXVhbnRpdHlGb3JtQ29udHJvbChlbnRyeTogT3JkZXJFbnRyeSk6IEZvcm1Db250cm9sIHtcbiAgICBpZiAoIXRoaXMuZm9ybS5nZXQoJ3F1YW50aXR5JykpIHtcbiAgICAgIGNvbnN0IHF1YW50aXR5ID0gbmV3IEZvcm1Db250cm9sKGVudHJ5LnF1YW50aXR5LCB7IHVwZGF0ZU9uOiAnYmx1cicgfSk7XG4gICAgICB0aGlzLmZvcm0uYWRkQ29udHJvbCgncXVhbnRpdHknLCBxdWFudGl0eSk7XG5cbiAgICAgIGNvbnN0IGVudHJ5TnVtYmVyID0gbmV3IEZvcm1Db250cm9sKGVudHJ5LmVudHJ5TnVtYmVyKTtcbiAgICAgIHRoaXMuZm9ybS5hZGRDb250cm9sKCdlbnRyeU51bWJlcicsIGVudHJ5TnVtYmVyKTtcbiAgICB9XG4gICAgcmV0dXJuIDxGb3JtQ29udHJvbD50aGlzLmZvcm0uZ2V0KCdxdWFudGl0eScpO1xuICB9XG5cbiAgZGlzbWlzc01vZGFsKHJlYXNvbj86IGFueSk6IHZvaWQge1xuICAgIHRoaXMubW9kYWxTZXJ2aWNlLmRpc21pc3NBY3RpdmVNb2RhbChyZWFzb24pO1xuICB9XG59XG4iLCI8ZGl2ICNkaWFsb2c+XG4gIDwhLS0gTW9kYWwgSGVhZGVyIC0tPlxuICA8bmctY29udGFpbmVyICpuZ0lmPVwiKGxvYWRlZCQgfCBhc3luYykgfHwgbW9kYWxJc09wZW47IGVsc2UgbG9hZGluZ1wiPlxuICAgIDxkaXYgY2xhc3M9XCJjeC1kaWFsb2ctaGVhZGVyIG1vZGFsLWhlYWRlclwiPlxuICAgICAgPGRpdlxuICAgICAgICBjbGFzcz1cImN4LWRpYWxvZy10aXRsZSBtb2RhbC10aXRsZVwiXG4gICAgICAgIGFyaWEtbGl2ZT1cInBvbGl0ZVwiXG4gICAgICAgIGFyaWEtYXRvbWljPVwidHJ1ZVwiXG4gICAgICA+XG4gICAgICAgIHt7XG4gICAgICAgICAgKGFkZGVkRW50cnlXYXNNZXJnZWQkIHwgYXN5bmMpXG4gICAgICAgICAgICA/ICgnYWRkVG9DYXJ0Lml0ZW1zSW5jcmVtZW50ZWRJbllvdXJDYXJ0JyB8IGN4VHJhbnNsYXRlKVxuICAgICAgICAgICAgOiAoJ2FkZFRvQ2FydC5pdGVtc0FkZGVkVG9Zb3VyQ2FydCcgfCBjeFRyYW5zbGF0ZSlcbiAgICAgICAgfX1cbiAgICAgIDwvZGl2PlxuICAgICAgPGJ1dHRvblxuICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgY2xhc3M9XCJjbG9zZVwiXG4gICAgICAgIGF0dHIuYXJpYS1sYWJlbD1cInt7ICdhZGRUb0NhcnQuY2xvc2VNb2RhbCcgfCBjeFRyYW5zbGF0ZSB9fVwiXG4gICAgICAgIGN4TW9kYWw9XCJkaXNtaXNzXCJcbiAgICAgICAgY3hNb2RhbFJlYXNvbj1cIkNyb3NzIGNsaWNrXCJcbiAgICAgID5cbiAgICAgICAgPHNwYW4gYXJpYS1oaWRkZW49XCJ0cnVlXCI+XG4gICAgICAgICAgPGN4LWljb24gW3R5cGVdPVwiaWNvblR5cGVzLkNMT1NFXCI+PC9jeC1pY29uPlxuICAgICAgICA8L3NwYW4+XG4gICAgICA8L2J1dHRvbj5cbiAgICA8L2Rpdj5cbiAgICA8IS0tIE1vZGFsIEJvZHkgLS0+XG4gICAgPGRpdiBjbGFzcz1cImN4LWRpYWxvZy1ib2R5IG1vZGFsLWJvZHlcIiAqbmdJZj1cImVudHJ5JCB8IGFzeW5jIGFzIGVudHJ5XCI+XG4gICAgICA8ZGl2IGNsYXNzPVwiY3gtZGlhbG9nLXJvd1wiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwiY3gtZGlhbG9nLWl0ZW0gY29sLXNtLTEyIGNvbC1tZC02XCI+XG4gICAgICAgICAgPGN4LWNhcnQtaXRlbVxuICAgICAgICAgICAgW2l0ZW1dPVwiZW50cnlcIlxuICAgICAgICAgICAgW2NvbXBhY3RdPVwidHJ1ZVwiXG4gICAgICAgICAgICBbcXVhbnRpdHlDb250cm9sXT1cImdldFF1YW50aXR5Q29udHJvbCgpIHwgYXN5bmNcIlxuICAgICAgICAgICAgW3Byb21vdGlvbkxvY2F0aW9uXT1cInByb21vdGlvbkxvY2F0aW9uXCJcbiAgICAgICAgICA+PC9jeC1jYXJ0LWl0ZW0+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8IS0tIFNlcGFyYXRvciAtLT5cbiAgICAgICAgPGRpdlxuICAgICAgICAgIGNsYXNzPVwiY3gtZGlhbG9nLXNlcGFyYXRvciBjb2wtc20tMTIgZC14cy1ibG9jayBkLXNtLWJsb2NrIGQtbWQtbm9uZVwiXG4gICAgICAgID48L2Rpdj5cbiAgICAgICAgPCEtLSBUb3RhbCBjb250YWluZXIgLS0+XG4gICAgICAgIDxkaXZcbiAgICAgICAgICBjbGFzcz1cImN4LWRpYWxvZy1hY3Rpb25zIGNvbC1zbS0xMiBjb2wtbWQtNlwiXG4gICAgICAgICAgKm5nSWY9XCJjYXJ0JCB8IGFzeW5jIGFzIGNhcnRcIlxuICAgICAgICA+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImN4LWRpYWxvZy10b3RhbFwiPlxuICAgICAgICAgICAgPGRpdj5cbiAgICAgICAgICAgICAge3tcbiAgICAgICAgICAgICAgICAnY2FydEl0ZW1zLmNhcnRUb3RhbCdcbiAgICAgICAgICAgICAgICAgIHwgY3hUcmFuc2xhdGU6IHsgY291bnQ6IGNhcnQuZGVsaXZlcnlJdGVtc1F1YW50aXR5IH1cbiAgICAgICAgICAgICAgfX1cbiAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICA8ZGl2Pnt7IGNhcnQuc3ViVG90YWw/LmZvcm1hdHRlZFZhbHVlIH19PC9kaXY+XG4gICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICA8IS0tIFByb21vdGlvbnMgLS0+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImN4LWRpYWxvZy1wcm9tb3Rpb25zXCI+XG4gICAgICAgICAgICA8Y3gtcHJvbW90aW9uc1xuICAgICAgICAgICAgICBbcHJvbW90aW9uc109XCJcbiAgICAgICAgICAgICAgICAoY2FydC5hcHBsaWVkT3JkZXJQcm9tb3Rpb25zIHx8IFtdKS5jb25jYXQoXG4gICAgICAgICAgICAgICAgICBjYXJ0LnBvdGVudGlhbE9yZGVyUHJvbW90aW9ucyB8fCBbXVxuICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgXCJcbiAgICAgICAgICAgID48L2N4LXByb21vdGlvbnM+XG4gICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICA8IS0tIEFjdGlvbnMgLS0+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImN4LWRpYWxvZy1idXR0b25zXCI+XG4gICAgICAgICAgICA8YVxuICAgICAgICAgICAgICBbY2xhc3MuZGlzYWJsZWRdPVwiZm9ybS5kaXJ0eVwiXG4gICAgICAgICAgICAgIFtyb3V0ZXJMaW5rXT1cInsgY3hSb3V0ZTogJ2NhcnQnIH0gfCBjeFVybFwiXG4gICAgICAgICAgICAgIGN4TW9kYWw9XCJkaXNtaXNzXCJcbiAgICAgICAgICAgICAgY3hNb2RhbFJlYXNvbj1cIlZpZXcgQ2FydCBjbGlja1wiXG4gICAgICAgICAgICAgIGNsYXNzPVwiYnRuIGJ0bi1wcmltYXJ5XCJcbiAgICAgICAgICAgICAgYXV0b2ZvY3VzXG4gICAgICAgICAgICAgID57eyAnYWRkVG9DYXJ0LnZpZXdDYXJ0JyB8IGN4VHJhbnNsYXRlIH19PC9hXG4gICAgICAgICAgICA+XG4gICAgICAgICAgICA8YVxuICAgICAgICAgICAgICBbY2xhc3MuZGlzYWJsZWRdPVwiZm9ybS5kaXJ0eVwiXG4gICAgICAgICAgICAgIFtyb3V0ZXJMaW5rXT1cInsgY3hSb3V0ZTogJ2NoZWNrb3V0JyB9IHwgY3hVcmxcIlxuICAgICAgICAgICAgICBjeE1vZGFsPVwiZGlzbWlzc1wiXG4gICAgICAgICAgICAgIGN4TW9kYWxSZWFzb249XCJQcm9jZWVkIFRvIENoZWNrb3V0IGNsaWNrXCJcbiAgICAgICAgICAgICAgY2xhc3M9XCJidG4gYnRuLXNlY29uZGFyeVwiXG4gICAgICAgICAgICAgID57eyAnYWRkVG9DYXJ0LnByb2NlZWRUb0NoZWNrb3V0JyB8IGN4VHJhbnNsYXRlIH19PC9hXG4gICAgICAgICAgICA+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG4gIDwvbmctY29udGFpbmVyPlxuXG4gIDxuZy10ZW1wbGF0ZSAjbG9hZGluZz5cbiAgICA8ZGl2IGNsYXNzPVwiY3gtZGlhbG9nLWhlYWRlciBtb2RhbC1oZWFkZXJcIj5cbiAgICAgIDxkaXYgY2xhc3M9XCJjeC1kaWFsb2ctdGl0bGUgbW9kYWwtdGl0bGVcIj5cbiAgICAgICAge3sgJ2FkZFRvQ2FydC51cGRhdGluZ0NhcnQnIHwgY3hUcmFuc2xhdGUgfX1cbiAgICAgIDwvZGl2PlxuICAgICAgPGJ1dHRvblxuICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgY2xhc3M9XCJjbG9zZVwiXG4gICAgICAgIFthdHRyLmFyaWEtbGFiZWxdPVwiJ2NvbW1vbi5jbG9zZScgfCBjeFRyYW5zbGF0ZVwiXG4gICAgICAgIGN4TW9kYWw9XCJkaXNtaXNzXCJcbiAgICAgICAgY3hNb2RhbFJlYXNvbj1cIkNyb3NzIGNsaWNrXCJcbiAgICAgID5cbiAgICAgICAgPHNwYW4gYXJpYS1oaWRkZW49XCJ0cnVlXCI+XG4gICAgICAgICAgPGN4LWljb24gW3R5cGVdPVwiaWNvblR5cGVzLkNMT1NFXCI+PC9jeC1pY29uPlxuICAgICAgICA8L3NwYW4+XG4gICAgICA8L2J1dHRvbj5cbiAgICA8L2Rpdj5cbiAgICA8IS0tIE1vZGFsIEJvZHkgLS0+XG4gICAgPGRpdiBjbGFzcz1cImN4LWRpYWxvZy1ib2R5IG1vZGFsLWJvZHlcIj5cbiAgICAgIDxkaXYgY2xhc3M9XCJjeC1kaWFsb2ctcm93XCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtc20tMTJcIj48Y3gtc3Bpbm5lcj48L2N4LXNwaW5uZXI+PC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgPC9uZy10ZW1wbGF0ZT5cbjwvZGl2PlxuIl19