@ragemp-mango/webview 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.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Aurėjus Remeika
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,20 @@
1
+ ## Mango Framework
2
+
3
+ A simple, lightweight, and powerful TypeScript framework for building RageMP servers.
4
+
5
+ ## Features
6
+
7
+ - Mango Framework is built with TypeScript and provides a powerful type system for your application.
8
+ - Mango Framework has a wide range of decorators that allow you to easily create and manage your resource flow.
9
+ - Mango Framework is built with modularity in mind, allowing you to organize your application into small, reusable pieces.
10
+ - Mango Framework uses InversifyJS under the hood to provide a powerful dependency injection for your application.
11
+ - Mango Framework uses controllers to group and listen to events/rpcs together under a single class.
12
+ - Mango Framework uses Guards, Interceptors, and Error Filters to create a powerful pipeline that allows you to easily manage every incoming event/rpc.
13
+
14
+ ## Documentation
15
+
16
+ [Documentation](https://ragemp-mango.vercel.app)
17
+
18
+ ## License
19
+
20
+ [MIT](https://choosealicense.com/licenses/mit/)
@@ -0,0 +1,72 @@
1
+ import { RPCCallOptions, RPCResult, ScriptRPCHandler, LoggerService } from '@ragemp-mango/core/interfaces';
2
+
3
+ interface ScriptEventHandler {
4
+ destroy(): void;
5
+ valid?: boolean;
6
+ }
7
+
8
+ interface EventService {
9
+ on<E extends keyof MangoEvents.CustomWebViewEvent>(eventName: E, callback: (body: Parameters<MangoEvents.CustomWebViewEvent[E]>[0]) => void | Promise<void>): ScriptEventHandler;
10
+ on<E extends string>(eventName: Exclude<E, keyof MangoEvents.CustomWebViewEvent>, callback: (body: unknown) => void | Promise<void>): ScriptEventHandler;
11
+ once<E extends keyof MangoEvents.CustomWebViewEvent>(eventName: E, callback: (body: Parameters<MangoEvents.CustomWebViewEvent[E]>[0]) => void | Promise<void>): ScriptEventHandler;
12
+ once<E extends string>(eventName: Exclude<E, keyof MangoEvents.CustomWebViewEvent>, callback: (body: unknown) => void | Promise<void>): ScriptEventHandler;
13
+ emit<E extends keyof MangoEvents.CustomWebViewEvent>(eventName: E, body?: Parameters<MangoEvents.CustomWebViewEvent[E]>[0]): void;
14
+ emit<E extends string>(eventName: Exclude<E, keyof MangoEvents.CustomWebViewEvent>, body?: unknown): void;
15
+ onPlayer<E extends keyof MangoEvents.CustomClientToWebViewEvent>(eventName: E, callback: (body: Parameters<MangoEvents.CustomClientToWebViewEvent[E]>[0]) => void | Promise<void>): ScriptEventHandler;
16
+ onPlayer<E extends string>(eventName: Exclude<E, keyof MangoEvents.CustomClientToWebViewEvent>, callback: (body: unknown) => void | Promise<void>): ScriptEventHandler;
17
+ oncePlayer<E extends keyof MangoEvents.CustomClientToWebViewEvent>(eventName: E, callback: (body: Parameters<MangoEvents.CustomClientToWebViewEvent[E]>[0]) => void | Promise<void>): ScriptEventHandler;
18
+ oncePlayer<E extends string>(eventName: Exclude<E, keyof MangoEvents.CustomClientToWebViewEvent>, callback: (body: unknown) => void | Promise<void>): ScriptEventHandler;
19
+ emitPlayer<E extends keyof MangoEvents.CustomWebViewToClientEvent>(eventName: E, body?: Parameters<MangoEvents.CustomWebViewToClientEvent[E]>[0]): void;
20
+ emitPlayer<E extends string>(eventName: Exclude<E, keyof MangoEvents.CustomWebViewToClientEvent>, body?: unknown): void;
21
+ onServer<E extends keyof MangoEvents.CustomServerToWebViewEvent>(eventName: E, callback: (body: Parameters<MangoEvents.CustomServerToWebViewEvent[E]>[0]) => void | Promise<void>): ScriptEventHandler;
22
+ onServer<E extends string>(eventName: Exclude<E, keyof MangoEvents.CustomServerToWebViewEvent>, callback: (body: unknown) => void | Promise<void>): ScriptEventHandler;
23
+ onceServer<E extends keyof MangoEvents.CustomServerToWebViewEvent>(eventName: E, callback: (body: Parameters<MangoEvents.CustomServerToWebViewEvent[E]>[0]) => void | Promise<void>): ScriptEventHandler;
24
+ onceServer<E extends string>(eventName: Exclude<E, keyof MangoEvents.CustomServerToWebViewEvent>, callback: (body: unknown) => void | Promise<void>): ScriptEventHandler;
25
+ emitServer<E extends keyof MangoEvents.CustomWebViewToServerEvent>(eventName: E, body?: Parameters<MangoEvents.CustomWebViewToServerEvent[E]>[0]): void;
26
+ emitServer<E extends string>(eventName: Exclude<E, keyof MangoEvents.CustomWebViewToServerEvent>, body?: unknown): void;
27
+ }
28
+
29
+ interface RPCService {
30
+ call<E extends keyof MangoRPC.CustomWebViewRPC>(rpcName: E, body?: Parameters<MangoRPC.CustomWebViewRPC[E]>[0], options?: RPCCallOptions): Promise<RPCResult<ReturnType<MangoRPC.CustomWebViewRPC[E]>>>;
31
+ call<E extends string>(rpcName: Exclude<E, keyof MangoRPC.CustomWebViewRPC>, body?: unknown, options?: RPCCallOptions): Promise<RPCResult>;
32
+ onRequest<E extends keyof MangoRPC.CustomWebViewRPC>(rpcName: E, handler: (body: Parameters<MangoRPC.CustomWebViewRPC[E]>[0]) => ReturnType<MangoRPC.CustomWebViewRPC[E]>): ScriptRPCHandler;
33
+ onRequest<E extends string>(rpcName: Exclude<E, keyof MangoRPC.CustomWebViewRPC>, handler: (body: unknown) => unknown | Promise<unknown>): ScriptRPCHandler;
34
+ callServer<E extends keyof MangoRPC.CustomWebViewToServerRPC>(rpcName: E, body?: Parameters<MangoRPC.CustomWebViewToServerRPC[E]>[0], options?: RPCCallOptions): Promise<RPCResult<ReturnType<MangoRPC.CustomWebViewToServerRPC[E]>>>;
35
+ callServer<E extends string>(rpcName: Exclude<E, keyof MangoRPC.CustomWebViewToServerRPC>, body?: unknown, options?: RPCCallOptions): Promise<RPCResult>;
36
+ onServerRequest<E extends keyof MangoRPC.CustomServerToWebViewRPC>(rpcName: E, handler: (body: Parameters<MangoRPC.CustomServerToWebViewRPC[E]>[0]) => ReturnType<MangoRPC.CustomServerToWebViewRPC[E]>): ScriptRPCHandler;
37
+ onServerRequest<E extends string>(rpcName: Exclude<E, keyof MangoRPC.CustomServerToWebViewRPC>, handler: (body: unknown) => unknown | Promise<unknown>): ScriptRPCHandler;
38
+ callPlayer<E extends keyof MangoRPC.CustomWebViewToClientRPC>(rpcName: E, body?: Parameters<MangoRPC.CustomWebViewToClientRPC[E]>[0], options?: RPCCallOptions): Promise<RPCResult<ReturnType<MangoRPC.CustomWebViewToClientRPC[E]>>>;
39
+ callPlayer<E extends string>(rpcName: Exclude<E, keyof MangoRPC.CustomWebViewToClientRPC>, body?: unknown, options?: RPCCallOptions): Promise<RPCResult>;
40
+ onPlayerRequest<E extends keyof MangoRPC.CustomClientToWebviewRPC>(rpcName: E, handler: (body: Parameters<MangoRPC.CustomClientToWebviewRPC[E]>[0]) => ReturnType<MangoRPC.CustomClientToWebviewRPC[E]>): ScriptRPCHandler;
41
+ onPlayerRequest<E extends string>(rpcName: Exclude<E, keyof MangoRPC.CustomClientToWebviewRPC>, handler: (body: unknown) => unknown | Promise<unknown>): ScriptRPCHandler;
42
+ }
43
+
44
+ // RageMP WebView type extensions
45
+ // These are empty placeholders - extend MangoEvents and MangoRPC namespaces in your project
46
+
47
+ declare global {
48
+ namespace MangoEvents {
49
+ // Extend these in your project
50
+ }
51
+
52
+ namespace MangoRPC {
53
+ // Extend these in your project
54
+ }
55
+ }
56
+
57
+ declare function initMango(): {
58
+ event: EventService;
59
+ rpc: RPCService;
60
+ logger: LoggerService;
61
+ };
62
+ declare global {
63
+ export interface Window {
64
+ mango: {
65
+ event: EventService;
66
+ rpc: RPCService;
67
+ logger: LoggerService;
68
+ };
69
+ }
70
+ }
71
+
72
+ export { initMango };
package/dist/index.js ADDED
@@ -0,0 +1,535 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
3
+
4
+ // src/services/webview-logger.service.ts
5
+ var WebViewLoggerService = class {
6
+ static {
7
+ __name(this, "WebViewLoggerService");
8
+ }
9
+ log(...args) {
10
+ console.log(`[\u{1F96D}WebView][Log]`, ...args);
11
+ }
12
+ error(...args) {
13
+ console.error(`[\u{1F96D}WebView][Error]`, ...args);
14
+ }
15
+ warn(...args) {
16
+ console.warn(`[\u{1F96D}WebView][Warn]`, ...args);
17
+ }
18
+ debug(...args) {
19
+ console.debug(`[\u{1F96D}WebView][Debug]`, ...args);
20
+ }
21
+ };
22
+
23
+ // src/services/webview-event.service.ts
24
+ var WebViewEventService = class {
25
+ static {
26
+ __name(this, "WebViewEventService");
27
+ }
28
+ $localHandlers = /* @__PURE__ */ new Map();
29
+ $remoteHandlers = /* @__PURE__ */ new Map();
30
+ on(eventName, callback) {
31
+ const eventHandler = {
32
+ destroy: /* @__PURE__ */ __name(() => {
33
+ eventHandler.valid = false;
34
+ const handlers = this.$localHandlers.get(eventName);
35
+ handlers?.delete(eventHandler);
36
+ }, "destroy"),
37
+ eventName,
38
+ handler: callback,
39
+ local: true,
40
+ onlyOnce: false,
41
+ remote: false,
42
+ valid: true
43
+ };
44
+ if (!this.$localHandlers.has(eventName)) {
45
+ this.$localHandlers.set(eventName, /* @__PURE__ */ new Set());
46
+ }
47
+ this.$localHandlers.get(eventName).add(eventHandler);
48
+ return eventHandler;
49
+ }
50
+ once(eventName, callback) {
51
+ const eventHandler = {
52
+ destroy: /* @__PURE__ */ __name(() => {
53
+ eventHandler.valid = false;
54
+ const handlers = this.$localHandlers.get(eventName);
55
+ handlers?.delete(eventHandler);
56
+ }, "destroy"),
57
+ eventName,
58
+ handler: callback,
59
+ local: true,
60
+ onlyOnce: true,
61
+ remote: false,
62
+ valid: true
63
+ };
64
+ if (!this.$localHandlers.has(eventName)) {
65
+ this.$localHandlers.set(eventName, /* @__PURE__ */ new Set());
66
+ }
67
+ this.$localHandlers.get(eventName).add(eventHandler);
68
+ return eventHandler;
69
+ }
70
+ emit(eventName, body) {
71
+ const listeners = this.$localHandlers.get(eventName);
72
+ listeners?.forEach((scriptEventHandler) => {
73
+ scriptEventHandler.handler(body);
74
+ if (!scriptEventHandler.onlyOnce) return;
75
+ scriptEventHandler.destroy();
76
+ });
77
+ }
78
+ onPlayer(eventName, callback) {
79
+ const wrapper = /* @__PURE__ */ __name((...args) => callback(args[0]), "wrapper");
80
+ const eventHandler = {
81
+ destroy: /* @__PURE__ */ __name(() => {
82
+ eventHandler.valid = false;
83
+ const handlers = this.$remoteHandlers.get(eventName);
84
+ handlers?.delete(eventHandler);
85
+ }, "destroy"),
86
+ eventName,
87
+ handler: wrapper,
88
+ local: false,
89
+ onlyOnce: false,
90
+ remote: true,
91
+ valid: true
92
+ };
93
+ if (typeof window.mp !== "undefined") {
94
+ window.mp.events.add(eventName, wrapper);
95
+ }
96
+ if (!this.$remoteHandlers.has(eventName)) {
97
+ this.$remoteHandlers.set(eventName, /* @__PURE__ */ new Set());
98
+ }
99
+ this.$remoteHandlers.get(eventName).add(eventHandler);
100
+ return eventHandler;
101
+ }
102
+ oncePlayer(eventName, callback) {
103
+ const wrapper = /* @__PURE__ */ __name((...args) => {
104
+ callback(args[0]);
105
+ eventHandler.destroy();
106
+ }, "wrapper");
107
+ const eventHandler = {
108
+ destroy: /* @__PURE__ */ __name(() => {
109
+ eventHandler.valid = false;
110
+ const handlers = this.$remoteHandlers.get(eventName);
111
+ handlers?.delete(eventHandler);
112
+ }, "destroy"),
113
+ eventName,
114
+ handler: wrapper,
115
+ local: false,
116
+ onlyOnce: true,
117
+ remote: true,
118
+ valid: true
119
+ };
120
+ if (typeof window.mp !== "undefined") {
121
+ window.mp.events.add(eventName, wrapper);
122
+ }
123
+ if (!this.$remoteHandlers.has(eventName)) {
124
+ this.$remoteHandlers.set(eventName, /* @__PURE__ */ new Set());
125
+ }
126
+ this.$remoteHandlers.get(eventName).add(eventHandler);
127
+ return eventHandler;
128
+ }
129
+ emitPlayer(eventName, body) {
130
+ if (typeof window.mp !== "undefined") {
131
+ window.mp.trigger(eventName, body);
132
+ }
133
+ }
134
+ onServer(eventName, callback) {
135
+ return this.onPlayer(`WEBVIEW::ON_SERVER_${eventName}`, callback);
136
+ }
137
+ onceServer(eventName, callback) {
138
+ return this.oncePlayer(`WEBVIEW::ON_SERVER_${eventName}`, callback);
139
+ }
140
+ emitServer(eventName, body) {
141
+ if (typeof window.mp !== "undefined") {
142
+ window.mp.trigger("WEBVIEW::EMIT_SERVER", {
143
+ eventName,
144
+ payload: body
145
+ });
146
+ }
147
+ }
148
+ };
149
+
150
+ // ../core/dist/chunk-DXPVUDXD.js
151
+ var ErrorMessage = /* @__PURE__ */ (function(ErrorMessage2) {
152
+ ErrorMessage2["TooManyRequests"] = "Too many requests.";
153
+ ErrorMessage2["EventNameMustBeString"] = "The event name must be a string.";
154
+ ErrorMessage2["EventNameMustBeUnique"] = "The event name must be unique.";
155
+ ErrorMessage2["EventNotAllowedInClient"] = "The event is not allowed in the client environment.";
156
+ ErrorMessage2["EventNotAllowedInServer"] = "The event is not allowed in the server environment.";
157
+ ErrorMessage2["InvalidEventType"] = "Invalid event type.";
158
+ ErrorMessage2["InvalidInternalEventName"] = "The name of the internal event is invalid.";
159
+ ErrorMessage2["InvalidReturnInEvent"] = "Cannot return a value from an event.";
160
+ ErrorMessage2["RPCNameMustBeString"] = "The RPC name must be a string.";
161
+ ErrorMessage2["RPCNameMustBeUnique"] = "The RPC name must be unique.";
162
+ ErrorMessage2["RPCNotAllowedInClient"] = "The RPC is not allowed in the client environment.";
163
+ ErrorMessage2["RPCNotAllowedInServer"] = "The RPC is not allowed in the server environment.";
164
+ ErrorMessage2["InvalidRPCType"] = "Invalid RPC type.";
165
+ ErrorMessage2["RPCHandlerAlreadyExists"] = "The RPC handler already exists. Please provide a unique name for the RPC.";
166
+ ErrorMessage2["RPCResponseAlreadySent"] = "The RPC response has already been sent.";
167
+ ErrorMessage2["InvalidErrorFilterDefinition"] = "Invalid error filter. Error filters must be a class reference or an object with a catch method.";
168
+ ErrorMessage2["ErrorAlreadyHandledByFilter"] = "The error already points to a filter.";
169
+ ErrorMessage2["ExceptionHandlingConflict"] = "The same exception can only be caught once.";
170
+ ErrorMessage2["AtLeastOneFilterRequired"] = "At least one error filter must be provided.";
171
+ ErrorMessage2["DuplicateErrorFilterDetected"] = "Duplicate error filter found. Ensure that the same filter is not applied more than once.";
172
+ ErrorMessage2["WebViewNotFound"] = "The WebView with the specified id does not exist.";
173
+ ErrorMessage2["WebViewIdMustBeStringOrNumber"] = "The WebView id must be a string or number.";
174
+ ErrorMessage2["InvalidGuardDefinition"] = "Invalid guard. Guards must be a class reference or an object with a canActivate method.";
175
+ ErrorMessage2["AtLeastOneGuardRequired"] = "At least one guard must be provided.";
176
+ ErrorMessage2["InvalidInterceptorDefinition"] = "Invalid interceptor. Interceptors must be a class reference or an object with an intercept method.";
177
+ ErrorMessage2["AtLeastOneInterceptorRequired"] = "At least one interceptor must be provided.";
178
+ ErrorMessage2["InvalidInterceptorReturnValue"] = "The interceptor must return a function.";
179
+ ErrorMessage2["InvalidPipeDefinition"] = "Invalid pipe. Pipes must be a class reference or an object with a transform method.";
180
+ ErrorMessage2["AtLeastOnePipeRequired"] = "At least one pipe must be provided.";
181
+ ErrorMessage2["AppAlreadyLoaded"] = "App is already loaded. Please call the stop method before calling the start method.";
182
+ ErrorMessage2["AppNotLoaded"] = "App is not loaded. Please call the start method before calling the stop method.";
183
+ ErrorMessage2["InvalidInjectionTokenSpecified"] = "The specified injection token is invalid.";
184
+ ErrorMessage2["InjectionTokenNotFound"] = "The injection token could not be found.";
185
+ ErrorMessage2["ParamKeyMustBeString"] = "The param key must be a string.";
186
+ ErrorMessage2["IndexKeyMustBeNumber"] = "The index key must be a number.";
187
+ ErrorMessage2["DuplicateDecoratorUsage"] = "The same decorator can only be used once in the same class.";
188
+ ErrorMessage2["InvalidControllerOptions"] = "Invalid controller options found.";
189
+ ErrorMessage2["InvalidInjectableOptions"] = "Invalid injectable options found.";
190
+ ErrorMessage2["InvalidModuleOptions"] = "Invalid module options found.";
191
+ ErrorMessage2["MultipleDecoratorsOnSingleParameterNotAllowed"] = "Cannot apply multiple decorators to the same parameter.";
192
+ ErrorMessage2["CircularDependencyDetected"] = "Circular dependency detected.";
193
+ ErrorMessage2["InvalidModuleDefinition"] = "The module is invalid.";
194
+ ErrorMessage2["InvalidExportDefinition"] = "The export is invalid.";
195
+ ErrorMessage2["InvalidProviderDefinition"] = "The provider is invalid.";
196
+ ErrorMessage2["InvalidParameterDecoratorUsage"] = "Each parameter must have their its own decorator.";
197
+ ErrorMessage2["ResponseDecoratorNotAllowedOnEvents"] = "The @Response() decorator is not allowed on events.";
198
+ ErrorMessage2["PlayerDecoratorNotAllowedOnClientEvents"] = "The @Player() decorator is not allowed on client events.";
199
+ ErrorMessage2["TimerNameMustBeString"] = "The timer name must be a string.";
200
+ return ErrorMessage2;
201
+ })({});
202
+ var RPCResultStatus = /* @__PURE__ */ (function(RPCResultStatus2) {
203
+ RPCResultStatus2[RPCResultStatus2["Success"] = 1] = "Success";
204
+ RPCResultStatus2[RPCResultStatus2["Timeout"] = 2] = "Timeout";
205
+ RPCResultStatus2[RPCResultStatus2["HandlerNotFound"] = 3] = "HandlerNotFound";
206
+ RPCResultStatus2[RPCResultStatus2["Unknown"] = 4] = "Unknown";
207
+ RPCResultStatus2[RPCResultStatus2["CancelledByGuard"] = 5] = "CancelledByGuard";
208
+ RPCResultStatus2[RPCResultStatus2["InvalidGuardReturn"] = 6] = "InvalidGuardReturn";
209
+ RPCResultStatus2[RPCResultStatus2["TooManyRequests"] = 7] = "TooManyRequests";
210
+ RPCResultStatus2[RPCResultStatus2["PlayerDisconnected"] = 8] = "PlayerDisconnected";
211
+ RPCResultStatus2[RPCResultStatus2["PlayerNotFound"] = 9] = "PlayerNotFound";
212
+ return RPCResultStatus2;
213
+ })({});
214
+
215
+ // ../core/dist/chunk-HK7QTFPA.js
216
+ var RPC_RESULT_TIMEOUT = {
217
+ success: false,
218
+ error: {
219
+ message: "RPC call timed out."
220
+ },
221
+ status: RPCResultStatus.Timeout
222
+ };
223
+ var RPC_RESULT_HANDLER_NOT_FOUND = {
224
+ success: false,
225
+ error: {
226
+ message: "RPC handler not found."
227
+ },
228
+ status: RPCResultStatus.HandlerNotFound
229
+ };
230
+ var RPC_RESULT_UNKNOWN = {
231
+ success: false,
232
+ error: {
233
+ message: "Unknown error."
234
+ },
235
+ status: RPCResultStatus.Unknown
236
+ };
237
+ var RPC_RESULT_PLAYER_DISCONNECTED = {
238
+ success: false,
239
+ error: {
240
+ message: "Player disconnected."
241
+ },
242
+ status: RPCResultStatus.PlayerDisconnected
243
+ };
244
+ var RPC_RESULT_PLAYER_NOT_FOUND = {
245
+ success: false,
246
+ error: {
247
+ message: "Player not found."
248
+ },
249
+ status: RPCResultStatus.PlayerNotFound
250
+ };
251
+
252
+ // ../core/dist/chunk-7QVYU63E.js
253
+ var __defProp2 = Object.defineProperty;
254
+ var __name2 = /* @__PURE__ */ __name((target, value) => __defProp2(target, "name", {
255
+ value,
256
+ configurable: true
257
+ }), "__name");
258
+
259
+ // ../core/dist/chunk-E6IQL4S6.js
260
+ function generateRandomId() {
261
+ return Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);
262
+ }
263
+ __name(generateRandomId, "generateRandomId");
264
+ __name2(generateRandomId, "generateRandomId");
265
+ var isUndefined = /* @__PURE__ */ __name2((obj) => typeof obj === "undefined", "isUndefined");
266
+ var isNil = /* @__PURE__ */ __name2((val) => isUndefined(val) || val === null, "isNil");
267
+
268
+ // ../core/dist/chunk-TBWHLT75.js
269
+ var EventDestination = /* @__PURE__ */ (function(EventDestination2) {
270
+ EventDestination2["Server"] = "server";
271
+ EventDestination2["Client"] = "client";
272
+ EventDestination2["WebView"] = "webview";
273
+ return EventDestination2;
274
+ })({});
275
+
276
+ // src/services/webview-rpc.service.ts
277
+ var WebViewRPCService = class {
278
+ static {
279
+ __name(this, "WebViewRPCService");
280
+ }
281
+ $eventService;
282
+ $loggerService;
283
+ $TIMEOUT = 2e3;
284
+ $localHandlers = /* @__PURE__ */ new Map();
285
+ $clientHandlers = /* @__PURE__ */ new Map();
286
+ $serverHandlers = /* @__PURE__ */ new Map();
287
+ constructor($eventService, $loggerService) {
288
+ this.$eventService = $eventService;
289
+ this.$loggerService = $loggerService;
290
+ }
291
+ async call(rpcName, body, options = {
292
+ timeout: this.$TIMEOUT
293
+ }) {
294
+ return new Promise(async (resolve) => {
295
+ const rpcHandler = this.$localHandlers.get(rpcName);
296
+ if (isNil(rpcHandler)) {
297
+ resolve(RPC_RESULT_HANDLER_NOT_FOUND);
298
+ return;
299
+ }
300
+ const timeoutId = setTimeout(() => {
301
+ resolve(RPC_RESULT_TIMEOUT);
302
+ }, options.timeout);
303
+ const result = await rpcHandler.handler(body);
304
+ clearTimeout(timeoutId);
305
+ resolve({
306
+ success: true,
307
+ status: RPCResultStatus.Success,
308
+ body: result,
309
+ error: void 0
310
+ });
311
+ });
312
+ }
313
+ onRequest(rpcName, handler) {
314
+ if (this.$localHandlers.has(rpcName)) {
315
+ this.$loggerService.error("An error occurred while registering a RPC handler.");
316
+ throw new Error(ErrorMessage.RPCHandlerAlreadyExists);
317
+ }
318
+ const rpcHandler = {
319
+ destroy: /* @__PURE__ */ __name(() => {
320
+ rpcHandler.valid = false;
321
+ this.$localHandlers.delete(rpcName);
322
+ }, "destroy"),
323
+ rpcName,
324
+ handler,
325
+ valid: true
326
+ };
327
+ this.$localHandlers.set(rpcName, rpcHandler);
328
+ return rpcHandler;
329
+ }
330
+ callServer(rpcName, body, options = {
331
+ timeout: this.$TIMEOUT
332
+ }) {
333
+ return this.$handleCall(rpcName, EventDestination.Server, options, body);
334
+ }
335
+ onServerRequest(rpcName, handler) {
336
+ if (this.$serverHandlers.has(rpcName)) {
337
+ this.$loggerService.error("An error occurred while registering a RPC handler.");
338
+ throw new Error(ErrorMessage.RPCHandlerAlreadyExists);
339
+ }
340
+ const rpcHandler = {
341
+ destroy: /* @__PURE__ */ __name(() => {
342
+ rpcHandler.valid = false;
343
+ this.$serverHandlers.delete(rpcName);
344
+ }, "destroy"),
345
+ rpcName,
346
+ handler,
347
+ valid: true
348
+ };
349
+ this.$serverHandlers.set(rpcName, rpcHandler);
350
+ return rpcHandler;
351
+ }
352
+ callPlayer(rpcName, body, options = {
353
+ timeout: this.$TIMEOUT
354
+ }) {
355
+ return this.$handleCall(rpcName, EventDestination.Client, options, body);
356
+ }
357
+ onPlayerRequest(rpcName, handler) {
358
+ if (this.$clientHandlers.has(rpcName)) {
359
+ this.$loggerService.error("An error occurred while registering a RPC listener.");
360
+ throw new Error(ErrorMessage.RPCHandlerAlreadyExists);
361
+ }
362
+ const rpcHandler = {
363
+ destroy: /* @__PURE__ */ __name(() => {
364
+ rpcHandler.valid = false;
365
+ this.$clientHandlers.delete(rpcName);
366
+ }, "destroy"),
367
+ rpcName,
368
+ handler,
369
+ valid: true
370
+ };
371
+ this.$clientHandlers.set(rpcName, rpcHandler);
372
+ return rpcHandler;
373
+ }
374
+ async $handleCall(rpcName, destination, options, body) {
375
+ return new Promise((resolve) => {
376
+ const callId = generateRandomId();
377
+ let timeoutId;
378
+ const onceHandle = /* @__PURE__ */ __name((body2) => {
379
+ clearTimeout(timeoutId);
380
+ resolve(body2);
381
+ }, "onceHandle");
382
+ const scriptEventHandler = destination === EventDestination.Server ? this.$eventService.onceServer(`RPC::RETURN_FROM_SERVER_${callId}`, onceHandle) : this.$eventService.oncePlayer(`RPC::RETURN_FROM_CLIENT_${callId}`, onceHandle);
383
+ const payload = {
384
+ source: EventDestination.WebView,
385
+ destination,
386
+ id: callId,
387
+ rpcName,
388
+ body
389
+ };
390
+ destination === EventDestination.Server ? this.$eventService.emitPlayer("RPC::CALL_SERVER", payload) : this.$eventService.emitPlayer("RPC::CALL_CLIENT", payload);
391
+ timeoutId = setTimeout(() => {
392
+ scriptEventHandler.destroy();
393
+ resolve(RPC_RESULT_TIMEOUT);
394
+ }, options?.timeout ?? this.$TIMEOUT);
395
+ });
396
+ }
397
+ };
398
+
399
+ // ../core/dist/chunk-6YEWPMZJ.js
400
+ var MangoError = class extends Error {
401
+ static {
402
+ __name(this, "MangoError");
403
+ }
404
+ static {
405
+ __name2(this, "MangoError");
406
+ }
407
+ status = RPCResultStatus.Unknown;
408
+ details;
409
+ constructor(message, status, details) {
410
+ super(message);
411
+ this.status = status ?? RPCResultStatus.Unknown;
412
+ this.details = details;
413
+ }
414
+ };
415
+ var GuardCancelError = class extends MangoError {
416
+ static {
417
+ __name(this, "GuardCancelError");
418
+ }
419
+ static {
420
+ __name2(this, "GuardCancelError");
421
+ }
422
+ constructor() {
423
+ super("Process cancelled by the guard.", RPCResultStatus.CancelledByGuard);
424
+ }
425
+ };
426
+ var GuardInvalidReturnError = class extends MangoError {
427
+ static {
428
+ __name(this, "GuardInvalidReturnError");
429
+ }
430
+ static {
431
+ __name2(this, "GuardInvalidReturnError");
432
+ }
433
+ constructor() {
434
+ super("Guard returned an invalid value. Expected boolean.", RPCResultStatus.InvalidGuardReturn);
435
+ }
436
+ };
437
+ var TooManyRequests = class extends MangoError {
438
+ static {
439
+ __name(this, "TooManyRequests");
440
+ }
441
+ static {
442
+ __name2(this, "TooManyRequests");
443
+ }
444
+ constructor(message = "Too many requests.") {
445
+ super(message, RPCResultStatus.TooManyRequests);
446
+ }
447
+ };
448
+ var UnknownError = class extends MangoError {
449
+ static {
450
+ __name(this, "UnknownError");
451
+ }
452
+ static {
453
+ __name2(this, "UnknownError");
454
+ }
455
+ constructor() {
456
+ super("Unknown error.", RPCResultStatus.Unknown);
457
+ }
458
+ };
459
+
460
+ // src/index.ts
461
+ function initMango() {
462
+ if (!isNil(window.mango)) {
463
+ return window.mango;
464
+ }
465
+ const event = new WebViewEventService();
466
+ const logger = new WebViewLoggerService();
467
+ const rpc = new WebViewRPCService(event, logger);
468
+ event.onServer("RPC::CALL_WEBVIEW", async (body) => {
469
+ const id = body.id;
470
+ const name = body.rpcName;
471
+ const payload = body.body;
472
+ const rpcHandler = rpc.$serverHandlers.get(name);
473
+ if (!rpcHandler) {
474
+ event.emitServer(`RPC::RETURN_FROM_WEBVIEW_${id}`, RPC_RESULT_HANDLER_NOT_FOUND);
475
+ return;
476
+ }
477
+ try {
478
+ const result = await rpcHandler.handler(payload);
479
+ const rpcResult = {
480
+ success: true,
481
+ status: RPCResultStatus.Success,
482
+ body: result
483
+ };
484
+ event.emitServer(`RPC::RETURN_FROM_WEBVIEW_${id}`, rpcResult);
485
+ } catch (error) {
486
+ if (error instanceof MangoError) {
487
+ const rpcResult = {
488
+ success: false,
489
+ status: error.status,
490
+ error: {
491
+ message: error.message,
492
+ details: error.details
493
+ }
494
+ };
495
+ event.emitServer(`RPC::RETURN_FROM_WEBVIEW_${id}`, rpcResult);
496
+ return;
497
+ }
498
+ event.emitServer(`RPC::RETURN_FROM_WEBVIEW_${id}`, RPC_RESULT_UNKNOWN);
499
+ }
500
+ });
501
+ event.onPlayer("RPC::CALL_WEBVIEW", async (body) => {
502
+ const id = body.id;
503
+ const name = body.rpcName;
504
+ const payload = body.body;
505
+ const rpcHandler = rpc.$clientHandlers.get(name);
506
+ if (isNil(rpcHandler)) {
507
+ event.emitPlayer(`RPC::RETURN_FROM_WEBVIEW_${id}`, RPC_RESULT_HANDLER_NOT_FOUND);
508
+ return;
509
+ }
510
+ try {
511
+ const result = await rpcHandler.handler(payload);
512
+ const rpcResult = {
513
+ success: true,
514
+ status: RPCResultStatus.Success,
515
+ body: result
516
+ };
517
+ event.emitPlayer(`RPC::RETURN_FROM_WEBVIEW_${id}`, rpcResult);
518
+ } catch (error) {
519
+ event.emitPlayer(`RPC::RETURN_FROM_WEBVIEW_${id}`, RPC_RESULT_UNKNOWN);
520
+ }
521
+ });
522
+ const mango = {
523
+ event,
524
+ rpc,
525
+ logger
526
+ };
527
+ window.mango = mango;
528
+ logger.log("WebView initialized");
529
+ return mango;
530
+ }
531
+ __name(initMango, "initMango");
532
+ export {
533
+ initMango
534
+ };
535
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vc3JjL3NlcnZpY2VzL3dlYnZpZXctbG9nZ2VyLnNlcnZpY2UudHMiLCAiLi4vc3JjL3NlcnZpY2VzL3dlYnZpZXctZXZlbnQuc2VydmljZS50cyIsICIuLi8uLi9jb3JlL3NyYy9lbnVtcy9lcnJvci1tZXNzYWdlLmVudW0udHMiLCAiLi4vLi4vY29yZS9zcmMvZW51bXMvaW5qZWN0YWJsZS1zY29wZS5lbnVtLnRzIiwgIi4uLy4uL2NvcmUvc3JjL2VudW1zL3JwYy1yZXN1bHQtc3RhdHVzLmVudW0udHMiLCAiLi4vLi4vY29yZS9zcmMvYXBwL2NvbnN0YW50cy9pbmRleC50cyIsICIuLi8uLi9jb3JlL2Rpc3QvY2h1bmstN1FWWVU2M0UuanMiLCAiLi4vLi4vY29yZS9zcmMvdXRpbHMvZ2VuZXJhdGUtcmFuZG9tLWlkLnV0aWwudHMiLCAiLi4vLi4vY29yZS9zcmMvdXRpbHMvdHlwZS1jaGVjay51dGlsLnRzIiwgIi4uLy4uL2NvcmUvc3JjL2FwcC9lbnVtcy9hcHAtZW52aXJvbWVudC5lbnVtLnRzIiwgIi4uLy4uL2NvcmUvc3JjL2FwcC9lbnVtcy9jb3JlLW1ldGFkYXRhLWtleS5lbnVtLnRzIiwgIi4uLy4uL2NvcmUvc3JjL2FwcC9lbnVtcy9ldmVudC1kZXN0aW5hdGlvbi5lbnVtLnRzIiwgIi4uLy4uL2NvcmUvc3JjL2FwcC9lbnVtcy9leGVjdXRpb24tY29udGV4dC10eXBlLmVudW0udHMiLCAiLi4vLi4vY29yZS9zcmMvYXBwL2VudW1zL21ldGhvZC1wYXJhbS10eXBlLmVudW0udHMiLCAiLi4vc3JjL3NlcnZpY2VzL3dlYnZpZXctcnBjLnNlcnZpY2UudHMiLCAiLi4vLi4vY29yZS9zcmMvZXJyb3JzL21hbmdvLmVycm9yLnRzIiwgIi4uLy4uL2NvcmUvc3JjL2Vycm9ycy9ndWFyZC1jYW5jZWwuZXJyb3IudHMiLCAiLi4vLi4vY29yZS9zcmMvZXJyb3JzL2d1YXJkLWludmFsaWQtcmV0dXJuLmVycm9yLnRzIiwgIi4uLy4uL2NvcmUvc3JjL2Vycm9ycy90b28tbWFueS1yZXF1ZXN0cy5lcnJvci50cyIsICIuLi8uLi9jb3JlL3NyYy9lcnJvcnMvdW5rbm93bi5lcnJvci50cyIsICIuLi9zcmMvaW5kZXgudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbImltcG9ydCB0eXBlIHsgTG9nZ2VyU2VydmljZSB9IGZyb20gJ0ByYWdlbXAtbWFuZ28vY29yZS9pbnRlcmZhY2VzJztcblxuZXhwb3J0IGNsYXNzIFdlYlZpZXdMb2dnZXJTZXJ2aWNlIGltcGxlbWVudHMgTG9nZ2VyU2VydmljZSB7XG4gICAgcHVibGljIGxvZyguLi5hcmdzOiB1bmtub3duW10pIHtcbiAgICAgICAgY29uc29sZS5sb2coYFvwn6WtV2ViVmlld11bTG9nXWAsIC4uLmFyZ3MpO1xuICAgIH1cblxuICAgIHB1YmxpYyBlcnJvciguLi5hcmdzOiB1bmtub3duW10pIHtcbiAgICAgICAgY29uc29sZS5lcnJvcihgW/Cfpa1XZWJWaWV3XVtFcnJvcl1gLCAuLi5hcmdzKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgd2FybiguLi5hcmdzOiB1bmtub3duW10pIHtcbiAgICAgICAgY29uc29sZS53YXJuKGBb8J+lrVdlYlZpZXddW1dhcm5dYCwgLi4uYXJncyk7XG4gICAgfVxuXG4gICAgcHVibGljIGRlYnVnKC4uLmFyZ3M6IHVua25vd25bXSkge1xuICAgICAgICBjb25zb2xlLmRlYnVnKGBb8J+lrVdlYlZpZXddW0RlYnVnXWAsIC4uLmFyZ3MpO1xuICAgIH1cbn1cbiIsICJpbXBvcnQgdHlwZSB7IEV2ZW50U2VydmljZSwgU2NyaXB0RXZlbnRIYW5kbGVyIH0gZnJvbSAnLi4vaW50ZXJmYWNlcyc7XG5cbmV4cG9ydCBjbGFzcyBXZWJWaWV3RXZlbnRTZXJ2aWNlIGltcGxlbWVudHMgRXZlbnRTZXJ2aWNlIHtcbiAgICBwcml2YXRlIHJlYWRvbmx5ICRsb2NhbEhhbmRsZXJzOiBNYXA8c3RyaW5nLCBTZXQ8U2NyaXB0RXZlbnRIYW5kbGVyPj4gPSBuZXcgTWFwKCk7XG4gICAgcHJpdmF0ZSByZWFkb25seSAkcmVtb3RlSGFuZGxlcnM6IE1hcDxzdHJpbmcsIFNldDxTY3JpcHRFdmVudEhhbmRsZXI+PiA9IG5ldyBNYXAoKTtcblxuICAgIHB1YmxpYyBvbjxFIGV4dGVuZHMgc3RyaW5nPihcbiAgICAgICAgZXZlbnROYW1lOiBFLFxuICAgICAgICBjYWxsYmFjazogKGJvZHk6IHVua25vd24pID0+IHZvaWQgfCBQcm9taXNlPHZvaWQ+LFxuICAgICkge1xuICAgICAgICBjb25zdCBldmVudEhhbmRsZXI6IFNjcmlwdEV2ZW50SGFuZGxlciA9IHtcbiAgICAgICAgICAgIGRlc3Ryb3k6ICgpID0+IHtcbiAgICAgICAgICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgICAgICAgICAgZXZlbnRIYW5kbGVyLnZhbGlkID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgY29uc3QgaGFuZGxlcnMgPSB0aGlzLiRsb2NhbEhhbmRsZXJzLmdldChldmVudE5hbWUpO1xuICAgICAgICAgICAgICAgIGhhbmRsZXJzPy5kZWxldGUoZXZlbnRIYW5kbGVyKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBldmVudE5hbWUsXG4gICAgICAgICAgICBoYW5kbGVyOiBjYWxsYmFjayxcbiAgICAgICAgICAgIGxvY2FsOiB0cnVlLFxuICAgICAgICAgICAgb25seU9uY2U6IGZhbHNlLFxuICAgICAgICAgICAgcmVtb3RlOiBmYWxzZSxcbiAgICAgICAgICAgIHZhbGlkOiB0cnVlLFxuICAgICAgICB9O1xuXG4gICAgICAgIGlmICghdGhpcy4kbG9jYWxIYW5kbGVycy5oYXMoZXZlbnROYW1lKSkge1xuICAgICAgICAgICAgdGhpcy4kbG9jYWxIYW5kbGVycy5zZXQoZXZlbnROYW1lLCBuZXcgU2V0KCkpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuJGxvY2FsSGFuZGxlcnMuZ2V0KGV2ZW50TmFtZSkhLmFkZChldmVudEhhbmRsZXIpO1xuXG4gICAgICAgIHJldHVybiBldmVudEhhbmRsZXI7XG4gICAgfVxuXG4gICAgcHVibGljIG9uY2U8RSBleHRlbmRzIHN0cmluZz4oXG4gICAgICAgIGV2ZW50TmFtZTogRSxcbiAgICAgICAgY2FsbGJhY2s6IChib2R5OiB1bmtub3duKSA9PiB2b2lkIHwgUHJvbWlzZTx2b2lkPixcbiAgICApIHtcbiAgICAgICAgY29uc3QgZXZlbnRIYW5kbGVyID0ge1xuICAgICAgICAgICAgZGVzdHJveTogKCkgPT4ge1xuICAgICAgICAgICAgICAgIGV2ZW50SGFuZGxlci52YWxpZCA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIGNvbnN0IGhhbmRsZXJzID0gdGhpcy4kbG9jYWxIYW5kbGVycy5nZXQoZXZlbnROYW1lKTtcbiAgICAgICAgICAgICAgICBoYW5kbGVycz8uZGVsZXRlKGV2ZW50SGFuZGxlcik7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZXZlbnROYW1lLFxuICAgICAgICAgICAgaGFuZGxlcjogY2FsbGJhY2ssXG4gICAgICAgICAgICBsb2NhbDogdHJ1ZSxcbiAgICAgICAgICAgIG9ubHlPbmNlOiB0cnVlLFxuICAgICAgICAgICAgcmVtb3RlOiBmYWxzZSxcbiAgICAgICAgICAgIHZhbGlkOiB0cnVlLFxuICAgICAgICB9O1xuXG4gICAgICAgIGlmICghdGhpcy4kbG9jYWxIYW5kbGVycy5oYXMoZXZlbnROYW1lKSkge1xuICAgICAgICAgICAgdGhpcy4kbG9jYWxIYW5kbGVycy5zZXQoZXZlbnROYW1lLCBuZXcgU2V0KCkpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuJGxvY2FsSGFuZGxlcnMuZ2V0KGV2ZW50TmFtZSkhLmFkZChldmVudEhhbmRsZXIpO1xuXG4gICAgICAgIHJldHVybiA8U2NyaXB0RXZlbnRIYW5kbGVyPmV2ZW50SGFuZGxlcjtcbiAgICB9XG5cbiAgICBwdWJsaWMgZW1pdDxFIGV4dGVuZHMgc3RyaW5nPihldmVudE5hbWU6IEUsIGJvZHk/OiB1bmtub3duKSB7XG4gICAgICAgIGNvbnN0IGxpc3RlbmVycyA9IHRoaXMuJGxvY2FsSGFuZGxlcnMuZ2V0KGV2ZW50TmFtZSk7XG4gICAgICAgIGxpc3RlbmVycz8uZm9yRWFjaCgoc2NyaXB0RXZlbnRIYW5kbGVyKSA9PiB7XG4gICAgICAgICAgICBzY3JpcHRFdmVudEhhbmRsZXIuaGFuZGxlcihib2R5KTtcbiAgICAgICAgICAgIGlmICghc2NyaXB0RXZlbnRIYW5kbGVyLm9ubHlPbmNlKSByZXR1cm47XG4gICAgICAgICAgICBzY3JpcHRFdmVudEhhbmRsZXIuZGVzdHJveSgpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwdWJsaWMgb25QbGF5ZXI8RSBleHRlbmRzIHN0cmluZz4oXG4gICAgICAgIGV2ZW50TmFtZTogRSxcbiAgICAgICAgY2FsbGJhY2s6IChib2R5OiB1bmtub3duKSA9PiB2b2lkIHwgUHJvbWlzZTx2b2lkPixcbiAgICApIHtcbiAgICAgICAgY29uc3Qgd3JhcHBlciA9ICguLi5hcmdzOiBhbnlbXSkgPT4gY2FsbGJhY2soYXJnc1swXSk7XG4gICAgICAgIGNvbnN0IGV2ZW50SGFuZGxlcjogU2NyaXB0RXZlbnRIYW5kbGVyID0ge1xuICAgICAgICAgICAgZGVzdHJveTogKCkgPT4ge1xuICAgICAgICAgICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgICAgICAgICBldmVudEhhbmRsZXIudmFsaWQgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICBjb25zdCBoYW5kbGVycyA9IHRoaXMuJHJlbW90ZUhhbmRsZXJzLmdldChldmVudE5hbWUpO1xuICAgICAgICAgICAgICAgIGhhbmRsZXJzPy5kZWxldGUoZXZlbnRIYW5kbGVyKTtcbiAgICAgICAgICAgICAgICAvLyBJbiBSYWdlTVAgQ0VGLCB3ZSB1c2UgbXAudHJpZ2dlciB0byBjb21tdW5pY2F0ZVxuICAgICAgICAgICAgICAgIC8vIEV2ZW50cyBhcmUgcmVnaXN0ZXJlZCB2aWEgd2luZG93IGV2ZW50IGxpc3RlbmVycyBvciBtcC5ldmVudHNcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBldmVudE5hbWUsXG4gICAgICAgICAgICBoYW5kbGVyOiB3cmFwcGVyLFxuICAgICAgICAgICAgbG9jYWw6IGZhbHNlLFxuICAgICAgICAgICAgb25seU9uY2U6IGZhbHNlLFxuICAgICAgICAgICAgcmVtb3RlOiB0cnVlLFxuICAgICAgICAgICAgdmFsaWQ6IHRydWUsXG4gICAgICAgIH07XG5cbiAgICAgICAgLy8gUmFnZU1QIENFRiB1c2VzIHdpbmRvdy1sZXZlbCBldmVudCByZWdpc3RyYXRpb25cbiAgICAgICAgaWYgKHR5cGVvZiAod2luZG93IGFzIGFueSkubXAgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICAod2luZG93IGFzIGFueSkubXAuZXZlbnRzLmFkZChldmVudE5hbWUsIHdyYXBwZXIpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCF0aGlzLiRyZW1vdGVIYW5kbGVycy5oYXMoZXZlbnROYW1lKSkge1xuICAgICAgICAgICAgdGhpcy4kcmVtb3RlSGFuZGxlcnMuc2V0KGV2ZW50TmFtZSwgbmV3IFNldCgpKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLiRyZW1vdGVIYW5kbGVycy5nZXQoZXZlbnROYW1lKSEuYWRkKGV2ZW50SGFuZGxlcik7XG5cbiAgICAgICAgcmV0dXJuIGV2ZW50SGFuZGxlcjtcbiAgICB9XG5cbiAgICBwdWJsaWMgb25jZVBsYXllcjxFIGV4dGVuZHMgc3RyaW5nPihcbiAgICAgICAgZXZlbnROYW1lOiBFLFxuICAgICAgICBjYWxsYmFjazogKGJvZHk6IHVua25vd24pID0+IHZvaWQgfCBQcm9taXNlPHZvaWQ+LFxuICAgICkge1xuICAgICAgICBjb25zdCB3cmFwcGVyID0gKC4uLmFyZ3M6IGFueVtdKSA9PiB7XG4gICAgICAgICAgICBjYWxsYmFjayhhcmdzWzBdKTtcbiAgICAgICAgICAgIGV2ZW50SGFuZGxlci5kZXN0cm95KCk7XG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IGV2ZW50SGFuZGxlcjogU2NyaXB0RXZlbnRIYW5kbGVyID0ge1xuICAgICAgICAgICAgZGVzdHJveTogKCkgPT4ge1xuICAgICAgICAgICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgICAgICAgICBldmVudEhhbmRsZXIudmFsaWQgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICBjb25zdCBoYW5kbGVycyA9IHRoaXMuJHJlbW90ZUhhbmRsZXJzLmdldChldmVudE5hbWUpO1xuICAgICAgICAgICAgICAgIGhhbmRsZXJzPy5kZWxldGUoZXZlbnRIYW5kbGVyKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBldmVudE5hbWUsXG4gICAgICAgICAgICBoYW5kbGVyOiB3cmFwcGVyLFxuICAgICAgICAgICAgbG9jYWw6IGZhbHNlLFxuICAgICAgICAgICAgb25seU9uY2U6IHRydWUsXG4gICAgICAgICAgICByZW1vdGU6IHRydWUsXG4gICAgICAgICAgICB2YWxpZDogdHJ1ZSxcbiAgICAgICAgfTtcblxuICAgICAgICBpZiAodHlwZW9mICh3aW5kb3cgYXMgYW55KS5tcCAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgICh3aW5kb3cgYXMgYW55KS5tcC5ldmVudHMuYWRkKGV2ZW50TmFtZSwgd3JhcHBlcik7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIXRoaXMuJHJlbW90ZUhhbmRsZXJzLmhhcyhldmVudE5hbWUpKSB7XG4gICAgICAgICAgICB0aGlzLiRyZW1vdGVIYW5kbGVycy5zZXQoZXZlbnROYW1lLCBuZXcgU2V0KCkpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuJHJlbW90ZUhhbmRsZXJzLmdldChldmVudE5hbWUpIS5hZGQoZXZlbnRIYW5kbGVyKTtcblxuICAgICAgICByZXR1cm4gZXZlbnRIYW5kbGVyO1xuICAgIH1cblxuICAgIHB1YmxpYyBlbWl0UGxheWVyPEUgZXh0ZW5kcyBzdHJpbmc+KGV2ZW50TmFtZTogRSwgYm9keT86IHVua25vd24pIHtcbiAgICAgICAgLy8gUmFnZU1QIENFRiB1c2VzIG1wLnRyaWdnZXIgdG8gc2VuZCBldmVudHMgdG8gY2xpZW50XG4gICAgICAgIGlmICh0eXBlb2YgKHdpbmRvdyBhcyBhbnkpLm1wICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgKHdpbmRvdyBhcyBhbnkpLm1wLnRyaWdnZXIoZXZlbnROYW1lLCBib2R5KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHB1YmxpYyBvblNlcnZlcjxFIGV4dGVuZHMgc3RyaW5nPihcbiAgICAgICAgZXZlbnROYW1lOiBFLFxuICAgICAgICBjYWxsYmFjazogKGJvZHk6IHVua25vd24pID0+IHZvaWQgfCBQcm9taXNlPHZvaWQ+LFxuICAgICkge1xuICAgICAgICByZXR1cm4gdGhpcy5vblBsYXllcig8c3RyaW5nPmBXRUJWSUVXOjpPTl9TRVJWRVJfJHtldmVudE5hbWV9YCwgPGFueT5jYWxsYmFjayk7XG4gICAgfVxuXG4gICAgcHVibGljIG9uY2VTZXJ2ZXI8RSBleHRlbmRzIHN0cmluZz4oXG4gICAgICAgIGV2ZW50TmFtZTogRSxcbiAgICAgICAgY2FsbGJhY2s6IChib2R5OiB1bmtub3duKSA9PiB2b2lkIHwgUHJvbWlzZTx2b2lkPixcbiAgICApOiBTY3JpcHRFdmVudEhhbmRsZXIge1xuICAgICAgICByZXR1cm4gdGhpcy5vbmNlUGxheWVyKDxzdHJpbmc+YFdFQlZJRVc6Ok9OX1NFUlZFUl8ke2V2ZW50TmFtZX1gLCA8YW55PmNhbGxiYWNrKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgZW1pdFNlcnZlcjxFIGV4dGVuZHMgc3RyaW5nPihldmVudE5hbWU6IEUsIGJvZHk/OiB1bmtub3duKSB7XG4gICAgICAgIC8vIEluIFJhZ2VNUCwgd2UgZW1pdCB0byBjbGllbnQgd2hpY2ggdGhlbiBmb3J3YXJkcyB0byBzZXJ2ZXJcbiAgICAgICAgaWYgKHR5cGVvZiAod2luZG93IGFzIGFueSkubXAgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICAod2luZG93IGFzIGFueSkubXAudHJpZ2dlcignV0VCVklFVzo6RU1JVF9TRVJWRVInLCB7XG4gICAgICAgICAgICAgICAgZXZlbnROYW1lLFxuICAgICAgICAgICAgICAgIHBheWxvYWQ6IGJvZHksXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cbn1cbiIsICJleHBvcnQgZW51bSBFcnJvck1lc3NhZ2Uge1xuICAgIFRvb01hbnlSZXF1ZXN0cyA9ICdUb28gbWFueSByZXF1ZXN0cy4nLFxuXG4gICAgLy8gRXZlbnRzXG4gICAgRXZlbnROYW1lTXVzdEJlU3RyaW5nID0gJ1RoZSBldmVudCBuYW1lIG11c3QgYmUgYSBzdHJpbmcuJyxcbiAgICBFdmVudE5hbWVNdXN0QmVVbmlxdWUgPSAnVGhlIGV2ZW50IG5hbWUgbXVzdCBiZSB1bmlxdWUuJyxcbiAgICBFdmVudE5vdEFsbG93ZWRJbkNsaWVudCA9ICdUaGUgZXZlbnQgaXMgbm90IGFsbG93ZWQgaW4gdGhlIGNsaWVudCBlbnZpcm9ubWVudC4nLFxuICAgIEV2ZW50Tm90QWxsb3dlZEluU2VydmVyID0gJ1RoZSBldmVudCBpcyBub3QgYWxsb3dlZCBpbiB0aGUgc2VydmVyIGVudmlyb25tZW50LicsXG4gICAgSW52YWxpZEV2ZW50VHlwZSA9ICdJbnZhbGlkIGV2ZW50IHR5cGUuJyxcbiAgICBJbnZhbGlkSW50ZXJuYWxFdmVudE5hbWUgPSAnVGhlIG5hbWUgb2YgdGhlIGludGVybmFsIGV2ZW50IGlzIGludmFsaWQuJyxcbiAgICBJbnZhbGlkUmV0dXJuSW5FdmVudCA9ICdDYW5ub3QgcmV0dXJuIGEgdmFsdWUgZnJvbSBhbiBldmVudC4nLFxuXG4gICAgLy8gUlBDXG4gICAgUlBDTmFtZU11c3RCZVN0cmluZyA9ICdUaGUgUlBDIG5hbWUgbXVzdCBiZSBhIHN0cmluZy4nLFxuICAgIFJQQ05hbWVNdXN0QmVVbmlxdWUgPSAnVGhlIFJQQyBuYW1lIG11c3QgYmUgdW5pcXVlLicsXG4gICAgUlBDTm90QWxsb3dlZEluQ2xpZW50ID0gJ1RoZSBSUEMgaXMgbm90IGFsbG93ZWQgaW4gdGhlIGNsaWVudCBlbnZpcm9ubWVudC4nLFxuICAgIFJQQ05vdEFsbG93ZWRJblNlcnZlciA9ICdUaGUgUlBDIGlzIG5vdCBhbGxvd2VkIGluIHRoZSBzZXJ2ZXIgZW52aXJvbm1lbnQuJyxcbiAgICBJbnZhbGlkUlBDVHlwZSA9ICdJbnZhbGlkIFJQQyB0eXBlLicsXG4gICAgUlBDSGFuZGxlckFscmVhZHlFeGlzdHMgPSAnVGhlIFJQQyBoYW5kbGVyIGFscmVhZHkgZXhpc3RzLiBQbGVhc2UgcHJvdmlkZSBhIHVuaXF1ZSBuYW1lIGZvciB0aGUgUlBDLicsXG4gICAgUlBDUmVzcG9uc2VBbHJlYWR5U2VudCA9ICdUaGUgUlBDIHJlc3BvbnNlIGhhcyBhbHJlYWR5IGJlZW4gc2VudC4nLFxuXG4gICAgLy8gRXJyb3IgZmlsdGVyc1xuICAgIEludmFsaWRFcnJvckZpbHRlckRlZmluaXRpb24gPSAnSW52YWxpZCBlcnJvciBmaWx0ZXIuIEVycm9yIGZpbHRlcnMgbXVzdCBiZSBhIGNsYXNzIHJlZmVyZW5jZSBvciBhbiBvYmplY3Qgd2l0aCBhIGNhdGNoIG1ldGhvZC4nLFxuICAgIEVycm9yQWxyZWFkeUhhbmRsZWRCeUZpbHRlciA9ICdUaGUgZXJyb3IgYWxyZWFkeSBwb2ludHMgdG8gYSBmaWx0ZXIuJyxcbiAgICBFeGNlcHRpb25IYW5kbGluZ0NvbmZsaWN0ID0gJ1RoZSBzYW1lIGV4Y2VwdGlvbiBjYW4gb25seSBiZSBjYXVnaHQgb25jZS4nLFxuICAgIEF0TGVhc3RPbmVGaWx0ZXJSZXF1aXJlZCA9ICdBdCBsZWFzdCBvbmUgZXJyb3IgZmlsdGVyIG11c3QgYmUgcHJvdmlkZWQuJyxcbiAgICBEdXBsaWNhdGVFcnJvckZpbHRlckRldGVjdGVkID0gJ0R1cGxpY2F0ZSBlcnJvciBmaWx0ZXIgZm91bmQuIEVuc3VyZSB0aGF0IHRoZSBzYW1lIGZpbHRlciBpcyBub3QgYXBwbGllZCBtb3JlIHRoYW4gb25jZS4nLFxuXG4gICAgLy8gV2ViVmlld1xuICAgIFdlYlZpZXdOb3RGb3VuZCA9ICdUaGUgV2ViVmlldyB3aXRoIHRoZSBzcGVjaWZpZWQgaWQgZG9lcyBub3QgZXhpc3QuJyxcbiAgICBXZWJWaWV3SWRNdXN0QmVTdHJpbmdPck51bWJlciA9ICdUaGUgV2ViVmlldyBpZCBtdXN0IGJlIGEgc3RyaW5nIG9yIG51bWJlci4nLFxuXG4gICAgLy8gR3VhcmRcbiAgICBJbnZhbGlkR3VhcmREZWZpbml0aW9uID0gJ0ludmFsaWQgZ3VhcmQuIEd1YXJkcyBtdXN0IGJlIGEgY2xhc3MgcmVmZXJlbmNlIG9yIGFuIG9iamVjdCB3aXRoIGEgY2FuQWN0aXZhdGUgbWV0aG9kLicsXG4gICAgQXRMZWFzdE9uZUd1YXJkUmVxdWlyZWQgPSAnQXQgbGVhc3Qgb25lIGd1YXJkIG11c3QgYmUgcHJvdmlkZWQuJyxcblxuICAgIC8vIEludGVyY2VwdG9yXG4gICAgSW52YWxpZEludGVyY2VwdG9yRGVmaW5pdGlvbiA9ICdJbnZhbGlkIGludGVyY2VwdG9yLiBJbnRlcmNlcHRvcnMgbXVzdCBiZSBhIGNsYXNzIHJlZmVyZW5jZSBvciBhbiBvYmplY3Qgd2l0aCBhbiBpbnRlcmNlcHQgbWV0aG9kLicsXG4gICAgQXRMZWFzdE9uZUludGVyY2VwdG9yUmVxdWlyZWQgPSAnQXQgbGVhc3Qgb25lIGludGVyY2VwdG9yIG11c3QgYmUgcHJvdmlkZWQuJyxcbiAgICBJbnZhbGlkSW50ZXJjZXB0b3JSZXR1cm5WYWx1ZSA9ICdUaGUgaW50ZXJjZXB0b3IgbXVzdCByZXR1cm4gYSBmdW5jdGlvbi4nLFxuXG4gICAgLy8gUGlwZVxuICAgIEludmFsaWRQaXBlRGVmaW5pdGlvbiA9ICdJbnZhbGlkIHBpcGUuIFBpcGVzIG11c3QgYmUgYSBjbGFzcyByZWZlcmVuY2Ugb3IgYW4gb2JqZWN0IHdpdGggYSB0cmFuc2Zvcm0gbWV0aG9kLicsXG4gICAgQXRMZWFzdE9uZVBpcGVSZXF1aXJlZCA9ICdBdCBsZWFzdCBvbmUgcGlwZSBtdXN0IGJlIHByb3ZpZGVkLicsXG5cbiAgICAvLyBBcHAgbG9hZGluZ1xuICAgIEFwcEFscmVhZHlMb2FkZWQgPSAnQXBwIGlzIGFscmVhZHkgbG9hZGVkLiBQbGVhc2UgY2FsbCB0aGUgc3RvcCBtZXRob2QgYmVmb3JlIGNhbGxpbmcgdGhlIHN0YXJ0IG1ldGhvZC4nLFxuICAgIEFwcE5vdExvYWRlZCA9ICdBcHAgaXMgbm90IGxvYWRlZC4gUGxlYXNlIGNhbGwgdGhlIHN0YXJ0IG1ldGhvZCBiZWZvcmUgY2FsbGluZyB0aGUgc3RvcCBtZXRob2QuJyxcblxuICAgIC8vIERlY29yYXRvcnNcbiAgICBJbnZhbGlkSW5qZWN0aW9uVG9rZW5TcGVjaWZpZWQgPSAnVGhlIHNwZWNpZmllZCBpbmplY3Rpb24gdG9rZW4gaXMgaW52YWxpZC4nLFxuICAgIEluamVjdGlvblRva2VuTm90Rm91bmQgPSAnVGhlIGluamVjdGlvbiB0b2tlbiBjb3VsZCBub3QgYmUgZm91bmQuJyxcbiAgICBQYXJhbUtleU11c3RCZVN0cmluZyA9ICdUaGUgcGFyYW0ga2V5IG11c3QgYmUgYSBzdHJpbmcuJyxcbiAgICBJbmRleEtleU11c3RCZU51bWJlciA9ICdUaGUgaW5kZXgga2V5IG11c3QgYmUgYSBudW1iZXIuJyxcbiAgICBEdXBsaWNhdGVEZWNvcmF0b3JVc2FnZSA9ICdUaGUgc2FtZSBkZWNvcmF0b3IgY2FuIG9ubHkgYmUgdXNlZCBvbmNlIGluIHRoZSBzYW1lIGNsYXNzLicsXG4gICAgSW52YWxpZENvbnRyb2xsZXJPcHRpb25zID0gJ0ludmFsaWQgY29udHJvbGxlciBvcHRpb25zIGZvdW5kLicsXG4gICAgSW52YWxpZEluamVjdGFibGVPcHRpb25zID0gJ0ludmFsaWQgaW5qZWN0YWJsZSBvcHRpb25zIGZvdW5kLicsXG4gICAgSW52YWxpZE1vZHVsZU9wdGlvbnMgPSAnSW52YWxpZCBtb2R1bGUgb3B0aW9ucyBmb3VuZC4nLFxuICAgIE11bHRpcGxlRGVjb3JhdG9yc09uU2luZ2xlUGFyYW1ldGVyTm90QWxsb3dlZCA9ICdDYW5ub3QgYXBwbHkgbXVsdGlwbGUgZGVjb3JhdG9ycyB0byB0aGUgc2FtZSBwYXJhbWV0ZXIuJyxcblxuICAgIC8vIEludGVybmFsIEFwcFxuICAgIENpcmN1bGFyRGVwZW5kZW5jeURldGVjdGVkID0gJ0NpcmN1bGFyIGRlcGVuZGVuY3kgZGV0ZWN0ZWQuJyxcbiAgICBJbnZhbGlkTW9kdWxlRGVmaW5pdGlvbiA9ICdUaGUgbW9kdWxlIGlzIGludmFsaWQuJyxcbiAgICBJbnZhbGlkRXhwb3J0RGVmaW5pdGlvbiA9ICdUaGUgZXhwb3J0IGlzIGludmFsaWQuJyxcbiAgICBJbnZhbGlkUHJvdmlkZXJEZWZpbml0aW9uID0gJ1RoZSBwcm92aWRlciBpcyBpbnZhbGlkLicsXG4gICAgSW52YWxpZFBhcmFtZXRlckRlY29yYXRvclVzYWdlID0gJ0VhY2ggcGFyYW1ldGVyIG11c3QgaGF2ZSB0aGVpciBpdHMgb3duIGRlY29yYXRvci4nLFxuICAgIFJlc3BvbnNlRGVjb3JhdG9yTm90QWxsb3dlZE9uRXZlbnRzID0gJ1RoZSBAUmVzcG9uc2UoKSBkZWNvcmF0b3IgaXMgbm90IGFsbG93ZWQgb24gZXZlbnRzLicsXG4gICAgUGxheWVyRGVjb3JhdG9yTm90QWxsb3dlZE9uQ2xpZW50RXZlbnRzID0gJ1RoZSBAUGxheWVyKCkgZGVjb3JhdG9yIGlzIG5vdCBhbGxvd2VkIG9uIGNsaWVudCBldmVudHMuJyxcblxuICAgIC8vIFRpbWVyc1xuICAgIFRpbWVyTmFtZU11c3RCZVN0cmluZyA9ICdUaGUgdGltZXIgbmFtZSBtdXN0IGJlIGEgc3RyaW5nLicsXG59XG4iLCAiZXhwb3J0IGVudW0gSW5qZWN0YWJsZVNjb3BlIHtcbiAgICBSZXF1ZXN0ID0gJ3JlcXVlc3QnLFxuICAgIFRyYW5zaWVudCA9ICd0cmFuc2llbnQnLFxuICAgIFNpbmdsZXRvbiA9ICdzaW5nbGV0b24nLFxufVxuIiwgImV4cG9ydCBlbnVtIFJQQ1Jlc3VsdFN0YXR1cyB7XG4gICAgU3VjY2VzcyA9IDEsXG4gICAgVGltZW91dCA9IDIsXG4gICAgSGFuZGxlck5vdEZvdW5kID0gMyxcbiAgICBVbmtub3duID0gNCxcbiAgICBDYW5jZWxsZWRCeUd1YXJkID0gNSxcbiAgICBJbnZhbGlkR3VhcmRSZXR1cm4gPSA2LFxuICAgIFRvb01hbnlSZXF1ZXN0cyA9IDcsXG4gICAgUGxheWVyRGlzY29ubmVjdGVkID0gOCxcbiAgICBQbGF5ZXJOb3RGb3VuZCA9IDksXG59XG4iLCAiaW1wb3J0IHsgUlBDUmVzdWx0U3RhdHVzIH0gZnJvbSAnLi4vLi4vZW51bXMnO1xuaW1wb3J0IHR5cGUgeyBSUENSZXN1bHQgfSBmcm9tICcuLi8uLi9pbnRlcmZhY2VzJztcblxuZXhwb3J0IGNvbnN0IElOVEVSTkFMX0FQUF9DT05UQUlORVIgPSAnSU5URVJOQUxfQVBQX0NPTlRBSU5FUic7XG5leHBvcnQgY29uc3QgR0xPQkFMX0FQUF9DT05UQUlORVIgPSAnR0xPQkFMX0FQUF9DT05UQUlORVInO1xuZXhwb3J0IGNvbnN0IEFQUF9FTlZJUk9NRU5UID0gJ0FQUF9FTlZJUk9NRU5UJztcblxuZXhwb3J0IGNvbnN0IEdMT0JBTF9HVUFSRFMgPSAnR0xPQkFMX0dVQVJEUyc7XG5leHBvcnQgY29uc3QgR0xPQkFMX0lOVEVSQ0VQVE9SUyA9ICdHTE9CQUxfSU5URVJDRVBUT1JTJztcbmV4cG9ydCBjb25zdCBHTE9CQUxfUElQRVMgPSAnR0xPQkFMX1BJUEVTJztcbmV4cG9ydCBjb25zdCBHTE9CQUxfRVJST1JfRklMVEVSUyA9ICdHTE9CQUxfRVJST1JfRklMVEVSUyc7XG5cbmV4cG9ydCBjb25zdCBQTFVHSU5TID0gJ1BMVUdJTlMnO1xuXG5leHBvcnQgY29uc3QgRU5BQkxFX1NIVVRET1dOX0hPT0tTID0gJ0VOQUJMRV9TSFVURE9XTl9IT09LUyc7XG5leHBvcnQgY29uc3QgQ09OVEFJTkVSX09QVElPTlMgPSAnQ09OVEFJTkVSX09QVElPTlMnO1xuZXhwb3J0IGNvbnN0IExPR19FUlJPUl9TVEFDS1RSQUNFID0gJ0xPR19FUlJPUl9TVEFDS1RSQUNFJztcblxuZXhwb3J0IGNvbnN0IE1BTkdPX0xPR19QUkVGSVggPSAn8J+lrSc7XG5cbmV4cG9ydCBjb25zdCBNQU5HT19SRVFVRVNUX0ZBQ1RPUlkgPSAnTUFOR09fUkVRVUVTVF9GQUNUT1JZJztcbmV4cG9ydCBjb25zdCBNQU5HT19SRVNQT05TRV9GQUNUT1JZID0gJ01BTkdPX1JFU1BPTlNFX0ZBQ1RPUlknO1xuZXhwb3J0IGNvbnN0IEVYRUNVVElPTl9DT05URVhUX0ZBQ1RPUlkgPSAnRVhFQ1VUSU9OX0NPTlRFWFRfRkFDVE9SWSc7XG5cbmV4cG9ydCBjb25zdCBNVUxUSVBMQVlFUl9TRVJWSUNFID0gJ01VTFRJUExBWUVSX1NFUlZJQ0UnO1xuXG5leHBvcnQgY29uc3QgUlBDX1JFU1VMVF9USU1FT1VUOiBSUENSZXN1bHQgPSB7XG4gICAgc3VjY2VzczogZmFsc2UsXG4gICAgZXJyb3I6IHsgbWVzc2FnZTogJ1JQQyBjYWxsIHRpbWVkIG91dC4nIH0sXG4gICAgc3RhdHVzOiBSUENSZXN1bHRTdGF0dXMuVGltZW91dCxcbn07XG5cbmV4cG9ydCBjb25zdCBSUENfUkVTVUxUX0hBTkRMRVJfTk9UX0ZPVU5EOiBSUENSZXN1bHQgPSB7XG4gICAgc3VjY2VzczogZmFsc2UsXG4gICAgZXJyb3I6IHsgbWVzc2FnZTogJ1JQQyBoYW5kbGVyIG5vdCBmb3VuZC4nIH0sXG4gICAgc3RhdHVzOiBSUENSZXN1bHRTdGF0dXMuSGFuZGxlck5vdEZvdW5kLFxufTtcblxuZXhwb3J0IGNvbnN0IFJQQ19SRVNVTFRfVU5LTk9XTjogUlBDUmVzdWx0ID0ge1xuICAgIHN1Y2Nlc3M6IGZhbHNlLFxuICAgIGVycm9yOiB7IG1lc3NhZ2U6ICdVbmtub3duIGVycm9yLicgfSxcbiAgICBzdGF0dXM6IFJQQ1Jlc3VsdFN0YXR1cy5Vbmtub3duLFxufTtcblxuZXhwb3J0IGNvbnN0IFJQQ19SRVNVTFRfUExBWUVSX0RJU0NPTk5FQ1RFRDogUlBDUmVzdWx0ID0ge1xuICAgIHN1Y2Nlc3M6IGZhbHNlLFxuICAgIGVycm9yOiB7IG1lc3NhZ2U6ICdQbGF5ZXIgZGlzY29ubmVjdGVkLicgfSxcbiAgICBzdGF0dXM6IFJQQ1Jlc3VsdFN0YXR1cy5QbGF5ZXJEaXNjb25uZWN0ZWQsXG59O1xuXG5leHBvcnQgY29uc3QgUlBDX1JFU1VMVF9QTEFZRVJfTk9UX0ZPVU5EOiBSUENSZXN1bHQgPSB7XG4gICAgc3VjY2VzczogZmFsc2UsXG4gICAgZXJyb3I6IHsgbWVzc2FnZTogJ1BsYXllciBub3QgZm91bmQuJyB9LFxuICAgIHN0YXR1czogUlBDUmVzdWx0U3RhdHVzLlBsYXllck5vdEZvdW5kLFxufTtcbiIsICJ2YXIgX19kZWZQcm9wID0gT2JqZWN0LmRlZmluZVByb3BlcnR5O1xudmFyIF9fbmFtZSA9ICh0YXJnZXQsIHZhbHVlKT0+X19kZWZQcm9wKHRhcmdldCwgXCJuYW1lXCIsIHtcbiAgICAgICAgdmFsdWUsXG4gICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxuICAgIH0pO1xuZXhwb3J0IHsgX19uYW1lIH07IC8vIyBzb3VyY2VNYXBwaW5nVVJMPWRhdGE6YXBwbGljYXRpb24vanNvbjtiYXNlNjQsZXdvZ0lDSjJaWEp6YVc5dUlqb2dNeXdLSUNBaWMyOTFjbU5sY3lJNklGdGRMQW9nSUNKemIzVnlZMlZ6UTI5dWRHVnVkQ0k2SUZ0ZExBb2dJQ0p0WVhCd2FXNW5jeUk2SUNJaUxBb2dJQ0p1WVcxbGN5STZJRnRkQ24wS1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGF0YTphcHBsaWNhdGlvbi9qc29uO2Jhc2U2NCxleUoyWlhKemFXOXVJam96TENKemIzVnlZMlZ6SWpwYlhTd2libUZ0WlhNaU9sdGRMQ0p0WVhCd2FXNW5jeUk2SWlKOSIsICJleHBvcnQgZnVuY3Rpb24gZ2VuZXJhdGVSYW5kb21JZCgpIHtcbiAgICByZXR1cm4gTWF0aC5yYW5kb20oKS50b1N0cmluZygzNikuc3Vic3RyaW5nKDIsIDE1KSArIE1hdGgucmFuZG9tKCkudG9TdHJpbmcoMzYpLnN1YnN0cmluZygyLCAxNSk7XG59XG4iLCAiZXhwb3J0IGNvbnN0IGlzVW5kZWZpbmVkID0gKG9iajogYW55KTogb2JqIGlzIHVuZGVmaW5lZCA9PiB0eXBlb2Ygb2JqID09PSAndW5kZWZpbmVkJztcbmV4cG9ydCBjb25zdCBpc09iamVjdCA9IChmbjogYW55KTogZm4gaXMgb2JqZWN0ID0+ICFpc05pbChmbikgJiYgdHlwZW9mIGZuID09PSAnb2JqZWN0JztcbmV4cG9ydCBjb25zdCBpc0Z1bmN0aW9uID0gKHZhbDogYW55KTogdmFsIGlzIEZ1bmN0aW9uID0+IHR5cGVvZiB2YWwgPT09ICdmdW5jdGlvbic7XG5leHBvcnQgY29uc3QgaXNTdHJpbmcgPSAodmFsOiBhbnkpOiB2YWwgaXMgc3RyaW5nID0+IHR5cGVvZiB2YWwgPT09ICdzdHJpbmcnO1xuZXhwb3J0IGNvbnN0IGlzTnVtYmVyID0gKHZhbDogYW55KTogdmFsIGlzIG51bWJlciA9PiB0eXBlb2YgdmFsID09PSAnbnVtYmVyJztcbmV4cG9ydCBjb25zdCBpc0NvbnN0cnVjdG9yID0gKHZhbDogYW55KTogYm9vbGVhbiA9PiB2YWwgPT09ICdjb25zdHJ1Y3Rvcic7XG5leHBvcnQgY29uc3QgaXNOaWwgPSAodmFsOiBhbnkpOiB2YWwgaXMgbnVsbCB8IHVuZGVmaW5lZCA9PiBpc1VuZGVmaW5lZCh2YWwpIHx8IHZhbCA9PT0gbnVsbDtcbmV4cG9ydCBjb25zdCBpc0VtcHR5ID0gKGFycmF5OiBhbnkpOiBib29sZWFuID0+ICEoYXJyYXkgJiYgYXJyYXkubGVuZ3RoID4gMCk7XG5leHBvcnQgY29uc3QgaXNTeW1ib2wgPSAodmFsOiBhbnkpOiB2YWwgaXMgc3ltYm9sID0+IHR5cGVvZiB2YWwgPT09ICdzeW1ib2wnO1xuZXhwb3J0IGNvbnN0IGlzQXN5bmNGdW5jdGlvbiA9ICh2YWw6IGFueSk6IGJvb2xlYW4gPT4gaXNGdW5jdGlvbih2YWwpICYmIHZhbC5jb25zdHJ1Y3Rvci5uYW1lID09PSAnQXN5bmNGdW5jdGlvbic7XG5leHBvcnQgY29uc3QgaXNCb29sZWFuID0gKHZhbDogYW55KTogdmFsIGlzIGJvb2xlYW4gPT4gdHlwZW9mIHZhbCA9PT0gJ2Jvb2xlYW4nO1xuZXhwb3J0IGNvbnN0IGlzUHJvbWlzZSA9IDxUID0gYW55Pih2YWw6IGFueSk6IHZhbCBpcyBQcm9taXNlPFQ+ID0+IHZhbCBpbnN0YW5jZW9mIFByb21pc2U7XG4iLCAiZXhwb3J0IGVudW0gQXBwRW52aXJvbWVudCB7XG4gICAgQ2xpZW50LFxuICAgIFNlcnZlcixcbn1cbiIsICJleHBvcnQgZW51bSBDb3JlTWV0YWRhdGFLZXkge1xuICAgIC8vIEdlbmVyYWxcbiAgICBJbmplY3RhYmxlID0gJ21hbmdvOmluamVjdGFibGUnLFxuICAgIEluamVjdCA9ICdtYW5nbzppbmplY3QnLFxuICAgIE1vZHVsZSA9ICdtYW5nbzptb2R1bGUnLFxuICAgIEdsb2JhbE1vZHVsZSA9ICdtYW5nbzpnbG9iYWwtbW9kdWxlJyxcbiAgICBDb250cm9sbGVyID0gJ21hbmdvOmNvbnRyb2xsZXItb3B0aW9ucycsXG4gICAgLy8gRXZlbnRzICYgUlBDXG4gICAgQ29udHJvbGxlckV2ZW50cyA9ICdtYW5nbzpjb250cm9sbGVyLWV2ZW50cycsXG4gICAgQ29udHJvbGxlclJQQ3MgPSAnbWFuZ286Y29udHJvbGxlci1ycGNzJyxcbiAgICBDb250cm9sbGVyUGFyYW1zID0gJ21hbmdvOmNvbnRyb2xsZXItcnBjLXBhcmFtcycsXG4gICAgLy8gUGlwZWxpbmVcbiAgICBHdWFyZHMgPSAnbWFuZ286Z3VhcmRzJyxcbiAgICBJbnRlcmNlcHRvcnMgPSAnbWFuZ286aW50ZXJjZXB0b3JzJyxcbiAgICBQaXBlcyA9ICdtYW5nbzpwaXBlcycsXG4gICAgLy8gRXJyb3JcbiAgICBDYXRjaCA9ICdtYW5nbzpjYXRjaCcsXG4gICAgRXJyb3JGaWx0ZXJzID0gJ21hbmdvOmVycm9yLWZpbHRlcnMnLFxuICAgIC8vXG4gICAgVGltZXJzID0gJ21hbmdvOnRpbWVycycsXG59XG4iLCAiZXhwb3J0IGVudW0gRXZlbnREZXN0aW5hdGlvbiB7XG4gICAgU2VydmVyID0gJ3NlcnZlcicsXG4gICAgQ2xpZW50ID0gJ2NsaWVudCcsXG4gICAgV2ViVmlldyA9ICd3ZWJ2aWV3Jyxcbn1cbiIsICJleHBvcnQgZW51bSBFeGVjdXRpb25Db250ZXh0VHlwZSB7XG4gICAgRXZlbnQgPSAnZXZlbnQnLFxuICAgIFJQQyA9ICdycGMnLFxufVxuIiwgImV4cG9ydCBlbnVtIE1ldGhvZFBhcmFtVHlwZSB7XG4gICAgQm9keSA9ICdib2R5JyxcbiAgICBDdXN0b20gPSAnY3VzdG9tJyxcbiAgICBQYXJhbSA9ICdwYXJhbScsXG4gICAgUGxheWVyID0gJ3BsYXllcicsXG4gICAgUmVxdWVzdCA9ICdyZXF1ZXN0JyxcbiAgICBSZXNwb25zZSA9ICdyZXNwb25zZScsXG4gICAgSW5kZXggPSAnaW5kZXgnLFxufVxuIiwgImltcG9ydCB7IHR5cGUgUlBDQ2FsbE9wdGlvbnMsIHR5cGUgUlBDUmVzdWx0LCB0eXBlIFNjcmlwdFJQQ0hhbmRsZXIgfSBmcm9tICdAcmFnZW1wLW1hbmdvL2NvcmUvaW50ZXJmYWNlcyc7XG5pbXBvcnQgeyBSUENfUkVTVUxUX0hBTkRMRVJfTk9UX0ZPVU5ELCBSUENfUkVTVUxUX1RJTUVPVVQgfSBmcm9tICdAcmFnZW1wLW1hbmdvL2NvcmUvYXBwL2NvbnN0YW50cyc7XG5pbXBvcnQgdHlwZSB7IEV2ZW50U2VydmljZSwgUlBDU2VydmljZSB9IGZyb20gJy4uL2ludGVyZmFjZXMnO1xuaW1wb3J0IHR5cGUgeyBXZWJWaWV3RXZlbnRTZXJ2aWNlIH0gZnJvbSAnLi93ZWJ2aWV3LWV2ZW50LnNlcnZpY2UnO1xuaW1wb3J0IHR5cGUgeyBXZWJWaWV3TG9nZ2VyU2VydmljZSB9IGZyb20gJy4vd2Vidmlldy1sb2dnZXIuc2VydmljZSc7XG5pbXBvcnQgeyBnZW5lcmF0ZVJhbmRvbUlkLCBpc05pbCB9IGZyb20gJ0ByYWdlbXAtbWFuZ28vY29yZS91dGlscyc7XG5pbXBvcnQgeyBFcnJvck1lc3NhZ2UsIFJQQ1Jlc3VsdFN0YXR1cyB9IGZyb20gJ0ByYWdlbXAtbWFuZ28vY29yZS9lbnVtcyc7XG5pbXBvcnQgeyBFdmVudERlc3RpbmF0aW9uIH0gZnJvbSAnQHJhZ2VtcC1tYW5nby9jb3JlL2FwcC9lbnVtcyc7XG5pbXBvcnQgdHlwZSB7IFJQQ1BheWxvYWQgfSBmcm9tICdAcmFnZW1wLW1hbmdvL2NvcmUvYXBwL2ludGVyZmFjZXMnO1xuXG5leHBvcnQgY2xhc3MgV2ViVmlld1JQQ1NlcnZpY2UgaW1wbGVtZW50cyBSUENTZXJ2aWNlIHtcbiAgICBwcml2YXRlIHJlYWRvbmx5ICRUSU1FT1VUID0gMjAwMDtcbiAgICBwdWJsaWMgcmVhZG9ubHkgJGxvY2FsSGFuZGxlcnMgPSBuZXcgTWFwPHN0cmluZywgU2NyaXB0UlBDSGFuZGxlcj4oKTtcbiAgICBwdWJsaWMgcmVhZG9ubHkgJGNsaWVudEhhbmRsZXJzID0gbmV3IE1hcDxzdHJpbmcsIFNjcmlwdFJQQ0hhbmRsZXI+KCk7XG4gICAgcHVibGljIHJlYWRvbmx5ICRzZXJ2ZXJIYW5kbGVycyA9IG5ldyBNYXA8c3RyaW5nLCBTY3JpcHRSUENIYW5kbGVyPigpO1xuXG4gICAgcHVibGljIGNvbnN0cnVjdG9yKHByaXZhdGUgcmVhZG9ubHkgJGV2ZW50U2VydmljZTogV2ViVmlld0V2ZW50U2VydmljZSwgcHJpdmF0ZSByZWFkb25seSAkbG9nZ2VyU2VydmljZTogV2ViVmlld0xvZ2dlclNlcnZpY2UpIHt9XG5cbiAgICBwdWJsaWMgYXN5bmMgY2FsbDxFIGV4dGVuZHMgc3RyaW5nPihcbiAgICAgICAgcnBjTmFtZTogRSxcbiAgICAgICAgYm9keT86IHVua25vd24sXG4gICAgICAgIG9wdGlvbnM6IFJQQ0NhbGxPcHRpb25zID0geyB0aW1lb3V0OiB0aGlzLiRUSU1FT1VUIH0sXG4gICAgKTogUHJvbWlzZTxSUENSZXN1bHQ+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKGFzeW5jIChyZXNvbHZlKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBycGNIYW5kbGVyID0gdGhpcy4kbG9jYWxIYW5kbGVycy5nZXQocnBjTmFtZSk7XG4gICAgICAgICAgICBpZiAoaXNOaWwocnBjSGFuZGxlcikpIHtcbiAgICAgICAgICAgICAgICByZXNvbHZlKFJQQ19SRVNVTFRfSEFORExFUl9OT1RfRk9VTkQpO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgdGltZW91dElkID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgcmVzb2x2ZShSUENfUkVTVUxUX1RJTUVPVVQpO1xuICAgICAgICAgICAgfSwgb3B0aW9ucy50aW1lb3V0KTtcblxuICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgcnBjSGFuZGxlci5oYW5kbGVyKGJvZHkpO1xuICAgICAgICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXRJZCk7XG4gICAgICAgICAgICByZXNvbHZlKHsgc3VjY2VzczogdHJ1ZSwgc3RhdHVzOiBSUENSZXN1bHRTdGF0dXMuU3VjY2VzcywgYm9keTogcmVzdWx0LCBlcnJvcjogdW5kZWZpbmVkIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwdWJsaWMgb25SZXF1ZXN0PEUgZXh0ZW5kcyBzdHJpbmc+KFxuICAgICAgICBycGNOYW1lOiBFLFxuICAgICAgICBoYW5kbGVyOiAoYm9keTogdW5rbm93bikgPT4gdW5rbm93biB8IFByb21pc2U8dW5rbm93bj4sXG4gICAgKTogU2NyaXB0UlBDSGFuZGxlciB7XG4gICAgICAgIGlmICh0aGlzLiRsb2NhbEhhbmRsZXJzLmhhcyhycGNOYW1lKSkge1xuICAgICAgICAgICAgdGhpcy4kbG9nZ2VyU2VydmljZS5lcnJvcignQW4gZXJyb3Igb2NjdXJyZWQgd2hpbGUgcmVnaXN0ZXJpbmcgYSBSUEMgaGFuZGxlci4nKTtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihFcnJvck1lc3NhZ2UuUlBDSGFuZGxlckFscmVhZHlFeGlzdHMpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHJwY0hhbmRsZXI6IFNjcmlwdFJQQ0hhbmRsZXIgPSB7XG4gICAgICAgICAgICBkZXN0cm95OiAoKSA9PiB7XG4gICAgICAgICAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICAgICAgICAgIHJwY0hhbmRsZXIudmFsaWQgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICB0aGlzLiRsb2NhbEhhbmRsZXJzLmRlbGV0ZShycGNOYW1lKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBycGNOYW1lLFxuICAgICAgICAgICAgaGFuZGxlcixcbiAgICAgICAgICAgIHZhbGlkOiB0cnVlLFxuICAgICAgICB9O1xuICAgICAgICB0aGlzLiRsb2NhbEhhbmRsZXJzLnNldChycGNOYW1lLCBycGNIYW5kbGVyKTtcbiAgICAgICAgcmV0dXJuIHJwY0hhbmRsZXI7XG4gICAgfVxuXG4gICAgcHVibGljIGNhbGxTZXJ2ZXI8RSBleHRlbmRzIHN0cmluZz4oXG4gICAgICAgIHJwY05hbWU6IEUsXG4gICAgICAgIGJvZHk/OiB1bmtub3duLFxuICAgICAgICBvcHRpb25zOiBSUENDYWxsT3B0aW9ucyA9IHsgdGltZW91dDogdGhpcy4kVElNRU9VVCB9LFxuICAgICk6IFByb21pc2U8UlBDUmVzdWx0PiB7XG4gICAgICAgIHJldHVybiB0aGlzLiRoYW5kbGVDYWxsKHJwY05hbWUsIEV2ZW50RGVzdGluYXRpb24uU2VydmVyLCBvcHRpb25zLCBib2R5KTtcbiAgICB9XG5cbiAgICBwdWJsaWMgb25TZXJ2ZXJSZXF1ZXN0PEUgZXh0ZW5kcyBzdHJpbmc+KFxuICAgICAgICBycGNOYW1lOiBFLFxuICAgICAgICBoYW5kbGVyOiAoYm9keTogdW5rbm93bikgPT4gdW5rbm93biB8IFByb21pc2U8dW5rbm93bj4sXG4gICAgKTogU2NyaXB0UlBDSGFuZGxlciB7XG4gICAgICAgIGlmICh0aGlzLiRzZXJ2ZXJIYW5kbGVycy5oYXMocnBjTmFtZSkpIHtcbiAgICAgICAgICAgIHRoaXMuJGxvZ2dlclNlcnZpY2UuZXJyb3IoJ0FuIGVycm9yIG9jY3VycmVkIHdoaWxlIHJlZ2lzdGVyaW5nIGEgUlBDIGhhbmRsZXIuJyk7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoRXJyb3JNZXNzYWdlLlJQQ0hhbmRsZXJBbHJlYWR5RXhpc3RzKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBycGNIYW5kbGVyOiBTY3JpcHRSUENIYW5kbGVyID0ge1xuICAgICAgICAgICAgZGVzdHJveTogKCkgPT4ge1xuICAgICAgICAgICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgICAgICAgICBycGNIYW5kbGVyLnZhbGlkID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgdGhpcy4kc2VydmVySGFuZGxlcnMuZGVsZXRlKHJwY05hbWUpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHJwY05hbWUsXG4gICAgICAgICAgICBoYW5kbGVyLFxuICAgICAgICAgICAgdmFsaWQ6IHRydWUsXG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuJHNlcnZlckhhbmRsZXJzLnNldChycGNOYW1lLCBycGNIYW5kbGVyKTtcbiAgICAgICAgcmV0dXJuIHJwY0hhbmRsZXI7XG4gICAgfVxuXG4gICAgcHVibGljIGNhbGxQbGF5ZXI8RSBleHRlbmRzIHN0cmluZz4oXG4gICAgICAgIHJwY05hbWU6IEUsXG4gICAgICAgIGJvZHk/OiB1bmtub3duLFxuICAgICAgICBvcHRpb25zOiBSUENDYWxsT3B0aW9ucyA9IHsgdGltZW91dDogdGhpcy4kVElNRU9VVCB9LFxuICAgICk6IFByb21pc2U8UlBDUmVzdWx0PiB7XG4gICAgICAgIHJldHVybiB0aGlzLiRoYW5kbGVDYWxsKHJwY05hbWUsIEV2ZW50RGVzdGluYXRpb24uQ2xpZW50LCBvcHRpb25zLCBib2R5KTtcbiAgICB9XG5cbiAgICBwdWJsaWMgb25QbGF5ZXJSZXF1ZXN0PEUgZXh0ZW5kcyBzdHJpbmc+KFxuICAgICAgICBycGNOYW1lOiBFLFxuICAgICAgICBoYW5kbGVyOiAoYm9keTogdW5rbm93bikgPT4gdW5rbm93biB8IFByb21pc2U8dW5rbm93bj4sXG4gICAgKTogU2NyaXB0UlBDSGFuZGxlciB7XG4gICAgICAgIGlmICh0aGlzLiRjbGllbnRIYW5kbGVycy5oYXMocnBjTmFtZSkpIHtcbiAgICAgICAgICAgIHRoaXMuJGxvZ2dlclNlcnZpY2UuZXJyb3IoJ0FuIGVycm9yIG9jY3VycmVkIHdoaWxlIHJlZ2lzdGVyaW5nIGEgUlBDIGxpc3RlbmVyLicpO1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKEVycm9yTWVzc2FnZS5SUENIYW5kbGVyQWxyZWFkeUV4aXN0cyk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcnBjSGFuZGxlcjogU2NyaXB0UlBDSGFuZGxlciA9IHtcbiAgICAgICAgICAgIGRlc3Ryb3k6ICgpID0+IHtcbiAgICAgICAgICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgICAgICAgICAgcnBjSGFuZGxlci52YWxpZCA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIHRoaXMuJGNsaWVudEhhbmRsZXJzLmRlbGV0ZShycGNOYW1lKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBycGNOYW1lLFxuICAgICAgICAgICAgaGFuZGxlcixcbiAgICAgICAgICAgIHZhbGlkOiB0cnVlLFxuICAgICAgICB9O1xuICAgICAgICB0aGlzLiRjbGllbnRIYW5kbGVycy5zZXQocnBjTmFtZSwgcnBjSGFuZGxlcik7XG4gICAgICAgIHJldHVybiBycGNIYW5kbGVyO1xuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgJGhhbmRsZUNhbGw8VFJlc3VsdD4oXG4gICAgICAgIHJwY05hbWU6IHN0cmluZyxcbiAgICAgICAgZGVzdGluYXRpb246IEV2ZW50RGVzdGluYXRpb24sIC8vICdjbGllbnQnIHwgJ3NlcnZlcicsXG4gICAgICAgIG9wdGlvbnM/OiBQYXJ0aWFsPFJQQ0NhbGxPcHRpb25zPixcbiAgICAgICAgYm9keT86IHVua25vd24sXG4gICAgKSB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZTxSUENSZXN1bHQ8VFJlc3VsdD4+KChyZXNvbHZlKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBjYWxsSWQgPSBnZW5lcmF0ZVJhbmRvbUlkKCk7XG4gICAgICAgICAgICBsZXQgdGltZW91dElkOiBudW1iZXI7XG5cbiAgICAgICAgICAgIGNvbnN0IG9uY2VIYW5kbGUgPSAoYm9keTogdW5rbm93bikgPT4ge1xuICAgICAgICAgICAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0SWQpO1xuICAgICAgICAgICAgICAgIHJlc29sdmUoPFJQQ1Jlc3VsdDxUUmVzdWx0Pj5ib2R5KTtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBjb25zdCBzY3JpcHRFdmVudEhhbmRsZXIgPVxuICAgICAgICAgICAgICAgIGRlc3RpbmF0aW9uID09PSBFdmVudERlc3RpbmF0aW9uLlNlcnZlclxuICAgICAgICAgICAgICAgICAgICA/IHRoaXMuJGV2ZW50U2VydmljZS5vbmNlU2VydmVyKGBSUEM6OlJFVFVSTl9GUk9NX1NFUlZFUl8ke2NhbGxJZH1gLCBvbmNlSGFuZGxlKVxuICAgICAgICAgICAgICAgICAgICA6IHRoaXMuJGV2ZW50U2VydmljZS5vbmNlUGxheWVyKGBSUEM6OlJFVFVSTl9GUk9NX0NMSUVOVF8ke2NhbGxJZH1gLCBvbmNlSGFuZGxlKTtcblxuICAgICAgICAgICAgY29uc3QgcGF5bG9hZDogUlBDUGF5bG9hZCA9IHtcbiAgICAgICAgICAgICAgICBzb3VyY2U6IEV2ZW50RGVzdGluYXRpb24uV2ViVmlldyxcbiAgICAgICAgICAgICAgICBkZXN0aW5hdGlvbixcbiAgICAgICAgICAgICAgICBpZDogY2FsbElkLFxuICAgICAgICAgICAgICAgIHJwY05hbWUsXG4gICAgICAgICAgICAgICAgYm9keSxcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBkZXN0aW5hdGlvbiA9PT0gRXZlbnREZXN0aW5hdGlvbi5TZXJ2ZXJcbiAgICAgICAgICAgICAgICA/ICg8RXZlbnRTZXJ2aWNlPnRoaXMuJGV2ZW50U2VydmljZSkuZW1pdFBsYXllcignUlBDOjpDQUxMX1NFUlZFUicsIHBheWxvYWQpXG4gICAgICAgICAgICAgICAgOiAoPEV2ZW50U2VydmljZT50aGlzLiRldmVudFNlcnZpY2UpLmVtaXRQbGF5ZXIoJ1JQQzo6Q0FMTF9DTElFTlQnLCBwYXlsb2FkKTtcblxuICAgICAgICAgICAgdGltZW91dElkID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgc2NyaXB0RXZlbnRIYW5kbGVyLmRlc3Ryb3koKTtcbiAgICAgICAgICAgICAgICByZXNvbHZlKDxSUENSZXN1bHQ8VFJlc3VsdD4+UlBDX1JFU1VMVF9USU1FT1VUKTtcbiAgICAgICAgICAgIH0sIG9wdGlvbnM/LnRpbWVvdXQgPz8gdGhpcy4kVElNRU9VVCk7XG4gICAgICAgIH0pO1xuICAgIH1cbn1cbiIsICJpbXBvcnQgeyBSUENSZXN1bHRTdGF0dXMgfSBmcm9tICcuLi9lbnVtcyc7XG5cbmV4cG9ydCBjbGFzcyBNYW5nb0Vycm9yPFREZXRhaWxzID0gdW5rbm93bj4gZXh0ZW5kcyBFcnJvciB7XG4gICAgcHVibGljIHN0YXR1czogbnVtYmVyID0gUlBDUmVzdWx0U3RhdHVzLlVua25vd247XG4gICAgcHVibGljIGRldGFpbHM6IFREZXRhaWxzIHwgdW5kZWZpbmVkO1xuXG4gICAgcHVibGljIGNvbnN0cnVjdG9yKG1lc3NhZ2U6IHN0cmluZywgc3RhdHVzPzogbnVtYmVyLCBkZXRhaWxzPzogVERldGFpbHMpIHtcbiAgICAgICAgc3VwZXIobWVzc2FnZSk7XG4gICAgICAgIHRoaXMuc3RhdHVzID0gc3RhdHVzID8/IFJQQ1Jlc3VsdFN0YXR1cy5Vbmtub3duO1xuICAgICAgICB0aGlzLmRldGFpbHMgPSBkZXRhaWxzO1xuICAgIH1cbn1cbiIsICJpbXBvcnQgeyBSUENSZXN1bHRTdGF0dXMgfSBmcm9tICcuLi9lbnVtcyc7XG5pbXBvcnQgeyBNYW5nb0Vycm9yIH0gZnJvbSAnLi9tYW5nby5lcnJvcic7XG5cbmV4cG9ydCBjbGFzcyBHdWFyZENhbmNlbEVycm9yIGV4dGVuZHMgTWFuZ29FcnJvciB7XG4gICAgcHVibGljIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcignUHJvY2VzcyBjYW5jZWxsZWQgYnkgdGhlIGd1YXJkLicsIFJQQ1Jlc3VsdFN0YXR1cy5DYW5jZWxsZWRCeUd1YXJkKTtcbiAgICB9XG59XG4iLCAiaW1wb3J0IHsgUlBDUmVzdWx0U3RhdHVzIH0gZnJvbSAnLi4vZW51bXMnO1xuaW1wb3J0IHsgTWFuZ29FcnJvciB9IGZyb20gJy4vbWFuZ28uZXJyb3InO1xuXG5leHBvcnQgY2xhc3MgR3VhcmRJbnZhbGlkUmV0dXJuRXJyb3IgZXh0ZW5kcyBNYW5nb0Vycm9yIHtcbiAgICBwdWJsaWMgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKCdHdWFyZCByZXR1cm5lZCBhbiBpbnZhbGlkIHZhbHVlLiBFeHBlY3RlZCBib29sZWFuLicsIFJQQ1Jlc3VsdFN0YXR1cy5JbnZhbGlkR3VhcmRSZXR1cm4pO1xuICAgIH1cbn1cbiIsICJpbXBvcnQgeyBSUENSZXN1bHRTdGF0dXMgfSBmcm9tICcuLi9lbnVtcyc7XG5pbXBvcnQgeyBNYW5nb0Vycm9yIH0gZnJvbSAnLi9tYW5nby5lcnJvcic7XG5cbmV4cG9ydCBjbGFzcyBUb29NYW55UmVxdWVzdHMgZXh0ZW5kcyBNYW5nb0Vycm9yIHtcbiAgICBwdWJsaWMgY29uc3RydWN0b3IobWVzc2FnZSA9ICdUb28gbWFueSByZXF1ZXN0cy4nKSB7XG4gICAgICAgIHN1cGVyKG1lc3NhZ2UsIFJQQ1Jlc3VsdFN0YXR1cy5Ub29NYW55UmVxdWVzdHMpO1xuICAgIH1cbn1cbiIsICJpbXBvcnQgeyBSUENSZXN1bHRTdGF0dXMgfSBmcm9tICcuLi9lbnVtcyc7XG5pbXBvcnQgeyBNYW5nb0Vycm9yIH0gZnJvbSAnLi9tYW5nby5lcnJvcic7XG5cbmV4cG9ydCBjbGFzcyBVbmtub3duRXJyb3IgZXh0ZW5kcyBNYW5nb0Vycm9yIHtcbiAgICBwdWJsaWMgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKCdVbmtub3duIGVycm9yLicsIFJQQ1Jlc3VsdFN0YXR1cy5Vbmtub3duKTtcbiAgICB9XG59XG4iLCAiaW1wb3J0IHsgV2ViVmlld0V2ZW50U2VydmljZSwgV2ViVmlld0xvZ2dlclNlcnZpY2UsIFdlYlZpZXdSUENTZXJ2aWNlIH0gZnJvbSAnLi9zZXJ2aWNlcyc7XG5pbXBvcnQgeyBpc05pbCB9IGZyb20gJ0ByYWdlbXAtbWFuZ28vY29yZS91dGlscyc7XG5pbXBvcnQgeyBSUENfUkVTVUxUX0hBTkRMRVJfTk9UX0ZPVU5ELCBSUENfUkVTVUxUX1VOS05PV04gfSBmcm9tICdAcmFnZW1wLW1hbmdvL2NvcmUvYXBwL2NvbnN0YW50cyc7XG5pbXBvcnQgeyBSUENSZXN1bHRTdGF0dXMgfSBmcm9tICdAcmFnZW1wLW1hbmdvL2NvcmUvZW51bXMnO1xuaW1wb3J0IHR5cGUgeyBMb2dnZXJTZXJ2aWNlLCBSUENSZXN1bHQgfSBmcm9tICdAcmFnZW1wLW1hbmdvL2NvcmUvaW50ZXJmYWNlcyc7XG5pbXBvcnQgeyBNYW5nb0Vycm9yIH0gZnJvbSAnQHJhZ2VtcC1tYW5nby9jb3JlL2Vycm9ycyc7XG5pbXBvcnQgdHlwZSB7IEV2ZW50U2VydmljZSwgUlBDU2VydmljZSB9IGZyb20gJy4vaW50ZXJmYWNlcyc7XG5cbmV4cG9ydCBmdW5jdGlvbiBpbml0TWFuZ28oKSB7XG4gICAgaWYgKCFpc05pbCh3aW5kb3cubWFuZ28pKSB7XG4gICAgICAgIHJldHVybiB3aW5kb3cubWFuZ287XG4gICAgfVxuXG4gICAgY29uc3QgZXZlbnQgPSBuZXcgV2ViVmlld0V2ZW50U2VydmljZSgpO1xuICAgIGNvbnN0IGxvZ2dlciA9IG5ldyBXZWJWaWV3TG9nZ2VyU2VydmljZSgpO1xuICAgIGNvbnN0IHJwYyA9IG5ldyBXZWJWaWV3UlBDU2VydmljZShldmVudCwgbG9nZ2VyKTtcblxuICAgICg8RXZlbnRTZXJ2aWNlPmV2ZW50KS5vblNlcnZlcignUlBDOjpDQUxMX1dFQlZJRVcnLCBhc3luYyAoYm9keSkgPT4ge1xuICAgICAgICBjb25zdCBpZCA9IGJvZHkuaWQ7XG4gICAgICAgIGNvbnN0IG5hbWUgPSBib2R5LnJwY05hbWU7XG4gICAgICAgIGNvbnN0IHBheWxvYWQgPSBib2R5LmJvZHk7XG5cbiAgICAgICAgY29uc3QgcnBjSGFuZGxlciA9IHJwYy4kc2VydmVySGFuZGxlcnMuZ2V0KG5hbWUpO1xuICAgICAgICBpZiAoIXJwY0hhbmRsZXIpIHtcbiAgICAgICAgICAgIGV2ZW50LmVtaXRTZXJ2ZXIoYFJQQzo6UkVUVVJOX0ZST01fV0VCVklFV18ke2lkfWAsIFJQQ19SRVNVTFRfSEFORExFUl9OT1RfRk9VTkQpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHJwY0hhbmRsZXIuaGFuZGxlcihwYXlsb2FkKTtcbiAgICAgICAgICAgIGNvbnN0IHJwY1Jlc3VsdDogUlBDUmVzdWx0ID0ge1xuICAgICAgICAgICAgICAgIHN1Y2Nlc3M6IHRydWUsXG4gICAgICAgICAgICAgICAgc3RhdHVzOiBSUENSZXN1bHRTdGF0dXMuU3VjY2VzcyxcbiAgICAgICAgICAgICAgICBib2R5OiByZXN1bHQsXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgZXZlbnQuZW1pdFNlcnZlcihgUlBDOjpSRVRVUk5fRlJPTV9XRUJWSUVXXyR7aWR9YCwgcnBjUmVzdWx0KTtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIE1hbmdvRXJyb3IpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBycGNSZXN1bHQ6IFJQQ1Jlc3VsdCA9IHtcbiAgICAgICAgICAgICAgICAgICAgc3VjY2VzczogZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgIHN0YXR1czogZXJyb3Iuc3RhdHVzLFxuICAgICAgICAgICAgICAgICAgICBlcnJvcjogeyBtZXNzYWdlOiBlcnJvci5tZXNzYWdlLCBkZXRhaWxzOiBlcnJvci5kZXRhaWxzIH0sXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBldmVudC5lbWl0U2VydmVyKGBSUEM6OlJFVFVSTl9GUk9NX1dFQlZJRVdfJHtpZH1gLCBycGNSZXN1bHQpO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgZXZlbnQuZW1pdFNlcnZlcihgUlBDOjpSRVRVUk5fRlJPTV9XRUJWSUVXXyR7aWR9YCwgUlBDX1JFU1VMVF9VTktOT1dOKTtcbiAgICAgICAgfVxuICAgIH0pO1xuICAgICg8RXZlbnRTZXJ2aWNlPmV2ZW50KS5vblBsYXllcignUlBDOjpDQUxMX1dFQlZJRVcnLCBhc3luYyAoYm9keSkgPT4ge1xuICAgICAgICBjb25zdCBpZCA9IGJvZHkuaWQ7XG4gICAgICAgIGNvbnN0IG5hbWUgPSBib2R5LnJwY05hbWU7XG4gICAgICAgIGNvbnN0IHBheWxvYWQgPSBib2R5LmJvZHk7XG5cbiAgICAgICAgY29uc3QgcnBjSGFuZGxlciA9IHJwYy4kY2xpZW50SGFuZGxlcnMuZ2V0KG5hbWUpO1xuICAgICAgICBpZiAoaXNOaWwocnBjSGFuZGxlcikpIHtcbiAgICAgICAgICAgIGV2ZW50LmVtaXRQbGF5ZXIoYFJQQzo6UkVUVVJOX0ZST01fV0VCVklFV18ke2lkfWAsIFJQQ19SRVNVTFRfSEFORExFUl9OT1RfRk9VTkQpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHJwY0hhbmRsZXIuaGFuZGxlcihwYXlsb2FkKTtcbiAgICAgICAgICAgIGNvbnN0IHJwY1Jlc3VsdDogUlBDUmVzdWx0ID0ge1xuICAgICAgICAgICAgICAgIHN1Y2Nlc3M6IHRydWUsXG4gICAgICAgICAgICAgICAgc3RhdHVzOiBSUENSZXN1bHRTdGF0dXMuU3VjY2VzcyxcbiAgICAgICAgICAgICAgICBib2R5OiByZXN1bHQsXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgZXZlbnQuZW1pdFBsYXllcihgUlBDOjpSRVRVUk5fRlJPTV9XRUJWSUVXXyR7aWR9YCwgcnBjUmVzdWx0KTtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIGV2ZW50LmVtaXRQbGF5ZXIoYFJQQzo6UkVUVVJOX0ZST01fV0VCVklFV18ke2lkfWAsIFJQQ19SRVNVTFRfVU5LTk9XTik7XG4gICAgICAgIH1cbiAgICB9KTtcblxuICAgIGNvbnN0IG1hbmdvID0geyBldmVudCwgcnBjLCBsb2dnZXIgfTtcblxuICAgIHdpbmRvdy5tYW5nbyA9IG1hbmdvO1xuXG4gICAgbG9nZ2VyLmxvZygnV2ViVmlldyBpbml0aWFsaXplZCcpO1xuXG4gICAgcmV0dXJuIG1hbmdvO1xufVxuXG5kZWNsYXJlIGdsb2JhbCB7XG4gICAgZXhwb3J0IGludGVyZmFjZSBXaW5kb3cge1xuICAgICAgICBtYW5nbzoge1xuICAgICAgICAgICAgZXZlbnQ6IEV2ZW50U2VydmljZTtcbiAgICAgICAgICAgIHJwYzogUlBDU2VydmljZTtcbiAgICAgICAgICAgIGxvZ2dlcjogTG9nZ2VyU2VydmljZTtcbiAgICAgICAgfTtcbiAgICB9XG59XG5cbmltcG9ydCAnLi9leHRlbnNpb24uZC50cyc7XG4iXSwKICAibWFwcGluZ3MiOiAiOzs7O0FBRU8sSUFBTUEsdUJBQU4sTUFBTUE7RUFBYixPQUFhQTs7O0VBQ0ZDLE9BQU9DLE1BQWlCO0FBQzNCQyxZQUFRRixJQUFJLDJCQUFrQixHQUFLQyxJQUFBQTtFQUN2QztFQUVPRSxTQUFTRixNQUFpQjtBQUM3QkMsWUFBUUMsTUFBTSw2QkFBb0IsR0FBS0YsSUFBQUE7RUFDM0M7RUFFT0csUUFBUUgsTUFBaUI7QUFDNUJDLFlBQVFFLEtBQUssNEJBQW1CLEdBQUtILElBQUFBO0VBQ3pDO0VBRU9JLFNBQVNKLE1BQWlCO0FBQzdCQyxZQUFRRyxNQUFNLDZCQUFvQixHQUFLSixJQUFBQTtFQUMzQztBQUNKOzs7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SUFBRUM7SUFBT0k7SUFBS0Y7RUFBTztBQUVuQ0osU0FBT0MsUUFBUUE7QUFFZkcsU0FBTzhCLElBQUkscUJBQUE7QUFFWCxTQUFPakM7QUFDWDtBQXpFZ0JIOyIsCiAgIm5hbWVzIjogWyJXZWJWaWV3TG9nZ2VyU2VydmljZSIsICJsb2ciLCAiYXJncyIsICJjb25zb2xlIiwgImVycm9yIiwgIndhcm4iLCAiZGVidWciLCAiV2ViVmlld0V2ZW50U2VydmljZSIsICIkbG9jYWxIYW5kbGVycyIsICJNYXAiLCAiJHJlbW90ZUhhbmRsZXJzIiwgIm9uIiwgImV2ZW50TmFtZSIsICJjYWxsYmFjayIsICJldmVudEhhbmRsZXIiLCAiZGVzdHJveSIsICJ2YWxpZCIsICJoYW5kbGVycyIsICJnZXQiLCAiZGVsZXRlIiwgImhhbmRsZXIiLCAibG9jYWwiLCAib25seU9uY2UiLCAicmVtb3RlIiwgImhhcyIsICJzZXQiLCAiU2V0IiwgImFkZCIsICJvbmNlIiwgImVtaXQiLCAiYm9keSIsICJsaXN0ZW5lcnMiLCAiZm9yRWFjaCIsICJzY3JpcHRFdmVudEhhbmRsZXIiLCAib25QbGF5ZXIiLCAid3JhcHBlciIsICJhcmdzIiwgIndpbmRvdyIsICJtcCIsICJldmVudHMiLCAib25jZVBsYXllciIsICJlbWl0UGxheWVyIiwgInRyaWdnZXIiLCAib25TZXJ2ZXIiLCAib25jZVNlcnZlciIsICJlbWl0U2VydmVyIiwgInBheWxvYWQiLCAiRXJyb3JNZXNzYWdlIiwgIlJQQ1Jlc3VsdFN0YXR1cyIsICJSUENfUkVTVUxUX1RJTUVPVVQiLCAic3VjY2VzcyIsICJlcnJvciIsICJtZXNzYWdlIiwgInN0YXR1cyIsICJSUENSZXN1bHRTdGF0dXMiLCAiVGltZW91dCIsICJSUENfUkVTVUxUX0hBTkRMRVJfTk9UX0ZPVU5EIiwgIkhhbmRsZXJOb3RGb3VuZCIsICJSUENfUkVTVUxUX1VOS05PV04iLCAiVW5rbm93biIsICJSUENfUkVTVUxUX1BMQVlFUl9ESVNDT05ORUNURUQiLCAiUGxheWVyRGlzY29ubmVjdGVkIiwgIlJQQ19SRVNVTFRfUExBWUVSX05PVF9GT1VORCIsICJQbGF5ZXJOb3RGb3VuZCIsICJfX2RlZlByb3AiLCAiX19uYW1lIiwgImdlbmVyYXRlUmFuZG9tSWQiLCAiTWF0aCIsICJyYW5kb20iLCAidG9TdHJpbmciLCAic3Vic3RyaW5nIiwgImlzVW5kZWZpbmVkIiwgIl9fbmFtZSIsICJvYmoiLCAiaXNOaWwiLCAiX19uYW1lIiwgInZhbCIsICJpc1VuZGVmaW5lZCIsICJFdmVudERlc3RpbmF0aW9uIiwgIldlYlZpZXdSUENTZXJ2aWNlIiwgIiRUSU1FT1VUIiwgIiRsb2NhbEhhbmRsZXJzIiwgIk1hcCIsICIkY2xpZW50SGFuZGxlcnMiLCAiJHNlcnZlckhhbmRsZXJzIiwgIiRldmVudFNlcnZpY2UiLCAiJGxvZ2dlclNlcnZpY2UiLCAiY2FsbCIsICJycGNOYW1lIiwgImJvZHkiLCAib3B0aW9ucyIsICJ0aW1lb3V0IiwgIlByb21pc2UiLCAicmVzb2x2ZSIsICJycGNIYW5kbGVyIiwgImdldCIsICJpc05pbCIsICJSUENfUkVTVUxUX0hBTkRMRVJfTk9UX0ZPVU5EIiwgInRpbWVvdXRJZCIsICJzZXRUaW1lb3V0IiwgIlJQQ19SRVNVTFRfVElNRU9VVCIsICJyZXN1bHQiLCAiaGFuZGxlciIsICJjbGVhclRpbWVvdXQiLCAic3VjY2VzcyIsICJzdGF0dXMiLCAiUlBDUmVzdWx0U3RhdHVzIiwgIlN1Y2Nlc3MiLCAiZXJyb3IiLCAidW5kZWZpbmVkIiwgIm9uUmVxdWVzdCIsICJoYXMiLCAiRXJyb3IiLCAiRXJyb3JNZXNzYWdlIiwgIlJQQ0hhbmRsZXJBbHJlYWR5RXhpc3RzIiwgImRlc3Ryb3kiLCAidmFsaWQiLCAiZGVsZXRlIiwgInNldCIsICJjYWxsU2VydmVyIiwgIiRoYW5kbGVDYWxsIiwgIkV2ZW50RGVzdGluYXRpb24iLCAiU2VydmVyIiwgIm9uU2VydmVyUmVxdWVzdCIsICJjYWxsUGxheWVyIiwgIkNsaWVudCIsICJvblBsYXllclJlcXVlc3QiLCAiZGVzdGluYXRpb24iLCAiY2FsbElkIiwgImdlbmVyYXRlUmFuZG9tSWQiLCAib25jZUhhbmRsZSIsICJzY3JpcHRFdmVudEhhbmRsZXIiLCAib25jZVNlcnZlciIsICJvbmNlUGxheWVyIiwgInBheWxvYWQiLCAic291cmNlIiwgIldlYlZpZXciLCAiaWQiLCAiZW1pdFBsYXllciIsICJNYW5nb0Vycm9yIiwgIkVycm9yIiwgInN0YXR1cyIsICJSUENSZXN1bHRTdGF0dXMiLCAiVW5rbm93biIsICJkZXRhaWxzIiwgIm1lc3NhZ2UiLCAiR3VhcmRDYW5jZWxFcnJvciIsICJDYW5jZWxsZWRCeUd1YXJkIiwgIkd1YXJkSW52YWxpZFJldHVybkVycm9yIiwgIkludmFsaWRHdWFyZFJldHVybiIsICJUb29NYW55UmVxdWVzdHMiLCAiVW5rbm93bkVycm9yIiwgImluaXRNYW5nbyIsICJpc05pbCIsICJ3aW5kb3ciLCAibWFuZ28iLCAiZXZlbnQiLCAiV2ViVmlld0V2ZW50U2VydmljZSIsICJsb2dnZXIiLCAiV2ViVmlld0xvZ2dlclNlcnZpY2UiLCAicnBjIiwgIldlYlZpZXdSUENTZXJ2aWNlIiwgIm9uU2VydmVyIiwgImJvZHkiLCAiaWQiLCAibmFtZSIsICJycGNOYW1lIiwgInBheWxvYWQiLCAicnBjSGFuZGxlciIsICIkc2VydmVySGFuZGxlcnMiLCAiZ2V0IiwgImVtaXRTZXJ2ZXIiLCAiUlBDX1JFU1VMVF9IQU5ETEVSX05PVF9GT1VORCIsICJyZXN1bHQiLCAiaGFuZGxlciIsICJycGNSZXN1bHQiLCAic3VjY2VzcyIsICJzdGF0dXMiLCAiUlBDUmVzdWx0U3RhdHVzIiwgIlN1Y2Nlc3MiLCAiZXJyb3IiLCAiTWFuZ29FcnJvciIsICJtZXNzYWdlIiwgImRldGFpbHMiLCAiUlBDX1JFU1VMVF9VTktOT1dOIiwgIm9uUGxheWVyIiwgIiRjbGllbnRIYW5kbGVycyIsICJlbWl0UGxheWVyIiwgImxvZyJdCn0K
package/package.json ADDED
@@ -0,0 +1,40 @@
1
+ {
2
+ "name": "@ragemp-mango/webview",
3
+ "version": "2.0.6-beta.0",
4
+ "homepage": "https://github.com/kkwlkk/ragemp-mango",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "https://github.com/kkwlkk/ragemp-mango",
8
+ "directory": "packages/webview"
9
+ },
10
+ "license": "MIT",
11
+ "author": "5exyGuy (Aurėjus Remeika), wlk (https://github.com/kkwlkk)",
12
+ "description": "Webview/CEF package for the RageMP Mango Framework - a decorator-driven TypeScript framework for RageMP servers.",
13
+ "type": "module",
14
+ "main": "dist/index.js",
15
+ "types": "dist/index.d.ts",
16
+ "files": [
17
+ "dist"
18
+ ],
19
+ "dependencies": {},
20
+ "devDependencies": {
21
+ "tsup": "^8.0.2",
22
+ "typescript": "^5.4.5",
23
+ "@abraham/reflection": "^0.12.0",
24
+ "@ragemp-mango/core": "^2.0.6-beta.0"
25
+ },
26
+ "peerDependencies": {
27
+ "@ragempcommunity/types-cef": "^2.1.8",
28
+ "@ragemp-mango/core": "^2.0.6-beta.0"
29
+ },
30
+ "publishConfig": {
31
+ "access": "public",
32
+ "registry": "https://registry.npmjs.org/"
33
+ },
34
+ "scripts": {
35
+ "build": "tsup",
36
+ "dev": "tsup --watch",
37
+ "typecheck": "tsc --noEmit",
38
+ "types": "tsup --dts-only"
39
+ }
40
+ }