@jubbio/core 1.3.1 → 1.3.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 (121) hide show
  1. package/dist/cjs/Client.d.ts +157 -0
  2. package/dist/cjs/Client.js +640 -0
  3. package/dist/cjs/builders/ActionRowBuilder.d.ts +53 -0
  4. package/dist/cjs/builders/ActionRowBuilder.js +68 -0
  5. package/dist/cjs/builders/ButtonBuilder.d.ts +77 -0
  6. package/dist/cjs/builders/ButtonBuilder.js +96 -0
  7. package/dist/cjs/builders/EmbedBuilder.d.ts +157 -0
  8. package/dist/cjs/builders/EmbedBuilder.js +208 -0
  9. package/dist/cjs/builders/ModalBuilder.d.ts +122 -0
  10. package/dist/cjs/builders/ModalBuilder.js +162 -0
  11. package/dist/cjs/builders/SelectMenuBuilder.d.ts +123 -0
  12. package/dist/cjs/builders/SelectMenuBuilder.js +165 -0
  13. package/dist/cjs/builders/SlashCommandBuilder.d.ts +197 -0
  14. package/dist/cjs/builders/SlashCommandBuilder.js +324 -0
  15. package/dist/cjs/builders/index.d.ts +9 -0
  16. package/dist/cjs/builders/index.js +26 -0
  17. package/dist/cjs/enums.d.ts +191 -0
  18. package/dist/cjs/enums.js +211 -0
  19. package/dist/cjs/index.d.ts +25 -0
  20. package/dist/cjs/index.js +130 -0
  21. package/dist/cjs/managers/BaseManager.d.ts +69 -0
  22. package/dist/cjs/managers/BaseManager.js +106 -0
  23. package/dist/cjs/managers/ChannelManager.d.ts +95 -0
  24. package/dist/cjs/managers/ChannelManager.js +205 -0
  25. package/dist/cjs/managers/GuildMemberManager.d.ts +74 -0
  26. package/dist/cjs/managers/GuildMemberManager.js +157 -0
  27. package/dist/cjs/managers/RoleManager.d.ts +84 -0
  28. package/dist/cjs/managers/RoleManager.js +207 -0
  29. package/dist/cjs/managers/index.d.ts +7 -0
  30. package/dist/cjs/managers/index.js +24 -0
  31. package/dist/cjs/rest/REST.d.ts +527 -0
  32. package/dist/cjs/rest/REST.js +904 -0
  33. package/dist/cjs/rest/index.d.ts +1 -0
  34. package/dist/cjs/rest/index.js +18 -0
  35. package/dist/cjs/sharding/ShardingManager.d.ts +179 -0
  36. package/dist/cjs/sharding/ShardingManager.js +375 -0
  37. package/dist/cjs/sharding/index.d.ts +4 -0
  38. package/dist/cjs/sharding/index.js +21 -0
  39. package/dist/cjs/structures/Channel.d.ts +122 -0
  40. package/dist/cjs/structures/Channel.js +240 -0
  41. package/dist/cjs/structures/Collection.d.ts +53 -0
  42. package/dist/cjs/structures/Collection.js +115 -0
  43. package/dist/cjs/structures/Guild.d.ts +59 -0
  44. package/dist/cjs/structures/Guild.js +94 -0
  45. package/dist/cjs/structures/GuildMember.d.ts +174 -0
  46. package/dist/cjs/structures/GuildMember.js +311 -0
  47. package/dist/cjs/structures/Interaction.d.ts +245 -0
  48. package/dist/cjs/structures/Interaction.js +450 -0
  49. package/dist/cjs/structures/Message.d.ts +98 -0
  50. package/dist/cjs/structures/Message.js +195 -0
  51. package/dist/cjs/structures/User.d.ts +37 -0
  52. package/dist/cjs/structures/User.js +65 -0
  53. package/dist/cjs/structures/index.d.ts +7 -0
  54. package/dist/cjs/structures/index.js +25 -0
  55. package/dist/cjs/structures.d.ts +1 -0
  56. package/dist/cjs/structures.js +19 -0
  57. package/dist/cjs/types.d.ts +255 -0
  58. package/dist/cjs/types.js +3 -0
  59. package/dist/cjs/utils/BitField.d.ts +66 -0
  60. package/dist/cjs/utils/BitField.js +138 -0
  61. package/dist/cjs/utils/Collection.d.ts +116 -0
  62. package/dist/cjs/utils/Collection.js +265 -0
  63. package/dist/cjs/utils/Collector.d.ts +152 -0
  64. package/dist/cjs/utils/Collector.js +314 -0
  65. package/dist/cjs/utils/DataResolver.d.ts +61 -0
  66. package/dist/cjs/utils/DataResolver.js +146 -0
  67. package/dist/cjs/utils/Formatters.d.ts +145 -0
  68. package/dist/cjs/utils/Formatters.js +213 -0
  69. package/dist/cjs/utils/IntentsBitField.d.ts +85 -0
  70. package/dist/cjs/utils/IntentsBitField.js +99 -0
  71. package/dist/cjs/utils/Partials.d.ts +104 -0
  72. package/dist/cjs/utils/Partials.js +148 -0
  73. package/dist/cjs/utils/PermissionsBitField.d.ts +118 -0
  74. package/dist/cjs/utils/PermissionsBitField.js +145 -0
  75. package/dist/cjs/utils/SnowflakeUtil.d.ts +63 -0
  76. package/dist/cjs/utils/SnowflakeUtil.js +93 -0
  77. package/dist/cjs/utils/Sweepers.d.ts +119 -0
  78. package/dist/cjs/utils/Sweepers.js +249 -0
  79. package/dist/cjs/utils/index.d.ts +13 -0
  80. package/dist/cjs/utils/index.js +30 -0
  81. package/dist/esm/Client.js +634 -0
  82. package/dist/esm/builders/ActionRowBuilder.js +64 -0
  83. package/dist/esm/builders/ButtonBuilder.js +92 -0
  84. package/dist/esm/builders/EmbedBuilder.js +204 -0
  85. package/dist/esm/builders/ModalBuilder.js +157 -0
  86. package/dist/esm/builders/SelectMenuBuilder.js +161 -0
  87. package/dist/esm/builders/SlashCommandBuilder.js +311 -0
  88. package/dist/esm/builders/index.js +10 -0
  89. package/dist/esm/enums.js +208 -0
  90. package/dist/esm/index.js +34 -0
  91. package/dist/esm/managers/BaseManager.js +100 -0
  92. package/dist/esm/managers/ChannelManager.js +200 -0
  93. package/dist/esm/managers/GuildMemberManager.js +153 -0
  94. package/dist/esm/managers/RoleManager.js +203 -0
  95. package/dist/esm/managers/index.js +8 -0
  96. package/dist/esm/rest/REST.js +900 -0
  97. package/dist/esm/rest/index.js +2 -0
  98. package/dist/esm/sharding/ShardingManager.js +366 -0
  99. package/dist/esm/sharding/index.js +5 -0
  100. package/dist/esm/structures/Channel.js +232 -0
  101. package/dist/esm/structures/Collection.js +111 -0
  102. package/dist/esm/structures/Guild.js +90 -0
  103. package/dist/esm/structures/GuildMember.js +306 -0
  104. package/dist/esm/structures/Interaction.js +438 -0
  105. package/dist/esm/structures/Message.js +191 -0
  106. package/dist/esm/structures/User.js +61 -0
  107. package/dist/esm/structures/index.js +9 -0
  108. package/dist/esm/structures.js +3 -0
  109. package/dist/esm/types.js +2 -0
  110. package/dist/esm/utils/BitField.js +134 -0
  111. package/dist/esm/utils/Collection.js +261 -0
  112. package/dist/esm/utils/Collector.js +305 -0
  113. package/dist/esm/utils/DataResolver.js +142 -0
  114. package/dist/esm/utils/Formatters.js +191 -0
  115. package/dist/esm/utils/IntentsBitField.js +93 -0
  116. package/dist/esm/utils/Partials.js +137 -0
  117. package/dist/esm/utils/PermissionsBitField.js +141 -0
  118. package/dist/esm/utils/SnowflakeUtil.js +89 -0
  119. package/dist/esm/utils/Sweepers.js +245 -0
  120. package/dist/esm/utils/index.js +14 -0
  121. package/package.json +14 -4
@@ -0,0 +1,438 @@
1
+ import { InteractionType, InteractionResponseType, MessageFlags } from '../enums';
2
+ import { User } from './User';
3
+ import { GuildMember } from './GuildMember';
4
+ import { EmbedBuilder } from '../builders/EmbedBuilder';
5
+ /**
6
+ * Base interaction class
7
+ */
8
+ export class Interaction {
9
+ /** Reference to the client */
10
+ client;
11
+ /** Interaction ID */
12
+ id;
13
+ /** Application ID */
14
+ applicationId;
15
+ /** Interaction type */
16
+ type;
17
+ /** Guild ID */
18
+ guildId;
19
+ /** Channel ID */
20
+ channelId;
21
+ /** Interaction token */
22
+ token;
23
+ /** User who triggered the interaction */
24
+ user;
25
+ /** Guild member (if in a guild) */
26
+ member;
27
+ /** Whether the interaction has been replied to */
28
+ replied = false;
29
+ /** Whether the interaction has been deferred */
30
+ deferred = false;
31
+ constructor(client, data) {
32
+ this.client = client;
33
+ // Handle both string and number IDs
34
+ this.id = String(data.id);
35
+ this.applicationId = String(data.application_id);
36
+ this.type = data.type;
37
+ this.guildId = data.guild_id ? String(data.guild_id) : undefined;
38
+ this.channelId = data.channel_id ? String(data.channel_id) : undefined;
39
+ this.token = data.token;
40
+ // User can come from member.user or directly from user
41
+ const userData = data.member?.user || data.user;
42
+ this.user = userData ? new User(userData) : new User({ id: '0', username: 'Unknown' });
43
+ // Create member if in guild
44
+ if (data.member && this.guildId) {
45
+ const guild = client.guilds.get(this.guildId) || { id: this.guildId, ownerId: null };
46
+ this.member = new GuildMember(client, guild, data.member);
47
+ }
48
+ }
49
+ /**
50
+ * Check if this is a command interaction
51
+ */
52
+ isCommand() {
53
+ return this.type === InteractionType.ApplicationCommand;
54
+ }
55
+ /**
56
+ * Check if this is an autocomplete interaction
57
+ */
58
+ isAutocomplete() {
59
+ return this.type === InteractionType.ApplicationCommandAutocomplete;
60
+ }
61
+ /**
62
+ * Check if this is a modal submit interaction
63
+ */
64
+ isModalSubmit() {
65
+ return this.type === InteractionType.ModalSubmit;
66
+ }
67
+ /**
68
+ * Check if this is a button interaction
69
+ */
70
+ isButton() {
71
+ return this.type === InteractionType.MessageComponent && this.componentType === 2;
72
+ }
73
+ /**
74
+ * Check if this is a select menu interaction
75
+ */
76
+ isSelectMenu() {
77
+ return this.type === InteractionType.MessageComponent && this.componentType === 3;
78
+ }
79
+ /**
80
+ * Reply to the interaction
81
+ */
82
+ async reply(options) {
83
+ if (this.replied || this.deferred) {
84
+ throw new Error('Interaction has already been replied to or deferred');
85
+ }
86
+ const content = typeof options === 'string' ? options : options.content;
87
+ const rawEmbeds = typeof options === 'string' ? undefined : options.embeds;
88
+ const components = typeof options === 'string' ? undefined : options.components;
89
+ const ephemeral = typeof options === 'string' ? false : options.ephemeral;
90
+ // Convert EmbedBuilder instances to plain objects
91
+ const embeds = rawEmbeds?.map(e => e instanceof EmbedBuilder ? e.toJSON() : e);
92
+ await this.client.rest.createInteractionResponse(this.id, this.token, {
93
+ type: InteractionResponseType.ChannelMessageWithSource,
94
+ data: {
95
+ content,
96
+ embeds,
97
+ components,
98
+ flags: ephemeral ? MessageFlags.Ephemeral : 0
99
+ }
100
+ });
101
+ this.replied = true;
102
+ }
103
+ /**
104
+ * Defer the reply (shows "thinking...")
105
+ */
106
+ async deferReply(options) {
107
+ if (this.replied || this.deferred) {
108
+ throw new Error('Interaction has already been replied to or deferred');
109
+ }
110
+ await this.client.rest.createInteractionResponse(this.id, this.token, {
111
+ type: InteractionResponseType.DeferredChannelMessageWithSource,
112
+ data: options?.ephemeral ? { flags: MessageFlags.Ephemeral } : undefined
113
+ });
114
+ this.deferred = true;
115
+ }
116
+ /**
117
+ * Edit the reply
118
+ */
119
+ async editReply(options) {
120
+ const content = typeof options === 'string' ? options : options.content;
121
+ const rawEmbeds = typeof options === 'string' ? undefined : options.embeds;
122
+ const components = typeof options === 'string' ? undefined : options.components;
123
+ const files = typeof options === 'string' ? undefined : options.files;
124
+ // Convert EmbedBuilder instances to plain objects
125
+ const embeds = rawEmbeds?.map(e => e instanceof EmbedBuilder ? e.toJSON() : e);
126
+ await this.client.rest.editInteractionResponse(this.token, {
127
+ content,
128
+ embeds,
129
+ components,
130
+ files
131
+ }, this.guildId, this.channelId, this.id);
132
+ }
133
+ /**
134
+ * Delete the reply
135
+ */
136
+ async deleteReply() {
137
+ await this.client.rest.deleteInteractionResponse(this.token);
138
+ }
139
+ /**
140
+ * Send a followup message
141
+ */
142
+ async followUp(options) {
143
+ const content = typeof options === 'string' ? options : options.content;
144
+ const rawEmbeds = typeof options === 'string' ? undefined : options.embeds;
145
+ const ephemeral = typeof options === 'string' ? false : options.ephemeral;
146
+ // Convert EmbedBuilder instances to plain objects
147
+ const embeds = rawEmbeds?.map(e => e instanceof EmbedBuilder ? e.toJSON() : e);
148
+ await this.client.rest.createFollowup(this.token, {
149
+ content,
150
+ embeds,
151
+ flags: ephemeral ? MessageFlags.Ephemeral : 0
152
+ });
153
+ }
154
+ }
155
+ /**
156
+ * Command interaction
157
+ */
158
+ export class CommandInteraction extends Interaction {
159
+ /** Command name */
160
+ commandName;
161
+ /** Command options */
162
+ options;
163
+ constructor(client, data) {
164
+ super(client, data);
165
+ this.commandName = data.data?.name || '';
166
+ this.options = new CommandInteractionOptions(data.data?.options || []);
167
+ }
168
+ /**
169
+ * Show a modal
170
+ */
171
+ async showModal(modal) {
172
+ const modalData = 'toJSON' in modal && typeof modal.toJSON === 'function' ? modal.toJSON() : modal;
173
+ await this.client.rest.createInteractionResponse(this.id, this.token, {
174
+ type: InteractionResponseType.Modal,
175
+ data: modalData
176
+ });
177
+ }
178
+ }
179
+ /**
180
+ * Command interaction options helper
181
+ */
182
+ export class CommandInteractionOptions {
183
+ options;
184
+ constructor(options) {
185
+ this.options = options;
186
+ }
187
+ /**
188
+ * Get a string option
189
+ */
190
+ getString(name, required) {
191
+ const option = this.options.find(o => o.name === name);
192
+ if (!option && required)
193
+ throw new Error(`Required option "${name}" not found`);
194
+ return option?.value || null;
195
+ }
196
+ /**
197
+ * Get an integer option
198
+ */
199
+ getInteger(name, required) {
200
+ const option = this.options.find(o => o.name === name);
201
+ if (!option && required)
202
+ throw new Error(`Required option "${name}" not found`);
203
+ return option?.value || null;
204
+ }
205
+ /**
206
+ * Get a number option
207
+ */
208
+ getNumber(name, required) {
209
+ return this.getInteger(name, required);
210
+ }
211
+ /**
212
+ * Get a boolean option
213
+ */
214
+ getBoolean(name, required) {
215
+ const option = this.options.find(o => o.name === name);
216
+ if (!option && required)
217
+ throw new Error(`Required option "${name}" not found`);
218
+ return option?.value ?? null;
219
+ }
220
+ /**
221
+ * Get a user option
222
+ */
223
+ getUser(name, required) {
224
+ const option = this.options.find(o => o.name === name);
225
+ if (!option && required)
226
+ throw new Error(`Required option "${name}" not found`);
227
+ return option?.value || null;
228
+ }
229
+ /**
230
+ * Get a channel option
231
+ */
232
+ getChannel(name, required) {
233
+ const option = this.options.find(o => o.name === name);
234
+ if (!option && required)
235
+ throw new Error(`Required option "${name}" not found`);
236
+ return option?.value || null;
237
+ }
238
+ /**
239
+ * Get a subcommand name
240
+ */
241
+ getSubcommand(required) {
242
+ const option = this.options.find(o => o.type === 1);
243
+ if (!option && required)
244
+ throw new Error('Required subcommand not found');
245
+ return option?.name || null;
246
+ }
247
+ /**
248
+ * Get the focused option (for autocomplete)
249
+ */
250
+ getFocused() {
251
+ const option = this.options.find(o => o.focused);
252
+ if (!option)
253
+ return null;
254
+ return { name: option.name, value: option.value };
255
+ }
256
+ }
257
+ /**
258
+ * Autocomplete interaction
259
+ */
260
+ export class AutocompleteInteraction extends Interaction {
261
+ /** Command name */
262
+ commandName;
263
+ /** Command options */
264
+ options;
265
+ constructor(client, data) {
266
+ super(client, data);
267
+ this.commandName = data.data?.name || '';
268
+ this.options = new CommandInteractionOptions(data.data?.options || []);
269
+ }
270
+ /**
271
+ * Respond with autocomplete choices
272
+ */
273
+ async respond(choices) {
274
+ await this.client.rest.createInteractionResponse(this.id, this.token, {
275
+ type: InteractionResponseType.ApplicationCommandAutocompleteResult,
276
+ data: { choices }
277
+ });
278
+ }
279
+ }
280
+ /**
281
+ * Button interaction
282
+ */
283
+ export class ButtonInteraction extends Interaction {
284
+ /** Button custom ID */
285
+ customId;
286
+ /** Component type (always 2 for buttons) */
287
+ componentType = 2;
288
+ /** Message the button is attached to */
289
+ message;
290
+ constructor(client, data) {
291
+ super(client, data);
292
+ this.customId = data.data?.custom_id || '';
293
+ this.message = data.message;
294
+ }
295
+ /**
296
+ * Update the message the button is attached to
297
+ */
298
+ async update(options) {
299
+ // Convert EmbedBuilder instances to plain objects
300
+ const embeds = options.embeds?.map(e => e instanceof EmbedBuilder ? e.toJSON() : e);
301
+ await this.client.rest.createInteractionResponse(this.id, this.token, {
302
+ type: InteractionResponseType.UpdateMessage,
303
+ data: {
304
+ content: options.content,
305
+ embeds,
306
+ components: options.components
307
+ }
308
+ });
309
+ this.replied = true;
310
+ }
311
+ /**
312
+ * Show a modal in response to this button interaction
313
+ */
314
+ async showModal(modal) {
315
+ const modalData = 'toJSON' in modal && typeof modal.toJSON === 'function' ? modal.toJSON() : modal;
316
+ await this.client.rest.createInteractionResponse(this.id, this.token, {
317
+ type: InteractionResponseType.Modal,
318
+ data: modalData
319
+ });
320
+ }
321
+ }
322
+ /**
323
+ * Select menu interaction
324
+ */
325
+ export class SelectMenuInteraction extends Interaction {
326
+ /** Select menu custom ID */
327
+ customId;
328
+ /** Component type (always 3 for select menus) */
329
+ componentType = 3;
330
+ /** Selected values */
331
+ values;
332
+ /** Message the select menu is attached to */
333
+ message;
334
+ constructor(client, data) {
335
+ super(client, data);
336
+ this.customId = data.data?.custom_id || '';
337
+ this.values = data.data?.values || [];
338
+ this.message = data.message;
339
+ }
340
+ /**
341
+ * Update the message the select menu is attached to
342
+ */
343
+ async update(options) {
344
+ // Convert EmbedBuilder instances to plain objects
345
+ const embeds = options.embeds?.map(e => e instanceof EmbedBuilder ? e.toJSON() : e);
346
+ await this.client.rest.createInteractionResponse(this.id, this.token, {
347
+ type: InteractionResponseType.UpdateMessage,
348
+ data: {
349
+ content: options.content,
350
+ embeds,
351
+ components: options.components
352
+ }
353
+ });
354
+ this.replied = true;
355
+ }
356
+ /**
357
+ * Show a modal in response to this select menu interaction
358
+ */
359
+ async showModal(modal) {
360
+ const modalData = 'toJSON' in modal && typeof modal.toJSON === 'function' ? modal.toJSON() : modal;
361
+ await this.client.rest.createInteractionResponse(this.id, this.token, {
362
+ type: InteractionResponseType.Modal,
363
+ data: modalData
364
+ });
365
+ }
366
+ }
367
+ /**
368
+ * Modal submit interaction
369
+ */
370
+ export class ModalSubmitInteraction extends Interaction {
371
+ /** Modal custom ID */
372
+ customId;
373
+ /** Modal fields */
374
+ fields;
375
+ constructor(client, data) {
376
+ super(client, data);
377
+ this.customId = data.data?.custom_id || '';
378
+ // Modal values come from components array (action rows containing text inputs)
379
+ const components = data.data?.components || [];
380
+ this.fields = new ModalFields(components);
381
+ }
382
+ }
383
+ /**
384
+ * Modal fields helper
385
+ */
386
+ export class ModalFields {
387
+ fieldMap;
388
+ constructor(components) {
389
+ this.fieldMap = new Map();
390
+ // Parse action rows → text inputs
391
+ for (const row of components) {
392
+ const innerComponents = row?.components || [];
393
+ for (const comp of innerComponents) {
394
+ if (comp.custom_id && comp.value !== undefined) {
395
+ this.fieldMap.set(comp.custom_id, comp.value);
396
+ }
397
+ }
398
+ }
399
+ }
400
+ /**
401
+ * Get a text input value by custom_id
402
+ */
403
+ getTextInputValue(customId) {
404
+ return this.fieldMap.get(customId) ?? null;
405
+ }
406
+ /**
407
+ * Get a field (alias for getTextInputValue)
408
+ */
409
+ getField(customId) {
410
+ const value = this.fieldMap.get(customId);
411
+ return value !== undefined ? { value } : null;
412
+ }
413
+ }
414
+ /**
415
+ * Create appropriate interaction class based on type
416
+ */
417
+ export function createInteraction(client, data) {
418
+ switch (data.type) {
419
+ case InteractionType.ApplicationCommand:
420
+ return new CommandInteraction(client, data);
421
+ case InteractionType.ApplicationCommandAutocomplete:
422
+ return new AutocompleteInteraction(client, data);
423
+ case InteractionType.ModalSubmit:
424
+ return new ModalSubmitInteraction(client, data);
425
+ case InteractionType.MessageComponent:
426
+ // component_type: 2 = Button, 3 = Select Menu
427
+ if (data.data?.component_type === 2) {
428
+ return new ButtonInteraction(client, data);
429
+ }
430
+ else if (data.data?.component_type === 3) {
431
+ return new SelectMenuInteraction(client, data);
432
+ }
433
+ return new Interaction(client, data);
434
+ default:
435
+ return new Interaction(client, data);
436
+ }
437
+ }
438
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiSW50ZXJhY3Rpb24uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvc3RydWN0dXJlcy9JbnRlcmFjdGlvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLEVBQUUsZUFBZSxFQUFFLHVCQUF1QixFQUFFLFlBQVksRUFBRSxNQUFNLFVBQVUsQ0FBQztBQUNsRixPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sUUFBUSxDQUFDO0FBQzlCLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDNUMsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBR3hEOztHQUVHO0FBQ0gsTUFBTSxPQUFPLFdBQVc7SUFDdEIsOEJBQThCO0lBQ2QsTUFBTSxDQUFTO0lBRS9CLHFCQUFxQjtJQUNMLEVBQUUsQ0FBUztJQUUzQixxQkFBcUI7SUFDTCxhQUFhLENBQVM7SUFFdEMsdUJBQXVCO0lBQ1AsSUFBSSxDQUFrQjtJQUV0QyxlQUFlO0lBQ0MsT0FBTyxDQUFVO0lBRWpDLGlCQUFpQjtJQUNELFNBQVMsQ0FBVTtJQUVuQyx3QkFBd0I7SUFDUixLQUFLLENBQVM7SUFFOUIseUNBQXlDO0lBQ3pCLElBQUksQ0FBTztJQUUzQixtQ0FBbUM7SUFDbkIsTUFBTSxDQUFlO0lBRXJDLGtEQUFrRDtJQUMzQyxPQUFPLEdBQUcsS0FBSyxDQUFDO0lBRXZCLGdEQUFnRDtJQUN6QyxRQUFRLEdBQUcsS0FBSyxDQUFDO0lBRXhCLFlBQVksTUFBYyxFQUFFLElBQW9CO1FBQzlDLElBQUksQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFDO1FBQ3JCLG9DQUFvQztRQUNwQyxJQUFJLENBQUMsRUFBRSxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDMUIsSUFBSSxDQUFDLGFBQWEsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxDQUFDO1FBQ2pELElBQUksQ0FBQyxJQUFJLEdB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QUksQ0FBQyxJQUFJLEVBQUUsY0FBYyxLQUFLLENBQUMsRUFBRSxDQUFDO2dCQUNwQyxPQUFPLElBQUksaUJBQWlCLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxDQUFDO1lBQzdDLENBQUM7aUJBQU0sSUFBSSxJQUFJLENBQUMsSUFBSSxFQUFFLGNBQWMsS0FBSyxDQUFDLEVBQUUsQ0FBQztnQkFDM0MsT0FBTyxJQUFJLHFCQUFxQixDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsQ0FBQztZQUNqRCxDQUFDO1lBQ0QsT0FBTyxJQUFJLFdBQVcsQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDdkM7WUFDRSxPQUFPLElBQUksV0FBVyxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsQ0FBQztJQUN6QyxDQUFDO0FBQ0gsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEFQSUludGVyYWN0aW9uLCBBUElJbnRlcmFjdGlvbk9wdGlvbiwgQVBJRW1iZWQgfSBmcm9tICcuLi90eXBlcyc7XHJcbmltcG9ydCB7IEludGVyYWN0aW9uVHlwZSwgSW50ZXJhY3Rpb25SZXNwb25zZVR5cGUsIE1lc3NhZ2VGbGFncyB9IGZyb20gJy4uL2VudW1zJztcclxuaW1wb3J0IHsgVXNlciB9IGZyb20gJy4vVXNlcic7XHJcbmltcG9ydCB7IEd1aWxkTWVtYmVyIH0gZnJvbSAnLi9HdWlsZE1lbWJlcic7XHJcbmltcG9ydCB7IEVtYmVkQnVpbGRlciB9IGZyb20gJy4uL2J1aWxkZXJzL0VtYmVkQnVpbGRlcic7XHJcbmltcG9ydCB0eXBlIHsgQ2xpZW50IH0gZnJvbSAnLi4vQ2xpZW50JztcclxuXHJcbi8qKlxyXG4gKiBCYXNlIGludGVyYWN0aW9uIGNsYXNzXHJcbiAqL1xyXG5leHBvcnQgY2xhc3MgSW50ZXJhY3Rpb24ge1xyXG4gIC8qKiBSZWZlcmVuY2UgdG8gdGhlIGNsaWVudCAqL1xyXG4gIHB1YmxpYyByZWFkb25seSBjbGllbnQ6IENsaWVudDtcclxuICBcclxuICAvKiogSW50ZXJhY3Rpb24gSUQgKi9cclxuICBwdWJsaWMgcmVhZG9ubHkgaWQ6IHN0cmluZztcclxuICBcclxuICAvKiogQXBwbGljYXRpb24gSUQgKi9cclxuICBwdWJsaWMgcmVhZG9ubHkgYXBwbGljYXRpb25JZDogc3RyaW5nO1xyXG4gIFxyXG4gIC8qKiBJbnRlcmFjdGlvbiB0eXBlICovXHJcbiAgcHVibGljIHJlYWRvbmx5IHR5cGU6IEludGVyYWN0aW9uVHlwZTtcclxuICBcclxuICAvKiogR3VpbGQgSUQgKi9cclxuICBwdWJsaWMgcmVhZG9ubHkgZ3VpbGRJZD86IHN0cmluZztcclxuICBcclxuICAvKiogQ2hhbm5lbCBJRCAqL1xyXG4gIHB1YmxpYyByZWFkb25seSBjaGFubmVsSWQ/OiBzdHJpbmc7XHJcbiAgXHJcbiAgLyoqIEludGVyYWN0aW9uIHRva2VuICovXHJcbiAgcHVibGljIHJlYWRvbmx5IHRva2VuOiBzdHJpbmc7XHJcbiAgXHJcbiAgLyoqIFVzZXIgd2hvIHRyaWdnZXJlZCB0aGUgaW50ZXJhY3Rpb24gKi9cclxuICBwdWJsaWMgcmVhZG9ubHkgdXNlcjogVXNlcjtcclxuICBcclxuICAvKiogR3VpbGQgbWVtYmVyIChpZiBpbiBhIGd1aWxkKSAqL1xyXG4gIHB1YmxpYyByZWFkb25seSBtZW1iZXI/OiBHdWlsZE1lbWJlcjtcclxuICBcclxuICAvKiogV2hldGhlciB0aGUgaW50ZXJhY3Rpb24gaGFzIGJlZW4gcmVwbGllZCB0byAqL1xyXG4gIHB1YmxpYyByZXBsaWVkID0gZmFsc2U7XHJcbiAgXHJcbiAgLyoqIFdoZXRoZXIgdGhlIGludGVyYWN0aW9uIGhhcyBiZWVuIGRlZmVycmVkICovXHJcbiAgcHVibGljIGRlZmVycmVkID0gZmFsc2U7XHJcblxyXG4gIGNvbnN0cnVjdG9yKGNsaWVudDogQ2xpZW50LCBkYXRhOiBBUElJbnRlcmFjdGlvbikge1xyXG4gICAgdGhpcy5jbGllbnQgPSBjbGllbnQ7XHJcbiAgICAvLyBIYW5kbGUgYm90aCBzdHJpbmcgYW5kIG51bWJlciBJRHNcclxuICAgIHRoaXMuaWQgPSBTdHJpbmcoZGF0YS5pZCk7XHJcbiAgICB0aGlzLmFwcGxpY2F0aW9uSWQgPSBTdHJpbmcoZGF0YS5hcHBsaWNhdGlvbl9pZCk7XHJcbiAgICB0aGlzLnR5cGUgPSBkYXRhLnR5cGU7XHJcbiAgICB0aGlzLmd1aWxkSWQgPSBkYXRhLmd1aWxkX2lkID8gU3RyaW5nKGRhdGEuZ3VpbGRfaWQpIDogdW5kZWZpbmVkO1xyXG4gICAgdGhpcy5jaGFubmVsSWQgPSBkYXRhLmNoYW5uZWxfaWQgPyBTdHJpbmcoZGF0YS5jaGFubmVsX2lkKSA6IHVuZGVmaW5lZDtcclxuICAgIHRoaXMudG9rZW4gPSBkYXRhLnRva2VuO1xyXG4gICAgXHJcbiAgICAvLyBVc2VyIGNhbiBjb21lIGZyb20gbWVtYmVyLnVzZXIgb3IgZGlyZWN0bHkgZnJvbSB1c2VyXHJcbiAgICBjb25zdCB1c2VyRGF0YSA9IGRhdGEubWVtYmVyPy51c2VyIHx8IGRhdGEudXNlcjtcclxuICAgIHRoaXMudXNlciA9IHVzZXJEYXRhID8gbmV3IFVzZXIodXNlckRhdGEpIDogbmV3IFVzZXIoeyBpZDogJzAnLCB1c2VybmFtZTogJ1Vua25vd24nIH0pO1xyXG4gICAgXHJcbiAgICAvLyBDcmVhdGUgbWVtYmVyIGlmIGluIGd1aWxkXHJcbiAgICBpZiAoZGF0YS5tZW1iZXIgJiYgdGhpcy5ndWlsZElkKSB7XHJcbiAgICAgIGNvbnN0IGd1aWxkID0gY2xpZW50Lmd1aWxkcy5nZXQodGhpcy5ndWlsZElkKSB8fCB7IGlkOiB0aGlzLmd1aWxkSWQsIG93bmVySWQ6IG51bGwgfSBhcyBhbnk7XHJcbiAgICAgIHRoaXMubWVtYmVyID0gbmV3IEd1aWxkTWVtYmVyKGNsaWVudCwgZ3VpbGQsIGRhdGEubWVtYmVyKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIENoZWNrIGlmIHRoaXMgaXMgYSBjb21tYW5kIGludGVyYWN0aW9uXHJcbiAgICovXHJcbiAgaXNDb21tYW5kKCk6IHRoaXMgaXMgQ29tbWFuZEludGVyYWN0aW9uIHtcclxuICAgIHJldHVybiB0aGlzLnR5cGUgPT09IEludGVyYWN0aW9uVHlwZS5BcHBsaWNhdGlvbkNvbW1hbmQ7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBDaGVjayBpZiB0aGlzIGlzIGFuIGF1dG9jb21wbGV0ZSBpbnRlcmFjdGlvblxyXG4gICAqL1xyXG4gIGlzQXV0b2NvbXBsZXRlKCk6IHRoaXMgaXMgQXV0b2NvbXBsZXRlSW50ZXJhY3Rpb24ge1xyXG4gICAgcmV0dXJuIHRoaXMudHlwZSA9PT0gSW50ZXJhY3Rpb25UeXBlLkFwcGxpY2F0aW9uQ29tbWFuZEF1dG9jb21wbGV0ZTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIENoZWNrIGlmIHRoaXMgaXMgYSBtb2RhbCBzdWJtaXQgaW50ZXJhY3Rpb25cclxuICAgKi9cclxuICBpc01vZGFsU3VibWl0KCk6IHRoaXMgaXMgTW9kYWxTdWJtaXRJbnRlcmFjdGlvbiB7XHJcbiAgICByZXR1cm4gdGhpcy50eXBlID09PSBJbnRlcmFjdGlvblR5cGUuTW9kYWxTdWJtaXQ7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBDaGVjayBpZiB0aGlzIGlzIGEgYnV0dG9uIGludGVyYWN0aW9uXHJcbiAgICovXHJcbiAgaXNCdXR0b24oKTogdGhpcyBpcyBCdXR0b25JbnRlcmFjdGlvbiB7XHJcbiAgICByZXR1cm4gdGhpcy50eXBlID09PSBJbnRlcmFjdGlvblR5cGUuTWVzc2FnZUNvbXBvbmVudCAmJiAodGhpcyBhcyBhbnkpLmNvbXBvbmVudFR5cGUgPT09IDI7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBDaGVjayBpZiB0aGlzIGlzIGEgc2VsZWN0IG1lbnUgaW50ZXJhY3Rpb25cclxuICAgKi9cclxuICBpc1NlbGVjdE1lbnUoKTogdGhpcyBpcyBTZWxlY3RNZW51SW50ZXJhY3Rpb24ge1xyXG4gICAgcmV0dXJuIHRoaXMudHlwZSA9PT0gSW50ZXJhY3Rpb25UeXBlLk1lc3NhZ2VDb21wb25lbnQgJiYgKHRoaXMgYXMgYW55KS5jb21wb25lbnRUeXBlID09PSAzO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogUmVwbHkgdG8gdGhlIGludGVyYWN0aW9uXHJcbiAgICovXHJcbiAgYXN5bmMgcmVwbHkob3B0aW9uczogc3RyaW5nIHwgSW50ZXJhY3Rpb25SZXBseU9wdGlvbnMpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgIGlmICh0aGlzLnJlcGxpZWQgfHwgdGhpcy5kZWZlcnJlZCkge1xyXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludGVyYWN0aW9uIGhhcyBhbHJlYWR5IGJlZW4gcmVwbGllZCB0byBvciBkZWZlcnJlZCcpO1xyXG4gICAgfVxyXG4gICAgXHJcbiAgICBjb25zdCBjb250ZW50ID0gdHlwZW9mIG9wdGlvbnMgPT09ICdzdHJpbmcnID8gb3B0aW9ucyA6IG9wdGlvbnMuY29udGVudDtcclxuICAgIGNvbnN0IHJhd0VtYmVkcyA9IHR5cGVvZiBvcHRpb25zID09PSAnc3RyaW5nJyA/IHVuZGVmaW5lZCA6IG9wdGlvbnMuZW1iZWRzO1xyXG4gICAgY29uc3QgY29tcG9uZW50cyA9IHR5cGVvZiBvcHRpb25zID09PSAnc3RyaW5nJyA/IHVuZGVmaW5lZCA6IG9wdGlvbnMuY29tcG9uZW50cztcclxuICAgIGNvbnN0IGVwaGVtZXJhbCA9IHR5cGVvZiBvcHRpb25zID09PSAnc3RyaW5nJyA/IGZhbHNlIDogb3B0aW9ucy5lcGhlbWVyYWw7XHJcbiAgICBcclxuICAgIC8vIENvbnZlcnQgRW1iZWRCdWlsZGVyIGluc3RhbmNlcyB0byBwbGFpbiBvYmplY3RzXHJcbiAgICBjb25zdCBlbWJlZHMgPSByYXdFbWJlZHM/Lm1hcChlID0+IGUgaW5zdGFuY2VvZiBFbWJlZEJ1aWxkZXIgPyBlLnRvSlNPTigpIDogZSk7XHJcbiAgICBcclxuICAgIGF3YWl0IHRoaXMuY2xpZW50LnJlc3QuY3JlYXRlSW50ZXJhY3Rpb25SZXNwb25zZSh0aGlzLmlkLCB0aGlzLnRva2VuLCB7XHJcbiAgICAgIHR5cGU6IEludGVyYWN0aW9uUmVzcG9uc2VUeXBlLkNoYW5uZWxNZXNzYWdlV2l0aFNvdXJjZSxcclxuICAgICAgZGF0YToge1xyXG4gICAgICAgIGNvbnRlbnQsXHJcbiAgICAgICAgZW1iZWRzLFxyXG4gICAgICAgIGNvbXBvbmVudHMsXHJcbiAgICAgICAgZmxhZ3M6IGVwaGVtZXJhbCA/IE1lc3NhZ2VGbGFncy5FcGhlbWVyYWwgOiAwXHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG4gICAgXHJcbiAgICB0aGlzLnJlcGxpZWQgPSB0cnVlO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogRGVmZXIgdGhlIHJlcGx5IChzaG93cyBcInRoaW5raW5nLi4uXCIpXHJcbiAgICovXHJcbiAgYXN5bmMgZGVmZXJSZXBseShvcHRpb25zPzogeyBlcGhlbWVyYWw/OiBib29sZWFuIH0pOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgIGlmICh0aGlzLnJlcGxpZWQgfHwgdGhpcy5kZWZlcnJlZCkge1xyXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludGVyYWN0aW9uIGhhcyBhbHJlYWR5IGJlZW4gcmVwbGllZCB0byBvciBkZWZlcnJlZCcpO1xyXG4gICAgfVxyXG4gICAgXHJcbiAgICBhd2FpdCB0aGlzLmNsaWVudC5yZXN0LmNyZWF0ZUludGVyYWN0aW9uUmVzcG9uc2UodGhpcy5pZCwgdGhpcy50b2tlbiwge1xyXG4gICAgICB0eXBlOiBJbnRlcmFjdGlvblJlc3BvbnNlVHlwZS5EZWZlcnJlZENoYW5uZWxNZXNzYWdlV2l0aFNvdXJjZSxcclxuICAgICAgZGF0YTogb3B0aW9ucz8uZXBoZW1lcmFsID8geyBmbGFnczogTWVzc2FnZUZsYWdzLkVwaGVtZXJhbCB9IDogdW5kZWZpbmVkXHJcbiAgICB9KTtcclxuICAgIFxyXG4gICAgdGhpcy5kZWZlcnJlZCA9IHRydWU7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBFZGl0IHRoZSByZXBseVxyXG4gICAqL1xyXG4gIGFzeW5jIGVkaXRSZXBseShvcHRpb25zOiBzdHJpbmcgfCBJbnRlcmFjdGlvblJlcGx5T3B0aW9ucyk6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgY29uc3QgY29udGVudCA9IHR5cGVvZiBvcHRpb25zID09PSAnc3RyaW5nJyA/IG9wdGlvbnMgOiBvcHRpb25zLmNvbnRlbnQ7XHJcbiAgICBjb25zdCByYXdFbWJlZHMgPSB0eXBlb2Ygb3B0aW9ucyA9PT0gJ3N0cmluZycgPyB1bmRlZmluZWQgOiBvcHRpb25zLmVtYmVkcztcclxuICAgIGNvbnN0IGNvbXBvbmVudHMgPSB0eXBlb2Ygb3B0aW9ucyA9PT0gJ3N0cmluZycgPyB1bmRlZmluZWQgOiBvcHRpb25zLmNvbXBvbmVudHM7XHJcbiAgICBjb25zdCBmaWxlcyA9IHR5cGVvZiBvcHRpb25zID09PSAnc3RyaW5nJyA/IHVuZGVmaW5lZCA6IG9wdGlvbnMuZmlsZXM7XHJcbiAgICBcclxuICAgIC8vIENvbnZlcnQgRW1iZWRCdWlsZGVyIGluc3RhbmNlcyB0byBwbGFpbiBvYmplY3RzXHJcbiAgICBjb25zdCBlbWJlZHMgPSByYXdFbWJlZHM/Lm1hcChlID0+IGUgaW5zdGFuY2VvZiBFbWJlZEJ1aWxkZXIgPyBlLnRvSlNPTigpIDogZSk7XHJcbiAgICBcclxuICAgIGF3YWl0IHRoaXMuY2xpZW50LnJlc3QuZWRpdEludGVyYWN0aW9uUmVzcG9uc2UodGhpcy50b2tlbiwge1xyXG4gICAgICBjb250ZW50LFxyXG4gICAgICBlbWJlZHMsXHJcbiAgICAgIGNvbXBvbmVudHMsXHJcbiAgICAgIGZpbGVzXHJcbiAgICB9LCB0aGlzLmd1aWxkSWQsIHRoaXMuY2hhbm5lbElkLCB0aGlzLmlkKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIERlbGV0ZSB0aGUgcmVwbHlcclxuICAgKi9cclxuICBhc3luYyBkZWxldGVSZXBseSgpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgIGF3YWl0IHRoaXMuY2xpZW50LnJlc3QuZGVsZXRlSW50ZXJhY3Rpb25SZXNwb25zZSh0aGlzLnRva2VuKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFNlbmQgYSBmb2xsb3d1cCBtZXNzYWdlXHJcbiAgICovXHJcbiAgYXN5bmMgZm9sbG93VXAob3B0aW9uczogc3RyaW5nIHwgSW50ZXJhY3Rpb25SZXBseU9wdGlvbnMpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgIGNvbnN0IGNvbnRlbnQgPSB0eXBlb2Ygb3B0aW9ucyA9PT0gJ3N0cmluZycgPyBvcHRpb25zIDogb3B0aW9ucy5jb250ZW50O1xyXG4gICAgY29uc3QgcmF3RW1iZWRzID0gdHlwZW9mIG9wdGlvbnMgPT09ICdzdHJpbmcnID8gdW5kZWZpbmVkIDogb3B0aW9ucy5lbWJlZHM7XHJcbiAgICBjb25zdCBlcGhlbWVyYWwgPSB0eXBlb2Ygb3B0aW9ucyA9PT0gJ3N0cmluZycgPyBmYWxzZSA6IG9wdGlvbnMuZXBoZW1lcmFsO1xyXG4gICAgXHJcbiAgICAvLyBDb252ZXJ0IEVtYmVkQnVpbGRlciBpbnN0YW5jZXMgdG8gcGxhaW4gb2JqZWN0c1xyXG4gICAgY29uc3QgZW1iZWRzID0gcmF3RW1iZWRzPy5tYXAoZSA9PiBlIGluc3RhbmNlb2YgRW1iZWRCdWlsZGVyID8gZS50b0pTT04oKSA6IGUpO1xyXG4gICAgXHJcbiAgICBhd2FpdCB0aGlzLmNsaWVudC5yZXN0LmNyZWF0ZUZvbGxvd3VwKHRoaXMudG9rZW4sIHtcclxuICAgICAgY29udGVudCxcclxuICAgICAgZW1iZWRzLFxyXG4gICAgICBmbGFnczogZXBoZW1lcmFsID8gTWVzc2FnZUZsYWdzLkVwaGVtZXJhbCA6IDBcclxuICAgIH0pO1xyXG4gIH1cclxufVxyXG5cclxuLyoqXHJcbiAqIENvbW1hbmQgaW50ZXJhY3Rpb25cclxuICovXHJcbmV4cG9ydCBjbGFzcyBDb21tYW5kSW50ZXJhY3Rpb24gZXh0ZW5kcyBJbnRlcmFjdGlvbiB7XHJcbiAgLyoqIENvbW1hbmQgbmFtZSAqL1xyXG4gIHB1YmxpYyByZWFkb25seSBjb21tYW5kTmFtZTogc3RyaW5nO1xyXG4gIFxyXG4gIC8qKiBDb21tYW5kIG9wdGlvbnMgKi9cclxuICBwdWJsaWMgcmVhZG9ubHkgb3B0aW9uczogQ29tbWFuZEludGVyYWN0aW9uT3B0aW9ucztcclxuXHJcbiAgY29uc3RydWN0b3IoY2xpZW50OiBDbGllbnQsIGRhdGE6IEFQSUludGVyYWN0aW9uKSB7XHJcbiAgICBzdXBlcihjbGllbnQsIGRhdGEpO1xyXG4gICAgdGhpcy5jb21tYW5kTmFtZSA9IGRhdGEuZGF0YT8ubmFtZSB8fCAnJztcclxuICAgIHRoaXMub3B0aW9ucyA9IG5ldyBDb21tYW5kSW50ZXJhY3Rpb25PcHRpb25zKGRhdGEuZGF0YT8ub3B0aW9ucyB8fCBbXSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBTaG93IGEgbW9kYWxcclxuICAgKi9cclxuICBhc3luYyBzaG93TW9kYWwobW9kYWw6IE1vZGFsRGF0YSB8IHsgdG9KU09OKCk6IE1vZGFsRGF0YSB9KTogUHJvbWlzZTx2b2lkPiB7XHJcbiAgICBjb25zdCBtb2RhbERhdGEgPSAndG9KU09OJyBpbiBtb2RhbCAmJiB0eXBlb2YgbW9kYWwudG9KU09OID09PSAnZnVuY3Rpb24nID8gbW9kYWwudG9KU09OKCkgOiBtb2RhbDtcclxuICAgIGF3YWl0IHRoaXMuY2xpZW50LnJlc3QuY3JlYXRlSW50ZXJhY3Rpb25SZXNwb25zZSh0aGlzLmlkLCB0aGlzLnRva2VuLCB7XHJcbiAgICAgIHR5cGU6IEludGVyYWN0aW9uUmVzcG9uc2VUeXBlLk1vZGFsLFxyXG4gICAgICBkYXRhOiBtb2RhbERhdGFcclxuICAgIH0pO1xyXG4gIH1cclxufVxyXG5cclxuLyoqXHJcbiAqIENvbW1hbmQgaW50ZXJhY3Rpb24gb3B0aW9ucyBoZWxwZXJcclxuICovXHJcbmV4cG9ydCBjbGFzcyBDb21tYW5kSW50ZXJhY3Rpb25PcHRpb25zIHtcclxuICBwcml2YXRlIG9wdGlvbnM6IEFQSUludGVyYWN0aW9uT3B0aW9uW107XHJcblxyXG4gIGNvbnN0cnVjdG9yKG9wdGlvbnM6IEFQSUludGVyYWN0aW9uT3B0aW9uW10pIHtcclxuICAgIHRoaXMub3B0aW9ucyA9IG9wdGlvbnM7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBHZXQgYSBzdHJpbmcgb3B0aW9uXHJcbiAgICovXHJcbiAgZ2V0U3RyaW5nKG5hbWU6IHN0cmluZywgcmVxdWlyZWQ/OiBib29sZWFuKTogc3RyaW5nIHwgbnVsbCB7XHJcbiAgICBjb25zdCBvcHRpb24gPSB0aGlzLm9wdGlvbnMuZmluZChvID0+IG8ubmFtZSA9PT0gbmFtZSk7XHJcbiAgICBpZiAoIW9wdGlvbiAmJiByZXF1aXJlZCkgdGhyb3cgbmV3IEVycm9yKGBSZXF1aXJlZCBvcHRpb24gXCIke25hbWV9XCIgbm90IGZvdW5kYCk7XHJcbiAgICByZXR1cm4gb3B0aW9uPy52YWx1ZSBhcyBzdHJpbmcgfHwgbnVsbDtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEdldCBhbiBpbnRlZ2VyIG9wdGlvblxyXG4gICAqL1xyXG4gIGdldEludGVnZXIobmFtZTogc3RyaW5nLCByZXF1aXJlZD86IGJvb2xlYW4pOiBudW1iZXIgfCBudWxsIHtcclxuICAgIGNvbnN0IG9wdGlvbiA9IHRoaXMub3B0aW9ucy5maW5kKG8gPT4gby5uYW1lID09PSBuYW1lKTtcclxuICAgIGlmICghb3B0aW9uICYmIHJlcXVpcmVkKSB0aHJvdyBuZXcgRXJyb3IoYFJlcXVpcmVkIG9wdGlvbiBcIiR7bmFtZX1cIiBub3QgZm91bmRgKTtcclxuICAgIHJldHVybiBvcHRpb24/LnZhbHVlIGFzIG51bWJlciB8fCBudWxsO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogR2V0IGEgbnVtYmVyIG9wdGlvblxyXG4gICAqL1xyXG4gIGdldE51bWJlcihuYW1lOiBzdHJpbmcsIHJlcXVpcmVkPzogYm9vbGVhbik6IG51bWJlciB8IG51bGwge1xyXG4gICAgcmV0dXJuIHRoaXMuZ2V0SW50ZWdlcihuYW1lLCByZXF1aXJlZCk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBHZXQgYSBib29sZWFuIG9wdGlvblxyXG4gICAqL1xyXG4gIGdldEJvb2xlYW4obmFtZTogc3RyaW5nLCByZXF1aXJlZD86IGJvb2xlYW4pOiBib29sZWFuIHwgbnVsbCB7XHJcbiAgICBjb25zdCBvcHRpb24gPSB0aGlzLm9wdGlvbnMuZmluZChvID0+IG8ubmFtZSA9PT0gbmFtZSk7XHJcbiAgICBpZiAoIW9wdGlvbiAmJiByZXF1aXJlZCkgdGhyb3cgbmV3IEVycm9yKGBSZXF1aXJlZCBvcHRpb24gXCIke25hbWV9XCIgbm90IGZvdW5kYCk7XHJcbiAgICByZXR1cm4gb3B0aW9uPy52YWx1ZSBhcyBib29sZWFuID8/IG51bGw7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBHZXQgYSB1c2VyIG9wdGlvblxyXG4gICAqL1xyXG4gIGdldFVzZXIobmFtZTogc3RyaW5nLCByZXF1aXJlZD86IGJvb2xlYW4pOiBzdHJpbmcgfCBudWxsIHtcclxuICAgIGNvbnN0IG9wdGlvbiA9IHRoaXMub3B0aW9ucy5maW5kKG8gPT4gby5uYW1lID09PSBuYW1lKTtcclxuICAgIGlmICghb3B0aW9uICYmIHJlcXVpcmVkKSB0aHJvdyBuZXcgRXJyb3IoYFJlcXVpcmVkIG9wdGlvbiBcIiR7bmFtZX1cIiBub3QgZm91bmRgKTtcclxuICAgIHJldHVybiBvcHRpb24/LnZhbHVlIGFzIHN0cmluZyB8fCBudWxsO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogR2V0IGEgY2hhbm5lbCBvcHRpb25cclxuICAgKi9cclxuICBnZXRDaGFubmVsKG5hbWU6IHN0cmluZywgcmVxdWlyZWQ/OiBib29sZWFuKTogc3RyaW5nIHwgbnVsbCB7XHJcbiAgICBjb25zdCBvcHRpb24gPSB0aGlzLm9wdGlvbnMuZmluZChvID0+IG8ubmFtZSA9PT0gbmFtZSk7XHJcbiAgICBpZiAoIW9wdGlvbiAmJiByZXF1aXJlZCkgdGhyb3cgbmV3IEVycm9yKGBSZXF1aXJlZCBvcHRpb24gXCIke25hbWV9XCIgbm90IGZvdW5kYCk7XHJcbiAgICByZXR1cm4gb3B0aW9uPy52YWx1ZSBhcyBzdHJpbmcgfHwgbnVsbDtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEdldCBhIHN1YmNvbW1hbmQgbmFtZVxyXG4gICAqL1xyXG4gIGdldFN1YmNvbW1hbmQocmVxdWlyZWQ/OiBib29sZWFuKTogc3RyaW5nIHwgbnVsbCB7XHJcbiAgICBjb25zdCBvcHRpb24gPSB0aGlzLm9wdGlvbnMuZmluZChvID0+IG8udHlwZSA9PT0gMSk7XHJcbiAgICBpZiAoIW9wdGlvbiAmJiByZXF1aXJlZCkgdGhyb3cgbmV3IEVycm9yKCdSZXF1aXJlZCBzdWJjb21tYW5kIG5vdCBmb3VuZCcpO1xyXG4gICAgcmV0dXJuIG9wdGlvbj8ubmFtZSB8fCBudWxsO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogR2V0IHRoZSBmb2N1c2VkIG9wdGlvbiAoZm9yIGF1dG9jb21wbGV0ZSlcclxuICAgKi9cclxuICBnZXRGb2N1c2VkKCk6IHsgbmFtZTogc3RyaW5nOyB2YWx1ZTogc3RyaW5nIH0gfCBudWxsIHtcclxuICAgIGNvbnN0IG9wdGlvbiA9IHRoaXMub3B0aW9ucy5maW5kKG8gPT4gby5mb2N1c2VkKTtcclxuICAgIGlmICghb3B0aW9uKSByZXR1cm4gbnVsbDtcclxuICAgIHJldHVybiB7IG5hbWU6IG9wdGlvbi5uYW1lLCB2YWx1ZTogb3B0aW9uLnZhbHVlIGFzIHN0cmluZyB9O1xyXG4gIH1cclxufVxyXG5cclxuLyoqXHJcbiAqIEF1dG9jb21wbGV0ZSBpbnRlcmFjdGlvblxyXG4gKi9cclxuZXhwb3J0IGNsYXNzIEF1dG9jb21wbGV0ZUludGVyYWN0aW9uIGV4dGVuZHMgSW50ZXJhY3Rpb24ge1xyXG4gIC8qKiBDb21tYW5kIG5hbWUgKi9cclxuICBwdWJsaWMgcmVhZG9ubHkgY29tbWFuZE5hbWU6IHN0cmluZztcclxuICBcclxuICAvKiogQ29tbWFuZCBvcHRpb25zICovXHJcbiAgcHVibGljIHJlYWRvbmx5IG9wdGlvbnM6IENvbW1hbmRJbnRlcmFjdGlvbk9wdGlvbnM7XHJcblxyXG4gIGNvbnN0cnVjdG9yKGNsaWVudDogQ2xpZW50LCBkYXRhOiBBUElJbnRlcmFjdGlvbikge1xyXG4gICAgc3VwZXIoY2xpZW50LCBkYXRhKTtcclxuICAgIHRoaXMuY29tbWFuZE5hbWUgPSBkYXRhLmRhdGE/Lm5hbWUgfHwgJyc7XHJcbiAgICB0aGlzLm9wdGlvbnMgPSBuZXcgQ29tbWFuZEludGVyYWN0aW9uT3B0aW9ucyhkYXRhLmRhdGE/Lm9wdGlvbnMgfHwgW10pO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogUmVzcG9uZCB3aXRoIGF1dG9jb21wbGV0ZSBjaG9pY2VzXHJcbiAgICovXHJcbiAgYXN5bmMgcmVzcG9uZChjaG9pY2VzOiBBdXRvY29tcGxldGVDaG9pY2VbXSk6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgYXdhaXQgdGhpcy5jbGllbnQucmVzdC5jcmVhdGVJbnRlcmFjdGlvblJlc3BvbnNlKHRoaXMuaWQsIHRoaXMudG9rZW4sIHtcclxuICAgICAgdHlwZTogSW50ZXJhY3Rpb25SZXNwb25zZVR5cGUuQXBwbGljYXRpb25Db21tYW5kQXV0b2NvbXBsZXRlUmVzdWx0LFxyXG4gICAgICBkYXRhOiB7IGNob2ljZXMgfVxyXG4gICAgfSk7XHJcbiAgfVxyXG59XHJcblxyXG4vKipcclxuICogQnV0dG9uIGludGVyYWN0aW9uXHJcbiAqL1xyXG5leHBvcnQgY2xhc3MgQnV0dG9uSW50ZXJhY3Rpb24gZXh0ZW5kcyBJbnRlcmFjdGlvbiB7XHJcbiAgLyoqIEJ1dHRvbiBjdXN0b20gSUQgKi9cclxuICBwdWJsaWMgcmVhZG9ubHkgY3VzdG9tSWQ6IHN0cmluZztcclxuICBcclxuICAvKiogQ29tcG9uZW50IHR5cGUgKGFsd2F5cyAyIGZvciBidXR0b25zKSAqL1xyXG4gIHB1YmxpYyByZWFkb25seSBjb21wb25lbnRUeXBlOiBudW1iZXIgPSAyO1xyXG4gIFxyXG4gIC8qKiBNZXNzYWdlIHRoZSBidXR0b24gaXMgYXR0YWNoZWQgdG8gKi9cclxuICBwdWJsaWMgcmVhZG9ubHkgbWVzc2FnZT86IGFueTtcclxuXHJcbiAgY29uc3RydWN0b3IoY2xpZW50OiBDbGllbnQsIGRhdGE6IEFQSUludGVyYWN0aW9uKSB7XHJcbiAgICBzdXBlcihjbGllbnQsIGRhdGEpO1xyXG4gICAgdGhpcy5jdXN0b21JZCA9IGRhdGEuZGF0YT8uY3VzdG9tX2lkIHx8ICcnO1xyXG4gICAgdGhpcy5tZXNzYWdlID0gZGF0YS5tZXNzYWdlO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogVXBkYXRlIHRoZSBtZXNzYWdlIHRoZSBidXR0b24gaXMgYXR0YWNoZWQgdG9cclxuICAgKi9cclxuICBhc3luYyB1cGRhdGUob3B0aW9uczogSW50ZXJhY3Rpb25SZXBseU9wdGlvbnMpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgIC8vIENvbnZlcnQgRW1iZWRCdWlsZGVyIGluc3RhbmNlcyB0byBwbGFpbiBvYmplY3RzXHJcbiAgICBjb25zdCBlbWJlZHMgPSBvcHRpb25zLmVtYmVkcz8ubWFwKGUgPT4gZSBpbnN0YW5jZW9mIEVtYmVkQnVpbGRlciA/IGUudG9KU09OKCkgOiBlKTtcclxuICAgIFxyXG4gICAgYXdhaXQgdGhpcy5jbGllbnQucmVzdC5jcmVhdGVJbnRlcmFjdGlvblJlc3BvbnNlKHRoaXMuaWQsIHRoaXMudG9rZW4sIHtcclxuICAgICAgdHlwZTogSW50ZXJhY3Rpb25SZXNwb25zZVR5cGUuVXBkYXRlTWVzc2FnZSxcclxuICAgICAgZGF0YToge1xyXG4gICAgICAgIGNvbnRlbnQ6IG9wdGlvbnMuY29udGVudCxcclxuICAgICAgICBlbWJlZHMsXHJcbiAgICAgICAgY29tcG9uZW50czogb3B0aW9ucy5jb21wb25lbnRzXHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG4gICAgdGhpcy5yZXBsaWVkID0gdHJ1ZTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFNob3cgYSBtb2RhbCBpbiByZXNwb25zZSB0byB0aGlzIGJ1dHRvbiBpbnRlcmFjdGlvblxyXG4gICAqL1xyXG4gIGFzeW5jIHNob3dNb2RhbChtb2RhbDogTW9kYWxEYXRhIHwgeyB0b0pTT04oKTogTW9kYWxEYXRhIH0pOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgIGNvbnN0IG1vZGFsRGF0YSA9ICd0b0pTT04nIGluIG1vZGFsICYmIHR5cGVvZiBtb2RhbC50b0pTT04gPT09ICdmdW5jdGlvbicgPyBtb2RhbC50b0pTT04oKSA6IG1vZGFsO1xyXG4gICAgYXdhaXQgdGhpcy5jbGllbnQucmVzdC5jcmVhdGVJbnRlcmFjdGlvblJlc3BvbnNlKHRoaXMuaWQsIHRoaXMudG9rZW4sIHtcclxuICAgICAgdHlwZTogSW50ZXJhY3Rpb25SZXNwb25zZVR5cGUuTW9kYWwsXHJcbiAgICAgIGRhdGE6IG1vZGFsRGF0YVxyXG4gICAgfSk7XHJcbiAgfVxyXG59XHJcblxyXG4vKipcclxuICogU2VsZWN0IG1lbnUgaW50ZXJhY3Rpb25cclxuICovXHJcbmV4cG9ydCBjbGFzcyBTZWxlY3RNZW51SW50ZXJhY3Rpb24gZXh0ZW5kcyBJbnRlcmFjdGlvbiB7XHJcbiAgLyoqIFNlbGVjdCBtZW51IGN1c3RvbSBJRCAqL1xyXG4gIHB1YmxpYyByZWFkb25seSBjdXN0b21JZDogc3RyaW5nO1xyXG4gIFxyXG4gIC8qKiBDb21wb25lbnQgdHlwZSAoYWx3YXlzIDMgZm9yIHNlbGVjdCBtZW51cykgKi9cclxuICBwdWJsaWMgcmVhZG9ubHkgY29tcG9uZW50VHlwZTogbnVtYmVyID0gMztcclxuICBcclxuICAvKiogU2VsZWN0ZWQgdmFsdWVzICovXHJcbiAgcHVibGljIHJlYWRvbmx5IHZhbHVlczogc3RyaW5nW107XHJcbiAgXHJcbiAgLyoqIE1lc3NhZ2UgdGhlIHNlbGVjdCBtZW51IGlzIGF0dGFjaGVkIHRvICovXHJcbiAgcHVibGljIHJlYWRvbmx5IG1lc3NhZ2U/OiBhbnk7XHJcblxyXG4gIGNvbnN0cnVjdG9yKGNsaWVudDogQ2xpZW50LCBkYXRhOiBBUElJbnRlcmFjdGlvbikge1xyXG4gICAgc3VwZXIoY2xpZW50LCBkYXRhKTtcclxuICAgIHRoaXMuY3VzdG9tSWQgPSBkYXRhLmRhdGE/LmN1c3RvbV9pZCB8fCAnJztcclxuICAgIHRoaXMudmFsdWVzID0gZGF0YS5kYXRhPy52YWx1ZXMgfHwgW107XHJcbiAgICB0aGlzLm1lc3NhZ2UgPSBkYXRhLm1lc3NhZ2U7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBVcGRhdGUgdGhlIG1lc3NhZ2UgdGhlIHNlbGVjdCBtZW51IGlzIGF0dGFjaGVkIHRvXHJcbiAgICovXHJcbiAgYXN5bmMgdXBkYXRlKG9wdGlvbnM6IEludGVyYWN0aW9uUmVwbHlPcHRpb25zKTogUHJvbWlzZTx2b2lkPiB7XHJcbiAgICAvLyBDb252ZXJ0IEVtYmVkQnVpbGRlciBpbnN0YW5jZXMgdG8gcGxhaW4gb2JqZWN0c1xyXG4gICAgY29uc3QgZW1iZWRzID0gb3B0aW9ucy5lbWJlZHM/Lm1hcChlID0+IGUgaW5zdGFuY2VvZiBFbWJlZEJ1aWxkZXIgPyBlLnRvSlNPTigpIDogZSk7XHJcbiAgICBcclxuICAgIGF3YWl0IHRoaXMuY2xpZW50LnJlc3QuY3JlYXRlSW50ZXJhY3Rpb25SZXNwb25zZSh0aGlzLmlkLCB0aGlzLnRva2VuLCB7XHJcbiAgICAgIHR5cGU6IEludGVyYWN0aW9uUmVzcG9uc2VUeXBlLlVwZGF0ZU1lc3NhZ2UsXHJcbiAgICAgIGRhdGE6IHtcclxuICAgICAgICBjb250ZW50OiBvcHRpb25zLmNvbnRlbnQsXHJcbiAgICAgICAgZW1iZWRzLFxyXG4gICAgICAgIGNvbXBvbmVudHM6IG9wdGlvbnMuY29tcG9uZW50c1xyXG4gICAgICB9XHJcbiAgICB9KTtcclxuICAgIHRoaXMucmVwbGllZCA9IHRydWU7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBTaG93IGEgbW9kYWwgaW4gcmVzcG9uc2UgdG8gdGhpcyBzZWxlY3QgbWVudSBpbnRlcmFjdGlvblxyXG4gICAqL1xyXG4gIGFzeW5jIHNob3dNb2RhbChtb2RhbDogTW9kYWxEYXRhIHwgeyB0b0pTT04oKTogTW9kYWxEYXRhIH0pOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgIGNvbnN0IG1vZGFsRGF0YSA9ICd0b0pTT04nIGluIG1vZGFsICYmIHR5cGVvZiBtb2RhbC50b0pTT04gPT09ICdmdW5jdGlvbicgPyBtb2RhbC50b0pTT04oKSA6IG1vZGFsO1xyXG4gICAgYXdhaXQgdGhpcy5jbGllbnQucmVzdC5jcmVhdGVJbnRlcmFjdGlvblJlc3BvbnNlKHRoaXMuaWQsIHRoaXMudG9rZW4sIHtcclxuICAgICAgdHlwZTogSW50ZXJhY3Rpb25SZXNwb25zZVR5cGUuTW9kYWwsXHJcbiAgICAgIGRhdGE6IG1vZGFsRGF0YVxyXG4gICAgfSk7XHJcbiAgfVxyXG59XHJcblxyXG4vKipcclxuICogTW9kYWwgc3VibWl0IGludGVyYWN0aW9uXHJcbiAqL1xyXG5leHBvcnQgY2xhc3MgTW9kYWxTdWJtaXRJbnRlcmFjdGlvbiBleHRlbmRzIEludGVyYWN0aW9uIHtcclxuICAvKiogTW9kYWwgY3VzdG9tIElEICovXHJcbiAgcHVibGljIHJlYWRvbmx5IGN1c3RvbUlkOiBzdHJpbmc7XHJcbiAgXHJcbiAgLyoqIE1vZGFsIGZpZWxkcyAqL1xyXG4gIHB1YmxpYyByZWFkb25seSBmaWVsZHM6IE1vZGFsRmllbGRzO1xyXG5cclxuICBjb25zdHJ1Y3RvcihjbGllbnQ6IENsaWVudCwgZGF0YTogQVBJSW50ZXJhY3Rpb24pIHtcclxuICAgIHN1cGVyKGNsaWVudCwgZGF0YSk7XHJcbiAgICB0aGlzLmN1c3RvbUlkID0gZGF0YS5kYXRhPy5jdXN0b21faWQgfHwgJyc7XHJcbiAgICAvLyBNb2RhbCB2YWx1ZXMgY29tZSBmcm9tIGNvbXBvbmVudHMgYXJyYXkgKGFjdGlvbiByb3dzIGNvbnRhaW5pbmcgdGV4dCBpbnB1dHMpXHJcbiAgICBjb25zdCBjb21wb25lbnRzID0gKGRhdGEuZGF0YSBhcyBhbnkpPy5jb21wb25lbnRzIHx8IFtdO1xyXG4gICAgdGhpcy5maWVsZHMgPSBuZXcgTW9kYWxGaWVsZHMoY29tcG9uZW50cyk7XHJcbiAgfVxyXG59XHJcblxyXG4vKipcclxuICogTW9kYWwgZmllbGRzIGhlbHBlclxyXG4gKi9cclxuZXhwb3J0IGNsYXNzIE1vZGFsRmllbGRzIHtcclxuICBwcml2YXRlIGZpZWxkTWFwOiBNYXA8c3RyaW5nLCBzdHJpbmc+O1xyXG5cclxuICBjb25zdHJ1Y3Rvcihjb21wb25lbnRzOiBhbnlbXSkge1xyXG4gICAgdGhpcy5maWVsZE1hcCA9IG5ldyBNYXAoKTtcclxuICAgIC8vIFBhcnNlIGFjdGlvbiByb3dzIOKGkiB0ZXh0IGlucHV0c1xyXG4gICAgZm9yIChjb25zdCByb3cgb2YgY29tcG9uZW50cykge1xyXG4gICAgICBjb25zdCBpbm5lckNvbXBvbmVudHMgPSByb3c/LmNvbXBvbmVudHMgfHwgW107XHJcbiAgICAgIGZvciAoY29uc3QgY29tcCBvZiBpbm5lckNvbXBvbmVudHMpIHtcclxuICAgICAgICBpZiAoY29tcC5jdXN0b21faWQgJiYgY29tcC52YWx1ZSAhPT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICB0aGlzLmZpZWxkTWFwLnNldChjb21wLmN1c3RvbV9pZCwgY29tcC52YWx1ZSk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBHZXQgYSB0ZXh0IGlucHV0IHZhbHVlIGJ5IGN1c3RvbV9pZFxyXG4gICAqL1xyXG4gIGdldFRleHRJbnB1dFZhbHVlKGN1c3RvbUlkOiBzdHJpbmcpOiBzdHJpbmcgfCBudWxsIHtcclxuICAgIHJldHVybiB0aGlzLmZpZWxkTWFwLmdldChjdXN0b21JZCkgPz8gbnVsbDtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEdldCBhIGZpZWxkIChhbGlhcyBmb3IgZ2V0VGV4dElucHV0VmFsdWUpXHJcbiAgICovXHJcbiAgZ2V0RmllbGQoY3VzdG9tSWQ6IHN0cmluZyk6IHsgdmFsdWU6IHN0cmluZyB9IHwgbnVsbCB7XHJcbiAgICBjb25zdCB2YWx1ZSA9IHRoaXMuZmllbGRNYXAuZ2V0KGN1c3RvbUlkKTtcclxuICAgIHJldHVybiB2YWx1ZSAhPT0gdW5kZWZpbmVkID8geyB2YWx1ZSB9IDogbnVsbDtcclxuICB9XHJcbn1cclxuXHJcbi8vIFR5cGVzXHJcbmV4cG9ydCBpbnRlcmZhY2UgSW50ZXJhY3Rpb25SZXBseU9wdGlvbnMge1xyXG4gIGNvbnRlbnQ/OiBzdHJpbmc7XHJcbiAgZW1iZWRzPzogKEFQSUVtYmVkIHwgRW1iZWRCdWlsZGVyKVtdO1xyXG4gIGNvbXBvbmVudHM/OiBhbnlbXTtcclxuICBlcGhlbWVyYWw/OiBib29sZWFuO1xyXG4gIGZpbGVzPzogQXJyYXk8eyBuYW1lOiBzdHJpbmc7IGRhdGE6IEJ1ZmZlcjsgY29udGVudFR5cGU/OiBzdHJpbmcgfT47XHJcbn1cclxuXHJcbmV4cG9ydCBpbnRlcmZhY2UgQXV0b2NvbXBsZXRlQ2hvaWNlIHtcclxuICBuYW1lOiBzdHJpbmc7XHJcbiAgdmFsdWU6IHN0cmluZyB8IG51bWJlcjtcclxufVxyXG5cclxuZXhwb3J0IGludGVyZmFjZSBNb2RhbERhdGEge1xyXG4gIGN1c3RvbV9pZDogc3RyaW5nO1xyXG4gIHRpdGxlOiBzdHJpbmc7XHJcbiAgY29tcG9uZW50czogYW55W107XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBDcmVhdGUgYXBwcm9wcmlhdGUgaW50ZXJhY3Rpb24gY2xhc3MgYmFzZWQgb24gdHlwZVxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUludGVyYWN0aW9uKGNsaWVudDogQ2xpZW50LCBkYXRhOiBBUElJbnRlcmFjdGlvbik6IEludGVyYWN0aW9uIHtcclxuICBzd2l0Y2ggKGRhdGEudHlwZSkge1xyXG4gICAgY2FzZSBJbnRlcmFjdGlvblR5cGUuQXBwbGljYXRpb25Db21tYW5kOlxyXG4gICAgICByZXR1cm4gbmV3IENvbW1hbmRJbnRlcmFjdGlvbihjbGllbnQsIGRhdGEpO1xyXG4gICAgY2FzZSBJbnRlcmFjdGlvblR5cGUuQXBwbGljYXRpb25Db21tYW5kQXV0b2NvbXBsZXRlOlxyXG4gICAgICByZXR1cm4gbmV3IEF1dG9jb21wbGV0ZUludGVyYWN0aW9uKGNsaWVudCwgZGF0YSk7XHJcbiAgICBjYXNlIEludGVyYWN0aW9uVHlwZS5Nb2RhbFN1Ym1pdDpcclxuICAgICAgcmV0dXJuIG5ldyBNb2RhbFN1Ym1pdEludGVyYWN0aW9uKGNsaWVudCwgZGF0YSk7XHJcbiAgICBjYXNlIEludGVyYWN0aW9uVHlwZS5NZXNzYWdlQ29tcG9uZW50OlxyXG4gICAgICAvLyBjb21wb25lbnRfdHlwZTogMiA9IEJ1dHRvbiwgMyA9IFNlbGVjdCBNZW51XHJcbiAgICAgIGlmIChkYXRhLmRhdGE/LmNvbXBvbmVudF90eXBlID09PSAyKSB7XHJcbiAgICAgICAgcmV0dXJuIG5ldyBCdXR0b25JbnRlcmFjdGlvbihjbGllbnQsIGRhdGEpO1xyXG4gICAgICB9IGVsc2UgaWYgKGRhdGEuZGF0YT8uY29tcG9uZW50X3R5cGUgPT09IDMpIHtcclxuICAgICAgICByZXR1cm4gbmV3IFNlbGVjdE1lbnVJbnRlcmFjdGlvbihjbGllbnQsIGRhdGEpO1xyXG4gICAgICB9XHJcbiAgICAgIHJldHVybiBuZXcgSW50ZXJhY3Rpb24oY2xpZW50LCBkYXRhKTtcclxuICAgIGRlZmF1bHQ6XHJcbiAgICAgIHJldHVybiBuZXcgSW50ZXJhY3Rpb24oY2xpZW50LCBkYXRhKTtcclxuICB9XHJcbn1cclxuIl19