@expressive/mvc 0.72.0 → 0.73.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/state.js CHANGED
@@ -1,324 +1,293 @@
1
- import {
2
- addListener,
3
- watch,
4
- event,
5
- Observable,
6
- PENDING_KEYS
7
- } from "./control";
1
+ import { Observable, PENDING_KEYS, addListener, event, watch } from "./observable.js";
2
+
3
+ //#region src/state.ts
8
4
  const define = Object.defineProperty;
5
+ /** Register for all active states via string identifiers (usually unique). */
9
6
  const ID = /* @__PURE__ */ new WeakMap();
7
+ /** Internal state assigned to states. */
10
8
  const STATE = /* @__PURE__ */ new WeakMap();
9
+ /** External listeners for any given State. */
11
10
  const NOTIFY = /* @__PURE__ */ new WeakMap();
11
+ /** Parent-child relationships. */
12
12
  const PARENT = /* @__PURE__ */ new WeakMap();
13
+ /** List of methods defined by a given type. */
13
14
  const METHODS = /* @__PURE__ */ new WeakMap();
15
+ /** Reference bound instance methods to real ones. */
14
16
  const METHOD = /* @__PURE__ */ new WeakMap();
17
+ /** Currently accumulating export. Stores real values of placeholder properties such as ref() or child states. */
15
18
  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
- });
19
+ var State = class {
20
+ constructor(...args) {
21
+ prepare(this);
22
+ define(this, "is", { value: this });
23
+ init(this, ...args, (x) => x.new && x.new());
24
+ }
25
+ [Observable](callback, required) {
26
+ const watch = /* @__PURE__ */ new Set();
27
+ const proxy = Object.create(this);
28
+ addListener(this, (key) => {
29
+ if (watch.has(key)) callback();
30
+ });
31
+ OBSERVER.set(proxy, (key, value) => {
32
+ if (value === void 0 && required) throw new Error(`${this}.${key} is required in this context.`);
33
+ watch.add(key);
34
+ if (value instanceof Object && Observable in value) return value[Observable](callback, required) || value;
35
+ return value;
36
+ });
37
+ return proxy;
38
+ }
39
+ get(arg1, arg2) {
40
+ const self = this.is;
41
+ if (arg1 === void 0) return values(self);
42
+ if (typeof arg1 == "function") return effect(self, arg1);
43
+ if (typeof arg2 == "function") return addListener(self, arg2, arg1);
44
+ if (arg1 === null) return Object.isFrozen(STATE.get(self));
45
+ return access(self, arg1, arg2);
46
+ }
47
+ set(arg1, arg2, arg3) {
48
+ const self = this.is;
49
+ if (typeof arg1 == "function") return addListener(self, (key) => {
50
+ if (arg2 === key || arg2 === void 0 && typeof key == "string") return arg1.call(self, key, self);
51
+ });
52
+ if (arg1 && typeof arg1 == "object") assign(self, arg1, arg2 === true);
53
+ else if (!arg2) event(self, arg1);
54
+ else if (arg3) manage(self, arg1, arg2);
55
+ else update(self, arg1, arg2);
56
+ const pending = PENDING_KEYS.get(this);
57
+ if (pending) return { then: (resolve) => new Promise((res) => {
58
+ const remove = addListener(this, (key) => {
59
+ if (key !== true) {
60
+ remove();
61
+ return () => res(Array.from(pending));
62
+ }
63
+ });
64
+ }).then(resolve) };
65
+ }
66
+ /**
67
+ * Iterate over managed properties in this instance of State.
68
+ * Yeilds the key and current value for each property.
69
+ */
70
+ [Symbol.iterator]() {
71
+ return Object.entries(STATE.get(this.is))[Symbol.iterator]();
72
+ }
73
+ /**
74
+ * Create and activate a new instance of this state.
75
+ *
76
+ * **Important** - Unlike `new this(...)` - this method also activates state.
77
+ *
78
+ * @param args - arguments sent to constructor
79
+ */
80
+ static new(...args) {
81
+ const instance = new this(...args);
82
+ event(instance);
83
+ return instance;
84
+ }
85
+ /**
86
+ * Static equivalent of `x instanceof this`.
87
+ * Determines if provided class is a subtype of this one.
88
+ * If so, language server will make available all static
89
+ * methods and properties of this class.
90
+ */
91
+ static is(maybe) {
92
+ return maybe === this || typeof maybe == "function" && maybe.prototype instanceof this;
93
+ }
94
+ /**
95
+ * Register a callback to run when any instance of this State is updated.
96
+ */
97
+ static on(listener) {
98
+ let notify = NOTIFY.get(this);
99
+ if (!notify) NOTIFY.set(this, notify = /* @__PURE__ */ new Set());
100
+ notify.add(listener);
101
+ return () => notify.delete(listener);
102
+ }
103
+ };
104
+ define(State.prototype, "toString", { value() {
105
+ return ID.get(this.is);
106
+ } });
107
+ define(State, "toString", { value() {
108
+ return this.name;
109
+ } });
126
110
  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
- }
111
+ const methods = METHODS.get(subject.constructor);
112
+ for (const key in data) {
113
+ const bind = methods.get(key);
114
+ if (bind) bind.call(subject, data[key]);
115
+ else if (key in subject && key !== "is") {
116
+ const desc = Object.getOwnPropertyDescriptor(subject, key);
117
+ const set = desc && desc.set;
118
+ if (set) set.call(subject, data[key], silent);
119
+ else subject[key] = data[key];
120
+ }
121
+ }
141
122
  }
123
+ /** Apply instructions and inherited event listeners. Ensure class metadata is ready. */
142
124
  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
- }
125
+ let T = state.constructor;
126
+ if (T === State) throw new Error("Cannot create base State.");
127
+ const chain = [];
128
+ let keys = /* @__PURE__ */ new Map();
129
+ ID.set(state, `${T}-${uid()}`);
130
+ while (T.name) {
131
+ for (const cb of NOTIFY.get(T) || []) addListener(state, cb);
132
+ if (T === State) break;
133
+ else chain.unshift(T);
134
+ T = Object.getPrototypeOf(T);
135
+ }
136
+ for (const type of chain) {
137
+ if (METHODS.has(type)) {
138
+ keys = METHODS.get(type);
139
+ continue;
140
+ }
141
+ METHODS.set(type, keys = new Map(keys));
142
+ for (const [key, { value }] of Object.entries(Object.getOwnPropertyDescriptors(type.prototype))) {
143
+ if (!value || key == "constructor") continue;
144
+ function bind(original) {
145
+ const { is } = this;
146
+ if (is.hasOwnProperty(key) && !original) return value;
147
+ const fn = original || value;
148
+ const bound = fn.bind(is);
149
+ METHOD.set(bound, fn);
150
+ define(is, key, {
151
+ value: bound,
152
+ writable: true
153
+ });
154
+ return bound;
155
+ }
156
+ keys.set(key, bind);
157
+ define(type.prototype, key, {
158
+ get: bind,
159
+ set: bind
160
+ });
161
+ }
162
+ }
180
163
  }
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
- });
164
+ /**
165
+ * Apply state arguemnts, run callbacks and observe properties.
166
+ * Accumulate and handle cleanup events.
167
+ **/
168
+ function init(self, ...args) {
169
+ const state = {};
170
+ STATE.set(self, state);
171
+ args = args.flat().filter((arg) => {
172
+ if (typeof arg == "string") ID.set(self, arg);
173
+ else return true;
174
+ });
175
+ addListener(self, () => {
176
+ if (!PARENT.has(self)) PARENT.set(self, null);
177
+ for (const key in self) {
178
+ const desc = Object.getOwnPropertyDescriptor(self, key);
179
+ if ("value" in desc) manage(self, key, desc.value, true);
180
+ }
181
+ for (const arg of args) {
182
+ const use = typeof arg == "function" ? arg.call(self, self) : arg;
183
+ if (use instanceof Promise) use.catch((err) => {
184
+ console.error(`Async error in constructor for ${self}:`);
185
+ console.error(err);
186
+ });
187
+ else if (Array.isArray(use)) args.push(...use);
188
+ else if (typeof use == "function") addListener(self, use, null);
189
+ else if (typeof use == "object") assign(self, use, true);
190
+ }
191
+ addListener(self, () => {
192
+ for (const [_, value] of self) if (value instanceof State && PARENT.get(value) === self) value.set(null);
193
+ Object.freeze(state);
194
+ }, null);
195
+ return null;
196
+ });
197
+ }
198
+ function manage(target, key, value, silent) {
199
+ const state = STATE.get(target);
200
+ function get() {
201
+ return follow(this, key, state[key]);
202
+ }
203
+ function set(value, silent) {
204
+ update(target, key, value, silent);
205
+ if (value instanceof State && !PARENT.has(value)) {
206
+ PARENT.set(value, target);
207
+ event(value);
208
+ }
209
+ }
210
+ define(target, key, {
211
+ set,
212
+ get
213
+ });
214
+ set(value, silent);
217
215
  }
218
216
  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
- });
217
+ const effect = METHOD.get(fn) || fn;
218
+ let pending = /* @__PURE__ */ new Set();
219
+ return watch(target, (proxy) => {
220
+ const cb = effect.call(proxy, proxy, pending);
221
+ if (cb === null) return cb;
222
+ return (update) => {
223
+ pending = PENDING_KEYS.get(target);
224
+ if (typeof cb == "function") cb(update);
225
+ };
226
+ });
229
227
  }
230
228
  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);
229
+ const values = {};
230
+ let isNotRecursive;
231
+ if (!EXPORT) {
232
+ isNotRecursive = true;
233
+ EXPORT = new Map([[target, values]]);
234
+ }
235
+ for (let [key, value] of target) {
236
+ if (EXPORT.has(value)) value = EXPORT.get(value);
237
+ else if (value && typeof value == "object" && "get" in value && typeof value.get === "function") EXPORT.set(value, value = value.get());
238
+ values[key] = value;
239
+ }
240
+ if (isNotRecursive) EXPORT = void 0;
241
+ return Object.freeze(values);
260
242
  }
261
243
  const OBSERVER = /* @__PURE__ */ new WeakMap();
262
244
  function follow(from, key, value) {
263
- const observe = OBSERVER.get(from);
264
- return observe ? observe(key, value) : value;
245
+ const observe = OBSERVER.get(from);
246
+ return observe ? observe(key, value) : value;
265
247
  }
266
248
  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
- });
249
+ const state = STATE.get(subject);
250
+ if (property in state || required === false) {
251
+ const value = state[property];
252
+ if (value !== void 0 || !required) return value;
253
+ }
254
+ if (METHODS.get(subject.constructor).has(property)) return METHOD.get(subject[property]);
255
+ const error = /* @__PURE__ */ new Error(`${subject}.${property} is not yet available.`);
256
+ const promise = new Promise((resolve, reject) => {
257
+ addListener(subject, (key) => {
258
+ if (key === property) {
259
+ resolve(state[key]);
260
+ return null;
261
+ }
262
+ if (key === null) reject(/* @__PURE__ */ new Error(`${subject} is destroyed.`));
263
+ });
264
+ });
265
+ throw Object.assign(promise, {
266
+ toString: () => String(error),
267
+ name: "Suspense",
268
+ message: error.message,
269
+ stack: error.stack
270
+ });
292
271
  }
293
272
  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;
273
+ const state = STATE.get(subject);
274
+ if (Object.isFrozen(state)) throw new Error(`Tried to update ${subject}.${String(key)} but state is destroyed.`);
275
+ const previous = state[key];
276
+ if (typeof arg == "function") {
277
+ const out = arg.call(subject, value, previous);
278
+ if (out === false) return false;
279
+ if (typeof out == "function") value = out();
280
+ }
281
+ if (value === previous && key in state) return;
282
+ state[key] = value;
283
+ if (arg !== true) event(subject, key);
284
+ return true;
309
285
  }
286
+ /** Random alphanumberic of length 6; always starts with a letter. */
310
287
  function uid() {
311
- return (0.278 + Math.random() * 0.722).toString(36).substring(2, 8).toUpperCase();
288
+ return (.278 + Math.random() * .722).toString(36).substring(2, 8).toUpperCase();
312
289
  }
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=
290
+
291
+ //#endregion
292
+ export { METHOD, PARENT, STATE, State, access, event, follow, uid, update };
293
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RhdGUuanMiLCJuYW1lcyI6W10sInNvdXJjZXMiOlsiLi4vLi4vc3JjL3N0YXRlLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIGFkZExpc3RlbmVyLFxuICB3YXRjaCxcbiAgZXZlbnQsXG4gIE9ic2VydmFibGUsXG4gIE5vdGlmeSxcbiAgUEVORElOR19LRVlTXG59IGZyb20gJy4vb2JzZXJ2YWJsZSc7XG5cbmNvbnN0IGRlZmluZSA9IE9iamVjdC5kZWZpbmVQcm9wZXJ0eTtcblxuLyoqIFJlZ2lzdGVyIGZvciBhbGwgYWN0aXZlIHN0YXRlcyB2aWEgc3RyaW5nIGlkZW50aWZpZXJzICh1c3VhbGx5IHVuaXF1ZSkuICovXG5jb25zdCBJRCA9IG5ldyBXZWFrTWFwPFN0YXRlLCBzdHJpbmc+KCk7XG5cbi8qKiBJbnRlcm5hbCBzdGF0ZSBhc3NpZ25lZCB0byBzdGF0ZXMuICovXG5jb25zdCBTVEFURSA9IG5ldyBXZWFrTWFwPFN0YXRlLCBSZWNvcmQ8c3RyaW5nIHwgbnVtYmVyIHwgc3ltYm9sLCB1bmtub3duPj4oKTtcblxuLyoqIEV4dGVybmFsIGxpc3RlbmVycyBmb3IgYW55IGdpdmVuIFN0YXRlLiAqL1xuY29uc3QgTk9USUZZID0gbmV3IFdlYWtNYXA8U3RhdGUuRXh0ZW5kcywgU2V0PE5vdGlmeT4+KCk7XG5cbi8qKiBQYXJlbnQtY2hpbGQgcmVsYXRpb25zaGlwcy4gKi9cbmNvbnN0IFBBUkVOVCA9IG5ldyBXZWFrTWFwPFN0YXRlLCBTdGF0ZSB8IG51bGw+KCk7XG5cbi8qKiBMaXN0IG9mIG1ldGhvZHMgZGVmaW5lZCBieSBhIGdpdmVuIHR5cGUuICovXG5jb25zdCBNRVRIT0RTID0gbmV3IFdlYWtNYXA8RnVuY3Rpb24sIE1hcDxzdHJpbmcsICh2YWx1ZTogYW55KSA9PiB2b2lkPj4oKTtcblxuLyoqIFJlZmVyZW5jZSBib3VuZCBpbnN0YW5jZSBtZXRob2RzIHRvIHJlYWwgb25lcy4gKi9cbmNvbnN0IE1FVEhPRCA9IG5ldyBXZWFrTWFwPGFueSwgYW55PigpO1xuXG4vKiogQ3VycmVudGx5IGFjY3VtdWxhdGluZyBleHBvcnQuIFN0b3JlcyByZWFsIHZhbHVlcyBvZiBwbGFjZWhvbGRlciBwcm9wZXJ0aWVzIHN1Y2ggYXMgcmVmKCkgb3IgY2hpbGQgc3RhdGVzLiAqL1xubGV0IEVYUE9SVDogTWFwPGFueSwgYW55PiB8IHVuZGVmaW5lZDtcblxuZGVjbGFyZSBuYW1lc3BhY2UgU3RhdGUge1xuICAvKiogQW55IHR5cGUgb2YgU3RhdGUsIHVzaW5nIG93biBjbGFzcyBjb25zdHJ1Y3RvciBhcyBpdHMgaWRlbnRpZmllci4gKi9cbiAgdHlwZSBFeHRlbmRzPFQgZXh0ZW5kcyBTdGF0ZSA9IFN0YXRlPiA9IChhYnN0cmFjdCBuZXcgKC4uLmFyZ3M6IGFueVtdKSA9PiBUKSAmXG4gICAgdHlwZW9mIFN0YXRlO1xuXG4gIC8qKiBBIFN0YXRlIGNvbnN0cnVjdG9yIHdoaWNoIG1heSBiZSBpbnN0YW5jaWF0ZWQuICovXG4gIHR5cGUgVHlwZTxUIGV4dGVuZHMgU3RhdGUgPSBTdGF0ZT4gPSAobmV3ICguLi5hcmdzOiBTdGF0ZS5BcmdzPFQ+KSA9PiBUKSAmXG4gICAgT21pdDx0eXBlb2YgU3RhdGUsIG5ldmVyPjtcblxuICAvKiogU3RhdGUgY29uc3RydWN0b3IgYXJndW1lbnRzICovXG4gIHR5cGUgQXJnczxUIGV4dGVuZHMgU3RhdGUgPSBhbnk+ID0gKFxuICAgIHwgQXJnczxUPlxuICAgIHwgSW5pdDxUPlxuICAgIHwgQXNzaWduPFQ+XG4gICAgfCBzdHJpbmdcbiAgICB8IHZvaWRcbiAgKVtdO1xuXG4gIC8qKlxuICAgKiBTdGF0ZSBjb25zdHJ1Y3RvciBjYWxsYmFjayAtIGlzIGNhbGxlZCB3aGVuIFN0YXRlIGZpbmlzaGVzIGludGlhbGl6aW5nLlxuICAgKiBSZXR1cm5lZCBmdW5jdGlvbiB3aWxsIHJ1biB3aGVuIHN0YXRlIGlzIGRlc3Ryb3llZC5cbiAgICovXG4gIHR5cGUgSW5pdDxUIGV4dGVuZHMgU3RhdGUgPSBTdGF0ZT4gPSAoXG4gICAgdGhpczogVCxcbiAgICB0aGlzQXJnOiBUXG4gICkgPT4gUHJvbWlzZTx2b2lkPiB8ICgoKSA9PiB2b2lkKSB8IEFyZ3M8VD4gfCBBc3NpZ248VD4gfCB2b2lkO1xuXG4gIC8qKiBPYmplY3Qgb3ZlcmxheSB0byBvdmVycmlkZSB2YWx1ZXMgYW5kIG1ldGhvZHMgb24gYSBzdGF0ZS4gKi9cbiAgdHlwZSBBc3NpZ248VD4gPSBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiAmIHtcbiAgICBbSyBpbiBGaWVsZDxUPl0/OiBUW0tdIGV4dGVuZHMgKC4uLmFyZ3M6IGluZmVyIEEpID0+IGluZmVyIFJcbiAgICAgID8gKHRoaXM6IFQsIC4uLmFyZ3M6IEEpID0+IFJcbiAgICAgIDogVFtLXTtcbiAgfTtcblxuICAvKiogU3Vic2V0IG9mIGBrZXlvZiBUYCB3aGljaCBhcmUgbm90IG1ldGhvZHMgb3IgZGVmaW5lZCBieSBiYXNlIFN0YXRlIFUuICoqL1xuICB0eXBlIEZpZWxkPFQ+ID0gRXhjbHVkZTxrZXlvZiBULCBrZXlvZiBTdGF0ZT47XG5cbiAgLyoqIEFueSB2YWxpZCBrZXkgZm9yIHN0YXRlLCBpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIEZpZWxkPFQ+LiAqL1xuICB0eXBlIEV2ZW50PFQ+ID0gRmllbGQ8VD4gfCBudW1iZXIgfCBzeW1ib2wgfCAoc3RyaW5nICYge30pO1xuXG4gIC8qKiBFeHBvcnQvSW1wb3J0IGNvbXBhdGlibGUgdmFsdWUgZm9yIGEgZ2l2ZW4gcHJvcGVydHkgaW4gYSBTdGF0ZS4gKi9cbiAgdHlwZSBFeHBvcnQ8Uj4gPSBSIGV4dGVuZHMgeyBnZXQoKTogaW5mZXIgVCB9ID8gVCA6IFI7XG5cbiAgLyoqIFZhbHVlIGZvciBhIHByb3BlcnR5IG1hbmFnZWQgYnkgYSBzdGF0ZS4gKi9cbiAgdHlwZSBWYWx1ZTxUIGV4dGVuZHMgU3RhdGUsIEsgZXh0ZW5kcyBTdGF0ZS5FdmVudDxUPj4gPSBLIGV4dGVuZHMga2V5b2YgVFxuICAgID8gRXhwb3J0PFRbS10+XG4gICAgOiB1bmtub3duO1xuXG4gIHR5cGUgU2V0dGVyPFQ+ID0gKHZhbHVlOiBULCBwcmV2aW91czogVCkgPT4gYm9vbGVhbiB8IHZvaWQgfCAoKCkgPT4gVCk7XG5cbiAgdHlwZSBPbkV2ZW50PFQgZXh0ZW5kcyBTdGF0ZT4gPSAoXG4gICAgdGhpczogVCxcbiAgICBrZXk6IHVua25vd24sXG4gICAgc291cmNlOiBUXG4gICkgPT4gdm9pZCB8ICgoKSA9PiB2b2lkKSB8IG51bGw7XG5cbiAgdHlwZSBPblVwZGF0ZTxUIGV4dGVuZHMgU3RhdGUsIEsgZXh0ZW5kcyBTdGF0ZS5FdmVudDxUPj4gPSAoXG4gICAgdGhpczogVCxcbiAgICBrZXk6IEssXG4gICAgdGhpc0FyZzogS1xuICApID0+IHZvaWQ7XG5cbiAgLyoqXG4gICAqIFZhbHVlcyBmcm9tIGN1cnJlbnQgc3RhdGUgb2YgZ2l2ZW4gc3RhdGUuXG4gICAqIERpZmZlcnMgZnJvbSBgVmFsdWVzYCBhcyB2YWx1ZXMgaGVyZSB3aWxsIGRyaWxsXG4gICAqIGludG8gXCJyZWFsXCIgdmFsdWVzIGhlbGQgYnkgZXhvdGljcyBsaWtlIHJlZi5PYmplY3QuXG4gICAqL1xuICB0eXBlIFZhbHVlczxUPiA9IHsgW1AgaW4gRmllbGQ8VD5dOiBFeHBvcnQ8VFtQXT4gfTtcblxuICAvKiogT2JqZWN0IGNvbXBlcmFibGUgdG8gZGF0YSBmb3VuZCBpbiBULiAqL1xuICB0eXBlIFBhcnRpYWw8VD4gPSB7IFtQIGluIEZpZWxkPFQ+XT86IEV4cG9ydDxUW1BdPiB9O1xuXG4gIC8qKiBFeG90aWMgdmFsdWUsIHdoZXJlIGFjdHVhbCB2YWx1ZSBpcyBjb250YWluZWQgd2l0aGluLiAqL1xuICB0eXBlIFJlZjxUID0gYW55PiA9IHtcbiAgICAobmV4dDogVCk6IHZvaWQ7XG4gICAgY3VycmVudDogVCB8IG51bGw7XG4gIH07XG5cbiAgLyoqXG4gICAqIEEgY2FsbGJhY2sgZnVuY3Rpb24gd2hpY2ggaXMgc3Vic2NyaWJlZCB0byBwYXJlbnQgYW5kIHVwZGF0ZXMgd2hlbiBhY2Nlc3NlZCBwcm9wZXJ0aWVzIGNoYW5nZS5cbiAgICpcbiAgICogQHBhcmFtIGN1cnJlbnQgLSBDdXJyZW50IHN0YXRlIG9mIHRoaXMgc3RhdGUuIFRoaXMgaXMgYSBwcm94eSB3aGljaCBkZXRlY3RzIHByb3BlcnRpZXMgd2hpY2hcbiAgICogd2hlcmUgYWNjZXNzZWQsIGFuZCB0aHVzIGRlcGVuZGVkIHVwb24gdG8gc3RheSBjdXJyZW50LlxuICAgKlxuICAgKiBAcGFyYW0gdXBkYXRlIC0gU2V0IG9mIHByb3BlcnRpZXMgd2hpY2ggaGF2ZSBjaGFuZ2VkLCBhbmQgZXZlbnRzIGZpcmVkLCBzaW5jZSBsYXN0IHVwZGF0ZS5cbiAgICpcbiAgICogQHJldHVybnMgQSBjYWxsYmFjayBmdW5jdGlvbiB3aGljaCB3aWxsIGJlIGNhbGxlZCB3aGVuIHRoaXMgZWZmZWN0IGlzIHN0YWxlLlxuICAgKi9cbiAgdHlwZSBFZmZlY3Q8VD4gPSAoXG4gICAgdGhpczogVCxcbiAgICBjdXJyZW50OiBULFxuICAgIHVwZGF0ZTogU2V0PFN0YXRlLkV2ZW50PFQ+PlxuICApID0+IEVmZmVjdENhbGxiYWNrIHwgUHJvbWlzZTx2b2lkPiB8IG51bGwgfCB2b2lkO1xuXG4gIC8qKlxuICAgKiBBIGNhbGxiYWNrIGZ1bmN0aW9uIHJldHVybmVkIGJ5IGVmZmVjdC4gV2lsbCBiZSBjYWxsZWQgd2hlbiBlZmZlY3QgaXMgc3RhbGUuXG4gICAqXG4gICAqIEBwYXJhbSB1cGRhdGUgLSBgdHJ1ZWAgaWYgdXBkYXRlIGlzIHBlbmRpbmcsIGBmYWxzZWAgZWZmZWN0IGhhcyBiZWVuIGNhbmNlbGxlZCwgYG51bGxgIGlmIHN0YXRlIGlzIGRlc3Ryb3llZC5cbiAgICovXG4gIHR5cGUgRWZmZWN0Q2FsbGJhY2sgPSAodXBkYXRlOiBib29sZWFuIHwgbnVsbCkgPT4gdm9pZDtcbn1cblxuaW50ZXJmYWNlIFN0YXRlIHtcbiAgLyoqXG4gICAqIExvb3BiYWNrIHRvIGluc3RhbmNlIG9mIHRoaXMgc3RhdGUuIFRoaXMgaXMgdXNlZnVsIHdoZW4gaW4gYSBzdWJzY3JpYmVkIGNvbnRleHQsXG4gICAqIHRvIGtlZXAgd3JpdGUgYWNjZXNzIHRvIGB0aGlzYCBhZnRlciBhIGRlc3RydWN0dXJlLiBZb3UgY2FuIHVzZSBpdCB0byByZWFkIHZhcmlhYmxlcyBzaWxlbnRseSBhcyB3ZWxsLlxuICAgKiovXG4gIGlzOiB0aGlzO1xufVxuXG5hYnN0cmFjdCBjbGFzcyBTdGF0ZSBpbXBsZW1lbnRzIE9ic2VydmFibGUge1xuICBjb25zdHJ1Y3RvciguLi5hcmdzOiBTdGF0ZS5BcmdzKSB7XG4gICAgcHJlcGFyZSh0aGlzKTtcbiAgICBkZWZpbmUodGhpcywgJ2lzJywgeyB2YWx1ZTogdGhpcyB9KTtcbiAgICBpbml0KHRoaXMsIC4uLmFyZ3MsICh4OiB0aGlzKSA9PiB4Lm5ldyAmJiB4Lm5ldygpKTtcbiAgfVxuXG4gIFtPYnNlcnZhYmxlXShjYWxsYmFjazogT2JzZXJ2YWJsZS5DYWxsYmFjaywgcmVxdWlyZWQ/OiBib29sZWFuKSB7XG4gICAgY29uc3Qgd2F0Y2ggPSBuZXcgU2V0PHVua25vd24+KCk7XG4gICAgY29uc3QgcHJveHkgPSBPYmplY3QuY3JlYXRlKHRoaXMpO1xuXG4gICAgYWRkTGlzdGVuZXIodGhpcywgKGtleSkgPT4ge1xuICAgICAgaWYgKHdhdGNoLmhhcyhrZXkpKSBjYWxsYmFjaygpO1xuICAgIH0pO1xuXG4gICAgT0JTRVJWRVIuc2V0KHByb3h5LCAoa2V5LCB2YWx1ZSkgPT4ge1xuICAgICAgaWYgKHZhbHVlID09PSB1bmRlZmluZWQgJiYgcmVxdWlyZWQpXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgJHt0aGlzfS4ke2tleX0gaXMgcmVxdWlyZWQgaW4gdGhpcyBjb250ZXh0LmApO1xuXG4gICAgICB3YXRjaC5hZGQoa2V5KTtcblxuICAgICAgaWYgKHZhbHVlIGluc3RhbmNlb2YgT2JqZWN0ICYmIE9ic2VydmFibGUgaW4gdmFsdWUpXG4gICAgICAgIHJldHVybiB2YWx1ZVtPYnNlcnZhYmxlXShjYWxsYmFjaywgcmVxdWlyZWQpIHx8IHZhbHVlO1xuXG4gICAgICByZXR1cm4gdmFsdWU7XG4gICAgfSk7XG5cbiAgICByZXR1cm4gcHJveHkgYXMgdGhpcztcbiAgfVxuXG4gIC8qKlxuICAgKiBPcHRpb25hbCBsaWZlY3ljbGUgaG9vayBjYWxsZWQgZHVyaW5nIFN0YXRlIGluaXRpYWxpemF0aW9uLlxuICAgKiBDYW4gcmV0dXJuIGEgY2xlYW51cCBmdW5jdGlvbiB0byBydW4gd2hlbiBzdGF0ZSBpcyBkZXN0cm95ZWQuXG4gICAqL1xuICBwcm90ZWN0ZWQgbmV3PygpOiB2b2lkIHwgKCgpID0+IHZvaWQpO1xuXG4gIC8qKlxuICAgKiBQdWxsIGN1cnJlbnQgdmFsdWVzIGZyb20gc3RhdGUuIEZsYXR0ZW5zIGFsbCBzdGF0ZXMgYW5kIGV4b3RpYyB2YWx1ZXMgcmVjdXJzaXZlbHkuXG4gICAqXG4gICAqIEByZXR1cm5zIE9iamVjdCB3aXRoIGFsbCB2YWx1ZXMgZnJvbSB0aGlzIHN0YXRlLlxuICAgKiovXG4gIGdldCgpOiBTdGF0ZS5WYWx1ZXM8dGhpcz47XG5cbiAgLyoqXG4gICAqIFJ1biBhIGZ1bmN0aW9uIHdoaWNoIHdpbGwgcnVuIGF1dG9tYXRpY2FsbHkgd2hlbiBhY2Nlc3NlZCB2YWx1ZXMgY2hhbmdlLlxuICAgKlxuICAgKiBAcGFyYW0gZWZmZWN0IEZ1bmN0aW9uIHRvIHJ1biwgYW5kIGFnYWluIHdoZW5ldmVyIGFjY2Vzc2VkIHZhbHVlcyBjaGFuZ2UuXG4gICAqICAgICAgICAgICAgICAgSWYgZWZmZWN0IHJldHVybnMgYSBmdW5jdGlvbiwgaXQgd2lsbCBiZSBjYWxsZWQgd2hlbiBhIGNoYW5nZSBvY2N1cnMgKHN5bmNyb25vdXNseSksXG4gICAqICAgICAgICAgICAgICAgZWZmZWN0IGlzIGNhbmNlbGxlZCwgb3IgcGFyZW50IHN0YXRlIGlzIGRlc3Ryb3llZC5cbiAgICogQHJldHVybnMgRnVuY3Rpb24gdG8gY2FuY2VsIGxpc3RlbmVyLlxuICAgKi9cbiAgZ2V0KGVmZmVjdDogU3RhdGUuRWZmZWN0PHRoaXM+KTogKCkgPT4gdm9pZDtcblxuICAvKipcbiAgICogR2V0IHZhbHVlIG9mIGEgcHJvcGVydHkuXG4gICAqXG4gICAqIEBwYXJhbSBrZXkgLSBQcm9wZXJ0eSB0byBnZXQgdmFsdWUgb2YuXG4gICAqIEBwYXJhbSByZXF1aXJlZCAtIElmIHRydWUsIHdpbGwgdGhyb3cgYW4gZXJyb3IgaWYgcHJvcGVydHkgaXMgbm90IGF2YWlsYWJsZS5cbiAgICogQHJldHVybnMgVmFsdWUgb2YgcHJvcGVydHkuXG4gICAqL1xuICBnZXQ8VCBleHRlbmRzIFN0YXRlLkV2ZW50PHRoaXM+PihcbiAgICBrZXk6IFQsXG4gICAgcmVxdWlyZWQ/OiBib29sZWFuXG4gICk6IFN0YXRlLlZhbHVlPHRoaXMsIFQ+O1xuXG4gIC8qKlxuICAgKiBSdW4gYSBmdW5jdGlvbiB3aGVuIGEgcHJvcGVydHkgaXMgdXBkYXRlZC5cbiAgICpcbiAgICogQHBhcmFtIGtleSAtIFByb3BlcnR5IHRvIHdhdGNoIGZvciB1cGRhdGVzLlxuICAgKiBAcGFyYW0gY2FsbGJhY2sgLSBGdW5jdGlvbiB0byBjYWxsIHdoZW4gcHJvcGVydHkgaXMgdXBkYXRlZC5cbiAgICogQHJldHVybnMgRnVuY3Rpb24gdG8gY2FuY2VsIGxpc3RlbmVyLlxuICAgKi9cbiAgZ2V0PFQgZXh0ZW5kcyBTdGF0ZS5FdmVudDx0aGlzPj4oXG4gICAga2V5OiBULFxuICAgIGNhbGxiYWNrOiBTdGF0ZS5PblVwZGF0ZTx0aGlzLCBUPlxuICApOiAoKSA9PiB2b2lkO1xuXG4gIC8qKlxuICAgKiBDaGVjayBpZiBzdGF0ZSBpcyBleHBpcmVkLlxuICAgKlxuICAgKiBAcGFyYW0gc3RhdHVzIC0gYG51bGxgIHRvIGNoZWNrIGlmIHN0YXRlIGlzIGV4cGlyZWQuXG4gICAqIEByZXR1cm5zIGB0cnVlYCBpZiBzdGF0ZSBpcyBleHBpcmVkLCBgZmFsc2VgIG90aGVyd2lzZS5cbiAgICovXG4gIGdldChzdGF0dXM6IG51bGwpOiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBDYWxsYmFjayB3aGVuIHN0YXRlIGlzIHRvIGJlIGRlc3Ryb3llZC5cbiAgICpcbiAgICogQHBhcmFtIGNhbGxiYWNrIC0gRnVuY3Rpb24gdG8gY2FsbCB3aGVuIHN0YXRlIGlzIGRlc3Ryb3llZC5cbiAgICogQHJldHVybnMgRnVuY3Rpb24gdG8gY2FuY2VsIGxpc3RlbmVyLlxuICAgKi9cbiAgZ2V0KHN0YXR1czogbnVsbCwgY2FsbGJhY2s6ICgpID0+IHZvaWQpOiAoKSA9PiB2b2lkO1xuXG4gIGdldChcbiAgICBhcmcxPzogU3RhdGUuRWZmZWN0PHRoaXM+IHwgc3RyaW5nIHwgbnVsbCxcbiAgICBhcmcyPzogYm9vbGVhbiB8IFN0YXRlLk9uVXBkYXRlPHRoaXMsIGFueT5cbiAgKSB7XG4gICAgY29uc3Qgc2VsZiA9IHRoaXMuaXM7XG5cbiAgICBpZiAoYXJnMSA9PT0gdW5kZWZpbmVkKSByZXR1cm4gdmFsdWVzKHNlbGYpO1xuICAgIGlmICh0eXBlb2YgYXJnMSA9PSAnZnVuY3Rpb24nKSByZXR1cm4gZWZmZWN0KHNlbGYsIGFyZzEpO1xuICAgIGlmICh0eXBlb2YgYXJnMiA9PSAnZnVuY3Rpb24nKSByZXR1cm4gYWRkTGlzdGVuZXIoc2VsZiwgYXJnMiwgYXJnMSk7XG4gICAgaWYgKGFyZzEgPT09IG51bGwpIHJldHVybiBPYmplY3QuaXNGcm96ZW4oU1RBVEUuZ2V0KHNlbGYpKTtcbiAgICByZXR1cm4gYWNjZXNzKHNlbGYsIGFyZzEsIGFyZzIpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCB1cGRhdGUgaW4gcHJvZ3Jlc3MuXG4gICAqXG4gICAqIEByZXR1cm5zIFByb21pc2Ugd2hpY2ggcmVzb2x2ZXMgb2JqZWN0IHdpdGggdXBkYXRlZCB2YWx1ZXMsIGB1bmRlZmluZWRgIGlmIHRoZXJlIG5vIHVwZGF0ZSBpcyBwZW5kaW5nLlxuICAgKiovXG4gIHNldCgpOiBQcm9taXNlTGlrZTxTdGF0ZS5FdmVudDx0aGlzPltdPiB8IHVuZGVmaW5lZDtcblxuICAvKipcbiAgICogVXBkYXRlIG11bGl0cGxlIHByb3BlcnRpZXMgYXQgb25jZS4gTWVyZ2VzIGFyZ3VtZW50IHdpdGggY3VycmVudCBzdGF0ZS5cbiAgICogUHJvcGVydGllcyB3aGljaCBhcmUgbm90IG1hbmFnZWQgYnkgdGhpcyBzdGF0ZSB3aWxsIGJlIGlnbm9yZWQuXG4gICAqXG4gICAqIEBwYXJhbSBhc3NpZ24gLSBPYmplY3Qgd2l0aCBwcm9wZXJ0aWVzIHRvIHVwZGF0ZS5cbiAgICogQHBhcmFtIHNpbGVudCAtIElmIGFuIHVwZGF0ZSBkb2VzIG9jY3VyLCBsaXN0ZW5lcnMgd2lsbCBub3QgYmUgcmVmcmVzaGVkIGF1dG9tYXRpY2FsbHkuXG4gICAqIEByZXR1cm5zIFByb21pc2UgcmVzb2x2aW5nIGFuIGFycmF5IG9mIGtleXMgdXBkYXRlZCwgYHVuZGVmaW5lZGAgKGltbWVkaWF0ZWx5KSBpZiBhIG5vb3AuXG4gICAqL1xuICBzZXQoXG4gICAgYXNzaWduPzogU3RhdGUuQXNzaWduPHRoaXM+LFxuICAgIHNpbGVudD86IGJvb2xlYW5cbiAgKTogUHJvbWlzZUxpa2U8U3RhdGUuRXZlbnQ8dGhpcz5bXT4gfCB1bmRlZmluZWQ7XG5cbiAgLyoqXG4gICAqIFB1c2ggYW4gdXBkYXRlLiBUaGlzIHdpbGwgbm90IGNoYW5nZSB0aGUgdmFsdWUgb2YgYXNzb2NpYXRlZCBwcm9wZXJ0eS5cbiAgICpcbiAgICogVXNlZnVsIHdoZXJlIGEgcHJvcGVydHkgdmFsdWUgaW50ZXJuYWxseSBoYXMgY2hhbmdlZCwgYnV0IHRoZSBvYmplY3QgaXMgdGhlIHNhbWUuXG4gICAqIEZvciBleGFtcGxlOiBBbiBhcnJheSBoYXMgcHVzaGVkIGEgbmV3IHZhbHVlLCBvciBhIG5lc3RlZCBwcm9wZXJ0eSBpcyB1cGRhdGVkLlxuICAgKlxuICAgKiBZb3UgY2FuIGFsc28gdXNlIHRoaXMgdG8gZGlzcGF0Y2ggYXJiaXRyYXJ5IGV2ZW50cy5cbiAgICogU3ltYm9scyBhcmUgcmVjb21tZW5kZWQgYXMgbm9uLXByb3BlcnR5IGV2ZW50cywgaG93ZXZlciB5b3UgY2FuIHVzZSBhbnkgc3RyaW5nLlxuICAgKiBJZiBkb2luZyBzbywgYmUgc3VyZSB0byBhdm9pZCBjb2xsaXNpb25zIHdpdGggcHJvcGVydHkgbmFtZXMhIEFuIGVhc3kgd2F5IHRvIGRvIHRoaXMgaXNcbiAgICogdG8gcHJlZml4IGFuIGV2ZW50IHdpdGggXCIhXCIgYW5kL29yIHVzZSBkYXNoLWNhc2UuIGUuZy4gYHNldChcIiFldmVudFwiKWAgb3IgYHNldChcIm15LWV2ZW50XCIpYC5cbiAgICpcbiAgICogQHBhcmFtIGtleSAtIFByb3BlcnR5IG9yIGV2ZW50IHRvIGRpc3BhdGNoLlxuICAgKiBAcmV0dXJucyBQcm9taXNlIHJlc29sdmVzIGFuIGFycmF5IG9mIGtleXMgdXBkYXRlZC5cbiAgICovXG4gIHNldChrZXk6IFN0YXRlLkV2ZW50PHRoaXM+KTogUHJvbWlzZUxpa2U8U3RhdGUuRXZlbnQ8dGhpcz5bXT47XG5cbiAgLyoqXG4gICAqIFNldCBhIHZhbHVlIGZvciBhIHByb3BlcnR5LiBUaGlzIHdpbGwgdXBkYXRlIHRoZSB2YWx1ZSBhbmQgbm90aWZ5IGxpc3RlbmVycy5cbiAgICpcbiAgICogKipVc2Ugd2l0aCBjYXV0aW9uISoqIEtleSBub3IgdmFsdWUgYXJlIGNoZWNrZWQgZm9yIHZhbGlkaXR5LlxuICAgKlxuICAgKiBUaGlzIGlzIG1lYW50IGZvciBhc3NpZ25pbmcgdmFsdWVzIHByb2dyYW1tYXRpY2FsbHksXG4gICAqIHdoZXJlIHNpbXBsZSBhc3NpZ25tZW50IGlzIG5vdCBwcmFjdGljYWJsZS5cbiAgICpcbiAgICogRm9yIGV4YW1wbGU6IGAodGhpcyBhcyBhbnkpW215UHJvcGVydHldID0gdmFsdWU7YFxuICAgKlxuICAgKiBAcGFyYW0ga2V5IC0gUHJvcGVydHkgdG8gc2V0IHZhbHVlIGZvci5cbiAgICogQHBhcmFtIHZhbHVlIC0gVmFsdWUgdG8gc2V0IGZvciBwcm9wZXJ0eS5cbiAgICogQHBhcmFtIGluaXQgLSBJZiB0cnVlLCBzdGF0ZSB3aWxsIGJlZ2luIHRvIG1hbmFnZSB0aGUgcHJvcGVydHkgaWYgaXQgaXMgbm90IGFscmVhZHkuXG4gICAqIEByZXR1cm5zIFByb21pc2UgcmVzb2x2ZXMgYW4gYXJyYXkgb2Yga2V5cyB1cGRhdGVkLlxuICAgKi9cbiAgc2V0KFxuICAgIGtleTogU3RhdGUuRXZlbnQ8dGhpcz4sXG4gICAgdmFsdWU6IHVua25vd24sXG4gICAgaW5pdD86IGJvb2xlYW5cbiAgKTogUHJvbWlzZUxpa2U8U3RhdGUuRXZlbnQ8dGhpcz5bXT47XG5cbiAgLyoqXG4gICAqIENhbGwgYSBmdW5jdGlvbiB3aGVuIHVwZGF0ZSBvY2N1cnMuXG4gICAqXG4gICAqIEdpdmVuIGZ1bmN0aW9uIGlzIGNhbGxlZCBmb3IgZXZlcnkgYXNzaWdubWVudCAod2hpY2ggY2hhbmdlcyB2YWx1ZSkgb3IgZXhwbGljaXQgYHNldGAuXG4gICAqXG4gICAqIFRvIHJ1biBsb2dpYyBvbiBmaW5hbCB2YWx1ZSBvbmx5LCBjYWxsYmFjayBtYXkgcmV0dXJuIGEgZnVuY3Rpb24uIFVzaW5nIHRoZSBzYW1lXG4gICAqIGZ1bmN0aW9uIGZvciBvbmUgb3IgbW9yZSBldmVudHMgd2lsbCBlbnN1cmUgaXQgaXMgY2FsbGVkIG9ubHkgd2hlbiBldmVudHMgYXJlIHNldHRsZWQuXG4gICAqXG4gICAqIEBwYXJhbSBjYWxsYmFjayAtIEZ1bmN0aW9uIHRvIGNhbGwgd2hlbiB1cGRhdGUgb2NjdXJzLlxuICAgKiBAcmV0dXJucyBGdW5jdGlvbiB0byByZW1vdmUgbGlzdGVuZXIuIFdpbGwgcmV0dXJuIGB0cnVlYCBpZiByZW1vdmVkLCBgZmFsc2VgIGlmIGluYWN0aXZlIGFscmVhZHkuXG4gICAqXG4gICAqL1xuICBzZXQoY2FsbGJhY2s6IFN0YXRlLk9uRXZlbnQ8dGhpcz4pOiAoKSA9PiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBDYWxsIGEgZnVuY3Rpb24gd2hlbiBhIHByb3BlcnR5IGlzIHVwZGF0ZWQuXG4gICAqIFVubGlrZSBgZ2V0YCwgdGhpcyBjYWxscyBzeW5jaHJvbm91c2x5IGFuZCB3aWxsIGZpcmUgYXMgbWFueSB0aW1lcyBhcyB0aGUgcHJvcGVydHkgaXMgdXBkYXRlZC5cbiAgICpcbiAgICogQHBhcmFtIGNhbGxiYWNrIC0gRnVuY3Rpb24gdG8gY2FsbCB3aGVuIHByb3BlcnR5IGlzIHVwZGF0ZWQuXG4gICAqIEBwYXJhbSBldmVudCAtIFByb3BlcnR5IHRvIHdhdGNoIGZvciB1cGRhdGVzLlxuICAgKi9cbiAgc2V0KFxuICAgIGNhbGxiYWNrOiBTdGF0ZS5PbkV2ZW50PHRoaXM+LFxuICAgIGV2ZW50OiBTdGF0ZS5FdmVudDx0aGlzPiB8IG51bGxcbiAgKTogKCkgPT4gYm9vbGVhbjtcblxuICAvKipcbiAgICogRGVjbGFyZSBhbiBlbmQgdG8gdXBkYXRlcy4gVGhpcyBldmVudCBpcyBmaW5hbCBhbmQgd2lsbCBmcmVlemUgc3RhdGUuXG4gICAqIFRoaXMgZXZlbnQgY2FuIGJlIHdhdGNoZWQgZm9yIGFzIHdlbGwsIHRvIHJ1biBjbGVhbnVwIGxvZ2ljIGFuZCBpbnRlcm5hbGx5IHdpbGwgcmVtb3ZlIGFsbCBsaXN0ZW5lcnMuXG4gICAqXG4gICAqIEBwYXJhbSBzdGF0dXMgLSBgbnVsbGAgdG8gZW5kIHVwZGF0ZXMuXG4gICAqL1xuICBzZXQoc3RhdHVzOiBudWxsKTogdm9pZDtcblxuICBzZXQoXG4gICAgYXJnMT86IFN0YXRlLk9uRXZlbnQ8dGhpcz4gfCBTdGF0ZS5Bc3NpZ248dGhpcz4gfCBTdGF0ZS5FdmVudDx0aGlzPiB8IG51bGwsXG4gICAgYXJnMj86IHVua25vd24sXG4gICAgYXJnMz86IGJvb2xlYW5cbiAgKSB7XG4gICAgY29uc3Qgc2VsZiA9IHRoaXMuaXM7XG5cbiAgICBpZiAodHlwZW9mIGFyZzEgPT0gJ2Z1bmN0aW9uJylcbiAgICAgIHJldHVybiBhZGRMaXN0ZW5lcihzZWxmLCAoa2V5KSA9PiB7XG4gICAgICAgIGlmIChhcmcyID09PSBrZXkgfHwgKGFyZzIgPT09IHVuZGVmaW5lZCAmJiB0eXBlb2Yga2V5ID09ICdzdHJpbmcnKSlcbiAgICAgICAgICByZXR1cm4gYXJnMS5jYWxsKHNlbGYsIGtleSwgc2VsZik7XG4gICAgICB9KTtcblxuICAgIGlmIChhcmcxICYmIHR5cGVvZiBhcmcxID09ICdvYmplY3QnKSB7XG4gICAgICBhc3NpZ24oc2VsZiwgYXJnMSwgYXJnMiA9PT0gdHJ1ZSk7XG4gICAgfSBlbHNlIGlmICghYXJnMikge1xuICAgICAgZXZlbnQoc2VsZiwgYXJnMSk7XG4gICAgfSBlbHNlIGlmIChhcmczKSB7XG4gICAgICBtYW5hZ2Uoc2VsZiwgYXJnMSBhcyBzdHJpbmcgfCBudW1iZXIsIGFyZzIpO1xuICAgIH0gZWxzZSB7XG4gICAgICB1cGRhdGUoc2VsZiwgYXJnMSBhcyBzdHJpbmcgfCBudW1iZXIsIGFyZzIpO1xuICAgIH1cblxuICAgIGNvbnN0IHBlbmRpbmcgPSBQRU5ESU5HX0tFWVMuZ2V0KHRoaXMpO1xuXG4gICAgaWYgKHBlbmRpbmcpXG4gICAgICByZXR1cm4gPFByb21pc2VMaWtlPFN0YXRlLkV2ZW50PHRoaXM+W10+PntcbiAgICAgICAgdGhlbjogKHJlc29sdmUpID0+XG4gICAgICAgICAgbmV3IFByb21pc2U8YW55PigocmVzKSA9PiB7XG4gICAgICAgICAgICBjb25zdCByZW1vdmUgPSBhZGRMaXN0ZW5lcih0aGlzLCAoa2V5KSA9PiB7XG4gICAgICAgICAgICAgIGlmIChrZXkgIT09IHRydWUpIHtcbiAgICAgICAgICAgICAgICByZW1vdmUoKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gKCkgPT4gcmVzKEFycmF5LmZyb20ocGVuZGluZykpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9KS50aGVuKHJlc29sdmUpXG4gICAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIEl0ZXJhdGUgb3ZlciBtYW5hZ2VkIHByb3BlcnRpZXMgaW4gdGhpcyBpbnN0YW5jZSBvZiBTdGF0ZS5cbiAgICogWWVpbGRzIHRoZSBrZXkgYW5kIGN1cnJlbnQgdmFsdWUgZm9yIGVhY2ggcHJvcGVydHkuXG4gICAqL1xuICBbU3ltYm9sLml0ZXJhdG9yXSgpOiBJdGVyYXRvcjxbc3RyaW5nLCB1bmtub3duXT4ge1xuICAgIHJldHVybiBPYmplY3QuZW50cmllcyhTVEFURS5nZXQodGhpcy5pcykhKVtTeW1ib2wuaXRlcmF0b3JdKCk7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlIGFuZCBhY3RpdmF0ZSBhIG5ldyBpbnN0YW5jZSBvZiB0aGlzIHN0YXRlLlxuICAgKlxuICAgKiAqKkltcG9ydGFudCoqIC0gVW5saWtlIGBuZXcgdGhpcyguLi4pYCAtIHRoaXMgbWV0aG9kIGFsc28gYWN0aXZhdGVzIHN0YXRlLlxuICAgKlxuICAgKiBAcGFyYW0gYXJncyAtIGFyZ3VtZW50cyBzZW50IHRvIGNvbnN0cnVjdG9yXG4gICAqL1xuICBzdGF0aWMgbmV3PFQgZXh0ZW5kcyBTdGF0ZT4odGhpczogU3RhdGUuVHlwZTxUPiwgLi4uYXJnczogU3RhdGUuQXJnczxUPik6IFQge1xuICAgIGNvbnN0IGluc3RhbmNlID0gbmV3IHRoaXMoLi4uYXJncyk7XG4gICAgZXZlbnQoaW5zdGFuY2UpO1xuICAgIHJldHVybiBpbnN0YW5jZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTdGF0aWMgZXF1aXZhbGVudCBvZiBgeCBpbnN0YW5jZW9mIHRoaXNgLlxuICAgKiBEZXRlcm1pbmVzIGlmIHByb3ZpZGVkIGNsYXNzIGlzIGEgc3VidHlwZSBvZiB0aGlzIG9uZS5cbiAgICogSWYgc28sIGxhbmd1YWdlIHNlcnZlciB3aWxsIG1ha2UgYXZhaWxhYmxlIGFsbCBzdGF0aWNcbiAgICogbWV0aG9kcyBhbmQgcHJvcGVydGllcyBvZiB0aGlzIGNsYXNzLlxuICAgKi9cbiAgc3RhdGljIGlzPFQgZXh0ZW5kcyBTdGF0ZS5FeHRlbmRzPih0aGlzOiBULCBtYXliZTogdW5rbm93bik6IG1heWJlIGlzIFQge1xuICAgIHJldHVybiAoXG4gICAgICBtYXliZSA9PT0gdGhpcyB8fFxuICAgICAgKHR5cGVvZiBtYXliZSA9PSAnZnVuY3Rpb24nICYmIG1heWJlLnByb3RvdHlwZSBpbnN0YW5jZW9mIHRoaXMpXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWdpc3RlciBhIGNhbGxiYWNrIHRvIHJ1biB3aGVuIGFueSBpbnN0YW5jZSBvZiB0aGlzIFN0YXRlIGlzIHVwZGF0ZWQuXG4gICAqL1xuICBzdGF0aWMgb248VCBleHRlbmRzIFN0YXRlPihcbiAgICB0aGlzOiBTdGF0ZS5FeHRlbmRzPFQ+LFxuICAgIGxpc3RlbmVyOiBTdGF0ZS5PbkV2ZW50PFQ+XG4gICkge1xuICAgIGxldCBub3RpZnkgPSBOT1RJRlkuZ2V0KHRoaXMpO1xuXG4gICAgaWYgKCFub3RpZnkpIE5PVElGWS5zZXQodGhpcywgKG5vdGlmeSA9IG5ldyBTZXQoKSkpO1xuXG4gICAgbm90aWZ5LmFkZChsaXN0ZW5lcik7XG5cbiAgICByZXR1cm4gKCkgPT4gbm90aWZ5LmRlbGV0ZShsaXN0ZW5lcik7XG4gIH1cbn1cblxuZGVmaW5lKFN0YXRlLnByb3RvdHlwZSwgJ3RvU3RyaW5nJywge1xuICB2YWx1ZSgpIHtcbiAgICByZXR1cm4gSUQuZ2V0KHRoaXMuaXMpO1xuICB9XG59KTtcblxuZGVmaW5lKFN0YXRlLCAndG9TdHJpbmcnLCB7XG4gIHZhbHVlKCkge1xuICAgIHJldHVybiB0aGlzLm5hbWU7XG4gIH1cbn0pO1xuXG5mdW5jdGlvbiBhc3NpZ24oc3ViamVjdDogU3RhdGUsIGRhdGE6IFN0YXRlLkFzc2lnbjxTdGF0ZT4sIHNpbGVudD86IGJvb2xlYW4pIHtcbiAgY29uc3QgbWV0aG9kcyA9IE1FVEhPRFMuZ2V0KHN1YmplY3QuY29uc3RydWN0b3IpITtcblxuICBmb3IgKGNvbnN0IGtleSBpbiBkYXRhKSB7XG4gICAgY29uc3QgYmluZCA9IG1ldGhvZHMuZ2V0KGtleSk7XG5cbiAgICBpZiAoYmluZCkgYmluZC5jYWxsKHN1YmplY3QsIGRhdGFba2V5XSk7XG4gICAgZWxzZSBpZiAoa2V5IGluIHN1YmplY3QgJiYga2V5ICE9PSAnaXMnKSB7XG4gICAgICBjb25zdCBkZXNjID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihzdWJqZWN0LCBrZXkpITtcbiAgICAgIGNvbnN0IHNldCA9IGRlc2MgJiYgKGRlc2Muc2V0IGFzICh2YWx1ZTogYW55LCBzaWxlbnQ/OiBib29sZWFuKSA9PiB2b2lkKTtcblxuICAgICAgaWYgKHNldCkge1xuICAgICAgICBzZXQuY2FsbChzdWJqZWN0LCBkYXRhW2tleV0sIHNpbGVudCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAoc3ViamVjdCBhcyBhbnkpW2tleV0gPSBkYXRhW2tleV07XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbi8qKiBBcHBseSBpbnN0cnVjdGlvbnMgYW5kIGluaGVyaXRlZCBldmVudCBsaXN0ZW5lcnMuIEVuc3VyZSBjbGFzcyBtZXRhZGF0YSBpcyByZWFkeS4gKi9cbmZ1bmN0aW9uIHByZXBhcmUoc3RhdGU6IFN0YXRlKSB7XG4gIGxldCBUID0gc3RhdGUuY29uc3RydWN0b3IgYXMgU3RhdGUuRXh0ZW5kcztcblxuICBpZiAoVCA9PT0gU3RhdGUpIHRocm93IG5ldyBFcnJvcignQ2Fubm90IGNyZWF0ZSBiYXNlIFN0YXRlLicpO1xuXG4gIGNvbnN0IGNoYWluID0gW10gYXMgU3RhdGUuRXh0ZW5kc1tdO1xuICBsZXQga2V5cyA9IG5ldyBNYXA8c3RyaW5nLCAodmFsdWU6IGFueSkgPT4gdm9pZD4oKTtcblxuICBJRC5zZXQoc3RhdGUsIGAke1R9LSR7dWlkKCl9YCk7XG5cbiAgd2hpbGUgKFQubmFtZSkge1xuICAgIGZvciAoY29uc3QgY2Igb2YgTk9USUZZLmdldChUKSB8fCBbXSkge1xuICAgICAgYWRkTGlzdGVuZXIoc3RhdGUsIGNiKTtcbiAgICB9XG5cbiAgICBpZiAoVCA9PT0gU3RhdGUpIGJyZWFrO1xuICAgIGVsc2UgY2hhaW4udW5zaGlmdChUKTtcblxuICAgIFQgPSBPYmplY3QuZ2V0UHJvdG90eXBlT2YoVCk7XG4gIH1cblxuICBmb3IgKGNvbnN0IHR5cGUgb2YgY2hhaW4pIHtcbiAgICBpZiAoTUVUSE9EUy5oYXModHlwZSkpIHtcbiAgICAgIGtleXMgPSBNRVRIT0RTLmdldCh0eXBlKSE7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBNRVRIT0RTLnNldCh0eXBlLCAoa2V5cyA9IG5ldyBNYXAoa2V5cykpKTtcblxuICAgIGZvciAoY29uc3QgW2tleSwgeyB2YWx1ZSB9XSBvZiBPYmplY3QuZW50cmllcyhcbiAgICAgIE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3JzKHR5cGUucHJvdG90eXBlKVxuICAgICkpIHtcbiAgICAgIGlmICghdmFsdWUgfHwga2V5ID09ICdjb25zdHJ1Y3RvcicpIGNvbnRpbnVlO1xuXG4gICAgICBmdW5jdGlvbiBiaW5kKHRoaXM6IFN0YXRlLCBvcmlnaW5hbD86IEZ1bmN0aW9uKSB7XG4gICAgICAgIGNvbnN0IHsgaXMgfSA9IHRoaXM7XG5cbiAgICAgICAgaWYgKGlzLmhhc093blByb3BlcnR5KGtleSkgJiYgIW9yaWdpbmFsKSByZXR1cm4gdmFsdWUgYXMgRnVuY3Rpb247XG5cbiAgICAgICAgY29uc3QgZm4gPSBvcmlnaW5hbCB8fCB2YWx1ZTtcbiAgICAgICAgY29uc3QgYm91bmQgPSBmbi5iaW5kKGlzKTtcblxuICAgICAgICBNRVRIT0Quc2V0KGJvdW5kLCBmbik7XG4gICAgICAgIGRlZmluZShpcywga2V5LCB7IHZhbHVlOiBib3VuZCwgd3JpdGFibGU6IHRydWUgfSk7XG5cbiAgICAgICAgcmV0dXJuIGJvdW5kO1xuICAgICAgfVxuXG4gICAgICBrZXlzLnNldChrZXksIGJpbmQpO1xuICAgICAgZGVmaW5lKHR5cGUucHJvdG90eXBlLCBrZXksIHsgZ2V0OiBiaW5kLCBzZXQ6IGJpbmQgfSk7XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogQXBwbHkgc3RhdGUgYXJndWVtbnRzLCBydW4gY2FsbGJhY2tzIGFuZCBvYnNlcnZlIHByb3BlcnRpZXMuXG4gKiBBY2N1bXVsYXRlIGFuZCBoYW5kbGUgY2xlYW51cCBldmVudHMuXG4gKiovXG5mdW5jdGlvbiBpbml0KHNlbGY6IFN0YXRlLCAuLi5hcmdzOiBTdGF0ZS5BcmdzKSB7XG4gIGNvbnN0IHN0YXRlID0ge30gYXMgUmVjb3JkPHN0cmluZyB8IG51bWJlciB8IHN5bWJvbCwgdW5rbm93bj47XG5cbiAgU1RBVEUuc2V0KHNlbGYsIHN0YXRlKTtcblxuICBhcmdzID0gYXJncy5mbGF0KCkuZmlsdGVyKChhcmcpID0+IHtcbiAgICBpZiAodHlwZW9mIGFyZyA9PSAnc3RyaW5nJykgSUQuc2V0KHNlbGYsIGFyZyk7XG4gICAgZWxzZSByZXR1cm4gdHJ1ZTtcbiAgfSk7XG5cbiAgYWRkTGlzdGVuZXIoc2VsZiwgKCkgPT4ge1xuICAgIGlmICghUEFSRU5ULmhhcyhzZWxmKSkgUEFSRU5ULnNldChzZWxmLCBudWxsKTtcblxuICAgIGZvciAoY29uc3Qga2V5IGluIHNlbGYpIHtcbiAgICAgIGNvbnN0IGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHNlbGYsIGtleSkhO1xuXG4gICAgICBpZiAoJ3ZhbHVlJyBpbiBkZXNjKSBtYW5hZ2Uoc2VsZiwga2V5LCBkZXNjLnZhbHVlLCB0cnVlKTtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IGFyZyBvZiBhcmdzKSB7XG4gICAgICBjb25zdCB1c2UgPVxuICAgICAgICB0eXBlb2YgYXJnID09ICdmdW5jdGlvbidcbiAgICAgICAgICA/IGFyZy5jYWxsKHNlbGYsIHNlbGYpXG4gICAgICAgICAgOiAoYXJnIGFzIFN0YXRlLkFzc2lnbjxTdGF0ZT4pO1xuXG4gICAgICBpZiAodXNlIGluc3RhbmNlb2YgUHJvbWlzZSlcbiAgICAgICAgdXNlLmNhdGNoKChlcnIpID0+IHtcbiAgICAgICAgICBjb25zb2xlLmVycm9yKGBBc3luYyBlcnJvciBpbiBjb25zdHJ1Y3RvciBmb3IgJHtzZWxmfTpgKTtcbiAgICAgICAgICBjb25zb2xlLmVycm9yKGVycik7XG4gICAgICAgIH0pO1xuICAgICAgZWxzZSBpZiAoQXJyYXkuaXNBcnJheSh1c2UpKSBhcmdzLnB1c2goLi4udXNlKTtcbiAgICAgIGVsc2UgaWYgKHR5cGVvZiB1c2UgPT0gJ2Z1bmN0aW9uJykgYWRkTGlzdGVuZXIoc2VsZiwgdXNlLCBudWxsKTtcbiAgICAgIGVsc2UgaWYgKHR5cGVvZiB1c2UgPT0gJ29iamVjdCcpIGFzc2lnbihzZWxmLCB1c2UsIHRydWUpO1xuICAgIH1cblxuICAgIGFkZExpc3RlbmVyKFxuICAgICAgc2VsZixcbiAgICAgICgpID0+IHtcbiAgICAgICAgZm9yIChjb25zdCBbXywgdmFsdWVdIG9mIHNlbGYpXG4gICAgICAgICAgaWYgKHZhbHVlIGluc3RhbmNlb2YgU3RhdGUgJiYgUEFSRU5ULmdldCh2YWx1ZSkgPT09IHNlbGYpXG4gICAgICAgICAgICB2YWx1ZS5zZXQobnVsbCk7XG5cbiAgICAgICAgT2JqZWN0LmZyZWV6ZShzdGF0ZSk7XG4gICAgICB9LFxuICAgICAgbnVsbFxuICAgICk7XG5cbiAgICByZXR1cm4gbnVsbDtcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIG1hbmFnZShcbiAgdGFyZ2V0OiBTdGF0ZSxcbiAga2V5OiBzdHJpbmcgfCBudW1iZXIsXG4gIHZhbHVlOiBhbnksXG4gIHNpbGVudD86IGJvb2xlYW5cbikge1xuICBjb25zdCBzdGF0ZSA9IFNUQVRFLmdldCh0YXJnZXQpITtcblxuICBmdW5jdGlvbiBnZXQodGhpczogU3RhdGUpIHtcbiAgICByZXR1cm4gZm9sbG93KHRoaXMsIGtleSwgc3RhdGVba2V5XSk7XG4gIH1cblxuICBmdW5jdGlvbiBzZXQodmFsdWU6IHVua25vd24sIHNpbGVudD86IGJvb2xlYW4pIHtcbiAgICB1cGRhdGUodGFyZ2V0LCBrZXksIHZhbHVlLCBzaWxlbnQpO1xuICAgIGlmICh2YWx1ZSBpbnN0YW5jZW9mIFN0YXRlICYmICFQQVJFTlQuaGFzKHZhbHVlKSkge1xuICAgICAgUEFSRU5ULnNldCh2YWx1ZSwgdGFyZ2V0KTtcbiAgICAgIGV2ZW50KHZhbHVlKTtcbiAgICB9XG4gIH1cblxuICBkZWZpbmUodGFyZ2V0LCBrZXksIHsgc2V0LCBnZXQgfSk7XG4gIHNldCh2YWx1ZSwgc2lsZW50KTtcbn1cblxuZnVuY3Rpb24gZWZmZWN0PFQgZXh0ZW5kcyBTdGF0ZT4odGFyZ2V0OiBULCBmbjogU3RhdGUuRWZmZWN0PFQ+KSB7XG4gIGNvbnN0IGVmZmVjdCA9IE1FVEhPRC5nZXQoZm4pIHx8IGZuO1xuICBsZXQgcGVuZGluZyA9IG5ldyBTZXQ8U3RhdGUuRXZlbnQ8VD4+KCk7XG5cbiAgcmV0dXJuIHdhdGNoKHRhcmdldCwgKHByb3h5KSA9PiB7XG4gICAgY29uc3QgY2IgPSBlZmZlY3QuY2FsbChwcm94eSwgcHJveHksIHBlbmRpbmcpO1xuXG4gICAgaWYgKGNiID09PSBudWxsKSByZXR1cm4gY2I7XG5cbiAgICByZXR1cm4gKHVwZGF0ZSkgPT4ge1xuICAgICAgcGVuZGluZyA9IFBFTkRJTkdfS0VZUy5nZXQodGFyZ2V0KSE7XG4gICAgICBpZiAodHlwZW9mIGNiID09ICdmdW5jdGlvbicpIGNiKHVwZGF0ZSk7XG4gICAgfTtcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIHZhbHVlczxUIGV4dGVuZHMgU3RhdGU+KHRhcmdldDogVCk6IFN0YXRlLlZhbHVlczxUPiB7XG4gIGNvbnN0IHZhbHVlcyA9IHt9IGFzIGFueTtcbiAgbGV0IGlzTm90UmVjdXJzaXZlO1xuXG4gIGlmICghRVhQT1JUKSB7XG4gICAgaXNOb3RSZWN1cnNpdmUgPSB0cnVlO1xuICAgIEVYUE9SVCA9IG5ldyBNYXAoW1t0YXJnZXQsIHZhbHVlc11dKTtcbiAgfVxuXG4gIGZvciAobGV0IFtrZXksIHZhbHVlXSBvZiB0YXJnZXQpIHtcbiAgICBpZiAoRVhQT1JULmhhcyh2YWx1ZSkpIHZhbHVlID0gRVhQT1JULmdldCh2YWx1ZSk7XG4gICAgZWxzZSBpZiAoXG4gICAgICB2YWx1ZSAmJlxuICAgICAgdHlwZW9mIHZhbHVlID09ICdvYmplY3QnICYmXG4gICAgICAnZ2V0JyBpbiB2YWx1ZSAmJlxuICAgICAgdHlwZW9mIHZhbHVlLmdldCA9PT0gJ2Z1bmN0aW9uJ1xuICAgIClcbiAgICAgIEVYUE9SVC5zZXQodmFsdWUsICh2YWx1ZSA9IHZhbHVlLmdldCgpKSk7XG5cbiAgICB2YWx1ZXNba2V5XSA9IHZhbHVlO1xuICB9XG5cbiAgaWYgKGlzTm90UmVjdXJzaXZlKSBFWFBPUlQgPSB1bmRlZmluZWQ7XG5cbiAgcmV0dXJuIE9iamVjdC5mcmVlemUodmFsdWVzKTtcbn1cblxudHlwZSBQcm94eTxUID0gYW55PiA9IChrZXk6IHN0cmluZyB8IG51bWJlciwgdmFsdWU6IFQpID0+IFQ7XG5cbmNvbnN0IE9CU0VSVkVSID0gbmV3IFdlYWtNYXA8U3RhdGUsIFByb3h5PigpO1xuXG5mdW5jdGlvbiBmb2xsb3coZnJvbTogU3RhdGUsIGtleTogc3RyaW5nIHwgbnVtYmVyLCB2YWx1ZT86IGFueSkge1xuICBjb25zdCBvYnNlcnZlID0gT0JTRVJWRVIuZ2V0KGZyb20pO1xuICByZXR1cm4gb2JzZXJ2ZSA/IG9ic2VydmUoa2V5LCB2YWx1ZSkgOiB2YWx1ZTtcbn1cblxuZnVuY3Rpb24gYWNjZXNzKHN1YmplY3Q6IFN0YXRlLCBwcm9wZXJ0eTogc3RyaW5nLCByZXF1aXJlZD86IGJvb2xlYW4pIHtcbiAgY29uc3Qgc3RhdGUgPSBTVEFURS5nZXQoc3ViamVjdCkhO1xuXG4gIGlmIChwcm9wZXJ0eSBpbiBzdGF0ZSB8fCByZXF1aXJlZCA9PT0gZmFsc2UpIHtcbiAgICBjb25zdCB2YWx1ZSA9IHN0YXRlW3Byb3BlcnR5XTtcblxuICAgIGlmICh2YWx1ZSAhPT0gdW5kZWZpbmVkIHx8ICFyZXF1aXJlZCkgcmV0dXJuIHZhbHVlO1xuICB9XG5cbiAgaWYgKE1FVEhPRFMuZ2V0KHN1YmplY3QuY29uc3RydWN0b3IpIS5oYXMocHJvcGVydHkpKVxuICAgIHJldHVybiBNRVRIT0QuZ2V0KChzdWJqZWN0IGFzIGFueSlbcHJvcGVydHldKTtcblxuICBjb25zdCBlcnJvciA9IG5ldyBFcnJvcihgJHtzdWJqZWN0fS4ke3Byb3BlcnR5fSBpcyBub3QgeWV0IGF2YWlsYWJsZS5gKTtcbiAgY29uc3QgcHJvbWlzZSA9IG5ldyBQcm9taXNlPGFueT4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgIGFkZExpc3RlbmVyKHN1YmplY3QsIChrZXkpID0+IHtcbiAgICAgIGlmIChrZXkgPT09IHByb3BlcnR5KSB7XG4gICAgICAgIHJlc29sdmUoc3RhdGVba2V5XSk7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuXG4gICAgICBpZiAoa2V5ID09PSBudWxsKSB7XG4gICAgICAgIHJlamVjdChuZXcgRXJyb3IoYCR7c3ViamVjdH0gaXMgZGVzdHJveWVkLmApKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfSk7XG5cbiAgdGhyb3cgT2JqZWN0LmFzc2lnbihwcm9taXNlLCB7XG4gICAgdG9TdHJpbmc6ICgpID0+IFN0cmluZyhlcnJvciksXG4gICAgbmFtZTogJ1N1c3BlbnNlJyxcbiAgICBtZXNzYWdlOiBlcnJvci5tZXNzYWdlLFxuICAgIHN0YWNrOiBlcnJvci5zdGFja1xuICB9KTtcbn1cblxuZnVuY3Rpb24gdXBkYXRlPFQ+KFxuICBzdWJqZWN0OiBTdGF0ZSxcbiAga2V5OiBzdHJpbmcgfCBudW1iZXIgfCBzeW1ib2wsXG4gIHZhbHVlOiBULFxuICBhcmc/OiBib29sZWFuIHwgU3RhdGUuU2V0dGVyPFQ+XG4pIHtcbiAgY29uc3Qgc3RhdGUgPSBTVEFURS5nZXQoc3ViamVjdCkhO1xuXG4gIGlmIChPYmplY3QuaXNGcm96ZW4oc3RhdGUpKVxuICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgIGBUcmllZCB0byB1cGRhdGUgJHtzdWJqZWN0fS4ke1N0cmluZyhrZXkpfSBidXQgc3RhdGUgaXMgZGVzdHJveWVkLmBcbiAgICApO1xuXG4gIGNvbnN0IHByZXZpb3VzID0gc3RhdGVba2V5XSBhcyBUO1xuXG4gIGlmICh0eXBlb2YgYXJnID09ICdmdW5jdGlvbicpIHtcbiAgICBjb25zdCBvdXQgPSBhcmcuY2FsbChzdWJqZWN0LCB2YWx1ZSwgcHJldmlvdXMpO1xuXG4gICAgaWYgKG91dCA9PT0gZmFsc2UpIHJldHVybiBmYWxzZTtcblxuICAgIGlmICh0eXBlb2Ygb3V0ID09ICdmdW5jdGlvbicpIHZhbHVlID0gb3V0KCk7XG4gIH1cblxuICBpZiAodmFsdWUgPT09IHByZXZpb3VzICYmIGtleSBpbiBzdGF0ZSkgcmV0dXJuO1xuXG4gIHN0YXRlW2tleV0gPSB2YWx1ZTtcblxuICBpZiAoYXJnICE9PSB0cnVlKSBldmVudChzdWJqZWN0LCBrZXkpO1xuXG4gIHJldHVybiB0cnVlO1xufVxuXG4vKiogUmFuZG9tIGFscGhhbnVtYmVyaWMgb2YgbGVuZ3RoIDY7IGFsd2F5cyBzdGFydHMgd2l0aCBhIGxldHRlci4gKi9cbmZ1bmN0aW9uIHVpZCgpIHtcbiAgcmV0dXJuICgwLjI3OCArIE1hdGgucmFuZG9tKCkgKiAwLjcyMilcbiAgICAudG9TdHJpbmcoMzYpXG4gICAgLnN1YnN0cmluZygyLCA4KVxuICAgIC50b1VwcGVyQ2FzZSgpO1xufVxuXG5leHBvcnQgeyBldmVudCwgTUVUSE9ELCBTdGF0ZSwgUEFSRU5ULCBTVEFURSwgdWlkLCBhY2Nlc3MsIHVwZGF0ZSwgZm9sbG93IH07XG4iXSwibWFwcGluZ3MiOiI7OztBQVNBLE1BQU0sU0FBUyxPQUFPOztBQUd0QixNQUFNLHFCQUFLLElBQUksU0FBd0I7O0FBR3ZDLE1BQU0sd0JBQVEsSUFBSSxTQUEyRDs7QUFHN0UsTUFBTSx5QkFBUyxJQUFJLFNBQXFDOztBQUd4RCxNQUFNLHlCQUFTLElBQUksU0FBOEI7O0FBR2pELE1BQU0sMEJBQVUsSUFBSSxTQUFzRDs7QUFHMUUsTUFBTSx5QkFBUyxJQUFJLFNBQW1COztBQUd0QyxJQUFJO0FBZ0hKLElBQWUsUUFBZixNQUEyQztDQUN6QyxZQUFZLEdBQUcsTUFBa0I7QUFDL0IsVUFBUSxLQUFLO0FBQ2IsU0FBTyxNQUFNLE1BQU0sRUFBRSxPQUFPLE1BQU0sQ0FBQztBQUNuQyxPQUFLLE1BQU0sR0FBRyxPQUFPLE1BQVks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