@banta/sdk 5.3.0 → 5.4.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.
Files changed (138) hide show
  1. package/{esm2022 → esm2020}/banta-sdk.mjs +4 -4
  2. package/{esm2022 → esm2020}/lib/attachment-scraper.mjs +1 -1
  3. package/esm2020/lib/banta/banta.component.mjs +204 -0
  4. package/{esm2022 → esm2020}/lib/banta-logo.component.mjs +11 -11
  5. package/{esm2022 → esm2020}/lib/banta-sdk.module.mjs +135 -135
  6. package/esm2020/lib/chat/banta-chat/banta-chat.component.mjs +209 -0
  7. package/esm2020/lib/chat/chat-message/chat-message.component.mjs +62 -0
  8. package/esm2020/lib/chat/chat-view/chat-view.component.mjs +170 -0
  9. package/{esm2022 → esm2020}/lib/chat/chat.module.mjs +51 -51
  10. package/{esm2022 → esm2020}/lib/chat/index.mjs +5 -5
  11. package/esm2020/lib/chat/live-chat-message.component.mjs +80 -0
  12. package/{esm2022 → esm2020}/lib/chat-backend-base.mjs +30 -30
  13. package/esm2020/lib/chat-backend.mjs +194 -0
  14. package/{esm2022 → esm2020}/lib/chat-source-base.mjs +1 -1
  15. package/esm2020/lib/chat-source.mjs +233 -0
  16. package/esm2020/lib/comments/attachment-button/attachment-button.component.mjs +76 -0
  17. package/esm2020/lib/comments/attachment-scraper.directive.mjs +107 -0
  18. package/esm2020/lib/comments/banta-comments/banta-comments.component.mjs +749 -0
  19. package/esm2020/lib/comments/comment/comment.component.mjs +175 -0
  20. package/esm2020/lib/comments/comment-field/comment-field.component.mjs +401 -0
  21. package/esm2020/lib/comments/comment-sort/comment-sort.component.mjs +37 -0
  22. package/esm2020/lib/comments/comment-view/comment-view.component.mjs +470 -0
  23. package/{esm2022 → esm2020}/lib/comments/comments.module.mjs +111 -111
  24. package/{esm2022 → esm2020}/lib/comments/index.mjs +10 -10
  25. package/esm2020/lib/comments/live-comment.component.mjs +80 -0
  26. package/{esm2022 → esm2020}/lib/comments/reply-send-options.directive.mjs +13 -13
  27. package/esm2020/lib/common/attachment/attachment.component.mjs +128 -0
  28. package/{esm2022 → esm2020}/lib/common/attachments/attachments.component.mjs +75 -75
  29. package/{esm2022 → esm2020}/lib/common/common.module.mjs +68 -68
  30. package/{esm2022 → esm2020}/lib/common/index.mjs +10 -10
  31. package/{esm2022 → esm2020}/lib/common/lazy-connection.mjs +14 -14
  32. package/esm2020/lib/common/lightbox/lightbox.component.mjs +31 -0
  33. package/esm2020/lib/common/markdown-to-html.pipe.mjs +88 -0
  34. package/esm2020/lib/common/mention-linker.pipe.mjs +35 -0
  35. package/esm2020/lib/common/timer-pool.service.mjs +83 -0
  36. package/esm2020/lib/common/timestamp.component.mjs +123 -0
  37. package/{esm2022 → esm2020}/lib/common/trust-resource-url.pipe.mjs +22 -22
  38. package/esm2020/lib/emoji/emoji-selector-button.component.mjs +116 -0
  39. package/esm2020/lib/emoji/emoji-selector-panel/emoji-selector-panel.component.mjs +98 -0
  40. package/{esm2022 → esm2020}/lib/emoji/emoji.module.mjs +55 -55
  41. package/{esm2022 → esm2020}/lib/emoji/emojis.mjs +6507 -6507
  42. package/{esm2022 → esm2020}/lib/emoji/index.mjs +4 -4
  43. package/esm2020/lib/giphy-attachments.mjs +16 -0
  44. package/{esm2022 → esm2020}/lib/index.mjs +19 -19
  45. package/{esm2022 → esm2020}/lib/live-message.component.mjs +61 -61
  46. package/{esm2022 → esm2020}/lib/message-menu-item.mjs +1 -1
  47. package/{esm2022 → esm2020}/lib/sdk-options.mjs +1 -1
  48. package/esm2020/lib/static-chat-source.mjs +71 -0
  49. package/esm2020/lib/tweet-attachments.mjs +13 -0
  50. package/esm2020/lib/url-attachments.mjs +42 -0
  51. package/esm2020/lib/youtube-attachments.mjs +29 -0
  52. package/{esm2022 → esm2020}/public-api.mjs +4 -4
  53. package/fesm2015/banta-sdk.mjs +11258 -0
  54. package/fesm2015/banta-sdk.mjs.map +1 -0
  55. package/{fesm2022 → fesm2020}/banta-sdk.mjs +10823 -10822
  56. package/fesm2020/banta-sdk.mjs.map +1 -0
  57. package/index.d.ts +5 -5
  58. package/lib/attachment-scraper.d.ts +15 -15
  59. package/lib/banta/banta.component.d.ts +58 -58
  60. package/lib/banta-logo.component.d.ts +5 -5
  61. package/lib/banta-sdk.module.d.ts +31 -31
  62. package/lib/chat/banta-chat/banta-chat.component.d.ts +79 -79
  63. package/lib/chat/chat-message/chat-message.component.d.ts +21 -21
  64. package/lib/chat/chat-view/chat-view.component.d.ts +52 -52
  65. package/lib/chat/chat.module.d.ts +15 -15
  66. package/lib/chat/index.d.ts +5 -5
  67. package/lib/chat/live-chat-message.component.d.ts +23 -23
  68. package/lib/chat-backend-base.d.ts +72 -72
  69. package/lib/chat-backend.d.ts +67 -67
  70. package/lib/chat-source-base.d.ts +44 -44
  71. package/lib/chat-source.d.ts +65 -65
  72. package/lib/comments/attachment-button/attachment-button.component.d.ts +17 -17
  73. package/lib/comments/attachment-scraper.directive.d.ts +21 -21
  74. package/lib/comments/banta-comments/banta-comments.component.d.ts +203 -203
  75. package/lib/comments/comment/comment.component.d.ts +72 -72
  76. package/lib/comments/comment-field/comment-field.component.d.ts +89 -89
  77. package/lib/comments/comment-sort/comment-sort.component.d.ts +16 -16
  78. package/lib/comments/comment-view/comment-view.component.d.ts +121 -121
  79. package/lib/comments/comments.module.d.ts +30 -30
  80. package/lib/comments/index.d.ts +10 -10
  81. package/lib/comments/live-comment.component.d.ts +23 -23
  82. package/lib/comments/reply-send-options.directive.d.ts +5 -5
  83. package/lib/common/attachment/attachment.component.d.ts +34 -34
  84. package/lib/common/attachments/attachments.component.d.ts +26 -26
  85. package/lib/common/common.module.d.ts +19 -19
  86. package/lib/common/index.d.ts +10 -10
  87. package/lib/common/lazy-connection.d.ts +6 -6
  88. package/lib/common/lightbox/lightbox.component.d.ts +14 -14
  89. package/lib/common/markdown-to-html.pipe.d.ts +15 -15
  90. package/lib/common/mention-linker.pipe.d.ts +13 -13
  91. package/lib/common/timer-pool.service.d.ts +15 -15
  92. package/lib/common/timestamp.component.d.ts +19 -19
  93. package/lib/common/trust-resource-url.pipe.d.ts +10 -10
  94. package/lib/emoji/emoji-selector-button.component.d.ts +30 -30
  95. package/lib/emoji/emoji-selector-panel/emoji-selector-panel.component.d.ts +26 -26
  96. package/lib/emoji/emoji.module.d.ts +16 -16
  97. package/lib/emoji/emojis.d.ts +6507 -6507
  98. package/lib/emoji/index.d.ts +4 -4
  99. package/lib/giphy-attachments.d.ts +5 -5
  100. package/lib/index.d.ts +19 -19
  101. package/lib/live-message.component.d.ts +22 -22
  102. package/lib/message-menu-item.d.ts +6 -6
  103. package/lib/sdk-options.d.ts +5 -5
  104. package/lib/static-chat-source.d.ts +42 -42
  105. package/lib/tweet-attachments.d.ts +5 -5
  106. package/lib/url-attachments.d.ts +14 -14
  107. package/lib/youtube-attachments.d.ts +5 -5
  108. package/package.json +11 -5
  109. package/public-api.d.ts +1 -1
  110. package/esm2022/lib/banta/banta.component.mjs +0 -204
  111. package/esm2022/lib/chat/banta-chat/banta-chat.component.mjs +0 -209
  112. package/esm2022/lib/chat/chat-message/chat-message.component.mjs +0 -62
  113. package/esm2022/lib/chat/chat-view/chat-view.component.mjs +0 -170
  114. package/esm2022/lib/chat/live-chat-message.component.mjs +0 -80
  115. package/esm2022/lib/chat-backend.mjs +0 -194
  116. package/esm2022/lib/chat-source.mjs +0 -233
  117. package/esm2022/lib/comments/attachment-button/attachment-button.component.mjs +0 -76
  118. package/esm2022/lib/comments/attachment-scraper.directive.mjs +0 -107
  119. package/esm2022/lib/comments/banta-comments/banta-comments.component.mjs +0 -748
  120. package/esm2022/lib/comments/comment/comment.component.mjs +0 -175
  121. package/esm2022/lib/comments/comment-field/comment-field.component.mjs +0 -401
  122. package/esm2022/lib/comments/comment-sort/comment-sort.component.mjs +0 -37
  123. package/esm2022/lib/comments/comment-view/comment-view.component.mjs +0 -470
  124. package/esm2022/lib/comments/live-comment.component.mjs +0 -80
  125. package/esm2022/lib/common/attachment/attachment.component.mjs +0 -128
  126. package/esm2022/lib/common/lightbox/lightbox.component.mjs +0 -31
  127. package/esm2022/lib/common/markdown-to-html.pipe.mjs +0 -88
  128. package/esm2022/lib/common/mention-linker.pipe.mjs +0 -35
  129. package/esm2022/lib/common/timer-pool.service.mjs +0 -83
  130. package/esm2022/lib/common/timestamp.component.mjs +0 -123
  131. package/esm2022/lib/emoji/emoji-selector-button.component.mjs +0 -115
  132. package/esm2022/lib/emoji/emoji-selector-panel/emoji-selector-panel.component.mjs +0 -98
  133. package/esm2022/lib/giphy-attachments.mjs +0 -16
  134. package/esm2022/lib/static-chat-source.mjs +0 -71
  135. package/esm2022/lib/tweet-attachments.mjs +0 -13
  136. package/esm2022/lib/url-attachments.mjs +0 -42
  137. package/esm2022/lib/youtube-attachments.mjs +0 -29
  138. package/fesm2022/banta-sdk.mjs.map +0 -1
@@ -1,748 +0,0 @@
1
- /// <reference types="@types/resize-observer-browser" />
2
- import { Component, ContentChild, HostBinding, Input, Output, TemplateRef, ViewChild, ViewChildren } from '@angular/core';
3
- import { CommentsOrder, FilterMode } from '@banta/common';
4
- import { Subject, Subscription } from 'rxjs';
5
- import { take } from 'rxjs/operators';
6
- import { BantaReplySendOptionsDirective } from '../reply-send-options.directive';
7
- import { CommentViewComponent } from '../comment-view/comment-view.component';
8
- import * as i0 from "@angular/core";
9
- import * as i1 from "../../chat-backend-base";
10
- import * as i2 from "@angular/router";
11
- import * as i3 from "@angular/material/snack-bar";
12
- import * as i4 from "@angular/common";
13
- import * as i5 from "@angular/material/icon";
14
- import * as i6 from "@angular/material/button";
15
- import * as i7 from "@angular/material/menu";
16
- import * as i8 from "@angular/material/progress-spinner";
17
- import * as i9 from "@angular/material/tooltip";
18
- import * as i10 from "../comment/comment.component";
19
- import * as i11 from "../comment-view/comment-view.component";
20
- import * as i12 from "../comment-field/comment-field.component";
21
- /**
22
- * Comments component
23
- */
24
- export class BantaCommentsComponent {
25
- constructor(backend, elementRef, activatedRoute, matSnackBar, ngZone) {
26
- this.backend = backend;
27
- this.elementRef = elementRef;
28
- this.activatedRoute = activatedRoute;
29
- this.matSnackBar = matSnackBar;
30
- this.ngZone = ngZone;
31
- this.isMobileSized = false;
32
- this.viewReady = new Promise(r => this.markViewReady = r);
33
- this.loadingTitle = 'Loading...';
34
- // Loading Screen
35
- this._loadingMessage = '';
36
- this.loadingMessageVisible = false;
37
- this.loading = true;
38
- this.showLoadingScreen = false;
39
- this.customMenuItems = [];
40
- this._loadingMessageIndex = 0;
41
- this.maxCommentLength = 1500;
42
- this.loadingMessages = [
43
- `Just a second...`,
44
- `It's definitely worth the wait!`,
45
- `This has never happened before.`,
46
- `We'll keep trying, but it's not looking great.
47
- Commenting & chat services may be down or degraded. Try reloading the page.
48
- If you keep experiencing issues or reloading the page works for you, please let us know by contacting support.
49
- `
50
- ];
51
- this.useInlineReplies = true;
52
- this.loaded = new Promise(r => this.markLoaded = r);
53
- // Properties
54
- this._signInSelected = new Subject();
55
- this._permissionDeniedError = new Subject();
56
- this._editAvatarSelected = new Subject();
57
- this._upvoted = new Subject();
58
- this._reported = new Subject();
59
- this._selected = new Subject();
60
- this._userSelected = new Subject();
61
- this._shared = new Subject();
62
- this._usernameSelected = new Subject();
63
- this._avatarSelected = new Subject();
64
- /**
65
- * Track whether we created this source. If we did not (ie it was passed in from the caller),
66
- * then we are not responsible for calling close(). If we do own it though, we will call close()
67
- * when we are done with it.
68
- */
69
- this._sourceIsOwned = false;
70
- this._subs = new Subscription();
71
- this.selectedMessageVisible = false;
72
- // Inputs
73
- this.signInLabel = 'Sign In';
74
- this.sendLabel = 'Send';
75
- this.signingInLabel = 'Signing in...';
76
- this.replyLabel = 'Reply';
77
- this.sendingLabel = 'Sending';
78
- this.permissionDeniedLabel = 'Send';
79
- this.postCommentLabel = 'Post a comment';
80
- this.postReplyLabel = 'Post a reply';
81
- this.allowAttachments = true;
82
- this.maxVisibleMessages = 20;
83
- this.genericAvatarUrl = `https://gravatar.com/avatar/${Date.now().toString(16)}?s=512&d=robohash`;
84
- this.participants = [];
85
- this.hashtags = [
86
- { hashtag: 'error', description: 'Cause an error' },
87
- { hashtag: 'timeout', description: 'Cause a slow timeout error' },
88
- { hashtag: 'slow', description: 'Be slow when this message is posted' },
89
- ];
90
- this._sortOrder = 'newest';
91
- this._filterMode = FilterMode.ALL;
92
- this._metadata = {};
93
- this.loadingSharedComment = false;
94
- this.sharedCommentMissing = false;
95
- this.sendMessage = async (message) => {
96
- try {
97
- const intercept = await this.shouldInterceptMessageSend?.(message, this.source);
98
- if (!intercept) {
99
- await this.source.send(message);
100
- }
101
- if (this.source.sortOrder !== CommentsOrder.NEWEST)
102
- this.sortOrder = CommentsOrder.NEWEST;
103
- if (this.source.filterMode !== FilterMode.ALL)
104
- this.filterMode = FilterMode.ALL;
105
- return true;
106
- }
107
- catch (e) {
108
- this.handleBackendException(e, 'Could not send: ');
109
- }
110
- };
111
- this.sendReply = async (message) => {
112
- try {
113
- const intercept = await this.shouldInterceptMessageSend?.(message, this.selectedMessageThread);
114
- if (!intercept) {
115
- await this.selectedMessageThread.send(message);
116
- }
117
- return true;
118
- }
119
- catch (e) {
120
- this.handleBackendException(e, 'Could not send reply: ');
121
- }
122
- };
123
- }
124
- get element() {
125
- return this.elementRef.nativeElement;
126
- }
127
- handleBackendExceptionAsAlert(e, prefix = '') {
128
- try {
129
- this.handleBackendException(e, prefix);
130
- }
131
- catch (e) {
132
- console.log(`[Banta/Comments] Showed user error (via alert): '${e.message}'`);
133
- console.error(e);
134
- alert(e.message);
135
- }
136
- }
137
- handleBackendExceptionAsSnack(e, prefix = '') {
138
- try {
139
- this.handleBackendException(e, prefix);
140
- }
141
- catch (e) {
142
- console.log(`[Banta/Comments] Showed user error (via snack): '${e.message}'`);
143
- console.error(e);
144
- this.matSnackBar.open(e.message, undefined, { duration: 3000 });
145
- //alert(e.message);
146
- }
147
- }
148
- handleBackendException(e, prefix = '') {
149
- let errorMessage = e.message;
150
- if (errorMessage.startsWith('permission-denied|')) {
151
- errorMessage = errorMessage.replace(/^permission-denied\|/, '');
152
- if (errorMessage.startsWith(`app-handle|`)) {
153
- // If this is an error during authorizeAction on the backend, pass control to the user-provided
154
- // permission-denied handler.
155
- this.sendPermissionDenied(errorMessage.replace(/^app-handle\|/, ''));
156
- return;
157
- }
158
- }
159
- throw new Error(`${prefix}${errorMessage}`);
160
- }
161
- // Lifecycle Events / Initialization
162
- ngOnInit() {
163
- this._subs.add(this.backend.userChanged.subscribe(user => this.user = user));
164
- this.startLoading();
165
- if (typeof window !== 'undefined') {
166
- let queryString = window.location.search.substring(1);
167
- let query = queryString.split('&')
168
- .map(s => s.split('='))
169
- .reduce((o, [k, v]) => (o[decodeURIComponent(k)] = decodeURIComponent(v), o), {});
170
- const commentID = query['comment'];
171
- if (commentID) {
172
- this.sharedCommentID = commentID;
173
- }
174
- }
175
- }
176
- ngAfterViewInit() {
177
- if (typeof window !== 'undefined') {
178
- let callback = () => {
179
- let size = this.elementRef.nativeElement.getBoundingClientRect();
180
- this.ngZone.run(() => {
181
- setTimeout(() => {
182
- this.width = size.width;
183
- this.height = size.height;
184
- this.isMobileSized = this.width < 500;
185
- });
186
- });
187
- };
188
- if (typeof ResizeObserver !== 'undefined') {
189
- this.resizeObserver = new ResizeObserver(callback);
190
- this.resizeObserver.observe(this.elementRef.nativeElement);
191
- }
192
- else {
193
- // One check is better than nothing!
194
- setTimeout(() => {
195
- this.width = this.elementRef.nativeElement.clientWidth;
196
- this.height = this.elementRef.nativeElement.clientHeight;
197
- this.isMobileSized = this.width < 500;
198
- }, 1000);
199
- }
200
- callback();
201
- }
202
- this.markViewReady();
203
- }
204
- ngOnDestroy() {
205
- this._subs.unsubscribe();
206
- if (this.resizeObserver)
207
- this.resizeObserver.disconnect();
208
- }
209
- async setSourceFromTopicID(topicID) {
210
- if (typeof window === 'undefined')
211
- return;
212
- setTimeout(async () => {
213
- console.log(`[Banta/Comments] Subscribing to topic source '${topicID}'`);
214
- this.source = await this.backend.getSourceForTopic(topicID, {
215
- sortOrder: this.sortOrder,
216
- filterMode: this.filterMode,
217
- metadata: this.metadata
218
- });
219
- this._sourceIsOwned = true;
220
- });
221
- }
222
- get loadingMessage() {
223
- return this._loadingMessage;
224
- }
225
- set loadingMessage(value) {
226
- this.loadingMessageVisible = false;
227
- setTimeout(() => {
228
- this._loadingMessage = value;
229
- this._loadingMessage = value;
230
- setTimeout(() => {
231
- this.loadingMessageVisible = true;
232
- });
233
- }, 500);
234
- }
235
- async startLoading() {
236
- this.loadingStartedAt = this.messageChangedAt = Date.now();
237
- if (this.updateLoading())
238
- return;
239
- await new Promise(resolve => setTimeout(() => resolve(), 100));
240
- if (this.updateLoading())
241
- return;
242
- await new Promise(resolve => setTimeout(() => resolve(), 250));
243
- if (this.updateLoading())
244
- return;
245
- await new Promise(resolve => setTimeout(() => resolve(), 500));
246
- if (this.updateLoading())
247
- return;
248
- console.log(`[Banta] Loading is taking a long time! Showing loading screen.`);
249
- this.showLoadingScreen = true;
250
- if (typeof window !== 'undefined')
251
- this._loadingTimer = setInterval(() => {
252
- this.updateLoading();
253
- this.loadingTitle = `Connecting to Live Comments service...`;
254
- }, 1000);
255
- }
256
- /**
257
- * Attempts to find the CommentComponent that corresponds to the given ChatMessage.
258
- * The ChatMessage could be a top-level message in this conversation, or a reply,
259
- * but note that a CommentComponent will only exist for a reply if the user has
260
- * the relevant reply thread open.
261
- * @param message The message to look for
262
- */
263
- getCommentComponentForMessage(message) {
264
- if (message.parentMessageId)
265
- return this.threadView?.getCommentComponentForMessage(message);
266
- else
267
- return this.commentView.getCommentComponentForMessage(message);
268
- }
269
- /**
270
- * Access the CommentViewComponent corresponding to the currently open reply thread.
271
- * This is not the top level comments, but instead the reply thread that the user has
272
- * opened (only one set of replies can be open at a time).
273
- *
274
- * For details about what CommentViewComponent affords you, see the commentView property.
275
- */
276
- get threadView() {
277
- return Array.from(this.threadViewQuery).filter(x => x !== this.commentView)[0];
278
- }
279
- async waitForThreadView() {
280
- if (this.threadView)
281
- return this.threadView;
282
- await this.threadViewQuery.changes.pipe(take(1)).toPromise();
283
- return this.threadView;
284
- }
285
- updateLoading() {
286
- if (this.source?.state && !['connecting', 'lost'].includes(this.source?.state)) {
287
- clearInterval(this._loadingTimer);
288
- this.loadingMessage = `Here we go!`;
289
- setTimeout(() => {
290
- this.loading = false;
291
- this.markLoaded();
292
- }, 750);
293
- return true;
294
- }
295
- console.log(`[Banta/Loader] State=${this.source ? this.source.state : 'no-source'}`);
296
- let messageSwitchTime = 5 * 1000;
297
- if (this.messageChangedAt + messageSwitchTime < Date.now()) {
298
- if (this.loadingMessages[this._loadingMessageIndex]) {
299
- this.loadingMessage = this.loadingMessages[this._loadingMessageIndex++];
300
- this.messageChangedAt = Date.now();
301
- }
302
- }
303
- return false;
304
- }
305
- get source() { return this._source; }
306
- set source(value) {
307
- if (this._source && this._sourceIsOwned) {
308
- this._source.close();
309
- this._sourceSubscription?.unsubscribe();
310
- this._source = null;
311
- this.participants = [];
312
- }
313
- this._source = value;
314
- this._sourceIsOwned = false; // Assume we don't own this source.
315
- this._sourceSubscription = new Subscription();
316
- if (value) {
317
- if (this.sharedCommentID) {
318
- this.navigateToSharedComment(this.sharedCommentID);
319
- this.lastSharedCommentID = this.sharedCommentID;
320
- this.sharedCommentID = null;
321
- }
322
- this._source.messages.forEach(m => this.addParticipant(m));
323
- this._sourceSubscription.add(this._source.connectionStateChanged.subscribe(state => this.connectionState = state));
324
- this._sourceSubscription.add(this._source.messageReceived.subscribe(m => this.addParticipant(m)));
325
- this._sourceSubscription.add(this._source.messageSent.subscribe(m => this.addParticipant(m)));
326
- this._sourceSubscription.add(this._source.messageObserved.subscribe(m => this.addParticipant(m)));
327
- this._sourceSubscription.add(this._source.messageUpdated.subscribe(msg => {
328
- console.log(`comments received message: `, msg);
329
- if (msg.id === this.selectedMessage?.id && msg.hidden) {
330
- this.unselectMessage();
331
- this.matSnackBar.open("The thread you were viewing was removed.", undefined, {
332
- duration: 2500
333
- });
334
- }
335
- }));
336
- }
337
- }
338
- get topicID() { return this._topicID; }
339
- set topicID(value) {
340
- if (this._topicID !== value) {
341
- this._topicID = value;
342
- setTimeout(() => this.setSourceFromTopicID(value));
343
- }
344
- }
345
- // Outputs
346
- get signInSelected() { return this._signInSelected; }
347
- get editAvatarSelected() { return this._editAvatarSelected; }
348
- get permissionDeniedError() { return this._permissionDeniedError; }
349
- get upvoted() { return this._upvoted.asObservable(); }
350
- get reported() { return this._reported.asObservable(); }
351
- get selected() { return this._selected.asObservable(); }
352
- get userSelected() { return this._userSelected.asObservable(); }
353
- get usernameSelected() { return this._usernameSelected.asObservable(); }
354
- get avatarSelected() { return this._avatarSelected.asObservable(); }
355
- get shared() { return this._shared.asObservable(); }
356
- reloadSource() {
357
- clearTimeout(this._reloadSourceTimeout);
358
- this._reloadSourceTimeout = setTimeout(() => {
359
- this.setSourceFromTopicID(this.topicID);
360
- });
361
- }
362
- get sortOrder() { return this._sortOrder; }
363
- set sortOrder(value) {
364
- if (this._sortOrder !== value) {
365
- this._sortOrder = value;
366
- this.reloadSource();
367
- }
368
- }
369
- get filterMode() { return this._filterMode; }
370
- set filterMode(value) {
371
- if (this._filterMode !== value) {
372
- this._filterMode = value;
373
- this.reloadSource();
374
- }
375
- }
376
- /**
377
- * Arbitrary metadata to send to the chat server. This can be used to provide context about the client to the server
378
- * for things like validating authorization and other uses.
379
- */
380
- get metadata() { return this._metadata; }
381
- set metadata(value) {
382
- if (JSON.stringify(this._metadata) !== JSON.stringify(value)) {
383
- this._metadata = value;
384
- this.reloadSource();
385
- }
386
- }
387
- get filterModes() {
388
- return FilterMode.options;
389
- }
390
- get filterModeLabels() {
391
- return {
392
- [FilterMode.ALL]: 'All',
393
- [FilterMode.MINE]: 'Mine',
394
- [FilterMode.THREADS]: 'Involving Me',
395
- [FilterMode.MY_LIKES]: 'My Likes'
396
- };
397
- }
398
- get sortOrders() {
399
- return CommentsOrder.options;
400
- }
401
- get sortOrderLabels() {
402
- return {
403
- [CommentsOrder.NEWEST]: 'Newest',
404
- [CommentsOrder.OLDEST]: 'Oldest',
405
- [CommentsOrder.LIKES]: 'Likes'
406
- };
407
- }
408
- // UI Interactions
409
- async scrollToComment(commentId) {
410
- if (typeof window === 'undefined')
411
- return;
412
- await this.commentView.waitForAllCommentsToLoad();
413
- const comment = document.querySelector(`[data-comment-id="${commentId}"]`);
414
- if (comment) {
415
- comment.scrollIntoView({
416
- inline: 'center',
417
- block: 'center'
418
- });
419
- }
420
- }
421
- async navigateToSharedComment(id) {
422
- this.loadingSharedComment = true;
423
- await new Promise(r => setTimeout(r, 10));
424
- this.sharedCommentMissing = false;
425
- let source = this.source;
426
- await source.ready;
427
- await this.viewReady;
428
- await this.loaded;
429
- console.log(`Navigating to shared comment with ID '${id}'...`);
430
- let message;
431
- try {
432
- message = await this.source.get(id);
433
- }
434
- catch (e) {
435
- console.error(`Failed to find comment from URL: ${e.message}`);
436
- this.sharedCommentMissing = true;
437
- this.loadingSharedComment = false;
438
- if (typeof window !== 'undefined') {
439
- setTimeout(() => {
440
- let notice = this.element.querySelector('.loading-comment');
441
- notice.scrollIntoView({
442
- block: 'center',
443
- inline: 'center'
444
- });
445
- }, 200);
446
- }
447
- return;
448
- }
449
- message.transientState ??= {};
450
- // If there is a parent message, we should instead focus that and let the
451
- // scrollToComment and highlight do the work.
452
- if (message.parentMessageId) {
453
- let parentMessage = await this.source.get(message.parentMessageId);
454
- parentMessage.transientState ??= {};
455
- // Make sure that this message is loaded and visible to the user
456
- await this.commentView.loadMessageInContext(parentMessage);
457
- let thread = await this.selectMessage(parentMessage);
458
- // Need to re-retrieve the message within the new chat source to affect its
459
- // transient state.
460
- await thread.ready;
461
- // Make sure that this message is loaded and visible to the user
462
- await this.waitForThreadView();
463
- await this.threadView.loadMessageInContext(message);
464
- message = await thread.get(message.id);
465
- message.transientState ??= {};
466
- message.transientState.highlighted = true;
467
- console.dir(message);
468
- await new Promise(resolve => setTimeout(() => resolve(), 500));
469
- }
470
- else {
471
- // Make sure that this message is loaded and visible to the user
472
- await this.commentView.loadMessageInContext(message);
473
- message.transientState ??= {};
474
- message.transientState.highlighted = true;
475
- }
476
- this.loadingSharedComment = false;
477
- await this.scrollToComment(id);
478
- }
479
- handlePermissionDenied(errorMessage) {
480
- // This is what other components call when handling permission errors
481
- if (errorMessage.startsWith(`app-handle|`)) {
482
- // If this is an error during authorizeAction on the backend, pass control to the user-provided
483
- // permission-denied handler.
484
- this.sendPermissionDenied(errorMessage.replace(/^app-handle\|/, ''));
485
- return;
486
- }
487
- alert(errorMessage);
488
- }
489
- sendPermissionDenied(message) {
490
- this._permissionDeniedError.next(message);
491
- }
492
- scrollToMessage(message) {
493
- let el = this.elementRef.nativeElement.querySelector(`[data-comment-id="${message.id}"]`);
494
- if (!el)
495
- return;
496
- el.scrollIntoView({ block: 'center', inline: 'start' });
497
- }
498
- addParticipant(message) {
499
- if (!message || !message.user || !message.user.id)
500
- return;
501
- let existing = this.participants.find(x => x.id === message.user.id);
502
- if (existing)
503
- return;
504
- this.participants.push(message.user);
505
- }
506
- // Actions
507
- async likeMessage(source, message) {
508
- if (!this.user) {
509
- await this.showSignIn();
510
- return;
511
- }
512
- this._upvoted.next(message);
513
- message.transientState.liking = true;
514
- try {
515
- await source.likeMessage(message.id);
516
- }
517
- catch (e) {
518
- this.handleBackendExceptionAsSnack(e, 'Could not like this message: ');
519
- }
520
- finally {
521
- await new Promise(resolve => setTimeout(() => resolve(), 250));
522
- message.transientState.liking = false;
523
- }
524
- }
525
- async unlikeMessage(source, message) {
526
- if (!this.user) {
527
- await this.showSignIn();
528
- return;
529
- }
530
- this._upvoted.next(message);
531
- message.transientState.liking = true;
532
- if (message.userState?.liked)
533
- message.likes = (message.likes || 0) - 1;
534
- try {
535
- await source.unlikeMessage(message.id);
536
- }
537
- catch (e) {
538
- this.handleBackendExceptionAsAlert(e, 'Failed to unlike this message: ');
539
- }
540
- await new Promise(resolve => setTimeout(() => resolve(), 250));
541
- message.transientState.liking = false;
542
- }
543
- async reportMessage(message) {
544
- this._reported.next(message);
545
- }
546
- async unselectMessage() {
547
- let message = this.selectedMessage;
548
- this._selected.next(null);
549
- this.selectedMessage = null;
550
- if (this.selectedMessageThread) {
551
- if (this.selectedMessageThread.close)
552
- this.selectedMessageThread.close();
553
- this.selectedMessageThread = null;
554
- }
555
- if (message)
556
- setTimeout(() => this.scrollToMessage(message));
557
- }
558
- async toggleSelectedMessage(message) {
559
- if (this.selectedMessage === message) {
560
- await this.unselectMessage();
561
- }
562
- else {
563
- await this.selectMessage(message);
564
- }
565
- }
566
- async selectMessage(message) {
567
- if (this.selectedMessage === message) {
568
- console.log(`[Banta] Thread ${this.topicID}/${message.id} is already open.`);
569
- return this.selectedMessageThread;
570
- }
571
- if (this.selectedMessageThread) {
572
- if (this.selectedMessageThread.close)
573
- this.selectedMessageThread.close();
574
- this.selectedMessageThread = null;
575
- }
576
- this._selected.next(message);
577
- console.log(`[Banta] Opening thread for ${this.topicID}/${message.id}...`);
578
- let selectedMessageThread = await this.backend.getSourceForThread(this.topicID, message.id);
579
- if (!selectedMessageThread) {
580
- console.warn(`Failed to locate thread for message ${this.topicID}/${message.id}!`);
581
- return null;
582
- }
583
- console.log(`[Banta] Thread opened for ${this.topicID}/${message.id}.`);
584
- setTimeout(() => this.selectedMessageVisible = true);
585
- setTimeout(async () => {
586
- this.selectedMessage = message;
587
- this.selectedMessageThread = selectedMessageThread;
588
- }, 250);
589
- return selectedMessageThread;
590
- }
591
- async showSignIn() {
592
- this._signInSelected.next();
593
- }
594
- async showEditAvatar() {
595
- this._editAvatarSelected.next();
596
- }
597
- async selectMessageUser(message) {
598
- this._userSelected.next(message);
599
- }
600
- async selectUsername(user) {
601
- this._usernameSelected.next(user);
602
- }
603
- async selectAvatar(user) {
604
- this._avatarSelected.next(user);
605
- }
606
- async shareMessage(message) {
607
- this._shared.next(message);
608
- }
609
- async deleteMessage(message) {
610
- if (!this.user) {
611
- await this.showSignIn();
612
- return;
613
- }
614
- if (!confirm("Are you sure you want to delete this comment? You cannot undo this action."))
615
- return;
616
- try {
617
- await this.source.deleteMessage(message.id);
618
- if (this.selectedMessage?.id === message.id)
619
- this.unselectMessage();
620
- }
621
- catch (e) {
622
- this.handleBackendExceptionAsAlert(e, `Could not delete message: `);
623
- }
624
- }
625
- async editMessage(source, message, newText) {
626
- if (!this.user) {
627
- await this.showSignIn();
628
- return;
629
- }
630
- try {
631
- await source.editMessage(message.id, newText);
632
- }
633
- catch (e) {
634
- this.handleBackendExceptionAsAlert(e, 'Could not edit this message: ');
635
- return;
636
- }
637
- message.message = newText;
638
- message.transientState.editing = false;
639
- }
640
- async startEditing(message) {
641
- this.selectedMessage.transientState.editing = false;
642
- message.transientState.editing = true;
643
- }
644
- async saveEdit(message, text) {
645
- if (!this.user) {
646
- await this.showSignIn();
647
- return;
648
- }
649
- try {
650
- await this.source.editMessage(message.id, text);
651
- message.transientState.editing = false;
652
- }
653
- catch (e) {
654
- this.handleBackendExceptionAsAlert(e, `Could not edit message: `);
655
- }
656
- }
657
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.9", ngImport: i0, type: BantaCommentsComponent, deps: [{ token: i1.ChatBackendBase }, { token: i0.ElementRef }, { token: i2.ActivatedRoute }, { token: i3.MatSnackBar }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component }); }
658
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.9", type: BantaCommentsComponent, selector: "banta-comments", inputs: { customMenuItems: "customMenuItems", url: "url", maxCommentLength: "maxCommentLength", loadingMessages: "loadingMessages", useInlineReplies: "useInlineReplies", signInLabel: "signInLabel", sendLabel: "sendLabel", signingInLabel: "signingInLabel", replyLabel: "replyLabel", sendingLabel: "sendingLabel", permissionDeniedLabel: "permissionDeniedLabel", postCommentLabel: "postCommentLabel", postReplyLabel: "postReplyLabel", allowAttachments: "allowAttachments", fixedHeight: "fixedHeight", maxMessages: "maxMessages", maxVisibleMessages: "maxVisibleMessages", genericAvatarUrl: "genericAvatarUrl", shouldInterceptMessageSend: "shouldInterceptMessageSend", participants: "participants", source: "source", hashtags: "hashtags", topicID: "topicID", sortOrder: "sortOrder", filterMode: "filterMode", metadata: "metadata" }, outputs: { signInSelected: "signInSelected", editAvatarSelected: "editAvatarSelected", permissionDeniedError: "permissionDeniedError", upvoted: "upvoted", reported: "reported", selected: "selected", userSelected: "userSelected", usernameSelected: "usernameSelected", avatarSelected: "avatarSelected", shared: "shared" }, host: { properties: { "class.banta-mobile": "this.isMobileSized" } }, queries: [{ propertyName: "sendReplyOptionsTemplate", first: true, predicate: BantaReplySendOptionsDirective, descendants: true, read: TemplateRef }], viewQueries: [{ propertyName: "commentView", first: true, predicate: ["commentView"], descendants: true }, { propertyName: "threadViewQuery", predicate: CommentViewComponent, descendants: true }], ngImport: i0, template: "<ng-container *ngIf=\"loading\">\r\n <div class=\"loading-screen\" [class.visible]=\"showLoadingScreen\">\r\n <h1>{{loadingTitle}}</h1>\r\n <div>\r\n <mat-spinner [diameter]=\"300\" [strokeWidth]=\"2\"></mat-spinner>\r\n </div>\r\n\r\n <p class=\"loading-message\" [class.visible]=\"loadingMessageVisible\">{{loadingMessage}}</p>\r\n </div>\r\n</ng-container>\r\n<ng-container *ngIf=\"!loading\">\r\n <div class=\"focused\" [class.visible]=\"selectedMessageVisible\" *ngIf=\"selectedMessage && !useInlineReplies\">\r\n\r\n <div>\r\n <a mat-button href=\"javascript:;\" (click)=\"unselectMessage()\">\r\n <mat-icon>arrow_back</mat-icon>\r\n Latest Comments\r\n </a>\r\n </div>\r\n\r\n <banta-comment\r\n [message]=\"selectedMessage\"\r\n [liking]=\"selectedMessage.transientState.liking\"\r\n [mine]=\"user?.id === selectedMessage.user?.id\"\r\n [permissions]=\"source?.permissions\"\r\n [showReplyAction]=\"false\"\r\n [editing]=\"selectedMessage.transientState.editing\"\r\n [maxLength]=\"maxCommentLength\"\r\n [genericAvatarUrl]=\"genericAvatarUrl\"\r\n [readonly]=\"source?.readonly\"\r\n (editStarted)=\"startEditing(selectedMessage)\"\r\n (editEnded)=\"selectedMessage.transientState.editing = false\"\r\n (edited)=\"saveEdit(selectedMessage, $event)\"\r\n (userSelected)=\"selectMessageUser(selectedMessage)\"\r\n (avatarSelected)=\"selectAvatar($event)\"\r\n (usernameSelected)=\"selectUsername($event)\"\r\n (liked)=\"likeMessage(source, selectedMessage)\"\r\n (unliked)=\"unlikeMessage(source, selectedMessage)\"\r\n (reported)=\"reportMessage(selectedMessage)\"\r\n (selected)=\"toggleSelectedMessage(selectedMessage)\"\r\n (shared)=\"shareMessage($event)\"\r\n (deleted)=\"deleteMessage(selectedMessage)\"\r\n ></banta-comment>\r\n\r\n <div class=\"replies\">\r\n\r\n <ng-container *ngIf=\"!selectedMessageThread\">\r\n <div class=\"loading\">\r\n <mat-spinner></mat-spinner>\r\n </div>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"selectedMessageThread\">\r\n <banta-comment-view\r\n class=\"replies\"\r\n #threadView\r\n [source]=\"selectedMessageThread\"\r\n [allowReplies]=\"false\"\r\n [fixedHeight]=\"false\"\r\n [showEmptyState]=\"false\"\r\n [newestLast]=\"true\"\r\n [genericAvatarUrl]=\"genericAvatarUrl\"\r\n (liked)=\"likeMessage(selectedMessageThread, $event)\"\r\n (unliked)=\"unlikeMessage(selectedMessageThread, $event)\"\r\n (messageEdited)=\"editMessage(selectedMessageThread, $event.message, $event.newMessage)\"\r\n (reported)=\"reportMessage($event)\"\r\n (usernameSelected)=\"selectUsername($event)\"\r\n (avatarSelected)=\"selectAvatar($event)\"\r\n (shared)=\"shareMessage($event)\"\r\n (deleted)=\"deleteMessage($event)\"\r\n [customMenuItems]=\"customMenuItems\"\r\n ></banta-comment-view>\r\n\r\n <banta-comment-field\r\n [url]=\"url\"\r\n [sendLabel]=\"replyLabel\"\r\n [sendingLabel]=\"sendingLabel\"\r\n [signingInLabel]=\"signingInLabel\"\r\n [hashtags]=\"hashtags\"\r\n [participants]=\"participants\"\r\n [readonly]=\"source?.readonly\"\r\n (signInSelected)=\"showSignIn()\"\r\n (editAvatarSelected)=\"showEditAvatar()\"\r\n [source]=\"selectedMessageThread\"\r\n [maxLength]=\"maxCommentLength\"\r\n [canComment]=\"source?.permissions?.canPost\"\r\n [signInState]=\"source?.signInState\"\r\n [signInLabel]=\"signInLabel\"\r\n [permissionDeniedLabel]=\"source?.permissions?.canPostErrorMessage || permissionDeniedLabel\"\r\n (permissionDeniedError)=\"handlePermissionDenied($event)\"\r\n [shouldInterceptMessageSend]=\"shouldInterceptMessageSend\"\r\n [user]=\"user\"\r\n [label]=\"postReplyLabel\"\r\n [submit]=\"sendReply\"\r\n [allowAttachments]=\"allowAttachments\"\r\n [genericAvatarUrl]=\"genericAvatarUrl\"\r\n >\r\n <ng-container *ngTemplateOutlet=\"sendReplyOptionsTemplate\"></ng-container>\r\n </banta-comment-field>\r\n </ng-container>\r\n </div>\r\n </div>\r\n\r\n <div class=\"main\" [class.hidden]=\"selectedMessage && !useInlineReplies\">\r\n <banta-comment-field\r\n [url]=\"url\"\r\n [source]=\"source\"\r\n [user]=\"user\"\r\n [sendLabel]=\"sendLabel\"\r\n [sendingLabel]=\"sendingLabel\"\r\n [signingInLabel]=\"signingInLabel\"\r\n [signInLabel]=\"signInLabel\"\r\n [signInState]=\"source?.signInState\"\r\n [canComment]=\"source?.permissions?.canPost\"\r\n [hashtags]=\"hashtags\"\r\n [participants]=\"participants\"\r\n [label]=\"postCommentLabel\"\r\n [maxLength]=\"maxCommentLength\"\r\n [permissionDeniedLabel]=\"source?.permissions?.canPostErrorMessage || permissionDeniedLabel\"\r\n [shouldInterceptMessageSend]=\"shouldInterceptMessageSend\"\r\n [submit]=\"sendMessage\"\r\n [allowAttachments]=\"allowAttachments\"\r\n [genericAvatarUrl]=\"genericAvatarUrl\"\r\n [readonly]=\"source?.readonly\"\r\n (editAvatarSelected)=\"showEditAvatar()\"\r\n (signInSelected)=\"showSignIn()\"\r\n (permissionDeniedError)=\"handlePermissionDenied($event)\"\r\n >\r\n \r\n </banta-comment-field>\r\n\r\n <mat-menu #filterMenu=\"matMenu\">\r\n <button mat-menu-item *ngFor=\"let filter of filterModes\" (click)=\"filterMode = filter\">\r\n {{filterModeLabels[filter]}}\r\n </button>\r\n </mat-menu>\r\n <mat-menu #sortMenu=\"matMenu\">\r\n <button mat-menu-item *ngFor=\"let sort of sortOrders\" (click)=\"sortOrder = sort\">\r\n {{sortOrderLabels[sort]}}\r\n </button>\r\n </mat-menu>\r\n\r\n <div class=\"settings\">\r\n <button mat-button [matMenuTriggerFor]=\"filterMenu\">\r\n <mat-icon>filter_list</mat-icon>\r\n {{filterModeLabels[filterMode]}}\r\n </button>\r\n <button mat-button [matMenuTriggerFor]=\"sortMenu\">\r\n <mat-icon>sort</mat-icon>\r\n {{sortOrderLabels[sortOrder]}}\r\n </button>\r\n </div>\r\n\r\n <div class=\"loading-comment\" *ngIf=\"loadingSharedComment\">\r\n <h1>Loading the comment you linked to...</h1>\r\n <mat-spinner [diameter]=\"300\" [strokeWidth]=\"2\"></mat-spinner>\r\n <p>\r\n If there are a lot of comments, this might take awhile!\r\n </p>\r\n </div>\r\n <div class=\"loading-comment\" *ngIf=\"!loadingSharedComment && lastSharedCommentID\">\r\n <ng-container *ngIf=\"sharedCommentMissing\">\r\n\r\n <a class=\"close\" mat-icon-button matTooltip=\"Close this notice\" href=\"javascript:;\" (click)=\"lastSharedCommentID = null\">\r\n <mat-icon>close</mat-icon>\r\n </a>\r\n\r\n <h1>\r\n <mat-icon>error</mat-icon>\r\n Uh oh!\r\n </h1>\r\n\r\n <p>The comment you linked to can't be found! It may have been removed.</p>\r\n </ng-container>\r\n <ng-container *ngIf=\"!sharedCommentMissing\">\r\n <a class=\"close\" mat-icon-button matTooltip=\"Close this notice\" href=\"javascript:;\" (click)=\"lastSharedCommentID = null\">\r\n <mat-icon>close</mat-icon>\r\n </a>\r\n <button mat-button (click)=\"navigateToSharedComment(lastSharedCommentID)\">\r\n <mat-icon>move_down</mat-icon> Jump to shared comment\r\n </button>\r\n </ng-container>\r\n </div>\r\n\r\n <banta-comment-view\r\n #commentView\r\n [class.faded]=\"selectedMessage && !useInlineReplies\"\r\n [source]=\"source\"\r\n [fixedHeight]=\"fixedHeight\"\r\n [maxMessages]=\"maxMessages\"\r\n [maxVisibleMessages]=\"maxVisibleMessages\"\r\n [genericAvatarUrl]=\"genericAvatarUrl\"\r\n [customMenuItems]=\"customMenuItems\"\r\n [holdNewMessages]=\"selectedMessageVisible\"\r\n (userSelected)=\"selectMessageUser($event)\"\r\n (sortOrderChanged)=\"sortOrder = $event\"\r\n (filterModeChanged)=\"filterMode = $event\"\r\n (selected)=\"toggleSelectedMessage($event)\"\r\n (liked)=\"likeMessage(source, $event)\"\r\n (unliked)=\"unlikeMessage(source, $event)\"\r\n (messageEdited)=\"editMessage(source, $event.message, $event.newMessage)\"\r\n (reported)=\"reportMessage($event)\"\r\n (usernameSelected)=\"selectUsername($event)\"\r\n (avatarSelected)=\"selectAvatar($event)\"\r\n (shared)=\"shareMessage($event)\"\r\n [selectedMessage]=\"selectedMessage\"\r\n (deleted)=\"deleteMessage($event)\"\r\n >\r\n <div class=\"inline-replies\">\r\n <div class=\"focused\" [class.visible]=\"selectedMessageVisible\" *ngIf=\"selectedMessage\">\r\n <div class=\"replies\">\r\n \r\n <ng-container *ngIf=\"!selectedMessageThread\">\r\n <div class=\"loading\">\r\n <mat-spinner></mat-spinner>\r\n </div>\r\n </ng-container>\r\n \r\n <ng-container *ngIf=\"selectedMessageThread\">\r\n <banta-comment-view\r\n [source]=\"selectedMessageThread\"\r\n [allowReplies]=\"false\"\r\n [fixedHeight]=\"false\"\r\n [showEmptyState]=\"false\"\r\n [newestLast]=\"true\"\r\n [enableHoldOnClick]=\"false\"\r\n [holdNewMessages]=\"replyFieldFocused\"\r\n [genericAvatarUrl]=\"genericAvatarUrl\"\r\n (liked)=\"likeMessage(selectedMessageThread, $event)\"\r\n (unliked)=\"unlikeMessage(selectedMessageThread, $event)\"\r\n (messageEdited)=\"editMessage(selectedMessageThread, $event.message, $event.newMessage)\"\r\n (reported)=\"reportMessage($event)\"\r\n (usernameSelected)=\"selectUsername($event)\"\r\n (avatarSelected)=\"selectAvatar($event)\"\r\n (shared)=\"shareMessage($event)\"\r\n (deleted)=\"deleteMessage($event)\"\r\n ></banta-comment-view>\r\n \r\n <banta-comment-field\r\n [url]=\"url\"\r\n [sendLabel]=\"replyLabel\"\r\n [sendingLabel]=\"sendingLabel\"\r\n [signingInLabel]=\"signingInLabel\"\r\n [hashtags]=\"hashtags\"\r\n [participants]=\"participants\"\r\n (signInSelected)=\"showSignIn()\"\r\n [maxLength]=\"maxCommentLength\"\r\n [source]=\"selectedMessageThread\"\r\n [signInState]=\"source?.signInState\"\r\n [canComment]=\"source?.permissions?.canPost\"\r\n [signInLabel]=\"signInLabel\"\r\n [permissionDeniedLabel]=\"source?.permissions?.canPostErrorMessage || permissionDeniedLabel\"\r\n [readonly]=\"source?.readonly\"\r\n [shouldInterceptMessageSend]=\"shouldInterceptMessageSend\"\r\n [user]=\"user\"\r\n [label]=\"postReplyLabel\"\r\n [submit]=\"sendReply\"\r\n [allowAttachments]=\"allowAttachments\"\r\n [genericAvatarUrl]=\"genericAvatarUrl\"\r\n (permissionDeniedError)=\"handlePermissionDenied($event)\"\r\n (editAvatarSelected)=\"showEditAvatar()\"\r\n (focusChange)=\"replyFieldFocused = $event\"\r\n >\r\n <ng-container *ngTemplateOutlet=\"sendReplyOptionsTemplate\"></ng-container>\r\n </banta-comment-field>\r\n </ng-container>\r\n </div>\r\n </div>\r\n </div>\r\n </banta-comment-view>\r\n </div>\r\n <div class=\"reconnecting\" *ngIf=\"connectionState === 'lost'\">\r\n <strong>Connection to Live Comments lost.</strong> Reconnecting...\r\n </div>\r\n</ng-container>\r\n", styles: [":host{display:flex;flex-direction:column}@keyframes select-comment{0%{transform:scale(1.15)}to{transform:scale(1)}}.focused{animation-name:select-comment;animation-duration:.4s;animation-fill-mode:both}.focused .replies{margin-top:1em;margin-left:2em;border-left:2px solid #333;padding-left:2em}banta-comment-view{opacity:1;transition:.4s opacity ease-in-out}banta-comment-view.faded{opacity:.25}.loading{display:block;width:fit-content;margin:0 auto;min-height:16em}.main.hidden{display:none}.loading-screen{text-align:center;opacity:0;transition:.25s ease-in-out opacity}.loading-screen.visible{opacity:1}.loading-screen h1{font-weight:100}.loading-screen mat-spinner{margin:5em auto}.loading-screen .loading-message{opacity:0;transition:.25s ease-in-out opacity;width:500px;max-width:100%;margin:0 auto}.loading-screen .loading-message.visible{opacity:1}banta-comment-sort{margin:0 0 0 auto;width:fit-content;display:block}.inline-replies{margin-left:4em}@media (max-width: 500px){.focused .replies{margin-left:0}.inline-replies{margin-left:1em}.focused .replies{padding-left:.5em}banta-comment-sort{margin:0;width:100%}}:host-context(.banta-mobile) .focused .replies{margin-left:0}:host-context(.banta-mobile) .inline-replies{margin-left:1em}:host-context(.banta-mobile) .focused .replies{padding-left:.5em}:host-context(.banta-mobile) banta-comment-sort{margin:0;width:100%}.loading-comment{z-index:100;border:1px solid #333;background:#000;color:#fff;padding:1em;border-radius:4px;text-align:center;position:relative}.loading-comment a.close{position:absolute;top:1em;right:1em}.loading-comment h1{font-weight:100;text-align:center}.loading-comment mat-spinner{margin:0 auto}.reconnecting{position:sticky;bottom:1em;background:#380a39;color:#926893;padding:1em;z-index:10;border-radius:4px;text-align:center}.settings{display:flex}\n"], dependencies: [{ kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i4.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i6.MatAnchor, selector: "a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i6.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: i6.MatIconAnchor, selector: "a[mat-icon-button]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i7.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i7.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i7.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "component", type: i8.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "directive", type: i9.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: i10.CommentComponent, selector: "banta-comment", inputs: ["message", "customMenuItems", "showReplyAction", "maxLength", "permissions", "mine", "editing", "genericAvatarUrl", "readonly"], outputs: ["liked", "unliked", "selected", "edited", "deleted", "editStarted", "editEnded", "shared", "userSelected", "usernameSelected", "avatarSelected", "reported", "loaded"] }, { kind: "component", type: i11.CommentViewComponent, selector: "banta-comment-view", inputs: ["source", "maxMessages", "maxVisibleMessages", "newestLast", "holdNewMessages", "showEmptyState", "allowReplies", "enableHoldOnClick", "enableHoldOnScroll", "customMenuItems", "fixedHeight", "selectedMessage", "genericAvatarUrl"], outputs: ["userSelected", "reported", "liked", "unliked", "usernameSelected", "avatarSelected", "shared", "deleted", "selected", "messageEdited", "sortOrderChanged", "filterModeChanged"] }, { kind: "component", type: i12.CommentFieldComponent, selector: "banta-comment-field", inputs: ["source", "user", "canComment", "signInState", "allowAttachments", "transientMessage", "sendLabel", "signingInLabel", "sendingLabel", "label", "permissionDeniedLabel", "signInLabel", "maxLength", "placeholder", "shouldInterceptMessageSend", "hashtags", "participants", "genericAvatarUrl", "url", "submit", "readonly"], outputs: ["signInSelected", "editAvatarSelected", "focusChange", "textChanged", "permissionDeniedError"] }] }); }
659
- }
660
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.9", ngImport: i0, type: BantaCommentsComponent, decorators: [{
661
- type: Component,
662
- args: [{ selector: 'banta-comments', template: "<ng-container *ngIf=\"loading\">\r\n <div class=\"loading-screen\" [class.visible]=\"showLoadingScreen\">\r\n <h1>{{loadingTitle}}</h1>\r\n <div>\r\n <mat-spinner [diameter]=\"300\" [strokeWidth]=\"2\"></mat-spinner>\r\n </div>\r\n\r\n <p class=\"loading-message\" [class.visible]=\"loadingMessageVisible\">{{loadingMessage}}</p>\r\n </div>\r\n</ng-container>\r\n<ng-container *ngIf=\"!loading\">\r\n <div class=\"focused\" [class.visible]=\"selectedMessageVisible\" *ngIf=\"selectedMessage && !useInlineReplies\">\r\n\r\n <div>\r\n <a mat-button href=\"javascript:;\" (click)=\"unselectMessage()\">\r\n <mat-icon>arrow_back</mat-icon>\r\n Latest Comments\r\n </a>\r\n </div>\r\n\r\n <banta-comment\r\n [message]=\"selectedMessage\"\r\n [liking]=\"selectedMessage.transientState.liking\"\r\n [mine]=\"user?.id === selectedMessage.user?.id\"\r\n [permissions]=\"source?.permissions\"\r\n [showReplyAction]=\"false\"\r\n [editing]=\"selectedMessage.transientState.editing\"\r\n [maxLength]=\"maxCommentLength\"\r\n [genericAvatarUrl]=\"genericAvatarUrl\"\r\n [readonly]=\"source?.readonly\"\r\n (editStarted)=\"startEditing(selectedMessage)\"\r\n (editEnded)=\"selectedMessage.transientState.editing = false\"\r\n (edited)=\"saveEdit(selectedMessage, $event)\"\r\n (userSelected)=\"selectMessageUser(selectedMessage)\"\r\n (avatarSelected)=\"selectAvatar($event)\"\r\n (usernameSelected)=\"selectUsername($event)\"\r\n (liked)=\"likeMessage(source, selectedMessage)\"\r\n (unliked)=\"unlikeMessage(source, selectedMessage)\"\r\n (reported)=\"reportMessage(selectedMessage)\"\r\n (selected)=\"toggleSelectedMessage(selectedMessage)\"\r\n (shared)=\"shareMessage($event)\"\r\n (deleted)=\"deleteMessage(selectedMessage)\"\r\n ></banta-comment>\r\n\r\n <div class=\"replies\">\r\n\r\n <ng-container *ngIf=\"!selectedMessageThread\">\r\n <div class=\"loading\">\r\n <mat-spinner></mat-spinner>\r\n </div>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"selectedMessageThread\">\r\n <banta-comment-view\r\n class=\"replies\"\r\n #threadView\r\n [source]=\"selectedMessageThread\"\r\n [allowReplies]=\"false\"\r\n [fixedHeight]=\"false\"\r\n [showEmptyState]=\"false\"\r\n [newestLast]=\"true\"\r\n [genericAvatarUrl]=\"genericAvatarUrl\"\r\n (liked)=\"likeMessage(selectedMessageThread, $event)\"\r\n (unliked)=\"unlikeMessage(selectedMessageThread, $event)\"\r\n (messageEdited)=\"editMessage(selectedMessageThread, $event.message, $event.newMessage)\"\r\n (reported)=\"reportMessage($event)\"\r\n (usernameSelected)=\"selectUsername($event)\"\r\n (avatarSelected)=\"selectAvatar($event)\"\r\n (shared)=\"shareMessage($event)\"\r\n (deleted)=\"deleteMessage($event)\"\r\n [customMenuItems]=\"customMenuItems\"\r\n ></banta-comment-view>\r\n\r\n <banta-comment-field\r\n [url]=\"url\"\r\n [sendLabel]=\"replyLabel\"\r\n [sendingLabel]=\"sendingLabel\"\r\n [signingInLabel]=\"signingInLabel\"\r\n [hashtags]=\"hashtags\"\r\n [participants]=\"participants\"\r\n [readonly]=\"source?.readonly\"\r\n (signInSelected)=\"showSignIn()\"\r\n (editAvatarSelected)=\"showEditAvatar()\"\r\n [source]=\"selectedMessageThread\"\r\n [maxLength]=\"maxCommentLength\"\r\n [canComment]=\"source?.permissions?.canPost\"\r\n [signInState]=\"source?.signInState\"\r\n [signInLabel]=\"signInLabel\"\r\n [permissionDeniedLabel]=\"source?.permissions?.canPostErrorMessage || permissionDeniedLabel\"\r\n (permissionDeniedError)=\"handlePermissionDenied($event)\"\r\n [shouldInterceptMessageSend]=\"shouldInterceptMessageSend\"\r\n [user]=\"user\"\r\n [label]=\"postReplyLabel\"\r\n [submit]=\"sendReply\"\r\n [allowAttachments]=\"allowAttachments\"\r\n [genericAvatarUrl]=\"genericAvatarUrl\"\r\n >\r\n <ng-container *ngTemplateOutlet=\"sendReplyOptionsTemplate\"></ng-container>\r\n </banta-comment-field>\r\n </ng-container>\r\n </div>\r\n </div>\r\n\r\n <div class=\"main\" [class.hidden]=\"selectedMessage && !useInlineReplies\">\r\n <banta-comment-field\r\n [url]=\"url\"\r\n [source]=\"source\"\r\n [user]=\"user\"\r\n [sendLabel]=\"sendLabel\"\r\n [sendingLabel]=\"sendingLabel\"\r\n [signingInLabel]=\"signingInLabel\"\r\n [signInLabel]=\"signInLabel\"\r\n [signInState]=\"source?.signInState\"\r\n [canComment]=\"source?.permissions?.canPost\"\r\n [hashtags]=\"hashtags\"\r\n [participants]=\"participants\"\r\n [label]=\"postCommentLabel\"\r\n [maxLength]=\"maxCommentLength\"\r\n [permissionDeniedLabel]=\"source?.permissions?.canPostErrorMessage || permissionDeniedLabel\"\r\n [shouldInterceptMessageSend]=\"shouldInterceptMessageSend\"\r\n [submit]=\"sendMessage\"\r\n [allowAttachments]=\"allowAttachments\"\r\n [genericAvatarUrl]=\"genericAvatarUrl\"\r\n [readonly]=\"source?.readonly\"\r\n (editAvatarSelected)=\"showEditAvatar()\"\r\n (signInSelected)=\"showSignIn()\"\r\n (permissionDeniedError)=\"handlePermissionDenied($event)\"\r\n >\r\n \r\n </banta-comment-field>\r\n\r\n <mat-menu #filterMenu=\"matMenu\">\r\n <button mat-menu-item *ngFor=\"let filter of filterModes\" (click)=\"filterMode = filter\">\r\n {{filterModeLabels[filter]}}\r\n </button>\r\n </mat-menu>\r\n <mat-menu #sortMenu=\"matMenu\">\r\n <button mat-menu-item *ngFor=\"let sort of sortOrders\" (click)=\"sortOrder = sort\">\r\n {{sortOrderLabels[sort]}}\r\n </button>\r\n </mat-menu>\r\n\r\n <div class=\"settings\">\r\n <button mat-button [matMenuTriggerFor]=\"filterMenu\">\r\n <mat-icon>filter_list</mat-icon>\r\n {{filterModeLabels[filterMode]}}\r\n </button>\r\n <button mat-button [matMenuTriggerFor]=\"sortMenu\">\r\n <mat-icon>sort</mat-icon>\r\n {{sortOrderLabels[sortOrder]}}\r\n </button>\r\n </div>\r\n\r\n <div class=\"loading-comment\" *ngIf=\"loadingSharedComment\">\r\n <h1>Loading the comment you linked to...</h1>\r\n <mat-spinner [diameter]=\"300\" [strokeWidth]=\"2\"></mat-spinner>\r\n <p>\r\n If there are a lot of comments, this might take awhile!\r\n </p>\r\n </div>\r\n <div class=\"loading-comment\" *ngIf=\"!loadingSharedComment && lastSharedCommentID\">\r\n <ng-container *ngIf=\"sharedCommentMissing\">\r\n\r\n <a class=\"close\" mat-icon-button matTooltip=\"Close this notice\" href=\"javascript:;\" (click)=\"lastSharedCommentID = null\">\r\n <mat-icon>close</mat-icon>\r\n </a>\r\n\r\n <h1>\r\n <mat-icon>error</mat-icon>\r\n Uh oh!\r\n </h1>\r\n\r\n <p>The comment you linked to can't be found! It may have been removed.</p>\r\n </ng-container>\r\n <ng-container *ngIf=\"!sharedCommentMissing\">\r\n <a class=\"close\" mat-icon-button matTooltip=\"Close this notice\" href=\"javascript:;\" (click)=\"lastSharedCommentID = null\">\r\n <mat-icon>close</mat-icon>\r\n </a>\r\n <button mat-button (click)=\"navigateToSharedComment(lastSharedCommentID)\">\r\n <mat-icon>move_down</mat-icon> Jump to shared comment\r\n </button>\r\n </ng-container>\r\n </div>\r\n\r\n <banta-comment-view\r\n #commentView\r\n [class.faded]=\"selectedMessage && !useInlineReplies\"\r\n [source]=\"source\"\r\n [fixedHeight]=\"fixedHeight\"\r\n [maxMessages]=\"maxMessages\"\r\n [maxVisibleMessages]=\"maxVisibleMessages\"\r\n [genericAvatarUrl]=\"genericAvatarUrl\"\r\n [customMenuItems]=\"customMenuItems\"\r\n [holdNewMessages]=\"selectedMessageVisible\"\r\n (userSelected)=\"selectMessageUser($event)\"\r\n (sortOrderChanged)=\"sortOrder = $event\"\r\n (filterModeChanged)=\"filterMode = $event\"\r\n (selected)=\"toggleSelectedMessage($event)\"\r\n (liked)=\"likeMessage(source, $event)\"\r\n (unliked)=\"unlikeMessage(source, $event)\"\r\n (messageEdited)=\"editMessage(source, $event.message, $event.newMessage)\"\r\n (reported)=\"reportMessage($event)\"\r\n (usernameSelected)=\"selectUsername($event)\"\r\n (avatarSelected)=\"selectAvatar($event)\"\r\n (shared)=\"shareMessage($event)\"\r\n [selectedMessage]=\"selectedMessage\"\r\n (deleted)=\"deleteMessage($event)\"\r\n >\r\n <div class=\"inline-replies\">\r\n <div class=\"focused\" [class.visible]=\"selectedMessageVisible\" *ngIf=\"selectedMessage\">\r\n <div class=\"replies\">\r\n \r\n <ng-container *ngIf=\"!selectedMessageThread\">\r\n <div class=\"loading\">\r\n <mat-spinner></mat-spinner>\r\n </div>\r\n </ng-container>\r\n \r\n <ng-container *ngIf=\"selectedMessageThread\">\r\n <banta-comment-view\r\n [source]=\"selectedMessageThread\"\r\n [allowReplies]=\"false\"\r\n [fixedHeight]=\"false\"\r\n [showEmptyState]=\"false\"\r\n [newestLast]=\"true\"\r\n [enableHoldOnClick]=\"false\"\r\n [holdNewMessages]=\"replyFieldFocused\"\r\n [genericAvatarUrl]=\"genericAvatarUrl\"\r\n (liked)=\"likeMessage(selectedMessageThread, $event)\"\r\n (unliked)=\"unlikeMessage(selectedMessageThread, $event)\"\r\n (messageEdited)=\"editMessage(selectedMessageThread, $event.message, $event.newMessage)\"\r\n (reported)=\"reportMessage($event)\"\r\n (usernameSelected)=\"selectUsername($event)\"\r\n (avatarSelected)=\"selectAvatar($event)\"\r\n (shared)=\"shareMessage($event)\"\r\n (deleted)=\"deleteMessage($event)\"\r\n ></banta-comment-view>\r\n \r\n <banta-comment-field\r\n [url]=\"url\"\r\n [sendLabel]=\"replyLabel\"\r\n [sendingLabel]=\"sendingLabel\"\r\n [signingInLabel]=\"signingInLabel\"\r\n [hashtags]=\"hashtags\"\r\n [participants]=\"participants\"\r\n (signInSelected)=\"showSignIn()\"\r\n [maxLength]=\"maxCommentLength\"\r\n [source]=\"selectedMessageThread\"\r\n [signInState]=\"source?.signInState\"\r\n [canComment]=\"source?.permissions?.canPost\"\r\n [signInLabel]=\"signInLabel\"\r\n [permissionDeniedLabel]=\"source?.permissions?.canPostErrorMessage || permissionDeniedLabel\"\r\n [readonly]=\"source?.readonly\"\r\n [shouldInterceptMessageSend]=\"shouldInterceptMessageSend\"\r\n [user]=\"user\"\r\n [label]=\"postReplyLabel\"\r\n [submit]=\"sendReply\"\r\n [allowAttachments]=\"allowAttachments\"\r\n [genericAvatarUrl]=\"genericAvatarUrl\"\r\n (permissionDeniedError)=\"handlePermissionDenied($event)\"\r\n (editAvatarSelected)=\"showEditAvatar()\"\r\n (focusChange)=\"replyFieldFocused = $event\"\r\n >\r\n <ng-container *ngTemplateOutlet=\"sendReplyOptionsTemplate\"></ng-container>\r\n </banta-comment-field>\r\n </ng-container>\r\n </div>\r\n </div>\r\n </div>\r\n </banta-comment-view>\r\n </div>\r\n <div class=\"reconnecting\" *ngIf=\"connectionState === 'lost'\">\r\n <strong>Connection to Live Comments lost.</strong> Reconnecting...\r\n </div>\r\n</ng-container>\r\n", styles: [":host{display:flex;flex-direction:column}@keyframes select-comment{0%{transform:scale(1.15)}to{transform:scale(1)}}.focused{animation-name:select-comment;animation-duration:.4s;animation-fill-mode:both}.focused .replies{margin-top:1em;margin-left:2em;border-left:2px solid #333;padding-left:2em}banta-comment-view{opacity:1;transition:.4s opacity ease-in-out}banta-comment-view.faded{opacity:.25}.loading{display:block;width:fit-content;margin:0 auto;min-height:16em}.main.hidden{display:none}.loading-screen{text-align:center;opacity:0;transition:.25s ease-in-out opacity}.loading-screen.visible{opacity:1}.loading-screen h1{font-weight:100}.loading-screen mat-spinner{margin:5em auto}.loading-screen .loading-message{opacity:0;transition:.25s ease-in-out opacity;width:500px;max-width:100%;margin:0 auto}.loading-screen .loading-message.visible{opacity:1}banta-comment-sort{margin:0 0 0 auto;width:fit-content;display:block}.inline-replies{margin-left:4em}@media (max-width: 500px){.focused .replies{margin-left:0}.inline-replies{margin-left:1em}.focused .replies{padding-left:.5em}banta-comment-sort{margin:0;width:100%}}:host-context(.banta-mobile) .focused .replies{margin-left:0}:host-context(.banta-mobile) .inline-replies{margin-left:1em}:host-context(.banta-mobile) .focused .replies{padding-left:.5em}:host-context(.banta-mobile) banta-comment-sort{margin:0;width:100%}.loading-comment{z-index:100;border:1px solid #333;background:#000;color:#fff;padding:1em;border-radius:4px;text-align:center;position:relative}.loading-comment a.close{position:absolute;top:1em;right:1em}.loading-comment h1{font-weight:100;text-align:center}.loading-comment mat-spinner{margin:0 auto}.reconnecting{position:sticky;bottom:1em;background:#380a39;color:#926893;padding:1em;z-index:10;border-radius:4px;text-align:center}.settings{display:flex}\n"] }]
663
- }], ctorParameters: () => [{ type: i1.ChatBackendBase }, { type: i0.ElementRef }, { type: i2.ActivatedRoute }, { type: i3.MatSnackBar }, { type: i0.NgZone }], propDecorators: { isMobileSized: [{
664
- type: HostBinding,
665
- args: ['class.banta-mobile']
666
- }], sendReplyOptionsTemplate: [{
667
- type: ContentChild,
668
- args: [BantaReplySendOptionsDirective, { read: TemplateRef }]
669
- }], customMenuItems: [{
670
- type: Input
671
- }], url: [{
672
- type: Input
673
- }], maxCommentLength: [{
674
- type: Input
675
- }], loadingMessages: [{
676
- type: Input
677
- }], useInlineReplies: [{
678
- type: Input
679
- }], commentView: [{
680
- type: ViewChild,
681
- args: ['commentView']
682
- }], threadViewQuery: [{
683
- type: ViewChildren,
684
- args: [CommentViewComponent]
685
- }], signInLabel: [{
686
- type: Input
687
- }], sendLabel: [{
688
- type: Input
689
- }], signingInLabel: [{
690
- type: Input
691
- }], replyLabel: [{
692
- type: Input
693
- }], sendingLabel: [{
694
- type: Input
695
- }], permissionDeniedLabel: [{
696
- type: Input
697
- }], postCommentLabel: [{
698
- type: Input
699
- }], postReplyLabel: [{
700
- type: Input
701
- }], allowAttachments: [{
702
- type: Input
703
- }], fixedHeight: [{
704
- type: Input
705
- }], maxMessages: [{
706
- type: Input
707
- }], maxVisibleMessages: [{
708
- type: Input
709
- }], genericAvatarUrl: [{
710
- type: Input
711
- }], shouldInterceptMessageSend: [{
712
- type: Input
713
- }], participants: [{
714
- type: Input
715
- }], source: [{
716
- type: Input
717
- }], hashtags: [{
718
- type: Input
719
- }], topicID: [{
720
- type: Input
721
- }], signInSelected: [{
722
- type: Output
723
- }], editAvatarSelected: [{
724
- type: Output
725
- }], permissionDeniedError: [{
726
- type: Output
727
- }], upvoted: [{
728
- type: Output
729
- }], reported: [{
730
- type: Output
731
- }], selected: [{
732
- type: Output
733
- }], userSelected: [{
734
- type: Output
735
- }], usernameSelected: [{
736
- type: Output
737
- }], avatarSelected: [{
738
- type: Output
739
- }], shared: [{
740
- type: Output
741
- }], sortOrder: [{
742
- type: Input
743
- }], filterMode: [{
744
- type: Input
745
- }], metadata: [{
746
- type: Input
747
- }] } });
748
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFudGEtY29tbWVudHMuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvc2RrL3NyYy9saWIvY29tbWVudHMvYmFudGEtY29tbWVudHMvYmFudGEtY29tbWVudHMuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvc2RrL3NyYy9saWIvY29tbWVudHMvYmFudGEtY29tbWVudHMvYmFudGEtY29tbWVudHMuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsd0RBQXdEO0FBRXhELE9BQU8sRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFjLFdBQVcsRUFBRSxLQUFLLEVBQVUsTUFBTSxFQUFhLFdBQVcsRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3pKLE9BQU8sRUFBcUIsYUFBYSxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUU3RSxPQUFPLEVBQUUsT0FBTyxFQUFjLFlBQVksRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUN6RCxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFNdEMsT0FBTyxFQUFFLDhCQUE4QixFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFFakYsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sd0NBQXdDLENBQUM7Ozs7Ozs7Ozs7Ozs7O0FBRzlFOztHQUVHO0FBTUgsTUFBTSxPQUFPLHNCQUFzQjtJQUMvQixZQUNZLE9BQXdCLEVBQ3hCLFVBQW1DLEVBQ25DLGNBQThCLEVBQzlCLFdBQXdCLEVBQ3hCLE1BQWM7UUFKZCxZQUFPLEdBQVAsT0FBTyxDQUFpQjtRQUN4QixlQUFVLEdBQVYsVUFBVSxDQUF5QjtRQUNuQyxtQkFBYyxHQUFkLGNBQWMsQ0FBZ0I7UUFDOUIsZ0JBQVcsR0FBWCxXQUFXLENBQWE7UUFDeEIsV0FBTSxHQUFOLE1BQU0sQ0FBUTtRQXdHMUIsa0JBQWEsR0FBWSxLQUFLLENBQUM7UUFNL0IsY0FBUyxHQUFHLElBQUksT0FBTyxDQUFPLENBQUMsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLGFBQWEsR0FBRyxDQUFDLENBQUMsQ0FBQztRQXNEM0QsaUJBQVksR0FBRyxZQUFZLENBQUM7UUFFNUIsaUJBQWlCO1FBQ1Qsb0JBQWUsR0FBRyxFQUFFLENBQUM7UUFDN0IsMEJBQXFCLEdBQUcsS0FBSyxDQUFDO1FBaUI5QixZQUFPLEdBQVksSUFBSSxDQUFDO1FBQ3hCLHNCQUFpQixHQUFHLEtBQUssQ0FBQztRQU1qQixvQkFBZSxHQUFzQixFQUFFLENBQUM7UUF1QnpDLHlCQUFvQixHQUFHLENBQUMsQ0FBQztRQU94QixxQkFBZ0IsR0FBVyxJQUFJLENBQUM7UUFDaEMsb0JBQWUsR0FBYTtZQUNqQyxrQkFBa0I7WUFDbEIsaUNBQWlDO1lBQ2pDLGlDQUFpQztZQUNqQzs7O1NBR0M7U0FDSixDQUFDO1FBRU8scUJBQWdCLEdBQUcsSUFBSSxDQUFDO1FBb0RqQyxXQUFNLEdBQUcsSUFBSSxPQUFPLENBQU8sQ0FBQyxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsVUFBVSxHQUFHLENBQUMsQ0FBQyxDQUFDO1FBeUJyRCxhQUFhO1FBRUwsb0JBQWUsR0FBRyxJQUFJLE9BQU8sRUFBUSxDQUFDO1FBQ3RDLDJCQUFzQixHQUFHLElBQUksT0FBTyxFQUFVLENBQUM7UUFDL0Msd0JBQW1CLEdBQUcsSUFBSSxPQUFPLEVBQVEsQ0FBQztRQUMxQyxhQUFRLEdBQUcsSUFBSSxPQUFPLEVBQWUsQ0FBQztRQUN0QyxjQUFTLEdBQUcsSUFBSSxPQUFPLEVBQWUsQ0FBQztRQUN2QyxjQUFTLEdBQUcsSUFBSSxPQUFPLEVBQWUsQ0FBQztRQUN2QyxrQkFBYSxHQUFHLElBQUksT0FBTyxFQUFlLENBQUM7UUFDM0MsWUFBTyxHQUFHLElBQUksT0FBTyxFQUFlLENBQUM7UUFDckMsc0JBQWlCLEdBQUcsSUFBSSxPQUFPLEVBQVEsQ0FBQztRQUN4QyxvQkFBZSxHQUFHLElBQUksT0FBTyxFQUFRLENBQUM7UUFHOUM7Ozs7V0FJRztRQUNLLG1CQUFjLEdBQUcsS0FBSyxDQUFDO1FBQ3ZCLFVBQUssR0FBRyxJQUFJLFlBQVksRUFBRSxDQUFDO1FBTW5DLDJCQUFzQixHQUFHLEtBQUssQ0FBQztRQUcvQixTQUFTO1FBRUEsZ0JBQVcsR0FBRyxTQUFTLENBQUM7UUFDeEIsY0FBUyxHQUFHLE1BQU0sQ0FBQztRQUNuQixtQkFBYyxHQUFHLGVBQWUsQ0FBQztRQUNqQyxlQUFVLEdBQUcsT0FBTyxDQUFDO1FBQ3JCLGlCQUFZLEdBQUcsU0FBUyxDQUFDO1FBQ3pCLDBCQUFxQixHQUFHLE1BQU0sQ0FBQztRQUMvQixxQkFBZ0IsR0FBRyxnQkFBZ0IsQ0FBQztRQUNwQyxtQkFBYyxHQUFHLGNBQWMsQ0FBQztRQUNoQyxxQkFBZ0IsR0FBRyxJQUFJLENBQUM7UUFHeEIsdUJBQWtCLEdBQVcsRUFBRSxDQUFDO1FBQ2hDLHFCQUFnQixHQUFHLCtCQUErQixJQUFJLENBQUMsR0FBRyxFQUFFLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxtQkFBbUIsQ0FBQztRQUc3RixpQkFBWSxHQUFXLEVBQUUsQ0FBQztRQWtEbkMsYUFBUSxHQUFjO1lBQ2xCLEVBQUMsT0FBTyxFQUFFLE9BQU8sRUFBRSxXQUFXLEVBQUUsZ0JBQWdCLEVBQUM7WUFDakQsRUFBQyxPQUFPLEVBQUUsU0FBUyxFQUFFLFdBQVcsRUFBRSw0QkFBNEIsRUFBQztZQUMvRCxFQUFDLE9BQU8sRUFBRSxNQUFNLEVBQUUsV0FBVyxFQUFFLHFDQUFxQyxFQUFDO1NBQ3hFLENBQUM7UUErQk0sZUFBVSxHQUFrQixRQUFRLENBQUM7UUFTckMsZ0JBQVcsR0FBZSxVQUFVLENBQUMsR0FBRyxDQUFDO1FBU3pDLGNBQVMsR0FBd0IsRUFBRSxDQUFDO1FBMkQ1Qyx5QkFBb0IsR0FBRyxLQUFLLENBQUM7UUFDN0IseUJBQW9CLEdBQUcsS0FBSyxDQUFDO1FBcmdCekIsSUFBSSxDQUFDLFdBQVcsR0FBRyxLQUFLLEVBQUUsT0FBb0IsRUFBRSxFQUFFO1lBQzlDLElBQUksQ0FBQztnQkFDRCxNQUFNLFNBQVMsR0FBRyxNQUFNLElBQUksQ0FBQywwQkFBMEIsRUFBRSxDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7Z0JBQ2hGLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztvQkFDYixNQUFNLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO2dCQUNwQyxDQUFDO2dCQUVELElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQyxTQUFTLEtBQUssYUFBYSxDQUFDLE1BQU07b0JBQzlDLElBQUksQ0FBQyxTQUFTLEdBQUcsYUFBYSxDQUFDLE1BQU0sQ0FBQztnQkFFMUMsSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLFVBQVUsS0FBSyxVQUFVLENBQUMsR0FBRztvQkFDekMsSUFBSSxDQUFDLFVBQVUsR0FBRyxVQUFVLENBQUMsR0FBRyxDQUFDO2dCQUVyQyxPQUFPLElBQUksQ0FBQztZQUNoQixDQUFDO1lBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztnQkFDVCxJQUFJLENBQUMsc0JBQXNCLENBQUMsQ0FBQyxFQUFFLGtCQUFrQixDQUFDLENBQUM7WUFDdkQsQ0FBQztRQUNMLENBQUMsQ0FBQTtRQUVELElBQUksQ0FBQyxTQUFTLEdBQUcsS0FBSyxFQUFFLE9BQW9CLEVBQUUsRUFBRTtZQUM1QyxJQUFJLENBQUM7Z0JBQ0QsTUFBTSxTQUFTLEdBQUcsTUFBTSxJQUFJLENBQUMsMEJBQTBCLEVBQUUsQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLHFCQUFxQixDQUFDLENBQUM7Z0JBQy9GLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztvQkFDYixNQUFNLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7Z0JBQ25ELENBQUM7Z0JBQ0QsT0FBTyxJQUFJLENBQUM7WUFDaEIsQ0FBQztZQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7Z0JBQ1QsSUFBSSxDQUFDLHNCQUFzQixDQUFDLENBQUMsRUFBRSx3QkFBd0IsQ0FBQyxDQUFDO1lBQzdELENBQUM7UUFDTCxDQUFDLENBQUE7SUFDTCxDQUFDO0lBRUQsSUFBSSxPQUFPO1FBQ1AsT0FBTyxJQUFJLENBQUMsVUFBVSxDQUFDLGFBQWEsQ0FBQztJQUN6QyxDQUFDO0lBRU8sNkJBQTZCLENBQUMsQ0FBUSxFQUFFLFNBQWlCLEVBQUU7UUFDL0QsSUFBSSxDQUFDO1lBQ0QsSUFBSSxDQUFDLHNCQUFzQixDQUFDLENBQUMsRUFBRSxNQUFNLENBQUMsQ0FBQztRQUMzQyxDQUFDO1FBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztZQUNULE9BQU8sQ0FBQyxHQUFHLENBQUMsb0RBQW9ELENBQUMsQ0FBQyxPQUFPLEdBQUcsQ0FBQyxDQUFDO1lBQzlFLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFFakIsS0FBSyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUNyQixDQUFDO0lBQ0wsQ0FBQztJQUVPLDZCQUE2QixDQUFDLENBQVEsRUFBRSxTQUFpQixFQUFFO1FBQy9ELElBQUksQ0FBQztZQUNELElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFDM0MsQ0FBQztRQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7WUFDVCxPQUFPLENBQUMsR0FBRyxDQUFDLG9EQUFvRCxDQUFDLENBQUMsT0FBTyxHQUFHLENBQUMsQ0FBQztZQUM5RSxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBRWpCLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxPQUFPLEVBQUUsU0FBUyxFQUFFLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7WUFDaEUsbUJBQW1CO1FBQ3ZCLENBQUM7SUFDTCxDQUFDO0lBRU8sc0JBQXNCLENBQUMsQ0FBUSxFQUFFLFNBQWlCLEVBQUU7UUFDeEQsSUFBSSxZQUFZLEdBQUcsQ0FBQyxDQUFDLE9BQU8sQ0FBQztRQUU3QixJQUFJLFlBQVksQ0FBQyxVQUFVLENBQUMsb0JBQW9CLENBQUMsRUFBRSxDQUFDO1lBQ2hELFlBQVksR0FBRyxZQUFZLENBQUMsT0FBTyxDQUFDLHNCQUFzQixFQUFFLEVBQUUsQ0FBQyxDQUFDO1lBRWhFLElBQUksWUFBWSxDQUFDLFVBQVUsQ0FBQyxhQUFhLENBQUMsRUFBRSxDQUFDO2dCQUN6QyxnR0FBZ0c7Z0JBQ2hHLDZCQUE2QjtnQkFFN0IsSUFBSSxDQUFDLG9CQUFvQixDQUFDLFlBQVksQ0FBQyxPQUFPLENBQUMsZUFBZSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUM7Z0JBQ3JFLE9BQU87WUFDWCxDQUFDO1FBQ0wsQ0FBQztRQUVELE1BQU0sSUFBSSxLQUFLLENBQUMsR0FBRyxNQUFNLEdBQUcsWUFBWSxFQUFFLENBQUMsQ0FBQztJQUNoRCxDQUFDO0lBRUQsb0NBQW9DO0lBRXBDLFFBQVE7UUFDSixJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLFdBQVcsQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUM7UUFDN0UsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO1FBRXBCLElBQUksT0FBTyxNQUFNLEtBQUssV0FBVyxFQUFFLENBQUM7WUFDaEMsSUFBSSxXQUFXLEdBQUcsTUFBTSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ3RELElBQUksS0FBSyxHQUFHLFdBQVcsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDO2lCQUM3QixHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO2lCQUN0QixNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLGtCQUFrQixDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsa0JBQWtCLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQ3BGO1lBRUQsTUFBTSxTQUFTLEdBQUcsS0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUFDO1lBQ25DLElBQUksU0FBUyxFQUFFLENBQUM7Z0JBQ1osSUFBSSxDQUFDLGVBQWUsR0FBRyxTQUFTLENBQUM7WUFDckMsQ0FBQztRQUNMLENBQUM7SUFDTCxDQUFDO0lBZUQsZUFBZTtRQUNYLElBQUksT0FBTyxNQUFNLEtBQUssV0FBVyxFQUFFLENBQUM7WUFDaEMsSUFBSSxRQUFRLEdBQUcsR0FBRyxFQUFFO2dCQUNoQixJQUFJLElBQUksR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLGFBQWEsQ0FBQyxxQkFBcUIsRUFBRSxDQUFDO2dCQUNqRSxJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUU7b0JBQ2pCLFVBQVUsQ0FBQyxHQUFHLEVBQUU7d0JBQ1osSUFBSSxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDO3dCQUN4QixJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUM7d0JBQzFCLElBQUksQ0FBQyxhQUFhLEdBQUcsSUFBSSxDQUFDLEtBQUssR0FBRyxHQUFHLENBQUM7b0JBQzFDLENBQUMsQ0FBQyxDQUFDO2dCQUNQLENBQUMsQ0FBQyxDQUFBO1lBQ04sQ0FBQyxDQUFDO1lBRUYsSUFBSSxPQUFPLGNBQWMsS0FBSyxXQUFXLEVBQUUsQ0FBQztnQkFDeEMsSUFBSSxDQUFDLGNBQWMsR0FBRyxJQUFJLGNBQWMsQ0FBQyxRQUFRLENBQUMsQ0FBQztnQkFDbkQsSUFBSSxDQUFDLGNBQWMsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxhQUFhLENBQUMsQ0FBQztZQUMvRCxDQUFDO2lCQUFNLENBQUM7Z0JBQ0osb0NBQW9DO2dCQUNwQyxVQUFVLENBQUMsR0FBRyxFQUFFO29CQUNaLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxhQUFhLENBQUMsV0FBVyxDQUFDO29CQUN2RCxJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsYUFBYSxDQUFDLFlBQVksQ0FBQztvQkFDekQsSUFBSSxDQUFDLGFBQWEsR0FBRyxJQUFJLENBQUMsS0FBSyxHQUFHLEdBQUcsQ0FBQztnQkFDMUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDO1lBQ2IsQ0FBQztZQUVELFFBQVEsRUFBRSxDQUFDO1FBQ2YsQ0FBQztRQUVELElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztJQUN6QixDQUFDO0lBRUQsV0FBVztRQUNQLElBQUksQ0FBQyxLQUFLLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDekIsSUFBSSxJQUFJLENBQUMsY0FBYztZQUNuQixJQUFJLENBQUMsY0FBYyxDQUFDLFVBQVUsRUFBRSxDQUFDO0lBQ3pDLENBQUM7SUFFTyxLQUFLLENBQUMsb0JBQW9CLENBQUMsT0FBZTtRQUM5QyxJQUFJLE9BQU8sTUFBTSxLQUFLLFdBQVc7WUFDN0IsT0FBTztRQUVYLFVBQVUsQ0FBQyxLQUFLLElBQUksRUFBRTtZQUNsQixPQUFPLENBQUMsR0FBRyxDQUFDLGlEQUFpRCxPQUFPLEdBQUcsQ0FBQyxDQUFDO1lBQ3pFLElBQUksQ0FBQyxNQUFNLEdBQUcsTUFBTSxJQUFJLENBQUMsT0FBTyxDQUFDLGlCQUFpQixDQUFDLE9BQU8sRUFBRTtnQkFDeEQsU0FBUyxFQUFFLElBQUksQ0FBQyxTQUFTO2dCQUN6QixVQUFVLEVBQUUsSUFBSSxDQUFDLFVBQVU7Z0JBQzNCLFFBQVEsRUFBRSxJQUFJLENBQUMsUUFBUTthQUMxQixDQUFDLENBQUM7WUFDSCxJQUFJLENBQUMsY0FBYyxHQUFHLElBQUksQ0FBQztRQUMvQixDQUFDLENBQUMsQ0FBQztJQUNQLENBQUM7SUFRRCxJQUFJLGNBQWM7UUFDZCxPQUFPLElBQUksQ0FBQyxlQUFlLENBQUM7SUFDaEMsQ0FBQztJQUVELElBQUksY0FBYyxDQUFDLEtBQUs7UUFDcEIsSUFBSSxDQUFDLHFCQUFxQixHQUFHLEtBQUssQ0FBQztRQUNuQyxVQUFVLENBQUMsR0FBRyxFQUFFO1lBQ1osSUFBSSxDQUFDLGVBQWUsR0FBRyxLQUFLLENBQUM7WUFDN0IsSUFBSSxDQUFDLGVBQWUsR0FBRyxLQUFLLENBQUM7WUFDN0IsVUFBVSxDQUFDLEdBQUcsRUFBRTtnQkFDWixJQUFJLENBQUMscUJBQXFCLEdBQUcsSUFBSSxDQUFDO1lBQ3RDLENBQUMsQ0FBQyxDQUFBO1FBQ04sQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDO0lBQ1osQ0FBQztJQVdPLEtBQUssQ0FBQyxZQUFZO1FBQ3RCLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDO1FBRTNELElBQUksSUFBSSxDQUFDLGFBQWEsRUFBRTtZQUFFLE9BQU87UUFDakMsTUFBTSxJQUFJLE9BQU8sQ0FBTyxPQUFPLENBQUMsRUFBRSxDQUFDLFVBQVUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxPQUFPLEVBQUUsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDO1FBQ3JFLElBQUksSUFBSSxDQUFDLGFBQWEsRUFBRTtZQUFFLE9BQU87UUFDakMsTUFBTSxJQUFJLE9BQU8sQ0FBTyxPQUFPLENBQUMsRUFBRSxDQUFDLFVBQVUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxPQUFPLEVBQUUsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDO1FBQ3JFLElBQUksSUFBSSxDQUFDLGFBQWEsRUFBRTtZQUFFLE9BQU87UUFDakMsTUFBTSxJQUFJLE9BQU8sQ0FBTyxPQUFPLENBQUMsRUFBRSxDQUFDLFVBQVUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxPQUFPLEVBQUUsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDO1FBQ3JFLElBQUksSUFBSSxDQUFDLGFBQWEsRUFBRTtZQUFFLE9BQU87UUFFakMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxnRUFBZ0UsQ0FBQyxDQUFDO1FBQzlFLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxJQUFJLENBQUM7UUFDOUIsSUFBSSxPQUFPLE1BQU0sS0FBSyxXQUFXO1lBQzdCLElBQUksQ0FBQyxhQUFhLEdBQUcsV0FBVyxDQUFDLEdBQUcsRUFBRTtnQkFDbEMsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO2dCQUNyQixJQUFJLENBQUMsWUFBWSxHQUFHLHdDQUF3QyxDQUFDO1lBQ2pFLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQztJQUNqQixDQUFDO0lBdUNEOzs7Ozs7T0FNRztJQUNILDZCQUE2QixDQUFDLE9BQW9CO1FBQzlDLElBQUksT0FBTyxDQUFDLGVBQWU7WUFDdkIsT0FBTyxJQUFJLENBQUMsVUFBVSxFQUFFLDZCQUE2QixDQUFDLE9BQU8sQ0FBQyxDQUFDOztZQUUvRCxPQUFPLElBQUksQ0FBQyxXQUFXLENBQUMsNkJBQTZCLENBQUMsT0FBTyxDQUFDLENBQUE7SUFDdEUsQ0FBQztJQUVEOzs7Ozs7T0FNRztJQUNILElBQUksVUFBVTtRQUNWLE9BQU8sS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxLQUFLLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNuRixDQUFDO0lBRUQsS0FBSyxDQUFDLGlCQUFpQjtRQUNuQixJQUFJLElBQUksQ0FBQyxVQUFVO1lBQ2YsT0FBTyxJQUFJLENBQUMsVUFBVSxDQUFDO1FBRTNCLE1BQU0sSUFBSSxDQUFDLGVBQWUsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsRUFBRSxDQUFDO1FBQzdELE9BQU8sSUFBSSxDQUFDLFVBQVUsQ0FBQztJQUMzQixDQUFDO0lBS08sYUFBYTtRQUNqQixJQUFJLElBQUksQ0FBQyxNQUFNLEVBQUUsS0FBSyxJQUFJLENBQUMsQ0FBQyxZQUFZLEVBQUUsTUFBTSxDQUFDLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUM3RSxhQUFhLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDO1lBQ2xDLElBQUksQ0FBQyxjQUFjLEdBQUcsYUFBYSxDQUFDO1lBQ3BDLFVBQVUsQ0FBQyxHQUFHLEVBQUU7Z0JBQ1osSUFBSSxDQUFDLE9BQU8sR0FBRyxLQUFLLENBQUM7Z0JBQ3JCLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztZQUN0QixDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUM7WUFDUixPQUFPLElBQUksQ0FBQztRQUNoQixDQUFDO1FBRUQsT0FBTyxDQUFDLEdBQUcsQ0FBQyx3QkFBd0IsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLFdBQVcsRUFBRSxDQUFDLENBQUM7UUFDckYsSUFBSSxpQkFBaUIsR0FBRyxDQUFDLEdBQUMsSUFBSSxDQUFDO1FBQy9CLElBQUksSUFBSSxDQUFDLGdCQUFnQixHQUFHLGlCQUFpQixHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDO1lBQ3pELElBQUksSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsb0JBQW9CLENBQUMsRUFBRSxDQUFDO2dCQUNsRCxJQUFJLENBQUMsY0FBYyxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLG9CQUFvQixFQUFFLENBQUMsQ0FBQztnQkFDeEUsSUFBSSxDQUFDLGdCQUFnQixHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQztZQUN2QyxDQUFDO1FBQ0wsQ0FBQztRQUVELE9BQU8sS0FBSyxDQUFDO0lBQ2pCLENBQUM7SUFvREQsSUFDSSxNQUFNLEtBQXFCLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7SUFDckQsSUFBSSxNQUFNLENBQUMsS0FBSztRQUNaLElBQUksSUFBSSxDQUFDLE9BQU8sSUFBSSxJQUFJLENBQUMsY0FBYyxFQUFFLENBQUM7WUFDdEMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUNyQixJQUFJLENBQUMsbUJBQW1CLEVBQUUsV0FBVyxFQUFFLENBQUM7WUFDeEMsSUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUM7WUFDcEIsSUFBSSxDQUFDLFlBQVksR0FBRyxFQUFFLENBQUM7UUFDM0IsQ0FBQztRQUVELElBQUksQ0FBQyxPQUFPLEdBQUcsS0FBSyxDQUFDO1FBQ3JCLElBQUksQ0FBQyxjQUFjLEdBQUcsS0FBSyxDQUFDLENBQUMsbUNBQW1DO1FBQ2hFLElBQUksQ0FBQyxtQkFBbUIsR0FBRyxJQUFJLFlBQVksRUFBRSxDQUFDO1FBRTlDLElBQUksS0FBSyxFQUFFLENBQUM7WUFDUixJQUFJLElBQUksQ0FBQyxlQUFlLEVBQUUsQ0FBQztnQkFDdkIsSUFBSSxDQUFDLHVCQUF1QixDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsQ0FBQztnQkFDbkQsSUFBSSxDQUFDLG1CQUFtQixHQUFHLElBQUksQ0FBQyxlQUFlLENBQUM7Z0JBQ2hELElBQUksQ0FBQyxlQUFlLEdBQUcsSUFBSSxDQUFDO1lBQ2hDLENBQUM7WUFFRCxJQUFJLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFFM0QsSUFBSSxDQUFDLG1CQUFtQixDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLHNCQUFzQixDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxlQUFlLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQztZQUNuSCxJQUFJLENBQUMsbUJBQW1CLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsZUFBZSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ2xHLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDOUYsSUFBSSxDQUFDLG1CQUFtQixDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLGVBQWUsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUNsRyxJQUFJLENBQUMsbUJBQW1CLENBQUMsR0FBRyxDQUN4QixJQUFJLENBQUMsT0FBTyxDQUFDLGNBQWMsQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLEVBQUU7Z0JBQ3hDLE9BQU8sQ0FBQyxHQUFHLENBQUMsNkJBQTZCLEVBQUUsR0FBRyxDQUFDLENBQUM7Z0JBQ2hELElBQUksR0FBRyxDQUFDLEVBQUUsS0FBSyxJQUFJLENBQUMsZUFBZSxFQUFFLEVBQUUsSUFBSSxHQUFHLENBQUMsTUFBTSxFQUFFLENBQUM7b0JBQ3BELElBQUksQ0FBQyxlQUFlLEVBQUUsQ0FBQztvQkFDdkIsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQ2pCLDBDQUEwQyxFQUMxQyxTQUFTLEVBQ1Q7d0JBQ0ksUUFBUSxFQUFFLElBQUk7cUJBQ2pCLENBQ0osQ0FBQTtnQkFDTCxDQUFDO1lBQ0wsQ0FBQyxDQUFDLENBQ0wsQ0FBQztRQUVOLENBQUM7SUFDTCxDQUFDO0lBT0QsSUFDSSxPQUFPLEtBQWEsT0FBTyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQztJQUMvQyxJQUFJLE9BQU8sQ0FBQyxLQUFLO1FBQ2IsSUFBSSxJQUFJLENBQUMsUUFBUSxLQUFLLEtBQUssRUFBRSxDQUFDO1lBQzFCLElBQUksQ0FBQyxRQUFRLEdBQUcsS0FBSyxDQUFDO1lBQ3RCLFVBQVUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsb0JBQW9CLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztRQUN2RCxDQUFDO0lBQ0wsQ0FBQztJQUVELFVBQVU7SUFFVixJQUFjLGNBQWMsS0FBdUIsT0FBTyxJQUFJLENBQUMsZUFBZSxDQUFDLENBQUMsQ0FBQztJQUNqRixJQUFjLGtCQUFrQixLQUFLLE9BQU8sSUFBSSxDQUFDLG1CQUFtQixDQUFDLENBQUMsQ0FBQztJQUN2RSxJQUFjLHFCQUFxQixLQUF5QixPQUFPLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDLENBQUM7SUFDakcsSUFBYyxPQUFPLEtBQUssT0FBTyxJQUFJLENBQUMsUUFBUSxDQUFDLFlBQVksRUFBRSxDQUFDLENBQUMsQ0FBQztJQUNoRSxJQUFjLFFBQVEsS0FBSyxPQUFPLElBQUksQ0FBQyxTQUFTLENBQUMsWUFBWSxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQ2xFLElBQWMsUUFBUSxLQUFLLE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQyxZQUFZLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDbEUsSUFBYyxZQUFZLEtBQUssT0FBTyxJQUFJLENBQUMsYUFBYSxDQUFDLFlBQVksRUFBRSxDQUFDLENBQUMsQ0FBQztJQUMxRSxJQUFjLGdCQUFnQixLQUFLLE9BQU8sSUFBSSxDQUFDLGlCQUFpQixDQUFDLFlBQVksRUFBRSxDQUFDLENBQUMsQ0FBQztJQUNsRixJQUFjLGNBQWMsS0FBSyxPQUFPLElBQUksQ0FBQyxlQUFlLENBQUMsWUFBWSxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQzlFLElBQWMsTUFBTSxLQUFLLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFHdEQsWUFBWTtRQUNoQixZQUFZLENBQUMsSUFBSSxDQUFDLG9CQUFvQixDQUFDLENBQUM7UUFDeEMsSUFBSSxDQUFDLG9CQUFvQixHQUFHLFVBQVUsQ0FBQyxHQUFHLEVBQUU7WUFDeEMsSUFBSSxDQUFDLG9CQUFvQixDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUM1QyxDQUFDLENBQUMsQ0FBQztJQUNQLENBQUM7SUFHRCxJQUFhLFNBQVMsS0FBSyxPQUFPLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDO0lBQ3BELElBQUksU0FBUyxDQUFDLEtBQUs7UUFDZixJQUFJLElBQUksQ0FBQyxVQUFVLEtBQUssS0FBSyxFQUFFLENBQUM7WUFDNUIsSUFBSSxDQUFDLFVBQVUsR0FBRyxLQUFLLENBQUM7WUFDeEIsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO1FBQ3hCLENBQUM7SUFDTCxDQUFDO0lBR0QsSUFBYSxVQUFVLEtBQUssT0FBTyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQztJQUN0RCxJQUFJLFVBQVUsQ0FBQyxLQUFLO1FBQ2hCLElBQUksSUFBSSxDQUFDLFdBQVcsS0FBSyxLQUFLLEVBQUUsQ0FBQztZQUM3QixJQUFJLENBQUMsV0FBVyxHQUFHLEtBQUssQ0FBQztZQUN6QixJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7UUFDeEIsQ0FBQztJQUNMLENBQUM7SUFJRDs7O09BR0c7SUFDSCxJQUFhLFFBQVEsS0FBSyxPQUFPLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDO0lBQ2xELElBQUksUUFBUSxDQUFDLEtBQUs7UUFDZCxJQUFJLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUMzRCxJQUFJLENBQUMsU0FBUyxHQUFHLEtBQUssQ0FBQztZQUN2QixJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7UUFDeEIsQ0FBQztJQUNMLENBQUM7SUFFRCxJQUFJLFdBQVc7UUFDWCxPQUFPLFVBQVUsQ0FBQyxPQUFPLENBQUM7SUFDOUIsQ0FBQztJQUVELElBQUksZ0JBQWdCO1FBQ2hCLE9BQU87WUFDSCxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsRUFBRSxLQUFLO1lBQ3ZCLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxFQUFFLE1BQU07WUFDekIsQ0FBQyxVQUFVLENBQUMsT0FBTyxDQUFDLEVBQUUsY0FBYztZQUNwQyxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUMsRUFBRSxVQUFVO1NBQ3BDLENBQUE7SUFDTCxDQUFDO0lBRUQsSUFBSSxVQUFVO1FBQ1YsT0FBTyxhQUFhLENBQUMsT0FBTyxDQUFDO0lBQ2pDLENBQUM7SUFFRCxJQUFJLGVBQWU7UUFDZixPQUFPO1lBQ0gsQ0FBQyxhQUFhLENBQUMsTUFBTSxDQUFDLEVBQUUsUUFBUTtZQUNoQyxDQUFDLGFBQWEsQ0FBQyxNQUFNLENBQUMsRUFBRSxRQUFRO1lBQ2hDLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQyxFQUFFLE9BQU87U0FDakMsQ0FBQTtJQUNMLENBQUM7SUFLRCxrQkFBa0I7SUFFbEIsS0FBSyxDQUFDLGVBQWUsQ0FBQyxTQUE0QjtRQUM5QyxJQUFJLE9BQU8sTUFBTSxLQUFLLFdBQVc7WUFDN0IsT0FBTztRQUVYLE1BQU0sSUFBSSxDQUFDLFdBQVcsQ0FBQyx3QkFBd0IsRUFBRSxDQUFDO1FBRWxELE1BQU0sT0FBTyxHQUFHLFFBQVEsQ0FBQyxhQUFhLENBQUMscUJBQXFCLFNBQVMsSUFBSSxDQUFDLENBQUM7UUFDM0UsSUFBSSxPQUFPLEVBQUUsQ0FBQztZQUNWLE9BQU8sQ0FBQyxjQUFjLENBQUM7Z0JBQ25CLE1BQU0sRUFBRSxRQUFRO2dCQUNoQixLQUFLLEVBQUUsUUFBUTthQUNsQixDQUFDLENBQUM7UUFDUCxDQUFDO0lBQ0wsQ0FBQztJQUtELEtBQUssQ0FBQyx1QkFBdUIsQ0FBQyxFQUFVO1FBQ3BDLElBQUksQ0FBQyxvQkFBb0IsR0FBRyxJQUFJLENBQUM7UUFDakMsTUFBTSxJQUFJLE9BQU8sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLFVBQVUsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUMxQyxJQUFJLENBQUMsb0JBQW9CLEdBQUcsS0FBSyxDQUFDO1FBQ2xDLElBQUksTUFBTSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUM7UUFFekIsTUFBTSxNQUFNLENBQUMsS0FBSyxDQUFDO1FBQ25CLE1BQU0sSUFBSSxDQUFDLFNBQVMsQ0FBQztRQUNyQixNQUFNLElBQUksQ0FBQyxNQUFNLENBQUM7UUFFbEIsT0FBTyxDQUFDLEdBQUcsQ0FBQyx5Q0FBeUMsRUFBRSxNQUFNLENBQUMsQ0FBQztRQUMvRCxJQUFJLE9BQW9CLENBQUM7UUFFekIsSUFBSSxDQUFDO1lBQ0QsT0FBTyxHQUFHLE1BQU0sSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDeEMsQ0FBQztRQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7WUFDVCxPQUFPLENBQUMsS0FBSyxDQUFDLG9DQUFvQyxDQUFDLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQztZQUMvRCxJQUFJLENBQUMsb0JBQW9CLEdBQUcsSUFBSSxDQUFDO1lBQ2pDLElBQUksQ0FBQyxvQkFBb0IsR0FBRyxLQUFLLENBQUM7WUFFbEMsSUFBSSxPQUFPLE1BQU0sS0FBSyxXQUFXLEVBQUUsQ0FBQztnQkFDaEMsVUFBVSxDQUFDLEdBQUcsRUFBRTtvQkFDWixJQUFJLE1BQU0sR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLGFBQWEsQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO29CQUM1RCxNQUFNLENBQUMsY0FBYyxDQUFDO3dCQUNsQixLQUFLLEVBQUUsUUFBUTt3QkFDZixNQUFNLEVBQUUsUUFBUTtxQkFDbkIsQ0FBQyxDQUFDO2dCQUNQLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQztZQUNaLENBQUM7WUFDRCxPQUFPO1FBQ1gsQ0FBQztRQUVELE9BQU8sQ0FBQyxjQUFjLEtBQUssRUFBRSxDQUFDO1FBRTlCLDBFQUEwRTtRQUMxRSw2Q0FBNkM7UUFFN0MsSUFBSSxPQUFPLENBQUMsZUFBZSxFQUFFLENBQUM7WUFFMUIsSUFBSSxhQUFhLEdBQUcsTUFBTSxJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsZUFBZSxDQUFDLENBQUM7WUFDbkUsYUFBYSxDQUFDLGNBQWMsS0FBSyxFQUFFLENBQUM7WUFFcEMsZ0VBQWdFO1lBQ2hFLE1BQU0sSUFBSSxDQUFDLFdBQVcsQ0FBQyxvQkFBb0IsQ0FBQyxhQUFhLENBQUMsQ0FBQztZQUUzRCxJQUFJLE1BQU0sR0FBRyxNQUFNLElBQUksQ0FBQyxhQUFhLENBQUMsYUFBYSxDQUFDLENBQUM7WUFFckQsMkVBQTJFO1lBQzNFLG1CQUFtQjtZQUNuQixNQUFNLE1BQU0sQ0FBQyxLQUFLLENBQUM7WUFFbkIsZ0VBQWdFO1lBQ2hFLE1BQU0sSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUM7WUFDL0IsTUFBTSxJQUFJLENBQUMsVUFBVSxDQUFDLG9CQUFvQixDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBRXBELE9BQU8sR0FBRyxNQUFNLE1BQU0sQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBQ3ZDLE9BQU8sQ0FBQyxjQUFjLEtBQUssRUFBRSxDQUFDO1lBQzlCLE9BQU8sQ0FBQyxjQUFjLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQztZQUMxQyxPQUFPLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQ3JCLE1BQU0sSUFBSSxPQUFPLENBQU8sT0FBTyxDQUFDLEVBQUUsQ0FBQyxVQUFVLENBQUMsR0FBRyxFQUFFLENBQUMsT0FBTyxFQUFFLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQztRQUV6RSxDQUFDO2FBQU0sQ0FBQztZQUNKLGdFQUFnRTtZQUNoRSxNQUFNLElBQUksQ0FBQyxXQUFXLENBQUMsb0JBQW9CLENBQUMsT0FBTyxDQUFDLENBQUM7WUFFckQsT0FBTyxDQUFDLGNBQWMsS0FBSyxFQUFFLENBQUM7WUFDOUIsT0FBTyxDQUFDLGNBQWMsQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDO1FBQzlDLENBQUM7UUFFRCxJQUFJLENBQUMsb0JBQW9CLEdBQUcsS0FBSyxDQUFDO1FBQ2xDLE1BQU0sSUFBSSxDQUFDLGVBQWUsQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUNuQyxDQUFDO0lBRUQsc0JBQXNCLENBQUMsWUFBb0I7UUFDdkMscUVBQXFFO1FBRXJFLElBQUksWUFBWSxDQUFDLFVBQVUsQ0FBQyxhQUFhLENBQUMsRUFBRSxDQUFDO1lBQ3pDLGdHQUFnRztZQUNoRyw2QkFBNkI7WUFFN0IsSUFBSSxDQUFDLG9CQUFvQixDQUFDLFlBQVksQ0FBQyxPQUFPLENBQUMsZUFBZSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFDckUsT0FBTztRQUNYLENBQUM7UUFFRCxLQUFLLENBQUMsWUFBWSxDQUFDLENBQUM7SUFDeEIsQ0FBQztJQUVELG9CQUFvQixDQUFDLE9BQWU7UUFDaEMsSUFBSSxDQUFDLHNCQUFzQixDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUM5QyxDQUFDO0lBRUQsZUFBZSxDQUFDLE9BQW9CO1FBQ2hDLElBQUksRUFBRSxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsYUFBYSxDQUFDLGFBQWEsQ0FBQyxxQkFBcUIsT0FBTyxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDMUYsSUFBSSxDQUFDLEVBQUU7WUFDSCxPQUFPO1FBQ1gsRUFBRSxDQUFDLGNBQWMsQ0FBQyxFQUFDLEtBQUssRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBQyxDQUFDLENBQUM7SUFDMUQsQ0FBQztJQUVPLGNBQWMsQ0FBQyxPQUFvQjtRQUN2QyxJQUFJLENBQUMsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsRUFBRTtZQUM3QyxPQUFPO1FBRVgsSUFBSSxRQUFRLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxLQUFLLE9BQU8sQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDckUsSUFBSSxRQUFRO1lBQ1IsT0FBTztRQUNYLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUN6QyxDQUFDO0lBRUQsVUFBVTtJQUVWLEtBQUssQ0FBQyxXQUFXLENBQUMsTUFBc0IsRUFBRSxPQUFvQjtRQUMxRCxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDO1lBQ2IsTUFBTSxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7WUFDeEIsT0FBTztRQUNYLENBQUM7UUFFRCxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUM1QixPQUFPLENBQUMsY0FBYyxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUM7UUFFckMsSUFBSSxDQUFDO1lBQ0QsTUFBTSxNQUFNLENBQUMsV0FBVyxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUN6QyxDQUFDO1FBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztZQUNULElBQUksQ0FBQyw2QkFBNkIsQ0FBQyxDQUFDLEVBQUUsK0JBQStCLENBQUMsQ0FBQztRQUMzRSxDQUFDO2dCQUFTLENBQUM7WUFDUCxNQUFNLElBQUksT0FBTyxDQUFPLE9BQU8sQ0FBQyxFQUFFLENBQUMsVUFBVSxDQUFDLEdBQUcsRUFBRSxDQUFDLE9BQU8sRUFBRSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUM7WUFDckUsT0FBTyxDQUFDLGNBQWMsQ0FBQyxNQUFNLEdBQUcsS0FBSyxDQUFDO1FBQzFDLENBQUM7SUFDTCxDQUFDO0lBRUQsS0FBSyxDQUFDLGFBQWEsQ0FBQyxNQUFzQixFQUFFLE9BQW9CO1FBQzVELElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7WUFDYixNQUFNLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztZQUN4QixPQUFPO1FBQ1gsQ0FBQztRQUVELElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQzVCLE9BQU8sQ0FBQyxjQUFjLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQztRQUVyQyxJQUFJLE9BQU8sQ0FBQyxTQUFTLEVBQUUsS0FBSztZQUN4QixPQUFPLENBQUMsS0FBSyxHQUFHLENBQUMsT0FBTyxDQUFDLEtBQUssSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7UUFFN0MsSUFBSSxDQUFDO1lBQ0QsTUFBTSxNQUFNLENBQUMsYUFBYSxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUMzQyxDQUFDO1FBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztZQUNULElBQUksQ0FBQyw2QkFBNkIsQ0FBQyxDQUFDLEVBQUUsaUNBQWlDLENBQUMsQ0FBQztRQUM3RSxDQUFDO1FBRUQsTUFBTSxJQUFJLE9BQU8sQ0FBTyxPQUFPLENBQUMsRUFBRSxDQUFDLFVBQVUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxPQUFPLEVBQUUsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDO1FBQ3JFLE9BQU8sQ0FBQyxjQUFjLENBQUMsTUFBTSxHQUFHLEtBQUssQ0FBQztJQUMxQyxDQUFDO0lBRUQsS0FBSyxDQUFDLGFBQWEsQ0FBQyxPQUFvQjtRQUNwQyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUNqQyxDQUFDO0lBRUQsS0FBSyxDQUFDLGVBQWU7UUFDakIsSUFBSSxPQUFPLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQztRQUVuQyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUMxQixJQUFJLENBQUMsZUFBZSxHQUFHLElBQUksQ0FBQztRQUM1QixJQUFJLElBQUksQ0FBQyxxQkFBcUIsRUFBRSxDQUFDO1lBQzdCLElBQUksSUFBSSxDQUFDLHFCQUFxQixDQUFDLEtBQUs7Z0JBQ2hDLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUN2QyxJQUFJLENBQUMscUJBQXFCLEdBQUcsSUFBSSxDQUFDO1FBQ3RDLENBQUM7UUFFRCxJQUFJLE9BQU87WUFDUCxVQUFVLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDO0lBQ3hELENBQUM7SUFFRCxLQUFLLENBQUMscUJBQXFCLENBQUMsT0FBb0I7UUFDNUMsSUFBSSxJQUFJLENBQUMsZUFBZSxLQUFLLE9BQU8sRUFBRSxDQUFDO1lBQ25DLE1BQU0sSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDO1FBQ2pDLENBQUM7YUFBTSxDQUFDO1lBQ0osTUFBTSxJQUFJLENBQUMsYUFBYSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ3RDLENBQUM7SUFDTCxDQUFDO0lBRUQsS0FBSyxDQUFDLGFBQWEsQ0FBQyxPQUFvQjtRQUNwQyxJQUFJLElBQUksQ0FBQyxlQUFlLEtBQUssT0FBTyxFQUFFLENBQUM7WUFDbkMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxrQkFBa0IsSUFBSSxDQUFDLE9BQU8sSUFBSSxPQUFPLENBQUMsRUFBRSxtQkFBbUIsQ0FBQyxDQUFDO1lBQzdFLE9BQU8sSUFBSSxDQUFDLHFCQUFxQixDQUFDO1FBQ3RDLENBQUM7UUFFRCxJQUFJLElBQUksQ0FBQyxxQkFBcUIsRUFBRSxDQUFDO1lBQzdCLElBQUksSUFBSSxDQUFDLHFCQUFxQixDQUFDLEtBQUs7Z0JBQ2hDLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUN2QyxJQUFJLENBQUMscUJBQXFCLEdBQUcsSUFBSSxDQUFDO1FBQ3RDLENBQUM7UUFFRCxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUU3QixPQUFPLENBQUMsR0FBRyxDQUFDLDhCQUE4QixJQUFJLENBQUMsT0FBTyxJQUFJLE9BQU8sQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQzNFLElBQUkscUJBQXFCLEdBQUcsTUFBTSxJQUFJLENBQUMsT0FBTyxDQUFDLGtCQUFrQixDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsT0FBTyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBRTVGLElBQUksQ0FBQyxxQkFBcUIsRUFBRSxDQUFDO1lBQ3pCLE9BQU8sQ0FBQyxJQUFJLENBQUMsdUNBQXVDLElBQUksQ0FBQyxPQUFPLElBQUksT0FBTyxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUM7WUFDbkYsT0FBTyxJQUFJLENBQUM7UUFDaEIsQ0FBQztRQUVELE9BQU8sQ0FBQyxHQUFHLENBQUMsNkJBQTZCLElBQUksQ0FBQyxPQUFPLElBQUksT0FBTyxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUM7UUFFeEUsVUFBVSxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxzQkFBc0IsR0FBRyxJQUFJLENBQUMsQ0FBQztRQUNyRCxVQUFVLENBQUMsS0FBSyxJQUFJLEVBQUU7WUFDbEIsSUFBSSxDQUFDLGVBQWUsR0FBRyxPQUFPLENBQUM7WUFDL0IsSUFBSSxDQUFDLHFCQUFxQixHQUFHLHFCQUFxQixDQUFDO1FBQ3ZELENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQztRQUVSLE9BQU8scUJBQXFCLENBQUM7SUFDakMsQ0FBQztJQUVELEtBQUssQ0FBQyxVQUFVO1FBQ1osSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLEVBQUUsQ0FBQztJQUNoQyxDQUFDO0lBRUQsS0FBSyxDQUFDLGNBQWM7UUFDaEIsSUFBSSxDQUFDLG1CQUFtQixDQUFDLElBQUksRUFBRSxDQUFDO0lBQ3BDLENBQUM7SUFFRCxLQUFLLENBQUMsaUJBQWlCLENBQUMsT0FBb0I7UUFDeEMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDckMsQ0FBQztJQUVELEtBQUssQ0FBQyxjQUFjLENBQUMsSUFBVTtRQUMzQixJQUFJLENBQUMsaUJBQWlCLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ3RDLENBQUM7SUFFRCxLQUFLLENBQUMsWUFBWSxDQUFDLElBQVU7UUFDekIsSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDcEMsQ0FBQztJQUVELEtBQUssQ0FBQyxZQUFZLENBQUMsT0FBb0I7UUFDbkMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDL0IsQ0FBQztJQUVELEtBQUssQ0FBQyxhQUFhLENBQUMsT0FBb0I7UUFDcEMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUNiLE1BQU0sSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO1lBQ3hCLE9BQU87UUFDWCxDQUFDO1FBRUQsSUFBSSxDQUFDLE9BQU8sQ0FBQyw0RUFBNEUsQ0FBQztZQUN0RixPQUFPO1FBRVgsSUFBSSxDQUFDO1lBQ0QsTUFBTSxJQUFJLENBQUMsTUFBTSxDQUFDLGFBQWEsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLENBQUM7WUFFNUMsSUFBSSxJQUFJLENBQUMsZUFBZSxFQUFFLEVBQUUsS0FBSyxPQUFPLENBQUMsRUFBRTtnQkFDdkMsSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDO1FBRS9CLENBQUM7UUFBQyxPQUFPLENBQUMsRUFBRSxDQUFDO1lBQ1QsSUFBSSxDQUFDLDZCQUE2QixDQUFDLENBQUMsRUFBRSw0QkFBNEIsQ0FBQyxDQUFDO1FBQ3hFLENBQUM7SUFDTCxDQUFDO0lBRUQsS0FBSyxDQUFDLFdBQVcsQ0FBQyxNQUFzQixFQUFFLE9BQW9CLEVBQUUsT0FBZTtRQUMzRSxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDO1lBQ2IsTUFBTSxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7WUFDeEIsT0FBTztRQUNYLENBQUM7UUFFRCxJQUFJLENBQUM7WUFDRCxNQUFNLE1BQU0sQ0FBQyxXQUFXLENBQUMsT0FBTyxDQUFDLEVBQUUsRUFBRSxPQUFPLENBQUMsQ0FBQztRQUNsRCxDQUFDO1FBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztZQUNULElBQUksQ0FBQyw2QkFBNkIsQ0FBQyxDQUFDLEVBQUUsK0JBQStCLENBQUMsQ0FBQztZQUN2RSxPQUFPO1FBQ1gsQ0FBQztRQUVELE9BQU8sQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUFDO1FBQzFCLE9BQU8sQ0FBQyxjQUFjLENBQUMsT0FBTyxHQUFHLEtBQUssQ0FBQztJQUMzQyxDQUFDO0lBRUQsS0FBSyxDQUFDLFlBQVksQ0FBQyxPQUFvQjtRQUNuQyxJQUFJLENBQUMsZUFBZSxDQUFDLGNBQWMsQ0FBQyxPQUFPLEdBQUcsS0FBSyxDQUFDO1FBQ3BELE9BQU8sQ0FBQyxjQUFjLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQztJQUMxQyxDQUFDO0lBRUQsS0FBSyxDQUFDLFFBQVEsQ0FBQyxPQUFvQixFQUFFLElBQVk7UUFDN0MsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUNiLE1BQU0sSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO1lBQ3hCLE9BQU87UUFDWCxDQUFDO1FBRUQsSUFBSSxDQUFDO1lBQ0QsTUFBTSxJQUFJLENBQUMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxPQUFPLENBQUMsRUFBRSxFQUFFLElBQUksQ0FBQyxDQUFDO1lBQ2hELE9BQU8sQ0FBQyxjQUFjLENBQUMsT0FBTyxHQUFHLEtBQUssQ0FBQztRQUMzQyxDQUFDO1FBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztZQUNULElBQUksQ0FBQyw2QkFBNkIsQ0FBQyxDQUFDLEVBQUUsMEJBQTBCLENBQUMsQ0FBQztRQUN0RSxDQUFDO0lBQ0wsQ0FBQzs4R0FoekJRLHNCQUFzQjtrR0FBdEIsc0JBQXNCLCt5Q0FnSGpCLDhCQUE4QiwyQkFBUyxXQUFXLDhKQThJbEQsb0JBQW9CLGdEQ3ZSdEMseWljQW1SQTs7MkZEMVBhLHNCQUFzQjtrQkFMbEMsU0FBUzsrQkFDSSxnQkFBZ0I7eUxBa0gxQixhQUFhO3NCQURaLFdBQVc7dUJBQUMsb0JBQW9CO2dCQUlqQyx3QkFBd0I7c0JBRHZCLFlBQVk7dUJBQUMsOEJBQThCLEVBQUUsRUFBQyxJQUFJLEVBQUUsV0FBVyxFQUFDO2dCQXNGeEQsZUFBZTtzQkFBdkIsS0FBSztnQkE0QkcsR0FBRztzQkFBWCxLQUFLO2dCQUVHLGdCQUFnQjtzQkFBeEIsS0FBSztnQkFDRyxlQUFlO3NCQUF2QixLQUFLO2dCQVVHLGdCQUFnQjtzQkFBeEIsS0FBSztnQkFhTixXQUFXO3NCQURWLFNBQVM7dUJBQUMsYUFBYTtnQkFJeEIsZUFBZTtzQkFEZCxZQUFZO3VCQUFDLG9CQUFvQjtnQkE2RnpCLFdBQVc7c0JBQW5CLEtBQUs7Z0JBQ0csU0FBUztzQkFBakIsS0FBSztnQkFDRyxjQUFjO3NCQUF0QixLQUFLO2dCQUNHLFVBQVU7c0JBQWxCLEtBQUs7Z0JBQ0csWUFBWTtzQkFBcEIsS0FBSztnQkFDRyxxQkFBcUI7c0JBQTdCLEtBQUs7Z0JBQ0csZ0JBQWdCO3NCQUF4QixLQUFLO2dCQUNHLGNBQWM7c0JBQXRCLEtBQUs7Z0JBQ0csZ0JBQWdCO3NCQUF4QixLQUFLO2dCQUNHLFdBQVc7c0JBQW5CLEtBQUs7Z0JBQ0csV0FBVztzQkFBbkIsS0FBSztnQkFDRyxrQkFBa0I7c0JBQTFCLEtBQUs7Z0JBQ0csZ0JBQWdCO3NCQUF4QixLQUFLO2dCQUVHLDBCQUEwQjtzQkFBbEMsS0FBSztnQkFDRyxZQUFZO3NCQUFwQixLQUFLO2dCQUtGLE1BQU07c0JBRFQsS0FBSztnQkE4Q04sUUFBUTtzQkFEUCxLQUFLO2dCQU9GLE9BQU87c0JBRFYsS0FBSztnQkFXUSxjQUFjO3NCQUEzQixNQUFNO2dCQUNPLGtCQUFrQjtzQkFBL0IsTUFBTTtnQkFDTyxxQkFBcUI7c0JBQWxDLE1BQU07Z0JBQ08sT0FBTztzQkFBcEIsTUFBTTtnQkFDTyxRQUFRO3NCQUFyQixNQUFNO2dCQUNPLFFBQVE7c0JBQXJCLE1BQU07Z0JBQ08sWUFBWTtzQkFBekIsTUFBTTtnQkFDTyxnQkFBZ0I7c0JBQTdCLE1BQU07Z0JBQ08sY0FBYztzQkFBM0IsTUFBTTtnQkFDTyxNQUFNO3NCQUFuQixNQUFNO2dCQVdNLFNBQVM7c0JBQXJCLEtBQUs7Z0JBU08sVUFBVTtzQkFBdEIsS0FBSztnQkFjTyxRQUFRO3NCQUFwQixLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiLy8vIDxyZWZlcmVuY2UgdHlwZXM9XCJAdHlwZXMvcmVzaXplLW9ic2VydmVyLWJyb3dzZXJcIiAvPlxyXG5cclxuaW1wb3J0IHsgQ29tcG9uZW50LCBDb250ZW50Q2hpbGQsIEVsZW1lbnRSZWYsIEhvc3RCaW5kaW5nLCBJbnB1dCwgTmdab25lLCBPdXRwdXQsIFF1ZXJ5TGlzdCwgVGVtcGxhdGVSZWYsIFZpZXdDaGlsZCwgVmlld0NoaWxkcmVuIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IFVzZXIsIENoYXRNZXNzYWdlLCBDb21tZW50c09yZGVyLCBGaWx0ZXJNb2RlIH0gZnJvbSAnQGJhbnRhL2NvbW1vbic7XHJcbmltcG9ydCB7IEhhc2hUYWcgfSBmcm9tICcuLi9jb21tZW50LWZpZWxkL2NvbW1lbnQtZmllbGQuY29tcG9uZW50JztcclxuaW1wb3J0IHsgU3ViamVjdCwgT2JzZXJ2YWJsZSwgU3Vic2NyaXB0aW9uIH0gZnJvbSAncnhqcyc7XHJcbmltcG9ydCB7IHRha2UgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XHJcblxyXG5pbXBvcnQgeyBBY3RpdmF0ZWRSb3V0ZSB9IGZyb20gJ0Bhbmd1bGFyL3JvdXRlcic7XHJcbmltcG9ydCB7IENoYXRCYWNrZW5kQmFzZSB9IGZyb20gJy4uLy4uL2NoYXQtYmFja2VuZC1iYXNlJztcclxuaW1wb3J0IHsgQ2hhdFNvdXJjZUJhc2UgfSBmcm9tICcuLi8uLi9jaGF0LXNvdXJjZS1iYXNlJztcclxuaW1wb3J0IHsgTWF0U25hY2tCYXIgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9zbmFjay1iYXInO1xyXG5pbXBvcnQgeyBCYW50YVJlcGx5U2VuZE9wdGlvbnNEaXJlY3RpdmUgfSBmcm9tICcuLi9yZXBseS1zZW5kLW9wdGlvbnMuZGlyZWN0aXZlJztcclxuaW1wb3J0IHsgTWVzc2FnZU1lbnVJdGVtIH0gZnJvbSAnLi4vLi4vbWVzc2FnZS1tZW51LWl0ZW0nO1xyXG5pbXBvcnQgeyBDb21tZW50Vmlld0NvbXBvbmVudCB9IGZyb20gJy4uL2NvbW1lbnQtdmlldy9jb21tZW50LXZpZXcuY29tcG9uZW50JztcclxuaW1wb3J0IHsgQ29tbWVudENvbXBvbmVudCB9IGZyb20gJy4uL2NvbW1lbnQvY29tbWVudC5jb21wb25lbnQnO1xyXG5cclxuLyoqXHJcbiAqIENvbW1lbnRzIGNvbXBvbmVudFxyXG4gKi9cclxuQENvbXBvbmVudCh7XHJcbiAgICBzZWxlY3RvcjogJ2JhbnRhLWNvbW1lbnRzJyxcclxuICAgIHRlbXBsYXRlVXJsOiAnLi9iYW50YS1jb21tZW50cy5jb21wb25lbnQuaHRtbCcsXHJcbiAgICBzdHlsZVVybHM6IFsnLi9iYW50YS1jb21tZW50cy5jb21wb25lbnQuc2NzcyddXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBCYW50YUNvbW1lbnRzQ29tcG9uZW50IHtcclxuICAgIGNvbnN0cnVjdG9yKFxyXG4gICAgICAgIHByaXZhdGUgYmFja2VuZDogQ2hhdEJhY2tlbmRCYXNlLFxyXG4gICAgICAgIHByaXZhdGUgZWxlbWVudFJlZjogRWxlbWVudFJlZjxIVE1MRWxlbWVudD4sXHJcbiAgICAgICAgcHJpdmF0ZSBhY3RpdmF0ZWRSb3V0ZTogQWN0aXZhdGVkUm91dGUsXHJcbiAgICAgICAgcHJpdmF0ZSBtYXRTbmFja0JhcjogTWF0U25hY2tCYXIsXHJcbiAgICAgICAgcHJpdmF0ZSBuZ1pvbmU6IE5nWm9uZVxyXG4gICAgKSB7XHJcbiAgICAgICAgdGhpcy5zZW5kTWVzc2FnZSA9IGFzeW5jIChtZXNzYWdlOiBDaGF0TWVzc2FnZSkgPT4ge1xyXG4gICAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgaW50ZXJjZXB0ID0gYXdhaXQgdGhpcy5zaG91bGRJbnRlcmNlcHRNZXNzYWdlU2VuZD8uKG1lc3NhZ2UsIHRoaXMuc291cmNlKTtcclxuICAgICAgICAgICAgICAgIGlmICghaW50ZXJjZXB0KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5zb3VyY2Uuc2VuZChtZXNzYWdlKTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5zb3VyY2Uuc29ydE9yZGVyICE9PSBDb21tZW50c09yZGVyLk5FV0VTVClcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnNvcnRPcmRlciA9IENvbW1lbnRzT3JkZXIuTkVXRVNUO1xyXG5cclxuICAgICAgICAgICAgICAgIGlmICh0aGlzLnNvdXJjZS5maWx0ZXJNb2RlICE9PSBGaWx0ZXJNb2RlLkFMTClcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmZpbHRlck1vZGUgPSBGaWx0ZXJNb2RlLkFMTDtcclxuXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5oYW5kbGVCYWNrZW5kRXhjZXB0aW9uKGUsICdDb3VsZCBub3Qgc2VuZDogJyk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRoaXMuc2VuZFJlcGx5ID0gYXN5bmMgKG1lc3NhZ2U6IENoYXRNZXNzYWdlKSA9PiB7XHJcbiAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBpbnRlcmNlcHQgPSBhd2FpdCB0aGlzLnNob3VsZEludGVyY2VwdE1lc3NhZ2VTZW5kPy4obWVzc2FnZSwgdGhpcy5zZWxlY3RlZE1lc3NhZ2VUaHJlYWQpO1xyXG4gICAgICAgICAgICAgICAgaWYgKCFpbnRlcmNlcHQpIHtcclxuICAgICAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLnNlbGVjdGVkTWVzc2FnZVRocmVhZC5zZW5kKG1lc3NhZ2UpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuaGFuZGxlQmFja2VuZEV4Y2VwdGlvbihlLCAnQ291bGQgbm90IHNlbmQgcmVwbHk6ICcpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGdldCBlbGVtZW50KCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudDtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIGhhbmRsZUJhY2tlbmRFeGNlcHRpb25Bc0FsZXJ0KGU6IEVycm9yLCBwcmVmaXg6IHN0cmluZyA9ICcnKSB7XHJcbiAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgdGhpcy5oYW5kbGVCYWNrZW5kRXhjZXB0aW9uKGUsIHByZWZpeCk7XHJcbiAgICAgICAgfSBjYXRjaCAoZSkge1xyXG4gICAgICAgICAgICBjb25zb2xlLmxvZyhgW0JhbnRhL0NvbW1lbnRzXSBTaG93ZWQgdXNlciBlcnJvciAodmlhIGFsZXJ0KTogJyR7ZS5tZXNzYWdlfSdgKTtcclxuICAgICAgICAgICAgY29uc29sZS5lcnJvcihlKTtcclxuICAgICAgICAgICAgXHJcbiAgICAgICAgICAgIGFsZXJ0KGUubWVzc2FnZSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgaGFuZGxlQmFja2VuZEV4Y2VwdGlvbkFzU25hY2soZTogRXJyb3IsIHByZWZpeDogc3RyaW5nID0gJycpIHtcclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICB0aGlzLmhhbmRsZUJhY2tlbmRFeGNlcHRpb24oZSwgcHJlZml4KTtcclxuICAgICAgICB9IGNhdGNoIChlKSB7XHJcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKGBbQmFudGEvQ29tbWVudHNdIFNob3dlZCB1c2VyIGVycm9yICh2aWEgc25hY2spOiAnJHtlLm1lc3NhZ2V9J2ApO1xyXG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKGUpO1xyXG4gICAgICAgICAgICBcclxuICAgICAgICAgICAgdGhpcy5tYXRTbmFja0Jhci5vcGVuKGUubWVzc2FnZSwgdW5kZWZpbmVkLCB7IGR1cmF0aW9uOiAzMDAwIH0pO1xyXG4gICAgICAgICAgICAvL2FsZXJ0KGUubWVzc2FnZSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgaGFuZGxlQmFja2VuZEV4Y2VwdGlvbihlOiBFcnJvciwgcHJlZml4OiBzdHJpbmcgPSAnJykge1xyXG4gICAgICAgIGxldCBlcnJvck1lc3NhZ2UgPSBlLm1lc3NhZ2U7XHJcblxyXG4gICAgICAgIGlmIChlcnJvck1lc3NhZ2Uuc3RhcnRzV2l0aCgncGVybWlzc2lvbi1kZW5pZWR8JykpIHtcclxuICAgICAgICAgICAgZXJyb3JNZXNzYWdlID0gZXJyb3JNZXNzYWdlLnJlcGxhY2UoL15wZXJtaXNzaW9uLWRlbmllZFxcfC8sICcnKTtcclxuXHJcbiAgICAgICAgICAgIGlmIChlcnJvck1lc3NhZ2Uuc3RhcnRzV2l0aChgYXBwLWhhbmRsZXxgKSkge1xyXG4gICAgICAgICAgICAgICAgLy8gSWYgdGhpcyBpcyBhbiBlcnJvciBkdXJpbmcgYXV0aG9yaXplQWN0aW9uIG9uIHRoZSBiYWNrZW5kLCBwYXNzIGNvbnRyb2wgdG8gdGhlIHVzZXItcHJvdmlkZWQgXHJcbiAgICAgICAgICAgICAgICAvLyBwZXJtaXNzaW9uLWRlbmllZCBoYW5kbGVyLlxyXG5cclxuICAgICAgICAgICAgICAgIHRoaXMuc2VuZFBlcm1pc3Npb25EZW5pZWQoZXJyb3JNZXNzYWdlLnJlcGxhY2UoL15hcHAtaGFuZGxlXFx8LywgJycpKTtcclxuICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAke3ByZWZpeH0ke2Vycm9yTWVzc2FnZX1gKTtcclxuICAgIH1cclxuXHJcbiAgICAvLyBMaWZlY3ljbGUgRXZlbnRzIC8gSW5pdGlhbGl6YXRpb25cclxuXHJcbiAgICBuZ09uSW5pdCgpIHtcclxuICAgICAgICB0aGlzLl9zdWJzLmFkZCh0aGlzLmJhY2tlbmQudXNlckNoYW5nZWQuc3Vic2NyaWJlKHVzZXIgPT4gdGhpcy51c2VyID0gdXNlcikpO1xyXG4gICAgICAgIHRoaXMuc3RhcnRMb2FkaW5nKCk7XHJcblxyXG4gICAgICAgIGlmICh0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJykge1xyXG4gICAgICAgICAgICBsZXQgcXVlcnlTdHJpbmcgPSB3aW5kb3cubG9jYXRpb24uc2VhcmNoLnN1YnN0cmluZygxKTtcclxuICAgICAgICAgICAgbGV0IHF1ZXJ5ID0gcXVlcnlTdHJpbmcuc3BsaXQoJyYnKVxyXG4gICAgICAgICAgICAgICAgLm1hcChzID0+IHMuc3BsaXQoJz0nKSlcclxuICAgICAgICAgICAgICAgIC5yZWR1Y2UoKG8sIFtrLCB2XSkgPT4gKG9bZGVjb2RlVVJJQ29tcG9uZW50KGspXSA9IGRlY29kZVVSSUNvbXBvbmVudCh2KSwgbyksIHt9KVxyXG4gICAgICAgICAgICA7XHJcblxyXG4gICAgICAgICAgICBjb25zdCBjb21tZW50SUQgPSBxdWVyeVsnY29tbWVudCddO1xyXG4gICAgICAgICAgICBpZiAoY29tbWVudElEKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnNoYXJlZENvbW1lbnRJRCA9IGNvbW1lbnRJRDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIHJlc2l6ZU9ic2VydmVyOiBSZXNpemVPYnNlcnZlcjtcclxuICAgIHByaXZhdGUgd2lkdGg6IG51bWJlcjtcclxuICAgIHByaXZhdGUgaGVpZ2h0OiBudW1iZXI7XHJcblxyXG4gICAgQEhvc3RCaW5kaW5nKCdjbGFzcy5iYW50YS1tb2JpbGUnKVxyXG4gICAgaXNNb2JpbGVTaXplZDogYm9vbGVhbiA9IGZhbHNlO1xyXG5cclxuICAgIEBDb250ZW50Q2hpbGQoQmFudGFSZXBseVNlbmRPcHRpb25zRGlyZWN0aXZlLCB7cmVhZDogVGVtcGxhdGVSZWZ9KSBcclxuICAgIHNlbmRSZXBseU9wdGlvbnNUZW1wbGF0ZTogYW55O1xyXG5cclxuICAgIG1hcmtWaWV3UmVhZHk6ICgpID0+IHZvaWQ7XHJcbiAgICB2aWV3UmVhZHkgPSBuZXcgUHJvbWlzZTx2b2lkPihyID0+IHRoaXMubWFya1ZpZXdSZWFkeSA9IHIpO1xyXG5cclxuICAgIG5nQWZ0ZXJWaWV3SW5pdCgpIHtcclxuICAgICAgICBpZiAodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcpIHtcclxuICAgICAgICAgICAgbGV0IGNhbGxiYWNrID0gKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgbGV0IHNpemUgPSB0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcclxuICAgICAgICAgICAgICAgIHRoaXMubmdab25lLnJ1bigoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMud2lkdGggPSBzaXplLndpZHRoO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmhlaWdodCA9IHNpemUuaGVpZ2h0O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmlzTW9iaWxlU2l6ZWQgPSB0aGlzLndpZHRoIDwgNTAwO1xyXG4gICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgIGlmICh0eXBlb2YgUmVzaXplT2JzZXJ2ZXIgIT09ICd1bmRlZmluZWQnKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnJlc2l6ZU9ic2VydmVyID0gbmV3IFJlc2l6ZU9ic2VydmVyKGNhbGxiYWNrKTtcclxuICAgICAgICAgICAgICAgIHRoaXMucmVzaXplT2JzZXJ2ZXIub2JzZXJ2ZSh0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudCk7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAvLyBPbmUgY2hlY2sgaXMgYmV0dGVyIHRoYW4gbm90aGluZyFcclxuICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMud2lkdGggPSB0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5jbGllbnRXaWR0aDtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmhlaWdodCA9IHRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LmNsaWVudEhlaWdodDtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmlzTW9iaWxlU2l6ZWQgPSB0aGlzLndpZHRoIDwgNTAwO1xyXG4gICAgICAgICAgICAgICAgfSwgMTAwMCk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGNhbGxiYWNrKCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLm1hcmtWaWV3UmVhZHkoKTtcclxuICAgIH1cclxuXHJcbiAgICBuZ09uRGVzdHJveSgpIHtcclxuICAgICAgICB0aGlzLl9zdWJzLnVuc3Vic2NyaWJlKCk7XHJcbiAgICAgICAgaWYgKHRoaXMucmVzaXplT2JzZXJ2ZXIpXHJcbiAgICAgICAgICAgIHRoaXMucmVzaXplT2JzZXJ2ZXIuZGlzY29ubmVjdCgpO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgYXN5bmMgc2V0U291cmNlRnJvbVRvcGljSUQodG9waWNJRDogc3RyaW5nKSB7XHJcbiAgICAgICAgaWYgKHR5cGVvZiB3aW5kb3cgPT09ICd1bmRlZmluZWQnKVxyXG4gICAgICAgICAgICByZXR1cm47XHJcblxyXG4gICAgICAgIHNldFRpbWVvdXQoYXN5bmMgKCkgPT4ge1xyXG4gICAgICAgICAgICBjb25zb2xlLmxvZyhgW0JhbnRhL0NvbW1lbnRzXSBTdWJzY3JpYmluZyB0byB0b3BpYyBzb3VyY2UgJyR7dG9waWNJRH0nYCk7XHJcbiAgICAgICAgICAgIHRoaXMuc291cmNlID0gYXdhaXQgdGhpcy5iYWNrZW5kLmdldFNvdXJjZUZvclRvcGljKHRvcGljSUQsIHsgXHJcbiAgICAgICAgICAgICAgICBzb3J0T3JkZXI6IHRoaXMuc29ydE9yZGVyLCBcclxuICAgICAgICAgICAgICAgIGZpbHRlck1vZGU6IHRoaXMuZmlsdGVyTW9kZSxcclxuICAgICAgICAgICAgICAgIG1ldGFkYXRhOiB0aGlzLm1ldGFkYXRhXHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB0aGlzLl9zb3VyY2VJc093bmVkID0gdHJ1ZTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBsb2FkaW5nVGl0bGUgPSAnTG9hZGluZy4uLic7XHJcblxyXG4gICAgLy8gTG9hZGluZyBTY3JlZW5cclxuICAgIHByaXZhdGUgX2xvYWRpbmdNZXNzYWdlID0gJyc7XHJcbiAgICBsb2FkaW5nTWVzc2FnZVZpc2libGUgPSBmYWxzZTtcclxuXHJcbiAgICBnZXQgbG9hZGluZ01lc3NhZ2UoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2xvYWRpbmdNZXNzYWdlO1xyXG4gICAgfVxyXG5cclxuICAgIHNldCBsb2FkaW5nTWVzc2FnZSh2YWx1ZSkge1xyXG4gICAgICAgIHRoaXMubG9hZGluZ01lc3NhZ2VWaXNpYmxlID0gZmFsc2U7XHJcbiAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XHJcbiAgICAgICAgICAgIHRoaXMuX2xvYWRpbmdNZXNzYWdlID0gdmFsdWU7XHJcbiAgICAgICAgICAgIHRoaXMuX2xvYWRpbmdNZXNzYWdlID0gdmFsdWU7XHJcbiAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5sb2FkaW5nTWVzc2FnZVZpc2libGUgPSB0cnVlO1xyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgIH0sIDUwMCk7XHJcbiAgICB9XHJcblxyXG4gICAgbG9hZGluZzogYm9vbGVhbiA9IHRydWU7XHJcbiAgICBzaG93TG9hZGluZ1NjcmVlbiA9IGZhbHNlO1xyXG4gICAgbG9hZGluZ1N0YXJ0ZWRBdDogbnVtYmVyO1xyXG4gICAgbWVzc2FnZUNoYW5nZWRBdDogbnVtYmVyO1xyXG4gICAgc2hhcmVkQ29tbWVudElEOiBzdHJpbmc7XHJcbiAgICBsYXN0U2hhcmVkQ29tbWVudElEOiBzdHJpbmc7XHJcblxyXG4gICAgQElucHV0KCkgY3VzdG9tTWVudUl0ZW1zOiBNZXNzYWdlTWVudUl0ZW1bXSA9IFtdO1xyXG5cclxuICAgIHByaXZhdGUgYXN5bmMgc3RhcnRMb2FkaW5nKCkge1xyXG4gICAgICAgIHRoaXMubG9hZGluZ1N0YXJ0ZWRBdCA9IHRoaXMubWVzc2FnZUNoYW5nZWRBdCA9IERhdGUubm93KCk7XHJcblxyXG4gICAgICAgIGlmICh0aGlzLnVwZGF0ZUxvYWRpbmcoKSkgcmV0dXJuO1xyXG4gICAgICAgIGF3YWl0IG5ldyBQcm9taXNlPHZvaWQ+KHJlc29sdmUgPT4gc2V0VGltZW91dCgoKSA9PiByZXNvbHZlKCksIDEwMCkpO1xyXG4gICAgICAgIGlmICh0aGlzLnVwZGF0ZUxvYWRpbmcoKSkgcmV0dXJuO1xyXG4gICAgICAgIGF3YWl0IG5ldyBQcm9taXNlPHZvaWQ+KHJlc29sdmUgPT4gc2V0VGltZW91dCgoKSA9PiByZXNvbHZlKCksIDI1MCkpO1xyXG4gICAgICAgIGlmICh0aGlzLnVwZGF0ZUxvYWRpbmcoKSkgcmV0dXJuO1xyXG4gICAgICAgIGF3YWl0IG5ldyBQcm9taXNlPHZvaWQ+KHJlc29sdmUgPT4gc2V0VGltZW91dCgoKSA9PiByZXNvbHZlKCksIDUwMCkpO1xyXG4gICAgICAgIGlmICh0aGlzLnVwZGF0ZUxvYWRpbmcoKSkgcmV0dXJuO1xyXG5cclxuICAgICAgICBjb25zb2xlLmxvZyhgW0JhbnRhXSBMb2FkaW5nIGlzIHRha2luZyBhIGxvbmcgdGltZSEgU2hvd2luZyBsb2FkaW5nIHNjcmVlbi5gKTtcclxuICAgICAgICB0aGlzLnNob3dMb2FkaW5nU2NyZWVuID0gdHJ1ZTtcclxuICAgICAgICBpZiAodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcpXHJcbiAgICAgICAgICAgIHRoaXMuX2xvYWRpbmdUaW1lciA9IHNldEludGVydmFsKCgpID0+IHtcclxuICAgICAgICAgICAgICAgIHRoaXMudXBkYXRlTG9hZGluZygpO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5sb2FkaW5nVGl0bGUgPSBgQ29ubmVjdGluZyB0byBMaXZlIENvbW1lbnRzIHNlcnZpY2UuLi5gO1xyXG4gICAgICAgICAgICB9LCAxMDAwKTtcclxuICAgIH1cclxuICAgIFxyXG4gICAgcHJpdmF0ZSBfbG9hZGluZ1RpbWVyO1xyXG4gICAgcHJpdmF0ZSBfbG9hZGluZ01lc3NhZ2VJbmRleCA9IDA7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgY2Fub25pY2FsIFVSTCB3aGVyZSB0aGlzIGNvbW1lbnQgc2VjdGlvbiBjYW4gYmUgZm91bmQuIElmIG5vdCBzcGVjaWZpZWQsIHVzZXMgdGhlIGN1cnJlbnQgVVJMLlxyXG4gICAgICovXHJcbiAgICBASW5wdXQoKSB1cmw6IHN0cmluZztcclxuXHJcbiAgICBASW5wdXQoKSBtYXhDb21tZW50TGVuZ3RoOiBudW1iZXIgPSAxNTAwO1xyXG4gICAgQElucHV0KCkgbG9hZGluZ01lc3NhZ2VzOiBzdHJpbmdbXSA9IFtcclxuICAgICAgICBgSnVzdCBhIHNlY29uZC4uLmAsXHJcbiAgICAgICAgYEl0J3MgZGVmaW5pdGVseSB3b3J0aCB0aGUgd2FpdCFgLFxyXG4gICAgICAgIGBUaGlzIGhhcyBuZXZlciBoYXBwZW5lZCBiZWZvcmUuYCxcclxuICAgICAgICBgV2UnbGwga2VlcCB0cnlpbmcsIGJ1dCBpdCdzIG5vdCBsb29raW5nIGdyZWF0LiBcclxuICAgICAgICAgICAgQ29tbWVudGluZyAmIGNoYXQgc2VydmljZXMgbWF5IGJlIGRvd24gb3IgZGVncmFkZWQuIFRyeSByZWxvYWRpbmcgdGhlIHBhZ2UuXHJcbiAgICAgICAgICAgIElmIHlvdSBrZWVwIGV4cGVyaWVuY2luZyBpc3N1ZXMgb3IgcmVsb2FkaW5nIHRoZSBwYWdlIHdvcmtzIGZvciB5b3UsIHBsZWFzZSBsZXQgdXMga25vdyBieSBjb250YWN0aW5nIHN1cHBvcnQuXHJcbiAgICAgICAgYFxyXG4gICAgXTtcclxuXHJcbiAgICBASW5wdXQoKSB1c2VJbmxpbmVSZXBsaWVzID0gdHJ1ZTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEFjY2VzcyB0aGUgQ29tbWVudFZpZXdDb21wb25lbnQgZm9yIHRoaXMgQmFudGFDb21tZW50c0NvbXBvbmVudC4gXHJcbiAgICAgKiBDb21tZW50Vmlld0NvbXBvbmVudCBpcyByZXNwb25zaWJsZSBmb3IgaW50ZXJhY3Rpbmcgd2l0aCB0aGUgQ2hhdFNvdXJjZSBcclxuICAgICAqIG9iamVjdCBhbmQgcmVuZGVyaW5nIGNvbW1lbnRzIGFzIENvbW1lbnRDb21wb25lbnRzLiBJdCBpcyB0aGUgc291cmNlIG9mIFxyXG4gICAgICogdHJ1dGggZm9yIHdoaWNoIENvbW1lbnRDb21wb25lbnQgY29ycmVzcG9uZHMgdG8gd2hpY2ggQ2hhdE1lc3NhZ2UuIFxyXG4gICAgICogXHJcbiAgICAgKiBOb3RlIHRoYXQgdGhpcyBDb21tZW50Vmlld0NvbXBvbmVudCBpcyBvbmx5IGZvciB0aGUgdG9wIGxldmVsIGNvbW1lbnRzLlxyXG4gICAgICogUmVwbGllcyBhcmUgaGFuZGxlZCBieSBhIHNlcGFyYXRlIENvbW1lbnRWaWV3Q29tcG9uZW50IHdoaWNoIGNhbiBiZSBcclxuICAgICAqIHJldHJpZXZlZCB1c2luZyB0aGUgdGhyZWFkVmlldyBwcm9wZXJ0eS5cclxuICAgICAqL1xyXG4gICAgQFZpZXdDaGlsZCgnY29tbWVudFZpZXcnKVxyXG4gICAgY29tbWVudFZpZXc6IENvbW1lbnRWaWV3Q29tcG9uZW50O1xyXG5cclxuICAgIEBWaWV3Q2hpbGRyZW4oQ29tbWVudFZpZXdDb21wb25lbnQpXHJcbiAgICB0aHJlYWRWaWV3UXVlcnk6IFF1ZXJ5TGlzdDxDb21tZW50Vmlld0NvbXBvbmVudD47XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBBdHRlbXB0cyB0byBmaW5kIHRoZSBDb21tZW50Q29tcG9uZW50IHRoYXQgY29ycmVzcG9uZHMgdG8gdGhlIGdpdmVuIENoYXRNZXNzYWdlLlxyXG4gICAgICogVGhlIENoYXRNZXNzYWdlIGNvdWxkIGJlIGEgdG9wLWxldmVsIG1lc3NhZ2UgaW4gdGhpcyBjb252ZXJzYXRpb24sIG9yIGEgcmVwbHksIFxyXG4gICAgICogYnV0IG5vdGUgdGhhdCBhIENvbW1lbnRDb21wb25lbnQgd2lsbCBvbmx5IGV4aXN0IGZvciBhIHJlcGx5IGlmIHRoZSB1c2VyIGhhcyBcclxuICAgICAqIHRoZSByZWxldmFudCByZXBseSB0aHJlYWQgb3Blbi5cclxuICAgICAqIEBwYXJhbSBtZXNzYWdlIFRoZSBtZXNzYWdlIHRvIGxvb2sgZm9yXHJcbiAgICAgKi9cclxuICAgIGdldENvbW1lbnRDb21wb25lbnRGb3JNZXNzYWdlKG1lc3NhZ2U6IENoYXRNZXNzYWdlKTogQ29tbWVudENvbXBvbmVudCB7XHJcbiAgICAgICAgaWYgKG1lc3NhZ2UucGFyZW50TWVzc2FnZUlkKVxyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy50aHJlYWRWaWV3Py5nZXRDb21tZW50Q29tcG9uZW50Rm9yTWVzc2FnZShtZXNzYWdlKTtcclxuICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmNvbW1lbnRWaWV3LmdldENvbW1lbnRDb21wb25lbnRGb3JNZXNzYWdlKG1lc3NhZ2UpXHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBBY2Nlc3MgdGhlIENvbW1lbnRWaWV3Q29tcG9uZW50IGNvcnJlc3BvbmRpbmcgdG8gdGhlIGN1cnJlbnRseSBvcGVuIHJlcGx5IHRocmVhZC5cclxuICAgICAqIFRoaXMgaXMgbm90IHRoZSB0b3AgbGV2ZWwgY29tbWVudHMsIGJ1dCBpbnN0ZWFkIHRoZSByZXBseSB0aHJlYWQgdGhhdCB0aGUgdXNlciBoYXMgXHJcbiAgICAgKiBvcGVuZWQgKG9ubHkgb25lIHNldCBvZiByZXBsaWVzIGNhbiBiZSBvcGVuIGF0IGEgdGltZSkuXHJcbiAgICAgKiBcclxuICAgICAqIEZvciBkZXRhaWxzIGFib3V0IHdoYXQgQ29tbWVudFZpZXdDb21wb25lbnQgYWZmb3JkcyB5b3UsIHNlZSB0aGUgY29tbWVudFZpZXcgcHJvcGVydHkuXHJcbiAgICAgKi9cclxuICAgIGdldCB0aHJlYWRWaWV3KCkge1xyXG4gICAgICAgIHJldHVybiBBcnJheS5mcm9tKHRoaXMudGhyZWFkVmlld1F1ZXJ5KS5maWx0ZXIoeCA9PiB4ICE9PSB0aGlzLmNvbW1lbnRWaWV3KVswXTtcclxuICAgIH1cclxuXHJcbiAgICBhc3luYyB3YWl0Rm9yVGhyZWFkVmlldygpIHtcclxuICAgICAgICBpZiAodGhpcy50aHJlYWRWaWV3KVxyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy50aHJlYWRWaWV3O1xyXG4gICAgICAgIFxyXG4gICAgICAgIGF3YWl0IHRoaXMudGhyZWFkVmlld1F1ZXJ5LmNoYW5nZXMucGlwZSh0YWtlKDEpKS50b1Byb21pc2UoKTtcclxuICAgICAgICByZXR1cm4gdGhpcy50aHJlYWRWaWV3O1xyXG4gICAgfVxyXG5cclxuICAgIG1hcmtMb2FkZWQ6ICgpID0+IHZvaWQ7XHJcbiAgICBsb2FkZWQgPSBuZXcgUHJvbWlzZTx2b2lkPihyID0+IHRoaXMubWFya0xvYWRlZCA9IHIpO1xyXG5cclxuICAgIHByaXZhdGUgdXBkYXRlTG9hZGluZygpOiBib29sZWFuIHtcclxuICAgICAgICBpZiAodGhpcy5zb3VyY2U/LnN0YXRlICYmICFbJ2Nvbm5lY3RpbmcnLCAnbG9zdCddLmluY2x1ZGVzKHRoaXMuc291cmNlPy5zdGF0ZSkpIHtcclxuICAgICAgICAgICAgY2xlYXJJbnRlcnZhbCh0aGlzLl9sb2FkaW5nVGltZXIpO1xyXG4gICAgICAgICAgICB0aGlzLmxvYWRpbmdNZXNzYWdlID0gYEhlcmUgd2UgZ28hYDtcclxuICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmxvYWRpbmcgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgIHRoaXMubWFya0xvYWRlZCgpO1xyXG4gICAgICAgICAgICB9LCA3NTApO1xyXG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGNvbnNvbGUubG9nKGBbQmFudGEvTG9hZGVyXSBTdGF0ZT0ke3RoaXMuc291cmNlID8gdGhpcy5zb3VyY2Uuc3RhdGUgOiAnbm8tc291cmNlJ31gKTtcclxuICAgICAgICBsZXQgbWVzc2FnZVN3aXRjaFRpbWUgPSA1KjEwMDA7XHJcbiAgICAgICAgaWYgKHRoaXMubWVzc2FnZUNoYW5nZWRBdCArIG1lc3NhZ2VTd2l0Y2hUaW1lIDwgRGF0ZS5ub3coKSkge1xyXG4gICAgICAgICAgICBpZiAodGhpcy5sb2FkaW5nTWVzc2FnZXNbdGhpcy5fbG9hZGluZ01lc3NhZ2VJbmRleF0pIHtcclxuICAgICAgICAgICAgICAgIHRoaXMubG9hZGluZ01lc3NhZ2UgPSB0aGlzLmxvYWRpbmdNZXNzYWdlc1t0aGlzLl9sb2FkaW5nTWVzc2FnZUluZGV4KytdO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5tZXNzYWdlQ2hhbmdlZEF0ID0gRGF0ZS5ub3coKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIFByb3BlcnRpZXNcclxuXHJcbiAgICBwcml2YXRlIF9zaWduSW5TZWxlY3RlZCA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XHJcbiAgICBwcml2YXRlIF9wZXJtaXNzaW9uRGVuaWVkRXJyb3IgPSBuZXcgU3ViamVjdDxzdHJpbmc+KCk7XHJcbiAgICBwcml2YXRlIF9lZGl0QXZhdGFyU2VsZWN0ZWQgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xyXG4gICAgcHJpdmF0ZSBfdXB2b3RlZCA9IG5ldyBTdWJqZWN0PENoYXRNZXNzYWdlPigpO1xyXG4gICAgcHJpdmF0ZSBfcmVwb3J0ZWQgPSBuZXcgU3ViamVjdDxDaGF0TWVzc2FnZT4oKTtcclxuICAgIHByaXZhdGUgX3NlbGVjdGVkID0gbmV3IFN1YmplY3Q8Q2hhdE1lc3NhZ2U+KCk7XHJcbiAgICBwcml2YXRlIF91c2VyU2VsZWN0ZWQgPSBuZXcgU3ViamVjdDxDaGF0TWVzc2FnZT4oKTtcclxuICAgIHByaXZhdGUgX3NoYXJlZCA9IG5ldyBTdWJqZWN0PENoYXRNZXNzYWdlPigpO1xyXG4gICAgcHJpdmF0ZSBfdXNlcm5hbWVTZWxlY3RlZCA9IG5ldyBTdWJqZWN0PFVzZXI+KCk7XHJcbiAgICBwcml2YXRlIF9hdmF0YXJTZWxlY3RlZCA9IG5ldyBTdWJqZWN0PFVzZXI+KCk7XHJcbiAgICBwcml2YXRlIF9zb3VyY2U6IENoYXRTb3VyY2VCYXNlO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogVHJhY2sgd2hldGhlciB3ZSBjcmVhdGVkIHRoaXMgc291cmNlLiBJZiB3ZSBkaWQgbm90IChpZSBpdCB3YXMgcGFzc2VkIGluIGZyb20gdGhlIGNhbGxlciksXHJcbiAgICAgKiB0aGVuIHdlIGFyZSBub3QgcmVzcG9uc2libGUgZm9yIGNhbGxpbmcgY2xvc2UoKS4gSWYgd2UgZG8gb3duIGl0IHRob3VnaCwgd2Ugd2lsbCBjYWxsIGNsb3NlKCkgXHJcbiAgICAgKiB3aGVuIHdlIGFyZSBkb25lIHdpdGggaXQuXHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgX3NvdXJjZUlzT3duZWQgPSBmYWxzZTtcclxuICAgIHByaXZhdGUgX3N1YnMgPSBuZXcgU3Vic2NyaXB0aW9uKCk7XHJcbiAgICBwcml2YXRlIF90b3BpY0lEOiBzdHJpbmc7XHJcbiAgICBcclxuICAgIHVzZXI6IFVzZXI7XHJcbiAgICBzZWxlY3RlZE1lc3NhZ2U6IENoYXRNZXNzYWdlO1xyXG4gICAgc2VsZWN0ZWRNZXNzYWdlVGhyZWFkOiBDaGF0U291cmNlQmFzZTtcclxuICAgIHNlbGVjdGVkTWVzc2FnZVZpc2libGUgPSBmYWxzZTtcclxuICAgIGNvbm5lY3Rpb25TdGF0ZTogc3RyaW5nO1xyXG5cclxuICAgIC8vIElucHV0c1xyXG5cclxuICAgIEBJbnB1dCgpIHNpZ25JbkxhYmVsID0gJ1NpZ24gSW4nO1xyXG4gICAgQElucHV0KCkgc2VuZExhYmVsID0gJ1NlbmQnO1xyXG4gICAgQElucHV0KCkgc2lnbmluZ0luTGFiZWwgPSAnU2lnbmluZyBpbi4uLic7XHJcbiAgICBASW5wdXQoKSByZXBseUxhYmVsID0gJ1JlcGx5JztcclxuICAgIEBJbnB1dCgpIHNlbmRpbmdMYWJlbCA9ICdTZW5kaW5nJztcclxuICAgIEBJbnB1dCgpIHBlcm1pc3Npb25EZW5pZWRMYWJlbCA9ICdTZW5kJztcclxuICAgIEBJbnB1dCgpIHBvc3RDb21tZW50TGFiZWwgPSAnUG9zdCBhIGNvbW1lbnQnO1xyXG4gICAgQElucHV0KCkgcG9zdFJlcGx5TGFiZWwgPSAnUG9zdCBhIHJlcGx5JztcclxuICAgIEBJbnB1dCgpIGFsbG93QXR0YWNobWVudHMgPSB0cnVlO1xyXG4gICAgQElucHV0KCkgZml4ZWRIZWlnaHQ6IGJvb2xlYW47XHJcbiAgICBASW5wdXQoKSBtYXhNZXNzYWdlczogbnVtYmVyO1xyXG4gICAgQElucHV0KCkgbWF4VmlzaWJsZU1lc3NhZ2VzOiBudW1iZXIgPSAyMDtcclxuICAgIEBJbnB1dCgpIGdlbmVyaWNBdmF0YXJVcmwgPSBgaHR0cHM6Ly9ncmF2YXRhci5jb20vYXZhdGFyLyR7RGF0ZS5ub3coKS50b1N0cmluZygxNil9P3M9NTEyJmQ9cm9ib2hhc2hgO1xyXG5cclxuICAgIEBJbnB1dCgpIHNob3VsZEludGVyY2VwdE1lc3NhZ2VTZW5kPzogKG1lc3NhZ2U6IENoYXRNZXNzYWdlLCBzb3VyY2U6IENoYXRTb3VyY2VCYXNlKSA9PiBib29sZWFuIHwgUHJvbWlzZTxib29sZWFuPjtcclxuICAgIEBJbnB1dCgpIHBhcnRpY2lwYW50czogVXNlcltdID0gW107XHJcblxyXG4gICAgcHJpdmF0ZSBfc291cmNlU3Vic2NyaXB0aW9uOiBTdWJzY3JpcHRpb247XHJcblxyXG4gICAgQElucHV0KClcclxuICAgIGdldCBzb3VyY2UoKTogQ2hhdFNvdXJjZUJhc2UgeyByZXR1cm4gdGhpcy5fc291cmNlOyB9XHJcbiAgICBzZXQgc291cmNlKHZhbHVlKSB7IFxyXG4gICAgICAgIGlmICh0aGlzLl9zb3VyY2UgJiYgdGhpcy5fc291cmNlSXNPd25lZCkge1xyXG4gICAgICAgICAgICB0aGlzLl9zb3VyY2UuY2xvc2UoKTtcclxuICAgICAgICAgICAgdGhpcy5fc291cmNlU3Vic2NyaXB0aW9uPy51bnN1YnNjcmliZSgpO1xyXG4gICAgICAgICAgICB0aGlzLl9zb3VyY2UgPSBudWxsO1xyXG4gICAgICAgICAgICB0aGlzLnBhcnRpY2lwYW50cyA9IFtdO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy5fc291cmNlID0gdmFsdWU7XHJcbiAgICAgICAgdGhpcy5fc291cmNlSXNPd25lZCA9IGZhbHNlOyAvLyBBc3N1bWUgd2UgZG9uJ3Qgb3duIHRoaXMgc291cmNlLlxyXG4gICAgICAgIHRoaXMuX3NvdXJjZVN1YnNjcmlwdGlvbiA9IG5ldyBTdWJzY3JpcHRpb24oKTtcclxuICAgICAgICBcclxuICAgICAgICBpZiAodmFsdWUpIHtcclxuICAgICAgICAgICAgaWYgKHRoaXMuc2hhcmVkQ29tbWVudElEKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLm5hdmlnYXRlVG9TaGFyZWRDb21tZW50KHRoaXMuc2hhcmVkQ29tbWVudElEKTtcclxuICAgICAgICAgICAgICAgIHRoaXMubGFzdFNoYXJlZENvbW1lbnRJRCA9IHRoaXMuc2hhcmVkQ29tbWVudElEO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5zaGFyZWRDb21tZW50SUQgPSBudWxsO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICB0aGlzLl9zb3VyY2UubWVzc2FnZXMuZm9yRWFjaChtID0+IHRoaXMuYWRkUGFydGljaXBhbnQobSkpO1xyXG5cclxuICAgICAgICAgICAgdGhpcy5fc291cmNlU3Vic2NyaXB0aW9uLmFkZCh0aGlzLl9zb3VyY2UuY29ubmVjdGlvblN0YXRlQ2hhbmdlZC5zdWJzY3JpYmUoc3RhdGUgPT4gdGhpcy5jb25uZWN0aW9uU3RhdGUgPSBzdGF0ZSkpO1xyXG4gICAgICAgICAgICB0aGlzLl9zb3VyY2VTdWJzY3JpcHRpb24uYWRkKHRoaXMuX3NvdXJjZS5tZXNzYWdlUmVjZWl2ZWQuc3Vic2NyaWJlKG0gPT4gdGhpcy5hZGRQYXJ0aWNpcGFudChtKSkpO1xyXG4gICAgICAgICAgICB0aGlzLl9zb3VyY2VTdWJzY3JpcHRpb24uYWRkKHRoaXMuX3NvdXJjZS5tZXNzYWdlU2VudC5zdWJzY3JpYmUobSA9PiB0aGlzLmFkZFBhcnRpY2lwYW50KG0pKSk7XHJcbiAgICAgICAgICAgIHRoaXMuX3NvdXJjZVN1YnNjcmlwdGlvbi5hZGQodGhpcy5fc291cmNlLm1lc3NhZ2VPYnNlcnZlZC5zdWJzY3JpYmUobSA9PiB0aGlzLmFkZFBhcnRpY2lwYW50KG0pKSk7XHJcbiAgICAgICAgICAgIHRoaXMuX3NvdXJjZVN1YnNjcmlwdGlvbi5hZGQoXHJcbiAgICAgICAgICAgICAgICB0aGlzLl9zb3VyY2UubWVzc2FnZVVwZGF0ZWQuc3Vic2NyaWJlKG1zZyA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coYGNvbW1lbnRzIHJlY2VpdmVkIG1lc3NhZ2U6IGAsIG1zZyk7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKG1zZy5pZCA9PT0gdGhpcy5zZWxlY3RlZE1lc3NhZ2U/LmlkICYmIG1zZy5oaWRkZW4pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy51bnNlbGVjdE1lc3NhZ2UoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5tYXRTbmFja0Jhci5vcGVuKFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJUaGUgdGhyZWFkIHlvdSB3ZXJlIHZpZXdpbmcgd2FzIHJlbW92ZWQuXCIsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bmRlZmluZWQsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHVyYXRpb246IDI1MDBcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgKVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgICk7XHJcblxyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIEBJbnB1dCgpIFxyXG4gICAgaGFzaHRhZ3M6IEhhc2hUYWdbXSA9IFtcclxuICAgICAgICB7aGFzaHRhZzogJ2Vycm9yJywgZGVzY3JpcHRpb246ICdDYXVzZSBhbiBlcnJvcid9LFxyXG4gICAgICAgIHtoYXNodGFnOiAndGltZW91dCcsIGRlc2NyaXB0aW9uOiAnQ2F1c2UgYSBzbG93IHRpbWVvdXQgZXJyb3InfSxcclxuICAgICAgICB7aGFzaHRhZzogJ3Nsb3cnLCBkZXNjcmlwdGlvbjogJ0JlIHNsb3cgd2hlbiB0aGlzIG1lc3NhZ2UgaXMgcG9zdGVkJ30sXHJcbiAgICBdO1xyXG4gICAgQElucHV0KClcclxuICAgIGdldCB0b3BpY0lEKCk6IHN0cmluZyB7IHJldHVybiB0aGlzLl90b3BpY0lEOyB9XHJcbiAgICBzZXQgdG9waWNJRCh2YWx1ZSkge1xyXG4gICAgICAgIGlmICh0aGlzLl90b3BpY0lEICE9PSB2YWx1ZSkge1xyXG4gICAgICAgICAgICB0aGlzLl90b3BpY0lEID0gdmFsdWU7XHJcbiAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4gdGhpcy5zZXRTb3VyY2VGcm9tVG9waWNJRCh2YWx1ZSkpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvLyBPdXRwdXRzXHJcblxyXG4gICAgQE91dHB1dCgpIGdldCBzaWduSW5TZWxlY3RlZCgpOiBPYnNlcnZhYmxlPHZvaWQ+IHsgcmV0dXJuIHRoaXMuX3NpZ25JblNlbGVjdGVkOyB9XHJcbiAgICBAT3V0cHV0KCkgZ2V0IGVkaXRBdmF0YXJTZWxlY3RlZCgpIHsgcmV0dXJuIHRoaXMuX2VkaXRBdmF0YXJTZWxlY3RlZDsgfVxyXG4gICAgQE91dHB1dCgpIGdldCBwZXJtaXNzaW9uRGVuaWVkRXJyb3IoKTogT2JzZXJ2YWJsZTxzdHJpbmc+IHsgcmV0dXJuIHRoaXMuX3Blcm1pc3Npb25EZW5pZWRFcnJvcjsgfVxyXG4gICAgQE91dHB1dCgpIGdldCB1cHZvdGVkKCkgeyByZXR1cm4gdGhpcy5fdXB2b3RlZC5hc09ic2VydmFibGUoKTsgfVxyXG4gICAgQE91dHB1dCgpIGdldCByZXBvcnRlZCgpIHsgcmV0dXJuIHRoaXMuX3JlcG9ydGVkLmFzT2JzZXJ2YWJsZSgpOyB9XHJcbiAgICBAT3V0cHV0KCkgZ2V0IHNlbGVjdGVkKCkgeyByZXR1cm4gdGhpcy5fc2VsZWN0ZWQuYXNPYnNlcnZhYmxlKCk7IH1cclxuICAgIEBPdXRwdXQoKSBnZXQgdXNlclNlbGVjdGVkKCkgeyByZXR1cm4gdGhpcy5fdXNlclNlbGVjdGVkLmFzT2JzZXJ2YWJsZSgpOyB9XHJcbiAgICBAT3V0cHV0KCkgZ2V0IHVzZXJuYW1lU2VsZWN0ZWQoKSB7IHJldHVybiB0aGlzLl91c2VybmFtZVNlbGVjdGVkLmFzT2JzZXJ2YWJsZSgpOyB9XHJcbiAgICBAT3V0cHV0KCkgZ2V0IGF2YXRhclNlbGVjdGVkKCkgeyByZXR1cm4gdGhpcy5fYXZhdGFyU2VsZWN0ZWQuYXNPYnNlcnZhYmxlKCk7IH1cclxuICAgIEBPdXRwdXQoKSBnZXQgc2hhcmVkKCkgeyByZXR1cm4gdGhpcy5fc2hhcmVkLmFzT2JzZXJ2YWJsZSgpOyB9XHJcblxyXG4gICAgcHJpdmF0ZSBfcmVsb2FkU291cmNlVGltZW91dDtcclxuICAgIHByaXZhdGUgcmVsb2FkU291cmNlKCkge1xyXG4gICAgICAgIGNsZWFyVGltZW91dCh0aGlzLl9yZWxvYWRTb3VyY2VUaW1lb3V0KTtcclxuICAgICAgICB0aGlzLl9yZWxvYWRTb3VyY2VUaW1lb3V0ID0gc2V0VGltZW91dCgoKSA9PiB7XHJcbiAgICAgICAgICAgIHRoaXMuc2V0U291cmNlRnJvbVRvcGljSUQodGhpcy50b3BpY0lEKTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIF9zb3J0T3JkZXI6IENvbW1lbnRzT3JkZXIgPSAnbmV3ZXN0JztcclxuICAgIEBJbnB1dCgpIGdldCBzb3J0T3JkZXIoKSB7IHJldHVybiB0aGlzLl9zb3J0T3JkZXI7IH1cclxuICAgIHNldCBzb3J0T3JkZXIodmFsdWUpIHtcclxuICAgICAgICBpZiAodGhpcy5fc29ydE9yZGVyICE9PSB2YWx1ZSkge1xyXG4gICAgICAgICAgICB0aGlzLl9zb3J0T3JkZXIgPSB2YWx1ZTtcclxuICAgICAgICAgICAgdGhpcy5yZWxvYWRTb3VyY2UoKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfZmlsdGVyTW9kZTogRmlsdGVyTW9kZSA9IEZpbHRlck1vZGUuQUxMO1xyXG4gICAgQElucHV0KCkgZ2V0IGZpbHRlck1vZGUoKSB7IHJldHVybiB0aGlzLl9maWx0ZXJNb2RlOyB9XHJcbiAgICBzZXQgZmlsdGVyTW9kZSh2YWx1ZSkgeyBcclxuICAgICAgICBpZiAodGhpcy5fZmlsdGVyTW9kZSAhPT0gdmFsdWUpIHtcclxuICAgICAgICAgICAgdGhpcy5fZmlsdGVyTW9kZSA9IHZhbHVlO1xyXG4gICAgICAgICAgICB0aGlzLnJlbG9hZFNvdXJjZSgpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIF9tZXRhZGF0YTogUmVjb3JkPHN0cmluZywgYW55PiA9IHt9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQXJiaXRyYXJ5IG1ldGFkYXRhIHRvIHNlbmQgdG8gdGhlIGNoYXQgc2VydmVyLiBUaGlzIGNhbiBiZSB1c2VkIHRvIHByb3ZpZGUgY29udGV4dCBhYm91dCB0aGUgY2xpZW50IHRvIHRoZSBzZXJ2ZXJcclxuICAgICAqIGZvciB0aGluZ3MgbGlrZSB2YWxpZGF0aW5nIGF1dGhvcml6YXRpb24gYW5kIG90aGVyIHVzZXMuXHJcbiAgICAgKi9cclxuICAgIEBJbnB1dCgpIGdldCBtZXRhZGF0YSgpIHsgcmV0dXJuIHRoaXMuX21ldGFkYXRhOyB9XHJcbiAgICBzZXQgbWV0YWRhdGEodmFsdWUpIHtcclxuICAgICAgICBpZiAoSlNPTi5zdHJpbmdpZnkodGhpcy5fbWV0YWRhdGEpICE9PSBKU09OLnN0cmluZ2lmeSh2YWx1ZSkpIHtcclxuICAgICAgICAgICAgdGhpcy5fbWV0YWRhdGEgPSB2YWx1ZTtcclxuICAgICAgICAgICAgdGhpcy5yZWxvYWRTb3VyY2UoKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0IGZpbHRlck1vZGVzKCkgeyBcclxuICAgICAgICByZXR1cm4gRmlsdGVyTW9kZS5vcHRpb25zO1xyXG4gICAgfVxyXG5cclxuICAgIGdldCBmaWx0ZXJNb2RlTGFiZWxzKCkge1xyXG4gICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgIFtGaWx0ZXJNb2RlLkFMTF06ICdBbGwnLFxyXG4gICAgICAgICAgICBbRmlsdGVyTW9kZS5NSU5FXTogJ01pbmUnLFxyXG4gICAgICAgICAgICBbRmlsdGVyTW9kZS5USFJFQURTXTogJ0ludm9sdmluZyBNZScsXHJcbiAgICAgICAgICAgIFtGaWx0ZXJNb2RlLk1ZX0xJS0VTXTogJ015IExpa2VzJ1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBnZXQgc29ydE9yZGVycygpIHsgXHJcbiAgICAgICAgcmV0dXJuIENvbW1lbnRzT3JkZXIub3B0aW9ucztcclxuICAgIH1cclxuXHJcbiAgICBnZXQgc29ydE9yZGVyTGFiZWxzKCkge1xyXG4gICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgIFtDb21tZW50c09yZGVyLk5FV0VTVF06ICdOZXdlc3QnLFxyXG4gICAgICAgICAgICBbQ29tbWVudHNPcmRlci5PTERFU1RdOiAnT2xkZXN0JyxcclxuICAgICAgICAgICAgW0NvbW1lbnRzT3JkZXIuTElLRVNdOiAnTGlrZXMnXHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHNlbmRNZXNzYWdlOiAobWVzc2FnZTogQ2hhdE1lc3NhZ2UpID0+IHZvaWQ7XHJcbiAgICBzZW5kUmVwbHk6IChtZXNzYWdlOiBDaGF0TWVzc2FnZSkgPT4gdm9pZDtcclxuXHJcbiAgICAvLyBVSSBJbnRlcmFjdGlvbnNcclxuXHJcbiAgICBhc3luYyBzY3JvbGxUb0NvbW1lbnQoY29tbWVudElkOiBDaGF0TWVzc2FnZVsnaWQnXSkge1xyXG4gICAgICAgIGlmICh0eXBlb2Ygd2luZG93ID09PSAndW5kZWZpbmVkJylcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIFxyXG4gICAgICAgIGF3YWl0IHRoaXMuY29tbWVudFZpZXcud2FpdEZvckFsbENvbW1lbnRzVG9Mb2FkKCk7XHJcblxyXG4gICAgICAgIGNvbnN0IGNvbW1lbnQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKGBbZGF0YS1jb21tZW50LWlkPVwiJHtjb21tZW50SWR9XCJdYCk7XHJcbiAgICAgICAgaWYgKGNvbW1lbnQpIHtcclxuICAgICAgICAgICAgY29tbWVudC5zY3JvbGxJbnRvVmlldyh7XHJcbiAgICAgICAgICAgICAgICBpbmxpbmU6ICdjZW50ZXInLFxyXG4gICAgICAgICAgICAgICAgYmxvY2s6ICdjZW50ZXInXHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBsb2FkaW5nU2hhcmVkQ29tbWVudCA9IGZhbHNlO1xyXG4gICAgc2hhcmVkQ29tbWVudE1pc3NpbmcgPSBmYWxzZTtcclxuXHJcbiAgICBhc3luYyBuYXZpZ2F0ZVRvU2hhcmVkQ29tbWVudChpZDogc3RyaW5nKSB7XHJcbiAgICAgICAgdGhpcy5sb2FkaW5nU2hhcmVkQ29tbWVudCA9IHRydWU7XHJcbiAgICAgICAgYXdhaXQgbmV3IFByb21pc2UociA9PiBzZXRUaW1lb3V0KHIsIDEwKSk7XHJcbiAgICAgICAgdGhpcy5zaGFyZWRDb21tZW50TWlzc2luZyA9IGZhbHNlO1xyXG4gICAgICAgIGxldCBzb3VyY2UgPSB0aGlzLnNvdXJjZTtcclxuXHJcbiAgICAgICAgYXdhaXQgc291cmNlLnJlYWR5O1xyXG4gICAgICAgIGF3YWl0IHRoaXMudmlld1JlYWR5O1xyXG4gICAgICAgIGF3YWl0IHRoaXMubG9hZGVkO1xyXG4gICAgICAgIFxyXG4gICAgICAgIGNvbnNvbGUubG9nKGBOYXZpZ2F0aW5nIHRvIHNoYXJlZCBjb21tZW50IHdpdGggSUQgJyR7aWR9Jy4uLmApO1xyXG4gICAgICAgIGxldCBtZXNzYWdlOiBDaGF0TWVzc2FnZTtcclxuICAgICAgICBcclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICBtZXNzYWdlID0gYXdhaXQgdGhpcy5zb3VyY2UuZ2V0KGlkKTtcclxuICAgICAgICB9IGNhdGNoIChlKSB7XHJcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoYEZhaWxlZCB0byBmaW5kIGNvbW1lbnQgZnJvbSBVUkw6ICR7ZS5tZXNzYWdlfWApO1xyXG4gICAgICAgICAgICB0aGlzLnNoYXJlZENvbW1lbnRNaXNzaW5nID0gdHJ1ZTtcclxuICAgICAgICAgICAgdGhpcy5sb2FkaW5nU2hhcmVkQ29tbWVudCA9IGZhbHNlO1xyXG5cclxuICAgICAgICAgICAgaWYgKHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnKSB7XHJcbiAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICBsZXQgbm90aWNlID0gdGhpcy5lbGVtZW50LnF1ZXJ5U2VsZWN0b3IoJy5sb2FkaW5nLWNvbW1lbnQnKTtcclxuICAgICAgICAgICAgICAgICAgICBub3RpY2Uuc2Nyb2xsSW50b1ZpZXcoe1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBibG9jazogJ2NlbnRlcicsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlubGluZTogJ2NlbnRlcidcclxuICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgIH0sIDIwMCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgbWVzc2FnZS50cmFuc2llbnRTdGF0ZSA/Pz0ge307XHJcblxyXG4gICAgICAgIC8vIElmIHRoZXJlIGlzIGEgcGFyZW50IG1lc3NhZ2UsIHdlIHNob3VsZCBpbnN0ZWFkIGZvY3VzIHRoYXQgYW5kIGxldCB0aGUgXHJcbiAgICAgICAgLy8gc2Nyb2xsVG9Db21tZW50IGFuZCBoaWdobGlnaHQgZG8gdGhlIHdvcmsuXHJcblxyXG4gICAgICAgIGlmIChtZXNzYWdlLnBhcmVudE1lc3NhZ2VJZCkge1xyXG5cclxuICAgICAgICAgICAgbGV0IHBhcmVudE1lc3NhZ2UgPSBhd2FpdCB0aGlzLnNvdXJjZS5nZXQobWVzc2FnZS5wYXJlbnRNZXNzYWdlSWQpO1xyXG4gICAgICAgICAgICBwYXJlbnRNZXNzYWdlLnRyYW5zaWVudFN0YXRlID8/PSB7fTtcclxuICAgICAgICAgICAgXHJcbiAgICAgICAgICAgIC8vIE1ha2Ugc3VyZSB0aGF0IHRoaXMgbWVzc2FnZSBpcyBsb2FkZWQgYW5kIHZpc2libGUgdG8gdGhlIHVzZXJcclxuICAgICAgICAgICAgYXdhaXQgdGhpcy5jb21tZW50Vmlldy5sb2FkTWVzc2FnZUluQ29udGV4dChwYXJlbnRNZXNzYWdlKTtcclxuICAgICAgICAgICAgXHJcbiAgICAgICAgICAgIGxldCB0aHJlYWQgPSBhd2FpdCB0aGlzLnNlbGVjdE1lc3NhZ2UocGFyZW50TWVzc2FnZSk7IFxyXG5cclxuICAgICAgICAgICAgLy8gTmVlZCB0byByZS1yZXRyaWV2ZSB0aGUgbWVzc2FnZSB3aXRoaW4gdGhlIG5ldyBjaGF0IHNvdXJjZSB0byBhZmZlY3QgaXRzXHJcbiAgICAgICAgICAgIC8vIHRyYW5zaWVudCBzdGF0ZS5cclxuICAgICAgICAgICAgYXdhaXQgdGhyZWFkLnJlYWR5O1xyXG4gICAgICAgICAgICBcclxuICAgICAgICAgICAgLy8gTWFrZSBzdXJlIHRoYXQgdGhpcyBtZXNzYWdlIGlzIGxvYWRlZCBhbmQgdmlzaWJsZSB0byB0aGUgdXNlclxyXG4gICAgICAgICAgICBhd2FpdCB0aGlzLndhaXRGb3JUaHJlYWRWaWV3KCk7XHJcbiAgICAgICAgICAgIGF3YWl0IHRoaXMudGhyZWFkVmlldy5sb2FkTWVzc2FnZUluQ29udGV4dChtZXNzYWdlKTtcclxuXHJcbiAgICAgICAgICAgIG1lc3NhZ2UgPSBhd2FpdCB0aHJlYWQuZ2V0KG1lc3NhZ2UuaWQpO1xyXG4gICAgICAgICAgICBtZXNzYWdlLnRyYW5zaWVudFN0YXRlID8/PSB7fTtcclxuICAgICAgICAgICAgbWVzc2FnZS50cmFuc2llbnRTdGF0ZS5oaWdobGlnaHRlZCA9IHRydWU7XHJcbiAgICAgICAgICAgIGNvbnNvbGUuZGlyKG1lc3NhZ2UpO1xyXG4gICAgICAgICAgICBhd2FpdCBuZXcgUHJvbWlzZTx2b2lkPihyZXNvbHZlID0+IHNldFRpbWVvdXQoKCkgPT4gcmVzb2x2ZSgpLCA1MDApKTtcclxuXHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgLy8gTWFrZSBzdXJlIHRoYXQgdGhpcyBtZXNzYWdlIGlzIGxvYWRlZCBhbmQgdmlzaWJsZSB0byB0aGUgdXNlclxyXG4gICAgICAgICAgICBhd2FpdCB0aGlzLmNvbW1lbnRWaWV3LmxvYWRNZXNzYWdlSW5Db250ZXh0KG1lc3NhZ2UpO1xyXG5cclxuICAgICAgICAgICAgbWVzc2FnZS50cmFuc2llbnRTdGF0ZSA/Pz0ge307XHJcbiAgICAgICAgICAgIG1lc3NhZ2UudHJhbnNpZW50U3RhdGUuaGlnaGxpZ2h0ZWQgPSB0cnVlO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy5sb2FkaW5nU2hhcmVkQ29tbWVudCA9IGZhbHNlO1xyXG4gICAgICAgIGF3YWl0IHRoaXMuc2Nyb2xsVG9Db21tZW50KGlkKTtcclxuICAgIH1cclxuXHJcbiAgICBoYW5kbGVQZXJtaXNzaW9uRGVuaWVkKGVycm9yTWVzc2FnZTogc3RyaW5nKSB7XHJcbiAgICAgICAgLy8gVGhpcyBpcyB3aGF0IG90aGVyIGNvbXBvbmVudHMgY2FsbCB3aGVuIGhhbmRsaW5nIHBlcm1pc3Npb24gZXJyb3JzXHJcbiAgICAgICAgXHJcbiAgICAgICAgaWYgKGVycm9yTWVzc2FnZS5zdGFydHNXaXRoKGBhcHAtaGFuZGxlfGApKSB7XHJcbiAgICAgICAgICAgIC8vIElmIHRoaXMgaXMgYW4gZXJyb3IgZHVyaW5nIGF1dGhvcml6ZUFjdGlvbiBvbiB0aGUgYmFja2VuZCwgcGFzcyBjb250cm9sIHRvIHRoZSB1c2VyLXByb3ZpZGVkIFxyXG4gICAgICAgICAgICAvLyBwZXJtaXNzaW9uLWRlbmllZCBoYW5kbGVyLlxyXG5cclxuICAgICAgICAgICAgdGhpcy5zZW5kUGVybWlzc2lvbkRlbmllZChlcnJvck1lc3NhZ2UucmVwbGFjZSgvXmFwcC1oYW5kbGVcXHwvLCAnJykpO1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBhbGVydChlcnJvck1lc3NhZ2UpO1xyXG4gICAgfVxyXG5cclxuICAgIHNlbmRQZXJtaXNzaW9uRGVuaWVkKG1lc3NhZ2U6IHN0cmluZykge1xyXG4gICAgICAgIHRoaXMuX3Blcm1pc3Npb25EZW5pZWRFcnJvci5uZXh0KG1lc3NhZ2UpO1xyXG4gICAgfVxyXG5cclxuICAgIHNjcm9sbFRvTWVzc2FnZShtZXNzYWdlOiBDaGF0TWVzc2FnZSkge1xyXG4gICAgICAgIGxldCBlbCA9IHRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LnF1ZXJ5U2VsZWN0b3IoYFtkYXRhLWNvbW1lbnQtaWQ9XCIke21lc3NhZ2UuaWR9XCJdYCk7XHJcbiAgICAgICAgaWYgKCFlbClcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIGVsLnNjcm9sbEludG9WaWV3KHtibG9jazogJ2NlbnRlcicsIGlubGluZTogJ3N0YXJ0J30pO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgYWRkUGFydGljaXBhbnQobWVzc2FnZTogQ2hhdE1lc3NhZ2UpIHtcclxuICAgICAgICBpZiAoIW1lc3NhZ2UgfHwgIW1lc3NhZ2UudXNlciB8fCAhbWVzc2FnZS51c2VyLmlkKVxyXG4gICAgICAgICAgICByZXR1cm47XHJcblxyXG4gICAgICAgIGxldCBleGlzdGluZyA9IHRoaXMucGFydGljaXBhbnRzLmZpbmQoeCA9PiB4LmlkID09PSBtZXNzYWdlLnVzZXIuaWQpO1xyXG4gICAgICAgIGlmIChleGlzdGluZylcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIHRoaXMucGFydGljaXBhbnRzLnB1c2gobWVzc2FnZS51c2VyKTtcclxuICAgIH1cclxuXHJcbiAgICAvLyBBY3Rpb25zXHJcblxyXG4gICAgYXN5bmMgbGlrZU1lc3NhZ2Uoc291cmNlOiBDaGF0U291cmNlQmFzZSwgbWVzc2FnZTogQ2hhdE1lc3NhZ2UpIHtcclxuICAgICAgICBpZiAoIXRoaXMudXNlcikge1xyXG4gICAgICAgICAgICBhd2FpdCB0aGlzLnNob3dTaWduSW4oKTtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy5fdXB2b3RlZC5uZXh0KG1lc3NhZ2UpO1xyXG4gICAgICAgIG1lc3NhZ2UudHJhbnNpZW50U3RhdGUubGlraW5nID0gdHJ1ZTtcclxuICAgICAgICBcclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICBhd2FpdCBzb3VyY2UubGlrZU1lc3NhZ2UobWVzc2FnZS5pZCk7XHJcbiAgICAgICAgfSBjYXRjaCAoZSkge1xyXG4gICAgICAgICAgICB0aGlzLmhhbmRsZUJhY2tlbmRFeGNlcHRpb25Bc1NuYWNrKGUsICdDb3VsZCBub3QgbGlrZSB0aGlzIG1lc3NhZ2U6ICcpO1xyXG4gICAgICAgIH0gZmluYWxseSB7XHJcbiAgICAgICAgICAgIGF3YWl0IG5ldyBQcm9taXNlPHZvaWQ+KHJlc29sdmUgPT4gc2V0VGltZW91dCgoKSA9PiByZXNvbHZlKCksIDI1MCkpO1xyXG4gICAgICAgICAgICBtZXNzYWdlLnRyYW5zaWVudFN0YXRlLmxpa2luZyA9IGZhbHNlO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBhc3luYyB1bmxpa2VNZXNzYWdlKHNvdXJjZTogQ2hhdFNvdXJjZUJhc2UsIG1lc3NhZ2U6IENoYXRNZXNzYWdlKSB7XHJcbiAgICAgICAgaWYgKCF0aGlzLnVzZXIpIHtcclxuICAgICAgICAgICAgYXdhaXQgdGhpcy5zaG93U2lnbkluKCk7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRoaXMuX3Vwdm90ZWQubmV4dChtZXNzYWdlKTtcclxuICAgICAgICBtZXNzYWdlLnRyYW5zaWVudFN0YXRlLmxpa2luZyA9IHRydWU7XHJcblxyXG4gICAgICAgIGlmIChtZXNzYWdlLnVzZXJTdGF0ZT8ubGlrZWQpXHJcbiAgICAgICAgICAgIG1lc3NhZ2UubGlrZXMgPSAobWVzc2FnZS5saWtlcyB8fCAwKSAtIDE7XHJcblxyXG4gICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgIGF3YWl0IHNvdXJjZS51bmxpa2VNZXNzYWdlKG1lc3NhZ2UuaWQpO1xyXG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcclxuICAgICAgICAgICAgdGhpcy5oYW5kbGVCYWNrZW5kRXhjZXB0aW9uQXNBbGVydChlLCAnRmFpbGVkIHRvIHVubGlrZSB0aGlzIG1lc3NhZ2U6ICcpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgYXdhaXQgbmV3IFByb21pc2U8dm9pZD4ocmVzb2x2ZSA9PiBzZXRUaW1lb3V0KCgpID0+IHJlc29sdmUoKSwgMjUwKSk7XHJcbiAgICAgICAgbWVzc2FnZS50cmFuc2llbnRTdGF0ZS5saWtpbmcgPSBmYWxzZTtcclxuICAgIH1cclxuXHJcbiAgICBhc3luYyByZXBvcnRNZXNzYWdlKG1lc3NhZ2U6IENoYXRNZXNzYWdlKSB7XHJcbiAgICAgICAgdGhpcy5fcmVwb3J0ZWQubmV4dChtZXNzYWdlKTtcclxuICAgIH1cclxuXHJcbiAgICBhc3luYyB1bnNlbGVjdE1lc3NhZ2UoKSB7XHJcbiAgICAgICAgbGV0IG1lc3NhZ2UgPSB0aGlzLnNlbGVjdGVkTWVzc2FnZTtcclxuXHJcbiAgICAgICAgdGhpcy5fc2VsZWN0ZWQubmV4dChudWxsKTtcclxuICAgICAgICB0aGlzLnNlbGVjdGVkTWVzc2FnZSA9IG51bGw7XHJcbiAgICAgICAgaWYgKHRoaXMuc2VsZWN0ZWRNZXNzYWdlVGhyZWFkKSB7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLnNlbGVjdGVkTWVzc2FnZVRocmVhZC5jbG9zZSlcclxuICAgICAgICAgICAgICAgIHRoaXMuc2VsZWN0ZWRNZXNzYWdlVGhyZWFkLmNsb3NlKCk7XHJcbiAgICAgICAgICAgIHRoaXMuc2VsZWN0ZWRNZXNzYWdlVGhyZWFkID0gbnVsbDtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChtZXNzYWdlKVxyXG4gICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHRoaXMuc2Nyb2xsVG9NZXNzYWdlKG1lc3NhZ2UpKTtcclxuICAgIH1cclxuXHJcbiAgICBhc3luYyB0b2dnbGVTZWxlY3RlZE1lc3NhZ2UobWVzc2FnZTogQ2hhdE1lc3NhZ2UpIHtcclxuICAgICAgICBpZiAodGhpcy5zZWxlY3RlZE1lc3NhZ2UgPT09IG1lc3NhZ2UpIHtcclxuICAgICAgICAgICAgYXdhaXQgdGhpcy51bnNlbGVjdE1lc3NhZ2UoKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBhd2FpdCB0aGlzLnNlbGVjdE1lc3NhZ2UobWVzc2FnZSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGFzeW5jIHNlbGVjdE1lc3NhZ2UobWVzc2FnZTogQ2hhdE1lc3NhZ2UpIHtcclxuICAgICAgICBpZiAodGhpcy5zZWxlY3RlZE1lc3NhZ2UgPT09IG1lc3NhZ2UpIHtcclxuICAgICAgICAgICAgY29uc29sZS5sb2coYFtCYW50YV0gVGhyZWFkICR7dGhpcy50b3BpY0lEfS8ke21lc3NhZ2UuaWR9IGlzIGFscmVhZHkgb3Blbi5gKTtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuc2VsZWN0ZWRNZXNzYWdlVGhyZWFkO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKHRoaXMuc2VsZWN0ZWRNZXNzYWdlVGhyZWFkKSB7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLnNlbGVjdGVkTWVzc2FnZVRocmVhZC5jbG9zZSlcclxuICAgICAgICAgICAgICAgIHRoaXMuc2VsZWN0ZWRNZXNzYWdlVGhyZWFkLmNsb3NlKCk7XHJcbiAgICAgICAgICAgIHRoaXMuc2VsZWN0ZWRNZXNzYWdlVGhyZWFkID0gbnVsbDtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRoaXMuX3NlbGVjdGVkLm5leHQobWVzc2FnZSk7XHJcblxyXG4gICAgICAgIGNvbnNvbGUubG9nKGBbQmFudGFdIE9wZW5pbmcgdGhyZWFkIGZvciAke3RoaXMudG9waWNJRH0vJHttZXNzYWdlLmlkfS4uLmApO1xyXG4gICAgICAgIGxldCBzZWxlY3RlZE1lc3NhZ2VUaHJlYWQgPSBhd2FpdCB0aGlzLmJhY2tlbmQuZ2V0U291cmNlRm9yVGhyZWFkKHRoaXMudG9waWNJRCwgbWVzc2FnZS5pZCk7XHJcblxyXG4gICAgICAgIGlmICghc2VsZWN0ZWRNZXNzYWdlVGhyZWFkKSB7XHJcbiAgICAgICAgICAgIGNvbnNvbGUud2FybihgRmFpbGVkIHRvIGxvY2F0ZSB0aHJlYWQgZm9yIG1lc3NhZ2UgJHt0aGlzLnRvcGljSUR9LyR7bWVzc2FnZS5pZH0hYCk7XHJcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgY29uc29sZS5sb2coYFtCYW50YV0gVGhyZWFkIG9wZW5lZCBmb3IgJHt0aGlzLnRvcGljSUR9LyR7bWVzc2FnZS5pZH0uYCk7XHJcblxyXG4gICAgICAgIHNldFRpbWVvdXQoKCkgPT4gdGhpcy5zZWxlY3RlZE1lc3NhZ2VWaXNpYmxlID0gdHJ1ZSk7XHJcbiAgICAgICAgc2V0VGltZW91dChhc3luYyAoKSA9PiB7XHJcbiAgICAgICAgICAgIHRoaXMuc2VsZWN0ZWRNZXNzYWdlID0gbWVzc2FnZTtcclxuICAgICAgICAgICAgdGhpcy5zZWxlY3RlZE1lc3NhZ2VUaHJlYWQgPSBzZWxlY3RlZE1lc3NhZ2VUaHJlYWQ7XHJcbiAgICAgICAgfSwgMjUwKTtcclxuXHJcbiAgICAgICAgcmV0dXJuIHNlbGVjdGVkTWVzc2FnZVRocmVhZDtcclxuICAgIH1cclxuXHJcbiAgICBhc3luYyBzaG93U2lnbkluKCkge1xyXG4gICAgICAgIHRoaXMuX3NpZ25JblNlbGVjdGVkLm5leHQoKTtcclxuICAgIH1cclxuXHJcbiAgICBhc3luYyBzaG93RWRpdEF2YXRhcigpIHtcclxuICAgICAgICB0aGlzLl9lZGl0QXZhdGFyU2VsZWN0ZWQubmV4dCgpO1xyXG4gICAgfVxyXG5cclxuICAgIGFzeW5jIHNlbGVjdE1lc3NhZ2VVc2VyKG1lc3NhZ2U6IENoYXRNZXNzYWdlKSB7XHJcbiAgICAgICAgdGhpcy5fdXNlclNlbGVjdGVkLm5leHQobWVzc2FnZSk7XHJcbiAgICB9XHJcblxyXG4gICAgYXN5bmMgc2VsZWN0VXNlcm5hbWUodXNlcjogVXNlcikge1xyXG4gICAgICAgIHRoaXMuX3VzZXJuYW1lU2VsZWN0ZWQubmV4dCh1c2VyKTtcclxuICAgIH1cclxuXHJcbiAgICBhc3luYyBzZWxlY3RBdmF0YXIodXNlcjogVXNlcikge1xyXG4gICAgICAgIHRoaXMuX2F2YXRhclNlbGVjdGVkLm5leHQodXNlcik7XHJcbiAgICB9XHJcblxyXG4gICAgYXN5bmMgc2hhcmVNZXNzYWdlKG1lc3NhZ2U6IENoYXRNZXNzYWdlKSB7XHJcbiAgICAgICAgdGhpcy5fc2hhcmVkLm5leHQobWVzc2FnZSk7XHJcbiAgICB9XHJcblxyXG4gICAgYXN5bmMgZGVsZXRlTWVzc2FnZShtZXNzYWdlOiBDaGF0TWVzc2FnZSkge1xyXG4gICAgICAgIGlmICghdGhpcy51c2VyKSB7XHJcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuc2hvd1NpZ25JbigpO1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoIWNvbmZpcm0oXCJBcmUgeW91IHN1cmUgeW91IHdhbnQgdG8gZGVsZXRlIHRoaXMgY29tbWVudD8gWW91IGNhbm5vdCB1bmRvIHRoaXMgYWN0aW9uLlwiKSlcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG5cclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICBhd2FpdCB0aGlzLnNvdXJjZS5kZWxldGVNZXNzYWdlKG1lc3NhZ2UuaWQpO1xyXG5cclxuICAgICAgICAgICAgaWYgKHRoaXMuc2VsZWN0ZWRNZXNzYWdlPy5pZCA9PT0gbWVzc2FnZS5pZClcclxuICAgICAgICAgICAgICAgIHRoaXMudW5zZWxlY3RNZXNzYWdlKCk7XHJcblxyXG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcclxuICAgICAgICAgICAgdGhpcy5oYW5kbGVCYWNrZW5kRXhjZXB0aW9uQXNBbGVydChlLCBgQ291bGQgbm90IGRlbGV0ZSBtZXNzYWdlOiBgKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgYXN5bmMgZWRpdE1lc3NhZ2Uoc291cmNlOiBDaGF0U291cmNlQmFzZSwgbWVzc2FnZTogQ2hhdE1lc3NhZ2UsIG5ld1RleHQ6IHN0cmluZykge1xyXG4gICAgICAgIGlmICghdGhpcy51c2VyKSB7XHJcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuc2hvd1NpZ25JbigpO1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICBhd2FpdCBzb3VyY2UuZWRpdE1lc3NhZ2UobWVzc2FnZS5pZCwgbmV3VGV4dCk7XHJcbiAgICAgICAgfSBjYXRjaCAoZSkge1xyXG4gICAgICAgICAgICB0aGlzLmhhbmRsZUJhY2tlbmRFeGNlcHRpb25Bc0FsZXJ0KGUsICdDb3VsZCBub3QgZWRpdCB0aGlzIG1lc3NhZ2U6ICcpO1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBtZXNzYWdlLm1lc3NhZ2UgPSBuZXdUZXh0O1xyXG4gICAgICAgIG1lc3NhZ2UudHJhbnNpZW50U3RhdGUuZWRpdGluZyA9IGZhbHNlO1xyXG4gICAgfVxyXG5cclxuICAgIGFzeW5jIHN0YXJ0RWRpdGluZyhtZXNzYWdlOiBDaGF0TWVzc2FnZSkge1xyXG4gICAgICAgIHRoaXMuc2VsZWN0ZWRNZXNzYWdlLnRyYW5zaWVudFN0YXRlLmVkaXRpbmcgPSBmYWxzZTtcclxuICAgICAgICBtZXNzYWdlLnRyYW5zaWVudFN0YXRlLmVkaXRpbmcgPSB0cnVlO1xyXG4gICAgfVxyXG5cclxuICAgIGFzeW5jIHNhdmVFZGl0KG1lc3NhZ2U6IENoYXRNZXNzYWdlLCB0ZXh0OiBzdHJpbmcpIHtcclxuICAgICAgICBpZiAoIXRoaXMudXNlcikge1xyXG4gICAgICAgICAgICBhd2FpdCB0aGlzLnNob3dTaWduSW4oKTtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuICAgICAgICBcclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICBhd2FpdCB0aGlzLnNvdXJjZS5lZGl0TWVzc2FnZShtZXNzYWdlLmlkLCB0ZXh0KTtcclxuICAgICAgICAgICAgbWVzc2FnZS50cmFuc2llbnRTdGF0ZS5lZGl0aW5nID0gZmFsc2U7XHJcbiAgICAgICAgfSBjYXRjaCAoZSkge1xyXG4gICAgICAgICAgICB0aGlzLmhhbmRsZUJhY2tlbmRFeGNlcHRpb25Bc0FsZXJ0KGUsIGBDb3VsZCBub3QgZWRpdCBtZXNzYWdlOiBgKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbn1cclxuIiwiPG5nLWNvbnRhaW5lciAqbmdJZj1cImxvYWRpbmdcIj5cclxuICAgIDxkaXYgY2xhc3M9XCJsb2FkaW5nLXNjcmVlblwiIFtjbGFzcy52aXNpYmxlXT1cInNob3dMb2FkaW5nU2NyZWVuXCI+XHJcbiAgICAgICAgPGgxPnt7bG9hZGluZ1RpdGxlfX08L2gxPlxyXG4gICAgICAgIDxkaXY+XHJcbiAgICAgICAgICAgIDxtYXQtc3Bpbm5lciBbZGlhbWV0ZXJdPVwiMzAwXCIgW3N0cm9rZVdpZHRoXT1cIjJcIj48L21hdC1zcGlubmVyPlxyXG4gICAgICAgIDwvZGl2PlxyXG5cclxuICAgICAgICA8cCBjbGFzcz1cImxvYWRpbmctbWVzc2FnZVwiIFtjbGFzcy52aXNpYmxlXT1cImxvYWRpbmdNZXNzYWdlVmlzaWJsZVwiPnt7bG9hZGluZ01lc3NhZ2V9fTwvcD5cclxuICAgIDwvZGl2PlxyXG48L25nLWNvbnRhaW5lcj5cclxuPG5nLWNvbnRhaW5lciAqbmdJZj1cIiFsb2FkaW5nXCI+XHJcbiAgICA8ZGl2IGNsYXNzPVwiZm9jdXNlZFwiIFtjbGFzcy52aXNpYmxlXT1cInNlbGVjdGVkTWVzc2FnZVZpc2libGVcIiAqbmdJZj1cInNlbGVjdGVkTWVzc2FnZSAmJiAhdXNlSW5saW5lUmVwbGllc1wiPlxyXG5cclxuICAgICAgICA8ZGl2PlxyXG4gICAgICAgICAgICA8YSBtYXQtYnV0dG9uIGhyZWY9XCJqYXZhc2NyaXB0OjtcIiAoY2xpY2spPVwidW5zZWxlY3RNZXNzYWdlKClcIj5cclxuICAgICAgICAgICAgICAgIDxtYXQtaWNvbj5hcnJvd19iYWNrPC9tYXQtaWNvbj5cclxuICAgICAgICAgICAgICAgIExhdGVzdCBDb21tZW50c1xyXG4gICAgICAgICAgICA8L2E+XHJcbiAgICAgICAgPC9kaXY+XHJcblxyXG4gICAgICAgIDxiYW50YS1jb21tZW50XHJcbiAgICAgICAgICAgIFttZXNzYWdlXT1cInNlbGVjdGVkTWVzc2FnZVwiXHJcbiAgICAgICAgICAgIFtsaWtpbmddPVwic2VsZWN0ZWRNZXNzYWdlLnRyYW5zaWVudFN0YXRlLmxpa2luZ1wiXHJcbiAgICAgICAgICAgIFttaW5lXT1cInVzZXI/LmlkID09PSBzZWxlY3RlZE1lc3NhZ2UudXNlcj8uaWRcIlxyXG4gICAgICAgICAgICBbcGVybWlzc2lvbnNdPVwic291cmNlPy5wZXJtaXNzaW9uc1wiXHJcbiAgICAgICAgICAgIFtzaG93UmVwbHlBY3Rpb25dPVwiZmFsc2VcIlxyXG4gICAgICAgICAgICBbZWRpdGluZ109XCJzZWxlY3RlZE1lc3NhZ2UudHJhbnNpZW50U3RhdGUuZWRpdGluZ1wiXHJcbiAgICAgICAgICAgIFttYXhMZW5ndGhdPVwibWF4Q29tbWVudExlbmd0aFwiXHJcbiAgICAgICAgICAgIFtnZW5lcmljQXZhdGFyVXJsXT1cImdlbmVyaWNBdmF0YXJVcmxcIlxyXG4gICAgICAgICAgICBbcmVhZG9ubHldPVwic291cmNlPy5yZWFkb25seVwiXHJcbiAgICAgICAgICAgIChlZGl0U3RhcnRlZCk9XCJzdGFydEVkaXRpbmcoc2VsZWN0ZWRNZXNzYWdlKVwiXHJcbiAgICAgICAgICAgIChlZGl0RW5kZWQpPVwic2VsZWN0ZWRNZXNzYWdlLnRyYW5zaWVudFN0YXRlLmVkaXRpbmcgPSBmYWxzZVwiXHJcbiAgICAgICAgICAgIChlZGl0ZWQpPVwic2F2ZUVkaXQoc2VsZWN0ZWRNZXNzYWdlLCAkZXZlbnQpXCJcclxuICAgICAgICAgICAgKHVzZXJTZWxlY3RlZCk9XCJzZWxlY3RNZXNzYWdlVXNlcihzZWxlY3RlZE1lc3NhZ2UpXCJcclxuICAgICAgICAgICAgKGF2YXRhclNlbGVjdGVkKT1cInNlbGVjdEF2YXRhcigkZXZlbnQpXCJcclxuICAgICAgICAgICAgKHVzZXJuYW1lU2VsZWN0ZWQpPVwic2VsZWN0VXNlcm5hbWUoJGV2ZW50KVwiXHJcbiAgICAgICAgICAgIChsaWtlZCk9XCJsaWtlTWVzc2FnZShzb3VyY2UsIHNlbGVjdGVkTWVzc2FnZSlcIlxyXG4gICAgICAgICAgICAodW5saWtlZCk9XCJ1bmxpa2VNZXNzYWdlKHNvdXJjZSwgc2VsZWN0ZWRNZXNzYWdlKVwiXHJcbiAgICAgICAgICAgIChyZXBvcnRlZCk9XCJyZXBvcnRNZXNzYWdlKHNlbGVjdGVkTWVzc2FnZSlcIlxyXG4gICAgICAgICAgICAoc2VsZWN0ZWQpPVwidG9nZ2xlU2VsZWN0ZWRNZXNzYWdlKHNlbGVjdGVkTWVzc2FnZSlcIlxyXG4gICAgICAgICAgICAoc2hhcmVkKT1cInNoYXJlTWVzc2FnZSgkZXZlbnQpXCJcclxuICAgICAgICAgICAgKGRlbGV0ZWQpPVwiZGVsZXRlTWVzc2FnZShzZWxlY3RlZE1lc3NhZ2UpXCJcclxuICAgICAgICAgICAgPjwvYmFudGEtY29tbWVudD5cclxuXHJcbiAgICAgICAgPGRpdiBjbGFzcz1cInJlcGxpZXNcIj5cclxuXHJcbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCIhc2VsZWN0ZWRNZXNzYWdlVGhyZWFkXCI+XHJcbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibG9hZGluZ1wiPlxyXG4gICAgICAgICAgICAgICAgICAgIDxtYXQtc3Bpbm5lcj48L21hdC1zcGlubmVyPlxyXG4gICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG5cclxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cInNlbGVjdGVkTWVzc2FnZVRocmVhZFwiPlxyXG4gICAgICAgICAgICAgICAgPGJhbnRhLWNvbW1lbnQtdmlld1xyXG4gICAgICAgICAgICAgICAgICAgIGNsYXNzPVwicmVwbGllc1wiXHJcbiAgICAgICAgICAgICAgICAgICAgI3RocmVhZFZpZXdcclxuICAgICAgICAgICAgICAgICAgICBbc291cmNlXT1cInNlbGVjdGVkTWVzc2FnZVRocmVhZFwiXHJcbiAgICAgICAgICAgICAgICAgICAgW2FsbG93UmVwbGllc109XCJmYWxzZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgW2ZpeGVkSGVpZ2h0XT1cImZhbHNlXCJcclxuICAgICAgICAgICAgICAgICAgICBbc2hvd0VtcHR5U3RhdGVdPVwiZmFsc2VcIlxyXG4gICAgICAgICAgICAgICAgICAgIFtuZXdlc3RMYXN0XT1cInRydWVcIlxyXG4gICAgICAgICAgICAgICAgICAgIFtnZW5lcmljQXZhdGFyVXJsXT1cImdlbmVyaWNBdmF0YXJVcmxcIlxyXG4gICAgICAgICAgICAgICAgICAgIChsaWtlZCk9XCJsaWtlTWVzc2FnZShzZWxlY3RlZE1lc3NhZ2VUaHJlYWQsICRldmVudClcIlxyXG4gICAgICAgICAgICAgICAgICAgICh1bmxpa2VkKT1cInVubGlrZU1lc3NhZ2Uoc2VsZWN0ZWRNZXNzYWdlVGhyZWFkLCAkZXZlbnQpXCJcclxuICAgICAgICAgICAgICAgICAgICAobWVzc2FnZUVkaXRlZCk9XCJlZGl0TWVzc2FnZShzZWxlY3RlZE1lc3NhZ2VUaHJlYWQsICRldmVudC5tZXNzYWdlLCAkZXZlbnQubmV3TWVzc2FnZSlcIlxyXG4gICAgICAgICAgICAgICAgICAgIChyZXBvcnRlZCk9XCJyZXBvcnRNZXNzYWdlKCRldmVudClcIlxyXG4gICAgICAgICAgICAgICAgICAgICh1c2VybmFtZVNlbGVjdGVkKT1cInNlbGVjdFVzZXJuYW1lKCRldmVudClcIlxyXG4gICAgICAgICAgICAgICAgICAgIChhdmF0YXJTZWxlY3RlZCk9XCJzZWxlY3RBdmF0YXIoJGV2ZW50KVwiXHJcbiAgICAgICAgICAgICAgICAgICAgKHNoYXJlZCk9XCJzaGFyZU1lc3NhZ2UoJGV2ZW50KVwiXHJcbiAgICAgICAgICAgICAgICAgICAgKGRlbGV0ZWQpPVwiZGVsZXRlTWVzc2FnZSgkZXZlbnQpXCJcclxuICAgICAgICAgICAgICAgICAgICBbY3VzdG9tTWVudUl0ZW1zXT1cImN1c3RvbU1lbnVJdGVtc1wiXHJcbiAgICAgICAgICAgICAgICAgICAgPjwvYmFudGEtY29tbWVudC12aWV3PlxyXG5cclxuICAgICAgICAgICAgICAgIDxiYW50YS1jb21tZW50LWZpZWxkXHJcbiAgICAgICAgICAgICAgICAgICAgW3VybF09XCJ1cmxcIlxyXG4gICAgICAgICAgICAgICAgICAgIFtzZW5kTGFiZWxdPVwicmVwbHlMYWJlbFwiXHJcbiAgICAgICAgICAgICAgICAgICAgW3NlbmRpbmdMYWJlbF09XCJzZW5kaW5nTGFiZWxcIlxyXG4gICAgICAgICAgICAgICAgICAgIFtzaWduaW5nSW5MYWJlbF09XCJzaWduaW5nSW5MYWJlbFwiXHJcbiAgICAgICAgICAgICAgICAgICAgW2hhc2h0YWdzXT1cImhhc2h0YWdzXCJcclxuICAgICAgICAgICAgICAgICAgICBbcGFydGljaXBhbnRzXT1cInBhcnRpY2lwYW50c1wiXHJcbiAgICAgICAgICAgICAgICAgICAgW3JlYWRvbmx5XT1cInNvdXJjZT8ucmVhZG9ubHlcIlxyXG4gICAgICAgICAgICAgICAgICAgIChzaWduSW5TZWxlY3RlZCk9XCJzaG93U2lnbkluKClcIlxyXG4gICAgICAgICAgICAgICAgICAgIChlZGl0QXZhdGFyU2VsZWN0ZWQpPVwic2hvd0VkaXRBdmF0YXIoKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgW3NvdXJjZV09XCJzZWxlY3RlZE1lc3NhZ2VUaHJlYWRcIlxyXG4gICAgICAgICAgICAgICAgICAgIFttYXhMZW5ndGhdPVwibWF4Q29tbWVudExlbmd0aFwiXHJcbiAgICAgICAgICAgICAgICAgICAgW2NhbkNvbW1lbnRdPVwic291cmNlPy5wZXJtaXNzaW9ucz8uY2FuUG9zdFwiXHJcbiAgICAgICAgICAgICAgICAgICAgW3NpZ25JblN0YXRlXT1cInNvdXJjZT8uc2lnbkluU3RhdGVcIlxyXG4gICAgICAgICAgICAgICAgICAgIFtzaWduSW5MYWJlbF09XCJzaWduSW5MYWJlbFwiXHJcbiAgICAgICAgICAgICAgICAgICAgW3Blcm1pc3Npb25EZW5pZWRMYWJlbF09XCJzb3VyY2U/LnBlcm1pc3Npb25zPy5jYW5Qb3N0RXJyb3JNZXNzYWdlIHx8IHBlcm1pc3Npb25EZW5pZWRMYWJlbFwiXHJcbiAgICAgICAgICAgICAgICAgICAgKHBlcm1pc3Npb25EZW5pZWRFcnJvcik9XCJoYW5kbGVQZXJtaXNzaW9uRGVuaWVkKCRldmVudClcIlxyXG4gICAgICAgICAgICAgICAgICAgIFtzaG91bGRJbnRlcmNlcHRNZXNzYWdlU2VuZF09XCJzaG91bGRJbnRlcmNlcHRNZXNzYWdlU2VuZFwiXHJcbiAgICAgICAgICAgICAgICAgICAgW3VzZXJdPVwidXNlclwiXHJcbiAgICAgICAgICAgICAgICAgICAgW2xhYmVsXT1cInBvc3RSZXBseUxhYmVsXCJcclxuICAgICAgICAgICAgICAgICAgICBbc3VibWl0XT1cInNlbmRSZXBseVwiXHJcbiAgICAgICAgICAgICAgICAgICAgW2FsbG93QXR0YWNobWVudHNdPVwiYWxsb3dBdHRhY2htZW50c1wiXHJcbiAgICAgICAgICAgICAgICAgICAgW2dlbmVyaWNBdmF0YXJVcmxdPVwiZ2VuZXJpY0F2YXRhclVybFwiXHJcbiAgICAgICAgICAgICAgICAgICAgPlxyXG4gICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJzZW5kUmVwbHlPcHRpb25zVGVtcGxhdGVcIj48L25nLWNvbnRhaW5lcj5cclxuICAgICAgICAgICAgICAgIDwvYmFudGEtY29tbWVudC1maWVsZD5cclxuICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgPC9kaXY+XHJcbiAgICA8L2Rpdj5cclxuXHJcbiAgICA8ZGl2IGNsYXNzPVwibWFpblwiIFtjbGFzcy5oaWRkZW5dPVwic2VsZWN0ZWRNZXNzYWdlICYmICF1c2VJbmxpbmVSZXBsaWVzXCI+XHJcbiAgICAgICAgPGJhbnRhLWNvbW1lbnQtZmllbGRcclxuICAgICAgICAgICAgW3VybF09XCJ1cmxcIlxyXG4gICAgICAgICAgICBbc291cmNlXT1cInNvdXJjZVwiXHJcbiAgICAgICAgICAgIFt1c2VyXT1cInVzZXJcIlxyXG4gICAgICAgICAgICBbc2VuZExhYmVsXT1cInNlbmRMYWJlbFwiXHJcbiAgICAgICAgICAgIFtzZW5kaW5nTGFiZWxdPVwic2VuZGluZ0xhYmVsXCJcclxuICAgICAgICAgICAgW3NpZ25pbmdJbkxhYmVsXT1cInNpZ25pbmdJbkxhYmVsXCJcclxuICAgICAgICAgICAgW3NpZ25JbkxhYmVsXT1cInNpZ25JbkxhYmVsXCJcclxuICAgICAgICAgICAgW3NpZ25JblN0YXRlXT1cInNvdXJjZT8uc2lnbkluU3RhdGVcIlxyXG4gICAgICAgICAgICBbY2FuQ29tbWVudF09XCJzb3VyY2U/LnBlcm1pc3Npb25zPy5jYW5Qb3N0XCJcclxuICAgICAgICAgICAgW2hhc2h0YWdzXT1cImhhc2h0YWdzXCJcclxuICAgICAgICAgICAgW3BhcnRpY2lwYW50c109XCJwYXJ0aWNpcGFudHNcIlxyXG4gICAgICAgICAgICBbbGFiZWxdPVwicG9zdENvbW1lbnRMYWJlbFwiXHJcbiAgICAgICAgICAgIFttYXhMZW5ndGhdPVwibWF4Q29tbWVudExlbmd0aFwiXHJcbiAgICAgICAgICAgIFtwZXJtaXNzaW9uRGVuaWVkTGFiZWxdPVwic291cmNlPy5wZXJtaXNzaW9ucz8uY2FuUG9zdEVycm9yTWVzc2FnZSB8fCBwZXJtaXNzaW9uRGVuaWVkTGFiZWxcIlxyXG4gICAgICAgICAgICBbc2hvdWxkSW50ZXJjZXB0TWVzc2FnZVNlbmRdPVwic2hvdWxkSW50ZXJjZXB0TWVzc2FnZVNlbmRcIlxyXG4gICAgICAgICAgICBbc3VibWl0XT1cInNlbmRNZXNzYWdlXCJcclxuICAgICAgICAgICAgW2FsbG93QXR0YWNobWVudHNdPVwiYWxsb3dBdHRhY2htZW50c1wiXHJcbiAgICAgICAgICAgIFtnZW5lcmljQXZhdGFyVXJsXT1cImdlbmVyaWNBdmF0YXJVcmxcIlxyXG4gICAgICAgICAgICBbcmVhZG9ubHldPVwic291cmNlPy5yZWFkb25seVwiXHJcbiAgICAgICAgICAgIChlZGl0QXZhdGFyU2VsZWN0ZWQpPVwic2hvd0VkaXRBdmF0YXIoKVwiXHJcbiAgICAgICAgICAgIChzaWduSW5TZWxlY3RlZCk9XCJzaG93U2lnbkluKClcIlxyXG4gICAgICAgICAgICAocGVybWlzc2lvbkRlbmllZEVycm9yKT1cImhhbmRsZVBlcm1pc3Npb25EZW5pZWQoJGV2ZW50KVwiXHJcbiAgICAgICAgICAgID5cclxuICAgICAgICBcclxuICAgICAgICA8L2JhbnRhLWNvbW1lbnQtZmllbGQ+XHJcblxyXG4gICAgICAgIDxtYXQtbWVudSAjZmlsdGVyTWVudT1cIm1hdE1lbnVcIj5cclxuICAgICAgICAgICAgPGJ1dHRvbiBtYXQtbWVudS1pdGVtICpuZ0Zvcj1cImxldCBmaWx0ZXIgb2YgZmlsdGVyTW9kZXNcIiAoY2xpY2spPVwiZmlsdGVyTW9kZSA9IGZpbHRlclwiPlxyXG4gICAgICAgICAgICAgICAge3tmaWx0ZXJNb2RlTGFiZWxzW2ZpbHRlcl19fVxyXG4gICAgICAgICAgICA8L2J1dHRvbj5cclxuICAgICAgICA8L21hdC1tZW51PlxyXG4gICAgICAgIDxtYXQtbWVudSAjc29ydE1lbnU9XCJtYXRNZW51XCI+XHJcbiAgICAgICAgICAgIDxidXR0b24gbWF0LW1lbnUtaXRlbSAqbmdGb3I9XCJsZXQgc29ydCBvZiBzb3J0T3JkZXJzXCIgKGNsaWNrKT1cInNvcnRPcmRlciA9IHNvcnRcIj5cclxuICAgICAgICAgICAgICAgIHt7c29ydE9yZGVyTGFiZWxzW3NvcnRdfX1cclxuICAgICAgICAgICAgPC9idXR0b24+XHJcbiAgICAgICAgPC9tYXQtbWVudT5cclxuXHJcbiAgICAgICAgPGRpdiBjbGFzcz1cInNldHRpbmdzXCI+XHJcbiAgICAgICAgICAgIDxidXR0b24gbWF0LWJ1dHRvbiBbbWF0TWVudVRyaWdnZXJGb3JdPVwiZmlsdGVyTWVudVwiPlxyXG4gICAgICAgICAgICAgICAgPG1hdC1pY29uPmZpbHRlcl9saXN0PC9tYXQtaWNvbj5cclxuICAgICAgICAgICAgICAgIHt7ZmlsdGVyTW9kZUxhYmVsc1tmaWx0ZXJNb2RlXX19XHJcbiAgICAgICAgICAgIDwvYnV0dG9uPlxyXG4gICAgICAgICAgICA8YnV0dG9uIG1hdC1idXR0b24gW21hdE1lbnVUcmlnZ2VyRm9yXT1cInNvcnRNZW51XCI+XHJcbiAgICAgICAgICAgICAgICA8bWF0LWljb24+c29ydDwvbWF0LWljb24+XHJcbiAgICAgICAgICAgICAgICB7e3NvcnRPcmRlckxhYmVsc1tzb3J0T3JkZXJdfX1cclxuICAgICAgICAgICAgPC9idXR0b24+XHJcbiAgICAgICAgPC9kaXY+XHJcblxyXG4gICAgICAgIDxkaXYgY2xhc3M9XCJsb2FkaW5nLWNvbW1lbnRcIiAqbmdJZj1cImxvYWRpbmdTaGFyZWRDb21tZW50XCI+XHJcbiAgICAgICAgICAgIDxoMT5Mb2FkaW5nIHRoZSBjb21tZW50IHlvdSBsaW5rZWQgdG8uLi48L2gxPlxyXG4gICAgICAgICAgICA8bWF0LXNwaW5uZXIgW2RpYW1ldGVyXT1cIjMwMFwiIFtzdHJva2VXaWR0aF09XCIyXCI+PC9tYXQtc3Bpbm5lcj5cclxuICAgICAgICAgICAgPHA+XHJcbiAgICAgICAgICAgICAgICBJZiB0aGVyZSBhcmUgYSBsb3Qgb2YgY29tbWVudHMsIHRoaXMgbWlnaHQgdGFrZSBhd2hpbGUhXHJcbiAgICAgICAgICAgIDwvcD5cclxuICAgICAgICA8L2Rpdj5cclxuICAgICAgICA8ZGl2IGNsYXNzPVwibG9hZGluZy1jb21tZW50XCIgKm5nSWY9XCIhbG9hZGluZ1NoYXJlZENvbW1lbnQgJiYgbGFzdFNoYXJlZENvbW1lbnRJRFwiPlxyXG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwic2hhcmVkQ29tbWVudE1pc3NpbmdcIj5cclxuXHJcbiAgICAgICAgICAgICAgICA8YSBjbGFzcz1cImNsb3NlXCIgbWF0LWljb24tYnV0dG9uIG1hdFRvb2x0aXA9XCJDbG9zZSB0aGlzIG5vdGljZVwiIGhyZWY9XCJqYXZhc2NyaXB0OjtcIiAoY2xpY2spPVwibGFzdFNoYXJlZENvbW1lbnRJRCA9IG51bGxcIj5cclxuICAgICAgICAgICAgICAgICAgICA8bWF0LWljb24+Y2xvc2U8L21hdC1pY29uPlxyXG4gICAgICAgICAgICAgICAgPC9hPlxyXG5cclxuICAgICAgICAgICAgICAgIDxoMT5cclxuICAgICAgICAgICAgICAgICAgICA8bWF0LWljb24+ZXJyb3I8L21hdC1pY29uPlxyXG4gICAgICAgICAgICAgICAgICAgIFVoIG9oIVxyXG4gICAgICAgICAgICAgICAgPC9oMT5cclxuXHJcbiAgICAgICAgICAgICAgICA8cD5UaGUgY29tbWVudCB5b3UgbGlua2VkIHRvIGNhbid0IGJlIGZvdW5kISBJdCBtYXkgaGF2ZSBiZWVuIHJlbW92ZWQuPC9wPlxyXG4gICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIiFzaGFyZWRDb21tZW50TWlzc2luZ1wiPlxyXG4gICAgICAgICAgICAgICAgPGEgY2xhc3M9XCJjbG9zZVwiIG1hdC1pY29uLWJ1dHRvbiBtYXRUb29sdGlwPVwiQ2xvc2UgdGhpcyBub3RpY2VcIiBocmVmPVwiamF2YXNjcmlwdDo7XCIgKGNsaWNrKT1cImxhc3RTaGFyZWRDb21tZW50SUQgPSBudWxsXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uPmNsb3NlPC9tYXQtaWNvbj5cclxuICAgICAgICAgICAgICAgIDwvYT5cclxuICAgICAgICAgICAgICAgIDxidXR0b24gbWF0LWJ1dHRvbiAoY2xpY2spPVwibmF2aWdhdGVUb1NoYXJlZENvbW1lbnQobGFzdFNoYXJlZENvbW1lbnRJRClcIj5cclxuICAgICAgICAgICAgICAgICAgICA8bWF0LWljb24+bW92ZV9kb3duPC9tYXQtaWNvbj4gSnVtcCB0byBzaGFyZWQgY29tbWVudFxyXG4gICAgICAgICAgICAgICAgPC9idXR0b24+XHJcbiAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICAgIDwvZGl2PlxyXG5cclxuICAgICAgICA8YmFudGEtY29tbWVudC12aWV3XHJcbiAgICAgICAgICAgICNjb21tZW50Vmlld1xyXG4gICAgICAgICAgICBbY2xhc3MuZmFkZWRdPVwic2VsZWN0ZWRNZXNzYWdlICYmICF1c2VJbmxpbmVSZXBsaWVzXCJcclxuICAgICAgICAgICAgW3NvdXJjZV09XCJzb3VyY2VcIlxyXG4gICAgICAgICAgICBbZml4ZWRIZWlnaHRdPVwiZml4ZWRIZWlnaHRcIlxyXG4gICAgICAgICAgICBbbWF4TWVzc2FnZXNdPVwibWF4TWVzc2FnZXNcIlxyXG4gICAgICAgICAgICBbbWF4VmlzaWJsZU1lc3NhZ2VzXT1cIm1heFZpc2libGVNZXNzYWdlc1wiXHJcbiAgICAgICAgICAgIFtnZW5lcmljQXZhdGFyVXJsXT1cImdlbmVyaWNBdmF0YXJVcmxcIlxyXG4gICAgICAgICAgICBbY3VzdG9tTWVudUl0ZW1zXT1cImN1c3RvbU1lbnVJdGVtc1wiXHJcbiAgICAgICAgICAgIFtob2xkTmV3TWVzc2FnZXNdPVwic2VsZWN0ZWRNZXNzYWdlVmlzaWJsZVwiXHJcbiAgICAgICAgICAgICh1c2VyU2VsZWN0ZWQpPVwic2VsZWN0TWVzc2FnZVVzZXIoJGV2ZW50KVwiXHJcbiAgICAgICAgICAgIChzb3J0T3JkZXJDaGFuZ2VkKT1cInNvcnRPcmRlciA9ICRldmVudFwiXHJcbiAgICAgICAgICAgIChmaWx0ZXJNb2RlQ2hhbmdlZCk9XCJmaWx0ZXJNb2RlID0gJGV2ZW50XCJcclxuICAgICAgICAgICAgKHNlbGVjdGVkKT1cInRvZ2dsZVNlbGVjdGVkTWVzc2FnZSgkZXZlbnQpXCJcclxuICAgICAgICAgICAgKGxpa2VkKT1cImxpa2VNZXNzYWdlKHNvdXJjZSwgJGV2ZW50KVwiXHJcbiAgICAgICAgICAgICh1bmxpa2VkKT1cInVubGlrZU1lc3NhZ2Uoc291cmNlLCAkZXZlbnQpXCJcclxuICAgICAgICAgICAgKG1lc3NhZ2VFZGl0ZWQpPVwiZWRpdE1lc3NhZ2Uoc291cmNlLCAkZXZlbnQubWVzc2FnZSwgJGV2ZW50Lm5ld01lc3NhZ2UpXCJcclxuICAgICAgICAgICAgKHJlcG9ydGVkKT1cInJlcG9ydE1lc3NhZ2UoJGV2ZW50KVwiXHJcbiAgICAgICAgICAgICh1c2VybmFtZVNlbGVjdGVkKT1cInNlbGVjdFVzZXJuYW1lKCRldmVudClcIlxyXG4gICAgICAgICAgICAoYXZhdGFyU2VsZWN0ZWQpPVwic2VsZWN0QXZhdGFyKCRldmVudClcIlxyXG4gICAgICAgICAgICAoc2hhcmVkKT1cInNoYXJlTWVzc2FnZSgkZXZlbnQpXCJcclxuICAgICAgICAgICAgW3NlbGVjdGVkTWVzc2FnZV09XCJzZWxlY3RlZE1lc3NhZ2VcIlxyXG4gICAgICAgICAgICAoZGVsZXRlZCk9XCJkZWxldGVNZXNzYWdlKCRldmVudClcIlxyXG4gICAgICAgICAgICA+XHJcbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJpbmxpbmUtcmVwbGllc1wiPlxyXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZvY3VzZWRcIiBbY2xhc3MudmlzaWJsZV09XCJzZWxlY3RlZE1lc3NhZ2VWaXNpYmxlXCIgKm5nSWY9XCJzZWxlY3RlZE1lc3NhZ2VcIj5cclxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicmVwbGllc1wiPlxyXG4gICAgICAgICAgICBcclxuICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIiFzZWxlY3RlZE1lc3NhZ2VUaHJlYWRcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJsb2FkaW5nXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1zcGlubmVyPjwvbWF0LXNwaW5uZXI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwic2VsZWN0ZWRNZXNzYWdlVGhyZWFkXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YmFudGEtY29tbWVudC12aWV3XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3NvdXJjZV09XCJzZWxlY3RlZE1lc3NhZ2VUaHJlYWRcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFthbGxvd1JlcGxpZXNdPVwiZmFsc2VcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtmaXhlZEhlaWdodF09XCJmYWxzZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3Nob3dFbXB0eVN0YXRlXT1cImZhbHNlXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmV3ZXN0TGFzdF09XCJ0cnVlXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbZW5hYmxlSG9sZE9uQ2xpY2tdPVwiZmFsc2VcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtob2xkTmV3TWVzc2FnZXNdPVwicmVwbHlGaWVsZEZvY3VzZWRcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtnZW5lcmljQXZhdGFyVXJsXT1cImdlbmVyaWNBdmF0YXJVcmxcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChsaWtlZCk9XCJsaWtlTWVzc2FnZShzZWxlY3RlZE1lc3NhZ2VUaHJlYWQsICRldmVudClcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh1bmxpa2VkKT1cInVubGlrZU1lc3NhZ2Uoc2VsZWN0ZWRNZXNzYWdlVGhyZWFkLCAkZXZlbnQpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobWVzc2FnZUVkaXRlZCk9XCJlZGl0TWVzc2FnZShzZWxlY3RlZE1lc3NhZ2VUaHJlYWQsICRldmVudC5tZXNzYWdlLCAkZXZlbnQubmV3TWVzc2FnZSlcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChyZXBvcnRlZCk9XCJyZXBvcnRNZXNzYWdlKCRldmVudClcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh1c2VybmFtZVNlbGVjdGVkKT1cInNlbGVjdFVzZXJuYW1lKCRldmVudClcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChhdmF0YXJTZWxlY3RlZCk9XCJzZWxlY3RBdmF0YXIoJGV2ZW50KVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHNoYXJlZCk9XCJzaGFyZU1lc3NhZ2UoJGV2ZW50KVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGRlbGV0ZWQpPVwiZGVsZXRlTWVzc2FnZSgkZXZlbnQpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA+PC9iYW50YS1jb21tZW50LXZpZXc+XHJcbiAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGJhbnRhLWNvbW1lbnQtZmllbGRcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbdXJsXT1cInVybFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3NlbmRMYWJlbF09XCJyZXBseUxhYmVsXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbc2VuZGluZ0xhYmVsXT1cInNlbmRpbmdMYWJlbFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3NpZ25pbmdJbkxhYmVsXT1cInNpZ25pbmdJbkxhYmVsXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbaGFzaHRhZ3NdPVwiaGFzaHRhZ3NcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtwYXJ0aWNpcGFudHNdPVwicGFydGljaXBhbnRzXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoc2lnbkluU2VsZWN0ZWQpPVwic2hvd1NpZ25JbigpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbWF4TGVuZ3RoXT1cIm1heENvbW1lbnRMZW5ndGhcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzb3VyY2VdPVwic2VsZWN0ZWRNZXNzYWdlVGhyZWFkXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbc2lnbkluU3RhdGVdPVwic291cmNlPy5zaWduSW5TdGF0ZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2NhbkNvbW1lbnRdPVwic291cmNlPy5wZXJtaXNzaW9ucz8uY2FuUG9zdFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3NpZ25JbkxhYmVsXT1cInNpZ25JbkxhYmVsXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbcGVybWlzc2lvbkRlbmllZExhYmVsXT1cInNvdXJjZT8ucGVybWlzc2lvbnM/LmNhblBvc3RFcnJvck1lc3NhZ2UgfHwgcGVybWlzc2lvbkRlbmllZExhYmVsXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbcmVhZG9ubHldPVwic291cmNlPy5yZWFkb25seVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3Nob3VsZEludGVyY2VwdE1lc3NhZ2VTZW5kXT1cInNob3VsZEludGVyY2VwdE1lc3NhZ2VTZW5kXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbdXNlcl09XCJ1c2VyXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbGFiZWxdPVwicG9zdFJlcGx5TGFiZWxcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzdWJtaXRdPVwic2VuZFJlcGx5XCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbYWxsb3dBdHRhY2htZW50c109XCJhbGxvd0F0dGFjaG1lbnRzXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbZ2VuZXJpY0F2YXRhclVybF09XCJnZW5lcmljQXZhdGFyVXJsXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAocGVybWlzc2lvbkRlbmllZEVycm9yKT1cImhhbmRsZVBlcm1pc3Npb25EZW5pZWQoJGV2ZW50KVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGVkaXRBdmF0YXJTZWxlY3RlZCk9XCJzaG93RWRpdEF2YXRhcigpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoZm9jdXNDaGFuZ2UpPVwicmVwbHlGaWVsZEZvY3VzZWQgPSAkZXZlbnRcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwic2VuZFJlcGx5T3B0aW9uc1RlbXBsYXRlXCI+PC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2JhbnRhLWNvbW1lbnQtZmllbGQ+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgIDwvYmFudGEtY29tbWVudC12aWV3PlxyXG4gICAgPC9kaXY+XHJcbiAgICA8ZGl2IGNsYXNzPVwicmVjb25uZWN0aW5nXCIgKm5nSWY9XCJjb25uZWN0aW9uU3RhdGUgPT09ICdsb3N0J1wiPlxyXG4gICAgICAgIDxzdHJvbmc+Q29ubmVjdGlvbiB0byBMaXZlIENvbW1lbnRzIGxvc3QuPC9zdHJvbmc+IFJlY29ubmVjdGluZy4uLlxyXG4gICAgPC9kaXY+XHJcbjwvbmctY29udGFpbmVyPlxyXG4iXX0=