stream-chat-angular 4.66.1 → 5.0.0-v5.2

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 (161) hide show
  1. package/assets/version.d.ts +1 -1
  2. package/{esm2015/assets/version.js → esm2020/assets/version.mjs} +2 -2
  3. package/esm2020/lib/attachment-configuration.service.mjs +185 -0
  4. package/esm2020/lib/attachment-list/attachment-list.component.mjs +205 -0
  5. package/esm2020/lib/attachment-preview-list/attachment-preview-list.component.mjs +45 -0
  6. package/esm2020/lib/attachment.service.mjs +262 -0
  7. package/esm2020/lib/avatar/avatar.component.mjs +163 -0
  8. package/esm2020/lib/avatar-placeholder/avatar-placeholder.component.mjs +74 -0
  9. package/esm2020/lib/channel/channel.component.mjs +46 -0
  10. package/esm2020/lib/channel-header/channel-header.component.mjs +79 -0
  11. package/esm2020/lib/channel-list/channel-list-toggle.service.mjs +72 -0
  12. package/esm2020/lib/channel-list/channel-list.component.mjs +60 -0
  13. package/esm2020/lib/channel-preview/channel-preview.component.mjs +155 -0
  14. package/esm2020/lib/channel.service.mjs +1460 -0
  15. package/esm2020/lib/chat-client.service.mjs +206 -0
  16. package/{esm2015/lib/custom-templates.service.js → esm2020/lib/custom-templates.service.mjs} +3 -3
  17. package/{esm2015/lib/date-parser.service.js → esm2020/lib/date-parser.service.mjs} +3 -3
  18. package/esm2020/lib/edit-message-form/edit-message-form.component.mjs +83 -0
  19. package/esm2020/lib/get-channel-display-text.mjs +14 -0
  20. package/esm2020/lib/get-message-translation.mjs +12 -0
  21. package/esm2020/lib/icon/icon.component.mjs +21 -0
  22. package/esm2020/lib/icon-placeholder/icon-placeholder.component.mjs +31 -0
  23. package/esm2020/lib/loading-indicator/loading-indicator.component.mjs +31 -0
  24. package/esm2020/lib/loading-indicator-placeholder/loading-indicator-placeholder.component.mjs +38 -0
  25. package/esm2020/lib/message/message.component.mjs +418 -0
  26. package/esm2020/lib/message-actions-box/message-actions-box.component.mjs +130 -0
  27. package/esm2020/lib/message-actions.service.mjs +119 -0
  28. package/esm2020/lib/message-bounce-prompt/message-bounce-prompt.component.mjs +71 -0
  29. package/esm2020/lib/message-input/autocomplete-textarea/autocomplete-textarea.component.mjs +262 -0
  30. package/{esm2015/lib/message-input/emoji-input.service.js → esm2020/lib/message-input/emoji-input.service.mjs} +3 -3
  31. package/{esm2015/lib/message-input/message-input-config.service.js → esm2020/lib/message-input/message-input-config.service.mjs} +3 -3
  32. package/esm2020/lib/message-input/message-input.component.mjs +443 -0
  33. package/{esm2015/lib/message-input/textarea/textarea.component.js → esm2020/lib/message-input/textarea/textarea.component.mjs} +5 -9
  34. package/esm2020/lib/message-input/textarea.directive.mjs +89 -0
  35. package/esm2020/lib/message-list/group-styles.mjs +52 -0
  36. package/{esm2015/lib/message-list/image-load.service.js → esm2020/lib/message-list/image-load.service.mjs} +3 -3
  37. package/esm2020/lib/message-list/message-list.component.mjs +699 -0
  38. package/esm2020/lib/message-preview.mjs +21 -0
  39. package/esm2020/lib/message-reactions/message-reactions.component.mjs +252 -0
  40. package/{esm2015/lib/message-reactions.service.js → esm2020/lib/message-reactions.service.mjs} +3 -3
  41. package/{esm2015/lib/message.service.js → esm2020/lib/message.service.mjs} +4 -4
  42. package/esm2020/lib/modal/modal.component.mjs +69 -0
  43. package/esm2020/lib/notification/notification.component.mjs +20 -0
  44. package/esm2020/lib/notification-list/notification-list.component.mjs +37 -0
  45. package/esm2020/lib/notification.service.mjs +79 -0
  46. package/esm2020/lib/read-by.mjs +12 -0
  47. package/{esm2015/lib/stream-autocomplete-textarea.module.js → esm2020/lib/stream-autocomplete-textarea.module.mjs} +6 -6
  48. package/{esm2015/lib/stream-avatar.module.js → esm2020/lib/stream-avatar.module.mjs} +5 -5
  49. package/{esm2015/lib/stream-chat.module.js → esm2020/lib/stream-chat.module.mjs} +14 -16
  50. package/{esm2015/lib/stream-i18n.service.js → esm2020/lib/stream-i18n.service.mjs} +5 -5
  51. package/{esm2015/lib/stream-textarea.module.js → esm2020/lib/stream-textarea.module.mjs} +6 -6
  52. package/esm2020/lib/theme.service.mjs +123 -0
  53. package/esm2020/lib/thread/thread.component.mjs +51 -0
  54. package/{esm2015/lib/transliteration.service.js → esm2020/lib/transliteration.service.mjs} +3 -3
  55. package/esm2020/lib/types.mjs +2 -0
  56. package/esm2020/lib/voice-recording/voice-recording-wavebar/voice-recording-wavebar.component.mjs +183 -0
  57. package/esm2020/lib/voice-recording/voice-recording.component.mjs +102 -0
  58. package/fesm2015/{stream-chat-angular.js → stream-chat-angular.mjs} +313 -426
  59. package/fesm2015/stream-chat-angular.mjs.map +1 -0
  60. package/fesm2020/stream-chat-angular.mjs +7123 -0
  61. package/fesm2020/stream-chat-angular.mjs.map +1 -0
  62. package/lib/attachment-list/attachment-list.component.d.ts +3 -3
  63. package/lib/attachment-preview-list/attachment-preview-list.component.d.ts +1 -1
  64. package/lib/attachment.service.d.ts +0 -1
  65. package/lib/avatar/avatar.component.d.ts +1 -1
  66. package/lib/avatar-placeholder/avatar-placeholder.component.d.ts +1 -1
  67. package/lib/channel/channel.component.d.ts +1 -1
  68. package/lib/channel-header/channel-header.component.d.ts +1 -1
  69. package/lib/channel-list/channel-list-toggle.service.d.ts +0 -1
  70. package/lib/channel-list/channel-list.component.d.ts +1 -1
  71. package/lib/channel-preview/channel-preview.component.d.ts +1 -1
  72. package/lib/channel.service.d.ts +7 -7
  73. package/lib/chat-client.service.d.ts +1 -1
  74. package/lib/edit-message-form/edit-message-form.component.d.ts +1 -1
  75. package/lib/get-message-translation.d.ts +1 -1
  76. package/lib/icon/icon.component.d.ts +1 -1
  77. package/lib/icon-placeholder/icon-placeholder.component.d.ts +1 -1
  78. package/lib/loading-indicator/loading-indicator.component.d.ts +1 -1
  79. package/lib/loading-indicator-placeholder/loading-indicator-placeholder.component.d.ts +1 -1
  80. package/lib/message/message.component.d.ts +3 -7
  81. package/lib/message-actions-box/message-actions-box.component.d.ts +2 -4
  82. package/lib/message-actions.service.d.ts +0 -1
  83. package/lib/message-bounce-prompt/message-bounce-prompt.component.d.ts +1 -1
  84. package/lib/message-input/autocomplete-textarea/autocomplete-textarea.component.d.ts +1 -1
  85. package/lib/message-input/message-input.component.d.ts +2 -2
  86. package/lib/message-input/textarea/textarea.component.d.ts +1 -1
  87. package/lib/message-input/textarea.directive.d.ts +1 -1
  88. package/lib/message-list/group-styles.d.ts +1 -1
  89. package/lib/message-list/message-list.component.d.ts +4 -5
  90. package/lib/message-reactions/message-reactions.component.d.ts +1 -4
  91. package/lib/message.service.d.ts +0 -1
  92. package/lib/modal/modal.component.d.ts +1 -1
  93. package/lib/notification/notification.component.d.ts +1 -1
  94. package/lib/notification-list/notification-list.component.d.ts +2 -2
  95. package/lib/notification.service.d.ts +2 -5
  96. package/lib/stream-chat.module.d.ts +3 -3
  97. package/lib/theme.service.d.ts +1 -2
  98. package/lib/thread/thread.component.d.ts +1 -1
  99. package/lib/types.d.ts +18 -18
  100. package/lib/voice-recording/voice-recording-wavebar/voice-recording-wavebar.component.d.ts +2 -2
  101. package/lib/voice-recording/voice-recording.component.d.ts +1 -1
  102. package/package.json +31 -17
  103. package/src/assets/styles/v2/css/index.css +1 -1
  104. package/src/assets/styles/v2/css/index.layout.css +1 -1
  105. package/src/assets/styles/v2/scss/_base.scss +2 -2
  106. package/src/assets/version.ts +1 -1
  107. package/bundles/stream-chat-angular.umd.js +0 -8445
  108. package/bundles/stream-chat-angular.umd.js.map +0 -1
  109. package/esm2015/lib/attachment-configuration.service.js +0 -186
  110. package/esm2015/lib/attachment-list/attachment-list.component.js +0 -209
  111. package/esm2015/lib/attachment-preview-list/attachment-preview-list.component.js +0 -49
  112. package/esm2015/lib/attachment.service.js +0 -276
  113. package/esm2015/lib/avatar/avatar.component.js +0 -172
  114. package/esm2015/lib/avatar-placeholder/avatar-placeholder.component.js +0 -78
  115. package/esm2015/lib/channel/channel.component.js +0 -50
  116. package/esm2015/lib/channel-header/channel-header.component.js +0 -86
  117. package/esm2015/lib/channel-list/channel-list-toggle.service.js +0 -73
  118. package/esm2015/lib/channel-list/channel-list.component.js +0 -67
  119. package/esm2015/lib/channel-preview/channel-preview.component.js +0 -167
  120. package/esm2015/lib/channel.service.js +0 -1487
  121. package/esm2015/lib/chat-client.service.js +0 -211
  122. package/esm2015/lib/edit-message-form/edit-message-form.component.js +0 -87
  123. package/esm2015/lib/get-channel-display-text.js +0 -15
  124. package/esm2015/lib/get-message-translation.js +0 -13
  125. package/esm2015/lib/icon/icon.component.js +0 -25
  126. package/esm2015/lib/icon-placeholder/icon-placeholder.component.js +0 -35
  127. package/esm2015/lib/loading-indicator/loading-indicator.component.js +0 -35
  128. package/esm2015/lib/loading-indicator-placeholder/loading-indicator-placeholder.component.js +0 -42
  129. package/esm2015/lib/message/message.component.js +0 -436
  130. package/esm2015/lib/message-actions-box/message-actions-box.component.js +0 -137
  131. package/esm2015/lib/message-actions.service.js +0 -114
  132. package/esm2015/lib/message-bounce-prompt/message-bounce-prompt.component.js +0 -80
  133. package/esm2015/lib/message-input/autocomplete-textarea/autocomplete-textarea.component.js +0 -262
  134. package/esm2015/lib/message-input/message-input.component.js +0 -455
  135. package/esm2015/lib/message-input/textarea.directive.js +0 -90
  136. package/esm2015/lib/message-list/group-styles.js +0 -53
  137. package/esm2015/lib/message-list/message-list.component.js +0 -726
  138. package/esm2015/lib/message-preview.js +0 -7
  139. package/esm2015/lib/message-reactions/message-reactions.component.js +0 -266
  140. package/esm2015/lib/modal/modal.component.js +0 -74
  141. package/esm2015/lib/notification/notification.component.js +0 -24
  142. package/esm2015/lib/notification-list/notification-list.component.js +0 -38
  143. package/esm2015/lib/notification.service.js +0 -79
  144. package/esm2015/lib/read-by.js +0 -13
  145. package/esm2015/lib/theme.service.js +0 -122
  146. package/esm2015/lib/thread/thread.component.js +0 -55
  147. package/esm2015/lib/types.js +0 -2
  148. package/esm2015/lib/voice-recording/voice-recording-wavebar/voice-recording-wavebar.component.js +0 -192
  149. package/esm2015/lib/voice-recording/voice-recording.component.js +0 -115
  150. package/fesm2015/stream-chat-angular.js.map +0 -1
  151. /package/{esm2015/assets/i18n/en.js → esm2020/assets/i18n/en.mjs} +0 -0
  152. /package/{esm2015/lib/injection-tokens.js → esm2020/lib/injection-tokens.mjs} +0 -0
  153. /package/{esm2015/lib/is-image-attachment.js → esm2020/lib/is-image-attachment.mjs} +0 -0
  154. /package/{esm2015/lib/is-image-file.js → esm2020/lib/is-image-file.mjs} +0 -0
  155. /package/{esm2015/lib/is-on-separate-date.js → esm2020/lib/is-on-separate-date.mjs} +0 -0
  156. /package/{esm2015/lib/list-users.js → esm2020/lib/list-users.mjs} +0 -0
  157. /package/{esm2015/lib/message-input/textarea.interface.js → esm2020/lib/message-input/textarea.interface.mjs} +0 -0
  158. /package/{esm2015/lib/parse-date.js → esm2020/lib/parse-date.mjs} +0 -0
  159. /package/{esm2015/public-api.js → esm2020/public-api.mjs} +0 -0
  160. /package/{esm2015/stream-chat-angular.js → esm2020/stream-chat-angular.mjs} +0 -0
  161. /package/{stream-chat-angular.d.ts → index.d.ts} +0 -0
@@ -1,1487 +0,0 @@
1
- import { __awaiter } from "tslib";
2
- import { Injectable } from '@angular/core';
3
- import { BehaviorSubject, combineLatest, ReplaySubject, } from 'rxjs';
4
- import { filter, first, map, shareReplay, take } from 'rxjs/operators';
5
- import { getMessageTranslation } from './get-message-translation';
6
- import { createMessagePreview } from './message-preview';
7
- import { getReadBy } from './read-by';
8
- import * as i0 from "@angular/core";
9
- import * as i1 from "./chat-client.service";
10
- import * as i2 from "./notification.service";
11
- /**
12
- * The `ChannelService` provides data and interaction for the channel list and message list.
13
- */
14
- export class ChannelService {
15
- constructor(chatClientService, ngZone, notificationService) {
16
- this.chatClientService = chatClientService;
17
- this.ngZone = ngZone;
18
- this.notificationService = notificationService;
19
- this.channelsSubject = new BehaviorSubject(undefined);
20
- this.activeChannelSubject = new BehaviorSubject(undefined);
21
- this.activeChannelMessagesSubject = new BehaviorSubject([]);
22
- this.activeChannelPinnedMessagesSubject = new BehaviorSubject([]);
23
- this.hasMoreChannelsSubject = new ReplaySubject(1);
24
- this.activeChannelSubscriptions = [];
25
- this.channelSubscriptions = {};
26
- this.activeParentMessageIdSubject = new BehaviorSubject(undefined);
27
- this.activeThreadMessagesSubject = new BehaviorSubject([]);
28
- this.jumpToMessageSubject = new BehaviorSubject({ id: undefined, parentId: undefined });
29
- this.latestMessageDateByUserByChannelsSubject = new BehaviorSubject({});
30
- this.messagePageSize = 25;
31
- this.messageToQuoteSubject = new BehaviorSubject(undefined);
32
- this.usersTypingInChannelSubject = new BehaviorSubject([]);
33
- this.usersTypingInThreadSubject = new BehaviorSubject([]);
34
- this._shouldMarkActiveChannelAsRead = true;
35
- this.isStateRecoveryInProgress = false;
36
- this.channelQueryStateSubject = new BehaviorSubject(undefined);
37
- this.channelListSetter = (channels, shouldStopWatchingRemovedChannels = true) => {
38
- const currentChannels = this.channelsSubject.getValue() || [];
39
- const newChannels = channels.filter((c) => !currentChannels.find((channel) => channel.cid === c.cid));
40
- const deletedChannels = currentChannels.filter((c) => !(channels === null || channels === void 0 ? void 0 : channels.find((channel) => channel.cid === c.cid)));
41
- void this.addChannelsFromNotification(newChannels);
42
- this.removeChannelsFromChannelList(deletedChannels.map((c) => c.cid), shouldStopWatchingRemovedChannels);
43
- };
44
- this.messageListSetter = (messages) => {
45
- this.activeChannelMessagesSubject.next(messages);
46
- };
47
- this.threadListSetter = (messages) => {
48
- this.activeThreadMessagesSubject.next(messages);
49
- };
50
- this.parentMessageSetter = (message) => {
51
- this.activeParentMessageIdSubject.next(message === null || message === void 0 ? void 0 : message.id);
52
- };
53
- this.areReadEventsPaused = false;
54
- this.channels$ = this.channelsSubject.asObservable().pipe(shareReplay(1));
55
- this.activeChannel$ = this.activeChannelSubject
56
- .asObservable()
57
- .pipe(shareReplay(1));
58
- this.activeChannelMessages$ = this.activeChannelMessagesSubject.pipe(map((messages) => {
59
- const channel = this.activeChannelSubject.getValue();
60
- return messages.map((message) => this.transformToStreamMessage(message, channel));
61
- }), shareReplay(1));
62
- this.bouncedMessage$ = new BehaviorSubject(undefined);
63
- this.hasMoreChannels$ = this.hasMoreChannelsSubject
64
- .asObservable()
65
- .pipe(shareReplay(1));
66
- this.activeParentMessageId$ = this.activeParentMessageIdSubject
67
- .asObservable()
68
- .pipe(shareReplay(1));
69
- this.activeThreadMessages$ = this.activeThreadMessagesSubject.pipe(map((messages) => {
70
- const channel = this.activeChannelSubject.getValue();
71
- return messages.map((message) => this.transformToStreamMessage(message, channel));
72
- }), shareReplay(1));
73
- this.activeParentMessage$ = combineLatest([
74
- this.activeChannelMessages$,
75
- this.activeParentMessageId$,
76
- ]).pipe(map(([messages, parentMessageId]) => {
77
- if (!parentMessageId) {
78
- return undefined;
79
- }
80
- else {
81
- const message = messages.find((m) => m.id === parentMessageId);
82
- if (!message) {
83
- void this.setAsActiveParentMessage(undefined);
84
- return undefined;
85
- }
86
- else {
87
- return message;
88
- }
89
- }
90
- }), shareReplay(1));
91
- this.messageToQuote$ = this.messageToQuoteSubject
92
- .asObservable()
93
- .pipe(shareReplay(1));
94
- this.jumpToMessage$ = this.jumpToMessageSubject
95
- .asObservable()
96
- .pipe(shareReplay(1));
97
- this.usersTypingInChannel$ = this.usersTypingInChannelSubject
98
- .asObservable()
99
- .pipe(shareReplay(1));
100
- this.usersTypingInThread$ = this.usersTypingInThreadSubject
101
- .asObservable()
102
- .pipe(shareReplay(1));
103
- this.latestMessageDateByUserByChannels$ =
104
- this.latestMessageDateByUserByChannelsSubject
105
- .asObservable()
106
- .pipe(shareReplay(1));
107
- this.activeChannelPinnedMessages$ = this.activeChannelPinnedMessagesSubject
108
- .asObservable()
109
- .pipe(shareReplay(1));
110
- this.channelQueryState$ = this.channelQueryStateSubject
111
- .asObservable()
112
- .pipe(shareReplay(1));
113
- }
114
- /**
115
- * If set to false, read events won't be sent as new messages are received. If set to true active channel (if any) will immediately be marked as read.
116
- */
117
- get shouldMarkActiveChannelAsRead() {
118
- return this._shouldMarkActiveChannelAsRead;
119
- }
120
- /**
121
- * If set to false, read events won't be sent as new messages are received. If set to true active channel (if any) will immediately be marked as read.
122
- */
123
- set shouldMarkActiveChannelAsRead(shouldMarkActiveChannelAsRead) {
124
- if (!this._shouldMarkActiveChannelAsRead && shouldMarkActiveChannelAsRead) {
125
- const activeChannel = this.activeChannelSubject.getValue();
126
- if (activeChannel && this.canSendReadEvents) {
127
- void activeChannel.markRead();
128
- }
129
- }
130
- this._shouldMarkActiveChannelAsRead = shouldMarkActiveChannelAsRead;
131
- }
132
- /**
133
- * Sets the given `channel` as active and marks it as read.
134
- * If the channel wasn't previously part of the channel, it will be added to the beginning of the list.
135
- *
136
- * @param channel
137
- */
138
- setAsActiveChannel(channel) {
139
- var _a, _b;
140
- const prevActiveChannel = this.activeChannelSubject.getValue();
141
- if ((prevActiveChannel === null || prevActiveChannel === void 0 ? void 0 : prevActiveChannel.cid) === channel.cid) {
142
- return;
143
- }
144
- this.stopWatchForActiveChannelEvents(prevActiveChannel);
145
- this.areReadEventsPaused = false;
146
- const readState = channel.state.read[((_a = this.chatClientService.chatClient.user) === null || _a === void 0 ? void 0 : _a.id) || ''];
147
- this.activeChannelLastReadMessageId = readState === null || readState === void 0 ? void 0 : readState.last_read_message_id;
148
- if (((_b = channel.state.latestMessages[channel.state.latestMessages.length - 1]) === null || _b === void 0 ? void 0 : _b.id) === this.activeChannelLastReadMessageId) {
149
- this.activeChannelLastReadMessageId = undefined;
150
- }
151
- this.activeChannelUnreadCount = (readState === null || readState === void 0 ? void 0 : readState.unread_messages) || 0;
152
- this.watchForActiveChannelEvents(channel);
153
- this.addChannel(channel);
154
- this.activeChannelSubject.next(channel);
155
- const channelStateLength = channel.state.latestMessages.length;
156
- if (channelStateLength > 2 * this.messagePageSize) {
157
- channel.state.latestMessages = channel.state.latestMessages.slice(channelStateLength - 2 * this.messagePageSize);
158
- }
159
- this.setChannelState(channel);
160
- }
161
- /**
162
- * Deselects the currently active (if any) channel
163
- */
164
- deselectActiveChannel() {
165
- const activeChannel = this.activeChannelSubject.getValue();
166
- if (!activeChannel) {
167
- return;
168
- }
169
- this.stopWatchForActiveChannelEvents(activeChannel);
170
- this.activeChannelMessagesSubject.next([]);
171
- this.activeChannelSubject.next(undefined);
172
- this.activeParentMessageIdSubject.next(undefined);
173
- this.activeThreadMessagesSubject.next([]);
174
- this.latestMessageDateByUserByChannelsSubject.next({});
175
- this.selectMessageToQuote(undefined);
176
- this.jumpToMessageSubject.next({ id: undefined, parentId: undefined });
177
- this.activeChannelPinnedMessagesSubject.next([]);
178
- this.usersTypingInChannelSubject.next([]);
179
- this.usersTypingInThreadSubject.next([]);
180
- this.activeChannelLastReadMessageId = undefined;
181
- this.activeChannelUnreadCount = undefined;
182
- this.areReadEventsPaused = false;
183
- }
184
- /**
185
- * Sets the given `message` as an active parent message. If `undefined` is provided, it will deleselect the current parent message.
186
- * @param message
187
- * @param loadMessagesForm
188
- */
189
- setAsActiveParentMessage(message, loadMessagesForm = 'request') {
190
- var _a;
191
- return __awaiter(this, void 0, void 0, function* () {
192
- const messageToQuote = this.messageToQuoteSubject.getValue();
193
- if (messageToQuote && !!messageToQuote.parent_id) {
194
- this.messageToQuoteSubject.next(undefined);
195
- }
196
- if (!message) {
197
- this.activeParentMessageIdSubject.next(undefined);
198
- this.activeThreadMessagesSubject.next([]);
199
- const messageToJumpTo = this.jumpToMessageSubject.getValue();
200
- if (messageToJumpTo && !!messageToJumpTo.parentId) {
201
- this.jumpToMessageSubject.next({ id: undefined, parentId: undefined });
202
- }
203
- }
204
- else {
205
- this.activeParentMessageIdSubject.next(message.id);
206
- const activeChannel = this.activeChannelSubject.getValue();
207
- if (loadMessagesForm === 'request') {
208
- const result = yield (activeChannel === null || activeChannel === void 0 ? void 0 : activeChannel.getReplies(message.id, {
209
- limit: (_a = this.options) === null || _a === void 0 ? void 0 : _a.message_limit,
210
- }));
211
- this.activeThreadMessagesSubject.next((result === null || result === void 0 ? void 0 : result.messages) || []);
212
- }
213
- else {
214
- this.activeThreadMessagesSubject.next((activeChannel === null || activeChannel === void 0 ? void 0 : activeChannel.state.threads[message.id]) || []);
215
- }
216
- }
217
- });
218
- }
219
- /**
220
- * Loads the next page of messages of the active channel. The page size can be set in the [query option](https://getstream.io/chat/docs/javascript/query_channels/?language=javascript#query-options) object.
221
- * @param direction
222
- */
223
- loadMoreMessages(direction = 'older') {
224
- var _a, _b, _c, _d;
225
- const activeChnannel = this.activeChannelSubject.getValue();
226
- const messages = this.activeChannelMessagesSubject.getValue();
227
- const lastMessageId = (_a = messages[direction === 'older' ? 0 : messages.length - 1]) === null || _a === void 0 ? void 0 : _a.id;
228
- if (direction === 'newer' &&
229
- ((_b = activeChnannel === null || activeChnannel === void 0 ? void 0 : activeChnannel.state) === null || _b === void 0 ? void 0 : _b.latestMessages) === ((_c = activeChnannel === null || activeChnannel === void 0 ? void 0 : activeChnannel.state) === null || _c === void 0 ? void 0 : _c.messages)) {
230
- // If we are on latest message set, activeChannelMessages$ will be refreshed by WS events, no need for a request
231
- return false;
232
- }
233
- return activeChnannel === null || activeChnannel === void 0 ? void 0 : activeChnannel.query({
234
- messages: {
235
- limit: (_d = this.options) === null || _d === void 0 ? void 0 : _d.message_limit,
236
- [direction === 'older' ? 'id_lt' : 'id_gt']: lastMessageId,
237
- },
238
- members: { limit: 0 },
239
- watchers: { limit: 0 },
240
- }).then((res) => {
241
- var _a, _b, _c;
242
- if (((_a = activeChnannel === null || activeChnannel === void 0 ? void 0 : activeChnannel.data) === null || _a === void 0 ? void 0 : _a.id) ===
243
- ((_c = (_b = this.activeChannelSubject.getValue()) === null || _b === void 0 ? void 0 : _b.data) === null || _c === void 0 ? void 0 : _c.id)) {
244
- this.activeChannelMessagesSubject.next([
245
- ...activeChnannel.state.messages,
246
- ]);
247
- }
248
- return res;
249
- });
250
- }
251
- /**
252
- * Loads the next page of messages of the active thread. The page size can be set in the [query option](https://getstream.io/chat/docs/javascript/query_channels/?language=javascript#query-options) object.
253
- * @param direction
254
- */
255
- loadMoreThreadReplies(direction = 'older') {
256
- var _a, _b;
257
- return __awaiter(this, void 0, void 0, function* () {
258
- if (direction === 'newer') {
259
- // Thread replies aren't broke into different message sets, activeThreadMessages$ will be refreshed by WS events, no need for a request
260
- return;
261
- }
262
- const activeChnannel = this.activeChannelSubject.getValue();
263
- const parentMessageId = this.activeParentMessageIdSubject.getValue();
264
- if (!parentMessageId) {
265
- return;
266
- }
267
- const threadMessages = this.activeThreadMessagesSubject.getValue();
268
- const lastMessageId = (_a = threadMessages[direction === 'older' ? 0 : threadMessages.length - 1]) === null || _a === void 0 ? void 0 : _a.id;
269
- yield (activeChnannel === null || activeChnannel === void 0 ? void 0 : activeChnannel.getReplies(parentMessageId, {
270
- limit: (_b = this.options) === null || _b === void 0 ? void 0 : _b.message_limit,
271
- [direction === 'older' ? 'id_lt' : 'id_gt']: lastMessageId,
272
- }));
273
- this.activeThreadMessagesSubject.next((activeChnannel === null || activeChnannel === void 0 ? void 0 : activeChnannel.state.threads[parentMessageId]) || []);
274
- });
275
- }
276
- /**
277
- * Queries the channels with the given filters, sorts and options. More info about [channel querying](https://getstream.io/chat/docs/javascript/query_channels/?language=javascript) can be found in the platform documentation. By default the first channel in the list will be set as active channel and will be marked as read.
278
- * @param filters
279
- * @param sort
280
- * @param options
281
- * @param shouldSetActiveChannel Decides if the first channel in the result should be made as an active channel, or no channel should be marked as active
282
- * @returns the list of channels found by the query
283
- */
284
- init(filters, sort, options, shouldSetActiveChannel = true) {
285
- return __awaiter(this, void 0, void 0, function* () {
286
- this.filters = filters;
287
- this.options = Object.assign({ limit: 25, state: true, presence: true, watch: true, message_limit: this.messagePageSize }, options);
288
- this.sort = sort || { last_message_at: -1 };
289
- this.shouldSetActiveChannel = shouldSetActiveChannel;
290
- this.clientEventsSubscription = this.chatClientService.events$.subscribe((notification) => void this.handleNotification(notification));
291
- try {
292
- const result = yield this.queryChannels(this.shouldSetActiveChannel);
293
- return result;
294
- }
295
- catch (error) {
296
- this.dismissErrorNotification =
297
- this.notificationService.addPermanentNotification('streamChat.Error loading channels', 'error');
298
- throw error;
299
- }
300
- });
301
- }
302
- /**
303
- * Resets the `activeChannel$`, `channels$` and `activeChannelMessages$` Observables. Useful when disconnecting a chat user, use in combination with [`disconnectUser`](./ChatClientService.mdx/#disconnectuser).
304
- */
305
- reset() {
306
- var _a, _b;
307
- this.deselectActiveChannel();
308
- this.channelsSubject.next(undefined);
309
- this.channelQueryStateSubject.next(undefined);
310
- (_a = this.clientEventsSubscription) === null || _a === void 0 ? void 0 : _a.unsubscribe();
311
- (_b = this.dismissErrorNotification) === null || _b === void 0 ? void 0 : _b.call(this);
312
- this.dismissErrorNotification = undefined;
313
- Object.keys(this.channelSubscriptions).forEach((cid) => {
314
- this.channelSubscriptions[cid]();
315
- });
316
- this.channelSubscriptions = {};
317
- this.nextPageConfiguration = undefined;
318
- }
319
- /**
320
- * Loads the next page of channels. The page size can be set in the [query option](https://getstream.io/chat/docs/javascript/query_channels/?language=javascript#query-options) object.
321
- */
322
- loadMoreChannels() {
323
- return __awaiter(this, void 0, void 0, function* () {
324
- yield this.queryChannels(false);
325
- });
326
- }
327
- /**
328
- * Adds a reaction to a message.
329
- * @param messageId The id of the message to add the reaction to
330
- * @param reactionType The type of the reaction
331
- * @param customData
332
- */
333
- addReaction(messageId, reactionType, customData) {
334
- var _a;
335
- return __awaiter(this, void 0, void 0, function* () {
336
- yield ((_a = this.activeChannelSubject.getValue()) === null || _a === void 0 ? void 0 : _a.sendReaction(messageId, Object.assign({ type: reactionType }, customData)));
337
- });
338
- }
339
- /**
340
- * Removes a reaction from a message.
341
- * @param messageId The id of the message to remove the reaction from
342
- * @param reactionType Thr type of reaction to remove
343
- */
344
- removeReaction(messageId, reactionType) {
345
- var _a;
346
- return __awaiter(this, void 0, void 0, function* () {
347
- yield ((_a = this.activeChannelSubject
348
- .getValue()) === null || _a === void 0 ? void 0 : _a.deleteReaction(messageId, reactionType));
349
- });
350
- }
351
- /**
352
- * Sends a message to the active channel. The message is immediately added to the message list, if an error occurs and the message can't be sent, the error is indicated in `state` of the message.
353
- * @param text The text of the message
354
- * @param attachments The attachments
355
- * @param mentionedUsers Mentioned users
356
- * @param parentId Id of the parent message (if sending a thread reply)
357
- * @param quotedMessageId Id of the message to quote (if sending a quote reply)
358
- * @param customData
359
- */
360
- sendMessage(text, attachments = [], mentionedUsers = [], parentId = undefined, quotedMessageId = undefined, customData = undefined) {
361
- return __awaiter(this, void 0, void 0, function* () {
362
- let input = {
363
- text,
364
- attachments,
365
- mentionedUsers,
366
- parentId,
367
- quotedMessageId,
368
- customData,
369
- };
370
- if (this.beforeSendMessage) {
371
- input = yield this.beforeSendMessage(input);
372
- }
373
- const preview = createMessagePreview(this.chatClientService.chatClient.user, input.text, input.attachments, input.mentionedUsers, input.parentId, input.quotedMessageId, input.customData);
374
- const channel = this.activeChannelSubject.getValue();
375
- preview.readBy = [];
376
- channel.state.addMessageSorted(preview, true);
377
- const response = yield this.sendMessageRequest(preview, input.customData);
378
- return response;
379
- });
380
- }
381
- /**
382
- * Resends the given message to the active channel
383
- * @param message The message to resend
384
- */
385
- resendMessage(message) {
386
- return __awaiter(this, void 0, void 0, function* () {
387
- const channel = this.activeChannelSubject.getValue();
388
- channel.state.addMessageSorted(Object.assign(Object.assign({}, message), { errorStatusCode: undefined, status: 'sending' }), true);
389
- return this.sendMessageRequest(message, undefined, true);
390
- });
391
- }
392
- /**
393
- * Updates the message in the active channel
394
- * @param message Mesage to be updated
395
- */
396
- updateMessage(message) {
397
- var _a;
398
- return __awaiter(this, void 0, void 0, function* () {
399
- let messageToUpdate = Object.assign({}, message);
400
- delete messageToUpdate.i18n;
401
- if (this.beforeUpdateMessage) {
402
- messageToUpdate = yield this.beforeUpdateMessage(messageToUpdate);
403
- }
404
- if (message.moderation_details) {
405
- return this.resendMessage(message);
406
- }
407
- const response = yield this.chatClientService.chatClient.updateMessage(messageToUpdate);
408
- const channel = (_a = this.channelsSubject
409
- .getValue()) === null || _a === void 0 ? void 0 : _a.find((c) => c.cid === message.cid);
410
- if (response.message.type === 'error' &&
411
- response.message.moderation_details) {
412
- this.notificationService.addTemporaryNotification('streamChat.This message did not meet our content guidelines');
413
- return message;
414
- }
415
- return this.transformToStreamMessage(response.message, channel);
416
- });
417
- }
418
- /**
419
- * Deletes the message from the active channel
420
- * @param message Message to be deleted
421
- * @param isLocalDelete set this `true` if you want to delete a message that's only part of the local state, not yet saved on the backend
422
- */
423
- deleteMessage(message, isLocalDelete = false) {
424
- return __awaiter(this, void 0, void 0, function* () {
425
- if (isLocalDelete && this.activeChannel) {
426
- const result = this.activeChannel.state.removeMessage({
427
- id: message.id,
428
- parent_id: message.parent_id,
429
- });
430
- if (result) {
431
- message.parent_id
432
- ? this.activeThreadMessagesSubject.next(this.activeChannel.state.threads[message.parent_id])
433
- : this.activeChannelMessagesSubject.next(this.activeChannel.state.messages);
434
- }
435
- return;
436
- }
437
- if (this.messageDeleteConfirmationHandler) {
438
- const result = yield this.messageDeleteConfirmationHandler(message);
439
- if (result) {
440
- yield this.chatClientService.chatClient.deleteMessage(message.id);
441
- }
442
- }
443
- else {
444
- yield this.chatClientService.chatClient.deleteMessage(message.id);
445
- }
446
- });
447
- }
448
- /**
449
- * Uploads files to the channel. If you want to know more about [file uploads](https://getstream.io/chat/docs/javascript/file_uploads/?language=javascript) check out the platform documentation.
450
- * @param uploads the attachments to upload (output of the [`AttachmentService`](./AttachmentService.mdx))
451
- * @returns the result of file upload requests
452
- */
453
- uploadAttachments(uploads) {
454
- return __awaiter(this, void 0, void 0, function* () {
455
- const result = [];
456
- const channel = this.activeChannelSubject.getValue();
457
- const uploadResults = yield Promise.allSettled(uploads.map((upload) => upload.type === 'image'
458
- ? this.customImageUploadRequest
459
- ? this.customImageUploadRequest(upload.file, channel)
460
- : channel.sendImage(upload.file, upload.file.name, upload.file.type)
461
- : this.customFileUploadRequest
462
- ? this.customFileUploadRequest(upload.file, channel)
463
- : channel.sendFile(upload.file, upload.file.name, upload.file.type)));
464
- uploadResults.forEach((uploadResult, i) => {
465
- var _a, _b, _c, _d, _e, _f, _g;
466
- const file = uploads[i].file;
467
- const type = uploads[i].type;
468
- if (uploadResult.status === 'fulfilled') {
469
- result.push({
470
- file,
471
- type,
472
- state: 'success',
473
- url: uploadResult.value.file,
474
- /* eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access */
475
- thumb_url: uploadResult.value.thumb_url,
476
- });
477
- }
478
- else {
479
- let reason = 'unknown';
480
- let extraData;
481
- /* eslint-disable-next-line @typescript-eslint/no-unsafe-assignment */
482
- const message =
483
- /* eslint-disable-next-line @typescript-eslint/no-unsafe-member-access */
484
- (_b = (_a = uploadResult.reason.response) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.message;
485
- /* eslint-disable-next-line @typescript-eslint/no-unsafe-assignment */
486
- const code =
487
- /* eslint-disable-next-line @typescript-eslint/no-unsafe-member-access */
488
- (_d = (_c = uploadResult.reason.response) === null || _c === void 0 ? void 0 : _c.data) === null || _d === void 0 ? void 0 : _d.code;
489
- if (code === 22) {
490
- reason = 'file-size';
491
- extraData = { param: ((_e = /\d+MB/.exec(message || '')) === null || _e === void 0 ? void 0 : _e[0]) || '100MB' };
492
- }
493
- else if (code === 4 &&
494
- ((_f = message === null || message === void 0 ? void 0 : message.toLowerCase()) === null || _f === void 0 ? void 0 : _f.includes('file extension'))) {
495
- reason = 'file-extension';
496
- extraData = { param: ((_g = /\.\w+/.exec(message)) === null || _g === void 0 ? void 0 : _g[0]) || '' };
497
- }
498
- result.push({
499
- file,
500
- type,
501
- state: 'error',
502
- errorReason: reason,
503
- errorExtraInfo: extraData ? [extraData] : undefined,
504
- });
505
- }
506
- });
507
- return result;
508
- });
509
- }
510
- /**
511
- * Deletes an uploaded file by URL. If you want to know more about [file uploads](https://getstream.io/chat/docs/javascript/file_uploads/?language=javascript) check out the platform documentation
512
- * @param attachmentUpload Attachment to be deleted (output of the [`AttachmentService`](./AttachmentService.mdx))
513
- */
514
- deleteAttachment(attachmentUpload) {
515
- return __awaiter(this, void 0, void 0, function* () {
516
- const channel = this.activeChannelSubject.getValue();
517
- yield (attachmentUpload.type === 'image'
518
- ? this.customImageDeleteRequest
519
- ? this.customImageDeleteRequest(attachmentUpload.url, channel)
520
- : channel.deleteImage(attachmentUpload.url)
521
- : this.customFileDeleteRequest
522
- ? this.customFileDeleteRequest(attachmentUpload.url, channel)
523
- : channel.deleteFile(attachmentUpload.url));
524
- });
525
- }
526
- /**
527
- * Returns the autocomplete options for current channel members. If the channel has less than 100 members, it returns the channel members, otherwise sends a [search request](https://getstream.io/chat/docs/javascript/query_members/?language=javascript#pagination-and-ordering) with the given search term.
528
- * @param searchTerm Text to search for in the names of members
529
- * @returns The list of members matching the search filter
530
- */
531
- autocompleteMembers(searchTerm) {
532
- return __awaiter(this, void 0, void 0, function* () {
533
- const activeChannel = this.activeChannelSubject.getValue();
534
- if (!activeChannel) {
535
- return [];
536
- }
537
- if (Object.keys(activeChannel.state.members).length < 100) {
538
- return Object.values(activeChannel.state.members).filter((m) => { var _a; return ((_a = m.user) === null || _a === void 0 ? void 0 : _a.id) !== this.chatClientService.chatClient.userID; });
539
- }
540
- else {
541
- if (!searchTerm) {
542
- return [];
543
- }
544
- const result = yield activeChannel.queryMembers({
545
- name: { $autocomplete: searchTerm },
546
- id: { $ne: this.chatClientService.chatClient.userID },
547
- }); // TODO: find out why we need typecast here
548
- return Object.values(result.members);
549
- }
550
- });
551
- }
552
- /**
553
- * [Runs a message action](https://getstream.io/chat/docs/rest/#messages-runmessageaction) in the current channel. Updates the message list based on the action result (if no message is returned, the message will be removed from the message list).
554
- * @param messageId
555
- * @param formData
556
- * @param parentMessageId
557
- */
558
- sendAction(messageId, formData, parentMessageId) {
559
- return __awaiter(this, void 0, void 0, function* () {
560
- const channel = this.activeChannelSubject.getValue();
561
- const response = yield channel.sendAction(messageId, formData);
562
- if (response === null || response === void 0 ? void 0 : response.message) {
563
- channel.state.addMessageSorted(Object.assign(Object.assign({}, response.message), { status: 'received' }));
564
- const isThreadReply = !!response.message.parent_id;
565
- isThreadReply
566
- ? this.activeThreadMessagesSubject.next([
567
- ...channel.state.threads[response.message.parent_id],
568
- ])
569
- : this.activeChannelMessagesSubject.next([...channel.state.messages]);
570
- }
571
- else {
572
- channel.state.removeMessage({
573
- id: messageId,
574
- parent_id: parentMessageId,
575
- });
576
- if (parentMessageId) {
577
- this.activeThreadMessagesSubject.next(channel.state.threads[this.activeParentMessageIdSubject.getValue()]);
578
- }
579
- else {
580
- this.activeChannelMessagesSubject.next([...channel.state.messages]);
581
- }
582
- }
583
- });
584
- }
585
- /**
586
- * Selects or deselects the current message to quote reply to
587
- * @param message The message to select, if called with `undefined`, it deselects the message
588
- */
589
- selectMessageToQuote(message) {
590
- this.messageToQuoteSubject.next(message);
591
- }
592
- /**
593
- * Add a new channel to the channel list
594
- * The channel will be added to the beginning of the channel list
595
- * @param channel
596
- */
597
- addChannel(channel) {
598
- if (!this.channels.find((c) => c.cid === channel.cid)) {
599
- this.channelsSubject.next([channel, ...this.channels]);
600
- this.watchForChannelEvents(channel);
601
- }
602
- }
603
- sendMessageRequest(preview, customData, isResend = false) {
604
- var _a, _b, _c, _d;
605
- return __awaiter(this, void 0, void 0, function* () {
606
- const channel = this.activeChannelSubject.getValue();
607
- const isThreadReply = !!preview.parent_id;
608
- isThreadReply
609
- ? this.activeThreadMessagesSubject.next([
610
- ...channel.state.threads[preview.parent_id],
611
- ])
612
- : this.activeChannelMessagesSubject.next([...channel.state.messages]);
613
- try {
614
- const response = yield channel.sendMessage(Object.assign({ id: preview.id, text: preview.text, attachments: preview.attachments, mentioned_users: (_a = preview.mentioned_users) === null || _a === void 0 ? void 0 : _a.map((u) => u.id), parent_id: preview.parent_id, quoted_message_id: preview.quoted_message_id }, customData)); // TODO: find out why we need typecast here
615
- channel.state.addMessageSorted(Object.assign(Object.assign({}, response.message), { status: 'received' }), true);
616
- isThreadReply
617
- ? this.activeThreadMessagesSubject.next([
618
- ...channel.state.threads[preview.parent_id],
619
- ])
620
- : this.activeChannelMessagesSubject.next([...channel.state.messages]);
621
- let messages;
622
- (isThreadReply ? this.activeThreadMessages$ : this.activeChannelMessages$)
623
- .pipe(take(1))
624
- .subscribe((m) => (messages = m));
625
- const newMessage = messages[messages.length - 1];
626
- return newMessage;
627
- }
628
- catch (error) {
629
- const stringError = JSON.stringify(error);
630
- const parsedError = stringError ? JSON.parse(stringError) : {};
631
- let isAlreadyExists = false;
632
- if (isResend) {
633
- if (parsedError.status === 400 &&
634
- parsedError.code === 4 &&
635
- ((_d = (_c = (_b = parsedError === null || parsedError === void 0 ? void 0 : parsedError.response) === null || _b === void 0 ? void 0 : _b.data) === null || _c === void 0 ? void 0 : _c.message) === null || _d === void 0 ? void 0 : _d.includes('already exists'))) {
636
- isAlreadyExists = true;
637
- }
638
- }
639
- channel.state.addMessageSorted(Object.assign(Object.assign({}, preview), { errorStatusCode: isAlreadyExists
640
- ? undefined
641
- : parsedError.status || undefined, status: isAlreadyExists ? 'received' : 'failed' }), true);
642
- isThreadReply
643
- ? this.activeThreadMessagesSubject.next([
644
- ...channel.state.threads[preview.parent_id],
645
- ])
646
- : this.activeChannelMessagesSubject.next([...channel.state.messages]);
647
- let messages;
648
- (isThreadReply ? this.activeThreadMessages$ : this.activeChannelMessages$)
649
- .pipe(take(1))
650
- .subscribe((m) => (messages = m));
651
- const newMessage = messages[messages.length - 1];
652
- return newMessage;
653
- }
654
- });
655
- }
656
- /**
657
- * Jumps to the selected message inside the message list, if the message is not yet loaded, it'll load the message (and it's surroundings) from the API.
658
- * @param messageId The ID of the message to be loaded, 'latest' means jump to the latest messages
659
- * @param parentMessageId The ID of the parent message if we want to load a thread message
660
- */
661
- jumpToMessage(messageId, parentMessageId) {
662
- return __awaiter(this, void 0, void 0, function* () {
663
- const activeChannel = this.activeChannelSubject.getValue();
664
- try {
665
- yield (activeChannel === null || activeChannel === void 0 ? void 0 : activeChannel.state.loadMessageIntoState(messageId, parentMessageId));
666
- const messages = (activeChannel === null || activeChannel === void 0 ? void 0 : activeChannel.state.messages) || [];
667
- this.activeChannelMessagesSubject.next([...messages]);
668
- if (parentMessageId) {
669
- const parentMessage = messages.find((m) => m.id === parentMessageId);
670
- void this.setAsActiveParentMessage(parentMessage, 'state');
671
- }
672
- this.jumpToMessageSubject.next({
673
- id: messageId,
674
- parentId: parentMessageId,
675
- });
676
- }
677
- catch (error) {
678
- this.notificationService.addTemporaryNotification('streamChat.Message not found');
679
- throw error;
680
- }
681
- });
682
- }
683
- /**
684
- * Pins the given message in the channel
685
- * @param message
686
- */
687
- pinMessage(message) {
688
- var _a;
689
- return __awaiter(this, void 0, void 0, function* () {
690
- try {
691
- yield ((_a = this.chatClientService.chatClient) === null || _a === void 0 ? void 0 : _a.pinMessage(message));
692
- this.notificationService.addTemporaryNotification('streamChat.Message pinned', 'success');
693
- }
694
- catch (error) {
695
- this.notificationService.addTemporaryNotification('streamChat.Error pinning message');
696
- throw error;
697
- }
698
- });
699
- }
700
- /**
701
- * Removes the given message from pinned messages
702
- * @param message
703
- */
704
- unpinMessage(message) {
705
- var _a;
706
- return __awaiter(this, void 0, void 0, function* () {
707
- try {
708
- yield ((_a = this.chatClientService.chatClient) === null || _a === void 0 ? void 0 : _a.unpinMessage(message));
709
- this.notificationService.addTemporaryNotification('streamChat.Message unpinned', 'success');
710
- }
711
- catch (error) {
712
- this.notificationService.addTemporaryNotification('streamChat.Error removing message pin');
713
- throw error;
714
- }
715
- });
716
- }
717
- handleNotification(clientEvent) {
718
- switch (clientEvent.eventType) {
719
- case 'connection.recovered': {
720
- void this.ngZone.run(() => __awaiter(this, void 0, void 0, function* () {
721
- if (this.isStateRecoveryInProgress) {
722
- return;
723
- }
724
- this.isStateRecoveryInProgress = true;
725
- try {
726
- this.nextPageConfiguration = undefined;
727
- // If channel list is not inited, we set the active channel
728
- const shoulSetActiveChannel = this.shouldSetActiveChannel &&
729
- !this.activeChannelSubject.getValue();
730
- yield this.queryChannels(shoulSetActiveChannel || false, true);
731
- if (this.activeChannelSubject.getValue()) {
732
- // Thread messages are not refetched so active thread gets deselected to avoid displaying stale messages
733
- void this.setAsActiveParentMessage(undefined);
734
- // Update and reselect message to quote
735
- const messageToQuote = this.messageToQuoteSubject.getValue();
736
- this.setChannelState(this.activeChannelSubject.getValue());
737
- let messages;
738
- this.activeChannelMessages$
739
- .pipe(take(1))
740
- .subscribe((m) => (messages = m));
741
- const updatedMessageToQuote = messages.find((m) => m.id === (messageToQuote === null || messageToQuote === void 0 ? void 0 : messageToQuote.id));
742
- if (updatedMessageToQuote) {
743
- this.selectMessageToQuote(updatedMessageToQuote);
744
- }
745
- }
746
- this.isStateRecoveryInProgress = false;
747
- }
748
- catch (_a) {
749
- this.isStateRecoveryInProgress = false;
750
- }
751
- }));
752
- break;
753
- }
754
- case 'notification.message_new': {
755
- this.ngZone.run(() => {
756
- if (this.customNewMessageNotificationHandler) {
757
- this.customNewMessageNotificationHandler(clientEvent, this.channelListSetter);
758
- }
759
- else {
760
- this.handleNewMessageNotification(clientEvent);
761
- }
762
- });
763
- break;
764
- }
765
- case 'notification.added_to_channel': {
766
- this.ngZone.run(() => {
767
- if (this.customAddedToChannelNotificationHandler) {
768
- this.customAddedToChannelNotificationHandler(clientEvent, this.channelListSetter);
769
- }
770
- else {
771
- this.handleAddedToChannelNotification(clientEvent);
772
- }
773
- });
774
- break;
775
- }
776
- case 'notification.removed_from_channel': {
777
- this.ngZone.run(() => {
778
- if (this.customRemovedFromChannelNotificationHandler) {
779
- this.customRemovedFromChannelNotificationHandler(clientEvent, this.channelListSetter);
780
- }
781
- else {
782
- this.handleRemovedFromChannelNotification(clientEvent);
783
- }
784
- });
785
- break;
786
- }
787
- case 'user.updated': {
788
- this.ngZone.run(() => {
789
- var _a;
790
- const updatedChannels = (_a = this.channelsSubject.getValue()) === null || _a === void 0 ? void 0 : _a.map((c) => {
791
- if (this.chatClientService.chatClient.activeChannels[c.cid]) {
792
- return this.chatClientService.chatClient.activeChannels[c.cid];
793
- }
794
- else {
795
- return c;
796
- }
797
- });
798
- this.channelsSubject.next(updatedChannels);
799
- const activeChannel = this.activeChannelSubject.getValue();
800
- if (activeChannel) {
801
- this.activeChannelSubject.next(this.chatClientService.chatClient.activeChannels[activeChannel.cid] || activeChannel);
802
- this.activeChannelMessagesSubject.next(activeChannel.state.messages.map((m) => {
803
- m.readBy = getReadBy(m, activeChannel);
804
- return Object.assign({}, m);
805
- }));
806
- const activeParentMessage = this.activeParentMessageIdSubject.getValue();
807
- if (activeParentMessage) {
808
- const messages = activeChannel.state.threads[activeParentMessage];
809
- this.activeThreadMessagesSubject.next([...messages]);
810
- }
811
- this.activeChannelPinnedMessagesSubject.next([
812
- ...activeChannel.state.pinnedMessages,
813
- ]);
814
- }
815
- });
816
- break;
817
- }
818
- }
819
- }
820
- handleRemovedFromChannelNotification(clientEvent) {
821
- const channelIdToBeRemoved = clientEvent.event.channel.cid;
822
- this.removeChannelsFromChannelList([channelIdToBeRemoved], true);
823
- }
824
- handleNewMessageNotification(clientEvent) {
825
- if (clientEvent.event.channel) {
826
- void this.addChannelsFromNotification([clientEvent.event.channel]);
827
- }
828
- }
829
- handleAddedToChannelNotification(clientEvent) {
830
- if (clientEvent.event.channel) {
831
- void this.addChannelsFromNotification([clientEvent.event.channel]);
832
- }
833
- }
834
- addChannelsFromNotification(channelResponses) {
835
- return __awaiter(this, void 0, void 0, function* () {
836
- let newChannels = [];
837
- const watchRequests = [];
838
- channelResponses.forEach((channelResponse) => {
839
- const channel = this.chatClientService.chatClient.channel(channelResponse.type, channelResponse.id);
840
- watchRequests.push(channel.watch());
841
- newChannels.push(channel);
842
- });
843
- yield Promise.all(watchRequests);
844
- const currentChannels = this.channelsSubject.getValue() || [];
845
- newChannels = newChannels.filter((newChannel) => !currentChannels.find((c) => c.cid === newChannel.cid));
846
- if (newChannels.length > 0) {
847
- newChannels.forEach((c) => this.watchForChannelEvents(c));
848
- this.channelsSubject.next([...newChannels, ...currentChannels]);
849
- }
850
- });
851
- }
852
- removeChannelsFromChannelList(cids, shouldStopWatching) {
853
- var _a;
854
- const channels = this.channels.filter((c) => !cids.includes(c.cid || ''));
855
- if (shouldStopWatching) {
856
- cids.forEach((cid) => {
857
- var _a;
858
- if (this.channelSubscriptions[cid]) {
859
- this.channelSubscriptions[cid]();
860
- delete this.channelSubscriptions.cid;
861
- }
862
- void ((_a = this.chatClientService.chatClient.activeChannels[cid]) === null || _a === void 0 ? void 0 : _a.stopWatching());
863
- });
864
- }
865
- if (channels.length < this.channels.length) {
866
- this.channelsSubject.next(channels);
867
- if (cids.includes(((_a = this.activeChannelSubject.getValue()) === null || _a === void 0 ? void 0 : _a.cid) || '')) {
868
- if (channels.length > 0) {
869
- this.setAsActiveChannel(channels[0]);
870
- }
871
- else {
872
- this.activeChannelSubject.next(undefined);
873
- }
874
- }
875
- }
876
- }
877
- watchForActiveChannelEvents(channel) {
878
- this.activeChannelSubscriptions.push(channel.on('message.new', (event) => {
879
- this.ngZone.run(() => {
880
- event.message && event.message.parent_id
881
- ? event.message.parent_id ===
882
- this.activeParentMessageIdSubject.getValue()
883
- ? this.activeThreadMessagesSubject.next([
884
- ...channel.state.threads[event.message.parent_id],
885
- ])
886
- : null
887
- : this.activeChannelMessagesSubject.next([
888
- ...channel.state.messages,
889
- ]);
890
- this.activeChannel$.pipe(first()).subscribe((c) => {
891
- if (c) {
892
- this.markRead(c);
893
- }
894
- });
895
- this.updateLatestMessages(event);
896
- });
897
- }));
898
- this.activeChannelSubscriptions.push(channel.on('message.updated', (event) => this.messageUpdated(event)));
899
- this.activeChannelSubscriptions.push(channel.on('message.deleted', (event) => this.messageUpdated(event)));
900
- this.activeChannelSubscriptions.push(channel.on('reaction.new', (e) => this.messageReactionEventReceived(e)));
901
- this.activeChannelSubscriptions.push(channel.on('reaction.deleted', (e) => this.messageReactionEventReceived(e)));
902
- this.activeChannelSubscriptions.push(channel.on('reaction.updated', (e) => this.messageReactionEventReceived(e)));
903
- this.activeChannelSubscriptions.push(channel.on('message.read', (e) => {
904
- this.ngZone.run(() => {
905
- let latestMessage;
906
- let messages;
907
- this.activeChannelMessages$.pipe(first()).subscribe((m) => {
908
- messages = m;
909
- latestMessage = messages[messages.length - 1];
910
- });
911
- if (!latestMessage || !e.user) {
912
- return;
913
- }
914
- if (latestMessage.readBy) {
915
- latestMessage.readBy.splice(0, latestMessage.readBy.length);
916
- }
917
- else {
918
- latestMessage.readBy = [];
919
- }
920
- latestMessage.readBy.push(...getReadBy(latestMessage, channel));
921
- messages[messages.length - 1] = Object.assign({}, latestMessage);
922
- this.activeChannelMessagesSubject.next([...messages]);
923
- });
924
- }));
925
- this.activeChannelSubscriptions.push(this.chatClientService.events$
926
- .pipe(filter((e) => e.eventType === 'notification.mark_unread' &&
927
- e.event.channel_id === channel.id), map((e) => e.event))
928
- .subscribe((e) => {
929
- this.ngZone.run(() => {
930
- this.activeChannelLastReadMessageId = e.last_read_message_id;
931
- this.activeChannelUnreadCount = e.unread_messages;
932
- this.activeChannelSubject.next(this.activeChannel);
933
- });
934
- }));
935
- this.activeChannelSubscriptions.push(channel.on('typing.start', (e) => this.ngZone.run(() => this.handleTypingStartEvent(e))));
936
- this.activeChannelSubscriptions.push(channel.on('typing.stop', (e) => this.ngZone.run(() => this.handleTypingStopEvent(e))));
937
- }
938
- /**
939
- * Call this method if user started typing in the active channel
940
- * @param parentId The id of the parent message, if user is typing in a thread
941
- */
942
- typingStarted(parentId) {
943
- return __awaiter(this, void 0, void 0, function* () {
944
- const activeChannel = this.activeChannelSubject.getValue();
945
- yield (activeChannel === null || activeChannel === void 0 ? void 0 : activeChannel.keystroke(parentId));
946
- });
947
- }
948
- /**
949
- * Call this method if user stopped typing in the active channel
950
- * @param parentId The id of the parent message, if user were typing in a thread
951
- */
952
- typingStopped(parentId) {
953
- return __awaiter(this, void 0, void 0, function* () {
954
- const activeChannel = this.activeChannelSubject.getValue();
955
- yield (activeChannel === null || activeChannel === void 0 ? void 0 : activeChannel.stopTyping(parentId));
956
- });
957
- }
958
- /**
959
- * The current list of channels
960
- */
961
- get channels() {
962
- return this.channelsSubject.getValue() || [];
963
- }
964
- /**
965
- * The current active channel
966
- */
967
- get activeChannel() {
968
- return this.activeChannelSubject.getValue() || undefined;
969
- }
970
- /**
971
- * The current active channel messages
972
- */
973
- get activeChannelMessages() {
974
- return this.activeChannelMessagesSubject.getValue() || [];
975
- }
976
- /**
977
- * Get the last 1200 reactions of a message in the current active channel. If you need to fetch more reactions please use the [following endpoint](https://getstream.io/chat/docs/javascript/send_reaction/?language=javascript#paginating-reactions).
978
- * @param messageId
979
- * @returns all reactions of a message
980
- */
981
- getMessageReactions(messageId) {
982
- var _a, _b;
983
- return __awaiter(this, void 0, void 0, function* () {
984
- const reactions = [];
985
- const limit = 300;
986
- let offset = 0;
987
- const reactionsLimit = ChannelService.MAX_MESSAGE_REACTIONS_TO_FETCH;
988
- let lastPageSize = limit;
989
- while (lastPageSize === limit && reactions.length < reactionsLimit) {
990
- try {
991
- const response = yield ((_a = this.activeChannel) === null || _a === void 0 ? void 0 : _a.getReactions(messageId, {
992
- offset,
993
- limit,
994
- }));
995
- lastPageSize = ((_b = response === null || response === void 0 ? void 0 : response.reactions) === null || _b === void 0 ? void 0 : _b.length) || 0;
996
- if (lastPageSize > 0) {
997
- reactions.push(...response.reactions);
998
- }
999
- offset += lastPageSize;
1000
- }
1001
- catch (e) {
1002
- this.notificationService.addTemporaryNotification('streamChat.Error loading reactions');
1003
- throw e;
1004
- }
1005
- }
1006
- return reactions;
1007
- });
1008
- }
1009
- /**
1010
- * Marks the channel from the given message as unread
1011
- * @param messageId
1012
- * @returns the result of the request
1013
- */
1014
- markMessageUnread(messageId) {
1015
- var _a, _b, _c, _d;
1016
- return __awaiter(this, void 0, void 0, function* () {
1017
- if (!this.activeChannel) {
1018
- return;
1019
- }
1020
- try {
1021
- const response = yield this.activeChannel.markUnread({
1022
- message_id: messageId,
1023
- });
1024
- this.areReadEventsPaused = true;
1025
- return response;
1026
- }
1027
- catch (e) {
1028
- const error = JSON.parse(JSON.stringify(e));
1029
- const data = (_a = error === null || error === void 0 ? void 0 : error.response) === null || _a === void 0 ? void 0 : _a.data;
1030
- if (data &&
1031
- data.code === 4 &&
1032
- data.StatusCode === 400 &&
1033
- ((_b = data.message) === null || _b === void 0 ? void 0 : _b.includes('it is older than last'))) {
1034
- const count = (_d = (_c = /\d+ channel messages/
1035
- .exec(data.message)) === null || _c === void 0 ? void 0 : _c[0].match(/\d+/)) === null || _d === void 0 ? void 0 : _d[0];
1036
- if (count) {
1037
- this.notificationService.addTemporaryNotification('streamChat.Error, only the first {{count}} message can be marked as unread', undefined, undefined, { count });
1038
- throw e;
1039
- }
1040
- }
1041
- this.notificationService.addTemporaryNotification('streamChat.Error marking message as unread');
1042
- throw e;
1043
- }
1044
- });
1045
- }
1046
- messageUpdated(event) {
1047
- this.ngZone.run(() => {
1048
- var _a;
1049
- const isThreadReply = event.message && event.message.parent_id;
1050
- const channel = this.activeChannelSubject.getValue();
1051
- if (!channel) {
1052
- return;
1053
- }
1054
- // Get messages from state as message order could change, and message could've been deleted
1055
- const messages = isThreadReply
1056
- ? channel.state.threads[((_a = event === null || event === void 0 ? void 0 : event.message) === null || _a === void 0 ? void 0 : _a.parent_id) || '']
1057
- : channel.state.messages;
1058
- if (!messages) {
1059
- return;
1060
- }
1061
- const messageIndex = messages.findIndex((m) => { var _a; return m.id === ((_a = event === null || event === void 0 ? void 0 : event.message) === null || _a === void 0 ? void 0 : _a.id); });
1062
- if (messageIndex !== -1) {
1063
- isThreadReply
1064
- ? this.activeThreadMessagesSubject.next([...messages])
1065
- : this.activeChannelMessagesSubject.next([...messages]);
1066
- this.activeChannelPinnedMessagesSubject.next([
1067
- ...channel.state.pinnedMessages,
1068
- ]);
1069
- }
1070
- });
1071
- }
1072
- messageReactionEventReceived(e) {
1073
- this.ngZone.run(() => {
1074
- var _a, _b, _c, _d;
1075
- const isThreadMessage = e.message && e.message.parent_id;
1076
- let messages;
1077
- (isThreadMessage
1078
- ? this.activeThreadMessages$
1079
- : this.activeChannelMessages$)
1080
- .pipe(first())
1081
- .subscribe((m) => (messages = m));
1082
- const messageIndex = messages.findIndex((m) => { var _a; return m.id === ((_a = e === null || e === void 0 ? void 0 : e.message) === null || _a === void 0 ? void 0 : _a.id); });
1083
- if (messageIndex === -1) {
1084
- return;
1085
- }
1086
- const message = messages[messageIndex];
1087
- message.reaction_counts = Object.assign({}, (_a = e.message) === null || _a === void 0 ? void 0 : _a.reaction_counts);
1088
- message.reaction_scores = Object.assign({}, (_b = e.message) === null || _b === void 0 ? void 0 : _b.reaction_scores);
1089
- message.latest_reactions = [...(((_c = e.message) === null || _c === void 0 ? void 0 : _c.latest_reactions) || [])];
1090
- message.own_reactions = [...(((_d = e.message) === null || _d === void 0 ? void 0 : _d.own_reactions) || [])];
1091
- messages[messageIndex] = Object.assign({}, message);
1092
- isThreadMessage
1093
- ? this.activeThreadMessagesSubject.next([...messages])
1094
- : this.activeChannelMessagesSubject.next([...messages]);
1095
- });
1096
- }
1097
- formatMessage(message) {
1098
- const m = message;
1099
- m.pinned_at = message.pinned_at ? new Date(message.pinned_at) : null;
1100
- m.created_at = message.created_at
1101
- ? new Date(message.created_at)
1102
- : new Date();
1103
- m.updated_at = message.updated_at
1104
- ? new Date(message.updated_at)
1105
- : new Date();
1106
- message.status = message.status || 'received';
1107
- return m;
1108
- }
1109
- isStreamMessage(message) {
1110
- return !!message.readBy;
1111
- }
1112
- isFormatMessageResponse(message) {
1113
- return message.created_at instanceof Date;
1114
- }
1115
- stopWatchForActiveChannelEvents(channel) {
1116
- if (!channel) {
1117
- return;
1118
- }
1119
- this.activeChannelSubscriptions.forEach((s) => s.unsubscribe());
1120
- this.activeChannelSubscriptions = [];
1121
- }
1122
- queryChannels(shouldSetActiveChannel, recoverState = false) {
1123
- var _a, _b;
1124
- return __awaiter(this, void 0, void 0, function* () {
1125
- try {
1126
- this.channelQueryStateSubject.next({ state: 'in-progress' });
1127
- let filters;
1128
- let options;
1129
- if (this.nextPageConfiguration) {
1130
- if (this.nextPageConfiguration.type === 'filter') {
1131
- filters = Object.assign(Object.assign({}, this.filters), this.nextPageConfiguration.paginationFilter);
1132
- options = this.options;
1133
- }
1134
- else {
1135
- options = Object.assign(Object.assign({}, this.options), { offset: this.nextPageConfiguration.offset });
1136
- filters = this.filters;
1137
- }
1138
- }
1139
- else {
1140
- filters = this.filters;
1141
- options = this.options;
1142
- }
1143
- const channels = yield this.chatClientService.chatClient.queryChannels(filters, this.sort || {}, options);
1144
- this.setNextPageConfiguration(channels);
1145
- channels.forEach((c) => this.watchForChannelEvents(c));
1146
- const prevChannels = recoverState
1147
- ? []
1148
- : this.channelsSubject.getValue() || [];
1149
- const filteredChannels = channels.filter((channel) => !prevChannels.find((existingChannel) => existingChannel.cid === channel.cid));
1150
- let currentActiveChannel = this.activeChannelSubject.getValue();
1151
- let isCurrentActiveChannelDeselected = false;
1152
- const nextChannels = [...prevChannels, ...filteredChannels];
1153
- if (recoverState &&
1154
- currentActiveChannel &&
1155
- !filteredChannels.find((c) => c.cid === (currentActiveChannel === null || currentActiveChannel === void 0 ? void 0 : currentActiveChannel.cid))) {
1156
- try {
1157
- yield currentActiveChannel.watch();
1158
- nextChannels.unshift(currentActiveChannel);
1159
- }
1160
- catch (e) {
1161
- isCurrentActiveChannelDeselected = true;
1162
- }
1163
- }
1164
- this.channelsSubject.next(nextChannels);
1165
- if (isCurrentActiveChannelDeselected) {
1166
- this.deselectActiveChannel();
1167
- }
1168
- if (filteredChannels.length > 0 &&
1169
- !currentActiveChannel &&
1170
- shouldSetActiveChannel) {
1171
- this.setAsActiveChannel(filteredChannels[0]);
1172
- currentActiveChannel = this.activeChannelSubject.getValue();
1173
- }
1174
- this.hasMoreChannelsSubject.next(channels.length >= this.options.limit);
1175
- this.channelQueryStateSubject.next({ state: 'success' });
1176
- if (((_a = this.options) === null || _a === void 0 ? void 0 : _a.keepAliveChannels$OnError) &&
1177
- this.dismissErrorNotification) {
1178
- this.dismissErrorNotification();
1179
- }
1180
- return channels;
1181
- }
1182
- catch (error) {
1183
- if (!((_b = this.options) === null || _b === void 0 ? void 0 : _b.keepAliveChannels$OnError)) {
1184
- this.channelsSubject.error(error);
1185
- }
1186
- this.channelQueryStateSubject.next({
1187
- state: 'error',
1188
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
1189
- error,
1190
- });
1191
- throw error;
1192
- }
1193
- });
1194
- }
1195
- watchForChannelEvents(channel) {
1196
- const unsubscribe = channel.on((event) => {
1197
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
1198
- const type = event.type;
1199
- switch (type) {
1200
- case 'message.new': {
1201
- this.ngZone.run(() => {
1202
- if (this.customNewMessageHandler) {
1203
- this.customNewMessageHandler(event, channel, this.channelListSetter, this.messageListSetter, this.threadListSetter, this.parentMessageSetter);
1204
- }
1205
- else {
1206
- this.handleNewMessage(event, channel);
1207
- }
1208
- });
1209
- break;
1210
- }
1211
- case 'channel.hidden': {
1212
- this.ngZone.run(() => {
1213
- if (this.customChannelHiddenHandler) {
1214
- this.customChannelHiddenHandler(event, channel, this.channelListSetter, this.messageListSetter, this.threadListSetter, this.parentMessageSetter);
1215
- }
1216
- else {
1217
- this.handleChannelHidden(event);
1218
- }
1219
- });
1220
- break;
1221
- }
1222
- case 'channel.deleted': {
1223
- this.ngZone.run(() => {
1224
- if (this.customChannelDeletedHandler) {
1225
- this.customChannelDeletedHandler(event, channel, this.channelListSetter, this.messageListSetter, this.threadListSetter, this.parentMessageSetter);
1226
- }
1227
- else {
1228
- this.handleChannelDeleted(event);
1229
- }
1230
- });
1231
- break;
1232
- }
1233
- case 'channel.visible': {
1234
- this.ngZone.run(() => {
1235
- if (this.customChannelVisibleHandler) {
1236
- this.customChannelVisibleHandler(event, channel, this.channelListSetter, this.messageListSetter, this.threadListSetter, this.parentMessageSetter);
1237
- }
1238
- else {
1239
- this.handleChannelVisible(event, channel);
1240
- }
1241
- });
1242
- break;
1243
- }
1244
- case 'channel.updated': {
1245
- this.ngZone.run(() => {
1246
- if (this.customChannelUpdatedHandler) {
1247
- this.customChannelUpdatedHandler(event, channel, this.channelListSetter, this.messageListSetter, this.threadListSetter, this.parentMessageSetter);
1248
- }
1249
- else {
1250
- this.handleChannelUpdate(event);
1251
- }
1252
- });
1253
- break;
1254
- }
1255
- case 'channel.truncated': {
1256
- this.ngZone.run(() => {
1257
- if (this.customChannelTruncatedHandler) {
1258
- this.customChannelTruncatedHandler(event, channel, this.channelListSetter, this.messageListSetter, this.threadListSetter, this.parentMessageSetter);
1259
- }
1260
- else {
1261
- this.handleChannelTruncate(event);
1262
- }
1263
- });
1264
- break;
1265
- }
1266
- case 'capabilities.changed': {
1267
- this.ngZone.run(() => {
1268
- var _a;
1269
- const cid = event.cid;
1270
- if (cid) {
1271
- const currentChannels = this.channelsSubject.getValue();
1272
- const index = currentChannels === null || currentChannels === void 0 ? void 0 : currentChannels.findIndex((c) => c.cid === cid);
1273
- if (index !== -1 && index !== undefined) {
1274
- this.channelsSubject.next([...currentChannels]);
1275
- if (cid === ((_a = this.activeChannelSubject.getValue()) === null || _a === void 0 ? void 0 : _a.cid)) {
1276
- this.activeChannelSubject.next(this.activeChannelSubject.getValue());
1277
- }
1278
- }
1279
- }
1280
- });
1281
- break;
1282
- }
1283
- }
1284
- });
1285
- this.channelSubscriptions[channel.cid] = unsubscribe.unsubscribe;
1286
- }
1287
- handleNewMessage(_, channel) {
1288
- const channelIndex = this.channels.findIndex((c) => c.cid === channel.cid);
1289
- this.channels.splice(channelIndex, 1);
1290
- this.channelsSubject.next([channel, ...this.channels]);
1291
- }
1292
- handleChannelHidden(event) {
1293
- this.removeChannelsFromChannelList([event.channel.cid], false);
1294
- }
1295
- handleChannelDeleted(event) {
1296
- this.removeChannelsFromChannelList([event.channel.cid], false);
1297
- }
1298
- handleChannelVisible(event, channel) {
1299
- if (!this.channels.find((c) => c.cid === event.cid)) {
1300
- this.ngZone.run(() => this.channelsSubject.next([...this.channels, channel]));
1301
- }
1302
- }
1303
- handleChannelUpdate(event) {
1304
- var _a, _b, _c, _d;
1305
- const channelIndex = this.channels.findIndex((c) => c.cid === event.channel.cid);
1306
- if (channelIndex !== -1) {
1307
- const channel = this.channels[channelIndex];
1308
- const notIncludedProperies = {
1309
- hidden: ((_a = channel.data) === null || _a === void 0 ? void 0 : _a.hidden) || false,
1310
- own_capabilities: ((_b = channel.data) === null || _b === void 0 ? void 0 : _b.own_capabilities) || [],
1311
- };
1312
- channel.data = Object.assign(Object.assign({}, event.channel), notIncludedProperies);
1313
- this.channelsSubject.next([...this.channels]);
1314
- if (((_c = event.channel) === null || _c === void 0 ? void 0 : _c.cid) === ((_d = this.activeChannelSubject.getValue()) === null || _d === void 0 ? void 0 : _d.cid)) {
1315
- this.activeChannelSubject.next(channel);
1316
- }
1317
- }
1318
- }
1319
- handleChannelTruncate(event) {
1320
- var _a, _b;
1321
- const channelIndex = this.channels.findIndex((c) => c.cid === event.channel.cid);
1322
- if (channelIndex !== -1) {
1323
- this.channels[channelIndex].state.messages = [];
1324
- this.channelsSubject.next([...this.channels]);
1325
- if (((_a = event.channel) === null || _a === void 0 ? void 0 : _a.cid) === ((_b = this.activeChannelSubject.getValue()) === null || _b === void 0 ? void 0 : _b.cid)) {
1326
- const channel = this.activeChannelSubject.getValue();
1327
- channel.state.messages = [];
1328
- this.activeChannelSubject.next(channel);
1329
- this.activeChannelMessagesSubject.next([]);
1330
- this.activeParentMessageIdSubject.next(undefined);
1331
- this.activeThreadMessagesSubject.next([]);
1332
- }
1333
- }
1334
- }
1335
- get canSendReadEvents() {
1336
- var _a;
1337
- const channel = this.activeChannelSubject.getValue();
1338
- if (!channel) {
1339
- return false;
1340
- }
1341
- const capabilites = (_a = channel.data) === null || _a === void 0 ? void 0 : _a.own_capabilities;
1342
- return capabilites.indexOf('read-events') !== -1;
1343
- }
1344
- transformToStreamMessage(message, channel) {
1345
- const isThreadMessage = !!message.parent_id;
1346
- if (this.isStreamMessage(message) &&
1347
- this.isFormatMessageResponse(message)) {
1348
- if (message.quoted_message) {
1349
- message.quoted_message.translation = getMessageTranslation(message.quoted_message, channel, this.chatClientService.chatClient.user);
1350
- }
1351
- message.translation = getMessageTranslation(message, channel, this.chatClientService.chatClient.user);
1352
- return message;
1353
- }
1354
- else {
1355
- if (message.quoted_message) {
1356
- message.quoted_message.translation = getMessageTranslation(message.quoted_message, channel, this.chatClientService.chatClient.user);
1357
- }
1358
- if (this.isFormatMessageResponse(message)) {
1359
- message.readBy = isThreadMessage
1360
- ? []
1361
- : channel
1362
- ? getReadBy(message, channel)
1363
- : [];
1364
- message.translation = getMessageTranslation(message, channel, this.chatClientService.chatClient.user);
1365
- return message;
1366
- }
1367
- else {
1368
- message = this.formatMessage(message);
1369
- message.readBy = isThreadMessage
1370
- ? []
1371
- : channel
1372
- ? getReadBy(message, channel)
1373
- : [];
1374
- message.translation = getMessageTranslation(message, channel, this.chatClientService.chatClient.user);
1375
- return message;
1376
- }
1377
- }
1378
- }
1379
- handleTypingStartEvent(event) {
1380
- var _a, _b;
1381
- if (((_a = event.user) === null || _a === void 0 ? void 0 : _a.id) === ((_b = this.chatClientService.chatClient.user) === null || _b === void 0 ? void 0 : _b.id)) {
1382
- return;
1383
- }
1384
- const isTypingInThread = !!event.parent_id;
1385
- if (isTypingInThread &&
1386
- event.parent_id !== this.activeParentMessageIdSubject.getValue()) {
1387
- return;
1388
- }
1389
- const subject = isTypingInThread
1390
- ? this.usersTypingInThreadSubject
1391
- : this.usersTypingInChannelSubject;
1392
- const users = subject.getValue();
1393
- const user = event.user;
1394
- if (user && !users.find((u) => u.id === user.id)) {
1395
- users.push(user);
1396
- subject.next([...users]);
1397
- }
1398
- }
1399
- handleTypingStopEvent(event) {
1400
- const usersTypingInChannel = this.usersTypingInChannelSubject.getValue();
1401
- const usersTypingInThread = this.usersTypingInThreadSubject.getValue();
1402
- const user = event.user;
1403
- if (user && usersTypingInChannel.find((u) => u.id === user.id)) {
1404
- usersTypingInChannel.splice(usersTypingInChannel.findIndex((u) => u.id === user.id), 1);
1405
- this.usersTypingInChannelSubject.next([...usersTypingInChannel]);
1406
- return;
1407
- }
1408
- if (user && usersTypingInThread.find((u) => u.id === user.id)) {
1409
- usersTypingInThread.splice(usersTypingInThread.findIndex((u) => u.id === user.id), 1);
1410
- this.usersTypingInThreadSubject.next([...usersTypingInThread]);
1411
- return;
1412
- }
1413
- }
1414
- updateLatestMessages(event) {
1415
- var _a, _b, _c, _d, _e, _f, _g;
1416
- if (((_b = (_a = event.message) === null || _a === void 0 ? void 0 : _a.user) === null || _b === void 0 ? void 0 : _b.id) !== ((_d = (_c = this.chatClientService) === null || _c === void 0 ? void 0 : _c.chatClient.user) === null || _d === void 0 ? void 0 : _d.id)) {
1417
- return;
1418
- }
1419
- const latestMessages = this.latestMessageDateByUserByChannelsSubject.getValue();
1420
- if (!((_e = event.message) === null || _e === void 0 ? void 0 : _e.created_at)) {
1421
- return;
1422
- }
1423
- const channelId = (_f = event === null || event === void 0 ? void 0 : event.message) === null || _f === void 0 ? void 0 : _f.cid;
1424
- if (!channelId) {
1425
- return;
1426
- }
1427
- const messageDate = new Date(event.message.created_at);
1428
- if (!latestMessages[channelId] ||
1429
- ((_g = latestMessages[channelId]) === null || _g === void 0 ? void 0 : _g.getTime()) < messageDate.getTime()) {
1430
- latestMessages[channelId] = messageDate;
1431
- this.latestMessageDateByUserByChannelsSubject.next(Object.assign({}, latestMessages));
1432
- }
1433
- }
1434
- setChannelState(channel) {
1435
- channel.state.messages.forEach((m) => {
1436
- m.readBy = getReadBy(m, channel);
1437
- m.translation = getMessageTranslation(m, channel, this.chatClientService.chatClient.user);
1438
- if (m.quoted_message) {
1439
- m.quoted_message.translation = getMessageTranslation(m.quoted_message, channel, this.chatClientService.chatClient.user);
1440
- }
1441
- });
1442
- this.markRead(channel);
1443
- this.activeChannelMessagesSubject.next([...channel.state.messages]);
1444
- this.activeChannelPinnedMessagesSubject.next([
1445
- ...channel.state.pinnedMessages,
1446
- ]);
1447
- this.activeParentMessageIdSubject.next(undefined);
1448
- this.activeThreadMessagesSubject.next([]);
1449
- this.messageToQuoteSubject.next(undefined);
1450
- this.usersTypingInChannelSubject.next([]);
1451
- this.usersTypingInThreadSubject.next([]);
1452
- }
1453
- markRead(channel) {
1454
- if (this.canSendReadEvents &&
1455
- this.shouldMarkActiveChannelAsRead &&
1456
- !this.areReadEventsPaused) {
1457
- void channel.markRead();
1458
- }
1459
- }
1460
- setNextPageConfiguration(channelQueryResult) {
1461
- var _a;
1462
- if (this.customPaginator) {
1463
- this.nextPageConfiguration = this.customPaginator(channelQueryResult);
1464
- }
1465
- else {
1466
- this.nextPageConfiguration = {
1467
- type: 'offset',
1468
- offset: (((_a = this.nextPageConfiguration) === null || _a === void 0 ? void 0 : _a.type) === 'offset'
1469
- ? this.nextPageConfiguration.offset
1470
- : 0) + channelQueryResult.length,
1471
- };
1472
- }
1473
- }
1474
- }
1475
- /**
1476
- * internal
1477
- */
1478
- ChannelService.MAX_MESSAGE_REACTIONS_TO_FETCH = 1200;
1479
- ChannelService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: ChannelService, deps: [{ token: i1.ChatClientService }, { token: i0.NgZone }, { token: i2.NotificationService }], target: i0.ɵɵFactoryTarget.Injectable });
1480
- ChannelService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: ChannelService, providedIn: 'root' });
1481
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: ChannelService, decorators: [{
1482
- type: Injectable,
1483
- args: [{
1484
- providedIn: 'root',
1485
- }]
1486
- }], ctorParameters: function () { return [{ type: i1.ChatClientService }, { type: i0.NgZone }, { type: i2.NotificationService }]; } });
1487
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2hhbm5lbC5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcHJvamVjdHMvc3RyZWFtLWNoYXQtYW5ndWxhci9zcmMvbGliL2NoYW5uZWwuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsT0FBTyxFQUFFLFVBQVUsRUFBVSxNQUFNLGVBQWUsQ0FBQztBQUNuRCxPQUFPLEVBQ0wsZUFBZSxFQUNmLGFBQWEsRUFFYixhQUFhLEdBRWQsTUFBTSxNQUFNLENBQUM7QUFDZCxPQUFPLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxHQUFHLEVBQUUsV0FBVyxFQUFFLElBQUksRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBbUJ2RSxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUNsRSxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUV6RCxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sV0FBVyxDQUFDOzs7O0FBWXRDOztHQUVHO0FBSUgsTUFBTSxPQUFPLGNBQWM7SUF3V3pCLFlBQ1UsaUJBQXVDLEVBQ3ZDLE1BQWMsRUFDZCxtQkFBd0M7UUFGeEMsc0JBQWlCLEdBQWpCLGlCQUFpQixDQUFzQjtRQUN2QyxXQUFNLEdBQU4sTUFBTSxDQUFRO1FBQ2Qsd0JBQW1CLEdBQW5CLG1CQUFtQixDQUFxQjtRQXZGMUMsb0JBQWUsR0FBRyxJQUFJLGVBQWUsQ0FDM0MsU0FBUyxDQUNWLENBQUM7UUFDTSx5QkFBb0IsR0FBRyxJQUFJLGVBQWUsQ0FDaEQsU0FBUyxDQUNWLENBQUM7UUFDTSxpQ0FBNEIsR0FBRyxJQUFJLGVBQWUsQ0FFeEQsRUFBRSxDQUFDLENBQUM7UUFDRSx1Q0FBa0MsR0FBRyxJQUFJLGVBQWUsQ0FFOUQsRUFBRSxDQUFDLENBQUM7UUFDRSwyQkFBc0IsR0FBRyxJQUFJLGFBQWEsQ0FBVSxDQUFDLENBQUMsQ0FBQztRQUN2RCwrQkFBMEIsR0FB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QUFkLGNBQWMsY0FGYixNQUFNOzJGQUVQLGNBQWM7a0JBSDFCLFVBQVU7bUJBQUM7b0JBQ1YsVUFBVSxFQUFFLE1BQU07aUJBQ25CIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSwgTmdab25lIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQge1xuICBCZWhhdmlvclN1YmplY3QsXG4gIGNvbWJpbmVMYXRlc3QsXG4gIE9ic2VydmFibGUsXG4gIFJlcGxheVN1YmplY3QsXG4gIFN1YnNjcmlwdGlvbixcbn0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBmaWx0ZXIsIGZpcnN0LCBtYXAsIHNoYXJlUmVwbGF5LCB0YWtlIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHtcbiAgQXR0YWNobWVudCxcbiAgQ2hhbm5lbCxcbiAgQ2hhbm5lbEZpbHRlcnMsXG4gIENoYW5uZWxPcHRpb25zLFxuICBDaGFubmVsUmVzcG9uc2UsXG4gIENoYW5uZWxTb3J0LFxuICBFdmVudCxcbiAgRXZlbnRUeXBlcyxcbiAgRm9ybWF0TWVzc2FnZVJlc3BvbnNlLFxuICBNZXNzYWdlLFxuICBNZXNzYWdlUmVzcG9uc2UsXG4gIFJlYWN0aW9uUmVzcG9uc2UsXG4gIFVwZGF0ZWRNZXNzYWdlLFxuICBVc2VyRmlsdGVycyxcbiAgVXNlclJlc3BvbnNlLFxufSBmcm9tICdzdHJlYW0tY2hhdCc7XG5pbXBvcnQgeyBDaGF0Q2xpZW50U2VydmljZSwgQ2xpZW50RXZlbnQgfSBmcm9tICcuL2NoYXQtY2xpZW50LnNlcnZpY2UnO1xuaW1wb3J0IHsgZ2V0TWVzc2FnZVRyYW5zbGF0aW9uIH0gZnJvbSAnLi9nZXQtbWVzc2FnZS10cmFuc2xhdGlvbic7XG5pbXBvcnQgeyBjcmVhdGVNZXNzYWdlUHJldmlldyB9IGZyb20gJy4vbWVzc2FnZS1wcmV2aWV3JztcbmltcG9ydCB7IE5vdGlmaWNhdGlvblNlcnZpY2UgfSBmcm9tICcuL25vdGlmaWNhdGlvbi5zZXJ2aWNlJztcbmltcG9ydCB7IGdldFJlYWRCeSB9IGZyb20gJy4vcmVhZC1ieSc7XG5pbXBvcnQge1xuICBBdHRhY2htZW50VXBsb2FkLFxuICBBdHRhY2htZW50VXBsb2FkRXJyb3JSZWFzb24sXG4gIENoYW5uZWxRdWVyeVN0YXRlLFxuICBEZWZhdWx0U3RyZWFtQ2hhdEdlbmVyaWNzLFxuICBNZXNzYWdlSW5wdXQsXG4gIE1lc3NhZ2VSZWFjdGlvblR5cGUsXG4gIE5leHRQYWdlQ29uZmlndXJhdGlvbixcbiAgU3RyZWFtTWVzc2FnZSxcbn0gZnJvbSAnLi90eXBlcyc7XG5cbi8qKlxuICogVGhlIGBDaGFubmVsU2VydmljZWAgcHJvdmlkZXMgZGF0YSBhbmQgaW50ZXJhY3Rpb24gZm9yIHRoZSBjaGFubmVsIGxpc3QgYW5kIG1lc3NhZ2UgbGlzdC5cbiAqL1xuQEluamVjdGFibGUoe1xuICBwcm92aWRlZEluOiAncm9vdCcsXG59KVxuZXhwb3J0IGNsYXNzIENoYW5uZWxTZXJ2aWNlPFxuICBUIGV4dGVuZHMgRGVmYXVsdFN0cmVhbUNoYXRHZW5lcmljcyA9IERlZmF1bHRTdHJlYW1DaGF0R2VuZXJpY3Ncbj4ge1xuICAvKipcbiAgICogRW1pdHMgYGZhbHNlYCBpZiB0aGVyZSBhcmUgbm8gbW9yZSBwYWdlcyBvZiBjaGFubmVscyB0aGF0IGNhbiBiZSBsb2FkZWQuXG4gICAqL1xuICBoYXNNb3JlQ2hhbm5lbHMkOiBPYnNlcnZhYmxlPGJvb2xlYW4+O1xuICAvKipcbiAgICogRW1pdHMgdGhlIGN1cnJlbnRseSBsb2FkZWQgYW5kIFt3YXRjaGVkXShodHRwczovL2dldHN0cmVhbS5pby9jaGF0L2RvY3MvamF2YXNjcmlwdC93YXRjaF9jaGFubmVsLz9sYW5ndWFnZT1qYXZhc2NyaXB0KSBjaGFubmVsIGxpc3QuXG4gICAqXG4gICAqIDo6OmltcG9ydGFudFxuICAgKiBJZiB5b3Ugd2FudCB0byBzdWJzY3JpYmUgdG8gY2hhbm5lbCBldmVudHMsIHlvdSBuZWVkIHRvIG1hbnVhbGx5IHJlZW50ZXIgQW5ndWxhcidzIGNoYW5nZSBkZXRlY3Rpb24gem9uZSwgb3VyIFtDaGFuZ2UgZGV0ZWN0aW9uIGd1aWRlXSguLi9jb25jZXB0cy9jaGFuZ2UtZGV0ZWN0aW9uLm1keCkgZXhwbGFpbnMgdGhpcyBpbiBkZXRhaWwuXG4gICAqIDo6OlxuICAgKlxuICAgKiAgQXBhcnQgZnJvbSBwYWdpbmF0aW9uLCB0aGUgY2hhbm5lbCBsaXN0IGlzIGFsc28gdXBkYXRlZCBvbiB0aGUgZm9sbG93aW5nIGV2ZW50czpcbiAgICpcbiAgICogIHwgRXZlbnQgdHlwZSAgICAgICAgICAgICAgICAgICAgICAgICAgfCBEZWZhdWx0IGJlaGF2aW9yICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBDdXN0b20gaGFuZGxlciB0byBvdmVycmlkZSAgICAgICAgICAgICAgICAgICAgfFxuICAgKiAgfCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSB8IC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSB8IC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSB8XG4gICAqICB8IGBjaGFubmVsLmRlbGV0ZWRgICAgICAgICAgICAgICAgICAgIHwgUmVtb3ZlIGNoYW5uZWwgZnJvbSB0aGUgbGlzdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgYGN1c3RvbUNoYW5uZWxEZWxldGVkSGFuZGxlcmAgICAgICAgICAgICAgICAgIHxcbiAgICogIHwgYGNoYW5uZWwuaGlkZGVuYCAgICAgICAgICAgICAgICAgICAgfCBSZW1vdmUgY2hhbm5lbCBmcm9tIHRoZSBsaXN0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBgY3VzdG9tQ2hhbm5lbEhpZGRlbkhhbmRsZXJgICAgICAgICAgICAgICAgICAgfFxuICAgKiAgfCBgY2hhbm5lbC50cnVuY2F0ZWRgICAgICAgICAgICAgICAgICB8IFVwZGF0ZXMgdGhlIGNoYW5uZWwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IGBjdXN0b21DaGFubmVsVHJ1bmNhdGVkSGFuZGxlcmAgICAgICAgICAgICAgICB8XG4gICAqICB8IGBjaGFubmVsLnVwZGF0ZWRgICAgICAgICAgICAgICAgICAgIHwgVXBkYXRlcyB0aGUgY2hhbm5lbCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgYGN1c3RvbUNoYW5uZWxVcGRhdGVkSGFuZGxlcmAgICAgICAgICAgICAgICAgIHxcbiAgICogIHwgYGNoYW5uZWwudmlzaWJsZWAgICAgICAgICAgICAgICAgICAgfCBBZGRzIHRoZSBjaGFubmVsIHRvIHRoZSBsaXN0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBgY3VzdG9tQ2hhbm5lbFZpc2libGVIYW5kbGVyYCAgICAgICAgICAgICAgICAgfFxuICAgKiAgfCBgbWVzc2FnZS5uZXdgICAgICAgICAgICAgICAgICAgICAgICB8IE1vdmVzIHRoZSBjaGFubmVsIHRvIHRvcCBvZiB0aGUgbGlzdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IGBjdXN0b21OZXdNZXNzYWdlSGFuZGxlcmAgICAgICAgICAgICAgICAgICAgICB8XG4gICAqICB8IGBub3RpZmljYXRpb24uYWRkZWRfdG9fY2hhbm5lbGAgICAgIHwgQWRkcyB0aGUgbmV3IGNoYW5uZWwgdG8gdGhlIHRvcCBvZiB0aGUgbGlzdCBhbmQgc3RhcnRzIHdhdGNoaW5nIGl0IHwgYGN1c3RvbUFkZGVkVG9DaGFubmVsTm90aWZpY2F0aW9uSGFuZGxlcmAgICAgIHxcbiAgICogIHwgYG5vdGlmaWNhdGlvbi5tZXNzYWdlX25ld2AgICAgICAgICAgfCBBZGRzIHRoZSBuZXcgY2hhbm5lbCB0byB0aGUgdG9wIG9mIHRoZSBsaXN0IGFuZCBzdGFydHMgd2F0Y2hpbmcgaXQgfCBgY3VzdG9tTmV3TWVzc2FnZU5vdGlmaWNhdGlvbkhhbmRsZXJgICAgICAgICAgfFxuICAgKiAgfCBgbm90aWZpY2F0aW9uLnJlbW92ZWRfZnJvbV9jaGFubmVsYCB8IFJlbW92ZXMgdGhlIGNoYW5uZWwgZnJvbSB0aGUgbGlzdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IGBjdXN0b21SZW1vdmVkRnJvbUNoYW5uZWxOb3RpZmljYXRpb25IYW5kbGVyYCB8XG4gICAqXG4gICAqICBJdCdzIGltcG9ydGFudCB0byBub3RlIHRoYXQgZmlsdGVycyBkb24ndCBhcHBseSB0byB1cGRhdGVzIHRvIHRoZSBsaXN0IGZyb20gZXZlbnRzLlxuICAgKlxuICAgKiAgT3VyIHBsYXRmb3JtIGRvY3VtZW50YXRpb24gY292ZXJzIHRoZSB0b3BpYyBvZiBbY2hhbm5lbCBldmVudHNdKGh0dHBzOi8vZ2V0c3RyZWFtLmlvL2NoYXQvZG9jcy9qYXZhc2NyaXB0L2V2ZW50X29iamVjdC8/bGFuZ3VhZ2U9amF2YXNjcmlwdCNldmVudHMpIGluIGRlcHRoLlxuICAgKlxuICAgKiAgQnkgZGVmYXVsdCBpZiBhbiBlcnJvciBvY2N1cnMgZHVyaW5nIGNoYW5uZWwgbG9hZCwgdGhlIE9ic2VydmFibGUgd2lsbCBlbWl0IGFuIGVycm9yLCB3aGljaCB3aWxsIGNsb3NlIHRoZSBzdHJlYW0uIFVzZXJzIHdpbGwgaGF2ZSB0byByZWxvYWQgdGhlIHBhZ2UgdG8gYmUgYWJsZSB0byByZWluaXRpYWxpemUgdGhlIGBDaGFubmVsU2VydmljZWAuIElmIHlvdSBkb24ndCB3YW50IHRoZSBzdHJlYW1zIHRvIGJlIGNsb3NlZCwgeW91IGNhbiBwYXNzIGBvcHRpb25zLmtlZXBBbGl2ZUNoYW5uZWxzJE9uRXJyb3IgPSB0cnVlYCB0byB0aGUgYGluaXRgIG1ldGhvZC4gSW4gdGhhdCBjYXNlIHRoZSBgY2hhbm5lbFF1ZXJ5U3RhdGUkYCBzdHJlYW0gd2lsbCBlbWl0IHRoZSBzdGF0dXMgb2YgdGhlIGxhdGVzdCBjaGFubmVsIGxvYWQgcmVxdWVzdC5cbiAgICovXG4gIGNoYW5uZWxzJDogT2JzZXJ2YWJsZTxDaGFubmVsPFQ+W10gfCB1bmRlZmluZWQ+O1xuICAvKipcbiAgICogVGhlIHJlc3VsdCBvZiB0aGUgbGF0ZXN0IGNoYW5uZWwgcXVlcnkgcmVxdWVzdC5cbiAgICovXG4gIGNoYW5uZWxRdWVyeVN0YXRlJDogT2JzZXJ2YWJsZTxDaGFubmVsUXVlcnlTdGF0ZSB8IHVuZGVmaW5lZD47XG4gIC8qKlxuICAgKiBFbWl0cyB0aGUgY3VycmVudGx5IGFjdGl2ZSBjaGFubmVsLlxuICAgKlxuICAgKiA6OjppbXBvcnRhbnRcbiAgICogSWYgeW91IHdhbnQgdG8gc3Vic2NyaWJlIHRvIGNoYW5uZWwgZXZlbnRzLCB5b3UgbmVlZCB0byBtYW51YWxseSByZWVudGVyIEFuZ3VsYXIncyBjaGFuZ2UgZGV0ZWN0aW9uIHpvbmUsIG91ciBbQ2hhbmdlIGRldGVjdGlvbiBndWlkZV0oLi4vY29uY2VwdHMvY2hhbmdlLWRldGVjdGlvbi5tZHgpIGV4cGxhaW5zIHRoaXMgaW4gZGV0YWlsLlxuICAgKiA6OjpcbiAgICpcbiAgICogVGhlIGFjdGl2ZSBjaGFubmVsIHdpbGwgYWx3YXlzIGJlIG1hcmtlZCBhcyByZWFkIHdoZW4gYSBuZXcgbWVzc2FnZSBpcyByZWNlaXZlZFxuICAgKi9cbiAgYWN0aXZlQ2hhbm5lbCQ6IE9ic2VydmFibGU8Q2hhbm5lbDxUPiB8IHVuZGVmaW5lZD47XG4gIC8qKlxuICAgKiBFbWl0cyB0aGUgbGlzdCBvZiBjdXJyZW50bHkgbG9hZGVkIG1lc3NhZ2VzIG9mIHRoZSBhY3RpdmUgY2hhbm5lbC5cbiAgICovXG4gIGFjdGl2ZUNoYW5uZWxNZXNzYWdlcyQ6IE9ic2VydmFibGU8U3RyZWFtTWVzc2FnZTxUPltdPjtcbiAgLyoqXG4gICAqIEVtaXRzIHRoZSBsaXN0IG9mIHBpbm5lZCBtZXNzYWdlcyBvZiB0aGUgYWN0aXZlIGNoYW5uZWwuXG4gICAqL1xuICBhY3RpdmVDaGFubmVsUGlubmVkTWVzc2FnZXMkOiBPYnNlcnZhYmxlPFN0cmVhbU1lc3NhZ2U8VD5bXT47XG4gIC8qKlxuICAgKiBFbWl0cyB0aGUgaWQgb2YgdGhlIGN1cnJlbnRseSBzZWxlY3RlZCBwYXJlbnQgbWVzc2FnZS4gSWYgbm8gbWVzc2FnZSBpcyBzZWxlY3RlZCwgaXQgZW1pdHMgdW5kZWZpbmVkLlxuICAgKi9cbiAgYWN0aXZlUGFyZW50TWVzc2FnZUlkJDogT2JzZXJ2YWJsZTxzdHJpbmcgfCB1bmRlZmluZWQ+O1xuICAvKipcbiAgICogRW1pdHMgdGhlIGxpc3Qgb2YgY3VycmVudGx5IGxvYWRlZCB0aHJlYWQgcmVwbGllcyBiZWxvbmdpbmcgdG8gdGhlIHNlbGVjdGVkIHBhcmVudCBtZXNzYWdlLiBJZiB0aGVyZSBpcyBubyBjdXJyZW50bHkgYWN0aXZlIHRocmVhZCBpdCBlbWl0cyBhbiBlbXB0eSBhcnJheS5cbiAgICovXG4gIGFjdGl2ZVRocmVhZE1lc3NhZ2VzJDogT2JzZXJ2YWJsZTxTdHJlYW1NZXNzYWdlPFQ+W10+O1xuICAvKipcbiAgICogRW1pdHMgdGhlIGN1cnJlbnRseSBzZWxlY3RlZCBwYXJlbnQgbWVzc2FnZS4gSWYgbm8gbWVzc2FnZSBpcyBzZWxlY3RlZCwgaXQgZW1pdHMgdW5kZWZpbmVkLlxuICAgKi9cbiAgYWN0aXZlUGFyZW50TWVzc2FnZSQ6IE9ic2VydmFibGU8U3RyZWFtTWVzc2FnZTxUPiB8IHVuZGVmaW5lZD47XG4gIC8qKlxuICAgKiBFbWl0cyB0aGUgY3VycmVudGx5IHNlbGVjdGVkIG1lc3NhZ2UgdG8gcXVvdGVcbiAgICovXG4gIG1lc3NhZ2VUb1F1b3RlJDogT2JzZXJ2YWJsZTxTdHJlYW1NZXNzYWdlPFQ+IHwgdW5kZWZpbmVkPjtcbiAgLyoqXG4gICAqIEVtaXRzIHRoZSBJRCBvZiB0aGUgbWVzc2FnZSB0aGUgbWVzc2FnZSBsaXN0IHNob3VsZCBqdW1wIHRvIChjYW4gYmUgYSBjaGFubmVsIG1lc3NhZ2Ugb3IgdGhyZWFkIG1lc3NhZ2UpXG4gICAqL1xuICBqdW1wVG9NZXNzYWdlJDogT2JzZXJ2YWJsZTx7IGlkPzogc3RyaW5nOyBwYXJlbnRJZD86IHN0cmluZyB9PjtcbiAgLyoqXG4gICAqIEVtaXRzIHRoZSBsaXN0IG9mIHVzZXJzIHRoYXQgYXJlIGN1cnJlbnRseSB0eXBpbmcgaW4gdGhlIGNoYW5uZWwgKGN1cnJlbnQgdXNlciBpcyBub3QgaW5jbHVkZWQpXG4gICAqL1xuICB1c2Vyc1R5cGluZ0luQ2hhbm5lbCQ6IE9ic2VydmFibGU8VXNlclJlc3BvbnNlPFQ+W10+O1xuICAvKipcbiAgICogRW1pdHMgdGhlIGxpc3Qgb2YgdXNlcnMgdGhhdCBhcmUgY3VycmVudGx5IHR5cGluZyBpbiB0aGUgYWN0aXZlIHRocmVhZCAoY3VycmVudCB1c2VyIGlzIG5vdCBpbmNsdWRlZClcbiAgICovXG4gIHVzZXJzVHlwaW5nSW5UaHJlYWQkOiBPYnNlcnZhYmxlPFVzZXJSZXNwb25zZTxUPltdPjtcbiAgLyoqXG4gICAqIEVtaXRzIGEgbWFwIHRoYXQgY29udGFpbnMgdGhlIGRhdGUgb2YgdGhlIGxhdGVzdCBtZXNzYWdlIHNlbnQgYnkgdGhlIGN1cnJlbnQgdXNlciBieSBjaGFubmVscyAodGhpcyBpcyB1c2VkIHRvIGRldGVjdCBpZiBzbG93IG1vZGUgY291bnRkb3duIHNob3VsZCBiZSBzdGFydGVkKVxuICAgKi9cbiAgbGF0ZXN0TWVzc2FnZURhdGVCeVVzZXJCeUNoYW5uZWxzJDogT2JzZXJ2YWJsZTx7IFtrZXk6IHN0cmluZ106IERhdGUgfT47XG4gIC8qKlxuICAgKiBJZiB5b3UncmUgdXNpbmcgW3NlbWFudGljIGZpbHRlcnMgZm9yIG1vZGVyYXRpb25dKGh0dHBzOi8vZ2V0c3RyZWFtLmlvL2F1dG9tYXRlZC1tb2RlcmF0aW9uL2RvY3MvYXV0b21vZF9jb25maWd1cmF0aW9uLz9xPXNlbWFudGljJTIwZmlsdGVycykgeW91IGNhbiBzZXQgdXAgcnVsZXMgZm9yIGJvdW5jaW5nIG1lc3NhZ2VzLlxuICAgKlxuICAgKiBJZiBhIG1lc3NhZ2UgaXMgYm91bmNlZCwgaXQgd2lsbCBiZSBlbWl0dGVkIHZpYSB0aGlzIGBPYnNlcnZhYmxlYC4gVGhlIGJ1aWx0LWluIFtgTWVzc2FnZUJvdW5jZVByb21wdGAgY29tcG9uZW50XSguLi8uLi9jb21wb25lbnRzL01lc3NhZ2VCb3VuY2VQcm9tcHRDb21wb25lbnQpIHdpbGwgZGlzcGxheSB0aGUgYm91bmNlIG9wdGlvbiB0byB0aGUgdXNlciBpZiBhIGJvdW5jZWQgbWVzc2FnZSBpcyBjbGlja2VkLlxuICAgKi9cbiAgYm91bmNlZE1lc3NhZ2UkOiBCZWhhdmlvclN1YmplY3Q8U3RyZWFtTWVzc2FnZTxUPiB8IHVuZGVmaW5lZD47XG4gIC8qKlxuICAgKiBUaGUgbGFzdCByZWFkIG1lc3NhZ2UgaWQgb2YgdGhlIGFjdGl2ZSBjaGFubmVsLCBpdCdzIHVzZWQgYnkgdGhlIG1lc3NhZ2UgbGlzdCBjb21wb25lbnQgdG8gZGlzcGxheSB1bnJlYWQgVUksIGFuZCBqdW1wIHRvIGxhdGVzdCByZWFkIG1lc3NhZ2VcbiAgICpcbiAgICogVGhpcyBwcm9wZXJ0eSBpc24ndCBhbHdheXMgdXBkYXRlZCwgcGxlYXNlIHVzZSBgY2hhbm5lbC5yZWFkYCB0byBkaXNwbGF5IHVwLXRvLWRhdGUgcmVhZCBpbmZvcm1hdGlvblxuICAgKi9cbiAgYWN0aXZlQ2hhbm5lbExhc3RSZWFkTWVzc2FnZUlkPzogc3RyaW5nO1xuICAvKipcbiAgICogVGhlIHVucmVhZCBjb3VudCBvZiB0aGUgYWN0aXZlIGNoYW5uZWwsIGl0J3MgdXNlZCBieSB0aGUgbWVzc2FnZSBsaXN0IGNvbXBvbmVudCB0byBkaXNwbGF5IHVucmVhZCBVSVxuICAgKlxuICAgKiBUaGlzIHByb3BlcnR5IGlzbid0IGFsd2F5cyB1cGRhdGVkLCBwbGVhc2UgdXNlIGBjaGFubmVsLnJlYWRgIHRvIGRpc3BsYXkgdXAtdG8tZGF0ZSByZWFkIGluZm9ybWF0aW9uXG4gICAqL1xuICBhY3RpdmVDaGFubmVsVW5yZWFkQ291bnQ/OiBudW1iZXI7XG4gIC8qKlxuICAgKiBDdXN0b20gZXZlbnQgaGFuZGxlciB0byBjYWxsIGlmIGEgbmV3IG1lc3NhZ2UgcmVjZWl2ZWQgZnJvbSBhIGNoYW5uZWwgdGhhdCBpcyBub3QgYmVpbmcgd2F0Y2hlZCwgcHJvdmlkZSBhbiBldmVudCBoYW5kbGVyIGlmIHlvdSB3YW50IHRvIG92ZXJyaWRlIHRoZSBbZGVmYXVsdCBjaGFubmVsIGxpc3Qgb3JkZXJpbmddKC4vQ2hhbm5lbFNlcnZpY2UubWR4LyNjaGFubmVscylcbiAgICovXG4gIGN1c3RvbU5ld01lc3NhZ2VOb3RpZmljYXRpb25IYW5kbGVyPzogKFxuICAgIGNsaWVudEV2ZW50OiBDbGllbnRFdmVudCxcbiAgICBjaGFubmVsTGlzdFNldHRlcjogKFxuICAgICAgY2hhbm5lbHM6IChDaGFubmVsPFQ+IHwgQ2hhbm5lbFJlc3BvbnNlPFQ+KVtdLFxuICAgICAgc2hvdWxkU3RvcFdhdGNoaW5nUmVtb3ZlZENoYW5uZWxzPzogYm9vbGVhblxuICAgICkgPT4gdm9pZFxuICApID0+IHZvaWQ7XG4gIC8qKlxuICAgKiBDdXN0b20gZXZlbnQgaGFuZGxlciB0byBjYWxsIHdoZW4gdGhlIHVzZXIgaXMgYWRkZWQgdG8gYSBjaGFubmVsLCBwcm92aWRlIGFuIGV2ZW50IGhhbmRsZXIgaWYgeW91IHdhbnQgdG8gb3ZlcnJpZGUgdGhlIFtkZWZhdWx0IGNoYW5uZWwgbGlzdCBvcmRlcmluZ10oLi9DaGFubmVsU2VydmljZS5tZHgvI2NoYW5uZWxzKVxuICAgKi9cbiAgY3VzdG9tQWRkZWRUb0NoYW5uZWxOb3RpZmljYXRpb25IYW5kbGVyPzogKFxuICAgIGNsaWVudEV2ZW50OiBDbGllbnRFdmVudCxcbiAgICBjaGFubmVsTGlzdFNldHRlcjogKFxuICAgICAgY2hhbm5lbHM6IChDaGFubmVsPFQ+IHwgQ2hhbm5lbFJlc3BvbnNlPFQ+KVtdLFxuICAgICAgc2hvdWxkU3RvcFdhdGNoaW5nUmVtb3ZlZENoYW5uZWxzPzogYm9vbGVhblxuICAgICkgPT4gdm9pZFxuICApID0+IHZvaWQ7XG4gIC8qKlxuICAgKiBDdXN0b20gZXZlbnQgaGFuZGxlciB0byBjYWxsIHdoZW4gdGhlIHVzZXIgaXMgcmVtb3ZlZCBmcm9tIGEgY2hhbm5lbCwgcHJvdmlkZSBhbiBldmVudCBoYW5kbGVyIGlmIHlvdSB3YW50IHRvIG92ZXJyaWRlIHRoZSBbZGVmYXVsdCBjaGFubmVsIGxpc3Qgb3JkZXJpbmddKC4vQ2hhbm5lbFNlcnZpY2UubWR4LyNjaGFubmVscylcbiAgICovXG4gIGN1c3RvbVJlbW92ZWRGcm9tQ2hhbm5lbE5vdGlmaWNhdGlvbkhhbmRsZXI/OiAoXG4gICAgY2xpZW50RXZlbnQ6IENsaWVudEV2ZW50LFxuICAgIGNoYW5uZWxMaXN0U2V0dGVyOiAoXG4gICAgICBjaGFubmVsczogKENoYW5uZWw8VD4gfCBDaGFubmVsUmVzcG9uc2U8VD4pW10sXG4gICAgICBzaG91bGRTdG9wV2F0Y2hpbmdSZW1vdmVkQ2hhbm5lbHM/OiBib29sZWFuXG4gICAgKSA9PiB2b2lkXG4gICkgPT4gdm9pZDtcbiAgLyoqXG4gICAqIEN1c3RvbSBldmVudCBoYW5kbGVyIHRvIGNhbGwgd2hlbiBhIGNoYW5uZWwgaXMgZGVsZXRlZCwgcHJvdmlkZSBhbiBldmVudCBoYW5kbGVyIGlmIHlvdSB3YW50IHRvIG92ZXJyaWRlIHRoZSBbZGVmYXVsdCBjaGFubmVsIGxpc3Qgb3JkZXJpbmddKC4vQ2hhbm5lbFNlcnZpY2UubWR4LyNjaGFubmVscylcbiAgICovXG4gIGN1c3RvbUNoYW5uZWxEZWxldGVkSGFuZGxlcj86IChcbiAgICBldmVudDogRXZlbnQsXG4gICAgY2hhbm5lbDogQ2hhbm5lbDxUPixcbiAgICBjaGFubmVsTGlzdFNldHRlcjogKFxuICAgICAgY2hhbm5lbHM6IChDaGFubmVsPFQ+IHwgQ2hhbm5lbFJlc3BvbnNlPFQ+KVtdLFxuICAgICAgc2hvdWxkU3RvcFdhdGNoaW5nUmVtb3ZlZENoYW5uZWxzPzogYm9vbGVhblxuICAgICkgPT4gdm9pZCxcbiAgICBtZXNzYWdlTGlzdFNldHRlcjogKG1lc3NhZ2VzOiBTdHJlYW1NZXNzYWdlPFQ+W10pID0+IHZvaWQsXG4gICAgdGhyZWFkTGlzdFNldHRlcjogKG1lc3NhZ2VzOiBTdHJlYW1NZXNzYWdlPFQ+W10pID0+IHZvaWQsXG4gICAgcGFyZW50TWVzc2FnZVNldHRlcjogKG1lc3NhZ2U6IFN0cmVhbU1lc3NhZ2U8VD4gfCB1bmRlZmluZWQpID0+IHZvaWRcbiAgKSA9PiB2b2lkO1xuICAvKipcbiAgICogQ3VzdG9tIGV2ZW50IGhhbmRsZXIgdG8gY2FsbCB3aGVuIGEgY2hhbm5lbCBpcyB1cGRhdGVkLCBwcm92aWRlIGFuIGV2ZW50IGhhbmRsZXIgaWYgeW91IHdhbnQgdG8gb3ZlcnJpZGUgdGhlIFtkZWZhdWx0IGNoYW5uZWwgbGlzdCBvcmRlcmluZ10oLi9DaGFubmVsU2VydmljZS5tZHgvI2NoYW5uZWxzKVxuICAgKi9cbiAgY3VzdG9tQ2hhbm5lbFVwZGF0ZWRIYW5kbGVyPzogKFxuICAgIGV2ZW50OiBFdmVudCxcbiAgICBjaGFubmVsOiBDaGFubmVsPFQ+LFxuICAgIGNoYW5uZWxMaXN0U2V0dGVyOiAoXG4gICAgICBjaGFubmVsczogKENoYW5uZWw8VD4gfCBDaGFubmVsUmVzcG9uc2U8VD4pW10sXG4gICAgICBzaG91bGRTdG9wV2F0Y2hpbmdSZW1vdmVkQ2hhbm5lbHM/OiBib29sZWFuXG4gICAgKSA9PiB2b2lkLFxuICAgIG1lc3NhZ2VMaXN0U2V0dGVyOiAobWVzc2FnZXM6IFN0cmVhbU1lc3NhZ2VbXSkgPT4gdm9pZCxcbiAgICB0aHJlYWRMaXN0U2V0dGVyOiAobWVzc2FnZXM6IFN0cmVhbU1lc3NhZ2VbXSkgPT4gdm9pZCxcbiAgICBwYXJlbnRNZXNzYWdlU2V0dGVyOiAobWVzc2FnZTogU3RyZWFtTWVzc2FnZSB8IHVuZGVmaW5lZCkgPT4gdm9pZFxuICApID0+IHZvaWQ7XG4gIC8qKlxuICAgKiBDdXN0b20gZXZlbnQgaGFuZGxlciB0byBjYWxsIHdoZW4gYSBjaGFubmVsIGlzIHRydW5jYXRlZCwgcHJvdmlkZSBhbiBldmVudCBoYW5kbGVyIGlmIHlvdSB3YW50IHRvIG92ZXJyaWRlIHRoZSBbZGVmYXVsdCBjaGFubmVsIGxpc3Qgb3JkZXJpbmddKC4vQ2hhbm5lbFNlcnZpY2UubWR4LyNjaGFubmVscylcbiAgICovXG4gIGN1c3RvbUNoYW5uZWxUcnVuY2F0ZWRIYW5kbGVyPzogKFxuICAgIGV2ZW50OiBFdmVudCxcbiAgICBjaGFubmVsOiBDaGFubmVsPFQ+LFxuICAgIGNoYW5uZWxMaXN0U2V0dGVyOiAoXG4gICAgICBjaGFubmVsczogKENoYW5uZWw8VD4gfCBDaGFubmVsUmVzcG9uc2U8VD4pW10sXG4gICAgICBzaG91bGRTdG9wV2F0Y2hpbmdSZW1vdmVkQ2hhbm5lbHM/OiBib29sZWFuXG4gICAgKSA9PiB2b2lkLFxuICAgIG1lc3NhZ2VMaXN0U2V0dGVyOiAobWVzc2FnZXM6IFN0cmVhbU1lc3NhZ2U8VD5bXSkgPT4gdm9pZCxcbiAgICB0aHJlYWRMaXN0U2V0dGVyOiAobWVzc2FnZXM6IFN0cmVhbU1lc3NhZ2U8VD5bXSkgPT4gdm9pZCxcbiAgICBwYXJlbnRNZXNzYWdlU2V0dGVyOiAobWVzc2FnZTogU3RyZWFtTWVzc2FnZTxUPiB8IHVuZGVmaW5lZCkgPT4gdm9pZFxuICApID0+IHZvaWQ7XG4gIC8qKlxuICAgKiBDdXN0b20gZXZlbnQgaGFuZGxlciB0byBjYWxsIHdoZW4gYSBjaGFubmVsIGJlY29tZXMgaGlkZGVuLCBwcm92aWRlIGFuIGV2ZW50IGhhbmRsZXIgaWYgeW91IHdhbnQgdG8gb3ZlcnJpZGUgdGhlIFtkZWZhdWx0IGNoYW5uZWwgbGlzdCBvcmRlcmluZ10oLi9DaGFubmVsU2VydmljZS5tZHgvI2NoYW5uZWxzKVxuICAgKi9cbiAgY3VzdG9tQ2hhbm5lbEhpZGRlbkhhbmRsZXI/OiAoXG4gICAgZXZlbnQ6IEV2ZW50LFxuICAgIGNoYW5uZWw6IENoYW5uZWw8VD4sXG4gICAgY2hhbm5lbExpc3RTZXR0ZXI6IChcbiAgICAgIGNoYW5uZWxzOiAoQ2hhbm5lbDxUPiB8IENoYW5uZWxSZXNwb25zZTxUPilbXSxcbiAgICAgIHNob3VsZFN0b3BXYXRjaGluZ1JlbW92ZWRDaGFubmVscz86IGJvb2xlYW5cbiAgICApID0+IHZvaWQsXG4gICAgbWVzc2FnZUxpc3RTZXR0ZXI6IChtZXNzYWdlczogU3RyZWFtTWVzc2FnZTxUPltdKSA9PiB2b2lkLFxuICAgIHRocmVhZExpc3RTZXR0ZXI6IChtZXNzYWdlczogU3RyZWFtTWVzc2FnZTxUPltdKSA9PiB2b2lkLFxuICAgIHBhcmVudE1lc3NhZ2VTZXR0ZXI6IChtZXNzYWdlOiBTdHJlYW1NZXNzYWdlPFQ+IHwgdW5kZWZpbmVkKSA9PiB2b2lkXG4gICkgPT4gdm9pZDtcbiAgLyoqXG4gICAqIEN1c3RvbSBldmVudCBoYW5kbGVyIHRvIGNhbGwgd2hlbiBhIGNoYW5uZWwgYmVjb21lcyB2aXNpYmxlLCBwcm92aWRlIGFuIGV2ZW50IGhhbmRsZXIgaWYgeW91IHdhbnQgdG8gb3ZlcnJpZGUgdGhlIFtkZWZhdWx0IGNoYW5uZWwgbGlzdCBvcmRlcmluZ10oLi9DaGFubmVsU2VydmljZS5tZHgvI2NoYW5uZWxzKVxuICAgKi9cbiAgY3VzdG9tQ2hhbm5lbFZpc2libGVIYW5kbGVyPzogKFxuICAgIGV2ZW50OiBFdmVudCxcbiAgICBjaGFubmVsOiBDaGFubmVsPFQ+LFxuICAgIGNoYW5uZWxMaXN0U2V0dGVyOiAoXG4gICAgICBjaGFubmVsczogKENoYW5uZWw8VD4gfCBDaGFubmVsUmVzcG9uc2U8VD4pW10sXG4gICAgICBzaG91bGRTdG9wV2F0Y2hpbmdSZW1vdmVkQ2hhbm5lbHM/OiBib29sZWFuXG4gICAgKSA9PiB2b2lkLFxuICAgIG1lc3NhZ2VMaXN0U2V0dGVyOiAobWVzc2FnZXM6IFN0cmVhbU1lc3NhZ2U8VD5bXSkgPT4gdm9pZCxcbiAgICB0aHJlYWRMaXN0U2V0dGVyOiAobWVzc2FnZXM6IFN0cmVhbU1lc3NhZ2U8VD5bXSkgPT4gdm9pZCxcbiAgICBwYXJlbnRNZXNzYWdlU2V0dGVyOiAobWVzc2FnZTogU3RyZWFtTWVzc2FnZTxUPiB8IHVuZGVmaW5lZCkgPT4gdm9pZFxuICApID0+IHZvaWQ7XG4gIC8qKlxuICAgKiBDdXN0b20gZXZlbnQgaGFuZGxlciB0byBjYWxsIGlmIGEgbmV3IG1lc3NhZ2UgcmVjZWl2ZWQgZnJvbSBhIGNoYW5uZWwgdGhhdCBpcyBiZWluZyB3YXRjaGVkLCBwcm92aWRlIGFuIGV2ZW50IGhhbmRsZXIgaWYgeW91IHdhbnQgdG8gb3ZlcnJpZGUgdGhlIFtkZWZhdWx0IGNoYW5uZWwgbGlzdCBvcmRlcmluZ10oLi9DaGFubmVsU2VydmljZS5tZHgvI2NoYW5uZWxzKVxuICAgKi9cbiAgY3VzdG9tTmV3TWVzc2FnZUhhbmRsZXI/OiAoXG4gICAgZXZlbnQ6IEV2ZW50LFxuICAgIGNoYW5uZWw6IENoYW5uZWw8VD4sXG4gICAgY2hhbm5lbExpc3RTZXR0ZXI6IChcbiAgICAgIGNoYW5uZWxzOiAoQ2hhbm5lbDxUPiB8IENoYW5uZWxSZXNwb25zZTxUPilbXSxcbiAgICAgIHNob3VsZFN0b3BXYXRjaGluZ1JlbW92ZWRDaGFubmVscz86IGJvb2xlYW5cbiAgICApID0+IHZvaWQsXG4gICAgbWVzc2FnZUxpc3RTZXR0ZXI6IChtZXNzYWdlczogU3RyZWFtTWVzc2FnZTxUPltdKSA9PiB2b2lkLFxuICAgIHRocmVhZExpc3RTZXR0ZXI6IChtZXNzYWdlczogU3RyZWFtTWVzc2FnZTxUPltdKSA9PiB2b2lkLFxuICAgIHBhcmVudE1lc3NhZ2VTZXR0ZXI6IChtZXNzYWdlOiBTdHJlYW1NZXNzYWdlPFQ+IHwgdW5kZWZpbmVkKSA9PiB2b2lkXG4gICkgPT4gdm9pZDtcbiAgLyoqXG4gICAqIFlvdSBjYW4gb3ZlcnJpZGUgdGhlIGRlZmF1bHQgZmlsZSB1cGxvYWQgcmVxdWVzdCAtIHlvdSBjYW4gdXNlIHRoaXMgdG8gdXBsb2FkIGZpbGVzIHRvIHlvdXIgb3duIENETlxuICAgKi9cbiAgY3VzdG9tRmlsZVVwbG9hZFJlcXVlc3Q/OiAoXG4gICAgZmlsZTogRmlsZSxcbiAgICBjaGFubmVsOiBDaGFubmVsPFQ+XG4gICkgPT4gUHJvbWlzZTx7IGZpbGU6IHN0cmluZyB9PjtcbiAgLyoqXG4gICAqIFlvdSBjYW4gb3ZlcnJpZGUgdGhlIGRlZmF1bHQgaW1hZ2UgdXBsb2FkIHJlcXVlc3QgLSB5b3UgY2FuIHVzZSB0aGlzIHRvIHVwbG9hZCBpbWFnZXMgdG8geW91ciBvd24gQ0ROXG4gICAqL1xuICBjdXN0b21JbWFnZVVwbG9hZFJlcXVlc3Q/OiAoXG4gICAgZmlsZTogRmlsZSxcbiAgICBjaGFubmVsOiBDaGFubmVsPFQ+XG4gICkgPT4gUHJvbWlzZTx7IGZpbGU6IHN0cmluZyB9PjtcbiAgLyoqXG4gICAqIFlvdSBjYW4gb3ZlcnJpZGUgdGhlIGRlZmF1bHQgZmlsZSBkZWxldGUgcmVxdWVzdCAtIG92ZXJyaWRlIHRoaXMgaWYgeW91IHVzZSB5b3VyIG93biBDRE5cbiAgICovXG4gIGN1c3RvbUZpbGVEZWxldGVSZXF1ZXN0PzogKHVybDogc3RyaW5nLCBjaGFubmVsOiBDaGFubmVsPFQ+KSA9PiBQcm9taXNlPHZvaWQ+O1xuICAvKipcbiAgICogWW91IGNhbiBvdmVycmlkZSB0aGUgZGVmYXVsdCBpbWFnZSBkZWxldGUgcmVxdWVzdCAtIG92ZXJyaWRlIHRoaXMgaWYgeW91IHVzZSB5b3VyIG93biBDRE5cbiAgICovXG4gIGN1c3RvbUltYWdlRGVsZXRlUmVxdWVzdD86IChcbiAgICB1cmw6IHN0cmluZyxcbiAgICBjaGFubmVsOiBDaGFubmVsPFQ+XG4gICkgPT4gUHJvbWlzZTx2b2lkPjtcbiAgLyoqXG4gICAqIFRoZSBwcm92aWRlZCBtZXRob2Qgd2lsbCBiZSBjYWxsZWQgYmVmb3JlIGRlbGV0aW5nIGEgbWVzc2FnZS4gSWYgdGhlIHJldHVybmVkIFByb21pc2UgcmVzb2x2ZXMgdG8gYHRydWVgIHRvIGRlbGV0aW9uIHdpbGwgZ28gYWhlYWQuIElmIGBmYWxzZWAgaXMgcmV0dXJuZWQsIHRoZSBtZXNzYWdlIHdvbid0IGJlIGRlbGV0ZWQuXG4gICAqL1xuICBtZXNzYWdlRGVsZXRlQ29uZmlybWF0aW9uSGFuZGxlcj86IChcbiAgICBtZXNzYWdlOiBTdHJlYW1NZXNzYWdlPFQ+XG4gICkgPT4gUHJvbWlzZTxib29sZWFuPjtcbiAgLyoqXG4gICAqIFRoZSBwcm92aWRlZCBtZXRob2Qgd2lsbCBiZSBjYWxsZWQgYmVmb3JlIGEgbmV3IG1lc3NhZ2UgaXMgc2VudCB0byBTdHJlYW0ncyBBUEkuIFlvdSBjYW4gdXNlIHRoaXMgaG9vayB0byB0cmFuZnJvbSBvciBlbnJpY2ggdGhlIG1lc3NhZ2UgYmVpbmcgc2VudC5cbiAgICovXG4gIGJlZm9yZVNlbmRNZXNzYWdlPzogKFxuICAgIGlucHV0OiBNZXNzYWdlSW5wdXQ8VD5cbiAgKSA9PiBNZXNzYWdlSW5wdXQ8VD4gfCBQcm9taXNlPE1lc3NhZ2VJbnB1dDxUPj47XG4gIC8qKlxuICAgKiBUaGUgcHJvdmlkZWQgbWV0aG9kIHdpbGwgYmUgY2FsbGVkIGJlZm9yZSBhIG1lc3NhZ2UgaXMgc2VudCB0byBTdHJlYW0ncyBBUEkgZm9yIHVwZGF0ZS4gWW91IGNhbiB1c2UgdGhpcyBob29rIHRvIHRyYW5mcm9tIG9yIGVucmljaCB0aGUgbWVzc2FnZSBiZWluZyB1cGRhdGVkLlxuICAgKi9cbiAgYmVmb3JlVXBkYXRlTWVzc2FnZT86IChcbiAgICBtZXNzYWdlOiBTdHJlYW1NZXNzYWdlPFQ+XG4gICkgPT4gU3RyZWFtTWVzc2FnZTxUPiB8IFByb21pc2U8U3RyZWFtTWVzc2FnZTxUPj47XG4gIC8qKlxuICAgKiBCeSBkZWZhdWx0IHRoZSBTREsgdXNlcyBhbiBvZmZzZXQgYmFzZWQgcGFnaW5hdGlvbiwgeW91IGNhbiBjaGFuZ2UvZXh0ZW5kIHRoaXMgYnkgcHJvdmlkaW5nIHlvdXIgb3duIGN1c3RvbSBwYWdpbmF0b3IgbWV0aG9kLlxuICAgKlxuICAgKiBUaGUgbWV0aG9kIHdpbGwgYmUgY2FsbGVkIHdpdGggdGhlIHJlc3VsdCBvZiB0aGUgbGF0ZXN0IGNoYW5uZWwgcXVlcnkuXG4gICAqXG4gICAqIFlvdSBjYW4gcmV0dXJuIGVpdGhlciBhbiBvZmZzZXQsIG9yIGEgZmlsdGVyIHVzaW5nIHRoZSBbYCRsdGVgL2AkZ3RlYCBvcGVyYXRvcl0oaHR0cHM6Ly9nZXRzdHJlYW0uaW8vY2hhdC9kb2NzL2phdmFzY3JpcHQvcXVlcnlfc3ludGF4X29wZXJhdG9ycy8pLiBJZiB5b3UgcmV0dXJuIGEgZmlsdGVyLCBpdCB3aWxsIGJlIG1lcmdlZCB3aXRoIHRoZSBmaWx0ZXIgcHJvdmlkZWQgZm9yIHRoZSBgaW5pdGAgbWV0aG9kLlxuICAgKi9cbiAgY3VzdG9tUGFnaW5hdG9yPzogKGNoYW5uZWxRdWVyeVJlc3VsdDogQ2hhbm5lbDxUPltdKSA9PiBOZXh0UGFnZUNvbmZpZ3VyYXRpb247XG4gIC8qKlxuICAgKiBpbnRlcm5hbFxuICAgKi9cbiAgc3RhdGljIHJlYWRvbmx5IE1BWF9NRVNTQUdFX1JFQUNUSU9OU19UT19GRVRDSCA9IDEyMDA7XG4gIHByaXZhdGUgY2hhbm5lbHNTdWJqZWN0ID0gbmV3IEJlaGF2aW9yU3ViamVjdDxDaGFubmVsPFQ+W10gfCB1bmRlZmluZWQ+KFxuICAgIHVuZGVmaW5lZFxuICApO1xuICBwcml2YXRlIGFjdGl2ZUNoYW5uZWxTdWJqZWN0ID0gbmV3IEJlaGF2aW9yU3ViamVjdDxDaGFubmVsPFQ+IHwgdW5kZWZpbmVkPihcbiAgICB1bmRlZmluZWRcbiAgKTtcbiAgcHJpdmF0ZSBhY3RpdmVDaGFubmVsTWVzc2FnZXNTdWJqZWN0ID0gbmV3IEJlaGF2aW9yU3ViamVjdDxcbiAgICAoU3RyZWFtTWVzc2FnZTxUPiB8IE1lc3NhZ2VSZXNwb25zZTxUPiB8IEZvcm1hdE1lc3NhZ2VSZXNwb25zZTxUPilbXVxuICA+KFtdKTtcbiAgcHJpdmF0ZSBhY3RpdmVDaGFubmVsUGlubmVkTWVzc2FnZXNTdWJqZWN0ID0gbmV3IEJlaGF2aW9yU3ViamVjdDxcbiAgICBTdHJlYW1NZXNzYWdlW11cbiAgPihbXSk7XG4gIHByaXZhdGUgaGFzTW9yZUNoYW5uZWxzU3ViamVjdCA9IG5ldyBSZXBsYXlTdWJqZWN0PGJvb2xlYW4+KDEpO1xuICBwcml2YXRlIGFjdGl2ZUNoYW5uZWxTdWJzY3JpcHRpb25zOiB7IHVuc3Vic2NyaWJlOiAoKSA9PiB2b2lkIH1bXSA9IFtdO1xuICBwcml2YXRlIGNoYW5uZWxTdWJzY3JpcHRpb25zOiB7IFtrZXk6IHN0cmluZ106ICgpID0+IHZvaWQgfSA9IHt9O1xuICBwcml2YXRlIGFjdGl2ZVBhcmVudE1lc3NhZ2VJZFN1YmplY3QgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PFxuICAgIHN0cmluZyB8IHVuZGVmaW5lZFxuICA+KHVuZGVmaW5lZCk7XG4gIHByaXZhdGUgYWN0aXZlVGhyZWFkTWVzc2FnZXNTdWJqZWN0ID0gbmV3IEJlaGF2aW9yU3ViamVjdDxcbiAgICAoU3RyZWFtTWVzc2FnZTxUPiB8IE1lc3NhZ2VSZXNwb25zZTxUPiB8IEZvcm1hdE1lc3NhZ2VSZXNwb25zZTxUPilbXVxuICA+KFtdKTtcbiAgcHJpdmF0ZSBqdW1wVG9NZXNzYWdlU3ViamVjdCA9IG5ldyBCZWhhdmlvclN1YmplY3Q8e1xuICAgIGlkPzogc3RyaW5nO1xuICAgIHBhcmVudElkPzogc3RyaW5nO1xuICB9Pih7IGlkOiB1bmRlZmluZWQsIHBhcmVudElkOiB1bmRlZmluZWQgfSk7XG4gIHByaXZhdGUgbGF0ZXN0TWVzc2FnZURhdGVCeVVzZXJCeUNoYW5uZWxzU3ViamVjdCA9IG5ldyBCZWhhdmlvclN1YmplY3Q8e1xuICAgIFtrZXk6IHN0cmluZ106IERhdGU7XG4gIH0+KHt9KTtcbiAgcHJpdmF0ZSBmaWx0ZXJzOiBDaGFubmVsRmlsdGVyczxUPiB8IHVuZGVmaW5lZDtcbiAgcHJpdmF0ZSBzb3J0OiBDaGFubmVsU29ydDxUPiB8IHVuZGVmaW5lZDtcbiAgcHJpdmF0ZSBvcHRpb25zOlxuICAgIHwgKENoYW5uZWxPcHRpb25zICYgeyBrZWVwQWxpdmVDaGFubmVscyRPbkVycm9yPzogYm9vbGVhbiB9KVxuICAgIHwgdW5kZWZpbmVkO1xuICBwcml2YXRlIHJlYWRvbmx5IG1lc3NhZ2VQYWdlU2l6ZSA9IDI1O1xuICBwcml2YXRlIG1lc3NhZ2VUb1F1b3RlU3ViamVjdCA9IG5ldyBCZWhhdmlvclN1YmplY3Q8XG4gICAgU3RyZWFtTWVzc2FnZTxUPiB8IHVuZGVmaW5lZFxuICA+KHVuZGVmaW5lZCk7XG4gIHByaXZhdGUgdXNlcnNUeXBpbmdJbkNoYW5uZWxTdWJqZWN0ID0gbmV3IEJlaGF2aW9yU3ViamVjdDxVc2VyUmVzcG9uc2U8VD5bXT4oXG4gICAgW11cbiAgKTtcbiAgcHJpdmF0ZSB1c2Vyc1R5cGluZ0luVGhyZWFkU3ViamVjdCA9IG5ldyBCZWhhdmlvclN1YmplY3Q8VXNlclJlc3BvbnNlPFQ+W10+KFxuICAgIFtdXG4gICk7XG4gIHByaXZhdGUgX3Nob3VsZE1hcmtBY3RpdmVDaGFubmVsQXNSZWFkID0gdHJ1ZTtcbiAgcHJpdmF0ZSBzaG91bGRTZXRBY3RpdmVDaGFubmVsOiBib29sZWFuIHwgdW5kZWZpbmVkO1xuICBwcml2YXRlIGNsaWVudEV2ZW50c1N1YnNjcmlwdGlvbjogU3Vic2NyaXB0aW9uIHwgdW5kZWZpbmVkO1xuICBwcml2YXRlIGlzU3RhdGVSZWNvdmVyeUluUHJvZ3Jlc3MgPSBmYWxzZTtcbiAgcHJpdmF0ZSBjaGFubmVsUXVlcnlTdGF0ZVN1YmplY3QgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PFxuICAgIENoYW5uZWxRdWVyeVN0YXRlIHwgdW5kZWZpbmVkXG4gID4odW5kZWZpbmVkKTtcblxuICBwcml2YXRlIGNoYW5uZWxMaXN0U2V0dGVyID0gKFxuICAgIGNoYW5uZWxzOiAoQ2hhbm5lbDxUPiB8IENoYW5uZWxSZXNwb25zZTxUPilbXSxcbiAgICBzaG91bGRTdG9wV2F0Y2hpbmdSZW1vdmVkQ2hhbm5lbHMgPSB0cnVlXG4gICkgPT4ge1xuICAgIGNvbnN0IGN1cnJlbnRDaGFubmVscyA9IHRoaXMuY2hhbm5lbHNTdWJqZWN0LmdldFZhbHVlKCkgfHwgW107XG4gICAgY29uc3QgbmV3Q2hhbm5lbHMgPSBjaGFubmVscy5maWx0ZXIoXG4gICAgICAoYykgPT4gIWN1cnJlbnRDaGFubmVscy5maW5kKChjaGFubmVsKSA9PiBjaGFubmVsLmNpZCA9PT0gYy5jaWQpXG4gICAgKTtcbiAgICBjb25zdCBkZWxldGVkQ2hhbm5lbHMgPSBjdXJyZW50Q2hhbm5lbHMuZmlsdGVyKFxuICAgICAgKGMpID0+ICFjaGFubmVscz8uZmluZCgoY2hhbm5lbCkgPT4gY2hhbm5lbC5jaWQgPT09IGMuY2lkKVxuICAgICk7XG4gICAgdm9pZCB0aGlzLmFkZENoYW5uZWxzRnJvbU5vdGlmaWNhdGlvbihuZXdDaGFubmVscyBhcyBDaGFubmVsUmVzcG9uc2U8VD5bXSk7XG4gICAgdGhpcy5yZW1vdmVDaGFubmVsc0Zyb21DaGFubmVsTGlzdChcbiAgICAgIGRlbGV0ZWRDaGFubmVscy5tYXAoKGMpID0+IGMuY2lkKSxcbiAgICAgIHNob3VsZFN0b3BXYXRjaGluZ1JlbW92ZWRDaGFubmVsc1xuICAgICk7XG4gIH07XG5cbiAgcHJpdmF0ZSBtZXNzYWdlTGlzdFNldHRlciA9IChtZXNzYWdlczogU3RyZWFtTWVzc2FnZTxUPltdKSA9PiB7XG4gICAgdGhpcy5hY3RpdmVDaGFubmVsTWVzc2FnZXNTdWJqZWN0Lm5leHQobWVzc2FnZXMpO1xuICB9O1xuXG4gIHByaXZhdGUgdGhyZWFkTGlzdFNldHRlciA9IChtZXNzYWdlczogU3RyZWFtTWVzc2FnZTxUPltdKSA9PiB7XG4gICAgdGhpcy5hY3RpdmVUaHJlYWRNZXNzYWdlc1N1YmplY3QubmV4dChtZXNzYWdlcyk7XG4gIH07XG5cbiAgcHJpdmF0ZSBwYXJlbnRNZXNzYWdlU2V0dGVyID0gKG1lc3NhZ2U6IFN0cmVhbU1lc3NhZ2U8VD4gfCB1bmRlZmluZWQpID0+IHtcbiAgICB0aGlzLmFjdGl2ZVBhcmVudE1lc3NhZ2VJZFN1YmplY3QubmV4dChtZXNzYWdlPy5pZCk7XG4gIH07XG4gIHByaXZhdGUgZGlzbWlzc0Vycm9yTm90aWZpY2F0aW9uPzogRnVuY3Rpb247XG4gIHByaXZhdGUgbmV4dFBhZ2VDb25maWd1cmF0aW9uPzogTmV4dFBhZ2VDb25maWd1cmF0aW9uO1xuICBwcml2YXRlIGFyZVJlYWRFdmVudHNQYXVzZWQgPSBmYWxzZTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIGNoYXRDbGllbnRTZXJ2aWNlOiBDaGF0Q2xpZW50U2VydmljZTxUPixcbiAgICBwcml2YXRlIG5nWm9uZTogTmdab25lLFxuICAgIHByaXZhdGUgbm90aWZpY2F0aW9uU2VydmljZTogTm90aWZpY2F0aW9uU2VydmljZVxuICApIHtcbiAgICB0aGlzLmNoYW5uZWxzJCA9IHRoaXMuY2hhbm5lbHNTdWJqZWN0LmFzT2JzZXJ2YWJsZSgpLnBpcGUoc2hhcmVSZXBsYXkoMSkpO1xuICAgIHRoaXMuYWN0aXZlQ2hhbm5lbCQgPSB0aGlzLmFjdGl2ZUNoYW5uZWxTdWJqZWN0XG4gICAgICAuYXNPYnNlcnZhYmxlKClcbiAgICAgIC5waXBlKHNoYXJlUmVwbGF5KDEpKTtcbiAgICB0aGlzLmFjdGl2ZUNoYW5uZWxNZXNzYWdlcyQgPSB0aGlzLmFjdGl2ZUNoYW5uZWxNZXNzYWdlc1N1YmplY3QucGlwZShcbiAgICAgIG1hcCgobWVzc2FnZXMpID0+IHtcbiAgICAgICAgY29uc3QgY2hhbm5lbCA9IHRoaXMuYWN0aXZlQ2hhbm5lbFN1YmplY3QuZ2V0VmFsdWUoKSE7XG4gICAgICAgIHJldHVybiBtZXNzYWdlcy5tYXAoKG1lc3NhZ2UpID0+XG4gICAgICAgICAgdGhpcy50cmFuc2Zvcm1Ub1N0cmVhbU1lc3NhZ2UobWVzc2FnZSwgY2hhbm5lbClcbiAgICAgICAgKTtcbiAgICAgIH0pLFxuICAgICAgc2hhcmVSZXBsYXkoMSlcbiAgICApO1xuICAgIHRoaXMuYm91bmNlZE1lc3NhZ2UkID0gbmV3IEJlaGF2aW9yU3ViamVjdDxTdHJlYW1NZXNzYWdlPFQ+IHwgdW5kZWZpbmVkPihcbiAgICAgIHVuZGVmaW5lZFxuICAgICk7XG4gICAgdGhpcy5oYXNNb3JlQ2hhbm5lbHMkID0gdGhpcy5oYXNNb3JlQ2hhbm5lbHNTdWJqZWN0XG4gICAgICAuYXNPYnNlcnZhYmxlKClcbiAgICAgIC5waXBlKHNoYXJlUmVwbGF5KDEpKTtcbiAgICB0aGlzLmFjdGl2ZVBhcmVudE1lc3NhZ2VJZCQgPSB0aGlzLmFjdGl2ZVBhcmVudE1lc3NhZ2VJZFN1YmplY3RcbiAgICAgIC5hc09ic2VydmFibGUoKVxuICAgICAgLnBpcGUoc2hhcmVSZXBsYXkoMSkpO1xuICAgIHRoaXMuYWN0aXZlVGhyZWFkTWVzc2FnZXMkID0gdGhpcy5hY3RpdmVUaHJlYWRNZXNzYWdlc1N1YmplY3QucGlwZShcbiAgICAgIG1hcCgobWVzc2FnZXMpID0+IHtcbiAgICAgICAgY29uc3QgY2hhbm5lbCA9IHRoaXMuYWN0aXZlQ2hhbm5lbFN1YmplY3QuZ2V0VmFsdWUoKSE7XG4gICAgICAgIHJldHVybiBtZXNzYWdlcy5tYXAoKG1lc3NhZ2UpID0+XG4gICAgICAgICAgdGhpcy50cmFuc2Zvcm1Ub1N0cmVhbU1lc3NhZ2UobWVzc2FnZSwgY2hhbm5lbClcbiAgICAgICAgKTtcbiAgICAgIH0pLFxuICAgICAgc2hhcmVSZXBsYXkoMSlcbiAgICApO1xuICAgIHRoaXMuYWN0aXZlUGFyZW50TWVzc2FnZSQgPSBjb21iaW5lTGF0ZXN0KFtcbiAgICAgIHRoaXMuYWN0aXZlQ2hhbm5lbE1lc3NhZ2VzJCxcbiAgICAgIHRoaXMuYWN0aXZlUGFyZW50TWVzc2FnZUlkJCxcbiAgICBdKS5waXBlKFxuICAgICAgbWFwKFxuICAgICAgICAoW21lc3NhZ2VzLCBwYXJlbnRNZXNzYWdlSWRdOiBbXG4gICAgICAgICAgU3RyZWFtTWVzc2FnZVtdLFxuICAgICAgICAgIHN0cmluZyB8IHVuZGVmaW5lZFxuICAgICAgICBdKSA9PiB7XG4gICAgICAgICAgaWYgKCFwYXJlbnRNZXNzYWdlSWQpIHtcbiAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IG1lc3NhZ2UgPSBtZXNzYWdlcy5maW5kKChtKSA9PiBtLmlkID09PSBwYXJlbnRNZXNzYWdlSWQpO1xuICAgICAgICAgICAgaWYgKCFtZXNzYWdlKSB7XG4gICAgICAgICAgICAgIHZvaWQgdGhpcy5zZXRBc0FjdGl2ZVBhcmVudE1lc3NhZ2UodW5kZWZpbmVkKTtcbiAgICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHJldHVybiBtZXNzYWdlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgKSxcbiAgICAgIHNoYXJlUmVwbGF5KDEpXG4gICAgKTtcbiAgICB0aGlzLm1lc3NhZ2VUb1F1b3RlJCA9IHRoaXMubWVzc2FnZVRvUXVvdGVTdWJqZWN0XG4gICAgICAuYXNPYnNlcnZhYmxlKClcbiAgICAgIC5waXBlKHNoYXJlUmVwbGF5KDEpKTtcbiAgICB0aGlzLmp1bXBUb01lc3NhZ2UkID0gdGhpcy5qdW1wVG9NZXNzYWdlU3ViamVjdFxuICAgICAgLmFzT2JzZXJ2YWJsZSgpXG4gICAgICAucGlwZShzaGFyZVJlcGxheSgxKSk7XG5cbiAgICB0aGlzLnVzZXJzVHlwaW5nSW5DaGFubmVsJCA9IHRoaXMudXNlcnNUeXBpbmdJbkNoYW5uZWxTdWJqZWN0XG4gICAgICAuYXNPYnNlcnZhYmxlKClcbiAgICAgIC5waXBlKHNoYXJlUmVwbGF5KDEpKTtcbiAgICB0aGlzLnVzZXJzVHlwaW5nSW5UaHJlYWQkID0gdGhpcy51c2Vyc1R5cGluZ0luVGhyZWFkU3ViamVjdFxuICAgICAgLmFzT2JzZXJ2YWJsZSgpXG4gICAgICAucGlwZShzaGFyZVJlcGxheSgxKSk7XG4gICAgdGhpcy5sYXRlc3RNZXNzYWdlRGF0ZUJ5VXNlckJ5Q2hhbm5lbHMkID1cbiAgICAgIHRoaXMubGF0ZXN0TWVzc2FnZURhdGVCeVVzZXJCeUNoYW5uZWxzU3ViamVjdFxuICAgICAgICAuYXNPYnNlcnZhYmxlKClcbiAgICAgICAgLnBpcGUoc2hhcmVSZXBsYXkoMSkpO1xuICAgIHRoaXMuYWN0aXZlQ2hhbm5lbFBpbm5lZE1lc3NhZ2VzJCA9IHRoaXMuYWN0aXZlQ2hhbm5lbFBpbm5lZE1lc3NhZ2VzU3ViamVjdFxuICAgICAgLmFzT2JzZXJ2YWJsZSgpXG4gICAgICAucGlwZShzaGFyZVJlcGxheSgxKSk7XG4gICAgdGhpcy5jaGFubmVsUXVlcnlTdGF0ZSQgPSB0aGlzLmNoYW5uZWxRdWVyeVN0YXRlU3ViamVjdFxuICAgICAgLmFzT2JzZXJ2YWJsZSgpXG4gICAgICAucGlwZShzaGFyZVJlcGxheSgxKSk7XG4gIH1cblxuICAvKipcbiAgICogSWYgc2V0IHRvIGZhbHNlLCByZWFkIGV2ZW50cyB3b24ndCBiZSBzZW50IGFzIG5ldyBtZXNzYWdlcyBhcmUgcmVjZWl2ZWQuIElmIHNldCB0byB0cnVlIGFjdGl2ZSBjaGFubmVsIChpZiBhbnkpIHdpbGwgaW1tZWRpYXRlbHkgYmUgbWFya2VkIGFzIHJlYWQuXG4gICAqL1xuICBnZXQgc2hvdWxkTWFya0FjdGl2ZUNoYW5uZWxBc1JlYWQoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3Nob3VsZE1hcmtBY3RpdmVDaGFubmVsQXNSZWFkO1xuICB9XG5cbiAgLyoqXG4gICAqIElmIHNldCB0byBmYWxzZSwgcmVhZCBldmVudHMgd29uJ3QgYmUgc2VudCBhcyBuZXcgbWVzc2FnZXMgYXJlIHJlY2VpdmVkLiBJZiBzZXQgdG8gdHJ1ZSBhY3RpdmUgY2hhbm5lbCAoaWYgYW55KSB3aWxsIGltbWVkaWF0ZWx5IGJlIG1hcmtlZCBhcyByZWFkLlxuICAgKi9cbiAgc2V0IHNob3VsZE1hcmtBY3RpdmVDaGFubmVsQXNSZWFkKHNob3VsZE1hcmtBY3RpdmVDaGFubmVsQXNSZWFkOiBib29sZWFuKSB7XG4gICAgaWYgKCF0aGlzLl9zaG91bGRNYXJrQWN0aXZlQ2hhbm5lbEFzUmVhZCAmJiBzaG91bGRNYXJrQWN0aXZlQ2hhbm5lbEFzUmVhZCkge1xuICAgICAgY29uc3QgYWN0aXZlQ2hhbm5lbCA9IHRoaXMuYWN0aXZlQ2hhbm5lbFN1YmplY3QuZ2V0VmFsdWUoKTtcbiAgICAgIGlmIChhY3RpdmVDaGFubmVsICYmIHRoaXMuY2FuU2VuZFJlYWRFdmVudHMpIHtcbiAgICAgICAgdm9pZCBhY3RpdmVDaGFubmVsLm1hcmtSZWFkKCk7XG4gICAgICB9XG4gICAgfVxuICAgIHRoaXMuX3Nob3VsZE1hcmtBY3RpdmVDaGFubmVsQXNSZWFkID0gc2hvdWxkTWFya0FjdGl2ZUNoYW5uZWxBc1JlYWQ7XG4gIH1cblxuICAvKipcbiAgICogU2V0cyB0aGUgZ2l2ZW4gYGNoYW5uZWxgIGFzIGFjdGl2ZSBhbmQgbWFya3MgaXQgYXMgcmVhZC5cbiAgICogSWYgdGhlIGNoYW5uZWwgd2Fzbid0IHByZXZpb3VzbHkgcGFydCBvZiB0aGUgY2hhbm5lbCwgaXQgd2lsbCBiZSBhZGRlZCB0byB0aGUgYmVnaW5uaW5nIG9mIHRoZSBsaXN0LlxuICAgKlxuICAgKiBAcGFyYW0gY2hhbm5lbFxuICAgKi9cbiAgc2V0QXNBY3RpdmVDaGFubmVsKGNoYW5uZWw6IENoYW5uZWw8VD4pIHtcbiAgICBjb25zdCBwcmV2QWN0aXZlQ2hhbm5lbCA9IHRoaXMuYWN0aXZlQ2hhbm5lbFN1YmplY3QuZ2V0VmFsdWUoKTtcbiAgICBpZiAocHJldkFjdGl2ZUNoYW5uZWw/LmNpZCA9PT0gY2hhbm5lbC5jaWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5zdG9wV2F0Y2hGb3JBY3RpdmVDaGFubmVsRXZlbnRzKHByZXZBY3RpdmVDaGFubmVsKTtcbiAgICB0aGlzLmFyZVJlYWRFdmVudHNQYXVzZWQgPSBmYWxzZTtcbiAgICBjb25zdCByZWFkU3RhdGUgPVxuICAgICAgY2hhbm5lbC5zdGF0ZS5yZWFkW3RoaXMuY2hhdENsaWVudFNlcnZpY2UuY2hhdENsaWVudC51c2VyPy5pZCB8fCAnJ107XG4gICAgdGhpcy5hY3RpdmVDaGFubmVsTGFzdFJlYWRNZXNzYWdlSWQgPSByZWFkU3RhdGU/Lmxhc3RfcmVhZF9tZXNzYWdlX2lkO1xuICAgIGlmIChcbiAgICAgIGNoYW5uZWwuc3RhdGUubGF0ZXN0TWVzc2FnZXNbY2hhbm5lbC5zdGF0ZS5sYXRlc3RNZXNzYWdlcy5sZW5ndGggLSAxXVxuICAgICAgICA/LmlkID09PSB0aGlzLmFjdGl2ZUNoYW5uZWxMYXN0UmVhZE1lc3NhZ2VJZFxuICAgICkge1xuICAgICAgdGhpcy5hY3RpdmVDaGFubmVsTGFzdFJlYWRNZXNzYWdlSWQgPSB1bmRlZmluZWQ7XG4gICAgfVxuICAgIHRoaXMuYWN0aXZlQ2hhbm5lbFVucmVhZENvdW50ID0gcmVhZFN0YXRlPy51bnJlYWRfbWVzc2FnZXMgfHwgMDtcbiAgICB0aGlzLndhdGNoRm9yQWN0aXZlQ2hhbm5lbEV2ZW50cyhjaGFubmVsKTtcbiAgICB0aGlzLmFkZENoYW5uZWwoY2hhbm5lbCk7XG4gICAgdGhpcy5hY3RpdmVDaGFubmVsU3ViamVjdC5uZXh0KGNoYW5uZWwpO1xuICAgIGNvbnN0IGNoYW5uZWxTdGF0ZUxlbmd0aCA9IGNoYW5uZWwuc3RhdGUubGF0ZXN0TWVzc2FnZXMubGVuZ3RoO1xuICAgIGlmIChjaGFubmVsU3RhdGVMZW5ndGggPiAyICogdGhpcy5tZXNzYWdlUGFnZVNpemUpIHtcbiAgICAgIGNoYW5uZWwuc3RhdGUubGF0ZXN0TWVzc2FnZXMgPSBjaGFubmVsLnN0YXRlLmxhdGVzdE1lc3NhZ2VzLnNsaWNlKFxuICAgICAgICBjaGFubmVsU3RhdGVMZW5ndGggLSAyICogdGhpcy5tZXNzYWdlUGFnZVNpemVcbiAgICAgICk7XG4gICAgfVxuICAgIHRoaXMuc2V0Q2hhbm5lbFN0YXRlKGNoYW5uZWwpO1xuICB9XG5cbiAgLyoqXG4gICAqIERlc2VsZWN0cyB0aGUgY3VycmVudGx5IGFjdGl2ZSAoaWYgYW55KSBjaGFubmVsXG4gICAqL1xuICBkZXNlbGVjdEFjdGl2ZUNoYW5uZWwoKSB7XG4gICAgY29uc3QgYWN0aXZlQ2hhbm5lbCA9IHRoaXMuYWN0aXZlQ2hhbm5lbFN1YmplY3QuZ2V0VmFsdWUoKTtcbiAgICBpZiAoIWFjdGl2ZUNoYW5uZWwpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5zdG9wV2F0Y2hGb3JBY3RpdmVDaGFubmVsRXZlbnRzKGFjdGl2ZUNoYW5uZWwpO1xuICAgIHRoaXMuYWN0aXZlQ2hhbm5lbE1lc3NhZ2VzU3ViamVjdC5uZXh0KFtdKTtcbiAgICB0aGlzLmFjdGl2ZUNoYW5uZWxTdWJqZWN0Lm5leHQodW5kZWZpbmVkKTtcbiAgICB0aGlzLmFjdGl2ZVBhcmVudE1lc3NhZ2VJZFN1YmplY3QubmV4dCh1bmRlZmluZWQpO1xuICAgIHRoaXMuYWN0aXZlVGhyZWFkTWVzc2FnZXNTdWJqZWN0Lm5leHQoW10pO1xuICAgIHRoaXMubGF0ZXN0TWVzc2FnZURhdGVCeVVzZXJCeUNoYW5uZWxzU3ViamVjdC5uZXh0KHt9KTtcbiAgICB0aGlzLnNlbGVjdE1lc3NhZ2VUb1F1b3RlKHVuZGVmaW5lZCk7XG4gICAgdGhpcy5qdW1wVG9NZXNzYWdlU3ViamVjdC5uZXh0KHsgaWQ6IHVuZGVmaW5lZCwgcGFyZW50SWQ6IHVuZGVmaW5lZCB9KTtcbiAgICB0aGlzLmFjdGl2ZUNoYW5uZWxQaW5uZWRNZXNzYWdlc1N1YmplY3QubmV4dChbXSk7XG4gICAgdGhpcy51c2Vyc1R5cGluZ0luQ2hhbm5lbFN1YmplY3QubmV4dChbXSk7XG4gICAgdGhpcy51c2Vyc1R5cGluZ0luVGhyZWFkU3ViamVjdC5uZXh0KFtdKTtcbiAgICB0aGlzLmFjdGl2ZUNoYW5uZWxMYXN0UmVhZE1lc3NhZ2VJZCA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLmFjdGl2ZUNoYW5uZWxVbnJlYWRDb3VudCA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLmFyZVJlYWRFdmVudHNQYXVzZWQgPSBmYWxzZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZXRzIHRoZSBnaXZlbiBgbWVzc2FnZWAgYXMgYW4gYWN0aXZlIHBhcmVudCBtZXNzYWdlLiBJZiBgdW5kZWZpbmVkYCBpcyBwcm92aWRlZCwgaXQgd2lsbCBkZWxlc2VsZWN0IHRoZSBjdXJyZW50IHBhcmVudCBtZXNzYWdlLlxuICAgKiBAcGFyYW0gbWVzc2FnZVxuICAgKiBAcGFyYW0gbG9hZE1lc3NhZ2VzRm9ybVxuICAgKi9cbiAgYXN5bmMgc2V0QXNBY3RpdmVQYXJlbnRNZXNzYWdlKFxuICAgIG1lc3NhZ2U6IFN0cmVhbU1lc3NhZ2U8VD4gfCB1bmRlZmluZWQsXG4gICAgbG9hZE1lc3NhZ2VzRm9ybTogJ3JlcXVlc3QnIHwgJ3N0YXRlJyA9ICdyZXF1ZXN0J1xuICApIHtcbiAgICBjb25zdCBtZXNzYWdlVG9RdW90ZSA9IHRoaXMubWVzc2FnZVRvUXVvdGVTdWJqZWN0LmdldFZhbHVlKCk7XG4gICAgaWYgKG1lc3NhZ2VUb1F1b3RlICYmICEhbWVzc2FnZVRvUXVvdGUucGFyZW50X2lkKSB7XG4gICAgICB0aGlzLm1lc3NhZ2VUb1F1b3RlU3ViamVjdC5uZXh0KHVuZGVmaW5lZCk7XG4gICAgfVxuICAgIGlmICghbWVzc2FnZSkge1xuICAgICAgdGhpcy5hY3RpdmVQYXJlbnRNZXNzYWdlSWRTdWJqZWN0Lm5leHQodW5kZWZpbmVkKTtcbiAgICAgIHRoaXMuYWN0aXZlVGhyZWFkTWVzc2FnZXNTdWJqZWN0Lm5leHQoW10pO1xuICAgICAgY29uc3QgbWVzc2FnZVRvSnVtcFRvID0gdGhpcy5qdW1wVG9NZXNzYWdlU3ViamVjdC5nZXRWYWx1ZSgpO1xuICAgICAgaWYgKG1lc3NhZ2VUb0p1bXBUbyAmJiAhIW1lc3NhZ2VUb0p1bXBUby5wYXJlbnRJZCkge1xuICAgICAgICB0aGlzLmp1bXBUb01lc3NhZ2VTdWJqZWN0Lm5leHQoeyBpZDogdW5kZWZpbmVkLCBwYXJlbnRJZDogdW5kZWZpbmVkIH0pO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmFjdGl2ZVBhcmVudE1lc3NhZ2VJZFN1YmplY3QubmV4dChtZXNzYWdlLmlkKTtcbiAgICAgIGNvbnN0IGFjdGl2ZUNoYW5uZWwgPSB0aGlzLmFjdGl2ZUNoYW5uZWxTdWJqZWN0LmdldFZhbHVlKCk7XG4gICAgICBpZiAobG9hZE1lc3NhZ2VzRm9ybSA9PT0gJ3JlcXVlc3QnKSB7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGFjdGl2ZUNoYW5uZWw/LmdldFJlcGxpZXMobWVzc2FnZS5pZCwge1xuICAgICAgICAgIGxpbWl0OiB0aGlzLm9wdGlvbnM/Lm1lc3NhZ2VfbGltaXQsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmFjdGl2ZVRocmVhZE1lc3NhZ2VzU3ViamVjdC5uZXh0KHJlc3VsdD8ubWVzc2FnZXMgfHwgW10pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5hY3RpdmVUaHJlYWRNZXNzYWdlc1N1YmplY3QubmV4dChcbiAgICAgICAgICBhY3RpdmVDaGFubmVsPy5zdGF0ZS50aHJlYWRzW21lc3NhZ2UuaWRdIHx8IFtdXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIExvYWRzIHRoZSBuZXh0IHBhZ2Ugb2YgbWVzc2FnZXMgb2YgdGhlIGFjdGl2ZSBjaGFubmVsLiBUaGUgcGFnZSBzaXplIGNhbiBiZSBzZXQgaW4gdGhlIFtxdWVyeSBvcHRpb25dKGh0dHBzOi8vZ2V0c3RyZWFtLmlvL2NoYXQvZG9jcy9qYXZhc2NyaXB0L3F1ZXJ5X2NoYW5uZWxzLz9sYW5ndWFnZT1qYXZhc2NyaXB0I3F1ZXJ5LW9wdGlvbnMpIG9iamVjdC5cbiAgICogQHBhcmFtIGRpcmVjdGlvblxuICAgKi9cbiAgbG9hZE1vcmVNZXNzYWdlcyhkaXJlY3Rpb246ICdvbGRlcicgfCAnbmV3ZXInID0gJ29sZGVyJykge1xuICAgIGNvbnN0IGFjdGl2ZUNobmFubmVsID0gdGhpcy5hY3RpdmVDaGFubmVsU3ViamVjdC5nZXRWYWx1ZSgpO1xuICAgIGNvbnN0IG1lc3NhZ2VzID0gdGhpcy5hY3RpdmVDaGFubmVsTWVzc2FnZXNTdWJqZWN0LmdldFZhbHVlKCk7XG4gICAgY29uc3QgbGFzdE1lc3NhZ2VJZCA9XG4gICAgICBtZXNzYWdlc1tkaXJlY3Rpb24gPT09ICdvbGRlcicgPyAwIDogbWVzc2FnZXMubGVuZ3RoIC0gMV0/LmlkO1xuICAgIGlmIChcbiAgICAgIGRpcmVjdGlvbiA9PT0gJ25ld2VyJyAmJlxuICAgICAgYWN0aXZlQ2huYW5uZWw/LnN0YXRlPy5sYXRlc3RNZXNzYWdlcyA9PT0gYWN0aXZlQ2huYW5uZWw/LnN0YXRlPy5tZXNzYWdlc1xuICAgICkge1xuICAgICAgLy8gSWYgd2UgYXJlIG9uIGxhdGVzdCBtZXNzYWdlIHNldCwgYWN0aXZlQ2hhbm5lbE1lc3NhZ2VzJCB3aWxsIGJlIHJlZnJlc2hlZCBieSBXUyBldmVudHMsIG5vIG5lZWQgZm9yIGEgcmVxdWVzdFxuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4gYWN0aXZlQ2huYW5uZWxcbiAgICAgID8ucXVlcnkoe1xuICAgICAgICBtZXNzYWdlczoge1xuICAgICAgICAgIGxpbWl0OiB0aGlzLm9wdGlvbnM/Lm1lc3NhZ2VfbGltaXQsXG4gICAgICAgICAgW2RpcmVjdGlvbiA9PT0gJ29sZGVyJyA/ICdpZF9sdCcgOiAnaWRfZ3QnXTogbGFzdE1lc3NhZ2VJZCxcbiAgICAgICAgfSxcbiAgICAgICAgbWVtYmVyczogeyBsaW1pdDogMCB9LFxuICAgICAgICB3YXRjaGVyczogeyBsaW1pdDogMCB9LFxuICAgICAgfSlcbiAgICAgIC50aGVuKChyZXMpID0+IHtcbiAgICAgICAgaWYgKFxuICAgICAgICAgIGFjdGl2ZUNobmFubmVsPy5kYXRhPy5pZCA9PT1cbiAgICAgICAgICB0aGlzLmFjdGl2ZUNoYW5uZWxTdWJqZWN0LmdldFZhbHVlKCk/LmRhdGE/LmlkXG4gICAgICAgICkge1xuICAgICAgICAgIHRoaXMuYWN0aXZlQ2hhbm5lbE1lc3NhZ2VzU3ViamVjdC5uZXh0KFtcbiAgICAgICAgICAgIC4uLmFjdGl2ZUNobmFubmVsLnN0YXRlLm1lc3NhZ2VzLFxuICAgICAgICAgIF0pO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHJlcztcbiAgICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIExvYWRzIHRoZSBuZXh0IHBhZ2Ugb2YgbWVzc2FnZXMgb2YgdGhlIGFjdGl2ZSB0aHJlYWQuIFRoZSBwYWdlIHNpemUgY2FuIGJlIHNldCBpbiB0aGUgW3F1ZXJ5IG9wdGlvbl0oaHR0cHM6Ly9nZXRzdHJlYW0uaW8vY2hhdC9kb2NzL2phdmFzY3JpcHQvcXVlcnlfY2hhbm5lbHMvP2xhbmd1YWdlPWphdmFzY3JpcHQjcXVlcnktb3B0aW9ucykgb2JqZWN0LlxuICAgKiBAcGFyYW0gZGlyZWN0aW9uXG4gICAqL1xuICBhc3luYyBsb2FkTW9yZVRocmVhZFJlcGxpZXMoZGlyZWN0aW9uOiAnb2xkZXInIHwgJ25ld2VyJyA9ICdvbGRlcicpIHtcbiAgICBpZiAoZGlyZWN0aW9uID09PSAnbmV3ZXInKSB7XG4gICAgICAvLyBUaHJlYWQgcmVwbGllcyBhcmVuJ3QgYnJva2UgaW50byBkaWZmZXJlbnQgbWVzc2FnZSBzZXRzLCBhY3RpdmVUaHJlYWRNZXNzYWdlcyQgd2lsbCBiZSByZWZyZXNoZWQgYnkgV1MgZXZlbnRzLCBubyBuZWVkIGZvciBhIHJlcXVlc3RcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgYWN0aXZlQ2huYW5uZWwgPSB0aGlzLmFjdGl2ZUNoYW5uZWxTdWJqZWN0LmdldFZhbHVlKCk7XG4gICAgY29uc3QgcGFyZW50TWVzc2FnZUlkID0gdGhpcy5hY3RpdmVQYXJlbnRNZXNzYWdlSWRTdWJqZWN0LmdldFZhbHVlKCk7XG4gICAgaWYgKCFwYXJlbnRNZXNzYWdlSWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgdGhyZWFkTWVzc2FnZXMgPSB0aGlzLmFjdGl2ZVRocmVhZE1lc3NhZ2VzU3ViamVjdC5nZXRWYWx1ZSgpO1xuICAgIGNvbnN0IGxhc3RNZXNzYWdlSWQgPVxuICAgICAgdGhyZWFkTWVzc2FnZXNbZGlyZWN0aW9uID09PSAnb2xkZXInID8gMCA6IHRocmVhZE1lc3NhZ2VzLmxlbmd0aCAtIDFdPy5pZDtcbiAgICBhd2FpdCBhY3RpdmVDaG5hbm5lbD8uZ2V0UmVwbGllcyhwYXJlbnRNZXNzYWdlSWQsIHtcbiAgICAgIGxpbWl0OiB0aGlzLm9wdGlvbnM/Lm1lc3NhZ2VfbGltaXQsXG4gICAgICBbZGlyZWN0aW9uID09PSAnb2xkZXInID8gJ2lkX2x0JyA6ICdpZF9ndCddOiBsYXN0TWVzc2FnZUlkLFxuICAgIH0pO1xuICAgIHRoaXMuYWN0aXZlVGhyZWFkTWVzc2FnZXNTdWJqZWN0Lm5leHQoXG4gICAgICBhY3RpdmVDaG5hbm5lbD8uc3RhdGUudGhyZWFkc1twYXJlbnRNZXNzYWdlSWRdIHx8IFtdXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBRdWVyaWVzIHRoZSBjaGFubmVscyB3aXRoIHRoZSBnaXZlbiBmaWx0ZXJzLCBzb3J0cyBhbmQgb3B0aW9ucy4gTW9yZSBpbmZvIGFib3V0IFtjaGFubmVsIHF1ZXJ5aW5nXShodHRwczovL2dldHN0cmVhbS5pby9jaGF0L2RvY3MvamF2YXNjcmlwdC9xdWVyeV9jaGFubmVscy8/bGFuZ3VhZ2U9amF2YXNjcmlwdCkgY2FuIGJlIGZvdW5kIGluIHRoZSBwbGF0Zm9ybSBkb2N1bWVudGF0aW9uLiBCeSBkZWZhdWx0IHRoZSBmaXJzdCBjaGFubmVsIGluIHRoZSBsaXN0IHdpbGwgYmUgc2V0IGFzIGFjdGl2ZSBjaGFubmVsIGFuZCB3aWxsIGJlIG1hcmtlZCBhcyByZWFkLlxuICAgKiBAcGFyYW0gZmlsdGVyc1xuICAgKiBAcGFyYW0gc29ydFxuICAgKiBAcGFyYW0gb3B0aW9uc1xuICAgKiBAcGFyYW0gc2hvdWxkU2V0QWN0aXZlQ2hhbm5lbCBEZWNpZGVzIGlmIHRoZSBmaXJzdCBjaGFubmVsIGluIHRoZSByZXN1bHQgc2hvdWxkIGJlIG1hZGUgYXMgYW4gYWN0aXZlIGNoYW5uZWwsIG9yIG5vIGNoYW5uZWwgc2hvdWxkIGJlIG1hcmtlZCBhcyBhY3RpdmVcbiAgICogQHJldHVybnMgdGhlIGxpc3Qgb2YgY2hhbm5lbHMgZm91bmQgYnkgdGhlIHF1ZXJ5XG4gICAqL1xuICBhc3luYyBpbml0KFxuICAgIGZpbHRlcnM6IENoYW5uZWxGaWx0ZXJzPFQ+LFxuICAgIHNvcnQ/OiBDaGFubmVsU29ydDxUPixcbiAgICBvcHRpb25zPzogQ2hhbm5lbE9wdGlvbnMgJiB7IGtlZXBBbGl2ZUNoYW5uZWxzJE9uRXJyb3I/OiBib29sZWFuIH0sXG4gICAgc2hvdWxkU2V0QWN0aXZlQ2hhbm5lbDogYm9vbGVhbiA9IHRydWVcbiAgKSB7XG4gICAgdGhpcy5maWx0ZXJzID0gZmlsdGVycztcbiAgICB0aGlzLm9wdGlvbnMgPSB7XG4gICAgICBsaW1pdDogMjUsXG4gICAgICBzdGF0ZTogdHJ1ZSxcbiAgICAgIHByZXNlbmNlOiB0cnVlLFxuICAgICAgd2F0Y2g6IHRydWUsXG4gICAgICBtZXNzYWdlX2xpbWl0OiB0aGlzLm1lc3NhZ2VQYWdlU2l6ZSxcbiAgICAgIC4uLm9wdGlvbnMsXG4gICAgfTtcbiAgICB0aGlzLnNvcnQgPSBzb3J0IHx8IHsgbGFzdF9tZXNzYWdlX2F0OiAtMSB9O1xuICAgIHRoaXMuc2hvdWxkU2V0QWN0aXZlQ2hhbm5lbCA9IHNob3VsZFNldEFjdGl2ZUNoYW5uZWw7XG4gICAgdGhpcy5jbGllbnRFdmVudHNTdWJzY3JpcHRpb24gPSB0aGlzLmNoYXRDbGllbnRTZXJ2aWNlLmV2ZW50cyQuc3Vic2NyaWJlKFxuICAgICAgKG5vdGlmaWNhdGlvbikgPT4gdm9pZCB0aGlzLmhhbmRsZU5vdGlmaWNhdGlvbihub3RpZmljYXRpb24pXG4gICAgKTtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdGhpcy5xdWVyeUNoYW5uZWxzKHRoaXMuc2hvdWxkU2V0QWN0aXZlQ2hhbm5lbCk7XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICB0aGlzLmRpc21pc3NFcnJvck5vdGlmaWNhdGlvbiA9XG4gICAgICAgIHRoaXMubm90aWZpY2F0aW9uU2VydmljZS5hZGRQZXJtYW5lbnROb3RpZmljYXRpb24oXG4gICAgICAgICAgJ3N0cmVhbUNoYXQuRXJyb3IgbG9hZGluZyBjaGFubmVscycsXG4gICAgICAgICAgJ2Vycm9yJ1xuICAgICAgICApO1xuICAgICAgdGhyb3cgZXJyb3I7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJlc2V0cyB0aGUgYGFjdGl2ZUNoYW5uZWwkYCwgYGNoYW5uZWxzJGAgYW5kIGBhY3RpdmVDaGFubmVsTWVzc2FnZXMkYCBPYnNlcnZhYmxlcy4gVXNlZnVsIHdoZW4gZGlzY29ubmVjdGluZyBhIGNoYXQgdXNlciwgdXNlIGluIGNvbWJpbmF0aW9uIHdpdGggW2BkaXNjb25uZWN0VXNlcmBdKC4vQ2hhdENsaWVudFNlcnZpY2UubWR4LyNkaXNjb25uZWN0dXNlcikuXG4gICAqL1xuICByZXNldCgpIHtcbiAgICB0aGlzLmRlc2VsZWN0QWN0aXZlQ2hhbm5lbCgpO1xuICAgIHRoaXMuY2hhbm5lbHNTdWJqZWN0Lm5leHQodW5kZWZpbmVkKTtcbiAgICB0aGlzLmNoYW5uZWxRdWVyeVN0YXRlU3ViamVjdC5uZXh0KHVuZGVmaW5lZCk7XG4gICAgdGhpcy5jbGllbnRFdmVudHNTdWJzY3JpcHRpb24/LnVuc3Vic2NyaWJlKCk7XG4gICAgdGhpcy5kaXNtaXNzRXJyb3JOb3RpZmljYXRpb24/LigpO1xuICAgIHRoaXMuZGlzbWlzc0Vycm9yTm90aWZpY2F0aW9uID0gdW5kZWZpbmVkO1xuICAgIE9iamVjdC5rZXlzKHRoaXMuY2hhbm5lbFN1YnNjcmlwdGlvbnMpLmZvckVhY2goKGNpZCkgPT4ge1xuICAgICAgdGhpcy5jaGFubmVsU3Vic2NyaXB0aW9uc1tjaWRdKCk7XG4gICAgfSk7XG4gICAgdGhpcy5jaGFubmVsU3Vic2NyaXB0aW9ucyA9IHt9O1xuICAgIHRoaXMubmV4dFBhZ2VDb25maWd1cmF0aW9uID0gdW5kZWZpbmVkO1xuICB9XG5cbiAgLyoqXG4gICAqIExvYWRzIHRoZSBuZXh0IHBhZ2Ugb2YgY2hhbm5lbHMuIFRoZSBwYWdlIHNpemUgY2FuIGJlIHNldCBpbiB0aGUgW3F1ZXJ5IG9wdGlvbl0oaHR0cHM6Ly9nZXRzdHJlYW0uaW8vY2hhdC9kb2NzL2phdmFzY3JpcHQvcXVlcnlfY2hhbm5lbHMvP2xhbmd1YWdlPWphdmFzY3JpcHQjcXVlcnktb3B0aW9ucykgb2JqZWN0LlxuICAgKi9cbiAgYXN5bmMgbG9hZE1vcmVDaGFubmVscygpIHtcbiAgICBhd2FpdCB0aGlzLnF1ZXJ5Q2hhbm5lbHMoZmFsc2UpO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZHMgYSByZWFjdGlvbiB0byBhIG1lc3NhZ2UuXG4gICAqIEBwYXJhbSBtZXNzYWdlSWQgVGhlIGlkIG9mIHRoZSBtZXNzYWdlIHRvIGFkZCB0aGUgcmVhY3Rpb24gdG9cbiAgICogQHBhcmFtIHJlYWN0aW9uVHlwZSBUaGUgdHlwZSBvZiB0aGUgcmVhY3Rpb25cbiAgICogQHBhcmFtIGN1c3RvbURhdGFcbiAgICovXG4gIGFzeW5jIGFkZFJlYWN0aW9uKFxuICAgIG1lc3NhZ2VJZDogc3RyaW5nLFxuICAgIHJlYWN0aW9uVHlwZTogTWVzc2FnZVJlYWN0aW9uVHlwZSxcbiAgICBjdXN0b21EYXRhPzogVFsncmVhY3Rpb25UeXBlJ11cbiAgKSB7XG4gICAgYXdhaXQgdGhpcy5hY3RpdmVDaGFubmVsU3ViamVjdC5nZXRWYWx1ZSgpPy5zZW5kUmVhY3Rpb24obWVzc2FnZUlkLCB7XG4gICAgICB0eXBlOiByZWFjdGlvblR5cGUsXG4gICAgICAuLi5jdXN0b21EYXRhLFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlbW92ZXMgYSByZWFjdGlvbiBmcm9tIGEgbWVzc2FnZS5cbiAgICogQHBhcmFtIG1lc3NhZ2VJZCBUaGUgaWQgb2YgdGhlIG1lc3NhZ2UgdG8gcmVtb3ZlIHRoZSByZWFjdGlvbiBmcm9tXG4gICAqIEBwYXJhbSByZWFjdGlvblR5cGUgVGhyIHR5cGUgb2YgcmVhY3Rpb24gdG8gcmVtb3ZlXG4gICAqL1xuICBhc3luYyByZW1vdmVSZWFjdGlvbihtZXNzYWdlSWQ6IHN0cmluZywgcmVhY3Rpb25UeXBlOiBNZXNzYWdlUmVhY3Rpb25UeXBlKSB7XG4gICAgYXdhaXQgdGhpcy5hY3RpdmVDaGFubmVsU3ViamVjdFxuICAgICAgLmdldFZhbHVlKClcbiAgICAgID8uZGVsZXRlUmVhY3Rpb24obWVzc2FnZUlkLCByZWFjdGlvblR5cGUpO1xuICB9XG5cbiAgLyoqXG4gICAqIFNlbmRzIGEgbWVzc2FnZSB0byB0aGUgYWN0aXZlIGNoYW5uZWwuIFRoZSBtZXNzYWdlIGlzIGltbWVkaWF0ZWx5IGFkZGVkIHRvIHRoZSBtZXNzYWdlIGxpc3QsIGlmIGFuIGVycm9yIG9jY3VycyBhbmQgdGhlIG1lc3NhZ2UgY2FuJ3QgYmUgc2VudCwgdGhlIGVycm9yIGlzIGluZGljYXRlZCBpbiBgc3RhdGVgIG9mIHRoZSBtZXNzYWdlLlxuICAgKiBAcGFyYW0gdGV4dCBUaGUgdGV4dCBvZiB0aGUgbWVzc2FnZVxuICAgKiBAcGFyYW0gYXR0YWNobWVudHMgVGhlIGF0dGFjaG1lbnRzXG4gICAqIEBwYXJhbSBtZW50aW9uZWRVc2VycyBNZW50aW9uZWQgdXNlcnNcbiAgICogQHBhcmFtIHBhcmVudElkIElkIG9mIHRoZSBwYXJlbnQgbWVzc2FnZSAoaWYgc2VuZGluZyBhIHRocmVhZCByZXBseSlcbiAgICogQHBhcmFtIHF1b3RlZE1lc3NhZ2VJZCBJZCBvZiB0aGUgbWVzc2FnZSB0byBxdW90ZSAoaWYgc2VuZGluZyBhIHF1b3RlIHJlcGx5KVxuICAgKiBAcGFyYW0gY3VzdG9tRGF0YVxuICAgKi9cbiAgYXN5bmMgc2VuZE1lc3NhZ2UoXG4gICAgdGV4dDogc3RyaW5nLFxuICAgIGF0dGFjaG1lbnRzOiBBdHRhY2htZW50PFQ+W10gPSBbXSxcbiAgICBtZW50aW9uZWRVc2VyczogVXNlclJlc3BvbnNlPFQ+W10gPSBbXSxcbiAgICBwYXJlbnRJZDogc3RyaW5nIHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkLFxuICAgIHF1b3RlZE1lc3NhZ2VJZDogc3RyaW5nIHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkLFxuICAgIGN1c3RvbURhdGE6IHVuZGVmaW5lZCB8IFBhcnRpYWw8VFsnbWVzc2FnZVR5cGUnXT4gPSB1bmRlZmluZWRcbiAgKSB7XG4gICAgbGV0IGlucHV0OiBNZXNzYWdlSW5wdXQ8VD4gPSB7XG4gICAgICB0ZXh0LFxuICAgICAgYXR0YWNobWVudHMsXG4gICAgICBtZW50aW9uZWRVc2VycyxcbiAgICAgIHBhcmVudElkLFxuICAgICAgcXVvdGVkTWVzc2FnZUlkLFxuICAgICAgY3VzdG9tRGF0YSxcbiAgICB9O1xuICAgIGlmICh0aGlzLmJlZm9yZVNlbmRNZXNzYWdlKSB7XG4gICAgICBpbnB1dCA9IGF3YWl0IHRoaXMuYmVmb3JlU2VuZE1lc3NhZ2UoaW5wdXQpO1xuICAgIH1cbiAgICBjb25zdCBwcmV2aWV3ID0gY3JlYXRlTWVzc2FnZVByZXZpZXcoXG4gICAgICB0aGlzLmNoYXRDbGllbnRTZXJ2aWNlLmNoYXRDbGllbnQudXNlciEsXG4gICAgICBpbnB1dC50ZXh0LFxuICAgICAgaW5wdXQuYXR0YWNobWVudHMsXG4gICAgICBpbnB1dC5tZW50aW9uZWRVc2VycyxcbiAgICAgIGlucHV0LnBhcmVudElkLFxuICAgICAgaW5wdXQucXVvdGVkTWVzc2FnZUlkLFxuICAgICAgaW5wdXQuY3VzdG9tRGF0YVxuICAgICk7XG4gICAgY29uc3QgY2hhbm5lbCA9IHRoaXMuYWN0aXZlQ2hhbm5lbFN1YmplY3QuZ2V0VmFsdWUoKSE7XG4gICAgcHJldmlldy5yZWFkQnkgPSBbXTtcbiAgICBjaGFubmVsLnN0YXRlLmFkZE1lc3NhZ2VTb3J0ZWQocHJldmlldywgdHJ1ZSk7XG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLnNlbmRNZXNzYWdlUmVxdWVzdChwcmV2aWV3LCBpbnB1dC5jdXN0b21EYXRhKTtcbiAgICByZXR1cm4gcmVzcG9uc2U7XG4gIH1cblxuICAvKipcbiAgICogUmVzZW5kcyB0aGUgZ2l2ZW4gbWVzc2FnZSB0byB0aGUgYWN0aXZlIGNoYW5uZWxcbiAgICogQHBhcmFtIG1lc3NhZ2UgVGhlIG1lc3NhZ2UgdG8gcmVzZW5kXG4gICAqL1xuICBhc3luYyByZXNlbmRNZXNzYWdlKG1lc3NhZ2U6IFN0cmVhbU1lc3NhZ2UpIHtcbiAgICBjb25zdCBjaGFubmVsID0gdGhpcy5hY3RpdmVDaGFubmVsU3ViamVjdC5nZXRWYWx1ZSgpITtcbiAgICBjaGFubmVsLnN0YXRlLmFkZE1lc3NhZ2VTb3J0ZWQoXG4gICAgICB7XG4gICAgICAgIC4uLihtZXNzYWdlIGFzIGFueSBhcyBNZXNzYWdlUmVzcG9uc2U8VD4pLFxuICAgICAgICBlcnJvclN0YXR1c0NvZGU6IHVuZGVmaW5lZCxcbiAgICAgICAgc3RhdHVzOiAnc2VuZGluZycsXG4gICAgICB9LFxuICAgICAgdHJ1ZVxuICAgICk7XG4gICAgcmV0dXJuIHRoaXMuc2VuZE1lc3NhZ2VSZXF1ZXN0KG1lc3NhZ2UsIHVuZGVmaW5lZCwgdHJ1ZSk7XG4gIH1cblxuICAvKipcbiAgICogVXBkYXRlcyB0aGUgbWVzc2FnZSBpbiB0aGUgYWN0aXZlIGNoYW5uZWxcbiAgICogQHBhcmFtIG1lc3NhZ2UgTWVzYWdlIHRvIGJlIHVwZGF0ZWRcbiAgICovXG4gIGFzeW5jIHVwZGF0ZU1lc3NhZ2UobWVzc2FnZTogU3RyZWFtTWVzc2FnZTxUPikge1xuICAgIGxldCBtZXNzYWdlVG9VcGRhdGUgPSB7IC4uLm1lc3NhZ2UgfTtcbiAgICBkZWxldGUgbWVzc2FnZVRvVXBkYXRlLmkxOG47XG4gICAgaWYgKHRoaXMuYmVmb3JlVXBkYXRlTWVzc2FnZSkge1xuICAgICAgbWVzc2FnZVRvVXBkYXRlID0gYXdhaXQgdGhpcy5iZWZvcmVVcGRhdGVNZXNzYWdlKG1lc3NhZ2VUb1VwZGF0ZSk7XG4gICAgfVxuICAgIGlmIChtZXNzYWdlLm1vZGVyYXRpb25fZGV0YWlscykge1xuICAgICAgcmV0dXJuIHRoaXMucmVzZW5kTWVzc2FnZShtZXNzYWdlKTtcbiAgICB9XG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLmNoYXRDbGllbnRTZXJ2aWNlLmNoYXRDbGllbnQudXBkYXRlTWVzc2FnZShcbiAgICAgIG1lc3NhZ2VUb1VwZGF0ZSBhcyBhbnkgYXMgVXBkYXRlZE1lc3NhZ2U8VD5cbiAgICApO1xuXG4gICAgY29uc3QgY2hhbm5lbCA9IHRoaXMuY2hhbm5lbHNTdWJqZWN0XG4gICAgICAuZ2V0VmFsdWUoKVxuICAgICAgPy5maW5kKChjKSA9PiBjLmNpZCA9PT0gbWVzc2FnZS5jaWQpO1xuXG4gICAgaWYgKFxuICAgICAgcmVzcG9uc2UubWVzc2FnZS50eXBlID09PSAnZXJyb3InICYmXG4gICAgICByZXNwb25zZS5tZXNzYWdlLm1vZGVyYXRpb25fZGV0YWlsc1xuICAgICkge1xuICAgICAgdGhpcy5ub3RpZmljYXRpb25TZXJ2aWNlLmFkZFRlbXBvcmFyeU5vdGlmaWNhdGlvbihcbiAgICAgICAgJ3N0cmVhbUNoYXQuVGhpcyBtZXNzYWdlIGRpZCBub3QgbWVldCBvdXIgY29udGVudCBndWlkZWxpbmVzJ1xuICAgICAgKTtcbiAgICAgIHJldHVybiBtZXNzYWdlO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLnRyYW5zZm9ybVRvU3RyZWFtTWVzc2FnZShyZXNwb25zZS5tZXNzYWdlLCBjaGFubmVsKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEZWxldGVzIHRoZSBtZXNzYWdlIGZyb20gdGhlIGFjdGl2ZSBjaGFubmVsXG4gICAqIEBwYXJhbSBtZXNzYWdlIE1lc3NhZ2UgdG8gYmUgZGVsZXRlZFxuICAgKiBAcGFyYW0gaXNMb2NhbERlbGV0ZSBzZXQgdGhpcyBgdHJ1ZWAgaWYgeW91IHdhbnQgdG8gZGVsZXRlIGEgbWVzc2FnZSB0aGF0J3Mgb25seSBwYXJ0IG9mIHRoZSBsb2NhbCBzdGF0ZSwgbm90IHlldCBzYXZlZCBvbiB0aGUgYmFja2VuZFxuICAgKi9cbiAgYXN5bmMgZGVsZXRlTWVzc2FnZShtZXNzYWdlOiBTdHJlYW1NZXNzYWdlLCBpc0xvY2FsRGVsZXRlID0gZmFsc2UpIHtcbiAgICBpZiAoaXNMb2NhbERlbGV0ZSAmJiB0aGlzLmFjdGl2ZUNoYW5uZWwpIHtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IHRoaXMuYWN0aXZlQ2hhbm5lbC5zdGF0ZS5yZW1vdmVNZXNzYWdlKHtcbiAgICAgICAgaWQ6IG1lc3NhZ2UuaWQsXG4gICAgICAgIHBhcmVudF9pZDogbWVzc2FnZS5wYXJlbnRfaWQsXG4gICAgICB9KTtcbiAgICAgIGlmIChyZXN1bHQpIHtcbiAgICAgICAgbWVzc2FnZS5wYXJlbnRfaWRcbiAgICAgICAgICA/IHRoaXMuYWN0aXZlVGhyZWFkTWVzc2FnZXNTdWJqZWN0Lm5leHQoXG4gICAgICAgICAgICAgIHRoaXMuYWN0aXZlQ2hhbm5lbC5zdGF0ZS50aHJlYWRzW21lc3NhZ2UucGFyZW50X2lkXVxuICAgICAgICAgICAgKVxuICAgICAgICAgIDogdGhpcy5hY3RpdmVDaGFubmVsTWVzc2FnZXNTdWJqZWN0Lm5leHQoXG4gICAgICAgICAgICAgIHRoaXMuYWN0aXZlQ2hhbm5lbC5zdGF0ZS5tZXNzYWdlc1xuICAgICAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKHRoaXMubWVzc2FnZURlbGV0ZUNvbmZpcm1hdGlvbkhhbmRsZXIpIHtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRoaXMubWVzc2FnZURlbGV0ZUNvbmZpcm1hdGlvbkhhbmRsZXIobWVzc2FnZSk7XG4gICAgICBpZiAocmVzdWx0KSB7XG4gICAgICAgIGF3YWl0IHRoaXMuY2hhdENsaWVudFNlcnZpY2UuY2hhdENsaWVudC5kZWxldGVNZXNzYWdlKG1lc3NhZ2UuaWQpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBhd2FpdCB0aGlzLmNoYXRDbGllbnRTZXJ2aWNlLmNoYXRDbGllbnQuZGVsZXRlTWVzc2FnZShtZXNzYWdlLmlkKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogVXBsb2FkcyBmaWxlcyB0byB0aGUgY2hhbm5lbC4gSWYgeW91IHdhbnQgdG8ga25vdyBtb3JlIGFib3V0IFtmaWxlIHVwbG9hZHNdKGh0dHBzOi8vZ2V0c3RyZWFtLmlvL2NoYXQvZG9jcy9qYXZhc2NyaXB0L2ZpbGVfdXBsb2Fkcy8/bGFuZ3VhZ2U9amF2YXNjcmlwdCkgY2hlY2sgb3V0IHRoZSBwbGF0Zm9ybSBkb2N1bWVudGF0aW9uLlxuICAgKiBAcGFyYW0gdXBsb2FkcyB0aGUgYXR0YWNobWVudHMgdG8gdXBsb2FkIChvdXRwdXQgb2YgdGhlIFtgQXR0YWNobWVudFNlcnZpY2VgXSguL0F0dGFjaG1lbnRTZXJ2aWNlLm1keCkpXG4gICAqIEByZXR1cm5zIHRoZSByZXN1bHQgb2YgZmlsZSB1cGxvYWQgcmVxdWVzdHNcbiAgICovXG4gIGFzeW5jIHVwbG9hZEF0dGFjaG1lbnRzKFxuICAgIHVwbG9hZHM6IEF0dGFjaG1lbnRVcGxvYWRbXVxuICApOiBQcm9taXNlPEF0dGFjaG1lbnRVcGxvYWRbXT4ge1xuICAgIGNvbnN0IHJlc3VsdDogQXR0YWNobWVudFVwbG9hZFtdID0gW107XG4gICAgY29uc3QgY2hhbm5lbCA9IHRoaXMuYWN0aXZlQ2hhbm5lbFN1YmplY3QuZ2V0VmFsdWUoKSE7XG4gICAgY29uc3QgdXBsb2FkUmVzdWx0cyA9IGF3YWl0IFByb21pc2UuYWxsU2V0dGxlZChcbiAgICAgIHVwbG9hZHMubWFwKCh1cGxvYWQpID0+XG4gICAgICAgIHVwbG9hZC50eXBlID09PSAnaW1hZ2UnXG4gICAgICAgICAgPyB0aGlzLmN1c3RvbUltYWdlVXBsb2FkUmVxdWVzdFxuICAgICAgICAgICAgPyB0aGlzLmN1c3RvbUltYWdlVXBsb2FkUmVxdWVzdCh1cGxvYWQuZmlsZSwgY2hhbm5lbClcbiAgICAgICAgICAgIDogY2hhbm5lbC5zZW5kSW1hZ2UodXBsb2FkLmZpbGUsIHVwbG9hZC5maWxlLm5hbWUsIHVwbG9hZC5maWxlLnR5cGUpXG4gICAgICAgICAgOiB0aGlzLmN1c3RvbUZpbGVVcGxvYWRSZXF1ZXN0XG4gICAgICAgICAgPyB0aGlzLmN1c3RvbUZpbGVVcGxvYWRSZXF1ZXN0KHVwbG9hZC5maWxlLCBjaGFubmVsKVxuICAgICAgICAgIDogY2hhbm5lbC5zZW5kRmlsZSh1cGxvYWQuZmlsZSwgdXBsb2FkLmZpbGUubmFtZSwgdXBsb2FkLmZpbGUudHlwZSlcbiAgICAgIClcbiAgICApO1xuICAgIHVwbG9hZFJlc3VsdHMuZm9yRWFjaCgodXBsb2FkUmVzdWx0LCBpKSA9PiB7XG4gICAgICBjb25zdCBmaWxlID0gdXBsb2Fkc1tpXS5maWxlO1xuICAgICAgY29uc3QgdHlwZSA9IHVwbG9hZHNbaV0udHlwZTtcbiAgICAgIGlmICh1cGxvYWRSZXN1bHQuc3RhdHVzID09PSAnZnVsZmlsbGVkJykge1xuICAgICAgICByZXN1bHQucHVzaCh7XG4gICAgICAgICAgZmlsZSxcbiAgICAgICAgICB0eXBlLFxuICAgICAgICAgIHN0YXRlOiAnc3VjY2VzcycsXG4gICAgICAgICAgdXJsOiB1cGxvYWRSZXN1bHQudmFsdWUuZmlsZSxcbiAgICAgICAgICAvKiBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVuc2FmZS1hc3NpZ25tZW50LCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW5zYWZlLW1lbWJlci1hY2Nlc3MgKi9cbiAgICAgICAgICB0aHVtYl91cmw6ICh1cGxvYWRSZXN1bHQudmFsdWUgYXMgYW55KS50aHVtYl91cmwsXG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbGV0IHJlYXNvbjogQXR0YWNobWVudFVwbG9hZEVycm9yUmVhc29uID0gJ3Vua25vd24nO1xuICAgICAgICBsZXQgZXh0cmFEYXRhOiB7IHBhcmFtOiBzdHJpbmcgfSB8IHVuZGVmaW5lZDtcbiAgICAgICAgLyogZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnNhZmUtYXNzaWdubWVudCAqL1xuICAgICAgICBjb25zdCBtZXNzYWdlOiBzdHJpbmcgfCB1bmRlZmluZWQgPVxuICAgICAgICAgIC8qIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW5zYWZlLW1lbWJlci1hY2Nlc3MgKi9cbiAgICAgICAgICB1cGxvYWRSZXN1bHQucmVhc29uLnJlc3BvbnNlPy5kYXRhPy5tZXNzYWdlO1xuICAgICAgICAvKiBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVuc2FmZS1hc3NpZ25tZW50ICovXG4gICAgICAgIGNvbnN0IGNvZGU6IG51bWJlciB8IHVuZGVmaW5lZCA9XG4gICAgICAgICAgLyogZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnNhZmUtbWVtYmVyLWFjY2VzcyAqL1xuICAgICAgICAgIHVwbG9hZFJlc3VsdC5yZWFzb24ucmVzcG9uc2U/LmRhdGE/LmNvZGU7XG4gICAgICAgIGlmIChjb2RlID09PSAyMikge1xuICAgICAgICAgIHJlYXNvbiA9ICdmaWxlLXNpemUnO1xuICAgICAgICAgIGV4dHJhRGF0YSA9IHsgcGFyYW06IC9cXGQrTUIvLmV4ZWMobWVzc2FnZSB8fCAnJyk/LlswXSB8fCAnMTAwTUInIH07XG4gICAgICAgIH0gZWxzZSBpZiAoXG4gICAgICAgICAgY29kZSA9PT0gNCAmJlxuICAgICAgICAgIG1lc3NhZ2U/LnRvTG93ZXJDYXNlKCk/LmluY2x1ZGVzKCdmaWxlIGV4dGVuc2lvbicpXG4gICAgICAgICkge1xuICAgICAgICAgIHJlYXNvbiA9ICdmaWxlLWV4dGVuc2lvbic7XG4gICAgICAgICAgZXh0cmFEYXRhID0geyBwYXJhbTogL1xcLlxcdysvLmV4ZWMobWVzc2FnZSk/LlswXSB8fCAnJyB9O1xuICAgICAgICB9XG4gICAgICAgIHJlc3VsdC5wdXNoKHtcbiAgICAgICAgICBmaWxlLFxuICAgICAgICAgIHR5cGUsXG4gICAgICAgICAgc3RhdGU6ICdlcnJvcicsXG4gICAgICAgICAgZXJyb3JSZWFzb246IHJlYXNvbixcbiAgICAgICAgICBlcnJvckV4dHJhSW5mbzogZXh0cmFEYXRhID8gW2V4dHJhRGF0YV0gOiB1bmRlZmluZWQsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIC8qKlxuICAgKiBEZWxldGVzIGFuIHVwbG9hZGVkIGZpbGUgYnkgVVJMLiBJZiB5b3Ugd2FudCB0byBrbm93IG1vcmUgYWJvdXQgW2ZpbGUgdXBsb2Fkc10oaHR0cHM6Ly9nZXRzdHJlYW0uaW8vY2hhdC9kb2NzL2phdmFzY3JpcHQvZmlsZV91cGxvYWRzLz9sYW5ndWFnZT1qYXZhc2NyaXB0KSBjaGVjayBvdXQgdGhlIHBsYXRmb3JtIGRvY3VtZW50YXRpb25cbiAgICogQHBhcmFtIGF0dGFjaG1lbnRVcGxvYWQgQXR0YWNobWVudCB0byBiZSBkZWxldGVkIChvdXRwdXQgb2YgdGhlIFtgQXR0YWNobWVudFNlcnZpY2VgXSguL0F0dGFjaG1lbnRTZXJ2aWNlLm1keCkpXG4gICAqL1xuICBhc3luYyBkZWxldGVBdHRhY2htZW50KGF0dGFjaG1lbnRVcGxvYWQ6IEF0dGFjaG1lbnRVcGxvYWQpIHtcbiAgICBjb25zdCBjaGFubmVsID0gdGhpcy5hY3RpdmVDaGFubmVsU3ViamVjdC5nZXRWYWx1ZSgpITtcbiAgICBhd2FpdCAoYXR0YWNobWVudFVwbG9hZC50eXBlID09PSAnaW1hZ2UnXG4gICAgICA/IHRoaXMuY3VzdG9tSW1hZ2VEZWxldGVSZXF1ZXN0XG4gICAgICAgID8gdGhpcy5jdXN0b21JbWFnZURlbGV0ZVJlcXVlc3QoYXR0YWNobWVudFVwbG9hZC51cmwhLCBjaGFubmVsKVxuICAgICAgICA6IGNoYW5uZWwuZGVsZXRlSW1hZ2UoYXR0YWNobWVudFVwbG9hZC51cmwhKVxuICAgICAgOiB0aGlzLmN1c3RvbUZpbGVEZWxldGVSZXF1ZXN0XG4gICAgICA/IHRoaXMuY3VzdG9tRmlsZURlbGV0ZVJlcXVlc3QoYXR0YWNobWVudFVwbG9hZC51cmwhLCBjaGFubmVsKVxuICAgICAgOiBjaGFubmVsLmRlbGV0ZUZpbGUoYXR0YWNobWVudFVwbG9hZC51cmwhKSk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgYXV0b2NvbXBsZXRlIG9wdGlvbnMgZm9yIGN1cnJlbnQgY2hhbm5lbCBtZW1iZXJzLiBJZiB0aGUgY2hhbm5lbCBoYXMgbGVzcyB0aGFuIDEwMCBtZW1iZXJzLCBpdCByZXR1cm5zIHRoZSBjaGFubmVsIG1lbWJlcnMsIG90aGVyd2lzZSBzZW5kcyBhIFtzZWFyY2ggcmVxdWVzdF0oaHR0cHM6Ly9nZXRzdHJlYW0uaW8vY2hhdC9kb2NzL2phdmFzY3JpcHQvcXVlcnlfbWVtYmVycy8/bGFuZ3VhZ2U9amF2YXNjcmlwdCNwYWdpbmF0aW9uLWFuZC1vcmRlcmluZykgd2l0aCB0aGUgZ2l2ZW4gc2VhcmNoIHRlcm0uXG4gICAqIEBwYXJhbSBzZWFyY2hUZXJtIFRleHQgdG8gc2VhcmNoIGZvciBpbiB0aGUgbmFtZXMgb2YgbWVtYmVyc1xuICAgKiBAcmV0dXJucyBUaGUgbGlzdCBvZiBtZW1iZXJzIG1hdGNoaW5nIHRoZSBzZWFyY2ggZmlsdGVyXG4gICAqL1xuICBhc3luYyBhdXRvY29tcGxldGVNZW1iZXJzKHNlYXJjaFRlcm06IHN0cmluZykge1xuICAgIGNvbnN0IGFjdGl2ZUNoYW5uZWwgPSB0aGlzLmFjdGl2ZUNoYW5uZWxTdWJqZWN0LmdldFZhbHVlKCk7XG4gICAgaWYgKCFhY3RpdmVDaGFubmVsKSB7XG4gICAgICByZXR1cm4gW107XG4gICAgfVxuICAgIGlmIChPYmplY3Qua2V5cyhhY3RpdmVDaGFubmVsLnN0YXRlLm1lbWJlcnMpLmxlbmd0aCA8IDEwMCkge1xuICAgICAgcmV0dXJuIE9iamVjdC52YWx1ZXMoYWN0aXZlQ2hhbm5lbC5zdGF0ZS5tZW1iZXJzKS5maWx0ZXIoXG4gICAgICAgIChtKSA9PiBtLnVzZXI/LmlkICE9PSB0aGlzLmNoYXRDbGllbnRTZXJ2aWNlLmNoYXRDbGllbnQudXNlcklEIVxuICAgICAgKTtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKCFzZWFyY2hUZXJtKSB7XG4gICAgICAgIHJldHVybiBbXTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGFjdGl2ZUNoYW5uZWwucXVlcnlNZW1iZXJzKHtcbiAgICAgICAgbmFtZTogeyAkYXV0b2NvbXBsZXRlOiBzZWFyY2hUZXJtIH0sXG4gICAgICAgIGlkOiB7ICRuZTogdGhpcy5jaGF0Q2xpZW50U2VydmljZS5jaGF0Q2xpZW50LnVzZXJJRCEgfSxcbiAgICAgIH0gYXMgVXNlckZpbHRlcnM8VD4pOyAvLyBUT0RPOiBmaW5kIG91dCB3aHkgd2UgbmVlZCB0eXBlY2FzdCBoZXJlXG4gICAgICByZXR1cm4gT2JqZWN0LnZhbHVlcyhyZXN1bHQubWVtYmVycyk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFtSdW5zIGEgbWVzc2FnZSBhY3Rpb25dKGh0dHBzOi8vZ2V0c3RyZWFtLmlvL2NoYXQvZG9jcy9yZXN0LyNtZXNzYWdlcy1ydW5tZXNzYWdlYWN0aW9uKSBpbiB0aGUgY3VycmVudCBjaGFubmVsLiBVcGRhdGVzIHRoZSBtZXNzYWdlIGxpc3QgYmFzZWQgb24gdGhlIGFjdGlvbiByZXN1bHQgKGlmIG5vIG1lc3NhZ2UgaXMgcmV0dXJuZWQsIHRoZSBtZXNzYWdlIHdpbGwgYmUgcmVtb3ZlZCBmcm9tIHRoZSBtZXNzYWdlIGxpc3QpLlxuICAgKiBAcGFyYW0gbWVzc2FnZUlkXG4gICAqIEBwYXJhbSBmb3JtRGF0YVxuICAgKiBAcGFyYW0gcGFyZW50TWVzc2FnZUlkXG4gICAqL1xuICBhc3luYyBzZW5kQWN0aW9uKFxuICAgIG1lc3NhZ2VJZDogc3RyaW5nLFxuICAgIGZvcm1EYXRhOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+LFxuICAgIHBhcmVudE1lc3NhZ2VJZD86IHN0cmluZ1xuICApIHtcbiAgICBjb25zdCBjaGFubmVsID0gdGhpcy5hY3RpdmVDaGFubmVsU3ViamVjdC5nZXRWYWx1ZSgpITtcbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGNoYW5uZWwuc2VuZEFjdGlvbihtZXNzYWdlSWQsIGZvcm1EYXRhKTtcbiAgICBpZiAocmVzcG9uc2U/Lm1lc3NhZ2UpIHtcbiAgICAgIGNoYW5uZWwuc3RhdGUuYWRkTWVzc2FnZVNvcnRlZCh7XG4gICAgICAgIC4uLnJlc3BvbnNlLm1lc3NhZ2UsXG4gICAgICAgIHN0YXR1czogJ3JlY2VpdmVkJyxcbiAgICAgIH0pO1xuICAgICAgY29uc3QgaXNUaHJlYWRSZXBseSA9ICEhcmVzcG9uc2UubWVzc2FnZS5wYXJlbnRfaWQ7XG4gICAgICBpc1RocmVhZFJlcGx5XG4gICAgICAgID8gdGhpcy5hY3RpdmVUaHJlYWRNZXNzYWdlc1N1YmplY3QubmV4dChbXG4gICAgICAgICAgICAuLi5jaGFubmVsLnN0YXRlLnRocmVhZHNbcmVzcG9uc2UubWVzc2FnZS5wYXJlbnRfaWQhXSxcbiAgICAgICAgICBdKVxuICAgICAgICA6IHRoaXMuYWN0aXZlQ2hhbm5lbE1lc3NhZ2VzU3ViamVjdC5uZXh0KFsuLi5jaGFubmVsLnN0YXRlLm1lc3NhZ2VzXSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNoYW5uZWwuc3RhdGUucmVtb3ZlTWVzc2FnZSh7XG4gICAgICAgIGlkOiBtZXNzYWdlSWQsXG4gICAgICAgIHBhcmVudF9pZDogcGFyZW50TWVzc2FnZUlkLFxuICAgICAgfSk7XG4gICAgICBpZiAocGFyZW50TWVzc2FnZUlkKSB7XG4gICAgICAgIHRoaXMuYWN0aXZlVGhyZWFkTWVzc2FnZXNTdWJqZWN0Lm5leHQoXG4gICAgICAgICAgY2hhbm5lbC5zdGF0ZS50aHJlYWRzW3RoaXMuYWN0aXZlUGFyZW50TWVzc2FnZUlkU3ViamVjdC5nZXRWYWx1ZSgpIV1cbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuYWN0aXZlQ2hhbm5lbE1lc3NhZ2VzU3ViamVjdC5uZXh0KFsuLi5jaGFubmVsLnN0YXRlLm1lc3NhZ2VzXSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFNlbGVjdHMgb3IgZGVzZWxlY3RzIHRoZSBjdXJyZW50IG1lc3NhZ2UgdG8gcXVvdGUgcmVwbHkgdG9cbiAgICogQHBhcmFtIG1lc3NhZ2UgVGhlIG1lc3NhZ2UgdG8gc2VsZWN0LCBpZiBjYWxsZWQgd2l0aCBgdW5kZWZpbmVkYCwgaXQgZGVzZWxlY3RzIHRoZSBtZXNzYWdlXG4gICAqL1xuICBzZWxlY3RNZXNzYWdlVG9RdW90ZShtZXNzYWdlOiBTdHJlYW1NZXNzYWdlIHwgdW5kZWZpbmVkKSB7XG4gICAgdGhpcy5tZXNzYWdlVG9RdW90ZVN1YmplY3QubmV4dChtZXNzYWdlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBZGQgYSBuZXcgY2hhbm5lbCB0byB0aGUgY2hhbm5lbCBsaXN0XG4gICAqIFRoZSBjaGFubmVsIHdpbGwgYmUgYWRkZWQgdG8gdGhlIGJlZ2lubmluZyBvZiB0aGUgY2hhbm5lbCBsaXN0XG4gICAqIEBwYXJhbSBjaGFubmVsXG4gICAqL1xuICBhZGRDaGFubmVsKGNoYW5uZWw6IENoYW5uZWw8VD4pIHtcbiAgICBpZiAoIXRoaXMuY2hhbm5lbHMuZmluZCgoYykgPT4gYy5jaWQgPT09IGNoYW5uZWwuY2lkKSkge1xuICAgICAgdGhpcy5jaGFubmVsc1N1YmplY3QubmV4dChbY2hhbm5lbCwgLi4udGhpcy5jaGFubmVsc10pO1xuICAgICAgdGhpcy53YXRjaEZvckNoYW5uZWxFdmVudHMoY2hhbm5lbCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBzZW5kTWVzc2FnZVJlcXVlc3QoXG4gICAgcHJldmlldzogTWVzc2FnZVJlc3BvbnNlPFQ+IHwgU3RyZWFtTWVzc2FnZTxUPixcbiAgICBjdXN0b21EYXRhPzogUGFydGlhbDxUWydtZXNzYWdlVHlwZSddPixcbiAgICBpc1Jlc2VuZCA9IGZhbHNlXG4gICkge1xuICAgIGNvbnN0IGNoYW5uZWwgPSB0aGlzLmFjdGl2ZUNoYW5uZWxTdWJqZWN0LmdldFZhbHVlKCkhO1xuICAgIGNvbnN0IGlzVGhyZWFkUmVwbHkgPSAhIXByZXZpZXcucGFyZW50X2lkO1xuICAgIGlzVGhyZWFkUmVwbHlcbiAgICAgID8gdGhpcy5hY3RpdmVUaHJlYWRNZXNzYWdlc1N1YmplY3QubmV4dChbXG4gICAgICAgICAgLi4uY2hhbm5lbC5zdGF0ZS50aHJlYWRzW3ByZXZpZXcucGFyZW50X2lkIV0sXG4gICAgICAgIF0pXG4gICAgICA6IHRoaXMuYWN0aXZlQ2hhbm5lbE1lc3NhZ2VzU3ViamVjdC5uZXh0KFsuLi5jaGFubmVsLnN0YXRlLm1lc3NhZ2VzXSk7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgY2hhbm5lbC5zZW5kTWVzc2FnZSh7XG4gICAgICAgIGlkOiBwcmV2aWV3LmlkLFxuICAgICAgICB0ZXh0OiBwcmV2aWV3LnRleHQsXG4gICAgICAgIGF0dGFjaG1lbnRzOiBwcmV2aWV3LmF0dGFjaG1lbnRzLFxuICAgICAgICBtZW50aW9uZWRfdXNlcnM6IHByZXZpZXcubWVudGlvbmVkX3VzZXJzPy5tYXAoKHUpID0+IHUuaWQpLFxuICAgICAgICBwYXJlbnRfaWQ6IHByZXZpZXcucGFyZW50X2lkLFxuICAgICAgICBxdW90ZWRfbWVzc2FnZV9pZDogcHJldmlldy5xdW90ZWRfbWVzc2FnZV9pZCxcbiAgICAgICAgLi4uY3VzdG9tRGF0YSxcbiAgICAgIH0gYXMgTWVzc2FnZTxUPik7IC8vIFRPRE86IGZpbmQgb3V0IHdoeSB3ZSBuZWVkIHR5cGVjYXN0IGhlcmVcbiAgICAgIGNoYW5uZWwuc3RhdGUuYWRkTWVzc2FnZVNvcnRlZChcbiAgICAgICAge1xuICAgICAgICAgIC4uLnJlc3BvbnNlLm1lc3NhZ2UsXG4gICAgICAgICAgc3RhdHVzOiAncmVjZWl2ZWQnLFxuICAgICAgICB9LFxuICAgICAgICB0cnVlXG4gICAgICApO1xuICAgICAgaXNUaHJlYWRSZXBseVxuICAgICAgICA/IHRoaXMuYWN0aXZlVGhyZWFkTWVzc2FnZXNTdWJqZWN0Lm5leHQoW1xuICAgICAgICAgICAgLi4uY2hhbm5lbC5zdGF0ZS50aHJlYWRzW3ByZXZpZXcucGFyZW50X2lkIV0sXG4gICAgICAgICAgXSlcbiAgICAgICAgOiB0aGlzLmFjdGl2ZUNoYW5uZWxNZXNzYWdlc1N1YmplY3QubmV4dChbLi4uY2hhbm5lbC5zdGF0ZS5tZXNzYWdlc10pO1xuICAgICAgbGV0IG1lc3NhZ2VzITogU3RyZWFtTWVzc2FnZTxUPltdO1xuICAgICAgKGlzVGhyZWFkUmVwbHkgPyB0aGlzLmFjdGl2ZVRocmVhZE1lc3NhZ2VzJCA6IHRoaXMuYWN0aXZlQ2hhbm5lbE1lc3NhZ2VzJClcbiAgICAgICAgLnBpcGUodGFrZSgxKSlcbiAgICAgICAgLnN1YnNjcmliZSgobSkgPT4gKG1lc3NhZ2VzID0gbSkpO1xuICAgICAgY29uc3QgbmV3TWVzc2FnZSA9IG1lc3NhZ2VzW21lc3NhZ2VzLmxlbmd0aCAtIDFdITtcbiAgICAgIHJldHVybiBuZXdNZXNzYWdlO1xuICAgIH0gY2F0Y2ggKGVycm9yOiBhbnkpIHtcbiAgICAgIGNvbnN0IHN0cmluZ0Vycm9yID0gSlNPTi5zdHJpbmdpZnkoZXJyb3IpO1xuICAgICAgY29uc3QgcGFyc2VkRXJyb3I6IHtcbiAgICAgICAgc3RhdHVzPzogbnVtYmVyO1xuICAgICAgICBjb2RlPzogbnVtYmVyO1xuICAgICAgICByZXNwb25zZT86IHsgZGF0YT86IHsgbWVzc2FnZT86IHN0cmluZyB9IH07XG4gICAgICB9ID0gc3RyaW5nRXJyb3IgPyAoSlNPTi5wYXJzZShzdHJpbmdFcnJvcikgYXMgeyBzdGF0dXM/OiBudW1iZXIgfSkgOiB7fTtcblxuICAgICAgbGV0IGlzQWxyZWFkeUV4aXN0cyA9IGZhbHNlO1xuICAgICAgaWYgKGlzUmVzZW5kKSB7XG4gICAgICAgIGlmIChcbiAgICAgICAgICBwYXJzZWRFcnJvci5zdGF0dXMgPT09IDQwMCAmJlxuICAgICAgICAgIHBhcnNlZEVycm9yLmNvZGUgPT09IDQgJiZcbiAgICAgICAgICBwYXJzZWRFcnJvcj8ucmVzcG9uc2U/LmRhdGE/Lm1lc3NhZ2U/LmluY2x1ZGVzKCdhbHJlYWR5IGV4aXN0cycpXG4gICAgICAgICkge1xuICAgICAgICAgIGlzQWxyZWFkeUV4aXN0cyA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgY2hhbm5lbC5zdGF0ZS5hZGRNZXNzYWdlU29ydGVkKFxuICAgICAgICB7XG4gICAgICAgICAgLi4uKHByZXZpZXcgYXMgTWVzc2FnZVJlc3BvbnNlPFQ+KSxcbiAgICAgICAgICBlcnJvclN0YXR1c0NvZGU6IGlzQWxyZWFkeUV4aXN0c1xuICAgICAgICAgICAgPyB1bmRlZmluZWRcbiAgICAgICAgICAgIDogcGFyc2VkRXJyb3Iuc3RhdHVzIHx8IHVuZGVmaW5lZCxcbiAgICAgICAgICBzdGF0dXM6IGlzQWxyZWFkeUV4aXN0cyA/ICdyZWNlaXZlZCcgOiAnZmFpbGVkJyxcbiAgICAgICAgfSxcbiAgICAgICAgdHJ1ZVxuICAgICAgKTtcbiAgICAgIGlzVGhyZWFkUmVwbHlcbiAgICAgICAgPyB0aGlzLmFjdGl2ZVRocmVhZE1lc3NhZ2VzU3ViamVjdC5uZXh0KFtcbiAgICAgICAgICAgIC4uLmNoYW5uZWwuc3RhdGUudGhyZWFkc1twcmV2aWV3LnBhcmVudF9pZCFdLFxuICAgICAgICAgIF0pXG4gICAgICAgIDogdGhpcy5hY3RpdmVDaGFubmVsTWVzc2FnZXNTdWJqZWN0Lm5leHQoWy4uLmNoYW5uZWwuc3RhdGUubWVzc2FnZXNdKTtcbiAgICAgIGxldCBtZXNzYWdlcyE6IFN0cmVhbU1lc3NhZ2U8VD5bXTtcbiAgICAgIChpc1RocmVhZFJlcGx5ID8gdGhpcy5hY3RpdmVUaHJlYWRNZXNzYWdlcyQgOiB0aGlzLmFjdGl2ZUNoYW5uZWxNZXNzYWdlcyQpXG4gICAgICAgIC5waXBlKHRha2UoMSkpXG4gICAgICAgIC5zdWJzY3JpYmUoKG0pID0+IChtZXNzYWdlcyA9IG0pKTtcbiAgICAgIGNvbnN0IG5ld01lc3NhZ2UgPSBtZXNzYWdlc1ttZXNzYWdlcy5sZW5ndGggLSAxXSE7XG4gICAgICByZXR1cm4gbmV3TWVzc2FnZTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogSnVtcHMgdG8gdGhlIHNlbGVjdGVkIG1lc3NhZ2UgaW5zaWRlIHRoZSBtZXNzYWdlIGxpc3QsIGlmIHRoZSBtZXNzYWdlIGlzIG5vdCB5ZXQgbG9hZGVkLCBpdCdsbCBsb2FkIHRoZSBtZXNzYWdlIChhbmQgaXQncyBzdXJyb3VuZGluZ3MpIGZyb20gdGhlIEFQSS5cbiAgICogQHBhcmFtIG1lc3NhZ2VJZCBUaGUgSUQgb2YgdGhlIG1lc3NhZ2UgdG8gYmUgbG9hZGVkLCAnbGF0ZXN0JyBtZWFucyBqdW1wIHRvIHRoZSBsYXRlc3QgbWVzc2FnZXNcbiAgICogQHBhcmFtIHBhcmVudE1lc3NhZ2VJZCBUaGUgSUQgb2YgdGhlIHBhcmVudCBtZXNzYWdlIGlmIHdlIHdhbnQgdG8gbG9hZCBhIHRocmVhZCBtZXNzYWdlXG4gICAqL1xuICBhc3luYyBqdW1wVG9NZXNzYWdlKG1lc3NhZ2VJZDogc3RyaW5nLCBwYXJlbnRNZXNzYWdlSWQ/OiBzdHJpbmcpIHtcbiAgICBjb25zdCBhY3RpdmVDaGFubmVsID0gdGhpcy5hY3RpdmVDaGFubmVsU3ViamVjdC5nZXRWYWx1ZSgpO1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCBhY3RpdmVDaGFubmVsPy5zdGF0ZS5sb2FkTWVzc2FnZUludG9TdGF0ZShcbiAgICAgICAgbWVzc2FnZUlkLFxuICAgICAgICBwYXJlbnRNZXNzYWdlSWRcbiAgICAgICk7XG4gICAgICBjb25zdCBtZXNzYWdlcyA9IGFjdGl2ZUNoYW5uZWw/LnN0YXRlLm1lc3NhZ2VzIHx8IFtdO1xuICAgICAgdGhpcy5hY3RpdmVDaGFubmVsTWVzc2FnZXNTdWJqZWN0Lm5leHQoWy4uLm1lc3NhZ2VzXSk7XG4gICAgICBpZiAocGFyZW50TWVzc2FnZUlkKSB7XG4gICAgICAgIGNvbnN0IHBhcmVudE1lc3NhZ2UgPSBtZXNzYWdlcy5maW5kKChtKSA9PiBtLmlkID09PSBwYXJlbnRNZXNzYWdlSWQpO1xuICAgICAgICB2b2lkIHRoaXMuc2V0QXNBY3RpdmVQYXJlbnRNZXNzYWdlKHBhcmVudE1lc3NhZ2UsICdzdGF0ZScpO1xuICAgICAgfVxuICAgICAgdGhpcy5qdW1wVG9NZXNzYWdlU3ViamVjdC5uZXh0KHtcbiAgICAgICAgaWQ6IG1lc3NhZ2VJZCxcbiAgICAgICAgcGFyZW50SWQ6IHBhcmVudE1lc3NhZ2VJZCxcbiAgICAgIH0pO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICB0aGlzLm5vdGlmaWNhdGlvblNlcnZpY2UuYWRkVGVtcG9yYXJ5Tm90aWZpY2F0aW9uKFxuICAgICAgICAnc3RyZWFtQ2hhdC5NZXNzYWdlIG5vdCBmb3VuZCdcbiAgICAgICk7XG4gICAgICB0aHJvdyBlcnJvcjtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUGlucyB0aGUgZ2l2ZW4gbWVzc2FnZSBpbiB0aGUgY2hhbm5lbFxuICAgKiBAcGFyYW0gbWVzc2FnZVxuICAgKi9cbiAgYXN5bmMgcGluTWVzc2FnZShtZXNzYWdlOiBTdHJlYW1NZXNzYWdlPERlZmF1bHRTdHJlYW1DaGF0R2VuZXJpY3M+KSB7XG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IHRoaXMuY2hhdENsaWVudFNlcnZpY2UuY2hhdENsaWVudD8ucGluTWVzc2FnZShtZXNzYWdlKTtcbiAgICAgIHRoaXMubm90aWZpY2F0aW9uU2VydmljZS5hZGRUZW1wb3JhcnlOb3RpZmljYXRpb24oXG4gICAgICAgICdzdHJlYW1DaGF0Lk1lc3NhZ2UgcGlubmVkJyxcbiAgICAgICAgJ3N1Y2Nlc3MnXG4gICAgICApO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICB0aGlzLm5vdGlmaWNhdGlvblNlcnZpY2UuYWRkVGVtcG9yYXJ5Tm90aWZpY2F0aW9uKFxuICAgICAgICAnc3RyZWFtQ2hhdC5FcnJvciBwaW5uaW5nIG1lc3NhZ2UnXG4gICAgICApO1xuICAgICAgdGhyb3cgZXJyb3I7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJlbW92ZXMgdGhlIGdpdmVuIG1lc3NhZ2UgZnJvbSBwaW5uZWQgbWVzc2FnZXNcbiAgICogQHBhcmFtIG1lc3NhZ2VcbiAgICovXG4gIGFzeW5jIHVucGluTWVzc2FnZShtZXNzYWdlOiBTdHJlYW1NZXNzYWdlPERlZmF1bHRTdHJlYW1DaGF0R2VuZXJpY3M+KSB7XG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IHRoaXMuY2hhdENsaWVudFNlcnZpY2UuY2hhdENsaWVudD8udW5waW5NZXNzYWdlKG1lc3NhZ2UpO1xuICAgICAgdGhpcy5ub3RpZmljYXRpb25TZXJ2aWNlLmFkZFRlbXBvcmFyeU5vdGlmaWNhdGlvbihcbiAgICAgICAgJ3N0cmVhbUNoYXQuTWVzc2FnZSB1bnBpbm5lZCcsXG4gICAgICAgICdzdWNjZXNzJ1xuICAgICAgKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgdGhpcy5ub3RpZmljYXRpb25TZXJ2aWNlLmFkZFRlbXBvcmFyeU5vdGlmaWNhdGlvbihcbiAgICAgICAgJ3N0cmVhbUNoYXQuRXJyb3IgcmVtb3ZpbmcgbWVzc2FnZSBwaW4nXG4gICAgICApO1xuICAgICAgdGhyb3cgZXJyb3I7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBoYW5kbGVOb3RpZmljYXRpb24oY2xpZW50RXZlbnQ6IENsaWVudEV2ZW50PFQ+KSB7XG4gICAgc3dpdGNoIChjbGllbnRFdmVudC5ldmVudFR5cGUpIHtcbiAgICAgIGNhc2UgJ2Nvbm5lY3Rpb24ucmVjb3ZlcmVkJzoge1xuICAgICAgICB2b2lkIHRoaXMubmdab25lLnJ1bihhc3luYyAoKSA9PiB7XG4gICAgICAgICAgaWYgKHRoaXMuaXNTdGF0ZVJlY292ZXJ5SW5Qcm9ncmVzcykge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cbiAgICAgICAgICB0aGlzLmlzU3RhdGVSZWNvdmVyeUluUHJvZ3Jlc3MgPSB0cnVlO1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICB0aGlzLm5leHRQYWdlQ29uZmlndXJhdGlvbiA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIC8vIElmIGNoYW5uZWwgbGlzdCBpcyBub3QgaW5pdGVkLCB3ZSBzZXQgdGhlIGFjdGl2ZSBjaGFubmVsXG4gICAgICAgICAgICBjb25zdCBzaG91bFNldEFjdGl2ZUNoYW5uZWwgPVxuICAgICAgICAgICAgICB0aGlzLnNob3VsZFNldEFjdGl2ZUNoYW5uZWwgJiZcbiAgICAgICAgICAgICAgIXRoaXMuYWN0aXZlQ2hhbm5lbFN1YmplY3QuZ2V0VmFsdWUoKTtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMucXVlcnlDaGFubmVscyhzaG91bFNldEFjdGl2ZUNoYW5uZWwgfHwgZmFsc2UsIHRydWUpO1xuICAgICAgICAgICAgaWYgKHRoaXMuYWN0aXZlQ2hhbm5lbFN1YmplY3QuZ2V0VmFsdWUoKSkge1xuICAgICAgICAgICAgICAvLyBUaHJlYWQgbWVzc2FnZXMgYXJlIG5vdCByZWZldGNoZWQgc28gYWN0aXZlIHRocmVhZCBnZXRzIGRlc2VsZWN0ZWQgdG8gYXZvaWQgZGlzcGxheWluZyBzdGFsZSBtZXNzYWdlc1xuICAgICAgICAgICAgICB2b2lkIHRoaXMuc2V0QXNBY3RpdmVQYXJlbnRNZXNzYWdlKHVuZGVmaW5lZCk7XG4gICAgICAgICAgICAgIC8vIFVwZGF0ZSBhbmQgcmVzZWxlY3QgbWVzc2FnZSB0byBxdW90ZVxuICAgICAgICAgICAgICBjb25zdCBtZXNzYWdlVG9RdW90ZSA9IHRoaXMubWVzc2FnZVRvUXVvdGVTdWJqZWN0LmdldFZhbHVlKCk7XG4gICAgICAgICAgICAgIHRoaXMuc2V0Q2hhbm5lbFN0YXRlKHRoaXMuYWN0aXZlQ2hhbm5lbFN1YmplY3QuZ2V0VmFsdWUoKSEpO1xuICAgICAgICAgICAgICBsZXQgbWVzc2FnZXMhOiBTdHJlYW1NZXNzYWdlPFQ+W107XG4gICAgICAgICAgICAgIHRoaXMuYWN0aXZlQ2hhbm5lbE1lc3NhZ2VzJFxuICAgICAgICAgICAgICAgIC5waXBlKHRha2UoMSkpXG4gICAgICAgICAgICAgICAgLnN1YnNjcmliZSgobSkgPT4gKG1lc3NhZ2VzID0gbSkpO1xuICAgICAgICAgICAgICBjb25zdCB1cGRhdGVkTWVzc2FnZVRvUXVvdGUgPSBtZXNzYWdlcy5maW5kKFxuICAgICAgICAgICAgICAgIChtKSA9PiBtLmlkID09PSBtZXNzYWdlVG9RdW90ZT8uaWRcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgaWYgKHVwZGF0ZWRNZXNzYWdlVG9RdW90ZSkge1xuICAgICAgICAgICAgICAgIHRoaXMuc2VsZWN0TWVzc2FnZVRvUXVvdGUodXBkYXRlZE1lc3NhZ2VUb1F1b3RlKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5pc1N0YXRlUmVjb3ZlcnlJblByb2dyZXNzID0gZmFsc2U7XG4gICAgICAgICAgfSBjYXRjaCB7XG4gICAgICAgICAgICB0aGlzLmlzU3RhdGVSZWNvdmVyeUluUHJvZ3Jlc3MgPSBmYWxzZTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGNhc2UgJ25vdGlmaWNhdGlvbi5tZXNzYWdlX25ldyc6IHtcbiAgICAgICAgdGhpcy5uZ1pvbmUucnVuKCgpID0+IHtcbiAgICAgICAgICBpZiAodGhpcy5jdXN0b21OZXdNZXNzYWdlTm90aWZpY2F0aW9uSGFuZGxlcikge1xuICAgICAgICAgICAgdGhpcy5jdXN0b21OZXdNZXNzYWdlTm90aWZpY2F0aW9uSGFuZGxlcihcbiAgICAgICAgICAgICAgY2xpZW50RXZlbnQsXG4gICAgICAgICAgICAgIHRoaXMuY2hhbm5lbExpc3RTZXR0ZXJcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuaGFuZGxlTmV3TWVzc2FnZU5vdGlmaWNhdGlvbihjbGllbnRFdmVudCk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBjYXNlICdub3RpZmljYXRpb24uYWRkZWRfdG9fY2hhbm5lbCc6IHtcbiAgICAgICAgdGhpcy5uZ1pvbmUucnVuKCgpID0+IHtcbiAgICAgICAgICBpZiAodGhpcy5jdXN0b21BZGRlZFRvQ2hhbm5lbE5vdGlmaWNhdGlvbkhhbmRsZXIpIHtcbiAgICAgICAgICAgIHRoaXMuY3VzdG9tQWRkZWRUb0NoYW5uZWxOb3RpZmljYXRpb25IYW5kbGVyKFxuICAgICAgICAgICAgICBjbGllbnRFdmVudCxcbiAgICAgICAgICAgICAgdGhpcy5jaGFubmVsTGlzdFNldHRlclxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5oYW5kbGVBZGRlZFRvQ2hhbm5lbE5vdGlmaWNhdGlvbihjbGllbnRFdmVudCk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBjYXNlICdub3RpZmljYXRpb24ucmVtb3ZlZF9mcm9tX2NoYW5uZWwnOiB7XG4gICAgICAgIHRoaXMubmdab25lLnJ1bigoKSA9PiB7XG4gICAgICAgICAgaWYgKHRoaXMuY3VzdG9tUmVtb3ZlZEZyb21DaGFubmVsTm90aWZpY2F0aW9uSGFuZGxlcikge1xuICAgICAgICAgICAgdGhpcy5jdXN0b21SZW1vdmVkRnJvbUNoYW5uZWxOb3RpZmljYXRpb25IYW5kbGVyKFxuICAgICAgICAgICAgICBjbGllbnRFdmVudCxcbiAgICAgICAgICAgICAgdGhpcy5jaGFubmVsTGlzdFNldHRlclxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5oYW5kbGVSZW1vdmVkRnJvbUNoYW5uZWxOb3RpZmljYXRpb24oY2xpZW50RXZlbnQpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgY2FzZSAndXNlci51cGRhdGVkJzoge1xuICAgICAgICB0aGlzLm5nWm9uZS5ydW4oKCkgPT4ge1xuICAgICAgICAgIGNvbnN0IHVwZGF0ZWRDaGFubmVscyA9IHRoaXMuY2hhbm5lbHNTdWJqZWN0LmdldFZhbHVlKCk/Lm1hcCgoYykgPT4ge1xuICAgICAgICAgICAgaWYgKHRoaXMuY2hhdENsaWVudFNlcnZpY2UuY2hhdENsaWVudC5hY3RpdmVDaGFubmVsc1tjLmNpZF0pIHtcbiAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuY2hhdENsaWVudFNlcnZpY2UuY2hhdENsaWVudC5hY3RpdmVDaGFubmVsc1tjLmNpZF07XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICByZXR1cm4gYztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KTtcbiAgICAgICAgICB0aGlzLmNoYW5uZWxzU3ViamVjdC5uZXh0KHVwZGF0ZWRDaGFubmVscyk7XG4gICAgICAgICAgY29uc3QgYWN0aXZlQ2hhbm5lbCA9IHRoaXMuYWN0aXZlQ2hhbm5lbFN1YmplY3QuZ2V0VmFsdWUoKTtcbiAgICAgICAgICBpZiAoYWN0aXZlQ2hhbm5lbCkge1xuICAgICAgICAgICAgdGhpcy5hY3RpdmVDaGFubmVsU3ViamVjdC5uZXh0KFxuICAgICAgICAgICAgICB0aGlzLmNoYXRDbGllbnRTZXJ2aWNlLmNoYXRDbGllbnQuYWN0aXZlQ2hhbm5lbHNbXG4gICAgICAgICAgICAgICAgYWN0aXZlQ2hhbm5lbC5jaWRcbiAgICAgICAgICAgICAgXSB8fCBhY3RpdmVDaGFubmVsXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgdGhpcy5hY3RpdmVDaGFubmVsTWVzc2FnZXNTdWJqZWN0Lm5leHQoXG4gICAgICAgICAgICAgIGFjdGl2ZUNoYW5uZWwuc3RhdGUubWVzc2FnZXMubWFwKChtKSA9PiB7XG4gICAgICAgICAgICAgICAgbS5yZWFkQnkgPSBnZXRSZWFkQnkobSwgYWN0aXZlQ2hhbm5lbCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHsgLi4ubSB9O1xuICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGNvbnN0IGFjdGl2ZVBhcmVudE1lc3NhZ2UgPVxuICAgICAgICAgICAgICB0aGlzLmFjdGl2ZVBhcmVudE1lc3NhZ2VJZFN1YmplY3QuZ2V0VmFsdWUoKTtcbiAgICAgICAgICAgIGlmIChhY3RpdmVQYXJlbnRNZXNzYWdlKSB7XG4gICAgICAgICAgICAgIGNvbnN0IG1lc3NhZ2VzID0gYWN0aXZlQ2hhbm5lbC5zdGF0ZS50aHJlYWRzW2FjdGl2ZVBhcmVudE1lc3NhZ2VdO1xuICAgICAgICAgICAgICB0aGlzLmFjdGl2ZVRocmVhZE1lc3NhZ2VzU3ViamVjdC5uZXh0KFsuLi5tZXNzYWdlc10pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5hY3RpdmVDaGFubmVsUGlubmVkTWVzc2FnZXNTdWJqZWN0Lm5leHQoW1xuICAgICAgICAgICAgICAuLi5hY3RpdmVDaGFubmVsLnN0YXRlLnBpbm5lZE1lc3NhZ2VzLFxuICAgICAgICAgICAgXSk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBoYW5kbGVSZW1vdmVkRnJvbUNoYW5uZWxOb3RpZmljYXRpb24oY2xpZW50RXZlbnQ6IENsaWVudEV2ZW50PFQ+KSB7XG4gICAgY29uc3QgY2hhbm5lbElkVG9CZVJlbW92ZWQgPSBjbGllbnRFdmVudC5ldmVudC5jaGFubmVsIS5jaWQ7XG4gICAgdGhpcy5yZW1vdmVDaGFubmVsc0Zyb21DaGFubmVsTGlzdChbY2hhbm5lbElkVG9CZVJlbW92ZWRdLCB0cnVlKTtcbiAgfVxuXG4gIHByaXZhdGUgaGFuZGxlTmV3TWVzc2FnZU5vdGlmaWNhdGlvbihjbGllbnRFdmVudDogQ2xpZW50RXZlbnQ8VD4pIHtcbiAgICBpZiAoY2xpZW50RXZlbnQuZXZlbnQuY2hhbm5lbCkge1xuICAgICAgdm9pZCB0aGlzLmFkZENoYW5uZWxzRnJvbU5vdGlmaWNhdGlvbihbY2xpZW50RXZlbnQuZXZlbnQuY2hhbm5lbF0pO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgaGFuZGxlQWRkZWRUb0NoYW5uZWxOb3RpZmljYXRpb24oY2xpZW50RXZlbnQ6IENsaWVudEV2ZW50PFQ+KSB7XG4gICAgaWYgKGNsaWVudEV2ZW50LmV2ZW50LmNoYW5uZWwpIHtcbiAgICAgIHZvaWQgdGhpcy5hZGRDaGFubmVsc0Zyb21Ob3RpZmljYXRpb24oW2NsaWVudEV2ZW50LmV2ZW50LmNoYW5uZWxdKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGFkZENoYW5uZWxzRnJvbU5vdGlmaWNhdGlvbihcbiAgICBjaGFubmVsUmVzcG9uc2VzOiBDaGFubmVsUmVzcG9uc2U8VD5bXVxuICApIHtcbiAgICBsZXQgbmV3Q2hhbm5lbHM6IENoYW5uZWw8VD5bXSA9IFtdO1xuICAgIGNvbnN0IHdhdGNoUmVxdWVzdHM6IFByb21pc2U8YW55PltdID0gW107XG4gICAgY2hhbm5lbFJlc3BvbnNlcy5mb3JFYWNoKChjaGFubmVsUmVzcG9uc2UpID0+IHtcbiAgICAgIGNvbnN0IGNoYW5uZWwgPSB0aGlzLmNoYXRDbGllbnRTZXJ2aWNlLmNoYXRDbGllbnQuY2hhbm5lbChcbiAgICAgICAgY2hhbm5lbFJlc3BvbnNlLnR5cGUsXG4gICAgICAgIGNoYW5uZWxSZXNwb25zZS5pZFxuICAgICAgKTtcbiAgICAgIHdhdGNoUmVxdWVzdHMucHVzaChjaGFubmVsLndhdGNoKCkpO1xuICAgICAgbmV3Q2hhbm5lbHMucHVzaChjaGFubmVsKTtcbiAgICB9KTtcbiAgICBhd2FpdCBQcm9taXNlLmFsbCh3YXRjaFJlcXVlc3RzKTtcbiAgICBjb25zdCBjdXJyZW50Q2hhbm5lbHMgPSB0aGlzLmNoYW5uZWxzU3ViamVjdC5nZXRWYWx1ZSgpIHx8IFtdO1xuICAgIG5ld0NoYW5uZWxzID0gbmV3Q2hhbm5lbHMuZmlsdGVyKFxuICAgICAgKG5ld0NoYW5uZWwpID0+ICFjdXJyZW50Q2hhbm5lbHMuZmluZCgoYykgPT4gYy5jaWQgPT09IG5ld0NoYW5uZWwuY2lkKVxuICAgICk7XG4gICAgaWYgKG5ld0NoYW5uZWxzLmxlbmd0aCA+IDApIHtcbiAgICAgIG5ld0NoYW5uZWxzLmZvckVhY2goKGMpID0+IHRoaXMud2F0Y2hGb3JDaGFubmVsRXZlbnRzKGMpKTtcbiAgICAgIHRoaXMuY2hhbm5lbHNTdWJqZWN0Lm5leHQoWy4uLm5ld0NoYW5uZWxzLCAuLi5jdXJyZW50Q2hhbm5lbHNdKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHJlbW92ZUNoYW5uZWxzRnJvbUNoYW5uZWxMaXN0KFxuICAgIGNpZHM6IHN0cmluZ1tdLFxuICAgIHNob3VsZFN0b3BXYXRjaGluZzogYm9vbGVhblxuICApIHtcbiAgICBjb25zdCBjaGFubmVscyA9IHRoaXMuY2hhbm5lbHMuZmlsdGVyKChjKSA9PiAhY2lkcy5pbmNsdWRlcyhjLmNpZCB8fCAnJykpO1xuICAgIGlmIChzaG91bGRTdG9wV2F0Y2hpbmcpIHtcbiAgICAgIGNpZHMuZm9yRWFjaCgoY2lkKSA9PiB7XG4gICAgICAgIGlmICh0aGlzLmNoYW5uZWxTdWJzY3JpcHRpb25zW2NpZF0pIHtcbiAgICAgICAgICB0aGlzLmNoYW5uZWxTdWJzY3JpcHRpb25zW2NpZF0oKTtcbiAgICAgICAgICBkZWxldGUgdGhpcy5jaGFubmVsU3Vic2NyaXB0aW9ucy5jaWQ7XG4gICAgICAgIH1cbiAgICAgICAgdm9pZCB0aGlzLmNoYXRDbGllbnRTZXJ2aWNlLmNoYXRDbGllbnQuYWN0aXZlQ2hhbm5lbHNbXG4gICAgICAgICAgY2lkXG4gICAgICAgIF0/LnN0b3BXYXRjaGluZygpO1xuICAgICAgfSk7XG4gICAgfVxuICAgIGlmIChjaGFubmVscy5sZW5ndGggPCB0aGlzLmNoYW5uZWxzLmxlbmd0aCkge1xuICAgICAgdGhpcy5jaGFubmVsc1N1YmplY3QubmV4dChjaGFubmVscyk7XG4gICAgICBpZiAoY2lkcy5pbmNsdWRlcyh0aGlzLmFjdGl2ZUNoYW5uZWxTdWJqZWN0LmdldFZhbHVlKCk/LmNpZCB8fCAnJykpIHtcbiAgICAgICAgaWYgKGNoYW5uZWxzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICB0aGlzLnNldEFzQWN0aXZlQ2hhbm5lbChjaGFubmVsc1swXSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhpcy5hY3RpdmVDaGFubmVsU3ViamVjdC5uZXh0KHVuZGVmaW5lZCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHdhdGNoRm9yQWN0aXZlQ2hhbm5lbEV2ZW50cyhjaGFubmVsOiBDaGFubmVsPFQ+KSB7XG4gICAgdGhpcy5hY3RpdmVDaGFubmVsU3Vic2NyaXB0aW9ucy5wdXNoKFxuICAgICAgY2hhbm5lbC5vbignbWVzc2FnZS5uZXcnLCAoZXZlbnQpID0+IHtcbiAgICAgICAgdGhpcy5uZ1pvbmUucnVuKCgpID0+IHtcbiAgICAgICAgICBldmVudC5tZXNzYWdlICYmIGV2ZW50Lm1lc3NhZ2UucGFyZW50X2lkXG4gICAgICAgICAgICA/IGV2ZW50Lm1lc3NhZ2UucGFyZW50X2lkID09PVxuICAgICAgICAgICAgICB0aGlzLmFjdGl2ZVBhcmVudE1lc3NhZ2VJZFN1YmplY3QuZ2V0VmFsdWUoKVxuICAgICAgICAgICAgICA/IHRoaXMuYWN0aXZlVGhyZWFkTWVzc2FnZXNTdWJqZWN0Lm5leHQoW1xuICAgICAgICAgICAgICAgICAgLi4uY2hhbm5lbC5zdGF0ZS50aHJlYWRzW2V2ZW50Lm1lc3NhZ2UucGFyZW50X2lkXSxcbiAgICAgICAgICAgICAgICBdKVxuICAgICAgICAgICAgICA6IG51bGxcbiAgICAgICAgICAgIDogdGhpcy5hY3RpdmVDaGFubmVsTWVzc2FnZXNTdWJqZWN0Lm5leHQoW1xuICAgICAgICAgICAgICAgIC4uLmNoYW5uZWwuc3RhdGUubWVzc2FnZXMsXG4gICAgICAgICAgICAgIF0pO1xuICAgICAgICAgIHRoaXMuYWN0aXZlQ2hhbm5lbCQucGlwZShmaXJzdCgpKS5zdWJzY3JpYmUoKGMpID0+IHtcbiAgICAgICAgICAgIGlmIChjKSB7XG4gICAgICAgICAgICAgIHRoaXMubWFya1JlYWQoYyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSk7XG4gICAgICAgICAgdGhpcy51cGRhdGVMYXRlc3RNZXNzYWdlcyhldmVudCk7XG4gICAgICAgIH0pO1xuICAgICAgfSlcbiAgICApO1xuICAgIHRoaXMuYWN0aXZlQ2hhbm5lbFN1YnNjcmlwdGlvbnMucHVzaChcbiAgICAgIGNoYW5uZWwub24oJ21lc3NhZ2UudXBkYXRlZCcsIChldmVudCkgPT4gdGhpcy5tZXNzYWdlVXBkYXRlZChldmVudCkpXG4gICAgKTtcbiAgICB0aGlzLmFjdGl2ZUNoYW5uZWxTdWJzY3JpcHRpb25zLnB1c2goXG4gICAgICBjaGFubmVsLm9uKCdtZXNzYWdlLmRlbGV0ZWQnLCAoZXZlbnQpID0+IHRoaXMubWVzc2FnZVVwZGF0ZWQoZXZlbnQpKVxuICAgICk7XG4gICAgdGhpcy5hY3RpdmVDaGFubmVsU3Vic2NyaXB0aW9ucy5wdXNoKFxuICAgICAgY2hhbm5lbC5vbigncmVhY3Rpb24ubmV3JywgKGUpID0+IHRoaXMubWVzc2FnZVJlYWN0aW9uRXZlbnRSZWNlaXZlZChlKSlcbiAgICApO1xuICAgIHRoaXMuYWN0aXZlQ2hhbm5lbFN1YnNjcmlwdGlvbnMucHVzaChcbiAgICAgIGNoYW5uZWwub24oJ3JlYWN0aW9uLmRlbGV0ZWQnLCAoZSkgPT5cbiAgICAgICAgdGhpcy5tZXNzYWdlUmVhY3Rpb25FdmVudFJlY2VpdmVkKGUpXG4gICAgICApXG4gICAgKTtcbiAgICB0aGlzLmFjdGl2ZUNoYW5uZWxTdWJzY3JpcHRpb25zLnB1c2goXG4gICAgICBjaGFubmVsLm9uKCdyZWFjdGlvbi51cGRhdGVkJywgKGUpID0+XG4gICAgICAgIHRoaXMubWVzc2FnZVJlYWN0aW9uRXZlbnRSZWNlaXZlZChlKVxuICAgICAgKVxuICAgICk7XG4gICAgdGhpcy5hY3RpdmVDaGFubmVsU3Vic2NyaXB0aW9ucy5wdXNoKFxuICAgICAgY2hhbm5lbC5vbignbWVzc2FnZS5yZWFkJywgKGUpID0+IHtcbiAgICAgICAgdGhpcy5uZ1pvbmUucnVuKCgpID0+IHtcbiAgICAgICAgICBsZXQgbGF0ZXN0TWVzc2FnZSE6IFN0cmVhbU1lc3NhZ2U7XG4gICAgICAgICAgbGV0IG1lc3NhZ2VzITogU3RyZWFtTWVzc2FnZVtdO1xuICAgICAgICAgIHRoaXMuYWN0aXZlQ2hhbm5lbE1lc3NhZ2VzJC5waXBlKGZpcnN0KCkpLnN1YnNjcmliZSgobSkgPT4ge1xuICAgICAgICAgICAgbWVzc2FnZXMgPSBtO1xuICAgICAgICAgICAgbGF0ZXN0TWVzc2FnZSA9IG1lc3NhZ2VzW21lc3NhZ2VzLmxlbmd0aCAtIDFdO1xuICAgICAgICAgIH0pO1xuICAgICAgICAgIGlmICghbGF0ZXN0TWVzc2FnZSB8fCAhZS51c2VyKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChsYXRlc3RNZXNzYWdlLnJlYWRCeSkge1xuICAgICAgICAgICAgbGF0ZXN0TWVzc2FnZS5yZWFkQnkuc3BsaWNlKDAsIGxhdGVzdE1lc3NhZ2UucmVhZEJ5Lmxlbmd0aCk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGxhdGVzdE1lc3NhZ2UucmVhZEJ5ID0gW107XG4gICAgICAgICAgfVxuICAgICAgICAgIGxhdGVzdE1lc3NhZ2UucmVhZEJ5LnB1c2goLi4uZ2V0UmVhZEJ5KGxhdGVzdE1lc3NhZ2UsIGNoYW5uZWwpKTtcbiAgICAgICAgICBtZXNzYWdlc1ttZXNzYWdlcy5sZW5ndGggLSAxXSA9IHsgLi4ubGF0ZXN0TWVzc2FnZSB9O1xuXG4gICAgICAgICAgdGhpcy5hY3RpdmVDaGFubmVsTWVzc2FnZXNTdWJqZWN0Lm5leHQoWy4uLm1lc3NhZ2VzXSk7XG4gICAgICAgIH0pO1xuICAgICAgfSlcbiAgICApO1xuICAgIHRoaXMuYWN0aXZlQ2hhbm5lbFN1YnNjcmlwdGlvbnMucHVzaChcbiAgICAgIHRoaXMuY2hhdENsaWVudFNlcnZpY2UuZXZlbnRzJFxuICAgICAgICAucGlwZShcbiAgICAgICAgICBmaWx0ZXIoXG4gICAgICAgICAgICAoZSkgPT5cbiAgICAgICAgICAgICAgZS5ldmVudFR5cGUgPT09ICdub3RpZmljYXRpb24ubWFya191bnJlYWQnICYmXG4gICAgICAgICAgICAgIGUuZXZlbnQuY2hhbm5lbF9pZCA9PT0gY2hhbm5lbC5pZFxuICAgICAgICAgICksXG4gICAgICAgICAgbWFwKChlKSA9PiBlLmV2ZW50KVxuICAgICAgICApXG4gICAgICAgIC5zdWJzY3JpYmUoKGUpID0+IHtcbiAgICAgICAgICB0aGlzLm5nWm9uZS5ydW4oKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5hY3RpdmVDaGFubmVsTGFzdFJlYWRNZXNzYWdlSWQgPSBlLmxhc3RfcmVhZF9tZXNzYWdlX2lkO1xuICAgICAgICAgICAgdGhpcy5hY3RpdmVDaGFubmVsVW5yZWFkQ291bnQgPSBlLnVucmVhZF9tZXNzYWdlcztcbiAgICAgICAgICAgIHRoaXMuYWN0aXZlQ2hhbm5lbFN1YmplY3QubmV4dCh0aGlzLmFjdGl2ZUNoYW5uZWwpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9KVxuICAgICk7XG4gICAgdGhpcy5hY3RpdmVDaGFubmVsU3Vic2NyaXB0aW9ucy5wdXNoKFxuICAgICAgY2hhbm5lbC5vbigndHlwaW5nLnN0YXJ0JywgKGUpID0+XG4gICAgICAgIHRoaXMubmdab25lLnJ1bigoKSA9PiB0aGlzLmhhbmRsZVR5cGluZ1N0YXJ0RXZlbnQoZSkpXG4gICAgICApXG4gICAgKTtcbiAgICB0aGlzLmFjdGl2ZUNoYW5uZWxTdWJzY3JpcHRpb25zLnB1c2goXG4gICAgICBjaGFubmVsLm9uKCd0eXBpbmcuc3RvcCcsIChlKSA9PlxuICAgICAgICB0aGlzLm5nWm9uZS5ydW4oKCkgPT4gdGhpcy5oYW5kbGVUeXBpbmdTdG9wRXZlbnQoZSkpXG4gICAgICApXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDYWxsIHRoaXMgbWV0aG9kIGlmIHVzZXIgc3RhcnRlZCB0eXBpbmcgaW4gdGhlIGFjdGl2ZSBjaGFubmVsXG4gICAqIEBwYXJhbSBwYXJlbnRJZCBUaGUgaWQgb2YgdGhlIHBhcmVudCBtZXNzYWdlLCBpZiB1c2VyIGlzIHR5cGluZyBpbiBhIHRocmVhZFxuICAgKi9cbiAgYXN5bmMgdHlwaW5nU3RhcnRlZChwYXJlbnRJZD86IHN0cmluZykge1xuICAgIGNvbnN0IGFjdGl2ZUNoYW5uZWwgPSB0aGlzLmFjdGl2ZUNoYW5uZWxTdWJqZWN0LmdldFZhbHVlKCk7XG4gICAgYXdhaXQgYWN0aXZlQ2hhbm5lbD8ua2V5c3Ryb2tlKHBhcmVudElkKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDYWxsIHRoaXMgbWV0aG9kIGlmIHVzZXIgc3RvcHBlZCB0eXBpbmcgaW4gdGhlIGFjdGl2ZSBjaGFubmVsXG4gICAqIEBwYXJhbSBwYXJlbnRJZCBUaGUgaWQgb2YgdGhlIHBhcmVudCBtZXNzYWdlLCBpZiB1c2VyIHdlcmUgdHlwaW5nIGluIGEgdGhyZWFkXG4gICAqL1xuICBhc3luYyB0eXBpbmdTdG9wcGVkKHBhcmVudElkPzogc3RyaW5nKSB7XG4gICAgY29uc3QgYWN0aXZlQ2hhbm5lbCA9IHRoaXMuYWN0aXZlQ2hhbm5lbFN1YmplY3QuZ2V0VmFsdWUoKTtcbiAgICBhd2FpdCBhY3RpdmVDaGFubmVsPy5zdG9wVHlwaW5nKHBhcmVudElkKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgY3VycmVudCBsaXN0IG9mIGNoYW5uZWxzXG4gICAqL1xuICBnZXQgY2hhbm5lbHMoKSB7XG4gICAgcmV0dXJuIHRoaXMuY2hhbm5lbHNTdWJqZWN0LmdldFZhbHVlKCkgfHwgW107XG4gIH1cblxuICAvKipcbiAgICogVGhlIGN1cnJlbnQgYWN0aXZlIGNoYW5uZWxcbiAgICovXG4gIGdldCBhY3RpdmVDaGFubmVsKCkge1xuICAgIHJldHVybiB0aGlzLmFjdGl2ZUNoYW5uZWxTdWJqZWN0LmdldFZhbHVlKCkgfHwgdW5kZWZpbmVkO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBjdXJyZW50IGFjdGl2ZSBjaGFubmVsIG1lc3NhZ2VzXG4gICAqL1xuICBnZXQgYWN0aXZlQ2hhbm5lbE1lc3NhZ2VzKCkge1xuICAgIHJldHVybiB0aGlzLmFjdGl2ZUNoYW5uZWxNZXNzYWdlc1N1YmplY3QuZ2V0VmFsdWUoKSB8fCBbXTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgdGhlIGxhc3QgMTIwMCByZWFjdGlvbnMgb2YgYSBtZXNzYWdlIGluIHRoZSBjdXJyZW50IGFjdGl2ZSBjaGFubmVsLiBJZiB5b3UgbmVlZCB0byBmZXRjaCBtb3JlIHJlYWN0aW9ucyBwbGVhc2UgdXNlIHRoZSBbZm9sbG93aW5nIGVuZHBvaW50XShodHRwczovL2dldHN0cmVhbS5pby9jaGF0L2RvY3MvamF2YXNjcmlwdC9zZW5kX3JlYWN0aW9uLz9sYW5ndWFnZT1qYXZhc2NyaXB0I3BhZ2luYXRpbmctcmVhY3Rpb25zKS5cbiAgICogQHBhcmFtIG1lc3NhZ2VJZFxuICAgKiBAcmV0dXJucyBhbGwgcmVhY3Rpb25zIG9mIGEgbWVzc2FnZVxuICAgKi9cbiAgYXN5bmMgZ2V0TWVzc2FnZVJlYWN0aW9ucyhtZXNzYWdlSWQ6IHN0cmluZykge1xuICAgIGNvbnN0IHJlYWN0aW9uczogUmVhY3Rpb25SZXNwb25zZTxUPltdID0gW107XG4gICAgY29uc3QgbGltaXQgPSAzMDA7XG4gICAgbGV0IG9mZnNldCA9IDA7XG4gICAgY29uc3QgcmVhY3Rpb25zTGltaXQgPSBDaGFubmVsU2VydmljZS5NQVhfTUVTU0FHRV9SRUFDVElPTlNfVE9fRkVUQ0g7XG4gICAgbGV0IGxhc3RQYWdlU2l6ZSA9IGxpbWl0O1xuXG4gICAgd2hpbGUgKGxhc3RQYWdlU2l6ZSA9PT0gbGltaXQgJiYgcmVhY3Rpb25zLmxlbmd0aCA8IHJlYWN0aW9uc0xpbWl0KSB7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHRoaXMuYWN0aXZlQ2hhbm5lbD8uZ2V0UmVhY3Rpb25zKG1lc3NhZ2VJZCwge1xuICAgICAgICAgIG9mZnNldCxcbiAgICAgICAgICBsaW1pdCxcbiAgICAgICAgfSk7XG4gICAgICAgIGxhc3RQYWdlU2l6ZSA9IHJlc3BvbnNlPy5yZWFjdGlvbnM/Lmxlbmd0aCB8fCAwO1xuICAgICAgICBpZiAobGFzdFBhZ2VTaXplID4gMCkge1xuICAgICAgICAgIHJlYWN0aW9ucy5wdXNoKC4uLnJlc3BvbnNlIS5yZWFjdGlvbnMpO1xuICAgICAgICB9XG4gICAgICAgIG9mZnNldCArPSBsYXN0UGFnZVNpemU7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHRoaXMubm90aWZpY2F0aW9uU2VydmljZS5hZGRUZW1wb3JhcnlOb3RpZmljYXRpb24oXG4gICAgICAgICAgJ3N0cmVhbUNoYXQuRXJyb3IgbG9hZGluZyByZWFjdGlvbnMnXG4gICAgICAgICk7XG4gICAgICAgIHRocm93IGU7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiByZWFjdGlvbnM7XG4gIH1cblxuICAvKipcbiAgICogTWFya3MgdGhlIGNoYW5uZWwgZnJvbSB0aGUgZ2l2ZW4gbWVzc2FnZSBhcyB1bnJlYWRcbiAgICogQHBhcmFtIG1lc3NhZ2VJZFxuICAgKiBAcmV0dXJucyB0aGUgcmVzdWx0IG9mIHRoZSByZXF1ZXN0XG4gICAqL1xuICBhc3luYyBtYXJrTWVzc2FnZVVucmVhZChtZXNzYWdlSWQ6IHN0cmluZykge1xuICAgIGlmICghdGhpcy5hY3RpdmVDaGFubmVsKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgdGhpcy5hY3RpdmVDaGFubmVsLm1hcmtVbnJlYWQoe1xuICAgICAgICBtZXNzYWdlX2lkOiBtZXNzYWdlSWQsXG4gICAgICB9KTtcbiAgICAgIHRoaXMuYXJlUmVhZEV2ZW50c1BhdXNlZCA9IHRydWU7XG4gICAgICByZXR1cm4gcmVzcG9uc2U7XG4gICAgfSBjYXRjaCAoZTogYW55KSB7XG4gICAgICBjb25zdCBlcnJvcjoge1xuICAgICAgICByZXNwb25zZT86IHtcbiAgICAgICAgICBkYXRhPzogeyBjb2RlPzogbnVtYmVyOyBtZXNzYWdlPzogc3RyaW5nOyBTdGF0dXNDb2RlPzogbnVtYmVyIH07XG4gICAgICAgIH07XG4gICAgICB9ID0gSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShlKSkgYXMge1xuICAgICAgICByZXNwb25zZT86IHtcbiAgICAgICAgICBkYXRhPzogeyBjb2RlPzogbnVtYmVyOyBtZXNzYWdlPzogc3RyaW5nOyBTdGF0dXNDb2RlPzogbnVtYmVyIH07XG4gICAgICAgIH07XG4gICAgICB9O1xuICAgICAgY29uc3QgZGF0YSA9IGVycm9yPy5yZXNwb25zZT8uZGF0YTtcbiAgICAgIGlmIChcbiAgICAgICAgZGF0YSAmJlxuICAgICAgICBkYXRhLmNvZGUgPT09IDQgJiZcbiAgICAgICAgZGF0YS5TdGF0dXNDb2RlID09PSA0MDAgJiZcbiAgICAgICAgZGF0YS5tZXNzYWdlPy5pbmNsdWRlcygnaXQgaXMgb2xkZXIgdGhhbiBsYXN0JylcbiAgICAgICkge1xuICAgICAgICBjb25zdCBjb3VudCA9IC9cXGQrIGNoYW5uZWwgbWVzc2FnZXMvXG4gICAgICAgICAgLmV4ZWMoZGF0YS5tZXNzYWdlKT8uWzBdXG4gICAgICAgICAgLm1hdGNoKC9cXGQrLyk/LlswXTtcbiAgICAgICAgaWYgKGNvdW50KSB7XG4gICAgICAgICAgdGhpcy5ub3RpZmljYXRpb25TZXJ2aWNlLmFkZFRlbXBvcmFyeU5vdGlmaWNhdGlvbihcbiAgICAgICAgICAgICdzdHJlYW1DaGF0LkVycm9yLCBvbmx5IHRoZSBmaXJzdCB7e2NvdW50fX0gbWVzc2FnZSBjYW4gYmUgbWFya2VkIGFzIHVucmVhZCcsXG4gICAgICAgICAgICB1bmRlZmluZWQsXG4gICAgICAgICAgICB1bmRlZmluZWQsXG4gICAgICAgICAgICB7IGNvdW50IH1cbiAgICAgICAgICApO1xuICAgICAgICAgIHRocm93IGU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHRoaXMubm90aWZpY2F0aW9uU2VydmljZS5hZGRUZW1wb3JhcnlOb3RpZmljYXRpb24oXG4gICAgICAgICdzdHJlYW1DaGF0LkVycm9yIG1hcmtpbmcgbWVzc2FnZSBhcyB1bnJlYWQnXG4gICAgICApO1xuICAgICAgdGhyb3cgZTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIG1lc3NhZ2VVcGRhdGVkKGV2ZW50OiBFdmVudDxUPikge1xuICAgIHRoaXMubmdab25lLnJ1bigoKSA9PiB7XG4gICAgICBjb25zdCBpc1RocmVhZFJlcGx5ID0gZXZlbnQubWVzc2FnZSAmJiBldmVudC5tZXNzYWdlLnBhcmVudF9pZDtcbiAgICAgIGNvbnN0IGNoYW5uZWwgPSB0aGlzLmFjdGl2ZUNoYW5uZWxTdWJqZWN0LmdldFZhbHVlKCk7XG4gICAgICBpZiAoIWNoYW5uZWwpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgLy8gR2V0IG1lc3NhZ2VzIGZyb20gc3RhdGUgYXMgbWVzc2FnZSBvcmRlciBjb3VsZCBjaGFuZ2UsIGFuZCBtZXNzYWdlIGNvdWxkJ3ZlIGJlZW4gZGVsZXRlZFxuICAgICAgY29uc3QgbWVzc2FnZXM6IEZvcm1hdE1lc3NhZ2VSZXNwb25zZTxUPltdID0gaXNUaHJlYWRSZXBseVxuICAgICAgICA/IGNoYW5uZWwuc3RhdGUudGhyZWFkc1tldmVudD8ubWVzc2FnZT8ucGFyZW50X2lkIHx8ICcnXVxuICAgICAgICA6IGNoYW5uZWwuc3RhdGUubWVzc2FnZXM7XG4gICAgICBpZiAoIW1lc3NhZ2VzKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGNvbnN0IG1lc3NhZ2VJbmRleCA9IG1lc3NhZ2VzLmZpbmRJbmRleChcbiAgICAgICAgKG0pID0+IG0uaWQgPT09IGV2ZW50Py5tZXNzYWdlPy5pZFxuICAgICAgKTtcbiAgICAgIGlmIChtZXNzYWdlSW5kZXggIT09IC0xKSB7XG4gICAgICAgIGlzVGhyZWFkUmVwbHlcbiAgICAgICAgICA/IHRoaXMuYWN0aXZlVGhyZWFkTWVzc2FnZXNTdWJqZWN0Lm5leHQoWy4uLm1lc3NhZ2VzXSlcbiAgICAgICAgICA6IHRoaXMuYWN0aXZlQ2hhbm5lbE1lc3NhZ2VzU3ViamVjdC5uZXh0KFsuLi5tZXNzYWdlc10pO1xuICAgICAgICB0aGlzLmFjdGl2ZUNoYW5uZWxQaW5uZWRNZXNzYWdlc1N1YmplY3QubmV4dChbXG4gICAgICAgICAgLi4uY2hhbm5lbC5zdGF0ZS5waW5uZWRNZXNzYWdlcyxcbiAgICAgICAgXSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIG1lc3NhZ2VSZWFjdGlvbkV2ZW50UmVjZWl2ZWQoZTogRXZlbnQ8VD4pIHtcbiAgICB0aGlzLm5nWm9uZS5ydW4oKCkgPT4ge1xuICAgICAgY29uc3QgaXNUaHJlYWRNZXNzYWdlID0gZS5tZXNzYWdlICYmIGUubWVzc2FnZS5wYXJlbnRfaWQ7XG4gICAgICBsZXQgbWVzc2FnZXMhOiBTdHJlYW1NZXNzYWdlW107XG4gICAgICAoaXNUaHJlYWRNZXNzYWdlXG4gICAgICAgID8gdGhpcy5hY3RpdmVUaHJlYWRNZXNzYWdlcyRcbiAgICAgICAgOiB0aGlzLmFjdGl2ZUNoYW5uZWxNZXNzYWdlcyRcbiAgICAgIClcbiAgICAgICAgLnBpcGUoZmlyc3QoKSlcbiAgICAgICAgLnN1YnNjcmliZSgobSkgPT4gKG1lc3NhZ2VzID0gbSkpO1xuICAgICAgY29uc3QgbWVzc2FnZUluZGV4ID0gbWVzc2FnZXMuZmluZEluZGV4KChtKSA9PiBtLmlkID09PSBlPy5tZXNzYWdlPy5pZCk7XG4gICAgICBpZiAobWVzc2FnZUluZGV4ID09PSAtMSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBjb25zdCBtZXNzYWdlID0gbWVzc2FnZXNbbWVzc2FnZUluZGV4XTtcbiAgICAgIG1lc3NhZ2UucmVhY3Rpb25fY291bnRzID0geyAuLi5lLm1lc3NhZ2U/LnJlYWN0aW9uX2NvdW50cyB9O1xuICAgICAgbWVzc2FnZS5yZWFjdGlvbl9zY29yZXMgPSB7IC4uLmUubWVzc2FnZT8ucmVhY3Rpb25fc2NvcmVzIH07XG4gICAgICBtZXNzYWdlLmxhdGVzdF9yZWFjdGlvbnMgPSBbLi4uKGUubWVzc2FnZT8ubGF0ZXN0X3JlYWN0aW9ucyB8fCBbXSldO1xuICAgICAgbWVzc2FnZS5vd25fcmVhY3Rpb25zID0gWy4uLihlLm1lc3NhZ2U/Lm93bl9yZWFjdGlvbnMgfHwgW10pXTtcblxuICAgICAgbWVzc2FnZXNbbWVzc2FnZUluZGV4XSA9IHsgLi4ubWVzc2FnZSB9O1xuICAgICAgaXNUaHJlYWRNZXNzYWdlXG4gICAgICAgID8gdGhpcy5hY3RpdmVUaHJlYWRNZXNzYWdlc1N1YmplY3QubmV4dChbLi4ubWVzc2FnZXNdKVxuICAgICAgICA6IHRoaXMuYWN0aXZlQ2hhbm5lbE1lc3NhZ2VzU3ViamVjdC5uZXh0KFsuLi5tZXNzYWdlc10pO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBmb3JtYXRNZXNzYWdlKG1lc3NhZ2U6IE1lc3NhZ2VSZXNwb25zZTxUPikge1xuICAgIGNvbnN0IG0gPSBtZXNzYWdlIGFzIGFueSBhcyBGb3JtYXRNZXNzYWdlUmVzcG9uc2U8VD47XG4gICAgbS5waW5uZWRfYXQgPSBtZXNzYWdlLnBpbm5lZF9hdCA/IG5ldyBEYXRlKG1lc3NhZ2UucGlubmVkX2F0KSA6IG51bGw7XG4gICAgbS5jcmVhdGVkX2F0ID0gbWVzc2FnZS5jcmVhdGVkX2F0XG4gICAgICA/IG5ldyBEYXRlKG1lc3NhZ2UuY3JlYXRlZF9hdClcbiAgICAgIDogbmV3IERhdGUoKTtcbiAgICBtLnVwZGF0ZWRfYXQgPSBtZXNzYWdlLnVwZGF0ZWRfYXRcbiAgICAgID8gbmV3IERhdGUobWVzc2FnZS51cGRhdGVkX2F0KVxuICAgICAgOiBuZXcgRGF0ZSgpO1xuICAgIG1lc3NhZ2Uuc3RhdHVzID0gbWVzc2FnZS5zdGF0dXMgfHwgJ3JlY2VpdmVkJztcblxuICAgIHJldHVybiBtO1xuICB9XG5cbiAgcHJpdmF0ZSBpc1N0cmVhbU1lc3NhZ2UoXG4gICAgbWVzc2FnZTogU3RyZWFtTWVzc2FnZSB8IEZvcm1hdE1lc3NhZ2VSZXNwb25zZSB8IE1lc3NhZ2VSZXNwb25zZVxuICApOiBtZXNzYWdlIGlzIFN0cmVhbU1lc3NhZ2Uge1xuICAgIHJldHVybiAhIW1lc3NhZ2UucmVhZEJ5O1xuICB9XG5cbiAgcHJpdmF0ZSBpc0Zvcm1hdE1lc3NhZ2VSZXNwb25zZShcbiAgICBtZXNzYWdlOiBTdHJlYW1NZXNzYWdlIHwgRm9ybWF0TWVzc2FnZVJlc3BvbnNlIHwgTWVzc2FnZVJlc3BvbnNlXG4gICk6IG1lc3NhZ2UgaXMgRm9ybWF0TWVzc2FnZVJlc3BvbnNlIHtcbiAgICByZXR1cm4gbWVzc2FnZS5jcmVhdGVkX2F0IGluc3RhbmNlb2YgRGF0ZTtcbiAgfVxuXG4gIHByaXZhdGUgc3RvcFdhdGNoRm9yQWN0aXZlQ2hhbm5lbEV2ZW50cyhjaGFubmVsOiBDaGFubmVsPFQ+IHwgdW5kZWZpbmVkKSB7XG4gICAgaWYgKCFjaGFubmVsKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMuYWN0aXZlQ2hhbm5lbFN1YnNjcmlwdGlvbnMuZm9yRWFjaCgocykgPT4gcy51bnN1YnNjcmliZSgpKTtcbiAgICB0aGlzLmFjdGl2ZUNoYW5uZWxTdWJzY3JpcHRpb25zID0gW107XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHF1ZXJ5Q2hhbm5lbHMoXG4gICAgc2hvdWxkU2V0QWN0aXZlQ2hhbm5lbDogYm9vbGVhbixcbiAgICByZWNvdmVyU3RhdGUgPSBmYWxzZVxuICApIHtcbiAgICB0cnkge1xuICAgICAgdGhpcy5jaGFubmVsUXVlcnlTdGF0ZVN1YmplY3QubmV4dCh7IHN0YXRlOiAnaW4tcHJvZ3Jlc3MnIH0pO1xuICAgICAgbGV0IGZpbHRlcnM6IENoYW5uZWxGaWx0ZXJzPFQ+O1xuICAgICAgbGV0IG9wdGlvbnM6IENoYW5uZWxPcHRpb25zO1xuICAgICAgaWYgKHRoaXMubmV4dFBhZ2VDb25maWd1cmF0aW9uKSB7XG4gICAgICAgIGlmICh0aGlzLm5leHRQYWdlQ29uZmlndXJhdGlvbi50eXBlID09PSAnZmlsdGVyJykge1xuICAgICAgICAgIGZpbHRlcnMgPSB7XG4gICAgICAgICAgICAuLi50aGlzLmZpbHRlcnMhLFxuICAgICAgICAgICAgLi4udGhpcy5uZXh0UGFnZUNvbmZpZ3VyYXRpb24ucGFnaW5hdGlvbkZpbHRlcixcbiAgICAgICAgICB9O1xuICAgICAgICAgIG9wdGlvbnMgPSB0aGlzLm9wdGlvbnMgYXMgQ2hhbm5lbE9wdGlvbnM7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgb3B0aW9ucyA9IHtcbiAgICAgICAgICAgIC4uLnRoaXMub3B0aW9ucyxcbiAgICAgICAgICAgIG9mZnNldDogdGhpcy5uZXh0UGFnZUNvbmZpZ3VyYXRpb24ub2Zmc2V0LFxuICAgICAgICAgIH07XG4gICAgICAgICAgZmlsdGVycyA9IHRoaXMuZmlsdGVycyE7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGZpbHRlcnMgPSB0aGlzLmZpbHRlcnMhO1xuICAgICAgICBvcHRpb25zID0gdGhpcy5vcHRpb25zIGFzIENoYW5uZWxPcHRpb25zO1xuICAgICAgfVxuICAgICAgY29uc3QgY2hhbm5lbHMgPSBhd2FpdCB0aGlzLmNoYXRDbGllbnRTZXJ2aWNlLmNoYXRDbGllbnQucXVlcnlDaGFubmVscyhcbiAgICAgICAgZmlsdGVycyxcbiAgICAgICAgdGhpcy5zb3J0IHx8IHt9LFxuICAgICAgICBvcHRpb25zXG4gICAgICApO1xuICAgICAgdGhpcy5zZXROZXh0UGFnZUNvbmZpZ3VyYXRpb24oY2hhbm5lbHMpO1xuICAgICAgY2hhbm5lbHMuZm9yRWFjaCgoYykgPT4gdGhpcy53YXRjaEZvckNoYW5uZWxFdmVudHMoYykpO1xuICAgICAgY29uc3QgcHJldkNoYW5uZWxzID0gcmVjb3ZlclN0YXRlXG4gICAgICAgID8gW11cbiAgICAgICAgOiB0aGlzLmNoYW5uZWxzU3ViamVjdC5nZXRWYWx1ZSgpIHx8IFtdO1xuICAgICAgY29uc3QgZmlsdGVyZWRDaGFubmVscyA9IGNoYW5uZWxzLmZpbHRlcihcbiAgICAgICAgKGNoYW5uZWwpID0+XG4gICAgICAgICAgIXByZXZDaGFubmVscy5maW5kKFxuICAgICAgICAgICAgKGV4aXN0aW5nQ2hhbm5lbCkgPT4gZXhpc3RpbmdDaGFubmVsLmNpZCA9PT0gY2hhbm5lbC5jaWRcbiAgICAgICAgICApXG4gICAgICApO1xuICAgICAgbGV0IGN1cnJlbnRBY3RpdmVDaGFubmVsID0gdGhpcy5hY3RpdmVDaGFubmVsU3ViamVjdC5nZXRWYWx1ZSgpO1xuICAgICAgbGV0IGlzQ3VycmVudEFjdGl2ZUNoYW5uZWxEZXNlbGVjdGVkID0gZmFsc2U7XG4gICAgICBjb25zdCBuZXh0Q2hhbm5lbHMgPSBbLi4ucHJldkNoYW5uZWxzLCAuLi5maWx0ZXJlZENoYW5uZWxzXTtcbiAgICAgIGlmIChcbiAgICAgICAgcmVjb3ZlclN0YXRlICYmXG4gICAgICAgIGN1cnJlbnRBY3RpdmVDaGFubmVsICYmXG4gICAgICAgICFmaWx0ZXJlZENoYW5uZWxzLmZpbmQoKGMpID0+IGMuY2lkID09PSBjdXJyZW50QWN0aXZlQ2hhbm5lbD8uY2lkKVxuICAgICAgKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgYXdhaXQgY3VycmVudEFjdGl2ZUNoYW5uZWwud2F0Y2goKTtcbiAgICAgICAgICBuZXh0Q2hhbm5lbHMudW5zaGlmdChjdXJyZW50QWN0aXZlQ2hhbm5lbCk7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICBpc0N1cnJlbnRBY3RpdmVDaGFubmVsRGVzZWxlY3RlZCA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHRoaXMuY2hhbm5lbHNTdWJqZWN0Lm5leHQobmV4dENoYW5uZWxzKTtcbiAgICAgIGlmIChpc0N1cnJlbnRBY3RpdmVDaGFubmVsRGVzZWxlY3RlZCkge1xuICAgICAgICB0aGlzLmRlc2VsZWN0QWN0aXZlQ2hhbm5lbCgpO1xuICAgICAgfVxuICAgICAgaWYgKFxuICAgICAgICBmaWx0ZXJlZENoYW5uZWxzLmxlbmd0aCA+IDAgJiZcbiAgICAgICAgIWN1cnJlbnRBY3RpdmVDaGFubmVsICYmXG4gICAgICAgIHNob3VsZFNldEFjdGl2ZUNoYW5uZWxcbiAgICAgICkge1xuICAgICAgICB0aGlzLnNldEFzQWN0aXZlQ2hhbm5lbChmaWx0ZXJlZENoYW5uZWxzWzBdKTtcbiAgICAgICAgY3VycmVudEFjdGl2ZUNoYW5uZWwgPSB0aGlzLmFjdGl2ZUNoYW5uZWxTdWJqZWN0LmdldFZhbHVlKCk7XG4gICAgICB9XG4gICAgICB0aGlzLmhhc01vcmVDaGFubmVsc1N1YmplY3QubmV4dChjaGFubmVscy5sZW5ndGggPj0gdGhpcy5vcHRpb25zIS5saW1pdCEpO1xuICAgICAgdGhpcy5jaGFubmVsUXVlcnlTdGF0ZVN1YmplY3QubmV4dCh7IHN0YXRlOiAnc3VjY2VzcycgfSk7XG4gICAgICBpZiAoXG4gICAgICAgIHRoaXMub3B0aW9ucz8ua2VlcEFsaXZlQ2hhbm5lbHMkT25FcnJvciAmJlxuICAgICAgICB0aGlzLmRpc21pc3NFcnJvck5vdGlmaWNhdGlvblxuICAgICAgKSB7XG4gICAgICAgIHRoaXMuZGlzbWlzc0Vycm9yTm90aWZpY2F0aW9uKCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gY2hhbm5lbHM7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGlmICghdGhpcy5vcHRpb25zPy5rZWVwQWxpdmVDaGFubmVscyRPbkVycm9yKSB7XG4gICAgICAgIHRoaXMuY2hhbm5lbHNTdWJqZWN0LmVycm9yKGVycm9yKTtcbiAgICAgIH1cbiAgICAgIHRoaXMuY2hhbm5lbFF1ZXJ5U3RhdGVTdWJqZWN0Lm5leHQoe1xuICAgICAgICBzdGF0ZTogJ2Vycm9yJyxcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnNhZmUtYXNzaWdubWVudFxuICAgICAgICBlcnJvcixcbiAgICAgIH0pO1xuICAgICAgdGhyb3cgZXJyb3I7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSB3YXRjaEZvckNoYW5uZWxFdmVudHMoY2hhbm5lbDogQ2hhbm5lbDxUPikge1xuICAgIGNvbnN0IHVuc3Vic2NyaWJlID0gY2hhbm5lbC5vbigoZXZlbnQ6IEV2ZW50PFQ+KSA9PiB7XG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVubmVjZXNzYXJ5LXR5cGUtYXNzZXJ0aW9uXG4gICAgICBjb25zdCB0eXBlID0gZXZlbnQudHlwZSBhcyBFdmVudFR5cGVzIHwgJ2NhcGFiaWxpdGllcy5jaGFuZ2VkJztcbiAgICAgIHN3aXRjaCAodHlwZSkge1xuICAgICAgICBjYXNlICdtZXNzYWdlLm5ldyc6IHtcbiAgICAgICAgICB0aGlzLm5nWm9uZS5ydW4oKCkgPT4ge1xuICAgICAgICAgICAgaWYgKHRoaXMuY3VzdG9tTmV3TWVzc2FnZUhhbmRsZXIpIHtcbiAgICAgICAgICAgICAgdGhpcy5jdXN0b21OZXdNZXNzYWdlSGFuZGxlcihcbiAgICAgICAgICAgICAgICBldmVudCxcbiAgICAgICAgICAgICAgICBjaGFubmVsLFxuICAgICAgICAgICAgICAgIHRoaXMuY2hhbm5lbExpc3RTZXR0ZXIsXG4gICAgICAgICAgICAgICAgdGhpcy5tZXNzYWdlTGlzdFNldHRlcixcbiAgICAgICAgICAgICAgICB0aGlzLnRocmVhZExpc3RTZXR0ZXIsXG4gICAgICAgICAgICAgICAgdGhpcy5wYXJlbnRNZXNzYWdlU2V0dGVyXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICB0aGlzLmhhbmRsZU5ld01lc3NhZ2UoZXZlbnQsIGNoYW5uZWwpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIGNhc2UgJ2NoYW5uZWwuaGlkZGVuJzoge1xuICAgICAgICAgIHRoaXMubmdab25lLnJ1bigoKSA9PiB7XG4gICAgICAgICAgICBpZiAodGhpcy5jdXN0b21DaGFubmVsSGlkZGVuSGFuZGxlcikge1xuICAgICAgICAgICAgICB0aGlzLmN1c3RvbUNoYW5uZWxIaWRkZW5IYW5kbGVyKFxuICAgICAgICAgICAgICAgIGV2ZW50LFxuICAgICAgICAgICAgICAgIGNoYW5uZWwsXG4gICAgICAgICAgICAgICAgdGhpcy5jaGFubmVsTGlzdFNldHRlcixcbiAgICAgICAgICAgICAgICB0aGlzLm1lc3NhZ2VMaXN0U2V0dGVyLFxuICAgICAgICAgICAgICAgIHRoaXMudGhyZWFkTGlzdFNldHRlcixcbiAgICAgICAgICAgICAgICB0aGlzLnBhcmVudE1lc3NhZ2VTZXR0ZXJcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHRoaXMuaGFuZGxlQ2hhbm5lbEhpZGRlbihldmVudCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgY2FzZSAnY2hhbm5lbC5kZWxldGVkJzoge1xuICAgICAgICAgIHRoaXMubmdab25lLnJ1bigoKSA9PiB7XG4gICAgICAgICAgICBpZiAodGhpcy5jdXN0b21DaGFubmVsRGVsZXRlZEhhbmRsZXIpIHtcbiAgICAgICAgICAgICAgdGhpcy5jdXN0b21DaGFubmVsRGVsZXRlZEhhbmRsZXIoXG4gICAgICAgICAgICAgICAgZXZlbnQsXG4gICAgICAgICAgICAgICAgY2hhbm5lbCxcbiAgICAgICAgICAgICAgICB0aGlzLmNoYW5uZWxMaXN0U2V0dGVyLFxuICAgICAgICAgICAgICAgIHRoaXMubWVzc2FnZUxpc3RTZXR0ZXIsXG4gICAgICAgICAgICAgICAgdGhpcy50aHJlYWRMaXN0U2V0dGVyLFxuICAgICAgICAgICAgICAgIHRoaXMucGFyZW50TWVzc2FnZVNldHRlclxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgdGhpcy5oYW5kbGVDaGFubmVsRGVsZXRlZChldmVudCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgY2FzZSAnY2hhbm5lbC52aXNpYmxlJzoge1xuICAgICAgICAgIHRoaXMubmdab25lLnJ1bigoKSA9PiB7XG4gICAgICAgICAgICBpZiAodGhpcy5jdXN0b21DaGFubmVsVmlzaWJsZUhhbmRsZXIpIHtcbiAgICAgICAgICAgICAgdGhpcy5jdXN0b21DaGFubmVsVmlzaWJsZUhhbmRsZXIoXG4gICAgICAgICAgICAgICAgZXZlbnQsXG4gICAgICAgICAgICAgICAgY2hhbm5lbCxcbiAgICAgICAgICAgICAgICB0aGlzLmNoYW5uZWxMaXN0U2V0dGVyLFxuICAgICAgICAgICAgICAgIHRoaXMubWVzc2FnZUxpc3RTZXR0ZXIsXG4gICAgICAgICAgICAgICAgdGhpcy50aHJlYWRMaXN0U2V0dGVyLFxuICAgICAgICAgICAgICAgIHRoaXMucGFyZW50TWVzc2FnZVNldHRlclxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgdGhpcy5oYW5kbGVDaGFubmVsVmlzaWJsZShldmVudCwgY2hhbm5lbCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgY2FzZSAnY2hhbm5lbC51cGRhdGVkJzoge1xuICAgICAgICAgIHRoaXMubmdab25lLnJ1bigoKSA9PiB7XG4gICAgICAgICAgICBpZiAodGhpcy5jdXN0b21DaGFubmVsVXBkYXRlZEhhbmRsZXIpIHtcbiAgICAgICAgICAgICAgdGhpcy5jdXN0b21DaGFubmVsVXBkYXRlZEhhbmRsZXIoXG4gICAgICAgICAgICAgICAgZXZlbnQsXG4gICAgICAgICAgICAgICAgY2hhbm5lbCxcbiAgICAgICAgICAgICAgICB0aGlzLmNoYW5uZWxMaXN0U2V0dGVyLFxuICAgICAgICAgICAgICAgIHRoaXMubWVzc2FnZUxpc3RTZXR0ZXIsXG4gICAgICAgICAgICAgICAgdGhpcy50aHJlYWRMaXN0U2V0dGVyLFxuICAgICAgICAgICAgICAgIHRoaXMucGFyZW50TWVzc2FnZVNldHRlclxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgdGhpcy5oYW5kbGVDaGFubmVsVXBkYXRlKGV2ZW50KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBjYXNlICdjaGFubmVsLnRydW5jYXRlZCc6IHtcbiAgICAgICAgICB0aGlzLm5nWm9uZS5ydW4oKCkgPT4ge1xuICAgICAgICAgICAgaWYgKHRoaXMuY3VzdG9tQ2hhbm5lbFRydW5jYXRlZEhhbmRsZXIpIHtcbiAgICAgICAgICAgICAgdGhpcy5jdXN0b21DaGFubmVsVHJ1bmNhdGVkSGFuZGxlcihcbiAgICAgICAgICAgICAgICBldmVudCxcbiAgICAgICAgICAgICAgICBjaGFubmVsLFxuICAgICAgICAgICAgICAgIHRoaXMuY2hhbm5lbExpc3RTZXR0ZXIsXG4gICAgICAgICAgICAgICAgdGhpcy5tZXNzYWdlTGlzdFNldHRlcixcbiAgICAgICAgICAgICAgICB0aGlzLnRocmVhZExpc3RTZXR0ZXIsXG4gICAgICAgICAgICAgICAgdGhpcy5wYXJlbnRNZXNzYWdlU2V0dGVyXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICB0aGlzLmhhbmRsZUNoYW5uZWxUcnVuY2F0ZShldmVudCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgY2FzZSAnY2FwYWJpbGl0aWVzLmNoYW5nZWQnOiB7XG4gICAgICAgICAgdGhpcy5uZ1pvbmUucnVuKCgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGNpZCA9IGV2ZW50LmNpZDtcbiAgICAgICAgICAgIGlmIChjaWQpIHtcbiAgICAgICAgICAgICAgY29uc3QgY3VycmVudENoYW5uZWxzID0gdGhpcy5jaGFubmVsc1N1YmplY3QuZ2V0VmFsdWUoKTtcbiAgICAgICAgICAgICAgY29uc3QgaW5kZXggPSBjdXJyZW50Q2hhbm5lbHM/LmZpbmRJbmRleCgoYykgPT4gYy5jaWQgPT09IGNpZCk7XG4gICAgICAgICAgICAgIGlmIChpbmRleCAhPT0gLTEgJiYgaW5kZXggIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIHRoaXMuY2hhbm5lbHNTdWJqZWN0Lm5leHQoWy4uLmN1cnJlbnRDaGFubmVscyFdKTtcbiAgICAgICAgICAgICAgICBpZiAoY2lkID09PSB0aGlzLmFjdGl2ZUNoYW5uZWxTdWJqZWN0LmdldFZhbHVlKCk/LmNpZCkge1xuICAgICAgICAgICAgICAgICAgdGhpcy5hY3RpdmVDaGFubmVsU3ViamVjdC5uZXh0KFxuICAgICAgICAgICAgICAgICAgICB0aGlzLmFjdGl2ZUNoYW5uZWxTdWJqZWN0LmdldFZhbHVlKClcbiAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcbiAgICB0aGlzLmNoYW5uZWxTdWJzY3JpcHRpb25zW2NoYW5uZWwuY2lkXSA9IHVuc3Vic2NyaWJlLnVuc3Vic2NyaWJlO1xuICB9XG5cbiAgcHJpdmF0ZSBoYW5kbGVOZXdNZXNzYWdlKF86IEV2ZW50LCBjaGFubmVsOiBDaGFubmVsPFQ+KSB7XG4gICAgY29uc3QgY2hhbm5lbEluZGV4ID0gdGhpcy5jaGFubmVscy5maW5kSW5kZXgoKGMpID0+IGMuY2lkID09PSBjaGFubmVsLmNpZCk7XG4gICAgdGhpcy5jaGFubmVscy5zcGxpY2UoY2hhbm5lbEluZGV4LCAxKTtcbiAgICB0aGlzLmNoYW5uZWxzU3ViamVjdC5uZXh0KFtjaGFubmVsLCAuLi50aGlzLmNoYW5uZWxzXSk7XG4gIH1cblxuICBwcml2YXRlIGhhbmRsZUNoYW5uZWxIaWRkZW4oZXZlbnQ6IEV2ZW50KSB7XG4gICAgdGhpcy5yZW1vdmVDaGFubmVsc0Zyb21DaGFubmVsTGlzdChbZXZlbnQuY2hhbm5lbCEuY2lkXSwgZmFsc2UpO1xuICB9XG5cbiAgcHJpdmF0ZSBoYW5kbGVDaGFubmVsRGVsZXRlZChldmVudDogRXZlbnQpIHtcbiAgICB0aGlzLnJlbW92ZUNoYW5uZWxzRnJvbUNoYW5uZWxMaXN0KFtldmVudC5jaGFubmVsIS5jaWRdLCBmYWxzZSk7XG4gIH1cblxuICBwcml2YXRlIGhhbmRsZUNoYW5uZWxWaXNpYmxlKGV2ZW50OiBFdmVudCwgY2hhbm5lbDogQ2hhbm5lbDxUPikge1xuICAgIGlmICghdGhpcy5jaGFubmVscy5maW5kKChjKSA9PiBjLmNpZCA9PT0gZXZlbnQuY2lkKSkge1xuICAgICAgdGhpcy5uZ1pvbmUucnVuKCgpID0+XG4gICAgICAgIHRoaXMuY2hhbm5lbHNTdWJqZWN0Lm5leHQoWy4uLnRoaXMuY2hhbm5lbHMsIGNoYW5uZWxdKVxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGhhbmRsZUNoYW5uZWxVcGRhdGUoZXZlbnQ6IEV2ZW50PFQ+KSB7XG4gICAgY29uc3QgY2hhbm5lbEluZGV4ID0gdGhpcy5jaGFubmVscy5maW5kSW5kZXgoXG4gICAgICAoYykgPT4gYy5jaWQgPT09IGV2ZW50LmNoYW5uZWwhLmNpZFxuICAgICk7XG4gICAgaWYgKGNoYW5uZWxJbmRleCAhPT0gLTEpIHtcbiAgICAgIGNvbnN0IGNoYW5uZWwgPSB0aGlzLmNoYW5uZWxzW2NoYW5uZWxJbmRleF07XG4gICAgICBjb25zdCBub3RJbmNsdWRlZFByb3BlcmllcyA9IHtcbiAgICAgICAgaGlkZGVuOiBjaGFubmVsLmRhdGE/LmhpZGRlbiB8fCBmYWxzZSxcbiAgICAgICAgb3duX2NhcGFiaWxpdGllczogY2hhbm5lbC5kYXRhPy5vd25fY2FwYWJpbGl0aWVzIHx8IFtdLFxuICAgICAgfTtcbiAgICAgIGNoYW5uZWwuZGF0YSA9IHtcbiAgICAgICAgLi4uZXZlbnQuY2hhbm5lbCEsXG4gICAgICAgIC4uLm5vdEluY2x1ZGVkUHJvcGVyaWVzLFxuICAgICAgfTtcbiAgICAgIHRoaXMuY2hhbm5lbHNTdWJqZWN0Lm5leHQoWy4uLnRoaXMuY2hhbm5lbHNdKTtcbiAgICAgIGlmIChldmVudC5jaGFubmVsPy5jaWQgPT09IHRoaXMuYWN0aXZlQ2hhbm5lbFN1YmplY3QuZ2V0VmFsdWUoKT8uY2lkKSB7XG4gICAgICAgIHRoaXMuYWN0aXZlQ2hhbm5lbFN1YmplY3QubmV4dChjaGFubmVsKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGhhbmRsZUNoYW5uZWxUcnVuY2F0ZShldmVudDogRXZlbnQpIHtcbiAgICBjb25zdCBjaGFubmVsSW5kZXggPSB0aGlzLmNoYW5uZWxzLmZpbmRJbmRleChcbiAgICAgIChjKSA9PiBjLmNpZCA9PT0gZXZlbnQuY2hhbm5lbCEuY2lkXG4gICAgKTtcbiAgICBpZiAoY2hhbm5lbEluZGV4ICE9PSAtMSkge1xuICAgICAgdGhpcy5jaGFubmVsc1tjaGFubmVsSW5kZXhdLnN0YXRlLm1lc3NhZ2VzID0gW107XG4gICAgICB0aGlzLmNoYW5uZWxzU3ViamVjdC5uZXh0KFsuLi50aGlzLmNoYW5uZWxzXSk7XG4gICAgICBpZiAoZXZlbnQuY2hhbm5lbD8uY2lkID09PSB0aGlzLmFjdGl2ZUNoYW5uZWxTdWJqZWN0LmdldFZhbHVlKCk/LmNpZCkge1xuICAgICAgICBjb25zdCBjaGFubmVsID0gdGhpcy5hY3RpdmVDaGFubmVsU3ViamVjdC5nZXRWYWx1ZSgpITtcbiAgICAgICAgY2hhbm5lbC5zdGF0ZS5tZXNzYWdlcyA9IFtdO1xuICAgICAgICB0aGlzLmFjdGl2ZUNoYW5uZWxTdWJqZWN0Lm5leHQoY2hhbm5lbCk7XG4gICAgICAgIHRoaXMuYWN0aXZlQ2hhbm5lbE1lc3NhZ2VzU3ViamVjdC5uZXh0KFtdKTtcbiAgICAgICAgdGhpcy5hY3RpdmVQYXJlbnRNZXNzYWdlSWRTdWJqZWN0Lm5leHQodW5kZWZpbmVkKTtcbiAgICAgICAgdGhpcy5hY3RpdmVUaHJlYWRNZXNzYWdlc1N1YmplY3QubmV4dChbXSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBnZXQgY2FuU2VuZFJlYWRFdmVudHMoKSB7XG4gICAgY29uc3QgY2hhbm5lbCA9IHRoaXMuYWN0aXZlQ2hhbm5lbFN1YmplY3QuZ2V0VmFsdWUoKTtcbiAgICBpZiAoIWNoYW5uZWwpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgY29uc3QgY2FwYWJpbGl0ZXMgPSBjaGFubmVsLmRhdGE/Lm93bl9jYXBhYmlsaXRpZXMgYXMgc3RyaW5nW107XG4gICAgcmV0dXJuIGNhcGFiaWxpdGVzLmluZGV4T2YoJ3JlYWQtZXZlbnRzJykgIT09IC0xO1xuICB9XG5cbiAgcHJpdmF0ZSB0cmFuc2Zvcm1Ub1N0cmVhbU1lc3NhZ2UoXG4gICAgbWVzc2FnZTogU3RyZWFtTWVzc2FnZTxUPiB8IE1lc3NhZ2VSZXNwb25zZTxUPiB8IEZvcm1hdE1lc3NhZ2VSZXNwb25zZTxUPixcbiAgICBjaGFubmVsPzogQ2hhbm5lbDxUPlxuICApIHtcbiAgICBjb25zdCBpc1RocmVhZE1lc3NhZ2UgPSAhIW1lc3NhZ2UucGFyZW50X2lkO1xuICAgIGlmIChcbiAgICAgIHRoaXMuaXNTdHJlYW1NZXNzYWdlKG1lc3NhZ2UpICYmXG4gICAgICB0aGlzLmlzRm9ybWF0TWVzc2FnZVJlc3BvbnNlKG1lc3NhZ2UpXG4gICAgKSB7XG4gICAgICBpZiAobWVzc2FnZS5xdW90ZWRfbWVzc2FnZSkge1xuICAgICAgICBtZXNzYWdlLnF1b3RlZF9tZXNzYWdlLnRyYW5zbGF0aW9uID0gZ2V0TWVzc2FnZVRyYW5zbGF0aW9uKFxuICAgICAgICAgIG1lc3NhZ2UucXVvdGVkX21lc3NhZ2UsXG4gICAgICAgICAgY2hhbm5lbCxcbiAgICAgICAgICB0aGlzLmNoYXRDbGllbnRTZXJ2aWNlLmNoYXRDbGllbnQudXNlclxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgbWVzc2FnZS50cmFuc2xhdGlvbiA9IGdldE1lc3NhZ2VUcmFuc2xhdGlvbihcbiAgICAgICAgbWVzc2FnZSxcbiAgICAgICAgY2hhbm5lbCxcbiAgICAgICAgdGhpcy5jaGF0Q2xpZW50U2VydmljZS5jaGF0Q2xpZW50LnVzZXJcbiAgICAgICk7XG4gICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKG1lc3NhZ2UucXVvdGVkX21lc3NhZ2UpIHtcbiAgICAgICAgbWVzc2FnZS5xdW90ZWRfbWVzc2FnZS50cmFuc2xhdGlvbiA9IGdldE1lc3NhZ2VUcmFuc2xhdGlvbihcbiAgICAgICAgICBtZXNzYWdlLnF1b3RlZF9tZXNzYWdlLFxuICAgICAgICAgIGNoYW5uZWwsXG4gICAgICAgICAgdGhpcy5jaGF0Q2xpZW50U2VydmljZS5jaGF0Q2xpZW50LnVzZXJcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIGlmICh0aGlzLmlzRm9ybWF0TWVzc2FnZVJlc3BvbnNlKG1lc3NhZ2UpKSB7XG4gICAgICAgIG1lc3NhZ2UucmVhZEJ5ID0gaXNUaHJlYWRNZXNzYWdlXG4gICAgICAgICAgPyBbXVxuICAgICAgICAgIDogY2hhbm5lbFxuICAgICAgICAgID8gZ2V0UmVhZEJ5KG1lc3NhZ2UsIGNoYW5uZWwpXG4gICAgICAgICAgOiBbXTtcbiAgICAgICAgbWVzc2FnZS50cmFuc2xhdGlvbiA9IGdldE1lc3NhZ2VUcmFuc2xhdGlvbihcbiAgICAgICAgICBtZXNzYWdlLFxuICAgICAgICAgIGNoYW5uZWwsXG4gICAgICAgICAgdGhpcy5jaGF0Q2xpZW50U2VydmljZS5jaGF0Q2xpZW50LnVzZXJcbiAgICAgICAgKTtcblxuICAgICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG1lc3NhZ2UgPSB0aGlzLmZvcm1hdE1lc3NhZ2UobWVzc2FnZSk7XG4gICAgICAgIG1lc3NhZ2UucmVhZEJ5ID0gaXNUaHJlYWRNZXNzYWdlXG4gICAgICAgICAgPyBbXVxuICAgICAgICAgIDogY2hhbm5lbFxuICAgICAgICAgID8gZ2V0UmVhZEJ5KG1lc3NhZ2UsIGNoYW5uZWwpXG4gICAgICAgICAgOiBbXTtcbiAgICAgICAgbWVzc2FnZS50cmFuc2xhdGlvbiA9IGdldE1lc3NhZ2VUcmFuc2xhdGlvbihcbiAgICAgICAgICBtZXNzYWdlLFxuICAgICAgICAgIGNoYW5uZWwsXG4gICAgICAgICAgdGhpcy5jaGF0Q2xpZW50U2VydmljZS5jaGF0Q2xpZW50LnVzZXJcbiAgICAgICAgKTtcbiAgICAgICAgcmV0dXJuIG1lc3NhZ2U7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBoYW5kbGVUeXBpbmdTdGFydEV2ZW50KGV2ZW50OiBFdmVudCkge1xuICAgIGlmIChldmVudC51c2VyPy5pZCA9PT0gdGhpcy5jaGF0Q2xpZW50U2VydmljZS5jaGF0Q2xpZW50LnVzZXI/LmlkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IGlzVHlwaW5nSW5UaHJlYWQgPSAhIWV2ZW50LnBhcmVudF9pZDtcbiAgICBpZiAoXG4gICAgICBpc1R5cGluZ0luVGhyZWFkICYmXG4gICAgICBldmVudC5wYXJlbnRfaWQgIT09IHRoaXMuYWN0aXZlUGFyZW50TWVzc2FnZUlkU3ViamVjdC5nZXRWYWx1ZSgpXG4gICAgKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IHN1YmplY3QgPSBpc1R5cGluZ0luVGhyZWFkXG4gICAgICA/IHRoaXMudXNlcnNUeXBpbmdJblRocmVhZFN1YmplY3RcbiAgICAgIDogdGhpcy51c2Vyc1R5cGluZ0luQ2hhbm5lbFN1YmplY3Q7XG4gICAgY29uc3QgdXNlcnM6IFVzZXJSZXNwb25zZVtdID0gc3ViamVjdC5nZXRWYWx1ZSgpO1xuICAgIGNvbnN0IHVzZXIgPSBldmVudC51c2VyO1xuICAgIGlmICh1c2VyICYmICF1c2Vycy5maW5kKCh1KSA9PiB1LmlkID09PSB1c2VyLmlkKSkge1xuICAgICAgdXNlcnMucHVzaCh1c2VyKTtcbiAgICAgIHN1YmplY3QubmV4dChbLi4udXNlcnNdKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGhhbmRsZVR5cGluZ1N0b3BFdmVudChldmVudDogRXZlbnQpIHtcbiAgICBjb25zdCB1c2Vyc1R5cGluZ0luQ2hhbm5lbCA9IHRoaXMudXNlcnNUeXBpbmdJbkNoYW5uZWxTdWJqZWN0LmdldFZhbHVlKCk7XG4gICAgY29uc3QgdXNlcnNUeXBpbmdJblRocmVhZCA9IHRoaXMudXNlcnNUeXBpbmdJblRocmVhZFN1YmplY3QuZ2V0VmFsdWUoKTtcbiAgICBjb25zdCB1c2VyID0gZXZlbnQudXNlcjtcbiAgICBpZiAodXNlciAmJiB1c2Vyc1R5cGluZ0luQ2hhbm5lbC5maW5kKCh1KSA9PiB1LmlkID09PSB1c2VyLmlkKSkge1xuICAgICAgdXNlcnNUeXBpbmdJbkNoYW5uZWwuc3BsaWNlKFxuICAgICAgICB1c2Vyc1R5cGluZ0luQ2hhbm5lbC5maW5kSW5kZXgoKHUpID0+IHUuaWQgPT09IHVzZXIuaWQpLFxuICAgICAgICAxXG4gICAgICApO1xuICAgICAgdGhpcy51c2Vyc1R5cGluZ0luQ2hhbm5lbFN1YmplY3QubmV4dChbLi4udXNlcnNUeXBpbmdJbkNoYW5uZWxdKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKHVzZXIgJiYgdXNlcnNUeXBpbmdJblRocmVhZC5maW5kKCh1KSA9PiB1LmlkID09PSB1c2VyLmlkKSkge1xuICAgICAgdXNlcnNUeXBpbmdJblRocmVhZC5zcGxpY2UoXG4gICAgICAgIHVzZXJzVHlwaW5nSW5UaHJlYWQuZmluZEluZGV4KCh1KSA9PiB1LmlkID09PSB1c2VyLmlkKSxcbiAgICAgICAgMVxuICAgICAgKTtcbiAgICAgIHRoaXMudXNlcnNUeXBpbmdJblRocmVhZFN1YmplY3QubmV4dChbLi4udXNlcnNUeXBpbmdJblRocmVhZF0pO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgdXBkYXRlTGF0ZXN0TWVzc2FnZXMoZXZlbnQ6IEV2ZW50KSB7XG4gICAgaWYgKFxuICAgICAgZXZlbnQubWVzc2FnZT8udXNlcj8uaWQgIT09IHRoaXMuY2hhdENsaWVudFNlcnZpY2U/LmNoYXRDbGllbnQudXNlcj8uaWRcbiAgICApIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgbGF0ZXN0TWVzc2FnZXMgPVxuICAgICAgdGhpcy5sYXRlc3RNZXNzYWdlRGF0ZUJ5VXNlckJ5Q2hhbm5lbHNTdWJqZWN0LmdldFZhbHVlKCk7XG4gICAgaWYgKCFldmVudC5tZXNzYWdlPy5jcmVhdGVkX2F0KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IGNoYW5uZWxJZCA9IGV2ZW50Py5tZXNzYWdlPy5jaWQ7XG4gICAgaWYgKCFjaGFubmVsSWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgbWVzc2FnZURhdGUgPSBuZXcgRGF0ZShldmVudC5tZXNzYWdlLmNyZWF0ZWRfYXQpO1xuICAgIGlmIChcbiAgICAgICFsYXRlc3RNZXNzYWdlc1tjaGFubmVsSWRdIHx8XG4gICAgICBsYXRlc3RNZXNzYWdlc1tjaGFubmVsSWRdPy5nZXRUaW1lKCkgPCBtZXNzYWdlRGF0ZS5nZXRUaW1lKClcbiAgICApIHtcbiAgICAgIGxhdGVzdE1lc3NhZ2VzW2NoYW5uZWxJZF0gPSBtZXNzYWdlRGF0ZTtcbiAgICAgIHRoaXMubGF0ZXN0TWVzc2FnZURhdGVCeVVzZXJCeUNoYW5uZWxzU3ViamVjdC5uZXh0KHtcbiAgICAgICAgLi4ubGF0ZXN0TWVzc2FnZXMsXG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHNldENoYW5uZWxTdGF0ZShjaGFubmVsOiBDaGFubmVsPFQ+KSB7XG4gICAgY2hhbm5lbC5zdGF0ZS5tZXNzYWdlcy5mb3JFYWNoKChtKSA9PiB7XG4gICAgICBtLnJlYWRCeSA9IGdldFJlYWRCeShtLCBjaGFubmVsKTtcbiAgICAgIG0udHJhbnNsYXRpb24gPSBnZXRNZXNzYWdlVHJhbnNsYXRpb24oXG4gICAgICAgIG0sXG4gICAgICAgIGNoYW5uZWwsXG4gICAgICAgIHRoaXMuY2hhdENsaWVudFNlcnZpY2UuY2hhdENsaWVudC51c2VyXG4gICAgICApO1xuICAgICAgaWYgKG0ucXVvdGVkX21lc3NhZ2UpIHtcbiAgICAgICAgbS5xdW90ZWRfbWVzc2FnZS50cmFuc2xhdGlvbiA9IGdldE1lc3NhZ2VUcmFuc2xhdGlvbihcbiAgICAgICAgICBtLnF1b3RlZF9tZXNzYWdlLFxuICAgICAgICAgIGNoYW5uZWwsXG4gICAgICAgICAgdGhpcy5jaGF0Q2xpZW50U2VydmljZS5jaGF0Q2xpZW50LnVzZXJcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICB0aGlzLm1hcmtSZWFkKGNoYW5uZWwpO1xuICAgIHRoaXMuYWN0aXZlQ2hhbm5lbE1lc3NhZ2VzU3ViamVjdC5uZXh0KFsuLi5jaGFubmVsLnN0YXRlLm1lc3NhZ2VzXSk7XG4gICAgdGhpcy5hY3RpdmVDaGFubmVsUGlubmVkTWVzc2FnZXNTdWJqZWN0Lm5leHQoW1xuICAgICAgLi4uY2hhbm5lbC5zdGF0ZS5waW5uZWRNZXNzYWdlcyxcbiAgICBdKTtcbiAgICB0aGlzLmFjdGl2ZVBhcmVudE1lc3NhZ2VJZFN1YmplY3QubmV4dCh1bmRlZmluZWQpO1xuICAgIHRoaXMuYWN0aXZlVGhyZWFkTWVzc2FnZXNTdWJqZWN0Lm5leHQoW10pO1xuICAgIHRoaXMubWVzc2FnZVRvUXVvdGVTdWJqZWN0Lm5leHQodW5kZWZpbmVkKTtcbiAgICB0aGlzLnVzZXJzVHlwaW5nSW5DaGFubmVsU3ViamVjdC5uZXh0KFtdKTtcbiAgICB0aGlzLnVzZXJzVHlwaW5nSW5UaHJlYWRTdWJqZWN0Lm5leHQoW10pO1xuICB9XG5cbiAgcHJpdmF0ZSBtYXJrUmVhZChjaGFubmVsOiBDaGFubmVsPFQ+KSB7XG4gICAgaWYgKFxuICAgICAgdGhpcy5jYW5TZW5kUmVhZEV2ZW50cyAmJlxuICAgICAgdGhpcy5zaG91bGRNYXJrQWN0aXZlQ2hhbm5lbEFzUmVhZCAmJlxuICAgICAgIXRoaXMuYXJlUmVhZEV2ZW50c1BhdXNlZFxuICAgICkge1xuICAgICAgdm9pZCBjaGFubmVsLm1hcmtSZWFkKCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBzZXROZXh0UGFnZUNvbmZpZ3VyYXRpb24oY2hhbm5lbFF1ZXJ5UmVzdWx0OiBDaGFubmVsPFQ+W10pIHtcbiAgICBpZiAodGhpcy5jdXN0b21QYWdpbmF0b3IpIHtcbiAgICAgIHRoaXMubmV4dFBhZ2VDb25maWd1cmF0aW9uID0gdGhpcy5jdXN0b21QYWdpbmF0b3IoY2hhbm5lbFF1ZXJ5UmVzdWx0KTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5uZXh0UGFnZUNvbmZpZ3VyYXRpb24gPSB7XG4gICAgICAgIHR5cGU6ICdvZmZzZXQnLFxuICAgICAgICBvZmZzZXQ6XG4gICAgICAgICAgKHRoaXMubmV4dFBhZ2VDb25maWd1cmF0aW9uPy50eXBlID09PSAnb2Zmc2V0J1xuICAgICAgICAgICAgPyB0aGlzLm5leHRQYWdlQ29uZmlndXJhdGlvbi5vZmZzZXRcbiAgICAgICAgICAgIDogMCkgKyBjaGFubmVsUXVlcnlSZXN1bHQubGVuZ3RoLFxuICAgICAgfTtcbiAgICB9XG4gIH1cbn1cbiJdfQ==