@ragemp-mango/core 2.0.6-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +20 -0
  3. package/dist/app/constants/index.d.ts +26 -0
  4. package/dist/app/constants/index.js +49 -0
  5. package/dist/app/controller/index.d.ts +70 -0
  6. package/dist/app/controller/index.js +24 -0
  7. package/dist/app/enums/index.d.ts +27 -0
  8. package/dist/app/enums/index.js +16 -0
  9. package/dist/app/index.d.ts +138 -0
  10. package/dist/app/index.js +132 -0
  11. package/dist/app/interfaces/index.d.ts +157 -0
  12. package/dist/app/interfaces/index.js +2 -0
  13. package/dist/app/module/index.d.ts +27 -0
  14. package/dist/app/module/index.js +16 -0
  15. package/dist/app/module-tree/index.d.ts +56 -0
  16. package/dist/app/module-tree/index.js +25 -0
  17. package/dist/app/pipeline/index.d.ts +5 -0
  18. package/dist/app/pipeline/index.js +14 -0
  19. package/dist/app/services/index.d.ts +37 -0
  20. package/dist/app/services/index.js +14 -0
  21. package/dist/app/utils/index.d.ts +16 -0
  22. package/dist/app/utils/index.js +10 -0
  23. package/dist/call-handler.interface-DVdaknsB.d.ts +52 -0
  24. package/dist/chunk-2ADQZWQE.js +170 -0
  25. package/dist/chunk-6YEWPMZJ.js +69 -0
  26. package/dist/chunk-73LIJA6X.js +176 -0
  27. package/dist/chunk-7QVYU63E.js +7 -0
  28. package/dist/chunk-AO6BXG54.js +139 -0
  29. package/dist/chunk-CFHBJ5MV.js +1906 -0
  30. package/dist/chunk-CW7WAA3P.js +1906 -0
  31. package/dist/chunk-DEPJRTVT.js +1 -0
  32. package/dist/chunk-DJZCOYB3.js +17 -0
  33. package/dist/chunk-DXPVUDXD.js +81 -0
  34. package/dist/chunk-E6IQL4S6.js +40 -0
  35. package/dist/chunk-HK7QTFPA.js +81 -0
  36. package/dist/chunk-ITEHLEIP.js +29 -0
  37. package/dist/chunk-M55YEQ7J.js +1 -0
  38. package/dist/chunk-PGWRESZG.js +790 -0
  39. package/dist/chunk-PQK4E654.js +1 -0
  40. package/dist/chunk-RYOUF322.js +68 -0
  41. package/dist/chunk-SKPH3K2M.js +570 -0
  42. package/dist/chunk-TBWHLT75.js +61 -0
  43. package/dist/constants/index.d.ts +8 -0
  44. package/dist/constants/index.js +18 -0
  45. package/dist/controller-Ss0TVrxQ.d.ts +30 -0
  46. package/dist/custom-decorator.type-BHRvXIGz.d.ts +5 -0
  47. package/dist/decorators/index.d.ts +90 -0
  48. package/dist/decorators/index.js +91 -0
  49. package/dist/enums/index.d.ts +66 -0
  50. package/dist/enums/index.js +12 -0
  51. package/dist/errors/index.d.ts +23 -0
  52. package/dist/errors/index.js +17 -0
  53. package/dist/event-destination.enum-DT8jJFwR.d.ts +7 -0
  54. package/dist/event-emmiter.interface-7Ne9W8SM.d.ts +10 -0
  55. package/dist/event-metadata.interface-CREizDNq.d.ts +89 -0
  56. package/dist/execution-context-type.enum-fwYPtPvp.d.ts +6 -0
  57. package/dist/execution-context.interface-DpRN4oVj.d.ts +56 -0
  58. package/dist/index.d.ts +33 -0
  59. package/dist/index.js +190 -0
  60. package/dist/injectable-options.interface-8Gp9oRY6.d.ts +10 -0
  61. package/dist/injectable-scope.enum-CjyQMpW2.d.ts +7 -0
  62. package/dist/injection-token.type-dQTkkP6p.d.ts +5 -0
  63. package/dist/interfaces/index.d.ts +38 -0
  64. package/dist/interfaces/index.js +2 -0
  65. package/dist/logger-service.interface-BGV-o_Fx.d.ts +8 -0
  66. package/dist/method-param-type.enum-BfrJ8zqa.d.ts +11 -0
  67. package/dist/module-metadata.interface-B3bn1vqq.d.ts +59 -0
  68. package/dist/multiplayer-timers.interface-CFDTWwAT.d.ts +22 -0
  69. package/dist/newable.type-BdhG3MZC.d.ts +5 -0
  70. package/dist/nullable.type-C-lE7JU4.d.ts +3 -0
  71. package/dist/pipe-transform.interface-BlzOrUy3.d.ts +14 -0
  72. package/dist/pipes/index.d.ts +12 -0
  73. package/dist/pipes/index.js +9 -0
  74. package/dist/reflectable-decorator.interface-CLOGdtEQ.d.ts +14 -0
  75. package/dist/rpc-call-options.interface-BJ5mHrvT.d.ts +5 -0
  76. package/dist/rpc-error.interface-CeaZLqzE.d.ts +6 -0
  77. package/dist/rpc-metadata.interface-DS-GqgqA.d.ts +11 -0
  78. package/dist/rpc-result.interface-C758heM0.d.ts +10 -0
  79. package/dist/schemas/index.d.ts +189 -0
  80. package/dist/schemas/index.js +39 -0
  81. package/dist/script-event-handler.interface-B-Th4Ssg.d.ts +24 -0
  82. package/dist/script-event-handler.interface-vUr_v6tV.d.ts +5 -0
  83. package/dist/script-rpc-handler.interface-DBpD9-yk.d.ts +8 -0
  84. package/dist/services/index.d.ts +45 -0
  85. package/dist/services/index.js +23 -0
  86. package/dist/types/index.d.ts +9 -0
  87. package/dist/types/index.js +2 -0
  88. package/dist/utils/index.d.ts +16 -0
  89. package/dist/utils/index.js +32 -0
  90. package/package.json +133 -0
@@ -0,0 +1,570 @@
1
+ import {
2
+ APP_ENVIROMENT,
3
+ EXECUTION_CONTEXT_FACTORY,
4
+ MANGO_REQUEST_FACTORY,
5
+ MANGO_RESPONSE_FACTORY,
6
+ MULTIPLAYER_SERVICE
7
+ } from "./chunk-HK7QTFPA.js";
8
+ import {
9
+ AppEnviroment,
10
+ CoreMetadataKey,
11
+ ExecutionContextType
12
+ } from "./chunk-TBWHLT75.js";
13
+ import {
14
+ EVENT_SERVICE,
15
+ LOGGER_SERVICE,
16
+ RPC_SERVICE
17
+ } from "./chunk-DJZCOYB3.js";
18
+ import {
19
+ GuardCancelError,
20
+ GuardInvalidReturnError
21
+ } from "./chunk-6YEWPMZJ.js";
22
+ import {
23
+ ErrorMessage
24
+ } from "./chunk-DXPVUDXD.js";
25
+ import {
26
+ isAsyncFunction,
27
+ isFunction,
28
+ isNil,
29
+ isObject
30
+ } from "./chunk-E6IQL4S6.js";
31
+ import {
32
+ __name
33
+ } from "./chunk-7QVYU63E.js";
34
+
35
+ // src/app/controller/controller-event.handler.ts
36
+ import { inject as inject3, injectable as injectable3 } from "inversify";
37
+
38
+ // src/app/controller/pipeline.handler.ts
39
+ import { inject, injectable } from "inversify";
40
+ function _ts_decorate(decorators, target, key, desc) {
41
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
42
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
43
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
44
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
45
+ }
46
+ __name(_ts_decorate, "_ts_decorate");
47
+ function _ts_metadata(k, v) {
48
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
49
+ }
50
+ __name(_ts_metadata, "_ts_metadata");
51
+ var PipelineHandler = class {
52
+ static {
53
+ __name(this, "PipelineHandler");
54
+ }
55
+ loggerService;
56
+ // @inject(GLOBAL_APP_CONTAINER) private readonly globalContainer: Container;
57
+ async goTroughGuards(executionContext, guards, container) {
58
+ for (const guard of guards) {
59
+ const instance = isFunction(guard) ? container.get(guard) : isObject(guard) && isFunction(guard["canActivate"]) ? guard : null;
60
+ if (isNil(instance)) {
61
+ this.loggerService.error("An error occurred while trying to go through guards.");
62
+ throw new Error(ErrorMessage.InvalidGuardDefinition);
63
+ }
64
+ const canActivate = await instance.canActivate.call(instance, executionContext);
65
+ if (typeof canActivate !== "boolean") {
66
+ this.loggerService.error("An error occurred while trying to go through guards.");
67
+ throw new GuardInvalidReturnError();
68
+ }
69
+ if (!canActivate) {
70
+ throw new GuardCancelError();
71
+ }
72
+ }
73
+ }
74
+ async goThroughInterceptors(executionContext, interceptors, container, callHandler) {
75
+ for (const interceptor of interceptors) {
76
+ const instance = isFunction(interceptor) ? container.get(interceptor) : isObject(interceptor) && isFunction(interceptor["intercept"]) ? interceptor : null;
77
+ if (isNil(instance)) {
78
+ this.loggerService.error("An error occurred while trying to go through interceptors.");
79
+ throw new Error(ErrorMessage.InvalidInterceptorDefinition);
80
+ }
81
+ await instance.intercept.call(instance, executionContext, callHandler);
82
+ }
83
+ }
84
+ async goTroughPipes(value, pipes, argumentMetadata, container) {
85
+ for (const pipe of pipes) {
86
+ const instance = isFunction(pipe) ? container.get(pipe) : isObject(pipe) ? pipe : null;
87
+ if (isNil(instance)) {
88
+ this.loggerService.error("An error occurred while trying to go through pipes.");
89
+ throw new Error(ErrorMessage.InvalidPipeDefinition);
90
+ }
91
+ value = await Promise.resolve(instance.transform.call(instance, value, argumentMetadata));
92
+ }
93
+ return value;
94
+ }
95
+ };
96
+ _ts_decorate([
97
+ inject(LOGGER_SERVICE),
98
+ _ts_metadata("design:type", typeof LoggerService === "undefined" ? Object : LoggerService)
99
+ ], PipelineHandler.prototype, "loggerService", void 0);
100
+ PipelineHandler = _ts_decorate([
101
+ injectable()
102
+ ], PipelineHandler);
103
+
104
+ // src/app/controller/controller-flow.handler.ts
105
+ import { inject as inject2, injectable as injectable2 } from "inversify";
106
+ function _ts_decorate2(decorators, target, key, desc) {
107
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
108
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
109
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
110
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
111
+ }
112
+ __name(_ts_decorate2, "_ts_decorate");
113
+ function _ts_metadata2(k, v) {
114
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
115
+ }
116
+ __name(_ts_metadata2, "_ts_metadata");
117
+ var ControllerFlowHandler = class {
118
+ static {
119
+ __name(this, "ControllerFlowHandler");
120
+ }
121
+ appEnv;
122
+ pipelineHandler;
123
+ async createArgs(controller, executionContext, metadata, pipes, player) {
124
+ return Promise.all(metadata.params.map(async (param) => {
125
+ const argumentMetadata = {
126
+ type: param.type,
127
+ data: param.data,
128
+ metatype: param.metatype
129
+ };
130
+ if (param.type === "body") {
131
+ return this.pipelineHandler.goTroughPipes(executionContext.request.body, [
132
+ ...pipes,
133
+ ...param?.pipes ?? []
134
+ ], argumentMetadata, controller.owner.container);
135
+ } else if (param.type === "param") {
136
+ if (!isObject(executionContext.request.body)) return void 0;
137
+ return this.pipelineHandler.goTroughPipes(executionContext.request.body[param.data], [
138
+ ...pipes,
139
+ ...param?.pipes ?? []
140
+ ], argumentMetadata, controller.owner.container);
141
+ } else if (param.type === "index") {
142
+ if (!Array.isArray(executionContext.request.body)) return void 0;
143
+ return this.pipelineHandler.goTroughPipes(executionContext.request.body[param.data], [
144
+ ...pipes,
145
+ ...param?.pipes ?? []
146
+ ], argumentMetadata, controller.owner.container);
147
+ } else if (param.type === "request") {
148
+ return executionContext.request;
149
+ } else if (param.type === "custom") {
150
+ return this.pipelineHandler.goTroughPipes(param.factory(param.data, executionContext), [
151
+ ...pipes,
152
+ ...param?.pipes ?? []
153
+ ], argumentMetadata, controller.owner.container);
154
+ } else if (param.type === "player" && this.appEnv === AppEnviroment.Server) {
155
+ return this.pipelineHandler.goTroughPipes(param.data ? player[param.data] : player, [
156
+ ...pipes,
157
+ ...param?.pipes ?? []
158
+ ], argumentMetadata, controller.owner.container);
159
+ }
160
+ return void 0;
161
+ }));
162
+ }
163
+ };
164
+ _ts_decorate2([
165
+ inject2(APP_ENVIROMENT),
166
+ _ts_metadata2("design:type", typeof AppEnviroment === "undefined" ? Object : AppEnviroment)
167
+ ], ControllerFlowHandler.prototype, "appEnv", void 0);
168
+ _ts_decorate2([
169
+ inject2(PipelineHandler),
170
+ _ts_metadata2("design:type", typeof PipelineHandler === "undefined" ? Object : PipelineHandler)
171
+ ], ControllerFlowHandler.prototype, "pipelineHandler", void 0);
172
+ ControllerFlowHandler = _ts_decorate2([
173
+ injectable2()
174
+ ], ControllerFlowHandler);
175
+
176
+ // src/app/controller/controller-event.handler.ts
177
+ function _ts_decorate3(decorators, target, key, desc) {
178
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
179
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
180
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
181
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
182
+ }
183
+ __name(_ts_decorate3, "_ts_decorate");
184
+ function _ts_metadata3(k, v) {
185
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
186
+ }
187
+ __name(_ts_metadata3, "_ts_metadata");
188
+ var ControllerEventHandler = class {
189
+ static {
190
+ __name(this, "ControllerEventHandler");
191
+ }
192
+ appEnv;
193
+ multiplayerService;
194
+ eventService;
195
+ controllerFlowHandler;
196
+ pipelineHandler;
197
+ loggerService;
198
+ createMangoRequest;
199
+ createExecutionContext;
200
+ registerEvent(guards, interceptors, pipes, mappedErrorFilters, controller, event) {
201
+ if (event.type === "on" || event.type === "once") {
202
+ return this.eventService[event.type](event.name, async (body) => {
203
+ await this.handleEvent(guards, interceptors, pipes, mappedErrorFilters, controller, event, body);
204
+ });
205
+ } else if (event.type === "onInternal" || event.type === "onceInternal") {
206
+ return this.eventService[`$${event.type}`](event.name, async (...args) => {
207
+ const { player, body } = this.multiplayerService.parseInternalArgs(...args);
208
+ await this.handleEvent(guards, interceptors, pipes, mappedErrorFilters, controller, event, body, player);
209
+ });
210
+ } else if (event.type === "onPlayer" || event.type === "oncePlayer") {
211
+ return this.eventService[event.type](event.name, async (player, body) => {
212
+ await this.handleEvent(guards, interceptors, pipes, mappedErrorFilters, controller, event, body, player);
213
+ });
214
+ } else if (event.type === "onServer" || event.type === "onceServer") {
215
+ return this.eventService[event.type](event.name, async (body) => {
216
+ await this.handleEvent(guards, interceptors, pipes, mappedErrorFilters, controller, event, body);
217
+ });
218
+ } else if (event.type === "onWebView" || event.type === "onceWebView") {
219
+ return this.eventService[event.type](event.webViewId, event.name, async (...args) => {
220
+ const body = this.appEnv === AppEnviroment.Server ? args[1] : args[0];
221
+ const player = this.appEnv === AppEnviroment.Server ? args[0] : void 0;
222
+ await this.handleEvent(guards, interceptors, pipes, mappedErrorFilters, controller, event, body, player);
223
+ });
224
+ }
225
+ this.loggerService.error("An error occurred while trying to register event.");
226
+ throw new Error(ErrorMessage.InvalidEventType);
227
+ }
228
+ async handleEvent(guards, interceptors, pipes, mappedErrorFilters, controller, event, body, player) {
229
+ const request = this.createMangoRequest(body, player);
230
+ const executionContext = this.createExecutionContext(ExecutionContextType.Event, controller.metadata.classRef, controller.metadata.classRef.prototype[event.method], request, void 0, event.name);
231
+ try {
232
+ await this.pipelineHandler.goTroughGuards(executionContext, guards, controller.owner.container);
233
+ const args = await this.controllerFlowHandler.createArgs(controller, executionContext, event, pipes, player);
234
+ const controllerMethod = controller.instance[event.method];
235
+ const handle = isAsyncFunction(controllerMethod) ? () => controller.instance[event.method].apply(controller.instance, args) : () => controller.instance[event.method].apply(controller.instance, args);
236
+ const callHandler = {
237
+ handle,
238
+ return: /* @__PURE__ */ __name(() => {
239
+ this.loggerService.error("An error occurred while trying to return a value from an event.");
240
+ throw new Error(ErrorMessage.InvalidReturnInEvent);
241
+ }, "return")
242
+ };
243
+ if (interceptors.length > 0) {
244
+ await this.pipelineHandler.goThroughInterceptors(executionContext, interceptors, controller.owner.container, callHandler);
245
+ } else {
246
+ await callHandler.handle();
247
+ }
248
+ } catch (error) {
249
+ const errorGroup = mappedErrorFilters.find(([errorType]) => isFunction(errorType) && error instanceof errorType || errorType === "MANGO_ANY_ERROR" || error === errorType);
250
+ if (isNil(errorGroup)) return;
251
+ const instance = isFunction(errorGroup[1]) ? controller.owner.container.get(errorGroup[1]) : isObject(errorGroup[1]) && isFunction(errorGroup[1]["catch"]) ? errorGroup[1] : null;
252
+ if (isNil(instance)) {
253
+ this.loggerService.error("An error occurred while trying to go through error filters.");
254
+ throw new Error(ErrorMessage.InvalidErrorFilterDefinition);
255
+ }
256
+ await Promise.resolve(instance.catch.call(instance, error, executionContext));
257
+ }
258
+ }
259
+ };
260
+ _ts_decorate3([
261
+ inject3(APP_ENVIROMENT),
262
+ _ts_metadata3("design:type", typeof AppEnviroment === "undefined" ? Object : AppEnviroment)
263
+ ], ControllerEventHandler.prototype, "appEnv", void 0);
264
+ _ts_decorate3([
265
+ inject3(MULTIPLAYER_SERVICE),
266
+ _ts_metadata3("design:type", typeof MultiplayerService === "undefined" ? Object : MultiplayerService)
267
+ ], ControllerEventHandler.prototype, "multiplayerService", void 0);
268
+ _ts_decorate3([
269
+ inject3(EVENT_SERVICE),
270
+ _ts_metadata3("design:type", typeof InternalEventService === "undefined" ? Object : InternalEventService)
271
+ ], ControllerEventHandler.prototype, "eventService", void 0);
272
+ _ts_decorate3([
273
+ inject3(ControllerFlowHandler),
274
+ _ts_metadata3("design:type", typeof ControllerFlowHandler === "undefined" ? Object : ControllerFlowHandler)
275
+ ], ControllerEventHandler.prototype, "controllerFlowHandler", void 0);
276
+ _ts_decorate3([
277
+ inject3(PipelineHandler),
278
+ _ts_metadata3("design:type", typeof PipelineHandler === "undefined" ? Object : PipelineHandler)
279
+ ], ControllerEventHandler.prototype, "pipelineHandler", void 0);
280
+ _ts_decorate3([
281
+ inject3(LOGGER_SERVICE),
282
+ _ts_metadata3("design:type", typeof LoggerService === "undefined" ? Object : LoggerService)
283
+ ], ControllerEventHandler.prototype, "loggerService", void 0);
284
+ _ts_decorate3([
285
+ inject3(MANGO_REQUEST_FACTORY),
286
+ _ts_metadata3("design:type", Function)
287
+ ], ControllerEventHandler.prototype, "createMangoRequest", void 0);
288
+ _ts_decorate3([
289
+ inject3(EXECUTION_CONTEXT_FACTORY),
290
+ _ts_metadata3("design:type", Function)
291
+ ], ControllerEventHandler.prototype, "createExecutionContext", void 0);
292
+ ControllerEventHandler = _ts_decorate3([
293
+ injectable3()
294
+ ], ControllerEventHandler);
295
+
296
+ // src/app/controller/controller-metadata.reader.ts
297
+ import { inject as inject4, injectable as injectable4 } from "inversify";
298
+ function _ts_decorate4(decorators, target, key, desc) {
299
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
300
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
301
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
302
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
303
+ }
304
+ __name(_ts_decorate4, "_ts_decorate");
305
+ function _ts_metadata4(k, v) {
306
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
307
+ }
308
+ __name(_ts_metadata4, "_ts_metadata");
309
+ var ControllerMetadataReader = class {
310
+ static {
311
+ __name(this, "ControllerMetadataReader");
312
+ }
313
+ appEnv;
314
+ loggerService;
315
+ async read(classRef) {
316
+ const options = Reflect.getMetadata(CoreMetadataKey.Controller, classRef) ?? {};
317
+ const events = this.getEvents(classRef);
318
+ const rpcs = this.getRPCs(classRef);
319
+ const timers = this.getTimers(classRef);
320
+ return {
321
+ ...options,
322
+ classRef,
323
+ events,
324
+ rpcs,
325
+ ...this.getPipeline(classRef),
326
+ timers
327
+ };
328
+ }
329
+ getEvents(classRef) {
330
+ const events = Reflect.getMetadata(CoreMetadataKey.ControllerEvents, classRef.prototype) ?? [];
331
+ return events.map((event) => {
332
+ return {
333
+ ...event,
334
+ params: this.getMethodParams(classRef, event),
335
+ ...this.getPipeline(classRef, event.method)
336
+ };
337
+ });
338
+ }
339
+ getRPCs(classRef) {
340
+ const rpcs = Reflect.getMetadata(CoreMetadataKey.ControllerRPCs, classRef.prototype) ?? [];
341
+ return rpcs.map((rpc) => {
342
+ return {
343
+ ...rpc,
344
+ params: this.getMethodParams(classRef, rpc),
345
+ ...this.getPipeline(classRef, rpc.method)
346
+ };
347
+ });
348
+ }
349
+ getMethodParams(classRef, metadata) {
350
+ const params = Reflect.getMetadata(CoreMetadataKey.ControllerParams, classRef.prototype, metadata.method) ?? [];
351
+ params.sort((a, b) => a.index - b.index);
352
+ params.forEach((param, index) => {
353
+ if (param.index !== index) {
354
+ this.loggerService.error("An error occurred while reading controller metadata.");
355
+ throw new Error(ErrorMessage.InvalidParameterDecoratorUsage);
356
+ } else if ((metadata.type === "on" || metadata.type === "onPlayer" || metadata.type === "onInternal" || metadata.type === "onServer" || metadata.type === "onWebView" || metadata.type === "once" || metadata.type === "oncePlayer" || metadata.type === "onceInternal" || metadata.type === "onceServer" || metadata.type === "onceWebView") && param.type === "response") {
357
+ this.loggerService.error("An error occurred while reading controller metadata.");
358
+ throw new Error(ErrorMessage.ResponseDecoratorNotAllowedOnEvents);
359
+ } else if (param.type === "player" && this.appEnv === AppEnviroment.Client) {
360
+ this.loggerService.error("An error occurred while reading controller metadata.");
361
+ throw new Error(ErrorMessage.PlayerDecoratorNotAllowedOnClientEvents);
362
+ } else if (metadata.type === "onPlayerRequest" && this.appEnv === AppEnviroment.Client) {
363
+ this.loggerService.error("An error occurred while reading controller metadata.");
364
+ throw new Error(ErrorMessage.RPCNotAllowedInClient);
365
+ } else if (metadata.type === "onServerRequest" && this.appEnv === AppEnviroment.Server) {
366
+ this.loggerService.error("An error occurred while reading controller metadata.");
367
+ throw new Error(ErrorMessage.RPCNotAllowedInServer);
368
+ } else if ((metadata.type === "onPlayer" || metadata.type === "oncePlayer") && this.appEnv === AppEnviroment.Client) {
369
+ this.loggerService.error("An error occurred while reading controller metadata.");
370
+ throw new Error(ErrorMessage.EventNotAllowedInClient);
371
+ } else if ((metadata.type === "onServer" || metadata.type === "onceServer") && this.appEnv === AppEnviroment.Server) {
372
+ this.loggerService.error("An error occurred while reading controller metadata.");
373
+ throw new Error(ErrorMessage.EventNotAllowedInServer);
374
+ }
375
+ });
376
+ return params;
377
+ }
378
+ getPipeline(target, method) {
379
+ const guards = Reflect.getMetadata(CoreMetadataKey.Guards, target, method) ?? [];
380
+ const interceptors = Reflect.getMetadata(CoreMetadataKey.Interceptors, target, method) ?? [];
381
+ const pipes = Reflect.getMetadata(CoreMetadataKey.Pipes, target, method) ?? [];
382
+ const errorFilters = Reflect.getMetadata(CoreMetadataKey.ErrorFilters, target, method) ?? [];
383
+ return {
384
+ guards,
385
+ interceptors,
386
+ pipes,
387
+ errorFilters
388
+ };
389
+ }
390
+ getTimers(classRef) {
391
+ return Reflect.getMetadata(CoreMetadataKey.Timers, classRef.prototype) ?? [];
392
+ }
393
+ };
394
+ _ts_decorate4([
395
+ inject4(APP_ENVIROMENT),
396
+ _ts_metadata4("design:type", typeof AppEnviroment === "undefined" ? Object : AppEnviroment)
397
+ ], ControllerMetadataReader.prototype, "appEnv", void 0);
398
+ _ts_decorate4([
399
+ inject4(LOGGER_SERVICE),
400
+ _ts_metadata4("design:type", typeof LoggerService === "undefined" ? Object : LoggerService)
401
+ ], ControllerMetadataReader.prototype, "loggerService", void 0);
402
+ ControllerMetadataReader = _ts_decorate4([
403
+ injectable4()
404
+ ], ControllerMetadataReader);
405
+
406
+ // src/app/controller/controller-rpc.handler.ts
407
+ import { inject as inject5, injectable as injectable5 } from "inversify";
408
+ function _ts_decorate5(decorators, target, key, desc) {
409
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
410
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
411
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
412
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
413
+ }
414
+ __name(_ts_decorate5, "_ts_decorate");
415
+ function _ts_metadata5(k, v) {
416
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
417
+ }
418
+ __name(_ts_metadata5, "_ts_metadata");
419
+ var ControllerRPCHandler = class {
420
+ static {
421
+ __name(this, "ControllerRPCHandler");
422
+ }
423
+ appEnv;
424
+ rpcService;
425
+ pipelineHandler;
426
+ controllerFlowHandler;
427
+ loggerService;
428
+ createMangoRequest;
429
+ createMangoResponse;
430
+ createExecutionContext;
431
+ async registerRPC(guards, interceptors, pipes, mappedErrorFilters, controller, rpc) {
432
+ if (rpc.type === "onRequest") {
433
+ return this.rpcService[rpc.type](rpc.name, async (body) => {
434
+ return this.handleRPC(guards, interceptors, pipes, mappedErrorFilters, controller, rpc, body);
435
+ });
436
+ } else if (rpc.type === "onPlayerRequest") {
437
+ return this.rpcService[rpc.type](rpc.name, async (player, body) => {
438
+ return this.handleRPC(guards, interceptors, pipes, mappedErrorFilters, controller, rpc, body, player);
439
+ });
440
+ } else if (rpc.type === "onServerRequest") {
441
+ return this.rpcService[rpc.type](rpc.name, async (body) => {
442
+ return this.handleRPC(guards, interceptors, pipes, mappedErrorFilters, controller, rpc, body);
443
+ });
444
+ } else if (rpc.type === "onWebViewRequest") {
445
+ return this.rpcService[rpc.type](rpc.webViewId, rpc.name, async (...args) => {
446
+ const body = this.appEnv === AppEnviroment.Server ? args[1] : args[0];
447
+ const player = this.appEnv === AppEnviroment.Server ? args[0] : void 0;
448
+ return this.handleRPC(guards, interceptors, pipes, mappedErrorFilters, controller, rpc, body, player);
449
+ });
450
+ }
451
+ this.loggerService.error("An error occurred while trying to register RPC.");
452
+ throw new Error(ErrorMessage.InvalidRPCType);
453
+ }
454
+ async handleRPC(guards, interceptors, pipes, mappedErrorFilters, controller, rpc, body, player) {
455
+ return new Promise(async (resolve) => {
456
+ const request = this.createMangoRequest(body, this.appEnv === AppEnviroment.Server && (rpc.type === "onPlayerRequest" || rpc.type === "onWebViewRequest") ? player : void 0);
457
+ const response = this.createMangoResponse();
458
+ response.$onSend((data) => resolve(data));
459
+ response.$onError((error) => resolve(error));
460
+ const executionContext = this.createExecutionContext(ExecutionContextType.RPC, controller.metadata.classRef, controller.metadata.classRef.prototype[rpc.method], request, response, rpc.name);
461
+ try {
462
+ await this.pipelineHandler.goTroughGuards(executionContext, guards, controller.owner.container);
463
+ const args = await this.controllerFlowHandler.createArgs(controller, executionContext, rpc, pipes, player);
464
+ const controllerMethod = controller.instance[rpc.method];
465
+ const handle = isAsyncFunction(controllerMethod) ? (options = {
466
+ send: true
467
+ }) => {
468
+ const result = controller.instance[rpc.method].apply(controller.instance, args);
469
+ if (options.send) {
470
+ response.send(result);
471
+ }
472
+ return result;
473
+ } : async (options = {
474
+ send: true
475
+ }) => {
476
+ const result = await controller.instance[rpc.method].apply(controller.instance, args);
477
+ if (options.send) {
478
+ response.send(result);
479
+ }
480
+ return result;
481
+ };
482
+ const callHandler = {
483
+ handle,
484
+ return: /* @__PURE__ */ __name((value) => response.send(value), "return")
485
+ };
486
+ if (interceptors.length > 0) {
487
+ await this.pipelineHandler.goThroughInterceptors(executionContext, interceptors, controller.owner.container, callHandler);
488
+ } else {
489
+ await callHandler.handle();
490
+ }
491
+ } catch (error) {
492
+ const errorGroup = mappedErrorFilters.find(([errorType]) => isFunction(errorType) && error instanceof errorType || errorType === "MANGO_ANY_ERROR" || error === errorType);
493
+ if (isNil(errorGroup)) return;
494
+ const instance = isFunction(errorGroup[1]) ? controller.owner.container.get(errorGroup[1]) : isObject(errorGroup[1]) && isFunction(errorGroup[1]["catch"]) ? errorGroup[1] : null;
495
+ if (isNil(instance)) {
496
+ return this.loggerService.error(ErrorMessage.InvalidErrorFilterDefinition);
497
+ }
498
+ await Promise.resolve(instance.catch.call(instance, error, executionContext));
499
+ }
500
+ });
501
+ }
502
+ };
503
+ _ts_decorate5([
504
+ inject5(APP_ENVIROMENT),
505
+ _ts_metadata5("design:type", typeof AppEnviroment === "undefined" ? Object : AppEnviroment)
506
+ ], ControllerRPCHandler.prototype, "appEnv", void 0);
507
+ _ts_decorate5([
508
+ inject5(RPC_SERVICE),
509
+ _ts_metadata5("design:type", typeof InternalRPCService === "undefined" ? Object : InternalRPCService)
510
+ ], ControllerRPCHandler.prototype, "rpcService", void 0);
511
+ _ts_decorate5([
512
+ inject5(PipelineHandler),
513
+ _ts_metadata5("design:type", typeof PipelineHandler === "undefined" ? Object : PipelineHandler)
514
+ ], ControllerRPCHandler.prototype, "pipelineHandler", void 0);
515
+ _ts_decorate5([
516
+ inject5(ControllerFlowHandler),
517
+ _ts_metadata5("design:type", typeof ControllerFlowHandler === "undefined" ? Object : ControllerFlowHandler)
518
+ ], ControllerRPCHandler.prototype, "controllerFlowHandler", void 0);
519
+ _ts_decorate5([
520
+ inject5(LOGGER_SERVICE),
521
+ _ts_metadata5("design:type", typeof LoggerService === "undefined" ? Object : LoggerService)
522
+ ], ControllerRPCHandler.prototype, "loggerService", void 0);
523
+ _ts_decorate5([
524
+ inject5(MANGO_REQUEST_FACTORY),
525
+ _ts_metadata5("design:type", Function)
526
+ ], ControllerRPCHandler.prototype, "createMangoRequest", void 0);
527
+ _ts_decorate5([
528
+ inject5(MANGO_RESPONSE_FACTORY),
529
+ _ts_metadata5("design:type", Function)
530
+ ], ControllerRPCHandler.prototype, "createMangoResponse", void 0);
531
+ _ts_decorate5([
532
+ inject5(EXECUTION_CONTEXT_FACTORY),
533
+ _ts_metadata5("design:type", Function)
534
+ ], ControllerRPCHandler.prototype, "createExecutionContext", void 0);
535
+ ControllerRPCHandler = _ts_decorate5([
536
+ injectable5()
537
+ ], ControllerRPCHandler);
538
+
539
+ // src/app/controller/controller.ts
540
+ import { injectable as injectable6 } from "inversify";
541
+ function _ts_decorate6(decorators, target, key, desc) {
542
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
543
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
544
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
545
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
546
+ }
547
+ __name(_ts_decorate6, "_ts_decorate");
548
+ var Controller = class {
549
+ static {
550
+ __name(this, "Controller");
551
+ }
552
+ metadata;
553
+ instance;
554
+ owner;
555
+ eventHandlers = [];
556
+ rpcHandlers = [];
557
+ };
558
+ Controller = _ts_decorate6([
559
+ injectable6()
560
+ ], Controller);
561
+
562
+ export {
563
+ PipelineHandler,
564
+ ControllerFlowHandler,
565
+ ControllerEventHandler,
566
+ ControllerMetadataReader,
567
+ ControllerRPCHandler,
568
+ Controller
569
+ };
570
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vc3JjL2FwcC9jb250cm9sbGVyL2NvbnRyb2xsZXItZXZlbnQuaGFuZGxlci50cyIsICIuLi9zcmMvYXBwL2NvbnRyb2xsZXIvcGlwZWxpbmUuaGFuZGxlci50cyIsICIuLi9zcmMvYXBwL2NvbnRyb2xsZXIvY29udHJvbGxlci1mbG93LmhhbmRsZXIudHMiLCAiLi4vc3JjL2FwcC9jb250cm9sbGVyL2NvbnRyb2xsZXItbWV0YWRhdGEucmVhZGVyLnRzIiwgIi4uL3NyYy9hcHAvY29udHJvbGxlci9jb250cm9sbGVyLXJwYy5oYW5kbGVyLnRzIiwgIi4uL3NyYy9hcHAvY29udHJvbGxlci9jb250cm9sbGVyLnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyJpbXBvcnQgeyBpbmplY3QsIGluamVjdGFibGUgfSBmcm9tICdpbnZlcnNpZnknO1xuaW1wb3J0IHR5cGUgeyBFcnJvckZpbHRlciwgR3VhcmQsIEludGVyY2VwdG9yLCBJbnRlcm5hbEV2ZW50U2VydmljZSwgTXVsdGlwbGF5ZXJTZXJ2aWNlIH0gZnJvbSAnLi4vaW50ZXJmYWNlcyc7XG5pbXBvcnQgdHlwZSB7IE5ld2FibGUgfSBmcm9tICcuLi8uLi90eXBlcyc7XG5pbXBvcnQgeyBBUFBfRU5WSVJPTUVOVCwgRVhFQ1VUSU9OX0NPTlRFWFRfRkFDVE9SWSwgTUFOR09fUkVRVUVTVF9GQUNUT1JZLCBNVUxUSVBMQVlFUl9TRVJWSUNFIH0gZnJvbSAnLi4vY29uc3RhbnRzJztcbmltcG9ydCB7IGlzRnVuY3Rpb24sIGlzTmlsLCBpc09iamVjdCB9IGZyb20gJy4uLy4uL3V0aWxzJztcbmltcG9ydCB7IFBpcGVsaW5lSGFuZGxlciB9IGZyb20gJy4vcGlwZWxpbmUuaGFuZGxlcic7XG5pbXBvcnQgdHlwZSB7IEV2ZW50TWV0YWRhdGEgfSBmcm9tICcuLi9pbnRlcmZhY2VzJztcbmltcG9ydCB7IEVWRU5UX1NFUlZJQ0UsIExPR0dFUl9TRVJWSUNFIH0gZnJvbSAnLi4vLi4vY29uc3RhbnRzJztcbmltcG9ydCB0eXBlIHsgQ29udHJvbGxlciB9IGZyb20gJy4vY29udHJvbGxlcic7XG5pbXBvcnQgeyBBcHBFbnZpcm9tZW50LCBFeGVjdXRpb25Db250ZXh0VHlwZSB9IGZyb20gJy4uL2VudW1zJztcbmltcG9ydCB7IEV4ZWN1dGlvbkNvbnRleHRCYXNlLCBNYW5nb1Jlc3BvbnNlQmFzZSwgdHlwZSBNYW5nb1JlcXVlc3RCYXNlIH0gZnJvbSAnLi4vcGlwZWxpbmUnO1xuaW1wb3J0IHsgRXJyb3JNZXNzYWdlIH0gZnJvbSAnLi4vLi4vZW51bXMnO1xuaW1wb3J0IHR5cGUgeyBDYWxsSGFuZGxlciwgTG9nZ2VyU2VydmljZSwgUGlwZSB9IGZyb20gJy4uLy4uL2ludGVyZmFjZXMnO1xuaW1wb3J0IHsgaXNBc3luY0Z1bmN0aW9uIH0gZnJvbSAnLi4vLi4vdXRpbHMnO1xuaW1wb3J0IHsgQ29udHJvbGxlckZsb3dIYW5kbGVyIH0gZnJvbSAnLi9jb250cm9sbGVyLWZsb3cuaGFuZGxlcic7XG5cbkBpbmplY3RhYmxlKClcbmV4cG9ydCBjbGFzcyBDb250cm9sbGVyRXZlbnRIYW5kbGVyIHtcbiAgICBAaW5qZWN0KEFQUF9FTlZJUk9NRU5UKSBwcml2YXRlIHJlYWRvbmx5IGFwcEVudjogQXBwRW52aXJvbWVudDtcbiAgICBAaW5qZWN0KE1VTFRJUExBWUVSX1NFUlZJQ0UpIHByaXZhdGUgcmVhZG9ubHkgbXVsdGlwbGF5ZXJTZXJ2aWNlOiBNdWx0aXBsYXllclNlcnZpY2U7XG4gICAgQGluamVjdChFVkVOVF9TRVJWSUNFKSBwcml2YXRlIHJlYWRvbmx5IGV2ZW50U2VydmljZTogSW50ZXJuYWxFdmVudFNlcnZpY2U7XG4gICAgQGluamVjdChDb250cm9sbGVyRmxvd0hhbmRsZXIpIHByaXZhdGUgcmVhZG9ubHkgY29udHJvbGxlckZsb3dIYW5kbGVyOiBDb250cm9sbGVyRmxvd0hhbmRsZXI7XG4gICAgQGluamVjdChQaXBlbGluZUhhbmRsZXIpIHByaXZhdGUgcmVhZG9ubHkgcGlwZWxpbmVIYW5kbGVyOiBQaXBlbGluZUhhbmRsZXI7XG4gICAgQGluamVjdChMT0dHRVJfU0VSVklDRSkgcHJpdmF0ZSByZWFkb25seSBsb2dnZXJTZXJ2aWNlOiBMb2dnZXJTZXJ2aWNlO1xuICAgIEBpbmplY3QoTUFOR09fUkVRVUVTVF9GQUNUT1JZKSBwcml2YXRlIHJlYWRvbmx5IGNyZWF0ZU1hbmdvUmVxdWVzdDogKGJvZHk6IHVua25vd24sIHBsYXllcj86IFBsYXllck1wKSA9PiBNYW5nb1JlcXVlc3RCYXNlO1xuICAgIEBpbmplY3QoRVhFQ1VUSU9OX0NPTlRFWFRfRkFDVE9SWSkgcHJpdmF0ZSByZWFkb25seSBjcmVhdGVFeGVjdXRpb25Db250ZXh0OiAoXG4gICAgICAgIHR5cGU6IEV4ZWN1dGlvbkNvbnRleHRUeXBlLFxuICAgICAgICBjbGFzc1JlZjogTmV3YWJsZSxcbiAgICAgICAgaGFuZGxlcjogRnVuY3Rpb24sXG4gICAgICAgIHJlcXVlc3Q6IE1hbmdvUmVxdWVzdEJhc2UsXG4gICAgICAgIHJlc3BvbnNlPzogTWFuZ29SZXNwb25zZUJhc2UsXG4gICAgICAgIG5hbWU/OiBzdHJpbmcsXG4gICAgKSA9PiBFeGVjdXRpb25Db250ZXh0QmFzZTtcblxuICAgIHB1YmxpYyByZWdpc3RlckV2ZW50KFxuICAgICAgICBndWFyZHM6IChOZXdhYmxlPEd1YXJkPiB8IEd1YXJkKVtdLFxuICAgICAgICBpbnRlcmNlcHRvcnM6IChOZXdhYmxlPEludGVyY2VwdG9yPiB8IEludGVyY2VwdG9yKVtdLFxuICAgICAgICBwaXBlczogKE5ld2FibGU8UGlwZT4gfCBQaXBlKVtdLFxuICAgICAgICBtYXBwZWRFcnJvckZpbHRlcnM6IFthbnkgfCAnTUFOR09fQU5ZX0VSUk9SJywgTmV3YWJsZTxFcnJvckZpbHRlcj4gfCBFcnJvckZpbHRlcl1bXSxcbiAgICAgICAgY29udHJvbGxlcjogQ29udHJvbGxlcixcbiAgICAgICAgZXZlbnQ6IEV2ZW50TWV0YWRhdGEsXG4gICAgKSB7XG4gICAgICAgIGlmIChldmVudC50eXBlID09PSAnb24nIHx8IGV2ZW50LnR5cGUgPT09ICdvbmNlJykge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZXZlbnRTZXJ2aWNlW2V2ZW50LnR5cGVdKGV2ZW50Lm5hbWUsIGFzeW5jIChib2R5KSA9PiB7XG4gICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5oYW5kbGVFdmVudChndWFyZHMsIGludGVyY2VwdG9ycywgcGlwZXMsIG1hcHBlZEVycm9yRmlsdGVycywgY29udHJvbGxlciwgZXZlbnQsIGJvZHkpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSBpZiAoZXZlbnQudHlwZSA9PT0gJ29uSW50ZXJuYWwnIHx8IGV2ZW50LnR5cGUgPT09ICdvbmNlSW50ZXJuYWwnKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5ldmVudFNlcnZpY2VbYCQke2V2ZW50LnR5cGV9YF0oZXZlbnQubmFtZSwgYXN5bmMgKC4uLmFyZ3MpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCB7IHBsYXllciwgYm9keSB9ID0gdGhpcy5tdWx0aXBsYXllclNlcnZpY2UucGFyc2VJbnRlcm5hbEFyZ3M8UGxheWVyTXA+KC4uLmFyZ3MpO1xuICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMuaGFuZGxlRXZlbnQoZ3VhcmRzLCBpbnRlcmNlcHRvcnMsIHBpcGVzLCBtYXBwZWRFcnJvckZpbHRlcnMsIGNvbnRyb2xsZXIsIGV2ZW50LCBib2R5LCBwbGF5ZXIpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSBpZiAoZXZlbnQudHlwZSA9PT0gJ29uUGxheWVyJyB8fCBldmVudC50eXBlID09PSAnb25jZVBsYXllcicpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmV2ZW50U2VydmljZVtldmVudC50eXBlXShldmVudC5uYW1lLCBhc3luYyAocGxheWVyLCBib2R5KSA9PiB7XG4gICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5oYW5kbGVFdmVudChndWFyZHMsIGludGVyY2VwdG9ycywgcGlwZXMsIG1hcHBlZEVycm9yRmlsdGVycywgY29udHJvbGxlciwgZXZlbnQsIGJvZHksIHBsYXllcik7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIGlmIChldmVudC50eXBlID09PSAnb25TZXJ2ZXInIHx8IGV2ZW50LnR5cGUgPT09ICdvbmNlU2VydmVyJykge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZXZlbnRTZXJ2aWNlW2V2ZW50LnR5cGVdKGV2ZW50Lm5hbWUsIGFzeW5jIChib2R5KSA9PiB7XG4gICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5oYW5kbGVFdmVudChndWFyZHMsIGludGVyY2VwdG9ycywgcGlwZXMsIG1hcHBlZEVycm9yRmlsdGVycywgY29udHJvbGxlciwgZXZlbnQsIGJvZHkpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSBpZiAoZXZlbnQudHlwZSA9PT0gJ29uV2ViVmlldycgfHwgZXZlbnQudHlwZSA9PT0gJ29uY2VXZWJWaWV3Jykge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZXZlbnRTZXJ2aWNlW2V2ZW50LnR5cGVdKGV2ZW50LndlYlZpZXdJZCEsIGV2ZW50Lm5hbWUsIGFzeW5jICguLi5hcmdzOiB1bmtub3duW10pID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBib2R5ID0gdGhpcy5hcHBFbnYgPT09IEFwcEVudmlyb21lbnQuU2VydmVyID8gYXJnc1sxXSA6IGFyZ3NbMF07XG4gICAgICAgICAgICAgICAgY29uc3QgcGxheWVyID0gdGhpcy5hcHBFbnYgPT09IEFwcEVudmlyb21lbnQuU2VydmVyID8gPFBsYXllck1wPmFyZ3NbMF0gOiB1bmRlZmluZWQ7XG4gICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5oYW5kbGVFdmVudChndWFyZHMsIGludGVyY2VwdG9ycywgcGlwZXMsIG1hcHBlZEVycm9yRmlsdGVycywgY29udHJvbGxlciwgZXZlbnQsIGJvZHksIHBsYXllcik7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMubG9nZ2VyU2VydmljZS5lcnJvcignQW4gZXJyb3Igb2NjdXJyZWQgd2hpbGUgdHJ5aW5nIHRvIHJlZ2lzdGVyIGV2ZW50LicpO1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoRXJyb3JNZXNzYWdlLkludmFsaWRFdmVudFR5cGUpO1xuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgaGFuZGxlRXZlbnQoXG4gICAgICAgIGd1YXJkczogKE5ld2FibGU8R3VhcmQ+IHwgR3VhcmQpW10sXG4gICAgICAgIGludGVyY2VwdG9yczogKE5ld2FibGU8SW50ZXJjZXB0b3I+IHwgSW50ZXJjZXB0b3IpW10sXG4gICAgICAgIHBpcGVzOiAoTmV3YWJsZTxQaXBlPiB8IFBpcGUpW10sXG4gICAgICAgIG1hcHBlZEVycm9yRmlsdGVyczogW2FueSB8ICdNQU5HT19BTllfRVJST1InLCBOZXdhYmxlPEVycm9yRmlsdGVyPiB8IEVycm9yRmlsdGVyXVtdLFxuICAgICAgICBjb250cm9sbGVyOiBDb250cm9sbGVyLFxuICAgICAgICBldmVudDogRXZlbnRNZXRhZGF0YSxcbiAgICAgICAgYm9keTogdW5rbm93bixcbiAgICAgICAgcGxheWVyPzogUGxheWVyTXAsXG4gICAgKSB7XG4gICAgICAgIGNvbnN0IHJlcXVlc3QgPSB0aGlzLmNyZWF0ZU1hbmdvUmVxdWVzdChib2R5LCBwbGF5ZXIpO1xuICAgICAgICBjb25zdCBleGVjdXRpb25Db250ZXh0ID0gdGhpcy5jcmVhdGVFeGVjdXRpb25Db250ZXh0KFxuICAgICAgICAgICAgRXhlY3V0aW9uQ29udGV4dFR5cGUuRXZlbnQsXG4gICAgICAgICAgICBjb250cm9sbGVyLm1ldGFkYXRhLmNsYXNzUmVmLFxuICAgICAgICAgICAgY29udHJvbGxlci5tZXRhZGF0YS5jbGFzc1JlZi5wcm90b3R5cGVbZXZlbnQubWV0aG9kXSxcbiAgICAgICAgICAgIHJlcXVlc3QsXG4gICAgICAgICAgICB1bmRlZmluZWQsXG4gICAgICAgICAgICBldmVudC5uYW1lLFxuICAgICAgICApO1xuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLnBpcGVsaW5lSGFuZGxlci5nb1Ryb3VnaEd1YXJkcyhleGVjdXRpb25Db250ZXh0LCBndWFyZHMsIGNvbnRyb2xsZXIub3duZXIuY29udGFpbmVyKTtcbiAgICAgICAgICAgIGNvbnN0IGFyZ3MgPSBhd2FpdCB0aGlzLmNvbnRyb2xsZXJGbG93SGFuZGxlci5jcmVhdGVBcmdzKGNvbnRyb2xsZXIsIGV4ZWN1dGlvbkNvbnRleHQsIGV2ZW50LCBwaXBlcywgcGxheWVyKTtcbiAgICAgICAgICAgIGNvbnN0IGNvbnRyb2xsZXJNZXRob2QgPSBjb250cm9sbGVyLmluc3RhbmNlW2V2ZW50Lm1ldGhvZF0hO1xuICAgICAgICAgICAgY29uc3QgaGFuZGxlID0gaXNBc3luY0Z1bmN0aW9uKGNvbnRyb2xsZXJNZXRob2QpXG4gICAgICAgICAgICAgICAgPyAoKTogdW5rbm93biA9PiBjb250cm9sbGVyLmluc3RhbmNlW2V2ZW50Lm1ldGhvZF0hLmFwcGx5KGNvbnRyb2xsZXIuaW5zdGFuY2UsIGFyZ3MpXG4gICAgICAgICAgICAgICAgOiAoKTogUHJvbWlzZTx1bmtub3duPiA9PiBjb250cm9sbGVyLmluc3RhbmNlW2V2ZW50Lm1ldGhvZF0hLmFwcGx5KGNvbnRyb2xsZXIuaW5zdGFuY2UsIGFyZ3MpO1xuICAgICAgICAgICAgY29uc3QgY2FsbEhhbmRsZXI6IENhbGxIYW5kbGVyID0ge1xuICAgICAgICAgICAgICAgIGhhbmRsZSxcbiAgICAgICAgICAgICAgICByZXR1cm46ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5sb2dnZXJTZXJ2aWNlLmVycm9yKCdBbiBlcnJvciBvY2N1cnJlZCB3aGlsZSB0cnlpbmcgdG8gcmV0dXJuIGEgdmFsdWUgZnJvbSBhbiBldmVudC4nKTtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKEVycm9yTWVzc2FnZS5JbnZhbGlkUmV0dXJuSW5FdmVudCk7XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGlmIChpbnRlcmNlcHRvcnMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMucGlwZWxpbmVIYW5kbGVyLmdvVGhyb3VnaEludGVyY2VwdG9ycyhleGVjdXRpb25Db250ZXh0LCBpbnRlcmNlcHRvcnMsIGNvbnRyb2xsZXIub3duZXIuY29udGFpbmVyLCBjYWxsSGFuZGxlcik7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGF3YWl0IGNhbGxIYW5kbGVyLmhhbmRsZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgY29uc3QgZXJyb3JHcm91cCA9IG1hcHBlZEVycm9yRmlsdGVycy5maW5kKFxuICAgICAgICAgICAgICAgIChbZXJyb3JUeXBlXSkgPT5cbiAgICAgICAgICAgICAgICAgICAgKGlzRnVuY3Rpb24oZXJyb3JUeXBlKSAmJiBlcnJvciBpbnN0YW5jZW9mIGVycm9yVHlwZSkgfHwgZXJyb3JUeXBlID09PSAnTUFOR09fQU5ZX0VSUk9SJyB8fCBlcnJvciA9PT0gZXJyb3JUeXBlLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGlmIChpc05pbChlcnJvckdyb3VwKSkgcmV0dXJuO1xuICAgICAgICAgICAgY29uc3QgaW5zdGFuY2UgPSBpc0Z1bmN0aW9uKGVycm9yR3JvdXBbMV0pXG4gICAgICAgICAgICAgICAgPyBjb250cm9sbGVyLm93bmVyLmNvbnRhaW5lci5nZXQoZXJyb3JHcm91cFsxXSlcbiAgICAgICAgICAgICAgICA6IGlzT2JqZWN0KGVycm9yR3JvdXBbMV0pICYmIGlzRnVuY3Rpb24oZXJyb3JHcm91cFsxXVsnY2F0Y2gnXSlcbiAgICAgICAgICAgICAgICAgID8gZXJyb3JHcm91cFsxXVxuICAgICAgICAgICAgICAgICAgOiBudWxsO1xuICAgICAgICAgICAgaWYgKGlzTmlsKGluc3RhbmNlKSkge1xuICAgICAgICAgICAgICAgIHRoaXMubG9nZ2VyU2VydmljZS5lcnJvcignQW4gZXJyb3Igb2NjdXJyZWQgd2hpbGUgdHJ5aW5nIHRvIGdvIHRocm91Z2ggZXJyb3IgZmlsdGVycy4nKTtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoRXJyb3JNZXNzYWdlLkludmFsaWRFcnJvckZpbHRlckRlZmluaXRpb24pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYXdhaXQgUHJvbWlzZS5yZXNvbHZlKGluc3RhbmNlLmNhdGNoLmNhbGwoaW5zdGFuY2UsIGVycm9yLCBleGVjdXRpb25Db250ZXh0KSk7XG4gICAgICAgIH1cbiAgICB9XG59XG4iLCAiaW1wb3J0IHsgaW5qZWN0LCBpbmplY3RhYmxlIH0gZnJvbSAnaW52ZXJzaWZ5JztcbmltcG9ydCB0eXBlIHsgR3VhcmQsIEludGVyY2VwdG9yIH0gZnJvbSAnLi4vaW50ZXJmYWNlcyc7XG5pbXBvcnQgdHlwZSB7IE5ld2FibGUgfSBmcm9tICcuLi8uLi90eXBlcyc7XG5pbXBvcnQgeyBHdWFyZENhbmNlbEVycm9yLCBHdWFyZEludmFsaWRSZXR1cm5FcnJvciB9IGZyb20gJy4uLy4uL2Vycm9ycyc7XG5pbXBvcnQgeyBpc0Z1bmN0aW9uLCBpc05pbCwgaXNPYmplY3QgfSBmcm9tICcuLi8uLi91dGlscyc7XG5pbXBvcnQgdHlwZSB7IEV4ZWN1dGlvbkNvbnRleHRCYXNlIH0gZnJvbSAnLi4vcGlwZWxpbmUnO1xuaW1wb3J0IHsgRXJyb3JNZXNzYWdlIH0gZnJvbSAnLi4vLi4vZW51bXMnO1xuaW1wb3J0IHR5cGUgeyBBcmd1bWVudE1ldGFkYXRhLCBDYWxsSGFuZGxlciwgTG9nZ2VyU2VydmljZSwgUGlwZSB9IGZyb20gJy4uLy4uL2ludGVyZmFjZXMnO1xuaW1wb3J0IHsgTE9HR0VSX1NFUlZJQ0UgfSBmcm9tICcuLi8uLi9jb25zdGFudHMnO1xuaW1wb3J0IHR5cGUgeyBNb2R1bGVDb250YWluZXIgfSBmcm9tICcuLi9tb2R1bGUnO1xuXG5AaW5qZWN0YWJsZSgpXG5leHBvcnQgY2xhc3MgUGlwZWxpbmVIYW5kbGVyIHtcbiAgICBAaW5qZWN0KExPR0dFUl9TRVJWSUNFKSBwcml2YXRlIHJlYWRvbmx5IGxvZ2dlclNlcnZpY2U6IExvZ2dlclNlcnZpY2U7XG4gICAgLy8gQGluamVjdChHTE9CQUxfQVBQX0NPTlRBSU5FUikgcHJpdmF0ZSByZWFkb25seSBnbG9iYWxDb250YWluZXI6IENvbnRhaW5lcjtcblxuICAgIHB1YmxpYyBhc3luYyBnb1Ryb3VnaEd1YXJkcyhleGVjdXRpb25Db250ZXh0OiBFeGVjdXRpb25Db250ZXh0QmFzZSwgZ3VhcmRzOiAoTmV3YWJsZTxHdWFyZD4gfCBHdWFyZClbXSwgY29udGFpbmVyOiBNb2R1bGVDb250YWluZXIpIHtcbiAgICAgICAgZm9yIChjb25zdCBndWFyZCBvZiBndWFyZHMpIHtcbiAgICAgICAgICAgIGNvbnN0IGluc3RhbmNlID0gaXNGdW5jdGlvbihndWFyZCkgPyBjb250YWluZXIuZ2V0KGd1YXJkKSA6IGlzT2JqZWN0KGd1YXJkKSAmJiBpc0Z1bmN0aW9uKGd1YXJkWydjYW5BY3RpdmF0ZSddKSA/IGd1YXJkIDogbnVsbDtcbiAgICAgICAgICAgIGlmIChpc05pbChpbnN0YW5jZSkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmxvZ2dlclNlcnZpY2UuZXJyb3IoJ0FuIGVycm9yIG9jY3VycmVkIHdoaWxlIHRyeWluZyB0byBnbyB0aHJvdWdoIGd1YXJkcy4nKTtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoRXJyb3JNZXNzYWdlLkludmFsaWRHdWFyZERlZmluaXRpb24pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgY2FuQWN0aXZhdGUgPSBhd2FpdCBpbnN0YW5jZS5jYW5BY3RpdmF0ZS5jYWxsKGluc3RhbmNlLCBleGVjdXRpb25Db250ZXh0KTtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgY2FuQWN0aXZhdGUgIT09ICdib29sZWFuJykge1xuICAgICAgICAgICAgICAgIHRoaXMubG9nZ2VyU2VydmljZS5lcnJvcignQW4gZXJyb3Igb2NjdXJyZWQgd2hpbGUgdHJ5aW5nIHRvIGdvIHRocm91Z2ggZ3VhcmRzLicpO1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBHdWFyZEludmFsaWRSZXR1cm5FcnJvcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCFjYW5BY3RpdmF0ZSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBHdWFyZENhbmNlbEVycm9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwdWJsaWMgYXN5bmMgZ29UaHJvdWdoSW50ZXJjZXB0b3JzKFxuICAgICAgICBleGVjdXRpb25Db250ZXh0OiBFeGVjdXRpb25Db250ZXh0QmFzZSxcbiAgICAgICAgaW50ZXJjZXB0b3JzOiAoTmV3YWJsZTxJbnRlcmNlcHRvcj4gfCBJbnRlcmNlcHRvcilbXSxcbiAgICAgICAgY29udGFpbmVyOiBNb2R1bGVDb250YWluZXIsXG4gICAgICAgIGNhbGxIYW5kbGVyOiBDYWxsSGFuZGxlcixcbiAgICApIHtcbiAgICAgICAgZm9yIChjb25zdCBpbnRlcmNlcHRvciBvZiBpbnRlcmNlcHRvcnMpIHtcbiAgICAgICAgICAgIGNvbnN0IGluc3RhbmNlID0gaXNGdW5jdGlvbihpbnRlcmNlcHRvcilcbiAgICAgICAgICAgICAgICA/IGNvbnRhaW5lci5nZXQoaW50ZXJjZXB0b3IpXG4gICAgICAgICAgICAgICAgOiBpc09iamVjdChpbnRlcmNlcHRvcikgJiYgaXNGdW5jdGlvbihpbnRlcmNlcHRvclsnaW50ZXJjZXB0J10pXG4gICAgICAgICAgICAgICAgICA/IGludGVyY2VwdG9yXG4gICAgICAgICAgICAgICAgICA6IG51bGw7XG4gICAgICAgICAgICBpZiAoaXNOaWwoaW5zdGFuY2UpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5sb2dnZXJTZXJ2aWNlLmVycm9yKCdBbiBlcnJvciBvY2N1cnJlZCB3aGlsZSB0cnlpbmcgdG8gZ28gdGhyb3VnaCBpbnRlcmNlcHRvcnMuJyk7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKEVycm9yTWVzc2FnZS5JbnZhbGlkSW50ZXJjZXB0b3JEZWZpbml0aW9uKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGF3YWl0IGluc3RhbmNlLmludGVyY2VwdC5jYWxsKGluc3RhbmNlLCBleGVjdXRpb25Db250ZXh0LCBjYWxsSGFuZGxlcik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwdWJsaWMgYXN5bmMgZ29Ucm91Z2hQaXBlcyhcbiAgICAgICAgdmFsdWU6IHVua25vd24sXG4gICAgICAgIHBpcGVzOiAoTmV3YWJsZTxQaXBlPiB8IFBpcGUpW10sXG4gICAgICAgIGFyZ3VtZW50TWV0YWRhdGE6IEFyZ3VtZW50TWV0YWRhdGEsXG4gICAgICAgIGNvbnRhaW5lcjogTW9kdWxlQ29udGFpbmVyLFxuICAgICkge1xuICAgICAgICBmb3IgKGNvbnN0IHBpcGUgb2YgcGlwZXMpIHtcbiAgICAgICAgICAgIGNvbnN0IGluc3RhbmNlID0gaXNGdW5jdGlvbihwaXBlKSA/IGNvbnRhaW5lci5nZXQocGlwZSkgOiBpc09iamVjdChwaXBlKSA/IHBpcGUgOiBudWxsO1xuICAgICAgICAgICAgaWYgKGlzTmlsKGluc3RhbmNlKSkge1xuICAgICAgICAgICAgICAgIHRoaXMubG9nZ2VyU2VydmljZS5lcnJvcignQW4gZXJyb3Igb2NjdXJyZWQgd2hpbGUgdHJ5aW5nIHRvIGdvIHRocm91Z2ggcGlwZXMuJyk7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKEVycm9yTWVzc2FnZS5JbnZhbGlkUGlwZURlZmluaXRpb24pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFsdWUgPSBhd2FpdCBQcm9taXNlLnJlc29sdmUoaW5zdGFuY2UudHJhbnNmb3JtLmNhbGwoaW5zdGFuY2UsIHZhbHVlLCBhcmd1bWVudE1ldGFkYXRhKSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgfVxufVxuIiwgImltcG9ydCB7IGluamVjdCwgaW5qZWN0YWJsZSB9IGZyb20gJ2ludmVyc2lmeSc7XG5pbXBvcnQgdHlwZSB7IENvbnRyb2xsZXIgfSBmcm9tICcuL2NvbnRyb2xsZXInO1xuaW1wb3J0IHR5cGUgeyBFeGVjdXRpb25Db250ZXh0QmFzZSB9IGZyb20gJy4uL3BpcGVsaW5lJztcbmltcG9ydCB0eXBlIHsgRXZlbnRNZXRhZGF0YSwgUlBDTWV0YWRhdGEgfSBmcm9tICcuLi9pbnRlcmZhY2VzJztcbmltcG9ydCB0eXBlIHsgTmV3YWJsZSB9IGZyb20gJy4uLy4uL3R5cGVzJztcbmltcG9ydCB0eXBlIHsgUGlwZSB9IGZyb20gJy4uLy4uL2ludGVyZmFjZXMnO1xuaW1wb3J0IHsgUGlwZWxpbmVIYW5kbGVyIH0gZnJvbSAnLi9waXBlbGluZS5oYW5kbGVyJztcbmltcG9ydCB7IGlzT2JqZWN0IH0gZnJvbSAnLi4vLi4vdXRpbHMnO1xuaW1wb3J0IHsgQXBwRW52aXJvbWVudCB9IGZyb20gJy4uL2VudW1zJztcbmltcG9ydCB7IEFQUF9FTlZJUk9NRU5UIH0gZnJvbSAnLi4vY29uc3RhbnRzJztcblxuQGluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIENvbnRyb2xsZXJGbG93SGFuZGxlciB7XG4gICAgQGluamVjdChBUFBfRU5WSVJPTUVOVCkgcHJpdmF0ZSByZWFkb25seSBhcHBFbnY6IEFwcEVudmlyb21lbnQ7XG4gICAgQGluamVjdChQaXBlbGluZUhhbmRsZXIpIHByaXZhdGUgcmVhZG9ubHkgcGlwZWxpbmVIYW5kbGVyOiBQaXBlbGluZUhhbmRsZXI7XG5cbiAgICBwdWJsaWMgYXN5bmMgY3JlYXRlQXJncyhcbiAgICAgICAgY29udHJvbGxlcjogQ29udHJvbGxlcixcbiAgICAgICAgZXhlY3V0aW9uQ29udGV4dDogRXhlY3V0aW9uQ29udGV4dEJhc2UsXG4gICAgICAgIG1ldGFkYXRhOiBSUENNZXRhZGF0YSB8IEV2ZW50TWV0YWRhdGEsXG4gICAgICAgIHBpcGVzOiAoTmV3YWJsZTxQaXBlPiB8IFBpcGUpW10sXG4gICAgICAgIHBsYXllcj86IFBsYXllck1wLFxuICAgICkge1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5hbGwoXG4gICAgICAgICAgICBtZXRhZGF0YS5wYXJhbXMubWFwKGFzeW5jIChwYXJhbSkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGFyZ3VtZW50TWV0YWRhdGEgPSB7XG4gICAgICAgICAgICAgICAgICAgIHR5cGU6IHBhcmFtLnR5cGUsXG4gICAgICAgICAgICAgICAgICAgIGRhdGE6IHBhcmFtLmRhdGEsXG4gICAgICAgICAgICAgICAgICAgIG1ldGF0eXBlOiBwYXJhbS5tZXRhdHlwZSxcbiAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgICAgaWYgKHBhcmFtLnR5cGUgPT09ICdib2R5Jykge1xuICAgICAgICAgICAgICAgICAgICAvLyBCb2R5XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnBpcGVsaW5lSGFuZGxlci5nb1Ryb3VnaFBpcGVzKFxuICAgICAgICAgICAgICAgICAgICAgICAgZXhlY3V0aW9uQ29udGV4dC5yZXF1ZXN0LmJvZHksXG4gICAgICAgICAgICAgICAgICAgICAgICBbLi4ucGlwZXMsIC4uLihwYXJhbT8ucGlwZXMgPz8gW10pXSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGFyZ3VtZW50TWV0YWRhdGEsXG4gICAgICAgICAgICAgICAgICAgICAgICBjb250cm9sbGVyLm93bmVyLmNvbnRhaW5lcixcbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHBhcmFtLnR5cGUgPT09ICdwYXJhbScpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gUGFyYW1cbiAgICAgICAgICAgICAgICAgICAgaWYgKCFpc09iamVjdChleGVjdXRpb25Db250ZXh0LnJlcXVlc3QuYm9keSkpIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnBpcGVsaW5lSGFuZGxlci5nb1Ryb3VnaFBpcGVzKFxuICAgICAgICAgICAgICAgICAgICAgICAgKDxSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj5leGVjdXRpb25Db250ZXh0LnJlcXVlc3QuYm9keSlbcGFyYW0uZGF0YV0sXG4gICAgICAgICAgICAgICAgICAgICAgICBbLi4ucGlwZXMsIC4uLihwYXJhbT8ucGlwZXMgPz8gW10pXSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGFyZ3VtZW50TWV0YWRhdGEsXG4gICAgICAgICAgICAgICAgICAgICAgICBjb250cm9sbGVyLm93bmVyLmNvbnRhaW5lcixcbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHBhcmFtLnR5cGUgPT09ICdpbmRleCcpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KGV4ZWN1dGlvbkNvbnRleHQucmVxdWVzdC5ib2R5KSkgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMucGlwZWxpbmVIYW5kbGVyLmdvVHJvdWdoUGlwZXMoXG4gICAgICAgICAgICAgICAgICAgICAgICBleGVjdXRpb25Db250ZXh0LnJlcXVlc3QuYm9keVtwYXJhbS5kYXRhXSxcbiAgICAgICAgICAgICAgICAgICAgICAgIFsuLi5waXBlcywgLi4uKHBhcmFtPy5waXBlcyA/PyBbXSldLFxuICAgICAgICAgICAgICAgICAgICAgICAgYXJndW1lbnRNZXRhZGF0YSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRyb2xsZXIub3duZXIuY29udGFpbmVyLFxuICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAocGFyYW0udHlwZSA9PT0gJ3JlcXVlc3QnKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBleGVjdXRpb25Db250ZXh0LnJlcXVlc3Q7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChwYXJhbS50eXBlID09PSAnY3VzdG9tJykge1xuICAgICAgICAgICAgICAgICAgICAvLyBDdXN0b21cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMucGlwZWxpbmVIYW5kbGVyLmdvVHJvdWdoUGlwZXMoXG4gICAgICAgICAgICAgICAgICAgICAgICBwYXJhbS5mYWN0b3J5KHBhcmFtLmRhdGEsIGV4ZWN1dGlvbkNvbnRleHQpLFxuICAgICAgICAgICAgICAgICAgICAgICAgWy4uLnBpcGVzLCAuLi4ocGFyYW0/LnBpcGVzID8/IFtdKV0sXG4gICAgICAgICAgICAgICAgICAgICAgICBhcmd1bWVudE1ldGFkYXRhLFxuICAgICAgICAgICAgICAgICAgICAgICAgY29udHJvbGxlci5vd25lci5jb250YWluZXIsXG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChwYXJhbS50eXBlID09PSAncGxheWVyJyAmJiB0aGlzLmFwcEVudiA9PT0gQXBwRW52aXJvbWVudC5TZXJ2ZXIpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gUGxheWVyIChTZXJ2ZXIpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnBpcGVsaW5lSGFuZGxlci5nb1Ryb3VnaFBpcGVzKFxuICAgICAgICAgICAgICAgICAgICAgICAgcGFyYW0uZGF0YSA/IHBsYXllciFbPGtleW9mIFBsYXllck1wPnBhcmFtLmRhdGFdIDogcGxheWVyLFxuICAgICAgICAgICAgICAgICAgICAgICAgWy4uLnBpcGVzLCAuLi4ocGFyYW0/LnBpcGVzID8/IFtdKV0sXG4gICAgICAgICAgICAgICAgICAgICAgICBhcmd1bWVudE1ldGFkYXRhLFxuICAgICAgICAgICAgICAgICAgICAgICAgY29udHJvbGxlci5vd25lci5jb250YWluZXIsXG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgICAgICB9KSxcbiAgICAgICAgKTtcbiAgICB9XG59XG4iLCAiaW1wb3J0IHsgaW5qZWN0LCBpbmplY3RhYmxlIH0gZnJvbSAnaW52ZXJzaWZ5JztcbmltcG9ydCB0eXBlIHsgR3VhcmQsIEludGVyY2VwdG9yLCBFcnJvckZpbHRlciwgVGltZXJNZXRhZGF0YSB9IGZyb20gJy4uL2ludGVyZmFjZXMnO1xuaW1wb3J0IHR5cGUgeyBOZXdhYmxlIH0gZnJvbSAnLi4vLi4vdHlwZXMnO1xuaW1wb3J0IHR5cGUgeyBDb250cm9sbGVyTWV0YWRhdGEsIEV2ZW50TWV0YWRhdGEsIE1ldGhvZFBhcmFtZXRlciwgUlBDTWV0YWRhdGEgfSBmcm9tICcuLi9pbnRlcmZhY2VzJztcbmltcG9ydCB7IEFwcEVudmlyb21lbnQsIENvcmVNZXRhZGF0YUtleSB9IGZyb20gJy4uL2VudW1zJztcbmltcG9ydCB7IEFQUF9FTlZJUk9NRU5UIH0gZnJvbSAnLi4vY29uc3RhbnRzJztcbmltcG9ydCB7IEVycm9yTWVzc2FnZSB9IGZyb20gJy4uLy4uL2VudW1zJztcbmltcG9ydCB0eXBlIHsgTG9nZ2VyU2VydmljZSwgUGlwZSB9IGZyb20gJy4uLy4uL2ludGVyZmFjZXMnO1xuaW1wb3J0IHsgTE9HR0VSX1NFUlZJQ0UgfSBmcm9tICcuLi8uLi9jb25zdGFudHMnO1xuXG5AaW5qZWN0YWJsZSgpXG5leHBvcnQgY2xhc3MgQ29udHJvbGxlck1ldGFkYXRhUmVhZGVyIHtcbiAgICBAaW5qZWN0KEFQUF9FTlZJUk9NRU5UKSBwcml2YXRlIHJlYWRvbmx5IGFwcEVudjogQXBwRW52aXJvbWVudDtcbiAgICBAaW5qZWN0KExPR0dFUl9TRVJWSUNFKSBwcml2YXRlIHJlYWRvbmx5IGxvZ2dlclNlcnZpY2U6IExvZ2dlclNlcnZpY2U7XG5cbiAgICBwdWJsaWMgYXN5bmMgcmVhZChjbGFzc1JlZjogTmV3YWJsZSkge1xuICAgICAgICBjb25zdCBvcHRpb25zID1cbiAgICAgICAgICAgIFJlZmxlY3QuZ2V0TWV0YWRhdGE8UGljazxDb250cm9sbGVyTWV0YWRhdGEsICdwcmVmaXgnPj4oQ29yZU1ldGFkYXRhS2V5LkNvbnRyb2xsZXIsIGNsYXNzUmVmKSA/P1xuICAgICAgICAgICAgPFBpY2s8Q29udHJvbGxlck1ldGFkYXRhLCAncHJlZml4Jz4+e307XG4gICAgICAgIGNvbnN0IGV2ZW50cyA9IHRoaXMuZ2V0RXZlbnRzKGNsYXNzUmVmKTtcbiAgICAgICAgY29uc3QgcnBjcyA9IHRoaXMuZ2V0UlBDcyhjbGFzc1JlZik7XG4gICAgICAgIGNvbnN0IHRpbWVycyA9IHRoaXMuZ2V0VGltZXJzKGNsYXNzUmVmKTtcblxuICAgICAgICByZXR1cm4gPENvbnRyb2xsZXJNZXRhZGF0YT57XG4gICAgICAgICAgICAuLi5vcHRpb25zLFxuICAgICAgICAgICAgY2xhc3NSZWYsXG4gICAgICAgICAgICBldmVudHMsXG4gICAgICAgICAgICBycGNzLFxuICAgICAgICAgICAgLi4udGhpcy5nZXRQaXBlbGluZShjbGFzc1JlZiksXG4gICAgICAgICAgICB0aW1lcnMsXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXRFdmVudHMoY2xhc3NSZWY6IE5ld2FibGUpIHtcbiAgICAgICAgY29uc3QgZXZlbnRzID0gUmVmbGVjdC5nZXRNZXRhZGF0YTxFdmVudE1ldGFkYXRhW10+KENvcmVNZXRhZGF0YUtleS5Db250cm9sbGVyRXZlbnRzLCBjbGFzc1JlZi5wcm90b3R5cGUpID8/IFtdO1xuXG4gICAgICAgIHJldHVybiBldmVudHMubWFwKChldmVudCkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIDxFdmVudE1ldGFkYXRhPntcbiAgICAgICAgICAgICAgICAuLi5ldmVudCxcbiAgICAgICAgICAgICAgICBwYXJhbXM6IHRoaXMuZ2V0TWV0aG9kUGFyYW1zKGNsYXNzUmVmLCBldmVudCksXG4gICAgICAgICAgICAgICAgLi4udGhpcy5nZXRQaXBlbGluZShjbGFzc1JlZiwgZXZlbnQubWV0aG9kKSxcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgZ2V0UlBDcyhjbGFzc1JlZjogTmV3YWJsZSkge1xuICAgICAgICBjb25zdCBycGNzID0gUmVmbGVjdC5nZXRNZXRhZGF0YTxSUENNZXRhZGF0YVtdPihDb3JlTWV0YWRhdGFLZXkuQ29udHJvbGxlclJQQ3MsIGNsYXNzUmVmLnByb3RvdHlwZSkgPz8gW107XG5cbiAgICAgICAgcmV0dXJuIHJwY3MubWFwKChycGMpID0+IHtcbiAgICAgICAgICAgIHJldHVybiA8UlBDTWV0YWRhdGE+e1xuICAgICAgICAgICAgICAgIC4uLnJwYyxcbiAgICAgICAgICAgICAgICBwYXJhbXM6IHRoaXMuZ2V0TWV0aG9kUGFyYW1zKGNsYXNzUmVmLCBycGMpLFxuICAgICAgICAgICAgICAgIC4uLnRoaXMuZ2V0UGlwZWxpbmUoY2xhc3NSZWYsIHJwYy5tZXRob2QpLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXRNZXRob2RQYXJhbXMoY2xhc3NSZWY6IE5ld2FibGUsIG1ldGFkYXRhOiBFdmVudE1ldGFkYXRhIHwgUlBDTWV0YWRhdGEpIHtcbiAgICAgICAgY29uc3QgcGFyYW1zID0gUmVmbGVjdC5nZXRNZXRhZGF0YTxNZXRob2RQYXJhbWV0ZXJbXT4oQ29yZU1ldGFkYXRhS2V5LkNvbnRyb2xsZXJQYXJhbXMsIGNsYXNzUmVmLnByb3RvdHlwZSwgbWV0YWRhdGEubWV0aG9kKSA/PyBbXTtcblxuICAgICAgICBwYXJhbXMuc29ydCgoYSwgYikgPT4gYS5pbmRleCAtIGIuaW5kZXgpO1xuICAgICAgICBwYXJhbXMuZm9yRWFjaCgocGFyYW0sIGluZGV4KSA9PiB7XG4gICAgICAgICAgICBpZiAocGFyYW0uaW5kZXggIT09IGluZGV4KSB7XG4gICAgICAgICAgICAgICAgdGhpcy5sb2dnZXJTZXJ2aWNlLmVycm9yKCdBbiBlcnJvciBvY2N1cnJlZCB3aGlsZSByZWFkaW5nIGNvbnRyb2xsZXIgbWV0YWRhdGEuJyk7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKEVycm9yTWVzc2FnZS5JbnZhbGlkUGFyYW1ldGVyRGVjb3JhdG9yVXNhZ2UpO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChcbiAgICAgICAgICAgICAgICAobWV0YWRhdGEudHlwZSA9PT0gJ29uJyB8fFxuICAgICAgICAgICAgICAgICAgICBtZXRhZGF0YS50eXBlID09PSAnb25QbGF5ZXInIHx8XG4gICAgICAgICAgICAgICAgICAgIG1ldGFkYXRhLnR5cGUgPT09ICdvbkludGVybmFsJyB8fFxuICAgICAgICAgICAgICAgICAgICBtZXRhZGF0YS50eXBlID09PSAnb25TZXJ2ZXInIHx8XG4gICAgICAgICAgICAgICAgICAgIG1ldGFkYXRhLnR5cGUgPT09ICdvbldlYlZpZXcnIHx8XG4gICAgICAgICAgICAgICAgICAgIG1ldGFkYXRhLnR5cGUgPT09ICdvbmNlJyB8fFxuICAgICAgICAgICAgICAgICAgICBtZXRhZGF0YS50eXBlID09PSAnb25jZVBsYXllcicgfHxcbiAgICAgICAgICAgICAgICAgICAgbWV0YWRhdGEudHlwZSA9PT0gJ29uY2VJbnRlcm5hbCcgfHxcbiAgICAgICAgICAgICAgICAgICAgbWV0YWRhdGEudHlwZSA9PT0gJ29uY2VTZXJ2ZXInIHx8XG4gICAgICAgICAgICAgICAgICAgIG1ldGFkYXRhLnR5cGUgPT09ICdvbmNlV2ViVmlldycpICYmXG4gICAgICAgICAgICAgICAgcGFyYW0udHlwZSA9PT0gJ3Jlc3BvbnNlJ1xuICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgLy8gUmVzcG9uc2VcbiAgICAgICAgICAgICAgICB0aGlzLmxvZ2dlclNlcnZpY2UuZXJyb3IoJ0FuIGVycm9yIG9jY3VycmVkIHdoaWxlIHJlYWRpbmcgY29udHJvbGxlciBtZXRhZGF0YS4nKTtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoRXJyb3JNZXNzYWdlLlJlc3BvbnNlRGVjb3JhdG9yTm90QWxsb3dlZE9uRXZlbnRzKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAocGFyYW0udHlwZSA9PT0gJ3BsYXllcicgJiYgdGhpcy5hcHBFbnYgPT09IEFwcEVudmlyb21lbnQuQ2xpZW50KSB7XG4gICAgICAgICAgICAgICAgLy8gUGxheWVyIChDbGllbnQpIC0gTm90IGFsbG93ZWRcbiAgICAgICAgICAgICAgICB0aGlzLmxvZ2dlclNlcnZpY2UuZXJyb3IoJ0FuIGVycm9yIG9jY3VycmVkIHdoaWxlIHJlYWRpbmcgY29udHJvbGxlciBtZXRhZGF0YS4nKTtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoRXJyb3JNZXNzYWdlLlBsYXllckRlY29yYXRvck5vdEFsbG93ZWRPbkNsaWVudEV2ZW50cyk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKG1ldGFkYXRhLnR5cGUgPT09ICdvblBsYXllclJlcXVlc3QnICYmIHRoaXMuYXBwRW52ID09PSBBcHBFbnZpcm9tZW50LkNsaWVudCkge1xuICAgICAgICAgICAgICAgIHRoaXMubG9nZ2VyU2VydmljZS5lcnJvcignQW4gZXJyb3Igb2NjdXJyZWQgd2hpbGUgcmVhZGluZyBjb250cm9sbGVyIG1ldGFkYXRhLicpO1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihFcnJvck1lc3NhZ2UuUlBDTm90QWxsb3dlZEluQ2xpZW50KTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAobWV0YWRhdGEudHlwZSA9PT0gJ29uU2VydmVyUmVxdWVzdCcgJiYgdGhpcy5hcHBFbnYgPT09IEFwcEVudmlyb21lbnQuU2VydmVyKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5sb2dnZXJTZXJ2aWNlLmVycm9yKCdBbiBlcnJvciBvY2N1cnJlZCB3aGlsZSByZWFkaW5nIGNvbnRyb2xsZXIgbWV0YWRhdGEuJyk7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKEVycm9yTWVzc2FnZS5SUENOb3RBbGxvd2VkSW5TZXJ2ZXIpO1xuICAgICAgICAgICAgfSBlbHNlIGlmICgobWV0YWRhdGEudHlwZSA9PT0gJ29uUGxheWVyJyB8fCBtZXRhZGF0YS50eXBlID09PSAnb25jZVBsYXllcicpICYmIHRoaXMuYXBwRW52ID09PSBBcHBFbnZpcm9tZW50LkNsaWVudCkge1xuICAgICAgICAgICAgICAgIHRoaXMubG9nZ2VyU2VydmljZS5lcnJvcignQW4gZXJyb3Igb2NjdXJyZWQgd2hpbGUgcmVhZGluZyBjb250cm9sbGVyIG1ldGFkYXRhLicpO1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihFcnJvck1lc3NhZ2UuRXZlbnROb3RBbGxvd2VkSW5DbGllbnQpO1xuICAgICAgICAgICAgfSBlbHNlIGlmICgobWV0YWRhdGEudHlwZSA9PT0gJ29uU2VydmVyJyB8fCBtZXRhZGF0YS50eXBlID09PSAnb25jZVNlcnZlcicpICYmIHRoaXMuYXBwRW52ID09PSBBcHBFbnZpcm9tZW50LlNlcnZlcikge1xuICAgICAgICAgICAgICAgIHRoaXMubG9nZ2VyU2VydmljZS5lcnJvcignQW4gZXJyb3Igb2NjdXJyZWQgd2hpbGUgcmVhZGluZyBjb250cm9sbGVyIG1ldGFkYXRhLicpO1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihFcnJvck1lc3NhZ2UuRXZlbnROb3RBbGxvd2VkSW5TZXJ2ZXIpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4gcGFyYW1zO1xuICAgIH1cblxuICAgIHByaXZhdGUgZ2V0UGlwZWxpbmUodGFyZ2V0OiBOZXdhYmxlIHwgb2JqZWN0LCBtZXRob2Q/OiBzdHJpbmcpIHtcbiAgICAgICAgY29uc3QgZ3VhcmRzID0gUmVmbGVjdC5nZXRNZXRhZGF0YTxOZXdhYmxlPEd1YXJkPltdPihDb3JlTWV0YWRhdGFLZXkuR3VhcmRzLCB0YXJnZXQsIG1ldGhvZCkgPz8gW107XG4gICAgICAgIGNvbnN0IGludGVyY2VwdG9ycyA9IFJlZmxlY3QuZ2V0TWV0YWRhdGE8TmV3YWJsZTxJbnRlcmNlcHRvcj5bXT4oQ29yZU1ldGFkYXRhS2V5LkludGVyY2VwdG9ycywgdGFyZ2V0LCBtZXRob2QpID8/IFtdO1xuICAgICAgICBjb25zdCBwaXBlcyA9IFJlZmxlY3QuZ2V0TWV0YWRhdGE8TmV3YWJsZTxQaXBlPltdPihDb3JlTWV0YWRhdGFLZXkuUGlwZXMsIHRhcmdldCwgbWV0aG9kKSA/PyBbXTtcbiAgICAgICAgY29uc3QgZXJyb3JGaWx0ZXJzID0gUmVmbGVjdC5nZXRNZXRhZGF0YTxOZXdhYmxlPEVycm9yRmlsdGVyPltdPihDb3JlTWV0YWRhdGFLZXkuRXJyb3JGaWx0ZXJzLCB0YXJnZXQsIG1ldGhvZCkgPz8gW107XG5cbiAgICAgICAgcmV0dXJuIHsgZ3VhcmRzLCBpbnRlcmNlcHRvcnMsIHBpcGVzLCBlcnJvckZpbHRlcnMgfTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGdldFRpbWVycyhjbGFzc1JlZjogTmV3YWJsZSkge1xuICAgICAgICByZXR1cm4gUmVmbGVjdC5nZXRNZXRhZGF0YTxUaW1lck1ldGFkYXRhW10+KENvcmVNZXRhZGF0YUtleS5UaW1lcnMsIGNsYXNzUmVmLnByb3RvdHlwZSkgPz8gW107XG4gICAgfVxufVxuIiwgImltcG9ydCB7IGluamVjdCwgaW5qZWN0YWJsZSB9IGZyb20gJ2ludmVyc2lmeSc7XG5pbXBvcnQgdHlwZSB7IEVycm9yRmlsdGVyLCBHdWFyZCwgSW50ZXJjZXB0b3IsIEludGVybmFsUlBDU2VydmljZSB9IGZyb20gJy4uL2ludGVyZmFjZXMnO1xuaW1wb3J0IHsgTE9HR0VSX1NFUlZJQ0UsIFJQQ19TRVJWSUNFIH0gZnJvbSAnLi4vLi4vY29uc3RhbnRzJztcbmltcG9ydCB7IEFQUF9FTlZJUk9NRU5ULCBFWEVDVVRJT05fQ09OVEVYVF9GQUNUT1JZLCBNQU5HT19SRVFVRVNUX0ZBQ1RPUlksIE1BTkdPX1JFU1BPTlNFX0ZBQ1RPUlkgfSBmcm9tICcuLi9jb25zdGFudHMnO1xuaW1wb3J0IHR5cGUgeyBOZXdhYmxlIH0gZnJvbSAnLi4vLi4vdHlwZXMnO1xuaW1wb3J0IHsgaXNBc3luY0Z1bmN0aW9uLCBpc0Z1bmN0aW9uLCBpc05pbCwgaXNPYmplY3QgfSBmcm9tICcuLi8uLi91dGlscyc7XG5pbXBvcnQgeyBQaXBlbGluZUhhbmRsZXIgfSBmcm9tICcuL3BpcGVsaW5lLmhhbmRsZXInO1xuaW1wb3J0IHR5cGUgeyBSUENNZXRhZGF0YSB9IGZyb20gJy4uL2ludGVyZmFjZXMnO1xuaW1wb3J0IHsgQXBwRW52aXJvbWVudCwgRXhlY3V0aW9uQ29udGV4dFR5cGUgfSBmcm9tICcuLi9lbnVtcyc7XG5pbXBvcnQgeyBFeGVjdXRpb25Db250ZXh0QmFzZSwgdHlwZSBNYW5nb1JlcXVlc3RCYXNlLCB0eXBlIE1hbmdvUmVzcG9uc2VCYXNlIH0gZnJvbSAnLi4vcGlwZWxpbmUnO1xuaW1wb3J0IHsgRXJyb3JNZXNzYWdlIH0gZnJvbSAnLi4vLi4vZW51bXMnO1xuaW1wb3J0IHR5cGUgeyBDYWxsSGFuZGxlciwgTG9nZ2VyU2VydmljZSwgUGlwZSB9IGZyb20gJy4uLy4uL2ludGVyZmFjZXMnO1xuaW1wb3J0IHR5cGUgeyBDb250cm9sbGVyIH0gZnJvbSAnLi9jb250cm9sbGVyJztcbmltcG9ydCB7IENvbnRyb2xsZXJGbG93SGFuZGxlciB9IGZyb20gJy4vY29udHJvbGxlci1mbG93LmhhbmRsZXInO1xuXG5AaW5qZWN0YWJsZSgpXG5leHBvcnQgY2xhc3MgQ29udHJvbGxlclJQQ0hhbmRsZXIge1xuICAgIEBpbmplY3QoQVBQX0VOVklST01FTlQpIHByaXZhdGUgcmVhZG9ubHkgYXBwRW52OiBBcHBFbnZpcm9tZW50O1xuICAgIEBpbmplY3QoUlBDX1NFUlZJQ0UpIHByaXZhdGUgcmVhZG9ubHkgcnBjU2VydmljZTogSW50ZXJuYWxSUENTZXJ2aWNlO1xuICAgIEBpbmplY3QoUGlwZWxpbmVIYW5kbGVyKSBwcml2YXRlIHJlYWRvbmx5IHBpcGVsaW5lSGFuZGxlcjogUGlwZWxpbmVIYW5kbGVyO1xuICAgIEBpbmplY3QoQ29udHJvbGxlckZsb3dIYW5kbGVyKSBwcml2YXRlIHJlYWRvbmx5IGNvbnRyb2xsZXJGbG93SGFuZGxlcjogQ29udHJvbGxlckZsb3dIYW5kbGVyO1xuICAgIEBpbmplY3QoTE9HR0VSX1NFUlZJQ0UpIHByaXZhdGUgcmVhZG9ubHkgbG9nZ2VyU2VydmljZTogTG9nZ2VyU2VydmljZTtcbiAgICBAaW5qZWN0KE1BTkdPX1JFUVVFU1RfRkFDVE9SWSkgcHJpdmF0ZSByZWFkb25seSBjcmVhdGVNYW5nb1JlcXVlc3Q6IChkYXRhOiB1bmtub3duLCBwbGF5ZXI/OiBQbGF5ZXJNcCkgPT4gTWFuZ29SZXF1ZXN0QmFzZTtcbiAgICBAaW5qZWN0KE1BTkdPX1JFU1BPTlNFX0ZBQ1RPUlkpIHByaXZhdGUgcmVhZG9ubHkgY3JlYXRlTWFuZ29SZXNwb25zZTogKCkgPT4gTWFuZ29SZXNwb25zZUJhc2U7XG4gICAgQGluamVjdChFWEVDVVRJT05fQ09OVEVYVF9GQUNUT1JZKSBwcml2YXRlIHJlYWRvbmx5IGNyZWF0ZUV4ZWN1dGlvbkNvbnRleHQ6IChcbiAgICAgICAgdHlwZTogRXhlY3V0aW9uQ29udGV4dFR5cGUsXG4gICAgICAgIGNsYXNzUmVmOiBOZXdhYmxlLFxuICAgICAgICBoYW5kbGVyOiBGdW5jdGlvbixcbiAgICAgICAgcmVxdWVzdDogTWFuZ29SZXF1ZXN0QmFzZSxcbiAgICAgICAgcmVzcG9uc2U6IE1hbmdvUmVzcG9uc2VCYXNlLFxuICAgICAgICBuYW1lOiBzdHJpbmcsXG4gICAgKSA9PiBFeGVjdXRpb25Db250ZXh0QmFzZTtcblxuICAgIHB1YmxpYyBhc3luYyByZWdpc3RlclJQQyhcbiAgICAgICAgZ3VhcmRzOiAoTmV3YWJsZTxHdWFyZD4gfCBHdWFyZClbXSxcbiAgICAgICAgaW50ZXJjZXB0b3JzOiAoTmV3YWJsZTxJbnRlcmNlcHRvcj4gfCBJbnRlcmNlcHRvcilbXSxcbiAgICAgICAgcGlwZXM6IChOZXdhYmxlPFBpcGU+IHwgUGlwZSlbXSxcbiAgICAgICAgbWFwcGVkRXJyb3JGaWx0ZXJzOiBbYW55IHwgJ01BTkdPX0FOWV9FUlJPUicsIE5ld2FibGU8RXJyb3JGaWx0ZXI+IHwgRXJyb3JGaWx0ZXJdW10sXG4gICAgICAgIGNvbnRyb2xsZXI6IENvbnRyb2xsZXIsXG4gICAgICAgIHJwYzogUlBDTWV0YWRhdGEsXG4gICAgKSB7XG4gICAgICAgIGlmIChycGMudHlwZSA9PT0gJ29uUmVxdWVzdCcpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnJwY1NlcnZpY2VbcnBjLnR5cGVdKHJwYy5uYW1lLCBhc3luYyAoYm9keSkgPT4ge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmhhbmRsZVJQQyhndWFyZHMsIGludGVyY2VwdG9ycywgcGlwZXMsIG1hcHBlZEVycm9yRmlsdGVycywgY29udHJvbGxlciwgcnBjLCBib2R5KTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2UgaWYgKHJwYy50eXBlID09PSAnb25QbGF5ZXJSZXF1ZXN0Jykge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMucnBjU2VydmljZVtycGMudHlwZV0ocnBjLm5hbWUsIGFzeW5jIChwbGF5ZXIsIGJvZHkpID0+IHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5oYW5kbGVSUEMoZ3VhcmRzLCBpbnRlcmNlcHRvcnMsIHBpcGVzLCBtYXBwZWRFcnJvckZpbHRlcnMsIGNvbnRyb2xsZXIsIHJwYywgYm9keSwgcGxheWVyKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2UgaWYgKHJwYy50eXBlID09PSAnb25TZXJ2ZXJSZXF1ZXN0Jykge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMucnBjU2VydmljZVtycGMudHlwZV0ocnBjLm5hbWUsIGFzeW5jIChib2R5KSA9PiB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuaGFuZGxlUlBDKGd1YXJkcywgaW50ZXJjZXB0b3JzLCBwaXBlcywgbWFwcGVkRXJyb3JGaWx0ZXJzLCBjb250cm9sbGVyLCBycGMsIGJvZHkpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSBpZiAocnBjLnR5cGUgPT09ICdvbldlYlZpZXdSZXF1ZXN0Jykge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMucnBjU2VydmljZVtycGMudHlwZV0ocnBjLndlYlZpZXdJZCEsIHJwYy5uYW1lLCBhc3luYyAoLi4uYXJnczogdW5rbm93bltdKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgYm9keSA9IHRoaXMuYXBwRW52ID09PSBBcHBFbnZpcm9tZW50LlNlcnZlciA/IGFyZ3NbMV0gOiBhcmdzWzBdO1xuICAgICAgICAgICAgICAgIGNvbnN0IHBsYXllciA9IHRoaXMuYXBwRW52ID09PSBBcHBFbnZpcm9tZW50LlNlcnZlciA/IDxQbGF5ZXJNcD5hcmdzWzBdIDogdW5kZWZpbmVkO1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmhhbmRsZVJQQyhndWFyZHMsIGludGVyY2VwdG9ycywgcGlwZXMsIG1hcHBlZEVycm9yRmlsdGVycywgY29udHJvbGxlciwgcnBjLCBib2R5LCBwbGF5ZXIpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmxvZ2dlclNlcnZpY2UuZXJyb3IoJ0FuIGVycm9yIG9jY3VycmVkIHdoaWxlIHRyeWluZyB0byByZWdpc3RlciBSUEMuJyk7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihFcnJvck1lc3NhZ2UuSW52YWxpZFJQQ1R5cGUpO1xuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgaGFuZGxlUlBDKFxuICAgICAgICBndWFyZHM6IChOZXdhYmxlPEd1YXJkPiB8IEd1YXJkKVtdLFxuICAgICAgICBpbnRlcmNlcHRvcnM6IChOZXdhYmxlPEludGVyY2VwdG9yPiB8IEludGVyY2VwdG9yKVtdLFxuICAgICAgICBwaXBlczogKE5ld2FibGU8UGlwZT4gfCBQaXBlKVtdLFxuICAgICAgICBtYXBwZWRFcnJvckZpbHRlcnM6IFthbnkgfCAnTUFOR09fQU5ZX0VSUk9SJywgTmV3YWJsZTxFcnJvckZpbHRlcj4gfCBFcnJvckZpbHRlcl1bXSxcbiAgICAgICAgY29udHJvbGxlcjogQ29udHJvbGxlcixcbiAgICAgICAgcnBjOiBSUENNZXRhZGF0YSxcbiAgICAgICAgYm9keTogdW5rbm93bixcbiAgICAgICAgcGxheWVyPzogUGxheWVyTXAsXG4gICAgKSB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZShhc3luYyAocmVzb2x2ZSkgPT4ge1xuICAgICAgICAgICAgY29uc3QgcmVxdWVzdCA9IHRoaXMuY3JlYXRlTWFuZ29SZXF1ZXN0KFxuICAgICAgICAgICAgICAgIGJvZHksXG4gICAgICAgICAgICAgICAgdGhpcy5hcHBFbnYgPT09IEFwcEVudmlyb21lbnQuU2VydmVyICYmIChycGMudHlwZSA9PT0gJ29uUGxheWVyUmVxdWVzdCcgfHwgcnBjLnR5cGUgPT09ICdvbldlYlZpZXdSZXF1ZXN0JylcbiAgICAgICAgICAgICAgICAgICAgPyBwbGF5ZXJcbiAgICAgICAgICAgICAgICAgICAgOiB1bmRlZmluZWQsXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgY29uc3QgcmVzcG9uc2UgPSB0aGlzLmNyZWF0ZU1hbmdvUmVzcG9uc2UoKTtcbiAgICAgICAgICAgIHJlc3BvbnNlLiRvblNlbmQoKGRhdGEpID0+IHJlc29sdmUoZGF0YSkpO1xuICAgICAgICAgICAgcmVzcG9uc2UuJG9uRXJyb3IoKGVycm9yKSA9PiByZXNvbHZlKGVycm9yKSk7XG4gICAgICAgICAgICBjb25zdCBleGVjdXRpb25Db250ZXh0ID0gdGhpcy5jcmVhdGVFeGVjdXRpb25Db250ZXh0KFxuICAgICAgICAgICAgICAgIEV4ZWN1dGlvbkNvbnRleHRUeXBlLlJQQyxcbiAgICAgICAgICAgICAgICBjb250cm9sbGVyLm1ldGFkYXRhLmNsYXNzUmVmLFxuICAgICAgICAgICAgICAgIGNvbnRyb2xsZXIubWV0YWRhdGEuY2xhc3NSZWYucHJvdG90eXBlW3JwYy5tZXRob2RdLFxuICAgICAgICAgICAgICAgIHJlcXVlc3QsXG4gICAgICAgICAgICAgICAgcmVzcG9uc2UsXG4gICAgICAgICAgICAgICAgcnBjLm5hbWUsXG4gICAgICAgICAgICApO1xuXG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMucGlwZWxpbmVIYW5kbGVyLmdvVHJvdWdoR3VhcmRzKGV4ZWN1dGlvbkNvbnRleHQsIGd1YXJkcywgY29udHJvbGxlci5vd25lci5jb250YWluZXIpO1xuICAgICAgICAgICAgICAgIGNvbnN0IGFyZ3MgPSBhd2FpdCB0aGlzLmNvbnRyb2xsZXJGbG93SGFuZGxlci5jcmVhdGVBcmdzKGNvbnRyb2xsZXIsIGV4ZWN1dGlvbkNvbnRleHQsIHJwYywgcGlwZXMsIHBsYXllcik7XG4gICAgICAgICAgICAgICAgY29uc3QgY29udHJvbGxlck1ldGhvZCA9IGNvbnRyb2xsZXIuaW5zdGFuY2VbcnBjLm1ldGhvZF0hO1xuICAgICAgICAgICAgICAgIGNvbnN0IGhhbmRsZSA9IGlzQXN5bmNGdW5jdGlvbihjb250cm9sbGVyTWV0aG9kKVxuICAgICAgICAgICAgICAgICAgICA/IChvcHRpb25zOiB7IHNlbmQ6IGJvb2xlYW4gfSA9IHsgc2VuZDogdHJ1ZSB9KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGNvbnRyb2xsZXIuaW5zdGFuY2VbcnBjLm1ldGhvZF0hLmFwcGx5KGNvbnRyb2xsZXIuaW5zdGFuY2UsIGFyZ3MpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAob3B0aW9ucy5zZW5kKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNwb25zZS5zZW5kKHJlc3VsdCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIDogYXN5bmMgKG9wdGlvbnM6IHsgc2VuZDogYm9vbGVhbiB9ID0geyBzZW5kOiB0cnVlIH0pID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgY29udHJvbGxlci5pbnN0YW5jZVtycGMubWV0aG9kXSEuYXBwbHkoY29udHJvbGxlci5pbnN0YW5jZSwgYXJncyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChvcHRpb25zLnNlbmQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3BvbnNlLnNlbmQocmVzdWx0KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgY29uc3QgY2FsbEhhbmRsZXI6IENhbGxIYW5kbGVyID0ge1xuICAgICAgICAgICAgICAgICAgICBoYW5kbGUsXG4gICAgICAgICAgICAgICAgICAgIHJldHVybjogKHZhbHVlOiB1bmtub3duKSA9PiByZXNwb25zZS5zZW5kKHZhbHVlKSxcbiAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgICAgaWYgKGludGVyY2VwdG9ycy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMucGlwZWxpbmVIYW5kbGVyLmdvVGhyb3VnaEludGVyY2VwdG9ycyhcbiAgICAgICAgICAgICAgICAgICAgICAgIGV4ZWN1dGlvbkNvbnRleHQsXG4gICAgICAgICAgICAgICAgICAgICAgICBpbnRlcmNlcHRvcnMsXG4gICAgICAgICAgICAgICAgICAgICAgICBjb250cm9sbGVyLm93bmVyLmNvbnRhaW5lcixcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxIYW5kbGVyLFxuICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGF3YWl0IGNhbGxIYW5kbGVyLmhhbmRsZSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgZXJyb3JHcm91cCA9IG1hcHBlZEVycm9yRmlsdGVycy5maW5kKFxuICAgICAgICAgICAgICAgICAgICAoW2Vycm9yVHlwZV0pID0+XG4gICAgICAgICAgICAgICAgICAgICAgICAoaXNGdW5jdGlvbihlcnJvclR5cGUpICYmIGVycm9yIGluc3RhbmNlb2YgZXJyb3JUeXBlKSB8fCBlcnJvclR5cGUgPT09ICdNQU5HT19BTllfRVJST1InIHx8IGVycm9yID09PSBlcnJvclR5cGUsXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICBpZiAoaXNOaWwoZXJyb3JHcm91cCkpIHJldHVybjtcbiAgICAgICAgICAgICAgICBjb25zdCBpbnN0YW5jZSA9IGlzRnVuY3Rpb24oZXJyb3JHcm91cFsxXSlcbiAgICAgICAgICAgICAgICAgICAgPyBjb250cm9sbGVyLm93bmVyLmNvbnRhaW5lci5nZXQoZXJyb3JHcm91cFsxXSlcbiAgICAgICAgICAgICAgICAgICAgOiBpc09iamVjdChlcnJvckdyb3VwWzFdKSAmJiBpc0Z1bmN0aW9uKGVycm9yR3JvdXBbMV1bJ2NhdGNoJ10pXG4gICAgICAgICAgICAgICAgICAgICAgPyBlcnJvckdyb3VwWzFdXG4gICAgICAgICAgICAgICAgICAgICAgOiBudWxsO1xuICAgICAgICAgICAgICAgIGlmIChpc05pbChpbnN0YW5jZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMubG9nZ2VyU2VydmljZS5lcnJvcihFcnJvck1lc3NhZ2UuSW52YWxpZEVycm9yRmlsdGVyRGVmaW5pdGlvbik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGF3YWl0IFByb21pc2UucmVzb2x2ZShpbnN0YW5jZS5jYXRjaC5jYWxsKGluc3RhbmNlLCBlcnJvciwgZXhlY3V0aW9uQ29udGV4dCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG59XG4iLCAiaW1wb3J0IHsgaW5qZWN0YWJsZSB9IGZyb20gJ2ludmVyc2lmeSc7XG5pbXBvcnQgdHlwZSB7IENvbnRyb2xsZXJNZXRhZGF0YSwgU2NyaXB0RXZlbnRIYW5kbGVyIH0gZnJvbSAnLi4vaW50ZXJmYWNlcyc7XG5pbXBvcnQgdHlwZSB7IE1vZHVsZSB9IGZyb20gJy4uL21vZHVsZSc7XG5pbXBvcnQgdHlwZSB7IFNjcmlwdFJQQ0hhbmRsZXIgfSBmcm9tICcuLi8uLi9pbnRlcmZhY2VzJztcblxuQGluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIENvbnRyb2xsZXIge1xuICAgIHB1YmxpYyBtZXRhZGF0YTogQ29udHJvbGxlck1ldGFkYXRhO1xuICAgIHB1YmxpYyBpbnN0YW5jZTogeyBba2V5OiBzdHJpbmddOiBGdW5jdGlvbiB9O1xuICAgIHB1YmxpYyBvd25lcjogTW9kdWxlO1xuICAgIHB1YmxpYyBldmVudEhhbmRsZXJzOiBTY3JpcHRFdmVudEhhbmRsZXJbXSA9IFtdO1xuICAgIHB1YmxpYyBycGNIYW5kbGVyczogU2NyaXB0UlBDSGFuZGxlcltdID0gW107XG59XG4iXSwKICAibWFwcGluZ3MiOiAiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLFNBQVNBLFVBQUFBLFNBQVFDLGNBQUFBLG1CQUFrQjs7O0FDQW5DLFNBQVNDLFFBQVFDLGtCQUFrQjs7Ozs7Ozs7Ozs7O0FBWTVCLElBQU1DLGtCQUFOLE1BQU1BO1NBQUFBOzs7RUFDZ0NDOztFQUd6QyxNQUFhQyxlQUFlQyxrQkFBd0NDLFFBQW9DQyxXQUE0QjtBQUNoSSxlQUFXQyxTQUFTRixRQUFRO0FBQ3hCLFlBQU1HLFdBQVdDLFdBQVdGLEtBQUFBLElBQVNELFVBQVVJLElBQUlILEtBQUFBLElB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Ozs7Ozs7QUFNcEIsSUFBTUMsYUFBTixNQUFNQTtTQUFBQTs7O0VBQ0ZDO0VBQ0FDO0VBQ0FDO0VBQ0FDLGdCQUFzQyxDQUFBO0VBQ3RDQyxjQUFrQyxDQUFBO0FBQzdDOzs7OyIsCiAgIm5hbWVzIjogWyJpbmplY3QiLCAiaW5qZWN0YWJsZSIsICJpbmplY3QiLCAiaW5qZWN0YWJsZSIsICJQaXBlbGluZUhhbmRsZXIiLCAibG9nZ2VyU2VydmljZSIsICJnb1Ryb3VnaEd1YXJkcyIsICJleGVjdXRpb25Db250ZXh0IiwgImd1YXJkcyIsICJjb250YWluZXIiLCAiZ3VhcmQiLCAiaW5zdGFuY2UiLCAiaXNGdW5jdGlvbiIsICJnZXQiLCAiaXNPYmplY3QiLCAiaXNOaWwiLCAiZXJyb3IiLCAiRXJyb3IiLCAiRXJyb3JNZXNzYWdlIiwgIkludmFsaWRHdWFyZERlZmluaXRpb24iLCAiY2FuQWN0aXZhdGUiLCAiY2FsbCIsICJHdWFyZEludmFsaWRSZXR1cm5FcnJvciIsICJHdWFyZENhbmNlbEVycm9yIiwgImdvVGhyb3VnaEludGVyY2VwdG9ycyIsICJpbnRlcmNlcHRvcnMiLCAiY2FsbEhhbmRsZXIiLCAiaW50ZXJjZXB0b3IiLCAiSW52YWxpZEludGVyY2VwdG9yRGVmaW5pdGlvbiIsICJpbnRlcmNlcHQiLCAiZ29Ucm91Z2hQaXBlcyIsICJ2YWx1ZSIsICJwaXBlcyIsICJhcmd1bWVudE1ldGFkYXRhIiwgInBpcGUiLCAiSW52YWxpZFBpcGVEZWZpbml0aW9uIiwgIlByb21pc2UiLCAicmVzb2x2ZSIsICJ0cmFuc2Zvcm0iLCAiaW5qZWN0IiwgImluamVjdGFibGUiLCAiQ29udHJvbGxlckZsb3dIYW5kbGVyIiwgImFwcEVudiIsICJwaXBlbGluZUhhbmRsZXIiLCAiY3JlYXRlQXJncyIsICJjb250cm9sbGVyIiwgImV4ZWN1dGlvbkNvbnRleHQiLCAibWV0YWRhdGEiLCAicGlwZXMiLCAicGxheWVyIiwgIlByb21pc2UiLCAiYWxsIiwgInBhcmFtcyIsICJtYXAiLCAicGFyYW0iLCAiYXJndW1lbnRNZXRhZGF0YSIsICJ0eXBlIiwgImRhdGEiLCAibWV0YXR5cGUiLCAiZ29Ucm91Z2hQaXBlcyIsICJyZXF1ZXN0IiwgImJvZHkiLCAib3duZXIiLCAiY29udGFpbmVyIiwgImlzT2JqZWN0IiwgInVuZGVmaW5lZCIsICJBcnJheSIsICJpc0FycmF5IiwgImZhY3RvcnkiLCAiQXBwRW52aXJvbWVudCIsICJTZXJ2ZXIiLCAiQ29udHJvbGxlckV2ZW50SGFuZGxlciIsICJhcHBFbnYiLCAibXVsdGlwbGF5ZXJTZXJ2aWNlIiwgImV2ZW50U2VydmljZSIsICJjb250cm9sbGVyRmxvd0hhbmRsZXIiLCAicGlwZWxpbmVIYW5kbGVyIiwgImxvZ2dlclNlcnZpY2UiLCAiY3JlYXRlTWFuZ29SZXF1ZXN0IiwgImNyZWF0ZUV4ZWN1dGlvbkNvbnRleHQiLCAicmVnaXN0ZXJFdmVudCIsICJndWFyZHMiLCAiaW50ZXJjZXB0b3JzIiwgInBpcGVzIiwgIm1hcHBlZEVycm9yRmlsdGVycyIsICJjb250cm9sbGVyIiwgImV2ZW50IiwgInR5cGUiLCAibmFtZSIsICJib2R5IiwgImhhbmRsZUV2ZW50IiwgImFyZ3MiLCAicGxheWVyIiwgInBhcnNlSW50ZXJuYWxBcmdzIiwgIndlYlZpZXdJZCIsICJBcHBFbnZpcm9tZW50IiwgIlNlcnZlciIsICJ1bmRlZmluZWQiLCAiZXJyb3IiLCAiRXJyb3IiLCAiRXJyb3JNZXNzYWdlIiwgIkludmFsaWRFdmVudFR5cGUiLCAicmVxdWVzdCIsICJleGVjdXRpb25Db250ZXh0IiwgIkV4ZWN1dGlvbkNvbnRleHRUeXBlIiwgIkV2ZW50IiwgIm1ldGFkYXRhIiwgImNsYXNzUmVmIiwgInByb3RvdHlwZSIsICJtZXRob2QiLCAiZ29Ucm91Z2hHdWFyZHMiLCAib3duZXIiLCAiY29udGFpbmVyIiwgImNyZWF0ZUFyZ3MiLCAiY29udHJvbGxlck1ldGhvZCIsICJpbnN0YW5jZSIsICJoYW5kbGUiLCAiaXNBc3luY0Z1bmN0aW9uIiwgImFwcGx5IiwgImNhbGxIYW5kbGVyIiwgInJldHVybiIsICJJbnZhbGlkUmV0dXJuSW5FdmVudCIsICJsZW5ndGgiLCAiZ29UaHJvdWdoSW50ZXJjZXB0b3JzIiwgImVycm9yR3JvdXAiLCAiZmluZCIsICJlcnJvclR5cGUiLCAiaXNGdW5jdGlvbiIsICJpc05pbCIsICJnZXQiLCAiaXNPYmplY3QiLCAiSW52YWxpZEVycm9yRmlsdGVyRGVmaW5pdGlvbiIsICJQcm9taXNlIiwgInJlc29sdmUiLCAiY2F0Y2giLCAiY2FsbCIsICJpbmplY3QiLCAiaW5qZWN0YWJsZSIsICJDb250cm9sbGVyTWV0YWRhdGFSZWFkZXIiLCAiYXBwRW52IiwgImxvZ2dlclNlcnZpY2UiLCAicmVhZCIsICJjbGFzc1JlZiIsICJvcHRpb25zIiwgIlJlZmxlY3QiLCAiZ2V0TWV0YWRhdGEiLCAiQ29yZU1ldGFkYXRhS2V5IiwgIkNvbnRyb2xsZXIiLCAiZXZlbnRzIiwgImdldEV2ZW50cyIsICJycGNzIiwgImdldFJQQ3MiLCAidGltZXJzIiwgImdldFRpbWVycyIsICJnZXRQaXBlbGluZSIsICJDb250cm9sbGVyRXZlbnRzIiwgInByb3RvdHlwZSIsICJtYXAiLCAiZXZlbnQiLCAicGFyYW1zIiwgImdldE1ldGhvZFBhcmFtcyIsICJtZXRob2QiLCAiQ29udHJvbGxlclJQQ3MiLCAicnBjIiwgIm1ldGFkYXRhIiwgIkNvbnRyb2xsZXJQYXJhbXMiLCAic29ydCIsICJhIiwgImIiLCAiaW5kZXgiLCAiZm9yRWFjaCIsICJwYXJhbSIsICJlcnJvciIsICJFcnJvciIsICJFcnJvck1lc3NhZ2UiLCAiSW52YWxpZFBhcmFtZXRlckRlY29yYXRvclVzYWdlIiwgInR5cGUiLCAiUmVzcG9uc2VEZWNvcmF0b3JOb3RBbGxvd2VkT25FdmVudHMiLCAiQXBwRW52aXJvbWVudCIsICJDbGllbnQiLCAiUGxheWVyRGVjb3JhdG9yTm90QWxsb3dlZE9uQ2xpZW50RXZlbnRzIiwgIlJQQ05vdEFsbG93ZWRJbkNsaWVudCIsICJTZXJ2ZXIiLCAiUlBDTm90QWxsb3dlZEluU2VydmVyIiwgIkV2ZW50Tm90QWxsb3dlZEluQ2xpZW50IiwgIkV2ZW50Tm90QWxsb3dlZEluU2VydmVyIiwgInRhcmdldCIsICJndWFyZHMiLCAiR3VhcmRzIiwgImludGVyY2VwdG9ycyIsICJJbnRlcmNlcHRvcnMiLCAicGlwZXMiLCAiUGlwZXMiLCAiZXJyb3JGaWx0ZXJzIiwgIkVycm9yRmlsdGVycyIsICJUaW1lcnMiLCAiaW5qZWN0IiwgImluamVjdGFibGUiLCAiQ29udHJvbGxlclJQQ0hhbmRsZXIiLCAiYXBwRW52IiwgInJwY1NlcnZpY2UiLCAicGlwZWxpbmVIYW5kbGVyIiwgImNvbnRyb2xsZXJGbG93SGFuZGxlciIsICJsb2dnZXJTZXJ2aWNlIiwgImNyZWF0ZU1hbmdvUmVxdWVzdCIsICJjcmVhdGVNYW5nb1Jlc3BvbnNlIiwgImNyZWF0ZUV4ZWN1dGlvbkNvbnRleHQiLCAicmVnaXN0ZXJSUEMiLCAiZ3VhcmRzIiwgImludGVyY2VwdG9ycyIsICJwaXBlcyIsICJtYXBwZWRFcnJvckZpbHRlcnMiLCAiY29udHJvbGxlciIsICJycGMiLCAidHlwZSIsICJuYW1lIiwgImJvZHkiLCAiaGFuZGxlUlBDIiwgInBsYXllciIsICJ3ZWJWaWV3SWQiLCAiYXJncyIsICJBcHBFbnZpcm9tZW50IiwgIlNlcnZlciIsICJ1bmRlZmluZWQiLCAiZXJyb3IiLCAiRXJyb3IiLCAiRXJyb3JNZXNzYWdlIiwgIkludmFsaWRSUENUeXBlIiwgIlByb21pc2UiLCAicmVzb2x2ZSIsICJyZXF1ZXN0IiwgInJlc3BvbnNlIiwgIiRvblNlbmQiLCAiZGF0YSIsICIkb25FcnJvciIsICJleGVjdXRpb25Db250ZXh0IiwgIkV4ZWN1dGlvbkNvbnRleHRUeXBlIiwgIlJQQyIsICJtZXRhZGF0YSIsICJjbGFzc1JlZiIsICJwcm90b3R5cGUiLCAibWV0aG9kIiwgImdvVHJvdWdoR3VhcmRzIiwgIm93bmVyIiwgImNvbnRhaW5lciIsICJjcmVhdGVBcmdzIiwgImNvbnRyb2xsZXJNZXRob2QiLCAiaW5zdGFuY2UiLCAiaGFuZGxlIiwgImlzQXN5bmNGdW5jdGlvbiIsICJvcHRpb25zIiwgInNlbmQiLCAicmVzdWx0IiwgImFwcGx5IiwgImNhbGxIYW5kbGVyIiwgInJldHVybiIsICJ2YWx1ZSIsICJsZW5ndGgiLCAiZ29UaHJvdWdoSW50ZXJjZXB0b3JzIiwgImVycm9yR3JvdXAiLCAiZmluZCIsICJlcnJvclR5cGUiLCAiaXNGdW5jdGlvbiIsICJpc05pbCIsICJnZXQiLCAiaXNPYmplY3QiLCAiSW52YWxpZEVycm9yRmlsdGVyRGVmaW5pdGlvbiIsICJjYXRjaCIsICJjYWxsIiwgImluamVjdGFibGUiLCAiQ29udHJvbGxlciIsICJtZXRhZGF0YSIsICJpbnN0YW5jZSIsICJvd25lciIsICJldmVudEhhbmRsZXJzIiwgInJwY0hhbmRsZXJzIl0KfQo=