@pvh-afl/core 1.2.13 → 1.2.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/integrations/commerce/commerce.types.d.ts +16 -0
- package/dist/integrations/commerce/commerce.types.d.ts.map +1 -1
- package/dist/integrations/commerce/shopify.service.d.ts.map +1 -1
- package/dist/integrations/commerce/shopify.service.js +9 -1
- package/dist/integrations/commerce/shopify.service.js.map +1 -1
- package/package.json +1 -1
- package/dist/common/circuit-breaker.d.ts +0 -81
- package/dist/common/circuit-breaker.d.ts.map +0 -1
- package/dist/common/circuit-breaker.js +0 -163
- package/dist/common/circuit-breaker.js.map +0 -1
- package/dist/integrations/search/search-fallback.service.d.ts +0 -93
- package/dist/integrations/search/search-fallback.service.d.ts.map +0 -1
- package/dist/integrations/search/search-fallback.service.js +0 -339
- package/dist/integrations/search/search-fallback.service.js.map +0 -1
- package/dist/integrations/search/shopify-search.mapper.d.ts +0 -31
- package/dist/integrations/search/shopify-search.mapper.d.ts.map +0 -1
- package/dist/integrations/search/shopify-search.mapper.js +0 -360
- package/dist/integrations/search/shopify-search.mapper.js.map +0 -1
|
@@ -1,339 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Search Fallback Service
|
|
4
|
-
*
|
|
5
|
-
* Serves search from Shopify when the search vendor (Wizzy) is unavailable,
|
|
6
|
-
* and holds the circuit breaker that decides whether the vendor is worth
|
|
7
|
-
* calling at all. Wizzy's own service is untouched: classification happens
|
|
8
|
-
* here, from the IntegrationResponse it already returns.
|
|
9
|
-
*
|
|
10
|
-
* See afl-brand-tommy/docs/SEARCH-FALLBACK-PLAN.md.
|
|
11
|
-
*/
|
|
12
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
-
exports.SearchFallbackService = exports.FallbackUnavailableError = exports.DEFAULT_FALLBACK_CONFIG = void 0;
|
|
14
|
-
const tslib_1 = require("tslib");
|
|
15
|
-
const common_1 = require("@nestjs/common");
|
|
16
|
-
const logger_1 = require("../../common/logger");
|
|
17
|
-
const circuit_breaker_1 = require("../../common/circuit-breaker");
|
|
18
|
-
const shopify_service_1 = require("../commerce/shopify.service");
|
|
19
|
-
const search_types_1 = require("./search.types");
|
|
20
|
-
const shopify_search_mapper_1 = require("./shopify-search.mapper");
|
|
21
|
-
exports.DEFAULT_FALLBACK_CONFIG = {
|
|
22
|
-
enabled: false,
|
|
23
|
-
maxConcurrentFallbacks: 25,
|
|
24
|
-
forceFallback: false,
|
|
25
|
-
breaker: {
|
|
26
|
-
failureThreshold: 5,
|
|
27
|
-
failureRateThreshold: 0.5,
|
|
28
|
-
minimumCalls: 10,
|
|
29
|
-
windowMs: 30_000,
|
|
30
|
-
openMs: 60_000,
|
|
31
|
-
maxOpenMs: 300_000,
|
|
32
|
-
probeIntervalMs: 15_000,
|
|
33
|
-
},
|
|
34
|
-
};
|
|
35
|
-
/** Wizzy error codes that mean "our request was wrong", not "the vendor is down". */
|
|
36
|
-
const CALLER_ERROR_CODES = ['BAD_REQUEST', 'NOT_CONFIGURED'];
|
|
37
|
-
/** Variant option name carrying colour in this store's Shopify catalogue. */
|
|
38
|
-
const COLOUR_OPTION_NAME = 'Brand Colour';
|
|
39
|
-
/** Shopify's `first` ceiling — bounds the over-fetch used for deep pages. */
|
|
40
|
-
const SHOPIFY_MAX_FIRST = 250;
|
|
41
|
-
class FallbackUnavailableError extends Error {
|
|
42
|
-
originalError;
|
|
43
|
-
constructor(originalError) {
|
|
44
|
-
super(originalError?.message ?? 'Search is unavailable');
|
|
45
|
-
this.originalError = originalError;
|
|
46
|
-
this.name = 'FallbackUnavailableError';
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
exports.FallbackUnavailableError = FallbackUnavailableError;
|
|
50
|
-
let SearchFallbackService = class SearchFallbackService {
|
|
51
|
-
shopify;
|
|
52
|
-
config = exports.DEFAULT_FALLBACK_CONFIG;
|
|
53
|
-
breaker = new circuit_breaker_1.CircuitBreaker({ name: 'wizzy' });
|
|
54
|
-
brand = '';
|
|
55
|
-
mapperConfig = search_types_1.DEFAULT_MAPPER_CONFIG;
|
|
56
|
-
inFlight = 0;
|
|
57
|
-
constructor(shopify) {
|
|
58
|
-
this.shopify = shopify;
|
|
59
|
-
}
|
|
60
|
-
configure(brand, config = {}, mapperConfig = search_types_1.DEFAULT_MAPPER_CONFIG) {
|
|
61
|
-
this.brand = brand;
|
|
62
|
-
this.config = {
|
|
63
|
-
...exports.DEFAULT_FALLBACK_CONFIG,
|
|
64
|
-
...config,
|
|
65
|
-
breaker: { ...exports.DEFAULT_FALLBACK_CONFIG.breaker, ...(config.breaker ?? {}) },
|
|
66
|
-
};
|
|
67
|
-
this.mapperConfig = mapperConfig;
|
|
68
|
-
this.breaker = new circuit_breaker_1.CircuitBreaker({ name: 'wizzy', ...this.config.breaker });
|
|
69
|
-
logger_1.logger.info('Search fallback configured', {
|
|
70
|
-
brand,
|
|
71
|
-
enabled: this.config.enabled,
|
|
72
|
-
forceFallback: this.config.forceFallback,
|
|
73
|
-
});
|
|
74
|
-
}
|
|
75
|
-
isEnabled() {
|
|
76
|
-
return this.config.enabled;
|
|
77
|
-
}
|
|
78
|
-
/**
|
|
79
|
-
* Whether Wizzy should be called for this request. False means the breaker is
|
|
80
|
-
* open (or the fallback is forced), so the caller goes straight to Shopify.
|
|
81
|
-
*/
|
|
82
|
-
shouldCallWizzy() {
|
|
83
|
-
if (!this.config.enabled)
|
|
84
|
-
return true;
|
|
85
|
-
if (this.config.forceFallback)
|
|
86
|
-
return false;
|
|
87
|
-
const decision = this.breaker.canAttempt();
|
|
88
|
-
if (decision.reason === 'probe') {
|
|
89
|
-
logger_1.logger.warn('Wizzy breaker probing', { brand: this.brand });
|
|
90
|
-
}
|
|
91
|
-
return decision.allowed;
|
|
92
|
-
}
|
|
93
|
-
/** Record a Wizzy outcome. Caller errors are not vendor failures. */
|
|
94
|
-
recordWizzyOutcome(success, errorCode) {
|
|
95
|
-
if (!this.config.enabled)
|
|
96
|
-
return;
|
|
97
|
-
if (success) {
|
|
98
|
-
const before = this.breaker.getState();
|
|
99
|
-
this.breaker.recordSuccess();
|
|
100
|
-
if (before === 'OPEN') {
|
|
101
|
-
logger_1.logger.warn('Wizzy breaker closed — vendor recovered', { brand: this.brand });
|
|
102
|
-
}
|
|
103
|
-
return;
|
|
104
|
-
}
|
|
105
|
-
if (errorCode && CALLER_ERROR_CODES.includes(errorCode)) {
|
|
106
|
-
logger_1.logger.error('Wizzy rejected our request; not counted against the breaker', {
|
|
107
|
-
brand: this.brand,
|
|
108
|
-
errorCode,
|
|
109
|
-
});
|
|
110
|
-
return;
|
|
111
|
-
}
|
|
112
|
-
const before = this.breaker.getState();
|
|
113
|
-
this.breaker.recordFailure();
|
|
114
|
-
const after = this.breaker.getState();
|
|
115
|
-
if (before === 'CLOSED' && after === 'OPEN') {
|
|
116
|
-
logger_1.logger.warn('Wizzy breaker opened', {
|
|
117
|
-
brand: this.brand,
|
|
118
|
-
errorCode,
|
|
119
|
-
snapshot: this.breaker.getSnapshot(),
|
|
120
|
-
});
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
/** Should this error fall back at all? Caller errors must stay visible. */
|
|
124
|
-
isFallbackableError(errorCode) {
|
|
125
|
-
return !errorCode || !CALLER_ERROR_CODES.includes(errorCode);
|
|
126
|
-
}
|
|
127
|
-
/**
|
|
128
|
-
* A products payload we can actually map. Wizzy can answer HTTP 200 with
|
|
129
|
-
* `status: 1` and still omit `payload.result`; that is a broken vendor
|
|
130
|
-
* response, not an empty result set (an empty result set is `result: []`).
|
|
131
|
-
*/
|
|
132
|
-
isUsableProductsPayload(data) {
|
|
133
|
-
return Array.isArray(data?.payload?.result);
|
|
134
|
-
}
|
|
135
|
-
/** Same guard for the autocomplete payload shape. */
|
|
136
|
-
isUsableAutocompletePayload(data) {
|
|
137
|
-
return Boolean(data?.payload) && typeof data?.payload === 'object';
|
|
138
|
-
}
|
|
139
|
-
getBreakerState() {
|
|
140
|
-
return this.breaker.getState();
|
|
141
|
-
}
|
|
142
|
-
getSnapshot() {
|
|
143
|
-
return {
|
|
144
|
-
enabled: this.config.enabled,
|
|
145
|
-
forceFallback: this.config.forceFallback,
|
|
146
|
-
inFlightFallbacks: this.inFlight,
|
|
147
|
-
breaker: this.breaker.getSnapshot(),
|
|
148
|
-
};
|
|
149
|
-
}
|
|
150
|
-
/** Keyword search fallback via the Storefront `search` query. */
|
|
151
|
-
async searchProducts(query, productsCount, originalError, requestedFacetKeys) {
|
|
152
|
-
return this.guarded('search', originalError, async () => {
|
|
153
|
-
// The shopper's query is passed through untouched.
|
|
154
|
-
const result = await this.shopify.searchProducts({
|
|
155
|
-
query,
|
|
156
|
-
first: Math.min(productsCount, SHOPIFY_MAX_FIRST),
|
|
157
|
-
});
|
|
158
|
-
if (!result.success || !result.data) {
|
|
159
|
-
throw new FallbackUnavailableError(originalError ?? result.error);
|
|
160
|
-
}
|
|
161
|
-
return (0, shopify_search_mapper_1.mapShopifySearchResponse)(result.data.products, result.data.totalCount, result.data.filters, 1, productsCount, this.mapperConfig, requestedFacetKeys);
|
|
162
|
-
});
|
|
163
|
-
}
|
|
164
|
-
/**
|
|
165
|
-
* Collection listing fallback via `collection(handle:)`.
|
|
166
|
-
*
|
|
167
|
-
* Shopify paginates by cursor and we hold no cursor state, so page N is
|
|
168
|
-
* served by over-fetching N*size and slicing. Beyond Shopify's `first`
|
|
169
|
-
* ceiling the page is reported as empty rather than wrong.
|
|
170
|
-
*/
|
|
171
|
-
async filterProducts(filters, originalError) {
|
|
172
|
-
return this.guarded('filter', originalError, async () => {
|
|
173
|
-
const handle = filters.categories?.[0];
|
|
174
|
-
const page = Math.max(1, filters.page ?? 1);
|
|
175
|
-
const perPage = filters.productsCount ?? 20;
|
|
176
|
-
const facetKeys = (filters.facets ?? []).map((f) => f.key);
|
|
177
|
-
// No collection handle means this was a filtered keyword search; the
|
|
178
|
-
// keyword path is the closer analogue.
|
|
179
|
-
if (!handle) {
|
|
180
|
-
const result = await this.shopify.searchProducts({
|
|
181
|
-
query: filters.q ?? '',
|
|
182
|
-
first: Math.min(perPage, SHOPIFY_MAX_FIRST),
|
|
183
|
-
filters: this.toShopifyFilters(filters),
|
|
184
|
-
});
|
|
185
|
-
if (!result.success || !result.data) {
|
|
186
|
-
throw new FallbackUnavailableError(originalError ?? result.error);
|
|
187
|
-
}
|
|
188
|
-
return (0, shopify_search_mapper_1.mapShopifySearchResponse)(result.data.products, result.data.totalCount, result.data.filters, page, perPage, this.mapperConfig, facetKeys);
|
|
189
|
-
}
|
|
190
|
-
const needed = page * perPage;
|
|
191
|
-
if (needed > SHOPIFY_MAX_FIRST) {
|
|
192
|
-
logger_1.logger.warn('Fallback pagination beyond Shopify window', {
|
|
193
|
-
brand: this.brand,
|
|
194
|
-
handle,
|
|
195
|
-
page,
|
|
196
|
-
perPage,
|
|
197
|
-
});
|
|
198
|
-
return {
|
|
199
|
-
products: [],
|
|
200
|
-
total: 0,
|
|
201
|
-
pages: Math.floor(SHOPIFY_MAX_FIRST / perPage),
|
|
202
|
-
currentPage: page,
|
|
203
|
-
productsPerPage: perPage,
|
|
204
|
-
hasExactMatch: false,
|
|
205
|
-
facets: [],
|
|
206
|
-
source: 'shopify',
|
|
207
|
-
};
|
|
208
|
-
}
|
|
209
|
-
const result = await this.shopify.getCollectionProducts({
|
|
210
|
-
handle,
|
|
211
|
-
first: needed,
|
|
212
|
-
filters: this.toShopifyFilters(filters),
|
|
213
|
-
sortKey: this.toCollectionSortKey(filters),
|
|
214
|
-
reverse: filters.sort?.[0]?.order === 'desc',
|
|
215
|
-
});
|
|
216
|
-
if (!result.success) {
|
|
217
|
-
throw new FallbackUnavailableError(originalError ?? result.error);
|
|
218
|
-
}
|
|
219
|
-
// Unknown handle: an empty page is the correct answer, not an error.
|
|
220
|
-
if (!result.data) {
|
|
221
|
-
return {
|
|
222
|
-
products: [],
|
|
223
|
-
total: 0,
|
|
224
|
-
pages: 0,
|
|
225
|
-
currentPage: page,
|
|
226
|
-
productsPerPage: perPage,
|
|
227
|
-
hasExactMatch: false,
|
|
228
|
-
facets: [],
|
|
229
|
-
source: 'shopify',
|
|
230
|
-
};
|
|
231
|
-
}
|
|
232
|
-
const windowStart = (page - 1) * perPage;
|
|
233
|
-
const slice = result.data.products.slice(windowStart, windowStart + perPage);
|
|
234
|
-
const mapped = (0, shopify_search_mapper_1.mapShopifySearchResponse)(slice, result.data.totalCount, result.data.filters, page, perPage, this.mapperConfig, facetKeys);
|
|
235
|
-
mapped.collectionTitle = result.data.title;
|
|
236
|
-
return mapped;
|
|
237
|
-
});
|
|
238
|
-
}
|
|
239
|
-
/** Autocomplete fallback via `predictiveSearch`. */
|
|
240
|
-
async autocomplete(query, limit, originalError) {
|
|
241
|
-
return this.guarded('autocomplete', originalError, async () => {
|
|
242
|
-
const result = await this.shopify.predictiveSearch(query, limit);
|
|
243
|
-
if (!result.success || !result.data) {
|
|
244
|
-
throw new FallbackUnavailableError(originalError ?? result.error);
|
|
245
|
-
}
|
|
246
|
-
return (0, shopify_search_mapper_1.mapShopifyAutocompleteResponse)(result.data, this.mapperConfig);
|
|
247
|
-
});
|
|
248
|
-
}
|
|
249
|
-
/**
|
|
250
|
-
* Concurrency guard. Without a cache, an outage turns full search traffic
|
|
251
|
-
* into live Storefront calls; shedding past the cap keeps a vendor outage
|
|
252
|
-
* from becoming a Shopify outage.
|
|
253
|
-
*/
|
|
254
|
-
async guarded(endpoint, originalError, run) {
|
|
255
|
-
if (!this.config.enabled) {
|
|
256
|
-
throw new FallbackUnavailableError(originalError);
|
|
257
|
-
}
|
|
258
|
-
if (this.inFlight >= this.config.maxConcurrentFallbacks) {
|
|
259
|
-
logger_1.logger.error('Search fallback shed — concurrency cap reached', {
|
|
260
|
-
brand: this.brand,
|
|
261
|
-
endpoint,
|
|
262
|
-
inFlight: this.inFlight,
|
|
263
|
-
});
|
|
264
|
-
throw new FallbackUnavailableError(originalError);
|
|
265
|
-
}
|
|
266
|
-
this.inFlight++;
|
|
267
|
-
try {
|
|
268
|
-
const result = await run();
|
|
269
|
-
logger_1.logger.warn('Search served by Shopify fallback', {
|
|
270
|
-
brand: this.brand,
|
|
271
|
-
endpoint,
|
|
272
|
-
breakerState: this.breaker.getState(),
|
|
273
|
-
});
|
|
274
|
-
return result;
|
|
275
|
-
}
|
|
276
|
-
catch (error) {
|
|
277
|
-
if (error instanceof FallbackUnavailableError)
|
|
278
|
-
throw error;
|
|
279
|
-
logger_1.logger.error('Search fallback failed', {
|
|
280
|
-
brand: this.brand,
|
|
281
|
-
endpoint,
|
|
282
|
-
error: error instanceof Error ? error.message : 'Unknown',
|
|
283
|
-
});
|
|
284
|
-
throw new FallbackUnavailableError(originalError);
|
|
285
|
-
}
|
|
286
|
-
finally {
|
|
287
|
-
this.inFlight--;
|
|
288
|
-
}
|
|
289
|
-
}
|
|
290
|
-
/** Translate the Wizzy filter request into Shopify ProductFilter inputs. */
|
|
291
|
-
toShopifyFilters(filters) {
|
|
292
|
-
const out = [];
|
|
293
|
-
if (filters.inStock?.includes(true)) {
|
|
294
|
-
out.push({ available: true });
|
|
295
|
-
}
|
|
296
|
-
// Wizzy sends ranges as an array of { gte, lte }.
|
|
297
|
-
const range = (filters.sellingPrice ?? filters.price)?.[0];
|
|
298
|
-
if (range && (range.gte !== undefined || range.lte !== undefined)) {
|
|
299
|
-
out.push({ price: { min: range.gte, max: range.lte } });
|
|
300
|
-
}
|
|
301
|
-
for (const color of filters.colors ?? []) {
|
|
302
|
-
out.push({ variantOption: { name: COLOUR_OPTION_NAME, value: color } });
|
|
303
|
-
}
|
|
304
|
-
for (const size of filters.sizes ?? []) {
|
|
305
|
-
out.push({ variantOption: { name: 'Size', value: size } });
|
|
306
|
-
}
|
|
307
|
-
for (const brand of filters.brands ?? []) {
|
|
308
|
-
out.push({ productVendor: brand });
|
|
309
|
-
}
|
|
310
|
-
// Wizzy carries colour/product-type selections on `attributes`, keyed by
|
|
311
|
-
// attribute id (e.g. `product_Basic Colour`).
|
|
312
|
-
for (const [key, values] of Object.entries(filters.attributes ?? {})) {
|
|
313
|
-
const lowerKey = key.toLowerCase();
|
|
314
|
-
for (const value of values ?? []) {
|
|
315
|
-
if (lowerKey.includes('colour') || lowerKey.includes('color')) {
|
|
316
|
-
out.push({ variantOption: { name: COLOUR_OPTION_NAME, value } });
|
|
317
|
-
}
|
|
318
|
-
else if (lowerKey.includes('product_type')) {
|
|
319
|
-
out.push({ productType: value });
|
|
320
|
-
}
|
|
321
|
-
}
|
|
322
|
-
}
|
|
323
|
-
return out;
|
|
324
|
-
}
|
|
325
|
-
toCollectionSortKey(filters) {
|
|
326
|
-
const field = filters.sort?.[0]?.field;
|
|
327
|
-
if (field === 'sellingPrice' || field === 'price')
|
|
328
|
-
return 'PRICE';
|
|
329
|
-
if (field === 'createdAt')
|
|
330
|
-
return 'CREATED';
|
|
331
|
-
return 'COLLECTION_DEFAULT';
|
|
332
|
-
}
|
|
333
|
-
};
|
|
334
|
-
exports.SearchFallbackService = SearchFallbackService;
|
|
335
|
-
exports.SearchFallbackService = SearchFallbackService = tslib_1.__decorate([
|
|
336
|
-
(0, common_1.Injectable)(),
|
|
337
|
-
tslib_1.__metadata("design:paramtypes", [shopify_service_1.ShopifyCommerceService])
|
|
338
|
-
], SearchFallbackService);
|
|
339
|
-
//# sourceMappingURL=search-fallback.service.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"search-fallback.service.js","sourceRoot":"","sources":["../../../src/integrations/search/search-fallback.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Shopify Search Fallback Mapper
|
|
3
|
-
*
|
|
4
|
-
* Maps Storefront API results into the same unified structures the Wizzy
|
|
5
|
-
* mapper produces, so a fallback response is shape-compatible with a normal
|
|
6
|
-
* one. Fields Wizzy owns and Shopify cannot supply (wizzyId, groupId,
|
|
7
|
-
* swatches, searchedKey) get honest defaults — nothing is invented.
|
|
8
|
-
*/
|
|
9
|
-
import { CommerceProduct, CommerceFilter, CommercePredictiveSearchResult } from '../commerce/commerce.types';
|
|
10
|
-
import { SearchProduct, SearchProductsResponse, SearchMapperConfig, AutocompleteResponse } from './search.types';
|
|
11
|
-
/**
|
|
12
|
-
* Map one Shopify product to a SearchProduct.
|
|
13
|
-
*
|
|
14
|
-
* Prices come from priceRange/compareAtPrice; discount is derived rather than
|
|
15
|
-
* reported, since Shopify has no discount field of its own.
|
|
16
|
-
*/
|
|
17
|
-
export declare function mapShopifyProduct(product: CommerceProduct, config?: SearchMapperConfig): SearchProduct;
|
|
18
|
-
/**
|
|
19
|
-
* Build a SearchProductsResponse from Shopify results.
|
|
20
|
-
*
|
|
21
|
-
* `searchedKey` is deliberately absent — only Wizzy mints one.
|
|
22
|
-
*/
|
|
23
|
-
export declare function mapShopifySearchResponse(products: CommerceProduct[], totalCount: number, filters: CommerceFilter[], page: number, productsPerPage: number, config?: SearchMapperConfig, requestedFacetKeys?: string[]): SearchProductsResponse;
|
|
24
|
-
/**
|
|
25
|
-
* Build an AutocompleteResponse from predictiveSearch results.
|
|
26
|
-
*
|
|
27
|
-
* `brands` stays empty — predictiveSearch has no brand suggestions — and
|
|
28
|
-
* `valueHighlighted` mirrors `value`, since Shopify returns no markup.
|
|
29
|
-
*/
|
|
30
|
-
export declare function mapShopifyAutocompleteResponse(result: CommercePredictiveSearchResult, config?: SearchMapperConfig): AutocompleteResponse;
|
|
31
|
-
//# sourceMappingURL=shopify-search.mapper.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"shopify-search.mapper.d.ts","sourceRoot":"","sources":["../../../src/integrations/search/shopify-search.mapper.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EACL,eAAe,EACf,cAAc,EAGd,8BAA8B,EAC/B,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,aAAa,EACb,sBAAsB,EAItB,kBAAkB,EAElB,oBAAoB,EAErB,MAAM,gBAAgB,CAAC;AAiKxB;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,eAAe,EACxB,MAAM,GAAE,kBAA0C,GACjD,aAAa,CAgIf;AAqHD;;;;GAIG;AACH,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,eAAe,EAAE,EAC3B,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,cAAc,EAAE,EACzB,IAAI,EAAE,MAAM,EACZ,eAAe,EAAE,MAAM,EACvB,MAAM,GAAE,kBAA0C,EAClD,kBAAkB,CAAC,EAAE,MAAM,EAAE,GAC5B,sBAAsB,CAaxB;AAED;;;;;GAKG;AACH,wBAAgB,8BAA8B,CAC5C,MAAM,EAAE,8BAA8B,EACtC,MAAM,GAAE,kBAA0C,GACjD,oBAAoB,CAmBtB"}
|