ai-text-summary-ng 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +118 -0
- package/ai-text-summary-ng-1.0.0.tgz +0 -0
- package/app/app.component.d.ts +38 -0
- package/app/components/fmode-avatar/fmode-avatar.component.d.ts +16 -0
- package/app/components/fmode-badge/fmode-badge.component.d.ts +8 -0
- package/app/components/fmode-button/fmode-button.component.d.ts +10 -0
- package/app/components/fmode-card/fmode-card.component.d.ts +6 -0
- package/app/components/fmode-digital-human/fmode-digital-human.component.d.ts +10 -0
- package/app/components/fmode-divider/fmode-divider.component.d.ts +7 -0
- package/app/components/fmode-header/fmode-header.component.d.ts +7 -0
- package/app/components/fmode-list/fmode-list.component.d.ts +9 -0
- package/app/components/fmode-loading/fmode-loading.component.d.ts +6 -0
- package/app/components/fmode-select/fmode-select.component.d.ts +17 -0
- package/app/components/fmode-tag/fmode-tag.component.d.ts +9 -0
- package/app/components/fmode-textarea/fmode-textarea.component.d.ts +15 -0
- package/esm2022/ai-text-summary-ng.mjs +5 -0
- package/esm2022/app/app.component.mjs +533 -0
- package/esm2022/app/components/fmode-avatar/fmode-avatar.component.mjs +83 -0
- package/esm2022/app/components/fmode-badge/fmode-badge.component.mjs +49 -0
- package/esm2022/app/components/fmode-button/fmode-button.component.mjs +52 -0
- package/esm2022/app/components/fmode-card/fmode-card.component.mjs +34 -0
- package/esm2022/app/components/fmode-digital-human/fmode-digital-human.component.mjs +119 -0
- package/esm2022/app/components/fmode-divider/fmode-divider.component.mjs +35 -0
- package/esm2022/app/components/fmode-header/fmode-header.component.mjs +33 -0
- package/esm2022/app/components/fmode-list/fmode-list.component.mjs +50 -0
- package/esm2022/app/components/fmode-loading/fmode-loading.component.mjs +25 -0
- package/esm2022/app/components/fmode-select/fmode-select.component.mjs +62 -0
- package/esm2022/app/components/fmode-tag/fmode-tag.component.mjs +54 -0
- package/esm2022/app/components/fmode-textarea/fmode-textarea.component.mjs +75 -0
- package/esm2022/public-api.mjs +15 -0
- package/fesm2022/ai-text-summary-ng.mjs +1155 -0
- package/fesm2022/ai-text-summary-ng.mjs.map +1 -0
- package/index.d.ts +5 -0
- package/package.json +42 -0
- package/public-api.d.ts +13 -0
|
@@ -0,0 +1,533 @@
|
|
|
1
|
+
import { Component } from '@angular/core';
|
|
2
|
+
import { CommonModule } from '@angular/common';
|
|
3
|
+
import { FmodeHeaderComponent } from './components/fmode-header/fmode-header.component';
|
|
4
|
+
import { FmodeCardComponent } from './components/fmode-card/fmode-card.component';
|
|
5
|
+
import { FmodeTextareaComponent } from './components/fmode-textarea/fmode-textarea.component';
|
|
6
|
+
import { FmodeSelectComponent } from './components/fmode-select/fmode-select.component';
|
|
7
|
+
import { FmodeButtonComponent } from './components/fmode-button/fmode-button.component';
|
|
8
|
+
import { FmodeLoadingComponent } from './components/fmode-loading/fmode-loading.component';
|
|
9
|
+
import { FmodeListComponent } from './components/fmode-list/fmode-list.component';
|
|
10
|
+
import { FmodeAvatarComponent } from './components/fmode-avatar/fmode-avatar.component';
|
|
11
|
+
import { FmodeBadgeComponent } from './components/fmode-badge/fmode-badge.component';
|
|
12
|
+
import { FmodeDividerComponent } from './components/fmode-divider/fmode-divider.component';
|
|
13
|
+
import { FmodeTagComponent } from './components/fmode-tag/fmode-tag.component';
|
|
14
|
+
import { FmodeDigitalHumanComponent } from './components/fmode-digital-human/fmode-digital-human.component';
|
|
15
|
+
import * as i0 from "@angular/core";
|
|
16
|
+
import * as i1 from "@angular/common";
|
|
17
|
+
export class AppComponent {
|
|
18
|
+
inputText = '';
|
|
19
|
+
currentSummary = '';
|
|
20
|
+
isLoading = false;
|
|
21
|
+
summaryLength = 'short';
|
|
22
|
+
history = [];
|
|
23
|
+
digitalHumanState = 'waiting';
|
|
24
|
+
digitalHumanSpeech = '等待输入...';
|
|
25
|
+
lengthOptions = [
|
|
26
|
+
{ value: 'short', label: '简短' },
|
|
27
|
+
{ value: 'long', label: '详细' }
|
|
28
|
+
];
|
|
29
|
+
testTexts = [
|
|
30
|
+
{
|
|
31
|
+
id: 1,
|
|
32
|
+
title: '人工智能简介',
|
|
33
|
+
content: '人工智能(Artificial Intelligence,简称AI)是计算机科学的一个分支,它企图了解智能的实质,并生产出一种新的能以人类智能相似的方式做出反应的智能机器。该领域的研究包括机器人、语言识别、图像识别、自然语言处理和专家系统等。人工智能从诞生以来,理论和技术日益成熟,应用领域也不断扩大,可以设想,未来人工智能带来的科技产品,将会是人类智慧的"容器"。人工智能可以对人的意识、思维的信息过程的模拟。人工智能不是人的智能,但能像人那样思考、也可能超过人的智能。'
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
id: 2,
|
|
37
|
+
title: '气候变化与环境保护',
|
|
38
|
+
content: '气候变化是指气候状态的变化,特别是平均天气模式的长期变化,这种变化可能是由自然内部过程或外部强迫引起的,也可能是由于人类活动改变了地球大气的组成。气候变化对人类社会和自然生态系统产生了深远的影响,包括海平面上升、极端天气事件增加、生物多样性减少等。为了应对气候变化,国际社会采取了一系列措施,如减少温室气体排放、发展可再生能源、提高能源效率等。环境保护是指人类为解决现实或潜在的环境问题,协调人类与环境的关系,保障经济社会的可持续发展而采取的各种行动的总称。'
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
id: 3,
|
|
42
|
+
title: '健康生活方式',
|
|
43
|
+
content: '健康的生活方式对于维持身体和心理健康至关重要。这包括均衡的饮食、定期的体育锻炼、充足的睡眠、减少压力以及避免有害习惯如吸烟和过度饮酒。均衡饮食意味着摄入各种营养素,包括蛋白质、碳水化合物、脂肪、维生素和矿物质。定期锻炼可以增强心肺功能、提高肌肉力量和灵活性,并有助于控制体重。充足的睡眠对于身体恢复和大脑功能至关重要。管理压力可以通过冥想、瑜伽、深呼吸或其他放松技巧来实现。避免吸烟和限制酒精摄入可以降低患心脏病、癌症和其他慢性疾病的风险。'
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
id: 4,
|
|
47
|
+
title: '科技创新与未来',
|
|
48
|
+
content: '科技创新是推动社会进步和经济发展的重要动力。近年来,人工智能、大数据、物联网、区块链、量子计算等新兴技术的快速发展,正在深刻改变着我们的生活和工作方式。人工智能正在各个领域得到广泛应用,从智能助手到自动驾驶汽车。大数据分析帮助企业做出更明智的决策。物联网连接了各种设备,使我们的生活更加便捷。区块链技术提供了安全、透明的交易方式。量子计算有望解决传统计算机难以处理的复杂问题。这些技术的发展将继续推动产业升级和社会变革,为未来创造更多可能性。'
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
id: 5,
|
|
52
|
+
title: '教育的重要性',
|
|
53
|
+
content: '教育是人类社会发展的基石,对于个人和社会都具有重要意义。教育不仅传授知识和技能,还培养人的思维能力、创造力和社会责任感。通过教育,个人可以获得更好的就业机会,提高生活质量。对于社会而言,教育可以促进经济发展、减少贫困、提高社会凝聚力。教育还可以培养公民的民主意识和参与能力,促进社会的公平与正义。在当今快速变化的世界中,终身学习变得越来越重要,人们需要不断更新知识和技能以适应社会的发展。因此,投资教育是对未来最好的投资。'
|
|
54
|
+
}
|
|
55
|
+
];
|
|
56
|
+
onInputTextChange(value) {
|
|
57
|
+
console.log('onInputTextChange:', value);
|
|
58
|
+
this.inputText = value;
|
|
59
|
+
}
|
|
60
|
+
onSummaryLengthChange(value) {
|
|
61
|
+
console.log('onSummaryLengthChange:', value);
|
|
62
|
+
this.summaryLength = value;
|
|
63
|
+
}
|
|
64
|
+
loadTestText(index) {
|
|
65
|
+
console.log('Loading test text:', index);
|
|
66
|
+
const testText = this.testTexts[index];
|
|
67
|
+
if (testText) {
|
|
68
|
+
this.inputText = testText.content;
|
|
69
|
+
console.log('Test text loaded:', testText.title);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
async summarizeText() {
|
|
73
|
+
console.log('=== summarizeText called ===');
|
|
74
|
+
console.log('inputText:', this.inputText);
|
|
75
|
+
console.log('inputText.trim():', this.inputText.trim());
|
|
76
|
+
console.log('isLoading:', this.isLoading);
|
|
77
|
+
if (!this.inputText.trim() || this.isLoading) {
|
|
78
|
+
console.log('Early return: empty text or already loading');
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
const text = this.inputText.trim();
|
|
82
|
+
console.log('Text length:', text.length);
|
|
83
|
+
if (text.length < 50) {
|
|
84
|
+
alert('请输入至少50个字符的文本内容');
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
if (text.length > 10000) {
|
|
88
|
+
alert('文本长度不能超过10000个字符');
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
// 数字人状态:开始聆听
|
|
92
|
+
this.digitalHumanState = 'listening';
|
|
93
|
+
this.digitalHumanSpeech = '正在聆听...';
|
|
94
|
+
this.isLoading = true;
|
|
95
|
+
console.log('Starting summary generation...');
|
|
96
|
+
try {
|
|
97
|
+
// 模拟聆听过程
|
|
98
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
99
|
+
// 数字人状态:开始思考
|
|
100
|
+
this.digitalHumanState = 'thinking';
|
|
101
|
+
this.digitalHumanSpeech = '正在思考...';
|
|
102
|
+
const summary = await this.mockAISummary(text, this.summaryLength);
|
|
103
|
+
console.log('Summary generated:', summary);
|
|
104
|
+
// 数字人状态:开始说话
|
|
105
|
+
this.digitalHumanState = 'speaking';
|
|
106
|
+
this.digitalHumanSpeech = '总结完成!';
|
|
107
|
+
this.currentSummary = summary;
|
|
108
|
+
console.log('currentSummary set to:', this.currentSummary);
|
|
109
|
+
const historyItem = {
|
|
110
|
+
id: Date.now(),
|
|
111
|
+
originalText: text,
|
|
112
|
+
summaryText: summary,
|
|
113
|
+
timestamp: new Date()
|
|
114
|
+
};
|
|
115
|
+
this.history.unshift(historyItem);
|
|
116
|
+
if (this.history.length > 10) {
|
|
117
|
+
this.history = this.history.slice(0, 10);
|
|
118
|
+
}
|
|
119
|
+
// 3秒后恢复到等待状态
|
|
120
|
+
setTimeout(() => {
|
|
121
|
+
this.digitalHumanState = 'waiting';
|
|
122
|
+
this.digitalHumanSpeech = '等待输入...';
|
|
123
|
+
}, 3000);
|
|
124
|
+
}
|
|
125
|
+
catch (error) {
|
|
126
|
+
console.error('总结失败:', error);
|
|
127
|
+
alert('总结过程中出现错误,请重试');
|
|
128
|
+
// 错误时恢复到等待状态
|
|
129
|
+
this.digitalHumanState = 'waiting';
|
|
130
|
+
this.digitalHumanSpeech = '等待输入...';
|
|
131
|
+
}
|
|
132
|
+
finally {
|
|
133
|
+
this.isLoading = false;
|
|
134
|
+
console.log('Loading complete');
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
async mockAISummary(text, length) {
|
|
138
|
+
return new Promise((resolve) => {
|
|
139
|
+
setTimeout(() => {
|
|
140
|
+
const sentences = text.split(/[。!?.!?]/).filter((s) => s.trim());
|
|
141
|
+
let summary = '';
|
|
142
|
+
const ratio = length === 'short' ? 0.3 : length === 'medium' ? 0.5 : 0.7;
|
|
143
|
+
const targetCount = Math.max(1, Math.floor(sentences.length * ratio));
|
|
144
|
+
if (sentences.length <= 2) {
|
|
145
|
+
summary = `【智能总结】\n${text}`;
|
|
146
|
+
}
|
|
147
|
+
else {
|
|
148
|
+
const keyPoints = sentences.slice(0, Math.min(3, sentences.length));
|
|
149
|
+
summary = `【智能总结】\n核心要点:\n`;
|
|
150
|
+
keyPoints.forEach((point, index) => {
|
|
151
|
+
summary += `${index + 1}. ${point.trim()}\n`;
|
|
152
|
+
});
|
|
153
|
+
const selectedSentences = sentences.slice(0, targetCount);
|
|
154
|
+
const summaryText = selectedSentences.join('。');
|
|
155
|
+
summary += `\n总结:${summaryText}。`;
|
|
156
|
+
}
|
|
157
|
+
resolve(summary);
|
|
158
|
+
}, 1500);
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
clearInput() {
|
|
162
|
+
this.inputText = '';
|
|
163
|
+
this.currentSummary = '';
|
|
164
|
+
}
|
|
165
|
+
clearHistory() {
|
|
166
|
+
if (confirm('确定要清空所有历史记录吗?')) {
|
|
167
|
+
this.history = [];
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
loadHistoryItem(item) {
|
|
171
|
+
this.inputText = item.originalText;
|
|
172
|
+
this.currentSummary = item.summaryText;
|
|
173
|
+
}
|
|
174
|
+
copySummary() {
|
|
175
|
+
if (this.currentSummary) {
|
|
176
|
+
navigator.clipboard.writeText(this.currentSummary).then(() => {
|
|
177
|
+
alert('已复制到剪贴板');
|
|
178
|
+
}).catch(() => {
|
|
179
|
+
alert('复制失败,请手动复制');
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
formatTime(timestamp) {
|
|
184
|
+
const date = new Date(timestamp);
|
|
185
|
+
const now = new Date();
|
|
186
|
+
const diff = now.getTime() - date.getTime();
|
|
187
|
+
const minutes = Math.floor(diff / 60000);
|
|
188
|
+
const hours = Math.floor(diff / 3600000);
|
|
189
|
+
const days = Math.floor(diff / 86400000);
|
|
190
|
+
if (minutes < 1)
|
|
191
|
+
return '刚刚';
|
|
192
|
+
if (minutes < 60)
|
|
193
|
+
return `${minutes}分钟前`;
|
|
194
|
+
if (hours < 24)
|
|
195
|
+
return `${hours}小时前`;
|
|
196
|
+
if (days < 7)
|
|
197
|
+
return `${days}天前`;
|
|
198
|
+
return date.toLocaleDateString('zh-CN');
|
|
199
|
+
}
|
|
200
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: AppComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
201
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: AppComponent, isStandalone: true, selector: "app-root", ngImport: i0, template: `
|
|
202
|
+
<div class="app-container">
|
|
203
|
+
<fmode-header title="AI 文本智能总结助手" subtitle="基于 fmode-ng UI 组件库"></fmode-header>
|
|
204
|
+
|
|
205
|
+
<div class="main-content">
|
|
206
|
+
<div class="left-panel">
|
|
207
|
+
<fmode-card title="文本输入" class="input-card">
|
|
208
|
+
<div class="input-header">
|
|
209
|
+
<fmode-avatar name="AI" size="large" backgroundColor="#667eea" textColor="#ffffff"></fmode-avatar>
|
|
210
|
+
<div class="input-info">
|
|
211
|
+
<h3>智能文本总结</h3>
|
|
212
|
+
<p>输入长文本,AI 自动生成精简总结</p>
|
|
213
|
+
</div>
|
|
214
|
+
</div>
|
|
215
|
+
|
|
216
|
+
<div class="test-texts-section">
|
|
217
|
+
<h4>测试文本</h4>
|
|
218
|
+
<div class="test-texts-buttons">
|
|
219
|
+
<fmode-button *ngFor="let testText of testTexts; let i = index"
|
|
220
|
+
(onClick)="loadTestText(i)"
|
|
221
|
+
type="secondary"
|
|
222
|
+
size="small"
|
|
223
|
+
>
|
|
224
|
+
{{ testText.title }}
|
|
225
|
+
</fmode-button>
|
|
226
|
+
</div>
|
|
227
|
+
</div>
|
|
228
|
+
|
|
229
|
+
<fmode-divider></fmode-divider>
|
|
230
|
+
|
|
231
|
+
<fmode-textarea
|
|
232
|
+
[value]="inputText"
|
|
233
|
+
(valueChange)="onInputTextChange($event)"
|
|
234
|
+
placeholder="请输入需要总结的长文本内容..."
|
|
235
|
+
[rows]="12"
|
|
236
|
+
[disabled]="isLoading"
|
|
237
|
+
[showCharCount]="true"
|
|
238
|
+
[maxLength]="10000"
|
|
239
|
+
></fmode-textarea>
|
|
240
|
+
|
|
241
|
+
<div class="control-bar">
|
|
242
|
+
<fmode-select
|
|
243
|
+
[value]="summaryLength"
|
|
244
|
+
(valueChange)="onSummaryLengthChange($event)"
|
|
245
|
+
[options]="lengthOptions"
|
|
246
|
+
label="总结长度"
|
|
247
|
+
[disabled]="isLoading"
|
|
248
|
+
></fmode-select>
|
|
249
|
+
|
|
250
|
+
<div class="button-group">
|
|
251
|
+
<fmode-button
|
|
252
|
+
(onClick)="summarizeText()"
|
|
253
|
+
[disabled]="isLoading"
|
|
254
|
+
type="primary"
|
|
255
|
+
>
|
|
256
|
+
智能总结
|
|
257
|
+
</fmode-button>
|
|
258
|
+
<fmode-button
|
|
259
|
+
(onClick)="clearInput()"
|
|
260
|
+
[disabled]="isLoading"
|
|
261
|
+
type="secondary"
|
|
262
|
+
>
|
|
263
|
+
清空
|
|
264
|
+
</fmode-button>
|
|
265
|
+
</div>
|
|
266
|
+
</div>
|
|
267
|
+
</fmode-card>
|
|
268
|
+
|
|
269
|
+
<fmode-card title="历史记录" class="history-card">
|
|
270
|
+
<div class="history-header">
|
|
271
|
+
<div class="history-info">
|
|
272
|
+
<fmode-avatar name="历史" size="small" backgroundColor="#6c757d" textColor="#ffffff"></fmode-avatar>
|
|
273
|
+
<span class="history-count">共 {{ history.length }} 条记录</span>
|
|
274
|
+
</div>
|
|
275
|
+
<fmode-button
|
|
276
|
+
(onClick)="clearHistory()"
|
|
277
|
+
[disabled]="history.length === 0"
|
|
278
|
+
type="danger"
|
|
279
|
+
>
|
|
280
|
+
清空历史
|
|
281
|
+
</fmode-button>
|
|
282
|
+
</div>
|
|
283
|
+
|
|
284
|
+
<fmode-divider></fmode-divider>
|
|
285
|
+
|
|
286
|
+
<div class="history-list">
|
|
287
|
+
<div
|
|
288
|
+
*ngFor="let item of history"
|
|
289
|
+
(click)="loadHistoryItem(item)"
|
|
290
|
+
class="history-item"
|
|
291
|
+
>
|
|
292
|
+
<div class="history-item-header">
|
|
293
|
+
<fmode-avatar [name]="formatTime(item.timestamp)" size="small" backgroundColor="#17a2b8" textColor="#ffffff"></fmode-avatar>
|
|
294
|
+
<div class="history-meta">
|
|
295
|
+
<div class="history-time">{{ formatTime(item.timestamp) }}</div>
|
|
296
|
+
<fmode-tag type="info">{{ item.originalText.length }} 字符</fmode-tag>
|
|
297
|
+
</div>
|
|
298
|
+
</div>
|
|
299
|
+
<div class="history-text">{{ item.originalText.substring(0, 100) }}...</div>
|
|
300
|
+
</div>
|
|
301
|
+
|
|
302
|
+
<div *ngIf="history.length === 0" class="empty-history">
|
|
303
|
+
<fmode-avatar name="空" size="large" backgroundColor="#e9ecef" textColor="#6c757d"></fmode-avatar>
|
|
304
|
+
<p>暂无历史记录</p>
|
|
305
|
+
</div>
|
|
306
|
+
</div>
|
|
307
|
+
</fmode-card>
|
|
308
|
+
</div>
|
|
309
|
+
|
|
310
|
+
<div class="right-panel">
|
|
311
|
+
<fmode-card title="总结结果" class="result-card">
|
|
312
|
+
<div class="result-header">
|
|
313
|
+
<fmode-digital-human
|
|
314
|
+
size="large"
|
|
315
|
+
[state]="digitalHumanState"
|
|
316
|
+
[speechText]="digitalHumanSpeech"
|
|
317
|
+
></fmode-digital-human>
|
|
318
|
+
<div class="result-badges">
|
|
319
|
+
<fmode-badge *ngIf="currentSummary" type="success" [pill]="true">已完成</fmode-badge>
|
|
320
|
+
<fmode-badge *ngIf="!currentSummary" type="secondary" [pill]="true">等待中</fmode-badge>
|
|
321
|
+
</div>
|
|
322
|
+
</div>
|
|
323
|
+
|
|
324
|
+
<fmode-divider></fmode-divider>
|
|
325
|
+
|
|
326
|
+
<div *ngIf="isLoading" class="loading-container">
|
|
327
|
+
<fmode-loading loadingText="正在智能总结中..."></fmode-loading>
|
|
328
|
+
</div>
|
|
329
|
+
|
|
330
|
+
<div *ngIf="!isLoading && !currentSummary" class="empty-result">
|
|
331
|
+
<fmode-avatar name="空" size="xlarge" backgroundColor="#e9ecef" textColor="#6c757d"></fmode-avatar>
|
|
332
|
+
<p>输入文本并点击"智能总结"按钮</p>
|
|
333
|
+
</div>
|
|
334
|
+
|
|
335
|
+
<div *ngIf="!isLoading && currentSummary" class="result-content">
|
|
336
|
+
<pre class="summary-text">{{ currentSummary }}</pre>
|
|
337
|
+
|
|
338
|
+
<fmode-divider></fmode-divider>
|
|
339
|
+
|
|
340
|
+
<div class="result-actions">
|
|
341
|
+
<div class="result-info">
|
|
342
|
+
<fmode-tag type="success">{{ currentSummary.length }} 字符</fmode-tag>
|
|
343
|
+
<fmode-tag type="primary">{{ summaryLength === 'short' ? '简短' : '详细' }}</fmode-tag>
|
|
344
|
+
</div>
|
|
345
|
+
<fmode-button
|
|
346
|
+
(onClick)="copySummary()"
|
|
347
|
+
type="success"
|
|
348
|
+
>
|
|
349
|
+
复制结果
|
|
350
|
+
</fmode-button>
|
|
351
|
+
</div>
|
|
352
|
+
</div>
|
|
353
|
+
</fmode-card>
|
|
354
|
+
</div>
|
|
355
|
+
</div>
|
|
356
|
+
</div>
|
|
357
|
+
`, isInline: true, styles: [".app-container{min-height:100vh;background:linear-gradient(135deg,#f5f7fa,#e4e8eb)}.main-content{max-width:1400px;margin:0 auto;padding:2rem;display:grid;grid-template-columns:1fr 1fr;gap:2rem}.left-panel{display:flex;flex-direction:column;gap:2rem}.input-card{flex:1}.input-header{display:flex;align-items:center;gap:1rem;margin-bottom:1rem}.input-info{flex:1}.input-info h3{margin:0 0 .25rem;color:#495057;font-size:1.25rem}.input-info p{margin:0;color:#6c757d;font-size:.875rem}.test-texts-section{margin:1rem 0}.test-texts-section h4{margin:0 0 .75rem;color:#495057;font-size:1rem}.test-texts-buttons{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:.5rem}.input-badges{display:flex;gap:.5rem}.control-bar{margin-top:1.5rem;display:flex;flex-direction:column;gap:1rem}.button-group{display:flex;gap:1rem}.history-card{flex:1}.history-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:1rem;padding-bottom:1rem;border-bottom:2px solid #e9ecef}.history-info{display:flex;align-items:center;gap:.75rem}.history-count{font-weight:600;color:#495057}.history-list{max-height:300px;overflow-y:auto}.history-item{padding:1rem;border-bottom:1px solid #e9ecef;cursor:pointer;transition:background .3s;display:flex;flex-direction:column;gap:.75rem}.history-item-header{display:flex;align-items:center;gap:.75rem}.history-meta{flex:1;display:flex;flex-direction:column;gap:.25rem}.history-item:hover{background:#f8f9fa}.history-item:last-child{border-bottom:none}.history-time{font-size:.85rem;color:#6c757d}.history-text{color:#495057;line-height:1.5}.empty-history{padding:2rem;text-align:center;color:#6c757d;font-style:italic}.right-panel{display:flex;flex-direction:column}.result-card{flex:1;display:flex;flex-direction:column}.result-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:1rem}.result-badges{display:flex;gap:.5rem}.loading-container{flex:1;display:flex;align-items:center;justify-content:center}.empty-result{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:1rem;color:#6c757d}.result-content{flex:1;display:flex;flex-direction:column}.summary-text{flex:1;background:#f8f9fa;padding:1.5rem;border-radius:8px;border:2px solid #e9ecef;font-family:Courier New,monospace;line-height:1.8;white-space:pre-wrap;word-wrap:break-word;overflow-y:auto;max-height:500px}.result-actions{margin-top:1rem;display:flex;justify-content:space-between;align-items:center}.result-info{display:flex;gap:.5rem}.empty-history{padding:2rem;text-align:center;color:#6c757d;font-style:italic;display:flex;flex-direction:column;align-items:center;gap:1rem}.empty-result{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:1.5rem;color:#6c757d}.empty-icon{font-size:4rem;opacity:.5}@media (max-width: 1024px){.main-content{grid-template-columns:1fr;padding:1rem}.left-panel{order:1}.right-panel{order:2}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: FmodeHeaderComponent, selector: "fmode-header", inputs: ["title", "subtitle"] }, { kind: "component", type: FmodeCardComponent, selector: "fmode-card", inputs: ["title"] }, { kind: "component", type: FmodeTextareaComponent, selector: "fmode-textarea", inputs: ["value", "placeholder", "label", "rows", "disabled", "maxLength", "showCharCount"], outputs: ["valueChange"] }, { kind: "component", type: FmodeSelectComponent, selector: "fmode-select", inputs: ["value", "label", "disabled", "options"], outputs: ["valueChange"] }, { kind: "component", type: FmodeButtonComponent, selector: "fmode-button", inputs: ["disabled", "type", "size"], outputs: ["onClick"] }, { kind: "component", type: FmodeLoadingComponent, selector: "fmode-loading", inputs: ["loadingText"] }, { kind: "component", type: FmodeAvatarComponent, selector: "fmode-avatar", inputs: ["name", "imageUrl", "size", "backgroundColor", "textColor", "alt", "rounded", "clickable"], outputs: ["onClick"] }, { kind: "component", type: FmodeBadgeComponent, selector: "fmode-badge", inputs: ["type", "pill", "outline"] }, { kind: "component", type: FmodeDividerComponent, selector: "fmode-divider", inputs: ["text", "vertical"] }, { kind: "component", type: FmodeTagComponent, selector: "fmode-tag", inputs: ["color", "closable"], outputs: ["onClose"] }, { kind: "component", type: FmodeDigitalHumanComponent, selector: "fmode-digital-human", inputs: ["size", "state", "speechText"] }] });
|
|
358
|
+
}
|
|
359
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: AppComponent, decorators: [{
|
|
360
|
+
type: Component,
|
|
361
|
+
args: [{ selector: 'app-root', standalone: true, imports: [
|
|
362
|
+
CommonModule,
|
|
363
|
+
FmodeHeaderComponent,
|
|
364
|
+
FmodeCardComponent,
|
|
365
|
+
FmodeTextareaComponent,
|
|
366
|
+
FmodeSelectComponent,
|
|
367
|
+
FmodeButtonComponent,
|
|
368
|
+
FmodeLoadingComponent,
|
|
369
|
+
FmodeListComponent,
|
|
370
|
+
FmodeAvatarComponent,
|
|
371
|
+
FmodeBadgeComponent,
|
|
372
|
+
FmodeDividerComponent,
|
|
373
|
+
FmodeTagComponent,
|
|
374
|
+
FmodeDigitalHumanComponent
|
|
375
|
+
], template: `
|
|
376
|
+
<div class="app-container">
|
|
377
|
+
<fmode-header title="AI 文本智能总结助手" subtitle="基于 fmode-ng UI 组件库"></fmode-header>
|
|
378
|
+
|
|
379
|
+
<div class="main-content">
|
|
380
|
+
<div class="left-panel">
|
|
381
|
+
<fmode-card title="文本输入" class="input-card">
|
|
382
|
+
<div class="input-header">
|
|
383
|
+
<fmode-avatar name="AI" size="large" backgroundColor="#667eea" textColor="#ffffff"></fmode-avatar>
|
|
384
|
+
<div class="input-info">
|
|
385
|
+
<h3>智能文本总结</h3>
|
|
386
|
+
<p>输入长文本,AI 自动生成精简总结</p>
|
|
387
|
+
</div>
|
|
388
|
+
</div>
|
|
389
|
+
|
|
390
|
+
<div class="test-texts-section">
|
|
391
|
+
<h4>测试文本</h4>
|
|
392
|
+
<div class="test-texts-buttons">
|
|
393
|
+
<fmode-button *ngFor="let testText of testTexts; let i = index"
|
|
394
|
+
(onClick)="loadTestText(i)"
|
|
395
|
+
type="secondary"
|
|
396
|
+
size="small"
|
|
397
|
+
>
|
|
398
|
+
{{ testText.title }}
|
|
399
|
+
</fmode-button>
|
|
400
|
+
</div>
|
|
401
|
+
</div>
|
|
402
|
+
|
|
403
|
+
<fmode-divider></fmode-divider>
|
|
404
|
+
|
|
405
|
+
<fmode-textarea
|
|
406
|
+
[value]="inputText"
|
|
407
|
+
(valueChange)="onInputTextChange($event)"
|
|
408
|
+
placeholder="请输入需要总结的长文本内容..."
|
|
409
|
+
[rows]="12"
|
|
410
|
+
[disabled]="isLoading"
|
|
411
|
+
[showCharCount]="true"
|
|
412
|
+
[maxLength]="10000"
|
|
413
|
+
></fmode-textarea>
|
|
414
|
+
|
|
415
|
+
<div class="control-bar">
|
|
416
|
+
<fmode-select
|
|
417
|
+
[value]="summaryLength"
|
|
418
|
+
(valueChange)="onSummaryLengthChange($event)"
|
|
419
|
+
[options]="lengthOptions"
|
|
420
|
+
label="总结长度"
|
|
421
|
+
[disabled]="isLoading"
|
|
422
|
+
></fmode-select>
|
|
423
|
+
|
|
424
|
+
<div class="button-group">
|
|
425
|
+
<fmode-button
|
|
426
|
+
(onClick)="summarizeText()"
|
|
427
|
+
[disabled]="isLoading"
|
|
428
|
+
type="primary"
|
|
429
|
+
>
|
|
430
|
+
智能总结
|
|
431
|
+
</fmode-button>
|
|
432
|
+
<fmode-button
|
|
433
|
+
(onClick)="clearInput()"
|
|
434
|
+
[disabled]="isLoading"
|
|
435
|
+
type="secondary"
|
|
436
|
+
>
|
|
437
|
+
清空
|
|
438
|
+
</fmode-button>
|
|
439
|
+
</div>
|
|
440
|
+
</div>
|
|
441
|
+
</fmode-card>
|
|
442
|
+
|
|
443
|
+
<fmode-card title="历史记录" class="history-card">
|
|
444
|
+
<div class="history-header">
|
|
445
|
+
<div class="history-info">
|
|
446
|
+
<fmode-avatar name="历史" size="small" backgroundColor="#6c757d" textColor="#ffffff"></fmode-avatar>
|
|
447
|
+
<span class="history-count">共 {{ history.length }} 条记录</span>
|
|
448
|
+
</div>
|
|
449
|
+
<fmode-button
|
|
450
|
+
(onClick)="clearHistory()"
|
|
451
|
+
[disabled]="history.length === 0"
|
|
452
|
+
type="danger"
|
|
453
|
+
>
|
|
454
|
+
清空历史
|
|
455
|
+
</fmode-button>
|
|
456
|
+
</div>
|
|
457
|
+
|
|
458
|
+
<fmode-divider></fmode-divider>
|
|
459
|
+
|
|
460
|
+
<div class="history-list">
|
|
461
|
+
<div
|
|
462
|
+
*ngFor="let item of history"
|
|
463
|
+
(click)="loadHistoryItem(item)"
|
|
464
|
+
class="history-item"
|
|
465
|
+
>
|
|
466
|
+
<div class="history-item-header">
|
|
467
|
+
<fmode-avatar [name]="formatTime(item.timestamp)" size="small" backgroundColor="#17a2b8" textColor="#ffffff"></fmode-avatar>
|
|
468
|
+
<div class="history-meta">
|
|
469
|
+
<div class="history-time">{{ formatTime(item.timestamp) }}</div>
|
|
470
|
+
<fmode-tag type="info">{{ item.originalText.length }} 字符</fmode-tag>
|
|
471
|
+
</div>
|
|
472
|
+
</div>
|
|
473
|
+
<div class="history-text">{{ item.originalText.substring(0, 100) }}...</div>
|
|
474
|
+
</div>
|
|
475
|
+
|
|
476
|
+
<div *ngIf="history.length === 0" class="empty-history">
|
|
477
|
+
<fmode-avatar name="空" size="large" backgroundColor="#e9ecef" textColor="#6c757d"></fmode-avatar>
|
|
478
|
+
<p>暂无历史记录</p>
|
|
479
|
+
</div>
|
|
480
|
+
</div>
|
|
481
|
+
</fmode-card>
|
|
482
|
+
</div>
|
|
483
|
+
|
|
484
|
+
<div class="right-panel">
|
|
485
|
+
<fmode-card title="总结结果" class="result-card">
|
|
486
|
+
<div class="result-header">
|
|
487
|
+
<fmode-digital-human
|
|
488
|
+
size="large"
|
|
489
|
+
[state]="digitalHumanState"
|
|
490
|
+
[speechText]="digitalHumanSpeech"
|
|
491
|
+
></fmode-digital-human>
|
|
492
|
+
<div class="result-badges">
|
|
493
|
+
<fmode-badge *ngIf="currentSummary" type="success" [pill]="true">已完成</fmode-badge>
|
|
494
|
+
<fmode-badge *ngIf="!currentSummary" type="secondary" [pill]="true">等待中</fmode-badge>
|
|
495
|
+
</div>
|
|
496
|
+
</div>
|
|
497
|
+
|
|
498
|
+
<fmode-divider></fmode-divider>
|
|
499
|
+
|
|
500
|
+
<div *ngIf="isLoading" class="loading-container">
|
|
501
|
+
<fmode-loading loadingText="正在智能总结中..."></fmode-loading>
|
|
502
|
+
</div>
|
|
503
|
+
|
|
504
|
+
<div *ngIf="!isLoading && !currentSummary" class="empty-result">
|
|
505
|
+
<fmode-avatar name="空" size="xlarge" backgroundColor="#e9ecef" textColor="#6c757d"></fmode-avatar>
|
|
506
|
+
<p>输入文本并点击"智能总结"按钮</p>
|
|
507
|
+
</div>
|
|
508
|
+
|
|
509
|
+
<div *ngIf="!isLoading && currentSummary" class="result-content">
|
|
510
|
+
<pre class="summary-text">{{ currentSummary }}</pre>
|
|
511
|
+
|
|
512
|
+
<fmode-divider></fmode-divider>
|
|
513
|
+
|
|
514
|
+
<div class="result-actions">
|
|
515
|
+
<div class="result-info">
|
|
516
|
+
<fmode-tag type="success">{{ currentSummary.length }} 字符</fmode-tag>
|
|
517
|
+
<fmode-tag type="primary">{{ summaryLength === 'short' ? '简短' : '详细' }}</fmode-tag>
|
|
518
|
+
</div>
|
|
519
|
+
<fmode-button
|
|
520
|
+
(onClick)="copySummary()"
|
|
521
|
+
type="success"
|
|
522
|
+
>
|
|
523
|
+
复制结果
|
|
524
|
+
</fmode-button>
|
|
525
|
+
</div>
|
|
526
|
+
</div>
|
|
527
|
+
</fmode-card>
|
|
528
|
+
</div>
|
|
529
|
+
</div>
|
|
530
|
+
</div>
|
|
531
|
+
`, styles: [".app-container{min-height:100vh;background:linear-gradient(135deg,#f5f7fa,#e4e8eb)}.main-content{max-width:1400px;margin:0 auto;padding:2rem;display:grid;grid-template-columns:1fr 1fr;gap:2rem}.left-panel{display:flex;flex-direction:column;gap:2rem}.input-card{flex:1}.input-header{display:flex;align-items:center;gap:1rem;margin-bottom:1rem}.input-info{flex:1}.input-info h3{margin:0 0 .25rem;color:#495057;font-size:1.25rem}.input-info p{margin:0;color:#6c757d;font-size:.875rem}.test-texts-section{margin:1rem 0}.test-texts-section h4{margin:0 0 .75rem;color:#495057;font-size:1rem}.test-texts-buttons{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:.5rem}.input-badges{display:flex;gap:.5rem}.control-bar{margin-top:1.5rem;display:flex;flex-direction:column;gap:1rem}.button-group{display:flex;gap:1rem}.history-card{flex:1}.history-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:1rem;padding-bottom:1rem;border-bottom:2px solid #e9ecef}.history-info{display:flex;align-items:center;gap:.75rem}.history-count{font-weight:600;color:#495057}.history-list{max-height:300px;overflow-y:auto}.history-item{padding:1rem;border-bottom:1px solid #e9ecef;cursor:pointer;transition:background .3s;display:flex;flex-direction:column;gap:.75rem}.history-item-header{display:flex;align-items:center;gap:.75rem}.history-meta{flex:1;display:flex;flex-direction:column;gap:.25rem}.history-item:hover{background:#f8f9fa}.history-item:last-child{border-bottom:none}.history-time{font-size:.85rem;color:#6c757d}.history-text{color:#495057;line-height:1.5}.empty-history{padding:2rem;text-align:center;color:#6c757d;font-style:italic}.right-panel{display:flex;flex-direction:column}.result-card{flex:1;display:flex;flex-direction:column}.result-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:1rem}.result-badges{display:flex;gap:.5rem}.loading-container{flex:1;display:flex;align-items:center;justify-content:center}.empty-result{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:1rem;color:#6c757d}.result-content{flex:1;display:flex;flex-direction:column}.summary-text{flex:1;background:#f8f9fa;padding:1.5rem;border-radius:8px;border:2px solid #e9ecef;font-family:Courier New,monospace;line-height:1.8;white-space:pre-wrap;word-wrap:break-word;overflow-y:auto;max-height:500px}.result-actions{margin-top:1rem;display:flex;justify-content:space-between;align-items:center}.result-info{display:flex;gap:.5rem}.empty-history{padding:2rem;text-align:center;color:#6c757d;font-style:italic;display:flex;flex-direction:column;align-items:center;gap:1rem}.empty-result{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:1.5rem;color:#6c757d}.empty-icon{font-size:4rem;opacity:.5}@media (max-width: 1024px){.main-content{grid-template-columns:1fr;padding:1rem}.left-panel{order:1}.right-panel{order:2}}\n"] }]
|
|
532
|
+
}] });
|
|
533
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBwLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9hcHAvYXBwLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzFDLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMvQyxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSxrREFBa0QsQ0FBQztBQUN4RixPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSw4Q0FBOEMsQ0FBQztBQUNsRixPQUFPLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSxzREFBc0QsQ0FBQztBQUM5RixPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSxrREFBa0QsQ0FBQztBQUN4RixPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSxrREFBa0QsQ0FBQztBQUN4RixPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSxvREFBb0QsQ0FBQztBQUMzRixPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSw4Q0FBOEMsQ0FBQztBQUNsRixPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSxrREFBa0QsQ0FBQztBQUN4RixPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxnREFBZ0QsQ0FBQztBQUNyRixPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSxvREFBb0QsQ0FBQztBQUMzRixPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSw0Q0FBNEMsQ0FBQztBQUMvRSxPQUFPLEVBQUUsMEJBQTBCLEVBQUUsTUFBTSxnRUFBZ0UsQ0FBQzs7O0FBNmM1RyxNQUFNLE9BQU8sWUFBWTtJQUN2QixTQUFTLEdBQUcsRUFBRSxDQUFDO0lBQ2YsY0FBYyxHQUFHLEVBQUUsQ0FBQztJQUNwQixTQUFTLEdBQUcsS0FBSyxDQUFDO0lBQ2xCLGFBQWEsR0FBRyxPQUFPLENBQUM7SUFDeEIsT0FBTyxHQUFxQixFQUFFLENBQUM7SUFDL0IsaUJBQWlCLEdBQXNELFNBQVMsQ0FBQztJQUNqRixrQkFBa0IsR0FBRyxTQUFTLENBQUM7SUFFL0IsYUFBYSxHQUFHO1FBQ2QsRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUU7UUFDL0IsRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUU7S0FDL0IsQ0FBQztJQUVGLFNBQVMsR0FBRztRQUNWO1lBQ0UsRUFBRSxFQUFFLENBQUM7WUFDTCxLQUFLLEVBQUUsUUFBUTtZQUNmLE9BQU8sRUFBRSw4T0FBOE87U0FDeFA7UUFDRDtZQUNFLEVBQUUsRUFBRSxDQUFDO1lBQ0wsS0FBSyxFQUFFLFdBQVc7WUFDbEIsT0FBTyxFQUFFLHVPQUF1TztTQUNqUDtRQUNEO1lBQ0UsRUFBRSxFQUFFLENBQUM7WUFDTCxLQUFLLEVBQUUsUUFBUTtZQUNmLE9BQU8sRUFBRSw4TkFBOE47U0FDeE87UUFDRDtZQUNFLEVBQUUsRUFBRSxDQUFDO1lBQ0wsS0FBSyxFQUFFLFNBQVM7WUFDaEIsT0FBTyxFQUFFLCtOQUErTjtTQUN6TztRQUNEO1lBQ0UsRUFBRSxFQUFFLENBQUM7WUFDTCxLQUFLLEVBQUUsUUFBUTtZQUNmLE9BQU8sRUFBRSxxTkFBcU47U0FDL047S0FDRixDQUFDO0lBRUYsaUJBQWlCLENBQUMsS0FBYTtRQUM3QixPQUFPLENBQUMsR0FBRyxDQUFDLG9CQUFvQixFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQ3pDLElBQUksQ0FBQyxTQUFTLEdBQUcsS0FBSyxDQUFDO0lBQ3pCLENBQUM7SUFFRCxxQkFBcUIsQ0FBQyxLQUFhO1FBQ2pDLE9BQU8sQ0FBQyxHQUFHLENBQUMsd0JBQXdCLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDN0MsSUFBSSxDQUFDLGFBQWEsR0FBRyxLQUFLLENBQUM7SUFDN0IsQ0FBQztJQUVELFlBQVksQ0FBQyxLQUFhO1FBQ3hCLE9BQU8sQ0FBQyxHQUFHLENBQUMsb0JBQW9CLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDekMsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUN2QyxJQUFJLFFBQVEsRUFBRSxDQUFDO1lBQ2IsSUFBSSxDQUFDLFNBQVMsR0FBRyxRQUFRLENBQUMsT0FBTyxDQUFDO1lBQ2xDLE9BQU8sQ0FBQyxHQUFHLENBQUMsbUJBQW1CLEVBQUUsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ25ELENBQUM7SUFDSCxDQUFDO0lBRUQsS0FBSyxDQUFDLGFBQWE7UUFDakIsT0FBTyxDQUFDLEdBQUcsQ0FBQyw4QkFBOEIsQ0FBQyxDQUFDO1FBQzVDLE9BQU8sQ0FBQyxHQUFHLENBQUMsWUFBWSxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUMxQyxPQUFPLENBQUMsR0FBRyxDQUFDLG1CQUFtQixFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQztRQUN4RCxPQUFPLENBQUMsR0FBRyxDQUFDLFlBQVksRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7UUFFMUMsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxFQUFFLElBQUksSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDO1lBQzdDLE9BQU8sQ0FBQyxHQUFHLENBQUMsNkNBQTZDLENBQUMsQ0FBQztZQUMzRCxPQUFPO1FBQ1QsQ0FBQztRQUVELE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDbkMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxjQUFjLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBRXpDLElBQUksSUFBSSxDQUFDLE1BQU0sR0FBRyxFQUFFLEVBQUUsQ0FBQztZQUNyQixLQUFLLENBQUMsaUJBQWlCLENBQUMsQ0FBQztZQUN6QixPQUFPO1FBQ1QsQ0FBQztRQUVELElBQUksSUFBSSxDQUFDLE1BQU0sR0FBRyxLQUFLLEVBQUUsQ0FBQztZQUN4QixLQUFLLENBQUMsa0JBQWtCLENBQUMsQ0FBQztZQUMxQixPQUFPO1FBQ1QsQ0FBQztRQUVELGFBQWE7UUFDYixJQUFJLENBQUMsaUJBQWlCLEdBQUcsV0FBVyxDQUFDO1FBQ3JDLElBQUksQ0FBQyxrQkFBa0IsR0FBRyxTQUFTLENBQUM7UUFDcEMsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUM7UUFDdEIsT0FBTyxDQUFDLEdBQUcsQ0FBQyxnQ0FBZ0MsQ0FBQyxDQUFDO1FBRTlDLElBQUksQ0FBQztZQUNILFNBQVM7WUFDVCxNQUFNLElBQUksT0FBTyxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsVUFBVSxDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDO1lBRXhELGFBQWE7WUFDYixJQUFJLENBQUMsaUJBQWlCLEdBQUcsVUFBVSxDQUFDO1lBQ3BDLElBQUksQ0FBQyxrQkFBa0IsR0FBRyxTQUFTLENBQUM7WUFFcEMsTUFBTSxPQUFPLEdBQUcsTUFBTSxJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUM7WUFDbkUsT0FBTyxDQUFDLEdBQUcsQ0FBQyxvQkFBb0IsRUFBRSxPQUFPLENBQUMsQ0FBQztZQUUzQyxhQUFhO1lBQ2IsSUFBSSxDQUFDLGlCQUFpQixHQUFHLFVBQVUsQ0FBQztZQUNwQyxJQUFJLENBQUMsa0JBQWtCLEdBQUcsT0FBTyxDQUFDO1lBRWxDLElBQUksQ0FBQyxjQUFjLEdBQUcsT0FBTyxDQUFDO1lBQzlCLE9BQU8sQ0FBQyxHQUFHLENBQUMsd0JBQXdCLEVBQUUsSUFBSSxDQUFDLGNBQWMsQ0FBQyxDQUFDO1lBRTNELE1BQU0sV0FBVyxHQUFtQjtnQkFDbEMsRUFBRSxFQUFFLElBQUksQ0FBQyxHQUFHLEVBQUU7Z0JBQ2QsWUFBWSxFQUFFLElBQUk7Z0JBQ2xCLFdBQVcsRUFBRSxPQUFPO2dCQUNwQixTQUFTLEVBQUUsSUFBSSxJQUFJLEVBQUU7YUFDdEIsQ0FBQztZQUVGLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLFdBQVcsQ0FBQyxDQUFDO1lBRWxDLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLEdBQUcsRUFBRSxFQUFFLENBQUM7Z0JBQzdCLElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1lBQzNDLENBQUM7WUFFRCxhQUFhO1lBQ2IsVUFBVSxDQUFDLEdBQUcsRUFBRTtnQkFDZCxJQUFJLENBQUMsaUJBQWlCLEdBQUcsU0FBUyxDQUFDO2dCQUNuQyxJQUFJLENBQUMsa0JBQWtCLEdBQUcsU0FBUyxDQUFDO1lBQ3RDLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQztRQUVYLENBQUM7UUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1lBQ2YsT0FBTyxDQUFDLEtBQUssQ0FBQyxPQUFPLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFDOUIsS0FBSyxDQUFDLGVBQWUsQ0FBQyxDQUFDO1lBRXZCLGFBQWE7WUFDYixJQUFJLENBQUMsaUJBQWlCLEdBQUcsU0FBUyxDQUFDO1lBQ25DLElBQUksQ0FBQyxrQkFBa0IsR0FBRyxTQUFTLENBQUM7UUFDdEMsQ0FBQztnQkFBUyxDQUFDO1lBQ1QsSUFBSSxDQUFDLFNBQVMsR0FBRyxLQUFLLENBQUM7WUFDdkIsT0FBTyxDQUFDLEdBQUcsQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO1FBQ2xDLENBQUM7SUFDSCxDQUFDO0lBRUQsS0FBSyxDQUFDLGFBQWEsQ0FBQyxJQUFZLEVBQUUsTUFBYztRQUM5QyxPQUFPLElBQUksT0FBTyxDQUFDLENBQUMsT0FBTyxFQUFFLEVBQUU7WUFDN0IsVUFBVSxDQUFDLEdBQUcsRUFBRTtnQkFDZCxNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQVMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUM7Z0JBRXpFLElBQUksT0FBTyxHQUFHLEVBQUUsQ0FBQztnQkFDakIsTUFBTSxLQUFLLEdBQUcsTUFBTSxLQUFLLE9BQU8sQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxNQUFNLEtBQUssUUFBUSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQztnQkFDekUsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsTUFBTSxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUM7Z0JBRXRFLElBQUksU0FBUyxDQUFDLE1BQU0sSUFBSSxDQUFDLEVBQUUsQ0FBQztvQkFDMUIsT0FBTyxHQUFHLFdBQVcsSUFBSSxFQUFFLENBQUM7Z0JBQzlCLENBQUM7cUJBQU0sQ0FBQztvQkFDTixNQUFNLFNBQVMsR0FBRyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxTQUFTLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztvQkFDcEUsT0FBTyxHQUFHLGlCQUFpQixDQUFDO29CQUM1QixTQUFTLENBQUMsT0FBTyxDQUFDLENBQUMsS0FBYSxFQUFFLEtBQWEsRUFBRSxFQUFFO3dCQUNqRCxPQUFPLElBQUksR0FBRyxLQUFLLEdBQUcsQ0FBQyxLQUFLLEtBQUssQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDO29CQUMvQyxDQUFDLENBQUMsQ0FBQztvQkFFSCxNQUFNLGlCQUFpQixHQUFHLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLFdBQVcsQ0FBQyxDQUFDO29CQUMxRCxNQUFNLFdBQVcsR0FBRyxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7b0JBQ2hELE9BQU8sSUFBSSxRQUFRLFdBQVcsR0FBRyxDQUFDO2dCQUNwQyxDQUFDO2dCQUVELE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUNuQixDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDWCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRCxVQUFVO1FBQ1IsSUFBSSxDQUFDLFNBQVMsR0FBRyxFQUFFLENBQUM7UUFDcEIsSUFBSSxDQUFDLGNBQWMsR0FBRyxFQUFFLENBQUM7SUFDM0IsQ0FBQztJQUVELFlBQVk7UUFDVixJQUFJLE9BQU8sQ0FBQyxlQUFlLENBQUMsRUFBRSxDQUFDO1lBQzdCLElBQUksQ0FBQyxPQUFPLEdBQUcsRUFBRSxDQUFDO1FBQ3BCLENBQUM7SUFDSCxDQUFDO0lBRUQsZUFBZSxDQUFDLElBQW9CO1FBQ2xDLElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQztRQUNuQyxJQUFJLENBQUMsY0FBYyxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUM7SUFDekMsQ0FBQztJQUVELFdBQVc7UUFDVCxJQUFJLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztZQUN4QixTQUFTLENBQUMsU0FBUyxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRTtnQkFDM0QsS0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUFDO1lBQ25CLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxHQUFHLEVBQUU7Z0JBQ1osS0FBSyxDQUFDLFlBQVksQ0FBQyxDQUFDO1lBQ3RCLENBQUMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQztJQUNILENBQUM7SUFFRCxVQUFVLENBQUMsU0FBZTtRQUN4QixNQUFNLElBQUksR0FBRyxJQUFJLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUNqQyxNQUFNLEdBQUcsR0FBRyxJQUFJLElBQUksRUFBRSxDQUFDO1FBQ3ZCLE1BQU0sSUFBSSxHQUFHLEdBQUcsQ0FBQyxPQUFPLEVBQUUsR0FBRyxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7UUFFNUMsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLEdBQUcsS0FBSyxDQUFDLENBQUM7UUFDekMsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLEdBQUcsT0FBTyxDQUFDLENBQUM7UUFDekMsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLEdBQUcsUUFBUSxDQUFDLENBQUM7UUFFekMsSUFBSSxPQUFPLEdBQUcsQ0FBQztZQUFFLE9BQU8sSUFBSSxDQUFDO1FBQzdCLElBQUksT0FBTyxHQUFHLEVBQUU7WUFBRSxPQUFPLEdBQUcsT0FBTyxLQUFLLENBQUM7UUFDekMsSUFBSSxLQUFLLEdBQUcsRUFBRTtZQUFFLE9BQU8sR0FBRyxLQUFLLEtBQUssQ0FBQztRQUNyQyxJQUFJLElBQUksR0FBRyxDQUFDO1lBQUUsT0FBTyxHQUFHLElBQUksSUFBSSxDQUFDO1FBRWpDLE9BQU8sSUFBSSxDQUFDLGtCQUFrQixDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQzFDLENBQUM7d0dBbE5VLFlBQVk7NEZBQVosWUFBWSxvRUFsYmI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQTRKVCxvOUZBMUtDLFlBQVksZ1FBQ1osb0JBQW9CLHdGQUNwQixrQkFBa0IsMEVBQ2xCLHNCQUFzQixrTEFDdEIsb0JBQW9CLHNJQUNwQixvQkFBb0IscUhBQ3BCLHFCQUFxQixtRkFFckIsb0JBQW9CLG9MQUNwQixtQkFBbUIsNkZBQ25CLHFCQUFxQix3RkFDckIsaUJBQWlCLDJHQUNqQiwwQkFBMEI7OzRGQW9iakIsWUFBWTtrQkFwY3hCLFNBQVM7K0JBQ0UsVUFBVSxjQUNSLElBQUksV0FDUDt3QkFDUCxZQUFZO3dCQUNaLG9CQUFvQjt3QkFDcEIsa0JBQWtCO3dCQUNsQixzQkFBc0I7d0JBQ3RCLG9CQUFvQjt3QkFDcEIsb0JBQW9CO3dCQUNwQixxQkFBcUI7d0JBQ3JCLGtCQUFrQjt3QkFDbEIsb0JBQW9CO3dCQUNwQixtQkFBbUI7d0JBQ25CLHFCQUFxQjt3QkFDckIsaUJBQWlCO3dCQUNqQiwwQkFBMEI7cUJBQzNCLFlBQ1M7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQTRKVCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IEZtb2RlSGVhZGVyQ29tcG9uZW50IH0gZnJvbSAnLi9jb21wb25lbnRzL2Ztb2RlLWhlYWRlci9mbW9kZS1oZWFkZXIuY29tcG9uZW50JztcbmltcG9ydCB7IEZtb2RlQ2FyZENvbXBvbmVudCB9IGZyb20gJy4vY29tcG9uZW50cy9mbW9kZS1jYXJkL2Ztb2RlLWNhcmQuY29tcG9uZW50JztcbmltcG9ydCB7IEZtb2RlVGV4dGFyZWFDb21wb25lbnQgfSBmcm9tICcuL2NvbXBvbmVudHMvZm1vZGUtdGV4dGFyZWEvZm1vZGUtdGV4dGFyZWEuY29tcG9uZW50JztcbmltcG9ydCB7IEZtb2RlU2VsZWN0Q29tcG9uZW50IH0gZnJvbSAnLi9jb21wb25lbnRzL2Ztb2RlLXNlbGVjdC9mbW9kZS1zZWxlY3QuY29tcG9uZW50JztcbmltcG9ydCB7IEZtb2RlQnV0dG9uQ29tcG9uZW50IH0gZnJvbSAnLi9jb21wb25lbnRzL2Ztb2RlLWJ1dHRvbi9mbW9kZS1idXR0b24uY29tcG9uZW50JztcbmltcG9ydCB7IEZtb2RlTG9hZGluZ0NvbXBvbmVudCB9IGZyb20gJy4vY29tcG9uZW50cy9mbW9kZS1sb2FkaW5nL2Ztb2RlLWxvYWRpbmcuY29tcG9uZW50JztcbmltcG9ydCB7IEZtb2RlTGlzdENvbXBvbmVudCB9IGZyb20gJy4vY29tcG9uZW50cy9mbW9kZS1saXN0L2Ztb2RlLWxpc3QuY29tcG9uZW50JztcbmltcG9ydCB7IEZtb2RlQXZhdGFyQ29tcG9uZW50IH0gZnJvbSAnLi9jb21wb25lbnRzL2Ztb2RlLWF2YXRhci9mbW9kZS1hdmF0YXIuY29tcG9uZW50JztcbmltcG9ydCB7IEZtb2RlQmFkZ2VDb21wb25lbnQgfSBmcm9tICcuL2NvbXBvbmVudHMvZm1vZGUtYmFkZ2UvZm1vZGUtYmFkZ2UuY29tcG9uZW50JztcbmltcG9ydCB7IEZtb2RlRGl2aWRlckNvbXBvbmVudCB9IGZyb20gJy4vY29tcG9uZW50cy9mbW9kZS1kaXZpZGVyL2Ztb2RlLWRpdmlkZXIuY29tcG9uZW50JztcbmltcG9ydCB7IEZtb2RlVGFnQ29tcG9uZW50IH0gZnJvbSAnLi9jb21wb25lbnRzL2Ztb2RlLXRhZy9mbW9kZS10YWcuY29tcG9uZW50JztcbmltcG9ydCB7IEZtb2RlRGlnaXRhbEh1bWFuQ29tcG9uZW50IH0gZnJvbSAnLi9jb21wb25lbnRzL2Ztb2RlLWRpZ2l0YWwtaHVtYW4vZm1vZGUtZGlnaXRhbC1odW1hbi5jb21wb25lbnQnO1xuXG5pbnRlcmZhY2UgU3VtbWFyeUhpc3Rvcnkge1xuICBpZDogbnVtYmVyO1xuICBvcmlnaW5hbFRleHQ6IHN0cmluZztcbiAgc3VtbWFyeVRleHQ6IHN0cmluZztcbiAgdGltZXN0YW1wOiBEYXRlO1xufVxuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdhcHAtcm9vdCcsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGltcG9ydHM6IFtcbiAgICBDb21tb25Nb2R1bGUsXG4gICAgRm1vZGVIZWFkZXJDb21wb25lbnQsXG4gICAgRm1vZGVDYXJkQ29tcG9uZW50LFxuICAgIEZtb2RlVGV4dGFyZWFDb21wb25lbnQsXG4gICAgRm1vZGVTZWxlY3RDb21wb25lbnQsXG4gICAgRm1vZGVCdXR0b25Db21wb25lbnQsXG4gICAgRm1vZGVMb2FkaW5nQ29tcG9uZW50LFxuICAgIEZtb2RlTGlzdENvbXBvbmVudCxcbiAgICBGbW9kZUF2YXRhckNvbXBvbmVudCxcbiAgICBGbW9kZUJhZGdlQ29tcG9uZW50LFxuICAgIEZtb2RlRGl2aWRlckNvbXBvbmVudCxcbiAgICBGbW9kZVRhZ0NvbXBvbmVudCxcbiAgICBGbW9kZURpZ2l0YWxIdW1hbkNvbXBvbmVudFxuICBdLFxuICB0ZW1wbGF0ZTogYFxuICAgIDxkaXYgY2xhc3M9XCJhcHAtY29udGFpbmVyXCI+XG4gICAgICA8Zm1vZGUtaGVhZGVyIHRpdGxlPVwiQUkg5paH5pys5pm66IO95oC757uT5Yqp5omLXCIgc3VidGl0bGU9XCLln7rkuo4gZm1vZGUtbmcgVUkg57uE5Lu25bqTXCI+PC9mbW9kZS1oZWFkZXI+XG4gICAgICBcbiAgICAgIDxkaXYgY2xhc3M9XCJtYWluLWNvbnRlbnRcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImxlZnQtcGFuZWxcIj5cbiAgICAgICAgICA8Zm1vZGUtY2FyZCB0aXRsZT1cIuaWh+acrOi+k+WFpVwiIGNsYXNzPVwiaW5wdXQtY2FyZFwiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImlucHV0LWhlYWRlclwiPlxuICAgICAgICAgICAgICA8Zm1vZGUtYXZhdGFyIG5hbWU9XCJBSVwiIHNpemU9XCJsYXJnZVwiIGJhY2tncm91bmRDb2xvcj1cIiM2NjdlZWFcIiB0ZXh0Q29sb3I9XCIjZmZmZmZmXCI+PC9mbW9kZS1hdmF0YXI+XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJpbnB1dC1pbmZvXCI+XG4gICAgICAgICAgICAgICAgPGgzPuaZuuiDveaWh+acrOaAu+e7kzwvaDM+XG4gICAgICAgICAgICAgICAgPHA+6L6T5YWl6ZW/5paH5pys77yMQUkg6Ieq5Yqo55Sf5oiQ57K+566A5oC757uTPC9wPlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGVzdC10ZXh0cy1zZWN0aW9uXCI+XG4gICAgICAgICAgICAgIDxoND7mtYvor5XmlofmnKw8L2g0PlxuICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGVzdC10ZXh0cy1idXR0b25zXCI+XG4gICAgICAgICAgICAgICAgPGZtb2RlLWJ1dHRvbiAqbmdGb3I9XCJsZXQgdGVzdFRleHQgb2YgdGVzdFRleHRzOyBsZXQgaSA9IGluZGV4XCJcbiAgICAgICAgICAgICAgICAgIChvbkNsaWNrKT1cImxvYWRUZXN0VGV4dChpKVwiXG4gICAgICAgICAgICAgICAgICB0eXBlPVwic2Vjb25kYXJ5XCJcbiAgICAgICAgICAgICAgICAgIHNpemU9XCJzbWFsbFwiXG4gICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAge3sgdGVzdFRleHQudGl0bGUgfX1cbiAgICAgICAgICAgICAgICA8L2Ztb2RlLWJ1dHRvbj5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIFxuICAgICAgICAgICAgPGZtb2RlLWRpdmlkZXI+PC9mbW9kZS1kaXZpZGVyPlxuICAgICAgICAgICAgXG4gICAgICAgICAgICA8Zm1vZGUtdGV4dGFyZWFcbiAgICAgICAgICAgICAgW3ZhbHVlXT1cImlucHV0VGV4dFwiXG4gICAgICAgICAgICAgICh2YWx1ZUNoYW5nZSk9XCJvbklucHV0VGV4dENoYW5nZSgkZXZlbnQpXCJcbiAgICAgICAgICAgICAgcGxhY2Vob2xkZXI9XCLor7fovpPlhaXpnIDopoHmgLvnu5PnmoTplb/mlofmnKzlhoXlrrkuLi5cIlxuICAgICAgICAgICAgICBbcm93c109XCIxMlwiXG4gICAgICAgICAgICAgIFtkaXNhYmxlZF09XCJpc0xvYWRpbmdcIlxuICAgICAgICAgICAgICBbc2hvd0NoYXJDb3VudF09XCJ0cnVlXCJcbiAgICAgICAgICAgICAgW21heExlbmd0aF09XCIxMDAwMFwiXG4gICAgICAgICAgICA+PC9mbW9kZS10ZXh0YXJlYT5cbiAgICAgICAgICAgIFxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbnRyb2wtYmFyXCI+XG4gICAgICAgICAgICAgIDxmbW9kZS1zZWxlY3RcbiAgICAgICAgICAgICAgICBbdmFsdWVdPVwic3VtbWFyeUxlbmd0aFwiXG4gICAgICAgICAgICAgICAgKHZhbHVlQ2hhbmdlKT1cIm9uU3VtbWFyeUxlbmd0aENoYW5nZSgkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICBbb3B0aW9uc109XCJsZW5ndGhPcHRpb25zXCJcbiAgICAgICAgICAgICAgICBsYWJlbD1cIuaAu+e7k+mVv+W6plwiXG4gICAgICAgICAgICAgICAgW2Rpc2FibGVkXT1cImlzTG9hZGluZ1wiXG4gICAgICAgICAgICAgID48L2Ztb2RlLXNlbGVjdD5cbiAgICAgICAgICAgICAgXG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJidXR0b24tZ3JvdXBcIj5cbiAgICAgICAgICAgICAgICA8Zm1vZGUtYnV0dG9uXG4gICAgICAgICAgICAgICAgICAob25DbGljayk9XCJzdW1tYXJpemVUZXh0KClcIlxuICAgICAgICAgICAgICAgICAgW2Rpc2FibGVkXT1cImlzTG9hZGluZ1wiXG4gICAgICAgICAgICAgICAgICB0eXBlPVwicHJpbWFyeVwiXG4gICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAg5pm66IO95oC757uTXG4gICAgICAgICAgICAgICAgPC9mbW9kZS1idXR0b24+XG4gICAgICAgICAgICAgICAgPGZtb2RlLWJ1dHRvblxuICAgICAgICAgICAgICAgICAgKG9uQ2xpY2spPVwiY2xlYXJJbnB1dCgpXCJcbiAgICAgICAgICAgICAgICAgIFtkaXNhYmxlZF09XCJpc0xvYWRpbmdcIlxuICAgICAgICAgICAgICAgICAgdHlwZT1cInNlY29uZGFyeVwiXG4gICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAg5riF56m6XG4gICAgICAgICAgICAgICAgPC9mbW9kZS1idXR0b24+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC9mbW9kZS1jYXJkPlxuICAgICAgICAgIFxuICAgICAgICAgIDxmbW9kZS1jYXJkIHRpdGxlPVwi5Y6G5Y+y6K6w5b2VXCIgY2xhc3M9XCJoaXN0b3J5LWNhcmRcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJoaXN0b3J5LWhlYWRlclwiPlxuICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaGlzdG9yeS1pbmZvXCI+XG4gICAgICAgICAgICAgICAgPGZtb2RlLWF2YXRhciBuYW1lPVwi5Y6G5Y+yXCIgc2l6ZT1cInNtYWxsXCIgYmFja2dyb3VuZENvbG9yPVwiIzZjNzU3ZFwiIHRleHRDb2xvcj1cIiNmZmZmZmZcIj48L2Ztb2RlLWF2YXRhcj5cbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImhpc3RvcnktY291bnRcIj7lhbEge3sgaGlzdG9yeS5sZW5ndGggfX0g5p2h6K6w5b2VPC9zcGFuPlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgPGZtb2RlLWJ1dHRvblxuICAgICAgICAgICAgICAgIChvbkNsaWNrKT1cImNsZWFySGlzdG9yeSgpXCJcbiAgICAgICAgICAgICAgICBbZGlzYWJsZWRdPVwiaGlzdG9yeS5sZW5ndGggPT09IDBcIlxuICAgICAgICAgICAgICAgIHR5cGU9XCJkYW5nZXJcIlxuICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAg5riF56m65Y6G5Y+yXG4gICAgICAgICAgICAgIDwvZm1vZGUtYnV0dG9uPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICBcbiAgICAgICAgICAgIDxmbW9kZS1kaXZpZGVyPjwvZm1vZGUtZGl2aWRlcj5cbiAgICAgICAgICAgIFxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImhpc3RvcnktbGlzdFwiPlxuICAgICAgICAgICAgICA8ZGl2IFxuICAgICAgICAgICAgICAgICpuZ0Zvcj1cImxldCBpdGVtIG9mIGhpc3RvcnlcIlxuICAgICAgICAgICAgICAgIChjbGljayk9XCJsb2FkSGlzdG9yeUl0ZW0oaXRlbSlcIlxuICAgICAgICAgICAgICAgIGNsYXNzPVwiaGlzdG9yeS1pdGVtXCJcbiAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJoaXN0b3J5LWl0ZW0taGVhZGVyXCI+XG4gICAgICAgICAgICAgICAgICA8Zm1vZGUtYXZhdGFyIFtuYW1lXT1cImZvcm1hdFRpbWUoaXRlbS50aW1lc3RhbXApXCIgc2l6ZT1cInNtYWxsXCIgYmFja2dyb3VuZENvbG9yPVwiIzE3YTJiOFwiIHRleHRDb2xvcj1cIiNmZmZmZmZcIj48L2Ztb2RlLWF2YXRhcj5cbiAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJoaXN0b3J5LW1ldGFcIj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImhpc3RvcnktdGltZVwiPnt7IGZvcm1hdFRpbWUoaXRlbS50aW1lc3RhbXApIH19PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDxmbW9kZS10YWcgdHlwZT1cImluZm9cIj57eyBpdGVtLm9yaWdpbmFsVGV4dC5sZW5ndGggfX0g5a2X56ymPC9mbW9kZS10YWc+XG4gICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaGlzdG9yeS10ZXh0XCI+e3sgaXRlbS5vcmlnaW5hbFRleHQuc3Vic3RyaW5nKDAsIDEwMCkgfX0uLi48L2Rpdj5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgIFxuICAgICAgICAgICAgICA8ZGl2ICpuZ0lmPVwiaGlzdG9yeS5sZW5ndGggPT09IDBcIiBjbGFzcz1cImVtcHR5LWhpc3RvcnlcIj5cbiAgICAgICAgICAgICAgICA8Zm1vZGUtYXZhdGFyIG5hbWU9XCLnqbpcIiBzaXplPVwibGFyZ2VcIiBiYWNrZ3JvdW5kQ29sb3I9XCIjZTllY2VmXCIgdGV4dENvbG9yPVwiIzZjNzU3ZFwiPjwvZm1vZGUtYXZhdGFyPlxuICAgICAgICAgICAgICAgIDxwPuaaguaXoOWOhuWPsuiusOW9lTwvcD5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L2Ztb2RlLWNhcmQ+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICBcbiAgICAgICAgPGRpdiBjbGFzcz1cInJpZ2h0LXBhbmVsXCI+XG4gICAgICAgICAgPGZtb2RlLWNhcmQgdGl0bGU9XCLmgLvnu5Pnu5PmnpxcIiBjbGFzcz1cInJlc3VsdC1jYXJkXCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwicmVzdWx0LWhlYWRlclwiPlxuICAgICAgICAgICAgICA8Zm1vZGUtZGlnaXRhbC1odW1hbiBcbiAgICAgICAgICAgICAgICBzaXplPVwibGFyZ2VcIiBcbiAgICAgICAgICAgICAgICBbc3RhdGVdPVwiZGlnaXRhbEh1bWFuU3RhdGVcIiBcbiAgICAgICAgICAgICAgICBbc3BlZWNoVGV4dF09XCJkaWdpdGFsSHVtYW5TcGVlY2hcIlxuICAgICAgICAgICAgICA+PC9mbW9kZS1kaWdpdGFsLWh1bWFuPlxuICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicmVzdWx0LWJhZGdlc1wiPlxuICAgICAgICAgICAgICAgIDxmbW9kZS1iYWRnZSAqbmdJZj1cImN1cnJlbnRTdW1tYXJ5XCIgdHlwZT1cInN1Y2Nlc3NcIiBbcGlsbF09XCJ0cnVlXCI+5bey5a6M5oiQPC9mbW9kZS1iYWRnZT5cbiAgICAgICAgICAgICAgICA8Zm1vZGUtYmFkZ2UgKm5nSWY9XCIhY3VycmVudFN1bW1hcnlcIiB0eXBlPVwic2Vjb25kYXJ5XCIgW3BpbGxdPVwidHJ1ZVwiPuetieW+heS4rTwvZm1vZGUtYmFkZ2U+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICBcbiAgICAgICAgICAgIDxmbW9kZS1kaXZpZGVyPjwvZm1vZGUtZGl2aWRlcj5cbiAgICAgICAgICAgIFxuICAgICAgICAgICAgPGRpdiAqbmdJZj1cImlzTG9hZGluZ1wiIGNsYXNzPVwibG9hZGluZy1jb250YWluZXJcIj5cbiAgICAgICAgICAgICAgPGZtb2RlLWxvYWRpbmcgbG9hZGluZ1RleHQ9XCLmraPlnKjmmbrog73mgLvnu5PkuK0uLi5cIj48L2Ztb2RlLWxvYWRpbmc+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIFxuICAgICAgICAgICAgPGRpdiAqbmdJZj1cIiFpc0xvYWRpbmcgJiYgIWN1cnJlbnRTdW1tYXJ5XCIgY2xhc3M9XCJlbXB0eS1yZXN1bHRcIj5cbiAgICAgICAgICAgICAgPGZtb2RlLWF2YXRhciBuYW1lPVwi56m6XCIgc2l6ZT1cInhsYXJnZVwiIGJhY2tncm91bmRDb2xvcj1cIiNlOWVjZWZcIiB0ZXh0Q29sb3I9XCIjNmM3NTdkXCI+PC9mbW9kZS1hdmF0YXI+XG4gICAgICAgICAgICAgIDxwPui+k+WFpeaWh+acrOW5tueCueWHu1wi5pm66IO95oC757uTXCLmjInpkq48L3A+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIFxuICAgICAgICAgICAgPGRpdiAqbmdJZj1cIiFpc0xvYWRpbmcgJiYgY3VycmVudFN1bW1hcnlcIiBjbGFzcz1cInJlc3VsdC1jb250ZW50XCI+XG4gICAgICAgICAgICAgIDxwcmUgY2xhc3M9XCJzdW1tYXJ5LXRleHRcIj57eyBjdXJyZW50U3VtbWFyeSB9fTwvcHJlPlxuICAgICAgICAgICAgICBcbiAgICAgICAgICAgICAgPGZtb2RlLWRpdmlkZXI+PC9mbW9kZS1kaXZpZGVyPlxuICAgICAgICAgICAgICBcbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInJlc3VsdC1hY3Rpb25zXCI+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInJlc3VsdC1pbmZvXCI+XG4gICAgICAgICAgICAgICAgICA8Zm1vZGUtdGFnIHR5cGU9XCJzdWNjZXNzXCI+e3sgY3VycmVudFN1bW1hcnkubGVuZ3RoIH19IOWtl+espjwvZm1vZGUtdGFnPlxuICAgICAgICAgICAgICAgICAgPGZtb2RlLXRhZyB0eXBlPVwicHJpbWFyeVwiPnt7IHN1bW1hcnlMZW5ndGggPT09ICdzaG9ydCcgPyAn566A55+tJyA6ICfor6bnu4YnIH19PC9mbW9kZS10YWc+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPGZtb2RlLWJ1dHRvblxuICAgICAgICAgICAgICAgICAgKG9uQ2xpY2spPVwiY29weVN1bW1hcnkoKVwiXG4gICAgICAgICAgICAgICAgICB0eXBlPVwic3VjY2Vzc1wiXG4gICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAg5aSN5Yi257uT5p6cXG4gICAgICAgICAgICAgICAgPC9mbW9kZS1idXR0b24+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC9mbW9kZS1jYXJkPlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuICBgLFxuICBzdHlsZXM6IFtgXG4gICAgLmFwcC1jb250YWluZXIge1xuICAgICAgbWluLWhlaWdodDogMTAwdmg7XG4gICAgICBiYWNrZ3JvdW5kOiBsaW5lYXItZ3JhZGllbnQoMTM1ZGVnLCAjZjVmN2ZhIDAlLCAjZTRlOGViIDEwMCUpO1xuICAgIH1cblxuICAgIC5tYWluLWNvbnRlbnQge1xuICAgICAgbWF4LXdpZHRoOiAxNDAwcHg7XG4gICAgICBtYXJnaW46IDAgYXV0bztcbiAgICAgIHBhZGRpbmc6IDJyZW07XG4gICAgICBkaXNwbGF5OiBncmlkO1xuICAgICAgZ3JpZC10ZW1wbGF0ZS1jb2x1bW5zOiAxZnIgMWZyO1xuICAgICAgZ2FwOiAycmVtO1xuICAgIH1cblxuICAgIC5sZWZ0LXBhbmVsIHtcbiAgICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgICBmbGV4LWRpcmVjdGlvbjogY29sdW1uO1xuICAgICAgZ2FwOiAycmVtO1xuICAgIH1cblxuICAgIC5pbnB1dC1jYXJkIHtcbiAgICAgIGZsZXg6IDE7XG4gICAgfVxuXG4gICAgLmlucHV0LWhlYWRlciB7XG4gICAgICBkaXNwbGF5OiBmbGV4O1xuICAgICAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgICAgIGdhcDogMXJlbTtcbiAgICAgIG1hcmdpbi1ib3R0b206IDFyZW07XG4gICAgfVxuXG4gICAgLmlucHV0LWluZm8ge1xuICAgICAgZmxleDogMTtcbiAgICB9XG5cbiAgICAuaW5wdXQtaW5mbyBoMyB7XG4gICAgICBtYXJnaW46IDAgMCAwLjI1cmVtIDA7XG4gICAgICBjb2xvcjogIzQ5NTA1NztcbiAgICAgIGZvbnQtc2l6ZTogMS4yNXJlbTtcbiAgICB9XG5cbiAgICAuaW5wdXQtaW5mbyBwIHtcbiAgICAgIG1hcmdpbjogMDtcbiAgICAgIGNvbG9yOiAjNmM3NTdkO1xuICAgICAgZm9udC1zaXplOiAwLjg3NXJlbTtcbiAgICB9XG5cbiAgICAudGVzdC10ZXh0cy1zZWN0aW9uIHtcbiAgICAgIG1hcmdpbjogMXJlbSAwO1xuICAgIH1cblxuICAgIC50ZXN0LXRleHRzLXNlY3Rpb24gaDQge1xuICAgICAgbWFyZ2luOiAwIDAgMC43NXJlbSAwO1xuICAgICAgY29sb3I6ICM0OTUwNTc7XG4gICAgICBmb250LXNpemU6IDFyZW07XG4gICAgfVxuXG4gICAgLnRlc3QtdGV4dHMtYnV0dG9ucyB7XG4gICAgICBkaXNwbGF5OiBncmlkO1xuICAgICAgZ3JpZC10ZW1wbGF0ZS1jb2x1bW5zOiByZXBlYXQoYXV0by1maXQsIG1pbm1heCgxNTBweCwgMWZyKSk7XG4gICAgICBnYXA6IDAuNXJlbTtcbiAgICB9XG5cbiAgICAuaW5wdXQtYmFkZ2VzIHtcbiAgICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgICBnYXA6IDAuNXJlbTtcbiAgICB9XG5cbiAgICAuY29udHJvbC1iYXIge1xuICAgICAgbWFyZ2luLXRvcDogMS41cmVtO1xuICAgICAgZGlzcGxheTogZmxleDtcbiAgICAgIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XG4gICAgICBnYXA6IDFyZW07XG4gICAgfVxuXG4gICAgLmJ1dHRvbi1ncm91cCB7XG4gICAgICBkaXNwbGF5OiBmbGV4O1xuICAgICAgZ2FwOiAxcmVtO1xuICAgIH1cblxuICAgIC5oaXN0b3J5LWNhcmQge1xuICAgICAgZmxleDogMTtcbiAgICB9XG5cbiAgICAuaGlzdG9yeS1oZWFkZXIge1xuICAgICAgZGlzcGxheTogZmxleDtcbiAgICAgIGp1c3RpZnktY29udGVudDogc3BhY2UtYmV0d2VlbjtcbiAgICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gICAgICBtYXJnaW4tYm90dG9tOiAxcmVtO1xuICAgICAgcGFkZGluZy1ib3R0b206IDFyZW07XG4gICAgICBib3JkZXItYm90dG9tOiAycHggc29saWQgI2U5ZWNlZjtcbiAgICB9XG5cbiAgICAuaGlzdG9yeS1pbmZvIHtcbiAgICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgICBhbGlnbi1pdGVtczogY2VudGVyO1xuICAgICAgZ2FwOiAwLjc1cmVtO1xuICAgIH1cblxuICAgIC5oaXN0b3J5LWNvdW50IHtcbiAgICAgIGZvbnQtd2VpZ2h0OiA2MDA7XG4gICAgICBjb2xvcjogIzQ5NTA1NztcbiAgICB9XG5cbiAgICAuaGlzdG9yeS1saXN0IHtcbiAgICAgIG1heC1oZWlnaHQ6IDMwMHB4O1xuICAgICAgb3ZlcmZsb3cteTogYXV0bztcbiAgICB9XG5cbiAgICAuaGlzdG9yeS1pdGVtIHtcbiAgICAgIHBhZGRpbmc6IDFyZW07XG4gICAgICBib3JkZXItYm90dG9tOiAxcHggc29saWQgI2U5ZWNlZjtcbiAgICAgIGN1cnNvcjogcG9pbnRlcjtcbiAgICAgIHRyYW5zaXRpb246IGJhY2tncm91bmQgMC4zcztcbiAgICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgICBmbGV4LWRpcmVjdGlvbjogY29sdW1uO1xuICAgICAgZ2FwOiAwLjc1cmVtO1xuICAgIH1cblxuICAgIC5oaXN0b3J5LWl0ZW0taGVhZGVyIHtcbiAgICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgICBhbGlnbi1pdGVtczogY2VudGVyO1xuICAgICAgZ2FwOiAwLjc1cmVtO1xuICAgIH1cblxuICAgIC5oaXN0b3J5LW1ldGEge1xuICAgICAgZmxleDogMTtcbiAgICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgICBmbGV4LWRpcmVjdGlvbjogY29sdW1uO1xuICAgICAgZ2FwOiAwLjI1cmVtO1xuICAgIH1cblxuICAgIC5oaXN0b3J5LWl0ZW06aG92ZXIge1xuICAgICAgYmFja2dyb3VuZDogI2Y4ZjlmYTtcbiAgICB9XG5cbiAgICAuaGlzdG9yeS1pdGVtOmxhc3QtY2hpbGQge1xuICAgICAgYm9yZGVyLWJvdHRvbTogbm9uZTtcbiAgICB9XG5cbiAgICAuaGlzdG9yeS10aW1lIHtcbiAgICAgIGZvbnQtc2l6ZTogMC44NXJlbTtcbiAgICAgIGNvbG9yOiAjNmM3NTdkO1xuICAgIH1cblxuICAgIC5oaXN0b3J5LXRleHQge1xuICAgICAgY29sb3I6ICM0OTUwNTc7XG4gICAgICBsaW5lLWhlaWdodDogMS41O1xuICAgIH1cblxuICAgIC5lbXB0eS1oaXN0b3J5IHtcbiAgICAgIHBhZGRpbmc6IDJyZW07XG4gICAgICB0ZXh0LWFsaWduOiBjZW50ZXI7XG4gICAgICBjb2xvcjogIzZjNzU3ZDtcbiAgICAgIGZvbnQtc3R5bGU6IGl0YWxpYztcbiAgICB9XG5cbiAgICAucmlnaHQtcGFuZWwge1xuICAgICAgZGlzcGxheTogZmxleDtcbiAgICAgIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XG4gICAgfVxuXG4gICAgLnJlc3VsdC1jYXJkIHtcbiAgICAgIGZsZXg6IDE7XG4gICAgICBkaXNwbGF5OiBmbGV4O1xuICAgICAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcbiAgICB9XG5cbiAgICAucmVzdWx0LWhlYWRlciB7XG4gICAgICBkaXNwbGF5OiBmbGV4O1xuICAgICAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgICAgIGp1c3RpZnktY29udGVudDogc3BhY2UtYmV0d2VlbjtcbiAgICAgIG1hcmdpbi1ib3R0b206IDFyZW07XG4gICAgfVxuXG4gICAgLnJlc3VsdC1iYWRnZXMge1xuICAgICAgZGlzcGxheTogZmxleDtcbiAgICAgIGdhcDogMC41cmVtO1xuICAgIH1cblxuICAgIC5sb2FkaW5nLWNvbnRhaW5lciB7XG4gICAgICBmbGV4OiAxO1xuICAgICAgZGlzcGxheTogZmxleDtcbiAgICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gICAgICBqdXN0aWZ5LWNvbnRlbnQ6IGNlbnRlcjtcbiAgICB9XG5cbiAgICAuZW1wdHktcmVzdWx0IHtcbiAgICAgIGZsZXg6IDE7XG4gICAgICBkaXNwbGF5OiBmbGV4O1xuICAgICAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcbiAgICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gICAgICBqdXN0aWZ5LWNvbnRlbnQ6IGNlbnRlcjtcbiAgICAgIGdhcDogMXJlbTtcbiAgICAgIGNvbG9yOiAjNmM3NTdkO1xuICAgIH1cblxuICAgIC5lbXB0eS1pY29uIHtcbiAgICAgIGZvbnQtc2l6ZTogNHJlbTtcbiAgICAgIG9wYWNpdHk6IDAuNTtcbiAgICB9XG5cbiAgICAucmVzdWx0LWNvbnRlbnQge1xuICAgICAgZmxleDogMTtcbiAgICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgICBmbGV4LWRpcmVjdGlvbjogY29sdW1uO1xuICAgIH1cblxuICAgIC5zdW1tYXJ5LXRleHQge1xuICAgICAgZmxleDogMTtcbiAgICAgIGJhY2tncm91bmQ6ICNmOGY5ZmE7XG4gICAgICBwYWRkaW5nOiAxLjVyZW07XG4gICAgICBib3JkZXItcmFkaXVzOiA4cHg7XG4gICAgICBib3JkZXI6IDJweCBzb2xpZCAjZTllY2VmO1xuICAgICAgZm9udC1mYW1pbHk6ICdDb3VyaWVyIE5ldycsIG1vbm9zcGFjZTtcbiAgICAgIGxpbmUtaGVpZ2h0OiAxLjg7XG4gICAgICB3aGl0ZS1zcGFjZTogcHJlLXdyYXA7XG4gICAgICB3b3JkLXdyYXA6IGJyZWFrLXdvcmQ7XG4gICAgICBvdmVyZmxvdy15OiBhdXRvO1xuICAgICAgbWF4LWhlaWdodDogNTAwcHg7XG4gICAgfVxuXG4gICAgLnJlc3VsdC1hY3Rpb25zIHtcbiAgICAgIG1hcmdpbi10b3A6IDFyZW07XG4gICAgICBkaXNwbGF5OiBmbGV4O1xuICAgICAganVzdGlmeS1jb250ZW50OiBzcGFjZS1iZXR3ZWVuO1xuICAgICAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgICB9XG5cbiAgICAucmVzdWx0LWluZm8ge1xuICAgICAgZGlzcGxheTogZmxleDtcbiAgICAgIGdhcDogMC41cmVtO1xuICAgIH1cblxuICAgIC5lbXB0eS1oaXN0b3J5IHtcbiAgICAgIHBhZGRpbmc6IDJyZW07XG4gICAgICB0ZXh0LWFsaWduOiBjZW50ZXI7XG4gICAgICBjb2xvcjogIzZjNzU3ZDtcbiAgICAgIGZvbnQtc3R5bGU6IGl0YWxpYztcbiAgICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgICBmbGV4LWRpcmVjdGlvbjogY29sdW1uO1xuICAgICAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgICAgIGdhcDogMXJlbTtcbiAgICB9XG5cbiAgICAuZW1wdHktcmVzdWx0IHtcbiAgICAgIGZsZXg6IDE7XG4gICAgICBkaXNwbGF5OiBmbGV4O1xuICAgICAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcbiAgICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gICAgICBqdXN0aWZ5LWNvbnRlbnQ6IGNlbnRlcjtcbiAgICAgIGdhcDogMS41cmVtO1xuICAgICAgY29sb3I6ICM2Yzc1N2Q7XG4gICAgfVxuXG4gICAgLmVtcHR5LWljb24ge1xuICAgICAgZm9udC1zaXplOiA0cmVtO1xuICAgICAgb3BhY2l0eTogMC41O1xuICAgIH1cblxuICAgIEBtZWRpYSAobWF4LXdpZHRoOiAxMDI0cHgpIHtcbiAgICAgIC5tYWluLWNvbnRlbnQge1xuICAgICAgICBncmlkLXRlbXBsYXRlLWNvbHVtbnM6IDFmcjtcbiAgICAgICAgcGFkZGluZzogMXJlbTtcbiAgICAgIH1cblxuICAgICAgLmxlZnQtcGFuZWwge1xuICAgICAgICBvcmRlcjogMTtcbiAgICAgIH1cblxuICAgICAgLnJpZ2h0LXBhbmVsIHtcbiAgICAgICAgb3JkZXI6IDI7XG4gICAgICB9XG4gICAgfVxuICBgXVxufSlcbmV4cG9ydCBjbGFzcyBBcHBDb21wb25lbnQge1xuICBpbnB1dFRleHQgPSAnJztcbiAgY3VycmVudFN1bW1hcnkgPSAnJztcbiAgaXNMb2FkaW5nID0gZmFsc2U7XG4gIHN1bW1hcnlMZW5ndGggPSAnc2hvcnQnO1xuICBoaXN0b3J5OiBTdW1tYXJ5SGlzdG9yeVtdID0gW107XG4gIGRpZ2l0YWxIdW1hblN0YXRlOiAnd2FpdGluZycgfCAnbGlzdGVuaW5nJyB8ICd0aGlua2luZycgfCAnc3BlYWtpbmcnID0gJ3dhaXRpbmcnO1xuICBkaWdpdGFsSHVtYW5TcGVlY2ggPSAn562J5b6F6L6T5YWlLi4uJztcblxuICBsZW5ndGhPcHRpb25zID0gW1xuICAgIHsgdmFsdWU6ICdzaG9ydCcsIGxhYmVsOiAn566A55+tJyB9LFxuICAgIHsgdmFsdWU6ICdsb25nJywgbGFiZWw6ICfor6bnu4YnIH1cbiAgXTtcblxuICB0ZXN0VGV4dHMgPSBbXG4gICAge1xuICAgICAgaWQ6IDEsXG4gICAgICB0aXRsZTogJ+S6uuW3peaZuuiDveeugOS7iycsXG4gICAgICBjb250ZW50OiAn5Lq65bel5pm66IO977yIQXJ0aWZpY2lhbCBJbnRlbGxpZ2VuY2XvvIznroDnp7BBSe+8ieaYr+iuoeeul+acuuenkeWtpueahOS4gOS4quWIhuaUr++8jOWug+S8geWbvuS6huino+aZuuiDveeahOWunui0qO+8jOW5tueUn+S6p+WHuuS4gOenjeaWsOeahOiDveS7peS6uuexu+aZuuiDveebuOS8vOeahOaWueW8j+WBmuWHuuWPjeW6lOeahOaZuuiDveacuuWZqOOAguivpemihuWfn+eahOeglOeptuWMheaLrOacuuWZqOS6uuOAgeivreiogOivhuWIq+OAgeWbvuWDj+ivhuWIq+OAgeiHqueEtuivreiogOWkhOeQhuWSjOS4k+Wutuezu+e7n+etieOAguS6uuW3peaZuuiDveS7juivnueUn+S7peadpe+8jOeQhuiuuuWSjOaKgOacr+aXpeebiuaIkOeGn++8jOW6lOeUqOmihuWfn+S5n+S4jeaWreaJqeWkp++8jOWPr+S7peiuvuaDs++8jOacquadpeS6uuW3peaZuuiDveW4puadpeeahOenkeaKgOS6p+WTge+8jOWwhuS8muaYr+S6uuexu+aZuuaFp+eahFwi5a655ZmoXCLjgILkurrlt6Xmmbrog73lj6/ku6Xlr7nkurrnmoTmhI/or4bjgIHmgJ3nu7TnmoTkv6Hmga/ov4fnqIvnmoTmqKHmi5/jgILkurrlt6Xmmbrog73kuI3mmK/kurrnmoTmmbrog73vvIzkvYbog73lg4/kurrpgqPmoLfmgJ3ogIPjgIHkuZ/lj6/og73otoXov4fkurrnmoTmmbrog73jgIInXG4gICAgfSxcbiAgICB7XG4gICAgICBpZDogMixcbiAgICAgIHRpdGxlOiAn5rCU5YCZ5Y+Y5YyW5LiO546v5aKD5L+d5oqkJyxcbiAgICAgIGNvbnRlbnQ6ICfmsJTlgJnlj5jljJbmmK/mjIfmsJTlgJnnirbmgIHnmoTlj5jljJbvvIznibnliKvmmK/lubPlnYflpKnmsJTmqKHlvI/nmoTplb/mnJ/lj5jljJbvvIzov5nnp43lj5jljJblj6/og73mmK/nlLHoh6rnhLblhoXpg6jov4fnqIvmiJblpJbpg6jlvLrov6vlvJXotbfnmoTvvIzkuZ/lj6/og73mmK/nlLHkuo7kurrnsbvmtLvliqjmlLnlj5jkuoblnLDnkIPlpKfmsJTnmoTnu4TmiJDjgILmsJTlgJnlj5jljJblr7nkurrnsbvnpL7kvJrlkozoh6rnhLbnlJ/mgIHns7vnu5/kuqfnlJ/kuobmt7Hov5znmoTlvbHlk43vvIzljIXmi6zmtbflubPpnaLkuIrljYfjgIHmnoHnq6/lpKnmsJTkuovku7blop7liqDjgIHnlJ/nianlpJrmoLfmgKflh4/lsJHnrYnjgILkuLrkuoblupTlr7nmsJTlgJnlj5jljJbvvIzlm73pmYXnpL7kvJrph4flj5bkuobkuIDns7vliJfmjqrmlr3vvIzlpoLlh4/lsJHmuKnlrqTmsJTkvZPmjpLmlL7jgIHlj5HlsZXlj6/lho3nlJ/og73mupDjgIHmj5Dpq5jog73mupDmlYjnjofnrYnjgILnjq/looPkv53miqTmmK/mjIfkurrnsbvkuLrop6PlhrPnjrDlrp7miJbmvZzlnKjnmoTnjq/looPpl67popjvvIzljY/osIPkurrnsbvkuI7njq/looPnmoTlhbPns7vvvIzkv53pmpznu4/mtY7npL7kvJrnmoTlj6/mjIHnu63lj5HlsZXogIzph4flj5bnmoTlkITnp43ooYzliqjnmoTmgLvnp7DjgIInXG4gICAgfSxcbiAgICB7XG4gICAgICBpZDogMyxcbiAgICAgIHRpdGxlOiAn5YGl5bq355Sf5rS75pa55byPJyxcbiAgICAgIGNvbnRlbnQ6ICflgaXlurfnmoTnlJ/mtLvmlrnlvI/lr7nkuo7nu7TmjIHouqvkvZPlkozlv4PnkIblgaXlurfoh7PlhbPph43opoHjgILov5nljIXmi6zlnYfooaHnmoTppa7po5/jgIHlrprmnJ/nmoTkvZPogrLplLvngrzjgIHlhYXotrPnmoTnnaHnnKDjgIHlh4/lsJHljovlipvku6Xlj4rpgb/lhY3mnInlrrPkuaDmg6/lpoLlkLjng5/lkozov4fluqbppa7phZLjgILlnYfooaHppa7po5/mhI/lkbPnnYDmkYTlhaXlkITnp43okKXlhbvntKDvvIzljIXmi6zom4vnmb3otKjjgIHnorPmsLTljJblkIjnianjgIHohILogqrjgIHnu7TnlJ/ntKDlkoznn7/nianotKjjgILlrprmnJ/plLvngrzlj6/ku6Xlop7lvLrlv4Pogrrlip/og73jgIHmj5Dpq5jogozogonlipvph4/lkozngbXmtLvmgKfvvIzlubbmnInliqnkuo7mjqfliLbkvZPph43jgILlhYXotrPnmoTnnaHnnKDlr7nkuo7ouqvkvZPmgaLlpI3lkozlpKfohJHlip/og73oh7PlhbPph43opoHjgILnrqHnkIbljovlipvlj6/ku6XpgJrov4flhqXmg7PjgIHnkZzkvL3jgIHmt7HlkbzlkLjmiJblhbbku5bmlL7mnb7mioDlt6fmnaXlrp7njrDjgILpgb/lhY3lkLjng5/lkozpmZDliLbphZLnsr7mkYTlhaXlj6/ku6XpmY3kvY7mgqPlv4PohI/nl4XjgIHnmYznl4flkozlhbbku5bmhaLmgKfnlr7nl4XnmoTpo47pmanjgIInXG4gICAgfSxcbiAgICB7XG4gICAgICBpZDogNCxcbiAgICAgIHRpdGxlOiAn56eR5oqA5Yib5paw5LiO5pyq5p2lJyxcbiAgICAgIGNvbnRlbnQ6ICfnp5HmioDliJvmlrDmmK/mjqjliqjnpL7kvJrov5vmraXlkoznu4/mtY7lj5HlsZXnmoTph43opoHliqjlipvjgILov5HlubTmnaXvvIzkurrlt6Xmmbrog73jgIHlpKfmlbDmja7jgIHnianogZTnvZHjgIHljLrlnZfpk77jgIHph4/lrZDorqHnrpfnrYnmlrDlhbTmioDmnK/nmoTlv6vpgJ/lj5HlsZXvvIzmraPlnKjmt7HliLvmlLnlj5jnnYDmiJHku6znmoTnlJ/mtLvlkozlt6XkvZzmlrnlvI/jgILkurrlt6Xmmbrog73mraPlnKjlkITkuKrpoobln5/lvpfliLDlub/ms5vlupTnlKjvvIzku47mmbrog73liqnmiYvliLDoh6rliqjpqb7pqbbmsb3ovabjgILlpKfmlbDmja7liIbmnpDluK7liqnkvIHkuJrlgZrlh7rmm7TmmI7mmbrnmoTlhrPnrZbjgILnianogZTnvZHov57mjqXkuoblkITnp43orr7lpIfvvIzkvb/miJHku6znmoTnlJ/mtLvmm7TliqDkvr/mjbfjgILljLrlnZfpk77mioDmnK/mj5DkvpvkuoblronlhajjgIHpgI/mmI7nmoTkuqTmmJPmlrnlvI/jgILph4/lrZDorqHnrpfmnInmnJvop6PlhrPkvKDnu5/orqHnrpfmnLrpmr7ku6XlpITnkIbnmoTlpI3mnYLpl67popjjgILov5nkupvmioDmnK/nmoTlj5HlsZXlsIbnu6fnu63mjqjliqjkuqfkuJrljYfnuqflkoznpL7kvJrlj5jpnanvvIzkuLrmnKrmnaXliJvpgKDmm7TlpJrlj6/og73mgKfjgIInXG4gICAgfSxcbiAgICB7XG4gICAgICBpZDogNSxcbiAgICAgIHRpdGxlOiAn5pWZ6IKy55qE6YeN6KaB5oCnJyxcbiAgICAgIGNvbnRlbnQ6ICfmlZnogrLmmK/kurrnsbvnpL7kvJrlj5HlsZXnmoTln7rnn7PvvIzlr7nkuo7kuKrkurrlkoznpL7kvJrpg73lhbfmnInph43opoHmhI/kuYnjgILmlZnogrLkuI3ku4XkvKDmjojnn6Xor4blkozmioDog73vvIzov5jln7nlhbvkurrnmoTmgJ3nu7Tog73lipvjgIHliJvpgKDlipvlkoznpL7kvJrotKPku7vmhJ/jgILpgJrov4fmlZnogrLvvIzkuKrkurrlj6/ku6Xojrflvpfmm7Tlpb3nmoTlsLHkuJrmnLrkvJrvvIzmj5Dpq5jnlJ/mtLvotKjph4/jgILlr7nkuo7npL7kvJrogIzoqIDvvIzmlZnogrLlj6/ku6Xkv4Pov5vnu4/mtY7lj5HlsZXjgIHlh4/lsJHotKvlm7DjgIHmj5Dpq5jnpL7kvJrlh53ogZrlipvjgILmlZnogrLov5jlj6/ku6Xln7nlhbvlhazmsJHnmoTmsJHkuLvmhI/or4blkozlj4LkuI7og73lipvvvIzkv4Pov5vnpL7kvJrnmoTlhazlubPkuI7mraPkuYnjgILlnKjlvZPku4rlv6vpgJ/lj5jljJbnmoTkuJbnlYzkuK3vvIznu4jouqvlrabkuaDlj5jlvpfotormnaXotorph43opoHvvIzkurrku6zpnIDopoHkuI3mlq3mm7TmlrDnn6Xor4blkozmioDog73ku6XpgILlupTnpL7kvJrnmoTlj5HlsZXjgILlm6DmraTvvIzmipXotYTmlZnogrLmmK/lr7nmnKrmnaXmnIDlpb3nmoTmipXotYTjgIInXG4gICAgfVxuICBdO1xuXG4gIG9uSW5wdXRUZXh0Q2hhbmdlKHZhbHVlOiBzdHJpbmcpIHtcbiAgICBjb25zb2xlLmxvZygnb25JbnB1dFRleHRDaGFuZ2U6JywgdmFsdWUpO1xuICAgIHRoaXMuaW5wdXRUZXh0ID0gdmFsdWU7XG4gIH1cblxuICBvblN1bW1hcnlMZW5ndGhDaGFuZ2UodmFsdWU6IHN0cmluZykge1xuICAgIGNvbnNvbGUubG9nKCdvblN1bW1hcnlMZW5ndGhDaGFuZ2U6JywgdmFsdWUpO1xuICAgIHRoaXMuc3VtbWFyeUxlbmd0aCA9IHZhbHVlO1xuICB9XG5cbiAgbG9hZFRlc3RUZXh0KGluZGV4OiBudW1iZXIpIHtcbiAgICBjb25zb2xlLmxvZygnTG9hZGluZyB0ZXN0IHRleHQ6JywgaW5kZXgpO1xuICAgIGNvbnN0IHRlc3RUZXh0ID0gdGhpcy50ZXN0VGV4dHNbaW5kZXhdO1xuICAgIGlmICh0ZXN0VGV4dCkge1xuICAgICAgdGhpcy5pbnB1dFRleHQgPSB0ZXN0VGV4dC5jb250ZW50O1xuICAgICAgY29uc29sZS5sb2coJ1Rlc3QgdGV4dCBsb2FkZWQ6JywgdGVzdFRleHQudGl0bGUpO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIHN1bW1hcml6ZVRleHQoKSB7XG4gICAgY29uc29sZS5sb2coJz09PSBzdW1tYXJpemVUZXh0IGNhbGxlZCA9PT0nKTtcbiAgICBjb25zb2xlLmxvZygnaW5wdXRUZXh0OicsIHRoaXMuaW5wdXRUZXh0KTtcbiAgICBjb25zb2xlLmxvZygnaW5wdXRUZXh0LnRyaW0oKTonLCB0aGlzLmlucHV0VGV4dC50cmltKCkpO1xuICAgIGNvbnNvbGUubG9nKCdpc0xvYWRpbmc6JywgdGhpcy5pc0xvYWRpbmcpO1xuICAgIFxuICAgIGlmICghdGhpcy5pbnB1dFRleHQudHJpbSgpIHx8IHRoaXMuaXNMb2FkaW5nKSB7XG4gICAgICBjb25zb2xlLmxvZygnRWFybHkgcmV0dXJuOiBlbXB0eSB0ZXh0IG9yIGFscmVhZHkgbG9hZGluZycpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBcbiAgICBjb25zdCB0ZXh0ID0gdGhpcy5pbnB1dFRleHQudHJpbSgpO1xuICAgIGNvbnNvbGUubG9nKCdUZXh0IGxlbmd0aDonLCB0ZXh0Lmxlbmd0aCk7XG4gICAgXG4gICAgaWYgKHRleHQubGVuZ3RoIDwgNTApIHtcbiAgICAgIGFsZXJ0KCfor7fovpPlhaXoh7PlsJE1MOS4quWtl+espueahOaWh+acrOWGheWuuScpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBcbiAgICBpZiAodGV4dC5sZW5ndGggPiAxMDAwMCkge1xuICAgICAgYWxlcnQoJ+aWh+acrOmVv+W6puS4jeiDvei2hei/hzEwMDAw5Liq5a2X56ymJyk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIFxuICAgIC8vIOaVsOWtl+S6uueKtuaAge+8muW8gOWni+iBhuWQrFxuICAgIHRoaXMuZGlnaXRhbEh1bWFuU3RhdGUgPSAnbGlzdGVuaW5nJztcbiAgICB0aGlzLmRpZ2l0YWxIdW1hblNwZWVjaCA9ICfmraPlnKjogYblkKwuLi4nO1xuICAgIHRoaXMuaXNMb2FkaW5nID0gdHJ1ZTtcbiAgICBjb25zb2xlLmxvZygnU3RhcnRpbmcgc3VtbWFyeSBnZW5lcmF0aW9uLi4uJyk7XG4gICAgXG4gICAgdHJ5IHtcbiAgICAgIC8vIOaooeaLn+iBhuWQrOi/h+eoi1xuICAgICAgYXdhaXQgbmV3IFByb21pc2UocmVzb2x2ZSA9PiBzZXRUaW1lb3V0KHJlc29sdmUsIDEwMDApKTtcbiAgICAgIFxuICAgICAgLy8g5pWw5a2X5Lq654q25oCB77ya5byA5aeL5oCd6ICDXG4gICAgICB0aGlzLmRpZ2l0YWxIdW1hblN0YXRlID0gJ3RoaW5raW5nJztcbiAgICAgIHRoaXMuZGlnaXRhbEh1bWFuU3BlZWNoID0gJ+ato+WcqOaAneiAgy4uLic7XG4gICAgICBcbiAgICAgIGNvbnN0IHN1bW1hcnkgPSBhd2FpdCB0aGlzLm1vY2tBSVN1bW1hcnkodGV4dCwgdGhpcy5zdW1tYXJ5TGVuZ3RoKTtcbiAgICAgIGNvbnNvbGUubG9nKCdTdW1tYXJ5IGdlbmVyYXRlZDonLCBzdW1tYXJ5KTtcbiAgICAgIFxuICAgICAgLy8g5pWw5a2X5Lq654q25oCB77ya5byA5aeL6K+06K+dXG4gICAgICB0aGlzLmRpZ2l0YWxIdW1hblN0YXRlID0gJ3NwZWFraW5nJztcbiAgICAgIHRoaXMuZGlnaXRhbEh1bWFuU3BlZWNoID0gJ+aAu+e7k+WujOaIkO+8gSc7XG4gICAgICBcbiAgICAgIHRoaXMuY3VycmVudFN1bW1hcnkgPSBzdW1tYXJ5O1xuICAgICAgY29uc29sZS5sb2coJ2N1cnJlbnRTdW1tYXJ5IHNldCB0bzonLCB0aGlzLmN1cnJlbnRTdW1tYXJ5KTtcbiAgICAgIFxuICAgICAgY29uc3QgaGlzdG9yeUl0ZW06IFN1bW1hcnlIaXN0b3J5ID0ge1xuICAgICAgICBpZDogRGF0ZS5ub3coKSxcbiAgICAgICAgb3JpZ2luYWxUZXh0OiB0ZXh0LFxuICAgICAgICBzdW1tYXJ5VGV4dDogc3VtbWFyeSxcbiAgICAgICAgdGltZXN0YW1wOiBuZXcgRGF0ZSgpXG4gICAgICB9O1xuICAgICAgXG4gICAgICB0aGlzLmhpc3RvcnkudW5zaGlmdChoaXN0b3J5SXRlbSk7XG4gICAgICBcbiAgICAgIGlmICh0aGlzLmhpc3RvcnkubGVuZ3RoID4gMTApIHtcbiAgICAgICAgdGhpcy5oaXN0b3J5ID0gdGhpcy5oaXN0b3J5LnNsaWNlKDAsIDEwKTtcbiAgICAgIH1cbiAgICAgIFxuICAgICAgLy8gM+enkuWQjuaBouWkjeWIsOetieW+heeKtuaAgVxuICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgIHRoaXMuZGlnaXRhbEh1bWFuU3RhdGUgPSAnd2FpdGluZyc7XG4gICAgICAgIHRoaXMuZGlnaXRhbEh1bWFuU3BlZWNoID0gJ+etieW+hei+k+WFpS4uLic7XG4gICAgICB9LCAzMDAwKTtcbiAgICAgIFxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBjb25zb2xlLmVycm9yKCfmgLvnu5PlpLHotKU6JywgZXJyb3IpO1xuICAgICAgYWxlcnQoJ+aAu+e7k+i/h+eoi+S4reWHuueOsOmUmeivr++8jOivt+mHjeivlScpO1xuICAgICAgXG4gICAgICAvLyDplJnor6/ml7bmgaLlpI3liLDnrYnlvoXnirbmgIFcbiAgICAgIHRoaXMuZGlnaXRhbEh1bWFuU3RhdGUgPSAnd2FpdGluZyc7XG4gICAgICB0aGlzLmRpZ2l0YWxIdW1hblNwZWVjaCA9ICfnrYnlvoXovpPlhaUuLi4nO1xuICAgIH0gZmluYWxseSB7XG4gICAgICB0aGlzLmlzTG9hZGluZyA9IGZhbHNlO1xuICAgICAgY29uc29sZS5sb2coJ0xvYWRpbmcgY29tcGxldGUnKTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBtb2NrQUlTdW1tYXJ5KHRleHQ6IHN0cmluZywgbGVuZ3RoOiBzdHJpbmcpOiBQcm9taXNlPHN0cmluZz4ge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4ge1xuICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgIGNvbnN0IHNlbnRlbmNlcyA9IHRleHQuc3BsaXQoL1vjgILvvIHvvJ8uIT9dLykuZmlsdGVyKChzOiBzdHJpbmcpID0+IHMudHJpbSgpKTtcbiAgICAgICAgXG4gICAgICAgIGxldCBzdW1tYXJ5ID0gJyc7XG4gICAgICAgIGNvbnN0IHJhdGlvID0gbGVuZ3RoID09PSAnc2hvcnQnID8gMC4zIDogbGVuZ3RoID09PSAnbWVkaXVtJyA/IDAuNSA6IDAuNztcbiAgICAgICAgY29uc3QgdGFyZ2V0Q291bnQgPSBNYXRoLm1heCgxLCBNYXRoLmZsb29yKHNlbnRlbmNlcy5sZW5ndGggKiByYXRpbykpO1xuICAgICAgICBcbiAgICAgICAgaWYgKHNlbnRlbmNlcy5sZW5ndGggPD0gMikge1xuICAgICAgICAgIHN1bW1hcnkgPSBg44CQ5pm66IO95oC757uT44CRXFxuJHt0ZXh0fWA7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29uc3Qga2V5UG9pbnRzID0gc2VudGVuY2VzLnNsaWNlKDAsIE1hdGgubWluKDMsIHNlbnRlbmNlcy5sZW5ndGgpKTtcbiAgICAgICAgICBzdW1tYXJ5ID0gYOOAkOaZuuiDveaAu+e7k+OAkVxcbuaguOW/g+imgeeCue+8mlxcbmA7XG4gICAgICAgICAga2V5UG9pbnRzLmZvckVhY2goKHBvaW50OiBzdHJpbmcsIGluZGV4OiBudW1iZXIpID0+IHtcbiAgICAgICAgICAgIHN1bW1hcnkgKz0gYCR7aW5kZXggKyAxfS4gJHtwb2ludC50cmltKCl9XFxuYDtcbiAgICAgICAgICB9KTtcbiAgICAgICAgICBcbiAgICAgICAgICBjb25zdCBzZWxlY3RlZFNlbnRlbmNlcyA9IHNlbnRlbmNlcy5zbGljZSgwLCB0YXJnZXRDb3VudCk7XG4gICAgICAgICAgY29uc3Qgc3VtbWFyeVRleHQgPSBzZWxlY3RlZFNlbnRlbmNlcy5qb2luKCfjgIInKTtcbiAgICAgICAgICBzdW1tYXJ5ICs9IGBcXG7mgLvnu5PvvJoke3N1bW1hcnlUZXh0feOAgmA7XG4gICAgICAgIH1cbiAgICAgICAgXG4gICAgICAgIHJlc29sdmUoc3VtbWFyeSk7XG4gICAgICB9LCAxNTAwKTtcbiAgICB9KTtcbiAgfVxuXG4gIGNsZWFySW5wdXQoKSB7XG4gICAgdGhpcy5pbnB1dFRleHQgPSAnJztcbiAgICB0aGlzLmN1cnJlbnRTdW1tYXJ5ID0gJyc7XG4gIH1cblxuICBjbGVhckhpc3RvcnkoKSB7XG4gICAgaWYgKGNvbmZpcm0oJ+ehruWumuimgea4heepuuaJgOacieWOhuWPsuiusOW9leWQl++8nycpKSB7XG4gICAgICB0aGlzLmhpc3RvcnkgPSBbXTtcbiAgICB9XG4gIH1cblxuICBsb2FkSGlzdG9yeUl0ZW0oaXRlbTogU3VtbWFyeUhpc3RvcnkpIHtcbiAgICB0aGlzLmlucHV0VGV4dCA9IGl0ZW0ub3JpZ2luYWxUZXh0O1xuICAgIHRoaXMuY3VycmVudFN1bW1hcnkgPSBpdGVtLnN1bW1hcnlUZXh0O1xuICB9XG5cbiAgY29weVN1bW1hcnkoKSB7XG4gICAgaWYgKHRoaXMuY3VycmVudFN1bW1hcnkpIHtcbiAgICAgIG5hdmlnYXRvci5jbGlwYm9hcmQud3JpdGVUZXh0KHRoaXMuY3VycmVudFN1bW1hcnkpLnRoZW4oKCkgPT4ge1xuICAgICAgICBhbGVydCgn5bey5aSN5Yi25Yiw5Ymq6LS05p2/Jyk7XG4gICAgICB9KS5jYXRjaCgoKSA9PiB7XG4gICAgICAgIGFsZXJ0KCflpI3liLblpLHotKXvvIzor7fmiYvliqjlpI3liLYnKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIGZvcm1hdFRpbWUodGltZXN0YW1wOiBEYXRlKTogc3RyaW5nIHtcbiAgICBjb25zdCBkYXRlID0gbmV3IERhdGUodGltZXN0YW1wKTtcbiAgICBjb25zdCBub3cgPSBuZXcgRGF0ZSgpO1xuICAgIGNvbnN0IGRpZmYgPSBub3cuZ2V0VGltZSgpIC0gZGF0ZS5nZXRUaW1lKCk7XG4gICAgXG4gICAgY29uc3QgbWludXRlcyA9IE1hdGguZmxvb3IoZGlmZiAvIDYwMDAwKTtcbiAgICBjb25zdCBob3VycyA9IE1hdGguZmxvb3IoZGlmZiAvIDM2MDAwMDApO1xuICAgIGNvbnN0IGRheXMgPSBNYXRoLmZsb29yKGRpZmYgLyA4NjQwMDAwMCk7XG4gICAgXG4gICAgaWYgKG1pbnV0ZXMgPCAxKSByZXR1cm4gJ+WImuWImic7XG4gICAgaWYgKG1pbnV0ZXMgPCA2MCkgcmV0dXJuIGAke21pbnV0ZXN95YiG6ZKf5YmNYDtcbiAgICBpZiAoaG91cnMgPCAyNCkgcmV0dXJuIGAke2hvdXJzfeWwj+aXtuWJjWA7XG4gICAgaWYgKGRheXMgPCA3KSByZXR1cm4gYCR7ZGF5c33lpKnliY1gO1xuICAgIFxuICAgIHJldHVybiBkYXRlLnRvTG9jYWxlRGF0ZVN0cmluZygnemgtQ04nKTtcbiAgfVxufSJdfQ==
|