@alauda-fe/common 1.4.28-beta.5 → 1.4.28
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/core/constants/constants.d.ts +0 -3
- package/core/services/intercept-deactivate.service.d.ts +2 -2
- package/core/services/time.service.d.ts +2 -8
- package/esm2022/abnormal-page/abnormal-page.component.mjs +1 -1
- package/esm2022/array-form-table/form/component.mjs +1 -1
- package/esm2022/array-form-table/key-value-form/component.mjs +1 -1
- package/esm2022/array-form-table/key-value-table/component.mjs +1 -1
- package/esm2022/array-form-table/string-array-form/component.mjs +1 -1
- package/esm2022/async-data/error-page/component.mjs +1 -1
- package/esm2022/async-data/page-state/component.mjs +1 -1
- package/esm2022/business/notification-disabled-container/component.mjs +1 -1
- package/esm2022/business/resource-select/exports/cluster-list/component.mjs +1 -1
- package/esm2022/business/resource-select/exports/cluster-selector/component.mjs +1 -1
- package/esm2022/business/resource-select/exports/icon/component.mjs +1 -1
- package/esm2022/business/resource-select/exports/mesh-group-selector/component.mjs +1 -1
- package/esm2022/business/resource-select/exports/namespace-list/component.mjs +1 -1
- package/esm2022/business/resource-select/exports/namespace-page/component.mjs +1 -1
- package/esm2022/business/resource-select/exports/namespace-selector/component.mjs +1 -1
- package/esm2022/business/resource-select/exports/project-list/component.mjs +1 -1
- package/esm2022/business/resource-select/exports/project-page/component.mjs +1 -1
- package/esm2022/business/resource-select/exports/project-selector/component.mjs +1 -1
- package/esm2022/business/resource-select/internals/data-grid/component.mjs +1 -1
- package/esm2022/business/resource-select/internals/meshgroup-list/component.mjs +1 -1
- package/esm2022/business/resource-select/internals/no-data/component.mjs +1 -1
- package/esm2022/business/resource-select/internals/resource-dashboard/component.mjs +1 -1
- package/esm2022/business/resource-select/internals/selector-popup/component.mjs +1 -1
- package/esm2022/chart/common/axis/axis-label.component.mjs +1 -1
- package/esm2022/chart/common/axis/x-axis-ticks.component.mjs +1 -1
- package/esm2022/chart/common/axis/x-axis.component.mjs +1 -1
- package/esm2022/chart/common/axis/x-plot-lines.component.mjs +1 -1
- package/esm2022/chart/common/axis/y-axis-ticks.component.mjs +1 -1
- package/esm2022/chart/common/axis/y-axis.component.mjs +1 -1
- package/esm2022/chart/common/axis/y-plot-lines.component.mjs +1 -1
- package/esm2022/chart/common/chart/chart.component.mjs +1 -1
- package/esm2022/chart/common/legend/legend.component.mjs +1 -1
- package/esm2022/chart/common/range-area/range-area.component.mjs +1 -1
- package/esm2022/chart/common/reference-area/reference-area.component.mjs +1 -1
- package/esm2022/chart/common/series/area-series.component.mjs +1 -1
- package/esm2022/chart/common/series/bar-path.component.mjs +1 -1
- package/esm2022/chart/common/series/bar-series.component.mjs +1 -1
- package/esm2022/chart/common/series/line-series.component.mjs +1 -1
- package/esm2022/chart/common/tooltip/tooltip.component.mjs +1 -1
- package/esm2022/chart/custom-template/dropdown-legend.mjs +1 -1
- package/esm2022/code/code-display-dialog/component.mjs +1 -1
- package/esm2022/code/k8s-yaml-display-dialog/component.mjs +1 -1
- package/esm2022/code/resource-yaml-display/component.mjs +1 -1
- package/esm2022/code/resource-yaml-editor/component.mjs +1 -1
- package/esm2022/code/yaml-sidebar/component.mjs +1 -1
- package/esm2022/core/components/tree/node/component.mjs +1 -1
- package/esm2022/core/components/tree/tree/component.mjs +1 -1
- package/esm2022/core/constants/constants.mjs +1 -4
- package/esm2022/core/directives/readonly-field.directive.mjs +1 -1
- package/esm2022/core/guards/intercept-deactivate.guard.mjs +2 -2
- package/esm2022/core/services/intercept-deactivate.service.mjs +1 -1
- package/esm2022/core/services/time.service.mjs +36 -13
- package/esm2022/custom-columns-setting/component.mjs +1 -1
- package/esm2022/disabled-container/disabled-container.component.mjs +1 -1
- package/esm2022/editable/editable.component.mjs +1 -1
- package/esm2022/editable-text/component.mjs +1 -1
- package/esm2022/exec/placeholder/component.mjs +1 -1
- package/esm2022/exec/terminal/component.mjs +1 -1
- package/esm2022/exec/terminal-group/component.mjs +1 -1
- package/esm2022/feature-gate-forbidden/component/component.mjs +1 -1
- package/esm2022/form/errors-mapper/errors-mapper-component/component.mjs +1 -1
- package/esm2022/form/errors-mapper/errors-mapper.directive.mjs +1 -1
- package/esm2022/form/labels-editor/component.mjs +1 -1
- package/esm2022/form/taints-editor/component.mjs +1 -1
- package/esm2022/form/upload-file/component.mjs +1 -1
- package/esm2022/form/validators/strong-password/strong-password-tooltip/component.mjs +1 -1
- package/esm2022/graph-canvas/components/graph-actions.component.mjs +1 -1
- package/esm2022/graph-canvas/components/graph-canvas.component.mjs +1 -1
- package/esm2022/graph-canvas/components/graph-link.component.mjs +1 -1
- package/esm2022/graph-canvas/components/graph-links.component.mjs +1 -1
- package/esm2022/grid-layout/components/grid/component.mjs +1 -1
- package/esm2022/grid-layout/components/grid-items/component.mjs +1 -1
- package/esm2022/help-document/component.mjs +1 -1
- package/esm2022/k8s-resource-list/footer/component.mjs +1 -1
- package/esm2022/k8s-shared/resource-mark/k8s-resource-mark.component.mjs +1 -1
- package/esm2022/k8s-shared/update-description-dialog/component.mjs +1 -1
- package/esm2022/k8s-shared/update-display-name-dialog/component.mjs +1 -1
- package/esm2022/k8s-shared/update-key-value-dialog/component.mjs +1 -1
- package/esm2022/lazy-component/lazy-load-component.mjs +1 -1
- package/esm2022/license/license-error/component.mjs +1 -1
- package/esm2022/list-display/component.mjs +1 -1
- package/esm2022/metric-chart/metric-chart.component.mjs +1 -1
- package/esm2022/metric-chart/metric-time-pick.mjs +1 -1
- package/esm2022/multi-search/action-input/component.mjs +1 -1
- package/esm2022/multi-search/form/component.mjs +1 -1
- package/esm2022/multi-search/multi-search-tags/component.mjs +1 -1
- package/esm2022/mutable/mosaic/mosaic.component.mjs +1 -1
- package/esm2022/notification/feedback-notification/component.mjs +1 -1
- package/esm2022/overview-banner/overview-banner.component.mjs +1 -1
- package/esm2022/page-guard/component/component.mjs +1 -1
- package/esm2022/page-scaffold/navigation/breadcrumb/breadcrumb.component.mjs +1 -1
- package/esm2022/page-scaffold/navigation/nav-menu/nav-item-li/nav-item-li.component.mjs +1 -1
- package/esm2022/page-scaffold/navigation/nav-menu/nav-item-ul/nav-item-ul.component.mjs +1 -1
- package/esm2022/page-scaffold/navigation/nav-menu/nav-menu.component.mjs +1 -1
- package/esm2022/page-scaffold/page/notices/maintenance.component.mjs +1 -1
- package/esm2022/page-scaffold/page/notices/notice.component.mjs +1 -1
- package/esm2022/page-scaffold/page/page.component.mjs +1 -1
- package/esm2022/page-scaffold/page/page.module.mjs +6 -5
- package/esm2022/page-scaffold/page-header/account-menu/component/component.mjs +1 -1
- package/esm2022/page-scaffold/page-header/common-layout/namespace-select/component.mjs +1 -1
- package/esm2022/page-scaffold/page-header/common-layout/product-select/component.mjs +1 -1
- package/esm2022/page-scaffold/page-header/component.mjs +1 -1
- package/esm2022/page-scaffold/page-header/enterprise-support-status/component.mjs +1 -1
- package/esm2022/page-scaffold/page-header/header-notify/component/header-notify.component.mjs +1 -1
- package/esm2022/page-scaffold/page-header/header-notify/component/notification-list/notification-list.component.mjs +1 -1
- package/esm2022/page-scaffold/page-header/help-menu/component/component.mjs +1 -1
- package/esm2022/page-scaffold/page-header/help-menu/module.mjs +9 -8
- package/esm2022/pie-derivative-chart/donut-status/component.mjs +1 -1
- package/esm2022/pie-derivative-chart/radial-bar/radial-bar-chart.component.mjs +1 -1
- package/esm2022/pod-status/component.mjs +1 -1
- package/esm2022/searchable-selector/component.mjs +1 -1
- package/esm2022/skeleton/item/component.mjs +1 -1
- package/esm2022/skeleton/nav-skeleton/component.mjs +1 -1
- package/esm2022/table/component.mjs +1 -1
- package/esm2022/table/module.mjs +12 -11
- package/esm2022/translate/constants.mjs +1 -2
- package/esm2022/translate/intl-format.pipes.mjs +293 -0
- package/esm2022/translate/public-api.mjs +4 -3
- package/esm2022/translate/relative-time-manager.service.mjs +87 -0
- package/esm2022/translate/translate.directive.mjs +5 -4
- package/esm2022/translate/translate.module.mjs +22 -3
- package/esm2022/translate/translate.pipe.mjs +7 -8
- package/esm2022/translate/translate.service.mjs +721 -142
- package/esm2022/translate/types.mjs +1 -1
- package/esm2022/view-chart/custom-template/dropdown-legend.mjs +1 -1
- package/esm2022/view-chart/legend/legend.component.mjs +1 -1
- package/esm2022/view-chart/view-chart.component.mjs +1 -1
- package/esm2022/view-zchart/custom-template/dropdown-legend.mjs +1 -1
- package/esm2022/view-zchart/legend/legend.component.mjs +1 -1
- package/esm2022/view-zchart/view-zchart.component.mjs +1 -1
- package/esm2022/widget/card-section/card-section.component.mjs +1 -1
- package/esm2022/widget/confirm-delete/confirm-delete.component.mjs +1 -1
- package/esm2022/widget/current-time/component.mjs +1 -1
- package/esm2022/widget/date-range-picker/component.mjs +1 -1
- package/esm2022/widget/field-set/column/component.mjs +2 -2
- package/esm2022/widget/field-set/group/component.mjs +1 -1
- package/esm2022/widget/field-set/item/component.mjs +1 -1
- package/esm2022/widget/foldable-block/component.mjs +1 -1
- package/esm2022/widget/foldable-item-in-table/component.mjs +1 -1
- package/esm2022/widget/loading-mask/loading-mask.component.mjs +1 -1
- package/esm2022/widget/password-input/component.mjs +1 -1
- package/esm2022/widget/relative-time/component.mjs +1 -1
- package/esm2022/widget/resource-label/component.mjs +1 -1
- package/esm2022/widget/resource-multi-select/component.mjs +1 -1
- package/esm2022/widget/search-panel/component.mjs +1 -1
- package/esm2022/widget/search-panel/search-item/component.mjs +1 -1
- package/esm2022/widget/status-icon/status-icon.component.mjs +1 -1
- package/esm2022/widget/tags-label/component.mjs +1 -1
- package/esm2022/widget/terminating-tag/component.mjs +1 -1
- package/esm2022/widget/text-ellipsis/component.mjs +1 -1
- package/esm2022/widget/text-with-url/component.mjs +1 -1
- package/esm2022/widget/zero-state/zero-state.component.mjs +1 -1
- package/esm2022/workload-status-icon/component.mjs +1 -1
- package/esm2022/xterm/xterm-terminal/xterm-terminal.component.mjs +1 -1
- package/esm2022/xterm/xterm.component.mjs +1 -1
- package/package.json +2 -2
- package/page-scaffold/page/page.module.d.ts +4 -3
- package/page-scaffold/page-header/help-menu/module.d.ts +2 -1
- package/table/component.d.ts +1 -1
- package/table/module.d.ts +2 -1
- package/translate/intl-format.pipes.d.ts +122 -0
- package/translate/public-api.d.ts +3 -2
- package/translate/relative-time-manager.service.d.ts +32 -0
- package/translate/translate.module.d.ts +4 -2
- package/translate/translate.pipe.d.ts +4 -5
- package/translate/translate.service.d.ts +292 -20
- package/translate/types.d.ts +16 -0
- package/code/resource-yaml-display/schema/component.d.ts +0 -61
- package/code/yaml-sidebar/yaml-examples.d.ts +0 -8
- package/esm2022/code/resource-yaml-display/schema/component.mjs +0 -531
- package/esm2022/code/yaml-sidebar/yaml-examples.mjs +0 -340
|
@@ -5,239 +5,818 @@ import { __decorate, __metadata } from "tslib";
|
|
|
5
5
|
*/
|
|
6
6
|
import { HttpClient } from '@angular/common/http';
|
|
7
7
|
import { Inject, Injectable, Optional, isDevMode, } from '@angular/core';
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
8
|
+
import { IntlMessageFormat } from 'intl-messageformat';
|
|
9
|
+
import { get, head, isPlainObject } from 'lodash-es';
|
|
10
|
+
import { Observable, Subject, forkJoin, throwError, EMPTY, catchError, filter, finalize, map, takeUntil, } from 'rxjs';
|
|
10
11
|
import { ajax } from 'rxjs/ajax';
|
|
11
|
-
import { API_GATEWAY
|
|
12
|
-
import { TOKEN_BASE_HREF } from '../core/public-api';
|
|
12
|
+
import { API_GATEWAY } from '../core/constants/constants';
|
|
13
|
+
import { ObservableInput, TOKEN_BASE_HREF } from '../core/public-api';
|
|
13
14
|
import { isAbsoluteUrl } from '../core/utils/common';
|
|
14
|
-
import { ObservableInput } from '../core/utils/decorators';
|
|
15
15
|
import { parse } from '../core/utils/yaml';
|
|
16
16
|
import { FALLBACK_LANGUAGE, LOCALE_PLACEHOLDER_REGEX, LOCALE_STORAGE, } from './constants';
|
|
17
|
+
import { getUserLanguage } from './i18n-config';
|
|
17
18
|
import { TRANSLATE_OPTIONS, TRANSLATIONS } from './tokens';
|
|
18
19
|
import * as i0 from "@angular/core";
|
|
19
20
|
import * as i1 from "@angular/common/http";
|
|
21
|
+
/**
|
|
22
|
+
* 国际化翻译服务
|
|
23
|
+
*
|
|
24
|
+
* 特性:
|
|
25
|
+
* - 支持多层级翻译优先级(远程翻译 > 手动添加翻译 > 配置翻译)
|
|
26
|
+
* - 支持动态语言切换
|
|
27
|
+
* - 支持 ICU Message Format 模板插值
|
|
28
|
+
* - 支持宽松模式语言匹配
|
|
29
|
+
* - 支持异步远程翻译加载
|
|
30
|
+
*/
|
|
20
31
|
export class TranslateService {
|
|
32
|
+
/** 获取支持的语言列表 */
|
|
21
33
|
get locales() {
|
|
22
34
|
return this.options.locales;
|
|
23
35
|
}
|
|
36
|
+
/** 获取回退语言 */
|
|
24
37
|
get fallbackLocale() {
|
|
25
38
|
return this.options.fallbackLocale;
|
|
26
39
|
}
|
|
27
40
|
constructor(http, baseHref, options, translationList) {
|
|
28
41
|
this.http = http;
|
|
29
42
|
this.baseHref = baseHref;
|
|
30
|
-
|
|
43
|
+
/** 翻译添加通知流 */
|
|
44
|
+
this.translationsAdded$$ = new Subject();
|
|
45
|
+
this.translationsAdded$ = this.translationsAdded$$.asObservable();
|
|
46
|
+
/** 组件销毁通知流 */
|
|
31
47
|
this.destroy$$ = new Subject();
|
|
48
|
+
/** 本地翻译列表(优先级:后加入的优先级更高) */
|
|
32
49
|
this.translationsList = [];
|
|
50
|
+
/** 远程翻译列表(优先级最高) */
|
|
33
51
|
this.remoteTranslationsList = [];
|
|
34
|
-
|
|
52
|
+
// 初始化语言环境
|
|
53
|
+
this.locale = this.getInitialLocale(options);
|
|
54
|
+
// 初始化配置选项
|
|
35
55
|
this.options = {
|
|
36
56
|
locales: [this.locale],
|
|
37
57
|
fallbackLocale: FALLBACK_LANGUAGE,
|
|
58
|
+
loose: false,
|
|
38
59
|
...options,
|
|
39
60
|
};
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
if (options?.remoteUrl) {
|
|
45
|
-
if (Array.isArray(options.remoteUrl)) {
|
|
46
|
-
options.remoteUrl.forEach(url => this.addRemoteTranslations(url));
|
|
47
|
-
}
|
|
48
|
-
else {
|
|
49
|
-
this.addRemoteTranslations(options.remoteUrl);
|
|
50
|
-
}
|
|
51
|
-
}
|
|
61
|
+
// 初始化翻译列表
|
|
62
|
+
this.translationsList = this.getInitializeTranslations(options, translationList);
|
|
63
|
+
// 加载远程翻译
|
|
64
|
+
this.loadRemoteTranslations(options);
|
|
52
65
|
}
|
|
66
|
+
/**
|
|
67
|
+
* 组件销毁清理
|
|
68
|
+
*/
|
|
53
69
|
ngOnDestroy() {
|
|
54
70
|
this.destroy$$.next();
|
|
55
71
|
this.destroy$$.complete();
|
|
56
72
|
}
|
|
57
73
|
/**
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
*
|
|
74
|
+
* 获取翻译文本并进行模板插值
|
|
75
|
+
* 自动将传统 {{ key }} 语法转换为 ICU {key} 格式进行解析
|
|
76
|
+
* 同时支持原生 ICU Message Format 语法
|
|
77
|
+
* @param key - 翻译键或翻译对象
|
|
78
|
+
* @param data - 模板数据(支持基本类型、Date、对象和数组)
|
|
79
|
+
* @returns 翻译后的文本
|
|
80
|
+
*
|
|
81
|
+
* @example
|
|
82
|
+
* ```typescript
|
|
83
|
+
* // 对象参数(推荐)
|
|
84
|
+
* translate.get('hello', { name: 'World' }) // 模板: "Hello {name}"
|
|
85
|
+
*
|
|
86
|
+
* // 基本类型参数(自动转换为 {value})
|
|
87
|
+
* translate.get('welcome', 'John') // 模板: "Welcome {value}"
|
|
88
|
+
*
|
|
89
|
+
* // ICU 格式(数字)
|
|
90
|
+
* translate.get('itemCount', { count: 5 })
|
|
91
|
+
*
|
|
92
|
+
* // ICU 格式(日期,默认本地化)
|
|
93
|
+
* translate.get('createdAt', { date: new Date() })
|
|
94
|
+
* ```
|
|
61
95
|
*/
|
|
62
96
|
get(key, data) {
|
|
63
97
|
const translation = this.getRaw(key);
|
|
64
|
-
if (data
|
|
65
|
-
|
|
98
|
+
if (data == null) {
|
|
99
|
+
return translation;
|
|
66
100
|
}
|
|
67
101
|
try {
|
|
68
|
-
|
|
102
|
+
// 将传统的 {{ key }} 语法转换为 ICU {key} 格式
|
|
103
|
+
const icuMessage = this.convertToIcuFormat(translation);
|
|
104
|
+
// 将数据转换为 ICU 兼容的格式
|
|
105
|
+
const icuData = this.normalizeAndConvertToIcuData(data);
|
|
106
|
+
return this.formatIcuMessage(icuMessage, icuData);
|
|
69
107
|
}
|
|
70
|
-
catch {
|
|
71
|
-
|
|
72
|
-
|
|
108
|
+
catch (error) {
|
|
109
|
+
this.handleTemplateError(key, error);
|
|
110
|
+
return translation;
|
|
73
111
|
}
|
|
74
112
|
}
|
|
75
113
|
/**
|
|
76
|
-
*
|
|
77
|
-
* @param key -
|
|
78
|
-
* @
|
|
114
|
+
* 获取原始翻译文本模板(不进行插值处理)
|
|
115
|
+
* @param key - 翻译键或翻译对象
|
|
116
|
+
* @returns 原始翻译模板文本
|
|
79
117
|
*/
|
|
80
118
|
getRaw(key) {
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
119
|
+
if (typeof key === 'string') {
|
|
120
|
+
return this.getTranslationByKey(key);
|
|
121
|
+
}
|
|
122
|
+
// 当key是Translation对象时,获取当前语言的翻译值
|
|
123
|
+
const value = this.getTranslationByObject(key);
|
|
124
|
+
// 如果找到值则返回字符串形式,否则返回JSON字符串表示
|
|
125
|
+
if (value !== undefined) {
|
|
126
|
+
return value === null ? 'null' : String(value);
|
|
127
|
+
}
|
|
128
|
+
// 如果没有找到翻译,返回JSON字符串形式
|
|
129
|
+
return JSON.stringify(key);
|
|
84
130
|
}
|
|
85
131
|
/**
|
|
86
|
-
*
|
|
132
|
+
* 切换到下一个支持的语言环境
|
|
87
133
|
*/
|
|
88
134
|
toggleLocale() {
|
|
89
|
-
const
|
|
90
|
-
if (
|
|
91
|
-
|
|
92
|
-
throw new TypeError('`locales` has not been initialized correctly');
|
|
93
|
-
}
|
|
135
|
+
const currentIndex = this.options.locales.indexOf(this.locale);
|
|
136
|
+
if (currentIndex === -1) {
|
|
137
|
+
this.handleInvalidLocale();
|
|
94
138
|
return;
|
|
95
139
|
}
|
|
96
|
-
const
|
|
97
|
-
|
|
98
|
-
|
|
140
|
+
const nextIndex = (currentIndex + 1) % this.options.locales.length;
|
|
141
|
+
const nextLocale = this.options.locales[nextIndex];
|
|
142
|
+
if (nextLocale && nextLocale !== this.locale) {
|
|
143
|
+
this.setLocale(nextLocale);
|
|
99
144
|
}
|
|
100
|
-
this.setLocale(nextLocale);
|
|
101
145
|
}
|
|
146
|
+
/**
|
|
147
|
+
* 设置当前语言环境
|
|
148
|
+
* @param locale - 要设置的语言环境
|
|
149
|
+
*/
|
|
102
150
|
setLocale(locale) {
|
|
151
|
+
if (!this.isValidLocale(locale)) {
|
|
152
|
+
if (isDevMode()) {
|
|
153
|
+
console.warn(`Invalid locale: ${locale}. Supported locales: ${this.options.locales.join(', ')}`);
|
|
154
|
+
}
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
103
157
|
localStorage.setItem(LOCALE_STORAGE, locale);
|
|
104
158
|
this.locale = locale;
|
|
105
159
|
}
|
|
106
160
|
/**
|
|
107
|
-
*
|
|
161
|
+
* 手动添加翻译包
|
|
162
|
+
* @param translations - 要添加的翻译包
|
|
108
163
|
*/
|
|
109
164
|
addTranslations(translations) {
|
|
110
|
-
|
|
111
|
-
|
|
165
|
+
if (!translations || typeof translations !== 'object') {
|
|
166
|
+
if (isDevMode()) {
|
|
167
|
+
console.warn('Invalid translations object provided');
|
|
168
|
+
}
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
// 开发模式下检查重复翻译
|
|
172
|
+
if (isDevMode() && this.translationsList.length > 0) {
|
|
173
|
+
this.checkForDuplicateTranslations(translations);
|
|
174
|
+
}
|
|
175
|
+
this.translationsList.push(translations);
|
|
176
|
+
this.translationsAdded$$.next();
|
|
112
177
|
}
|
|
113
178
|
/**
|
|
114
|
-
*
|
|
179
|
+
* 添加远程翻译包
|
|
180
|
+
* @param remoteUrl - 远程翻译文件URL
|
|
115
181
|
*/
|
|
116
182
|
addRemoteTranslations(remoteUrl) {
|
|
117
183
|
if (!remoteUrl) {
|
|
118
184
|
return;
|
|
119
185
|
}
|
|
120
|
-
|
|
121
|
-
const
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
186
|
+
const normalizedUrl = this.normalizeRemoteUrl(remoteUrl);
|
|
187
|
+
const request$ = this.createRemoteTranslationRequest(normalizedUrl);
|
|
188
|
+
request$
|
|
189
|
+
.pipe(takeUntil(this.destroy$$), finalize(() => {
|
|
190
|
+
this.translationsAdded$$.next();
|
|
191
|
+
}))
|
|
192
|
+
.subscribe({
|
|
193
|
+
next: remoteTranslations => {
|
|
194
|
+
if (remoteTranslations) {
|
|
195
|
+
this.remoteTranslationsList.push(remoteTranslations);
|
|
196
|
+
}
|
|
197
|
+
},
|
|
198
|
+
error: error => {
|
|
199
|
+
if (isDevMode()) {
|
|
200
|
+
console.error(`Failed to load remote translations from ${remoteUrl}:`, error);
|
|
201
|
+
}
|
|
202
|
+
},
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
fetchTranslation(remoteUrl, locale) {
|
|
206
|
+
this.validateFetchTranslationParams(remoteUrl, locale);
|
|
207
|
+
const targetUrl = locale
|
|
208
|
+
? remoteUrl.replace(LOCALE_PLACEHOLDER_REGEX, locale)
|
|
209
|
+
: remoteUrl;
|
|
210
|
+
return this.performTranslationRequest(targetUrl);
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* 获取初始语言环境
|
|
214
|
+
*/
|
|
215
|
+
getInitialLocale(options) {
|
|
216
|
+
return options?.locale || getUserLanguage();
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* 获取初始翻译列表
|
|
220
|
+
*/
|
|
221
|
+
getInitializeTranslations(options, translationList) {
|
|
222
|
+
return [options?.translations, ...(translationList || [])].filter(Boolean);
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* 加载远程翻译
|
|
226
|
+
*/
|
|
227
|
+
loadRemoteTranslations(options) {
|
|
228
|
+
if (!options?.remoteUrl)
|
|
229
|
+
return;
|
|
230
|
+
const urls = Array.isArray(options.remoteUrl)
|
|
231
|
+
? options.remoteUrl
|
|
232
|
+
: [options.remoteUrl];
|
|
233
|
+
urls.forEach(url => this.addRemoteTranslations(url));
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* 转换模板数据为 ICU 兼容格式
|
|
237
|
+
* @param data - 模板数据
|
|
238
|
+
* @returns ICU 兼容的数据对象
|
|
239
|
+
*/
|
|
240
|
+
normalizeAndConvertToIcuData(data) {
|
|
241
|
+
if (data == null) {
|
|
242
|
+
return {};
|
|
243
|
+
}
|
|
244
|
+
// 如果是纯对象,直接转换其属性
|
|
245
|
+
if (this.isPlainTemplateObject(data)) {
|
|
246
|
+
return this.convertObjectToIcuData(data);
|
|
247
|
+
}
|
|
248
|
+
// 基本类型、数组、Date等包装为 { value: data }
|
|
249
|
+
return { value: this.convertValueToIcuValue(data) };
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* 检查是否为纯模板对象(不是数组、Date等特殊对象)
|
|
253
|
+
*/
|
|
254
|
+
isPlainTemplateObject(data) {
|
|
255
|
+
return (typeof data === 'object' &&
|
|
256
|
+
data !== null &&
|
|
257
|
+
!Array.isArray(data) &&
|
|
258
|
+
!(data instanceof Date) &&
|
|
259
|
+
data.constructor === Object);
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* 转换对象的所有属性为 ICU 兼容值
|
|
263
|
+
*/
|
|
264
|
+
convertObjectToIcuData(obj) {
|
|
265
|
+
const result = {};
|
|
266
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
267
|
+
if (value != null) {
|
|
268
|
+
result[key] = this.convertValueToIcuValue(value);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
return result;
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* 将单个值转换为 ICU 兼容类型
|
|
275
|
+
* 按照 ICU MessageFormat 规范,只支持 string | number | Date
|
|
276
|
+
*/
|
|
277
|
+
convertValueToIcuValue(value) {
|
|
278
|
+
// ICU 原生支持的类型直接返回
|
|
279
|
+
if (typeof value === 'string' || typeof value === 'number') {
|
|
280
|
+
return value;
|
|
281
|
+
}
|
|
282
|
+
if (value instanceof Date) {
|
|
283
|
+
return value;
|
|
284
|
+
}
|
|
285
|
+
// 其他类型转为字符串
|
|
286
|
+
if (typeof value === 'boolean') {
|
|
287
|
+
return String(value);
|
|
288
|
+
}
|
|
289
|
+
if (Array.isArray(value)) {
|
|
290
|
+
// 简单数组转为逗号分隔的字符串
|
|
291
|
+
return value.map(item => String(item ?? '')).join(', ');
|
|
292
|
+
}
|
|
293
|
+
if (value === null) {
|
|
294
|
+
return 'null';
|
|
295
|
+
}
|
|
296
|
+
if (value === undefined) {
|
|
297
|
+
return '';
|
|
298
|
+
}
|
|
299
|
+
// 对象转为 JSON 字符串
|
|
300
|
+
if (typeof value === 'object') {
|
|
301
|
+
try {
|
|
302
|
+
return JSON.stringify(value);
|
|
127
303
|
}
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
'do not use any dot with slash for relative url which should always base from base href';
|
|
304
|
+
catch {
|
|
305
|
+
return String(value);
|
|
131
306
|
}
|
|
132
|
-
|
|
133
|
-
|
|
307
|
+
}
|
|
308
|
+
return String(value);
|
|
309
|
+
}
|
|
310
|
+
/**
|
|
311
|
+
* 处理模板错误
|
|
312
|
+
*/
|
|
313
|
+
handleTemplateError(key, error) {
|
|
314
|
+
const keyStr = typeof key === 'string' ? key : '[object]';
|
|
315
|
+
const message = `The translation key '${keyStr}' is missing the necessary parameters.`;
|
|
316
|
+
if (isDevMode()) {
|
|
317
|
+
console.error(message, error);
|
|
318
|
+
}
|
|
319
|
+
else {
|
|
320
|
+
console.warn(message, error);
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
/**
|
|
324
|
+
* 将传统的 {{ key }} 语法转换为 ICU {key} 格式
|
|
325
|
+
* 同时保持已有的 ICU 格式不变
|
|
326
|
+
* @param message - 原始消息模板
|
|
327
|
+
* @returns 转换后的 ICU 格式消息
|
|
328
|
+
*/
|
|
329
|
+
convertToIcuFormat(message) {
|
|
330
|
+
// 将 {{ key }} 转换为 {key}
|
|
331
|
+
// 支持空格:{{ key }} -> {key},但去掉内部的空格
|
|
332
|
+
return message.replace(/\{\{([^}]+)\}\}/g, (_, content) => {
|
|
333
|
+
return `{${content.trim()}}`;
|
|
334
|
+
});
|
|
335
|
+
}
|
|
336
|
+
/**
|
|
337
|
+
* 使用 ICU message format 格式化文本
|
|
338
|
+
*/
|
|
339
|
+
formatIcuMessage(message, icuData) {
|
|
340
|
+
try {
|
|
341
|
+
const messageFormat = new IntlMessageFormat(message, this.locale);
|
|
342
|
+
return messageFormat.format(icuData);
|
|
343
|
+
}
|
|
344
|
+
catch (error) {
|
|
345
|
+
if (isDevMode()) {
|
|
346
|
+
console.warn(`ICU message formatting failed for "${message}":`, error);
|
|
134
347
|
}
|
|
348
|
+
// 降级处理:返回原始消息
|
|
349
|
+
return message;
|
|
135
350
|
}
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
.pipe(takeUntil(this.destroy$$), finalize(() => {
|
|
156
|
-
this.translationsAdded$.next();
|
|
157
|
-
}))
|
|
158
|
-
.subscribe(remoteTranslations => {
|
|
159
|
-
if (!remoteTranslations) {
|
|
160
|
-
return;
|
|
351
|
+
}
|
|
352
|
+
/**
|
|
353
|
+
* 格式化数字
|
|
354
|
+
* @param value - 要格式化的数字
|
|
355
|
+
* @param options - 格式化选项
|
|
356
|
+
* @returns 格式化后的数字字符串
|
|
357
|
+
*
|
|
358
|
+
* @example
|
|
359
|
+
* formatNumber(1234.56) // "1,234.56"
|
|
360
|
+
* formatNumber(0.85, { style: 'percent' }) // "85%"
|
|
361
|
+
* formatNumber(1234.56, { style: 'currency', currency: 'CNY' }) // "¥1,234.56"
|
|
362
|
+
*/
|
|
363
|
+
formatNumber(value, options = {}) {
|
|
364
|
+
try {
|
|
365
|
+
return new Intl.NumberFormat(this.locale, options).format(value);
|
|
366
|
+
}
|
|
367
|
+
catch (error) {
|
|
368
|
+
if (isDevMode()) {
|
|
369
|
+
console.warn(`Number formatting failed for value ${value}:`, error);
|
|
161
370
|
}
|
|
162
|
-
|
|
371
|
+
return value.toString();
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
/**
|
|
375
|
+
* 格式化货币
|
|
376
|
+
* @param value - 要格式化的金额
|
|
377
|
+
* @param currency - 货币代码,默认为 CNY
|
|
378
|
+
* @param options - 其他格式化选项
|
|
379
|
+
* @returns 格式化后的货币字符串
|
|
380
|
+
*
|
|
381
|
+
* @example
|
|
382
|
+
* formatCurrency(1234.56) // en-US: "CN¥1,234.56", zh-CN: "¥1,234.56"
|
|
383
|
+
* formatCurrency(1234.56, 'USD') // en-US: "$1,234.56", zh-CN: "US$1,234.56"
|
|
384
|
+
*/
|
|
385
|
+
formatCurrency(value, currency = 'CNY', options = {}) {
|
|
386
|
+
return this.formatNumber(value, {
|
|
387
|
+
style: 'currency',
|
|
388
|
+
currency,
|
|
389
|
+
...options,
|
|
163
390
|
});
|
|
164
391
|
}
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
392
|
+
/**
|
|
393
|
+
* 格式化百分比
|
|
394
|
+
* @param value - 要格式化的值(0.85 表示 85%)
|
|
395
|
+
* @param options - 格式化选项
|
|
396
|
+
* @returns 格式化后的百分比字符串
|
|
397
|
+
*
|
|
398
|
+
* @example
|
|
399
|
+
* formatPercent(0.85) // "85%"
|
|
400
|
+
* formatPercent(0.8567, { minimumFractionDigits: 2 }) // "85.67%"
|
|
401
|
+
*/
|
|
402
|
+
formatPercent(value, options = {}) {
|
|
403
|
+
return this.formatNumber(value, {
|
|
404
|
+
style: 'percent',
|
|
405
|
+
...options,
|
|
406
|
+
});
|
|
407
|
+
}
|
|
408
|
+
/**
|
|
409
|
+
* 格式化日期
|
|
410
|
+
* @param date - 要格式化的日期
|
|
411
|
+
* @param options - Intl.DateTimeFormatOptions 格式配置
|
|
412
|
+
* @returns 格式化后的日期字符串
|
|
413
|
+
*
|
|
414
|
+
* @example
|
|
415
|
+
* formatDate(new Date()) // en-US: "01/01/2025", zh-CN: "2025/01/01"
|
|
416
|
+
* formatDate(new Date(), { dateStyle: 'full' }) // "2024年8月20日星期二"
|
|
417
|
+
* formatDate(new Date(), { year: 'numeric', month: '2-digit', day: '2-digit' }) // 根据locale格式化
|
|
418
|
+
* formatDate(new Date(), { year: 'numeric', month: 'long' }) // "2024年8月"
|
|
419
|
+
*/
|
|
420
|
+
formatDate(date, options = {
|
|
421
|
+
year: 'numeric',
|
|
422
|
+
month: '2-digit',
|
|
423
|
+
day: '2-digit',
|
|
424
|
+
}) {
|
|
425
|
+
try {
|
|
426
|
+
const dateObj = new Date(date);
|
|
427
|
+
if (isNaN(dateObj.getTime())) {
|
|
428
|
+
throw new Error('Invalid date');
|
|
429
|
+
}
|
|
430
|
+
return this.formatDateByOptions(dateObj, options);
|
|
431
|
+
}
|
|
432
|
+
catch (error) {
|
|
433
|
+
if (isDevMode()) {
|
|
434
|
+
console.warn(`Date formatting failed for date ${date}:`, error);
|
|
435
|
+
}
|
|
436
|
+
return String(date);
|
|
168
437
|
}
|
|
169
|
-
|
|
438
|
+
}
|
|
439
|
+
/**
|
|
440
|
+
* 格式化日期和时间
|
|
441
|
+
* @param date - 要格式化的日期时间
|
|
442
|
+
* @param options - Intl.DateTimeFormatOptions 格式配置
|
|
443
|
+
* @returns 格式化后的日期时间字符串
|
|
444
|
+
*
|
|
445
|
+
* @example
|
|
446
|
+
* formatDateTime(new Date()) // en-US: "01/01/2025, 14:30:00", zh-CN: "2025/01/01 14:30:00"
|
|
447
|
+
* formatDateTime(new Date(), { dateStyle: 'medium', timeStyle: 'short' }) // "2024年8月20日 14:30"
|
|
448
|
+
* formatDateTime(new Date(), { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', second: '2-digit', hour12: false }) // 根据locale格式化
|
|
449
|
+
*/
|
|
450
|
+
formatDateTime(date, options = {
|
|
451
|
+
year: 'numeric',
|
|
452
|
+
month: '2-digit',
|
|
453
|
+
day: '2-digit',
|
|
454
|
+
hour: '2-digit',
|
|
455
|
+
minute: '2-digit',
|
|
456
|
+
second: '2-digit',
|
|
457
|
+
hour12: false,
|
|
458
|
+
}) {
|
|
459
|
+
return this.formatDate(date, options);
|
|
460
|
+
}
|
|
461
|
+
formatRelativeTime(value, unitOrOptions, options = { numeric: 'auto' }) {
|
|
462
|
+
try {
|
|
463
|
+
let finalValue;
|
|
464
|
+
let finalUnit;
|
|
465
|
+
let finalOptions;
|
|
466
|
+
if (value instanceof Date) {
|
|
467
|
+
// 自动计算时间差和单位
|
|
468
|
+
const { value: calculatedValue, unit: calculatedUnit } = this.calculateRelativeTime(value);
|
|
469
|
+
finalValue = calculatedValue;
|
|
470
|
+
finalUnit = calculatedUnit;
|
|
471
|
+
finalOptions =
|
|
472
|
+
unitOrOptions || options;
|
|
473
|
+
}
|
|
474
|
+
else {
|
|
475
|
+
// 使用提供的数值和单位
|
|
476
|
+
finalValue = value;
|
|
477
|
+
finalUnit = unitOrOptions;
|
|
478
|
+
finalOptions = options;
|
|
479
|
+
}
|
|
480
|
+
return new Intl.RelativeTimeFormat(this.locale, finalOptions).format(finalValue, finalUnit);
|
|
481
|
+
}
|
|
482
|
+
catch (error) {
|
|
483
|
+
if (isDevMode()) {
|
|
484
|
+
console.warn(`Relative time formatting failed for ${value}:`, error);
|
|
485
|
+
}
|
|
486
|
+
return value instanceof Date
|
|
487
|
+
? value.toLocaleString(this.locale)
|
|
488
|
+
: `${value}`;
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
/**
|
|
492
|
+
* 根据日期计算相对时间差值和最合适的单位
|
|
493
|
+
* @param date - 目标日期
|
|
494
|
+
* @returns 包含时间差值和单位的对象
|
|
495
|
+
*/
|
|
496
|
+
calculateRelativeTime(date) {
|
|
497
|
+
const now = new Date();
|
|
498
|
+
const diffMs = date.getTime() - now.getTime();
|
|
499
|
+
const absDiffMs = Math.abs(diffMs);
|
|
500
|
+
// 时间单位阈值(毫秒)
|
|
501
|
+
const MINUTE_MS = 60 * 1000;
|
|
502
|
+
const HOUR_MS = 60 * MINUTE_MS;
|
|
503
|
+
const DAY_MS = 24 * HOUR_MS;
|
|
504
|
+
// 根据时间差选择合适的单位,最大单位为day
|
|
505
|
+
if (absDiffMs >= DAY_MS) {
|
|
506
|
+
return {
|
|
507
|
+
value: Math.round(diffMs / DAY_MS),
|
|
508
|
+
unit: 'day',
|
|
509
|
+
};
|
|
510
|
+
}
|
|
511
|
+
if (absDiffMs >= HOUR_MS) {
|
|
512
|
+
return {
|
|
513
|
+
value: Math.round(diffMs / HOUR_MS),
|
|
514
|
+
unit: 'hour',
|
|
515
|
+
};
|
|
516
|
+
}
|
|
517
|
+
if (absDiffMs >= MINUTE_MS) {
|
|
518
|
+
return {
|
|
519
|
+
value: Math.round(diffMs / MINUTE_MS),
|
|
520
|
+
unit: 'minute',
|
|
521
|
+
};
|
|
522
|
+
}
|
|
523
|
+
return {
|
|
524
|
+
value: Math.round(diffMs / 1000),
|
|
525
|
+
unit: 'second',
|
|
526
|
+
};
|
|
527
|
+
}
|
|
528
|
+
/**
|
|
529
|
+
* 根据日期格式配置格式化日期
|
|
530
|
+
* 使用标准 Intl.DateTimeFormatOptions 确保格式可预测性
|
|
531
|
+
*/
|
|
532
|
+
formatDateByOptions(date, options) {
|
|
533
|
+
try {
|
|
534
|
+
return new Intl.DateTimeFormat(this.locale, options).format(date);
|
|
535
|
+
}
|
|
536
|
+
catch (error) {
|
|
537
|
+
if (isDevMode()) {
|
|
538
|
+
console.warn(`Date formatting failed:`, error);
|
|
539
|
+
}
|
|
540
|
+
return date.toISOString();
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
/**
|
|
544
|
+
* 通过字符串键获取翻译
|
|
545
|
+
*/
|
|
546
|
+
getTranslationByKey(key) {
|
|
547
|
+
return this.resolveTranslation(key);
|
|
548
|
+
}
|
|
549
|
+
/**
|
|
550
|
+
* 通过翻译对象获取翻译值
|
|
551
|
+
*/
|
|
552
|
+
getTranslationByObject(translationObj) {
|
|
553
|
+
return this.getTranslationValue(translationObj, this.locale);
|
|
554
|
+
}
|
|
555
|
+
/**
|
|
556
|
+
* 处理无效语言环境
|
|
557
|
+
*/
|
|
558
|
+
handleInvalidLocale() {
|
|
559
|
+
if (isDevMode()) {
|
|
560
|
+
throw new TypeError('`locales` has not been initialized correctly');
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
/**
|
|
564
|
+
* 验证语言环境是否有效
|
|
565
|
+
*/
|
|
566
|
+
isValidLocale(locale) {
|
|
567
|
+
return this.options.locales.includes(locale);
|
|
568
|
+
}
|
|
569
|
+
/**
|
|
570
|
+
* 检查重复翻译(开发模式)
|
|
571
|
+
*/
|
|
572
|
+
checkForDuplicateTranslations(newTranslations) {
|
|
573
|
+
for (const existingTranslations of this.translationsList) {
|
|
574
|
+
Object.keys(newTranslations).forEach(locale => {
|
|
575
|
+
if (existingTranslations[locale]) {
|
|
576
|
+
this.compareTranslationKeys(locale, newTranslations[locale], existingTranslations[locale]);
|
|
577
|
+
}
|
|
578
|
+
});
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
/**
|
|
582
|
+
* 标准化远程URL
|
|
583
|
+
*/
|
|
584
|
+
normalizeRemoteUrl(remoteUrl) {
|
|
585
|
+
remoteUrl = this.cleanUrl(remoteUrl);
|
|
586
|
+
const isAbsolute = isAbsoluteUrl(remoteUrl);
|
|
170
587
|
const isApiGateWayRequest = remoteUrl.startsWith(API_GATEWAY);
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
588
|
+
// 开发模式下进行URL验证
|
|
589
|
+
if (isDevMode()) {
|
|
590
|
+
this.validateRemoteUrl(remoteUrl, isAbsolute);
|
|
591
|
+
}
|
|
592
|
+
// 相对URL转换为绝对URL
|
|
593
|
+
if (!isAbsolute && !isApiGateWayRequest) {
|
|
594
|
+
const baseUrl = this.baseHref.endsWith('/')
|
|
595
|
+
? this.baseHref
|
|
596
|
+
: `${this.baseHref}/`;
|
|
597
|
+
return `${baseUrl}${remoteUrl}`;
|
|
598
|
+
}
|
|
599
|
+
return remoteUrl;
|
|
600
|
+
}
|
|
601
|
+
/**
|
|
602
|
+
* 清理URL(移除hash片段)
|
|
603
|
+
*/
|
|
604
|
+
cleanUrl(url) {
|
|
605
|
+
return head(url.split(/#/)) || url;
|
|
606
|
+
}
|
|
607
|
+
/**
|
|
608
|
+
* 验证远程URL(开发模式)
|
|
609
|
+
*/
|
|
610
|
+
validateRemoteUrl(remoteUrl, isAbsolute) {
|
|
611
|
+
if (!isAbsolute && (!this.baseHref || !isAbsoluteUrl(this.baseHref))) {
|
|
612
|
+
throw new TypeError('absolute base href is required for relative remote url');
|
|
613
|
+
}
|
|
614
|
+
if (remoteUrl.split('?')[0].includes('./')) {
|
|
615
|
+
throw new TypeError('do not use any dot with slash for relative url which should always base from base href');
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
/**
|
|
619
|
+
* 创建远程翻译请求
|
|
620
|
+
*/
|
|
621
|
+
createRemoteTranslationRequest(normalizedUrl) {
|
|
622
|
+
if (LOCALE_PLACEHOLDER_REGEX.test(normalizedUrl)) {
|
|
623
|
+
return this.createMultiLocaleRequest(normalizedUrl);
|
|
624
|
+
}
|
|
625
|
+
return this.createSingleLocaleRequest(normalizedUrl);
|
|
626
|
+
}
|
|
627
|
+
/**
|
|
628
|
+
* 创建多语言请求
|
|
629
|
+
*/
|
|
630
|
+
createMultiLocaleRequest(urlTemplate) {
|
|
631
|
+
const requests = this.options.locales.map(locale => this.fetchTranslation(urlTemplate, locale).pipe(catchError(error => {
|
|
632
|
+
if (this.options.loose) {
|
|
633
|
+
const looseLocale = this.extractLooseLocale(locale);
|
|
634
|
+
if (locale !== looseLocale &&
|
|
635
|
+
!this.options.locales.includes(looseLocale)) {
|
|
636
|
+
return this.fetchTranslation(urlTemplate, looseLocale);
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
return isDevMode() ? throwError(() => error) : EMPTY;
|
|
640
|
+
}), filter(isPlainObject), map((translation) => ({ [locale]: translation }))));
|
|
641
|
+
return forkJoin(requests).pipe(map(results => results.reduce((acc, curr) => Object.assign(acc, curr), {})));
|
|
642
|
+
}
|
|
643
|
+
/**
|
|
644
|
+
* 创建单语言请求
|
|
645
|
+
*/
|
|
646
|
+
createSingleLocaleRequest(url) {
|
|
647
|
+
return this.performTranslationRequest(url).pipe(catchError(error => (isDevMode() ? throwError(() => error) : EMPTY)));
|
|
648
|
+
}
|
|
649
|
+
/**
|
|
650
|
+
* 执行翻译请求
|
|
651
|
+
*/
|
|
652
|
+
performTranslationRequest(url) {
|
|
653
|
+
const isJSON = url.endsWith('.json');
|
|
654
|
+
const isApiGateWayRequest = url.startsWith(API_GATEWAY);
|
|
174
655
|
const responseType = isJSON ? 'json' : 'text';
|
|
175
656
|
if (isApiGateWayRequest) {
|
|
176
657
|
return this.http
|
|
177
658
|
.request('GET', url, { responseType })
|
|
178
659
|
.pipe(map(body => (isJSON ? body : parse(body))));
|
|
179
660
|
}
|
|
180
|
-
return ajax({
|
|
181
|
-
url,
|
|
182
|
-
responseType,
|
|
183
|
-
}).pipe(map(({ response }) => (isJSON ? response : parse(response))));
|
|
661
|
+
return ajax({ url, responseType }).pipe(map(({ response }) => (isJSON ? response : parse(response))));
|
|
184
662
|
}
|
|
185
|
-
|
|
186
|
-
|
|
663
|
+
/**
|
|
664
|
+
* 验证fetchTranslation参数
|
|
665
|
+
*/
|
|
666
|
+
validateFetchTranslationParams(remoteUrl, locale) {
|
|
667
|
+
if (isDevMode() && LOCALE_PLACEHOLDER_REGEX.test(remoteUrl) && !locale) {
|
|
668
|
+
throw new TypeError('`locale` is required since the provided remote url contains locale placeholder');
|
|
669
|
+
}
|
|
187
670
|
}
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
671
|
+
/**
|
|
672
|
+
* 解析翻译文本
|
|
673
|
+
*/
|
|
674
|
+
resolveTranslation(key, locale = this.locale) {
|
|
675
|
+
// 优先从远程翻译中查找
|
|
676
|
+
let value = this.searchInTranslationsList(key, locale, this.remoteTranslationsList);
|
|
677
|
+
// 如果远程翻译中没有找到(undefined),则从本地翻译中查找
|
|
678
|
+
if (value === undefined) {
|
|
679
|
+
value = this.searchInTranslationsList(key, locale, this.translationsList);
|
|
680
|
+
}
|
|
681
|
+
return value ?? key;
|
|
682
|
+
}
|
|
683
|
+
/**
|
|
684
|
+
* 在翻译列表中搜索
|
|
685
|
+
*/
|
|
686
|
+
searchInTranslationsList(key, locale, translationsList) {
|
|
687
|
+
if (!translationsList || translationsList.length === 0) {
|
|
688
|
+
return undefined;
|
|
191
689
|
}
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
const
|
|
195
|
-
value
|
|
196
|
-
|
|
197
|
-
? Object.entries(source).find(([key]) => locale === this._getLooseLocale(key))?.[1]
|
|
198
|
-
: source[looseLocale];
|
|
199
|
-
}
|
|
200
|
-
if (value == null && locale !== this.options.fallbackLocale) {
|
|
201
|
-
return this._getValue(source, this.options.fallbackLocale);
|
|
202
|
-
}
|
|
203
|
-
return value;
|
|
204
|
-
}
|
|
205
|
-
_getWithFallback(key, locale = this.locale, translations) {
|
|
206
|
-
const value = get(this._getValue(translations, locale), key);
|
|
207
|
-
if (value != null) {
|
|
208
|
-
if (typeof value === 'object' &&
|
|
209
|
-
isDevMode() &&
|
|
210
|
-
typeof get(value, Symbol.toPrimitive) !== 'function') {
|
|
211
|
-
console.warn(`The translation for locale: \`${locale}\` and key:\`${key}\` is an object, which could be unexpected`);
|
|
690
|
+
// 从后往前遍历(后加入的优先级更高)
|
|
691
|
+
for (let i = translationsList.length - 1; i >= 0; i--) {
|
|
692
|
+
const value = this.searchInTranslations(key, locale, translationsList[i]);
|
|
693
|
+
if (value !== undefined) {
|
|
694
|
+
return value;
|
|
212
695
|
}
|
|
213
|
-
return String(value);
|
|
214
696
|
}
|
|
697
|
+
return undefined;
|
|
698
|
+
}
|
|
699
|
+
/**
|
|
700
|
+
* 在单个翻译对象中搜索
|
|
701
|
+
*/
|
|
702
|
+
searchInTranslations(key, locale, translations) {
|
|
703
|
+
const translationValue = this.getTranslationValue(translations, locale);
|
|
704
|
+
// 如果没有获取到翻译值对象(getTranslationValue已经处理了loose和fallback),直接返回
|
|
705
|
+
if (translationValue === undefined) {
|
|
706
|
+
return undefined;
|
|
707
|
+
}
|
|
708
|
+
// 获取翻译值,支持扁平和嵌套两种结构
|
|
709
|
+
const value = this.getTranslationFromSource(translationValue, key);
|
|
710
|
+
// 如果找到值(包括null值),则处理并返回
|
|
711
|
+
if (value !== undefined) {
|
|
712
|
+
this.validateTranslationValue(value, locale, key);
|
|
713
|
+
// null值转换为字符串'null',其他值正常转换
|
|
714
|
+
return value === null ? 'null' : String(value);
|
|
715
|
+
}
|
|
716
|
+
// 如果在当前语言的翻译值中找不到key,但这不是fallback语言,尝试fallback
|
|
215
717
|
if (locale !== this.options.fallbackLocale) {
|
|
216
|
-
|
|
718
|
+
const fallbackTranslationValue = this.getTranslationValue(translations, this.options.fallbackLocale);
|
|
719
|
+
if (fallbackTranslationValue !== undefined) {
|
|
720
|
+
const fallbackValue = this.getTranslationFromSource(fallbackTranslationValue, key);
|
|
721
|
+
if (fallbackValue !== undefined) {
|
|
722
|
+
this.validateTranslationValue(fallbackValue, this.options.fallbackLocale, key);
|
|
723
|
+
return fallbackValue === null ? 'null' : String(fallbackValue);
|
|
724
|
+
}
|
|
725
|
+
}
|
|
217
726
|
}
|
|
727
|
+
return undefined;
|
|
218
728
|
}
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
729
|
+
/**
|
|
730
|
+
* 从翻译源获取翻译值,支持扁平和嵌套两种结构
|
|
731
|
+
* @param source - 翻译源对象
|
|
732
|
+
* @param key - 翻译键(如 'a.b.c')
|
|
733
|
+
* @returns 翻译值或undefined
|
|
734
|
+
*/
|
|
735
|
+
getTranslationFromSource(source, key) {
|
|
736
|
+
if (!source || typeof source !== 'object') {
|
|
737
|
+
return undefined;
|
|
222
738
|
}
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
739
|
+
// 1. 优先尝试扁平结构:直接查找完整的键 'a.b.c'
|
|
740
|
+
if (Object.prototype.hasOwnProperty.call(source, key)) {
|
|
741
|
+
return source[key];
|
|
742
|
+
}
|
|
743
|
+
// 2. 再尝试嵌套结构:使用lodash.get按路径查找 a.b.c
|
|
744
|
+
const nestedValue = get(source, key);
|
|
745
|
+
if (nestedValue !== undefined) {
|
|
746
|
+
return nestedValue;
|
|
747
|
+
}
|
|
748
|
+
return undefined;
|
|
749
|
+
}
|
|
750
|
+
/**
|
|
751
|
+
* 获取指定语言的翻译值(处理loose模式和fallback逻辑)
|
|
752
|
+
*/
|
|
753
|
+
getTranslationValue(source, locale = this.locale) {
|
|
754
|
+
if (!source) {
|
|
755
|
+
return undefined;
|
|
756
|
+
}
|
|
757
|
+
// 1. 首先检查精确匹配的键是否存在
|
|
758
|
+
if (Object.prototype.hasOwnProperty.call(source, locale)) {
|
|
759
|
+
return source[locale]; // 返回实际值,可能是null、undefined或其他值
|
|
760
|
+
}
|
|
761
|
+
// 2. 如果启用了宽松模式,尝试宽松匹配
|
|
762
|
+
if (this.options.loose) {
|
|
763
|
+
const looseValue = this.getLooseTranslationValue(source, locale);
|
|
764
|
+
if (looseValue !== undefined) {
|
|
765
|
+
return looseValue;
|
|
227
766
|
}
|
|
228
767
|
}
|
|
768
|
+
// 3. 如果当前语言不是fallback语言,尝试fallback语言
|
|
769
|
+
if (locale !== this.options.fallbackLocale) {
|
|
770
|
+
// 首先检查fallback语言的精确匹配
|
|
771
|
+
if (Object.prototype.hasOwnProperty.call(source, this.options.fallbackLocale)) {
|
|
772
|
+
return source[this.options.fallbackLocale];
|
|
773
|
+
}
|
|
774
|
+
// 如果启用了宽松模式,也对fallback语言进行宽松匹配
|
|
775
|
+
if (this.options.loose) {
|
|
776
|
+
const fallbackLooseValue = this.getLooseTranslationValue(source, this.options.fallbackLocale);
|
|
777
|
+
if (fallbackLooseValue !== undefined) {
|
|
778
|
+
return fallbackLooseValue;
|
|
779
|
+
}
|
|
780
|
+
}
|
|
781
|
+
}
|
|
782
|
+
return undefined;
|
|
229
783
|
}
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
784
|
+
/**
|
|
785
|
+
* 宽松模式下获取翻译值
|
|
786
|
+
*/
|
|
787
|
+
getLooseTranslationValue(source, locale) {
|
|
788
|
+
const looseLocale = this.extractLooseLocale(locale);
|
|
789
|
+
if (locale === looseLocale) {
|
|
790
|
+
// 寻找匹配的宽松语言
|
|
791
|
+
const matchedEntry = Object.entries(source).find(([key]) => looseLocale === this.extractLooseLocale(key));
|
|
792
|
+
return matchedEntry?.[1];
|
|
234
793
|
}
|
|
235
|
-
|
|
236
|
-
|
|
794
|
+
// 检查宽松语言键是否存在
|
|
795
|
+
if (Object.prototype.hasOwnProperty.call(source, looseLocale)) {
|
|
796
|
+
return source[looseLocale];
|
|
237
797
|
}
|
|
238
|
-
return
|
|
798
|
+
return undefined;
|
|
239
799
|
}
|
|
240
|
-
|
|
800
|
+
/**
|
|
801
|
+
* 提取宽松语言代码(如:zh-CN -> zh)
|
|
802
|
+
*/
|
|
803
|
+
extractLooseLocale(locale) {
|
|
804
|
+
return head(locale.split(/[_-]/)) || locale;
|
|
805
|
+
}
|
|
806
|
+
/**
|
|
807
|
+
* 验证翻译值(开发模式)
|
|
808
|
+
*/
|
|
809
|
+
validateTranslationValue(value, locale, key) {
|
|
810
|
+
if (isDevMode() &&
|
|
811
|
+
typeof value === 'object' &&
|
|
812
|
+
typeof get(value, Symbol.toPrimitive) !== 'function') {
|
|
813
|
+
console.warn(`The translation for locale: \`${locale}\` and key:\`${key}\` is an object, which could be unexpected`);
|
|
814
|
+
}
|
|
815
|
+
}
|
|
816
|
+
/**
|
|
817
|
+
* 比较翻译键(开发模式下检查重复)
|
|
818
|
+
*/
|
|
819
|
+
compareTranslationKeys(locale, translation, prevTranslation, path = []) {
|
|
241
820
|
if (translation == null || prevTranslation == null) {
|
|
242
821
|
return;
|
|
243
822
|
}
|
|
@@ -249,7 +828,7 @@ export class TranslateService {
|
|
|
249
828
|
const valueIsPlainObject = isPlainObject(value);
|
|
250
829
|
const prevValueIsPlainObject = isPlainObject(prevValue);
|
|
251
830
|
if (valueIsPlainObject && prevValueIsPlainObject) {
|
|
252
|
-
this.
|
|
831
|
+
this.compareTranslationKeys(locale, value, prevValue, [...path, key]);
|
|
253
832
|
return;
|
|
254
833
|
}
|
|
255
834
|
if (!valueIsPlainObject && !prevValueIsPlainObject) {
|
|
@@ -258,7 +837,7 @@ export class TranslateService {
|
|
|
258
837
|
console.warn(`The customized translation for locale: \`${locale}\` and path: \`${outputPath}\` is duplicated with the other translation, please remove it in your translation file.`);
|
|
259
838
|
}
|
|
260
839
|
else {
|
|
261
|
-
console.warn(`Two keys that the locale is \`${locale}\` and the path is \`${outputPath}\` are same,
|
|
840
|
+
console.warn(`Two keys that the locale is \`${locale}\` and the path is \`${outputPath}\` are same, but their values are not equal, please remove one of them or change one of the keys.`);
|
|
262
841
|
}
|
|
263
842
|
}
|
|
264
843
|
});
|
|
@@ -287,4 +866,4 @@ __decorate([
|
|
|
287
866
|
type: Inject,
|
|
288
867
|
args: [TRANSLATIONS]
|
|
289
868
|
}] }], { locale$: [] }); })();
|
|
290
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhbnNsYXRlLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9saWJzL2NvbW1vbi9zcmMvdHJhbnNsYXRlL3RyYW5zbGF0ZS5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTs7O0dBR0c7QUFFSCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDbEQsT0FBTyxFQUNMLE1BQU0sRUFDTixVQUFVLEVBRVYsUUFBUSxFQUNSLFNBQVMsR0FDVixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxhQUFhLEVBQUUsUUFBUSxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBQy9ELE9BQU8sRUFDTCxLQUFLLEVBQ0wsVUFBVSxFQUNWLE9BQU8sRUFDUCxRQUFRLEVBQ1IsVUFBVSxFQUNWLFVBQVUsRUFDVixNQUFNLEVBQ04sUUFBUSxFQUNSLEdBQUcsRUFDSCxTQUFTLEdBQ1YsTUFBTSxNQUFNLENBQUM7QUFDZCxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBRWpDLE9BQU8sRUFBRSxXQUFXLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUM1RSxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDckQsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQ3JELE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUMzRCxPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFFM0MsT0FBTyxFQUNMLGlCQUFpQixFQUNqQix3QkFBd0IsRUFDeEIsY0FBYyxHQUNmLE1BQU0sYUFBYSxDQUFDO0FBQ3JCLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxZQUFZLEVBQUUsTUFBTSxVQUFVLENBQUM7OztBQVUzRCxNQUFNLE9BQU8sZ0JBQWdCO0lB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Z0IsbUJBREgsTUFBTTs7QUFhckI7SUFEUixlQUFlLEVBQUU7OEJBQ0EsVUFBVTtpREFBUztpRkFaMUIsZ0JBQWdCO2NBRDVCLFVBQVU7ZUFBQyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUU7O3NCQXlCN0IsTUFBTTt1QkFBQyxlQUFlOztzQkFFdEIsUUFBUTs7c0JBQ1IsTUFBTTt1QkFBQyxpQkFBaUI7O3NCQUV4QixRQUFROztzQkFBSSxNQUFNO3VCQUFDLFlBQVk7cUJBakJ6QixPQUFPIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAcGFja2FnZURvY3VtZW50YXRpb25cbiAqIEBtb2R1bGUgdHJhbnNsYXRlXG4gKi9cblxuaW1wb3J0IHsgSHR0cENsaWVudCB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbi9odHRwJztcbmltcG9ydCB7XG4gIEluamVjdCxcbiAgSW5qZWN0YWJsZSxcbiAgT25EZXN0cm95LFxuICBPcHRpb25hbCxcbiAgaXNEZXZNb2RlLFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IGdldCwgaGVhZCwgaXNQbGFpbk9iamVjdCwgdGVtcGxhdGUgfSBmcm9tICdsb2Rhc2gtZXMnO1xuaW1wb3J0IHtcbiAgRU1QVFksXG4gIE9ic2VydmFibGUsXG4gIFN1YmplY3QsXG4gIGZvcmtKb2luLFxuICB0aHJvd0Vycm9yLFxuICBjYXRjaEVycm9yLFxuICBmaWx0ZXIsXG4gIGZpbmFsaXplLFxuICBtYXAsXG4gIHRha2VVbnRpbCxcbn0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBhamF4IH0gZnJvbSAncnhqcy9hamF4JztcblxuaW1wb3J0IHsgQVBJX0dBVEVXQVksIFRFTVBMQVRFX09QVElPTlMgfSBmcm9tICcuLi9jb3JlL2NvbnN0YW50cy9jb25zdGFudHMnO1xuaW1wb3J0IHsgVE9LRU5fQkFTRV9IUkVGIH0gZnJvbSAnLi4vY29yZS9wdWJsaWMtYXBpJztcbmltcG9ydCB7IGlzQWJzb2x1dGVVcmwgfSBmcm9tICcuLi9jb3JlL3V0aWxzL2NvbW1vbic7XG5pbXBvcnQgeyBPYnNlcnZhYmxlSW5wdXQgfSBmcm9tICcuLi9jb3JlL3V0aWxzL2RlY29yYXRvcnMnO1xuaW1wb3J0IHsgcGFyc2UgfSBmcm9tICcuLi9jb3JlL3V0aWxzL3lhbWwnO1xuXG5pbXBvcnQge1xuICBGQUxMQkFDS19MQU5HVUFHRSxcbiAgTE9DQUxFX1BMQUNFSE9MREVSX1JFR0VYLFxuICBMT0NBTEVfU1RPUkFHRSxcbn0gZnJvbSAnLi9jb25zdGFudHMnO1xuaW1wb3J0IHsgVFJBTlNMQVRFX09QVElPTlMsIFRSQU5TTEFUSU9OUyB9IGZyb20gJy4vdG9rZW5zJztcbmltcG9ydCB7XG4gIFRyYW5zbGF0ZUtleSxcbiAgVHJhbnNsYXRlT3B0aW9ucyxcbiAgVHJhbnNsYXRpb24sXG4gIFRyYW5zbGF0aW9uVmFsdWUsXG4gIFRyYW5zbGF0aW9ucyxcbn0gZnJvbSAnLi90eXBlcyc7XG5cbkBJbmplY3RhYmxlKHsgcHJvdmlkZWRJbjogJ3Jvb3QnIH0pXG5leHBvcnQgY2xhc3MgVHJhbnNsYXRlU2VydmljZSBpbXBsZW1lbnRzIE9uRGVzdHJveSB7XG4gIHJlYWRvbmx5IHRyYW5zbGF0aW9uc0FkZGVkJCA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XG5cbiAgcHJpdmF0ZSByZWFkb25seSBkZXN0cm95JCQgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xuXG4gIHJlYWRvbmx5IHRyYW5zbGF0aW9uc0xpc3Q6IEFycmF5PFJlYWRvbmx5PFRyYW5zbGF0aW9ucz4+ID0gW107XG4gIHJlYWRvbmx5IHJlbW90ZVRyYW5zbGF0aW9uc0xpc3Q6IEFycmF5PFJlYWRvbmx5PFRyYW5zbGF0aW9ucz4+ID0gW107XG4gIHJlYWRvbmx5IG9wdGlvbnM6IFRyYW5zbGF0ZU9wdGlvbnM7XG5cbiAgbG9jYWxlOiBzdHJpbmc7XG5cbiAgQE9ic2VydmFibGVJbnB1dCgpXG4gIHJlYWRvbmx5IGxvY2FsZSQ6IE9ic2VydmFibGU8c3RyaW5nPjtcblxuICBnZXQgbG9jYWxlcygpIHtcbiAgICByZXR1cm4gdGhpcy5vcHRpb25zLmxvY2FsZXM7XG4gIH1cblxuICBnZXQgZmFsbGJhY2tMb2NhbGUoKSB7XG4gICAgcmV0dXJuIHRoaXMub3B0aW9ucy5mYWxsYmFja0xvY2FsZTtcbiAgfVxuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgcmVhZG9ubHkgaHR0cDogSHR0cENsaWVudCxcbiAgICBASW5qZWN0KFRPS0VOX0JBU0VfSFJFRilcbiAgICBwcml2YXRlIHJlYWRvbmx5IGJhc2VIcmVmOiBzdHJpbmcsXG4gICAgQE9wdGlvbmFsKClcbiAgICBASW5qZWN0KFRSQU5TTEFURV9PUFRJT05TKVxuICAgIG9wdGlvbnM6IFRyYW5zbGF0ZU9wdGlvbnMsXG4gICAgQE9wdGlvbmFsKCkgQEluamVjdChUUkFOU0xBVElPTlMpIHRyYW5zbGF0aW9uTGlzdDogVHJhbnNsYXRpb25zW10sXG4gICkge1xuICAgIHRoaXMubG9jYWxlID0gb3B0aW9ucz8ubG9jYWxlIHx8IG5hdmlnYXRvci5sYW5ndWFnZTtcbiAgICB0aGlzLm9wdGlvbnMgPSB7XG4gICAgICBsb2NhbGVzOiBbdGhpcy5sb2NhbGVdLFxuICAgICAgZmFsbGJhY2tMb2NhbGU6IEZBTExCQUNLX0xBTkdVQUdFLFxuICAgICAgLi4ub3B0aW9ucyxcbiAgICB9O1xuXG4gICAgdGhpcy50cmFuc2xhdGlvbnNMaXN0ID0gW1xuICAgICAgb3B0aW9ucz8udHJhbnNsYXRpb25zLFxuICAgICAgLi4uKHRyYW5zbGF0aW9uTGlzdCB8fCBbXSksXG4gICAgXS5maWx0ZXIoQm9vbGVhbik7XG5cbiAgICBpZiAob3B0aW9ucz8ucmVtb3RlVXJsKSB7XG4gICAgICBpZiAoQXJyYXkuaXNBcnJheShvcHRpb25zLnJlbW90ZVVybCkpIHtcbiAgICAgICAgb3B0aW9ucy5yZW1vdGVVcmwuZm9yRWFjaCh1cmwgPT4gdGhpcy5hZGRSZW1vdGVUcmFuc2xhdGlvbnModXJsKSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmFkZFJlbW90ZVRyYW5zbGF0aW9ucyhvcHRpb25zLnJlbW90ZVVybCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgbmdPbkRlc3Ryb3koKSB7XG4gICAgdGhpcy5kZXN0cm95JCQubmV4dCgpO1xuICAgIHRoaXMuZGVzdHJveSQkLmNvbXBsZXRlKCk7XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIGtleSAtIOe/u+ivkWtleVxuICAgKiBAcGFyYW0gZGF0YSAtIOagueaNrue/u+ivkeS4iuS4i+aWh+aVsOaNruiOt+WPlue/u+ivkeWGheWuue+8jOe/u+ivkemhueS4jeWtmOWcqOebtOaOpei/lOWbniBrZXkg5paH5pysXG4gICAqIEBwYXJhbSBpZ25vcmVOb25FeGlzdCAtIOW8gOWPkeeOr+Wig+aYr+WQpuW/veinhuS4jeWtmOWcqOeahOe/u+ivkemhuVxuICAgKi9cbiAgZ2V0KGtleTogVHJhbnNsYXRlS2V5LCBkYXRhPzogdW5rbm93bikge1xuICAgIGNvbnN0IHRyYW5zbGF0aW9uID0gdGhpcy5nZXRSYXcoa2V5KTtcbiAgICBpZiAoZGF0YSAhPSBudWxsICYmIHR5cGVvZiBkYXRhICE9PSAnb2JqZWN0Jykge1xuICAgICAgZGF0YSA9IFtkYXRhXTtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiB0ZW1wbGF0ZSh0cmFuc2xhdGlvbiwgVEVNUExBVEVfT1BUSU9OUykoZGF0YSBhcyBvYmplY3QpO1xuICAgIH0gY2F0Y2gge1xuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnNvbGVcbiAgICAgIGNvbnNvbGVbaXNEZXZNb2RlKCkgPyAnZXJyb3InIDogJ3dhcm4nXShcbiAgICAgICAgYFRoZSB0cmFuc2xhdGlvbiBrZXkgJyR7a2V5fScgaXMgbWlzc2luZyB0aGUgbmVjZXNzYXJ5IHBhcmFtZXRlcnMuYCxcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIOebtOaOpei/lOWbnue/u+ivkeaWh+acrOaooeadv1xuICAgKiBAcGFyYW0ga2V5IC0g57+76K+Ra2V5XG4gICAqIEBwYXJhbSBpZ25vcmVOb25FeGlzdCAtIOW8gOWPkeeOr+Wig+aYr+WQpuW/veinhuS4jeWtmOWcqOeahOe/u+ivkemhuVxuICAgKi9cbiAgZ2V0UmF3KGtleTogVHJhbnNsYXRlS2V5KSB7XG4gICAgcmV0dXJuIHR5cGVvZiBrZXkgPT09ICdzdHJpbmcnXG4gICAgICA/IHRoaXMuX2dldChrZXkpXG4gICAgICA6ICh0aGlzLl9nZXRWYWx1ZShrZXkpIGFzIHN0cmluZyk7XG4gIH1cblxuICAvKipcbiAgICog5qC55o2uIGBsb2NhbGVzYCDlvqrnjq/liIfmjaLlvZPliY3ljLrln5/orr7nva5cbiAgICovXG4gIHRvZ2dsZUxvY2FsZSgpIHtcbiAgICBjb25zdCBpbmRleCA9IHRoaXMub3B0aW9ucy5sb2NhbGVzLmluZGV4T2YodGhpcy5sb2NhbGUpO1xuICAgIGlmIChpbmRleCA9PT0gLTEpIHtcbiAgICAgIGlmIChpc0Rldk1vZGUoKSkge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdgbG9jYWxlc2AgaGFzIG5vdCBiZWVuIGluaXRpYWxpemVkIGNvcnJlY3RseScpO1xuICAgICAgfVxuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBuZXh0TG9jYWxlID1cbiAgICAgIHRoaXMub3B0aW9ucy5sb2NhbGVzW1xuICAgICAgICBpbmRleCA9PT0gdGhpcy5vcHRpb25zLmxvY2FsZXMubGVuZ3RoIC0gMSA/IDAgOiBpbmRleCArIDFcbiAgICAgIF07XG5cbiAgICBpZiAoIW5leHRMb2NhbGUgfHwgdGhpcy5sb2NhbGUgPT09IG5leHRMb2NhbGUpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLnNldExvY2FsZShuZXh0TG9jYWxlKTtcbiAgfVxuXG4gIHNldExvY2FsZShsb2NhbGU6IHN0cmluZykge1xuICAgIGxvY2FsU3RvcmFnZS5zZXRJdGVtKExPQ0FMRV9TVE9SQUdFLCBsb2NhbGUpO1xuICAgIHRoaXMubG9jYWxlID0gbG9jYWxlO1xuICB9XG5cbiAgLyoqXG4gICAqIOaJi+WKqOa3u+WKoOivreiogOWMhVxuICAgKi9cbiAgYWRkVHJhbnNsYXRpb25zKHRyYW5zbGF0aW9uczogVHJhbnNsYXRpb25zKSB7XG4gICAgdGhpcy50cmFuc2xhdGlvbnNMaXN0LnVuc2hpZnQoT2JqZWN0LmZyZWV6ZSh0cmFuc2xhdGlvbnMpKTtcbiAgICB0aGlzLnRyYW5zbGF0aW9uc0FkZGVkJC5uZXh0KCk7XG4gIH1cblxuICAvKipcbiAgICog5omL5Yqo5re75Yqg6K+t6KiA5YyFXG4gICAqL1xuICBhZGRSZW1vdGVUcmFuc2xhdGlvbnMocmVtb3RlVXJsOiBzdHJpbmcpIHtcbiAgICBpZiAoIXJlbW90ZVVybCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICByZW1vdGVVcmwgPSBoZWFkKHJlbW90ZVVybC5zcGxpdCgvIy8pKTtcbiAgICBjb25zdCBpc0Fic29sdXRlID0gaXNBYnNvbHV0ZVVybChyZW1vdGVVcmwpO1xuICAgIGNvbnN0IGlzQXBpR2F0ZVdheVJlcXVlc3QgPSByZW1vdGVVcmwuc3RhcnRzV2l0aChBUElfR0FURVdBWSk7XG4gICAgaWYgKGlzRGV2TW9kZSgpKSB7XG4gICAgICBsZXQgZXJyb3JNZXNzYWdlOiBzdHJpbmc7XG4gICAgICBpZiAoIWlzQWJzb2x1dGUgJiYgKCF0aGlzLmJhc2VIcmVmIHx8ICFpc0Fic29sdXRlVXJsKHRoaXMuYmFzZUhyZWYpKSkge1xuICAgICAgICBlcnJvck1lc3NhZ2UgPSAnYWJzb2x1dGUgYmFzZSBocmVmIGlzIHJlcXVpcmVkIGZvciByZWxhdGl2ZSByZW1vdGUgdXJsJztcbiAgICAgIH0gZWxzZSBpZiAocmVtb3RlVXJsLnNwbGl0KCc/JylbMF0uaW5jbHVkZXMoJy4vJykpIHtcbiAgICAgICAgZXJyb3JNZXNzYWdlID1cbiAgICAgICAgICAnZG8gbm90IHVzZSBhbnkgZG90IHdpdGggc2xhc2ggZm9yIHJlbGF0aXZlIHVybCB3aGljaCBzaG91bGQgYWx3YXlzIGJhc2UgZnJvbSBiYXNlIGhyZWYnO1xuICAgICAgfVxuICAgICAgaWYgKGVycm9yTWVzc2FnZSkge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGVycm9yTWVzc2FnZSk7XG4gICAgICB9XG4gICAgfVxuICAgIGlmICghaXNBYnNvbHV0ZSAmJiAhaXNBcGlHYXRlV2F5UmVxdWVzdCkge1xuICAgICAgcmVtb3RlVXJsID1cbiAgICAgICAgKHRoaXMuYmFzZUhyZWYuZW5kc1dpdGgoJy8nKSA/IHRoaXMuYmFzZUhyZWYgOiB0aGlzLmJhc2VIcmVmICsgJy8nKSArXG4gICAgICAgIHJlbW90ZVVybDtcbiAgICB9XG4gICAgKExPQ0FMRV9QTEFDRUhPTERFUl9SRUdFWC50ZXN0KHJlbW90ZVVybClcbiAgICAgID8gZm9ya0pvaW4oXG4gICAgICAgICAgdGhpcy5vcHRpb25zLmxvY2FsZXMubWFwKGxvY2FsZSA9PlxuICAgICAgICAgICAgdGhpcy5mZXRjaFRyYW5zbGF0aW9uKHJlbW90ZVVybCwgbG9jYWxlKS5waXBlKFxuICAgICAgICAgICAgICBjYXRjaEVycm9yKGVycm9yID0+IHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5vcHRpb25zLmxvb3NlKSB7XG4gICAgICAgICAgICAgICAgICBjb25zdCBsb29zZUxvY2FsZSA9IHRoaXMuX2dldExvb3NlTG9jYWxlKGxvY2FsZSk7XG4gICAgICAgICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICAgICAgIGxvY2FsZSAhPT0gbG9vc2VMb2NhbGUgJiZcbiAgICAgICAgICAgICAgICAgICAgIXRoaXMub3B0aW9ucy5sb2NhbGVzLmluY2x1ZGVzKGxvb3NlTG9jYWxlKVxuICAgICAgICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmZldGNoVHJhbnNsYXRpb24ocmVtb3RlVXJsLCBsb29zZUxvY2FsZSk7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBpc0Rldk1vZGUoKSA/IHRocm93RXJyb3IoKCkgPT4gZXJyb3IpIDogRU1QVFk7XG4gICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICBmaWx0ZXIoaXNQbGFpbk9iamVjdCksXG4gICAgICAgICAgICAgIG1hcChcbiAgICAgICAgICAgICAgICAodHJhbnNsYXRpb246IFRyYW5zbGF0aW9uKSA9PlxuICAgICAgICAgICAgICAgICAgKHtcbiAgICAgICAgICAgICAgICAgICAgW2xvY2FsZV06IHRyYW5zbGF0aW9uLFxuICAgICAgICAgICAgICAgICAgfSkgYXMgVHJhbnNsYXRpb25zLFxuICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgKSxcbiAgICAgICAgICApLFxuICAgICAgICApLnBpcGUobWFwKF8gPT4gXy5yZWR1Y2UoT2JqZWN0LmFzc2lnbikpKVxuICAgICAgOiB0aGlzLmZldGNoVHJhbnNsYXRpb24ocmVtb3RlVXJsKS5waXBlKFxuICAgICAgICAgIGNhdGNoRXJyb3IoZXJyb3IgPT4gKGlzRGV2TW9kZSgpID8gdGhyb3dFcnJvcigoKSA9PiBlcnJvcikgOiBFTVBUWSkpLFxuICAgICAgICApXG4gICAgKVxuICAgICAgLnBpcGUoXG4gICAgICAgIHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kkJCksXG4gICAgICAgIGZpbmFsaXplKCgpID0+IHtcbiAgICAgICAgICB0aGlzLnRyYW5zbGF0aW9uc0FkZGVkJC5uZXh0KCk7XG4gICAgICAgIH0pLFxuICAgICAgKVxuICAgICAgLnN1YnNjcmliZShyZW1vdGVUcmFuc2xhdGlvbnMgPT4ge1xuICAgICAgICBpZiAoIXJlbW90ZVRyYW5zbGF0aW9ucykge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnJlbW90ZVRyYW5zbGF0aW9uc0xpc3QudW5zaGlmdChPYmplY3QuZnJlZXplKHJlbW90ZVRyYW5zbGF0aW9ucykpO1xuICAgICAgfSk7XG4gIH1cblxuICAvKipcbiAgICog5LuO6L+c56iLIHVybCDmqKHmnb/lkozljLrln5/ojrflj5bnv7vor5HljIVcbiAgICovXG4gIGZldGNoVHJhbnNsYXRpb24ocmVtb3RlVXJsOiBzdHJpbmcpOiBPYnNlcnZhYmxlPFRyYW5zbGF0aW9ucz47XG4gIGZldGNoVHJhbnNsYXRpb24ocmVtb3RlVXJsOiBzdHJpbmcsIGxvY2FsZTogc3RyaW5nKTogT2JzZXJ2YWJsZTxUcmFuc2xhdGlvbj47XG4gIGZldGNoVHJhbnNsYXRpb24ocmVtb3RlVXJsOiBzdHJpbmcsIGxvY2FsZT86IHN0cmluZykge1xuICAgIGlmIChpc0Rldk1vZGUoKSAmJiBMT0NBTEVfUExBQ0VIT0xERVJfUkVHRVgudGVzdChyZW1vdGVVcmwpICYmICFsb2NhbGUpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXG4gICAgICAgICdgbG9jYWxlYCBpcyByZXF1aXJlZCBzaW5lIHRoZSBwcm92aWRlZCByZW1vdGUgdXJsIGNvbnRhaW5zIGxvY2FsZSBwbGFjZWhvbGRlcicsXG4gICAgICApO1xuICAgIH1cbiAgICBjb25zdCBpc0pTT04gPSByZW1vdGVVcmwuZW5kc1dpdGgoJy5qc29uJyk7XG4gICAgY29uc3QgaXNBcGlHYXRlV2F5UmVxdWVzdCA9IHJlbW90ZVVybC5zdGFydHNXaXRoKEFQSV9HQVRFV0FZKTtcbiAgICBjb25zdCB1cmwgPSBsb2NhbGVcbiAgICAgID8gcmVtb3RlVXJsLnJlcGxhY2UoTE9DQUxFX1BMQUNFSE9MREVSX1JFR0VYLCBsb2NhbGUpXG4gICAgICA6IHJlbW90ZVVybDtcbiAgICBjb25zdCByZXNwb25zZVR5cGUgPSBpc0pTT04gPyAnanNvbicgOiAndGV4dCc7XG4gICAgaWYgKGlzQXBpR2F0ZVdheVJlcXVlc3QpIHtcbiAgICAgIHJldHVybiB0aGlzLmh0dHBcbiAgICAgICAgLnJlcXVlc3QoJ0dFVCcsIHVybCwgeyByZXNwb25zZVR5cGUgfSlcbiAgICAgICAgLnBpcGUobWFwKGJvZHkgPT4gKGlzSlNPTiA/IGJvZHkgOiBwYXJzZShib2R5KSkpKTtcbiAgICB9XG4gICAgcmV0dXJuIGFqYXgoe1xuICAgICAgdXJsLFxuICAgICAgcmVzcG9uc2VUeXBlLFxuICAgIH0pLnBpcGUoXG4gICAgICBtYXAoKHsgcmVzcG9uc2UgfSkgPT4gKGlzSlNPTiA/IHJlc3BvbnNlIDogcGFyc2UocmVzcG9uc2UgYXMgc3RyaW5nKSkpLFxuICAgICk7XG4gIH1cblxuICBwcml2YXRlIF9nZXRMb29zZUxvY2FsZShsb2NhbGU6IHN0cmluZykge1xuICAgIHJldHVybiBoZWFkKGxvY2FsZS5zcGxpdCgvW18tXS8pKTtcbiAgfVxuXG4gIHByaXZhdGUgX2dldFZhbHVlKFxuICAgIHNvdXJjZTogVHJhbnNsYXRpb24sXG4gICAgbG9jYWxlID0gdGhpcy5sb2NhbGUsXG4gICk6IFRyYW5zbGF0aW9uVmFsdWUge1xuICAgIGlmICghc291cmNlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGxldCB2YWx1ZSA9IHNvdXJjZVtsb2NhbGVdO1xuICAgIGlmICh2YWx1ZSA9PSBudWxsICYmIHRoaXMub3B0aW9ucy5sb29zZSkge1xuICAgICAgY29uc3QgbG9vc2VMb2NhbGUgPSB0aGlzLl9nZXRMb29zZUxvY2FsZShsb2NhbGUpO1xuICAgICAgdmFsdWUgPVxuICAgICAgICBsb2NhbGUgPT09IGxvb3NlTG9jYWxlXG4gICAgICAgICAgPyBPYmplY3QuZW50cmllcyhzb3VyY2UpLmZpbmQoXG4gICAgICAgICAgICAgIChba2V5XSkgPT4gbG9jYWxlID09PSB0aGlzLl9nZXRMb29zZUxvY2FsZShrZXkpLFxuICAgICAgICAgICAgKT8uWzFdXG4gICAgICAgICAgOiBzb3VyY2VbbG9vc2VMb2NhbGVdO1xuICAgIH1cbiAgICBpZiAodmFsdWUgPT0gbnVsbCAmJiBsb2NhbGUgIT09IHRoaXMub3B0aW9ucy5mYWxsYmFja0xvY2FsZSkge1xuICAgICAgcmV0dXJuIHRoaXMuX2dldFZhbHVlKHNvdXJjZSwgdGhpcy5vcHRpb25zLmZhbGxiYWNrTG9jYWxlKTtcbiAgICB9XG4gICAgcmV0dXJuIHZhbHVlO1xuICB9XG5cbiAgcHJpdmF0ZSBfZ2V0V2l0aEZhbGxiYWNrKFxuICAgIGtleTogc3RyaW5nLFxuICAgIGxvY2FsZSA9IHRoaXMubG9jYWxlLFxuICAgIHRyYW5zbGF0aW9uczogVHJhbnNsYXRpb25zLFxuICApOiBzdHJpbmcge1xuICAgIGNvbnN0IHZhbHVlID0gZ2V0KHRoaXMuX2dldFZhbHVlKHRyYW5zbGF0aW9ucywgbG9jYWxlKSwga2V5KTtcbiAgICBpZiAodmFsdWUgIT0gbnVsbCkge1xuICAgICAgaWYgKFxuICAgICAgICB0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnICYmXG4gICAgICAgIGlzRGV2TW9kZSgpICYmXG4gICAgICAgIHR5cGVvZiBnZXQodmFsdWUsIFN5bWJvbC50b1ByaW1pdGl2ZSkgIT09ICdmdW5jdGlvbidcbiAgICAgICkge1xuICAgICAgICBjb25zb2xlLndhcm4oXG4gICAgICAgICAgYFRoZSB0cmFuc2xhdGlvbiBmb3IgbG9jYWxlOiBcXGAke2xvY2FsZX1cXGAgYW5kIGtleTpcXGAke2tleX1cXGAgaXMgYW4gb2JqZWN0LCB3aGljaCBjb3VsZCBiZSB1bmV4cGVjdGVkYCxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBTdHJpbmcodmFsdWUpO1xuICAgIH1cbiAgICBpZiAobG9jYWxlICE9PSB0aGlzLm9wdGlvbnMuZmFsbGJhY2tMb2NhbGUpIHtcbiAgICAgIHJldHVybiB0aGlzLl9nZXRXaXRoRmFsbGJhY2soXG4gICAgICAgIGtleSxcbiAgICAgICAgdGhpcy5vcHRpb25zLmZhbGxiYWNrTG9jYWxlLFxuICAgICAgICB0cmFuc2xhdGlvbnMsXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgX2dldEJhc2UoXG4gICAga2V5OiBzdHJpbmcsXG4gICAgbG9jYWxlID0gdGhpcy5sb2NhbGUsXG4gICAgdHJhbnNsYXRpb25zTGlzdDogVHJhbnNsYXRpb25zW10sXG4gICkge1xuICAgIGlmICghdHJhbnNsYXRpb25zTGlzdCB8fCB0cmFuc2xhdGlvbnNMaXN0Lmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBmb3IgKGxldCBpID0gdHJhbnNsYXRpb25zTGlzdC5sZW5ndGg7IGkgPiAwOyBpLS0pIHtcbiAgICAgIGNvbnN0IHZhbHVlID0gdGhpcy5fZ2V0V2l0aEZhbGxiYWNrKGtleSwgbG9jYWxlLCB0cmFuc2xhdGlvbnNMaXN0W2kgLSAxXSk7XG4gICAgICBpZiAodmFsdWUgIT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHJvdGVjdGVkIF9nZXQoa2V5OiBzdHJpbmcsIGxvY2FsZSA9IHRoaXMubG9jYWxlKSB7XG4gICAgbGV0IHZhbHVlID0gdGhpcy5fZ2V0QmFzZShrZXksIGxvY2FsZSwgdGhpcy5yZW1vdGVUcmFuc2xhdGlvbnNMaXN0KTtcbiAgICBpZiAodmFsdWUgPT0gbnVsbCkge1xuICAgICAgdmFsdWUgPSB0aGlzLl9nZXRCYXNlKGtleSwgbG9jYWxlLCB0aGlzLnRyYW5zbGF0aW9uc0xpc3QpO1xuICAgIH1cbiAgICBpZiAodmFsdWUgIT0gbnVsbCkge1xuICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH1cbiAgICByZXR1cm4ga2V5O1xuICB9XG5cbiAgcHJpdmF0ZSBfY29tcGFyZUtleXMoXG4gICAgbG9jYWxlOiBzdHJpbmcsXG4gICAgdHJhbnNsYXRpb246IFRyYW5zbGF0aW9uLFxuICAgIHByZXZUcmFuc2xhdGlvbjogVHJhbnNsYXRpb24sXG4gICAgcGF0aDogc3RyaW5nW10gPSBbXSxcbiAgKSB7XG4gICAgaWYgKHRyYW5zbGF0aW9uID09IG51bGwgfHwgcHJldlRyYW5zbGF0aW9uID09IG51bGwpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBPYmplY3QuZW50cmllcyh0cmFuc2xhdGlvbikuZm9yRWFjaCgoW2tleSwgdmFsdWVdKSA9PiB7XG4gICAgICBpZiAoIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChwcmV2VHJhbnNsYXRpb24sIGtleSkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBwcmV2VmFsdWUgPSBwcmV2VHJhbnNsYXRpb25ba2V5XTtcbiAgICAgIGNvbnN0IHZhbHVlSXNQbGFpbk9iamVjdCA9IGlzUGxhaW5PYmplY3QodmFsdWUpO1xuICAgICAgY29uc3QgcHJldlZhbHVlSXNQbGFpbk9iamVjdCA9IGlzUGxhaW5PYmplY3QocHJldlZhbHVlKTtcblxuICAgICAgaWYgKHZhbHVlSXNQbGFpbk9iamVjdCAmJiBwcmV2VmFsdWVJc1BsYWluT2JqZWN0KSB7XG4gICAgICAgIHRoaXMuX2NvbXBhcmVLZXlzKFxuICAgICAgICAgIGxvY2FsZSxcbiAgICAgICAgICB2YWx1ZSBhcyBUcmFuc2xhdGlvbixcbiAgICAgICAgICBwcmV2VmFsdWUgYXMgVHJhbnNsYXRpb24sXG4gICAgICAgICAgWy4uLnBhdGgsIGtleV0sXG4gICAgICAgICk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKCF2YWx1ZUlzUGxhaW5PYmplY3QgJiYgIXByZXZWYWx1ZUlzUGxhaW5PYmplY3QpIHtcbiAgICAgICAgY29uc3Qgb3V0cHV0UGF0aCA9IFsuLi5wYXRoLCBrZXldLmpvaW4oJyAtPiAnKTtcbiAgICAgICAgaWYgKHZhbHVlID09PSBwcmV2VmFsdWUpIHtcbiAgICAgICAgICBjb25zb2xlLndhcm4oXG4gICAgICAgICAgICBgVGhlIGN1c3RvbWl6ZWQgdHJhbnNsYXRpb24gZm9yIGxvY2FsZTogXFxgJHtsb2NhbGV9XFxgIGFuZCBwYXRoOiBcXGAke291dHB1dFBhdGh9XFxgIGlzIGR1cGxpY2F0ZWQgd2l0aCB0aGUgb3RoZXIgdHJhbnNsYXRpb24sIHBsZWFzZSByZW1vdmUgaXQgaW4geW91ciB0cmFuc2xhdGlvbiBmaWxlLmAsXG4gICAgICAgICAgKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjb25zb2xlLndhcm4oXG4gICAgICAgICAgICBgVHdvIGtleXMgdGhhdCB0aGUgbG9jYWxlIGlzIFxcYCR7bG9jYWxlfVxcYCBhbmQgdGhlIHBhdGggaXMgXFxgJHtvdXRwdXRQYXRofVxcYCBhcmUgc2FtZSwgIGJ1dCB0aGVpciB2YWx1ZXMgYXJlIG5vdCBlcXVhbCAsIHBsZWFzZSByZW1vdmUgb25lIG9mIHRoZW0gb3IgY2hhbmdlIG9uZSBvZiB0aGUga2V5cy5gLFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcbiAgfVxufVxuIl19
|
|
869
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhbnNsYXRlLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9saWJzL2NvbW1vbi9zcmMvdHJhbnNsYXRlL3RyYW5zbGF0ZS5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTs7O0dBR0c7QUFFSCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDbEQsT0FBTyxFQUNMLE1BQU0sRUFDTixVQUFVLEVBRVYsUUFBUSxFQUNSLFNBQVMsR0FDVixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUN2RCxPQUFPLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxhQUFhLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFDckQsT0FBTyxFQUNMLFVBQVUsRUFDVixPQUFPLEVBQ1AsUUFBUSxFQUNSLFVBQVUsRUFDVixLQUFLLEVBQ0wsVUFBVSxFQUNWLE1BQU0sRUFDTixRQUFRLEVBQ1IsR0FBRyxFQUNILFNBQVMsR0FDVixNQUFNLE1BQU0sQ0FBQztBQUNkLE9BQU8sRUFBRSxJQUFJLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFFakMsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBQzFELE9BQU8sRUFBRSxlQUFlLEVBQUUsZUFBZSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDdEUsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQ3JELE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUUzQyxPQUFPLEVBQ0wsaUJBQWlCLEVBQ2pCLHdCQUF3QixFQUN4QixjQUFjLEdBQ2YsTUFBTSxhQUFhLENBQUM7QUFDckIsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNoRCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsWUFBWSxFQUFFLE1BQU0sVUFBVSxD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IjpbIi8qKlxuICogQHBhY2thZ2VEb2N1bWVudGF0aW9uXG4gKiBAbW9kdWxlIHRyYW5zbGF0ZVxuICovXG5cbmltcG9ydCB7IEh0dHBDbGllbnQgfSBmcm9tICdAYW5ndWxhci9jb21tb24vaHR0cCc7XG5pbXBvcnQge1xuICBJbmplY3QsXG4gIEluamVjdGFibGUsXG4gIE9uRGVzdHJveSxcbiAgT3B0aW9uYWwsXG4gIGlzRGV2TW9kZSxcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBJbnRsTWVzc2FnZUZvcm1hdCB9IGZyb20gJ2ludGwtbWVzc2FnZWZvcm1hdCc7XG5pbXBvcnQgeyBnZXQsIGhlYWQsIGlzUGxhaW5PYmplY3QgfSBmcm9tICdsb2Rhc2gtZXMnO1xuaW1wb3J0IHtcbiAgT2JzZXJ2YWJsZSxcbiAgU3ViamVjdCxcbiAgZm9ya0pvaW4sXG4gIHRocm93RXJyb3IsXG4gIEVNUFRZLFxuICBjYXRjaEVycm9yLFxuICBmaWx0ZXIsXG4gIGZpbmFsaXplLFxuICBtYXAsXG4gIHRha2VVbnRpbCxcbn0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBhamF4IH0gZnJvbSAncnhqcy9hamF4JztcblxuaW1wb3J0IHsgQVBJX0dBVEVXQVkgfSBmcm9tICcuLi9jb3JlL2NvbnN0YW50cy9jb25zdGFudHMnO1xuaW1wb3J0IHsgT2JzZXJ2YWJsZUlucHV0LCBUT0tFTl9CQVNFX0hSRUYgfSBmcm9tICcuLi9jb3JlL3B1YmxpYy1hcGknO1xuaW1wb3J0IHsgaXNBYnNvbHV0ZVVybCB9IGZyb20gJy4uL2NvcmUvdXRpbHMvY29tbW9uJztcbmltcG9ydCB7IHBhcnNlIH0gZnJvbSAnLi4vY29yZS91dGlscy95YW1sJztcblxuaW1wb3J0IHtcbiAgRkFMTEJBQ0tfTEFOR1VBR0UsXG4gIExPQ0FMRV9QTEFDRUhPTERFUl9SRUdFWCxcbiAgTE9DQUxFX1NUT1JBR0UsXG59IGZyb20gJy4vY29uc3RhbnRzJztcbmltcG9ydCB7IGdldFVzZXJMYW5ndWFnZSB9IGZyb20gJy4vaTE4bi1jb25maWcnO1xuaW1wb3J0IHsgVFJBTlNMQVRFX09QVElPTlMsIFRSQU5TTEFUSU9OUyB9IGZyb20gJy4vdG9rZW5zJztcbmltcG9ydCB7XG4gIFRyYW5zbGF0ZUtleSxcbiAgVHJhbnNsYXRlT3B0aW9ucyxcbiAgVHJhbnNsYXRpb24sXG4gIFRyYW5zbGF0aW9uVmFsdWUsXG4gIFRyYW5zbGF0aW9ucyxcbiAgVGVtcGxhdGVEYXRhLFxuICBJY3VEYXRhLFxufSBmcm9tICcuL3R5cGVzJztcblxuLyoqXG4gKiDlm73pmYXljJbnv7vor5HmnI3liqFcbiAqXG4gKiDnibnmgKfvvJpcbiAqIC0g5pSv5oyB5aSa5bGC57qn57+76K+R5LyY5YWI57qn77yI6L+c56iL57+76K+RID4g5omL5Yqo5re75Yqg57+76K+RID4g6YWN572u57+76K+R77yJXG4gKiAtIOaUr+aMgeWKqOaAgeivreiogOWIh+aNolxuICogLSDmlK/mjIEgSUNVIE1lc3NhZ2UgRm9ybWF0IOaooeadv+aPkuWAvFxuICogLSDmlK/mjIHlrr3mnb7mqKHlvI/or63oqIDljLnphY1cbiAqIC0g5pSv5oyB5byC5q2l6L+c56iL57+76K+R5Yqg6L29XG4gKi9cbkBJbmplY3RhYmxlKHsgcHJvdmlkZWRJbjogJ3Jvb3QnIH0pXG5leHBvcnQgY2xhc3MgVHJhbnNsYXRlU2VydmljZSBpbXBsZW1lbnRzIE9uRGVzdHJveSB7XG4gIC8qKiDnv7vor5Hmt7vliqDpgJrnn6XmtYEgKi9cbiAgcHJpdmF0ZSByZWFkb25seSB0cmFuc2xhdGlvbnNBZGRlZCQkID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcblxuICByZWFkb25seSB0cmFuc2xhdGlvbnNBZGRlZCQgPSB0aGlzLnRyYW5zbGF0aW9uc0FkZGVkJCQuYXNPYnNlcnZhYmxlKCk7XG5cbiAgLyoqIOe7hOS7tumUgOavgemAmuefpea1gSAqL1xuICBwcml2YXRlIHJlYWRvbmx5IGRlc3Ryb3kkJCA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XG5cbiAgLyoqIOacrOWcsOe/u+ivkeWIl+ihqO+8iOS8mOWFiOe6p++8muWQjuWKoOWFpeeahOS8mOWFiOe6p+abtOmrmO+8iSAqL1xuICByZWFkb25seSB0cmFuc2xhdGlvbnNMaXN0OiBBcnJheTxSZWFkb25seTxUcmFuc2xhdGlvbnM+PiA9IFtdO1xuXG4gIC8qKiDov5znqIvnv7vor5HliJfooajvvIjkvJjlhYjnuqfmnIDpq5jvvIkgKi9cbiAgcmVhZG9ubHkgcmVtb3RlVHJhbnNsYXRpb25zTGlzdDogQXJyYXk8UmVhZG9ubHk8VHJhbnNsYXRpb25zPj4gPSBbXTtcblxuICAvKiog57+76K+R6YWN572u6YCJ6aG5ICovXG4gIHJlYWRvbmx5IG9wdGlvbnM6IFRyYW5zbGF0ZU9wdGlvbnM7XG5cbiAgLyoqIOW9k+WJjeivreiogOeOr+WigyAqL1xuICBsb2NhbGU6IHN0cmluZztcblxuICAvKiog5b2T5YmN6K+t6KiA546v5aKD77yI5ZON5bqU5byP77yJICovXG4gIEBPYnNlcnZhYmxlSW5wdXQoKVxuICByZWFkb25seSBsb2NhbGUkOiBPYnNlcnZhYmxlPHN0cmluZz47XG5cbiAgLyoqIOiOt+WPluaUr+aMgeeahOivreiogOWIl+ihqCAqL1xuICBnZXQgbG9jYWxlcygpOiBzdHJpbmdbXSB7XG4gICAgcmV0dXJuIHRoaXMub3B0aW9ucy5sb2NhbGVzO1xuICB9XG5cbiAgLyoqIOiOt+WPluWbnumAgOivreiogCAqL1xuICBnZXQgZmFsbGJhY2tMb2NhbGUoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5vcHRpb25zLmZhbGxiYWNrTG9jYWxlO1xuICB9XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSByZWFkb25seSBodHRwOiBIdHRwQ2xpZW50LFxuICAgIEBJbmplY3QoVE9LRU5fQkFTRV9IUkVGKSBwcml2YXRlIHJlYWRvbmx5IGJhc2VIcmVmOiBzdHJpbmcsXG4gICAgQE9wdGlvbmFsKCkgQEluamVjdChUUkFOU0xBVEVfT1BUSU9OUykgb3B0aW9uczogVHJhbnNsYXRlT3B0aW9ucyxcbiAgICBAT3B0aW9uYWwoKSBASW5qZWN0KFRSQU5TTEFUSU9OUykgdHJhbnNsYXRpb25MaXN0OiBUcmFuc2xhdGlvbnNbXSxcbiAgKSB7XG4gICAgLy8g5Yid5aeL5YyW6K+t6KiA546v5aKDXG4gICAgdGhpcy5sb2NhbGUgPSB0aGlzLmdldEluaXRpYWxMb2NhbGUob3B0aW9ucyk7XG5cbiAgICAvLyDliJ3lp4vljJbphY3nva7pgInpoblcbiAgICB0aGlzLm9wdGlvbnMgPSB7XG4gICAgICBsb2NhbGVzOiBbdGhpcy5sb2NhbGVdLFxuICAgICAgZmFsbGJhY2tMb2NhbGU6IEZBTExCQUNLX0xBTkdVQUdFLFxuICAgICAgbG9vc2U6IGZhbHNlLFxuICAgICAgLi4ub3B0aW9ucyxcbiAgICB9O1xuXG4gICAgLy8g5Yid5aeL5YyW57+76K+R5YiX6KGoXG4gICAgdGhpcy50cmFuc2xhdGlvbnNMaXN0ID0gdGhpcy5nZXRJbml0aWFsaXplVHJhbnNsYXRpb25zKFxuICAgICAgb3B0aW9ucyxcbiAgICAgIHRyYW5zbGF0aW9uTGlzdCxcbiAgICApO1xuXG4gICAgLy8g5Yqg6L296L+c56iL57+76K+RXG4gICAgdGhpcy5sb2FkUmVtb3RlVHJhbnNsYXRpb25zKG9wdGlvbnMpO1xuICB9XG5cbiAgLyoqXG4gICAqIOe7hOS7tumUgOavgea4heeQhlxuICAgKi9cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy5kZXN0cm95JCQubmV4dCgpO1xuICAgIHRoaXMuZGVzdHJveSQkLmNvbXBsZXRlKCk7XG4gIH1cblxuICAvKipcbiAgICog6I635Y+W57+76K+R5paH5pys5bm26L+b6KGM5qih5p2/5o+S5YC8XG4gICAqIOiHquWKqOWwhuS8oOe7nyB7eyBrZXkgfX0g6K+t5rOV6L2s5o2i5Li6IElDVSB7a2V5fSDmoLzlvI/ov5vooYzop6PmnpBcbiAgICog5ZCM5pe25pSv5oyB5Y6f55SfIElDVSBNZXNzYWdlIEZvcm1hdCDor63ms5VcbiAgICogQHBhcmFtIGtleSAtIOe/u+ivkemUruaIlue/u+ivkeWvueixoVxuICAgKiBAcGFyYW0gZGF0YSAtIOaooeadv+aVsOaNru+8iOaUr+aMgeWfuuacrOexu+Wei+OAgURhdGXjgIHlr7nosaHlkozmlbDnu4TvvIlcbiAgICogQHJldHVybnMg57+76K+R5ZCO55qE5paH5pysXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqIGBgYHR5cGVzY3JpcHRcbiAgICogLy8g5a+56LGh5Y+C5pWw77yI5o6o6I2Q77yJXG4gICAqIHRyYW5zbGF0ZS5nZXQoJ2hlbGxvJywgeyBuYW1lOiAnV29ybGQnIH0pIC8vIOaooeadvzogXCJIZWxsbyB7bmFtZX1cIlxuICAgKlxuICAgKiAvLyDln7rmnKznsbvlnovlj4LmlbDvvIjoh6rliqjovazmjaLkuLoge3ZhbHVlfe+8iVxuICAgKiB0cmFuc2xhdGUuZ2V0KCd3ZWxjb21lJywgJ0pvaG4nKSAvLyDmqKHmnb86IFwiV2VsY29tZSB7dmFsdWV9XCJcbiAgICpcbiAgICogLy8gSUNVIOagvOW8j++8iOaVsOWtl++8iVxuICAgKiB0cmFuc2xhdGUuZ2V0KCdpdGVtQ291bnQnLCB7IGNvdW50OiA1IH0pXG4gICAqXG4gICAqIC8vIElDVSDmoLzlvI/vvIjml6XmnJ/vvIzpu5jorqTmnKzlnLDljJbvvIlcbiAgICogdHJhbnNsYXRlLmdldCgnY3JlYXRlZEF0JywgeyBkYXRlOiBuZXcgRGF0ZSgpIH0pXG4gICAqIGBgYFxuICAgKi9cbiAgZ2V0KGtleTogVHJhbnNsYXRlS2V5LCBkYXRhPzogVGVtcGxhdGVEYXRhKTogc3RyaW5nIHtcbiAgICBjb25zdCB0cmFuc2xhdGlvbiA9IHRoaXMuZ2V0UmF3KGtleSk7XG5cbiAgICBpZiAoZGF0YSA9PSBudWxsKSB7XG4gICAgICByZXR1cm4gdHJhbnNsYXRpb247XG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgIC8vIOWwhuS8oOe7n+eahCB7eyBrZXkgfX0g6K+t5rOV6L2s5o2i5Li6IElDVSB7a2V5fSDmoLzlvI9cbiAgICAgIGNvbnN0IGljdU1lc3NhZ2UgPSB0aGlzLmNvbnZlcnRUb0ljdUZvcm1hdCh0cmFuc2xhdGlvbik7XG4gICAgICAvLyDlsIbmlbDmja7ovazmjaLkuLogSUNVIOWFvOWuueeahOagvOW8j1xuICAgICAgY29uc3QgaWN1RGF0YSA9IHRoaXMubm9ybWFsaXplQW5kQ29udmVydFRvSWN1RGF0YShkYXRhKTtcbiAgICAgIHJldHVybiB0aGlzLmZvcm1hdEljdU1lc3NhZ2UoaWN1TWVzc2FnZSwgaWN1RGF0YSk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHRoaXMuaGFuZGxlVGVtcGxhdGVFcnJvcihrZXksIGVycm9yKTtcbiAgICAgIHJldHVybiB0cmFuc2xhdGlvbjtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICog6I635Y+W5Y6f5aeL57+76K+R5paH5pys5qih5p2/77yI5LiN6L+b6KGM5o+S5YC85aSE55CG77yJXG4gICAqIEBwYXJhbSBrZXkgLSDnv7vor5HplK7miJbnv7vor5Hlr7nosaFcbiAgICogQHJldHVybnMg5Y6f5aeL57+76K+R5qih5p2/5paH5pysXG4gICAqL1xuICBnZXRSYXcoa2V5OiBUcmFuc2xhdGVLZXkpOiBzdHJpbmcge1xuICAgIGlmICh0eXBlb2Yga2V5ID09PSAnc3RyaW5nJykge1xuICAgICAgcmV0dXJuIHRoaXMuZ2V0VHJhbnNsYXRpb25CeUtleShrZXkpO1xuICAgIH1cblxuICAgIC8vIOW9k2tleeaYr1RyYW5zbGF0aW9u5a+56LGh5pe277yM6I635Y+W5b2T5YmN6K+t6KiA55qE57+76K+R5YC8XG4gICAgY29uc3QgdmFsdWUgPSB0aGlzLmdldFRyYW5zbGF0aW9uQnlPYmplY3Qoa2V5KTtcblxuICAgIC8vIOWmguaenOaJvuWIsOWAvOWImei/lOWbnuWtl+espuS4suW9ouW8j++8jOWQpuWImei/lOWbnkpTT07lrZfnrKbkuLLooajnpLpcbiAgICBpZiAodmFsdWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIHZhbHVlID09PSBudWxsID8gJ251bGwnIDogU3RyaW5nKHZhbHVlKTtcbiAgICB9XG5cbiAgICAvLyDlpoLmnpzmsqHmnInmib7liLDnv7vor5HvvIzov5Tlm55KU09O5a2X56ym5Liy5b2i5byPXG4gICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KGtleSk7XG4gIH1cblxuICAvKipcbiAgICog5YiH5o2i5Yiw5LiL5LiA5Liq5pSv5oyB55qE6K+t6KiA546v5aKDXG4gICAqL1xuICB0b2dnbGVMb2NhbGUoKTogdm9pZCB7XG4gICAgY29uc3QgY3VycmVudEluZGV4ID0gdGhpcy5vcHRpb25zLmxvY2FsZXMuaW5kZXhPZih0aGlzLmxvY2FsZSk7XG5cbiAgICBpZiAoY3VycmVudEluZGV4ID09PSAtMSkge1xuICAgICAgdGhpcy5oYW5kbGVJbnZhbGlkTG9jYWxlKCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgbmV4dEluZGV4ID0gKGN1cnJlbnRJbmRleCArIDEpICUgdGhpcy5vcHRpb25zLmxvY2FsZXMubGVuZ3RoO1xuICAgIGNvbnN0IG5leHRMb2NhbGUgPSB0aGlzLm9wdGlvbnMubG9jYWxlc1tuZXh0SW5kZXhdO1xuXG4gICAgaWYgKG5leHRMb2NhbGUgJiYgbmV4dExvY2FsZSAhPT0gdGhpcy5sb2NhbGUpIHtcbiAgICAgIHRoaXMuc2V0TG9jYWxlKG5leHRMb2NhbGUpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiDorr7nva7lvZPliY3or63oqIDnjq/looNcbiAgICogQHBhcmFtIGxvY2FsZSAtIOimgeiuvue9rueahOivreiogOeOr+Wig1xuICAgKi9cbiAgc2V0TG9jYWxlKGxvY2FsZTogc3RyaW5nKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLmlzVmFsaWRMb2NhbGUobG9jYWxlKSkge1xuICAgICAgaWYgKGlzRGV2TW9kZSgpKSB7XG4gICAgICAgIGNvbnNvbGUud2FybihcbiAgICAgICAgICBgSW52YWxpZCBsb2NhbGU6ICR7bG9jYWxlfS4gU3VwcG9ydGVkIGxvY2FsZXM6ICR7dGhpcy5vcHRpb25zLmxvY2FsZXMuam9pbignLCAnKX1gLFxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGxvY2FsU3RvcmFnZS5zZXRJdGVtKExPQ0FMRV9TVE9SQUdFLCBsb2NhbGUpO1xuICAgIHRoaXMubG9jYWxlID0gbG9jYWxlO1xuICB9XG5cbiAgLyoqXG4gICAqIOaJi+WKqOa3u+WKoOe/u+ivkeWMhVxuICAgKiBAcGFyYW0gdHJhbnNsYXRpb25zIC0g6KaB5re75Yqg55qE57+76K+R5YyFXG4gICAqL1xuICBhZGRUcmFuc2xhdGlvbnModHJhbnNsYXRpb25zOiBUcmFuc2xhdGlvbnMpOiB2b2lkIHtcbiAgICBpZiAoIXRyYW5zbGF0aW9ucyB8fCB0eXBlb2YgdHJhbnNsYXRpb25zICE9PSAnb2JqZWN0Jykge1xuICAgICAgaWYgKGlzRGV2TW9kZSgpKSB7XG4gICAgICAgIGNvbnNvbGUud2FybignSW52YWxpZCB0cmFuc2xhdGlvbnMgb2JqZWN0IHByb3ZpZGVkJyk7XG4gICAgICB9XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8g5byA5Y+R5qih5byP5LiL5qOA5p+l6YeN5aSN57+76K+RXG4gICAgaWYgKGlzRGV2TW9kZSgpICYmIHRoaXMudHJhbnNsYXRpb25zTGlzdC5sZW5ndGggPiAwKSB7XG4gICAgICB0aGlzLmNoZWNrRm9yRHVwbGljYXRlVHJhbnNsYXRpb25zKHRyYW5zbGF0aW9ucyk7XG4gICAgfVxuXG4gICAgdGhpcy50cmFuc2xhdGlvbnNMaXN0LnB1c2godHJhbnNsYXRpb25zKTtcbiAgICB0aGlzLnRyYW5zbGF0aW9uc0FkZGVkJCQubmV4dCgpO1xuICB9XG5cbiAgLyoqXG4gICAqIOa3u+WKoOi/nOeoi+e/u+ivkeWMhVxuICAgKiBAcGFyYW0gcmVtb3RlVXJsIC0g6L+c56iL57+76K+R5paH5Lu2VVJMXG4gICAqL1xuICBhZGRSZW1vdGVUcmFuc2xhdGlvbnMocmVtb3RlVXJsOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBpZiAoIXJlbW90ZVVybCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IG5vcm1hbGl6ZWRVcmwgPSB0aGlzLm5vcm1hbGl6ZVJlbW90ZVVybChyZW1vdGVVcmwpO1xuICAgIGNvbnN0IHJlcXVlc3QkID0gdGhpcy5jcmVhdGVSZW1vdGVUcmFuc2xhdGlvblJlcXVlc3Qobm9ybWFsaXplZFVybCk7XG5cbiAgICByZXF1ZXN0JFxuICAgICAgLnBpcGUoXG4gICAgICAgIHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kkJCksXG4gICAgICAgIGZpbmFsaXplKCgpID0+IHtcbiAgICAgICAgICB0aGlzLnRyYW5zbGF0aW9uc0FkZGVkJCQubmV4dCgpO1xuICAgICAgICB9KSxcbiAgICAgIClcbiAgICAgIC5zdWJzY3JpYmUoe1xuICAgICAgICBuZXh0OiByZW1vdGVUcmFuc2xhdGlvbnMgPT4ge1xuICAgICAgICAgIGlmIChyZW1vdGVUcmFuc2xhdGlvbnMpIHtcbiAgICAgICAgICAgIHRoaXMucmVtb3RlVHJhbnNsYXRpb25zTGlzdC5wdXNoKHJlbW90ZVRyYW5zbGF0aW9ucyk7XG4gICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICBlcnJvcjogZXJyb3IgPT4ge1xuICAgICAgICAgIGlmIChpc0Rldk1vZGUoKSkge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcihcbiAgICAgICAgICAgICAgYEZhaWxlZCB0byBsb2FkIHJlbW90ZSB0cmFuc2xhdGlvbnMgZnJvbSAke3JlbW90ZVVybH06YCxcbiAgICAgICAgICAgICAgZXJyb3IsXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIOS7jui/nOeoi1VSTOiOt+WPlue/u+ivkeaVsOaNrlxuICAgKiBAcGFyYW0gcmVtb3RlVXJsIC0g6L+c56iLVVJMXG4gICAqIEBwYXJhbSBsb2NhbGUgLSDlj6/pgInnmoTor63oqIDnjq/looPvvIjnlKjkuo5VUkzmqKHmnb/mm7/mjaLvvIlcbiAgICogQHJldHVybnMg57+76K+R5pWw5o2u55qET2JzZXJ2YWJsZVxuICAgKi9cbiAgZmV0Y2hUcmFuc2xhdGlvbihyZW1vdGVVcmw6IHN0cmluZyk6IE9ic2VydmFibGU8VHJhbnNsYXRpb25zPjtcbiAgZmV0Y2hUcmFuc2xhdGlvbihyZW1vdGVVcmw6IHN0cmluZywgbG9jYWxlOiBzdHJpbmcpOiBPYnNlcnZhYmxlPFRyYW5zbGF0aW9uPjtcbiAgZmV0Y2hUcmFuc2xhdGlvbihcbiAgICByZW1vdGVVcmw6IHN0cmluZyxcbiAgICBsb2NhbGU/OiBzdHJpbmcsXG4gICk6IE9ic2VydmFibGU8VHJhbnNsYXRpb25zIHwgVHJhbnNsYXRpb24+IHtcbiAgICB0aGlzLnZhbGlkYXRlRmV0Y2hUcmFuc2xhdGlvblBhcmFtcyhyZW1vdGVVcmwsIGxvY2FsZSk7XG5cbiAgICBjb25zdCB0YXJnZXRVcmwgPSBsb2NhbGVcbiAgICAgID8gcmVtb3RlVXJsLnJlcGxhY2UoTE9DQUxFX1BMQUNFSE9MREVSX1JFR0VYLCBsb2NhbGUpXG4gICAgICA6IHJlbW90ZVVybDtcblxuICAgIHJldHVybiB0aGlzLnBlcmZvcm1UcmFuc2xhdGlvblJlcXVlc3QodGFyZ2V0VXJsKTtcbiAgfVxuXG4gIC8qKlxuICAgKiDojrflj5bliJ3lp4vor63oqIDnjq/looNcbiAgICovXG4gIHByaXZhdGUgZ2V0SW5pdGlhbExvY2FsZShvcHRpb25zOiBUcmFuc2xhdGVPcHRpb25zKTogc3RyaW5nIHtcbiAgICByZXR1cm4gb3B0aW9ucz8ubG9jYWxlIHx8IGdldFVzZXJMYW5ndWFnZSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIOiOt+WPluWIneWni+e/u+ivkeWIl+ihqFxuICAgKi9cbiAgcHJpdmF0ZSBnZXRJbml0aWFsaXplVHJhbnNsYXRpb25zKFxuICAgIG9wdGlvbnM6IFRyYW5zbGF0ZU9wdGlvbnMsXG4gICAgdHJhbnNsYXRpb25MaXN0OiBUcmFuc2xhdGlvbnNbXSxcbiAgKTogVHJhbnNsYXRpb25zW10ge1xuICAgIHJldHVybiBbb3B0aW9ucz8udHJhbnNsYXRpb25zLCAuLi4odHJhbnNsYXRpb25MaXN0IHx8IFtdKV0uZmlsdGVyKEJvb2xlYW4pO1xuICB9XG5cbiAgLyoqXG4gICAqIOWKoOi9vei/nOeoi+e/u+ivkVxuICAgKi9cbiAgcHJpdmF0ZSBsb2FkUmVtb3RlVHJhbnNsYXRpb25zKG9wdGlvbnM6IFRyYW5zbGF0ZU9wdGlvbnMpOiB2b2lkIHtcbiAgICBpZiAoIW9wdGlvbnM/LnJlbW90ZVVybCkgcmV0dXJuO1xuXG4gICAgY29uc3QgdXJscyA9IEFycmF5LmlzQXJyYXkob3B0aW9ucy5yZW1vdGVVcmwpXG4gICAgICA/IG9wdGlvbnMucmVtb3RlVXJsXG4gICAgICA6IFtvcHRpb25zLnJlbW90ZVVybF07XG5cbiAgICB1cmxzLmZvckVhY2godXJsID0+IHRoaXMuYWRkUmVtb3RlVHJhbnNsYXRpb25zKHVybCkpO1xuICB9XG5cbiAgLyoqXG4gICAqIOi9rOaNouaooeadv+aVsOaNruS4uiBJQ1Ug5YW85a655qC85byPXG4gICAqIEBwYXJhbSBkYXRhIC0g5qih5p2/5pWw5o2uXG4gICAqIEByZXR1cm5zIElDVSDlhbzlrrnnmoTmlbDmja7lr7nosaFcbiAgICovXG4gIHByaXZhdGUgbm9ybWFsaXplQW5kQ29udmVydFRvSWN1RGF0YShkYXRhOiBUZW1wbGF0ZURhdGEpOiBJY3VEYXRhIHtcbiAgICBpZiAoZGF0YSA9PSBudWxsKSB7XG4gICAgICByZXR1cm4ge307XG4gICAgfVxuXG4gICAgLy8g5aaC5p6c5piv57qv5a+56LGh77yM55u05o6l6L2s5o2i5YW25bGe5oCnXG4gICAgaWYgKHRoaXMuaXNQbGFpblRlbXBsYXRlT2JqZWN0KGRhdGEpKSB7XG4gICAgICByZXR1cm4gdGhpcy5jb252ZXJ0T2JqZWN0VG9JY3VEYXRhKGRhdGEpO1xuICAgIH1cblxuICAgIC8vIOWfuuacrOexu+Wei+OAgeaVsOe7hOOAgURhdGXnrYnljIXoo4XkuLogeyB2YWx1ZTogZGF0YSB9XG4gICAgcmV0dXJuIHsgdmFsdWU6IHRoaXMuY29udmVydFZhbHVlVG9JY3VWYWx1ZShkYXRhKSB9O1xuICB9XG5cbiAgLyoqXG4gICAqIOajgOafpeaYr+WQpuS4uue6r+aooeadv+Wvueixoe+8iOS4jeaYr+aVsOe7hOOAgURhdGXnrYnnibnmrorlr7nosaHvvIlcbiAgICovXG4gIHByaXZhdGUgaXNQbGFpblRlbXBsYXRlT2JqZWN0KFxuICAgIGRhdGE6IFRlbXBsYXRlRGF0YSxcbiAgKTogZGF0YSBpcyBSZWNvcmQ8c3RyaW5nLCBUZW1wbGF0ZURhdGE+IHtcbiAgICByZXR1cm4gKFxuICAgICAgdHlwZW9mIGRhdGEgPT09ICdvYmplY3QnICYmXG4gICAgICBkYXRhICE9PSBudWxsICYmXG4gICAgICAhQXJyYXkuaXNBcnJheShkYXRhKSAmJlxuICAgICAgIShkYXRhIGluc3RhbmNlb2YgRGF0ZSkgJiZcbiAgICAgIGRhdGEuY29uc3RydWN0b3IgPT09IE9iamVjdFxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICog6L2s5o2i5a+56LGh55qE5omA5pyJ5bGe5oCn5Li6IElDVSDlhbzlrrnlgLxcbiAgICovXG4gIHByaXZhdGUgY29udmVydE9iamVjdFRvSWN1RGF0YShvYmo6IFJlY29yZDxzdHJpbmcsIFRlbXBsYXRlRGF0YT4pOiBJY3VEYXRhIHtcbiAgICBjb25zdCByZXN1bHQ6IEljdURhdGEgPSB7fTtcblxuICAgIGZvciAoY29uc3QgW2tleSwgdmFsdWVdIG9mIE9iamVjdC5lbnRyaWVzKG9iaikpIHtcbiAgICAgIGlmICh2YWx1ZSAhPSBudWxsKSB7XG4gICAgICAgIHJlc3VsdFtrZXldID0gdGhpcy5jb252ZXJ0VmFsdWVUb0ljdVZhbHVlKHZhbHVlKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgLyoqXG4gICAqIOWwhuWNleS4quWAvOi9rOaNouS4uiBJQ1Ug5YW85a6557G75Z6LXG4gICAqIOaMieeFpyBJQ1UgTWVzc2FnZUZvcm1hdCDop4TojIPvvIzlj6rmlK/mjIEgc3RyaW5nIHwgbnVtYmVyIHwgRGF0ZVxuICAgKi9cbiAgcHJpdmF0ZSBjb252ZXJ0VmFsdWVUb0ljdVZhbHVlKHZhbHVlOiBUZW1wbGF0ZURhdGEpOiBzdHJpbmcgfCBudW1iZXIgfCBEYXRlIHtcbiAgICAvLyBJQ1Ug5Y6f55Sf5pSv5oyB55qE57G75Z6L55u05o6l6L+U5ZueXG4gICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycgfHwgdHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJykge1xuICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH1cblxuICAgIGlmICh2YWx1ZSBpbnN0YW5jZW9mIERhdGUpIHtcbiAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9XG5cbiAgICAvLyDlhbbku5bnsbvlnovovazkuLrlrZfnrKbkuLJcbiAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnYm9vbGVhbicpIHtcbiAgICAgIHJldHVybiBTdHJpbmcodmFsdWUpO1xuICAgIH1cblxuICAgIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgICAgLy8g566A5Y2V5pWw57uE6L2s5Li66YCX5Y+35YiG6ZqU55qE5a2X56ym5LiyXG4gICAgICByZXR1cm4gdmFsdWUubWFwKGl0ZW0gPT4gU3RyaW5nKGl0ZW0gPz8gJycpKS5qb2luKCcsICcpO1xuICAgIH1cblxuICAgIGlmICh2YWx1ZSA9PT0gbnVsbCkge1xuICAgICAgcmV0dXJuICdudWxsJztcbiAgICB9XG5cbiAgICBpZiAodmFsdWUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuICcnO1xuICAgIH1cblxuICAgIC8vIOWvueixoei9rOS4uiBKU09OIOWtl+espuS4slxuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnKSB7XG4gICAgICB0cnkge1xuICAgICAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkodmFsdWUpO1xuICAgICAgfSBjYXRjaCB7XG4gICAgICAgIHJldHVybiBTdHJpbmcodmFsdWUpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBTdHJpbmcodmFsdWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIOWkhOeQhuaooeadv+mUmeivr1xuICAgKi9cbiAgcHJpdmF0ZSBoYW5kbGVUZW1wbGF0ZUVycm9yKGtleTogVHJhbnNsYXRlS2V5LCBlcnJvcjogYW55KTogdm9pZCB7XG4gICAgY29uc3Qga2V5U3RyID0gdHlwZW9mIGtleSA9PT0gJ3N0cmluZycgPyBrZXkgOiAnW29iamVjdF0nO1xuICAgIGNvbnN0IG1lc3NhZ2UgPSBgVGhlIHRyYW5zbGF0aW9uIGtleSAnJHtrZXlTdHJ9JyBpcyBtaXNzaW5nIHRoZSBuZWNlc3NhcnkgcGFyYW1ldGVycy5gO1xuICAgIGlmIChpc0Rldk1vZGUoKSkge1xuICAgICAgY29uc29sZS5lcnJvcihtZXNzYWdlLCBlcnJvcik7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnNvbGUud2FybihtZXNzYWdlLCBlcnJvcik7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIOWwhuS8oOe7n+eahCB7eyBrZXkgfX0g6K+t5rOV6L2s5o2i5Li6IElDVSB7a2V5fSDmoLzlvI9cbiAgICog5ZCM5pe25L+d5oyB5bey5pyJ55qEIElDVSDmoLzlvI/kuI3lj5hcbiAgICogQHBhcmFtIG1lc3NhZ2UgLSDljp/lp4vmtojmga/mqKHmnb9cbiAgICogQHJldHVybnMg6L2s5o2i5ZCO55qEIElDVSDmoLzlvI/mtojmga9cbiAgICovXG4gIHByaXZhdGUgY29udmVydFRvSWN1Rm9ybWF0KG1lc3NhZ2U6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgLy8g5bCGIHt7IGtleSB9fSDovazmjaLkuLoge2tleX1cbiAgICAvLyDmlK/mjIHnqbrmoLzvvJp7eyBrZXkgfX0gLT4ge2tleX3vvIzkvYbljrvmjonlhoXpg6jnmoTnqbrmoLxcbiAgICByZXR1cm4gbWVzc2FnZS5yZXBsYWNlKC9cXHtcXHsoW159XSspXFx9XFx9L2csIChfLCBjb250ZW50KSA9PiB7XG4gICAgICByZXR1cm4gYHske2NvbnRlbnQudHJpbSgpfX1gO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIOS9v+eUqCBJQ1UgbWVzc2FnZSBmb3JtYXQg5qC85byP5YyW5paH5pysXG4gICAqL1xuICBwcml2YXRlIGZvcm1hdEljdU1lc3NhZ2UobWVzc2FnZTogc3RyaW5nLCBpY3VEYXRhOiBJY3VEYXRhKTogc3RyaW5nIHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgbWVzc2FnZUZvcm1hdCA9IG5ldyBJbnRsTWVzc2FnZUZvcm1hdChtZXNzYWdlLCB0aGlzLmxvY2FsZSk7XG4gICAgICByZXR1cm4gbWVzc2FnZUZvcm1hdC5mb3JtYXQoaWN1RGF0YSkgYXMgc3RyaW5nO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBpZiAoaXNEZXZNb2RlKCkpIHtcbiAgICAgICAgY29uc29sZS53YXJuKGBJQ1UgbWVzc2FnZSBmb3JtYXR0aW5nIGZhaWxlZCBmb3IgXCIke21lc3NhZ2V9XCI6YCwgZXJyb3IpO1xuICAgICAgfVxuICAgICAgLy8g6ZmN57qn5aSE55CG77ya6L+U5Zue5Y6f5aeL5raI5oGvXG4gICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICog5qC85byP5YyW5pWw5a2XXG4gICAqIEBwYXJhbSB2YWx1ZSAtIOimgeagvOW8j+WMlueahOaVsOWtl1xuICAgKiBAcGFyYW0gb3B0aW9ucyAtIOagvOW8j+WMlumAiemhuVxuICAgKiBAcmV0dXJucyDmoLzlvI/ljJblkI7nmoTmlbDlrZflrZfnrKbkuLJcbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogZm9ybWF0TnVtYmVyKDEyMzQuNTYpIC8vIFwiMSwyMzQuNTZcIlxuICAgKiBmb3JtYXROdW1iZXIoMC44NSwgeyBzdHlsZTogJ3BlcmNlbnQnIH0pIC8vIFwiODUlXCJcbiAgICogZm9ybWF0TnVtYmVyKDEyMzQuNTYsIHsgc3R5bGU6ICdjdXJyZW5jeScsIGN1cnJlbmN5OiAnQ05ZJyB9KSAvLyBcIsKlMSwyMzQuNTZcIlxuICAgKi9cbiAgZm9ybWF0TnVtYmVyKHZhbHVlOiBudW1iZXIsIG9wdGlvbnM6IEludGwuTnVtYmVyRm9ybWF0T3B0aW9ucyA9IHt9KTogc3RyaW5nIHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIG5ldyBJbnRsLk51bWJlckZvcm1hdCh0aGlzLmxvY2FsZSwgb3B0aW9ucykuZm9ybWF0KHZhbHVlKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgaWYgKGlzRGV2TW9kZSgpKSB7XG4gICAgICAgIGNvbnNvbGUud2FybihgTnVtYmVyIGZvcm1hdHRpbmcgZmFpbGVkIGZvciB2YWx1ZSAke3ZhbHVlfTpgLCBlcnJvcik7XG4gICAgICB9XG4gICAgICByZXR1cm4gdmFsdWUudG9TdHJpbmcoKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICog5qC85byP5YyW6LSn5biBXG4gICAqIEBwYXJhbSB2YWx1ZSAtIOimgeagvOW8j+WMlueahOmHkeminVxuICAgKiBAcGFyYW0gY3VycmVuY3kgLSDotKfluIHku6PnoIHvvIzpu5jorqTkuLogQ05ZXG4gICAqIEBwYXJhbSBvcHRpb25zIC0g5YW25LuW5qC85byP5YyW6YCJ6aG5XG4gICAqIEByZXR1cm5zIOagvOW8j+WMluWQjueahOi0p+W4geWtl+espuS4slxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKiBmb3JtYXRDdXJyZW5jeSgxMjM0LjU2KSAvLyBlbi1VUzogXCJDTsKlMSwyMzQuNTZcIiwgemgtQ046IFwiwqUxLDIzNC41NlwiXG4gICAqIGZvcm1hdEN1cnJlbmN5KDEyMzQuNTYsICdVU0QnKSAvLyBlbi1VUzogXCIkMSwyMzQuNTZcIiwgemgtQ046IFwiVVMkMSwyMzQuNTZcIlxuICAgKi9cbiAgZm9ybWF0Q3VycmVuY3koXG4gICAgdmFsdWU6IG51bWJlcixcbiAgICBjdXJyZW5jeTogc3RyaW5nID0gJ0NOWScsXG4gICAgb3B0aW9uczogT21pdDxJbnRsLk51bWJlckZvcm1hdE9wdGlvbnMsICdzdHlsZScgfCAnY3VycmVuY3knPiA9IHt9LFxuICApOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLmZvcm1hdE51bWJlcih2YWx1ZSwge1xuICAgICAgc3R5bGU6ICdjdXJyZW5jeScsXG4gICAgICBjdXJyZW5jeSxcbiAgICAgIC4uLm9wdGlvbnMsXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICog5qC85byP5YyW55m+5YiG5q+UXG4gICAqIEBwYXJhbSB2YWx1ZSAtIOimgeagvOW8j+WMlueahOWAvO+8iDAuODUg6KGo56S6IDg1Je+8iVxuICAgKiBAcGFyYW0gb3B0aW9ucyAtIOagvOW8j+WMlumAiemhuVxuICAgKiBAcmV0dXJucyDmoLzlvI/ljJblkI7nmoTnmb7liIbmr5TlrZfnrKbkuLJcbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogZm9ybWF0UGVyY2VudCgwLjg1KSAvLyBcIjg1JVwiXG4gICAqIGZvcm1hdFBlcmNlbnQoMC44NTY3LCB7IG1pbmltdW1GcmFjdGlvbkRpZ2l0czogMiB9KSAvLyBcIjg1LjY3JVwiXG4gICAqL1xuICBmb3JtYXRQZXJjZW50KFxuICAgIHZhbHVlOiBudW1iZXIsXG4gICAgb3B0aW9uczogT21pdDxJbnRsLk51bWJlckZvcm1hdE9wdGlvbnMsICdzdHlsZSc+ID0ge30sXG4gICk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMuZm9ybWF0TnVtYmVyKHZhbHVlLCB7XG4gICAgICBzdHlsZTogJ3BlcmNlbnQnLFxuICAgICAgLi4ub3B0aW9ucyxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiDmoLzlvI/ljJbml6XmnJ9cbiAgICogQHBhcmFtIGRhdGUgLSDopoHmoLzlvI/ljJbnmoTml6XmnJ9cbiAgICogQHBhcmFtIG9wdGlvbnMgLSBJbnRsLkRhdGVUaW1lRm9ybWF0T3B0aW9ucyDmoLzlvI/phY3nva5cbiAgICogQHJldHVybnMg5qC85byP5YyW5ZCO55qE5pel5pyf5a2X56ym5LiyXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqIGZvcm1hdERhdGUobmV3IERhdGUoKSkgLy8gZW4tVVM6IFwiMDEvMDEvMjAyNVwiLCB6aC1DTjogXCIyMDI1LzAxLzAxXCJcbiAgICogZm9ybWF0RGF0ZShuZXcgRGF0ZSgpLCB7IGRhdGVTdHlsZTogJ2Z1bGwnIH0pIC8vIFwiMjAyNOW5tDjmnIgyMOaXpeaYn+acn+S6jFwiXG4gICAqIGZvcm1hdERhdGUobmV3IERhdGUoKSwgeyB5ZWFyOiAnbnVtZXJpYycsIG1vbnRoOiAnMi1kaWdpdCcsIGRheTogJzItZGlnaXQnIH0pIC8vIOagueaNrmxvY2FsZeagvOW8j+WMllxuICAgKiBmb3JtYXREYXRlKG5ldyBEYXRlKCksIHsgeWVhcjogJ251bWVyaWMnLCBtb250aDogJ2xvbmcnIH0pIC8vIFwiMjAyNOW5tDjmnIhcIlxuICAgKi9cbiAgZm9ybWF0RGF0ZShcbiAgICBkYXRlOiBEYXRlIHwgc3RyaW5nIHwgbnVtYmVyLFxuICAgIG9wdGlvbnM6IEludGwuRGF0ZVRpbWVGb3JtYXRPcHRpb25zID0ge1xuICAgICAgeWVhcjogJ251bWVyaWMnLFxuICAgICAgbW9udGg6ICcyLWRpZ2l0JyxcbiAgICAgIGRheTogJzItZGlnaXQnLFxuICAgIH0sXG4gICk6IHN0cmluZyB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGRhdGVPYmogPSBuZXcgRGF0ZShkYXRlKTtcbiAgICAgIGlmIChpc05hTihkYXRlT2JqLmdldFRpbWUoKSkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGRhdGUnKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzLmZvcm1hdERhdGVCeU9wdGlvbnMoZGF0ZU9iaiwgb3B0aW9ucyk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGlmIChpc0Rldk1vZGUoKSkge1xuICAgICAgICBjb25zb2xlLndhcm4oYERhdGUgZm9ybWF0dGluZyBmYWlsZWQgZm9yIGRhdGUgJHtkYXRlfTpgLCBlcnJvcik7XG4gICAgICB9XG4gICAgICByZXR1cm4gU3RyaW5nKGRhdGUpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiDmoLzlvI/ljJbml6XmnJ/lkozml7bpl7RcbiAgICogQHBhcmFtIGRhdGUgLSDopoHmoLzlvI/ljJbnmoTml6XmnJ/ml7bpl7RcbiAgICogQHBhcmFtIG9wdGlvbnMgLSBJbnRsLkRhdGVUaW1lRm9ybWF0T3B0aW9ucyDmoLzlvI/phY3nva5cbiAgICogQHJldHVybnMg5qC85byP5YyW5ZCO55qE5pel5pyf5pe26Ze05a2X56ym5LiyXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqIGZvcm1hdERhdGVUaW1lKG5ldyBEYXRlKCkpIC8vIGVuLVVTOiBcIjAxLzAxLzIwMjUsIDE0OjMwOjAwXCIsIHpoLUNOOiBcIjIwMjUvMDEvMDEgMTQ6MzA6MDBcIlxuICAgKiBmb3JtYXREYXRlVGltZShuZXcgRGF0ZSgpLCB7IGRhdGVTdHlsZTogJ21lZGl1bScsIHRpbWVTdHlsZTogJ3Nob3J0JyB9KSAvLyBcIjIwMjTlubQ45pyIMjDml6UgMTQ6MzBcIlxuICAgKiBmb3JtYXREYXRlVGltZShuZXcgRGF0ZSgpLCB7IHllYXI6ICdudW1lcmljJywgbW9udGg6ICcyLWRpZ2l0JywgZGF5OiAnMi1kaWdpdCcsIGhvdXI6ICcyLWRpZ2l0JywgbWludXRlOiAnMi1kaWdpdCcsIHNlY29uZDogJzItZGlnaXQnLCBob3VyMTI6IGZhbHNlIH0pIC8vIOagueaNrmxvY2FsZeagvOW8j+WMllxuICAgKi9cbiAgZm9ybWF0RGF0ZVRpbWUoXG4gICAgZGF0ZTogRGF0ZSB8IHN0cmluZyB8IG51bWJlcixcbiAgICBvcHRpb25zOiBJbnRsLkRhdGVUaW1lRm9ybWF0T3B0aW9ucyA9IHtcbiAgICAgIHllYXI6ICdudW1lcmljJyxcbiAgICAgIG1vbnRoOiAnMi1kaWdpdCcsXG4gICAgICBkYXk6ICcyLWRpZ2l0JyxcbiAgICAgIGhvdXI6ICcyLWRpZ2l0JyxcbiAgICAgIG1pbnV0ZTogJzItZGlnaXQnLFxuICAgICAgc2Vjb25kOiAnMi1kaWdpdCcsXG4gICAgICBob3VyMTI6IGZhbHNlLFxuICAgIH0sXG4gICk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMuZm9ybWF0RGF0ZShkYXRlLCBvcHRpb25zKTtcbiAgfVxuXG4gIC8qKlxuICAgKiDmoLzlvI/ljJbnm7jlr7nml7bpl7RcbiAgICogQHBhcmFtIHZhbHVlIC0g5pe26Ze05beu5YC877yI5pWw5a2X77yJ5oiW5pel5pyf5a+56LGhXG4gICAqIEBwYXJhbSB1bml0IC0g5pe26Ze05Y2V5L2N77yI5b2TdmFsdWXkuLrmlbDlrZfml7blv4Xpobvmj5DkvpvvvIlcbiAgICogQHBhcmFtIG9wdGlvbnMgLSDmoLzlvI/ljJbpgInpoblcbiAgICogQHJldHVybnMg5qC85byP5YyW5ZCO55qE55u45a+55pe26Ze05a2X56ym5LiyXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqIC8vIOaJi+WKqOaMh+WumuWNleS9jVxuICAgKiBmb3JtYXRSZWxhdGl2ZVRpbWUoLTEsICdkYXknKSAvLyBlbi1VUzogXCJ5ZXN0ZXJkYXlcIiwgemgtQ046IFwi5pio5aSpXCJcbiAgICogZm9ybWF0UmVsYXRpdmVUaW1lKDIsICdob3VyJykgLy8gZW4tVVM6IFwiaW4gMiBob3Vyc1wiLCB6aC1DTjogXCIy5bCP5pe25ZCOXCJcbiAgICogZm9ybWF0UmVsYXRpdmVUaW1lKC0zMCwgJ21pbnV0ZScpIC8vIGVuLVVTOiBcIjMwIG1pbnV0ZXMgYWdvXCIsIHpoLUNOOiBcIjMw5YiG6ZKf5YmNXCJcbiAgICpcbiAgICogLy8g6Ieq5Yqo6K6h566X5Y2V5L2NXG4gICAqIGZvcm1hdFJlbGF0aXZlVGltZShuZXcgRGF0ZShEYXRlLm5vdygpIC0gNjAwMDApKSAvLyBcIjEgbWludXRlIGFnb1wiXG4gICAqIGZvcm1hdFJlbGF0aXZlVGltZShuZXcgRGF0ZShEYXRlLm5vdygpICsgNzIwMDAwMCkpIC8vIFwiaW4gMiBob3Vyc1wiXG4gICAqIGZvcm1hdFJlbGF0aXZlVGltZShuZXcgRGF0ZShEYXRlLm5vdygpIC0gODY0MDAwMDApKSAvLyBcInllc3RlcmRheVwiXG4gICAqL1xuICBmb3JtYXRSZWxhdGl2ZVRpbWUoXG4gICAgdmFsdWU6IERhdGUsXG4gICAgb3B0aW9ucz86IEludGwuUmVsYXRpdmVUaW1lRm9ybWF0T3B0aW9ucyxcbiAgKTogc3RyaW5nO1xuXG4gIGZvcm1hdFJlbGF0aXZlVGltZShcbiAgICB2YWx1ZTogbnVtYmVyLFxuICAgIHVuaXQ6IEludGwuUmVsYXRpdmVUaW1lRm9ybWF0VW5pdCxcbiAgICBvcHRpb25zPzogSW50bC5SZWxhdGl2ZVRpbWVGb3JtYXRPcHRpb25zLFxuICApOiBzdHJpbmc7XG5cbiAgZm9ybWF0UmVsYXRpdmVUaW1lKFxuICAgIHZhbHVlOiBudW1iZXIgfCBEYXRlLFxuICAgIHVuaXRPck9wdGlvbnM/OlxuICAgICAgfCBJbnRsLlJlbGF0aXZlVGltZUZvcm1hdFVuaXRcbiAgICAgIHwgSW50bC5SZWxhdGl2ZVRpbWVGb3JtYXRPcHRpb25zLFxuICAgIG9wdGlvbnM6IEludGwuUmVsYXRpdmVUaW1lRm9ybWF0T3B0aW9ucyA9IHsgbnVtZXJpYzogJ2F1dG8nIH0sXG4gICk6IHN0cmluZyB7XG4gICAgdHJ5IHtcbiAgICAgIGxldCBmaW5hbFZhbHVlOiBudW1iZXI7XG4gICAgICBsZXQgZmluYWxVbml0OiBJbnRsLlJlbGF0aXZlVGltZUZvcm1hdFVuaXQ7XG4gICAgICBsZXQgZmluYWxPcHRpb25zOiBJbnRsLlJlbGF0aXZlVGltZUZvcm1hdE9wdGlvbnM7XG5cbiAgICAgIGlmICh2YWx1ZSBpbnN0YW5jZW9mIERhdGUpIHtcbiAgICAgICAgLy8g6Ieq5Yqo6K6h566X5pe26Ze05beu5ZKM5Y2V5L2NXG4gICAgICAgIGNvbnN0IHsgdmFsdWU6IGNhbGN1bGF0ZWRWYWx1ZSwgdW5pdDogY2FsY3VsYXRlZFVuaXQgfSA9XG4gICAgICAgICAgdGhpcy5jYWxjdWxhdGVSZWxhdGl2ZVRpbWUodmFsdWUpO1xuICAgICAgICBmaW5hbFZhbHVlID0gY2FsY3VsYXRlZFZhbHVlO1xuICAgICAgICBmaW5hbFVuaXQgPSBjYWxjdWxhdGVkVW5pdDtcbiAgICAgICAgZmluYWxPcHRpb25zID1cbiAgICAgICAgICAodW5pdE9yT3B0aW9ucyBhcyBJbnRsLlJlbGF0aXZlVGltZUZvcm1hdE9wdGlvbnMpIHx8IG9wdGlvbnM7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyDkvb/nlKjmj5DkvpvnmoTmlbDlgLzlkozljZXkvY1cbiAgICAgICAgZmluYWxWYWx1ZSA9IHZhbHVlO1xuICAgICAgICBmaW5hbFVuaXQgPSB1bml0T3JPcHRpb25zIGFzIEludGwuUmVsYXRpdmVUaW1lRm9ybWF0VW5pdDtcbiAgICAgICAgZmluYWxPcHRpb25zID0gb3B0aW9ucztcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIG5ldyBJbnRsLlJlbGF0aXZlVGltZUZvcm1hdCh0aGlzLmxvY2FsZSwgZmluYWxPcHRpb25zKS5mb3JtYXQoXG4gICAgICAgIGZpbmFsVmFsdWUsXG4gICAgICAgIGZpbmFsVW5pdCxcbiAgICAgICk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGlmIChpc0Rldk1vZGUoKSkge1xuICAgICAgICBjb25zb2xlLndhcm4oYFJlbGF0aXZlIHRpbWUgZm9ybWF0dGluZyBmYWlsZWQgZm9yICR7dmFsdWV9OmAsIGVycm9yKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB2YWx1ZSBpbnN0YW5jZW9mIERhdGVcbiAgICAgICAgPyB2YWx1ZS50b0xvY2FsZVN0cmluZyh0aGlzLmxvY2FsZSlcbiAgICAgICAgOiBgJHt2YWx1ZX1gO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiDmoLnmja7ml6XmnJ/orqHnrpfnm7jlr7nml7bpl7Tlt67lgLzlkozmnIDlkIjpgILnmoTljZXkvY1cbiAgICogQHBhcmFtIGRhdGUgLSDnm67moIfml6XmnJ9cbiAgICogQHJldHVybnMg5YyF5ZCr5pe26Ze05beu5YC85ZKM5Y2V5L2N55qE5a+56LGhXG4gICAqL1xuICBwcml2YXRlIGNhbGN1bGF0ZVJlbGF0aXZlVGltZShkYXRlOiBEYXRlKToge1xuICAgIHZhbHVlOiBudW1iZXI7XG4gICAgdW5pdDogSW50bC5SZWxhdGl2ZVRpbWVGb3JtYXRVbml0O1xuICB9IHtcbiAgICBjb25zdCBub3cgPSBuZXcgRGF0ZSgpO1xuICAgIGNvbnN0IGRpZmZNcyA9IGRhdGUuZ2V0VGltZSgpIC0gbm93LmdldFRpbWUoKTtcbiAgICBjb25zdCBhYnNEaWZmTXMgPSBNYXRoLmFicyhkaWZmTXMpO1xuXG4gICAgLy8g5pe26Ze05Y2V5L2N6ZiI5YC877yI5q+r56eS77yJXG4gICAgY29uc3QgTUlOVVRFX01TID0gNjAgKiAxMDAwO1xuICAgIGNvbnN0IEhPVVJfTVMgPSA2MCAqIE1JTlVURV9NUztcbiAgICBjb25zdCBEQVlfTVMgPSAyNCAqIEhPVVJfTVM7XG5cbiAgICAvLyDmoLnmja7ml7bpl7Tlt67pgInmi6nlkIjpgILnmoTljZXkvY3vvIzmnIDlpKfljZXkvY3kuLpkYXlcbiAgICBpZiAoYWJzRGlmZk1zID49IERBWV9NUykge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdmFsdWU6IE1hdGgucm91bmQoZGlmZk1zIC8gREFZX01TKSxcbiAgICAgICAgdW5pdDogJ2RheScsXG4gICAgICB9O1xuICAgIH1cbiAgICBpZiAoYWJzRGlmZk1zID49IEhPVVJfTVMpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHZhbHVlOiBNYXRoLnJvdW5kKGRpZmZNcyAvIEhPVVJfTVMpLFxuICAgICAgICB1bml0OiAnaG91cicsXG4gICAgICB9O1xuICAgIH1cbiAgICBpZiAoYWJzRGlmZk1zID49IE1JTlVURV9NUykge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdmFsdWU6IE1hdGgucm91bmQoZGlmZk1zIC8gTUlOVVRFX01TKSxcbiAgICAgICAgdW5pdDogJ21pbnV0ZScsXG4gICAgICB9O1xuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgdmFsdWU6IE1hdGgucm91bmQoZGlmZk1zIC8gMTAwMCksXG4gICAgICB1bml0OiAnc2Vjb25kJyxcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIOagueaNruaXpeacn+agvOW8j+mFjee9ruagvOW8j+WMluaXpeacn1xuICAgKiDkvb/nlKjmoIflh4YgSW50bC5EYXRlVGltZUZvcm1hdE9wdGlvbnMg56Gu5L+d5qC85byP5Y+v6aKE5rWL5oCnXG4gICAqL1xuICBwcml2YXRlIGZvcm1hdERhdGVCeU9wdGlvbnMoXG4gICAgZGF0ZTogRGF0ZSxcbiAgICBvcHRpb25zOiBJbnRsLkRhdGVUaW1lRm9ybWF0T3B0aW9ucyxcbiAgKTogc3RyaW5nIHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIG5ldyBJbnRsLkRhdGVUaW1lRm9ybWF0KHRoaXMubG9jYWxlLCBvcHRpb25zKS5mb3JtYXQoZGF0ZSk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGlmIChpc0Rldk1vZGUoKSkge1xuICAgICAgICBjb25zb2xlLndhcm4oYERhdGUgZm9ybWF0dGluZyBmYWlsZWQ6YCwgZXJyb3IpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGRhdGUudG9JU09TdHJpbmcoKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICog6YCa6L+H5a2X56ym5Liy6ZSu6I635Y+W57+76K+RXG4gICAqL1xuICBwcml2YXRlIGdldFRyYW5zbGF0aW9uQnlLZXkoa2V5OiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLnJlc29sdmVUcmFuc2xhdGlvbihrZXkpO1xuICB9XG5cbiAgLyoqXG4gICAqIOmAmui/h+e/u+ivkeWvueixoeiOt+WPlue/u+ivkeWAvFxuICAgKi9cbiAgcHJpdmF0ZSBnZXRUcmFuc2xhdGlvbkJ5T2JqZWN0KFxuICAgIHRyYW5zbGF0aW9uT2JqOiBUcmFuc2xhdGlvbixcbiAgKTogVHJhbnNsYXRpb25WYWx1ZSB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0VHJhbnNsYXRpb25WYWx1ZSh0cmFuc2xhdGlvbk9iaiwgdGhpcy5sb2NhbGUpO1xuICB9XG5cbiAgLyoqXG4gICAqIOWkhOeQhuaXoOaViOivreiogOeOr+Wig1xuICAgKi9cbiAgcHJpdmF0ZSBoYW5kbGVJbnZhbGlkTG9jYWxlKCk6IHZvaWQge1xuICAgIGlmIChpc0Rldk1vZGUoKSkge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignYGxvY2FsZXNgIGhhcyBub3QgYmVlbiBpbml0aWFsaXplZCBjb3JyZWN0bHknKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICog6aqM6K+B6K+t6KiA546v5aKD5piv5ZCm5pyJ5pWIXG4gICAqL1xuICBwcml2YXRlIGlzVmFsaWRMb2NhbGUobG9jYWxlOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5vcHRpb25zLmxvY2FsZXMuaW5jbHVkZXMobG9jYWxlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiDmo4Dmn6Xph43lpI3nv7vor5HvvIjlvIDlj5HmqKHlvI/vvIlcbiAgICovXG4gIHByaXZhdGUgY2hlY2tGb3JEdXBsaWNhdGVUcmFuc2xhdGlvbnMobmV3VHJhbnNsYXRpb25zOiBUcmFuc2xhdGlvbnMpOiB2b2lkIHtcbiAgICBmb3IgKGNvbnN0IGV4aXN0aW5nVHJhbnNsYXRpb25zIG9mIHRoaXMudHJhbnNsYXRpb25zTGlzdCkge1xuICAgICAgT2JqZWN0LmtleXMobmV3VHJhbnNsYXRpb25zKS5mb3JFYWNoKGxvY2FsZSA9PiB7XG4gICAgICAgIGlmIChleGlzdGluZ1RyYW5zbGF0aW9uc1tsb2NhbGVdKSB7XG4gICAgICAgICAgdGhpcy5jb21wYXJlVHJhbnNsYXRpb25LZXlzKFxuICAgICAgICAgICAgbG9jYWxlLFxuICAgICAgICAgICAgbmV3VHJhbnNsYXRpb25zW2xvY2FsZV0sXG4gICAgICAgICAgICBleGlzdGluZ1RyYW5zbGF0aW9uc1tsb2NhbGVdLFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiDmoIflh4bljJbov5znqItVUkxcbiAgICovXG4gIHByaXZhdGUgbm9ybWFsaXplUmVtb3RlVXJsKHJlbW90ZVVybDogc3RyaW5nKTogc3RyaW5nIHtcbiAgICByZW1vdGVVcmwgPSB0aGlzLmNsZWFuVXJsKHJlbW90ZVVybCk7XG4gICAgY29uc3QgaXNBYnNvbHV0ZSA9IGlzQWJzb2x1dGVVcmwocmVtb3RlVXJsKTtcbiAgICBjb25zdCBpc0FwaUdhdGVXYXlSZXF1ZXN0ID0gcmVtb3RlVXJsLnN0YXJ0c1dpdGgoQVBJX0dBVEVXQVkpO1xuXG4gICAgLy8g5byA5Y+R5qih5byP5LiL6L+b6KGMVVJM6aqM6K+BXG4gICAgaWYgKGlzRGV2TW9kZSgpKSB7XG4gICAgICB0aGlzLnZhbGlkYXRlUmVtb3RlVXJsKHJlbW90ZVVybCwgaXNBYnNvbHV0ZSk7XG4gICAgfVxuXG4gICAgLy8g55u45a+5VVJM6L2s5o2i5Li657ud5a+5VVJMXG4gICAgaWYgKCFpc0Fic29sdXRlICYmICFpc0FwaUdhdGVXYXlSZXF1ZXN0KSB7XG4gICAgICBjb25zdCBiYXNlVXJsID0gdGhpcy5iYXNlSHJlZi5lbmRzV2l0aCgnLycpXG4gICAgICAgID8gdGhpcy5iYXNlSHJlZlxuICAgICAgICA6IGAke3RoaXMuYmFzZUhyZWZ9L2A7XG4gICAgICByZXR1cm4gYCR7YmFzZVVybH0ke3JlbW90ZVVybH1gO1xuICAgIH1cblxuICAgIHJldHVybiByZW1vdGVVcmw7XG4gIH1cblxuICAvKipcbiAgICog5riF55CGVVJM77yI56e76ZmkaGFzaOeJh+aute+8iVxuICAgKi9cbiAgcHJpdmF0ZSBjbGVhblVybCh1cmw6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgcmV0dXJuIGhlYWQodXJsLnNwbGl0KC8jLykpIHx8IHVybDtcbiAgfVxuXG4gIC8qKlxuICAgKiDpqozor4Hov5znqItVUkzvvIjlvIDlj5HmqKHlvI/vvIlcbiAgICovXG4gIHByaXZhdGUgdmFsaWRhdGVSZW1vdGVVcmwocmVtb3RlVXJsOiBzdHJpbmcsIGlzQWJzb2x1dGU6IGJvb2xlYW4pOiB2b2lkIHtcbiAgICBpZiAoIWlzQWJzb2x1dGUgJiYgKCF0aGlzLmJhc2VIcmVmIHx8ICFpc0Fic29sdXRlVXJsKHRoaXMuYmFzZUhyZWYpKSkge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcbiAgICAgICAgJ2Fic29sdXRlIGJhc2UgaHJlZiBpcyByZXF1aXJlZCBmb3IgcmVsYXRpdmUgcmVtb3RlIHVybCcsXG4gICAgICApO1xuICAgIH1cblxuICAgIGlmIChyZW1vdGVVcmwuc3BsaXQoJz8nKVswXS5pbmNsdWRlcygnLi8nKSkge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcbiAgICAgICAgJ2RvIG5vdCB1c2UgYW55IGRvdCB3aXRoIHNsYXNoIGZvciByZWxhdGl2ZSB1cmwgd2hpY2ggc2hvdWxkIGFsd2F5cyBiYXNlIGZyb20gYmFzZSBocmVmJyxcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIOWIm+W7uui/nOeoi+e/u+ivkeivt+axglxuICAgKi9cbiAgcHJpdmF0ZSBjcmVhdGVSZW1vdGVUcmFuc2xhdGlvblJlcXVlc3QoXG4gICAgbm9ybWFsaXplZFVybDogc3RyaW5nLFxuICApOiBPYnNlcnZhYmxlPFRyYW5zbGF0aW9ucz4ge1xuICAgIGlmIChMT0NBTEVfUExBQ0VIT0xERVJfUkVHRVgudGVzdChub3JtYWxpemVkVXJsKSkge1xuICAgICAgcmV0dXJuIHRoaXMuY3JlYXRlTXVsdGlMb2NhbGVSZXF1ZXN0KG5vcm1hbGl6ZWRVcmwpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5jcmVhdGVTaW5nbGVMb2NhbGVSZXF1ZXN0KG5vcm1hbGl6ZWRVcmwpO1xuICB9XG5cbiAgLyoqXG4gICAqIOWIm+W7uuWkmuivreiogOivt+axglxuICAgKi9cbiAgcHJpdmF0ZSBjcmVhdGVNdWx0aUxvY2FsZVJlcXVlc3QoXG4gICAgdXJsVGVtcGxhdGU6IHN0cmluZyxcbiAgKTogT2JzZXJ2YWJsZTxUcmFuc2xhdGlvbnM+IHtcbiAgICBjb25zdCByZXF1ZXN0cyA9IHRoaXMub3B0aW9ucy5sb2NhbGVzLm1hcChsb2NhbGUgPT5cbiAgICAgIHRoaXMuZmV0Y2hUcmFuc2xhdGlvbih1cmxUZW1wbGF0ZSwgbG9jYWxlKS5waXBlKFxuICAgICAgICBjYXRjaEVycm9yKGVycm9yID0+IHtcbiAgICAgICAgICBpZiAodGhpcy5vcHRpb25zLmxvb3NlKSB7XG4gICAgICAgICAgICBjb25zdCBsb29zZUxvY2FsZSA9IHRoaXMuZXh0cmFjdExvb3NlTG9jYWxlKGxvY2FsZSk7XG4gICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgIGxvY2FsZSAhPT0gbG9vc2VMb2NhbGUgJiZcbiAgICAgICAgICAgICAgIXRoaXMub3B0aW9ucy5sb2NhbGVzLmluY2x1ZGVzKGxvb3NlTG9jYWxlKVxuICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgIHJldHVybiB0aGlzLmZldGNoVHJhbnNsYXRpb24odXJsVGVtcGxhdGUsIGxvb3NlTG9jYWxlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIGlzRGV2TW9kZSgpID8gdGhyb3dFcnJvcigoKSA9PiBlcnJvcikgOiBFTVBUWTtcbiAgICAgICAgfSksXG4gICAgICAgIGZpbHRlcihpc1BsYWluT2JqZWN0KSxcbiAgICAgICAgbWFwKFxuICAgICAgICAgICh0cmFuc2xhdGlvbjogVHJhbnNsYXRpb24pID0+XG4gICAgICAgICAgICAoeyBbbG9jYWxlXTogdHJhbnNsYXRpb24gfSkgYXMgVHJhbnNsYXRpb25zLFxuICAgICAgICApLFxuICAgICAgKSxcbiAgICApO1xuXG4gICAgcmV0dXJuIGZvcmtKb2luKHJlcXVlc3RzKS5waXBlKFxuICAgICAgbWFwKHJlc3VsdHMgPT5cbiAgICAgICAgcmVzdWx0cy5yZWR1Y2UoKGFjYywgY3VycikgPT4gT2JqZWN0LmFzc2lnbihhY2MsIGN1cnIpLCB7fSksXG4gICAgICApLFxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICog5Yib5bu65Y2V6K+t6KiA6K+35rGCXG4gICAqL1xuICBwcml2YXRlIGNyZWF0ZVNpbmdsZUxvY2FsZVJlcXVlc3QodXJsOiBzdHJpbmcpOiBPYnNlcnZhYmxlPFRyYW5zbGF0aW9ucz4ge1xuICAgIHJldHVybiB0aGlzLnBlcmZvcm1UcmFuc2xhdGlvblJlcXVlc3QodXJsKS5waXBlKFxuICAgICAgY2F0Y2hFcnJvcihlcnJvciA9PiAoaXNEZXZNb2RlKCkgPyB0aHJvd0Vycm9yKCgpID0+IGVycm9yKSA6IEVNUFRZKSksXG4gICAgKSBhcyBPYnNlcnZhYmxlPFRyYW5zbGF0aW9ucz47XG4gIH1cblxuICAvKipcbiAgICog5omn6KGM57+76K+R6K+35rGCXG4gICAqL1xuICBwcml2YXRlIHBlcmZvcm1UcmFuc2xhdGlvblJlcXVlc3QodXJsOiBzdHJpbmcpOiBPYnNlcnZhYmxlPGFueT4ge1xuICAgIGNvbnN0IGlzSlNPTiA9IHVybC5lbmRzV2l0aCgnLmpzb24nKTtcbiAgICBjb25zdCBpc0FwaUdhdGVXYXlSZXF1ZXN0ID0gdXJsLnN0YXJ0c1dpdGgoQVBJX0dBVEVXQVkpO1xuICAgIGNvbnN0IHJlc3BvbnNlVHlwZSA9IGlzSlNPTiA/ICdqc29uJyA6ICd0ZXh0JztcblxuICAgIGlmIChpc0FwaUdhdGVXYXlSZXF1ZXN0KSB7XG4gICAgICByZXR1cm4gdGhpcy5odHRwXG4gICAgICAgIC5yZXF1ZXN0KCdHRVQnLCB1cmwsIHsgcmVzcG9uc2VUeXBlIH0pXG4gICAgICAgIC5waXBlKG1hcChib2R5ID0+IChpc0pTT04gPyBib2R5IDogcGFyc2UoYm9keSkpKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGFqYXgoeyB1cmwsIHJlc3BvbnNlVHlwZSB9KS5waXBlKFxuICAgICAgbWFwKCh7IHJlc3BvbnNlIH0pID0+IChpc0pTT04gPyByZXNwb25zZSA6IHBhcnNlKHJlc3BvbnNlIGFzIHN0cmluZykpKSxcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIOmqjOivgWZldGNoVHJhbnNsYXRpb27lj4LmlbBcbiAgICovXG4gIHByaXZhdGUgdmFsaWRhdGVGZXRjaFRyYW5zbGF0aW9uUGFyYW1zKFxuICAgIHJlbW90ZVVybDogc3RyaW5nLFxuICAgIGxvY2FsZT86IHN0cmluZyxcbiAgKTogdm9pZCB7XG4gICAgaWYgKGlzRGV2TW9kZSgpICYmIExPQ0FMRV9QTEFDRUhPTERFUl9SRUdFWC50ZXN0KHJlbW90ZVVybCkgJiYgIWxvY2FsZSkge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcbiAgICAgICAgJ2Bsb2NhbGVgIGlzIHJlcXVpcmVkIHNpbmNlIHRoZSBwcm92aWRlZCByZW1vdGUgdXJsIGNvbnRhaW5zIGxvY2FsZSBwbGFjZWhvbGRlcicsXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiDop6PmnpDnv7vor5HmlofmnKxcbiAgICovXG4gIHByaXZhdGUgcmVzb2x2ZVRyYW5zbGF0aW9uKGtleTogc3RyaW5nLCBsb2NhbGUgPSB0aGlzLmxvY2FsZSk6IHN0cmluZyB7XG4gICAgLy8g5LyY5YWI5LuO6L+c56iL57+76K+R5Lit5p+l5om+XG4gICAgbGV0IHZhbHVlID0gdGhpcy5zZWFyY2hJblRyYW5zbGF0aW9uc0xpc3QoXG4gICAgICBrZXksXG4gICAgICBsb2NhbGUsXG4gICAgICB0aGlzLnJlbW90ZVRyYW5zbGF0aW9uc0xpc3QsXG4gICAgKTtcblxuICAgIC8vIOWmguaenOi/nOeoi+e/u+ivkeS4reayoeacieaJvuWIsO+8iHVuZGVmaW5lZO+8ie+8jOWImeS7juacrOWcsOe/u+ivkeS4reafpeaJvlxuICAgIGlmICh2YWx1ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICB2YWx1ZSA9IHRoaXMuc2VhcmNoSW5UcmFuc2xhdGlvbnNMaXN0KGtleSwgbG9jYWxlLCB0aGlzLnRyYW5zbGF0aW9uc0xpc3QpO1xuICAgIH1cblxuICAgIHJldHVybiB2YWx1ZSA/PyBrZXk7XG4gIH1cblxuICAvKipcbiAgICog5Zyo57+76K+R5YiX6KGo5Lit5pCc57SiXG4gICAqL1xuICBwcml2YXRlIHNlYXJjaEluVHJhbnNsYXRpb25zTGlzdChcbiAgICBrZXk6IHN0cmluZyxcbiAgICBsb2NhbGU6IHN0cmluZyxcbiAgICB0cmFuc2xhdGlvbnNMaXN0OiBUcmFuc2xhdGlvbnNbXSxcbiAgKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgICBpZiAoIXRyYW5zbGF0aW9uc0xpc3QgfHwgdHJhbnNsYXRpb25zTGlzdC5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgLy8g5LuO5ZCO5b6A5YmN6YGN5Y6G77yI5ZCO5Yqg5YWl55qE5LyY5YWI57qn5pu06auY77yJXG4gICAgZm9yIChsZXQgaSA9IHRyYW5zbGF0aW9uc0xpc3QubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgIGNvbnN0IHZhbHVlID0gdGhpcy5zZWFyY2hJblRyYW5zbGF0aW9ucyhrZXksIGxvY2FsZSwgdHJhbnNsYXRpb25zTGlzdFtpXSk7XG4gICAgICBpZiAodmFsdWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIC8qKlxuICAgKiDlnKjljZXkuKrnv7vor5Hlr7nosaHkuK3mkJzntKJcbiAgICovXG4gIHByaXZhdGUgc2VhcmNoSW5UcmFuc2xhdGlvbnMoXG4gICAga2V5OiBzdHJpbmcsXG4gICAgbG9jYWxlOiBzdHJpbmcsXG4gICAgdHJhbnNsYXRpb25zOiBUcmFuc2xhdGlvbnMsXG4gICk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gICAgY29uc3QgdHJhbnNsYXRpb25WYWx1ZSA9IHRoaXMuZ2V0VHJhbnNsYXRpb25WYWx1ZSh0cmFuc2xhdGlvbnMsIGxvY2FsZSk7XG5cbiAgICAvLyDlpoLmnpzmsqHmnInojrflj5bliLDnv7vor5HlgLzlr7nosaHvvIhnZXRUcmFuc2xhdGlvblZhbHVl5bey57uP5aSE55CG5LqGbG9vc2XlkoxmYWxsYmFja++8ie+8jOebtOaOpei/lOWbnlxuICAgIGlmICh0cmFuc2xhdGlvblZhbHVlID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgLy8g6I635Y+W57+76K+R5YC877yM5pSv5oyB5omB5bmz5ZKM5bWM5aWX5Lik56eN57uT5p6EXG4gICAgY29uc3QgdmFsdWUgPSB0aGlzLmdldFRyYW5zbGF0aW9uRnJvbVNvdXJjZSh0cmFuc2xhdGlvblZhbHVlLCBrZXkpO1xuXG4gICAgLy8g5aaC5p6c5om+5Yiw5YC877yI5YyF5ousbnVsbOWAvO+8ie+8jOWImeWkhOeQhuW5tui/lOWbnlxuICAgIGlmICh2YWx1ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aGlzLnZhbGlkYXRlVHJhbnNsYXRpb25WYWx1ZSh2YWx1ZSwgbG9jYWxlLCBrZXkpO1xuICAgICAgLy8gbnVsbOWAvOi9rOaNouS4uuWtl+espuS4sidudWxsJ++8jOWFtuS7luWAvOato+W4uOi9rOaNolxuICAgICAgcmV0dXJuIHZhbHVlID09PSBudWxsID8gJ251bGwnIDogU3RyaW5nKHZhbHVlKTtcbiAgICB9XG5cbiAgICAvLyDlpoLmnpzlnKjlvZPliY3or63oqIDnmoTnv7vor5HlgLzkuK3mib7kuI3liLBrZXnvvIzkvYbov5nkuI3mmK9mYWxsYmFja+ivreiogO+8jOWwneivlWZhbGxiYWNrXG4gICAgaWYgKGxvY2FsZSAhPT0gdGhpcy5vcHRpb25zLmZhbGxiYWNrTG9jYWxlKSB7XG4gICAgICBjb25zdCBmYWxsYmFja1RyYW5zbGF0aW9uVmFsdWUgPSB0aGlzLmdldFRyYW5zbGF0aW9uVmFsdWUoXG4gICAgICAgIHRyYW5zbGF0aW9ucyxcbiAgICAgICAgdGhpcy5vcHRpb25zLmZhbGxiYWNrTG9jYWxlLFxuICAgICAgKTtcblxuICAgICAgaWYgKGZhbGxiYWNrVHJhbnNsYXRpb25WYWx1ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGNvbnN0IGZhbGxiYWNrVmFsdWUgPSB0aGlzLmdldFRyYW5zbGF0aW9uRnJvbVNvdXJjZShcbiAgICAgICAgICBmYWxsYmFja1RyYW5zbGF0aW9uVmFsdWUsXG4gICAgICAgICAga2V5LFxuICAgICAgICApO1xuICAgICAgICBpZiAoZmFsbGJhY2tWYWx1ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgdGhpcy52YWxpZGF0ZVRyYW5zbGF0aW9uVmFsdWUoXG4gICAgICAgICAgICBmYWxsYmFja1ZhbHVlLFxuICAgICAgICAgICAgdGhpcy5vcHRpb25zLmZhbGxiYWNrTG9jYWxlLFxuICAgICAgICAgICAga2V5LFxuICAgICAgICAgICk7XG4gICAgICAgICAgcmV0dXJuIGZhbGxiYWNrVmFsdWUgPT09IG51bGwgPyAnbnVsbCcgOiBTdHJpbmcoZmFsbGJhY2tWYWx1ZSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbiAgLyoqXG4gICAqIOS7jue/u+ivkea6kOiOt+WPlue/u+ivkeWAvO+8jOaUr+aMgeaJgeW5s+WSjOW1jOWll+S4pOenjee7k+aehFxuICAgKiBAcGFyYW0gc291cmNlIC0g57+76K+R5rqQ5a+56LGhXG4gICAqIEBwYXJhbSBrZXkgLSDnv7vor5HplK7vvIjlpoIgJ2EuYi5jJ++8iVxuICAgKiBAcmV0dXJucyDnv7vor5HlgLzmiJZ1bmRlZmluZWRcbiAgICovXG4gIHByaXZhdGUgZ2V0VHJhbnNsYXRpb25Gcm9tU291cmNlKHNvdXJjZTogYW55LCBrZXk6IHN0cmluZyk6IGFueSB7XG4gICAgaWYgKCFzb3VyY2UgfHwgdHlwZW9mIHNvdXJjZSAhPT0gJ29iamVjdCcpIHtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgLy8gMS4g5LyY5YWI5bCd6K+V5omB5bmz57uT5p6E77ya55u05o6l5p+l5om+5a6M5pW055qE6ZSuICdhLmIuYydcbiAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHNvdXJjZSwga2V5KSkge1xuICAgICAgcmV0dXJuIHNvdXJjZVtrZXldO1xuICAgIH1cblxuICAgIC8vIDIuIOWGjeWwneivleW1jOWll+e7k+aehO+8muS9v+eUqGxvZGFzaC5nZXTmjInot6/lvoTmn6Xmib4gYS5iLmNcbiAgICBjb25zdCBuZXN0ZWRWYWx1ZSA9IGdldChzb3VyY2UsIGtleSk7XG4gICAgaWYgKG5lc3RlZFZhbHVlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiBuZXN0ZWRWYWx1ZTtcbiAgICB9XG5cbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbiAgLyoqXG4gICAqIOiOt+WPluaMh+WumuivreiogOeahOe/u+ivkeWAvO+8iOWkhOeQhmxvb3Nl5qih5byP5ZKMZmFsbGJhY2vpgLvovpHvvIlcbiAgICovXG4gIHByaXZhdGUgZ2V0VHJhbnNsYXRpb25WYWx1ZShcbiAgICBzb3VyY2U6IFRyYW5zbGF0aW9uLFxuICAgIGxvY2FsZSA9IHRoaXMubG9jYWxlLFxuICApOiBUcmFuc2xhdGlvblZhbHVlIHtcbiAgICBpZiAoIXNvdXJjZSkge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICAvLyAxLiDpppblhYjmo4Dmn6Xnsr7noa7ljLnphY3nmoTplK7mmK/lkKblrZjlnKhcbiAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHNvdXJjZSwgbG9jYWxlKSkge1xuICAgICAgcmV0dXJuIHNvdXJjZVtsb2NhbGVdOyAvLyDov5Tlm57lrp7pmYXlgLzvvIzlj6/og73mmK9udWxs44CBdW5kZWZpbmVk5oiW5YW25LuW5YC8XG4gICAgfVxuXG4gICAgLy8gMi4g5aaC5p6c5ZCv55So5LqG5a695p2+5qih5byP77yM5bCd6K+V5a695p2+5Yy56YWNXG4gICAgaWYgKHRoaXMub3B0aW9ucy5sb29zZSkge1xuICAgICAgY29uc3QgbG9vc2VWYWx1ZSA9IHRoaXMuZ2V0TG9vc2VUcmFuc2xhdGlvblZhbHVlKHNvdXJjZSwgbG9jYWxlKTtcbiAgICAgIGlmIChsb29zZVZhbHVlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuIGxvb3NlVmFsdWU7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gMy4g5aaC5p6c5b2T5YmN6K+t6KiA5LiN5pivZmFsbGJhY2vor63oqIDvvIzlsJ3or5VmYWxsYmFja+ivreiogFxuICAgIGlmIChsb2NhbGUgIT09IHRoaXMub3B0aW9ucy5mYWxsYmFja0xvY2FsZSkge1xuICAgICAgLy8g6aaW5YWI5qOA5p+lZmFsbGJhY2vor63oqIDnmoTnsr7noa7ljLnphY1cbiAgICAgIGlmIChcbiAgICAgICAgT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKFxuICAgICAgICAgIHNvdXJjZSxcbiAgICAgICAgICB0aGlzLm9wdGlvbnMuZmFsbGJhY2tMb2NhbGUsXG4gICAgICAgIClcbiAgICAgICkge1xuICAgICAgICByZXR1cm4gc291cmNlW3RoaXMub3B0aW9ucy5mYWxsYmFja0xvY2FsZV07XG4gICAgICB9XG5cbiAgICAgIC8vIOWmguaenOWQr+eUqOS6huWuveadvuaooeW8j++8jOS5n+WvuWZhbGxiYWNr6K+t6KiA6L+b6KGM5a695p2+5Yy56YWNXG4gICAgICBpZiAodGhpcy5vcHRpb25zLmxvb3NlKSB7XG4gICAgICAgIGNvbnN0IGZhbGxiYWNrTG9vc2VWYWx1ZSA9IHRoaXMuZ2V0TG9vc2VUcmFuc2xhdGlvblZhbHVlKFxuICAgICAgICAgIHNvdXJjZSxcbiAgICAgICAgICB0aGlzLm9wdGlvbnMuZmFsbGJhY2tMb2NhbGUsXG4gICAgICAgICk7XG4gICAgICAgIGlmIChmYWxsYmFja0xvb3NlVmFsdWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHJldHVybiBmYWxsYmFja0xvb3NlVmFsdWU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbiAgLyoqXG4gICAqIOWuveadvuaooeW8j+S4i+iOt+WPlue/u+ivkeWAvFxuICAgKi9cbiAgcHJpdmF0ZSBnZXRMb29zZVRyYW5zbGF0aW9uVmFsdWUoXG4gICAgc291cmNlOiBUcmFuc2xhdGlvbixcbiAgICBsb2NhbGU6IHN0cmluZyxcbiAgKTogVHJhbnNsYXRpb25WYWx1ZSB7XG4gICAgY29uc3QgbG9vc2VMb2NhbGUgPSB0aGlzLmV4dHJhY3RMb29zZUxvY2FsZShsb2NhbGUpO1xuXG4gICAgaWYgKGxvY2FsZSA9PT0gbG9vc2VMb2NhbGUpIHtcbiAgICAgIC8vIOWvu+aJvuWMuemFjeeahOWuveadvuivreiogFxuICAgICAgY29uc3QgbWF0Y2hlZEVudHJ5ID0gT2JqZWN0LmVudHJpZXMoc291cmNlKS5maW5kKFxuICAgICAgICAoW2tleV0pID0+IGxvb3NlTG9jYWxlID09PSB0aGlzLmV4dHJhY3RMb29zZUxvY2FsZShrZXkpLFxuICAgICAgKTtcbiAgICAgIHJldHVybiBtYXRjaGVkRW50cnk/LlsxXTtcbiAgICB9XG5cbiAgICAvLyDmo4Dmn6Xlrr3mnb7or63oqIDplK7mmK/lkKblrZjlnKhcbiAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHNvdXJjZSwgbG9vc2VMb2NhbGUpKSB7XG4gICAgICByZXR1cm4gc291cmNlW2xvb3NlTG9jYWxlXTtcbiAgICB9XG5cbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbiAgLyoqXG4gICAqIOaPkOWPluWuveadvuivreiogOS7o+egge+8iOWmgu+8mnpoLUNOIC0+IHpo77yJXG4gICAqL1xuICBwcml2YXRlIGV4dHJhY3RMb29zZUxvY2FsZShsb2NhbGU6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgcmV0dXJuIGhlYWQobG9jYWxlLnNwbGl0KC9bXy1dLykpIHx8IGxvY2FsZTtcbiAgfVxuXG4gIC8qKlxuICAgKiDpqozor4Hnv7vor5HlgLzvvIjlvIDlj5HmqKHlvI/vvIlcbiAgICovXG4gIHByaXZhdGUgdmFsaWRhdGVUcmFuc2xhdGlvblZhbHVlKFxuICAgIHZhbHVlOiBhbnksXG4gICAgbG9jYWxlOiBzdHJpbmcsXG4gICAga2V5OiBzdHJpbmcsXG4gICk6IHZvaWQge1xuICAgIGlmIChcbiAgICAgIGlzRGV2TW9kZSgpICYmXG4gICAgICB0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnICYmXG4gICAgICB0eXBlb2YgZ2V0KHZhbHVlLCBTeW1ib2wudG9QcmltaXRpdmUpICE9PSAnZnVuY3Rpb24nXG4gICAgKSB7XG4gICAgICBjb25zb2xlLndhcm4oXG4gICAgICAgIGBUaGUgdHJhbnNsYXRpb24gZm9yIGxvY2FsZTogXFxgJHtsb2NhbGV9XFxgIGFuZCBrZXk6XFxgJHtrZXl9XFxgIGlzIGFuIG9iamVjdCwgd2hpY2ggY291bGQgYmUgdW5leHBlY3RlZGAsXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiDmr5TovoPnv7vor5HplK7vvIjlvIDlj5HmqKHlvI/kuIvmo4Dmn6Xph43lpI3vvIlcbiAgICovXG4gIHByaXZhdGUgY29tcGFyZVRyYW5zbGF0aW9uS2V5cyhcbiAgICBsb2NhbGU6IHN0cmluZyxcbiAgICB0cmFuc2xhdGlvbjogVHJhbnNsYXRpb24sXG4gICAgcHJldlRyYW5zbGF0aW9uOiBUcmFuc2xhdGlvbixcbiAgICBwYXRoOiBzdHJpbmdbXSA9IFtdLFxuICApOiB2b2lkIHtcbiAgICBpZiAodHJhbnNsYXRpb24gPT0gbnVsbCB8fCBwcmV2VHJhbnNsYXRpb24gPT0gbnVsbCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIE9iamVjdC5lbnRyaWVzKHRyYW5zbGF0aW9uKS5mb3JFYWNoKChba2V5LCB2YWx1ZV0pID0+IHtcbiAgICAgIGlmICghT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHByZXZUcmFuc2xhdGlvbiwga2V5KSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHByZXZWYWx1ZSA9IHByZXZUcmFuc2xhdGlvbltrZXldO1xuICAgICAgY29uc3QgdmFsdWVJc1BsYWluT2JqZWN0ID0gaXNQbGFpbk9iamVjdCh2YWx1ZSk7XG4gICAgICBjb25zdCBwcmV2VmFsdWVJc1BsYWluT2JqZWN0ID0gaXNQbGFpbk9iamVjdChwcmV2VmFsdWUpO1xuXG4gICAgICBpZiAodmFsdWVJc1BsYWluT2JqZWN0ICYmIHByZXZWYWx1ZUlzUGxhaW5PYmplY3QpIHtcbiAgICAgICAgdGhpcy5jb21wYXJlVHJhbnNsYXRpb25LZXlzKFxuICAgICAgICAgIGxvY2FsZSxcbiAgICAgICAgICB2YWx1ZSBhcyBUcmFuc2xhdGlvbixcbiAgICAgICAgICBwcmV2VmFsdWUgYXMgVHJhbnNsYXRpb24sXG4gICAgICAgICAgWy4uLnBhdGgsIGtleV0sXG4gICAgICAgICk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKCF2YWx1ZUlzUGxhaW5PYmplY3QgJiYgIXByZXZWYWx1ZUlzUGxhaW5PYmplY3QpIHtcbiAgICAgICAgY29uc3Qgb3V0cHV0UGF0aCA9IFsuLi5wYXRoLCBrZXldLmpvaW4oJyAtPiAnKTtcbiAgICAgICAgaWYgKHZhbHVlID09PSBwcmV2VmFsdWUpIHtcbiAgICAgICAgICBjb25zb2xlLndhcm4oXG4gICAgICAgICAgICBgVGhlIGN1c3RvbWl6ZWQgdHJhbnNsYXRpb24gZm9yIGxvY2FsZTogXFxgJHtsb2NhbGV9XFxgIGFuZCBwYXRoOiBcXGAke291dHB1dFBhdGh9XFxgIGlzIGR1cGxpY2F0ZWQgd2l0aCB0aGUgb3RoZXIgdHJhbnNsYXRpb24sIHBsZWFzZSByZW1vdmUgaXQgaW4geW91ciB0cmFuc2xhdGlvbiBmaWxlLmAsXG4gICAgICAgICAgKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjb25zb2xlLndhcm4oXG4gICAgICAgICAgICBgVHdvIGtleXMgdGhhdCB0aGUgbG9jYWxlIGlzIFxcYCR7bG9jYWxlfVxcYCBhbmQgdGhlIHBhdGggaXMgXFxgJHtvdXRwdXRQYXRofVxcYCBhcmUgc2FtZSwgYnV0IHRoZWlyIHZhbHVlcyBhcmUgbm90IGVxdWFsLCBwbGVhc2UgcmVtb3ZlIG9uZSBvZiB0aGVtIG9yIGNoYW5nZSBvbmUgb2YgdGhlIGtleXMuYCxcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG4gIH1cbn1cbiJdfQ==
|