@pathscale/rebuild-plugin-ui-css-purge 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +2 -2
- package/dist/index.js +22 -137
- package/dist/postbuild-purge.d.ts +12 -0
- package/dist/postbuild-purge.js +362 -0
- package/dist/scan-consumer.d.ts +2 -1
- package/package.json +2 -6
- package/src/generate-manifest.ts +3 -1
- package/dist/rsbuild-plugin.d.ts +0 -28
package/dist/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export {
|
|
2
|
-
export type {
|
|
1
|
+
export { extractUIImports, extractJSXUsages, buildSafelists, scanConsumerSource } from "./scan-consumer";
|
|
2
|
+
export type { PropUsage, PurgeManifest, ComponentManifest, Safelists } from "./scan-consumer";
|
package/dist/index.js
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
|
-
//
|
|
2
|
-
|
|
3
|
-
import postcss from "postcss";
|
|
1
|
+
// @bun
|
|
2
|
+
// src/scan-consumer.ts
|
|
4
3
|
import swc from "@swc/core";
|
|
4
|
+
var {Glob } = globalThis.Bun;
|
|
5
5
|
import path from "path";
|
|
6
|
-
import { readFile as nodeReadFile } from "node:fs/promises";
|
|
7
|
-
import { glob as fastGlob } from "fast-glob";
|
|
8
6
|
function walkAST(node, visitor) {
|
|
9
7
|
if (!node || typeof node !== "object")
|
|
10
8
|
return;
|
|
@@ -108,10 +106,12 @@ function buildSafelists(allUsages, manifest) {
|
|
|
108
106
|
}
|
|
109
107
|
for (const [entryName, entry] of Object.entries(manifest)) {
|
|
110
108
|
const matchingUsages = findMatchingUsages(entryName, componentUsages);
|
|
111
|
-
if (matchingUsages.length === 0)
|
|
109
|
+
if (matchingUsages.length === 0) {
|
|
112
110
|
continue;
|
|
113
|
-
|
|
111
|
+
}
|
|
112
|
+
for (const cls of entry.classes.always) {
|
|
114
113
|
classSafelist.add(cls);
|
|
114
|
+
}
|
|
115
115
|
for (const [propOrSlot, value] of Object.entries(entry.classes.byProp)) {
|
|
116
116
|
if (Array.isArray(value)) {
|
|
117
117
|
if (isPropUsed(propOrSlot, matchingUsages)) {
|
|
@@ -139,7 +139,7 @@ function buildSafelists(allUsages, manifest) {
|
|
|
139
139
|
for (const [propName, attrMap] of Object.entries(entry.attrs)) {
|
|
140
140
|
if (isPropUsed(propName, matchingUsages)) {
|
|
141
141
|
for (const [attr, val] of Object.entries(attrMap)) {
|
|
142
|
-
attrSafelist.add(
|
|
142
|
+
attrSafelist.add(`${attr}=${val}`);
|
|
143
143
|
}
|
|
144
144
|
}
|
|
145
145
|
}
|
|
@@ -148,8 +148,9 @@ function buildSafelists(allUsages, manifest) {
|
|
|
148
148
|
return { classSafelist, attrSafelist };
|
|
149
149
|
}
|
|
150
150
|
function findMatchingUsages(entryName, usageMap) {
|
|
151
|
-
if (usageMap.has(entryName))
|
|
151
|
+
if (usageMap.has(entryName)) {
|
|
152
152
|
return usageMap.get(entryName);
|
|
153
|
+
}
|
|
153
154
|
const results = [];
|
|
154
155
|
for (const [usageName, usages] of usageMap) {
|
|
155
156
|
if (usageName === entryName) {
|
|
@@ -192,10 +193,12 @@ function getUsedEnumValues(slotName, usages) {
|
|
|
192
193
|
}
|
|
193
194
|
async function scanConsumerSource(srcDir) {
|
|
194
195
|
const allUsages = [];
|
|
195
|
-
const
|
|
196
|
-
for (const relPath of
|
|
196
|
+
const glob = new Glob("**/*.{tsx,ts,jsx,js}");
|
|
197
|
+
for await (const relPath of glob.scan({ cwd: srcDir })) {
|
|
198
|
+
if (relPath.includes("node_modules"))
|
|
199
|
+
continue;
|
|
197
200
|
const fullPath = path.join(srcDir, relPath);
|
|
198
|
-
const code = await
|
|
201
|
+
const code = await Bun.file(fullPath).text();
|
|
199
202
|
if (!code.includes("@pathscale/ui"))
|
|
200
203
|
continue;
|
|
201
204
|
const isTsx = /\.[tj]sx$/.test(relPath);
|
|
@@ -207,131 +210,13 @@ async function scanConsumerSource(srcDir) {
|
|
|
207
210
|
}
|
|
208
211
|
return allUsages;
|
|
209
212
|
}
|
|
210
|
-
|
|
211
|
-
const root = postcss.parse(css);
|
|
212
|
-
root.walkRules((rule) => {
|
|
213
|
-
const selectors = rule.selectors;
|
|
214
|
-
const kept = [];
|
|
215
|
-
for (const sel of selectors) {
|
|
216
|
-
const attrMatches = sel.matchAll(/\[(data-[a-z-]+|aria-[a-z-]+)="([^"]+)"\]/g);
|
|
217
|
-
let shouldKeep = true;
|
|
218
|
-
for (const match of attrMatches) {
|
|
219
|
-
const attrSelector = `[${match[1]}="${match[2]}"]`;
|
|
220
|
-
if (match[1] === "data-slot")
|
|
221
|
-
continue;
|
|
222
|
-
if (!attrSafelist.has(attrSelector)) {
|
|
223
|
-
shouldKeep = false;
|
|
224
|
-
break;
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
if (shouldKeep)
|
|
228
|
-
kept.push(sel);
|
|
229
|
-
}
|
|
230
|
-
if (kept.length === 0) {
|
|
231
|
-
rule.remove();
|
|
232
|
-
} else if (kept.length < selectors.length) {
|
|
233
|
-
rule.selectors = kept;
|
|
234
|
-
}
|
|
235
|
-
});
|
|
236
|
-
return root.toString();
|
|
237
|
-
}
|
|
238
|
-
function cleanUnusedVars(css) {
|
|
239
|
-
let changed = true;
|
|
240
|
-
let result = css;
|
|
241
|
-
while (changed) {
|
|
242
|
-
changed = false;
|
|
243
|
-
const root = postcss.parse(result);
|
|
244
|
-
const declared = new Map;
|
|
245
|
-
root.walkDecls(/^--/, (decl) => {
|
|
246
|
-
const entries = declared.get(decl.prop) ?? [];
|
|
247
|
-
entries.push({ rule: decl.parent, prop: decl.prop, index: entries.length });
|
|
248
|
-
declared.set(decl.prop, entries);
|
|
249
|
-
});
|
|
250
|
-
const referenced = new Set;
|
|
251
|
-
root.walkDecls((decl) => {
|
|
252
|
-
const refs = decl.value.matchAll(/var\(\s*(--[a-zA-Z0-9_-]+)/g);
|
|
253
|
-
for (const ref of refs) {
|
|
254
|
-
referenced.add(ref[1]);
|
|
255
|
-
}
|
|
256
|
-
});
|
|
257
|
-
for (const [varName, entries] of declared) {
|
|
258
|
-
if (!referenced.has(varName)) {
|
|
259
|
-
for (const entry of entries) {
|
|
260
|
-
entry.rule.walkDecls(entry.prop, (decl) => {
|
|
261
|
-
decl.remove();
|
|
262
|
-
changed = true;
|
|
263
|
-
});
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
root.walkRules((rule) => {
|
|
268
|
-
if (rule.nodes && rule.nodes.length === 0)
|
|
269
|
-
rule.remove();
|
|
270
|
-
});
|
|
271
|
-
root.walkAtRules((atRule) => {
|
|
272
|
-
if (atRule.nodes && atRule.nodes.length === 0)
|
|
273
|
-
atRule.remove();
|
|
274
|
-
});
|
|
275
|
-
result = root.toString();
|
|
276
|
-
}
|
|
277
|
-
return result;
|
|
278
|
-
}
|
|
279
|
-
var pluginCssPurge = (options) => ({
|
|
280
|
-
name: "plugin-css-purge",
|
|
281
|
-
setup(api) {
|
|
282
|
-
const {
|
|
283
|
-
manifest: manifestPath,
|
|
284
|
-
srcDir = "src",
|
|
285
|
-
attrPurge = true,
|
|
286
|
-
cleanVars = true,
|
|
287
|
-
verbose = true
|
|
288
|
-
} = options;
|
|
289
|
-
api.processAssets({ stage: "optimize-size" }, async ({ assets, sources, compilation }) => {
|
|
290
|
-
const log = verbose ? console.log.bind(console) : () => {};
|
|
291
|
-
const manifest = JSON.parse(await nodeReadFile(path.resolve(manifestPath), "utf-8"));
|
|
292
|
-
log(`[css-purge] Manifest loaded: ${Object.keys(manifest).length} entries`);
|
|
293
|
-
const resolvedSrc = path.resolve(srcDir);
|
|
294
|
-
const usages = await scanConsumerSource(resolvedSrc);
|
|
295
|
-
log(`[css-purge] Scanned ${resolvedSrc}: ${usages.length} component usages`);
|
|
296
|
-
const { classSafelist, attrSafelist } = buildSafelists(usages, manifest);
|
|
297
|
-
log(`[css-purge] Safelist: ${classSafelist.size} classes, ${attrSafelist.size} attrs`);
|
|
298
|
-
for (const [name, asset] of Object.entries(assets)) {
|
|
299
|
-
if (!name.endsWith(".css"))
|
|
300
|
-
continue;
|
|
301
|
-
const originalCss = asset.source().toString();
|
|
302
|
-
const originalSize = Buffer.byteLength(originalCss, "utf-8");
|
|
303
|
-
log(`[css-purge] Processing ${name} (${(originalSize / 1024).toFixed(1)} KB)`);
|
|
304
|
-
const purgeResult = await new PurgeCSS().purge({
|
|
305
|
-
content: [],
|
|
306
|
-
css: [{ raw: originalCss }],
|
|
307
|
-
safelist: [...classSafelist],
|
|
308
|
-
keyframes: false,
|
|
309
|
-
fontFace: false
|
|
310
|
-
});
|
|
311
|
-
let purgedCss = purgeResult[0]?.css ?? originalCss;
|
|
312
|
-
const afterL1 = Buffer.byteLength(purgedCss, "utf-8");
|
|
313
|
-
log(`[css-purge] L1 class purge: ${(originalSize / 1024).toFixed(1)} → ${(afterL1 / 1024).toFixed(1)} KB`);
|
|
314
|
-
if (attrPurge && attrSafelist.size > 0) {
|
|
315
|
-
purgedCss = purgeAttributes(purgedCss, attrSafelist);
|
|
316
|
-
const afterL2 = Buffer.byteLength(purgedCss, "utf-8");
|
|
317
|
-
log(`[css-purge] L2 attr purge: ${(afterL1 / 1024).toFixed(1)} → ${(afterL2 / 1024).toFixed(1)} KB`);
|
|
318
|
-
}
|
|
319
|
-
if (cleanVars) {
|
|
320
|
-
purgedCss = cleanUnusedVars(purgedCss);
|
|
321
|
-
const afterL3 = Buffer.byteLength(purgedCss, "utf-8");
|
|
322
|
-
log(`[css-purge] L3 var cleanup: → ${(afterL3 / 1024).toFixed(1)} KB`);
|
|
323
|
-
}
|
|
324
|
-
const finalSize = Buffer.byteLength(purgedCss, "utf-8");
|
|
325
|
-
log(`[css-purge] Final: ${(originalSize / 1024).toFixed(1)} → ${(finalSize / 1024).toFixed(1)} KB (${((1 - finalSize / originalSize) * 100).toFixed(1)}% reduction)`);
|
|
326
|
-
const source = new sources.RawSource(purgedCss);
|
|
327
|
-
compilation.updateAsset(name, source);
|
|
328
|
-
}
|
|
329
|
-
});
|
|
330
|
-
}
|
|
331
|
-
});
|
|
213
|
+
if (false) {}
|
|
332
214
|
export {
|
|
333
|
-
|
|
215
|
+
scanConsumerSource,
|
|
216
|
+
extractUIImports,
|
|
217
|
+
extractJSXUsages,
|
|
218
|
+
buildSafelists
|
|
334
219
|
};
|
|
335
220
|
|
|
336
|
-
//# debugId=
|
|
337
|
-
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vc3JjL3JzYnVpbGQtcGx1Z2luLnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWwogICAgIi8qKlxuICogcnNidWlsZC1wbHVnaW4tY3NzLXB1cmdlXG4gKlxuICogVHdvLWxldmVsIENTUyBwdXJnZSBmb3IgQHBhdGhzY2FsZS91aSBjb25zdW1lcnMuXG4gKlxuICogTGV2ZWwgMTogY2xhc3MtbGV2ZWwgcHVyZ2UgdmlhIHB1cmdlY3NzIOKAlCByZW1vdmVzIGVudGlyZSBydWxlcyB3aG9zZSBzZWxlY3RvcnNcbiAqICAgICAgICAgIGRvbid0IG1hdGNoIHRoZSBzYWZlbGlzdCBidWlsdCBmcm9tIGNvbnN1bWVyIEpTWCBhbmFseXNpcy5cbiAqIExldmVsIDI6IGF0dHJpYnV0ZS1sZXZlbCBwdXJnZSDigJQgd2l0aGluIGtlcHQgcnVsZXMsIHN0cmlwcyBjb21wb3VuZCBzZWxlY3RvcnNcbiAqICAgICAgICAgIGNvbnRhaW5pbmcgZGF0YS1hdHRyIC8gYXJpYS1hdHRyIGF0dHJpYnV0ZSBzZWxlY3RvcnMgbm90IGluIHRoZSBhdHRyIHNhZmVsaXN0LlxuICpcbiAqIFVzYWdlIGluIHJzYnVpbGQuY29uZmlnLnRzOlxuICogICBpbXBvcnQgeyBwbHVnaW5Dc3NQdXJnZSB9IGZyb20gXCJAcGF0aHNjYWxlL3JlYnVpbGQtcGx1Z2luLXVpLWNzcy1wdXJnZVwiO1xuICogICBleHBvcnQgZGVmYXVsdCBkZWZpbmVDb25maWcoeyBwbHVnaW5zOiBbcGx1Z2luQ3NzUHVyZ2UoeyBtYW5pZmVzdDogXCIuLi5cIiB9KV0gfSk7XG4gKi9cblxuaW1wb3J0IHR5cGUgeyBSc2J1aWxkUGx1Z2luIH0gZnJvbSBcIkByc2J1aWxkL2NvcmVcIjtcbmltcG9ydCB7IFB1cmdlQ1NTIH0gZnJvbSBcInB1cmdlY3NzXCI7XG5pbXBvcnQgcG9zdGNzcyBmcm9tIFwicG9zdGNzc1wiO1xuaW1wb3J0IHR5cGUgeyBSdWxlLCBBdFJ1bGUgfSBmcm9tIFwicG9zdGNzc1wiO1xuaW1wb3J0IHN3YyBmcm9tIFwiQHN3Yy9jb3JlXCI7XG5pbXBvcnQgcGF0aCBmcm9tIFwicGF0aFwiO1xuaW1wb3J0IHsgcmVhZEZpbGUgYXMgbm9kZVJlYWRGaWxlIH0gZnJvbSBcIm5vZGU6ZnMvcHJvbWlzZXNcIjtcbmltcG9ydCB7IGdsb2IgYXMgZmFzdEdsb2IgfSBmcm9tIFwiZmFzdC1nbG9iXCI7XG5cbi8vIOKUgOKUgCBUeXBlcyDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuaW50ZXJmYWNlIENvbXBvbmVudE1hbmlmZXN0IHtcbiAgY2xhc3Nlczoge1xuICAgIGFsd2F5czogc3RyaW5nW107XG4gICAgYnlQcm9wOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmdbXSB8IFJlY29yZDxzdHJpbmcsIHN0cmluZ1tdPj47XG4gIH07XG4gIGF0dHJzPzogUmVjb3JkPHN0cmluZywgUmVjb3JkPHN0cmluZywgc3RyaW5nPj47XG59XG5cbnR5cGUgUHVyZ2VNYW5pZmVzdCA9IFJlY29yZDxzdHJpbmcsIENvbXBvbmVudE1hbmlmZXN0PjtcblxuaW50ZXJmYWNlIFByb3BVc2FnZSB7XG4gIGNvbXBvbmVudDogc3RyaW5nO1xuICBwcm9wczogTWFwPHN0cmluZywgc3RyaW5nIHwgXCJEWU5BTUlDXCI+O1xuICBib29sZWFuUHJvcHM6IFNldDxzdHJpbmc+O1xuICBoYXNTcHJlYWQ6IGJvb2xlYW47XG59XG5cbi8vIOKUgOKUgCBQbHVnaW4gb3B0aW9ucyDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuZXhwb3J0IGludGVyZmFjZSBDc3NQdXJnZU9wdGlvbnMge1xuICAvKiogUGF0aCB0byBwdXJnZS1tYW5pZmVzdC5qc29uIChnZW5lcmF0ZWQgYnkgZ2VuZXJhdGUtbWFuaWZlc3QudHMpICovXG4gIG1hbmlmZXN0OiBzdHJpbmc7XG4gIC8qKiBDb25zdW1lciBzb3VyY2UgZGlyZWN0b3J5IHRvIHNjYW4gZm9yIEpTWCB1c2FnZSAoZGVmYXVsdDogXCJzcmNcIikgKi9cbiAgc3JjRGlyPzogc3RyaW5nO1xuICAvKiogRW5hYmxlIExldmVsIDIgYXR0cmlidXRlIHB1cmdlIChkZWZhdWx0OiB0cnVlKSAqL1xuICBhdHRyUHVyZ2U/OiBib29sZWFuO1xuICAvKiogRW5hYmxlIENTUyB2YXJpYWJsZSBjbGVhbnVwIChkZWZhdWx0OiB0cnVlKSAqL1xuICBjbGVhblZhcnM/OiBib29sZWFuO1xuICAvKiogTG9nIHB1cmdlIHN0YXRzIChkZWZhdWx0OiB0cnVlKSAqL1xuICB2ZXJib3NlPzogYm9vbGVhbjtcbn1cblxuLy8g4pSA4pSAIEFTVCB1dGlsaXRpZXMg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbmZ1bmN0aW9uIHdhbGtBU1Qobm9kZTogYW55LCB2aXNpdG9yOiAobm9kZTogYW55KSA9PiB2b2lkKSB7XG4gIGlmICghbm9kZSB8fCB0eXBlb2Ygbm9kZSAhPT0gXCJvYmplY3RcIikgcmV0dXJuO1xuICB2aXNpdG9yKG5vZGUpO1xuICBmb3IgKGNvbnN0IGtleSBvZiBPYmplY3Qua2V5cyhub2RlKSkge1xuICAgIGlmIChrZXkgPT09IFwic3BhblwiKSBjb250aW51ZTtcbiAgICBjb25zdCB2YWwgPSBub2RlW2tleV07XG4gICAgaWYgKEFycmF5LmlzQXJyYXkodmFsKSkge1xuICAgICAgZm9yIChjb25zdCBpdGVtIG9mIHZhbCkgd2Fsa0FTVChpdGVtLCB2aXNpdG9yKTtcbiAgICB9IGVsc2UgaWYgKHZhbCAmJiB0eXBlb2YgdmFsID09PSBcIm9iamVjdFwiKSB7XG4gICAgICB3YWxrQVNUKHZhbCwgdmlzaXRvcik7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGV4dHJhY3RVSUltcG9ydHMoYXN0OiBhbnkpOiBNYXA8c3RyaW5nLCBzdHJpbmc+IHtcbiAgY29uc3QgaW1wb3J0cyA9IG5ldyBNYXA8c3RyaW5nLCBzdHJpbmc+KCk7XG4gIGZvciAoY29uc3Qgbm9kZSBvZiBhc3QuYm9keSkge1xuICAgIGlmIChub2RlLnR5cGUgIT09IFwiSW1wb3J0RGVjbGFyYXRpb25cIikgY29udGludWU7XG4gICAgY29uc3Qgc3JjID0gbm9kZS5zb3VyY2U/LnZhbHVlIGFzIHN0cmluZztcbiAgICBpZiAoIXNyYyB8fCAhc3JjLnN0YXJ0c1dpdGgoXCJAcGF0aHNjYWxlL3VpXCIpKSBjb250aW51ZTtcbiAgICBmb3IgKGNvbnN0IHNwZWMgb2Ygbm9kZS5zcGVjaWZpZXJzKSB7XG4gICAgICBpZiAoc3BlYy50eXBlID09PSBcIkltcG9ydFNwZWNpZmllclwiKSB7XG4gICAgICAgIGNvbnN0IGltcG9ydGVkID0gc3BlYy5pbXBvcnRlZD8udmFsdWUgPz8gc3BlYy5sb2NhbD8udmFsdWU7XG4gICAgICAgIGNvbnN0IGxvY2FsID0gc3BlYy5sb2NhbD8udmFsdWU7XG4gICAgICAgIGlmIChsb2NhbCAmJiBpbXBvcnRlZCkgaW1wb3J0cy5zZXQobG9jYWwsIGltcG9ydGVkKTtcbiAgICAgIH0gZWxzZSBpZiAoc3BlYy50eXBlID09PSBcIkltcG9ydERlZmF1bHRTcGVjaWZpZXJcIikge1xuICAgICAgICBjb25zdCBsb2NhbCA9IHNwZWMubG9jYWw/LnZhbHVlO1xuICAgICAgICBpZiAobG9jYWwpIGltcG9ydHMuc2V0KGxvY2FsLCBsb2NhbCk7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiBpbXBvcnRzO1xufVxuXG5mdW5jdGlvbiBleHRyYWN0SlNYVXNhZ2VzKGFzdDogYW55LCB1aUNvbXBvbmVudHM6IE1hcDxzdHJpbmcsIHN0cmluZz4pOiBQcm9wVXNhZ2VbXSB7XG4gIGNvbnN0IHVzYWdlczogUHJvcFVzYWdlW10gPSBbXTtcbiAgd2Fsa0FTVChhc3QsIChub2RlKSA9PiB7XG4gICAgaWYgKG5vZGUudHlwZSAhPT0gXCJKU1hPcGVuaW5nRWxlbWVudFwiKSByZXR1cm47XG4gICAgbGV0IGVsZW1lbnROYW1lOiBzdHJpbmcgfCBudWxsID0gbnVsbDtcbiAgICBsZXQgcm9vdE5hbWU6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuICAgIGlmIChub2RlLm5hbWU/LnR5cGUgPT09IFwiSWRlbnRpZmllclwiKSB7XG4gICAgICBlbGVtZW50TmFtZSA9IG5vZGUubmFtZS52YWx1ZTtcbiAgICAgIHJvb3ROYW1lID0gZWxlbWVudE5hbWU7XG4gICAgfSBlbHNlIGlmIChub2RlLm5hbWU/LnR5cGUgPT09IFwiSlNYTWVtYmVyRXhwcmVzc2lvblwiKSB7XG4gICAgICBjb25zdCBwYXJ0czogc3RyaW5nW10gPSBbXTtcbiAgICAgIGxldCBjdXJzb3IgPSBub2RlLm5hbWU7XG4gICAgICB3aGlsZSAoY3Vyc29yPy50eXBlID09PSBcIkpTWE1lbWJlckV4cHJlc3Npb25cIikge1xuICAgICAgICBwYXJ0cy51bnNoaWZ0KGN1cnNvci5wcm9wZXJ0eT8udmFsdWUpO1xuICAgICAgICBjdXJzb3IgPSBjdXJzb3Iub2JqZWN0O1xuICAgICAgfVxuICAgICAgaWYgKGN1cnNvcj8udHlwZSA9PT0gXCJJZGVudGlmaWVyXCIpIHtcbiAgICAgICAgcGFydHMudW5zaGlmdChjdXJzb3IudmFsdWUpO1xuICAgICAgICByb290TmFtZSA9IGN1cnNvci52YWx1ZTtcbiAgICAgIH1cbiAgICAgIGVsZW1lbnROYW1lID0gcGFydHMuam9pbihcIi5cIik7XG4gICAgfVxuICAgIGlmICghcm9vdE5hbWUgfHwgIXVpQ29tcG9uZW50cy5oYXMocm9vdE5hbWUpKSByZXR1cm47XG4gICAgY29uc3QgdXNhZ2U6IFByb3BVc2FnZSA9IHtcbiAgICAgIGNvbXBvbmVudDogZWxlbWVudE5hbWUhLFxuICAgICAgcHJvcHM6IG5ldyBNYXAoKSxcbiAgICAgIGJvb2xlYW5Qcm9wczogbmV3IFNldCgpLFxuICAgICAgaGFzU3ByZWFkOiBmYWxzZSxcbiAgICB9O1xuICAgIGZvciAoY29uc3QgYXR0ciBvZiBub2RlLmF0dHJpYnV0ZXMgfHwgW10pIHtcbiAgICAgIGlmIChhdHRyLnR5cGUgPT09IFwiU3ByZWFkRWxlbWVudFwiIHx8IGF0dHIudHlwZSA9PT0gXCJKU1hTcHJlYWRBdHRyaWJ1dGVcIikge1xuICAgICAgICB1c2FnZS5oYXNTcHJlYWQgPSB0cnVlO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIGlmIChhdHRyLnR5cGUgIT09IFwiSlNYQXR0cmlidXRlXCIpIGNvbnRpbnVlO1xuICAgICAgY29uc3QgcHJvcE5hbWUgPSBhdHRyLm5hbWU/LnZhbHVlO1xuICAgICAgaWYgKCFwcm9wTmFtZSkgY29udGludWU7XG4gICAgICBpZiAoIWF0dHIudmFsdWUpIHtcbiAgICAgICAgdXNhZ2UuYm9vbGVhblByb3BzLmFkZChwcm9wTmFtZSk7XG4gICAgICB9IGVsc2UgaWYgKGF0dHIudmFsdWUudHlwZSA9PT0gXCJTdHJpbmdMaXRlcmFsXCIpIHtcbiAgICAgICAgdXNhZ2UucHJvcHMuc2V0KHByb3BOYW1lLCBhdHRyLnZhbHVlLnZhbHVlKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHVzYWdlLnByb3BzLnNldChwcm9wTmFtZSwgXCJEWU5BTUlDXCIpO1xuICAgICAgfVxuICAgIH1cbiAgICB1c2FnZXMucHVzaCh1c2FnZSk7XG4gIH0pO1xuICByZXR1cm4gdXNhZ2VzO1xufVxuXG4vLyDilIDilIAgU2FmZWxpc3QgYnVpbGRlciDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuZnVuY3Rpb24gYnVpbGRTYWZlbGlzdHMoXG4gIGFsbFVzYWdlczogUHJvcFVzYWdlW10sXG4gIG1hbmlmZXN0OiBQdXJnZU1hbmlmZXN0LFxuKTogeyBjbGFzc1NhZmVsaXN0OiBTZXQ8c3RyaW5nPjsgYXR0clNhZmVsaXN0OiBTZXQ8c3RyaW5nPiB9IHtcbiAgY29uc3QgY2xhc3NTYWZlbGlzdCA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuICBjb25zdCBhdHRyU2FmZWxpc3QgPSBuZXcgU2V0PHN0cmluZz4oKTtcblxuICBjb25zdCBjb21wb25lbnRVc2FnZXMgPSBuZXcgTWFwPHN0cmluZywgUHJvcFVzYWdlW10+KCk7XG4gIGZvciAoY29uc3QgdXNhZ2Ugb2YgYWxsVXNhZ2VzKSB7XG4gICAgY29uc3QgZXhpc3RpbmcgPSBjb21wb25lbnRVc2FnZXMuZ2V0KHVzYWdlLmNvbXBvbmVudCkgPz8gW107XG4gICAgZXhpc3RpbmcucHVzaCh1c2FnZSk7XG4gICAgY29tcG9uZW50VXNhZ2VzLnNldCh1c2FnZS5jb21wb25lbnQsIGV4aXN0aW5nKTtcbiAgfVxuXG4gIGZvciAoY29uc3QgW2VudHJ5TmFtZSwgZW50cnldIG9mIE9iamVjdC5lbnRyaWVzKG1hbmlmZXN0KSkge1xuICAgIGNvbnN0IG1hdGNoaW5nVXNhZ2VzID0gZmluZE1hdGNoaW5nVXNhZ2VzKGVudHJ5TmFtZSwgY29tcG9uZW50VXNhZ2VzKTtcbiAgICBpZiAobWF0Y2hpbmdVc2FnZXMubGVuZ3RoID09PSAwKSBjb250aW51ZTtcblxuICAgIGZvciAoY29uc3QgY2xzIG9mIGVudHJ5LmNsYXNzZXMuYWx3YXlzKSBjbGFzc1NhZmVsaXN0LmFkZChjbHMpO1xuXG4gICAgZm9yIChjb25zdCBbcHJvcE9yU2xvdCwgdmFsdWVdIG9mIE9iamVjdC5lbnRyaWVzKGVudHJ5LmNsYXNzZXMuYnlQcm9wKSkge1xuICAgICAgaWYgKEFycmF5LmlzQXJyYXkodmFsdWUpKSB7XG4gICAgICAgIGlmIChpc1Byb3BVc2VkKHByb3BPclNsb3QsIG1hdGNoaW5nVXNhZ2VzKSkge1xuICAgICAgICAgIGZvciAoY29uc3QgY2xzIG9mIHZhbHVlKSBjbGFzc1NhZmVsaXN0LmFkZChjbHMpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zdCB1c2VkVmFsdWVzID0gZ2V0VXNlZEVudW1WYWx1ZXMocHJvcE9yU2xvdCwgbWF0Y2hpbmdVc2FnZXMpO1xuICAgICAgICBpZiAodXNlZFZhbHVlcyA9PT0gXCJBTExcIikge1xuICAgICAgICAgIGZvciAoY29uc3QgY2xhc3NlcyBvZiBPYmplY3QudmFsdWVzKHZhbHVlKSkge1xuICAgICAgICAgICAgZm9yIChjb25zdCBjbHMgb2YgY2xhc3NlcykgY2xhc3NTYWZlbGlzdC5hZGQoY2xzKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgZm9yIChjb25zdCB2YWwgb2YgdXNlZFZhbHVlcykge1xuICAgICAgICAgICAgaWYgKHZhbHVlW3ZhbF0pIHtcbiAgICAgICAgICAgICAgZm9yIChjb25zdCBjbHMgb2YgdmFsdWVbdmFsXSkgY2xhc3NTYWZlbGlzdC5hZGQoY2xzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoZW50cnkuYXR0cnMpIHtcbiAgICAgIGZvciAoY29uc3QgW3Byb3BOYW1lLCBhdHRyTWFwXSBvZiBPYmplY3QuZW50cmllcyhlbnRyeS5hdHRycykpIHtcbiAgICAgICAgaWYgKGlzUHJvcFVzZWQocHJvcE5hbWUsIG1hdGNoaW5nVXNhZ2VzKSkge1xuICAgICAgICAgIGZvciAoY29uc3QgW2F0dHIsIHZhbF0gb2YgT2JqZWN0LmVudHJpZXMoYXR0ck1hcCkpIHtcbiAgICAgICAgICAgIGF0dHJTYWZlbGlzdC5hZGQoYFske2F0dHJ9PVwiJHt2YWx9XCJdYCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHsgY2xhc3NTYWZlbGlzdCwgYXR0clNhZmVsaXN0IH07XG59XG5cbmZ1bmN0aW9uIGZpbmRNYXRjaGluZ1VzYWdlcyhlbnRyeU5hbWU6IHN0cmluZywgdXNhZ2VNYXA6IE1hcDxzdHJpbmcsIFByb3BVc2FnZVtdPik6IFByb3BVc2FnZVtdIHtcbiAgaWYgKHVzYWdlTWFwLmhhcyhlbnRyeU5hbWUpKSByZXR1cm4gdXNhZ2VNYXAuZ2V0KGVudHJ5TmFtZSkhO1xuICBjb25zdCByZXN1bHRzOiBQcm9wVXNhZ2VbXSA9IFtdO1xuICBmb3IgKGNvbnN0IFt1c2FnZU5hbWUsIHVzYWdlc10gb2YgdXNhZ2VNYXApIHtcbiAgICBpZiAodXNhZ2VOYW1lID09PSBlbnRyeU5hbWUpIHtcbiAgICAgIHJlc3VsdHMucHVzaCguLi51c2FnZXMpO1xuICAgIH1cbiAgICBpZiAoZW50cnlOYW1lLmluY2x1ZGVzKFwiLlwiKSkge1xuICAgICAgY29uc3QgW2ZhbWlseSwgcGFydF0gPSBlbnRyeU5hbWUuc3BsaXQoXCIuXCIpO1xuICAgICAgaWYgKHBhcnQgPT09IGZhbWlseSAmJiB1c2FnZU5hbWUgPT09IGZhbWlseSkge1xuICAgICAgICByZXN1bHRzLnB1c2goLi4udXNhZ2VzKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgcmV0dXJuIHJlc3VsdHM7XG59XG5cbmZ1bmN0aW9uIGlzUHJvcFVzZWQocHJvcE5hbWU6IHN0cmluZywgdXNhZ2VzOiBQcm9wVXNhZ2VbXSk6IGJvb2xlYW4ge1xuICBmb3IgKGNvbnN0IHVzYWdlIG9mIHVzYWdlcykge1xuICAgIGlmICh1c2FnZS5oYXNTcHJlYWQpIHJldHVybiB0cnVlO1xuICAgIGlmICh1c2FnZS5ib29sZWFuUHJvcHMuaGFzKHByb3BOYW1lKSkgcmV0dXJuIHRydWU7XG4gICAgaWYgKHVzYWdlLnByb3BzLmhhcyhwcm9wTmFtZSkpIHJldHVybiB0cnVlO1xuICB9XG4gIHJldHVybiBmYWxzZTtcbn1cblxuZnVuY3Rpb24gZ2V0VXNlZEVudW1WYWx1ZXMoc2xvdE5hbWU6IHN0cmluZywgdXNhZ2VzOiBQcm9wVXNhZ2VbXSk6IFNldDxzdHJpbmc+IHwgXCJBTExcIiB7XG4gIGNvbnN0IHZhbHVlcyA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuICBmb3IgKGNvbnN0IHVzYWdlIG9mIHVzYWdlcykge1xuICAgIGlmICh1c2FnZS5oYXNTcHJlYWQpIHJldHVybiBcIkFMTFwiO1xuICAgIGNvbnN0IHZhbCA9IHVzYWdlLnByb3BzLmdldChzbG90TmFtZSk7XG4gICAgaWYgKHZhbCA9PT0gXCJEWU5BTUlDXCIpIHJldHVybiBcIkFMTFwiO1xuICAgIGlmICh2YWwgIT09IHVuZGVmaW5lZCkgdmFsdWVzLmFkZCh2YWwpO1xuICAgIGlmICh1c2FnZS5ib29sZWFuUHJvcHMuaGFzKHNsb3ROYW1lKSkgcmV0dXJuIFwiQUxMXCI7XG4gIH1cbiAgcmV0dXJuIHZhbHVlcztcbn1cblxuLy8g4pSA4pSAIENvbnN1bWVyIHNvdXJjZSBzY2FubmluZyDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuYXN5bmMgZnVuY3Rpb24gc2NhbkNvbnN1bWVyU291cmNlKHNyY0Rpcjogc3RyaW5nKTogUHJvbWlzZTxQcm9wVXNhZ2VbXT4ge1xuICBjb25zdCBhbGxVc2FnZXM6IFByb3BVc2FnZVtdID0gW107XG4gIGNvbnN0IGZpbGVzID0gYXdhaXQgZmFzdEdsb2IoXCIqKi8qLnt0c3gsdHMsanN4LGpzfVwiLCB7IGN3ZDogc3JjRGlyLCBpZ25vcmU6IFtcIioqL25vZGVfbW9kdWxlcy8qKlwiXSB9KTtcblxuICBmb3IgKGNvbnN0IHJlbFBhdGggb2YgZmlsZXMpIHtcbiAgICBjb25zdCBmdWxsUGF0aCA9IHBhdGguam9pbihzcmNEaXIsIHJlbFBhdGgpO1xuICAgIGNvbnN0IGNvZGUgPSBhd2FpdCBub2RlUmVhZEZpbGUoZnVsbFBhdGgsIFwidXRmLThcIik7XG4gICAgaWYgKCFjb2RlLmluY2x1ZGVzKFwiQHBhdGhzY2FsZS91aVwiKSkgY29udGludWU7XG5cbiAgICBjb25zdCBpc1RzeCA9IC9cXC5bdGpdc3gkLy50ZXN0KHJlbFBhdGgpO1xuICAgIGNvbnN0IGFzdCA9IGF3YWl0IHN3Yy5wYXJzZShjb2RlLCB7IHN5bnRheDogXCJ0eXBlc2NyaXB0XCIsIHRzeDogaXNUc3ggfSk7XG4gICAgY29uc3QgdWlJbXBvcnRzID0gZXh0cmFjdFVJSW1wb3J0cyhhc3QpO1xuICAgIGlmICh1aUltcG9ydHMuc2l6ZSA9PT0gMCkgY29udGludWU7XG5cbiAgICBhbGxVc2FnZXMucHVzaCguLi5leHRyYWN0SlNYVXNhZ2VzKGFzdCwgdWlJbXBvcnRzKSk7XG4gIH1cblxuICByZXR1cm4gYWxsVXNhZ2VzO1xufVxuXG4vLyDilIDilIAgTGV2ZWwgMjogYXR0cmlidXRlIHB1cmdlIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG5mdW5jdGlvbiBwdXJnZUF0dHJpYnV0ZXMoY3NzOiBzdHJpbmcsIGF0dHJTYWZlbGlzdDogU2V0PHN0cmluZz4pOiBzdHJpbmcge1xuICBjb25zdCByb290ID0gcG9zdGNzcy5wYXJzZShjc3MpO1xuXG4gIHJvb3Qud2Fsa1J1bGVzKChydWxlKSA9PiB7XG4gICAgY29uc3Qgc2VsZWN0b3JzID0gcnVsZS5zZWxlY3RvcnM7XG4gICAgY29uc3Qga2VwdDogc3RyaW5nW10gPSBbXTtcblxuICAgIGZvciAoY29uc3Qgc2VsIG9mIHNlbGVjdG9ycykge1xuICAgICAgY29uc3QgYXR0ck1hdGNoZXMgPSBzZWwubWF0Y2hBbGwoL1xcWyhkYXRhLVthLXotXSt8YXJpYS1bYS16LV0rKT1cIihbXlwiXSspXCJcXF0vZyk7XG4gICAgICBsZXQgc2hvdWxkS2VlcCA9IHRydWU7XG5cbiAgICAgIGZvciAoY29uc3QgbWF0Y2ggb2YgYXR0ck1hdGNoZXMpIHtcbiAgICAgICAgY29uc3QgYXR0clNlbGVjdG9yID0gYFske21hdGNoWzFdfT1cIiR7bWF0Y2hbMl19XCJdYDtcbiAgICAgICAgaWYgKG1hdGNoWzFdID09PSBcImRhdGEtc2xvdFwiKSBjb250aW51ZTtcbiAgICAgICAgaWYgKCFhdHRyU2FmZWxpc3QuaGFzKGF0dHJTZWxlY3RvcikpIHtcbiAgICAgICAgICBzaG91bGRLZWVwID0gZmFsc2U7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKHNob3VsZEtlZXApIGtlcHQucHVzaChzZWwpO1xuICAgIH1cblxuICAgIGlmIChrZXB0Lmxlbmd0aCA9PT0gMCkge1xuICAgICAgcnVsZS5yZW1vdmUoKTtcbiAgICB9IGVsc2UgaWYgKGtlcHQubGVuZ3RoIDwgc2VsZWN0b3JzLmxlbmd0aCkge1xuICAgICAgcnVsZS5zZWxlY3RvcnMgPSBrZXB0O1xuICAgIH1cbiAgfSk7XG5cbiAgcmV0dXJuIHJvb3QudG9TdHJpbmcoKTtcbn1cblxuLy8g4pSA4pSAIExldmVsIDM6IHVudXNlZCBDU1MgdmFyaWFibGUgY2xlYW51cCDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuZnVuY3Rpb24gY2xlYW5VbnVzZWRWYXJzKGNzczogc3RyaW5nKTogc3RyaW5nIHtcbiAgbGV0IGNoYW5nZWQgPSB0cnVlO1xuICBsZXQgcmVzdWx0ID0gY3NzO1xuXG4gIHdoaWxlIChjaGFuZ2VkKSB7XG4gICAgY2hhbmdlZCA9IGZhbHNlO1xuICAgIGNvbnN0IHJvb3QgPSBwb3N0Y3NzLnBhcnNlKHJlc3VsdCk7XG5cbiAgICBjb25zdCBkZWNsYXJlZCA9IG5ldyBNYXA8c3RyaW5nLCB7IHJ1bGU6IFJ1bGUgfCBBdFJ1bGU7IHByb3A6IHN0cmluZzsgaW5kZXg6IG51bWJlciB9W10+KCk7XG4gICAgcm9vdC53YWxrRGVjbHMoL14tLS8sIChkZWNsKSA9PiB7XG4gICAgICBjb25zdCBlbnRyaWVzID0gZGVjbGFyZWQuZ2V0KGRlY2wucHJvcCkgPz8gW107XG4gICAgICBlbnRyaWVzLnB1c2goeyBydWxlOiBkZWNsLnBhcmVudCBhcyBSdWxlLCBwcm9wOiBkZWNsLnByb3AsIGluZGV4OiBlbnRyaWVzLmxlbmd0aCB9KTtcbiAgICAgIGRlY2xhcmVkLnNldChkZWNsLnByb3AsIGVudHJpZXMpO1xuICAgIH0pO1xuXG4gICAgY29uc3QgcmVmZXJlbmNlZCA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuICAgIHJvb3Qud2Fsa0RlY2xzKChkZWNsKSA9PiB7XG4gICAgICBjb25zdCByZWZzID0gZGVjbC52YWx1ZS5tYXRjaEFsbCgvdmFyXFwoXFxzKigtLVthLXpBLVowLTlfLV0rKS9nKTtcbiAgICAgIGZvciAoY29uc3QgcmVmIG9mIHJlZnMpIHtcbiAgICAgICAgcmVmZXJlbmNlZC5hZGQocmVmWzFdKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGZvciAoY29uc3QgW3Zhck5hbWUsIGVudHJpZXNdIG9mIGRlY2xhcmVkKSB7XG4gICAgICBpZiAoIXJlZmVyZW5jZWQuaGFzKHZhck5hbWUpKSB7XG4gICAgICAgIGZvciAoY29uc3QgZW50cnkgb2YgZW50cmllcykge1xuICAgICAgICAgIGVudHJ5LnJ1bGUud2Fsa0RlY2xzKGVudHJ5LnByb3AsIChkZWNsKSA9PiB7XG4gICAgICAgICAgICBkZWNsLnJlbW92ZSgpO1xuICAgICAgICAgICAgY2hhbmdlZCA9IHRydWU7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICByb290LndhbGtSdWxlcygocnVsZSkgPT4ge1xuICAgICAgaWYgKHJ1bGUubm9kZXMgJiYgcnVsZS5ub2Rlcy5sZW5ndGggPT09IDApIHJ1bGUucmVtb3ZlKCk7XG4gICAgfSk7XG4gICAgcm9vdC53YWxrQXRSdWxlcygoYXRSdWxlKSA9PiB7XG4gICAgICBpZiAoYXRSdWxlLm5vZGVzICYmIGF0UnVsZS5ub2Rlcy5sZW5ndGggPT09IDApIGF0UnVsZS5yZW1vdmUoKTtcbiAgICB9KTtcblxuICAgIHJlc3VsdCA9IHJvb3QudG9TdHJpbmcoKTtcbiAgfVxuXG4gIHJldHVybiByZXN1bHQ7XG59XG5cbi8vIOKUgOKUgCBUaGUgcnNidWlsZCBwbHVnaW4g4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbmV4cG9ydCBjb25zdCBwbHVnaW5Dc3NQdXJnZSA9IChvcHRpb25zOiBDc3NQdXJnZU9wdGlvbnMpOiBSc2J1aWxkUGx1Z2luID0+ICh7XG4gIG5hbWU6IFwicGx1Z2luLWNzcy1wdXJnZVwiLFxuXG4gIHNldHVwKGFwaSkge1xuICAgIGNvbnN0IHtcbiAgICAgIG1hbmlmZXN0OiBtYW5pZmVzdFBhdGgsXG4gICAgICBzcmNEaXIgPSBcInNyY1wiLFxuICAgICAgYXR0clB1cmdlID0gdHJ1ZSxcbiAgICAgIGNsZWFuVmFycyA9IHRydWUsXG4gICAgICB2ZXJib3NlID0gdHJ1ZSxcbiAgICB9ID0gb3B0aW9ucztcblxuICAgIGFwaS5wcm9jZXNzQXNzZXRzKFxuICAgICAgeyBzdGFnZTogXCJvcHRpbWl6ZS1zaXplXCIgfSxcbiAgICAgIGFzeW5jICh7IGFzc2V0cywgc291cmNlcywgY29tcGlsYXRpb24gfSkgPT4ge1xuICAgICAgICBjb25zdCBsb2cgPSB2ZXJib3NlID8gY29uc29sZS5sb2cuYmluZChjb25zb2xlKSA6ICgpID0+IHt9O1xuXG4gICAgICAgIC8vIDEuIExvYWQgbWFuaWZlc3RcbiAgICAgICAgY29uc3QgbWFuaWZlc3Q6IFB1cmdlTWFuaWZlc3QgPSBKU09OLnBhcnNlKFxuICAgICAgICAgIGF3YWl0IG5vZGVSZWFkRmlsZShwYXRoLnJlc29sdmUobWFuaWZlc3RQYXRoKSwgXCJ1dGYtOFwiKSxcbiAgICAgICAgKTtcbiAgICAgICAgbG9nKGBbY3NzLXB1cmdlXSBNYW5pZmVzdCBsb2FkZWQ6ICR7T2JqZWN0LmtleXMobWFuaWZlc3QpLmxlbmd0aH0gZW50cmllc2ApO1xuXG4gICAgICAgIC8vIDIuIFNjYW4gY29uc3VtZXIgc291cmNlXG4gICAgICAgIGNvbnN0IHJlc29sdmVkU3JjID0gcGF0aC5yZXNvbHZlKHNyY0Rpcik7XG4gICAgICAgIGNvbnN0IHVzYWdlcyA9IGF3YWl0IHNjYW5Db25zdW1lclNvdXJjZShyZXNvbHZlZFNyYyk7XG4gICAgICAgIGxvZyhgW2Nzcy1wdXJnZV0gU2Nhbm5lZCAke3Jlc29sdmVkU3JjfTogJHt1c2FnZXMubGVuZ3RofSBjb21wb25lbnQgdXNhZ2VzYCk7XG5cbiAgICAgICAgLy8gMy4gQnVpbGQgc2FmZWxpc3RzXG4gICAgICAgIGNvbnN0IHsgY2xhc3NTYWZlbGlzdCwgYXR0clNhZmVsaXN0IH0gPSBidWlsZFNhZmVsaXN0cyh1c2FnZXMsIG1hbmlmZXN0KTtcbiAgICAgICAgbG9nKGBbY3NzLXB1cmdlXSBTYWZlbGlzdDogJHtjbGFzc1NhZmVsaXN0LnNpemV9IGNsYXNzZXMsICR7YXR0clNhZmVsaXN0LnNpemV9IGF0dHJzYCk7XG5cbiAgICAgICAgLy8gNC4gUHJvY2VzcyBlYWNoIENTUyBhc3NldFxuICAgICAgICBmb3IgKGNvbnN0IFtuYW1lLCBhc3NldF0gb2YgT2JqZWN0LmVudHJpZXMoYXNzZXRzKSkge1xuICAgICAgICAgIGlmICghbmFtZS5lbmRzV2l0aChcIi5jc3NcIikpIGNvbnRpbnVlO1xuXG4gICAgICAgICAgY29uc3Qgb3JpZ2luYWxDc3MgPSBhc3NldC5zb3VyY2UoKS50b1N0cmluZygpO1xuICAgICAgICAgIGNvbnN0IG9yaWdpbmFsU2l6ZSA9IEJ1ZmZlci5ieXRlTGVuZ3RoKG9yaWdpbmFsQ3NzLCBcInV0Zi04XCIpO1xuICAgICAgICAgIGxvZyhgW2Nzcy1wdXJnZV0gUHJvY2Vzc2luZyAke25hbWV9ICgkeyhvcmlnaW5hbFNpemUgLyAxMDI0KS50b0ZpeGVkKDEpfSBLQilgKTtcblxuICAgICAgICAgIC8vIExldmVsIDE6IGNsYXNzLWxldmVsIHB1cmdlXG4gICAgICAgICAgY29uc3QgcHVyZ2VSZXN1bHQgPSBhd2FpdCBuZXcgUHVyZ2VDU1MoKS5wdXJnZSh7XG4gICAgICAgICAgICBjb250ZW50OiBbXSxcbiAgICAgICAgICAgIGNzczogW3sgcmF3OiBvcmlnaW5hbENzcyB9XSxcbiAgICAgICAgICAgIHNhZmVsaXN0OiBbLi4uY2xhc3NTYWZlbGlzdF0sXG4gICAgICAgICAgICBrZXlmcmFtZXM6IGZhbHNlLFxuICAgICAgICAgICAgZm9udEZhY2U6IGZhbHNlLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgbGV0IHB1cmdlZENzcyA9IHB1cmdlUmVzdWx0WzBdPy5jc3MgPz8gb3JpZ2luYWxDc3M7XG4gICAgICAgICAgY29uc3QgYWZ0ZXJMMSA9IEJ1ZmZlci5ieXRlTGVuZ3RoKHB1cmdlZENzcywgXCJ1dGYtOFwiKTtcbiAgICAgICAgICBsb2coYFtjc3MtcHVyZ2VdICAgTDEgY2xhc3MgcHVyZ2U6ICR7KG9yaWdpbmFsU2l6ZSAvIDEwMjQpLnRvRml4ZWQoMSl9IOKGkiAkeyhhZnRlckwxIC8gMTAyNCkudG9GaXhlZCgxKX0gS0JgKTtcblxuICAgICAgICAgIC8vIExldmVsIDI6IGF0dHJpYnV0ZS1sZXZlbCBwdXJnZVxuICAgICAgICAgIGlmIChhdHRyUHVyZ2UgJiYgYXR0clNhZmVsaXN0LnNpemUgPiAwKSB7XG4gICAgICAgICAgICBwdXJnZWRDc3MgPSBwdXJnZUF0dHJpYnV0ZXMocHVyZ2VkQ3NzLCBhdHRyU2FmZWxpc3QpO1xuICAgICAgICAgICAgY29uc3QgYWZ0ZXJMMiA9IEJ1ZmZlci5ieXRlTGVuZ3RoKHB1cmdlZENzcywgXCJ1dGYtOFwiKTtcbiAgICAgICAgICAgIGxvZyhgW2Nzcy1wdXJnZV0gICBMMiBhdHRyIHB1cmdlOiAkeyhhZnRlckwxIC8gMTAyNCkudG9GaXhlZCgxKX0g4oaSICR7KGFmdGVyTDIgLyAxMDI0KS50b0ZpeGVkKDEpfSBLQmApO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIC8vIExldmVsIDM6IHVudXNlZCBDU1MgdmFyaWFibGUgY2xlYW51cFxuICAgICAgICAgIGlmIChjbGVhblZhcnMpIHtcbiAgICAgICAgICAgIHB1cmdlZENzcyA9IGNsZWFuVW51c2VkVmFycyhwdXJnZWRDc3MpO1xuICAgICAgICAgICAgY29uc3QgYWZ0ZXJMMyA9IEJ1ZmZlci5ieXRlTGVuZ3RoKHB1cmdlZENzcywgXCJ1dGYtOFwiKTtcbiAgICAgICAgICAgIGxvZyhgW2Nzcy1wdXJnZV0gICBMMyB2YXIgY2xlYW51cDog4oaSICR7KGFmdGVyTDMgLyAxMDI0KS50b0ZpeGVkKDEpfSBLQmApO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGNvbnN0IGZpbmFsU2l6ZSA9IEJ1ZmZlci5ieXRlTGVuZ3RoKHB1cmdlZENzcywgXCJ1dGYtOFwiKTtcbiAgICAgICAgICBsb2coYFtjc3MtcHVyZ2VdICAgRmluYWw6ICR7KG9yaWdpbmFsU2l6ZSAvIDEwMjQpLnRvRml4ZWQoMSl9IOKGkiAkeyhmaW5hbFNpemUgLyAxMDI0KS50b0ZpeGVkKDEpfSBLQiAoJHsoKDEgLSBmaW5hbFNpemUgLyBvcmlnaW5hbFNpemUpICogMTAwKS50b0ZpeGVkKDEpfSUgcmVkdWN0aW9uKWApO1xuXG4gICAgICAgICAgLy8gV3JpdGUgYmFja1xuICAgICAgICAgIGNvbnN0IHNvdXJjZSA9IG5ldyBzb3VyY2VzLlJhd1NvdXJjZShwdXJnZWRDc3MpO1xuICAgICAgICAgIGNvbXBpbGF0aW9uLnVwZGF0ZUFzc2V0KG5hbWUsIHNvdXJjZSk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgKTtcbiAgfSxcbn0pO1xuIgogIF0sCiAgIm1hcHBpbmdzIjogIjtBQWdCQTtBQUNBO0FBRUE7QUFDQTtBQUNBLHFCQUFTO0FBQ1QsaUJBQVM7QUFzQ1QsU0FBUyxPQUFPLENBQUMsTUFBVyxTQUE4QjtBQUFBLEVBQ3hELElBQUksQ0FBQyxRQUFRLE9BQU8sU0FBUztBQUFBLElBQVU7QUFBQSxFQUN2QyxRQUFRLElBQUk7QUFBQSxFQUNaLFdBQVcsT0FBTyxPQUFPLEtBQUssSUFBSSxHQUFHO0FBQUEsSUFDbkMsSUFBSSxRQUFRO0FBQUEsTUFBUTtBQUFBLElBQ3BCLE1BQU0sTUFBTSxLQUFLO0FBQUEsSUFDakIsSUFBSSxNQUFNLFFBQVEsR0FBRyxHQUFHO0FBQUEsTUFDdEIsV0FBVyxRQUFRO0FBQUEsUUFBSyxRQUFRLE1BQU0sT0FBTztBQUFBLElBQy9DLEVBQU8sU0FBSSxPQUFPLE9BQU8sUUFBUSxVQUFVO0FBQUEsTUFDekMsUUFBUSxLQUFLLE9BQU87QUFBQSxJQUN0QjtBQUFBLEVBQ0Y7QUFBQTtBQUdGLFNBQVMsZ0JBQWdCLENBQUMsS0FBK0I7QUFBQSxFQUN2RCxNQUFNLFVBQVUsSUFBSTtBQUFBLEVBQ3BCLFdBQVcsUUFBUSxJQUFJLE1BQU07QUFBQSxJ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QU87QUFBQSxRQUN2QyxNQUFNLFVBQVUsT0FBTyxXQUFXLFdBQVcsT0FBTztBQUFBLFFBQ3BELElBQUksa0NBQWtDLGVBQWUsTUFBTSxRQUFRLENBQUMsUUFBTyxVQUFVLE1BQU0sUUFBUSxDQUFDLE1BQU07QUFBQSxRQUcxRyxJQUFJLGFBQWEsYUFBYSxPQUFPLEdBQUc7QUFBQSxVQUN0QyxZQUFZLGdCQUFnQixXQUFXLFlBQVk7QUFBQSxVQUNuRCxNQUFNLFVBQVUsT0FBTyxXQUFXLFdBQVcsT0FBTztBQUFBLFVBQ3BELElBQUksaUNBQWlDLFVBQVUsTUFBTSxRQUFRLENBQUMsUUFBTyxVQUFVLE1BQU0sUUFBUSxDQUFDLE1BQU07QUFBQSxRQUN0RztBQUFBLFFBR0EsSUFBSSxXQUFXO0FBQUEsVUFDYixZQUFZLGdCQUFnQixTQUFTO0FBQUEsVUFDckMsTUFBTSxVQUFVLE9BQU8sV0FBVyxXQUFXLE9BQU87QUFBQSxVQUNwRCxJQUFJLG9DQUFtQyxVQUFVLE1BQU0sUUFBUSxDQUFDLE1BQU07QUFBQSxRQUN4RTtBQUFBLFFBRUEsTUFBTSxZQUFZLE9BQU8sV0FBVyxXQUFXLE9BQU87QUFBQSxRQUN0RCxJQUFJLHlCQUF5QixlQUFlLE1BQU0sUUFBUSxDQUFDLFFBQU8sWUFBWSxNQUFNLFFBQVEsQ0FBQyxXQUFXLElBQUksWUFBWSxnQkFBZ0IsS0FBSyxRQUFRLENBQUMsZUFBZTtBQUFBLFFBR3JLLE1BQU0sU0FBUyxJQUFJLFFBQVEsVUFBVSxTQUFTO0FBQUEsUUFDOUMsWUFBWSxZQUFZLE1BQU0sTUFBTTtBQUFBLE1BQ3RDO0FBQUEsS0FFSjtBQUFBO0FBRUo7IiwKICAiZGVidWdJZCI6ICJDQjVCMjA5MzA2MzY2M0U4NjQ3NTZFMjE2NDc1NkUyMSIsCiAgIm5hbWVzIjogW10KfQ==
|
|
221
|
+
//# debugId=E6760AADCED89B2864756E2164756E21
|
|
222
|
+
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vc3JjL3NjYW4tY29uc3VtZXIudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbCiAgICAiLyoqXG4gKiBDb25zdW1lci1zaWRlIEpTWCBzY2FubmVyLlxuICpcbiAqIFdhbGtzIGEgY29uc3VtZXIncyBzb3VyY2UgdHJlZSwgZmluZHMgY29tcG9uZW50IGltcG9ydHMgZnJvbSBAcGF0aHNjYWxlL3VpLFxuICogY29sbGVjdHMgcHJvcCB2YWx1ZXMsIGFuZCBjcm9zcy1yZWZlcmVuY2VzIHdpdGggdGhlIHB1cmdlIG1hbmlmZXN0IHRvIGJ1aWxkXG4gKiBMZXZlbCAxIChjbGFzcykgYW5kIExldmVsIDIgKGF0dHJpYnV0ZSkgc2FmZWxpc3RzLlxuICpcbiAqIFVzYWdlOiAgYnVuIHJ1biBzcmMvc2Nhbi1jb25zdW1lci50cyA8Y29uc3VtZXItc3JjLWRpcj4gPHB1cmdlLW1hbmlmZXN0Lmpzb24+XG4gKi9cblxuaW1wb3J0IHN3YyBmcm9tIFwiQHN3Yy9jb3JlXCI7XG5pbXBvcnQgeyBHbG9iIH0gZnJvbSBcImJ1blwiO1xuaW1wb3J0IHBhdGggZnJvbSBcInBhdGhcIjtcblxuLy8g4pSA4pSAIFR5cGVzIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG5pbnRlcmZhY2UgQ29tcG9uZW50TWFuaWZlc3Qge1xuICBjbGFzc2VzOiB7XG4gICAgYWx3YXlzOiBzdHJpbmdbXTtcbiAgICBieVByb3A6IFJlY29yZDxzdHJpbmcsIHN0cmluZ1tdIHwgUmVjb3JkPHN0cmluZywgc3RyaW5nW10+PjtcbiAgfTtcbiAgYXR0cnM/OiBSZWNvcmQ8c3RyaW5nLCBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+Pjtcbn1cblxudHlwZSBQdXJnZU1hbmlmZXN0ID0gUmVjb3JkPHN0cmluZywgQ29tcG9uZW50TWFuaWZlc3Q+O1xuXG4vKiogV2hhdCB3ZSBjb2xsZWN0IHBlciBjb21wb25lbnQgdXNhZ2UgZnJvbSBKU1ggKi9cbmludGVyZmFjZSBQcm9wVXNhZ2Uge1xuICBjb21wb25lbnQ6IHN0cmluZztcbiAgcHJvcHM6IE1hcDxzdHJpbmcsIHN0cmluZyB8IFwiRFlOQU1JQ1wiPjsgLy8gcHJvcE5hbWUg4oaSIGxpdGVyYWwgdmFsdWUgb3IgRFlOQU1JQ1xuICBib29sZWFuUHJvcHM6IFNldDxzdHJpbmc+OyAvLyBwcm9wcyBwcmVzZW50IHdpdGhvdXQgYSB2YWx1ZSAodHJ1dGh5KVxuICBoYXNTcHJlYWQ6IGJvb2xlYW47XG59XG5cbi8vIOKUgOKUgCBBU1Qgd2Fsa2VyIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG5mdW5jdGlvbiB3YWxrQVNUKG5vZGU6IGFueSwgdmlzaXRvcjogKG5vZGU6IGFueSkgPT4gdm9pZCkge1xuICBpZiAoIW5vZGUgfHwgdHlwZW9mIG5vZGUgIT09IFwib2JqZWN0XCIpIHJldHVybjtcbiAgdmlzaXRvcihub2RlKTtcbiAgZm9yIChjb25zdCBrZXkgb2YgT2JqZWN0LmtleXMobm9kZSkpIHtcbiAgICBpZiAoa2V5ID09PSBcInNwYW5cIikgY29udGludWU7XG4gICAgY29uc3QgdmFsID0gbm9kZVtrZXldO1xuICAgIGlmIChBcnJheS5pc0FycmF5KHZhbCkpIHtcbiAgICAgIGZvciAoY29uc3QgaXRlbSBvZiB2YWwpIHdhbGtBU1QoaXRlbSwgdmlzaXRvcik7XG4gICAgfSBlbHNlIGlmICh2YWwgJiYgdHlwZW9mIHZhbCA9PT0gXCJvYmplY3RcIikge1xuICAgICAgd2Fsa0FTVCh2YWwsIHZpc2l0b3IpO1xuICAgIH1cbiAgfVxufVxuXG4vKiogRXh0cmFjdCBAcGF0aHNjYWxlL3VpIGltcG9ydHMgZnJvbSBhIHBhcnNlZCBtb2R1bGUgKi9cbmZ1bmN0aW9uIGV4dHJhY3RVSUltcG9ydHMoYXN0OiBhbnkpOiBNYXA8c3RyaW5nLCBzdHJpbmc+IHtcbiAgY29uc3QgaW1wb3J0cyA9IG5ldyBNYXA8c3RyaW5nLCBzdHJpbmc+KCk7XG4gIGZvciAoY29uc3Qgbm9kZSBvZiBhc3QuYm9keSkge1xuICAgIGlmIChub2RlLnR5cGUgIT09IFwiSW1wb3J0RGVjbGFyYXRpb25cIikgY29udGludWU7XG4gICAgY29uc3Qgc3JjID0gbm9kZS5zb3VyY2U/LnZhbHVlIGFzIHN0cmluZztcbiAgICBpZiAoIXNyYyB8fCAhc3JjLnN0YXJ0c1dpdGgoXCJAcGF0aHNjYWxlL3VpXCIpKSBjb250aW51ZTtcblxuICAgIGZvciAoY29uc3Qgc3BlYyBvZiBub2RlLnNwZWNpZmllcnMpIHtcbiAgICAgIGlmIChzcGVjLnR5cGUgPT09IFwiSW1wb3J0U3BlY2lmaWVyXCIpIHtcbiAgICAgICAgY29uc3QgaW1wb3J0ZWQgPSBzcGVjLmltcG9ydGVkPy52YWx1ZSA/PyBzcGVjLmxvY2FsPy52YWx1ZTtcbiAgICAgICAgY29uc3QgbG9jYWwgPSBzcGVjLmxvY2FsPy52YWx1ZTtcbiAgICAgICAgaWYgKGxvY2FsICYmIGltcG9ydGVkKSBpbXBvcnRzLnNldChsb2NhbCwgaW1wb3J0ZWQpO1xuICAgICAgfSBlbHNlIGlmIChzcGVjLnR5cGUgPT09IFwiSW1wb3J0RGVmYXVsdFNwZWNpZmllclwiKSB7XG4gICAgICAgIGNvbnN0IGxvY2FsID0gc3BlYy5sb2NhbD8udmFsdWU7XG4gICAgICAgIGlmIChsb2NhbCkgaW1wb3J0cy5zZXQobG9jYWwsIGxvY2FsKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgcmV0dXJuIGltcG9ydHM7XG59XG5cbi8qKiBFeHRyYWN0IEpTWCB1c2FnZXMgb2YgVUkgY29tcG9uZW50cyAqL1xuZnVuY3Rpb24gZXh0cmFjdEpTWFVzYWdlcyhhc3Q6IGFueSwgdWlDb21wb25lbnRzOiBNYXA8c3RyaW5nLCBzdHJpbmc+KTogUHJvcFVzYWdlW10ge1xuICBjb25zdCB1c2FnZXM6IFByb3BVc2FnZVtdID0gW107XG5cbiAgd2Fsa0FTVChhc3QsIChub2RlKSA9PiB7XG4gICAgaWYgKG5vZGUudHlwZSAhPT0gXCJKU1hPcGVuaW5nRWxlbWVudFwiKSByZXR1cm47XG5cbiAgICBsZXQgZWxlbWVudE5hbWU6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuICAgIGxldCByb290TmFtZTogc3RyaW5nIHwgbnVsbCA9IG51bGw7XG5cbiAgICBpZiAobm9kZS5uYW1lPy50eXBlID09PSBcIklkZW50aWZpZXJcIikge1xuICAgICAgZWxlbWVudE5hbWUgPSBub2RlLm5hbWUudmFsdWU7XG4gICAgICByb290TmFtZSA9IGVsZW1lbnROYW1lO1xuICAgIH0gZWxzZSBpZiAobm9kZS5uYW1lPy50eXBlID09PSBcIkpTWE1lbWJlckV4cHJlc3Npb25cIikge1xuICAgICAgY29uc3QgcGFydHM6IHN0cmluZ1tdID0gW107XG4gICAgICBsZXQgY3Vyc29yID0gbm9kZS5uYW1lO1xuICAgICAgd2hpbGUgKGN1cnNvcj8udHlwZSA9PT0gXCJKU1hNZW1iZXJFeHByZXNzaW9uXCIpIHtcbiAgICAgICAgcGFydHMudW5zaGlmdChjdXJzb3IucHJvcGVydHk/LnZhbHVlKTtcbiAgICAgICAgY3Vyc29yID0gY3Vyc29yLm9iamVjdDtcbiAgICAgIH1cbiAgICAgIGlmIChjdXJzb3I/LnR5cGUgPT09IFwiSWRlbnRpZmllclwiKSB7XG4gICAgICAgIHBhcnRzLnVuc2hpZnQoY3Vyc29yLnZhbHVlKTtcbiAgICAgICAgcm9vdE5hbWUgPSBjdXJzb3IudmFsdWU7XG4gICAgICB9XG4gICAgICBlbGVtZW50TmFtZSA9IHBhcnRzLmpvaW4oXCIuXCIpO1xuICAgIH1cblxuICAgIGlmICghcm9vdE5hbWUgfHwgIXVpQ29tcG9uZW50cy5oYXMocm9vdE5hbWUpKSByZXR1cm47XG5cbiAgICBjb25zdCB1c2FnZTogUHJvcFVzYWdlID0ge1xuICAgICAgY29tcG9uZW50OiBlbGVtZW50TmFtZSEsXG4gICAgICBwcm9wczogbmV3IE1hcCgpLFxuICAgICAgYm9vbGVhblByb3BzOiBuZXcgU2V0KCksXG4gICAgICBoYXNTcHJlYWQ6IGZhbHNlLFxuICAgIH07XG5cbiAgICBmb3IgKGNvbnN0IGF0dHIgb2Ygbm9kZS5hdHRyaWJ1dGVzIHx8IFtdKSB7XG4gICAgICBpZiAoYXR0ci50eXBlID09PSBcIlNwcmVhZEVsZW1lbnRcIiB8fCBhdHRyLnR5cGUgPT09IFwiSlNYU3ByZWFkQXR0cmlidXRlXCIpIHtcbiAgICAgICAgdXNhZ2UuaGFzU3ByZWFkID0gdHJ1ZTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBpZiAoYXR0ci50eXBlICE9PSBcIkpTWEF0dHJpYnV0ZVwiKSBjb250aW51ZTtcblxuICAgICAgY29uc3QgcHJvcE5hbWUgPSBhdHRyLm5hbWU/LnZhbHVlO1xuICAgICAgaWYgKCFwcm9wTmFtZSkgY29udGludWU7XG5cbiAgICAgIGlmICghYXR0ci52YWx1ZSkge1xuICAgICAgICB1c2FnZS5ib29sZWFuUHJvcHMuYWRkKHByb3BOYW1lKTtcbiAgICAgIH0gZWxzZSBpZiAoYXR0ci52YWx1ZS50eXBlID09PSBcIlN0cmluZ0xpdGVyYWxcIikge1xuICAgICAgICB1c2FnZS5wcm9wcy5zZXQocHJvcE5hbWUsIGF0dHIudmFsdWUudmFsdWUpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdXNhZ2UucHJvcHMuc2V0KHByb3BOYW1lLCBcIkRZTkFNSUNcIik7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdXNhZ2VzLnB1c2godXNhZ2UpO1xuICB9KTtcblxuICByZXR1cm4gdXNhZ2VzO1xufVxuXG4vLyDilIDilIAgU2FmZWxpc3QgYnVpbGRlciDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuaW50ZXJmYWNlIFNhZmVsaXN0cyB7XG4gIGNsYXNzU2FmZWxpc3Q6IFNldDxzdHJpbmc+O1xuICBhdHRyU2FmZWxpc3Q6IFNldDxzdHJpbmc+O1xufVxuXG5mdW5jdGlvbiBidWlsZFNhZmVsaXN0cyhcbiAgYWxsVXNhZ2VzOiBQcm9wVXNhZ2VbXSxcbiAgbWFuaWZlc3Q6IFB1cmdlTWFuaWZlc3QsXG4pOiBTYWZlbGlzdHMge1xuICBjb25zdCBjbGFzc1NhZmVsaXN0ID0gbmV3IFNldDxzdHJpbmc+KCk7XG4gIGNvbnN0IGF0dHJTYWZlbGlzdCA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuXG4gIGNvbnN0IGNvbXBvbmVudFVzYWdlcyA9IG5ldyBNYXA8c3RyaW5nLCBQcm9wVXNhZ2VbXT4oKTtcbiAgZm9yIChjb25zdCB1c2FnZSBvZiBhbGxVc2FnZXMpIHtcbiAgICBjb25zdCBleGlzdGluZyA9IGNvbXBvbmVudFVzYWdlcy5nZXQodXNhZ2UuY29tcG9uZW50KSA/PyBbXTtcbiAgICBleGlzdGluZy5wdXNoKHVzYWdlKTtcbiAgICBjb21wb25lbnRVc2FnZXMuc2V0KHVzYWdlLmNvbXBvbmVudCwgZXhpc3RpbmcpO1xuICB9XG5cbiAgZm9yIChjb25zdCBbZW50cnlOYW1lLCBlbnRyeV0gb2YgT2JqZWN0LmVudHJpZXMobWFuaWZlc3QpKSB7XG4gICAgY29uc3QgbWF0Y2hpbmdVc2FnZXMgPSBmaW5kTWF0Y2hpbmdVc2FnZXMoZW50cnlOYW1lLCBjb21wb25lbnRVc2FnZXMpO1xuXG4gICAgaWYgKG1hdGNoaW5nVXNhZ2VzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBjbHMgb2YgZW50cnkuY2xhc3Nlcy5hbHdheXMpIHtcbiAgICAgIGNsYXNzU2FmZWxpc3QuYWRkKGNscyk7XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBbcHJvcE9yU2xvdCwgdmFsdWVdIG9mIE9iamVjdC5lbnRyaWVzKGVudHJ5LmNsYXNzZXMuYnlQcm9wKSkge1xuICAgICAgaWYgKEFycmF5LmlzQXJyYXkodmFsdWUpKSB7XG4gICAgICAgIGlmIChpc1Byb3BVc2VkKHByb3BPclNsb3QsIG1hdGNoaW5nVXNhZ2VzKSkge1xuICAgICAgICAgIGZvciAoY29uc3QgY2xzIG9mIHZhbHVlKSBjbGFzc1NhZmVsaXN0LmFkZChjbHMpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zdCB1c2VkVmFsdWVzID0gZ2V0VXNlZEVudW1WYWx1ZXMocHJvcE9yU2xvdCwgbWF0Y2hpbmdVc2FnZXMpO1xuICAgICAgICBpZiAodXNlZFZhbHVlcyA9PT0gXCJBTExcIikge1xuICAgICAgICAgIGZvciAoY29uc3QgY2xhc3NlcyBvZiBPYmplY3QudmFsdWVzKHZhbHVlKSkge1xuICAgICAgICAgICAgZm9yIChjb25zdCBjbHMgb2YgY2xhc3NlcykgY2xhc3NTYWZlbGlzdC5hZGQoY2xzKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgZm9yIChjb25zdCB2YWwgb2YgdXNlZFZhbHVlcykge1xuICAgICAgICAgICAgaWYgKHZhbHVlW3ZhbF0pIHtcbiAgICAgICAgICAgICAgZm9yIChjb25zdCBjbHMgb2YgdmFsdWVbdmFsXSkgY2xhc3NTYWZlbGlzdC5hZGQoY2xzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoZW50cnkuYXR0cnMpIHtcbiAgICAgIGZvciAoY29uc3QgW3Byb3BOYW1lLCBhdHRyTWFwXSBvZiBPYmplY3QuZW50cmllcyhlbnRyeS5hdHRycykpIHtcbiAgICAgICAgaWYgKGlzUHJvcFVzZWQocHJvcE5hbWUsIG1hdGNoaW5nVXNhZ2VzKSkge1xuICAgICAgICAgIGZvciAoY29uc3QgW2F0dHIsIHZhbF0gb2YgT2JqZWN0LmVudHJpZXMoYXR0ck1hcCkpIHtcbiAgICAgICAgICAgIGF0dHJTYWZlbGlzdC5hZGQoYCR7YXR0cn09JHt2YWx9YCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHsgY2xhc3NTYWZlbGlzdCwgYXR0clNhZmVsaXN0IH07XG59XG5cbmZ1bmN0aW9uIGZpbmRNYXRjaGluZ1VzYWdlcyhcbiAgZW50cnlOYW1lOiBzdHJpbmcsXG4gIHVzYWdlTWFwOiBNYXA8c3RyaW5nLCBQcm9wVXNhZ2VbXT4sXG4pOiBQcm9wVXNhZ2VbXSB7XG4gIGlmICh1c2FnZU1hcC5oYXMoZW50cnlOYW1lKSkge1xuICAgIHJldHVybiB1c2FnZU1hcC5nZXQoZW50cnlOYW1lKSE7XG4gIH1cblxuICBjb25zdCByZXN1bHRzOiBQcm9wVXNhZ2VbXSA9IFtdO1xuICBmb3IgKGNvbnN0IFt1c2FnZU5hbWUsIHVzYWdlc10gb2YgdXNhZ2VNYXApIHtcbiAgICBpZiAodXNhZ2VOYW1lID09PSBlbnRyeU5hbWUpIHtcbiAgICAgIHJlc3VsdHMucHVzaCguLi51c2FnZXMpO1xuICAgIH1cbiAgICBpZiAoZW50cnlOYW1lLmluY2x1ZGVzKFwiLlwiKSkge1xuICAgICAgY29uc3QgW2ZhbWlseSwgcGFydF0gPSBlbnRyeU5hbWUuc3BsaXQoXCIuXCIpO1xuICAgICAgaWYgKHBhcnQgPT09IGZhbWlseSAmJiB1c2FnZU5hbWUgPT09IGZhbWlseSkge1xuICAgICAgICByZXN1bHRzLnB1c2goLi4udXNhZ2VzKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgcmV0dXJuIHJlc3VsdHM7XG59XG5cbmZ1bmN0aW9uIGlzUHJvcFVzZWQocHJvcE5hbWU6IHN0cmluZywgdXNhZ2VzOiBQcm9wVXNhZ2VbXSk6IGJvb2xlYW4ge1xuICBmb3IgKGNvbnN0IHVzYWdlIG9mIHVzYWdlcykge1xuICAgIGlmICh1c2FnZS5oYXNTcHJlYWQpIHJldHVybiB0cnVlO1xuICAgIGlmICh1c2FnZS5ib29sZWFuUHJvcHMuaGFzKHByb3BOYW1lKSkgcmV0dXJuIHRydWU7XG4gICAgaWYgKHVzYWdlLnByb3BzLmhhcyhwcm9wTmFtZSkpIHJldHVybiB0cnVlO1xuICB9XG4gIHJldHVybiBmYWxzZTtcbn1cblxuZnVuY3Rpb24gZ2V0VXNlZEVudW1WYWx1ZXMoc2xvdE5hbWU6IHN0cmluZywgdXNhZ2VzOiBQcm9wVXNhZ2VbXSk6IFNldDxzdHJpbmc+IHwgXCJBTExcIiB7XG4gIGNvbnN0IHZhbHVlcyA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuICBmb3IgKGNvbnN0IHVzYWdlIG9mIHVzYWdlcykge1xuICAgIGlmICh1c2FnZS5oYXNTcHJlYWQpIHJldHVybiBcIkFMTFwiO1xuICAgIGNvbnN0IHZhbCA9IHVzYWdlLnByb3BzLmdldChzbG90TmFtZSk7XG4gICAgaWYgKHZhbCA9PT0gXCJEWU5BTUlDXCIpIHJldHVybiBcIkFMTFwiO1xuICAgIGlmICh2YWwgIT09IHVuZGVmaW5lZCkgdmFsdWVzLmFkZCh2YWwpO1xuICAgIGlmICh1c2FnZS5ib29sZWFuUHJvcHMuaGFzKHNsb3ROYW1lKSkgcmV0dXJuIFwiQUxMXCI7XG4gIH1cbiAgcmV0dXJuIHZhbHVlcztcbn1cblxuLy8g4pSA4pSAIENvbnN1bWVyIHNvdXJjZSBzY2FubmluZyDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuYXN5bmMgZnVuY3Rpb24gc2NhbkNvbnN1bWVyU291cmNlKHNyY0Rpcjogc3RyaW5nKTogUHJvbWlzZTxQcm9wVXNhZ2VbXT4ge1xuICBjb25zdCBhbGxVc2FnZXM6IFByb3BVc2FnZVtdID0gW107XG4gIGNvbnN0IGdsb2IgPSBuZXcgR2xvYihcIioqLyoue3RzeCx0cyxqc3gsanN9XCIpO1xuXG4gIGZvciBhd2FpdCAoY29uc3QgcmVsUGF0aCBvZiBnbG9iLnNjYW4oeyBjd2Q6IHNyY0RpciB9KSkge1xuICAgIGlmIChyZWxQYXRoLmluY2x1ZGVzKFwibm9kZV9tb2R1bGVzXCIpKSBjb250aW51ZTtcbiAgICBjb25zdCBmdWxsUGF0aCA9IHBhdGguam9pbihzcmNEaXIsIHJlbFBhdGgpO1xuICAgIGNvbnN0IGNvZGUgPSBhd2FpdCBCdW4uZmlsZShmdWxsUGF0aCkudGV4dCgpO1xuICAgIGlmICghY29kZS5pbmNsdWRlcyhcIkBwYXRoc2NhbGUvdWlcIikpIGNvbnRpbnVlO1xuXG4gICAgY29uc3QgaXNUc3ggPSAvXFwuW3RqXXN4JC8udGVzdChyZWxQYXRoKTtcbiAgICBjb25zdCBhc3QgPSBhd2FpdCBzd2MucGFyc2UoY29kZSwgeyBzeW50YXg6IFwidHlwZXNjcmlwdFwiLCB0c3g6IGlzVHN4IH0pO1xuICAgIGNvbnN0IHVpSW1wb3J0cyA9IGV4dHJhY3RVSUltcG9ydHMoYXN0KTtcbiAgICBpZiAodWlJbXBvcnRzLnNpemUgPT09IDApIGNvbnRpbnVlO1xuXG4gICAgYWxsVXNhZ2VzLnB1c2goLi4uZXh0cmFjdEpTWFVzYWdlcyhhc3QsIHVpSW1wb3J0cykpO1xuICB9XG5cbiAgcmV0dXJuIGFsbFVzYWdlcztcbn1cblxuLy8g4pSA4pSAIE1haW4gKHN0YW5kYWxvbmUgQ0xJKSDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuYXN5bmMgZnVuY3Rpb24gbWFpbigpIHtcbiAgY29uc3QgW3NyY0RpciwgbWFuaWZlc3RQYXRoXSA9IHByb2Nlc3MuYXJndi5zbGljZSgyKTtcbiAgaWYgKCFzcmNEaXIgfHwgIW1hbmlmZXN0UGF0aCkge1xuICAgIGNvbnNvbGUuZXJyb3IoXCJVc2FnZTogYnVuIHJ1biBzcmMvc2Nhbi1jb25zdW1lci50cyA8Y29uc3VtZXItc3JjLWRpcj4gPHB1cmdlLW1hbmlmZXN0Lmpzb24+XCIpO1xuICAgIHByb2Nlc3MuZXhpdCgxKTtcbiAgfVxuXG4gIGNvbnN0IG1hbmlmZXN0OiBQdXJnZU1hbmlmZXN0ID0gSlNPTi5wYXJzZShcbiAgICBhd2FpdCBCdW4uZmlsZShtYW5pZmVzdFBhdGgpLnRleHQoKSxcbiAgKTtcbiAgY29uc3QgcmVzb2x2ZWRTcmMgPSBwYXRoLnJlc29sdmUoc3JjRGlyKTtcbiAgY29uc29sZS5sb2coYFNjYW5uaW5nICR7cmVzb2x2ZWRTcmN9IGZvciBAcGF0aHNjYWxlL3VpIGNvbXBvbmVudCB1c2FnZeKApmApO1xuICBjb25zb2xlLmxvZyhgTWFuaWZlc3Q6ICR7T2JqZWN0LmtleXMobWFuaWZlc3QpLmxlbmd0aH0gZW50cmllc1xcbmApO1xuXG4gIGNvbnN0IHVzYWdlcyA9IGF3YWl0IHNjYW5Db25zdW1lclNvdXJjZShyZXNvbHZlZFNyYyk7XG4gIGNvbnN0IHsgY2xhc3NTYWZlbGlzdCwgYXR0clNhZmVsaXN0IH0gPSBidWlsZFNhZmVsaXN0cyh1c2FnZXMsIG1hbmlmZXN0KTtcblxuICBjb25zb2xlLmxvZyhcIj09PSBDbGFzcyBTYWZlbGlzdCA9PT1cIik7XG4gIGZvciAoY29uc3QgY2xzIG9mIFsuLi5jbGFzc1NhZmVsaXN0XS5zb3J0KCkpIHtcbiAgICBjb25zb2xlLmxvZyhgICAke2Nsc31gKTtcbiAgfVxuXG4gIGNvbnNvbGUubG9nKGBcXG49PT0gQXR0cmlidXRlIFNhZmVsaXN0ID09PWApO1xuICBmb3IgKGNvbnN0IGF0dHIgb2YgWy4uLmF0dHJTYWZlbGlzdF0uc29ydCgpKSB7XG4gICAgY29uc29sZS5sb2coYCAgWyR7YXR0cn1dYCk7XG4gIH1cblxuICBjb25zb2xlLmxvZyhgXFxuVG90YWw6ICR7Y2xhc3NTYWZlbGlzdC5zaXplfSBjbGFzc2VzLCAke2F0dHJTYWZlbGlzdC5zaXplfSBhdHRyaWJ1dGUgc2VsZWN0b3JzYCk7XG59XG5cbi8vIE9ubHkgcnVuIENMSSB3aGVuIGludm9rZWQgZGlyZWN0bHkgKG5vdCB3aGVuIGltcG9ydGVkIGFzIGEgbW9kdWxlKVxuaWYgKGltcG9ydC5tZXRhLm1haW4pIHtcbiAgbWFpbigpO1xufVxuXG5leHBvcnQgeyBleHRyYWN0VUlJbXBvcnRzLCBleHRyYWN0SlNYVXNhZ2VzLCBidWlsZFNhZmVsaXN0cywgc2NhbkNvbnN1bWVyU291cmNlIH07XG5leHBvcnQgdHlwZSB7IFByb3BVc2FnZSwgUHVyZ2VNYW5pZmVzdCwgQ29tcG9uZW50TWFuaWZlc3QsIFNhZmVsaXN0cyB9O1xuIgogIF0sCiAgIm1hcHBpbmdzIjogIjs7QUFVQTtBQUNBO0FBQ0E7QUF3QkEsU0FBUyxPQUFPLENBQUMsTUFBVyxTQUE4QjtBQUFBLEVBQ3hELElBQUksQ0FBQyxRQUFRLE9BQU8sU0FBUztBQUFBLElBQVU7QUFBQSxFQUN2QyxRQUFRLElBQUk7QUFBQSxFQUNaLFdBQVcsT0FBTyxPQUFPLEtBQUssSUFBSSxHQUFHO0FBQUEsSUFDbkMsSUFBSSxRQUFRO0FBQUEsTUFBUTtBQUFBLElBQ3BCLE1BQU0sTUFBTSxLQUFLO0FBQUEsSUFDakIsSUFBSSxNQUFNLFFBQVEsR0FBRyxHQUFHO0FBQUEsTUFDdEIsV0FBVyxRQUFRO0FBQUEsUUFBSyxRQUFRLE1BQU0sT0FBTztBQUFBLElBQy9DLEVBQU8sU0FBSSxPQUFPLE9BQU8sUUFBUSxVQUFVO0FBQUEsTUFDekMsUUFBUSxLQUFLLE9BQU87QUFBQSxJQUN0QjtBQUFBLEVBQ0Y7QUFBQTtBQUlGLFNBQVMsZ0JB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QixJQUFJLE1BQU0sYUFBYSxJQUFJLFFBQVE7QUFBQSxNQUFHLE9BQU87QUFBQSxJQUM3QyxJQUFJLE1BQU0sTUFBTSxJQUFJLFFBQVE7QUFBQSxNQUFHLE9BQU87QUFBQSxFQUN4QztBQUFBLEVBQ0EsT0FBTztBQUFBO0FBR1QsU0FBUyxpQkFBaUIsQ0FBQyxVQUFrQixRQUEwQztBQUFBLEVBQ3JGLE1BQU0sU0FBUyxJQUFJO0FBQUEsRUFDbkIsV0FBVyxTQUFTLFFBQVE7QUFBQSxJQUMxQixJQUFJLE1BQU07QUFBQSxNQUFXLE9BQU87QUFBQSxJQUM1QixNQUFNLE1BQU0sTUFBTSxNQUFNLElBQUksUUFBUTtBQUFBLElBQ3BDLElBQUksUUFBUTtBQUFBLE1BQVcsT0FBTztBQUFBLElBQzlCLElBQUksUUFBUTtBQUFBLE1BQVcsT0FBTyxJQUFJLEdBQUc7QUFBQSxJQUNyQyxJQUFJLE1BQU0sYUFBYSxJQUFJLFFBQVE7QUFBQSxNQUFHLE9BQU87QUFBQSxFQUMvQztBQUFBLEVBQ0EsT0FBTztBQUFBO0FBS1QsZUFBZSxrQkFBa0IsQ0FBQyxRQUFzQztBQUFBLEVBQ3RFLE1BQU0sWUFBeUIsQ0FBQztBQUFBLEVBQ2hDLE1BQU0sT0FBTyxJQUFJLEtBQUssc0JBQXNCO0FBQUEsRUFFNUMsaUJBQWlCLFdBQVcsS0FBSyxLQUFLLEVBQUUsS0FBSyxPQUFPLENBQUMsR0FBRztBQUFBLElBQ3RELElBQUksUUFBUSxTQUFTLGNBQWM7QUFBQSxNQUFHO0FBQUEsSUFDdEMsTUFBTSxXQUFXLEtBQUssS0FBSyxRQUFRLE9BQU87QUFBQSxJQUMxQyxNQUFNLE9BQU8sTUFBTSxJQUFJLEtBQUssUUFBUSxFQUFFLEtBQUs7QUFBQSxJQUMzQyxJQUFJLENBQUMsS0FBSyxTQUFTLGVBQWU7QUFBQSxNQUFHO0FBQUEsSUFFckMsTUFBTSxRQUFRLFlBQVksS0FBSyxPQUFPO0FBQUEsSUFDdEMsTUFBTSxNQUFNLE1BQU0sSUFBSSxNQUFNLE1BQU0sRUFBRSxRQUFRLGNBQWMsS0FBSyxNQUFNLENBQUM7QUFBQSxJQUN0RSxNQUFNLFlBQVksaUJBQWlCLEdBQUc7QUFBQSxJQUN0QyxJQUFJLFVBQVUsU0FBUztBQUFBLE1BQUc7QUFBQSxJQUUxQixVQUFVLEtBQUssR0FBRyxpQkFBaUIsS0FBSyxTQUFTLENBQUM7QUFBQSxFQUNwRDtBQUFBLEVBRUEsT0FBTztBQUFBO0FBb0NULElBQUksT0FBa0IsQ0FFdEI7IiwKICAiZGVidWdJZCI6ICJFNjc2MEFBRENFRDg5QjI4NjQ3NTZFMjE2NDc1NkUyMSIsCiAgIm5hbWVzIjogW10KfQ==
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
/**
|
|
3
|
+
* Postbuild CSS purge — standalone Bun script.
|
|
4
|
+
*
|
|
5
|
+
* Runs after rsbuild build, purges CSS files in dist/ using the purge manifest
|
|
6
|
+
* and consumer JSX analysis. Zero Node imports.
|
|
7
|
+
*
|
|
8
|
+
* Usage:
|
|
9
|
+
* bunx @pathscale/rebuild-plugin-ui-css-purge \
|
|
10
|
+
* --dist dist --src src --manifest node_modules/@pathscale/ui/dist/purge-manifest.json
|
|
11
|
+
*/
|
|
12
|
+
export {};
|
|
@@ -0,0 +1,362 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
// @bun
|
|
3
|
+
|
|
4
|
+
// src/postbuild-purge.ts
|
|
5
|
+
var {Glob: Glob2 } = globalThis.Bun;
|
|
6
|
+
import { PurgeCSS } from "purgecss";
|
|
7
|
+
import postcss from "postcss";
|
|
8
|
+
import path2 from "path";
|
|
9
|
+
|
|
10
|
+
// src/scan-consumer.ts
|
|
11
|
+
import swc from "@swc/core";
|
|
12
|
+
var {Glob } = globalThis.Bun;
|
|
13
|
+
import path from "path";
|
|
14
|
+
function walkAST(node, visitor) {
|
|
15
|
+
if (!node || typeof node !== "object")
|
|
16
|
+
return;
|
|
17
|
+
visitor(node);
|
|
18
|
+
for (const key of Object.keys(node)) {
|
|
19
|
+
if (key === "span")
|
|
20
|
+
continue;
|
|
21
|
+
const val = node[key];
|
|
22
|
+
if (Array.isArray(val)) {
|
|
23
|
+
for (const item of val)
|
|
24
|
+
walkAST(item, visitor);
|
|
25
|
+
} else if (val && typeof val === "object") {
|
|
26
|
+
walkAST(val, visitor);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
function extractUIImports(ast) {
|
|
31
|
+
const imports = new Map;
|
|
32
|
+
for (const node of ast.body) {
|
|
33
|
+
if (node.type !== "ImportDeclaration")
|
|
34
|
+
continue;
|
|
35
|
+
const src = node.source?.value;
|
|
36
|
+
if (!src || !src.startsWith("@pathscale/ui"))
|
|
37
|
+
continue;
|
|
38
|
+
for (const spec of node.specifiers) {
|
|
39
|
+
if (spec.type === "ImportSpecifier") {
|
|
40
|
+
const imported = spec.imported?.value ?? spec.local?.value;
|
|
41
|
+
const local = spec.local?.value;
|
|
42
|
+
if (local && imported)
|
|
43
|
+
imports.set(local, imported);
|
|
44
|
+
} else if (spec.type === "ImportDefaultSpecifier") {
|
|
45
|
+
const local = spec.local?.value;
|
|
46
|
+
if (local)
|
|
47
|
+
imports.set(local, local);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return imports;
|
|
52
|
+
}
|
|
53
|
+
function extractJSXUsages(ast, uiComponents) {
|
|
54
|
+
const usages = [];
|
|
55
|
+
walkAST(ast, (node) => {
|
|
56
|
+
if (node.type !== "JSXOpeningElement")
|
|
57
|
+
return;
|
|
58
|
+
let elementName = null;
|
|
59
|
+
let rootName = null;
|
|
60
|
+
if (node.name?.type === "Identifier") {
|
|
61
|
+
elementName = node.name.value;
|
|
62
|
+
rootName = elementName;
|
|
63
|
+
} else if (node.name?.type === "JSXMemberExpression") {
|
|
64
|
+
const parts = [];
|
|
65
|
+
let cursor = node.name;
|
|
66
|
+
while (cursor?.type === "JSXMemberExpression") {
|
|
67
|
+
parts.unshift(cursor.property?.value);
|
|
68
|
+
cursor = cursor.object;
|
|
69
|
+
}
|
|
70
|
+
if (cursor?.type === "Identifier") {
|
|
71
|
+
parts.unshift(cursor.value);
|
|
72
|
+
rootName = cursor.value;
|
|
73
|
+
}
|
|
74
|
+
elementName = parts.join(".");
|
|
75
|
+
}
|
|
76
|
+
if (!rootName || !uiComponents.has(rootName))
|
|
77
|
+
return;
|
|
78
|
+
const usage = {
|
|
79
|
+
component: elementName,
|
|
80
|
+
props: new Map,
|
|
81
|
+
booleanProps: new Set,
|
|
82
|
+
hasSpread: false
|
|
83
|
+
};
|
|
84
|
+
for (const attr of node.attributes || []) {
|
|
85
|
+
if (attr.type === "SpreadElement" || attr.type === "JSXSpreadAttribute") {
|
|
86
|
+
usage.hasSpread = true;
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
if (attr.type !== "JSXAttribute")
|
|
90
|
+
continue;
|
|
91
|
+
const propName = attr.name?.value;
|
|
92
|
+
if (!propName)
|
|
93
|
+
continue;
|
|
94
|
+
if (!attr.value) {
|
|
95
|
+
usage.booleanProps.add(propName);
|
|
96
|
+
} else if (attr.value.type === "StringLiteral") {
|
|
97
|
+
usage.props.set(propName, attr.value.value);
|
|
98
|
+
} else {
|
|
99
|
+
usage.props.set(propName, "DYNAMIC");
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
usages.push(usage);
|
|
103
|
+
});
|
|
104
|
+
return usages;
|
|
105
|
+
}
|
|
106
|
+
function buildSafelists(allUsages, manifest) {
|
|
107
|
+
const classSafelist = new Set;
|
|
108
|
+
const attrSafelist = new Set;
|
|
109
|
+
const componentUsages = new Map;
|
|
110
|
+
for (const usage of allUsages) {
|
|
111
|
+
const existing = componentUsages.get(usage.component) ?? [];
|
|
112
|
+
existing.push(usage);
|
|
113
|
+
componentUsages.set(usage.component, existing);
|
|
114
|
+
}
|
|
115
|
+
for (const [entryName, entry] of Object.entries(manifest)) {
|
|
116
|
+
const matchingUsages = findMatchingUsages(entryName, componentUsages);
|
|
117
|
+
if (matchingUsages.length === 0) {
|
|
118
|
+
continue;
|
|
119
|
+
}
|
|
120
|
+
for (const cls of entry.classes.always) {
|
|
121
|
+
classSafelist.add(cls);
|
|
122
|
+
}
|
|
123
|
+
for (const [propOrSlot, value] of Object.entries(entry.classes.byProp)) {
|
|
124
|
+
if (Array.isArray(value)) {
|
|
125
|
+
if (isPropUsed(propOrSlot, matchingUsages)) {
|
|
126
|
+
for (const cls of value)
|
|
127
|
+
classSafelist.add(cls);
|
|
128
|
+
}
|
|
129
|
+
} else {
|
|
130
|
+
const usedValues = getUsedEnumValues(propOrSlot, matchingUsages);
|
|
131
|
+
if (usedValues === "ALL") {
|
|
132
|
+
for (const classes of Object.values(value)) {
|
|
133
|
+
for (const cls of classes)
|
|
134
|
+
classSafelist.add(cls);
|
|
135
|
+
}
|
|
136
|
+
} else {
|
|
137
|
+
for (const val of usedValues) {
|
|
138
|
+
if (value[val]) {
|
|
139
|
+
for (const cls of value[val])
|
|
140
|
+
classSafelist.add(cls);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
if (entry.attrs) {
|
|
147
|
+
for (const [propName, attrMap] of Object.entries(entry.attrs)) {
|
|
148
|
+
if (isPropUsed(propName, matchingUsages)) {
|
|
149
|
+
for (const [attr, val] of Object.entries(attrMap)) {
|
|
150
|
+
attrSafelist.add(`${attr}=${val}`);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
return { classSafelist, attrSafelist };
|
|
157
|
+
}
|
|
158
|
+
function findMatchingUsages(entryName, usageMap) {
|
|
159
|
+
if (usageMap.has(entryName)) {
|
|
160
|
+
return usageMap.get(entryName);
|
|
161
|
+
}
|
|
162
|
+
const results = [];
|
|
163
|
+
for (const [usageName, usages] of usageMap) {
|
|
164
|
+
if (usageName === entryName) {
|
|
165
|
+
results.push(...usages);
|
|
166
|
+
}
|
|
167
|
+
if (entryName.includes(".")) {
|
|
168
|
+
const [family, part] = entryName.split(".");
|
|
169
|
+
if (part === family && usageName === family) {
|
|
170
|
+
results.push(...usages);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
return results;
|
|
175
|
+
}
|
|
176
|
+
function isPropUsed(propName, usages) {
|
|
177
|
+
for (const usage of usages) {
|
|
178
|
+
if (usage.hasSpread)
|
|
179
|
+
return true;
|
|
180
|
+
if (usage.booleanProps.has(propName))
|
|
181
|
+
return true;
|
|
182
|
+
if (usage.props.has(propName))
|
|
183
|
+
return true;
|
|
184
|
+
}
|
|
185
|
+
return false;
|
|
186
|
+
}
|
|
187
|
+
function getUsedEnumValues(slotName, usages) {
|
|
188
|
+
const values = new Set;
|
|
189
|
+
for (const usage of usages) {
|
|
190
|
+
if (usage.hasSpread)
|
|
191
|
+
return "ALL";
|
|
192
|
+
const val = usage.props.get(slotName);
|
|
193
|
+
if (val === "DYNAMIC")
|
|
194
|
+
return "ALL";
|
|
195
|
+
if (val !== undefined)
|
|
196
|
+
values.add(val);
|
|
197
|
+
if (usage.booleanProps.has(slotName))
|
|
198
|
+
return "ALL";
|
|
199
|
+
}
|
|
200
|
+
return values;
|
|
201
|
+
}
|
|
202
|
+
async function scanConsumerSource(srcDir) {
|
|
203
|
+
const allUsages = [];
|
|
204
|
+
const glob = new Glob("**/*.{tsx,ts,jsx,js}");
|
|
205
|
+
for await (const relPath of glob.scan({ cwd: srcDir })) {
|
|
206
|
+
if (relPath.includes("node_modules"))
|
|
207
|
+
continue;
|
|
208
|
+
const fullPath = path.join(srcDir, relPath);
|
|
209
|
+
const code = await Bun.file(fullPath).text();
|
|
210
|
+
if (!code.includes("@pathscale/ui"))
|
|
211
|
+
continue;
|
|
212
|
+
const isTsx = /\.[tj]sx$/.test(relPath);
|
|
213
|
+
const ast = await swc.parse(code, { syntax: "typescript", tsx: isTsx });
|
|
214
|
+
const uiImports = extractUIImports(ast);
|
|
215
|
+
if (uiImports.size === 0)
|
|
216
|
+
continue;
|
|
217
|
+
allUsages.push(...extractJSXUsages(ast, uiImports));
|
|
218
|
+
}
|
|
219
|
+
return allUsages;
|
|
220
|
+
}
|
|
221
|
+
if (false) {}
|
|
222
|
+
|
|
223
|
+
// src/postbuild-purge.ts
|
|
224
|
+
function parseArgs(argv) {
|
|
225
|
+
const args = argv.slice(2);
|
|
226
|
+
let distDir = "./dist";
|
|
227
|
+
let srcDir = "./src";
|
|
228
|
+
let manifestPath = "";
|
|
229
|
+
for (let i = 0;i < args.length; i++) {
|
|
230
|
+
if (args[i] === "--dist" && args[i + 1])
|
|
231
|
+
distDir = args[++i];
|
|
232
|
+
else if (args[i] === "--src" && args[i + 1])
|
|
233
|
+
srcDir = args[++i];
|
|
234
|
+
else if (args[i] === "--manifest" && args[i + 1])
|
|
235
|
+
manifestPath = args[++i];
|
|
236
|
+
}
|
|
237
|
+
if (!manifestPath) {
|
|
238
|
+
console.error("Usage: bunx @pathscale/rebuild-plugin-ui-css-purge --manifest <path> [--dist <path>] [--src <path>]");
|
|
239
|
+
process.exit(1);
|
|
240
|
+
}
|
|
241
|
+
return {
|
|
242
|
+
distDir: path2.resolve(distDir),
|
|
243
|
+
srcDir: path2.resolve(srcDir),
|
|
244
|
+
manifestPath: path2.resolve(manifestPath)
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
function purgeAttributes(css, attrSafelist) {
|
|
248
|
+
const root = postcss.parse(css);
|
|
249
|
+
root.walkRules((rule) => {
|
|
250
|
+
const selectors = rule.selectors;
|
|
251
|
+
const kept = [];
|
|
252
|
+
for (const sel of selectors) {
|
|
253
|
+
const attrMatches = sel.matchAll(/\[(data-[a-z-]+|aria-[a-z-]+)="([^"]+)"\]/g);
|
|
254
|
+
let shouldKeep = true;
|
|
255
|
+
for (const match of attrMatches) {
|
|
256
|
+
const attrSelector = `[${match[1]}="${match[2]}"]`;
|
|
257
|
+
if (match[1] === "data-slot")
|
|
258
|
+
continue;
|
|
259
|
+
if (!attrSafelist.has(attrSelector)) {
|
|
260
|
+
shouldKeep = false;
|
|
261
|
+
break;
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
if (shouldKeep)
|
|
265
|
+
kept.push(sel);
|
|
266
|
+
}
|
|
267
|
+
if (kept.length === 0) {
|
|
268
|
+
rule.remove();
|
|
269
|
+
} else if (kept.length < selectors.length) {
|
|
270
|
+
rule.selectors = kept;
|
|
271
|
+
}
|
|
272
|
+
});
|
|
273
|
+
return root.toString();
|
|
274
|
+
}
|
|
275
|
+
function cleanUnusedVars(css) {
|
|
276
|
+
let changed = true;
|
|
277
|
+
let result = css;
|
|
278
|
+
while (changed) {
|
|
279
|
+
changed = false;
|
|
280
|
+
const root = postcss.parse(result);
|
|
281
|
+
const declared = new Map;
|
|
282
|
+
root.walkDecls(/^--/, (decl) => {
|
|
283
|
+
const entries = declared.get(decl.prop) ?? [];
|
|
284
|
+
entries.push({ rule: decl.parent, prop: decl.prop, index: entries.length });
|
|
285
|
+
declared.set(decl.prop, entries);
|
|
286
|
+
});
|
|
287
|
+
const referenced = new Set;
|
|
288
|
+
root.walkDecls((decl) => {
|
|
289
|
+
const refs = decl.value.matchAll(/var\(\s*(--[a-zA-Z0-9_-]+)/g);
|
|
290
|
+
for (const ref of refs) {
|
|
291
|
+
referenced.add(ref[1]);
|
|
292
|
+
}
|
|
293
|
+
});
|
|
294
|
+
for (const [varName, entries] of declared) {
|
|
295
|
+
if (!referenced.has(varName)) {
|
|
296
|
+
for (const entry of entries) {
|
|
297
|
+
entry.rule.walkDecls(entry.prop, (decl) => {
|
|
298
|
+
decl.remove();
|
|
299
|
+
changed = true;
|
|
300
|
+
});
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
root.walkRules((rule) => {
|
|
305
|
+
if (rule.nodes && rule.nodes.length === 0)
|
|
306
|
+
rule.remove();
|
|
307
|
+
});
|
|
308
|
+
root.walkAtRules((atRule) => {
|
|
309
|
+
if (atRule.nodes && atRule.nodes.length === 0)
|
|
310
|
+
atRule.remove();
|
|
311
|
+
});
|
|
312
|
+
result = root.toString();
|
|
313
|
+
}
|
|
314
|
+
return result;
|
|
315
|
+
}
|
|
316
|
+
async function main() {
|
|
317
|
+
const { distDir, srcDir, manifestPath } = parseArgs(process.argv);
|
|
318
|
+
const manifest = JSON.parse(await Bun.file(manifestPath).text());
|
|
319
|
+
console.log(`[css-purge] Manifest loaded: ${Object.keys(manifest).length} entries`);
|
|
320
|
+
const usages = await scanConsumerSource(srcDir);
|
|
321
|
+
console.log(`[css-purge] Scanned ${srcDir}: ${usages.length} component usages`);
|
|
322
|
+
const { classSafelist, attrSafelist } = buildSafelists(usages, manifest);
|
|
323
|
+
console.log(`[css-purge] Safelist: ${classSafelist.size} classes, ${attrSafelist.size} attrs`);
|
|
324
|
+
const glob = new Glob2("**/*.css");
|
|
325
|
+
let totalBefore = 0;
|
|
326
|
+
let totalAfter = 0;
|
|
327
|
+
for await (const relPath of glob.scan({ cwd: distDir })) {
|
|
328
|
+
const fullPath = path2.join(distDir, relPath);
|
|
329
|
+
const originalCss = await Bun.file(fullPath).text();
|
|
330
|
+
const originalSize = Buffer.byteLength(originalCss, "utf-8");
|
|
331
|
+
totalBefore += originalSize;
|
|
332
|
+
console.log(`[css-purge] Processing ${relPath} (${(originalSize / 1024).toFixed(1)} KB)`);
|
|
333
|
+
const purgeResult = await new PurgeCSS().purge({
|
|
334
|
+
content: [],
|
|
335
|
+
css: [{ raw: originalCss }],
|
|
336
|
+
safelist: [...classSafelist],
|
|
337
|
+
keyframes: false,
|
|
338
|
+
fontFace: false
|
|
339
|
+
});
|
|
340
|
+
let purgedCss = purgeResult[0]?.css ?? originalCss;
|
|
341
|
+
const afterL1 = Buffer.byteLength(purgedCss, "utf-8");
|
|
342
|
+
console.log(`[css-purge] L1 class purge: ${(originalSize / 1024).toFixed(1)} \u2192 ${(afterL1 / 1024).toFixed(1)} KB`);
|
|
343
|
+
if (attrSafelist.size > 0) {
|
|
344
|
+
purgedCss = purgeAttributes(purgedCss, attrSafelist);
|
|
345
|
+
const afterL2 = Buffer.byteLength(purgedCss, "utf-8");
|
|
346
|
+
console.log(`[css-purge] L2 attr purge: ${(afterL1 / 1024).toFixed(1)} \u2192 ${(afterL2 / 1024).toFixed(1)} KB`);
|
|
347
|
+
}
|
|
348
|
+
purgedCss = cleanUnusedVars(purgedCss);
|
|
349
|
+
const afterL3 = Buffer.byteLength(purgedCss, "utf-8");
|
|
350
|
+
console.log(`[css-purge] L3 var cleanup: \u2192 ${(afterL3 / 1024).toFixed(1)} KB`);
|
|
351
|
+
const finalSize = Buffer.byteLength(purgedCss, "utf-8");
|
|
352
|
+
totalAfter += finalSize;
|
|
353
|
+
console.log(`[css-purge] Final: ${(originalSize / 1024).toFixed(1)} \u2192 ${(finalSize / 1024).toFixed(1)} KB (${((1 - finalSize / originalSize) * 100).toFixed(1)}% reduction)`);
|
|
354
|
+
await Bun.write(fullPath, purgedCss);
|
|
355
|
+
}
|
|
356
|
+
console.log(`
|
|
357
|
+
[css-purge] Total: ${(totalBefore / 1024).toFixed(1)} \u2192 ${(totalAfter / 1024).toFixed(1)} KB (${((1 - totalAfter / totalBefore) * 100).toFixed(1)}% reduction)`);
|
|
358
|
+
}
|
|
359
|
+
main();
|
|
360
|
+
|
|
361
|
+
//# debugId=9846F414E5F0A23D64756E2164756E21
|
|
362
|
+
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vc3JjL3Bvc3RidWlsZC1wdXJnZS50cyIsICIuLi9zcmMvc2Nhbi1jb25zdW1lci50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsKICAgICIjIS91c3IvYmluL2VudiBidW5cbi8qKlxuICogUG9zdGJ1aWxkIENTUyBwdXJnZSDigJQgc3RhbmRhbG9uZSBCdW4gc2NyaXB0LlxuICpcbiAqIFJ1bnMgYWZ0ZXIgcnNidWlsZCBidWlsZCwgcHVyZ2VzIENTUyBmaWxlcyBpbiBkaXN0LyB1c2luZyB0aGUgcHVyZ2UgbWFuaWZlc3RcbiAqIGFuZCBjb25zdW1lciBKU1ggYW5hbHlzaXMuIFplcm8gTm9kZSBpbXBvcnRzLlxuICpcbiAqIFVzYWdlOlxuICogICBidW54IEBwYXRoc2NhbGUvcmVidWlsZC1wbHVnaW4tdWktY3NzLXB1cmdlIFxcXG4gKiAgICAgLS1kaXN0IGRpc3QgLS1zcmMgc3JjIC0tbWFuaWZlc3Qgbm9kZV9tb2R1bGVzL0BwYXRoc2NhbGUvdWkvZGlzdC9wdXJnZS1tYW5pZmVzdC5qc29uXG4gKi9cblxuaW1wb3J0IHsgR2xvYiB9IGZyb20gXCJidW5cIjtcbmltcG9ydCB7IFB1cmdlQ1NTIH0gZnJvbSBcInB1cmdlY3NzXCI7XG5pbXBvcnQgcG9zdGNzcyBmcm9tIFwicG9zdGNzc1wiO1xuaW1wb3J0IHR5cGUgeyBSdWxlLCBBdFJ1bGUgfSBmcm9tIFwicG9zdGNzc1wiO1xuaW1wb3J0IHBhdGggZnJvbSBcInBhdGhcIjtcbmltcG9ydCB7IHNjYW5Db25zdW1lclNvdXJjZSwgYnVpbGRTYWZlbGlzdHMgfSBmcm9tIFwiLi9zY2FuLWNvbnN1bWVyXCI7XG5pbXBvcnQgdHlwZSB7IFB1cmdlTWFuaWZlc3QgfSBmcm9tIFwiLi9zY2FuLWNvbnN1bWVyXCI7XG5cbi8vIOKUgOKUgCBDTEkgYXJncyDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuZnVuY3Rpb24gcGFyc2VBcmdzKGFyZ3Y6IHN0cmluZ1tdKTogeyBkaXN0RGlyOiBzdHJpbmc7IHNyY0Rpcjogc3RyaW5nOyBtYW5pZmVzdFBhdGg6IHN0cmluZyB9IHtcbiAgY29uc3QgYXJncyA9IGFyZ3Yuc2xpY2UoMik7XG4gIGxldCBkaXN0RGlyID0gXCIuL2Rpc3RcIjtcbiAgbGV0IHNyY0RpciA9IFwiLi9zcmNcIjtcbiAgbGV0IG1hbmlmZXN0UGF0aCA9IFwiXCI7XG5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBhcmdzLmxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKGFyZ3NbaV0gPT09IFwiLS1kaXN0XCIgJiYgYXJnc1tpICsgMV0pIGRpc3REaXIgPSBhcmdzWysraV07XG4gICAgZWxzZSBpZiAoYXJnc1tpXSA9PT0gXCItLXNyY1wiICYmIGFyZ3NbaSArIDFdKSBzcmNEaXIgPSBhcmdzWysraV07XG4gICAgZWxzZSBpZiAoYXJnc1tpXSA9PT0gXCItLW1hbmlmZXN0XCIgJiYgYXJnc1tpICsgMV0pIG1hbmlmZXN0UGF0aCA9IGFyZ3NbKytpXTtcbiAgfVxuXG4gIGlmICghbWFuaWZlc3RQYXRoKSB7XG4gICAgY29uc29sZS5lcnJvcihcbiAgICAgIFwiVXNhZ2U6IGJ1bnggQHBhdGhzY2FsZS9yZWJ1aWxkLXBsdWdpbi11aS1jc3MtcHVyZ2UgLS1tYW5pZmVzdCA8cGF0aD4gWy0tZGlzdCA8cGF0aD5dIFstLXNyYyA8cGF0aD5dXCIsXG4gICAgKTtcbiAgICBwcm9jZXNzLmV4aXQoMSk7XG4gIH1cblxuICByZXR1cm4ge1xuICAgIGRpc3REaXI6IHBhdGgucmVzb2x2ZShkaXN0RGlyKSxcbiAgICBzcmNEaXI6IHBhdGgucmVzb2x2ZShzcmNEaXIpLFxuICAgIG1hbmlmZXN0UGF0aDogcGF0aC5yZXNvbHZlKG1hbmlmZXN0UGF0aCksXG4gIH07XG59XG5cbi8vIOKUgOKUgCBMZXZlbCAyOiBhdHRyaWJ1dGUgcHVyZ2Ug4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbmZ1bmN0aW9uIHB1cmdlQXR0cmlidXRlcyhjc3M6IHN0cmluZywgYXR0clNhZmVsaXN0OiBTZXQ8c3RyaW5nPik6IHN0cmluZyB7XG4gIGNvbnN0IHJvb3QgPSBwb3N0Y3NzLnBhcnNlKGNzcyk7XG5cbiAgcm9vdC53YWxrUnVsZXMoKHJ1bGUpID0+IHtcbiAgICBjb25zdCBzZWxlY3RvcnMgPSBydWxlLnNlbGVjdG9ycztcbiAgICBjb25zdCBrZXB0OiBzdHJpbmdbXSA9IFtdO1xuXG4gICAgZm9yIChjb25zdCBzZWwgb2Ygc2VsZWN0b3JzKSB7XG4gICAgICBjb25zdCBhdHRyTWF0Y2hlcyA9IHNlbC5tYXRjaEFsbCgvXFxbKGRhdGEtW2Etei1dK3xhcmlhLVthLXotXSspPVwiKFteXCJdKylcIlxcXS9nKTtcbiAgICAgIGxldCBzaG91bGRLZWVwID0gdHJ1ZTtcblxuICAgICAgZm9yIChjb25zdCBtYXRjaCBvZiBhdHRyTWF0Y2hlcykge1xuICAgICAgICBjb25zdCBhdHRyU2VsZWN0b3IgPSBgWyR7bWF0Y2hbMV19PVwiJHttYXRjaFsyXX1cIl1gO1xuICAgICAgICBpZiAobWF0Y2hbMV0gPT09IFwiZGF0YS1zbG90XCIpIGNvbnRpbnVlO1xuICAgICAgICBpZiAoIWF0dHJTYWZlbGlzdC5oYXMoYXR0clNlbGVjdG9yKSkge1xuICAgICAgICAgIHNob3VsZEtlZXAgPSBmYWxzZTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoc2hvdWxkS2VlcCkga2VwdC5wdXNoKHNlbCk7XG4gICAgfVxuXG4gICAgaWYgKGtlcHQubGVuZ3RoID09PSAwKSB7XG4gICAgICBydWxlLnJlbW92ZSgpO1xuICAgIH0gZWxzZSBpZiAoa2VwdC5sZW5ndGggPCBzZWxlY3RvcnMubGVuZ3RoKSB7XG4gICAgICBydWxlLnNlbGVjdG9ycyA9IGtlcHQ7XG4gICAgfVxuICB9KTtcblxuICByZXR1cm4gcm9vdC50b1N0cmluZygpO1xufVxuXG4vLyDilIDilIAgTGV2ZWwgMzogdW51c2VkIENTUyB2YXJpYWJsZSBjbGVhbnVwIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG5mdW5jdGlvbiBjbGVhblVudXNlZFZhcnMoY3NzOiBzdHJpbmcpOiBzdHJpbmcge1xuICBsZXQgY2hhbmdlZCA9IHRydWU7XG4gIGxldCByZXN1bHQgPSBjc3M7XG5cbiAgd2hpbGUgKGNoYW5nZWQpIHtcbiAgICBjaGFuZ2VkID0gZmFsc2U7XG4gICAgY29uc3Qgcm9vdCA9IHBvc3Rjc3MucGFyc2UocmVzdWx0KTtcblxuICAgIGNvbnN0IGRlY2xhcmVkID0gbmV3IE1hcDxzdHJpbmcsIHsgcnVsZTogUnVsZSB8IEF0UnVsZTsgcHJvcDogc3RyaW5nOyBpbmRleDogbnVtYmVyIH1bXT4oKTtcbiAgICByb290LndhbGtEZWNscygvXi0tLywgKGRlY2wpID0+IHtcbiAgICAgIGNvbnN0IGVudHJpZXMgPSBkZWNsYXJlZC5nZXQoZGVjbC5wcm9wKSA/PyBbXTtcbiAgICAgIGVudHJpZXMucHVzaCh7IHJ1bGU6IGRlY2wucGFyZW50IGFzIFJ1bGUsIHByb3A6IGRlY2wucHJvcCwgaW5kZXg6IGVudHJpZXMubGVuZ3RoIH0pO1xuICAgICAgZGVjbGFyZWQuc2V0KGRlY2wucHJvcCwgZW50cmllcyk7XG4gICAgfSk7XG5cbiAgICBjb25zdCByZWZlcmVuY2VkID0gbmV3IFNldDxzdHJpbmc+KCk7XG4gICAgcm9vdC53YWxrRGVjbHMoKGRlY2wpID0+IHtcbiAgICAgIGNvbnN0IHJlZnMgPSBkZWNsLnZhbHVlLm1hdGNoQWxsKC92YXJcXChcXHMqKC0tW2EtekEtWjAtOV8tXSspL2cpO1xuICAgICAgZm9yIChjb25zdCByZWYgb2YgcmVmcykge1xuICAgICAgICByZWZlcmVuY2VkLmFkZChyZWZbMV0pO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgZm9yIChjb25zdCBbdmFyTmFtZSwgZW50cmllc10gb2YgZGVjbGFyZWQpIHtcbiAgICAgIGlmICghcmVmZXJlbmNlZC5oYXModmFyTmFtZSkpIHtcbiAgICAgICAgZm9yIChjb25zdCBlbnRyeSBvZiBlbnRyaWVzKSB7XG4gICAgICAgICAgZW50cnkucnVsZS53YWxrRGVjbHMoZW50cnkucHJvcCwgKGRlY2wpID0+IHtcbiAgICAgICAgICAgIGRlY2wucmVtb3ZlKCk7XG4gICAgICAgICAgICBjaGFuZ2VkID0gdHJ1ZTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHJvb3Qud2Fsa1J1bGVzKChydWxlKSA9PiB7XG4gICAgICBpZiAocnVsZS5ub2RlcyAmJiBydWxlLm5vZGVzLmxlbmd0aCA9PT0gMCkgcnVsZS5yZW1vdmUoKTtcbiAgICB9KTtcbiAgICByb290LndhbGtBdFJ1bGVzKChhdFJ1bGUpID0+IHtcbiAgICAgIGlmIChhdFJ1bGUubm9kZXMgJiYgYXRSdWxlLm5vZGVzLmxlbmd0aCA9PT0gMCkgYXRSdWxlLnJlbW92ZSgpO1xuICAgIH0pO1xuXG4gICAgcmVzdWx0ID0gcm9vdC50b1N0cmluZygpO1xuICB9XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuLy8g4pSA4pSAIE1haW4g4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbmFzeW5jIGZ1bmN0aW9uIG1haW4oKSB7XG4gIGNvbnN0IHsgZGlzdERpciwgc3JjRGlyLCBtYW5pZmVzdFBhdGggfSA9IHBhcnNlQXJncyhwcm9jZXNzLmFyZ3YpO1xuXG4gIC8vIDEuIExvYWQgbWFuaWZlc3RcbiAgY29uc3QgbWFuaWZlc3Q6IFB1cmdlTWFuaWZlc3QgPSBKU09OLnBhcnNlKFxuICAgIGF3YWl0IEJ1bi5maWxlKG1hbmlmZXN0UGF0aCkudGV4dCgpLFxuICApO1xuICBjb25zb2xlLmxvZyhgW2Nzcy1wdXJnZV0gTWFuaWZlc3QgbG9hZGVkOiAke09iamVjdC5rZXlzKG1hbmlmZXN0KS5sZW5ndGh9IGVudHJpZXNgKTtcblxuICAvLyAyLiBTY2FuIGNvbnN1bWVyIHNvdXJjZVxuICBjb25zdCB1c2FnZXMgPSBhd2FpdCBzY2FuQ29uc3VtZXJTb3VyY2Uoc3JjRGlyKTtcbiAgY29uc29sZS5sb2coYFtjc3MtcHVyZ2VdIFNjYW5uZWQgJHtzcmNEaXJ9OiAke3VzYWdlcy5sZW5ndGh9IGNvbXBvbmVudCB1c2FnZXNgKTtcblxuICAvLyAzLiBCdWlsZCBzYWZlbGlzdHNcbiAgY29uc3QgeyBjbGFzc1NhZmVsaXN0LCBhdHRyU2FmZWxpc3QgfSA9IGJ1aWxkU2FmZWxpc3RzKHVzYWdlcywgbWFuaWZlc3QpO1xuICBjb25zb2xlLmxvZyhgW2Nzcy1wdXJnZV0gU2FmZWxpc3Q6ICR7Y2xhc3NTYWZlbGlzdC5zaXplfSBjbGFzc2VzLCAke2F0dHJTYWZlbGlzdC5zaXplfSBhdHRyc2ApO1xuXG4gIC8vIDQuIEdsb2IgQ1NTIGZpbGVzIGluIGRpc3RcbiAgY29uc3QgZ2xvYiA9IG5ldyBHbG9iKFwiKiovKi5jc3NcIik7XG4gIGxldCB0b3RhbEJlZm9yZSA9IDA7XG4gIGxldCB0b3RhbEFmdGVyID0gMDtcblxuICBmb3IgYXdhaXQgKGNvbnN0IHJlbFBhdGggb2YgZ2xvYi5zY2FuKHsgY3dkOiBkaXN0RGlyIH0pKSB7XG4gICAgY29uc3QgZnVsbFBhdGggPSBwYXRoLmpvaW4oZGlzdERpciwgcmVsUGF0aCk7XG4gICAgY29uc3Qgb3JpZ2luYWxDc3MgPSBhd2FpdCBCdW4uZmlsZShmdWxsUGF0aCkudGV4dCgpO1xuICAgIGNvbnN0IG9yaWdpbmFsU2l6ZSA9IEJ1ZmZlci5ieXRlTGVuZ3RoKG9yaWdpbmFsQ3NzLCBcInV0Zi04XCIpO1xuICAgIHRvdGFsQmVmb3JlICs9IG9yaWdpbmFsU2l6ZTtcblxuICAgIGNvbnNvbGUubG9nKGBbY3NzLXB1cmdlXSBQcm9jZXNzaW5nICR7cmVsUGF0aH0gKCR7KG9yaWdpbmFsU2l6ZSAvIDEwMjQpLnRvRml4ZWQoMSl9IEtCKWApO1xuXG4gICAgLy8gTGV2ZWwgMTogY2xhc3MtbGV2ZWwgcHVyZ2VcbiAgICBjb25zdCBwdXJnZVJlc3VsdCA9IGF3YWl0IG5ldyBQdXJnZUNTUygpLnB1cmdlKHtcbiAgICAgIGNvbnRlbnQ6IFtdLFxuICAgICAgY3NzOiBbeyByYXc6IG9yaWdpbmFsQ3NzIH1dLFxuICAgICAgc2FmZWxpc3Q6IFsuLi5jbGFzc1NhZmVsaXN0XSxcbiAgICAgIGtleWZyYW1lczogZmFsc2UsXG4gICAgICBmb250RmFjZTogZmFsc2UsXG4gICAgfSk7XG5cbiAgICBsZXQgcHVyZ2VkQ3NzID0gcHVyZ2VSZXN1bHRbMF0/LmNzcyA/PyBvcmlnaW5hbENzcztcbiAgICBjb25zdCBhZnRlckwxID0gQnVmZmVyLmJ5dGVMZW5ndGgocHVyZ2VkQ3NzLCBcInV0Zi04XCIpO1xuICAgIGNvbnNvbGUubG9nKGBbY3NzLXB1cmdlXSAgIEwxIGNsYXNzIHB1cmdlOiAkeyhvcmlnaW5hbFNpemUgLyAxMDI0KS50b0ZpeGVkKDEpfSDihpIgJHsoYWZ0ZXJMMSAvIDEwMjQpLnRvRml4ZWQoMSl9IEtCYCk7XG5cbiAgICAvLyBMZXZlbCAyOiBhdHRyaWJ1dGUtbGV2ZWwgcHVyZ2VcbiAgICBpZiAoYXR0clNhZmVsaXN0LnNpemUgPiAwKSB7XG4gICAgICBwdXJnZWRDc3MgPSBwdXJnZUF0dHJpYnV0ZXMocHVyZ2VkQ3NzLCBhdHRyU2FmZWxpc3QpO1xuICAgICAgY29uc3QgYWZ0ZXJMMiA9IEJ1ZmZlci5ieXRlTGVuZ3RoKHB1cmdlZENzcywgXCJ1dGYtOFwiKTtcbiAgICAgIGNvbnNvbGUubG9nKGBbY3NzLXB1cmdlXSAgIEwyIGF0dHIgcHVyZ2U6ICR7KGFmdGVyTDEgLyAxMDI0KS50b0ZpeGVkKDEpfSDihpIgJHsoYWZ0ZXJMMiAvIDEwMjQpLnRvRml4ZWQoMSl9IEtCYCk7XG4gICAgfVxuXG4gICAgLy8gTGV2ZWwgMzogdW51c2VkIENTUyB2YXJpYWJsZSBjbGVhbnVwXG4gICAgcHVyZ2VkQ3NzID0gY2xlYW5VbnVzZWRWYXJzKHB1cmdlZENzcyk7XG4gICAgY29uc3QgYWZ0ZXJMMyA9IEJ1ZmZlci5ieXRlTGVuZ3RoKHB1cmdlZENzcywgXCJ1dGYtOFwiKTtcbiAgICBjb25zb2xlLmxvZyhgW2Nzcy1wdXJnZV0gICBMMyB2YXIgY2xlYW51cDog4oaSICR7KGFmdGVyTDMgLyAxMDI0KS50b0ZpeGVkKDEpfSBLQmApO1xuXG4gICAgY29uc3QgZmluYWxTaXplID0gQnVmZmVyLmJ5dGVMZW5ndGgocHVyZ2VkQ3NzLCBcInV0Zi04XCIpO1xuICAgIHRvdGFsQWZ0ZXIgKz0gZmluYWxTaXplO1xuICAgIGNvbnNvbGUubG9nKGBbY3NzLXB1cmdlXSAgIEZpbmFsOiAkeyhvcmlnaW5hbFNpemUgLyAxMDI0KS50b0ZpeGVkKDEpfSDihpIgJHsoZmluYWxTaXplIC8gMTAyNCkudG9GaXhlZCgxKX0gS0IgKCR7KCgxIC0gZmluYWxTaXplIC8gb3JpZ2luYWxTaXplKSAqIDEwMCkudG9GaXhlZCgxKX0lIHJlZHVjdGlvbilgKTtcblxuICAgIC8vIFdyaXRlIGJhY2tcbiAgICBhd2FpdCBCdW4ud3JpdGUoZnVsbFBhdGgsIHB1cmdlZENzcyk7XG4gIH1cblxuICBjb25zb2xlLmxvZyhgXFxuW2Nzcy1wdXJnZV0gVG90YWw6ICR7KHRvdGFsQmVmb3JlIC8gMTAyNCkudG9GaXhlZCgxKX0g4oaSICR7KHRvdGFsQWZ0ZXIgLyAxMDI0KS50b0ZpeGVkKDEpfSBLQiAoJHsoKDEgLSB0b3RhbEFmdGVyIC8gdG90YWxCZWZvcmUpICogMTAwKS50b0ZpeGVkKDEpfSUgcmVkdWN0aW9uKWApO1xufVxuXG5tYWluKCk7XG4iLAogICAgIi8qKlxuICogQ29uc3VtZXItc2lkZSBKU1ggc2Nhbm5lci5cbiAqXG4gKiBXYWxrcyBhIGNvbnN1bWVyJ3Mgc291cmNlIHRyZWUsIGZpbmRzIGNvbXBvbmVudCBpbXBvcnRzIGZyb20gQHBhdGhzY2FsZS91aSxcbiAqIGNvbGxlY3RzIHByb3AgdmFsdWVzLCBhbmQgY3Jvc3MtcmVmZXJlbmNlcyB3aXRoIHRoZSBwdXJnZSBtYW5pZmVzdCB0byBidWlsZFxuICogTGV2ZWwgMSAoY2xhc3MpIGFuZCBMZXZlbCAyIChhdHRyaWJ1dGUpIHNhZmVsaXN0cy5cbiAqXG4gKiBVc2FnZTogIGJ1biBydW4gc3JjL3NjYW4tY29uc3VtZXIudHMgPGNvbnN1bWVyLXNyYy1kaXI+IDxwdXJnZS1tYW5pZmVzdC5qc29uPlxuICovXG5cbmltcG9ydCBzd2MgZnJvbSBcIkBzd2MvY29yZVwiO1xuaW1wb3J0IHsgR2xvYiB9IGZyb20gXCJidW5cIjtcbmltcG9ydCBwYXRoIGZyb20gXCJwYXRoXCI7XG5cbi8vIOKUgOKUgCBUeXBlcyDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuaW50ZXJmYWNlIENvbXBvbmVudE1hbmlmZXN0IHtcbiAgY2xhc3Nlczoge1xuICAgIGFsd2F5czogc3RyaW5nW107XG4gICAgYnlQcm9wOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmdbXSB8IFJlY29yZDxzdHJpbmcsIHN0cmluZ1tdPj47XG4gIH07XG4gIGF0dHJzPzogUmVjb3JkPHN0cmluZywgUmVjb3JkPHN0cmluZywgc3RyaW5nPj47XG59XG5cbnR5cGUgUHVyZ2VNYW5pZmVzdCA9IFJlY29yZDxzdHJpbmcsIENvbXBvbmVudE1hbmlmZXN0PjtcblxuLyoqIFdoYXQgd2UgY29sbGVjdCBwZXIgY29tcG9uZW50IHVzYWdlIGZyb20gSlNYICovXG5pbnRlcmZhY2UgUHJvcFVzYWdlIHtcbiAgY29tcG9uZW50OiBzdHJpbmc7XG4gIHByb3BzOiBNYXA8c3RyaW5nLCBzdHJpbmcgfCBcIkRZTkFNSUNcIj47IC8vIHByb3BOYW1lIOKGkiBsaXRlcmFsIHZhbHVlIG9yIERZTkFNSUNcbiAgYm9vbGVhblByb3BzOiBTZXQ8c3RyaW5nPjsgLy8gcHJvcHMgcHJlc2VudCB3aXRob3V0IGEgdmFsdWUgKHRydXRoeSlcbiAgaGFzU3ByZWFkOiBib29sZWFuO1xufVxuXG4vLyDilIDilIAgQVNUIHdhbGtlciDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuZnVuY3Rpb24gd2Fsa0FTVChub2RlOiBhbnksIHZpc2l0b3I6IChub2RlOiBhbnkpID0+IHZvaWQpIHtcbiAgaWYgKCFub2RlIHx8IHR5cGVvZiBub2RlICE9PSBcIm9iamVjdFwiKSByZXR1cm47XG4gIHZpc2l0b3Iobm9kZSk7XG4gIGZvciAoY29uc3Qga2V5IG9mIE9iamVjdC5rZXlzKG5vZGUpKSB7XG4gICAgaWYgKGtleSA9PT0gXCJzcGFuXCIpIGNvbnRpbnVlO1xuICAgIGNvbnN0IHZhbCA9IG5vZGVba2V5XTtcbiAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWwpKSB7XG4gICAgICBmb3IgKGNvbnN0IGl0ZW0gb2YgdmFsKSB3YWxrQVNUKGl0ZW0sIHZpc2l0b3IpO1xuICAgIH0gZWxzZSBpZiAodmFsICYmIHR5cGVvZiB2YWwgPT09IFwib2JqZWN0XCIpIHtcbiAgICAgIHdhbGtBU1QodmFsLCB2aXNpdG9yKTtcbiAgICB9XG4gIH1cbn1cblxuLyoqIEV4dHJhY3QgQHBhdGhzY2FsZS91aSBpbXBvcnRzIGZyb20gYSBwYXJzZWQgbW9kdWxlICovXG5mdW5jdGlvbiBleHRyYWN0VUlJbXBvcnRzKGFzdDogYW55KTogTWFwPHN0cmluZywgc3RyaW5nPiB7XG4gIGNvbnN0IGltcG9ydHMgPSBuZXcgTWFwPHN0cmluZywgc3RyaW5nPigpO1xuICBmb3IgKGNvbnN0IG5vZGUgb2YgYXN0LmJvZHkpIHtcbiAgICBpZiAobm9kZS50eXBlICE9PSBcIkltcG9ydERlY2xhcmF0aW9uXCIpIGNvbnRpbnVlO1xuICAgIGNvbnN0IHNyYyA9IG5vZGUuc291cmNlPy52YWx1ZSBhcyBzdHJpbmc7XG4gICAgaWYgKCFzcmMgfHwgIXNyYy5zdGFydHNXaXRoKFwiQHBhdGhzY2FsZS91aVwiKSkgY29udGludWU7XG5cbiAgICBmb3IgKGNvbnN0IHNwZWMgb2Ygbm9kZS5zcGVjaWZpZXJzKSB7XG4gICAgICBpZiAoc3BlYy50eXBlID09PSBcIkltcG9ydFNwZWNpZmllclwiKSB7XG4gICAgICAgIGNvbnN0IGltcG9ydGVkID0gc3BlYy5pbXBvcnRlZD8udmFsdWUgPz8gc3BlYy5sb2NhbD8udmFsdWU7XG4gICAgICAgIGNvbnN0IGxvY2FsID0gc3BlYy5sb2NhbD8udmFsdWU7XG4gICAgICAgIGlmIChsb2NhbCAmJiBpbXBvcnRlZCkgaW1wb3J0cy5zZXQobG9jYWwsIGltcG9ydGVkKTtcbiAgICAgIH0gZWxzZSBpZiAoc3BlYy50eXBlID09PSBcIkltcG9ydERlZmF1bHRTcGVjaWZpZXJcIikge1xuICAgICAgICBjb25zdCBsb2NhbCA9IHNwZWMubG9jYWw/LnZhbHVlO1xuICAgICAgICBpZiAobG9jYWwpIGltcG9ydHMuc2V0KGxvY2FsLCBsb2NhbCk7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiBpbXBvcnRzO1xufVxuXG4vKiogRXh0cmFjdCBKU1ggdXNhZ2VzIG9mIFVJIGNvbXBvbmVudHMgKi9cbmZ1bmN0aW9uIGV4dHJhY3RKU1hVc2FnZXMoYXN0OiBhbnksIHVpQ29tcG9uZW50czogTWFwPHN0cmluZywgc3RyaW5nPik6IFByb3BVc2FnZVtdIHtcbiAgY29uc3QgdXNhZ2VzOiBQcm9wVXNhZ2VbXSA9IFtdO1xuXG4gIHdhbGtBU1QoYXN0LCAobm9kZSkgPT4ge1xuICAgIGlmIChub2RlLnR5cGUgIT09IFwiSlNYT3BlbmluZ0VsZW1lbnRcIikgcmV0dXJuO1xuXG4gICAgbGV0IGVsZW1lbnROYW1lOiBzdHJpbmcgfCBudWxsID0gbnVsbDtcbiAgICBsZXQgcm9vdE5hbWU6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuXG4gICAgaWYgKG5vZGUubmFtZT8udHlwZSA9PT0gXCJJZGVudGlmaWVyXCIpIHtcbiAgICAgIGVsZW1lbnROYW1lID0gbm9kZS5uYW1lLnZhbHVlO1xuICAgICAgcm9vdE5hbWUgPSBlbGVtZW50TmFtZTtcbiAgICB9IGVsc2UgaWYgKG5vZGUubmFtZT8udHlwZSA9PT0gXCJKU1hNZW1iZXJFeHByZXNzaW9uXCIpIHtcbiAgICAgIGNvbnN0IHBhcnRzOiBzdHJpbmdbXSA9IFtdO1xuICAgICAgbGV0IGN1cnNvciA9IG5vZGUubmFtZTtcbiAgICAgIHdoaWxlIChjdXJzb3I/LnR5cGUgPT09IFwiSlNYTWVtYmVyRXhwcmVzc2lvblwiKSB7XG4gICAgICAgIHBhcnRzLnVuc2hpZnQoY3Vyc29yLnByb3BlcnR5Py52YWx1ZSk7XG4gICAgICAgIGN1cnNvciA9IGN1cnNvci5vYmplY3Q7XG4gICAgICB9XG4gICAgICBpZiAoY3Vyc29yPy50eXBlID09PSBcIklkZW50aWZpZXJcIikge1xuICAgICAgICBwYXJ0cy51bnNoaWZ0KGN1cnNvci52YWx1ZSk7XG4gICAgICAgIHJvb3ROYW1lID0gY3Vyc29yLnZhbHVlO1xuICAgICAgfVxuICAgICAgZWxlbWVudE5hbWUgPSBwYXJ0cy5qb2luKFwiLlwiKTtcbiAgICB9XG5cbiAgICBpZiAoIXJvb3ROYW1lIHx8ICF1aUNvbXBvbmVudHMuaGFzKHJvb3ROYW1lKSkgcmV0dXJuO1xuXG4gICAgY29uc3QgdXNhZ2U6IFByb3BVc2FnZSA9IHtcbiAgICAgIGNvbXBvbmVudDogZWxlbWVudE5hbWUhLFxuICAgICAgcHJvcHM6IG5ldyBNYXAoKSxcbiAgICAgIGJvb2xlYW5Qcm9wczogbmV3IFNldCgpLFxuICAgICAgaGFzU3ByZWFkOiBmYWxzZSxcbiAgICB9O1xuXG4gICAgZm9yIChjb25zdCBhdHRyIG9mIG5vZGUuYXR0cmlidXRlcyB8fCBbXSkge1xuICAgICAgaWYgKGF0dHIudHlwZSA9PT0gXCJTcHJlYWRFbGVtZW50XCIgfHwgYXR0ci50eXBlID09PSBcIkpTWFNwcmVhZEF0dHJpYnV0ZVwiKSB7XG4gICAgICAgIHVzYWdlLmhhc1NwcmVhZCA9IHRydWU7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgaWYgKGF0dHIudHlwZSAhPT0gXCJKU1hBdHRyaWJ1dGVcIikgY29udGludWU7XG5cbiAgICAgIGNvbnN0IHByb3BOYW1lID0gYXR0ci5uYW1lPy52YWx1ZTtcbiAgICAgIGlmICghcHJvcE5hbWUpIGNvbnRpbnVlO1xuXG4gICAgICBpZiAoIWF0dHIudmFsdWUpIHtcbiAgICAgICAgdXNhZ2UuYm9vbGVhblByb3BzLmFkZChwcm9wTmFtZSk7XG4gICAgICB9IGVsc2UgaWYgKGF0dHIudmFsdWUudHlwZSA9PT0gXCJTdHJpbmdMaXRlcmFsXCIpIHtcbiAgICAgICAgdXNhZ2UucHJvcHMuc2V0KHByb3BOYW1lLCBhdHRyLnZhbHVlLnZhbHVlKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHVzYWdlLnByb3BzLnNldChwcm9wTmFtZSwgXCJEWU5BTUlDXCIpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHVzYWdlcy5wdXNoKHVzYWdlKTtcbiAgfSk7XG5cbiAgcmV0dXJuIHVzYWdlcztcbn1cblxuLy8g4pSA4pSAIFNhZmVsaXN0IGJ1aWxkZXIg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbmludGVyZmFjZSBTYWZlbGlzdHMge1xuICBjbGFzc1NhZmVsaXN0OiBTZXQ8c3RyaW5nPjtcbiAgYXR0clNhZmVsaXN0OiBTZXQ8c3RyaW5nPjtcbn1cblxuZnVuY3Rpb24gYnVpbGRTYWZlbGlzdHMoXG4gIGFsbFVzYWdlczogUHJvcFVzYWdlW10sXG4gIG1hbmlmZXN0OiBQdXJnZU1hbmlmZXN0LFxuKTogU2FmZWxpc3RzIHtcbiAgY29uc3QgY2xhc3NTYWZlbGlzdCA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuICBjb25zdCBhdHRyU2FmZWxpc3QgPSBuZXcgU2V0PHN0cmluZz4oKTtcblxuICBjb25zdCBjb21wb25lbnRVc2FnZXMgPSBuZXcgTWFwPHN0cmluZywgUHJvcFVzYWdlW10+KCk7XG4gIGZvciAoY29uc3QgdXNhZ2Ugb2YgYWxsVXNhZ2VzKSB7XG4gICAgY29uc3QgZXhpc3RpbmcgPSBjb21wb25lbnRVc2FnZXMuZ2V0KHVzYWdlLmNvbXBvbmVudCkgPz8gW107XG4gICAgZXhpc3RpbmcucHVzaCh1c2FnZSk7XG4gICAgY29tcG9uZW50VXNhZ2VzLnNldCh1c2FnZS5jb21wb25lbnQsIGV4aXN0aW5nKTtcbiAgfVxuXG4gIGZvciAoY29uc3QgW2VudHJ5TmFtZSwgZW50cnldIG9mIE9iamVjdC5lbnRyaWVzKG1hbmlmZXN0KSkge1xuICAgIGNvbnN0IG1hdGNoaW5nVXNhZ2VzID0gZmluZE1hdGNoaW5nVXNhZ2VzKGVudHJ5TmFtZSwgY29tcG9uZW50VXNhZ2VzKTtcblxuICAgIGlmIChtYXRjaGluZ1VzYWdlcy5sZW5ndGggPT09IDApIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIGZvciAoY29uc3QgY2xzIG9mIGVudHJ5LmNsYXNzZXMuYWx3YXlzKSB7XG4gICAgICBjbGFzc1NhZmVsaXN0LmFkZChjbHMpO1xuICAgIH1cblxuICAgIGZvciAoY29uc3QgW3Byb3BPclNsb3QsIHZhbHVlXSBvZiBPYmplY3QuZW50cmllcyhlbnRyeS5jbGFzc2VzLmJ5UHJvcCkpIHtcbiAgICAgIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgICAgICBpZiAoaXNQcm9wVXNlZChwcm9wT3JTbG90LCBtYXRjaGluZ1VzYWdlcykpIHtcbiAgICAgICAgICBmb3IgKGNvbnN0IGNscyBvZiB2YWx1ZSkgY2xhc3NTYWZlbGlzdC5hZGQoY2xzKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3QgdXNlZFZhbHVlcyA9IGdldFVzZWRFbnVtVmFsdWVzKHByb3BPclNsb3QsIG1hdGNoaW5nVXNhZ2VzKTtcbiAgICAgICAgaWYgKHVzZWRWYWx1ZXMgPT09IFwiQUxMXCIpIHtcbiAgICAgICAgICBmb3IgKGNvbnN0IGNsYXNzZXMgb2YgT2JqZWN0LnZhbHVlcyh2YWx1ZSkpIHtcbiAgICAgICAgICAgIGZvciAoY29uc3QgY2xzIG9mIGNsYXNzZXMpIGNsYXNzU2FmZWxpc3QuYWRkKGNscyk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGZvciAoY29uc3QgdmFsIG9mIHVzZWRWYWx1ZXMpIHtcbiAgICAgICAgICAgIGlmICh2YWx1ZVt2YWxdKSB7XG4gICAgICAgICAgICAgIGZvciAoY29uc3QgY2xzIG9mIHZhbHVlW3ZhbF0pIGNsYXNzU2FmZWxpc3QuYWRkKGNscyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGVudHJ5LmF0dHJzKSB7XG4gICAgICBmb3IgKGNvbnN0IFtwcm9wTmFtZSwgYXR0ck1hcF0gb2YgT2JqZWN0LmVudHJpZXMoZW50cnkuYXR0cnMpKSB7XG4gICAgICAgIGlmIChpc1Byb3BVc2VkKHByb3BOYW1lLCBtYXRjaGluZ1VzYWdlcykpIHtcbiAgICAgICAgICBmb3IgKGNvbnN0IFthdHRyLCB2YWxdIG9mIE9iamVjdC5lbnRyaWVzKGF0dHJNYXApKSB7XG4gICAgICAgICAgICBhdHRyU2FmZWxpc3QuYWRkKGAke2F0dHJ9PSR7dmFsfWApO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiB7IGNsYXNzU2FmZWxpc3QsIGF0dHJTYWZlbGlzdCB9O1xufVxuXG5mdW5jdGlvbiBmaW5kTWF0Y2hpbmdVc2FnZXMoXG4gIGVudHJ5TmFtZTogc3RyaW5nLFxuICB1c2FnZU1hcDogTWFwPHN0cmluZywgUHJvcFVzYWdlW10+LFxuKTogUHJvcFVzYWdlW10ge1xuICBpZiAodXNhZ2VNYXAuaGFzKGVudHJ5TmFtZSkpIHtcbiAgICByZXR1cm4gdXNhZ2VNYXAuZ2V0KGVudHJ5TmFtZSkhO1xuICB9XG5cbiAgY29uc3QgcmVzdWx0czogUHJvcFVzYWdlW10gPSBbXTtcbiAgZm9yIChjb25zdCBbdXNhZ2VOYW1lLCB1c2FnZXNdIG9mIHVzYWdlTWFwKSB7XG4gICAgaWYgKHVzYWdlTmFtZSA9PT0gZW50cnlOYW1lKSB7XG4gICAgICByZXN1bHRzLnB1c2goLi4udXNhZ2VzKTtcbiAgICB9XG4gICAgaWYgKGVudHJ5TmFtZS5pbmNsdWRlcyhcIi5cIikpIHtcbiAgICAgIGNvbnN0IFtmYW1pbHksIHBhcnRdID0gZW50cnlOYW1lLnNwbGl0KFwiLlwiKTtcbiAgICAgIGlmIChwYXJ0ID09PSBmYW1pbHkgJiYgdXNhZ2VOYW1lID09PSBmYW1pbHkpIHtcbiAgICAgICAgcmVzdWx0cy5wdXNoKC4uLnVzYWdlcyk7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiByZXN1bHRzO1xufVxuXG5mdW5jdGlvbiBpc1Byb3BVc2VkKHByb3BOYW1lOiBzdHJpbmcsIHVzYWdlczogUHJvcFVzYWdlW10pOiBib29sZWFuIHtcbiAgZm9yIChjb25zdCB1c2FnZSBvZiB1c2FnZXMpIHtcbiAgICBpZiAodXNhZ2UuaGFzU3ByZWFkKSByZXR1cm4gdHJ1ZTtcbiAgICBpZiAodXNhZ2UuYm9vbGVhblByb3BzLmhhcyhwcm9wTmFtZSkpIHJldHVybiB0cnVlO1xuICAgIGlmICh1c2FnZS5wcm9wcy5oYXMocHJvcE5hbWUpKSByZXR1cm4gdHJ1ZTtcbiAgfVxuICByZXR1cm4gZmFsc2U7XG59XG5cbmZ1bmN0aW9uIGdldFVzZWRFbnVtVmFsdWVzKHNsb3ROYW1lOiBzdHJpbmcsIHVzYWdlczogUHJvcFVzYWdlW10pOiBTZXQ8c3RyaW5nPiB8IFwiQUxMXCIge1xuICBjb25zdCB2YWx1ZXMgPSBuZXcgU2V0PHN0cmluZz4oKTtcbiAgZm9yIChjb25zdCB1c2FnZSBvZiB1c2FnZXMpIHtcbiAgICBpZiAodXNhZ2UuaGFzU3ByZWFkKSByZXR1cm4gXCJBTExcIjtcbiAgICBjb25zdCB2YWwgPSB1c2FnZS5wcm9wcy5nZXQoc2xvdE5hbWUpO1xuICAgIGlmICh2YWwgPT09IFwiRFlOQU1JQ1wiKSByZXR1cm4gXCJBTExcIjtcbiAgICBpZiAodmFsICE9PSB1bmRlZmluZWQpIHZhbHVlcy5hZGQodmFsKTtcbiAgICBpZiAodXNhZ2UuYm9vbGVhblByb3BzLmhhcyhzbG90TmFtZSkpIHJldHVybiBcIkFMTFwiO1xuICB9XG4gIHJldHVybiB2YWx1ZXM7XG59XG5cbi8vIOKUgOKUgCBDb25zdW1lciBzb3VyY2Ugc2Nhbm5pbmcg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbmFzeW5jIGZ1bmN0aW9uIHNjYW5Db25zdW1lclNvdXJjZShzcmNEaXI6IHN0cmluZyk6IFByb21pc2U8UHJvcFVzYWdlW10+IHtcbiAgY29uc3QgYWxsVXNhZ2VzOiBQcm9wVXNhZ2VbXSA9IFtdO1xuICBjb25zdCBnbG9iID0gbmV3IEdsb2IoXCIqKi8qLnt0c3gsdHMsanN4LGpzfVwiKTtcblxuICBmb3IgYXdhaXQgKGNvbnN0IHJlbFBhdGggb2YgZ2xvYi5zY2FuKHsgY3dkOiBzcmNEaXIgfSkpIHtcbiAgICBpZiAocmVsUGF0aC5pbmNsdWRlcyhcIm5vZGVfbW9kdWxlc1wiKSkgY29udGludWU7XG4gICAgY29uc3QgZnVsbFBhdGggPSBwYXRoLmpvaW4oc3JjRGlyLCByZWxQYXRoKTtcbiAgICBjb25zdCBjb2RlID0gYXdhaXQgQnVuLmZpbGUoZnVsbFBhdGgpLnRleHQoKTtcbiAgICBpZiAoIWNvZGUuaW5jbHVkZXMoXCJAcGF0aHNjYWxlL3VpXCIpKSBjb250aW51ZTtcblxuICAgIGNvbnN0IGlzVHN4ID0gL1xcLlt0al1zeCQvLnRlc3QocmVsUGF0aCk7XG4gICAgY29uc3QgYXN0ID0gYXdhaXQgc3djLnBhcnNlKGNvZGUsIHsgc3ludGF4OiBcInR5cGVzY3JpcHRcIiwgdHN4OiBpc1RzeCB9KTtcbiAgICBjb25zdCB1aUltcG9ydHMgPSBleHRyYWN0VUlJbXBvcnRzKGFzdCk7XG4gICAgaWYgKHVpSW1wb3J0cy5zaXplID09PSAwKSBjb250aW51ZTtcblxuICAgIGFsbFVzYWdlcy5wdXNoKC4uLmV4dHJhY3RKU1hVc2FnZXMoYXN0LCB1aUltcG9ydHMpKTtcbiAgfVxuXG4gIHJldHVybiBhbGxVc2FnZXM7XG59XG5cbi8vIOKUgOKUgCBNYWluIChzdGFuZGFsb25lIENMSSkg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbmFzeW5jIGZ1bmN0aW9uIG1haW4oKSB7XG4gIGNvbnN0IFtzcmNEaXIsIG1hbmlmZXN0UGF0aF0gPSBwcm9jZXNzLmFyZ3Yuc2xpY2UoMik7XG4gIGlmICghc3JjRGlyIHx8ICFtYW5pZmVzdFBhdGgpIHtcbiAgICBjb25zb2xlLmVycm9yKFwiVXNhZ2U6IGJ1biBydW4gc3JjL3NjYW4tY29uc3VtZXIudHMgPGNvbnN1bWVyLXNyYy1kaXI+IDxwdXJnZS1tYW5pZmVzdC5qc29uPlwiKTtcbiAgICBwcm9jZXNzLmV4aXQoMSk7XG4gIH1cblxuICBjb25zdCBtYW5pZmVzdDogUHVyZ2VNYW5pZmVzdCA9IEpTT04ucGFyc2UoXG4gICAgYXdhaXQgQnVuLmZpbGUobWFuaWZlc3RQYXRoKS50ZXh0KCksXG4gICk7XG4gIGNvbnN0IHJlc29sdmVkU3JjID0gcGF0aC5yZXNvbHZlKHNyY0Rpcik7XG4gIGNvbnNvbGUubG9nKGBTY2FubmluZyAke3Jlc29sdmVkU3JjfSBmb3IgQHBhdGhzY2FsZS91aSBjb21wb25lbnQgdXNhZ2XigKZgKTtcbiAgY29uc29sZS5sb2coYE1hbmlmZXN0OiAke09iamVjdC5rZXlzKG1hbmlmZXN0KS5sZW5ndGh9IGVudHJpZXNcXG5gKTtcblxuICBjb25zdCB1c2FnZXMgPSBhd2FpdCBzY2FuQ29uc3VtZXJTb3VyY2UocmVzb2x2ZWRTcmMpO1xuICBjb25zdCB7IGNsYXNzU2FmZWxpc3QsIGF0dHJTYWZlbGlzdCB9ID0gYnVpbGRTYWZlbGlzdHModXNhZ2VzLCBtYW5pZmVzdCk7XG5cbiAgY29uc29sZS5sb2coXCI9PT0gQ2xhc3MgU2FmZWxpc3QgPT09XCIpO1xuICBmb3IgKGNvbnN0IGNscyBvZiBbLi4uY2xhc3NTYWZlbGlzdF0uc29ydCgpKSB7XG4gICAgY29uc29sZS5sb2coYCAgJHtjbHN9YCk7XG4gIH1cblxuICBjb25zb2xlLmxvZyhgXFxuPT09IEF0dHJpYnV0ZSBTYWZlbGlzdCA9PT1gKTtcbiAgZm9yIChjb25zdCBhdHRyIG9mIFsuLi5hdHRyU2FmZWxpc3RdLnNvcnQoKSkge1xuICAgIGNvbnNvbGUubG9nKGAgIFske2F0dHJ9XWApO1xuICB9XG5cbiAgY29uc29sZS5sb2coYFxcblRvdGFsOiAke2NsYXNzU2FmZWxpc3Quc2l6ZX0gY2xhc3NlcywgJHthdHRyU2FmZWxpc3Quc2l6ZX0gYXR0cmlidXRlIHNlbGVjdG9yc2ApO1xufVxuXG4vLyBPbmx5IHJ1biBDTEkgd2hlbiBpbnZva2VkIGRpcmVjdGx5IChub3Qgd2hlbiBpbXBvcnRlZCBhcyBhIG1vZHVsZSlcbmlmIChpbXBvcnQubWV0YS5tYWluKSB7XG4gIG1haW4oKTtcbn1cblxuZXhwb3J0IHsgZXh0cmFjdFVJSW1wb3J0cywgZXh0cmFjdEpTWFVzYWdlcywgYnVpbGRTYWZlbGlzdHMsIHNjYW5Db25zdW1lclNvdXJjZSB9O1xuZXhwb3J0IHR5cGUgeyBQcm9wVXNhZ2UsIFB1cmdlTWFuaWZlc3QsIENvbXBvbmVudE1hbmlmZXN0LCBTYWZlbGlzdHMgfTtcbiIKICBdLAogICJtYXBwaW5ncyI6ICI7Ozs7QUFZQTtBQUNBO0FBQ0E7QUFFQTs7O0FDTkE7QUFDQTtBQUNBO0FBd0JBLFNBQVMsT0FBTyxDQUFDLE1BQVcsU0FBOEI7QUFBQSxFQUN4RCxJQUFJLENBQUMsUUFBUSxPQUFPLFNBQVM7QUFBQSxJQUFVO0FBQUEsRUFDdkMsUUFBUSxJQUFJO0FBQUEsRUFDWixXQUFXLE9BQU8sT0FBTyxLQUFLLElBQUksR0FBRztBQUFBLElBQ25DLElBQUksUUFBUTtBQUFBLE1BQVE7QUFBQSxJQUNwQixNQUFNLE1BQU0sS0FBSztBQUFBLElBQ2pCLElBQUksTUFBTSxRQUFRLEdBQUcs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QU8sVUFBVSxNQUFNLFFBQVEsQ0FBQyxNQUFNO0FBQUEsSUFHbEgsSUFBSSxhQUFhLE9BQU8sR0FBRztBQUFBLE1BQ3pCLFlBQVksZ0JBQWdCLFdBQVcsWUFBWTtBQUFBLE1BQ25ELE1BQU0sVUFBVSxPQUFPLFdBQVcsV0FBVyxPQUFPO0FBQUEsTUFDcEQsUUFBUSxJQUFJLGlDQUFpQyxVQUFVLE1BQU0sUUFBUSxDQUFDLGFBQU8sVUFBVSxNQUFNLFFBQVEsQ0FBQyxNQUFNO0FBQUEsSUFDOUc7QUFBQSxJQUdBLFlBQVksZ0JBQWdCLFNBQVM7QUFBQSxJQUNyQyxNQUFNLFVBQVUsT0FBTyxXQUFXLFdBQVcsT0FBTztBQUFBLElBQ3BELFFBQVEsSUFBSSx5Q0FBbUMsVUFBVSxNQUFNLFFBQVEsQ0FBQyxNQUFNO0FBQUEsSUFFOUUsTUFBTSxZQUFZLE9BQU8sV0FBVyxXQUFXLE9BQU87QUFBQSxJQUN0RCxjQUFjO0FBQUEsSUFDZCxRQUFRLElBQUkseUJBQXlCLGVBQWUsTUFBTSxRQUFRLENBQUMsYUFBTyxZQUFZLE1BQU0sUUFBUSxDQUFDLFdBQVcsSUFBSSxZQUFZLGdCQUFnQixLQUFLLFFBQVEsQ0FBQyxlQUFlO0FBQUEsSUFHN0ssTUFBTSxJQUFJLE1BQU0sVUFBVSxTQUFTO0FBQUEsRUFDckM7QUFBQSxFQUVBLFFBQVEsSUFBSTtBQUFBLHNCQUF5QixjQUFjLE1BQU0sUUFBUSxDQUFDLGFBQU8sYUFBYSxNQUFNLFFBQVEsQ0FBQyxXQUFXLElBQUksYUFBYSxlQUFlLEtBQUssUUFBUSxDQUFDLGVBQWU7QUFBQTtBQUcvSyxLQUFLOyIsCiAgImRlYnVnSWQiOiAiOTg0NkY0MTRFNUYwQTIzRDY0NzU2RTIxNjQ3NTZFMjEiLAogICJuYW1lcyI6IFtdCn0=
|
package/dist/scan-consumer.d.ts
CHANGED
|
@@ -31,5 +31,6 @@ interface Safelists {
|
|
|
31
31
|
attrSafelist: Set<string>;
|
|
32
32
|
}
|
|
33
33
|
declare function buildSafelists(allUsages: PropUsage[], manifest: PurgeManifest): Safelists;
|
|
34
|
-
|
|
34
|
+
declare function scanConsumerSource(srcDir: string): Promise<PropUsage[]>;
|
|
35
|
+
export { extractUIImports, extractJSXUsages, buildSafelists, scanConsumerSource };
|
|
35
36
|
export type { PropUsage, PurgeManifest, ComponentManifest, Safelists };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pathscale/rebuild-plugin-ui-css-purge",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -11,25 +11,21 @@
|
|
|
11
11
|
}
|
|
12
12
|
},
|
|
13
13
|
"bin": {
|
|
14
|
+
"rebuild-plugin-ui-css-purge": "dist/postbuild-purge.js",
|
|
14
15
|
"generate-manifest": "src/generate-manifest.ts"
|
|
15
16
|
},
|
|
16
17
|
"files": ["dist", "src/generate-manifest.ts"],
|
|
17
18
|
"dependencies": {
|
|
18
19
|
"@swc/core": "^1.15.24",
|
|
19
|
-
"fast-glob": "^3.3.3",
|
|
20
20
|
"postcss": "^8.5.9",
|
|
21
21
|
"purgecss": "^8.0.0"
|
|
22
22
|
},
|
|
23
|
-
"peerDependencies": {
|
|
24
|
-
"@rsbuild/core": "^1.7.5"
|
|
25
|
-
},
|
|
26
23
|
"scripts": {
|
|
27
24
|
"build": "bun run build.ts",
|
|
28
25
|
"lint": "biome check .",
|
|
29
26
|
"format": "biome format . --write"
|
|
30
27
|
},
|
|
31
28
|
"devDependencies": {
|
|
32
|
-
"@rsbuild/core": "^1.7.5",
|
|
33
29
|
"bun-types": "^1.3.12"
|
|
34
30
|
}
|
|
35
31
|
}
|
package/src/generate-manifest.ts
CHANGED
package/dist/rsbuild-plugin.d.ts
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* rsbuild-plugin-css-purge
|
|
3
|
-
*
|
|
4
|
-
* Two-level CSS purge for @pathscale/ui consumers.
|
|
5
|
-
*
|
|
6
|
-
* Level 1: class-level purge via purgecss — removes entire rules whose selectors
|
|
7
|
-
* don't match the safelist built from consumer JSX analysis.
|
|
8
|
-
* Level 2: attribute-level purge — within kept rules, strips compound selectors
|
|
9
|
-
* containing data-attr / aria-attr attribute selectors not in the attr safelist.
|
|
10
|
-
*
|
|
11
|
-
* Usage in rsbuild.config.ts:
|
|
12
|
-
* import { pluginCssPurge } from "@pathscale/rebuild-plugin-ui-css-purge";
|
|
13
|
-
* export default defineConfig({ plugins: [pluginCssPurge({ manifest: "..." })] });
|
|
14
|
-
*/
|
|
15
|
-
import type { RsbuildPlugin } from "@rsbuild/core";
|
|
16
|
-
export interface CssPurgeOptions {
|
|
17
|
-
/** Path to purge-manifest.json (generated by generate-manifest.ts) */
|
|
18
|
-
manifest: string;
|
|
19
|
-
/** Consumer source directory to scan for JSX usage (default: "src") */
|
|
20
|
-
srcDir?: string;
|
|
21
|
-
/** Enable Level 2 attribute purge (default: true) */
|
|
22
|
-
attrPurge?: boolean;
|
|
23
|
-
/** Enable CSS variable cleanup (default: true) */
|
|
24
|
-
cleanVars?: boolean;
|
|
25
|
-
/** Log purge stats (default: true) */
|
|
26
|
-
verbose?: boolean;
|
|
27
|
-
}
|
|
28
|
-
export declare const pluginCssPurge: (options: CssPurgeOptions) => RsbuildPlugin;
|