@expressive/mvc 0.71.0 → 0.72.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/esm/context.js +111 -90
- package/dist/esm/control.js +31 -42
- package/dist/esm/index.js +10 -11
- package/dist/esm/instruction/get.js +64 -73
- package/dist/esm/instruction/ref.js +40 -37
- package/dist/esm/instruction/set.js +78 -27
- package/dist/esm/instruction/use.js +19 -21
- package/dist/esm/state.js +324 -0
- package/dist/index.d.ts +225 -190
- package/dist/index.js +502 -531
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/dist/esm/instruction/has.js +0 -86
- package/dist/esm/model.js +0 -318
package/dist/esm/model.js
DELETED
|
@@ -1,318 +0,0 @@
|
|
|
1
|
-
import { addListener, createEffect, event, Observable, PENDING_KEYS } from "./control";
|
|
2
|
-
const define = Object.defineProperty;
|
|
3
|
-
const ID = /* @__PURE__ */ new WeakMap();
|
|
4
|
-
const STATE = /* @__PURE__ */ new WeakMap();
|
|
5
|
-
const NOTIFY = /* @__PURE__ */ new WeakMap();
|
|
6
|
-
const PARENT = /* @__PURE__ */ new WeakMap();
|
|
7
|
-
const METHODS = /* @__PURE__ */ new WeakMap();
|
|
8
|
-
const METHOD = /* @__PURE__ */ new WeakMap();
|
|
9
|
-
class Model {
|
|
10
|
-
constructor(...args) {
|
|
11
|
-
prepare(this);
|
|
12
|
-
define(this, "is", { value: this });
|
|
13
|
-
init(this, args);
|
|
14
|
-
}
|
|
15
|
-
[Observable](callback, required) {
|
|
16
|
-
const watch2 = /* @__PURE__ */ new Set();
|
|
17
|
-
const proxy = Object.create(this);
|
|
18
|
-
addListener(this, (key) => {
|
|
19
|
-
if (watch2.has(key))
|
|
20
|
-
callback();
|
|
21
|
-
});
|
|
22
|
-
OBSERVER.set(proxy, (key, value) => {
|
|
23
|
-
if (value === void 0 && required)
|
|
24
|
-
throw new Error(`${this}.${key} is required in this context.`);
|
|
25
|
-
watch2.add(key);
|
|
26
|
-
if (value instanceof Object && Observable in value)
|
|
27
|
-
return value[Observable](callback, required) || value;
|
|
28
|
-
return value;
|
|
29
|
-
});
|
|
30
|
-
return proxy;
|
|
31
|
-
}
|
|
32
|
-
get(arg1, arg2) {
|
|
33
|
-
const self = this.is;
|
|
34
|
-
if (typeof arg1 == "function") {
|
|
35
|
-
const effect = METHOD.get(arg1) || arg1;
|
|
36
|
-
let pending = /* @__PURE__ */ new Set();
|
|
37
|
-
return createEffect(self, (proxy) => {
|
|
38
|
-
const cb = effect.call(proxy, proxy, pending);
|
|
39
|
-
return cb === null ? null : (update2) => {
|
|
40
|
-
pending = PENDING_KEYS.get(self);
|
|
41
|
-
if (typeof cb == "function")
|
|
42
|
-
cb(update2);
|
|
43
|
-
};
|
|
44
|
-
});
|
|
45
|
-
}
|
|
46
|
-
return arg1 === void 0 ? snapshot(self) : typeof arg2 == "function" ? addListener(self, arg2, arg1) : arg1 === null ? Object.isFrozen(STATE.get(self)) : fetch(self, arg1, arg2);
|
|
47
|
-
}
|
|
48
|
-
set(arg1, arg2, arg3) {
|
|
49
|
-
const self = this.is;
|
|
50
|
-
if (typeof arg1 == "function")
|
|
51
|
-
return addListener(self, (key) => {
|
|
52
|
-
if (arg2 === key || arg2 === void 0 && typeof key == "string")
|
|
53
|
-
return arg1.call(self, key, self);
|
|
54
|
-
});
|
|
55
|
-
if (arg1 && typeof arg1 == "object")
|
|
56
|
-
assign(self, arg1, arg2 === true);
|
|
57
|
-
else if (!arg2)
|
|
58
|
-
event(self, arg1);
|
|
59
|
-
else if (arg3)
|
|
60
|
-
manage(self, arg1, arg2);
|
|
61
|
-
else
|
|
62
|
-
update(self, arg1, arg2);
|
|
63
|
-
const pending = PENDING_KEYS.get(this);
|
|
64
|
-
if (pending)
|
|
65
|
-
return {
|
|
66
|
-
then: (res) => new Promise((res2) => {
|
|
67
|
-
const remove = addListener(this, (key) => {
|
|
68
|
-
if (key !== true) {
|
|
69
|
-
remove();
|
|
70
|
-
return res2.bind(null, Array.from(pending));
|
|
71
|
-
}
|
|
72
|
-
});
|
|
73
|
-
}).then(res)
|
|
74
|
-
};
|
|
75
|
-
}
|
|
76
|
-
/**
|
|
77
|
-
* Iterate over managed properties in this instance of Model.
|
|
78
|
-
* Yeilds the key and current value for each property.
|
|
79
|
-
*/
|
|
80
|
-
[Symbol.iterator]() {
|
|
81
|
-
return Object.entries(STATE.get(this.is))[Symbol.iterator]();
|
|
82
|
-
}
|
|
83
|
-
/**
|
|
84
|
-
* Create and activate a new instance of this model.
|
|
85
|
-
*
|
|
86
|
-
* **Important** - Unlike `new this(...)` - this method also activates state.
|
|
87
|
-
*
|
|
88
|
-
* @param args - arguments sent to constructor
|
|
89
|
-
*/
|
|
90
|
-
static new(...args) {
|
|
91
|
-
const instance = new this(...args);
|
|
92
|
-
event(instance);
|
|
93
|
-
return instance;
|
|
94
|
-
}
|
|
95
|
-
/**
|
|
96
|
-
* Static equivalent of `x instanceof this`.
|
|
97
|
-
* Determines if provided class is a subtype of this one.
|
|
98
|
-
* If so, language server will make available all static
|
|
99
|
-
* methods and properties of this class.
|
|
100
|
-
*/
|
|
101
|
-
static is(maybe) {
|
|
102
|
-
return maybe === this || typeof maybe == "function" && maybe.prototype instanceof this;
|
|
103
|
-
}
|
|
104
|
-
/**
|
|
105
|
-
* Register a callback to run when any instance of this Model is updated.
|
|
106
|
-
*/
|
|
107
|
-
static on(listener) {
|
|
108
|
-
let notify = NOTIFY.get(this);
|
|
109
|
-
if (!notify)
|
|
110
|
-
NOTIFY.set(this, notify = /* @__PURE__ */ new Set());
|
|
111
|
-
notify.add(listener);
|
|
112
|
-
return () => notify.delete(listener);
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
define(Model.prototype, "toString", {
|
|
116
|
-
value() {
|
|
117
|
-
return ID.get(this.is);
|
|
118
|
-
}
|
|
119
|
-
});
|
|
120
|
-
define(Model, "toString", {
|
|
121
|
-
value() {
|
|
122
|
-
return this.name;
|
|
123
|
-
}
|
|
124
|
-
});
|
|
125
|
-
function assign(subject, data, silent) {
|
|
126
|
-
const methods = METHODS.get(subject.constructor);
|
|
127
|
-
for (const key in data) {
|
|
128
|
-
const bind = methods.get(key);
|
|
129
|
-
if (bind)
|
|
130
|
-
bind.call(subject, data[key]);
|
|
131
|
-
else if (key in subject && key !== "is") {
|
|
132
|
-
const desc = Object.getOwnPropertyDescriptor(subject, key);
|
|
133
|
-
const set = desc && desc.set;
|
|
134
|
-
if (set)
|
|
135
|
-
set.call(subject, data[key], silent);
|
|
136
|
-
else
|
|
137
|
-
subject[key] = data[key];
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
function prepare(model) {
|
|
142
|
-
let T = model.constructor;
|
|
143
|
-
if (T === Model)
|
|
144
|
-
throw new Error("Cannot create base Model.");
|
|
145
|
-
const chain = [];
|
|
146
|
-
let keys = /* @__PURE__ */ new Map();
|
|
147
|
-
ID.set(model, `${T}-${uid()}`);
|
|
148
|
-
while (T.name) {
|
|
149
|
-
for (const cb of NOTIFY.get(T) || [])
|
|
150
|
-
addListener(model, cb);
|
|
151
|
-
if (T === Model) break;
|
|
152
|
-
else chain.unshift(T);
|
|
153
|
-
T = Object.getPrototypeOf(T);
|
|
154
|
-
}
|
|
155
|
-
for (const type of chain) {
|
|
156
|
-
if (METHODS.has(type)) {
|
|
157
|
-
keys = METHODS.get(type);
|
|
158
|
-
continue;
|
|
159
|
-
}
|
|
160
|
-
METHODS.set(type, keys = new Map(keys));
|
|
161
|
-
for (const [key, { value }] of Object.entries(
|
|
162
|
-
Object.getOwnPropertyDescriptors(type.prototype)
|
|
163
|
-
)) {
|
|
164
|
-
let bind2 = function(original) {
|
|
165
|
-
const { is } = this;
|
|
166
|
-
if (is.hasOwnProperty(key) && !original)
|
|
167
|
-
return value;
|
|
168
|
-
const fn = original || value;
|
|
169
|
-
const bound = fn.bind(is);
|
|
170
|
-
METHOD.set(bound, fn);
|
|
171
|
-
define(is, key, { value: bound, writable: true });
|
|
172
|
-
return bound;
|
|
173
|
-
};
|
|
174
|
-
var bind = bind2;
|
|
175
|
-
if (!value || key == "constructor")
|
|
176
|
-
continue;
|
|
177
|
-
keys.set(key, bind2);
|
|
178
|
-
define(type.prototype, key, { get: bind2, set: bind2 });
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
function init(model, args) {
|
|
183
|
-
const state = {};
|
|
184
|
-
STATE.set(model, state);
|
|
185
|
-
args = args.flat().filter((arg) => {
|
|
186
|
-
if (typeof arg != "string")
|
|
187
|
-
return true;
|
|
188
|
-
ID.set(model, arg);
|
|
189
|
-
});
|
|
190
|
-
addListener(model, () => {
|
|
191
|
-
if (!PARENT.has(model))
|
|
192
|
-
PARENT.set(model, null);
|
|
193
|
-
for (const key in model) {
|
|
194
|
-
const desc = Object.getOwnPropertyDescriptor(model, key);
|
|
195
|
-
if ("value" in desc)
|
|
196
|
-
manage(model, key, desc.value, true);
|
|
197
|
-
}
|
|
198
|
-
for (const arg of args) {
|
|
199
|
-
const use = typeof arg == "function" ? arg.call(model, model) : arg;
|
|
200
|
-
if (use instanceof Promise)
|
|
201
|
-
use.catch((err) => {
|
|
202
|
-
console.error(`Async error in constructor for ${model}:`);
|
|
203
|
-
console.error(err);
|
|
204
|
-
});
|
|
205
|
-
else if (typeof use == "function")
|
|
206
|
-
addListener(model, use, null);
|
|
207
|
-
else if (typeof use == "object")
|
|
208
|
-
assign(model, use, true);
|
|
209
|
-
}
|
|
210
|
-
addListener(model, () => {
|
|
211
|
-
for (const [_, value] of model)
|
|
212
|
-
if (value instanceof Model && PARENT.get(value) === model)
|
|
213
|
-
value.set(null);
|
|
214
|
-
Object.freeze(state);
|
|
215
|
-
}, null);
|
|
216
|
-
return null;
|
|
217
|
-
});
|
|
218
|
-
}
|
|
219
|
-
function manage(target, key, value, silent) {
|
|
220
|
-
const state = STATE.get(target);
|
|
221
|
-
function get() {
|
|
222
|
-
return watch(this, key, state[key]);
|
|
223
|
-
}
|
|
224
|
-
function set(value2, silent2) {
|
|
225
|
-
update(target, key, value2, silent2);
|
|
226
|
-
if (value2 instanceof Model && !PARENT.has(value2)) {
|
|
227
|
-
PARENT.set(value2, target);
|
|
228
|
-
event(value2);
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
define(target, key, { set, get });
|
|
232
|
-
set(value, silent);
|
|
233
|
-
}
|
|
234
|
-
const OBSERVER = /* @__PURE__ */ new WeakMap();
|
|
235
|
-
function watch(from, key, value) {
|
|
236
|
-
const access = OBSERVER.get(from);
|
|
237
|
-
return access ? access(key, value) : value;
|
|
238
|
-
}
|
|
239
|
-
function fetch(subject, property, required) {
|
|
240
|
-
const state = STATE.get(subject);
|
|
241
|
-
if (property in state || required === false) {
|
|
242
|
-
const value = state[property];
|
|
243
|
-
if (value !== void 0 || !required)
|
|
244
|
-
return value;
|
|
245
|
-
}
|
|
246
|
-
if (METHODS.get(subject.constructor).has(property))
|
|
247
|
-
return METHOD.get(subject[property]);
|
|
248
|
-
const error = new Error(`${subject}.${property} is not yet available.`);
|
|
249
|
-
const promise = new Promise((resolve, reject) => {
|
|
250
|
-
addListener(subject, (key) => {
|
|
251
|
-
if (key === property) {
|
|
252
|
-
resolve(state[key]);
|
|
253
|
-
return null;
|
|
254
|
-
}
|
|
255
|
-
if (key === null)
|
|
256
|
-
reject(new Error(`${subject} is destroyed.`));
|
|
257
|
-
});
|
|
258
|
-
});
|
|
259
|
-
throw Object.assign(promise, {
|
|
260
|
-
toString: () => String(error),
|
|
261
|
-
name: "Suspense",
|
|
262
|
-
message: error.message,
|
|
263
|
-
stack: error.stack
|
|
264
|
-
});
|
|
265
|
-
}
|
|
266
|
-
let EXPORT;
|
|
267
|
-
function snapshot(model) {
|
|
268
|
-
const values = {};
|
|
269
|
-
let isNotRecursive;
|
|
270
|
-
if (!EXPORT) {
|
|
271
|
-
isNotRecursive = true;
|
|
272
|
-
EXPORT = /* @__PURE__ */ new Map([[model, values]]);
|
|
273
|
-
}
|
|
274
|
-
for (let [key, value] of model) {
|
|
275
|
-
if (EXPORT.has(value))
|
|
276
|
-
value = EXPORT.get(value);
|
|
277
|
-
else if (value && typeof value == "object" && "get" in value && typeof value.get === "function")
|
|
278
|
-
EXPORT.set(value, value = value.get());
|
|
279
|
-
values[key] = value;
|
|
280
|
-
}
|
|
281
|
-
if (isNotRecursive)
|
|
282
|
-
EXPORT = void 0;
|
|
283
|
-
return Object.freeze(values);
|
|
284
|
-
}
|
|
285
|
-
function update(subject, key, value, arg) {
|
|
286
|
-
const state = STATE.get(subject);
|
|
287
|
-
if (Object.isFrozen(state))
|
|
288
|
-
throw new Error(`Tried to update ${subject}.${String(key)} but model is destroyed.`);
|
|
289
|
-
const previous = state[key];
|
|
290
|
-
if (typeof arg == "function") {
|
|
291
|
-
const out = arg.call(subject, value, previous);
|
|
292
|
-
if (out === false)
|
|
293
|
-
return false;
|
|
294
|
-
if (typeof out == "function")
|
|
295
|
-
value = out();
|
|
296
|
-
}
|
|
297
|
-
if (value === previous && key in state)
|
|
298
|
-
return;
|
|
299
|
-
state[key] = value;
|
|
300
|
-
if (arg !== true)
|
|
301
|
-
event(subject, key);
|
|
302
|
-
return true;
|
|
303
|
-
}
|
|
304
|
-
function uid() {
|
|
305
|
-
return (0.278 + Math.random() * 0.722).toString(36).substring(2, 8).toUpperCase();
|
|
306
|
-
}
|
|
307
|
-
export {
|
|
308
|
-
METHOD,
|
|
309
|
-
Model,
|
|
310
|
-
PARENT,
|
|
311
|
-
STATE,
|
|
312
|
-
event,
|
|
313
|
-
fetch,
|
|
314
|
-
uid,
|
|
315
|
-
update,
|
|
316
|
-
watch
|
|
317
|
-
};
|
|
318
|
-
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vc3JjL21vZGVsLnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyJpbXBvcnQgeyBhZGRMaXN0ZW5lciwgY3JlYXRlRWZmZWN0LCBldmVudCwgT2JzZXJ2YWJsZSwgT25VcGRhdGUsIFBFTkRJTkdfS0VZUyB9IGZyb20gJy4vY29udHJvbCc7XG5cbmNvbnN0IGRlZmluZSA9IE9iamVjdC5kZWZpbmVQcm9wZXJ0eTtcblxuLyoqIFJlZ2lzdGVyIGZvciBhbGwgYWN0aXZlIG1vZGVscyB2aWEgc3RyaW5nIGlkZW50aWZpZXJzICh1c3VhbGx5IHVuaXF1ZSkuICovXG5jb25zdCBJRCA9IG5ldyBXZWFrTWFwPE1vZGVsLCBzdHJpbmc+KCk7XG5cbi8qKiBJbnRlcm5hbCBzdGF0ZSBhc3NpZ25lZCB0byBtb2RlbHMuICovXG5jb25zdCBTVEFURSA9IG5ldyBXZWFrTWFwPE1vZGVsLCBSZWNvcmQ8c3RyaW5nIHwgbnVtYmVyIHwgc3ltYm9sLCB1bmtub3duPj4oKTtcblxuLyoqIEV4dGVybmFsIGxpc3RlbmVycyBmb3IgYW55IGdpdmVuIE1vZGVsLiAqL1xuY29uc3QgTk9USUZZID0gbmV3IFdlYWtNYXA8TW9kZWwuVHlwZSwgU2V0PE9uVXBkYXRlPj4oKTtcblxuLyoqIFBhcmVudC1jaGlsZCByZWxhdGlvbnNoaXBzLiAqL1xuY29uc3QgUEFSRU5UID0gbmV3IFdlYWtNYXA8TW9kZWwsIE1vZGVsIHwgbnVsbD4oKTtcblxuLyoqIExpc3Qgb2YgbWV0aG9kcyBkZWZpbmVkIGJ5IGEgZ2l2ZW4gdHlwZS4gKi9cbmNvbnN0IE1FVEhPRFMgPSBuZXcgV2Vha01hcDxNb2RlbC5UeXBlLCBNYXA8c3RyaW5nLCAodmFsdWU6IGFueSkgPT4gdm9pZD4+KCk7XG5cbi8qKiBSZWZlcmVuY2UgYm91bmQgaW5zdGFuY2UgbWV0aG9kcyB0byByZWFsIG9uZXMuICovXG5jb25zdCBNRVRIT0QgPSBuZXcgV2Vha01hcDxhbnksIGFueT4oKTtcblxuZGVjbGFyZSBuYW1lc3BhY2UgTW9kZWwge1xuICAvKiogQW55IHR5cGUgb2YgTW9kZWwsIHVzaW5nIG93biBjbGFzcyBjb25zdHJ1Y3RvciBhcyBpdHMgaWRlbnRpZmllci4gKi9cbiAgdHlwZSBUeXBlPFQgZXh0ZW5kcyBNb2RlbCA9IE1vZGVsPiA9XG4gICAgKGFic3RyYWN0IG5ldyAoLi4uYXJnczogYW55W10pID0+IFQpICYgdHlwZW9mIE1vZGVsO1xuXG4gIC8qKiBBIE1vZGVsIGNvbnN0cnVjdG9yLCBidXQgd2hpY2ggaXMgbm90IGFic3RyYWN0LiAqL1xuICB0eXBlIEluaXQ8VCBleHRlbmRzIE1vZGVsID0gTW9kZWw+ID1cbiAgICAobmV3ICguLi5hcmdzOiBNb2RlbC5BcmdzPFQ+KSA9PiBUKSAmIE9taXQ8dHlwZW9mIE1vZGVsLCBuZXZlcj47XG5cbiAgLyoqXG4gICAqIE1vZGVsIGNvbnN0cnVjdG9yIGNhbGxiYWNrIC0gaXMgY2FsbGVkIHdoZW4gTW9kZWwgZmluaXNoZXMgaW50aWFsaXppbmcuXG4gICAqIFJldHVybmVkIGZ1bmN0aW9uIHdpbGwgcnVuIHdoZW4gbW9kZWwgaXMgZGVzdHJveWVkLlxuICAgKi9cbiAgdHlwZSBDYWxsYmFjazxUIGV4dGVuZHMgTW9kZWwgPSBNb2RlbD4gPVxuICAgICh0aGlzOiBULCB0aGlzQXJnOiBUKSA9PiBQcm9taXNlPHZvaWQ+IHwgKCgpID0+IHZvaWQpIHwgQXNzaWduPFQ+IHwgdm9pZDtcblxuICAvKiogTW9kZWwgY29uc3RydWN0b3IgYXJndW1lbnQgKi9cbiAgdHlwZSBBcmd1bWVudDxUIGV4dGVuZHMgTW9kZWwgPSBNb2RlbD4gPSBBc3NpZ248VD4gfCBDYWxsYmFjazxUPiB8IHN0cmluZyB8IHZvaWQ7XG5cbiAgLyoqIE1vZGVsIGNvbnN0cnVjdG9yIGFyZ3VtZW50cyAqL1xuICB0eXBlIEFyZ3M8VCBleHRlbmRzIE1vZGVsID0gYW55PiA9IChBcmd1bWVudDxUPiB8IEFyZ3M8VD4pW107XG5cbiAgLyoqIFN1YnNldCBvZiBga2V5b2YgVGAgd2hpY2ggYXJlIG5vdCBtZXRob2RzIG9yIGRlZmluZWQgYnkgYmFzZSBNb2RlbCBVLiAqKi9cbiAgdHlwZSBGaWVsZDxUPiA9IEV4Y2x1ZGU8a2V5b2YgVCwga2V5b2YgTW9kZWw+O1xuXG4gIC8qKiBBbnkgdmFsaWQga2V5IGZvciBtb2RlbCwgaW5jbHVkaW5nIGJ1dCBub3QgbGltaXRlZCB0byBGaWVsZDxUPi4gKi9cbiAgdHlwZSBFdmVudDxUPiA9IEZpZWxkPFQ+IHwgKHN0cmluZyAmIHt9KSB8IG51bWJlciB8IHN5bWJvbDtcblxuICAvKiogT2JqZWN0IG92ZXJsYXkgdG8gb3ZlcnJpZGUgdmFsdWVzIGFuZCBtZXRob2RzIG9uIGEgbW9kZWwuICovXG4gIHR5cGUgQXNzaWduPFQ+ID0ge1xuICAgIFtLIGluIEZpZWxkPFQ+XT86XG4gICAgICBUW0tdIGV4dGVuZHMgKC4uLmFyZ3M6IGluZmVyIEEpID0+IGluZmVyIFIgXG4gICAgICAgID8gKHRoaXM6IFQsIC4uLmFyZ3M6IEEpID0+IFJcbiAgICAgICAgOiBUW0tdO1xuICB9ICYgUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG5cbiAgLyoqIEV4cG9ydC9JbXBvcnQgY29tcGF0aWJsZSB2YWx1ZSBmb3IgYSBnaXZlbiBwcm9wZXJ0eSBpbiBhIE1vZGVsLiAqL1xuICB0eXBlIEV4cG9ydDxSPiA9IFIgZXh0ZW5kcyB7IGdldCgpOiBpbmZlciBUIH0gPyBUIDogUjtcblxuICAvKiogVmFsdWUgZm9yIGEgcHJvcGVydHkgbWFuYWdlZCBieSBhIG1vZGVsLiAqL1xuICB0eXBlIFZhbHVlPFQgZXh0ZW5kcyBNb2RlbCwgSyBleHRlbmRzIEV2ZW50PFQ+PiA9XG4gICAgSyBleHRlbmRzIGtleW9mIFQgPyBFeHBvcnQ8VFtLXT4gOiB1bmtub3duO1xuXG4gIHR5cGUgT25FdmVudDxUIGV4dGVuZHMgTW9kZWw+ID1cbiAgICAodGhpczogVCwga2V5OiB1bmtub3duLCBzb3VyY2U6IFQpID0+ICgoKSA9PiB2b2lkKSB8IHZvaWQgfCBudWxsO1xuXG4gIHR5cGUgT25VcGRhdGU8VCBleHRlbmRzIE1vZGVsLCBLIGV4dGVuZHMgRXZlbnQ8VD4+ID1cbiAgICAodGhpczogVCwga2V5OiBLLCB0aGlzQXJnOiBLKSA9PiB2b2lkO1xuXG4gIC8qKlxuICAgKiBWYWx1ZXMgZnJvbSBjdXJyZW50IHN0YXRlIG9mIGdpdmVuIG1vZGVsLlxuICAgKiBEaWZmZXJzIGZyb20gYFZhbHVlc2AgYXMgdmFsdWVzIGhlcmUgd2lsbCBkcmlsbFxuICAgKiBpbnRvIFwicmVhbFwiIHZhbHVlcyBoZWxkIGJ5IGV4b3RpY3MgbGlrZSByZWYuT2JqZWN0LlxuICAgKi9cbiAgdHlwZSBTdGF0ZTxUPiA9IHsgW1AgaW4gRmllbGQ8VD5dOiBFeHBvcnQ8VFtQXT4gfTtcblxuICAvKiogT2JqZWN0IGNvbXBlcmFibGUgdG8gZGF0YSBmb3VuZCBpbiBULiAqL1xuICB0eXBlIFZhbHVlczxUPiA9IHsgW1AgaW4gRmllbGQ8VD5dPzogRXhwb3J0PFRbUF0+IH07XG5cbiAgLyoqIEV4b3RpYyB2YWx1ZSwgd2hlcmUgYWN0dWFsIHZhbHVlIGlzIGNvbnRhaW5lZCB3aXRoaW4uICovXG4gIHR5cGUgUmVmPFQgPSBhbnk+ID0ge1xuICAgIChuZXh0OiBUKTogdm9pZDtcbiAgICBjdXJyZW50OiBUIHwgbnVsbDtcbiAgfVxuXG4gIC8qKlxuICAgKiBBIGNhbGxiYWNrIGZ1bmN0aW9uIHdoaWNoIGlzIHN1YnNjcmliZWQgdG8gcGFyZW50IGFuZCB1cGRhdGVzIHdoZW4gYWNjZXNzZWQgcHJvcGVydGllcyBjaGFuZ2UuXG4gICAqIFxuICAgKiBAcGFyYW0gY3VycmVudCAtIEN1cnJlbnQgc3RhdGUgb2YgdGhpcyBtb2RlbC4gVGhpcyBpcyBhIHByb3h5IHdoaWNoIGRldGVjdHMgcHJvcGVydGllcyB3aGljaFxuICAgKiB3aGVyZSBhY2Nlc3NlZCwgYW5kIHRodXMgZGVwZW5kZWQgdXBvbiB0byBzdGF5IGN1cnJlbnQuXG4gICAqIFxuICAgKiBAcGFyYW0gdXBkYXRlIC0gU2V0IG9mIHByb3BlcnRpZXMgd2hpY2ggaGF2ZSBjaGFuZ2VkLCBhbmQgZXZlbnRzIGZpcmVkLCBzaW5jZSBsYXN0IHVwZGF0ZS5cbiAgICogXG4gICAqIEByZXR1cm5zIEEgY2FsbGJhY2sgZnVuY3Rpb24gd2hpY2ggd2lsbCBiZSBjYWxsZWQgd2hlbiB0aGlzIGVmZmVjdCBpcyBzdGFsZS5cbiAgICovXG4gIHR5cGUgRWZmZWN0PFQ+ID0gKHRoaXM6IFQsIGN1cnJlbnQ6IFQsIHVwZGF0ZTogU2V0PEV2ZW50PFQ+PikgPT5cbiAgICBFZmZlY3RDYWxsYmFjayB8IFByb21pc2U8dm9pZD4gfCBudWxsIHwgdm9pZDtcblxuICAvKipcbiAgICogQSBjYWxsYmFjayBmdW5jdGlvbiByZXR1cm5lZCBieSBlZmZlY3QuIFdpbGwgYmUgY2FsbGVkIHdoZW4gZWZmZWN0IGlzIHN0YWxlLlxuICAgKiBcbiAgICogQHBhcmFtIHVwZGF0ZSAtIGB0cnVlYCBpZiB1cGRhdGUgaXMgcGVuZGluZywgYGZhbHNlYCBlZmZlY3QgaGFzIGJlZW4gY2FuY2VsbGVkLCBgbnVsbGAgaWYgbW9kZWwgaXMgZGVzdHJveWVkLlxuICAgKi9cbiAgdHlwZSBFZmZlY3RDYWxsYmFjayA9ICgodXBkYXRlOiBib29sZWFuIHwgbnVsbCkgPT4gdm9pZCk7XG5cbiAgLyoqXG4gICAqIFByb3BlcnR5IGluaXRpYWxpemVyLCB3aWxsIHJ1biB1cG9uIGluc3RhbmNlIGNyZWF0aW9uLlxuICAgKiBPcHRpb25hbCByZXR1cm5lZCBjYWxsYmFjayB3aWxsIHJ1biB3aGVuIG9uY2UgdXBvbiBmaXJzdCBhY2Nlc3MuXG4gICAqL1xuICB0eXBlIEluc3RydWN0aW9uPFQgPSBhbnksIE0gZXh0ZW5kcyBNb2RlbCA9IGFueT4gPVxuICAgIC8vIFRPRE86IFNob3VsZCB0aGlzIGFsbG93IGZvciBudW1iZXJzL3N5bWJvbCBwcm9wZXJ0aWVzP1xuICAgICh0aGlzOiBNLCBrZXk6IEV4dHJhY3Q8RmllbGQ8TT4sIHN0cmluZz4sIHRoaXNBcmc6IE0sIHN0YXRlOiBTdGF0ZTxNPikgPT5cbiAgICAgIERlc2NyaXB0b3I8VD4gfCAoKHNvdXJjZTogTSkgPT4gVCkgfCB2b2lkO1xuXG4gIHR5cGUgR2V0dGVyPFQ+ID0gKHNvdXJjZTogTW9kZWwpID0+IFQ7XG4gIHR5cGUgU2V0dGVyPFQ+ID0gKHZhbHVlOiBULCBwcmV2aW91czogVCkgPT4gYm9vbGVhbiB8IHZvaWQgfCAoKCkgPT4gVCk7XG5cbiAgdHlwZSBEZXNjcmlwdG9yPFQgPSBhbnk+ID0ge1xuICAgIGdldD86IEdldHRlcjxUPiB8IGJvb2xlYW47XG4gICAgc2V0PzogU2V0dGVyPFQ+IHwgYm9vbGVhbjtcbiAgICBlbnVtZXJhYmxlPzogYm9vbGVhbjtcbiAgICB2YWx1ZT86IFQ7XG4gIH1cbn1cblxuaW50ZXJmYWNlIE1vZGVsIHtcbiAgLyoqXG4gICAqIExvb3BiYWNrIHRvIGluc3RhbmNlIG9mIHRoaXMgbW9kZWwuIFRoaXMgaXMgdXNlZnVsIHdoZW4gaW4gYSBzdWJzY3JpYmVkIGNvbnRleHQsXG4gICAqIHRvIGtlZXAgd3JpdGUgYWNjZXNzIHRvIGB0aGlzYCBhZnRlciBhIGRlc3RydWN0dXJlLiBZb3UgY2FuIHVzZSBpdCB0byByZWFkIHZhcmlhYmxlcyBzaWxlbnRseSBhcyB3ZWxsLlxuICAgKiovXG4gIGlzOiB0aGlzO1xufVxuXG5hYnN0cmFjdCBjbGFzcyBNb2RlbCBpbXBsZW1lbnRzIE9ic2VydmFibGUge1xuICBjb25zdHJ1Y3RvciguLi5hcmdzOiBNb2RlbC5BcmdzKXtcbiAgICBwcmVwYXJlKHRoaXMpO1xuICAgIGRlZmluZSh0aGlzLCBcImlzXCIsIHsgdmFsdWU6IHRoaXMgfSk7XG4gICAgaW5pdCh0aGlzLCBhcmdzKTtcbiAgfVxuXG4gIFtPYnNlcnZhYmxlXShjYWxsYmFjazogT2JzZXJ2YWJsZS5DYWxsYmFjaywgcmVxdWlyZWQ/OiBib29sZWFuKXtcbiAgICBjb25zdCB3YXRjaCA9IG5ldyBTZXQ8dW5rbm93bj4oKTtcbiAgICBjb25zdCBwcm94eSA9IE9iamVjdC5jcmVhdGUodGhpcyk7XG4gICAgXG4gICAgYWRkTGlzdGVuZXIodGhpcywgKGtleSkgPT4ge1xuICAgICAgaWYod2F0Y2guaGFzKGtleSkpXG4gICAgICAgIGNhbGxiYWNrKCk7XG4gICAgfSk7XG5cbiAgICBPQlNFUlZFUi5zZXQocHJveHksIChrZXksIHZhbHVlKSA9PiB7XG4gICAgICBpZih2YWx1ZSA9PT0gdW5kZWZpbmVkICYmIHJlcXVpcmVkKVxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7dGhpc30uJHtrZXl9IGlzIHJlcXVpcmVkIGluIHRoaXMgY29udGV4dC5gKTtcblxuICAgICAgd2F0Y2guYWRkKGtleSk7XG5cbiAgICAgIGlmKHZhbHVlIGluc3RhbmNlb2YgT2JqZWN0ICYmIE9ic2VydmFibGUgaW4gdmFsdWUpXG4gICAgICAgIHJldHVybiB2YWx1ZVtPYnNlcnZhYmxlXShjYWxsYmFjaywgcmVxdWlyZWQpIHx8IHZhbHVlO1xuXG4gICAgICByZXR1cm4gdmFsdWU7XG4gICAgfSk7XG5cbiAgICByZXR1cm4gcHJveHkgYXMgdGhpcztcbiAgfVxuXG4gIC8qKlxuICAgKiBQdWxsIGN1cnJlbnQgdmFsdWVzIGZyb20gc3RhdGUuIEZsYXR0ZW5zIGFsbCBtb2RlbHMgYW5kIGV4b3RpYyB2YWx1ZXMgcmVjdXJzaXZlbHkuXG4gICAqIFxuICAgKiBAcmV0dXJucyBPYmplY3Qgd2l0aCBhbGwgdmFsdWVzIGZyb20gdGhpcyBtb2RlbC5cbiAgICoqL1xuICBnZXQoKTogTW9kZWwuU3RhdGU8dGhpcz47XG5cbiAgLyoqXG4gICAqIFJ1biBhIGZ1bmN0aW9uIHdoaWNoIHdpbGwgcnVuIGF1dG9tYXRpY2FsbHkgd2hlbiBhY2Nlc3NlZCB2YWx1ZXMgY2hhbmdlLlxuICAgKiBcbiAgICogQHBhcmFtIGVmZmVjdCBGdW5jdGlvbiB0byBydW4sIGFuZCBhZ2FpbiB3aGVuZXZlciBhY2Nlc3NlZCB2YWx1ZXMgY2hhbmdlLlxuICAgKiAgICAgICAgICAgICAgIElmIGVmZmVjdCByZXR1cm5zIGEgZnVuY3Rpb24sIGl0IHdpbGwgYmUgY2FsbGVkIHdoZW4gYSBjaGFuZ2Ugb2NjdXJzIChzeW5jcm9ub3VzbHkpLFxuICAgKiAgICAgICAgICAgICAgIGVmZmVjdCBpcyBjYW5jZWxsZWQsIG9yIHBhcmVudCBtb2RlbCBpcyBkZXN0cm95ZWQuXG4gICAqIEByZXR1cm5zIEZ1bmN0aW9uIHRvIGNhbmNlbCBsaXN0ZW5lci5cbiAgICovXG4gIGdldChlZmZlY3Q6IE1vZGVsLkVmZmVjdDx0aGlzPik6ICgpID0+IHZvaWQ7XG5cbiAgLyoqXG4gICAqIEdldCB2YWx1ZSBvZiBhIHByb3BlcnR5LlxuICAgKiBcbiAgICogQHBhcmFtIGtleSAtIFByb3BlcnR5IHRvIGdldCB2YWx1ZSBvZi5cbiAgICogQHBhcmFtIHJlcXVpcmVkIC0gSWYgdHJ1ZSwgd2lsbCB0aHJvdyBhbiBlcnJvciBpZiBwcm9wZXJ0eSBpcyBub3QgYXZhaWxhYmxlLlxuICAgKiBAcmV0dXJucyBWYWx1ZSBvZiBwcm9wZXJ0eS5cbiAgICovXG4gIGdldDxUIGV4dGVuZHMgTW9kZWwuRXZlbnQ8dGhpcz4+KGtleTogVCwgcmVxdWlyZWQ/OiBib29sZWFuKTogTW9kZWwuVmFsdWU8dGhpcywgVD47XG5cbiAgLyoqXG4gICAqIFJ1biBhIGZ1bmN0aW9uIHdoZW4gYSBwcm9wZXJ0eSBpcyB1cGRhdGVkLlxuICAgKiBcbiAgICogQHBhcmFtIGtleSAtIFByb3BlcnR5IHRvIHdhdGNoIGZvciB1cGRhdGVzLlxuICAgKiBAcGFyYW0gY2FsbGJhY2sgLSBGdW5jdGlvbiB0byBjYWxsIHdoZW4gcHJvcGVydHkgaXMgdXBkYXRlZC5cbiAgICogQHJldHVybnMgRnVuY3Rpb24gdG8gY2FuY2VsIGxpc3RlbmVyLlxuICAgKi9cbiAgZ2V0PFQgZXh0ZW5kcyBNb2RlbC5FdmVudDx0aGlzPj4oa2V5OiBULCBjYWxsYmFjazogTW9kZWwuT25VcGRhdGU8dGhpcywgVD4pOiAoKSA9PiB2b2lkO1xuXG4gIC8qKlxuICAgKiBDaGVjayBpZiBtb2RlbCBpcyBleHBpcmVkLlxuICAgKiBcbiAgICogQHBhcmFtIHN0YXR1cyAtIGBudWxsYCB0byBjaGVjayBpZiBtb2RlbCBpcyBleHBpcmVkLlxuICAgKiBAcmV0dXJucyBgdHJ1ZWAgaWYgbW9kZWwgaXMgZXhwaXJlZCwgYGZhbHNlYCBvdGhlcndpc2UuXG4gICAqL1xuICBnZXQoc3RhdHVzOiBudWxsKTogYm9vbGVhbjtcblxuICAvKipcbiAgICogQ2FsbGJhY2sgd2hlbiBtb2RlbCBpcyB0byBiZSBkZXN0cm95ZWQuXG4gICAqIFxuICAgKiBAcGFyYW0gY2FsbGJhY2sgLSBGdW5jdGlvbiB0byBjYWxsIHdoZW4gbW9kZWwgaXMgZGVzdHJveWVkLlxuICAgKiBAcmV0dXJucyBGdW5jdGlvbiB0byBjYW5jZWwgbGlzdGVuZXIuXG4gICAqL1xuICBnZXQoc3RhdHVzOiBudWxsLCBjYWxsYmFjazogKCkgPT4gdm9pZCk6ICgpID0+IHZvaWQ7XG5cbiAgZ2V0KGFyZzE/OiBNb2RlbC5FZmZlY3Q8dGhpcz4gfCBzdHJpbmcgfCBudWxsLCBhcmcyPzogYm9vbGVhbiB8IE1vZGVsLk9uVXBkYXRlPHRoaXMsIGFueT4pe1xuICAgIGNvbnN0IHNlbGYgPSB0aGlzLmlzO1xuXG4gICAgaWYodHlwZW9mIGFyZzEgPT0gXCJmdW5jdGlvblwiKXtcbiAgICAgIGNvbnN0IGVmZmVjdCA9IE1FVEhPRC5nZXQoYXJnMSkgfHwgYXJnMTtcbiAgICAgIGxldCBwZW5kaW5nID0gbmV3IFNldDxNb2RlbC5FdmVudDx0aGlzPj4oKTtcblxuICAgICAgcmV0dXJuIGNyZWF0ZUVmZmVjdChzZWxmLCAocHJveHkpID0+IHtcbiAgICAgICAgY29uc3QgY2IgPSBlZmZlY3QuY2FsbChwcm94eSwgcHJveHksIHBlbmRpbmcpO1xuXG4gICAgICAgIHJldHVybiBjYiA9PT0gbnVsbCA/IG51bGwgOiAoKHVwZGF0ZSkgPT4ge1xuICAgICAgICAgIHBlbmRpbmcgPSBQRU5ESU5HX0tFWVMuZ2V0KHNlbGYpITtcbiAgICAgICAgICBpZih0eXBlb2YgY2IgPT0gXCJmdW5jdGlvblwiKVxuICAgICAgICAgICAgY2IodXBkYXRlKTtcbiAgICAgICAgfSlcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHJldHVybiAoXG4gICAgICBhcmcxID09PSB1bmRlZmluZWQgPyBzbmFwc2hvdChzZWxmKSA6XG4gICAgICB0eXBlb2YgYXJnMiA9PSBcImZ1bmN0aW9uXCIgPyBhZGRMaXN0ZW5lcihzZWxmLCBhcmcyLCBhcmcxKSA6XG4gICAgICBhcmcxID09PSBudWxsID8gT2JqZWN0LmlzRnJvemVuKFNUQVRFLmdldChzZWxmKSkgOlxuICAgICAgZmV0Y2goc2VsZiwgYXJnMSwgYXJnMilcbiAgICApXG4gIH1cblxuICAvKipcbiAgICogR2V0IHVwZGF0ZSBpbiBwcm9ncmVzcy5cbiAgICpcbiAgICogQHJldHVybnMgUHJvbWlzZSB3aGljaCByZXNvbHZlcyBvYmplY3Qgd2l0aCB1cGRhdGVkIHZhbHVlcywgYHVuZGVmaW5lZGAgaWYgdGhlcmUgbm8gdXBkYXRlIGlzIHBlbmRpbmcuXG4gICAqKi9cbiAgc2V0KCk6IFByb21pc2VMaWtlPE1vZGVsLkV2ZW50PHRoaXM+W10+IHwgdW5kZWZpbmVkO1xuXG4gIC8qKlxuICAgKiBVcGRhdGUgbXVsaXRwbGUgcHJvcGVydGllcyBhdCBvbmNlLiBNZXJnZXMgYXJndW1lbnQgd2l0aCBjdXJyZW50IHN0YXRlLlxuICAgKiBQcm9wZXJ0aWVzIHdoaWNoIGFyZSBub3QgbWFuYWdlZCBieSB0aGlzIG1vZGVsIHdpbGwgYmUgaWdub3JlZC5cbiAgICogXG4gICAqIEBwYXJhbSBhc3NpZ24gLSBPYmplY3Qgd2l0aCBwcm9wZXJ0aWVzIHRvIHVwZGF0ZS5cbiAgICogQHBhcmFtIHNpbGVudCAtIElmIGFuIHVwZGF0ZSBkb2VzIG9jY3VyLCBsaXN0ZW5lcnMgd2lsbCBub3QgYmUgcmVmcmVzaGVkIGF1dG9tYXRpY2FsbHkuXG4gICAqIEByZXR1cm5zIFByb21pc2UgcmVzb2x2aW5nIGFuIGFycmF5IG9mIGtleXMgdXBkYXRlZCwgYHVuZGVmaW5lZGAgKGltbWVkaWF0ZWx5KSBpZiBhIG5vb3AuXG4gICAqL1xuICBzZXQoYXNzaWduPzogTW9kZWwuQXNzaWduPHRoaXM+LCBzaWxlbnQ/OiBib29sZWFuKTogUHJvbWlzZUxpa2U8TW9kZWwuRXZlbnQ8dGhpcz5bXT4gfCB1bmRlZmluZWQ7XG5cbiAgLyoqXG4gICAqIFB1c2ggYW4gdXBkYXRlLiBUaGlzIHdpbGwgbm90IGNoYW5nZSB0aGUgdmFsdWUgb2YgYXNzb2NpYXRlZCBwcm9wZXJ0eS5cbiAgICogXG4gICAqIFVzZWZ1bCB3aGVyZSBhIHByb3BlcnR5IHZhbHVlIGludGVybmFsbHkgaGFzIGNoYW5nZWQsIGJ1dCB0aGUgb2JqZWN0IGlzIHRoZSBzYW1lLlxuICAgKiBGb3IgZXhhbXBsZTogQW4gYXJyYXkgaGFzIHB1c2hlZCBhIG5ldyB2YWx1ZSwgb3IgYSBuZXN0ZWQgcHJvcGVydHkgaXMgdXBkYXRlZC5cbiAgICogXG4gICAqIFlvdSBjYW4gYWxzbyB1c2UgdGhpcyB0byBkaXNwYXRjaCBhcmJpdHJhcnkgZXZlbnRzLlxuICAgKiBTeW1ib2xzIGFyZSByZWNvbW1lbmRlZCBhcyBub24tcHJvcGVydHkgZXZlbnRzLCBob3dldmVyIHlvdSBjYW4gdXNlIGFueSBzdHJpbmcuXG4gICAqIElmIGRvaW5nIHNvLCBiZSBzdXJlIHRvIGF2b2lkIGNvbGxpc2lvbnMgd2l0aCBwcm9wZXJ0eSBuYW1lcyEgQW4gZWFzeSB3YXkgdG8gZG8gdGhpcyBpc1xuICAgKiB0byBwcmVmaXggYW4gZXZlbnQgd2l0aCBcIiFcIiBhbmQvb3IgdXNlIGRhc2gtY2FzZS4gZS5nLiBgc2V0KFwiIWV2ZW50XCIpYCBvciBgc2V0KFwibXktZXZlbnRcIilgLlxuICAgKiBcbiAgICogQHBhcmFtIGtleSAtIFByb3BlcnR5IG9yIGV2ZW50IHRvIGRpc3BhdGNoLlxuICAgKiBAcmV0dXJucyBQcm9taXNlIHJlc29sdmVzIGFuIGFycmF5IG9mIGtleXMgdXBkYXRlZC5cbiAgICovXG4gIHNldChrZXk6IE1vZGVsLkV2ZW50PHRoaXM+KTogUHJvbWlzZUxpa2U8TW9kZWwuRXZlbnQ8dGhpcz5bXT47XG5cbiAgLyoqXG4gICAqIFNldCBhIHZhbHVlIGZvciBhIHByb3BlcnR5LiBUaGlzIHdpbGwgdXBkYXRlIHRoZSB2YWx1ZSBhbmQgbm90aWZ5IGxpc3RlbmVycy5cbiAgICogXG4gICAqICoqVXNlIHdpdGggY2F1dGlvbiEqKiBLZXkgbm9yIHZhbHVlIGFyZSBjaGVja2VkIGZvciB2YWxpZGl0eS5cbiAgICogXG4gICAqIFRoaXMgaXMgbWVhbnQgZm9yIGFzc2lnbmluZyB2YWx1ZXMgcHJvZ3JhbW1hdGljYWxseSxcbiAgICogd2hlcmUgc2ltcGxlIGFzc2lnbm1lbnQgaXMgbm90IHByYWN0aWNhYmxlLlxuICAgKiBcbiAgICogRm9yIGV4YW1wbGU6IGAodGhpcyBhcyBhbnkpW215UHJvcGVydHldID0gdmFsdWU7YFxuICAgKiBcbiAgICogQHBhcmFtIGtleSAtIFByb3BlcnR5IHRvIHNldCB2YWx1ZSBmb3IuXG4gICAqIEBwYXJhbSB2YWx1ZSAtIFZhbHVlIHRvIHNldCBmb3IgcHJvcGVydHkuXG4gICAqIEBwYXJhbSBpbml0IC0gSWYgdHJ1ZSwgbW9kZWwgd2lsbCBiZWdpbiB0byBtYW5hZ2UgdGhlIHByb3BlcnR5IGlmIGl0IGlzIG5vdCBhbHJlYWR5LlxuICAgKiBAcmV0dXJucyBQcm9taXNlIHJlc29sdmVzIGFuIGFycmF5IG9mIGtleXMgdXBkYXRlZC5cbiAgICovXG4gIHNldChrZXk6IE1vZGVsLkV2ZW50PHRoaXM+LCB2YWx1ZTogdW5rbm93biwgaW5pdD86IGJvb2xlYW4pOiBQcm9taXNlTGlrZTxNb2RlbC5FdmVudDx0aGlzPltdPjtcblxuICAvKipcbiAgICogQ2FsbCBhIGZ1bmN0aW9uIHdoZW4gdXBkYXRlIG9jY3Vycy5cbiAgICogXG4gICAqIEdpdmVuIGZ1bmN0aW9uIGlzIGNhbGxlZCBmb3IgZXZlcnkgYXNzaWdubWVudCAod2hpY2ggY2hhbmdlcyB2YWx1ZSkgb3IgZXhwbGljaXQgYHNldGAuXG4gICAqIFxuICAgKiBUbyBydW4gbG9naWMgb24gZmluYWwgdmFsdWUgb25seSwgY2FsbGJhY2sgbWF5IHJldHVybiBhIGZ1bmN0aW9uLiBVc2luZyB0aGUgc2FtZVxuICAgKiBmdW5jdGlvbiBmb3Igb25lIG9yIG1vcmUgZXZlbnRzIHdpbGwgZW5zdXJlIGl0IGlzIGNhbGxlZCBvbmx5IHdoZW4gZXZlbnRzIGFyZSBzZXR0bGVkLlxuICAgKiBcbiAgICogQHBhcmFtIGNhbGxiYWNrIC0gRnVuY3Rpb24gdG8gY2FsbCB3aGVuIHVwZGF0ZSBvY2N1cnMuXG4gICAqIEByZXR1cm5zIEZ1bmN0aW9uIHRvIHJlbW92ZSBsaXN0ZW5lci4gV2lsbCByZXR1cm4gYHRydWVgIGlmIHJlbW92ZWQsIGBmYWxzZWAgaWYgaW5hY3RpdmUgYWxyZWFkeS5cbiAgICogXG4gICovXG4gIHNldChjYWxsYmFjazogTW9kZWwuT25FdmVudDx0aGlzPik6ICgpID0+IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIENhbGwgYSBmdW5jdGlvbiB3aGVuIGEgcHJvcGVydHkgaXMgdXBkYXRlZC5cbiAgICogVW5saWtlIGBnZXRgLCB0aGlzIGNhbHNsIHN5bmNocm9ub3VzbHkgYW5kIHdpbGwgZmlyZSBhcyBtYW55IHRpbWVzIGFzIHRoZSBwcm9wZXJ0eSBpcyB1cGRhdGVkLlxuICAgKiBcbiAgICogQHBhcmFtIGNhbGxiYWNrIC0gRnVuY3Rpb24gdG8gY2FsbCB3aGVuIHByb3BlcnR5IGlzIHVwZGF0ZWQuXG4gICAqIEBwYXJhbSBldmVudCAtIFByb3BlcnR5IHRvIHdhdGNoIGZvciB1cGRhdGVzLlxuICAgKi9cbiAgc2V0KGNhbGxiYWNrOiBNb2RlbC5PbkV2ZW50PHRoaXM+LCBldmVudDogTW9kZWwuRXZlbnQ8dGhpcz4gfCBudWxsKTogKCkgPT4gYm9vbGVhbjtcblxuICAvKipcbiAgICogRGVjbGFyZSBhbiBlbmQgdG8gdXBkYXRlcy4gVGhpcyBldmVudCBpcyBmaW5hbCBhbmQgd2lsbCBmcmVlemUgc3RhdGUuXG4gICAqIFRoaXMgZXZlbnQgY2FuIGJlIHdhdGNoZWQgZm9yIGFzIHdlbGwsIHRvIHJ1biBjbGVhbnVwIGxvZ2ljIGFuZCBpbnRlcm5hbGx5IHdpbGwgcmVtb3ZlIGFsbCBsaXN0ZW5lcnMuXG4gICAqIFxuICAgKiBAcGFyYW0gc3RhdHVzIC0gYG51bGxgIHRvIGVuZCB1cGRhdGVzLlxuICAgKi9cbiAgc2V0KHN0YXR1czogbnVsbCk6IHZvaWQ7XG5cbiAgc2V0KFxuICAgIGFyZzE/OiBNb2RlbC5PbkV2ZW50PHRoaXM+IHwgTW9kZWwuQXNzaWduPHRoaXM+IHwgTW9kZWwuRXZlbnQ8dGhpcz4gfCBudWxsLFxuICAgIGFyZzI/OiB1bmtub3duLFxuICAgIGFyZzM/OiBib29sZWFuKXtcblxuICAgIGNvbnN0IHNlbGYgPSB0aGlzLmlzO1xuXG4gICAgaWYodHlwZW9mIGFyZzEgPT0gXCJmdW5jdGlvblwiKVxuICAgICAgcmV0dXJuIGFkZExpc3RlbmVyKHNlbGYsIGtleSA9PiB7XG4gICAgICAgIGlmKGFyZzIgPT09IGtleSB8fCBhcmcyID09PSB1bmRlZmluZWQgJiYgdHlwZW9mIGtleSA9PSBcInN0cmluZ1wiKVxuICAgICAgICAgIHJldHVybiBhcmcxLmNhbGwoc2VsZiwga2V5LCBzZWxmKTtcbiAgICAgIH0pXG4gICAgICBcbiAgICBpZihhcmcxICYmIHR5cGVvZiBhcmcxID09IFwib2JqZWN0XCIpXG4gICAgICBhc3NpZ24oc2VsZiwgYXJnMSwgYXJnMiA9PT0gdHJ1ZSk7XG4gICAgZWxzZSBpZighYXJnMilcbiAgICAgIGV2ZW50KHNlbGYsIGFyZzEpO1xuICAgIGVsc2UgaWYoYXJnMylcbiAgICAgIG1hbmFnZShzZWxmLCBhcmcxIGFzIHN0cmluZyB8IG51bWJlciwgYXJnMik7XG4gICAgZWxzZVxuICAgICAgdXBkYXRlKHNlbGYsIGFyZzEgYXMgc3RyaW5nIHwgbnVtYmVyLCBhcmcyKVxuXG4gICAgY29uc3QgcGVuZGluZyA9IFBFTkRJTkdfS0VZUy5nZXQodGhpcyk7XG5cbiAgICBpZihwZW5kaW5nKVxuICAgICAgcmV0dXJuIDxQcm9taXNlTGlrZTxNb2RlbC5FdmVudDx0aGlzPltdPj4ge1xuICAgICAgICB0aGVuOiAocmVzKSA9PiBuZXcgUHJvbWlzZTxhbnk+KHJlcyA9PiB7XG4gICAgICAgICAgY29uc3QgcmVtb3ZlID0gYWRkTGlzdGVuZXIodGhpcywga2V5ID0+IHtcbiAgICAgICAgICAgIGlmKGtleSAhPT0gdHJ1ZSl7XG4gICAgICAgICAgICAgIHJlbW92ZSgpO1xuICAgICAgICAgICAgICByZXR1cm4gcmVzLmJpbmQobnVsbCwgQXJyYXkuZnJvbShwZW5kaW5nKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pLnRoZW4ocmVzKVxuICAgICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEl0ZXJhdGUgb3ZlciBtYW5hZ2VkIHByb3BlcnRpZXMgaW4gdGhpcyBpbnN0YW5jZSBvZiBNb2RlbC5cbiAgICogWWVpbGRzIHRoZSBrZXkgYW5kIGN1cnJlbnQgdmFsdWUgZm9yIGVhY2ggcHJvcGVydHkuXG4gICAqL1xuICBbU3ltYm9sLml0ZXJhdG9yXSgpOiBJdGVyYXRvcjxbc3RyaW5nLCB1bmtub3duXT4ge1xuICAgIHJldHVybiBPYmplY3QuZW50cmllcyhTVEFURS5nZXQodGhpcy5pcykhKVtTeW1ib2wuaXRlcmF0b3JdKCk7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlIGFuZCBhY3RpdmF0ZSBhIG5ldyBpbnN0YW5jZSBvZiB0aGlzIG1vZGVsLlxuICAgKiBcbiAgICogKipJbXBvcnRhbnQqKiAtIFVubGlrZSBgbmV3IHRoaXMoLi4uKWAgLSB0aGlzIG1ldGhvZCBhbHNvIGFjdGl2YXRlcyBzdGF0ZS5cbiAgICogXG4gICAqIEBwYXJhbSBhcmdzIC0gYXJndW1lbnRzIHNlbnQgdG8gY29uc3RydWN0b3JcbiAgICovXG4gIHN0YXRpYyBuZXc8VCBleHRlbmRzIE1vZGVsPih0aGlzOiBNb2RlbC5Jbml0PFQ+LCAuLi5hcmdzOiBNb2RlbC5BcmdzPFQ+KXtcbiAgICBjb25zdCBpbnN0YW5jZSA9IG5ldyB0aGlzKC4uLmFyZ3MpO1xuICAgIGV2ZW50KGluc3RhbmNlKTtcbiAgICByZXR1cm4gaW5zdGFuY2U7XG4gIH1cblxuICAvKipcbiAgICogU3RhdGljIGVxdWl2YWxlbnQgb2YgYHggaW5zdGFuY2VvZiB0aGlzYC5cbiAgICogRGV0ZXJtaW5lcyBpZiBwcm92aWRlZCBjbGFzcyBpcyBhIHN1YnR5cGUgb2YgdGhpcyBvbmUuXG4gICAqIElmIHNvLCBsYW5ndWFnZSBzZXJ2ZXIgd2lsbCBtYWtlIGF2YWlsYWJsZSBhbGwgc3RhdGljXG4gICAqIG1ldGhvZHMgYW5kIHByb3BlcnRpZXMgb2YgdGhpcyBjbGFzcy5cbiAgICovXG4gIHN0YXRpYyBpczxUIGV4dGVuZHMgTW9kZWwuVHlwZT4odGhpczogVCwgbWF5YmU6IHVua25vd24pOiBtYXliZSBpcyBUIHtcbiAgICByZXR1cm4gbWF5YmUgPT09IHRoaXMgfHwgdHlwZW9mIG1heWJlID09IFwiZnVuY3Rpb25cIiAmJiBtYXliZS5wcm90b3R5cGUgaW5zdGFuY2VvZiB0aGlzO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlZ2lzdGVyIGEgY2FsbGJhY2sgdG8gcnVuIHdoZW4gYW55IGluc3RhbmNlIG9mIHRoaXMgTW9kZWwgaXMgdXBkYXRlZC4gXG4gICAqL1xuICBzdGF0aWMgb248VCBleHRlbmRzIE1vZGVsPih0aGlzOiBNb2RlbC5UeXBlPFQ+LCBsaXN0ZW5lcjogTW9kZWwuT25FdmVudDxUPil7XG4gICAgbGV0IG5vdGlmeSA9IE5PVElGWS5nZXQodGhpcyk7XG5cbiAgICBpZighbm90aWZ5KVxuICAgICAgTk9USUZZLnNldCh0aGlzLCBub3RpZnkgPSBuZXcgU2V0KTtcblxuICAgIG5vdGlmeS5hZGQobGlzdGVuZXIpO1xuXG4gICAgcmV0dXJuICgpID0+IG5vdGlmeS5kZWxldGUobGlzdGVuZXIpO1xuICB9XG59XG5cbmRlZmluZShNb2RlbC5wcm90b3R5cGUsIFwidG9TdHJpbmdcIiwge1xuICB2YWx1ZSgpe1xuICAgIHJldHVybiBJRC5nZXQodGhpcy5pcyk7XG4gIH1cbn0pO1xuXG5kZWZpbmUoTW9kZWwsIFwidG9TdHJpbmdcIiwge1xuICB2YWx1ZSgpe1xuICAgIHJldHVybiB0aGlzLm5hbWU7XG4gIH1cbn0pO1xuXG5mdW5jdGlvbiBhc3NpZ24oc3ViamVjdDogTW9kZWwsIGRhdGE6IE1vZGVsLkFzc2lnbjxNb2RlbD4sIHNpbGVudD86IGJvb2xlYW4pe1xuICBjb25zdCBtZXRob2RzID0gTUVUSE9EUy5nZXQoc3ViamVjdC5jb25zdHJ1Y3RvciBhcyBNb2RlbC5UeXBlKSE7XG4gICAgXG4gIGZvcihjb25zdCBrZXkgaW4gZGF0YSl7XG4gICAgY29uc3QgYmluZCA9IG1ldGhvZHMuZ2V0KGtleSk7XG5cbiAgICBpZihiaW5kKVxuICAgICAgYmluZC5jYWxsKHN1YmplY3QsIGRhdGFba2V5XSk7XG4gICAgZWxzZSBpZihrZXkgaW4gc3ViamVjdCAmJiBrZXkgIT09IFwiaXNcIil7XG4gICAgICBjb25zdCBkZXNjID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihzdWJqZWN0LCBrZXkpITtcbiAgICAgIGNvbnN0IHNldCA9IGRlc2MgJiYgZGVzYy5zZXQgYXMgKHZhbHVlOiBhbnksIHNpbGVudD86IGJvb2xlYW4pID0+IHZvaWQ7XG5cbiAgICAgIGlmKHNldClcbiAgICAgICAgc2V0LmNhbGwoc3ViamVjdCwgZGF0YVtrZXldLCBzaWxlbnQpO1xuICAgICAgZWxzZVxuICAgICAgICAoc3ViamVjdCBhcyBhbnkpW2tleV0gPSBkYXRhW2tleV07XG4gICAgfVxuICB9XG59XG5cbi8qKiBBcHBseSBpbnN0cnVjdGlvbnMgYW5kIGluaGVyaXRlZCBldmVudCBsaXN0ZW5lcnMuIEVuc3VyZSBjbGFzcyBtZXRhZGF0YSBpcyByZWFkeS4gKi9cbmZ1bmN0aW9uIHByZXBhcmUobW9kZWw6IE1vZGVsKXtcbiAgbGV0IFQgPSBtb2RlbC5jb25zdHJ1Y3RvciBhcyBNb2RlbC5UeXBlO1xuXG4gIGlmKFQgPT09IE1vZGVsKVxuICAgIHRocm93IG5ldyBFcnJvcihcIkNhbm5vdCBjcmVhdGUgYmFzZSBNb2RlbC5cIik7XG5cbiAgY29uc3QgY2hhaW4gPSBbXSBhcyBNb2RlbC5UeXBlW107XG4gIGxldCBrZXlzID0gbmV3IE1hcDxzdHJpbmcsICh2YWx1ZTogYW55KSA9PiB2b2lkPigpO1xuXG4gIElELnNldChtb2RlbCwgYCR7VH0tJHt1aWQoKX1gKTtcblxuICB3aGlsZShULm5hbWUpe1xuICAgIGZvcihjb25zdCBjYiBvZiBOT1RJRlkuZ2V0KFQpIHx8IFtdKVxuICAgICAgYWRkTGlzdGVuZXIobW9kZWwsIGNiKTtcblxuICAgIGlmKFQgPT09IE1vZGVsKSBicmVhaztcbiAgICBlbHNlIGNoYWluLnVuc2hpZnQoVCk7XG5cbiAgICBUID0gT2JqZWN0LmdldFByb3RvdHlwZU9mKFQpXG4gIH1cblxuICBmb3IoY29uc3QgdHlwZSBvZiBjaGFpbil7XG4gICAgaWYoTUVUSE9EUy5oYXModHlwZSkpe1xuICAgICAga2V5cyA9IE1FVEhPRFMuZ2V0KHR5cGUpITtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIE1FVEhPRFMuc2V0KHR5cGUsIGtleXMgPSBuZXcgTWFwKGtleXMpKTtcblxuICAgIGZvcihjb25zdCBba2V5LCB7IHZhbHVlIH1dIG9mIE9iamVjdC5lbnRyaWVzKFxuICAgICAgT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcnModHlwZS5wcm90b3R5cGUpXG4gICAgKSl7XG4gICAgICBpZighdmFsdWUgfHwga2V5ID09IFwiY29uc3RydWN0b3JcIilcbiAgICAgICAgY29udGludWU7XG4gICAgICBcbiAgICAgIGZ1bmN0aW9uIGJpbmQodGhpczogTW9kZWwsIG9yaWdpbmFsPzogRnVuY3Rpb24pe1xuICAgICAgICBjb25zdCB7IGlzIH0gPSB0aGlzO1xuXG4gICAgICAgIGlmKGlzLmhhc093blByb3BlcnR5KGtleSkgJiYgIW9yaWdpbmFsKVxuICAgICAgICAgIHJldHVybiB2YWx1ZSBhcyBGdW5jdGlvbjtcblxuICAgICAgICBjb25zdCBmbiA9IG9yaWdpbmFsIHx8IHZhbHVlO1xuICAgICAgICBjb25zdCBib3VuZCA9IGZuLmJpbmQoaXMpO1xuICAgICAgICBcbiAgICAgICAgTUVUSE9ELnNldChib3VuZCwgZm4pO1xuICAgICAgICBkZWZpbmUoaXMsIGtleSwgeyB2YWx1ZTogYm91bmQsIHdyaXRhYmxlOiB0cnVlIH0pO1xuICAgICAgICBcbiAgICAgICAgcmV0dXJuIGJvdW5kO1xuICAgICAgfVxuXG4gICAgICBrZXlzLnNldChrZXksIGJpbmQpO1xuICAgICAgZGVmaW5lKHR5cGUucHJvdG90eXBlLCBrZXksIHsgZ2V0OiBiaW5kLCBzZXQ6IGJpbmQgfSk7XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogQXBwbHkgbW9kZWwgYXJndWVtbnRzLCBydW4gY2FsbGJhY2tzIGFuZCBvYnNlcnZlIHByb3BlcnRpZXMuXG4gKiBBY2N1bXVsYXRlIGFuZCBoYW5kbGUgY2xlYW51cCBldmVudHMuXG4gKiovXG5mdW5jdGlvbiBpbml0KG1vZGVsOiBNb2RlbCwgYXJnczogTW9kZWwuQXJncyl7XG4gIGNvbnN0IHN0YXRlID0ge30gYXMgUmVjb3JkPHN0cmluZyB8IG51bWJlciB8IHN5bWJvbCwgdW5rbm93bj47XG5cbiAgU1RBVEUuc2V0KG1vZGVsLCBzdGF0ZSk7XG5cbiAgYXJncyA9IGFyZ3MuZmxhdCgpLmZpbHRlcihhcmcgPT4ge1xuICAgIGlmKHR5cGVvZiBhcmcgIT0gXCJzdHJpbmdcIilcbiAgICAgIHJldHVybiB0cnVlO1xuXG4gICAgSUQuc2V0KG1vZGVsLCBhcmcpO1xuICB9KTtcblxuICBhZGRMaXN0ZW5lcihtb2RlbCwgKCkgPT4ge1xuICAgIGlmKCFQQVJFTlQuaGFzKG1vZGVsKSlcbiAgICAgIFBBUkVOVC5zZXQobW9kZWwsIG51bGwpO1xuXG4gICAgZm9yKGNvbnN0IGtleSBpbiBtb2RlbCl7XG4gICAgICBjb25zdCBkZXNjID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihtb2RlbCwga2V5KSE7XG5cbiAgICAgIGlmKFwidmFsdWVcIiBpbiBkZXNjKVxuICAgICAgICBtYW5hZ2UobW9kZWwsIGtleSwgZGVzYy52YWx1ZSwgdHJ1ZSk7XG4gICAgfVxuXG4gICAgZm9yKGNvbnN0IGFyZyBvZiBhcmdzKXtcbiAgICAgIGNvbnN0IHVzZSA9IHR5cGVvZiBhcmcgPT0gXCJmdW5jdGlvblwiXG4gICAgICAgID8gYXJnLmNhbGwobW9kZWwsIG1vZGVsKVxuICAgICAgICA6IGFyZyBhcyBNb2RlbC5Bc3NpZ248TW9kZWw+O1xuXG4gICAgICBpZih1c2UgaW5zdGFuY2VvZiBQcm9taXNlKVxuICAgICAgICB1c2UuY2F0Y2goZXJyID0+IHtcbiAgICAgICAgICBjb25zb2xlLmVycm9yKGBBc3luYyBlcnJvciBpbiBjb25zdHJ1Y3RvciBmb3IgJHttb2RlbH06YCk7XG4gICAgICAgICAgY29uc29sZS5lcnJvcihlcnIpO1xuICAgICAgICB9KTtcbiAgICAgIGVsc2UgaWYodHlwZW9mIHVzZSA9PSBcImZ1bmN0aW9uXCIpXG4gICAgICAgIGFkZExpc3RlbmVyKG1vZGVsLCB1c2UsIG51bGwpXG4gICAgICBlbHNlIGlmKHR5cGVvZiB1c2UgPT0gXCJvYmplY3RcIilcbiAgICAgICAgYXNzaWduKG1vZGVsLCB1c2UsIHRydWUpO1xuICAgIH1cblxuICAgIGFkZExpc3RlbmVyKG1vZGVsLCAoKSA9PiB7XG4gICAgICBmb3IoY29uc3QgW18sIHZhbHVlXSBvZiBtb2RlbClcbiAgICAgICAgaWYodmFsdWUgaW5zdGFuY2VvZiBNb2RlbCAmJiBQQVJFTlQuZ2V0KHZhbHVlKSA9PT0gbW9kZWwpXG4gICAgICAgICAgdmFsdWUuc2V0KG51bGwpO1xuICBcbiAgICAgIE9iamVjdC5mcmVlemUoc3RhdGUpO1xuICAgIH0sIG51bGwpO1xuICBcbiAgICByZXR1cm4gbnVsbDtcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIG1hbmFnZSh0YXJnZXQ6IE1vZGVsLCBrZXk6IHN0cmluZyB8IG51bWJlciwgdmFsdWU6IGFueSwgc2lsZW50PzogYm9vbGVhbil7XG4gIGNvbnN0IHN0YXRlID0gU1RBVEUuZ2V0KHRhcmdldCkhO1xuICBcbiAgZnVuY3Rpb24gZ2V0KHRoaXM6IE1vZGVsKXtcbiAgICByZXR1cm4gd2F0Y2godGhpcywga2V5LCBzdGF0ZVtrZXldKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHNldCh2YWx1ZTogdW5rbm93biwgc2lsZW50PzogYm9vbGVhbil7XG4gICAgdXBkYXRlKHRhcmdldCwga2V5LCB2YWx1ZSwgc2lsZW50KTtcbiAgICBpZih2YWx1ZSBpbnN0YW5jZW9mIE1vZGVsICYmICFQQVJFTlQuaGFzKHZhbHVlKSl7XG4gICAgICBQQVJFTlQuc2V0KHZhbHVlLCB0YXJnZXQpO1xuICAgICAgZXZlbnQodmFsdWUpO1xuICAgIH1cbiAgfVxuXG4gIGRlZmluZSh0YXJnZXQsIGtleSwgeyBzZXQsIGdldCB9KTtcbiAgc2V0KHZhbHVlLCBzaWxlbnQpO1xufVxuXG50eXBlIFByb3h5PFQgPSBhbnk+ID0gKGtleTogc3RyaW5nIHwgbnVtYmVyLCB2YWx1ZTogVCkgPT4gVDtcblxuY29uc3QgT0JTRVJWRVIgPSBuZXcgV2Vha01hcDxNb2RlbCwgUHJveHk+KCk7XG5cbmZ1bmN0aW9uIHdhdGNoKGZyb206IE1vZGVsLCBrZXk6IHN0cmluZyB8IG51bWJlciwgdmFsdWU/OiBhbnkpe1xuICBjb25zdCBhY2Nlc3MgPSBPQlNFUlZFUi5nZXQoZnJvbSk7XG4gIHJldHVybiBhY2Nlc3MgPyBhY2Nlc3Moa2V5LCB2YWx1ZSkgOiB2YWx1ZTtcbn1cblxuZnVuY3Rpb24gZmV0Y2goc3ViamVjdDogTW9kZWwsIHByb3BlcnR5OiBzdHJpbmcsIHJlcXVpcmVkPzogYm9vbGVhbil7XG4gIGNvbnN0IHN0YXRlID0gU1RBVEUuZ2V0KHN1YmplY3QpITtcbiAgXG4gIGlmKHByb3BlcnR5IGluIHN0YXRlIHx8IHJlcXVpcmVkID09PSBmYWxzZSl7XG4gICAgY29uc3QgdmFsdWUgPSBzdGF0ZVtwcm9wZXJ0eV07XG5cbiAgICBpZih2YWx1ZSAhPT0gdW5kZWZpbmVkIHx8ICFyZXF1aXJlZClcbiAgICAgIHJldHVybiB2YWx1ZTtcbiAgfVxuXG4gIGlmKE1FVEhPRFMuZ2V0KHN1YmplY3QuY29uc3RydWN0b3IgYXMgTW9kZWwuSW5pdCkhLmhhcyhwcm9wZXJ0eSkpXG4gICAgcmV0dXJuIE1FVEhPRC5nZXQoKHN1YmplY3QgYXMgYW55KVtwcm9wZXJ0eV0pO1xuXG4gIGNvbnN0IGVycm9yID0gbmV3IEVycm9yKGAke3N1YmplY3R9LiR7cHJvcGVydHl9IGlzIG5vdCB5ZXQgYXZhaWxhYmxlLmApO1xuICBjb25zdCBwcm9taXNlID0gbmV3IFByb21pc2U8YW55PigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgYWRkTGlzdGVuZXIoc3ViamVjdCwga2V5ID0+IHtcbiAgICAgIGlmKGtleSA9PT0gcHJvcGVydHkpe1xuICAgICAgICByZXNvbHZlKHN0YXRlW2tleV0pO1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cblxuICAgICAgaWYoa2V5ID09PSBudWxsKVxuICAgICAgICByZWplY3QobmV3IEVycm9yKGAke3N1YmplY3R9IGlzIGRlc3Ryb3llZC5gKSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIHRocm93IE9iamVjdC5hc3NpZ24ocHJvbWlzZSwge1xuICAgIHRvU3RyaW5nOiAoKSA9PiBTdHJpbmcoZXJyb3IpLFxuICAgIG5hbWU6IFwiU3VzcGVuc2VcIixcbiAgICBtZXNzYWdlOiBlcnJvci5tZXNzYWdlLFxuICAgIHN0YWNrOiBlcnJvci5zdGFja1xuICB9KTtcbn1cblxuLyoqIEN1cnJlbnRseSBhY2N1bXVsYXRpbmcgZXhwb3J0LiBTdG9yZXMgcmVhbCB2YWx1ZXMgb2YgcGxhY2Vob2xkZXIgcHJvcGVydGllcyBzdWNoIGFzIHJlZigpIG9yIGNoaWxkIG1vZGVscy4gKi9cbmxldCBFWFBPUlQ6IE1hcDxhbnksIGFueT4gfCB1bmRlZmluZWQ7XG5cbmZ1bmN0aW9uIHNuYXBzaG90PFQgZXh0ZW5kcyBNb2RlbD4obW9kZWw6IFQpOiBNb2RlbC5TdGF0ZTxUPiB7XG4gIGNvbnN0IHZhbHVlcyA9IHt9IGFzIGFueTtcbiAgbGV0IGlzTm90UmVjdXJzaXZlO1xuXG4gIGlmKCFFWFBPUlQpe1xuICAgIGlzTm90UmVjdXJzaXZlID0gdHJ1ZTtcbiAgICBFWFBPUlQgPSBuZXcgTWFwKFtbbW9kZWwsIHZhbHVlc11dKTtcbiAgfVxuXG4gIGZvcihsZXQgW2tleSwgdmFsdWVdIG9mIG1vZGVsKXtcbiAgICBpZihFWFBPUlQuaGFzKHZhbHVlKSlcbiAgICAgIHZhbHVlID0gRVhQT1JULmdldCh2YWx1ZSk7XG4gICAgZWxzZSBpZih2YWx1ZSAmJiB0eXBlb2YgdmFsdWUgPT0gXCJvYmplY3RcIiAmJiBcImdldFwiIGluIHZhbHVlICYmIHR5cGVvZiB2YWx1ZS5nZXQgPT09IFwiZnVuY3Rpb25cIilcbiAgICAgIEVYUE9SVC5zZXQodmFsdWUsIHZhbHVlID0gdmFsdWUuZ2V0KCkpO1xuXG4gICAgdmFsdWVzW2tleV0gPSB2YWx1ZTtcbiAgfVxuXG4gIGlmKGlzTm90UmVjdXJzaXZlKVxuICAgIEVYUE9SVCA9IHVuZGVmaW5lZDtcblxuICByZXR1cm4gT2JqZWN0LmZyZWV6ZSh2YWx1ZXMpO1xufVxuXG5mdW5jdGlvbiB1cGRhdGU8VD4oXG4gIHN1YmplY3Q6IE1vZGVsLFxuICBrZXk6IHN0cmluZyB8IG51bWJlciB8IHN5bWJvbCxcbiAgdmFsdWU6IFQsXG4gIGFyZz86IGJvb2xlYW4gfCBNb2RlbC5TZXR0ZXI8VD4pe1xuXG4gIGNvbnN0IHN0YXRlID0gU1RBVEUuZ2V0KHN1YmplY3QpITtcblxuICBpZihPYmplY3QuaXNGcm96ZW4oc3RhdGUpKVxuICAgIHRocm93IG5ldyBFcnJvcihgVHJpZWQgdG8gdXBkYXRlICR7c3ViamVjdH0uJHtTdHJpbmcoa2V5KX0gYnV0IG1vZGVsIGlzIGRlc3Ryb3llZC5gKTtcblxuICBjb25zdCBwcmV2aW91cyA9IHN0YXRlW2tleV0gYXMgVDtcblxuICBpZih0eXBlb2YgYXJnID09IFwiZnVuY3Rpb25cIil7XG4gICAgY29uc3Qgb3V0ID0gYXJnLmNhbGwoc3ViamVjdCwgdmFsdWUsIHByZXZpb3VzKTtcblxuICAgIGlmKG91dCA9PT0gZmFsc2UpXG4gICAgICByZXR1cm4gZmFsc2U7XG5cbiAgICBpZih0eXBlb2Ygb3V0ID09IFwiZnVuY3Rpb25cIilcbiAgICAgIHZhbHVlID0gb3V0KCk7XG4gIH1cblxuICBpZih2YWx1ZSA9PT0gcHJldmlvdXMgJiYga2V5IGluIHN0YXRlKVxuICAgIHJldHVybjtcblxuICBzdGF0ZVtrZXldID0gdmFsdWU7XG5cbiAgaWYoYXJnICE9PSB0cnVlKVxuICAgIGV2ZW50KHN1YmplY3QsIGtleSk7XG5cbiAgcmV0dXJuIHRydWU7XG59XG5cbi8qKiBSYW5kb20gYWxwaGFudW1iZXJpYyBvZiBsZW5ndGggNjsgYWx3YXlzIHN0YXJ0cyB3aXRoIGEgbGV0dGVyLiAqL1xuZnVuY3Rpb24gdWlkKCl7XG4gIHJldHVybiAoMC4yNzggKyBNYXRoLnJhbmRvbSgpICogMC43MjIpLnRvU3RyaW5nKDM2KS5zdWJzdHJpbmcoMiwgOCkudG9VcHBlckNhc2UoKTtcbn1cblxuZXhwb3J0IHtcbiAgZXZlbnQsXG4gIGZldGNoLFxuICBNRVRIT0QsXG4gIE1vZGVsLFxuICBQQVJFTlQsXG4gIFNUQVRFLFxuICB1aWQsXG4gIHVwZGF0ZSxcbiAgd2F0Y2hcbn0iXSwKICAibWFwcGluZ3MiOiAiQUFBQSxTQUFTLGFBQWEsY0FBYyxPQUFPLFlBQXNCLG9CQUFvQjtBQUVyRixNQUFNLFNBQVMsT0FBTztBQUd0QixNQUFNLEtBQUssb0JBQUksUUFBdUI7QUFHdEMsTUFBTSxRQUFRLG9CQUFJLFFBQTBEO0FBRzVFLE1BQU0sU0FBUyxvQkFBSSxRQUFtQztBQUd0RCxNQUFNLFNBQVMsb0JBQUksUUFBNkI7QUFHaEQsTUFBTSxVQUFVLG9CQUFJLFFBQXVEO0FBRzNFLE1BQU0sU0FBUyxvQkFBSSxRQUFrQjtBQW1IckMsTUFBZSxNQUE0QjtBQUFBLEVBQ3pDLGVBQWUsTUFBaUI7QUFDOUIsWUFBUSxJQUFJO0FBQ1osV0FBTyxNQUFNLE1BQU0s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QU8sR0FBRyxDQUFDLDBCQUEwQjtBQUVyRixRQUFNLFdBQVcsTUFBTSxHQUFHO0FBRTFCLE1BQUcsT0FBTyxPQUFPLFlBQVc7QUFDMUIsVUFBTSxNQUFNLElBQUksS0FBSyxTQUFTLE9BQU8sUUFBUTtBQUU3QyxRQUFHLFFBQVE7QUFDVCxhQUFPO0FBRVQsUUFBRyxPQUFPLE9BQU87QUFDZixjQUFRLElBQUk7QUFBQSxFQUNoQjtBQUVBLE1BQUcsVUFBVSxZQUFZLE9BQU87QUFDOUI7QUFFRixRQUFNLEdBQUcsSUFBSTtBQUViLE1BQUcsUUFBUTtBQUNULFVBQU0sU0FBUyxHQUFHO0FBRXBCLFNBQU87QUFDVDtBQUdBLFNBQVMsTUFBSztBQUNaLFVBQVEsUUFBUSxLQUFLLE9BQU8sSUFBSSxPQUFPLFNBQVMsRUFBRSxFQUFFLFVBQVUsR0FBRyxDQUFDLEVBQUUsWUFBWTtBQUNsRjsiLAogICJuYW1lcyI6IFsid2F0Y2giLCAidXBkYXRlIiwgInJlcyIsICJiaW5kIiwgInZhbHVlIiwgInNpbGVudCJdCn0K
|