ng-miam 6.4.13 → 7.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bundles/ng-miam.umd.js +8539 -10855
- package/bundles/ng-miam.umd.js.map +1 -1
- package/bundles/ng-miam.umd.min.js +2 -2
- package/bundles/ng-miam.umd.min.js.map +1 -1
- package/esm2015/lib/_components/abstracts/event-tracer.component.js +3 -2
- package/esm2015/lib/_components/accordion/accordion.component.js +75 -0
- package/esm2015/lib/_components/components.module.js +27 -21
- package/esm2015/lib/_components/counter-input/counter-input.component.js +86 -76
- package/esm2015/lib/_components/icon/icon.component.js +1 -1
- package/esm2015/lib/_components/index.js +5 -5
- package/esm2015/lib/_components/like-button/like-button.component.js +1 -1
- package/esm2015/lib/_components/list-input/list-input.component.js +5 -5
- package/esm2015/lib/_components/loader/loader.component.js +1 -1
- package/esm2015/lib/_components/meals-planner-link/meals-planner-link.component.js +3 -3
- package/esm2015/lib/_components/modal/modal.component.js +155 -137
- package/esm2015/lib/_components/product-card/product-card.component.js +333 -0
- package/esm2015/lib/_components/products-picker/products-picker.component.js +155 -0
- package/esm2015/lib/_components/progress-tracker/progress-tracker.component.js +1 -1
- package/esm2015/lib/_components/recipe-filters/recipe-filters.component.js +166 -217
- package/esm2015/lib/_components/recipe-pricing/recipe-pricing.component.js +55 -35
- package/esm2015/lib/_components/slider-tabs/slider-tabs.component.js +84 -0
- package/esm2015/lib/_components/sponsor-blocks/sponsor-image-and-text-block/sponsor-image-and-text-block.component.js +1 -1
- package/esm2015/lib/_components/sponsor-blocks/sponsor-text-and-image-block/sponsor-text-and-image-block.component.js +1 -1
- package/esm2015/lib/_components/tabs/tabs.component.js +48 -88
- package/esm2015/lib/_components/toaster/toaster.component.js +48 -84
- package/esm2015/lib/_components/tooltipable-content/tooltipable-content.component.js +1 -1
- package/esm2015/lib/_models/basket-entry.js +33 -49
- package/esm2015/lib/_models/basket-preview-line.js +5 -5
- package/esm2015/lib/_models/basket.js +15 -12
- package/esm2015/lib/_models/item.js +2 -2
- package/esm2015/lib/_models/recipe.js +2 -15
- package/esm2015/lib/_models/user.js +1 -1
- package/esm2015/lib/_services/analytics.service.js +24 -5
- package/esm2015/lib/_services/baskets-synchronizing/baskets-comparator.service.js +1 -10
- package/esm2015/lib/_services/baskets-synchronizing/baskets-synchronizer.service.js +15 -15
- package/esm2015/lib/_services/baskets.service.js +478 -60
- package/esm2015/lib/_services/context.service.js +22 -35
- package/esm2015/lib/_services/index.js +3 -5
- package/esm2015/lib/_services/interceptor.service.js +2 -2
- package/esm2015/lib/_services/items.service.js +27 -4
- package/esm2015/lib/_services/recipe-details.service.js +198 -0
- package/esm2015/lib/_services/recipe-likes.service.js +1 -1
- package/esm2015/lib/_services/recipes.service.js +24 -53
- package/esm2015/lib/_services/scrolling.service.js +17 -0
- package/esm2015/lib/_services/toaster.service.js +4 -5
- package/esm2015/lib/_services/user.service.js +2 -2
- package/esm2015/lib/_types/basket-action-type.enum.js +11 -0
- package/esm2015/lib/_types/basket-action.js +2 -0
- package/esm2015/lib/_types/basket-stats.js +2 -0
- package/esm2015/lib/_types/builded/miam-interface.js +1 -1
- package/esm2015/lib/_types/event-trace.js +5 -0
- package/esm2015/lib/_types/items-comparator.js +1 -10
- package/esm2015/lib/_types/recipe-filters.js +1 -1
- package/esm2015/lib/_types/toaster.js +1 -1
- package/esm2015/lib/_utils/directives/index.js +2 -1
- package/esm2015/lib/_utils/directives/reach-top.directive.js +33 -0
- package/esm2015/lib/_utils/pipes/readable-float-number/readable-float-number.pipe.js +8 -2
- package/esm2015/lib/_utils/utils.module.js +12 -8
- package/esm2015/lib/_web-components/basket-preview/basket-preview-block/basket-preview-block.component.js +140 -118
- package/esm2015/lib/_web-components/basket-preview/basket-preview-disabled/basket-preview-disabled.component.js +2 -2
- package/esm2015/lib/_web-components/basket-preview/basket-preview-line/basket-preview-line.component.js +125 -444
- package/esm2015/lib/_web-components/basket-preview/replace-item/replace-item.component.js +211 -108
- package/esm2015/lib/_web-components/index.js +1 -4
- package/esm2015/lib/_web-components/list-scan/basket-preview/basket-preview.component.js +11 -14
- package/esm2015/lib/_web-components/list-scan/files-inputs/files-inputs.component.js +13 -13
- package/esm2015/lib/_web-components/list-scan/ingredients-list/ingredients-list.component.js +6 -6
- package/esm2015/lib/_web-components/list-scan/list-scan.component.js +10 -10
- package/esm2015/lib/_web-components/list-scan/overlay-button/overlay-button.component.js +23 -11
- package/esm2015/lib/_web-components/meals-planner/meals-planner-basket-confirmation/meals-planner-basket-confirmation.component.js +1 -1
- package/esm2015/lib/_web-components/meals-planner/meals-planner-catalog/meals-planner-catalog.component.js +1 -1
- package/esm2015/lib/_web-components/meals-planner/meals-planner-form/meals-planner-form.component.js +7 -7
- package/esm2015/lib/_web-components/meals-planner/meals-planner-result/meals-planner-result.component.js +5 -5
- package/esm2015/lib/_web-components/meals-planner/meals-planner.component.js +16 -20
- package/esm2015/lib/_web-components/planner-side-menu/planner-side-menu.component.js +4 -53
- package/esm2015/lib/_web-components/recipe-cards/add-recipe-card/add-recipe-card.component.js +1 -1
- package/esm2015/lib/_web-components/recipe-cards/index.js +1 -3
- package/esm2015/lib/_web-components/recipe-cards/recipe-card/recipe-card.component.js +326 -404
- package/esm2015/lib/_web-components/recipe-cards/recipe-card-cta/recipe-card-cta.component.js +50 -146
- package/esm2015/lib/_web-components/recipe-cards/recipe-cards.module.js +3 -15
- package/esm2015/lib/_web-components/recipe-catalog/catalog-article-card/catalog-article-card.component.js +1 -1
- package/esm2015/lib/_web-components/recipe-catalog/catalog-category/catalog-category.component.js +35 -29
- package/esm2015/lib/_web-components/recipe-catalog/catalog-header/catalog-header.component.js +1 -1
- package/esm2015/lib/_web-components/recipe-catalog/catalog-list/catalog-list.component.js +27 -31
- package/esm2015/lib/_web-components/recipe-catalog/recipe-catalog.component.js +98 -100
- package/esm2015/lib/_web-components/recipe-creation/recipe-form/recipe-form.component.js +2 -2
- package/esm2015/lib/_web-components/recipe-creation/recipe-stepper/recipe-stepper.component.js +7 -7
- package/esm2015/lib/_web-components/recipe-creation/tags-creator/tags-creator.component.js +4 -4
- package/esm2015/lib/_web-components/recipe-creation/tags-selector/tags-selector.component.js +8 -8
- package/esm2015/lib/_web-components/recipe-details/recipe-addon/recipe-addon.component.js +7 -3
- package/esm2015/lib/_web-components/recipe-details/recipe-details-infos/recipe-details-infos.component.js +57 -358
- package/esm2015/lib/_web-components/recipe-details/recipe-details-ingredients/recipe-details-ingredients.component.js +59 -122
- package/esm2015/lib/_web-components/recipe-details/recipe-details-steps/recipe-details-steps.component.js +51 -72
- package/esm2015/lib/_web-components/recipe-details/recipe-details.component.js +313 -363
- package/esm2015/lib/_web-components/recipe-details/recipe-details.module.js +8 -4
- package/esm2015/lib/_web-components/recipe-details/sponsor-storytelling/sponsor-storytelling.component.js +1 -1
- package/esm2015/lib/_web-components/recipe-helper/recipe-helper.component.js +89 -113
- package/esm2015/lib/_web-components/recipe-modal/recipe-modal.component.js +78 -69
- package/esm2015/lib/_web-components/recipe-tags/recipe-tags.component.js +5 -5
- package/esm2015/lib/_web-components/toaster-stack/toaster-stack.component.js +8 -4
- package/esm2015/lib/_web-components/web-components.module.js +3 -19
- package/esm2015/lib/ng-miam.module.js +5 -7
- package/fesm2015/ng-miam.js +5165 -6973
- package/fesm2015/ng-miam.js.map +1 -1
- package/lib/_components/abstracts/event-tracer.component.d.ts +2 -1
- package/lib/_components/accordion/accordion.component.d.ts +23 -0
- package/lib/_components/components.module.d.ts +38 -36
- package/lib/_components/counter-input/counter-input.component.d.ts +12 -14
- package/lib/_components/index.d.ts +4 -4
- package/lib/_components/modal/modal.component.d.ts +18 -18
- package/lib/_components/product-card/product-card.component.d.ts +40 -0
- package/lib/_components/products-picker/products-picker.component.d.ts +17 -0
- package/lib/_components/recipe-pricing/recipe-pricing.component.d.ts +12 -8
- package/lib/_components/slider-tabs/slider-tabs.component.d.ts +16 -0
- package/lib/_components/tabs/tabs.component.d.ts +11 -11
- package/lib/_components/toaster/toaster.component.d.ts +4 -2
- package/lib/_models/basket-entry.d.ts +16 -20
- package/lib/_models/basket-preview-line.d.ts +1 -0
- package/lib/_models/basket.d.ts +12 -5
- package/lib/_models/item.d.ts +1 -1
- package/lib/_models/recipe.d.ts +0 -5
- package/lib/_models/user.d.ts +0 -1
- package/lib/_services/analytics.service.d.ts +8 -22
- package/lib/_services/baskets-synchronizing/baskets-comparator.service.d.ts +0 -5
- package/lib/_services/baskets-synchronizing/baskets-synchronizer.service.d.ts +3 -6
- package/lib/_services/baskets.service.d.ts +137 -18
- package/lib/_services/context.service.d.ts +2 -4
- package/lib/_services/index.d.ts +2 -4
- package/lib/_services/items.service.d.ts +9 -2
- package/lib/_services/recipe-details.service.d.ts +84 -0
- package/lib/_services/recipe-likes.service.d.ts +2 -1
- package/lib/_services/recipes.service.d.ts +10 -14
- package/lib/_services/scrolling.service.d.ts +8 -0
- package/lib/_services/toaster.service.d.ts +1 -1
- package/lib/_types/basket-action-type.enum.d.ts +9 -0
- package/lib/_types/basket-action.d.ts +14 -0
- package/lib/_types/basket-stats.d.ts +5 -0
- package/lib/_types/builded/miam-interface.d.ts +16 -25
- package/lib/_types/event-trace.d.ts +22 -0
- package/lib/_types/items-comparator.d.ts +0 -5
- package/lib/_types/recipe-filters.d.ts +0 -2
- package/lib/_types/toaster.d.ts +1 -1
- package/lib/_utils/directives/index.d.ts +1 -0
- package/lib/_utils/directives/reach-top.directive.d.ts +13 -0
- package/lib/_utils/pipes/readable-float-number/readable-float-number.pipe.d.ts +1 -1
- package/lib/_utils/utils.module.d.ts +2 -2
- package/lib/_web-components/basket-preview/basket-preview-block/basket-preview-block.component.d.ts +9 -8
- package/lib/_web-components/basket-preview/basket-preview-line/basket-preview-line.component.d.ts +11 -9
- package/lib/_web-components/basket-preview/replace-item/replace-item.component.d.ts +27 -20
- package/lib/_web-components/index.d.ts +0 -3
- package/lib/_web-components/list-scan/basket-preview/basket-preview.component.d.ts +1 -2
- package/lib/_web-components/list-scan/files-inputs/files-inputs.component.d.ts +6 -5
- package/lib/_web-components/list-scan/ingredients-list/ingredients-list.component.d.ts +3 -3
- package/lib/_web-components/list-scan/list-scan.component.d.ts +3 -3
- package/lib/_web-components/list-scan/overlay-button/overlay-button.component.d.ts +8 -6
- package/lib/_web-components/meals-planner/meals-planner.component.d.ts +2 -3
- package/lib/_web-components/recipe-cards/index.d.ts +0 -2
- package/lib/_web-components/recipe-cards/recipe-card/recipe-card.component.d.ts +58 -17
- package/lib/_web-components/recipe-cards/recipe-card-cta/recipe-card-cta.component.d.ts +5 -12
- package/lib/_web-components/recipe-cards/recipe-cards.module.d.ts +7 -9
- package/lib/_web-components/recipe-catalog/catalog-category/catalog-category.component.d.ts +8 -6
- package/lib/_web-components/recipe-catalog/catalog-list/catalog-list.component.d.ts +7 -4
- package/lib/_web-components/recipe-catalog/recipe-catalog.component.d.ts +2 -3
- package/lib/_web-components/recipe-details/recipe-addon/recipe-addon.component.d.ts +5 -2
- package/lib/_web-components/recipe-details/recipe-details-infos/recipe-details-infos.component.d.ts +6 -18
- package/lib/_web-components/recipe-details/recipe-details-ingredients/recipe-details-ingredients.component.d.ts +6 -13
- package/lib/_web-components/recipe-details/recipe-details-steps/recipe-details-steps.component.d.ts +2 -10
- package/lib/_web-components/recipe-details/recipe-details.component.d.ts +29 -36
- package/lib/_web-components/recipe-details/recipe-details.module.d.ts +2 -1
- package/lib/_web-components/recipe-helper/recipe-helper.component.d.ts +2 -6
- package/lib/_web-components/recipe-modal/recipe-modal.component.d.ts +11 -9
- package/lib/_web-components/toaster-stack/toaster-stack.component.d.ts +5 -2
- package/lib/_web-components/web-components.module.d.ts +23 -29
- package/miam-style.css +1 -1
- package/package.json +1 -1
- package/esm2015/lib/_components/abstracts/abstract-recipe-card.component.js +0 -130
- package/esm2015/lib/_components/skeleton/skeleton.component.js +0 -70
- package/esm2015/lib/_components/tabs/tab-body.component.js +0 -30
- package/esm2015/lib/_components/tabs/tab-item.component.js +0 -36
- package/esm2015/lib/_components/tabs/tab-label.component.js +0 -30
- package/esm2015/lib/_models/groceries-entry.js +0 -42
- package/esm2015/lib/_models/groceries-list.js +0 -36
- package/esm2015/lib/_services/counter.service.js +0 -20
- package/esm2015/lib/_services/groceries-entries.service.js +0 -21
- package/esm2015/lib/_services/groceries-lists.service.js +0 -240
- package/esm2015/lib/_services/recipe-events.service.js +0 -63
- package/esm2015/lib/_types/skeleton.enum.js +0 -7
- package/esm2015/lib/_web-components/drawer/drawer.component.js +0 -273
- package/esm2015/lib/_web-components/pos-card/pos-card.component.js +0 -207
- package/esm2015/lib/_web-components/pos-selection/pos-selection.component.js +0 -283
- package/esm2015/lib/_web-components/recipe-cards/catalog-recipe-card/catalog-recipe-card.component.js +0 -632
- package/esm2015/lib/_web-components/recipe-cards/suggestion-card/suggestion-card.component.js +0 -144
- package/lib/_components/abstracts/abstract-recipe-card.component.d.ts +0 -49
- package/lib/_components/skeleton/skeleton.component.d.ts +0 -11
- package/lib/_components/tabs/tab-body.component.d.ts +0 -8
- package/lib/_components/tabs/tab-item.component.d.ts +0 -11
- package/lib/_components/tabs/tab-label.component.d.ts +0 -8
- package/lib/_models/groceries-entry.d.ts +0 -20
- package/lib/_models/groceries-list.d.ts +0 -30
- package/lib/_services/counter.service.d.ts +0 -10
- package/lib/_services/groceries-entries.service.d.ts +0 -10
- package/lib/_services/groceries-lists.service.d.ts +0 -68
- package/lib/_services/recipe-events.service.d.ts +0 -23
- package/lib/_types/skeleton.enum.d.ts +0 -5
- package/lib/_web-components/drawer/drawer.component.d.ts +0 -37
- package/lib/_web-components/pos-card/pos-card.component.d.ts +0 -24
- package/lib/_web-components/pos-selection/pos-selection.component.d.ts +0 -38
- package/lib/_web-components/recipe-cards/catalog-recipe-card/catalog-recipe-card.component.d.ts +0 -49
- package/lib/_web-components/recipe-cards/suggestion-card/suggestion-card.component.d.ts +0 -42
|
@@ -1,36 +1,40 @@
|
|
|
1
1
|
import { HttpClient } from '@angular/common/http';
|
|
2
2
|
import { Injectable } from '@angular/core';
|
|
3
|
-
import {
|
|
3
|
+
import { flatten, unionBy } from 'lodash-es';
|
|
4
4
|
import { Service } from 'ngx-jsonapi';
|
|
5
|
-
import { BehaviorSubject,
|
|
6
|
-
import {
|
|
7
|
-
import { Basket } from '../_models
|
|
8
|
-
import {
|
|
5
|
+
import { BehaviorSubject, forkJoin, of } from 'rxjs';
|
|
6
|
+
import { debounceTime, map, skipWhile, switchMap, take, tap } from 'rxjs/operators';
|
|
7
|
+
import { Basket, BasketPreviewLine } from '../_models';
|
|
8
|
+
import { BasketActionType } from '../_types/basket-action-type.enum';
|
|
9
|
+
import { MessageType } from '../_types/message-type.enum';
|
|
9
10
|
import { environment as e } from '../environments/environment';
|
|
10
11
|
import { AnalyticsService } from './analytics.service';
|
|
11
12
|
import { BasketEntriesService } from './basket-entries.service';
|
|
12
|
-
import { GroceriesEntriesService } from './groceries-entries.service';
|
|
13
|
-
import { GroceriesListsService } from './groceries-lists.service';
|
|
14
13
|
import { PointOfSalesService } from './point-of-sales.service';
|
|
15
14
|
import { RecipesService } from './recipes.service';
|
|
15
|
+
import { ToasterService } from './toaster.service';
|
|
16
|
+
import { UserService } from './user.service';
|
|
16
17
|
import * as i0 from "@angular/core";
|
|
17
18
|
import * as i1 from "@angular/common/http";
|
|
18
19
|
import * as i2 from "./basket-entries.service";
|
|
19
|
-
import * as i3 from "./
|
|
20
|
-
import * as i4 from "./
|
|
21
|
-
import * as i5 from "./
|
|
22
|
-
import * as i6 from "./
|
|
23
|
-
import * as i7 from "./
|
|
20
|
+
import * as i3 from "./point-of-sales.service";
|
|
21
|
+
import * as i4 from "./recipes.service";
|
|
22
|
+
import * as i5 from "./analytics.service";
|
|
23
|
+
import * as i6 from "./user.service";
|
|
24
|
+
import * as i7 from "./toaster.service";
|
|
25
|
+
const BASKET_SPARSE_FIELDS = {
|
|
26
|
+
baskets: ['total-price', 'pricebook-key', 'recipes-infos', 'completion']
|
|
27
|
+
};
|
|
24
28
|
export class BasketsService extends Service {
|
|
25
|
-
constructor(http, basketEntriesService,
|
|
29
|
+
constructor(http, basketEntriesService, posService, recipesService, analyticsService, usersService, toasterService) {
|
|
26
30
|
super();
|
|
27
31
|
this.http = http;
|
|
28
32
|
this.basketEntriesService = basketEntriesService;
|
|
29
|
-
this.listsService = listsService;
|
|
30
|
-
this.groceriesEntriesService = groceriesEntriesService;
|
|
31
33
|
this.posService = posService;
|
|
32
34
|
this.recipesService = recipesService;
|
|
33
35
|
this.analyticsService = analyticsService;
|
|
36
|
+
this.usersService = usersService;
|
|
37
|
+
this.toasterService = toasterService;
|
|
34
38
|
this.resource = Basket;
|
|
35
39
|
this.type = 'baskets';
|
|
36
40
|
this._basket$ = new BehaviorSubject(null);
|
|
@@ -39,9 +43,18 @@ export class BasketsService extends Service {
|
|
|
39
43
|
this.basketIsFetching = false;
|
|
40
44
|
this.basketPreviewIsCalculating = false;
|
|
41
45
|
this.basketInitCalled = false;
|
|
46
|
+
this.basketActionsQueue = new BehaviorSubject([]);
|
|
42
47
|
this._entries$ = new BehaviorSubject([]);
|
|
48
|
+
this.actionsBeingProcessed = new BehaviorSubject([]);
|
|
49
|
+
this.actionsBeingOverriden = [];
|
|
50
|
+
this.subscriptions = [];
|
|
43
51
|
this.register();
|
|
52
|
+
this.subscriptions.push(this.basketActionsQueue.pipe(debounceTime(200), skipWhile(actions => actions.length === 0 || this.actionsBeingProcessed.value.length > 0), tap(() => this.emptyActionsQueue())).subscribe());
|
|
53
|
+
if (this.recipesService.confirmationToaster) {
|
|
54
|
+
this.showRecipeAddedToaster();
|
|
55
|
+
}
|
|
44
56
|
}
|
|
57
|
+
/** ************************************************************ GETTERS ************************************************************ **/
|
|
45
58
|
/**
|
|
46
59
|
* We want basket$ to be a singleton that always returns the same basket, so it is fetched only when necessary.
|
|
47
60
|
* At any point in time the basket can be fetched via the initBasket function (if we want to fetch it on startup to save time later)
|
|
@@ -65,19 +78,82 @@ export class BasketsService extends Service {
|
|
|
65
78
|
}
|
|
66
79
|
return this._basketPreview$;
|
|
67
80
|
}
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
81
|
+
/**
|
|
82
|
+
* To use when needing to be sure that basket was fetched before doing an action that doesn't need to stay subscribed to basket$
|
|
83
|
+
* This method is meant to be an equivalent of basket$.value but asynchronous
|
|
84
|
+
*/
|
|
85
|
+
get waitForBasket() {
|
|
86
|
+
return this.basket$.pipe(skipWhile(b => !b), take(1));
|
|
87
|
+
}
|
|
88
|
+
/** ************************************** QUEUE UTILS TO LOCK MORE ACTIONS OR DISPLAY LOADERS ************************************** **/
|
|
89
|
+
// Util method to avoid repeating too much for the next 6 methods
|
|
90
|
+
subjectContainsRecipeId(subject, type, recipeId) {
|
|
91
|
+
return subject.pipe(map(value => value.some(a => a.type === type && a.params.recipeId === recipeId)));
|
|
92
|
+
}
|
|
93
|
+
// Util method to avoid repeating too much for the next 6 methods
|
|
94
|
+
subjectContainsIngredientId(subject, type, ingredientId) {
|
|
95
|
+
return subject.pipe(map(value => value.some(a => a.type === type && a.params.ingredientId === ingredientId)));
|
|
96
|
+
}
|
|
97
|
+
recipeWillBeAdded(recipeId) {
|
|
98
|
+
return this.subjectContainsRecipeId(this.basketActionsQueue, BasketActionType.ADD_RECIPE, recipeId);
|
|
99
|
+
}
|
|
100
|
+
recipeWillBeRemoved(recipeId) {
|
|
101
|
+
return this.subjectContainsRecipeId(this.basketActionsQueue, BasketActionType.REMOVE_RECIPE, recipeId);
|
|
102
|
+
}
|
|
103
|
+
recipeWillBeUpdated(recipeId) {
|
|
104
|
+
return this.subjectContainsRecipeId(this.basketActionsQueue, BasketActionType.UPDATE_RECIPE, recipeId);
|
|
105
|
+
}
|
|
106
|
+
recipeIsBeingAdded(recipeId) {
|
|
107
|
+
return this.subjectContainsRecipeId(this.actionsBeingProcessed, BasketActionType.ADD_RECIPE, recipeId);
|
|
108
|
+
}
|
|
109
|
+
recipeIsBeingRemoved(recipeId) {
|
|
110
|
+
return this.subjectContainsRecipeId(this.actionsBeingProcessed, BasketActionType.REMOVE_RECIPE, recipeId);
|
|
111
|
+
}
|
|
112
|
+
recipeIsBeingUpdated(recipeId) {
|
|
113
|
+
return this.subjectContainsRecipeId(this.actionsBeingProcessed, BasketActionType.UPDATE_RECIPE, recipeId);
|
|
114
|
+
}
|
|
115
|
+
ingredientWillBeAdded(ingredientId) {
|
|
116
|
+
return this.subjectContainsIngredientId(this.basketActionsQueue, BasketActionType.ADD_PRODUCT, ingredientId);
|
|
117
|
+
}
|
|
118
|
+
ingredientWillBeRemoved(ingredientId) {
|
|
119
|
+
return this.subjectContainsIngredientId(this.basketActionsQueue, BasketActionType.REMOVE_PRODUCT, ingredientId);
|
|
120
|
+
}
|
|
121
|
+
recipesWillBeAdded() {
|
|
122
|
+
return this.basketActionsQueue.pipe(map(queue => queue.some(a => a.type === BasketActionType.ADD_RECIPE)));
|
|
123
|
+
}
|
|
124
|
+
recipesWillBeRemoved() {
|
|
125
|
+
return this.basketActionsQueue.pipe(map(queue => queue.some(a => a.type === BasketActionType.REMOVE_RECIPE)));
|
|
126
|
+
}
|
|
127
|
+
recipesWillBeUpdated() {
|
|
128
|
+
return this.basketActionsQueue.pipe(map(queue => queue.some(a => a.type === BasketActionType.UPDATE_RECIPE)));
|
|
129
|
+
}
|
|
130
|
+
productsWillBeAdded() {
|
|
131
|
+
return this.basketActionsQueue.pipe(map(queue => queue.filter(a => a.type === BasketActionType.ADD_PRODUCT).length));
|
|
132
|
+
}
|
|
133
|
+
/** ************************************************************* UTILS ************************************************************* **/
|
|
134
|
+
// Check if the recipeId is in the Basket's recipes-infos
|
|
135
|
+
recipeIsInBasket(recipeId) {
|
|
136
|
+
return this.basket$.pipe(skipWhile(b => !b), map(basket => basket.hasRecipe(recipeId)));
|
|
137
|
+
}
|
|
138
|
+
guestsForRecipe(recipeId) {
|
|
139
|
+
var _a;
|
|
140
|
+
return (_a = this.basket$.value) === null || _a === void 0 ? void 0 : _a.guestsForRecipe(recipeId);
|
|
141
|
+
}
|
|
142
|
+
showRecipeAddedToaster() {
|
|
143
|
+
let previousNumberOfProductToAdd = 0;
|
|
144
|
+
this.subscriptions.push(this.productsWillBeAdded().pipe(skipWhile(number => previousNumberOfProductToAdd === number)).subscribe(number => {
|
|
145
|
+
if (previousNumberOfProductToAdd > number) {
|
|
146
|
+
const article = previousNumberOfProductToAdd - number === 1 ? 'article ajouté' : 'articles ajoutés';
|
|
147
|
+
const msg = `${previousNumberOfProductToAdd - number} ${article} à votre panier`;
|
|
148
|
+
this.toasterService.show(MessageType.Success, msg, '', false);
|
|
149
|
+
}
|
|
150
|
+
previousNumberOfProductToAdd = number;
|
|
79
151
|
}));
|
|
80
152
|
}
|
|
153
|
+
/** ***************************************************** LOAD / RELOAD / RESET ***************************************************** **/
|
|
154
|
+
reloadBasket() {
|
|
155
|
+
return this.refreshCurrentBasket().pipe(take(1));
|
|
156
|
+
}
|
|
81
157
|
initBasket() {
|
|
82
158
|
if (!this.basketInitCalled) {
|
|
83
159
|
this.basketInitCalled = true;
|
|
@@ -85,21 +161,39 @@ export class BasketsService extends Service {
|
|
|
85
161
|
this.loadPreview().subscribe();
|
|
86
162
|
}
|
|
87
163
|
}
|
|
88
|
-
|
|
89
|
-
return this.
|
|
164
|
+
refreshCurrentBasket() {
|
|
165
|
+
return this.posService.pos$.pipe(skipWhile(pos => !pos), take(1), switchMap(pos => {
|
|
166
|
+
console.log('[Miam] refreshing basket');
|
|
167
|
+
const cachedBasketId = localStorage.getItem('_miam/basketId');
|
|
168
|
+
const baseRoute = 'current?point_of_sale_id=' + pos.id;
|
|
169
|
+
const endpoint = ((cachedBasketId === null || cachedBasketId === void 0 ? void 0 : cachedBasketId.toString().match(/^[0-9]+$/)) ? baseRoute + '&merge_with=' + cachedBasketId : baseRoute) +
|
|
170
|
+
`&fields[baskets]=${BASKET_SPARSE_FIELDS.baskets.join(',')}`;
|
|
171
|
+
// Cancel last subscription before starting another one
|
|
172
|
+
if (this.currentSubscription) {
|
|
173
|
+
this.currentSubscription.unsubscribe();
|
|
174
|
+
}
|
|
175
|
+
this.currentSubscription = this.get(endpoint).pipe(skipWhile(basket => basket.is_loading), switchMap(basket => this.updateLocalBasket(basket))).subscribe();
|
|
176
|
+
return this._basket$;
|
|
177
|
+
}));
|
|
90
178
|
}
|
|
179
|
+
resetBasket(eventTrace = { originPath: '', props: {} }) {
|
|
180
|
+
console.log('[Miam] resetting basket');
|
|
181
|
+
this.analyticsService.sendEventWhenReady(this.analyticsService.EVENT_RECIPE_RESET, eventTrace.originPath, eventTrace.props);
|
|
182
|
+
return this.posService.pos$.pipe(skipWhile(pos => !pos), take(1), switchMap(pos => this.waitForBasket.pipe(tap(basket => this.analyticsService.sendEventsOfResetBasket(basket, eventTrace)), switchMap(() => this.get(`reset?point_of_sale_id=${pos.id}&fields[baskets]=${BASKET_SPARSE_FIELDS.baskets.join(',')}`).pipe(skipWhile(basket => basket.is_loading), switchMap(basket => this.updateLocalBasket(basket)))))));
|
|
183
|
+
}
|
|
184
|
+
/** ********************************************************* CONFIRM BASKET ********************************************************* **/
|
|
91
185
|
// Set basket as confirmed, and returns only once the new current list is returned
|
|
92
186
|
confirmBasket(totalPrice) {
|
|
93
187
|
let confirmedBasket;
|
|
94
188
|
console.log(`[Miam] Confirm basket ${JSON.stringify(confirmedBasket)}`);
|
|
95
|
-
return this.
|
|
189
|
+
return this.waitForBasket.pipe(tap(basket => {
|
|
96
190
|
if (basket.totalPrice > 0) {
|
|
97
191
|
this.analyticsService.sendEventWhenReady(this.analyticsService.EVENT_PAYMENT_CONFIRMED, null, this.eventProps(basket, totalPrice));
|
|
98
192
|
}
|
|
99
193
|
}), switchMap(basket => {
|
|
100
194
|
console.log('[Miam] Save basket with confirmed=true');
|
|
101
195
|
basket.attributes.confirmed = true;
|
|
102
|
-
return basket.save();
|
|
196
|
+
return basket.save({ fields: { baskets: [...BASKET_SPARSE_FIELDS.baskets, ...['token']] } });
|
|
103
197
|
}), switchMap((resp) => {
|
|
104
198
|
confirmedBasket = this.new();
|
|
105
199
|
confirmedBasket.fill(resp);
|
|
@@ -108,7 +202,7 @@ export class BasketsService extends Service {
|
|
|
108
202
|
this.analyticsService.sendEventWhenReady(this.analyticsService.EVENT_BASKET_CONFIRMED, null, this.eventProps(confirmedBasket, totalPrice));
|
|
109
203
|
}
|
|
110
204
|
this._basket$.next(undefined);
|
|
111
|
-
return this.
|
|
205
|
+
return this.resetBasket();
|
|
112
206
|
}), switchMap(() => this._basket$), skipWhile(b => !b), map(() => confirmedBasket));
|
|
113
207
|
}
|
|
114
208
|
eventProps(basket, totalPrice) {
|
|
@@ -121,11 +215,12 @@ export class BasketsService extends Service {
|
|
|
121
215
|
total_amount: totalPrice
|
|
122
216
|
};
|
|
123
217
|
}
|
|
218
|
+
/** ******************************************************* ACTIONS ON ENTRIES ******************************************************* **/
|
|
124
219
|
basketEntries() {
|
|
125
220
|
return this._entries$;
|
|
126
221
|
}
|
|
127
222
|
activeBasketEntries() {
|
|
128
|
-
return this.basketEntries().pipe(map((entries) => entries.filter(entry => entry.
|
|
223
|
+
return this.basketEntries().pipe(map((entries) => entries.filter(entry => entry.status === 'active')));
|
|
129
224
|
}
|
|
130
225
|
// Decrease quantity on a list of basket entries
|
|
131
226
|
// If the quantity goes below 1, the corresponding groceries entry's status gets deleted
|
|
@@ -146,39 +241,363 @@ export class BasketsService extends Service {
|
|
|
146
241
|
}
|
|
147
242
|
else {
|
|
148
243
|
basketEntry.quantity = 1;
|
|
149
|
-
basketEntry.
|
|
150
|
-
return forkJoin([basketEntry.save(), basketEntry.
|
|
244
|
+
basketEntry.status = 'deleted';
|
|
245
|
+
return forkJoin([basketEntry.save(), basketEntry.save()]);
|
|
151
246
|
}
|
|
152
247
|
});
|
|
153
|
-
return forkJoin(saveObservables).pipe(switchMap(() => this.
|
|
248
|
+
return forkJoin(saveObservables).pipe(switchMap(() => this.refreshCurrentBasket()), take(1));
|
|
154
249
|
}
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
250
|
+
/**
|
|
251
|
+
* Fetches the BasketEntry for an ingredient if it exists
|
|
252
|
+
* Returns a fake BasketEntry with id = -1 if it doesn't exist
|
|
253
|
+
*/
|
|
254
|
+
basketEntryFromIngredient(ingredientId) {
|
|
255
|
+
return this.waitForBasket.pipe(switchMap(basket => {
|
|
256
|
+
const url = `${e.miamAPI}/api/v1/baskets/${basket.id}/basket-entries/from-ingredient?ingredient_id=${ingredientId}`;
|
|
257
|
+
return this.http.get(url, { params: { include: ['selected-item'] } });
|
|
258
|
+
}), skipWhile(result => result.is_loading || !result), map(res => {
|
|
259
|
+
const entry = this.basketEntriesService.new();
|
|
260
|
+
entry.fill(res);
|
|
261
|
+
return entry;
|
|
159
262
|
}));
|
|
160
263
|
}
|
|
264
|
+
/** *********************************************************** PRICEBOOK *********************************************************** **/
|
|
161
265
|
// will patch basket with given pricebookName
|
|
162
266
|
// Api will look for prices (pos items) corresponding to this pricebook key
|
|
163
267
|
// fall case to a default pricebook
|
|
164
268
|
updatePricebook(pricebookName) {
|
|
165
|
-
return this.
|
|
269
|
+
return this.waitForBasket.pipe(switchMap(basket => {
|
|
166
270
|
if (basket.pricebookKey === pricebookName) {
|
|
167
271
|
console.log(`[Miam] same pricebook ${JSON.stringify(pricebookName)}`);
|
|
168
|
-
return of(
|
|
272
|
+
return of();
|
|
169
273
|
}
|
|
170
274
|
console.log(`[Miam] update pricebook to ${JSON.stringify(pricebookName)}`);
|
|
171
275
|
basket.pricebookKey = pricebookName;
|
|
172
|
-
return basket.save().pipe(
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
276
|
+
return basket.save({ fields: BASKET_SPARSE_FIELDS }).pipe(switchMap((resp) => {
|
|
277
|
+
this.fillBasket(resp);
|
|
278
|
+
return this.loadPreview();
|
|
279
|
+
}));
|
|
280
|
+
}));
|
|
281
|
+
}
|
|
282
|
+
/** ******************************************************** ADD FROM PICTURE ******************************************************** **/
|
|
283
|
+
addEntriesFromPicture(file, include = [], disableIngredientsMatching = false) {
|
|
284
|
+
return this.waitForBasket.pipe(switchMap(basket => {
|
|
285
|
+
const url = `${e.miamAPI}/api/v1/baskets/${basket.id}/add_entries_from_picture` +
|
|
286
|
+
`?fields[baskets]=${BASKET_SPARSE_FIELDS.baskets.join(',')}${(disableIngredientsMatching ? '&disable_matching=true' : '')}`;
|
|
287
|
+
const formData = new FormData();
|
|
288
|
+
formData.append('picture', file);
|
|
289
|
+
formData.append('include', include.join(','));
|
|
290
|
+
return this.http.patch(url, formData).pipe(map((response) => this.fillBasket(response)));
|
|
291
|
+
}));
|
|
292
|
+
}
|
|
293
|
+
/** **************************************************** ADD ACTIONS TO THE QUEUE **************************************************** **/
|
|
294
|
+
/**
|
|
295
|
+
* Adds recipes to the basket action to queue.
|
|
296
|
+
*
|
|
297
|
+
* @param recipeIds - The array of recipe IDs to add.
|
|
298
|
+
* @param guests - The number of guests.
|
|
299
|
+
* @param eventTrace - The event trace.
|
|
300
|
+
* @param withIngredients - Whether to include ingredients. Default is true.
|
|
301
|
+
* @return This function does not return anything.
|
|
302
|
+
*/
|
|
303
|
+
addRecipesToBasket(recipeIds, guests, eventTrace, withIngredients = true) {
|
|
304
|
+
const toAdd = this.basketActionsQueue.value;
|
|
305
|
+
recipeIds.forEach(recipeId => toAdd.push({
|
|
306
|
+
type: withIngredients ? BasketActionType.ADD_RECIPE : BasketActionType.ADD_RECIPE_LIGHT,
|
|
307
|
+
params: { recipeId, eventTrace, guests }
|
|
308
|
+
}));
|
|
309
|
+
this.basketActionsQueue.next(toAdd);
|
|
310
|
+
}
|
|
311
|
+
removeRecipesFromBasket(recipeIds, eventTrace) {
|
|
312
|
+
const toRemove = this.basketActionsQueue.value;
|
|
313
|
+
recipeIds.forEach(recipeId => toRemove.push({
|
|
314
|
+
type: BasketActionType.REMOVE_RECIPE,
|
|
315
|
+
params: { recipeId, eventTrace }
|
|
316
|
+
}));
|
|
317
|
+
this.basketActionsQueue.next(toRemove);
|
|
318
|
+
}
|
|
319
|
+
updateRecipesInBasket(recipeIds, guests, eventTrace) {
|
|
320
|
+
const toUpdate = this.basketActionsQueue.value;
|
|
321
|
+
recipeIds.forEach(recipeId => toUpdate.push({
|
|
322
|
+
type: BasketActionType.UPDATE_RECIPE,
|
|
323
|
+
params: { recipeId, eventTrace, guests }
|
|
324
|
+
}));
|
|
325
|
+
this.basketActionsQueue.next(toUpdate);
|
|
326
|
+
}
|
|
327
|
+
addIngredientsToBasket(recipeId, ingredientIdsAndEntries, eventTrace) {
|
|
328
|
+
const toAdd = this.basketActionsQueue.value;
|
|
329
|
+
ingredientIdsAndEntries.forEach(ingredientIdAndEntry => toAdd.push({
|
|
330
|
+
type: BasketActionType.ADD_PRODUCT,
|
|
331
|
+
params: { recipeId, ingredientId: ingredientIdAndEntry.ingredientId, basketEntry: ingredientIdAndEntry.entry, eventTrace }
|
|
332
|
+
}));
|
|
333
|
+
this.basketActionsQueue.next(toAdd);
|
|
334
|
+
}
|
|
335
|
+
removeIngredientsFromBasket(basketEntry, recipeId, ingredientIds, eventTrace) {
|
|
336
|
+
const toRemove = this.basketActionsQueue.value;
|
|
337
|
+
ingredientIds.forEach(ingredientId => toRemove.push({
|
|
338
|
+
type: BasketActionType.REMOVE_PRODUCT,
|
|
339
|
+
params: { basketEntry, recipeId, ingredientId, eventTrace }
|
|
340
|
+
}));
|
|
341
|
+
this.basketActionsQueue.next(toRemove);
|
|
342
|
+
}
|
|
343
|
+
changeProductQuantity(basketEntry, recipeId, newQuantity, eventTrace) {
|
|
344
|
+
const toUpdate = this.basketActionsQueue.value;
|
|
345
|
+
toUpdate.push({
|
|
346
|
+
type: BasketActionType.UPDATE_PRODUCT,
|
|
347
|
+
params: { basketEntry, recipeId, newQuantity, eventTrace }
|
|
348
|
+
});
|
|
349
|
+
this.basketActionsQueue.next(toUpdate);
|
|
350
|
+
}
|
|
351
|
+
/** *************************************************** PROCESS THE ACTIONS QUEUE *************************************************** **/
|
|
352
|
+
emptyActionsQueue() {
|
|
353
|
+
if (this.basketActionsQueue.value.length > 0) {
|
|
354
|
+
const actionsToProcess = this.nextActionsBatch();
|
|
355
|
+
this.actionsBeingProcessed.next([...actionsToProcess]);
|
|
356
|
+
if (actionsToProcess.length > 0) {
|
|
357
|
+
this.processActionsBatch(actionsToProcess).subscribe(() => {
|
|
358
|
+
this.actionsBeingProcessed.next([]);
|
|
359
|
+
this.basketActionsQueue.next(this.basketActionsQueue.value.filter(i => !actionsToProcess.includes(i) && !this.actionsBeingOverriden.includes(i)));
|
|
360
|
+
this.actionsBeingOverriden = [];
|
|
361
|
+
});
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
/**
|
|
366
|
+
* If multiple actions of the same type are next to each other in the queue, we want to process them as a batch.
|
|
367
|
+
* @returns the next batch of actions to process
|
|
368
|
+
*/
|
|
369
|
+
nextActionsBatch() {
|
|
370
|
+
var _a;
|
|
371
|
+
const batch = [];
|
|
372
|
+
let i = 0;
|
|
373
|
+
let currentAction = this.basketActionsQueue.value[i];
|
|
374
|
+
let shouldForceStop = false;
|
|
375
|
+
while (((_a = this.basketActionsQueue.value[i]) === null || _a === void 0 ? void 0 : _a.type) === (currentAction === null || currentAction === void 0 ? void 0 : currentAction.type) && !shouldForceStop) {
|
|
376
|
+
currentAction = this.basketActionsQueue.value[i];
|
|
377
|
+
shouldForceStop = this.addActionToBatchOrStopProcessingBatch(batch, currentAction);
|
|
378
|
+
i++;
|
|
379
|
+
}
|
|
380
|
+
return batch;
|
|
381
|
+
}
|
|
382
|
+
/**
|
|
383
|
+
* @returns true if the batch should stop processing
|
|
384
|
+
*/
|
|
385
|
+
addActionToBatchOrStopProcessingBatch(batch, currentAction) {
|
|
386
|
+
const recipeIndex = this.checkForActionToOverride(batch, currentAction);
|
|
387
|
+
if (recipeIndex !== -1) {
|
|
388
|
+
this.actionsBeingOverriden.push(batch[recipeIndex]);
|
|
389
|
+
batch[recipeIndex] = currentAction;
|
|
390
|
+
}
|
|
391
|
+
else {
|
|
392
|
+
if (this.shouldForceStopBatch(batch, currentAction)) {
|
|
393
|
+
return true;
|
|
394
|
+
}
|
|
395
|
+
else {
|
|
396
|
+
batch.push(currentAction);
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
return false;
|
|
400
|
+
}
|
|
401
|
+
shouldForceStopBatch(batch, currentAction) {
|
|
402
|
+
// If the current batch is an UPDATE batch, we can't update multiple recipes with differents guests values at the same time
|
|
403
|
+
// so in this case we stop the batch before the UPDATE with a different guests value
|
|
404
|
+
return (currentAction.type === BasketActionType.UPDATE_RECIPE &&
|
|
405
|
+
batch.length > 0 &&
|
|
406
|
+
!batch.some(a => a.params.guests === currentAction.params.guests)) ||
|
|
407
|
+
// If the current batch is an product add/remove batch, we can't add or remove products from different recipes at the same time
|
|
408
|
+
// so in this case we stop the batch before the add/remove with a different recipe
|
|
409
|
+
((currentAction.type === BasketActionType.ADD_PRODUCT || currentAction.type === BasketActionType.REMOVE_PRODUCT) &&
|
|
410
|
+
batch.length > 0 &&
|
|
411
|
+
!batch.some(a => a.params.recipeId === currentAction.params.recipeId));
|
|
412
|
+
}
|
|
413
|
+
/**
|
|
414
|
+
* Check for actions for which overriding would have the same result as processing both in order
|
|
415
|
+
*/
|
|
416
|
+
checkForActionToOverride(batch, currentAction) {
|
|
417
|
+
if (currentAction.type === BasketActionType.UPDATE_RECIPE &&
|
|
418
|
+
batch.length > 0 &&
|
|
419
|
+
!batch.some(a => a.params.recipeId !== currentAction.params.recipeId)) {
|
|
420
|
+
return batch.findIndex(a => a.params.recipeId === currentAction.params.recipeId);
|
|
421
|
+
// if there are only the same recipeId as the currentAction in the batch and we are updating this recipe's guests
|
|
422
|
+
// we can safely override the action in the batch
|
|
423
|
+
}
|
|
424
|
+
else if (currentAction.type === BasketActionType.UPDATE_PRODUCT) {
|
|
425
|
+
return batch.findIndex(a => a.params.basketEntry.id === currentAction.params.basketEntry.id);
|
|
426
|
+
// If the currentAction modifies the same basketEntry as a previous one in the batch, it overrides it
|
|
427
|
+
}
|
|
428
|
+
else if (![BasketActionType.ADD_PRODUCT, BasketActionType.REMOVE_PRODUCT, BasketActionType.UPDATE_RECIPE].includes(currentAction.type)) {
|
|
429
|
+
return batch.findIndex(a => a.params.recipeId === currentAction.params.recipeId);
|
|
430
|
+
// If the currentAction modifies the same recipe as a previous one in the batch, it overrides it
|
|
431
|
+
}
|
|
432
|
+
else {
|
|
433
|
+
return batch.findIndex(a => a.params.ingredientId === currentAction.params.ingredientId &&
|
|
434
|
+
a.params.recipeId === currentAction.params.recipeId);
|
|
435
|
+
// If the currentAction modifies the same ingredient for the same recipe as a previous one in the batch, it overrides it
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
processActionsBatch(actionsToProcess) {
|
|
439
|
+
switch (actionsToProcess[0].type) {
|
|
440
|
+
case BasketActionType.ADD_RECIPE:
|
|
441
|
+
return this.addRecipes(actionsToProcess);
|
|
442
|
+
case BasketActionType.ADD_RECIPE_LIGHT:
|
|
443
|
+
return this.addRecipesWithoutIngredients(actionsToProcess);
|
|
444
|
+
case BasketActionType.REMOVE_RECIPE:
|
|
445
|
+
return this.removeRecipes(actionsToProcess);
|
|
446
|
+
case BasketActionType.UPDATE_RECIPE:
|
|
447
|
+
return this.updateRecipesGuests(actionsToProcess);
|
|
448
|
+
case BasketActionType.ADD_PRODUCT:
|
|
449
|
+
return this.addItemsForIngredients(actionsToProcess);
|
|
450
|
+
case BasketActionType.REMOVE_PRODUCT:
|
|
451
|
+
return this.removeItemsForIngredients(actionsToProcess);
|
|
452
|
+
case BasketActionType.UPDATE_PRODUCT:
|
|
453
|
+
return this.changeBasketEntriesQuantities(actionsToProcess);
|
|
454
|
+
default:
|
|
455
|
+
return of();
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
/** ****************************************************** PROCESS THE ACTIONS ****************************************************** **/
|
|
459
|
+
/**
|
|
460
|
+
* Adds recipes to the basket HTTP request.
|
|
461
|
+
*
|
|
462
|
+
* @param recipesToAdd - The recipes to add to the basket.
|
|
463
|
+
* @param withIngredients - (optional) Whether to include ingredients in the request. Default is true.
|
|
464
|
+
* @return An observable that emits void when the request is completed.
|
|
465
|
+
*/
|
|
466
|
+
addRecipes(recipesToAdd, withIngredients = true) {
|
|
467
|
+
return this.waitForBasket.pipe(switchMap(basket => {
|
|
468
|
+
const url = `${e.miamAPI}/api/v1/baskets/${basket.id}/recipes` +
|
|
469
|
+
`?fields[baskets]=${BASKET_SPARSE_FIELDS.baskets.join(',')}${withIngredients ? '' : '&light_mode=true'}`;
|
|
470
|
+
const body = { data: recipesToAdd.map(r => ({ recipe_id: r.params.recipeId, guests: r.params.guests })) };
|
|
471
|
+
this.analyticsService.sendAddRecipesEvents(recipesToAdd);
|
|
472
|
+
return this.http.post(url, body).pipe(skipWhile((b) => b.is_loading), switchMap(b => {
|
|
473
|
+
var _a;
|
|
474
|
+
if ((_a = b === null || b === void 0 ? void 0 : b.data) === null || _a === void 0 ? void 0 : _a.id) {
|
|
475
|
+
this.fillBasket(b);
|
|
476
|
+
return this.loadPreview();
|
|
477
|
+
}
|
|
478
|
+
return of();
|
|
479
|
+
}));
|
|
480
|
+
}));
|
|
481
|
+
}
|
|
482
|
+
addRecipesWithoutIngredients(recipesToAdd) {
|
|
483
|
+
return this.addRecipes(recipesToAdd, false);
|
|
484
|
+
}
|
|
485
|
+
removeRecipes(recipesToRemove) {
|
|
486
|
+
return this.waitForBasket.pipe(switchMap(basket => {
|
|
487
|
+
const url = `${e.miamAPI}/api/v1/baskets/${basket.id}/recipes?recipe_ids[]=` +
|
|
488
|
+
recipesToRemove.map(r => r.params.recipeId).join('&recipe_ids[]=') + `&fields[baskets]=${BASKET_SPARSE_FIELDS.baskets.join(',')}`;
|
|
489
|
+
this.analyticsService.sendRemoveRecipesEvents(recipesToRemove);
|
|
490
|
+
return this.http.delete(url).pipe(skipWhile((b) => b.is_loading), switchMap(b => {
|
|
491
|
+
var _a;
|
|
492
|
+
if ((_a = b === null || b === void 0 ? void 0 : b.data) === null || _a === void 0 ? void 0 : _a.id) {
|
|
493
|
+
this.fillBasket(b);
|
|
494
|
+
return this.loadPreview();
|
|
495
|
+
}
|
|
496
|
+
return of();
|
|
177
497
|
}));
|
|
178
498
|
}));
|
|
179
499
|
}
|
|
500
|
+
updateRecipesGuests(recipesToUpdate) {
|
|
501
|
+
return this.waitForBasket.pipe(switchMap(basket => {
|
|
502
|
+
const url = `${e.miamAPI}/api/v1/baskets/${basket.id}/recipes_guests?guests=${recipesToUpdate[0].params.guests}&recipe_ids[]=` +
|
|
503
|
+
recipesToUpdate.map(r => r.params.recipeId).join('&recipe_ids[]=') + `&fields[baskets]=${BASKET_SPARSE_FIELDS.baskets.join(',')}`;
|
|
504
|
+
this.analyticsService.sendUpdateGuestsEvents(recipesToUpdate);
|
|
505
|
+
return this.http.patch(url, {}).pipe(skipWhile((b) => !b || b.is_loading), switchMap(b => {
|
|
506
|
+
var _a;
|
|
507
|
+
if ((_a = b === null || b === void 0 ? void 0 : b.data) === null || _a === void 0 ? void 0 : _a.id) {
|
|
508
|
+
this.fillBasket(b);
|
|
509
|
+
return this.loadPreview();
|
|
510
|
+
}
|
|
511
|
+
return of();
|
|
512
|
+
}));
|
|
513
|
+
}));
|
|
514
|
+
}
|
|
515
|
+
/**
|
|
516
|
+
* @param ingredientsToAdd
|
|
517
|
+
*/
|
|
518
|
+
addItemsForIngredients(ingredientsToAdd) {
|
|
519
|
+
return this.waitForBasket.pipe(skipWhile(basket => basket.is_loading), switchMap(basket => {
|
|
520
|
+
const requests = ingredientsToAdd.map(action => {
|
|
521
|
+
const modifiedGuests = this.guestsForRecipe(action.params.recipeId);
|
|
522
|
+
const url = `${e.miamAPI}/api/v1/baskets/${basket.id}/basket-entries/${action.params.basketEntry.id}/add-ingredient` +
|
|
523
|
+
`?ingredient_id=${action.params.ingredientId}&selected_item_id=${action.params.basketEntry.selectedItem.id}` +
|
|
524
|
+
`&guests=${modifiedGuests}`;
|
|
525
|
+
return this.http.patch(url, {});
|
|
526
|
+
});
|
|
527
|
+
return forkJoin(requests);
|
|
528
|
+
}), switchMap(() => this.reloadBasket()), switchMap(() => of(null)) // Just to keep the return type as Observable<void> to match with the other methods
|
|
529
|
+
);
|
|
530
|
+
}
|
|
531
|
+
/**
|
|
532
|
+
* Removes the specified ingredients from the basket HTTP request.
|
|
533
|
+
*
|
|
534
|
+
* @param ingredientsToRemove - The list of ingredients to remove from the basket.
|
|
535
|
+
* @return An observable that emits when the ingredients are successfully removed.
|
|
536
|
+
*/
|
|
537
|
+
removeItemsForIngredients(ingredientsToRemove) {
|
|
538
|
+
return this.waitForBasket.pipe(skipWhile(basket => basket.is_loading), switchMap(basket => {
|
|
539
|
+
const requests = ingredientsToRemove.map(action => {
|
|
540
|
+
const modifiedGuests = this.guestsForRecipe(action.params.recipeId);
|
|
541
|
+
const url = e.miamAPI + '/api/v1/baskets/' + basket.id +
|
|
542
|
+
'/basket-entries/' + action.params.basketEntry.id +
|
|
543
|
+
'/remove-ingredient?ingredient_id=' + action.params.ingredientId +
|
|
544
|
+
'&selected_item_id=' + action.params.basketEntry.selectedItem.id +
|
|
545
|
+
'&guests=' + modifiedGuests;
|
|
546
|
+
return this.http.patch(url, {});
|
|
547
|
+
});
|
|
548
|
+
return forkJoin(requests);
|
|
549
|
+
}), switchMap(() => this.reloadBasket()), switchMap(() => of(null)) // Just to keep the return type as Observable<void> to match with the other methods
|
|
550
|
+
);
|
|
551
|
+
}
|
|
552
|
+
/**
|
|
553
|
+
* Removes the specified ingredients from the basket HTTP request.
|
|
554
|
+
*
|
|
555
|
+
* @param ingredientsToRemove - The list of ingredients to remove from the basket.
|
|
556
|
+
* @return An observable that emits when the ingredients are successfully removed.
|
|
557
|
+
*/
|
|
558
|
+
changeBasketEntriesQuantities(quantitiesToChange) {
|
|
559
|
+
const requests = quantitiesToChange.map(action => {
|
|
560
|
+
action.params.basketEntry.quantity = action.params.newQuantity;
|
|
561
|
+
return action.params.basketEntry.save();
|
|
562
|
+
});
|
|
563
|
+
return forkJoin(requests).pipe(switchMap(() => this.reloadBasket()), switchMap(() => of(null)) // Just to keep the return type as Observable<void> to match with the other methods
|
|
564
|
+
);
|
|
565
|
+
}
|
|
566
|
+
/** ****************************************************** UPDATING THE BASKET ****************************************************** **/
|
|
567
|
+
/**
|
|
568
|
+
* Update _basket$ content & save basketId in the localStorage if the user is not loggued in so we can mergeWith when they log in
|
|
569
|
+
*/
|
|
570
|
+
updateLocalBasket(basket) {
|
|
571
|
+
if (this.usersService.isLogged$.value) {
|
|
572
|
+
localStorage.removeItem('_miam/basketId');
|
|
573
|
+
}
|
|
574
|
+
else {
|
|
575
|
+
localStorage.setItem('_miam/basketId', basket.id);
|
|
576
|
+
}
|
|
577
|
+
this._basket$.next(basket);
|
|
578
|
+
return this.loadPreview().pipe(tap(() => this.basketIsFetching = false));
|
|
579
|
+
}
|
|
580
|
+
/**
|
|
581
|
+
* save() returns an object that isn't a resource so methods aren't attached, so we have to do a little trick
|
|
582
|
+
* @param res result of the save
|
|
583
|
+
* @returns correct Basket with the right attributes & methods
|
|
584
|
+
*/
|
|
585
|
+
fillBasket(res) {
|
|
586
|
+
const basket = this.new();
|
|
587
|
+
basket.fill(res);
|
|
588
|
+
this._basket$.next(basket);
|
|
589
|
+
return basket;
|
|
590
|
+
}
|
|
591
|
+
/** ********************************************************** INITIAL LOAD ********************************************************** **/
|
|
592
|
+
/**
|
|
593
|
+
* Initialise the basket loading when the pos is initialised or modified
|
|
594
|
+
* @returns _basket$
|
|
595
|
+
*/
|
|
596
|
+
loadBasket() {
|
|
597
|
+
return this.posService.pos$.pipe(skipWhile(pos => !pos), switchMap(() => this.refreshCurrentBasket()));
|
|
598
|
+
}
|
|
180
599
|
loadPreview() {
|
|
181
|
-
return this.basket$.pipe(skipWhile(b => !b),
|
|
600
|
+
return this.basket$.pipe(skipWhile(b => !b), take(1), switchMap(basket => this.recipesService.loadRecipes(basket.recipeInfos)), switchMap((recipes) => {
|
|
182
601
|
const basket = this._basket$.value;
|
|
183
602
|
return this.fetchBasketEntries(basket).pipe(map(entries => {
|
|
184
603
|
const lineEntries = this.groupBasketEntries(recipes, entries);
|
|
@@ -186,20 +605,18 @@ export class BasketsService extends Service {
|
|
|
186
605
|
this._basketPreview$.next(lines);
|
|
187
606
|
this.basketPreviewIsCalculating = false;
|
|
188
607
|
this.basketStats$.next(this.buildStats(lines));
|
|
189
|
-
return lines;
|
|
190
608
|
}));
|
|
191
609
|
}));
|
|
192
610
|
}
|
|
193
611
|
fetchBasketEntries(basket) {
|
|
194
612
|
if (!basket || !basket.completion || basket.completion.total < 1) {
|
|
195
613
|
this._entries$.next([]);
|
|
196
|
-
return this._entries
|
|
614
|
+
return this._entries$.pipe(take(1));
|
|
197
615
|
}
|
|
198
616
|
const pagesCount = Math.ceil(basket.completion.total / BasketsService.entriesPerPages);
|
|
199
617
|
return forkJoin(Array(pagesCount).fill(0).map((v, i) => this.fetchBasketEntriesPage(basket, i + 1))).pipe(map((collections) => {
|
|
200
618
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
|
|
201
619
|
const entries = flatten(collections.map(col => col.data));
|
|
202
|
-
entries.forEach((entry) => entry.setItemsSelection());
|
|
203
620
|
this._entries$.next(entries);
|
|
204
621
|
return this._entries$.value;
|
|
205
622
|
}));
|
|
@@ -219,8 +636,8 @@ export class BasketsService extends Service {
|
|
|
219
636
|
};
|
|
220
637
|
}
|
|
221
638
|
fetchBasketEntriesPage(basket, page) {
|
|
222
|
-
let url =
|
|
223
|
-
url = `${url}?include=
|
|
639
|
+
let url = `${e.miamAPI}/api/v1/baskets/${basket.id}/basket-entries`;
|
|
640
|
+
url = `${url}?include=items&include=selected-item&page[number]=${page}&page[size]=${BasketsService.entriesPerPages}`;
|
|
224
641
|
return this.http.get(url).pipe(skipWhile((resp) => resp.is_loading), map((resp) => {
|
|
225
642
|
const basketEntries = this.basketEntriesService.newCollection();
|
|
226
643
|
basketEntries.fill(resp);
|
|
@@ -236,22 +653,22 @@ export class BasketsService extends Service {
|
|
|
236
653
|
const selectedItem = entry.attributes['basket-entries-items'].find(item => item.item_id === entry.attributes['selected-item-id']);
|
|
237
654
|
const qty = entry.attributes.quantity;
|
|
238
655
|
const unitPrice = parseFloat(selectedItem['unit-price']);
|
|
239
|
-
const numberOfRecipesForEntry = entry.
|
|
656
|
+
const numberOfRecipesForEntry = entry.recipesIds.length || 1;
|
|
240
657
|
recipePrice += (qty * unitPrice) / numberOfRecipesForEntry;
|
|
241
658
|
});
|
|
242
659
|
const pricePerGuest = recipePrice / guests;
|
|
243
660
|
return BasketPreviewLine.fromRecipe(recipe, itemsCount, pricePerGuest, recipePrice, lineEntries[idx]);
|
|
244
|
-
}).sort((a, b) => recipes.findIndex(r => r.id ===
|
|
661
|
+
}).sort((a, b) => recipes.findIndex(r => r.id === b.id) - recipes.findIndex(r => r.id === a.id));
|
|
245
662
|
}
|
|
246
663
|
groupBasketEntries(recipes, entries) {
|
|
247
664
|
return recipes.map(recipe => {
|
|
248
|
-
const lineEntries = { found: [], notFound: [], oftenDeleted: [], removed: [] };
|
|
665
|
+
const lineEntries = { found: [], notFound: [], oftenDeleted: [], removed: [], all: [] };
|
|
249
666
|
entries
|
|
250
|
-
.filter(entry => entry.
|
|
667
|
+
.filter(entry => entry.recipesIds.includes(parseInt(recipe.id, 10)))
|
|
251
668
|
.forEach(entry => {
|
|
252
669
|
const available = entry.attributes['selected-item-id'];
|
|
253
670
|
if (available) {
|
|
254
|
-
switch (entry.
|
|
671
|
+
switch (entry.status) {
|
|
255
672
|
case 'often_deleted': {
|
|
256
673
|
lineEntries.oftenDeleted.push(entry);
|
|
257
674
|
break;
|
|
@@ -269,18 +686,19 @@ export class BasketsService extends Service {
|
|
|
269
686
|
else {
|
|
270
687
|
lineEntries.notFound.push(entry);
|
|
271
688
|
}
|
|
689
|
+
lineEntries.all.push(entry);
|
|
272
690
|
});
|
|
273
691
|
return lineEntries;
|
|
274
692
|
});
|
|
275
693
|
}
|
|
276
694
|
}
|
|
277
695
|
BasketsService.entriesPerPages = 30;
|
|
278
|
-
BasketsService.ɵfac = function BasketsService_Factory(t) { return new (t || BasketsService)(i0.ɵɵinject(i1.HttpClient), i0.ɵɵinject(i2.BasketEntriesService), i0.ɵɵinject(i3.
|
|
696
|
+
BasketsService.ɵfac = function BasketsService_Factory(t) { return new (t || BasketsService)(i0.ɵɵinject(i1.HttpClient), i0.ɵɵinject(i2.BasketEntriesService), i0.ɵɵinject(i3.PointOfSalesService), i0.ɵɵinject(i4.RecipesService), i0.ɵɵinject(i5.AnalyticsService), i0.ɵɵinject(i6.UserService), i0.ɵɵinject(i7.ToasterService)); };
|
|
279
697
|
BasketsService.ɵprov = i0.ɵɵdefineInjectable({ token: BasketsService, factory: BasketsService.ɵfac, providedIn: 'root' });
|
|
280
698
|
/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(BasketsService, [{
|
|
281
699
|
type: Injectable,
|
|
282
700
|
args: [{
|
|
283
701
|
providedIn: 'root'
|
|
284
702
|
}]
|
|
285
|
-
}], function () { return [{ type: i1.HttpClient }, { type: i2.BasketEntriesService }, { type: i3.
|
|
286
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFza2V0cy5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6Ii9idWlsZHMvbWlhbS9uZy1taWFtLXNkay9wcm9qZWN0cy9uZy1taWFtL3NyYy8iLCJzb3VyY2VzIjpbImxpYi9fc2VydmljZXMvYmFza2V0cy5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUNsRCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzNDLE9BQU8sRUFBRSxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBQzdDLE9BQU8sRUFBRSxPQUFPLEVBQXdDLE1BQU0sYUFBYSxDQUFDO0FBQzVFLE9BQU8sRUFBYyxlQUFlLEVBQUUsYUFBYSxFQUFFLFFBQVEsRUFBRSxFQUFFLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDaEYsT0FBTyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUN0RSxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFFM0MsT0FBTyxFQUFFLGlCQUFpQixFQUFlLE1BQU0sZ0NBQWdDLENBQUM7QUFJaEYsT0FBTyxFQUFFLFdBQVcsSUFBSSxDQUFDLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUMvRCxPQUFPLEVBQUUsZ0JBQWdCLEVBQW9CLE1BQU0scUJBQXFCLENBQUM7QUFDekUsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDaEUsT0FBTyxFQUFFLHVCQUF1QixFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFDdEUsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFDbEUsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDL0QsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLG1CQUFtQixDQUFDOzs7Ozs7Ozs7QUFXbkQsTUFBTSxPQUFPLGNBQWUsU0FBUSxPQUFlO0lBY2pELFlBQ1UsSUFBZ0IsRUFDaEIsb0JBQTBDLEVBQzFDLFlBQW1DLEVBQ25DLHVCQUFnRCxFQUNoRCxVQUErQixFQUMvQixjQUE4QixFQUM5QixnQkFBa0M7UUFFMUMsS0FBSyxFQUFFLENBQUM7UUFSQSxTQUFJLEdBQUosSUFBSSxDQUFZO1FBQ2hCLHlCQUFvQixHQUFwQixvQkFBb0IsQ0FBc0I7UUFDMUMsaUJBQVksR0FBWixZQUFZLENBQXVCO1FBQ25DLDRCQUF1QixHQUF2Qix1QkFBdUIsQ0FBeUI7UUFDaEQsZUFBVSxHQUFWLFVBQVUsQ0FBcUI7UUFDL0IsbUJBQWMsR0FBZCxjQUFjLENBQWdCO1FBQzlCLHFCQUFnQixHQUFoQixnQkFBZ0IsQ0FBa0I7UUFsQjVDLGFBQVEsR0FBRyxNQUFNLENBQUM7UUFDbEIsU0FBSSxHQUFHLFNBQVMsQ0FBQztRQUNqQixhQUFRLEdBQUcsSUFBSSxlQUFlLENBQVMsSUFBSSxDQUFDLENBQUM7UUFDN0Msb0JBQWUsR0FBRyxJQUFJLGVBQWUsQ0FBc0IsSUFBSSxDQUFDLENBQUM7UUFDakUsaUJBQVksR0FBRyxJQUFJLGVBQWUsQ0FBYyxJQUFJLENBQUMsQ0FBQztRQUN0RCxxQkFBZ0IsR0FBRyxLQUFLLENBQUM7UUFDekIsK0JBQTBCLEdBQUcsS0FBSyxDQUFDO1FBQ25DLHFCQUFnQixHQUFHLEtBQUssQ0FBQztRQUVqQixjQUFTLEdBQUcsSUFBSSxlQUFlLENBQWdCLEVBQUUsQ0FBQyxDQUFDO1FBWXpELElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztJQUNsQixDQUFDO0lBRUQ7Ozs7T0FJRztJQUNILElBQUksT0FBTztRQUNULElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLEtBQUssSUFBSSxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsRUFBRTtZQUNsRCxJQUFJLENBQUMsZ0JBQWdCLEdBQUcsSUFBSSxDQUFDO1lBQzdCLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztTQUNuQjtRQUNELE9BQU8sSUFBSSxDQUFDLFFBQVEsQ0FBQztJQUN2QixDQUFDO0lBRUQ7OztPQUdHO0lBQ0gsSUFBSSxjQUFjO1FBQ2hCLElBQUksQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLEtBQUssSUFBSSxDQUFDLElBQUksQ0FBQywwQkFBMEIsRUFBRTtZQUNuRSxJQUFJLENBQUMsMEJBQTBCLEdBQUcsSUFBSSxDQUFDO1lBQ3ZDLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztTQUNuQjtRQUNELE9BQU8sSUFBSSxDQUFDLGVBQWUsQ0FBQztJQUM5QixDQUFDO0lBRUQsc0RBQXNEO0lBQ3RELGtCQUFrQixDQUFDLE1BQWMsRUFBRSxLQUFhO1FBQzlDLElBQUksQ0FBQyxNQUFNLElBQUksQ0FBQyxLQUFLLEVBQUU7WUFDckIsT0FBUSxFQUFFLENBQUMsSUFBSSxDQUF3QixDQUFDO1NBQ3pDO1FBQ0QsSUFBSSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsT0FBTyxFQUFFLHdCQUF3QixFQUFFLE1BQU0sRUFBRSxTQUFTLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDN0UsR0FBRyxHQUFHLEdBQUcsR0FBRyw2QkFBNkIsS0FBSyxFQUFFLENBQUM7UUFFakQsT0FBTyxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQzVCLFNBQVMsQ0FBQyxDQUFDLElBQWdDLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsRUFDaEUsR0FBRyxDQUFDLENBQUMsSUFBZ0MsRUFBRSxFQUFFO1lBQ3ZDLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztZQUNyQyxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ25CLE9BQU8sT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN6QixDQUFDLENBQUMsQ0FDSCxDQUFDO0lBQ0osQ0FBQztJQUVELFVBQVU7UUFDUixJQUFJLENBQUMsSUFBSSxDQUFDLGdCQUFnQixFQUFFO1lBQzFCLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxJQUFJLENBQUM7WUFDN0IsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDLFNBQVMsRUFBRSxDQUFDO1lBQzlCLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQyxTQUFTLEVBQUUsQ0FBQztTQUNoQztJQUNILENBQUM7SUFFRCxZQUFZO1FBQ1YsT0FBTyxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3pDLENBQUM7SUFFRCxrRkFBa0Y7SUFDbEYsYUFBYSxDQUFDLFVBQTJCO1FBQ3ZDLElBQUksZUFBdUIsQ0FBQztRQUM1QixPQUFPLENBQUMsR0FBRyxDQUFDLHlCQUF5QixJQUFJLENBQUMsU0FBUyxDQUFDLGVBQWUsQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUN4RSxPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUN0QixTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUNsQixJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQ1AsR0FBRyxDQUFDLE1BQU0sQ0FBQyxFQUFFO1lBQ1gsSUFBSSxNQUFNLENBQUMsVUFBVSxHQUFHLENBQUMsRUFBRTtnQkFDekIsSUFBSSxDQUFDLGdCQUFnQixDQUFDLGtCQUFrQixDQUN0QyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsdUJBQXVCLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxVQUFVLENBQUMsTUFBTSxFQUFFLFVBQVUsQ0FBQyxDQUN6RixDQUFDO2FBQ0g7UUFDSCxDQUFDLENBQUMsRUFDRixTQUFTLENBQUMsTUFBTSxDQUFDLEVBQUU7WUFDakIsT0FBTyxDQUFDLEdBQUcsQ0FBQyx3Q0FBd0MsQ0FBQyxDQUFDO1lBQ3RELE1BQU0sQ0FBQyxVQUFVLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQztZQUNuQyxPQUFPLE1BQU0sQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUN2QixDQUFDLENBQUMsRUFDRixTQUFTLENBQUMsQ0FBQyxJQUE4QixFQUFFLEVBQUU7WUFDM0MsZUFBZSxHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQztZQUM3QixlQUFlLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQzNCLE9BQU8sQ0FBQyxHQUFHLENBQ1QsNENBQTRDLElBQUksQ0FBQyxTQUFTLENBQUMsZUFBZSxDQUFDLFVBQVUsQ0FBQyxJQUFJLElBQUksQ0FBQyxTQUFTLENBQUMsZUFBZSxDQUFDLEVBQUUsQ0FDNUgsQ0FBQztZQUNGLElBQUksZUFBZSxDQUFDLFVBQVUsR0FBRyxDQUFDLElBQUksZUFBZSxDQUFDLEtBQUssRUFBRTtnQkFDM0QsSUFBSSxDQUFDLGdCQUFnQixDQUFDLGtCQUFrQixDQUN0QyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsc0JBQXNCLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxVQUFVLENBQUMsZUFBZSxFQUFFLFVBQVUsQ0FBQyxDQUNqRyxDQUFDO2FBQ0g7WUFDRCxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztZQUM5QixPQUFPLElBQUksQ0FBQyxZQUFZLENBQUMsU0FBUyxFQUFFLENBQUM7UUFDdkMsQ0FBQyxDQUFDLEVBQ0YsU0FBUyxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQzVCLEVBQ0QsU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFDbEIsR0FBRyxDQUFDLEdBQUcsRUFBRSxDQUFDLGVBQWUsQ0FBQyxDQUMzQixDQUFDO0lBQ0osQ0FBQztJQUVELFVBQVUsQ0FBQyxNQUFjLEVBQUUsVUFBMkI7UUFDcEQsT0FBTztZQUNMLHlDQUF5QztZQUN6QyxNQUFNLEVBQUUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUMsRUFBRTtZQUMxQyxRQUFRLEVBQUUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUMsVUFBVSxDQUFDLElBQUk7WUFDekQsU0FBUyxFQUFFLE1BQU0sQ0FBQyxFQUFFO1lBQ3BCLFdBQVcsRUFBRSxNQUFNLENBQUMsVUFBVTtZQUM5QixZQUFZLEVBQUUsVUFBVTtTQUN6QixDQUFDO0lBQ0osQ0FBQztJQUVELGFBQWE7UUFDWCxPQUFPLElBQUksQ0FBQyxTQUFTLENBQUM7SUFDeEIsQ0FBQztJQUVELG1CQUFtQjtRQUNqQixPQUFPLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQyxJQUFJLENBQzlCLEdBQUcsQ0FBQyxDQUFDLE9BQXNCLEVBQUUsRUFBRSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxLQUFLLENBQUMsb0JBQW9CLEtBQUssUUFBUSxDQUFDLENBQUMsQ0FDbEcsQ0FBQztJQUNKLENBQUM7SUFFRCxnREFBZ0Q7SUFDaEQsd0ZBQXdGO0lBQ3hGLDRDQUE0QztJQUM1QyxtQkFBbUIsQ0FBQyxlQUFvQztRQUN0RCxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLEVBQUU7WUFDekIsT0FBTztTQUNSO1FBRUQsTUFBTSxlQUFlLEdBQXNCLGVBQWUsQ0FBQyxHQUFHLENBQUMsYUFBYSxDQUFDLEVBQUU7WUFDN0UsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsS0FBSyxhQUFhLENBQUMsRUFBRSxDQUFDLENBQUM7WUFDaEYsSUFBSSxDQUFDLFdBQVcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxRQUFRLEVBQUU7Z0JBQzNDLE9BQU8sRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDO2FBQ2pCO1lBRUQsTUFBTSxVQUFVLEdBQUcsV0FBVyxDQUFDLFFBQVEsR0FBRyxhQUFhLENBQUMsUUFBUSxDQUFDO1lBQ2pFLElBQUksVUFBVSxJQUFJLENBQUMsRUFBRTtnQkFDbkIsV0FBVyxDQUFDLFFBQVEsR0FBRyxVQUFVLENBQUM7Z0JBQ2xDLE9BQU8sV0FBVyxDQUFDLElBQUksRUFBRSxDQUFDO2FBQzNCO2lCQUFNO2dCQUNMLFdBQVcsQ0FBQyxRQUFRLEdBQUcsQ0FBQyxDQUFDO2dCQUN6QixXQUFXLENBQUMsY0FBYyxDQUFDLE1BQU0sR0FBRyxTQUFTLENBQUM7Z0JBQzlDLE9BQU8sUUFBUSxDQUFDLENBQUMsV0FBVyxDQUFDLElBQUksRUFBRSxFQUFFLFdBQVcsQ0FBQyxjQUFjLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDO2FBQzFFO1FBQ0gsQ0FBQyxDQUFDLENBQUM7UUFFSCxPQUFPLFFBQVEsQ0FBQyxlQUFlLENBQUMsQ0FBQyxJQUFJLENBQ25DLFNBQVMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLGtCQUFrQixFQUFFLENBQUMsRUFDdkQsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUNSLENBQUM7SUFDSixDQUFDO0lBRU8sVUFBVTtRQUNoQixPQUFPLGFBQWEsQ0FBQyxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQ3hFLFNBQVMsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFFLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQ2pELFNBQVMsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUMzRSxHQUFHLENBQUMsTUFBTSxDQUFDLEVBQUU7WUFDWCxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUMzQixJQUFJLENBQUMsZ0JBQWdCLEdBQUcsS0FBSyxDQUFDO1FBQ2hDLENBQUMsQ0FBQyxDQUNILENBQUM7SUFDSixDQUFDO0lBRUQsNkNBQTZDO0lBQzdDLDJFQUEyRTtJQUMzRSxtQ0FBbUM7SUFDbkMsZUFBZSxDQUFDLGFBQXFCO1FBQ25DLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQ3RCLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQ2xCLElBQUksQ0FBQyxDQUFDLENBQUMsRUFDUCxTQUFTLENBQUMsTUFBTSxDQUFDLEVBQUU7WUFDakIsSUFBSSxNQUFNLENBQUMsWUFBWSxLQUFLLGFBQWEsRUFBRTtnQkFDekMsT0FBTyxDQUFDLEdBQUcsQ0FBQyx5QkFBeUIsSUFBSSxDQUFDLFNBQVMsQ0FBQyxhQUFhLENBQUMsRUFBRSxDQUFDLENBQUM7Z0JBQ3RFLE9BQU8sRUFBRSxDQUFDLE1BQU0sQ0FBQyxDQUFDO2FBQ25CO1lBQ0QsT0FBTyxDQUFDLEdBQUcsQ0FBQyw4QkFBOEIsSUFBSSxDQUFDLFNBQVMsQ0FBQyxhQUFhLENBQUMsRUFBRSxDQUFDLENBQUM7WUFDM0UsTUFBTSxDQUFDLFlBQVksR0FBRyxhQUFhLENBQUM7WUFDcEMsT0FBTyxNQUFNLENBQUMsSUFBSSxFQUFFLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQThCLEVBQUUsRUFBRTtnQkFDL0QsTUFBTSxhQUFhLEdBQUcsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDO2dCQUNqQyxhQUFhLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO2dCQUN6QixJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQztnQkFDbEMsT0FBTyxhQUFhLENBQUM7WUFDdkIsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNOLENBQUMsQ0FBQyxDQUNILENBQUM7SUFDSixDQUFDO0lBRU8sV0FBVztRQUNqQixPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUN0QixTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUNsQixTQUFTLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxXQUFXLEVBQUUsQ0FBQyxFQUNsRCxTQUFTLENBQUMsT0FBTyxDQUFDLEVBQUU7WUFDbEIsTUFBTSxNQUFNLEdBQVcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUM7WUFDM0MsT0FBTyxJQUFJLENBQUMsa0JBQWtCLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxDQUN6QyxHQUFHLENBQUMsT0FBTyxDQUFDLEVBQUU7Z0JBQ1osTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixDQUFDLE9BQU8sRUFBRSxPQUFPLENBQUMsQ0FBQztnQkFDOUQsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLHdDQUF3QyxDQUFDLE9BQU8sRUFBRSxXQUFXLENBQUMsQ0FBQztnQkFDbEYsSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7Z0JBQ2pDLElBQUksQ0FBQywwQkFBMEIsR0FBRyxLQUFLLENBQUM7Z0JBQ3hDLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztnQkFDL0MsT0FBTyxLQUFLLENBQUM7WUFDZixDQUFDLENBQUMsQ0FDSCxDQUFDO1FBQ0osQ0FBQyxDQUFDLENBQ0gsQ0FBQztJQUNKLENBQUM7SUFFTyxrQkFBa0IsQ0FBQyxNQUFjO1FBQ3ZDLElBQUksQ0FBQyxNQUFNLElBQUksQ0FBQyxNQUFNLENBQUMsVUFBVSxJQUFJLE1BQU0sQ0FBQyxVQUFVLENBQUMsS0FBSyxHQUFHLENBQUMsRUFBRTtZQUNoRSxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUN4QixPQUFPLElBQUksQ0FBQyxTQUFTLENBQUM7U0FDdkI7UUFFRCxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsS0FBSyxHQUFHLGNBQWMsQ0FBQyxlQUFlLENBQUMsQ0FBQztRQUN2RixPQUFPLFFBQVEsQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQ3ZHLEdBQUcsQ0FBQyxDQUFDLFdBQThDLEVBQUUsRUFBRTtZQUNyRCw2REFBNkQ7WUFDN0QsTUFBTSxPQUFPLEdBQUksT0FBTyxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQW1CLENBQUM7WUFDN0UsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDLEtBQWtCLEVBQUUsRUFBRSxDQUFDLEtBQUssQ0FBQyxpQkFBaUIsRUFBRSxDQUFDLENBQUM7WUFDbkUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDN0IsT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQztRQUM5QixDQUFDLENBQUMsQ0FDSCxDQUFDO0lBQ0osQ0FBQztJQUVPLFVBQVUsQ0FBQyxLQUEwQjtRQUMzQyxzR0FBc0c7UUFDdEcsTUFBTSxZQUFZLEdBQWtCLE9BQU8sQ0FBQyxHQUFJLEtBQUssQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDO1FBRTdGLE1BQU0sVUFBVSxHQUFHLFlBQVksQ0FBQyxNQUFNLENBQUMsQ0FBQyxLQUFLLEVBQUUsS0FBSyxFQUFFLEVBQUU7WUFDdEQsTUFBTSxJQUFJLEdBQUcsS0FBSyxDQUFDLFVBQVUsQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxPQUFPLEtBQUssS0FBSyxDQUFDLFVBQVUsQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDLENBQUM7WUFDcEgsS0FBSyxJQUFLLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxRQUFRLElBQUksQ0FBQyxDQUFDLEdBQUcsVUFBVSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDO1lBQzVFLE9BQU8sS0FBSyxDQUFDO1FBQ2YsQ0FBQyxFQUFFLENBQUMsQ0FBRSxDQUFDO1FBRVAsT0FBTztZQUNMLFlBQVksRUFBRSxLQUFLLENBQUMsTUFBTTtZQUMxQixZQUFZLEVBQUUsWUFBWSxDQUFDLE1BQU07WUFDakMsVUFBVTtTQUNYLENBQUM7SUFDSixDQUFDO0lBRU8sc0JBQXNCLENBQUMsTUFBYyxFQUFFLElBQVk7UUFDekQsSUFBSSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sQ0FBQyxFQUFFLEVBQUUsZ0JBQWdCLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDL0UsR0FBRyxHQUFHLEdBQUcsR0FBRywrQ0FBK0MsSUFBSSxlQUFlLGNBQWMsQ0FBQyxlQUFlLEVBQUUsQ0FBQztRQUUvRyxPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FDNUIsU0FBUyxDQUFDLENBQUMsSUFBcUMsRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxFQUNyRSxHQUFHLENBQUMsQ0FBQyxJQUFxQyxFQUFFLEVBQUU7WUFDNUMsTUFBTSxhQUFhLEdBQUcsSUFBSSxDQUFDLG9CQUFvQixDQUFDLGFBQWEsRUFBRSxDQUFDO1lBQ2hFLGFBQWEsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDekIsT0FBTyxhQUFhLENBQUM7UUFDdkIsQ0FBQyxDQUFDLENBQ0gsQ0FBQztJQUNKLENBQUM7SUFFTyx3Q0FBd0MsQ0FBQyxPQUFpQixFQUFFLFdBQTBCO1FBQzVGLE9BQU8sT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLE1BQU0sRUFBRSxHQUFHLEVBQUUsRUFBRTtZQUNqQyxNQUFNLFVBQVUsR0FBRyxXQUFXLENBQUMsR0FBRyxDQUFDLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQztZQUNqRCxJQUFJLFdBQVcsR0FBRyxHQUFHLENBQUM7WUFDdEIsTUFBTSxNQUFNLEdBQUcsTUFBTSxDQUFDLGNBQWMsSUFBSSxRQUFRLENBQUMsTUFBTSxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsQ0FBQztZQUVwRSxXQUFXLENBQUMsR0FBRyxDQUFDLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsRUFBRTtnQkFDckMsTUFBTSxZQUFZLEdBQUcsS0FBSyxDQUFDLFVBQVUsQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxPQUFPLEtBQUssS0FBSyxDQUFDLFVBQVUsQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDLENBQUM7Z0JBQ2xJLE1BQU0sR0FBRyxHQUFHLEtBQUssQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDO2dCQUN0QyxNQUFNLFNBQVMsR0FBRyxVQUFVLENBQUMsWUFBWSxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUM7Z0JBQ3pELE1BQU0sdUJBQXVCLEdBQUcsS0FBSyxDQUFDLFVBQVUsQ0FBQyxZQUFZLENBQUMsQ0FBQyxNQUFNLElBQUksQ0FBQyxDQUFDO2dCQUUzRSxXQUFXLElBQUksQ0FBQyxHQUFHLEdBQUcsU0FBUyxDQUFDLEdBQUcsdUJBQXVCLENBQUM7WUFDN0QsQ0FBQyxDQUFDLENBQUM7WUFDSCxNQUFNLGFBQWEsR0FBRyxXQUFXLEdBQUcsTUFBTSxDQUFDO1lBRTNDLE9BQU8saUJBQWlCLENBQUMsVUFBVSxDQUFDLE1BQU0sRUFBRSxVQUFVLEVBQUUsYUFBYSxFQUFFLFdBQVcsRUFBRSxXQUFXLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztRQUN4RyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUMsRUFBRSxDQUFDLEdBQUcsT0FBTyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDbkcsQ0FBQztJQUVPLGtCQUFrQixDQUFDLE9BQWlCLEVBQUUsT0FBc0I7UUFDbEUsT0FBTyxPQUFPLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxFQUFFO1lBQzFCLE1BQU0sV0FBVyxHQUFHLEVBQUUsS0FBSyxFQUFFLEVBQUUsRUFBRSxRQUFRLEVBQUUsRUFBRSxFQUFFLFlBQVksRUFBRSxFQUFFLEVBQUUsT0FBTyxFQUFFLEVBQUUsRUFBaUIsQ0FBQztZQUM5RixPQUFPO2lCQUNKLE1BQU0sQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUMsWUFBWSxDQUFDLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUM7aUJBQ2pGLE9BQU8sQ0FBQyxLQUFLLENBQUMsRUFBRTtnQkFDZixNQUFNLFNBQVMsR0FBRyxLQUFLLENBQUMsVUFBVSxDQUFDLGtCQUFrQixDQUFDLENBQUM7Z0JBQ3ZELElBQUksU0FBUyxFQUFFO29CQUNiLFFBQVEsS0FBSyxDQUFDLFVBQVUsQ0FBQyx3QkFBd0IsQ0FBQyxFQUFFO3dCQUNsRCxLQUFLLGVBQWUsQ0FBQyxDQUFDOzRCQUNwQixXQUFXLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQzs0QkFDckMsTUFBTTt5QkFDUDt3QkFDRCxLQUFLLFNBQVMsQ0FBQyxDQUFDOzRCQUNkLFdBQVcsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDOzRCQUNoQyxNQUFNO3lCQUNQO3dCQUNELE9BQU8sQ0FBQyxDQUFDOzRCQUNQLFdBQVcsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDOzRCQUM5QixNQUFNO3lCQUNQO3FCQUNGO2lCQUNGO3FCQUFNO29CQUNMLFdBQVcsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO2lCQUNsQztZQUNILENBQUMsQ0FBQyxDQUFDO1lBQ0wsT0FBTyxXQUFXLENBQUM7UUFDckIsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDOztBQXJVTSw4QkFBZSxHQUFHLEVBQUUsQ0FBQzs0RUFEakIsY0FBYztzREFBZCxjQUFjLFdBQWQsY0FBYyxtQkFGYixNQUFNO2tEQUVQLGNBQWM7Y0FIMUIsVUFBVTtlQUFDO2dCQUNWLFVBQVUsRUFBRSxNQUFNO2FBQ25CIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSHR0cENsaWVudCB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbi9odHRwJztcbmltcG9ydCB7IEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IHVuaW9uQnksIGZsYXR0ZW4gfSBmcm9tICdsb2Rhc2gtZXMnO1xuaW1wb3J0IHsgU2VydmljZSwgRG9jdW1lbnRDb2xsZWN0aW9uLCBEb2N1bWVudFJlc291cmNlIH0gZnJvbSAnbmd4LWpzb25hcGknO1xuaW1wb3J0IHsgT2JzZXJ2YWJsZSwgQmVoYXZpb3JTdWJqZWN0LCBjb21iaW5lTGF0ZXN0LCBmb3JrSm9pbiwgb2YgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IHNraXBXaGlsZSwgc3dpdGNoTWFwLCB0YXAsIG1hcCwgdGFrZSB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7IEJhc2tldCB9IGZyb20gJy4uL19tb2RlbHMvYmFza2V0JztcbmltcG9ydCB7IEJhc2tldEVudHJ5IH0gZnJvbSAnLi4vX21vZGVscy9iYXNrZXQtZW50cnknO1xuaW1wb3J0IHsgQmFza2V0UHJldmlld0xpbmUsIExpbmVFbnRyaWVzIH0gZnJvbSAnLi4vX21vZGVscy9iYXNrZXQtcHJldmlldy1saW5lJztcbmltcG9ydCB7IEdyb2Nlcmllc0VudHJ5IH0gZnJvbSAnLi4vX21vZGVscy9ncm9jZXJpZXMtZW50cnknO1xuaW1wb3J0IHsgUmVjaXBlIH0gZnJvbSAnLi4vX21vZGVscy9yZWNpcGUnO1xuaW1wb3J0IHsgQ29tcGFyYWJsZVByb2R1Y3QgfSBmcm9tICcuLi9fdHlwZXMvYnVpbGRlZC9jb21wYXJhYmxlLXByb2R1Y3QnO1xuaW1wb3J0IHsgZW52aXJvbm1lbnQgYXMgZSB9IGZyb20gJy4uL2Vudmlyb25tZW50cy9lbnZpcm9ubWVudCc7XG5pbXBvcnQgeyBBbmFseXRpY3NTZXJ2aWNlLCBDdXN0b21Qcm9wZXJ0aWVzIH0gZnJvbSAnLi9hbmFseXRpY3Muc2VydmljZSc7XG5pbXBvcnQgeyBCYXNrZXRFbnRyaWVzU2VydmljZSB9IGZyb20gJy4vYmFza2V0LWVudHJpZXMuc2VydmljZSc7XG5pbXBvcnQgeyBHcm9jZXJpZXNFbnRyaWVzU2VydmljZSB9IGZyb20gJy4vZ3JvY2VyaWVzLWVudHJpZXMuc2VydmljZSc7XG5pbXBvcnQgeyBHcm9jZXJpZXNMaXN0c1NlcnZpY2UgfSBmcm9tICcuL2dyb2Nlcmllcy1saXN0cy5zZXJ2aWNlJztcbmltcG9ydCB7IFBvaW50T2ZTYWxlc1NlcnZpY2UgfSBmcm9tICcuL3BvaW50LW9mLXNhbGVzLnNlcnZpY2UnO1xuaW1wb3J0IHsgUmVjaXBlc1NlcnZpY2UgfSBmcm9tICcuL3JlY2lwZXMuc2VydmljZSc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgQmFza2V0U3RhdHMge1xuICB0b3RhbFByaWNlOiBudW1iZXI7XG4gIHJlY2lwZXNDb3VudDogbnVtYmVyO1xuICBlbnRyaWVzQ291bnQ6IG51bWJlcjtcbn1cblxuQEluamVjdGFibGUoe1xuICBwcm92aWRlZEluOiAncm9vdCdcbn0pXG5leHBvcnQgY2xhc3MgQmFza2V0c1NlcnZpY2UgZXh0ZW5kcyBTZXJ2aWNlPEJhc2tldD4ge1xuICBzdGF0aWMgZW50cmllc1BlclBhZ2VzID0gMzA7XG5cbiAgcmVzb3VyY2UgPSBCYXNrZXQ7XG4gIHR5cGUgPSAnYmFza2V0cyc7XG4gIF9iYXNrZXQkID0gbmV3IEJlaGF2aW9yU3ViamVjdDxCYXNrZXQ+KG51bGwpO1xuICBfYmFza2V0UHJldmlldyQgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PEJhc2tldFByZXZpZXdMaW5lW10+KG51bGwpO1xuICBiYXNrZXRTdGF0cyQgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PEJhc2tldFN0YXRzPihudWxsKTtcbiAgYmFza2V0SXNGZXRjaGluZyA9IGZhbHNlO1xuICBiYXNrZXRQcmV2aWV3SXNDYWxjdWxhdGluZyA9IGZhbHNlO1xuICBiYXNrZXRJbml0Q2FsbGVkID0gZmFsc2U7XG5cbiAgcHJpdmF0ZSBfZW50cmllcyQgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PEJhc2tldEVudHJ5W10+KFtdKTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIGh0dHA6IEh0dHBDbGllbnQsXG4gICAgcHJpdmF0ZSBiYXNrZXRFbnRyaWVzU2VydmljZTogQmFza2V0RW50cmllc1NlcnZpY2UsXG4gICAgcHJpdmF0ZSBsaXN0c1NlcnZpY2U6IEdyb2Nlcmllc0xpc3RzU2VydmljZSxcbiAgICBwcml2YXRlIGdyb2Nlcmllc0VudHJpZXNTZXJ2aWNlOiBHcm9jZXJpZXNFbnRyaWVzU2VydmljZSxcbiAgICBwcml2YXRlIHBvc1NlcnZpY2U6IFBvaW50T2ZTYWxlc1NlcnZpY2UsXG4gICAgcHJpdmF0ZSByZWNpcGVzU2VydmljZTogUmVjaXBlc1NlcnZpY2UsXG4gICAgcHJpdmF0ZSBhbmFseXRpY3NTZXJ2aWNlOiBBbmFseXRpY3NTZXJ2aWNlXG4gICkge1xuICAgIHN1cGVyKCk7XG4gICAgdGhpcy5yZWdpc3RlcigpO1xuICB9XG5cbiAgLyoqXG4gICAqIFdlIHdhbnQgYmFza2V0JCB0byBiZSBhIHNpbmdsZXRvbiB0aGF0IGFsd2F5cyByZXR1cm5zIHRoZSBzYW1lIGJhc2tldCwgc28gaXQgaXMgZmV0Y2hlZCBvbmx5IHdoZW4gbmVjZXNzYXJ5LlxuICAgKiBBdCBhbnkgcG9pbnQgaW4gdGltZSB0aGUgYmFza2V0IGNhbiBiZSBmZXRjaGVkIHZpYSB0aGUgaW5pdEJhc2tldCBmdW5jdGlvbiAoaWYgd2Ugd2FudCB0byBmZXRjaCBpdCBvbiBzdGFydHVwIHRvIHNhdmUgdGltZSBsYXRlcilcbiAgICogQnV0IGlmIGluaXRCYXNrZXQgaXMgbm90IGNhbGxlZCwgdGhlIGJhc2tldCB3aWxsIG9ubHkgYmUgZmV0Y2hlZCB0aGUgMXN0IHRpbWUgaXQgaXMgbmVlZGVkLlxuICAgKi9cbiAgZ2V0IGJhc2tldCQoKTogQmVoYXZpb3JTdWJqZWN0PEJhc2tldD4ge1xuICAgIGlmICghdGhpcy5fYmFza2V0JC52YWx1ZSAmJiAhdGhpcy5iYXNrZXRJc0ZldGNoaW5nKSB7XG4gICAgICB0aGlzLmJhc2tldElzRmV0Y2hpbmcgPSB0cnVlO1xuICAgICAgdGhpcy5pbml0QmFza2V0KCk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLl9iYXNrZXQkO1xuICB9XG5cbiAgLyoqXG4gICAqIGJhc2tldFByZXZpZXckIHNob3VsZCBhbHNvIGJlIGEgc2luZ2xldG9uLCBhbmQgYXMgd2VsbCBhcyBiYXNrZXQkIGl0IHdpbGwgYmUgY2FsY3VsYXRlZCBmb3IgdGhlIGZpcnN0IHRpbWUgb25seSB3aGVuIG5lY2Vzc2FyeVxuICAgKiBvciBpZiBsb2FkUHJldmlldyBpcyBjYWxsZWQgYmVmb3JlXG4gICAqL1xuICBnZXQgYmFza2V0UHJldmlldyQoKTogQmVoYXZpb3JTdWJqZWN0PEJhc2tldFByZXZpZXdMaW5lW10+IHtcbiAgICBpZiAoIXRoaXMuX2Jhc2tldFByZXZpZXckLnZhbHVlICYmICF0aGlzLmJhc2tldFByZXZpZXdJc0NhbGN1bGF0aW5nKSB7XG4gICAgICB0aGlzLmJhc2tldFByZXZpZXdJc0NhbGN1bGF0aW5nID0gdHJ1ZTtcbiAgICAgIHRoaXMuaW5pdEJhc2tldCgpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5fYmFza2V0UHJldmlldyQ7XG4gIH1cblxuICAvLyBGZXRjaCByZWxhdGVkIGJhc2tldHMsIGZpbHRlcmluZyBvbiBhIHBvaW50IG9mIHNhbGVcbiAgZmV0Y2hGb3JMaXN0QW5kUG9zKGxpc3RJZDogc3RyaW5nLCBwb3NJZDogc3RyaW5nKTogT2JzZXJ2YWJsZTxCYXNrZXQ+IHtcbiAgICBpZiAoIWxpc3RJZCB8fCAhcG9zSWQpIHtcbiAgICAgIHJldHVybiAob2YobnVsbCkgYXMgT2JzZXJ2YWJsZTxCYXNrZXQ+KTtcbiAgICB9XG4gICAgbGV0IHVybCA9IFtlLm1pYW1BUEksICdhcGkvdjEvZ3JvY2VyaWVzLWxpc3RzJywgbGlzdElkLCAnYmFza2V0cyddLmpvaW4oJy8nKTtcbiAgICB1cmwgPSBgJHt1cmx9P2ZpbHRlcltwb2ludF9vZl9zYWxlX2lkXT0ke3Bvc0lkfWA7XG5cbiAgICByZXR1cm4gdGhpcy5odHRwLmdldCh1cmwpLnBpcGUoXG4gICAgICBza2lwV2hpbGUoKHJlc3A6IERvY3VtZW50Q29sbGVjdGlvbjxCYXNrZXQ+KSA9PiByZXNwLmlzX2xvYWRpbmcpLFxuICAgICAgbWFwKChyZXNwOiBEb2N1bWVudENvbGxlY3Rpb248QmFza2V0PikgPT4ge1xuICAgICAgICBjb25zdCBiYXNrZXRzID0gdGhpcy5uZXdDb2xsZWN0aW9uKCk7XG4gICAgICAgIGJhc2tldHMuZmlsbChyZXNwKTtcbiAgICAgICAgcmV0dXJuIGJhc2tldHMuZGF0YVswXTtcbiAgICAgIH0pXG4gICAgKTtcbiAgfVxuXG4gIGluaXRCYXNrZXQoKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLmJhc2tldEluaXRDYWxsZWQpIHtcbiAgICAgIHRoaXMuYmFza2V0SW5pdENhbGxlZCA9IHRydWU7XG4gICAgICB0aGlzLmxvYWRCYXNrZXQoKS5zdWJzY3JpYmUoKTtcbiAgICAgIHRoaXMubG9hZFByZXZpZXcoKS5zdWJzY3JpYmUoKTtcbiAgICB9XG4gIH1cblxuICByZWxvYWRCYXNrZXQoKTogT2JzZXJ2YWJsZTxCYXNrZXQ+IHtcbiAgICByZXR1cm4gdGhpcy5sb2FkQmFza2V0KCkucGlwZSh0YWtlKDEpKTtcbiAgfVxuXG4gIC8vIFNldCBiYXNrZXQgYXMgY29uZmlybWVkLCBhbmQgcmV0dXJucyBvbmx5IG9uY2UgdGhlIG5ldyBjdXJyZW50IGxpc3QgaXMgcmV0dXJuZWRcbiAgY29uZmlybUJhc2tldCh0b3RhbFByaWNlOiBudW1iZXIgfCBzdHJpbmcpOiBPYnNlcnZhYmxlPEJhc2tldD4ge1xuICAgIGxldCBjb25maXJtZWRCYXNrZXQ6IEJhc2tldDtcbiAgICBjb25zb2xlLmxvZyhgW01pYW1dIENvbmZpcm0gYmFza2V0ICR7SlNPTi5zdHJpbmdpZnkoY29uZmlybWVkQmFza2V0KX1gKTtcbiAgICByZXR1cm4gdGhpcy5iYXNrZXQkLnBpcGUoXG4gICAgICBza2lwV2hpbGUoYiA9PiAhYiksXG4gICAgICB0YWtlKDEpLFxuICAgICAgdGFwKGJhc2tldCA9PiB7XG4gICAgICAgIGlmIChiYXNrZXQudG90YWxQcmljZSA+IDApIHtcbiAgICAgICAgICB0aGlzLmFuYWx5dGljc1NlcnZpY2Uuc2VuZEV2ZW50V2hlblJlYWR5KFxuICAgICAgICAgICAgdGhpcy5hbmFseXRpY3NTZXJ2aWNlLkVWRU5UX1BBWU1FTlRfQ09ORklSTUVELCBudWxsLCB0aGlzLmV2ZW50UHJvcHMoYmFza2V0LCB0b3RhbFByaWNlKVxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgIH0pLFxuICAgICAgc3dpdGNoTWFwKGJhc2tldCA9PiB7XG4gICAgICAgIGNvbnNvbGUubG9nKCdbTWlhbV0gU2F2ZSBiYXNrZXQgd2l0aCBjb25maXJtZWQ9dHJ1ZScpO1xuICAgICAgICBiYXNrZXQuYXR0cmlidXRlcy5jb25maXJtZWQgPSB0cnVlO1xuICAgICAgICByZXR1cm4gYmFza2V0LnNhdmUoKTtcbiAgICAgIH0pLFxuICAgICAgc3dpdGNoTWFwKChyZXNwOiBEb2N1bWVudFJlc291cmNlPEJhc2tldD4pID0+IHtcbiAgICAgICAgY29uZmlybWVkQmFza2V0ID0gdGhpcy5uZXcoKTtcbiAgICAgICAgY29uZmlybWVkQmFza2V0LmZpbGwocmVzcCk7XG4gICAgICAgIGNvbnNvbGUubG9nKFxuICAgICAgICAgIGBbTWlhbV0gc2VuZCBwdXNoIGFuYWx5dGljcyBldmVudCBpZiA+IDA6ICR7SlNPTi5zdHJpbmdpZnkoY29uZmlybWVkQmFza2V0LnRvdGFsUHJpY2UpfSAke0pTT04uc3RyaW5naWZ5KGNvbmZpcm1lZEJhc2tldCl9YFxuICAgICAgICApO1xuICAgICAgICBpZiAoY29uZmlybWVkQmFza2V0LnRvdGFsUHJpY2UgPiAwICYmIGNvbmZpcm1lZEJhc2tldC50b2tlbikge1xuICAgICAgICAgIHRoaXMuYW5hbHl0aWNzU2VydmljZS5zZW5kRXZlbnRXaGVuUmVhZHkoXG4gICAgICAgICAgICB0aGlzLmFuYWx5dGljc1NlcnZpY2UuRVZFTlRfQkFTS0VUX0NPTkZJUk1FRCwgbnVsbCwgdGhpcy5ldmVudFByb3BzKGNvbmZpcm1lZEJhc2tldCwgdG90YWxQcmljZSlcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX2Jhc2tldCQubmV4dCh1bmRlZmluZWQpO1xuICAgICAgICByZXR1cm4gdGhpcy5saXN0c1NlcnZpY2UucmVzZXRMaXN0KCk7XG4gICAgICB9KSxcbiAgICAgIHN3aXRjaE1hcCgoKSA9PiB0aGlzLl9iYXNrZXQkXG4gICAgICApLFxuICAgICAgc2tpcFdoaWxlKGIgPT4gIWIpLFxuICAgICAgbWFwKCgpID0+IGNvbmZpcm1lZEJhc2tldClcbiAgICApO1xuICB9XG5cbiAgZXZlbnRQcm9wcyhiYXNrZXQ6IEJhc2tldCwgdG90YWxQcmljZTogbnVtYmVyIHwgc3RyaW5nKTogQ3VzdG9tUHJvcGVydGllcyB7XG4gICAgcmV0dXJuIHtcbiAgICAgIC8vIGlmIHlvdSBoYXZlIGEgYmFza2V0IHlvdSBoYXZlIGEgcG9zLi4uXG4gICAgICBwb3NfaWQ6IHRoaXMucG9zU2VydmljZS5wb3MkLmdldFZhbHVlKCkuaWQsXG4gICAgICBwb3NfbmFtZTogdGhpcy5wb3NTZXJ2aWNlLnBvcyQuZ2V0VmFsdWUoKS5hdHRyaWJ1dGVzLm5hbWUsXG4gICAgICBiYXNrZXRfaWQ6IGJhc2tldC5pZCxcbiAgICAgIG1pYW1fYW1vdW50OiBiYXNrZXQudG90YWxQcmljZSxcbiAgICAgIHRvdGFsX2Ftb3VudDogdG90YWxQcmljZVxuICAgIH07XG4gIH1cblxuICBiYXNrZXRFbnRyaWVzKCk6IE9ic2VydmFibGU8QmFza2V0RW50cnlbXT4ge1xuICAgIHJldHVybiB0aGlzLl9lbnRyaWVzJDtcbiAgfVxuXG4gIGFjdGl2ZUJhc2tldEVudHJpZXMoKTogT2JzZXJ2YWJsZTxCYXNrZXRFbnRyeVtdPiB7XG4gICAgcmV0dXJuIHRoaXMuYmFza2V0RW50cmllcygpLnBpcGUoXG4gICAgICBtYXAoKGVudHJpZXM6IEJhc2tldEVudHJ5W10pID0+IGVudHJpZXMuZmlsdGVyKGVudHJ5ID0+IGVudHJ5Lmdyb2Nlcmllc0VudHJ5U3RhdHVzID09PSAnYWN0aXZlJykpXG4gICAgKTtcbiAgfVxuXG4gIC8vIERlY3JlYXNlIHF1YW50aXR5IG9uIGEgbGlzdCBvZiBiYXNrZXQgZW50cmllc1xuICAvLyBJZiB0aGUgcXVhbnRpdHkgZ29lcyBiZWxvdyAxLCB0aGUgY29ycmVzcG9uZGluZyBncm9jZXJpZXMgZW50cnkncyBzdGF0dXMgZ2V0cyBkZWxldGVkXG4gIC8vIFJlbG9hZCBiYXNrZXQgYWZ0ZXIgYWxsIG9iamVjdHMgYXJlIHNhdmVkXG4gIHJlbW92ZUJhc2tldEVudHJpZXMoZW50cmllc1RvUmVtb3ZlOiBDb21wYXJhYmxlUHJvZHVjdFtdKTogT2JzZXJ2YWJsZTxhbnk+IHtcbiAgICBpZiAoIXRoaXMuX2VudHJpZXMkLnZhbHVlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3Qgc2F2ZU9ic2VydmFibGVzOiBPYnNlcnZhYmxlPGFueT5bXSA9IGVudHJpZXNUb1JlbW92ZS5tYXAoZW50cnlUb1JlbW92ZSA9PiB7XG4gICAgICBjb25zdCBiYXNrZXRFbnRyeSA9IHRoaXMuX2VudHJpZXMkLnZhbHVlLmZpbmQoYmUgPT4gYmUuaWQgPT09IGVudHJ5VG9SZW1vdmUuaWQpO1xuICAgICAgaWYgKCFiYXNrZXRFbnRyeSB8fCAhZW50cnlUb1JlbW92ZS5xdWFudGl0eSkge1xuICAgICAgICByZXR1cm4gb2YobnVsbCk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGZpbmFsQ291bnQgPSBiYXNrZXRFbnRyeS5xdWFudGl0eSAtIGVudHJ5VG9SZW1vdmUucXVhbnRpdHk7XG4gICAgICBpZiAoZmluYWxDb3VudCA+PSAxKSB7XG4gICAgICAgIGJhc2tldEVudHJ5LnF1YW50aXR5ID0gZmluYWxDb3VudDtcbiAgICAgICAgcmV0dXJuIGJhc2tldEVudHJ5LnNhdmUoKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGJhc2tldEVudHJ5LnF1YW50aXR5ID0gMTtcbiAgICAgICAgYmFza2V0RW50cnkuZ3JvY2VyaWVzRW50cnkuc3RhdHVzID0gJ2RlbGV0ZWQnO1xuICAgICAgICByZXR1cm4gZm9ya0pvaW4oW2Jhc2tldEVudHJ5LnNhdmUoKSwgYmFza2V0RW50cnkuZ3JvY2VyaWVzRW50cnkuc2F2ZSgpXSk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICByZXR1cm4gZm9ya0pvaW4oc2F2ZU9ic2VydmFibGVzKS5waXBlKFxuICAgICAgc3dpdGNoTWFwKCgpID0+IHRoaXMubGlzdHNTZXJ2aWNlLnJlZnJlc2hDdXJyZW50TGlzdCgpKSxcbiAgICAgIHRha2UoMSlcbiAgICApO1xuICB9XG5cbiAgcHJpdmF0ZSBsb2FkQmFza2V0KCk6IE9ic2VydmFibGU8QmFza2V0PiB7XG4gICAgcmV0dXJuIGNvbWJpbmVMYXRlc3QoW3RoaXMubGlzdHNTZXJ2aWNlLmxpc3QkLCB0aGlzLnBvc1NlcnZpY2UucG9zJF0pLnBpcGUoXG4gICAgICBza2lwV2hpbGUocmVzdWx0cyA9PiAgIXJlc3VsdHNbMF0gfHwgIXJlc3VsdHNbMV0pLFxuICAgICAgc3dpdGNoTWFwKHJlc3VsdHMgPT4gdGhpcy5mZXRjaEZvckxpc3RBbmRQb3MocmVzdWx0c1swXS5pZCwgcmVzdWx0c1sxXS5pZCkpLFxuICAgICAgdGFwKGJhc2tldCA9PiB7XG4gICAgICAgIHRoaXMuX2Jhc2tldCQubmV4dChiYXNrZXQpO1xuICAgICAgICB0aGlzLmJhc2tldElzRmV0Y2hpbmcgPSBmYWxzZTtcbiAgICAgIH0pXG4gICAgKTtcbiAgfVxuXG4gIC8vIHdpbGwgcGF0Y2ggYmFza2V0IHdpdGggZ2l2ZW4gcHJpY2Vib29rTmFtZVxuICAvLyBBcGkgd2lsbCBsb29rIGZvciBwcmljZXMgKHBvcyBpdGVtcykgY29ycmVzcG9uZGluZyB0byB0aGlzIHByaWNlYm9vayBrZXlcbiAgLy8gZmFsbCBjYXNlIHRvIGEgZGVmYXVsdCBwcmljZWJvb2tcbiAgdXBkYXRlUHJpY2Vib29rKHByaWNlYm9va05hbWU6IHN0cmluZyk6IE9ic2VydmFibGU8QmFza2V0PiB7XG4gICAgcmV0dXJuIHRoaXMuYmFza2V0JC5waXBlKFxuICAgICAgc2tpcFdoaWxlKGIgPT4gIWIpLFxuICAgICAgdGFrZSgxKSxcbiAgICAgIHN3aXRjaE1hcChiYXNrZXQgPT4ge1xuICAgICAgICBpZiAoYmFza2V0LnByaWNlYm9va0tleSA9PT0gcHJpY2Vib29rTmFtZSkge1xuICAgICAgICAgIGNvbnNvbGUubG9nKGBbTWlhbV0gc2FtZSBwcmljZWJvb2sgJHtKU09OLnN0cmluZ2lmeShwcmljZWJvb2tOYW1lKX1gKTtcbiAgICAgICAgICByZXR1cm4gb2YoYmFza2V0KTtcbiAgICAgICAgfVxuICAgICAgICBjb25zb2xlLmxvZyhgW01pYW1dIHVwZGF0ZSBwcmljZWJvb2sgdG8gJHtKU09OLnN0cmluZ2lmeShwcmljZWJvb2tOYW1lKX1gKTtcbiAgICAgICAgYmFza2V0LnByaWNlYm9va0tleSA9IHByaWNlYm9va05hbWU7XG4gICAgICAgIHJldHVybiBiYXNrZXQuc2F2ZSgpLnBpcGUobWFwKChyZXNwOiBEb2N1bWVudFJlc291cmNlPEJhc2tldD4pID0+IHtcbiAgICAgICAgICBjb25zdCB1cGRhdGVkQmFza2V0ID0gdGhpcy5uZXcoKTtcbiAgICAgICAgICB1cGRhdGVkQmFza2V0LmZpbGwocmVzcCk7XG4gICAgICAgICAgdGhpcy5fYmFza2V0JC5uZXh0KHVwZGF0ZWRCYXNrZXQpO1xuICAgICAgICAgIHJldHVybiB1cGRhdGVkQmFza2V0O1xuICAgICAgICB9KSk7XG4gICAgICB9KVxuICAgICk7XG4gIH1cblxuICBwcml2YXRlIGxvYWRQcmV2aWV3KCk6IE9ic2VydmFibGU8QmFza2V0UHJldmlld0xpbmVbXT4ge1xuICAgIHJldHVybiB0aGlzLmJhc2tldCQucGlwZShcbiAgICAgIHNraXBXaGlsZShiID0+ICFiKSxcbiAgICAgIHN3aXRjaE1hcCgoKSA9PiB0aGlzLnJlY2lwZXNTZXJ2aWNlLmxvYWRSZWNpcGVzKCkpLFxuICAgICAgc3dpdGNoTWFwKHJlY2lwZXMgPT4ge1xuICAgICAgICBjb25zdCBiYXNrZXQ6IEJhc2tldCA9IHRoaXMuX2Jhc2tldCQudmFsdWU7XG4gICAgICAgIHJldHVybiB0aGlzLmZldGNoQmFza2V0RW50cmllcyhiYXNrZXQpLnBpcGUoXG4gICAgICAgICAgbWFwKGVudHJpZXMgPT4ge1xuICAgICAgICAgICAgY29uc3QgbGluZUVudHJpZXMgPSB0aGlzLmdyb3VwQmFza2V0RW50cmllcyhyZWNpcGVzLCBlbnRyaWVzKTtcbiAgICAgICAgICAgIGNvbnN0IGxpbmVzID0gdGhpcy5yZWNpcGVzQW5kTGluZUVudHJpZXNUb0Jhc2tldFByZXZpZXdMaW5lKHJlY2lwZXMsIGxpbmVFbnRyaWVzKTtcbiAgICAgICAgICAgIHRoaXMuX2Jhc2tldFByZXZpZXckLm5leHQobGluZXMpO1xuICAgICAgICAgICAgdGhpcy5iYXNrZXRQcmV2aWV3SXNDYWxjdWxhdGluZyA9IGZhbHNlO1xuICAgICAgICAgICAgdGhpcy5iYXNrZXRTdGF0cyQubmV4dCh0aGlzLmJ1aWxkU3RhdHMobGluZXMpKTtcbiAgICAgICAgICAgIHJldHVybiBsaW5lcztcbiAgICAgICAgICB9KVxuICAgICAgICApO1xuICAgICAgfSlcbiAgICApO1xuICB9XG5cbiAgcHJpdmF0ZSBmZXRjaEJhc2tldEVudHJpZXMoYmFza2V0OiBCYXNrZXQpOiBPYnNlcnZhYmxlPEJhc2tldEVudHJ5W10+IHtcbiAgICBpZiAoIWJhc2tldCB8fCAhYmFza2V0LmNvbXBsZXRpb24gfHwgYmFza2V0LmNvbXBsZXRpb24udG90YWwgPCAxKSB7XG4gICAgICB0aGlzLl9lbnRyaWVzJC5uZXh0KFtdKTtcbiAgICAgIHJldHVybiB0aGlzLl9lbnRyaWVzJDtcbiAgICB9XG5cbiAgICBjb25zdCBwYWdlc0NvdW50ID0gTWF0aC5jZWlsKGJhc2tldC5jb21wbGV0aW9uLnRvdGFsIC8gQmFza2V0c1NlcnZpY2UuZW50cmllc1BlclBhZ2VzKTtcbiAgICByZXR1cm4gZm9ya0pvaW4oQXJyYXkocGFnZXNDb3VudCkuZmlsbCgwKS5tYXAoKHYsIGkpID0+IHRoaXMuZmV0Y2hCYXNrZXRFbnRyaWVzUGFnZShiYXNrZXQsIGkgKyAxKSkpLnBpcGUoXG4gICAgICBtYXAoKGNvbGxlY3Rpb25zOiBEb2N1bWVudENvbGxlY3Rpb248QmFza2V0RW50cnk+W10pID0+IHtcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnNhZmUtY2FsbFxuICAgICAgICBjb25zdCBlbnRyaWVzID0gKGZsYXR0ZW4oY29sbGVjdGlvbnMubWFwKGNvbCA9PiBjb2wuZGF0YSkpIGFzIEJhc2tldEVudHJ5W10pO1xuICAgICAgICBlbnRyaWVzLmZvckVhY2goKGVudHJ5OiBCYXNrZXRFbnRyeSkgPT4gZW50cnkuc2V0SXRlbXNTZWxlY3Rpb24oKSk7XG4gICAgICAgIHRoaXMuX2VudHJpZXMkLm5leHQoZW50cmllcyk7XG4gICAgICAgIHJldHVybiB0aGlzLl9lbnRyaWVzJC52YWx1ZTtcbiAgICAgIH0pXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgYnVpbGRTdGF0cyhsaW5lczogQmFza2V0UHJldmlld0xpbmVbXSk6IEJhc2tldFN0YXRzIHtcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVuc2FmZS1hc3NpZ25tZW50LCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW5zYWZlLWNhbGxcbiAgICBjb25zdCBlbnRyaWVzRm91bmQ6IEJhc2tldEVudHJ5W10gPSB1bmlvbkJ5KC4uLiBsaW5lcy5tYXAobGluZSA9PiBsaW5lLmVudHJpZXMuZm91bmQpLCAnaWQnKTtcblxuICAgIGNvbnN0IHRvdGFsUHJpY2UgPSBlbnRyaWVzRm91bmQucmVkdWNlKCh0b3RhbCwgZW50cnkpID0+IHtcbiAgICAgIGNvbnN0IGl0ZW0gPSBlbnRyeS5hdHRyaWJ1dGVzWydiYXNrZXQtZW50cmllcy1pdGVtcyddLmZpbmQoaSA9PiBpLml0ZW1faWQgPT09IGVudHJ5LmF0dHJpYnV0ZXNbJ3NlbGVjdGVkLWl0ZW0taWQnXSk7XG4gICAgICB0b3RhbCArPSAgKGVudHJ5LmF0dHJpYnV0ZXMucXVhbnRpdHkgfHwgMCkgKiBwYXJzZUZsb2F0KGl0ZW1bJ3VuaXQtcHJpY2UnXSk7XG4gICAgICByZXR1cm4gdG90YWw7XG4gICAgfSwgMCApO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIHJlY2lwZXNDb3VudDogbGluZXMubGVuZ3RoLFxuICAgICAgZW50cmllc0NvdW50OiBlbnRyaWVzRm91bmQubGVuZ3RoLFxuICAgICAgdG90YWxQcmljZVxuICAgIH07XG4gIH1cblxuICBwcml2YXRlIGZldGNoQmFza2V0RW50cmllc1BhZ2UoYmFza2V0OiBCYXNrZXQsIHBhZ2U6IG51bWJlcik6IE9ic2VydmFibGU8RG9jdW1lbnRDb2xsZWN0aW9uPEJhc2tldEVudHJ5Pj4ge1xuICAgIGxldCB1cmwgPSBbZS5taWFtQVBJLCAnYXBpL3YxL2Jhc2tldHMnLCBiYXNrZXQuaWQsICdiYXNrZXQtZW50cmllcyddLmpvaW4oJy8nKTtcbiAgICB1cmwgPSBgJHt1cmx9P2luY2x1ZGU9Z3JvY2VyaWVzLWVudHJ5LGl0ZW1zJnBhZ2VbbnVtYmVyXT0ke3BhZ2V9JnBhZ2Vbc2l6ZV09JHtCYXNrZXRzU2VydmljZS5lbnRyaWVzUGVyUGFnZXN9YDtcblxuICAgIHJldHVybiB0aGlzLmh0dHAuZ2V0KHVybCkucGlwZShcbiAgICAgIHNraXBXaGlsZSgocmVzcDogRG9jdW1lbnRDb2xsZWN0aW9uPEJhc2tldEVudHJ5PikgPT4gcmVzcC5pc19sb2FkaW5nKSxcbiAgICAgIG1hcCgocmVzcDogRG9jdW1lbnRDb2xsZWN0aW9uPEJhc2tldEVudHJ5PikgPT4ge1xuICAgICAgICBjb25zdCBiYXNrZXRFbnRyaWVzID0gdGhpcy5iYXNrZXRFbnRyaWVzU2VydmljZS5uZXdDb2xsZWN0aW9uKCk7XG4gICAgICAgIGJhc2tldEVudHJpZXMuZmlsbChyZXNwKTtcbiAgICAgICAgcmV0dXJuIGJhc2tldEVudHJpZXM7XG4gICAgICB9KVxuICAgICk7XG4gIH1cblxuICBwcml2YXRlIHJlY2lwZXNBbmRMaW5lRW50cmllc1RvQmFza2V0UHJldmlld0xpbmUocmVjaXBlczogUmVjaXBlW10sIGxpbmVFbnRyaWVzOiBMaW5lRW50cmllc1tdKTogQmFza2V0UHJldmlld0xpbmVbXSB7XG4gICAgcmV0dXJuIHJlY2lwZXMubWFwKChyZWNpcGUsIGlkeCkgPT4ge1xuICAgICAgY29uc3QgaXRlbXNDb3VudCA9IGxpbmVFbnRyaWVzW2lkeF0uZm91bmQubGVuZ3RoO1xuICAgICAgbGV0IHJlY2lwZVByaWNlID0gMC4wO1xuICAgICAgY29uc3QgZ3Vlc3RzID0gcmVjaXBlLm1vZGlmaWVkR3Vlc3RzIHx8IHBhcnNlSW50KHJlY2lwZS5ndWVzdHMsIDEwKTtcblxuICAgICAgbGluZUVudHJpZXNbaWR4XS5mb3VuZC5mb3JFYWNoKGVudHJ5ID0+IHtcbiAgICAgICAgY29uc3Qgc2VsZWN0ZWRJdGVtID0gZW50cnkuYXR0cmlidXRlc1snYmFza2V0LWVudHJpZXMtaXRlbXMnXS5maW5kKGl0ZW0gPT4gaXRlbS5pdGVtX2lkID09PSBlbnRyeS5hdHRyaWJ1dGVzWydzZWxlY3RlZC1pdGVtLWlkJ10pO1xuICAgICAgICBjb25zdCBxdHkgPSBlbnRyeS5hdHRyaWJ1dGVzLnF1YW50aXR5O1xuICAgICAgICBjb25zdCB1bml0UHJpY2UgPSBwYXJzZUZsb2F0KHNlbGVjdGVkSXRlbVsndW5pdC1wcmljZSddKTtcbiAgICAgICAgY29uc3QgbnVtYmVyT2ZSZWNpcGVzRm9yRW50cnkgPSBlbnRyeS5hdHRyaWJ1dGVzWydyZWNpcGUtaWRzJ10ubGVuZ3RoIHx8IDE7XG5cbiAgICAgICAgcmVjaXBlUHJpY2UgKz0gKHF0eSAqIHVuaXRQcmljZSkgLyBudW1iZXJPZlJlY2lwZXNGb3JFbnRyeTtcbiAgICAgIH0pO1xuICAgICAgY29uc3QgcHJpY2VQZXJHdWVzdCA9IHJlY2lwZVByaWNlIC8gZ3Vlc3RzO1xuXG4gICAgICByZXR1cm4gQmFza2V0UHJldmlld0xpbmUuZnJvbVJlY2lwZShyZWNpcGUsIGl0ZW1zQ291bnQsIHByaWNlUGVyR3Vlc3QsIHJlY2lwZVByaWNlLCBsaW5lRW50cmllc1tpZHhdKTtcbiAgICB9KS5zb3J0KChhLCBiKSA9PiByZWNpcGVzLmZpbmRJbmRleChyID0+IHIuaWQgPT09IGEuaWQpIC0gcmVjaXBlcy5maW5kSW5kZXgociA9PiByLmlkID09PSBiLmlkKSk7XG4gIH1cblxuICBwcml2YXRlIGdyb3VwQmFza2V0RW50cmllcyhyZWNpcGVzOiBSZWNpcGVbXSwgZW50cmllczogQmFza2V0RW50cnlbXSk6IExpbmVFbnRyaWVzW10ge1xuICAgIHJldHVybiByZWNpcGVzLm1hcChyZWNpcGUgPT4ge1xuICAgICAgY29uc3QgbGluZUVudHJpZXMgPSB7IGZvdW5kOiBbXSwgbm90Rm91bmQ6IFtdLCBvZnRlbkRlbGV0ZWQ6IFtdLCByZW1vdmVkOiBbXSB9IGFzIExpbmVFbnRyaWVzO1xuICAgICAgZW50cmllc1xuICAgICAgICAuZmlsdGVyKGVudHJ5ID0+IGVudHJ5LmF0dHJpYnV0ZXNbJ3JlY2lwZS1pZHMnXS5pbmNsdWRlcyhwYXJzZUludChyZWNpcGUuaWQsIDEwKSkpXG4gICAgICAgIC5mb3JFYWNoKGVudHJ5ID0+IHtcbiAgICAgICAgICBjb25zdCBhdmFpbGFibGUgPSBlbnRyeS5hdHRyaWJ1dGVzWydzZWxlY3RlZC1pdGVtLWlkJ107XG4gICAgICAgICAgaWYgKGF2YWlsYWJsZSkge1xuICAgICAgICAgICAgc3dpdGNoIChlbnRyeS5hdHRyaWJ1dGVzWydncm9jZXJpZXMtZW50cnktc3RhdHVzJ10pIHtcbiAgICAgICAgICAgICAgY2FzZSAnb2Z0ZW5fZGVsZXRlZCc6IHtcbiAgICAgICAgICAgICAgICBsaW5lRW50cmllcy5vZnRlbkRlbGV0ZWQucHVzaChlbnRyeSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgY2FzZSAnZGVsZXRlZCc6IHtcbiAgICAgICAgICAgICAgICBsaW5lRW50cmllcy5yZW1vdmVkLnB1c2goZW50cnkpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGRlZmF1bHQ6IHtcbiAgICAgICAgICAgICAgICBsaW5lRW50cmllcy5mb3VuZC5wdXNoKGVudHJ5KTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBsaW5lRW50cmllcy5ub3RGb3VuZC5wdXNoKGVudHJ5KTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgcmV0dXJuIGxpbmVFbnRyaWVzO1xuICAgIH0pO1xuICB9XG59XG4iXX0=
|
|
703
|
+
}], function () { return [{ type: i1.HttpClient }, { type: i2.BasketEntriesService }, { type: i3.PointOfSalesService }, { type: i4.RecipesService }, { type: i5.AnalyticsService }, { type: i6.UserService }, { type: i7.ToasterService }]; }, null); })();
|
|
704
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFza2V0cy5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6Ii9idWlsZHMvbWlhbS9uZy1taWFtLXNkay9wcm9qZWN0cy9uZy1taWFtL3NyYy8iLCJzb3VyY2VzIjpbImxpYi9fc2VydmljZXMvYmFza2V0cy5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUNsRCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzNDLE9BQU8sRUFBRSxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBQzdDLE9BQU8sRUFBd0MsT0FBTyxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQzVFLE9BQU8sRUFBRSxlQUFlLEVBQUUsUUFBUSxFQUFjLEVBQUUsRUFBZ0IsTUFBTSxNQUFNLENBQUM7QUFDL0UsT0FBTyxFQUFFLFlBQVksRUFBRSxHQUFHLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsR0FBRyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDcEYsT0FBTyxFQUFFLE1BQU0sRUFBZSxpQkFBaUIsRUFBdUIsTUFBTSxZQUFZLENBQUM7QUFFekYsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sbUNBQW1DLENBQUM7QUFJckUsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBQzFELE9BQU8sRUFBRSxXQUFXLElBQUksQ0FBQyxFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFDL0QsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDdkQsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDaEUsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDL0QsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQ25ELE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUNuRCxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7Ozs7Ozs7OztBQUU3QyxNQUFNLG9CQUFvQixHQUFHO0lBQzNCLE9BQU8sRUFBRSxDQUFDLGFBQWEsRUFBRSxlQUFlLEVBQUUsZUFBZSxFQUFFLFlBQVksQ0FBQztDQUN6RSxDQUFDO0FBTUYsTUFBTSxPQUFPLGNBQWUsU0FBUSxPQUFlO0lBbUJqRCxZQUNVLElBQWdCLEVBQ2hCLG9CQUEwQyxFQUMxQyxVQUErQixFQUMvQixjQUE4QixFQUM5QixnQkFBa0MsRUFDbEMsWUFBeUIsRUFDekIsY0FBOEI7UUFFdEMsS0FBSyxFQUFFLENBQUM7UUFSQSxTQUFJLEdBQUosSUFBSSxDQUFZO1FBQ2hCLHlCQUFvQixHQUFwQixvQkFBb0IsQ0FBc0I7UUFDMUMsZUFBVSxHQUFWLFVBQVUsQ0FBcUI7UUFDL0IsbUJBQWMsR0FBZCxjQUFjLENBQWdCO1FBQzlCLHFCQUFnQixHQUFoQixnQkFBZ0IsQ0FBa0I7UUFDbEMsaUJBQVksR0FBWixZQUFZLENBQWE7UUFDekIsbUJBQWMsR0FBZCxjQUFjLENBQWdCO1FBdkJ4QyxhQUFRLEdBQUcsTUFBTSxDQUFDO1FBQ2xCLFNBQUksR0FBRyxTQUFTLENBQUM7UUFDakIsYUFBUSxHQUFHLElBQUksZUFBZSxDQUFTLElBQUksQ0FBQyxDQUFDO1FBQzdDLG9CQUFlLEdBQUcsSUFBSSxlQUFlLENBQXNCLElBQUksQ0FBQyxDQUFDO1FBQ2pFLGlCQUFZLEdBQUcsSUFBSSxlQUFlLENBQWMsSUFBSSxDQUFDLENBQUM7UUFDdEQscUJBQWdCLEdBQUcsS0FBSyxDQUFDO1FBQ3pCLCtCQUEwQixHQUFHLEtBQUssQ0FBQztRQUNuQyxxQkFBZ0IsR0FBRyxLQUFLLENBQUM7UUFFakIsdUJBQWtCLEdBQUcsSUFBSSxlQUFlLENBQWlCLEVBQUUsQ0FBQyxDQUFDO1FBRTdELGNBQVMsR0FBRyxJQUFJLGVBQWUsQ0FBZ0IsRUFBRSxDQUFDLENBQUM7UUFDbkQsMEJBQXFCLEdBQUcsSUFBSSxlQUFlLENBQWlCLEVBQUUsQ0FBQyxDQUFDO1FBQ2hFLDBCQUFxQixHQUFtQixFQUFFLENBQUM7UUFDM0Msa0JBQWEsR0FBbUIsRUFBRSxDQUFDO1FBWXpDLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztRQUNoQixJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksQ0FDckIsSUFBSSxDQUFDLGtCQUFrQixDQUFDLElBQUksQ0FDMUIsWUFBWSxDQUFDLEdBQUcsQ0FBQyxFQUNqQixTQUFTLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxPQUFPLENBQUMsTUFBTSxLQUFLLENBQUMsSUFBSSxJQUFJLENBQUMscUJBQXFCLENBQUMsS0FBSyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsRUFDekYsR0FBRyxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxDQUFDLENBQ3BDLENBQUMsU0FBUyxFQUFFLENBQ2QsQ0FBQztRQUNGLElBQUksSUFBSSxDQUFDLGNBQWMsQ0FBQyxtQkFBbUIsRUFBRTtZQUMzQyxJQUFJLENBQUMsc0JBQXNCLEVBQUUsQ0FBQztTQUMvQjtJQUNILENBQUM7SUFFRCx5SUFBeUk7SUFFekk7Ozs7T0FJRztJQUNILElBQUksT0FBTztRQUNULElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLEtBQUssSUFBSSxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsRUFBRTtZQUNsRCxJQUFJLENBQUMsZ0JBQWdCLEdBQUcsSUFBSSxDQUFDO1lBQzdCLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztTQUNuQjtRQUNELE9BQU8sSUFBSSxDQUFDLFFBQVEsQ0FBQztJQUN2QixDQUFDO0lBRUQ7OztPQUdHO0lBQ0gsSUFBSSxjQUFjO1FBQ2hCLElBQUksQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLEtBQUssSUFBSSxDQUFDLElBQUksQ0FBQywwQkFBMEIsRUFBRTtZQUNuRSxJQUFJLENBQUMsMEJBQTBCLEdBQUcsSUFBSSxDQUFDO1lBQ3ZDLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztTQUNuQjtRQUNELE9BQU8sSUFBSSxDQUFDLGVBQWUsQ0FBQztJQUM5QixDQUFDO0lBRUQ7OztPQUdHO0lBQ0gsSUFBSSxhQUFhO1FBQ2YsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FDdEIsU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFDbEIsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUNSLENBQUM7SUFDSixDQUFDO0lBRUQseUlBQXlJO0lBRXpJLGlFQUFpRTtJQUN6RCx1QkFBdUIsQ0FBQyxPQUF3QyxFQUFFLElBQXNCLEVBQUUsUUFBZ0I7UUFDaEgsT0FBTyxPQUFPLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxLQUFLLElBQUksSUFBSSxDQUFDLENBQUMsTUFBTSxDQUFDLFFBQVEsS0FBSyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDeEcsQ0FBQztJQUVELGlFQUFpRTtJQUN6RCwyQkFBMkIsQ0FDakMsT0FBd0MsRUFBRSxJQUFzQixFQUFFLFlBQW9CO1FBRXRGLE9BQU8sT0FBTyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksS0FBSyxJQUFJLElBQUksQ0FBQyxDQUFDLE1BQU0sQ0FBQyxZQUFZLEtBQUssWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ2hILENBQUM7SUFFRCxpQkFBaUIsQ0FBQyxRQUFnQjtRQUNoQyxPQUFPLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxJQUFJLENBQUMsa0JBQWtCLEVBQUUsZ0JBQWdCLENBQUMsVUFBVSxFQUFFLFFBQVEsQ0FBQyxDQUFDO0lBQ3RHLENBQUM7SUFFRCxtQkFBbUIsQ0FBQyxRQUFnQjtRQUNsQyxPQUFPLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxJQUFJLENBQUMsa0JBQWtCLEVBQUUsZ0JBQWdCLENBQUMsYUFBYSxFQUFFLFFBQVEsQ0FBQyxDQUFDO0lBQ3pHLENBQUM7SUFFRCxtQkFBbUIsQ0FBQyxRQUFnQjtRQUNsQyxPQUFPLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxJQUFJLENBQUMsa0JBQWtCLEVBQUUsZ0JBQWdCLENBQUMsYUFBYSxFQUFFLFFBQVEsQ0FBQyxDQUFDO0lBQ3pHLENBQUM7SUFFRCxrQkFBa0IsQ0FBQyxRQUFnQjtRQUNqQyxPQUFPLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxJQUFJLENBQUMscUJBQXFCLEVBQUUsZ0JBQWdCLENBQUMsVUFBVSxFQUFFLFFBQVEsQ0FBQyxDQUFDO0lBQ3pHLENBQUM7SUFFRCxvQkFBb0IsQ0FBQyxRQUFnQjtRQUNuQyxPQUFPLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxJQUFJLENBQUMscUJBQXFCLEVBQUUsZ0JBQWdCLENBQUMsYUFBYSxFQUFFLFFBQVEsQ0FBQyxDQUFDO0lBQzVHLENBQUM7SUFFRCxvQkFBb0IsQ0FBQyxRQUFnQjtRQUNuQyxPQUFPLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxJQUFJLENBQUMscUJBQXFCLEVBQUUsZ0JBQWdCLENBQUMsYUFBYSxFQUFFLFFBQVEsQ0FBQyxDQUFDO0lBQzVHLENBQUM7SUFFRCxxQkFBcUIsQ0FBQyxZQUFvQjtRQUN4QyxPQUFPLElBQUksQ0FBQywyQkFBMkIsQ0FBQyxJQUFJLENBQUMsa0JBQWtCLEVBQUUsZ0JBQWdCLENBQUMsV0FBVyxFQUFFLFlBQVksQ0FBQyxDQUFDO0lBQy9HLENBQUM7SUFFRCx1QkFBdUIsQ0FBQyxZQUFvQjtRQUMxQyxPQUFPLElBQUksQ0FBQywyQkFBMkIsQ0FBQyxJQUFJLENBQUMsa0JBQWtCLEVBQUUsZ0JBQWdCLENBQUMsY0FBYyxFQUFFLFlBQVksQ0FBQyxDQUFDO0lBQ2xILENBQUM7SUFFRCxrQkFBa0I7UUFDaEIsT0FBTyxJQUFJLENBQUMsa0JBQWtCLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxLQUFLLGdCQUFnQixDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUM3RyxDQUFDO0lBRUQsb0JBQW9CO1FBQ2xCLE9BQU8sSUFBSSxDQUFDLGtCQUFrQixDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksS0FBSyxnQkFBZ0IsQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDaEgsQ0FBQztJQUVELG9CQUFvQjtRQUNsQixPQUFPLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLEtBQUssZ0JBQWdCLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ2hILENBQUM7SUFFRCxtQkFBbUI7UUFDakIsT0FBTyxJQUFJLENBQUMsa0JBQWtCLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxLQUFLLGdCQUFnQixDQUFDLFdBQVcsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7SUFDdkgsQ0FBQztJQUVELHlJQUF5STtJQUV6SSx5REFBeUQ7SUFDekQsZ0JBQWdCLENBQUMsUUFBZ0I7UUFDL0IsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FDdEIsU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFDbEIsR0FBRyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUMxQyxDQUFDO0lBQ0osQ0FBQztJQUVELGVBQWUsQ0FBQyxRQUFnQjs7UUFDOUIsYUFBTyxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssMENBQUUsZUFBZSxDQUFDLFFBQVEsRUFBRTtJQUN2RCxDQUFDO0lBRU8sc0JBQXNCO1FBQzVCLElBQUksNEJBQTRCLEdBQUcsQ0FBQyxDQUFDO1FBQ3JDLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUNyQixJQUFJLENBQUMsbUJBQW1CLEVBQUUsQ0FBQyxJQUFJLENBQzdCLFNBQVMsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLDRCQUE0QixLQUFLLE1BQU0sQ0FBQyxDQUM3RCxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsRUFBRTtZQUNuQixJQUFLLDRCQUE0QixHQUFHLE1BQU0sRUFBRTtnQkFDMUMsTUFBTSxPQUFPLEdBQUcsNEJBQTRCLEdBQUcsTUFBTSxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxDQUFDLGtCQUFrQixDQUFDO2dCQUNwRyxNQUFNLEdBQUcsR0FBRyxHQUFHLDRCQUE0QixHQUFHLE1BQU0sSUFBSSxPQUFPLGlCQUFpQixDQUFDO2dCQUNqRixJQUFJLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsT0FBTyxFQUFFLEdBQUcsRUFBRSxFQUFFLEVBQUUsS0FBSyxDQUFDLENBQUM7YUFDL0Q7WUFDRCw0QkFBNEIsR0FBRyxNQUFNLENBQUM7UUFDeEMsQ0FBQyxDQUFDLENBQ0gsQ0FBQztJQUNKLENBQUM7SUFFRCx5SUFBeUk7SUFFekksWUFBWTtRQUNWLE9BQU8sSUFBSSxDQUFDLG9CQUFvQixFQUFFLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ25ELENBQUM7SUFFRCxVQUFVO1FBQ1IsSUFBSSxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsRUFBRTtZQUMxQixJQUFJLENBQUMsZ0JBQWdCLEdBQUcsSUFBSSxDQUFDO1lBQzdCLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQyxTQUFTLEVBQUUsQ0FBQztZQUM5QixJQUFJLENBQUMsV0FBVyxFQUFFLENBQUMsU0FBUyxFQUFFLENBQUM7U0FDaEM7SUFDSCxDQUFDO0lBRUQsb0JBQW9CO1FBQ2xCLE9BQU8sSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUM5QixTQUFTLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxFQUN0QixJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQ1AsU0FBUyxDQUFDLEdBQUcsQ0FBQyxFQUFFO1lBQ2QsT0FBTyxDQUFDLEdBQUcsQ0FBQywwQkFBMEIsQ0FBQyxDQUFDO1lBQ3hDLE1BQU0sY0FBYyxHQUFHLFlBQVksQ0FBQyxPQUFPLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztZQUM5RCxNQUFNLFNBQVMsR0FBRywyQkFBMkIsR0FBRyxHQUFHLENBQUMsRUFBRSxDQUFDO1lBQ3ZELE1BQU0sUUFBUSxHQUFHLENBQUMsQ0FBQSxjQUFjLGFBQWQsY0FBYyx1QkFBZCxjQUFjLENBQUUsUUFBUSxHQUFHLEtBQUssQ0FBQyxVQUFVLEdBQUUsQ0FBQyxDQUFDLFNBQVMsR0FBRyxjQUFjLEdBQUcsY0FBYyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7Z0JBQ3ZILG9CQUFvQixvQkFBb0IsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDL0QsdURBQXVEO1lBQ3ZELElBQUksSUFBSSxDQUFDLG1CQUFtQixFQUFFO2dCQUM1QixJQUFJLENBQUMsbUJBQW1CLENBQUMsV0FBVyxFQUFFLENBQUM7YUFDeEM7WUFDRCxJQUFJLENBQUMsbUJBQW1CLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsQ0FBQyxJQUFJLENBQ2hELFNBQVMsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsRUFDdEMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQ3BELENBQUMsU0FBUyxFQUFFLENBQUM7WUFFZCxPQUFPLElBQUksQ0FBQyxRQUFRLENBQUM7UUFDdkIsQ0FBQyxDQUFDLENBQ0gsQ0FBQztJQUNKLENBQUM7SUFFRCxXQUFXLENBQUMsYUFBeUIsRUFBRSxVQUFVLEVBQUUsRUFBRSxFQUFFLEtBQUssRUFBRSxFQUFFLEVBQUU7UUFDaEUsT0FBTyxDQUFDLEdBQUcsQ0FBQyx5QkFBeUIsQ0FBQyxDQUFDO1FBQ3ZDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsa0JBQWtCLEVBQUUsVUFBVSxDQUFDLFVBQVUsRUFBRSxVQUFVLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDNUgsT0FBTyxJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQzlCLFNBQVMsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUMsR0FBRyxDQUFDLEVBQ3RCLElBQUksQ0FBQyxDQUFDLENBQUMsRUFDUCxTQUFTLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksQ0FDdEMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLHVCQUF1QixDQUFDLE1BQU0sRUFBRSxVQUFVLENBQUMsQ0FBQyxFQUNoRixTQUFTLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQywwQkFBMEIsR0FBRyxDQUFDLEVBQUUsb0JBQW9CLG9CQUFvQixDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FDekgsU0FBUyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxFQUN0QyxTQUFTLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FDcEQsQ0FBQyxDQUNILENBQUMsQ0FDSCxDQUFDO0lBQ0osQ0FBQztJQUVELDBJQUEwSTtJQUUxSSxrRkFBa0Y7SUFDbEYsYUFBYSxDQUFDLFVBQTJCO1FBQ3ZDLElBQUksZUFBdUIsQ0FBQztRQUM1QixPQUFPLENBQUMsR0FBRyxDQUFDLHlCQUF5QixJQUFJLENBQUMsU0FBUyxDQUFDLGVBQWUsQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUN4RSxPQUFPLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUM1QixHQUFHLENBQUMsTUFBTSxDQUFDLEVBQUU7WUFDWCxJQUFJLE1BQU0sQ0FBQyxVQUFVLEdBQUcsQ0FBQyxFQUFFO2dCQUN6QixJQUFJLENBQUMsZ0JBQWdCLENBQUMsa0JBQWtCLENBQ3RDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyx1QkFBdUIsRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLEVBQUUsVUFBVSxDQUFDLENBQ3pGLENBQUM7YUFDSDtRQUNILENBQUMsQ0FBQyxFQUNGLFNBQVMsQ0FBQyxNQUFNLENBQUMsRUFBRTtZQUNqQixPQUFPLENBQUMsR0FBRyxDQUFDLHdDQUF3QyxDQUFDLENBQUM7WUFDdEQsTUFBTSxDQUFDLFVBQVUsQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDO1lBQ25DLE9BQU8sTUFBTSxDQUFDLElBQUksQ0FBQyxFQUFFLE1BQU0sRUFBRSxFQUFFLE9BQU8sRUFBRSxDQUFDLEdBQUcsb0JBQW9CLENBQUMsT0FBTyxFQUFFLEdBQUcsQ0FBQyxPQUFPLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBQy9GLENBQUMsQ0FBQyxFQUNGLFNBQVMsQ0FBQyxDQUFDLElBQThCLEVBQUUsRUFBRTtZQUMzQyxlQUFlLEdBQUcsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDO1lBQzdCLGVBQWUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDM0IsT0FBTyxDQUFDLEdBQUcsQ0FDVCw0Q0FBNEMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxlQUFlLENBQUMsVUFBVSxDQUFDLElBQUksSUFBSSxDQUFDLFNBQVMsQ0FBQyxlQUFlLENBQUMsRUFBRSxDQUM1SCxDQUFDO1lBQ0YsSUFBSSxlQUFlLENBQUMsVUFBVSxHQUFHLENBQUMsSUFBSSxlQUFlLENBQUMsS0FBSyxFQUFFO2dCQUMzRCxJQUFJLENBQUMsZ0JBQWdCLENBQUMsa0JBQWtCLENBQ3RDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxzQkFBc0IsRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxlQUFlLEVBQUUsVUFBVSxDQUFDLENBQ2pHLENBQUM7YUFDSDtZQUNELElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1lBQzlCLE9BQU8sSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQzVCLENBQUMsQ0FBQyxFQUNGLFNBQVMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUM1QixFQUNELFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQ2xCLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxlQUFlLENBQUMsQ0FDM0IsQ0FBQztJQUNKLENBQUM7SUFFRCxVQUFVLENBQUMsTUFBYyxFQUFFLFVBQTJCO1FBQ3BELE9BQU87WUFDTCx5Q0FBeUM7WUFDekMsTUFBTSxFQUFFLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDLEVBQUU7WUFDMUMsUUFBUSxFQUFFLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDLFVBQVUsQ0FBQyxJQUFJO1lBQ3pELFNBQVMsRUFBRSxNQUFNLENBQUMsRUFBRTtZQUNwQixXQUFXLEVBQUUsTUFBTSxDQUFDLFVBQVU7WUFDOUIsWUFBWSxFQUFFLFVBQVU7U0FDekIsQ0FBQztJQUNKLENBQUM7SUFFRCwwSUFBMEk7SUFFMUksYUFBYTtRQUNYLE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQztJQUN4QixDQUFDO0lBRUQsbUJBQW1CO1FBQ2pCLE9BQU8sSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDLElBQUksQ0FDOUIsR0FBRyxDQUFDLENBQUMsT0FBc0IsRUFBRSxFQUFFLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxNQUFNLEtBQUssUUFBUSxDQUFDLENBQUMsQ0FDcEYsQ0FBQztJQUNKLENBQUM7SUFFRCxnREFBZ0Q7SUFDaEQsd0ZBQXdGO0lBQ3hGLDRDQUE0QztJQUM1QyxtQkFBbUIsQ0FBQyxlQUFvQztRQUN0RCxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLEVBQUU7WUFDekIsT0FBTztTQUNSO1FBRUQsTUFBTSxlQUFlLEdBQXNCLGVBQWUsQ0FBQyxHQUFHLENBQUMsYUFBYSxDQUFDLEVBQUU7WUFDN0UsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsS0FBSyxhQUFhLENBQUMsRUFBRSxDQUFDLENBQUM7WUFDaEYsSUFBSSxDQUFDLFdBQVcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxRQUFRLEVBQUU7Z0JBQzNDLE9BQU8sRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDO2FBQ2pCO1lBRUQsTUFBTSxVQUFVLEdBQUcsV0FBVyxDQUFDLFFBQVEsR0FBRyxhQUFhLENBQUMsUUFBUSxDQUFDO1lBQ2pFLElBQUksVUFBVSxJQUFJLENBQUMsRUFBRTtnQkFDbkIsV0FBVyxDQUFDLFFBQVEsR0FBRyxVQUFVLENBQUM7Z0JBQ2xDLE9BQU8sV0FBVyxDQUFDLElBQUksRUFBRSxDQUFDO2FBQzNCO2lCQUFNO2dCQUNMLFdBQVcsQ0FBQyxRQUFRLEdBQUcsQ0FBQyxDQUFDO2dCQUN6QixXQUFXLENBQUMsTUFBTSxHQUFHLFNBQVMsQ0FBQztnQkFDL0IsT0FBTyxRQUFRLENBQUMsQ0FBQyxXQUFXLENBQUMsSUFBSSxFQUFFLEVBQUUsV0FBVyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQzthQUMzRDtRQUNILENBQUMsQ0FBQyxDQUFDO1FBRUgsT0FBTyxRQUFRLENBQUMsZUFBZSxDQUFDLENBQUMsSUFBSSxDQUNuQyxTQUFTLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLG9CQUFvQixFQUFFLENBQUMsRUFDNUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUNSLENBQUM7SUFDSixDQUFDO0lBRUQ7OztPQUdHO0lBQ0gseUJBQXlCLENBQUMsWUFBb0I7UUFDNUMsT0FBTyxJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksQ0FDNUIsU0FBUyxDQUFDLE1BQU0sQ0FBQyxFQUFFO1lBQ2pCLE1BQU0sR0FBRyxHQUFHLEdBQUcsQ0FBQyxDQUFDLE9BQU8sbUJBQW1CLE1BQU0sQ0FBQyxFQUFFLGlEQUFpRCxZQUFZLEVBQUUsQ0FBQztZQUNwSCxPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxFQUFFLE1BQU0sRUFBRSxFQUFFLE9BQU8sRUFBRSxDQUFDLGVBQWUsQ0FBQyxFQUFFLEVBQUUsQ0FBOEMsQ0FBQztRQUNySCxDQUFDLENBQUMsRUFDRixTQUFTLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxNQUFNLENBQUMsVUFBVSxJQUFJLENBQUMsTUFBTSxDQUFDLEVBQ2pELEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRTtZQUNSLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxHQUFHLEVBQUUsQ0FBQztZQUM5QyxLQUFLLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQ2hCLE9BQU8sS0FBSyxDQUFDO1FBQ2YsQ0FBQyxDQUFDLENBQ0gsQ0FBQztJQUNKLENBQUM7SUFFRCx5SUFBeUk7SUFFekksNkNBQTZDO0lBQzdDLDJFQUEyRTtJQUMzRSxtQ0FBbUM7SUFDbkMsZUFBZSxDQUFDLGFBQXFCO1FBQ25DLE9BQU8sSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQzVCLFNBQVMsQ0FBQyxNQUFNLENBQUMsRUFBRTtZQUNqQixJQUFJLE1BQU0sQ0FBQyxZQUFZLEtBQUssYUFBYSxFQUFFO2dCQUN6QyxPQUFPLENBQUMsR0FBRyxDQUFDLHlCQUF5QixJQUFJLENBQUMsU0FBUyxDQUFDLGFBQWEsQ0FBQyxFQUFFLENBQUMsQ0FBQztnQkFDdEUsT0FBTyxFQUFFLEVBQVEsQ0FBQzthQUNuQjtZQUNELE9BQU8sQ0FBQyxHQUFHLENBQUMsOEJBQThCLElBQUksQ0FBQyxTQUFTLENBQUMsYUFBYSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBQzNFLE1BQU0sQ0FBQyxZQUFZLEdBQUcsYUFBYSxDQUFDO1lBQ3BDLE9BQU8sTUFBTSxDQUFDLElBQUksQ0FBQyxFQUFFLE1BQU0sRUFBRSxvQkFBb0IsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUN2RCxTQUFTLENBQUMsQ0FBQyxJQUE4QixFQUFFLEVBQUU7Z0JBQzNDLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLENBQUM7Z0JBQ3RCLE9BQU8sSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO1lBQzVCLENBQUMsQ0FBQyxDQUNILENBQUM7UUFDSixDQUFDLENBQUMsQ0FDSCxDQUFDO0lBQ0osQ0FBQztJQUVELDBJQUEwSTtJQUUxSSxxQkFBcUIsQ0FBQyxJQUFVLEVBQUUsT0FBTyxHQUFHLEVBQUUsRUFBRSwwQkFBMEIsR0FBRyxLQUFLO1FBQ2hGLE9BQU8sSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQzVCLFNBQVMsQ0FBQyxNQUFNLENBQUMsRUFBRTtZQUNqQixNQUFNLEdBQUcsR0FBRyxHQUFHLENBQUMsQ0FBQyxPQUFPLG1CQUFtQixNQUFNLENBQUMsRUFBRSwyQkFBMkI7Z0JBQzdFLG9CQUFvQixvQkFBb0IsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsMEJBQTBCLENBQUMsQ0FBQyxDQUFDLHdCQUF3QixDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDO1lBQzlILE1BQU0sUUFBUSxHQUFhLElBQUksUUFBUSxFQUFFLENBQUM7WUFDMUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxTQUFTLEVBQUUsSUFBSSxDQUFDLENBQUM7WUFDakMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxTQUFTLEVBQUUsT0FBTyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO1lBQzlDLE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxFQUFFLFFBQVEsQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxRQUFrQyxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNySCxDQUFDLENBQUMsQ0FDSCxDQUFDO0lBQ0osQ0FBQztJQUVELDBJQUEwSTtJQUUxSTs7Ozs7Ozs7T0FRRztJQUNILGtCQUFrQixDQUFDLFNBQW1CLEVBQUUsTUFBYyxFQUFFLFVBQXNCLEVBQUUsZUFBZSxHQUFHLElBQUk7UUFDcEcsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixDQUFDLEtBQUssQ0FBQztRQUM1QyxTQUFTLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQzNCLEtBQUssQ0FBQyxJQUFJLENBQUM7WUFDVCxJQUFJLEVBQUUsZUFBZSxDQUFDLENBQUMsQ0FBQyxnQkFBZ0IsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLGdCQUFnQixDQUFDLGdCQUFnQjtZQUN2RixNQUFNLEVBQUUsRUFBRSxRQUFRLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRTtTQUN6QyxDQUFDLENBQ0gsQ0FBQztRQUNGLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDdEMsQ0FBQztJQUVELHVCQUF1QixDQUFDLFNBQW1CLEVBQUUsVUFBc0I7UUFDakUsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixDQUFDLEtBQUssQ0FBQztRQUMvQyxTQUFTLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQzNCLFFBQVEsQ0FBQyxJQUFJLENBQUM7WUFDWixJQUFJLEVBQUUsZ0JBQWdCLENBQUMsYUFBYTtZQUNwQyxNQUFNLEVBQUUsRUFBRSxRQUFRLEVBQUUsVUFBVSxFQUFFO1NBQ2pDLENBQUMsQ0FDSCxDQUFDO1FBQ0YsSUFBSSxDQUFDLGtCQUFrQixDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUN6QyxDQUFDO0lBRUQscUJBQXFCLENBQUMsU0FBbUIsRUFBRSxNQUFjLEVBQUUsVUFBc0I7UUFDL0UsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixDQUFDLEtBQUssQ0FBQztRQUMvQyxTQUFTLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQzNCLFFBQVEsQ0FBQyxJQUFJLENBQUM7WUFDWixJQUFJLEVBQUUsZ0JBQWdCLENBQUMsYUFBYTtZQUNwQyxNQUFNLEVBQUUsRUFBRSxRQUFRLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRTtTQUN6QyxDQUFDLENBQ0gsQ0FBQztRQUNGLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7SUFDekMsQ0FBQztJQUVELHNCQUFzQixDQUFDLFFBQWdCLEVBQUUsdUJBQXVFLEVBQzlHLFVBQXNCO1FBQ3RCLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxLQUFLLENBQUM7UUFDNUMsdUJBQXVCLENBQUMsT0FBTyxDQUFDLG9CQUFvQixDQUFDLEVBQUUsQ0FDckQsS0FBSyxDQUFDLElBQUksQ0FBQztZQUNULElBQUksRUFBRSxnQkFBZ0IsQ0FBQyxXQUFXO1lBQ2xDLE1BQU0sRUFBRSxFQUFFLFFBQVEsRUFBRSxZQUFZLEVBQUUsb0JBQW9CLENBQUMsWUFBWSxFQUFFLFdBQVcsRUFBRSxvQkFBb0IsQ0FBQyxLQUFLLEVBQUUsVUFBVSxFQUFFO1NBQzNILENBQUMsQ0FDSCxDQUFDO1FBQ0YsSUFBSSxDQUFDLGtCQUFrQixDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUN0QyxDQUFDO0lBRUQsMkJBQTJCLENBQUMsV0FBd0IsRUFBRSxRQUFnQixFQUFFLGFBQXVCLEVBQUUsVUFBc0I7UUFDckgsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixDQUFDLEtBQUssQ0FBQztRQUMvQyxhQUFhLENBQUMsT0FBTyxDQUFDLFlBQVksQ0FBQyxFQUFFLENBQ25DLFFBQVEsQ0FBQyxJQUFJLENBQUM7WUFDWixJQUFJLEVBQUUsZ0JBQWdCLENBQUMsY0FBYztZQUNyQyxNQUFNLEVBQUUsRUFBRSxXQUFXLEVBQUUsUUFBUSxFQUFFLFlBQVksRUFBRSxVQUFVLEVBQUU7U0FDNUQsQ0FBQyxDQUNILENBQUM7UUFDRixJQUFJLENBQUMsa0JBQWtCLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQ3pDLENBQUM7SUFFRCxxQkFBcUIsQ0FBQyxXQUF3QixFQUFFLFFBQWdCLEVBQUUsV0FBbUIsRUFBRSxVQUFzQjtRQUMzRyxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsa0JBQWtCLENBQUMsS0FBSyxDQUFDO1FBQy9DLFFBQVEsQ0FBQyxJQUFJLENBQUM7WUFDWixJQUFJLEVBQUUsZ0JBQWdCLENBQUMsY0FBYztZQUNyQyxNQUFNLEVBQUUsRUFBRSxXQUFXLEVBQUUsUUFBUSxFQUFFLFdBQVcsRUFBRSxVQUFVLEVBQUU7U0FDM0QsQ0FBQyxDQUFDO1FBQ0gsSUFBSSxDQUFDLGtCQUFrQixDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUN6QyxDQUFDO0lBRUQseUlBQXlJO0lBRWpJLGlCQUFpQjtRQUN2QixJQUFJLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxLQUFLLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRTtZQUM1QyxNQUFNLGdCQUFnQixHQUFHLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO1lBQ2pELElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxJQUFJLENBQUMsQ0FBQyxHQUFHLGdCQUFnQixDQUFDLENBQUMsQ0FBQztZQUN2RCxJQUFJLGdCQUFnQixDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUU7Z0JBQy9CLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxHQUFHLEVBQUU7b0JBQ3hELElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUM7b0JBQ3BDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLENBQzFCLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxnQkFBZ0IsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMscUJBQXFCLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQ3BILENBQUM7b0JBQ0YsSUFBSSxDQUFDLHFCQUFxQixHQUFHLEVBQUUsQ0FBQztnQkFDbEMsQ0FBQyxDQUFDLENBQUM7YUFDSjtTQUNGO0lBQ0gsQ0FBQztJQUVEOzs7T0FHRztJQUNLLGdCQUFnQjs7UUFDdEIsTUFBTSxLQUFLLEdBQW1CLEVBQUUsQ0FBQztRQUNqQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDVixJQUFJLGFBQWEsR0FBRyxJQUFJLENBQUMsa0JBQWtCLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3JELElBQUksZUFBZSxHQUFHLEtBQUssQ0FBQztRQUM1QixPQUFPLE9BQUEsSUFBSSxDQUFDLGtCQUFrQixDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsMENBQUUsSUFBSSxPQUFLLGFBQWEsYUFBYixhQUFhLHVCQUFiLGFBQWEsQ0FBRSxJQUFJLENBQUEsSUFBSSxDQUFDLGVBQWUsRUFBRTtZQUN6RixhQUFhLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUNqRCxlQUFlLEdBQUcsSUFBSSxDQUFDLHFDQUFxQyxDQUFDLEtBQUssRUFBRSxhQUFhLENBQUMsQ0FBQztZQUNuRixDQUFDLEVBQUUsQ0FBQztTQUNMO1FBQ0QsT0FBTyxLQUFLLENBQUM7SUFDZixDQUFDO0lBRUQ7O09BRUc7SUFDSyxxQ0FBcUMsQ0FBQyxLQUFxQixFQUFFLGFBQTJCO1FBQzlGLE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyx3QkFBd0IsQ0FBQyxLQUFLLEVBQUUsYUFBYSxDQUFDLENBQUM7UUFDeEUsSUFBSSxXQUFXLEtBQUssQ0FBQyxDQUFDLEVBQUU7WUFDdEIsSUFBSSxDQUFDLHFCQUFxQixDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQztZQUNwRCxLQUFLLENBQUMsV0FBVyxDQUFDLEdBQUcsYUFBYSxDQUFDO1NBQ3BDO2FBQU07WUFDTCxJQUFJLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxLQUFLLEVBQUUsYUFBYSxDQUFDLEVBQUU7Z0JBQ25ELE9BQU8sSUFBSSxDQUFDO2FBQ2I7aUJBQU07Z0JBQ0wsS0FBSyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQzthQUMzQjtTQUNGO1FBQ0QsT0FBTyxLQUFLLENBQUM7SUFDZixDQUFDO0lBRU8sb0JBQW9CLENBQUMsS0FBcUIsRUFBRSxhQUEyQjtRQUM3RSwySEFBMkg7UUFDM0gsb0ZBQW9GO1FBQ3BGLE9BQU8sQ0FBQyxhQUFhLENBQUMsSUFBSSxLQUFLLGdCQUFnQixDQUFDLGFBQWE7WUFDekQsS0FBSyxDQUFDLE1BQU0sR0FBRyxDQUFDO1lBQ2hCLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsTUFBTSxLQUFLLGFBQWEsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDcEUsK0hBQStIO1lBQy9ILGtGQUFrRjtZQUNsRixDQUFDLENBQUMsYUFBYSxDQUFDLElBQUksS0FBSyxnQkFBZ0IsQ0FBQyxXQUFXLElBQUksYUFBYSxDQUFDLElBQUksS0FBSyxnQkFBZ0IsQ0FBQyxjQUFjLENBQUM7Z0JBQzlHLEtBQUssQ0FBQyxNQUFNLEdBQUcsQ0FBQztnQkFDaEIsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxRQUFRLEtBQUssYUFBYSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDO0lBQzdFLENBQUM7SUFFRDs7T0FFRztJQUNLLHdCQUF3QixDQUFDLEtBQXFCLEVBQUUsYUFBMkI7UUFDakYsSUFBSSxhQUFhLENBQUMsSUFBSSxLQUFLLGdCQUFnQixDQUFDLGFBQWE7WUFDdkQsS0FBSyxDQUFDLE1BQU0sR0FBRyxDQUFDO1lBQ2hCLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsUUFBUSxLQUFLLGFBQWEsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLEVBQ3JFO1lBQ0EsT0FBTyxLQUFLLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxRQUFRLEtBQUssYUFBYSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUNqRixpSEFBaUg7WUFDakgsaURBQWlEO1NBQ2xEO2FBQU0sSUFBSSxhQUFhLENBQUMsSUFBSSxLQUFLLGdCQUFnQixDQUFDLGNBQWMsRUFBRztZQUNsRSxPQUFPLEtBQUssQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxFQUFFLEtBQUssYUFBYSxDQUFDLE1BQU0sQ0FBQyxXQUFXLENBQUMsRUFBRSxDQUFDLENBQUM7WUFDN0YscUdBQXFHO1NBQ3RHO2FBQU0sSUFDTCxDQUFDLENBQUMsZ0JBQWdCLENBQUMsV0FBVyxFQUFFLGdCQUFnQixDQUFDLGNBQWMsRUFBRSxnQkFBZ0IsQ0FBQyxhQUFhLENBQUMsQ0FBQyxRQUFRLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxFQUM3SDtZQUNBLE9BQU8sS0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsUUFBUSxLQUFLLGFBQWEsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDakYsZ0dBQWdHO1NBQ2pHO2FBQU07WUFDTCxPQUFPLEtBQUssQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FDekIsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxZQUFZLEtBQUssYUFBYSxDQUFDLE1BQU0sQ0FBQyxZQUFZO2dCQUMzRCxDQUFDLENBQUMsTUFBTSxDQUFDLFFBQVEsS0FBSyxhQUFhLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FDcEQsQ0FBQztZQUNGLHdIQUF3SDtTQUN6SDtJQUNILENBQUM7SUFFTyxtQkFBbUIsQ0FBQyxnQkFBZ0M7UUFDMUQsUUFBUSxnQkFBZ0IsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLEVBQUU7WUFDaEMsS0FBSyxnQkFBZ0IsQ0FBQyxVQUFVO2dCQUM5QixPQUFPLElBQUksQ0FBQyxVQUFVLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztZQUUzQyxLQUFLLGdCQUFnQixDQUFDLGdCQUFnQjtnQkFDcEMsT0FBTyxJQUFJLENBQUMsNEJBQTRCLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztZQUU3RCxLQUFLLGdCQUFnQixDQUFDLGFBQWE7Z0JBQ2pDLE9BQU8sSUFBSSxDQUFDLGFBQWEsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO1lBRTlDLEtBQUssZ0JBQWdCLENBQUMsYUFBYTtnQkFDakMsT0FBTyxJQUFJLENBQUMsbUJBQW1CLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztZQUVwRCxLQUFLLGdCQUFnQixDQUFDLFdBQVc7Z0JBQy9CLE9BQU8sSUFBSSxDQUFDLHNCQUFzQixDQUFDLGdCQUFnQixDQUFDLENBQUM7WUFFdkQsS0FBSyxnQkFBZ0IsQ0FBQyxjQUFjO2dCQUNsQyxPQUFPLElBQUksQ0FBQyx5QkFBeUIsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO1lBRTFELEtBQUssZ0JBQWdCLENBQUMsY0FBYztnQkFDbEMsT0FBTyxJQUFJLENBQUMsNkJBQTZCLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztZQUU5RDtnQkFDRSxPQUFPLEVBQUUsRUFBRSxDQUFDO1NBQ2Y7SUFDSCxDQUFDO0lBRUQseUlBQXlJO0lBRXpJOzs7Ozs7T0FNRztJQUNLLFVBQVUsQ0FBQyxZQUE0QixFQUFFLGVBQWUsR0FBRyxJQUFJO1FBQ3JFLE9BQU8sSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQzVCLFNBQVMsQ0FBQyxNQUFNLENBQUMsRUFBRTtZQUNqQixNQUFNLEdBQUcsR0FBRyxHQUFHLENBQUMsQ0FBQyxPQUFPLG1CQUFtQixNQUFNLENBQUMsRUFBRSxVQUFVO2dCQUM5RCxvQkFBb0Isb0JBQW9CLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxlQUFlLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztZQUN6RyxNQUFNLElBQUksR0FBRyxFQUFFLElBQUksRUFBRSxZQUFZLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLFNBQVMsRUFBRSxDQUFDLENBQUMsTUFBTSxDQUFDLFFBQVEsRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQztZQUMxRyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsb0JBQW9CLENBQUMsWUFBWSxDQUFDLENBQUM7WUFDekQsT0FBTyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUNuQyxTQUFTLENBQUMsQ0FBQyxDQUEyQixFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLEVBQ3hELFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRTs7Z0JBQ1osVUFBSSxDQUFDLGFBQUQsQ0FBQyx1QkFBRCxDQUFDLENBQUUsSUFBSSwwQ0FBRSxFQUFFLEVBQUU7b0JBQ2YsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQztvQkFDbkIsT0FBTyxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7aUJBQzNCO2dCQUVELE9BQU8sRUFBRSxFQUFRLENBQUM7WUFDcEIsQ0FBQyxDQUFDLENBQ0gsQ0FBQztRQUNKLENBQUMsQ0FBQyxDQUNILENBQUM7SUFDSixDQUFDO0lBRU8sNEJBQTRCLENBQUMsWUFBNEI7UUFDL0QsT0FBTyxJQUFJLENBQUMsVUFBVSxDQUFDLFlBQVksRUFBRSxLQUFLLENBQUMsQ0FBQztJQUM5QyxDQUFDO0lBRU8sYUFBYSxDQUFDLGVBQStCO1FBQ25ELE9BQU8sSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQzVCLFNBQVMsQ0FBQyxNQUFNLENBQUMsRUFBRTtZQUNqQixNQUFNLEdBQUcsR0FBRyxHQUFHLENBQUMsQ0FBQyxPQUFPLG1CQUFtQixNQUFNLENBQUMsRUFBRSx3QkFBd0I7Z0JBQzFFLGVBQWUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxHQUFHLG9CQUFvQixvQkFBb0IsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDcEksSUFBSSxDQUFDLGdCQUFnQixDQUFDLHVCQUF1QixDQUFDLGVBQWUsQ0FBQyxDQUFDO1lBQy9ELE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUMvQixTQUFTLENBQUMsQ0FBQyxDQUEyQixFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLEVBQ3hELFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRTs7Z0JBQ1osVUFBSSxDQUFDLGFBQUQsQ0FBQyx1QkFBRCxDQUFDLENBQUUsSUFBSSwwQ0FBRSxFQUFFLEVBQUU7b0JBQ2YsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQztvQkFDbkIsT0FBTyxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7aUJBQzNCO2dCQUVELE9BQU8sRUFBRSxFQUFRLENBQUM7WUFDcEIsQ0FBQyxDQUFDLENBQ0gsQ0FBQztRQUNKLENBQUMsQ0FBQyxDQUNILENBQUM7SUFDSixDQUFDO0lBRU8sbUJBQW1CLENBQUMsZUFBK0I7UUFDekQsT0FBTyxJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksQ0FDNUIsU0FBUyxDQUFDLE1BQU0sQ0FBQyxFQUFFO1lBQ2pCLE1BQU0sR0FBRyxHQUFHLEdBQUcsQ0FBQyxDQUFDLE9BQU8sbUJBQW1CLE1BQU0sQ0FBQyxFQUFFLDBCQUEwQixlQUFlLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLE1BQU0sZ0JBQWdCO2dCQUM5SCxlQUFlLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsR0FBRyxvQkFBb0Isb0JBQW9CLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDO1lBQ2xJLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxzQkFBc0IsQ0FBQyxlQUFlLENBQUMsQ0FBQztZQUM5RCxPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQ2xDLFNBQVMsQ0FBQyxDQUFDLENBQTJCLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxVQUFVLENBQUMsRUFDOUQsU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFOztnQkFDWixVQUFJLENBQUMsYUFBRCxDQUFDLHVCQUFELENBQUMsQ0FBRSxJQUFJLDBDQUFFLEVBQUUsRUFBRTtvQkFDZixJQUFJLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDO29CQUNuQixPQUFPLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztpQkFDM0I7Z0JBRUQsT0FBTyxFQUFFLEVBQVEsQ0FBQztZQUNwQixDQUFDLENBQUMsQ0FDSCxDQUFDO1FBQ0osQ0FBQyxDQUFDLENBQ0gsQ0FBQztJQUNKLENBQUM7SUFFRDs7T0FFRztJQUNLLHNCQUFzQixDQUFDLGdCQUFnQztRQUM3RCxPQUFPLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUM1QixTQUFTLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLEVBQ3RDLFNBQVMsQ0FBQyxNQUFNLENBQUMsRUFBRTtZQUNqQixNQUFNLFFBQVEsR0FBRyxnQkFBZ0IsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLEVBQUU7Z0JBQzdDLE1BQU0sY0FBYyxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQztnQkFDcEUsTUFBTSxHQUFHLEdBQUcsR0FBRyxDQUFDLENBQUMsT0FBTyxtQkFBbUIsTUFBTSxDQUFDLEVBQUUsbUJBQW1CLE1BQU0sQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLEVBQUUsaUJBQWlCO29CQUNsSCxrQkFBa0IsTUFBTSxDQUFDLE1BQU0sQ0FBQyxZQUFZLHFCQUFxQixNQUFNLENBQUMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxZQUFZLENBQUMsRUFBRSxFQUFFO29CQUM1RyxXQUFXLGNBQWMsRUFBRSxDQUFDO2dCQUM5QixPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsQ0FBQztZQUNsQyxDQUFDLENBQUMsQ0FBQztZQUNILE9BQU8sUUFBUSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQzVCLENBQUMsQ0FBQyxFQUNGLFNBQVMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUMsRUFDcEMsU0FBUyxDQUFDLEdBQUcsRUFBRSxDQUFDLEVBQUUsQ0FBTyxJQUFJLENBQUMsQ0FBQyxDQUFDLG1GQUFtRjtTQUNwSCxDQUFDO0lBQ0osQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0sseUJBQXlCLENBQUMsbUJBQW1DO1FBQ25FLE9BQU8sSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQzVCLFNBQVMsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsRUFDdEMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxFQUFFO1lBQ2pCLE1BQU0sUUFBUSxHQUFHLG1CQUFtQixDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsRUFBRTtnQkFDaEQsTUFBTSxjQUFjLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDO2dCQUNwRSxNQUFNLEdBQUcsR0FBRyxDQUFDLENBQUMsT0FBTyxHQUFHLGtCQUFrQixHQUFHLE1BQU0sQ0FBQyxFQUFFO29CQUNwRCxrQkFBa0IsR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxFQUFFO29CQUNqRCxtQ0FBbUMsR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLFlBQVk7b0JBQ2hFLG9CQUFvQixHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLFlBQVksQ0FBQyxFQUFFO29CQUNoRSxVQUFVLEdBQUcsY0FBYyxDQUFDO2dCQUM5QixPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsQ0FBQztZQUNsQyxDQUFDLENBQUMsQ0FBQztZQUNILE9BQU8sUUFBUSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQzVCLENBQUMsQ0FBQyxFQUNGLFNBQVMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUMsRUFDcEMsU0FBUyxDQUFDLEdBQUcsRUFBRSxDQUFDLEVBQUUsQ0FBTyxJQUFJLENBQUMsQ0FBQyxDQUFDLG1GQUFtRjtTQUNwSCxDQUFDO0lBQ0osQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0ssNkJBQTZCLENBQUMsa0JBQWtDO1FBQ3RFLE1BQU0sUUFBUSxHQUFHLGtCQUFrQixDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsRUFBRTtZQUMvQyxNQUFNLENBQUMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxRQUFRLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxXQUFXLENBQUM7WUFDL0QsT0FBTyxNQUFNLENBQUMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUMxQyxDQUFDLENBQUMsQ0FBQztRQUNILE9BQU8sUUFBUSxDQUFDLFFBQVEsQ0FBQyxDQUFDLElBQUksQ0FDNUIsU0FBUyxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQyxFQUNwQyxTQUFTLENBQUMsR0FBRyxFQUFFLENBQUMsRUFBRSxDQUFPLElBQUksQ0FBQyxDQUFDLENBQUMsbUZBQW1GO1NBQ3BILENBQUM7SUFDSixDQUFDO0lBRUQseUlBQXlJO0lBRXpJOztPQUVHO0lBQ0ssaUJBQWlCLENBQUMsTUFBYztRQUN0QyxJQUFJLElBQUksQ0FBQyxZQUFZLENBQUMsU0FBUyxDQUFDLEtBQUssRUFBRTtZQUNyQyxZQUFZLENBQUMsVUFBVSxDQUFDLGdCQUFnQixDQUFDLENBQUM7U0FDM0M7YUFBTTtZQUNMLFlBQVksQ0FBQyxPQUFPLENBQUMsZ0JBQWdCLEVBQUUsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1NBQ25EO1FBQ0QsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDM0IsT0FBTyxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQztJQUMzRSxDQUFDO0lBRUQ7Ozs7T0FJRztJQUNLLFVBQVUsQ0FBQyxHQUE2QjtRQUM5QyxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUM7UUFDMUIsTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUNqQixJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUMzQixPQUFPLE1BQU0sQ0FBQztJQUNoQixDQUFDO0lBRUQsMElBQTBJO0lBRTFJOzs7T0FHRztJQUNLLFVBQVU7UUFDaEIsT0FBTyxJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQzlCLFNBQVMsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUMsR0FBRyxDQUFDLEVBQ3RCLFNBQVMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsb0JBQW9CLEVBQUUsQ0FBQyxDQUM3QyxDQUFDO0lBQ0osQ0FBQztJQUVPLFdBQVc7UUFDakIsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FDdEIsU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFDbEIsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUNQLFNBQVMsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxXQUFXLENBQUMsQ0FBQyxFQUN4RSxTQUFTLENBQUMsQ0FBQyxPQUFpQixFQUFFLEVBQUU7WUFDOUIsTUFBTSxNQUFNLEdBQVcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUM7WUFDM0MsT0FBTyxJQUFJLENBQUMsa0JBQWtCLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxDQUN6QyxHQUFHLENBQUMsT0FBTyxDQUFDLEVBQUU7Z0JBQ1osTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixDQUFDLE9BQU8sRUFBRSxPQUFPLENBQUMsQ0FBQztnQkFDOUQsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLHdDQUF3QyxDQUFDLE9BQU8sRUFBRSxXQUFXLENBQUMsQ0FBQztnQkFDbEYsSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7Z0JBQ2pDLElBQUksQ0FBQywwQkFBMEIsR0FBRyxLQUFLLENBQUM7Z0JBQ3hDLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztZQUNqRCxDQUFDLENBQUMsQ0FDSCxDQUFDO1FBQ0osQ0FBQyxDQUFDLENBQ0gsQ0FBQztJQUNKLENBQUM7SUFFTyxrQkFBa0IsQ0FBQyxNQUFjO1FBQ3ZDLElBQUksQ0FBQyxNQUFNLElBQUksQ0FBQyxNQUFNLENBQUMsVUFBVSxJQUFJLE1BQU0sQ0FBQyxVQUFVLENBQUMsS0FBSyxHQUFHLENBQUMsRUFBRTtZQUNoRSxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUN4QixPQUFPLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1NBQ3JDO1FBRUQsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLEtBQUssR0FBRyxjQUFjLENBQUMsZUFBZSxDQUFDLENBQUM7UUFDdkYsT0FBTyxRQUFRLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsc0JBQXNCLENBQUMsTUFBTSxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUN2RyxHQUFHLENBQUMsQ0FBQyxXQUE4QyxFQUFFLEVBQUU7WUFDckQsNkRBQTZEO1lBQzdELE1BQU0sT0FBTyxHQUFJLE9BQU8sQ0FBQyxXQUFXLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFtQixDQUFDO1lBQzdFLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQzdCLE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUM7UUFDOUIsQ0FBQyxDQUFDLENBQ0gsQ0FBQztJQUNKLENBQUM7SUFFTyxVQUFVLENBQUMsS0FBMEI7UUFDM0Msc0dBQXNHO1FBQ3RHLE1BQU0sWUFBWSxHQUFrQixPQUFPLENBQUMsR0FBRyxLQUFLLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQztRQUU1RixNQUFNLFVBQVUsR0FBRyxZQUFZLENBQUMsTUFBTSxDQUFDLENBQUMsS0FBSyxFQUFFLEtBQUssRUFBRSxFQUFFO1lBQ3RELE1BQU0sSUFBSSxHQUFHLEtBQUssQ0FBQyxVQUFVLENBQUMsc0JBQXNCLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsT0FBTyxLQUFLLEtBQUssQ0FBQyxVQUFVLENBQUMsa0JBQWtCLENBQUMsQ0FBQyxDQUFDO1lBQ3BILEtBQUssSUFBSSxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUMsUUFBUSxJQUFJLENBQUMsQ0FBQyxHQUFHLFVBQVUsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQztZQUMzRSxPQUFPLEtBQUssQ0FBQztRQUNmLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUVOLE9BQU87WUFDTCxZQUFZLEVBQUUsS0FBSyxDQUFDLE1BQU07WUFDMUIsWUFBWSxFQUFFLFlBQVksQ0FBQyxNQUFNO1lBQ2pDLFVBQVU7U0FDWCxDQUFDO0lBQ0osQ0FBQztJQUVPLHNCQUFzQixDQUFDLE1BQWMsRUFBRSxJQUFZO1FBQ3pELElBQUksR0FBRyxHQUFHLEdBQUcsQ0FBQyxDQUFDLE9BQU8sbUJBQW1CLE1BQU0sQ0FBQyxFQUFFLGlCQUFpQixDQUFDO1FBQ3BFLEdBQUcsR0FBRyxHQUFHLEdBQUcscURBQXFELElBQUksZUFBZSxjQUFjLENBQUMsZUFBZSxFQUFFLENBQUM7UUFFckgsT0FBTyxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQzVCLFNBQVMsQ0FBQyxDQUFDLElBQXFDLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsRUFDckUsR0FBRyxDQUFDLENBQUMsSUFBcUMsRUFBRSxFQUFFO1lBQzVDLE1BQU0sYUFBYSxHQUFHLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxhQUFhLEVBQUUsQ0FBQztZQUNoRSxhQUFhLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ3pCLE9BQU8sYUFBYSxDQUFDO1FBQ3ZCLENBQUMsQ0FBQyxDQUNILENBQUM7SUFDSixDQUFDO0lBRU8sd0NBQXdDLENBQUMsT0FBaUIsRUFBRSxXQUEwQjtRQUM1RixPQUFPLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxNQUFNLEVBQUUsR0FBRyxFQUFFLEVBQUU7WUFDakMsTUFBTSxVQUFVLEdBQUcsV0FBVyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUM7WUFDakQsSUFBSSxXQUFXLEdBQUcsR0FBRyxDQUFDO1lBQ3RCLE1BQU0sTUFBTSxHQUFHLE1BQU0sQ0FBQyxjQUFjLElBQUksUUFBUSxDQUFDLE1BQU0sQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDLENBQUM7WUFFcEUsV0FBVyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLEVBQUU7Z0JBQ3JDLE1BQU0sWUFBWSxHQUFHLEtBQUssQ0FBQyxVQUFVLENBQUMsc0JBQXNCLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsT0FBTyxLQUFLLEtBQUssQ0FBQyxVQUFVLENBQUMsa0JBQWtCLENBQUMsQ0FBQyxDQUFDO2dCQUNsSSxNQUFNLEdBQUcsR0FBRyxLQUFLLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQztnQkFDdEMsTUFBTSxTQUFTLEdBQUcsVUFBVSxDQUFDLFlBQVksQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDO2dCQUN6RCxNQUFNLHVCQUF1QixHQUFHLEtBQUssQ0FBQyxVQUFVLENBQUMsTUFBTSxJQUFJLENBQUMsQ0FBQztnQkFFN0QsV0FBVyxJQUFJLENBQUMsR0FBRyxHQUFHLFNBQVMsQ0FBQyxHQUFHLHVCQUF1QixDQUFDO1lBQzdELENBQUMsQ0FBQyxDQUFDO1lBQ0gsTUFBTSxhQUFhLEdBQUcsV0FBVyxHQUFHLE1BQU0sQ0FBQztZQUUzQyxPQUFPLGlCQUFpQixDQUFDLFVBQVUsQ0FBQyxNQUFNLEVBQUUsVUFBVSxFQUFFLGFBQWEsRUFBRSxXQUFXLEVBQUUsV0FBVyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7UUFDeEcsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQyxHQUFHLE9BQU8sQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQ25HLENBQUM7SUFFTyxrQkFBa0IsQ0FBQyxPQUFpQixFQUFFLE9BQXNCO1FBQ2xFLE9BQU8sT0FBTyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsRUFBRTtZQUMxQixNQUFNLFdBQVcsR0FBRyxFQUFFLEtBQUssRUFBRSxFQUFFLEVBQUUsUUFBUSxFQUFFLEVBQUUsRUFBRSxZQUFZLEVBQUUsRUFBRSxFQUFFLE9BQU8sRUFBRSxFQUFFLEVBQUUsR0FBRyxFQUFFLEVBQUUsRUFBaUIsQ0FBQztZQUN2RyxPQUFPO2lCQUNKLE1BQU0sQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUM7aUJBQ25FLE9BQU8sQ0FBQyxLQUFLLENBQUMsRUFBRTtnQkFDZixNQUFNLFNBQVMsR0FBRyxLQUFLLENBQUMsVUFBVSxDQUFDLGtCQUFrQixDQUFDLENBQUM7Z0JBQ3ZELElBQUksU0FBUyxFQUFFO29CQUNiLFFBQVEsS0FBSyxDQUFDLE1BQU0sRUFBRTt3QkFDcEIsS0FBSyxlQUFlLENBQUMsQ0FBQzs0QkFDcEIsV0FBVyxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7NEJBQ3JDLE1BQU07eUJBQ1A7d0JBQ0QsS0FBSyxTQUFTLENBQUMsQ0FBQzs0QkFDZCxXQUFXLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQzs0QkFDaEMsTUFBTTt5QkFDUDt3QkFDRCxPQUFPLENBQUMsQ0FBQzs0QkFDUCxXQUFXLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQzs0QkFDOUIsTUFBTTt5QkFDUDtxQkFDRjtpQkFDRjtxQkFBTTtvQkFDTCxXQUFXLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztpQkFDbEM7Z0JBQ0QsV0FBVyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDOUIsQ0FBQyxDQUFDLENBQUM7WUFDTCxPQUFPLFdBQVcsQ0FBQztRQUNyQixDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7O0FBejJCTSw4QkFBZSxHQUFHLEVBQUUsQ0FBQzs0RUFEakIsY0FBYztzREFBZCxjQUFjLFdBQWQsY0FBYyxtQkFGYixNQUFNO2tEQUVQLGNBQWM7Y0FIMUIsVUFBVTtlQUFDO2dCQUNWLFVBQVUsRUFBRSxNQUFNO2FBQ25CIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSHR0cENsaWVudCB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbi9odHRwJztcbmltcG9ydCB7IEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IGZsYXR0ZW4sIHVuaW9uQnkgfSBmcm9tICdsb2Rhc2gtZXMnO1xuaW1wb3J0IHsgRG9jdW1lbnRDb2xsZWN0aW9uLCBEb2N1bWVudFJlc291cmNlLCBTZXJ2aWNlIH0gZnJvbSAnbmd4LWpzb25hcGknO1xuaW1wb3J0IHsgQmVoYXZpb3JTdWJqZWN0LCBmb3JrSm9pbiwgT2JzZXJ2YWJsZSwgb2YsIFN1YnNjcmlwdGlvbiB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgZGVib3VuY2VUaW1lLCBtYXAsIHNraXBXaGlsZSwgc3dpdGNoTWFwLCB0YWtlLCB0YXAgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBCYXNrZXQsIEJhc2tldEVudHJ5LCBCYXNrZXRQcmV2aWV3TGluZSwgTGluZUVudHJpZXMsIFJlY2lwZSB9IGZyb20gJy4uL19tb2RlbHMnO1xuaW1wb3J0IHsgQmFza2V0QWN0aW9uIH0gZnJvbSAnLi4vX3R5cGVzL2Jhc2tldC1hY3Rpb24nO1xuaW1wb3J0IHsgQmFza2V0QWN0aW9uVHlwZSB9IGZyb20gJy4uL190eXBlcy9iYXNrZXQtYWN0aW9uLXR5cGUuZW51bSc7XG5pbXBvcnQgeyBCYXNrZXRTdGF0cyB9IGZyb20gJy4uL190eXBlcy9iYXNrZXQtc3RhdHMnO1xuaW1wb3J0IHsgQ29tcGFyYWJsZVByb2R1Y3QgfSBmcm9tICcuLi9fdHlwZXMvYnVpbGRlZC9jb21wYXJhYmxlLXByb2R1Y3QnO1xuaW1wb3J0IHsgQ3VzdG9tUHJvcGVydGllcywgRXZlbnRUcmFjZSB9IGZyb20gJy4uL190eXBlcy9ldmVudC10cmFjZSc7XG5pbXBvcnQgeyBNZXNzYWdlVHlwZSB9IGZyb20gJy4uL190eXBlcy9tZXNzYWdlLXR5cGUuZW51bSc7XG5pbXBvcnQgeyBlbnZpcm9ubWVudCBhcyBlIH0gZnJvbSAnLi4vZW52aXJvbm1lbnRzL2Vudmlyb25tZW50JztcbmltcG9ydCB7IEFuYWx5dGljc1NlcnZpY2UgfSBmcm9tICcuL2FuYWx5dGljcy5zZXJ2aWNlJztcbmltcG9ydCB7IEJhc2tldEVudHJpZXNTZXJ2aWNlIH0gZnJvbSAnLi9iYXNrZXQtZW50cmllcy5zZXJ2aWNlJztcbmltcG9ydCB7IFBvaW50T2ZTYWxlc1NlcnZpY2UgfSBmcm9tICcuL3BvaW50LW9mLXNhbGVzLnNlcnZpY2UnO1xuaW1wb3J0IHsgUmVjaXBlc1NlcnZpY2UgfSBmcm9tICcuL3JlY2lwZXMuc2VydmljZSc7XG5pbXBvcnQgeyBUb2FzdGVyU2VydmljZSB9IGZyb20gJy4vdG9hc3Rlci5zZXJ2aWNlJztcbmltcG9ydCB7IFVzZXJTZXJ2aWNlIH0gZnJvbSAnLi91c2VyLnNlcnZpY2UnO1xuXG5jb25zdCBCQVNLRVRfU1BBUlNFX0ZJRUxEUyA9IHtcbiAgYmFza2V0czogWyd0b3RhbC1wcmljZScsICdwcmljZWJvb2sta2V5JywgJ3JlY2lwZXMtaW5mb3MnLCAnY29tcGxldGlvbiddXG59O1xuXG5cbkBJbmplY3RhYmxlKHtcbiAgcHJvdmlkZWRJbjogJ3Jvb3QnXG59KVxuZXhwb3J0IGNsYXNzIEJhc2tldHNTZXJ2aWNlIGV4dGVuZHMgU2VydmljZTxCYXNrZXQ+IHtcbiAgc3RhdGljIGVudHJpZXNQZXJQYWdlcyA9IDMwO1xuXG4gIHJlc291cmNlID0gQmFza2V0O1xuICB0eXBlID0gJ2Jhc2tldHMnO1xuICBfYmFza2V0JCA9IG5ldyBCZWhhdmlvclN1YmplY3Q8QmFza2V0PihudWxsKTtcbiAgX2Jhc2tldFByZXZpZXckID0gbmV3IEJlaGF2aW9yU3ViamVjdDxCYXNrZXRQcmV2aWV3TGluZVtdPihudWxsKTtcbiAgYmFza2V0U3RhdHMkID0gbmV3IEJlaGF2aW9yU3ViamVjdDxCYXNrZXRTdGF0cz4obnVsbCk7XG4gIGJhc2tldElzRmV0Y2hpbmcgPSBmYWxzZTtcbiAgYmFza2V0UHJldmlld0lzQ2FsY3VsYXRpbmcgPSBmYWxzZTtcbiAgYmFza2V0SW5pdENhbGxlZCA9IGZhbHNlO1xuXG4gIHByaXZhdGUgYmFza2V0QWN0aW9uc1F1ZXVlID0gbmV3IEJlaGF2aW9yU3ViamVjdDxCYXNrZXRBY3Rpb25bXT4oW10pO1xuICBwcml2YXRlIGN1cnJlbnRTdWJzY3JpcHRpb246IFN1YnNjcmlwdGlvbjtcbiAgcHJpdmF0ZSBfZW50cmllcyQgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PEJhc2tldEVudHJ5W10+KFtdKTtcbiAgcHJpdmF0ZSBhY3Rpb25zQmVpbmdQcm9jZXNzZWQgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PEJhc2tldEFjdGlvbltdPihbXSk7XG4gIHByaXZhdGUgYWN0aW9uc0JlaW5nT3ZlcnJpZGVuOiBCYXNrZXRBY3Rpb25bXSA9IFtdO1xuICBwcml2YXRlIHN1YnNjcmlwdGlvbnM6IFN1YnNjcmlwdGlvbltdID0gW107XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBodHRwOiBIdHRwQ2xpZW50LFxuICAgIHByaXZhdGUgYmFza2V0RW50cmllc1NlcnZpY2U6IEJhc2tldEVudHJpZXNTZXJ2aWNlLFxuICAgIHByaXZhdGUgcG9zU2VydmljZTogUG9pbnRPZlNhbGVzU2VydmljZSxcbiAgICBwcml2YXRlIHJlY2lwZXNTZXJ2aWNlOiBSZWNpcGVzU2VydmljZSxcbiAgICBwcml2YXRlIGFuYWx5dGljc1NlcnZpY2U6IEFuYWx5dGljc1NlcnZpY2UsXG4gICAgcHJpdmF0ZSB1c2Vyc1NlcnZpY2U6IFVzZXJTZXJ2aWNlLFxuICAgIHByaXZhdGUgdG9hc3RlclNlcnZpY2U6IFRvYXN0ZXJTZXJ2aWNlXG4gICkge1xuICAgIHN1cGVyKCk7XG4gICAgdGhpcy5yZWdpc3RlcigpO1xuICAgIHRoaXMuc3Vic2NyaXB0aW9ucy5wdXNoKFxuICAgICAgdGhpcy5iYXNrZXRBY3Rpb25zUXVldWUucGlwZShcbiAgICAgICAgZGVib3VuY2VUaW1lKDIwMCksXG4gICAgICAgIHNraXBXaGlsZShhY3Rpb25zID0+IGFjdGlvbnMubGVuZ3RoID09PSAwIHx8IHRoaXMuYWN0aW9uc0JlaW5nUHJvY2Vzc2VkLnZhbHVlLmxlbmd0aCA+IDApLFxuICAgICAgICB0YXAoKCkgPT4gdGhpcy5lbXB0eUFjdGlvbnNRdWV1ZSgpKVxuICAgICAgKS5zdWJzY3JpYmUoKVxuICAgICk7XG4gICAgaWYgKHRoaXMucmVjaXBlc1NlcnZpY2UuY29uZmlybWF0aW9uVG9hc3Rlcikge1xuICAgICAgdGhpcy5zaG93UmVjaXBlQWRkZWRUb2FzdGVyKCk7XG4gICAgfVxuICB9XG5cbiAgLyoqICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiBHRVRURVJTICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiAqKi9cblxuICAvKipcbiAgICogV2Ugd2FudCBiYXNrZXQkIHRvIGJlIGEgc2luZ2xldG9uIHRoYXQgYWx3YXlzIHJldHVybnMgdGhlIHNhbWUgYmFza2V0LCBzbyBpdCBpcyBmZXRjaGVkIG9ubHkgd2hlbiBuZWNlc3NhcnkuXG4gICAqIEF0IGFueSBwb2ludCBpbiB0aW1lIHRoZSBiYXNrZXQgY2FuIGJlIGZldGNoZWQgdmlhIHRoZSBpbml0QmFza2V0IGZ1bmN0aW9uIChpZiB3ZSB3YW50IHRvIGZldGNoIGl0IG9uIHN0YXJ0dXAgdG8gc2F2ZSB0aW1lIGxhdGVyKVxuICAgKiBCdXQgaWYgaW5pdEJhc2tldCBpcyBub3QgY2FsbGVkLCB0aGUgYmFza2V0IHdpbGwgb25seSBiZSBmZXRjaGVkIHRoZSAxc3QgdGltZSBpdCBpcyBuZWVkZWQuXG4gICAqL1xuICBnZXQgYmFza2V0JCgpOiBCZWhhdmlvclN1YmplY3Q8QmFza2V0PiB7XG4gICAgaWYgKCF0aGlzLl9iYXNrZXQkLnZhbHVlICYmICF0aGlzLmJhc2tldElzRmV0Y2hpbmcpIHtcbiAgICAgIHRoaXMuYmFza2V0SXNGZXRjaGluZyA9IHRydWU7XG4gICAgICB0aGlzLmluaXRCYXNrZXQoKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX2Jhc2tldCQ7XG4gIH1cblxuICAvKipcbiAgICogYmFza2V0UHJldmlldyQgc2hvdWxkIGFsc28gYmUgYSBzaW5nbGV0b24sIGFuZCBhcyB3ZWxsIGFzIGJhc2tldCQgaXQgd2lsbCBiZSBjYWxjdWxhdGVkIGZvciB0aGUgZmlyc3QgdGltZSBvbmx5IHdoZW4gbmVjZXNzYXJ5XG4gICAqIG9yIGlmIGxvYWRQcmV2aWV3IGlzIGNhbGxlZCBiZWZvcmVcbiAgICovXG4gIGdldCBiYXNrZXRQcmV2aWV3JCgpOiBCZWhhdmlvclN1YmplY3Q8QmFza2V0UHJldmlld0xpbmVbXT4ge1xuICAgIGlmICghdGhpcy5fYmFza2V0UHJldmlldyQudmFsdWUgJiYgIXRoaXMuYmFza2V0UHJldmlld0lzQ2FsY3VsYXRpbmcpIHtcbiAgICAgIHRoaXMuYmFza2V0UHJldmlld0lzQ2FsY3VsYXRpbmcgPSB0cnVlO1xuICAgICAgdGhpcy5pbml0QmFza2V0KCk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLl9iYXNrZXRQcmV2aWV3JDtcbiAgfVxuXG4gIC8qKlxuICAgKiBUbyB1c2Ugd2hlbiBuZWVkaW5nIHRvIGJlIHN1cmUgdGhhdCBiYXNrZXQgd2FzIGZldGNoZWQgYmVmb3JlIGRvaW5nIGFuIGFjdGlvbiB0aGF0IGRvZXNuJ3QgbmVlZCB0byBzdGF5IHN1YnNjcmliZWQgdG8gYmFza2V0JFxuICAgKiBUaGlzIG1ldGhvZCBpcyBtZWFudCB0byBiZSBhbiBlcXVpdmFsZW50IG9mIGJhc2tldCQudmFsdWUgYnV0IGFzeW5jaHJvbm91c1xuICAgKi9cbiAgZ2V0IHdhaXRGb3JCYXNrZXQoKTogT2JzZXJ2YWJsZTxCYXNrZXQ+IHtcbiAgICByZXR1cm4gdGhpcy5iYXNrZXQkLnBpcGUoXG4gICAgICBza2lwV2hpbGUoYiA9PiAhYiksXG4gICAgICB0YWtlKDEpXG4gICAgKTtcbiAgfVxuXG4gIC8qKiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiBRVUVVRSBVVElMUyBUTyBMT0NLIE1PUkUgQUNUSU9OUyBPUiBESVNQTEFZIExPQURFUlMgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogKiovXG5cbiAgLy8gVXRpbCBtZXRob2QgdG8gYXZvaWQgcmVwZWF0aW5nIHRvbyBtdWNoIGZvciB0aGUgbmV4dCA2IG1ldGhvZHNcbiAgcHJpdmF0ZSBzdWJqZWN0Q29udGFpbnNSZWNpcGVJZChzdWJqZWN0OiBCZWhhdmlvclN1YmplY3Q8QmFza2V0QWN0aW9uW10+LCB0eXBlOiBCYXNrZXRBY3Rpb25UeXBlLCByZWNpcGVJZDogc3RyaW5nKTogT2JzZXJ2YWJsZTxib29sZWFuPiB7XG4gICAgcmV0dXJuIHN1YmplY3QucGlwZShtYXAodmFsdWUgPT4gdmFsdWUuc29tZShhID0+IGEudHlwZSA9PT0gdHlwZSAmJiBhLnBhcmFtcy5yZWNpcGVJZCA9PT0gcmVjaXBlSWQpKSk7XG4gIH1cblxuICAvLyBVdGlsIG1ldGhvZCB0byBhdm9pZCByZXBlYXRpbmcgdG9vIG11Y2ggZm9yIHRoZSBuZXh0IDYgbWV0aG9kc1xuICBwcml2YXRlIHN1YmplY3RDb250YWluc0luZ3JlZGllbnRJZChcbiAgICBzdWJqZWN0OiBCZWhhdmlvclN1YmplY3Q8QmFza2V0QWN0aW9uW10+LCB0eXBlOiBCYXNrZXRBY3Rpb25UeXBlLCBpbmdyZWRpZW50SWQ6IHN0cmluZ1xuICApOiBPYnNlcnZhYmxlPGJvb2xlYW4+IHtcbiAgICByZXR1cm4gc3ViamVjdC5waXBlKG1hcCh2YWx1ZSA9PiB2YWx1ZS5zb21lKGEgPT4gYS50eXBlID09PSB0eXBlICYmIGEucGFyYW1zLmluZ3JlZGllbnRJZCA9PT0gaW5ncmVkaWVudElkKSkpO1xuICB9XG5cbiAgcmVjaXBlV2lsbEJlQWRkZWQocmVjaXBlSWQ6IHN0cmluZyk6IE9ic2VydmFibGU8Ym9vbGVhbj4ge1xuICAgIHJldHVybiB0aGlzLnN1YmplY3RDb250YWluc1JlY2lwZUlkKHRoaXMuYmFza2V0QWN0aW9uc1F1ZXVlLCBCYXNrZXRBY3Rpb25UeXBlLkFERF9SRUNJUEUsIHJlY2lwZUlkKTtcbiAgfVxuXG4gIHJlY2lwZVdpbGxCZVJlbW92ZWQocmVjaXBlSWQ6IHN0cmluZyk6IE9ic2VydmFibGU8Ym9vbGVhbj4ge1xuICAgIHJldHVybiB0aGlzLnN1YmplY3RDb250YWluc1JlY2lwZUlkKHRoaXMuYmFza2V0QWN0aW9uc1F1ZXVlLCBCYXNrZXRBY3Rpb25UeXBlLlJFTU9WRV9SRUNJUEUsIHJlY2lwZUlkKTtcbiAgfVxuXG4gIHJlY2lwZVdpbGxCZVVwZGF0ZWQocmVjaXBlSWQ6IHN0cmluZyk6IE9ic2VydmFibGU8Ym9vbGVhbj4ge1xuICAgIHJldHVybiB0aGlzLnN1YmplY3RDb250YWluc1JlY2lwZUlkKHRoaXMuYmFza2V0QWN0aW9uc1F1ZXVlLCBCYXNrZXRBY3Rpb25UeXBlLlVQREFURV9SRUNJUEUsIHJlY2lwZUlkKTtcbiAgfVxuXG4gIHJlY2lwZUlzQmVpbmdBZGRlZChyZWNpcGVJZDogc3RyaW5nKTogT2JzZXJ2YWJsZTxib29sZWFuPiB7XG4gICAgcmV0dXJuIHRoaXMuc3ViamVjdENvbnRhaW5zUmVjaXBlSWQodGhpcy5hY3Rpb25zQmVpbmdQcm9jZXNzZWQsIEJhc2tldEFjdGlvblR5cGUuQUREX1JFQ0lQRSwgcmVjaXBlSWQpO1xuICB9XG5cbiAgcmVjaXBlSXNCZWluZ1JlbW92ZWQocmVjaXBlSWQ6IHN0cmluZyk6IE9ic2VydmFibGU8Ym9vbGVhbj4ge1xuICAgIHJldHVybiB0aGlzLnN1YmplY3RDb250YWluc1JlY2lwZUlkKHRoaXMuYWN0aW9uc0JlaW5nUHJvY2Vzc2VkLCBCYXNrZXRBY3Rpb25UeXBlLlJFTU9WRV9SRUNJUEUsIHJlY2lwZUlkKTtcbiAgfVxuXG4gIHJlY2lwZUlzQmVpbmdVcGRhdGVkKHJlY2lwZUlkOiBzdHJpbmcpOiBPYnNlcnZhYmxlPGJvb2xlYW4+IHtcbiAgICByZXR1cm4gdGhpcy5zdWJqZWN0Q29udGFpbnNSZWNpcGVJZCh0aGlzLmFjdGlvbnNCZWluZ1Byb2Nlc3NlZCwgQmFza2V0QWN0aW9uVHlwZS5VUERBVEVfUkVDSVBFLCByZWNpcGVJZCk7XG4gIH1cblxuICBpbmdyZWRpZW50V2lsbEJlQWRkZWQoaW5ncmVkaWVudElkOiBzdHJpbmcpOiBPYnNlcnZhYmxlPGJvb2xlYW4+IHtcbiAgICByZXR1cm4gdGhpcy5zdWJqZWN0Q29udGFpbnNJbmdyZWRpZW50SWQodGhpcy5iYXNrZXRBY3Rpb25zUXVldWUsIEJhc2tldEFjdGlvblR5cGUuQUREX1BST0RVQ1QsIGluZ3JlZGllbnRJZCk7XG4gIH1cblxuICBpbmdyZWRpZW50V2lsbEJlUmVtb3ZlZChpbmdyZWRpZW50SWQ6IHN0cmluZyk6IE9ic2VydmFibGU8Ym9vbGVhbj4ge1xuICAgIHJldHVybiB0aGlzLnN1YmplY3RDb250YWluc0luZ3JlZGllbnRJZCh0aGlzLmJhc2tldEFjdGlvbnNRdWV1ZSwgQmFza2V0QWN0aW9uVHlwZS5SRU1PVkVfUFJPRFVDVCwgaW5ncmVkaWVudElkKTtcbiAgfVxuXG4gIHJlY2lwZXNXaWxsQmVBZGRlZCgpOiBPYnNlcnZhYmxlPGJvb2xlYW4+IHtcbiAgICByZXR1cm4gdGhpcy5iYXNrZXRBY3Rpb25zUXVldWUucGlwZShtYXAocXVldWUgPT4gcXVldWUuc29tZShhID0+IGEudHlwZSA9PT0gQmFza2V0QWN0aW9uVHlwZS5BRERfUkVDSVBFKSkpO1xuICB9XG5cbiAgcmVjaXBlc1dpbGxCZVJlbW92ZWQoKTogT2JzZXJ2YWJsZTxib29sZWFuPiB7XG4gICAgcmV0dXJuIHRoaXMuYmFza2V0QWN0aW9uc1F1ZXVlLnBpcGUobWFwKHF1ZXVlID0+IHF1ZXVlLnNvbWUoYSA9PiBhLnR5cGUgPT09IEJhc2tldEFjdGlvblR5cGUuUkVNT1ZFX1JFQ0lQRSkpKTtcbiAgfVxuXG4gIHJlY2lwZXNXaWxsQmVVcGRhdGVkKCk6IE9ic2VydmFibGU8Ym9vbGVhbj4ge1xuICAgIHJldHVybiB0aGlzLmJhc2tldEFjdGlvbnNRdWV1ZS5waXBlKG1hcChxdWV1ZSA9PiBxdWV1ZS5zb21lKGEgPT4gYS50eXBlID09PSBCYXNrZXRBY3Rpb25UeXBlLlVQREFURV9SRUNJUEUpKSk7XG4gIH1cblxuICBwcm9kdWN0c1dpbGxCZUFkZGVkKCk6IE9ic2VydmFibGU8bnVtYmVyPiB7XG4gICAgcmV0dXJuIHRoaXMuYmFza2V0QWN0aW9uc1F1ZXVlLnBpcGUobWFwKHF1ZXVlID0+IHF1ZXVlLmZpbHRlcihhID0+IGEudHlwZSA9PT0gQmFza2V0QWN0aW9uVHlwZS5BRERfUFJPRFVDVCkubGVuZ3RoKSk7XG4gIH1cblxuICAvKiogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiBVVElMUyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqICoqL1xuXG4gIC8vIENoZWNrIGlmIHRoZSByZWNpcGVJZCBpcyBpbiB0aGUgQmFza2V0J3MgcmVjaXBlcy1pbmZvc1xuICByZWNpcGVJc0luQmFza2V0KHJlY2lwZUlkOiBzdHJpbmcpOiBPYnNlcnZhYmxlPGJvb2xlYW4+IHtcbiAgICByZXR1cm4gdGhpcy5iYXNrZXQkLnBpcGUoXG4gICAgICBza2lwV2hpbGUoYiA9PiAhYiksXG4gICAgICBtYXAoYmFza2V0ID0+IGJhc2tldC5oYXNSZWNpcGUocmVjaXBlSWQpKVxuICAgICk7XG4gIH1cblxuICBndWVzdHNGb3JSZWNpcGUocmVjaXBlSWQ6IHN0cmluZyk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMuYmFza2V0JC52YWx1ZT8uZ3Vlc3RzRm9yUmVjaXBlKHJlY2lwZUlkKTtcbiAgfVxuXG4gIHByaXZhdGUgc2hvd1JlY2lwZUFkZGVkVG9hc3RlcigpOiB2b2lkIHtcbiAgICBsZXQgcHJldmlvdXNOdW1iZXJPZlByb2R1Y3RUb0FkZCA9IDA7XG4gICAgdGhpcy5zdWJzY3JpcHRpb25zLnB1c2goXG4gICAgICB0aGlzLnByb2R1Y3RzV2lsbEJlQWRkZWQoKS5waXBlKFxuICAgICAgICBza2lwV2hpbGUobnVtYmVyID0+IHByZXZpb3VzTnVtYmVyT2ZQcm9kdWN0VG9BZGQgPT09IG51bWJlcilcbiAgICAgICkuc3Vic2NyaWJlKG51bWJlciA9PiB7XG4gICAgICAgIGlmICggcHJldmlvdXNOdW1iZXJPZlByb2R1Y3RUb0FkZCA+IG51bWJlcikge1xuICAgICAgICAgIGNvbnN0IGFydGljbGUgPSBwcmV2aW91c051bWJlck9mUHJvZHVjdFRvQWRkIC0gbnVtYmVyID09PSAxID8gJ2FydGljbGUgYWpvdXTDqScgOiAnYXJ0aWNsZXMgYWpvdXTDqXMnO1xuICAgICAgICAgIGNvbnN0IG1zZyA9IGAke3ByZXZpb3VzTnVtYmVyT2ZQcm9kdWN0VG9BZGQgLSBudW1iZXJ9ICR7YXJ0aWNsZX0gw6Agdm90cmUgcGFuaWVyYDtcbiAgICAgICAgICB0aGlzLnRvYXN0ZXJTZXJ2aWNlLnNob3coTWVzc2FnZVR5cGUuU3VjY2VzcywgbXNnLCAnJywgZmFsc2UpO1xuICAgICAgICB9XG4gICAgICAgIHByZXZpb3VzTnVtYmVyT2ZQcm9kdWN0VG9BZGQgPSBudW1iZXI7XG4gICAgICB9KVxuICAgICk7XG4gIH1cblxuICAvKiogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogTE9BRCAvIFJFTE9BRCAvIFJFU0VUICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqICoqL1xuXG4gIHJlbG9hZEJhc2tldCgpOiBPYnNlcnZhYmxlPEJhc2tldD4ge1xuICAgIHJldHVybiB0aGlzLnJlZnJlc2hDdXJyZW50QmFza2V0KCkucGlwZSh0YWtlKDEpKTtcbiAgfVxuXG4gIGluaXRCYXNrZXQoKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLmJhc2tldEluaXRDYWxsZWQpIHtcbiAgICAgIHRoaXMuYmFza2V0SW5pdENhbGxlZCA9IHRydWU7XG4gICAgICB0aGlzLmxvYWRCYXNrZXQoKS5zdWJzY3JpYmUoKTtcbiAgICAgIHRoaXMubG9hZFByZXZpZXcoKS5zdWJzY3JpYmUoKTtcbiAgICB9XG4gIH1cblxuICByZWZyZXNoQ3VycmVudEJhc2tldCgpOiBPYnNlcnZhYmxlPEJhc2tldD4ge1xuICAgIHJldHVybiB0aGlzLnBvc1NlcnZpY2UucG9zJC5waXBlKFxuICAgICAgc2tpcFdoaWxlKHBvcyA9PiAhcG9zKSxcbiAgICAgIHRha2UoMSksXG4gICAgICBzd2l0Y2hNYXAocG9zID0+IHtcbiAgICAgICAgY29uc29sZS5sb2coJ1tNaWFtXSByZWZyZXNoaW5nIGJhc2tldCcpO1xuICAgICAgICBjb25zdCBjYWNoZWRCYXNrZXRJZCA9IGxvY2FsU3RvcmFnZS5nZXRJdGVtKCdfbWlhbS9iYXNrZXRJZCcpO1xuICAgICAgICBjb25zdCBiYXNlUm91dGUgPSAnY3VycmVudD9wb2ludF9vZl9zYWxlX2lkPScgKyBwb3MuaWQ7XG4gICAgICAgIGNvbnN0IGVuZHBvaW50ID0gKGNhY2hlZEJhc2tldElkPy50b1N0cmluZygpLm1hdGNoKC9eWzAtOV0rJC8pID8gYmFzZVJvdXRlICsgJyZtZXJnZV93aXRoPScgKyBjYWNoZWRCYXNrZXRJZCA6IGJhc2VSb3V0ZSkgK1xuICAgICAgICAgIGAmZmllbGRzW2Jhc2tldHNdPSR7QkFTS0VUX1NQQVJTRV9GSUVMRFMuYmFza2V0cy5qb2luKCcsJyl9YDtcbiAgICAgICAgLy8gQ2FuY2VsIGxhc3Qgc3Vic2NyaXB0aW9uIGJlZm9yZSBzdGFydGluZyBhbm90aGVyIG9uZVxuICAgICAgICBpZiAodGhpcy5jdXJyZW50U3Vic2NyaXB0aW9uKSB7XG4gICAgICAgICAgdGhpcy5jdXJyZW50U3Vic2NyaXB0aW9uLnVuc3Vic2NyaWJlKCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5jdXJyZW50U3Vic2NyaXB0aW9uID0gdGhpcy5nZXQoZW5kcG9pbnQpLnBpcGUoXG4gICAgICAgICAgc2tpcFdoaWxlKGJhc2tldCA9PiBiYXNrZXQuaXNfbG9hZGluZyksXG4gICAgICAgICAgc3dpdGNoTWFwKGJhc2tldCA9PiB0aGlzLnVwZGF0ZUxvY2FsQmFza2V0KGJhc2tldCkpXG4gICAgICAgICkuc3Vic2NyaWJlKCk7XG5cbiAgICAgICAgcmV0dXJuIHRoaXMuX2Jhc2tldCQ7XG4gICAgICB9KVxuICAgICk7XG4gIH1cblxuICByZXNldEJhc2tldChldmVudFRyYWNlOiBFdmVudFRyYWNlID0geyBvcmlnaW5QYXRoOiAnJywgcHJvcHM6IHt9IH0pOiBPYnNlcnZhYmxlPHZvaWQ+IHtcbiAgICBjb25zb2xlLmxvZygnW01pYW1dIHJlc2V0dGluZyBiYXNrZXQnKTtcbiAgICB0aGlzLmFuYWx5dGljc1NlcnZpY2Uuc2VuZEV2ZW50V2hlblJlYWR5KHRoaXMuYW5hbHl0aWNzU2VydmljZS5FVkVOVF9SRUNJUEVfUkVTRVQsIGV2ZW50VHJhY2Uub3JpZ2luUGF0aCwgZXZlbnRUcmFjZS5wcm9wcyk7XG4gICAgcmV0dXJuIHRoaXMucG9zU2VydmljZS5wb3MkLnBpcGUoXG4gICAgICBza2lwV2hpbGUocG9zID0+ICFwb3MpLFxuICAgICAgdGFrZSgxKSxcbiAgICAgIHN3aXRjaE1hcChwb3MgPT4gdGhpcy53YWl0Rm9yQmFza2V0LnBpcGUoXG4gICAgICAgIHRhcChiYXNrZXQgPT4gdGhpcy5hbmFseXRpY3NTZXJ2aWNlLnNlbmRFdmVudHNPZlJlc2V0QmFza2V0KGJhc2tldCwgZXZlbnRUcmFjZSkpLFxuICAgICAgICBzd2l0Y2hNYXAoKCkgPT4gdGhpcy5nZXQoYHJlc2V0P3BvaW50X29mX3NhbGVfaWQ9JHtwb3MuaWR9JmZpZWxkc1tiYXNrZXRzXT0ke0JBU0tFVF9TUEFSU0VfRklFTERTLmJhc2tldHMuam9pbignLCcpfWApLnBpcGUoXG4gICAgICAgICAgc2tpcFdoaWxlKGJhc2tldCA9PiBiYXNrZXQuaXNfbG9hZGluZyksXG4gICAgICAgICAgc3dpdGNoTWFwKGJhc2tldCA9PiB0aGlzLnVwZGF0ZUxvY2FsQmFza2V0KGJhc2tldCkpXG4gICAgICAgICkpXG4gICAgICApKVxuICAgICk7XG4gIH1cblxuICAvKiogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqIENPTkZJUk0gQkFTS0VUICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiAqKi9cblxuICAvLyBTZXQgYmFza2V0IGFzIGNvbmZpcm1lZCwgYW5kIHJldHVybnMgb25seSBvbmNlIHRoZSBuZXcgY3VycmVudCBsaXN0IGlzIHJldHVybmVkXG4gIGNvbmZpcm1CYXNrZXQodG90YWxQcmljZTogbnVtYmVyIHwgc3RyaW5nKTogT2JzZXJ2YWJsZTxCYXNrZXQ+IHtcbiAgICBsZXQgY29uZmlybWVkQmFza2V0OiBCYXNrZXQ7XG4gICAgY29uc29sZS5sb2coYFtNaWFtXSBDb25maXJtIGJhc2tldCAke0pTT04uc3RyaW5naWZ5KGNvbmZpcm1lZEJhc2tldCl9YCk7XG4gICAgcmV0dXJuIHRoaXMud2FpdEZvckJhc2tldC5waXBlKFxuICAgICAgdGFwKGJhc2tldCA9PiB7XG4gICAgICAgIGlmIChiYXNrZXQudG90YWxQcmljZSA+IDApIHtcbiAgICAgICAgICB0aGlzLmFuYWx5dGljc1NlcnZpY2Uuc2VuZEV2ZW50V2hlblJlYWR5KFxuICAgICAgICAgICAgdGhpcy5hbmFseXRpY3NTZXJ2aWNlLkVWRU5UX1BBWU1FTlRfQ09ORklSTUVELCBudWxsLCB0aGlzLmV2ZW50UHJvcHMoYmFza2V0LCB0b3RhbFByaWNlKVxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgIH0pLFxuICAgICAgc3dpdGNoTWFwKGJhc2tldCA9PiB7XG4gICAgICAgIGNvbnNvbGUubG9nKCdbTWlhbV0gU2F2ZSBiYXNrZXQgd2l0aCBjb25maXJtZWQ9dHJ1ZScpO1xuICAgICAgICBiYXNrZXQuYXR0cmlidXRlcy5jb25maXJtZWQgPSB0cnVlO1xuICAgICAgICByZXR1cm4gYmFza2V0LnNhdmUoeyBmaWVsZHM6IHsgYmFza2V0czogWy4uLkJBU0tFVF9TUEFSU0VfRklFTERTLmJhc2tldHMsIC4uLlsndG9rZW4nXV0gfSB9KTtcbiAgICAgIH0pLFxuICAgICAgc3dpdGNoTWFwKChyZXNwOiBEb2N1bWVudFJlc291cmNlPEJhc2tldD4pID0+IHtcbiAgICAgICAgY29uZmlybWVkQmFza2V0ID0gdGhpcy5uZXcoKTtcbiAgICAgICAgY29uZmlybWVkQmFza2V0LmZpbGwocmVzcCk7XG4gICAgICAgIGNvbnNvbGUubG9nKFxuICAgICAgICAgIGBbTWlhbV0gc2VuZCBwdXNoIGFuYWx5dGljcyBldmVudCBpZiA+IDA6ICR7SlNPTi5zdHJpbmdpZnkoY29uZmlybWVkQmFza2V0LnRvdGFsUHJpY2UpfSAke0pTT04uc3RyaW5naWZ5KGNvbmZpcm1lZEJhc2tldCl9YFxuICAgICAgICApO1xuICAgICAgICBpZiAoY29uZmlybWVkQmFza2V0LnRvdGFsUHJpY2UgPiAwICYmIGNvbmZpcm1lZEJhc2tldC50b2tlbikge1xuICAgICAgICAgIHRoaXMuYW5hbHl0aWNzU2VydmljZS5zZW5kRXZlbnRXaGVuUmVhZHkoXG4gICAgICAgICAgICB0aGlzLmFuYWx5dGljc1NlcnZpY2UuRVZFTlRfQkFTS0VUX0NPTkZJUk1FRCwgbnVsbCwgdGhpcy5ldmVudFByb3BzKGNvbmZpcm1lZEJhc2tldCwgdG90YWxQcmljZSlcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX2Jhc2tldCQubmV4dCh1bmRlZmluZWQpO1xuICAgICAgICByZXR1cm4gdGhpcy5yZXNldEJhc2tldCgpO1xuICAgICAgfSksXG4gICAgICBzd2l0Y2hNYXAoKCkgPT4gdGhpcy5fYmFza2V0JFxuICAgICAgKSxcbiAgICAgIHNraXBXaGlsZShiID0+ICFiKSxcbiAgICAgIG1hcCgoKSA9PiBjb25maXJtZWRCYXNrZXQpXG4gICAgKTtcbiAgfVxuXG4gIGV2ZW50UHJvcHMoYmFza2V0OiBCYXNrZXQsIHRvdGFsUHJpY2U6IG51bWJlciB8IHN0cmluZyk6IEN1c3RvbVByb3BlcnRpZXMge1xuICAgIHJldHVybiB7XG4gICAgICAvLyBpZiB5b3UgaGF2ZSBhIGJhc2tldCB5b3UgaGF2ZSBhIHBvcy4uLlxuICAgICAgcG9zX2lkOiB0aGlzLnBvc1NlcnZpY2UucG9zJC5nZXRWYWx1ZSgpLmlkLFxuICAgICAgcG9zX25hbWU6IHRoaXMucG9zU2VydmljZS5wb3MkLmdldFZhbHVlKCkuYXR0cmlidXRlcy5uYW1lLFxuICAgICAgYmFza2V0X2lkOiBiYXNrZXQuaWQsXG4gICAgICBtaWFtX2Ftb3VudDogYmFza2V0LnRvdGFsUHJpY2UsXG4gICAgICB0b3RhbF9hbW91bnQ6IHRvdGFsUHJpY2VcbiAgICB9O1xuICB9XG5cbiAgLyoqICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogQUNUSU9OUyBPTiBFTlRSSUVTICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogKiovXG5cbiAgYmFza2V0RW50cmllcygpOiBPYnNlcnZhYmxlPEJhc2tldEVudHJ5W10+IHtcbiAgICByZXR1cm4gdGhpcy5fZW50cmllcyQ7XG4gIH1cblxuICBhY3RpdmVCYXNrZXRFbnRyaWVzKCk6IE9ic2VydmFibGU8QmFza2V0RW50cnlbXT4ge1xuICAgIHJldHVybiB0aGlzLmJhc2tldEVudHJpZXMoKS5waXBlKFxuICAgICAgbWFwKChlbnRyaWVzOiBCYXNrZXRFbnRyeVtdKSA9PiBlbnRyaWVzLmZpbHRlcihlbnRyeSA9PiBlbnRyeS5zdGF0dXMgPT09ICdhY3RpdmUnKSlcbiAgICApO1xuICB9XG5cbiAgLy8gRGVjcmVhc2UgcXVhbnRpdHkgb24gYSBsaXN0IG9mIGJhc2tldCBlbnRyaWVzXG4gIC8vIElmIHRoZSBxdWFudGl0eSBnb2VzIGJlbG93IDEsIHRoZSBjb3JyZXNwb25kaW5nIGdyb2NlcmllcyBlbnRyeSdzIHN0YXR1cyBnZXRzIGRlbGV0ZWRcbiAgLy8gUmVsb2FkIGJhc2tldCBhZnRlciBhbGwgb2JqZWN0cyBhcmUgc2F2ZWRcbiAgcmVtb3ZlQmFza2V0RW50cmllcyhlbnRyaWVzVG9SZW1vdmU6IENvbXBhcmFibGVQcm9kdWN0W10pOiBPYnNlcnZhYmxlPGFueT4ge1xuICAgIGlmICghdGhpcy5fZW50cmllcyQudmFsdWUpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBzYXZlT2JzZXJ2YWJsZXM6IE9ic2VydmFibGU8YW55PltdID0gZW50cmllc1RvUmVtb3ZlLm1hcChlbnRyeVRvUmVtb3ZlID0+IHtcbiAgICAgIGNvbnN0IGJhc2tldEVudHJ5ID0gdGhpcy5fZW50cmllcyQudmFsdWUuZmluZChiZSA9PiBiZS5pZCA9PT0gZW50cnlUb1JlbW92ZS5pZCk7XG4gICAgICBpZiAoIWJhc2tldEVudHJ5IHx8ICFlbnRyeVRvUmVtb3ZlLnF1YW50aXR5KSB7XG4gICAgICAgIHJldHVybiBvZihudWxsKTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgZmluYWxDb3VudCA9IGJhc2tldEVudHJ5LnF1YW50aXR5IC0gZW50cnlUb1JlbW92ZS5xdWFudGl0eTtcbiAgICAgIGlmIChmaW5hbENvdW50ID49IDEpIHtcbiAgICAgICAgYmFza2V0RW50cnkucXVhbnRpdHkgPSBmaW5hbENvdW50O1xuICAgICAgICByZXR1cm4gYmFza2V0RW50cnkuc2F2ZSgpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgYmFza2V0RW50cnkucXVhbnRpdHkgPSAxO1xuICAgICAgICBiYXNrZXRFbnRyeS5zdGF0dXMgPSAnZGVsZXRlZCc7XG4gICAgICAgIHJldHVybiBmb3JrSm9pbihbYmFza2V0RW50cnkuc2F2ZSgpLCBiYXNrZXRFbnRyeS5zYXZlKCldKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIHJldHVybiBmb3JrSm9pbihzYXZlT2JzZXJ2YWJsZXMpLnBpcGUoXG4gICAgICBzd2l0Y2hNYXAoKCkgPT4gdGhpcy5yZWZyZXNoQ3VycmVudEJhc2tldCgpKSxcbiAgICAgIHRha2UoMSlcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIEZldGNoZXMgdGhlIEJhc2tldEVudHJ5IGZvciBhbiBpbmdyZWRpZW50IGlmIGl0IGV4aXN0c1xuICAgKiBSZXR1cm5zIGEgZmFrZSBCYXNrZXRFbnRyeSB3aXRoIGlkID0gLTEgaWYgaXQgZG9lc24ndCBleGlzdFxuICAgKi9cbiAgYmFza2V0RW50cnlGcm9tSW5ncmVkaWVudChpbmdyZWRpZW50SWQ6IHN0cmluZyk6IE9ic2VydmFibGU8QmFza2V0RW50cnk+IHtcbiAgICByZXR1cm4gdGhpcy53YWl0Rm9yQmFza2V0LnBpcGUoXG4gICAgICBzd2l0Y2hNYXAoYmFza2V0ID0+IHtcbiAgICAgICAgY29uc3QgdXJsID0gYCR7ZS5taWFtQVBJfS9hcGkvdjEvYmFza2V0cy8ke2Jhc2tldC5pZH0vYmFza2V0LWVudHJpZXMvZnJvbS1pbmdyZWRpZW50P2luZ3JlZGllbnRfaWQ9JHtpbmdyZWRpZW50SWR9YDtcbiAgICAgICAgcmV0dXJuIHRoaXMuaHR0cC5nZXQodXJsLCB7IHBhcmFtczogeyBpbmNsdWRlOiBbJ3NlbGVjdGVkLWl0ZW0nXSB9IH0pIGFzIE9ic2VydmFibGU8RG9jdW1lbnRSZXNvdXJjZTxCYXNrZXRFbnRyeT4+O1xuICAgICAgfSksXG4gICAgICBza2lwV2hpbGUocmVzdWx0ID0+IHJlc3VsdC5pc19sb2FkaW5nIHx8ICFyZXN1bHQpLFxuICAgICAgbWFwKHJlcyA9PiB7XG4gICAgICAgIGNvbnN0IGVudHJ5ID0gdGhpcy5iYXNrZXRFbnRyaWVzU2VydmljZS5uZXcoKTtcbiAgICAgICAgZW50cnkuZmlsbChyZXMpO1xuICAgICAgICByZXR1cm4gZW50cnk7XG4gICAgICB9KVxuICAgICk7XG4gIH1cblxuICAvKiogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogUFJJQ0VCT09LICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqICoqL1xuXG4gIC8vIHdpbGwgcGF0Y2ggYmFza2V0IHdpdGggZ2l2ZW4gcHJpY2Vib29rTmFtZVxuICAvLyBBcGkgd2lsbCBsb29rIGZvciBwcmljZXMgKHBvcyBpdGVtcykgY29ycmVzcG9uZGluZyB0byB0aGlzIHByaWNlYm9vayBrZXlcbiAgLy8gZmFsbCBjYXNlIHRvIGEgZGVmYXVsdCBwcmljZWJvb2tcbiAgdXBkYXRlUHJpY2Vib29rKHByaWNlYm9va05hbWU6IHN0cmluZyk6IE9ic2VydmFibGU8dm9pZD4ge1xuICAgIHJldHVybiB0aGlzLndhaXRGb3JCYXNrZXQucGlwZShcbiAgICAgIHN3aXRjaE1hcChiYXNrZXQgPT4ge1xuICAgICAgICBpZiAoYmFza2V0LnByaWNlYm9va0tleSA9PT0gcHJpY2Vib29rTmFtZSkge1xuICAgICAgICAgIGNvbnNvbGUubG9nKGBbTWlhbV0gc2FtZSBwcmljZWJvb2sgJHtKU09OLnN0cmluZ2lmeShwcmljZWJvb2tOYW1lKX1gKTtcbiAgICAgICAgICByZXR1cm4gb2Y8dm9pZD4oKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zb2xlLmxvZyhgW01pYW1dIHVwZGF0ZSBwcmljZWJvb2sgdG8gJHtKU09OLnN0cmluZ2lmeShwcmljZWJvb2tOYW1lKX1gKTtcbiAgICAgICAgYmFza2V0LnByaWNlYm9va0tleSA9IHByaWNlYm9va05hbWU7XG4gICAgICAgIHJldHVybiBiYXNrZXQuc2F2ZSh7IGZpZWxkczogQkFTS0VUX1NQQVJTRV9GSUVMRFMgfSkucGlwZShcbiAgICAgICAgICBzd2l0Y2hNYXAoKHJlc3A6IERvY3VtZW50UmVzb3VyY2U8QmFza2V0PikgPT4ge1xuICAgICAgICAgICAgdGhpcy5maWxsQmFza2V0KHJlc3ApO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMubG9hZFByZXZpZXcoKTtcbiAgICAgICAgICB9KVxuICAgICAgICApO1xuICAgICAgfSlcbiAgICApO1xuICB9XG5cbiAgLyoqICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqIEFERCBGUk9NIFBJQ1RVUkUgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogKiovXG5cbiAgYWRkRW50cmllc0Zyb21QaWN0dXJlKGZpbGU6IEZpbGUsIGluY2x1ZGUgPSBbXSwgZGlzYWJsZUluZ3JlZGllbnRzTWF0Y2hpbmcgPSBmYWxzZSk6IE9ic2VydmFibGU8QmFza2V0PiB7XG4gICAgcmV0dXJuIHRoaXMud2FpdEZvckJhc2tldC5waXBlKFxuICAgICAgc3dpdGNoTWFwKGJhc2tldCA9PiB7XG4gICAgICAgIGNvbnN0IHVybCA9IGAke2UubWlhbUFQSX0vYXBpL3YxL2Jhc2tldHMvJHtiYXNrZXQuaWR9L2FkZF9lbnRyaWVzX2Zyb21fcGljdHVyZWAgK1xuICAgICAgICAgIGA/ZmllbGRzW2Jhc2tldHNdPSR7QkFTS0VUX1NQQVJTRV9GSUVMRFMuYmFza2V0cy5qb2luKCcsJyl9JHsoZGlzYWJsZUluZ3JlZGllbnRzTWF0Y2hpbmcgPyAnJmRpc2FibGVfbWF0Y2hpbmc9dHJ1ZScgOiAnJyl9YDtcbiAgICAgICAgY29uc3QgZm9ybURhdGE6IEZvcm1EYXRhID0gbmV3IEZvcm1EYXRhKCk7XG4gICAgICAgIGZvcm1EYXRhLmFwcGVuZCgncGljdHVyZScsIGZpbGUpO1xuICAgICAgICBmb3JtRGF0YS5hcHBlbmQoJ2luY2x1ZGUnLCBpbmNsdWRlLmpvaW4oJywnKSk7XG4gICAgICAgIHJldHVybiB0aGlzLmh0dHAucGF0Y2godXJsLCBmb3JtRGF0YSkucGlwZShtYXAoKHJlc3BvbnNlOiBEb2N1bWVudFJlc291cmNlPEJhc2tldD4pID0+IHRoaXMuZmlsbEJhc2tldChyZXNwb25zZSkpKTtcbiAgICAgIH0pXG4gICAgKTtcbiAgfVxuXG4gIC8qKiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqIEFERCBBQ1RJT05TIFRPIFRIRSBRVUVVRSAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqICoqL1xuXG4gIC8qKlxuICAgKiBBZGRzIHJlY2lwZXMgdG8gdGhlIGJhc2tldCBhY3Rpb24gdG8gcXVldWUuXG4gICAqXG4gICAqIEBwYXJhbSByZWNpcGVJZHMgLSBUaGUgYXJyYXkgb2YgcmVjaXBlIElEcyB0byBhZGQuXG4gICAqIEBwYXJhbSBndWVzdHMgLSBUaGUgbnVtYmVyIG9mIGd1ZXN0cy5cbiAgICogQHBhcmFtIGV2ZW50VHJhY2UgLSBUaGUgZXZlbnQgdHJhY2UuXG4gICAqIEBwYXJhbSB3aXRoSW5ncmVkaWVudHMgLSBXaGV0aGVyIHRvIGluY2x1ZGUgaW5ncmVkaWVudHMuIERlZmF1bHQgaXMgdHJ1ZS5cbiAgICogQHJldHVybiBUaGlzIGZ1bmN0aW9uIGRvZXMgbm90IHJldHVybiBhbnl0aGluZy5cbiAgICovXG4gIGFkZFJlY2lwZXNUb0Jhc2tldChyZWNpcGVJZHM6IHN0cmluZ1tdLCBndWVzdHM6IG51bWJlciwgZXZlbnRUcmFjZTogRXZlbnRUcmFjZSwgd2l0aEluZ3JlZGllbnRzID0gdHJ1ZSk6IHZvaWQge1xuICAgIGNvbnN0IHRvQWRkID0gdGhpcy5iYXNrZXRBY3Rpb25zUXVldWUudmFsdWU7XG4gICAgcmVjaXBlSWRzLmZvckVhY2gocmVjaXBlSWQgPT5cbiAgICAgIHRvQWRkLnB1c2goe1xuICAgICAgICB0eXBlOiB3aXRoSW5ncmVkaWVudHMgPyBCYXNrZXRBY3Rpb25UeXBlLkFERF9SRUNJUEUgOiBCYXNrZXRBY3Rpb25UeXBlLkFERF9SRUNJUEVfTElHSFQsXG4gICAgICAgIHBhcmFtczogeyByZWNpcGVJZCwgZXZlbnRUcmFjZSwgZ3Vlc3RzIH1cbiAgICAgIH0pXG4gICAgKTtcbiAgICB0aGlzLmJhc2tldEFjdGlvbnNRdWV1ZS5uZXh0KHRvQWRkKTtcbiAgfVxuXG4gIHJlbW92ZVJlY2lwZXNGcm9tQmFza2V0KHJlY2lwZUlkczogc3RyaW5nW10sIGV2ZW50VHJhY2U6IEV2ZW50VHJhY2UpOiB2b2lkIHtcbiAgICBjb25zdCB0b1JlbW92ZSA9IHRoaXMuYmFza2V0QWN0aW9uc1F1ZXVlLnZhbHVlO1xuICAgIHJlY2lwZUlkcy5mb3JFYWNoKHJlY2lwZUlkID0+XG4gICAgICB0b1JlbW92ZS5wdXNoKHtcbiAgICAgICAgdHlwZTogQmFza2V0QWN0aW9uVHlwZS5SRU1PVkVfUkVDSVBFLFxuICAgICAgICBwYXJhbXM6IHsgcmVjaXBlSWQsIGV2ZW50VHJhY2UgfVxuICAgICAgfSlcbiAgICApO1xuICAgIHRoaXMuYmFza2V0QWN0aW9uc1F1ZXVlLm5leHQodG9SZW1vdmUpO1xuICB9XG5cbiAgdXBkYXRlUmVjaXBlc0luQmFza2V0KHJlY2lwZUlkczogc3RyaW5nW10sIGd1ZXN0czogbnVtYmVyLCBldmVudFRyYWNlOiBFdmVudFRyYWNlKTogdm9pZCB7XG4gICAgY29uc3QgdG9VcGRhdGUgPSB0aGlzLmJhc2tldEFjdGlvbnNRdWV1ZS52YWx1ZTtcbiAgICByZWNpcGVJZHMuZm9yRWFjaChyZWNpcGVJZCA9PlxuICAgICAgdG9VcGRhdGUucHVzaCh7XG4gICAgICAgIHR5cGU6IEJhc2tldEFjdGlvblR5cGUuVVBEQVRFX1JFQ0lQRSxcbiAgICAgICAgcGFyYW1zOiB7IHJlY2lwZUlkLCBldmVudFRyYWNlLCBndWVzdHMgfVxuICAgICAgfSlcbiAgICApO1xuICAgIHRoaXMuYmFza2V0QWN0aW9uc1F1ZXVlLm5leHQodG9VcGRhdGUpO1xuICB9XG5cbiAgYWRkSW5ncmVkaWVudHNUb0Jhc2tldChyZWNpcGVJZDogc3RyaW5nLCBpbmdyZWRpZW50SWRzQW5kRW50cmllczogeyBpbmdyZWRpZW50SWQ6IHN0cmluZzsgZW50cnk6IEJhc2tldEVudHJ5IH1bXSxcbiAgICBldmVudFRyYWNlOiBFdmVudFRyYWNlKTogdm9pZCB7XG4gICAgY29uc3QgdG9BZGQgPSB0aGlzLmJhc2tldEFjdGlvbnNRdWV1ZS52YWx1ZTtcbiAgICBpbmdyZWRpZW50SWRzQW5kRW50cmllcy5mb3JFYWNoKGluZ3JlZGllbnRJZEFuZEVudHJ5ID0+XG4gICAgICB0b0FkZC5wdXNoKHtcbiAgICAgICAgdHlwZTogQmFza2V0QWN0aW9uVHlwZS5BRERfUFJPRFVDVCxcbiAgICAgICAgcGFyYW1zOiB7IHJlY2lwZUlkLCBpbmdyZWRpZW50SWQ6IGluZ3JlZGllbnRJZEFuZEVudHJ5LmluZ3JlZGllbnRJZCwgYmFza2V0RW50cnk6IGluZ3JlZGllbnRJZEFuZEVudHJ5LmVudHJ5LCBldmVudFRyYWNlIH1cbiAgICAgIH0pXG4gICAgKTtcbiAgICB0aGlzLmJhc2tldEFjdGlvbnNRdWV1ZS5uZXh0KHRvQWRkKTtcbiAgfVxuXG4gIHJlbW92ZUluZ3JlZGllbnRzRnJvbUJhc2tldChiYXNrZXRFbnRyeTogQmFza2V0RW50cnksIHJlY2lwZUlkOiBzdHJpbmcsIGluZ3JlZGllbnRJZHM6IHN0cmluZ1tdLCBldmVudFRyYWNlOiBFdmVudFRyYWNlKTogdm9pZCB7XG4gICAgY29uc3QgdG9SZW1vdmUgPSB0aGlzLmJhc2tldEFjdGlvbnNRdWV1ZS52YWx1ZTtcbiAgICBpbmdyZWRpZW50SWRzLmZvckVhY2goaW5ncmVkaWVudElkID0+XG4gICAgICB0b1JlbW92ZS5wdXNoKHtcbiAgICAgICAgdHlwZTogQmFza2V0QWN0aW9uVHlwZS5SRU1PVkVfUFJPRFVDVCxcbiAgICAgICAgcGFyYW1zOiB7IGJhc2tldEVudHJ5LCByZWNpcGVJZCwgaW5ncmVkaWVudElkLCBldmVudFRyYWNlIH1cbiAgICAgIH0pXG4gICAgKTtcbiAgICB0aGlzLmJhc2tldEFjdGlvbnNRdWV1ZS5uZXh0KHRvUmVtb3ZlKTtcbiAgfVxuXG4gIGNoYW5nZVByb2R1Y3RRdWFudGl0eShiYXNrZXRFbnRyeTogQmFza2V0RW50cnksIHJlY2lwZUlkOiBzdHJpbmcsIG5ld1F1YW50aXR5OiBudW1iZXIsIGV2ZW50VHJhY2U6IEV2ZW50VHJhY2UpOiB2b2lkIHtcbiAgICBjb25zdCB0b1VwZGF0ZSA9IHRoaXMuYmFza2V0QWN0aW9uc1F1ZXVlLnZhbHVlO1xuICAgIHRvVXBkYXRlLnB1c2goe1xuICAgICAgdHlwZTogQmFza2V0QWN0aW9uVHlwZS5VUERBVEVfUFJPRFVDVCxcbiAgICAgIHBhcmFtczogeyBiYXNrZXRFbnRyeSwgcmVjaXBlSWQsIG5ld1F1YW50aXR5LCBldmVudFRyYWNlIH1cbiAgICB9KTtcbiAgICB0aGlzLmJhc2tldEFjdGlvbnNRdWV1ZS5uZXh0KHRvVXBkYXRlKTtcbiAgfVxuXG4gIC8qKiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogUFJPQ0VTUyBUSEUgQUNUSU9OUyBRVUVVRSAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogKiovXG5cbiAgcHJpdmF0ZSBlbXB0eUFjdGlvbnNRdWV1ZSgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5iYXNrZXRBY3Rpb25zUXVldWUudmFsdWUubGVuZ3RoID4gMCkge1xuICAgICAgY29uc3QgYWN0aW9uc1RvUHJvY2VzcyA9IHRoaXMubmV4dEFjdGlvbnNCYXRjaCgpO1xuICAgICAgdGhpcy5hY3Rpb25zQmVpbmdQcm9jZXNzZWQubmV4dChbLi4uYWN0aW9uc1RvUHJvY2Vzc10pO1xuICAgICAgaWYgKGFjdGlvbnNUb1Byb2Nlc3MubGVuZ3RoID4gMCkge1xuICAgICAgICB0aGlzLnByb2Nlc3NBY3Rpb25zQmF0Y2goYWN0aW9uc1RvUHJvY2Vzcykuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgICAgICB0aGlzLmFjdGlvbnNCZWluZ1Byb2Nlc3NlZC5uZXh0KFtdKTtcbiAgICAgICAgICB0aGlzLmJhc2tldEFjdGlvbnNRdWV1ZS5uZXh0KFxuICAgICAgICAgICAgdGhpcy5iYXNrZXRBY3Rpb25zUXVldWUudmFsdWUuZmlsdGVyKGkgPT4gIWFjdGlvbnNUb1Byb2Nlc3MuaW5jbHVkZXMoaSkgJiYgIXRoaXMuYWN0aW9uc0JlaW5nT3ZlcnJpZGVuLmluY2x1ZGVzKGkpKVxuICAgICAgICAgICk7XG4gICAgICAgICAgdGhpcy5hY3Rpb25zQmVpbmdPdmVycmlkZW4gPSBbXTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIElmIG11bHRpcGxlIGFjdGlvbnMgb2YgdGhlIHNhbWUgdHlwZSBhcmUgbmV4dCB0byBlYWNoIG90aGVyIGluIHRoZSBxdWV1ZSwgd2Ugd2FudCB0byBwcm9jZXNzIHRoZW0gYXMgYSBiYXRjaC5cbiAgICogQHJldHVybnMgdGhlIG5leHQgYmF0Y2ggb2YgYWN0aW9ucyB0byBwcm9jZXNzXG4gICAqL1xuICBwcml2YXRlIG5leHRBY3Rpb25zQmF0Y2goKTogQmFza2V0QWN0aW9uW10ge1xuICAgIGNvbnN0IGJhdGNoOiBCYXNrZXRBY3Rpb25bXSA9IFtdO1xuICAgIGxldCBpID0gMDtcbiAgICBsZXQgY3VycmVudEFjdGlvbiA9IHRoaXMuYmFza2V0QWN0aW9uc1F1ZXVlLnZhbHVlW2ldO1xuICAgIGxldCBzaG91bGRGb3JjZVN0b3AgPSBmYWxzZTtcbiAgICB3aGlsZSAodGhpcy5iYXNrZXRBY3Rpb25zUXVldWUudmFsdWVbaV0/LnR5cGUgPT09IGN1cnJlbnRBY3Rpb24/LnR5cGUgJiYgIXNob3VsZEZvcmNlU3RvcCkge1xuICAgICAgY3VycmVudEFjdGlvbiA9IHRoaXMuYmFza2V0QWN0aW9uc1F1ZXVlLnZhbHVlW2ldO1xuICAgICAgc2hvdWxkRm9yY2VTdG9wID0gdGhpcy5hZGRBY3Rpb25Ub0JhdGNoT3JTdG9wUHJvY2Vzc2luZ0JhdGNoKGJhdGNoLCBjdXJyZW50QWN0aW9uKTtcbiAgICAgIGkrKztcbiAgICB9XG4gICAgcmV0dXJuIGJhdGNoO1xuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm5zIHRydWUgaWYgdGhlIGJhdGNoIHNob3VsZCBzdG9wIHByb2Nlc3NpbmdcbiAgICovXG4gIHByaXZhdGUgYWRkQWN0aW9uVG9CYXRjaE9yU3RvcFByb2Nlc3NpbmdCYXRjaChiYXRjaDogQmFza2V0QWN0aW9uW10sIGN1cnJlbnRBY3Rpb246IEJhc2tldEFjdGlvbik6IGJvb2xlYW4ge1xuICAgIGNvbnN0IHJlY2lwZUluZGV4ID0gdGhpcy5jaGVja0ZvckFjdGlvblRvT3ZlcnJpZGUoYmF0Y2gsIGN1cnJlbnRBY3Rpb24pO1xuICAgIGlmIChyZWNpcGVJbmRleCAhPT0gLTEpIHtcbiAgICAgIHRoaXMuYWN0aW9uc0JlaW5nT3ZlcnJpZGVuLnB1c2goYmF0Y2hbcmVjaXBlSW5kZXhdKTtcbiAgICAgIGJhdGNoW3JlY2lwZUluZGV4XSA9IGN1cnJlbnRBY3Rpb247XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICh0aGlzLnNob3VsZEZvcmNlU3RvcEJhdGNoKGJhdGNoLCBjdXJyZW50QWN0aW9uKSkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGJhdGNoLnB1c2goY3VycmVudEFjdGlvbik7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHByaXZhdGUgc2hvdWxkRm9yY2VTdG9wQmF0Y2goYmF0Y2g6IEJhc2tldEFjdGlvbltdLCBjdXJyZW50QWN0aW9uOiBCYXNrZXRBY3Rpb24pOiBib29sZWFuIHtcbiAgICAvLyBJZiB0aGUgY3VycmVudCBiYXRjaCBpcyBhbiBVUERBVEUgYmF0Y2gsIHdlIGNhbid0IHVwZGF0ZSBtdWx0aXBsZSByZWNpcGVzIHdpdGggZGlmZmVyZW50cyBndWVzdHMgdmFsdWVzIGF0IHRoZSBzYW1lIHRpbWVcbiAgICAvLyBzbyBpbiB0aGlzIGNhc2Ugd2Ugc3RvcCB0aGUgYmF0Y2ggYmVmb3JlIHRoZSBVUERBVEUgd2l0aCBhIGRpZmZlcmVudCBndWVzdHMgdmFsdWVcbiAgICByZXR1cm4gKGN1cnJlbnRBY3Rpb24udHlwZSA9PT0gQmFza2V0QWN0aW9uVHlwZS5VUERBVEVfUkVDSVBFICYmXG4gICAgICAgIGJhdGNoLmxlbmd0aCA+IDAgJiZcbiAgICAgICAgIWJhdGNoLnNvbWUoYSA9PiBhLnBhcmFtcy5ndWVzdHMgPT09IGN1cnJlbnRBY3Rpb24ucGFyYW1zLmd1ZXN0cykpIHx8XG4gICAgICAvLyBJZiB0aGUgY3VycmVudCBiYXRjaCBpcyBhbiBwcm9kdWN0IGFkZC9yZW1vdmUgYmF0Y2gsIHdlIGNhbid0IGFkZCBvciByZW1vdmUgcHJvZHVjdHMgZnJvbSBkaWZmZXJlbnQgcmVjaXBlcyBhdCB0aGUgc2FtZSB0aW1lXG4gICAgICAvLyBzbyBpbiB0aGlzIGNhc2Ugd2Ugc3RvcCB0aGUgYmF0Y2ggYmVmb3JlIHRoZSBhZGQvcmVtb3ZlIHdpdGggYSBkaWZmZXJlbnQgcmVjaXBlXG4gICAgICAoKGN1cnJlbnRBY3Rpb24udHlwZSA9PT0gQmFza2V0QWN0aW9uVHlwZS5BRERfUFJPRFVDVCB8fCBjdXJyZW50QWN0aW9uLnR5cGUgPT09IEJhc2tldEFjdGlvblR5cGUuUkVNT1ZFX1BST0RVQ1QpICYmXG4gICAgICAgIGJhdGNoLmxlbmd0aCA+IDAgJiZcbiAgICAgICAgIWJhdGNoLnNvbWUoYSA9PiBhLnBhcmFtcy5yZWNpcGVJZCA9PT0gY3VycmVudEFjdGlvbi5wYXJhbXMucmVjaXBlSWQpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVjayBmb3IgYWN0aW9ucyBmb3Igd2hpY2ggb3ZlcnJpZGluZyB3b3VsZCBoYXZlIHRoZSBzYW1lIHJlc3VsdCBhcyBwcm9jZXNzaW5nIGJvdGggaW4gb3JkZXJcbiAgICovXG4gIHByaXZhdGUgY2hlY2tGb3JBY3Rpb25Ub092ZXJyaWRlKGJhdGNoOiBCYXNrZXRBY3Rpb25bXSwgY3VycmVudEFjdGlvbjogQmFza2V0QWN0aW9uKTogbnVtYmVyIHtcbiAgICBpZiAoY3VycmVudEFjdGlvbi50eXBlID09PSBCYXNrZXRBY3Rpb25UeXBlLlVQREFURV9SRUNJUEUgJiZcbiAgICAgIGJhdGNoLmxlbmd0aCA+IDAgJiZcbiAgICAgICFiYXRjaC5zb21lKGEgPT4gYS5wYXJhbXMucmVjaXBlSWQgIT09IGN1cnJlbnRBY3Rpb24ucGFyYW1zLnJlY2lwZUlkKVxuICAgICkge1xuICAgICAgcmV0dXJuIGJhdGNoLmZpbmRJbmRleChhID0+IGEucGFyYW1zLnJlY2lwZUlkID09PSBjdXJyZW50QWN0aW9uLnBhcmFtcy5yZWNpcGVJZCk7XG4gICAgICAvLyBpZiB0aGVyZSBhcmUgb25seSB0aGUgc2FtZSByZWNpcGVJZCBhcyB0aGUgY3VycmVudEFjdGlvbiBpbiB0aGUgYmF0Y2ggYW5kIHdlIGFyZSB1cGRhdGluZyB0aGlzIHJlY2lwZSdzIGd1ZXN0c1xuICAgICAgLy8gd2UgY2FuIHNhZmVseSBvdmVycmlkZSB0aGUgYWN0aW9uIGluIHRoZSBiYXRjaFxuICAgIH0gZWxzZSBpZiAoY3VycmVudEFjdGlvbi50eXBlID09PSBCYXNrZXRBY3Rpb25UeXBlLlVQREFURV9QUk9EVUNUICkge1xuICAgICAgcmV0dXJuIGJhdGNoLmZpbmRJbmRleChhID0+IGEucGFyYW1zLmJhc2tldEVudHJ5LmlkID09PSBjdXJyZW50QWN0aW9uLnBhcmFtcy5iYXNrZXRFbnRyeS5pZCk7XG4gICAgICAvLyBJZiB0aGUgY3VycmVudEFjdGlvbiBtb2RpZmllcyB0aGUgc2FtZSBiYXNrZXRFbnRyeSBhcyBhIHByZXZpb3VzIG9uZSBpbiB0aGUgYmF0Y2gsIGl0IG92ZXJyaWRlcyBpdFxuICAgIH0gZWxzZSBpZiAoXG4gICAgICAhW0Jhc2tldEFjdGlvblR5cGUuQUREX1BST0RVQ1QsIEJhc2tldEFjdGlvblR5cGUuUkVNT1ZFX1BST0RVQ1QsIEJhc2tldEFjdGlvblR5cGUuVVBEQVRFX1JFQ0lQRV0uaW5jbHVkZXMoY3VycmVudEFjdGlvbi50eXBlKVxuICAgICkge1xuICAgICAgcmV0dXJuIGJhdGNoLmZpbmRJbmRleChhID0+IGEucGFyYW1zLnJlY2lwZUlkID09PSBjdXJyZW50QWN0aW9uLnBhcmFtcy5yZWNpcGVJZCk7XG4gICAgICAvLyBJZiB0aGUgY3VycmVudEFjdGlvbiBtb2RpZmllcyB0aGUgc2FtZSByZWNpcGUgYXMgYSBwcmV2aW91cyBvbmUgaW4gdGhlIGJhdGNoLCBpdCBvdmVycmlkZXMgaXRcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGJhdGNoLmZpbmRJbmRleChhID0+XG4gICAgICAgIGEucGFyYW1zLmluZ3JlZGllbnRJZCA9PT0gY3VycmVudEFjdGlvbi5wYXJhbXMuaW5ncmVkaWVudElkICYmXG4gICAgICAgIGEucGFyYW1zLnJlY2lwZUlkID09PSBjdXJyZW50QWN0aW9uLnBhcmFtcy5yZWNpcGVJZFxuICAgICAgKTtcbiAgICAgIC8vIElmIHRoZSBjdXJyZW50QWN0aW9uIG1vZGlmaWVzIHRoZSBzYW1lIGluZ3JlZGllbnQgZm9yIHRoZSBzYW1lIHJlY2lwZSBhcyBhIHByZXZpb3VzIG9uZSBpbiB0aGUgYmF0Y2gsIGl0IG92ZXJyaWRlcyBpdFxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgcHJvY2Vzc0FjdGlvbnNCYXRjaChhY3Rpb25zVG9Qcm9jZXNzOiBCYXNrZXRBY3Rpb25bXSk6IE9ic2VydmFibGU8dm9pZD4ge1xuICAgIHN3aXRjaCAoYWN0aW9uc1RvUHJvY2Vzc1swXS50eXBlKSB7XG4gICAgICBjYXNlIEJhc2tldEFjdGlvblR5cGUuQUREX1JFQ0lQRTpcbiAgICAgICAgcmV0dXJuIHRoaXMuYWRkUmVjaXBlcyhhY3Rpb25zVG9Qcm9jZXNzKTtcblxuICAgICAgY2FzZSBCYXNrZXRBY3Rpb25UeXBlLkFERF9SRUNJUEVfTElHSFQ6XG4gICAgICAgIHJldHVybiB0aGlzLmFkZFJlY2lwZXNXaXRob3V0SW5ncmVkaWVudHMoYWN0aW9uc1RvUHJvY2Vzcyk7XG5cbiAgICAgIGNhc2UgQmFza2V0QWN0aW9uVHlwZS5SRU1PVkVfUkVDSVBFOlxuICAgICAgICByZXR1cm4gdGhpcy5yZW1vdmVSZWNpcGVzKGFjdGlvbnNUb1Byb2Nlc3MpO1xuXG4gICAgICBjYXNlIEJhc2tldEFjdGlvblR5cGUuVVBEQVRFX1JFQ0lQRTpcbiAgICAgICAgcmV0dXJuIHRoaXMudXBkYXRlUmVjaXBlc0d1ZXN0cyhhY3Rpb25zVG9Qcm9jZXNzKTtcblxuICAgICAgY2FzZSBCYXNrZXRBY3Rpb25UeXBlLkFERF9QUk9EVUNUOlxuICAgICAgICByZXR1cm4gdGhpcy5hZGRJdGVtc0ZvckluZ3JlZGllbnRzKGFjdGlvbnNUb1Byb2Nlc3MpO1xuXG4gICAgICBjYXNlIEJhc2tldEFjdGlvblR5cGUuUkVNT1ZFX1BST0RVQ1Q6XG4gICAgICAgIHJldHVybiB0aGlzLnJlbW92ZUl0ZW1zRm9ySW5ncmVkaWVudHMoYWN0aW9uc1RvUHJvY2Vzcyk7XG5cbiAgICAgIGNhc2UgQmFza2V0QWN0aW9uVHlwZS5VUERBVEVfUFJPRFVDVDpcbiAgICAgICAgcmV0dXJuIHRoaXMuY2hhbmdlQmFza2V0RW50cmllc1F1YW50aXRpZXMoYWN0aW9uc1RvUHJvY2Vzcyk7XG5cbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHJldHVybiBvZigpO1xuICAgIH1cbiAgfVxuXG4gIC8qKiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogUFJPQ0VTUyBUSEUgQUNUSU9OUyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogKiovXG5cbiAgLyoqXG4gICAqIEFkZHMgcmVjaXBlcyB0byB0aGUgYmFza2V0IEhUVFAgcmVxdWVzdC5cbiAgICpcbiAgICogQHBhcmFtIHJlY2lwZXNUb0FkZCAtIFRoZSByZWNpcGVzIHRvIGFkZCB0byB0aGUgYmFza2V0LlxuICAgKiBAcGFyYW0gd2l0aEluZ3JlZGllbnRzIC0gKG9wdGlvbmFsKSBXaGV0aGVyIHRvIGluY2x1ZGUgaW5ncmVkaWVudHMgaW4gdGhlIHJlcXVlc3QuIERlZmF1bHQgaXMgdHJ1ZS5cbiAgICogQHJldHVybiBBbiBvYnNlcnZhYmxlIHRoYXQgZW1pdHMgdm9pZCB3aGVuIHRoZSByZXF1ZXN0IGlzIGNvbXBsZXRlZC5cbiAgICovXG4gIHByaXZhdGUgYWRkUmVjaXBlcyhyZWNpcGVzVG9BZGQ6IEJhc2tldEFjdGlvbltdLCB3aXRoSW5ncmVkaWVudHMgPSB0cnVlKTogT2JzZXJ2YWJsZTx2b2lkPiB7XG4gICAgcmV0dXJuIHRoaXMud2FpdEZvckJhc2tldC5waXBlKFxuICAgICAgc3dpdGNoTWFwKGJhc2tldCA9PiB7XG4gICAgICAgIGNvbnN0IHVybCA9IGAke2UubWlhbUFQSX0vYXBpL3YxL2Jhc2tldHMvJHtiYXNrZXQuaWR9L3JlY2lwZXNgICtcbiAgICAgICAgYD9maWVsZHNbYmFza2V0c109JHtCQVNLRVRfU1BBUlNFX0ZJRUxEUy5iYXNrZXRzLmpvaW4oJywnKX0ke3dpdGhJbmdyZWRpZW50cyA/ICcnIDogJyZsaWdodF9tb2RlPXRydWUnfWA7XG4gICAgICAgIGNvbnN0IGJvZHkgPSB7IGRhdGE6IHJlY2lwZXNUb0FkZC5tYXAociA9PiAoeyByZWNpcGVfaWQ6IHIucGFyYW1zLnJlY2lwZUlkLCBndWVzdHM6IHIucGFyYW1zLmd1ZXN0cyB9KSkgfTtcbiAgICAgICAgdGhpcy5hbmFseXRpY3NTZXJ2aWNlLnNlbmRBZGRSZWNpcGVzRXZlbnRzKHJlY2lwZXNUb0FkZCk7XG4gICAgICAgIHJldHVybiB0aGlzLmh0dHAucG9zdCh1cmwsIGJvZHkpLnBpcGUoXG4gICAgICAgICAgc2tpcFdoaWxlKChiOiBEb2N1bWVudFJlc291cmNlPEJhc2tldD4pID0+IGIuaXNfbG9hZGluZyksXG4gICAgICAgICAgc3dpdGNoTWFwKGIgPT4ge1xuICAgICAgICAgICAgaWYgKGI/LmRhdGE/LmlkKSB7XG4gICAgICAgICAgICAgIHRoaXMuZmlsbEJhc2tldChiKTtcbiAgICAgICAgICAgICAgcmV0dXJuIHRoaXMubG9hZFByZXZpZXcoKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIG9mPHZvaWQ+KCk7XG4gICAgICAgICAgfSlcbiAgICAgICAgKTtcbiAgICAgIH0pXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgYWRkUmVjaXBlc1dpdGhvdXRJbmdyZWRpZW50cyhyZWNpcGVzVG9BZGQ6IEJhc2tldEFjdGlvbltdKTogT2JzZXJ2YWJsZTx2b2lkPiB7XG4gICAgcmV0dXJuIHRoaXMuYWRkUmVjaXBlcyhyZWNpcGVzVG9BZGQsIGZhbHNlKTtcbiAgfVxuXG4gIHByaXZhdGUgcmVtb3ZlUmVjaXBlcyhyZWNpcGVzVG9SZW1vdmU6IEJhc2tldEFjdGlvbltdKTogT2JzZXJ2YWJsZTx2b2lkPiB7XG4gICAgcmV0dXJuIHRoaXMud2FpdEZvckJhc2tldC5waXBlKFxuICAgICAgc3dpdGNoTWFwKGJhc2tldCA9PiB7XG4gICAgICAgIGNvbnN0IHVybCA9IGAke2UubWlhbUFQSX0vYXBpL3YxL2Jhc2tldHMvJHtiYXNrZXQuaWR9L3JlY2lwZXM/cmVjaXBlX2lkc1tdPWAgK1xuICAgICAgICAgIHJlY2lwZXNUb1JlbW92ZS5tYXAociA9PiByLnBhcmFtcy5yZWNpcGVJZCkuam9pbignJnJlY2lwZV9pZHNbXT0nKSArIGAmZmllbGRzW2Jhc2tldHNdPSR7QkFTS0VUX1NQQVJTRV9GSUVMRFMuYmFza2V0cy5qb2luKCcsJyl9YDtcbiAgICAgICAgdGhpcy5hbmFseXRpY3NTZXJ2aWNlLnNlbmRSZW1vdmVSZWNpcGVzRXZlbnRzKHJlY2lwZXNUb1JlbW92ZSk7XG4gICAgICAgIHJldHVybiB0aGlzLmh0dHAuZGVsZXRlKHVybCkucGlwZShcbiAgICAgICAgICBza2lwV2hpbGUoKGI6IERvY3VtZW50UmVzb3VyY2U8QmFza2V0PikgPT4gYi5pc19sb2FkaW5nKSxcbiAgICAgICAgICBzd2l0Y2hNYXAoYiA9PiB7XG4gICAgICAgICAgICBpZiAoYj8uZGF0YT8uaWQpIHtcbiAgICAgICAgICAgICAgdGhpcy5maWxsQmFza2V0KGIpO1xuICAgICAgICAgICAgICByZXR1cm4gdGhpcy5sb2FkUHJldmlldygpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gb2Y8dm9pZD4oKTtcbiAgICAgICAgICB9KVxuICAgICAgICApO1xuICAgICAgfSlcbiAgICApO1xuICB9XG5cbiAgcHJpdmF0ZSB1cGRhdGVSZWNpcGVzR3Vlc3RzKHJlY2lwZXNUb1VwZGF0ZTogQmFza2V0QWN0aW9uW10pOiBPYnNlcnZhYmxlPHZvaWQ+IHtcbiAgICByZXR1cm4gdGhpcy53YWl0Rm9yQmFza2V0LnBpcGUoXG4gICAgICBzd2l0Y2hNYXAoYmFza2V0ID0+IHtcbiAgICAgICAgY29uc3QgdXJsID0gYCR7ZS5taWFtQVBJfS9hcGkvdjEvYmFza2V0cy8ke2Jhc2tldC5pZH0vcmVjaXBlc19ndWVzdHM/Z3Vlc3RzPSR7cmVjaXBlc1RvVXBkYXRlWzBdLnBhcmFtcy5ndWVzdHN9JnJlY2lwZV9pZHNbXT1gICtcbiAgICAgICAgcmVjaXBlc1RvVXBkYXRlLm1hcChyID0+IHIucGFyYW1zLnJlY2lwZUlkKS5qb2luKCcmcmVjaXBlX2lkc1tdPScpICsgYCZmaWVsZHNbYmFza2V0c109JHtCQVNLRVRfU1BBUlNFX0ZJRUxEUy5iYXNrZXRzLmpvaW4oJywnKX1gO1xuICAgICAgICB0aGlzLmFuYWx5dGljc1NlcnZpY2Uuc2VuZFVwZGF0ZUd1ZXN0c0V2ZW50cyhyZWNpcGVzVG9VcGRhdGUpO1xuICAgICAgICByZXR1cm4gdGhpcy5odHRwLnBhdGNoKHVybCwge30pLnBpcGUoXG4gICAgICAgICAgc2tpcFdoaWxlKChiOiBEb2N1bWVudFJlc291cmNlPEJhc2tldD4pID0+ICFiIHx8IGIuaXNfbG9hZGluZyksXG4gICAgICAgICAgc3dpdGNoTWFwKGIgPT4ge1xuICAgICAgICAgICAgaWYgKGI/LmRhdGE/LmlkKSB7XG4gICAgICAgICAgICAgIHRoaXMuZmlsbEJhc2tldChiKTtcbiAgICAgICAgICAgICAgcmV0dXJuIHRoaXMubG9hZFByZXZpZXcoKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIG9mPHZvaWQ+KCk7XG4gICAgICAgICAgfSlcbiAgICAgICAgKTtcbiAgICAgIH0pXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0gaW5ncmVkaWVudHNUb0FkZFxuICAgKi9cbiAgcHJpdmF0ZSBhZGRJdGVtc0ZvckluZ3JlZGllbnRzKGluZ3JlZGllbnRzVG9BZGQ6IEJhc2tldEFjdGlvbltdKTogT2JzZXJ2YWJsZTx2b2lkPiB7XG4gICAgcmV0dXJuIHRoaXMud2FpdEZvckJhc2tldC5waXBlKFxuICAgICAgc2tpcFdoaWxlKGJhc2tldCA9PiBiYXNrZXQuaXNfbG9hZGluZyksXG4gICAgICBzd2l0Y2hNYXAoYmFza2V0ID0+IHtcbiAgICAgICAgY29uc3QgcmVxdWVzdHMgPSBpbmdyZWRpZW50c1RvQWRkLm1hcChhY3Rpb24gPT4ge1xuICAgICAgICAgIGNvbnN0IG1vZGlmaWVkR3Vlc3RzID0gdGhpcy5ndWVzdHNGb3JSZWNpcGUoYWN0aW9uLnBhcmFtcy5yZWNpcGVJZCk7XG4gICAgICAgICAgY29uc3QgdXJsID0gYCR7ZS5taWFtQVBJfS9hcGkvdjEvYmFza2V0cy8ke2Jhc2tldC5pZH0vYmFza2V0LWVudHJpZXMvJHthY3Rpb24ucGFyYW1zLmJhc2tldEVudHJ5LmlkfS9hZGQtaW5ncmVkaWVudGAgK1xuICAgICAgICAgICAgYD9pbmdyZWRpZW50X2lkPSR7YWN0aW9uLnBhcmFtcy5pbmdyZWRpZW50SWR9JnNlbGVjdGVkX2l0ZW1faWQ9JHthY3Rpb24ucGFyYW1zLmJhc2tldEVudHJ5LnNlbGVjdGVkSXRlbS5pZH1gICtcbiAgICAgICAgICAgIGAmZ3Vlc3RzPSR7bW9kaWZpZWRHdWVzdHN9YDtcbiAgICAgICAgICByZXR1cm4gdGhpcy5odHRwLnBhdGNoKHVybCwge30pO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIGZvcmtKb2luKHJlcXVlc3RzKTtcbiAgICAgIH0pLFxuICAgICAgc3dpdGNoTWFwKCgpID0+IHRoaXMucmVsb2FkQmFza2V0KCkpLFxuICAgICAgc3dpdGNoTWFwKCgpID0+IG9mPHZvaWQ+KG51bGwpKSAvLyBKdXN0IHRvIGtlZXAgdGhlIHJldHVybiB0eXBlIGFzIE9ic2VydmFibGU8dm9pZD4gdG8gbWF0Y2ggd2l0aCB0aGUgb3RoZXIgbWV0aG9kc1xuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogUmVtb3ZlcyB0aGUgc3BlY2lmaWVkIGluZ3JlZGllbnRzIGZyb20gdGhlIGJhc2tldCBIVFRQIHJlcXVlc3QuXG4gICAqXG4gICAqIEBwYXJhbSBpbmdyZWRpZW50c1RvUmVtb3ZlIC0gVGhlIGxpc3Qgb2YgaW5ncmVkaWVudHMgdG8gcmVtb3ZlIGZyb20gdGhlIGJhc2tldC5cbiAgICogQHJldHVybiBBbiBvYnNlcnZhYmxlIHRoYXQgZW1pdHMgd2hlbiB0aGUgaW5ncmVkaWVudHMgYXJlIHN1Y2Nlc3NmdWxseSByZW1vdmVkLlxuICAgKi9cbiAgcHJpdmF0ZSByZW1vdmVJdGVtc0ZvckluZ3JlZGllbnRzKGluZ3JlZGllbnRzVG9SZW1vdmU6IEJhc2tldEFjdGlvbltdKTogT2JzZXJ2YWJsZTx2b2lkPiB7XG4gICAgcmV0dXJuIHRoaXMud2FpdEZvckJhc2tldC5waXBlKFxuICAgICAgc2tpcFdoaWxlKGJhc2tldCA9PiBiYXNrZXQuaXNfbG9hZGluZyksXG4gICAgICBzd2l0Y2hNYXAoYmFza2V0ID0+IHtcbiAgICAgICAgY29uc3QgcmVxdWVzdHMgPSBpbmdyZWRpZW50c1RvUmVtb3ZlLm1hcChhY3Rpb24gPT4ge1xuICAgICAgICAgIGNvbnN0IG1vZGlmaWVkR3Vlc3RzID0gdGhpcy5ndWVzdHNGb3JSZWNpcGUoYWN0aW9uLnBhcmFtcy5yZWNpcGVJZCk7XG4gICAgICAgICAgY29uc3QgdXJsID0gZS5taWFtQVBJICsgJy9hcGkvdjEvYmFza2V0cy8nICsgYmFza2V0LmlkICtcbiAgICAgICAgICAgICcvYmFza2V0LWVudHJpZXMvJyArIGFjdGlvbi5wYXJhbXMuYmFza2V0RW50cnkuaWQgK1xuICAgICAgICAgICAgJy9yZW1vdmUtaW5ncmVkaWVudD9pbmdyZWRpZW50X2lkPScgKyBhY3Rpb24ucGFyYW1zLmluZ3JlZGllbnRJZCArXG4gICAgICAgICAgICAnJnNlbGVjdGVkX2l0ZW1faWQ9JyArIGFjdGlvbi5wYXJhbXMuYmFza2V0RW50cnkuc2VsZWN0ZWRJdGVtLmlkICtcbiAgICAgICAgICAgICcmZ3Vlc3RzPScgKyBtb2RpZmllZEd1ZXN0cztcbiAgICAgICAgICByZXR1cm4gdGhpcy5odHRwLnBhdGNoKHVybCwge30pO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIGZvcmtKb2luKHJlcXVlc3RzKTtcbiAgICAgIH0pLFxuICAgICAgc3dpdGNoTWFwKCgpID0+IHRoaXMucmVsb2FkQmFza2V0KCkpLFxuICAgICAgc3dpdGNoTWFwKCgpID0+IG9mPHZvaWQ+KG51bGwpKSAvLyBKdXN0IHRvIGtlZXAgdGhlIHJldHVybiB0eXBlIGFzIE9ic2VydmFibGU8dm9pZD4gdG8gbWF0Y2ggd2l0aCB0aGUgb3RoZXIgbWV0aG9kc1xuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogUmVtb3ZlcyB0aGUgc3BlY2lmaWVkIGluZ3JlZGllbnRzIGZyb20gdGhlIGJhc2tldCBIVFRQIHJlcXVlc3QuXG4gICAqXG4gICAqIEBwYXJhbSBpbmdyZWRpZW50c1RvUmVtb3ZlIC0gVGhlIGxpc3Qgb2YgaW5ncmVkaWVudHMgdG8gcmVtb3ZlIGZyb20gdGhlIGJhc2tldC5cbiAgICogQHJldHVybiBBbiBvYnNlcnZhYmxlIHRoYXQgZW1pdHMgd2hlbiB0aGUgaW5ncmVkaWVudHMgYXJlIHN1Y2Nlc3NmdWxseSByZW1vdmVkLlxuICAgKi9cbiAgcHJpdmF0ZSBjaGFuZ2VCYXNrZXRFbnRyaWVzUXVhbnRpdGllcyhxdWFudGl0aWVzVG9DaGFuZ2U6IEJhc2tldEFjdGlvbltdKTogT2JzZXJ2YWJsZTx2b2lkPiB7XG4gICAgY29uc3QgcmVxdWVzdHMgPSBxdWFudGl0aWVzVG9DaGFuZ2UubWFwKGFjdGlvbiA9PiB7XG4gICAgICBhY3Rpb24ucGFyYW1zLmJhc2tldEVudHJ5LnF1YW50aXR5ID0gYWN0aW9uLnBhcmFtcy5uZXdRdWFudGl0eTtcbiAgICAgIHJldHVybiBhY3Rpb24ucGFyYW1zLmJhc2tldEVudHJ5LnNhdmUoKTtcbiAgICB9KTtcbiAgICByZXR1cm4gZm9ya0pvaW4ocmVxdWVzdHMpLnBpcGUoXG4gICAgICBzd2l0Y2hNYXAoKCkgPT4gdGhpcy5yZWxvYWRCYXNrZXQoKSksXG4gICAgICBzd2l0Y2hNYXAoKCkgPT4gb2Y8dm9pZD4obnVsbCkpIC8vIEp1c3QgdG8ga2VlcCB0aGUgcmV0dXJuIHR5cGUgYXMgT2JzZXJ2YWJsZTx2b2lkPiB0byBtYXRjaCB3aXRoIHRoZSBvdGhlciBtZXRob2RzXG4gICAgKTtcbiAgfVxuXG4gIC8qKiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogVVBEQVRJTkcgVEhFIEJBU0tFVCAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogKiovXG5cbiAgLyoqXG4gICAqIFVwZGF0ZSBfYmFza2V0JCBjb250ZW50ICYgc2F2ZSBiYXNrZXRJZCBpbiB0aGUgbG9jYWxTdG9yYWdlIGlmIHRoZSB1c2VyIGlzIG5vdCBsb2dndWVkIGluIHNvIHdlIGNhbiBtZXJnZVdpdGggd2hlbiB0aGV5IGxvZyBpblxuICAgKi9cbiAgcHJpdmF0ZSB1cGRhdGVMb2NhbEJhc2tldChiYXNrZXQ6IEJhc2tldCk6IE9ic2VydmFibGU8dm9pZD4ge1xuICAgIGlmICh0aGlzLnVzZXJzU2VydmljZS5pc0xvZ2dlZCQudmFsdWUpIHtcbiAgICAgIGxvY2FsU3RvcmFnZS5yZW1vdmVJdGVtKCdfbWlhbS9iYXNrZXRJZCcpO1xuICAgIH0gZWxzZSB7XG4gICAgICBsb2NhbFN0b3JhZ2Uuc2V0SXRlbSgnX21pYW0vYmFza2V0SWQnLCBiYXNrZXQuaWQpO1xuICAgIH1cbiAgICB0aGlzLl9iYXNrZXQkLm5leHQoYmFza2V0KTtcbiAgICByZXR1cm4gdGhpcy5sb2FkUHJldmlldygpLnBpcGUodGFwKCgpID0+IHRoaXMuYmFza2V0SXNGZXRjaGluZyA9IGZhbHNlKSk7XG4gIH1cblxuICAvKipcbiAgICogc2F2ZSgpIHJldHVybnMgYW4gb2JqZWN0IHRoYXQgaXNuJ3QgYSByZXNvdXJjZSBzbyBtZXRob2RzIGFyZW4ndCBhdHRhY2hlZCwgc28gd2UgaGF2ZSB0byBkbyBhIGxpdHRsZSB0cmlja1xuICAgKiBAcGFyYW0gcmVzIHJlc3VsdCBvZiB0aGUgc2F2ZVxuICAgKiBAcmV0dXJucyBjb3JyZWN0IEJhc2tldCB3aXRoIHRoZSByaWdodCBhdHRyaWJ1dGVzICYgbWV0aG9kc1xuICAgKi9cbiAgcHJpdmF0ZSBmaWxsQmFza2V0KHJlczogRG9jdW1lbnRSZXNvdXJjZTxCYXNrZXQ+KTogQmFza2V0IHtcbiAgICBjb25zdCBiYXNrZXQgPSB0aGlzLm5ldygpO1xuICAgIGJhc2tldC5maWxsKHJlcyk7XG4gICAgdGhpcy5fYmFza2V0JC5uZXh0KGJhc2tldCk7XG4gICAgcmV0dXJuIGJhc2tldDtcbiAgfVxuXG4gIC8qKiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqIElOSVRJQUwgTE9BRCAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqICoqL1xuXG4gIC8qKlxuICAgKiBJbml0aWFsaXNlIHRoZSBiYXNrZXQgbG9hZGluZyB3aGVuIHRoZSBwb3MgaXMgaW5pdGlhbGlzZWQgb3IgbW9kaWZpZWRcbiAgICogQHJldHVybnMgX2Jhc2tldCRcbiAgICovXG4gIHByaXZhdGUgbG9hZEJhc2tldCgpOiBPYnNlcnZhYmxlPEJhc2tldD4ge1xuICAgIHJldHVybiB0aGlzLnBvc1NlcnZpY2UucG9zJC5waXBlKFxuICAgICAgc2tpcFdoaWxlKHBvcyA9PiAhcG9zKSxcbiAgICAgIHN3aXRjaE1hcCgoKSA9PiB0aGlzLnJlZnJlc2hDdXJyZW50QmFza2V0KCkpXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgbG9hZFByZXZpZXcoKTogT2JzZXJ2YWJsZTx2b2lkPiB7XG4gICAgcmV0dXJuIHRoaXMuYmFza2V0JC5waXBlKFxuICAgICAgc2tpcFdoaWxlKGIgPT4gIWIpLFxuICAgICAgdGFrZSgxKSxcbiAgICAgIHN3aXRjaE1hcChiYXNrZXQgPT4gdGhpcy5yZWNpcGVzU2VydmljZS5sb2FkUmVjaXBlcyhiYXNrZXQucmVjaXBlSW5mb3MpKSxcbiAgICAgIHN3aXRjaE1hcCgocmVjaXBlczogUmVjaXBlW10pID0+IHtcbiAgICAgICAgY29uc3QgYmFza2V0OiBCYXNrZXQgPSB0aGlzLl9iYXNrZXQkLnZhbHVlO1xuICAgICAgICByZXR1cm4gdGhpcy5mZXRjaEJhc2tldEVudHJpZXMoYmFza2V0KS5waXBlKFxuICAgICAgICAgIG1hcChlbnRyaWVzID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGxpbmVFbnRyaWVzID0gdGhpcy5ncm91cEJhc2tldEVudHJpZXMocmVjaXBlcywgZW50cmllcyk7XG4gICAgICAgICAgICBjb25zdCBsaW5lcyA9IHRoaXMucmVjaXBlc0FuZExpbmVFbnRyaWVzVG9CYXNrZXRQcmV2aWV3TGluZShyZWNpcGVzLCBsaW5lRW50cmllcyk7XG4gICAgICAgICAgICB0aGlzLl9iYXNrZXRQcmV2aWV3JC5uZXh0KGxpbmVzKTtcbiAgICAgICAgICAgIHRoaXMuYmFza2V0UHJldmlld0lzQ2FsY3VsYXRpbmcgPSBmYWxzZTtcbiAgICAgICAgICAgIHRoaXMuYmFza2V0U3RhdHMkLm5leHQodGhpcy5idWlsZFN0YXRzKGxpbmVzKSk7XG4gICAgICAgICAgfSlcbiAgICAgICAgKTtcbiAgICAgIH0pXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgZmV0Y2hCYXNrZXRFbnRyaWVzKGJhc2tldDogQmFza2V0KTogT2JzZXJ2YWJsZTxCYXNrZXRFbnRyeVtdPiB7XG4gICAgaWYgKCFiYXNrZXQgfHwgIWJhc2tldC5jb21wbGV0aW9uIHx8IGJhc2tldC5jb21wbGV0aW9uLnRvdGFsIDwgMSkge1xuICAgICAgdGhpcy5fZW50cmllcyQubmV4dChbXSk7XG4gICAgICByZXR1cm4gdGhpcy5fZW50cmllcyQucGlwZSh0YWtlKDEpKTtcbiAgICB9XG5cbiAgICBjb25zdCBwYWdlc0NvdW50ID0gTWF0aC5jZWlsKGJhc2tldC5jb21wbGV0aW9uLnRvdGFsIC8gQmFza2V0c1NlcnZpY2UuZW50cmllc1BlclBhZ2VzKTtcbiAgICByZXR1cm4gZm9ya0pvaW4oQXJyYXkocGFnZXNDb3VudCkuZmlsbCgwKS5tYXAoKHYsIGkpID0+IHRoaXMuZmV0Y2hCYXNrZXRFbnRyaWVzUGFnZShiYXNrZXQsIGkgKyAxKSkpLnBpcGUoXG4gICAgICBtYXAoKGNvbGxlY3Rpb25zOiBEb2N1bWVudENvbGxlY3Rpb248QmFza2V0RW50cnk+W10pID0+IHtcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnNhZmUtY2FsbFxuICAgICAgICBjb25zdCBlbnRyaWVzID0gKGZsYXR0ZW4oY29sbGVjdGlvbnMubWFwKGNvbCA9PiBjb2wuZGF0YSkpIGFzIEJhc2tldEVudHJ5W10pO1xuICAgICAgICB0aGlzLl9lbnRyaWVzJC5uZXh0KGVudHJpZXMpO1xuICAgICAgICByZXR1cm4gdGhpcy5fZW50cmllcyQudmFsdWU7XG4gICAgICB9KVxuICAgICk7XG4gIH1cblxuICBwcml2YXRlIGJ1aWxkU3RhdHMobGluZXM6IEJhc2tldFByZXZpZXdMaW5lW10pOiBCYXNrZXRTdGF0cyB7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnNhZmUtYXNzaWdubWVudCwgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVuc2FmZS1jYWxsXG4gICAgY29uc3QgZW50cmllc0ZvdW5kOiBCYXNrZXRFbnRyeVtdID0gdW5pb25CeSguLi5saW5lcy5tYXAobGluZSA9PiBsaW5lLmVudHJpZXMuZm91bmQpLCAnaWQnKTtcblxuICAgIGNvbnN0IHRvdGFsUHJpY2UgPSBlbnRyaWVzRm91bmQucmVkdWNlKCh0b3RhbCwgZW50cnkpID0+IHtcbiAgICAgIGNvbnN0IGl0ZW0gPSBlbnRyeS5hdHRyaWJ1dGVzWydiYXNrZXQtZW50cmllcy1pdGVtcyddLmZpbmQoaSA9PiBpLml0ZW1faWQgPT09IGVudHJ5LmF0dHJpYnV0ZXNbJ3NlbGVjdGVkLWl0ZW0taWQnXSk7XG4gICAgICB0b3RhbCArPSAoZW50cnkuYXR0cmlidXRlcy5xdWFudGl0eSB8fCAwKSAqIHBhcnNlRmxvYXQoaXRlbVsndW5pdC1wcmljZSddKTtcbiAgICAgIHJldHVybiB0b3RhbDtcbiAgICB9LCAwKTtcblxuICAgIHJldHVybiB7XG4gICAgICByZWNpcGVzQ291bnQ6IGxpbmVzLmxlbmd0aCxcbiAgICAgIGVudHJpZXNDb3VudDogZW50cmllc0ZvdW5kLmxlbmd0aCxcbiAgICAgIHRvdGFsUHJpY2VcbiAgICB9O1xuICB9XG5cbiAgcHJpdmF0ZSBmZXRjaEJhc2tldEVudHJpZXNQYWdlKGJhc2tldDogQmFza2V0LCBwYWdlOiBudW1iZXIpOiBPYnNlcnZhYmxlPERvY3VtZW50Q29sbGVjdGlvbjxCYXNrZXRFbnRyeT4+IHtcbiAgICBsZXQgdXJsID0gYCR7ZS5taWFtQVBJfS9hcGkvdjEvYmFza2V0cy8ke2Jhc2tldC5pZH0vYmFza2V0LWVudHJpZXNgO1xuICAgIHVybCA9IGAke3VybH0/aW5jbHVkZT1pdGVtcyZpbmNsdWRlPXNlbGVjdGVkLWl0ZW0mcGFnZVtudW1iZXJdPSR7cGFnZX0mcGFnZVtzaXplXT0ke0Jhc2tldHNTZXJ2aWNlLmVudHJpZXNQZXJQYWdlc31gO1xuXG4gICAgcmV0dXJuIHRoaXMuaHR0cC5nZXQodXJsKS5waXBlKFxuICAgICAgc2tpcFdoaWxlKChyZXNwOiBEb2N1bWVudENvbGxlY3Rpb248QmFza2V0RW50cnk+KSA9PiByZXNwLmlzX2xvYWRpbmcpLFxuICAgICAgbWFwKChyZXNwOiBEb2N1bWVudENvbGxlY3Rpb248QmFza2V0RW50cnk+KSA9PiB7XG4gICAgICAgIGNvbnN0IGJhc2tldEVudHJpZXMgPSB0aGlzLmJhc2tldEVudHJpZXNTZXJ2aWNlLm5ld0NvbGxlY3Rpb24oKTtcbiAgICAgICAgYmFza2V0RW50cmllcy5maWxsKHJlc3ApO1xuICAgICAgICByZXR1cm4gYmFza2V0RW50cmllcztcbiAgICAgIH0pXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgcmVjaXBlc0FuZExpbmVFbnRyaWVzVG9CYXNrZXRQcmV2aWV3TGluZShyZWNpcGVzOiBSZWNpcGVbXSwgbGluZUVudHJpZXM6IExpbmVFbnRyaWVzW10pOiBCYXNrZXRQcmV2aWV3TGluZVtdIHtcbiAgICByZXR1cm4gcmVjaXBlcy5tYXAoKHJlY2lwZSwgaWR4KSA9PiB7XG4gICAgICBjb25zdCBpdGVtc0NvdW50ID0gbGluZUVudHJpZXNbaWR4XS5mb3VuZC5sZW5ndGg7XG4gICAgICBsZXQgcmVjaXBlUHJpY2UgPSAwLjA7XG4gICAgICBjb25zdCBndWVzdHMgPSByZWNpcGUubW9kaWZpZWRHdWVzdHMgfHwgcGFyc2VJbnQocmVjaXBlLmd1ZXN0cywgMTApO1xuXG4gICAgICBsaW5lRW50cmllc1tpZHhdLmZvdW5kLmZvckVhY2goZW50cnkgPT4ge1xuICAgICAgICBjb25zdCBzZWxlY3RlZEl0ZW0gPSBlbnRyeS5hdHRyaWJ1dGVzWydiYXNrZXQtZW50cmllcy1pdGVtcyddLmZpbmQoaXRlbSA9PiBpdGVtLml0ZW1faWQgPT09IGVudHJ5LmF0dHJpYnV0ZXNbJ3NlbGVjdGVkLWl0ZW0taWQnXSk7XG4gICAgICAgIGNvbnN0IHF0eSA9IGVudHJ5LmF0dHJpYnV0ZXMucXVhbnRpdHk7XG4gICAgICAgIGNvbnN0IHVuaXRQcmljZSA9IHBhcnNlRmxvYXQoc2VsZWN0ZWRJdGVtWyd1bml0LXByaWNlJ10pO1xuICAgICAgICBjb25zdCBudW1iZXJPZlJlY2lwZXNGb3JFbnRyeSA9IGVudHJ5LnJlY2lwZXNJZHMubGVuZ3RoIHx8IDE7XG5cbiAgICAgICAgcmVjaXBlUHJpY2UgKz0gKHF0eSAqIHVuaXRQcmljZSkgLyBudW1iZXJPZlJlY2lwZXNGb3JFbnRyeTtcbiAgICAgIH0pO1xuICAgICAgY29uc3QgcHJpY2VQZXJHdWVzdCA9IHJlY2lwZVByaWNlIC8gZ3Vlc3RzO1xuXG4gICAgICByZXR1cm4gQmFza2V0UHJldmlld0xpbmUuZnJvbVJlY2lwZShyZWNpcGUsIGl0ZW1zQ291bnQsIHByaWNlUGVyR3Vlc3QsIHJlY2lwZVByaWNlLCBsaW5lRW50cmllc1tpZHhdKTtcbiAgICB9KS5zb3J0KChhLCBiKSA9PiByZWNpcGVzLmZpbmRJbmRleChyID0+IHIuaWQgPT09IGIuaWQpIC0gcmVjaXBlcy5maW5kSW5kZXgociA9PiByLmlkID09PSBhLmlkKSk7XG4gIH1cblxuICBwcml2YXRlIGdyb3VwQmFza2V0RW50cmllcyhyZWNpcGVzOiBSZWNpcGVbXSwgZW50cmllczogQmFza2V0RW50cnlbXSk6IExpbmVFbnRyaWVzW10ge1xuICAgIHJldHVybiByZWNpcGVzLm1hcChyZWNpcGUgPT4ge1xuICAgICAgY29uc3QgbGluZUVudHJpZXMgPSB7IGZvdW5kOiBbXSwgbm90Rm91bmQ6IFtdLCBvZnRlbkRlbGV0ZWQ6IFtdLCByZW1vdmVkOiBbXSwgYWxsOiBbXSB9IGFzIExpbmVFbnRyaWVzO1xuICAgICAgZW50cmllc1xuICAgICAgICAuZmlsdGVyKGVudHJ5ID0+IGVudHJ5LnJlY2lwZXNJZHMuaW5jbHVkZXMocGFyc2VJbnQocmVjaXBlLmlkLCAxMCkpKVxuICAgICAgICAuZm9yRWFjaChlbnRyeSA9PiB7XG4gICAgICAgICAgY29uc3QgYXZhaWxhYmxlID0gZW50cnkuYXR0cmlidXRlc1snc2VsZWN0ZWQtaXRlbS1pZCddO1xuICAgICAgICAgIGlmIChhdmFpbGFibGUpIHtcbiAgICAgICAgICAgIHN3aXRjaCAoZW50cnkuc3RhdHVzKSB7XG4gICAgICAgICAgICAgIGNhc2UgJ29mdGVuX2RlbGV0ZWQnOiB7XG4gICAgICAgICAgICAgICAgbGluZUVudHJpZXMub2Z0ZW5EZWxldGVkLnB1c2goZW50cnkpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGNhc2UgJ2RlbGV0ZWQnOiB7XG4gICAgICAgICAgICAgICAgbGluZUVudHJpZXMucmVtb3ZlZC5wdXNoKGVudHJ5KTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBkZWZhdWx0OiB7XG4gICAgICAgICAgICAgICAgbGluZUVudHJpZXMuZm91bmQucHVzaChlbnRyeSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbGluZUVudHJpZXMubm90Rm91bmQucHVzaChlbnRyeSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGxpbmVFbnRyaWVzLmFsbC5wdXNoKGVudHJ5KTtcbiAgICAgICAgfSk7XG4gICAgICByZXR1cm4gbGluZUVudHJpZXM7XG4gICAgfSk7XG4gIH1cbn1cbiJdfQ==
|