@monorepolint/utils 0.6.0-alpha.0 → 0.6.0-alpha.2
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/.turbo/turbo-clean.log +1 -1
- package/.turbo/turbo-compile-typescript.log +1 -1
- package/.turbo/turbo-lint.log +1 -1
- package/.turbo/turbo-test.log +32 -23
- package/.turbo/turbo-transpile-typescript.log +5 -5
- package/CHANGELOG.md +28 -0
- package/build/js/index.js +10 -19
- package/build/js/index.js.map +1 -1
- package/build/tsconfig.tsbuildinfo +1 -1
- package/build/types/CachingHost.d.ts +0 -2
- package/build/types/CachingHost.d.ts.map +1 -1
- package/build/types/Host.d.ts +0 -1
- package/build/types/Host.d.ts.map +1 -1
- package/build/types/SimpleHost.d.ts +0 -2
- package/build/types/SimpleHost.d.ts.map +1 -1
- package/coverage/AggregateTiming.ts.html +295 -0
- package/coverage/CachingHost.ts.html +1570 -0
- package/coverage/Host.ts.html +187 -0
- package/coverage/PackageJson.ts.html +151 -0
- package/coverage/SimpleHost.ts.html +253 -0
- package/coverage/Table.ts.html +1039 -0
- package/coverage/Timing.ts.html +247 -0
- package/coverage/base.css +224 -0
- package/coverage/block-navigation.js +87 -0
- package/coverage/clover.xml +1128 -0
- package/coverage/coverage-final.json +15 -0
- package/coverage/favicon.png +0 -0
- package/coverage/findWorkspaceDir.ts.html +223 -0
- package/coverage/getPackageNameToDir.ts.html +187 -0
- package/coverage/getWorkspacePackageDirs.ts.html +295 -0
- package/coverage/index.html +311 -0
- package/coverage/index.ts.html +145 -0
- package/coverage/matchesAnyGlob.ts.html +523 -0
- package/coverage/mutateJson.ts.html +124 -0
- package/coverage/nanosecondsToSanity.ts.html +115 -0
- package/coverage/prettify.css +1 -0
- package/coverage/prettify.js +2 -0
- package/coverage/sort-arrow-sprite.png +0 -0
- package/coverage/sorter.js +196 -0
- package/package.json +13 -17
- package/src/CachingHost.ts +4 -0
- package/src/__tests__/CachingHost.spec.ts +1 -1
- package/src/getWorkspacePackageDirs.ts +1 -1
- package/vitest.config.mjs +14 -0
- package/vitest.config.mjs.timestamp-1736878329730-aa478e2241542.mjs +18 -0
- package/jest.config.cjs +0 -4
package/.turbo/turbo-clean.log
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
|
|
2
|
-
> @monorepolint/utils@0.6.0-alpha.
|
|
2
|
+
> @monorepolint/utils@0.6.0-alpha.2 clean /home/runner/work/monorepolint/monorepolint/packages/utils
|
|
3
3
|
> rm -rf build dist lib node_modules *.tgz tsconfig.tsbuildinfo
|
|
4
4
|
|
package/.turbo/turbo-lint.log
CHANGED
package/.turbo/turbo-test.log
CHANGED
|
@@ -1,26 +1,35 @@
|
|
|
1
1
|
|
|
2
|
-
> @monorepolint/utils@0.6.0-alpha.
|
|
3
|
-
>
|
|
2
|
+
> @monorepolint/utils@0.6.0-alpha.2 test /home/runner/work/monorepolint/monorepolint/packages/utils
|
|
3
|
+
> vitest run --passWithNoTests
|
|
4
4
|
|
|
5
|
-
(node:2461) ExperimentalWarning: VM Modules is an experimental feature and might change at any time
|
|
6
|
-
(Use `node --trace-warnings ...` to show where the warning was created)
|
|
7
|
-
[0m[7m[1m[32m PASS [39m[22m[27m[0m [2msrc/__tests__/[22m[1mCachingHost.spec.ts[22m
|
|
8
|
-
CachingHost
|
|
9
|
-
fs
|
|
10
|
-
[32m✓[39m [2mAnswers exists() properly (28 ms)[22m
|
|
11
|
-
[32m✓[39m [2mproperly handles deletes (2 ms)[22m
|
|
12
|
-
[32m✓[39m [2mhandles simple read/write workflow (2 ms)[22m
|
|
13
|
-
[32m✓[39m [2mhandles target symlink changing (1 ms)[22m
|
|
14
|
-
[32m✓[39m [2mhandles writing symlinks properly (3 ms)[22m
|
|
15
|
-
[32m✓[39m [2mhandles writing symlinks properly if you read it first (3 ms)[22m
|
|
16
|
-
[32m✓[39m [2mhandles creating new symlinks (2 ms)[22m
|
|
17
|
-
[32m✓[39m [2mmakes directories (2 ms)[22m
|
|
18
|
-
[32m✓[39m [2mcan unlink empty dirs (1 ms)[22m
|
|
19
|
-
[32m✓[39m [2mdoesnt let you delete a directory with files (36 ms)[22m
|
|
20
|
-
[32m✓[39m [2mdoesn't let you rmdir() a file (2 ms)[22m
|
|
21
5
|
|
|
22
|
-
[
|
|
23
|
-
[
|
|
24
|
-
|
|
25
|
-
[
|
|
26
|
-
|
|
6
|
+
[1m[7m[36m RUN [39m[27m[22m [36mv2.1.8 [39m[90m/home/runner/work/monorepolint/monorepolint/packages/utils[39m
|
|
7
|
+
[2mCoverage enabled with [22m[33mv8[39m
|
|
8
|
+
|
|
9
|
+
[32m✓[39m src/__tests__/CachingHost.spec.ts [2m([22m[2m11 tests[22m[2m)[22m[90m 28[2mms[22m[39m
|
|
10
|
+
|
|
11
|
+
[2m Test Files [22m [1m[32m1 passed[39m[22m[90m (1)[39m
|
|
12
|
+
[2m Tests [22m [1m[32m11 passed[39m[22m[90m (11)[39m
|
|
13
|
+
[2m Start at [22m 16:18:29
|
|
14
|
+
[2m Duration [22m 1.58s[2m (transform 210ms, setup 0ms, collect 203ms, tests 28ms, environment 0ms, prepare 181ms)[22m
|
|
15
|
+
|
|
16
|
+
[34m % [39m[2mCoverage report from [22m[33mv8[39m
|
|
17
|
+
-------------------|---------|----------|---------|---------|-------------------
|
|
18
|
+
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
|
|
19
|
+
-------------------|---------|----------|---------|---------|-------------------
|
|
20
|
+
All files | 88.98 | 71.15 | 79.31 | 88.98 |
|
|
21
|
+
...egateTiming.ts | 100 | 100 | 100 | 100 |
|
|
22
|
+
CachingHost.ts | 84.43 | 74 | 92 | 84.43 | ...69-470,478-479
|
|
23
|
+
Host.ts | 0 | 0 | 0 | 0 | 1
|
|
24
|
+
PackageJson.ts | 0 | 0 | 0 | 0 | 1
|
|
25
|
+
SimpleHost.ts | 100 | 100 | 100 | 100 |
|
|
26
|
+
Table.ts | 100 | 100 | 100 | 100 |
|
|
27
|
+
Timing.ts | 100 | 100 | 100 | 100 |
|
|
28
|
+
...orkspaceDir.ts | 100 | 100 | 100 | 100 |
|
|
29
|
+
...geNameToDir.ts | 100 | 100 | 100 | 100 |
|
|
30
|
+
...PackageDirs.ts | 0 | 0 | 0 | 0 | 1-70
|
|
31
|
+
index.ts | 0 | 0 | 0 | 0 | 1
|
|
32
|
+
matchesAnyGlob.ts | 100 | 100 | 100 | 100 |
|
|
33
|
+
mutateJson.ts | 100 | 100 | 100 | 100 |
|
|
34
|
+
...ndsToSanity.ts | 100 | 100 | 100 | 100 |
|
|
35
|
+
-------------------|---------|----------|---------|---------|-------------------
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
|
|
2
|
-
> @monorepolint/utils@0.6.0-alpha.
|
|
2
|
+
> @monorepolint/utils@0.6.0-alpha.2 transpile-typescript /home/runner/work/monorepolint/monorepolint/packages/utils
|
|
3
3
|
> tsup --config ../../tsup.config.cjs
|
|
4
4
|
|
|
5
5
|
[34mCLI[39m Building entry: src/index.ts
|
|
6
6
|
[34mCLI[39m Using tsconfig: tsconfig.json
|
|
7
|
-
[34mCLI[39m tsup v8.
|
|
7
|
+
[34mCLI[39m tsup v8.3.5
|
|
8
8
|
[34mCLI[39m Using tsup config: /home/runner/work/monorepolint/monorepolint/tsup.config.cjs
|
|
9
9
|
[34mCLI[39m Target: node16
|
|
10
10
|
[34mCLI[39m Cleaning output folder
|
|
11
11
|
[34mESM[39m Build start
|
|
12
|
-
[32mESM[39m [1mbuild/js/index.js [22m[32m26.
|
|
13
|
-
[32mESM[39m [1mbuild/js/index.js.map [22m[
|
|
14
|
-
[32mESM[39m ⚡️ Build success in
|
|
12
|
+
[32mESM[39m [1mbuild/js/index.js [22m[32m26.56 KB[39m
|
|
13
|
+
[32mESM[39m [1mbuild/js/index.js.map [22m[32m60.13 KB[39m
|
|
14
|
+
[32mESM[39m ⚡️ Build success in 54ms
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,33 @@
|
|
|
1
1
|
# @monorepolint/utils
|
|
2
2
|
|
|
3
|
+
## 0.6.0-alpha.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 4f42aad: Upgraded dependencies
|
|
8
|
+
|
|
9
|
+
- `@docusaurus/*`: 3.7.0
|
|
10
|
+
- `@mdx-js/react`: 3.1.0
|
|
11
|
+
- `chalk`: 5.4.1
|
|
12
|
+
- `eslint`: 9.18.0
|
|
13
|
+
- `gh-pages`: 6.3.0
|
|
14
|
+
- `gh-pages`: 6.3.0
|
|
15
|
+
- `globals`: 15.14.0
|
|
16
|
+
- `globby`: 14.0.2
|
|
17
|
+
- `husky`: 15.14.0
|
|
18
|
+
- `lint-staged`: 15.3.0
|
|
19
|
+
- `micromatch`: 4.0.8
|
|
20
|
+
- `mock-fs`: 5.4.1
|
|
21
|
+
- `prettier`: 3.4.2
|
|
22
|
+
- `prism-react-renderer`:2.4.1
|
|
23
|
+
- `semver`: 7.6.3
|
|
24
|
+
- `tslib`: 2.8.1
|
|
25
|
+
- `tsup`: 8.3.5
|
|
26
|
+
- `typescript-eslint`: 8.20.0
|
|
27
|
+
- `turbo`: 2.x
|
|
28
|
+
|
|
29
|
+
## 0.6.0-alpha.1
|
|
30
|
+
|
|
3
31
|
## 0.6.0-alpha.0
|
|
4
32
|
|
|
5
33
|
## 0.5.0
|
package/build/js/index.js
CHANGED
|
@@ -3,7 +3,7 @@ import { existsSync } from "fs";
|
|
|
3
3
|
import * as glob from "glob";
|
|
4
4
|
import * as path from "node:path";
|
|
5
5
|
import * as fs from "node:fs";
|
|
6
|
-
import
|
|
6
|
+
import readYamlFile from "read-yaml-file";
|
|
7
7
|
import { findPackages } from "find-packages";
|
|
8
8
|
async function findPNPMWorkspacePackages(workspaceRoot) {
|
|
9
9
|
workspaceRoot = fs.realpathSync(workspaceRoot);
|
|
@@ -176,8 +176,7 @@ var CachingHost = class {
|
|
|
176
176
|
// We need many trees because of windows, key is the `root`
|
|
177
177
|
#trees = /* @__PURE__ */ new Map();
|
|
178
178
|
#replaceNode(node, partialNewNode) {
|
|
179
|
-
if (!node.parent)
|
|
180
|
-
throw new Error("Cannot replace root node");
|
|
179
|
+
if (!node.parent) throw new Error("Cannot replace root node");
|
|
181
180
|
const newNode = {
|
|
182
181
|
...partialNewNode,
|
|
183
182
|
fullPath: node.fullPath,
|
|
@@ -283,10 +282,8 @@ var CachingHost = class {
|
|
|
283
282
|
}
|
|
284
283
|
#getNodeResolvingSymlinks(filePath, follows = 100) {
|
|
285
284
|
const node = this.#getNode(filePath);
|
|
286
|
-
if (!node || node.type !== "symlink")
|
|
287
|
-
|
|
288
|
-
if (follows === 0)
|
|
289
|
-
throw new Error("Exhausted symlink follows");
|
|
285
|
+
if (!node || node.type !== "symlink") return node;
|
|
286
|
+
if (follows === 0) throw new Error("Exhausted symlink follows");
|
|
290
287
|
return this.#getNodeResolvingSymlinks(node.symlink, follows--);
|
|
291
288
|
}
|
|
292
289
|
mkdir(filePath, opts = { recursive: false }) {
|
|
@@ -295,8 +292,7 @@ var CachingHost = class {
|
|
|
295
292
|
if (filePath === pathWithSymlinks) {
|
|
296
293
|
assertType(node, "dir");
|
|
297
294
|
assertHasParent(node);
|
|
298
|
-
if (!node.tombstone)
|
|
299
|
-
return;
|
|
295
|
+
if (!node.tombstone) return;
|
|
300
296
|
} else if (path3.dirname(filePath) === pathWithSymlinks) {
|
|
301
297
|
assertType(node, "dir");
|
|
302
298
|
assertNoTombstone(node);
|
|
@@ -398,8 +394,7 @@ var CachingHost = class {
|
|
|
398
394
|
deleteFile(filePath) {
|
|
399
395
|
const canonicalPath = path3.resolve(filePath);
|
|
400
396
|
const node = this.#getNode(canonicalPath);
|
|
401
|
-
if (!node || node.type === "file" && node.tombstone === true)
|
|
402
|
-
return;
|
|
397
|
+
if (!node || node.type === "file" && node.tombstone === true) return;
|
|
403
398
|
assertNotType(node, "dir");
|
|
404
399
|
this.#replaceNode(node, {
|
|
405
400
|
type: "file",
|
|
@@ -430,8 +425,7 @@ var CachingHost = class {
|
|
|
430
425
|
}
|
|
431
426
|
}
|
|
432
427
|
async #flushSymlinkNode(node) {
|
|
433
|
-
if (!node.needsFlush)
|
|
434
|
-
return;
|
|
428
|
+
if (!node.needsFlush) return;
|
|
435
429
|
try {
|
|
436
430
|
const linkValue = await this.fs.promises.readlink(node.fullPath);
|
|
437
431
|
if (linkValue === node.symlink) {
|
|
@@ -520,8 +514,7 @@ var Table = class {
|
|
|
520
514
|
...columnConfig.footer
|
|
521
515
|
});
|
|
522
516
|
} else if ("aggregate" in columnConfig.footer) {
|
|
523
|
-
if (columnConfig.type !== "bigint")
|
|
524
|
-
throw new Error("expecting bigint for aggregate");
|
|
517
|
+
if (columnConfig.type !== "bigint") throw new Error("expecting bigint for aggregate");
|
|
525
518
|
this.#footerRowConfig.push({
|
|
526
519
|
type: columnConfig.type,
|
|
527
520
|
renderAs: columnConfig.renderAs,
|
|
@@ -635,8 +628,7 @@ var Table = class {
|
|
|
635
628
|
rowText.trim();
|
|
636
629
|
console.log(rowText);
|
|
637
630
|
}
|
|
638
|
-
if (this.#config.showFooter)
|
|
639
|
-
this.#printFooterRow();
|
|
631
|
+
if (this.#config.showFooter) this.#printFooterRow();
|
|
640
632
|
console.log();
|
|
641
633
|
}
|
|
642
634
|
#getCellValueAsString(value, config) {
|
|
@@ -734,8 +726,7 @@ var matchesAnyGlob = function matchesAnyGlobFunc(needle, haystack) {
|
|
|
734
726
|
singleMatcherHits++;
|
|
735
727
|
singleMatcherSaves++;
|
|
736
728
|
}
|
|
737
|
-
if (result)
|
|
738
|
-
break;
|
|
729
|
+
if (result) break;
|
|
739
730
|
}
|
|
740
731
|
cacheForHaystack.set(needle, result);
|
|
741
732
|
} else {
|
package/build/js/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/getWorkspacePackageDirs.ts","../../src/mutateJson.ts","../../src/findWorkspaceDir.ts","../../src/getPackageNameToDir.ts","../../src/SimpleHost.ts","../../src/CachingHost.ts","../../src/matchesAnyGlob.ts","../../src/nanosecondsToSanity.ts","../../src/Table.ts","../../src/AggregateTiming.ts","../../src/Timing.ts"],"sourcesContent":["/*!\n * Copyright 2019 Palantir Technologies, Inc.\n *\n * Licensed under the MIT license. See LICENSE file in the project root for details.\n *\n */\n\nimport { existsSync } from \"fs\";\nimport * as glob from \"glob\";\nimport * as path from \"node:path\";\nimport * as fs from \"node:fs\";\nimport { Host } from \"./Host.js\";\nimport { PackageJson } from \"./PackageJson.js\";\nimport * as readYamlFile from \"read-yaml-file\";\nimport { findPackages } from \"find-packages\";\n\nasync function findPNPMWorkspacePackages(workspaceRoot: string) {\n workspaceRoot = fs.realpathSync(workspaceRoot);\n const workspaceManifest = await readYamlFile.default<{ packages?: string[] }>(\n path.join(workspaceRoot, \"pnpm-workspace.yaml\")\n );\n\n return findPackages(workspaceRoot, {\n ignore: [\"**/node_modules/**\", \"**/bower_components/**\"],\n includeRoot: true,\n patterns: workspaceManifest.packages,\n });\n}\n\nexport async function getWorkspacePackageDirs(\n host: Pick<Host, \"readJson\" | \"exists\">,\n workspaceDir: string,\n resolvePaths: boolean = false\n) {\n const packageJson = host.readJson(path.join(workspaceDir, \"package.json\")) as PackageJson;\n\n const isPnpmWorkspace = host.exists(path.join(workspaceDir, \"pnpm-workspace.yaml\"));\n if (isPnpmWorkspace) {\n const workspacePackages = await findPNPMWorkspacePackages(workspaceDir);\n if (workspacePackages.length === 0) {\n throw new Error(\"Invalid workspaceDir: \" + workspaceDir);\n }\n return workspacePackages.map((project) => project.dir).filter((d) => d !== workspaceDir);\n }\n\n if (!packageJson.workspaces) {\n throw new Error(\"Unsupported! Monorepo is not backed by either pnpm nor yarn workspaces.\");\n }\n\n const ret: string[] = [];\n const packageGlobs = Array.isArray(packageJson.workspaces)\n ? packageJson.workspaces\n : packageJson.workspaces.packages || [];\n\n for (const pattern of packageGlobs) {\n for (const packagePath of glob.sync(pattern, { cwd: workspaceDir })) {\n const packageJsonPath = path.join(workspaceDir, packagePath, \"package.json\");\n\n if (existsSync(packageJsonPath)) {\n if (resolvePaths === true) {\n ret.push(path.resolve(path.join(workspaceDir, packagePath)));\n } else {\n ret.push(packagePath);\n }\n }\n }\n }\n\n return ret;\n}\n","/*!\n * Copyright 2019 Palantir Technologies, Inc.\n *\n * Licensed under the MIT license. See LICENSE file in the project root for details.\n *\n */\n\nimport { Host } from \"./Host.js\";\nexport function mutateJson<T extends object>(path: string, host: Host, mutator: (f: T) => T) {\n let file = host.readJson(path) as T;\n file = mutator(file);\n host.writeJson(path, file);\n}\n","/*!\n * Copyright 2019 Palantir Technologies, Inc.\n *\n * Licensed under the MIT license. See LICENSE file in the project root for details.\n *\n */\n\nimport * as path from \"path\";\nimport { Host } from \"./Host.js\";\nimport { PackageJson } from \"./PackageJson.js\";\nimport * as fs from \"fs\";\nimport { findUp } from \"find-up\";\n\nexport async function findPnpmWorkspaceDir(cwd: string) {\n const workspaceManifestLocation = await findUp(\"pnpm-workspace.yaml\", {\n cwd: await fs.promises.realpath(cwd),\n });\n return workspaceManifestLocation && path.dirname(workspaceManifestLocation);\n}\n\nexport async function findWorkspaceDir(\n host: Pick<Host, \"readJson\" | \"exists\">,\n dir: string\n): Promise<string | undefined> {\n // Defining workspaces in package.json is not necessary in PNPM\n const maybePnpmWorkspaceDir = await findPnpmWorkspaceDir(dir);\n if (maybePnpmWorkspaceDir != null) {\n return maybePnpmWorkspaceDir;\n }\n\n // We may not be in a repository that uses PNPM, look for workspaces in package.json\n const packagePath = path.join(dir, \"package.json\");\n if (host.exists(packagePath)) {\n const packageJson = host.readJson(packagePath) as PackageJson;\n if (packageJson.workspaces !== undefined) {\n return dir;\n }\n }\n\n const nextDir = path.normalize(path.join(dir, \"..\"));\n if (nextDir === dir) {\n return undefined;\n }\n\n return findWorkspaceDir(host, nextDir);\n}\n","/*!\n * Copyright 2019 Palantir Technologies, Inc.\n *\n * Licensed under the MIT license. See LICENSE file in the project root for details.\n *\n */\n\nimport { join as pathJoin } from \"path\";\nimport { getWorkspacePackageDirs } from \"./getWorkspacePackageDirs.js\";\nimport { Host } from \"./Host.js\";\nimport { PackageJson } from \"./PackageJson.js\";\n/**\n * returns a map of package names to their directories in the workspace.\n * if `resolvePaths` is true, the returned directory names are absolute paths\n * resolved against the `workspaceDir`.\n */\nexport async function getPackageNameToDir(\n host: Pick<Host, \"readJson\" | \"exists\">,\n workspaceDir: string,\n resolvePaths: boolean = false\n) {\n const ret = new Map<string, string>();\n\n const workspacePackages = await getWorkspacePackageDirs(host, workspaceDir, resolvePaths);\n for (const packageDir of workspacePackages) {\n const packagePath = pathJoin(packageDir, \"package.json\");\n const { name } = host.readJson(packagePath) as PackageJson;\n if (name === undefined) {\n throw new Error(`Package needs a name: ${packagePath}`);\n }\n ret.set(name, packageDir);\n }\n return ret;\n}\n","/*!\n * Copyright 2022 Palantir Technologies, Inc.\n *\n * Licensed under the MIT license. See LICENSE file in the project root for details.\n *\n */\n\nimport * as realFs from \"fs\";\n\nimport { Host } from \"./Host.js\";\nexport class SimpleHost implements Host {\n constructor(private fs: typeof realFs = realFs) {}\n mkdir(directoryPath: string, opts?: { recursive: boolean }): void {\n this.fs.mkdirSync(directoryPath, { recursive: opts?.recursive ?? false });\n }\n rmdir(directoryPath: string): void {\n this.fs.rmdirSync(directoryPath);\n }\n\n exists(path: string): boolean {\n return this.fs.existsSync(path);\n }\n\n writeFile(path: string, buffer: Buffer): void;\n writeFile(path: string, body: string, opts: { encoding: BufferEncoding }): void;\n writeFile(path: string, body: string | Buffer, opts?: { encoding: BufferEncoding }): void {\n if (opts) {\n this.fs.writeFileSync(path, body, { encoding: opts.encoding });\n } else {\n this.fs.writeFileSync(path, body);\n }\n }\n readFile(path: string, opts?: undefined): Buffer;\n readFile(path: string, opts: { encoding: BufferEncoding }): string;\n readFile(path: string, opts: { asJson: true }): object;\n readFile(path: string, opts?: { encoding?: BufferEncoding; asJson?: boolean }): string | object | Buffer {\n if (opts?.asJson) {\n return JSON.parse(this.fs.readFileSync(path, \"utf-8\"));\n }\n return this.fs.readFileSync(path, opts?.encoding);\n }\n deleteFile(path: string) {\n this.fs.unlinkSync(path);\n }\n readJson(filename: string) {\n const contents = this.fs.readFileSync(filename, \"utf-8\");\n return JSON.parse(contents);\n }\n writeJson(path: string, o: object): void {\n return this.fs.writeFileSync(path, JSON.stringify(o, undefined, 2) + \"\\n\");\n }\n flush() {\n // noop in the simple case\n return Promise.resolve();\n }\n}\n","/*!\n * Copyright 2022 Palantir Technologies, Inc.\n *\n * Licensed under the MIT license. See LICENSE file in the project root for details.\n *\n */\n\nimport * as realFs from \"node:fs\";\nimport { Host } from \"./Host.js\";\nimport * as path from \"node:path\";\n\nfunction assertNoTombstone(node: Node): asserts node is Node & { tombstone?: false } {\n if (node.tombstone) {\n throw new Error(`Unexpected tombstone ${JSON.stringify(node)}`);\n }\n}\n\nfunction assertNotType<N extends Node, T extends Node[\"type\"]>(\n node: N,\n type: T\n): asserts node is N & { type: Exclude<N[\"type\"], T> } {\n if (node.type === type) {\n throw new Error(`Unexpected node type ${JSON.stringify(node)}`);\n }\n}\n\nfunction assertType<N extends Node, T extends Node[\"type\"]>(node: N, type: T): asserts node is N & { type: T } {\n if (node.type !== type) {\n throw new Error(`Unexpected node type ${JSON.stringify(node)}`);\n }\n}\n\nfunction assertExists<T extends Node>(node: T | undefined): asserts node is T {\n if (!node) {\n throw new Error(`Expected node to exist`);\n }\n}\n\nfunction assertHasParent(node: Node) {\n if (!node.parent) {\n throw new Error(\"Expected node to have a parent directory\");\n }\n}\n\ninterface BaseNode<T extends string> {\n type: T;\n fullPath: string;\n tombstone?: boolean;\n parent?: DirNode | DirStubNode;\n needsFlush: boolean;\n}\ninterface DirNode extends BaseNode<\"dir\"> {\n stub?: false;\n tombstone?: false;\n dir: Map<string, Node>;\n}\n\ninterface DirStubNode extends BaseNode<\"dir\"> {\n stub: true;\n tombstone?: false;\n dir: Map<string, Node>;\n}\n\ninterface DirTombstoneNode extends BaseNode<\"dir\"> {\n stub?: false;\n tombstone: true;\n dir: Map<string, Node>;\n}\n\ninterface FileNode extends BaseNode<\"file\"> {\n stub?: false;\n tombstone?: false;\n file: Buffer;\n}\n\ninterface FileTombstoneNode extends BaseNode<\"file\"> {\n stub?: false;\n tombstone: true;\n file?: never;\n}\n\ninterface FileStubNode extends BaseNode<\"file\"> {\n stub: true;\n tombstone?: false;\n file?: never;\n}\n\ninterface SymlinkNode extends BaseNode<\"symlink\"> {\n tombstone?: false;\n symlink: string;\n}\n\ntype Node = DirNode | FileNode | SymlinkNode | DirTombstoneNode | FileTombstoneNode | DirStubNode | FileStubNode;\n\nexport class CachingHost implements Host {\n // We need many trees because of windows, key is the `root`\n #trees = new Map<string, DirNode | DirStubNode>();\n\n constructor(\n private fs: Pick<\n typeof realFs,\n | \"existsSync\"\n | \"lstatSync\"\n | \"mkdirSync\"\n | \"promises\"\n | \"readdirSync\"\n | \"readFileSync\"\n | \"readlinkSync\"\n | \"realpathSync\"\n | \"rmdirSync\"\n | \"statSync\"\n | \"unlinkSync\"\n | \"writeFileSync\"\n > = realFs\n ) {}\n\n #replaceNode(\n node: FileNode | FileStubNode | SymlinkNode,\n newNode: Omit<FileTombstoneNode, \"fullPath\" | \"parent\">\n ): FileTombstoneNode;\n #replaceNode(\n node: FileNode | FileStubNode | FileTombstoneNode,\n newNode: Omit<FileNode, \"fullPath\" | \"parent\">\n ): FileNode;\n #replaceNode(\n node: DirTombstoneNode | DirStubNode,\n newNode: Omit<DirNode, \"fullPath\" | \"parent\" | \"dir\">\n ): DirStubNode;\n #replaceNode(node: DirNode, newNode: Omit<DirTombstoneNode, \"fullPath\" | \"parent\" | \"dir\">): DirTombstoneNode;\n #replaceNode(node: Node, partialNewNode: Omit<Node, \"fullPath\" | \"parent\">): Node {\n if (!node.parent) throw new Error(\"Cannot replace root node\");\n const newNode: Node = {\n ...partialNewNode,\n fullPath: node.fullPath,\n parent: node.parent,\n dir: (node as DirNode).dir,\n } as Node;\n node.parent.dir.set(path.basename(node.fullPath), newNode);\n return newNode;\n }\n\n #unstubDirectory(node: DirNode | DirStubNode): asserts node is DirNode {\n // So the rules for our stub dirs. We assume the things in the map are authority but\n // for things not in the map, the real FS is the authority\n for (const child of this.fs.readdirSync(node.fullPath)) {\n // just makign this call will populate the structure but its a little expensive.\n // TODO: make an unknown stub\n this.#getNode(path.join(node.fullPath, child));\n }\n node.stub = false;\n }\n\n /**\n * Assumes no parent -> path is root\n *\n * Throws if the path doesnt exist!\n */\n #stubify(filePath: string, parent: undefined): DirStubNode;\n #stubify(filePath: string, parent: DirNode | DirStubNode | undefined): DirStubNode | SymlinkNode | FileStubNode;\n #stubify(\n filePath: string,\n parent: DirNode | DirStubNode | undefined\n ): typeof parent extends undefined ? DirNode | DirStubNode : DirNode | DirStubNode | SymlinkNode | FileStubNode {\n const canonicalPath = path.resolve(filePath);\n\n if (!parent && canonicalPath !== path.parse(canonicalPath).root) {\n throw new Error(`parent can only be null if path is root. Instead got: ${canonicalPath}`);\n }\n const stat = this.fs.lstatSync(canonicalPath); // may throw\n\n let node: SymlinkNode | FileStubNode | DirStubNode;\n\n if (stat.isDirectory()) {\n node = {\n fullPath: canonicalPath,\n type: \"dir\",\n stub: true,\n dir: new Map(),\n parent,\n needsFlush: false,\n };\n } else if (stat.isSymbolicLink()) {\n node = {\n fullPath: canonicalPath,\n type: \"symlink\",\n symlink: this.fs.readlinkSync(canonicalPath),\n parent,\n needsFlush: false,\n };\n } else if (stat.isFile()) {\n node = {\n fullPath: canonicalPath,\n type: \"file\",\n stub: true,\n parent,\n needsFlush: false,\n };\n } else {\n throw new Error(`what is not a file nor symlink nor directory? nothing we care about: ${canonicalPath}`);\n }\n\n if (!parent && node.type === \"dir\") {\n this.#trees.set(canonicalPath, node);\n return node;\n } else if (parent) {\n parent.dir.set(path.basename(canonicalPath), node);\n } else {\n throw new Error(`root can only be a dir, got ${JSON.stringify(node)} for path: ${canonicalPath}`);\n }\n return node;\n }\n\n /**\n * Note: may return the node itself!\n * You should check the `fullPath` of the result.\n */\n #getNearestAncestorNode(filePath: string) {\n const canonicalPath = path.resolve(filePath);\n const { root } = path.parse(canonicalPath);\n const parts = [];\n\n let maybePath = canonicalPath;\n while (maybePath !== root) {\n parts.unshift(path.basename(maybePath));\n maybePath = path.dirname(maybePath);\n }\n\n let curPath = root;\n let curNode: Node = this.#trees.get(root) ?? this.#stubify(curPath, undefined); // its okay to throw if there is no root\n try {\n for (const part of parts) {\n assertNoTombstone(curNode);\n assertNotType(curNode, \"file\");\n if (curNode.type === \"symlink\") {\n const linkedNode = this.#getNodeResolvingSymlinks(path.resolve(path.dirname(curPath), curNode.symlink));\n assertExists(linkedNode);\n assertNoTombstone(linkedNode);\n assertType(linkedNode, \"dir\");\n curNode = linkedNode;\n }\n assertType(curNode, \"dir\");\n assertNoTombstone(curNode);\n curNode = curNode.dir.get(part) ?? this.#stubify(path.join(curNode.fullPath, part), curNode);\n curPath = path.join(curPath, part);\n }\n } catch (e) {\n // This error is expected when things done exist.\n // console.log(`Got EXPECTED error when trying to getNearestAncestorNode(${canonicalPath}): `, (e as any).message);\n }\n return { pathWithSymlinks: curPath, node: curNode };\n }\n\n #getNode(filePath: string) {\n const canonicalPath = path.resolve(filePath);\n const { pathWithSymlinks, node } = this.#getNearestAncestorNode(canonicalPath);\n if (pathWithSymlinks === canonicalPath) {\n return node;\n }\n return undefined;\n }\n\n #getNodeResolvingSymlinks(filePath: string, follows: number = 100): Exclude<Node, SymlinkNode> | undefined {\n const node = this.#getNode(filePath); // canonicalizes for us\n if (!node || node.type !== \"symlink\") return node;\n // this is a really poor mans way of doing this. but who has 100's of symlinks hanging around?\n if (follows === 0) throw new Error(\"Exhausted symlink follows\");\n\n return this.#getNodeResolvingSymlinks(node.symlink, follows--);\n }\n\n mkdir(filePath: string, opts: { recursive: boolean } = { recursive: false }): void {\n const canonicalPath = path.resolve(filePath);\n const { node, pathWithSymlinks } = this.#getNearestAncestorNode(canonicalPath);\n if (filePath === pathWithSymlinks) {\n assertType(node, \"dir\");\n assertHasParent(node);\n if (!node.tombstone) return; // already done\n } else if (path.dirname(filePath) === pathWithSymlinks) {\n assertType(node, \"dir\");\n assertNoTombstone(node);\n node.dir.set(path.basename(filePath), {\n type: \"dir\",\n fullPath: filePath,\n parent: node,\n dir: new Map(),\n needsFlush: true,\n });\n return;\n }\n\n if (!opts.recursive && path.dirname(canonicalPath) !== pathWithSymlinks) {\n throw new Error(\"no such file or directory\");\n }\n\n const rootPath = pathWithSymlinks;\n let maybePath = canonicalPath;\n const toMake: string[] = [];\n while (maybePath !== rootPath) {\n toMake.unshift(path.resolve(node.fullPath, path.relative(rootPath, maybePath)));\n maybePath = path.dirname(maybePath);\n }\n\n for (const dirToMake of toMake) {\n this.mkdir(dirToMake);\n }\n }\n\n rmdir(directoryPath: string): void {\n const node = this.#getNode(directoryPath);\n if (!node || node.tombstone) {\n return; // this isnt how FS usually work but its what we are doing\n }\n assertType(node, \"dir\");\n if (node.stub) {\n this.#unstubDirectory(node);\n }\n\n if (node.dir.size === 0) {\n this.#replaceNode(node, {\n type: \"dir\",\n tombstone: true,\n needsFlush: true,\n });\n } else {\n throw new Error(\"directory not empty\");\n }\n }\n\n exists(filePath: string): boolean {\n const node = this.#getNode(filePath); // canonicalizes for us\n return !!node && !node.tombstone;\n }\n\n readFile(filePath: string, opts?: undefined): Buffer;\n readFile(filePath: string, opts: { encoding: BufferEncoding }): string;\n readFile(filePath: string, opts: { asJson: true }): object;\n readFile(\n filePath: string,\n opts: undefined | { encoding: BufferEncoding; asJson?: false } | { encoding?: never; asJson: true }\n ) {\n let node = this.#getNodeResolvingSymlinks(filePath); // canonicalizes for us\n\n if (!node) {\n return undefined;\n }\n assertNotType(node, \"dir\");\n assertNoTombstone(node);\n\n if (node.stub) {\n node = this.#replaceNode(node, {\n type: \"file\",\n file: this.fs.readFileSync(filePath),\n needsFlush: false,\n });\n }\n\n if (!opts) {\n return Buffer.from(node.file);\n } else if (opts.asJson) {\n return JSON.parse(node.file.toString(\"utf-8\"));\n } else {\n return node.file.toString(opts.encoding);\n }\n }\n\n writeFile(filePath: string, buffer: Buffer): void;\n writeFile(filePath: string, body: string, opts: { encoding: BufferEncoding }): void;\n writeFile(filePath: string, body: string, opts: { encoding: BufferEncoding }): void;\n writeFile(filePath: string, body: string | Buffer, opts?: { encoding: BufferEncoding }) {\n const fileContentsAsBuffer = typeof body === \"string\" ? Buffer.from(body, opts?.encoding) : Buffer.from(body);\n\n const canonicalPath = path.resolve(filePath);\n const existingNode = this.#getNodeResolvingSymlinks(canonicalPath);\n if (existingNode) {\n if (existingNode.type === \"dir\") {\n throw new Error(\"cant write file to a dir\");\n }\n this.#replaceNode(existingNode, {\n file: fileContentsAsBuffer,\n type: \"file\",\n needsFlush: true,\n });\n return;\n }\n\n const maybeDirNode = this.#getNodeResolvingSymlinks(path.dirname(canonicalPath));\n assertExists(maybeDirNode);\n assertType(maybeDirNode, \"dir\");\n assertNoTombstone(maybeDirNode);\n\n maybeDirNode.dir.set(path.basename(canonicalPath), {\n type: \"file\",\n fullPath: canonicalPath,\n parent: maybeDirNode,\n file: fileContentsAsBuffer,\n needsFlush: true,\n });\n }\n\n deleteFile(filePath: string) {\n const canonicalPath = path.resolve(filePath);\n const node = this.#getNode(canonicalPath);\n if (!node || (node.type === \"file\" && node.tombstone === true)) return;\n assertNotType(node, \"dir\");\n this.#replaceNode(node, {\n type: \"file\",\n tombstone: true,\n needsFlush: true,\n });\n }\n\n readJson(filePath: string) {\n return this.readFile(filePath, { asJson: true });\n }\n\n writeJson(filePath: string, o: object): void {\n return this.writeFile(filePath, JSON.stringify(o, undefined, 2) + \"\\n\", {\n encoding: \"utf-8\",\n });\n }\n\n async #flushFileNode(node: FileNode | FileStubNode | FileTombstoneNode): Promise<unknown> {\n // FIXME all tombstones need a flush, so we can get rid of needsFlush for them\n if (node.tombstone) {\n try {\n await this.fs.promises.access(node.fullPath);\n return this.fs.promises.unlink(node.fullPath);\n } catch (e) {\n // should only throw if file doesnt exist which is no op\n return;\n }\n } else if (node.stub === true || node.needsFlush === false) {\n return;\n } else {\n // we dont do things with file stubs\n return this.fs.promises.writeFile(node.fullPath, node.file);\n }\n }\n\n async #flushSymlinkNode(node: SymlinkNode) {\n if (!node.needsFlush) return;\n try {\n const linkValue = await this.fs.promises.readlink(node.fullPath);\n if (linkValue === node.symlink) {\n return;\n }\n } catch (e) {\n // expected when the link doesnt exist\n }\n return this.fs.promises.symlink(node.symlink, node.fullPath);\n }\n\n async #flushDirNode(node: DirNode | DirStubNode | DirTombstoneNode): Promise<unknown> {\n if (!node.tombstone && node.needsFlush) {\n try {\n await this.fs.promises.access(node.fullPath); // throws if the file doesnt exist\n } catch (e) {\n await this.fs.promises.mkdir(node.fullPath); // throws if it does :(\n }\n }\n\n const promises: Promise<unknown>[] = [];\n for (const child of node.dir.values()) {\n if (node.tombstone && !child.tombstone) {\n throw new Error(\"Unexpected failure during sanity check. A non-deleted child is on a deleted dir\");\n }\n if (child.type === \"dir\") {\n promises.push(this.#flushDirNode(child));\n } else if (child.type === \"file\") {\n promises.push(this.#flushFileNode(child));\n } else if (child.type === \"symlink\") {\n promises.push(this.#flushSymlinkNode(child));\n } else {\n throw new Error(\"should never happen\");\n }\n }\n await Promise.all(promises);\n if (node.tombstone) {\n return this.fs.promises.rmdir(node.fullPath);\n }\n return;\n }\n\n flush() {\n const promises: Promise<unknown>[] = [];\n for (const rootNode of this.#trees.values()) {\n promises.push(this.#flushDirNode(rootNode));\n }\n return Promise.all(promises);\n }\n}\n","/*!\n * Copyright 2022 Palantir Technologies, Inc.\n *\n * Licensed under the MIT license. See LICENSE file in the project root for details.\n *\n */\n\nimport micromatch from \"micromatch\";\nimport { nanosecondsToSanity } from \"./nanosecondsToSanity.js\";\nimport { Table } from \"./Table.js\";\n// This file requires a LOT of caching to be performant. We have three layers to avoid work.\n\n/**\n * Multimap cache of whether a needle was found in the glob haystack. Short circuits many\n * individual checks against the globs.\n */\nconst cache = new Map</* haystack */ readonly string[], Map</* needle */ string, /* result */ boolean>>();\n\n/**\n * Multimap cache of whether a needle matches a glob. Allows us to avoid regexp's.\n */\nconst singleMatcherCache = new Map</* glob */ string, Map</* needle */ string, /* result*/ boolean>>();\n\n/**\n * Cache of glob to regular expression. Compiling the regular expression is expensive.\n */\nconst compiledGlobCache = new Map</* glob */ string, RegExp>();\n\nlet haystackMiss = 0;\nlet haystackHit = 0;\n\nlet matchTime = BigInt(0);\n\nlet singleMatcherHits = 0;\nlet singleMatcherMisses = 0;\nlet singleMatcherSaves = 0; // hits + hits you would have had if the haystack didn't save you\n\ninterface MatchesAnyGlob {\n (needle: string, haystack: readonly string[]): boolean | undefined;\n printStats?: () => void;\n}\nexport const matchesAnyGlob: MatchesAnyGlob = function matchesAnyGlobFunc(needle: string, haystack: readonly string[]) {\n matchTime -= process.hrtime.bigint();\n\n let cacheForHaystack = cache.get(haystack);\n if (cacheForHaystack === undefined) {\n cacheForHaystack = new Map<string, boolean>();\n cache.set(haystack, cacheForHaystack);\n }\n\n let result = cacheForHaystack!.get(needle);\n if (result === undefined) {\n haystackMiss++;\n result = false;\n for (const pattern of haystack) {\n // result = needleInPattern(needle, pattern); // commented out as a reminder to update both\n // BEGIN INLINE of needleInPattern\n let patternCache = singleMatcherCache.get(pattern);\n if (patternCache === undefined) {\n patternCache = new Map<string, boolean>();\n singleMatcherCache.set(pattern, patternCache);\n }\n\n // N.B. true/false/undefined\n result = patternCache.get(needle); // only thing different from the inline is we need to reuse `result`\n if (result === undefined) {\n let regexp: RegExp | undefined | false = compiledGlobCache.get(pattern);\n if (regexp === undefined) {\n regexp = micromatch.makeRe(pattern);\n // if (regexp === false) throw new Error(\"bad glob\");\n compiledGlobCache.set(pattern, regexp);\n }\n\n singleMatcherMisses++;\n result = regexp.test(needle);\n patternCache.set(needle, result);\n } else {\n singleMatcherHits++;\n singleMatcherSaves++;\n }\n // END INLINE of needleInPattern\n if (result) break;\n }\n cacheForHaystack!.set(needle, result);\n } else {\n singleMatcherSaves += haystack.length;\n haystackHit++;\n }\n matchTime += process.hrtime.bigint();\n return result;\n};\n\nmatchesAnyGlob.printStats = () => {\n const table = new Table<[string, string]>({\n title: \"matchesAnyGlob stats\",\n showHeader: true,\n showFooter: false,\n columns: [\n { header: \"Stat\", type: \"string\" },\n { header: \"Value\", type: \"string\" },\n ],\n });\n table.addRow(\"Haystack Miss\", \"\" + haystackMiss);\n table.addRow(\"Haystack Hit\", \"\" + haystackHit);\n table.addRow(\"Single Glob Hits\", \"\" + singleMatcherHits);\n table.addRow(\"Single Glob Misses\", \"\" + singleMatcherMisses);\n table.addRow(\"Single Glob Saves\", \"\" + singleMatcherSaves);\n table.addRow(\"Total Time\", nanosecondsToSanity(matchTime, 6));\n\n table.print();\n};\n\n/**\n * @deprecated Don't use this directly. We manually inline it above\n */\nexport function needleInPattern(needle: string, pattern: string) {\n // benchmark says the uncommented version is best\n // https://jsben.ch/Y8TWs\n\n // option 2\n let patternCache = singleMatcherCache.get(pattern);\n if (patternCache === undefined) {\n patternCache = new Map<string, boolean>();\n singleMatcherCache.set(pattern, patternCache);\n }\n\n // N.B. true/false/undefined\n let result = patternCache.get(needle);\n if (result === undefined) {\n let regexp: RegExp | undefined | false = compiledGlobCache.get(pattern);\n if (regexp === undefined) {\n regexp = micromatch.makeRe(pattern);\n // if (regexp === false) throw new Error(\"bad glob\");\n compiledGlobCache.set(pattern, regexp);\n }\n\n singleMatcherMisses++;\n result = regexp.test(needle);\n patternCache.set(needle, result);\n } else {\n singleMatcherHits++;\n singleMatcherSaves++;\n }\n\n return result;\n}\n","/*!\n * Copyright 2022 Palantir Technologies, Inc.\n *\n * Licensed under the MIT license. See LICENSE file in the project root for details.\n *\n */\n\nexport function nanosecondsToSanity(n: bigint, precision: number = 9) {\n return n / BigInt(1000000000) + \".\" + (\"\" + (n % BigInt(1000000000))).padStart(9, \"0\").substring(0, precision) + \"s\";\n}\n","/*!\n * Copyright 2022 Palantir Technologies, Inc.\n *\n * Licensed under the MIT license. See LICENSE file in the project root for details.\n *\n */\n// tslint:disable:no-console\nimport { nanosecondsToSanity } from \"./nanosecondsToSanity.js\";\ntype HeaderFooterHelper<HB, FB, H, F> = (HB extends true ? { header: H } : { header?: H }) &\n (FB extends true ? { footer: F } : { footer?: F });\n\ntype WithAlignemnt = { alignment?: \"right\" | \"left\" };\ntype BaseCellConfig = WithAlignemnt & { type: \"bigint\" | \"string\" };\n\ntype BaseBigIntCellConfig = {\n type: \"bigint\";\n renderAs?: \"nanoseconds\";\n precision?: number;\n} & WithAlignemnt;\ntype BaseStringCellConfig = { type: \"string\" } & WithAlignemnt;\n\ntype BigIntColumnConfig<H, F> = WithAlignemnt &\n BaseBigIntCellConfig &\n HeaderFooterHelper<H, F, string, AggregateFooterConfig | StaticFooterConfig>;\n\ntype StringColumnConfig<H, F> = WithAlignemnt &\n BaseStringCellConfig &\n HeaderFooterHelper<H, F, string, StaticFooterConfig>;\n\ntype AggregateFooterConfig = {\n aggregate: \"sum\" | \"average\";\n renderAs?: \"nanoseconds\";\n precision?: number;\n} & WithAlignemnt;\n\ntype StaticFooterConfig = StrictStaticFooterConfig | string;\ntype StrictStaticFooterConfig = {\n aggregate: \"static\";\n value: string;\n} & WithAlignemnt;\n\ntype AnyStrictFooterConfig = AggregateFooterConfig | StrictStaticFooterConfig;\n\ntype TableConfig<T extends any[], H extends boolean, F extends boolean> = {\n sortColumn?: number;\n padding?: number;\n showHeader: H;\n showFooter: F;\n columns: {\n [K in keyof T]: T[K] extends bigint ? BigIntColumnConfig<H, F> : StringColumnConfig<H, F>;\n };\n title: string;\n};\n\ntype InternalTableConfig = {\n padding: number;\n showHeader: boolean;\n showFooter: boolean;\n sortColumn?: number;\n columns: Array<BigIntColumnConfig<any, any> | StringColumnConfig<any, any>>;\n title: string;\n};\n\nexport class Table<T extends any[]> {\n #rows: T[] = [];\n #config: InternalTableConfig;\n #columnWidths: number[] = [];\n #footer: Array<bigint | string> = [];\n #footerRowConfig?: Array<Required<BaseCellConfig> & AnyStrictFooterConfig>;\n #totalWidth = 0;\n\n constructor(\n config:\n | TableConfig<T, true, true>\n | TableConfig<T, true, false>\n | TableConfig<T, false, true>\n | TableConfig<T, false, false>\n ) {\n this.#config = {\n padding: 2,\n ...config,\n };\n this.#columnWidths.fill(0, 0, config.columns.length);\n\n if (config.showFooter) {\n this.#footerRowConfig = [];\n for (const columnConfig of config.columns) {\n if (columnConfig.footer === undefined) {\n throw new Error(\"Must specify footer fields when showFooter is true\");\n } else if (typeof columnConfig.footer === \"string\") {\n this.#footerRowConfig.push({\n type: \"string\",\n alignment: \"left\",\n aggregate: \"static\",\n value: columnConfig.footer,\n });\n } else if (\"value\" in columnConfig.footer) {\n this.#footerRowConfig.push({\n type: \"string\",\n alignment: \"left\",\n ...columnConfig.footer,\n });\n } else if (\"aggregate\" in columnConfig.footer) {\n if (columnConfig.type !== \"bigint\") throw new Error(\"expecting bigint for aggregate\");\n this.#footerRowConfig.push({\n type: columnConfig.type,\n renderAs: columnConfig.renderAs,\n precision: columnConfig.precision,\n alignment: \"right\",\n ...columnConfig.footer,\n });\n }\n }\n }\n }\n\n addRow(...data: T) {\n // TODO: maybe clone the data\n this.#rows.push(data);\n }\n\n #sumColumn(c: number) {\n let total = BigInt(0);\n for (const row of this.#rows) {\n total += row[c];\n }\n return total;\n }\n\n #updateFooterRow() {\n const footerRowConfig = this.#footerRowConfig;\n if (footerRowConfig) {\n for (let c = 0; c < footerRowConfig.length; c++) {\n const footerColConfig = footerRowConfig[c];\n\n switch (footerColConfig.aggregate) {\n case \"sum\":\n this.#footer[c] = this.#sumColumn(c);\n break;\n case \"average\":\n this.#footer[c] = this.#sumColumn(c) / BigInt(this.#rows.length);\n break;\n case \"static\":\n this.#footer[c] = footerColConfig.value;\n break;\n }\n }\n }\n }\n\n #calculateColumnWidths() {\n this.#columnWidths.fill(0, 0, this.#config.columns.length);\n\n for (let c = 0; c < this.#config.columns.length; c++) {\n const colConfig = this.#config.columns[c];\n this.#columnWidths[c] = Math.max(\n (this.#config.columns[c].header ?? \"\").length,\n ...this.#rows.map((a) => this.#getCellValueAsString(a[c], colConfig).length),\n this.#footer && this.#footerRowConfig\n ? this.#getCellValueAsString(this.#footer?.[c] ?? \"\", this.#footerRowConfig[c]).length\n : 0\n );\n }\n\n this.#totalWidth = 0;\n for (const colWidth of this.#columnWidths) {\n this.#totalWidth += colWidth;\n }\n this.#totalWidth += (this.#columnWidths.length - 1) * this.#config.padding;\n }\n\n #printSeparator(fillString: string) {\n const paddingString = \"\".padStart(this.#config.padding, \" \");\n\n let hr2 = \"\";\n\n // tslint:disable-next-line: prefer-for-of\n for (let c = 0; c < this.#columnWidths.length; c++) {\n hr2 += \"\".padStart(this.#columnWidths[c], fillString) + paddingString;\n }\n hr2 = hr2.trimRight();\n console.log(hr2);\n }\n\n #printHeaderRow() {\n if (this.#config.showHeader) {\n const colConfigs = this.#config.columns;\n const paddingString = \"\".padStart(this.#config.padding, \" \");\n\n let hr = \"\";\n for (let c = 0; c < colConfigs.length; c++) {\n const heading = colConfigs[c].header ?? \"\";\n hr += heading.padEnd(this.#columnWidths[c], \" \") + paddingString;\n }\n hr = hr.trimRight();\n console.log(hr);\n\n this.#printSeparator(\"-\");\n }\n }\n\n #printFooterRow() {\n const footerRow = this.#footer;\n if (footerRow) {\n this.#printSeparator(\"=\");\n\n const paddingString = \"\".padStart(this.#config.padding, \" \");\n\n let hr = \"\";\n for (let c = 0; c < footerRow.length; c++) {\n hr += this.#getCellValueAligned(footerRow[c], this.#footerRowConfig![c], c) + paddingString; // .padEnd(this.#columnWidths[c], \" \") + paddingString;\n }\n hr = hr.trimRight();\n console.log(hr);\n }\n }\n\n print() {\n // let data = [...this.#rows];\n if (this.#config.sortColumn !== undefined) {\n // todo\n }\n\n this.#updateFooterRow();\n this.#calculateColumnWidths();\n\n console.log();\n console.log(`${this.#config.title}`);\n console.log(\"\".padStart(this.#totalWidth, \"=\"));\n\n const paddingString = \"\".padStart(this.#config.padding, \" \");\n if (this.#config.showHeader) {\n this.#printHeaderRow();\n }\n\n for (let r = 0; r < this.#rows.length; r++) {\n let rowText = \"\";\n for (let c = 0; c < this.#config.columns.length; c++) {\n rowText += this.getEntryAsStringAligned(c, r) + paddingString;\n }\n rowText.trim();\n console.log(rowText);\n }\n\n if (this.#config.showFooter) this.#printFooterRow();\n console.log();\n }\n\n #getCellValueAsString(value: bigint | string, config: BaseBigIntCellConfig | BaseStringCellConfig) {\n if (config.type === \"bigint\" && config.renderAs === \"nanoseconds\") {\n return nanosecondsToSanity(value as bigint, config.precision ?? 9);\n } else {\n return \"\" + value;\n }\n }\n\n #getCellValueAligned(value: bigint | string, config: BaseBigIntCellConfig | BaseStringCellConfig, column: number) {\n let result: string;\n if (config.type === \"bigint\" && config.renderAs === \"nanoseconds\") {\n result = nanosecondsToSanity(value as bigint, config.precision ?? 9);\n } else {\n result = \"\" + value;\n }\n\n if (config.alignment === \"left\") {\n return result.padEnd(this.#columnWidths[column]);\n } else {\n return result.padStart(this.#columnWidths[column]);\n }\n }\n\n getEntryAsString(colNum: number, rowNum: number) {\n const config = this.#config.columns[colNum];\n\n if (config.type === \"bigint\" && config.renderAs === \"nanoseconds\") {\n return nanosecondsToSanity(this.#rows[rowNum][colNum], config.precision ?? 9);\n } else {\n return \"\" + this.#rows[rowNum][colNum];\n }\n }\n\n getEntryAsStringAligned(colNum: number, rowNum: number) {\n const config = this.#config.columns[colNum];\n\n let result: string;\n if (config.type === \"bigint\" && config.renderAs === \"nanoseconds\") {\n result = nanosecondsToSanity(this.#rows[rowNum][colNum], config.precision ?? 9);\n } else {\n result = \"\" + this.#rows[rowNum][colNum];\n }\n\n if (config.alignment === \"left\") {\n return result.padEnd(this.#columnWidths[colNum]);\n } else {\n return result.padStart(this.#columnWidths[colNum]);\n }\n }\n\n getColumnWidth(colNum: number, config: BigIntColumnConfig<boolean, boolean> | StringColumnConfig<boolean, boolean>) {\n let maxWidth = Math.max(\n (config.header ?? \"\").length,\n this.#footer && this.#footerRowConfig\n ? this.#getCellValueAsString(this.#footer[colNum], this.#footerRowConfig[colNum]).length\n : 0\n );\n\n for (let r = 0; r < this.#rows.length; r++) {\n maxWidth = Math.max(maxWidth, this.getEntryAsString(colNum, r).length);\n // if (config.type == \"bigint\" && config.renderAs === \"nanoseconds\") {\n // maxWidth = Math.max(maxWidth, Number(row[colNum] / BigInt(1000000000)) + 10); // 1 for period, 9 for digits\n // } else if (config.type == \"bigint\" || config.type == \"string\") {\n // maxWidth = Math.max(maxWidth, (\"\" + row[colNum]).length);\n // }\n }\n\n return maxWidth;\n }\n}\n","/*!\n * Copyright 2022 Palantir Technologies, Inc.\n *\n * Licensed under the MIT license. See LICENSE file in the project root for details.\n *\n */\n// tslint:disable:no-console\n\nimport { Table } from \"./Table.js\";\nexport class AggregateTiming {\n #data = new Map<string, { count: number; total: bigint }>();\n #last: { count: number; total: bigint } | undefined;\n\n constructor(private title: string) {}\n\n public start(name: string) {\n const time = process.hrtime.bigint();\n if (this.#last) {\n this.#last.total += time;\n }\n\n let data = this.#data.get(name);\n if (data === undefined) {\n data = { count: 1, total: -time };\n this.#data.set(name, data);\n } else {\n data.total -= time;\n data.count++;\n }\n this.#last = data;\n }\n\n public stop() {\n const time = process.hrtime.bigint();\n if (this.#last) {\n this.#last.total += time;\n this.#last = undefined;\n }\n }\n\n public printResults() {\n const table = new Table<[bigint, string, bigint, bigint]>({\n sortColumn: -1,\n showFooter: true,\n showHeader: true,\n title: this.title,\n columns: [\n {\n header: \"Duration\",\n type: \"bigint\",\n renderAs: \"nanoseconds\",\n footer: { aggregate: \"sum\" },\n },\n { header: \"Task\", type: \"string\", alignment: \"left\", footer: \"TOTAL\" },\n { header: \"Count\", type: \"bigint\", footer: { aggregate: \"sum\" } },\n { header: \"Avg\", type: \"bigint\", footer: { aggregate: \"average\" } },\n ],\n });\n\n for (const [name, value] of this.#data) {\n table.addRow(\n value.total,\n name,\n BigInt(value.count), // fixme this can be a number later\n value.total / BigInt(value.count)\n );\n }\n table.print();\n }\n}\n","/*!\n * Copyright 2022 Palantir Technologies, Inc.\n *\n * Licensed under the MIT license. See LICENSE file in the project root for details.\n *\n */\n// tslint:disable:no-console\nimport { Table } from \"./Table.js\";\nexport class Timing {\n #starts: Array<{ name?: string; start: bigint }> = [];\n constructor(private title: string) {\n this.stop(); // make sure we have starting point\n }\n\n public start(name: string) {\n this.#starts.push({ name, start: process.hrtime.bigint() });\n }\n\n public stop() {\n this.#starts.push({ start: process.hrtime.bigint() });\n }\n\n public printResults() {\n const table = new Table<[bigint, string]>({\n sortColumn: -1,\n showFooter: true,\n showHeader: true,\n title: this.title,\n columns: [\n {\n header: \"Duration\",\n type: \"bigint\",\n renderAs: \"nanoseconds\",\n precision: 4,\n footer: { aggregate: \"sum\" },\n },\n { header: \"Task\", type: \"string\", footer: \"TOTAL\" },\n ],\n });\n\n this.stop(); // be sure we stopped the last one\n\n let cur: { name?: string; start: bigint } = this.#starts[0];\n for (const entry of this.#starts) {\n if (cur.name) {\n const span = entry.start - cur.start;\n table.addRow(span, cur.name);\n }\n cur = entry;\n }\n\n table.print();\n }\n}\n"],"mappings":"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","names":["path","path","fs","fs","path","realFs","path","fs","promises"]}
|
|
1
|
+
{"version":3,"sources":["../../src/getWorkspacePackageDirs.ts","../../src/mutateJson.ts","../../src/findWorkspaceDir.ts","../../src/getPackageNameToDir.ts","../../src/SimpleHost.ts","../../src/CachingHost.ts","../../src/matchesAnyGlob.ts","../../src/nanosecondsToSanity.ts","../../src/Table.ts","../../src/AggregateTiming.ts","../../src/Timing.ts"],"sourcesContent":["/*!\n * Copyright 2019 Palantir Technologies, Inc.\n *\n * Licensed under the MIT license. See LICENSE file in the project root for details.\n *\n */\n\nimport { existsSync } from \"fs\";\nimport * as glob from \"glob\";\nimport * as path from \"node:path\";\nimport * as fs from \"node:fs\";\nimport { Host } from \"./Host.js\";\nimport { PackageJson } from \"./PackageJson.js\";\nimport readYamlFile from \"read-yaml-file\";\nimport { findPackages } from \"find-packages\";\n\nasync function findPNPMWorkspacePackages(workspaceRoot: string) {\n workspaceRoot = fs.realpathSync(workspaceRoot);\n const workspaceManifest = await readYamlFile.default<{ packages?: string[] }>(\n path.join(workspaceRoot, \"pnpm-workspace.yaml\")\n );\n\n return findPackages(workspaceRoot, {\n ignore: [\"**/node_modules/**\", \"**/bower_components/**\"],\n includeRoot: true,\n patterns: workspaceManifest.packages,\n });\n}\n\nexport async function getWorkspacePackageDirs(\n host: Pick<Host, \"readJson\" | \"exists\">,\n workspaceDir: string,\n resolvePaths: boolean = false\n) {\n const packageJson = host.readJson(path.join(workspaceDir, \"package.json\")) as PackageJson;\n\n const isPnpmWorkspace = host.exists(path.join(workspaceDir, \"pnpm-workspace.yaml\"));\n if (isPnpmWorkspace) {\n const workspacePackages = await findPNPMWorkspacePackages(workspaceDir);\n if (workspacePackages.length === 0) {\n throw new Error(\"Invalid workspaceDir: \" + workspaceDir);\n }\n return workspacePackages.map((project) => project.dir).filter((d) => d !== workspaceDir);\n }\n\n if (!packageJson.workspaces) {\n throw new Error(\"Unsupported! Monorepo is not backed by either pnpm nor yarn workspaces.\");\n }\n\n const ret: string[] = [];\n const packageGlobs = Array.isArray(packageJson.workspaces)\n ? packageJson.workspaces\n : packageJson.workspaces.packages || [];\n\n for (const pattern of packageGlobs) {\n for (const packagePath of glob.sync(pattern, { cwd: workspaceDir })) {\n const packageJsonPath = path.join(workspaceDir, packagePath, \"package.json\");\n\n if (existsSync(packageJsonPath)) {\n if (resolvePaths === true) {\n ret.push(path.resolve(path.join(workspaceDir, packagePath)));\n } else {\n ret.push(packagePath);\n }\n }\n }\n }\n\n return ret;\n}\n","/*!\n * Copyright 2019 Palantir Technologies, Inc.\n *\n * Licensed under the MIT license. See LICENSE file in the project root for details.\n *\n */\n\nimport { Host } from \"./Host.js\";\nexport function mutateJson<T extends object>(path: string, host: Host, mutator: (f: T) => T) {\n let file = host.readJson(path) as T;\n file = mutator(file);\n host.writeJson(path, file);\n}\n","/*!\n * Copyright 2019 Palantir Technologies, Inc.\n *\n * Licensed under the MIT license. See LICENSE file in the project root for details.\n *\n */\n\nimport * as path from \"path\";\nimport { Host } from \"./Host.js\";\nimport { PackageJson } from \"./PackageJson.js\";\nimport * as fs from \"fs\";\nimport { findUp } from \"find-up\";\n\nexport async function findPnpmWorkspaceDir(cwd: string) {\n const workspaceManifestLocation = await findUp(\"pnpm-workspace.yaml\", {\n cwd: await fs.promises.realpath(cwd),\n });\n return workspaceManifestLocation && path.dirname(workspaceManifestLocation);\n}\n\nexport async function findWorkspaceDir(\n host: Pick<Host, \"readJson\" | \"exists\">,\n dir: string\n): Promise<string | undefined> {\n // Defining workspaces in package.json is not necessary in PNPM\n const maybePnpmWorkspaceDir = await findPnpmWorkspaceDir(dir);\n if (maybePnpmWorkspaceDir != null) {\n return maybePnpmWorkspaceDir;\n }\n\n // We may not be in a repository that uses PNPM, look for workspaces in package.json\n const packagePath = path.join(dir, \"package.json\");\n if (host.exists(packagePath)) {\n const packageJson = host.readJson(packagePath) as PackageJson;\n if (packageJson.workspaces !== undefined) {\n return dir;\n }\n }\n\n const nextDir = path.normalize(path.join(dir, \"..\"));\n if (nextDir === dir) {\n return undefined;\n }\n\n return findWorkspaceDir(host, nextDir);\n}\n","/*!\n * Copyright 2019 Palantir Technologies, Inc.\n *\n * Licensed under the MIT license. See LICENSE file in the project root for details.\n *\n */\n\nimport { join as pathJoin } from \"path\";\nimport { getWorkspacePackageDirs } from \"./getWorkspacePackageDirs.js\";\nimport { Host } from \"./Host.js\";\nimport { PackageJson } from \"./PackageJson.js\";\n/**\n * returns a map of package names to their directories in the workspace.\n * if `resolvePaths` is true, the returned directory names are absolute paths\n * resolved against the `workspaceDir`.\n */\nexport async function getPackageNameToDir(\n host: Pick<Host, \"readJson\" | \"exists\">,\n workspaceDir: string,\n resolvePaths: boolean = false\n) {\n const ret = new Map<string, string>();\n\n const workspacePackages = await getWorkspacePackageDirs(host, workspaceDir, resolvePaths);\n for (const packageDir of workspacePackages) {\n const packagePath = pathJoin(packageDir, \"package.json\");\n const { name } = host.readJson(packagePath) as PackageJson;\n if (name === undefined) {\n throw new Error(`Package needs a name: ${packagePath}`);\n }\n ret.set(name, packageDir);\n }\n return ret;\n}\n","/*!\n * Copyright 2022 Palantir Technologies, Inc.\n *\n * Licensed under the MIT license. See LICENSE file in the project root for details.\n *\n */\n\nimport * as realFs from \"fs\";\n\nimport { Host } from \"./Host.js\";\nexport class SimpleHost implements Host {\n constructor(private fs: typeof realFs = realFs) {}\n mkdir(directoryPath: string, opts?: { recursive: boolean }): void {\n this.fs.mkdirSync(directoryPath, { recursive: opts?.recursive ?? false });\n }\n rmdir(directoryPath: string): void {\n this.fs.rmdirSync(directoryPath);\n }\n\n exists(path: string): boolean {\n return this.fs.existsSync(path);\n }\n\n writeFile(path: string, buffer: Buffer): void;\n writeFile(path: string, body: string, opts: { encoding: BufferEncoding }): void;\n writeFile(path: string, body: string | Buffer, opts?: { encoding: BufferEncoding }): void {\n if (opts) {\n this.fs.writeFileSync(path, body, { encoding: opts.encoding });\n } else {\n this.fs.writeFileSync(path, body);\n }\n }\n readFile(path: string, opts?: undefined): Buffer;\n readFile(path: string, opts: { encoding: BufferEncoding }): string;\n readFile(path: string, opts: { asJson: true }): object;\n readFile(path: string, opts?: { encoding?: BufferEncoding; asJson?: boolean }): string | object | Buffer {\n if (opts?.asJson) {\n return JSON.parse(this.fs.readFileSync(path, \"utf-8\"));\n }\n return this.fs.readFileSync(path, opts?.encoding);\n }\n deleteFile(path: string) {\n this.fs.unlinkSync(path);\n }\n readJson(filename: string) {\n const contents = this.fs.readFileSync(filename, \"utf-8\");\n return JSON.parse(contents);\n }\n writeJson(path: string, o: object): void {\n return this.fs.writeFileSync(path, JSON.stringify(o, undefined, 2) + \"\\n\");\n }\n flush() {\n // noop in the simple case\n return Promise.resolve();\n }\n}\n","/*!\n * Copyright 2022 Palantir Technologies, Inc.\n *\n * Licensed under the MIT license. See LICENSE file in the project root for details.\n *\n */\n\nimport * as realFs from \"node:fs\";\nimport { Host } from \"./Host.js\";\nimport * as path from \"node:path\";\n\nfunction assertNoTombstone(node: Node): asserts node is Node & { tombstone?: false } {\n if (node.tombstone) {\n throw new Error(`Unexpected tombstone ${JSON.stringify(node)}`);\n }\n}\n\nfunction assertNotType<N extends Node, T extends Node[\"type\"]>(\n node: N,\n type: T\n): asserts node is N & { type: Exclude<N[\"type\"], T> } {\n if (node.type === type) {\n throw new Error(`Unexpected node type ${JSON.stringify(node)}`);\n }\n}\n\nfunction assertType<N extends Node, T extends Node[\"type\"]>(node: N, type: T): asserts node is N & { type: T } {\n if (node.type !== type) {\n throw new Error(`Unexpected node type ${JSON.stringify(node)}`);\n }\n}\n\nfunction assertExists<T extends Node>(node: T | undefined): asserts node is T {\n if (!node) {\n throw new Error(`Expected node to exist`);\n }\n}\n\nfunction assertHasParent(node: Node) {\n if (!node.parent) {\n throw new Error(\"Expected node to have a parent directory\");\n }\n}\n\ninterface BaseNode<T extends string> {\n type: T;\n fullPath: string;\n tombstone?: boolean;\n parent?: DirNode | DirStubNode;\n needsFlush: boolean;\n}\ninterface DirNode extends BaseNode<\"dir\"> {\n stub?: false;\n tombstone?: false;\n dir: Map<string, Node>;\n}\n\ninterface DirStubNode extends BaseNode<\"dir\"> {\n stub: true;\n tombstone?: false;\n dir: Map<string, Node>;\n}\n\ninterface DirTombstoneNode extends BaseNode<\"dir\"> {\n stub?: false;\n tombstone: true;\n dir: Map<string, Node>;\n}\n\ninterface FileNode extends BaseNode<\"file\"> {\n stub?: false;\n tombstone?: false;\n file: Buffer;\n}\n\ninterface FileTombstoneNode extends BaseNode<\"file\"> {\n stub?: false;\n tombstone: true;\n file?: never;\n}\n\ninterface FileStubNode extends BaseNode<\"file\"> {\n stub: true;\n tombstone?: false;\n file?: never;\n}\n\ninterface SymlinkNode extends BaseNode<\"symlink\"> {\n tombstone?: false;\n symlink: string;\n}\n\ntype Node = DirNode | FileNode | SymlinkNode | DirTombstoneNode | FileTombstoneNode | DirStubNode | FileStubNode;\n\nexport class CachingHost implements Host {\n // We need many trees because of windows, key is the `root`\n #trees = new Map<string, DirNode | DirStubNode>();\n\n constructor(\n private fs: Pick<\n typeof realFs,\n | \"existsSync\"\n | \"lstatSync\"\n | \"mkdirSync\"\n | \"promises\"\n | \"readdirSync\"\n | \"readFileSync\"\n | \"readlinkSync\"\n | \"realpathSync\"\n | \"rmdirSync\"\n | \"statSync\"\n | \"unlinkSync\"\n | \"writeFileSync\"\n > = realFs\n ) {}\n\n #replaceNode(\n node: FileNode | FileStubNode | SymlinkNode,\n newNode: Omit<FileTombstoneNode, \"fullPath\" | \"parent\">\n ): FileTombstoneNode;\n #replaceNode(\n node: FileNode | FileStubNode | FileTombstoneNode,\n newNode: Omit<FileNode, \"fullPath\" | \"parent\">\n ): FileNode;\n #replaceNode(\n node: DirTombstoneNode | DirStubNode,\n newNode: Omit<DirNode, \"fullPath\" | \"parent\" | \"dir\">\n ): DirStubNode;\n #replaceNode(node: DirNode, newNode: Omit<DirTombstoneNode, \"fullPath\" | \"parent\" | \"dir\">): DirTombstoneNode;\n #replaceNode(node: Node, partialNewNode: Omit<Node, \"fullPath\" | \"parent\">): Node {\n if (!node.parent) throw new Error(\"Cannot replace root node\");\n const newNode: Node = {\n ...partialNewNode,\n fullPath: node.fullPath,\n parent: node.parent,\n dir: (node as DirNode).dir,\n } as Node;\n node.parent.dir.set(path.basename(node.fullPath), newNode);\n return newNode;\n }\n\n #unstubDirectory(node: DirNode | DirStubNode): asserts node is DirNode {\n // So the rules for our stub dirs. We assume the things in the map are authority but\n // for things not in the map, the real FS is the authority\n for (const child of this.fs.readdirSync(node.fullPath)) {\n // just makign this call will populate the structure but its a little expensive.\n // TODO: make an unknown stub\n this.#getNode(path.join(node.fullPath, child));\n }\n node.stub = false;\n }\n\n /**\n * Assumes no parent -> path is root\n *\n * Throws if the path doesnt exist!\n */\n #stubify(filePath: string, parent: undefined): DirStubNode;\n #stubify(filePath: string, parent: DirNode | DirStubNode | undefined): DirStubNode | SymlinkNode | FileStubNode;\n #stubify(\n filePath: string,\n parent: DirNode | DirStubNode | undefined\n ): typeof parent extends undefined ? DirNode | DirStubNode : DirNode | DirStubNode | SymlinkNode | FileStubNode {\n const canonicalPath = path.resolve(filePath);\n\n if (!parent && canonicalPath !== path.parse(canonicalPath).root) {\n throw new Error(`parent can only be null if path is root. Instead got: ${canonicalPath}`);\n }\n const stat = this.fs.lstatSync(canonicalPath); // may throw\n\n let node: SymlinkNode | FileStubNode | DirStubNode;\n\n if (stat.isDirectory()) {\n node = {\n fullPath: canonicalPath,\n type: \"dir\",\n stub: true,\n dir: new Map(),\n parent,\n needsFlush: false,\n };\n } else if (stat.isSymbolicLink()) {\n node = {\n fullPath: canonicalPath,\n type: \"symlink\",\n symlink: this.fs.readlinkSync(canonicalPath),\n parent,\n needsFlush: false,\n };\n } else if (stat.isFile()) {\n node = {\n fullPath: canonicalPath,\n type: \"file\",\n stub: true,\n parent,\n needsFlush: false,\n };\n } else {\n throw new Error(`what is not a file nor symlink nor directory? nothing we care about: ${canonicalPath}`);\n }\n\n if (!parent && node.type === \"dir\") {\n this.#trees.set(canonicalPath, node);\n return node;\n } else if (parent) {\n parent.dir.set(path.basename(canonicalPath), node);\n } else {\n throw new Error(`root can only be a dir, got ${JSON.stringify(node)} for path: ${canonicalPath}`);\n }\n return node;\n }\n\n /**\n * Note: may return the node itself!\n * You should check the `fullPath` of the result.\n */\n #getNearestAncestorNode(filePath: string) {\n const canonicalPath = path.resolve(filePath);\n const { root } = path.parse(canonicalPath);\n const parts = [];\n\n let maybePath = canonicalPath;\n while (maybePath !== root) {\n parts.unshift(path.basename(maybePath));\n maybePath = path.dirname(maybePath);\n }\n\n let curPath = root;\n let curNode: Node = this.#trees.get(root) ?? this.#stubify(curPath, undefined); // its okay to throw if there is no root\n try {\n for (const part of parts) {\n assertNoTombstone(curNode);\n assertNotType(curNode, \"file\");\n if (curNode.type === \"symlink\") {\n const linkedNode = this.#getNodeResolvingSymlinks(path.resolve(path.dirname(curPath), curNode.symlink));\n assertExists(linkedNode);\n assertNoTombstone(linkedNode);\n assertType(linkedNode, \"dir\");\n curNode = linkedNode;\n }\n assertType(curNode, \"dir\");\n assertNoTombstone(curNode);\n curNode = curNode.dir.get(part) ?? this.#stubify(path.join(curNode.fullPath, part), curNode);\n curPath = path.join(curPath, part);\n }\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n } catch (e) {\n // This error is expected when things done exist.\n // console.log(`Got EXPECTED error when trying to getNearestAncestorNode(${canonicalPath}): `, (e as any).message);\n }\n return { pathWithSymlinks: curPath, node: curNode };\n }\n\n #getNode(filePath: string) {\n const canonicalPath = path.resolve(filePath);\n const { pathWithSymlinks, node } = this.#getNearestAncestorNode(canonicalPath);\n if (pathWithSymlinks === canonicalPath) {\n return node;\n }\n return undefined;\n }\n\n #getNodeResolvingSymlinks(filePath: string, follows: number = 100): Exclude<Node, SymlinkNode> | undefined {\n const node = this.#getNode(filePath); // canonicalizes for us\n if (!node || node.type !== \"symlink\") return node;\n // this is a really poor mans way of doing this. but who has 100's of symlinks hanging around?\n if (follows === 0) throw new Error(\"Exhausted symlink follows\");\n\n return this.#getNodeResolvingSymlinks(node.symlink, follows--);\n }\n\n mkdir(filePath: string, opts: { recursive: boolean } = { recursive: false }): void {\n const canonicalPath = path.resolve(filePath);\n const { node, pathWithSymlinks } = this.#getNearestAncestorNode(canonicalPath);\n if (filePath === pathWithSymlinks) {\n assertType(node, \"dir\");\n assertHasParent(node);\n if (!node.tombstone) return; // already done\n } else if (path.dirname(filePath) === pathWithSymlinks) {\n assertType(node, \"dir\");\n assertNoTombstone(node);\n node.dir.set(path.basename(filePath), {\n type: \"dir\",\n fullPath: filePath,\n parent: node,\n dir: new Map(),\n needsFlush: true,\n });\n return;\n }\n\n if (!opts.recursive && path.dirname(canonicalPath) !== pathWithSymlinks) {\n throw new Error(\"no such file or directory\");\n }\n\n const rootPath = pathWithSymlinks;\n let maybePath = canonicalPath;\n const toMake: string[] = [];\n while (maybePath !== rootPath) {\n toMake.unshift(path.resolve(node.fullPath, path.relative(rootPath, maybePath)));\n maybePath = path.dirname(maybePath);\n }\n\n for (const dirToMake of toMake) {\n this.mkdir(dirToMake);\n }\n }\n\n rmdir(directoryPath: string): void {\n const node = this.#getNode(directoryPath);\n if (!node || node.tombstone) {\n return; // this isnt how FS usually work but its what we are doing\n }\n assertType(node, \"dir\");\n if (node.stub) {\n this.#unstubDirectory(node);\n }\n\n if (node.dir.size === 0) {\n this.#replaceNode(node, {\n type: \"dir\",\n tombstone: true,\n needsFlush: true,\n });\n } else {\n throw new Error(\"directory not empty\");\n }\n }\n\n exists(filePath: string): boolean {\n const node = this.#getNode(filePath); // canonicalizes for us\n return !!node && !node.tombstone;\n }\n\n readFile(filePath: string, opts?: undefined): Buffer;\n readFile(filePath: string, opts: { encoding: BufferEncoding }): string;\n readFile(filePath: string, opts: { asJson: true }): object;\n readFile(\n filePath: string,\n opts: undefined | { encoding: BufferEncoding; asJson?: false } | { encoding?: never; asJson: true }\n ) {\n let node = this.#getNodeResolvingSymlinks(filePath); // canonicalizes for us\n\n if (!node) {\n return undefined;\n }\n assertNotType(node, \"dir\");\n assertNoTombstone(node);\n\n if (node.stub) {\n node = this.#replaceNode(node, {\n type: \"file\",\n file: this.fs.readFileSync(filePath),\n needsFlush: false,\n });\n }\n\n if (!opts) {\n return Buffer.from(node.file);\n } else if (opts.asJson) {\n return JSON.parse(node.file.toString(\"utf-8\"));\n } else {\n return node.file.toString(opts.encoding);\n }\n }\n\n writeFile(filePath: string, buffer: Buffer): void;\n writeFile(filePath: string, body: string, opts: { encoding: BufferEncoding }): void;\n writeFile(filePath: string, body: string, opts: { encoding: BufferEncoding }): void;\n writeFile(filePath: string, body: string | Buffer, opts?: { encoding: BufferEncoding }) {\n const fileContentsAsBuffer = typeof body === \"string\" ? Buffer.from(body, opts?.encoding) : Buffer.from(body);\n\n const canonicalPath = path.resolve(filePath);\n const existingNode = this.#getNodeResolvingSymlinks(canonicalPath);\n if (existingNode) {\n if (existingNode.type === \"dir\") {\n throw new Error(\"cant write file to a dir\");\n }\n this.#replaceNode(existingNode, {\n file: fileContentsAsBuffer,\n type: \"file\",\n needsFlush: true,\n });\n return;\n }\n\n const maybeDirNode = this.#getNodeResolvingSymlinks(path.dirname(canonicalPath));\n assertExists(maybeDirNode);\n assertType(maybeDirNode, \"dir\");\n assertNoTombstone(maybeDirNode);\n\n maybeDirNode.dir.set(path.basename(canonicalPath), {\n type: \"file\",\n fullPath: canonicalPath,\n parent: maybeDirNode,\n file: fileContentsAsBuffer,\n needsFlush: true,\n });\n }\n\n deleteFile(filePath: string) {\n const canonicalPath = path.resolve(filePath);\n const node = this.#getNode(canonicalPath);\n if (!node || (node.type === \"file\" && node.tombstone === true)) return;\n assertNotType(node, \"dir\");\n this.#replaceNode(node, {\n type: \"file\",\n tombstone: true,\n needsFlush: true,\n });\n }\n\n readJson(filePath: string) {\n return this.readFile(filePath, { asJson: true });\n }\n\n writeJson(filePath: string, o: object): void {\n return this.writeFile(filePath, JSON.stringify(o, undefined, 2) + \"\\n\", {\n encoding: \"utf-8\",\n });\n }\n\n async #flushFileNode(node: FileNode | FileStubNode | FileTombstoneNode): Promise<unknown> {\n // FIXME all tombstones need a flush, so we can get rid of needsFlush for them\n if (node.tombstone) {\n try {\n await this.fs.promises.access(node.fullPath);\n return this.fs.promises.unlink(node.fullPath);\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n } catch (e) {\n // should only throw if file doesnt exist which is no op\n return;\n }\n } else if (node.stub === true || node.needsFlush === false) {\n return;\n } else {\n // we dont do things with file stubs\n return this.fs.promises.writeFile(node.fullPath, node.file);\n }\n }\n\n async #flushSymlinkNode(node: SymlinkNode) {\n if (!node.needsFlush) return;\n try {\n const linkValue = await this.fs.promises.readlink(node.fullPath);\n if (linkValue === node.symlink) {\n return;\n }\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n } catch (e) {\n // expected when the link doesnt exist\n }\n return this.fs.promises.symlink(node.symlink, node.fullPath);\n }\n\n async #flushDirNode(node: DirNode | DirStubNode | DirTombstoneNode): Promise<unknown> {\n if (!node.tombstone && node.needsFlush) {\n try {\n await this.fs.promises.access(node.fullPath); // throws if the file doesnt exist\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n } catch (e) {\n await this.fs.promises.mkdir(node.fullPath); // throws if it does :(\n }\n }\n\n const promises: Promise<unknown>[] = [];\n for (const child of node.dir.values()) {\n if (node.tombstone && !child.tombstone) {\n throw new Error(\"Unexpected failure during sanity check. A non-deleted child is on a deleted dir\");\n }\n if (child.type === \"dir\") {\n promises.push(this.#flushDirNode(child));\n } else if (child.type === \"file\") {\n promises.push(this.#flushFileNode(child));\n } else if (child.type === \"symlink\") {\n promises.push(this.#flushSymlinkNode(child));\n } else {\n throw new Error(\"should never happen\");\n }\n }\n await Promise.all(promises);\n if (node.tombstone) {\n return this.fs.promises.rmdir(node.fullPath);\n }\n return;\n }\n\n flush() {\n const promises: Promise<unknown>[] = [];\n for (const rootNode of this.#trees.values()) {\n promises.push(this.#flushDirNode(rootNode));\n }\n return Promise.all(promises);\n }\n}\n","/*!\n * Copyright 2022 Palantir Technologies, Inc.\n *\n * Licensed under the MIT license. See LICENSE file in the project root for details.\n *\n */\n\nimport micromatch from \"micromatch\";\nimport { nanosecondsToSanity } from \"./nanosecondsToSanity.js\";\nimport { Table } from \"./Table.js\";\n// This file requires a LOT of caching to be performant. We have three layers to avoid work.\n\n/**\n * Multimap cache of whether a needle was found in the glob haystack. Short circuits many\n * individual checks against the globs.\n */\nconst cache = new Map</* haystack */ readonly string[], Map</* needle */ string, /* result */ boolean>>();\n\n/**\n * Multimap cache of whether a needle matches a glob. Allows us to avoid regexp's.\n */\nconst singleMatcherCache = new Map</* glob */ string, Map</* needle */ string, /* result*/ boolean>>();\n\n/**\n * Cache of glob to regular expression. Compiling the regular expression is expensive.\n */\nconst compiledGlobCache = new Map</* glob */ string, RegExp>();\n\nlet haystackMiss = 0;\nlet haystackHit = 0;\n\nlet matchTime = BigInt(0);\n\nlet singleMatcherHits = 0;\nlet singleMatcherMisses = 0;\nlet singleMatcherSaves = 0; // hits + hits you would have had if the haystack didn't save you\n\ninterface MatchesAnyGlob {\n (needle: string, haystack: readonly string[]): boolean | undefined;\n printStats?: () => void;\n}\nexport const matchesAnyGlob: MatchesAnyGlob = function matchesAnyGlobFunc(needle: string, haystack: readonly string[]) {\n matchTime -= process.hrtime.bigint();\n\n let cacheForHaystack = cache.get(haystack);\n if (cacheForHaystack === undefined) {\n cacheForHaystack = new Map<string, boolean>();\n cache.set(haystack, cacheForHaystack);\n }\n\n let result = cacheForHaystack!.get(needle);\n if (result === undefined) {\n haystackMiss++;\n result = false;\n for (const pattern of haystack) {\n // result = needleInPattern(needle, pattern); // commented out as a reminder to update both\n // BEGIN INLINE of needleInPattern\n let patternCache = singleMatcherCache.get(pattern);\n if (patternCache === undefined) {\n patternCache = new Map<string, boolean>();\n singleMatcherCache.set(pattern, patternCache);\n }\n\n // N.B. true/false/undefined\n result = patternCache.get(needle); // only thing different from the inline is we need to reuse `result`\n if (result === undefined) {\n let regexp: RegExp | undefined | false = compiledGlobCache.get(pattern);\n if (regexp === undefined) {\n regexp = micromatch.makeRe(pattern);\n // if (regexp === false) throw new Error(\"bad glob\");\n compiledGlobCache.set(pattern, regexp);\n }\n\n singleMatcherMisses++;\n result = regexp.test(needle);\n patternCache.set(needle, result);\n } else {\n singleMatcherHits++;\n singleMatcherSaves++;\n }\n // END INLINE of needleInPattern\n if (result) break;\n }\n cacheForHaystack!.set(needle, result);\n } else {\n singleMatcherSaves += haystack.length;\n haystackHit++;\n }\n matchTime += process.hrtime.bigint();\n return result;\n};\n\nmatchesAnyGlob.printStats = () => {\n const table = new Table<[string, string]>({\n title: \"matchesAnyGlob stats\",\n showHeader: true,\n showFooter: false,\n columns: [\n { header: \"Stat\", type: \"string\" },\n { header: \"Value\", type: \"string\" },\n ],\n });\n table.addRow(\"Haystack Miss\", \"\" + haystackMiss);\n table.addRow(\"Haystack Hit\", \"\" + haystackHit);\n table.addRow(\"Single Glob Hits\", \"\" + singleMatcherHits);\n table.addRow(\"Single Glob Misses\", \"\" + singleMatcherMisses);\n table.addRow(\"Single Glob Saves\", \"\" + singleMatcherSaves);\n table.addRow(\"Total Time\", nanosecondsToSanity(matchTime, 6));\n\n table.print();\n};\n\n/**\n * @deprecated Don't use this directly. We manually inline it above\n */\nexport function needleInPattern(needle: string, pattern: string) {\n // benchmark says the uncommented version is best\n // https://jsben.ch/Y8TWs\n\n // option 2\n let patternCache = singleMatcherCache.get(pattern);\n if (patternCache === undefined) {\n patternCache = new Map<string, boolean>();\n singleMatcherCache.set(pattern, patternCache);\n }\n\n // N.B. true/false/undefined\n let result = patternCache.get(needle);\n if (result === undefined) {\n let regexp: RegExp | undefined | false = compiledGlobCache.get(pattern);\n if (regexp === undefined) {\n regexp = micromatch.makeRe(pattern);\n // if (regexp === false) throw new Error(\"bad glob\");\n compiledGlobCache.set(pattern, regexp);\n }\n\n singleMatcherMisses++;\n result = regexp.test(needle);\n patternCache.set(needle, result);\n } else {\n singleMatcherHits++;\n singleMatcherSaves++;\n }\n\n return result;\n}\n","/*!\n * Copyright 2022 Palantir Technologies, Inc.\n *\n * Licensed under the MIT license. See LICENSE file in the project root for details.\n *\n */\n\nexport function nanosecondsToSanity(n: bigint, precision: number = 9) {\n return n / BigInt(1000000000) + \".\" + (\"\" + (n % BigInt(1000000000))).padStart(9, \"0\").substring(0, precision) + \"s\";\n}\n","/*!\n * Copyright 2022 Palantir Technologies, Inc.\n *\n * Licensed under the MIT license. See LICENSE file in the project root for details.\n *\n */\n// tslint:disable:no-console\nimport { nanosecondsToSanity } from \"./nanosecondsToSanity.js\";\ntype HeaderFooterHelper<HB, FB, H, F> = (HB extends true ? { header: H } : { header?: H }) &\n (FB extends true ? { footer: F } : { footer?: F });\n\ntype WithAlignemnt = { alignment?: \"right\" | \"left\" };\ntype BaseCellConfig = WithAlignemnt & { type: \"bigint\" | \"string\" };\n\ntype BaseBigIntCellConfig = {\n type: \"bigint\";\n renderAs?: \"nanoseconds\";\n precision?: number;\n} & WithAlignemnt;\ntype BaseStringCellConfig = { type: \"string\" } & WithAlignemnt;\n\ntype BigIntColumnConfig<H, F> = WithAlignemnt &\n BaseBigIntCellConfig &\n HeaderFooterHelper<H, F, string, AggregateFooterConfig | StaticFooterConfig>;\n\ntype StringColumnConfig<H, F> = WithAlignemnt &\n BaseStringCellConfig &\n HeaderFooterHelper<H, F, string, StaticFooterConfig>;\n\ntype AggregateFooterConfig = {\n aggregate: \"sum\" | \"average\";\n renderAs?: \"nanoseconds\";\n precision?: number;\n} & WithAlignemnt;\n\ntype StaticFooterConfig = StrictStaticFooterConfig | string;\ntype StrictStaticFooterConfig = {\n aggregate: \"static\";\n value: string;\n} & WithAlignemnt;\n\ntype AnyStrictFooterConfig = AggregateFooterConfig | StrictStaticFooterConfig;\n\ntype TableConfig<T extends any[], H extends boolean, F extends boolean> = {\n sortColumn?: number;\n padding?: number;\n showHeader: H;\n showFooter: F;\n columns: {\n [K in keyof T]: T[K] extends bigint ? BigIntColumnConfig<H, F> : StringColumnConfig<H, F>;\n };\n title: string;\n};\n\ntype InternalTableConfig = {\n padding: number;\n showHeader: boolean;\n showFooter: boolean;\n sortColumn?: number;\n columns: Array<BigIntColumnConfig<any, any> | StringColumnConfig<any, any>>;\n title: string;\n};\n\nexport class Table<T extends any[]> {\n #rows: T[] = [];\n #config: InternalTableConfig;\n #columnWidths: number[] = [];\n #footer: Array<bigint | string> = [];\n #footerRowConfig?: Array<Required<BaseCellConfig> & AnyStrictFooterConfig>;\n #totalWidth = 0;\n\n constructor(\n config:\n | TableConfig<T, true, true>\n | TableConfig<T, true, false>\n | TableConfig<T, false, true>\n | TableConfig<T, false, false>\n ) {\n this.#config = {\n padding: 2,\n ...config,\n };\n this.#columnWidths.fill(0, 0, config.columns.length);\n\n if (config.showFooter) {\n this.#footerRowConfig = [];\n for (const columnConfig of config.columns) {\n if (columnConfig.footer === undefined) {\n throw new Error(\"Must specify footer fields when showFooter is true\");\n } else if (typeof columnConfig.footer === \"string\") {\n this.#footerRowConfig.push({\n type: \"string\",\n alignment: \"left\",\n aggregate: \"static\",\n value: columnConfig.footer,\n });\n } else if (\"value\" in columnConfig.footer) {\n this.#footerRowConfig.push({\n type: \"string\",\n alignment: \"left\",\n ...columnConfig.footer,\n });\n } else if (\"aggregate\" in columnConfig.footer) {\n if (columnConfig.type !== \"bigint\") throw new Error(\"expecting bigint for aggregate\");\n this.#footerRowConfig.push({\n type: columnConfig.type,\n renderAs: columnConfig.renderAs,\n precision: columnConfig.precision,\n alignment: \"right\",\n ...columnConfig.footer,\n });\n }\n }\n }\n }\n\n addRow(...data: T) {\n // TODO: maybe clone the data\n this.#rows.push(data);\n }\n\n #sumColumn(c: number) {\n let total = BigInt(0);\n for (const row of this.#rows) {\n total += row[c];\n }\n return total;\n }\n\n #updateFooterRow() {\n const footerRowConfig = this.#footerRowConfig;\n if (footerRowConfig) {\n for (let c = 0; c < footerRowConfig.length; c++) {\n const footerColConfig = footerRowConfig[c];\n\n switch (footerColConfig.aggregate) {\n case \"sum\":\n this.#footer[c] = this.#sumColumn(c);\n break;\n case \"average\":\n this.#footer[c] = this.#sumColumn(c) / BigInt(this.#rows.length);\n break;\n case \"static\":\n this.#footer[c] = footerColConfig.value;\n break;\n }\n }\n }\n }\n\n #calculateColumnWidths() {\n this.#columnWidths.fill(0, 0, this.#config.columns.length);\n\n for (let c = 0; c < this.#config.columns.length; c++) {\n const colConfig = this.#config.columns[c];\n this.#columnWidths[c] = Math.max(\n (this.#config.columns[c].header ?? \"\").length,\n ...this.#rows.map((a) => this.#getCellValueAsString(a[c], colConfig).length),\n this.#footer && this.#footerRowConfig\n ? this.#getCellValueAsString(this.#footer?.[c] ?? \"\", this.#footerRowConfig[c]).length\n : 0\n );\n }\n\n this.#totalWidth = 0;\n for (const colWidth of this.#columnWidths) {\n this.#totalWidth += colWidth;\n }\n this.#totalWidth += (this.#columnWidths.length - 1) * this.#config.padding;\n }\n\n #printSeparator(fillString: string) {\n const paddingString = \"\".padStart(this.#config.padding, \" \");\n\n let hr2 = \"\";\n\n // tslint:disable-next-line: prefer-for-of\n for (let c = 0; c < this.#columnWidths.length; c++) {\n hr2 += \"\".padStart(this.#columnWidths[c], fillString) + paddingString;\n }\n hr2 = hr2.trimRight();\n console.log(hr2);\n }\n\n #printHeaderRow() {\n if (this.#config.showHeader) {\n const colConfigs = this.#config.columns;\n const paddingString = \"\".padStart(this.#config.padding, \" \");\n\n let hr = \"\";\n for (let c = 0; c < colConfigs.length; c++) {\n const heading = colConfigs[c].header ?? \"\";\n hr += heading.padEnd(this.#columnWidths[c], \" \") + paddingString;\n }\n hr = hr.trimRight();\n console.log(hr);\n\n this.#printSeparator(\"-\");\n }\n }\n\n #printFooterRow() {\n const footerRow = this.#footer;\n if (footerRow) {\n this.#printSeparator(\"=\");\n\n const paddingString = \"\".padStart(this.#config.padding, \" \");\n\n let hr = \"\";\n for (let c = 0; c < footerRow.length; c++) {\n hr += this.#getCellValueAligned(footerRow[c], this.#footerRowConfig![c], c) + paddingString; // .padEnd(this.#columnWidths[c], \" \") + paddingString;\n }\n hr = hr.trimRight();\n console.log(hr);\n }\n }\n\n print() {\n // let data = [...this.#rows];\n if (this.#config.sortColumn !== undefined) {\n // todo\n }\n\n this.#updateFooterRow();\n this.#calculateColumnWidths();\n\n console.log();\n console.log(`${this.#config.title}`);\n console.log(\"\".padStart(this.#totalWidth, \"=\"));\n\n const paddingString = \"\".padStart(this.#config.padding, \" \");\n if (this.#config.showHeader) {\n this.#printHeaderRow();\n }\n\n for (let r = 0; r < this.#rows.length; r++) {\n let rowText = \"\";\n for (let c = 0; c < this.#config.columns.length; c++) {\n rowText += this.getEntryAsStringAligned(c, r) + paddingString;\n }\n rowText.trim();\n console.log(rowText);\n }\n\n if (this.#config.showFooter) this.#printFooterRow();\n console.log();\n }\n\n #getCellValueAsString(value: bigint | string, config: BaseBigIntCellConfig | BaseStringCellConfig) {\n if (config.type === \"bigint\" && config.renderAs === \"nanoseconds\") {\n return nanosecondsToSanity(value as bigint, config.precision ?? 9);\n } else {\n return \"\" + value;\n }\n }\n\n #getCellValueAligned(value: bigint | string, config: BaseBigIntCellConfig | BaseStringCellConfig, column: number) {\n let result: string;\n if (config.type === \"bigint\" && config.renderAs === \"nanoseconds\") {\n result = nanosecondsToSanity(value as bigint, config.precision ?? 9);\n } else {\n result = \"\" + value;\n }\n\n if (config.alignment === \"left\") {\n return result.padEnd(this.#columnWidths[column]);\n } else {\n return result.padStart(this.#columnWidths[column]);\n }\n }\n\n getEntryAsString(colNum: number, rowNum: number) {\n const config = this.#config.columns[colNum];\n\n if (config.type === \"bigint\" && config.renderAs === \"nanoseconds\") {\n return nanosecondsToSanity(this.#rows[rowNum][colNum], config.precision ?? 9);\n } else {\n return \"\" + this.#rows[rowNum][colNum];\n }\n }\n\n getEntryAsStringAligned(colNum: number, rowNum: number) {\n const config = this.#config.columns[colNum];\n\n let result: string;\n if (config.type === \"bigint\" && config.renderAs === \"nanoseconds\") {\n result = nanosecondsToSanity(this.#rows[rowNum][colNum], config.precision ?? 9);\n } else {\n result = \"\" + this.#rows[rowNum][colNum];\n }\n\n if (config.alignment === \"left\") {\n return result.padEnd(this.#columnWidths[colNum]);\n } else {\n return result.padStart(this.#columnWidths[colNum]);\n }\n }\n\n getColumnWidth(colNum: number, config: BigIntColumnConfig<boolean, boolean> | StringColumnConfig<boolean, boolean>) {\n let maxWidth = Math.max(\n (config.header ?? \"\").length,\n this.#footer && this.#footerRowConfig\n ? this.#getCellValueAsString(this.#footer[colNum], this.#footerRowConfig[colNum]).length\n : 0\n );\n\n for (let r = 0; r < this.#rows.length; r++) {\n maxWidth = Math.max(maxWidth, this.getEntryAsString(colNum, r).length);\n // if (config.type == \"bigint\" && config.renderAs === \"nanoseconds\") {\n // maxWidth = Math.max(maxWidth, Number(row[colNum] / BigInt(1000000000)) + 10); // 1 for period, 9 for digits\n // } else if (config.type == \"bigint\" || config.type == \"string\") {\n // maxWidth = Math.max(maxWidth, (\"\" + row[colNum]).length);\n // }\n }\n\n return maxWidth;\n }\n}\n","/*!\n * Copyright 2022 Palantir Technologies, Inc.\n *\n * Licensed under the MIT license. See LICENSE file in the project root for details.\n *\n */\n// tslint:disable:no-console\n\nimport { Table } from \"./Table.js\";\nexport class AggregateTiming {\n #data = new Map<string, { count: number; total: bigint }>();\n #last: { count: number; total: bigint } | undefined;\n\n constructor(private title: string) {}\n\n public start(name: string) {\n const time = process.hrtime.bigint();\n if (this.#last) {\n this.#last.total += time;\n }\n\n let data = this.#data.get(name);\n if (data === undefined) {\n data = { count: 1, total: -time };\n this.#data.set(name, data);\n } else {\n data.total -= time;\n data.count++;\n }\n this.#last = data;\n }\n\n public stop() {\n const time = process.hrtime.bigint();\n if (this.#last) {\n this.#last.total += time;\n this.#last = undefined;\n }\n }\n\n public printResults() {\n const table = new Table<[bigint, string, bigint, bigint]>({\n sortColumn: -1,\n showFooter: true,\n showHeader: true,\n title: this.title,\n columns: [\n {\n header: \"Duration\",\n type: \"bigint\",\n renderAs: \"nanoseconds\",\n footer: { aggregate: \"sum\" },\n },\n { header: \"Task\", type: \"string\", alignment: \"left\", footer: \"TOTAL\" },\n { header: \"Count\", type: \"bigint\", footer: { aggregate: \"sum\" } },\n { header: \"Avg\", type: \"bigint\", footer: { aggregate: \"average\" } },\n ],\n });\n\n for (const [name, value] of this.#data) {\n table.addRow(\n value.total,\n name,\n BigInt(value.count), // fixme this can be a number later\n value.total / BigInt(value.count)\n );\n }\n table.print();\n }\n}\n","/*!\n * Copyright 2022 Palantir Technologies, Inc.\n *\n * Licensed under the MIT license. See LICENSE file in the project root for details.\n *\n */\n// tslint:disable:no-console\nimport { Table } from \"./Table.js\";\nexport class Timing {\n #starts: Array<{ name?: string; start: bigint }> = [];\n constructor(private title: string) {\n this.stop(); // make sure we have starting point\n }\n\n public start(name: string) {\n this.#starts.push({ name, start: process.hrtime.bigint() });\n }\n\n public stop() {\n this.#starts.push({ start: process.hrtime.bigint() });\n }\n\n public printResults() {\n const table = new Table<[bigint, string]>({\n sortColumn: -1,\n showFooter: true,\n showHeader: true,\n title: this.title,\n columns: [\n {\n header: \"Duration\",\n type: \"bigint\",\n renderAs: \"nanoseconds\",\n precision: 4,\n footer: { aggregate: \"sum\" },\n },\n { header: \"Task\", type: \"string\", footer: \"TOTAL\" },\n ],\n });\n\n this.stop(); // be sure we stopped the last one\n\n let cur: { name?: string; start: bigint } = this.#starts[0];\n for (const entry of this.#starts) {\n if (cur.name) {\n const span = entry.start - cur.start;\n table.addRow(span, cur.name);\n }\n cur = entry;\n }\n\n table.print();\n }\n}\n"],"mappings":";AAOA,SAAS,kBAAkB;AAC3B,YAAY,UAAU;AACtB,YAAY,UAAU;AACtB,YAAY,QAAQ;AAGpB,OAAO,kBAAkB;AACzB,SAAS,oBAAoB;AAE7B,eAAe,0BAA0B,eAAuB;AAC9D,kBAAmB,gBAAa,aAAa;AAC7C,QAAM,oBAAoB,MAAM,aAAa;AAAA,IACtC,UAAK,eAAe,qBAAqB;AAAA,EAChD;AAEA,SAAO,aAAa,eAAe;AAAA,IACjC,QAAQ,CAAC,sBAAsB,wBAAwB;AAAA,IACvD,aAAa;AAAA,IACb,UAAU,kBAAkB;AAAA,EAC9B,CAAC;AACH;AAEA,eAAsB,wBACpB,MACA,cACA,eAAwB,OACxB;AACA,QAAM,cAAc,KAAK,SAAc,UAAK,cAAc,cAAc,CAAC;AAEzE,QAAM,kBAAkB,KAAK,OAAY,UAAK,cAAc,qBAAqB,CAAC;AAClF,MAAI,iBAAiB;AACnB,UAAM,oBAAoB,MAAM,0BAA0B,YAAY;AACtE,QAAI,kBAAkB,WAAW,GAAG;AAClC,YAAM,IAAI,MAAM,2BAA2B,YAAY;AAAA,IACzD;AACA,WAAO,kBAAkB,IAAI,CAAC,YAAY,QAAQ,GAAG,EAAE,OAAO,CAAC,MAAM,MAAM,YAAY;AAAA,EACzF;AAEA,MAAI,CAAC,YAAY,YAAY;AAC3B,UAAM,IAAI,MAAM,yEAAyE;AAAA,EAC3F;AAEA,QAAM,MAAgB,CAAC;AACvB,QAAM,eAAe,MAAM,QAAQ,YAAY,UAAU,IACrD,YAAY,aACZ,YAAY,WAAW,YAAY,CAAC;AAExC,aAAW,WAAW,cAAc;AAClC,eAAW,eAAoB,UAAK,SAAS,EAAE,KAAK,aAAa,CAAC,GAAG;AACnE,YAAM,kBAAuB,UAAK,cAAc,aAAa,cAAc;AAE3E,UAAI,WAAW,eAAe,GAAG;AAC/B,YAAI,iBAAiB,MAAM;AACzB,cAAI,KAAU,aAAa,UAAK,cAAc,WAAW,CAAC,CAAC;AAAA,QAC7D,OAAO;AACL,cAAI,KAAK,WAAW;AAAA,QACtB;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;;;AC7DO,SAAS,WAA6BA,OAAc,MAAY,SAAsB;AAC3F,MAAI,OAAO,KAAK,SAASA,KAAI;AAC7B,SAAO,QAAQ,IAAI;AACnB,OAAK,UAAUA,OAAM,IAAI;AAC3B;;;ACLA,YAAYC,WAAU;AAGtB,YAAYC,SAAQ;AACpB,SAAS,cAAc;AAEvB,eAAsB,qBAAqB,KAAa;AACtD,QAAM,4BAA4B,MAAM,OAAO,uBAAuB;AAAA,IACpE,KAAK,MAAS,aAAS,SAAS,GAAG;AAAA,EACrC,CAAC;AACD,SAAO,6BAAkC,cAAQ,yBAAyB;AAC5E;AAEA,eAAsB,iBACpB,MACA,KAC6B;AAE7B,QAAM,wBAAwB,MAAM,qBAAqB,GAAG;AAC5D,MAAI,yBAAyB,MAAM;AACjC,WAAO;AAAA,EACT;AAGA,QAAM,cAAmB,WAAK,KAAK,cAAc;AACjD,MAAI,KAAK,OAAO,WAAW,GAAG;AAC5B,UAAM,cAAc,KAAK,SAAS,WAAW;AAC7C,QAAI,YAAY,eAAe,QAAW;AACxC,aAAO;AAAA,IACT;AAAA,EACF;AAEA,QAAM,UAAe,gBAAe,WAAK,KAAK,IAAI,CAAC;AACnD,MAAI,YAAY,KAAK;AACnB,WAAO;AAAA,EACT;AAEA,SAAO,iBAAiB,MAAM,OAAO;AACvC;;;ACtCA,SAAS,QAAQ,gBAAgB;AASjC,eAAsB,oBACpB,MACA,cACA,eAAwB,OACxB;AACA,QAAM,MAAM,oBAAI,IAAoB;AAEpC,QAAM,oBAAoB,MAAM,wBAAwB,MAAM,cAAc,YAAY;AACxF,aAAW,cAAc,mBAAmB;AAC1C,UAAM,cAAc,SAAS,YAAY,cAAc;AACvD,UAAM,EAAE,KAAK,IAAI,KAAK,SAAS,WAAW;AAC1C,QAAI,SAAS,QAAW;AACtB,YAAM,IAAI,MAAM,yBAAyB,WAAW,EAAE;AAAA,IACxD;AACA,QAAI,IAAI,MAAM,UAAU;AAAA,EAC1B;AACA,SAAO;AACT;;;AC1BA,YAAY,YAAY;AAGjB,IAAM,aAAN,MAAiC;AAAA,EACtC,YAAoBC,MAAoB,QAAQ;AAA5B,cAAAA;AAAA,EAA6B;AAAA,EACjD,MAAM,eAAuB,MAAqC;AAChE,SAAK,GAAG,UAAU,eAAe,EAAE,YAAW,6BAAM,cAAa,MAAM,CAAC;AAAA,EAC1E;AAAA,EACA,MAAM,eAA6B;AACjC,SAAK,GAAG,UAAU,aAAa;AAAA,EACjC;AAAA,EAEA,OAAOC,OAAuB;AAC5B,WAAO,KAAK,GAAG,WAAWA,KAAI;AAAA,EAChC;AAAA,EAIA,UAAUA,OAAc,MAAuB,MAA2C;AACxF,QAAI,MAAM;AACR,WAAK,GAAG,cAAcA,OAAM,MAAM,EAAE,UAAU,KAAK,SAAS,CAAC;AAAA,IAC/D,OAAO;AACL,WAAK,GAAG,cAAcA,OAAM,IAAI;AAAA,IAClC;AAAA,EACF;AAAA,EAIA,SAASA,OAAc,MAAkF;AACvG,QAAI,6BAAM,QAAQ;AAChB,aAAO,KAAK,MAAM,KAAK,GAAG,aAAaA,OAAM,OAAO,CAAC;AAAA,IACvD;AACA,WAAO,KAAK,GAAG,aAAaA,OAAM,6BAAM,QAAQ;AAAA,EAClD;AAAA,EACA,WAAWA,OAAc;AACvB,SAAK,GAAG,WAAWA,KAAI;AAAA,EACzB;AAAA,EACA,SAAS,UAAkB;AACzB,UAAM,WAAW,KAAK,GAAG,aAAa,UAAU,OAAO;AACvD,WAAO,KAAK,MAAM,QAAQ;AAAA,EAC5B;AAAA,EACA,UAAUA,OAAc,GAAiB;AACvC,WAAO,KAAK,GAAG,cAAcA,OAAM,KAAK,UAAU,GAAG,QAAW,CAAC,IAAI,IAAI;AAAA,EAC3E;AAAA,EACA,QAAQ;AAEN,WAAO,QAAQ,QAAQ;AAAA,EACzB;AACF;;;AChDA,YAAYC,aAAY;AAExB,YAAYC,WAAU;AAEtB,SAAS,kBAAkB,MAA0D;AACnF,MAAI,KAAK,WAAW;AAClB,UAAM,IAAI,MAAM,wBAAwB,KAAK,UAAU,IAAI,CAAC,EAAE;AAAA,EAChE;AACF;AAEA,SAAS,cACP,MACA,MACqD;AACrD,MAAI,KAAK,SAAS,MAAM;AACtB,UAAM,IAAI,MAAM,wBAAwB,KAAK,UAAU,IAAI,CAAC,EAAE;AAAA,EAChE;AACF;AAEA,SAAS,WAAmD,MAAS,MAA0C;AAC7G,MAAI,KAAK,SAAS,MAAM;AACtB,UAAM,IAAI,MAAM,wBAAwB,KAAK,UAAU,IAAI,CAAC,EAAE;AAAA,EAChE;AACF;AAEA,SAAS,aAA6B,MAAwC;AAC5E,MAAI,CAAC,MAAM;AACT,UAAM,IAAI,MAAM,wBAAwB;AAAA,EAC1C;AACF;AAEA,SAAS,gBAAgB,MAAY;AACnC,MAAI,CAAC,KAAK,QAAQ;AAChB,UAAM,IAAI,MAAM,0CAA0C;AAAA,EAC5D;AACF;AAoDO,IAAM,cAAN,MAAkC;AAAA,EAIvC,YACUC,MAcJF,SACJ;AAfQ,cAAAE;AAAA,EAeP;AAAA;AAAA,EAlBH,SAAS,oBAAI,IAAmC;AAAA,EAiChD,aAAa,MAAY,gBAAyD;AAChF,QAAI,CAAC,KAAK,OAAQ,OAAM,IAAI,MAAM,0BAA0B;AAC5D,UAAM,UAAgB;AAAA,MACpB,GAAG;AAAA,MACH,UAAU,KAAK;AAAA,MACf,QAAQ,KAAK;AAAA,MACb,KAAM,KAAiB;AAAA,IACzB;AACA,SAAK,OAAO,IAAI,IAAS,eAAS,KAAK,QAAQ,GAAG,OAAO;AACzD,WAAO;AAAA,EACT;AAAA,EAEA,iBAAiB,MAAsD;AAGrE,eAAW,SAAS,KAAK,GAAG,YAAY,KAAK,QAAQ,GAAG;AAGtD,WAAK,SAAc,WAAK,KAAK,UAAU,KAAK,CAAC;AAAA,IAC/C;AACA,SAAK,OAAO;AAAA,EACd;AAAA,EASA,SACE,UACA,QAC8G;AAC9G,UAAM,gBAAqB,cAAQ,QAAQ;AAE3C,QAAI,CAAC,UAAU,kBAAuB,YAAM,aAAa,EAAE,MAAM;AAC/D,YAAM,IAAI,MAAM,yDAAyD,aAAa,EAAE;AAAA,IAC1F;AACA,UAAM,OAAO,KAAK,GAAG,UAAU,aAAa;AAE5C,QAAI;AAEJ,QAAI,KAAK,YAAY,GAAG;AACtB,aAAO;AAAA,QACL,UAAU;AAAA,QACV,MAAM;AAAA,QACN,MAAM;AAAA,QACN,KAAK,oBAAI,IAAI;AAAA,QACb;AAAA,QACA,YAAY;AAAA,MACd;AAAA,IACF,WAAW,KAAK,eAAe,GAAG;AAChC,aAAO;AAAA,QACL,UAAU;AAAA,QACV,MAAM;AAAA,QACN,SAAS,KAAK,GAAG,aAAa,aAAa;AAAA,QAC3C;AAAA,QACA,YAAY;AAAA,MACd;AAAA,IACF,WAAW,KAAK,OAAO,GAAG;AACxB,aAAO;AAAA,QACL,UAAU;AAAA,QACV,MAAM;AAAA,QACN,MAAM;AAAA,QACN;AAAA,QACA,YAAY;AAAA,MACd;AAAA,IACF,OAAO;AACL,YAAM,IAAI,MAAM,wEAAwE,aAAa,EAAE;AAAA,IACzG;AAEA,QAAI,CAAC,UAAU,KAAK,SAAS,OAAO;AAClC,WAAK,OAAO,IAAI,eAAe,IAAI;AACnC,aAAO;AAAA,IACT,WAAW,QAAQ;AACjB,aAAO,IAAI,IAAS,eAAS,aAAa,GAAG,IAAI;AAAA,IACnD,OAAO;AACL,YAAM,IAAI,MAAM,+BAA+B,KAAK,UAAU,IAAI,CAAC,cAAc,aAAa,EAAE;AAAA,IAClG;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,wBAAwB,UAAkB;AACxC,UAAM,gBAAqB,cAAQ,QAAQ;AAC3C,UAAM,EAAE,KAAK,IAAS,YAAM,aAAa;AACzC,UAAM,QAAQ,CAAC;AAEf,QAAI,YAAY;AAChB,WAAO,cAAc,MAAM;AACzB,YAAM,QAAa,eAAS,SAAS,CAAC;AACtC,kBAAiB,cAAQ,SAAS;AAAA,IACpC;AAEA,QAAI,UAAU;AACd,QAAI,UAAgB,KAAK,OAAO,IAAI,IAAI,KAAK,KAAK,SAAS,SAAS,MAAS;AAC7E,QAAI;AACF,iBAAW,QAAQ,OAAO;AACxB,0BAAkB,OAAO;AACzB,sBAAc,SAAS,MAAM;AAC7B,YAAI,QAAQ,SAAS,WAAW;AAC9B,gBAAM,aAAa,KAAK,0BAA+B,cAAa,cAAQ,OAAO,GAAG,QAAQ,OAAO,CAAC;AACtG,uBAAa,UAAU;AACvB,4BAAkB,UAAU;AAC5B,qBAAW,YAAY,KAAK;AAC5B,oBAAU;AAAA,QACZ;AACA,mBAAW,SAAS,KAAK;AACzB,0BAAkB,OAAO;AACzB,kBAAU,QAAQ,IAAI,IAAI,IAAI,KAAK,KAAK,SAAc,WAAK,QAAQ,UAAU,IAAI,GAAG,OAAO;AAC3F,kBAAe,WAAK,SAAS,IAAI;AAAA,MACnC;AAAA,IAEF,SAAS,GAAG;AAAA,IAGZ;AACA,WAAO,EAAE,kBAAkB,SAAS,MAAM,QAAQ;AAAA,EACpD;AAAA,EAEA,SAAS,UAAkB;AACzB,UAAM,gBAAqB,cAAQ,QAAQ;AAC3C,UAAM,EAAE,kBAAkB,KAAK,IAAI,KAAK,wBAAwB,aAAa;AAC7E,QAAI,qBAAqB,eAAe;AACtC,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT;AAAA,EAEA,0BAA0B,UAAkB,UAAkB,KAA6C;AACzG,UAAM,OAAO,KAAK,SAAS,QAAQ;AACnC,QAAI,CAAC,QAAQ,KAAK,SAAS,UAAW,QAAO;AAE7C,QAAI,YAAY,EAAG,OAAM,IAAI,MAAM,2BAA2B;AAE9D,WAAO,KAAK,0BAA0B,KAAK,SAAS,SAAS;AAAA,EAC/D;AAAA,EAEA,MAAM,UAAkB,OAA+B,EAAE,WAAW,MAAM,GAAS;AACjF,UAAM,gBAAqB,cAAQ,QAAQ;AAC3C,UAAM,EAAE,MAAM,iBAAiB,IAAI,KAAK,wBAAwB,aAAa;AAC7E,QAAI,aAAa,kBAAkB;AACjC,iBAAW,MAAM,KAAK;AACtB,sBAAgB,IAAI;AACpB,UAAI,CAAC,KAAK,UAAW;AAAA,IACvB,WAAgB,cAAQ,QAAQ,MAAM,kBAAkB;AACtD,iBAAW,MAAM,KAAK;AACtB,wBAAkB,IAAI;AACtB,WAAK,IAAI,IAAS,eAAS,QAAQ,GAAG;AAAA,QACpC,MAAM;AAAA,QACN,UAAU;AAAA,QACV,QAAQ;AAAA,QACR,KAAK,oBAAI,IAAI;AAAA,QACb,YAAY;AAAA,MACd,CAAC;AACD;AAAA,IACF;AAEA,QAAI,CAAC,KAAK,aAAkB,cAAQ,aAAa,MAAM,kBAAkB;AACvE,YAAM,IAAI,MAAM,2BAA2B;AAAA,IAC7C;AAEA,UAAM,WAAW;AACjB,QAAI,YAAY;AAChB,UAAM,SAAmB,CAAC;AAC1B,WAAO,cAAc,UAAU;AAC7B,aAAO,QAAa,cAAQ,KAAK,UAAe,eAAS,UAAU,SAAS,CAAC,CAAC;AAC9E,kBAAiB,cAAQ,SAAS;AAAA,IACpC;AAEA,eAAW,aAAa,QAAQ;AAC9B,WAAK,MAAM,SAAS;AAAA,IACtB;AAAA,EACF;AAAA,EAEA,MAAM,eAA6B;AACjC,UAAM,OAAO,KAAK,SAAS,aAAa;AACxC,QAAI,CAAC,QAAQ,KAAK,WAAW;AAC3B;AAAA,IACF;AACA,eAAW,MAAM,KAAK;AACtB,QAAI,KAAK,MAAM;AACb,WAAK,iBAAiB,IAAI;AAAA,IAC5B;AAEA,QAAI,KAAK,IAAI,SAAS,GAAG;AACvB,WAAK,aAAa,MAAM;AAAA,QACtB,MAAM;AAAA,QACN,WAAW;AAAA,QACX,YAAY;AAAA,MACd,CAAC;AAAA,IACH,OAAO;AACL,YAAM,IAAI,MAAM,qBAAqB;AAAA,IACvC;AAAA,EACF;AAAA,EAEA,OAAO,UAA2B;AAChC,UAAM,OAAO,KAAK,SAAS,QAAQ;AACnC,WAAO,CAAC,CAAC,QAAQ,CAAC,KAAK;AAAA,EACzB;AAAA,EAKA,SACE,UACA,MACA;AACA,QAAI,OAAO,KAAK,0BAA0B,QAAQ;AAElD,QAAI,CAAC,MAAM;AACT,aAAO;AAAA,IACT;AACA,kBAAc,MAAM,KAAK;AACzB,sBAAkB,IAAI;AAEtB,QAAI,KAAK,MAAM;AACb,aAAO,KAAK,aAAa,MAAM;AAAA,QAC7B,MAAM;AAAA,QACN,MAAM,KAAK,GAAG,aAAa,QAAQ;AAAA,QACnC,YAAY;AAAA,MACd,CAAC;AAAA,IACH;AAEA,QAAI,CAAC,MAAM;AACT,aAAO,OAAO,KAAK,KAAK,IAAI;AAAA,IAC9B,WAAW,KAAK,QAAQ;AACtB,aAAO,KAAK,MAAM,KAAK,KAAK,SAAS,OAAO,CAAC;AAAA,IAC/C,OAAO;AACL,aAAO,KAAK,KAAK,SAAS,KAAK,QAAQ;AAAA,IACzC;AAAA,EACF;AAAA,EAKA,UAAU,UAAkB,MAAuB,MAAqC;AACtF,UAAM,uBAAuB,OAAO,SAAS,WAAW,OAAO,KAAK,MAAM,6BAAM,QAAQ,IAAI,OAAO,KAAK,IAAI;AAE5G,UAAM,gBAAqB,cAAQ,QAAQ;AAC3C,UAAM,eAAe,KAAK,0BAA0B,aAAa;AACjE,QAAI,cAAc;AAChB,UAAI,aAAa,SAAS,OAAO;AAC/B,cAAM,IAAI,MAAM,0BAA0B;AAAA,MAC5C;AACA,WAAK,aAAa,cAAc;AAAA,QAC9B,MAAM;AAAA,QACN,MAAM;AAAA,QACN,YAAY;AAAA,MACd,CAAC;AACD;AAAA,IACF;AAEA,UAAM,eAAe,KAAK,0BAA+B,cAAQ,aAAa,CAAC;AAC/E,iBAAa,YAAY;AACzB,eAAW,cAAc,KAAK;AAC9B,sBAAkB,YAAY;AAE9B,iBAAa,IAAI,IAAS,eAAS,aAAa,GAAG;AAAA,MACjD,MAAM;AAAA,MACN,UAAU;AAAA,MACV,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,YAAY;AAAA,IACd,CAAC;AAAA,EACH;AAAA,EAEA,WAAW,UAAkB;AAC3B,UAAM,gBAAqB,cAAQ,QAAQ;AAC3C,UAAM,OAAO,KAAK,SAAS,aAAa;AACxC,QAAI,CAAC,QAAS,KAAK,SAAS,UAAU,KAAK,cAAc,KAAO;AAChE,kBAAc,MAAM,KAAK;AACzB,SAAK,aAAa,MAAM;AAAA,MACtB,MAAM;AAAA,MACN,WAAW;AAAA,MACX,YAAY;AAAA,IACd,CAAC;AAAA,EACH;AAAA,EAEA,SAAS,UAAkB;AACzB,WAAO,KAAK,SAAS,UAAU,EAAE,QAAQ,KAAK,CAAC;AAAA,EACjD;AAAA,EAEA,UAAU,UAAkB,GAAiB;AAC3C,WAAO,KAAK,UAAU,UAAU,KAAK,UAAU,GAAG,QAAW,CAAC,IAAI,MAAM;AAAA,MACtE,UAAU;AAAA,IACZ,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,eAAe,MAAqE;AAExF,QAAI,KAAK,WAAW;AAClB,UAAI;AACF,cAAM,KAAK,GAAG,SAAS,OAAO,KAAK,QAAQ;AAC3C,eAAO,KAAK,GAAG,SAAS,OAAO,KAAK,QAAQ;AAAA,MAE9C,SAAS,GAAG;AAEV;AAAA,MACF;AAAA,IACF,WAAW,KAAK,SAAS,QAAQ,KAAK,eAAe,OAAO;AAC1D;AAAA,IACF,OAAO;AAEL,aAAO,KAAK,GAAG,SAAS,UAAU,KAAK,UAAU,KAAK,IAAI;AAAA,IAC5D;AAAA,EACF;AAAA,EAEA,MAAM,kBAAkB,MAAmB;AACzC,QAAI,CAAC,KAAK,WAAY;AACtB,QAAI;AACF,YAAM,YAAY,MAAM,KAAK,GAAG,SAAS,SAAS,KAAK,QAAQ;AAC/D,UAAI,cAAc,KAAK,SAAS;AAC9B;AAAA,MACF;AAAA,IAEF,SAAS,GAAG;AAAA,IAEZ;AACA,WAAO,KAAK,GAAG,SAAS,QAAQ,KAAK,SAAS,KAAK,QAAQ;AAAA,EAC7D;AAAA,EAEA,MAAM,cAAc,MAAkE;AACpF,QAAI,CAAC,KAAK,aAAa,KAAK,YAAY;AACtC,UAAI;AACF,cAAM,KAAK,GAAG,SAAS,OAAO,KAAK,QAAQ;AAAA,MAE7C,SAAS,GAAG;AACV,cAAM,KAAK,GAAG,SAAS,MAAM,KAAK,QAAQ;AAAA,MAC5C;AAAA,IACF;AAEA,UAAMC,YAA+B,CAAC;AACtC,eAAW,SAAS,KAAK,IAAI,OAAO,GAAG;AACrC,UAAI,KAAK,aAAa,CAAC,MAAM,WAAW;AACtC,cAAM,IAAI,MAAM,iFAAiF;AAAA,MACnG;AACA,UAAI,MAAM,SAAS,OAAO;AACxB,QAAAA,UAAS,KAAK,KAAK,cAAc,KAAK,CAAC;AAAA,MACzC,WAAW,MAAM,SAAS,QAAQ;AAChC,QAAAA,UAAS,KAAK,KAAK,eAAe,KAAK,CAAC;AAAA,MAC1C,WAAW,MAAM,SAAS,WAAW;AACnC,QAAAA,UAAS,KAAK,KAAK,kBAAkB,KAAK,CAAC;AAAA,MAC7C,OAAO;AACL,cAAM,IAAI,MAAM,qBAAqB;AAAA,MACvC;AAAA,IACF;AACA,UAAM,QAAQ,IAAIA,SAAQ;AAC1B,QAAI,KAAK,WAAW;AAClB,aAAO,KAAK,GAAG,SAAS,MAAM,KAAK,QAAQ;AAAA,IAC7C;AACA;AAAA,EACF;AAAA,EAEA,QAAQ;AACN,UAAMA,YAA+B,CAAC;AACtC,eAAW,YAAY,KAAK,OAAO,OAAO,GAAG;AAC3C,MAAAA,UAAS,KAAK,KAAK,cAAc,QAAQ,CAAC;AAAA,IAC5C;AACA,WAAO,QAAQ,IAAIA,SAAQ;AAAA,EAC7B;AACF;;;ACveA,OAAO,gBAAgB;;;ACAhB,SAAS,oBAAoB,GAAW,YAAoB,GAAG;AACpE,SAAO,IAAI,OAAO,GAAU,IAAI,OAAO,KAAM,IAAI,OAAO,GAAU,GAAI,SAAS,GAAG,GAAG,EAAE,UAAU,GAAG,SAAS,IAAI;AACnH;;;ACsDO,IAAM,QAAN,MAA6B;AAAA,EAClC,QAAa,CAAC;AAAA,EACd;AAAA,EACA,gBAA0B,CAAC;AAAA,EAC3B,UAAkC,CAAC;AAAA,EACnC;AAAA,EACA,cAAc;AAAA,EAEd,YACE,QAKA;AACA,SAAK,UAAU;AAAA,MACb,SAAS;AAAA,MACT,GAAG;AAAA,IACL;AACA,SAAK,cAAc,KAAK,GAAG,GAAG,OAAO,QAAQ,MAAM;AAEnD,QAAI,OAAO,YAAY;AACrB,WAAK,mBAAmB,CAAC;AACzB,iBAAW,gBAAgB,OAAO,SAAS;AACzC,YAAI,aAAa,WAAW,QAAW;AACrC,gBAAM,IAAI,MAAM,oDAAoD;AAAA,QACtE,WAAW,OAAO,aAAa,WAAW,UAAU;AAClD,eAAK,iBAAiB,KAAK;AAAA,YACzB,MAAM;AAAA,YACN,WAAW;AAAA,YACX,WAAW;AAAA,YACX,OAAO,aAAa;AAAA,UACtB,CAAC;AAAA,QACH,WAAW,WAAW,aAAa,QAAQ;AACzC,eAAK,iBAAiB,KAAK;AAAA,YACzB,MAAM;AAAA,YACN,WAAW;AAAA,YACX,GAAG,aAAa;AAAA,UAClB,CAAC;AAAA,QACH,WAAW,eAAe,aAAa,QAAQ;AAC7C,cAAI,aAAa,SAAS,SAAU,OAAM,IAAI,MAAM,gCAAgC;AACpF,eAAK,iBAAiB,KAAK;AAAA,YACzB,MAAM,aAAa;AAAA,YACnB,UAAU,aAAa;AAAA,YACvB,WAAW,aAAa;AAAA,YACxB,WAAW;AAAA,YACX,GAAG,aAAa;AAAA,UAClB,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEA,UAAU,MAAS;AAEjB,SAAK,MAAM,KAAK,IAAI;AAAA,EACtB;AAAA,EAEA,WAAW,GAAW;AACpB,QAAI,QAAQ,OAAO,CAAC;AACpB,eAAW,OAAO,KAAK,OAAO;AAC5B,eAAS,IAAI,CAAC;AAAA,IAChB;AACA,WAAO;AAAA,EACT;AAAA,EAEA,mBAAmB;AACjB,UAAM,kBAAkB,KAAK;AAC7B,QAAI,iBAAiB;AACnB,eAAS,IAAI,GAAG,IAAI,gBAAgB,QAAQ,KAAK;AAC/C,cAAM,kBAAkB,gBAAgB,CAAC;AAEzC,gBAAQ,gBAAgB,WAAW;AAAA,UACjC,KAAK;AACH,iBAAK,QAAQ,CAAC,IAAI,KAAK,WAAW,CAAC;AACnC;AAAA,UACF,KAAK;AACH,iBAAK,QAAQ,CAAC,IAAI,KAAK,WAAW,CAAC,IAAI,OAAO,KAAK,MAAM,MAAM;AAC/D;AAAA,UACF,KAAK;AACH,iBAAK,QAAQ,CAAC,IAAI,gBAAgB;AAClC;AAAA,QACJ;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEA,yBAAyB;AAtJ3B;AAuJI,SAAK,cAAc,KAAK,GAAG,GAAG,KAAK,QAAQ,QAAQ,MAAM;AAEzD,aAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,QAAQ,QAAQ,KAAK;AACpD,YAAM,YAAY,KAAK,QAAQ,QAAQ,CAAC;AACxC,WAAK,cAAc,CAAC,IAAI,KAAK;AAAA,SAC1B,KAAK,QAAQ,QAAQ,CAAC,EAAE,UAAU,IAAI;AAAA,QACvC,GAAG,KAAK,MAAM,IAAI,CAAC,MAAM,KAAK,sBAAsB,EAAE,CAAC,GAAG,SAAS,EAAE,MAAM;AAAA,QAC3E,KAAK,WAAW,KAAK,mBACjB,KAAK,wBAAsB,UAAK,YAAL,mBAAe,OAAM,IAAI,KAAK,iBAAiB,CAAC,CAAC,EAAE,SAC9E;AAAA,MACN;AAAA,IACF;AAEA,SAAK,cAAc;AACnB,eAAW,YAAY,KAAK,eAAe;AACzC,WAAK,eAAe;AAAA,IACtB;AACA,SAAK,gBAAgB,KAAK,cAAc,SAAS,KAAK,KAAK,QAAQ;AAAA,EACrE;AAAA,EAEA,gBAAgB,YAAoB;AAClC,UAAM,gBAAgB,GAAG,SAAS,KAAK,QAAQ,SAAS,GAAG;AAE3D,QAAI,MAAM;AAGV,aAAS,IAAI,GAAG,IAAI,KAAK,cAAc,QAAQ,KAAK;AAClD,aAAO,GAAG,SAAS,KAAK,cAAc,CAAC,GAAG,UAAU,IAAI;AAAA,IAC1D;AACA,UAAM,IAAI,UAAU;AACpB,YAAQ,IAAI,GAAG;AAAA,EACjB;AAAA,EAEA,kBAAkB;AAChB,QAAI,KAAK,QAAQ,YAAY;AAC3B,YAAM,aAAa,KAAK,QAAQ;AAChC,YAAM,gBAAgB,GAAG,SAAS,KAAK,QAAQ,SAAS,GAAG;AAE3D,UAAI,KAAK;AACT,eAAS,IAAI,GAAG,IAAI,WAAW,QAAQ,KAAK;AAC1C,cAAM,UAAU,WAAW,CAAC,EAAE,UAAU;AACxC,cAAM,QAAQ,OAAO,KAAK,cAAc,CAAC,GAAG,GAAG,IAAI;AAAA,MACrD;AACA,WAAK,GAAG,UAAU;AAClB,cAAQ,IAAI,EAAE;AAEd,WAAK,gBAAgB,GAAG;AAAA,IAC1B;AAAA,EACF;AAAA,EAEA,kBAAkB;AAChB,UAAM,YAAY,KAAK;AACvB,QAAI,WAAW;AACb,WAAK,gBAAgB,GAAG;AAExB,YAAM,gBAAgB,GAAG,SAAS,KAAK,QAAQ,SAAS,GAAG;AAE3D,UAAI,KAAK;AACT,eAAS,IAAI,GAAG,IAAI,UAAU,QAAQ,KAAK;AACzC,cAAM,KAAK,qBAAqB,UAAU,CAAC,GAAG,KAAK,iBAAkB,CAAC,GAAG,CAAC,IAAI;AAAA,MAChF;AACA,WAAK,GAAG,UAAU;AAClB,cAAQ,IAAI,EAAE;AAAA,IAChB;AAAA,EACF;AAAA,EAEA,QAAQ;AAEN,QAAI,KAAK,QAAQ,eAAe,QAAW;AAAA,IAE3C;AAEA,SAAK,iBAAiB;AACtB,SAAK,uBAAuB;AAE5B,YAAQ,IAAI;AACZ,YAAQ,IAAI,GAAG,KAAK,QAAQ,KAAK,EAAE;AACnC,YAAQ,IAAI,GAAG,SAAS,KAAK,aAAa,GAAG,CAAC;AAE9C,UAAM,gBAAgB,GAAG,SAAS,KAAK,QAAQ,SAAS,GAAG;AAC3D,QAAI,KAAK,QAAQ,YAAY;AAC3B,WAAK,gBAAgB;AAAA,IACvB;AAEA,aAAS,IAAI,GAAG,IAAI,KAAK,MAAM,QAAQ,KAAK;AAC1C,UAAI,UAAU;AACd,eAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,QAAQ,QAAQ,KAAK;AACpD,mBAAW,KAAK,wBAAwB,GAAG,CAAC,IAAI;AAAA,MAClD;AACA,cAAQ,KAAK;AACb,cAAQ,IAAI,OAAO;AAAA,IACrB;AAEA,QAAI,KAAK,QAAQ,WAAY,MAAK,gBAAgB;AAClD,YAAQ,IAAI;AAAA,EACd;AAAA,EAEA,sBAAsB,OAAwB,QAAqD;AACjG,QAAI,OAAO,SAAS,YAAY,OAAO,aAAa,eAAe;AACjE,aAAO,oBAAoB,OAAiB,OAAO,aAAa,CAAC;AAAA,IACnE,OAAO;AACL,aAAO,KAAK;AAAA,IACd;AAAA,EACF;AAAA,EAEA,qBAAqB,OAAwB,QAAqD,QAAgB;AAChH,QAAI;AACJ,QAAI,OAAO,SAAS,YAAY,OAAO,aAAa,eAAe;AACjE,eAAS,oBAAoB,OAAiB,OAAO,aAAa,CAAC;AAAA,IACrE,OAAO;AACL,eAAS,KAAK;AAAA,IAChB;AAEA,QAAI,OAAO,cAAc,QAAQ;AAC/B,aAAO,OAAO,OAAO,KAAK,cAAc,MAAM,CAAC;AAAA,IACjD,OAAO;AACL,aAAO,OAAO,SAAS,KAAK,cAAc,MAAM,CAAC;AAAA,IACnD;AAAA,EACF;AAAA,EAEA,iBAAiB,QAAgB,QAAgB;AAC/C,UAAM,SAAS,KAAK,QAAQ,QAAQ,MAAM;AAE1C,QAAI,OAAO,SAAS,YAAY,OAAO,aAAa,eAAe;AACjE,aAAO,oBAAoB,KAAK,MAAM,MAAM,EAAE,MAAM,GAAG,OAAO,aAAa,CAAC;AAAA,IAC9E,OAAO;AACL,aAAO,KAAK,KAAK,MAAM,MAAM,EAAE,MAAM;AAAA,IACvC;AAAA,EACF;AAAA,EAEA,wBAAwB,QAAgB,QAAgB;AACtD,UAAM,SAAS,KAAK,QAAQ,QAAQ,MAAM;AAE1C,QAAI;AACJ,QAAI,OAAO,SAAS,YAAY,OAAO,aAAa,eAAe;AACjE,eAAS,oBAAoB,KAAK,MAAM,MAAM,EAAE,MAAM,GAAG,OAAO,aAAa,CAAC;AAAA,IAChF,OAAO;AACL,eAAS,KAAK,KAAK,MAAM,MAAM,EAAE,MAAM;AAAA,IACzC;AAEA,QAAI,OAAO,cAAc,QAAQ;AAC/B,aAAO,OAAO,OAAO,KAAK,cAAc,MAAM,CAAC;AAAA,IACjD,OAAO;AACL,aAAO,OAAO,SAAS,KAAK,cAAc,MAAM,CAAC;AAAA,IACnD;AAAA,EACF;AAAA,EAEA,eAAe,QAAgB,QAAqF;AAClH,QAAI,WAAW,KAAK;AAAA,OACjB,OAAO,UAAU,IAAI;AAAA,MACtB,KAAK,WAAW,KAAK,mBACjB,KAAK,sBAAsB,KAAK,QAAQ,MAAM,GAAG,KAAK,iBAAiB,MAAM,CAAC,EAAE,SAChF;AAAA,IACN;AAEA,aAAS,IAAI,GAAG,IAAI,KAAK,MAAM,QAAQ,KAAK;AAC1C,iBAAW,KAAK,IAAI,UAAU,KAAK,iBAAiB,QAAQ,CAAC,EAAE,MAAM;AAAA,IAMvE;AAEA,WAAO;AAAA,EACT;AACF;;;AF7SA,IAAM,QAAQ,oBAAI,IAAsF;AAKxG,IAAM,qBAAqB,oBAAI,IAAsE;AAKrG,IAAM,oBAAoB,oBAAI,IAA+B;AAE7D,IAAI,eAAe;AACnB,IAAI,cAAc;AAElB,IAAI,YAAY,OAAO,CAAC;AAExB,IAAI,oBAAoB;AACxB,IAAI,sBAAsB;AAC1B,IAAI,qBAAqB;AAMlB,IAAM,iBAAiC,SAAS,mBAAmB,QAAgB,UAA6B;AACrH,eAAa,QAAQ,OAAO,OAAO;AAEnC,MAAI,mBAAmB,MAAM,IAAI,QAAQ;AACzC,MAAI,qBAAqB,QAAW;AAClC,uBAAmB,oBAAI,IAAqB;AAC5C,UAAM,IAAI,UAAU,gBAAgB;AAAA,EACtC;AAEA,MAAI,SAAS,iBAAkB,IAAI,MAAM;AACzC,MAAI,WAAW,QAAW;AACxB;AACA,aAAS;AACT,eAAW,WAAW,UAAU;AAG9B,UAAI,eAAe,mBAAmB,IAAI,OAAO;AACjD,UAAI,iBAAiB,QAAW;AAC9B,uBAAe,oBAAI,IAAqB;AACxC,2BAAmB,IAAI,SAAS,YAAY;AAAA,MAC9C;AAGA,eAAS,aAAa,IAAI,MAAM;AAChC,UAAI,WAAW,QAAW;AACxB,YAAI,SAAqC,kBAAkB,IAAI,OAAO;AACtE,YAAI,WAAW,QAAW;AACxB,mBAAS,WAAW,OAAO,OAAO;AAElC,4BAAkB,IAAI,SAAS,MAAM;AAAA,QACvC;AAEA;AACA,iBAAS,OAAO,KAAK,MAAM;AAC3B,qBAAa,IAAI,QAAQ,MAAM;AAAA,MACjC,OAAO;AACL;AACA;AAAA,MACF;AAEA,UAAI,OAAQ;AAAA,IACd;AACA,qBAAkB,IAAI,QAAQ,MAAM;AAAA,EACtC,OAAO;AACL,0BAAsB,SAAS;AAC/B;AAAA,EACF;AACA,eAAa,QAAQ,OAAO,OAAO;AACnC,SAAO;AACT;AAEA,eAAe,aAAa,MAAM;AAChC,QAAM,QAAQ,IAAI,MAAwB;AAAA,IACxC,OAAO;AAAA,IACP,YAAY;AAAA,IACZ,YAAY;AAAA,IACZ,SAAS;AAAA,MACP,EAAE,QAAQ,QAAQ,MAAM,SAAS;AAAA,MACjC,EAAE,QAAQ,SAAS,MAAM,SAAS;AAAA,IACpC;AAAA,EACF,CAAC;AACD,QAAM,OAAO,iBAAiB,KAAK,YAAY;AAC/C,QAAM,OAAO,gBAAgB,KAAK,WAAW;AAC7C,QAAM,OAAO,oBAAoB,KAAK,iBAAiB;AACvD,QAAM,OAAO,sBAAsB,KAAK,mBAAmB;AAC3D,QAAM,OAAO,qBAAqB,KAAK,kBAAkB;AACzD,QAAM,OAAO,cAAc,oBAAoB,WAAW,CAAC,CAAC;AAE5D,QAAM,MAAM;AACd;;;AGrGO,IAAM,kBAAN,MAAsB;AAAA,EAI3B,YAAoB,OAAe;AAAf;AAAA,EAAgB;AAAA,EAHpC,QAAQ,oBAAI,IAA8C;AAAA,EAC1D;AAAA,EAIO,MAAM,MAAc;AACzB,UAAM,OAAO,QAAQ,OAAO,OAAO;AACnC,QAAI,KAAK,OAAO;AACd,WAAK,MAAM,SAAS;AAAA,IACtB;AAEA,QAAI,OAAO,KAAK,MAAM,IAAI,IAAI;AAC9B,QAAI,SAAS,QAAW;AACtB,aAAO,EAAE,OAAO,GAAG,OAAO,CAAC,KAAK;AAChC,WAAK,MAAM,IAAI,MAAM,IAAI;AAAA,IAC3B,OAAO;AACL,WAAK,SAAS;AACd,WAAK;AAAA,IACP;AACA,SAAK,QAAQ;AAAA,EACf;AAAA,EAEO,OAAO;AACZ,UAAM,OAAO,QAAQ,OAAO,OAAO;AACnC,QAAI,KAAK,OAAO;AACd,WAAK,MAAM,SAAS;AACpB,WAAK,QAAQ;AAAA,IACf;AAAA,EACF;AAAA,EAEO,eAAe;AACpB,UAAM,QAAQ,IAAI,MAAwC;AAAA,MACxD,YAAY;AAAA,MACZ,YAAY;AAAA,MACZ,YAAY;AAAA,MACZ,OAAO,KAAK;AAAA,MACZ,SAAS;AAAA,QACP;AAAA,UACE,QAAQ;AAAA,UACR,MAAM;AAAA,UACN,UAAU;AAAA,UACV,QAAQ,EAAE,WAAW,MAAM;AAAA,QAC7B;AAAA,QACA,EAAE,QAAQ,QAAQ,MAAM,UAAU,WAAW,QAAQ,QAAQ,QAAQ;AAAA,QACrE,EAAE,QAAQ,SAAS,MAAM,UAAU,QAAQ,EAAE,WAAW,MAAM,EAAE;AAAA,QAChE,EAAE,QAAQ,OAAO,MAAM,UAAU,QAAQ,EAAE,WAAW,UAAU,EAAE;AAAA,MACpE;AAAA,IACF,CAAC;AAED,eAAW,CAAC,MAAM,KAAK,KAAK,KAAK,OAAO;AACtC,YAAM;AAAA,QACJ,MAAM;AAAA,QACN;AAAA,QACA,OAAO,MAAM,KAAK;AAAA;AAAA,QAClB,MAAM,QAAQ,OAAO,MAAM,KAAK;AAAA,MAClC;AAAA,IACF;AACA,UAAM,MAAM;AAAA,EACd;AACF;;;AC7DO,IAAM,SAAN,MAAa;AAAA,EAElB,YAAoB,OAAe;AAAf;AAClB,SAAK,KAAK;AAAA,EACZ;AAAA,EAHA,UAAmD,CAAC;AAAA,EAK7C,MAAM,MAAc;AACzB,SAAK,QAAQ,KAAK,EAAE,MAAM,OAAO,QAAQ,OAAO,OAAO,EAAE,CAAC;AAAA,EAC5D;AAAA,EAEO,OAAO;AACZ,SAAK,QAAQ,KAAK,EAAE,OAAO,QAAQ,OAAO,OAAO,EAAE,CAAC;AAAA,EACtD;AAAA,EAEO,eAAe;AACpB,UAAM,QAAQ,IAAI,MAAwB;AAAA,MACxC,YAAY;AAAA,MACZ,YAAY;AAAA,MACZ,YAAY;AAAA,MACZ,OAAO,KAAK;AAAA,MACZ,SAAS;AAAA,QACP;AAAA,UACE,QAAQ;AAAA,UACR,MAAM;AAAA,UACN,UAAU;AAAA,UACV,WAAW;AAAA,UACX,QAAQ,EAAE,WAAW,MAAM;AAAA,QAC7B;AAAA,QACA,EAAE,QAAQ,QAAQ,MAAM,UAAU,QAAQ,QAAQ;AAAA,MACpD;AAAA,IACF,CAAC;AAED,SAAK,KAAK;AAEV,QAAI,MAAwC,KAAK,QAAQ,CAAC;AAC1D,eAAW,SAAS,KAAK,SAAS;AAChC,UAAI,IAAI,MAAM;AACZ,cAAM,OAAO,MAAM,QAAQ,IAAI;AAC/B,cAAM,OAAO,MAAM,IAAI,IAAI;AAAA,MAC7B;AACA,YAAM;AAAA,IACR;AAEA,UAAM,MAAM;AAAA,EACd;AACF;","names":["path","path","fs","fs","path","realFs","path","fs","promises"]}
|