@infrab4a/connect-angular 4.3.11 → 4.3.12-beta.1

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 (108) hide show
  1. package/angular-connect.module.d.ts +26 -26
  2. package/angular-elastic-search.module.d.ts +9 -9
  3. package/angular-firebase-auth.module.d.ts +11 -11
  4. package/angular-firestore.module.d.ts +18 -18
  5. package/angular-hasura-graphql.module.d.ts +16 -16
  6. package/consts/backend-url.const.d.ts +1 -1
  7. package/consts/category-structure.d.ts +1 -1
  8. package/consts/default-shop.const.d.ts +1 -1
  9. package/consts/es-config.const.d.ts +1 -1
  10. package/consts/firebase-const.d.ts +3 -3
  11. package/consts/hasura-options.const.d.ts +1 -1
  12. package/consts/index.d.ts +7 -7
  13. package/consts/persistence.const.d.ts +1 -1
  14. package/consts/storage-base-url.const.d.ts +1 -1
  15. package/esm2020/angular-connect.module.mjs +115 -115
  16. package/esm2020/angular-elastic-search.module.mjs +34 -34
  17. package/esm2020/angular-firebase-auth.module.mjs +115 -115
  18. package/esm2020/angular-firestore.module.mjs +502 -502
  19. package/esm2020/angular-hasura-graphql.module.mjs +265 -265
  20. package/esm2020/consts/backend-url.const.mjs +1 -1
  21. package/esm2020/consts/category-structure.mjs +2 -2
  22. package/esm2020/consts/default-shop.const.mjs +2 -2
  23. package/esm2020/consts/es-config.const.mjs +2 -2
  24. package/esm2020/consts/firebase-const.mjs +4 -4
  25. package/esm2020/consts/hasura-options.const.mjs +2 -2
  26. package/esm2020/consts/index.mjs +8 -8
  27. package/esm2020/consts/persistence.const.mjs +2 -2
  28. package/esm2020/consts/storage-base-url.const.mjs +2 -2
  29. package/esm2020/helpers/index.mjs +2 -2
  30. package/esm2020/helpers/mobile-operation-system-checker.helper.mjs +7 -7
  31. package/esm2020/index.mjs +7 -7
  32. package/esm2020/infrab4a-connect-angular.mjs +4 -4
  33. package/esm2020/persistence/cookie-data-persistence.mjs +22 -22
  34. package/esm2020/persistence/data-persistence.mjs +2 -2
  35. package/esm2020/persistence/index.mjs +3 -3
  36. package/esm2020/services/auth.service.mjs +37 -37
  37. package/esm2020/services/cart.service.mjs +281 -281
  38. package/esm2020/services/catalog/adapters/category-structure.adapter.mjs +2 -2
  39. package/esm2020/services/catalog/adapters/index.mjs +4 -4
  40. package/esm2020/services/catalog/adapters/new-category-structure.adapter.mjs +41 -41
  41. package/esm2020/services/catalog/adapters/old-category-structure.adapter.mjs +23 -23
  42. package/esm2020/services/catalog/catalog.service.mjs +192 -185
  43. package/esm2020/services/catalog/category.service.mjs +51 -51
  44. package/esm2020/services/catalog/enums/index.mjs +2 -2
  45. package/esm2020/services/catalog/enums/product-sorts.enum.mjs +11 -11
  46. package/esm2020/services/catalog/index.mjs +8 -8
  47. package/esm2020/services/catalog/models/category-with-tree.model.mjs +10 -10
  48. package/esm2020/services/catalog/models/index.mjs +2 -2
  49. package/esm2020/services/catalog/types/index.mjs +2 -2
  50. package/esm2020/services/catalog/types/product-sort.type.mjs +2 -2
  51. package/esm2020/services/catalog/wishlist.service.mjs +115 -115
  52. package/esm2020/services/checkout-subscription.service.mjs +50 -50
  53. package/esm2020/services/checkout.service.mjs +68 -68
  54. package/esm2020/services/coupon.service.mjs +235 -235
  55. package/esm2020/services/helpers/index.mjs +2 -2
  56. package/esm2020/services/helpers/util.helper.mjs +18 -18
  57. package/esm2020/services/home-shop.service.mjs +125 -125
  58. package/esm2020/services/index.mjs +11 -11
  59. package/esm2020/services/order.service.mjs +30 -30
  60. package/esm2020/services/shipping.service.mjs +96 -96
  61. package/esm2020/services/types/index.mjs +3 -3
  62. package/esm2020/services/types/required-checkout-data.type.mjs +2 -2
  63. package/esm2020/services/types/required-checkout-subscription-data.type.mjs +2 -2
  64. package/esm2020/services/types/shipping-methods.type.mjs +2 -2
  65. package/esm2020/types/firebase-app-config.type.mjs +2 -2
  66. package/esm2020/types/index.mjs +2 -2
  67. package/fesm2015/infrab4a-connect-angular.mjs +2325 -2321
  68. package/fesm2015/infrab4a-connect-angular.mjs.map +1 -1
  69. package/fesm2020/infrab4a-connect-angular.mjs +2260 -2253
  70. package/fesm2020/infrab4a-connect-angular.mjs.map +1 -1
  71. package/helpers/index.d.ts +1 -1
  72. package/helpers/mobile-operation-system-checker.helper.d.ts +3 -3
  73. package/index.d.ts +6 -6
  74. package/package.json +1 -1
  75. package/persistence/cookie-data-persistence.d.ts +10 -10
  76. package/persistence/data-persistence.d.ts +6 -6
  77. package/persistence/index.d.ts +2 -2
  78. package/services/auth.service.d.ts +18 -18
  79. package/services/cart.service.d.ts +42 -42
  80. package/services/catalog/adapters/category-structure.adapter.d.ts +4 -4
  81. package/services/catalog/adapters/index.d.ts +3 -3
  82. package/services/catalog/adapters/new-category-structure.adapter.d.ts +12 -12
  83. package/services/catalog/adapters/old-category-structure.adapter.d.ts +10 -10
  84. package/services/catalog/catalog.service.d.ts +86 -86
  85. package/services/catalog/category.service.d.ts +20 -20
  86. package/services/catalog/enums/index.d.ts +1 -1
  87. package/services/catalog/enums/product-sorts.enum.d.ts +9 -9
  88. package/services/catalog/index.d.ts +7 -7
  89. package/services/catalog/models/category-with-tree.model.d.ts +4 -4
  90. package/services/catalog/models/index.d.ts +1 -1
  91. package/services/catalog/types/index.d.ts +1 -1
  92. package/services/catalog/types/product-sort.type.d.ts +2 -2
  93. package/services/catalog/wishlist.service.d.ts +38 -38
  94. package/services/checkout-subscription.service.d.ts +19 -19
  95. package/services/checkout.service.d.ts +24 -24
  96. package/services/coupon.service.d.ts +29 -29
  97. package/services/helpers/index.d.ts +1 -1
  98. package/services/helpers/util.helper.d.ts +3 -3
  99. package/services/home-shop.service.d.ts +26 -26
  100. package/services/index.d.ts +10 -10
  101. package/services/order.service.d.ts +13 -13
  102. package/services/shipping.service.d.ts +19 -19
  103. package/services/types/index.d.ts +2 -2
  104. package/services/types/required-checkout-data.type.d.ts +2 -2
  105. package/services/types/required-checkout-subscription-data.type.d.ts +2 -2
  106. package/services/types/shipping-methods.type.d.ts +12 -12
  107. package/types/firebase-app-config.type.d.ts +1 -1
  108. package/types/index.d.ts +1 -1
@@ -1,185 +1,192 @@
1
- import { Inject, Injectable } from '@angular/core';
2
- import { InvalidArgumentError, ProductsIndex, RoundProductPricesHelper, Shops, Where, 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, categoryRepository, categoryStructureAdapter, shop, productIndex) {
8
- this.productRepository = productRepository;
9
- this.categoryRepository = categoryRepository;
10
- this.categoryStructureAdapter = categoryStructureAdapter;
11
- this.shop = shop;
12
- this.productIndex = productIndex;
13
- this.productsByTerm = {};
14
- this.buildFilterQuery = ({ clubDiscount, brands, prices, gender, tags, rate, customOptions, }) => {
15
- const filters = {};
16
- if (clubDiscount?.length)
17
- set(filters, 'price.subscriberDiscountPercentage', { operator: Where.IN, value: clubDiscount });
18
- if (brands?.length)
19
- filters.brand = { operator: Where.IN, value: brands };
20
- if (gender?.length)
21
- filters.gender = { operator: Where.IN, value: gender };
22
- if (prices?.min || prices?.max)
23
- set(filters, prices.subscriberPrice ? 'price.subscriberPrice' : 'price.price', [
24
- ...(prices.min ? [{ operator: Where.GTE, value: Math.round(prices.min) }] : []),
25
- ...(prices.max ? [{ operator: Where.LTE, value: Math.ceil(prices.max) }] : []),
26
- ]);
27
- if (rate)
28
- filters.rate = { operator: Where.GTE, value: rate };
29
- if (tags?.length)
30
- filters.tags = { operator: Where.LIKE, value: tags };
31
- if (customOptions?.length)
32
- filters.filters = { operator: Where.LIKE, value: customOptions };
33
- return filters;
34
- };
35
- this.buildSortQuery = (sort) => {
36
- if (!sort || sort === 'most-relevant')
37
- return {};
38
- if (sort === 'best-sellers')
39
- return { shoppingCount: 'desc' };
40
- if (sort === 'biggest-price')
41
- return { subscriberPrice: 'desc' };
42
- if (sort === 'lowest-price')
43
- return { subscriberPrice: 'asc' };
44
- if (sort === 'best-rating')
45
- return { rate: 'desc' };
46
- if (sort === 'news')
47
- return { createdAt: 'desc' };
48
- if (sort === 'biggest-discount')
49
- return { subscriberDiscountPercentage: 'desc' };
50
- };
51
- this.buildLimitQuery = (options) => {
52
- const limit = options?.perPage || 20;
53
- return {
54
- limit,
55
- offset: ((options?.page || 1) - 1) * limit,
56
- };
57
- };
58
- this.hasProfile = (options) => 'profile' in options;
59
- this.hasTerm = (options) => 'term' in options;
60
- this.hasCategory = (options) => 'category' in options;
61
- }
62
- async fetchProducts(options) {
63
- const limits = this.buildLimitQuery(options);
64
- if (this.hasProfile(options) && options.filters?.customOptions)
65
- throw new InvalidArgumentError(`It couldn't filled customOptions when profile is given`);
66
- if (this.hasProfile(options) && options.filters?.tags)
67
- throw new InvalidArgumentError(`It couldn't filled tags when profile is given`);
68
- if (this.hasTerm(options) && options.filters?.customOptions)
69
- throw new InvalidArgumentError(`It couldn't filled customOptions when term is given`);
70
- return await this.findCatalog(options, limits).then(({ data, count: total, maximum, minimal, distinct }) => ({
71
- products: { data: data.map((product) => RoundProductPricesHelper.roundProductPrices(product)), total },
72
- pages: Math.ceil(total / limits.limit),
73
- prices: {
74
- price: { min: +minimal?.price?.price?.toFixed(2), max: +maximum?.price?.price?.toFixed(2) },
75
- subscriberPrice: {
76
- min: +minimal?.price?.subscriberPrice?.toFixed(2),
77
- max: +maximum?.price?.subscriberPrice?.toFixed(2),
78
- },
79
- },
80
- brands: distinct?.brand,
81
- }));
82
- }
83
- async findCatalog(options, limits) {
84
- if (this.hasTerm(options) && options.sort === 'most-relevant') {
85
- const productsIds = await this.findCatalogIdsByElasticSearch(options.term);
86
- return this.findCatalogAndSortByMostRevelant(productsIds, options, limits);
87
- }
88
- if (this.hasCategory(options) && options.sort === 'most-relevant') {
89
- const productsIds = options.category.products?.length
90
- ? options.category.products
91
- : await this.categoryRepository.get({ id: options.category.id }).then((categoryFound) => categoryFound.products);
92
- return this.findCatalogAndSortByMostRevelant(productsIds, options, limits);
93
- }
94
- const repoParams = {
95
- filters: {
96
- ...(await this.buildMainFilter(options)),
97
- ...this.buildFilterQuery(options?.filters || {}),
98
- },
99
- ...(options?.sort ? { orderBy: this.buildSortQuery(options?.sort) } : {}),
100
- limits,
101
- options: {
102
- minimal: ['price'],
103
- maximum: ['price'],
104
- ...(!this.hasCategory(options) ? { distinct: ['brand'] } : {}),
105
- },
106
- };
107
- if (['biggest-price', 'lowest-price', 'biggest-discount', 'best-rating'].includes(options.sort))
108
- return this.productRepository.findCatalog(repoParams);
109
- return this.productRepository.findCatalog(repoParams, options?.mainGender || this.shop === Shops.MENSMARKET ? 'male' : 'female');
110
- }
111
- async buildMainFilter({ category, profile, term, }) {
112
- if (category)
113
- return this.categoryStructureAdapter.buildProductFilterByCategory(category);
114
- if (profile)
115
- return { tags: { operator: Where.LIKE, value: profile } };
116
- if (term)
117
- return this.productIndex
118
- .search(term, 999, this.shop)
119
- .then((data) => ({ id: { operator: Where.IN, value: data.hits.map(({ _source }) => _source.id) } }));
120
- }
121
- async findCatalogAndSortByMostRevelant(productIds, options, limits) {
122
- const totalResult = await this.productRepository.findCatalog({
123
- fields: ['id', 'stock'],
124
- filters: {
125
- id: { operator: Where.IN, value: productIds },
126
- ...this.buildFilterQuery(options?.filters || {}),
127
- },
128
- options: {
129
- minimal: ['price'],
130
- maximum: ['price'],
131
- distinct: ['brand'],
132
- },
133
- }, options?.mainGender || this.shop === Shops.MENSMARKET ? 'male' : 'female');
134
- const stockData = totalResult.data.filter((product) => product.stock.quantity > 0);
135
- const stockOut = totalResult.data.filter((product) => product.stock.quantity <= 0);
136
- const productIdsStock = productIds.filter((product) => stockData.some((result) => result.id == product));
137
- const productIdsStockOut = productIds.filter((product) => stockOut.some((result) => result.id == product));
138
- const limitedProductId = productIdsStock
139
- .concat(productIdsStockOut)
140
- .slice(limits.offset, limits.offset + limits.limit);
141
- const orderedId = productIds.filter((product) => limitedProductId.includes(product));
142
- const productResult = await this.productRepository.findCatalog({
143
- filters: {
144
- id: { operator: Where.IN, value: orderedId },
145
- },
146
- });
147
- return {
148
- data: limitedProductId.map((id) => productResult.data.find((product) => product.id === id)).filter(Boolean),
149
- count: totalResult.count,
150
- maximum: totalResult.maximum,
151
- minimal: totalResult.minimal,
152
- distinct: totalResult.distinct,
153
- };
154
- }
155
- async findCatalogIdsByElasticSearch(term) {
156
- if (this.productsByTerm[term])
157
- return this.productsByTerm[term];
158
- return (this.productsByTerm[term] = await this.productIndex
159
- .search(term, 999, this.shop)
160
- .then(({ hits: products }) => {
161
- const withStock = products.filter(({ _source }) => _source.stock.quantity > 0);
162
- const withOutStock = products.filter(({ _source }) => _source.stock.quantity <= 0);
163
- const sorted = [...withStock, ...withOutStock];
164
- return [...new Set(sorted.map(({ _source }) => _source.id))];
165
- }));
166
- }
167
- }
168
- CatalogService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: CatalogService, deps: [{ token: 'ProductRepository' }, { token: 'CategoryRepository' }, { token: CATEGORY_STRUCTURE }, { token: DEFAULT_SHOP }, { token: i1.ProductsIndex }], target: i0.ɵɵFactoryTarget.Injectable });
169
- CatalogService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: CatalogService });
170
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: CatalogService, decorators: [{
171
- type: Injectable
172
- }], ctorParameters: function () { return [{ type: undefined, decorators: [{
173
- type: Inject,
174
- args: ['ProductRepository']
175
- }] }, { type: undefined, decorators: [{
176
- type: Inject,
177
- args: ['CategoryRepository']
178
- }] }, { type: undefined, decorators: [{
179
- type: Inject,
180
- args: [CATEGORY_STRUCTURE]
181
- }] }, { type: i1.Shops, decorators: [{
182
- type: Inject,
183
- args: [DEFAULT_SHOP]
184
- }] }, { type: i1.ProductsIndex }]; } });
185
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2F0YWxvZy5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvY29ubmVjdC1hbmd1bGFyL3NyYy9zZXJ2aWNlcy9jYXRhbG9nL2NhdGFsb2cuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsTUFBTSxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQTtBQUNsRCxPQUFPLEVBSUwsb0JBQW9CLEVBSXBCLGFBQWEsRUFJYix3QkFBd0IsRUFDeEIsS0FBSyxFQUNMLEtBQUssRUFDTCxHQUFHLEdBQ0osTUFBTSxtQkFBbUIsQ0FBQTtBQUMxQixPQUFPLEVBQUUsa0JBQWtCLEVBQUUsWUFBWSxFQUFFLE1BQU0sY0FBYyxDQUFBOzs7QUFzRC9ELE1BQU0sT0FBTyxjQUFjO0lBR3pCLFlBQ2dELGlCQUFvQyxFQUNuQyxrQkFBc0MsRUFDeEMsd0JBQWtELEVBQ3hELElBQVcsRUFDakMsWUFBMkI7UUFKRSxzQkFBaUIsR0FBakIsaUJBQWlCLENBQW1CO1FBQ25DLHVCQUFrQixHQUFsQixrQkFBa0IsQ0FBb0I7UUFDeEMsNkJBQXdCLEdBQXhCLHdCQUF3QixDQUEwQjtRQUN4RCxTQUFJLEdBQUosSUFBSSxDQUFPO1FBQ2pDLGlCQUFZLEdBQVosWUFBWSxDQUFlO1FBUHRDLG1CQUFjLEdBQTZCLEVBQUUsQ0FBQTtRQTZKN0MscUJBQWdCLEdBQUcsQ0FBQyxFQUMxQixZQUFZLEVBQ1osTUFBTSxFQUNOLE1BQU0sRUFDTixNQUFNLEVBQ04sSUFBSSxFQUNKLElBQUksRUFDSixhQUFhLEdBQ1EsRUFBbUMsRUFBRTtZQUMxRCxNQUFNLE9BQU8sR0FBRyxFQUFxQyxDQUFBO1lBRXJELElBQUksWUFBWSxFQUFFLE1BQU07Z0JBQ3RCLEdBQUcsQ0FBQyxPQUFPLEVBQUUsb0NBQW9DLEVBQUUsRUFBRSxRQUFRLEVBQUUsS0FBSyxDQUFDLEVBQUUsRUFBRSxLQUFLLEVBQUUsWUFB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QyxrQkFBa0I7OzBCQUN6QixNQUFNOzJCQUFDLFlBQVkiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3QsIEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJ1xuaW1wb3J0IHtcbiAgQ2F0ZWdvcnksXG4gIENhdGVnb3J5UmVwb3NpdG9yeSxcbiAgRmluZFJlcG9zaXRvcnlQYXJhbXMsXG4gIEludmFsaWRBcmd1bWVudEVycm9yLFxuICBQcm9kdWN0LFxuICBQcm9kdWN0R2VuZGVyLFxuICBQcm9kdWN0UmVwb3NpdG9yeSxcbiAgUHJvZHVjdHNJbmRleCxcbiAgUmVwb3NpdG9yeUZpbmRGaWVsdGVycyxcbiAgUmVwb3NpdG9yeUZpbmRSZXN1bHQsXG4gIFJlcG9zaXRvcnlPcmRlckJ5LFxuICBSb3VuZFByb2R1Y3RQcmljZXNIZWxwZXIsXG4gIFNob3BzLFxuICBXaGVyZSxcbiAgc2V0LFxufSBmcm9tICdAaW5mcmFiNGEvY29ubmVjdCdcbmltcG9ydCB7IENBVEVHT1JZX1NUUlVDVFVSRSwgREVGQVVMVF9TSE9QIH0gZnJvbSAnLi4vLi4vY29uc3RzJ1xuaW1wb3J0IHsgQ2F0ZWdvcnlTdHJ1Y3R1cmVBZGFwdGVyIH0gZnJvbSAnLi9hZGFwdGVycydcbmltcG9ydCB7IFByb2R1Y3RTb3J0IH0gZnJvbSAnLi90eXBlcy9wcm9kdWN0LXNvcnQudHlwZSdcblxudHlwZSBGZXRjaFByb2R1Y3RzRmlsdGVycyA9IHtcbiAgY2x1YkRpc2NvdW50PzogbnVtYmVyW11cbiAgYnJhbmRzPzogc3RyaW5nW11cbiAgcHJpY2VzPzogeyBtaW4/OiBudW1iZXI7IG1heD86IG51bWJlcjsgc3Vic2NyaWJlclByaWNlPzogYm9vbGVhbiB9XG4gIGdlbmRlcj86IFByb2R1Y3RHZW5kZXJbXVxuICByYXRlPzogbnVtYmVyXG4gIGN1c3RvbU9wdGlvbnM/OiBzdHJpbmdbXVxuICB0YWdzPzogc3RyaW5nW11cbn1cblxudHlwZSBGZXRjaFByb2R1Y3RzT3B0aW9ucyA9IHtcbiAgcGFnZT86IG51bWJlclxuICBwZXJQYWdlPzogbnVtYmVyXG4gIHNvcnQ/OiBQcm9kdWN0U29ydFxuICBtYWluR2VuZGVyPzogUHJvZHVjdEdlbmRlclxufVxuXG50eXBlIEZldGNoUHJvZHVjdHNNYWluUGFyYW1zPFQgZXh0ZW5kcyBDYXRlZ29yeT4gPSB7XG4gIGNhdGVnb3J5PzogVFxuICBwcm9maWxlPzogc3RyaW5nW11cbiAgdGVybT86IHN0cmluZ1xufVxuXG50eXBlIEZldGNoUHJvZHVjdHNQYXJhbXM8VCBleHRlbmRzIENhdGVnb3J5PiA9IEZldGNoUHJvZHVjdHNPcHRpb25zICZcbiAgKFxuICAgIHwge1xuICAgICAgICBjYXRlZ29yeTogRmV0Y2hQcm9kdWN0c01haW5QYXJhbXM8VD5bJ2NhdGVnb3J5J11cbiAgICAgICAgZmlsdGVycz86IEZldGNoUHJvZHVjdHNGaWx0ZXJzICYgeyBjdXN0b21PcHRpb25zPzogbmV2ZXIgfVxuICAgICAgfVxuICAgIHwge1xuICAgICAgICBwcm9maWxlOiBGZXRjaFByb2R1Y3RzTWFpblBhcmFtczxUPlsncHJvZmlsZSddXG4gICAgICAgIGZpbHRlcnM/OiBGZXRjaFByb2R1Y3RzRmlsdGVycyAmIHsgY3VzdG9tT3B0aW9ucz86IG5ldmVyOyB0YWdzPzogbmV2ZXIgfVxuICAgICAgfVxuICAgIHwge1xuICAgICAgICB0ZXJtOiBGZXRjaFByb2R1Y3RzTWFpblBhcmFtczxUPlsndGVybSddXG4gICAgICAgIGZpbHRlcnM/OiBGZXRjaFByb2R1Y3RzRmlsdGVycyAmIHsgY3VzdG9tT3B0aW9ucz86IG5ldmVyIH1cbiAgICAgIH1cbiAgKVxuXG50eXBlIEZldGNoUHJvZHVjdHNSZXNwb25zZSA9IHtcbiAgcHJvZHVjdHM6IHsgZGF0YTogUHJvZHVjdFtdOyB0b3RhbDogbnVtYmVyIH1cbiAgcGFnZXM6IG51bWJlclxuICBwcmljZXM6IHtcbiAgICBwcmljZTogeyBtaW46IG51bWJlcjsgbWF4OiBudW1iZXIgfVxuICAgIHN1YnNjcmliZXJQcmljZTogeyBtaW46IG51bWJlcjsgbWF4OiBudW1iZXIgfVxuICB9XG4gIGJyYW5kcz86IHN0cmluZ1tdXG59XG5cbkBJbmplY3RhYmxlKClcbmV4cG9ydCBjbGFzcyBDYXRhbG9nU2VydmljZTxUIGV4dGVuZHMgQ2F0ZWdvcnkgPSBDYXRlZ29yeT4ge1xuICBwcml2YXRlIHByb2R1Y3RzQnlUZXJtOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmdbXT4gPSB7fVxuXG4gIGNvbnN0cnVjdG9yKFxuICAgIEBJbmplY3QoJ1Byb2R1Y3RSZXBvc2l0b3J5JykgcHJpdmF0ZSByZWFkb25seSBwcm9kdWN0UmVwb3NpdG9yeTogUHJvZHVjdFJlcG9zaXRvcnksXG4gICAgQEluamVjdCgnQ2F0ZWdvcnlSZXBvc2l0b3J5JykgcHJpdmF0ZSByZWFkb25seSBjYXRlZ29yeVJlcG9zaXRvcnk6IENhdGVnb3J5UmVwb3NpdG9yeSxcbiAgICBASW5qZWN0KENBVEVHT1JZX1NUUlVDVFVSRSkgcHJpdmF0ZSByZWFkb25seSBjYXRlZ29yeVN0cnVjdHVyZUFkYXB0ZXI6IENhdGVnb3J5U3RydWN0dXJlQWRhcHRlcixcbiAgICBASW5qZWN0KERFRkFVTFRfU0hPUCkgcHJpdmF0ZSByZWFkb25seSBzaG9wOiBTaG9wcyxcbiAgICBwcml2YXRlIHJlYWRvbmx5IHByb2R1Y3RJbmRleDogUHJvZHVjdHNJbmRleCxcbiAgKSB7fVxuXG4gIGFzeW5jIGZldGNoUHJvZHVjdHMob3B0aW9uczogRmV0Y2hQcm9kdWN0c1BhcmFtczxUPik6IFByb21pc2U8RmV0Y2hQcm9kdWN0c1Jlc3BvbnNlPiB7XG4gICAgY29uc3QgbGltaXRzID0gdGhpcy5idWlsZExpbWl0UXVlcnkob3B0aW9ucylcblxuICAgIGlmICh0aGlzLmhhc1Byb2ZpbGUob3B0aW9ucykgJiYgb3B0aW9ucy5maWx0ZXJzPy5jdXN0b21PcHRpb25zKVxuICAgICAgdGhyb3cgbmV3IEludmFsaWRBcmd1bWVudEVycm9yKGBJdCBjb3VsZG4ndCBmaWxsZWQgY3VzdG9tT3B0aW9ucyB3aGVuIHByb2ZpbGUgaXMgZ2l2ZW5gKVxuICAgIGlmICh0aGlzLmhhc1Byb2ZpbGUob3B0aW9ucykgJiYgb3B0aW9ucy5maWx0ZXJzPy50YWdzKVxuICAgICAgdGhyb3cgbmV3IEludmFsaWRBcmd1bWVudEVycm9yKGBJdCBjb3VsZG4ndCBmaWxsZWQgdGFncyB3aGVuIHByb2ZpbGUgaXMgZ2l2ZW5gKVxuICAgIGlmICh0aGlzLmhhc1Rlcm0ob3B0aW9ucykgJiYgb3B0aW9ucy5maWx0ZXJzPy5jdXN0b21PcHRpb25zKVxuICAgICAgdGhyb3cgbmV3IEludmFsaWRBcmd1bWVudEVycm9yKGBJdCBjb3VsZG4ndCBmaWxsZWQgY3VzdG9tT3B0aW9ucyB3aGVuIHRlcm0gaXMgZ2l2ZW5gKVxuXG4gICAgcmV0dXJuIGF3YWl0IHRoaXMuZmluZENhdGFsb2cob3B0aW9ucywgbGltaXRzKS50aGVuKCh7IGRhdGEsIGNvdW50OiB0b3RhbCwgbWF4aW11bSwgbWluaW1hbCwgZGlzdGluY3QgfSkgPT4gKHtcbiAgICAgIHByb2R1Y3RzOiB7IGRhdGE6IGRhdGEubWFwKChwcm9kdWN0KSA9PiBSb3VuZFByb2R1Y3RQcmljZXNIZWxwZXIucm91bmRQcm9kdWN0UHJpY2VzKHByb2R1Y3QpKSwgdG90YWwgfSxcbiAgICAgIHBhZ2VzOiBNYXRoLmNlaWwodG90YWwgLyBsaW1pdHMubGltaXQpLFxuICAgICAgcHJpY2VzOiB7XG4gICAgICAgIHByaWNlOiB7IG1pbjogK21pbmltYWw/LnByaWNlPy5wcmljZT8udG9GaXhlZCgyKSwgbWF4OiArbWF4aW11bT8ucHJpY2U/LnByaWNlPy50b0ZpeGVkKDIpIH0sXG4gICAgICAgIHN1YnNjcmliZXJQcmljZToge1xuICAgICAgICAgIG1pbjogK21pbmltYWw/LnByaWNlPy5zdWJzY3JpYmVyUHJpY2U/LnRvRml4ZWQoMiksXG4gICAgICAgICAgbWF4OiArbWF4aW11bT8ucHJpY2U/LnN1YnNjcmliZXJQcmljZT8udG9GaXhlZCgyKSxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgICBicmFuZHM6IGRpc3RpbmN0Py5icmFuZCxcbiAgICB9KSlcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgZmluZENhdGFsb2coXG4gICAgb3B0aW9uczogRmV0Y2hQcm9kdWN0c1BhcmFtczxUPixcbiAgICBsaW1pdHM6IHtcbiAgICAgIGxpbWl0PzogbnVtYmVyXG4gICAgICBvZmZzZXQ/OiBudW1iZXJcbiAgICB9LFxuICApOiBQcm9taXNlPFJlcG9zaXRvcnlGaW5kUmVzdWx0PFByb2R1Y3Q+PiB7XG4gICAgaWYgKHRoaXMuaGFzVGVybShvcHRpb25zKSAmJiBvcHRpb25zLnNvcnQgPT09ICdtb3N0LXJlbGV2YW50Jykge1xuICAgICAgY29uc3QgcHJvZHVjdHNJZHMgPSBhd2FpdCB0aGlzLmZpbmRDYXRhbG9nSWRzQnlFbGFzdGljU2VhcmNoKG9wdGlvbnMudGVybSlcblxuICAgICAgcmV0dXJuIHRoaXMuZmluZENhdGFsb2dBbmRTb3J0QnlNb3N0UmV2ZWxhbnQocHJvZHVjdHNJZHMsIG9wdGlvbnMsIGxpbWl0cylcbiAgICB9XG5cbiAgICBpZiAodGhpcy5oYXNDYXRlZ29yeShvcHRpb25zKSAmJiBvcHRpb25zLnNvcnQgPT09ICdtb3N0LXJlbGV2YW50Jykge1xuICAgICAgY29uc3QgcHJvZHVjdHNJZHMgPSBvcHRpb25zLmNhdGVnb3J5LnByb2R1Y3RzPy5sZW5ndGhcbiAgICAgICAgPyBvcHRpb25zLmNhdGVnb3J5LnByb2R1Y3RzXG4gICAgICAgIDogYXdhaXQgdGhpcy5jYXRlZ29yeVJlcG9zaXRvcnkuZ2V0KHsgaWQ6IG9wdGlvbnMuY2F0ZWdvcnkuaWQgfSkudGhlbigoY2F0ZWdvcnlGb3VuZCkgPT4gY2F0ZWdvcnlGb3VuZC5wcm9kdWN0cylcblxuICAgICAgcmV0dXJuIHRoaXMuZmluZENhdGFsb2dBbmRTb3J0QnlNb3N0UmV2ZWxhbnQocHJvZHVjdHNJZHMsIG9wdGlvbnMsIGxpbWl0cylcbiAgICB9XG5cbiAgICBjb25zdCByZXBvUGFyYW1zOiBGaW5kUmVwb3NpdG9yeVBhcmFtczxQcm9kdWN0PiA9IHtcbiAgICAgIGZpbHRlcnM6IHtcbiAgICAgICAgLi4uKGF3YWl0IHRoaXMuYnVpbGRNYWluRmlsdGVyKG9wdGlvbnMpKSxcbiAgICAgICAgLi4udGhpcy5idWlsZEZpbHRlclF1ZXJ5KG9wdGlvbnM/LmZpbHRlcnMgfHwge30pLFxuICAgICAgfSxcbiAgICAgIC4uLihvcHRpb25zPy5zb3J0ID8geyBvcmRlckJ5OiB0aGlzLmJ1aWxkU29ydFF1ZXJ5KG9wdGlvbnM/LnNvcnQpIH0gOiB7fSksXG4gICAgICBsaW1pdHMsXG4gICAgICBvcHRpb25zOiB7XG4gICAgICAgIG1pbmltYWw6IFsncHJpY2UnXSxcbiAgICAgICAgbWF4aW11bTogWydwcmljZSddLFxuICAgICAgICAuLi4oIXRoaXMuaGFzQ2F0ZWdvcnkob3B0aW9ucykgPyB7IGRpc3RpbmN0OiBbJ2JyYW5kJ10gfSA6IHt9KSxcbiAgICAgIH0sXG4gICAgfVxuXG4gICAgaWYgKFsnYmlnZ2VzdC1wcmljZScsICdsb3dlc3QtcHJpY2UnLCAnYmlnZ2VzdC1kaXNjb3VudCcsICdiZXN0LXJhdGluZyddLmluY2x1ZGVzKG9wdGlvbnMuc29ydCkpXG4gICAgICByZXR1cm4gdGhpcy5wcm9kdWN0UmVwb3NpdG9yeS5maW5kQ2F0YWxvZyhyZXBvUGFyYW1zKVxuXG4gICAgcmV0dXJuIHRoaXMucHJvZHVjdFJlcG9zaXRvcnkuZmluZENhdGFsb2coXG4gICAgICByZXBvUGFyYW1zLFxuICAgICAgb3B0aW9ucz8ubWFpbkdlbmRlciB8fCB0aGlzLnNob3AgPT09IFNob3BzLk1FTlNNQVJLRVQgPyAnbWFsZScgOiAnZmVtYWxlJyxcbiAgICApXG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGJ1aWxkTWFpbkZpbHRlcih7XG4gICAgY2F0ZWdvcnksXG4gICAgcHJvZmlsZSxcbiAgICB0ZXJtLFxuICB9OiBGZXRjaFByb2R1Y3RzTWFpblBhcmFtczxUPik6IFByb21pc2U8UmVwb3NpdG9yeUZpbmRGaWVsdGVyczxQcm9kdWN0Pj4ge1xuICAgIGlmIChjYXRlZ29yeSkgcmV0dXJuIHRoaXMuY2F0ZWdvcnlTdHJ1Y3R1cmVBZGFwdGVyLmJ1aWxkUHJvZHVjdEZpbHRlckJ5Q2F0ZWdvcnkoY2F0ZWdvcnkpXG4gICAgaWYgKHByb2ZpbGUpIHJldHVybiB7IHRhZ3M6IHsgb3BlcmF0b3I6IFdoZXJlLkxJS0UsIHZhbHVlOiBwcm9maWxlIH0gfVxuICAgIGlmICh0ZXJtKVxuICAgICAgcmV0dXJuIHRoaXMucHJvZHVjdEluZGV4XG4gICAgICAgIC5zZWFyY2godGVybSwgOTk5LCB0aGlzLnNob3ApXG4gICAgICAgIC50aGVuKChkYXRhKSA9PiAoeyBpZDogeyBvcGVyYXRvcjogV2hlcmUuSU4sIHZhbHVlOiBkYXRhLmhpdHMubWFwKCh7IF9zb3VyY2UgfSkgPT4gX3NvdXJjZS5pZCkgfSB9KSlcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgZmluZENhdGFsb2dBbmRTb3J0QnlNb3N0UmV2ZWxhbnQoXG4gICAgcHJvZHVjdElkczogc3RyaW5nW10sXG4gICAgb3B0aW9uczogT21pdDxGZXRjaFByb2R1Y3RzT3B0aW9ucywgJ3NvcnQnPiAmIHtcbiAgICAgIHRlcm0/OiBGZXRjaFByb2R1Y3RzTWFpblBhcmFtczxUPlsndGVybSddXG4gICAgICBmaWx0ZXJzPzogRmV0Y2hQcm9kdWN0c0ZpbHRlcnMgJiB7IGN1c3RvbU9wdGlvbnM/OiBuZXZlciB9XG4gICAgfSxcbiAgICBsaW1pdHM6IHtcbiAgICAgIGxpbWl0PzogbnVtYmVyXG4gICAgICBvZmZzZXQ/OiBudW1iZXJcbiAgICB9LFxuICApOiBQcm9taXNlPFJlcG9zaXRvcnlGaW5kUmVzdWx0PFByb2R1Y3Q+PiB7XG4gICAgY29uc3QgdG90YWxSZXN1bHQgPSBhd2FpdCB0aGlzLnByb2R1Y3RSZXBvc2l0b3J5LmZpbmRDYXRhbG9nKFxuICAgICAge1xuICAgICAgICBmaWVsZHM6IFsnaWQnLCAnc3RvY2snXSxcbiAgICAgICAgZmlsdGVyczoge1xuICAgICAgICAgIGlkOiB7IG9wZXJhdG9yOiBXaGVyZS5JTiwgdmFsdWU6IHByb2R1Y3RJZHMgfSxcbiAgICAgICAgICAuLi50aGlzLmJ1aWxkRmlsdGVyUXVlcnkob3B0aW9ucz8uZmlsdGVycyB8fCB7fSksXG4gICAgICAgIH0sXG4gICAgICAgIG9wdGlvbnM6IHtcbiAgICAgICAgICBtaW5pbWFsOiBbJ3ByaWNlJ10sXG4gICAgICAgICAgbWF4aW11bTogWydwcmljZSddLFxuICAgICAgICAgIGRpc3RpbmN0OiBbJ2JyYW5kJ10sXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgICAgb3B0aW9ucz8ubWFpbkdlbmRlciB8fCB0aGlzLnNob3AgPT09IFNob3BzLk1FTlNNQVJLRVQgPyAnbWFsZScgOiAnZmVtYWxlJyxcbiAgICApXG5cbiAgICBjb25zdCBzdG9ja0RhdGEgPSB0b3RhbFJlc3VsdC5kYXRhLmZpbHRlcigocHJvZHVjdCkgPT4gcHJvZHVjdC5zdG9jay5xdWFudGl0eSA+IDApXG4gICAgY29uc3Qgc3RvY2tPdXQgPSB0b3RhbFJlc3VsdC5kYXRhLmZpbHRlcigocHJvZHVjdCkgPT4gcHJvZHVjdC5zdG9jay5xdWFudGl0eSA8PSAwKVxuICAgIGNvbnN0IHByb2R1Y3RJZHNTdG9jayA9IHByb2R1Y3RJZHMuZmlsdGVyKChwcm9kdWN0KSA9PiBzdG9ja0RhdGEuc29tZSgocmVzdWx0KSA9PiByZXN1bHQuaWQgPT0gcHJvZHVjdCkpXG4gICAgY29uc3QgcHJvZHVjdElkc1N0b2NrT3V0ID0gcHJvZHVjdElkcy5maWx0ZXIoKHByb2R1Y3QpID0+IHN0b2NrT3V0LnNvbWUoKHJlc3VsdCkgPT4gcmVzdWx0LmlkID09IHByb2R1Y3QpKVxuXG4gICAgY29uc3QgbGltaXRlZFByb2R1Y3RJZCA9IHByb2R1Y3RJZHNTdG9ja1xuICAgICAgLmNvbmNhdChwcm9kdWN0SWRzU3RvY2tPdXQpXG4gICAgICAuc2xpY2UobGltaXRzLm9mZnNldCwgbGltaXRzLm9mZnNldCArIGxpbWl0cy5saW1pdClcblxuICAgIGNvbnN0IG9yZGVyZWRJZCA9IHByb2R1Y3RJZHMuZmlsdGVyKChwcm9kdWN0KSA9PiBsaW1pdGVkUHJvZHVjdElkLmluY2x1ZGVzKHByb2R1Y3QpKVxuICAgIGNvbnN0IHByb2R1Y3RSZXN1bHQgPSBhd2FpdCB0aGlzLnByb2R1Y3RSZXBvc2l0b3J5LmZpbmRDYXRhbG9nKHtcbiAgICAgIGZpbHRlcnM6IHtcbiAgICAgICAgaWQ6IHsgb3BlcmF0b3I6IFdoZXJlLklOLCB2YWx1ZTogb3JkZXJlZElkIH0sXG4gICAgICB9LFxuICAgIH0pXG5cbiAgICByZXR1cm4ge1xuICAgICAgZGF0YTogbGltaXRlZFByb2R1Y3RJZC5tYXAoKGlkKSA9PiBwcm9kdWN0UmVzdWx0LmRhdGEuZmluZCgocHJvZHVjdCkgPT4gcHJvZHVjdC5pZCA9PT0gaWQpKS5maWx0ZXIoQm9vbGVhbiksXG4gICAgICBjb3VudDogdG90YWxSZXN1bHQuY291bnQsXG4gICAgICBtYXhpbXVtOiB0b3RhbFJlc3VsdC5tYXhpbXVtLFxuICAgICAgbWluaW1hbDogdG90YWxSZXN1bHQubWluaW1hbCxcbiAgICAgIGRpc3RpbmN0OiB0b3RhbFJlc3VsdC5kaXN0aW5jdCxcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGZpbmRDYXRhbG9nSWRzQnlFbGFzdGljU2VhcmNoKHRlcm06IHN0cmluZyk6IFByb21pc2U8c3RyaW5nW10+IHtcbiAgICBpZiAodGhpcy5wcm9kdWN0c0J5VGVybVt0ZXJtXSkgcmV0dXJuIHRoaXMucHJvZHVjdHNCeVRlcm1bdGVybV1cblxuICAgIHJldHVybiAodGhpcy5wcm9kdWN0c0J5VGVybVt0ZXJtXSA9IGF3YWl0IHRoaXMucHJvZHVjdEluZGV4XG4gICAgICAuc2VhcmNoKHRlcm0sIDk5OSwgdGhpcy5zaG9wKVxuICAgICAgLnRoZW4oKHsgaGl0czogcHJvZHVjdHMgfSkgPT4ge1xuICAgICAgICBjb25zdCB3aXRoU3RvY2sgPSBwcm9kdWN0cy5maWx0ZXIoKHsgX3NvdXJjZSB9KSA9PiBfc291cmNlLnN0b2NrLnF1YW50aXR5ID4gMClcbiAgICAgICAgY29uc3Qgd2l0aE91dFN0b2NrID0gcHJvZHVjdHMuZmlsdGVyKCh7IF9zb3VyY2UgfSkgPT4gX3NvdXJjZS5zdG9jay5xdWFudGl0eSA8PSAwKVxuICAgICAgICBjb25zdCBzb3J0ZWQgPSBbLi4ud2l0aFN0b2NrLCAuLi53aXRoT3V0U3RvY2tdXG5cbiAgICAgICAgcmV0dXJuIFsuLi5uZXcgU2V0KHNvcnRlZC5tYXAoKHsgX3NvdXJjZSB9KSA9PiBfc291cmNlLmlkKSldXG4gICAgICB9KSlcbiAgfVxuXG4gIHByaXZhdGUgYnVpbGRGaWx0ZXJRdWVyeSA9ICh7XG4gICAgY2x1YkRpc2NvdW50LFxuICAgIGJyYW5kcyxcbiAgICBwcmljZXMsXG4gICAgZ2VuZGVyLFxuICAgIHRhZ3MsXG4gICAgcmF0ZSxcbiAgICBjdXN0b21PcHRpb25zLFxuICB9OiBGZXRjaFByb2R1Y3RzRmlsdGVycyk6IFJlcG9zaXRvcnlGaW5kRmllbHRlcnM8UHJvZHVjdD4gPT4ge1xuICAgIGNvbnN0IGZpbHRlcnMgPSB7fSBhcyBSZXBvc2l0b3J5RmluZEZpZWx0ZXJzPFByb2R1Y3Q+XG5cbiAgICBpZiAoY2x1YkRpc2NvdW50Py5sZW5ndGgpXG4gICAgICBzZXQoZmlsdGVycywgJ3ByaWNlLnN1YnNjcmliZXJEaXNjb3VudFBlcmNlbnRhZ2UnLCB7IG9wZXJhdG9yOiBXaGVyZS5JTiwgdmFsdWU6IGNsdWJEaXNjb3VudCB9KVxuICAgIGlmIChicmFuZHM/Lmxlbmd0aCkgZmlsdGVycy5icmFuZCA9IHsgb3BlcmF0b3I6IFdoZXJlLklOLCB2YWx1ZTogYnJhbmRzIH1cbiAgICBpZiAoZ2VuZGVyPy5sZW5ndGgpIGZpbHRlcnMuZ2VuZGVyID0geyBvcGVyYXRvcjogV2hlcmUuSU4sIHZhbHVlOiBnZW5kZXIgfVxuICAgIGlmIChwcmljZXM/Lm1pbiB8fCBwcmljZXM/Lm1heClcbiAgICAgIHNldChmaWx0ZXJzLCBwcmljZXMuc3Vic2NyaWJlclByaWNlID8gJ3ByaWNlLnN1YnNjcmliZXJQcmljZScgOiAncHJpY2UucHJpY2UnLCBbXG4gICAgICAgIC4uLihwcmljZXMubWluID8gW3sgb3BlcmF0b3I6IFdoZXJlLkdURSwgdmFsdWU6IE1hdGgucm91bmQocHJpY2VzLm1pbikgfV0gOiBbXSksXG4gICAgICAgIC4uLihwcmljZXMubWF4ID8gW3sgb3BlcmF0b3I6IFdoZXJlLkxURSwgdmFsdWU6IE1hdGguY2VpbChwcmljZXMubWF4KSB9XSA6IFtdKSxcbiAgICAgIF0pXG4gICAgaWYgKHJhdGUpIGZpbHRlcnMucmF0ZSA9IHsgb3BlcmF0b3I6IFdoZXJlLkdURSwgdmFsdWU6IHJhdGUgfVxuICAgIGlmICh0YWdzPy5sZW5ndGgpIGZpbHRlcnMudGFncyA9IHsgb3BlcmF0b3I6IFdoZXJlLkxJS0UsIHZhbHVlOiB0YWdzIH1cbiAgICBpZiAoY3VzdG9tT3B0aW9ucz8ubGVuZ3RoKSBmaWx0ZXJzLmZpbHRlcnMgPSB7IG9wZXJhdG9yOiBXaGVyZS5MSUtFLCB2YWx1ZTogY3VzdG9tT3B0aW9ucyB9XG5cbiAgICByZXR1cm4gZmlsdGVyc1xuICB9XG5cbiAgcHJpdmF0ZSBidWlsZFNvcnRRdWVyeSA9IChzb3J0OiBQcm9kdWN0U29ydCk6IFJlcG9zaXRvcnlPcmRlckJ5PFByb2R1Y3Q+ID0+IHtcbiAgICBpZiAoIXNvcnQgfHwgc29ydCA9PT0gJ21vc3QtcmVsZXZhbnQnKSByZXR1cm4ge31cblxuICAgIGlmIChzb3J0ID09PSAnYmVzdC1zZWxsZXJzJykgcmV0dXJuIHsgc2hvcHBpbmdDb3VudDogJ2Rlc2MnIH1cbiAgICBpZiAoc29ydCA9PT0gJ2JpZ2dlc3QtcHJpY2UnKSByZXR1cm4geyBzdWJzY3JpYmVyUHJpY2U6ICdkZXNjJyB9IGFzIGFueVxuICAgIGlmIChzb3J0ID09PSAnbG93ZXN0LXByaWNlJykgcmV0dXJuIHsgc3Vic2NyaWJlclByaWNlOiAnYXNjJyB9IGFzIGFueVxuICAgIGlmIChzb3J0ID09PSAnYmVzdC1yYXRpbmcnKSByZXR1cm4geyByYXRlOiAnZGVzYycgfVxuICAgIGlmIChzb3J0ID09PSAnbmV3cycpIHJldHVybiB7IGNyZWF0ZWRBdDogJ2Rlc2MnIH1cbiAgICBpZiAoc29ydCA9PT0gJ2JpZ2dlc3QtZGlzY291bnQnKSByZXR1cm4geyBzdWJzY3JpYmVyRGlzY291bnRQZXJjZW50YWdlOiAnZGVzYycgfSBhcyBhbnlcbiAgfVxuXG4gIHByaXZhdGUgYnVpbGRMaW1pdFF1ZXJ5ID0gKG9wdGlvbnM6IHsgcGFnZT86IG51bWJlcjsgcGVyUGFnZT86IG51bWJlciB9KTogeyBsaW1pdD86IG51bWJlcjsgb2Zmc2V0PzogbnVtYmVyIH0gPT4ge1xuICAgIGNvbnN0IGxpbWl0ID0gb3B0aW9ucz8ucGVyUGFnZSB8fCAyMFxuXG4gICAgcmV0dXJuIHtcbiAgICAgIGxpbWl0LFxuICAgICAgb2Zmc2V0OiAoKG9wdGlvbnM/LnBhZ2UgfHwgMSkgLSAxKSAqIGxpbWl0LFxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgaGFzUHJvZmlsZSA9IChcbiAgICBvcHRpb25zOiBGZXRjaFByb2R1Y3RzUGFyYW1zPFQ+LFxuICApOiBvcHRpb25zIGlzIEZldGNoUHJvZHVjdHNPcHRpb25zICYge1xuICAgIHByb2ZpbGU6IEZldGNoUHJvZHVjdHNNYWluUGFyYW1zPFQ+Wydwcm9maWxlJ11cbiAgICBmaWx0ZXJzPzogRmV0Y2hQcm9kdWN0c0ZpbHRlcnMgJiB7IGN1c3RvbU9wdGlvbnM/OiBuZXZlcjsgdGFncz86IG5ldmVyIH1cbiAgfSA9PiAncHJvZmlsZScgaW4gb3B0aW9uc1xuXG4gIHByaXZhdGUgaGFzVGVybSA9IChcbiAgICBvcHRpb25zOiBGZXRjaFByb2R1Y3RzUGFyYW1zPFQ+LFxuICApOiBvcHRpb25zIGlzIEZldGNoUHJvZHVjdHNPcHRpb25zICYge1xuICAgIHRlcm06IEZldGNoUHJvZHVjdHNNYWluUGFyYW1zPFQ+Wyd0ZXJtJ11cbiAgICBmaWx0ZXJzPzogRmV0Y2hQcm9kdWN0c0ZpbHRlcnMgJiB7IGN1c3RvbU9wdGlvbnM/OiBuZXZlciB9XG4gIH0gPT4gJ3Rlcm0nIGluIG9wdGlvbnNcblxuICBwcml2YXRlIGhhc0NhdGVnb3J5ID0gKFxuICAgIG9wdGlvbnM6IEZldGNoUHJvZHVjdHNQYXJhbXM8VD4sXG4gICk6IG9wdGlvbnMgaXMgRmV0Y2hQcm9kdWN0c09wdGlvbnMgJiB7XG4gICAgY2F0ZWdvcnk6IEZldGNoUHJvZHVjdHNNYWluUGFyYW1zPFQ+WydjYXRlZ29yeSddXG4gICAgZmlsdGVycz86IEZldGNoUHJvZHVjdHNGaWx0ZXJzICYgeyBjdXN0b21PcHRpb25zPzogbmV2ZXIgfVxuICB9ID0+ICdjYXRlZ29yeScgaW4gb3B0aW9uc1xufVxuIl19
1
+ import { Inject, Injectable } from '@angular/core';
2
+ import { InvalidArgumentError, ProductsIndex, RoundProductPricesHelper, set, Shops, Where, } 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, categoryRepository, categoryStructureAdapter, shop, productIndex) {
8
+ this.productRepository = productRepository;
9
+ this.categoryRepository = categoryRepository;
10
+ this.categoryStructureAdapter = categoryStructureAdapter;
11
+ this.shop = shop;
12
+ this.productIndex = productIndex;
13
+ this.productsByTerm = {};
14
+ this.buildFilterQuery = ({ clubDiscount, brands, prices, gender, tags, rate, customOptions, }) => {
15
+ const filters = {};
16
+ if (clubDiscount?.length)
17
+ set(filters, 'price.subscriberDiscountPercentage', { operator: Where.IN, value: clubDiscount });
18
+ if (brands?.length)
19
+ filters.brand = { operator: Where.IN, value: brands };
20
+ if (gender?.length)
21
+ filters.gender = { operator: Where.IN, value: gender };
22
+ if (prices?.min || prices?.max)
23
+ set(filters, prices.subscriberPrice ? 'price.subscriberPrice' : 'price.price', [
24
+ ...(prices.min ? [{ operator: Where.GTE, value: Math.round(prices.min) }] : []),
25
+ ...(prices.max ? [{ operator: Where.LTE, value: Math.ceil(prices.max) }] : []),
26
+ ]);
27
+ if (rate)
28
+ filters.rate = { operator: Where.GTE, value: rate };
29
+ if (tags?.length)
30
+ filters.tags = { operator: Where.LIKE, value: tags };
31
+ if (customOptions?.length)
32
+ filters.filters = { operator: Where.LIKE, value: customOptions };
33
+ return filters;
34
+ };
35
+ this.buildSortQuery = (sort) => {
36
+ if (!sort || sort === 'most-relevant')
37
+ return {};
38
+ if (sort === 'best-sellers')
39
+ return { shoppingCount: 'desc' };
40
+ if (sort === 'biggest-price')
41
+ return { subscriberPrice: 'desc' };
42
+ if (sort === 'lowest-price')
43
+ return { subscriberPrice: 'asc' };
44
+ if (sort === 'best-rating')
45
+ return { rate: 'desc' };
46
+ if (sort === 'news')
47
+ return { createdAt: 'desc' };
48
+ if (sort === 'biggest-discount')
49
+ return { subscriberDiscountPercentage: 'desc' };
50
+ };
51
+ this.buildLimitQuery = (options) => {
52
+ const limit = options?.perPage || 20;
53
+ return {
54
+ limit,
55
+ offset: ((options?.page || 1) - 1) * limit,
56
+ };
57
+ };
58
+ this.hasProfile = (options) => 'profile' in options;
59
+ this.hasTerm = (options) => 'term' in options;
60
+ this.hasCategory = (options) => 'category' in options;
61
+ }
62
+ async fetchProducts(options) {
63
+ const limits = this.buildLimitQuery(options);
64
+ if (this.hasProfile(options) && options.filters?.customOptions)
65
+ throw new InvalidArgumentError(`It couldn't filled customOptions when profile is given`);
66
+ if (this.hasProfile(options) && options.filters?.tags)
67
+ throw new InvalidArgumentError(`It couldn't filled tags when profile is given`);
68
+ if (this.hasTerm(options) && options.filters?.customOptions)
69
+ throw new InvalidArgumentError(`It couldn't filled customOptions when term is given`);
70
+ return await this.findCatalog(options, limits).then(({ data, count: total, maximum, minimal, distinct }) => ({
71
+ products: { data: data.map((product) => RoundProductPricesHelper.roundProductPrices(product)), total },
72
+ pages: Math.ceil(total / limits.limit),
73
+ prices: {
74
+ price: { min: +minimal?.price?.price?.toFixed(2), max: +maximum?.price?.price?.toFixed(2) },
75
+ subscriberPrice: {
76
+ min: +minimal?.price?.subscriberPrice?.toFixed(2),
77
+ max: +maximum?.price?.subscriberPrice?.toFixed(2),
78
+ },
79
+ },
80
+ brands: distinct?.brand,
81
+ }));
82
+ }
83
+ async findCatalog(options, limits) {
84
+ if (this.hasTerm(options) && options.sort === 'most-relevant') {
85
+ const productsIds = await this.findCatalogIdsByElasticSearch(options.term);
86
+ return this.findCatalogAndSortByMostRevelant(productsIds, options, limits);
87
+ }
88
+ if (this.hasCategory(options) && options.sort === 'most-relevant') {
89
+ const productsIds = await this.productRepository
90
+ .find({
91
+ filters: {
92
+ ...(await this.buildMainFilter(options)),
93
+ },
94
+ })
95
+ .then((products) => products.data.map((product) => product.id));
96
+ // const productsIds = options.category.products?.length
97
+ // ? options.category.products
98
+ // : await this.categoryRepository.get({ id: options.category.id }).then((categoryFound) => categoryFound.products)
99
+ return this.findCatalogAndSortByMostRevelant(productsIds, options, limits);
100
+ }
101
+ const repoParams = {
102
+ filters: {
103
+ ...(await this.buildMainFilter(options)),
104
+ ...this.buildFilterQuery(options?.filters || {}),
105
+ },
106
+ ...(options?.sort ? { orderBy: this.buildSortQuery(options?.sort) } : {}),
107
+ limits,
108
+ options: {
109
+ minimal: ['price'],
110
+ maximum: ['price'],
111
+ ...(!this.hasCategory(options) ? { distinct: ['brand'] } : {}),
112
+ },
113
+ };
114
+ if (['biggest-price', 'lowest-price', 'biggest-discount', 'best-rating'].includes(options.sort))
115
+ return this.productRepository.findCatalog(repoParams);
116
+ return this.productRepository.findCatalog(repoParams, options?.mainGender || this.shop === Shops.MENSMARKET ? 'male' : 'female');
117
+ }
118
+ async buildMainFilter({ category, profile, term, }) {
119
+ if (category)
120
+ return this.categoryStructureAdapter.buildProductFilterByCategory(category);
121
+ if (profile)
122
+ return { tags: { operator: Where.LIKE, value: profile } };
123
+ if (term)
124
+ return this.productIndex
125
+ .search(term, 999, this.shop)
126
+ .then((data) => ({ id: { operator: Where.IN, value: data.hits.map(({ _source }) => _source.id) } }));
127
+ }
128
+ async findCatalogAndSortByMostRevelant(productIds, options, limits) {
129
+ const totalResult = await this.productRepository.findCatalog({
130
+ fields: ['id', 'stock'],
131
+ filters: {
132
+ id: { operator: Where.IN, value: productIds },
133
+ ...this.buildFilterQuery(options?.filters || {}),
134
+ },
135
+ options: {
136
+ minimal: ['price'],
137
+ maximum: ['price'],
138
+ distinct: ['brand'],
139
+ },
140
+ }, options?.mainGender || this.shop === Shops.MENSMARKET ? 'male' : 'female');
141
+ const stockData = totalResult.data.filter((product) => product.stock.quantity > 0);
142
+ const stockOut = totalResult.data.filter((product) => product.stock.quantity <= 0);
143
+ const productIdsStock = productIds.filter((product) => stockData.some((result) => result.id == product));
144
+ const productIdsStockOut = productIds.filter((product) => stockOut.some((result) => result.id == product));
145
+ const limitedProductId = productIdsStock
146
+ .concat(productIdsStockOut)
147
+ .slice(limits.offset, limits.offset + limits.limit);
148
+ const orderedId = productIds.filter((product) => limitedProductId.includes(product));
149
+ const productResult = await this.productRepository.findCatalog({
150
+ filters: {
151
+ id: { operator: Where.IN, value: orderedId },
152
+ },
153
+ });
154
+ return {
155
+ data: limitedProductId.map((id) => productResult.data.find((product) => product.id === id)).filter(Boolean),
156
+ count: totalResult.count,
157
+ maximum: totalResult.maximum,
158
+ minimal: totalResult.minimal,
159
+ distinct: totalResult.distinct,
160
+ };
161
+ }
162
+ async findCatalogIdsByElasticSearch(term) {
163
+ if (this.productsByTerm[term])
164
+ return this.productsByTerm[term];
165
+ return (this.productsByTerm[term] = await this.productIndex
166
+ .search(term, 999, this.shop)
167
+ .then(({ hits: products }) => {
168
+ const withStock = products.filter(({ _source }) => _source.stock.quantity > 0);
169
+ const withOutStock = products.filter(({ _source }) => _source.stock.quantity <= 0);
170
+ const sorted = [...withStock, ...withOutStock];
171
+ return [...new Set(sorted.map(({ _source }) => _source.id))];
172
+ }));
173
+ }
174
+ }
175
+ CatalogService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: CatalogService, deps: [{ token: 'ProductRepository' }, { token: 'CategoryRepository' }, { token: CATEGORY_STRUCTURE }, { token: DEFAULT_SHOP }, { token: i1.ProductsIndex }], target: i0.ɵɵFactoryTarget.Injectable });
176
+ CatalogService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: CatalogService });
177
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: CatalogService, decorators: [{
178
+ type: Injectable
179
+ }], ctorParameters: function () { return [{ type: undefined, decorators: [{
180
+ type: Inject,
181
+ args: ['ProductRepository']
182
+ }] }, { type: undefined, decorators: [{
183
+ type: Inject,
184
+ args: ['CategoryRepository']
185
+ }] }, { type: undefined, decorators: [{
186
+ type: Inject,
187
+ args: [CATEGORY_STRUCTURE]
188
+ }] }, { type: i1.Shops, decorators: [{
189
+ type: Inject,
190
+ args: [DEFAULT_SHOP]
191
+ }] }, { type: i1.ProductsIndex }]; } });
192
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2F0YWxvZy5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvY29ubmVjdC1hbmd1bGFyL3NyYy9zZXJ2aWNlcy9jYXRhbG9nL2NhdGFsb2cuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsTUFBTSxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQTtBQUNsRCxPQUFPLEVBSUwsb0JBQW9CLEVBSXBCLGFBQWEsRUFJYix3QkFBd0IsRUFDeEIsR0FBRyxFQUNILEtBQUssRUFDTCxLQUFLLEdBQ04sTUFBTSxtQkFBbUIsQ0FBQTtBQUMxQixPQUFPLEVBQUUsa0JBQWtCLEVBQUUsWUFBWSxFQUFFLE1BQU0sY0FBYyxDQUFBOzs7QUFzRC9ELE1BQU0sT0FBTyxjQUFjO0lBR3pCLFlBQ2dELGlCQUFvQyxFQUNuQyxrQkFBc0MsRUFDeEMsd0JBQWtELEVBQ3hELElBQVcsRUFDakMsWUFBMkI7UUFKRSxzQkFBaUIsR0FBakIsaUJBQWlCLENBQW1CO1FBQ25DLHVCQUFrQixHQUFsQixrQkFBa0IsQ0FBb0I7UUFDeEMsNkJBQXdCLEdBQXhCLHdCQUF3QixDQUEwQjtRQUN4RCxTQUFJLEdBQUosSUFBSSxDQUFPO1FBQ2pDLGlCQUFZLEdBQVosWUFBWSxDQUFlO1FBUHRDLG1CQUFjLEdBQTZCLEVBQUUsQ0FBQTtRQXFLN0MscUJBQWdCLEdBQUcsQ0FBQyxFQUMxQixZQUFZLEVBQ1osTUFBTSxFQUNOLE1BQU0sRUFDTixNQUFNLEVBQ04sSUFBSSxFQUNKLElBQUksRUFDSixhQUFhLEdBQ1EsRUFBbUMsRUFBRTtZQUMxRCxNQUFNLE9BQU8sR0FBRyxFQUFxQyxDQUFBO1lBRXJELElBQUksWUFBWSxFQUFFLE1BQU07Z0JBQ3RCLEdBQUcsQ0FBQyxPQUFPLEVBQUUsb0NBQW9DLEVBQUUsRUFBRSxRQUFRLEVBQUUsS0FBSyxDQUFDLEVBQUUsRUFBRSxLQUFLLEVBQUUsWUFB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QW1COzswQkFDMUIsTUFBTTsyQkFBQyxvQkFBb0I7OzBCQUMzQixNQUFNOzJCQUFDLGtCQUFrQjs7MEJBQ3pCLE1BQU07MkJBQUMsWUFBWSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdCwgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnXHJcbmltcG9ydCB7XHJcbiAgQ2F0ZWdvcnksXHJcbiAgQ2F0ZWdvcnlSZXBvc2l0b3J5LFxyXG4gIEZpbmRSZXBvc2l0b3J5UGFyYW1zLFxyXG4gIEludmFsaWRBcmd1bWVudEVycm9yLFxyXG4gIFByb2R1Y3QsXHJcbiAgUHJvZHVjdEdlbmRlcixcclxuICBQcm9kdWN0UmVwb3NpdG9yeSxcclxuICBQcm9kdWN0c0luZGV4LFxyXG4gIFJlcG9zaXRvcnlGaW5kRmllbHRlcnMsXHJcbiAgUmVwb3NpdG9yeUZpbmRSZXN1bHQsXHJcbiAgUmVwb3NpdG9yeU9yZGVyQnksXHJcbiAgUm91bmRQcm9kdWN0UHJpY2VzSGVscGVyLFxyXG4gIHNldCxcclxuICBTaG9wcyxcclxuICBXaGVyZSxcclxufSBmcm9tICdAaW5mcmFiNGEvY29ubmVjdCdcclxuaW1wb3J0IHsgQ0FURUdPUllfU1RSVUNUVVJFLCBERUZBVUxUX1NIT1AgfSBmcm9tICcuLi8uLi9jb25zdHMnXHJcbmltcG9ydCB7IENhdGVnb3J5U3RydWN0dXJlQWRhcHRlciB9IGZyb20gJy4vYWRhcHRlcnMnXHJcbmltcG9ydCB7IFByb2R1Y3RTb3J0IH0gZnJvbSAnLi90eXBlcy9wcm9kdWN0LXNvcnQudHlwZSdcclxuXHJcbnR5cGUgRmV0Y2hQcm9kdWN0c0ZpbHRlcnMgPSB7XHJcbiAgY2x1YkRpc2NvdW50PzogbnVtYmVyW11cclxuICBicmFuZHM/OiBzdHJpbmdbXVxyXG4gIHByaWNlcz86IHsgbWluPzogbnVtYmVyOyBtYXg/OiBudW1iZXI7IHN1YnNjcmliZXJQcmljZT86IGJvb2xlYW4gfVxyXG4gIGdlbmRlcj86IFByb2R1Y3RHZW5kZXJbXVxyXG4gIHJhdGU/OiBudW1iZXJcclxuICBjdXN0b21PcHRpb25zPzogc3RyaW5nW11cclxuICB0YWdzPzogc3RyaW5nW11cclxufVxyXG5cclxudHlwZSBGZXRjaFByb2R1Y3RzT3B0aW9ucyA9IHtcclxuICBwYWdlPzogbnVtYmVyXHJcbiAgcGVyUGFnZT86IG51bWJlclxyXG4gIHNvcnQ/OiBQcm9kdWN0U29ydFxyXG4gIG1haW5HZW5kZXI/OiBQcm9kdWN0R2VuZGVyXHJcbn1cclxuXHJcbnR5cGUgRmV0Y2hQcm9kdWN0c01haW5QYXJhbXM8VCBleHRlbmRzIENhdGVnb3J5PiA9IHtcclxuICBjYXRlZ29yeT86IFRcclxuICBwcm9maWxlPzogc3RyaW5nW11cclxuICB0ZXJtPzogc3RyaW5nXHJcbn1cclxuXHJcbnR5cGUgRmV0Y2hQcm9kdWN0c1BhcmFtczxUIGV4dGVuZHMgQ2F0ZWdvcnk+ID0gRmV0Y2hQcm9kdWN0c09wdGlvbnMgJlxyXG4gIChcclxuICAgIHwge1xyXG4gICAgICAgIGNhdGVnb3J5OiBGZXRjaFByb2R1Y3RzTWFpblBhcmFtczxUPlsnY2F0ZWdvcnknXVxyXG4gICAgICAgIGZpbHRlcnM/OiBGZXRjaFByb2R1Y3RzRmlsdGVycyAmIHsgY3VzdG9tT3B0aW9ucz86IG5ldmVyIH1cclxuICAgICAgfVxyXG4gICAgfCB7XHJcbiAgICAgICAgcHJvZmlsZTogRmV0Y2hQcm9kdWN0c01haW5QYXJhbXM8VD5bJ3Byb2ZpbGUnXVxyXG4gICAgICAgIGZpbHRlcnM/OiBGZXRjaFByb2R1Y3RzRmlsdGVycyAmIHsgY3VzdG9tT3B0aW9ucz86IG5ldmVyOyB0YWdzPzogbmV2ZXIgfVxyXG4gICAgICB9XHJcbiAgICB8IHtcclxuICAgICAgICB0ZXJtOiBGZXRjaFByb2R1Y3RzTWFpblBhcmFtczxUPlsndGVybSddXHJcbiAgICAgICAgZmlsdGVycz86IEZldGNoUHJvZHVjdHNGaWx0ZXJzICYgeyBjdXN0b21PcHRpb25zPzogbmV2ZXIgfVxyXG4gICAgICB9XHJcbiAgKVxyXG5cclxudHlwZSBGZXRjaFByb2R1Y3RzUmVzcG9uc2UgPSB7XHJcbiAgcHJvZHVjdHM6IHsgZGF0YTogUHJvZHVjdFtdOyB0b3RhbDogbnVtYmVyIH1cclxuICBwYWdlczogbnVtYmVyXHJcbiAgcHJpY2VzOiB7XHJcbiAgICBwcmljZTogeyBtaW46IG51bWJlcjsgbWF4OiBudW1iZXIgfVxyXG4gICAgc3Vic2NyaWJlclByaWNlOiB7IG1pbjogbnVtYmVyOyBtYXg6IG51bWJlciB9XHJcbiAgfVxyXG4gIGJyYW5kcz86IHN0cmluZ1tdXHJcbn1cclxuXHJcbkBJbmplY3RhYmxlKClcclxuZXhwb3J0IGNsYXNzIENhdGFsb2dTZXJ2aWNlPFQgZXh0ZW5kcyBDYXRlZ29yeSA9IENhdGVnb3J5PiB7XHJcbiAgcHJpdmF0ZSBwcm9kdWN0c0J5VGVybTogUmVjb3JkPHN0cmluZywgc3RyaW5nW10+ID0ge31cclxuXHJcbiAgY29uc3RydWN0b3IoXHJcbiAgICBASW5qZWN0KCdQcm9kdWN0UmVwb3NpdG9yeScpIHByaXZhdGUgcmVhZG9ubHkgcHJvZHVjdFJlcG9zaXRvcnk6IFByb2R1Y3RSZXBvc2l0b3J5LFxyXG4gICAgQEluamVjdCgnQ2F0ZWdvcnlSZXBvc2l0b3J5JykgcHJpdmF0ZSByZWFkb25seSBjYXRlZ29yeVJlcG9zaXRvcnk6IENhdGVnb3J5UmVwb3NpdG9yeSxcclxuICAgIEBJbmplY3QoQ0FURUdPUllfU1RSVUNUVVJFKSBwcml2YXRlIHJlYWRvbmx5IGNhdGVnb3J5U3RydWN0dXJlQWRhcHRlcjogQ2F0ZWdvcnlTdHJ1Y3R1cmVBZGFwdGVyLFxyXG4gICAgQEluamVjdChERUZBVUxUX1NIT1ApIHByaXZhdGUgcmVhZG9ubHkgc2hvcDogU2hvcHMsXHJcbiAgICBwcml2YXRlIHJlYWRvbmx5IHByb2R1Y3RJbmRleDogUHJvZHVjdHNJbmRleCxcclxuICApIHt9XHJcblxyXG4gIGFzeW5jIGZldGNoUHJvZHVjdHMob3B0aW9uczogRmV0Y2hQcm9kdWN0c1BhcmFtczxUPik6IFByb21pc2U8RmV0Y2hQcm9kdWN0c1Jlc3BvbnNlPiB7XHJcbiAgICBjb25zdCBsaW1pdHMgPSB0aGlzLmJ1aWxkTGltaXRRdWVyeShvcHRpb25zKVxyXG5cclxuICAgIGlmICh0aGlzLmhhc1Byb2ZpbGUob3B0aW9ucykgJiYgb3B0aW9ucy5maWx0ZXJzPy5jdXN0b21PcHRpb25zKVxyXG4gICAgICB0aHJvdyBuZXcgSW52YWxpZEFyZ3VtZW50RXJyb3IoYEl0IGNvdWxkbid0IGZpbGxlZCBjdXN0b21PcHRpb25zIHdoZW4gcHJvZmlsZSBpcyBnaXZlbmApXHJcbiAgICBpZiAodGhpcy5oYXNQcm9maWxlKG9wdGlvbnMpICYmIG9wdGlvbnMuZmlsdGVycz8udGFncylcclxuICAgICAgdGhyb3cgbmV3IEludmFsaWRBcmd1bWVudEVycm9yKGBJdCBjb3VsZG4ndCBmaWxsZWQgdGFncyB3aGVuIHByb2ZpbGUgaXMgZ2l2ZW5gKVxyXG4gICAgaWYgKHRoaXMuaGFzVGVybShvcHRpb25zKSAmJiBvcHRpb25zLmZpbHRlcnM/LmN1c3RvbU9wdGlvbnMpXHJcbiAgICAgIHRocm93IG5ldyBJbnZhbGlkQXJndW1lbnRFcnJvcihgSXQgY291bGRuJ3QgZmlsbGVkIGN1c3RvbU9wdGlvbnMgd2hlbiB0ZXJtIGlzIGdpdmVuYClcclxuXHJcbiAgICByZXR1cm4gYXdhaXQgdGhpcy5maW5kQ2F0YWxvZyhvcHRpb25zLCBsaW1pdHMpLnRoZW4oKHsgZGF0YSwgY291bnQ6IHRvdGFsLCBtYXhpbXVtLCBtaW5pbWFsLCBkaXN0aW5jdCB9KSA9PiAoe1xyXG4gICAgICBwcm9kdWN0czogeyBkYXRhOiBkYXRhLm1hcCgocHJvZHVjdCkgPT4gUm91bmRQcm9kdWN0UHJpY2VzSGVscGVyLnJvdW5kUHJvZHVjdFByaWNlcyhwcm9kdWN0KSksIHRvdGFsIH0sXHJcbiAgICAgIHBhZ2VzOiBNYXRoLmNlaWwodG90YWwgLyBsaW1pdHMubGltaXQpLFxyXG4gICAgICBwcmljZXM6IHtcclxuICAgICAgICBwcmljZTogeyBtaW46ICttaW5pbWFsPy5wcmljZT8ucHJpY2U/LnRvRml4ZWQoMiksIG1heDogK21heGltdW0/LnByaWNlPy5wcmljZT8udG9GaXhlZCgyKSB9LFxyXG4gICAgICAgIHN1YnNjcmliZXJQcmljZToge1xyXG4gICAgICAgICAgbWluOiArbWluaW1hbD8ucHJpY2U/LnN1YnNjcmliZXJQcmljZT8udG9GaXhlZCgyKSxcclxuICAgICAgICAgIG1heDogK21heGltdW0/LnByaWNlPy5zdWJzY3JpYmVyUHJpY2U/LnRvRml4ZWQoMiksXHJcbiAgICAgICAgfSxcclxuICAgICAgfSxcclxuICAgICAgYnJhbmRzOiBkaXN0aW5jdD8uYnJhbmQsXHJcbiAgICB9KSlcclxuICB9XHJcblxyXG4gIHByaXZhdGUgYXN5bmMgZmluZENhdGFsb2coXHJcbiAgICBvcHRpb25zOiBGZXRjaFByb2R1Y3RzUGFyYW1zPFQ+LFxyXG4gICAgbGltaXRzOiB7XHJcbiAgICAgIGxpbWl0PzogbnVtYmVyXHJcbiAgICAgIG9mZnNldD86IG51bWJlclxyXG4gICAgfSxcclxuICApOiBQcm9taXNlPFJlcG9zaXRvcnlGaW5kUmVzdWx0PFByb2R1Y3Q+PiB7XHJcbiAgICBpZiAodGhpcy5oYXNUZXJtKG9wdGlvbnMpICYmIG9wdGlvbnMuc29ydCA9PT0gJ21vc3QtcmVsZXZhbnQnKSB7XHJcbiAgICAgIGNvbnN0IHByb2R1Y3RzSWRzID0gYXdhaXQgdGhpcy5maW5kQ2F0YWxvZ0lkc0J5RWxhc3RpY1NlYXJjaChvcHRpb25zLnRlcm0pXHJcblxyXG4gICAgICByZXR1cm4gdGhpcy5maW5kQ2F0YWxvZ0FuZFNvcnRCeU1vc3RSZXZlbGFudChwcm9kdWN0c0lkcywgb3B0aW9ucywgbGltaXRzKVxyXG4gICAgfVxyXG5cclxuICAgIGlmICh0aGlzLmhhc0NhdGVnb3J5KG9wdGlvbnMpICYmIG9wdGlvbnMuc29ydCA9PT0gJ21vc3QtcmVsZXZhbnQnKSB7XHJcbiAgICAgIGNvbnN0IHByb2R1Y3RzSWRzID0gYXdhaXQgdGhpcy5wcm9kdWN0UmVwb3NpdG9yeVxyXG4gICAgICAgIC5maW5kKHtcclxuICAgICAgICAgIGZpbHRlcnM6IHtcclxuICAgICAgICAgICAgLi4uKGF3YWl0IHRoaXMuYnVpbGRNYWluRmlsdGVyKG9wdGlvbnMpKSxcclxuICAgICAgICAgIH0sXHJcbiAgICAgICAgfSlcclxuICAgICAgICAudGhlbigocHJvZHVjdHMpID0+IHByb2R1Y3RzLmRhdGEubWFwKChwcm9kdWN0KSA9PiBwcm9kdWN0LmlkKSlcclxuXHJcbiAgICAgIC8vIGNvbnN0IHByb2R1Y3RzSWRzID0gb3B0aW9ucy5jYXRlZ29yeS5wcm9kdWN0cz8ubGVuZ3RoXHJcbiAgICAgIC8vICAgPyBvcHRpb25zLmNhdGVnb3J5LnByb2R1Y3RzXHJcbiAgICAgIC8vICAgOiBhd2FpdCB0aGlzLmNhdGVnb3J5UmVwb3NpdG9yeS5nZXQoeyBpZDogb3B0aW9ucy5jYXRlZ29yeS5pZCB9KS50aGVuKChjYXRlZ29yeUZvdW5kKSA9PiBjYXRlZ29yeUZvdW5kLnByb2R1Y3RzKVxyXG5cclxuICAgICAgcmV0dXJuIHRoaXMuZmluZENhdGFsb2dBbmRTb3J0QnlNb3N0UmV2ZWxhbnQocHJvZHVjdHNJZHMsIG9wdGlvbnMsIGxpbWl0cylcclxuICAgIH1cclxuXHJcbiAgICBjb25zdCByZXBvUGFyYW1zOiBGaW5kUmVwb3NpdG9yeVBhcmFtczxQcm9kdWN0PiA9IHtcclxuICAgICAgZmlsdGVyczoge1xyXG4gICAgICAgIC4uLihhd2FpdCB0aGlzLmJ1aWxkTWFpbkZpbHRlcihvcHRpb25zKSksXHJcbiAgICAgICAgLi4udGhpcy5idWlsZEZpbHRlclF1ZXJ5KG9wdGlvbnM/LmZpbHRlcnMgfHwge30pLFxyXG4gICAgICB9LFxyXG4gICAgICAuLi4ob3B0aW9ucz8uc29ydCA/IHsgb3JkZXJCeTogdGhpcy5idWlsZFNvcnRRdWVyeShvcHRpb25zPy5zb3J0KSB9IDoge30pLFxyXG4gICAgICBsaW1pdHMsXHJcbiAgICAgIG9wdGlvbnM6IHtcclxuICAgICAgICBtaW5pbWFsOiBbJ3ByaWNlJ10sXHJcbiAgICAgICAgbWF4aW11bTogWydwcmljZSddLFxyXG4gICAgICAgIC4uLighdGhpcy5oYXNDYXRlZ29yeShvcHRpb25zKSA/IHsgZGlzdGluY3Q6IFsnYnJhbmQnXSB9IDoge30pLFxyXG4gICAgICB9LFxyXG4gICAgfVxyXG5cclxuICAgIGlmIChbJ2JpZ2dlc3QtcHJpY2UnLCAnbG93ZXN0LXByaWNlJywgJ2JpZ2dlc3QtZGlzY291bnQnLCAnYmVzdC1yYXRpbmcnXS5pbmNsdWRlcyhvcHRpb25zLnNvcnQpKVxyXG4gICAgICByZXR1cm4gdGhpcy5wcm9kdWN0UmVwb3NpdG9yeS5maW5kQ2F0YWxvZyhyZXBvUGFyYW1zKVxyXG5cclxuICAgIHJldHVybiB0aGlzLnByb2R1Y3RSZXBvc2l0b3J5LmZpbmRDYXRhbG9nKFxyXG4gICAgICByZXBvUGFyYW1zLFxyXG4gICAgICBvcHRpb25zPy5tYWluR2VuZGVyIHx8IHRoaXMuc2hvcCA9PT0gU2hvcHMuTUVOU01BUktFVCA/ICdtYWxlJyA6ICdmZW1hbGUnLFxyXG4gICAgKVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBhc3luYyBidWlsZE1haW5GaWx0ZXIoe1xyXG4gICAgY2F0ZWdvcnksXHJcbiAgICBwcm9maWxlLFxyXG4gICAgdGVybSxcclxuICB9OiBGZXRjaFByb2R1Y3RzTWFpblBhcmFtczxUPik6IFByb21pc2U8UmVwb3NpdG9yeUZpbmRGaWVsdGVyczxQcm9kdWN0Pj4ge1xyXG4gICAgaWYgKGNhdGVnb3J5KSByZXR1cm4gdGhpcy5jYXRlZ29yeVN0cnVjdHVyZUFkYXB0ZXIuYnVpbGRQcm9kdWN0RmlsdGVyQnlDYXRlZ29yeShjYXRlZ29yeSlcclxuICAgIGlmIChwcm9maWxlKSByZXR1cm4geyB0YWdzOiB7IG9wZXJhdG9yOiBXaGVyZS5MSUtFLCB2YWx1ZTogcHJvZmlsZSB9IH1cclxuICAgIGlmICh0ZXJtKVxyXG4gICAgICByZXR1cm4gdGhpcy5wcm9kdWN0SW5kZXhcclxuICAgICAgICAuc2VhcmNoKHRlcm0sIDk5OSwgdGhpcy5zaG9wKVxyXG4gICAgICAgIC50aGVuKChkYXRhKSA9PiAoeyBpZDogeyBvcGVyYXRvcjogV2hlcmUuSU4sIHZhbHVlOiBkYXRhLmhpdHMubWFwKCh7IF9zb3VyY2UgfSkgPT4gX3NvdXJjZS5pZCkgfSB9KSlcclxuICB9XHJcblxyXG4gIHByaXZhdGUgYXN5bmMgZmluZENhdGFsb2dBbmRTb3J0QnlNb3N0UmV2ZWxhbnQoXHJcbiAgICBwcm9kdWN0SWRzOiBzdHJpbmdbXSxcclxuICAgIG9wdGlvbnM6IE9taXQ8RmV0Y2hQcm9kdWN0c09wdGlvbnMsICdzb3J0Jz4gJiB7XHJcbiAgICAgIHRlcm0/OiBGZXRjaFByb2R1Y3RzTWFpblBhcmFtczxUPlsndGVybSddXHJcbiAgICAgIGZpbHRlcnM/OiBGZXRjaFByb2R1Y3RzRmlsdGVycyAmIHsgY3VzdG9tT3B0aW9ucz86IG5ldmVyIH1cclxuICAgIH0sXHJcbiAgICBsaW1pdHM6IHtcclxuICAgICAgbGltaXQ/OiBudW1iZXJcclxuICAgICAgb2Zmc2V0PzogbnVtYmVyXHJcbiAgICB9LFxyXG4gICk6IFByb21pc2U8UmVwb3NpdG9yeUZpbmRSZXN1bHQ8UHJvZHVjdD4+IHtcclxuICAgIGNvbnN0IHRvdGFsUmVzdWx0ID0gYXdhaXQgdGhpcy5wcm9kdWN0UmVwb3NpdG9yeS5maW5kQ2F0YWxvZyhcclxuICAgICAge1xyXG4gICAgICAgIGZpZWxkczogWydpZCcsICdzdG9jayddLFxyXG4gICAgICAgIGZpbHRlcnM6IHtcclxuICAgICAgICAgIGlkOiB7IG9wZXJhdG9yOiBXaGVyZS5JTiwgdmFsdWU6IHByb2R1Y3RJZHMgfSxcclxuICAgICAgICAgIC4uLnRoaXMuYnVpbGRGaWx0ZXJRdWVyeShvcHRpb25zPy5maWx0ZXJzIHx8IHt9KSxcclxuICAgICAgICB9LFxyXG4gICAgICAgIG9wdGlvbnM6IHtcclxuICAgICAgICAgIG1pbmltYWw6IFsncHJpY2UnXSxcclxuICAgICAgICAgIG1heGltdW06IFsncHJpY2UnXSxcclxuICAgICAgICAgIGRpc3RpbmN0OiBbJ2JyYW5kJ10sXHJcbiAgICAgICAgfSxcclxuICAgICAgfSxcclxuICAgICAgb3B0aW9ucz8ubWFpbkdlbmRlciB8fCB0aGlzLnNob3AgPT09IFNob3BzLk1FTlNNQVJLRVQgPyAnbWFsZScgOiAnZmVtYWxlJyxcclxuICAgIClcclxuXHJcbiAgICBjb25zdCBzdG9ja0RhdGEgPSB0b3RhbFJlc3VsdC5kYXRhLmZpbHRlcigocHJvZHVjdCkgPT4gcHJvZHVjdC5zdG9jay5xdWFudGl0eSA+IDApXHJcbiAgICBjb25zdCBzdG9ja091dCA9IHRvdGFsUmVzdWx0LmRhdGEuZmlsdGVyKChwcm9kdWN0KSA9PiBwcm9kdWN0LnN0b2NrLnF1YW50aXR5IDw9IDApXHJcbiAgICBjb25zdCBwcm9kdWN0SWRzU3RvY2sgPSBwcm9kdWN0SWRzLmZpbHRlcigocHJvZHVjdCkgPT4gc3RvY2tEYXRhLnNvbWUoKHJlc3VsdCkgPT4gcmVzdWx0LmlkID09IHByb2R1Y3QpKVxyXG4gICAgY29uc3QgcHJvZHVjdElkc1N0b2NrT3V0ID0gcHJvZHVjdElkcy5maWx0ZXIoKHByb2R1Y3QpID0+IHN0b2NrT3V0LnNvbWUoKHJlc3VsdCkgPT4gcmVzdWx0LmlkID09IHByb2R1Y3QpKVxyXG5cclxuICAgIGNvbnN0IGxpbWl0ZWRQcm9kdWN0SWQgPSBwcm9kdWN0SWRzU3RvY2tcclxuICAgICAgLmNvbmNhdChwcm9kdWN0SWRzU3RvY2tPdXQpXHJcbiAgICAgIC5zbGljZShsaW1pdHMub2Zmc2V0LCBsaW1pdHMub2Zmc2V0ICsgbGltaXRzLmxpbWl0KVxyXG5cclxuICAgIGNvbnN0IG9yZGVyZWRJZCA9IHByb2R1Y3RJZHMuZmlsdGVyKChwcm9kdWN0KSA9PiBsaW1pdGVkUHJvZHVjdElkLmluY2x1ZGVzKHByb2R1Y3QpKVxyXG4gICAgY29uc3QgcHJvZHVjdFJlc3VsdCA9IGF3YWl0IHRoaXMucHJvZHVjdFJlcG9zaXRvcnkuZmluZENhdGFsb2coe1xyXG4gICAgICBmaWx0ZXJzOiB7XHJcbiAgICAgICAgaWQ6IHsgb3BlcmF0b3I6IFdoZXJlLklOLCB2YWx1ZTogb3JkZXJlZElkIH0sXHJcbiAgICAgIH0sXHJcbiAgICB9KVxyXG5cclxuICAgIHJldHVybiB7XHJcbiAgICAgIGRhdGE6IGxpbWl0ZWRQcm9kdWN0SWQubWFwKChpZCkgPT4gcHJvZHVjdFJlc3VsdC5kYXRhLmZpbmQoKHByb2R1Y3QpID0+IHByb2R1Y3QuaWQgPT09IGlkKSkuZmlsdGVyKEJvb2xlYW4pLFxyXG4gICAgICBjb3VudDogdG90YWxSZXN1bHQuY291bnQsXHJcbiAgICAgIG1heGltdW06IHRvdGFsUmVzdWx0Lm1heGltdW0sXHJcbiAgICAgIG1pbmltYWw6IHRvdGFsUmVzdWx0Lm1pbmltYWwsXHJcbiAgICAgIGRpc3RpbmN0OiB0b3RhbFJlc3VsdC5kaXN0aW5jdCxcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHByaXZhdGUgYXN5bmMgZmluZENhdGFsb2dJZHNCeUVsYXN0aWNTZWFyY2godGVybTogc3RyaW5nKTogUHJvbWlzZTxzdHJpbmdbXT4ge1xyXG4gICAgaWYgKHRoaXMucHJvZHVjdHNCeVRlcm1bdGVybV0pIHJldHVybiB0aGlzLnByb2R1Y3RzQnlUZXJtW3Rlcm1dXHJcblxyXG4gICAgcmV0dXJuICh0aGlzLnByb2R1Y3RzQnlUZXJtW3Rlcm1dID0gYXdhaXQgdGhpcy5wcm9kdWN0SW5kZXhcclxuICAgICAgLnNlYXJjaCh0ZXJtLCA5OTksIHRoaXMuc2hvcClcclxuICAgICAgLnRoZW4oKHsgaGl0czogcHJvZHVjdHMgfSkgPT4ge1xyXG4gICAgICAgIGNvbnN0IHdpdGhTdG9jayA9IHByb2R1Y3RzLmZpbHRlcigoeyBfc291cmNlIH0pID0+IF9zb3VyY2Uuc3RvY2sucXVhbnRpdHkgPiAwKVxyXG4gICAgICAgIGNvbnN0IHdpdGhPdXRTdG9jayA9IHByb2R1Y3RzLmZpbHRlcigoeyBfc291cmNlIH0pID0+IF9zb3VyY2Uuc3RvY2sucXVhbnRpdHkgPD0gMClcclxuICAgICAgICBjb25zdCBzb3J0ZWQgPSBbLi4ud2l0aFN0b2NrLCAuLi53aXRoT3V0U3RvY2tdXHJcblxyXG4gICAgICAgIHJldHVybiBbLi4ubmV3IFNldChzb3J0ZWQubWFwKCh7IF9zb3VyY2UgfSkgPT4gX3NvdXJjZS5pZCkpXVxyXG4gICAgICB9KSlcclxuICB9XHJcblxyXG4gIHByaXZhdGUgYnVpbGRGaWx0ZXJRdWVyeSA9ICh7XHJcbiAgICBjbHViRGlzY291bnQsXHJcbiAgICBicmFuZHMsXHJcbiAgICBwcmljZXMsXHJcbiAgICBnZW5kZXIsXHJcbiAgICB0YWdzLFxyXG4gICAgcmF0ZSxcclxuICAgIGN1c3RvbU9wdGlvbnMsXHJcbiAgfTogRmV0Y2hQcm9kdWN0c0ZpbHRlcnMpOiBSZXBvc2l0b3J5RmluZEZpZWx0ZXJzPFByb2R1Y3Q+ID0+IHtcclxuICAgIGNvbnN0IGZpbHRlcnMgPSB7fSBhcyBSZXBvc2l0b3J5RmluZEZpZWx0ZXJzPFByb2R1Y3Q+XHJcblxyXG4gICAgaWYgKGNsdWJEaXNjb3VudD8ubGVuZ3RoKVxyXG4gICAgICBzZXQoZmlsdGVycywgJ3ByaWNlLnN1YnNjcmliZXJEaXNjb3VudFBlcmNlbnRhZ2UnLCB7IG9wZXJhdG9yOiBXaGVyZS5JTiwgdmFsdWU6IGNsdWJEaXNjb3VudCB9KVxyXG4gICAgaWYgKGJyYW5kcz8ubGVuZ3RoKSBmaWx0ZXJzLmJyYW5kID0geyBvcGVyYXRvcjogV2hlcmUuSU4sIHZhbHVlOiBicmFuZHMgfVxyXG4gICAgaWYgKGdlbmRlcj8ubGVuZ3RoKSBmaWx0ZXJzLmdlbmRlciA9IHsgb3BlcmF0b3I6IFdoZXJlLklOLCB2YWx1ZTogZ2VuZGVyIH1cclxuICAgIGlmIChwcmljZXM/Lm1pbiB8fCBwcmljZXM/Lm1heClcclxuICAgICAgc2V0KGZpbHRlcnMsIHByaWNlcy5zdWJzY3JpYmVyUHJpY2UgPyAncHJpY2Uuc3Vic2NyaWJlclByaWNlJyA6ICdwcmljZS5wcmljZScsIFtcclxuICAgICAgICAuLi4ocHJpY2VzLm1pbiA/IFt7IG9wZXJhdG9yOiBXaGVyZS5HVEUsIHZhbHVlOiBNYXRoLnJvdW5kKHByaWNlcy5taW4pIH1dIDogW10pLFxyXG4gICAgICAgIC4uLihwcmljZXMubWF4ID8gW3sgb3BlcmF0b3I6IFdoZXJlLkxURSwgdmFsdWU6IE1hdGguY2VpbChwcmljZXMubWF4KSB9XSA6IFtdKSxcclxuICAgICAgXSlcclxuICAgIGlmIChyYXRlKSBmaWx0ZXJzLnJhdGUgPSB7IG9wZXJhdG9yOiBXaGVyZS5HVEUsIHZhbHVlOiByYXRlIH1cclxuICAgIGlmICh0YWdzPy5sZW5ndGgpIGZpbHRlcnMudGFncyA9IHsgb3BlcmF0b3I6IFdoZXJlLkxJS0UsIHZhbHVlOiB0YWdzIH1cclxuICAgIGlmIChjdXN0b21PcHRpb25zPy5sZW5ndGgpIGZpbHRlcnMuZmlsdGVycyA9IHsgb3BlcmF0b3I6IFdoZXJlLkxJS0UsIHZhbHVlOiBjdXN0b21PcHRpb25zIH1cclxuXHJcbiAgICByZXR1cm4gZmlsdGVyc1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBidWlsZFNvcnRRdWVyeSA9IChzb3J0OiBQcm9kdWN0U29ydCk6IFJlcG9zaXRvcnlPcmRlckJ5PFByb2R1Y3Q+ID0+IHtcclxuICAgIGlmICghc29ydCB8fCBzb3J0ID09PSAnbW9zdC1yZWxldmFudCcpIHJldHVybiB7fVxyXG5cclxuICAgIGlmIChzb3J0ID09PSAnYmVzdC1zZWxsZXJzJykgcmV0dXJuIHsgc2hvcHBpbmdDb3VudDogJ2Rlc2MnIH1cclxuICAgIGlmIChzb3J0ID09PSAnYmlnZ2VzdC1wcmljZScpIHJldHVybiB7IHN1YnNjcmliZXJQcmljZTogJ2Rlc2MnIH0gYXMgYW55XHJcbiAgICBpZiAoc29ydCA9PT0gJ2xvd2VzdC1wcmljZScpIHJldHVybiB7IHN1YnNjcmliZXJQcmljZTogJ2FzYycgfSBhcyBhbnlcclxuICAgIGlmIChzb3J0ID09PSAnYmVzdC1yYXRpbmcnKSByZXR1cm4geyByYXRlOiAnZGVzYycgfVxyXG4gICAgaWYgKHNvcnQgPT09ICduZXdzJykgcmV0dXJuIHsgY3JlYXRlZEF0OiAnZGVzYycgfVxyXG4gICAgaWYgKHNvcnQgPT09ICdiaWdnZXN0LWRpc2NvdW50JykgcmV0dXJuIHsgc3Vic2NyaWJlckRpc2NvdW50UGVyY2VudGFnZTogJ2Rlc2MnIH0gYXMgYW55XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGJ1aWxkTGltaXRRdWVyeSA9IChvcHRpb25zOiB7IHBhZ2U/OiBudW1iZXI7IHBlclBhZ2U/OiBudW1iZXIgfSk6IHsgbGltaXQ/OiBudW1iZXI7IG9mZnNldD86IG51bWJlciB9ID0+IHtcclxuICAgIGNvbnN0IGxpbWl0ID0gb3B0aW9ucz8ucGVyUGFnZSB8fCAyMFxyXG5cclxuICAgIHJldHVybiB7XHJcbiAgICAgIGxpbWl0LFxyXG4gICAgICBvZmZzZXQ6ICgob3B0aW9ucz8ucGFnZSB8fCAxKSAtIDEpICogbGltaXQsXHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGhhc1Byb2ZpbGUgPSAoXHJcbiAgICBvcHRpb25zOiBGZXRjaFByb2R1Y3RzUGFyYW1zPFQ+LFxyXG4gICk6IG9wdGlvbnMgaXMgRmV0Y2hQcm9kdWN0c09wdGlvbnMgJiB7XHJcbiAgICBwcm9maWxlOiBGZXRjaFByb2R1Y3RzTWFpblBhcmFtczxUPlsncHJvZmlsZSddXHJcbiAgICBmaWx0ZXJzPzogRmV0Y2hQcm9kdWN0c0ZpbHRlcnMgJiB7IGN1c3RvbU9wdGlvbnM/OiBuZXZlcjsgdGFncz86IG5ldmVyIH1cclxuICB9ID0+ICdwcm9maWxlJyBpbiBvcHRpb25zXHJcblxyXG4gIHByaXZhdGUgaGFzVGVybSA9IChcclxuICAgIG9wdGlvbnM6IEZldGNoUHJvZHVjdHNQYXJhbXM8VD4sXHJcbiAgKTogb3B0aW9ucyBpcyBGZXRjaFByb2R1Y3RzT3B0aW9ucyAmIHtcclxuICAgIHRlcm06IEZldGNoUHJvZHVjdHNNYWluUGFyYW1zPFQ+Wyd0ZXJtJ11cclxuICAgIGZpbHRlcnM/OiBGZXRjaFByb2R1Y3RzRmlsdGVycyAmIHsgY3VzdG9tT3B0aW9ucz86IG5ldmVyIH1cclxuICB9ID0+ICd0ZXJtJyBpbiBvcHRpb25zXHJcblxyXG4gIHByaXZhdGUgaGFzQ2F0ZWdvcnkgPSAoXHJcbiAgICBvcHRpb25zOiBGZXRjaFByb2R1Y3RzUGFyYW1zPFQ+LFxyXG4gICk6IG9wdGlvbnMgaXMgRmV0Y2hQcm9kdWN0c09wdGlvbnMgJiB7XHJcbiAgICBjYXRlZ29yeTogRmV0Y2hQcm9kdWN0c01haW5QYXJhbXM8VD5bJ2NhdGVnb3J5J11cclxuICAgIGZpbHRlcnM/OiBGZXRjaFByb2R1Y3RzRmlsdGVycyAmIHsgY3VzdG9tT3B0aW9ucz86IG5ldmVyIH1cclxuICB9ID0+ICdjYXRlZ29yeScgaW4gb3B0aW9uc1xyXG59XHJcbiJdfQ==