UNPKG

@vendasta/store

Version:

Components and data for Store

341 lines 52.4 kB
import { Component, Input, Inject } from '@angular/core'; import { DisplayPriceService } from '@vendasta/core/shared'; import { BehaviorSubject, combineLatest, Observable, of, EMPTY } from 'rxjs'; import { TranslateService } from '@ngx-translate/core'; import { map, switchMap, expand, reduce, catchError, publishReplay, refCount, filter } from 'rxjs/operators'; import { DiscountService } from '@vendasta/billing'; import * as i0 from "@angular/core"; import * as i1 from "@ngx-translate/core"; import * as i2 from "@vendasta/core/shared"; import * as i3 from "@vendasta/billing"; import * as i4 from "rxjs"; export class VaBasePricingComponent { constructor(translateService, displayPriceService, partnerId$, discountService) { this.translateService = translateService; this.displayPriceService = displayPriceService; this.partnerId$ = partnerId$; this.discountService = discountService; this.pricing = null; this.wrapFrequency = false; this.isAddon = false; this.hasVerifiedContract = false; this.highlightPrice = true; this.loaded = true; this.showAllPrices = false; // When false this will only show the first element in the pricing.prices list this.useAbbreviatedFrequency = false; this.showIsStartingAt = false; this.pricing$$ = new BehaviorSubject(null); this.billedProduct$$ = new BehaviorSubject(null); this.hasVerifiedContract$$ = new BehaviorSubject(false); this.showPricingPopover = false; this.isFree$ = combineLatest([this.pricing$, this.billedProduct$, this.hasVerifiedContract$]).pipe(map(([pricing, billedProduct, hasVerifiedContract]) => { const isFreeHelper = (prices) => { return prices ? prices.every((p) => p.price === 0 || p.price === undefined) : false; }; if (hasVerifiedContract && billedProduct) { return billedProduct.pricingTiers.length === 1 ? isFreeHelper(billedProduct.pricingTiers) : false; } return !!pricing && isFreeHelper(pricing.prices); })); this.shouldContactSales$ = combineLatest([this.pricing$, this.billedProduct$, this.hasVerifiedContract$]).pipe(map(([pricing, billedProduct, hasVerifiedContract]) => { const nestedPricesIsContactSales = (prices) => { return prices && prices.length > 0 ? prices.some((p) => p.price === null || p.price < 0) : true; }; if (hasVerifiedContract && billedProduct) { return nestedPricesIsContactSales(billedProduct.pricingTiers); } if (!pricing) { return true; } return nestedPricesIsContactSales(pricing.prices); })); this.isFlatPrice$ = this.billedProduct$.pipe(map((billedProduct) => billedProduct.pricingTiers.length === 1)); this.pricingTierData$ = this.billedProduct$.pipe(switchMap((billedProduct) => { const pricingTierObservables = billedProduct.pricingTiers.map((pricingTier) => { return combineLatest([ of(pricingTier.isStartingPrice), this.buildPricingTierString(pricingTier), this.buildPricingTierForProduct(pricingTier, billedProduct.billingFrequency), this.buildPricingTierForAddon(pricingTier), this.buildPriceStringForTier(pricingTier, billedProduct.billingFrequency, pricingTier.isStartingPrice), this.buildPriceStringForTier(pricingTier), ]).pipe(map(([isStartingPrice, pricingTierString, pricingTierForProduct, pricingTierForAddon, priceStringForTier, priceStringForTierWithoutFreq,]) => { return { isStartingPrice: isStartingPrice, pricingTierString: pricingTierString, pricingTierForProduct: pricingTierForProduct, pricingTierForAddon: pricingTierForAddon, priceStringForTier: priceStringForTier, priceStringForTierWithoutFreq: priceStringForTierWithoutFreq, }; })); }); return combineLatest([...pricingTierObservables]); })); this.priceData$ = this.pricing$.pipe(switchMap((pricing) => { let filteredPrices = pricing.prices; if (pricing.prices.length > 1) { filteredPrices = pricing.prices.filter((price) => price.price > 0).sort(this.sortPricesByFrequency); } const priceObservables = filteredPrices.map((price) => { return combineLatest([ of(price.isStartingPrice), this.buildPriceStringForPricing(price, pricing.currency, true, false), this.buildPriceStringForPricing(price, pricing.currency, false, true), this.buildFrequencyString(price.frequency), of(this.buildAbbreviatedFrequencyString(price.frequency)), ]).pipe(map(([isStartingPrice, priceStringForPricingWithoutFrequency, priceStringForPricingWithFrequency, frequencyString, abbrevFreq,]) => { return { isStartingPrice: isStartingPrice, priceStringForPricingWithoutFrequency: priceStringForPricingWithoutFrequency, priceStringForPricingWithFrequency: priceStringForPricingWithFrequency, frequencyString: frequencyString, abbreviatedFrequencyString: abbrevFreq, }; })); }); return combineLatest([...priceObservables]); })); this.commitmentMessage$ = this.buildCommitmentMessage(); this.setupFeeString$ = this.displayPriceService.getSetupFeeString(); this.isFirstTierFree$ = this.billedProduct$.pipe(map((billedProduct) => { return billedProduct.pricingTiers.length > 1 && billedProduct.pricingTiers.some((item) => item.price === 0); })); } get pricing$() { return this.pricing$$.asObservable(); } get billedProduct$() { return this.billedProduct$$.asObservable(); } get hasVerifiedContract$() { return this.hasVerifiedContract$$.asObservable(); } ngOnChanges(changes) { if (changes.hasOwnProperty('pricing')) { this.pricing$$.next(changes.pricing.currentValue); } if (changes.hasOwnProperty('billedProduct')) { this.billedProduct$$.next(changes.billedProduct.currentValue); } if (changes.hasOwnProperty('hasVerifiedContract')) { this.hasVerifiedContract$$.next(changes.hasVerifiedContract.currentValue); } } buildPricingTierString(tier) { let max = String(tier.rangeMax); if (tier.rangeMax === -1) { max = '∞'; if (tier.rangeMin === 0 || tier.rangeMin === 1) { return of(''); } } return this.translateService.stream('FRONTEND.STORE.MIN_TO_MAX', { minRange: String(tier.rangeMin), maxRange: max, }); } buildPricingTierForProduct(tier, frequency) { return combineLatest([this.buildPricingTierString(tier), this.buildFrequencyString(frequency)]).pipe(switchMap(([pricingTier, formattedFrequency]) => { if (pricingTier) { return this.translateService.stream('FRONTEND.STORE.PRODUCT_PRICING_WITH_FREQUENCY', { pricingTier: pricingTier, frequency: formattedFrequency, }); } return of(formattedFrequency); })); } buildPricingTierForAddon(tier) { return this.buildPricingTierString(tier).pipe(map((pricingRange) => (pricingRange ? pricingRange : ''))); } sortPricesByFrequency(priceA, priceB) { // this map is coded based on frequency values described by the enums described in the marketplace packages vendasta // apis and the corresponding translations to strings laced throughout galaxy const priceFrequencyComparisonMap = new Map([ [ 'MONTHLY', new Map([ ['MONTHLY', 0], ['YEARLY', -1], ['ONCE', -1], ['ONE TIME', -1], ['ONE_TIME', -1], ]), ], [ 'YEARLY', new Map([ ['MONTHLY', 1], ['YEARLY', 0], ['ONCE', -1], ['ONE TIME', -1], ['ONE_TIME', -1], ]), ], [ 'ONCE', new Map([ ['MONTHLY', 1], ['YEARLY', 1], ['ONCE', 0], ['ONE TIME', 0], ['ONE_TIME', 0], ]), ], [ 'ONE TIME', new Map([ ['MONTHLY', 1], ['YEARLY', 1], ['ONCE', 0], ['ONE TIME', 0], ['ONE_TIME', 0], ]), ], [ 'ONE_TIME', new Map([ ['MONTHLY', 1], ['YEARLY', 1], ['ONCE', 0], ['ONE TIME', 0], ['ONE_TIME', 0], ]), ], ]); if (priceFrequencyComparisonMap.get(priceA.frequency.toUpperCase()) === undefined) { return 0; } const compareVal = priceFrequencyComparisonMap .get(priceA.frequency.toUpperCase()) .get(priceB.frequency.toUpperCase()); return compareVal ? compareVal : 0; } buildPriceStringForPricing(price, currency, excludeFrequency, canIncludeStartingAtPrefix) { return this.displayPriceService.formatDisplayPrice(price.price, currency, (excludeFrequency ? '' : price.frequency), true, true, true, price.isStartingPrice && canIncludeStartingAtPrefix); } buildPriceStringForTier(tier, frequency, isStartingPrice) { return this.displayPriceService.formatDisplayPrice(tier.price, this.billedProduct.currency, frequency, undefined, undefined, undefined, isStartingPrice); } buildFrequencyString(frequency) { return this.displayPriceService.formatBillingFrequency(frequency); } buildAbbreviatedFrequencyString(frequency) { switch ((frequency || '').toLowerCase()) { case 'daily': return 'dy'; case 'weekly': return 'wk'; case 'monthly': return 'mo'; case 'yearly': return 'yr'; } return null; } buildCommitmentMessage() { return combineLatest([ this.translateService.stream('FRONTEND.STORE.PRICING_FREQUENCIES'), this.billedProduct$, this.pricing$, this.isFree$, this.shouldContactSales$, ]).pipe(switchMap(([frequencyTranslations, billedProduct, pricing, isFree, shouldContactSales]) => { const frequency = billedProduct ? billedProduct.billingFrequency.toString().toLowerCase() : pricing && pricing.prices.length > 0 ? pricing.prices[0].frequency.toLowerCase() : ''; let frequencyString = ''; if (frequency === 'yearly') { frequencyString = frequencyTranslations.YEAR; } else if (frequency === 'monthly') { frequencyString = frequencyTranslations.MONTH; } if (!frequencyString || isFree || shouldContactSales) { return of(''); } if (billedProduct && billedProduct.commitment) { const initial = billedProduct.commitment.initial; const recurring = billedProduct.commitment.recurring; return this.translateService.stream('FRONTEND.STORE.COMMITMENT_WITH_RENEWAL', { initial: initial, frequencyString: frequencyString, recurring: recurring, }); } return of(''); })); } fetchAllDiscounts(pid, sku) { const pageSize = 50; const filters = { merchantId: pid, expiry: new Date(), skus: [sku], }; return this.discountService.list(filters, '', pageSize).pipe(expand((resp) => { if ((resp?.results || []).length >= pageSize) { return this.discountService.list(filters, resp.nextCursor, pageSize); } else { return EMPTY; } }), reduce((prev, curr) => { const discounts = curr?.results || []; return prev.concat(discounts); }, [])); } getDiscounts() { return combineLatest([this.partnerId$, this.billedProduct$]).pipe(filter(([pid, billedProduct]) => !!pid && !!billedProduct), switchMap(([pid, billedProduct]) => { return this.fetchAllDiscounts(pid, billedProduct.productId); }), catchError((err) => { console.error('error getting discount information:', err); return of([]); }), publishReplay(1), refCount()); } itemInfoIconEnter() { if (this.discounts$ === undefined) { this.discounts$ = this.getDiscounts(); } this.showPricingPopover = true; } itemInfoIconLeave() { this.showPricingPopover = false; } } VaBasePricingComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.0.2", ngImport: i0, type: VaBasePricingComponent, deps: [{ token: i1.TranslateService }, { token: i2.DisplayPriceService }, { token: 'PARTNER_ID' }, { token: i3.DiscountService }], target: i0.ɵɵFactoryTarget.Component }); VaBasePricingComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.0.2", type: VaBasePricingComponent, selector: "app-base-pricing", inputs: { pricing: "pricing", billedProduct: "billedProduct", wrapFrequency: "wrapFrequency", isAddon: "isAddon", hasVerifiedContract: "hasVerifiedContract", highlightPrice: "highlightPrice", loaded: "loaded", showAllPrices: "showAllPrices", useAbbreviatedFrequency: "useAbbreviatedFrequency", showIsStartingAt: "showIsStartingAt" }, usesOnChanges: true, ngImport: i0, template: '', isInline: true }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.2", ngImport: i0, type: VaBasePricingComponent, decorators: [{ type: Component, args: [{ selector: 'app-base-pricing', template: '', }] }], ctorParameters: function () { return [{ type: i1.TranslateService }, { type: i2.DisplayPriceService }, { type: i4.Observable, decorators: [{ type: Inject, args: ['PARTNER_ID'] }] }, { type: i3.DiscountService }]; }, propDecorators: { pricing: [{ type: Input }], billedProduct: [{ type: Input }], wrapFrequency: [{ type: Input }], isAddon: [{ type: Input }], hasVerifiedContract: [{ type: Input }], highlightPrice: [{ type: Input }], loaded: [{ type: Input }], showAllPrices: [{ type: Input }], useAbbreviatedFrequency: [{ type: Input }], showIsStartingAt: [{ type: Input }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFzZS1wcmljaW5nLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL2xpYnMvc3RvcmUvc3JjL2xpYi9wcmljaW5nL2Jhc2UtcHJpY2luZy5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQTRCLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUVuRixPQUFPLEVBQStCLG1CQUFtQixFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFFekYsT0FBTyxFQUFFLGVBQWUsRUFBRSxhQUFhLEVBQUUsVUFBVSxFQUFFLEVBQUUsRUFBRSxLQUFLLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDN0UsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDdkQsT0FBTyxFQUFFLEdBQUcsRUFBRSxTQUFTLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQUUsYUFBYSxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUM3RyxPQUFPLEVBQWtELGVBQWUsRUFBRSxNQUFNLG1CQUFtQixDQUFDOzs7Ozs7QUFPcEcsTUFBTSxPQUFPLHNCQUFzQjtJQTJEakMsWUFDVSxnQkFBa0MsRUFDbEMsbUJBQXdDLEVBQ2pCLFVBQThCLEVBQ3JELGVBQWdDO1FBSGhDLHFCQUFnQixHQUFoQixnQkFBZ0IsQ0FBa0I7UUFDbEMsd0JBQW1CLEdBQW5CLG1CQUFtQixDQUFxQjtRQUNqQixlQUFVLEdBQVYsVUFBVSxDQUFvQjtRQUNyRCxvQkFBZSxHQUFmLGVBQWUsQ0FBaUI7UUE5RGpDLFlBQU8sR0FBWSxJQUFJLENBQUM7UUFFeEIsa0JBQWEsR0FBRyxLQUFLLENBQUM7UUFDdEIsWUFBTyxHQUFHLEtBQUssQ0FBQztRQUNoQix3QkFBbUIsR0FBRyxLQUFLLENBQUM7UUFDNUIsbUJBQWMsR0FBRyxJQUFJLENBQUM7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QixFQUFFOzJGQUVELHNCQUFzQjtrQkFKbEMsU0FBUzttQkFBQztvQkFDVCxRQUFRLEVBQUUsa0JBQWtCO29CQUM1QixRQUFRLEVBQUUsRUFBRTtpQkFDYjs7MEJBK0RJLE1BQU07MkJBQUMsWUFBWTswRUE3RGIsT0FBTztzQkFBZixLQUFLO2dCQUNHLGFBQWE7c0JBQXJCLEtBQUs7Z0JBQ0csYUFBYTtzQkFBckIsS0FBSztnQkFDRyxPQUFPO3NCQUFmLEtBQUs7Z0JBQ0csbUJBQW1CO3NCQUEzQixLQUFLO2dCQUNHLGNBQWM7c0JBQXRCLEtBQUs7Z0JBQ0csTUFBTTtzQkFBZCxLQUFLO2dCQUNHLGFBQWE7c0JBQXJCLEtBQUs7Z0JBQ0csdUJBQXVCO3NCQUEvQixLQUFLO2dCQUNHLGdCQUFnQjtzQkFBeEIsS0FBSyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgSW5wdXQsIE9uQ2hhbmdlcywgU2ltcGxlQ2hhbmdlcywgSW5qZWN0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBCaWxsZWRQcm9kdWN0LCBQcmljaW5nVGllciB9IGZyb20gJ0B2ZW5kYXN0YS9iaWxsaW5nJztcbmltcG9ydCB7IE1hcmtldHBsYWNlQmlsbGluZ0ZyZXF1ZW5jeSwgRGlzcGxheVByaWNlU2VydmljZSB9IGZyb20gJ0B2ZW5kYXN0YS9jb3JlL3NoYXJlZCc7XG5pbXBvcnQgeyBQcmljaW5nLCBQcmljZSB9IGZyb20gJy4vcHJpY2luZyc7XG5pbXBvcnQgeyBCZWhhdmlvclN1YmplY3QsIGNvbWJpbmVMYXRlc3QsIE9ic2VydmFibGUsIG9mLCBFTVBUWSB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgVHJhbnNsYXRlU2VydmljZSB9IGZyb20gJ0BuZ3gtdHJhbnNsYXRlL2NvcmUnO1xuaW1wb3J0IHsgbWFwLCBzd2l0Y2hNYXAsIGV4cGFuZCwgcmVkdWNlLCBjYXRjaEVycm9yLCBwdWJsaXNoUmVwbGF5LCByZWZDb3VudCwgZmlsdGVyIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgRGlzY291bnQsIExpc3REaXNjb3VudHNSZXF1ZXN0RmlsdGVyc0ludGVyZmFjZSwgRGlzY291bnRTZXJ2aWNlIH0gZnJvbSAnQHZlbmRhc3RhL2JpbGxpbmcnO1xuaW1wb3J0IHsgSHR0cEVycm9yUmVzcG9uc2UgfSBmcm9tICdAYW5ndWxhci9jb21tb24vaHR0cCc7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2FwcC1iYXNlLXByaWNpbmcnLFxuICB0ZW1wbGF0ZTogJycsXG59KVxuZXhwb3J0IGNsYXNzIFZhQmFzZVByaWNpbmdDb21wb25lbnQgaW1wbGVtZW50cyBPbkNoYW5nZXMge1xuICBASW5wdXQoKSBwcmljaW5nOiBQcmljaW5nID0gbnVsbDtcbiAgQElucHV0KCkgYmlsbGVkUHJvZHVjdDogQmlsbGVkUHJvZHVjdDtcbiAgQElucHV0KCkgd3JhcEZyZXF1ZW5jeSA9IGZhbHNlO1xuICBASW5wdXQoKSBpc0FkZG9uID0gZmFsc2U7XG4gIEBJbnB1dCgpIGhhc1ZlcmlmaWVkQ29udHJhY3QgPSBmYWxzZTtcbiAgQElucHV0KCkgaGlnaGxpZ2h0UHJpY2UgPSB0cnVlO1xuICBASW5wdXQoKSBsb2FkZWQgPSB0cnVlO1xuICBASW5wdXQoKSBzaG93QWxsUHJpY2VzID0gZmFsc2U7IC8vIFdoZW4gZmFsc2UgdGhpcyB3aWxsIG9ubHkgc2hvdyB0aGUgZmlyc3QgZWxlbWVudCBpbiB0aGUgcHJpY2luZy5wcmljZXMgbGlzdFxuICBASW5wdXQoKSB1c2VBYmJyZXZpYXRlZEZyZXF1ZW5jeSA9IGZhbHNlO1xuICBASW5wdXQoKSBzaG93SXNTdGFydGluZ0F0ID0gZmFsc2U7XG5cbiAgcHJpY2luZyQkID0gbmV3IEJlaGF2aW9yU3ViamVjdDxQcmljaW5nPihudWxsKTtcbiAgYmlsbGVkUHJvZHVjdCQkID0gbmV3IEJlaGF2aW9yU3ViamVjdDxCaWxsZWRQcm9kdWN0PihudWxsKTtcbiAgaGFzVmVyaWZpZWRDb250cmFjdCQkID0gbmV3IEJlaGF2aW9yU3ViamVjdDxib29sZWFuPihmYWxzZSk7XG5cbiAgaXNGcmVlJDogT2JzZXJ2YWJsZTxib29sZWFuPjtcbiAgc2hvdWxkQ29udGFjdFNhbGVzJDogT2JzZXJ2YWJsZTxib29sZWFuPjtcbiAgaXNGbGF0UHJpY2UkOiBPYnNlcnZhYmxlPGJvb2xlYW4+O1xuXG4gIHByaWNpbmdUaWVyRGF0YSQ6IE9ic2VydmFibGU8XG4gICAge1xuICAgICAgaXNTdGFydGluZ1ByaWNlOiBib29sZWFuO1xuICAgICAgcHJpY2luZ1RpZXJTdHJpbmc6IHN0cmluZztcbiAgICAgIHByaWNpbmdUaWVyRm9yUHJvZHVjdDogc3RyaW5nO1xuICAgICAgcHJpY2luZ1RpZXJGb3JBZGRvbjogc3RyaW5nO1xuICAgICAgcHJpY2VTdHJpbmdGb3JUaWVyOiBzdHJpbmc7XG4gICAgICBwcmljZVN0cmluZ0ZvclRpZXJXaXRob3V0RnJlcTogc3RyaW5nO1xuICAgIH1bXVxuICA+O1xuXG4gIHByaWNlRGF0YSQ6IE9ic2VydmFibGU8XG4gICAge1xuICAgICAgaXNTdGFydGluZ1ByaWNlOiBib29sZWFuO1xuICAgICAgcHJpY2VTdHJpbmdGb3JQcmljaW5nV2l0aG91dEZyZXF1ZW5jeTogc3RyaW5nO1xuICAgICAgcHJpY2VTdHJpbmdGb3JQcmljaW5nV2l0aEZyZXF1ZW5jeTogc3RyaW5nO1xuICAgICAgZnJlcXVlbmN5U3RyaW5nOiBzdHJpbmc7XG4gICAgICBhYmJyZXZpYXRlZEZyZXF1ZW5jeVN0cmluZzogc3RyaW5nO1xuICAgIH1bXVxuICA+O1xuXG4gIGNvbW1pdG1lbnRNZXNzYWdlJDogT2JzZXJ2YWJsZTxzdHJpbmc+O1xuICBzZXR1cEZlZVN0cmluZyQ6IE9ic2VydmFibGU8c3RyaW5nPjtcbiAgaXNGaXJzdFRpZXJGcmVlJDogT2JzZXJ2YWJsZTxib29sZWFuPjtcbiAgc2hvd1ByaWNpbmdQb3BvdmVyOiBib29sZWFuID0gZmFsc2U7XG4gIGRpc2NvdW50cyQ6IE9ic2VydmFibGU8RGlzY291bnRbXT47XG5cbiAgZ2V0IHByaWNpbmckKCk6IE9ic2VydmFibGU8UHJpY2luZz4ge1xuICAgIHJldHVybiB0aGlzLnByaWNpbmckJC5hc09ic2VydmFibGUoKTtcbiAgfVxuXG4gIGdldCBiaWxsZWRQcm9kdWN0JCgpOiBPYnNlcnZhYmxlPEJpbGxlZFByb2R1Y3Q+IHtcbiAgICByZXR1cm4gdGhpcy5iaWxsZWRQcm9kdWN0JCQuYXNPYnNlcnZhYmxlKCk7XG4gIH1cblxuICBnZXQgaGFzVmVyaWZpZWRDb250cmFjdCQoKTogT2JzZXJ2YWJsZTxib29sZWFuPiB7XG4gICAgcmV0dXJuIHRoaXMuaGFzVmVyaWZpZWRDb250cmFjdCQkLmFzT2JzZXJ2YWJsZSgpO1xuICB9XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSB0cmFuc2xhdGVTZXJ2aWNlOiBUcmFuc2xhdGVTZXJ2aWNlLFxuICAgIHByaXZhdGUgZGlzcGxheVByaWNlU2VydmljZTogRGlzcGxheVByaWNlU2VydmljZSxcbiAgICBASW5qZWN0KCdQQVJUTkVSX0lEJykgcmVhZG9ubHkgcGFydG5lcklkJDogT2JzZXJ2YWJsZTxzdHJpbmc+LFxuICAgIHByaXZhdGUgZGlzY291bnRTZXJ2aWNlOiBEaXNjb3VudFNlcnZpY2UsXG4gICkge1xuICAgIHRoaXMuaXNGcmVlJCA9IGNvbWJpbmVMYXRlc3QoW3RoaXMucHJpY2luZyQsIHRoaXMuYmlsbGVkUHJvZHVjdCQsIHRoaXMuaGFzVmVyaWZpZWRDb250cmFjdCRdKS5waXBlKFxuICAgICAgbWFwKChbcHJpY2luZywgYmlsbGVkUHJvZHVjdCwgaGFzVmVyaWZpZWRDb250cmFjdF0pID0+IHtcbiAgICAgICAgY29uc3QgaXNGcmVlSGVscGVyID0gKHByaWNlczogeyBwcmljZTogbnVtYmVyIH1bXSk6IGJvb2xlYW4gPT4ge1xuICAgICAgICAgIHJldHVybiBwcmljZXMgPyBwcmljZXMuZXZlcnkoKHApID0+IHAucHJpY2UgPT09IDAgfHwgcC5wcmljZSA9PT0gdW5kZWZpbmVkKSA6IGZhbHNlO1xuICAgICAgICB9O1xuXG4gICAgICAgIGlmIChoYXNWZXJpZmllZENvbnRyYWN0ICYmIGJpbGxlZFByb2R1Y3QpIHtcbiAgICAgICAgICByZXR1cm4gYmlsbGVkUHJvZHVjdC5wcmljaW5nVGllcnMubGVuZ3RoID09PSAxID8gaXNGcmVlSGVscGVyKGJpbGxlZFByb2R1Y3QucHJpY2luZ1RpZXJzKSA6IGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiAhIXByaWNpbmcgJiYgaXNGcmVlSGVscGVyKHByaWNpbmcucHJpY2VzKTtcbiAgICAgIH0pLFxuICAgICk7XG5cbiAgICB0aGlzLnNob3VsZENvbnRhY3RTYWxlcyQgPSBjb21iaW5lTGF0ZXN0KFt0aGlzLnByaWNpbmckLCB0aGlzLmJpbGxlZFByb2R1Y3QkLCB0aGlzLmhhc1ZlcmlmaWVkQ29udHJhY3QkXSkucGlwZShcbiAgICAgIG1hcCgoW3ByaWNpbmcsIGJpbGxlZFByb2R1Y3QsIGhhc1ZlcmlmaWVkQ29udHJhY3RdKSA9PiB7XG4gICAgICAgIGNvbnN0IG5lc3RlZFByaWNlc0lzQ29udGFjdFNhbGVzID0gKHByaWNlczogeyBwcmljZTogbnVtYmVyIH1bXSkgPT4ge1xuICAgICAgICAgIHJldHVybiBwcmljZXMgJiYgcHJpY2VzLmxlbmd0aCA+IDAgPyBwcmljZXMuc29tZSgocCkgPT4gcC5wcmljZSA9PT0gbnVsbCB8fCBwLnByaWNlIDwgMCkgOiB0cnVlO1xuICAgICAgICB9O1xuXG4gICAgICAgIGlmIChoYXNWZXJpZmllZENvbnRyYWN0ICYmIGJpbGxlZFByb2R1Y3QpIHtcbiAgICAgICAgICByZXR1cm4gbmVzdGVkUHJpY2VzSXNDb250YWN0U2FsZXMoYmlsbGVkUHJvZHVjdC5wcmljaW5nVGllcnMpO1xuICAgICAgICB9XG4gICAgICAgIGlmICghcHJpY2luZykge1xuICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBuZXN0ZWRQcmljZXNJc0NvbnRhY3RTYWxlcyhwcmljaW5nLnByaWNlcyk7XG4gICAgICB9KSxcbiAgICApO1xuXG4gICAgdGhpcy5pc0ZsYXRQcmljZSQgPSB0aGlzLmJpbGxlZFByb2R1Y3QkLnBpcGUobWFwKChiaWxsZWRQcm9kdWN0KSA9PiBiaWxsZWRQcm9kdWN0LnByaWNpbmdUaWVycy5sZW5ndGggPT09IDEpKTtcbiAgICB0aGlzLnByaWNpbmdUaWVyRGF0YSQgPSB0aGlzLmJpbGxlZFByb2R1Y3QkLnBpcGUoXG4gICAgICBzd2l0Y2hNYXAoKGJpbGxlZFByb2R1Y3QpID0+IHtcbiAgICAgICAgY29uc3QgcHJpY2luZ1RpZXJPYnNlcnZhYmxlcyA9IGJpbGxlZFByb2R1Y3QucHJpY2luZ1RpZXJzLm1hcCgocHJpY2luZ1RpZXIpID0+IHtcbiAgICAgICAgICByZXR1cm4gY29tYmluZUxhdGVzdChbXG4gICAgICAgICAgICBvZihwcmljaW5nVGllci5pc1N0YXJ0aW5nUHJpY2UpLFxuICAgICAgICAgICAgdGhpcy5idWlsZFByaWNpbmdUaWVyU3RyaW5nKHByaWNpbmdUaWVyKSxcbiAgICAgICAgICAgIHRoaXMuYnVpbGRQcmljaW5nVGllckZvclByb2R1Y3QocHJpY2luZ1RpZXIsIGJpbGxlZFByb2R1Y3QuYmlsbGluZ0ZyZXF1ZW5jeSksXG4gICAgICAgICAgICB0aGlzLmJ1aWxkUHJpY2luZ1RpZXJGb3JBZGRvbihwcmljaW5nVGllciksXG4gICAgICAgICAgICB0aGlzLmJ1aWxkUHJpY2VTdHJpbmdGb3JUaWVyKHByaWNpbmdUaWVyLCBiaWxsZWRQcm9kdWN0LmJpbGxpbmdGcmVxdWVuY3ksIHByaWNpbmdUaWVyLmlzU3RhcnRpbmdQcmljZSksXG4gICAgICAgICAgICB0aGlzLmJ1aWxkUHJpY2VTdHJpbmdGb3JUaWVyKHByaWNpbmdUaWVyKSxcbiAgICAgICAgICBdKS5waXBlKFxuICAgICAgICAgICAgbWFwKFxuICAgICAgICAgICAgICAoW1xuICAgICAgICAgICAgICAgIGlzU3RhcnRpbmdQcmljZSxcbiAgICAgICAgICAgICAgICBwcmljaW5nVGllclN0cmluZyxcbiAgICAgICAgICAgICAgICBwcmljaW5nVGllckZvclByb2R1Y3QsXG4gICAgICAgICAgICAgICAgcHJpY2luZ1RpZXJGb3JBZGRvbixcbiAgICAgICAgICAgICAgICBwcmljZVN0cmluZ0ZvclRpZXIsXG4gICAgICAgICAgICAgICAgcHJpY2VTdHJpbmdGb3JUaWVyV2l0aG91dEZyZXEsXG4gICAgICAgICAgICAgIF0pID0+IHtcbiAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgaXNTdGFydGluZ1ByaWNlOiBpc1N0YXJ0aW5nUHJpY2UsXG4gICAgICAgICAgICAgICAgICBwcmljaW5nVGllclN0cmluZzogcHJpY2luZ1RpZXJTdHJpbmcsXG4gICAgICAgICAgICAgICAgICBwcmljaW5nVGllckZvclByb2R1Y3Q6IHByaWNpbmdUaWVyRm9yUHJvZHVjdCxcbiAgICAgICAgICAgICAgICAgIHByaWNpbmdUaWVyRm9yQWRkb246IHByaWNpbmdUaWVyRm9yQWRkb24sXG4gICAgICAgICAgICAgICAgICBwcmljZVN0cmluZ0ZvclRpZXI6IHByaWNlU3RyaW5nRm9yVGllcixcbiAgICAgICAgICAgICAgICAgIHByaWNlU3RyaW5nRm9yVGllcldpdGhvdXRGcmVxOiBwcmljZVN0cmluZ0ZvclRpZXJXaXRob3V0RnJlcSxcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgKSxcbiAgICAgICAgICApO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIGNvbWJpbmVMYXRlc3QoWy4uLnByaWNpbmdUaWVyT2JzZXJ2YWJsZXNdKTtcbiAgICAgIH0pLFxuICAgICk7XG5cbiAgICB0aGlzLnByaWNlRGF0YSQgPSB0aGlzLnByaWNpbmckLnBpcGUoXG4gICAgICBzd2l0Y2hNYXAoKHByaWNpbmcpID0+IHtcbiAgICAgICAgbGV0IGZpbHRlcmVkUHJpY2VzID0gcHJpY2luZy5wcmljZXM7XG4gICAgICAgIGlmIChwcmljaW5nLnByaWNlcy5sZW5ndGggPiAxKSB7XG4gICAgICAgICAgZmlsdGVyZWRQcmljZXMgPSBwcmljaW5nLnByaWNlcy5maWx0ZXIoKHByaWNlKSA9PiBwcmljZS5wcmljZSA+IDApLnNvcnQodGhpcy5zb3J0UHJpY2VzQnlGcmVxdWVuY3kpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHByaWNlT2JzZXJ2YWJsZXMgPSBmaWx0ZXJlZFByaWNlcy5tYXAoKHByaWNlKSA9PiB7XG4gICAgICAgICAgcmV0dXJuIGNvbWJpbmVMYXRlc3QoW1xuICAgICAgICAgICAgb2YocHJpY2UuaXNTdGFydGluZ1ByaWNlKSxcbiAgICAgICAgICAgIHRoaXMuYnVpbGRQcmljZVN0cmluZ0ZvclByaWNpbmcocHJpY2UsIHByaWNpbmcuY3VycmVuY3ksIHRydWUsIGZhbHNlKSxcbiAgICAgICAgICAgIHRoaXMuYnVpbGRQcmljZVN0cmluZ0ZvclByaWNpbmcocHJpY2UsIHByaWNpbmcuY3VycmVuY3ksIGZhbHNlLCB0cnVlKSxcbiAgICAgICAgICAgIHRoaXMuYnVpbGRGcmVxdWVuY3lTdHJpbmcocHJpY2UuZnJlcXVlbmN5KSxcbiAgICAgICAgICAgIG9mKHRoaXMuYnVpbGRBYmJyZXZpYXRlZEZyZXF1ZW5jeVN0cmluZyhwcmljZS5mcmVxdWVuY3kpKSxcbiAgICAgICAgICBdKS5waXBlKFxuICAgICAgICAgICAgbWFwKFxuICAgICAgICAgICAgICAoW1xuICAgICAgICAgICAgICAgIGlzU3RhcnRpbmdQcmljZSxcbiAgICAgICAgICAgICAgICBwcmljZVN0cmluZ0ZvclByaWNpbmdXaXRob3V0RnJlcXVlbmN5LFxuICAgICAgICAgICAgICAgIHByaWNlU3RyaW5nRm9yUHJpY2luZ1dpdGhGcmVxdWVuY3ksXG4gICAgICAgICAgICAgICAgZnJlcXVlbmN5U3RyaW5nLFxuICAgICAgICAgICAgICAgIGFiYnJldkZyZXEsXG4gICAgICAgICAgICAgIF0pID0+IHtcbiAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgaXNTdGFydGluZ1ByaWNlOiBpc1N0YXJ0aW5nUHJpY2UsXG4gICAgICAgICAgICAgICAgICBwcmljZVN0cmluZ0ZvclByaWNpbmdXaXRob3V0RnJlcXVlbmN5OiBwcmljZVN0cmluZ0ZvclByaWNpbmdXaXRob3V0RnJlcXVlbmN5LFxuICAgICAgICAgICAgICAgICAgcHJpY2VTdHJpbmdGb3JQcmljaW5nV2l0aEZyZXF1ZW5jeTogcHJpY2VTdHJpbmdGb3JQcmljaW5nV2l0aEZyZXF1ZW5jeSxcbiAgICAgICAgICAgICAgICAgIGZyZXF1ZW5jeVN0cmluZzogZnJlcXVlbmN5U3RyaW5nLFxuICAgICAgICAgICAgICAgICAgYWJicmV2aWF0ZWRGcmVxdWVuY3lTdHJpbmc6IGFiYnJldkZyZXEsXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICksXG4gICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBjb21iaW5lTGF0ZXN0KFsuLi5wcmljZU9ic2VydmFibGVzXSk7XG4gICAgICB9KSxcbiAgICApO1xuXG4gICAgdGhpcy5jb21taXRtZW50TWVzc2FnZSQgPSB0aGlzLmJ1aWxkQ29tbWl0bWVudE1lc3NhZ2UoKTtcbiAgICB0aGlzLnNldHVwRmVlU3RyaW5nJCA9IHRoaXMuZGlzcGxheVByaWNlU2VydmljZS5nZXRTZXR1cEZlZVN0cmluZygpO1xuICAgIHRoaXMuaXNGaXJzdFRpZXJGcmVlJCA9IHRoaXMuYmlsbGVkUHJvZHVjdCQucGlwZShcbiAgICAgIG1hcCgoYmlsbGVkUHJvZHVjdCkgPT4ge1xuICAgICAgICByZXR1cm4gYmlsbGVkUHJvZHVjdC5wcmljaW5nVGllcnMubGVuZ3RoID4gMSAmJiBiaWxsZWRQcm9kdWN0LnByaWNpbmdUaWVycy5zb21lKChpdGVtKSA9PiBpdGVtLnByaWNlID09PSAwKTtcbiAgICAgIH0pLFxuICAgICk7XG4gIH1cblxuICBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKTogdm9pZCB7XG4gICAgaWYgKGNoYW5nZXMuaGFzT3duUHJvcGVydHkoJ3ByaWNpbmcnKSkge1xuICAgICAgdGhpcy5wcmljaW5nJCQubmV4dChjaGFuZ2VzLnByaWNpbmcuY3VycmVudFZhbHVlKTtcbiAgICB9XG4gICAgaWYgKGNoYW5nZXMuaGFzT3duUHJvcGVydHkoJ2JpbGxlZFByb2R1Y3QnKSkge1xuICAgICAgdGhpcy5iaWxsZWRQcm9kdWN0JCQubmV4dChjaGFuZ2VzLmJpbGxlZFByb2R1Y3QuY3VycmVudFZhbHVlKTtcbiAgICB9XG4gICAgaWYgKGNoYW5nZXMuaGFzT3duUHJvcGVydHkoJ2hhc1ZlcmlmaWVkQ29udHJhY3QnKSkge1xuICAgICAgdGhpcy5oYXNWZXJpZmllZENvbnRyYWN0JCQubmV4dChjaGFuZ2VzLmhhc1ZlcmlmaWVkQ29udHJhY3QuY3VycmVudFZhbHVlKTtcbiAgICB9XG4gIH1cblxuICBidWlsZFByaWNpbmdUaWVyU3RyaW5nKHRpZXI6IFByaWNpbmdUaWVyKTogT2JzZXJ2YWJsZTxzdHJpbmc+IHtcbiAgICBsZXQgbWF4ID0gU3RyaW5nKHRpZXIucmFuZ2VNYXgpO1xuICAgIGlmICh0aWVyLnJhbmdlTWF4ID09PSAtMSkge1xuICAgICAgbWF4ID0gJ+KInic7XG4gICAgICBpZiAodGllci5yYW5nZU1pbiA9PT0gMCB8fCB0aWVyLnJhbmdlTWluID09PSAxKSB7XG4gICAgICAgIHJldHVybiBvZignJyk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnRyYW5zbGF0ZVNlcnZpY2Uuc3RyZWFtKCdGUk9OVEVORC5TVE9SRS5NSU5fVE9fTUFYJywge1xuICAgICAgbWluUmFuZ2U6IFN0cmluZyh0aWVyLnJhbmdlTWluKSxcbiAgICAgIG1heFJhbmdlOiBtYXgsXG4gICAgfSk7XG4gIH1cblxuICBidWlsZFByaWNpbmdUaWVyRm9yUHJvZHVjdCh0aWVyOiBQcmljaW5nVGllciwgZnJlcXVlbmN5Pzogc3RyaW5nKTogT2JzZXJ2YWJsZTxzdHJpbmc+IHtcbiAgICByZXR1cm4gY29tYmluZUxhdGVzdChbdGhpcy5idWlsZFByaWNpbmdUaWVyU3RyaW5nKHRpZXIpLCB0aGlzLmJ1aWxkRnJlcXVlbmN5U3RyaW5nKGZyZXF1ZW5jeSldKS5waXBlKFxuICAgICAgc3dpdGNoTWFwKChbcHJpY2luZ1RpZXIsIGZvcm1hdHRlZEZyZXF1ZW5jeV0pID0+IHtcbiAgICAgICAgaWYgKHByaWNpbmdUaWVyKSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMudHJhbnNsYXRlU2VydmljZS5zdHJlYW0oJ0ZST05URU5ELlNUT1JFLlBST0RVQ1RfUFJJQ0lOR19XSVRIX0ZSRVFVRU5DWScsIHtcbiAgICAgICAgICAgIHByaWNpbmdUaWVyOiBwcmljaW5nVGllcixcbiAgICAgICAgICAgIGZyZXF1ZW5jeTogZm9ybWF0dGVkRnJlcXVlbmN5LFxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBvZihmb3JtYXR0ZWRGcmVxdWVuY3kpO1xuICAgICAgfSksXG4gICAgKTtcbiAgfVxuXG4gIGJ1aWxkUHJpY2luZ1RpZXJGb3JBZGRvbih0aWVyOiBQcmljaW5nVGllcik6IE9ic2VydmFibGU8c3RyaW5nPiB7XG4gICAgcmV0dXJuIHRoaXMuYnVpbGRQcmljaW5nVGllclN0cmluZyh0aWVyKS5waXBlKG1hcCgocHJpY2luZ1JhbmdlKSA9PiAocHJpY2luZ1JhbmdlID8gcHJpY2luZ1JhbmdlIDogJycpKSk7XG4gIH1cblxuICBzb3J0UHJpY2VzQnlGcmVxdWVuY3kocHJpY2VBOiBQcmljZSwgcHJpY2VCOiBQcmljZSk6IG51bWJlciB7XG4gICAgLy8gdGhpcyBtYXAgaXMgY29kZWQgYmFzZWQgb24gZnJlcXVlbmN5IHZhbHVlcyBkZXNjcmliZWQgYnkgdGhlIGVudW1zIGRlc2NyaWJlZCBpbiB0aGUgbWFya2V0cGxhY2UgcGFja2FnZXMgdmVuZGFzdGFcbiAgICAvLyBhcGlzIGFuZCB0aGUgY29ycmVzcG9uZGluZyB0cmFuc2xhdGlvbnMgdG8gc3RyaW5ncyBsYWNlZCB0aHJvdWdob3V0IGdhbGF4eVxuICAgIGNvbnN0IHByaWNlRnJlcXVlbmN5Q29tcGFyaXNvbk1hcDogTWFwPHN0cmluZywgTWFwPHN0cmluZywgbnVtYmVyPj4gPSBuZXcgTWFwPHN0cmluZywgTWFwPHN0cmluZywgbnVtYmVyPj4oW1xuICAgICAgW1xuICAgICAgICAnTU9OVEhMWScsXG4gICAgICAgIG5ldyBNYXAoW1xuICAgICAgICAgIFsnTU9OVEhMWScsIDBdLFxuICAgICAgICAgIFsnWUVBUkxZJywgLTFdLFxuICAgICAgICAgIFsnT05DRScsIC0xXSxcbiAgICAgICAgICBbJ09ORSBUSU1FJywgLTFdLFxuICAgICAgICAgIFsnT05FX1RJTUUnLCAtMV0sXG4gICAgICAgIF0pLFxuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ1lFQVJMWScsXG4gICAgICAgIG5ldyBNYXAoW1xuICAgICAgICAgIFsnTU9OVEhMWScsIDFdLFxuICAgICAgICAgIFsnWUVBUkxZJywgMF0sXG4gICAgICAgICAgWydPTkNFJywgLTFdLFxuICAgICAgICAgIFsnT05FIFRJTUUnLCAtMV0sXG4gICAgICAgICAgWydPTkVfVElNRScsIC0xXSxcbiAgICAgICAgXSksXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnT05DRScsXG4gICAgICAgIG5ldyBNYXAoW1xuICAgICAgICAgIFsnTU9OVEhMWScsIDFdLFxuICAgICAgICAgIFsnWUVBUkxZJywgMV0sXG4gICAgICAgICAgWydPTkNFJywgMF0sXG4gICAgICAgICAgWydPTkUgVElNRScsIDBdLFxuICAgICAgICAgIFsnT05FX1RJTUUnLCAwXSxcbiAgICAgICAgXSksXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnT05FIFRJTUUnLFxuICAgICAgICBuZXcgTWFwKFtcbiAgICAgICAgICBbJ01PTlRITFknLCAxXSxcbiAgICAgICAgICBbJ1lFQVJMWScsIDFdLFxuICAgICAgICAgIFsnT05DRScsIDBdLFxuICAgICAgICAgIFsnT05FIFRJTUUnLCAwXSxcbiAgICAgICAgICBbJ09ORV9USU1FJywgMF0sXG4gICAgICAgIF0pLFxuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ09ORV9USU1FJyxcbiAgICAgICAgbmV3IE1hcChbXG4gICAgICAgICAgWydNT05USExZJywgMV0sXG4gICAgICAgICAgWydZRUFSTFknLCAxXSxcbiAgICAgICAgICBbJ09OQ0UnLCAwXSxcbiAgICAgICAgICBbJ09ORSBUSU1FJywgMF0sXG4gICAgICAgICAgWydPTkVfVElNRScsIDBdLFxuICAgICAgICBdKSxcbiAgICAgIF0sXG4gICAgXSk7XG5cbiAgICBpZiAocHJpY2VGcmVxdWVuY3lDb21wYXJpc29uTWFwLmdldChwcmljZUEuZnJlcXVlbmN5LnRvVXBwZXJDYXNlKCkpID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiAwO1xuICAgIH1cblxuICAgIGNvbnN0IGNvbXBhcmVWYWwgPSBwcmljZUZyZXF1ZW5jeUNvbXBhcmlzb25NYXBcbiAgICAgIC5nZXQocHJpY2VBLmZyZXF1ZW5jeS50b1VwcGVyQ2FzZSgpKVxuICAgICAgLmdldChwcmljZUIuZnJlcXVlbmN5LnRvVXBwZXJDYXNlKCkpO1xuICAgIHJldHVybiBjb21wYXJlVmFsID8gY29tcGFyZVZhbCA6IDA7XG4gIH1cblxuICBidWlsZFByaWNlU3RyaW5nRm9yUHJpY2luZyhcbiAgICBwcmljZTogUHJpY2UsXG4gICAgY3VycmVuY3k6IHN0cmluZyxcbiAgICBleGNsdWRlRnJlcXVlbmN5OiBib29sZWFuLFxuICAgIGNhbkluY2x1ZGVTdGFydGluZ0F0UHJlZml4OiBib29sZWFuLFxuICApOiBPYnNlcnZhYmxlPHN0cmluZz4ge1xuICAgIHJldHVybiB0aGlzLmRpc3BsYXlQcmljZVNlcnZpY2UuZm9ybWF0RGlzcGxheVByaWNlKFxuICAgICAgcHJpY2UucHJpY2UsXG4gICAgICBjdXJyZW5jeSxcbiAgICAgIChleGNsdWRlRnJlcXVlbmN5ID8gJycgOiBwcmljZS5mcmVxdWVuY3kpIGFzIGFueSxcbiAgICAgIHRydWUsXG4gICAgICB0cnVlLFxuICAgICAgdHJ1ZSxcbiAgICAgIHByaWNlLmlzU3RhcnRpbmdQcmljZSAmJiBjYW5JbmNsdWRlU3RhcnRpbmdBdFByZWZpeCxcbiAgICApO1xuICB9XG5cbiAgYnVpbGRQcmljZVN0cmluZ0ZvclRpZXIoXG4gICAgdGllcjogUHJpY2luZ1RpZXIsXG4gICAgZnJlcXVlbmN5PzogTWFya2V0cGxhY2VCaWxsaW5nRnJlcXVlbmN5LFxuICAgIGlzU3RhcnRpbmdQcmljZT86IGJvb2xlYW4sXG4gICk6IE9ic2VydmFibGU8c3RyaW5nPiB7XG4gICAgcmV0dXJuIHRoaXMuZGlzcGxheVByaWNlU2VydmljZS5mb3JtYXREaXNwbGF5UHJpY2UoXG4gICAgICB0aWVyLnByaWNlLFxuICAgICAgdGhpcy5iaWxsZWRQcm9kdWN0LmN1cnJlbmN5LFxuICAgICAgZnJlcXVlbmN5IGFzIGFueSxcbiAgICAgIHVuZGVmaW5lZCxcbiAgICAgIHVuZGVmaW5lZCxcbiAgICAgIHVuZGVmaW5lZCxcbiAgICAgIGlzU3RhcnRpbmdQcmljZSxcbiAgICApO1xuICB9XG5cbiAgYnVpbGRGcmVxdWVuY3lTdHJpbmcoZnJlcXVlbmN5Pzogc3RyaW5nKTogT2JzZXJ2YWJsZTxzdHJpbmc+IHtcbiAgICByZXR1cm4gdGhpcy5kaXNwbGF5UHJpY2VTZXJ2aWNlLmZvcm1hdEJpbGxpbmdGcmVxdWVuY3koZnJlcXVlbmN5KTtcbiAgfVxuXG4gIGJ1aWxkQWJicmV2aWF0ZWRGcmVxdWVuY3lTdHJpbmcoZnJlcXVlbmN5Pzogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBzd2l0Y2ggKChmcmVxdWVuY3kgfHwgJycpLnRvTG93ZXJDYXNlKCkpIHtcbiAgICAgIGNhc2UgJ2RhaWx5JzpcbiAgICAgICAgcmV0dXJuICdkeSc7XG4gICAgICBjYXNlICd3ZWVrbHknOlxuICAgICAgICByZXR1cm4gJ3drJztcbiAgICAgIGNhc2UgJ21vbnRobHknOlxuICAgICAgICByZXR1cm4gJ21vJztcbiAgICAgIGNhc2UgJ3llYXJseSc6XG4gICAgICAgIHJldHVybiAneXInO1xuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIGJ1aWxkQ29tbWl0bWVudE1lc3NhZ2UoKTogT2JzZXJ2YWJsZTxzdHJpbmc+IHtcbiAgICByZXR1cm4gY29tYmluZUxhdGVzdChbXG4gICAgICB0aGlzLnRyYW5zbGF0ZVNlcnZpY2Uuc3RyZWFtKCdGUk9OVEVORC5TVE9SRS5QUklDSU5HX0ZSRVFVRU5DSUVTJyksXG4gICAgICB0aGlzLmJpbGxlZFByb2R1Y3QkLFxuICAgICAgdGhpcy5wcmljaW5nJCxcbiAgICAgIHRoaXMuaXNGcmVlJCxcbiAgICAgIHRoaXMuc2hvdWxkQ29udGFjdFNhbGVzJCxcbiAgICBdKS5waXBlKFxuICAgICAgc3dpdGNoTWFwKChbZnJlcXVlbmN5VHJhbnNsYXRpb25zLCBiaWxsZWRQcm9kdWN0LCBwcmljaW5nLCBpc0ZyZWUsIHNob3VsZENvbnRhY3RTYWxlc10pID0+IHtcbiAgICAgICAgY29uc3QgZnJlcXVlbmN5ID0gYmlsbGVkUHJvZHVjdFxuICAgICAgICAgID8gYmlsbGVkUHJvZHVjdC5iaWxsaW5nRnJlcXVlbmN5LnRvU3RyaW5nKCkudG9Mb3dlckNhc2UoKVxuICAgICAgICAgIDogcHJpY2luZyAmJiBwcmljaW5nLnByaWNlcy5sZW5ndGggPiAwXG4gICAgICAgICAgPyBwcmljaW5nLnByaWNlc1swXS5mcmVxdWVuY3kudG9Mb3dlckNhc2UoKVxuICAgICAgICAgIDogJyc7XG4gICAgICAgIGxldCBmcmVxdWVuY3lTdHJpbmcgPSAnJztcbiAgICAgICAgaWYgKGZyZXF1ZW5jeSA9PT0gJ3llYXJseScpIHtcbiAgICAgICAgICBmcmVxdWVuY3lTdHJpbmcgPSBmcmVxdWVuY3lUcmFuc2xhdGlvbnMuWUVBUjtcbiAgICAgICAgfSBlbHNlIGlmIChmcmVxdWVuY3kgPT09ICdtb250aGx5Jykge1xuICAgICAgICAgIGZyZXF1ZW5jeVN0cmluZyA9IGZyZXF1ZW5jeVRyYW5zbGF0aW9ucy5NT05USDtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIWZyZXF1ZW5jeVN0cmluZyB8fCBpc0ZyZWUgfHwgc2hvdWxkQ29udGFjdFNhbGVzKSB7XG4gICAgICAgICAgcmV0dXJuIG9mKCcnKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoYmlsbGVkUHJvZHVjdCAmJiBiaWxsZWRQcm9kdWN0LmNvbW1pdG1lbnQpIHtcbiAgICAgICAgICBjb25zdCBpbml0aWFsID0gYmlsbGVkUHJvZHVjdC5jb21taXRtZW50LmluaXRpYWw7XG4gICAgICAgICAgY29uc3QgcmV