@borrowdev/docval 0.1.3 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adapters/index.mjs.map +1 -1
- package/dist/adapters/javascript/utils.mjs +12 -2
- package/dist/adapters/javascript/utils.mjs.map +1 -1
- package/dist/adapters/rust/index.mjs +1 -1
- package/dist/adapters/rust/utils.mjs +18 -6
- package/dist/adapters/rust/utils.mjs.map +1 -1
- package/dist/remark/plugin.mjs +12 -6
- package/dist/remark/plugin.mjs.map +1 -1
- package/dist/utils.mjs +51 -6
- package/dist/utils.mjs.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":["adapterJavaScript","adapterTypeScript","adapterJSX","adapterTSX","adapterRust"],"sources":["../../src/adapters/index.ts"],"sourcesContent":["import adapterJavaScript from \"./javascript\";\nimport adapterJSX from \"./jsx\";\nimport adapterRust from \"./rust\";\nimport adapterTSX from \"./tsx\";\nimport adapterTypeScript from \"./typescript\";\n\nconst map
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["adapterJavaScript","adapterTypeScript","adapterJSX","adapterTSX","adapterRust"],"sources":["../../src/adapters/index.ts"],"sourcesContent":["import adapterJavaScript from \"./javascript\";\nimport adapterJSX from \"./jsx\";\nimport adapterRust from \"./rust\";\nimport adapterTSX from \"./tsx\";\nimport adapterTypeScript from \"./typescript\";\n\nconst map = {\n javascript: adapterJavaScript,\n js: adapterJavaScript,\n typescript: adapterTypeScript,\n ts: adapterTypeScript,\n jsx: adapterJSX,\n tsx: adapterTSX,\n rust: adapterRust,\n rs: adapterRust,\n} as const;\n\ntype Language = keyof typeof map;\n\nexport { Language };\nexport default map;\n"],"mappings":";;;;;;;AAMA,MAAM,MAAM;CACV,YAAYA;CACZ,IAAIA;CACJ,YAAYC;CACZ,IAAIA;CACJ,KAAKC;CACL,KAAKC;CACL,MAAMC;CACN,IAAIA;CACL"}
|
|
@@ -8,6 +8,16 @@ import { join } from "path";
|
|
|
8
8
|
import { isBuiltin } from "module";
|
|
9
9
|
|
|
10
10
|
//#region src/adapters/javascript/utils.ts
|
|
11
|
+
function getTree(code, type, filename) {
|
|
12
|
+
return parse(filename ?? "unknown", code, { lang: type });
|
|
13
|
+
}
|
|
14
|
+
async function getComments(code, type) {
|
|
15
|
+
return (await getTree(code, type)).comments.map((comment) => ({
|
|
16
|
+
value: comment.value,
|
|
17
|
+
start: comment.start,
|
|
18
|
+
end: comment.end
|
|
19
|
+
}));
|
|
20
|
+
}
|
|
11
21
|
function getPackage(importSpec) {
|
|
12
22
|
let packageSpec = importSpec;
|
|
13
23
|
if (packageSpec.startsWith("npm:")) packageSpec = packageSpec.slice(4);
|
|
@@ -15,7 +25,7 @@ function getPackage(importSpec) {
|
|
|
15
25
|
return packageSpec.split("/")[0];
|
|
16
26
|
}
|
|
17
27
|
async function getImports(code, filename, type) {
|
|
18
|
-
const ast = await
|
|
28
|
+
const ast = await getTree(code, type, filename);
|
|
19
29
|
return [...ast.module.dynamicImports.map((d) => {
|
|
20
30
|
const packageSpec = getPackage(code.slice(d.moduleRequest.start, d.moduleRequest.end).replaceAll(/['"]/g, ""));
|
|
21
31
|
return {
|
|
@@ -55,5 +65,5 @@ async function createEnvironment(code, imports, env, options = { installCommand:
|
|
|
55
65
|
}
|
|
56
66
|
|
|
57
67
|
//#endregion
|
|
58
|
-
export { createEnvironment, getEntryPath, getImports };
|
|
68
|
+
export { createEnvironment, getComments, getEntryPath, getImports };
|
|
59
69
|
//# sourceMappingURL=utils.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.mjs","names":["manifest"],"sources":["../../../src/adapters/javascript/utils.ts"],"sourcesContent":["import { parse } from \"oxc-parser\";\nimport { tmpdir } from \"os\";\nimport { mkdir, writeFile } from \"fs/promises\";\nimport manifest from \"~/assets/package.json\";\nimport { join } from \"path\";\nimport { randomUUID } from \"crypto\";\nimport { isBuiltin } from \"module\";\nimport { cleanupEnvironment, execUntilExit, logger } from \"@/utils\";\n\ntype Import = {\n isExternal: boolean;\n package: string;\n};\n\nfunction getPackage(importSpec: string): string {\n let packageSpec = importSpec;\n // Deno environment\n if (packageSpec.startsWith(\"npm:\")) {\n packageSpec = packageSpec.slice(4);\n }\n if (packageSpec.startsWith(\"@\")) {\n return packageSpec.split(\"/\").slice(0, 2).join(\"/\");\n }\n return packageSpec.split(\"/\")[0];\n}\n\nasync function getImports(code: string, filename: string, type: JavaScriptType): Promise<Import[]> {\n const ast = await
|
|
1
|
+
{"version":3,"file":"utils.mjs","names":["manifest"],"sources":["../../../src/adapters/javascript/utils.ts"],"sourcesContent":["import { parse } from \"oxc-parser\";\nimport { tmpdir } from \"os\";\nimport { mkdir, writeFile } from \"fs/promises\";\nimport manifest from \"~/assets/package.json\";\nimport { join } from \"path\";\nimport { randomUUID } from \"crypto\";\nimport { isBuiltin } from \"module\";\nimport { cleanupEnvironment, execUntilExit, logger } from \"@/utils\";\nimport type { Comment } from \"@/utils\";\n\ntype Import = {\n isExternal: boolean;\n package: string;\n};\n\nfunction getTree(code: string, type: JavaScriptType, filename?: string) {\n return parse(filename ?? \"unknown\", code, {\n lang: type,\n });\n}\n\nasync function getComments(code: string, type: JavaScriptType): Promise<Comment[]> {\n const ast = await getTree(code, type);\n return ast.comments.map((comment) => ({\n value: comment.value,\n start: comment.start,\n end: comment.end,\n }));\n}\n\nfunction getPackage(importSpec: string): string {\n let packageSpec = importSpec;\n // Deno environment\n if (packageSpec.startsWith(\"npm:\")) {\n packageSpec = packageSpec.slice(4);\n }\n if (packageSpec.startsWith(\"@\")) {\n return packageSpec.split(\"/\").slice(0, 2).join(\"/\");\n }\n return packageSpec.split(\"/\")[0];\n}\n\nasync function getImports(code: string, filename: string, type: JavaScriptType): Promise<Import[]> {\n const ast = await getTree(code, type, filename);\n return [\n ...ast.module.dynamicImports.map((d) => {\n const packageSpec = getPackage(\n code.slice(d.moduleRequest.start, d.moduleRequest.end).replaceAll(/['\"]/g, \"\"),\n );\n return { package: packageSpec, isExternal: !isBuiltin(packageSpec) };\n }),\n ...ast.module.staticImports.map((s) => ({\n package: getPackage(s.moduleRequest.value),\n isExternal: !isBuiltin(s.moduleRequest.value),\n })),\n ];\n}\n\ntype EnvironmentOptions = {\n environmentPath?: string;\n installCommand: string[];\n};\n\nfunction getEntryPath(environmentPath: string) {\n return `${environmentPath}/dist/index.js`;\n}\n\nasync function createEnvironment(\n code: string,\n imports: Import[],\n env: string | undefined,\n options: EnvironmentOptions = {\n installCommand: [\"npm\", \"install\"],\n },\n) {\n logger.info(\n \"Creating environment with imports\",\n imports.map((i) => i.package),\n );\n if (options.environmentPath) {\n logger.info(\"Using explicit environment at\", options.environmentPath);\n await mkdir(`${options.environmentPath}/dist`, { recursive: true });\n await writeFile(`${options.environmentPath}/dist/index.js`, code);\n return options.environmentPath;\n }\n\n const path = join(tmpdir(), \"docval\", randomUUID());\n await mkdir(`${path}/dist`, { recursive: true });\n await Promise.all([\n writeFile(`${path}/package.json`, JSON.stringify(manifest)),\n writeFile(`${path}/dist/index.js`, code),\n env ? writeFile(`${path}/.env`, env) : Promise.resolve(),\n ]);\n logger.info(\"Created environment at\", path);\n const cmd = options.installCommand\n .concat(imports.filter((i) => i.isExternal).map((i) => i.package))\n .join(\" \");\n if (imports.length > 0) {\n logger.info(\"Installing dependencies with command:\", cmd);\n await execUntilExit(cmd, path);\n }\n return path;\n}\n\ntype JavaScriptType = \"js\" | \"ts\" | \"tsx\" | \"jsx\";\n\nexport type { JavaScriptType };\nexport {\n getImports,\n createEnvironment,\n cleanupEnvironment,\n execUntilExit,\n getEntryPath,\n getComments,\n};\n"],"mappings":";;;;;;;;;;AAeA,SAAS,QAAQ,MAAc,MAAsB,UAAmB;AACtE,QAAO,MAAM,YAAY,WAAW,MAAM,EACxC,MAAM,MACP,CAAC;;AAGJ,eAAe,YAAY,MAAc,MAA0C;AAEjF,SADY,MAAM,QAAQ,MAAM,KAAK,EAC1B,SAAS,KAAK,aAAa;EACpC,OAAO,QAAQ;EACf,OAAO,QAAQ;EACf,KAAK,QAAQ;EACd,EAAE;;AAGL,SAAS,WAAW,YAA4B;CAC9C,IAAI,cAAc;AAElB,KAAI,YAAY,WAAW,OAAO,CAChC,eAAc,YAAY,MAAM,EAAE;AAEpC,KAAI,YAAY,WAAW,IAAI,CAC7B,QAAO,YAAY,MAAM,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC,KAAK,IAAI;AAErD,QAAO,YAAY,MAAM,IAAI,CAAC;;AAGhC,eAAe,WAAW,MAAc,UAAkB,MAAyC;CACjG,MAAM,MAAM,MAAM,QAAQ,MAAM,MAAM,SAAS;AAC/C,QAAO,CACL,GAAG,IAAI,OAAO,eAAe,KAAK,MAAM;EACtC,MAAM,cAAc,WAClB,KAAK,MAAM,EAAE,cAAc,OAAO,EAAE,cAAc,IAAI,CAAC,WAAW,SAAS,GAAG,CAC/E;AACD,SAAO;GAAE,SAAS;GAAa,YAAY,CAAC,UAAU,YAAY;GAAE;GACpE,EACF,GAAG,IAAI,OAAO,cAAc,KAAK,OAAO;EACtC,SAAS,WAAW,EAAE,cAAc,MAAM;EAC1C,YAAY,CAAC,UAAU,EAAE,cAAc,MAAM;EAC9C,EAAE,CACJ;;AAQH,SAAS,aAAa,iBAAyB;AAC7C,QAAO,GAAG,gBAAgB;;AAG5B,eAAe,kBACb,MACA,SACA,KACA,UAA8B,EAC5B,gBAAgB,CAAC,OAAO,UAAU,EACnC,EACD;AACA,QAAO,KACL,qCACA,QAAQ,KAAK,MAAM,EAAE,QAAQ,CAC9B;AACD,KAAI,QAAQ,iBAAiB;AAC3B,SAAO,KAAK,iCAAiC,QAAQ,gBAAgB;AACrE,QAAM,MAAM,GAAG,QAAQ,gBAAgB,QAAQ,EAAE,WAAW,MAAM,CAAC;AACnE,QAAM,UAAU,GAAG,QAAQ,gBAAgB,iBAAiB,KAAK;AACjE,SAAO,QAAQ;;CAGjB,MAAM,OAAO,KAAK,QAAQ,EAAE,UAAU,YAAY,CAAC;AACnD,OAAM,MAAM,GAAG,KAAK,QAAQ,EAAE,WAAW,MAAM,CAAC;AAChD,OAAM,QAAQ,IAAI;EAChB,UAAU,GAAG,KAAK,gBAAgB,KAAK,UAAUA,gBAAS,CAAC;EAC3D,UAAU,GAAG,KAAK,iBAAiB,KAAK;EACxC,MAAM,UAAU,GAAG,KAAK,QAAQ,IAAI,GAAG,QAAQ,SAAS;EACzD,CAAC;AACF,QAAO,KAAK,0BAA0B,KAAK;CAC3C,MAAM,MAAM,QAAQ,eACjB,OAAO,QAAQ,QAAQ,MAAM,EAAE,WAAW,CAAC,KAAK,MAAM,EAAE,QAAQ,CAAC,CACjE,KAAK,IAAI;AACZ,KAAI,QAAQ,SAAS,GAAG;AACtB,SAAO,KAAK,yCAAyC,IAAI;AACzD,QAAM,cAAc,KAAK,KAAK;;AAEhC,QAAO"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { getOptions } from "../../remark/utils.mjs";
|
|
2
|
-
import { cleanupEnvironment, execUntilExit } from "../../utils.mjs";
|
|
3
2
|
import { createEnvironment, getImports } from "./utils.mjs";
|
|
3
|
+
import { cleanupEnvironment, execUntilExit } from "../../utils.mjs";
|
|
4
4
|
import { ADAPTER_OPTIONS } from "./constants.mjs";
|
|
5
5
|
|
|
6
6
|
//#region src/adapters/rust/index.ts
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { execUntilExit,
|
|
1
|
+
import { execUntilExit, getDirectives, logger } from "../../utils.mjs";
|
|
2
2
|
import { randomUUID } from "crypto";
|
|
3
3
|
import { tmpdir } from "os";
|
|
4
4
|
import { mkdir, readFile, writeFile } from "fs/promises";
|
|
@@ -27,15 +27,27 @@ const ERROR_CRATES = new Set([
|
|
|
27
27
|
"super",
|
|
28
28
|
"self"
|
|
29
29
|
]);
|
|
30
|
-
async function
|
|
30
|
+
async function getTree(code) {
|
|
31
31
|
const language = await getRustLanguage();
|
|
32
32
|
const parser = new Parser();
|
|
33
33
|
parser.setLanguage(language);
|
|
34
|
-
|
|
34
|
+
return parser.parse(code);
|
|
35
|
+
}
|
|
36
|
+
async function getComments(input) {
|
|
37
|
+
const tree = typeof input === "string" ? await getTree(input) : input;
|
|
38
|
+
return tree ? tree.rootNode.descendantsOfType("line_comment").map((comment) => ({
|
|
39
|
+
value: comment.text,
|
|
40
|
+
start: comment.startIndex,
|
|
41
|
+
end: comment.endIndex
|
|
42
|
+
})) : [];
|
|
43
|
+
}
|
|
44
|
+
async function getImports(code) {
|
|
45
|
+
const tree = await getTree(code);
|
|
46
|
+
const directives = await getDirectives(code, "rust");
|
|
35
47
|
const imports = [];
|
|
36
|
-
const directives = parseDirectives(tree?.rootNode.descendantsOfType("line_comment").map((n) => n.text) ?? []);
|
|
37
48
|
for (const directive of directives["cargo-add-options"] ?? []) {
|
|
38
|
-
const [packageSpec, ...options] = directive;
|
|
49
|
+
const [packageSpec, ...options] = directive.args;
|
|
50
|
+
if (!packageSpec) continue;
|
|
39
51
|
imports.push({
|
|
40
52
|
package: packageSpec,
|
|
41
53
|
cargoAddOptions: options.join(" "),
|
|
@@ -85,5 +97,5 @@ async function createEnvironment(code, imports, options = {}) {
|
|
|
85
97
|
}
|
|
86
98
|
|
|
87
99
|
//#endregion
|
|
88
|
-
export { createEnvironment, getImports };
|
|
100
|
+
export { createEnvironment, getComments, getImports };
|
|
89
101
|
//# sourceMappingURL=utils.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.mjs","names":[],"sources":["../../../src/adapters/rust/utils.ts"],"sourcesContent":["import { Language, Parser } from \"web-tree-sitter\";\nimport { createRequire } from \"module\";\nimport { tmpdir } from \"os\";\nimport { mkdir, readFile, writeFile } from \"fs/promises\";\nimport { join } from \"path\";\nimport { randomUUID } from \"crypto\";\nimport { execUntilExit, logger,
|
|
1
|
+
{"version":3,"file":"utils.mjs","names":[],"sources":["../../../src/adapters/rust/utils.ts"],"sourcesContent":["import { Language, Parser, Tree } from \"web-tree-sitter\";\nimport { createRequire } from \"module\";\nimport { tmpdir } from \"os\";\nimport { mkdir, readFile, writeFile } from \"fs/promises\";\nimport { join } from \"path\";\nimport { randomUUID } from \"crypto\";\nimport { execUntilExit, logger, getDirectives } from \"@/utils\";\nimport type { Comment } from \"@/utils\";\n\nconst require = createRequire(import.meta.url);\nconst RUST_WASM_PATH = require.resolve(\"tree-sitter-rust/tree-sitter-rust.wasm\");\n\nlet rustLanguage: Language | undefined;\n\nasync function getRustLanguage(): Promise<Language> {\n if (!rustLanguage) {\n await Parser.init();\n rustLanguage = await Language.load(RUST_WASM_PATH);\n }\n return rustLanguage!;\n}\n\nconst BUILTIN_CRATES = new Set([\"std\", \"core\", \"alloc\", \"crate\"]);\nconst ERROR_CRATES = new Set([\"crate\", \"super\", \"self\"]);\n\ntype Import = {\n isExternal: boolean;\n package: string;\n cargoAddOptions?: string;\n};\n\nasync function getTree(code: string): Promise<Tree | null> {\n const language = await getRustLanguage();\n const parser = new Parser();\n parser.setLanguage(language);\n return parser.parse(code);\n}\n\nasync function getComments(input: string | Tree): Promise<Comment[]> {\n const tree = typeof input === \"string\" ? await getTree(input) : input;\n return tree\n ? tree.rootNode.descendantsOfType(\"line_comment\").map((comment) => ({\n value: comment.text,\n start: comment.startIndex,\n end: comment.endIndex,\n }))\n : [];\n}\n\nasync function getImports(code: string): Promise<Import[]> {\n const tree = await getTree(code);\n const directives = await getDirectives(code, \"rust\");\n const imports: Import[] = [];\n\n for (const directive of directives[\"cargo-add-options\"] ?? []) {\n const [packageSpec, ...options] = directive.args;\n if (!packageSpec) {\n continue;\n }\n\n imports.push({ package: packageSpec, cargoAddOptions: options.join(\" \"), isExternal: true });\n }\n\n for (const node of tree!.rootNode.children) {\n let crateName: string | undefined;\n\n if (node.type === \"use_declaration\") {\n const arg = node.child(1);\n if (!arg) continue;\n if (arg.type === \"identifier\" || arg.type === \"scoped_identifier\") {\n crateName = arg.text.split(\"::\")[0];\n }\n }\n\n if (crateName) {\n if (ERROR_CRATES.has(crateName)) {\n throw new Error(\n `Unsupported import of \"${crateName}\". ` +\n `Imports of ${Array.from(ERROR_CRATES)\n .map((c) => `\"${c}\"`)\n .join(\", \")} are not supported.`,\n );\n }\n if (imports.some((i) => i.package === crateName)) {\n continue;\n }\n\n imports.push({\n package: crateName,\n isExternal: !BUILTIN_CRATES.has(crateName),\n });\n }\n }\n return imports;\n}\n\ntype EnvironmentOptions = {\n environmentPath?: string;\n};\n\ntype Directive = \"cargo-add-options\";\n\nfunction getEntryPath(environmentPath: string) {\n return `${environmentPath}/src/main.rs`;\n}\n\nasync function createEnvironment(\n code: string,\n imports: Import[],\n options: EnvironmentOptions = {},\n) {\n logger.info(\n \"Creating Rust environment with crates\",\n imports.map((i) => i.package),\n );\n\n if (options.environmentPath) {\n logger.info(\"Using explicit environment at\", options.environmentPath);\n await mkdir(`${options.environmentPath}/src`, { recursive: true });\n await writeFile(getEntryPath(options.environmentPath), code);\n return options.environmentPath;\n }\n\n const manifest = await readFile(new URL(\"../../../assets/Cargo.toml\", import.meta.url), \"utf-8\");\n const path = join(tmpdir(), \"docval\", randomUUID());\n await mkdir(`${path}/src`, { recursive: true });\n await Promise.all([\n writeFile(`${path}/Cargo.toml`, manifest),\n writeFile(`${path}/src/main.rs`, code),\n ]);\n if (imports.length > 0) {\n const crates = imports.filter((i) => i.isExternal);\n logger.info(\"Installing crates\", crates);\n for (const crate of crates) {\n await execUntilExit(\n `cargo add ${crate.package}${crate.cargoAddOptions ? ` ${crate.cargoAddOptions}` : \"\"}`,\n path,\n );\n }\n }\n\n logger.info(\"Created Rust environment at\", path);\n return path;\n}\n\nexport { getImports, createEnvironment, getEntryPath, getComments };\nexport type { Import, Directive };\n"],"mappings":"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"}
|
package/dist/remark/plugin.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { logger } from "../utils.mjs";
|
|
1
|
+
import { filterHiddenCode, logger } from "../utils.mjs";
|
|
2
2
|
import map from "../adapters/index.mjs";
|
|
3
3
|
import { CONTENT_CACHE_DIR } from "../constants.mjs";
|
|
4
4
|
import { hash } from "crypto";
|
|
@@ -18,11 +18,14 @@ function remarkDocval(options = defaultOptions) {
|
|
|
18
18
|
};
|
|
19
19
|
return async function(tree) {
|
|
20
20
|
const promises = [];
|
|
21
|
-
|
|
21
|
+
const newTree = structuredClone(tree);
|
|
22
|
+
newTree.children = await Promise.all(tree.children.map(async (node) => {
|
|
22
23
|
if (node.type === "code" && node.lang && node.lang in map) {
|
|
24
|
+
let newNode = node;
|
|
25
|
+
const lang = node.lang;
|
|
23
26
|
const contentHash = hash("sha1", JSON.stringify([
|
|
24
27
|
node.value,
|
|
25
|
-
|
|
28
|
+
lang,
|
|
26
29
|
node.meta
|
|
27
30
|
]));
|
|
28
31
|
if (cache) {
|
|
@@ -37,7 +40,7 @@ function remarkDocval(options = defaultOptions) {
|
|
|
37
40
|
message: "One or more code blocks failed validation.",
|
|
38
41
|
originalResults
|
|
39
42
|
});
|
|
40
|
-
else return;
|
|
43
|
+
else return node;
|
|
41
44
|
}
|
|
42
45
|
}
|
|
43
46
|
const metadata = node.meta?.split(" ") ?? [];
|
|
@@ -46,7 +49,7 @@ function remarkDocval(options = defaultOptions) {
|
|
|
46
49
|
if (include && noDocValIndex === -1 || docValIndex !== -1) promises.push((async () => {
|
|
47
50
|
try {
|
|
48
51
|
return {
|
|
49
|
-
result: await map[
|
|
52
|
+
result: await map[lang](node.value, metadata),
|
|
50
53
|
contentHash
|
|
51
54
|
};
|
|
52
55
|
} catch (err) {
|
|
@@ -56,7 +59,10 @@ function remarkDocval(options = defaultOptions) {
|
|
|
56
59
|
};
|
|
57
60
|
}
|
|
58
61
|
})());
|
|
62
|
+
newNode.value = await filterHiddenCode(node.value, lang);
|
|
63
|
+
return newNode;
|
|
59
64
|
} else if (node.type === "code" && process.env.DOCVAL_TEST_NO_SKIP === "true") throw new Error(`Skipped code block: ${JSON.stringify(node)}`);
|
|
65
|
+
return node;
|
|
60
66
|
}));
|
|
61
67
|
const res = await Promise.allSettled(promises);
|
|
62
68
|
if (cache) await Promise.all(res.map(async (r) => {
|
|
@@ -68,7 +74,7 @@ function remarkDocval(options = defaultOptions) {
|
|
|
68
74
|
message: "One or more code blocks failed validation.",
|
|
69
75
|
originalResults: res
|
|
70
76
|
});
|
|
71
|
-
return
|
|
77
|
+
return newTree;
|
|
72
78
|
};
|
|
73
79
|
}
|
|
74
80
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.mjs","names":["adapters"],"sources":["../../src/remark/plugin.ts"],"sourcesContent":["import adapters from \"@/adapters\";\nimport { CONTENT_CACHE_DIR } from \"@/constants\";\nimport { logger } from \"@/utils\";\nimport { hash } from \"crypto\";\nimport { existsSync, mkdirSync } from \"fs\";\nimport { readFile, writeFile } from \"fs/promises\";\nimport type { Root } from \"mdast\";\n\nexport type DocValOptions = {\n cache: boolean;\n include: boolean;\n};\n\nmkdirSync(CONTENT_CACHE_DIR, { recursive: true });\n\nconst defaultOptions: DocValOptions = {\n cache: process.env.CI !== \"true\" && process.env.NODE_ENV !== \"test\",\n include: false,\n};\n\nexport default function remarkDocval(options: Partial<DocValOptions> = defaultOptions) {\n const { cache, include } = { ...defaultOptions, ...options };\n\n return async function (tree: Root) {\n const promises: Promise<{\n result: any;\n contentHash: string;\n }>[] = [];\n await Promise.all(\n tree.children.map(async (node) => {\n if (node.type === \"code\" && node.lang && node.lang in adapters) {\n const contentHash = hash(\"sha1\", JSON.stringify([node.value,
|
|
1
|
+
{"version":3,"file":"plugin.mjs","names":["adapters"],"sources":["../../src/remark/plugin.ts"],"sourcesContent":["import adapters, { Language } from \"@/adapters\";\nimport { CONTENT_CACHE_DIR } from \"@/constants\";\nimport { filterHiddenCode, logger } from \"@/utils\";\nimport { hash } from \"crypto\";\nimport { existsSync, mkdirSync } from \"fs\";\nimport { readFile, writeFile } from \"fs/promises\";\nimport type { Root } from \"mdast\";\n\nexport type DocValOptions = {\n cache: boolean;\n include: boolean;\n};\n\nmkdirSync(CONTENT_CACHE_DIR, { recursive: true });\n\nconst defaultOptions: DocValOptions = {\n cache: process.env.CI !== \"true\" && process.env.NODE_ENV !== \"test\",\n include: false,\n};\n\nexport default function remarkDocval(options: Partial<DocValOptions> = defaultOptions) {\n const { cache, include } = { ...defaultOptions, ...options };\n\n return async function (tree: Root) {\n const promises: Promise<{\n result: any;\n contentHash: string;\n }>[] = [];\n const newTree = structuredClone(tree);\n\n newTree.children = await Promise.all(\n tree.children.map(async (node) => {\n if (node.type === \"code\" && node.lang && node.lang in adapters) {\n let newNode = node;\n const lang: Language = node.lang as Language;\n const contentHash = hash(\"sha1\", JSON.stringify([node.value, lang, node.meta]));\n if (cache) {\n const [success, originalResults]: [boolean | null, any] = await readFile(\n `${CONTENT_CACHE_DIR}/${contentHash}.txt`,\n { encoding: \"utf-8\" },\n )\n .then((content) => {\n const [success, results] = content.split(\"\\n\");\n\n if (![\"true\", \"false\"].includes(success)) {\n return [null, null] as [boolean | null, any];\n }\n return [success === \"true\", JSON.parse(results ?? \"null\")] as [boolean, any];\n })\n .catch(() => [null, null]);\n\n if (typeof success === \"boolean\") {\n logger.debug(\"Result found in cache, skipping validation\");\n\n if (!success) {\n throw JSON.stringify({\n message: \"One or more code blocks failed validation.\",\n originalResults: originalResults,\n });\n } else {\n return node;\n }\n }\n }\n\n const metadata = node.meta?.split(\" \") ?? [];\n const docValIndex = metadata.findIndex((item) => item === \"docval\");\n const noDocValIndex = metadata.findIndex((item) => item === \"no-docval\");\n if ((include && noDocValIndex === -1) || docValIndex !== -1) {\n promises.push(\n (async () => {\n try {\n const result = await adapters[lang as keyof typeof adapters](\n node.value,\n metadata,\n );\n return {\n result,\n contentHash,\n };\n } catch (err) {\n throw {\n result: err,\n contentHash,\n };\n }\n })(),\n );\n }\n\n newNode.value = await filterHiddenCode(node.value, lang);\n return newNode;\n } else if (node.type === \"code\" && process.env.DOCVAL_TEST_NO_SKIP === \"true\") {\n throw new Error(`Skipped code block: ${JSON.stringify(node)}`);\n }\n\n return node;\n }),\n );\n const res = await Promise.allSettled(promises);\n\n if (cache) {\n await Promise.all(\n res.map(async (r) => {\n const path = (hash: string) => `${CONTENT_CACHE_DIR}/${hash}.txt`;\n if (r.status === \"rejected\" && !existsSync(path(r.reason.contentHash))) {\n await writeFile(\n `${CONTENT_CACHE_DIR}/${r.reason.contentHash}.txt`,\n `false\\n${JSON.stringify(r.reason)}`,\n );\n } else if (r.status === \"fulfilled\" && !existsSync(path(r.value.contentHash))) {\n await writeFile(`${CONTENT_CACHE_DIR}/${r.value.contentHash}.txt`, \"true\");\n }\n }),\n );\n }\n\n if (res.some((r) => r.status === \"rejected\")) {\n throw JSON.stringify({\n message: \"One or more code blocks failed validation.\",\n originalResults: res,\n });\n }\n\n return newTree;\n };\n}\n"],"mappings":";;;;;;;;AAaA,UAAU,mBAAmB,EAAE,WAAW,MAAM,CAAC;AAEjD,MAAM,iBAAgC;CACpC,OAAO,QAAQ,IAAI,OAAO,UAAU,QAAQ,IAAI,aAAa;CAC7D,SAAS;CACV;AAED,SAAwB,aAAa,UAAkC,gBAAgB;CACrF,MAAM,EAAE,OAAO,YAAY;EAAE,GAAG;EAAgB,GAAG;EAAS;AAE5D,QAAO,eAAgB,MAAY;EACjC,MAAM,WAGC,EAAE;EACT,MAAM,UAAU,gBAAgB,KAAK;AAErC,UAAQ,WAAW,MAAM,QAAQ,IAC/B,KAAK,SAAS,IAAI,OAAO,SAAS;AAChC,OAAI,KAAK,SAAS,UAAU,KAAK,QAAQ,KAAK,QAAQA,KAAU;IAC9D,IAAI,UAAU;IACd,MAAM,OAAiB,KAAK;IAC5B,MAAM,cAAc,KAAK,QAAQ,KAAK,UAAU;KAAC,KAAK;KAAO;KAAM,KAAK;KAAK,CAAC,CAAC;AAC/E,QAAI,OAAO;KACT,MAAM,CAAC,SAAS,mBAA0C,MAAM,SAC9D,GAAG,kBAAkB,GAAG,YAAY,OACpC,EAAE,UAAU,SAAS,CACtB,CACE,MAAM,YAAY;MACjB,MAAM,CAAC,SAAS,WAAW,QAAQ,MAAM,KAAK;AAE9C,UAAI,CAAC,CAAC,QAAQ,QAAQ,CAAC,SAAS,QAAQ,CACtC,QAAO,CAAC,MAAM,KAAK;AAErB,aAAO,CAAC,YAAY,QAAQ,KAAK,MAAM,WAAW,OAAO,CAAC;OAC1D,CACD,YAAY,CAAC,MAAM,KAAK,CAAC;AAE5B,SAAI,OAAO,YAAY,WAAW;AAChC,aAAO,MAAM,6CAA6C;AAE1D,UAAI,CAAC,QACH,OAAM,KAAK,UAAU;OACnB,SAAS;OACQ;OAClB,CAAC;UAEF,QAAO;;;IAKb,MAAM,WAAW,KAAK,MAAM,MAAM,IAAI,IAAI,EAAE;IAC5C,MAAM,cAAc,SAAS,WAAW,SAAS,SAAS,SAAS;IACnE,MAAM,gBAAgB,SAAS,WAAW,SAAS,SAAS,YAAY;AACxE,QAAK,WAAW,kBAAkB,MAAO,gBAAgB,GACvD,UAAS,MACN,YAAY;AACX,SAAI;AAKF,aAAO;OACL,QALa,MAAMA,IAAS,MAC5B,KAAK,OACL,SACD;OAGC;OACD;cACM,KAAK;AACZ,YAAM;OACJ,QAAQ;OACR;OACD;;QAED,CACL;AAGH,YAAQ,QAAQ,MAAM,iBAAiB,KAAK,OAAO,KAAK;AACxD,WAAO;cACE,KAAK,SAAS,UAAU,QAAQ,IAAI,wBAAwB,OACrE,OAAM,IAAI,MAAM,uBAAuB,KAAK,UAAU,KAAK,GAAG;AAGhE,UAAO;IACP,CACH;EACD,MAAM,MAAM,MAAM,QAAQ,WAAW,SAAS;AAE9C,MAAI,MACF,OAAM,QAAQ,IACZ,IAAI,IAAI,OAAO,MAAM;GACnB,MAAM,QAAQ,SAAiB,GAAG,kBAAkB,GAAG,KAAK;AAC5D,OAAI,EAAE,WAAW,cAAc,CAAC,WAAW,KAAK,EAAE,OAAO,YAAY,CAAC,CACpE,OAAM,UACJ,GAAG,kBAAkB,GAAG,EAAE,OAAO,YAAY,OAC7C,UAAU,KAAK,UAAU,EAAE,OAAO,GACnC;YACQ,EAAE,WAAW,eAAe,CAAC,WAAW,KAAK,EAAE,MAAM,YAAY,CAAC,CAC3E,OAAM,UAAU,GAAG,kBAAkB,GAAG,EAAE,MAAM,YAAY,OAAO,OAAO;IAE5E,CACH;AAGH,MAAI,IAAI,MAAM,MAAM,EAAE,WAAW,WAAW,CAC1C,OAAM,KAAK,UAAU;GACnB,SAAS;GACT,iBAAiB;GAClB,CAAC;AAGJ,SAAO"}
|
package/dist/utils.mjs
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { getComments } from "./adapters/rust/utils.mjs";
|
|
2
|
+
import { getComments as getComments$1 } from "./adapters/javascript/utils.mjs";
|
|
1
3
|
import { spawn } from "child_process";
|
|
2
4
|
import consola from "consola";
|
|
3
5
|
|
|
@@ -25,23 +27,66 @@ function execUntilExit(command, cwd) {
|
|
|
25
27
|
async function cleanupEnvironment(path) {
|
|
26
28
|
await execUntilExit(`rm -rf ${path}`, process.cwd());
|
|
27
29
|
}
|
|
28
|
-
function
|
|
30
|
+
function isDirective(comment) {
|
|
31
|
+
return /@docval-.+/.test(comment.trim());
|
|
32
|
+
}
|
|
33
|
+
function isCodeDirective(directive) {
|
|
34
|
+
return directive === "hidden";
|
|
35
|
+
}
|
|
36
|
+
function getAssociatedCode(code, comment) {
|
|
37
|
+
const commentLineStart = code.lastIndexOf("\n", comment.start - 1);
|
|
38
|
+
const start = commentLineStart === -1 ? 0 : commentLineStart + 1;
|
|
39
|
+
const currentLineEnd = code.indexOf("\n", comment.end);
|
|
40
|
+
if (currentLineEnd === -1) return code.slice(start);
|
|
41
|
+
const nextLineStart = currentLineEnd + 1;
|
|
42
|
+
const nextLineEnd = code.indexOf("\n", nextLineStart);
|
|
43
|
+
return code.slice(start, nextLineEnd === -1 ? code.length : nextLineEnd + 1);
|
|
44
|
+
}
|
|
45
|
+
async function getDirectives(code, language) {
|
|
46
|
+
let comments = [];
|
|
47
|
+
switch (language) {
|
|
48
|
+
case "javascript":
|
|
49
|
+
case "js":
|
|
50
|
+
case "jsx":
|
|
51
|
+
case "typescript":
|
|
52
|
+
case "ts":
|
|
53
|
+
case "tsx":
|
|
54
|
+
comments = await getComments$1(code, ["javascript", "js"].includes(language) ? "js" : language === "jsx" ? "jsx" : ["typescript", "ts"].includes(language) ? "ts" : "tsx");
|
|
55
|
+
break;
|
|
56
|
+
case "rust":
|
|
57
|
+
case "rs":
|
|
58
|
+
comments = await getComments(code);
|
|
59
|
+
break;
|
|
60
|
+
}
|
|
29
61
|
const directives = {};
|
|
30
62
|
const prefix = "@docval-";
|
|
31
|
-
for (const
|
|
32
|
-
|
|
63
|
+
for (const comment of comments) {
|
|
64
|
+
if (!isDirective(comment.value)) continue;
|
|
65
|
+
const trimmed = comment.value.trim();
|
|
33
66
|
const prefixIndex = trimmed.indexOf(prefix);
|
|
34
67
|
if (prefixIndex === -1) continue;
|
|
35
68
|
const content = trimmed.slice(prefixIndex + 8);
|
|
36
69
|
const spaceIdx = content.indexOf(" ");
|
|
37
70
|
const directive = spaceIdx === -1 ? content : content.slice(0, spaceIdx);
|
|
38
71
|
const args = spaceIdx === -1 ? [] : content.slice(spaceIdx + 1).split(" ").filter(Boolean);
|
|
39
|
-
|
|
40
|
-
directives[
|
|
72
|
+
const key = directive;
|
|
73
|
+
directives[key] ??= [];
|
|
74
|
+
directives[key].push({
|
|
75
|
+
args,
|
|
76
|
+
code: isCodeDirective(directive) ? getAssociatedCode(code, comment) : void 0
|
|
77
|
+
});
|
|
41
78
|
}
|
|
42
79
|
return directives;
|
|
43
80
|
}
|
|
81
|
+
async function filterHiddenCode(code, language) {
|
|
82
|
+
const directives = await getDirectives(code, language);
|
|
83
|
+
let filteredCode = code;
|
|
84
|
+
if (directives.hidden) {
|
|
85
|
+
for (const directive of directives.hidden) if (directive.code) filteredCode = filteredCode.replace(directive.code, "");
|
|
86
|
+
}
|
|
87
|
+
return filteredCode;
|
|
88
|
+
}
|
|
44
89
|
|
|
45
90
|
//#endregion
|
|
46
|
-
export { cleanupEnvironment, execUntilExit,
|
|
91
|
+
export { cleanupEnvironment, execUntilExit, filterHiddenCode, getDirectives, logger };
|
|
47
92
|
//# sourceMappingURL=utils.mjs.map
|
package/dist/utils.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.mjs","names":[],"sources":["../src/utils.ts"],"sourcesContent":["import { spawn } from \"child_process\";\nimport consola from \"consola\";\n\nconst logger = consola.withTag(\"Borrow\").withTag(\"DocVal\");\n\nfunction execUntilExit(command: string, cwd: string): Promise<void> {\n let error = \"\";\n return new Promise((resolve, reject) => {\n const process = spawn(command, { cwd, shell: true });\n\n process.stdout.on(\"data\", (data) => {\n logger.debug(data.toString());\n });\n\n process.stderr.on(\"data\", (data) => {\n error += data;\n });\n\n process.on(\"close\", (code) => {\n if (code === 0) {\n resolve();\n } else {\n reject(`Command failed with exit code ${code}\\n${error})`);\n }\n });\n });\n}\n\nasync function cleanupEnvironment(path: string) {\n await execUntilExit(`rm -rf ${path}`, process.cwd());\n}\n\ntype
|
|
1
|
+
{"version":3,"file":"utils.mjs","names":["getCommentsJavaScript","getCommentsRust"],"sources":["../src/utils.ts"],"sourcesContent":["import { spawn } from \"child_process\";\nimport consola from \"consola\";\nimport { Language } from \"./adapters\";\nimport { Directive as DirectiveRust } from \"./adapters/rust/utils\";\nimport { getComments as getCommentsJavaScript } from \"./adapters/javascript/utils\";\nimport { getComments as getCommentsRust } from \"./adapters/rust/utils\";\n\nconst logger = consola.withTag(\"Borrow\").withTag(\"DocVal\");\n\nfunction execUntilExit(command: string, cwd: string): Promise<void> {\n let error = \"\";\n return new Promise((resolve, reject) => {\n const process = spawn(command, { cwd, shell: true });\n\n process.stdout.on(\"data\", (data) => {\n logger.debug(data.toString());\n });\n\n process.stderr.on(\"data\", (data) => {\n error += data;\n });\n\n process.on(\"close\", (code) => {\n if (code === 0) {\n resolve();\n } else {\n reject(`Command failed with exit code ${code}\\n${error})`);\n }\n });\n });\n}\n\nasync function cleanupEnvironment(path: string) {\n await execUntilExit(`rm -rf ${path}`, process.cwd());\n}\n\ntype Directive = \"hidden\";\n\ntype Comment = {\n value: string;\n start: number;\n end: number;\n};\n\ntype DirectiveValue = {\n args: string[];\n /**\n * Code associated with the directive\n */\n code?: string;\n};\n\ntype DirectiveKey = Directive | DirectiveRust;\ntype DirectiveMap = Partial<Record<DirectiveKey, DirectiveValue[]>>;\n\nfunction isDirective(comment: string): boolean {\n return /@docval-.+/.test(comment.trim());\n}\n\nfunction isCodeDirective(directive: string): boolean {\n return directive === \"hidden\";\n}\n\nfunction getAssociatedCode(code: string, comment: Comment): string | undefined {\n const commentLineStart = code.lastIndexOf(\"\\n\", comment.start - 1);\n const start = commentLineStart === -1 ? 0 : commentLineStart + 1;\n const currentLineEnd = code.indexOf(\"\\n\", comment.end);\n if (currentLineEnd === -1) {\n return code.slice(start);\n }\n\n const nextLineStart = currentLineEnd + 1;\n const nextLineEnd = code.indexOf(\"\\n\", nextLineStart);\n\n return code.slice(start, nextLineEnd === -1 ? code.length : nextLineEnd + 1);\n}\n\nasync function getDirectives(code: string, language: Language): Promise<DirectiveMap> {\n let comments: Comment[] = [];\n switch (language) {\n case \"javascript\":\n case \"js\":\n case \"jsx\":\n case \"typescript\":\n case \"ts\":\n case \"tsx\":\n const jsType = [\"javascript\", \"js\"].includes(language)\n ? \"js\"\n : language === \"jsx\"\n ? \"jsx\"\n : [\"typescript\", \"ts\"].includes(language)\n ? \"ts\"\n : \"tsx\";\n comments = await getCommentsJavaScript(code, jsType);\n break;\n case \"rust\":\n case \"rs\":\n comments = await getCommentsRust(code);\n break;\n }\n\n const directives: DirectiveMap = {};\n const prefix = \"@docval-\";\n for (const comment of comments) {\n if (!isDirective(comment.value)) continue;\n const trimmed = comment.value.trim();\n const prefixIndex = trimmed.indexOf(prefix);\n if (prefixIndex === -1) continue;\n const content = trimmed.slice(prefixIndex + prefix.length);\n const spaceIdx = content.indexOf(\" \");\n const directive = spaceIdx === -1 ? content : content.slice(0, spaceIdx);\n const args =\n spaceIdx === -1\n ? []\n : content\n .slice(spaceIdx + 1)\n .split(\" \")\n .filter(Boolean);\n const key = directive as DirectiveKey;\n directives[key] ??= [];\n directives[key].push({\n args,\n code: isCodeDirective(directive) ? getAssociatedCode(code, comment) : undefined,\n });\n }\n\n return directives;\n}\n\nasync function filterHiddenCode(code: string, language: Language): Promise<string> {\n const directives = await getDirectives(code, language);\n let filteredCode = code;\n if (directives.hidden) {\n for (const directive of directives.hidden) {\n if (directive.code) {\n filteredCode = filteredCode.replace(directive.code, \"\");\n }\n }\n }\n\n return filteredCode;\n}\n\nexport { execUntilExit, cleanupEnvironment, logger, getDirectives, filterHiddenCode };\nexport type { Comment };\n"],"mappings":";;;;;;AAOA,MAAM,SAAS,QAAQ,QAAQ,SAAS,CAAC,QAAQ,SAAS;AAE1D,SAAS,cAAc,SAAiB,KAA4B;CAClE,IAAI,QAAQ;AACZ,QAAO,IAAI,SAAS,SAAS,WAAW;EACtC,MAAM,UAAU,MAAM,SAAS;GAAE;GAAK,OAAO;GAAM,CAAC;AAEpD,UAAQ,OAAO,GAAG,SAAS,SAAS;AAClC,UAAO,MAAM,KAAK,UAAU,CAAC;IAC7B;AAEF,UAAQ,OAAO,GAAG,SAAS,SAAS;AAClC,YAAS;IACT;AAEF,UAAQ,GAAG,UAAU,SAAS;AAC5B,OAAI,SAAS,EACX,UAAS;OAET,QAAO,iCAAiC,KAAK,IAAI,MAAM,GAAG;IAE5D;GACF;;AAGJ,eAAe,mBAAmB,MAAc;AAC9C,OAAM,cAAc,UAAU,QAAQ,QAAQ,KAAK,CAAC;;AAsBtD,SAAS,YAAY,SAA0B;AAC7C,QAAO,aAAa,KAAK,QAAQ,MAAM,CAAC;;AAG1C,SAAS,gBAAgB,WAA4B;AACnD,QAAO,cAAc;;AAGvB,SAAS,kBAAkB,MAAc,SAAsC;CAC7E,MAAM,mBAAmB,KAAK,YAAY,MAAM,QAAQ,QAAQ,EAAE;CAClE,MAAM,QAAQ,qBAAqB,KAAK,IAAI,mBAAmB;CAC/D,MAAM,iBAAiB,KAAK,QAAQ,MAAM,QAAQ,IAAI;AACtD,KAAI,mBAAmB,GACrB,QAAO,KAAK,MAAM,MAAM;CAG1B,MAAM,gBAAgB,iBAAiB;CACvC,MAAM,cAAc,KAAK,QAAQ,MAAM,cAAc;AAErD,QAAO,KAAK,MAAM,OAAO,gBAAgB,KAAK,KAAK,SAAS,cAAc,EAAE;;AAG9E,eAAe,cAAc,MAAc,UAA2C;CACpF,IAAI,WAAsB,EAAE;AAC5B,SAAQ,UAAR;EACE,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;AAQH,cAAW,MAAMA,cAAsB,MAPxB,CAAC,cAAc,KAAK,CAAC,SAAS,SAAS,GAClD,OACA,aAAa,QACX,QACA,CAAC,cAAc,KAAK,CAAC,SAAS,SAAS,GACrC,OACA,MAC4C;AACpD;EACF,KAAK;EACL,KAAK;AACH,cAAW,MAAMC,YAAgB,KAAK;AACtC;;CAGJ,MAAM,aAA2B,EAAE;CACnC,MAAM,SAAS;AACf,MAAK,MAAM,WAAW,UAAU;AAC9B,MAAI,CAAC,YAAY,QAAQ,MAAM,CAAE;EACjC,MAAM,UAAU,QAAQ,MAAM,MAAM;EACpC,MAAM,cAAc,QAAQ,QAAQ,OAAO;AAC3C,MAAI,gBAAgB,GAAI;EACxB,MAAM,UAAU,QAAQ,MAAM,cAAc,EAAc;EAC1D,MAAM,WAAW,QAAQ,QAAQ,IAAI;EACrC,MAAM,YAAY,aAAa,KAAK,UAAU,QAAQ,MAAM,GAAG,SAAS;EACxE,MAAM,OACJ,aAAa,KACT,EAAE,GACF,QACG,MAAM,WAAW,EAAE,CACnB,MAAM,IAAI,CACV,OAAO,QAAQ;EACxB,MAAM,MAAM;AACZ,aAAW,SAAS,EAAE;AACtB,aAAW,KAAK,KAAK;GACnB;GACA,MAAM,gBAAgB,UAAU,GAAG,kBAAkB,MAAM,QAAQ,GAAG;GACvE,CAAC;;AAGJ,QAAO;;AAGT,eAAe,iBAAiB,MAAc,UAAqC;CACjF,MAAM,aAAa,MAAM,cAAc,MAAM,SAAS;CACtD,IAAI,eAAe;AACnB,KAAI,WAAW,QACb;OAAK,MAAM,aAAa,WAAW,OACjC,KAAI,UAAU,KACZ,gBAAe,aAAa,QAAQ,UAAU,MAAM,GAAG;;AAK7D,QAAO"}
|