gerbers-renderer 0.1.3 → 0.1.4
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/core/detect.d.ts +2 -0
- package/dist/core/errors.d.ts +5 -0
- package/dist/core/list.d.ts +2 -0
- package/dist/core/types.d.ts +18 -0
- package/dist/gerbers-renderer.es.js +2461 -2054
- package/dist/gerbers-renderer.es.js.map +1 -1
- package/dist/gerbers-renderer.umd.js +26 -23
- package/dist/gerbers-renderer.umd.js.map +1 -1
- package/dist/index.d.ts +5 -1
- package/dist/io/unpackArchive.d.ts +9 -0
- package/dist/libarchive-Bt1VdZR0.js +272 -0
- package/dist/libarchive-Bt1VdZR0.js.map +1 -0
- package/dist/parse/gerber-parser.d.ts +28 -2
- package/dist/render/renderGerbers.d.ts +3 -0
- package/dist/render/renderGerbersFiles.d.ts +7 -0
- package/dist/render/renderGerbersZip.d.ts +3 -7
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
export { renderGerbersZip } from './render/renderGerbersZip';
|
|
2
|
+
export { renderGerbers } from './render/renderGerbers';
|
|
3
|
+
export { renderGerbersFiles } from './render/renderGerbersFiles';
|
|
4
|
+
export { detectGerberBundle } from './core/detect';
|
|
2
5
|
export { createBoardViewer, type BoardViewerOptions } from './viewer/BoardViewer';
|
|
3
|
-
export type { RenderResult } from './render/
|
|
6
|
+
export type { RenderResult } from './render/renderGerbersFiles';
|
|
4
7
|
export type { BoardViewer, BoardGeom, ViewerLayers } from './viewer/types';
|
|
8
|
+
export { GerberError } from './core/errors';
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
type ArchiveInit = {
|
|
2
|
+
workerUrl?: string;
|
|
3
|
+
};
|
|
4
|
+
export type UnpackResult = {
|
|
5
|
+
archiveType: "zip" | "rar";
|
|
6
|
+
files: Record<string, Uint8Array>;
|
|
7
|
+
};
|
|
8
|
+
export declare function unpackGerberArchive(input: ArrayBuffer | Uint8Array, init?: ArchiveInit): Promise<UnpackResult>;
|
|
9
|
+
export {};
|
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
const N = Symbol("Comlink.proxy"), w = Symbol("Comlink.endpoint"), B = Symbol("Comlink.releaseProxy"), o = Symbol("Comlink.finalizer"), L = Symbol("Comlink.thrown"), x = (l) => typeof l == "object" && l !== null || typeof l == "function", P = /* @__PURE__ */ new Map([["proxy", { canHandle: (l) => x(l) && l[N], serialize(l) {
|
|
2
|
+
const { port1: Z, port2: b } = new MessageChannel();
|
|
3
|
+
return z(l, Z), [b, [b]];
|
|
4
|
+
}, deserialize: (l) => (l.start(), v(l)) }], ["throw", { canHandle: (l) => x(l) && L in l, serialize({ value: l }) {
|
|
5
|
+
let Z;
|
|
6
|
+
return Z = l instanceof Error ? { isError: !0, value: { message: l.message, name: l.name, stack: l.stack } } : { isError: !1, value: l }, [Z, []];
|
|
7
|
+
}, deserialize(l) {
|
|
8
|
+
throw l.isError ? Object.assign(new Error(l.value.message), l.value) : l.value;
|
|
9
|
+
} }]]);
|
|
10
|
+
function z(l, Z = globalThis, b = ["*"]) {
|
|
11
|
+
Z.addEventListener("message", (function c(m) {
|
|
12
|
+
if (!m || !m.data) return;
|
|
13
|
+
if (!(function(y, u) {
|
|
14
|
+
for (const i of y)
|
|
15
|
+
if (u === i || i === "*" || i instanceof RegExp && i.test(u)) return !0;
|
|
16
|
+
return !1;
|
|
17
|
+
})(b, m.origin)) return void console.warn(`Invalid origin '${m.origin}' for comlink proxy`);
|
|
18
|
+
const { id: d, type: G, path: X } = Object.assign({ path: [] }, m.data), V = (m.data.argumentList || []).map(p);
|
|
19
|
+
let W;
|
|
20
|
+
try {
|
|
21
|
+
const y = X.slice(0, -1).reduce(((i, K) => i[K]), l), u = X.reduce(((i, K) => i[K]), l);
|
|
22
|
+
switch (G) {
|
|
23
|
+
case "GET":
|
|
24
|
+
W = u;
|
|
25
|
+
break;
|
|
26
|
+
case "SET":
|
|
27
|
+
y[X.slice(-1)[0]] = p(m.data.value), W = !0;
|
|
28
|
+
break;
|
|
29
|
+
case "APPLY":
|
|
30
|
+
W = u.apply(y, V);
|
|
31
|
+
break;
|
|
32
|
+
case "CONSTRUCT":
|
|
33
|
+
W = J(new u(...V));
|
|
34
|
+
break;
|
|
35
|
+
case "ENDPOINT":
|
|
36
|
+
{
|
|
37
|
+
const { port1: i, port2: K } = new MessageChannel();
|
|
38
|
+
z(l, K), W = (function(a, j) {
|
|
39
|
+
return M.set(a, j), a;
|
|
40
|
+
})(i, [i]);
|
|
41
|
+
}
|
|
42
|
+
break;
|
|
43
|
+
case "RELEASE":
|
|
44
|
+
W = void 0;
|
|
45
|
+
break;
|
|
46
|
+
default:
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
} catch (y) {
|
|
50
|
+
W = { value: y, [L]: 0 };
|
|
51
|
+
}
|
|
52
|
+
Promise.resolve(W).catch(((y) => ({ value: y, [L]: 0 }))).then(((y) => {
|
|
53
|
+
const [u, i] = Y(y);
|
|
54
|
+
Z.postMessage(Object.assign(Object.assign({}, u), { id: d }), i), G === "RELEASE" && (Z.removeEventListener("message", c), C(Z), o in l && typeof l[o] == "function" && l[o]());
|
|
55
|
+
})).catch(((y) => {
|
|
56
|
+
const [u, i] = Y({ value: new TypeError("Unserializable return value"), [L]: 0 });
|
|
57
|
+
Z.postMessage(Object.assign(Object.assign({}, u), { id: d }), i);
|
|
58
|
+
}));
|
|
59
|
+
})), Z.start && Z.start();
|
|
60
|
+
}
|
|
61
|
+
function C(l) {
|
|
62
|
+
(function(Z) {
|
|
63
|
+
return Z.constructor.name === "MessagePort";
|
|
64
|
+
})(l) && l.close();
|
|
65
|
+
}
|
|
66
|
+
function v(l, Z) {
|
|
67
|
+
return n(l, [], Z);
|
|
68
|
+
}
|
|
69
|
+
function I(l) {
|
|
70
|
+
if (l) throw new Error("Proxy has been released and is not useable");
|
|
71
|
+
}
|
|
72
|
+
function g(l) {
|
|
73
|
+
return h(l, { type: "RELEASE" }).then((() => {
|
|
74
|
+
C(l);
|
|
75
|
+
}));
|
|
76
|
+
}
|
|
77
|
+
const R = /* @__PURE__ */ new WeakMap(), S = "FinalizationRegistry" in globalThis && new FinalizationRegistry(((l) => {
|
|
78
|
+
const Z = (R.get(l) || 0) - 1;
|
|
79
|
+
R.set(l, Z), Z === 0 && g(l);
|
|
80
|
+
}));
|
|
81
|
+
function n(l, Z = [], b = function() {
|
|
82
|
+
}) {
|
|
83
|
+
let c = !1;
|
|
84
|
+
const m = new Proxy(b, { get(d, G) {
|
|
85
|
+
if (I(c), G === B) return () => {
|
|
86
|
+
(function(X) {
|
|
87
|
+
S && S.unregister(X);
|
|
88
|
+
})(m), g(l), c = !0;
|
|
89
|
+
};
|
|
90
|
+
if (G === "then") {
|
|
91
|
+
if (Z.length === 0) return { then: () => m };
|
|
92
|
+
const X = h(l, { type: "GET", path: Z.map(((V) => V.toString())) }).then(p);
|
|
93
|
+
return X.then.bind(X);
|
|
94
|
+
}
|
|
95
|
+
return n(l, [...Z, G]);
|
|
96
|
+
}, set(d, G, X) {
|
|
97
|
+
I(c);
|
|
98
|
+
const [V, W] = Y(X);
|
|
99
|
+
return h(l, { type: "SET", path: [...Z, G].map(((y) => y.toString())), value: V }, W).then(p);
|
|
100
|
+
}, apply(d, G, X) {
|
|
101
|
+
I(c);
|
|
102
|
+
const V = Z[Z.length - 1];
|
|
103
|
+
if (V === w) return h(l, { type: "ENDPOINT" }).then(p);
|
|
104
|
+
if (V === "bind") return n(l, Z.slice(0, -1));
|
|
105
|
+
const [W, y] = H(X);
|
|
106
|
+
return h(l, { type: "APPLY", path: Z.map(((u) => u.toString())), argumentList: W }, y).then(p);
|
|
107
|
+
}, construct(d, G) {
|
|
108
|
+
I(c);
|
|
109
|
+
const [X, V] = H(G);
|
|
110
|
+
return h(l, { type: "CONSTRUCT", path: Z.map(((W) => W.toString())), argumentList: X }, V).then(p);
|
|
111
|
+
} });
|
|
112
|
+
return (function(d, G) {
|
|
113
|
+
const X = (R.get(G) || 0) + 1;
|
|
114
|
+
R.set(G, X), S && S.register(d, G, d);
|
|
115
|
+
})(m, l), m;
|
|
116
|
+
}
|
|
117
|
+
function H(l) {
|
|
118
|
+
const Z = l.map(Y);
|
|
119
|
+
return [Z.map(((c) => c[0])), (b = Z.map(((c) => c[1])), Array.prototype.concat.apply([], b))];
|
|
120
|
+
var b;
|
|
121
|
+
}
|
|
122
|
+
const M = /* @__PURE__ */ new WeakMap();
|
|
123
|
+
function J(l) {
|
|
124
|
+
return Object.assign(l, { [N]: !0 });
|
|
125
|
+
}
|
|
126
|
+
function Y(l) {
|
|
127
|
+
for (const [Z, b] of P) if (b.canHandle(l)) {
|
|
128
|
+
const [c, m] = b.serialize(l);
|
|
129
|
+
return [{ type: "HANDLER", name: Z, value: c }, m];
|
|
130
|
+
}
|
|
131
|
+
return [{ type: "RAW", value: l }, M.get(l) || []];
|
|
132
|
+
}
|
|
133
|
+
function p(l) {
|
|
134
|
+
switch (l.type) {
|
|
135
|
+
case "HANDLER":
|
|
136
|
+
return P.get(l.name).deserialize(l.value);
|
|
137
|
+
case "RAW":
|
|
138
|
+
return l.value;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
function h(l, Z, b) {
|
|
142
|
+
return new Promise(((c) => {
|
|
143
|
+
const m = new Array(4).fill(0).map((() => Math.floor(Math.random() * Number.MAX_SAFE_INTEGER).toString(16))).join("-");
|
|
144
|
+
l.addEventListener("message", (function d(G) {
|
|
145
|
+
G.data && G.data.id && G.data.id === m && (l.removeEventListener("message", d), c(G.data));
|
|
146
|
+
})), l.start && l.start(), l.postMessage(Object.assign({ id: m }, Z), b);
|
|
147
|
+
}));
|
|
148
|
+
}
|
|
149
|
+
class U {
|
|
150
|
+
constructor(Z, b, c, m, d) {
|
|
151
|
+
this._name = Z, this._size = b, this._path = c, this._lastModified = m, this._archiveRef = d;
|
|
152
|
+
}
|
|
153
|
+
get name() {
|
|
154
|
+
return this._name;
|
|
155
|
+
}
|
|
156
|
+
get size() {
|
|
157
|
+
return this._size;
|
|
158
|
+
}
|
|
159
|
+
get lastModified() {
|
|
160
|
+
return this._lastModified;
|
|
161
|
+
}
|
|
162
|
+
extract() {
|
|
163
|
+
return this._archiveRef.extractSingleFile(this._path);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
function t(l) {
|
|
167
|
+
if (l instanceof File || l instanceof U || l === null) return l;
|
|
168
|
+
const Z = {};
|
|
169
|
+
for (const b of Object.keys(l)) Z[b] = t(l[b]);
|
|
170
|
+
return Z;
|
|
171
|
+
}
|
|
172
|
+
function e(l, Z = "") {
|
|
173
|
+
const b = [];
|
|
174
|
+
for (const c of Object.keys(l)) l[c] instanceof File || l[c] instanceof U || l[c] === null ? b.push({ file: l[c] || c, path: Z }) : b.push(...e(l[c], `${Z}${c}/`));
|
|
175
|
+
return b;
|
|
176
|
+
}
|
|
177
|
+
function k(l, Z) {
|
|
178
|
+
const b = Z.split("/");
|
|
179
|
+
b[b.length - 1] === "" && b.pop();
|
|
180
|
+
let c = l, m = null;
|
|
181
|
+
for (const d of b) c[d] = c[d] || {}, m = c, c = c[d];
|
|
182
|
+
return [m, b[b.length - 1]];
|
|
183
|
+
}
|
|
184
|
+
class Q {
|
|
185
|
+
constructor(Z, b, c) {
|
|
186
|
+
this._content = {}, this._processed = 0, this.file = Z, this.client = b, this.worker = c;
|
|
187
|
+
}
|
|
188
|
+
open() {
|
|
189
|
+
return this._content = {}, this._processed = 0, new Promise(((Z, b) => {
|
|
190
|
+
this.client.open(this.file, J((() => {
|
|
191
|
+
Z(this);
|
|
192
|
+
})));
|
|
193
|
+
}));
|
|
194
|
+
}
|
|
195
|
+
async close() {
|
|
196
|
+
var Z;
|
|
197
|
+
(Z = this.worker) === null || Z === void 0 || Z.terminate(), this.worker = null, this.client = null, this.file = null;
|
|
198
|
+
}
|
|
199
|
+
async hasEncryptedData() {
|
|
200
|
+
return await this.client.hasEncryptedData();
|
|
201
|
+
}
|
|
202
|
+
async usePassword(Z) {
|
|
203
|
+
await this.client.usePassword(Z);
|
|
204
|
+
}
|
|
205
|
+
async setLocale(Z) {
|
|
206
|
+
await this.client.setLocale(Z);
|
|
207
|
+
}
|
|
208
|
+
async getFilesObject() {
|
|
209
|
+
return this._processed > 0 ? Promise.resolve().then((() => this._content)) : ((await this.client.listFiles()).forEach(((Z) => {
|
|
210
|
+
const [b, c] = k(this._content, Z.path);
|
|
211
|
+
Z.type === "FILE" && (b[c] = new U(Z.fileName, Z.size, Z.path, Z.lastModified, this));
|
|
212
|
+
})), this._processed = 1, t(this._content));
|
|
213
|
+
}
|
|
214
|
+
getFilesArray() {
|
|
215
|
+
return this.getFilesObject().then(((Z) => e(Z)));
|
|
216
|
+
}
|
|
217
|
+
async extractSingleFile(Z) {
|
|
218
|
+
if (this.worker === null) throw new Error("Archive already closed");
|
|
219
|
+
const b = await this.client.extractSingleFile(Z);
|
|
220
|
+
return new File([b.fileData], b.fileName, { type: "application/octet-stream", lastModified: b.lastModified / 1e6 });
|
|
221
|
+
}
|
|
222
|
+
async extractFiles(Z = void 0) {
|
|
223
|
+
var b;
|
|
224
|
+
return this._processed > 1 ? Promise.resolve().then((() => this._content)) : ((await this.client.extractFiles()).forEach(((c) => {
|
|
225
|
+
const [m, d] = k(this._content, c.path);
|
|
226
|
+
c.type === "FILE" && (m[d] = new File([c.fileData], c.fileName, { type: "application/octet-stream" }), Z !== void 0 && setTimeout(Z.bind(null, { file: m[d], path: c.path })));
|
|
227
|
+
})), this._processed = 2, (b = this.worker) === null || b === void 0 || b.terminate(), t(this._content));
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
var T, F;
|
|
231
|
+
(function(l) {
|
|
232
|
+
l.SEVEN_ZIP = "7zip", l.AR = "ar", l.ARBSD = "arbsd", l.ARGNU = "argnu", l.ARSVR4 = "arsvr4", l.BIN = "bin", l.BSDTAR = "bsdtar", l.CD9660 = "cd9660", l.CPIO = "cpio", l.GNUTAR = "gnutar", l.ISO = "iso", l.ISO9660 = "iso9660", l.MTREE = "mtree", l.MTREE_CLASSIC = "mtree-classic", l.NEWC = "newc", l.ODC = "odc", l.OLDTAR = "oldtar", l.PAX = "pax", l.PAXR = "paxr", l.POSIX = "posix", l.PWB = "pwb", l.RAW = "raw", l.RPAX = "rpax", l.SHAR = "shar", l.SHARDUMP = "shardump", l.USTAR = "ustar", l.V7TAR = "v7tar", l.V7 = "v7", l.WARC = "warc", l.XAR = "xar", l.ZIP = "zip";
|
|
233
|
+
})(T || (T = {})), (function(l) {
|
|
234
|
+
l.B64ENCODE = "b64encode", l.BZIP2 = "bzip2", l.COMPRESS = "compress", l.GRZIP = "grzip", l.GZIP = "gzip", l.LRZIP = "lrzip", l.LZ4 = "lz4", l.LZIP = "lzip", l.LZMA = "lzma", l.LZOP = "lzop", l.UUENCODE = "uuencode", l.XZ = "xz", l.ZSTD = "zstd", l.NONE = "none";
|
|
235
|
+
})(F || (F = {}));
|
|
236
|
+
class s {
|
|
237
|
+
static init(Z = null) {
|
|
238
|
+
return s._options = Z || {}, s._options;
|
|
239
|
+
}
|
|
240
|
+
static async open(Z) {
|
|
241
|
+
const b = s.getWorker(s._options), c = await s.getClient(b, s._options);
|
|
242
|
+
return await new Q(Z, c, b).open();
|
|
243
|
+
}
|
|
244
|
+
static async write({ files: Z, outputFileName: b, compression: c, format: m, passphrase: d = null }) {
|
|
245
|
+
const G = s.getWorker(s._options), X = await s.getClient(G, s._options), V = await X.writeArchive(Z, c, m, d);
|
|
246
|
+
return G.terminate(), new File([V], b, { type: "application/octet-stream" });
|
|
247
|
+
}
|
|
248
|
+
static getWorker(Z) {
|
|
249
|
+
return Z.getWorker ? Z.getWorker() : new Worker(Z.workerUrl || new URL("data:text/javascript;base64,LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE5IEdvb2dsZSBMTEMKICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjAKICovCmNvbnN0IGU9U3ltYm9sKCJDb21saW5rLnByb3h5Iikscj1TeW1ib2woIkNvbWxpbmsuZW5kcG9pbnQiKSx0PVN5bWJvbCgiQ29tbGluay5yZWxlYXNlUHJveHkiKSxuPVN5bWJvbCgiQ29tbGluay5maW5hbGl6ZXIiKSxvPVN5bWJvbCgiQ29tbGluay50aHJvd24iKSxhPWU9PiJvYmplY3QiPT10eXBlb2YgZSYmbnVsbCE9PWV8fCJmdW5jdGlvbiI9PXR5cGVvZiBlLHM9bmV3IE1hcChbWyJwcm94eSIse2NhbkhhbmRsZTpyPT5hKHIpJiZyW2VdLHNlcmlhbGl6ZShlKXtjb25zdHtwb3J0MTpyLHBvcnQyOnR9PW5ldyBNZXNzYWdlQ2hhbm5lbDtyZXR1cm4gaShlLHIpLFt0LFt0XV19LGRlc2VyaWFsaXplKGUpe3JldHVybiBlLnN0YXJ0KCksZihlLFtdLHIpO3ZhciByfX1dLFsidGhyb3ciLHtjYW5IYW5kbGU6ZT0+YShlKSYmbyBpbiBlLHNlcmlhbGl6ZSh7dmFsdWU6ZX0pe2xldCByO3JldHVybiByPWUgaW5zdGFuY2VvZiBFcnJvcj97aXNFcnJvcjohMCx2YWx1ZTp7bWVzc2FnZTplLm1lc3NhZ2UsbmFtZTplLm5hbWUsc3RhY2s6ZS5zdGFja319Ontpc0Vycm9yOiExLHZhbHVlOmV9LFtyLFtdXX0sZGVzZXJpYWxpemUoZSl7aWYoZS5pc0Vycm9yKXRocm93IE9iamVjdC5hc3NpZ24obmV3IEVycm9yKGUudmFsdWUubWVzc2FnZSksZS52YWx1ZSk7dGhyb3cgZS52YWx1ZX19XV0pO2Z1bmN0aW9uIGkocix0PWdsb2JhbFRoaXMsYT1bIioiXSl7dC5hZGRFdmVudExpc3RlbmVyKCJtZXNzYWdlIiwoZnVuY3Rpb24gcyhsKXtpZighbHx8IWwuZGF0YSlyZXR1cm47aWYoIWZ1bmN0aW9uKGUscil7Zm9yKGNvbnN0IHQgb2YgZSl7aWYocj09PXR8fCIqIj09PXQpcmV0dXJuITA7aWYodCBpbnN0YW5jZW9mIFJlZ0V4cCYmdC50ZXN0KHIpKXJldHVybiEwfXJldHVybiExfShhLGwub3JpZ2luKSlyZXR1cm4gdm9pZCBjb25zb2xlLndhcm4oYEludmFsaWQgb3JpZ2luICcke2wub3JpZ2lufScgZm9yIGNvbWxpbmsgcHJveHlgKTtjb25zdHtpZDpjLHR5cGU6ZCxwYXRoOmh9PU9iamVjdC5hc3NpZ24oe3BhdGg6W119LGwuZGF0YSksZj0obC5kYXRhLmFyZ3VtZW50TGlzdHx8W10pLm1hcCh3KTtsZXQgbTt0cnl7Y29uc3QgdD1oLnNsaWNlKDAsLTEpLnJlZHVjZSgoKGUscik9PmVbcl0pLHIpLG49aC5yZWR1Y2UoKChlLHIpPT5lW3JdKSxyKTtzd2l0Y2goZCl7Y2FzZSJHRVQiOm09bjticmVhaztjYXNlIlNFVCI6dFtoLnNsaWNlKC0xKVswXV09dyhsLmRhdGEudmFsdWUpLG09ITA7YnJlYWs7Y2FzZSJBUFBMWSI6bT1uLmFwcGx5KHQsZik7YnJlYWs7Y2FzZSJDT05TVFJVQ1QiOm09ZnVuY3Rpb24ocil7cmV0dXJuIE9iamVjdC5hc3NpZ24ocix7W2VdOiEwfSl9KG5ldyBuKC4uLmYpKTticmVhaztjYXNlIkVORFBPSU5UIjp7Y29uc3R7cG9ydDE6ZSxwb3J0Mjp0fT1uZXcgTWVzc2FnZUNoYW5uZWw7aShyLHQpLG09ZnVuY3Rpb24oZSxyKXtyZXR1cm4gcC5zZXQoZSxyKSxlfShlLFtlXSl9YnJlYWs7Y2FzZSJSRUxFQVNFIjptPXZvaWQgMDticmVhaztkZWZhdWx0OnJldHVybn19Y2F0Y2goZSl7bT17dmFsdWU6ZSxbb106MH19UHJvbWlzZS5yZXNvbHZlKG0pLmNhdGNoKChlPT4oe3ZhbHVlOmUsW29dOjB9KSkpLnRoZW4oKGU9Pntjb25zdFtvLGFdPXYoZSk7dC5wb3N0TWVzc2FnZShPYmplY3QuYXNzaWduKE9iamVjdC5hc3NpZ24oe30sbykse2lkOmN9KSxhKSwiUkVMRUFTRSI9PT1kJiYodC5yZW1vdmVFdmVudExpc3RlbmVyKCJtZXNzYWdlIixzKSx1KHQpLG4gaW4gciYmImZ1bmN0aW9uIj09dHlwZW9mIHJbbl0mJnJbbl0oKSl9KSkuY2F0Y2goKGU9Pntjb25zdFtyLG5dPXYoe3ZhbHVlOm5ldyBUeXBlRXJyb3IoIlVuc2VyaWFsaXphYmxlIHJldHVybiB2YWx1ZSIpLFtvXTowfSk7dC5wb3N0TWVzc2FnZShPYmplY3QuYXNzaWduKE9iamVjdC5hc3NpZ24oe30scikse2lkOmN9KSxuKX0pKX0pKSx0LnN0YXJ0JiZ0LnN0YXJ0KCl9ZnVuY3Rpb24gdShlKXsoZnVuY3Rpb24oZSl7cmV0dXJuIk1lc3NhZ2VQb3J0Ij09PWUuY29uc3RydWN0b3IubmFtZX0pKGUpJiZlLmNsb3NlKCl9ZnVuY3Rpb24gbChlKXtpZihlKXRocm93IG5ldyBFcnJvcigiUHJveHkgaGFzIGJlZW4gcmVsZWFzZWQgYW5kIGlzIG5vdCB1c2VhYmxlIil9ZnVuY3Rpb24gYyhlKXtyZXR1cm4gZyhlLHt0eXBlOiJSRUxFQVNFIn0pLnRoZW4oKCgpPT57dShlKX0pKX1jb25zdCBkPW5ldyBXZWFrTWFwLGg9IkZpbmFsaXphdGlvblJlZ2lzdHJ5ImluIGdsb2JhbFRoaXMmJm5ldyBGaW5hbGl6YXRpb25SZWdpc3RyeSgoZT0+e2NvbnN0IHI9KGQuZ2V0KGUpfHwwKS0xO2Quc2V0KGUsciksMD09PXImJmMoZSl9KSk7ZnVuY3Rpb24gZihlLG49W10sbz1mdW5jdGlvbigpe30pe2xldCBhPSExO2NvbnN0IHM9bmV3IFByb3h5KG8se2dldChyLG8pe2lmKGwoYSksbz09PXQpcmV0dXJuKCk9PnshZnVuY3Rpb24oZSl7aCYmaC51bnJlZ2lzdGVyKGUpfShzKSxjKGUpLGE9ITB9O2lmKCJ0aGVuIj09PW8pe2lmKDA9PT1uLmxlbmd0aClyZXR1cm57dGhlbjooKT0+c307Y29uc3Qgcj1nKGUse3R5cGU6IkdFVCIscGF0aDpuLm1hcCgoZT0+ZS50b1N0cmluZygpKSl9KS50aGVuKHcpO3JldHVybiByLnRoZW4uYmluZChyKX1yZXR1cm4gZihlLFsuLi5uLG9dKX0sc2V0KHIsdCxvKXtsKGEpO2NvbnN0W3MsaV09dihvKTtyZXR1cm4gZyhlLHt0eXBlOiJTRVQiLHBhdGg6Wy4uLm4sdF0ubWFwKChlPT5lLnRvU3RyaW5nKCkpKSx2YWx1ZTpzfSxpKS50aGVuKHcpfSxhcHBseSh0LG8scyl7bChhKTtjb25zdCBpPW5bbi5sZW5ndGgtMV07aWYoaT09PXIpcmV0dXJuIGcoZSx7dHlwZToiRU5EUE9JTlQifSkudGhlbih3KTtpZigiYmluZCI9PT1pKXJldHVybiBmKGUsbi5zbGljZSgwLC0xKSk7Y29uc3RbdSxjXT1tKHMpO3JldHVybiBnKGUse3R5cGU6IkFQUExZIixwYXRoOm4ubWFwKChlPT5lLnRvU3RyaW5nKCkpKSxhcmd1bWVudExpc3Q6dX0sYykudGhlbih3KX0sY29uc3RydWN0KHIsdCl7bChhKTtjb25zdFtvLHNdPW0odCk7cmV0dXJuIGcoZSx7dHlwZToiQ09OU1RSVUNUIixwYXRoOm4ubWFwKChlPT5lLnRvU3RyaW5nKCkpKSxhcmd1bWVudExpc3Q6b30scykudGhlbih3KX19KTtyZXR1cm4gZnVuY3Rpb24oZSxyKXtjb25zdCB0PShkLmdldChyKXx8MCkrMTtkLnNldChyLHQpLGgmJmgucmVnaXN0ZXIoZSxyLGUpfShzLGUpLHN9ZnVuY3Rpb24gbShlKXtjb25zdCByPWUubWFwKHYpO3JldHVybltyLm1hcCgoZT0+ZVswXSkpLCh0PXIubWFwKChlPT5lWzFdKSksQXJyYXkucHJvdG90eXBlLmNvbmNhdC5hcHBseShbXSx0KSldO3ZhciB0fWNvbnN0IHA9bmV3IFdlYWtNYXA7ZnVuY3Rpb24gdihlKXtmb3IoY29uc3Rbcix0XW9mIHMpaWYodC5jYW5IYW5kbGUoZSkpe2NvbnN0W24sb109dC5zZXJpYWxpemUoZSk7cmV0dXJuW3t0eXBlOiJIQU5ETEVSIixuYW1lOnIsdmFsdWU6bn0sb119cmV0dXJuW3t0eXBlOiJSQVciLHZhbHVlOmV9LHAuZ2V0KGUpfHxbXV19ZnVuY3Rpb24gdyhlKXtzd2l0Y2goZS50eXBlKXtjYXNlIkhBTkRMRVIiOnJldHVybiBzLmdldChlLm5hbWUpLmRlc2VyaWFsaXplKGUudmFsdWUpO2Nhc2UiUkFXIjpyZXR1cm4gZS52YWx1ZX19ZnVuY3Rpb24gZyhlLHIsdCl7cmV0dXJuIG5ldyBQcm9taXNlKChuPT57Y29uc3Qgbz1uZXcgQXJyYXkoNCkuZmlsbCgwKS5tYXAoKCgpPT5NYXRoLmZsb29yKE1hdGgucmFuZG9tKCkqTnVtYmVyLk1BWF9TQUZFX0lOVEVHRVIpLnRvU3RyaW5nKDE2KSkpLmpvaW4oIi0iKTtlLmFkZEV2ZW50TGlzdGVuZXIoIm1lc3NhZ2UiLChmdW5jdGlvbiByKHQpe3QuZGF0YSYmdC5kYXRhLmlkJiZ0LmRhdGEuaWQ9PT1vJiYoZS5yZW1vdmVFdmVudExpc3RlbmVyKCJtZXNzYWdlIixyKSxuKHQuZGF0YSkpfSkpLGUuc3RhcnQmJmUuc3RhcnQoKSxlLnBvc3RNZXNzYWdlKE9iamVjdC5hc3NpZ24oe2lkOm99LHIpLHQpfSkpfWNvbnN0IF89ezMyNzY4OiJGSUxFIiwxNjM4NDoiRElSIiw0MDk2MDoiU1lNQk9MSUNfTElOSyIsNDkxNTI6IlNPQ0tFVCIsODE5MjoiQ0hBUkFDVEVSX0RFVklDRSIsMjQ1NzY6IkJMT0NLX0RFVklDRSIsNDA5NjoiTkFNRURfUElQRSJ9O2NsYXNzIHl7Y29uc3RydWN0b3IoZSl7dGhpcy5fd2FzbU1vZHVsZT1lLHRoaXMuX3J1bkNvZGU9ZS5ydW5Db2RlLHRoaXMuX2ZpbGU9bnVsbCx0aGlzLl9wYXNzcGhyYXNlPW51bGwsdGhpcy5fbG9jYWxlPSJlbl9VUy5VVEYtOCJ9YXN5bmMgb3BlbihlKXtudWxsIT09dGhpcy5fZmlsZSYmKGNvbnNvbGUud2FybigiQ2xvc2luZyBwcmV2aW91cyBmaWxlIiksdGhpcy5jbG9zZSgpKTtjb25zdCByPWF3YWl0IHRoaXMuX2xvYWRGaWxlKGUpO3RoaXMuX2ZpbGVMZW5ndGg9ci5sZW5ndGgsdGhpcy5fZmlsZVB0cj1yLnB0cn1jbG9zZSgpe3RoaXMuX3J1bkNvZGUuY2xvc2VBcmNoaXZlKHRoaXMuX2FyY2hpdmUpLHRoaXMuX3dhc21Nb2R1bGUuX2ZyZWUodGhpcy5fZmlsZVB0ciksdGhpcy5fZmlsZT1udWxsLHRoaXMuX2ZpbGVQdHI9bnVsbCx0aGlzLl9hcmNoaXZlPW51bGx9aGFzRW5jcnlwdGVkRGF0YSgpe3RoaXMuX2FyY2hpdmU9dGhpcy5fcnVuQ29kZS5vcGVuQXJjaGl2ZSh0aGlzLl9maWxlUHRyLHRoaXMuX2ZpbGVMZW5ndGgsdGhpcy5fcGFzc3BocmFzZSx0aGlzLl9sb2NhbGUpLHRoaXMuX3J1bkNvZGUuZ2V0TmV4dEVudHJ5KHRoaXMuX2FyY2hpdmUpO2NvbnN0IGU9dGhpcy5fcnVuQ29kZS5oYXNFbmNyeXB0ZWRFbnRyaWVzKHRoaXMuX2FyY2hpdmUpO3JldHVybiAwIT09ZSYmKGU+MHx8bnVsbCl9c2V0UGFzc3BocmFzZShlKXt0aGlzLl9wYXNzcGhyYXNlPWV9c2V0TG9jYWxlKGUpe3RoaXMuX2xvY2FsZT1lfSplbnRyaWVzKGU9ITEscj1udWxsKXtsZXQgdDtmb3IodGhpcy5fYXJjaGl2ZT10aGlzLl9ydW5Db2RlLm9wZW5BcmNoaXZlKHRoaXMuX2ZpbGVQdHIsdGhpcy5fZmlsZUxlbmd0aCx0aGlzLl9wYXNzcGhyYXNlLHRoaXMuX2xvY2FsZSk7dD10aGlzLl9ydW5Db2RlLmdldE5leHRFbnRyeSh0aGlzLl9hcmNoaXZlKSwwIT09dDspe2NvbnN0IG49e3NpemU6dGhpcy5fcnVuQ29kZS5nZXRFbnRyeVNpemUodCkscGF0aDp0aGlzLl9ydW5Db2RlLmdldEVudHJ5TmFtZSh0KSx0eXBlOl9bdGhpcy5fcnVuQ29kZS5nZXRFbnRyeVR5cGUodCldLGxhc3RNb2RpZmllZDp0aGlzLl9ydW5Db2RlLmdldEVudHJ5TGFzdE1vZGlmaWVkKHQpLHJlZjp0fTtpZigiRklMRSI9PT1uLnR5cGUpe2xldCBlPW4ucGF0aC5zcGxpdCgiLyIpO24uZmlsZU5hbWU9ZVtlLmxlbmd0aC0xXX1pZihlJiZyIT09bi5wYXRoKXRoaXMuX3J1bkNvZGUuc2tpcEVudHJ5KHRoaXMuX2FyY2hpdmUpO2Vsc2V7Y29uc3QgZT10aGlzLl9ydW5Db2RlLmdldEZpbGVEYXRhKHRoaXMuX2FyY2hpdmUsbi5zaXplKTtpZihlPDApdGhyb3cgbmV3IEVycm9yKHRoaXMuX3J1bkNvZGUuZ2V0RXJyb3IodGhpcy5fYXJjaGl2ZSkpO24uZmlsZURhdGE9dGhpcy5fd2FzbU1vZHVsZS5IRUFQVTguc2xpY2UoZSxlK24uc2l6ZSksdGhpcy5fd2FzbU1vZHVsZS5fZnJlZShlKX15aWVsZCBufX1hc3luYyBfbG9hZEZpbGUoZSl7Y29uc3Qgcj1hd2FpdCBlLmFycmF5QnVmZmVyKCksdD1uZXcgVWludDhBcnJheShyKSxuPXRoaXMuX3J1bkNvZGUubWFsbG9jKHQubGVuZ3RoKTtyZXR1cm4gdGhpcy5fd2FzbU1vZHVsZS5IRUFQVTguc2V0KHQsbikse3B0cjpuLGxlbmd0aDp0Lmxlbmd0aH19fWNsYXNzIEV7Y29uc3RydWN0b3IoZSl7dGhpcy5fd2FzbU1vZHVsZT1lLHRoaXMuX3J1bkNvZGU9ZS5ydW5Db2RlLHRoaXMuX3Bhc3NwaHJhc2U9bnVsbCx0aGlzLl9sb2NhbGU9ImVuX1VTLlVURi04In1hc3luYyB3cml0ZShlLHIsdCxuPW51bGwpe2xldCBvPWUucmVkdWNlKCgoZSx7ZmlsZTpyfSk9PmUrci5zaXplKzEyOCksMCkrMTI4O2NvbnN0IGE9dGhpcy5fcnVuQ29kZS5tYWxsb2Mobykscz10aGlzLl9ydW5Db2RlLm1hbGxvYyh0aGlzLl9ydW5Db2RlLnNpemVPZlNpemVUKCkpLGk9dGhpcy5fcnVuQ29kZS5zdGFydEFyY2hpdmVXcml0ZShyLHQsYSxvLHMsbik7Zm9yKGNvbnN0e2ZpbGU6cixwYXRobmFtZTp0fW9mIGUpe2NvbnN0IGU9YXdhaXQgdGhpcy5fbG9hZEZpbGUocik7dGhpcy5fcnVuQ29kZS53cml0ZUFyY2hpdmVGaWxlKGksdHx8ci5uYW1lLGUubGVuZ3RoLGUucHRyKSx0aGlzLl9ydW5Db2RlLmZyZWUoZS5wdHIpfWNvbnN0IHU9dGhpcy5fcnVuQ29kZS5maW5pc2hBcmNoaXZlV3JpdGUoaSxzKTtpZih1PDApdGhyb3cgbmV3IEVycm9yKHRoaXMuX3J1bkNvZGUuZ2V0RXJyb3IoaSkpO3JldHVybiB0aGlzLl93YXNtTW9kdWxlLkhFQVBVOC5zbGljZShhLGErdSl9YXN5bmMgX2xvYWRGaWxlKGUpe2NvbnN0IHI9YXdhaXQgZS5hcnJheUJ1ZmZlcigpLHQ9bmV3IFVpbnQ4QXJyYXkociksbj10aGlzLl9ydW5Db2RlLm1hbGxvYyh0Lmxlbmd0aCk7cmV0dXJuIHRoaXMuX3dhc21Nb2R1bGUuSEVBUFU4LnNldCh0LG4pLHtwdHI6bixsZW5ndGg6dC5sZW5ndGh9fX12YXIgYixrPShiPWltcG9ydC5tZXRhLnVybCxhc3luYyBmdW5jdGlvbihlPXt9KXt2YXIgcix0LG49ZTtuLnJlYWR5PW5ldyBQcm9taXNlKCgoZSxuKT0+e3I9ZSx0PW59KSk7dmFyIG8sYSxzLGk9T2JqZWN0LmFzc2lnbih7fSxuKSx1PSIuL3RoaXMucHJvZ3JhbSIsbD0oZSxyKT0+e3Rocm93IHJ9LGM9Im9iamVjdCI9PXR5cGVvZiB3aW5kb3csZD0iZnVuY3Rpb24iPT10eXBlb2YgaW1wb3J0U2NyaXB0cyxoPSJvYmplY3QiPT10eXBlb2YgcHJvY2VzcyYmIm9iamVjdCI9PXR5cGVvZiBwcm9jZXNzLnZlcnNpb25zJiYic3RyaW5nIj09dHlwZW9mIHByb2Nlc3MudmVyc2lvbnMubm9kZSxmPSIiO2lmKGgpe2NvbnN0e2NyZWF0ZVJlcXVpcmU6ZX09YXdhaXQgaW1wb3J0KCJtb2R1bGUiKTt2YXIgbT1lKGltcG9ydC5tZXRhLnVybCkscD1tKCJmcyIpLHY9bSgicGF0aCIpO2Y9ZD92LmRpcm5hbWUoZikrIi8iOm0oInVybCIpLmZpbGVVUkxUb1BhdGgobmV3IFVSTCgiLi8iLGltcG9ydC5tZXRhLnVybCkpLG89KGUscik9PihlPVkoZSk/bmV3IFVSTChlKTp2Lm5vcm1hbGl6ZShlKSxwLnJlYWRGaWxlU3luYyhlLHI/dm9pZCAwOiJ1dGY4IikpLHM9ZT0+e3ZhciByPW8oZSwhMCk7cmV0dXJuIHIuYnVmZmVyfHwocj1uZXcgVWludDhBcnJheShyKSkscn0sYT0oZSxyLHQsbj0hMCk9PntlPVkoZSk/bmV3IFVSTChlKTp2Lm5vcm1hbGl6ZShlKSxwLnJlYWRGaWxlKGUsbj92b2lkIDA6InV0ZjgiLCgoZSxvKT0+e2U/dChlKTpyKG4/by5idWZmZXI6byl9KSl9LCFuLnRoaXNQcm9ncmFtJiZwcm9jZXNzLmFyZ3YubGVuZ3RoPjEmJih1PXByb2Nlc3MuYXJndlsxXS5yZXBsYWNlKC9cXC9nLCIvIikpLHByb2Nlc3MuYXJndi5zbGljZSgyKSxsPShlLHIpPT57dGhyb3cgcHJvY2Vzcy5leGl0Q29kZT1lLHJ9LG4uaW5zcGVjdD0oKT0+IltFbXNjcmlwdGVuIE1vZHVsZSBvYmplY3RdIn1lbHNlKGN8fGQpJiYoZD9mPXNlbGYubG9jYXRpb24uaHJlZjoidW5kZWZpbmVkIiE9dHlwZW9mIGRvY3VtZW50JiZkb2N1bWVudC5jdXJyZW50U2NyaXB0JiYoZj1kb2N1bWVudC5jdXJyZW50U2NyaXB0LnNyYyksYiYmKGY9YiksZj0wIT09Zi5pbmRleE9mKCJibG9iOiIpP2Yuc3Vic3RyKDAsZi5yZXBsYWNlKC9bPyNdLiovLCIiKS5sYXN0SW5kZXhPZigiLyIpKzEpOiIiLG89ZT0+e3ZhciByPW5ldyBYTUxIdHRwUmVxdWVzdDtyZXR1cm4gci5vcGVuKCJHRVQiLGUsITEpLHIuc2VuZChudWxsKSxyLnJlc3BvbnNlVGV4dH0sZCYmKHM9ZT0+e3ZhciByPW5ldyBYTUxIdHRwUmVxdWVzdDtyZXR1cm4gci5vcGVuKCJHRVQiLGUsITEpLHIucmVzcG9uc2VUeXBlPSJhcnJheWJ1ZmZlciIsci5zZW5kKG51bGwpLG5ldyBVaW50OEFycmF5KHIucmVzcG9uc2UpfSksYT0oZSxyLHQpPT57dmFyIG49bmV3IFhNTEh0dHBSZXF1ZXN0O24ub3BlbigiR0VUIixlLCEwKSxuLnJlc3BvbnNlVHlwZT0iYXJyYXlidWZmZXIiLG4ub25sb2FkPSgpPT57MjAwPT1uLnN0YXR1c3x8MD09bi5zdGF0dXMmJm4ucmVzcG9uc2U/cihuLnJlc3BvbnNlKTp0KCl9LG4ub25lcnJvcj10LG4uc2VuZChudWxsKX0pO3ZhciB3LGcsXz1uLnByaW50fHxjb25zb2xlLmxvZy5iaW5kKGNvbnNvbGUpLHk9bi5wcmludEVycnx8Y29uc29sZS5lcnJvci5iaW5kKGNvbnNvbGUpO09iamVjdC5hc3NpZ24obixpKSxpPW51bGwsbi5hcmd1bWVudHMmJm4uYXJndW1lbnRzLG4udGhpc1Byb2dyYW0mJih1PW4udGhpc1Byb2dyYW0pLG4ucXVpdCYmKGw9bi5xdWl0KSxuLndhc21CaW5hcnkmJih3PW4ud2FzbUJpbmFyeSksIm9iamVjdCIhPXR5cGVvZiBXZWJBc3NlbWJseSYmTygibm8gbmF0aXZlIHdhc20gc3VwcG9ydCBkZXRlY3RlZCIpO3ZhciBFLGssUyxGLEQsTT0hMTtmdW5jdGlvbiBBKGUscil7ZXx8TyhyKX1mdW5jdGlvbiBDKCl7dmFyIGU9Zy5idWZmZXI7bi5IRUFQOD1FPW5ldyBJbnQ4QXJyYXkoZSksbi5IRUFQMTY9Uz1uZXcgSW50MTZBcnJheShlKSxuLkhFQVBVOD1rPW5ldyBVaW50OEFycmF5KGUpLG4uSEVBUFUxNj1uZXcgVWludDE2QXJyYXkoZSksbi5IRUFQMzI9Rj1uZXcgSW50MzJBcnJheShlKSxuLkhFQVBVMzI9RD1uZXcgVWludDMyQXJyYXkoZSksbi5IRUFQRjMyPW5ldyBGbG9hdDMyQXJyYXkoZSksbi5IRUFQRjY0PW5ldyBGbG9hdDY0QXJyYXkoZSl9dmFyIFA9W10sVD1bXSxSPVtdLHo9MCxVPW51bGw7ZnVuY3Rpb24gTChlKXt6Kyssbi5tb25pdG9yUnVuRGVwZW5kZW5jaWVzPy4oeil9ZnVuY3Rpb24geChlKXtpZih6LS0sbi5tb25pdG9yUnVuRGVwZW5kZW5jaWVzPy4oeiksMD09eiYmVSl7dmFyIHI9VTtVPW51bGwscigpfX1mdW5jdGlvbiBPKGUpe24ub25BYm9ydD8uKGUpLHkoZT0iQWJvcnRlZCgiK2UrIikiKSxNPSEwLGUrPSIuIEJ1aWxkIHdpdGggLXNBU1NFUlRJT05TIGZvciBtb3JlIGluZm8uIjt2YXIgcj1uZXcgV2ViQXNzZW1ibHkuUnVudGltZUVycm9yKGUpO3Rocm93IHQocikscn12YXIgTixCLGosSSxIPWU9PmUuc3RhcnRzV2l0aCgiZGF0YTphcHBsaWNhdGlvbi9vY3RldC1zdHJlYW07YmFzZTY0LCIpLFk9ZT0+ZS5zdGFydHNXaXRoKCJmaWxlOi8vIik7ZnVuY3Rpb24gVyhlKXtpZihlPT1OJiZ3KXJldHVybiBuZXcgVWludDhBcnJheSh3KTtpZihzKXJldHVybiBzKGUpO3Rocm93ImJvdGggYXN5bmMgYW5kIHN5bmMgZmV0Y2hpbmcgb2YgdGhlIHdhc20gZmFpbGVkIn1mdW5jdGlvbiBLKGUscix0KXtyZXR1cm4gZnVuY3Rpb24oZSl7aWYoIXcmJihjfHxkKSl7aWYoImZ1bmN0aW9uIj09dHlwZW9mIGZldGNoJiYhWShlKSlyZXR1cm4gZmV0Y2goZSx7Y3JlZGVudGlhbHM6InNhbWUtb3JpZ2luIn0pLnRoZW4oKHI9PntpZighci5vayl0aHJvdyJmYWlsZWQgdG8gbG9hZCB3YXNtIGJpbmFyeSBmaWxlIGF0ICciK2UrIiciO3JldHVybiByLmFycmF5QnVmZmVyKCl9KSkuY2F0Y2goKCgpPT5XKGUpKSk7aWYoYSlyZXR1cm4gbmV3IFByb21pc2UoKChyLHQpPT57YShlLChlPT5yKG5ldyBVaW50OEFycmF5KGUpKSksdCl9KSl9cmV0dXJuIFByb21pc2UucmVzb2x2ZSgpLnRoZW4oKCgpPT5XKGUpKSl9KGUpLnRoZW4oKGU9PldlYkFzc2VtYmx5Lmluc3RhbnRpYXRlKGUscikpKS50aGVuKChlPT5lKSkudGhlbih0LChlPT57eShgZmFpbGVkIHRvIGFzeW5jaHJvbm91c2x5IHByZXBhcmUgd2FzbTogJHtlfWApLE8oZSl9KSl9ZnVuY3Rpb24gcShlKXt0aGlzLm5hbWU9IkV4aXRTdGF0dXMiLHRoaXMubWVzc2FnZT1gUHJvZ3JhbSB0ZXJtaW5hdGVkIHdpdGggZXhpdCgke2V9KWAsdGhpcy5zdGF0dXM9ZX1uLmxvY2F0ZUZpbGU/SChOPSJsaWJhcmNoaXZlLndhc20iKXx8KEI9TixOPW4ubG9jYXRlRmlsZT9uLmxvY2F0ZUZpbGUoQixmKTpmK0IpOk49bmV3IFVSTCgibGliYXJjaGl2ZS53YXNtIixpbXBvcnQubWV0YS51cmwpLmhyZWY7dmFyICQ9ZT0+e2Zvcig7ZS5sZW5ndGg+MDspZS5zaGlmdCgpKG4pfSxYPW4ubm9FeGl0UnVudGltZXx8ITAsWj17aXNBYnM6ZT0+Ii8iPT09ZS5jaGFyQXQoMCksc3BsaXRQYXRoOmU9Pi9eKFwvP3wpKFtcc1xTXSo/KSgoPzpcLnsxLDJ9fFteXC9dKz98KShcLlteLlwvXSp8KSkoPzpbXC9dKikkLy5leGVjKGUpLnNsaWNlKDEpLG5vcm1hbGl6ZUFycmF5OihlLHIpPT57Zm9yKHZhciB0PTAsbj1lLmxlbmd0aC0xO24+PTA7bi0tKXt2YXIgbz1lW25dOyIuIj09PW8/ZS5zcGxpY2UobiwxKToiLi4iPT09bz8oZS5zcGxpY2UobiwxKSx0KyspOnQmJihlLnNwbGljZShuLDEpLHQtLSl9aWYocilmb3IoO3Q7dC0tKWUudW5zaGlmdCgiLi4iKTtyZXR1cm4gZX0sbm9ybWFsaXplOmU9Pnt2YXIgcj1aLmlzQWJzKGUpLHQ9Ii8iPT09ZS5zdWJzdHIoLTEpO3JldHVybihlPVoubm9ybWFsaXplQXJyYXkoZS5zcGxpdCgiLyIpLmZpbHRlcigoZT0+ISFlKSksIXIpLmpvaW4oIi8iKSl8fHJ8fChlPSIuIiksZSYmdCYmKGUrPSIvIiksKHI/Ii8iOiIiKStlfSxkaXJuYW1lOmU9Pnt2YXIgcj1aLnNwbGl0UGF0aChlKSx0PXJbMF0sbj1yWzFdO3JldHVybiB0fHxuPyhuJiYobj1uLnN1YnN0cigwLG4ubGVuZ3RoLTEpKSx0K24pOiIuIn0sYmFzZW5hbWU6ZT0+e2lmKCIvIj09PWUpcmV0dXJuIi8iO3ZhciByPShlPShlPVoubm9ybWFsaXplKGUpKS5yZXBsYWNlKC9cLyQvLCIiKSkubGFzdEluZGV4T2YoIi8iKTtyZXR1cm4tMT09PXI/ZTplLnN1YnN0cihyKzEpfSxqb2luOmZ1bmN0aW9uKCl7dmFyIGU9QXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzKTtyZXR1cm4gWi5ub3JtYWxpemUoZS5qb2luKCIvIikpfSxqb2luMjooZSxyKT0+Wi5ub3JtYWxpemUoZSsiLyIrcil9LEc9ZT0+KEc9KCgpPT57aWYoIm9iamVjdCI9PXR5cGVvZiBjcnlwdG8mJiJmdW5jdGlvbiI9PXR5cGVvZiBjcnlwdG8uZ2V0UmFuZG9tVmFsdWVzKXJldHVybiBlPT5jcnlwdG8uZ2V0UmFuZG9tVmFsdWVzKGUpO2lmKGgpdHJ5e3ZhciBlPW0oImNyeXB0byIpO2lmKGUucmFuZG9tRmlsbFN5bmMpcmV0dXJuIHI9PmUucmFuZG9tRmlsbFN5bmMocik7dmFyIHI9ZS5yYW5kb21CeXRlcztyZXR1cm4gZT0+KGUuc2V0KHIoZS5ieXRlTGVuZ3RoKSksZSl9Y2F0Y2goZSl7fU8oImluaXRSYW5kb21EZXZpY2UiKX0pKCkpKGUpLFY9e3Jlc29sdmU6ZnVuY3Rpb24oKXtmb3IodmFyIGU9IiIscj0hMSx0PWFyZ3VtZW50cy5sZW5ndGgtMTt0Pj0tMSYmIXI7dC0tKXt2YXIgbj10Pj0wP2FyZ3VtZW50c1t0XTpsZS5jd2QoKTtpZigic3RyaW5nIiE9dHlwZW9mIG4pdGhyb3cgbmV3IFR5cGVFcnJvcigiQXJndW1lbnRzIHRvIHBhdGgucmVzb2x2ZSBtdXN0IGJlIHN0cmluZ3MiKTtpZighbilyZXR1cm4iIjtlPW4rIi8iK2Uscj1aLmlzQWJzKG4pfXJldHVybihyPyIvIjoiIikrKGU9Wi5ub3JtYWxpemVBcnJheShlLnNwbGl0KCIvIikuZmlsdGVyKChlPT4hIWUpKSwhcikuam9pbigiLyIpKXx8Ii4ifSxyZWxhdGl2ZTooZSxyKT0+e2Z1bmN0aW9uIHQoZSl7Zm9yKHZhciByPTA7cjxlLmxlbmd0aCYmIiI9PT1lW3JdO3IrKyk7Zm9yKHZhciB0PWUubGVuZ3RoLTE7dD49MCYmIiI9PT1lW3RdO3QtLSk7cmV0dXJuIHI+dD9bXTplLnNsaWNlKHIsdC1yKzEpfWU9Vi5yZXNvbHZlKGUpLnN1YnN0cigxKSxyPVYucmVzb2x2ZShyKS5zdWJzdHIoMSk7Zm9yKHZhciBuPXQoZS5zcGxpdCgiLyIpKSxvPXQoci5zcGxpdCgiLyIpKSxhPU1hdGgubWluKG4ubGVuZ3RoLG8ubGVuZ3RoKSxzPWEsaT0wO2k8YTtpKyspaWYobltpXSE9PW9baV0pe3M9aTticmVha312YXIgdT1bXTtmb3IoaT1zO2k8bi5sZW5ndGg7aSsrKXUucHVzaCgiLi4iKTtyZXR1cm4odT11LmNvbmNhdChvLnNsaWNlKHMpKSkuam9pbigiLyIpfX0sSj0idW5kZWZpbmVkIiE9dHlwZW9mIFRleHREZWNvZGVyP25ldyBUZXh0RGVjb2RlcigidXRmOCIpOnZvaWQgMCxRPShlLHIsdCk9Pntmb3IodmFyIG49cit0LG89cjtlW29dJiYhKG8+PW4pOykrK287aWYoby1yPjE2JiZlLmJ1ZmZlciYmSilyZXR1cm4gSi5kZWNvZGUoZS5zdWJhcnJheShyLG8pKTtmb3IodmFyIGE9IiI7cjxvOyl7dmFyIHM9ZVtyKytdO2lmKDEyOCZzKXt2YXIgaT02MyZlW3IrK107aWYoMTkyIT0oMjI0JnMpKXt2YXIgdT02MyZlW3IrK107aWYoKHM9MjI0PT0oMjQwJnMpPygxNSZzKTw8MTJ8aTw8Nnx1Oig3JnMpPDwxOHxpPDwxMnx1PDw2fDYzJmVbcisrXSk8NjU1MzYpYSs9U3RyaW5nLmZyb21DaGFyQ29kZShzKTtlbHNle3ZhciBsPXMtNjU1MzY7YSs9U3RyaW5nLmZyb21DaGFyQ29kZSg1NTI5NnxsPj4xMCw1NjMyMHwxMDIzJmwpfX1lbHNlIGErPVN0cmluZy5mcm9tQ2hhckNvZGUoKDMxJnMpPDw2fGkpfWVsc2UgYSs9U3RyaW5nLmZyb21DaGFyQ29kZShzKX1yZXR1cm4gYX0sZWU9W10scmU9ZT0+e2Zvcih2YXIgcj0wLHQ9MDt0PGUubGVuZ3RoOysrdCl7dmFyIG49ZS5jaGFyQ29kZUF0KHQpO248PTEyNz9yKys6bjw9MjA0Nz9yKz0yOm4+PTU1Mjk2JiZuPD01NzM0Mz8ocis9NCwrK3QpOnIrPTN9cmV0dXJuIHJ9LHRlPShlLHIsdCxuKT0+e2lmKCEobj4wKSlyZXR1cm4gMDtmb3IodmFyIG89dCxhPXQrbi0xLHM9MDtzPGUubGVuZ3RoOysrcyl7dmFyIGk9ZS5jaGFyQ29kZUF0KHMpO2lmKGk+PTU1Mjk2JiZpPD01NzM0MyYmKGk9NjU1MzYrKCgxMDIzJmkpPDwxMCl8MTAyMyZlLmNoYXJDb2RlQXQoKytzKSksaTw9MTI3KXtpZih0Pj1hKWJyZWFrO3JbdCsrXT1pfWVsc2UgaWYoaTw9MjA0Nyl7aWYodCsxPj1hKWJyZWFrO3JbdCsrXT0xOTJ8aT4+NixyW3QrK109MTI4fDYzJml9ZWxzZSBpZihpPD02NTUzNSl7aWYodCsyPj1hKWJyZWFrO3JbdCsrXT0yMjR8aT4+MTIsclt0KytdPTEyOHxpPj42JjYzLHJbdCsrXT0xMjh8NjMmaX1lbHNle2lmKHQrMz49YSlicmVhaztyW3QrK109MjQwfGk+PjE4LHJbdCsrXT0xMjh8aT4+MTImNjMsclt0KytdPTEyOHxpPj42JjYzLHJbdCsrXT0xMjh8NjMmaX19cmV0dXJuIHJbdF09MCx0LW99O2Z1bmN0aW9uIG5lKGUscix0KXt2YXIgbj10PjA/dDpyZShlKSsxLG89bmV3IEFycmF5KG4pLGE9dGUoZSxvLDAsby5sZW5ndGgpO3JldHVybiByJiYoby5sZW5ndGg9YSksb312YXIgb2U9e3R0eXM6W10saW5pdCgpe30sc2h1dGRvd24oKXt9LHJlZ2lzdGVyKGUscil7b2UudHR5c1tlXT17aW5wdXQ6W10sb3V0cHV0OltdLG9wczpyfSxsZS5yZWdpc3RlckRldmljZShlLG9lLnN0cmVhbV9vcHMpfSxzdHJlYW1fb3BzOntvcGVuKGUpe3ZhciByPW9lLnR0eXNbZS5ub2RlLnJkZXZdO2lmKCFyKXRocm93IG5ldyBsZS5FcnJub0Vycm9yKDQzKTtlLnR0eT1yLGUuc2Vla2FibGU9ITF9LGNsb3NlKGUpe2UudHR5Lm9wcy5mc3luYyhlLnR0eSl9LGZzeW5jKGUpe2UudHR5Lm9wcy5mc3luYyhlLnR0eSl9LHJlYWQoZSxyLHQsbixvKXtpZighZS50dHl8fCFlLnR0eS5vcHMuZ2V0X2NoYXIpdGhyb3cgbmV3IGxlLkVycm5vRXJyb3IoNjApO2Zvcih2YXIgYT0wLHM9MDtzPG47cysrKXt2YXIgaTt0cnl7aT1lLnR0eS5vcHMuZ2V0X2NoYXIoZS50dHkpfWNhdGNoKGUpe3Rocm93IG5ldyBsZS5FcnJub0Vycm9yKDI5KX1pZih2b2lkIDA9PT1pJiYwPT09YSl0aHJvdyBuZXcgbGUuRXJybm9FcnJvcig2KTtpZihudWxsPT1pKWJyZWFrO2ErKyxyW3Qrc109aX1yZXR1cm4gYSYmKGUubm9kZS50aW1lc3RhbXA9RGF0ZS5ub3coKSksYX0sd3JpdGUoZSxyLHQsbixvKXtpZighZS50dHl8fCFlLnR0eS5vcHMucHV0X2NoYXIpdGhyb3cgbmV3IGxlLkVycm5vRXJyb3IoNjApO3RyeXtmb3IodmFyIGE9MDthPG47YSsrKWUudHR5Lm9wcy5wdXRfY2hhcihlLnR0eSxyW3QrYV0pfWNhdGNoKGUpe3Rocm93IG5ldyBsZS5FcnJub0Vycm9yKDI5KX1yZXR1cm4gbiYmKGUubm9kZS50aW1lc3RhbXA9RGF0ZS5ub3coKSksYX19LGRlZmF1bHRfdHR5X29wczp7Z2V0X2NoYXI6ZT0+KCgpPT57aWYoIWVlLmxlbmd0aCl7dmFyIGU9bnVsbDtpZihoKXt2YXIgcj1CdWZmZXIuYWxsb2MoMjU2KSx0PTAsbj1wcm9jZXNzLnN0ZGluLmZkO3RyeXt0PXAucmVhZFN5bmMobixyKX1jYXRjaChlKXtpZighZS50b1N0cmluZygpLmluY2x1ZGVzKCJFT0YiKSl0aHJvdyBlO3Q9MH1lPXQ+MD9yLnNsaWNlKDAsdCkudG9TdHJpbmcoInV0Zi04Iik6bnVsbH1lbHNlInVuZGVmaW5lZCIhPXR5cGVvZiB3aW5kb3cmJiJmdW5jdGlvbiI9PXR5cGVvZiB3aW5kb3cucHJvbXB0P251bGwhPT0oZT13aW5kb3cucHJvbXB0KCJJbnB1dDogIikpJiYoZSs9IlxuIik6ImZ1bmN0aW9uIj09dHlwZW9mIHJlYWRsaW5lJiZudWxsIT09KGU9cmVhZGxpbmUoKSkmJihlKz0iXG4iKTtpZighZSlyZXR1cm4gbnVsbDtlZT1uZShlLCEwKX1yZXR1cm4gZWUuc2hpZnQoKX0pKCkscHV0X2NoYXIoZSxyKXtudWxsPT09cnx8MTA9PT1yPyhfKFEoZS5vdXRwdXQsMCkpLGUub3V0cHV0PVtdKTowIT1yJiZlLm91dHB1dC5wdXNoKHIpfSxmc3luYyhlKXtlLm91dHB1dCYmZS5vdXRwdXQubGVuZ3RoPjAmJihfKFEoZS5vdXRwdXQsMCkpLGUub3V0cHV0PVtdKX0saW9jdGxfdGNnZXRzOmU9Pih7Y19pZmxhZzoyNTg1NixjX29mbGFnOjUsY19jZmxhZzoxOTEsY19sZmxhZzozNTM4NyxjX2NjOlszLDI4LDEyNywyMSw0LDAsMSwwLDE3LDE5LDI2LDAsMTgsMTUsMjMsMjIsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMF19KSxpb2N0bF90Y3NldHM6KGUscix0KT0+MCxpb2N0bF90aW9jZ3dpbnN6OmU9PlsyNCw4MF19LGRlZmF1bHRfdHR5MV9vcHM6e3B1dF9jaGFyKGUscil7bnVsbD09PXJ8fDEwPT09cj8oeShRKGUub3V0cHV0LDApKSxlLm91dHB1dD1bXSk6MCE9ciYmZS5vdXRwdXQucHVzaChyKX0sZnN5bmMoZSl7ZS5vdXRwdXQmJmUub3V0cHV0Lmxlbmd0aD4wJiYoeShRKGUub3V0cHV0LDApKSxlLm91dHB1dD1bXSl9fX0sYWU9ZT0+e08oKX0sc2U9e29wc190YWJsZTpudWxsLG1vdW50OmU9PnNlLmNyZWF0ZU5vZGUobnVsbCwiLyIsMTY4OTUsMCksY3JlYXRlTm9kZShlLHIsdCxuKXtpZihsZS5pc0Jsa2Rldih0KXx8bGUuaXNGSUZPKHQpKXRocm93IG5ldyBsZS5FcnJub0Vycm9yKDYzKTtzZS5vcHNfdGFibGV8fD17ZGlyOntub2RlOntnZXRhdHRyOnNlLm5vZGVfb3BzLmdldGF0dHIsc2V0YXR0cjpzZS5ub2RlX29wcy5zZXRhdHRyLGxvb2t1cDpzZS5ub2RlX29wcy5sb29rdXAsbWtub2Q6c2Uubm9kZV9vcHMubWtub2QscmVuYW1lOnNlLm5vZGVfb3BzLnJlbmFtZSx1bmxpbms6c2Uubm9kZV9vcHMudW5saW5rLHJtZGlyOnNlLm5vZGVfb3BzLnJtZGlyLHJlYWRkaXI6c2Uubm9kZV9vcHMucmVhZGRpcixzeW1saW5rOnNlLm5vZGVfb3BzLnN5bWxpbmt9LHN0cmVhbTp7bGxzZWVrOnNlLnN0cmVhbV9vcHMubGxzZWVrfX0sZmlsZTp7bm9kZTp7Z2V0YXR0cjpzZS5ub2RlX29wcy5nZXRhdHRyLHNldGF0dHI6c2Uubm9kZV9vcHMuc2V0YXR0cn0sc3RyZWFtOntsbHNlZWs6c2Uuc3RyZWFtX29wcy5sbHNlZWsscmVhZDpzZS5zdHJlYW1fb3BzLnJlYWQsd3JpdGU6c2Uuc3RyZWFtX29wcy53cml0ZSxhbGxvY2F0ZTpzZS5zdHJlYW1fb3BzLmFsbG9jYXRlLG1tYXA6c2Uuc3RyZWFtX29wcy5tbWFwLG1zeW5jOnNlLnN0cmVhbV9vcHMubXN5bmN9fSxsaW5rOntub2RlOntnZXRhdHRyOnNlLm5vZGVfb3BzLmdldGF0dHIsc2V0YXR0cjpzZS5ub2RlX29wcy5zZXRhdHRyLHJlYWRsaW5rOnNlLm5vZGVfb3BzLnJlYWRsaW5rfSxzdHJlYW06e319LGNocmRldjp7bm9kZTp7Z2V0YXR0cjpzZS5ub2RlX29wcy5nZXRhdHRyLHNldGF0dHI6c2Uubm9kZV9vcHMuc2V0YXR0cn0sc3RyZWFtOmxlLmNocmRldl9zdHJlYW1fb3BzfX07dmFyIG89bGUuY3JlYXRlTm9kZShlLHIsdCxuKTtyZXR1cm4gbGUuaXNEaXIoby5tb2RlKT8oby5ub2RlX29wcz1zZS5vcHNfdGFibGUuZGlyLm5vZGUsby5zdHJlYW1fb3BzPXNlLm9wc190YWJsZS5kaXIuc3RyZWFtLG8uY29udGVudHM9e30pOmxlLmlzRmlsZShvLm1vZGUpPyhvLm5vZGVfb3BzPXNlLm9wc190YWJsZS5maWxlLm5vZGUsby5zdHJlYW1fb3BzPXNlLm9wc190YWJsZS5maWxlLnN0cmVhbSxvLnVzZWRCeXRlcz0wLG8uY29udGVudHM9bnVsbCk6bGUuaXNMaW5rKG8ubW9kZSk/KG8ubm9kZV9vcHM9c2Uub3BzX3RhYmxlLmxpbmsubm9kZSxvLnN0cmVhbV9vcHM9c2Uub3BzX3RhYmxlLmxpbmsuc3RyZWFtKTpsZS5pc0NocmRldihvLm1vZGUpJiYoby5ub2RlX29wcz1zZS5vcHNfdGFibGUuY2hyZGV2Lm5vZGUsby5zdHJlYW1fb3BzPXNlLm9wc190YWJsZS5jaHJkZXYuc3RyZWFtKSxvLnRpbWVzdGFtcD1EYXRlLm5vdygpLGUmJihlLmNvbnRlbnRzW3JdPW8sZS50aW1lc3RhbXA9by50aW1lc3RhbXApLG99LGdldEZpbGVEYXRhQXNUeXBlZEFycmF5OmU9PmUuY29udGVudHM/ZS5jb250ZW50cy5zdWJhcnJheT9lLmNvbnRlbnRzLnN1YmFycmF5KDAsZS51c2VkQnl0ZXMpOm5ldyBVaW50OEFycmF5KGUuY29udGVudHMpOm5ldyBVaW50OEFycmF5KDApLGV4cGFuZEZpbGVTdG9yYWdlKGUscil7dmFyIHQ9ZS5jb250ZW50cz9lLmNvbnRlbnRzLmxlbmd0aDowO2lmKCEodD49cikpe3I9TWF0aC5tYXgocix0Kih0PDEwNDg1NzY/MjoxLjEyNSk+Pj4wKSwwIT10JiYocj1NYXRoLm1heChyLDI1NikpO3ZhciBuPWUuY29udGVudHM7ZS5jb250ZW50cz1uZXcgVWludDhBcnJheShyKSxlLnVzZWRCeXRlcz4wJiZlLmNvbnRlbnRzLnNldChuLnN1YmFycmF5KDAsZS51c2VkQnl0ZXMpLDApfX0scmVzaXplRmlsZVN0b3JhZ2UoZSxyKXtpZihlLnVzZWRCeXRlcyE9cilpZigwPT1yKWUuY29udGVudHM9bnVsbCxlLnVzZWRCeXRlcz0wO2Vsc2V7dmFyIHQ9ZS5jb250ZW50cztlLmNvbnRlbnRzPW5ldyBVaW50OEFycmF5KHIpLHQmJmUuY29udGVudHMuc2V0KHQuc3ViYXJyYXkoMCxNYXRoLm1pbihyLGUudXNlZEJ5dGVzKSkpLGUudXNlZEJ5dGVzPXJ9fSxub2RlX29wczp7Z2V0YXR0cihlKXt2YXIgcj17fTtyZXR1cm4gci5kZXY9bGUuaXNDaHJkZXYoZS5tb2RlKT9lLmlkOjEsci5pbm89ZS5pZCxyLm1vZGU9ZS5tb2RlLHIubmxpbms9MSxyLnVpZD0wLHIuZ2lkPTAsci5yZGV2PWUucmRldixsZS5pc0RpcihlLm1vZGUpP3Iuc2l6ZT00MDk2OmxlLmlzRmlsZShlLm1vZGUpP3Iuc2l6ZT1lLnVzZWRCeXRlczpsZS5pc0xpbmsoZS5tb2RlKT9yLnNpemU9ZS5saW5rLmxlbmd0aDpyLnNpemU9MCxyLmF0aW1lPW5ldyBEYXRlKGUudGltZXN0YW1wKSxyLm10aW1lPW5ldyBEYXRlKGUudGltZXN0YW1wKSxyLmN0aW1lPW5ldyBEYXRlKGUudGltZXN0YW1wKSxyLmJsa3NpemU9NDA5NixyLmJsb2Nrcz1NYXRoLmNlaWwoci5zaXplL3IuYmxrc2l6ZSkscn0sc2V0YXR0cihlLHIpe3ZvaWQgMCE9PXIubW9kZSYmKGUubW9kZT1yLm1vZGUpLHZvaWQgMCE9PXIudGltZXN0YW1wJiYoZS50aW1lc3RhbXA9ci50aW1lc3RhbXApLHZvaWQgMCE9PXIuc2l6ZSYmc2UucmVzaXplRmlsZVN0b3JhZ2UoZSxyLnNpemUpfSxsb29rdXAoZSxyKXt0aHJvdyBsZS5nZW5lcmljRXJyb3JzWzQ0XX0sbWtub2Q6KGUscix0LG4pPT5zZS5jcmVhdGVOb2RlKGUscix0LG4pLHJlbmFtZShlLHIsdCl7aWYobGUuaXNEaXIoZS5tb2RlKSl7dmFyIG47dHJ5e249bGUubG9va3VwTm9kZShyLHQpfWNhdGNoKGUpe31pZihuKWZvcih2YXIgbyBpbiBuLmNvbnRlbnRzKXRocm93IG5ldyBsZS5FcnJub0Vycm9yKDU1KX1kZWxldGUgZS5wYXJlbnQuY29udGVudHNbZS5uYW1lXSxlLnBhcmVudC50aW1lc3RhbXA9RGF0ZS5ub3coKSxlLm5hbWU9dCxyLmNvbnRlbnRzW3RdPWUsci50aW1lc3RhbXA9ZS5wYXJlbnQudGltZXN0YW1wLGUucGFyZW50PXJ9LHVubGluayhlLHIpe2RlbGV0ZSBlLmNvbnRlbnRzW3JdLGUudGltZXN0YW1wPURhdGUubm93KCl9LHJtZGlyKGUscil7dmFyIHQ9bGUubG9va3VwTm9kZShlLHIpO2Zvcih2YXIgbiBpbiB0LmNvbnRlbnRzKXRocm93IG5ldyBsZS5FcnJub0Vycm9yKDU1KTtkZWxldGUgZS5jb250ZW50c1tyXSxlLnRpbWVzdGFtcD1EYXRlLm5vdygpfSxyZWFkZGlyKGUpe3ZhciByPVsiLiIsIi4uIl07Zm9yKHZhciB0IG9mIE9iamVjdC5rZXlzKGUuY29udGVudHMpKXIucHVzaCh0KTtyZXR1cm4gcn0sc3ltbGluayhlLHIsdCl7dmFyIG49c2UuY3JlYXRlTm9kZShlLHIsNDE0NzEsMCk7cmV0dXJuIG4ubGluaz10LG59LHJlYWRsaW5rKGUpe2lmKCFsZS5pc0xpbmsoZS5tb2RlKSl0aHJvdyBuZXcgbGUuRXJybm9FcnJvcigyOCk7cmV0dXJuIGUubGlua319LHN0cmVhbV9vcHM6e3JlYWQoZSxyLHQsbixvKXt2YXIgYT1lLm5vZGUuY29udGVudHM7aWYobz49ZS5ub2RlLnVzZWRCeXRlcylyZXR1cm4gMDt2YXIgcz1NYXRoLm1pbihlLm5vZGUudXNlZEJ5dGVzLW8sbik7aWYocz44JiZhLnN1YmFycmF5KXIuc2V0KGEuc3ViYXJyYXkobyxvK3MpLHQpO2Vsc2UgZm9yKHZhciBpPTA7aTxzO2krKylyW3QraV09YVtvK2ldO3JldHVybiBzfSx3cml0ZShlLHIsdCxuLG8sYSl7aWYoci5idWZmZXI9PT1FLmJ1ZmZlciYmKGE9ITEpLCFuKXJldHVybiAwO3ZhciBzPWUubm9kZTtpZihzLnRpbWVzdGFtcD1EYXRlLm5vdygpLHIuc3ViYXJyYXkmJighcy5jb250ZW50c3x8cy5jb250ZW50cy5zdWJhcnJheSkpe2lmKGEpcmV0dXJuIHMuY29udGVudHM9ci5zdWJhcnJheSh0LHQrbikscy51c2VkQnl0ZXM9bixuO2lmKDA9PT1zLnVzZWRCeXRlcyYmMD09PW8pcmV0dXJuIHMuY29udGVudHM9ci5zbGljZSh0LHQrbikscy51c2VkQnl0ZXM9bixuO2lmKG8rbjw9cy51c2VkQnl0ZXMpcmV0dXJuIHMuY29udGVudHMuc2V0KHIuc3ViYXJyYXkodCx0K24pLG8pLG59aWYoc2UuZXhwYW5kRmlsZVN0b3JhZ2UocyxvK24pLHMuY29udGVudHMuc3ViYXJyYXkmJnIuc3ViYXJyYXkpcy5jb250ZW50cy5zZXQoci5zdWJhcnJheSh0LHQrbiksbyk7ZWxzZSBmb3IodmFyIGk9MDtpPG47aSsrKXMuY29udGVudHNbbytpXT1yW3QraV07cmV0dXJuIHMudXNlZEJ5dGVzPU1hdGgubWF4KHMudXNlZEJ5dGVzLG8rbiksbn0sbGxzZWVrKGUscix0KXt2YXIgbj1yO2lmKDE9PT10P24rPWUucG9zaXRpb246Mj09PXQmJmxlLmlzRmlsZShlLm5vZGUubW9kZSkmJihuKz1lLm5vZGUudXNlZEJ5dGVzKSxuPDApdGhyb3cgbmV3IGxlLkVycm5vRXJyb3IoMjgpO3JldHVybiBufSxhbGxvY2F0ZShlLHIsdCl7c2UuZXhwYW5kRmlsZVN0b3JhZ2UoZS5ub2RlLHIrdCksZS5ub2RlLnVzZWRCeXRlcz1NYXRoLm1heChlLm5vZGUudXNlZEJ5dGVzLHIrdCl9LG1tYXAoZSxyLHQsbixvKXtpZighbGUuaXNGaWxlKGUubm9kZS5tb2RlKSl0aHJvdyBuZXcgbGUuRXJybm9FcnJvcig0Myk7dmFyIGEscyxpPWUubm9kZS5jb250ZW50cztpZigyJm98fGkuYnVmZmVyIT09RS5idWZmZXIpe2lmKCh0PjB8fHQrcjxpLmxlbmd0aCkmJihpPWkuc3ViYXJyYXk/aS5zdWJhcnJheSh0LHQrcik6QXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoaSx0LHQrcikpLHM9ITAsIShhPWFlKCkpKXRocm93IG5ldyBsZS5FcnJub0Vycm9yKDQ4KTtFLnNldChpLGEpfWVsc2Ugcz0hMSxhPWkuYnl0ZU9mZnNldDtyZXR1cm57cHRyOmEsYWxsb2NhdGVkOnN9fSxtc3luYzooZSxyLHQsbixvKT0+KHNlLnN0cmVhbV9vcHMud3JpdGUoZSxyLDAsbix0LCExKSwwKX19LGllPW4ucHJlbG9hZFBsdWdpbnN8fFtdLHVlPShlLHIpPT57dmFyIHQ9MDtyZXR1cm4gZSYmKHR8PTM2NSksciYmKHR8PTE0NiksdH0sbGU9e3Jvb3Q6bnVsbCxtb3VudHM6W10sZGV2aWNlczp7fSxzdHJlYW1zOltdLG5leHRJbm9kZToxLG5hbWVUYWJsZTpudWxsLGN1cnJlbnRQYXRoOiIvIixpbml0aWFsaXplZDohMSxpZ25vcmVQZXJtaXNzaW9uczohMCxFcnJub0Vycm9yOm51bGwsZ2VuZXJpY0Vycm9yczp7fSxmaWxlc3lzdGVtczpudWxsLHN5bmNGU1JlcXVlc3RzOjAsbG9va3VwUGF0aChlLHI9e30pe2lmKCEoZT1WLnJlc29sdmUoZSkpKXJldHVybntwYXRoOiIiLG5vZGU6bnVsbH07aWYoKHI9T2JqZWN0LmFzc2lnbih7Zm9sbG93X21vdW50OiEwLHJlY3Vyc2VfY291bnQ6MH0scikpLnJlY3Vyc2VfY291bnQ+OCl0aHJvdyBuZXcgbGUuRXJybm9FcnJvcigzMik7Zm9yKHZhciB0PWUuc3BsaXQoIi8iKS5maWx0ZXIoKGU9PiEhZSkpLG49bGUucm9vdCxvPSIvIixhPTA7YTx0Lmxlbmd0aDthKyspe3ZhciBzPWE9PT10Lmxlbmd0aC0xO2lmKHMmJnIucGFyZW50KWJyZWFrO2lmKG49bGUubG9va3VwTm9kZShuLHRbYV0pLG89Wi5qb2luMihvLHRbYV0pLGxlLmlzTW91bnRwb2ludChuKSYmKCFzfHxzJiZyLmZvbGxvd19tb3VudCkmJihuPW4ubW91bnRlZC5yb290KSwhc3x8ci5mb2xsb3cpZm9yKHZhciBpPTA7bGUuaXNMaW5rKG4ubW9kZSk7KXt2YXIgdT1sZS5yZWFkbGluayhvKTtpZihvPVYucmVzb2x2ZShaLmRpcm5hbWUobyksdSksbj1sZS5sb29rdXBQYXRoKG8se3JlY3Vyc2VfY291bnQ6ci5yZWN1cnNlX2NvdW50KzF9KS5ub2RlLGkrKz40MCl0aHJvdyBuZXcgbGUuRXJybm9FcnJvcigzMil9fXJldHVybntwYXRoOm8sbm9kZTpufX0sZ2V0UGF0aChlKXtmb3IodmFyIHI7Oyl7aWYobGUuaXNSb290KGUpKXt2YXIgdD1lLm1vdW50Lm1vdW50cG9pbnQ7cmV0dXJuIHI/Ii8iIT09dFt0Lmxlbmd0aC0xXT9gJHt0fS8ke3J9YDp0K3I6dH1yPXI/YCR7ZS5uYW1lfS8ke3J9YDplLm5hbWUsZT1lLnBhcmVudH19LGhhc2hOYW1lKGUscil7Zm9yKHZhciB0PTAsbj0wO248ci5sZW5ndGg7bisrKXQ9KHQ8PDUpLXQrci5jaGFyQ29kZUF0KG4pfDA7cmV0dXJuKGUrdD4+PjApJWxlLm5hbWVUYWJsZS5sZW5ndGh9LGhhc2hBZGROb2RlKGUpe3ZhciByPWxlLmhhc2hOYW1lKGUucGFyZW50LmlkLGUubmFtZSk7ZS5uYW1lX25leHQ9bGUubmFtZVRhYmxlW3JdLGxlLm5hbWVUYWJsZVtyXT1lfSxoYXNoUmVtb3ZlTm9kZShlKXt2YXIgcj1sZS5oYXNoTmFtZShlLnBhcmVudC5pZCxlLm5hbWUpO2lmKGxlLm5hbWVUYWJsZVtyXT09PWUpbGUubmFtZVRhYmxlW3JdPWUubmFtZV9uZXh0O2Vsc2UgZm9yKHZhciB0PWxlLm5hbWVUYWJsZVtyXTt0Oyl7aWYodC5uYW1lX25leHQ9PT1lKXt0Lm5hbWVfbmV4dD1lLm5hbWVfbmV4dDticmVha310PXQubmFtZV9uZXh0fX0sbG9va3VwTm9kZShlLHIpe3ZhciB0PWxlLm1heUxvb2t1cChlKTtpZih0KXRocm93IG5ldyBsZS5FcnJub0Vycm9yKHQsZSk7Zm9yKHZhciBuPWxlLmhhc2hOYW1lKGUuaWQsciksbz1sZS5uYW1lVGFibGVbbl07bztvPW8ubmFtZV9uZXh0KXt2YXIgYT1vLm5hbWU7aWYoby5wYXJlbnQuaWQ9PT1lLmlkJiZhPT09cilyZXR1cm4gb31yZXR1cm4gbGUubG9va3VwKGUscil9LGNyZWF0ZU5vZGUoZSxyLHQsbil7dmFyIG89bmV3IGxlLkZTTm9kZShlLHIsdCxuKTtyZXR1cm4gbGUuaGFzaEFkZE5vZGUobyksb30sZGVzdHJveU5vZGUoZSl7bGUuaGFzaFJlbW92ZU5vZGUoZSl9LGlzUm9vdDplPT5lPT09ZS5wYXJlbnQsaXNNb3VudHBvaW50OmU9PiEhZS5tb3VudGVkLGlzRmlsZTplPT4zMjc2OD09KDYxNDQwJmUpLGlzRGlyOmU9PjE2Mzg0PT0oNjE0NDAmZSksaXNMaW5rOmU9PjQwOTYwPT0oNjE0NDAmZSksaXNDaHJkZXY6ZT0+ODE5Mj09KDYxNDQwJmUpLGlzQmxrZGV2OmU9PjI0NTc2PT0oNjE0NDAmZSksaXNGSUZPOmU9PjQwOTY9PSg2MTQ0MCZlKSxpc1NvY2tldDplPT40OTE1Mj09KDQ5MTUyJmUpLGZsYWdzVG9QZXJtaXNzaW9uU3RyaW5nKGUpe3ZhciByPVsiciIsInciLCJydyJdWzMmZV07cmV0dXJuIDUxMiZlJiYocis9InciKSxyfSxub2RlUGVybWlzc2lvbnM6KGUscik9PmxlLmlnbm9yZVBlcm1pc3Npb25zfHwoIXIuaW5jbHVkZXMoInIiKXx8MjkyJmUubW9kZSkmJighci5pbmNsdWRlcygidyIpfHwxNDYmZS5tb2RlKSYmKCFyLmluY2x1ZGVzKCJ4Iil8fDczJmUubW9kZSk/MDoyLG1heUxvb2t1cChlKXt2YXIgcj1sZS5ub2RlUGVybWlzc2lvbnMoZSwieCIpO3JldHVybiByfHwoZS5ub2RlX29wcy5sb29rdXA/MDoyKX0sbWF5Q3JlYXRlKGUscil7dHJ5e3JldHVybiBsZS5sb29rdXBOb2RlKGUsciksMjB9Y2F0Y2goZSl7fXJldHVybiBsZS5ub2RlUGVybWlzc2lvbnMoZSwid3giKX0sbWF5RGVsZXRlKGUscix0KXt2YXIgbjt0cnl7bj1sZS5sb29rdXBOb2RlKGUscil9Y2F0Y2goZSl7cmV0dXJuIGUuZXJybm99dmFyIG89bGUubm9kZVBlcm1pc3Npb25zKGUsInd4Iik7aWYobylyZXR1cm4gbztpZih0KXtpZighbGUuaXNEaXIobi5tb2RlKSlyZXR1cm4gNTQ7aWYobGUuaXNSb290KG4pfHxsZS5nZXRQYXRoKG4pPT09bGUuY3dkKCkpcmV0dXJuIDEwfWVsc2UgaWYobGUuaXNEaXIobi5tb2RlKSlyZXR1cm4gMzE7cmV0dXJuIDB9LG1heU9wZW46KGUscik9PmU/bGUuaXNMaW5rKGUubW9kZSk/MzI6bGUuaXNEaXIoZS5tb2RlKSYmKCJyIiE9PWxlLmZsYWdzVG9QZXJtaXNzaW9uU3RyaW5nKHIpfHw1MTImcik/MzE6bGUubm9kZVBlcm1pc3Npb25zKGUsbGUuZmxhZ3NUb1Blcm1pc3Npb25TdHJpbmcocikpOjQ0LE1BWF9PUEVOX0ZEUzo0MDk2LG5leHRmZCgpe2Zvcih2YXIgZT0wO2U8PWxlLk1BWF9PUEVOX0ZEUztlKyspaWYoIWxlLnN0cmVhbXNbZV0pcmV0dXJuIGU7dGhyb3cgbmV3IGxlLkVycm5vRXJyb3IoMzMpfSxnZXRTdHJlYW1DaGVja2VkKGUpe3ZhciByPWxlLmdldFN0cmVhbShlKTtpZighcil0aHJvdyBuZXcgbGUuRXJybm9FcnJvcig4KTtyZXR1cm4gcn0sZ2V0U3RyZWFtOmU9PmxlLnN0cmVhbXNbZV0sY3JlYXRlU3RyZWFtOihlLHI9LTEpPT4obGUuRlNTdHJlYW18fChsZS5GU1N0cmVhbT1mdW5jdGlvbigpe3RoaXMuc2hhcmVkPXt9fSxsZS5GU1N0cmVhbS5wcm90b3R5cGU9e30sT2JqZWN0LmRlZmluZVByb3BlcnRpZXMobGUuRlNTdHJlYW0ucHJvdG90eXBlLHtvYmplY3Q6e2dldCgpe3JldHVybiB0aGlzLm5vZGV9LHNldChlKXt0aGlzLm5vZGU9ZX19LGlzUmVhZDp7Z2V0KCl7cmV0dXJuIDEhPSgyMDk3MTU1JnRoaXMuZmxhZ3MpfX0saXNXcml0ZTp7Z2V0KCl7cmV0dXJuIDAhPSgyMDk3MTU1JnRoaXMuZmxhZ3MpfX0saXNBcHBlbmQ6e2dldCgpe3JldHVybiAxMDI0JnRoaXMuZmxhZ3N9fSxmbGFnczp7Z2V0KCl7cmV0dXJuIHRoaXMuc2hhcmVkLmZsYWdzfSxzZXQoZSl7dGhpcy5zaGFyZWQuZmxhZ3M9ZX19LHBvc2l0aW9uOntnZXQoKXtyZXR1cm4gdGhpcy5zaGFyZWQucG9zaXRpb259LHNldChlKXt0aGlzLnNoYXJlZC5wb3NpdGlvbj1lfX19KSksZT1PYmplY3QuYXNzaWduKG5ldyBsZS5GU1N0cmVhbSxlKSwtMT09ciYmKHI9bGUubmV4dGZkKCkpLGUuZmQ9cixsZS5zdHJlYW1zW3JdPWUsZSksY2xvc2VTdHJlYW0oZSl7bGUuc3RyZWFtc1tlXT1udWxsfSxjaHJkZXZfc3RyZWFtX29wczp7b3BlbihlKXt2YXIgcj1sZS5nZXREZXZpY2UoZS5ub2RlLnJkZXYpO2Uuc3RyZWFtX29wcz1yLnN0cmVhbV9vcHMsZS5zdHJlYW1fb3BzLm9wZW4/LihlKX0sbGxzZWVrKCl7dGhyb3cgbmV3IGxlLkVycm5vRXJyb3IoNzApfX0sbWFqb3I6ZT0+ZT4+OCxtaW5vcjplPT4yNTUmZSxtYWtlZGV2OihlLHIpPT5lPDw4fHIscmVnaXN0ZXJEZXZpY2UoZSxyKXtsZS5kZXZpY2VzW2VdPXtzdHJlYW1fb3BzOnJ9fSxnZXREZXZpY2U6ZT0+bGUuZGV2aWNlc1tlXSxnZXRNb3VudHMoZSl7Zm9yKHZhciByPVtdLHQ9W2VdO3QubGVuZ3RoOyl7dmFyIG49dC5wb3AoKTtyLnB1c2gobiksdC5wdXNoLmFwcGx5KHQsbi5tb3VudHMpfXJldHVybiByfSxzeW5jZnMoZSxyKXsiZnVuY3Rpb24iPT10eXBlb2YgZSYmKHI9ZSxlPSExKSxsZS5zeW5jRlNSZXF1ZXN0cysrLGxlLnN5bmNGU1JlcXVlc3RzPjEmJnkoYHdhcm5pbmc6ICR7bGUuc3luY0ZTUmVxdWVzdHN9IEZTLnN5bmNmcyBvcGVyYXRpb25zIGluIGZsaWdodCBhdCBvbmNlLCBwcm9iYWJseSBqdXN0IGRvaW5nIGV4dHJhIHdvcmtgKTt2YXIgdD1sZS5nZXRNb3VudHMobGUucm9vdC5tb3VudCksbj0wO2Z1bmN0aW9uIG8oZSl7cmV0dXJuIGxlLnN5bmNGU1JlcXVlc3RzLS0scihlKX1mdW5jdGlvbiBhKGUpe2lmKGUpcmV0dXJuIGEuZXJyb3JlZD92b2lkIDA6KGEuZXJyb3JlZD0hMCxvKGUpKTsrK24+PXQubGVuZ3RoJiZvKG51bGwpfXQuZm9yRWFjaCgocj0+e2lmKCFyLnR5cGUuc3luY2ZzKXJldHVybiBhKG51bGwpO3IudHlwZS5zeW5jZnMocixlLGEpfSkpfSxtb3VudChlLHIsdCl7dmFyIG4sbz0iLyI9PT10LGE9IXQ7aWYobyYmbGUucm9vdCl0aHJvdyBuZXcgbGUuRXJybm9FcnJvcigxMCk7aWYoIW8mJiFhKXt2YXIgcz1sZS5sb29rdXBQYXRoKHQse2ZvbGxvd19tb3VudDohMX0pO2lmKHQ9cy5wYXRoLG49cy5ub2RlLGxlLmlzTW91bnRwb2ludChuKSl0aHJvdyBuZXcgbGUuRXJybm9FcnJvcigxMCk7aWYoIWxlLmlzRGlyKG4ubW9kZSkpdGhyb3cgbmV3IGxlLkVycm5vRXJyb3IoNTQpfXZhciBpPXt0eXBlOmUsb3B0czpyLG1vdW50cG9pbnQ6dCxtb3VudHM6W119LHU9ZS5tb3VudChpKTtyZXR1cm4gdS5tb3VudD1pLGkucm9vdD11LG8/bGUucm9vdD11Om4mJihuLm1vdW50ZWQ9aSxuLm1vdW50JiZuLm1vdW50Lm1vdW50cy5wdXNoKGkpKSx1fSx1bm1vdW50KGUpe3ZhciByPWxlLmxvb2t1cFBhdGgoZSx7Zm9sbG93X21vdW50OiExfSk7aWYoIWxlLmlzTW91bnRwb2ludChyLm5vZGUpKXRocm93IG5ldyBsZS5FcnJub0Vycm9yKDI4KTt2YXIgdD1yLm5vZGUsbj10Lm1vdW50ZWQsbz1sZS5nZXRNb3VudHMobik7T2JqZWN0LmtleXMobGUubmFtZVRhYmxlKS5mb3JFYWNoKChlPT57Zm9yKHZhciByPWxlLm5hbWVUYWJsZVtlXTtyOyl7dmFyIHQ9ci5uYW1lX25leHQ7by5pbmNsdWRlcyhyLm1vdW50KSYmbGUuZGVzdHJveU5vZGUocikscj10fX0pKSx0Lm1vdW50ZWQ9bnVsbDt2YXIgYT10Lm1vdW50Lm1vdW50cy5pbmRleE9mKG4pO3QubW91bnQubW91bnRzLnNwbGljZShhLDEpfSxsb29rdXA6KGUscik9PmUubm9kZV9vcHMubG9va3VwKGUsciksbWtub2QoZSxyLHQpe3ZhciBuPWxlLmxvb2t1cFBhdGgoZSx7cGFyZW50OiEwfSkubm9kZSxvPVouYmFzZW5hbWUoZSk7aWYoIW98fCIuIj09PW98fCIuLiI9PT1vKXRocm93IG5ldyBsZS5FcnJub0Vycm9yKDI4KTt2YXIgYT1sZS5tYXlDcmVhdGUobixvKTtpZihhKXRocm93IG5ldyBsZS5FcnJub0Vycm9yKGEpO2lmKCFuLm5vZGVfb3BzLm1rbm9kKXRocm93IG5ldyBsZS5FcnJub0Vycm9yKDYzKTtyZXR1cm4gbi5ub2RlX29wcy5ta25vZChuLG8scix0KX0sY3JlYXRlOihlLHIpPT4ocj12b2lkIDAhPT1yP3I6NDM4LHImPTQwOTUscnw9MzI3NjgsbGUubWtub2QoZSxyLDApKSxta2RpcjooZSxyKT0+KHI9dm9pZCAwIT09cj9yOjUxMSxyJj0xMDIzLHJ8PTE2Mzg0LGxlLm1rbm9kKGUsciwwKSksbWtkaXJUcmVlKGUscil7Zm9yKHZhciB0PWUuc3BsaXQoIi8iKSxuPSIiLG89MDtvPHQubGVuZ3RoOysrbylpZih0W29dKXtuKz0iLyIrdFtvXTt0cnl7bGUubWtkaXIobixyKX1jYXRjaChlKXtpZigyMCE9ZS5lcnJubyl0aHJvdyBlfX19LG1rZGV2OihlLHIsdCk9Pih2b2lkIDA9PT10JiYodD1yLHI9NDM4KSxyfD04MTkyLGxlLm1rbm9kKGUscix0KSksc3ltbGluayhlLHIpe2lmKCFWLnJlc29sdmUoZSkpdGhyb3cgbmV3IGxlLkVycm5vRXJyb3IoNDQpO3ZhciB0PWxlLmxvb2t1cFBhdGgocix7cGFyZW50OiEwfSkubm9kZTtpZighdCl0aHJvdyBuZXcgbGUuRXJybm9FcnJvcig0NCk7dmFyIG49Wi5iYXNlbmFtZShyKSxvPWxlLm1heUNyZWF0ZSh0LG4pO2lmKG8pdGhyb3cgbmV3IGxlLkVycm5vRXJyb3Iobyk7aWYoIXQubm9kZV9vcHMuc3ltbGluayl0aHJvdyBuZXcgbGUuRXJybm9FcnJvcig2Myk7cmV0dXJuIHQubm9kZV9vcHMuc3ltbGluayh0LG4sZSl9LHJlbmFtZShlLHIpe3ZhciB0LG4sbz1aLmRpcm5hbWUoZSksYT1aLmRpcm5hbWUocikscz1aLmJhc2VuYW1lKGUpLGk9Wi5iYXNlbmFtZShyKTtpZih0PWxlLmxvb2t1cFBhdGgoZSx7cGFyZW50OiEwfSkubm9kZSxuPWxlLmxvb2t1cFBhdGgocix7cGFyZW50OiEwfSkubm9kZSwhdHx8IW4pdGhyb3cgbmV3IGxlLkVycm5vRXJyb3IoNDQpO2lmKHQubW91bnQhPT1uLm1vdW50KXRocm93IG5ldyBsZS5FcnJub0Vycm9yKDc1KTt2YXIgdSxsPWxlLmxvb2t1cE5vZGUodCxzKSxjPVYucmVsYXRpdmUoZSxhKTtpZigiLiIhPT1jLmNoYXJBdCgwKSl0aHJvdyBuZXcgbGUuRXJybm9FcnJvcigyOCk7aWYoIi4iIT09KGM9Vi5yZWxhdGl2ZShyLG8pKS5jaGFyQXQoMCkpdGhyb3cgbmV3IGxlLkVycm5vRXJyb3IoNTUpO3RyeXt1PWxlLmxvb2t1cE5vZGUobixpKX1jYXRjaChlKXt9aWYobCE9PXUpe3ZhciBkPWxlLmlzRGlyKGwubW9kZSksaD1sZS5tYXlEZWxldGUodCxzLGQpO2lmKGgpdGhyb3cgbmV3IGxlLkVycm5vRXJyb3IoaCk7aWYoaD11P2xlLm1heURlbGV0ZShuLGksZCk6bGUubWF5Q3JlYXRlKG4saSkpdGhyb3cgbmV3IGxlLkVycm5vRXJyb3IoaCk7aWYoIXQubm9kZV9vcHMucmVuYW1lKXRocm93IG5ldyBsZS5FcnJub0Vycm9yKDYzKTtpZihsZS5pc01vdW50cG9pbnQobCl8fHUmJmxlLmlzTW91bnRwb2ludCh1KSl0aHJvdyBuZXcgbGUuRXJybm9FcnJvcigxMCk7aWYobiE9PXQmJihoPWxlLm5vZGVQZXJtaXNzaW9ucyh0LCJ3IikpKXRocm93IG5ldyBsZS5FcnJub0Vycm9yKGgpO2xlLmhhc2hSZW1vdmVOb2RlKGwpO3RyeXt0Lm5vZGVfb3BzLnJlbmFtZShsLG4saSl9Y2F0Y2goZSl7dGhyb3cgZX1maW5hbGx5e2xlLmhhc2hBZGROb2RlKGwpfX19LHJtZGlyKGUpe3ZhciByPWxlLmxvb2t1cFBhdGgoZSx7cGFyZW50OiEwfSkubm9kZSx0PVouYmFzZW5hbWUoZSksbj1sZS5sb29rdXBOb2RlKHIsdCksbz1sZS5tYXlEZWxldGUocix0LCEwKTtpZihvKXRocm93IG5ldyBsZS5FcnJub0Vycm9yKG8pO2lmKCFyLm5vZGVfb3BzLnJtZGlyKXRocm93IG5ldyBsZS5FcnJub0Vycm9yKDYzKTtpZihsZS5pc01vdW50cG9pbnQobikpdGhyb3cgbmV3IGxlLkVycm5vRXJyb3IoMTApO3Iubm9kZV9vcHMucm1kaXIocix0KSxsZS5kZXN0cm95Tm9kZShuKX0scmVhZGRpcihlKXt2YXIgcj1sZS5sb29rdXBQYXRoKGUse2ZvbGxvdzohMH0pLm5vZGU7aWYoIXIubm9kZV9vcHMucmVhZGRpcil0aHJvdyBuZXcgbGUuRXJybm9FcnJvcig1NCk7cmV0dXJuIHIubm9kZV9vcHMucmVhZGRpcihyKX0sdW5saW5rKGUpe3ZhciByPWxlLmxvb2t1cFBhdGgoZSx7cGFyZW50OiEwfSkubm9kZTtpZighcil0aHJvdyBuZXcgbGUuRXJybm9FcnJvcig0NCk7dmFyIHQ9Wi5iYXNlbmFtZShlKSxuPWxlLmxvb2t1cE5vZGUocix0KSxvPWxlLm1heURlbGV0ZShyLHQsITEpO2lmKG8pdGhyb3cgbmV3IGxlLkVycm5vRXJyb3Iobyk7aWYoIXIubm9kZV9vcHMudW5saW5rKXRocm93IG5ldyBsZS5FcnJub0Vycm9yKDYzKTtpZihsZS5pc01vdW50cG9pbnQobikpdGhyb3cgbmV3IGxlLkVycm5vRXJyb3IoMTApO3Iubm9kZV9vcHMudW5saW5rKHIsdCksbGUuZGVzdHJveU5vZGUobil9LHJlYWRsaW5rKGUpe3ZhciByPWxlLmxvb2t1cFBhdGgoZSkubm9kZTtpZighcil0aHJvdyBuZXcgbGUuRXJybm9FcnJvcig0NCk7aWYoIXIubm9kZV9vcHMucmVhZGxpbmspdGhyb3cgbmV3IGxlLkVycm5vRXJyb3IoMjgpO3JldHVybiBWLnJlc29sdmUobGUuZ2V0UGF0aChyLnBhcmVudCksci5ub2RlX29wcy5yZWFkbGluayhyKSl9LHN0YXQoZSxyKXt2YXIgdD1sZS5sb29rdXBQYXRoKGUse2ZvbGxvdzohcn0pLm5vZGU7aWYoIXQpdGhyb3cgbmV3IGxlLkVycm5vRXJyb3IoNDQpO2lmKCF0Lm5vZGVfb3BzLmdldGF0dHIpdGhyb3cgbmV3IGxlLkVycm5vRXJyb3IoNjMpO3JldHVybiB0Lm5vZGVfb3BzLmdldGF0dHIodCl9LGxzdGF0OmU9PmxlLnN0YXQoZSwhMCksY2htb2QoZSxyLHQpe3ZhciBuO2lmKCEobj0ic3RyaW5nIj09dHlwZW9mIGU/bGUubG9va3VwUGF0aChlLHtmb2xsb3c6IXR9KS5ub2RlOmUpLm5vZGVfb3BzLnNldGF0dHIpdGhyb3cgbmV3IGxlLkVycm5vRXJyb3IoNjMpO24ubm9kZV9vcHMuc2V0YXR0cihuLHttb2RlOjQwOTUmcnwtNDA5NiZuLm1vZGUsdGltZXN0YW1wOkRhdGUubm93KCl9KX0sbGNobW9kKGUscil7bGUuY2htb2QoZSxyLCEwKX0sZmNobW9kKGUscil7dmFyIHQ9bGUuZ2V0U3RyZWFtQ2hlY2tlZChlKTtsZS5jaG1vZCh0Lm5vZGUscil9LGNob3duKGUscix0LG4pe3ZhciBvO2lmKCEobz0ic3RyaW5nIj09dHlwZW9mIGU/bGUubG9va3VwUGF0aChlLHtmb2xsb3c6IW59KS5ub2RlOmUpLm5vZGVfb3BzLnNldGF0dHIpdGhyb3cgbmV3IGxlLkVycm5vRXJyb3IoNjMpO28ubm9kZV9vcHMuc2V0YXR0cihvLHt0aW1lc3RhbXA6RGF0ZS5ub3coKX0pfSxsY2hvd24oZSxyLHQpe2xlLmNob3duKGUscix0LCEwKX0sZmNob3duKGUscix0KXt2YXIgbj1sZS5nZXRTdHJlYW1DaGVja2VkKGUpO2xlLmNob3duKG4ubm9kZSxyLHQpfSx0cnVuY2F0ZShlLHIpe2lmKHI8MCl0aHJvdyBuZXcgbGUuRXJybm9FcnJvcigyOCk7dmFyIHQ7aWYoISh0PSJzdHJpbmciPT10eXBlb2YgZT9sZS5sb29rdXBQYXRoKGUse2ZvbGxvdzohMH0pLm5vZGU6ZSkubm9kZV9vcHMuc2V0YXR0cil0aHJvdyBuZXcgbGUuRXJybm9FcnJvcig2Myk7aWYobGUuaXNEaXIodC5tb2RlKSl0aHJvdyBuZXcgbGUuRXJybm9FcnJvcigzMSk7aWYoIWxlLmlzRmlsZSh0Lm1vZGUpKXRocm93IG5ldyBsZS5FcnJub0Vycm9yKDI4KTt2YXIgbj1sZS5ub2RlUGVybWlzc2lvbnModCwidyIpO2lmKG4pdGhyb3cgbmV3IGxlLkVycm5vRXJyb3Iobik7dC5ub2RlX29wcy5zZXRhdHRyKHQse3NpemU6cix0aW1lc3RhbXA6RGF0ZS5ub3coKX0pfSxmdHJ1bmNhdGUoZSxyKXt2YXIgdD1sZS5nZXRTdHJlYW1DaGVja2VkKGUpO2lmKDA9PSgyMDk3MTU1JnQuZmxhZ3MpKXRocm93IG5ldyBsZS5FcnJub0Vycm9yKDI4KTtsZS50cnVuY2F0ZSh0Lm5vZGUscil9LHV0aW1lKGUscix0KXt2YXIgbj1sZS5sb29rdXBQYXRoKGUse2ZvbGxvdzohMH0pLm5vZGU7bi5ub2RlX29wcy5zZXRhdHRyKG4se3RpbWVzdGFtcDpNYXRoLm1heChyLHQpfSl9LG9wZW4oZSxyLHQpe2lmKCIiPT09ZSl0aHJvdyBuZXcgbGUuRXJybm9FcnJvcig0NCk7dmFyIG87aWYodD12b2lkIDA9PT10PzQzODp0LHQ9NjQmKHI9InN0cmluZyI9PXR5cGVvZiByPyhlPT57dmFyIHI9e3I6MCwicisiOjIsdzo1NzcsIncrIjo1NzgsYToxMDg5LCJhKyI6MTA5MH1bZV07aWYodm9pZCAwPT09cil0aHJvdyBuZXcgRXJyb3IoYFVua25vd24gZmlsZSBvcGVuIG1vZGU6ICR7ZX1gKTtyZXR1cm4gcn0pKHIpOnIpPzQwOTUmdHwzMjc2ODowLCJvYmplY3QiPT10eXBlb2YgZSlvPWU7ZWxzZXtlPVoubm9ybWFsaXplKGUpO3RyeXtvPWxlLmxvb2t1cFBhdGgoZSx7Zm9sbG93OiEoMTMxMDcyJnIpfSkubm9kZX1jYXRjaChlKXt9fXZhciBhPSExO2lmKDY0JnIpaWYobyl7aWYoMTI4JnIpdGhyb3cgbmV3IGxlLkVycm5vRXJyb3IoMjApfWVsc2Ugbz1sZS5ta25vZChlLHQsMCksYT0hMDtpZighbyl0aHJvdyBuZXcgbGUuRXJybm9FcnJvcig0NCk7aWYobGUuaXNDaHJkZXYoby5tb2RlKSYmKHImPS01MTMpLDY1NTM2JnImJiFsZS5pc0RpcihvLm1vZGUpKXRocm93IG5ldyBsZS5FcnJub0Vycm9yKDU0KTtpZighYSl7dmFyIHM9bGUubWF5T3BlbihvLHIpO2lmKHMpdGhyb3cgbmV3IGxlLkVycm5vRXJyb3Iocyl9NTEyJnImJiFhJiZsZS50cnVuY2F0ZShvLDApLHImPS0xMzE3MTM7dmFyIGk9bGUuY3JlYXRlU3RyZWFtKHtub2RlOm8scGF0aDpsZS5nZXRQYXRoKG8pLGZsYWdzOnIsc2Vla2FibGU6ITAscG9zaXRpb246MCxzdHJlYW1fb3BzOm8uc3RyZWFtX29wcyx1bmdvdHRlbjpbXSxlcnJvcjohMX0pO3JldHVybiBpLnN0cmVhbV9vcHMub3BlbiYmaS5zdHJlYW1fb3BzLm9wZW4oaSksIW4ubG9nUmVhZEZpbGVzfHwxJnJ8fChsZS5yZWFkRmlsZXN8fChsZS5yZWFkRmlsZXM9e30pLGUgaW4gbGUucmVhZEZpbGVzfHwobGUucmVhZEZpbGVzW2VdPTEpKSxpfSxjbG9zZShlKXtpZihsZS5pc0Nsb3NlZChlKSl0aHJvdyBuZXcgbGUuRXJybm9FcnJvcig4KTtlLmdldGRlbnRzJiYoZS5nZXRkZW50cz1udWxsKTt0cnl7ZS5zdHJlYW1fb3BzLmNsb3NlJiZlLnN0cmVhbV9vcHMuY2xvc2UoZSl9Y2F0Y2goZSl7dGhyb3cgZX1maW5hbGx5e2xlLmNsb3NlU3RyZWFtKGUuZmQpfWUuZmQ9bnVsbH0saXNDbG9zZWQ6ZT0+bnVsbD09PWUuZmQsbGxzZWVrKGUscix0KXtpZihsZS5pc0Nsb3NlZChlKSl0aHJvdyBuZXcgbGUuRXJybm9FcnJvcig4KTtpZighZS5zZWVrYWJsZXx8IWUuc3RyZWFtX29wcy5sbHNlZWspdGhyb3cgbmV3IGxlLkVycm5vRXJyb3IoNzApO2lmKDAhPXQmJjEhPXQmJjIhPXQpdGhyb3cgbmV3IGxlLkVycm5vRXJyb3IoMjgpO3JldHVybiBlLnBvc2l0aW9uPWUuc3RyZWFtX29wcy5sbHNlZWsoZSxyLHQpLGUudW5nb3R0ZW49W10sZS5wb3NpdGlvbn0scmVhZChlLHIsdCxuLG8pe2lmKG48MHx8bzwwKXRocm93IG5ldyBsZS5FcnJub0Vycm9yKDI4KTtpZihsZS5pc0Nsb3NlZChlKSl0aHJvdyBuZXcgbGUuRXJybm9FcnJvcig4KTtpZigxPT0oMjA5NzE1NSZlLmZsYWdzKSl0aHJvdyBuZXcgbGUuRXJybm9FcnJvcig4KTtpZihsZS5pc0RpcihlLm5vZGUubW9kZSkpdGhyb3cgbmV3IGxlLkVycm5vRXJyb3IoMzEpO2lmKCFlLnN0cmVhbV9vcHMucmVhZCl0aHJvdyBuZXcgbGUuRXJybm9FcnJvcigyOCk7dmFyIGE9dm9pZCAwIT09bztpZihhKXtpZighZS5zZWVrYWJsZSl0aHJvdyBuZXcgbGUuRXJybm9FcnJvcig3MCl9ZWxzZSBvPWUucG9zaXRpb247dmFyIHM9ZS5zdHJlYW1fb3BzLnJlYWQoZSxyLHQsbixvKTtyZXR1cm4gYXx8KGUucG9zaXRpb24rPXMpLHN9LHdyaXRlKGUscix0LG4sbyxhKXtpZihuPDB8fG88MCl0aHJvdyBuZXcgbGUuRXJybm9FcnJvcigyOCk7aWYobGUuaXNDbG9zZWQoZSkpdGhyb3cgbmV3IGxlLkVycm5vRXJyb3IoOCk7aWYoMD09KDIwOTcxNTUmZS5mbGFncykpdGhyb3cgbmV3IGxlLkVycm5vRXJyb3IoOCk7aWYobGUuaXNEaXIoZS5ub2RlLm1vZGUpKXRocm93IG5ldyBsZS5FcnJub0Vycm9yKDMxKTtpZighZS5zdHJlYW1fb3BzLndyaXRlKXRocm93IG5ldyBsZS5FcnJub0Vycm9yKDI4KTtlLnNlZWthYmxlJiYxMDI0JmUuZmxhZ3MmJmxlLmxsc2VlayhlLDAsMik7dmFyIHM9dm9pZCAwIT09bztpZihzKXtpZighZS5zZWVrYWJsZSl0aHJvdyBuZXcgbGUuRXJybm9FcnJvcig3MCl9ZWxzZSBvPWUucG9zaXRpb247dmFyIGk9ZS5zdHJlYW1fb3BzLndyaXRlKGUscix0LG4sbyxhKTtyZXR1cm4gc3x8KGUucG9zaXRpb24rPWkpLGl9LGFsbG9jYXRlKGUscix0KXtpZihsZS5pc0Nsb3NlZChlKSl0aHJvdyBuZXcgbGUuRXJybm9FcnJvcig4KTtpZihyPDB8fHQ8PTApdGhyb3cgbmV3IGxlLkVycm5vRXJyb3IoMjgpO2lmKDA9PSgyMDk3MTU1JmUuZmxhZ3MpKXRocm93IG5ldyBsZS5FcnJub0Vycm9yKDgpO2lmKCFsZS5pc0ZpbGUoZS5ub2RlLm1vZGUpJiYhbGUuaXNEaXIoZS5ub2RlLm1vZGUpKXRocm93IG5ldyBsZS5FcnJub0Vycm9yKDQzKTtpZighZS5zdHJlYW1fb3BzLmFsbG9jYXRlKXRocm93IG5ldyBsZS5FcnJub0Vycm9yKDEzOCk7ZS5zdHJlYW1fb3BzLmFsbG9jYXRlKGUscix0KX0sbW1hcChlLHIsdCxuLG8pe2lmKDAhPSgyJm4pJiYwPT0oMiZvKSYmMiE9KDIwOTcxNTUmZS5mbGFncykpdGhyb3cgbmV3IGxlLkVycm5vRXJyb3IoMik7aWYoMT09KDIwOTcxNTUmZS5mbGFncykpdGhyb3cgbmV3IGxlLkVycm5vRXJyb3IoMik7aWYoIWUuc3RyZWFtX29wcy5tbWFwKXRocm93IG5ldyBsZS5FcnJub0Vycm9yKDQzKTtyZXR1cm4gZS5zdHJlYW1fb3BzLm1tYXAoZSxyLHQsbixvKX0sbXN5bmM6KGUscix0LG4sbyk9PmUuc3RyZWFtX29wcy5tc3luYz9lLnN0cmVhbV9vcHMubXN5bmMoZSxyLHQsbixvKTowLG11bm1hcDplPT4wLGlvY3RsKGUscix0KXtpZighZS5zdHJlYW1fb3BzLmlvY3RsKXRocm93IG5ldyBsZS5FcnJub0Vycm9yKDU5KTtyZXR1cm4gZS5zdHJlYW1fb3BzLmlvY3RsKGUscix0KX0scmVhZEZpbGUoZSxyPXt9KXtpZihyLmZsYWdzPXIuZmxhZ3N8fDAsci5lbmNvZGluZz1yLmVuY29kaW5nfHwiYmluYXJ5IiwidXRmOCIhPT1yLmVuY29kaW5nJiYiYmluYXJ5IiE9PXIuZW5jb2RpbmcpdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIGVuY29kaW5nIHR5cGUgIiR7ci5lbmNvZGluZ30iYCk7dmFyIHQsbj1sZS5vcGVuKGUsci5mbGFncyksbz1sZS5zdGF0KGUpLnNpemUsYT1uZXcgVWludDhBcnJheShvKTtyZXR1cm4gbGUucmVhZChuLGEsMCxvLDApLCJ1dGY4Ij09PXIuZW5jb2Rpbmc/dD1RKGEsMCk6ImJpbmFyeSI9PT1yLmVuY29kaW5nJiYodD1hKSxsZS5jbG9zZShuKSx0fSx3cml0ZUZpbGUoZSxyLHQ9e30pe3QuZmxhZ3M9dC5mbGFnc3x8NTc3O3ZhciBuPWxlLm9wZW4oZSx0LmZsYWdzLHQubW9kZSk7aWYoInN0cmluZyI9PXR5cGVvZiByKXt2YXIgbz1uZXcgVWludDhBcnJheShyZShyKSsxKSxhPXRlKHIsbywwLG8ubGVuZ3RoKTtsZS53cml0ZShuLG8sMCxhLHZvaWQgMCx0LmNhbk93bil9ZWxzZXtpZighQXJyYXlCdWZmZXIuaXNWaWV3KHIpKXRocm93IG5ldyBFcnJvcigiVW5zdXBwb3J0ZWQgZGF0YSB0eXBlIik7bGUud3JpdGUobixyLDAsci5ieXRlTGVuZ3RoLHZvaWQgMCx0LmNhbk93bil9bGUuY2xvc2Uobil9LGN3ZDooKT0+bGUuY3VycmVudFBhdGgsY2hkaXIoZSl7dmFyIHI9bGUubG9va3VwUGF0aChlLHtmb2xsb3c6ITB9KTtpZihudWxsPT09ci5ub2RlKXRocm93IG5ldyBsZS5FcnJub0Vycm9yKDQ0KTtpZighbGUuaXNEaXIoci5ub2RlLm1vZGUpKXRocm93IG5ldyBsZS5FcnJub0Vycm9yKDU0KTt2YXIgdD1sZS5ub2RlUGVybWlzc2lvbnMoci5ub2RlLCJ4Iik7aWYodCl0aHJvdyBuZXcgbGUuRXJybm9FcnJvcih0KTtsZS5jdXJyZW50UGF0aD1yLnBhdGh9LGNyZWF0ZURlZmF1bHREaXJlY3Rvcmllcygpe2xlLm1rZGlyKCIvdG1wIiksbGUubWtkaXIoIi9ob21lIiksbGUubWtkaXIoIi9ob21lL3dlYl91c2VyIil9LGNyZWF0ZURlZmF1bHREZXZpY2VzKCl7bGUubWtkaXIoIi9kZXYiKSxsZS5yZWdpc3RlckRldmljZShsZS5tYWtlZGV2KDEsMykse3JlYWQ6KCk9PjAsd3JpdGU6KGUscix0LG4sbyk9Pm59KSxsZS5ta2RldigiL2Rldi9udWxsIixsZS5tYWtlZGV2KDEsMykpLG9lLnJlZ2lzdGVyKGxlLm1ha2VkZXYoNSwwKSxvZS5kZWZhdWx0X3R0eV9vcHMpLG9lLnJlZ2lzdGVyKGxlLm1ha2VkZXYoNiwwKSxvZS5kZWZhdWx0X3R0eTFfb3BzKSxsZS5ta2RldigiL2Rldi90dHkiLGxlLm1ha2VkZXYoNSwwKSksbGUubWtkZXYoIi9kZXYvdHR5MSIsbGUubWFrZWRldig2LDApKTt2YXIgZT1uZXcgVWludDhBcnJheSgxMDI0KSxyPTAsdD0oKT0+KDA9PT1yJiYocj1HKGUpLmJ5dGVMZW5ndGgpLGVbLS1yXSk7bGUuY3JlYXRlRGV2aWNlKCIvZGV2IiwicmFuZG9tIix0KSxsZS5jcmVhdGVEZXZpY2UoIi9kZXYiLCJ1cmFuZG9tIix0KSxsZS5ta2RpcigiL2Rldi9zaG0iKSxsZS5ta2RpcigiL2Rldi9zaG0vdG1wIil9LGNyZWF0ZVNwZWNpYWxEaXJlY3Rvcmllcygpe2xlLm1rZGlyKCIvcHJvYyIpO3ZhciBlPWxlLm1rZGlyKCIvcHJvYy9zZWxmIik7bGUubWtkaXIoIi9wcm9jL3NlbGYvZmQiKSxsZS5tb3VudCh7bW91bnQoKXt2YXIgcj1sZS5jcmVhdGVOb2RlKGUsImZkIiwxNjg5NSw3Myk7cmV0dXJuIHIubm9kZV9vcHM9e2xvb2t1cChlLHIpe3ZhciB0PStyLG49bGUuZ2V0U3RyZWFtQ2hlY2tlZCh0KSxvPXtwYXJlbnQ6bnVsbCxtb3VudDp7bW91bnRwb2ludDoiZmFrZSJ9LG5vZGVfb3BzOntyZWFkbGluazooKT0+bi5wYXRofX07cmV0dXJuIG8ucGFyZW50PW8sb319LHJ9fSx7fSwiL3Byb2Mvc2VsZi9mZCIpfSxjcmVhdGVTdGFuZGFyZFN0cmVhbXMoKXtuLnN0ZGluP2xlLmNyZWF0ZURldmljZSgiL2RldiIsInN0ZGluIixuLnN0ZGluKTpsZS5zeW1saW5rKCIvZGV2L3R0eSIsIi9kZXYvc3RkaW4iKSxuLnN0ZG91dD9sZS5jcmVhdGVEZXZpY2UoIi9kZXYiLCJzdGRvdXQiLG51bGwsbi5zdGRvdXQpOmxlLnN5bWxpbmsoIi9kZXYvdHR5IiwiL2Rldi9zdGRvdXQiKSxuLnN0ZGVycj9sZS5jcmVhdGVEZXZpY2UoIi9kZXYiLCJzdGRlcnIiLG51bGwsbi5zdGRlcnIpOmxlLnN5bWxpbmsoIi9kZXYvdHR5MSIsIi9kZXYvc3RkZXJyIiksbGUub3BlbigiL2Rldi9zdGRpbiIsMCksbGUub3BlbigiL2Rldi9zdGRvdXQiLDEpLGxlLm9wZW4oIi9kZXYvc3RkZXJyIiwxKX0sZW5zdXJlRXJybm9FcnJvcigpe2xlLkVycm5vRXJyb3J8fChsZS5FcnJub0Vycm9yPWZ1bmN0aW9uKGUscil7dGhpcy5uYW1lPSJFcnJub0Vycm9yIix0aGlzLm5vZGU9cix0aGlzLnNldEVycm5vPWZ1bmN0aW9uKGUpe3RoaXMuZXJybm89ZX0sdGhpcy5zZXRFcnJubyhlKSx0aGlzLm1lc3NhZ2U9IkZTIGVycm9yIn0sbGUuRXJybm9FcnJvci5wcm90b3R5cGU9bmV3IEVycm9yLGxlLkVycm5vRXJyb3IucHJvdG90eXBlLmNvbnN0cnVjdG9yPWxlLkVycm5vRXJyb3IsWzQ0XS5mb3JFYWNoKChlPT57bGUuZ2VuZXJpY0Vycm9yc1tlXT1uZXcgbGUuRXJybm9FcnJvcihlKSxsZS5nZW5lcmljRXJyb3JzW2VdLnN0YWNrPSI8Z2VuZXJpYyBlcnJvciwgbm8gc3RhY2s+In0pKSl9LHN0YXRpY0luaXQoKXtsZS5lbnN1cmVFcnJub0Vycm9yKCksbGUubmFtZVRhYmxlPW5ldyBBcnJheSg0MDk2KSxsZS5tb3VudChzZSx7fSwiLyIpLGxlLmNyZWF0ZURlZmF1bHREaXJlY3RvcmllcygpLGxlLmNyZWF0ZURlZmF1bHREZXZpY2VzKCksbGUuY3JlYXRlU3BlY2lhbERpcmVjdG9yaWVzKCksbGUuZmlsZXN5c3RlbXM9e01FTUZTOnNlfX0saW5pdChlLHIsdCl7bGUuaW5pdC5pbml0aWFsaXplZD0hMCxsZS5lbnN1cmVFcnJub0Vycm9yKCksbi5zdGRpbj1lfHxuLnN0ZGluLG4uc3Rkb3V0PXJ8fG4uc3Rkb3V0LG4uc3RkZXJyPXR8fG4uc3RkZXJyLGxlLmNyZWF0ZVN0YW5kYXJkU3RyZWFtcygpfSxxdWl0KCl7bGUuaW5pdC5pbml0aWFsaXplZD0hMTtmb3IodmFyIGU9MDtlPGxlLnN0cmVhbXMubGVuZ3RoO2UrKyl7dmFyIHI9bGUuc3RyZWFtc1tlXTtyJiZsZS5jbG9zZShyKX19LGZpbmRPYmplY3QoZSxyKXt2YXIgdD1sZS5hbmFseXplUGF0aChlLHIpO3JldHVybiB0LmV4aXN0cz90Lm9iamVjdDpudWxsfSxhbmFseXplUGF0aChlLHIpe3RyeXtlPShuPWxlLmxvb2t1cFBhdGgoZSx7Zm9sbG93OiFyfSkpLnBhdGh9Y2F0Y2goZSl7fXZhciB0PXtpc1Jvb3Q6ITEsZXhpc3RzOiExLGVycm9yOjAsbmFtZTpudWxsLHBhdGg6bnVsbCxvYmplY3Q6bnVsbCxwYXJlbnRFeGlzdHM6ITEscGFyZW50UGF0aDpudWxsLHBhcmVudE9iamVjdDpudWxsfTt0cnl7dmFyIG49bGUubG9va3VwUGF0aChlLHtwYXJlbnQ6ITB9KTt0LnBhcmVudEV4aXN0cz0hMCx0LnBhcmVudFBhdGg9bi5wYXRoLHQucGFyZW50T2JqZWN0PW4ubm9kZSx0Lm5hbWU9Wi5iYXNlbmFtZShlKSxuPWxlLmxvb2t1cFBhdGgoZSx7Zm9sbG93OiFyfSksdC5leGlzdHM9ITAsdC5wYXRoPW4ucGF0aCx0Lm9iamVjdD1uLm5vZGUsdC5uYW1lPW4ubm9kZS5uYW1lLHQuaXNSb290PSIvIj09PW4ucGF0aH1jYXRjaChlKXt0LmVycm9yPWUuZXJybm99cmV0dXJuIHR9LGNyZWF0ZVBhdGgoZSxyLHQsbil7ZT0ic3RyaW5nIj09dHlwZW9mIGU/ZTpsZS5nZXRQYXRoKGUpO2Zvcih2YXIgbz1yLnNwbGl0KCIvIikucmV2ZXJzZSgpO28ubGVuZ3RoOyl7dmFyIGE9by5wb3AoKTtpZihhKXt2YXIgcz1aLmpvaW4yKGUsYSk7dHJ5e2xlLm1rZGlyKHMpfWNhdGNoKGUpe31lPXN9fXJldHVybiBzfSxjcmVhdGVGaWxlKGUscix0LG4sbyl7dmFyIGE9Wi5qb2luMigic3RyaW5nIj09dHlwZW9mIGU/ZTpsZS5nZXRQYXRoKGUpLHIpLHM9dWUobixvKTtyZXR1cm4gbGUuY3JlYXRlKGEscyl9LGNyZWF0ZURhdGFGaWxlKGUscix0LG4sbyxhKXt2YXIgcz1yO2UmJihlPSJzdHJpbmciPT10eXBlb2YgZT9lOmxlLmdldFBhdGgoZSkscz1yP1ouam9pbjIoZSxyKTplKTt2YXIgaT11ZShuLG8pLHU9bGUuY3JlYXRlKHMsaSk7aWYodCl7aWYoInN0cmluZyI9PXR5cGVvZiB0KXtmb3IodmFyIGw9bmV3IEFycmF5KHQubGVuZ3RoKSxjPTAsZD10Lmxlbmd0aDtjPGQ7KytjKWxbY109dC5jaGFyQ29kZUF0KGMpO3Q9bH1sZS5jaG1vZCh1LDE0NnxpKTt2YXIgaD1sZS5vcGVuKHUsNTc3KTtsZS53cml0ZShoLHQsMCx0Lmxlbmd0aCwwLGEpLGxlLmNsb3NlKGgpLGxlLmNobW9kKHUsaSl9fSxjcmVhdGVEZXZpY2UoZSxyLHQsbil7dmFyIG89Wi5qb2luMigic3RyaW5nIj09dHlwZW9mIGU/ZTpsZS5nZXRQYXRoKGUpLHIpLGE9dWUoISF0LCEhbik7bGUuY3JlYXRlRGV2aWNlLm1ham9yfHwobGUuY3JlYXRlRGV2aWNlLm1ham9yPTY0KTt2YXIgcz1sZS5tYWtlZGV2KGxlLmNyZWF0ZURldmljZS5tYWpvcisrLDApO3JldHVybiBsZS5yZWdpc3RlckRldmljZShzLHtvcGVuKGUpe2Uuc2Vla2FibGU9ITF9LGNsb3NlKGUpe24/LmJ1ZmZlcj8ubGVuZ3RoJiZuKDEwKX0scmVhZChlLHIsbixvLGEpe2Zvcih2YXIgcz0wLGk9MDtpPG87aSsrKXt2YXIgdTt0cnl7dT10KCl9Y2F0Y2goZSl7dGhyb3cgbmV3IGxlLkVycm5vRXJyb3IoMjkpfWlmKHZvaWQgMD09PXUmJjA9PT1zKXRocm93IG5ldyBsZS5FcnJub0Vycm9yKDYpO2lmKG51bGw9PXUpYnJlYWs7cysrLHJbbitpXT11fXJldHVybiBzJiYoZS5ub2RlLnRpbWVzdGFtcD1EYXRlLm5vdygpKSxzfSx3cml0ZShlLHIsdCxvLGEpe2Zvcih2YXIgcz0wO3M8bztzKyspdHJ5e24oclt0K3NdKX1jYXRjaChlKXt0aHJvdyBuZXcgbGUuRXJybm9FcnJvcigyOSl9cmV0dXJuIG8mJihlLm5vZGUudGltZXN0YW1wPURhdGUubm93KCkpLHN9fSksbGUubWtkZXYobyxhLHMpfSxmb3JjZUxvYWRGaWxlKGUpe2lmKGUuaXNEZXZpY2V8fGUuaXNGb2xkZXJ8fGUubGlua3x8ZS5jb250ZW50cylyZXR1cm4hMDtpZigidW5kZWZpbmVkIiE9dHlwZW9mIFhNTEh0dHBSZXF1ZXN0KXRocm93IG5ldyBFcnJvcigiTGF6eSBsb2FkaW5nIHNob3VsZCBoYXZlIGJlZW4gcGVyZm9ybWVkIChjb250ZW50cyBzZXQpIGluIGNyZWF0ZUxhenlGaWxlLCBidXQgaXQgd2FzIG5vdC4gTGF6eSBsb2FkaW5nIG9ubHkgd29ya3MgaW4gd2ViIHdvcmtlcnMuIFVzZSAtLWVtYmVkLWZpbGUgb3IgLS1wcmVsb2FkLWZpbGUgaW4gZW1jYyBvbiB0aGUgbWFpbiB0aHJlYWQuIik7aWYoIW8pdGhyb3cgbmV3IEVycm9yKCJDYW5ub3QgbG9hZCB3aXRob3V0IHJlYWQoKSBvciBYTUxIdHRwUmVxdWVzdC4iKTt0cnl7ZS5jb250ZW50cz1uZShvKGUudXJsKSwhMCksZS51c2VkQnl0ZXM9ZS5jb250ZW50cy5sZW5ndGh9Y2F0Y2goZSl7dGhyb3cgbmV3IGxlLkVycm5vRXJyb3IoMjkpfX0sY3JlYXRlTGF6eUZpbGUoZSxyLHQsbixvKXtmdW5jdGlvbiBhKCl7dGhpcy5sZW5ndGhLbm93bj0hMSx0aGlzLmNodW5rcz1bXX1pZihhLnByb3RvdHlwZS5nZXQ9ZnVuY3Rpb24oZSl7aWYoIShlPnRoaXMubGVuZ3RoLTF8fGU8MCkpe3ZhciByPWUldGhpcy5jaHVua1NpemUsdD1lL3RoaXMuY2h1bmtTaXplfDA7cmV0dXJuIHRoaXMuZ2V0dGVyKHQpW3JdfX0sYS5wcm90b3R5cGUuc2V0RGF0YUdldHRlcj1mdW5jdGlvbihlKXt0aGlzLmdldHRlcj1lfSxhLnByb3RvdHlwZS5jYWNoZUxlbmd0aD1mdW5jdGlvbigpe3ZhciBlPW5ldyBYTUxIdHRwUmVxdWVzdDtpZihlLm9wZW4oIkhFQUQiLHQsITEpLGUuc2VuZChudWxsKSwhKGUuc3RhdHVzPj0yMDAmJmUuc3RhdHVzPDMwMHx8MzA0PT09ZS5zdGF0dXMpKXRocm93IG5ldyBFcnJvcigiQ291bGRuJ3QgbG9hZCAiK3QrIi4gU3RhdHVzOiAiK2Uuc3RhdHVzKTt2YXIgcixuPU51bWJlcihlLmdldFJlc3BvbnNlSGVhZGVyKCJDb250ZW50LWxlbmd0aCIpKSxvPShyPWUuZ2V0UmVzcG9uc2VIZWFkZXIoIkFjY2VwdC1SYW5nZXMiKSkmJiJieXRlcyI9PT1yLGE9KHI9ZS5nZXRSZXNwb25zZUhlYWRlcigiQ29udGVudC1FbmNvZGluZyIpKSYmImd6aXAiPT09cixzPTEwNDg1NzY7b3x8KHM9bik7dmFyIGk9dGhpcztpLnNldERhdGFHZXR0ZXIoKGU9Pnt2YXIgcj1lKnMsbz0oZSsxKSpzLTE7aWYobz1NYXRoLm1pbihvLG4tMSksdm9pZCAwPT09aS5jaHVua3NbZV0mJihpLmNodW5rc1tlXT0oKGUscik9PntpZihlPnIpdGhyb3cgbmV3IEVycm9yKCJpbnZhbGlkIHJhbmdlICgiK2UrIiwgIityKyIpIG9yIG5vIGJ5dGVzIHJlcXVlc3RlZCEiKTtpZihyPm4tMSl0aHJvdyBuZXcgRXJyb3IoIm9ubHkgIituKyIgYnl0ZXMgYXZhaWxhYmxlISBwcm9ncmFtbWVyIGVycm9yISIpO3ZhciBvPW5ldyBYTUxIdHRwUmVxdWVzdDtpZihvLm9wZW4oIkdFVCIsdCwhMSksbiE9PXMmJm8uc2V0UmVxdWVzdEhlYWRlcigiUmFuZ2UiLCJieXRlcz0iK2UrIi0iK3IpLG8ucmVzcG9uc2VUeXBlPSJhcnJheWJ1ZmZlciIsby5vdmVycmlkZU1pbWVUeXBlJiZvLm92ZXJyaWRlTWltZVR5cGUoInRleHQvcGxhaW47IGNoYXJzZXQ9eC11c2VyLWRlZmluZWQiKSxvLnNlbmQobnVsbCksIShvLnN0YXR1cz49MjAwJiZvLnN0YXR1czwzMDB8fDMwND09PW8uc3RhdHVzKSl0aHJvdyBuZXcgRXJyb3IoIkNvdWxkbid0IGxvYWQgIit0KyIuIFN0YXR1czogIitvLnN0YXR1cyk7cmV0dXJuIHZvaWQgMCE9PW8ucmVzcG9uc2U/bmV3IFVpbnQ4QXJyYXkoby5yZXNwb25zZXx8W10pOm5lKG8ucmVzcG9uc2VUZXh0fHwiIiwhMCl9KShyLG8pKSx2b2lkIDA9PT1pLmNodW5rc1tlXSl0aHJvdyBuZXcgRXJyb3IoImRvWEhSIGZhaWxlZCEiKTtyZXR1cm4gaS5jaHVua3NbZV19KSksIWEmJm58fChzPW49MSxuPXRoaXMuZ2V0dGVyKDApLmxlbmd0aCxzPW4sXygiTGF6eUZpbGVzIG9uIGd6aXAgZm9yY2VzIGRvd25sb2FkIG9mIHRoZSB3aG9sZSBmaWxlIHdoZW4gbGVuZ3RoIGlzIGFjY2Vzc2VkIikpLHRoaXMuX2xlbmd0aD1uLHRoaXMuX2NodW5rU2l6ZT1zLHRoaXMubGVuZ3RoS25vd249ITB9LCJ1bmRlZmluZWQiIT10eXBlb2YgWE1MSHR0cFJlcXVlc3Qpe2lmKCFkKXRocm93IkNhbm5vdCBkbyBzeW5jaHJvbm91cyBiaW5hcnkgWEhScyBvdXRzaWRlIHdlYndvcmtlcnMgaW4gbW9kZXJuIGJyb3dzZXJzLiBVc2UgLS1lbWJlZC1maWxlIG9yIC0tcHJlbG9hZC1maWxlIGluIGVtY2MiO3ZhciBzPW5ldyBhO09iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKHMse2xlbmd0aDp7Z2V0OmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMubGVuZ3RoS25vd258fHRoaXMuY2FjaGVMZW5ndGgoKSx0aGlzLl9sZW5ndGh9fSxjaHVua1NpemU6e2dldDpmdW5jdGlvbigpe3JldHVybiB0aGlzLmxlbmd0aEtub3dufHx0aGlzLmNhY2hlTGVuZ3RoKCksdGhpcy5fY2h1bmtTaXplfX19KTt2YXIgaT17aXNEZXZpY2U6ITEsY29udGVudHM6c319ZWxzZSBpPXtpc0RldmljZTohMSx1cmw6dH07dmFyIHU9bGUuY3JlYXRlRmlsZShlLHIsaSxuLG8pO2kuY29udGVudHM/dS5jb250ZW50cz1pLmNvbnRlbnRzOmkudXJsJiYodS5jb250ZW50cz1udWxsLHUudXJsPWkudXJsKSxPYmplY3QuZGVmaW5lUHJvcGVydGllcyh1LHt1c2VkQnl0ZXM6e2dldDpmdW5jdGlvbigpe3JldHVybiB0aGlzLmNvbnRlbnRzLmxlbmd0aH19fSk7dmFyIGw9e307ZnVuY3Rpb24gYyhlLHIsdCxuLG8pe3ZhciBhPWUubm9kZS5jb250ZW50cztpZihvPj1hLmxlbmd0aClyZXR1cm4gMDt2YXIgcz1NYXRoLm1pbihhLmxlbmd0aC1vLG4pO2lmKGEuc2xpY2UpZm9yKHZhciBpPTA7aTxzO2krKylyW3QraV09YVtvK2ldO2Vsc2UgZm9yKGk9MDtpPHM7aSsrKXJbdCtpXT1hLmdldChvK2kpO3JldHVybiBzfXJldHVybiBPYmplY3Qua2V5cyh1LnN0cmVhbV9vcHMpLmZvckVhY2goKGU9Pnt2YXIgcj11LnN0cmVhbV9vcHNbZV07bFtlXT1mdW5jdGlvbigpe3JldHVybiBsZS5mb3JjZUxvYWRGaWxlKHUpLHIuYXBwbHkobnVsbCxhcmd1bWVudHMpfX0pKSxsLnJlYWQ9KGUscix0LG4sbyk9PihsZS5mb3JjZUxvYWRGaWxlKHUpLGMoZSxyLHQsbixvKSksbC5tbWFwPShlLHIsdCxuLG8pPT57bGUuZm9yY2VMb2FkRmlsZSh1KTt2YXIgYT1hZSgpO2lmKCFhKXRocm93IG5ldyBsZS5FcnJub0Vycm9yKDQ4KTtyZXR1cm4gYyhlLEUsYSxyLHQpLHtwdHI6YSxhbGxvY2F0ZWQ6ITB9fSx1LnN0cmVhbV9vcHM9bCx1fX0sY2U9KGUscik9PmU/UShrLGUscik6IiIsZGU9e0RFRkFVTFRfUE9MTE1BU0s6NSxjYWxjdWxhdGVBdChlLHIsdCl7aWYoWi5pc0FicyhyKSlyZXR1cm4gcjt2YXIgbjtpZihuPS0xMDA9PT1lP2xlLmN3ZCgpOmRlLmdldFN0cmVhbUZyb21GRChlKS5wYXRoLDA9PXIubGVuZ3RoKXtpZighdCl0aHJvdyBuZXcgbGUuRXJybm9FcnJvcig0NCk7cmV0dXJuIG59cmV0dXJuIFouam9pbjIobixyKX0sZG9TdGF0KGUscix0KXt0cnl7dmFyIG49ZShyKX1jYXRjaChlKXtpZihlJiZlLm5vZGUmJloubm9ybWFsaXplKHIpIT09Wi5ub3JtYWxpemUobGUuZ2V0UGF0aChlLm5vZGUpKSlyZXR1cm4tNTQ7dGhyb3cgZX1GW3Q+PjJdPW4uZGV2LEZbdCs0Pj4yXT1uLm1vZGUsRFt0Kzg+PjJdPW4ubmxpbmssRlt0KzEyPj4yXT1uLnVpZCxGW3QrMTY+PjJdPW4uZ2lkLEZbdCsyMD4+Ml09bi5yZGV2LEk9W24uc2l6ZT4+PjAsKGo9bi5zaXplLCtNYXRoLmFicyhqKT49MT9qPjA/K01hdGguZmxvb3Ioai80Mjk0OTY3Mjk2KT4+PjA6fn4rTWF0aC5jZWlsKChqLSsofn5qPj4+MCkpLzQyOTQ5NjcyOTYpPj4+MDowKV0sRlt0KzI0Pj4yXT1JWzBdLEZbdCsyOD4+Ml09SVsxXSxGW3QrMzI+PjJdPTQwOTYsRlt0KzM2Pj4yXT1uLmJsb2Nrczt2YXIgbz1uLmF0aW1lLmdldFRpbWUoKSxhPW4ubXRpbWUuZ2V0VGltZSgpLHM9bi5jdGltZS5nZXRUaW1lKCk7cmV0dXJuIEk9W01hdGguZmxvb3Ioby8xZTMpPj4+MCwoaj1NYXRoLmZsb29yKG8vMWUzKSwrTWF0aC5hYnMoaik+PTE/aj4wPytNYXRoLmZsb29yKGovNDI5NDk2NzI5Nik+Pj4wOn5+K01hdGguY2VpbCgoai0rKH5+aj4+PjApKS80Mjk0OTY3Mjk2KT4+PjA6MCldLEZbdCs0MD4+Ml09SVswXSxGW3QrNDQ+PjJdPUlbMV0sRFt0KzQ4Pj4yXT1vJTFlMyoxZTMsST1bTWF0aC5mbG9vcihhLzFlMyk+Pj4wLChqPU1hdGguZmxvb3IoYS8xZTMpLCtNYXRoLmFicyhqKT49MT9qPjA/K01hdGguZmxvb3Ioai80Mjk0OTY3Mjk2KT4+PjA6fn4rTWF0aC5jZWlsKChqLSsofn5qPj4+MCkpLzQyOTQ5NjcyOTYpPj4+MDowKV0sRlt0KzU2Pj4yXT1JWzBdLEZbdCs2MD4+Ml09SVsxXSxEW3QrNjQ+PjJdPWElMWUzKjFlMyxJPVtNYXRoLmZsb29yKHMvMWUzKT4+PjAsKGo9TWF0aC5mbG9vcihzLzFlMyksK01hdGguYWJzKGopPj0xP2o+MD8rTWF0aC5mbG9vcihqLzQyOTQ5NjcyOTYpPj4+MDp+fitNYXRoLmNlaWwoKGotKyh+fmo+Pj4wKSkvNDI5NDk2NzI5Nik+Pj4wOjApXSxGW3QrNzI+PjJdPUlbMF0sRlt0Kzc2Pj4yXT1JWzFdLERbdCs4MD4+Ml09cyUxZTMqMWUzLEk9W24uaW5vPj4+MCwoaj1uLmlubywrTWF0aC5hYnMoaik+PTE/aj4wPytNYXRoLmZsb29yKGovNDI5NDk2NzI5Nik+Pj4wOn5+K01hdGguY2VpbCgoai0rKH5+aj4+PjApKS80Mjk0OTY3Mjk2KT4+PjA6MCldLEZbdCs4OD4+Ml09SVswXSxGW3QrOTI+PjJdPUlbMV0sMH0sZG9Nc3luYyhlLHIsdCxuLG8pe2lmKCFsZS5pc0ZpbGUoci5ub2RlLm1vZGUpKXRocm93IG5ldyBsZS5FcnJub0Vycm9yKDQzKTtpZigyJm4pcmV0dXJuIDA7dmFyIGE9ay5zbGljZShlLGUrdCk7bGUubXN5bmMocixhLG8sdCxuKX0sdmFyYXJnczp2b2lkIDAsZ2V0KCl7dmFyIGU9RlsrZGUudmFyYXJncz4+Ml07cmV0dXJuIGRlLnZhcmFyZ3MrPTQsZX0sZ2V0cDooKT0+ZGUuZ2V0KCksZ2V0U3RyOmU9PmNlKGUpLGdldFN0cmVhbUZyb21GRDplPT5sZS5nZXRTdHJlYW1DaGVja2VkKGUpfSxoZT1lPT4oRltPZSgpPj4yXT1lLGUpLGZlPXtCVUNLRVRfQlVGRkVSX1NJWkU6ODE5Mixtb3VudDplPT5sZS5jcmVhdGVOb2RlKG51bGwsIi8iLDE2ODk1LDApLGNyZWF0ZVBpcGUoKXt2YXIgZT17YnVja2V0czpbXSxyZWZjbnQ6Mn07ZS5idWNrZXRzLnB1c2goe2J1ZmZlcjpuZXcgVWludDhBcnJheShmZS5CVUNLRVRfQlVGRkVSX1NJWkUpLG9mZnNldDowLHJvZmZzZXQ6MH0pO3ZhciByPWZlLm5leHRuYW1lKCksdD1mZS5uZXh0bmFtZSgpLG49bGUuY3JlYXRlTm9kZShmZS5yb290LHIsNDA5NiwwKSxvPWxlLmNyZWF0ZU5vZGUoZmUucm9vdCx0LDQwOTYsMCk7bi5waXBlPWUsby5waXBlPWU7dmFyIGE9bGUuY3JlYXRlU3RyZWFtKHtwYXRoOnIsbm9kZTpuLGZsYWdzOjAsc2Vla2FibGU6ITEsc3RyZWFtX29wczpmZS5zdHJlYW1fb3BzfSk7bi5zdHJlYW09YTt2YXIgcz1sZS5jcmVhdGVTdHJlYW0oe3BhdGg6dCxub2RlOm8sZmxhZ3M6MSxzZWVrYWJsZTohMSxzdHJlYW1fb3BzOmZlLnN0cmVhbV9vcHN9KTtyZXR1cm4gby5zdHJlYW09cyx7cmVhZGFibGVfZmQ6YS5mZCx3cml0YWJsZV9mZDpzLmZkfX0sc3RyZWFtX29wczp7cG9sbChlKXt2YXIgcj1lLm5vZGUucGlwZTtpZigxPT0oMjA5NzE1NSZlLmZsYWdzKSlyZXR1cm4gMjYwO2lmKHIuYnVja2V0cy5sZW5ndGg+MClmb3IodmFyIHQ9MDt0PHIuYnVja2V0cy5sZW5ndGg7dCsrKXt2YXIgbj1yLmJ1Y2tldHNbdF07aWYobi5vZmZzZXQtbi5yb2Zmc2V0PjApcmV0dXJuIDY1fXJldHVybiAwfSxpb2N0bDooZSxyLHQpPT4yOCxmc3luYzplPT4yOCxyZWFkKGUscix0LG4sbyl7Zm9yKHZhciBhPWUubm9kZS5waXBlLHM9MCxpPTA7aTxhLmJ1Y2tldHMubGVuZ3RoO2krKyl7dmFyIHU9YS5idWNrZXRzW2ldO3MrPXUub2Zmc2V0LXUucm9mZnNldH12YXIgbD1yLnN1YmFycmF5KHQsdCtuKTtpZihuPD0wKXJldHVybiAwO2lmKDA9PXMpdGhyb3cgbmV3IGxlLkVycm5vRXJyb3IoNik7dmFyIGM9TWF0aC5taW4ocyxuKSxkPWMsaD0wO2ZvcihpPTA7aTxhLmJ1Y2tldHMubGVuZ3RoO2krKyl7dmFyIGY9YS5idWNrZXRzW2ldLG09Zi5vZmZzZXQtZi5yb2Zmc2V0O2lmKGM8PW0pe3ZhciBwPWYuYnVmZmVyLnN1YmFycmF5KGYucm9mZnNldCxmLm9mZnNldCk7YzxtPyhwPXAuc3ViYXJyYXkoMCxjKSxmLnJvZmZzZXQrPWMpOmgrKyxsLnNldChwKTticmVha31wPWYuYnVmZmVyLnN1YmFycmF5KGYucm9mZnNldCxmLm9mZnNldCksbC5zZXQocCksbD1sLnN1YmFycmF5KHAuYnl0ZUxlbmd0aCksYy09cC5ieXRlTGVuZ3RoLGgrK31yZXR1cm4gaCYmaD09YS5idWNrZXRzLmxlbmd0aCYmKGgtLSxhLmJ1Y2tldHNbaF0ub2Zmc2V0PTAsYS5idWNrZXRzW2hdLnJvZmZzZXQ9MCksYS5idWNrZXRzLnNwbGljZSgwLGgpLGR9LHdyaXRlKGUscix0LG4sbyl7dmFyIGE9ZS5ub2RlLnBpcGUscz1yLnN1YmFycmF5KHQsdCtuKSxpPXMuYnl0ZUxlbmd0aDtpZihpPD0wKXJldHVybiAwO3ZhciB1PW51bGw7MD09YS5idWNrZXRzLmxlbmd0aD8odT17YnVmZmVyOm5ldyBVaW50OEFycmF5KGZlLkJVQ0tFVF9CVUZGRVJfU0laRSksb2Zmc2V0OjAscm9mZnNldDowfSxhLmJ1Y2tldHMucHVzaCh1KSk6dT1hLmJ1Y2tldHNbYS5idWNrZXRzLmxlbmd0aC0xXSxBKHUub2Zmc2V0PD1mZS5CVUNLRVRfQlVGRkVSX1NJWkUpO3ZhciBsPWZlLkJVQ0tFVF9CVUZGRVJfU0laRS11Lm9mZnNldDtpZihsPj1pKXJldHVybiB1LmJ1ZmZlci5zZXQocyx1Lm9mZnNldCksdS5vZmZzZXQrPWksaTtsPjAmJih1LmJ1ZmZlci5zZXQocy5zdWJhcnJheSgwLGwpLHUub2Zmc2V0KSx1Lm9mZnNldCs9bCxzPXMuc3ViYXJyYXkobCxzLmJ5dGVMZW5ndGgpKTtmb3IodmFyIGM9cy5ieXRlTGVuZ3RoL2ZlLkJVQ0tFVF9CVUZGRVJfU0laRXwwLGQ9cy5ieXRlTGVuZ3RoJWZlLkJVQ0tFVF9CVUZGRVJfU0laRSxoPTA7aDxjO2grKyl7dmFyIGY9e2J1ZmZlcjpuZXcgVWludDhBcnJheShmZS5CVUNLRVRfQlVGRkVSX1NJWkUpLG9mZnNldDpmZS5CVUNLRVRfQlVGRkVSX1NJWkUscm9mZnNldDowfTthLmJ1Y2tldHMucHVzaChmKSxmLmJ1ZmZlci5zZXQocy5zdWJhcnJheSgwLGZlLkJVQ0tFVF9CVUZGRVJfU0laRSkpLHM9cy5zdWJhcnJheShmZS5CVUNLRVRfQlVGRkVSX1NJWkUscy5ieXRlTGVuZ3RoKX1yZXR1cm4gZD4wJiYoZj17YnVmZmVyOm5ldyBVaW50OEFycmF5KGZlLkJVQ0tFVF9CVUZGRVJfU0laRSksb2Zmc2V0OnMuYnl0ZUxlbmd0aCxyb2Zmc2V0OjB9LGEuYnVja2V0cy5wdXNoKGYpLGYuYnVmZmVyLnNldChzKSksaX0sY2xvc2UoZSl7dmFyIHI9ZS5ub2RlLnBpcGU7ci5yZWZjbnQtLSwwPT09ci5yZWZjbnQmJihyLmJ1Y2tldHM9bnVsbCl9fSxuZXh0bmFtZTooKT0+KGZlLm5leHRuYW1lLmN1cnJlbnR8fChmZS5uZXh0bmFtZS5jdXJyZW50PTApLCJwaXBlWyIrZmUubmV4dG5hbWUuY3VycmVudCsrKyJdIil9LG1lPShlLHIpPT5yKzIwOTcxNTI+Pj4wPDQxOTQzMDUtISFlPyhlPj4+MCkrNDI5NDk2NzI5NipyOk5hTixwZT1lPT5lJTQ9PTAmJihlJTEwMCE9MHx8ZSU0MDA9PTApLHZlPVswLDMxLDYwLDkxLDEyMSwxNTIsMTgyLDIxMywyNDQsMjc0LDMwNSwzMzVdLHdlPVswLDMxLDU5LDkwLDEyMCwxNTEsMTgxLDIxMiwyNDMsMjczLDMwNCwzMzRdLGdlPWU9PihwZShlLmdldEZ1bGxZZWFyKCkpP3ZlOndlKVtlLmdldE1vbnRoKCldK2UuZ2V0RGF0ZSgpLTEsX2U9KGUscix0KT0+dGUoZSxrLHIsdCkseWU9ZT0+e3ZhciByPXJlKGUpKzEsdD14ZShyKTtyZXR1cm4gdCYmX2UoZSx0LHIpLHR9LEVlPWU9Pnt2YXIgcj0oZS1nLmJ1ZmZlci5ieXRlTGVuZ3RoKzY1NTM1KS82NTUzNjt0cnl7cmV0dXJuIGcuZ3JvdyhyKSxDKCksMX1jYXRjaChlKXt9fSxiZT17fSxrZT0oKT0+e2lmKCFrZS5zdHJpbmdzKXt2YXIgZT17VVNFUjoid2ViX3VzZXIiLExPR05BTUU6IndlYl91c2VyIixQQVRIOiIvIixQV0Q6Ii8iLEhPTUU6Ii9ob21lL3dlYl91c2VyIixMQU5HOigib2JqZWN0Ij09dHlwZW9mIG5hdmlnYXRvciYmbmF2aWdhdG9yLmxhbmd1YWdlcyYmbmF2aWdhdG9yLmxhbmd1YWdlc1swXXx8IkMiKS5yZXBsYWNlKCItIiwiXyIpKyIuVVRGLTgiLF86dXx8Ii4vdGhpcy5wcm9ncmFtIn07Zm9yKHZhciByIGluIGJlKXZvaWQgMD09PWJlW3JdP2RlbGV0ZSBlW3JdOmVbcl09YmVbcl07dmFyIHQ9W107Zm9yKHZhciByIGluIGUpdC5wdXNoKGAke3J9PSR7ZVtyXX1gKTtrZS5zdHJpbmdzPXR9cmV0dXJuIGtlLnN0cmluZ3N9LFNlPWU9PntYfHwobi5vbkV4aXQ/LihlKSxNPSEwKSxsKGUsbmV3IHEoZSkpfSxGZT0oZSxyKT0+e1NlKGUpfSxEZT1bMzEsMjksMzEsMzAsMzEsMzAsMzEsMzEsMzAsMzEsMzAsMzFdLE1lPVszMSwyOCwzMSwzMCwzMSwzMCwzMSwzMSwzMCwzMSwzMCwzMV0sQWU9KGUscik9PntFLnNldChlLHIpfSxDZT1lPT5uWyJfIitlXSxQZT0oZSxyLHQsbixvKT0+e3ZhciBhPXtzdHJpbmc6ZT0+e3ZhciByPTA7cmV0dXJuIG51bGwhPWUmJjAhPT1lJiYocj0oZT0+e3ZhciByPXJlKGUpKzEsdD1IZShyKTtyZXR1cm4gX2UoZSx0LHIpLHR9KShlKSkscn0sYXJyYXk6ZT0+e3ZhciByPUhlKGUubGVuZ3RoKTtyZXR1cm4gQWUoZSxyKSxyfX0scz1DZShlKSxpPVtdLHU9MDtpZihuKWZvcih2YXIgbD0wO2w8bi5sZW5ndGg7bCsrKXt2YXIgYz1hW3RbbF1dO2M/KDA9PT11JiYodT1qZSgpKSxpW2xdPWMobltsXSkpOmlbbF09bltsXX12YXIgZD1zLmFwcGx5KG51bGwsaSk7cmV0dXJuIGQ9ZnVuY3Rpb24oZSl7cmV0dXJuIDAhPT11JiZJZSh1KSxmdW5jdGlvbihlKXtyZXR1cm4ic3RyaW5nIj09PXI/Y2UoZSk6ImJvb2xlYW4iPT09cj9Cb29sZWFuKGUpOmV9KGUpfShkKX0sVGU9ZnVuY3Rpb24oZSxyLHQsbil7ZXx8KGU9dGhpcyksdGhpcy5wYXJlbnQ9ZSx0aGlzLm1vdW50PWUubW91bnQsdGhpcy5tb3VudGVkPW51bGwsdGhpcy5pZD1sZS5uZXh0SW5vZGUrKyx0aGlzLm5hbWU9cix0aGlzLm1vZGU9dCx0aGlzLm5vZGVfb3BzPXt9LHRoaXMuc3RyZWFtX29wcz17fSx0aGlzLnJkZXY9bn0sUmU9MzY1LHplPTE0NjtPYmplY3QuZGVmaW5lUHJvcGVydGllcyhUZS5wcm90b3R5cGUse3JlYWQ6e2dldDpmdW5jdGlvbigpe3JldHVybih0aGlzLm1vZGUmUmUpPT09UmV9LHNldDpmdW5jdGlvbihlKXtlP3RoaXMubW9kZXw9UmU6dGhpcy5tb2RlJj0tMzY2fX0sd3JpdGU6e2dldDpmdW5jdGlvbigpe3JldHVybih0aGlzLm1vZGUmemUpPT09emV9LHNldDpmdW5jdGlvbihlKXtlP3RoaXMubW9kZXw9emU6dGhpcy5tb2RlJj0tMTQ3fX0saXNGb2xkZXI6e2dldDpmdW5jdGlvbigpe3JldHVybiBsZS5pc0Rpcih0aGlzLm1vZGUpfX0saXNEZXZpY2U6e2dldDpmdW5jdGlvbigpe3JldHVybiBsZS5pc0NocmRldih0aGlzLm1vZGUpfX19KSxsZS5GU05vZGU9VGUsbGUuY3JlYXRlUHJlbG9hZGVkRmlsZT0oZSxyLHQsbixvLHMsaSx1LGwsYyk9Pnt2YXIgZD1yP1YucmVzb2x2ZShaLmpvaW4yKGUscikpOmU7ZnVuY3Rpb24gaCh0KXtmdW5jdGlvbiBhKHQpe2M/LigpLHV8fCgoZSxyLHQsbixvLGEpPT57bGUuY3JlYXRlRGF0YUZpbGUoZSxyLHQsbixvLGEpfSkoZSxyLHQsbixvLGwpLHM/LigpLHgoKX0oKGUscix0LG4pPT57InVuZGVmaW5lZCIhPXR5cGVvZiBCcm93c2VyJiZCcm93c2VyLmluaXQoKTt2YXIgbz0hMTtyZXR1cm4gaWUuZm9yRWFjaCgoYT0+e298fGEuY2FuSGFuZGxlKHIpJiYoYS5oYW5kbGUoZSxyLHQsbiksbz0hMCl9KSksb30pKHQsZCxhLCgoKT0+e2k/LigpLHgoKX0pKXx8YSh0KX1MKCksInN0cmluZyI9PXR5cGVvZiB0PygoZSxyLHQsbik9Pnt2YXIgbz1uPyIiOmBhbCAke2V9YDthKGUsKHQ9PntBKHQsYExvYWRpbmcgZGF0YSBmaWxlICIke2V9IiBmYWlsZWQgKG5vIGFycmF5QnVmZmVyKS5gKSxyKG5ldyBVaW50OEFycmF5KHQpKSxvJiZ4KCl9KSwocj0+e2lmKCF0KXRocm93YExvYWRpbmcgZGF0YSBmaWxlICIke2V9IiBmYWlsZWQuYDt0KCl9KSksbyYmTCgpfSkodCwoZT0+aChlKSksaSk6aCh0KX0sbGUuc3RhdGljSW5pdCgpO3ZhciBVZT17aTpmdW5jdGlvbihlKXt0cnl7dmFyIHI9ZGUuZ2V0U3RyZWFtRnJvbUZEKGUpO3JldHVybiBsZS5jcmVhdGVTdHJlYW0ocikuZmR9Y2F0Y2goZSl7aWYodm9pZCAwPT09bGV8fCJFcnJub0Vycm9yIiE9PWUubmFtZSl0aHJvdyBlO3JldHVybi1lLmVycm5vfX0sYTpmdW5jdGlvbihlLHIsdCl7ZGUudmFyYXJncz10O3RyeXt2YXIgbj1kZS5nZXRTdHJlYW1Gcm9tRkQoZSk7c3dpdGNoKHIpe2Nhc2UgMDppZigobz1kZS5nZXQoKSk8MClyZXR1cm4tMjg7Zm9yKDtsZS5zdHJlYW1zW29dOylvKys7cmV0dXJuIGxlLmNyZWF0ZVN0cmVhbShuLG8pLmZkO2Nhc2UgMTpjYXNlIDI6Y2FzZSA2OmNhc2UgNzpyZXR1cm4gMDtjYXNlIDM6cmV0dXJuIG4uZmxhZ3M7Y2FzZSA0OnZhciBvPWRlLmdldCgpO3JldHVybiBuLmZsYWdzfD1vLDA7Y2FzZSA1OnJldHVybiBvPWRlLmdldHAoKSxTW28rMD4+MV09MiwwO2Nhc2UgMTY6Y2FzZSA4OmRlZmF1bHQ6cmV0dXJuLTI4O2Nhc2UgOTpyZXR1cm4gaGUoMjgpLC0xfX1jYXRjaChlKXtpZih2b2lkIDA9PT1sZXx8IkVycm5vRXJyb3IiIT09ZS5uYW1lKXRocm93IGU7cmV0dXJuLWUuZXJybm99fSx4OmZ1bmN0aW9uKGUscil7dHJ5e3ZhciB0PWRlLmdldFN0cmVhbUZyb21GRChlKTtyZXR1cm4gZGUuZG9TdGF0KGxlLnN0YXQsdC5wYXRoLHIpfWNhdGNoKGUpe2lmKHZvaWQgMD09PWxlfHwiRXJybm9FcnJvciIhPT1lLm5hbWUpdGhyb3cgZTtyZXR1cm4tZS5lcnJub319LHU6ZnVuY3Rpb24oZSxyKXt0cnl7cmV0dXJuIGU9ZGUuZ2V0U3RyKGUpLGRlLmRvU3RhdChsZS5sc3RhdCxlLHIpfWNhdGNoKGUpe2lmKHZvaWQgMD09PWxlfHwiRXJybm9FcnJvciIhPT1lLm5hbWUpdGhyb3cgZTtyZXR1cm4tZS5lcnJub319LHY6ZnVuY3Rpb24oZSxyLHQsbil7dHJ5e3I9ZGUuZ2V0U3RyKHIpO3ZhciBvPTI1NiZuLGE9NDA5NiZuO3JldHVybiBuJj0tNjQwMSxyPWRlLmNhbGN1bGF0ZUF0KGUscixhKSxkZS5kb1N0YXQobz9sZS5sc3RhdDpsZS5zdGF0LHIsdCl9Y2F0Y2goZSl7aWYodm9pZCAwPT09bGV8fCJFcnJub0Vycm9yIiE9PWUubmFtZSl0aHJvdyBlO3JldHVybi1lLmVycm5vfX0seTpmdW5jdGlvbihlLHIsdCxuKXtkZS52YXJhcmdzPW47dHJ5e3I9ZGUuZ2V0U3RyKHIpLHI9ZGUuY2FsY3VsYXRlQXQoZSxyKTt2YXIgbz1uP2RlLmdldCgpOjA7cmV0dXJuIGxlLm9wZW4ocix0LG8pLmZkfWNhdGNoKGUpe2lmKHZvaWQgMD09PWxlfHwiRXJybm9FcnJvciIhPT1lLm5hbWUpdGhyb3cgZTtyZXR1cm4tZS5lcnJub319LHQ6ZnVuY3Rpb24oZSl7dHJ5e2lmKDA9PWUpdGhyb3cgbmV3IGxlLkVycm5vRXJyb3IoMjEpO3ZhciByPWZlLmNyZWF0ZVBpcGUoKTtyZXR1cm4gRltlPj4yXT1yLnJlYWRhYmxlX2ZkLEZbZSs0Pj4yXT1yLndyaXRhYmxlX2ZkLDB9Y2F0Y2goZSl7aWYodm9pZCAwPT09bGV8fCJFcnJub0Vycm9yIiE9PWUubmFtZSl0aHJvdyBlO3JldHVybi1lLmVycm5vfX0sczpmdW5jdGlvbihlLHIsdCl7dHJ5e2Zvcih2YXIgbj0wLG89MDtvPHI7bysrKXt2YXIgYT1lKzgqbyxzPUZbYT4+Ml0saT1TW2ErND4+MV0sdT0zMixsPWxlLmdldFN0cmVhbShzKTtsJiYodT1kZS5ERUZBVUxUX1BPTExNQVNLLGwuc3RyZWFtX29wcy5wb2xsJiYodT1sLnN0cmVhbV9vcHMucG9sbChsLC0xKSkpLCh1Jj0yNHxpKSYmbisrLFNbYSs2Pj4xXT11fXJldHVybiBufWNhdGNoKGUpe2lmKHZvaWQgMD09PWxlfHwiRXJybm9FcnJvciIhPT1lLm5hbWUpdGhyb3cgZTtyZXR1cm4tZS5lcnJub319LHc6ZnVuY3Rpb24oZSxyKXt0cnl7cmV0dXJuIGU9ZGUuZ2V0U3RyKGUpLGRlLmRvU3RhdChsZS5zdGF0LGUscil9Y2F0Y2goZSl7aWYodm9pZCAwPT09bGV8fCJFcnJub0Vycm9yIiE9PWUubmFtZSl0aHJvdyBlO3JldHVybi1lLmVycm5vfX0scTpmdW5jdGlvbihlLHIsdCl7dHJ5e3JldHVybiByPWRlLmdldFN0cihyKSxyPWRlLmNhbGN1bGF0ZUF0KGUsciksMD09PXQ/bGUudW5saW5rKHIpOjUxMj09PXQ/bGUucm1kaXIocik6TygiSW52YWxpZCBmbGFncyBwYXNzZWQgdG8gdW5saW5rYXQiKSwwfWNhdGNoKGUpe2lmKHZvaWQgMD09PWxlfHwiRXJybm9FcnJvciIhPT1lLm5hbWUpdGhyb3cgZTtyZXR1cm4tZS5lcnJub319LEI6KCk9PjEsazpmdW5jdGlvbihlLHIsdCl7dmFyIG49bWUoZSxyKSxvPW5ldyBEYXRlKDFlMypuKTtGW3Q+PjJdPW8uZ2V0VVRDU2Vjb25kcygpLEZbdCs0Pj4yXT1vLmdldFVUQ01pbnV0ZXMoKSxGW3QrOD4+Ml09by5nZXRVVENIb3VycygpLEZbdCsxMj4+Ml09by5nZXRVVENEYXRlKCksRlt0KzE2Pj4yXT1vLmdldFVUQ01vbnRoKCksRlt0KzIwPj4yXT1vLmdldFVUQ0Z1bGxZZWFyKCktMTkwMCxGW3QrMjQ+PjJdPW8uZ2V0VVRDRGF5KCk7dmFyIGE9RGF0ZS5VVEMoby5nZXRVVENGdWxsWWVhcigpLDAsMSwwLDAsMCwwKSxzPShvLmdldFRpbWUoKS1hKS84NjRlNXwwO0ZbdCsyOD4+Ml09c30sbDpmdW5jdGlvbihlLHIsdCl7dmFyIG49bWUoZSxyKSxvPW5ldyBEYXRlKDFlMypuKTtGW3Q+PjJdPW8uZ2V0U2Vjb25kcygpLEZbdCs0Pj4yXT1vLmdldE1pbnV0ZXMoKSxGW3QrOD4+Ml09by5nZXRIb3VycygpLEZbdCsxMj4+Ml09by5nZXREYXRlKCksRlt0KzE2Pj4yXT1vLmdldE1vbnRoKCksRlt0KzIwPj4yXT1vLmdldEZ1bGxZZWFyKCktMTkwMCxGW3QrMjQ+PjJdPW8uZ2V0RGF5KCk7dmFyIGE9MHxnZShvKTtGW3QrMjg+PjJdPWEsRlt0KzM2Pj4yXT0tNjAqby5nZXRUaW1lem9uZU9mZnNldCgpO3ZhciBzPW5ldyBEYXRlKG8uZ2V0RnVsbFllYXIoKSwwLDEpLGk9bmV3IERhdGUoby5nZXRGdWxsWWVhcigpLDYsMSkuZ2V0VGltZXpvbmVPZmZzZXQoKSx1PXMuZ2V0VGltZXpvbmVPZmZzZXQoKSxsPTB8KGkhPXUmJm8uZ2V0VGltZXpvbmVPZmZzZXQoKT09TWF0aC5taW4odSxpKSk7Rlt0KzMyPj4yXT1sfSxtOmZ1bmN0aW9uKGUpe3ZhciByPSgoKT0+e3ZhciByPW5ldyBEYXRlKEZbZSsyMD4+Ml0rMTkwMCxGW2UrMTY+PjJdLEZbZSsxMj4+Ml0sRltlKzg+PjJdLEZbZSs0Pj4yXSxGW2U+PjJdLDApLHQ9RltlKzMyPj4yXSxuPXIuZ2V0VGltZXpvbmVPZmZzZXQoKSxvPW5ldyBEYXRlKHIuZ2V0RnVsbFllYXIoKSwwLDEpLGE9bmV3IERhdGUoci5nZXRGdWxsWWVhcigpLDYsMSkuZ2V0VGltZXpvbmVPZmZzZXQoKSxzPW8uZ2V0VGltZXpvbmVPZmZzZXQoKSxpPU1hdGgubWluKHMsYSk7aWYodDwwKUZbZSszMj4+Ml09TnVtYmVyKGEhPXMmJmk9PW4pO2Vsc2UgaWYodD4wIT0oaT09bikpe3ZhciB1PU1hdGgubWF4KHMsYSksbD10PjA/aTp1O3Iuc2V0VGltZShyLmdldFRpbWUoKSs2ZTQqKGwtbikpfUZbZSsyND4+Ml09ci5nZXREYXkoKTt2YXIgYz0wfGdlKHIpO0ZbZSsyOD4+Ml09YyxGW2U+PjJdPXIuZ2V0U2Vjb25kcygpLEZbZSs0Pj4yXT1yLmdldE1pbnV0ZXMoKSxGW2UrOD4+Ml09ci5nZXRIb3VycygpLEZbZSsxMj4+Ml09ci5nZXREYXRlKCksRltlKzE2Pj4yXT1yLmdldE1vbnRoKCksRltlKzIwPj4yXT1yLmdldFllYXIoKTt2YXIgZD1yLmdldFRpbWUoKTtyZXR1cm4gaXNOYU4oZCk/KGhlKDYxKSwtMSk6ZC8xZTN9KSgpO3JldHVybiBCZSgoaj1yLCtNYXRoLmFicyhqKT49MT9qPjA/K01hdGguZmxvb3Ioai80Mjk0OTY3Mjk2KT4+PjA6fn4rTWF0aC5jZWlsKChqLSsofn5qPj4+MCkpLzQyOTQ5NjcyOTYpPj4+MDowKSkscj4+PjB9LG46ZnVuY3Rpb24oZSl7dmFyIHI9KCgpPT57dmFyIHI9RGF0ZS5VVEMoRltlKzIwPj4yXSsxOTAwLEZbZSsxNj4+Ml0sRltlKzEyPj4yXSxGW2UrOD4+Ml0sRltlKzQ+PjJdLEZbZT4+Ml0sMCksdD1uZXcgRGF0ZShyKTtGW2UrMjQ+PjJdPXQuZ2V0VVRDRGF5KCk7dmFyIG49RGF0ZS5VVEModC5nZXRVVENGdWxsWWVhcigpLDAsMSwwLDAsMCwwKSxvPSh0LmdldFRpbWUoKS1uKS84NjRlNXwwO3JldHVybiBGW2UrMjg+PjJdPW8sdC5nZXRUaW1lKCkvMWUzfSkoKTtyZXR1cm4gQmUoKGo9ciwrTWF0aC5hYnMoaik+PTE/aj4wPytNYXRoLmZsb29yKGovNDI5NDk2NzI5Nik+Pj4wOn5+K01hdGguY2VpbCgoai0rKH5+aj4+PjApKS80Mjk0OTY3Mjk2KT4+PjA6MCkpLHI+Pj4wfSxyOihlLHIsdCk9Pnt2YXIgbj0obmV3IERhdGUpLmdldEZ1bGxZZWFyKCksbz1uZXcgRGF0ZShuLDAsMSksYT1uZXcgRGF0ZShuLDYsMSkscz1vLmdldFRpbWV6b25lT2Zmc2V0KCksaT1hLmdldFRpbWV6b25lT2Zmc2V0KCksdT1NYXRoLm1heChzLGkpO2Z1bmN0aW9uIGwoZSl7dmFyIHI9ZS50b1RpbWVTdHJpbmcoKS5tYXRjaCgvXCgoW0EtWmEteiBdKylcKSQvKTtyZXR1cm4gcj9yWzFdOiJHTVQifURbZT4+Ml09NjAqdSxGW3I+PjJdPU51bWJlcihzIT1pKTt2YXIgYz1sKG8pLGQ9bChhKSxoPXllKGMpLGY9eWUoZCk7aTxzPyhEW3Q+PjJdPWgsRFt0KzQ+PjJdPWYpOihEW3Q+PjJdPWYsRFt0KzQ+PjJdPWgpfSxiOigpPT57TygiIil9LGM6KCk9PkRhdGUubm93KCksaDooZSxyLHQpPT5rLmNvcHlXaXRoaW4oZSxyLHIrdCkscDplPT57dmFyIHI9ay5sZW5ndGgsdD0yMTQ3NDgzNjQ4O2lmKChlPj4+PTApPnQpcmV0dXJuITE7Zm9yKHZhciBuLG8sYT0xO2E8PTQ7YSo9Mil7dmFyIHM9ciooMSsuMi9hKTtzPU1hdGgubWluKHMsZSsxMDA2NjMyOTYpO3ZhciBpPU1hdGgubWluKHQsKG49TWF0aC5tYXgoZSxzKSkrKChvPTY1NTM2KS1uJW8pJW8pO2lmKEVlKGkpKXJldHVybiEwfXJldHVybiExfSx6OihlLHIpPT57dmFyIHQ9MDtyZXR1cm4ga2UoKS5mb3JFYWNoKCgobixvKT0+e3ZhciBhPXIrdDtEW2UrNCpvPj4yXT1hLCgoZSxyKT0+e2Zvcih2YXIgdD0wO3Q8ZS5sZW5ndGg7Kyt0KUVbcisrPj4wXT1lLmNoYXJDb2RlQXQodCk7RVtyPj4wXT0wfSkobixhKSx0Kz1uLmxlbmd0aCsxfSkpLDB9LEE6KGUscik9Pnt2YXIgdD1rZSgpO0RbZT4+Ml09dC5sZW5ndGg7dmFyIG49MDtyZXR1cm4gdC5mb3JFYWNoKChlPT5uKz1lLmxlbmd0aCsxKSksRFtyPj4yXT1uLDB9LGc6RmUsZTpmdW5jdGlvbihlKXt0cnl7dmFyIHI9ZGUuZ2V0U3RyZWFtRnJvbUZEKGUpO3JldHVybiBsZS5jbG9zZShyKSwwfWNhdGNoKGUpe2lmKHZvaWQgMD09PWxlfHwiRXJybm9FcnJvciIhPT1lLm5hbWUpdGhyb3cgZTtyZXR1cm4gZS5lcnJub319LGo6ZnVuY3Rpb24oZSxyLHQsbil7dHJ5e3ZhciBvPSgoZSxyLHQsbik9Pntmb3IodmFyIG89MCxhPTA7YTx0O2ErKyl7dmFyIHM9RFtyPj4yXSxpPURbcis0Pj4yXTtyKz04O3ZhciB1PWxlLnJlYWQoZSxFLHMsaSxuKTtpZih1PDApcmV0dXJuLTE7aWYobys9dSx1PGkpYnJlYWs7dm9pZCAwIT09biYmKG4rPXUpfXJldHVybiBvfSkoZGUuZ2V0U3RyZWFtRnJvbUZEKGUpLHIsdCk7cmV0dXJuIERbbj4+Ml09bywwfWNhdGNoKGUpe2lmKHZvaWQgMD09PWxlfHwiRXJybm9FcnJvciIhPT1lLm5hbWUpdGhyb3cgZTtyZXR1cm4gZS5lcnJub319LG86ZnVuY3Rpb24oZSxyLHQsbixvKXt2YXIgYT1tZShyLHQpO3RyeXtpZihpc05hTihhKSlyZXR1cm4gNjE7dmFyIHM9ZGUuZ2V0U3RyZWFtRnJvbUZEKGUpO3JldHVybiBsZS5sbHNlZWsocyxhLG4pLEk9W3MucG9zaXRpb24+Pj4wLChqPXMucG9zaXRpb24sK01hdGguYWJzKGopPj0xP2o+MD8rTWF0aC5mbG9vcihqLzQyOTQ5NjcyOTYpPj4+MDp+fitNYXRoLmNlaWwoKGotKyh+fmo+Pj4wKSkvNDI5NDk2NzI5Nik+Pj4wOjApXSxGW28+PjJdPUlbMF0sRltvKzQ+PjJdPUlbMV0scy5nZXRkZW50cyYmMD09PWEmJjA9PT1uJiYocy5nZXRkZW50cz1udWxsKSwwfWNhdGNoKGUpe2lmKHZvaWQgMD09PWxlfHwiRXJybm9FcnJvciIhPT1lLm5hbWUpdGhyb3cgZTtyZXR1cm4gZS5lcnJub319LGQ6ZnVuY3Rpb24oZSxyLHQsbil7dHJ5e3ZhciBvPSgoZSxyLHQsbik9Pntmb3IodmFyIG89MCxhPTA7YTx0O2ErKyl7dmFyIHM9RFtyPj4yXSxpPURbcis0Pj4yXTtyKz04O3ZhciB1PWxlLndyaXRlKGUsRSxzLGksbik7aWYodTwwKXJldHVybi0xO28rPXUsdm9pZCAwIT09biYmKG4rPXUpfXJldHVybiBvfSkoZGUuZ2V0U3RyZWFtRnJvbUZEKGUpLHIsdCk7cmV0dXJuIERbbj4+Ml09bywwfWNhdGNoKGUpe2lmKHZvaWQgMD09PWxlfHwiRXJybm9FcnJvciIhPT1lLm5hbWUpdGhyb3cgZTtyZXR1cm4gZS5lcnJub319LGY6KGUscix0LG4pPT57dmFyIG89RFtuKzQwPj4yXSxhPXt0bV9zZWM6RltuPj4yXSx0bV9taW46RltuKzQ+PjJdLHRtX2hvdXI6RltuKzg+PjJdLHRtX21kYXk6RltuKzEyPj4yXSx0bV9tb246RltuKzE2Pj4yXSx0bV95ZWFyOkZbbisyMD4+Ml0sdG1fd2RheTpGW24rMjQ+PjJdLHRtX3lkYXk6RltuKzI4Pj4yXSx0bV9pc2RzdDpGW24rMzI+PjJdLHRtX2dtdG9mZjpGW24rMzY+PjJdLHRtX3pvbmU6bz9jZShvKToiIn0scz1jZSh0KSxpPXsiJWMiOiIlYSAlYiAlZCAlSDolTTolUyAlWSIsIiVEIjoiJW0vJWQvJXkiLCIlRiI6IiVZLSVtLSVkIiwiJWgiOiIlYiIsIiVyIjoiJUk6JU06JVMgJXAiLCIlUiI6IiVIOiVNIiwiJVQiOiIlSDolTTolUyIsIiV4IjoiJW0vJWQvJXkiLCIlWCI6IiVIOiVNOiVTIiwiJUVjIjoiJWMiLCIlRUMiOiIlQyIsIiVFeCI6IiVtLyVkLyV5IiwiJUVYIjoiJUg6JU06JVMiLCIlRXkiOiIleSIsIiVFWSI6IiVZIiwiJU9kIjoiJWQiLCIlT2UiOiIlZSIsIiVPSCI6IiVIIiwiJU9JIjoiJUkiLCIlT20iOiIlbSIsIiVPTSI6IiVNIiwiJU9TIjoiJVMiLCIlT3UiOiIldSIsIiVPVSI6IiVVIiwiJU9WIjoiJVYiLCIlT3ciOiIldyIsIiVPVyI6IiVXIiwiJU95IjoiJXkifTtmb3IodmFyIHUgaW4gaSlzPXMucmVwbGFjZShuZXcgUmVnRXhwKHUsImciKSxpW3VdKTt2YXIgbD1bIlN1bmRheSIsIk1vbmRheSIsIlR1ZXNkYXkiLCJXZWRuZXNkYXkiLCJUaHVyc2RheSIsIkZyaWRheSIsIlNhdHVyZGF5Il0sYz1bIkphbnVhcnkiLCJGZWJydWFyeSIsIk1hcmNoIiwiQXByaWwiLCJNYXkiLCJKdW5lIiwiSnVseSIsIkF1Z3VzdCIsIlNlcHRlbWJlciIsIk9jdG9iZXIiLCJOb3ZlbWJlciIsIkRlY2VtYmVyIl07ZnVuY3Rpb24gZChlLHIsdCl7Zm9yKHZhciBuPSJudW1iZXIiPT10eXBlb2YgZT9lLnRvU3RyaW5nKCk6ZXx8IiI7bi5sZW5ndGg8cjspbj10WzBdK247cmV0dXJuIG59ZnVuY3Rpb24gaChlLHIpe3JldHVybiBkKGUsciwiMCIpfWZ1bmN0aW9uIGYoZSxyKXtmdW5jdGlvbiB0KGUpe3JldHVybiBlPDA/LTE6ZT4wPzE6MH12YXIgbjtyZXR1cm4gMD09PShuPXQoZS5nZXRGdWxsWWVhcigpLXIuZ2V0RnVsbFllYXIoKSkpJiYwPT09KG49dChlLmdldE1vbnRoKCktci5nZXRNb250aCgpKSkmJihuPXQoZS5nZXREYXRlKCktci5nZXREYXRlKCkpKSxufWZ1bmN0aW9uIG0oZSl7c3dpdGNoKGUuZ2V0RGF5KCkpe2Nhc2UgMDpyZXR1cm4gbmV3IERhdGUoZS5nZXRGdWxsWWVhcigpLTEsMTEsMjkpO2Nhc2UgMTpyZXR1cm4gZTtjYXNlIDI6cmV0dXJuIG5ldyBEYXRlKGUuZ2V0RnVsbFllYXIoKSwwLDMpO2Nhc2UgMzpyZXR1cm4gbmV3IERhdGUoZS5nZXRGdWxsWWVhcigpLDAsMik7Y2FzZSA0OnJldHVybiBuZXcgRGF0ZShlLmdldEZ1bGxZZWFyKCksMCwxKTtjYXNlIDU6cmV0dXJuIG5ldyBEYXRlKGUuZ2V0RnVsbFllYXIoKS0xLDExLDMxKTtjYXNlIDY6cmV0dXJuIG5ldyBEYXRlKGUuZ2V0RnVsbFllYXIoKS0xLDExLDMwKX19ZnVuY3Rpb24gcChlKXt2YXIgcj0oKGUscik9Pntmb3IodmFyIHQ9bmV3IERhdGUoZS5nZXRUaW1lKCkpO3I+MDspe3ZhciBuPXBlKHQuZ2V0RnVsbFllYXIoKSksbz10LmdldE1vbnRoKCksYT0obj9EZTpNZSlbb107aWYoIShyPmEtdC5nZXREYXRlKCkpKXJldHVybiB0LnNldERhdGUodC5nZXREYXRlKCkrciksdDtyLT1hLXQuZ2V0RGF0ZSgpKzEsdC5zZXREYXRlKDEpLG88MTE/dC5zZXRNb250aChvKzEpOih0LnNldE1vbnRoKDApLHQuc2V0RnVsbFllYXIodC5nZXRGdWxsWWVhcigpKzEpKX1yZXR1cm4gdH0pKG5ldyBEYXRlKGUudG1feWVhcisxOTAwLDAsMSksZS50bV95ZGF5KSx0PW5ldyBEYXRlKHIuZ2V0RnVsbFllYXIoKSwwLDQpLG49bmV3IERhdGUoci5nZXRGdWxsWWVhcigpKzEsMCw0KSxvPW0odCksYT1tKG4pO3JldHVybiBmKG8scik8PTA/ZihhLHIpPD0wP3IuZ2V0RnVsbFllYXIoKSsxOnIuZ2V0RnVsbFllYXIoKTpyLmdldEZ1bGxZZWFyKCktMX12YXIgdj17IiVhIjplPT5sW2UudG1fd2RheV0uc3Vic3RyaW5nKDAsMyksIiVBIjplPT5sW2UudG1fd2RheV0sIiViIjplPT5jW2UudG1fbW9uXS5zdWJzdHJpbmcoMCwzKSwiJUIiOmU9PmNbZS50bV9tb25dLCIlQyI6ZT0+aCgoZS50bV95ZWFyKzE5MDApLzEwMHwwLDIpLCIlZCI6ZT0+aChlLnRtX21kYXksMiksIiVlIjplPT5kKGUudG1fbWRheSwyLCIgIiksIiVnIjplPT5wKGUpLnRvU3RyaW5nKCkuc3Vic3RyaW5nKDIpLCIlRyI6ZT0+cChlKSwiJUgiOmU9PmgoZS50bV9ob3VyLDIpLCIlSSI6ZT0+e3ZhciByPWUudG1faG91cjtyZXR1cm4gMD09cj9yPTEyOnI+MTImJihyLT0xMiksaChyLDIpfSwiJWoiOmU9PmgoZS50bV9tZGF5KygoZSxyKT0+e2Zvcih2YXIgdD0wLG49MDtuPD1yO3QrPWVbbisrXSk7cmV0dXJuIHR9KShwZShlLnRtX3llYXIrMTkwMCk/RGU6TWUsZS50bV9tb24tMSksMyksIiVtIjplPT5oKGUudG1fbW9uKzEsMiksIiVNIjplPT5oKGUudG1fbWluLDIpLCIlbiI6KCk9PiJcbiIsIiVwIjplPT5lLnRtX2hvdXI+PTAmJmUudG1faG91cjwxMj8iQU0iOiJQTSIsIiVTIjplPT5oKGUudG1fc2VjLDIpLCIldCI6KCk9PiJcdCIsIiV1IjplPT5lLnRtX3dkYXl8fDcsIiVVIjplPT57dmFyIHI9ZS50bV95ZGF5KzctZS50bV93ZGF5O3JldHVybiBoKE1hdGguZmxvb3Ioci83KSwyKX0sIiVWIjplPT57dmFyIHI9TWF0aC5mbG9vcigoZS50bV95ZGF5KzctKGUudG1fd2RheSs2KSU3KS83KTtpZigoZS50bV93ZGF5KzM3MS1lLnRtX3lkYXktMiklNzw9MiYmcisrLHIpe2lmKDUzPT1yKXt2YXIgdD0oZS50bV93ZGF5KzM3MS1lLnRtX3lkYXkpJTc7ND09dHx8Mz09dCYmcGUoZS50bV95ZWFyKXx8KHI9MSl9fWVsc2V7cj01Mjt2YXIgbj0oZS50bV93ZGF5KzctZS50bV95ZGF5LTEpJTc7KDQ9PW58fDU9PW4mJnBlKGUudG1feWVhciU0MDAtMSkpJiZyKyt9cmV0dXJuIGgociwyKX0sIiV3IjplPT5lLnRtX3dkYXksIiVXIjplPT57dmFyIHI9ZS50bV95ZGF5KzctKGUudG1fd2RheSs2KSU3O3JldHVybiBoKE1hdGguZmxvb3Ioci83KSwyKX0sIiV5IjplPT4oZS50bV95ZWFyKzE5MDApLnRvU3RyaW5nKCkuc3Vic3RyaW5nKDIpLCIlWSI6ZT0+ZS50bV95ZWFyKzE5MDAsIiV6IjplPT57dmFyIHI9ZS50bV9nbXRvZmYsdD1yPj0wO3JldHVybiByPShyPU1hdGguYWJzKHIpLzYwKS82MCoxMDArciU2MCwodD8iKyI6Ii0iKStTdHJpbmcoIjAwMDAiK3IpLnNsaWNlKC00KX0sIiVaIjplPT5lLnRtX3pvbmUsIiUlIjooKT0+IiUifTtmb3IodmFyIHUgaW4gcz1zLnJlcGxhY2UoLyUlL2csIlwwXDAiKSx2KXMuaW5jbHVkZXModSkmJihzPXMucmVwbGFjZShuZXcgUmVnRXhwKHUsImciKSx2W3VdKGEpKSk7dmFyIHc9bmUocz1zLnJlcGxhY2UoL1wwXDAvZywiJSIpLCExKTtyZXR1cm4gdy5sZW5ndGg+cj8wOihBZSh3LGUpLHcubGVuZ3RoLTEpfX0sTGU9ZnVuY3Rpb24oKXt2YXIgZSxyLG8sYSxzPXthOlVlfTtmdW5jdGlvbiBpKGUscil7dmFyIHQ7cmV0dXJuIExlPWUuZXhwb3J0cyxnPUxlLkMsQygpLHQ9TGUuRCxULnVuc2hpZnQodCkseCgpLExlfWlmKEwoKSxuLmluc3RhbnRpYXRlV2FzbSl0cnl7cmV0dXJuIG4uaW5zdGFudGlhdGVXYXNtKHMsaSl9Y2F0Y2goZSl7eShgTW9kdWxlLmluc3RhbnRpYXRlV2FzbSBjYWxsYmFjayBmYWlsZWQgd2l0aCBlcnJvcjogJHtlfWApLHQoZSl9cmV0dXJuKGU9dyxyPU4sbz1zLGE9ZnVuY3Rpb24oZSl7aShlLmluc3RhbmNlKX0sZXx8ImZ1bmN0aW9uIiE9dHlwZW9mIFdlYkFzc2VtYmx5Lmluc3RhbnRpYXRlU3RyZWFtaW5nfHxIKHIpfHxZKHIpfHxofHwiZnVuY3Rpb24iIT10eXBlb2YgZmV0Y2g/SyhyLG8sYSk6ZmV0Y2gocix7Y3JlZGVudGlhbHM6InNhbWUtb3JpZ2luIn0pLnRoZW4oKGU9PldlYkFzc2VtYmx5Lmluc3RhbnRpYXRlU3RyZWFtaW5nKGUsbykudGhlbihhLChmdW5jdGlvbihlKXtyZXR1cm4geShgd2FzbSBzdHJlYW1pbmcgY29tcGlsZSBmYWlsZWQ6ICR7ZX1gKSx5KCJmYWxsaW5nIGJhY2sgdG8gQXJyYXlCdWZmZXIgaW5zdGFudGlhdGlvbiIpLEsocixvLGEpfSkpKSkpLmNhdGNoKHQpLHt9fSgpO24uX2dldF92ZXJzaW9uPSgpPT4obi5fZ2V0X3ZlcnNpb249TGUuRSkoKSxuLl9hcmNoaXZlX29wZW49KGUscix0LG8pPT4obi5fYXJjaGl2ZV9vcGVuPUxlLkYpKGUscix0LG8pLG4uX2FyY2hpdmVfcmVhZF9hZGRfcGFzc3BocmFzZT0oZSxyKT0+KG4uX2FyY2hpdmVfcmVhZF9hZGRfcGFzc3BocmFzZT1MZS5HKShlLHIpLG4uX2FyY2hpdmVfZXJyb3Jfc3RyaW5nPWU9PihuLl9hcmNoaXZlX2Vycm9yX3N0cmluZz1MZS5IKShlKSxuLl9nZXRfbmV4dF9lbnRyeT1lPT4obi5fZ2V0X25leHRfZW50cnk9TGUuSSkoZSksbi5fZ2V0X2ZpbGVkYXRhPShlLHIpPT4obi5fZ2V0X2ZpbGVkYXRhPUxlLkopKGUscik7dmFyIHhlPW4uX21hbGxvYz1lPT4oeGU9bi5fbWFsbG9jPUxlLkspKGUpO24uX2FyY2hpdmVfY2xvc2U9ZT0+KG4uX2FyY2hpdmVfY2xvc2U9TGUuTCkoZSksbi5fc3RhcnRfYXJjaGl2ZV93cml0ZT0oZSxyLHQsbyxhLHMpPT4obi5fc3RhcnRfYXJjaGl2ZV93cml0ZT1MZS5NKShlLHIsdCxvLGEscyksbi5fd3JpdGVfYXJjaGl2ZV9maWxlPShlLHIsdCxvKT0+KG4uX3dyaXRlX2FyY2hpdmVfZmlsZT1MZS5OKShlLHIsdCxvKSxuLl9zaXplX29mX3NpemVfdD0oKT0+KG4uX3NpemVfb2Zfc2l6ZV90PUxlLk8pKCksbi5fZmluaXNoX2FyY2hpdmVfd3JpdGU9KGUscik9PihuLl9maW5pc2hfYXJjaGl2ZV93cml0ZT1MZS5QKShlLHIpLG4uX2ZyZWU9ZT0+KG4uX2ZyZWU9TGUuUSkoZSk7dmFyIE9lPSgpPT4oT2U9TGUuUikoKTtuLl9hcmNoaXZlX2VudHJ5X2JpcnRodGltZV9uc2VjPWU9PihuLl9hcmNoaXZlX2VudHJ5X2JpcnRodGltZV9uc2VjPUxlLlMpKGUpLG4uX2FyY2hpdmVfZW50cnlfZmlsZXR5cGU9ZT0+KG4uX2FyY2hpdmVfZW50cnlfZmlsZXR5cGU9TGUuVCkoZSksbi5fYXJjaGl2ZV9lbnRyeV9tdGltZV9uc2VjPWU9PihuLl9hcmNoaXZlX2VudHJ5X210aW1lX25zZWM9TGUuVSkoZSksbi5fYXJjaGl2ZV9lbnRyeV9wYXRobmFtZT1lPT4obi5fYXJjaGl2ZV9lbnRyeV9wYXRobmFtZT1MZS5WKShlKSxuLl9hcmNoaXZlX2VudHJ5X3BhdGhuYW1lX3V0Zjg9ZT0+KG4uX2FyY2hpdmVfZW50cnlfcGF0aG5hbWVfdXRmOD1MZS5XKShlKSxuLl9hcmNoaXZlX2VudHJ5X3NpemU9ZT0+KG4uX2FyY2hpdmVfZW50cnlfc2l6ZT1MZS5YKShlKSxuLl9hcmNoaXZlX2VudHJ5X2lzX2VuY3J5cHRlZD1lPT4obi5fYXJjaGl2ZV9lbnRyeV9pc19lbmNyeXB0ZWQ9TGUuWSkoZSksbi5fYXJjaGl2ZV9yZWFkX2hhc19lbmNyeXB0ZWRfZW50cmllcz1lPT4obi5fYXJjaGl2ZV9yZWFkX2hhc19lbmNyeXB0ZWRfZW50cmllcz1MZS5aKShlKSxuLl9hcmNoaXZlX3JlYWRfZGF0YV9za2lwPWU9PihuLl9hcmNoaXZlX3JlYWRfZGF0YV9za2lwPUxlLl8pKGUpO3ZhciBOZSxCZT1lPT4oQmU9TGUuYWEpKGUpLGplPSgpPT4oamU9TGUuYmEpKCksSWU9ZT0+KEllPUxlLmNhKShlKSxIZT1lPT4oSGU9TGUuZGEpKGUpO2Z1bmN0aW9uIFllKCl7ZnVuY3Rpb24gZSgpe05lfHwoTmU9ITAsbi5jYWxsZWRSdW49ITAsTXx8KG4ubm9GU0luaXR8fGxlLmluaXQuaW5pdGlhbGl6ZWR8fGxlLmluaXQoKSxsZS5pZ25vcmVQZXJtaXNzaW9ucz0hMSxmZS5yb290PWxlLm1vdW50KGZlLHt9LG51bGwpLCQoVCkscihuKSxuLm9uUnVudGltZUluaXRpYWxpemVkJiZuLm9uUnVudGltZUluaXRpYWxpemVkKCksZnVuY3Rpb24oKXtpZihuLnBvc3RSdW4pZm9yKCJmdW5jdGlvbiI9PXR5cGVvZiBuLnBvc3RSdW4mJihuLnBvc3RSdW49W24ucG9zdFJ1bl0pO24ucG9zdFJ1bi5sZW5ndGg7KWU9bi5wb3N0UnVuLnNoaWZ0KCksUi51bnNoaWZ0KGUpO3ZhciBlOyQoUil9KCkpKX16PjB8fChmdW5jdGlvbigpe2lmKG4ucHJlUnVuKWZvcigiZnVuY3Rpb24iPT10eXBlb2Ygbi5wcmVSdW4mJihuLnByZVJ1bj1bbi5wcmVSdW5dKTtuLnByZVJ1bi5sZW5ndGg7KWU9bi5wcmVSdW4uc2hpZnQoKSxQLnVuc2hpZnQoZSk7dmFyIGU7JChQKX0oKSx6PjB8fChuLnNldFN0YXR1cz8obi5zZXRTdGF0dXMoIlJ1bm5pbmcuLi4iKSxzZXRUaW1lb3V0KChmdW5jdGlvbigpe3NldFRpbWVvdXQoKGZ1bmN0aW9uKCl7bi5zZXRTdGF0dXMoIiIpfSksMSksZSgpfSksMSkpOmUoKSkpfWlmKG4uY3dyYXA9KGUscix0LG4pPT57dmFyIG89IXR8fHQuZXZlcnkoKGU9PiJudW1iZXIiPT09ZXx8ImJvb2xlYW4iPT09ZSkpO3JldHVybiJzdHJpbmciIT09ciYmbyYmIW4/Q2UoZSk6ZnVuY3Rpb24oKXtyZXR1cm4gUGUoZSxyLHQsYXJndW1lbnRzKX19LG4uYWxsb2NhdGU9KGUscik9Pnt2YXIgdDtyZXR1cm4gdD0xPT1yP0hlKGUubGVuZ3RoKTp4ZShlLmxlbmd0aCksZS5zdWJhcnJheXx8ZS5zbGljZXx8KGU9bmV3IFVpbnQ4QXJyYXkoZSkpLGsuc2V0KGUsdCksdH0sVT1mdW5jdGlvbiBlKCl7TmV8fFllKCksTmV8fChVPWUpfSxuLnByZUluaXQpZm9yKCJmdW5jdGlvbiI9PXR5cGVvZiBuLnByZUluaXQmJihuLnByZUluaXQ9W24ucHJlSW5pdF0pO24ucHJlSW5pdC5sZW5ndGg+MDspbi5wcmVJbml0LnBvcCgpKCk7cmV0dXJuIFllKCksZS5yZWFkeX0pO2NsYXNzIFN7Y29uc3RydWN0b3IoKXt0aGlzLnByZVJ1bj1bXSx0aGlzLnBvc3RSdW49W10sdGhpcy50b3RhbERlcGVuZGVuY2llcz0wfXByaW50KC4uLmUpe2NvbnNvbGUubG9nKGUpfXByaW50RXJyKC4uLmUpe2NvbnNvbGUuZXJyb3IoZSl9aW5pdEZ1bmN0aW9ucygpe3RoaXMucnVuQ29kZT17Z2V0VmVyc2lvbjp0aGlzLmN3cmFwKCJnZXRfdmVyc2lvbiIsInN0cmluZyIsW10pLG9wZW5BcmNoaXZlOnRoaXMuY3dyYXAoImFyY2hpdmVfb3BlbiIsIm51bWJlciIsWyJudW1iZXIiLCJudW1iZXIiLCJzdHJpbmciLCJzdHJpbmciXSksZ2V0TmV4dEVudHJ5OnRoaXMuY3dyYXAoImdldF9uZXh0X2VudHJ5IiwibnVtYmVyIixbIm51bWJlciJdKSxnZXRGaWxlRGF0YTp0aGlzLmN3cmFwKCJnZXRfZmlsZWRhdGEiLCJudW1iZXIiLFsibnVtYmVyIiwibnVtYmVyIl0pLHNraXBFbnRyeTp0aGlzLmN3cmFwKCJhcmNoaXZlX3JlYWRfZGF0YV9za2lwIiwibnVtYmVyIixbIm51bWJlciJdKSxjbG9zZUFyY2hpdmU6dGhpcy5jd3JhcCgiYXJjaGl2ZV9jbG9zZSIsbnVsbCxbIm51bWJlciJdKSxnZXRFbnRyeVNpemU6dGhpcy5jd3JhcCgiYXJjaGl2ZV9lbnRyeV9zaXplIiwibnVtYmVyIixbIm51bWJlciJdKSxnZXRFbnRyeU5hbWU6dGhpcy5jd3JhcCgiYXJjaGl2ZV9lbnRyeV9wYXRobmFtZSIsInN0cmluZyIsWyJudW1iZXIiXSksZ2V0RW50cnlUeXBlOnRoaXMuY3dyYXAoImFyY2hpdmVfZW50cnlfZmlsZXR5cGUiLCJudW1iZXIiLFsibnVtYmVyIl0pLGdldEVudHJ5TGFzdE1vZGlmaWVkOnRoaXMuY3dyYXAoImFyY2hpdmVfZW50cnlfbXRpbWVfbnNlYyIsIm51bWJlciIsWyJudW1iZXIiXSksZ2V0RXJyb3I6dGhpcy5jd3JhcCgiYXJjaGl2ZV9lcnJvcl9zdHJpbmciLCJzdHJpbmciLFsibnVtYmVyIl0pLHN0YXJ0QXJjaGl2ZVdyaXRlOnRoaXMuY3dyYXAoInN0YXJ0X2FyY2hpdmVfd3JpdGUiLCJudW1iZXIiLFsic3RyaW5nIiwic3RyaW5nIiwibnVtYmVyIiwibnVtYmVyIiwibnVtYmVyIiwic3RyaW5nIl0pLHdyaXRlQXJjaGl2ZUZpbGU6dGhpcy5jd3JhcCgid3JpdGVfYXJjaGl2ZV9maWxlIixudWxsLFsibnVtYmVyIiwic3RyaW5nIiwibnVtYmVyIiwibnVtYmVyIl0pLGZpbmlzaEFyY2hpdmVXcml0ZTp0aGlzLmN3cmFwKCJmaW5pc2hfYXJjaGl2ZV93cml0ZSIsIm51bWJlciIsWyJudW1iZXIiLCJudW1iZXIiXSksZW50cnlJc0VuY3J5cHRlZDp0aGlzLmN3cmFwKCJhcmNoaXZlX2VudHJ5X2lzX2VuY3J5cHRlZCIsIm51bWJlciIsWyJudW1iZXIiXSksaGFzRW5jcnlwdGVkRW50cmllczp0aGlzLmN3cmFwKCJhcmNoaXZlX3JlYWRfaGFzX2VuY3J5cHRlZF9lbnRyaWVzIiwibnVtYmVyIixbIm51bWJlciJdKSxhZGRQYXNzcGhyYXNlOnRoaXMuY3dyYXAoImFyY2hpdmVfcmVhZF9hZGRfcGFzc3BocmFzZSIsIm51bWJlciIsWyJudW1iZXIiLCJzdHJpbmciXSksc3RyaW5nOmU9PnRoaXMuYWxsb2NhdGUodGhpcy5pbnRBcnJheUZyb21TdHJpbmcoZSksImk4IiwwKSxtYWxsb2M6dGhpcy5jd3JhcCgibWFsbG9jIiwibnVtYmVyIixbIm51bWJlciJdKSxmcmVlOnRoaXMuY3dyYXAoImZyZWUiLG51bGwsWyJudW1iZXIiXSksc2l6ZU9mU2l6ZVQ6dGhpcy5jd3JhcCgic2l6ZV9vZl9zaXplX3QiLCJudW1iZXIiLFtdKX19bW9uaXRvclJ1bkRlcGVuZGVuY2llcygpe319bGV0IEY9bnVsbCxEPW51bGwsTT0hMTtjbGFzcyBBe2NvbnN0cnVjdG9yKGUpe0EucmVhZHlDYWxsYmFjaz1lLE0mJnNldFRpbWVvdXQoKCgpPT5lKCkpLDApfW9wZW4oZSxyKXtGLm9wZW4oZSkudGhlbigoKCk9PnIoKSkpfWxpc3RGaWxlcygpe2xldCBlPVtdO2Zvcihjb25zdCByIG9mIEYuZW50cmllcyghMCkpZS5wdXNoKHIpO3JldHVybiBlfWV4dHJhY3RGaWxlcygpe2xldCBlPVtdO2Zvcihjb25zdCByIG9mIEYuZW50cmllcyghMSkpZS5wdXNoKHIpO3JldHVybiBlfWV4dHJhY3RTaW5nbGVGaWxlKGUpe2Zvcihjb25zdCByIG9mIEYuZW50cmllcyghMCxlKSlpZihyLmZpbGVEYXRhKXJldHVybiByfWhhc0VuY3J5cHRlZERhdGEoKXtyZXR1cm4gRi5oYXNFbmNyeXB0ZWREYXRhKCl9dXNlUGFzc3dvcmQoZSl7Ri5zZXRQYXNzcGhyYXNlKGUpfXNldExvY2FsZShlKXtGLnNldExvY2FsZShlKX13cml0ZUFyY2hpdmUoZSxyLHQsbil7cmV0dXJuIEQud3JpdGUoZSxyLHQsbil9Y2xvc2UoKXtGLmNsb3NlKCl9fXZhciBDO0M9ZT0+e0Y9bmV3IHkoZSksRD1uZXcgRShlKSxBPy5yZWFkeUNhbGxiYWNrPy4oKSxNPSEwfSxrKG5ldyBTKS50aGVuKChlPT57ZS5pbml0RnVuY3Rpb25zKCksQyhlKX0pKSxpKEEpOwo=", import.meta.url), { type: "module" });
|
|
250
|
+
}
|
|
251
|
+
static async getClient(Z, b) {
|
|
252
|
+
var c;
|
|
253
|
+
const m = ((c = b.createClient) === null || c === void 0 ? void 0 : c.call(b, Z)) || v(Z);
|
|
254
|
+
let { promise: d, resolve: G } = Promise.withResolvers();
|
|
255
|
+
const X = await new m(J((() => {
|
|
256
|
+
G();
|
|
257
|
+
})));
|
|
258
|
+
return await d, X;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
s._options = {}, Promise.withResolvers || (Promise.withResolvers = function() {
|
|
262
|
+
var l, Z, b = new this((function(c, m) {
|
|
263
|
+
l = c, Z = m;
|
|
264
|
+
}));
|
|
265
|
+
return { resolve: l, reject: Z, promise: b };
|
|
266
|
+
});
|
|
267
|
+
export {
|
|
268
|
+
s as Archive,
|
|
269
|
+
F as ArchiveCompression,
|
|
270
|
+
T as ArchiveFormat
|
|
271
|
+
};
|
|
272
|
+
//# sourceMappingURL=libarchive-Bt1VdZR0.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"libarchive-Bt1VdZR0.js","sources":["../node_modules/libarchive.js/dist/libarchive.js"],"sourcesContent":["/**\n * @license\n * Copyright 2019 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\nconst e=Symbol(\"Comlink.proxy\"),t=Symbol(\"Comlink.endpoint\"),n=Symbol(\"Comlink.releaseProxy\"),r=Symbol(\"Comlink.finalizer\"),i=Symbol(\"Comlink.thrown\"),s=e=>\"object\"==typeof e&&null!==e||\"function\"==typeof e,a=new Map([[\"proxy\",{canHandle:t=>s(t)&&t[e],serialize(e){const{port1:t,port2:n}=new MessageChannel;return o(e,t),[n,[n]]},deserialize:e=>(e.start(),l(e))}],[\"throw\",{canHandle:e=>s(e)&&i in e,serialize({value:e}){let t;return t=e instanceof Error?{isError:!0,value:{message:e.message,name:e.name,stack:e.stack}}:{isError:!1,value:e},[t,[]]},deserialize(e){if(e.isError)throw Object.assign(new Error(e.value.message),e.value);throw e.value}}]]);function o(e,t=globalThis,n=[\"*\"]){t.addEventListener(\"message\",(function s(a){if(!a||!a.data)return;if(!function(e,t){for(const n of e){if(t===n||\"*\"===n)return!0;if(n instanceof RegExp&&n.test(t))return!0}return!1}(n,a.origin))return void console.warn(`Invalid origin '${a.origin}' for comlink proxy`);const{id:l,type:u,path:p}=Object.assign({path:[]},a.data),h=(a.data.argumentList||[]).map(v);let f;try{const t=p.slice(0,-1).reduce(((e,t)=>e[t]),e),n=p.reduce(((e,t)=>e[t]),e);switch(u){case\"GET\":f=n;break;case\"SET\":t[p.slice(-1)[0]]=v(a.data.value),f=!0;break;case\"APPLY\":f=n.apply(t,h);break;case\"CONSTRUCT\":f=w(new n(...h));break;case\"ENDPOINT\":{const{port1:t,port2:n}=new MessageChannel;o(e,n),f=function(e,t){return g.set(e,t),e}(t,[t])}break;case\"RELEASE\":f=void 0;break;default:return}}catch(e){f={value:e,[i]:0}}Promise.resolve(f).catch((e=>({value:e,[i]:0}))).then((n=>{const[i,a]=y(n);t.postMessage(Object.assign(Object.assign({},i),{id:l}),a),\"RELEASE\"===u&&(t.removeEventListener(\"message\",s),c(t),r in e&&\"function\"==typeof e[r]&&e[r]())})).catch((e=>{const[n,r]=y({value:new TypeError(\"Unserializable return value\"),[i]:0});t.postMessage(Object.assign(Object.assign({},n),{id:l}),r)}))})),t.start&&t.start()}function c(e){(function(e){return\"MessagePort\"===e.constructor.name})(e)&&e.close()}function l(e,t){return d(e,[],t)}function u(e){if(e)throw new Error(\"Proxy has been released and is not useable\")}function p(e){return E(e,{type:\"RELEASE\"}).then((()=>{c(e)}))}const h=new WeakMap,f=\"FinalizationRegistry\"in globalThis&&new FinalizationRegistry((e=>{const t=(h.get(e)||0)-1;h.set(e,t),0===t&&p(e)}));function d(e,r=[],i=function(){}){let s=!1;const a=new Proxy(i,{get(t,i){if(u(s),i===n)return()=>{!function(e){f&&f.unregister(e)}(a),p(e),s=!0};if(\"then\"===i){if(0===r.length)return{then:()=>a};const t=E(e,{type:\"GET\",path:r.map((e=>e.toString()))}).then(v);return t.then.bind(t)}return d(e,[...r,i])},set(t,n,i){u(s);const[a,o]=y(i);return E(e,{type:\"SET\",path:[...r,n].map((e=>e.toString())),value:a},o).then(v)},apply(n,i,a){u(s);const o=r[r.length-1];if(o===t)return E(e,{type:\"ENDPOINT\"}).then(v);if(\"bind\"===o)return d(e,r.slice(0,-1));const[c,l]=m(a);return E(e,{type:\"APPLY\",path:r.map((e=>e.toString())),argumentList:c},l).then(v)},construct(t,n){u(s);const[i,a]=m(n);return E(e,{type:\"CONSTRUCT\",path:r.map((e=>e.toString())),argumentList:i},a).then(v)}});return function(e,t){const n=(h.get(t)||0)+1;h.set(t,n),f&&f.register(e,t,e)}(a,e),a}function m(e){const t=e.map(y);return[t.map((e=>e[0])),(n=t.map((e=>e[1])),Array.prototype.concat.apply([],n))];var n}const g=new WeakMap;function w(t){return Object.assign(t,{[e]:!0})}function y(e){for(const[t,n]of a)if(n.canHandle(e)){const[r,i]=n.serialize(e);return[{type:\"HANDLER\",name:t,value:r},i]}return[{type:\"RAW\",value:e},g.get(e)||[]]}function v(e){switch(e.type){case\"HANDLER\":return a.get(e.name).deserialize(e.value);case\"RAW\":return e.value}}function E(e,t,n){return new Promise((r=>{const i=new Array(4).fill(0).map((()=>Math.floor(Math.random()*Number.MAX_SAFE_INTEGER).toString(16))).join(\"-\");e.addEventListener(\"message\",(function t(n){n.data&&n.data.id&&n.data.id===i&&(e.removeEventListener(\"message\",t),r(n.data))})),e.start&&e.start(),e.postMessage(Object.assign({id:i},t),n)}))}class R{constructor(e,t,n,r,i){this._name=e,this._size=t,this._path=n,this._lastModified=r,this._archiveRef=i}get name(){return this._name}get size(){return this._size}get lastModified(){return this._lastModified}extract(){return this._archiveRef.extractSingleFile(this._path)}}function b(e){if(e instanceof File||e instanceof R||null===e)return e;const t={};for(const n of Object.keys(e))t[n]=b(e[n]);return t}function P(e,t=\"\"){const n=[];for(const r of Object.keys(e))e[r]instanceof File||e[r]instanceof R||null===e[r]?n.push({file:e[r]||r,path:t}):n.push(...P(e[r],`${t}${r}/`));return n}function S(e,t){const n=t.split(\"/\");\"\"===n[n.length-1]&&n.pop();let r=e,i=null;for(const e of n)r[e]=r[e]||{},i=r,r=r[e];return[i,n[n.length-1]]}class A{constructor(e,t,n){this._content={},this._processed=0,this.file=e,this.client=t,this.worker=n}open(){return this._content={},this._processed=0,new Promise(((e,t)=>{this.client.open(this.file,w((()=>{e(this)})))}))}async close(){var e;null===(e=this.worker)||void 0===e||e.terminate(),this.worker=null,this.client=null,this.file=null}async hasEncryptedData(){return await this.client.hasEncryptedData()}async usePassword(e){await this.client.usePassword(e)}async setLocale(e){await this.client.setLocale(e)}async getFilesObject(){if(this._processed>0)return Promise.resolve().then((()=>this._content));return(await this.client.listFiles()).forEach((e=>{const[t,n]=S(this._content,e.path);\"FILE\"===e.type&&(t[n]=new R(e.fileName,e.size,e.path,e.lastModified,this))})),this._processed=1,b(this._content)}getFilesArray(){return this.getFilesObject().then((e=>P(e)))}async extractSingleFile(e){if(null===this.worker)throw new Error(\"Archive already closed\");const t=await this.client.extractSingleFile(e);return new File([t.fileData],t.fileName,{type:\"application/octet-stream\",lastModified:t.lastModified/1e6})}async extractFiles(e=void 0){var t;if(this._processed>1)return Promise.resolve().then((()=>this._content));return(await this.client.extractFiles()).forEach((t=>{const[n,r]=S(this._content,t.path);\"FILE\"===t.type&&(n[r]=new File([t.fileData],t.fileName,{type:\"application/octet-stream\"}),void 0!==e&&setTimeout(e.bind(null,{file:n[r],path:t.path})))})),this._processed=2,null===(t=this.worker)||void 0===t||t.terminate(),b(this._content)}}var _,k;!function(e){e.SEVEN_ZIP=\"7zip\",e.AR=\"ar\",e.ARBSD=\"arbsd\",e.ARGNU=\"argnu\",e.ARSVR4=\"arsvr4\",e.BIN=\"bin\",e.BSDTAR=\"bsdtar\",e.CD9660=\"cd9660\",e.CPIO=\"cpio\",e.GNUTAR=\"gnutar\",e.ISO=\"iso\",e.ISO9660=\"iso9660\",e.MTREE=\"mtree\",e.MTREE_CLASSIC=\"mtree-classic\",e.NEWC=\"newc\",e.ODC=\"odc\",e.OLDTAR=\"oldtar\",e.PAX=\"pax\",e.PAXR=\"paxr\",e.POSIX=\"posix\",e.PWB=\"pwb\",e.RAW=\"raw\",e.RPAX=\"rpax\",e.SHAR=\"shar\",e.SHARDUMP=\"shardump\",e.USTAR=\"ustar\",e.V7TAR=\"v7tar\",e.V7=\"v7\",e.WARC=\"warc\",e.XAR=\"xar\",e.ZIP=\"zip\"}(_||(_={})),function(e){e.B64ENCODE=\"b64encode\",e.BZIP2=\"bzip2\",e.COMPRESS=\"compress\",e.GRZIP=\"grzip\",e.GZIP=\"gzip\",e.LRZIP=\"lrzip\",e.LZ4=\"lz4\",e.LZIP=\"lzip\",e.LZMA=\"lzma\",e.LZOP=\"lzop\",e.UUENCODE=\"uuencode\",e.XZ=\"xz\",e.ZSTD=\"zstd\",e.NONE=\"none\"}(k||(k={}));class O{static init(e=null){return O._options=e||{},O._options}static async open(e){const t=O.getWorker(O._options),n=await O.getClient(t,O._options),r=new A(e,n,t);return await r.open()}static async write({files:e,outputFileName:t,compression:n,format:r,passphrase:i=null}){const s=O.getWorker(O._options),a=await O.getClient(s,O._options),o=await a.writeArchive(e,n,r,i);return s.terminate(),new File([o],t,{type:\"application/octet-stream\"})}static getWorker(e){return e.getWorker?e.getWorker():new Worker(e.workerUrl||new URL(\"./worker-bundle.js\",import.meta.url),{type:\"module\"})}static async getClient(e,t){var n;const r=(null===(n=t.createClient)||void 0===n?void 0:n.call(t,e))||l(e);let{promise:i,resolve:s}=Promise.withResolvers();const a=await new r(w((()=>{s()})));return await i,a}}O._options={},Promise.withResolvers||(Promise.withResolvers=function(){var e,t,n=new this((function(n,r){e=n,t=r}));return{resolve:e,reject:t,promise:n}});export{O as Archive,k as ArchiveCompression,_ as ArchiveFormat};\n"],"names":["e","t","n","r","i","s","a","o","l","u","p","h","v","f","w","g","y","c","d","E","m","R","b","P","S","A","_","k","O"],"mappings":"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","x_google_ignoreList":[0]}
|
|
@@ -4,10 +4,31 @@ import { LayerRole } from '../io/file-classifier';
|
|
|
4
4
|
* Primitive types used by the geometry pipeline. These are what
|
|
5
5
|
* polygonizer.ts consumes.
|
|
6
6
|
*/
|
|
7
|
+
export type Polarity = "dark" | "clear";
|
|
8
|
+
export type Op = {
|
|
9
|
+
kind: "track";
|
|
10
|
+
polarity: Polarity;
|
|
11
|
+
start: Vec2;
|
|
12
|
+
end: Vec2;
|
|
13
|
+
widthMm: number;
|
|
14
|
+
} | {
|
|
15
|
+
kind: "flash";
|
|
16
|
+
polarity: Polarity;
|
|
17
|
+
position: Vec2;
|
|
18
|
+
diameterMm: number;
|
|
19
|
+
shape: string;
|
|
20
|
+
widthMm?: number;
|
|
21
|
+
heightMm?: number;
|
|
22
|
+
} | {
|
|
23
|
+
kind: "region";
|
|
24
|
+
polarity: Polarity;
|
|
25
|
+
loops: Vec2[][];
|
|
26
|
+
};
|
|
7
27
|
export interface GerberPrimitiveTrack {
|
|
8
28
|
start: Vec2;
|
|
9
29
|
end: Vec2;
|
|
10
30
|
width: number;
|
|
31
|
+
polarity: Polarity;
|
|
11
32
|
}
|
|
12
33
|
export interface GerberPrimitiveArc {
|
|
13
34
|
start: Vec2;
|
|
@@ -19,16 +40,21 @@ export interface GerberPrimitiveArc {
|
|
|
19
40
|
export interface GerberPrimitiveFlash {
|
|
20
41
|
position: Vec2;
|
|
21
42
|
diameterMm: number;
|
|
43
|
+
shape: string;
|
|
44
|
+
widthMm?: number;
|
|
45
|
+
heightMm?: number;
|
|
46
|
+
polarity: Polarity;
|
|
22
47
|
}
|
|
23
48
|
export interface GerberPrimitiveRegion {
|
|
24
|
-
|
|
25
|
-
|
|
49
|
+
loops: Vec2[][];
|
|
50
|
+
polarity: Polarity;
|
|
26
51
|
}
|
|
27
52
|
export interface GerberPrimitives {
|
|
28
53
|
tracks: GerberPrimitiveTrack[];
|
|
29
54
|
arcs: GerberPrimitiveArc[];
|
|
30
55
|
flashes: GerberPrimitiveFlash[];
|
|
31
56
|
regions: GerberPrimitiveRegion[];
|
|
57
|
+
ops: Op[];
|
|
32
58
|
}
|
|
33
59
|
export interface GerberPrimitiveFlash {
|
|
34
60
|
position: Vec2;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { BoardGeom, ViewerLayers } from '../viewer/types';
|
|
2
|
+
export type RenderResult = {
|
|
3
|
+
boardGeom: BoardGeom;
|
|
4
|
+
layers: ViewerLayers;
|
|
5
|
+
revoke: () => void;
|
|
6
|
+
};
|
|
7
|
+
export declare function renderGerbersFiles(files: Record<string, Uint8Array>): Promise<RenderResult>;
|
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export
|
|
3
|
-
|
|
4
|
-
layers: ViewerLayers;
|
|
5
|
-
revoke: () => void;
|
|
6
|
-
};
|
|
7
|
-
export declare function renderGerbersZip(file: File): Promise<RenderResult>;
|
|
1
|
+
import { RenderResult } from './renderGerbersFiles';
|
|
2
|
+
export declare function renderGerbersZip(input: File | Blob | ArrayBuffer | Uint8Array): Promise<RenderResult>;
|
|
3
|
+
export type { RenderResult };
|