UNPKG

@spartacus/storefront

Version:

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

91 lines 27.3 kB
import { Component, Input } from '@angular/core'; import { PromotionLocation } from '@spartacus/core'; import { ICON_TYPE } from '../../../misc/icon/icon.model'; import { CartOutlets } from '../../cart-outlets.model'; import { CartItemContextSource } from './model/cart-item-context-source.model'; import { CartItemContext } from './model/cart-item-context.model'; import * as i0 from "@angular/core"; import * as i1 from "./model/cart-item-context-source.model"; import * as i2 from "../../validation/cart-item-warning/cart-item-validation-warning.component"; import * as i3 from "../../../../shared/components/media/media.component"; import * as i4 from "../../../../shared/components/item-counter/item-counter.component"; import * as i5 from "../../../misc/promotions/promotions.component"; import * as i6 from "../../../../cms-structure/outlet/outlet.directive"; import * as i7 from "@spartacus/core"; import * as i8 from "@angular/common"; import * as i9 from "@angular/router"; import * as i10 from "../../../../shared/components/modal/modal.directive"; export class CartItemComponent { constructor(cartItemContextSource) { this.cartItemContextSource = cartItemContextSource; this.compact = false; this.readonly = false; this.promotionLocation = PromotionLocation.ActiveCart; // TODO: evaluate whether this is generic enough this.options = { isSaveForLater: false, optionalBtn: null, }; this.iconTypes = ICON_TYPE; this.CartOutlets = CartOutlets; } ngOnChanges(changes) { if (changes === null || changes === void 0 ? void 0 : changes.compact) { this.cartItemContextSource.compact$.next(this.compact); } if (changes === null || changes === void 0 ? void 0 : changes.readonly) { this.cartItemContextSource.readonly$.next(this.readonly); } if (changes === null || changes === void 0 ? void 0 : changes.item) { this.cartItemContextSource.item$.next(this.item); } if (changes === null || changes === void 0 ? void 0 : changes.quantityControl) { this.cartItemContextSource.quantityControl$.next(this.quantityControl); } if (changes === null || changes === void 0 ? void 0 : changes.promotionLocation) { this.cartItemContextSource.location$.next(this.promotionLocation); } if (changes === null || changes === void 0 ? void 0 : changes.options) { this.cartItemContextSource.options$.next(this.options); } } isProductOutOfStock(product) { // TODO Move stocklevelstatuses across the app to an enum return (product && product.stock && product.stock.stockLevelStatus === 'outOfStock'); } removeItem() { this.quantityControl.setValue(0); this.quantityControl.markAsDirty(); } } CartItemComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.0.5", ngImport: i0, type: CartItemComponent, deps: [{ token: i1.CartItemContextSource }], target: i0.ɵɵFactoryTarget.Component }); CartItemComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.0.5", type: CartItemComponent, selector: "cx-cart-item", inputs: { compact: "compact", item: "item", readonly: "readonly", quantityControl: "quantityControl", promotionLocation: "promotionLocation", options: "options" }, providers: [ CartItemContextSource, { provide: CartItemContext, useExisting: CartItemContextSource }, ], usesOnChanges: true, ngImport: i0, template: "<!-- Item Start Outlet -->\n<ng-template [cxOutlet]=\"CartOutlets.ITEM\">\n <ng-container *cxFeatureLevel=\"'4.2'\">\n <cx-cart-item-validation-warning\n [code]=\"item.product.code\"\n ></cx-cart-item-validation-warning>\n </ng-container>\n <div [ngClass]=\"compact ? 'cx-compact row' : 'row'\">\n <!-- Item Image -->\n <div class=\"col-2 cx-image-container\">\n <a\n [routerLink]=\"{ cxRoute: 'product', params: item.product } | cxUrl\"\n cxModal=\"dismiss\"\n tabindex=\"-1\"\n >\n <cx-media\n [container]=\"item.product.images?.PRIMARY\"\n format=\"cartIcon\"\n ></cx-media>\n </a>\n </div>\n <!-- Item Information -->\n <div class=\"cx-info col-10\">\n <div class=\"cx-info-container row\">\n <!-- Item Description -->\n <div [ngClass]=\"compact ? '' : ' col-md-3 col-lg-3 col-xl-5'\">\n <div *ngIf=\"item.product.name\" class=\"cx-name\">\n <a\n class=\"cx-link\"\n [routerLink]=\"\n { cxRoute: 'product', params: item.product } | cxUrl\n \"\n cxModal=\"dismiss\"\n ><h2>{{ item.product.name }}</h2></a\n >\n </div>\n <div *ngIf=\"item.product.code\" class=\"cx-code\">\n {{ 'cartItems.id' | cxTranslate }} {{ item.product.code }}\n </div>\n\n <!-- Item Details Outlet -->\n <ng-template [cxOutlet]=\"CartOutlets.ITEM_DETAILS\"> </ng-template>\n\n <!-- Variants -->\n <ng-container *ngIf=\"item.product.baseOptions?.length\">\n <div\n *ngFor=\"\n let variant of item.product.baseOptions[0]?.selected\n ?.variantOptionQualifiers\n \"\n class=\"cx-property\"\n >\n <div class=\"cx-label\" *ngIf=\"variant.name && variant.value\">\n {{ variant.name }}: {{ variant.value }}\n </div>\n </div>\n </ng-container>\n </div>\n <!-- Item Price -->\n <div\n *ngIf=\"item.basePrice\"\n class=\"cx-price\"\n [ngClass]=\"compact ? '' : ' col-md-3 col-lg-3 col-xl-2'\"\n >\n <div\n class=\"cx-label\"\n [ngClass]=\"compact ? '' : ' d-block d-md-none d-lg-none d-xl-none'\"\n >\n {{ 'cartItems.itemPrice' | cxTranslate }}\n </div>\n <div *ngIf=\"item.basePrice\" class=\"cx-value\">\n {{ item.basePrice?.formattedValue }}\n </div>\n </div>\n <!-- Item Quantity -->\n <div class=\"cx-quantity\" [ngClass]=\"compact ? '' : ' col-3'\">\n <div\n class=\"cx-label\"\n [ngClass]=\"compact ? '' : ' d-block d-md-none d-lg-none d-xl-none'\"\n placement=\"left\"\n title=\"{{ 'cartItems.quantityTitle' | cxTranslate }}\"\n >\n {{ 'cartItems.quantity' | cxTranslate }}\n </div>\n <div class=\"cx-value\" [class.readonly-value]=\"readonly\">\n <cx-item-counter\n [control]=\"quantityControl\"\n [readonly]=\"\n !item.updateable || readonly || options.isSaveForLater\n \"\n [max]=\"item.product.stock?.stockLevel\"\n [allowZero]=\"true\"\n >\n </cx-item-counter>\n </div>\n </div>\n <!-- Total -->\n <ng-container *ngIf=\"options.isSaveForLater; else total\">\n <div\n class=\"cx-total\"\n [ngClass]=\"compact ? '' : ' col-md-3 col-lg-3 col-xl-2'\"\n >\n <div\n class=\"cx-label\"\n [ngClass]=\"\n compact ? '' : ' d-block d-md-none d-lg-none d-xl-none'\n \"\n >\n {{ 'saveForLaterItems.stock' | cxTranslate }}\n </div>\n <div\n *ngIf=\"item.product?.stock?.stockLevel >= 0; else forceInstock\"\n class=\"cx-value\"\n >\n {{ item.product.stock.stockLevel }}\n </div>\n <ng-template #forceInstock>\n <div class=\"cx-value\">\n {{ 'saveForLaterItems.forceInStock' | cxTranslate }}\n </div>\n </ng-template>\n </div>\n </ng-container>\n </div>\n <!-- Availability -->\n <div\n *ngIf=\"isProductOutOfStock(item.product)\"\n class=\"cx-availability col-12\"\n >\n {{ 'addToCart.outOfStock' | cxTranslate }}\n </div>\n\n <!-- Item Bundle Details Outlet -->\n <ng-template [cxOutlet]=\"CartOutlets.ITEM_BUNDLE_DETAILS\"> </ng-template>\n\n <!-- Promotion -->\n\n <cx-promotions [promotions]=\"item.promotions\"></cx-promotions>\n\n <!-- Actions -->\n <div\n *ngIf=\"(!readonly || options.isSaveForLater) && item.updateable\"\n class=\"cx-actions col-12\"\n >\n <ng-container *ngIf=\"!isProductOutOfStock(item.product)\">\n <ng-container\n *ngTemplateOutlet=\"\n options.optionalBtn;\n context: {\n $implicit: { loading: quantityControl.disabled, item: item }\n }\n \"\n ></ng-container>\n </ng-container>\n\n <div class=\"col-md-3 cx-remove-btn\">\n <button\n class=\"link cx-action-link\"\n [disabled]=\"quantityControl.disabled\"\n (click)=\"removeItem()\"\n attr.aria-label=\"{{ 'addToCart.removeFromCart' | cxTranslate }}\"\n >\n {{ 'common.remove' | cxTranslate }}\n </button>\n </div>\n </div>\n </div>\n </div>\n\n <ng-template #total>\n <div\n *ngIf=\"item.totalPrice\"\n class=\"cx-total\"\n [ngClass]=\"compact ? '' : ' col-md-3 col-xl-2'\"\n >\n <div\n class=\"cx-label\"\n [ngClass]=\"compact ? '' : ' d-block d-md-none d-lg-none d-xl-none'\"\n >\n {{ 'cartItems.total' | cxTranslate }}\n </div>\n <div class=\"cx-value\">{{ item.totalPrice.formattedValue }}</div>\n </div>\n </ng-template>\n</ng-template>\n", components: [{ type: i2.CartItemValidationWarningComponent, selector: "cx-cart-item-validation-warning", inputs: ["code"] }, { type: i3.MediaComponent, selector: "cx-media", inputs: ["container", "format", "alt", "role", "loading"], outputs: ["loaded"] }, { type: i4.ItemCounterComponent, selector: "cx-item-counter", inputs: ["control", "min", "max", "step", "allowZero", "readonly"] }, { type: i5.PromotionsComponent, selector: "cx-promotions", inputs: ["promotions"] }], directives: [{ type: i6.OutletDirective, selector: "[cxOutlet]", inputs: ["cxOutlet", "cxOutletContext", "cxOutletDefer"], outputs: ["loaded"] }, { type: i7.FeatureLevelDirective, selector: "[cxFeatureLevel]", inputs: ["cxFeatureLevel"] }, { type: i8.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { type: i9.RouterLinkWithHref, selector: "a[routerLink],area[routerLink]", inputs: ["routerLink", "target", "queryParams", "fragment", "queryParamsHandling", "preserveFragment", "skipLocationChange", "replaceUrl", "state", "relativeTo"] }, { type: i10.ModalDirective, selector: "[cxModal]", inputs: ["cxModal", "cxModalReason"] }, { type: i8.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i8.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i8.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }], pipes: { "cxUrl": i7.UrlPipe, "cxTranslate": i7.TranslatePipe } }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.0.5", ngImport: i0, type: CartItemComponent, decorators: [{ type: Component, args: [{ selector: 'cx-cart-item', templateUrl: './cart-item.component.html', providers: [ CartItemContextSource, { provide: CartItemContext, useExisting: CartItemContextSource }, ], }] }], ctorParameters: function () { return [{ type: i1.CartItemContextSource }]; }, propDecorators: { compact: [{ type: Input }], item: [{ type: Input }], readonly: [{ type: Input }], quantityControl: [{ type: Input }], promotionLocation: [{ type: Input }], options: [{ type: Input }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FydC1pdGVtLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3N0b3JlZnJvbnRsaWIvY21zLWNvbXBvbmVudHMvY2FydC9jYXJ0LXNoYXJlZC9jYXJ0LWl0ZW0vY2FydC1pdGVtLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3N0b3JlZnJvbnRsaWIvY21zLWNvbXBvbmVudHMvY2FydC9jYXJ0LXNoYXJlZC9jYXJ0LWl0ZW0vY2FydC1pdGVtLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUE0QixNQUFNLGVBQWUsQ0FBQztBQUUzRSxPQUFPLEVBQWMsaUJBQWlCLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUNoRSxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFDMUQsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQ3ZELE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxNQUFNLHdDQUF3QyxDQUFDO0FBQy9FLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQzs7Ozs7Ozs7Ozs7O0FBZWxFLE1BQU0sT0FBTyxpQkFBaUI7SUFpQjVCLFlBQXNCLHFCQUE0QztRQUE1QywwQkFBcUIsR0FBckIscUJBQXFCLENBQXVCO1FBaEJ6RCxZQUFPLEdBQUcsS0FBSyxDQUFDO1FBRWhCLGFBQVEsR0FBRyxLQUFLLENBQUM7UUFHakIsc0JBQWlCLEdBQXNCLGlCQUFpQixDQUFDLFVBQVUsQ0FBQztRQUU3RSxnREFBZ0Q7UUFDdkMsWUFBTyxHQUE2QjtZQUMzQyxjQUFjLEVBQUUsS0FBSztZQUNyQixXQUFXLEVBQUUsSUFBSTtTQUNsQixDQUFDO1FBRUYsY0FBUyxHQUFHLFNBQVMsQ0FBQztRQUNiLGdCQUFXLEdBQUcsV0FBVyxDQUFDO0lBRWtDLENBQUM7SUFFdEUsV0FBVyxDQUFDLE9BQXVCO1FBQ2pDLElBQUksT0FBTyxhQUFQLE9BQU8sdUJBQVAsT0FBTyxDQUFFLE9BQU8sRUFBRTtZQUNwQixJQUFJLENBQUMscUJBQXFCLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7U0FDeEQ7UUFDRCxJQUFJLE9BQU8sYUFBUCxPQUFPLHVCQUFQLE9BQU8sQ0FBRSxRQUFRLEVBQUU7WUFDckIsSUFBSSxDQUFDLHFCQUFxQixDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1NBQzFEO1FBQ0QsSUFBSSxPQUFPLGFBQVAsT0FBTyx1QkFBUCxPQUFPLENBQUUsSUFBSSxFQUFFO1lBQ2pCLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztTQUNsRDtRQUNELElBQUksT0FBTyxhQUFQLE9BQU8sdUJBQVAsT0FBTyxDQUFFLGVBQWUsRUFBRTtZQUM1QixJQUFJLENBQUMscUJBQXFCLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsQ0FBQztTQUN4RTtRQUNELElBQUksT0FBTyxhQUFQLE9BQU8sdUJBQVAsT0FBTyxDQUFFLGlCQUFpQixFQUFFO1lBQzlCLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO1NBQ25FO1FBQ0QsSUFBSSxPQUFPLGFBQVAsT0FBTyx1QkFBUCxPQUFPLENBQUUsT0FBTyxFQUFFO1lBQ3BCLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztTQUN4RDtJQUNILENBQUM7SUFFRCxtQkFBbUIsQ0FBQyxPQUFZO1FBQzlCLHlEQUF5RDtRQUN6RCxPQUFPLENBQ0wsT0FBTztZQUNQLE9BQU8sQ0FBQyxLQUFLO1lBQ2IsT0FBTyxDQUFDLEtBQUssQ0FBQyxnQkFBZ0IsS0FBSyxZQUFZLENBQ2hELENBQUM7SUFDSixDQUFDO0lBRUQsVUFBVTtRQUNSLElBQUksQ0FBQyxlQUFlLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ2pDLElBQUksQ0FBQyxlQUFlLENBQUMsV0FBVyxFQUFFLENBQUM7SUFDckMsQ0FBQzs7OEdBcERVLGlCQUFpQjtrR0FBakIsaUJBQWlCLDJNQUxqQjtRQUNULHFCQUFxQjtRQUNyQixFQUFFLE9BQU8sRUFBRSxlQUFlLEVBQUUsV0FBVyxFQUFFLHFCQUFxQixFQUFFO0tBQ2pFLCtDQ25CSCx1cU1BeUxBOzJGRHBLYSxpQkFBaUI7a0JBUjdCLFNBQVM7bUJBQUM7b0JBQ1QsUUFBUSxFQUFFLGNBQWM7b0JBQ3hCLFdBQVcsRUFBRSw0QkFBNEI7b0JBQ3pDLFNBQVMsRUFBRTt3QkFDVCxxQkFBcUI7d0JBQ3JCLEVBQUUsT0FBTyxFQUFFLGVBQWUsRUFBRSxXQUFXLEVBQUUscUJBQXFCLEVBQUU7cUJBQ2pFO2lCQUNGOzRHQUVVLE9BQU87c0JBQWYsS0FBSztnQkFDRyxJQUFJO3NCQUFaLEtBQUs7Z0JBQ0csUUFBUTtzQkFBaEIsS0FBSztnQkFDRyxlQUFlO3NCQUF2QixLQUFLO2dCQUVHLGlCQUFpQjtzQkFBekIsS0FBSztnQkFHRyxPQUFPO3NCQUFmLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIElucHV0LCBPbkNoYW5nZXMsIFNpbXBsZUNoYW5nZXMgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEZvcm1Db250cm9sIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHsgT3JkZXJFbnRyeSwgUHJvbW90aW9uTG9jYXRpb24gfSBmcm9tICdAc3BhcnRhY3VzL2NvcmUnO1xuaW1wb3J0IHsgSUNPTl9UWVBFIH0gZnJvbSAnLi4vLi4vLi4vbWlzYy9pY29uL2ljb24ubW9kZWwnO1xuaW1wb3J0IHsgQ2FydE91dGxldHMgfSBmcm9tICcuLi8uLi9jYXJ0LW91dGxldHMubW9kZWwnO1xuaW1wb3J0IHsgQ2FydEl0ZW1Db250ZXh0U291cmNlIH0gZnJvbSAnLi9tb2RlbC9jYXJ0LWl0ZW0tY29udGV4dC1zb3VyY2UubW9kZWwnO1xuaW1wb3J0IHsgQ2FydEl0ZW1Db250ZXh0IH0gZnJvbSAnLi9tb2RlbC9jYXJ0LWl0ZW0tY29udGV4dC5tb2RlbCc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ2FydEl0ZW1Db21wb25lbnRPcHRpb25zIHtcbiAgaXNTYXZlRm9yTGF0ZXI/OiBib29sZWFuO1xuICBvcHRpb25hbEJ0bj86IGFueTtcbn1cblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnY3gtY2FydC1pdGVtJyxcbiAgdGVtcGxhdGVVcmw6ICcuL2NhcnQtaXRlbS5jb21wb25lbnQuaHRtbCcsXG4gIHByb3ZpZGVyczogW1xuICAgIENhcnRJdGVtQ29udGV4dFNvdXJjZSxcbiAgICB7IHByb3ZpZGU6IENhcnRJdGVtQ29udGV4dCwgdXNlRXhpc3Rpbmc6IENhcnRJdGVtQ29udGV4dFNvdXJjZSB9LFxuICBdLFxufSlcbmV4cG9ydCBjbGFzcyBDYXJ0SXRlbUNvbXBvbmVudCBpbXBsZW1lbnRzIE9uQ2hhbmdlcyB7XG4gIEBJbnB1dCgpIGNvbXBhY3QgPSBmYWxzZTtcbiAgQElucHV0KCkgaXRlbTogT3JkZXJFbnRyeTtcbiAgQElucHV0KCkgcmVhZG9ubHkgPSBmYWxzZTtcbiAgQElucHV0KCkgcXVhbnRpdHlDb250cm9sOiBGb3JtQ29udHJvbDtcblxuICBASW5wdXQoKSBwcm9tb3Rpb25Mb2NhdGlvbjogUHJvbW90aW9uTG9jYXRpb24gPSBQcm9tb3Rpb25Mb2NhdGlvbi5BY3RpdmVDYXJ0O1xuXG4gIC8vIFRPRE86IGV2YWx1YXRlIHdoZXRoZXIgdGhpcyBpcyBnZW5lcmljIGVub3VnaFxuICBASW5wdXQoKSBvcHRpb25zOiBDYXJ0SXRlbUNvbXBvbmVudE9wdGlvbnMgPSB7XG4gICAgaXNTYXZlRm9yTGF0ZXI6IGZhbHNlLFxuICAgIG9wdGlvbmFsQnRuOiBudWxsLFxuICB9O1xuXG4gIGljb25UeXBlcyA9IElDT05fVFlQRTtcbiAgcmVhZG9ubHkgQ2FydE91dGxldHMgPSBDYXJ0T3V0bGV0cztcblxuICBjb25zdHJ1Y3Rvcihwcm90ZWN0ZWQgY2FydEl0ZW1Db250ZXh0U291cmNlOiBDYXJ0SXRlbUNvbnRleHRTb3VyY2UpIHt9XG5cbiAgbmdPbkNoYW5nZXMoY2hhbmdlcz86IFNpbXBsZUNoYW5nZXMpIHtcbiAgICBpZiAoY2hhbmdlcz8uY29tcGFjdCkge1xuICAgICAgdGhpcy5jYXJ0SXRlbUNvbnRleHRTb3VyY2UuY29tcGFjdCQubmV4dCh0aGlzLmNvbXBhY3QpO1xuICAgIH1cbiAgICBpZiAoY2hhbmdlcz8ucmVhZG9ubHkpIHtcbiAgICAgIHRoaXMuY2FydEl0ZW1Db250ZXh0U291cmNlLnJlYWRvbmx5JC5uZXh0KHRoaXMucmVhZG9ubHkpO1xuICAgIH1cbiAgICBpZiAoY2hhbmdlcz8uaXRlbSkge1xuICAgICAgdGhpcy5jYXJ0SXRlbUNvbnRleHRTb3VyY2UuaXRlbSQubmV4dCh0aGlzLml0ZW0pO1xuICAgIH1cbiAgICBpZiAoY2hhbmdlcz8ucXVhbnRpdHlDb250cm9sKSB7XG4gICAgICB0aGlzLmNhcnRJdGVtQ29udGV4dFNvdXJjZS5xdWFudGl0eUNvbnRyb2wkLm5leHQodGhpcy5xdWFudGl0eUNvbnRyb2wpO1xuICAgIH1cbiAgICBpZiAoY2hhbmdlcz8ucHJvbW90aW9uTG9jYXRpb24pIHtcbiAgICAgIHRoaXMuY2FydEl0ZW1Db250ZXh0U291cmNlLmxvY2F0aW9uJC5uZXh0KHRoaXMucHJvbW90aW9uTG9jYXRpb24pO1xuICAgIH1cbiAgICBpZiAoY2hhbmdlcz8ub3B0aW9ucykge1xuICAgICAgdGhpcy5jYXJ0SXRlbUNvbnRleHRTb3VyY2Uub3B0aW9ucyQubmV4dCh0aGlzLm9wdGlvbnMpO1xuICAgIH1cbiAgfVxuXG4gIGlzUHJvZHVjdE91dE9mU3RvY2socHJvZHVjdDogYW55KSB7XG4gICAgLy8gVE9ETyBNb3ZlIHN0b2NrbGV2ZWxzdGF0dXNlcyBhY3Jvc3MgdGhlIGFwcCB0byBhbiBlbnVtXG4gICAgcmV0dXJuIChcbiAgICAgIHByb2R1Y3QgJiZcbiAgICAgIHByb2R1Y3Quc3RvY2sgJiZcbiAgICAgIHByb2R1Y3Quc3RvY2suc3RvY2tMZXZlbFN0YXR1cyA9PT0gJ291dE9mU3RvY2snXG4gICAgKTtcbiAgfVxuXG4gIHJlbW92ZUl0ZW0oKSB7XG4gICAgdGhpcy5xdWFudGl0eUNvbnRyb2wuc2V0VmFsdWUoMCk7XG4gICAgdGhpcy5xdWFudGl0eUNvbnRyb2wubWFya0FzRGlydHkoKTtcbiAgfVxufVxuIiwiPCEtLSBJdGVtIFN0YXJ0IE91dGxldCAtLT5cbjxuZy10ZW1wbGF0ZSBbY3hPdXRsZXRdPVwiQ2FydE91dGxldHMuSVRFTVwiPlxuICA8bmctY29udGFpbmVyICpjeEZlYXR1cmVMZXZlbD1cIic0LjInXCI+XG4gICAgPGN4LWNhcnQtaXRlbS12YWxpZGF0aW9uLXdhcm5pbmdcbiAgICAgIFtjb2RlXT1cIml0ZW0ucHJvZHVjdC5jb2RlXCJcbiAgICA+PC9jeC1jYXJ0LWl0ZW0tdmFsaWRhdGlvbi13YXJuaW5nPlxuICA8L25nLWNvbnRhaW5lcj5cbiAgPGRpdiBbbmdDbGFzc109XCJjb21wYWN0ID8gJ2N4LWNvbXBhY3Qgcm93JyA6ICdyb3cnXCI+XG4gICAgPCEtLSBJdGVtIEltYWdlIC0tPlxuICAgIDxkaXYgY2xhc3M9XCJjb2wtMiBjeC1pbWFnZS1jb250YWluZXJcIj5cbiAgICAgIDxhXG4gICAgICAgIFtyb3V0ZXJMaW5rXT1cInsgY3hSb3V0ZTogJ3Byb2R1Y3QnLCBwYXJhbXM6IGl0ZW0ucHJvZHVjdCB9IHwgY3hVcmxcIlxuICAgICAgICBjeE1vZGFsPVwiZGlzbWlzc1wiXG4gICAgICAgIHRhYmluZGV4PVwiLTFcIlxuICAgICAgPlxuICAgICAgICA8Y3gtbWVkaWFcbiAgICAgICAgICBbY29udGFpbmVyXT1cIml0ZW0ucHJvZHVjdC5pbWFnZXM/LlBSSU1BUllcIlxuICAgICAgICAgIGZvcm1hdD1cImNhcnRJY29uXCJcbiAgICAgICAgPjwvY3gtbWVkaWE+XG4gICAgICA8L2E+XG4gICAgPC9kaXY+XG4gICAgPCEtLSBJdGVtIEluZm9ybWF0aW9uIC0tPlxuICAgIDxkaXYgY2xhc3M9XCJjeC1pbmZvIGNvbC0xMFwiPlxuICAgICAgPGRpdiBjbGFzcz1cImN4LWluZm8tY29udGFpbmVyIHJvd1wiPlxuICAgICAgICA8IS0tIEl0ZW0gRGVzY3JpcHRpb24gLS0+XG4gICAgICAgIDxkaXYgW25nQ2xhc3NdPVwiY29tcGFjdCA/ICcnIDogJyBjb2wtbWQtMyBjb2wtbGctMyBjb2wteGwtNSdcIj5cbiAgICAgICAgICA8ZGl2ICpuZ0lmPVwiaXRlbS5wcm9kdWN0Lm5hbWVcIiBjbGFzcz1cImN4LW5hbWVcIj5cbiAgICAgICAgICAgIDxhXG4gICAgICAgICAgICAgIGNsYXNzPVwiY3gtbGlua1wiXG4gICAgICAgICAgICAgIFtyb3V0ZXJMaW5rXT1cIlxuICAgICAgICAgICAgICAgIHsgY3hSb3V0ZTogJ3Byb2R1Y3QnLCBwYXJhbXM6IGl0ZW0ucHJvZHVjdCB9IHwgY3hVcmxcbiAgICAgICAgICAgICAgXCJcbiAgICAgICAgICAgICAgY3hNb2RhbD1cImRpc21pc3NcIlxuICAgICAgICAgICAgICA+PGgyPnt7IGl0ZW0ucHJvZHVjdC5uYW1lIH19PC9oMj48L2FcbiAgICAgICAgICAgID5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8ZGl2ICpuZ0lmPVwiaXRlbS5wcm9kdWN0LmNvZGVcIiBjbGFzcz1cImN4LWNvZGVcIj5cbiAgICAgICAgICAgIHt7ICdjYXJ0SXRlbXMuaWQnIHwgY3hUcmFuc2xhdGUgfX0ge3sgaXRlbS5wcm9kdWN0LmNvZGUgfX1cbiAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgIDwhLS0gSXRlbSBEZXRhaWxzIE91dGxldCAtLT5cbiAgICAgICAgICA8bmctdGVtcGxhdGUgW2N4T3V0bGV0XT1cIkNhcnRPdXRsZXRzLklURU1fREVUQUlMU1wiPiA8L25nLXRlbXBsYXRlPlxuXG4gICAgICAgICAgPCEtLSBWYXJpYW50cyAtLT5cbiAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiaXRlbS5wcm9kdWN0LmJhc2VPcHRpb25zPy5sZW5ndGhcIj5cbiAgICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgICAgKm5nRm9yPVwiXG4gICAgICAgICAgICAgICAgbGV0IHZhcmlhbnQgb2YgaXRlbS5wcm9kdWN0LmJhc2VPcHRpb25zWzBdPy5zZWxlY3RlZFxuICAgICAgICAgICAgICAgICAgPy52YXJpYW50T3B0aW9uUXVhbGlmaWVyc1xuICAgICAgICAgICAgICBcIlxuICAgICAgICAgICAgICBjbGFzcz1cImN4LXByb3BlcnR5XCJcbiAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImN4LWxhYmVsXCIgKm5nSWY9XCJ2YXJpYW50Lm5hbWUgJiYgdmFyaWFudC52YWx1ZVwiPlxuICAgICAgICAgICAgICAgIHt7IHZhcmlhbnQubmFtZSB9fToge3sgdmFyaWFudC52YWx1ZSB9fVxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPCEtLSBJdGVtIFByaWNlIC0tPlxuICAgICAgICA8ZGl2XG4gICAgICAgICAgKm5nSWY9XCJpdGVtLmJhc2VQcmljZVwiXG4gICAgICAgICAgY2xhc3M9XCJjeC1wcmljZVwiXG4gICAgICAgICAgW25nQ2xhc3NdPVwiY29tcGFjdCA/ICcnIDogJyBjb2wtbWQtMyBjb2wtbGctMyBjb2wteGwtMidcIlxuICAgICAgICA+XG4gICAgICAgICAgPGRpdlxuICAgICAgICAgICAgY2xhc3M9XCJjeC1sYWJlbFwiXG4gICAgICAgICAgICBbbmdDbGFzc109XCJjb21wYWN0ID8gJycgOiAnIGQtYmxvY2sgZC1tZC1ub25lIGQtbGctbm9uZSBkLXhsLW5vbmUnXCJcbiAgICAgICAgICA+XG4gICAgICAgICAgICB7eyAnY2FydEl0ZW1zLml0ZW1QcmljZScgfCBjeFRyYW5zbGF0ZSB9fVxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDxkaXYgKm5nSWY9XCJpdGVtLmJhc2VQcmljZVwiIGNsYXNzPVwiY3gtdmFsdWVcIj5cbiAgICAgICAgICAgIHt7IGl0ZW0uYmFzZVByaWNlPy5mb3JtYXR0ZWRWYWx1ZSB9fVxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPCEtLSBJdGVtIFF1YW50aXR5IC0tPlxuICAgICAgICA8ZGl2IGNsYXNzPVwiY3gtcXVhbnRpdHlcIiBbbmdDbGFzc109XCJjb21wYWN0ID8gJycgOiAnIGNvbC0zJ1wiPlxuICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgIGNsYXNzPVwiY3gtbGFiZWxcIlxuICAgICAgICAgICAgW25nQ2xhc3NdPVwiY29tcGFjdCA/ICcnIDogJyBkLWJsb2NrIGQtbWQtbm9uZSBkLWxnLW5vbmUgZC14bC1ub25lJ1wiXG4gICAgICAgICAgICBwbGFjZW1lbnQ9XCJsZWZ0XCJcbiAgICAgICAgICAgIHRpdGxlPVwie3sgJ2NhcnRJdGVtcy5xdWFudGl0eVRpdGxlJyB8IGN4VHJhbnNsYXRlIH19XCJcbiAgICAgICAgICA+XG4gICAgICAgICAgICB7eyAnY2FydEl0ZW1zLnF1YW50aXR5JyB8IGN4VHJhbnNsYXRlIH19XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImN4LXZhbHVlXCIgW2NsYXNzLnJlYWRvbmx5LXZhbHVlXT1cInJlYWRvbmx5XCI+XG4gICAgICAgICAgICA8Y3gtaXRlbS1jb3VudGVyXG4gICAgICAgICAgICAgIFtjb250cm9sXT1cInF1YW50aXR5Q29udHJvbFwiXG4gICAgICAgICAgICAgIFtyZWFkb25seV09XCJcbiAgICAgICAgICAgICAgICAhaXRlbS51cGRhdGVhYmxlIHx8IHJlYWRvbmx5IHx8IG9wdGlvbnMuaXNTYXZlRm9yTGF0ZXJcbiAgICAgICAgICAgICAgXCJcbiAgICAgICAgICAgICAgW21heF09XCJpdGVtLnByb2R1Y3Quc3RvY2s/LnN0b2NrTGV2ZWxcIlxuICAgICAgICAgICAgICBbYWxsb3daZXJvXT1cInRydWVcIlxuICAgICAgICAgICAgPlxuICAgICAgICAgICAgPC9jeC1pdGVtLWNvdW50ZXI+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8IS0tIFRvdGFsIC0tPlxuICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwib3B0aW9ucy5pc1NhdmVGb3JMYXRlcjsgZWxzZSB0b3RhbFwiPlxuICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgIGNsYXNzPVwiY3gtdG90YWxcIlxuICAgICAgICAgICAgW25nQ2xhc3NdPVwiY29tcGFjdCA/ICcnIDogJyBjb2wtbWQtMyBjb2wtbGctMyBjb2wteGwtMidcIlxuICAgICAgICAgID5cbiAgICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgICAgY2xhc3M9XCJjeC1sYWJlbFwiXG4gICAgICAgICAgICAgIFtuZ0NsYXNzXT1cIlxuICAgICAgICAgICAgICAgIGNvbXBhY3QgPyAnJyA6ICcgZC1ibG9jayBkLW1kLW5vbmUgZC1sZy1ub25lIGQteGwtbm9uZSdcbiAgICAgICAgICAgICAgXCJcbiAgICAgICAgICAgID5cbiAgICAgICAgICAgICAge3sgJ3NhdmVGb3JMYXRlckl0ZW1zLnN0b2NrJyB8IGN4VHJhbnNsYXRlIH19XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgICAgKm5nSWY9XCJpdGVtLnByb2R1Y3Q/LnN0b2NrPy5zdG9ja0xldmVsID49IDA7IGVsc2UgZm9yY2VJbnN0b2NrXCJcbiAgICAgICAgICAgICAgY2xhc3M9XCJjeC12YWx1ZVwiXG4gICAgICAgICAgICA+XG4gICAgICAgICAgICAgIHt7IGl0ZW0ucHJvZHVjdC5zdG9jay5zdG9ja0xldmVsIH19XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSAjZm9yY2VJbnN0b2NrPlxuICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY3gtdmFsdWVcIj5cbiAgICAgICAgICAgICAgICB7eyAnc2F2ZUZvckxhdGVySXRlbXMuZm9yY2VJblN0b2NrJyB8IGN4VHJhbnNsYXRlIH19XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICA8L2Rpdj5cbiAgICAgIDwhLS0gQXZhaWxhYmlsaXR5IC0tPlxuICAgICAgPGRpdlxuICAgICAgICAqbmdJZj1cImlzUHJvZHVjdE91dE9mU3RvY2soaXRlbS5wcm9kdWN0KVwiXG4gICAgICAgIGNsYXNzPVwiY3gtYXZhaWxhYmlsaXR5IGNvbC0xMlwiXG4gICAgICA+XG4gICAgICAgIHt7ICdhZGRUb0NhcnQub3V0T2ZTdG9jaycgfCBjeFRyYW5zbGF0ZSB9fVxuICAgICAgPC9kaXY+XG5cbiAgICAgIDwhLS0gSXRlbSBCdW5kbGUgRGV0YWlscyBPdXRsZXQgLS0+XG4gICAgICA8bmctdGVtcGxhdGUgW2N4T3V0bGV0XT1cIkNhcnRPdXRsZXRzLklURU1fQlVORExFX0RFVEFJTFNcIj4gPC9uZy10ZW1wbGF0ZT5cblxuICAgICAgPCEtLSBQcm9tb3Rpb24gLS0+XG5cbiAgICAgIDxjeC1wcm9tb3Rpb25zIFtwcm9tb3Rpb25zXT1cIml0ZW0ucHJvbW90aW9uc1wiPjwvY3gtcHJvbW90aW9ucz5cblxuICAgICAgPCEtLSBBY3Rpb25zIC0tPlxuICAgICAgPGRpdlxuICAgICAgICAqbmdJZj1cIighcmVhZG9ubHkgfHwgb3B0aW9ucy5pc1NhdmVGb3JMYXRlcikgJiYgaXRlbS51cGRhdGVhYmxlXCJcbiAgICAgICAgY2xhc3M9XCJjeC1hY3Rpb25zIGNvbC0xMlwiXG4gICAgICA+XG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCIhaXNQcm9kdWN0T3V0T2ZTdG9jayhpdGVtLnByb2R1Y3QpXCI+XG4gICAgICAgICAgPG5nLWNvbnRhaW5lclxuICAgICAgICAgICAgKm5nVGVtcGxhdGVPdXRsZXQ9XCJcbiAgICAgICAgICAgICAgb3B0aW9ucy5vcHRpb25hbEJ0bjtcbiAgICAgICAgICAgICAgY29udGV4dDoge1xuICAgICAgICAgICAgICAgICRpbXBsaWNpdDogeyBsb2FkaW5nOiBxdWFudGl0eUNvbnRyb2wuZGlzYWJsZWQsIGl0ZW06IGl0ZW0gfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBcIlxuICAgICAgICAgID48L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgPGRpdiBjbGFzcz1cImNvbC1tZC0zIGN4LXJlbW92ZS1idG5cIj5cbiAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICBjbGFzcz1cImxpbmsgY3gtYWN0aW9uLWxpbmtcIlxuICAgICAgICAgICAgW2Rpc2FibGVkXT1cInF1YW50aXR5Q29udHJvbC5kaXNhYmxlZFwiXG4gICAgICAgICAgICAoY2xpY2spPVwicmVtb3ZlSXRlbSgpXCJcbiAgICAgICAgICAgIGF0dHIuYXJpYS1sYWJlbD1cInt7ICdhZGRUb0NhcnQucmVtb3ZlRnJvbUNhcnQnIHwgY3hUcmFuc2xhdGUgfX1cIlxuICAgICAgICAgID5cbiAgICAgICAgICAgIHt7ICdjb21tb24ucmVtb3ZlJyB8IGN4VHJhbnNsYXRlIH19XG4gICAgICAgICAgPC9idXR0b24+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG4gIDwvZGl2PlxuXG4gIDxuZy10ZW1wbGF0ZSAjdG90YWw+XG4gICAgPGRpdlxuICAgICAgKm5nSWY9XCJpdGVtLnRvdGFsUHJpY2VcIlxuICAgICAgY2xhc3M9XCJjeC10b3RhbFwiXG4gICAgICBbbmdDbGFzc109XCJjb21wYWN0ID8gJycgOiAnIGNvbC1tZC0zIGNvbC14bC0yJ1wiXG4gICAgPlxuICAgICAgPGRpdlxuICAgICAgICBjbGFzcz1cImN4LWxhYmVsXCJcbiAgICAgICAgW25nQ2xhc3NdPVwiY29tcGFjdCA/ICcnIDogJyBkLWJsb2NrIGQtbWQtbm9uZSBkLWxnLW5vbmUgZC14bC1ub25lJ1wiXG4gICAgICA+XG4gICAgICAgIHt7ICdjYXJ0SXRlbXMudG90YWwnIHwgY3hUcmFuc2xhdGUgfX1cbiAgICAgIDwvZGl2PlxuICAgICAgPGRpdiBjbGFzcz1cImN4LXZhbHVlXCI+e3sgaXRlbS50b3RhbFByaWNlLmZvcm1hdHRlZFZhbHVlIH19PC9kaXY+XG4gICAgPC9kaXY+XG4gIDwvbmctdGVtcGxhdGU+XG48L25nLXRlbXBsYXRlPlxuIl19