@sergenkabakci/grept 0.0.0-stage → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +169 -2
- package/bin/grept.js +2 -0
- package/dist/cli/args.d.ts +50 -0
- package/dist/cli/args.d.ts.map +1 -0
- package/dist/cli/args.js +501 -0
- package/dist/cli/args.js.map +1 -0
- package/dist/cli/help.d.ts +2 -0
- package/dist/cli/help.d.ts.map +1 -0
- package/dist/cli/help.js +76 -0
- package/dist/cli/help.js.map +1 -0
- package/dist/cli/version.d.ts +3 -0
- package/dist/cli/version.d.ts.map +1 -0
- package/dist/cli/version.js +11 -0
- package/dist/cli/version.js.map +1 -0
- package/dist/core/binary.d.ts +6 -0
- package/dist/core/binary.d.ts.map +1 -0
- package/dist/core/binary.js +14 -0
- package/dist/core/binary.js.map +1 -0
- package/dist/core/encoding.d.ts +10 -0
- package/dist/core/encoding.d.ts.map +1 -0
- package/dist/core/encoding.js +16 -0
- package/dist/core/encoding.js.map +1 -0
- package/dist/core/line-reader.d.ts +19 -0
- package/dist/core/line-reader.d.ts.map +1 -0
- package/dist/core/line-reader.js +69 -0
- package/dist/core/line-reader.js.map +1 -0
- package/dist/core/matcher.d.ts +58 -0
- package/dist/core/matcher.d.ts.map +1 -0
- package/dist/core/matcher.js +342 -0
- package/dist/core/matcher.js.map +1 -0
- package/dist/core/offsets.d.ts +5 -0
- package/dist/core/offsets.d.ts.map +1 -0
- package/dist/core/offsets.js +11 -0
- package/dist/core/offsets.js.map +1 -0
- package/dist/core/patterns.d.ts +17 -0
- package/dist/core/patterns.d.ts.map +1 -0
- package/dist/core/patterns.js +223 -0
- package/dist/core/patterns.js.map +1 -0
- package/dist/core/search.d.ts +5 -0
- package/dist/core/search.d.ts.map +1 -0
- package/dist/core/search.js +249 -0
- package/dist/core/search.js.map +1 -0
- package/dist/errors/errors.d.ts +17 -0
- package/dist/errors/errors.d.ts.map +1 -0
- package/dist/errors/errors.js +32 -0
- package/dist/errors/errors.js.map +1 -0
- package/dist/errors/exit-codes.d.ts +7 -0
- package/dist/errors/exit-codes.d.ts.map +1 -0
- package/dist/errors/exit-codes.js +6 -0
- package/dist/errors/exit-codes.js.map +1 -0
- package/dist/filesystem/discover.d.ts +10 -0
- package/dist/filesystem/discover.d.ts.map +1 -0
- package/dist/filesystem/discover.js +110 -0
- package/dist/filesystem/discover.js.map +1 -0
- package/dist/filesystem/glob.d.ts +9 -0
- package/dist/filesystem/glob.d.ts.map +1 -0
- package/dist/filesystem/glob.js +61 -0
- package/dist/filesystem/glob.js.map +1 -0
- package/dist/filesystem/reparse-points.d.ts +10 -0
- package/dist/filesystem/reparse-points.d.ts.map +1 -0
- package/dist/filesystem/reparse-points.js +28 -0
- package/dist/filesystem/reparse-points.js.map +1 -0
- package/dist/filesystem/traversal.d.ts +15 -0
- package/dist/filesystem/traversal.d.ts.map +1 -0
- package/dist/filesystem/traversal.js +88 -0
- package/dist/filesystem/traversal.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +50 -0
- package/dist/index.js.map +1 -0
- package/dist/output/color.d.ts +11 -0
- package/dist/output/color.d.ts.map +1 -0
- package/dist/output/color.js +25 -0
- package/dist/output/color.js.map +1 -0
- package/dist/output/context.d.ts +21 -0
- package/dist/output/context.d.ts.map +1 -0
- package/dist/output/context.js +78 -0
- package/dist/output/context.js.map +1 -0
- package/dist/output/formatter.d.ts +24 -0
- package/dist/output/formatter.d.ts.map +1 -0
- package/dist/output/formatter.js +112 -0
- package/dist/output/formatter.js.map +1 -0
- package/dist/output/writer.d.ts +10 -0
- package/dist/output/writer.d.ts.map +1 -0
- package/dist/output/writer.js +62 -0
- package/dist/output/writer.js.map +1 -0
- package/dist/utils/terminal.d.ts +7 -0
- package/dist/utils/terminal.d.ts.map +1 -0
- package/dist/utils/terminal.js +21 -0
- package/dist/utils/terminal.js.map +1 -0
- package/dist/utils/windows-paths.d.ts +21 -0
- package/dist/utils/windows-paths.d.ts.map +1 -0
- package/dist/utils/windows-paths.js +47 -0
- package/dist/utils/windows-paths.js.map +1 -0
- package/docs/COMPATIBILITY.md +118 -0
- package/docs/PERFORMANCE.md +58 -0
- package/docs/REGEX.md +99 -0
- package/docs/WINDOWS.md +46 -0
- package/package.json +65 -4
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 grept contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,170 @@
|
|
|
1
|
-
#
|
|
1
|
+
# `grept` — Windows-Native GNU grep-Compatible CLI
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A production-ready, high-performance command-line text search utility designed specifically for Windows 10 and Windows 11. `grept` reproduces GNU grep's command-line interface, options, and matching semantics as closely as possible without requiring WSL, Git Bash, MSYS2, Cygwin, or native compilation.
|
|
4
|
+
|
|
5
|
+
[](https://github.com/sergenkabakci/grept/actions)
|
|
6
|
+
[](https://opensource.org/licenses/MIT)
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## Features
|
|
11
|
+
|
|
12
|
+
- **GNU grep Command-Line Compatibility**: Full support for standard pattern flags, output formatting, byte offsets, context controls, and recursive traversal.
|
|
13
|
+
- **Four Regex Engines**:
|
|
14
|
+
- `-G`, `--basic-regexp`: Basic Regular Expressions (GNU BRE syntax, default).
|
|
15
|
+
- `-E`, `--extended-regexp`: Extended Regular Expressions (POSIX ERE syntax).
|
|
16
|
+
- `-F`, `--fixed-strings`: High-speed literal substring matching.
|
|
17
|
+
- `-P`, `--perl-regexp`: WebAssembly-compiled PCRE2 engine supporting lookahead, lookbehind, atomic groups, and ReDoS protection.
|
|
18
|
+
- **Windows-Native Semantics**:
|
|
19
|
+
- Handles DOS drive paths (`C:\...`), UNC network paths (`\\server\share\...`), and extended-length paths (`\\?\...`).
|
|
20
|
+
- Traverses NTFS file systems with cycle detection across symbolic links and NTFS junction points.
|
|
21
|
+
- Native support for Windows CRLF (`\r\n`), LF, and missing final newline endings.
|
|
22
|
+
- Case-insensitive Windows file system and glob matching.
|
|
23
|
+
- **Streaming & Memory Efficiency**:
|
|
24
|
+
- 64 KB chunked streaming avoids loading entire files into memory; memory footprint remains bounded under 15 MB even on gigabyte-sized files.
|
|
25
|
+
- **Accurate Byte Offsets (`-b`)**:
|
|
26
|
+
- Measures raw byte positions in the input stream (properly accounting for multi-byte UTF-8 sequences and CRLF delimiters).
|
|
27
|
+
- **PowerShell and CMD Pipeline Integration**:
|
|
28
|
+
- Streams data cleanly through PowerShell (`Get-Content app.log | grept "error"`) and CMD (`type app.log | grept "error"`).
|
|
29
|
+
- **Zero Native Build Dependencies**:
|
|
30
|
+
- Written in TypeScript and runs on Node.js 20+; uses pure WebAssembly for PCRE2.
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## Installation
|
|
35
|
+
|
|
36
|
+
### Global Installation
|
|
37
|
+
```powershell
|
|
38
|
+
npm install -g @sergenkabakci/grept
|
|
39
|
+
```
|
|
40
|
+
Once installed globally, you can invoke the CLI directly as `grept`.
|
|
41
|
+
|
|
42
|
+
### On-Demand Execution (No install required)
|
|
43
|
+
```powershell
|
|
44
|
+
npx @sergenkabakci/grept --version
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## Usage Examples
|
|
50
|
+
|
|
51
|
+
### Tested PowerShell Examples
|
|
52
|
+
```powershell
|
|
53
|
+
# Basic search in a log file
|
|
54
|
+
grept "error" app.log
|
|
55
|
+
|
|
56
|
+
# Case-insensitive search with line numbers
|
|
57
|
+
grept -in "exception" app.log
|
|
58
|
+
|
|
59
|
+
# Recursive search from current directory
|
|
60
|
+
grept -rn "TODO" .
|
|
61
|
+
|
|
62
|
+
# Recursive search restricted to TypeScript files
|
|
63
|
+
grept -rn --include="*.ts" "useEffect" src
|
|
64
|
+
|
|
65
|
+
# Exclude directories from recursive search
|
|
66
|
+
grept -rn --exclude-dir=node_modules --exclude-dir=.git "TODO" .
|
|
67
|
+
|
|
68
|
+
# Output 3 lines of context around matches
|
|
69
|
+
grept -n -C 3 "Exception" app.log
|
|
70
|
+
|
|
71
|
+
# Extended regular expression search
|
|
72
|
+
grept -E "ERROR|WARNING|CRITICAL" app.log
|
|
73
|
+
|
|
74
|
+
# Fixed string search with Windows paths containing spaces
|
|
75
|
+
grept -F "C:\Program Files" config.txt
|
|
76
|
+
|
|
77
|
+
# List only files containing matches
|
|
78
|
+
grept -l "database" *.log
|
|
79
|
+
|
|
80
|
+
# Count total matching lines
|
|
81
|
+
grept -c "ERROR" *.log
|
|
82
|
+
|
|
83
|
+
# Pipeline search from PowerShell Get-Content
|
|
84
|
+
Get-Content app.log | grept "error"
|
|
85
|
+
|
|
86
|
+
# Null-delimited data search
|
|
87
|
+
Get-Content -Raw app.log | grept -z "error"
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
## Option Reference
|
|
93
|
+
|
|
94
|
+
### Pattern Selection
|
|
95
|
+
- `-E`, `--extended-regexp`: Interpret patterns as extended regular expressions.
|
|
96
|
+
- `-F`, `--fixed-strings`: Interpret patterns as fixed strings.
|
|
97
|
+
- `-G`, `--basic-regexp`: Interpret patterns as basic regular expressions (default).
|
|
98
|
+
- `-P`, `--perl-regexp`: Interpret patterns as Perl-compatible regular expressions (PCRE2).
|
|
99
|
+
- `-e PATTERN`, `--regexp=PATTERN`: Specify matching pattern (can be used multiple times).
|
|
100
|
+
- `-f FILE`, `--file=FILE`: Read patterns from file, one per line.
|
|
101
|
+
- `-i`, `--ignore-case`: Case-insensitive matching (including Turkish `İ`/`i` and `I`/`ı`).
|
|
102
|
+
- `-v`, `--invert-match`: Select non-matching lines.
|
|
103
|
+
- `-w`, `--word-regexp`: Match only whole words.
|
|
104
|
+
- `-x`, `--line-regexp`: Match only entire lines.
|
|
105
|
+
|
|
106
|
+
### Matching Control
|
|
107
|
+
- `-m NUM`, `--max-count=NUM`: Stop after `NUM` selected lines.
|
|
108
|
+
- `--line-buffered`: Flush output on every line.
|
|
109
|
+
- `-a`, `--text`: Process binary files as text.
|
|
110
|
+
- `-I`: Ignore binary files (treat as non-matching).
|
|
111
|
+
- `--binary-files=TYPE`: Specify binary handling (`binary`, `text`, `without-match`).
|
|
112
|
+
|
|
113
|
+
### Output Control
|
|
114
|
+
- `-b`, `--byte-offset`: Print 0-based byte offset of each output line.
|
|
115
|
+
- `-n`, `--line-number`: Print 1-based line number.
|
|
116
|
+
- `-H`, `--with-filename`: Print filename prefix for each match.
|
|
117
|
+
- `-h`, `--no-filename`: Suppress filename prefix.
|
|
118
|
+
- `--label=LABEL`: Use `LABEL` as standard input filename prefix.
|
|
119
|
+
- `-o`, `--only-matching`: Print only matching parts of lines.
|
|
120
|
+
- `-q`, `--quiet`, `--silent`: Exit immediately with status 0 upon finding a match.
|
|
121
|
+
- `-s`, `--no-messages`: Suppress error messages for nonexistent or unreadable files.
|
|
122
|
+
- `-c`, `--count`: Output only count of matching lines per file.
|
|
123
|
+
- `-l`, `--files-with-matches`: Output filenames of files containing matches.
|
|
124
|
+
- `-L`, `--files-without-match`: Output filenames of files containing no matches.
|
|
125
|
+
- `-Z`, `--null`: Print NUL (`\0`) byte instead of colon after filename.
|
|
126
|
+
- `-z`, `--null-data`: Input and output lines end in NUL byte instead of newline.
|
|
127
|
+
- `-T`, `--initial-tab`: Align output lines using a leading tab.
|
|
128
|
+
- `--color[=WHEN]`: Highlight matches (`never`, `always`, `auto`).
|
|
129
|
+
|
|
130
|
+
### Context Control
|
|
131
|
+
- `-B NUM`, `--before-context=NUM`: Print `NUM` lines of leading context.
|
|
132
|
+
- `-A NUM`, `--after-context=NUM`: Print `NUM` lines of trailing context.
|
|
133
|
+
- `-C NUM`, `--context=NUM`, `-NUM`: Print `NUM` lines of before and after context.
|
|
134
|
+
- `--group-separator=SEP`: Context group separator (default `--`).
|
|
135
|
+
- `--no-group-separator`: Suppress group separator.
|
|
136
|
+
|
|
137
|
+
### File and Directory Selection
|
|
138
|
+
- `-r`, `--recursive`: Recurse subdirectories (does not follow directory symlinks/junctions).
|
|
139
|
+
- `-R`, `--dereference-recursive`: Recurse subdirectories and dereference directory symlinks/junctions.
|
|
140
|
+
- `--follow`: Follow directory symlinks and reparse points.
|
|
141
|
+
- `--include=GLOB`: Search only files matching `GLOB`.
|
|
142
|
+
- `--exclude=GLOB`: Skip files matching `GLOB`.
|
|
143
|
+
- `--exclude-from=FILE`: Skip files matching glob patterns read from `FILE`.
|
|
144
|
+
- `--exclude-dir=GLOB`: Skip directories matching `GLOB`.
|
|
145
|
+
- `--max-depth=NUM`: Limit traversal to `NUM` directory levels.
|
|
146
|
+
- `-d ACTION`, `--directories=ACTION`: Directory handling (`read`, `recurse`, `skip`).
|
|
147
|
+
- `-D ACTION`, `--devices=ACTION`: Device handling (`read`, `skip`).
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
## Exit Codes
|
|
152
|
+
|
|
153
|
+
- `0`: One or more selected lines or matches were found.
|
|
154
|
+
- `1`: No lines were selected.
|
|
155
|
+
- `2`: An error occurred (e.g. invalid regex syntax, unreadable file without `-s`).
|
|
156
|
+
|
|
157
|
+
---
|
|
158
|
+
|
|
159
|
+
## Detailed Documentation
|
|
160
|
+
|
|
161
|
+
- [GNU grep Compatibility Matrix](docs/COMPATIBILITY.md)
|
|
162
|
+
- [Regex Engines & Matching Semantics](docs/REGEX.md)
|
|
163
|
+
- [Windows File System & Shell Notes](docs/WINDOWS.md)
|
|
164
|
+
- [Performance Architecture & Benchmarks](docs/PERFORMANCE.md)
|
|
165
|
+
|
|
166
|
+
---
|
|
167
|
+
|
|
168
|
+
## License
|
|
169
|
+
|
|
170
|
+
MIT © [grept contributors](LICENSE)
|
package/bin/grept.js
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type { ColorChoice } from '../utils/terminal.js';
|
|
2
|
+
export type RegexMode = 'basic' | 'extended' | 'fixed' | 'pcre';
|
|
3
|
+
export type BinaryMode = 'binary' | 'text' | 'without-match';
|
|
4
|
+
export type DirectoryAction = 'read' | 'recurse' | 'skip';
|
|
5
|
+
export type DeviceAction = 'read' | 'skip';
|
|
6
|
+
export interface CliOptions {
|
|
7
|
+
regexMode: RegexMode;
|
|
8
|
+
ignoreCase: boolean;
|
|
9
|
+
invertMatch: boolean;
|
|
10
|
+
wordRegexp: boolean;
|
|
11
|
+
lineRegexp: boolean;
|
|
12
|
+
patterns: string[];
|
|
13
|
+
patternFiles: string[];
|
|
14
|
+
maxCount?: number;
|
|
15
|
+
byteOffset: boolean;
|
|
16
|
+
lineNumber: boolean;
|
|
17
|
+
withFilename?: boolean;
|
|
18
|
+
label?: string;
|
|
19
|
+
onlyMatching: boolean;
|
|
20
|
+
quiet: boolean;
|
|
21
|
+
noMessages: boolean;
|
|
22
|
+
count: boolean;
|
|
23
|
+
filesWithMatches: boolean;
|
|
24
|
+
filesWithoutMatch: boolean;
|
|
25
|
+
initialTab: boolean;
|
|
26
|
+
nullByteFilename: boolean;
|
|
27
|
+
nullData: boolean;
|
|
28
|
+
lineBuffered: boolean;
|
|
29
|
+
color: ColorChoice;
|
|
30
|
+
unixByteOffsets: boolean;
|
|
31
|
+
binaryFiles: BinaryMode;
|
|
32
|
+
beforeContext: number;
|
|
33
|
+
afterContext: number;
|
|
34
|
+
groupSeparator: string | null;
|
|
35
|
+
recursive: boolean;
|
|
36
|
+
dereferenceRecursive: boolean;
|
|
37
|
+
includes: string[];
|
|
38
|
+
excludes: string[];
|
|
39
|
+
excludeFrom: string[];
|
|
40
|
+
excludeDirs: string[];
|
|
41
|
+
maxDepth?: number;
|
|
42
|
+
directories: DirectoryAction;
|
|
43
|
+
devices: DeviceAction;
|
|
44
|
+
debug: boolean;
|
|
45
|
+
help: boolean;
|
|
46
|
+
version: boolean;
|
|
47
|
+
targets: string[];
|
|
48
|
+
}
|
|
49
|
+
export declare function parseArgs(rawArgs: string[]): CliOptions;
|
|
50
|
+
//# sourceMappingURL=args.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"args.d.ts","sourceRoot":"","sources":["../../src/cli/args.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAExD,MAAM,MAAM,SAAS,GAAG,OAAO,GAAG,UAAU,GAAG,OAAO,GAAG,MAAM,CAAC;AAChE,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,MAAM,GAAG,eAAe,CAAC;AAC7D,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,SAAS,GAAG,MAAM,CAAC;AAC1D,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,MAAM,CAAC;AAE3C,MAAM,WAAW,UAAU;IAEzB,SAAS,EAAE,SAAS,CAAC;IAGrB,UAAU,EAAE,OAAO,CAAC;IACpB,WAAW,EAAE,OAAO,CAAC;IACrB,UAAU,EAAE,OAAO,CAAC;IACpB,UAAU,EAAE,OAAO,CAAC;IAGpB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,YAAY,EAAE,MAAM,EAAE,CAAC;IAGvB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,OAAO,CAAC;IACpB,UAAU,EAAE,OAAO,CAAC;IACpB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,OAAO,CAAC;IACtB,KAAK,EAAE,OAAO,CAAC;IACf,UAAU,EAAE,OAAO,CAAC;IACpB,KAAK,EAAE,OAAO,CAAC;IACf,gBAAgB,EAAE,OAAO,CAAC;IAC1B,iBAAiB,EAAE,OAAO,CAAC;IAC3B,UAAU,EAAE,OAAO,CAAC;IACpB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,QAAQ,EAAE,OAAO,CAAC;IAClB,YAAY,EAAE,OAAO,CAAC;IACtB,KAAK,EAAE,WAAW,CAAC;IACnB,eAAe,EAAE,OAAO,CAAC;IAGzB,WAAW,EAAE,UAAU,CAAC;IAGxB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAG9B,SAAS,EAAE,OAAO,CAAC;IACnB,oBAAoB,EAAE,OAAO,CAAC;IAC9B,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,eAAe,CAAC;IAC7B,OAAO,EAAE,YAAY,CAAC;IAGtB,KAAK,EAAE,OAAO,CAAC;IACf,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;IAGjB,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,UAAU,CAyfvD"}
|