@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 CHANGED
@@ -1,2 +1,2 @@
1
- export { pluginCssPurge } from "./rsbuild-plugin";
2
- export type { CssPurgeOptions } from "./rsbuild-plugin";
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
- // src/rsbuild-plugin.ts
2
- import { PurgeCSS } from "purgecss";
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
- for (const cls of entry.classes.always)
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(`[${attr}="${val}"]`);
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 files = await fastGlob("**/*.{tsx,ts,jsx,js}", { cwd: srcDir, ignore: ["**/node_modules/**"] });
196
- for (const relPath of files) {
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 nodeReadFile(fullPath, "utf-8");
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
- function purgeAttributes(css, attrSafelist) {
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
- pluginCssPurge
215
+ scanConsumerSource,
216
+ extractUIImports,
217
+ extractJSXUsages,
218
+ buildSafelists
334
219
  };
335
220
 
336
- //# debugId=CB5B2093063663E864756E2164756E21
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=
@@ -31,5 +31,6 @@ interface Safelists {
31
31
  attrSafelist: Set<string>;
32
32
  }
33
33
  declare function buildSafelists(allUsages: PropUsage[], manifest: PurgeManifest): Safelists;
34
- export { extractUIImports, extractJSXUsages, buildSafelists };
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.1.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
  }
@@ -152,4 +152,6 @@ async function main() {
152
152
  console.log(`\nWrote ${outPath} (${Object.keys(manifest).length} entries, ${json.length} bytes)`);
153
153
  }
154
154
 
155
- main();
155
+ if (import.meta.main) {
156
+ main();
157
+ }
@@ -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;