@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
|
@@ -0,0 +1,324 @@
|
|
|
1
|
+
import {
|
|
2
|
+
addListener,
|
|
3
|
+
watch,
|
|
4
|
+
event,
|
|
5
|
+
Observable,
|
|
6
|
+
PENDING_KEYS
|
|
7
|
+
} from "./control";
|
|
8
|
+
const define = Object.defineProperty;
|
|
9
|
+
const ID = /* @__PURE__ */ new WeakMap();
|
|
10
|
+
const STATE = /* @__PURE__ */ new WeakMap();
|
|
11
|
+
const NOTIFY = /* @__PURE__ */ new WeakMap();
|
|
12
|
+
const PARENT = /* @__PURE__ */ new WeakMap();
|
|
13
|
+
const METHODS = /* @__PURE__ */ new WeakMap();
|
|
14
|
+
const METHOD = /* @__PURE__ */ new WeakMap();
|
|
15
|
+
let EXPORT;
|
|
16
|
+
class State {
|
|
17
|
+
constructor(...args) {
|
|
18
|
+
prepare(this);
|
|
19
|
+
define(this, "is", { value: this });
|
|
20
|
+
init(this, args);
|
|
21
|
+
}
|
|
22
|
+
[Observable](callback, required) {
|
|
23
|
+
const watch2 = /* @__PURE__ */ new Set();
|
|
24
|
+
const proxy = Object.create(this);
|
|
25
|
+
addListener(this, (key) => {
|
|
26
|
+
if (watch2.has(key)) callback();
|
|
27
|
+
});
|
|
28
|
+
OBSERVER.set(proxy, (key, value) => {
|
|
29
|
+
if (value === void 0 && required)
|
|
30
|
+
throw new Error(`${this}.${key} is required in this context.`);
|
|
31
|
+
watch2.add(key);
|
|
32
|
+
if (value instanceof Object && Observable in value)
|
|
33
|
+
return value[Observable](callback, required) || value;
|
|
34
|
+
return value;
|
|
35
|
+
});
|
|
36
|
+
return proxy;
|
|
37
|
+
}
|
|
38
|
+
get(arg1, arg2) {
|
|
39
|
+
const self = this.is;
|
|
40
|
+
if (arg1 === void 0) return values(self);
|
|
41
|
+
if (typeof arg1 == "function") return effect(self, arg1);
|
|
42
|
+
if (typeof arg2 == "function") return addListener(self, arg2, arg1);
|
|
43
|
+
if (arg1 === null) return Object.isFrozen(STATE.get(self));
|
|
44
|
+
return access(self, arg1, arg2);
|
|
45
|
+
}
|
|
46
|
+
set(arg1, arg2, arg3) {
|
|
47
|
+
const self = this.is;
|
|
48
|
+
if (typeof arg1 == "function")
|
|
49
|
+
return addListener(self, (key) => {
|
|
50
|
+
if (arg2 === key || arg2 === void 0 && typeof key == "string")
|
|
51
|
+
return arg1.call(self, key, self);
|
|
52
|
+
});
|
|
53
|
+
if (arg1 && typeof arg1 == "object") {
|
|
54
|
+
assign(self, arg1, arg2 === true);
|
|
55
|
+
} else if (!arg2) {
|
|
56
|
+
event(self, arg1);
|
|
57
|
+
} else if (arg3) {
|
|
58
|
+
manage(self, arg1, arg2);
|
|
59
|
+
} else {
|
|
60
|
+
update(self, arg1, arg2);
|
|
61
|
+
}
|
|
62
|
+
const pending = PENDING_KEYS.get(this);
|
|
63
|
+
if (pending)
|
|
64
|
+
return {
|
|
65
|
+
then: (res) => new Promise((res2) => {
|
|
66
|
+
const remove = addListener(this, (key) => {
|
|
67
|
+
if (key !== true) {
|
|
68
|
+
remove();
|
|
69
|
+
return res2.bind(null, Array.from(pending));
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
}).then(res)
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Iterate over managed properties in this instance of State.
|
|
77
|
+
* Yeilds the key and current value for each property.
|
|
78
|
+
*/
|
|
79
|
+
[Symbol.iterator]() {
|
|
80
|
+
return Object.entries(STATE.get(this.is))[Symbol.iterator]();
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Create and activate a new instance of this state.
|
|
84
|
+
*
|
|
85
|
+
* **Important** - Unlike `new this(...)` - this method also activates state.
|
|
86
|
+
*
|
|
87
|
+
* @param args - arguments sent to constructor
|
|
88
|
+
*/
|
|
89
|
+
static new(...args) {
|
|
90
|
+
const instance = new this(...args, (x) => {
|
|
91
|
+
const cb = x.new && x.new();
|
|
92
|
+
if (cb) x.set(cb, null);
|
|
93
|
+
});
|
|
94
|
+
event(instance);
|
|
95
|
+
return instance;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Static equivalent of `x instanceof this`.
|
|
99
|
+
* Determines if provided class is a subtype of this one.
|
|
100
|
+
* If so, language server will make available all static
|
|
101
|
+
* methods and properties of this class.
|
|
102
|
+
*/
|
|
103
|
+
static is(maybe) {
|
|
104
|
+
return maybe === this || typeof maybe == "function" && maybe.prototype instanceof this;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Register a callback to run when any instance of this State is updated.
|
|
108
|
+
*/
|
|
109
|
+
static on(listener) {
|
|
110
|
+
let notify = NOTIFY.get(this);
|
|
111
|
+
if (!notify) NOTIFY.set(this, notify = /* @__PURE__ */ new Set());
|
|
112
|
+
notify.add(listener);
|
|
113
|
+
return () => notify.delete(listener);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
define(State.prototype, "toString", {
|
|
117
|
+
value() {
|
|
118
|
+
return ID.get(this.is);
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
define(State, "toString", {
|
|
122
|
+
value() {
|
|
123
|
+
return this.name;
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
function assign(subject, data, silent) {
|
|
127
|
+
const methods = METHODS.get(subject.constructor);
|
|
128
|
+
for (const key in data) {
|
|
129
|
+
const bind = methods.get(key);
|
|
130
|
+
if (bind) 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
|
+
}
|
|
142
|
+
function prepare(state) {
|
|
143
|
+
let T = state.constructor;
|
|
144
|
+
if (T === State) throw new Error("Cannot create base State.");
|
|
145
|
+
const chain = [];
|
|
146
|
+
let keys = /* @__PURE__ */ new Map();
|
|
147
|
+
ID.set(state, `${T}-${uid()}`);
|
|
148
|
+
while (T.name) {
|
|
149
|
+
for (const cb of NOTIFY.get(T) || []) {
|
|
150
|
+
addListener(state, cb);
|
|
151
|
+
}
|
|
152
|
+
if (T === State) break;
|
|
153
|
+
else chain.unshift(T);
|
|
154
|
+
T = Object.getPrototypeOf(T);
|
|
155
|
+
}
|
|
156
|
+
for (const type of chain) {
|
|
157
|
+
if (METHODS.has(type)) {
|
|
158
|
+
keys = METHODS.get(type);
|
|
159
|
+
continue;
|
|
160
|
+
}
|
|
161
|
+
METHODS.set(type, keys = new Map(keys));
|
|
162
|
+
for (const [key, { value }] of Object.entries(
|
|
163
|
+
Object.getOwnPropertyDescriptors(type.prototype)
|
|
164
|
+
)) {
|
|
165
|
+
let bind2 = function(original) {
|
|
166
|
+
const { is } = this;
|
|
167
|
+
if (is.hasOwnProperty(key) && !original) 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") continue;
|
|
176
|
+
keys.set(key, bind2);
|
|
177
|
+
define(type.prototype, key, { get: bind2, set: bind2 });
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
function init(self, args) {
|
|
182
|
+
const state = {};
|
|
183
|
+
STATE.set(self, state);
|
|
184
|
+
args = args.flat().filter((arg) => {
|
|
185
|
+
if (typeof arg == "string") ID.set(self, arg);
|
|
186
|
+
else return true;
|
|
187
|
+
});
|
|
188
|
+
addListener(self, () => {
|
|
189
|
+
if (!PARENT.has(self)) PARENT.set(self, null);
|
|
190
|
+
for (const key in self) {
|
|
191
|
+
const desc = Object.getOwnPropertyDescriptor(self, key);
|
|
192
|
+
if ("value" in desc) manage(self, key, desc.value, true);
|
|
193
|
+
}
|
|
194
|
+
for (const arg of args) {
|
|
195
|
+
const use = typeof arg == "function" ? arg.call(self, self) : arg;
|
|
196
|
+
if (use instanceof Promise)
|
|
197
|
+
use.catch((err) => {
|
|
198
|
+
console.error(`Async error in constructor for ${self}:`);
|
|
199
|
+
console.error(err);
|
|
200
|
+
});
|
|
201
|
+
else if (Array.isArray(use)) args.push(...use);
|
|
202
|
+
else if (typeof use == "function") addListener(self, use, null);
|
|
203
|
+
else if (typeof use == "object") assign(self, use, true);
|
|
204
|
+
}
|
|
205
|
+
addListener(
|
|
206
|
+
self,
|
|
207
|
+
() => {
|
|
208
|
+
for (const [_, value] of self)
|
|
209
|
+
if (value instanceof State && PARENT.get(value) === self)
|
|
210
|
+
value.set(null);
|
|
211
|
+
Object.freeze(state);
|
|
212
|
+
},
|
|
213
|
+
null
|
|
214
|
+
);
|
|
215
|
+
return null;
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
function effect(target, fn) {
|
|
219
|
+
const effect2 = METHOD.get(fn) || fn;
|
|
220
|
+
let pending = /* @__PURE__ */ new Set();
|
|
221
|
+
return watch(target, (proxy) => {
|
|
222
|
+
const cb = effect2.call(proxy, proxy, pending);
|
|
223
|
+
if (cb === null) return cb;
|
|
224
|
+
return (update2) => {
|
|
225
|
+
pending = PENDING_KEYS.get(target);
|
|
226
|
+
if (typeof cb == "function") cb(update2);
|
|
227
|
+
};
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
function values(target) {
|
|
231
|
+
const values2 = {};
|
|
232
|
+
let isNotRecursive;
|
|
233
|
+
if (!EXPORT) {
|
|
234
|
+
isNotRecursive = true;
|
|
235
|
+
EXPORT = /* @__PURE__ */ new Map([[target, values2]]);
|
|
236
|
+
}
|
|
237
|
+
for (let [key, value] of target) {
|
|
238
|
+
if (EXPORT.has(value)) value = EXPORT.get(value);
|
|
239
|
+
else if (value && typeof value == "object" && "get" in value && typeof value.get === "function")
|
|
240
|
+
EXPORT.set(value, value = value.get());
|
|
241
|
+
values2[key] = value;
|
|
242
|
+
}
|
|
243
|
+
if (isNotRecursive) EXPORT = void 0;
|
|
244
|
+
return Object.freeze(values2);
|
|
245
|
+
}
|
|
246
|
+
function manage(target, key, value, silent) {
|
|
247
|
+
const state = STATE.get(target);
|
|
248
|
+
function get() {
|
|
249
|
+
return follow(this, key, state[key]);
|
|
250
|
+
}
|
|
251
|
+
function set(value2, silent2) {
|
|
252
|
+
update(target, key, value2, silent2);
|
|
253
|
+
if (value2 instanceof State && !PARENT.has(value2)) {
|
|
254
|
+
PARENT.set(value2, target);
|
|
255
|
+
event(value2);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
define(target, key, { set, get });
|
|
259
|
+
set(value, silent);
|
|
260
|
+
}
|
|
261
|
+
const OBSERVER = /* @__PURE__ */ new WeakMap();
|
|
262
|
+
function follow(from, key, value) {
|
|
263
|
+
const observe = OBSERVER.get(from);
|
|
264
|
+
return observe ? observe(key, value) : value;
|
|
265
|
+
}
|
|
266
|
+
function access(subject, property, required) {
|
|
267
|
+
const state = STATE.get(subject);
|
|
268
|
+
if (property in state || required === false) {
|
|
269
|
+
const value = state[property];
|
|
270
|
+
if (value !== void 0 || !required) return value;
|
|
271
|
+
}
|
|
272
|
+
if (METHODS.get(subject.constructor).has(property))
|
|
273
|
+
return METHOD.get(subject[property]);
|
|
274
|
+
const error = new Error(`${subject}.${property} is not yet available.`);
|
|
275
|
+
const promise = new Promise((resolve, reject) => {
|
|
276
|
+
addListener(subject, (key) => {
|
|
277
|
+
if (key === property) {
|
|
278
|
+
resolve(state[key]);
|
|
279
|
+
return null;
|
|
280
|
+
}
|
|
281
|
+
if (key === null) {
|
|
282
|
+
reject(new Error(`${subject} is destroyed.`));
|
|
283
|
+
}
|
|
284
|
+
});
|
|
285
|
+
});
|
|
286
|
+
throw Object.assign(promise, {
|
|
287
|
+
toString: () => String(error),
|
|
288
|
+
name: "Suspense",
|
|
289
|
+
message: error.message,
|
|
290
|
+
stack: error.stack
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
function update(subject, key, value, arg) {
|
|
294
|
+
const state = STATE.get(subject);
|
|
295
|
+
if (Object.isFrozen(state))
|
|
296
|
+
throw new Error(
|
|
297
|
+
`Tried to update ${subject}.${String(key)} but state is destroyed.`
|
|
298
|
+
);
|
|
299
|
+
const previous = state[key];
|
|
300
|
+
if (typeof arg == "function") {
|
|
301
|
+
const out = arg.call(subject, value, previous);
|
|
302
|
+
if (out === false) return false;
|
|
303
|
+
if (typeof out == "function") value = out();
|
|
304
|
+
}
|
|
305
|
+
if (value === previous && key in state) return;
|
|
306
|
+
state[key] = value;
|
|
307
|
+
if (arg !== true) event(subject, key);
|
|
308
|
+
return true;
|
|
309
|
+
}
|
|
310
|
+
function uid() {
|
|
311
|
+
return (0.278 + Math.random() * 0.722).toString(36).substring(2, 8).toUpperCase();
|
|
312
|
+
}
|
|
313
|
+
export {
|
|
314
|
+
METHOD,
|
|
315
|
+
PARENT,
|
|
316
|
+
STATE,
|
|
317
|
+
State,
|
|
318
|
+
access,
|
|
319
|
+
event,
|
|
320
|
+
follow,
|
|
321
|
+
uid,
|
|
322
|
+
update
|
|
323
|
+
};
|
|
324
|
+
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vc3JjL3N0YXRlLnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyJpbXBvcnQge1xuICBhZGRMaXN0ZW5lcixcbiAgd2F0Y2gsXG4gIGV2ZW50LFxuICBPYnNlcnZhYmxlLFxuICBOb3RpZnksXG4gIFBFTkRJTkdfS0VZU1xufSBmcm9tICcuL2NvbnRyb2wnO1xuXG5jb25zdCBkZWZpbmUgPSBPYmplY3QuZGVmaW5lUHJvcGVydHk7XG5cbi8qKiBSZWdpc3RlciBmb3IgYWxsIGFjdGl2ZSBzdGF0ZXMgdmlhIHN0cmluZyBpZGVudGlmaWVycyAodXN1YWxseSB1bmlxdWUpLiAqL1xuY29uc3QgSUQgPSBuZXcgV2Vha01hcDxTdGF0ZSwgc3RyaW5nPigpO1xuXG4vKiogSW50ZXJuYWwgc3RhdGUgYXNzaWduZWQgdG8gc3RhdGVzLiAqL1xuY29uc3QgU1RBVEUgPSBuZXcgV2Vha01hcDxTdGF0ZSwgUmVjb3JkPHN0cmluZyB8IG51bWJlciB8IHN5bWJvbCwgdW5rbm93bj4+KCk7XG5cbi8qKiBFeHRlcm5hbCBsaXN0ZW5lcnMgZm9yIGFueSBnaXZlbiBTdGF0ZS4gKi9cbmNvbnN0IE5PVElGWSA9IG5ldyBXZWFrTWFwPFN0YXRlLkV4dGVuZHMsIFNldDxOb3RpZnk+PigpO1xuXG4vKiogUGFyZW50LWNoaWxkIHJlbGF0aW9uc2hpcHMuICovXG5jb25zdCBQQVJFTlQgPSBuZXcgV2Vha01hcDxTdGF0ZSwgU3RhdGUgfCBudWxsPigpO1xuXG4vKiogTGlzdCBvZiBtZXRob2RzIGRlZmluZWQgYnkgYSBnaXZlbiB0eXBlLiAqL1xuY29uc3QgTUVUSE9EUyA9IG5ldyBXZWFrTWFwPEZ1bmN0aW9uLCBNYXA8c3RyaW5nLCAodmFsdWU6IGFueSkgPT4gdm9pZD4+KCk7XG5cbi8qKiBSZWZlcmVuY2UgYm91bmQgaW5zdGFuY2UgbWV0aG9kcyB0byByZWFsIG9uZXMuICovXG5jb25zdCBNRVRIT0QgPSBuZXcgV2Vha01hcDxhbnksIGFueT4oKTtcblxuLyoqIEN1cnJlbnRseSBhY2N1bXVsYXRpbmcgZXhwb3J0LiBTdG9yZXMgcmVhbCB2YWx1ZXMgb2YgcGxhY2Vob2xkZXIgcHJvcGVydGllcyBzdWNoIGFzIHJlZigpIG9yIGNoaWxkIHN0YXRlcy4gKi9cbmxldCBFWFBPUlQ6IE1hcDxhbnksIGFueT4gfCB1bmRlZmluZWQ7XG5cbmRlY2xhcmUgbmFtZXNwYWNlIFN0YXRlIHtcbiAgLyoqXG4gICAqIFN0YXRlIHdoaWNoIGlzIHZhbGlkIHRvIGNyZWF0ZS5cbiAgICpcbiAgICogVGhpcyBpbnRlcmZhY2UgbWF5IGJlIGF1Z21lbnRlZCB0byBhZGQgZGRpdGlvbmFsXG4gICAqIGNvbnN0cmFpbnRzIG9uIHN0YXRlcywgc3VjaCBhcyBzcGVjaWFsIGhvb2tzIG9yIHByb3BlcnRpZXMsXG4gICAqIHRvIGludGVyYWN0IHdpdGggZW52aXJvbm1lbnQgb3IgaGVscGVyIGZyYW1ld29ya3MuXG4gICAqKi9cbiAgaW50ZXJmYWNlIFZhbGlkIGV4dGVuZHMgU3RhdGUge1xuICAgICduZXcnPygpOiB2b2lkIHwgKCgpID0+IHZvaWQpO1xuICB9XG5cbiAgLyoqXG4gICAqIEEgU3RhdGUgY2xhc3Mgd2hpY2ggaXMgdmFsaWQgYW5kIG1heSBiZSBpbnN0YW50aWF0ZWQuXG4gICAqL1xuICB0eXBlIE5ldzxUIGV4dGVuZHMgU3RhdGU+ID0gU3RhdGUuQ2xhc3M8VCAmIFZhbGlkPjtcblxuICAvKiogQW55IHR5cGUgb2YgU3RhdGUsIHVzaW5nIG93biBjbGFzcyBjb25zdHJ1Y3RvciBhcyBpdHMgaWRlbnRpZmllci4gKi9cbiAgdHlwZSBFeHRlbmRzPFQgZXh0ZW5kcyBTdGF0ZSA9IFN0YXRlPiA9IChhYnN0cmFjdCBuZXcgKC4uLmFyZ3M6IGFueVtdKSA9PiBUKSAmXG4gICAgdHlwZW9mIFN0YXRlO1xuXG4gIC8qKiBBIFN0YXRlIGNvbnN0cnVjdG9yIHdoaWNoIGlzIG5vdCBhYnN0cmFjdC4gKi9cbiAgdHlwZSBDbGFzczxUIGV4dGVuZHMgU3RhdGUgPSBTdGF0ZT4gPSAobmV3ICguLi5hcmdzOiBTdGF0ZS5BcmdzPFQ+KSA9PiBUKSAmXG4gICAgT21pdDx0eXBlb2YgU3RhdGUsIG5ldmVyPjtcblxuICAvKiogU3RhdGUgY29uc3RydWN0b3IgYXJndW1lbnRzICovXG4gIHR5cGUgQXJnczxUIGV4dGVuZHMgU3RhdGUgPSBhbnk+ID0gKFxuICAgIHwgQXJnczxUPlxuICAgIHwgSW5pdDxUPlxuICAgIHwgQXNzaWduPFQ+XG4gICAgfCBzdHJpbmdcbiAgICB8IHZvaWRcbiAgKVtdO1xuXG4gIC8qKlxuICAgKiBTdGF0ZSBjb25zdHJ1Y3RvciBjYWxsYmFjayAtIGlzIGNhbGxlZCB3aGVuIFN0YXRlIGZpbmlzaGVzIGludGlhbGl6aW5nLlxuICAgKiBSZXR1cm5lZCBmdW5jdGlvbiB3aWxsIHJ1biB3aGVuIHN0YXRlIGlzIGRlc3Ryb3llZC5cbiAgICovXG4gIHR5cGUgSW5pdDxUIGV4dGVuZHMgU3RhdGUgPSBTdGF0ZT4gPSAoXG4gICAgdGhpczogVCxcbiAgICB0aGlzQXJnOiBUXG4gICkgPT4gUHJvbWlzZTx2b2lkPiB8ICgoKSA9PiB2b2lkKSB8IEFyZ3M8VD4gfCBBc3NpZ248VD4gfCB2b2lkO1xuXG4gIC8qKiBPYmplY3Qgb3ZlcmxheSB0byBvdmVycmlkZSB2YWx1ZXMgYW5kIG1ldGhvZHMgb24gYSBzdGF0ZS4gKi9cbiAgdHlwZSBBc3NpZ248VD4gPSBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiAmIHtcbiAgICBbSyBpbiBGaWVsZDxUPl0/OiBUW0tdIGV4dGVuZHMgKC4uLmFyZ3M6IGluZmVyIEEpID0+IGluZmVyIFJcbiAgICAgID8gKHRoaXM6IFQsIC4uLmFyZ3M6IEEpID0+IFJcbiAgICAgIDogVFtLXTtcbiAgfTtcblxuICAvKiogU3Vic2V0IG9mIGBrZXlvZiBUYCB3aGljaCBhcmUgbm90IG1ldGhvZHMgb3IgZGVmaW5lZCBieSBiYXNlIFN0YXRlIFUuICoqL1xuICB0eXBlIEZpZWxkPFQ+ID0gRXhjbHVkZTxrZXlvZiBULCBrZXlvZiBTdGF0ZT47XG5cbiAgLyoqIEFueSB2YWxpZCBrZXkgZm9yIHN0YXRlLCBpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIEZpZWxkPFQ+LiAqL1xuICB0eXBlIEV2ZW50PFQ+ID0gRmllbGQ8VD4gfCBudW1iZXIgfCBzeW1ib2wgfCAoc3RyaW5nICYge30pO1xuXG4gIC8qKiBFeHBvcnQvSW1wb3J0IGNvbXBhdGlibGUgdmFsdWUgZm9yIGEgZ2l2ZW4gcHJvcGVydHkgaW4gYSBTdGF0ZS4gKi9cbiAgdHlwZSBFeHBvcnQ8Uj4gPSBSIGV4dGVuZHMgeyBnZXQoKTogaW5mZXIgVCB9ID8gVCA6IFI7XG5cbiAgLyoqIFZhbHVlIGZvciBhIHByb3BlcnR5IG1hbmFnZWQgYnkgYSBzdGF0ZS4gKi9cbiAgdHlwZSBWYWx1ZTxUIGV4dGVuZHMgU3RhdGUsIEsgZXh0ZW5kcyBFdmVudDxUPj4gPSBLIGV4dGVuZHMga2V5b2YgVFxuICAgID8gRXhwb3J0PFRbS10+XG4gICAgOiB1bmtub3duO1xuXG4gIHR5cGUgU2V0dGVyPFQ+ID0gKHZhbHVlOiBULCBwcmV2aW91czogVCkgPT4gYm9vbGVhbiB8IHZvaWQgfCAoKCkgPT4gVCk7XG5cbiAgdHlwZSBPbkV2ZW50PFQgZXh0ZW5kcyBTdGF0ZT4gPSAoXG4gICAgdGhpczogVCxcbiAgICBrZXk6IHVua25vd24sXG4gICAgc291cmNlOiBUXG4gICkgPT4gdm9pZCB8ICgoKSA9PiB2b2lkKSB8IG51bGw7XG5cbiAgdHlwZSBPblVwZGF0ZTxUIGV4dGVuZHMgU3RhdGUsIEsgZXh0ZW5kcyBFdmVudDxUPj4gPSAoXG4gICAgdGhpczogVCxcbiAgICBrZXk6IEssXG4gICAgdGhpc0FyZzogS1xuICApID0+IHZvaWQ7XG5cbiAgLyoqXG4gICAqIFZhbHVlcyBmcm9tIGN1cnJlbnQgc3RhdGUgb2YgZ2l2ZW4gc3RhdGUuXG4gICAqIERpZmZlcnMgZnJvbSBgVmFsdWVzYCBhcyB2YWx1ZXMgaGVyZSB3aWxsIGRyaWxsXG4gICAqIGludG8gXCJyZWFsXCIgdmFsdWVzIGhlbGQgYnkgZXhvdGljcyBsaWtlIHJlZi5PYmplY3QuXG4gICAqL1xuICB0eXBlIFZhbHVlczxUPiA9IHsgW1AgaW4gRmllbGQ8VD5dOiBFeHBvcnQ8VFtQXT4gfTtcblxuICAvKiogT2JqZWN0IGNvbXBlcmFibGUgdG8gZGF0YSBmb3VuZCBpbiBULiAqL1xuICB0eXBlIFBhcnRpYWw8VD4gPSB7IFtQIGluIEZpZWxkPFQ+XT86IEV4cG9ydDxUW1BdPiB9O1xuXG4gIC8qKiBFeG90aWMgdmFsdWUsIHdoZXJlIGFjdHVhbCB2YWx1ZSBpcyBjb250YWluZWQgd2l0aGluLiAqL1xuICB0eXBlIFJlZjxUID0gYW55PiA9IHtcbiAgICAobmV4dDogVCk6IHZvaWQ7XG4gICAgY3VycmVudDogVCB8IG51bGw7XG4gIH07XG5cbiAgLyoqXG4gICAqIEEgY2FsbGJhY2sgZnVuY3Rpb24gd2hpY2ggaXMgc3Vic2NyaWJlZCB0byBwYXJlbnQgYW5kIHVwZGF0ZXMgd2hlbiBhY2Nlc3NlZCBwcm9wZXJ0aWVzIGNoYW5nZS5cbiAgICpcbiAgICogQHBhcmFtIGN1cnJlbnQgLSBDdXJyZW50IHN0YXRlIG9mIHRoaXMgc3RhdGUuIFRoaXMgaXMgYSBwcm94eSB3aGljaCBkZXRlY3RzIHByb3BlcnRpZXMgd2hpY2hcbiAgICogd2hlcmUgYWNjZXNzZWQsIGFuZCB0aHVzIGRlcGVuZGVkIHVwb24gdG8gc3RheSBjdXJyZW50LlxuICAgKlxuICAgKiBAcGFyYW0gdXBkYXRlIC0gU2V0IG9mIHByb3BlcnRpZXMgd2hpY2ggaGF2ZSBjaGFuZ2VkLCBhbmQgZXZlbnRzIGZpcmVkLCBzaW5jZSBsYXN0IHVwZGF0ZS5cbiAgICpcbiAgICogQHJldHVybnMgQSBjYWxsYmFjayBmdW5jdGlvbiB3aGljaCB3aWxsIGJlIGNhbGxlZCB3aGVuIHRoaXMgZWZmZWN0IGlzIHN0YWxlLlxuICAgKi9cbiAgdHlwZSBFZmZlY3Q8VD4gPSAoXG4gICAgdGhpczogVCxcbiAgICBjdXJyZW50OiBULFxuICAgIHVwZGF0ZTogU2V0PEV2ZW50PFQ+PlxuICApID0+IEVmZmVjdENhbGxiYWNrIHwgUHJvbWlzZTx2b2lkPiB8IG51bGwgfCB2b2lkO1xuXG4gIC8qKlxuICAgKiBBIGNhbGxiYWNrIGZ1bmN0aW9uIHJldHVybmVkIGJ5IGVmZmVjdC4gV2lsbCBiZSBjYWxsZWQgd2hlbiBlZmZlY3QgaXMgc3RhbGUuXG4gICAqXG4gICAqIEBwYXJhbSB1cGRhdGUgLSBgdHJ1ZWAgaWYgdXBkYXRlIGlzIHBlbmRpbmcsIGBmYWxzZWAgZWZmZWN0IGhhcyBiZWVuIGNhbmNlbGxlZCwgYG51bGxgIGlmIHN0YXRlIGlzIGRlc3Ryb3llZC5cbiAgICovXG4gIHR5cGUgRWZmZWN0Q2FsbGJhY2sgPSAodXBkYXRlOiBib29sZWFuIHwgbnVsbCkgPT4gdm9pZDtcbn1cblxuaW50ZXJmYWNlIFN0YXRlIHtcbiAgLyoqXG4gICAqIExvb3BiYWNrIHRvIGluc3RhbmNlIG9mIHRoaXMgc3RhdGUuIFRoaXMgaXMgdXNlZnVsIHdoZW4gaW4gYSBzdWJzY3JpYmVkIGNvbnRleHQsXG4gICAqIHRvIGtlZXAgd3JpdGUgYWNjZXNzIHRvIGB0aGlzYCBhZnRlciBhIGRlc3RydWN0dXJlLiBZb3UgY2FuIHVzZSBpdCB0byByZWFkIHZhcmlhYmxlcyBzaWxlbnRseSBhcyB3ZWxsLlxuICAgKiovXG4gIGlzOiB0aGlzO1xufVxuXG5hYnN0cmFjdCBjbGFzcyBTdGF0ZSBpbXBsZW1lbnRzIE9ic2VydmFibGUge1xuICBjb25zdHJ1Y3RvciguLi5hcmdzOiBTdGF0ZS5BcmdzKSB7XG4gICAgcHJlcGFyZSh0aGlzKTtcbiAgICBkZWZpbmUodGhpcywgJ2lzJywgeyB2YWx1ZTogdGhpcyB9KTtcbiAgICBpbml0KHRoaXMsIGFyZ3MpO1xuICB9XG5cbiAgW09ic2VydmFibGVdKGNhbGxiYWNrOiBPYnNlcnZhYmxlLkNhbGxiYWNrLCByZXF1aXJlZD86IGJvb2xlYW4pIHtcbiAgICBjb25zdCB3YXRjaCA9IG5ldyBTZXQ8dW5rbm93bj4oKTtcbiAgICBjb25zdCBwcm94eSA9IE9iamVjdC5jcmVhdGUodGhpcyk7XG5cbiAgICBhZGRMaXN0ZW5lcih0aGlzLCAoa2V5KSA9PiB7XG4gICAgICBpZiAod2F0Y2guaGFzKGtleSkpIGNhbGxiYWNrKCk7XG4gICAgfSk7XG5cbiAgICBPQlNFUlZFUi5zZXQocHJveHksIChrZXksIHZhbHVlKSA9PiB7XG4gICAgICBpZiAodmFsdWUgPT09IHVuZGVmaW5lZCAmJiByZXF1aXJlZClcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAke3RoaXN9LiR7a2V5fSBpcyByZXF1aXJlZCBpbiB0aGlzIGNvbnRleHQuYCk7XG5cbiAgICAgIHdhdGNoLmFkZChrZXkpO1xuXG4gICAgICBpZiAodmFsdWUgaW5zdGFuY2VvZiBPYmplY3QgJiYgT2JzZXJ2YWJsZSBpbiB2YWx1ZSlcbiAgICAgICAgcmV0dXJuIHZhbHVlW09ic2VydmFibGVdKGNhbGxiYWNrLCByZXF1aXJlZCkgfHwgdmFsdWU7XG5cbiAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9KTtcblxuICAgIHJldHVybiBwcm94eSBhcyB0aGlzO1xuICB9XG5cbiAgLyoqXG4gICAqIFB1bGwgY3VycmVudCB2YWx1ZXMgZnJvbSBzdGF0ZS4gRmxhdHRlbnMgYWxsIHN0YXRlcyBhbmQgZXhvdGljIHZhbHVlcyByZWN1cnNpdmVseS5cbiAgICpcbiAgICogQHJldHVybnMgT2JqZWN0IHdpdGggYWxsIHZhbHVlcyBmcm9tIHRoaXMgc3RhdGUuXG4gICAqKi9cbiAgZ2V0KCk6IFN0YXRlLlZhbHVlczx0aGlzPjtcblxuICAvKipcbiAgICogUnVuIGEgZnVuY3Rpb24gd2hpY2ggd2lsbCBydW4gYXV0b21hdGljYWxseSB3aGVuIGFjY2Vzc2VkIHZhbHVlcyBjaGFuZ2UuXG4gICAqXG4gICAqIEBwYXJhbSBlZmZlY3QgRnVuY3Rpb24gdG8gcnVuLCBhbmQgYWdhaW4gd2hlbmV2ZXIgYWNjZXNzZWQgdmFsdWVzIGNoYW5nZS5cbiAgICogICAgICAgICAgICAgICBJZiBlZmZlY3QgcmV0dXJucyBhIGZ1bmN0aW9uLCBpdCB3aWxsIGJlIGNhbGxlZCB3aGVuIGEgY2hhbmdlIG9jY3VycyAoc3luY3Jvbm91c2x5KSxcbiAgICogICAgICAgICAgICAgICBlZmZlY3QgaXMgY2FuY2VsbGVkLCBvciBwYXJlbnQgc3RhdGUgaXMgZGVzdHJveWVkLlxuICAgKiBAcmV0dXJucyBGdW5jdGlvbiB0byBjYW5jZWwgbGlzdGVuZXIuXG4gICAqL1xuICBnZXQoZWZmZWN0OiBTdGF0ZS5FZmZlY3Q8dGhpcz4pOiAoKSA9PiB2b2lkO1xuXG4gIC8qKlxuICAgKiBHZXQgdmFsdWUgb2YgYSBwcm9wZXJ0eS5cbiAgICpcbiAgICogQHBhcmFtIGtleSAtIFByb3BlcnR5IHRvIGdldCB2YWx1ZSBvZi5cbiAgICogQHBhcmFtIHJlcXVpcmVkIC0gSWYgdHJ1ZSwgd2lsbCB0aHJvdyBhbiBlcnJvciBpZiBwcm9wZXJ0eSBpcyBub3QgYXZhaWxhYmxlLlxuICAgKiBAcmV0dXJucyBWYWx1ZSBvZiBwcm9wZXJ0eS5cbiAgICovXG4gIGdldDxUIGV4dGVuZHMgU3RhdGUuRXZlbnQ8dGhpcz4+KFxuICAgIGtleTogVCxcbiAgICByZXF1aXJlZD86IGJvb2xlYW5cbiAgKTogU3RhdGUuVmFsdWU8dGhpcywgVD47XG5cbiAgLyoqXG4gICAqIFJ1biBhIGZ1bmN0aW9uIHdoZW4gYSBwcm9wZXJ0eSBpcyB1cGRhdGVkLlxuICAgKlxuICAgKiBAcGFyYW0ga2V5IC0gUHJvcGVydHkgdG8gd2F0Y2ggZm9yIHVwZGF0ZXMuXG4gICAqIEBwYXJhbSBjYWxsYmFjayAtIEZ1bmN0aW9uIHRvIGNhbGwgd2hlbiBwcm9wZXJ0eSBpcyB1cGRhdGVkLlxuICAgKiBAcmV0dXJucyBGdW5jdGlvbiB0byBjYW5jZWwgbGlzdGVuZXIuXG4gICAqL1xuICBnZXQ8VCBleHRlbmRzIFN0YXRlLkV2ZW50PHRoaXM+PihcbiAgICBrZXk6IFQsXG4gICAgY2FsbGJhY2s6IFN0YXRlLk9uVXBkYXRlPHRoaXMsIFQ+XG4gICk6ICgpID0+IHZvaWQ7XG5cbiAgLyoqXG4gICAqIENoZWNrIGlmIHN0YXRlIGlzIGV4cGlyZWQuXG4gICAqXG4gICAqIEBwYXJhbSBzdGF0dXMgLSBgbnVsbGAgdG8gY2hlY2sgaWYgc3RhdGUgaXMgZXhwaXJlZC5cbiAgICogQHJldHVybnMgYHRydWVgIGlmIHN0YXRlIGlzIGV4cGlyZWQsIGBmYWxzZWAgb3RoZXJ3aXNlLlxuICAgKi9cbiAgZ2V0KHN0YXR1czogbnVsbCk6IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIENhbGxiYWNrIHdoZW4gc3RhdGUgaXMgdG8gYmUgZGVzdHJveWVkLlxuICAgKlxuICAgKiBAcGFyYW0gY2FsbGJhY2sgLSBGdW5jdGlvbiB0byBjYWxsIHdoZW4gc3RhdGUgaXMgZGVzdHJveWVkLlxuICAgKiBAcmV0dXJucyBGdW5jdGlvbiB0byBjYW5jZWwgbGlzdGVuZXIuXG4gICAqL1xuICBnZXQoc3RhdHVzOiBudWxsLCBjYWxsYmFjazogKCkgPT4gdm9pZCk6ICgpID0+IHZvaWQ7XG5cbiAgZ2V0KFxuICAgIGFyZzE/OiBTdGF0ZS5FZmZlY3Q8dGhpcz4gfCBzdHJpbmcgfCBudWxsLFxuICAgIGFyZzI/OiBib29sZWFuIHwgU3RhdGUuT25VcGRhdGU8dGhpcywgYW55PlxuICApIHtcbiAgICBjb25zdCBzZWxmID0gdGhpcy5pcztcblxuICAgIGlmIChhcmcxID09PSB1bmRlZmluZWQpIHJldHVybiB2YWx1ZXMoc2VsZik7XG4gICAgaWYgKHR5cGVvZiBhcmcxID09ICdmdW5jdGlvbicpIHJldHVybiBlZmZlY3Qoc2VsZiwgYXJnMSk7XG4gICAgaWYgKHR5cGVvZiBhcmcyID09ICdmdW5jdGlvbicpIHJldHVybiBhZGRMaXN0ZW5lcihzZWxmLCBhcmcyLCBhcmcxKTtcbiAgICBpZiAoYXJnMSA9PT0gbnVsbCkgcmV0dXJuIE9iamVjdC5pc0Zyb3plbihTVEFURS5nZXQoc2VsZikpO1xuICAgIHJldHVybiBhY2Nlc3Moc2VsZiwgYXJnMSwgYXJnMik7XG4gIH1cblxuICAvKipcbiAgICogR2V0IHVwZGF0ZSBpbiBwcm9ncmVzcy5cbiAgICpcbiAgICogQHJldHVybnMgUHJvbWlzZSB3aGljaCByZXNvbHZlcyBvYmplY3Qgd2l0aCB1cGRhdGVkIHZhbHVlcywgYHVuZGVmaW5lZGAgaWYgdGhlcmUgbm8gdXBkYXRlIGlzIHBlbmRpbmcuXG4gICAqKi9cbiAgc2V0KCk6IFByb21pc2VMaWtlPFN0YXRlLkV2ZW50PHRoaXM+W10+IHwgdW5kZWZpbmVkO1xuXG4gIC8qKlxuICAgKiBVcGRhdGUgbXVsaXRwbGUgcHJvcGVydGllcyBhdCBvbmNlLiBNZXJnZXMgYXJndW1lbnQgd2l0aCBjdXJyZW50IHN0YXRlLlxuICAgKiBQcm9wZXJ0aWVzIHdoaWNoIGFyZSBub3QgbWFuYWdlZCBieSB0aGlzIHN0YXRlIHdpbGwgYmUgaWdub3JlZC5cbiAgICpcbiAgICogQHBhcmFtIGFzc2lnbiAtIE9iamVjdCB3aXRoIHByb3BlcnRpZXMgdG8gdXBkYXRlLlxuICAgKiBAcGFyYW0gc2lsZW50IC0gSWYgYW4gdXBkYXRlIGRvZXMgb2NjdXIsIGxpc3RlbmVycyB3aWxsIG5vdCBiZSByZWZyZXNoZWQgYXV0b21hdGljYWxseS5cbiAgICogQHJldHVybnMgUHJvbWlzZSByZXNvbHZpbmcgYW4gYXJyYXkgb2Yga2V5cyB1cGRhdGVkLCBgdW5kZWZpbmVkYCAoaW1tZWRpYXRlbHkpIGlmIGEgbm9vcC5cbiAgICovXG4gIHNldChcbiAgICBhc3NpZ24/OiBTdGF0ZS5Bc3NpZ248dGhpcz4sXG4gICAgc2lsZW50PzogYm9vbGVhblxuICApOiBQcm9taXNlTGlrZTxTdGF0ZS5FdmVudDx0aGlzPltdPiB8IHVuZGVmaW5lZDtcblxuICAvKipcbiAgICogUHVzaCBhbiB1cGRhdGUuIFRoaXMgd2lsbCBub3QgY2hhbmdlIHRoZSB2YWx1ZSBvZiBhc3NvY2lhdGVkIHByb3BlcnR5LlxuICAgKlxuICAgKiBVc2VmdWwgd2hlcmUgYSBwcm9wZXJ0eSB2YWx1ZSBpbnRlcm5hbGx5IGhhcyBjaGFuZ2VkLCBidXQgdGhlIG9iamVjdCBpcyB0aGUgc2FtZS5cbiAgICogRm9yIGV4YW1wbGU6IEFuIGFycmF5IGhhcyBwdXNoZWQgYSBuZXcgdmFsdWUsIG9yIGEgbmVzdGVkIHByb3BlcnR5IGlzIHVwZGF0ZWQuXG4gICAqXG4gICAqIFlvdSBjYW4gYWxzbyB1c2UgdGhpcyB0byBkaXNwYXRjaCBhcmJpdHJhcnkgZXZlbnRzLlxuICAgKiBTeW1ib2xzIGFyZSByZWNvbW1lbmRlZCBhcyBub24tcHJvcGVydHkgZXZlbnRzLCBob3dldmVyIHlvdSBjYW4gdXNlIGFueSBzdHJpbmcuXG4gICAqIElmIGRvaW5nIHNvLCBiZSBzdXJlIHRvIGF2b2lkIGNvbGxpc2lvbnMgd2l0aCBwcm9wZXJ0eSBuYW1lcyEgQW4gZWFzeSB3YXkgdG8gZG8gdGhpcyBpc1xuICAgKiB0byBwcmVmaXggYW4gZXZlbnQgd2l0aCBcIiFcIiBhbmQvb3IgdXNlIGRhc2gtY2FzZS4gZS5nLiBgc2V0KFwiIWV2ZW50XCIpYCBvciBgc2V0KFwibXktZXZlbnRcIilgLlxuICAgKlxuICAgKiBAcGFyYW0ga2V5IC0gUHJvcGVydHkgb3IgZXZlbnQgdG8gZGlzcGF0Y2guXG4gICAqIEByZXR1cm5zIFByb21pc2UgcmVzb2x2ZXMgYW4gYXJyYXkgb2Yga2V5cyB1cGRhdGVkLlxuICAgKi9cbiAgc2V0KGtleTogU3RhdGUuRXZlbnQ8dGhpcz4pOiBQcm9taXNlTGlrZTxTdGF0ZS5FdmVudDx0aGlzPltdPjtcblxuICAvKipcbiAgICogU2V0IGEgdmFsdWUgZm9yIGEgcHJvcGVydHkuIFRoaXMgd2lsbCB1cGRhdGUgdGhlIHZhbHVlIGFuZCBub3RpZnkgbGlzdGVuZXJzLlxuICAgKlxuICAgKiAqKlVzZSB3aXRoIGNhdXRpb24hKiogS2V5IG5vciB2YWx1ZSBhcmUgY2hlY2tlZCBmb3IgdmFsaWRpdHkuXG4gICAqXG4gICAqIFRoaXMgaXMgbWVhbnQgZm9yIGFzc2lnbmluZyB2YWx1ZXMgcHJvZ3JhbW1hdGljYWxseSxcbiAgICogd2hlcmUgc2ltcGxlIGFzc2lnbm1lbnQgaXMgbm90IHByYWN0aWNhYmxlLlxuICAgKlxuICAgKiBGb3IgZXhhbXBsZTogYCh0aGlzIGFzIGFueSlbbXlQcm9wZXJ0eV0gPSB2YWx1ZTtgXG4gICAqXG4gICAqIEBwYXJhbSBrZXkgLSBQcm9wZXJ0eSB0byBzZXQgdmFsdWUgZm9yLlxuICAgKiBAcGFyYW0gdmFsdWUgLSBWYWx1ZSB0byBzZXQgZm9yIHByb3BlcnR5LlxuICAgKiBAcGFyYW0gaW5pdCAtIElmIHRydWUsIHN0YXRlIHdpbGwgYmVnaW4gdG8gbWFuYWdlIHRoZSBwcm9wZXJ0eSBpZiBpdCBpcyBub3QgYWxyZWFkeS5cbiAgICogQHJldHVybnMgUHJvbWlzZSByZXNvbHZlcyBhbiBhcnJheSBvZiBrZXlzIHVwZGF0ZWQuXG4gICAqL1xuICBzZXQoXG4gICAga2V5OiBTdGF0ZS5FdmVudDx0aGlzPixcbiAgICB2YWx1ZTogdW5rbm93bixcbiAgICBpbml0PzogYm9vbGVhblxuICApOiBQcm9taXNlTGlrZTxTdGF0ZS5FdmVudDx0aGlzPltdPjtcblxuICAvKipcbiAgICogQ2FsbCBhIGZ1bmN0aW9uIHdoZW4gdXBkYXRlIG9jY3Vycy5cbiAgICpcbiAgICogR2l2ZW4gZnVuY3Rpb24gaXMgY2FsbGVkIGZvciBldmVyeSBhc3NpZ25tZW50ICh3aGljaCBjaGFuZ2VzIHZhbHVlKSBvciBleHBsaWNpdCBgc2V0YC5cbiAgICpcbiAgICogVG8gcnVuIGxvZ2ljIG9uIGZpbmFsIHZhbHVlIG9ubHksIGNhbGxiYWNrIG1heSByZXR1cm4gYSBmdW5jdGlvbi4gVXNpbmcgdGhlIHNhbWVcbiAgICogZnVuY3Rpb24gZm9yIG9uZSBvciBtb3JlIGV2ZW50cyB3aWxsIGVuc3VyZSBpdCBpcyBjYWxsZWQgb25seSB3aGVuIGV2ZW50cyBhcmUgc2V0dGxlZC5cbiAgICpcbiAgICogQHBhcmFtIGNhbGxiYWNrIC0gRnVuY3Rpb24gdG8gY2FsbCB3aGVuIHVwZGF0ZSBvY2N1cnMuXG4gICAqIEByZXR1cm5zIEZ1bmN0aW9uIHRvIHJlbW92ZSBsaXN0ZW5lci4gV2lsbCByZXR1cm4gYHRydWVgIGlmIHJlbW92ZWQsIGBmYWxzZWAgaWYgaW5hY3RpdmUgYWxyZWFkeS5cbiAgICpcbiAgICovXG4gIHNldChjYWxsYmFjazogU3RhdGUuT25FdmVudDx0aGlzPik6ICgpID0+IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIENhbGwgYSBmdW5jdGlvbiB3aGVuIGEgcHJvcGVydHkgaXMgdXBkYXRlZC5cbiAgICogVW5saWtlIGBnZXRgLCB0aGlzIGNhbGxzIHN5bmNocm9ub3VzbHkgYW5kIHdpbGwgZmlyZSBhcyBtYW55IHRpbWVzIGFzIHRoZSBwcm9wZXJ0eSBpcyB1cGRhdGVkLlxuICAgKlxuICAgKiBAcGFyYW0gY2FsbGJhY2sgLSBGdW5jdGlvbiB0byBjYWxsIHdoZW4gcHJvcGVydHkgaXMgdXBkYXRlZC5cbiAgICogQHBhcmFtIGV2ZW50IC0gUHJvcGVydHkgdG8gd2F0Y2ggZm9yIHVwZGF0ZXMuXG4gICAqL1xuICBzZXQoXG4gICAgY2FsbGJhY2s6IFN0YXRlLk9uRXZlbnQ8dGhpcz4sXG4gICAgZXZlbnQ6IFN0YXRlLkV2ZW50PHRoaXM+IHwgbnVsbFxuICApOiAoKSA9PiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBEZWNsYXJlIGFuIGVuZCB0byB1cGRhdGVzLiBUaGlzIGV2ZW50IGlzIGZpbmFsIGFuZCB3aWxsIGZyZWV6ZSBzdGF0ZS5cbiAgICogVGhpcyBldmVudCBjYW4gYmUgd2F0Y2hlZCBmb3IgYXMgd2VsbCwgdG8gcnVuIGNsZWFudXAgbG9naWMgYW5kIGludGVybmFsbHkgd2lsbCByZW1vdmUgYWxsIGxpc3RlbmVycy5cbiAgICpcbiAgICogQHBhcmFtIHN0YXR1cyAtIGBudWxsYCB0byBlbmQgdXBkYXRlcy5cbiAgICovXG4gIHNldChzdGF0dXM6IG51bGwpOiB2b2lkO1xuXG4gIHNldChcbiAgICBhcmcxPzogU3RhdGUuT25FdmVudDx0aGlzPiB8IFN0YXRlLkFzc2lnbjx0aGlzPiB8IFN0YXRlLkV2ZW50PHRoaXM+IHwgbnVsbCxcbiAgICBhcmcyPzogdW5rbm93bixcbiAgICBhcmczPzogYm9vbGVhblxuICApIHtcbiAgICBjb25zdCBzZWxmID0gdGhpcy5pcztcblxuICAgIGlmICh0eXBlb2YgYXJnMSA9PSAnZnVuY3Rpb24nKVxuICAgICAgcmV0dXJuIGFkZExpc3RlbmVyKHNlbGYsIChrZXkpID0+IHtcbiAgICAgICAgaWYgKGFyZzIgPT09IGtleSB8fCAoYXJnMiA9PT0gdW5kZWZpbmVkICYmIHR5cGVvZiBrZXkgPT0gJ3N0cmluZycpKVxuICAgICAgICAgIHJldHVybiBhcmcxLmNhbGwoc2VsZiwga2V5LCBzZWxmKTtcbiAgICAgIH0pO1xuXG4gICAgaWYgKGFyZzEgJiYgdHlwZW9mIGFyZzEgPT0gJ29iamVjdCcpIHtcbiAgICAgIGFzc2lnbihzZWxmLCBhcmcxLCBhcmcyID09PSB0cnVlKTtcbiAgICB9IGVsc2UgaWYgKCFhcmcyKSB7XG4gICAgICBldmVudChzZWxmLCBhcmcxKTtcbiAgICB9IGVsc2UgaWYgKGFyZzMpIHtcbiAgICAgIG1hbmFnZShzZWxmLCBhcmcxIGFzIHN0cmluZyB8IG51bWJlciwgYXJnMik7XG4gICAgfSBlbHNlIHtcbiAgICAgIHVwZGF0ZShzZWxmLCBhcmcxIGFzIHN0cmluZyB8IG51bWJlciwgYXJnMik7XG4gICAgfVxuXG4gICAgY29uc3QgcGVuZGluZyA9IFBFTkRJTkdfS0VZUy5nZXQodGhpcyk7XG5cbiAgICBpZiAocGVuZGluZylcbiAgICAgIHJldHVybiA8UHJvbWlzZUxpa2U8U3RhdGUuRXZlbnQ8dGhpcz5bXT4+e1xuICAgICAgICB0aGVuOiAocmVzKSA9PlxuICAgICAgICAgIG5ldyBQcm9taXNlPGFueT4oKHJlcykgPT4ge1xuICAgICAgICAgICAgY29uc3QgcmVtb3ZlID0gYWRkTGlzdGVuZXIodGhpcywgKGtleSkgPT4ge1xuICAgICAgICAgICAgICBpZiAoa2V5ICE9PSB0cnVlKSB7XG4gICAgICAgICAgICAgICAgcmVtb3ZlKCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlcy5iaW5kKG51bGwsIEFycmF5LmZyb20ocGVuZGluZykpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9KS50aGVuKHJlcylcbiAgICAgIH07XG4gIH1cblxuICAvKipcbiAgICogSXRlcmF0ZSBvdmVyIG1hbmFnZWQgcHJvcGVydGllcyBpbiB0aGlzIGluc3RhbmNlIG9mIFN0YXRlLlxuICAgKiBZZWlsZHMgdGhlIGtleSBhbmQgY3VycmVudCB2YWx1ZSBmb3IgZWFjaCBwcm9wZXJ0eS5cbiAgICovXG4gIFtTeW1ib2wuaXRlcmF0b3JdKCk6IEl0ZXJhdG9yPFtzdHJpbmcsIHVua25vd25dPiB7XG4gICAgcmV0dXJuIE9iamVjdC5lbnRyaWVzKFNUQVRFLmdldCh0aGlzLmlzKSEpW1N5bWJvbC5pdGVyYXRvcl0oKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGUgYW5kIGFjdGl2YXRlIGEgbmV3IGluc3RhbmNlIG9mIHRoaXMgc3RhdGUuXG4gICAqXG4gICAqICoqSW1wb3J0YW50KiogLSBVbmxpa2UgYG5ldyB0aGlzKC4uLilgIC0gdGhpcyBtZXRob2QgYWxzbyBhY3RpdmF0ZXMgc3RhdGUuXG4gICAqXG4gICAqIEBwYXJhbSBhcmdzIC0gYXJndW1lbnRzIHNlbnQgdG8gY29uc3RydWN0b3JcbiAgICovXG4gIHN0YXRpYyBuZXc8VCBleHRlbmRzIFN0YXRlPih0aGlzOiBTdGF0ZS5OZXc8VD4sIC4uLmFyZ3M6IFN0YXRlLkFyZ3M8VD4pOiBUIHtcbiAgICBjb25zdCBpbnN0YW5jZSA9IG5ldyB0aGlzKC4uLmFyZ3MsICh4KSA9PiB7XG4gICAgICBjb25zdCBjYiA9IHgubmV3ICYmIHgubmV3KCk7XG4gICAgICBpZiAoY2IpIHguc2V0KGNiLCBudWxsKTtcbiAgICB9KTtcbiAgICBldmVudChpbnN0YW5jZSk7XG4gICAgcmV0dXJuIGluc3RhbmNlO1xuICB9XG5cbiAgLyoqXG4gICAqIFN0YXRpYyBlcXVpdmFsZW50IG9mIGB4IGluc3RhbmNlb2YgdGhpc2AuXG4gICAqIERldGVybWluZXMgaWYgcHJvdmlkZWQgY2xhc3MgaXMgYSBzdWJ0eXBlIG9mIHRoaXMgb25lLlxuICAgKiBJZiBzbywgbGFuZ3VhZ2Ugc2VydmVyIHdpbGwgbWFrZSBhdmFpbGFibGUgYWxsIHN0YXRpY1xuICAgKiBtZXRob2RzIGFuZCBwcm9wZXJ0aWVzIG9mIHRoaXMgY2xhc3MuXG4gICAqL1xuICBzdGF0aWMgaXM8VCBleHRlbmRzIFN0YXRlLkV4dGVuZHM+KHRoaXM6IFQsIG1heWJlOiB1bmtub3duKTogbWF5YmUgaXMgVCB7XG4gICAgcmV0dXJuIChcbiAgICAgIG1heWJlID09PSB0aGlzIHx8XG4gICAgICAodHlwZW9mIG1heWJlID09ICdmdW5jdGlvbicgJiYgbWF5YmUucHJvdG90eXBlIGluc3RhbmNlb2YgdGhpcylcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlZ2lzdGVyIGEgY2FsbGJhY2sgdG8gcnVuIHdoZW4gYW55IGluc3RhbmNlIG9mIHRoaXMgU3RhdGUgaXMgdXBkYXRlZC5cbiAgICovXG4gIHN0YXRpYyBvbjxUIGV4dGVuZHMgU3RhdGU+KFxuICAgIHRoaXM6IFN0YXRlLkV4dGVuZHM8VD4sXG4gICAgbGlzdGVuZXI6IFN0YXRlLk9uRXZlbnQ8VD5cbiAgKSB7XG4gICAgbGV0IG5vdGlmeSA9IE5PVElGWS5nZXQodGhpcyk7XG5cbiAgICBpZiAoIW5vdGlmeSkgTk9USUZZLnNldCh0aGlzLCAobm90aWZ5ID0gbmV3IFNldCgpKSk7XG5cbiAgICBub3RpZnkuYWRkKGxpc3RlbmVyKTtcblxuICAgIHJldHVybiAoKSA9PiBub3RpZnkuZGVsZXRlKGxpc3RlbmVyKTtcbiAgfVxufVxuXG5kZWZpbmUoU3RhdGUucHJvdG90eXBlLCAndG9TdHJpbmcnLCB7XG4gIHZhbHVlKCkge1xuICAgIHJldHVybiBJRC5nZXQodGhpcy5pcyk7XG4gIH1cbn0pO1xuXG5kZWZpbmUoU3RhdGUsICd0b1N0cmluZycsIHtcbiAgdmFsdWUoKSB7XG4gICAgcmV0dXJuIHRoaXMubmFtZTtcbiAgfVxufSk7XG5cbmZ1bmN0aW9uIGFzc2lnbihzdWJqZWN0OiBTdGF0ZSwgZGF0YTogU3RhdGUuQXNzaWduPFN0YXRlPiwgc2lsZW50PzogYm9vbGVhbikge1xuICBjb25zdCBtZXRob2RzID0gTUVUSE9EUy5nZXQoc3ViamVjdC5jb25zdHJ1Y3RvcikhO1xuXG4gIGZvciAoY29uc3Qga2V5IGluIGRhdGEpIHtcbiAgICBjb25zdCBiaW5kID0gbWV0aG9kcy5nZXQoa2V5KTtcblxuICAgIGlmIChiaW5kKSBiaW5kLmNhbGwoc3ViamVjdCwgZGF0YVtrZXldKTtcbiAgICBlbHNlIGlmIChrZXkgaW4gc3ViamVjdCAmJiBrZXkgIT09ICdpcycpIHtcbiAgICAgIGNvbnN0IGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHN1YmplY3QsIGtleSkhO1xuICAgICAgY29uc3Qgc2V0ID0gZGVzYyAmJiAoZGVzYy5zZXQgYXMgKHZhbHVlOiBhbnksIHNpbGVudD86IGJvb2xlYW4pID0+IHZvaWQpO1xuXG4gICAgICBpZiAoc2V0KSB7XG4gICAgICAgIHNldC5jYWxsKHN1YmplY3QsIGRhdGFba2V5XSwgc2lsZW50KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIChzdWJqZWN0IGFzIGFueSlba2V5XSA9IGRhdGFba2V5XTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuLyoqIEFwcGx5IGluc3RydWN0aW9ucyBhbmQgaW5oZXJpdGVkIGV2ZW50IGxpc3RlbmVycy4gRW5zdXJlIGNsYXNzIG1ldGFkYXRhIGlzIHJlYWR5LiAqL1xuZnVuY3Rpb24gcHJlcGFyZShzdGF0ZTogU3RhdGUpIHtcbiAgbGV0IFQgPSBzdGF0ZS5jb25zdHJ1Y3RvciBhcyBTdGF0ZS5FeHRlbmRzO1xuXG4gIGlmIChUID09PSBTdGF0ZSkgdGhyb3cgbmV3IEVycm9yKCdDYW5ub3QgY3JlYXRlIGJhc2UgU3RhdGUuJyk7XG5cbiAgY29uc3QgY2hhaW4gPSBbXSBhcyBTdGF0ZS5FeHRlbmRzW107XG4gIGxldCBrZXlzID0gbmV3IE1hcDxzdHJpbmcsICh2YWx1ZTogYW55KSA9PiB2b2lkPigpO1xuXG4gIElELnNldChzdGF0ZSwgYCR7VH0tJHt1aWQoKX1gKTtcblxuICB3aGlsZSAoVC5uYW1lKSB7XG4gICAgZm9yIChjb25zdCBjYiBvZiBOT1RJRlkuZ2V0KFQpIHx8IFtdKSB7XG4gICAgICBhZGRMaXN0ZW5lcihzdGF0ZSwgY2IpO1xuICAgIH1cblxuICAgIGlmIChUID09PSBTdGF0ZSkgYnJlYWs7XG4gICAgZWxzZSBjaGFpbi51bnNoaWZ0KFQpO1xuXG4gICAgVCA9IE9iamVjdC5nZXRQcm90b3R5cGVPZihUKTtcbiAgfVxuXG4gIGZvciAoY29uc3QgdHlwZSBvZiBjaGFpbikge1xuICAgIGlmIChNRVRIT0RTLmhhcyh0eXBlKSkge1xuICAgICAga2V5cyA9IE1FVEhPRFMuZ2V0KHR5cGUpITtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIE1FVEhPRFMuc2V0KHR5cGUsIChrZXlzID0gbmV3IE1hcChrZXlzKSkpO1xuXG4gICAgZm9yIChjb25zdCBba2V5LCB7IHZhbHVlIH1dIG9mIE9iamVjdC5lbnRyaWVzKFxuICAgICAgT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcnModHlwZS5wcm90b3R5cGUpXG4gICAgKSkge1xuICAgICAgaWYgKCF2YWx1ZSB8fCBrZXkgPT0gJ2NvbnN0cnVjdG9yJykgY29udGludWU7XG5cbiAgICAgIGZ1bmN0aW9uIGJpbmQodGhpczogU3RhdGUsIG9yaWdpbmFsPzogRnVuY3Rpb24pIHtcbiAgICAgICAgY29uc3QgeyBpcyB9ID0gdGhpcztcblxuICAgICAgICBpZiAoaXMuaGFzT3duUHJvcGVydHkoa2V5KSAmJiAhb3JpZ2luYWwpIHJldHVybiB2YWx1ZSBhcyBGdW5jdGlvbjtcblxuICAgICAgICBjb25zdCBmbiA9IG9yaWdpbmFsIHx8IHZhbHVlO1xuICAgICAgICBjb25zdCBib3VuZCA9IGZuLmJpbmQoaXMpO1xuXG4gICAgICAgIE1FVEhPRC5zZXQoYm91bmQsIGZuKTtcbiAgICAgICAgZGVmaW5lKGlzLCBrZXksIHsgdmFsdWU6IGJvdW5kLCB3cml0YWJsZTogdHJ1ZSB9KTtcblxuICAgICAgICByZXR1cm4gYm91bmQ7XG4gICAgICB9XG5cbiAgICAgIGtleXMuc2V0KGtleSwgYmluZCk7XG4gICAgICBkZWZpbmUodHlwZS5wcm90b3R5cGUsIGtleSwgeyBnZXQ6IGJpbmQsIHNldDogYmluZCB9KTtcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBBcHBseSBzdGF0ZSBhcmd1ZW1udHMsIHJ1biBjYWxsYmFja3MgYW5kIG9ic2VydmUgcHJvcGVydGllcy5cbiAqIEFjY3VtdWxhdGUgYW5kIGhhbmRsZSBjbGVhbnVwIGV2ZW50cy5cbiAqKi9cbmZ1bmN0aW9uIGluaXQoc2VsZjogU3RhdGUsIGFyZ3M6IFN0YXRlLkFyZ3MpIHtcbiAgY29uc3Qgc3RhdGUgPSB7fSBhcyBSZWNvcmQ8c3RyaW5nIHwgbnVtYmVyIHwgc3ltYm9sLCB1bmtub3duPjtcblxuICBTVEFURS5zZXQoc2VsZiwgc3RhdGUpO1xuXG4gIGFyZ3MgPSBhcmdzLmZsYXQoKS5maWx0ZXIoKGFyZykgPT4ge1xuICAgIGlmICh0eXBlb2YgYXJnID09ICdzdHJpbmcnKSBJRC5zZXQoc2VsZiwgYXJnKTtcbiAgICBlbHNlIHJldHVybiB0cnVlO1xuICB9KTtcblxuICBhZGRMaXN0ZW5lcihzZWxmLCAoKSA9PiB7XG4gICAgaWYgKCFQQVJFTlQuaGFzKHNlbGYpKSBQQVJFTlQuc2V0KHNlbGYsIG51bGwpO1xuXG4gICAgZm9yIChjb25zdCBrZXkgaW4gc2VsZikge1xuICAgICAgY29uc3QgZGVzYyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3Ioc2VsZiwga2V5KSE7XG5cbiAgICAgIGlmICgndmFsdWUnIGluIGRlc2MpIG1hbmFnZShzZWxmLCBrZXksIGRlc2MudmFsdWUsIHRydWUpO1xuICAgIH1cblxuICAgIGZvciAoY29uc3QgYXJnIG9mIGFyZ3MpIHtcbiAgICAgIGNvbnN0IHVzZSA9XG4gICAgICAgIHR5cGVvZiBhcmcgPT0gJ2Z1bmN0aW9uJ1xuICAgICAgICAgID8gYXJnLmNhbGwoc2VsZiwgc2VsZilcbiAgICAgICAgICA6IChhcmcgYXMgU3RhdGUuQXNzaWduPFN0YXRlPik7XG5cbiAgICAgIGlmICh1c2UgaW5zdGFuY2VvZiBQcm9taXNlKVxuICAgICAgICB1c2UuY2F0Y2goKGVycikgPT4ge1xuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoYEFzeW5jIGVycm9yIGluIGNvbnN0cnVjdG9yIGZvciAke3NlbGZ9OmApO1xuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyKTtcbiAgICAgICAgfSk7XG4gICAgICBlbHNlIGlmIChBcnJheS5pc0FycmF5KHVzZSkpIGFyZ3MucHVzaCguLi51c2UpO1xuICAgICAgZWxzZSBpZiAodHlwZW9mIHVzZSA9PSAnZnVuY3Rpb24nKSBhZGRMaXN0ZW5lcihzZWxmLCB1c2UsIG51bGwpO1xuICAgICAgZWxzZSBpZiAodHlwZW9mIHVzZSA9PSAnb2JqZWN0JykgYXNzaWduKHNlbGYsIHVzZSwgdHJ1ZSk7XG4gICAgfVxuXG4gICAgYWRkTGlzdGVuZXIoXG4gICAgICBzZWxmLFxuICAgICAgKCkgPT4ge1xuICAgICAgICBmb3IgKGNvbnN0IFtfLCB2YWx1ZV0gb2Ygc2VsZilcbiAgICAgICAgICBpZiAodmFsdWUgaW5zdGFuY2VvZiBTdGF0ZSAmJiBQQVJFTlQuZ2V0KHZhbHVlKSA9PT0gc2VsZilcbiAgICAgICAgICAgIHZhbHVlLnNldChudWxsKTtcblxuICAgICAgICBPYmplY3QuZnJlZXplKHN0YXRlKTtcbiAgICAgIH0sXG4gICAgICBudWxsXG4gICAgKTtcblxuICAgIHJldHVybiBudWxsO1xuICB9KTtcbn1cblxuZnVuY3Rpb24gZWZmZWN0PFQgZXh0ZW5kcyBTdGF0ZT4odGFyZ2V0OiBULCBmbjogU3RhdGUuRWZmZWN0PFQ+KSB7XG4gIGNvbnN0IGVmZmVjdCA9IE1FVEhPRC5nZXQoZm4pIHx8IGZuO1xuICBsZXQgcGVuZGluZyA9IG5ldyBTZXQ8U3RhdGUuRXZlbnQ8VD4+KCk7XG5cbiAgcmV0dXJuIHdhdGNoKHRhcmdldCwgKHByb3h5KSA9PiB7XG4gICAgY29uc3QgY2IgPSBlZmZlY3QuY2FsbChwcm94eSwgcHJveHksIHBlbmRpbmcpO1xuXG4gICAgaWYgKGNiID09PSBudWxsKSByZXR1cm4gY2I7XG5cbiAgICByZXR1cm4gKHVwZGF0ZSkgPT4ge1xuICAgICAgcGVuZGluZyA9IFBFTkRJTkdfS0VZUy5nZXQodGFyZ2V0KSE7XG4gICAgICBpZiAodHlwZW9mIGNiID09ICdmdW5jdGlvbicpIGNiKHVwZGF0ZSk7XG4gICAgfTtcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIHZhbHVlczxUIGV4dGVuZHMgU3RhdGU+KHRhcmdldDogVCk6IFN0YXRlLlZhbHVlczxUPiB7XG4gIGNvbnN0IHZhbHVlcyA9IHt9IGFzIGFueTtcbiAgbGV0IGlzTm90UmVjdXJzaXZlO1xuXG4gIGlmICghRVhQT1JUKSB7XG4gICAgaXNOb3RSZWN1cnNpdmUgPSB0cnVlO1xuICAgIEVYUE9SVCA9IG5ldyBNYXAoW1t0YXJnZXQsIHZhbHVlc11dKTtcbiAgfVxuXG4gIGZvciAobGV0IFtrZXksIHZhbHVlXSBvZiB0YXJnZXQpIHtcbiAgICBpZiAoRVhQT1JULmhhcyh2YWx1ZSkpIHZhbHVlID0gRVhQT1JULmdldCh2YWx1ZSk7XG4gICAgZWxzZSBpZiAoXG4gICAgICB2YWx1ZSAmJlxuICAgICAgdHlwZW9mIHZhbHVlID09ICdvYmplY3QnICYmXG4gICAgICAnZ2V0JyBpbiB2YWx1ZSAmJlxuICAgICAgdHlwZW9mIHZhbHVlLmdldCA9PT0gJ2Z1bmN0aW9uJ1xuICAgIClcbiAgICAgIEVYUE9SVC5zZXQodmFsdWUsICh2YWx1ZSA9IHZhbHVlLmdldCgpKSk7XG5cbiAgICB2YWx1ZXNba2V5XSA9IHZhbHVlO1xuICB9XG5cbiAgaWYgKGlzTm90UmVjdXJzaXZlKSBFWFBPUlQgPSB1bmRlZmluZWQ7XG5cbiAgcmV0dXJuIE9iamVjdC5mcmVlemUodmFsdWVzKTtcbn1cblxuZnVuY3Rpb24gbWFuYWdlKFxuICB0YXJnZXQ6IFN0YXRlLFxuICBrZXk6IHN0cmluZyB8IG51bWJlcixcbiAgdmFsdWU6IGFueSxcbiAgc2lsZW50PzogYm9vbGVhblxuKSB7XG4gIGNvbnN0IHN0YXRlID0gU1RBVEUuZ2V0KHRhcmdldCkhO1xuXG4gIGZ1bmN0aW9uIGdldCh0aGlzOiBTdGF0ZSkge1xuICAgIHJldHVybiBmb2xsb3codGhpcywga2V5LCBzdGF0ZVtrZXldKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHNldCh2YWx1ZTogdW5rbm93biwgc2lsZW50PzogYm9vbGVhbikge1xuICAgIHVwZGF0ZSh0YXJnZXQsIGtleSwgdmFsdWUsIHNpbGVudCk7XG4gICAgaWYgKHZhbHVlIGluc3RhbmNlb2YgU3RhdGUgJiYgIVBBUkVOVC5oYXModmFsdWUpKSB7XG4gICAgICBQQVJFTlQuc2V0KHZhbHVlLCB0YXJnZXQpO1xuICAgICAgZXZlbnQodmFsdWUpO1xuICAgIH1cbiAgfVxuXG4gIGRlZmluZSh0YXJnZXQsIGtleSwgeyBzZXQsIGdldCB9KTtcbiAgc2V0KHZhbHVlLCBzaWxlbnQpO1xufVxuXG50eXBlIFByb3h5PFQgPSBhbnk+ID0gKGtleTogc3RyaW5nIHwgbnVtYmVyLCB2YWx1ZTogVCkgPT4gVDtcblxuY29uc3QgT0JTRVJWRVIgPSBuZXcgV2Vha01hcDxTdGF0ZSwgUHJveHk+KCk7XG5cbmZ1bmN0aW9uIGZvbGxvdyhmcm9tOiBTdGF0ZSwga2V5OiBzdHJpbmcgfCBudW1iZXIsIHZhbHVlPzogYW55KSB7XG4gIGNvbnN0IG9ic2VydmUgPSBPQlNFUlZFUi5nZXQoZnJvbSk7XG4gIHJldHVybiBvYnNlcnZlID8gb2JzZXJ2ZShrZXksIHZhbHVlKSA6IHZhbHVlO1xufVxuXG5mdW5jdGlvbiBhY2Nlc3Moc3ViamVjdDogU3RhdGUsIHByb3BlcnR5OiBzdHJpbmcsIHJlcXVpcmVkPzogYm9vbGVhbikge1xuICBjb25zdCBzdGF0ZSA9IFNUQVRFLmdldChzdWJqZWN0KSE7XG5cbiAgaWYgKHByb3BlcnR5IGluIHN0YXRlIHx8IHJlcXVpcmVkID09PSBmYWxzZSkge1xuICAgIGNvbnN0IHZhbHVlID0gc3RhdGVbcHJvcGVydHldO1xuXG4gICAgaWYgKHZhbHVlICE9PSB1bmRlZmluZWQgfHwgIXJlcXVpcmVkKSByZXR1cm4gdmFsdWU7XG4gIH1cblxuICBpZiAoTUVUSE9EUy5nZXQoc3ViamVjdC5jb25zdHJ1Y3RvcikhLmhhcyhwcm9wZXJ0eSkpXG4gICAgcmV0dXJuIE1FVEhPRC5nZXQoKHN1YmplY3QgYXMgYW55KVtwcm9wZXJ0eV0pO1xuXG4gIGNvbnN0IGVycm9yID0gbmV3IEVycm9yKGAke3N1YmplY3R9LiR7cHJvcGVydHl9IGlzIG5vdCB5ZXQgYXZhaWxhYmxlLmApO1xuICBjb25zdCBwcm9taXNlID0gbmV3IFByb21pc2U8YW55PigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgYWRkTGlzdGVuZXIoc3ViamVjdCwgKGtleSkgPT4ge1xuICAgICAgaWYgKGtleSA9PT0gcHJvcGVydHkpIHtcbiAgICAgICAgcmVzb2x2ZShzdGF0ZVtrZXldKTtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG5cbiAgICAgIGlmIChrZXkgPT09IG51bGwpIHtcbiAgICAgICAgcmVqZWN0KG5ldyBFcnJvcihgJHtzdWJqZWN0fSBpcyBkZXN0cm95ZWQuYCkpO1xuICAgICAgfVxuICAgIH0pO1xuICB9KTtcblxuICB0aHJvdyBPYmplY3QuYXNzaWduKHByb21pc2UsIHtcbiAgICB0b1N0cmluZzogKCkgPT4gU3RyaW5nKGVycm9yKSxcbiAgICBuYW1lOiAnU3VzcGVuc2UnLFxuICAgIG1lc3NhZ2U6IGVycm9yLm1lc3NhZ2UsXG4gICAgc3RhY2s6IGVycm9yLnN0YWNrXG4gIH0pO1xufVxuXG5mdW5jdGlvbiB1cGRhdGU8VD4oXG4gIHN1YmplY3Q6IFN0YXRlLFxuICBrZXk6IHN0cmluZyB8IG51bWJlciB8IHN5bWJvbCxcbiAgdmFsdWU6IFQsXG4gIGFyZz86IGJvb2xlYW4gfCBTdGF0ZS5TZXR0ZXI8VD5cbikge1xuICBjb25zdCBzdGF0ZSA9IFNUQVRFLmdldChzdWJqZWN0KSE7XG5cbiAgaWYgKE9iamVjdC5pc0Zyb3plbihzdGF0ZSkpXG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgYFRyaWVkIHRvIHVwZGF0ZSAke3N1YmplY3R9LiR7U3RyaW5nKGtleSl9IGJ1dCBzdGF0ZSBpcyBkZXN0cm95ZWQuYFxuICAgICk7XG5cbiAgY29uc3QgcHJldmlvdXMgPSBzdGF0ZVtrZXldIGFzIFQ7XG5cbiAgaWYgKHR5cGVvZiBhcmcgPT0gJ2Z1bmN0aW9uJykge1xuICAgIGNvbnN0IG91dCA9IGFyZy5jYWxsKHN1YmplY3QsIHZhbHVlLCBwcmV2aW91cyk7XG5cbiAgICBpZiAob3V0ID09PSBmYWxzZSkgcmV0dXJuIGZhbHNlO1xuXG4gICAgaWYgKHR5cGVvZiBvdXQgPT0gJ2Z1bmN0aW9uJykgdmFsdWUgPSBvdXQoKTtcbiAgfVxuXG4gIGlmICh2YWx1ZSA9PT0gcHJldmlvdXMgJiYga2V5IGluIHN0YXRlKSByZXR1cm47XG5cbiAgc3RhdGVba2V5XSA9IHZhbHVlO1xuXG4gIGlmIChhcmcgIT09IHRydWUpIGV2ZW50KHN1YmplY3QsIGtleSk7XG5cbiAgcmV0dXJuIHRydWU7XG59XG5cbi8qKiBSYW5kb20gYWxwaGFudW1iZXJpYyBvZiBsZW5ndGggNjsgYWx3YXlzIHN0YXJ0cyB3aXRoIGEgbGV0dGVyLiAqL1xuZnVuY3Rpb24gdWlkKCkge1xuICByZXR1cm4gKDAuMjc4ICsgTWF0aC5yYW5kb20oKSAqIDAuNzIyKVxuICAgIC50b1N0cmluZygzNilcbiAgICAuc3Vic3RyaW5nKDIsIDgpXG4gICAgLnRvVXBwZXJDYXNlKCk7XG59XG5cbmV4cG9ydCB7IGV2ZW50LCBNRVRIT0QsIFN0YXRlLCBQQVJFTlQsIFNUQVRFLCB1aWQsIGFjY2VzcywgdXBkYXRlLCBmb2xsb3cgfTtcbiJdLAogICJtYXBwaW5ncyI6ICJBQUFBO0FBQUEsRUFDRTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBRUE7QUFBQSxPQUNLO0FBRVAsTUFBTSxTQUFT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LE1BQUksUUFBUSxJQUFJLFFBQVEsV0FBVyxFQUFHLElBQUksUUFBUTtBQUNoRCxXQUFPLE9BQU8sSUFBSyxRQUFnQixRQUFRLENBQUM7QUFFOUMsUUFBTSxRQUFRLElBQUksTUFBTSxHQUFHLE9BQU8sSUFBSSxRQUFRLHdCQUF3QjtBQUN0RSxRQUFNLFVBQVUsSUFBSSxRQUFhLENBQUMsU0FBUyxXQUFXO0FBQ3BELGdCQUFZLFNBQVMsQ0FBQyxRQUFRO0FBQzVCLFVBQUksUUFBUSxVQUFVO0FBQ3BCLGdCQUFRLE1BQU0sR0FBRyxDQUFDO0FBQ2xCLGVBQU87QUFBQSxNQUNUO0FBRUEsVUFBSSxRQUFRLE1BQU07QUFDaEIsZUFBTyxJQUFJLE1BQU0sR0FBRyxPQUFPLGdCQUFnQixDQUFDO0FBQUEsTUFDOUM7QUFBQSxJQUNGLENBQUM7QUFBQSxFQUNILENBQUM7QUFFRCxRQUFNLE9BQU8sT0FBTyxTQUFTO0FBQUEsSUFDM0IsVUFBVSxNQUFNLE9BQU8sS0FBSztBQUFBLElBQzVCLE1BQU07QUFBQSxJQUNOLFNBQVMsTUFBTTtBQUFBLElBQ2YsT0FBTyxNQUFNO0FBQUEsRUFDZixDQUFDO0FBQ0g7QUFFQSxTQUFTLE9BQ1AsU0FDQSxLQUNBLE9BQ0EsS0FDQTtBQUNBLFFBQU0sUUFBUSxNQUFNLElBQUksT0FBTztBQUUvQixNQUFJLE9BQU8sU0FBUyxLQUFLO0FBQ3ZCLFVBQU0sSUFBSTtBQUFBLE1BQ1IsbUJBQW1CLE9BQU8sSUFBSSxPQUFPLEdBQUcsQ0FBQztBQUFBLElBQzNDO0FBRUYsUUFBTSxXQUFXLE1BQU0sR0FBRztBQUUxQixNQUFJLE9BQU8sT0FBTyxZQUFZO0FBQzVCLFVBQU0sTUFBTSxJQUFJLEtBQUssU0FBUyxPQUFPLFFBQVE7QUFFN0MsUUFBSSxRQUFRLE1BQU8sUUFBTztBQUUxQixRQUFJLE9BQU8sT0FBTyxXQUFZLFNBQVEsSUFBSTtBQUFBLEVBQzVDO0FBRUEsTUFBSSxVQUFVLFlBQVksT0FBTyxNQUFPO0FBRXhDLFFBQU0sR0FBRyxJQUFJO0FBRWIsTUFBSSxRQUFRLEtBQU0sT0FBTSxTQUFTLEdBQUc7QUFFcEMsU0FBTztBQUNUO0FBR0EsU0FBUyxNQUFNO0FBQ2IsVUFBUSxRQUFRLEtBQUssT0FBTyxJQUFJLE9BQzdCLFNBQVMsRUFBRSxFQUNYLFVBQVUsR0FBRyxDQUFDLEVBQ2QsWUFBWTtBQUNqQjsiLAogICJuYW1lcyI6IFsid2F0Y2giLCAicmVzIiwgImJpbmQiLCAiZWZmZWN0IiwgInVwZGF0ZSIsICJ2YWx1ZXMiLCAidmFsdWUiLCAic2lsZW50Il0KfQo=
|