pathprobe 0.4.3 → 0.5.3

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/README.md CHANGED
@@ -1,6 +1,12 @@
1
1
  # pathprobe
2
2
 
3
- `pathprobe` 用于从自然语言文本中识别并验证真实存在的文件或目录路径。
3
+ `pathprobe` 用于从一段文本中找出其中提到的、真实存在于文件系统中的文件或目录路径。
4
+
5
+ ## 安装
6
+
7
+ ```bash
8
+ npm install pathprobe
9
+ ```
4
10
 
5
11
  ## 基本用法
6
12
 
@@ -9,8 +15,8 @@ import { findExistingPaths } from "pathprobe";
9
15
 
10
16
  const matches = await findExistingPaths(
11
17
  `
12
- Please check ./src/index.ts
13
- and C:\\projects\\demo\\README.md:10:5
18
+ 请检查 src/index.ts:12
19
+ 以及 "./config/settings.json"
14
20
  `,
15
21
  2,
16
22
  [process.cwd()],
@@ -27,20 +33,16 @@ console.log(matches);
27
33
  kind: "file",
28
34
  path: "/project/src/index.ts",
29
35
  position: {
30
- start: 16,
31
- end: 30,
36
+ start: 8,
37
+ end: 20,
38
+ },
39
+ location: {
40
+ line: 12,
32
41
  },
33
42
  },
34
43
  ];
35
44
  ```
36
45
 
37
- 每个匹配项包含:
38
-
39
- - `path`:解析后的绝对路径
40
- - `kind`:`"file"` 或 `"directory"`
41
- - `position`:路径在原始文本中的字符范围
42
- - `location`:可选的行号、列号信息
43
-
44
46
  ## API
45
47
 
46
48
  ```ts
@@ -54,100 +56,101 @@ findExistingPaths(
54
56
  ): Promise<PathMatch[]>
55
57
  ```
56
58
 
57
- ### `text`
59
+ 参数说明:
60
+
61
+ - `text`:需要扫描的文本。
62
+ - `level`:搜索强度,值越高,识别越宽松。
63
+ - `directories`:解析相对路径时使用的搜索目录。
64
+ - `variables`:可选的变量值。
65
+ - `respectIgnore`:是否遵守 `.gitignore` 等忽略规则。
66
+ - `searchHidden`:是否搜索隐藏文件和目录。
58
67
 
59
- 需要扫描的文本。
68
+ `directories` 中的目录必须真实存在。
60
69
 
61
- ### `level`
70
+ ## 搜索级别
62
71
 
63
- 搜索等级。等级越高,识别范围越宽,但需要进行的文件系统搜索也越多。
72
+ 级别越高,能够识别更多自然文本中的路径,也可能产生更多文件系统检查。
64
73
 
65
- 可通过以下方式获取当前最高等级:
74
+ 可通过:
66
75
 
67
76
  ```ts
68
77
  import { MAX_LEVEL } from "pathprobe";
69
78
  ```
70
79
 
71
- ### `directories`
80
+ 获取当前最高级别。
72
81
 
73
- 用于解析相对路径的搜索根目录。
82
+ ## 路径位置
74
83
 
75
- ```ts
76
- await findExistingPaths(text, 2, [process.cwd(), "/another/project"]);
77
- ```
78
-
79
- ### `variables`
84
+ 路径后可以附带行号或行列号:
80
85
 
81
- 可选的变量值:
82
-
83
- ```ts
84
- await findExistingPaths("$PROJECT/src/index.ts", 2, [process.cwd()], {
85
- PROJECT: "/home/user/project",
86
- });
86
+ ```text
87
+ src/index.ts:42
88
+ src/index.ts:42:8
87
89
  ```
88
90
 
89
- 支持多种常见写法,例如:
91
+ 匹配结果会包含:
90
92
 
91
- ```text
92
- $HOME/project
93
- ${HOME}/project
94
- $env:HOME/project
95
- %HOME%\project
96
- !HOME!\project
97
- {{ HOME }}/project
98
- ${{ env.HOME }}/project
99
- $(HOME)/project
100
- @HOME@/project
93
+ ```ts
94
+ {
95
+ location: {
96
+ line: 42,
97
+ column: 8,
98
+ }
99
+ }
101
100
  ```
102
101
 
103
- 未显式提供的变量也会尝试从 `process.env` 中读取。
102
+ 同时,`position.start` `position.end` 表示路径在原始文本中的字符范围。
104
103
 
105
- ### `respectIgnore`
104
+ ## 变量展开
106
105
 
107
- 是否遵守 Git ignore 规则及配置的 ignore 文件。
106
+ 可以在文本中使用常见的变量表达式:
108
107
 
109
- 默认值由库配置决定。
108
+ ```text
109
+ $HOME/project/file.txt
110
+ ${HOME}/project/file.txt
111
+ $env:HOME/project/file.txt
112
+ %HOME%\project\file.txt
113
+ {{ HOME }}/project/file.txt
114
+ ${{ env.HOME }}/project/file.txt
115
+ ```
110
116
 
111
- ### `searchHidden`
117
+ 也可以自行提供变量:
112
118
 
113
- 是否搜索隐藏文件和隐藏目录。
119
+ ```ts
120
+ await findExistingPaths("$PROJECT_ROOT/src/index.ts", 2, [process.cwd()], {
121
+ PROJECT_ROOT: "/projects/demo",
122
+ });
123
+ ```
114
124
 
115
- 默认值由库配置决定。
125
+ 未显式提供的变量会尝试从 `process.env` 中读取。
116
126
 
117
- ## 支持的路径形式
127
+ ## Windows / UNC
118
128
 
119
- 例如:
129
+ 在 Windows 上,`pathprobe` 可以处理:
120
130
 
121
131
  ```text
122
- ./src/index.ts
123
- ../config/settings.json
124
- ~/Documents/test.txt
125
- /usr/local/bin/tool
126
- C:\Users\me\project\README.md
127
- \\localhost\share\file.txt
128
- file:///tmp/example.txt
129
- src/index.ts:42
130
- src/index.ts:42:8
131
- "$HOME/My Project/file.txt"
132
+ \\server\share\project\file.txt
132
133
  ```
133
134
 
134
- 路径只有在文件系统中实际存在时才会出现在最终结果中。
135
+ 对于映射到本机盘符的网络共享,以及本机管理共享(如 `\\localhost\C$\...`),会尽可能转换成可由本机文件系统验证的路径。
135
136
 
136
- ## TypeScript 类型
137
+ 无法映射为本地可访问路径的 UNC 地址会被忽略。
137
138
 
138
- 库同时导出:
139
+ ## 返回类型
139
140
 
140
141
  ```ts
141
- import type {
142
- PathKind,
143
- PathLocation,
144
- PathMatch,
145
- PathPosition,
146
- SearchLevel,
147
- Variables,
148
- } from "pathprobe";
142
+ interface PathMatch {
143
+ kind: "file" | "directory";
144
+ path: string;
145
+ position: {
146
+ start: number;
147
+ end: number;
148
+ };
149
+ location?: {
150
+ line: number;
151
+ column?: number;
152
+ };
153
+ }
149
154
  ```
150
155
 
151
- ## 注意事项
152
-
153
- 在 Windows 上,UNC 路径仅会解析指向本机的共享路径,以避免意外访问远程网络位置。
156
+ `pathprobe` 只返回经过文件系统验证、当前真实存在的文件或目录。
package/dist/index.mjs CHANGED
@@ -4,8 +4,10 @@ import { readdir, stat } from "node:fs/promises";
4
4
  import pLimit from "p-limit";
5
5
  import fastGlob from "fast-glob";
6
6
  import { convertPathToPattern, globby } from "globby";
7
+ import { Buffer } from "node:buffer";
7
8
  import { isIP } from "node:net";
8
9
  import { hostname, networkInterfaces } from "node:os";
10
+ import koffi from "koffi";
9
11
  //#region config/settings.ts
10
12
  const settings = {
11
13
  batchValidationThreshold: 48,
@@ -213,6 +215,120 @@ async function classifyExistingPaths(paths, roots) {
213
215
  return found;
214
216
  }
215
217
  //#endregion
218
+ //#region src/unc.ts
219
+ const uncServerSegmentPattern = /^[^\\/:*?"<>|]+$/u;
220
+ const unmappedDriveErrors = /* @__PURE__ */ new Set([
221
+ 1200,
222
+ 1201,
223
+ 1203,
224
+ 1222,
225
+ 2250
226
+ ]);
227
+ const errorMoreData = 234;
228
+ const mappingBufferChars = 32768;
229
+ const getConnectionW = process.platform === "win32" ? koffi.load("mpr.dll").func("uint32_t WNetGetConnectionW(const char16_t *lpLocalName, _Out_ char16_t *lpRemoteName, _Inout_ uint32_t *lpnLength)") : void 0;
230
+ function normalizeServerName(value) {
231
+ return value.replace(/\.+$/u, "").toLowerCase();
232
+ }
233
+ function addLocalServerName(names, value) {
234
+ if (value !== void 0 && uncServerSegmentPattern.test(value)) names.add(normalizeServerName(value));
235
+ }
236
+ function addIpv6LiteralName(names, value) {
237
+ const zoneIndex = value.indexOf("%");
238
+ const address = zoneIndex === -1 ? value : value.slice(0, zoneIndex);
239
+ const zone = zoneIndex === -1 ? "" : `s${value.slice(zoneIndex + 1)}`;
240
+ addLocalServerName(names, `${address.replaceAll(":", "-")}${zone}.ipv6-literal.net`);
241
+ }
242
+ function collectLocalServerNames() {
243
+ const names = /* @__PURE__ */ new Set(["localhost"]);
244
+ const computerName = process.env.COMPUTERNAME;
245
+ addLocalServerName(names, hostname());
246
+ addLocalServerName(names, computerName);
247
+ if (computerName !== void 0 && process.env.USERDNSDOMAIN !== void 0) addLocalServerName(names, `${computerName}.${process.env.USERDNSDOMAIN}`);
248
+ for (const addresses of Object.values(networkInterfaces())) for (const address of addresses ?? []) if (isIP(address.address) === 4) addLocalServerName(names, address.address);
249
+ else if (isIP(address.address) === 6) addIpv6LiteralName(names, address.address);
250
+ addLocalServerName(names, "--1.ipv6-literal.net");
251
+ return names;
252
+ }
253
+ const localServerNames = process.platform === "win32" ? collectLocalServerNames() : /* @__PURE__ */ new Set();
254
+ let driveMappings;
255
+ function containsControlCharacter(value) {
256
+ return [...value].some((character) => character.charCodeAt(0) < 32);
257
+ }
258
+ function normalizeUncRoot(value) {
259
+ return value.replaceAll("/", "\\").replace(/\\+$/u, "").toLowerCase();
260
+ }
261
+ function parseUncPath(value) {
262
+ const normalized = value.replaceAll("/", "\\");
263
+ const extended = normalized.slice(0, 8).toLowerCase() === "\\\\?\\unc\\";
264
+ if (normalized.startsWith("\\\\.\\") || normalized.startsWith("\\\\?\\") && !extended) return;
265
+ const serverStart = extended ? 8 : 2;
266
+ const serverSeparator = normalized.slice(serverStart).indexOf("\\");
267
+ if (serverSeparator <= 0) return;
268
+ const serverEnd = serverStart + serverSeparator;
269
+ const shareStart = serverEnd + 1;
270
+ const shareSeparator = normalized.slice(shareStart).indexOf("\\");
271
+ const shareEnd = shareSeparator === -1 ? normalized.length : shareStart + shareSeparator;
272
+ const server = normalized.slice(serverStart, serverEnd);
273
+ const share = normalized.slice(shareStart, shareEnd);
274
+ if (share.length === 0 || !uncServerSegmentPattern.test(server) || !uncServerSegmentPattern.test(share)) return;
275
+ const suffix = normalized.slice(shareEnd);
276
+ return {
277
+ canonical: `\\\\${server}\\${share}${suffix}`,
278
+ server,
279
+ share,
280
+ suffix
281
+ };
282
+ }
283
+ function queryDriveMapping(drive) {
284
+ if (getConnectionW === void 0) return;
285
+ const buffer = Buffer.alloc(mappingBufferChars * 2);
286
+ const result = getConnectionW(drive, buffer, [mappingBufferChars]);
287
+ if (result === errorMoreData) throw new Error(`WNetGetConnectionW returned an oversized mapping for ${drive}`);
288
+ if (unmappedDriveErrors.has(result)) return;
289
+ if (result !== 0) throw new Error(`WNetGetConnectionW failed for ${drive} with error ${result}`);
290
+ const remote = koffi.decode(buffer, "char16_t", mappingBufferChars);
291
+ if (typeof remote !== "string" || !remote.startsWith("\\\\")) throw new TypeError(`WNetGetConnectionW returned an invalid mapping for ${drive}`);
292
+ return normalizeUncRoot(remote);
293
+ }
294
+ function queryDriveMappings() {
295
+ if (driveMappings !== void 0) return driveMappings;
296
+ const result = [];
297
+ for (let code = "A".charCodeAt(0); code <= "Z".charCodeAt(0); code += 1) {
298
+ const drive = `${String.fromCharCode(code)}:`;
299
+ const remote = queryDriveMapping(drive);
300
+ if (remote !== void 0) result.push({
301
+ drive,
302
+ remote
303
+ });
304
+ }
305
+ driveMappings = result.toSorted((left, right) => right.remote.length - left.remote.length);
306
+ return driveMappings;
307
+ }
308
+ function resolveMappedUncPath(path) {
309
+ const canonical = normalizeUncRoot(path.canonical);
310
+ const mapping = queryDriveMappings().find(({ remote }) => canonical === remote || canonical.startsWith(`${remote}\\`));
311
+ if (mapping === void 0) return;
312
+ const relative = path.canonical.slice(mapping.remote.length);
313
+ return nodePath.win32.normalize(`${mapping.drive}${relative}`);
314
+ }
315
+ function isLocalServer(value) {
316
+ const normalized = normalizeServerName(value);
317
+ return localServerNames.has(normalized) || isIP(value) === 4 && value.split(".")[0] === "127" || normalized === "--1.ipv6-literal.net";
318
+ }
319
+ function resolveLocalAdministrativeShare(path) {
320
+ const match = /^([A-Za-z])\$$/u.exec(path.share);
321
+ if (match === null || !isLocalServer(path.server)) return;
322
+ return nodePath.win32.normalize(`${match[1]}:${path.suffix || "\\"}`);
323
+ }
324
+ function resolveUncPath(value) {
325
+ if (process.platform !== "win32" || !value.startsWith("\\\\") && !value.startsWith("//")) return value;
326
+ if (containsControlCharacter(value)) return;
327
+ const path = parseUncPath(value);
328
+ if (path === void 0) return;
329
+ return resolveMappedUncPath(path) ?? resolveLocalAdministrativeShare(path);
330
+ }
331
+ //#endregion
216
332
  //#region src/policy.ts
217
333
  function pathKey$1(value) {
218
334
  return process.platform === "win32" ? value.toLowerCase() : value;
@@ -249,7 +365,9 @@ async function resolveSearchDirectories(directories) {
249
365
  const unique = /* @__PURE__ */ new Map();
250
366
  for (const directory of directories) {
251
367
  if (typeof directory !== "string" || directory.length === 0) throw new TypeError("every directory must be a non-empty string");
252
- const resolved = nodePath.resolve(directory);
368
+ const resolvedUnc = resolveUncPath(directory);
369
+ if (resolvedUnc === void 0 || resolvedUnc.length === 0) throw new TypeError(`${directory} cannot be represented as a drive-based path`);
370
+ const resolved = nodePath.resolve(resolvedUnc);
253
371
  unique.set(pathKey$1(resolved), resolved);
254
372
  }
255
373
  await Promise.all([...unique.values()].map(async (directory) => {
@@ -293,55 +411,6 @@ async function filterSearchablePaths(paths, roots, respectIgnore, searchHidden)
293
411
  return allowed;
294
412
  }
295
413
  //#endregion
296
- //#region src/unc.ts
297
- const uncServerSegmentPattern = /^[^\\/:*?"<>|]+$/u;
298
- function normalizeServerName(value) {
299
- return value.replace(/\.+$/u, "").toLowerCase();
300
- }
301
- function addLocalServerName(names, value) {
302
- if (value !== void 0 && uncServerSegmentPattern.test(value)) names.add(normalizeServerName(value));
303
- }
304
- function addIpv6LiteralName(names, value) {
305
- const zoneIndex = value.indexOf("%");
306
- const address = zoneIndex === -1 ? value : value.slice(0, zoneIndex);
307
- const zone = zoneIndex === -1 ? "" : `s${value.slice(zoneIndex + 1)}`;
308
- addLocalServerName(names, `${address.replaceAll(":", "-")}${zone}.ipv6-literal.net`);
309
- }
310
- function collectLocalServerNames() {
311
- const names = /* @__PURE__ */ new Set(["localhost"]);
312
- const computerName = process.env.COMPUTERNAME;
313
- addLocalServerName(names, hostname());
314
- addLocalServerName(names, computerName);
315
- if (computerName !== void 0 && process.env.USERDNSDOMAIN !== void 0) addLocalServerName(names, `${computerName}.${process.env.USERDNSDOMAIN}`);
316
- for (const addresses of Object.values(networkInterfaces())) for (const address of addresses ?? []) if (isIP(address.address) === 4) addLocalServerName(names, address.address);
317
- else if (isIP(address.address) === 6) addIpv6LiteralName(names, address.address);
318
- addLocalServerName(names, "--1.ipv6-literal.net");
319
- return names;
320
- }
321
- const localServerNames = collectLocalServerNames();
322
- function containsControlCharacter(value) {
323
- return [...value].some((character) => character.charCodeAt(0) < 32);
324
- }
325
- function resolveLocalUncPath(value) {
326
- if (process.platform !== "win32" || !value.startsWith("\\\\")) return value;
327
- if (containsControlCharacter(value)) return;
328
- const extended = value.slice(0, 8).toLowerCase() === "\\\\?\\unc\\";
329
- if (value.startsWith("\\\\.\\") || value.startsWith("\\\\?\\") && !extended) return;
330
- const serverStart = extended ? 8 : 2;
331
- const serverSeparator = value.slice(serverStart).search(/[\\/]/u);
332
- if (serverSeparator <= 0) return;
333
- const serverEnd = serverStart + serverSeparator;
334
- const shareStart = serverEnd + 1;
335
- const shareSeparator = value.slice(shareStart).search(/[\\/]/u);
336
- const shareEnd = shareSeparator === -1 ? value.length : shareStart + shareSeparator;
337
- const server = value.slice(serverStart, serverEnd);
338
- const share = value.slice(shareStart, shareEnd);
339
- if (share.length === 0 || !uncServerSegmentPattern.test(server) || !uncServerSegmentPattern.test(share)) return;
340
- const normalizedServer = normalizeServerName(server);
341
- if (!(isIP(server) === 4 && server.split(".")[0] === "127" || normalizedServer === "--1.ipv6-literal.net") && !localServerNames.has(normalizedServer)) return;
342
- return `${extended ? "\\\\?\\UNC\\" : "\\\\"}localhost${value.slice(serverEnd)}`;
343
- }
344
- //#endregion
345
414
  //#region src/filesystem.ts
346
415
  function pathKey(value) {
347
416
  return process.platform === "win32" ? value.toLowerCase() : value;
@@ -425,9 +494,9 @@ function toPaths(value, roots, variables) {
425
494
  expanded = unescape(expanded);
426
495
  if (expanded === "~" || /^~[\\/]/u.test(expanded)) expanded = nodePath.join(variables.HOME ?? variables.USERPROFILE ?? process.env.HOME ?? process.env.USERPROFILE ?? "", expanded.slice(2));
427
496
  }
428
- const localUncPath = resolveLocalUncPath(expanded);
429
- if (localUncPath === void 0 || localUncPath.length === 0) return [];
430
- expanded = localUncPath;
497
+ const resolvedPath = resolveUncPath(expanded);
498
+ if (resolvedPath === void 0 || resolvedPath.length === 0) return [];
499
+ expanded = resolvedPath;
431
500
  if (nodePath.isAbsolute(expanded)) return [nodePath.normalize(expanded)];
432
501
  return uniquePaths(roots.map((root) => nodePath.resolve(root, expanded)));
433
502
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["pathKey","pathKey"],"sources":["../config/settings.ts","../src/variables/index.ts","../src/candidates.ts","../src/existence.ts","../src/policy.ts","../src/unc.ts","../src/filesystem.ts","../src/inventory.ts","../src/index.ts"],"sourcesContent":["import type { SearchSettings } from \"../src/types.js\";\n\nexport const settings: SearchSettings = {\n batchValidationThreshold: 48,\n directoryScanThreshold: 2,\n ignoreFilePatterns: [\"**/.ignore\", \"**/.rgignore\"],\n locationSuffixPattern: /:(?<line>\\d+)(?::(?<column>\\d+))?$/u,\n respectIgnoreByDefault: true,\n searchHiddenByDefault: false,\n spanWordLimits: [3, 8, 24],\n trailingPunctuation: \".,;:!?,。;:!?、\",\n validationConcurrency: 32,\n};\n","import type { Variables } from \"../types.js\";\n\nconst nameSource = String.raw`[A-Za-z_][A-Za-z0-9_.-]*`;\nexport const variableReferenceSource = String.raw`(?:\\$\\{\\{\\s*(?:(?:env|vars|variables)[.:])?${nameSource}\\s*\\}\\}|\\{\\{\\s*${nameSource}\\s*\\}\\}|\\$\\{(?:env[.:])?${nameSource}\\}|\\$env:${nameSource}|\\$[A-Za-z_][A-Za-z0-9_]*|%${nameSource}%|!${nameSource}!|\\$\\(\\s*${nameSource}\\s*\\)|@${nameSource}@)`;\nconst expressionPatterns = [\n new RegExp(String.raw`\\$\\{\\{\\s*(?:(?:env|vars|variables)[.:])?(${nameSource})\\s*\\}\\}`, \"giu\"),\n new RegExp(String.raw`\\{\\{\\s*(${nameSource})\\s*\\}\\}`, \"gu\"),\n new RegExp(String.raw`\\$\\{(?:env[.:])?(${nameSource})\\}`, \"giu\"),\n new RegExp(String.raw`\\$env:(${nameSource})`, \"giu\"),\n new RegExp(String.raw`\\$(?!env:)([A-Za-z_][A-Za-z0-9_]*)`, \"giu\"),\n new RegExp(String.raw`%(${nameSource})%`, \"gu\"),\n new RegExp(String.raw`!(${nameSource})!`, \"gu\"),\n new RegExp(String.raw`\\$\\(\\s*(${nameSource})\\s*\\)`, \"gu\"),\n new RegExp(String.raw`@(${nameSource})@`, \"gu\"),\n];\nfunction resolveVariable(name: string, variables: Variables): string | undefined {\n const direct = variables[name] ?? process.env[name];\n if (direct !== undefined) {\n return direct;\n }\n const unscoped = /^(?:env|vars|variables)[.:](.+)$/iu.exec(name)?.[1];\n return unscoped === undefined ? undefined : (variables[unscoped] ?? process.env[unscoped]);\n}\nexport function expandVariables(value: string, variables: Variables): string {\n let result = value;\n for (const pattern of expressionPatterns) {\n result = result.replace(pattern, (match, name: string) => {\n const replacement = resolveVariable(name, variables);\n return replacement === undefined ? match : replacement;\n });\n }\n return result;\n}\n","import type { Candidate, SearchLevel } from \"./types.js\";\nimport { settings } from \"../config/settings.js\";\nimport { variableReferenceSource } from \"./variables/index.js\";\n\nconst explicitPattern =\n /(?:file:\\/\\/\\/?|[A-Za-z]:[\\\\/]|\\\\\\\\|\\/|(?:\\.{1,2}|~)[\\\\/])[^\"'`<>()[\\]{}\\s]+/gu;\nconst quotedPattern = /([\"'`])(?<value>[^\"'`\\r\\n]+)\\1/gu;\nconst tokenPattern = /[^\\s]+/gu;\nconst pathTokenPattern =\n /(?:(?:[\\p{L}\\p{N}_@%$+~.#[\\],-]+[\\\\/])+(?:[\\p{L}\\p{N}_@%$+~.#[\\],-]+)|[\\p{L}\\p{N}_@%$+~.#[\\],-]+\\.[\\p{L}\\p{N}_@%$-]{1,16})(?::\\d+){0,2}/gu;\nconst unquotedPathCharacterSource = \"[^\\\"'`<>()[\\\\]{}\\\\s]\";\nconst variablePathPattern = new RegExp(\n `${variableReferenceSource}(?:[\\\\\\\\/]${unquotedPathCharacterSource}+)+`,\n \"giu\",\n);\nconst clausePattern = /[^\\r\\n!?!?;;。]+/gu;\nconst pathHintPattern =\n /[\\\\/]|(?:^|[\\s\"'`])(?:\\.{1,2}|~|%[A-Za-z_][A-Za-z0-9_]*%|\\$\\{?[A-Za-z_][A-Za-z0-9_]*\\}?)(?:[\\\\/]|$)|\\.[\\p{L}\\p{N}]{1,16}(?::\\d+){0,2}(?:$|[\\s,.;:!?,。;:!?、])/u;\nconst variableHintPattern = new RegExp(String.raw`${variableReferenceSource}(?:[\\\\/]|$)`, \"iu\");\nfunction add(\n result: Candidate[],\n seen: Set<string>,\n value: string,\n start: number,\n end: number,\n kind: Candidate[\"kind\"],\n): void {\n if (value.length === 0) {\n return;\n }\n const key = `${start}:${end}:${value}`;\n if (!seen.has(key)) {\n seen.add(key);\n result.push({ end, kind, start, value });\n }\n}\nfunction addMatches(\n result: Candidate[],\n seen: Set<string>,\n text: string,\n pattern: RegExp,\n kind: Candidate[\"kind\"],\n): void {\n for (const match of text.matchAll(pattern)) {\n const value = match[0];\n const start = match.index ?? 0;\n add(result, seen, value, start, start + value.length, kind);\n }\n}\nfunction addQuotedMatches(result: Candidate[], seen: Set<string>, text: string): void {\n for (const match of text.matchAll(quotedPattern)) {\n const value = match.groups?.value;\n if (value === undefined) {\n continue;\n }\n const start = (match.index ?? 0) + match[0].indexOf(value);\n add(result, seen, value, start, start + value.length, \"quoted\");\n }\n}\nfunction addSpanMatches(\n result: Candidate[],\n seen: Set<string>,\n text: string,\n maximumWords: number,\n): void {\n for (const clause of text.matchAll(clausePattern)) {\n const clauseStart = clause.index ?? 0;\n const clauseText = clause[0];\n const tokens = [...clauseText.matchAll(tokenPattern)].map((token) => ({\n end: clauseStart + (token.index ?? 0) + token[0].length,\n hint: Number(pathHintPattern.test(token[0]) || variableHintPattern.test(token[0])),\n start: clauseStart + (token.index ?? 0),\n value: token[0],\n }));\n const hintCounts = [0];\n for (const token of tokens) {\n hintCounts.push((hintCounts.at(-1) ?? 0) + token.hint);\n }\n for (let start = 0; start < tokens.length; start += 1) {\n const last = Math.min(tokens.length, start + maximumWords);\n for (let end = start + 1; end <= last; end += 1) {\n const firstToken = tokens[start];\n const lastToken = tokens[end - 1];\n const hintsBefore = hintCounts[start];\n const hintsAfter = hintCounts[end];\n if (\n firstToken === undefined ||\n lastToken === undefined ||\n hintsBefore === undefined ||\n hintsAfter === undefined ||\n hintsBefore === hintsAfter\n ) {\n continue;\n }\n const value = text.slice(firstToken.start, lastToken.end);\n if (pathHintPattern.test(value)) {\n add(result, seen, value, firstToken.start, lastToken.end, \"span\");\n }\n }\n }\n }\n}\nexport function extractCandidates(text: string, level: SearchLevel): Candidate[] {\n const result: Candidate[] = [];\n const seen = new Set<string>();\n addQuotedMatches(result, seen, text);\n addMatches(result, seen, text, explicitPattern, \"explicit\");\n if (level >= 2) {\n addMatches(result, seen, text, variablePathPattern, \"heuristic\");\n addMatches(result, seen, text, pathTokenPattern, \"heuristic\");\n }\n if (level >= 3) {\n const maximumWords =\n settings.spanWordLimits[Math.min(level - 3, settings.spanWordLimits.length - 1)];\n if (maximumWords === undefined) {\n throw new RangeError(\"No text-span level is configured\");\n }\n addSpanMatches(result, seen, text, maximumWords);\n }\n return result;\n}\n","import { readdir, stat } from \"node:fs/promises\";\nimport nodePath from \"node:path\";\nimport pLimit from \"p-limit\";\nimport { settings } from \"../config/settings.js\";\nimport type { PathKind } from \"./types.js\";\n\nconst knownFileErrors = new Set([\n \"EACCES\",\n \"ELOOP\",\n \"ENAMETOOLONG\",\n \"ENOTDIR\",\n \"ENOENT\",\n \"EPERM\",\n \"EINVAL\",\n]);\nconst unverifiableUncErrors = new Set([\"UNKNOWN\", \"EUNKNOWN\"]);\nfunction pathKey(value: string): string {\n return process.platform === \"win32\" ? value.toLowerCase() : value;\n}\nfunction fileErrorCode(error: unknown): string | undefined {\n if (error instanceof Error && \"code\" in error && typeof error.code === \"string\") {\n return error.code;\n }\n return undefined;\n}\nfunction isKnownFileError(error: unknown, filePath?: string): boolean {\n const code = fileErrorCode(error);\n return (\n code !== undefined &&\n (knownFileErrors.has(code) ||\n (filePath?.startsWith(\"\\\\\\\\\") === true && unverifiableUncErrors.has(code)))\n );\n}\nasync function classifyPath(filePath: string): Promise<PathKind | undefined> {\n try {\n const pathStats = await stat(filePath);\n if (pathStats.isFile()) {\n return \"file\";\n }\n return pathStats.isDirectory() ? \"directory\" : undefined;\n } catch (error) {\n if (isKnownFileError(error, filePath)) {\n return undefined;\n }\n throw error;\n }\n}\nasync function classifyAndAdd(found: Map<string, PathKind>, filePath: string): Promise<void> {\n const kind = await classifyPath(filePath);\n if (kind !== undefined) {\n found.set(filePath, kind);\n }\n}\nexport async function classifyExistingPaths(\n paths: readonly string[],\n roots: readonly string[],\n): Promise<Map<string, PathKind>> {\n const found = new Map<string, PathKind>();\n const limit = pLimit(settings.validationConcurrency);\n if (paths.length < settings.batchValidationThreshold) {\n await Promise.all(paths.map((filePath) => limit(() => classifyAndAdd(found, filePath))));\n return found;\n }\n const rootKeys = new Set(roots.map(pathKey));\n const pathsByParent = new Map<string, { parent: string; paths: string[] }>();\n for (const filePath of paths) {\n if (rootKeys.has(pathKey(filePath))) {\n found.set(filePath, \"directory\");\n continue;\n }\n const parent = nodePath.dirname(filePath);\n const key = pathKey(parent);\n const group = pathsByParent.get(key) ?? { parent, paths: [] };\n group.paths.push(filePath);\n pathsByParent.set(key, group);\n }\n const directPaths: string[] = [];\n const scannedGroups: { parent: string; paths: string[] }[] = [];\n for (const group of pathsByParent.values()) {\n if (group.paths.length < settings.directoryScanThreshold) {\n directPaths.push(...group.paths);\n } else {\n scannedGroups.push(group);\n }\n }\n await Promise.all([\n ...directPaths.map((filePath) => limit(() => classifyAndAdd(found, filePath))),\n ...scannedGroups.map(({ parent, paths: groupPaths }) =>\n limit(async () => {\n let entries;\n try {\n entries = await readdir(parent, { withFileTypes: true });\n } catch (error) {\n if (isKnownFileError(error, parent)) {\n return;\n }\n throw error;\n }\n const entriesByName = new Map(entries.map((entry) => [pathKey(entry.name), entry]));\n await Promise.all(\n groupPaths.map(async (filePath) => {\n const name = nodePath.basename(filePath);\n const entry = entriesByName.get(pathKey(name));\n if (entry?.isFile()) {\n found.set(filePath, \"file\");\n } else if (entry?.isDirectory()) {\n found.set(filePath, \"directory\");\n } else if (\n entry !== undefined ||\n (process.platform === \"win32\" && name.includes(\":\"))\n ) {\n await classifyAndAdd(found, filePath);\n }\n }),\n );\n }),\n ),\n ]);\n return found;\n}\n","import { stat } from \"node:fs/promises\";\nimport nodePath from \"node:path\";\nimport fastGlob from \"fast-glob\";\nimport { convertPathToPattern, globby } from \"globby\";\nimport { settings } from \"../config/settings.js\";\n\nfunction pathKey(value: string): string {\n return process.platform === \"win32\" ? value.toLowerCase() : value;\n}\nfunction isWithinRoot(filePath: string, root: string): boolean {\n const relative = nodePath.relative(root, filePath);\n return (\n relative === \"\" ||\n (relative !== \"..\" &&\n !relative.startsWith(`..${nodePath.sep}`) &&\n !nodePath.isAbsolute(relative))\n );\n}\nfunction isHidden(relativePath: string): boolean {\n return relativePath.split(/[\\\\/]/u).some((part) => part.length > 1 && part.startsWith(\".\"));\n}\nfunction traversalOptions(root: string, searchHidden: boolean) {\n return {\n caseSensitiveMatch: process.platform !== \"win32\",\n cwd: root,\n dot: searchHidden,\n followSymbolicLinks: false,\n onlyFiles: false,\n unique: true,\n } as const;\n}\nfunction globbyOptions(root: string, respectIgnore: boolean, searchHidden: boolean) {\n return {\n ...traversalOptions(root, searchHidden),\n expandDirectories: false,\n gitignore: respectIgnore,\n globalGitignore: respectIgnore,\n ...(respectIgnore ? { ignoreFiles: settings.ignoreFilePatterns } : {}),\n } as const;\n}\nexport async function resolveSearchDirectories(directories: readonly string[]): Promise<string[]> {\n if (!Array.isArray(directories)) {\n throw new TypeError(\"directories must be an array\");\n }\n if (directories.length === 0) {\n throw new RangeError(\"directories must not be empty\");\n }\n const unique = new Map<string, string>();\n for (const directory of directories) {\n if (typeof directory !== \"string\" || directory.length === 0) {\n throw new TypeError(\"every directory must be a non-empty string\");\n }\n const resolved = nodePath.resolve(directory);\n unique.set(pathKey(resolved), resolved);\n }\n await Promise.all(\n [...unique.values()].map(async (directory) => {\n if (!(await stat(directory)).isDirectory()) {\n throw new TypeError(`${directory} is not a directory`);\n }\n }),\n );\n return [...unique.values()];\n}\nexport async function listSearchEntries(\n root: string,\n respectIgnore: boolean,\n searchHidden: boolean,\n): Promise<string[]> {\n if (!respectIgnore) {\n return fastGlob(\"**/*\", traversalOptions(root, searchHidden));\n }\n return globby(\"**/*\", globbyOptions(root, respectIgnore, searchHidden));\n}\nexport async function filterSearchablePaths(\n paths: readonly string[],\n roots: readonly string[],\n respectIgnore: boolean,\n searchHidden: boolean,\n): Promise<Set<string>> {\n const allowed = new Set<string>();\n const pathsByRoot = new Map<string, string[]>();\n for (const filePath of paths) {\n let hasSearchRoot = false;\n for (const root of roots) {\n if (!isWithinRoot(filePath, root)) {\n continue;\n }\n hasSearchRoot = true;\n const relative = nodePath.relative(root, filePath);\n if (!searchHidden && isHidden(relative)) {\n continue;\n }\n if (relative === \"\" || !respectIgnore) {\n allowed.add(filePath);\n } else {\n const grouped = pathsByRoot.get(root) ?? [];\n grouped.push(relative);\n pathsByRoot.set(root, grouped);\n }\n }\n if (hasSearchRoot) {\n continue;\n }\n const filesystemRelative = nodePath.relative(nodePath.parse(filePath).root, filePath);\n if (searchHidden || !isHidden(filesystemRelative)) {\n allowed.add(filePath);\n }\n }\n await Promise.all(\n [...pathsByRoot].map(async ([root, relativePaths]) => {\n const patterns = relativePaths.map(convertPathToPattern);\n const matches = await globby(patterns, {\n ...globbyOptions(root, true, true),\n absolute: true,\n });\n for (const match of matches) {\n allowed.add(nodePath.normalize(match));\n }\n }),\n );\n return allowed;\n}\n","import { isIP } from \"node:net\";\nimport { hostname, networkInterfaces } from \"node:os\";\n\nconst uncServerSegmentPattern = /^[^\\\\/:*?\"<>|]+$/u;\nfunction normalizeServerName(value: string): string {\n return value.replace(/\\.+$/u, \"\").toLowerCase();\n}\nfunction addLocalServerName(names: Set<string>, value: string | undefined): void {\n if (value !== undefined && uncServerSegmentPattern.test(value)) {\n names.add(normalizeServerName(value));\n }\n}\nfunction addIpv6LiteralName(names: Set<string>, value: string): void {\n const zoneIndex = value.indexOf(\"%\");\n const address = zoneIndex === -1 ? value : value.slice(0, zoneIndex);\n const zone = zoneIndex === -1 ? \"\" : `s${value.slice(zoneIndex + 1)}`;\n addLocalServerName(names, `${address.replaceAll(\":\", \"-\")}${zone}.ipv6-literal.net`);\n}\nfunction collectLocalServerNames(): Set<string> {\n const names = new Set<string>([\"localhost\"]);\n const computerName = process.env.COMPUTERNAME;\n addLocalServerName(names, hostname());\n addLocalServerName(names, computerName);\n if (computerName !== undefined && process.env.USERDNSDOMAIN !== undefined) {\n addLocalServerName(names, `${computerName}.${process.env.USERDNSDOMAIN}`);\n }\n for (const addresses of Object.values(networkInterfaces())) {\n for (const address of addresses ?? []) {\n if (isIP(address.address) === 4) {\n addLocalServerName(names, address.address);\n } else if (isIP(address.address) === 6) {\n addIpv6LiteralName(names, address.address);\n }\n }\n }\n addLocalServerName(names, \"--1.ipv6-literal.net\");\n return names;\n}\nconst localServerNames = collectLocalServerNames();\nfunction containsControlCharacter(value: string): boolean {\n return [...value].some((character) => character.charCodeAt(0) < 32);\n}\nexport function resolveLocalUncPath(value: string): string | undefined {\n if (process.platform !== \"win32\" || !value.startsWith(\"\\\\\\\\\")) {\n return value;\n }\n if (containsControlCharacter(value)) {\n return undefined;\n }\n const extended = value.slice(0, 8).toLowerCase() === \"\\\\\\\\?\\\\unc\\\\\";\n if (value.startsWith(\"\\\\\\\\.\\\\\") || (value.startsWith(\"\\\\\\\\?\\\\\") && !extended)) {\n return undefined;\n }\n const serverStart = extended ? 8 : 2;\n const serverSeparator = value.slice(serverStart).search(/[\\\\/]/u);\n if (serverSeparator <= 0) {\n return undefined;\n }\n const serverEnd = serverStart + serverSeparator;\n const shareStart = serverEnd + 1;\n const shareSeparator = value.slice(shareStart).search(/[\\\\/]/u);\n const shareEnd = shareSeparator === -1 ? value.length : shareStart + shareSeparator;\n const server = value.slice(serverStart, serverEnd);\n const share = value.slice(shareStart, shareEnd);\n if (\n share.length === 0 ||\n !uncServerSegmentPattern.test(server) ||\n !uncServerSegmentPattern.test(share)\n ) {\n return undefined;\n }\n const normalizedServer = normalizeServerName(server);\n const isLoopback =\n (isIP(server) === 4 && server.split(\".\")[0] === \"127\") ||\n normalizedServer === \"--1.ipv6-literal.net\";\n if (!isLoopback && !localServerNames.has(normalizedServer)) {\n return undefined;\n }\n const prefix = extended ? \"\\\\\\\\?\\\\UNC\\\\\" : \"\\\\\\\\\";\n return `${prefix}localhost${value.slice(serverEnd)}`;\n}\n","import { fileURLToPath } from \"node:url\";\nimport nodePath from \"node:path\";\nimport { classifyExistingPaths } from \"./existence.js\";\nimport { filterSearchablePaths } from \"./policy.js\";\nimport { expandVariables } from \"./variables/index.js\";\nimport { resolveLocalUncPath } from \"./unc.js\";\nimport { settings } from \"../config/settings.js\";\nimport type { Candidate, PathLocation, PathMatch, PathPosition, Variables } from \"./types.js\";\n\ninterface ResolvedCandidate {\n location?: PathLocation;\n path: string;\n position: PathPosition;\n}\ninterface PreparedCandidate {\n location?: PathLocation;\n position: PathPosition;\n value: string;\n}\nfunction pathKey(value: string): string {\n return process.platform === \"win32\" ? value.toLowerCase() : value;\n}\nfunction uniquePaths(values: Iterable<string>): string[] {\n const paths = new Map<string, string>();\n for (const value of values) {\n paths.set(pathKey(value), value);\n }\n return [...paths.values()];\n}\nfunction parseLocationPart(value: string, name: string): number {\n const result = Number(value);\n if (!Number.isSafeInteger(result)) {\n throw new RangeError(`${name} must be a safe integer`);\n }\n return result;\n}\nfunction prepareCandidate(candidate: Candidate): PreparedCandidate {\n let end = candidate.end;\n let start = candidate.start;\n let value = candidate.value;\n if (candidate.kind !== \"inventory\" && candidate.kind !== \"quoted\") {\n const startTrimmed = value.trimStart();\n start += value.length - startTrimmed.length;\n value = startTrimmed;\n const endTrimmed = value.trimEnd();\n end -= value.length - endTrimmed.length;\n value = endTrimmed;\n if (\n value.length >= 2 &&\n ((value[0] === '\"' && value.at(-1) === '\"') ||\n (value[0] === \"'\" && value.at(-1) === \"'\") ||\n (value[0] === \"`\" && value.at(-1) === \"`\"))\n ) {\n start += 1;\n end -= 1;\n value = value.slice(1, -1);\n }\n while (value.length > 0 && settings.trailingPunctuation.includes(value.at(-1) ?? \"\")) {\n end -= 1;\n value = value.slice(0, -1);\n }\n }\n if (candidate.kind === \"inventory\") {\n return { position: { end, start }, value };\n }\n const match = settings.locationSuffixPattern.exec(value);\n if (match === null) {\n return { position: { end, start }, value };\n }\n const lineValue = match.groups?.line;\n if (lineValue === undefined) {\n throw new TypeError(\"locationSuffixPattern must capture a line\");\n }\n const columnValue = match.groups?.column;\n const location: PathLocation =\n columnValue === undefined\n ? { line: parseLocationPart(lineValue, \"line\") }\n : {\n column: parseLocationPart(columnValue, \"column\"),\n line: parseLocationPart(lineValue, \"line\"),\n };\n end -= match[0].length;\n return {\n location,\n position: { end, start },\n value: value.slice(0, match.index),\n };\n}\nfunction unescape(value: string): string {\n if (value.startsWith(\"\\\\\\\\\") && !value.startsWith(\"\\\\\\\\\\\\\\\\\")) {\n return value;\n }\n return value.replace(/\\\\([\"'`\\\\])/gu, \"$1\").replace(/\\\\\\\\/gu, \"\\\\\");\n}\nfunction toPaths(value: string, roots: readonly string[], variables: Variables): string[] {\n let expanded = expandVariables(value, variables);\n if (expanded.startsWith(\"file://\")) {\n try {\n expanded = fileURLToPath(expanded);\n } catch (error) {\n if (error instanceof TypeError) {\n return [];\n }\n throw error;\n }\n } else {\n expanded = unescape(expanded);\n if (expanded === \"~\" || /^~[\\\\/]/u.test(expanded)) {\n expanded = nodePath.join(\n variables.HOME ??\n variables.USERPROFILE ??\n process.env.HOME ??\n process.env.USERPROFILE ??\n \"\",\n expanded.slice(2),\n );\n }\n }\n const localUncPath = resolveLocalUncPath(expanded);\n if (localUncPath === undefined || localUncPath.length === 0) {\n return [];\n }\n expanded = localUncPath;\n if (nodePath.isAbsolute(expanded)) {\n return [nodePath.normalize(expanded)];\n }\n return uniquePaths(roots.map((root) => nodePath.resolve(root, expanded)));\n}\nfunction mergeLocation(match: PathMatch, location: PathLocation | undefined): void {\n if (location === undefined) {\n return;\n }\n if (match.location === undefined) {\n match.location = location;\n return;\n }\n if (match.location.line !== location.line || match.location.column !== location.column) {\n throw new Error(\"Candidates for the same path and position have conflicting locations\");\n }\n}\nexport async function validateCandidates(\n candidates: Candidate[],\n roots: readonly string[],\n variables: Variables,\n respectIgnore: boolean,\n searchHidden: boolean,\n): Promise<PathMatch[]> {\n const resolvedCandidates: ResolvedCandidate[] = [];\n const validationPaths = new Map<string, string>();\n for (const candidate of candidates) {\n const prepared = prepareCandidate(candidate);\n const paths = toPaths(prepared.value, roots, variables);\n for (const filePath of paths) {\n resolvedCandidates.push({\n ...(prepared.location === undefined ? {} : { location: prepared.location }),\n path: filePath,\n position: prepared.position,\n });\n validationPaths.set(pathKey(filePath), filePath);\n }\n }\n let searchablePaths = [...validationPaths.values()];\n if (respectIgnore || !searchHidden) {\n searchablePaths = [\n ...(await filterSearchablePaths(searchablePaths, roots, respectIgnore, searchHidden)),\n ];\n }\n const classifiedPaths = await classifyExistingPaths(searchablePaths, roots);\n const kindsByPath = new Map(\n [...classifiedPaths].map(([filePath, kind]) => [pathKey(filePath), kind]),\n );\n const matches = new Map<string, PathMatch>();\n for (const { location, path, position } of resolvedCandidates) {\n const kind = kindsByPath.get(pathKey(path));\n if (kind === undefined) {\n continue;\n }\n const key = `${pathKey(path)}\\0${position.start}\\0${position.end}`;\n const existing = matches.get(key);\n if (existing !== undefined) {\n mergeLocation(existing, location);\n continue;\n }\n matches.set(key, {\n kind,\n ...(location === undefined ? {} : { location }),\n path,\n position,\n });\n }\n return [...matches.values()];\n}\n","import nodePath from \"node:path\";\nimport { listSearchEntries } from \"./policy.js\";\nimport type { Candidate } from \"./types.js\";\n\nfunction isBoundary(value: string | undefined, following: string | undefined): boolean {\n if (value === \".\") {\n return following === undefined || !/[\\p{L}\\p{N}_-]/u.test(following);\n }\n return value === undefined || !/[\\p{L}\\p{N}_/\\\\-]/u.test(value);\n}\nfunction addOccurrences(\n result: Candidate[],\n seen: Set<string>,\n source: string,\n text: string,\n value: string,\n): void {\n const target = process.platform === \"win32\" ? value.toLowerCase() : value;\n let offset = source.indexOf(target);\n while (offset !== -1) {\n const end = offset + target.length;\n if (isBoundary(text[offset - 1], text[offset]) && isBoundary(text[end], text[end + 1])) {\n const key = `${offset}:${end}:${text.slice(offset, end)}`;\n if (!seen.has(key)) {\n seen.add(key);\n result.push({\n end,\n kind: \"inventory\",\n start: offset,\n value,\n });\n }\n }\n offset = source.indexOf(target, offset + 1);\n }\n}\nexport async function inventoryCandidates(\n text: string,\n roots: readonly string[],\n respectIgnore: boolean,\n searchHidden: boolean,\n): Promise<Candidate[]> {\n const entries = await Promise.all(\n roots.map((root) => listSearchEntries(root, respectIgnore, searchHidden)),\n );\n const result: Candidate[] = [];\n const seen = new Set<string>();\n const scanned = new Set<string>();\n const source = process.platform === \"win32\" ? text.toLowerCase() : text;\n for (const [rootIndex, relativeEntries] of entries.entries()) {\n const root = roots[rootIndex];\n if (root === undefined) {\n continue;\n }\n for (const relativeEntry of relativeEntries) {\n const absoluteEntry = nodePath.resolve(root, relativeEntry);\n const variants = [\n relativeEntry,\n relativeEntry.replaceAll(\"/\", nodePath.sep),\n absoluteEntry,\n absoluteEntry.replaceAll(nodePath.sep, \"/\"),\n ];\n for (const value of variants) {\n const key = process.platform === \"win32\" ? value.toLowerCase() : value;\n if (!scanned.has(key)) {\n scanned.add(key);\n addOccurrences(result, seen, source, text, value);\n }\n }\n }\n }\n return result;\n}\n","import { extractCandidates } from \"./candidates.js\";\nimport { validateCandidates } from \"./filesystem.js\";\nimport { inventoryCandidates } from \"./inventory.js\";\nimport { resolveSearchDirectories } from \"./policy.js\";\nimport { settings } from \"../config/settings.js\";\nimport type { PathMatch, SearchLevel, Variables } from \"./types.js\";\n\nexport const MAX_LEVEL = settings.spanWordLimits.length + 3;\nfunction validateVariables(value: unknown): asserts value is Variables {\n if (\n typeof value !== \"object\" ||\n value === null ||\n Array.isArray(value) ||\n Object.values(value).some((item) => typeof item !== \"string\")\n ) {\n throw new TypeError(\"variables must be an object of string values\");\n }\n}\nexport async function findExistingPaths(\n text: string,\n level: SearchLevel,\n directories: readonly string[],\n variables: Variables = {},\n respectIgnore: boolean = settings.respectIgnoreByDefault,\n searchHidden: boolean = settings.searchHiddenByDefault,\n): Promise<PathMatch[]> {\n if (typeof text !== \"string\") {\n throw new TypeError(\"text must be a string\");\n }\n if (!Number.isInteger(level) || level < 1 || level > MAX_LEVEL) {\n throw new RangeError(`level must be an integer from 1 to ${MAX_LEVEL}`);\n }\n validateVariables(variables);\n if (typeof respectIgnore !== \"boolean\") {\n throw new TypeError(\"respectIgnore must be a boolean\");\n }\n if (typeof searchHidden !== \"boolean\") {\n throw new TypeError(\"searchHidden must be a boolean\");\n }\n const roots = await resolveSearchDirectories(directories);\n const candidates = extractCandidates(text, level);\n if (level === MAX_LEVEL) {\n candidates.push(...(await inventoryCandidates(text, roots, respectIgnore, searchHidden)));\n }\n return validateCandidates(candidates, roots, variables, respectIgnore, searchHidden);\n}\nexport type {\n PathKind,\n PathLocation,\n PathMatch,\n PathPosition,\n SearchLevel,\n Variables,\n} from \"./types.js\";\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":["pathKey","pathKey"],"sources":["../config/settings.ts","../src/variables/index.ts","../src/candidates.ts","../src/existence.ts","../src/unc.ts","../src/policy.ts","../src/filesystem.ts","../src/inventory.ts","../src/index.ts"],"sourcesContent":["import type { SearchSettings } from \"../src/types.js\";\n\nexport const settings: SearchSettings = {\n batchValidationThreshold: 48,\n directoryScanThreshold: 2,\n ignoreFilePatterns: [\"**/.ignore\", \"**/.rgignore\"],\n locationSuffixPattern: /:(?<line>\\d+)(?::(?<column>\\d+))?$/u,\n respectIgnoreByDefault: true,\n searchHiddenByDefault: false,\n spanWordLimits: [3, 8, 24],\n trailingPunctuation: \".,;:!?,。;:!?、\",\n validationConcurrency: 32,\n};\n","import type { Variables } from \"../types.js\";\n\nconst nameSource = String.raw`[A-Za-z_][A-Za-z0-9_.-]*`;\nexport const variableReferenceSource = String.raw`(?:\\$\\{\\{\\s*(?:(?:env|vars|variables)[.:])?${nameSource}\\s*\\}\\}|\\{\\{\\s*${nameSource}\\s*\\}\\}|\\$\\{(?:env[.:])?${nameSource}\\}|\\$env:${nameSource}|\\$[A-Za-z_][A-Za-z0-9_]*|%${nameSource}%|!${nameSource}!|\\$\\(\\s*${nameSource}\\s*\\)|@${nameSource}@)`;\nconst expressionPatterns = [\n new RegExp(String.raw`\\$\\{\\{\\s*(?:(?:env|vars|variables)[.:])?(${nameSource})\\s*\\}\\}`, \"giu\"),\n new RegExp(String.raw`\\{\\{\\s*(${nameSource})\\s*\\}\\}`, \"gu\"),\n new RegExp(String.raw`\\$\\{(?:env[.:])?(${nameSource})\\}`, \"giu\"),\n new RegExp(String.raw`\\$env:(${nameSource})`, \"giu\"),\n new RegExp(String.raw`\\$(?!env:)([A-Za-z_][A-Za-z0-9_]*)`, \"giu\"),\n new RegExp(String.raw`%(${nameSource})%`, \"gu\"),\n new RegExp(String.raw`!(${nameSource})!`, \"gu\"),\n new RegExp(String.raw`\\$\\(\\s*(${nameSource})\\s*\\)`, \"gu\"),\n new RegExp(String.raw`@(${nameSource})@`, \"gu\"),\n];\nfunction resolveVariable(name: string, variables: Variables): string | undefined {\n const direct = variables[name] ?? process.env[name];\n if (direct !== undefined) {\n return direct;\n }\n const unscoped = /^(?:env|vars|variables)[.:](.+)$/iu.exec(name)?.[1];\n return unscoped === undefined ? undefined : (variables[unscoped] ?? process.env[unscoped]);\n}\nexport function expandVariables(value: string, variables: Variables): string {\n let result = value;\n for (const pattern of expressionPatterns) {\n result = result.replace(pattern, (match, name: string) => {\n const replacement = resolveVariable(name, variables);\n return replacement === undefined ? match : replacement;\n });\n }\n return result;\n}\n","import type { Candidate, SearchLevel } from \"./types.js\";\nimport { settings } from \"../config/settings.js\";\nimport { variableReferenceSource } from \"./variables/index.js\";\n\nconst explicitPattern =\n /(?:file:\\/\\/\\/?|[A-Za-z]:[\\\\/]|\\\\\\\\|\\/|(?:\\.{1,2}|~)[\\\\/])[^\"'`<>()[\\]{}\\s]+/gu;\nconst quotedPattern = /([\"'`])(?<value>[^\"'`\\r\\n]+)\\1/gu;\nconst tokenPattern = /[^\\s]+/gu;\nconst pathTokenPattern =\n /(?:(?:[\\p{L}\\p{N}_@%$+~.#[\\],-]+[\\\\/])+(?:[\\p{L}\\p{N}_@%$+~.#[\\],-]+)|[\\p{L}\\p{N}_@%$+~.#[\\],-]+\\.[\\p{L}\\p{N}_@%$-]{1,16})(?::\\d+){0,2}/gu;\nconst unquotedPathCharacterSource = \"[^\\\"'`<>()[\\\\]{}\\\\s]\";\nconst variablePathPattern = new RegExp(\n `${variableReferenceSource}(?:[\\\\\\\\/]${unquotedPathCharacterSource}+)+`,\n \"giu\",\n);\nconst clausePattern = /[^\\r\\n!?!?;;。]+/gu;\nconst pathHintPattern =\n /[\\\\/]|(?:^|[\\s\"'`])(?:\\.{1,2}|~|%[A-Za-z_][A-Za-z0-9_]*%|\\$\\{?[A-Za-z_][A-Za-z0-9_]*\\}?)(?:[\\\\/]|$)|\\.[\\p{L}\\p{N}]{1,16}(?::\\d+){0,2}(?:$|[\\s,.;:!?,。;:!?、])/u;\nconst variableHintPattern = new RegExp(String.raw`${variableReferenceSource}(?:[\\\\/]|$)`, \"iu\");\nfunction add(\n result: Candidate[],\n seen: Set<string>,\n value: string,\n start: number,\n end: number,\n kind: Candidate[\"kind\"],\n): void {\n if (value.length === 0) {\n return;\n }\n const key = `${start}:${end}:${value}`;\n if (!seen.has(key)) {\n seen.add(key);\n result.push({ end, kind, start, value });\n }\n}\nfunction addMatches(\n result: Candidate[],\n seen: Set<string>,\n text: string,\n pattern: RegExp,\n kind: Candidate[\"kind\"],\n): void {\n for (const match of text.matchAll(pattern)) {\n const value = match[0];\n const start = match.index ?? 0;\n add(result, seen, value, start, start + value.length, kind);\n }\n}\nfunction addQuotedMatches(result: Candidate[], seen: Set<string>, text: string): void {\n for (const match of text.matchAll(quotedPattern)) {\n const value = match.groups?.value;\n if (value === undefined) {\n continue;\n }\n const start = (match.index ?? 0) + match[0].indexOf(value);\n add(result, seen, value, start, start + value.length, \"quoted\");\n }\n}\nfunction addSpanMatches(\n result: Candidate[],\n seen: Set<string>,\n text: string,\n maximumWords: number,\n): void {\n for (const clause of text.matchAll(clausePattern)) {\n const clauseStart = clause.index ?? 0;\n const clauseText = clause[0];\n const tokens = [...clauseText.matchAll(tokenPattern)].map((token) => ({\n end: clauseStart + (token.index ?? 0) + token[0].length,\n hint: Number(pathHintPattern.test(token[0]) || variableHintPattern.test(token[0])),\n start: clauseStart + (token.index ?? 0),\n value: token[0],\n }));\n const hintCounts = [0];\n for (const token of tokens) {\n hintCounts.push((hintCounts.at(-1) ?? 0) + token.hint);\n }\n for (let start = 0; start < tokens.length; start += 1) {\n const last = Math.min(tokens.length, start + maximumWords);\n for (let end = start + 1; end <= last; end += 1) {\n const firstToken = tokens[start];\n const lastToken = tokens[end - 1];\n const hintsBefore = hintCounts[start];\n const hintsAfter = hintCounts[end];\n if (\n firstToken === undefined ||\n lastToken === undefined ||\n hintsBefore === undefined ||\n hintsAfter === undefined ||\n hintsBefore === hintsAfter\n ) {\n continue;\n }\n const value = text.slice(firstToken.start, lastToken.end);\n if (pathHintPattern.test(value)) {\n add(result, seen, value, firstToken.start, lastToken.end, \"span\");\n }\n }\n }\n }\n}\nexport function extractCandidates(text: string, level: SearchLevel): Candidate[] {\n const result: Candidate[] = [];\n const seen = new Set<string>();\n addQuotedMatches(result, seen, text);\n addMatches(result, seen, text, explicitPattern, \"explicit\");\n if (level >= 2) {\n addMatches(result, seen, text, variablePathPattern, \"heuristic\");\n addMatches(result, seen, text, pathTokenPattern, \"heuristic\");\n }\n if (level >= 3) {\n const maximumWords =\n settings.spanWordLimits[Math.min(level - 3, settings.spanWordLimits.length - 1)];\n if (maximumWords === undefined) {\n throw new RangeError(\"No text-span level is configured\");\n }\n addSpanMatches(result, seen, text, maximumWords);\n }\n return result;\n}\n","import { readdir, stat } from \"node:fs/promises\";\nimport nodePath from \"node:path\";\nimport pLimit from \"p-limit\";\nimport { settings } from \"../config/settings.js\";\nimport type { PathKind } from \"./types.js\";\n\nconst knownFileErrors = new Set([\n \"EACCES\",\n \"ELOOP\",\n \"ENAMETOOLONG\",\n \"ENOTDIR\",\n \"ENOENT\",\n \"EPERM\",\n \"EINVAL\",\n]);\nconst unverifiableUncErrors = new Set([\"UNKNOWN\", \"EUNKNOWN\"]);\nfunction pathKey(value: string): string {\n return process.platform === \"win32\" ? value.toLowerCase() : value;\n}\nfunction fileErrorCode(error: unknown): string | undefined {\n if (error instanceof Error && \"code\" in error && typeof error.code === \"string\") {\n return error.code;\n }\n return undefined;\n}\nfunction isKnownFileError(error: unknown, filePath?: string): boolean {\n const code = fileErrorCode(error);\n return (\n code !== undefined &&\n (knownFileErrors.has(code) ||\n (filePath?.startsWith(\"\\\\\\\\\") === true && unverifiableUncErrors.has(code)))\n );\n}\nasync function classifyPath(filePath: string): Promise<PathKind | undefined> {\n try {\n const pathStats = await stat(filePath);\n if (pathStats.isFile()) {\n return \"file\";\n }\n return pathStats.isDirectory() ? \"directory\" : undefined;\n } catch (error) {\n if (isKnownFileError(error, filePath)) {\n return undefined;\n }\n throw error;\n }\n}\nasync function classifyAndAdd(found: Map<string, PathKind>, filePath: string): Promise<void> {\n const kind = await classifyPath(filePath);\n if (kind !== undefined) {\n found.set(filePath, kind);\n }\n}\nexport async function classifyExistingPaths(\n paths: readonly string[],\n roots: readonly string[],\n): Promise<Map<string, PathKind>> {\n const found = new Map<string, PathKind>();\n const limit = pLimit(settings.validationConcurrency);\n if (paths.length < settings.batchValidationThreshold) {\n await Promise.all(paths.map((filePath) => limit(() => classifyAndAdd(found, filePath))));\n return found;\n }\n const rootKeys = new Set(roots.map(pathKey));\n const pathsByParent = new Map<string, { parent: string; paths: string[] }>();\n for (const filePath of paths) {\n if (rootKeys.has(pathKey(filePath))) {\n found.set(filePath, \"directory\");\n continue;\n }\n const parent = nodePath.dirname(filePath);\n const key = pathKey(parent);\n const group = pathsByParent.get(key) ?? { parent, paths: [] };\n group.paths.push(filePath);\n pathsByParent.set(key, group);\n }\n const directPaths: string[] = [];\n const scannedGroups: { parent: string; paths: string[] }[] = [];\n for (const group of pathsByParent.values()) {\n if (group.paths.length < settings.directoryScanThreshold) {\n directPaths.push(...group.paths);\n } else {\n scannedGroups.push(group);\n }\n }\n await Promise.all([\n ...directPaths.map((filePath) => limit(() => classifyAndAdd(found, filePath))),\n ...scannedGroups.map(({ parent, paths: groupPaths }) =>\n limit(async () => {\n let entries;\n try {\n entries = await readdir(parent, { withFileTypes: true });\n } catch (error) {\n if (isKnownFileError(error, parent)) {\n return;\n }\n throw error;\n }\n const entriesByName = new Map(entries.map((entry) => [pathKey(entry.name), entry]));\n await Promise.all(\n groupPaths.map(async (filePath) => {\n const name = nodePath.basename(filePath);\n const entry = entriesByName.get(pathKey(name));\n if (entry?.isFile()) {\n found.set(filePath, \"file\");\n } else if (entry?.isDirectory()) {\n found.set(filePath, \"directory\");\n } else if (\n entry !== undefined ||\n (process.platform === \"win32\" && name.includes(\":\"))\n ) {\n await classifyAndAdd(found, filePath);\n }\n }),\n );\n }),\n ),\n ]);\n return found;\n}\n","import { Buffer } from \"node:buffer\";\nimport { isIP } from \"node:net\";\nimport { hostname, networkInterfaces } from \"node:os\";\nimport nodePath from \"node:path\";\nimport koffi from \"koffi\";\n\nconst uncServerSegmentPattern = /^[^\\\\/:*?\"<>|]+$/u;\nconst unmappedDriveErrors = new Set([1200, 1201, 1203, 1222, 2250]);\nconst errorMoreData = 234;\nconst mappingBufferChars = 32_768;\ninterface UncPath {\n canonical: string;\n server: string;\n share: string;\n suffix: string;\n}\ninterface DriveMapping {\n drive: string;\n remote: string;\n}\ntype GetConnectionW = (localName: string, remoteName: Buffer, length: number[]) => number;\nconst getConnectionW: GetConnectionW | undefined =\n process.platform === \"win32\"\n ? (koffi\n .load(\"mpr.dll\")\n .func(\n \"uint32_t WNetGetConnectionW(const char16_t *lpLocalName, _Out_ char16_t *lpRemoteName, _Inout_ uint32_t *lpnLength)\",\n ) as GetConnectionW)\n : undefined;\nfunction normalizeServerName(value: string): string {\n return value.replace(/\\.+$/u, \"\").toLowerCase();\n}\nfunction addLocalServerName(names: Set<string>, value: string | undefined): void {\n if (value !== undefined && uncServerSegmentPattern.test(value)) {\n names.add(normalizeServerName(value));\n }\n}\nfunction addIpv6LiteralName(names: Set<string>, value: string): void {\n const zoneIndex = value.indexOf(\"%\");\n const address = zoneIndex === -1 ? value : value.slice(0, zoneIndex);\n const zone = zoneIndex === -1 ? \"\" : `s${value.slice(zoneIndex + 1)}`;\n addLocalServerName(names, `${address.replaceAll(\":\", \"-\")}${zone}.ipv6-literal.net`);\n}\nfunction collectLocalServerNames(): Set<string> {\n const names = new Set<string>([\"localhost\"]);\n const computerName = process.env.COMPUTERNAME;\n addLocalServerName(names, hostname());\n addLocalServerName(names, computerName);\n if (computerName !== undefined && process.env.USERDNSDOMAIN !== undefined) {\n addLocalServerName(names, `${computerName}.${process.env.USERDNSDOMAIN}`);\n }\n for (const addresses of Object.values(networkInterfaces())) {\n for (const address of addresses ?? []) {\n if (isIP(address.address) === 4) {\n addLocalServerName(names, address.address);\n } else if (isIP(address.address) === 6) {\n addIpv6LiteralName(names, address.address);\n }\n }\n }\n addLocalServerName(names, \"--1.ipv6-literal.net\");\n return names;\n}\nconst localServerNames =\n process.platform === \"win32\" ? collectLocalServerNames() : new Set<string>();\nlet driveMappings: DriveMapping[] | undefined;\nfunction containsControlCharacter(value: string): boolean {\n return [...value].some((character) => character.charCodeAt(0) < 32);\n}\nfunction normalizeUncRoot(value: string): string {\n return value.replaceAll(\"/\", \"\\\\\").replace(/\\\\+$/u, \"\").toLowerCase();\n}\nfunction parseUncPath(value: string): UncPath | undefined {\n const normalized = value.replaceAll(\"/\", \"\\\\\");\n const extended = normalized.slice(0, 8).toLowerCase() === \"\\\\\\\\?\\\\unc\\\\\";\n if (normalized.startsWith(\"\\\\\\\\.\\\\\") || (normalized.startsWith(\"\\\\\\\\?\\\\\") && !extended)) {\n return undefined;\n }\n const serverStart = extended ? 8 : 2;\n const serverSeparator = normalized.slice(serverStart).indexOf(\"\\\\\");\n if (serverSeparator <= 0) {\n return undefined;\n }\n const serverEnd = serverStart + serverSeparator;\n const shareStart = serverEnd + 1;\n const shareSeparator = normalized.slice(shareStart).indexOf(\"\\\\\");\n const shareEnd = shareSeparator === -1 ? normalized.length : shareStart + shareSeparator;\n const server = normalized.slice(serverStart, serverEnd);\n const share = normalized.slice(shareStart, shareEnd);\n if (\n share.length === 0 ||\n !uncServerSegmentPattern.test(server) ||\n !uncServerSegmentPattern.test(share)\n ) {\n return undefined;\n }\n const suffix = normalized.slice(shareEnd);\n return {\n canonical: `\\\\\\\\${server}\\\\${share}${suffix}`,\n server,\n share,\n suffix,\n };\n}\nfunction queryDriveMapping(drive: string): string | undefined {\n if (getConnectionW === undefined) {\n return undefined;\n }\n const buffer = Buffer.alloc(mappingBufferChars * 2);\n const length = [mappingBufferChars];\n const result = getConnectionW(drive, buffer, length);\n if (result === errorMoreData) {\n throw new Error(`WNetGetConnectionW returned an oversized mapping for ${drive}`);\n }\n if (unmappedDriveErrors.has(result)) {\n return undefined;\n }\n if (result !== 0) {\n throw new Error(`WNetGetConnectionW failed for ${drive} with error ${result}`);\n }\n const remote = koffi.decode(buffer, \"char16_t\", mappingBufferChars);\n if (typeof remote !== \"string\" || !remote.startsWith(\"\\\\\\\\\")) {\n throw new TypeError(`WNetGetConnectionW returned an invalid mapping for ${drive}`);\n }\n return normalizeUncRoot(remote);\n}\nfunction queryDriveMappings(): DriveMapping[] {\n if (driveMappings !== undefined) {\n return driveMappings;\n }\n const result: DriveMapping[] = [];\n for (let code = \"A\".charCodeAt(0); code <= \"Z\".charCodeAt(0); code += 1) {\n const drive = `${String.fromCharCode(code)}:`;\n const remote = queryDriveMapping(drive);\n if (remote !== undefined) {\n result.push({ drive, remote });\n }\n }\n driveMappings = result.toSorted((left, right) => right.remote.length - left.remote.length);\n return driveMappings;\n}\nfunction resolveMappedUncPath(path: UncPath): string | undefined {\n const canonical = normalizeUncRoot(path.canonical);\n const mapping = queryDriveMappings().find(\n ({ remote }) => canonical === remote || canonical.startsWith(`${remote}\\\\`),\n );\n if (mapping === undefined) {\n return undefined;\n }\n const relative = path.canonical.slice(mapping.remote.length);\n return nodePath.win32.normalize(`${mapping.drive}${relative}`);\n}\nfunction isLocalServer(value: string): boolean {\n const normalized = normalizeServerName(value);\n return (\n localServerNames.has(normalized) ||\n (isIP(value) === 4 && value.split(\".\")[0] === \"127\") ||\n normalized === \"--1.ipv6-literal.net\"\n );\n}\nfunction resolveLocalAdministrativeShare(path: UncPath): string | undefined {\n const match = /^([A-Za-z])\\$$/u.exec(path.share);\n if (match === null || !isLocalServer(path.server)) {\n return undefined;\n }\n return nodePath.win32.normalize(`${match[1]}:${path.suffix || \"\\\\\"}`);\n}\nexport function resolveUncPath(value: string): string | undefined {\n if (process.platform !== \"win32\" || (!value.startsWith(\"\\\\\\\\\") && !value.startsWith(\"//\"))) {\n return value;\n }\n if (containsControlCharacter(value)) {\n return undefined;\n }\n const path = parseUncPath(value);\n if (path === undefined) {\n return undefined;\n }\n return resolveMappedUncPath(path) ?? resolveLocalAdministrativeShare(path);\n}\n","import { stat } from \"node:fs/promises\";\nimport nodePath from \"node:path\";\nimport fastGlob from \"fast-glob\";\nimport { convertPathToPattern, globby } from \"globby\";\nimport { settings } from \"../config/settings.js\";\nimport { resolveUncPath } from \"./unc.js\";\n\nfunction pathKey(value: string): string {\n return process.platform === \"win32\" ? value.toLowerCase() : value;\n}\nfunction isWithinRoot(filePath: string, root: string): boolean {\n const relative = nodePath.relative(root, filePath);\n return (\n relative === \"\" ||\n (relative !== \"..\" &&\n !relative.startsWith(`..${nodePath.sep}`) &&\n !nodePath.isAbsolute(relative))\n );\n}\nfunction isHidden(relativePath: string): boolean {\n return relativePath.split(/[\\\\/]/u).some((part) => part.length > 1 && part.startsWith(\".\"));\n}\nfunction traversalOptions(root: string, searchHidden: boolean) {\n return {\n caseSensitiveMatch: process.platform !== \"win32\",\n cwd: root,\n dot: searchHidden,\n followSymbolicLinks: false,\n onlyFiles: false,\n unique: true,\n } as const;\n}\nfunction globbyOptions(root: string, respectIgnore: boolean, searchHidden: boolean) {\n return {\n ...traversalOptions(root, searchHidden),\n expandDirectories: false,\n gitignore: respectIgnore,\n globalGitignore: respectIgnore,\n ...(respectIgnore ? { ignoreFiles: settings.ignoreFilePatterns } : {}),\n } as const;\n}\nexport async function resolveSearchDirectories(directories: readonly string[]): Promise<string[]> {\n if (!Array.isArray(directories)) {\n throw new TypeError(\"directories must be an array\");\n }\n if (directories.length === 0) {\n throw new RangeError(\"directories must not be empty\");\n }\n const unique = new Map<string, string>();\n for (const directory of directories) {\n if (typeof directory !== \"string\" || directory.length === 0) {\n throw new TypeError(\"every directory must be a non-empty string\");\n }\n const resolvedUnc = resolveUncPath(directory);\n if (resolvedUnc === undefined || resolvedUnc.length === 0) {\n throw new TypeError(`${directory} cannot be represented as a drive-based path`);\n }\n const resolved = nodePath.resolve(resolvedUnc);\n unique.set(pathKey(resolved), resolved);\n }\n await Promise.all(\n [...unique.values()].map(async (directory) => {\n if (!(await stat(directory)).isDirectory()) {\n throw new TypeError(`${directory} is not a directory`);\n }\n }),\n );\n return [...unique.values()];\n}\nexport async function listSearchEntries(\n root: string,\n respectIgnore: boolean,\n searchHidden: boolean,\n): Promise<string[]> {\n if (!respectIgnore) {\n return fastGlob(\"**/*\", traversalOptions(root, searchHidden));\n }\n return globby(\"**/*\", globbyOptions(root, respectIgnore, searchHidden));\n}\nexport async function filterSearchablePaths(\n paths: readonly string[],\n roots: readonly string[],\n respectIgnore: boolean,\n searchHidden: boolean,\n): Promise<Set<string>> {\n const allowed = new Set<string>();\n const pathsByRoot = new Map<string, string[]>();\n for (const filePath of paths) {\n let hasSearchRoot = false;\n for (const root of roots) {\n if (!isWithinRoot(filePath, root)) {\n continue;\n }\n hasSearchRoot = true;\n const relative = nodePath.relative(root, filePath);\n if (!searchHidden && isHidden(relative)) {\n continue;\n }\n if (relative === \"\" || !respectIgnore) {\n allowed.add(filePath);\n } else {\n const grouped = pathsByRoot.get(root) ?? [];\n grouped.push(relative);\n pathsByRoot.set(root, grouped);\n }\n }\n if (hasSearchRoot) {\n continue;\n }\n const filesystemRelative = nodePath.relative(nodePath.parse(filePath).root, filePath);\n if (searchHidden || !isHidden(filesystemRelative)) {\n allowed.add(filePath);\n }\n }\n await Promise.all(\n [...pathsByRoot].map(async ([root, relativePaths]) => {\n const patterns = relativePaths.map(convertPathToPattern);\n const matches = await globby(patterns, {\n ...globbyOptions(root, true, true),\n absolute: true,\n });\n for (const match of matches) {\n allowed.add(nodePath.normalize(match));\n }\n }),\n );\n return allowed;\n}\n","import { fileURLToPath } from \"node:url\";\nimport nodePath from \"node:path\";\nimport { classifyExistingPaths } from \"./existence.js\";\nimport { filterSearchablePaths } from \"./policy.js\";\nimport { expandVariables } from \"./variables/index.js\";\nimport { resolveUncPath } from \"./unc.js\";\nimport { settings } from \"../config/settings.js\";\nimport type { Candidate, PathLocation, PathMatch, PathPosition, Variables } from \"./types.js\";\n\ninterface ResolvedCandidate {\n location?: PathLocation;\n path: string;\n position: PathPosition;\n}\ninterface PreparedCandidate {\n location?: PathLocation;\n position: PathPosition;\n value: string;\n}\nfunction pathKey(value: string): string {\n return process.platform === \"win32\" ? value.toLowerCase() : value;\n}\nfunction uniquePaths(values: Iterable<string>): string[] {\n const paths = new Map<string, string>();\n for (const value of values) {\n paths.set(pathKey(value), value);\n }\n return [...paths.values()];\n}\nfunction parseLocationPart(value: string, name: string): number {\n const result = Number(value);\n if (!Number.isSafeInteger(result)) {\n throw new RangeError(`${name} must be a safe integer`);\n }\n return result;\n}\nfunction prepareCandidate(candidate: Candidate): PreparedCandidate {\n let end = candidate.end;\n let start = candidate.start;\n let value = candidate.value;\n if (candidate.kind !== \"inventory\" && candidate.kind !== \"quoted\") {\n const startTrimmed = value.trimStart();\n start += value.length - startTrimmed.length;\n value = startTrimmed;\n const endTrimmed = value.trimEnd();\n end -= value.length - endTrimmed.length;\n value = endTrimmed;\n if (\n value.length >= 2 &&\n ((value[0] === '\"' && value.at(-1) === '\"') ||\n (value[0] === \"'\" && value.at(-1) === \"'\") ||\n (value[0] === \"`\" && value.at(-1) === \"`\"))\n ) {\n start += 1;\n end -= 1;\n value = value.slice(1, -1);\n }\n while (value.length > 0 && settings.trailingPunctuation.includes(value.at(-1) ?? \"\")) {\n end -= 1;\n value = value.slice(0, -1);\n }\n }\n if (candidate.kind === \"inventory\") {\n return { position: { end, start }, value };\n }\n const match = settings.locationSuffixPattern.exec(value);\n if (match === null) {\n return { position: { end, start }, value };\n }\n const lineValue = match.groups?.line;\n if (lineValue === undefined) {\n throw new TypeError(\"locationSuffixPattern must capture a line\");\n }\n const columnValue = match.groups?.column;\n const location: PathLocation =\n columnValue === undefined\n ? { line: parseLocationPart(lineValue, \"line\") }\n : {\n column: parseLocationPart(columnValue, \"column\"),\n line: parseLocationPart(lineValue, \"line\"),\n };\n end -= match[0].length;\n return {\n location,\n position: { end, start },\n value: value.slice(0, match.index),\n };\n}\nfunction unescape(value: string): string {\n if (value.startsWith(\"\\\\\\\\\") && !value.startsWith(\"\\\\\\\\\\\\\\\\\")) {\n return value;\n }\n return value.replace(/\\\\([\"'`\\\\])/gu, \"$1\").replace(/\\\\\\\\/gu, \"\\\\\");\n}\nfunction toPaths(value: string, roots: readonly string[], variables: Variables): string[] {\n let expanded = expandVariables(value, variables);\n if (expanded.startsWith(\"file://\")) {\n try {\n expanded = fileURLToPath(expanded);\n } catch (error) {\n if (error instanceof TypeError) {\n return [];\n }\n throw error;\n }\n } else {\n expanded = unescape(expanded);\n if (expanded === \"~\" || /^~[\\\\/]/u.test(expanded)) {\n expanded = nodePath.join(\n variables.HOME ??\n variables.USERPROFILE ??\n process.env.HOME ??\n process.env.USERPROFILE ??\n \"\",\n expanded.slice(2),\n );\n }\n }\n const resolvedPath = resolveUncPath(expanded);\n if (resolvedPath === undefined || resolvedPath.length === 0) {\n return [];\n }\n expanded = resolvedPath;\n if (nodePath.isAbsolute(expanded)) {\n return [nodePath.normalize(expanded)];\n }\n return uniquePaths(roots.map((root) => nodePath.resolve(root, expanded)));\n}\nfunction mergeLocation(match: PathMatch, location: PathLocation | undefined): void {\n if (location === undefined) {\n return;\n }\n if (match.location === undefined) {\n match.location = location;\n return;\n }\n if (match.location.line !== location.line || match.location.column !== location.column) {\n throw new Error(\"Candidates for the same path and position have conflicting locations\");\n }\n}\nexport async function validateCandidates(\n candidates: Candidate[],\n roots: readonly string[],\n variables: Variables,\n respectIgnore: boolean,\n searchHidden: boolean,\n): Promise<PathMatch[]> {\n const resolvedCandidates: ResolvedCandidate[] = [];\n const validationPaths = new Map<string, string>();\n for (const candidate of candidates) {\n const prepared = prepareCandidate(candidate);\n const paths = toPaths(prepared.value, roots, variables);\n for (const filePath of paths) {\n resolvedCandidates.push({\n ...(prepared.location === undefined ? {} : { location: prepared.location }),\n path: filePath,\n position: prepared.position,\n });\n validationPaths.set(pathKey(filePath), filePath);\n }\n }\n let searchablePaths = [...validationPaths.values()];\n if (respectIgnore || !searchHidden) {\n searchablePaths = [\n ...(await filterSearchablePaths(searchablePaths, roots, respectIgnore, searchHidden)),\n ];\n }\n const classifiedPaths = await classifyExistingPaths(searchablePaths, roots);\n const kindsByPath = new Map(\n [...classifiedPaths].map(([filePath, kind]) => [pathKey(filePath), kind]),\n );\n const matches = new Map<string, PathMatch>();\n for (const { location, path, position } of resolvedCandidates) {\n const kind = kindsByPath.get(pathKey(path));\n if (kind === undefined) {\n continue;\n }\n const key = `${pathKey(path)}\\0${position.start}\\0${position.end}`;\n const existing = matches.get(key);\n if (existing !== undefined) {\n mergeLocation(existing, location);\n continue;\n }\n matches.set(key, {\n kind,\n ...(location === undefined ? {} : { location }),\n path,\n position,\n });\n }\n return [...matches.values()];\n}\n","import nodePath from \"node:path\";\nimport { listSearchEntries } from \"./policy.js\";\nimport type { Candidate } from \"./types.js\";\n\nfunction isBoundary(value: string | undefined, following: string | undefined): boolean {\n if (value === \".\") {\n return following === undefined || !/[\\p{L}\\p{N}_-]/u.test(following);\n }\n return value === undefined || !/[\\p{L}\\p{N}_/\\\\-]/u.test(value);\n}\nfunction addOccurrences(\n result: Candidate[],\n seen: Set<string>,\n source: string,\n text: string,\n value: string,\n): void {\n const target = process.platform === \"win32\" ? value.toLowerCase() : value;\n let offset = source.indexOf(target);\n while (offset !== -1) {\n const end = offset + target.length;\n if (isBoundary(text[offset - 1], text[offset]) && isBoundary(text[end], text[end + 1])) {\n const key = `${offset}:${end}:${text.slice(offset, end)}`;\n if (!seen.has(key)) {\n seen.add(key);\n result.push({\n end,\n kind: \"inventory\",\n start: offset,\n value,\n });\n }\n }\n offset = source.indexOf(target, offset + 1);\n }\n}\nexport async function inventoryCandidates(\n text: string,\n roots: readonly string[],\n respectIgnore: boolean,\n searchHidden: boolean,\n): Promise<Candidate[]> {\n const entries = await Promise.all(\n roots.map((root) => listSearchEntries(root, respectIgnore, searchHidden)),\n );\n const result: Candidate[] = [];\n const seen = new Set<string>();\n const scanned = new Set<string>();\n const source = process.platform === \"win32\" ? text.toLowerCase() : text;\n for (const [rootIndex, relativeEntries] of entries.entries()) {\n const root = roots[rootIndex];\n if (root === undefined) {\n continue;\n }\n for (const relativeEntry of relativeEntries) {\n const absoluteEntry = nodePath.resolve(root, relativeEntry);\n const variants = [\n relativeEntry,\n relativeEntry.replaceAll(\"/\", nodePath.sep),\n absoluteEntry,\n absoluteEntry.replaceAll(nodePath.sep, \"/\"),\n ];\n for (const value of variants) {\n const key = process.platform === \"win32\" ? value.toLowerCase() : value;\n if (!scanned.has(key)) {\n scanned.add(key);\n addOccurrences(result, seen, source, text, value);\n }\n }\n }\n }\n return result;\n}\n","import { extractCandidates } from \"./candidates.js\";\nimport { validateCandidates } from \"./filesystem.js\";\nimport { inventoryCandidates } from \"./inventory.js\";\nimport { resolveSearchDirectories } from \"./policy.js\";\nimport { settings } from \"../config/settings.js\";\nimport type { PathMatch, SearchLevel, Variables } from \"./types.js\";\n\nexport const MAX_LEVEL = settings.spanWordLimits.length + 3;\nfunction validateVariables(value: unknown): asserts value is Variables {\n if (\n typeof value !== \"object\" ||\n value === null ||\n Array.isArray(value) ||\n Object.values(value).some((item) => typeof item !== \"string\")\n ) {\n throw new TypeError(\"variables must be an object of string values\");\n }\n}\nexport async function findExistingPaths(\n text: string,\n level: SearchLevel,\n directories: readonly string[],\n variables: Variables = {},\n respectIgnore: boolean = settings.respectIgnoreByDefault,\n searchHidden: boolean = settings.searchHiddenByDefault,\n): Promise<PathMatch[]> {\n if (typeof text !== \"string\") {\n throw new TypeError(\"text must be a string\");\n }\n if (!Number.isInteger(level) || level < 1 || level > MAX_LEVEL) {\n throw new RangeError(`level must be an integer from 1 to ${MAX_LEVEL}`);\n }\n validateVariables(variables);\n if (typeof respectIgnore !== \"boolean\") {\n throw new TypeError(\"respectIgnore must be a boolean\");\n }\n if (typeof searchHidden !== \"boolean\") {\n throw new TypeError(\"searchHidden must be a boolean\");\n }\n const roots = await resolveSearchDirectories(directories);\n const candidates = extractCandidates(text, level);\n if (level === MAX_LEVEL) {\n candidates.push(...(await inventoryCandidates(text, roots, respectIgnore, searchHidden)));\n }\n return validateCandidates(candidates, roots, variables, respectIgnore, searchHidden);\n}\nexport type {\n PathKind,\n PathLocation,\n PathMatch,\n PathPosition,\n SearchLevel,\n Variables,\n} from \"./types.js\";\n"],"mappings":";;;;;;;;;;;AAEA,MAAa,WAA2B;CACtC,0BAA0B;CAC1B,wBAAwB;CACxB,oBAAoB,CAAC,cAAc,cAAc;CACjD,uBAAuB;CACvB,wBAAwB;CACxB,uBAAuB;CACvB,gBAAgB;EAAC;EAAG;EAAG;CAAE;CACzB,qBAAqB;CACrB,uBAAuB;AACzB;;;ACVA,MAAM,aAAa,OAAO,GAAG;AAC7B,MAAa,0BAA0B,OAAO,GAAG,8CAA8C,WAAW,iBAAiB,WAAW,0BAA0B,WAAW,WAAW,WAAW,6BAA6B,WAAW,KAAK,WAAW,WAAW,WAAW,SAAS,WAAW;AACnS,MAAM,qBAAqB;CACzB,IAAI,OAAO,OAAO,GAAG,4CAA4C,WAAW,WAAW,KAAK;CAC5F,IAAI,OAAO,OAAO,GAAG,WAAW,WAAW,WAAW,IAAI;CAC1D,IAAI,OAAO,OAAO,GAAG,oBAAoB,WAAW,MAAM,KAAK;CAC/D,IAAI,OAAO,OAAO,GAAG,UAAU,WAAW,IAAI,KAAK;CACnD,IAAI,OAAO,OAAO,GAAG,sCAAsC,KAAK;CAChE,IAAI,OAAO,OAAO,GAAG,KAAK,WAAW,KAAK,IAAI;CAC9C,IAAI,OAAO,OAAO,GAAG,KAAK,WAAW,KAAK,IAAI;CAC9C,IAAI,OAAO,OAAO,GAAG,WAAW,WAAW,SAAS,IAAI;CACxD,IAAI,OAAO,OAAO,GAAG,KAAK,WAAW,KAAK,IAAI;AAChD;AACA,SAAS,gBAAgB,MAAc,WAA0C;CAC/E,MAAM,SAAS,UAAU,SAAS,QAAQ,IAAI;CAC9C,IAAI,WAAW,KAAA,GACb,OAAO;CAET,MAAM,WAAW,qCAAqC,KAAK,IAAI,CAAC,GAAG;CACnE,OAAO,aAAa,KAAA,IAAY,KAAA,IAAa,UAAU,aAAa,QAAQ,IAAI;AAClF;AACA,SAAgB,gBAAgB,OAAe,WAA8B;CAC3E,IAAI,SAAS;CACb,KAAK,MAAM,WAAW,oBACpB,SAAS,OAAO,QAAQ,UAAU,OAAO,SAAiB;EACxD,MAAM,cAAc,gBAAgB,MAAM,SAAS;EACnD,OAAO,gBAAgB,KAAA,IAAY,QAAQ;CAC7C,CAAC;CAEH,OAAO;AACT;;;AC5BA,MAAM,kBACJ;AACF,MAAM,gBAAgB;AACtB,MAAM,eAAe;AACrB,MAAM,mBACJ;AAEF,MAAM,sBAAsB,IAAI,OAC9B,GAAG,wBAAwB,oCAC3B,KACF;AACA,MAAM,gBAAgB;AACtB,MAAM,kBACJ;AACF,MAAM,sBAAsB,IAAI,OAAO,OAAO,GAAG,GAAG,wBAAwB,cAAc,IAAI;AAC9F,SAAS,IACP,QACA,MACA,OACA,OACA,KACA,MACM;CACN,IAAI,MAAM,WAAW,GACnB;CAEF,MAAM,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG;CAC/B,IAAI,CAAC,KAAK,IAAI,GAAG,GAAG;EAClB,KAAK,IAAI,GAAG;EACZ,OAAO,KAAK;GAAE;GAAK;GAAM;GAAO;EAAM,CAAC;CACzC;AACF;AACA,SAAS,WACP,QACA,MACA,MACA,SACA,MACM;CACN,KAAK,MAAM,SAAS,KAAK,SAAS,OAAO,GAAG;EAC1C,MAAM,QAAQ,MAAM;EACpB,MAAM,QAAQ,MAAM,SAAS;EAC7B,IAAI,QAAQ,MAAM,OAAO,OAAO,QAAQ,MAAM,QAAQ,IAAI;CAC5D;AACF;AACA,SAAS,iBAAiB,QAAqB,MAAmB,MAAoB;CACpF,KAAK,MAAM,SAAS,KAAK,SAAS,aAAa,GAAG;EAChD,MAAM,QAAQ,MAAM,QAAQ;EAC5B,IAAI,UAAU,KAAA,GACZ;EAEF,MAAM,SAAS,MAAM,SAAS,KAAK,MAAM,EAAE,CAAC,QAAQ,KAAK;EACzD,IAAI,QAAQ,MAAM,OAAO,OAAO,QAAQ,MAAM,QAAQ,QAAQ;CAChE;AACF;AACA,SAAS,eACP,QACA,MACA,MACA,cACM;CACN,KAAK,MAAM,UAAU,KAAK,SAAS,aAAa,GAAG;EACjD,MAAM,cAAc,OAAO,SAAS;EAEpC,MAAM,SAAS,CAAC,GADG,OAAO,EACG,CAAC,SAAS,YAAY,CAAC,CAAC,CAAC,KAAK,WAAW;GACpE,KAAK,eAAe,MAAM,SAAS,KAAK,MAAM,EAAE,CAAC;GACjD,MAAM,OAAO,gBAAgB,KAAK,MAAM,EAAE,KAAK,oBAAoB,KAAK,MAAM,EAAE,CAAC;GACjF,OAAO,eAAe,MAAM,SAAS;GACrC,OAAO,MAAM;EACf,EAAE;EACF,MAAM,aAAa,CAAC,CAAC;EACrB,KAAK,MAAM,SAAS,QAClB,WAAW,MAAM,WAAW,GAAG,EAAE,KAAK,KAAK,MAAM,IAAI;EAEvD,KAAK,IAAI,QAAQ,GAAG,QAAQ,OAAO,QAAQ,SAAS,GAAG;GACrD,MAAM,OAAO,KAAK,IAAI,OAAO,QAAQ,QAAQ,YAAY;GACzD,KAAK,IAAI,MAAM,QAAQ,GAAG,OAAO,MAAM,OAAO,GAAG;IAC/C,MAAM,aAAa,OAAO;IAC1B,MAAM,YAAY,OAAO,MAAM;IAC/B,MAAM,cAAc,WAAW;IAC/B,MAAM,aAAa,WAAW;IAC9B,IACE,eAAe,KAAA,KACf,cAAc,KAAA,KACd,gBAAgB,KAAA,KAChB,eAAe,KAAA,KACf,gBAAgB,YAEhB;IAEF,MAAM,QAAQ,KAAK,MAAM,WAAW,OAAO,UAAU,GAAG;IACxD,IAAI,gBAAgB,KAAK,KAAK,GAC5B,IAAI,QAAQ,MAAM,OAAO,WAAW,OAAO,UAAU,KAAK,MAAM;GAEpE;EACF;CACF;AACF;AACA,SAAgB,kBAAkB,MAAc,OAAiC;CAC/E,MAAM,SAAsB,CAAC;CAC7B,MAAM,uBAAO,IAAI,IAAY;CAC7B,iBAAiB,QAAQ,MAAM,IAAI;CACnC,WAAW,QAAQ,MAAM,MAAM,iBAAiB,UAAU;CAC1D,IAAI,SAAS,GAAG;EACd,WAAW,QAAQ,MAAM,MAAM,qBAAqB,WAAW;EAC/D,WAAW,QAAQ,MAAM,MAAM,kBAAkB,WAAW;CAC9D;CACA,IAAI,SAAS,GAAG;EACd,MAAM,eACJ,SAAS,eAAe,KAAK,IAAI,QAAQ,GAAG,SAAS,eAAe,SAAS,CAAC;EAChF,IAAI,iBAAiB,KAAA,GACnB,MAAM,IAAI,WAAW,kCAAkC;EAEzD,eAAe,QAAQ,MAAM,MAAM,YAAY;CACjD;CACA,OAAO;AACT;;;AClHA,MAAM,kCAAkB,IAAI,IAAI;CAC9B;CACA;CACA;CACA;CACA;CACA;CACA;AACF,CAAC;AACD,MAAM,wCAAwB,IAAI,IAAI,CAAC,WAAW,UAAU,CAAC;AAC7D,SAASA,UAAQ,OAAuB;CACtC,OAAO,QAAQ,aAAa,UAAU,MAAM,YAAY,IAAI;AAC9D;AACA,SAAS,cAAc,OAAoC;CACzD,IAAI,iBAAiB,SAAS,UAAU,SAAS,OAAO,MAAM,SAAS,UACrE,OAAO,MAAM;AAGjB;AACA,SAAS,iBAAiB,OAAgB,UAA4B;CACpE,MAAM,OAAO,cAAc,KAAK;CAChC,OACE,SAAS,KAAA,MACR,gBAAgB,IAAI,IAAI,KACtB,UAAU,WAAW,MAAM,MAAM,QAAQ,sBAAsB,IAAI,IAAI;AAE9E;AACA,eAAe,aAAa,UAAiD;CAC3E,IAAI;EACF,MAAM,YAAY,MAAM,KAAK,QAAQ;EACrC,IAAI,UAAU,OAAO,GACnB,OAAO;EAET,OAAO,UAAU,YAAY,IAAI,cAAc,KAAA;CACjD,SAAS,OAAO;EACd,IAAI,iBAAiB,OAAO,QAAQ,GAClC;EAEF,MAAM;CACR;AACF;AACA,eAAe,eAAe,OAA8B,UAAiC;CAC3F,MAAM,OAAO,MAAM,aAAa,QAAQ;CACxC,IAAI,SAAS,KAAA,GACX,MAAM,IAAI,UAAU,IAAI;AAE5B;AACA,eAAsB,sBACpB,OACA,OACgC;CAChC,MAAM,wBAAQ,IAAI,IAAsB;CACxC,MAAM,QAAQ,OAAO,SAAS,qBAAqB;CACnD,IAAI,MAAM,SAAS,SAAS,0BAA0B;EACpD,MAAM,QAAQ,IAAI,MAAM,KAAK,aAAa,YAAY,eAAe,OAAO,QAAQ,CAAC,CAAC,CAAC;EACvF,OAAO;CACT;CACA,MAAM,WAAW,IAAI,IAAI,MAAM,IAAIA,SAAO,CAAC;CAC3C,MAAM,gCAAgB,IAAI,IAAiD;CAC3E,KAAK,MAAM,YAAY,OAAO;EAC5B,IAAI,SAAS,IAAIA,UAAQ,QAAQ,CAAC,GAAG;GACnC,MAAM,IAAI,UAAU,WAAW;GAC/B;EACF;EACA,MAAM,SAAS,SAAS,QAAQ,QAAQ;EACxC,MAAM,MAAMA,UAAQ,MAAM;EAC1B,MAAM,QAAQ,cAAc,IAAI,GAAG,KAAK;GAAE;GAAQ,OAAO,CAAC;EAAE;EAC5D,MAAM,MAAM,KAAK,QAAQ;EACzB,cAAc,IAAI,KAAK,KAAK;CAC9B;CACA,MAAM,cAAwB,CAAC;CAC/B,MAAM,gBAAuD,CAAC;CAC9D,KAAK,MAAM,SAAS,cAAc,OAAO,GACvC,IAAI,MAAM,MAAM,SAAS,SAAS,wBAChC,YAAY,KAAK,GAAG,MAAM,KAAK;MAE/B,cAAc,KAAK,KAAK;CAG5B,MAAM,QAAQ,IAAI,CAChB,GAAG,YAAY,KAAK,aAAa,YAAY,eAAe,OAAO,QAAQ,CAAC,CAAC,GAC7E,GAAG,cAAc,KAAK,EAAE,QAAQ,OAAO,iBACrC,MAAM,YAAY;EAChB,IAAI;EACJ,IAAI;GACF,UAAU,MAAM,QAAQ,QAAQ,EAAE,eAAe,KAAK,CAAC;EACzD,SAAS,OAAO;GACd,IAAI,iBAAiB,OAAO,MAAM,GAChC;GAEF,MAAM;EACR;EACA,MAAM,gBAAgB,IAAI,IAAI,QAAQ,KAAK,UAAU,CAACA,UAAQ,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC;EAClF,MAAM,QAAQ,IACZ,WAAW,IAAI,OAAO,aAAa;GACjC,MAAM,OAAO,SAAS,SAAS,QAAQ;GACvC,MAAM,QAAQ,cAAc,IAAIA,UAAQ,IAAI,CAAC;GAC7C,IAAI,OAAO,OAAO,GAChB,MAAM,IAAI,UAAU,MAAM;QACrB,IAAI,OAAO,YAAY,GAC5B,MAAM,IAAI,UAAU,WAAW;QAC1B,IACL,UAAU,KAAA,KACT,QAAQ,aAAa,WAAW,KAAK,SAAS,GAAG,GAElD,MAAM,eAAe,OAAO,QAAQ;EAExC,CAAC,CACH;CACF,CAAC,CACH,CACF,CAAC;CACD,OAAO;AACT;;;ACjHA,MAAM,0BAA0B;AAChC,MAAM,sCAAsB,IAAI,IAAI;CAAC;CAAM;CAAM;CAAM;CAAM;AAAI,CAAC;AAClE,MAAM,gBAAgB;AACtB,MAAM,qBAAqB;AAY3B,MAAM,iBACJ,QAAQ,aAAa,UAChB,MACE,KAAK,SAAS,CAAC,CACf,KACC,qHACF,IACF,KAAA;AACN,SAAS,oBAAoB,OAAuB;CAClD,OAAO,MAAM,QAAQ,SAAS,EAAE,CAAC,CAAC,YAAY;AAChD;AACA,SAAS,mBAAmB,OAAoB,OAAiC;CAC/E,IAAI,UAAU,KAAA,KAAa,wBAAwB,KAAK,KAAK,GAC3D,MAAM,IAAI,oBAAoB,KAAK,CAAC;AAExC;AACA,SAAS,mBAAmB,OAAoB,OAAqB;CACnE,MAAM,YAAY,MAAM,QAAQ,GAAG;CACnC,MAAM,UAAU,cAAc,KAAK,QAAQ,MAAM,MAAM,GAAG,SAAS;CACnE,MAAM,OAAO,cAAc,KAAK,KAAK,IAAI,MAAM,MAAM,YAAY,CAAC;CAClE,mBAAmB,OAAO,GAAG,QAAQ,WAAW,KAAK,GAAG,IAAI,KAAK,kBAAkB;AACrF;AACA,SAAS,0BAAuC;CAC9C,MAAM,wBAAQ,IAAI,IAAY,CAAC,WAAW,CAAC;CAC3C,MAAM,eAAe,QAAQ,IAAI;CACjC,mBAAmB,OAAO,SAAS,CAAC;CACpC,mBAAmB,OAAO,YAAY;CACtC,IAAI,iBAAiB,KAAA,KAAa,QAAQ,IAAI,kBAAkB,KAAA,GAC9D,mBAAmB,OAAO,GAAG,aAAa,GAAG,QAAQ,IAAI,eAAe;CAE1E,KAAK,MAAM,aAAa,OAAO,OAAO,kBAAkB,CAAC,GACvD,KAAK,MAAM,WAAW,aAAa,CAAC,GAClC,IAAI,KAAK,QAAQ,OAAO,MAAM,GAC5B,mBAAmB,OAAO,QAAQ,OAAO;MACpC,IAAI,KAAK,QAAQ,OAAO,MAAM,GACnC,mBAAmB,OAAO,QAAQ,OAAO;CAI/C,mBAAmB,OAAO,sBAAsB;CAChD,OAAO;AACT;AACA,MAAM,mBACJ,QAAQ,aAAa,UAAU,wBAAwB,oBAAI,IAAI,IAAY;AAC7E,IAAI;AACJ,SAAS,yBAAyB,OAAwB;CACxD,OAAO,CAAC,GAAG,KAAK,CAAC,CAAC,MAAM,cAAc,UAAU,WAAW,CAAC,IAAI,EAAE;AACpE;AACA,SAAS,iBAAiB,OAAuB;CAC/C,OAAO,MAAM,WAAW,KAAK,IAAI,CAAC,CAAC,QAAQ,SAAS,EAAE,CAAC,CAAC,YAAY;AACtE;AACA,SAAS,aAAa,OAAoC;CACxD,MAAM,aAAa,MAAM,WAAW,KAAK,IAAI;CAC7C,MAAM,WAAW,WAAW,MAAM,GAAG,CAAC,CAAC,CAAC,YAAY,MAAM;CAC1D,IAAI,WAAW,WAAW,SAAS,KAAM,WAAW,WAAW,SAAS,KAAK,CAAC,UAC5E;CAEF,MAAM,cAAc,WAAW,IAAI;CACnC,MAAM,kBAAkB,WAAW,MAAM,WAAW,CAAC,CAAC,QAAQ,IAAI;CAClE,IAAI,mBAAmB,GACrB;CAEF,MAAM,YAAY,cAAc;CAChC,MAAM,aAAa,YAAY;CAC/B,MAAM,iBAAiB,WAAW,MAAM,UAAU,CAAC,CAAC,QAAQ,IAAI;CAChE,MAAM,WAAW,mBAAmB,KAAK,WAAW,SAAS,aAAa;CAC1E,MAAM,SAAS,WAAW,MAAM,aAAa,SAAS;CACtD,MAAM,QAAQ,WAAW,MAAM,YAAY,QAAQ;CACnD,IACE,MAAM,WAAW,KACjB,CAAC,wBAAwB,KAAK,MAAM,KACpC,CAAC,wBAAwB,KAAK,KAAK,GAEnC;CAEF,MAAM,SAAS,WAAW,MAAM,QAAQ;CACxC,OAAO;EACL,WAAW,OAAO,OAAO,IAAI,QAAQ;EACrC;EACA;EACA;CACF;AACF;AACA,SAAS,kBAAkB,OAAmC;CAC5D,IAAI,mBAAmB,KAAA,GACrB;CAEF,MAAM,SAAS,OAAO,MAAM,qBAAqB,CAAC;CAElD,MAAM,SAAS,eAAe,OAAO,QAAQ,CAD7B,kBACkC,CAAC;CACnD,IAAI,WAAW,eACb,MAAM,IAAI,MAAM,wDAAwD,OAAO;CAEjF,IAAI,oBAAoB,IAAI,MAAM,GAChC;CAEF,IAAI,WAAW,GACb,MAAM,IAAI,MAAM,iCAAiC,MAAM,cAAc,QAAQ;CAE/E,MAAM,SAAS,MAAM,OAAO,QAAQ,YAAY,kBAAkB;CAClE,IAAI,OAAO,WAAW,YAAY,CAAC,OAAO,WAAW,MAAM,GACzD,MAAM,IAAI,UAAU,sDAAsD,OAAO;CAEnF,OAAO,iBAAiB,MAAM;AAChC;AACA,SAAS,qBAAqC;CAC5C,IAAI,kBAAkB,KAAA,GACpB,OAAO;CAET,MAAM,SAAyB,CAAC;CAChC,KAAK,IAAI,OAAO,IAAI,WAAW,CAAC,GAAG,QAAQ,IAAI,WAAW,CAAC,GAAG,QAAQ,GAAG;EACvE,MAAM,QAAQ,GAAG,OAAO,aAAa,IAAI,EAAE;EAC3C,MAAM,SAAS,kBAAkB,KAAK;EACtC,IAAI,WAAW,KAAA,GACb,OAAO,KAAK;GAAE;GAAO;EAAO,CAAC;CAEjC;CACA,gBAAgB,OAAO,UAAU,MAAM,UAAU,MAAM,OAAO,SAAS,KAAK,OAAO,MAAM;CACzF,OAAO;AACT;AACA,SAAS,qBAAqB,MAAmC;CAC/D,MAAM,YAAY,iBAAiB,KAAK,SAAS;CACjD,MAAM,UAAU,mBAAmB,CAAC,CAAC,MAClC,EAAE,aAAa,cAAc,UAAU,UAAU,WAAW,GAAG,OAAO,GAAG,CAC5E;CACA,IAAI,YAAY,KAAA,GACd;CAEF,MAAM,WAAW,KAAK,UAAU,MAAM,QAAQ,OAAO,MAAM;CAC3D,OAAO,SAAS,MAAM,UAAU,GAAG,QAAQ,QAAQ,UAAU;AAC/D;AACA,SAAS,cAAc,OAAwB;CAC7C,MAAM,aAAa,oBAAoB,KAAK;CAC5C,OACE,iBAAiB,IAAI,UAAU,KAC9B,KAAK,KAAK,MAAM,KAAK,MAAM,MAAM,GAAG,CAAC,CAAC,OAAO,SAC9C,eAAe;AAEnB;AACA,SAAS,gCAAgC,MAAmC;CAC1E,MAAM,QAAQ,kBAAkB,KAAK,KAAK,KAAK;CAC/C,IAAI,UAAU,QAAQ,CAAC,cAAc,KAAK,MAAM,GAC9C;CAEF,OAAO,SAAS,MAAM,UAAU,GAAG,MAAM,GAAG,GAAG,KAAK,UAAU,MAAM;AACtE;AACA,SAAgB,eAAe,OAAmC;CAChE,IAAI,QAAQ,aAAa,WAAY,CAAC,MAAM,WAAW,MAAM,KAAK,CAAC,MAAM,WAAW,IAAI,GACtF,OAAO;CAET,IAAI,yBAAyB,KAAK,GAChC;CAEF,MAAM,OAAO,aAAa,KAAK;CAC/B,IAAI,SAAS,KAAA,GACX;CAEF,OAAO,qBAAqB,IAAI,KAAK,gCAAgC,IAAI;AAC3E;;;AC5KA,SAASC,UAAQ,OAAuB;CACtC,OAAO,QAAQ,aAAa,UAAU,MAAM,YAAY,IAAI;AAC9D;AACA,SAAS,aAAa,UAAkB,MAAuB;CAC7D,MAAM,WAAW,SAAS,SAAS,MAAM,QAAQ;CACjD,OACE,aAAa,MACZ,aAAa,QACZ,CAAC,SAAS,WAAW,KAAK,SAAS,KAAK,KACxC,CAAC,SAAS,WAAW,QAAQ;AAEnC;AACA,SAAS,SAAS,cAA+B;CAC/C,OAAO,aAAa,MAAM,QAAQ,CAAC,CAAC,MAAM,SAAS,KAAK,SAAS,KAAK,KAAK,WAAW,GAAG,CAAC;AAC5F;AACA,SAAS,iBAAiB,MAAc,cAAuB;CAC7D,OAAO;EACL,oBAAoB,QAAQ,aAAa;EACzC,KAAK;EACL,KAAK;EACL,qBAAqB;EACrB,WAAW;EACX,QAAQ;CACV;AACF;AACA,SAAS,cAAc,MAAc,eAAwB,cAAuB;CAClF,OAAO;EACL,GAAG,iBAAiB,MAAM,YAAY;EACtC,mBAAmB;EACnB,WAAW;EACX,iBAAiB;EACjB,GAAI,gBAAgB,EAAE,aAAa,SAAS,mBAAmB,IAAI,CAAC;CACtE;AACF;AACA,eAAsB,yBAAyB,aAAmD;CAChG,IAAI,CAAC,MAAM,QAAQ,WAAW,GAC5B,MAAM,IAAI,UAAU,8BAA8B;CAEpD,IAAI,YAAY,WAAW,GACzB,MAAM,IAAI,WAAW,+BAA+B;CAEtD,MAAM,yBAAS,IAAI,IAAoB;CACvC,KAAK,MAAM,aAAa,aAAa;EACnC,IAAI,OAAO,cAAc,YAAY,UAAU,WAAW,GACxD,MAAM,IAAI,UAAU,4CAA4C;EAElE,MAAM,cAAc,eAAe,SAAS;EAC5C,IAAI,gBAAgB,KAAA,KAAa,YAAY,WAAW,GACtD,MAAM,IAAI,UAAU,GAAG,UAAU,6CAA6C;EAEhF,MAAM,WAAW,SAAS,QAAQ,WAAW;EAC7C,OAAO,IAAIA,UAAQ,QAAQ,GAAG,QAAQ;CACxC;CACA,MAAM,QAAQ,IACZ,CAAC,GAAG,OAAO,OAAO,CAAC,CAAC,CAAC,IAAI,OAAO,cAAc;EAC5C,IAAI,EAAE,MAAM,KAAK,SAAS,EAAA,CAAG,YAAY,GACvC,MAAM,IAAI,UAAU,GAAG,UAAU,oBAAoB;CAEzD,CAAC,CACH;CACA,OAAO,CAAC,GAAG,OAAO,OAAO,CAAC;AAC5B;AACA,eAAsB,kBACpB,MACA,eACA,cACmB;CACnB,IAAI,CAAC,eACH,OAAO,SAAS,QAAQ,iBAAiB,MAAM,YAAY,CAAC;CAE9D,OAAO,OAAO,QAAQ,cAAc,MAAM,eAAe,YAAY,CAAC;AACxE;AACA,eAAsB,sBACpB,OACA,OACA,eACA,cACsB;CACtB,MAAM,0BAAU,IAAI,IAAY;CAChC,MAAM,8BAAc,IAAI,IAAsB;CAC9C,KAAK,MAAM,YAAY,OAAO;EAC5B,IAAI,gBAAgB;EACpB,KAAK,MAAM,QAAQ,OAAO;GACxB,IAAI,CAAC,aAAa,UAAU,IAAI,GAC9B;GAEF,gBAAgB;GAChB,MAAM,WAAW,SAAS,SAAS,MAAM,QAAQ;GACjD,IAAI,CAAC,gBAAgB,SAAS,QAAQ,GACpC;GAEF,IAAI,aAAa,MAAM,CAAC,eACtB,QAAQ,IAAI,QAAQ;QACf;IACL,MAAM,UAAU,YAAY,IAAI,IAAI,KAAK,CAAC;IAC1C,QAAQ,KAAK,QAAQ;IACrB,YAAY,IAAI,MAAM,OAAO;GAC/B;EACF;EACA,IAAI,eACF;EAEF,MAAM,qBAAqB,SAAS,SAAS,SAAS,MAAM,QAAQ,CAAC,CAAC,MAAM,QAAQ;EACpF,IAAI,gBAAgB,CAAC,SAAS,kBAAkB,GAC9C,QAAQ,IAAI,QAAQ;CAExB;CACA,MAAM,QAAQ,IACZ,CAAC,GAAG,WAAW,CAAC,CAAC,IAAI,OAAO,CAAC,MAAM,mBAAmB;EACpD,MAAM,WAAW,cAAc,IAAI,oBAAoB;EACvD,MAAM,UAAU,MAAM,OAAO,UAAU;GACrC,GAAG,cAAc,MAAM,MAAM,IAAI;GACjC,UAAU;EACZ,CAAC;EACD,KAAK,MAAM,SAAS,SAClB,QAAQ,IAAI,SAAS,UAAU,KAAK,CAAC;CAEzC,CAAC,CACH;CACA,OAAO;AACT;;;AC5GA,SAAS,QAAQ,OAAuB;CACtC,OAAO,QAAQ,aAAa,UAAU,MAAM,YAAY,IAAI;AAC9D;AACA,SAAS,YAAY,QAAoC;CACvD,MAAM,wBAAQ,IAAI,IAAoB;CACtC,KAAK,MAAM,SAAS,QAClB,MAAM,IAAI,QAAQ,KAAK,GAAG,KAAK;CAEjC,OAAO,CAAC,GAAG,MAAM,OAAO,CAAC;AAC3B;AACA,SAAS,kBAAkB,OAAe,MAAsB;CAC9D,MAAM,SAAS,OAAO,KAAK;CAC3B,IAAI,CAAC,OAAO,cAAc,MAAM,GAC9B,MAAM,IAAI,WAAW,GAAG,KAAK,wBAAwB;CAEvD,OAAO;AACT;AACA,SAAS,iBAAiB,WAAyC;CACjE,IAAI,MAAM,UAAU;CACpB,IAAI,QAAQ,UAAU;CACtB,IAAI,QAAQ,UAAU;CACtB,IAAI,UAAU,SAAS,eAAe,UAAU,SAAS,UAAU;EACjE,MAAM,eAAe,MAAM,UAAU;EACrC,SAAS,MAAM,SAAS,aAAa;EACrC,QAAQ;EACR,MAAM,aAAa,MAAM,QAAQ;EACjC,OAAO,MAAM,SAAS,WAAW;EACjC,QAAQ;EACR,IACE,MAAM,UAAU,MACd,MAAM,OAAO,QAAO,MAAM,GAAG,EAAE,MAAM,QACpC,MAAM,OAAO,OAAO,MAAM,GAAG,EAAE,MAAM,OACrC,MAAM,OAAO,OAAO,MAAM,GAAG,EAAE,MAAM,MACxC;GACA,SAAS;GACT,OAAO;GACP,QAAQ,MAAM,MAAM,GAAG,EAAE;EAC3B;EACA,OAAO,MAAM,SAAS,KAAK,SAAS,oBAAoB,SAAS,MAAM,GAAG,EAAE,KAAK,EAAE,GAAG;GACpF,OAAO;GACP,QAAQ,MAAM,MAAM,GAAG,EAAE;EAC3B;CACF;CACA,IAAI,UAAU,SAAS,aACrB,OAAO;EAAE,UAAU;GAAE;GAAK;EAAM;EAAG;CAAM;CAE3C,MAAM,QAAQ,SAAS,sBAAsB,KAAK,KAAK;CACvD,IAAI,UAAU,MACZ,OAAO;EAAE,UAAU;GAAE;GAAK;EAAM;EAAG;CAAM;CAE3C,MAAM,YAAY,MAAM,QAAQ;CAChC,IAAI,cAAc,KAAA,GAChB,MAAM,IAAI,UAAU,2CAA2C;CAEjE,MAAM,cAAc,MAAM,QAAQ;CAClC,MAAM,WACJ,gBAAgB,KAAA,IACZ,EAAE,MAAM,kBAAkB,WAAW,MAAM,EAAE,IAC7C;EACE,QAAQ,kBAAkB,aAAa,QAAQ;EAC/C,MAAM,kBAAkB,WAAW,MAAM;CAC3C;CACN,OAAO,MAAM,EAAE,CAAC;CAChB,OAAO;EACL;EACA,UAAU;GAAE;GAAK;EAAM;EACvB,OAAO,MAAM,MAAM,GAAG,MAAM,KAAK;CACnC;AACF;AACA,SAAS,SAAS,OAAuB;CACvC,IAAI,MAAM,WAAW,MAAM,KAAK,CAAC,MAAM,WAAW,UAAU,GAC1D,OAAO;CAET,OAAO,MAAM,QAAQ,iBAAiB,IAAI,CAAC,CAAC,QAAQ,UAAU,IAAI;AACpE;AACA,SAAS,QAAQ,OAAe,OAA0B,WAAgC;CACxF,IAAI,WAAW,gBAAgB,OAAO,SAAS;CAC/C,IAAI,SAAS,WAAW,SAAS,GAC/B,IAAI;EACF,WAAW,cAAc,QAAQ;CACnC,SAAS,OAAO;EACd,IAAI,iBAAiB,WACnB,OAAO,CAAC;EAEV,MAAM;CACR;MACK;EACL,WAAW,SAAS,QAAQ;EAC5B,IAAI,aAAa,OAAO,WAAW,KAAK,QAAQ,GAC9C,WAAW,SAAS,KAClB,UAAU,QACR,UAAU,eACV,QAAQ,IAAI,QACZ,QAAQ,IAAI,eACZ,IACF,SAAS,MAAM,CAAC,CAClB;CAEJ;CACA,MAAM,eAAe,eAAe,QAAQ;CAC5C,IAAI,iBAAiB,KAAA,KAAa,aAAa,WAAW,GACxD,OAAO,CAAC;CAEV,WAAW;CACX,IAAI,SAAS,WAAW,QAAQ,GAC9B,OAAO,CAAC,SAAS,UAAU,QAAQ,CAAC;CAEtC,OAAO,YAAY,MAAM,KAAK,SAAS,SAAS,QAAQ,MAAM,QAAQ,CAAC,CAAC;AAC1E;AACA,SAAS,cAAc,OAAkB,UAA0C;CACjF,IAAI,aAAa,KAAA,GACf;CAEF,IAAI,MAAM,aAAa,KAAA,GAAW;EAChC,MAAM,WAAW;EACjB;CACF;CACA,IAAI,MAAM,SAAS,SAAS,SAAS,QAAQ,MAAM,SAAS,WAAW,SAAS,QAC9E,MAAM,IAAI,MAAM,sEAAsE;AAE1F;AACA,eAAsB,mBACpB,YACA,OACA,WACA,eACA,cACsB;CACtB,MAAM,qBAA0C,CAAC;CACjD,MAAM,kCAAkB,IAAI,IAAoB;CAChD,KAAK,MAAM,aAAa,YAAY;EAClC,MAAM,WAAW,iBAAiB,SAAS;EAC3C,MAAM,QAAQ,QAAQ,SAAS,OAAO,OAAO,SAAS;EACtD,KAAK,MAAM,YAAY,OAAO;GAC5B,mBAAmB,KAAK;IACtB,GAAI,SAAS,aAAa,KAAA,IAAY,CAAC,IAAI,EAAE,UAAU,SAAS,SAAS;IACzE,MAAM;IACN,UAAU,SAAS;GACrB,CAAC;GACD,gBAAgB,IAAI,QAAQ,QAAQ,GAAG,QAAQ;EACjD;CACF;CACA,IAAI,kBAAkB,CAAC,GAAG,gBAAgB,OAAO,CAAC;CAClD,IAAI,iBAAiB,CAAC,cACpB,kBAAkB,CAChB,GAAI,MAAM,sBAAsB,iBAAiB,OAAO,eAAe,YAAY,CACrF;CAEF,MAAM,kBAAkB,MAAM,sBAAsB,iBAAiB,KAAK;CAC1E,MAAM,cAAc,IAAI,IACtB,CAAC,GAAG,eAAe,CAAC,CAAC,KAAK,CAAC,UAAU,UAAU,CAAC,QAAQ,QAAQ,GAAG,IAAI,CAAC,CAC1E;CACA,MAAM,0BAAU,IAAI,IAAuB;CAC3C,KAAK,MAAM,EAAE,UAAU,MAAM,cAAc,oBAAoB;EAC7D,MAAM,OAAO,YAAY,IAAI,QAAQ,IAAI,CAAC;EAC1C,IAAI,SAAS,KAAA,GACX;EAEF,MAAM,MAAM,GAAG,QAAQ,IAAI,EAAE,IAAI,SAAS,MAAM,IAAI,SAAS;EAC7D,MAAM,WAAW,QAAQ,IAAI,GAAG;EAChC,IAAI,aAAa,KAAA,GAAW;GAC1B,cAAc,UAAU,QAAQ;GAChC;EACF;EACA,QAAQ,IAAI,KAAK;GACf;GACA,GAAI,aAAa,KAAA,IAAY,CAAC,IAAI,EAAE,SAAS;GAC7C;GACA;EACF,CAAC;CACH;CACA,OAAO,CAAC,GAAG,QAAQ,OAAO,CAAC;AAC7B;;;AC3LA,SAAS,WAAW,OAA2B,WAAwC;CACrF,IAAI,UAAU,KACZ,OAAO,cAAc,KAAA,KAAa,CAAC,kBAAkB,KAAK,SAAS;CAErE,OAAO,UAAU,KAAA,KAAa,CAAC,qBAAqB,KAAK,KAAK;AAChE;AACA,SAAS,eACP,QACA,MACA,QACA,MACA,OACM;CACN,MAAM,SAAS,QAAQ,aAAa,UAAU,MAAM,YAAY,IAAI;CACpE,IAAI,SAAS,OAAO,QAAQ,MAAM;CAClC,OAAO,WAAW,IAAI;EACpB,MAAM,MAAM,SAAS,OAAO;EAC5B,IAAI,WAAW,KAAK,SAAS,IAAI,KAAK,OAAO,KAAK,WAAW,KAAK,MAAM,KAAK,MAAM,EAAE,GAAG;GACtF,MAAM,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,KAAK,MAAM,QAAQ,GAAG;GACtD,IAAI,CAAC,KAAK,IAAI,GAAG,GAAG;IAClB,KAAK,IAAI,GAAG;IACZ,OAAO,KAAK;KACV;KACA,MAAM;KACN,OAAO;KACP;IACF,CAAC;GACH;EACF;EACA,SAAS,OAAO,QAAQ,QAAQ,SAAS,CAAC;CAC5C;AACF;AACA,eAAsB,oBACpB,MACA,OACA,eACA,cACsB;CACtB,MAAM,UAAU,MAAM,QAAQ,IAC5B,MAAM,KAAK,SAAS,kBAAkB,MAAM,eAAe,YAAY,CAAC,CAC1E;CACA,MAAM,SAAsB,CAAC;CAC7B,MAAM,uBAAO,IAAI,IAAY;CAC7B,MAAM,0BAAU,IAAI,IAAY;CAChC,MAAM,SAAS,QAAQ,aAAa,UAAU,KAAK,YAAY,IAAI;CACnE,KAAK,MAAM,CAAC,WAAW,oBAAoB,QAAQ,QAAQ,GAAG;EAC5D,MAAM,OAAO,MAAM;EACnB,IAAI,SAAS,KAAA,GACX;EAEF,KAAK,MAAM,iBAAiB,iBAAiB;GAC3C,MAAM,gBAAgB,SAAS,QAAQ,MAAM,aAAa;GAC1D,MAAM,WAAW;IACf;IACA,cAAc,WAAW,KAAK,SAAS,GAAG;IAC1C;IACA,cAAc,WAAW,SAAS,KAAK,GAAG;GAC5C;GACA,KAAK,MAAM,SAAS,UAAU;IAC5B,MAAM,MAAM,QAAQ,aAAa,UAAU,MAAM,YAAY,IAAI;IACjE,IAAI,CAAC,QAAQ,IAAI,GAAG,GAAG;KACrB,QAAQ,IAAI,GAAG;KACf,eAAe,QAAQ,MAAM,QAAQ,MAAM,KAAK;IAClD;GACF;EACF;CACF;CACA,OAAO;AACT;;;ACjEA,MAAa,YAAY,SAAS,eAAe,SAAS;AAC1D,SAAS,kBAAkB,OAA4C;CACrE,IACE,OAAO,UAAU,YACjB,UAAU,QACV,MAAM,QAAQ,KAAK,KACnB,OAAO,OAAO,KAAK,CAAC,CAAC,MAAM,SAAS,OAAO,SAAS,QAAQ,GAE5D,MAAM,IAAI,UAAU,8CAA8C;AAEtE;AACA,eAAsB,kBACpB,MACA,OACA,aACA,YAAuB,CAAC,GACxB,gBAAyB,SAAS,wBAClC,eAAwB,SAAS,uBACX;CACtB,IAAI,OAAO,SAAS,UAClB,MAAM,IAAI,UAAU,uBAAuB;CAE7C,IAAI,CAAC,OAAO,UAAU,KAAK,KAAK,QAAQ,KAAK,QAAQ,WACnD,MAAM,IAAI,WAAW,sCAAsC,WAAW;CAExE,kBAAkB,SAAS;CAC3B,IAAI,OAAO,kBAAkB,WAC3B,MAAM,IAAI,UAAU,iCAAiC;CAEvD,IAAI,OAAO,iBAAiB,WAC1B,MAAM,IAAI,UAAU,gCAAgC;CAEtD,MAAM,QAAQ,MAAM,yBAAyB,WAAW;CACxD,MAAM,aAAa,kBAAkB,MAAM,KAAK;CAChD,IAAI,UAAU,WACZ,WAAW,KAAK,GAAI,MAAM,oBAAoB,MAAM,OAAO,eAAe,YAAY,CAAE;CAE1F,OAAO,mBAAmB,YAAY,OAAO,WAAW,eAAe,YAAY;AACrF"}
@@ -1 +1 @@
1
- export declare function resolveLocalUncPath(value: string): string | undefined;
1
+ export declare function resolveUncPath(value: string): string | undefined;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pathprobe",
3
- "version": "0.4.3",
3
+ "version": "0.5.3",
4
4
  "description": "Extract, resolve, and validate file and directory paths mentioned in text, with variable expansion, ignore rules, hidden-file control, and configurable search roots.",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -29,6 +29,7 @@
29
29
  "dependencies": {
30
30
  "fast-glob": "latest",
31
31
  "globby": "latest",
32
+ "koffi": "latest",
32
33
  "p-limit": "latest"
33
34
  },
34
35
  "devDependencies": {