@infrab4a/connect-angular 5.0.0-beta.97 → 5.1.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.
Files changed (87) hide show
  1. package/angular-connect.module.d.ts +8 -14
  2. package/angular-firestore.module.d.ts +2 -1
  3. package/angular-hasura-graphql.module.d.ts +6 -4
  4. package/consts/firebase-const.d.ts +0 -1
  5. package/consts/index.d.ts +0 -1
  6. package/esm2020/angular-connect.module.mjs +115 -0
  7. package/esm2020/angular-elastic-search.module.mjs +34 -0
  8. package/esm2020/angular-firebase-auth.module.mjs +115 -0
  9. package/esm2020/angular-firestore.module.mjs +504 -0
  10. package/esm2020/angular-hasura-graphql.module.mjs +265 -0
  11. package/{esm2022 → esm2020}/consts/firebase-const.mjs +1 -2
  12. package/{esm2022 → esm2020}/consts/index.mjs +1 -2
  13. package/{esm2022 → esm2020}/persistence/cookie-data-persistence.mjs +4 -4
  14. package/{esm2022 → esm2020}/services/auth.service.mjs +6 -6
  15. package/esm2020/services/cart.service.mjs +281 -0
  16. package/{esm2022 → esm2020}/services/catalog/adapters/new-category-structure.adapter.mjs +6 -6
  17. package/{esm2022 → esm2020}/services/catalog/adapters/old-category-structure.adapter.mjs +6 -6
  18. package/esm2020/services/catalog/catalog.service.mjs +194 -0
  19. package/esm2020/services/catalog/category.service.mjs +51 -0
  20. package/{esm2022 → esm2020}/services/catalog/models/category-with-tree.model.mjs +1 -1
  21. package/esm2020/services/catalog/wishlist.service.mjs +115 -0
  22. package/{esm2022 → esm2020}/services/checkout-subscription.service.mjs +6 -6
  23. package/esm2020/services/checkout.service.mjs +68 -0
  24. package/esm2020/services/coupon.service.mjs +235 -0
  25. package/{esm2022 → esm2020}/services/home-shop.service.mjs +9 -9
  26. package/{esm2022 → esm2020}/services/index.mjs +2 -1
  27. package/{esm2022 → esm2020}/services/order.service.mjs +6 -6
  28. package/esm2020/services/shipping.service.mjs +96 -0
  29. package/esm2020/services/types/shipping-methods.type.mjs +2 -0
  30. package/fesm2015/infrab4a-connect-angular.mjs +2417 -0
  31. package/fesm2015/infrab4a-connect-angular.mjs.map +1 -0
  32. package/{fesm2022 → fesm2020}/infrab4a-connect-angular.mjs +1304 -1555
  33. package/fesm2020/infrab4a-connect-angular.mjs.map +1 -0
  34. package/package.json +15 -9
  35. package/services/cart.service.d.ts +19 -8
  36. package/services/catalog/catalog.service.d.ts +5 -15
  37. package/services/catalog/category.service.d.ts +3 -7
  38. package/services/catalog/wishlist.service.d.ts +4 -16
  39. package/services/checkout.service.d.ts +6 -16
  40. package/services/coupon.service.d.ts +2 -0
  41. package/services/index.d.ts +1 -0
  42. package/services/shipping.service.d.ts +19 -0
  43. package/services/types/shipping-methods.type.d.ts +12 -0
  44. package/angular-vertex-search.module.d.ts +0 -9
  45. package/consts/vertex-config.const.d.ts +0 -1
  46. package/esm2022/angular-connect.module.mjs +0 -187
  47. package/esm2022/angular-elastic-search.module.mjs +0 -34
  48. package/esm2022/angular-firebase-auth.module.mjs +0 -141
  49. package/esm2022/angular-firestore.module.mjs +0 -541
  50. package/esm2022/angular-hasura-graphql.module.mjs +0 -333
  51. package/esm2022/angular-vertex-search.module.mjs +0 -34
  52. package/esm2022/consts/vertex-config.const.mjs +0 -2
  53. package/esm2022/services/cart.service.mjs +0 -86
  54. package/esm2022/services/catalog/catalog.service.mjs +0 -325
  55. package/esm2022/services/catalog/category.service.mjs +0 -51
  56. package/esm2022/services/catalog/wishlist.service.mjs +0 -235
  57. package/esm2022/services/checkout.service.mjs +0 -122
  58. package/esm2022/services/coupon.service.mjs +0 -228
  59. package/fesm2022/infrab4a-connect-angular.mjs.map +0 -1
  60. /package/{esm2022 → esm2020}/consts/backend-url.const.mjs +0 -0
  61. /package/{esm2022 → esm2020}/consts/category-structure.mjs +0 -0
  62. /package/{esm2022 → esm2020}/consts/default-shop.const.mjs +0 -0
  63. /package/{esm2022 → esm2020}/consts/es-config.const.mjs +0 -0
  64. /package/{esm2022 → esm2020}/consts/hasura-options.const.mjs +0 -0
  65. /package/{esm2022 → esm2020}/consts/persistence.const.mjs +0 -0
  66. /package/{esm2022 → esm2020}/consts/storage-base-url.const.mjs +0 -0
  67. /package/{esm2022 → esm2020}/helpers/index.mjs +0 -0
  68. /package/{esm2022 → esm2020}/helpers/mobile-operation-system-checker.helper.mjs +0 -0
  69. /package/{esm2022 → esm2020}/index.mjs +0 -0
  70. /package/{esm2022 → esm2020}/infrab4a-connect-angular.mjs +0 -0
  71. /package/{esm2022 → esm2020}/persistence/data-persistence.mjs +0 -0
  72. /package/{esm2022 → esm2020}/persistence/index.mjs +0 -0
  73. /package/{esm2022 → esm2020}/services/catalog/adapters/category-structure.adapter.mjs +0 -0
  74. /package/{esm2022 → esm2020}/services/catalog/adapters/index.mjs +0 -0
  75. /package/{esm2022 → esm2020}/services/catalog/enums/index.mjs +0 -0
  76. /package/{esm2022 → esm2020}/services/catalog/enums/product-sorts.enum.mjs +0 -0
  77. /package/{esm2022 → esm2020}/services/catalog/index.mjs +0 -0
  78. /package/{esm2022 → esm2020}/services/catalog/models/index.mjs +0 -0
  79. /package/{esm2022 → esm2020}/services/catalog/types/index.mjs +0 -0
  80. /package/{esm2022 → esm2020}/services/catalog/types/product-sort.type.mjs +0 -0
  81. /package/{esm2022 → esm2020}/services/helpers/index.mjs +0 -0
  82. /package/{esm2022 → esm2020}/services/helpers/util.helper.mjs +0 -0
  83. /package/{esm2022 → esm2020}/services/types/index.mjs +0 -0
  84. /package/{esm2022 → esm2020}/services/types/required-checkout-data.type.mjs +0 -0
  85. /package/{esm2022 → esm2020}/services/types/required-checkout-subscription-data.type.mjs +0 -0
  86. /package/{esm2022 → esm2020}/types/firebase-app-config.type.mjs +0 -0
  87. /package/{esm2022 → esm2020}/types/index.mjs +0 -0
@@ -1,325 +0,0 @@
1
- import { Inject, Injectable } from '@angular/core';
2
- import { InvalidArgumentError, RoundProductPricesHelper, Shops, Where, isEmpty, set, } from '@infrab4a/connect';
3
- import { CATEGORY_STRUCTURE, DEFAULT_SHOP } from '../../consts';
4
- import * as i0 from "@angular/core";
5
- import * as i1 from "@infrab4a/connect";
6
- export class CatalogService {
7
- constructor(productRepository, productStockNotificationRepository, categoryRepository, categoryStructureAdapter, shop, productSearch) {
8
- this.productRepository = productRepository;
9
- this.productStockNotificationRepository = productStockNotificationRepository;
10
- this.categoryRepository = categoryRepository;
11
- this.categoryStructureAdapter = categoryStructureAdapter;
12
- this.shop = shop;
13
- this.productSearch = productSearch;
14
- this.productsByTerm = {};
15
- this.brandsList = {};
16
- this.fields = [
17
- 'id',
18
- 'name',
19
- 'slug',
20
- 'images',
21
- 'miniatures',
22
- 'price',
23
- 'stock',
24
- 'published',
25
- 'CEST',
26
- 'EAN',
27
- 'NCM',
28
- 'brand',
29
- 'costPrice',
30
- 'hasVariants',
31
- 'isKit',
32
- 'sku',
33
- 'rate',
34
- 'tags',
35
- 'type',
36
- 'shoppingCount',
37
- 'gender',
38
- 'createdAt',
39
- 'label',
40
- 'outlet',
41
- 'group',
42
- ];
43
- this.buildFilterQuery = ({ clubDiscount, brands, prices, gender, tags, rate, customOptions, }) => {
44
- const filters = {};
45
- if (clubDiscount?.length)
46
- set(filters, 'price.subscriberDiscountPercentage', { operator: Where.IN, value: clubDiscount });
47
- if (brands?.length)
48
- filters.brand = { operator: Where.IN, value: brands };
49
- if (gender?.length)
50
- filters.gender = { operator: Where.IN, value: gender };
51
- if (prices?.min || prices?.max)
52
- set(filters, prices.subscriberPrice ? 'price.subscriberPrice' : 'price.price', [
53
- ...(prices.min ? [{ operator: Where.GTE, value: Math.floor(prices.min) }] : []),
54
- ...(prices.max ? [{ operator: Where.LTE, value: Math.ceil(prices.max) }] : []),
55
- ]);
56
- if (rate)
57
- filters.rate = { operator: Where.GTE, value: rate };
58
- if (tags?.length)
59
- filters.tags = { operator: Where.LIKE, value: tags };
60
- if (customOptions?.length)
61
- filters.filters = { operator: Where.LIKE, value: customOptions };
62
- return filters;
63
- };
64
- this.buildSortQuery = (sort) => {
65
- if (!sort || sort === 'most-relevant')
66
- return {};
67
- if (sort === 'best-sellers')
68
- return {
69
- shoppingCount: 'desc',
70
- rate: 'desc',
71
- stock: 'desc',
72
- name: 'asc',
73
- };
74
- if (sort === 'biggest-price')
75
- return { subscriberPrice: 'desc', rate: 'desc', shoppingCount: 'desc' };
76
- if (sort === 'lowest-price')
77
- return { subscriberPrice: 'asc', rate: 'desc', shoppingCount: 'desc' };
78
- if (sort === 'best-rating')
79
- return { rate: 'desc', shoppingCount: 'desc', stock: 'desc', name: 'asc' };
80
- if (sort === 'news')
81
- return { createdAt: 'desc' };
82
- if (sort === 'biggest-discount')
83
- return { subscriberDiscountPercentage: 'desc', rate: 'desc', shoppingCount: 'desc' };
84
- };
85
- this.buildLimitQuery = (options) => {
86
- const limit = options?.perPage || 20;
87
- return {
88
- limit,
89
- offset: ((options?.page || 1) - 1) * limit,
90
- };
91
- };
92
- this.hasProfile = (options) => 'profile' in options;
93
- this.hasTerm = (options) => 'term' in options;
94
- this.hasCategory = (options) => 'category' in options;
95
- this.buildIndexBrands = (options) => {
96
- if (this.hasCategory(options))
97
- return `category-${options.category.id}`;
98
- if (this.hasTerm(options))
99
- return `term-${options.term}`;
100
- if (this.hasProfile(options))
101
- return `profile-${options.profile.join(',')}`;
102
- return '';
103
- };
104
- }
105
- async fetchProducts(options, optionsCache) {
106
- const limits = this.buildLimitQuery(options);
107
- if (this.hasProfile(options) && options.filters?.customOptions)
108
- throw new InvalidArgumentError(`It couldn't filled customOptions when profile is given`);
109
- if (this.hasProfile(options) && options.filters?.tags)
110
- throw new InvalidArgumentError(`It couldn't filled tags when profile is given`);
111
- if (this.hasTerm(options) && options.filters?.customOptions)
112
- throw new InvalidArgumentError(`It couldn't filled customOptions when term is given`);
113
- return await this.findCatalog(options, limits, optionsCache).then(async ({ data, count: total, maximum, minimal, distinct }) => {
114
- await this.setBrandsList(options, distinct?.brand);
115
- return {
116
- products: { data: data.map((product) => RoundProductPricesHelper.roundProductPrices(product)), total },
117
- pages: Math.ceil(total / limits.limit),
118
- prices: {
119
- price: { min: +minimal?.price?.price?.toFixed(2), max: +maximum?.price?.price?.toFixed(2) },
120
- subscriberPrice: {
121
- min: +minimal?.price?.subscriberPrice?.toFixed(2),
122
- max: +maximum?.price?.subscriberPrice?.toFixed(2),
123
- },
124
- },
125
- brands: this.brandsList[this.buildIndexBrands(options)],
126
- };
127
- });
128
- }
129
- async addCustomerToStockNotification(shop, productId, name, email) {
130
- return this.productStockNotificationRepository.addCustomerEmail(shop, productId, name, email);
131
- }
132
- async findCatalog(options, limits, optionsCache) {
133
- if (this.hasTerm(options) && options.sort === 'most-relevant') {
134
- const productsIds = await this.findCatalogIdsBySearch(options.term);
135
- return this.findCatalogAndSortByMostRevelantByTerm(productsIds, options, limits);
136
- }
137
- if (this.hasCategory(options) && options.sort === 'most-relevant') {
138
- const mostRelevant = options.category.isWishlist ? [] : options.category.getMostRelevantByShop(this.shop);
139
- const productsIds = await this.productRepository
140
- .findCatalog({
141
- fields: ['id'],
142
- filters: {
143
- ...(await this.buildMainFilter(options)),
144
- ...this.buildFilterQuery(options?.filters || {}),
145
- },
146
- }, undefined, optionsCache)
147
- .then((products) => products.data.map((product) => product.id));
148
- return this.findCatalogAndSortByMostRevelant(mostRelevant, productsIds, options, limits, optionsCache);
149
- }
150
- const repoParams = {
151
- fields: this.fields,
152
- filters: {
153
- ...(await this.buildMainFilter(options)),
154
- ...this.buildFilterQuery(options?.filters || {}),
155
- },
156
- ...(options?.sort ? { orderBy: this.buildSortQuery(options?.sort) } : {}),
157
- limits,
158
- options: {
159
- minimal: ['price'],
160
- maximum: ['price'],
161
- ...(!this.brandsList[this.buildIndexBrands(options)] && isEmpty(options.filters?.brands)
162
- ? { distinct: ['brand'] }
163
- : {}),
164
- },
165
- };
166
- if (['biggest-price', 'lowest-price', 'biggest-discount', 'best-rating'].includes(options.sort))
167
- return this.productRepository.findCatalog(repoParams, undefined, optionsCache);
168
- return this.productRepository.findCatalog(repoParams, options?.mainGender || this.shop === Shops.MENSMARKET ? 'male' : 'female', optionsCache);
169
- }
170
- async buildMainFilter({ category, profile, term, }) {
171
- if (category)
172
- return this.categoryStructureAdapter.buildProductFilterByCategory(category);
173
- if (profile)
174
- return { tags: { operator: Where.LIKE, value: profile } };
175
- if (term)
176
- return this.productSearch
177
- .search(term, 999, this.shop == Shops.GLAMSHOP ? 'female' : 'male')
178
- .then((data) => ({ id: { operator: Where.IN, value: data.map((_source) => _source.id) } }));
179
- }
180
- async findCatalogAndSortByMostRevelant(mostRelevants, productIds, options, limits, optionsCache) {
181
- const brandsList = this.brandsList[this.buildIndexBrands(options)];
182
- const mostRelevantProductsIds = [...new Set(mostRelevants.concat(productIds))];
183
- const totalResult = await this.productRepository.findCatalog({
184
- fields: this.fields,
185
- filters: {
186
- id: { operator: Where.IN, value: mostRelevantProductsIds },
187
- ...this.buildFilterQuery(options?.filters || {}),
188
- },
189
- orderBy: this.buildSortQuery('best-sellers'),
190
- options: {
191
- minimal: ['price'],
192
- maximum: ['price'],
193
- ...(!brandsList && isEmpty(options.filters?.brands) ? { distinct: ['brand'] } : {}),
194
- },
195
- }, options?.mainGender || this.shop === Shops.MENSMARKET ? 'male' : 'female', optionsCache);
196
- const mostRelevantWithouyStock = totalResult.data.filter((product) => mostRelevants.includes(product.id) && product.stock.quantity <= 0);
197
- const firstProducts = totalResult.data
198
- .filter((product) => mostRelevants.includes(product.id) && product.stock.quantity > 0)
199
- .sort((a, b) => mostRelevants.indexOf(a.id) - mostRelevants.indexOf(b.id));
200
- const lastProducts = totalResult.data
201
- .filter((product) => !mostRelevants.includes(product.id))
202
- .concat(mostRelevantWithouyStock);
203
- const categoryMostRelevants = firstProducts.concat(lastProducts);
204
- const resultFinal = categoryMostRelevants.slice(limits.offset, limits.offset + limits.limit);
205
- await this.setBrandsList(options, totalResult.distinct?.brand);
206
- return {
207
- data: resultFinal,
208
- count: totalResult.count,
209
- maximum: totalResult.maximum,
210
- minimal: totalResult.minimal,
211
- distinct: {
212
- ...totalResult.distinct,
213
- brand: this.brandsList[this.buildIndexBrands(options)],
214
- },
215
- };
216
- }
217
- async findCatalogAndSortByMostRevelantByTerm(productIds, options, limits) {
218
- const brandsList = this.brandsList[this.buildIndexBrands(options)];
219
- const totalResult = await this.productRepository.findCatalog({
220
- fields: ['id', 'stock', 'gender'],
221
- filters: {
222
- id: { operator: Where.IN, value: productIds },
223
- published: { operator: Where.EQUALS, value: true },
224
- ...this.buildFilterQuery(options?.filters || {}),
225
- },
226
- options: {
227
- minimal: ['price'],
228
- maximum: ['price'],
229
- ...(!brandsList && isEmpty(options.filters?.brands) ? { distinct: ['brand'] } : {}),
230
- },
231
- }, options?.mainGender || this.shop === Shops.MENSMARKET ? 'male' : 'female');
232
- const defaultGender = options?.filters?.gender
233
- ? options?.filters?.gender.at(0)
234
- : this.shop === Shops.GLAMSHOP
235
- ? 'female'
236
- : 'male';
237
- const stockData = totalResult.data.filter((product) => product.stock.quantity > 0);
238
- const stockOut = totalResult.data.filter((product) => product.stock.quantity <= 0);
239
- const productIdsStockGender = productIds.filter((product) => stockData.some((result) => result.id === product && (result.gender?.includes(defaultGender) || result.gender?.includes('unisex'))));
240
- const productIdsStockNotGender = productIds.filter((product) => stockData.some((result) => result.id === product && !result.gender?.includes(defaultGender) && !result.gender?.includes('unisex')));
241
- const productIdsStock = productIdsStockGender.concat(productIdsStockNotGender);
242
- const productIdsStockOut = productIds.filter((product) => stockOut.some((result) => result.id === product));
243
- const limitedProductId = productIdsStock
244
- .concat(productIdsStockOut)
245
- .slice(limits.offset, limits.offset + limits.limit);
246
- const orderedId = productIds.filter((product) => limitedProductId.includes(product));
247
- const productResult = await this.productRepository.findCatalog({
248
- filters: {
249
- id: { operator: Where.IN, value: orderedId },
250
- },
251
- fields: this.fields,
252
- });
253
- await this.setBrandsList(options, totalResult.distinct?.brand);
254
- return {
255
- data: limitedProductId.map((id) => productResult.data.find((product) => product.id === id)).filter(Boolean),
256
- count: totalResult.count,
257
- maximum: totalResult.maximum,
258
- minimal: totalResult.minimal,
259
- distinct: {
260
- ...totalResult.distinct,
261
- brand: this.brandsList[this.buildIndexBrands(options)],
262
- },
263
- };
264
- }
265
- async findCatalogIdsBySearch(term, preview = false) {
266
- if (this.productsByTerm[term])
267
- return this.productsByTerm[term];
268
- return (this.productsByTerm[term] = await this.productSearch
269
- .search(term, 999, this.shop == Shops.GLAMSHOP ? 'female' : 'male')
270
- .then((products) => [...new Set(products.map((product) => product.id))]));
271
- }
272
- async fetchBrandsOnly(options, productIds = []) {
273
- return this.productRepository
274
- .findCatalog({
275
- fields: ['id'],
276
- filters: {
277
- ...(!isEmpty(productIds) ? { id: { operator: Where.IN, value: productIds } } : {}),
278
- published: { operator: Where.EQUALS, value: true },
279
- ...this.buildFilterQuery(options?.filters || {}),
280
- },
281
- options: {
282
- distinct: ['brand'],
283
- },
284
- }, options?.mainGender || this.shop === Shops.MENSMARKET ? 'male' : 'female')
285
- .then((result) => {
286
- return result.distinct.brand;
287
- });
288
- }
289
- async setBrandsList(options, brands) {
290
- const filterBrands = options.filters?.brands;
291
- if (isEmpty(brands))
292
- delete options.filters?.brands;
293
- this.brandsList[this.buildIndexBrands(options)] =
294
- this.brandsList[this.buildIndexBrands(options)] || brands || (await this.fetchBrandsOnly(options));
295
- this.brandsList[this.buildIndexBrands(options)] = this.brandsList[this.buildIndexBrands(options)].filter(Boolean);
296
- options.filters = {
297
- ...options.filters,
298
- brands: filterBrands,
299
- };
300
- }
301
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.3", ngImport: i0, type: CatalogService, deps: [{ token: 'ProductRepository' }, { token: 'ProductStockNotificationRepository' }, { token: 'CategoryRepository' }, { token: CATEGORY_STRUCTURE }, { token: DEFAULT_SHOP }, { token: 'ProductSearch' }], target: i0.ɵɵFactoryTarget.Injectable }); }
302
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.0.3", ngImport: i0, type: CatalogService }); }
303
- }
304
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.3", ngImport: i0, type: CatalogService, decorators: [{
305
- type: Injectable
306
- }], ctorParameters: () => [{ type: undefined, decorators: [{
307
- type: Inject,
308
- args: ['ProductRepository']
309
- }] }, { type: undefined, decorators: [{
310
- type: Inject,
311
- args: ['ProductStockNotificationRepository']
312
- }] }, { type: undefined, decorators: [{
313
- type: Inject,
314
- args: ['CategoryRepository']
315
- }] }, { type: undefined, decorators: [{
316
- type: Inject,
317
- args: [CATEGORY_STRUCTURE]
318
- }] }, { type: i1.Shops, decorators: [{
319
- type: Inject,
320
- args: [DEFAULT_SHOP]
321
- }] }, { type: undefined, decorators: [{
322
- type: Inject,
323
- args: ['ProductSearch']
324
- }] }] });
325
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2F0YWxvZy5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvY29ubmVjdC1hbmd1bGFyL3NyYy9zZXJ2aWNlcy9jYXRhbG9nL2NhdGFsb2cuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsTUFBTSxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQTtBQUNsRCxPQUFPLEVBSUwsb0JBQW9CLEVBWXBCLHdCQUF3QixFQUN4QixLQUFLLEVBQ0wsS0FBSyxFQUNMLE9BQU8sRUFDUCxHQUFHLEdBQ0osTUFBTSxtQkFBbUIsQ0FBQTtBQUMxQixPQUFPLEVBQUUsa0JBQWtCLEVBQUUsWUFBWSxFQUFFLE1BQU0sY0FBYyxDQUFBOzs7QUFzRC9ELE1BQU0sT0FBTyxjQUFjO0lBK0J6QixZQUNnRCxpQkFBb0MsRUFFakUsa0NBQXNFLEVBQ3hDLGtCQUFzQyxFQUN4Qyx3QkFBa0QsRUFDeEQsSUFBVyxFQUNSLGFBQWlDO1FBTjdCLHNCQUFpQixHQUFqQixpQkFBaUIsQ0FBbUI7UUFFakUsdUNBQWtDLEdBQWxDLGtDQUFrQyxDQUFvQztRQUN4Qyx1QkFBa0IsR0FBbEIsa0JBQWtCLENBQW9CO1FBQ3hDLDZCQUF3QixHQUF4Qix3QkFBd0IsQ0FBMEI7UUFDeEQsU0FBSSxHQUFKLElBQUksQ0FBTztRQUNSLGtCQUFhLEdBQWIsYUFBYSxDQUFvQjtRQXJDckUsbUJBQWMsR0FBNkIsRUFBRSxDQUFBO1FBQzdDLGVBQVUsR0FBNkIsRUFBRSxDQUFBO1FBQ3pDLFdBQU0sR0FBd0M7WUFDcEQsSUFBSTtZQUNKLE1BQU07WUFDTixNQUFNO1lBQ04sUUFBUTtZQUNSLFlBQVk7WUFDWixPQUFPO1lBQ1AsT0FBTztZQUNQLFdBQVc7WUFDWCxNQUFNO1lBQ04sS0FBSztZQUNMLEtBQUs7WUFDTCxPQUFPO1lBQ1AsV0FBVztZQUNYLGFBQWE7WUFDYixPQUFPO1lBQ1AsS0FBSztZQUNMLE1BQU07WUFDTixNQUFNO1lBQ04sTUFBTTtZQUNOLGVBQWU7WUFDZixRQUFRO1lBQ1IsV0FBVztZQUNYLE9BQU87WUFDUCxRQUFRO1lBQ1IsT0FBTztTQUNSLENBQUE7UUErU08scUJBQWdCLEdBQUcsQ0FBQyxFQUMxQixZQUFZLEVBQ1osTUFBTSxFQUNOLE1BQU0sRUFDTixNQUFNLEVBQ04sSUFBSSxFQUNKLElBQUksRUFDSixhQUFhLEdBQ1EsRUFBbUMsRUFBRTtZQUMxRCxNQUFNLE9BQU8sR0FBRyxFQUFxQyxDQUFBO1lBRXJELElBQUksWUFBWSxFQUFFLE1BQU07Z0JBQ3RCLEdBQUcsQ0FBQyxPQUFPLEVBQUUsb0NBQW9DLEVBQUUsRUFBRSxRQUFRLEVBQUUsS0FBSyxDQUFDLEVBQUUsRUFBRSxLQUFLLEVBQUUsWUFBWSxFQUFFLENBQUMsQ0FBQTtZQUNqRyxJQUFJLE1BQU0sRUFBRSxNQUFNO2dCQUFFLE9BQU8sQ0FBQyxLQUFLLEdBQUcsRUFBRSxRQUFRLEVBQUUsS0FBSyxDQUFDLEVBQUUsRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLENBQUE7WUFDekUsSUFBSSxNQUFNLEVBQUUsTUFBTTtnQkFBRSxPQUFPLENBQUMsTUFBTSxHQUFHLEVBQUUsUUFBUSxFQUFFLEtBQUssQ0FBQyxFQUFFLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxDQUFBO1lBQzFFLElBQUksTUFBTSxFQUFFLEdBQUcsSUFBSSxNQUFNLEVBQUUsR0FBRztnQkFDNUIsR0FBRyxDQUFDLE9BQU8sRUFBRSxNQUFNLENBQUMsZUFBZSxDQUFDLENBQUMsQ0FBQyx1QkFBdUIsQ0FBQyxDQUFDLENBQUMsYUFBYSxFQUFFO29CQUM3RSxHQUFHLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLFFBQVEsRUFBRSxLQUFLLENBQUMsR0FBRyxFQUFFLEtBQUssRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztvQkFDL0UsR0FBRyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxRQUFRLEVBQUUsS0FBSyxDQUFDLEdBQUcsRUFBRSxLQUFLLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7aUJBQy9FLENBQUMsQ0FBQTtZQUNKLElBQUksSUFBSTtnQkFBRSxPQUFPLENBQUMsSUFBSSxHQUFHLEVBQUUsUUFBUSxFQUFFLEtBQUssQ0FBQyxHQUFHLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxDQUFBO1lBQzdELElBQUksSUFBSSxFQUFFLE1BQU07Z0JBQUUsT0FBTyxDQUFDLElBQUksR0FBRyxFQUFFLFFBQVEsRUFBRSxLQUFLLENBQUMsSUFBSSxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsQ0FBQTtZQUN0RSxJQUFJLGFBQWEsRUFBRSxNQUFNO2dCQUFFLE9BQU8sQ0FBQyxPQUFPLEdBQUcsRUFBRSxRQUFRLEVBQUUsS0FBSyxDQUFDLElBQUksRUFBRSxLQUFLLEVBQUUsYUFBYSxFQUFFLENBQUE7WUFFM0YsT0FBTyxPQUFPLENBQUE7UUFDaEIsQ0FBQyxDQUFBO1FBRU8sbUJBQWMsR0FBRyxDQUFDLElBQWlCLEVBQThCLEVBQUU7WUFDekUsSUFBSSxDQUFDLElBQUksSUFBSSxJQUFJLEtBQUssZUFBZTtnQkFBRSxPQUFPLEVBQUUsQ0FBQTtZQUVoRCxJQUFJLElBQUksS0FBSyxjQUFjO2dCQUN6QixPQUFPO29CQUNMLGFBQWEsRUFBRSxNQUFNO29CQUNyQixJQUFJLEVBQUUsTUFBTTtvQkFDWixLQUFLLEVBQUUsTUFBTTtvQkFDYixJQUFJLEVBQUUsS0FBSztpQkFDWixDQUFBO1lBQ0gsSUFBSSxJQUFJLEtBQUssZUFBZTtnQkFBRSxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLGFBQWEsRUFBRSxNQUFNLEVBQVMsQ0FBQTtZQUM1RyxJQUFJLElBQUksS0FBSyxjQUFjO2dCQUFFLE9BQU8sRUFBRSxlQUFlLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsYUFBYSxFQUFFLE1BQU0sRUFBUyxDQUFBO1lBQzFHLElBQUksSUFBSSxLQUFLLGFBQWE7Z0JBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsYUFBYSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsQ0FBQTtZQUN0RyxJQUFJLElBQUksS0FBSyxNQUFNO2dCQUFFLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxFQUFFLENBQUE7WUFDakQsSUFBSSxJQUFJLEtBQUssa0JBQWtCO2dCQUM3QixPQUFPLEVBQUUsNEJBQTRCLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsYUFBYSxFQUFFLE1BQU0sRUFBUyxDQUFBO1FBQy9GLENBQUMsQ0FBQTtRQUVPLG9CQUFlLEdBQUcsQ0FBQyxPQUE0QyxFQUF1QyxFQUFFO1lBQzlHLE1BQU0sS0FBSyxHQUFHLE9BQU8sRUFBRSxPQUFPLElBQUksRUFBRSxDQUFBO1lBRXBDLE9BQU87Z0JBQ0wsS0FBSztnQkFDTCxNQUFNLEVBQUUsQ0FBQyxDQUFDLE9BQU8sRUFBRSxJQUFJLElBQUksQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsS0FBSzthQUMzQyxDQUFBO1FBQ0gsQ0FBQyxDQUFBO1FBRU8sZUFBVSxHQUFHLENBQ25CLE9BQXdDLEVBSXhDLEVBQUUsQ0FBQyxTQUFTLElBQUksT0FBTyxDQUFBO1FBRWpCLFlBQU8sR0FBRyxDQUNoQixPQUF3QyxFQUl4QyxFQUFFLENBQUMsTUFBTSxJQUFJLE9BQU8sQ0FBQTtRQUVkLGdCQUFXLEdBQUcsQ0FDcEIsT0FBd0MsRUFJeEMsRUFBRSxDQUFDLFVBQVUsSUFBSSxPQUFPLENBQUE7UUFFbEIscUJBQWdCLEdBQUcsQ0FBQyxPQUF3QyxFQUFVLEVBQUU7WUFDOUUsSUFBSSxJQUFJLENBQUMsV0FBVyxDQUFDLE9BQU8sQ0FBQztnQkFBRSxPQUFPLFlBQVksT0FBTyxDQUFDLFFBQVEsQ0FBQyxFQUFFLEVBQUUsQ0FBQTtZQUN2RSxJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDO2dCQUFFLE9BQU8sUUFBUSxPQUFPLENBQUMsSUFBSSxFQUFFLENBQUE7WUFDeEQsSUFBSSxJQUFJLENBQUMsVUFBVSxDQUFDLE9BQU8sQ0FBQztnQkFBRSxPQUFPLFdBQVcsT0FBTyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQTtZQUUzRSxPQUFPLEVBQUUsQ0FBQTtRQUNYLENBQUMsQ0FBQTtJQXRYRSxDQUFDO0lBRUosS0FBSyxDQUFDLGFBQWEsQ0FDakIsT0FBK0IsRUFDL0IsWUFBaUQ7UUFFakQsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQyxPQUFPLENBQUMsQ0FBQTtRQUU1QyxJQUFJLElBQUksQ0FBQyxVQUFVLENBQUMsT0FBTyxDQUFDLElBQUksT0FBTyxDQUFDLE9BQU8sRUFBRSxhQUFhO1lBQzVELE1BQU0sSUFBSSxvQkFBb0IsQ0FBQyx3REFBd0QsQ0FBQyxDQUFBO1FBQzFGLElBQUksSUFBSSxDQUFDLFVBQVUsQ0FBQyxPQUFPLENBQUMsSUFBSSxPQUFPLENBQUMsT0FBTyxFQUFFLElBQUk7WUFDbkQsTUFBTSxJQUFJLG9CQUFvQixDQUFDLCtDQUErQyxDQUFDLENBQUE7UUFDakYsSUFBSSxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxJQUFJLE9BQU8sQ0FBQyxPQUFPLEVBQUUsYUFBYTtZQUN6RCxNQUFNLElBQUksb0JBQW9CLENBQUMscURBQXFELENBQUMsQ0FBQTtRQUV2RixPQUFPLE1BQU0sSUFBSSxDQUFDLFdBQVcsQ0FBQyxPQUFPLEVBQUUsTUFBTSxFQUFFLFlBQVksQ0FBQyxDQUFDLElBQUksQ0FDL0QsS0FBSyxFQUFFLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFLE9BQU8sRUFBRSxRQUFRLEVBQUUsRUFBRSxFQUFFO1lBQzNELE1BQU0sSUFBSSxDQUFDLGFBQWEsQ0FBQyxPQUFPLEVBQUUsUUFBUSxFQUFFLEtBQUssQ0FBQyxDQUFBO1lBRWxELE9BQU87Z0JBQ0wsUUFBUSxFQUFFLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDLHdCQUF3QixDQUFDLGtCQUFrQixDQUFDLE9BQU8sQ0FBQyxDQUFDLEVBQUUsS0FBSyxFQUFFO2dCQUN0RyxLQUFLLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLEdBQUcsTUFBTSxDQUFDLEtBQUssQ0FBQztnQkFDdEMsTUFBTSxFQUFFO29CQUNOLEtBQUssRUFBRSxFQUFFLEdBQUcsRUFBRSxDQUFDLE9BQU8sRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUMsRUFBRSxHQUFHLEVBQUUsQ0FBQyxPQUFPLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUU7b0JBQzNGLGVBQWUsRUFBRTt3QkFDZixHQUFHLEVBQUUsQ0FBQyxPQUFPLEVBQUUsS0FBSyxFQUFFLGVBQWUsRUFBRSxPQUFPLENBQUMsQ0FBQyxDQUFDO3dCQUNqRCxHQUFHLEVBQUUsQ0FBQyxPQUFPLEVBQUUsS0FBSyxFQUFFLGVBQWUsRUFBRSxPQUFPLENBQUMsQ0FBQyxDQUFDO3FCQUNsRDtpQkFDRjtnQkFDRCxNQUFNLEVBQUUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsT0FBTyxDQUFDLENBQUM7YUFDeEQsQ0FBQTtRQUNILENBQUMsQ0FDRixDQUFBO0lBQ0gsQ0FBQztJQUVELEtBQUssQ0FBQyw4QkFBOEIsQ0FBQyxJQUFXLEVBQUUsU0FBaUIsRUFBRSxJQUFZLEVBQUUsS0FBYTtRQUM5RixPQUFPLElBQUksQ0FBQyxrQ0FBa0MsQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxLQUFLLENBQUMsQ0FBQTtJQUMvRixDQUFDO0lBRU8sS0FBSyxDQUFDLFdBQVcsQ0FDdkIsT0FBK0IsRUFDL0IsTUFHQyxFQUNELFlBQWlEO1FBRWpELElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsSUFBSSxPQUFPLENBQUMsSUFBSSxLQUFLLGVBQWUsRUFBRTtZQUM3RCxNQUFNLFdBQVcsR0FBRyxNQUFNLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUE7WUFFbkUsT0FBTyxJQUFJLENBQUMsc0NBQXNDLENBQUMsV0FBVyxFQUFFLE9BQU8sRUFBRSxNQUFNLENBQUMsQ0FBQTtTQUNqRjtRQUVELElBQUksSUFBSSxDQUFDLFdBQVcsQ0FBQyxPQUFPLENBQUMsSUFBSSxPQUFPLENBQUMsSUFBSSxLQUFLLGVBQWUsRUFBRTtZQUNqRSxNQUFNLFlBQVksR0FBRyxPQUFPLENBQUMsUUFBUSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLHFCQUFxQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQTtZQUN6RyxNQUFNLFdBQVcsR0FBRyxNQUFNLElBQUksQ0FBQyxpQkFBaUI7aUJBQzdDLFdBQVcsQ0FDVjtnQkFDRSxNQUFNLEVBQUUsQ0FBQyxJQUFJLENBQUM7Z0JBQ2QsT0FBTyxFQUFFO29CQUNQLEdBQUcsQ0FBQyxNQUFNLElBQUksQ0FBQyxlQUFlLENBQUMsT0FBTyxDQUFDLENBQUM7b0JBQ3hDLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDLE9BQU8sRUFBRSxPQUFPLElBQUksRUFBRSxDQUFDO2lCQUNqRDthQUNGLEVBQ0QsU0FBUyxFQUNULFlBQVksQ0FDYjtpQkFDQSxJQUFJLENBQUMsQ0FBQyxRQUFRLEVBQUUsRUFBRSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQTtZQUVqRSxPQUFPLElBQUksQ0FBQyxnQ0FBZ0MsQ0FBQyxZQUFZLEVBQUUsV0FBVyxFQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUUsWUFBWSxDQUFDLENBQUE7U0FDdkc7UUFFRCxNQUFNLFVBQVUsR0FBa0M7WUFDaEQsTUFBTSxFQUFFLElBQUksQ0FBQyxNQUFNO1lBQ25CLE9BQU8sRUFBRTtnQkFDUCxHQUFHLENBQUMsTUFBTSxJQUFJLENBQUMsZUFBZSxDQUFDLE9BQU8sQ0FBQyxDQUFDO2dCQUN4QyxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxPQUFPLEVBQUUsT0FBTyxJQUFJLEVBQUUsQ0FBQzthQUNqRDtZQUNELEdBQUcsQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLE9BQU8sRUFBRSxJQUFJLENBQUMsY0FBYyxDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7WUFDekUsTUFBTTtZQUNOLE9BQU8sRUFBRTtnQkFDUCxPQUFPLEVBQUUsQ0FBQyxPQUFPLENBQUM7Z0JBQ2xCLE9BQU8sRUFBRSxDQUFDLE9BQU8sQ0FBQztnQkFDbEIsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsT0FBTyxDQUFDLENBQUMsSUFBSSxPQUFPLENBQUMsT0FBTyxDQUFDLE9BQU8sRUFBRSxNQUFNLENBQUM7b0JBQ3RGLENBQUMsQ0FBQyxFQUFFLFFBQVEsRUFBRSxDQUFDLE9BQU8sQ0FBQyxFQUFFO29CQUN6QixDQUFDLENBQUMsRUFBRSxDQUFDO2FBQ1I7U0FDRixDQUFBO1FBRUQsSUFBSSxDQUFDLGVBQWUsRUFBRSxjQUFjLEVBQUUsa0JBQWtCLEVBQUUsYUFBYSxDQUFDLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUM7WUFDN0YsT0FBTyxJQUFJLENBQUMsaUJBQWlCLENBQUMsV0FBVyxDQUFDLFVBQVUsRUFBRSxTQUFTLEVBQUUsWUFBWSxDQUFDLENBQUE7UUFFaEYsT0FBTyxJQUFJLENBQUMsaUJBQWlCLENBQUMsV0FBVyxDQUN2QyxVQUFVLEVBQ1YsT0FBTyxFQUFFLFVBQVUsSUFBSSxJQUFJLENBQUMsSUFBSSxLQUFLLEtBQUssQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsUUFBUSxFQUN6RSxZQUFZLENBQ2IsQ0FBQTtJQUNILENBQUM7SUFFTyxLQUFLLENBQUMsZUFBZSxDQUFDLEVBQzVCLFFBQVEsRUFDUixPQUFPLEVBQ1AsSUFBSSxHQUN1QjtRQUMzQixJQUFJLFFBQVE7WUFBRSxPQUFPLElBQUksQ0FBQyx3QkFBd0IsQ0FBQyw0QkFBNEIsQ0FBQyxRQUFRLENBQUMsQ0FBQTtRQUN6RixJQUFJLE9BQU87WUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLEVBQUUsUUFBUSxFQUFFLEtBQUssQ0FBQyxJQUFJLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRSxFQUFFLENBQUE7UUFDdEUsSUFBSSxJQUFJO1lBQ04sT0FBTyxJQUFJLENBQUMsYUFBYTtpQkFDdEIsTUFBTSxDQUFVLElBQUksRUFBRSxHQUFHLEVBQUUsSUFBSSxDQUFDLElBQUksSUFBSSxLQUFLLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQztpQkFDM0UsSUFBSSxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsUUFBUSxFQUFFLEtBQUssQ0FBQyxFQUFFLEVBQUUsS0FBSyxFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFBO0lBQ2pHLENBQUM7SUFFTyxLQUFLLENBQUMsZ0NBQWdDLENBQzVDLGFBQXVCLEVBQ3ZCLFVBQW9CLEVBQ3BCLE9BR0MsRUFDRCxNQUdDLEVBQ0QsWUFBaUQ7UUFFakQsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQTtRQUNsRSxNQUFNLHVCQUF1QixHQUFHLENBQUMsR0FBRyxJQUFJLEdBQUcsQ0FBQyxhQUFhLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQTtRQUM5RSxNQUFNLFdBQVcsR0FBRyxNQUFNLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxXQUFXLENBQzFEO1lBQ0UsTUFBTSxFQUFFLElBQUksQ0FBQyxNQUFNO1lBQ25CLE9BQU8sRUFBRTtnQkFDUCxFQUFFLEVBQUUsRUFBRSxRQUFRLEVBQUUsS0FBSyxDQUFDLEVBQUUsRUFBRSxLQUFLLEVBQUUsdUJBQXVCLEVBQUU7Z0JBQzFELEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDLE9BQU8sRUFBRSxPQUFPLElBQUksRUFBRSxDQUFDO2FBQ2pEO1lBQ0QsT0FBTyxFQUFFLElBQUksQ0FBQyxjQUFjLENBQUMsY0FBYyxDQUFDO1lBQzVDLE9BQU8sRUFBRTtnQkFDUCxPQUFPLEVBQUUsQ0FBQyxPQUFPLENBQUM7Z0JBQ2xCLE9BQU8sRUFBRSxDQUFDLE9BQU8sQ0FBQztnQkFDbEIsR0FBRyxDQUFDLENBQUMsVUFBVSxJQUFJLE9BQU8sQ0FBQyxPQUFPLENBQUMsT0FBTyxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLFFBQVEsRUFBRSxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQzthQUNwRjtTQUNGLEVBQ0QsT0FBTyxFQUFFLFVBQVUsSUFBSSxJQUFJLENBQUMsSUFBSSxLQUFLLEtBQUssQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsUUFBUSxFQUN6RSxZQUFZLENBQ2IsQ0FBQTtRQUVELE1BQU0sd0JBQXdCLEdBQUcsV0FBVyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQ3RELENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FBQyxhQUFhLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsSUFBSSxPQUFPLENBQUMsS0FBSyxDQUFDLFFBQVEsSUFBSSxDQUFDLENBQy9FLENBQUE7UUFDRCxNQUFNLGFBQWEsR0FBRyxXQUFXLENBQUMsSUFBSTthQUNuQyxNQUFNLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDLGFBQWEsQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxJQUFJLE9BQU8sQ0FBQyxLQUFLLENBQUMsUUFBUSxHQUFHLENBQUMsQ0FBQzthQUNyRixJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxhQUFhLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsR0FBRyxhQUFhLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFBO1FBQzVFLE1BQU0sWUFBWSxHQUFHLFdBQVcsQ0FBQyxJQUFJO2FBQ2xDLE1BQU0sQ0FBQyxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUMsQ0FBQyxhQUFhLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsQ0FBQzthQUN4RCxNQUFNLENBQUMsd0JBQXdCLENBQUMsQ0FBQTtRQUNuQyxNQUFNLHFCQUFxQixHQUFHLGFBQWEsQ0FBQyxNQUFNLENBQUMsWUFBWSxDQUFDLENBQUE7UUFDaEUsTUFBTSxXQUFXLEdBQUcscUJBQXFCLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxNQUFNLEVBQUUsTUFBTSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUE7UUFFNUYsTUFBTSxJQUFJLENBQUMsYUFBYSxDQUFDLE9BQU8sRUFBRSxXQUFXLENBQUMsUUFBUSxFQUFFLEtBQUssQ0FBQyxDQUFBO1FBRTlELE9BQU87WUFDTCxJQUFJLEVBQUUsV0FBVztZQUNqQixLQUFLLEVBQUUsV0FBVyxDQUFDLEtBQUs7WUFDeEIsT0FBTyxFQUFFLFdBQVcsQ0FBQyxPQUFPO1lBQzVCLE9BQU8sRUFBRSxXQUFXLENBQUMsT0FBTztZQUM1QixRQUFRLEVBQUU7Z0JBQ1IsR0FBRyxXQUFXLENBQUMsUUFBUTtnQkFDdkIsS0FBSyxFQUFFLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLE9BQU8sQ0FBQyxDQUFDO2FBQ3ZEO1NBQ0YsQ0FBQTtJQUNILENBQUM7SUFFTyxLQUFLLENBQUMsc0NBQXNDLENBQ2xELFVBQW9CLEVBQ3BCLE9BR0MsRUFDRCxNQUdDO1FBRUQsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQTtRQUNsRSxNQUFNLFdBQVcsR0FBRyxNQUFNLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxXQUFXLENBQzFEO1lBQ0UsTUFBTSxFQUFFLENBQUMsSUFBSSxFQUFFLE9BQU8sRUFBRSxRQUFRLENBQUM7WUFDakMsT0FBTyxFQUFFO2dCQUNQLEVBQUUsRUFBRSxFQUFFLFFBQVEsRUFBRSxLQUFLLENBQUMsRUFBRSxFQUFFLEtBQUssRUFBRSxVQUFVLEVBQUU7Z0JBQzdDLFNBQVMsRUFBRSxFQUFFLFFBQVEsRUFBRSxLQUFLLENBQUMsTUFBTSxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUU7Z0JBQ2xELEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDLE9BQU8sRUFBRSxPQUFPLElBQUksRUFBRSxDQUFDO2FBQ2pEO1lBQ0QsT0FBTyxFQUFFO2dCQUNQLE9BQU8sRUFBRSxDQUFDLE9BQU8sQ0FBQztnQkFDbEIsT0FBTyxFQUFFLENBQUMsT0FBTyxDQUFDO2dCQUNsQixHQUFHLENBQUMsQ0FBQyxVQUFVLElBQUksT0FBTyxDQUFDLE9BQU8sQ0FBQyxPQUFPLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsUUFBUSxFQUFFLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO2FBQ3BGO1NBQ0YsRUFDRCxPQUFPLEVBQUUsVUFBVSxJQUFJLElBQUksQ0FBQyxJQUFJLEtBQUssS0FBSyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQzFFLENBQUE7UUFDRCxNQUFNLGFBQWEsR0FBRyxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU07WUFDNUMsQ0FBQyxDQUFDLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFDaEMsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLEtBQUssS0FBSyxDQUFDLFFBQVE7Z0JBQzlCLENBQUMsQ0FBQyxRQUFRO2dCQUNWLENBQUMsQ0FBQyxNQUFNLENBQUE7UUFDVixNQUFNLFNBQVMsR0FBRyxXQUFXLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxRQUFRLEdBQUcsQ0FBQyxDQUFDLENBQUE7UUFDbEYsTUFBTSxRQUFRLEdBQUcsV0FBVyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsUUFBUSxJQUFJLENBQUMsQ0FBQyxDQUFBO1FBQ2xGLE1BQU0scUJBQXFCLEdBQUcsVUFBVSxDQUFDLE1BQU0sQ0FBQyxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQzFELFNBQVMsQ0FBQyxJQUFJLENBQ1osQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUNULE1BQU0sQ0FBQyxFQUFFLEtBQUssT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sRUFBRSxRQUFRLENBQUMsYUFBYSxDQUFDLElBQUksTUFBTSxDQUFDLE1BQU0sRUFBRSxRQUFRLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FDekcsQ0FDRixDQUFBO1FBQ0QsTUFBTSx3QkFBd0IsR0FBRyxVQUFVLENBQUMsTUFBTSxDQUFDLENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FDN0QsU0FBUyxDQUFDLElBQUksQ0FDWixDQUFDLE1BQU0sRUFBRSxFQUFFLENBQ1QsTUFBTSxDQUFDLEVBQUUsS0FBSyxPQUFPLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxFQUFFLFFBQVEsQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLEVBQUUsUUFBUSxDQUFDLFFBQVEsQ0FBQyxDQUN6RyxDQUNGLENBQUE7UUFDRCxNQUFNLGVBQWUsR0FBRyxxQkFBcUIsQ0FBQyxNQUFNLENBQUMsd0JBQXdCLENBQUMsQ0FBQTtRQUM5RSxNQUFNLGtCQUFrQixHQUFHLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEtBQUssT0FBTyxDQUFDLENBQUMsQ0FBQTtRQUMzRyxNQUFNLGdCQUFnQixHQUFHLGVBQWU7YUFDckMsTUFBTSxDQUFDLGtCQUFrQixDQUFDO2FBQzFCLEtBQUssQ0FBQyxNQUFNLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFBO1FBQ3JELE1BQU0sU0FBUyxHQUFHLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDLGdCQUFnQixDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFBO1FBQ3BGLE1BQU0sYUFBYSxHQUFHLE1BQU0sSUFBSSxDQUFDLGlCQUFpQixDQUFDLFdBQVcsQ0FBQztZQUM3RCxPQUFPLEVBQUU7Z0JBQ1AsRUFBRSxFQUFFLEVBQUUsUUFBUSxFQUFFLEtBQUssQ0FBQyxFQUFFLEVBQUUsS0FBSyxFQUFFLFNBQVMsRUFBRTthQUM3QztZQUNELE1BQU0sRUFBRSxJQUFJLENBQUMsTUFBTTtTQUNwQixDQUFDLENBQUE7UUFFRixNQUFNLElBQUksQ0FBQyxhQUFhLENBQUMsT0FBTyxFQUFFLFdBQVcsQ0FBQyxRQUFRLEVBQUUsS0FBSyxDQUFDLENBQUE7UUFFOUQsT0FBTztZQUNMLElBQUksRUFBRSxnQkFBZ0IsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FBQyxPQUFPLENBQUMsRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQztZQUMzRyxLQUFLLEVBQUUsV0FBVyxDQUFDLEtBQUs7WUFDeEIsT0FBTyxFQUFFLFdBQVcsQ0FBQyxPQUFPO1lBQzVCLE9BQU8sRUFBRSxXQUFXLENBQUMsT0FBTztZQUM1QixRQUFRLEVBQUU7Z0JBQ1IsR0FBRyxXQUFXLENBQUMsUUFBUTtnQkFDdkIsS0FBSyxFQUFFLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLE9BQU8sQ0FBQyxDQUFDO2FBQ3ZEO1NBQ0YsQ0FBQTtJQUNILENBQUM7SUFFTyxLQUFLLENBQUMsc0JBQXNCLENBQUMsSUFBWSxFQUFFLFVBQW1CLEtBQUs7UUFDekUsSUFBSSxJQUFJLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQztZQUFFLE9BQU8sSUFBSSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsQ0FBQTtRQUUvRCxPQUFPLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsR0FBRyxNQUFNLElBQUksQ0FBQyxhQUFhO2FBQ3pELE1BQU0sQ0FBZ0IsSUFBSSxFQUFFLEdBQUcsRUFBRSxJQUFJLENBQUMsSUFBSSxJQUFJLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDO2FBQ2pGLElBQUksQ0FBQyxDQUFDLFFBQVEsRUFBRSxFQUFFLENBQUMsQ0FBQyxHQUFHLElBQUksR0FBRyxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFBO0lBQzdFLENBQUM7SUFFTyxLQUFLLENBQUMsZUFBZSxDQUMzQixPQUErRCxFQUMvRCxhQUF1QixFQUFFO1FBRXpCLE9BQU8sSUFBSSxDQUFDLGlCQUFpQjthQUMxQixXQUFXLENBQ1Y7WUFDRSxNQUFNLEVBQUUsQ0FBQyxJQUFJLENBQUM7WUFDZCxPQUFPLEVBQUU7Z0JBQ1AsR0FBRyxDQUFDLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLFFBQVEsRUFBRSxLQUFLLENBQUMsRUFBRSxFQUFFLEtBQUssRUFBRSxVQUFVLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7Z0JBQ2xGLFNBQVMsRUFBRSxFQUFFLFFBQVEsRUFBRSxLQUFLLENBQUMsTUFBTSxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUU7Z0JBQ2xELEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDLE9BQU8sRUFBRSxPQUFPLElBQUksRUFBRSxDQUFDO2FBQ2pEO1lBQ0QsT0FBTyxFQUFFO2dCQUNQLFFBQVEsRUFBRSxDQUFDLE9BQU8sQ0FBQzthQUNwQjtTQUNGLEVBQ0QsT0FBTyxFQUFFLFVBQVUsSUFBSSxJQUFJLENBQUMsSUFBSSxLQUFLLEtBQUssQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUMxRTthQUNBLElBQUksQ0FBQyxDQUFDLE1BQU0sRUFBRSxFQUFFO1lBQ2YsT0FBTyxNQUFNLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQTtRQUM5QixDQUFDLENBQUMsQ0FBQTtJQUNOLENBQUM7SUFFTyxLQUFLLENBQUMsYUFBYSxDQUFDLE9BQXdDLEVBQUUsTUFBZ0I7UUFDcEYsTUFBTSxZQUFZLEdBQUcsT0FBTyxDQUFDLE9BQU8sRUFBRSxNQUFNLENBQUE7UUFFNUMsSUFBSSxPQUFPLENBQUMsTUFBTSxDQUFDO1lBQUUsT0FBTyxPQUFPLENBQUMsT0FBTyxFQUFFLE1BQU0sQ0FBQTtRQUVuRCxJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUM3QyxJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxPQUFPLENBQUMsQ0FBQyxJQUFJLE1BQU0sSUFBSSxDQUFDLE1BQU0sSUFBSSxDQUFDLGVBQWUsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFBO1FBRXBHLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLE9BQU8sQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUE7UUFFakgsT0FBTyxDQUFDLE9BQU8sR0FBRztZQUNoQixHQUFHLE9BQU8sQ0FBQyxPQUFPO1lBQ2xCLE1BQU0sRUFBRSxZQUFZO1NBQ3JCLENBQUE7SUFDSCxDQUFDOzhHQTFVVSxjQUFjLGtCQWdDZixtQkFBbUIsYUFDbkIsb0NBQW9DLGFBRXBDLG9CQUFvQixhQUNwQixrQkFBa0IsYUFDbEIsWUFBWSxhQUNaLGVBQWU7a0hBdENkLGNBQWM7OzJGQUFkLGNBQWM7a0JBRDFCLFVBQVU7OzBCQWlDTixNQUFNOzJCQUFDLG1CQUFtQjs7MEJBQzFCLE1BQU07MkJBQUMsb0NBQW9DOzswQkFFM0MsTUFBTTsyQkFBQyxvQkFBb0I7OzBCQUMzQixNQUFNOzJCQUFDLGtCQUFrQjs7MEJBQ3pCLE1BQU07MkJBQUMsWUFBWTs7MEJBQ25CLE1BQU07MkJBQUMsZUFBZSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdCwgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnXG5pbXBvcnQge1xuICBDYXRlZ29yeSxcbiAgQ2F0ZWdvcnlSZXBvc2l0b3J5LFxuICBGaW5kUmVwb3NpdG9yeVBhcmFtcyxcbiAgSW52YWxpZEFyZ3VtZW50RXJyb3IsXG4gIE5vbkZ1bmN0aW9uUHJvcGVydHlOYW1lcyxcbiAgUHJvZHVjdCxcbiAgUHJvZHVjdEdlbmRlcixcbiAgUHJvZHVjdFJlcG9zaXRvcnksXG4gIFByb2R1Y3RTZWFyY2gsXG4gIFByb2R1Y3RTZWFyY2hJbmRleCxcbiAgUHJvZHVjdFN0b2NrTm90aWZpY2F0aW9uUmVwb3NpdG9yeSxcbiAgUmVwb3NpdG9yeUNhY2hlT3B0aW9ucyxcbiAgUmVwb3NpdG9yeUZpbmRGaWVsdGVycyxcbiAgUmVwb3NpdG9yeUZpbmRSZXN1bHQsXG4gIFJlcG9zaXRvcnlPcmRlckJ5LFxuICBSb3VuZFByb2R1Y3RQcmljZXNIZWxwZXIsXG4gIFNob3BzLFxuICBXaGVyZSxcbiAgaXNFbXB0eSxcbiAgc2V0LFxufSBmcm9tICdAaW5mcmFiNGEvY29ubmVjdCdcbmltcG9ydCB7IENBVEVHT1JZX1NUUlVDVFVSRSwgREVGQVVMVF9TSE9QIH0gZnJvbSAnLi4vLi4vY29uc3RzJ1xuaW1wb3J0IHsgQ2F0ZWdvcnlTdHJ1Y3R1cmVBZGFwdGVyIH0gZnJvbSAnLi9hZGFwdGVycydcbmltcG9ydCB7IFByb2R1Y3RTb3J0IH0gZnJvbSAnLi90eXBlcy9wcm9kdWN0LXNvcnQudHlwZSdcblxudHlwZSBGZXRjaFByb2R1Y3RzRmlsdGVycyA9IHtcbiAgY2x1YkRpc2NvdW50PzogbnVtYmVyW11cbiAgYnJhbmRzPzogc3RyaW5nW11cbiAgcHJpY2VzPzogeyBtaW4/OiBudW1iZXI7IG1heD86IG51bWJlcjsgc3Vic2NyaWJlclByaWNlPzogYm9vbGVhbiB9XG4gIGdlbmRlcj86IFByb2R1Y3RHZW5kZXJbXVxuICByYXRlPzogbnVtYmVyXG4gIGN1c3RvbU9wdGlvbnM/OiBzdHJpbmdbXVxuICB0YWdzPzogc3RyaW5nW11cbn1cblxudHlwZSBGZXRjaFByb2R1Y3RzT3B0aW9ucyA9IHtcbiAgcGFnZT86IG51bWJlclxuICBwZXJQYWdlPzogbnVtYmVyXG4gIHNvcnQ/OiBQcm9kdWN0U29ydFxuICBtYWluR2VuZGVyPzogUHJvZHVjdEdlbmRlclxufVxuXG50eXBlIEZldGNoUHJvZHVjdHNNYWluUGFyYW1zPFQgZXh0ZW5kcyBDYXRlZ29yeT4gPSB7XG4gIGNhdGVnb3J5PzogVFxuICBwcm9maWxlPzogc3RyaW5nW11cbiAgdGVybT86IHN0cmluZ1xufVxuXG50eXBlIEZldGNoUHJvZHVjdHNQYXJhbXM8VCBleHRlbmRzIENhdGVnb3J5PiA9IEZldGNoUHJvZHVjdHNPcHRpb25zICZcbiAgKFxuICAgIHwge1xuICAgICAgICBjYXRlZ29yeTogRmV0Y2hQcm9kdWN0c01haW5QYXJhbXM8VD5bJ2NhdGVnb3J5J11cbiAgICAgICAgZmlsdGVycz86IEZldGNoUHJvZHVjdHNGaWx0ZXJzICYgeyBjdXN0b21PcHRpb25zPzogbmV2ZXIgfVxuICAgICAgfVxuICAgIHwge1xuICAgICAgICBwcm9maWxlOiBGZXRjaFByb2R1Y3RzTWFpblBhcmFtczxUPlsncHJvZmlsZSddXG4gICAgICAgIGZpbHRlcnM/OiBGZXRjaFByb2R1Y3RzRmlsdGVycyAmIHsgY3VzdG9tT3B0aW9ucz86IG5ldmVyOyB0YWdzPzogbmV2ZXIgfVxuICAgICAgfVxuICAgIHwge1xuICAgICAgICB0ZXJtOiBGZXRjaFByb2R1Y3RzTWFpblBhcmFtczxUPlsndGVybSddXG4gICAgICAgIGZpbHRlcnM/OiBGZXRjaFByb2R1Y3RzRmlsdGVycyAmIHsgY3VzdG9tT3B0aW9ucz86IG5ldmVyIH1cbiAgICAgIH1cbiAgKVxuXG50eXBlIEZldGNoUHJvZHVjdHNSZXNwb25zZSA9IHtcbiAgcHJvZHVjdHM6IHsgZGF0YTogUHJvZHVjdFtdOyB0b3RhbDogbnVtYmVyIH1cbiAgcGFnZXM6IG51bWJlclxuICBwcmljZXM6IHtcbiAgICBwcmljZTogeyBtaW46IG51bWJlcjsgbWF4OiBudW1iZXIgfVxuICAgIHN1YnNjcmliZXJQcmljZTogeyBtaW46IG51bWJlcjsgbWF4OiBudW1iZXIgfVxuICB9XG4gIGJyYW5kcz86IHN0cmluZ1tdXG59XG5cbkBJbmplY3RhYmxlKClcbmV4cG9ydCBjbGFzcyBDYXRhbG9nU2VydmljZTxUIGV4dGVuZHMgQ2F0ZWdvcnkgPSBDYXRlZ29yeT4ge1xuICBwcml2YXRlIHByb2R1Y3RzQnlUZXJtOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmdbXT4gPSB7fVxuICBwcml2YXRlIGJyYW5kc0xpc3Q6IFJlY29yZDxzdHJpbmcsIHN0cmluZ1tdPiA9IHt9XG4gIHByaXZhdGUgZmllbGRzOiBOb25GdW5jdGlvblByb3BlcnR5TmFtZXM8UHJvZHVjdD5bXSA9IFtcbiAgICAnaWQnLFxuICAgICduYW1lJyxcbiAgICAnc2x1ZycsXG4gICAgJ2ltYWdlcycsXG4gICAgJ21pbmlhdHVyZXMnLFxuICAgICdwcmljZScsXG4gICAgJ3N0b2NrJyxcbiAgICAncHVibGlzaGVkJyxcbiAgICAnQ0VTVCcsXG4gICAgJ0VBTicsXG4gICAgJ05DTScsXG4gICAgJ2JyYW5kJyxcbiAgICAnY29zdFByaWNlJyxcbiAgICAnaGFzVmFyaWFudHMnLFxuICAgICdpc0tpdCcsXG4gICAgJ3NrdScsXG4gICAgJ3JhdGUnLFxuICAgICd0YWdzJyxcbiAgICAndHlwZScsXG4gICAgJ3Nob3BwaW5nQ291bnQnLFxuICAgICdnZW5kZXInLFxuICAgICdjcmVhdGVkQXQnLFxuICAgICdsYWJlbCcsXG4gICAgJ291dGxldCcsXG4gICAgJ2dyb3VwJyxcbiAgXVxuXG4gIGNvbnN0cnVjdG9yKFxuICAgIEBJbmplY3QoJ1Byb2R1Y3RSZXBvc2l0b3J5JykgcHJpdmF0ZSByZWFkb25seSBwcm9kdWN0UmVwb3NpdG9yeTogUHJvZHVjdFJlcG9zaXRvcnksXG4gICAgQEluamVjdCgnUHJvZHVjdFN0b2NrTm90aWZpY2F0aW9uUmVwb3NpdG9yeScpXG4gICAgcHJpdmF0ZSByZWFkb25seSBwcm9kdWN0U3RvY2tOb3RpZmljYXRpb25SZXBvc2l0b3J5OiBQcm9kdWN0U3RvY2tOb3RpZmljYXRpb25SZXBvc2l0b3J5LFxuICAgIEBJbmplY3QoJ0NhdGVnb3J5UmVwb3NpdG9yeScpIHByaXZhdGUgcmVhZG9ubHkgY2F0ZWdvcnlSZXBvc2l0b3J5OiBDYXRlZ29yeVJlcG9zaXRvcnksXG4gICAgQEluamVjdChDQVRFR09SWV9TVFJVQ1RVUkUpIHByaXZhdGUgcmVhZG9ubHkgY2F0ZWdvcnlTdHJ1Y3R1cmVBZGFwdGVyOiBDYXRlZ29yeVN0cnVjdHVyZUFkYXB0ZXIsXG4gICAgQEluamVjdChERUZBVUxUX1NIT1ApIHByaXZhdGUgcmVhZG9ubHkgc2hvcDogU2hvcHMsXG4gICAgQEluamVjdCgnUHJvZHVjdFNlYXJjaCcpIHByaXZhdGUgcmVhZG9ubHkgcHJvZHVjdFNlYXJjaDogUHJvZHVjdFNlYXJjaEluZGV4LFxuICApIHt9XG5cbiAgYXN5bmMgZmV0Y2hQcm9kdWN0cyhcbiAgICBvcHRpb25zOiBGZXRjaFByb2R1Y3RzUGFyYW1zPFQ+LFxuICAgIG9wdGlvbnNDYWNoZT86IHsgY2FjaGU/OiBSZXBvc2l0b3J5Q2FjaGVPcHRpb25zIH0sXG4gICk6IFByb21pc2U8RmV0Y2hQcm9kdWN0c1Jlc3BvbnNlPiB7XG4gICAgY29uc3QgbGltaXRzID0gdGhpcy5idWlsZExpbWl0UXVlcnkob3B0aW9ucylcblxuICAgIGlmICh0aGlzLmhhc1Byb2ZpbGUob3B0aW9ucykgJiYgb3B0aW9ucy5maWx0ZXJzPy5jdXN0b21PcHRpb25zKVxuICAgICAgdGhyb3cgbmV3IEludmFsaWRBcmd1bWVudEVycm9yKGBJdCBjb3VsZG4ndCBmaWxsZWQgY3VzdG9tT3B0aW9ucyB3aGVuIHByb2ZpbGUgaXMgZ2l2ZW5gKVxuICAgIGlmICh0aGlzLmhhc1Byb2ZpbGUob3B0aW9ucykgJiYgb3B0aW9ucy5maWx0ZXJzPy50YWdzKVxuICAgICAgdGhyb3cgbmV3IEludmFsaWRBcmd1bWVudEVycm9yKGBJdCBjb3VsZG4ndCBmaWxsZWQgdGFncyB3aGVuIHByb2ZpbGUgaXMgZ2l2ZW5gKVxuICAgIGlmICh0aGlzLmhhc1Rlcm0ob3B0aW9ucykgJiYgb3B0aW9ucy5maWx0ZXJzPy5jdXN0b21PcHRpb25zKVxuICAgICAgdGhyb3cgbmV3IEludmFsaWRBcmd1bWVudEVycm9yKGBJdCBjb3VsZG4ndCBmaWxsZWQgY3VzdG9tT3B0aW9ucyB3aGVuIHRlcm0gaXMgZ2l2ZW5gKVxuXG4gICAgcmV0dXJuIGF3YWl0IHRoaXMuZmluZENhdGFsb2cob3B0aW9ucywgbGltaXRzLCBvcHRpb25zQ2FjaGUpLnRoZW4oXG4gICAgICBhc3luYyAoeyBkYXRhLCBjb3VudDogdG90YWwsIG1heGltdW0sIG1pbmltYWwsIGRpc3RpbmN0IH0pID0+IHtcbiAgICAgICAgYXdhaXQgdGhpcy5zZXRCcmFuZHNMaXN0KG9wdGlvbnMsIGRpc3RpbmN0Py5icmFuZClcblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIHByb2R1Y3RzOiB7IGRhdGE6IGRhdGEubWFwKChwcm9kdWN0KSA9PiBSb3VuZFByb2R1Y3RQcmljZXNIZWxwZXIucm91bmRQcm9kdWN0UHJpY2VzKHByb2R1Y3QpKSwgdG90YWwgfSxcbiAgICAgICAgICBwYWdlczogTWF0aC5jZWlsKHRvdGFsIC8gbGltaXRzLmxpbWl0KSxcbiAgICAgICAgICBwcmljZXM6IHtcbiAgICAgICAgICAgIHByaWNlOiB7IG1pbjogK21pbmltYWw/LnByaWNlPy5wcmljZT8udG9GaXhlZCgyKSwgbWF4OiArbWF4aW11bT8ucHJpY2U/LnByaWNlPy50b0ZpeGVkKDIpIH0sXG4gICAgICAgICAgICBzdWJzY3JpYmVyUHJpY2U6IHtcbiAgICAgICAgICAgICAgbWluOiArbWluaW1hbD8ucHJpY2U/LnN1YnNjcmliZXJQcmljZT8udG9GaXhlZCgyKSxcbiAgICAgICAgICAgICAgbWF4OiArbWF4aW11bT8ucHJpY2U/LnN1YnNjcmliZXJQcmljZT8udG9GaXhlZCgyKSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgICBicmFuZHM6IHRoaXMuYnJhbmRzTGlzdFt0aGlzLmJ1aWxkSW5kZXhCcmFuZHMob3B0aW9ucyldLFxuICAgICAgICB9XG4gICAgICB9LFxuICAgIClcbiAgfVxuXG4gIGFzeW5jIGFkZEN1c3RvbWVyVG9TdG9ja05vdGlmaWNhdGlvbihzaG9wOiBTaG9wcywgcHJvZHVjdElkOiBzdHJpbmcsIG5hbWU6IHN0cmluZywgZW1haWw6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIHJldHVybiB0aGlzLnByb2R1Y3RTdG9ja05vdGlmaWNhdGlvblJlcG9zaXRvcnkuYWRkQ3VzdG9tZXJFbWFpbChzaG9wLCBwcm9kdWN0SWQsIG5hbWUsIGVtYWlsKVxuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBmaW5kQ2F0YWxvZyhcbiAgICBvcHRpb25zOiBGZXRjaFByb2R1Y3RzUGFyYW1zPFQ+LFxuICAgIGxpbWl0czoge1xuICAgICAgbGltaXQ/OiBudW1iZXJcbiAgICAgIG9mZnNldD86IG51bWJlclxuICAgIH0sXG4gICAgb3B0aW9uc0NhY2hlPzogeyBjYWNoZT86IFJlcG9zaXRvcnlDYWNoZU9wdGlvbnMgfSxcbiAgKTogUHJvbWlzZTxSZXBvc2l0b3J5RmluZFJlc3VsdDxQcm9kdWN0Pj4ge1xuICAgIGlmICh0aGlzLmhhc1Rlcm0ob3B0aW9ucykgJiYgb3B0aW9ucy5zb3J0ID09PSAnbW9zdC1yZWxldmFudCcpIHtcbiAgICAgIGNvbnN0IHByb2R1Y3RzSWRzID0gYXdhaXQgdGhpcy5maW5kQ2F0YWxvZ0lkc0J5U2VhcmNoKG9wdGlvbnMudGVybSlcblxuICAgICAgcmV0dXJuIHRoaXMuZmluZENhdGFsb2dBbmRTb3J0QnlNb3N0UmV2ZWxhbnRCeVRlcm0ocHJvZHVjdHNJZHMsIG9wdGlvbnMsIGxpbWl0cylcbiAgICB9XG5cbiAgICBpZiAodGhpcy5oYXNDYXRlZ29yeShvcHRpb25zKSAmJiBvcHRpb25zLnNvcnQgPT09ICdtb3N0LXJlbGV2YW50Jykge1xuICAgICAgY29uc3QgbW9zdFJlbGV2YW50ID0gb3B0aW9ucy5jYXRlZ29yeS5pc1dpc2hsaXN0ID8gW10gOiBvcHRpb25zLmNhdGVnb3J5LmdldE1vc3RSZWxldmFudEJ5U2hvcCh0aGlzLnNob3ApXG4gICAgICBjb25zdCBwcm9kdWN0c0lkcyA9IGF3YWl0IHRoaXMucHJvZHVjdFJlcG9zaXRvcnlcbiAgICAgICAgLmZpbmRDYXRhbG9nKFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIGZpZWxkczogWydpZCddLFxuICAgICAgICAgICAgZmlsdGVyczoge1xuICAgICAgICAgICAgICAuLi4oYXdhaXQgdGhpcy5idWlsZE1haW5GaWx0ZXIob3B0aW9ucykpLFxuICAgICAgICAgICAgICAuLi50aGlzLmJ1aWxkRmlsdGVyUXVlcnkob3B0aW9ucz8uZmlsdGVycyB8fCB7fSksXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgICAgdW5kZWZpbmVkLFxuICAgICAgICAgIG9wdGlvbnNDYWNoZSxcbiAgICAgICAgKVxuICAgICAgICAudGhlbigocHJvZHVjdHMpID0+IHByb2R1Y3RzLmRhdGEubWFwKChwcm9kdWN0KSA9PiBwcm9kdWN0LmlkKSlcblxuICAgICAgcmV0dXJuIHRoaXMuZmluZENhdGFsb2dBbmRTb3J0QnlNb3N0UmV2ZWxhbnQobW9zdFJlbGV2YW50LCBwcm9kdWN0c0lkcywgb3B0aW9ucywgbGltaXRzLCBvcHRpb25zQ2FjaGUpXG4gICAgfVxuXG4gICAgY29uc3QgcmVwb1BhcmFtczogRmluZFJlcG9zaXRvcnlQYXJhbXM8UHJvZHVjdD4gPSB7XG4gICAgICBmaWVsZHM6IHRoaXMuZmllbGRzLFxuICAgICAgZmlsdGVyczoge1xuICAgICAgICAuLi4oYXdhaXQgdGhpcy5idWlsZE1haW5GaWx0ZXIob3B0aW9ucykpLFxuICAgICAgICAuLi50aGlzLmJ1aWxkRmlsdGVyUXVlcnkob3B0aW9ucz8uZmlsdGVycyB8fCB7fSksXG4gICAgICB9LFxuICAgICAgLi4uKG9wdGlvbnM/LnNvcnQgPyB7IG9yZGVyQnk6IHRoaXMuYnVpbGRTb3J0UXVlcnkob3B0aW9ucz8uc29ydCkgfSA6IHt9KSxcbiAgICAgIGxpbWl0cyxcbiAgICAgIG9wdGlvbnM6IHtcbiAgICAgICAgbWluaW1hbDogWydwcmljZSddLFxuICAgICAgICBtYXhpbXVtOiBbJ3ByaWNlJ10sXG4gICAgICAgIC4uLighdGhpcy5icmFuZHNMaXN0W3RoaXMuYnVpbGRJbmRleEJyYW5kcyhvcHRpb25zKV0gJiYgaXNFbXB0eShvcHRpb25zLmZpbHRlcnM/LmJyYW5kcylcbiAgICAgICAgICA/IHsgZGlzdGluY3Q6IFsnYnJhbmQnXSB9XG4gICAgICAgICAgOiB7fSksXG4gICAgICB9LFxuICAgIH1cblxuICAgIGlmIChbJ2JpZ2dlc3QtcHJpY2UnLCAnbG93ZXN0LXByaWNlJywgJ2JpZ2dlc3QtZGlzY291bnQnLCAnYmVzdC1yYXRpbmcnXS5pbmNsdWRlcyhvcHRpb25zLnNvcnQpKVxuICAgICAgcmV0dXJuIHRoaXMucHJvZHVjdFJlcG9zaXRvcnkuZmluZENhdGFsb2cocmVwb1BhcmFtcywgdW5kZWZpbmVkLCBvcHRpb25zQ2FjaGUpXG5cbiAgICByZXR1cm4gdGhpcy5wcm9kdWN0UmVwb3NpdG9yeS5maW5kQ2F0YWxvZyhcbiAgICAgIHJlcG9QYXJhbXMsXG4gICAgICBvcHRpb25zPy5tYWluR2VuZGVyIHx8IHRoaXMuc2hvcCA9PT0gU2hvcHMuTUVOU01BUktFVCA/ICdtYWxlJyA6ICdmZW1hbGUnLFxuICAgICAgb3B0aW9uc0NhY2hlLFxuICAgIClcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgYnVpbGRNYWluRmlsdGVyKHtcbiAgICBjYXRlZ29yeSxcbiAgICBwcm9maWxlLFxuICAgIHRlcm0sXG4gIH06IEZldGNoUHJvZHVjdHNNYWluUGFyYW1zPFQ+KTogUHJvbWlzZTxSZXBvc2l0b3J5RmluZEZpZWx0ZXJzPFByb2R1Y3Q+PiB7XG4gICAgaWYgKGNhdGVnb3J5KSByZXR1cm4gdGhpcy5jYXRlZ29yeVN0cnVjdHVyZUFkYXB0ZXIuYnVpbGRQcm9kdWN0RmlsdGVyQnlDYXRlZ29yeShjYXRlZ29yeSlcbiAgICBpZiAocHJvZmlsZSkgcmV0dXJuIHsgdGFnczogeyBvcGVyYXRvcjogV2hlcmUuTElLRSwgdmFsdWU6IHByb2ZpbGUgfSB9XG4gICAgaWYgKHRlcm0pXG4gICAgICByZXR1cm4gdGhpcy5wcm9kdWN0U2VhcmNoXG4gICAgICAgIC5zZWFyY2g8UHJvZHVjdD4odGVybSwgOTk5LCB0aGlzLnNob3AgPT0gU2hvcHMuR0xBTVNIT1AgPyAnZmVtYWxlJyA6ICdtYWxlJylcbiAgICAgICAgLnRoZW4oKGRhdGEpID0+ICh7IGlkOiB7IG9wZXJhdG9yOiBXaGVyZS5JTiwgdmFsdWU6IGRhdGEubWFwKChfc291cmNlKSA9PiBfc291cmNlLmlkKSB9IH0pKVxuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBmaW5kQ2F0YWxvZ0FuZFNvcnRCeU1vc3RSZXZlbGFudChcbiAgICBtb3N0UmVsZXZhbnRzOiBzdHJpbmdbXSxcbiAgICBwcm9kdWN0SWRzOiBzdHJpbmdbXSxcbiAgICBvcHRpb25zOiBPbWl0PEZldGNoUHJvZHVjdHNPcHRpb25zLCAnc29ydCc+ICYge1xuICAgICAgY2F0ZWdvcnk/OiBGZXRjaFByb2R1Y3RzTWFpblBhcmFtczxUPlsnY2F0ZWdvcnknXVxuICAgICAgZmlsdGVycz86IEZldGNoUHJvZHVjdHNGaWx0ZXJzICYgeyBjdXN0b21PcHRpb25zPzogbmV2ZXIgfVxuICAgIH0sXG4gICAgbGltaXRzOiB7XG4gICAgICBsaW1pdD86IG51bWJlclxuICAgICAgb2Zmc2V0PzogbnVtYmVyXG4gICAgfSxcbiAgICBvcHRpb25zQ2FjaGU/OiB7IGNhY2hlPzogUmVwb3NpdG9yeUNhY2hlT3B0aW9ucyB9LFxuICApOiBQcm9taXNlPFJlcG9zaXRvcnlGaW5kUmVzdWx0PFByb2R1Y3Q+PiB7XG4gICAgY29uc3QgYnJhbmRzTGlzdCA9IHRoaXMuYnJhbmRzTGlzdFt0aGlzLmJ1aWxkSW5kZXhCcmFuZHMob3B0aW9ucyldXG4gICAgY29uc3QgbW9zdFJlbGV2YW50UHJvZHVjdHNJZHMgPSBbLi4ubmV3IFNldChtb3N0UmVsZXZhbnRzLmNvbmNhdChwcm9kdWN0SWRzKSldXG4gICAgY29uc3QgdG90YWxSZXN1bHQgPSBhd2FpdCB0aGlzLnByb2R1Y3RSZXBvc2l0b3J5LmZpbmRDYXRhbG9nKFxuICAgICAge1xuICAgICAgICBmaWVsZHM6IHRoaXMuZmllbGRzLFxuICAgICAgICBmaWx0ZXJzOiB7XG4gICAgICAgICAgaWQ6IHsgb3BlcmF0b3I6IFdoZXJlLklOLCB2YWx1ZTogbW9zdFJlbGV2YW50UHJvZHVjdHNJZHMgfSxcbiAgICAgICAgICAuLi50aGlzLmJ1aWxkRmlsdGVyUXVlcnkob3B0aW9ucz8uZmlsdGVycyB8fCB7fSksXG4gICAgICAgIH0sXG4gICAgICAgIG9yZGVyQnk6IHRoaXMuYnVpbGRTb3J0UXVlcnkoJ2Jlc3Qtc2VsbGVycycpLFxuICAgICAgICBvcHRpb25zOiB7XG4gICAgICAgICAgbWluaW1hbDogWydwcmljZSddLFxuICAgICAgICAgIG1heGltdW06IFsncHJpY2UnXSxcbiAgICAgICAgICAuLi4oIWJyYW5kc0xpc3QgJiYgaXNFbXB0eShvcHRpb25zLmZpbHRlcnM/LmJyYW5kcykgPyB7IGRpc3RpbmN0OiBbJ2JyYW5kJ10gfSA6IHt9KSxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgICBvcHRpb25zPy5tYWluR2VuZGVyIHx8IHRoaXMuc2hvcCA9PT0gU2hvcHMuTUVOU01BUktFVCA/ICdtYWxlJyA6ICdmZW1hbGUnLFxuICAgICAgb3B0aW9uc0NhY2hlLFxuICAgIClcblxuICAgIGNvbnN0IG1vc3RSZWxldmFudFdpdGhvdXlTdG9jayA9IHRvdGFsUmVzdWx0LmRhdGEuZmlsdGVyKFxuICAgICAgKHByb2R1Y3QpID0+IG1vc3RSZWxldmFudHMuaW5jbHVkZXMocHJvZHVjdC5pZCkgJiYgcHJvZHVjdC5zdG9jay5xdWFudGl0eSA8PSAwLFxuICAgIClcbiAgICBjb25zdCBmaXJzdFByb2R1Y3RzID0gdG90YWxSZXN1bHQuZGF0YVxuICAgICAgLmZpbHRlcigocHJvZHVjdCkgPT4gbW9zdFJlbGV2YW50cy5pbmNsdWRlcyhwcm9kdWN0LmlkKSAmJiBwcm9kdWN0LnN0b2NrLnF1YW50aXR5ID4gMClcbiAgICAgIC5zb3J0KChhLCBiKSA9PiBtb3N0UmVsZXZhbnRzLmluZGV4T2YoYS5pZCkgLSBtb3N0UmVsZXZhbnRzLmluZGV4T2YoYi5pZCkpXG4gICAgY29uc3QgbGFzdFByb2R1Y3RzID0gdG90YWxSZXN1bHQuZGF0YVxuICAgICAgLmZpbHRlcigocHJvZHVjdCkgPT4gIW1vc3RSZWxldmFudHMuaW5jbHVkZXMocHJvZHVjdC5pZCkpXG4gICAgICAuY29uY2F0KG1vc3RSZWxldmFudFdpdGhvdXlTdG9jaylcbiAgICBjb25zdCBjYXRlZ29yeU1vc3RSZWxldmFudHMgPSBmaXJzdFByb2R1Y3RzLmNvbmNhdChsYXN0UHJvZHVjdHMpXG4gICAgY29uc3QgcmVzdWx0RmluYWwgPSBjYXRlZ29yeU1vc3RSZWxldmFudHMuc2xpY2UobGltaXRzLm9mZnNldCwgbGltaXRzLm9mZnNldCArIGxpbWl0cy5saW1pdClcblxuICAgIGF3YWl0IHRoaXMuc2V0QnJhbmRzTGlzdChvcHRpb25zLCB0b3RhbFJlc3VsdC5kaXN0aW5jdD8uYnJhbmQpXG5cbiAgICByZXR1cm4ge1xuICAgICAgZGF0YTogcmVzdWx0RmluYWwsXG4gICAgICBjb3VudDogdG90YWxSZXN1bHQuY291bnQsXG4gICAgICBtYXhpbXVtOiB0b3RhbFJlc3VsdC5tYXhpbXVtLFxuICAgICAgbWluaW1hbDogdG90YWxSZXN1bHQubWluaW1hbCxcbiAgICAgIGRpc3RpbmN0OiB7XG4gICAgICAgIC4uLnRvdGFsUmVzdWx0LmRpc3RpbmN0LFxuICAgICAgICBicmFuZDogdGhpcy5icmFuZHNMaXN0W3RoaXMuYnVpbGRJbmRleEJyYW5kcyhvcHRpb25zKV0sXG4gICAgICB9LFxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgZmluZENhdGFsb2dBbmRTb3J0QnlNb3N0UmV2ZWxhbnRCeVRlcm0oXG4gICAgcHJvZHVjdElkczogc3RyaW5nW10sXG4gICAgb3B0aW9uczogT21pdDxGZXRjaFByb2R1Y3RzT3B0aW9ucywgJ3NvcnQnPiAmIHtcbiAgICAgIHRlcm0/OiBGZXRjaFByb2R1Y3RzTWFpblBhcmFtczxUPlsndGVybSddXG4gICAgICBmaWx0ZXJzPzogRmV0Y2hQcm9kdWN0c0ZpbHRlcnMgJiB7IGN1c3RvbU9wdGlvbnM/OiBuZXZlciB9XG4gICAgfSxcbiAgICBsaW1pdHM6IHtcbiAgICAgIGxpbWl0PzogbnVtYmVyXG4gICAgICBvZmZzZXQ/OiBudW1iZXJcbiAgICB9LFxuICApOiBQcm9taXNlPFJlcG9zaXRvcnlGaW5kUmVzdWx0PFByb2R1Y3Q+PiB7XG4gICAgY29uc3QgYnJhbmRzTGlzdCA9IHRoaXMuYnJhbmRzTGlzdFt0aGlzLmJ1aWxkSW5kZXhCcmFuZHMob3B0aW9ucyldXG4gICAgY29uc3QgdG90YWxSZXN1bHQgPSBhd2FpdCB0aGlzLnByb2R1Y3RSZXBvc2l0b3J5LmZpbmRDYXRhbG9nKFxuICAgICAge1xuICAgICAgICBmaWVsZHM6IFsnaWQnLCAnc3RvY2snLCAnZ2VuZGVyJ10sXG4gICAgICAgIGZpbHRlcnM6IHtcbiAgICAgICAgICBpZDogeyBvcGVyYXRvcjogV2hlcmUuSU4sIHZhbHVlOiBwcm9kdWN0SWRzIH0sXG4gICAgICAgICAgcHVibGlzaGVkOiB7IG9wZXJhdG9yOiBXaGVyZS5FUVVBTFMsIHZhbHVlOiB0cnVlIH0sXG4gICAgICAgICAgLi4udGhpcy5idWlsZEZpbHRlclF1ZXJ5KG9wdGlvbnM/LmZpbHRlcnMgfHwge30pLFxuICAgICAgICB9LFxuICAgICAgICBvcHRpb25zOiB7XG4gICAgICAgICAgbWluaW1hbDogWydwcmljZSddLFxuICAgICAgICAgIG1heGltdW06IFsncHJpY2UnXSxcbiAgICAgICAgICAuLi4oIWJyYW5kc0xpc3QgJiYgaXNFbXB0eShvcHRpb25zLmZpbHRlcnM/LmJyYW5kcykgPyB7IGRpc3RpbmN0OiBbJ2JyYW5kJ10gfSA6IHt9KSxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgICBvcHRpb25zPy5tYWluR2VuZGVyIHx8IHRoaXMuc2hvcCA9PT0gU2hvcHMuTUVOU01BUktFVCA/ICdtYWxlJyA6ICdmZW1hbGUnLFxuICAgIClcbiAgICBjb25zdCBkZWZhdWx0R2VuZGVyID0gb3B0aW9ucz8uZmlsdGVycz8uZ2VuZGVyXG4gICAgICA/IG9wdGlvbnM/LmZpbHRlcnM/LmdlbmRlci5hdCgwKVxuICAgICAgOiB0aGlzLnNob3AgPT09IFNob3BzLkdMQU1TSE9QXG4gICAgICA/ICdmZW1hbGUnXG4gICAgICA6ICdtYWxlJ1xuICAgIGNvbnN0IHN0b2NrRGF0YSA9IHRvdGFsUmVzdWx0LmRhdGEuZmlsdGVyKChwcm9kdWN0KSA9PiBwcm9kdWN0LnN0b2NrLnF1YW50aXR5ID4gMClcbiAgICBjb25zdCBzdG9ja091dCA9IHRvdGFsUmVzdWx0LmRhdGEuZmlsdGVyKChwcm9kdWN0KSA9PiBwcm9kdWN0LnN0b2NrLnF1YW50aXR5IDw9IDApXG4gICAgY29uc3QgcHJvZHVjdElkc1N0b2NrR2VuZGVyID0gcHJvZHVjdElkcy5maWx0ZXIoKHByb2R1Y3QpID0+XG4gICAgICBzdG9ja0RhdGEuc29tZShcbiAgICAgICAgKHJlc3VsdCkgPT5cbiAgICAgICAgICByZXN1bHQuaWQgPT09IHByb2R1Y3QgJiYgKHJlc3VsdC5nZW5kZXI/LmluY2x1ZGVzKGRlZmF1bHRHZW5kZXIpIHx8IHJlc3VsdC5nZW5kZXI/LmluY2x1ZGVzKCd1bmlzZXgnKSksXG4gICAgICApLFxuICAgIClcbiAgICBjb25zdCBwcm9kdWN0SWRzU3RvY2tOb3RHZW5kZXIgPSBwcm9kdWN0SWRzLmZpbHRlcigocHJvZHVjdCkgPT5cbiAgICAgIHN0b2NrRGF0YS5zb21lKFxuICAgICAgICAocmVzdWx0KSA9PlxuICAgICAgICAgIHJlc3VsdC5pZCA9PT0gcHJvZHVjdCAmJiAhcmVzdWx0LmdlbmRlcj8uaW5jbHVkZXMoZGVmYXVsdEdlbmRlcikgJiYgIXJlc3VsdC5nZW5kZXI/LmluY2x1ZGVzKCd1bmlzZXgnKSxcbiAgICAgICksXG4gICAgKVxuICAgIGNvbnN0IHByb2R1Y3RJZHNTdG9jayA9IHByb2R1Y3RJZHNTdG9ja0dlbmRlci5jb25jYXQocHJvZHVjdElkc1N0b2NrTm90R2VuZGVyKVxuICAgIGNvbnN0IHByb2R1Y3RJZHNTdG9ja091dCA9IHByb2R1Y3RJZHMuZmlsdGVyKChwcm9kdWN0KSA9PiBzdG9ja091dC5zb21lKChyZXN1bHQpID0+IHJlc3VsdC5pZCA9PT0gcHJvZHVjdCkpXG4gICAgY29uc3QgbGltaXRlZFByb2R1Y3RJZCA9IHByb2R1Y3RJZHNTdG9ja1xuICAgICAgLmNvbmNhdChwcm9kdWN0SWRzU3RvY2tPdXQpXG4gICAgICAuc2xpY2UobGltaXRzLm9mZnNldCwgbGltaXRzLm9mZnNldCArIGxpbWl0cy5saW1pdClcbiAgICBjb25zdCBvcmRlcmVkSWQgPSBwcm9kdWN0SWRzLmZpbHRlcigocHJvZHVjdCkgPT4gbGltaXRlZFByb2R1Y3RJZC5pbmNsdWRlcyhwcm9kdWN0KSlcbiAgICBjb25zdCBwcm9kdWN0UmVzdWx0ID0gYXdhaXQgdGhpcy5wcm9kdWN0UmVwb3NpdG9yeS5maW5kQ2F0YWxvZyh7XG4gICAgICBmaWx0ZXJzOiB7XG4gICAgICAgIGlkOiB7IG9wZXJhdG9yOiBXaGVyZS5JTiwgdmFsdWU6IG9yZGVyZWRJZCB9LFxuICAgICAgfSxcbiAgICAgIGZpZWxkczogdGhpcy5maWVsZHMsXG4gICAgfSlcblxuICAgIGF3YWl0IHRoaXMuc2V0QnJhbmRzTGlzdChvcHRpb25zLCB0b3RhbFJlc3VsdC5kaXN0aW5jdD8uYnJhbmQpXG5cbiAgICByZXR1cm4ge1xuICAgICAgZGF0YTogbGltaXRlZFByb2R1Y3RJZC5tYXAoKGlkKSA9PiBwcm9kdWN0UmVzdWx0LmRhdGEuZmluZCgocHJvZHVjdCkgPT4gcHJvZHVjdC5pZCA9PT0gaWQpKS5maWx0ZXIoQm9vbGVhbiksXG4gICAgICBjb3VudDogdG90YWxSZXN1bHQuY291bnQsXG4gICAgICBtYXhpbXVtOiB0b3RhbFJlc3VsdC5tYXhpbXVtLFxuICAgICAgbWluaW1hbDogdG90YWxSZXN1bHQubWluaW1hbCxcbiAgICAgIGRpc3RpbmN0OiB7XG4gICAgICAgIC4uLnRvdGFsUmVzdWx0LmRpc3RpbmN0LFxuICAgICAgICBicmFuZDogdGhpcy5icmFuZHNMaXN0W3RoaXMuYnVpbGRJbmRleEJyYW5kcyhvcHRpb25zKV0sXG4gICAgICB9LFxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgZmluZENhdGFsb2dJZHNCeVNlYXJjaCh0ZXJtOiBzdHJpbmcsIHByZXZpZXc6IGJvb2xlYW4gPSBmYWxzZSk6IFByb21pc2U8c3RyaW5nW10+IHtcbiAgICBpZiAodGhpcy5wcm9kdWN0c0J5VGVybVt0ZXJtXSkgcmV0dXJuIHRoaXMucHJvZHVjdHNCeVRlcm1bdGVybV1cblxuICAgIHJldHVybiAodGhpcy5wcm9kdWN0c0J5VGVybVt0ZXJtXSA9IGF3YWl0IHRoaXMucHJvZHVjdFNlYXJjaFxuICAgICAgLnNlYXJjaDxQcm9kdWN0U2VhcmNoPih0ZXJtLCA5OTksIHRoaXMuc2hvcCA9PSBTaG9wcy5HTEFNU0hPUCA/ICdmZW1hbGUnIDogJ21hbGUnKVxuICAgICAgLnRoZW4oKHByb2R1Y3RzKSA9PiBbLi4ubmV3IFNldChwcm9kdWN0cy5tYXAoKHByb2R1Y3QpID0+IHByb2R1Y3QuaWQpKV0pKVxuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBmZXRjaEJyYW5kc09ubHkoXG4gICAgb3B0aW9uczogUGljazxGZXRjaFByb2R1Y3RzUGFyYW1zPFQ+LCAnZmlsdGVycycgfCAnbWFpbkdlbmRlcic+LFxuICAgIHByb2R1Y3RJZHM6IHN0cmluZ1tdID0gW10sXG4gICk6IFByb21pc2U8c3RyaW5nW10+IHtcbiAgICByZXR1cm4gdGhpcy5wcm9kdWN0UmVwb3NpdG9yeVxuICAgICAgLmZpbmRDYXRhbG9nKFxuICAgICAgICB7XG4gICAgICAgICAgZmllbGRzOiBbJ2lkJ10sXG4gICAgICAgICAgZmlsdGVyczoge1xuICAgICAgICAgICAgLi4uKCFpc0VtcHR5KHByb2R1Y3RJZHMpID8geyBpZDogeyBvcGVyYXRvcjogV2hlcmUuSU4sIHZhbHVlOiBwcm9kdWN0SWRzIH0gfSA6IHt9KSxcbiAgICAgICAgICAgIHB1Ymxpc2hlZDogeyBvcGVyYXRvcjogV2hlcmUuRVFVQUxTLCB2YWx1ZTogdHJ1ZSB9LFxuICAgICAgICAgICAgLi4udGhpcy5idWlsZEZpbHRlclF1ZXJ5KG9wdGlvbnM/LmZpbHRlcnMgfHwge30pLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgb3B0aW9uczoge1xuICAgICAgICAgICAgZGlzdGluY3Q6IFsnYnJhbmQnXSxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgICBvcHRpb25zPy5tYWluR2VuZGVyIHx8IHRoaXMuc2hvcCA9PT0gU2hvcHMuTUVOU01BUktFVCA/ICdtYWxlJyA6ICdmZW1hbGUnLFxuICAgICAgKVxuICAgICAgLnRoZW4oKHJlc3VsdCkgPT4ge1xuICAgICAgICByZXR1cm4gcmVzdWx0LmRpc3RpbmN0LmJyYW5kXG4gICAgICB9KVxuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBzZXRCcmFuZHNMaXN0KG9wdGlvbnM6IFBhcnRpYWw8RmV0Y2hQcm9kdWN0c1BhcmFtczxUPj4sIGJyYW5kczogc3RyaW5nW10pIHtcbiAgICBjb25zdCBmaWx0ZXJCcmFuZHMgPSBvcHRpb25zLmZpbHRlcnM/LmJyYW5kc1xuXG4gICAgaWYgKGlzRW1wdHkoYnJhbmRzKSkgZGVsZXRlIG9wdGlvbnMuZmlsdGVycz8uYnJhbmRzXG5cbiAgICB0aGlzLmJyYW5kc0xpc3RbdGhpcy5idWlsZEluZGV4QnJhbmRzKG9wdGlvbnMpXSA9XG4gICAgICB0aGlzLmJyYW5kc0xpc3RbdGhpcy5idWlsZEluZGV4QnJhbmRzKG9wdGlvbnMpXSB8fCBicmFuZHMgfHwgKGF3YWl0IHRoaXMuZmV0Y2hCcmFuZHNPbmx5KG9wdGlvbnMpKVxuXG4gICAgdGhpcy5icmFuZHNMaXN0W3RoaXMuYnVpbGRJbmRleEJyYW5kcyhvcHRpb25zKV0gPSB0aGlzLmJyYW5kc0xpc3RbdGhpcy5idWlsZEluZGV4QnJhbmRzKG9wdGlvbnMpXS5maWx0ZXIoQm9vbGVhbilcblxuICAgIG9wdGlvbnMuZmlsdGVycyA9IHtcbiAgICAgIC4uLm9wdGlvbnMuZmlsdGVycyxcbiAgICAgIGJyYW5kczogZmlsdGVyQnJhbmRzLFxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgYnVpbGRGaWx0ZXJRdWVyeSA9ICh7XG4gICAgY2x1YkRpc2NvdW50LFxuICAgIGJyYW5kcyxcbiAgICBwcmljZXMsXG4gICAgZ2VuZGVyLFxuICAgIHRhZ3MsXG4gICAgcmF0ZSxcbiAgICBjdXN0b21PcHRpb25zLFxuICB9OiBGZXRjaFByb2R1Y3RzRmlsdGVycyk6IFJlcG9zaXRvcnlGaW5kRmllbHRlcnM8UHJvZHVjdD4gPT4ge1xuICAgIGNvbnN0IGZpbHRlcnMgPSB7fSBhcyBSZXBvc2l0b3J5RmluZEZpZWx0ZXJzPFByb2R1Y3Q+XG5cbiAgICBpZiAoY2x1YkRpc2NvdW50Py5sZW5ndGgpXG4gICAgICBzZXQoZmlsdGVycywgJ3ByaWNlLnN1YnNjcmliZXJEaXNjb3VudFBlcmNlbnRhZ2UnLCB7IG9wZXJhdG9yOiBXaGVyZS5JTiwgdmFsdWU6IGNsdWJEaXNjb3VudCB9KVxuICAgIGlmIChicmFuZHM/Lmxlbmd0aCkgZmlsdGVycy5icmFuZCA9IHsgb3BlcmF0b3I6IFdoZXJlLklOLCB2YWx1ZTogYnJhbmRzIH1cbiAgICBpZiAoZ2VuZGVyPy5sZW5ndGgpIGZpbHRlcnMuZ2VuZGVyID0geyBvcGVyYXRvcjogV2hlcmUuSU4sIHZhbHVlOiBnZW5kZXIgfVxuICAgIGlmIChwcmljZXM/Lm1pbiB8fCBwcmljZXM/Lm1heClcbiAgICAgIHNldChmaWx0ZXJzLCBwcmljZXMuc3Vic2NyaWJlclByaWNlID8gJ3ByaWNlLnN1YnNjcmliZXJQcmljZScgOiAncHJpY2UucHJpY2UnLCBbXG4gICAgICAgIC4uLihwcmljZXMubWluID8gW3sgb3BlcmF0b3I6IFdoZXJlLkdURSwgdmFsdWU6IE1hdGguZmxvb3IocHJpY2VzLm1pbikgfV0gOiBbXSksXG4gICAgICAgIC4uLihwcmljZXMubWF4ID8gW3sgb3BlcmF0b3I6IFdoZXJlLkxURSwgdmFsdWU6IE1hdGguY2VpbChwcmljZXMubWF4KSB9XSA6IFtdKSxcbiAgICAgIF0pXG4gICAgaWYgKHJhdGUpIGZpbHRlcnMucmF0ZSA9IHsgb3BlcmF0b3I6IFdoZXJlLkdURSwgdmFsdWU6IHJhdGUgfVxuICAgIGlmICh0YWdzPy5sZW5ndGgpIGZpbHRlcnMudGFncyA9IHsgb3BlcmF0b3I6IFdoZXJlLkxJS0UsIHZhbHVlOiB0YWdzIH1cbiAgICBpZiAoY3VzdG9tT3B0aW9ucz8ubGVuZ3RoKSBmaWx0ZXJzLmZpbHRlcnMgPSB7IG9wZXJhdG9yOiBXaGVyZS5MSUtFLCB2YWx1ZTogY3VzdG9tT3B0aW9ucyB9XG5cbiAgICByZXR1cm4gZmlsdGVyc1xuICB9XG5cbiAgcHJpdmF0ZSBidWlsZFNvcnRRdWVyeSA9IChzb3J0OiBQcm9kdWN0U29ydCk6IFJlcG9zaXRvcnlPcmRlckJ5PFByb2R1Y3Q+ID0+IHtcbiAgICBpZiAoIXNvcnQgfHwgc29ydCA9PT0gJ21vc3QtcmVsZXZhbnQnKSByZXR1cm4ge31cblxuICAgIGlmIChzb3J0ID09PSAnYmVzdC1zZWxsZXJzJylcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHNob3BwaW5nQ291bnQ6ICdkZXNjJyxcbiAgICAgICAgcmF0ZTogJ2Rlc2MnLFxuICAgICAgICBzdG9jazogJ2Rlc2MnLFxuICAgICAgICBuYW1lOiAnYXNjJyxcbiAgICAgIH1cbiAgICBpZiAoc29ydCA9PT0gJ2JpZ2dlc3QtcHJpY2UnKSByZXR1cm4geyBzdWJzY3JpYmVyUHJpY2U6ICdkZXNjJywgcmF0ZTogJ2Rlc2MnLCBzaG9wcGluZ0NvdW50OiAnZGVzYycgfSBhcyBhbnlcbiAgICBpZiAoc29ydCA9PT0gJ2xvd2VzdC1wcmljZScpIHJldHVybiB7IHN1YnNjcmliZXJQcmljZTogJ2FzYycsIHJhdGU6ICdkZXNjJywgc2hvcHBpbmdDb3VudDogJ2Rlc2MnIH0gYXMgYW55XG4gICAgaWYgKHNvcnQgPT09ICdiZXN0LXJhdGluZycpIHJldHVybiB7IHJhdGU6ICdkZXNjJywgc2hvcHBpbmdDb3VudDogJ2Rlc2MnLCBzdG9jazogJ2Rlc2MnLCBuYW1lOiAnYXNjJyB9XG4gICAgaWYgKHNvcnQgPT09ICduZXdzJykgcmV0dXJuIHsgY3JlYXRlZEF0OiAnZGVzYycgfVxuICAgIGlmIChzb3J0ID09PSAnYmlnZ2VzdC1kaXNjb3VudCcpXG4gICAgICByZXR1cm4geyBzdWJzY3JpYmVyRGlzY291bnRQZXJjZW50YWdlOiAnZGVzYycsIHJhdGU6ICdkZXNjJywgc2hvcHBpbmdDb3VudDogJ2Rlc2MnIH0gYXMgYW55XG4gIH1cblxuICBwcml2YXRlIGJ1aWxkTGltaXRRdWVyeSA9IChvcHRpb25zOiB7IHBhZ2U/OiBudW1iZXI7IHBlclBhZ2U/OiBudW1iZXIgfSk6IHsgbGltaXQ/OiBudW1iZXI7IG9mZnNldD86IG51bWJlciB9ID0+IHtcbiAgICBjb25zdCBsaW1pdCA9IG9wdGlvbnM/LnBlclBhZ2UgfHwgMjBcblxuICAgIHJldHVybiB7XG4gICAgICBsaW1pdCxcbiAgICAgIG9mZnNldDogKChvcHRpb25zPy5wYWdlIHx8IDEpIC0gMSkgKiBsaW1pdCxcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGhhc1Byb2ZpbGUgPSAoXG4gICAgb3B0aW9uczogUGFydGlhbDxGZXRjaFByb2R1Y3RzUGFyYW1zPFQ+PixcbiAgKTogb3B0aW9ucyBpcyBGZXRjaFByb2R1Y3RzT3B0aW9ucyAmIHtcbiAgICBwcm9maWxlOiBGZXRjaFByb2R1Y3RzTWFpblBhcmFtczxUPlsncHJvZmlsZSddXG4gICAgZmlsdGVycz86IEZldGNoUHJvZHVjdHNGaWx0ZXJzICYgeyBjdXN0b21PcHRpb25zPzogbmV2ZXI7IHRhZ3M/OiBuZXZlciB9XG4gIH0gPT4gJ3Byb2ZpbGUnIGluIG9wdGlvbnNcblxuICBwcml2YXRlIGhhc1Rlcm0gPSAoXG4gICAgb3B0aW9uczogUGFydGlhbDxGZXRjaFByb2R1Y3RzUGFyYW1zPFQ+PixcbiAgKTogb3B0aW9ucyBpcyBGZXRjaFByb2R1Y3RzT3B0aW9ucyAmIHtcbiAgICB0ZXJtOiBGZXRjaFByb2R1Y3RzTWFpblBhcmFtczxUPlsndGVybSddXG4gICAgZmlsdGVycz86IEZldGNoUHJvZHVjdHNGaWx0ZXJzICYgeyBjdXN0b21PcHRpb25zPzogbmV2ZXIgfVxuICB9ID0+ICd0ZXJtJyBpbiBvcHRpb25zXG5cbiAgcHJpdmF0ZSBoYXNDYXRlZ29yeSA9IChcbiAgICBvcHRpb25zOiBQYXJ0aWFsPEZldGNoUHJvZHVjdHNQYXJhbXM8VD4+LFxuICApOiBvcHRpb25zIGlzIEZldGNoUHJvZHVjdHNPcHRpb25zICYge1xuICAgIGNhdGVnb3J5OiBGZXRjaFByb2R1Y3RzTWFpblBhcmFtczxUPlsnY2F0ZWdvcnknXVxuICAgIGZpbHRlcnM/OiBGZXRjaFByb2R1Y3RzRmlsdGVycyAmIHsgY3VzdG9tT3B0aW9ucz86IG5ldmVyIH1cbiAgfSA9PiAnY2F0ZWdvcnknIGluIG9wdGlvbnNcblxuICBwcml2YXRlIGJ1aWxkSW5kZXhCcmFuZHMgPSAob3B0aW9uczogUGFydGlhbDxGZXRjaFByb2R1Y3RzUGFyYW1zPFQ+Pik6IHN0cmluZyA9PiB7XG4gICAgaWYgKHRoaXMuaGFzQ2F0ZWdvcnkob3B0aW9ucykpIHJldHVybiBgY2F0ZWdvcnktJHtvcHRpb25zLmNhdGVnb3J5LmlkfWBcbiAgICBpZiAodGhpcy5oYXNUZXJtKG9wdGlvbnMpKSByZXR1cm4gYHRlcm0tJHtvcHRpb25zLnRlcm19YFxuICAgIGlmICh0aGlzLmhhc1Byb2ZpbGUob3B0aW9ucykpIHJldHVybiBgcHJvZmlsZS0ke29wdGlvbnMucHJvZmlsZS5qb2luKCcsJyl9YFxuXG4gICAgcmV0dXJuICcnXG4gIH1cbn1cbiJdfQ==
@@ -1,51 +0,0 @@
1
- import { Inject, Injectable } from '@angular/core';
2
- import { Shops, } from '@infrab4a/connect';
3
- import { CATEGORY_STRUCTURE, DEFAULT_SHOP } from '../../consts';
4
- import * as i0 from "@angular/core";
5
- import * as i1 from "@infrab4a/connect";
6
- export class CategoryService {
7
- constructor(productRepository, categoryRepository, categoryFilterRepository, categoryStructureAdapter, shop) {
8
- this.productRepository = productRepository;
9
- this.categoryRepository = categoryRepository;
10
- this.categoryFilterRepository = categoryFilterRepository;
11
- this.categoryStructureAdapter = categoryStructureAdapter;
12
- this.shop = shop;
13
- }
14
- async fetchBrands(category, options, optionsCache) {
15
- const brands = await this.productRepository
16
- .findCatalog({
17
- filters: await this.categoryStructureAdapter.buildProductFilterByCategory(category),
18
- fields: ['brand'],
19
- }, options?.mainGender ? options?.mainGender : this.shop === Shops.MENSMARKET ? 'male' : 'female', optionsCache)
20
- .then(({ data }) => Object.keys(data.map((product) => product.brand).reduce((brands, brand) => ({ ...brands, [brand]: true }), {})));
21
- return this.categoryRepository
22
- .find({ filters: { brandCategory: true, shop: options?.shop || this.shop }, orderBy: { name: 'asc' } }, optionsCache)
23
- .then(({ data }) => data.filter((category) => brands.includes(category.conditions.brand)));
24
- }
25
- async fetchFilterOptions(category, optionsCache) {
26
- return await this.categoryFilterRepository
27
- .find({ filters: { categoryId: +category.id } }, optionsCache)
28
- .then(({ data }) => data.map((categoryFilter) => categoryFilter.filter));
29
- }
30
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.3", ngImport: i0, type: CategoryService, deps: [{ token: 'ProductRepository' }, { token: 'CategoryRepository' }, { token: 'CategoryFilterRepository' }, { token: CATEGORY_STRUCTURE }, { token: DEFAULT_SHOP }], target: i0.ɵɵFactoryTarget.Injectable }); }
31
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.0.3", ngImport: i0, type: CategoryService }); }
32
- }
33
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.3", ngImport: i0, type: CategoryService, decorators: [{
34
- type: Injectable
35
- }], ctorParameters: () => [{ type: undefined, decorators: [{
36
- type: Inject,
37
- args: ['ProductRepository']
38
- }] }, { type: undefined, decorators: [{
39
- type: Inject,
40
- args: ['CategoryRepository']
41
- }] }, { type: undefined, decorators: [{
42
- type: Inject,
43
- args: ['CategoryFilterRepository']
44
- }] }, { type: undefined, decorators: [{
45
- type: Inject,
46
- args: [CATEGORY_STRUCTURE]
47
- }] }, { type: i1.Shops, decorators: [{
48
- type: Inject,
49
- args: [DEFAULT_SHOP]
50
- }] }] });
51
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2F0ZWdvcnkuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2Nvbm5lY3QtYW5ndWxhci9zcmMvc2VydmljZXMvY2F0YWxvZy9jYXRlZ29yeS5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxNQUFNLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFBO0FBQ2xELE9BQU8sRUFRTCxLQUFLLEdBQ04sTUFBTSxtQkFBbUIsQ0FBQTtBQUMxQixPQUFPLEVBQUUsa0JBQWtCLEVBQUUsWUFBWSxFQUFFLE1BQU0sY0FBYyxDQUFBOzs7QUFTL0QsTUFBTSxPQUFPLGVBQWU7SUFDMUIsWUFDZ0QsaUJBQW9DLEVBQ25DLGtCQUFzQyxFQUNoQyx3QkFBa0QsRUFDMUQsd0JBQWtELEVBQ3hELElBQVc7UUFKSixzQkFBaUIsR0FBakIsaUJBQWlCLENBQW1CO1FBQ25DLHVCQUFrQixHQUFsQixrQkFBa0IsQ0FBb0I7UUFDaEMsNkJBQXdCLEdBQXhCLHdCQUF3QixDQUEwQjtRQUMxRCw2QkFBd0IsR0FBeEIsd0JBQXdCLENBQTBCO1FBQ3hELFNBQUksR0FBSixJQUFJLENBQU87SUFDakQsQ0FBQztJQUVKLEtBQUssQ0FBQyxXQUFXLENBQ2YsUUFBa0IsRUFDbEIsT0FBNEIsRUFDNUIsWUFBaUQ7UUFFakQsTUFBTSxNQUFNLEdBQUcsTUFBTSxJQUFJLENBQUMsaUJBQWlCO2FBQ3hDLFdBQVcsQ0FDVjtZQUNFLE9BQU8sRUFBRSxNQUFNLElBQUksQ0FBQyx3QkFBd0IsQ0FBQyw0QkFBNEIsQ0FBQyxRQUFRLENBQUM7WUFDbkYsTUFBTSxFQUFFLENBQUMsT0FBTyxDQUFDO1NBQ2xCLEVBQ0QsT0FBTyxFQUFFLFVBQVUsQ0FBQyxDQUFDLENBQUMsT0FBTyxFQUFFLFVBQVUsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksS0FBSyxLQUFLLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLFFBQVEsRUFDOUYsWUFBWSxDQUNiO2FBQ0EsSUFBSSxDQUFDLENBQUMsRUFBRSxJQUFJLEVBQUUsRUFBRSxFQUFFLENBQ2pCLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLE1BQU0sRUFBRSxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUMsRUFBRSxHQUFHLE1BQU0sRUFBRSxDQUFDLEtBQUssQ0FBQyxFQUFFLElBQUksRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FDaEgsQ0FBQTtRQUVILE9BQU8sSUFBSSxDQUFDLGtCQUFrQjthQUMzQixJQUFJLENBQ0gsRUFBRSxPQUFPLEVBQUUsRUFBRSxhQUFhLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUUsSUFBSSxJQUFJLElBQUksQ0FBQyxJQUFJLEVBQUUsRUFBRSxPQUFPLEVBQUUsRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLEVBQUUsRUFDaEcsWUFBWSxDQUNiO2FBQ0EsSUFBSSxDQUFDLENBQUMsRUFBRSxJQUFJLEVBQUUsRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLFFBQVEsRUFBRSxFQUFFLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQTtJQUM5RixDQUFDO0lBRUQsS0FBSyxDQUFDLGtCQUFrQixDQUFDLFFBQWtCLEVBQUUsWUFBaUQ7UUFDNUYsT0FBTyxNQUFNLElBQUksQ0FBQyx3QkFBd0I7YUFDdkMsSUFBSSxDQUFDLEVBQUUsT0FBTyxFQUFFLEVBQUUsVUFBVSxFQUFFLENBQUMsUUFBUSxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsWUFBWSxDQUFDO2FBQzdELElBQUksQ0FBQyxDQUFDLEVBQUUsSUFBSSxFQUFFLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxjQUFjLEVBQUUsRUFBRSxDQUFDLGNBQWMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFBO0lBQzVFLENBQUM7OEdBdkNVLGVBQWUsa0JBRWhCLG1CQUFtQixhQUNuQixvQkFBb0IsYUFDcEIsMEJBQTBCLGFBQzFCLGtCQUFrQixhQUNsQixZQUFZO2tIQU5YLGVBQWU7OzJGQUFmLGVBQWU7a0JBRDNCLFVBQVU7OzBCQUdOLE1BQU07MkJBQUMsbUJBQW1COzswQkFDMUIsTUFBTTsyQkFBQyxvQkFBb0I7OzBCQUMzQixNQUFNOzJCQUFDLDBCQUEwQjs7MEJBQ2pDLE1BQU07MkJBQUMsa0JBQWtCOzswQkFDekIsTUFBTTsyQkFBQyxZQUFZIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0LCBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSdcbmltcG9ydCB7XG4gIENhdGVnb3J5LFxuICBDYXRlZ29yeUZpbHRlclJlcG9zaXRvcnksXG4gIENhdGVnb3J5UmVwb3NpdG9yeSxcbiAgRmlsdGVyLFxuICBQcm9kdWN0R2VuZGVyLFxuICBQcm9kdWN0UmVwb3NpdG9yeSxcbiAgUmVwb3NpdG9yeUNhY2hlT3B0aW9ucyxcbiAgU2hvcHMsXG59IGZyb20gJ0BpbmZyYWI0YS9jb25uZWN0J1xuaW1wb3J0IHsgQ0FURUdPUllfU1RSVUNUVVJFLCBERUZBVUxUX1NIT1AgfSBmcm9tICcuLi8uLi9jb25zdHMnXG5pbXBvcnQgeyBDYXRlZ29yeVN0cnVjdHVyZUFkYXB0ZXIgfSBmcm9tICcuL2FkYXB0ZXJzJ1xuXG50eXBlIEZldGNoQnJhbmRzT3B0aW9ucyA9IHtcbiAgbWFpbkdlbmRlcj86IFByb2R1Y3RHZW5kZXJcbiAgc2hvcD86IFNob3BzXG59XG5cbkBJbmplY3RhYmxlKClcbmV4cG9ydCBjbGFzcyBDYXRlZ29yeVNlcnZpY2Uge1xuICBjb25zdHJ1Y3RvcihcbiAgICBASW5qZWN0KCdQcm9kdWN0UmVwb3NpdG9yeScpIHByaXZhdGUgcmVhZG9ubHkgcHJvZHVjdFJlcG9zaXRvcnk6IFByb2R1Y3RSZXBvc2l0b3J5LFxuICAgIEBJbmplY3QoJ0NhdGVnb3J5UmVwb3NpdG9yeScpIHByaXZhdGUgcmVhZG9ubHkgY2F0ZWdvcnlSZXBvc2l0b3J5OiBDYXRlZ29yeVJlcG9zaXRvcnksXG4gICAgQEluamVjdCgnQ2F0ZWdvcnlGaWx0ZXJSZXBvc2l0b3J5JykgcHJpdmF0ZSByZWFkb25seSBjYXRlZ29yeUZpbHRlclJlcG9zaXRvcnk6IENhdGVnb3J5RmlsdGVyUmVwb3NpdG9yeSxcbiAgICBASW5qZWN0KENBVEVHT1JZX1NUUlVDVFVSRSkgcHJpdmF0ZSByZWFkb25seSBjYXRlZ29yeVN0cnVjdHVyZUFkYXB0ZXI6IENhdGVnb3J5U3RydWN0dXJlQWRhcHRlcixcbiAgICBASW5qZWN0KERFRkFVTFRfU0hPUCkgcHJpdmF0ZSByZWFkb25seSBzaG9wOiBTaG9wcyxcbiAgKSB7fVxuXG4gIGFzeW5jIGZldGNoQnJhbmRzKFxuICAgIGNhdGVnb3J5OiBDYXRlZ29yeSxcbiAgICBvcHRpb25zPzogRmV0Y2hCcmFuZHNPcHRpb25zLFxuICAgIG9wdGlvbnNDYWNoZT86IHsgY2FjaGU/OiBSZXBvc2l0b3J5Q2FjaGVPcHRpb25zIH0sXG4gICk6IFByb21pc2U8Q2F0ZWdvcnlbXT4ge1xuICAgIGNvbnN0IGJyYW5kcyA9IGF3YWl0IHRoaXMucHJvZHVjdFJlcG9zaXRvcnlcbiAgICAgIC5maW5kQ2F0YWxvZyhcbiAgICAgICAge1xuICAgICAgICAgIGZpbHRlcnM6IGF3YWl0IHRoaXMuY2F0ZWdvcnlTdHJ1Y3R1cmVBZGFwdGVyLmJ1aWxkUHJvZHVjdEZpbHRlckJ5Q2F0ZWdvcnkoY2F0ZWdvcnkpLFxuICAgICAgICAgIGZpZWxkczogWydicmFuZCddLFxuICAgICAgICB9LFxuICAgICAgICBvcHRpb25zPy5tYWluR2VuZGVyID8gb3B0aW9ucz8ubWFpbkdlbmRlciA6IHRoaXMuc2hvcCA9PT0gU2hvcHMuTUVOU01BUktFVCA/ICdtYWxlJyA6ICdmZW1hbGUnLFxuICAgICAgICBvcHRpb25zQ2FjaGUsXG4gICAgICApXG4gICAgICAudGhlbigoeyBkYXRhIH0pID0+XG4gICAgICAgIE9iamVjdC5rZXlzKGRhdGEubWFwKChwcm9kdWN0KSA9PiBwcm9kdWN0LmJyYW5kKS5yZWR1Y2UoKGJyYW5kcywgYnJhbmQpID0+ICh7IC4uLmJyYW5kcywgW2JyYW5kXTogdHJ1ZSB9KSwge30pKSxcbiAgICAgIClcblxuICAgIHJldHVybiB0aGlzLmNhdGVnb3J5UmVwb3NpdG9yeVxuICAgICAgLmZpbmQoXG4gICAgICAgIHsgZmlsdGVyczogeyBicmFuZENhdGVnb3J5OiB0cnVlLCBzaG9wOiBvcHRpb25zPy5zaG9wIHx8IHRoaXMuc2hvcCB9LCBvcmRlckJ5OiB7IG5hbWU6ICdhc2MnIH0gfSxcbiAgICAgICAgb3B0aW9uc0NhY2hlLFxuICAgICAgKVxuICAgICAgLnRoZW4oKHsgZGF0YSB9KSA9PiBkYXRhLmZpbHRlcigoY2F0ZWdvcnkpID0+IGJyYW5kcy5pbmNsdWRlcyhjYXRlZ29yeS5jb25kaXRpb25zLmJyYW5kKSkpXG4gIH1cblxuICBhc3luYyBmZXRjaEZpbHRlck9wdGlvbnMoY2F0ZWdvcnk6IENhdGVnb3J5LCBvcHRpb25zQ2FjaGU/OiB7IGNhY2hlPzogUmVwb3NpdG9yeUNhY2hlT3B0aW9ucyB9KTogUHJvbWlzZTxGaWx0ZXJbXT4ge1xuICAgIHJldHVybiBhd2FpdCB0aGlzLmNhdGVnb3J5RmlsdGVyUmVwb3NpdG9yeVxuICAgICAgLmZpbmQoeyBmaWx0ZXJzOiB7IGNhdGVnb3J5SWQ6ICtjYXRlZ29yeS5pZCB9IH0sIG9wdGlvbnNDYWNoZSlcbiAgICAgIC50aGVuKCh7IGRhdGEgfSkgPT4gZGF0YS5tYXAoKGNhdGVnb3J5RmlsdGVyKSA9PiBjYXRlZ29yeUZpbHRlci5maWx0ZXIpKVxuICB9XG59XG4iXX0=