@snabcentr/client-core 3.19.0 → 3.20.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.
@@ -1,7 +1,12 @@
1
+ import { UrlTree } from '@angular/router';
1
2
  import { MonoTypeOperatorFunction, Observable } from 'rxjs';
3
+ import { ScRedirectStatusEnum } from '../../common/enums/redirect-status-enum';
2
4
  import * as i0 from "@angular/core";
3
5
  /**
4
- * Сервис редиректа на родительскую категорию при недоступности (HTTP 404) товара или категории.
6
+ * Сервис редиректов каталога: на родительскую категорию при недоступности (HTTP 404) товара или категории
7
+ * и на канонический адрес товара или категории (см. {@link redirectToCanonicalUrl}).
8
+ *
9
+ * Редирект на родительскую категорию.
5
10
  *
6
11
  * Запрашивает у бэкенда родительскую категорию недоступной сущности и выполняет редирект:
7
12
  * - на сервере (SSR) при доступном {@link RESPONSE} — выставляет HTTP-статус 302 и заголовок `Location` для корректного редиректа поисковых ботов;
@@ -24,6 +29,10 @@ export declare class ScCatalogRedirectService {
24
29
  * Признак использования идентификатора или slug в маршрутах товаров и категорий.
25
30
  */
26
31
  private readonly idOrSlug;
32
+ /**
33
+ * Признак, что включён постоянный редирект на канонический адрес товара или категории.
34
+ */
35
+ private readonly isCanonicalRedirectEnabled;
27
36
  /**
28
37
  * Признак, что текущий скрипт исполняется на сервере.
29
38
  */
@@ -35,13 +44,30 @@ export declare class ScCatalogRedirectService {
35
44
  * через CommonEngine. На upgrade-ветке `server.ts` остался на CommonEngine, поэтому при слиянии здесь
36
45
  * ничего менять не нужно. Если `server.ts` мигрируют на `AngularNodeAppEngine` + `createNodeRequestHandler`,
37
46
  * замените {@link RESPONSE} на нативный `RESPONSE_INIT` (`InjectionToken<ResponseInit | null>` из `@angular/core`);
38
- * см. серверную ветку в {@link redirectToParentCategory$}.
47
+ * см. серверные ветки в {@link redirectToParentCategory$} и {@link redirectToCanonicalUrl}.
39
48
  */
40
49
  private readonly response;
41
50
  /**
42
51
  * Документ текущей страницы.
43
52
  */
44
53
  private readonly document;
54
+ /**
55
+ * Возвращает результат стража маршрута для перехода на канонический адрес товара или категории
56
+ * (адрес со slug либо с идентификатором — в зависимости от настроек окружения).
57
+ *
58
+ * @param commands Сегменты канонического маршрута.
59
+ * @param status Статус редиректа: вид адреса задаётся настройками окружения и может быть изменён, поэтому по умолчанию временный.
60
+ * @returns Дерево канонического маршрута для навигации либо `false`, если редирект выполнен ответом сервера.
61
+ */
62
+ redirectToCanonicalUrl(commands: Array<number | string>, status?: ScRedirectStatusEnum): boolean | UrlTree;
63
+ /**
64
+ * Выставляет редирект в ответе сервера (SSR).
65
+ *
66
+ * @param targetUrl Адрес, на который выполняется редирект.
67
+ * @param status Статус редиректа.
68
+ * @returns Признак, что редирект выставлен; `false`, если данные об ответе недоступны (например, dev-сервер `ng serve`).
69
+ */
70
+ private setServerRedirect;
45
71
  /**
46
72
  * Выполняет редирект на родительскую категорию недоступной категории.
47
73
  *
@@ -1 +1,2 @@
1
+ export * from './redirect-status-enum';
1
2
  export * from './request-state-status-enum';
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Статусы HTTP-редиректа, отдаваемые при рендере на сервере (SSR).
3
+ */
4
+ export declare enum ScRedirectStatusEnum {
5
+ /**
6
+ * Постоянный редирект: адрес изменился навсегда, страница заменяется в индексе поисковых систем.
7
+ */
8
+ Permanent = 301,
9
+ /**
10
+ * Временный редирект: исходный адрес может снова стать доступным, поэтому остаётся в индексе поисковых систем.
11
+ */
12
+ Temporary = 302
13
+ }
@@ -4,12 +4,17 @@ import { inject, Injectable } from '@angular/core';
4
4
  import { Router } from '@angular/router';
5
5
  import { tuiIsPresent } from '@taiga-ui/cdk';
6
6
  import { catchError, EMPTY, switchMap, throwError } from 'rxjs';
7
+ import { ScRedirectStatusEnum } from '../../common/enums/redirect-status-enum';
7
8
  import { IS_SERVER, RESPONSE } from '../../providers/ssr.providers';
9
+ import { SC_CANONICAL_REDIRECT_ENABLED } from '../../tokens/sc-canonical-redirect-enabled';
8
10
  import { SC_ID_OR_SLUG_IN_ROUTE } from '../../tokens/sc-id-or-slug-in-route';
9
11
  import { ScCatalogService } from './sc-catalog.service';
10
12
  import * as i0 from "@angular/core";
11
13
  /**
12
- * Сервис редиректа на родительскую категорию при недоступности (HTTP 404) товара или категории.
14
+ * Сервис редиректов каталога: на родительскую категорию при недоступности (HTTP 404) товара или категории
15
+ * и на канонический адрес товара или категории (см. {@link redirectToCanonicalUrl}).
16
+ *
17
+ * Редирект на родительскую категорию.
13
18
  *
14
19
  * Запрашивает у бэкенда родительскую категорию недоступной сущности и выполняет редирект:
15
20
  * - на сервере (SSR) при доступном {@link RESPONSE} — выставляет HTTP-статус 302 и заголовок `Location` для корректного редиректа поисковых ботов;
@@ -33,6 +38,10 @@ export class ScCatalogRedirectService {
33
38
  * Признак использования идентификатора или slug в маршрутах товаров и категорий.
34
39
  */
35
40
  this.idOrSlug = inject(SC_ID_OR_SLUG_IN_ROUTE);
41
+ /**
42
+ * Признак, что включён постоянный редирект на канонический адрес товара или категории.
43
+ */
44
+ this.isCanonicalRedirectEnabled = inject(SC_CANONICAL_REDIRECT_ENABLED);
36
45
  /**
37
46
  * Признак, что текущий скрипт исполняется на сервере.
38
47
  */
@@ -44,7 +53,7 @@ export class ScCatalogRedirectService {
44
53
  * через CommonEngine. На upgrade-ветке `server.ts` остался на CommonEngine, поэтому при слиянии здесь
45
54
  * ничего менять не нужно. Если `server.ts` мигрируют на `AngularNodeAppEngine` + `createNodeRequestHandler`,
46
55
  * замените {@link RESPONSE} на нативный `RESPONSE_INIT` (`InjectionToken<ResponseInit | null>` из `@angular/core`);
47
- * см. серверную ветку в {@link redirectToParentCategory$}.
56
+ * см. серверные ветки в {@link redirectToParentCategory$} и {@link redirectToCanonicalUrl}.
48
57
  */
49
58
  this.response = inject(RESPONSE, { optional: true });
50
59
  /**
@@ -52,6 +61,39 @@ export class ScCatalogRedirectService {
52
61
  */
53
62
  this.document = inject(DOCUMENT);
54
63
  }
64
+ /**
65
+ * Возвращает результат стража маршрута для перехода на канонический адрес товара или категории
66
+ * (адрес со slug либо с идентификатором — в зависимости от настроек окружения).
67
+ *
68
+ * @param commands Сегменты канонического маршрута.
69
+ * @param status Статус редиректа: вид адреса задаётся настройками окружения и может быть изменён, поэтому по умолчанию временный.
70
+ * @returns Дерево канонического маршрута для навигации либо `false`, если редирект выполнен ответом сервера.
71
+ */
72
+ // eslint-disable-next-line sonarjs/function-return-type
73
+ redirectToCanonicalUrl(commands, status = ScRedirectStatusEnum.Temporary) {
74
+ const urlTree = this.router.createUrlTree(commands);
75
+ if (this.isCanonicalRedirectEnabled && this.isServer && this.setServerRedirect(this.router.serializeUrl(urlTree), status)) {
76
+ return false;
77
+ }
78
+ return urlTree;
79
+ }
80
+ /**
81
+ * Выставляет редирект в ответе сервера (SSR).
82
+ *
83
+ * @param targetUrl Адрес, на который выполняется редирект.
84
+ * @param status Статус редиректа.
85
+ * @returns Признак, что редирект выставлен; `false`, если данные об ответе недоступны (например, dev-сервер `ng serve`).
86
+ */
87
+ setServerRedirect(targetUrl, status) {
88
+ if (!this.response) {
89
+ return false;
90
+ }
91
+ // Angular 21 (миграция SSR): при переходе server.ts на AngularNodeAppEngine статус и заголовок выставляются
92
+ // через нативный RESPONSE_INIT вместо Express-методов response.setHeader/response.status.
93
+ this.response.setHeader('Location', targetUrl);
94
+ this.response.status(status);
95
+ return true;
96
+ }
55
97
  /**
56
98
  * Выполняет редирект на родительскую категорию недоступной категории.
57
99
  *
@@ -133,14 +175,8 @@ export class ScCatalogRedirectService {
133
175
  const urlTree = this.router.createUrlTree(['/catalog', target]);
134
176
  const targetUrl = this.router.serializeUrl(urlTree);
135
177
  if (this.isServer) {
136
- // SSR с доступным RESPONSE (прод-сервер): выставляем 302 и заголовок Location для корректного редиректа поисковых ботов.
137
- //
138
- // Angular 21 (миграция SSR): при переходе server.ts на AngularNodeAppEngine выставляйте статус/заголовок
139
- // через нативный RESPONSE_INIT вместо Express-методов response.setHeader/response.status:
140
- // if (this.responseInit) { this.responseInit.status = 302; (this.responseInit.headers as Record<string, string>)['Location'] = targetUrl; }
141
- if (this.response) {
142
- this.response.setHeader('Location', targetUrl);
143
- this.response.status(302);
178
+ // Скрытые категория или товар могут снова стать доступными, поэтому редирект на родителя временный.
179
+ if (this.setServerRedirect(targetUrl, ScRedirectStatusEnum.Temporary)) {
144
180
  return EMPTY;
145
181
  }
146
182
  // SSR без RESPONSE (например, dev-сервер ng serve): серверный редирект невозможен,
@@ -171,4 +207,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
171
207
  providedIn: 'root',
172
208
  }]
173
209
  }] });
174
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2MtY2F0YWxvZy1yZWRpcmVjdC5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvY29yZS9jYXRhbG9nL3NlcnZpY2VzL3NjLWNhdGFsb2ctcmVkaXJlY3Quc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDM0MsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDekQsT0FBTyxFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDbkQsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ3pDLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDN0MsT0FBTyxFQUFFLFVBQVUsRUFBRSxLQUFLLEVBQXdDLFNBQVMsRUFBRSxVQUFVLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFFdEcsT0FBTyxFQUFFLFNBQVMsRUFBRSxRQUFRLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUNwRSxPQUFPLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSxxQ0FBcUMsQ0FBQztBQUU3RSxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQzs7QUFFeEQ7Ozs7Ozs7Ozs7R0FVRztBQUlILE1BQU0sT0FBTyx3QkFBd0I7SUFIckM7UUFJSTs7V0FFRztRQUNjLG1CQUFjLEdBQUcsTUFBTSxDQUFDLGdCQUFnQixDQUFDLENBQUM7UUFFM0Q7O1dBRUc7UUFDYyxXQUFNLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBRXpDOztXQUVHO1FBQ2MsYUFBUSxHQUFHLE1BQU0sQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDO1FBRTNEOztXQUVHO1FBQ2MsYUFBUSxHQUFHLE1BQU0sQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUU5Qzs7Ozs7Ozs7V0FRRztR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SSxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUM7Z0JBQ2hCLHlIQUF5SDtnQkFDekgsRUFBRTtnQkFDRix5R0FBeUc7Z0JBQ3pHLDBGQUEwRjtnQkFDMUYsOElBQThJO2dCQUM5SSxJQUFJLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztvQkFDaEIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQUMsVUFBVSxFQUFFLFNBQVMsQ0FBQyxDQUFDO29CQUMvQyxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQztvQkFFMUIsT0FBTyxLQUFLLENBQUM7Z0JBQ2pCLENBQUM7Z0JBRUQsbUZBQW1GO2dCQUNuRiwrRkFBK0Y7Z0JBQy9GLEVBQUU7Z0JBQ0YsMkdBQTJHO2dCQUMzRyx1SEFBdUg7Z0JBQ3ZILGdGQUFnRjtnQkFDaEYsT0FBTyxVQUFVLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxpQkFBaUIsQ0FBQyxFQUFFLE1BQU0sRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFDcEUsQ0FBQztZQUVELHFHQUFxRztZQUNyRyx1R0FBdUc7WUFDdkcsOEdBQThHO1lBQzlHLEVBQUU7WUFDRiwwR0FBMEc7WUFDMUcsNkdBQTZHO1lBQzdHLDJIQUEySDtZQUMzSCxJQUFJLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLENBQUM7WUFFMUMsT0FBTyxLQUFLLENBQUM7UUFDakIsQ0FBQyxDQUFDLENBQ0wsQ0FBQztJQUNOLENBQUM7K0dBektRLHdCQUF3QjttSEFBeEIsd0JBQXdCLGNBRnJCLE1BQU07OzRGQUVULHdCQUF3QjtrQkFIcEMsVUFBVTttQkFBQztvQkFDUixVQUFVLEVBQUUsTUFBTTtpQkFDckIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBET0NVTUVOVCB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQgeyBIdHRwRXJyb3JSZXNwb25zZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbi9odHRwJztcbmltcG9ydCB7IGluamVjdCwgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgUm91dGVyIH0gZnJvbSAnQGFuZ3VsYXIvcm91dGVyJztcbmltcG9ydCB7IHR1aUlzUHJlc2VudCB9IGZyb20gJ0B0YWlnYS11aS9jZGsnO1xuaW1wb3J0IHsgY2F0Y2hFcnJvciwgRU1QVFksIE1vbm9UeXBlT3BlcmF0b3JGdW5jdGlvbiwgT2JzZXJ2YWJsZSwgc3dpdGNoTWFwLCB0aHJvd0Vycm9yIH0gZnJvbSAncnhqcyc7XG5cbmltcG9ydCB7IElTX1NFUlZFUiwgUkVTUE9OU0UgfSBmcm9tICcuLi8uLi9wcm92aWRlcnMvc3NyLnByb3ZpZGVycyc7XG5pbXBvcnQgeyBTQ19JRF9PUl9TTFVHX0lOX1JPVVRFIH0gZnJvbSAnLi4vLi4vdG9rZW5zL3NjLWlkLW9yLXNsdWctaW4tcm91dGUnO1xuaW1wb3J0IHsgU2NJUGFyZW50Q2F0ZWdvcnlSZWRpcmVjdCB9IGZyb20gJy4uL2ludGVyZmFjZXMvc2MtaS1wYXJlbnQtY2F0ZWdvcnktcmVkaXJlY3QnO1xuaW1wb3J0IHsgU2NDYXRhbG9nU2VydmljZSB9IGZyb20gJy4vc2MtY2F0YWxvZy5zZXJ2aWNlJztcblxuLyoqXG4gKiDQodC10YDQstC40YEg0YDQtdC00LjRgNC10LrRgtCwINC90LAg0YDQvtC00LjRgtC10LvRjNGB0LrRg9GOINC60LDRgtC10LPQvtGA0LjRjiDQv9GA0Lgg0L3QtdC00L7RgdGC0YPQv9C90L7RgdGC0LggKEhUVFAgNDA0KSDRgtC+0LLQsNGA0LAg0LjQu9C4INC60LDRgtC10LPQvtGA0LjQuC5cbiAqXG4gKiDQl9Cw0L/RgNCw0YjQuNCy0LDQtdGCINGDINCx0Y3QutC10L3QtNCwINGA0L7QtNC40YLQtdC70YzRgdC60YPRjiDQutCw0YLQtdCz0L7RgNC40Y4g0L3QtdC00L7RgdGC0YPQv9C90L7QuSDRgdGD0YnQvdC+0YHRgtC4INC4INCy0YvQv9C+0LvQvdGP0LXRgiDRgNC10LTQuNGA0LXQutGCOlxuICogLSDQvdCwINGB0LXRgNCy0LXRgNC1IChTU1IpINC/0YDQuCDQtNC+0YHRgtGD0L/QvdC+0Lwge0BsaW5rIFJFU1BPTlNFfSDigJQg0LLRi9GB0YLQsNCy0LvRj9C10YIgSFRUUC3RgdGC0LDRgtGD0YEgMzAyINC4INC30LDQs9C+0LvQvtCy0L7QuiBgTG9jYXRpb25gINC00LvRjyDQutC+0YDRgNC10LrRgtC90L7Qs9C+INGA0LXQtNC40YDQtdC60YLQsCDQv9C+0LjRgdC60L7QstGL0YUg0LHQvtGC0L7QsjtcbiAqIC0g0L3QsCDRgdC10YDQstC10YDQtSDQsdC10Lcge0BsaW5rIFJFU1BPTlNFfSAo0L3QsNC/0YDQuNC80LXRgCwgZGV2LdGB0LXRgNCy0LXRgCBgbmcgc2VydmVgKSDigJQg0LfQsNCy0LXRgNGI0LDQtdGCINC/0L7RgtC+0Log0L7RiNC40LHQutC+0LkgNDA0LCDRh9GC0L7QsdGLINC+0YLQvtCx0YDQsNC30LjQu9Cw0YHRjCDRgdGC0YDQsNC90LjRhtCwINC+0YjQuNCx0LrQuDtcbiAqIC0g0LIg0LHRgNCw0YPQt9C10YDQtSDigJQg0LLRi9C/0L7Qu9C90Y/QtdGCINC/0L7Qu9C90YPRjiDQvdCw0LLQuNCz0LDRhtC40Y4g0L3QsCDRgNC+0LTQuNGC0LXQu9GM0YHQutGD0Y4g0LrQsNGC0LXQs9C+0YDQuNGOLlxuICpcbiAqINCV0YHQu9C4INGA0L7QtNC40YLQtdC70YzRgdC60LDRjyDQutCw0YLQtdCz0L7RgNC40Y8g0L3QtSDQvdCw0LnQtNC10L3QsCwg0L/QvtGC0L7QuiDRgtCw0LrQttC1INC30LDQstC10YDRiNCw0LXRgtGB0Y8g0L7RiNC40LHQutC+0Lkge0BsaW5rIEh0dHBFcnJvclJlc3BvbnNlfSxcbiAqINGH0YLQvtCx0Ysg0LLRi9C30YvQstCw0Y7RidC40Lkg0LrQvtC0INC+0YLQvtCx0YDQsNC30LjQuyDRgdGC0YDQsNC90LjRhtGDINC+0YjQuNCx0LrQuC5cbiAqL1xuQEluamVjdGFibGUoe1xuICAgIHByb3ZpZGVkSW46ICdyb290Jyxcbn0pXG5leHBvcnQgY2xhc3MgU2NDYXRhbG9nUmVkaXJlY3RTZXJ2aWNlIHtcbiAgICAvKipcbiAgICAgKiDQodC10YDQstC40YEg0LTQu9GPINGA0LDQsdC+0YLRiyDRgSDQutCw0YLQsNC70L7Qs9C+0LwuXG4gICAgICovXG4gICAgcHJpdmF0ZSByZWFkb25seSBjYXRhbG9nU2VydmljZSA9IGluamVjdChTY0NhdGFsb2dTZXJ2aWNlKTtcblxuICAgIC8qKlxuICAgICAqINCh0LXRgNCy0LjRgSDQvNCw0YDRiNGA0YPRgtC40LfQsNGG0LjQuC5cbiAgICAgKi9cbiAgICBwcml2YXRlIHJlYWRvbmx5IHJvdXRlciA9IGluamVjdChSb3V0ZXIpO1xuXG4gICAgLyoqXG4gICAgICog0J/RgNC40LfQvdCw0Log0LjRgdC/0L7Qu9GM0LfQvtCy0LDQvdC40Y8g0LjQtNC10L3RgtC40YTQuNC60LDRgtC+0YDQsCDQuNC70Lggc2x1ZyDQsiDQvNCw0YDRiNGA0YPRgtCw0YUg0YLQvtCy0LDRgNC+0LIg0Lgg0LrQsNGC0LXQs9C+0YDQuNC5LlxuICAgICAqL1xuICAgIHByaXZhdGUgcmVhZG9ubHkgaWRPclNsdWcgPSBpbmplY3QoU0NfSURfT1JfU0xVR19JTl9ST1VURSk7XG5cbiAgICAvKipcbiAgICAgKiDQn9GA0LjQt9C90LDQuiwg0YfRgtC+INGC0LXQutGD0YnQuNC5INGB0LrRgNC40L/RgiDQuNGB0L/QvtC70L3Rj9C10YLRgdGPINC90LAg0YHQtdGA0LLQtdGA0LUuXG4gICAgICovXG4gICAgcHJpdmF0ZSByZWFkb25seSBpc1NlcnZlciA9IGluamVjdChJU19TRVJWRVIpO1xuXG4gICAgLyoqXG4gICAgICog0JTQsNC90L3Ri9C1INC+0LEg0L7RgtCy0LXRgtC1INC90LAg0LfQsNC/0YDQvtGBICjQtNC+0YHRgtGD0L/QvdGLINGC0L7Qu9GM0LrQviDQvdCwINGB0LXRgNCy0LXRgNC1INC/0YDQuCBTU1IpLlxuICAgICAqXG4gICAgICogQW5ndWxhciAyMSAo0LzQuNCz0YDQsNGG0LjRjyBTU1IpOiB7QGxpbmsgUkVTUE9OU0V9IOKAlCDQutCw0YHRgtC+0LzQvdGL0LkgRXhwcmVzcy3RgtC+0LrQtdC9LCDQutC+0YLQvtGA0YvQuSDQv9GA0L7QstCw0LnQtNC40YLRgdGPINCyIGBzZXJ2ZXIudHNgXG4gICAgICog0YfQtdGA0LXQtyBDb21tb25FbmdpbmUuINCd0LAgdXBncmFkZS3QstC10YLQutC1IGBzZXJ2ZXIudHNgINC+0YHRgtCw0LvRgdGPINC90LAgQ29tbW9uRW5naW5lLCDQv9C+0Y3RgtC+0LzRgyDQv9GA0Lgg0YHQu9C40Y/QvdC40Lgg0LfQtNC10YHRjFxuICAgICAqINC90LjRh9C10LPQviDQvNC10L3Rj9GC0Ywg0L3QtSDQvdGD0LbQvdC+LiDQldGB0LvQuCBgc2VydmVyLnRzYCDQvNC40LPRgNC40YDRg9GO0YIg0L3QsCBgQW5ndWxhck5vZGVBcHBFbmdpbmVgICsgYGNyZWF0ZU5vZGVSZXF1ZXN0SGFuZGxlcmAsXG4gICAgICog0LfQsNC80LXQvdC40YLQtSB7QGxpbmsgUkVTUE9OU0V9INC90LAg0L3QsNGC0LjQstC90YvQuSBgUkVTUE9OU0VfSU5JVGAgKGBJbmplY3Rpb25Ub2tlbjxSZXNwb25zZUluaXQgfCBudWxsPmAg0LjQtyBgQGFuZ3VsYXIvY29yZWApO1xuICAgICAqINGB0LwuINGB0LXRgNCy0LXRgNC90YPRjiDQstC10YLQutGDINCyIHtAbGluayByZWRpcmVjdFRvUGFyZW50Q2F0ZWdvcnkkfS5cbiAgICAgKi9cbiAgICBwcml2YXRlIHJlYWRvbmx5IHJlc3BvbnNlID0gaW5qZWN0KFJFU1BPTlNFLCB7IG9wdGlvbmFsOiB0cnVlIH0pO1xuXG4gICAgLyoqXG4gICAgICog0JTQvtC60YPQvNC10L3RgiDRgtC10LrRg9GJ0LXQuSDRgdGC0YDQsNC90LjRhtGLLlxuICAgICAqL1xuICAgIHByaXZhdGUgcmVhZG9ubHkgZG9jdW1lbnQgPSBpbmplY3QoRE9DVU1FTlQpO1xuXG4gICAgLyoqXG4gICAgICog0JLRi9C/0L7Qu9C90Y/QtdGCINGA0LXQtNC40YDQtdC60YIg0L3QsCDRgNC+0LTQuNGC0LXQu9GM0YHQutGD0Y4g0LrQsNGC0LXQs9C+0YDQuNGOINC90LXQtNC+0YHRgtGD0L/QvdC+0Lkg0LrQsNGC0LXQs9C+0YDQuNC4LlxuICAgICAqXG4gICAgICogQHBhcmFtIGNhdGVnb3J5SWRPclNsdWcg0JjQtNC10L3RgtC40YTQuNC60LDRgtC+0YAg0LjQu9C4IHNsdWcg0L3QtdC00L7RgdGC0YPQv9C90L7QuSDQutCw0YLQtdCz0L7RgNC40LguXG4gICAgICogQHJldHVybnMg0J/QvtGC0L7Quiwg0LfQsNCy0LXRgNGI0LDRjtGJ0LjQudGB0Y8g0L/QvtGB0LvQtSDRgNC10LTQuNGA0LXQutGC0LAuINCt0LzQuNGC0LjRgiDQvtGI0LjQsdC60YMge0BsaW5rIEh0dHBFcnJvclJlc3BvbnNlfSwg0LXRgdC70Lgg0YDQvtC00LjRgtC10LvRjNGB0LrQsNGPINC60LDRgtC10LPQvtGA0LjRjyDQvdC1INC90LDQudC00LXQvdCwLlxuICAgICAqL1xuICAgIHB1YmxpYyByZWRpcmVjdFRvQ2F0ZWdvcnlQYXJlbnQkKGNhdGVnb3J5SWRPclNsdWc6IG51bWJlciB8IHN0cmluZyk6IE9ic2VydmFibGU8bmV2ZXI+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMucmVkaXJlY3RUb1BhcmVudENhdGVnb3J5JCh0aGlzLmNhdGFsb2dTZXJ2aWNlLmdldENhdGVnb3J5UGFyZW50Q2F0ZWdvcnkkKGNhdGVnb3J5SWRPclNsdWcpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiDQktGL0L/QvtC70L3Rj9C10YIg0YDQtdC00LjRgNC10LrRgiDQvdCwINGA0L7QtNC40YLQtdC70YzRgdC60YPRjiDQutCw0YLQtdCz0L7RgNC40Y4g0L3QtdC00L7RgdGC0YPQv9C90L7Qs9C+INGC0L7QstCw0YDQsC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBwcm9kdWN0SWRPclNsdWcg0JjQtNC10L3RgtC40YTQuNC60LDRgtC+0YAg0LjQu9C4IHNsdWcg0L3QtdC00L7RgdGC0YPQv9C90L7Qs9C+INGC0L7QstCw0YDQsC5cbiAgICAgKiBAcmV0dXJucyDQn9C+0YLQvtC6LCDQt9Cw0LLQtdGA0YjQsNGO0YnQuNC50YHRjyDQv9C+0YHQu9C1INGA0LXQtNC40YDQtdC60YLQsC4g0K3QvNC40YLQuNGCINC+0YjQuNCx0LrRgyB7QGxpbmsgSHR0cEVycm9yUmVzcG9uc2V9LCDQtdGB0LvQuCDRgNC+0LTQuNGC0LXQu9GM0YHQutCw0Y8g0LrQsNGC0LXQs9C+0YDQuNGPINC90LUg0L3QsNC50LTQtdC90LAuXG4gICAgICovXG4gICAgcHVibGljIHJlZGlyZWN0VG9Qcm9kdWN0UGFyZW50JChwcm9kdWN0SWRPclNsdWc6IG51bWJlciB8IHN0cmluZyk6IE9ic2VydmFibGU8bmV2ZXI+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMucmVkaXJlY3RUb1BhcmVudENhdGVnb3J5JCh0aGlzLmNhdGFsb2dTZXJ2aWNlLmdldFByb2R1Y3RQYXJlbnRDYXRlZ29yeSQocHJvZHVjdElkT3JTbHVnKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICog0J7Qv9C10YDQsNGC0L7RgCDRg9GB0YLQvtC50YfQuNCy0L7QuSDQvtCx0YDQsNCx0L7RgtC60Lgg0L3QtdC00L7RgdGC0YPQv9C90L7QuSAoSFRUUC3QvtGI0LjQsdC60LApINC60LDRgtC10LPQvtGA0LjQuCDQsiDQv9C+0YLQvtC60LUg0LTQsNC90L3Ri9GFOiDQv9GA0LggNDA0INCy0YvQv9C+0LvQvdGP0LXRgiDRgNC10LTQuNGA0LXQutGCXG4gICAgICog0L3QsCDRgNC+0LTQuNGC0LXQu9GM0YHQutGD0Y4g0LrQsNGC0LXQs9C+0YDQuNGOLCDQv9GA0Lgg0L3QtdC00L7RgdGC0YPQv9C90L7QvCDRgNC+0LTQuNGC0LXQu9C1INC40LvQuCDQuNC90L7QuSDQvtGI0LjQsdC60LUg0YHQvtC+0LHRidCw0LXRgiDQutC+0LQg0YfQtdGA0LXQtyB7QGxpbmsgb25FcnJvckNvZGV9LlxuICAgICAqINCe0YjQuNCx0LrRgyDQvdC1INC/0YDQvtCx0YDQsNGB0YvQstCw0LXRgiAo0LfQsNCy0LXRgNGI0LDQtdGCINC/0L7RgtC+0Loge0BsaW5rIEVNUFRZfSksINC/0L7RjdGC0L7QvNGDINC/0L7RgtC+0Log0LTQsNC90L3Ri9GFINC90LUg0LfQsNCy0LXRgNGI0LDQtdGC0YHRjyDQvtGI0LjQsdC60L7QuS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBjYXRlZ29yeUlkT3JTbHVnINCY0LTQtdC90YLQuNGE0LjQutCw0YLQvtGAINC40LvQuCBzbHVnINC90LXQtNC+0YHRgtGD0L/QvdC+0Lkg0LrQsNGC0LXQs9C+0YDQuNC4LlxuICAgICAqIEBwYXJhbSBvbkVycm9yQ29kZSDQmtC+0LvQsdGN0Log0YPRgdGC0LDQvdC+0LLQutC4INC60L7QtNCwINC+0YjQuNCx0LrQuCAo0L3QsNC/0YDQuNC80LXRgCwg0LTQu9GPINC+0YLQvtCx0YDQsNC20LXQvdC40Y8g0YHRgtGA0LDQvdC40YbRiyDQvtGI0LjQsdC60LgpLlxuICAgICAqL1xuICAgIHB1YmxpYyBoYW5kbGVVbmF2YWlsYWJsZUNhdGVnb3J5JDxUPihjYXRlZ29yeUlkT3JTbHVnOiBudW1iZXIgfCBzdHJpbmcsIG9uRXJyb3JDb2RlOiAoc3RhdHVzOiBudW1iZXIpID0+IHZvaWQpOiBNb25vVHlwZU9wZXJhdG9yRnVuY3Rpb248VD4ge1xuICAgICAgICByZXR1cm4gdGhpcy5oYW5kbGVVbmF2YWlsYWJsZSQoKCkgPT4gdGhpcy5yZWRpcmVjdFRvQ2F0ZWdvcnlQYXJlbnQkKGNhdGVnb3J5SWRPclNsdWcpLCBvbkVycm9yQ29kZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICog0J7Qv9C10YDQsNGC0L7RgCDRg9GB0YLQvtC50YfQuNCy0L7QuSDQvtCx0YDQsNCx0L7RgtC60Lgg0L3QtdC00L7RgdGC0YPQv9C90L7Qs9C+IChIVFRQLdC+0YjQuNCx0LrQsCkg0YLQvtCy0LDRgNCwINCyINC/0L7RgtC+0LrQtSDQtNCw0L3QvdGL0YU6INC/0YDQuCA0MDQg0LLRi9C/0L7Qu9C90Y/QtdGCINGA0LXQtNC40YDQtdC60YJcbiAgICAgKiDQvdCwINGA0L7QtNC40YLQtdC70YzRgdC60YPRjiDQutCw0YLQtdCz0L7RgNC40Y4g0YLQvtCy0LDRgNCwLCDQv9GA0Lgg0L3QtdC00L7RgdGC0YPQv9C90L7QvCDRgNC+0LTQuNGC0LXQu9C1INC40LvQuCDQuNC90L7QuSDQvtGI0LjQsdC60LUg0YHQvtC+0LHRidCw0LXRgiDQutC+0LQg0YfQtdGA0LXQtyB7QGxpbmsgb25FcnJvckNvZGV9LlxuICAgICAqINCe0YjQuNCx0LrRgyDQvdC1INC/0YDQvtCx0YDQsNGB0YvQstCw0LXRgiAo0LfQsNCy0LXRgNGI0LDQtdGCINC/0L7RgtC+0Loge0BsaW5rIEVNUFRZfSksINC/0L7RjdGC0L7QvNGDINC/0L7RgtC+0Log0LTQsNC90L3Ri9GFINC90LUg0LfQsNCy0LXRgNGI0LDQtdGC0YHRjyDQvtGI0LjQsdC60L7QuS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBwcm9kdWN0SWRPclNsdWcg0JjQtNC10L3RgtC40YTQuNC60LDRgtC+0YAg0LjQu9C4IHNsdWcg0L3QtdC00L7RgdGC0YPQv9C90L7Qs9C+INGC0L7QstCw0YDQsC5cbiAgICAgKiBAcGFyYW0gb25FcnJvckNvZGUg0JrQvtC70LHRjdC6INGD0YHRgtCw0L3QvtCy0LrQuCDQutC+0LTQsCDQvtGI0LjQsdC60LggKNC90LDQv9GA0LjQvNC10YAsINC00LvRjyDQvtGC0L7QsdGA0LDQttC10L3QuNGPINGB0YLRgNCw0L3QuNGG0Ysg0L7RiNC40LHQutC4KS5cbiAgICAgKi9cbiAgICBwdWJsaWMgaGFuZGxlVW5hdmFpbGFibGVQcm9kdWN0JDxUPihwcm9kdWN0SWRPclNsdWc6IG51bWJlciB8IHN0cmluZywgb25FcnJvckNvZGU6IChzdGF0dXM6IG51bWJlcikgPT4gdm9pZCk6IE1vbm9UeXBlT3BlcmF0b3JGdW5jdGlvbjxUPiB7XG4gICAgICAgIHJldHVybiB0aGlzLmhhbmRsZVVuYXZhaWxhYmxlJCgoKSA9PiB0aGlzLnJlZGlyZWN0VG9Qcm9kdWN0UGFyZW50JChwcm9kdWN0SWRPclNsdWcpLCBvbkVycm9yQ29kZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICog0JHQsNC30L7QstGL0Lkg0L7Qv9C10YDQsNGC0L7RgCDRg9GB0YLQvtC50YfQuNCy0L7QuSDQvtCx0YDQsNCx0L7RgtC60Lgg0L3QtdC00L7RgdGC0YPQv9C90L7QuSDRgdGD0YnQvdC+0YHRgtC4OiDQv9GA0LggNDA0IOKAlCDRgNC10LTQuNGA0LXQutGCINC90LAg0YDQvtC00LjRgtC10LvRjyAo0YfQtdGA0LXQtyB7QGxpbmsgcmVkaXJlY3RUb1BhcmVudCR9KSxcbiAgICAgKiDQv9GA0Lgg0L3QtdC00L7RgdGC0YPQv9C90L7QvCDRgNC+0LTQuNGC0LXQu9C1INC40LvQuCDQuNC90L7QvCB7QGxpbmsgSHR0cEVycm9yUmVzcG9uc2V9IOKAlCB7QGxpbmsgb25FcnJvckNvZGV9INGBINC60L7QtNC+0Lwg0L7RgtCy0LXRgtCwOyDQstGB0LXQs9C00LAge0BsaW5rIEVNUFRZfS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSByZWRpcmVjdFRvUGFyZW50JCDQpNCw0LHRgNC40LrQsCDQv9C+0YLQvtC60LAg0YDQtdC00LjRgNC10LrRgtCwINC90LAg0YDQvtC00LjRgtC10LvRjNGB0LrRg9GOINC60LDRgtC10LPQvtGA0LjRji5cbiAgICAgKiBAcGFyYW0gb25FcnJvckNvZGUg0JrQvtC70LHRjdC6INGD0YHRgtCw0L3QvtCy0LrQuCDQutC+0LTQsCDQvtGI0LjQsdC60LguXG4gICAgICovXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGNsYXNzLW1ldGhvZHMtdXNlLXRoaXNcbiAgICBwcml2YXRlIGhhbmRsZVVuYXZhaWxhYmxlJDxUPihyZWRpcmVjdFRvUGFyZW50JDogKCkgPT4gT2JzZXJ2YWJsZTxuZXZlcj4sIG9uRXJyb3JDb2RlOiAoc3RhdHVzOiBudW1iZXIpID0+IHZvaWQpOiBNb25vVHlwZU9wZXJhdG9yRnVuY3Rpb248VD4ge1xuICAgICAgICByZXR1cm4gKHNvdXJjZSQpID0+XG4gICAgICAgICAgICBzb3VyY2UkLnBpcGUoXG4gICAgICAgICAgICAgICAgY2F0Y2hFcnJvcigoZXJyb3I6IHVua25vd24pID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yIGluc3RhbmNlb2YgSHR0cEVycm9yUmVzcG9uc2UgJiYgZXJyb3Iuc3RhdHVzID09PSA0MDQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZWRpcmVjdFRvUGFyZW50JCgpLnBpcGUoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2F0Y2hFcnJvcigocmVkaXJlY3RFcnJvcjogdW5rbm93bikgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVkaXJlY3RFcnJvciBpbnN0YW5jZW9mIEh0dHBFcnJvclJlc3BvbnNlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbkVycm9yQ29kZShyZWRpcmVjdEVycm9yLnN0YXR1cyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gRU1QVFk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBIdHRwRXJyb3JSZXNwb25zZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgb25FcnJvckNvZGUoZXJyb3Iuc3RhdHVzKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBFTVBUWTtcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiDQktGL0L/QvtC70L3Rj9C10YIg0YDQtdC00LjRgNC10LrRgiDQvdCwINC/0L7Qu9GD0YfQtdC90L3Rg9GOINGA0L7QtNC40YLQtdC70YzRgdC60YPRjiDQutCw0YLQtdCz0L7RgNC40Y4uXG4gICAgICpcbiAgICAgKiBAcGFyYW0gcGFyZW50Q2F0ZWdvcnkkINCf0L7RgtC+0Log0YEg0LTQsNC90L3Ri9C80Lgg0YDQvtC00LjRgtC10LvRjNGB0LrQvtC5INC60LDRgtC10LPQvtGA0LjQuC5cbiAgICAgKiBAcmV0dXJucyDQn9C+0YLQvtC6LCDQt9Cw0LLQtdGA0YjQsNGO0YnQuNC50YHRjyDQv9C+0YHQu9C1INGA0LXQtNC40YDQtdC60YLQsC4g0K3QvNC40YLQuNGCINC+0YjQuNCx0LrRgyB7QGxpbmsgSHR0cEVycm9yUmVzcG9uc2V9INGBINC60L7QtNC+0LwgNDA0LCDQtdGB0LvQuCDRgNC+0LTQuNGC0LXQu9GM0YHQutCw0Y8g0LrQsNGC0LXQs9C+0YDQuNGPINC90LUg0L3QsNC50LTQtdC90LAuXG4gICAgICovXG4gICAgcHJpdmF0ZSByZWRpcmVjdFRvUGFyZW50Q2F0ZWdvcnkkKHBhcmVudENhdGVnb3J5JDogT2JzZXJ2YWJsZTxTY0lQYXJlbnRDYXRlZ29yeVJlZGlyZWN0Pik6IE9ic2VydmFibGU8bmV2ZXI+IHtcbiAgICAgICAgcmV0dXJuIHBhcmVudENhdGVnb3J5JC5waXBlKFxuICAgICAgICAgICAgc3dpdGNoTWFwKChwYXJlbnRDYXRlZ29yeSkgPT4ge1xuICAgICAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBzZWN1cml0eS9kZXRlY3Qtb2JqZWN0LWluamVjdGlvblxuICAgICAgICAgICAgICAgIGNvbnN0IHRhcmdldCA9IHBhcmVudENhdGVnb3J5W3RoaXMuaWRPclNsdWddO1xuXG4gICAgICAgICAgICAgICAgLy8g0KDQvtC00LjRgtC10LvRjNGB0LrQsNGPINC60LDRgtC10LPQvtGA0LjRjyDQvdC1INC90LDQudC00LXQvdCwIOKAlCDQvtGC0L7QsdGA0LDQttCw0LXQvCDRgdGC0YDQsNC90LjRhtGDINC+0YjQuNCx0LrQuC5cbiAgICAgICAgICAgICAgICBpZiAoIXR1aUlzUHJlc2VudCh0YXJnZXQpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aHJvd0Vycm9yKCgpID0+IG5ldyBIdHRwRXJyb3JSZXNwb25zZSh7IHN0YXR1czogNDA0IH0pKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBjb25zdCB1cmxUcmVlID0gdGhpcy5yb3V0ZXIuY3JlYXRlVXJsVHJlZShbJy9jYXRhbG9nJywgdGFyZ2V0XSk7XG5cbiAgICAgICAgICAgICAgICBjb25zdCB0YXJnZXRVcmwgPSB0aGlzLnJvdXRlci5zZXJpYWxpemVVcmwodXJsVHJlZSk7XG5cbiAgICAgICAgICAgICAgICBpZiAodGhpcy5pc1NlcnZlcikge1xuICAgICAgICAgICAgICAgICAgICAvLyBTU1Ig0YEg0LTQvtGB0YLRg9C/0L3Ri9C8IFJFU1BPTlNFICjQv9GA0L7QtC3RgdC10YDQstC10YApOiDQstGL0YHRgtCw0LLQu9GP0LXQvCAzMDIg0Lgg0LfQsNCz0L7Qu9C+0LLQvtC6IExvY2F0aW9uINC00LvRjyDQutC+0YDRgNC10LrRgtC90L7Qs9C+INGA0LXQtNC40YDQtdC60YLQsCDQv9C+0LjRgdC60L7QstGL0YUg0LHQvtGC0L7Qsi5cbiAgICAgICAgICAgICAgICAgICAgLy9cbiAgICAgICAgICAgICAgICAgICAgLy8gQW5ndWxhciAyMSAo0LzQuNCz0YDQsNGG0LjRjyBTU1IpOiDQv9GA0Lgg0L/QtdGA0LXRhdC+0LTQtSBzZXJ2ZXIudHMg0L3QsCBBbmd1bGFyTm9kZUFwcEVuZ2luZSDQstGL0YHRgtCw0LLQu9GP0LnRgtC1INGB0YLQsNGC0YPRgS/Qt9Cw0LPQvtC70L7QstC+0LpcbiAgICAgICAgICAgICAgICAgICAgLy8g0YfQtdGA0LXQtyDQvdCw0YLQuNCy0L3Ri9C5IFJFU1BPTlNFX0lOSVQg0LLQvNC10YHRgtC+IEV4cHJlc3Mt0LzQtdGC0L7QtNC+0LIgcmVzcG9uc2Uuc2V0SGVhZGVyL3Jlc3BvbnNlLnN0YXR1czpcbiAgICAgICAgICAgICAgICAgICAgLy8gICBpZiAodGhpcy5yZXNwb25zZUluaXQpIHsgdGhpcy5yZXNwb25zZUluaXQuc3RhdHVzID0gMzAyOyAodGhpcy5yZXNwb25zZUluaXQuaGVhZGVycyBhcyBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+KVsnTG9jYXRpb24nXSA9IHRhcmdldFVybDsgfVxuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5yZXNwb25zZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5yZXNwb25zZS5zZXRIZWFkZXIoJ0xvY2F0aW9uJywgdGFyZ2V0VXJsKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucmVzcG9uc2Uuc3RhdHVzKDMwMik7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBFTVBUWTtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIC8vIFNTUiDQsdC10LcgUkVTUE9OU0UgKNC90LDQv9GA0LjQvNC10YAsIGRldi3RgdC10YDQstC10YAgbmcgc2VydmUpOiDRgdC10YDQstC10YDQvdGL0Lkg0YDQtdC00LjRgNC10LrRgiDQvdC10LLQvtC30LzQvtC20LXQvSxcbiAgICAgICAgICAgICAgICAgICAgLy8g0L/QvtGN0YLQvtC80YMg0L7RgtC+0LHRgNCw0LbQsNC10Lwg0YHRgtGA0LDQvdC40YbRgyDQvtGI0LjQsdC60LgsINC60LDQuiDQtNC+INCy0L3QtdC00YDQtdC90LjRjyDRgNC10LTQuNGA0LXQutGC0LAsINCy0LzQtdGB0YLQviDQsdC10YHQutC+0L3QtdGH0L3QvtCz0L4g0LvQvtCw0LTQtdGA0LAuXG4gICAgICAgICAgICAgICAgICAgIC8vXG4gICAgICAgICAgICAgICAgICAgIC8vIEFuZ3VsYXIgMjEgKNC80LjQs9GA0LDRhtC40Y8gU1NSKTog0Y3RgtC+0YIg0YTQvtC70LHRjdC6INC90YPQttC10L0sINC/0L7QutCwIG5nIHNlcnZlINC90LUg0LjRgdC/0L7Qu9C90Y/QtdGCIHNlcnZlci50cyAo0L7QvSDQvdCwIENvbW1vbkVuZ2luZSkuXG4gICAgICAgICAgICAgICAgICAgIC8vINCf0L7RgdC70LUg0LzQuNCz0YDQsNGG0LjQuCBzZXJ2ZXIudHMg0L3QsCBjcmVhdGVOb2RlUmVxdWVzdEhhbmRsZXIgZGV2LdGB0LXRgNCy0LXRgCDQvdCw0YfQvdGR0YIg0LjRgdC/0L7Qu9C90Y/RgtGMIHNlcnZlci50cywg0LggUkVTUE9OU0UvUkVTUE9OU0VfSU5JVFxuICAgICAgICAgICAgICAgICAgICAvLyDRgdGC0LDQvdC10YIg0LTQvtGB0YLRg9C/0LXQvSDQsiBuZyBzZXJ2ZSDigJQg0YLQvtCz0LTQsCDRjdGC0YMg0LLQtdGC0LrRgyDRgSB0aHJvd0Vycm9yKDQwNCkg0LzQvtC20L3QviDRg9C00LDQu9C40YLRjC5cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRocm93RXJyb3IoKCkgPT4gbmV3IEh0dHBFcnJvclJlc3BvbnNlKHsgc3RhdHVzOiA0MDQgfSkpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIC8vINCR0YDQsNGD0LfQtdGAOiDQv9C+0YLQvtC6INC00LDQvdC90YvRhSDQutCw0YLQtdCz0L7RgNC40LggKFNDX0NBVEVHT1JZX0lORk8pINC30LDQstC10YDRiNCw0LXRgtGB0Y8g0L7RiNC40LHQutC+0Lkg0L/RgNC4IDQwNCDQuCDQvdC1INCy0L7Qt9C+0LHQvdC+0LLQu9GP0LXRgtGB0Y9cbiAgICAgICAgICAgICAgICAvLyDQv9GA0Lgg0L3QsNCy0LjQs9Cw0YbQuNC4INCyINGA0LDQvNC60LDRhSDRgtC+0LPQviDQttC1INC80LDRgNGI0YDRg9GC0LAsINC/0L7RjdGC0L7QvNGDINGA0LXQtNC40YDQtdC60YIg0LLRi9C/0L7Qu9C90Y/QtdGC0YHRjyDQv9C+0LvQvdC+0Lkg0L/QtdGA0LXQt9Cw0LPRgNGD0LfQutC+0Lkg0YHRgtGA0LDQvdC40YbRiy5cbiAgICAgICAgICAgICAgICAvLyBsb2NhdGlvbi5yZXBsYWNlINC90LUg0LTQvtCx0LDQstC70Y/QtdGCINC30LDQv9C40YHRjCDQsiDQuNGB0YLQvtGA0LjRjiwg0YfRgtC+0LHRiyDQutC90L7Qv9C60LAgwqvQndCw0LfQsNC0wrsg0L3QtSDQstC+0LfQstGA0LDRidCw0LvQsCDQvdCwINC90LXQtNC+0YHRgtGD0L/QvdGD0Y4g0YHRgtGA0LDQvdC40YbRgy5cbiAgICAgICAgICAgICAgICAvL1xuICAgICAgICAgICAgICAgIC8vIEFuZ3VsYXIgMjEgKNC80LjQs9GA0LDRhtC40Y8gU1NSKTog0Y3RgtGDINGB0YLRgNC+0LrRgyDQsNC/0LPRgNC10LnQtCDQndCVINGB0L3QuNC80LDQtdGCIOKAlCDQv9GA0LjRh9C40L3QsCDQsiDRgNCw0L3RgtCw0LnQvNC1INC/0YDQuNC70L7QttC10L3QuNGPICjQvNGR0YDRgtCy0YvQuSDQv9C+0YLQvtC6XG4gICAgICAgICAgICAgICAgLy8gU0NfQ0FURUdPUllfSU5GTyDQv9GA0LggU1BBLdC90LDQstC40LPQsNGG0LjQuCksINCwINC90LUg0LIgU1NSLiDQktC10YDQvdGD0YLRjCBTUEEt0L3QsNCy0LjQs9Cw0YbQuNGOIChyb3V0ZXIubmF2aWdhdGVCeVVybCkg0LzQvtC20L3QviDRgtC+0LvRjNC60L5cbiAgICAgICAgICAgICAgICAvLyDRgdC00LXQu9Cw0LIgU0NfQ0FURUdPUllfSU5GTyDRg9GB0YLQvtC50YfQuNCy0YvQvCDQuiA0MDQgKNC70L7QstC40YLRjCDQvtGI0LjQsdC60YMg0LLQvdGD0YLRgNC4IHN3aXRjaE1hcCkg0LvQuNCx0L4g0YPQvdC10YHRjyDRgNC10LTQuNGA0LXQutGCINCyIGd1YXJkICsgUmVkaXJlY3RDb21tYW5kLlxuICAgICAgICAgICAgICAgIHRoaXMuZG9jdW1lbnQubG9jYXRpb24ucmVwbGFjZSh0YXJnZXRVcmwpO1xuXG4gICAgICAgICAgICAgICAgcmV0dXJuIEVNUFRZO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgKTtcbiAgICB9XG59XG4iXX0=
210
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2MtY2F0YWxvZy1yZWRpcmVjdC5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvY29yZS9jYXRhbG9nL3NlcnZpY2VzL3NjLWNhdGFsb2ctcmVkaXJlY3Quc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDM0MsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDekQsT0FBTyxFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDbkQsT0FBTyxFQUFFLE1BQU0sRUFBVyxNQUFNLGlCQUFpQixDQUFDO0FBQ2xELE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDN0MsT0FBTyxFQUFFLFVBQVUsRUFBRSxLQUFLLEVBQXdDLFNBQVMsRUFBRSxVQUFVLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFFdEcsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0seUNBQXlDLENBQUM7QUFDL0UsT0FBTyxFQUFFLFNBQVMsRUFBRSxRQUFRLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUNwRSxPQUFPLEVBQUUsNkJBQTZCLEVBQUUsTUFBTSw0Q0FBNEMsQ0FBQztBQUMzRixPQUFPLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSxxQ0FBcUMsQ0FBQztBQUU3RSxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQzs7QUFFeEQ7Ozs7Ozs7Ozs7Ozs7R0FhRztBQUlILE1BQU0sT0FBTyx3QkFBd0I7SUFIckM7UUFJSTs7V0FFRztRQUNjLG1CQUFjLEdBQUcsTUFBTSxDQUFDLGdCQUFnQixDQUFDLENBQUM7UUFFM0Q7O1dBRUc7UUFDYyxXQUFNLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBRXpDOztXQUVHO1FBQ2MsYUFBUSxHQUFHLE1BQU0s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LENBQUM7b0JBQ3BFLE9BQU8sS0FBSyxDQUFDO2dCQUNqQixDQUFDO2dCQUVELG1GQUFtRjtnQkFDbkYsK0ZBQStGO2dCQUMvRixFQUFFO2dCQUNGLDJHQUEyRztnQkFDM0csdUhBQXVIO2dCQUN2SCxnRkFBZ0Y7Z0JBQ2hGLE9BQU8sVUFBVSxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksaUJBQWlCLENBQUMsRUFBRSxNQUFNLEVBQUUsR0FBRyxFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQ3BFLENBQUM7WUFFRCxxR0FBcUc7WUFDckcsdUdBQXVHO1lBQ3ZHLDhHQUE4RztZQUM5RyxFQUFFO1lBQ0YsMEdBQTBHO1lBQzFHLDZHQUE2RztZQUM3RywySEFBMkg7WUFDM0gsSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxDQUFDO1lBRTFDLE9BQU8sS0FBSyxDQUFDO1FBQ2pCLENBQUMsQ0FBQyxDQUNMLENBQUM7SUFDTixDQUFDOytHQTlNUSx3QkFBd0I7bUhBQXhCLHdCQUF3QixjQUZyQixNQUFNOzs0RkFFVCx3QkFBd0I7a0JBSHBDLFVBQVU7bUJBQUM7b0JBQ1IsVUFBVSxFQUFFLE1BQU07aUJBQ3JCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRE9DVU1FTlQgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgSHR0cEVycm9yUmVzcG9uc2UgfSBmcm9tICdAYW5ndWxhci9jb21tb24vaHR0cCc7XG5pbXBvcnQgeyBpbmplY3QsIEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IFJvdXRlciwgVXJsVHJlZSB9IGZyb20gJ0Bhbmd1bGFyL3JvdXRlcic7XG5pbXBvcnQgeyB0dWlJc1ByZXNlbnQgfSBmcm9tICdAdGFpZ2EtdWkvY2RrJztcbmltcG9ydCB7IGNhdGNoRXJyb3IsIEVNUFRZLCBNb25vVHlwZU9wZXJhdG9yRnVuY3Rpb24sIE9ic2VydmFibGUsIHN3aXRjaE1hcCwgdGhyb3dFcnJvciB9IGZyb20gJ3J4anMnO1xuXG5pbXBvcnQgeyBTY1JlZGlyZWN0U3RhdHVzRW51bSB9IGZyb20gJy4uLy4uL2NvbW1vbi9lbnVtcy9yZWRpcmVjdC1zdGF0dXMtZW51bSc7XG5pbXBvcnQgeyBJU19TRVJWRVIsIFJFU1BPTlNFIH0gZnJvbSAnLi4vLi4vcHJvdmlkZXJzL3Nzci5wcm92aWRlcnMnO1xuaW1wb3J0IHsgU0NfQ0FOT05JQ0FMX1JFRElSRUNUX0VOQUJMRUQgfSBmcm9tICcuLi8uLi90b2tlbnMvc2MtY2Fub25pY2FsLXJlZGlyZWN0LWVuYWJsZWQnO1xuaW1wb3J0IHsgU0NfSURfT1JfU0xVR19JTl9ST1VURSB9IGZyb20gJy4uLy4uL3Rva2Vucy9zYy1pZC1vci1zbHVnLWluLXJvdXRlJztcbmltcG9ydCB7IFNjSVBhcmVudENhdGVnb3J5UmVkaXJlY3QgfSBmcm9tICcuLi9pbnRlcmZhY2VzL3NjLWktcGFyZW50LWNhdGVnb3J5LXJlZGlyZWN0JztcbmltcG9ydCB7IFNjQ2F0YWxvZ1NlcnZpY2UgfSBmcm9tICcuL3NjLWNhdGFsb2cuc2VydmljZSc7XG5cbi8qKlxuICog0KHQtdGA0LLQuNGBINGA0LXQtNC40YDQtdC60YLQvtCyINC60LDRgtCw0LvQvtCz0LA6INC90LAg0YDQvtC00LjRgtC10LvRjNGB0LrRg9GOINC60LDRgtC10LPQvtGA0LjRjiDQv9GA0Lgg0L3QtdC00L7RgdGC0YPQv9C90L7RgdGC0LggKEhUVFAgNDA0KSDRgtC+0LLQsNGA0LAg0LjQu9C4INC60LDRgtC10LPQvtGA0LjQuFxuICog0Lgg0L3QsCDQutCw0L3QvtC90LjRh9C10YHQutC40Lkg0LDQtNGA0LXRgSDRgtC+0LLQsNGA0LAg0LjQu9C4INC60LDRgtC10LPQvtGA0LjQuCAo0YHQvC4ge0BsaW5rIHJlZGlyZWN0VG9DYW5vbmljYWxVcmx9KS5cbiAqXG4gKiDQoNC10LTQuNGA0LXQutGCINC90LAg0YDQvtC00LjRgtC10LvRjNGB0LrRg9GOINC60LDRgtC10LPQvtGA0LjRji5cbiAqXG4gKiDQl9Cw0L/RgNCw0YjQuNCy0LDQtdGCINGDINCx0Y3QutC10L3QtNCwINGA0L7QtNC40YLQtdC70YzRgdC60YPRjiDQutCw0YLQtdCz0L7RgNC40Y4g0L3QtdC00L7RgdGC0YPQv9C90L7QuSDRgdGD0YnQvdC+0YHRgtC4INC4INCy0YvQv9C+0LvQvdGP0LXRgiDRgNC10LTQuNGA0LXQutGCOlxuICogLSDQvdCwINGB0LXRgNCy0LXRgNC1IChTU1IpINC/0YDQuCDQtNC+0YHRgtGD0L/QvdC+0Lwge0BsaW5rIFJFU1BPTlNFfSDigJQg0LLRi9GB0YLQsNCy0LvRj9C10YIgSFRUUC3RgdGC0LDRgtGD0YEgMzAyINC4INC30LDQs9C+0LvQvtCy0L7QuiBgTG9jYXRpb25gINC00LvRjyDQutC+0YDRgNC10LrRgtC90L7Qs9C+INGA0LXQtNC40YDQtdC60YLQsCDQv9C+0LjRgdC60L7QstGL0YUg0LHQvtGC0L7QsjtcbiAqIC0g0L3QsCDRgdC10YDQstC10YDQtSDQsdC10Lcge0BsaW5rIFJFU1BPTlNFfSAo0L3QsNC/0YDQuNC80LXRgCwgZGV2LdGB0LXRgNCy0LXRgCBgbmcgc2VydmVgKSDigJQg0LfQsNCy0LXRgNGI0LDQtdGCINC/0L7RgtC+0Log0L7RiNC40LHQutC+0LkgNDA0LCDRh9GC0L7QsdGLINC+0YLQvtCx0YDQsNC30LjQu9Cw0YHRjCDRgdGC0YDQsNC90LjRhtCwINC+0YjQuNCx0LrQuDtcbiAqIC0g0LIg0LHRgNCw0YPQt9C10YDQtSDigJQg0LLRi9C/0L7Qu9C90Y/QtdGCINC/0L7Qu9C90YPRjiDQvdCw0LLQuNCz0LDRhtC40Y4g0L3QsCDRgNC+0LTQuNGC0LXQu9GM0YHQutGD0Y4g0LrQsNGC0LXQs9C+0YDQuNGOLlxuICpcbiAqINCV0YHQu9C4INGA0L7QtNC40YLQtdC70YzRgdC60LDRjyDQutCw0YLQtdCz0L7RgNC40Y8g0L3QtSDQvdCw0LnQtNC10L3QsCwg0L/QvtGC0L7QuiDRgtCw0LrQttC1INC30LDQstC10YDRiNCw0LXRgtGB0Y8g0L7RiNC40LHQutC+0Lkge0BsaW5rIEh0dHBFcnJvclJlc3BvbnNlfSxcbiAqINGH0YLQvtCx0Ysg0LLRi9C30YvQstCw0Y7RidC40Lkg0LrQvtC0INC+0YLQvtCx0YDQsNC30LjQuyDRgdGC0YDQsNC90LjRhtGDINC+0YjQuNCx0LrQuC5cbiAqL1xuQEluamVjdGFibGUoe1xuICAgIHByb3ZpZGVkSW46ICdyb290Jyxcbn0pXG5leHBvcnQgY2xhc3MgU2NDYXRhbG9nUmVkaXJlY3RTZXJ2aWNlIHtcbiAgICAvKipcbiAgICAgKiDQodC10YDQstC40YEg0LTQu9GPINGA0LDQsdC+0YLRiyDRgSDQutCw0YLQsNC70L7Qs9C+0LwuXG4gICAgICovXG4gICAgcHJpdmF0ZSByZWFkb25seSBjYXRhbG9nU2VydmljZSA9IGluamVjdChTY0NhdGFsb2dTZXJ2aWNlKTtcblxuICAgIC8qKlxuICAgICAqINCh0LXRgNCy0LjRgSDQvNCw0YDRiNGA0YPRgtC40LfQsNGG0LjQuC5cbiAgICAgKi9cbiAgICBwcml2YXRlIHJlYWRvbmx5IHJvdXRlciA9IGluamVjdChSb3V0ZXIpO1xuXG4gICAgLyoqXG4gICAgICog0J/RgNC40LfQvdCw0Log0LjRgdC/0L7Qu9GM0LfQvtCy0LDQvdC40Y8g0LjQtNC10L3RgtC40YTQuNC60LDRgtC+0YDQsCDQuNC70Lggc2x1ZyDQsiDQvNCw0YDRiNGA0YPRgtCw0YUg0YLQvtCy0LDRgNC+0LIg0Lgg0LrQsNGC0LXQs9C+0YDQuNC5LlxuICAgICAqL1xuICAgIHByaXZhdGUgcmVhZG9ubHkgaWRPclNsdWcgPSBpbmplY3QoU0NfSURfT1JfU0xVR19JTl9ST1VURSk7XG5cbiAgICAvKipcbiAgICAgKiDQn9GA0LjQt9C90LDQuiwg0YfRgtC+INCy0LrQu9GO0YfRkdC9INC/0L7RgdGC0L7Rj9C90L3Ri9C5INGA0LXQtNC40YDQtdC60YIg0L3QsCDQutCw0L3QvtC90LjRh9C10YHQutC40Lkg0LDQtNGA0LXRgSDRgtC+0LLQsNGA0LAg0LjQu9C4INC60LDRgtC10LPQvtGA0LjQuC5cbiAgICAgKi9cbiAgICBwcml2YXRlIHJlYWRvbmx5IGlzQ2Fub25pY2FsUmVkaXJlY3RFbmFibGVkID0gaW5qZWN0KFNDX0NBTk9OSUNBTF9SRURJUkVDVF9FTkFCTEVEKTtcblxuICAgIC8qKlxuICAgICAqINCf0YDQuNC30L3QsNC6LCDRh9GC0L4g0YLQtdC60YPRidC40Lkg0YHQutGA0LjQv9GCINC40YHQv9C+0LvQvdGP0LXRgtGB0Y8g0L3QsCDRgdC10YDQstC10YDQtS5cbiAgICAgKi9cbiAgICBwcml2YXRlIHJlYWRvbmx5IGlzU2VydmVyID0gaW5qZWN0KElTX1NFUlZFUik7XG5cbiAgICAvKipcbiAgICAgKiDQlNCw0L3QvdGL0LUg0L7QsSDQvtGC0LLQtdGC0LUg0L3QsCDQt9Cw0L/RgNC+0YEgKNC00L7RgdGC0YPQv9C90Ysg0YLQvtC70YzQutC+INC90LAg0YHQtdGA0LLQtdGA0LUg0L/RgNC4IFNTUikuXG4gICAgICpcbiAgICAgKiBBbmd1bGFyIDIxICjQvNC40LPRgNCw0YbQuNGPIFNTUik6IHtAbGluayBSRVNQT05TRX0g4oCUINC60LDRgdGC0L7QvNC90YvQuSBFeHByZXNzLdGC0L7QutC10L0sINC60L7RgtC+0YDRi9C5INC/0YDQvtCy0LDQudC00LjRgtGB0Y8g0LIgYHNlcnZlci50c2BcbiAgICAgKiDRh9C10YDQtdC3IENvbW1vbkVuZ2luZS4g0J3QsCB1cGdyYWRlLdCy0LXRgtC60LUgYHNlcnZlci50c2Ag0L7RgdGC0LDQu9GB0Y8g0L3QsCBDb21tb25FbmdpbmUsINC/0L7RjdGC0L7QvNGDINC/0YDQuCDRgdC70LjRj9C90LjQuCDQt9C00LXRgdGMXG4gICAgICog0L3QuNGH0LXQs9C+INC80LXQvdGP0YLRjCDQvdC1INC90YPQttC90L4uINCV0YHQu9C4IGBzZXJ2ZXIudHNgINC80LjQs9GA0LjRgNGD0Y7RgiDQvdCwIGBBbmd1bGFyTm9kZUFwcEVuZ2luZWAgKyBgY3JlYXRlTm9kZVJlcXVlc3RIYW5kbGVyYCxcbiAgICAgKiDQt9Cw0LzQtdC90LjRgtC1IHtAbGluayBSRVNQT05TRX0g0L3QsCDQvdCw0YLQuNCy0L3Ri9C5IGBSRVNQT05TRV9JTklUYCAoYEluamVjdGlvblRva2VuPFJlc3BvbnNlSW5pdCB8IG51bGw+YCDQuNC3IGBAYW5ndWxhci9jb3JlYCk7XG4gICAgICog0YHQvC4g0YHQtdGA0LLQtdGA0L3Ri9C1INCy0LXRgtC60Lgg0LIge0BsaW5rIHJlZGlyZWN0VG9QYXJlbnRDYXRlZ29yeSR9INC4IHtAbGluayByZWRpcmVjdFRvQ2Fub25pY2FsVXJsfS5cbiAgICAgKi9cbiAgICBwcml2YXRlIHJlYWRvbmx5IHJlc3BvbnNlID0gaW5qZWN0KFJFU1BPTlNFLCB7IG9wdGlvbmFsOiB0cnVlIH0pO1xuXG4gICAgLyoqXG4gICAgICog0JTQvtC60YPQvNC10L3RgiDRgtC10LrRg9GJ0LXQuSDRgdGC0YDQsNC90LjRhtGLLlxuICAgICAqL1xuICAgIHByaXZhdGUgcmVhZG9ubHkgZG9jdW1lbnQgPSBpbmplY3QoRE9DVU1FTlQpO1xuXG4gICAgLyoqXG4gICAgICog0JLQvtC30LLRgNCw0YnQsNC10YIg0YDQtdC30YPQu9GM0YLQsNGCINGB0YLRgNCw0LbQsCDQvNCw0YDRiNGA0YPRgtCwINC00LvRjyDQv9C10YDQtdGF0L7QtNCwINC90LAg0LrQsNC90L7QvdC40YfQtdGB0LrQuNC5INCw0LTRgNC10YEg0YLQvtCy0LDRgNCwINC40LvQuCDQutCw0YLQtdCz0L7RgNC40LhcbiAgICAgKiAo0LDQtNGA0LXRgSDRgdC+IHNsdWcg0LvQuNCx0L4g0YEg0LjQtNC10L3RgtC40YTQuNC60LDRgtC+0YDQvtC8IOKAlCDQsiDQt9Cw0LLQuNGB0LjQvNC+0YHRgtC4INC+0YIg0L3QsNGB0YLRgNC+0LXQuiDQvtC60YDRg9C20LXQvdC40Y8pLlxuICAgICAqXG4gICAgICogQHBhcmFtIGNvbW1hbmRzINCh0LXQs9C80LXQvdGC0Ysg0LrQsNC90L7QvdC40YfQtdGB0LrQvtCz0L4g0LzQsNGA0YjRgNGD0YLQsC5cbiAgICAgKiBAcGFyYW0gc3RhdHVzINCh0YLQsNGC0YPRgSDRgNC10LTQuNGA0LXQutGC0LA6INCy0LjQtCDQsNC00YDQtdGB0LAg0LfQsNC00LDRkdGC0YHRjyDQvdCw0YHRgtGA0L7QudC60LDQvNC4INC+0LrRgNGD0LbQtdC90LjRjyDQuCDQvNC+0LbQtdGCINCx0YvRgtGMINC40LfQvNC10L3RkdC9LCDQv9C+0Y3RgtC+0LzRgyDQv9C+INGD0LzQvtC70YfQsNC90LjRjiDQstGA0LXQvNC10L3QvdGL0LkuXG4gICAgICogQHJldHVybnMg0JTQtdGA0LXQstC+INC60LDQvdC+0L3QuNGH0LXRgdC60L7Qs9C+INC80LDRgNGI0YDRg9GC0LAg0LTQu9GPINC90LDQstC40LPQsNGG0LjQuCDQu9C40LHQviBgZmFsc2VgLCDQtdGB0LvQuCDRgNC10LTQuNGA0LXQutGCINCy0YvQv9C+0LvQvdC10L0g0L7RgtCy0LXRgtC+0Lwg0YHQtdGA0LLQtdGA0LAuXG4gICAgICovXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHNvbmFyanMvZnVuY3Rpb24tcmV0dXJuLXR5cGVcbiAgICBwdWJsaWMgcmVkaXJlY3RUb0Nhbm9uaWNhbFVybChjb21tYW5kczogQXJyYXk8bnVtYmVyIHwgc3RyaW5nPiwgc3RhdHVzOiBTY1JlZGlyZWN0U3RhdHVzRW51bSA9IFNjUmVkaXJlY3RTdGF0dXNFbnVtLlRlbXBvcmFyeSk6IGJvb2xlYW4gfCBVcmxUcmVlIHtcbiAgICAgICAgY29uc3QgdXJsVHJlZSA9IHRoaXMucm91dGVyLmNyZWF0ZVVybFRyZWUoY29tbWFuZHMpO1xuXG4gICAgICAgIGlmICh0aGlzLmlzQ2Fub25pY2FsUmVkaXJlY3RFbmFibGVkICYmIHRoaXMuaXNTZXJ2ZXIgJiYgdGhpcy5zZXRTZXJ2ZXJSZWRpcmVjdCh0aGlzLnJvdXRlci5zZXJpYWxpemVVcmwodXJsVHJlZSksIHN0YXR1cykpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB1cmxUcmVlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqINCS0YvRgdGC0LDQstC70Y/QtdGCINGA0LXQtNC40YDQtdC60YIg0LIg0L7RgtCy0LXRgtC1INGB0LXRgNCy0LXRgNCwIChTU1IpLlxuICAgICAqXG4gICAgICogQHBhcmFtIHRhcmdldFVybCDQkNC00YDQtdGBLCDQvdCwINC60L7RgtC+0YDRi9C5INCy0YvQv9C+0LvQvdGP0LXRgtGB0Y8g0YDQtdC00LjRgNC10LrRgi5cbiAgICAgKiBAcGFyYW0gc3RhdHVzINCh0YLQsNGC0YPRgSDRgNC10LTQuNGA0LXQutGC0LAuXG4gICAgICogQHJldHVybnMg0J/RgNC40LfQvdCw0LosINGH0YLQviDRgNC10LTQuNGA0LXQutGCINCy0YvRgdGC0LDQstC70LXQvTsgYGZhbHNlYCwg0LXRgdC70Lgg0LTQsNC90L3Ri9C1INC+0LEg0L7RgtCy0LXRgtC1INC90LXQtNC+0YHRgtGD0L/QvdGLICjQvdCw0L/RgNC40LzQtdGALCBkZXYt0YHQtdGA0LLQtdGAIGBuZyBzZXJ2ZWApLlxuICAgICAqL1xuICAgIHByaXZhdGUgc2V0U2VydmVyUmVkaXJlY3QodGFyZ2V0VXJsOiBzdHJpbmcsIHN0YXR1czogU2NSZWRpcmVjdFN0YXR1c0VudW0pOiBib29sZWFuIHtcbiAgICAgICAgaWYgKCF0aGlzLnJlc3BvbnNlKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBBbmd1bGFyIDIxICjQvNC40LPRgNCw0YbQuNGPIFNTUik6INC/0YDQuCDQv9C10YDQtdGF0L7QtNC1IHNlcnZlci50cyDQvdCwIEFuZ3VsYXJOb2RlQXBwRW5naW5lINGB0YLQsNGC0YPRgSDQuCDQt9Cw0LPQvtC70L7QstC+0Log0LLRi9GB0YLQsNCy0LvRj9GO0YLRgdGPXG4gICAgICAgIC8vINGH0LXRgNC10Lcg0L3QsNGC0LjQstC90YvQuSBSRVNQT05TRV9JTklUINCy0LzQtdGB0YLQviBFeHByZXNzLdC80LXRgtC+0LTQvtCyIHJlc3BvbnNlLnNldEhlYWRlci9yZXNwb25zZS5zdGF0dXMuXG4gICAgICAgIHRoaXMucmVzcG9uc2Uuc2V0SGVhZGVyKCdMb2NhdGlvbicsIHRhcmdldFVybCk7XG4gICAgICAgIHRoaXMucmVzcG9uc2Uuc3RhdHVzKHN0YXR1cyk7XG5cbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICog0JLRi9C/0L7Qu9C90Y/QtdGCINGA0LXQtNC40YDQtdC60YIg0L3QsCDRgNC+0LTQuNGC0LXQu9GM0YHQutGD0Y4g0LrQsNGC0LXQs9C+0YDQuNGOINC90LXQtNC+0YHRgtGD0L/QvdC+0Lkg0LrQsNGC0LXQs9C+0YDQuNC4LlxuICAgICAqXG4gICAgICogQHBhcmFtIGNhdGVnb3J5SWRPclNsdWcg0JjQtNC10L3RgtC40YTQuNC60LDRgtC+0YAg0LjQu9C4IHNsdWcg0L3QtdC00L7RgdGC0YPQv9C90L7QuSDQutCw0YLQtdCz0L7RgNC40LguXG4gICAgICogQHJldHVybnMg0J/QvtGC0L7Quiwg0LfQsNCy0LXRgNGI0LDRjtGJ0LjQudGB0Y8g0L/QvtGB0LvQtSDRgNC10LTQuNGA0LXQutGC0LAuINCt0LzQuNGC0LjRgiDQvtGI0LjQsdC60YMge0BsaW5rIEh0dHBFcnJvclJlc3BvbnNlfSwg0LXRgdC70Lgg0YDQvtC00LjRgtC10LvRjNGB0LrQsNGPINC60LDRgtC10LPQvtGA0LjRjyDQvdC1INC90LDQudC00LXQvdCwLlxuICAgICAqL1xuICAgIHB1YmxpYyByZWRpcmVjdFRvQ2F0ZWdvcnlQYXJlbnQkKGNhdGVnb3J5SWRPclNsdWc6IG51bWJlciB8IHN0cmluZyk6IE9ic2VydmFibGU8bmV2ZXI+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMucmVkaXJlY3RUb1BhcmVudENhdGVnb3J5JCh0aGlzLmNhdGFsb2dTZXJ2aWNlLmdldENhdGVnb3J5UGFyZW50Q2F0ZWdvcnkkKGNhdGVnb3J5SWRPclNsdWcpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiDQktGL0L/QvtC70L3Rj9C10YIg0YDQtdC00LjRgNC10LrRgiDQvdCwINGA0L7QtNC40YLQtdC70YzRgdC60YPRjiDQutCw0YLQtdCz0L7RgNC40Y4g0L3QtdC00L7RgdGC0YPQv9C90L7Qs9C+INGC0L7QstCw0YDQsC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBwcm9kdWN0SWRPclNsdWcg0JjQtNC10L3RgtC40YTQuNC60LDRgtC+0YAg0LjQu9C4IHNsdWcg0L3QtdC00L7RgdGC0YPQv9C90L7Qs9C+INGC0L7QstCw0YDQsC5cbiAgICAgKiBAcmV0dXJucyDQn9C+0YLQvtC6LCDQt9Cw0LLQtdGA0YjQsNGO0YnQuNC50YHRjyDQv9C+0YHQu9C1INGA0LXQtNC40YDQtdC60YLQsC4g0K3QvNC40YLQuNGCINC+0YjQuNCx0LrRgyB7QGxpbmsgSHR0cEVycm9yUmVzcG9uc2V9LCDQtdGB0LvQuCDRgNC+0LTQuNGC0LXQu9GM0YHQutCw0Y8g0LrQsNGC0LXQs9C+0YDQuNGPINC90LUg0L3QsNC50LTQtdC90LAuXG4gICAgICovXG4gICAgcHVibGljIHJlZGlyZWN0VG9Qcm9kdWN0UGFyZW50JChwcm9kdWN0SWRPclNsdWc6IG51bWJlciB8IHN0cmluZyk6IE9ic2VydmFibGU8bmV2ZXI+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMucmVkaXJlY3RUb1BhcmVudENhdGVnb3J5JCh0aGlzLmNhdGFsb2dTZXJ2aWNlLmdldFByb2R1Y3RQYXJlbnRDYXRlZ29yeSQocHJvZHVjdElkT3JTbHVnKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICog0J7Qv9C10YDQsNGC0L7RgCDRg9GB0YLQvtC50YfQuNCy0L7QuSDQvtCx0YDQsNCx0L7RgtC60Lgg0L3QtdC00L7RgdGC0YPQv9C90L7QuSAoSFRUUC3QvtGI0LjQsdC60LApINC60LDRgtC10LPQvtGA0LjQuCDQsiDQv9C+0YLQvtC60LUg0LTQsNC90L3Ri9GFOiDQv9GA0LggNDA0INCy0YvQv9C+0LvQvdGP0LXRgiDRgNC10LTQuNGA0LXQutGCXG4gICAgICog0L3QsCDRgNC+0LTQuNGC0LXQu9GM0YHQutGD0Y4g0LrQsNGC0LXQs9C+0YDQuNGOLCDQv9GA0Lgg0L3QtdC00L7RgdGC0YPQv9C90L7QvCDRgNC+0LTQuNGC0LXQu9C1INC40LvQuCDQuNC90L7QuSDQvtGI0LjQsdC60LUg0YHQvtC+0LHRidCw0LXRgiDQutC+0LQg0YfQtdGA0LXQtyB7QGxpbmsgb25FcnJvckNvZGV9LlxuICAgICAqINCe0YjQuNCx0LrRgyDQvdC1INC/0YDQvtCx0YDQsNGB0YvQstCw0LXRgiAo0LfQsNCy0LXRgNGI0LDQtdGCINC/0L7RgtC+0Loge0BsaW5rIEVNUFRZfSksINC/0L7RjdGC0L7QvNGDINC/0L7RgtC+0Log0LTQsNC90L3Ri9GFINC90LUg0LfQsNCy0LXRgNGI0LDQtdGC0YHRjyDQvtGI0LjQsdC60L7QuS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBjYXRlZ29yeUlkT3JTbHVnINCY0LTQtdC90YLQuNGE0LjQutCw0YLQvtGAINC40LvQuCBzbHVnINC90LXQtNC+0YHRgtGD0L/QvdC+0Lkg0LrQsNGC0LXQs9C+0YDQuNC4LlxuICAgICAqIEBwYXJhbSBvbkVycm9yQ29kZSDQmtC+0LvQsdGN0Log0YPRgdGC0LDQvdC+0LLQutC4INC60L7QtNCwINC+0YjQuNCx0LrQuCAo0L3QsNC/0YDQuNC80LXRgCwg0LTQu9GPINC+0YLQvtCx0YDQsNC20LXQvdC40Y8g0YHRgtGA0LDQvdC40YbRiyDQvtGI0LjQsdC60LgpLlxuICAgICAqL1xuICAgIHB1YmxpYyBoYW5kbGVVbmF2YWlsYWJsZUNhdGVnb3J5JDxUPihjYXRlZ29yeUlkT3JTbHVnOiBudW1iZXIgfCBzdHJpbmcsIG9uRXJyb3JDb2RlOiAoc3RhdHVzOiBudW1iZXIpID0+IHZvaWQpOiBNb25vVHlwZU9wZXJhdG9yRnVuY3Rpb248VD4ge1xuICAgICAgICByZXR1cm4gdGhpcy5oYW5kbGVVbmF2YWlsYWJsZSQoKCkgPT4gdGhpcy5yZWRpcmVjdFRvQ2F0ZWdvcnlQYXJlbnQkKGNhdGVnb3J5SWRPclNsdWcpLCBvbkVycm9yQ29kZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICog0J7Qv9C10YDQsNGC0L7RgCDRg9GB0YLQvtC50YfQuNCy0L7QuSDQvtCx0YDQsNCx0L7RgtC60Lgg0L3QtdC00L7RgdGC0YPQv9C90L7Qs9C+IChIVFRQLdC+0YjQuNCx0LrQsCkg0YLQvtCy0LDRgNCwINCyINC/0L7RgtC+0LrQtSDQtNCw0L3QvdGL0YU6INC/0YDQuCA0MDQg0LLRi9C/0L7Qu9C90Y/QtdGCINGA0LXQtNC40YDQtdC60YJcbiAgICAgKiDQvdCwINGA0L7QtNC40YLQtdC70YzRgdC60YPRjiDQutCw0YLQtdCz0L7RgNC40Y4g0YLQvtCy0LDRgNCwLCDQv9GA0Lgg0L3QtdC00L7RgdGC0YPQv9C90L7QvCDRgNC+0LTQuNGC0LXQu9C1INC40LvQuCDQuNC90L7QuSDQvtGI0LjQsdC60LUg0YHQvtC+0LHRidCw0LXRgiDQutC+0LQg0YfQtdGA0LXQtyB7QGxpbmsgb25FcnJvckNvZGV9LlxuICAgICAqINCe0YjQuNCx0LrRgyDQvdC1INC/0YDQvtCx0YDQsNGB0YvQstCw0LXRgiAo0LfQsNCy0LXRgNGI0LDQtdGCINC/0L7RgtC+0Loge0BsaW5rIEVNUFRZfSksINC/0L7RjdGC0L7QvNGDINC/0L7RgtC+0Log0LTQsNC90L3Ri9GFINC90LUg0LfQsNCy0LXRgNGI0LDQtdGC0YHRjyDQvtGI0LjQsdC60L7QuS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBwcm9kdWN0SWRPclNsdWcg0JjQtNC10L3RgtC40YTQuNC60LDRgtC+0YAg0LjQu9C4IHNsdWcg0L3QtdC00L7RgdGC0YPQv9C90L7Qs9C+INGC0L7QstCw0YDQsC5cbiAgICAgKiBAcGFyYW0gb25FcnJvckNvZGUg0JrQvtC70LHRjdC6INGD0YHRgtCw0L3QvtCy0LrQuCDQutC+0LTQsCDQvtGI0LjQsdC60LggKNC90LDQv9GA0LjQvNC10YAsINC00LvRjyDQvtGC0L7QsdGA0LDQttC10L3QuNGPINGB0YLRgNCw0L3QuNGG0Ysg0L7RiNC40LHQutC4KS5cbiAgICAgKi9cbiAgICBwdWJsaWMgaGFuZGxlVW5hdmFpbGFibGVQcm9kdWN0JDxUPihwcm9kdWN0SWRPclNsdWc6IG51bWJlciB8IHN0cmluZywgb25FcnJvckNvZGU6IChzdGF0dXM6IG51bWJlcikgPT4gdm9pZCk6IE1vbm9UeXBlT3BlcmF0b3JGdW5jdGlvbjxUPiB7XG4gICAgICAgIHJldHVybiB0aGlzLmhhbmRsZVVuYXZhaWxhYmxlJCgoKSA9PiB0aGlzLnJlZGlyZWN0VG9Qcm9kdWN0UGFyZW50JChwcm9kdWN0SWRPclNsdWcpLCBvbkVycm9yQ29kZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICog0JHQsNC30L7QstGL0Lkg0L7Qv9C10YDQsNGC0L7RgCDRg9GB0YLQvtC50YfQuNCy0L7QuSDQvtCx0YDQsNCx0L7RgtC60Lgg0L3QtdC00L7RgdGC0YPQv9C90L7QuSDRgdGD0YnQvdC+0YHRgtC4OiDQv9GA0LggNDA0IOKAlCDRgNC10LTQuNGA0LXQutGCINC90LAg0YDQvtC00LjRgtC10LvRjyAo0YfQtdGA0LXQtyB7QGxpbmsgcmVkaXJlY3RUb1BhcmVudCR9KSxcbiAgICAgKiDQv9GA0Lgg0L3QtdC00L7RgdGC0YPQv9C90L7QvCDRgNC+0LTQuNGC0LXQu9C1INC40LvQuCDQuNC90L7QvCB7QGxpbmsgSHR0cEVycm9yUmVzcG9uc2V9IOKAlCB7QGxpbmsgb25FcnJvckNvZGV9INGBINC60L7QtNC+0Lwg0L7RgtCy0LXRgtCwOyDQstGB0LXQs9C00LAge0BsaW5rIEVNUFRZfS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSByZWRpcmVjdFRvUGFyZW50JCDQpNCw0LHRgNC40LrQsCDQv9C+0YLQvtC60LAg0YDQtdC00LjRgNC10LrRgtCwINC90LAg0YDQvtC00LjRgtC10LvRjNGB0LrRg9GOINC60LDRgtC10LPQvtGA0LjRji5cbiAgICAgKiBAcGFyYW0gb25FcnJvckNvZGUg0JrQvtC70LHRjdC6INGD0YHRgtCw0L3QvtCy0LrQuCDQutC+0LTQsCDQvtGI0LjQsdC60LguXG4gICAgICovXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGNsYXNzLW1ldGhvZHMtdXNlLXRoaXNcbiAgICBwcml2YXRlIGhhbmRsZVVuYXZhaWxhYmxlJDxUPihyZWRpcmVjdFRvUGFyZW50JDogKCkgPT4gT2JzZXJ2YWJsZTxuZXZlcj4sIG9uRXJyb3JDb2RlOiAoc3RhdHVzOiBudW1iZXIpID0+IHZvaWQpOiBNb25vVHlwZU9wZXJhdG9yRnVuY3Rpb248VD4ge1xuICAgICAgICByZXR1cm4gKHNvdXJjZSQpID0+XG4gICAgICAgICAgICBzb3VyY2UkLnBpcGUoXG4gICAgICAgICAgICAgICAgY2F0Y2hFcnJvcigoZXJyb3I6IHVua25vd24pID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yIGluc3RhbmNlb2YgSHR0cEVycm9yUmVzcG9uc2UgJiYgZXJyb3Iuc3RhdHVzID09PSA0MDQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZWRpcmVjdFRvUGFyZW50JCgpLnBpcGUoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2F0Y2hFcnJvcigocmVkaXJlY3RFcnJvcjogdW5rbm93bikgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVkaXJlY3RFcnJvciBpbnN0YW5jZW9mIEh0dHBFcnJvclJlc3BvbnNlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbkVycm9yQ29kZShyZWRpcmVjdEVycm9yLnN0YXR1cyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gRU1QVFk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBIdHRwRXJyb3JSZXNwb25zZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgb25FcnJvckNvZGUoZXJyb3Iuc3RhdHVzKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBFTVBUWTtcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiDQktGL0L/QvtC70L3Rj9C10YIg0YDQtdC00LjRgNC10LrRgiDQvdCwINC/0L7Qu9GD0YfQtdC90L3Rg9GOINGA0L7QtNC40YLQtdC70YzRgdC60YPRjiDQutCw0YLQtdCz0L7RgNC40Y4uXG4gICAgICpcbiAgICAgKiBAcGFyYW0gcGFyZW50Q2F0ZWdvcnkkINCf0L7RgtC+0Log0YEg0LTQsNC90L3Ri9C80Lgg0YDQvtC00LjRgtC10LvRjNGB0LrQvtC5INC60LDRgtC10LPQvtGA0LjQuC5cbiAgICAgKiBAcmV0dXJucyDQn9C+0YLQvtC6LCDQt9Cw0LLQtdGA0YjQsNGO0YnQuNC50YHRjyDQv9C+0YHQu9C1INGA0LXQtNC40YDQtdC60YLQsC4g0K3QvNC40YLQuNGCINC+0YjQuNCx0LrRgyB7QGxpbmsgSHR0cEVycm9yUmVzcG9uc2V9INGBINC60L7QtNC+0LwgNDA0LCDQtdGB0LvQuCDRgNC+0LTQuNGC0LXQu9GM0YHQutCw0Y8g0LrQsNGC0LXQs9C+0YDQuNGPINC90LUg0L3QsNC50LTQtdC90LAuXG4gICAgICovXG4gICAgcHJpdmF0ZSByZWRpcmVjdFRvUGFyZW50Q2F0ZWdvcnkkKHBhcmVudENhdGVnb3J5JDogT2JzZXJ2YWJsZTxTY0lQYXJlbnRDYXRlZ29yeVJlZGlyZWN0Pik6IE9ic2VydmFibGU8bmV2ZXI+IHtcbiAgICAgICAgcmV0dXJuIHBhcmVudENhdGVnb3J5JC5waXBlKFxuICAgICAgICAgICAgc3dpdGNoTWFwKChwYXJlbnRDYXRlZ29yeSkgPT4ge1xuICAgICAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBzZWN1cml0eS9kZXRlY3Qtb2JqZWN0LWluamVjdGlvblxuICAgICAgICAgICAgICAgIGNvbnN0IHRhcmdldCA9IHBhcmVudENhdGVnb3J5W3RoaXMuaWRPclNsdWddO1xuXG4gICAgICAgICAgICAgICAgLy8g0KDQvtC00LjRgtC10LvRjNGB0LrQsNGPINC60LDRgtC10LPQvtGA0LjRjyDQvdC1INC90LDQudC00LXQvdCwIOKAlCDQvtGC0L7QsdGA0LDQttCw0LXQvCDRgdGC0YDQsNC90LjRhtGDINC+0YjQuNCx0LrQuC5cbiAgICAgICAgICAgICAgICBpZiAoIXR1aUlzUHJlc2VudCh0YXJnZXQpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aHJvd0Vycm9yKCgpID0+IG5ldyBIdHRwRXJyb3JSZXNwb25zZSh7IHN0YXR1czogNDA0IH0pKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBjb25zdCB1cmxUcmVlID0gdGhpcy5yb3V0ZXIuY3JlYXRlVXJsVHJlZShbJy9jYXRhbG9nJywgdGFyZ2V0XSk7XG5cbiAgICAgICAgICAgICAgICBjb25zdCB0YXJnZXRVcmwgPSB0aGlzLnJvdXRlci5zZXJpYWxpemVVcmwodXJsVHJlZSk7XG5cbiAgICAgICAgICAgICAgICBpZiAodGhpcy5pc1NlcnZlcikge1xuICAgICAgICAgICAgICAgICAgICAvLyDQodC60YDRi9GC0YvQtSDQutCw0YLQtdCz0L7RgNC40Y8g0LjQu9C4INGC0L7QstCw0YAg0LzQvtCz0YPRgiDRgdC90L7QstCwINGB0YLQsNGC0Ywg0LTQvtGB0YLRg9C/0L3Ri9C80LgsINC/0L7RjdGC0L7QvNGDINGA0LXQtNC40YDQtdC60YIg0L3QsCDRgNC+0LTQuNGC0LXQu9GPINCy0YDQtdC80LXQvdC90YvQuS5cbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuc2V0U2VydmVyUmVkaXJlY3QodGFyZ2V0VXJsLCBTY1JlZGlyZWN0U3RhdHVzRW51bS5UZW1wb3JhcnkpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gRU1QVFk7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAvLyBTU1Ig0LHQtdC3IFJFU1BPTlNFICjQvdCw0L/RgNC40LzQtdGALCBkZXYt0YHQtdGA0LLQtdGAIG5nIHNlcnZlKTog0YHQtdGA0LLQtdGA0L3Ri9C5INGA0LXQtNC40YDQtdC60YIg0L3QtdCy0L7Qt9C80L7QttC10L0sXG4gICAgICAgICAgICAgICAgICAgIC8vINC/0L7RjdGC0L7QvNGDINC+0YLQvtCx0YDQsNC20LDQtdC8INGB0YLRgNCw0L3QuNGG0YMg0L7RiNC40LHQutC4LCDQutCw0Log0LTQviDQstC90LXQtNGA0LXQvdC40Y8g0YDQtdC00LjRgNC10LrRgtCwLCDQstC80LXRgdGC0L4g0LHQtdGB0LrQvtC90LXRh9C90L7Qs9C+INC70L7QsNC00LXRgNCwLlxuICAgICAgICAgICAgICAgICAgICAvL1xuICAgICAgICAgICAgICAgICAgICAvLyBBbmd1bGFyIDIxICjQvNC40LPRgNCw0YbQuNGPIFNTUik6INGN0YLQvtGCINGE0L7Qu9Cx0Y3QuiDQvdGD0LbQtdC9LCDQv9C+0LrQsCBuZyBzZXJ2ZSDQvdC1INC40YHQv9C+0LvQvdGP0LXRgiBzZXJ2ZXIudHMgKNC+0L0g0L3QsCBDb21tb25FbmdpbmUpLlxuICAgICAgICAgICAgICAgICAgICAvLyDQn9C+0YHQu9C1INC80LjQs9GA0LDRhtC40Lggc2VydmVyLnRzINC90LAgY3JlYXRlTm9kZVJlcXVlc3RIYW5kbGVyIGRldi3RgdC10YDQstC10YAg0L3QsNGH0L3RkdGCINC40YHQv9C+0LvQvdGP0YLRjCBzZXJ2ZXIudHMsINC4IFJFU1BPTlNFL1JFU1BPTlNFX0lOSVRcbiAgICAgICAgICAgICAgICAgICAgLy8g0YHRgtCw0L3QtdGCINC00L7RgdGC0YPQv9C10L0g0LIgbmcgc2VydmUg4oCUINGC0L7Qs9C00LAg0Y3RgtGDINCy0LXRgtC60YMg0YEgdGhyb3dFcnJvcig0MDQpINC80L7QttC90L4g0YPQtNCw0LvQuNGC0YwuXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aHJvd0Vycm9yKCgpID0+IG5ldyBIdHRwRXJyb3JSZXNwb25zZSh7IHN0YXR1czogNDA0IH0pKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAvLyDQkdGA0LDRg9C30LXRgDog0L/QvtGC0L7QuiDQtNCw0L3QvdGL0YUg0LrQsNGC0LXQs9C+0YDQuNC4IChTQ19DQVRFR09SWV9JTkZPKSDQt9Cw0LLQtdGA0YjQsNC10YLRgdGPINC+0YjQuNCx0LrQvtC5INC/0YDQuCA0MDQg0Lgg0L3QtSDQstC+0LfQvtCx0L3QvtCy0LvRj9C10YLRgdGPXG4gICAgICAgICAgICAgICAgLy8g0L/RgNC4INC90LDQstC40LPQsNGG0LjQuCDQsiDRgNCw0LzQutCw0YUg0YLQvtCz0L4g0LbQtSDQvNCw0YDRiNGA0YPRgtCwLCDQv9C+0Y3RgtC+0LzRgyDRgNC10LTQuNGA0LXQutGCINCy0YvQv9C+0LvQvdGP0LXRgtGB0Y8g0L/QvtC70L3QvtC5INC/0LXRgNC10LfQsNCz0YDRg9C30LrQvtC5INGB0YLRgNCw0L3QuNGG0YsuXG4gICAgICAgICAgICAgICAgLy8gbG9jYXRpb24ucmVwbGFjZSDQvdC1INC00L7QsdCw0LLQu9GP0LXRgiDQt9Cw0L/QuNGB0Ywg0LIg0LjRgdGC0L7RgNC40Y4sINGH0YLQvtCx0Ysg0LrQvdC+0L/QutCwIMKr0J3QsNC30LDQtMK7INC90LUg0LLQvtC30LLRgNCw0YnQsNC70LAg0L3QsCDQvdC10LTQvtGB0YLRg9C/0L3Rg9GOINGB0YLRgNCw0L3QuNGG0YMuXG4gICAgICAgICAgICAgICAgLy9cbiAgICAgICAgICAgICAgICAvLyBBbmd1bGFyIDIxICjQvNC40LPRgNCw0YbQuNGPIFNTUik6INGN0YLRgyDRgdGC0YDQvtC60YMg0LDQv9Cz0YDQtdC50LQg0J3QlSDRgdC90LjQvNCw0LXRgiDigJQg0L/RgNC40YfQuNC90LAg0LIg0YDQsNC90YLQsNC50LzQtSDQv9GA0LjQu9C+0LbQtdC90LjRjyAo0LzRkdGA0YLQstGL0Lkg0L/QvtGC0L7QulxuICAgICAgICAgICAgICAgIC8vIFNDX0NBVEVHT1JZX0lORk8g0L/RgNC4IFNQQS3QvdCw0LLQuNCz0LDRhtC40LgpLCDQsCDQvdC1INCyIFNTUi4g0JLQtdGA0L3Rg9GC0YwgU1BBLdC90LDQstC40LPQsNGG0LjRjiAocm91dGVyLm5hdmlnYXRlQnlVcmwpINC80L7QttC90L4g0YLQvtC70YzQutC+XG4gICAgICAgICAgICAgICAgLy8g0YHQtNC10LvQsNCyIFNDX0NBVEVHT1JZX0lORk8g0YPRgdGC0L7QudGH0LjQstGL0Lwg0LogNDA0ICjQu9C+0LLQuNGC0Ywg0L7RiNC40LHQutGDINCy0L3Rg9GC0YDQuCBzd2l0Y2hNYXApINC70LjQsdC+INGD0L3QtdGB0Y8g0YDQtdC00LjRgNC10LrRgiDQsiBndWFyZCArIFJlZGlyZWN0Q29tbWFuZC5cbiAgICAgICAgICAgICAgICB0aGlzLmRvY3VtZW50LmxvY2F0aW9uLnJlcGxhY2UodGFyZ2V0VXJsKTtcblxuICAgICAgICAgICAgICAgIHJldHVybiBFTVBUWTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICk7XG4gICAgfVxufVxuIl19
@@ -1,2 +1,3 @@
1
+ export * from './redirect-status-enum';
1
2
  export * from './request-state-status-enum';
2
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9jb3JlL2NvbW1vbi9lbnVtcy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxjQUFjLDZCQUE2QixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0ICogZnJvbSAnLi9yZXF1ZXN0LXN0YXRlLXN0YXR1cy1lbnVtJztcbiJdfQ==
3
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9jb3JlL2NvbW1vbi9lbnVtcy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxjQUFjLHdCQUF3QixDQUFDO0FBQ3ZDLGNBQWMsNkJBQTZCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgKiBmcm9tICcuL3JlZGlyZWN0LXN0YXR1cy1lbnVtJztcbmV4cG9ydCAqIGZyb20gJy4vcmVxdWVzdC1zdGF0ZS1zdGF0dXMtZW51bSc7XG4iXX0=
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Статусы HTTP-редиректа, отдаваемые при рендере на сервере (SSR).
3
+ */
4
+ export var ScRedirectStatusEnum;
5
+ (function (ScRedirectStatusEnum) {
6
+ /**
7
+ * Постоянный редирект: адрес изменился навсегда, страница заменяется в индексе поисковых систем.
8
+ */
9
+ ScRedirectStatusEnum[ScRedirectStatusEnum["Permanent"] = 301] = "Permanent";
10
+ /**
11
+ * Временный редирект: исходный адрес может снова стать доступным, поэтому остаётся в индексе поисковых систем.
12
+ */
13
+ ScRedirectStatusEnum[ScRedirectStatusEnum["Temporary"] = 302] = "Temporary";
14
+ })(ScRedirectStatusEnum || (ScRedirectStatusEnum = {}));
15
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVkaXJlY3Qtc3RhdHVzLWVudW0uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9jb3JlL2NvbW1vbi9lbnVtcy9yZWRpcmVjdC1zdGF0dXMtZW51bS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7R0FFRztBQUNILE1BQU0sQ0FBTixJQUFZLG9CQVVYO0FBVkQsV0FBWSxvQkFBb0I7SUFDNUI7O09BRUc7SUFDSCwyRUFBZSxDQUFBO0lBRWY7O09BRUc7SUFDSCwyRUFBZSxDQUFBO0FBQ25CLENBQUMsRUFWVyxvQkFBb0IsS0FBcEIsb0JBQW9CLFFBVS9CIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiDQodGC0LDRgtGD0YHRiyBIVFRQLdGA0LXQtNC40YDQtdC60YLQsCwg0L7RgtC00LDQstCw0LXQvNGL0LUg0L/RgNC4INGA0LXQvdC00LXRgNC1INC90LAg0YHQtdGA0LLQtdGA0LUgKFNTUikuXG4gKi9cbmV4cG9ydCBlbnVtIFNjUmVkaXJlY3RTdGF0dXNFbnVtIHtcbiAgICAvKipcbiAgICAgKiDQn9C+0YHRgtC+0Y/QvdC90YvQuSDRgNC10LTQuNGA0LXQutGCOiDQsNC00YDQtdGBINC40LfQvNC10L3QuNC70YHRjyDQvdCw0LLRgdC10LPQtNCwLCDRgdGC0YDQsNC90LjRhtCwINC30LDQvNC10L3Rj9C10YLRgdGPINCyINC40L3QtNC10LrRgdC1INC/0L7QuNGB0LrQvtCy0YvRhSDRgdC40YHRgtC10LwuXG4gICAgICovXG4gICAgUGVybWFuZW50ID0gMzAxLFxuXG4gICAgLyoqXG4gICAgICog0JLRgNC10LzQtdC90L3Ri9C5INGA0LXQtNC40YDQtdC60YI6INC40YHRhdC+0LTQvdGL0Lkg0LDQtNGA0LXRgSDQvNC+0LbQtdGCINGB0L3QvtCy0LAg0YHRgtCw0YLRjCDQtNC+0YHRgtGD0L/QvdGL0LwsINC/0L7RjdGC0L7QvNGDINC+0YHRgtCw0ZHRgtGB0Y8g0LIg0LjQvdC00LXQutGB0LUg0L/QvtC40YHQutC+0LLRi9GFINGB0LjRgdGC0LXQvC5cbiAgICAgKi9cbiAgICBUZW1wb3JhcnkgPSAzMDIsXG59XG4iXX0=
@@ -1,12 +1,15 @@
1
1
  import { inject } from '@angular/core';
2
- import { Router } from '@angular/router';
3
2
  import { TUI_TRUE_HANDLER, tuiIsPresent } from '@taiga-ui/cdk';
4
3
  import { catchError, filter, map, of } from 'rxjs';
5
4
  import { ScCatalogService } from '../catalog/services/sc-catalog.service';
5
+ import { ScCatalogRedirectService } from '../catalog/services/sc-catalog-redirect.service';
6
6
  import { SC_ID_OR_SLUG_IN_ROUTE } from '../tokens/sc-id-or-slug-in-route';
7
7
  /**
8
8
  * Страж выполняющий проверку маршрута товара и категории, и редиректа в зависимости от настроек окружения.
9
9
  *
10
+ * Редирект выполняет {@link ScCatalogRedirectService.redirectToCanonicalUrl}: на сервере (SSR) это постоянный
11
+ * редирект (HTTP 301), в браузере — навигация внутри приложения.
12
+ *
10
13
  * @param route Сервис предоставляющий доступ к данным о маршруте.
11
14
  */
12
15
  // eslint-disable-next-line sonarjs/function-return-type
@@ -15,21 +18,21 @@ export const ScIdOrSlugGuard = (route) => {
15
18
  const categoryIdOrSlug = paramMap.get('categoryIdOrSlug');
16
19
  const productIdOrSlug = paramMap.get('productIdOrSlug');
17
20
  const idOrSlug = inject(SC_ID_OR_SLUG_IN_ROUTE);
18
- const router = inject(Router);
21
+ const catalogRedirectService = inject(ScCatalogRedirectService);
19
22
  if (categoryIdOrSlug && /^\d+$/.test(categoryIdOrSlug) !== (idOrSlug === 'id')) {
20
23
  return inject(ScCatalogService)
21
24
  .getCategoryCached$(categoryIdOrSlug)
22
25
  .pipe(filter(tuiIsPresent),
23
26
  // eslint-disable-next-line security/detect-object-injection
24
- map((category) => router.createUrlTree(['/catalog', category[idOrSlug]])), catchError(() => of(TUI_TRUE_HANDLER())));
27
+ map((category) => catalogRedirectService.redirectToCanonicalUrl(['/catalog', category[idOrSlug]])), catchError(() => of(TUI_TRUE_HANDLER())));
25
28
  }
26
29
  if (productIdOrSlug && /^\d+$/.test(productIdOrSlug) !== (idOrSlug === 'id')) {
27
30
  return inject(ScCatalogService)
28
31
  .getProductData$(productIdOrSlug)
29
32
  .pipe(filter(tuiIsPresent),
30
33
  // eslint-disable-next-line security/detect-object-injection
31
- map((product) => router.createUrlTree(['/catalog', 'product', product[idOrSlug]])), catchError(() => of(TUI_TRUE_HANDLER())));
34
+ map((product) => catalogRedirectService.redirectToCanonicalUrl(['/catalog', 'product', product[idOrSlug]])), catchError(() => of(TUI_TRUE_HANDLER())));
32
35
  }
33
36
  return true;
34
37
  };
35
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2MtaWQtb3Itc2x1Zy5ndWFyZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL2NvcmUvZ3VhcmRzL3NjLWlkLW9yLXNsdWcuZ3VhcmQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUN2QyxPQUFPLEVBQXlDLE1BQU0sRUFBVyxNQUFNLGlCQUFpQixDQUFDO0FBQ3pGLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxZQUFZLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDL0QsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUsR0FBRyxFQUFjLEVBQUUsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUUvRCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSx3Q0FBd0MsQ0FBQztBQUMxRSxPQUFPLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSxrQ0FBa0MsQ0FBQztBQUUxRTs7OztHQUlHO0FBQ0gsd0RBQXdEO0FBQ3hELE1BQU0sQ0FBQyxNQUFNLGVBQWUsR0FBa0IsQ0FBQyxLQUE2QixFQUEyQyxFQUFFO0lBQ3JILE1BQU0sRUFBRSxRQUFRLEVBQUUsR0FBRyxLQUFLLENBQUM7SUFDM0IsTUFBTSxnQkFBZ0IsR0FBRyxRQUFRLENBQUMsR0FBRyxDQUFDLGtCQUFrQixDQUFDLENBQUM7SUFDMUQsTUFBTSxlQUFlLEdBQUcsUUFBUSxDQUFDLEdBQUcsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO0lBQ3hELE1BQU0sUUFBUSxHQUFrQixNQUFNLENBQWdCLHNCQUFzQixDQUFDLENBQUM7SUFDOUUsTUFBTSxNQUFNLEdBQVcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBRXRDLElBQUksZ0JBQWdCLElBQUksT0FBTyxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxLQUFLLENBQUMsUUFBUSxLQUFLLElBQUksQ0FBQyxFQUFFLENBQUM7UUFDN0UsT0FBTyxNQUFNLENBQUMsZ0JBQWdCLENBQUM7YUFDMUIsa0JBQWtCLENBQUMsZ0JBQWdCLENBQUM7YUFDcEMsSUFBSSxDQUNELE1BQU0sQ0FBQyxZQUFZLENBQUM7UUFDcEIsNERBQTREO1FBQzVELEdBQUcsQ0FBQyxDQUFDLFFBQVEsRUFBRSxFQUFFLENBQUMsTUFBTSxDQUFDLGFBQWEsQ0FBQyxDQUFDLFVBQVUsRUFBRSxRQUFRLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQ3pFLFVBQVUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFFLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQyxDQUFDLENBQzNDLENBQUM7SUFDVixDQUFDO0lBRUQsSUFBSSxlQUFlLElBQUksT0FBTyxDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsS0FBSyxDQUFDLFFBQVEsS0FBSyxJQUFJLENBQUMsRUFBRSxDQUFDO1FBQzNFLE9BQU8sTUFBTSxDQUFDLGdCQUFnQixDQUFDO2FBQzFCLGVBQWUsQ0FBQyxlQUFlLENBQUM7YUFDaEMsSUFBSSxDQUNELE1BQU0sQ0FBQyxZQUFZLENBQUM7UUFDcEIsNERBQTREO1FBQzVELEdBQUcsQ0FBQyxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUMsTUFBTSxDQUFDLGFBQWEsQ0FBQyxDQUFDLFVBQVUsRUFBRSxTQUFTLEVBQUUsT0FBTyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUNsRixVQUFVLENBQUMsR0FBRyxFQUFFLENBQUMsRUFBRSxDQUFDLGdCQUFnQixFQUFFLENBQUMsQ0FBQyxDQUMzQyxDQUFDO0lBQ1YsQ0FBQztJQUVELE9BQU8sSUFBSSxDQUFDO0FBQ2hCLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGluamVjdCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQWN0aXZhdGVkUm91dGVTbmFwc2hvdCwgQ2FuQWN0aXZhdGVGbiwgUm91dGVyLCBVcmxUcmVlIH0gZnJvbSAnQGFuZ3VsYXIvcm91dGVyJztcbmltcG9ydCB7IFRVSV9UUlVFX0hBTkRMRVIsIHR1aUlzUHJlc2VudCB9IGZyb20gJ0B0YWlnYS11aS9jZGsnO1xuaW1wb3J0IHsgY2F0Y2hFcnJvciwgZmlsdGVyLCBtYXAsIE9ic2VydmFibGUsIG9mIH0gZnJvbSAncnhqcyc7XG5cbmltcG9ydCB7IFNjQ2F0YWxvZ1NlcnZpY2UgfSBmcm9tICcuLi9jYXRhbG9nL3NlcnZpY2VzL3NjLWNhdGFsb2cuc2VydmljZSc7XG5pbXBvcnQgeyBTQ19JRF9PUl9TTFVHX0lOX1JPVVRFIH0gZnJvbSAnLi4vdG9rZW5zL3NjLWlkLW9yLXNsdWctaW4tcm91dGUnO1xuXG4vKipcbiAqINCh0YLRgNCw0LYg0LLRi9C/0L7Qu9C90Y/RjtGJ0LjQuSDQv9GA0L7QstC10YDQutGDINC80LDRgNGI0YDRg9GC0LAg0YLQvtCy0LDRgNCwINC4INC60LDRgtC10LPQvtGA0LjQuCwg0Lgg0YDQtdC00LjRgNC10LrRgtCwINCyINC30LDQstC40YHQuNC80L7RgdGC0Lgg0L7RgiDQvdCw0YHRgtGA0L7QtdC6INC+0LrRgNGD0LbQtdC90LjRjy5cbiAqXG4gKiBAcGFyYW0gcm91dGUg0KHQtdGA0LLQuNGBINC/0YDQtdC00L7RgdGC0LDQstC70Y/RjtGJ0LjQuSDQtNC+0YHRgtGD0L8g0Log0LTQsNC90L3Ri9C8INC+INC80LDRgNGI0YDRg9GC0LUuXG4gKi9cbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBzb25hcmpzL2Z1bmN0aW9uLXJldHVybi10eXBlXG5leHBvcnQgY29uc3QgU2NJZE9yU2x1Z0d1YXJkOiBDYW5BY3RpdmF0ZUZuID0gKHJvdXRlOiBBY3RpdmF0ZWRSb3V0ZVNuYXBzaG90KTogT2JzZXJ2YWJsZTxib29sZWFuIHwgVXJsVHJlZT4gfCBib29sZWFuID0+IHtcbiAgICBjb25zdCB7IHBhcmFtTWFwIH0gPSByb3V0ZTtcbiAgICBjb25zdCBjYXRlZ29yeUlkT3JTbHVnID0gcGFyYW1NYXAuZ2V0KCdjYXRlZ29yeUlkT3JTbHVnJyk7XG4gICAgY29uc3QgcHJvZHVjdElkT3JTbHVnID0gcGFyYW1NYXAuZ2V0KCdwcm9kdWN0SWRPclNsdWcnKTtcbiAgICBjb25zdCBpZE9yU2x1ZzogJ2lkJyB8ICdzbHVnJyA9IGluamVjdDwnaWQnIHwgJ3NsdWcnPihTQ19JRF9PUl9TTFVHX0lOX1JPVVRFKTtcbiAgICBjb25zdCByb3V0ZXI6IFJvdXRlciA9IGluamVjdChSb3V0ZXIpO1xuXG4gICAgaWYgKGNhdGVnb3J5SWRPclNsdWcgJiYgL15cXGQrJC8udGVzdChjYXRlZ29yeUlkT3JTbHVnKSAhPT0gKGlkT3JTbHVnID09PSAnaWQnKSkge1xuICAgICAgICByZXR1cm4gaW5qZWN0KFNjQ2F0YWxvZ1NlcnZpY2UpXG4gICAgICAgICAgICAuZ2V0Q2F0ZWdvcnlDYWNoZWQkKGNhdGVnb3J5SWRPclNsdWcpXG4gICAgICAgICAgICAucGlwZShcbiAgICAgICAgICAgICAgICBmaWx0ZXIodHVpSXNQcmVzZW50KSxcbiAgICAgICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgc2VjdXJpdHkvZGV0ZWN0LW9iamVjdC1pbmplY3Rpb25cbiAgICAgICAgICAgICAgICBtYXAoKGNhdGVnb3J5KSA9PiByb3V0ZXIuY3JlYXRlVXJsVHJlZShbJy9jYXRhbG9nJywgY2F0ZWdvcnlbaWRPclNsdWddXSkpLFxuICAgICAgICAgICAgICAgIGNhdGNoRXJyb3IoKCkgPT4gb2YoVFVJX1RSVUVfSEFORExFUigpKSlcbiAgICAgICAgICAgICk7XG4gICAgfVxuXG4gICAgaWYgKHByb2R1Y3RJZE9yU2x1ZyAmJiAvXlxcZCskLy50ZXN0KHByb2R1Y3RJZE9yU2x1ZykgIT09IChpZE9yU2x1ZyA9PT0gJ2lkJykpIHtcbiAgICAgICAgcmV0dXJuIGluamVjdChTY0NhdGFsb2dTZXJ2aWNlKVxuICAgICAgICAgICAgLmdldFByb2R1Y3REYXRhJChwcm9kdWN0SWRPclNsdWcpXG4gICAgICAgICAgICAucGlwZShcbiAgICAgICAgICAgICAgICBmaWx0ZXIodHVpSXNQcmVzZW50KSxcbiAgICAgICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgc2VjdXJpdHkvZGV0ZWN0LW9iamVjdC1pbmplY3Rpb25cbiAgICAgICAgICAgICAgICBtYXAoKHByb2R1Y3QpID0+IHJvdXRlci5jcmVhdGVVcmxUcmVlKFsnL2NhdGFsb2cnLCAncHJvZHVjdCcsIHByb2R1Y3RbaWRPclNsdWddXSkpLFxuICAgICAgICAgICAgICAgIGNhdGNoRXJyb3IoKCkgPT4gb2YoVFVJX1RSVUVfSEFORExFUigpKSlcbiAgICAgICAgICAgICk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRydWU7XG59O1xuIl19
38
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2MtaWQtb3Itc2x1Zy5ndWFyZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL2NvcmUvZ3VhcmRzL3NjLWlkLW9yLXNsdWcuZ3VhcmQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUV2QyxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsWUFBWSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQy9ELE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFLEdBQUcsRUFBYyxFQUFFLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFFL0QsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sd0NBQXdDLENBQUM7QUFDMUUsT0FBTyxFQUFFLHdCQUF3QixFQUFFLE1BQU0saURBQWlELENBQUM7QUFDM0YsT0FBTyxFQUFFLHNCQUFzQixFQUFFLE1BQU0sa0NBQWtDLENBQUM7QUFFMUU7Ozs7Ozs7R0FPRztBQUNILHdEQUF3RDtBQUN4RCxNQUFNLENBQUMsTUFBTSxlQUFlLEdBQWtCLENBQUMsS0FBNkIsRUFBMkMsRUFBRTtJQUNySCxNQUFNLEVBQUUsUUFBUSxFQUFFLEdBQUcsS0FBSyxDQUFDO0lBQzNCLE1BQU0sZ0JBQWdCLEdBQUcsUUFBUSxDQUFDLEdBQUcsQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO0lBQzFELE1BQU0sZUFBZSxHQUFHLFFBQVEsQ0FBQyxHQUFHLENBQUMsaUJBQWlCLENBQUMsQ0FBQztJQUN4RCxNQUFNLFFBQVEsR0FBa0IsTUFBTSxDQUFnQixzQkFBc0IsQ0FBQyxDQUFDO0lBQzlFLE1BQU0sc0JBQXNCLEdBQUcsTUFBTSxDQUFDLHdCQUF3QixDQUFDLENBQUM7SUFFaEUsSUFBSSxnQkFBZ0IsSUFBSSxPQUFPLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLEtBQUssQ0FBQyxRQUFRLEtBQUssSUFBSSxDQUFDLEVBQUUsQ0FBQztRQUM3RSxPQUFPLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQzthQUMxQixrQkFBa0IsQ0FBQyxnQkFBZ0IsQ0FBQzthQUNwQyxJQUFJLENBQ0QsTUFBTSxDQUFDLFlBQVksQ0FBQztRQUNwQiw0REFBNEQ7UUFDNUQsR0FBRyxDQUFDLENBQUMsUUFBUSxFQUFFLEVBQUUsQ0FBQyxzQkFBc0IsQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDLFVBQVUsRUFBRSxRQUFRLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQ2xHLFVBQVUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFFLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQyxDQUFDLENBQzNDLENBQUM7SUFDVixDQUFDO0lBRUQsSUFBSSxlQUFlLElBQUksT0FBTyxDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsS0FBSyxDQUFDLFFBQVEsS0FBSyxJQUFJLENBQUMsRUFBRSxDQUFDO1FBQzNFLE9BQU8sTUFBTSxDQUFDLGdCQUFnQixDQUFDO2FBQzFCLGVBQWUsQ0FBQyxlQUFlLENBQUM7YUFDaEMsSUFBSSxDQUNELE1BQU0sQ0FBQyxZQUFZLENBQUM7UUFDcEIsNERBQTREO1FBQzVELEdBQUcsQ0FBQyxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUMsc0JBQXNCLENBQUMsc0JBQXNCLENBQUMsQ0FBQyxVQUFVLEVBQUUsU0FBUyxFQUFFLE9BQU8sQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFDM0csVUFBVSxDQUFDLEdBQUcsRUFBRSxDQUFDLEVBQUUsQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDLENBQUMsQ0FDM0MsQ0FBQztJQUNWLENBQUM7SUFFRCxPQUFPLElBQUksQ0FBQztBQUNoQixDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBpbmplY3QgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEFjdGl2YXRlZFJvdXRlU25hcHNob3QsIENhbkFjdGl2YXRlRm4sIFVybFRyZWUgfSBmcm9tICdAYW5ndWxhci9yb3V0ZXInO1xuaW1wb3J0IHsgVFVJX1RSVUVfSEFORExFUiwgdHVpSXNQcmVzZW50IH0gZnJvbSAnQHRhaWdhLXVpL2Nkayc7XG5pbXBvcnQgeyBjYXRjaEVycm9yLCBmaWx0ZXIsIG1hcCwgT2JzZXJ2YWJsZSwgb2YgfSBmcm9tICdyeGpzJztcblxuaW1wb3J0IHsgU2NDYXRhbG9nU2VydmljZSB9IGZyb20gJy4uL2NhdGFsb2cvc2VydmljZXMvc2MtY2F0YWxvZy5zZXJ2aWNlJztcbmltcG9ydCB7IFNjQ2F0YWxvZ1JlZGlyZWN0U2VydmljZSB9IGZyb20gJy4uL2NhdGFsb2cvc2VydmljZXMvc2MtY2F0YWxvZy1yZWRpcmVjdC5zZXJ2aWNlJztcbmltcG9ydCB7IFNDX0lEX09SX1NMVUdfSU5fUk9VVEUgfSBmcm9tICcuLi90b2tlbnMvc2MtaWQtb3Itc2x1Zy1pbi1yb3V0ZSc7XG5cbi8qKlxuICog0KHRgtGA0LDQtiDQstGL0L/QvtC70L3Rj9GO0YnQuNC5INC/0YDQvtCy0LXRgNC60YMg0LzQsNGA0YjRgNGD0YLQsCDRgtC+0LLQsNGA0LAg0Lgg0LrQsNGC0LXQs9C+0YDQuNC4LCDQuCDRgNC10LTQuNGA0LXQutGC0LAg0LIg0LfQsNCy0LjRgdC40LzQvtGB0YLQuCDQvtGCINC90LDRgdGC0YDQvtC10Log0L7QutGA0YPQttC10L3QuNGPLlxuICpcbiAqINCg0LXQtNC40YDQtdC60YIg0LLRi9C/0L7Qu9C90Y/QtdGCIHtAbGluayBTY0NhdGFsb2dSZWRpcmVjdFNlcnZpY2UucmVkaXJlY3RUb0Nhbm9uaWNhbFVybH06INC90LAg0YHQtdGA0LLQtdGA0LUgKFNTUikg0Y3RgtC+INC/0L7RgdGC0L7Rj9C90L3Ri9C5XG4gKiDRgNC10LTQuNGA0LXQutGCIChIVFRQIDMwMSksINCyINCx0YDQsNGD0LfQtdGA0LUg4oCUINC90LDQstC40LPQsNGG0LjRjyDQstC90YPRgtGA0Lgg0L/RgNC40LvQvtC20LXQvdC40Y8uXG4gKlxuICogQHBhcmFtIHJvdXRlINCh0LXRgNCy0LjRgSDQv9GA0LXQtNC+0YHRgtCw0LLQu9GP0Y7RidC40Lkg0LTQvtGB0YLRg9C/INC6INC00LDQvdC90YvQvCDQviDQvNCw0YDRiNGA0YPRgtC1LlxuICovXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgc29uYXJqcy9mdW5jdGlvbi1yZXR1cm4tdHlwZVxuZXhwb3J0IGNvbnN0IFNjSWRPclNsdWdHdWFyZDogQ2FuQWN0aXZhdGVGbiA9IChyb3V0ZTogQWN0aXZhdGVkUm91dGVTbmFwc2hvdCk6IE9ic2VydmFibGU8Ym9vbGVhbiB8IFVybFRyZWU+IHwgYm9vbGVhbiA9PiB7XG4gICAgY29uc3QgeyBwYXJhbU1hcCB9ID0gcm91dGU7XG4gICAgY29uc3QgY2F0ZWdvcnlJZE9yU2x1ZyA9IHBhcmFtTWFwLmdldCgnY2F0ZWdvcnlJZE9yU2x1ZycpO1xuICAgIGNvbnN0IHByb2R1Y3RJZE9yU2x1ZyA9IHBhcmFtTWFwLmdldCgncHJvZHVjdElkT3JTbHVnJyk7XG4gICAgY29uc3QgaWRPclNsdWc6ICdpZCcgfCAnc2x1ZycgPSBpbmplY3Q8J2lkJyB8ICdzbHVnJz4oU0NfSURfT1JfU0xVR19JTl9ST1VURSk7XG4gICAgY29uc3QgY2F0YWxvZ1JlZGlyZWN0U2VydmljZSA9IGluamVjdChTY0NhdGFsb2dSZWRpcmVjdFNlcnZpY2UpO1xuXG4gICAgaWYgKGNhdGVnb3J5SWRPclNsdWcgJiYgL15cXGQrJC8udGVzdChjYXRlZ29yeUlkT3JTbHVnKSAhPT0gKGlkT3JTbHVnID09PSAnaWQnKSkge1xuICAgICAgICByZXR1cm4gaW5qZWN0KFNjQ2F0YWxvZ1NlcnZpY2UpXG4gICAgICAgICAgICAuZ2V0Q2F0ZWdvcnlDYWNoZWQkKGNhdGVnb3J5SWRPclNsdWcpXG4gICAgICAgICAgICAucGlwZShcbiAgICAgICAgICAgICAgICBmaWx0ZXIodHVpSXNQcmVzZW50KSxcbiAgICAgICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgc2VjdXJpdHkvZGV0ZWN0LW9iamVjdC1pbmplY3Rpb25cbiAgICAgICAgICAgICAgICBtYXAoKGNhdGVnb3J5KSA9PiBjYXRhbG9nUmVkaXJlY3RTZXJ2aWNlLnJlZGlyZWN0VG9DYW5vbmljYWxVcmwoWycvY2F0YWxvZycsIGNhdGVnb3J5W2lkT3JTbHVnXV0pKSxcbiAgICAgICAgICAgICAgICBjYXRjaEVycm9yKCgpID0+IG9mKFRVSV9UUlVFX0hBTkRMRVIoKSkpXG4gICAgICAgICAgICApO1xuICAgIH1cblxuICAgIGlmIChwcm9kdWN0SWRPclNsdWcgJiYgL15cXGQrJC8udGVzdChwcm9kdWN0SWRPclNsdWcpICE9PSAoaWRPclNsdWcgPT09ICdpZCcpKSB7XG4gICAgICAgIHJldHVybiBpbmplY3QoU2NDYXRhbG9nU2VydmljZSlcbiAgICAgICAgICAgIC5nZXRQcm9kdWN0RGF0YSQocHJvZHVjdElkT3JTbHVnKVxuICAgICAgICAgICAgLnBpcGUoXG4gICAgICAgICAgICAgICAgZmlsdGVyKHR1aUlzUHJlc2VudCksXG4gICAgICAgICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHNlY3VyaXR5L2RldGVjdC1vYmplY3QtaW5qZWN0aW9uXG4gICAgICAgICAgICAgICAgbWFwKChwcm9kdWN0KSA9PiBjYXRhbG9nUmVkaXJlY3RTZXJ2aWNlLnJlZGlyZWN0VG9DYW5vbmljYWxVcmwoWycvY2F0YWxvZycsICdwcm9kdWN0JywgcHJvZHVjdFtpZE9yU2x1Z11dKSksXG4gICAgICAgICAgICAgICAgY2F0Y2hFcnJvcigoKSA9PiBvZihUVUlfVFJVRV9IQU5ETEVSKCkpKVxuICAgICAgICAgICAgKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdHJ1ZTtcbn07XG4iXX0=
@@ -1,6 +1,7 @@
1
1
  export * from './notification-options';
2
2
  export * from './sc-api-keys';
3
3
  export * from './sc-cache-lifetime';
4
+ export * from './sc-canonical-redirect-enabled';
4
5
  export * from './sc-company-info';
5
6
  export * from './sc-company-name';
6
7
  export * from './sc-configurator-components';
@@ -16,4 +17,4 @@ export * from './sc-release';
16
17
  export * from './sc-update-interval';
17
18
  export * from './sc-urls';
18
19
  export * from './sc-feedback-api';
19
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9jb3JlL3Rva2Vucy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxjQUFjLHdCQUF3QixDQUFDO0FBQ3ZDLGNBQWMsZUFBZSxDQUFDO0FBQzlCLGNBQWMscUJBQXFCLENBQUM7QUFDcEMsY0FBYyxtQkFBbUIsQ0FBQztBQUNsQyxjQUFjLG1CQUFtQixDQUFDO0FBQ2xDLGNBQWMsOEJBQThCLENBQUM7QUFDN0MsY0FBYyxrQkFBa0IsQ0FBQztBQUNqQyxjQUFjLHdCQUF3QixDQUFDO0FBQ3ZDLGNBQWMsNEJBQTRCLENBQUM7QUFDM0MsY0FBYywwQkFBMEIsQ0FBQztBQUN6QyxjQUFjLDRCQUE0QixDQUFDO0FBQzNDLGNBQWMsMEJBQTBCLENBQUM7QUFDekMsY0FBYywyQkFBMkIsQ0FBQztBQUMxQyxjQUFjLGlDQUFpQyxDQUFDO0FBQ2hELGNBQWMsY0FBYyxDQUFDO0FBQzdCLGNBQWMsc0JBQXNCLENBQUM7QUFDckMsY0FBYyxXQUFXLENBQUM7QUFDMUIsY0FBYyxtQkFBbUIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCAqIGZyb20gJy4vbm90aWZpY2F0aW9uLW9wdGlvbnMnO1xuZXhwb3J0ICogZnJvbSAnLi9zYy1hcGkta2V5cyc7XG5leHBvcnQgKiBmcm9tICcuL3NjLWNhY2hlLWxpZmV0aW1lJztcbmV4cG9ydCAqIGZyb20gJy4vc2MtY29tcGFueS1pbmZvJztcbmV4cG9ydCAqIGZyb20gJy4vc2MtY29tcGFueS1uYW1lJztcbmV4cG9ydCAqIGZyb20gJy4vc2MtY29uZmlndXJhdG9yLWNvbXBvbmVudHMnO1xuZXhwb3J0ICogZnJvbSAnLi9zYy1kYXRlLWZvcm1hdCc7XG5leHBvcnQgKiBmcm9tICcuL3NjLWRlZmF1bHQtcGFnZS1tZXRhJztcbmV4cG9ydCAqIGZyb20gJy4vc2MtY29uZmlndXJhdG9yLXNldHRpbmdzJztcbmV4cG9ydCAqIGZyb20gJy4vc2MtaWQtb3Itc2x1Zy1pbi1yb3V0ZSc7XG5leHBvcnQgKiBmcm9tICcuL3NjLWlzLWhpZGRlbi1lcnJvci1hbGVydCc7XG5leHBvcnQgKiBmcm9tICcuL3NjLWxpbmVhci12YWx1ZXMtdG9rZW4nO1xuZXhwb3J0ICogZnJvbSAnLi9zYy1wYXRoLWltYWdlLW5vdC1mb3VuZCc7XG5leHBvcnQgKiBmcm9tICcuL3NjLXByb2R1Y3QtcGFnaW5hdGlvbi1vcHRpb25zJztcbmV4cG9ydCAqIGZyb20gJy4vc2MtcmVsZWFzZSc7XG5leHBvcnQgKiBmcm9tICcuL3NjLXVwZGF0ZS1pbnRlcnZhbCc7XG5leHBvcnQgKiBmcm9tICcuL3NjLXVybHMnO1xuZXhwb3J0ICogZnJvbSAnLi9zYy1mZWVkYmFjay1hcGknO1xuIl19
20
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9jb3JlL3Rva2Vucy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxjQUFjLHdCQUF3QixDQUFDO0FBQ3ZDLGNBQWMsZUFBZSxDQUFDO0FBQzlCLGNBQWMscUJBQXFCLENBQUM7QUFDcEMsY0FBYyxpQ0FBaUMsQ0FBQztBQUNoRCxjQUFjLG1CQUFtQixDQUFDO0FBQ2xDLGNBQWMsbUJBQW1CLENBQUM7QUFDbEMsY0FBYyw4QkFBOEIsQ0FBQztBQUM3QyxjQUFjLGtCQUFrQixDQUFDO0FBQ2pDLGNBQWMsd0JBQXdCLENBQUM7QUFDdkMsY0FBYyw0QkFBNEIsQ0FBQztBQUMzQyxjQUFjLDBCQUEwQixDQUFDO0FBQ3pDLGNBQWMsNEJBQTRCLENBQUM7QUFDM0MsY0FBYywwQkFBMEIsQ0FBQztBQUN6QyxjQUFjLDJCQUEyQixDQUFDO0FBQzFDLGNBQWMsaUNBQWlDLENBQUM7QUFDaEQsY0FBYyxjQUFjLENBQUM7QUFDN0IsY0FBYyxzQkFBc0IsQ0FBQztBQUNyQyxjQUFjLFdBQVcsQ0FBQztBQUMxQixjQUFjLG1CQUFtQixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0ICogZnJvbSAnLi9ub3RpZmljYXRpb24tb3B0aW9ucyc7XG5leHBvcnQgKiBmcm9tICcuL3NjLWFwaS1rZXlzJztcbmV4cG9ydCAqIGZyb20gJy4vc2MtY2FjaGUtbGlmZXRpbWUnO1xuZXhwb3J0ICogZnJvbSAnLi9zYy1jYW5vbmljYWwtcmVkaXJlY3QtZW5hYmxlZCc7XG5leHBvcnQgKiBmcm9tICcuL3NjLWNvbXBhbnktaW5mbyc7XG5leHBvcnQgKiBmcm9tICcuL3NjLWNvbXBhbnktbmFtZSc7XG5leHBvcnQgKiBmcm9tICcuL3NjLWNvbmZpZ3VyYXRvci1jb21wb25lbnRzJztcbmV4cG9ydCAqIGZyb20gJy4vc2MtZGF0ZS1mb3JtYXQnO1xuZXhwb3J0ICogZnJvbSAnLi9zYy1kZWZhdWx0LXBhZ2UtbWV0YSc7XG5leHBvcnQgKiBmcm9tICcuL3NjLWNvbmZpZ3VyYXRvci1zZXR0aW5ncyc7XG5leHBvcnQgKiBmcm9tICcuL3NjLWlkLW9yLXNsdWctaW4tcm91dGUnO1xuZXhwb3J0ICogZnJvbSAnLi9zYy1pcy1oaWRkZW4tZXJyb3ItYWxlcnQnO1xuZXhwb3J0ICogZnJvbSAnLi9zYy1saW5lYXItdmFsdWVzLXRva2VuJztcbmV4cG9ydCAqIGZyb20gJy4vc2MtcGF0aC1pbWFnZS1ub3QtZm91bmQnO1xuZXhwb3J0ICogZnJvbSAnLi9zYy1wcm9kdWN0LXBhZ2luYXRpb24tb3B0aW9ucyc7XG5leHBvcnQgKiBmcm9tICcuL3NjLXJlbGVhc2UnO1xuZXhwb3J0ICogZnJvbSAnLi9zYy11cGRhdGUtaW50ZXJ2YWwnO1xuZXhwb3J0ICogZnJvbSAnLi9zYy11cmxzJztcbmV4cG9ydCAqIGZyb20gJy4vc2MtZmVlZGJhY2stYXBpJztcbiJdfQ==
@@ -0,0 +1,10 @@
1
+ import { InjectionToken } from '@angular/core';
2
+ /**
3
+ * Токен, определяющий, что включён постоянный (301) редирект на канонический адрес товара или категории.
4
+ *
5
+ * Если механизм выключен, редирект выполняется навигацией внутри приложения, и SSR отвечает кодом 200.
6
+ */
7
+ export const SC_CANONICAL_REDIRECT_ENABLED = new InjectionToken('SC_CANONICAL_REDIRECT_ENABLED', {
8
+ factory: () => true,
9
+ });
10
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2MtY2Fub25pY2FsLXJlZGlyZWN0LWVuYWJsZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9jb3JlL3Rva2Vucy9zYy1jYW5vbmljYWwtcmVkaXJlY3QtZW5hYmxlZC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBRS9DOzs7O0dBSUc7QUFDSCxNQUFNLENBQUMsTUFBTSw2QkFBNkIsR0FBRyxJQUFJLGNBQWMsQ0FBVSwrQkFBK0IsRUFBRTtJQUN0RyxPQUFPLEVBQUUsR0FBRyxFQUFFLENBQUMsSUFBSTtDQUN0QixDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3Rpb25Ub2tlbiB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuXG4vKipcbiAqINCi0L7QutC10L0sINC+0L/RgNC10LTQtdC70Y/RjtGJ0LjQuSwg0YfRgtC+INCy0LrQu9GO0YfRkdC9INC/0L7RgdGC0L7Rj9C90L3Ri9C5ICgzMDEpINGA0LXQtNC40YDQtdC60YIg0L3QsCDQutCw0L3QvtC90LjRh9C10YHQutC40Lkg0LDQtNGA0LXRgSDRgtC+0LLQsNGA0LAg0LjQu9C4INC60LDRgtC10LPQvtGA0LjQuC5cbiAqXG4gKiDQldGB0LvQuCDQvNC10YXQsNC90LjQt9C8INCy0YvQutC70Y7Rh9C10L0sINGA0LXQtNC40YDQtdC60YIg0LLRi9C/0L7Qu9C90Y/QtdGC0YHRjyDQvdCw0LLQuNCz0LDRhtC40LXQuSDQstC90YPRgtGA0Lgg0L/RgNC40LvQvtC20LXQvdC40Y8sINC4IFNTUiDQvtGC0LLQtdGH0LDQtdGCINC60L7QtNC+0LwgMjAwLlxuICovXG5leHBvcnQgY29uc3QgU0NfQ0FOT05JQ0FMX1JFRElSRUNUX0VOQUJMRUQgPSBuZXcgSW5qZWN0aW9uVG9rZW48Ym9vbGVhbj4oJ1NDX0NBTk9OSUNBTF9SRURJUkVDVF9FTkFCTEVEJywge1xuICAgIGZhY3Rvcnk6ICgpID0+IHRydWUsXG59KTtcbiJdfQ==
@@ -19,6 +19,21 @@ import { __decorate } from 'tslib';
19
19
  import { objectToSnake, objectToCamel, toSnake } from 'ts-case-convert';
20
20
  import { Meta, Title } from '@angular/platform-browser';
21
21
 
22
+ /**
23
+ * Статусы HTTP-редиректа, отдаваемые при рендере на сервере (SSR).
24
+ */
25
+ var ScRedirectStatusEnum;
26
+ (function (ScRedirectStatusEnum) {
27
+ /**
28
+ * Постоянный редирект: адрес изменился навсегда, страница заменяется в индексе поисковых систем.
29
+ */
30
+ ScRedirectStatusEnum[ScRedirectStatusEnum["Permanent"] = 301] = "Permanent";
31
+ /**
32
+ * Временный редирект: исходный адрес может снова стать доступным, поэтому остаётся в индексе поисковых систем.
33
+ */
34
+ ScRedirectStatusEnum[ScRedirectStatusEnum["Temporary"] = 302] = "Temporary";
35
+ })(ScRedirectStatusEnum || (ScRedirectStatusEnum = {}));
36
+
22
37
  /**
23
38
  * Статусы состояния запроса.
24
39
  */
@@ -472,6 +487,15 @@ const SC_AUTH_AS_CLIENT_OPTIONS = new InjectionToken('SC_AUTH_AS_CLIENT_OPTIONS'
472
487
  */
473
488
  const SC_CACHE_LIFETIME = new InjectionToken('ICacheLifetime');
474
489
 
490
+ /**
491
+ * Токен, определяющий, что включён постоянный (301) редирект на канонический адрес товара или категории.
492
+ *
493
+ * Если механизм выключен, редирект выполняется навигацией внутри приложения, и SSR отвечает кодом 200.
494
+ */
495
+ const SC_CANONICAL_REDIRECT_ENABLED = new InjectionToken('SC_CANONICAL_REDIRECT_ENABLED', {
496
+ factory: () => true,
497
+ });
498
+
475
499
  /**
476
500
  * Токен для получения полной информации о компании.
477
501
  */
@@ -3606,7 +3630,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
3606
3630
  }] }, { type: ScUserMetrikaService }] });
3607
3631
 
3608
3632
  /**
3609
- * Сервис редиректа на родительскую категорию при недоступности (HTTP 404) товара или категории.
3633
+ * Сервис редиректов каталога: на родительскую категорию при недоступности (HTTP 404) товара или категории
3634
+ * и на канонический адрес товара или категории (см. {@link redirectToCanonicalUrl}).
3635
+ *
3636
+ * Редирект на родительскую категорию.
3610
3637
  *
3611
3638
  * Запрашивает у бэкенда родительскую категорию недоступной сущности и выполняет редирект:
3612
3639
  * - на сервере (SSR) при доступном {@link RESPONSE} — выставляет HTTP-статус 302 и заголовок `Location` для корректного редиректа поисковых ботов;
@@ -3630,6 +3657,10 @@ class ScCatalogRedirectService {
3630
3657
  * Признак использования идентификатора или slug в маршрутах товаров и категорий.
3631
3658
  */
3632
3659
  this.idOrSlug = inject(SC_ID_OR_SLUG_IN_ROUTE);
3660
+ /**
3661
+ * Признак, что включён постоянный редирект на канонический адрес товара или категории.
3662
+ */
3663
+ this.isCanonicalRedirectEnabled = inject(SC_CANONICAL_REDIRECT_ENABLED);
3633
3664
  /**
3634
3665
  * Признак, что текущий скрипт исполняется на сервере.
3635
3666
  */
@@ -3641,7 +3672,7 @@ class ScCatalogRedirectService {
3641
3672
  * через CommonEngine. На upgrade-ветке `server.ts` остался на CommonEngine, поэтому при слиянии здесь
3642
3673
  * ничего менять не нужно. Если `server.ts` мигрируют на `AngularNodeAppEngine` + `createNodeRequestHandler`,
3643
3674
  * замените {@link RESPONSE} на нативный `RESPONSE_INIT` (`InjectionToken<ResponseInit | null>` из `@angular/core`);
3644
- * см. серверную ветку в {@link redirectToParentCategory$}.
3675
+ * см. серверные ветки в {@link redirectToParentCategory$} и {@link redirectToCanonicalUrl}.
3645
3676
  */
3646
3677
  this.response = inject(RESPONSE, { optional: true });
3647
3678
  /**
@@ -3649,6 +3680,39 @@ class ScCatalogRedirectService {
3649
3680
  */
3650
3681
  this.document = inject(DOCUMENT);
3651
3682
  }
3683
+ /**
3684
+ * Возвращает результат стража маршрута для перехода на канонический адрес товара или категории
3685
+ * (адрес со slug либо с идентификатором — в зависимости от настроек окружения).
3686
+ *
3687
+ * @param commands Сегменты канонического маршрута.
3688
+ * @param status Статус редиректа: вид адреса задаётся настройками окружения и может быть изменён, поэтому по умолчанию временный.
3689
+ * @returns Дерево канонического маршрута для навигации либо `false`, если редирект выполнен ответом сервера.
3690
+ */
3691
+ // eslint-disable-next-line sonarjs/function-return-type
3692
+ redirectToCanonicalUrl(commands, status = ScRedirectStatusEnum.Temporary) {
3693
+ const urlTree = this.router.createUrlTree(commands);
3694
+ if (this.isCanonicalRedirectEnabled && this.isServer && this.setServerRedirect(this.router.serializeUrl(urlTree), status)) {
3695
+ return false;
3696
+ }
3697
+ return urlTree;
3698
+ }
3699
+ /**
3700
+ * Выставляет редирект в ответе сервера (SSR).
3701
+ *
3702
+ * @param targetUrl Адрес, на который выполняется редирект.
3703
+ * @param status Статус редиректа.
3704
+ * @returns Признак, что редирект выставлен; `false`, если данные об ответе недоступны (например, dev-сервер `ng serve`).
3705
+ */
3706
+ setServerRedirect(targetUrl, status) {
3707
+ if (!this.response) {
3708
+ return false;
3709
+ }
3710
+ // Angular 21 (миграция SSR): при переходе server.ts на AngularNodeAppEngine статус и заголовок выставляются
3711
+ // через нативный RESPONSE_INIT вместо Express-методов response.setHeader/response.status.
3712
+ this.response.setHeader('Location', targetUrl);
3713
+ this.response.status(status);
3714
+ return true;
3715
+ }
3652
3716
  /**
3653
3717
  * Выполняет редирект на родительскую категорию недоступной категории.
3654
3718
  *
@@ -3730,14 +3794,8 @@ class ScCatalogRedirectService {
3730
3794
  const urlTree = this.router.createUrlTree(['/catalog', target]);
3731
3795
  const targetUrl = this.router.serializeUrl(urlTree);
3732
3796
  if (this.isServer) {
3733
- // SSR с доступным RESPONSE (прод-сервер): выставляем 302 и заголовок Location для корректного редиректа поисковых ботов.
3734
- //
3735
- // Angular 21 (миграция SSR): при переходе server.ts на AngularNodeAppEngine выставляйте статус/заголовок
3736
- // через нативный RESPONSE_INIT вместо Express-методов response.setHeader/response.status:
3737
- // if (this.responseInit) { this.responseInit.status = 302; (this.responseInit.headers as Record<string, string>)['Location'] = targetUrl; }
3738
- if (this.response) {
3739
- this.response.setHeader('Location', targetUrl);
3740
- this.response.status(302);
3797
+ // Скрытые категория или товар могут снова стать доступными, поэтому редирект на родителя временный.
3798
+ if (this.setServerRedirect(targetUrl, ScRedirectStatusEnum.Temporary)) {
3741
3799
  return EMPTY;
3742
3800
  }
3743
3801
  // SSR без RESPONSE (например, dev-сервер ng serve): серверный редирект невозможен,
@@ -5707,6 +5765,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
5707
5765
  /**
5708
5766
  * Страж выполняющий проверку маршрута товара и категории, и редиректа в зависимости от настроек окружения.
5709
5767
  *
5768
+ * Редирект выполняет {@link ScCatalogRedirectService.redirectToCanonicalUrl}: на сервере (SSR) это постоянный
5769
+ * редирект (HTTP 301), в браузере — навигация внутри приложения.
5770
+ *
5710
5771
  * @param route Сервис предоставляющий доступ к данным о маршруте.
5711
5772
  */
5712
5773
  // eslint-disable-next-line sonarjs/function-return-type
@@ -5715,20 +5776,20 @@ const ScIdOrSlugGuard = (route) => {
5715
5776
  const categoryIdOrSlug = paramMap.get('categoryIdOrSlug');
5716
5777
  const productIdOrSlug = paramMap.get('productIdOrSlug');
5717
5778
  const idOrSlug = inject(SC_ID_OR_SLUG_IN_ROUTE);
5718
- const router = inject(Router);
5779
+ const catalogRedirectService = inject(ScCatalogRedirectService);
5719
5780
  if (categoryIdOrSlug && /^\d+$/.test(categoryIdOrSlug) !== (idOrSlug === 'id')) {
5720
5781
  return inject(ScCatalogService)
5721
5782
  .getCategoryCached$(categoryIdOrSlug)
5722
5783
  .pipe(filter(tuiIsPresent),
5723
5784
  // eslint-disable-next-line security/detect-object-injection
5724
- map$1((category) => router.createUrlTree(['/catalog', category[idOrSlug]])), catchError$1(() => of(TUI_TRUE_HANDLER())));
5785
+ map$1((category) => catalogRedirectService.redirectToCanonicalUrl(['/catalog', category[idOrSlug]])), catchError$1(() => of(TUI_TRUE_HANDLER())));
5725
5786
  }
5726
5787
  if (productIdOrSlug && /^\d+$/.test(productIdOrSlug) !== (idOrSlug === 'id')) {
5727
5788
  return inject(ScCatalogService)
5728
5789
  .getProductData$(productIdOrSlug)
5729
5790
  .pipe(filter(tuiIsPresent),
5730
5791
  // eslint-disable-next-line security/detect-object-injection
5731
- map$1((product) => router.createUrlTree(['/catalog', 'product', product[idOrSlug]])), catchError$1(() => of(TUI_TRUE_HANDLER())));
5792
+ map$1((product) => catalogRedirectService.redirectToCanonicalUrl(['/catalog', 'product', product[idOrSlug]])), catchError$1(() => of(TUI_TRUE_HANDLER())));
5732
5793
  }
5733
5794
  return true;
5734
5795
  };
@@ -9032,5 +9093,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
9032
9093
  * Generated bundle index. Do not edit.
9033
9094
  */
9034
9095
 
9035
- export { CATEGORY_PROVIDERS, EMPTY_CART, IS_BROWSER, IS_RUNNING_ON_TERMINAL, IS_SERVER, RESPONSE, SC_ACCESS_AUTH_TOKEN_STORAGE_KEY, SC_API_KEYS, SC_AUTH_ADD_HEADER_REQUIRED, SC_AUTH_AS_CLIENT_DEFAULT_OPTIONS, SC_AUTH_AS_CLIENT_OPTIONS, SC_CACHE_LIFETIME, SC_CACHE_SETTINGS, SC_CATALOG_ITEM_PAGE_META, SC_CATALOG_ROOT_PAGE_META, SC_CATEGORY_INFO, SC_CATEGORY_STATE, SC_COMPANY_INFO, SC_COMPANY_NAME, SC_CONFIGURATOR_COMPONENTS, SC_CONFIGURATOR_SETTINGS, SC_COUNT_FIRST_DISCOUNTED_PRODUCTS, SC_COUNT_LAST_NEWS, SC_DATE_FORMAT, SC_DEFAULT_PAGE_META, SC_FEEDBACK_API, SC_GUEST_ENDPOINTS_TOKEN, SC_GUEST_PARAMETER_NAME_TOKEN, SC_GUEST_TOKEN_STORAGE_KEY, SC_ID_OR_SLUG_IN_ROUTE, SC_IS_HEADER_REQUIRED, SC_IS_HIDDEN_ERROR_ALERT, SC_IS_HIDDEN_ERROR_ALERT_HTTP_CONTEXT, SC_IS_LOGOUT_REQUEST, SC_IS_REFRESH_REQUIRED, SC_LINEAR_VALUES, SC_LINEAR_VALUES_TOKEN, SC_MAX_LENGTH_SEARCH_TERM, SC_MIN_LENGTH_SEARCH_TERM, SC_NEXT_PAGE_PAGINATION_CLICK, SC_ORDER_LOADER, SC_ORDER_LOADING, SC_PAGE_QUERY_PARAM, SC_PATH_IMAGE_NOT_FOUND, SC_PRODUCTS_PAGINATION_LOADER, SC_PRODUCT_PAGINATION_DEFAULT_OPTIONS, SC_PRODUCT_PAGINATION_OPTIONS, SC_REFRESH_AUTH_TOKEN_STORAGE_KEY, SC_RELEASE, SC_UPDATE_INTERVAL, SC_URLS, SC_USER_INFO, SC_VACANCIES_DATA_SOURCE, SC_VIRTUAL_CATEGORY_INFO, SC_VIRTUAL_CATEGORY_PROVIDERS, SEARCH_TERM, SEARCH_TERM_PROVIDERS, ScAuthAsClientGuard, ScAuthInterceptor, ScAuthService, ScBanner, ScBannerService, ScCacheInterceptor, ScCacheSettings, ScCachedData, ScCachedItem, ScCart, ScCartService, ScCatalogFilterService, ScCatalogFormat, ScCatalogItem, ScCatalogRedirectService, ScCatalogService, ScCatalogableItem, ScCategory, ScClientType, ScCodedIdentity, ScConfiguratorService, ScContactsService, ScContragentService, ScConvertInterceptor, ScConvertersService, ScDateFormatInterceptor, ScDeletableNamedIdentity, ScDeliveryAddressService, ScDeliveryCost, ScDeliveryType, ScDocumentInfoNode, ScDocumentInfoTypesEnum, ScErrorRequestState, ScErrorsInterceptor, ScFavoriteService, ScFeedbackForms, ScFeedbackService, ScFilesService, ScFrequentlyAskedQuestionsService, ScGuestInterceptor, ScHiddenCatalogableItem, ScIBreadcrumbItem, ScISuggestionType, ScIconTypesEnum, ScIdOrSlugGuard, ScIdOrSlugPipe, ScIdentity, ScImage, ScImageHelper, ScLoadingRequestState, ScLocationsService, ScMediaImageTransformerPipe, ScMimeTypes, ScNamedIdentity, ScNews, ScNewsService, ScNotificationActionTypes, ScNotificationLevelNames, ScNotificationsService, ScOpfList, ScOptionsInterceptor, ScOrder, ScOrderBase, ScOrderDraft, ScOrderDraftShort, ScOrderDraftType, ScOrderDraftsService, ScOrderItem, ScOrderShort, ScOrderStateStatus, ScOrdersService, ScPaginationPageQueryParamService, ScPaginationService, ScPaymentStatus, ScPaymentType, ScPhoneService, ScPrimaryCatalogableItem, ScProduct, ScProductTileType, ScQuestionnaireService, ScQuestionnaireStatusEnum, ScReclamationService, ScReclamationStatus, ScRecommendationService, ScReference, ScReferenceName, ScReferencesService, ScRequestStateStatusEnum, ScRequisitesService, ScRouteKeys, ScSearchService, ScSeoService, ScSocialType, ScSuccessRequestState, ScSuggestionService, ScSum, ScTokenService, ScUIService, ScUTMService, ScUnitsHelper, ScUpdatableNamedIdentity, ScUploadedFile, ScUser, ScUserMetadata, ScUserMetrikaGoalsEnum, ScUserMetrikaService, ScUserService, ScUserType, ScVCardService, ScVacanciesList, ScVacanciesService, ScVacancy, ScVerificationService, ScVirtualCategory, ScWarehouseService, SchemaOrgFactory, TERMINAL_PROVIDERS, USER_AGENT_TERMINAL, filterChangedByKey, loadingPlaceholder, mapRequestStateToDataOrNull, mapToRequestState, runningOnTerminalFactory, scGetCurrentRoute, scGetPageQueryParamChanges, scOrderIsLoaded, scParsePageQueryParam, searchTermFactory };
9096
+ export { CATEGORY_PROVIDERS, EMPTY_CART, IS_BROWSER, IS_RUNNING_ON_TERMINAL, IS_SERVER, RESPONSE, SC_ACCESS_AUTH_TOKEN_STORAGE_KEY, SC_API_KEYS, SC_AUTH_ADD_HEADER_REQUIRED, SC_AUTH_AS_CLIENT_DEFAULT_OPTIONS, SC_AUTH_AS_CLIENT_OPTIONS, SC_CACHE_LIFETIME, SC_CACHE_SETTINGS, SC_CANONICAL_REDIRECT_ENABLED, SC_CATALOG_ITEM_PAGE_META, SC_CATALOG_ROOT_PAGE_META, SC_CATEGORY_INFO, SC_CATEGORY_STATE, SC_COMPANY_INFO, SC_COMPANY_NAME, SC_CONFIGURATOR_COMPONENTS, SC_CONFIGURATOR_SETTINGS, SC_COUNT_FIRST_DISCOUNTED_PRODUCTS, SC_COUNT_LAST_NEWS, SC_DATE_FORMAT, SC_DEFAULT_PAGE_META, SC_FEEDBACK_API, SC_GUEST_ENDPOINTS_TOKEN, SC_GUEST_PARAMETER_NAME_TOKEN, SC_GUEST_TOKEN_STORAGE_KEY, SC_ID_OR_SLUG_IN_ROUTE, SC_IS_HEADER_REQUIRED, SC_IS_HIDDEN_ERROR_ALERT, SC_IS_HIDDEN_ERROR_ALERT_HTTP_CONTEXT, SC_IS_LOGOUT_REQUEST, SC_IS_REFRESH_REQUIRED, SC_LINEAR_VALUES, SC_LINEAR_VALUES_TOKEN, SC_MAX_LENGTH_SEARCH_TERM, SC_MIN_LENGTH_SEARCH_TERM, SC_NEXT_PAGE_PAGINATION_CLICK, SC_ORDER_LOADER, SC_ORDER_LOADING, SC_PAGE_QUERY_PARAM, SC_PATH_IMAGE_NOT_FOUND, SC_PRODUCTS_PAGINATION_LOADER, SC_PRODUCT_PAGINATION_DEFAULT_OPTIONS, SC_PRODUCT_PAGINATION_OPTIONS, SC_REFRESH_AUTH_TOKEN_STORAGE_KEY, SC_RELEASE, SC_UPDATE_INTERVAL, SC_URLS, SC_USER_INFO, SC_VACANCIES_DATA_SOURCE, SC_VIRTUAL_CATEGORY_INFO, SC_VIRTUAL_CATEGORY_PROVIDERS, SEARCH_TERM, SEARCH_TERM_PROVIDERS, ScAuthAsClientGuard, ScAuthInterceptor, ScAuthService, ScBanner, ScBannerService, ScCacheInterceptor, ScCacheSettings, ScCachedData, ScCachedItem, ScCart, ScCartService, ScCatalogFilterService, ScCatalogFormat, ScCatalogItem, ScCatalogRedirectService, ScCatalogService, ScCatalogableItem, ScCategory, ScClientType, ScCodedIdentity, ScConfiguratorService, ScContactsService, ScContragentService, ScConvertInterceptor, ScConvertersService, ScDateFormatInterceptor, ScDeletableNamedIdentity, ScDeliveryAddressService, ScDeliveryCost, ScDeliveryType, ScDocumentInfoNode, ScDocumentInfoTypesEnum, ScErrorRequestState, ScErrorsInterceptor, ScFavoriteService, ScFeedbackForms, ScFeedbackService, ScFilesService, ScFrequentlyAskedQuestionsService, ScGuestInterceptor, ScHiddenCatalogableItem, ScIBreadcrumbItem, ScISuggestionType, ScIconTypesEnum, ScIdOrSlugGuard, ScIdOrSlugPipe, ScIdentity, ScImage, ScImageHelper, ScLoadingRequestState, ScLocationsService, ScMediaImageTransformerPipe, ScMimeTypes, ScNamedIdentity, ScNews, ScNewsService, ScNotificationActionTypes, ScNotificationLevelNames, ScNotificationsService, ScOpfList, ScOptionsInterceptor, ScOrder, ScOrderBase, ScOrderDraft, ScOrderDraftShort, ScOrderDraftType, ScOrderDraftsService, ScOrderItem, ScOrderShort, ScOrderStateStatus, ScOrdersService, ScPaginationPageQueryParamService, ScPaginationService, ScPaymentStatus, ScPaymentType, ScPhoneService, ScPrimaryCatalogableItem, ScProduct, ScProductTileType, ScQuestionnaireService, ScQuestionnaireStatusEnum, ScReclamationService, ScReclamationStatus, ScRecommendationService, ScRedirectStatusEnum, ScReference, ScReferenceName, ScReferencesService, ScRequestStateStatusEnum, ScRequisitesService, ScRouteKeys, ScSearchService, ScSeoService, ScSocialType, ScSuccessRequestState, ScSuggestionService, ScSum, ScTokenService, ScUIService, ScUTMService, ScUnitsHelper, ScUpdatableNamedIdentity, ScUploadedFile, ScUser, ScUserMetadata, ScUserMetrikaGoalsEnum, ScUserMetrikaService, ScUserService, ScUserType, ScVCardService, ScVacanciesList, ScVacanciesService, ScVacancy, ScVerificationService, ScVirtualCategory, ScWarehouseService, SchemaOrgFactory, TERMINAL_PROVIDERS, USER_AGENT_TERMINAL, filterChangedByKey, loadingPlaceholder, mapRequestStateToDataOrNull, mapToRequestState, runningOnTerminalFactory, scGetCurrentRoute, scGetPageQueryParamChanges, scOrderIsLoaded, scParsePageQueryParam, searchTermFactory };
9036
9097
  //# sourceMappingURL=snabcentr-client-core.mjs.map