@archont561/qgis-sdk 0.3.0 → 0.5.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/dist/index.js CHANGED
@@ -1,31 +1,418 @@
1
+ import {
2
+ isPlainRecord,
3
+ BRIDGE_PROTOCOL_VERSION2,
4
+ MAX_CALL_ID_LENGTH2,
5
+ QgisSdkBridgeProtocolError2,
6
+ QgisSdkBridgeTimeoutError2,
7
+ QgisSdkBridgeAbortedError2,
8
+ QgisSdkBridgeClosedError2,
9
+ QgisSdkBridgeSequenceError2,
10
+ QgisSdkBridgeStreamEndedError2,
11
+ QgisSdkBridgeRemoteError2,
12
+ parseInvokeReply2,
13
+ parseStreamFrame2,
14
+ BridgeClient2
15
+ } from "./shared/chunk-8gawbn19.js";
1
16
  import {
2
17
  MAX_SAFE_INTEGER2,
3
18
  MIN_SAFE_INTEGER2,
4
19
  PLUGIN_DESCRIPTION_SCHEMA_VERSION2,
5
20
  isSafeJsonInteger2,
6
- QgisSdkError2,
7
- QgisSdkScopeClosedError2,
8
- QgisSdkUnsupportedCapabilityError2,
9
21
  QgisSdkDeclarationError2,
10
22
  QgisSdkValidationIssue2,
11
23
  QgisSdkContractValidationError2,
12
- isPlainRecord2,
13
- parsePluginDescription2
14
- } from "./shared/chunk-0fknax6w.js";
24
+ parsePluginDescription2,
25
+ QgisSdkContractError2,
26
+ validateAgainstSchema2,
27
+ QgisSdkStoreError2,
28
+ OperationStore2,
29
+ stableKey2,
30
+ StreamStore2,
31
+ labelFor2,
32
+ schemaFields2,
33
+ FormStore2,
34
+ formStore2,
35
+ HostQueryStore2,
36
+ layersQuery2,
37
+ layerFieldsQuery2
38
+ } from "./shared/chunk-t1vpt5yq.js";
39
+ import {
40
+ HOST_OPERATIONS2,
41
+ createHost2
42
+ } from "./shared/chunk-stre69mw.js";
43
+ import {
44
+ QgisSdkError2
45
+ } from "./shared/chunk-2hwva3a3.js";
46
+ // src/processing.ts
47
+ async function runAlgorithm(qgis, id, params, options) {
48
+ const raw = await qgis.host.algorithms.run({ algorithm_id: id, params }, options);
49
+ return {
50
+ algorithm: raw.algorithm,
51
+ outputs: outputsByName(raw.outputs),
52
+ raw
53
+ };
54
+ }
55
+ function outputsByName(outputs) {
56
+ const result = {};
57
+ for (const output of outputs) {
58
+ if (output.kind === "vector")
59
+ result[output.name] = output.layer;
60
+ else if (output.kind === "file")
61
+ result[output.name] = output.file;
62
+ else
63
+ result[output.name] = output.value;
64
+ }
65
+ return result;
66
+ }
67
+ // src/webchannel.ts
68
+ class QgisSdkWebChannelError extends QgisSdkError2 {
69
+ constructor(message) {
70
+ super(message, "no_web_channel");
71
+ }
72
+ }
73
+ function scope() {
74
+ return globalThis;
75
+ }
76
+ function insideQgis() {
77
+ const page = scope();
78
+ return page.qt !== undefined && typeof page.QWebChannel === "function";
79
+ }
80
+ function createWebChannelTransport(objectName = "bridge") {
81
+ const page = scope();
82
+ const qt = page.qt;
83
+ const QWebChannel = page.QWebChannel;
84
+ if (qt === undefined || typeof QWebChannel !== "function") {
85
+ throw new QgisSdkWebChannelError("not inside a QGIS web view: window.qt is missing");
86
+ }
87
+ const listeners = new Set;
88
+ const queue = [];
89
+ let object = null;
90
+ let failure = null;
91
+ let closed = false;
92
+ const forward = (text) => {
93
+ if (closed) {
94
+ return;
95
+ }
96
+ let parsed;
97
+ try {
98
+ parsed = JSON.parse(text);
99
+ } catch {
100
+ return;
101
+ }
102
+ for (const listener of [...listeners]) {
103
+ listener(parsed);
104
+ }
105
+ };
106
+ const ready = new Promise((resolve, reject) => {
107
+ new QWebChannel(qt.webChannelTransport, (channel) => {
108
+ const found = channel.objects[objectName];
109
+ if (found === undefined) {
110
+ failure = new QgisSdkWebChannelError(`the host registered no ${JSON.stringify(objectName)} channel object`);
111
+ queue.length = 0;
112
+ reject(failure);
113
+ return;
114
+ }
115
+ if (closed) {
116
+ resolve();
117
+ return;
118
+ }
119
+ object = found;
120
+ found.message.connect(forward);
121
+ for (const text of queue.splice(0)) {
122
+ found.receive(text);
123
+ }
124
+ resolve();
125
+ });
126
+ });
127
+ return {
128
+ ready,
129
+ send(message) {
130
+ if (closed) {
131
+ throw new QgisSdkWebChannelError("the web channel transport is closed");
132
+ }
133
+ if (failure !== null) {
134
+ throw failure;
135
+ }
136
+ const text = JSON.stringify(message);
137
+ if (object === null) {
138
+ queue.push(text);
139
+ return;
140
+ }
141
+ object.receive(text);
142
+ },
143
+ subscribe(listener) {
144
+ listeners.add(listener);
145
+ return () => {
146
+ listeners.delete(listener);
147
+ };
148
+ },
149
+ close() {
150
+ if (closed) {
151
+ return;
152
+ }
153
+ closed = true;
154
+ queue.length = 0;
155
+ listeners.clear();
156
+ object?.message.disconnect(forward);
157
+ }
158
+ };
159
+ }
160
+
161
+ // src/qgis-sdk.ts
162
+ var QGIS_SDK_MEMBERS = Object.freeze([
163
+ "client",
164
+ "host",
165
+ "schema",
166
+ "ready",
167
+ "close"
168
+ ]);
169
+ var HOST_IDS = new Set(HOST_OPERATIONS2);
170
+ function parseHandshake(value) {
171
+ if (!isPlainRecord(value) || !Array.isArray(value.operations)) {
172
+ throw new QgisSdkBridgeProtocolError2("The handshake reply carries no operations list");
173
+ }
174
+ const operations = [];
175
+ for (const operation of value.operations) {
176
+ if (isPlainRecord(operation) && typeof operation.id === "string") {
177
+ operations.push(operation.id);
178
+ }
179
+ }
180
+ return {
181
+ operations,
182
+ granted: Object.freeze(operations.filter((id) => HOST_IDS.has(id))),
183
+ theme: parseTheme(value.theme)
184
+ };
185
+ }
186
+ function parseTheme(value) {
187
+ if (!isPlainRecord(value) || !isPlainRecord(value.palette)) {
188
+ return null;
189
+ }
190
+ const palette = {};
191
+ for (const [role, colour] of Object.entries(value.palette)) {
192
+ if (typeof colour === "string") {
193
+ palette[role] = colour;
194
+ }
195
+ }
196
+ return Object.freeze({
197
+ palette: Object.freeze(palette),
198
+ dark: value.dark === true
199
+ });
200
+ }
201
+ function unwrapRequest(operation, request) {
202
+ if (request === undefined) {
203
+ return {};
204
+ }
205
+ if (!isPlainRecord(request)) {
206
+ throw new QgisSdkContractError2(operation, "request", [
207
+ ...validateAgainstSchema2(request, { type: "object" })
208
+ ]);
209
+ }
210
+ return request;
211
+ }
212
+ function checkedRequest(description, request) {
213
+ const payload = unwrapRequest(description.id, request);
214
+ const issues = validateAgainstSchema2(payload, description.request);
215
+ if (issues.length > 0) {
216
+ throw new QgisSdkContractError2(description.id, "request", issues);
217
+ }
218
+ return payload;
219
+ }
220
+ function operationMethod(client, action) {
221
+ return async (request, options) => {
222
+ const payload = checkedRequest(action, request);
223
+ const value = await client.invoke(action.id, payload, options);
224
+ const issues = validateAgainstSchema2(value, action.result, {
225
+ allowUnknown: true
226
+ });
227
+ if (issues.length > 0) {
228
+ throw new QgisSdkContractError2(action.id, "result", issues);
229
+ }
230
+ return value;
231
+ };
232
+ }
233
+ function streamMethod(client, stream) {
234
+ return async (request, handlers, options) => {
235
+ const payload = checkedRequest(stream, request);
236
+ let ended = false;
237
+ let violated = false;
238
+ let handle = null;
239
+ const end = (terminal) => {
240
+ if (ended) {
241
+ return;
242
+ }
243
+ ended = true;
244
+ handlers.onTerminal?.(terminal);
245
+ };
246
+ handle = await client.subscribe(stream.id, payload, {
247
+ onEvent: (event) => {
248
+ if (ended) {
249
+ return;
250
+ }
251
+ const declared = stream.events[event.kind];
252
+ const issues = declared === undefined ? undefined : validateAgainstSchema2(event.payload, declared, {
253
+ allowUnknown: true,
254
+ path: ["payload"]
255
+ });
256
+ if (issues !== undefined && issues.length === 0) {
257
+ handlers.onEvent?.(event);
258
+ return;
259
+ }
260
+ const error = new QgisSdkContractError2(stream.id, "event", issues ?? []);
261
+ end({ kind: "error", message: error.message });
262
+ if (handle === null) {
263
+ violated = true;
264
+ } else {
265
+ handle.close();
266
+ }
267
+ },
268
+ onTerminal: end
269
+ }, options);
270
+ if (violated) {
271
+ handle.close();
272
+ }
273
+ return handle;
274
+ };
275
+ }
276
+ function buildHost(client, handshake) {
277
+ const host = createHost2(client);
278
+ return Object.freeze({
279
+ ...host,
280
+ get granted() {
281
+ return granted(handshake());
282
+ },
283
+ get theme() {
284
+ return handshake()?.theme ?? null;
285
+ }
286
+ });
287
+ }
288
+ var NO_GRANTS = Object.freeze([]);
289
+ function granted(handshake) {
290
+ return handshake === null ? NO_GRANTS : handshake.granted;
291
+ }
292
+ function build(schema, options) {
293
+ if (options.client !== undefined && options.transport !== undefined) {
294
+ throw new QgisSdkDeclarationError2("QgisSdk.fromBridgeSchema takes a client or a transport, not both");
295
+ }
296
+ const owned = options.client === undefined;
297
+ const transport = options.transport ?? (options.client === undefined ? createWebChannelTransport(options.channelObject ?? "bridge") : undefined);
298
+ const client = options.client ?? new BridgeClient2(transport, options.timeoutMs === undefined ? {} : { timeoutMs: options.timeoutMs });
299
+ let handshake = null;
300
+ const ready = client.handshake().then((value) => {
301
+ handshake = parseHandshake(value);
302
+ });
303
+ ready.catch(() => {
304
+ return;
305
+ });
306
+ const members = {
307
+ schema,
308
+ client,
309
+ host: buildHost(client, () => handshake),
310
+ ready,
311
+ close: () => {
312
+ if (owned) {
313
+ client.close();
314
+ }
315
+ }
316
+ };
317
+ const namespaces = [];
318
+ for (const action of schema.actions) {
319
+ place(members, namespaces, action.id, operationMethod(client, action));
320
+ }
321
+ for (const stream of schema.streams) {
322
+ place(members, namespaces, stream.id, streamMethod(client, stream));
323
+ }
324
+ for (const namespace of namespaces) {
325
+ Object.freeze(namespace);
326
+ }
327
+ return Object.freeze(members);
328
+ }
329
+ function place(members, namespaces, id, method) {
330
+ const segments = id.split(".");
331
+ if (segments.some((segment) => segment === "")) {
332
+ throw new QgisSdkDeclarationError2(`${id}: an operation id may not have an empty segment`);
333
+ }
334
+ const head = segments[0];
335
+ if (QGIS_SDK_MEMBERS.includes(head)) {
336
+ throw new QgisSdkDeclarationError2(`${id}: an operation id may not start with a QgisSdk member (${QGIS_SDK_MEMBERS.join(", ")})`);
337
+ }
338
+ let node = members;
339
+ for (const [index, segment] of segments.entries()) {
340
+ const prefix = segments.slice(0, index + 1).join(".");
341
+ const existing = node[segment];
342
+ if (index === segments.length - 1) {
343
+ if (existing !== undefined) {
344
+ throw new QgisSdkDeclarationError2(typeof existing === "function" ? `${id}: duplicate operation id` : `${id}: an operation id may not be a prefix of another declared id`);
345
+ }
346
+ node[segment] = method;
347
+ return;
348
+ }
349
+ if (existing === undefined) {
350
+ const namespace = {};
351
+ namespaces.push(namespace);
352
+ node[segment] = namespace;
353
+ node = namespace;
354
+ } else if (typeof existing === "function") {
355
+ throw new QgisSdkDeclarationError2(`${id}: ${prefix} is already an operation id; an id may not extend another`);
356
+ } else {
357
+ node = existing;
358
+ }
359
+ }
360
+ }
361
+ var QgisSdk;
362
+ ((QgisSdk) => {
363
+ function fromBridgeSchema(schema, options = {}) {
364
+ return build(schema, options);
365
+ }
366
+ QgisSdk.fromBridgeSchema = fromBridgeSchema;
367
+ })(QgisSdk ||= {});
368
+ // src/schema.ts
369
+ function defineBridgeSchema(input) {
370
+ return parsePluginDescription2(input);
371
+ }
15
372
  export {
373
+ BRIDGE_PROTOCOL_VERSION2 as BRIDGE_PROTOCOL_VERSION,
374
+ BridgeClient2 as BridgeClient,
375
+ FormStore2 as FormStore,
376
+ HostQueryStore2 as HostQueryStore,
377
+ MAX_CALL_ID_LENGTH2 as MAX_CALL_ID_LENGTH,
16
378
  MAX_SAFE_INTEGER2 as MAX_SAFE_INTEGER,
17
379
  MIN_SAFE_INTEGER2 as MIN_SAFE_INTEGER,
380
+ OperationStore2 as OperationStore,
18
381
  PLUGIN_DESCRIPTION_SCHEMA_VERSION2 as PLUGIN_DESCRIPTION_SCHEMA_VERSION,
382
+ QGIS_SDK_MEMBERS,
383
+ QgisSdk,
384
+ QgisSdkBridgeAbortedError2 as QgisSdkBridgeAbortedError,
385
+ QgisSdkBridgeClosedError2 as QgisSdkBridgeClosedError,
386
+ QgisSdkBridgeProtocolError2 as QgisSdkBridgeProtocolError,
387
+ QgisSdkBridgeRemoteError2 as QgisSdkBridgeRemoteError,
388
+ QgisSdkBridgeSequenceError2 as QgisSdkBridgeSequenceError,
389
+ QgisSdkBridgeStreamEndedError2 as QgisSdkBridgeStreamEndedError,
390
+ QgisSdkBridgeTimeoutError2 as QgisSdkBridgeTimeoutError,
391
+ QgisSdkContractError2 as QgisSdkContractError,
19
392
  QgisSdkContractValidationError2 as QgisSdkContractValidationError,
20
393
  QgisSdkDeclarationError2 as QgisSdkDeclarationError,
21
394
  QgisSdkError2 as QgisSdkError,
22
- QgisSdkScopeClosedError2 as QgisSdkScopeClosedError,
23
- QgisSdkUnsupportedCapabilityError2 as QgisSdkUnsupportedCapabilityError,
395
+ QgisSdkStoreError2 as QgisSdkStoreError,
24
396
  QgisSdkValidationIssue2 as QgisSdkValidationIssue,
25
- isPlainRecord2 as isPlainRecord,
397
+ QgisSdkWebChannelError,
398
+ StreamStore2 as StreamStore,
399
+ createWebChannelTransport,
400
+ defineBridgeSchema,
401
+ formStore2 as formStore,
402
+ insideQgis,
26
403
  isSafeJsonInteger2 as isSafeJsonInteger,
27
- parsePluginDescription2 as parsePluginDescription
404
+ labelFor2 as labelFor,
405
+ layerFieldsQuery2 as layerFieldsQuery,
406
+ layersQuery2 as layersQuery,
407
+ outputsByName,
408
+ parseInvokeReply2 as parseInvokeReply,
409
+ parsePluginDescription2 as parsePluginDescription,
410
+ parseStreamFrame2 as parseStreamFrame,
411
+ runAlgorithm,
412
+ schemaFields2 as schemaFields,
413
+ stableKey2 as stableKey,
414
+ validateAgainstSchema2 as validateAgainstSchema
28
415
  };
29
416
 
30
- //# debugId=B8E64E2D8764D48064756E2164756E21
31
- //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFtdLAogICJzb3VyY2VzQ29udGVudCI6IFsKICBdLAogICJtYXBwaW5ncyI6ICIiLAogICJkZWJ1Z0lkIjogIkI4RTY0RTJEODc2NEQ0ODA2NDc1NkUyMTY0NzU2RTIxIiwKICAibmFtZXMiOiBbXQp9
417
+ //# debugId=507C47A54A87BD1B64756E2164756E21
418
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsic3JjL3Byb2Nlc3NpbmcudHMiLCAic3JjL3dlYmNoYW5uZWwudHMiLCAic3JjL3FnaXMtc2RrLnRzIiwgInNyYy9zY2hlbWEudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbCiAgICAiLyoqXG4gKiBQcm9jZXNzaW5nIGZyb20gYSBwYWdlIChkZWNpc2lvbi02NCk6IHRoZSB2YWx1ZSBhbGlhc2VzIGEgZ2VuZXJhdGVkXG4gKiBgcHJvY2Vzc2luZy5zY2hlbWEudHNgIGFubm90YXRlcyB3aXRoLCBhbmQgYHJ1bkFsZ29yaXRobWAsIHdoaWNoIHNlbmRzIG9uZVxuICogYGFsZ29yaXRobXMucnVuYCBhbmQgcmVzaGFwZXMgdGhlIHRhZ2dlZCBvdXRwdXRzIGludG8gdGhlIHJlc3VsdCBvYmplY3QgdGhlXG4gKiBnZW5lcmF0ZWQgYDxQcm92aWRlcj48QWxnb3JpdGhtPlJlc3VsdGAgdHlwZSBzcGVsbHMuXG4gKlxuICogVGhlIHR5cGluZyBsaXZlcyBpbiB0aGUgZ2VuZXJhdGVkIG1vZHVsZSwgbm90IGhlcmU6IGBxZ2lzLXNkayBwcm9jZXNzaW5nXG4gKiBnZW5lcmF0ZWAgZW1pdHMgYW4gYEFsZ29yaXRobVJlZ2lzdHJ5YCBmb3IgdGhlIHByb3ZpZGVycyB0aGUgcHJvamVjdCBhc2tlZFxuICogZm9yIGFuZCBhIGBydW5BbGdvcml0aG1gIGJvdW5kIHRvIGl0LiBUaGlzIG1vZHVsZSBpcyBnZW5lcmljIG92ZXIgYW55IHN1Y2hcbiAqIHJlZ2lzdHJ5IHNvIHRoZSBicmlkZ2UgaXRzZWxmIHNoaXBzIG5vIGNhdGFsb2d1ZSAoZGVjaXNpb24tNDc6IHplcm8gcnVudGltZVxuICogZGF0YSB0aGF0IGdvZXMgc3RhbGUgd2l0aCBhIFFHSVMgcmVsZWFzZSkuXG4gKlxuICogVGhlIGhvc3QgdmFsaWRhdGVzIHRoZSBwYXJhbWV0ZXJzIGFnYWluc3QgdGhlIGFsZ29yaXRobSdzIG93biBkZXNjcmlwdGlvblxuICogYmVmb3JlIGFueXRoaW5nIHJ1bnM7IGEgbGF5ZXIgaW5wdXQgaXMgYW4gb3duZWQgbGF5ZXIgaWQsIGEgZmlsZSBpbnB1dCBpcyBhXG4gKiByZWYgdGhlIGhvc3QgbWludGVkIGZvciB0aGlzIHZpZXcsIGFuZCBhbiBvbWl0dGVkIGRlc3RpbmF0aW9uIGNvbWVzIGJhY2sgYXNcbiAqIGFuIG93bmVkIGxheWVyIG9yIGEgcmVhZGFibGUgcmVmLlxuICovXG5cbmltcG9ydCB0eXBlIHtcblx0RmlsZVJlZixcblx0SG9zdEludm9rZU9wdGlvbnMsXG5cdEhvc3RPcGVyYXRpb25zLFxuXHRSdW5PdXRwdXQsXG5cdFJ1blJlc3VsdCxcblx0VmVjdG9yTGF5ZXJJbmZvLFxufSBmcm9tIFwiLi9nZW5lcmF0ZWQvaG9zdFwiO1xuXG5leHBvcnQgdHlwZSB7XG5cdEFsZ29yaXRobUluZm8sXG5cdEFsZ29yaXRobVN1bW1hcnksXG5cdEZpbGVSZWYsXG5cdEhvc3RJbnZva2VPcHRpb25zLFxuXHRPdXRwdXRJbmZvLFxuXHRQYXJhbWV0ZXJJbmZvLFxuXHRQcm92aWRlckluZm8sXG5cdFJ1bk91dHB1dCxcblx0UnVuUmVzdWx0LFxuXHRWZWN0b3JMYXllckluZm8sXG59IGZyb20gXCIuL2dlbmVyYXRlZC9ob3N0XCI7XG5cbi8qKiBBIGxheWVyIGlucHV0OiB0aGUgaWQgb2YgYSBsYXllciB0aGUgaG9zdCBvd25zLCBvciBhIHJlZiB0aGUgdmlldyBob2xkcy4gKi9cbmV4cG9ydCB0eXBlIExheWVyUmVmID0gc3RyaW5nIHwgRmlsZVJlZjtcbi8qKiBXaGVyZSBhbiBvdXRwdXQgZ29lczogYSB3cml0YWJsZSByZWYsIG9yIGBudWxsYCB0byBsZXQgdGhlIGhvc3QgYWxsb2NhdGUgb25lLiAqL1xuZXhwb3J0IHR5cGUgRGVzdGluYXRpb24gPSBGaWxlUmVmIHwgbnVsbDtcbi8qKiBgXCJ4bWluLHhtYXgseW1pbix5bWF4IFtjcnNdXCJgIGFzIFFHSVMgd3JpdGVzIGl0LCBvciB0aGUgZm91ciBudW1iZXJzLiAqL1xuZXhwb3J0IHR5cGUgRXh0ZW50ID0gc3RyaW5nIHwgcmVhZG9ubHkgW251bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlcl07XG4vKiogYFwieCx5IFtjcnNdXCJgIG9yIHRoZSB0d28gbnVtYmVycy4gKi9cbmV4cG9ydCB0eXBlIFBvaW50VmFsdWUgPSBzdHJpbmcgfCByZWFkb25seSBbbnVtYmVyLCBudW1iZXJdO1xuLyoqIGBbbG93ZXIsIHVwcGVyXWAuICovXG5leHBvcnQgdHlwZSBSYW5nZVZhbHVlID0gcmVhZG9ubHkgW251bWJlciwgbnVtYmVyXTtcblxuLyoqXG4gKiBXaGF0IGEgZ2VuZXJhdGVkIGBBbGdvcml0aG1SZWdpc3RyeWAgaXM6IHBhcmFtcyBhbmQgcmVzdWx0IHBlciBhbGdvcml0aG0gaWQuXG4gKiBTcGVsbGVkIGFzIGEgbWFwcGVkIGNvbnN0cmFpbnQgb3ZlciB0aGUgcmVnaXN0cnkgaXRzZWxmIHNvIGFuIGBpbnRlcmZhY2VgXG4gKiAod2hpY2ggaGFzIG5vIGltcGxpY2l0IGluZGV4IHNpZ25hdHVyZSkgc2F0aXNmaWVzIGl0LlxuICovXG5leHBvcnQgdHlwZSBBbGdvcml0aG1SZWdpc3RyeUxpa2U8Uj4gPSB7XG5cdHJlYWRvbmx5IFtLIGluIGtleW9mIFJdOiB7IHJlYWRvbmx5IHBhcmFtczogb2JqZWN0OyByZWFkb25seSByZXN1bHQ6IG9iamVjdCB9O1xufTtcblxuLyoqIFRoZSBwYXJ0IG9mIGEgYFFnaXNTZGtgIChvciBhbnl0aGluZyBlbHNlKSBgcnVuQWxnb3JpdGhtYCBuZWVkcy4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQWxnb3JpdGhtSG9zdCB7XG5cdHJlYWRvbmx5IGhvc3Q6IFBpY2s8SG9zdE9wZXJhdGlvbnMsIFwiYWxnb3JpdGhtc1wiPjtcbn1cblxuLyoqIE9uZSBydW4gYXMgdGhlIHBhZ2Ugc2VlcyBpdDogdGhlIG91dHB1dHMgYnkgbmFtZSwgcGx1cyB0aGUgcmVwbHkgYXMgaXQgY3Jvc3NlZC4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQWxnb3JpdGhtUnVuPFJlc3VsdCBleHRlbmRzIG9iamVjdD4ge1xuXHRyZWFkb25seSBhbGdvcml0aG06IHN0cmluZztcblx0cmVhZG9ubHkgb3V0cHV0czogUmVzdWx0O1xuXHRyZWFkb25seSByYXc6IFJ1blJlc3VsdDtcbn1cblxuLyoqXG4gKiBSdW4gYGlkYCB3aXRoIGBwYXJhbXNgIHRocm91Z2ggYHFnaXMuaG9zdC5hbGdvcml0aG1zLnJ1bmAgYW5kIHJlc2hhcGUgdGhlXG4gKiByZXBseTogYSBgdmVjdG9yYCBvdXRwdXQgYmVjb21lcyBpdHMgYFZlY3RvckxheWVySW5mb2AsIGEgYGZpbGVgIG91dHB1dCBpdHNcbiAqIGBGaWxlUmVmYCwgYSBgdmFsdWVgIG91dHB1dCB0aGUgc2NhbGFyIC0ga2V5ZWQgYnkgb3V0cHV0IG5hbWUsIHdoaWNoIGlzIHdoYXRcbiAqIHRoZSBnZW5lcmF0ZWQgYC4uLlJlc3VsdGAgaW50ZXJmYWNlcyBkZWNsYXJlLlxuICpcbiAqIEJvdGggdHlwZSBwYXJhbWV0ZXJzIGFyZSBtZWFudCB0byBiZSBib3VuZCBieSB0aGUgZ2VuZXJhdGVkIG1vZHVsZSdzIG93blxuICogYHJ1bkFsZ29yaXRobWA7IGNhbGxpbmcgdGhpcyBvbmUgZGlyZWN0bHkgbmVlZHMgdGhlbSBzcGVsbGVkIG91dC5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHJ1bkFsZ29yaXRobTxcblx0UiBleHRlbmRzIEFsZ29yaXRobVJlZ2lzdHJ5TGlrZTxSPixcblx0SyBleHRlbmRzIGtleW9mIFIgJiBzdHJpbmcsXG4+KFxuXHRxZ2lzOiBBbGdvcml0aG1Ib3N0LFxuXHRpZDogSyxcblx0cGFyYW1zOiBSW0tdW1wicGFyYW1zXCJdLFxuXHRvcHRpb25zPzogSG9zdEludm9rZU9wdGlvbnMsXG4pOiBQcm9taXNlPEFsZ29yaXRobVJ1bjxSW0tdW1wicmVzdWx0XCJdPj4ge1xuXHRjb25zdCByYXcgPSBhd2FpdCBxZ2lzLmhvc3QuYWxnb3JpdGhtcy5ydW4oXG5cdFx0eyBhbGdvcml0aG1faWQ6IGlkLCBwYXJhbXM6IHBhcmFtcyBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiB9LFxuXHRcdG9wdGlvbnMsXG5cdCk7XG5cdHJldHVybiB7XG5cdFx0YWxnb3JpdGhtOiByYXcuYWxnb3JpdGhtLFxuXHRcdG91dHB1dHM6IG91dHB1dHNCeU5hbWUocmF3Lm91dHB1dHMpIGFzIFJbS11bXCJyZXN1bHRcIl0sXG5cdFx0cmF3LFxuXHR9O1xufVxuXG4vKiogVW53cmFwIGEgdGFnZ2VkIG91dHB1dCBsaXN0IGludG8gYHsgW25hbWVdOiBsYXllciB8IHJlZiB8IHZhbHVlIH1gLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG91dHB1dHNCeU5hbWUoXG5cdG91dHB1dHM6IHJlYWRvbmx5IFJ1bk91dHB1dFtdLFxuKTogUmVjb3JkPFxuXHRzdHJpbmcsXG5cdFZlY3RvckxheWVySW5mbyB8IEZpbGVSZWYgfCBzdHJpbmcgfCBudW1iZXIgfCBib29sZWFuIHwgbnVsbCB8IHVuZGVmaW5lZFxuPiB7XG5cdGNvbnN0IHJlc3VsdDogUmVjb3JkPFxuXHRcdHN0cmluZyxcblx0XHRWZWN0b3JMYXllckluZm8gfCBGaWxlUmVmIHwgc3RyaW5nIHwgbnVtYmVyIHwgYm9vbGVhbiB8IG51bGwgfCB1bmRlZmluZWRcblx0PiA9IHt9O1xuXHRmb3IgKGNvbnN0IG91dHB1dCBvZiBvdXRwdXRzKSB7XG5cdFx0aWYgKG91dHB1dC5raW5kID09PSBcInZlY3RvclwiKSByZXN1bHRbb3V0cHV0Lm5hbWVdID0gb3V0cHV0LmxheWVyO1xuXHRcdGVsc2UgaWYgKG91dHB1dC5raW5kID09PSBcImZpbGVcIikgcmVzdWx0W291dHB1dC5uYW1lXSA9IG91dHB1dC5maWxlO1xuXHRcdGVsc2UgcmVzdWx0W291dHB1dC5uYW1lXSA9IG91dHB1dC52YWx1ZTtcblx0fVxuXHRyZXR1cm4gcmVzdWx0O1xufVxuIiwKICAgICIvKipcbiAqIFRoZSBkZWZhdWx0IHRyYW5zcG9ydDogUXQncyBXZWJDaGFubmVsLCBhcyBhIFFHSVMgd2ViIHZpZXcgaW5qZWN0cyBpdC5cbiAqXG4gKiBRR0lTIHJlZ2lzdGVycyBvbmUgb2JqZWN0IG9uIHRoZSBjaGFubmVsICh0aGUgZXhhbXBsZSBuYW1lcyBpdCBcImJyaWRnZVwiO1xuICogc2VlIGBjcmVhdGVfY2hhbm5lbF9vYmplY3RgIGluIHRoZSBQeXRob24gcnVudGltZSkuIEl0cyBgcmVjZWl2ZWAgc2xvdCB0YWtlc1xuICogYSBKU09OIGVudmVsb3BlIGFuZCBpdHMgYG1lc3NhZ2VgIHNpZ25hbCBjYXJyaWVzIGV2ZXJ5IHJlcGx5IGFuZCBzdHJlYW1cbiAqIGZyYW1lIGJhY2suIFRoZSBjaGFubmVsIGJlY29tZXMgcmVhZHkgb24gYSBsYXRlciB0dXJuLCBzbyB0aGlzIHRyYW5zcG9ydFxuICogaXMgbGF6eTogYSBgUWdpc1Nka2AgYnVpbHQgaW4gdGhlIGZpcnN0IHN0YXRlbWVudCBvZiBhIHBhZ2UgY2FuIHNlbmQgYXRcbiAqIG9uY2UsIGFuZCB3aGF0IGl0IHNlbnQgaXMgZGVsaXZlcmVkIHdoZW4gdGhlIGNoYW5uZWwgcmVwb3J0cyByZWFkeS5cbiAqXG4gKiBUaGlzIGlzIHRoZSBvbmUgbW9kdWxlIG9mIHRoZSByb290IGVudHJ5IHBvaW50IHRoYXQgcmVhZHMgYSBicm93c2VyIGdsb2JhbCxcbiAqIGFuZCBpdCBvbmx5IGRvZXMgc28gd2hlbiBjYWxsZWQ6IGltcG9ydGluZyBpdCB0b3VjaGVzIG5vdGhpbmcsIGFuZCBhIHBhZ2VcbiAqIHRoYXQgaXMgbm90IGluc2lkZSBRR0lTIGdldHMgYSBzeW5jaHJvbm91cywgbmFtZWQgcmVmdXNhbCBpbnN0ZWFkIG9mIGEgaGFuZy5cbiAqL1xuXG5pbXBvcnQgdHlwZSB7IFdpcmVUcmFuc3BvcnQgfSBmcm9tIFwiLi9icmlkZ2VcIjtcbmltcG9ydCB7IFFnaXNTZGtFcnJvciB9IGZyb20gXCIuL2Vycm9yc1wiO1xuXG5pbnRlcmZhY2UgQ2hhbm5lbE9iamVjdCB7XG5cdHJlY2VpdmUodGV4dDogc3RyaW5nKTogdm9pZDtcblx0cmVhZG9ubHkgbWVzc2FnZToge1xuXHRcdGNvbm5lY3QobGlzdGVuZXI6ICh0ZXh0OiBzdHJpbmcpID0+IHZvaWQpOiB2b2lkO1xuXHRcdGRpc2Nvbm5lY3QobGlzdGVuZXI6ICh0ZXh0OiBzdHJpbmcpID0+IHZvaWQpOiB2b2lkO1xuXHR9O1xufVxuXG5pbnRlcmZhY2UgQ2hhbm5lbCB7XG5cdHJlYWRvbmx5IG9iamVjdHM6IFJlYWRvbmx5PFJlY29yZDxzdHJpbmcsIENoYW5uZWxPYmplY3QgfCB1bmRlZmluZWQ+Pjtcbn1cblxuaW50ZXJmYWNlIFF0U2NvcGUge1xuXHRyZWFkb25seSBxdD86IHsgcmVhZG9ubHkgd2ViQ2hhbm5lbFRyYW5zcG9ydDogdW5rbm93biB9O1xuXHRyZWFkb25seSBRV2ViQ2hhbm5lbD86IG5ldyAoXG5cdFx0dHJhbnNwb3J0OiB1bmtub3duLFxuXHRcdHJlYWR5OiAoY2hhbm5lbDogQ2hhbm5lbCkgPT4gdm9pZCxcblx0KSA9PiB1bmtub3duO1xufVxuXG4vKiogVGhlIHdlYiB2aWV3IGRpZCBub3QgcHJvdmlkZSBhIHVzYWJsZSBjaGFubmVsLiAqL1xuZXhwb3J0IGNsYXNzIFFnaXNTZGtXZWJDaGFubmVsRXJyb3IgZXh0ZW5kcyBRZ2lzU2RrRXJyb3Ige1xuXHRwdWJsaWMgY29uc3RydWN0b3IobWVzc2FnZTogc3RyaW5nKSB7XG5cdFx0c3VwZXIobWVzc2FnZSwgXCJub193ZWJfY2hhbm5lbFwiKTtcblx0fVxufVxuXG4vKiogVGhlIHRyYW5zcG9ydCB7QGxpbmsgY3JlYXRlV2ViQ2hhbm5lbFRyYW5zcG9ydH0gcmV0dXJucy4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgV2ViQ2hhbm5lbFRyYW5zcG9ydCBleHRlbmRzIFdpcmVUcmFuc3BvcnQge1xuXHQvKiogUmVzb2x2ZXMgb25jZSB0aGUgY2hhbm5lbCBvYmplY3QgYW5zd2VyZWQ7IHJlamVjdHMgd2hlbiBpdCBuZXZlciB3aWxsLiAqL1xuXHRyZWFkb25seSByZWFkeTogUHJvbWlzZTx2b2lkPjtcblx0LyoqIFN0b3AgZm9yd2FyZGluZyBtZXNzYWdlczsgc2VuZHMgYWZ0ZXIgdGhpcyB0aHJvdy4gKi9cblx0Y2xvc2UoKTogdm9pZDtcbn1cblxuZnVuY3Rpb24gc2NvcGUoKTogUXRTY29wZSB7XG5cdHJldHVybiBnbG9iYWxUaGlzIGFzIHVua25vd24gYXMgUXRTY29wZTtcbn1cblxuLyoqIFRydWUgaW5zaWRlIGEgUUdJUyB3ZWIgdmlldywgd2hlcmUgUXQgaW5qZWN0ZWQgaXRzIHRyYW5zcG9ydCBhbmQgc2NyaXB0LiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGluc2lkZVFnaXMoKTogYm9vbGVhbiB7XG5cdGNvbnN0IHBhZ2UgPSBzY29wZSgpO1xuXHRyZXR1cm4gcGFnZS5xdCAhPT0gdW5kZWZpbmVkICYmIHR5cGVvZiBwYWdlLlFXZWJDaGFubmVsID09PSBcImZ1bmN0aW9uXCI7XG59XG5cbi8qKlxuICogQ29ubmVjdCB0byB0aGUgY2hhbm5lbCBvYmplY3QgYG9iamVjdE5hbWVgIGFuZCByZXR1cm4gYSB0cmFuc3BvcnQgb24gaXQuXG4gKlxuICogVGhyb3dzIHtAbGluayBRZ2lzU2RrV2ViQ2hhbm5lbEVycm9yfSBzeW5jaHJvbm91c2x5IG91dHNpZGUgYSBRR0lTIHdlYiB2aWV3LFxuICogc28gYSBwYWdlIGxlYXJucyBpbiBpdHMgZmlyc3Qgc3RhdGVtZW50IHRoYXQgaXQgaGFzIG5vIGhvc3QgdG8gdGFsayB0by5cbiAqIEluc2lkZSBvbmUsIG1lc3NhZ2VzIHNlbnQgYmVmb3JlIHRoZSBjaGFubmVsIGlzIHJlYWR5IGFyZSBxdWV1ZWQgYW5kXG4gKiBkZWxpdmVyZWQgaW4gb3JkZXIgb25jZSBpdCBpczsgYHJlYWR5YCByZWplY3RzIChhbmQgcXVldWVkIHNlbmRzIGFyZVxuICogZHJvcHBlZCkgd2hlbiB0aGUgaG9zdCByZWdpc3RlcmVkIG5vIG9iamVjdCB1bmRlciB0aGF0IG5hbWUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVXZWJDaGFubmVsVHJhbnNwb3J0KFxuXHRvYmplY3ROYW1lID0gXCJicmlkZ2VcIixcbik6IFdlYkNoYW5uZWxUcmFuc3BvcnQge1xuXHRjb25zdCBwYWdlID0gc2NvcGUoKTtcblx0Y29uc3QgcXQgPSBwYWdlLnF0O1xuXHRjb25zdCBRV2ViQ2hhbm5lbCA9IHBhZ2UuUVdlYkNoYW5uZWw7XG5cdGlmIChxdCA9PT0gdW5kZWZpbmVkIHx8IHR5cGVvZiBRV2ViQ2hhbm5lbCAhPT0gXCJmdW5jdGlvblwiKSB7XG5cdFx0dGhyb3cgbmV3IFFnaXNTZGtXZWJDaGFubmVsRXJyb3IoXG5cdFx0XHRcIm5vdCBpbnNpZGUgYSBRR0lTIHdlYiB2aWV3OiB3aW5kb3cucXQgaXMgbWlzc2luZ1wiLFxuXHRcdCk7XG5cdH1cblx0Y29uc3QgbGlzdGVuZXJzID0gbmV3IFNldDwobWVzc2FnZTogdW5rbm93bikgPT4gdm9pZD4oKTtcblx0Y29uc3QgcXVldWU6IHN0cmluZ1tdID0gW107XG5cdGxldCBvYmplY3Q6IENoYW5uZWxPYmplY3QgfCBudWxsID0gbnVsbDtcblx0bGV0IGZhaWx1cmU6IFFnaXNTZGtXZWJDaGFubmVsRXJyb3IgfCBudWxsID0gbnVsbDtcblx0bGV0IGNsb3NlZCA9IGZhbHNlO1xuXHRjb25zdCBmb3J3YXJkID0gKHRleHQ6IHN0cmluZyk6IHZvaWQgPT4ge1xuXHRcdGlmIChjbG9zZWQpIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cdFx0bGV0IHBhcnNlZDogdW5rbm93bjtcblx0XHR0cnkge1xuXHRcdFx0cGFyc2VkID0gSlNPTi5wYXJzZSh0ZXh0KTtcblx0XHR9IGNhdGNoIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cdFx0Zm9yIChjb25zdCBsaXN0ZW5lciBvZiBbLi4ubGlzdGVuZXJzXSkge1xuXHRcdFx0bGlzdGVuZXIocGFyc2VkKTtcblx0XHR9XG5cdH07XG5cdGNvbnN0IHJlYWR5ID0gbmV3IFByb21pc2U8dm9pZD4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuXHRcdG5ldyBRV2ViQ2hhbm5lbChxdC53ZWJDaGFubmVsVHJhbnNwb3J0LCAoY2hhbm5lbCkgPT4ge1xuXHRcdFx0Y29uc3QgZm91bmQgPSBjaGFubmVsLm9iamVjdHNbb2JqZWN0TmFtZV07XG5cdFx0XHRpZiAoZm91bmQgPT09IHVuZGVmaW5lZCkge1xuXHRcdFx0XHRmYWlsdXJlID0gbmV3IFFnaXNTZGtXZWJDaGFubmVsRXJyb3IoXG5cdFx0XHRcdFx0YHRoZSBob3N0IHJlZ2lzdGVyZWQgbm8gJHtKU09OLnN0cmluZ2lmeShvYmplY3ROYW1lKX0gY2hhbm5lbCBvYmplY3RgLFxuXHRcdFx0XHQpO1xuXHRcdFx0XHRxdWV1ZS5sZW5ndGggPSAwO1xuXHRcdFx0XHRyZWplY3QoZmFpbHVyZSk7XG5cdFx0XHRcdHJldHVybjtcblx0XHRcdH1cblx0XHRcdGlmIChjbG9zZWQpIHtcblx0XHRcdFx0cmVzb2x2ZSgpO1xuXHRcdFx0XHRyZXR1cm47XG5cdFx0XHR9XG5cdFx0XHRvYmplY3QgPSBmb3VuZDtcblx0XHRcdGZvdW5kLm1lc3NhZ2UuY29ubmVjdChmb3J3YXJkKTtcblx0XHRcdGZvciAoY29uc3QgdGV4dCBvZiBxdWV1ZS5zcGxpY2UoMCkpIHtcblx0XHRcdFx0Zm91bmQucmVjZWl2ZSh0ZXh0KTtcblx0XHRcdH1cblx0XHRcdHJlc29sdmUoKTtcblx0XHR9KTtcblx0fSk7XG5cdHJldHVybiB7XG5cdFx0cmVhZHksXG5cdFx0c2VuZChtZXNzYWdlOiB1bmtub3duKTogdm9pZCB7XG5cdFx0XHRpZiAoY2xvc2VkKSB7XG5cdFx0XHRcdHRocm93IG5ldyBRZ2lzU2RrV2ViQ2hhbm5lbEVycm9yKFwidGhlIHdlYiBjaGFubmVsIHRyYW5zcG9ydCBpcyBjbG9zZWRcIik7XG5cdFx0XHR9XG5cdFx0XHRpZiAoZmFpbHVyZSAhPT0gbnVsbCkge1xuXHRcdFx0XHR0aHJvdyBmYWlsdXJlO1xuXHRcdFx0fVxuXHRcdFx0Y29uc3QgdGV4dCA9IEpTT04uc3RyaW5naWZ5KG1lc3NhZ2UpO1xuXHRcdFx0aWYgKG9iamVjdCA9PT0gbnVsbCkge1xuXHRcdFx0XHRxdWV1ZS5wdXNoKHRleHQpO1xuXHRcdFx0XHRyZXR1cm47XG5cdFx0XHR9XG5cdFx0XHRvYmplY3QucmVjZWl2ZSh0ZXh0KTtcblx0XHR9LFxuXHRcdHN1YnNjcmliZShsaXN0ZW5lcjogKG1lc3NhZ2U6IHVua25vd24pID0+IHZvaWQpOiAoKSA9PiB2b2lkIHtcblx0XHRcdGxpc3RlbmVycy5hZGQobGlzdGVuZXIpO1xuXHRcdFx0cmV0dXJuICgpID0+IHtcblx0XHRcdFx0bGlzdGVuZXJzLmRlbGV0ZShsaXN0ZW5lcik7XG5cdFx0XHR9O1xuXHRcdH0sXG5cdFx0Y2xvc2UoKTogdm9pZCB7XG5cdFx0XHRpZiAoY2xvc2VkKSB7XG5cdFx0XHRcdHJldHVybjtcblx0XHRcdH1cblx0XHRcdGNsb3NlZCA9IHRydWU7XG5cdFx0XHRxdWV1ZS5sZW5ndGggPSAwO1xuXHRcdFx0bGlzdGVuZXJzLmNsZWFyKCk7XG5cdFx0XHRvYmplY3Q/Lm1lc3NhZ2UuZGlzY29ubmVjdChmb3J3YXJkKTtcblx0XHR9LFxuXHR9O1xufVxuIiwKICAgICIvKipcbiAqIGBRZ2lzU2RrYDogdGhlIHBhZ2Utc2lkZSBvYmplY3QgYSBwbHVnaW4ncyB3ZWIgdmlldyB0YWxrcyB0byBRR0lTIHRocm91Z2guXG4gKlxuICogVGhyZWUgc3RhdGVtZW50cyBjb25uZWN0IGEgcGFnZSAoZGVjaXNpb24tNDQpOlxuICpcbiAqIGBgYHRzXG4gKiBpbXBvcnQgc2NoZW1hIGZyb20gXCIuL2JyaWRnZS5zY2hlbWFcIjtcbiAqIGNvbnN0IHFnaXMgPSBRZ2lzU2RrLmZyb21CcmlkZ2VTY2hlbWEoc2NoZW1hKTtcbiAqIGF3YWl0IHFnaXMuc2l0ZXMuc3VtbWFyeSh7IGxheWVyX2lkIH0pO1xuICogYGBgXG4gKlxuICogVGhlIHNjaGVtYSBpcyB0aGUgZ2VuZXJhdGVkIGBicmlkZ2Uuc2NoZW1hLnRzYDogdGhlIHBsdWdpbiBkZXNjcmlwdGlvbiBwbHVzXG4gKiBpdHMgYE9wZXJhdGlvbnNgIGFuZCBgU3RyZWFtc2AgdHlwZXMuIEZyb20gdGhlIGRlc2NyaXB0aW9uIHRoZSBTREsgYnVpbGRzXG4gKiBvbmUgbWV0aG9kIHBlciBkZWNsYXJlZCBhY3Rpb24gYW5kIHN0cmVhbSwgbmVzdGVkIHVuZGVyIHRoZSBzZWdtZW50cyBvZiBpdHNcbiAqIGlkIChgc2l0ZXMuc3VtbWFyeWAgaXMgYHFnaXMuc2l0ZXMuc3VtbWFyeWAsIGBidWZmZXJgIGlzIGBxZ2lzLmJ1ZmZlcmApLFxuICogYW5kIGNoZWNrcyBldmVyeSBhcmd1bWVudCwgcmVwbHkgYW5kIGV2ZW50IGFnYWluc3QgdGhlIGRlY2xhcmVkIHNjaGVtYXNcbiAqIHdpdGggdGhlIHNhbWUgcnVsZXMgdGhlIGhvc3QgYXBwbGllcyAoYHZhbGlkYXRlLnRzYCkuIEZyb20gdGhlIHR5cGVzIGl0IGdpdmVzIHRob3NlXG4gKiBtZXRob2RzIHRoZWlyIHNpZ25hdHVyZXMsIHNvIGEgd3JvbmcgYXJndW1lbnQgc2hhcGUgb3IgYW4gdW5rbm93biBvcGVyYXRpb25cbiAqIGlzIGEgY29tcGlsZSBlcnJvciBhbmQgYSB2YWx1ZSBvdXRzaWRlIHRoZSBzY2hlbWEgYXQgcnVuIHRpbWUgaXMgYVxuICoge0BsaW5rIFFnaXNTZGtDb250cmFjdEVycm9yfS5cbiAqXG4gKiBgaG9zdGAgaXMgdGhlIGN1cmF0ZWQgaG9zdCBzdXJmYWNlIG9mIGRlY2lzaW9uLTI3LCBidWlsdCBvbiB0aGUgc2FtZSBjbGllbnQsXG4gKiBwbHVzIGBncmFudGVkYDogdGhlIGhvc3Qgb3BlcmF0aW9uIGlkcyB0aGUgaGFuZHNoYWtlIGFkdmVydGlzZWQgZm9yIHRoaXNcbiAqIHZpZXcuIEEgY2FsbCBvdXRzaWRlIHRoZSBncmFudHMgaXMgbm90IHJlZnVzZWQgaGVyZSAtIHRoZSBob3N0IHJlZnVzZXMgaXQsXG4gKiBhbmQgdGhlIHBhZ2Ugc2VlcyB0aGUgaG9zdCdzIGBub3RfYXV0aG9yaXplZGAgLSBidXQgYSBwYWdlIGNhbiByZWFkIGBncmFudGVkYFxuICogYWZ0ZXIgYHJlYWR5YCB0byBoaWRlIHdoYXQgaXQgbWF5IG5vdCB1c2UuXG4gKi9cblxuaW1wb3J0IHtcblx0QnJpZGdlQ2xpZW50LFxuXHR0eXBlIEJyaWRnZVN0cmVhbVRlcm1pbmFsLFxuXHR0eXBlIEJyaWRnZVN1YnNjcmlwdGlvbixcblx0dHlwZSBJbnZva2VPcHRpb25zLFxuXHRRZ2lzU2RrQnJpZGdlUHJvdG9jb2xFcnJvcixcblx0dHlwZSBXaXJlVHJhbnNwb3J0LFxufSBmcm9tIFwiLi9icmlkZ2VcIjtcbmltcG9ydCB7XG5cdHR5cGUgQWN0aW9uRGVzY3JpcHRpb24sXG5cdFFnaXNTZGtEZWNsYXJhdGlvbkVycm9yLFxuXHR0eXBlIFN0cmVhbURlc2NyaXB0aW9uLFxufSBmcm9tIFwiLi9kZWNsYXJhdGlvbnNcIjtcbmltcG9ydCB7XG5cdGNyZWF0ZUhvc3QsXG5cdEhPU1RfT1BFUkFUSU9OUyxcblx0dHlwZSBIb3N0T3BlcmF0aW9uSWQsXG5cdHR5cGUgSG9zdE9wZXJhdGlvbnMsXG59IGZyb20gXCIuL2dlbmVyYXRlZC9ob3N0XCI7XG5pbXBvcnQgeyBpc1BsYWluUmVjb3JkIH0gZnJvbSBcIi4vaW50ZXJuYWxcIjtcbmltcG9ydCB0eXBlIHtcblx0QnJpZGdlU2NoZW1hLFxuXHRPcGVyYXRpb25NYXAsXG5cdE9wZXJhdGlvblNoYXBlLFxuXHRTdHJlYW1NYXAsXG5cdFN0cmVhbVNoYXBlLFxufSBmcm9tIFwiLi9zY2hlbWFcIjtcbmltcG9ydCB7IFFnaXNTZGtDb250cmFjdEVycm9yLCB2YWxpZGF0ZUFnYWluc3RTY2hlbWEgfSBmcm9tIFwiLi92YWxpZGF0ZVwiO1xuaW1wb3J0IHsgY3JlYXRlV2ViQ2hhbm5lbFRyYW5zcG9ydCB9IGZyb20gXCIuL3dlYmNoYW5uZWxcIjtcblxuLyoqIE9wdGlvbnMgZm9yIHtAbGluayBRZ2lzU2RrLmZyb21CcmlkZ2VTY2hlbWF9LiAqL1xuZXhwb3J0IGludGVyZmFjZSBRZ2lzU2RrT3B0aW9ucyB7XG5cdC8qKiBBIHRyYW5zcG9ydCB0byBzcGVhayB0aHJvdWdoOyBkZWZhdWx0cyB0byB0aGUgcGFnZSdzIFFXZWJDaGFubmVsLiAqL1xuXHRyZWFkb25seSB0cmFuc3BvcnQ/OiBXaXJlVHJhbnNwb3J0O1xuXHQvKiogQSBjbGllbnQgdGhlIGNhbGxlciBvd25zOyBgY2xvc2UoKWAgbGVhdmVzIGl0IG9wZW4uIEV4Y2x1ZGVzIGB0cmFuc3BvcnRgLiAqL1xuXHRyZWFkb25seSBjbGllbnQ/OiBCcmlkZ2VDbGllbnQ7XG5cdC8qKiBQZXItY2FsbCB0aW1lb3V0IGZvciBhbiBvd25lZCBjbGllbnQuICovXG5cdHJlYWRvbmx5IHRpbWVvdXRNcz86IG51bWJlcjtcblx0LyoqIFRoZSBjaGFubmVsIG9iamVjdCdzIG5hbWUgd2hlbiB0aGUgZGVmYXVsdCB0cmFuc3BvcnQgaXMgdXNlZC4gKi9cblx0cmVhZG9ubHkgY2hhbm5lbE9iamVjdD86IHN0cmluZztcbn1cblxuLyoqIEhhbmRsZXJzIGZvciBhIHR5cGVkIHN0cmVhbTogZXZlbnRzIGFzIGRlY2xhcmVkLCB0aGVuIGV4YWN0bHkgb25lIGVuZC4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU3RyZWFtSGFuZGxlcnM8RT4ge1xuXHRyZWFkb25seSBvbkV2ZW50PzogKGV2ZW50OiBFKSA9PiB2b2lkO1xuXHRyZWFkb25seSBvblRlcm1pbmFsPzogKHRlcm1pbmFsOiBCcmlkZ2VTdHJlYW1UZXJtaW5hbCkgPT4gdm9pZDtcbn1cblxuLyoqIEEgbGl2ZSBzdHJlYW0sIGFzIHRoZSBjYWxsZXIgaG9sZHMgaXQuICovXG5leHBvcnQgdHlwZSBTdHJlYW1IYW5kbGUgPSBCcmlkZ2VTdWJzY3JpcHRpb247XG5cbi8qKiBUaGUgbWV0aG9kIG9uZSBkZWNsYXJlZCBhY3Rpb24gYmVjb21lczsgYW4gZW1wdHkgcmVxdWVzdCBtYXkgYmUgb21pdHRlZC4gKi9cbmV4cG9ydCB0eXBlIE9wZXJhdGlvbk1ldGhvZDxPcCBleHRlbmRzIE9wZXJhdGlvblNoYXBlPiA9XG5cdC8vIGJpb21lLWlnbm9yZSBsaW50L2NvbXBsZXhpdHkvbm9CYW5uZWRUeXBlczogYHt9YCBpcyB0aGUgdGVzdCBmb3IgXCJub3RoaW5nIHJlcXVpcmVkXCJcblx0e30gZXh0ZW5kcyBPcFtcInJlcXVlc3RcIl1cblx0XHQ/IChcblx0XHRcdFx0cmVxdWVzdD86IE9wW1wicmVxdWVzdFwiXSxcblx0XHRcdFx0b3B0aW9ucz86IEludm9rZU9wdGlvbnMsXG5cdFx0XHQpID0+IFByb21pc2U8T3BbXCJyZXN1bHRcIl0+XG5cdFx0OiAoXG5cdFx0XHRcdHJlcXVlc3Q6IE9wW1wicmVxdWVzdFwiXSxcblx0XHRcdFx0b3B0aW9ucz86IEludm9rZU9wdGlvbnMsXG5cdFx0XHQpID0+IFByb21pc2U8T3BbXCJyZXN1bHRcIl0+O1xuXG4vKiogVGhlIG1ldGhvZCBvbmUgZGVjbGFyZWQgc3RyZWFtIGJlY29tZXMuICovXG5leHBvcnQgdHlwZSBTdHJlYW1NZXRob2Q8U3QgZXh0ZW5kcyBTdHJlYW1TaGFwZT4gPSAoXG5cdHJlcXVlc3Q6IFN0W1wicmVxdWVzdFwiXSxcblx0aGFuZGxlcnM6IFN0cmVhbUhhbmRsZXJzPFN0W1wiZXZlbnRcIl0+LFxuXHRvcHRpb25zPzogSW52b2tlT3B0aW9ucyxcbikgPT4gUHJvbWlzZTxTdHJlYW1IYW5kbGU+O1xuXG4vKipcbiAqIFRoZSBydW5uaW5nIHBhbGV0dGUsIHdoZW4gdGhlIGhhbmRzaGFrZSBjYXJyaWVkIG9uZSAoZGVjaXNpb24tMTYpOiB0aGVcbiAqIGBRUGFsZXR0ZWAgY29sb3VyIHJvbGVzIHRoZSBob3N0IHJlYWQsIGFzIENTUyBoZXggKGAjcnJnZ2JiYCBvclxuICogYCNycmdnYmJhYWApIGJ5IHRoZWlyIGNhbWVsLWNhc2VkIHJvbGUgbmFtZSwgYW5kIHdoZXRoZXIgdGhlIHdpbmRvdyBjb2xvdXJcbiAqIGlzIGRhcmsuIGBxZ2lzLXNkay11aWAgdHVybnMgaXQgaW50byB0aGUgYC0tcWdpcy1zZGstKmAgY3VzdG9tIHByb3BlcnRpZXM7XG4gKiBhIHBhZ2Ugb3V0c2lkZSBRR0lTIHNlZXMgYG51bGxgIGFuZCBrZWVwcyB0aGUgZG9jdW1lbnRlZCBkZWZhdWx0cy5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBRZ2lzU2RrSG9zdFRoZW1lIHtcblx0cmVhZG9ubHkgcGFsZXR0ZTogUmVhZG9ubHk8UmVjb3JkPHN0cmluZywgc3RyaW5nPj47XG5cdHJlYWRvbmx5IGRhcms6IGJvb2xlYW47XG59XG5cbi8qKiBXaGF0IHRoZSBoYW5kc2hha2UgdG9sZCB0aGlzIHBhZ2UgYWJvdXQgdGhlIGhvc3QgKGRlY2lzaW9uLTI3KS4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUWdpc1Nka0hvc3QgZXh0ZW5kcyBIb3N0T3BlcmF0aW9ucyB7XG5cdC8qKlxuXHQgKiBUaGUgaG9zdCBvcGVyYXRpb24gaWRzIHRoZSBoYW5kc2hha2UgYWR2ZXJ0aXNlZCBmb3IgdGhpcyB2aWV3OyBlbXB0eVxuXHQgKiB1bnRpbCB7QGxpbmsgUWdpc1Nka0NvcmUucmVhZHl9IGhhcyByZXNvbHZlZC5cblx0ICovXG5cdHJlYWRvbmx5IGdyYW50ZWQ6IHJlYWRvbmx5IEhvc3RPcGVyYXRpb25JZFtdO1xuXHQvKipcblx0ICogVGhlIGhvc3QncyBwYWxldHRlLCBgbnVsbGAgdW50aWwge0BsaW5rIFFnaXNTZGtDb3JlLnJlYWR5fSBoYXMgcmVzb2x2ZWRcblx0ICogYW5kIHdoZW4gdGhlIGhvc3Qgc2VudCBub25lLlxuXHQgKi9cblx0cmVhZG9ubHkgdGhlbWU6IFFnaXNTZGtIb3N0VGhlbWUgfCBudWxsO1xufVxuXG4vKiogVGhlIG1lbWJlcnMgZXZlcnkgYFFnaXNTZGtgIGhhcywgd2hhdGV2ZXIgaXRzIHNjaGVtYSBkZWNsYXJlcy4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUWdpc1Nka0NvcmU8TyA9IE9wZXJhdGlvbk1hcCwgUyA9IFN0cmVhbU1hcD4ge1xuXHQvKiogVGhlIHNjaGVtYSB0aGlzIGluc3RhbmNlIHdhcyBidWlsdCBmcm9tLiAqL1xuXHRyZWFkb25seSBzY2hlbWE6IEJyaWRnZVNjaGVtYTxPLCBTPjtcblx0LyoqIFRoZSBjbGllbnQgdW5kZXIgdGhlIG1ldGhvZHMsIGZvciB3aGF0IGEgbWV0aG9kIGRvZXMgbm90IGNvdmVyLiAqL1xuXHRyZWFkb25seSBjbGllbnQ6IEJyaWRnZUNsaWVudDtcblx0LyoqIFRoZSBjdXJhdGVkIGhvc3Qgc3VyZmFjZSwgYW5kIHdoYXQgdGhpcyB2aWV3IHdhcyBncmFudGVkIG9mIGl0LiAqL1xuXHRyZWFkb25seSBob3N0OiBRZ2lzU2RrSG9zdDtcblx0LyoqIFJlc29sdmVzIG9uY2UgdGhlIGhhbmRzaGFrZSBhbnN3ZXJlZDsgcmVqZWN0cyB3aGVuIHRoZSBob3N0IHJlZnVzZWQgaXQuICovXG5cdHJlYWRvbmx5IHJlYWR5OiBQcm9taXNlPHZvaWQ+O1xuXHQvKiogQ2xvc2UgYW4gb3duZWQgY2xpZW50OyBhIGNsaWVudCB0aGUgY2FsbGVyIHBhc3NlZCBpbiBpcyBsZWZ0IGFsb25lLiAqL1xuXHRjbG9zZSgpOiB2b2lkO1xufVxuXG4vKiogVGhlIGZpcnN0IHNlZ21lbnQgb2YgYSBkb3R0ZWQgaWQsIG9yIHRoZSB3aG9sZSBpZCB3aGVuIGl0IGhhcyBub25lLiAqL1xudHlwZSBIZWFkPEsgZXh0ZW5kcyBzdHJpbmc+ID0gSyBleHRlbmRzIGAke2luZmVyIEh9LiR7c3RyaW5nfWAgPyBIIDogSztcblxuLyoqIFRoZSBtZW1iZXJzIG9mIGBNYCB1bmRlciBvbmUgaGVhZCwga2V5ZWQgYnkgdGhlIHJlc3Qgb2YgdGhlaXIgaWRzLiAqL1xudHlwZSBVbmRlcjxNLCBIIGV4dGVuZHMgc3RyaW5nPiA9IHtcblx0W0sgaW4ga2V5b2YgTSAmIHN0cmluZyBhcyBLIGV4dGVuZHMgYCR7SH0uJHtpbmZlciBSZXN0fWBcblx0XHQ/IFJlc3Rcblx0XHQ6IG5ldmVyXTogTVtLXTtcbn07XG5cbi8qKlxuICogVGhlIGRlY2xhcmVkIGFjdGlvbnMgYXMgYSB0cmVlOiBhIHBsYWluIGlkIGlzIGEgbWV0aG9kLCBhIGRvdHRlZCBpZCBuZXN0c1xuICogb25lIG9iamVjdCBwZXIgc2VnbWVudC4gQW4gaWQgdGhhdCBpcyBib3RoIGEgbGVhZiBhbmQgYSBwcmVmaXggb2YgYW5vdGhlclxuICogaXMgcmVmdXNlZCBhdCBydW4gdGltZSwgc28gdGhlIHR5cGUgbmVlZCBub3Qgc2F5IHdoYXQgaXQgd291bGQgbWVhbi5cbiAqL1xuZXhwb3J0IHR5cGUgT3BlcmF0aW9uVHJlZTxPPiA9IHtcblx0cmVhZG9ubHkgW0ggaW4gSGVhZDxrZXlvZiBPICYgc3RyaW5nPl06IEggZXh0ZW5kcyBrZXlvZiBPXG5cdFx0PyBPW0hdIGV4dGVuZHMgT3BlcmF0aW9uU2hhcGVcblx0XHRcdD8gT3BlcmF0aW9uTWV0aG9kPE9bSF0+XG5cdFx0XHQ6IG5ldmVyXG5cdFx0OiBPcGVyYXRpb25UcmVlPFVuZGVyPE8sIEg+Pjtcbn07XG5cbi8qKiBUaGUgZGVjbGFyZWQgc3RyZWFtcyBhcyB0aGUgc2FtZSB0cmVlLCB3aXRoIGEgc3RyZWFtIG1ldGhvZCBhdCBlYWNoIGxlYWYuICovXG5leHBvcnQgdHlwZSBTdHJlYW1UcmVlPFM+ID0ge1xuXHRyZWFkb25seSBbSCBpbiBIZWFkPGtleW9mIFMgJiBzdHJpbmc+XTogSCBleHRlbmRzIGtleW9mIFNcblx0XHQ/IFNbSF0gZXh0ZW5kcyBTdHJlYW1TaGFwZVxuXHRcdFx0PyBTdHJlYW1NZXRob2Q8U1tIXT5cblx0XHRcdDogbmV2ZXJcblx0XHQ6IFN0cmVhbVRyZWU8VW5kZXI8UywgSD4+O1xufTtcblxuLyoqXG4gKiBBIHBhZ2UncyBoYW5kbGUgb24gUUdJUzogdGhlIGNvcmUsIHBsdXMgb25lIG1ldGhvZCBwZXIgZGVjbGFyZWQgb3BlcmF0aW9uXG4gKiBuZXN0ZWQgdW5kZXIgdGhlIHNlZ21lbnRzIG9mIGl0cyBpZC5cbiAqL1xuZXhwb3J0IHR5cGUgUWdpc1NkazxPID0gT3BlcmF0aW9uTWFwLCBTID0gU3RyZWFtTWFwPiA9IFFnaXNTZGtDb3JlPE8sIFM+ICZcblx0T3BlcmF0aW9uVHJlZTxPPiAmXG5cdFN0cmVhbVRyZWU8Uz47XG5cbi8qKiBOYW1lcyB7QGxpbmsgUWdpc1Nka0NvcmV9IGtlZXBzOyBhIGRlY2xhcmVkIGlkIG1heSBub3Qgc3RhcnQgd2l0aCBvbmUuICovXG5leHBvcnQgY29uc3QgUUdJU19TREtfTUVNQkVSUzogcmVhZG9ubHkgc3RyaW5nW10gPSBPYmplY3QuZnJlZXplKFtcblx0XCJjbGllbnRcIixcblx0XCJob3N0XCIsXG5cdFwic2NoZW1hXCIsXG5cdFwicmVhZHlcIixcblx0XCJjbG9zZVwiLFxuXSk7XG5cbmNvbnN0IEhPU1RfSURTOiBSZWFkb25seVNldDxzdHJpbmc+ID0gbmV3IFNldDxzdHJpbmc+KEhPU1RfT1BFUkFUSU9OUyk7XG5cbi8qKiBUaGUgaGFuZHNoYWtlLCBhcyBmYXIgYXMgdGhpcyBtb2R1bGUgcmVhZHMgaXQuICovXG5pbnRlcmZhY2UgSGFuZHNoYWtlIHtcblx0cmVhZG9ubHkgb3BlcmF0aW9uczogcmVhZG9ubHkgc3RyaW5nW107XG5cdHJlYWRvbmx5IGdyYW50ZWQ6IHJlYWRvbmx5IEhvc3RPcGVyYXRpb25JZFtdO1xuXHRyZWFkb25seSB0aGVtZTogUWdpc1Nka0hvc3RUaGVtZSB8IG51bGw7XG59XG5cbmZ1bmN0aW9uIHBhcnNlSGFuZHNoYWtlKHZhbHVlOiB1bmtub3duKTogSGFuZHNoYWtlIHtcblx0aWYgKCFpc1BsYWluUmVjb3JkKHZhbHVlKSB8fCAhQXJyYXkuaXNBcnJheSh2YWx1ZS5vcGVyYXRpb25zKSkge1xuXHRcdHRocm93IG5ldyBRZ2lzU2RrQnJpZGdlUHJvdG9jb2xFcnJvcihcblx0XHRcdFwiVGhlIGhhbmRzaGFrZSByZXBseSBjYXJyaWVzIG5vIG9wZXJhdGlvbnMgbGlzdFwiLFxuXHRcdCk7XG5cdH1cblx0Y29uc3Qgb3BlcmF0aW9uczogc3RyaW5nW10gPSBbXTtcblx0Zm9yIChjb25zdCBvcGVyYXRpb24gb2YgdmFsdWUub3BlcmF0aW9ucykge1xuXHRcdGlmIChpc1BsYWluUmVjb3JkKG9wZXJhdGlvbikgJiYgdHlwZW9mIG9wZXJhdGlvbi5pZCA9PT0gXCJzdHJpbmdcIikge1xuXHRcdFx0b3BlcmF0aW9ucy5wdXNoKG9wZXJhdGlvbi5pZCk7XG5cdFx0fVxuXHR9XG5cdHJldHVybiB7XG5cdFx0b3BlcmF0aW9ucyxcblx0XHRncmFudGVkOiBPYmplY3QuZnJlZXplKFxuXHRcdFx0b3BlcmF0aW9ucy5maWx0ZXIoKGlkKTogaWQgaXMgSG9zdE9wZXJhdGlvbklkID0+IEhPU1RfSURTLmhhcyhpZCkpLFxuXHRcdCksXG5cdFx0dGhlbWU6IHBhcnNlVGhlbWUodmFsdWUudGhlbWUpLFxuXHR9O1xufVxuXG4vKipcbiAqIFRoZSBgdGhlbWVgIG9mIGEgaGFuZHNoYWtlLCBvciBgbnVsbGAgd2hlbiBhYnNlbnQgb3IgbWFsZm9ybWVkOiBhIHBhbGV0dGVcbiAqIHRoYXQgY2Fubm90IGJlIHJlYWQgaXMgbm8gcmVhc29uIHRvIHJlZnVzZSB0aGUgaG9zdCwgdGhlIHBhZ2UganVzdCBrZWVwc1xuICogaXRzIGRlZmF1bHRzLiBPbmx5IHN0cmluZyBjb2xvdXJzIGFyZSBrZXB0LlxuICovXG5mdW5jdGlvbiBwYXJzZVRoZW1lKHZhbHVlOiB1bmtub3duKTogUWdpc1Nka0hvc3RUaGVtZSB8IG51bGwge1xuXHRpZiAoIWlzUGxhaW5SZWNvcmQodmFsdWUpIHx8ICFpc1BsYWluUmVjb3JkKHZhbHVlLnBhbGV0dGUpKSB7XG5cdFx0cmV0dXJuIG51bGw7XG5cdH1cblx0Y29uc3QgcGFsZXR0ZTogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHt9O1xuXHRmb3IgKGNvbnN0IFtyb2xlLCBjb2xvdXJdIG9mIE9iamVjdC5lbnRyaWVzKHZhbHVlLnBhbGV0dGUpKSB7XG5cdFx0aWYgKHR5cGVvZiBjb2xvdXIgPT09IFwic3RyaW5nXCIpIHtcblx0XHRcdHBhbGV0dGVbcm9sZV0gPSBjb2xvdXI7XG5cdFx0fVxuXHR9XG5cdHJldHVybiBPYmplY3QuZnJlZXplKHtcblx0XHRwYWxldHRlOiBPYmplY3QuZnJlZXplKHBhbGV0dGUpLFxuXHRcdGRhcms6IHZhbHVlLmRhcmsgPT09IHRydWUsXG5cdH0pO1xufVxuXG5mdW5jdGlvbiB1bndyYXBSZXF1ZXN0KFxuXHRvcGVyYXRpb246IHN0cmluZyxcblx0cmVxdWVzdDogdW5rbm93bixcbik6IFJlY29yZDxzdHJpbmcsIHVua25vd24+IHtcblx0aWYgKHJlcXVlc3QgPT09IHVuZGVmaW5lZCkge1xuXHRcdHJldHVybiB7fTtcblx0fVxuXHRpZiAoIWlzUGxhaW5SZWNvcmQocmVxdWVzdCkpIHtcblx0XHR0aHJvdyBuZXcgUWdpc1Nka0NvbnRyYWN0RXJyb3Iob3BlcmF0aW9uLCBcInJlcXVlc3RcIiwgW1xuXHRcdFx0Li4udmFsaWRhdGVBZ2FpbnN0U2NoZW1hKHJlcXVlc3QsIHsgdHlwZTogXCJvYmplY3RcIiB9KSxcblx0XHRdKTtcblx0fVxuXHRyZXR1cm4gcmVxdWVzdDtcbn1cblxuZnVuY3Rpb24gY2hlY2tlZFJlcXVlc3QoXG5cdGRlc2NyaXB0aW9uOiBBY3Rpb25EZXNjcmlwdGlvbiB8IFN0cmVhbURlc2NyaXB0aW9uLFxuXHRyZXF1ZXN0OiB1bmtub3duLFxuKTogUmVjb3JkPHN0cmluZywgdW5rbm93bj4ge1xuXHRjb25zdCBwYXlsb2FkID0gdW53cmFwUmVxdWVzdChkZXNjcmlwdGlvbi5pZCwgcmVxdWVzdCk7XG5cdGNvbnN0IGlzc3VlcyA9IHZhbGlkYXRlQWdhaW5zdFNjaGVtYShwYXlsb2FkLCBkZXNjcmlwdGlvbi5yZXF1ZXN0KTtcblx0aWYgKGlzc3Vlcy5sZW5ndGggPiAwKSB7XG5cdFx0dGhyb3cgbmV3IFFnaXNTZGtDb250cmFjdEVycm9yKGRlc2NyaXB0aW9uLmlkLCBcInJlcXVlc3RcIiwgaXNzdWVzKTtcblx0fVxuXHRyZXR1cm4gcGF5bG9hZDtcbn1cblxuZnVuY3Rpb24gb3BlcmF0aW9uTWV0aG9kKFxuXHRjbGllbnQ6IEJyaWRnZUNsaWVudCxcblx0YWN0aW9uOiBBY3Rpb25EZXNjcmlwdGlvbixcbik6IChyZXF1ZXN0PzogdW5rbm93biwgb3B0aW9ucz86IEludm9rZU9wdGlvbnMpID0+IFByb21pc2U8dW5rbm93bj4ge1xuXHRyZXR1cm4gYXN5bmMgKHJlcXVlc3QsIG9wdGlvbnMpID0+IHtcblx0XHRjb25zdCBwYXlsb2FkID0gY2hlY2tlZFJlcXVlc3QoYWN0aW9uLCByZXF1ZXN0KTtcblx0XHRjb25zdCB2YWx1ZSA9IGF3YWl0IGNsaWVudC5pbnZva2UoYWN0aW9uLmlkLCBwYXlsb2FkLCBvcHRpb25zKTtcblx0XHRjb25zdCBpc3N1ZXMgPSB2YWxpZGF0ZUFnYWluc3RTY2hlbWEodmFsdWUsIGFjdGlvbi5yZXN1bHQsIHtcblx0XHRcdGFsbG93VW5rbm93bjogdHJ1ZSxcblx0XHR9KTtcblx0XHRpZiAoaXNzdWVzLmxlbmd0aCA+IDApIHtcblx0XHRcdHRocm93IG5ldyBRZ2lzU2RrQ29udHJhY3RFcnJvcihhY3Rpb24uaWQsIFwicmVzdWx0XCIsIGlzc3Vlcyk7XG5cdFx0fVxuXHRcdHJldHVybiB2YWx1ZTtcblx0fTtcbn1cblxuZnVuY3Rpb24gc3RyZWFtTWV0aG9kKFxuXHRjbGllbnQ6IEJyaWRnZUNsaWVudCxcblx0c3RyZWFtOiBTdHJlYW1EZXNjcmlwdGlvbixcbik6IChcblx0cmVxdWVzdDogdW5rbm93bixcblx0aGFuZGxlcnM6IFN0cmVhbUhhbmRsZXJzPHVua25vd24+LFxuXHRvcHRpb25zPzogSW52b2tlT3B0aW9ucyxcbikgPT4gUHJvbWlzZTxTdHJlYW1IYW5kbGU+IHtcblx0cmV0dXJuIGFzeW5jIChyZXF1ZXN0LCBoYW5kbGVycywgb3B0aW9ucykgPT4ge1xuXHRcdGNvbnN0IHBheWxvYWQgPSBjaGVja2VkUmVxdWVzdChzdHJlYW0sIHJlcXVlc3QpO1xuXHRcdC8vIFRoZSB0eXBlZCBzdHJlYW0gZW5kcyBleGFjdGx5IG9uY2UsIGxpa2UgdGhlIHN1YnNjcmlwdGlvbiB1bmRlciBpdDogYVxuXHRcdC8vIGNvbnRyYWN0IHZpb2xhdGlvbiBlbmRzIGl0IGhlcmUsIGNsb3NlcyB0aGUgc3Vic2NyaXB0aW9uLCBhbmQgdGhlXG5cdFx0Ly8gYGRpc3Bvc2VkYCB0aGUgY2xpZW50IHRoZW4gcmVwb3J0cyBpcyBub3QgZGVsaXZlcmVkIGEgc2Vjb25kIHRpbWUuXG5cdFx0bGV0IGVuZGVkID0gZmFsc2U7XG5cdFx0bGV0IHZpb2xhdGVkID0gZmFsc2U7XG5cdFx0bGV0IGhhbmRsZTogU3RyZWFtSGFuZGxlIHwgbnVsbCA9IG51bGw7XG5cdFx0Y29uc3QgZW5kID0gKHRlcm1pbmFsOiBCcmlkZ2VTdHJlYW1UZXJtaW5hbCk6IHZvaWQgPT4ge1xuXHRcdFx0aWYgKGVuZGVkKSB7XG5cdFx0XHRcdHJldHVybjtcblx0XHRcdH1cblx0XHRcdGVuZGVkID0gdHJ1ZTtcblx0XHRcdGhhbmRsZXJzLm9uVGVybWluYWw/Lih0ZXJtaW5hbCk7XG5cdFx0fTtcblx0XHRoYW5kbGUgPSBhd2FpdCBjbGllbnQuc3Vic2NyaWJlKFxuXHRcdFx0c3RyZWFtLmlkLFxuXHRcdFx0cGF5bG9hZCxcblx0XHRcdHtcblx0XHRcdFx0b25FdmVudDogKGV2ZW50KSA9PiB7XG5cdFx0XHRcdFx0aWYgKGVuZGVkKSB7XG5cdFx0XHRcdFx0XHRyZXR1cm47XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGNvbnN0IGRlY2xhcmVkID0gc3RyZWFtLmV2ZW50c1tldmVudC5raW5kXTtcblx0XHRcdFx0XHRjb25zdCBpc3N1ZXMgPVxuXHRcdFx0XHRcdFx0ZGVjbGFyZWQgPT09IHVuZGVmaW5lZFxuXHRcdFx0XHRcdFx0XHQ/IHVuZGVmaW5lZFxuXHRcdFx0XHRcdFx0XHQ6IHZhbGlkYXRlQWdhaW5zdFNjaGVtYShldmVudC5wYXlsb2FkLCBkZWNsYXJlZCwge1xuXHRcdFx0XHRcdFx0XHRcdFx0YWxsb3dVbmtub3duOiB0cnVlLFxuXHRcdFx0XHRcdFx0XHRcdFx0cGF0aDogW1wicGF5bG9hZFwiXSxcblx0XHRcdFx0XHRcdFx0XHR9KTtcblx0XHRcdFx0XHRpZiAoaXNzdWVzICE9PSB1bmRlZmluZWQgJiYgaXNzdWVzLmxlbmd0aCA9PT0gMCkge1xuXHRcdFx0XHRcdFx0aGFuZGxlcnMub25FdmVudD8uKGV2ZW50KTtcblx0XHRcdFx0XHRcdHJldHVybjtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0Y29uc3QgZXJyb3IgPSBuZXcgUWdpc1Nka0NvbnRyYWN0RXJyb3IoXG5cdFx0XHRcdFx0XHRzdHJlYW0uaWQsXG5cdFx0XHRcdFx0XHRcImV2ZW50XCIsXG5cdFx0XHRcdFx0XHRpc3N1ZXMgPz8gW10sXG5cdFx0XHRcdFx0KTtcblx0XHRcdFx0XHRlbmQoeyBraW5kOiBcImVycm9yXCIsIG1lc3NhZ2U6IGVycm9yLm1lc3NhZ2UgfSk7XG5cdFx0XHRcdFx0aWYgKGhhbmRsZSA9PT0gbnVsbCkge1xuXHRcdFx0XHRcdFx0dmlvbGF0ZWQgPSB0cnVlO1xuXHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRoYW5kbGUuY2xvc2UoKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH0sXG5cdFx0XHRcdG9uVGVybWluYWw6IGVuZCxcblx0XHRcdH0sXG5cdFx0XHRvcHRpb25zLFxuXHRcdCk7XG5cdFx0aWYgKHZpb2xhdGVkKSB7XG5cdFx0XHRoYW5kbGUuY2xvc2UoKTtcblx0XHR9XG5cdFx0cmV0dXJuIGhhbmRsZTtcblx0fTtcbn1cblxuZnVuY3Rpb24gYnVpbGRIb3N0KFxuXHRjbGllbnQ6IEJyaWRnZUNsaWVudCxcblx0aGFuZHNoYWtlOiAoKSA9PiBIYW5kc2hha2UgfCBudWxsLFxuKTogUWdpc1Nka0hvc3Qge1xuXHRjb25zdCBob3N0ID0gY3JlYXRlSG9zdChjbGllbnQpO1xuXHRyZXR1cm4gT2JqZWN0LmZyZWV6ZSh7XG5cdFx0Li4uaG9zdCxcblx0XHRnZXQgZ3JhbnRlZCgpOiByZWFkb25seSBIb3N0T3BlcmF0aW9uSWRbXSB7XG5cdFx0XHRyZXR1cm4gZ3JhbnRlZChoYW5kc2hha2UoKSk7XG5cdFx0fSxcblx0XHRnZXQgdGhlbWUoKTogUWdpc1Nka0hvc3RUaGVtZSB8IG51bGwge1xuXHRcdFx0cmV0dXJuIGhhbmRzaGFrZSgpPy50aGVtZSA/PyBudWxsO1xuXHRcdH0sXG5cdH0pO1xufVxuXG5jb25zdCBOT19HUkFOVFM6IHJlYWRvbmx5IEhvc3RPcGVyYXRpb25JZFtdID0gT2JqZWN0LmZyZWV6ZShbXSk7XG5cbmZ1bmN0aW9uIGdyYW50ZWQoaGFuZHNoYWtlOiBIYW5kc2hha2UgfCBudWxsKTogcmVhZG9ubHkgSG9zdE9wZXJhdGlvbklkW10ge1xuXHRyZXR1cm4gaGFuZHNoYWtlID09PSBudWxsID8gTk9fR1JBTlRTIDogaGFuZHNoYWtlLmdyYW50ZWQ7XG59XG5cbmZ1bmN0aW9uIGJ1aWxkPE8sIFM+KFxuXHRzY2hlbWE6IEJyaWRnZVNjaGVtYTxPLCBTPixcblx0b3B0aW9uczogUWdpc1Nka09wdGlvbnMsXG4pOiBRZ2lzU2RrPE8sIFM+IHtcblx0aWYgKG9wdGlvbnMuY2xpZW50ICE9PSB1bmRlZmluZWQgJiYgb3B0aW9ucy50cmFuc3BvcnQgIT09IHVuZGVmaW5lZCkge1xuXHRcdHRocm93IG5ldyBRZ2lzU2RrRGVjbGFyYXRpb25FcnJvcihcblx0XHRcdFwiUWdpc1Nkay5mcm9tQnJpZGdlU2NoZW1hIHRha2VzIGEgY2xpZW50IG9yIGEgdHJhbnNwb3J0LCBub3QgYm90aFwiLFxuXHRcdCk7XG5cdH1cblx0Y29uc3Qgb3duZWQgPSBvcHRpb25zLmNsaWVudCA9PT0gdW5kZWZpbmVkO1xuXHRjb25zdCB0cmFuc3BvcnQgPVxuXHRcdG9wdGlvbnMudHJhbnNwb3J0ID8/XG5cdFx0KG9wdGlvbnMuY2xpZW50ID09PSB1bmRlZmluZWRcblx0XHRcdD8gY3JlYXRlV2ViQ2hhbm5lbFRyYW5zcG9ydChvcHRpb25zLmNoYW5uZWxPYmplY3QgPz8gXCJicmlkZ2VcIilcblx0XHRcdDogdW5kZWZpbmVkKTtcblx0Y29uc3QgY2xpZW50ID1cblx0XHRvcHRpb25zLmNsaWVudCA/P1xuXHRcdG5ldyBCcmlkZ2VDbGllbnQoXG5cdFx0XHR0cmFuc3BvcnQgYXMgV2lyZVRyYW5zcG9ydCxcblx0XHRcdG9wdGlvbnMudGltZW91dE1zID09PSB1bmRlZmluZWQgPyB7fSA6IHsgdGltZW91dE1zOiBvcHRpb25zLnRpbWVvdXRNcyB9LFxuXHRcdCk7XG5cdGxldCBoYW5kc2hha2U6IEhhbmRzaGFrZSB8IG51bGwgPSBudWxsO1xuXHRjb25zdCByZWFkeSA9IGNsaWVudC5oYW5kc2hha2UoKS50aGVuKCh2YWx1ZSkgPT4ge1xuXHRcdGhhbmRzaGFrZSA9IHBhcnNlSGFuZHNoYWtlKHZhbHVlKTtcblx0fSk7XG5cdC8vIEEgcGFnZSB0aGF0IG5ldmVyIGF3YWl0cyBgcmVhZHlgIHN0aWxsIHNlZXMgZXZlcnkgY2FsbCBmYWlsIG9uIGl0cyBvd247XG5cdC8vIHRoZSByZWplY3Rpb24gaXMgbm90IGxlZnQgdW5vYnNlcnZlZCBvbiB0b3Agb2YgdGhhdC5cblx0cmVhZHkuY2F0Y2goKCkgPT4gdW5kZWZpbmVkKTtcblx0Y29uc3QgbWVtYmVyczogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gPSB7XG5cdFx0c2NoZW1hLFxuXHRcdGNsaWVudCxcblx0XHRob3N0OiBidWlsZEhvc3QoY2xpZW50LCAoKSA9PiBoYW5kc2hha2UpLFxuXHRcdHJlYWR5LFxuXHRcdGNsb3NlOiAoKTogdm9pZCA9PiB7XG5cdFx0XHRpZiAob3duZWQpIHtcblx0XHRcdFx0Y2xpZW50LmNsb3NlKCk7XG5cdFx0XHR9XG5cdFx0fSxcblx0fTtcblx0Y29uc3QgbmFtZXNwYWNlczogUmVjb3JkPHN0cmluZywgdW5rbm93bj5bXSA9IFtdO1xuXHRmb3IgKGNvbnN0IGFjdGlvbiBvZiBzY2hlbWEuYWN0aW9ucykge1xuXHRcdHBsYWNlKG1lbWJlcnMsIG5hbWVzcGFjZXMsIGFjdGlvbi5pZCwgb3BlcmF0aW9uTWV0aG9kKGNsaWVudCwgYWN0aW9uKSk7XG5cdH1cblx0Zm9yIChjb25zdCBzdHJlYW0gb2Ygc2NoZW1hLnN0cmVhbXMpIHtcblx0XHRwbGFjZShtZW1iZXJzLCBuYW1lc3BhY2VzLCBzdHJlYW0uaWQsIHN0cmVhbU1ldGhvZChjbGllbnQsIHN0cmVhbSkpO1xuXHR9XG5cdGZvciAoY29uc3QgbmFtZXNwYWNlIG9mIG5hbWVzcGFjZXMpIHtcblx0XHRPYmplY3QuZnJlZXplKG5hbWVzcGFjZSk7XG5cdH1cblx0cmV0dXJuIE9iamVjdC5mcmVlemUobWVtYmVycykgYXMgdW5rbm93biBhcyBRZ2lzU2RrPE8sIFM+O1xufVxuXG4vKipcbiAqIFB1dCBvbmUgbWV0aG9kIHdoZXJlIGl0cyBpZCBzYXlzOiBgYS5iLmNgIGJlY29tZXMgYG1lbWJlcnMuYS5iLmNgLCBidWlsZGluZ1xuICogdGhlIG9iamVjdHMgb24gdGhlIHdheS4gVHdvIGlkcyBjYW5ub3QgYm90aCBiZSBob25lc3Qgd2hlbiBvbmUgaXMgYSBwcmVmaXhcbiAqIG9mIHRoZSBvdGhlciAtIGBzaXRlc2AgY2Fubm90IGJlIGEgbWV0aG9kIGFuZCBob2xkIGBzaXRlcy5zdW1tYXJ5YCAtIGFuZCBhXG4gKiBmaXJzdCBzZWdtZW50IHRoYXQgaXMgYSBjb3JlIG1lbWJlciB3b3VsZCBoaWRlIGl0LCBzbyBib3RoIGFyZSByZWZ1c2VkLlxuICovXG5mdW5jdGlvbiBwbGFjZShcblx0bWVtYmVyczogUmVjb3JkPHN0cmluZywgdW5rbm93bj4sXG5cdG5hbWVzcGFjZXM6IFJlY29yZDxzdHJpbmcsIHVua25vd24+W10sXG5cdGlkOiBzdHJpbmcsXG5cdG1ldGhvZDogdW5rbm93bixcbik6IHZvaWQge1xuXHRjb25zdCBzZWdtZW50cyA9IGlkLnNwbGl0KFwiLlwiKTtcblx0aWYgKHNlZ21lbnRzLnNvbWUoKHNlZ21lbnQpID0+IHNlZ21lbnQgPT09IFwiXCIpKSB7XG5cdFx0dGhyb3cgbmV3IFFnaXNTZGtEZWNsYXJhdGlvbkVycm9yKFxuXHRcdFx0YCR7aWR9OiBhbiBvcGVyYXRpb24gaWQgbWF5IG5vdCBoYXZlIGFuIGVtcHR5IHNlZ21lbnRgLFxuXHRcdCk7XG5cdH1cblx0Y29uc3QgaGVhZCA9IHNlZ21lbnRzWzBdIGFzIHN0cmluZztcblx0aWYgKFFHSVNfU0RLX01FTUJFUlMuaW5jbHVkZXMoaGVhZCkpIHtcblx0XHR0aHJvdyBuZXcgUWdpc1Nka0RlY2xhcmF0aW9uRXJyb3IoXG5cdFx0XHRgJHtpZH06IGFuIG9wZXJhdGlvbiBpZCBtYXkgbm90IHN0YXJ0IHdpdGggYSBRZ2lzU2RrIG1lbWJlciAoJHtRR0lTX1NES19NRU1CRVJTLmpvaW4oXCIsIFwiKX0pYCxcblx0XHQpO1xuXHR9XG5cdGxldCBub2RlID0gbWVtYmVycztcblx0Zm9yIChjb25zdCBbaW5kZXgsIHNlZ21lbnRdIG9mIHNlZ21lbnRzLmVudHJpZXMoKSkge1xuXHRcdGNvbnN0IHByZWZpeCA9IHNlZ21lbnRzLnNsaWNlKDAsIGluZGV4ICsgMSkuam9pbihcIi5cIik7XG5cdFx0Y29uc3QgZXhpc3RpbmcgPSBub2RlW3NlZ21lbnRdO1xuXHRcdGlmIChpbmRleCA9PT0gc2VnbWVudHMubGVuZ3RoIC0gMSkge1xuXHRcdFx0aWYgKGV4aXN0aW5nICE9PSB1bmRlZmluZWQpIHtcblx0XHRcdFx0dGhyb3cgbmV3IFFnaXNTZGtEZWNsYXJhdGlvbkVycm9yKFxuXHRcdFx0XHRcdHR5cGVvZiBleGlzdGluZyA9PT0gXCJmdW5jdGlvblwiXG5cdFx0XHRcdFx0XHQ/IGAke2lkfTogZHVwbGljYXRlIG9wZXJhdGlvbiBpZGBcblx0XHRcdFx0XHRcdDogYCR7aWR9OiBhbiBvcGVyYXRpb24gaWQgbWF5IG5vdCBiZSBhIHByZWZpeCBvZiBhbm90aGVyIGRlY2xhcmVkIGlkYCxcblx0XHRcdFx0KTtcblx0XHRcdH1cblx0XHRcdG5vZGVbc2VnbWVudF0gPSBtZXRob2Q7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXHRcdGlmIChleGlzdGluZyA9PT0gdW5kZWZpbmVkKSB7XG5cdFx0XHRjb25zdCBuYW1lc3BhY2U6IFJlY29yZDxzdHJpbmcsIHVua25vd24+ID0ge307XG5cdFx0XHRuYW1lc3BhY2VzLnB1c2gobmFtZXNwYWNlKTtcblx0XHRcdG5vZGVbc2VnbWVudF0gPSBuYW1lc3BhY2U7XG5cdFx0XHRub2RlID0gbmFtZXNwYWNlO1xuXHRcdH0gZWxzZSBpZiAodHlwZW9mIGV4aXN0aW5nID09PSBcImZ1bmN0aW9uXCIpIHtcblx0XHRcdHRocm93IG5ldyBRZ2lzU2RrRGVjbGFyYXRpb25FcnJvcihcblx0XHRcdFx0YCR7aWR9OiAke3ByZWZpeH0gaXMgYWxyZWFkeSBhbiBvcGVyYXRpb24gaWQ7IGFuIGlkIG1heSBub3QgZXh0ZW5kIGFub3RoZXJgLFxuXHRcdFx0KTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0bm9kZSA9IGV4aXN0aW5nIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xuXHRcdH1cblx0fVxufVxuXG4vKipcbiAqIFRoZSBlbnRyeSBwb2ludDogYFFnaXNTZGsuZnJvbUJyaWRnZVNjaGVtYShzY2hlbWEpYC5cbiAqXG4gKiBBIG5hbWVzcGFjZSByYXRoZXIgdGhhbiBhIGNvbnN0YW50IHNvIHRoZSB2YWx1ZSBhbmQgdGhlIGluc3RhbmNlIHR5cGUgc2hhcmVcbiAqIG9uZSBuYW1lIHRocm91Z2ggZXZlcnkgZGVjbGFyYXRpb24gYnVuZGxlci5cbiAqL1xuZXhwb3J0IG5hbWVzcGFjZSBRZ2lzU2RrIHtcblx0LyoqXG5cdCAqIEJ1aWxkIGEgYFFnaXNTZGtgIG9uIGEgZ2VuZXJhdGVkIHNjaGVtYS5cblx0ICpcblx0ICogV2l0aG91dCBvcHRpb25zIGl0IGNvbm5lY3RzIHRvIHRoZSBwYWdlJ3MgUVdlYkNoYW5uZWwgb2JqZWN0IG5hbWVkXG5cdCAqIFwiYnJpZGdlXCIsIHdoaWNoIGlzIHdoYXQgdGhlIFB5dGhvbiBydW50aW1lIHJlZ2lzdGVyczsgYSB0ZXN0IHBhc3NlcyB0aGVcblx0ICogaGFybmVzcyBmcm9tIGBAYXJjaG9udDU2MS9xZ2lzLXNkay90ZXN0aW5nYCBhcyBgdHJhbnNwb3J0YCBpbnN0ZWFkLlxuXHQgKi9cblx0ZXhwb3J0IGZ1bmN0aW9uIGZyb21CcmlkZ2VTY2hlbWE8XG5cdFx0TyBleHRlbmRzIFJlY29yZDxrZXlvZiBPLCBPcGVyYXRpb25TaGFwZT4sXG5cdFx0UyBleHRlbmRzIFJlY29yZDxrZXlvZiBTLCBTdHJlYW1TaGFwZT4sXG5cdD4oc2NoZW1hOiBCcmlkZ2VTY2hlbWE8TywgUz4sIG9wdGlvbnM6IFFnaXNTZGtPcHRpb25zID0ge30pOiBRZ2lzU2RrPE8sIFM+IHtcblx0XHRyZXR1cm4gYnVpbGQoc2NoZW1hLCBvcHRpb25zKTtcblx0fVxufVxuIiwKICAgICIvKipcbiAqIFRoZSBicmlkZ2Ugc2NoZW1hOiBhIHBsdWdpbiBkZXNjcmlwdGlvbiB0aGF0IGFsc28gY2FycmllcyBpdHMgdHlwZXMuXG4gKlxuICogYHFnaXMtc2RrIGJyaWRnZSBnZW5lcmF0ZWAgd3JpdGVzIG9uZSBgYnJpZGdlLnNjaGVtYS50c2AgcGVyIHBsdWdpblxuICogKGRlY2lzaW9uLTQ0KS4gVGhhdCBtb2R1bGUgaGFzIG5vIGNvZGUgb2YgaXRzIG93bjogaXQgZGVjbGFyZXMgdGhlIHZhbHVlXG4gKiBpbnRlcmZhY2VzLCB0d28gbWFwcyAtIGBPcGVyYXRpb25zYCBhbmQgYFN0cmVhbXNgLCBrZXllZCBieSBvcGVyYXRpb24gaWQgLVxuICogYW5kIGVuZHMgaW4gYGRlZmluZUJyaWRnZVNjaGVtYTxPcGVyYXRpb25zLCBTdHJlYW1zPih7IC4uLmRlc2NyaXB0aW9uIH0pYC5cbiAqIFRoZSB0d28gdHlwZSBwYXJhbWV0ZXJzIG5ldmVyIGV4aXN0IGF0IHJ1biB0aW1lOyB0aGV5IHJpZGUgb24gdGhlIHJldHVybmVkXG4gKiBvYmplY3Qgc28gYFFnaXNTZGsuZnJvbUJyaWRnZVNjaGVtYShzY2hlbWEpYCBjYW4gaW5mZXIgdGhlbSwgYW5kIHRoZVxuICogZGVzY3JpcHRpb24gaXRzZWxmIGlzIHdoYXQgdGhlIFNESyB2YWxpZGF0ZXMgYWdhaW5zdC5cbiAqL1xuXG5pbXBvcnQgeyB0eXBlIFBsdWdpbkRlc2NyaXB0aW9uLCBwYXJzZVBsdWdpbkRlc2NyaXB0aW9uIH0gZnJvbSBcIi4vZGVjbGFyYXRpb25zXCI7XG5cbi8qKiBXaGF0IG9uZSBkZWNsYXJlZCBhY3Rpb24gcHJvbWlzZXM6IGFuIG9iamVjdCBpbiwgYSB2YWx1ZSBvdXQuICovXG5leHBvcnQgaW50ZXJmYWNlIE9wZXJhdGlvblNoYXBlIHtcblx0cmVhZG9ubHkgcmVxdWVzdDogb2JqZWN0O1xuXHRyZWFkb25seSByZXN1bHQ6IHVua25vd247XG59XG5cbi8qKiBXaGF0IG9uZSBkZWNsYXJlZCBzdHJlYW0gcHJvbWlzZXM6IGFuIG9iamVjdCBpbiwgZGlzY3JpbWluYXRlZCBldmVudHMgb3V0LiAqL1xuZXhwb3J0IGludGVyZmFjZSBTdHJlYW1TaGFwZSB7XG5cdHJlYWRvbmx5IHJlcXVlc3Q6IG9iamVjdDtcblx0cmVhZG9ubHkgZXZlbnQ6IHsgcmVhZG9ubHkga2luZDogc3RyaW5nOyByZWFkb25seSBwYXlsb2FkOiB1bmtub3duIH07XG59XG5cbi8qKiBUaGUgZGVmYXVsdCwgdW50eXBlZCBtYXA6IGFueSBpZCwgYW55IHNoYXBlLiAqL1xuZXhwb3J0IHR5cGUgT3BlcmF0aW9uTWFwID0geyByZWFkb25seSBbaWQ6IHN0cmluZ106IE9wZXJhdGlvblNoYXBlIH07XG5cbi8qKiBUaGUgZGVmYXVsdCwgdW50eXBlZCBtYXA6IGFueSBpZCwgYW55IHNoYXBlLiAqL1xuZXhwb3J0IHR5cGUgU3RyZWFtTWFwID0geyByZWFkb25seSBbaWQ6IHN0cmluZ106IFN0cmVhbVNoYXBlIH07XG5cbi8qKlxuICogQSBwYXJzZWQgcGx1Z2luIGRlc2NyaXB0aW9uIGNhcnJ5aW5nIGl0cyBgT3BlcmF0aW9uc2AgYW5kIGBTdHJlYW1zYCB0eXBlcy5cbiAqXG4gKiBUaGUgYFwifnR5cGVzXCJgIG1lbWJlciBpcyBjb21waWxlLXRpbWUgb25seTogaXQgaXMgbmV2ZXIgc2V0LCBhbmQgYSBzY2hlbWEgaXNcbiAqIGEgZnJvemVuIHtAbGluayBQbHVnaW5EZXNjcmlwdGlvbn0gYW5kIG5vdGhpbmcgbW9yZSBhdCBydW4gdGltZS4gSXQgaXMgYVxuICogc3RyaW5nIGtleSwgbm90IGEgdW5pcXVlIHN5bWJvbCwgc28gdGhlIHR5cGUgc3RheXMgc3RydWN0dXJhbGx5IHRoZSBzYW1lXG4gKiBhY3Jvc3MgdGhlIHBhY2thZ2UncyBlbnRyeSBwb2ludHMuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQnJpZGdlU2NoZW1hPE8gPSBPcGVyYXRpb25NYXAsIFMgPSBTdHJlYW1NYXA+XG5cdGV4dGVuZHMgUGx1Z2luRGVzY3JpcHRpb24ge1xuXHRyZWFkb25seSBcIn50eXBlc1wiPzoge1xuXHRcdHJlYWRvbmx5IG9wZXJhdGlvbnM6IE87XG5cdFx0cmVhZG9ubHkgc3RyZWFtczogUztcblx0fTtcbn1cblxuLyoqIFRoZSBgT3BlcmF0aW9uc2AgbWFwIGEgc2NoZW1hIGNhcnJpZXMuICovXG5leHBvcnQgdHlwZSBPcGVyYXRpb25zT2Y8U2NoZW1hPiA9XG5cdFNjaGVtYSBleHRlbmRzIEJyaWRnZVNjaGVtYTxpbmZlciBPLCB1bmtub3duPiA/IE8gOiBuZXZlcjtcblxuLyoqIFRoZSBgU3RyZWFtc2AgbWFwIGEgc2NoZW1hIGNhcnJpZXMuICovXG5leHBvcnQgdHlwZSBTdHJlYW1zT2Y8U2NoZW1hPiA9XG5cdFNjaGVtYSBleHRlbmRzIEJyaWRnZVNjaGVtYTx1bmtub3duLCBpbmZlciBTPiA/IFMgOiBuZXZlcjtcblxuLyoqXG4gKiBQYXJzZSBhIGRlc2NyaXB0aW9uIGFuZCB0eXBlIGl0OyB0aGUgZ2VuZXJhdGVkIG1vZHVsZSBpcyB0aGUgb25seSBjYWxsZXIuXG4gKlxuICogVGhlIGRlc2NyaXB0aW9uIGlzIGNoZWNrZWQgdGhlIHdheSBhbnkgZGVzY3JpcHRpb24gaXMgKGBzY2hlbWFfdmVyc2lvbmAsXG4gKiBpZHMsIGhhbmRsZXJzLCBkZWNsYXJlZCBzdHJlYW1zKSwgc28gYSBoYW5kLWVkaXRlZCBvciBzdGFsZSBtb2R1bGUgZmFpbHNcbiAqIGhlcmUsIGF0IGltcG9ydCwgcmF0aGVyIHRoYW4gb24gdGhlIGZpcnN0IGNhbGwuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkZWZpbmVCcmlkZ2VTY2hlbWE8XG5cdE8gZXh0ZW5kcyBSZWNvcmQ8a2V5b2YgTywgT3BlcmF0aW9uU2hhcGU+LFxuXHRTIGV4dGVuZHMgUmVjb3JkPGtleW9mIFMsIFN0cmVhbVNoYXBlPixcbj4oaW5wdXQ6IHN0cmluZyB8IFJlYWRvbmx5PFJlY29yZDxzdHJpbmcsIHVua25vd24+Pik6IEJyaWRnZVNjaGVtYTxPLCBTPiB7XG5cdHJldHVybiBwYXJzZVBsdWdpbkRlc2NyaXB0aW9uKGlucHV0KSBhcyBCcmlkZ2VT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RUFDbkU7QUFBQSxFQUNBLFdBQVcsYUFBYSxZQUFZO0FBQUEsSUFDbkMsT0FBTyxPQUFPLFNBQVM7QUFBQSxFQUN4QjtBQUFBLEVBQ0EsT0FBTyxPQUFPLE9BQU8sT0FBTztBQUFBO0FBUzdCLFNBQVMsS0FBSyxDQUNiLFNBQ0EsWUFDQSxJQUNBLFFBQ087QUFBQSxFQUNQLE1BQU0sV0FBVyxHQUFHLE1BQU0sR0FBRztBQUFBLEVBQzdCLElBQUksU0FBUyxLQUFLLENBQUMsWUFBWSxZQUFZLEVBQUUsR0FBRztBQUFBLElBQy9DLE1BQU0sSUFBSSx5QkFDVCxHQUFHLG1EQUNKO0FBQUEsRUFDRDtBQUFBLEVBQ0EsTUFBTSxPQUFPLFNBQVM7QUFBQSxFQUN0QixJQUFJLGlCQUFpQixTQUFTLElBQUksR0FBRztBQUFBLElBQ3BDLE1BQU0sSUFBSSx5QkFDVCxHQUFHLDREQUE0RCxpQkFBaUIsS0FBSyxJQUFJLElBQzFGO0FBQUEsRUFDRDtBQUFBLEVBQ0EsSUFBSSxPQUFPO0FBQUEsRUFDWCxZQUFZLE9BQU8sWUFBWSxTQUFTLFFBQVEsR0FBRztBQUFBLElBQ2xELE1BQU0sU0FBUyxTQUFTLE1BQU0sR0FBRyxRQUFRLENBQUMsRUFBRSxLQUFLLEdBQUc7QUFBQSxJQUNwRCxNQUFNLFdBQVcsS0FBSztBQUFBLElBQ3RCLElBQUksVUFBVSxTQUFTLFNBQVMsR0FBRztBQUFBLE1BQ2xDLElBQUksYUFBYSxXQUFXO0FBQUEsUUFDM0IsTUFBTSxJQUFJLHlCQUNULE9BQU8sYUFBYSxhQUNqQixHQUFHLCtCQUNILEdBQUcsZ0VBQ1A7QUFBQSxNQUNEO0FBQUEsTUFDQSxLQUFLLFdBQVc7QUFBQSxNQUNoQjtBQUFBLElBQ0Q7QUFBQSxJQUNBLElBQUksYUFBYSxXQUFXO0FBQUEsTUFDM0IsTUFBTSxZQUFxQyxDQUFDO0FBQUEsTUFDNUMsV0FBVyxLQUFLLFNBQVM7QUFBQSxNQUN6QixLQUFLLFdBQVc7QUFBQSxNQUNoQixPQUFPO0FBQUEsSUFDUixFQUFPLFNBQUksT0FBTyxhQUFhLFlBQVk7QUFBQSxNQUMxQyxNQUFNLElBQUkseUJBQ1QsR0FBRyxPQUFPLGlFQUNYO0FBQUEsSUFDRCxFQUFPO0FBQUEsTUFDTixPQUFPO0FBQUE7QUFBQSxFQUVUO0FBQUE7QUFTTSxJQUFVO0FBQUEsQ0FBVixDQUFVLFlBQVY7QUFBQSxFQVFDLFNBQVMsZ0JBR2YsQ0FBQyxRQUE0QixVQUEwQixDQUFDLEdBQWtCO0FBQUEsSUFDMUUsT0FBTyxNQUFNLFFBQVEsT0FBTztBQUFBO0FBQUEsRUFKdEIsUUFBUztBQUFBLEdBUkE7O0FDcGFWLFNBQVMsa0JBR2YsQ0FBQyxPQUF1RTtBQUFBLEVBQ3hFLE9BQU8sd0JBQXVCLEtBQUs7QUFBQTsiLAogICJkZWJ1Z0lkIjogIjUwN0M0N0E1NEE4N0JEMUI2NDc1NkUyMTY0NzU2RTIxIiwKICAibmFtZXMiOiBbXQp9