@jsonkit/db 3.0.1 → 4.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/README.md +47 -45
- package/dist/cjs/index.cjs +85 -22
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/esm/index.js +80 -23
- package/dist/esm/index.js.map +1 -1
- package/dist/index.d.ts +183 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +14 -13
- package/dist/types/common/index.d.ts +0 -2
- package/dist/types/common/multiEntryDb.d.ts +0 -19
- package/dist/types/common/types.d.ts +0 -38
- package/dist/types/file/__tests__/multiEntryFileDb.test.d.ts +0 -1
- package/dist/types/file/__tests__/singleEntryFileDb.test.d.ts +0 -1
- package/dist/types/file/files.d.ts +0 -44
- package/dist/types/file/multiEntryFileDb.d.ts +0 -20
- package/dist/types/file/singleEntryFileDb.d.ts +0 -13
- package/dist/types/index.d.ts +0 -5
- package/dist/types/memory/__tests__/multiEntryMemDb.test.d.ts +0 -1
- package/dist/types/memory/__tests__/singleEntryMemDb.test.d.ts +0 -1
- package/dist/types/memory/multiEntryMemDb.d.ts +0 -11
- package/dist/types/memory/singleEntryMemDb.d.ts +0 -8
package/README.md
CHANGED
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
|
|
5
5
|
The package exposes two core concepts:
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
- **Single-entry databases** – manage exactly one JSON-serializable object.
|
|
8
|
+
- **Multi-entry databases** – manage collections of identifiable records keyed by an `id`.
|
|
9
9
|
|
|
10
10
|
Both concepts are available in **file-backed** and **in-memory** variants.
|
|
11
11
|
|
|
@@ -27,20 +27,22 @@ Multi-entry databases manage collections of entries keyed by `id`.
|
|
|
27
27
|
|
|
28
28
|
All multi-entry implementations expose the same methods:
|
|
29
29
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
30
|
+
- `create(entry)`
|
|
31
|
+
- `getById(id)`
|
|
32
|
+
- `getByIdOrThrow(id)`
|
|
33
|
+
- `getWhere(predicate, pagination?)`
|
|
34
|
+
- `getFirstWhere(predicate)`
|
|
35
|
+
- `getFirstWhereOrThrow(predicate)`
|
|
36
|
+
- `getAll(ids?)`
|
|
37
|
+
- `getAllIds()`
|
|
38
|
+
- `update(id, updater)`
|
|
39
|
+
- `deleteById(id)`
|
|
40
|
+
- `deleteByIds(ids)`
|
|
41
|
+
- `deleteWhere(predicate)`
|
|
42
|
+
- `exists(id)`
|
|
43
|
+
- `countAll()`
|
|
44
|
+
- `countWhere(predicate)`
|
|
45
|
+
- `destroy()`
|
|
44
46
|
|
|
45
47
|
Updates are **partial merges**, and changing an entry’s `id` during an update is supported.
|
|
46
48
|
|
|
@@ -58,9 +60,9 @@ const db = new MultiEntryFileDb<User>('./data/users')
|
|
|
58
60
|
|
|
59
61
|
#### Behavior
|
|
60
62
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
63
|
+
- Each entry is stored as `<id>.json` in the provided directory.
|
|
64
|
+
- The directory is created implicitly as files are written.
|
|
65
|
+
- IDs are validated to prevent path traversal by default.
|
|
64
66
|
|
|
65
67
|
#### Constructor
|
|
66
68
|
|
|
@@ -77,9 +79,9 @@ new MultiEntryFileDb<T>(dirpath, options?)
|
|
|
77
79
|
|
|
78
80
|
#### Notes
|
|
79
81
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
82
|
+
- Failed reads (missing file or invalid JSON) return `null`.
|
|
83
|
+
- `destroy()` deletes the entire directory.
|
|
84
|
+
- Intended for development, prototyping, and small datasets.
|
|
83
85
|
|
|
84
86
|
---
|
|
85
87
|
|
|
@@ -95,9 +97,9 @@ const db = new MultiEntryMemDb<User>()
|
|
|
95
97
|
|
|
96
98
|
#### Behavior
|
|
97
99
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
100
|
+
- Fast, ephemeral storage.
|
|
101
|
+
- Ideal for tests and short-lived processes.
|
|
102
|
+
- `destroy()` clears all entries.
|
|
101
103
|
|
|
102
104
|
---
|
|
103
105
|
|
|
@@ -107,10 +109,10 @@ Single-entry databases manage **exactly one value**, often used for configuratio
|
|
|
107
109
|
|
|
108
110
|
### Common API (`SingleEntryDb<T>`)
|
|
109
111
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
112
|
+
- `isInited()`
|
|
113
|
+
- `read()`
|
|
114
|
+
- `write(entry | updater)`
|
|
115
|
+
- `delete()`
|
|
114
116
|
|
|
115
117
|
`write` supports either replacing the entry or partially updating it via an updater function.
|
|
116
118
|
|
|
@@ -128,9 +130,9 @@ const db = new SingleEntryFileDb<AppConfig>('./config.json')
|
|
|
128
130
|
|
|
129
131
|
#### Behavior
|
|
130
132
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
133
|
+
- Reads and writes a single JSON file.
|
|
134
|
+
- `isInited()` checks file existence.
|
|
135
|
+
- `read()` throws if the file does not exist.
|
|
134
136
|
|
|
135
137
|
#### Constructor
|
|
136
138
|
|
|
@@ -138,7 +140,7 @@ const db = new SingleEntryFileDb<AppConfig>('./config.json')
|
|
|
138
140
|
new SingleEntryFileDb<T>(filepath, parser?)
|
|
139
141
|
```
|
|
140
142
|
|
|
141
|
-
|
|
143
|
+
- `parser` defaults to `JSON`.
|
|
142
144
|
|
|
143
145
|
---
|
|
144
146
|
|
|
@@ -154,9 +156,9 @@ const db = new SingleEntryMemDb<AppConfig>()
|
|
|
154
156
|
|
|
155
157
|
#### Behavior
|
|
156
158
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
159
|
+
- Optional initial value.
|
|
160
|
+
- `read()` throws if uninitialized.
|
|
161
|
+
- `delete()` resets the entry to `null`.
|
|
160
162
|
|
|
161
163
|
---
|
|
162
164
|
|
|
@@ -178,11 +180,11 @@ const allUsers = await users.getAll()
|
|
|
178
180
|
|
|
179
181
|
## Use Cases
|
|
180
182
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
183
|
+
- Rapid application prototyping
|
|
184
|
+
- CLI tools
|
|
185
|
+
- Small internal services
|
|
186
|
+
- Tests and mocks
|
|
187
|
+
- Configuration and state persistence
|
|
186
188
|
|
|
187
189
|
---
|
|
188
190
|
|
|
@@ -235,10 +237,10 @@ type DeleteManyOutput = {
|
|
|
235
237
|
|
|
236
238
|
## Non-goals
|
|
237
239
|
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
240
|
+
- Concurrency control
|
|
241
|
+
- High-performance querying
|
|
242
|
+
- Large datasets
|
|
243
|
+
- ACID guarantees
|
|
242
244
|
|
|
243
245
|
For these, a dedicated database is recommended.
|
|
244
246
|
|
package/dist/cjs/index.cjs
CHANGED
|
@@ -27,13 +27,42 @@ var path__namespace = /*#__PURE__*/_interopNamespaceDefault(path);
|
|
|
27
27
|
var fsSync__namespace = /*#__PURE__*/_interopNamespaceDefault(fsSync);
|
|
28
28
|
var readline__namespace = /*#__PURE__*/_interopNamespaceDefault(readline);
|
|
29
29
|
|
|
30
|
+
class DbError extends Error {
|
|
31
|
+
}
|
|
32
|
+
class NotFoundError extends DbError {
|
|
33
|
+
}
|
|
34
|
+
class ConflictError extends DbError {
|
|
35
|
+
}
|
|
36
|
+
class FileIoError extends DbError {
|
|
37
|
+
}
|
|
38
|
+
class InvalidIdError extends DbError {
|
|
39
|
+
constructor(id) {
|
|
40
|
+
super(`Invalid entry id '${id}'`);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
class UninitError extends DbError {
|
|
44
|
+
constructor() {
|
|
45
|
+
super('Cannot read or update uninitialized entry. Use write(entry) to initialize first.');
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
30
49
|
class MultiEntryDb {
|
|
31
50
|
async getByIdOrThrow(id) {
|
|
32
51
|
const entry = await this.getById(id);
|
|
33
52
|
if (!entry)
|
|
34
|
-
throw new
|
|
53
|
+
throw new NotFoundError(`Entry with id '${id}' does not exist`);
|
|
35
54
|
return entry;
|
|
36
55
|
}
|
|
56
|
+
async getFirstWhere(predicate) {
|
|
57
|
+
const matches = await this.getWhere(predicate, { page: 0, take: 1 });
|
|
58
|
+
return matches.at(0) ?? null;
|
|
59
|
+
}
|
|
60
|
+
async getFirstWhereOrThrow(predicate) {
|
|
61
|
+
const match = await this.getFirstWhere(predicate);
|
|
62
|
+
if (!match)
|
|
63
|
+
throw new NotFoundError('No entry matches predicate');
|
|
64
|
+
return match;
|
|
65
|
+
}
|
|
37
66
|
async getWhere(predicate, pagination) {
|
|
38
67
|
let totalMatched = 0;
|
|
39
68
|
const entries = [];
|
|
@@ -127,6 +156,9 @@ class MultiEntryDb {
|
|
|
127
156
|
}
|
|
128
157
|
}
|
|
129
158
|
|
|
159
|
+
class SingleEntryDb {
|
|
160
|
+
}
|
|
161
|
+
|
|
130
162
|
exports.FileType = void 0;
|
|
131
163
|
(function (FileType) {
|
|
132
164
|
FileType["File"] = "file";
|
|
@@ -143,7 +175,7 @@ class Files {
|
|
|
143
175
|
const { recursive = false, overwrite = true } = options ?? {};
|
|
144
176
|
// Check if destination exists and handle overwrite
|
|
145
177
|
if (!overwrite && (await this.exists(destinationPath))) {
|
|
146
|
-
throw new
|
|
178
|
+
throw new FileIoError(`Destination '${destinationPath}' already exists`);
|
|
147
179
|
}
|
|
148
180
|
const sourceStats = await fs__namespace.stat(sourcePath);
|
|
149
181
|
if (sourceStats.isFile()) {
|
|
@@ -154,7 +186,7 @@ class Files {
|
|
|
154
186
|
}
|
|
155
187
|
if (sourceStats.isDirectory()) {
|
|
156
188
|
if (!recursive) {
|
|
157
|
-
throw new
|
|
189
|
+
throw new FileIoError(`'${sourcePath}' is a directory (use recursive option)`);
|
|
158
190
|
}
|
|
159
191
|
await this.copyRecursive(sourcePath, destinationPath);
|
|
160
192
|
}
|
|
@@ -291,7 +323,7 @@ class Files {
|
|
|
291
323
|
...commonMeta,
|
|
292
324
|
type: exports.FileType.File,
|
|
293
325
|
};
|
|
294
|
-
throw new
|
|
326
|
+
throw new FileIoError(`File at ${filepath} is not normal file or directory`);
|
|
295
327
|
}
|
|
296
328
|
async list(dirpath, options) {
|
|
297
329
|
const { depth = 0, stripBasepath } = options ?? {};
|
|
@@ -344,6 +376,10 @@ class Files {
|
|
|
344
376
|
}
|
|
345
377
|
|
|
346
378
|
class MultiEntryFileDb extends MultiEntryDb {
|
|
379
|
+
dirpath;
|
|
380
|
+
files;
|
|
381
|
+
parser;
|
|
382
|
+
noPathlikeIds;
|
|
347
383
|
constructor(dirpath, options) {
|
|
348
384
|
super();
|
|
349
385
|
this.dirpath = dirpath;
|
|
@@ -357,7 +393,7 @@ class MultiEntryFileDb extends MultiEntryDb {
|
|
|
357
393
|
}
|
|
358
394
|
async getById(id) {
|
|
359
395
|
if (!this.isIdValid(id))
|
|
360
|
-
throw new
|
|
396
|
+
throw new InvalidIdError(id);
|
|
361
397
|
try {
|
|
362
398
|
const filepath = this.getFilePath(id);
|
|
363
399
|
const text = await this.files.read(filepath);
|
|
@@ -402,7 +438,7 @@ class MultiEntryFileDb extends MultiEntryDb {
|
|
|
402
438
|
}
|
|
403
439
|
async writeEntry(entry) {
|
|
404
440
|
if (!this.isIdValid(entry.id))
|
|
405
|
-
throw new
|
|
441
|
+
throw new InvalidIdError(entry.id);
|
|
406
442
|
const filepath = this.getFilePath(entry.id);
|
|
407
443
|
await this.files.write(filepath, JSON.stringify(entry, null, 2));
|
|
408
444
|
}
|
|
@@ -434,11 +470,14 @@ class MultiEntryFileDb extends MultiEntryDb {
|
|
|
434
470
|
}
|
|
435
471
|
}
|
|
436
472
|
|
|
437
|
-
class SingleEntryFileDb {
|
|
473
|
+
class SingleEntryFileDb extends SingleEntryDb {
|
|
474
|
+
filepath;
|
|
475
|
+
parser;
|
|
476
|
+
files = new Files();
|
|
438
477
|
constructor(filepath, parser = JSON) {
|
|
478
|
+
super();
|
|
439
479
|
this.filepath = filepath;
|
|
440
480
|
this.parser = parser;
|
|
441
|
-
this.files = new Files();
|
|
442
481
|
}
|
|
443
482
|
path() {
|
|
444
483
|
return this.filepath;
|
|
@@ -472,10 +511,7 @@ class SingleEntryFileDb {
|
|
|
472
511
|
}
|
|
473
512
|
|
|
474
513
|
class MultiEntryMemDb extends MultiEntryDb {
|
|
475
|
-
|
|
476
|
-
super(...arguments);
|
|
477
|
-
this.entries = new Map();
|
|
478
|
-
}
|
|
514
|
+
entries = new Map();
|
|
479
515
|
async create(entry) {
|
|
480
516
|
this.entries.set(entry.id, entry);
|
|
481
517
|
return entry;
|
|
@@ -508,28 +544,40 @@ class MultiEntryMemDb extends MultiEntryDb {
|
|
|
508
544
|
yield id;
|
|
509
545
|
}
|
|
510
546
|
}
|
|
547
|
+
async persist(dirpath) {
|
|
548
|
+
const fileDb = new MultiEntryFileDb(dirpath);
|
|
549
|
+
await fileDb.destroy();
|
|
550
|
+
const values = [...this.entries.values()];
|
|
551
|
+
await Promise.all(values.map((entry) => fileDb.create(entry)));
|
|
552
|
+
}
|
|
553
|
+
async load(dirpath, parser) {
|
|
554
|
+
const fileDb = new MultiEntryFileDb(dirpath, { parser });
|
|
555
|
+
for await (const entry of fileDb.iterEntries()) {
|
|
556
|
+
await this.create(entry);
|
|
557
|
+
}
|
|
558
|
+
}
|
|
511
559
|
}
|
|
512
560
|
|
|
513
|
-
class SingleEntryMemDb {
|
|
561
|
+
class SingleEntryMemDb extends SingleEntryDb {
|
|
562
|
+
entry = null;
|
|
514
563
|
constructor(initialEntry = null) {
|
|
515
|
-
|
|
564
|
+
super();
|
|
516
565
|
this.entry = initialEntry;
|
|
517
566
|
}
|
|
518
|
-
isInited() {
|
|
567
|
+
async isInited() {
|
|
519
568
|
return this.entry !== null;
|
|
520
569
|
}
|
|
521
|
-
read() {
|
|
570
|
+
async read() {
|
|
522
571
|
if (this.entry === null)
|
|
523
|
-
throw new
|
|
572
|
+
throw new UninitError();
|
|
524
573
|
return this.entry;
|
|
525
574
|
}
|
|
526
|
-
write(updaterOrEntry) {
|
|
575
|
+
async write(updaterOrEntry) {
|
|
527
576
|
let entry;
|
|
528
577
|
if (typeof updaterOrEntry === 'function') {
|
|
529
578
|
const updater = updaterOrEntry;
|
|
530
|
-
if (this.entry === null)
|
|
531
|
-
throw new
|
|
532
|
-
}
|
|
579
|
+
if (this.entry === null)
|
|
580
|
+
throw new UninitError();
|
|
533
581
|
const updatedFields = updater(this.entry);
|
|
534
582
|
entry = { ...this.entry, ...updatedFields };
|
|
535
583
|
}
|
|
@@ -539,13 +587,28 @@ class SingleEntryMemDb {
|
|
|
539
587
|
this.entry = entry;
|
|
540
588
|
return entry;
|
|
541
589
|
}
|
|
542
|
-
delete() {
|
|
590
|
+
async delete() {
|
|
543
591
|
this.entry = null;
|
|
544
592
|
}
|
|
593
|
+
async persist(filepath) {
|
|
594
|
+
const fileDb = new SingleEntryFileDb(filepath);
|
|
595
|
+
await fileDb.write(await this.read());
|
|
596
|
+
}
|
|
597
|
+
async load(filepath, parser) {
|
|
598
|
+
const fileDb = new SingleEntryFileDb(filepath, parser);
|
|
599
|
+
const persistedEntry = await fileDb.read();
|
|
600
|
+
this.write(persistedEntry);
|
|
601
|
+
}
|
|
545
602
|
}
|
|
546
603
|
|
|
604
|
+
exports.ConflictError = ConflictError;
|
|
605
|
+
exports.DbError = DbError;
|
|
606
|
+
exports.FileIoError = FileIoError;
|
|
607
|
+
exports.InvalidIdError = InvalidIdError;
|
|
547
608
|
exports.MultiEntryFileDb = MultiEntryFileDb;
|
|
548
609
|
exports.MultiEntryMemDb = MultiEntryMemDb;
|
|
610
|
+
exports.NotFoundError = NotFoundError;
|
|
549
611
|
exports.SingleEntryFileDb = SingleEntryFileDb;
|
|
550
612
|
exports.SingleEntryMemDb = SingleEntryMemDb;
|
|
613
|
+
exports.UninitError = UninitError;
|
|
551
614
|
//# sourceMappingURL=index.cjs.map
|
package/dist/cjs/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":["../../src/common/multiEntryDb.ts","../../src/common/types.ts","../../src/file/files.ts","../../src/file/multiEntryFileDb.ts","../../src/file/singleEntryFileDb.ts","../../src/memory/multiEntryMemDb.ts","../../src/memory/singleEntryMemDb.ts"],"sourcesContent":["import type {\n Identifiable,\n DeleteManyOutput,\n PaginationInput,\n PredicateFn,\n Promisable,\n} from './types'\n\nexport abstract class MultiEntryDb<T extends Identifiable> {\n abstract create(entry: T): Promise<T>\n\n abstract getById(id: T['id']): Promise<T | null>\n\n abstract update(id: T['id'], updater: (entry: T) => Promisable<Partial<T>>): Promise<T>\n\n abstract deleteById(id: T['id']): Promise<boolean>\n\n abstract destroy(): Promise<void>\n\n protected abstract iterEntries(): AsyncIterable<T>\n\n protected abstract iterIds(): AsyncIterable<T['id']>\n\n async getByIdOrThrow(id: T['id']): Promise<T> {\n const entry = await this.getById(id)\n if (!entry) throw new Error(`Entry with id '${id}' does not exist`)\n return entry\n }\n\n async getWhere(predicate: PredicateFn<T>, pagination?: PaginationInput): Promise<T[]> {\n let totalMatched = 0\n const entries: T[] = []\n\n if (!pagination) {\n for await (const entry of this.iterEntries()) {\n const isMatch = predicate(entry)\n if (isMatch) entries.push(entry)\n }\n return entries\n }\n\n const { take, page } = pagination\n const skip = pagination.skip ?? 0\n const startIndex = (page - 1) * take + skip\n const endIndex = startIndex + take\n\n for await (const entry of this.iterEntries()) {\n const isMatch = predicate(entry)\n if (isMatch) {\n if (totalMatched >= startIndex && totalMatched < endIndex) {\n entries.push(entry)\n }\n totalMatched++\n\n if (totalMatched >= endIndex) break\n }\n }\n\n return entries\n }\n\n getAll(): Promise<T[]> {\n return this.getWhere(() => true)\n }\n\n async getAllIds(): Promise<T['id'][]> {\n const ids: T['id'][] = []\n for await (const id of this.iterIds()) {\n ids.push(id)\n }\n return ids\n }\n\n deleteByIds(ids: T['id'][]): Promise<DeleteManyOutput> {\n return this.deleteWhere((entry) => ids.includes(entry.id))\n }\n\n async deleteWhere(predicate: PredicateFn<T>): Promise<DeleteManyOutput> {\n const deletedIds: T['id'][] = []\n const ignoredIds: T['id'][] = []\n\n for await (const entry of this.iterEntries()) {\n if (!predicate(entry)) continue\n\n const didDelete = await this.deleteById(entry.id)\n if (didDelete) {\n deletedIds.push(entry.id)\n } else {\n ignoredIds.push(entry.id)\n }\n }\n\n return { deletedIds, ignoredIds }\n }\n\n async exists(id: T['id']): Promise<boolean> {\n const entry = await this.getById(id)\n return entry !== null\n }\n\n countAll(): Promise<number> {\n return this.countWhere(() => true)\n }\n\n async countWhere(predicate: PredicateFn<T>, pagination?: PaginationInput): Promise<number> {\n let totalMatched = 0\n let count = 0\n\n if (!pagination) {\n for await (const entry of this.iterEntries()) {\n const isMatch = predicate(entry)\n if (isMatch) count++\n }\n return count\n }\n\n const { take, page } = pagination\n const skip = pagination.skip ?? 0\n const startIndex = (page - 1) * take + skip\n const endIndex = startIndex + take\n\n for await (const entry of this.iterEntries()) {\n const isMatch = predicate(entry)\n if (isMatch) {\n if (totalMatched >= startIndex && totalMatched < endIndex) count++\n totalMatched++\n\n if (totalMatched >= endIndex) break\n }\n }\n\n return count\n }\n}\n","export type Identifiable = {\n id: Id\n}\n\nexport type Id = string\n\nexport type Promisable<T> = T | Promise<T>\n\nexport type PaginationInput = {\n take: number\n page: number\n skip?: number | undefined | null\n}\n\nexport type DeleteManyOutput = {\n deletedIds: Id[]\n ignoredIds: Id[]\n}\n\nexport type PredicateFn<T extends Identifiable> = (entry: T) => boolean\n\nexport type JsonEntryParser<T> = {\n parse: (text: string) => T\n}\n\nexport type MultiEntryFileDbOptions<T> = {\n noPathlikeIds?: boolean\n parser?: JsonEntryParser<T>\n}\n\nexport type FileMeta = {\n path: string\n size: number\n created: Date\n modified: Date\n accessed: Date\n} & (\n | {\n type: FileType.File\n }\n | {\n type: FileType.Directory\n children: FileMeta[]\n }\n)\n\nexport enum FileType {\n File = 'file',\n Directory = 'directory',\n //Symlink: 'symlink'\n}\n","import type { FileMeta } from '../common/types'\nimport { FileType } from '../common/types'\nimport * as fs from 'fs/promises'\nimport * as path from 'path'\nimport * as fsSync from 'fs'\nimport * as readline from 'readline'\n\ntype ListOptions = {\n depth?: number\n stripBasepath?: string\n}\n\ntype DeleteOptions = {\n force?: boolean\n recursive?: boolean\n}\n\ntype WriteOptions = {\n encoding?: BufferEncoding\n}\n\ntype ReadOptions = {\n encoding?: BufferEncoding\n lines?: number\n}\n\ntype CopyOptions = {\n recursive?: boolean\n overwrite?: boolean\n}\n\nconst DEFUALT_ENCODING: BufferEncoding = 'utf-8'\n\nexport class Files {\n async move(oldPath: string, newPath: string) {\n await fs.rename(oldPath, newPath)\n }\n\n async copy(sourcePath: string, destinationPath: string, options?: CopyOptions) {\n const { recursive = false, overwrite = true } = options ?? {}\n\n // Check if destination exists and handle overwrite\n if (!overwrite && (await this.exists(destinationPath))) {\n throw new Error(`Destination '${destinationPath}' already exists`)\n }\n\n const sourceStats = await fs.stat(sourcePath)\n\n if (sourceStats.isFile()) {\n const destinationDir = path.dirname(destinationPath)\n await this.mkdirUnsafe(destinationDir)\n await fs.copyFile(sourcePath, destinationPath)\n return\n }\n\n if (sourceStats.isDirectory()) {\n if (!recursive) {\n throw new Error(`'${sourcePath}' is a directory (use recursive option)`)\n }\n await this.copyRecursive(sourcePath, destinationPath)\n }\n }\n\n async copyRecursive(sourcePath: string, destinationPath: string) {\n const sourceStats = await fs.stat(sourcePath)\n\n if (sourceStats.isFile()) {\n const destinationDir = path.dirname(destinationPath)\n await this.mkdirUnsafe(destinationDir)\n await fs.copyFile(sourcePath, destinationPath)\n return\n }\n\n if (sourceStats.isDirectory()) {\n await this.mkdirUnsafe(destinationPath)\n const entries = await fs.readdir(sourcePath)\n\n for (const entry of entries) {\n const sourceEntryPath = path.join(sourcePath, entry)\n const destEntryPath = path.join(destinationPath, entry)\n await this.copyRecursive(sourceEntryPath, destEntryPath)\n }\n }\n }\n\n async mkdir(filepath: string) {\n await this.mkdirUnsafe(filepath)\n }\n\n protected async mkdirUnsafe(filepath: string) {\n await fs.mkdir(filepath, { recursive: true })\n }\n\n async write(filepath: string, content: string, options?: WriteOptions) {\n const { encoding = DEFUALT_ENCODING } = options ?? {}\n\n const parentDirs = path.dirname(filepath)\n await this.mkdirUnsafe(parentDirs)\n\n await fs.writeFile(filepath, content, encoding)\n }\n\n async touch(filepath: string) {\n const exists = await this.exists(filepath)\n if (!exists) await this.write(filepath, '')\n }\n\n async read(filepath: string, options?: ReadOptions) {\n const { encoding = DEFUALT_ENCODING, lines } = options ?? {}\n\n if (lines === undefined) {\n return await fs.readFile(filepath, encoding)\n }\n\n const stream = fsSync.createReadStream(filepath, { encoding })\n const reader = readline.createInterface({\n input: stream,\n crlfDelay: Infinity,\n })\n\n let result = ''\n let linesRead = 0\n for await (const line of reader) {\n if (linesRead >= lines) break\n result += line + '\\n'\n linesRead++\n }\n\n return result\n }\n\n async delete(filepath: string, options?: DeleteOptions) {\n const { force = true, recursive = true } = options ?? {}\n await fs.rm(filepath, { force, recursive })\n }\n\n async exists(filepath: string) {\n try {\n await fs.access(filepath)\n return true\n } catch {\n return false\n }\n }\n\n async isDir(filepath: string) {\n try {\n const stats = await fs.stat(filepath)\n return stats.isDirectory()\n } catch {\n return false\n }\n }\n\n async isFile(filepath: string) {\n try {\n const stats = await fs.stat(filepath)\n return stats.isFile()\n } catch {\n return false\n }\n }\n\n async isSymlink(filepath: string) {\n try {\n const stats = await fs.stat(filepath)\n return stats.isSymbolicLink()\n } catch {\n return false\n }\n }\n\n async getMeta(filepath: string, options?: ListOptions): Promise<FileMeta> {\n const { depth = 0, stripBasepath } = options ?? {}\n const stats = await fs.stat(filepath)\n const isDir = stats.isDirectory()\n const isFile = stats.isFile()\n\n const { size, ctime, mtime, atime } = stats\n const commonMeta = {\n path: this.stripBasepath(filepath, stripBasepath),\n size,\n created: ctime,\n modified: mtime,\n accessed: atime,\n }\n\n if (isDir) {\n const children: FileMeta[] = []\n\n if (depth > 0) {\n const childNames = await this.list(filepath)\n\n for (const child of childNames) {\n const childDepth = Math.max(0, depth - 1)\n const childMeta = await this.getMeta(path.join(filepath, child), {\n depth: childDepth,\n stripBasepath,\n })\n children.push(childMeta)\n }\n }\n\n return {\n ...commonMeta,\n type: FileType.Directory,\n children,\n }\n }\n if (isFile)\n return {\n ...commonMeta,\n type: FileType.File,\n }\n\n throw new Error(`File at ${filepath} is not normal file or directory`)\n }\n\n async list(dirpath: string, options?: ListOptions) {\n const { depth = 0, stripBasepath } = options ?? {}\n if (depth > 0) {\n return await this.listRecursive(dirpath, depth, 0, stripBasepath)\n }\n return await fs.readdir(dirpath)\n }\n\n async *listRead(dirpath: string, options?: ListOptions) {\n const { depth = 0 } = options ?? {}\n\n const files = await this.list(dirpath, { depth })\n\n for (const filepath of files) {\n const isFile = await this.isFile(filepath)\n if (!isFile) continue\n\n try {\n const content = await this.read(filepath)\n yield {\n filepath,\n content,\n }\n } catch {\n // Skip files that can't be read\n continue\n }\n }\n }\n\n protected async listRecursive(\n dirpath: string,\n maxDepth: number,\n currentDepth: number,\n stripBasepath: string | undefined,\n ): Promise<string[]> {\n const results: string[] = []\n const entries = await fs.readdir(dirpath, { withFileTypes: true })\n\n for (const entry of entries) {\n const fullPath = path.join(dirpath, entry.name)\n const strippedPath = this.stripBasepath(fullPath, stripBasepath)\n results.push(strippedPath)\n\n if (entry.isDirectory() && currentDepth < maxDepth) {\n const subResults = await this.listRecursive(\n fullPath,\n maxDepth,\n currentDepth + 1,\n stripBasepath,\n )\n results.push(...subResults)\n }\n }\n\n return results\n }\n\n protected stripBasepath(original: string, pathToStrip: string | undefined): string {\n if (!pathToStrip) return original\n const base = pathToStrip.replace(/^\\/+/, '/').replace(/\\/+$/, '/')\n const stripped = original.replace(base, '')\n return `/${stripped}`\n }\n}\n","import {\n Identifiable,\n DeleteManyOutput,\n Promisable,\n JsonEntryParser,\n MultiEntryFileDbOptions,\n MultiEntryDb,\n} from '../common'\nimport { Files } from './files'\nimport * as path from 'path'\n\nexport class MultiEntryFileDb<T extends Identifiable> extends MultiEntryDb<T> {\n protected readonly dirpath: string\n protected readonly files: Files\n protected readonly parser: JsonEntryParser<T>\n readonly noPathlikeIds: boolean\n\n constructor(dirpath: string, options?: MultiEntryFileDbOptions<T>) {\n super()\n this.dirpath = dirpath\n this.files = new Files()\n this.parser = options?.parser ?? JSON\n this.noPathlikeIds = options?.noPathlikeIds ?? true\n }\n\n async create(entry: T): Promise<T> {\n await this.writeEntry(entry)\n return entry\n }\n\n async getById(id: T['id']): Promise<T | null> {\n if (!this.isIdValid(id)) throw new Error(`Invalid id: ${id}`)\n\n try {\n const filepath = this.getFilePath(id)\n const text = await this.files.read(filepath)\n const entry = this.parser.parse(text)\n return entry\n } catch (error) {\n console.error('Failed to read entry', error)\n // File doesn't exist or invalid JSON\n return null\n }\n }\n\n async update(id: T['id'], updater: (entry: T) => Promisable<Partial<T>>): Promise<T> {\n const entry = await this.getByIdOrThrow(id)\n\n const updatedEntryFields = await updater(entry)\n const updatedEntry = { ...entry, ...updatedEntryFields }\n await this.writeEntry(updatedEntry)\n\n if (updatedEntry.id !== id) {\n await this.deleteById(id)\n }\n\n return updatedEntry\n }\n\n async deleteById(id: T['id']): Promise<boolean> {\n try {\n const filepath = this.getFilePath(id)\n await this.files.delete(filepath, { force: false })\n return true\n } catch {\n // File might not exist, ignore error\n return false\n }\n }\n\n async deleteByIds(ids: T['id'][]): Promise<DeleteManyOutput> {\n return this.deleteWhere((entry) => ids.includes(entry.id))\n }\n\n async destroy() {\n await this.files.delete(this.dirpath)\n }\n\n protected getFilePath(id: T['id']) {\n return path.join(this.dirpath, `${id}.json`)\n }\n\n protected async writeEntry(entry: T) {\n if (!this.isIdValid(entry.id)) throw new Error(`Invalid id: ${entry.id}`)\n\n const filepath = this.getFilePath(entry.id)\n await this.files.write(filepath, JSON.stringify(entry, null, 2))\n }\n\n isIdValid(id: T['id']): boolean {\n if (typeof id !== 'string') return false\n\n if (!this.noPathlikeIds) return true\n\n if (id.includes('/') || id.includes('\\\\')) return false\n\n return true\n }\n\n protected async *iterEntries() {\n for await (const id of this.iterIds()) {\n const entry = await this.getById(id)\n if (entry) yield entry\n }\n }\n\n protected async *iterIds() {\n const filenames = await this.files.list(this.dirpath)\n for (const filename of filenames) {\n if (!filename.endsWith('.json')) continue\n\n const id = filename.replace(/\\.json$/, '')\n if (this.isIdValid(id)) yield id\n }\n }\n}\n","import { JsonEntryParser, Promisable } from '../common/types'\nimport { Files } from './files'\n\nexport class SingleEntryFileDb<T> {\n protected readonly files: Files = new Files()\n\n constructor(\n protected readonly filepath: string,\n protected readonly parser: JsonEntryParser<T> = JSON,\n ) {}\n\n path() {\n return this.filepath\n }\n\n async isInited() {\n const exists = await this.files.exists(this.filepath)\n return exists\n }\n\n async read() {\n const text = await this.files.read(this.filepath)\n const entry = this.parser.parse(text)\n return entry\n }\n\n async write(updaterOrEntry: T | ((entry: T) => Promisable<Partial<T>>)): Promise<T> {\n let entry: T\n if (typeof updaterOrEntry === 'function') {\n const updater = updaterOrEntry as (entry: T) => T\n const existing = await this.read()\n\n const updatedFields = await updater(existing)\n entry = { ...existing, ...updatedFields }\n } else {\n entry = updaterOrEntry\n }\n\n await this.files.write(this.filepath, JSON.stringify(entry, null, 2))\n\n return entry\n }\n\n async delete(): Promise<void> {\n await this.files.delete(this.filepath)\n }\n}\n","import { Identifiable, Promisable, MultiEntryDb } from '../common'\n\nexport class MultiEntryMemDb<T extends Identifiable> extends MultiEntryDb<T> {\n protected entries: Map<T['id'], T> = new Map()\n\n async create(entry: T): Promise<T> {\n this.entries.set(entry.id, entry)\n return entry\n }\n\n async getById(id: T['id']): Promise<T | null> {\n return this.entries.get(id) ?? null\n }\n\n async update(id: T['id'], updater: (entry: T) => Promisable<Partial<T>>): Promise<T> {\n const entry = await this.getByIdOrThrow(id)\n\n const updatedEntryFields = await updater(entry)\n const updatedEntry = { ...entry, ...updatedEntryFields }\n\n this.entries.set(updatedEntry.id, updatedEntry)\n\n if (updatedEntry.id !== id) this.entries.delete(id)\n\n return updatedEntry\n }\n\n async deleteById(id: T['id']): Promise<boolean> {\n return this.entries.delete(id)\n }\n\n async destroy() {\n this.entries.clear()\n }\n\n protected async *iterEntries() {\n for (const entry of this.entries.values()) {\n yield entry\n }\n }\n\n protected async *iterIds() {\n for (const id of this.entries.keys()) {\n yield id\n }\n }\n}\n","export class SingleEntryMemDb<T> {\n protected entry: T | null = null\n\n constructor(initialEntry: T | null = null) {\n this.entry = initialEntry\n }\n\n isInited() {\n return this.entry !== null\n }\n\n read(): T {\n if (this.entry === null) throw new Error('Entry not initialized')\n return this.entry\n }\n\n write(updaterOrEntry: T | ((entry: T) => Partial<T>)): T {\n let entry: T\n\n if (typeof updaterOrEntry === 'function') {\n const updater = updaterOrEntry as (entry: T) => Partial<T>\n\n if (this.entry === null) {\n throw new Error('Cannot update uninitialized entry. Use write(entry) to initialize first.')\n }\n\n const updatedFields = updater(this.entry)\n entry = { ...this.entry, ...updatedFields }\n } else {\n entry = updaterOrEntry\n }\n\n this.entry = entry\n return entry\n }\n\n delete() {\n this.entry = null\n }\n}\n"],"names":["FileType","fs","path","fsSync","readline"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../../../src/common/errors.ts","../../../src/common/multiEntryDb.ts","../../../src/common/singleEntryDb.ts","../../../src/common/types.ts","../../../src/file/files.ts","../../../src/file/multiEntryFileDb.ts","../../../src/file/singleEntryFileDb.ts","../../../src/memory/multiEntryMemDb.ts","../../../src/memory/singleEntryMemDb.ts"],"sourcesContent":["export class DbError extends Error {}\n\nexport class NotFoundError extends DbError {}\n\nexport class ConflictError extends DbError {}\n\nexport class FileIoError extends DbError {}\n\nexport class InvalidIdError extends DbError {\n constructor(id: unknown) {\n super(`Invalid entry id '${id}'`)\n }\n}\n\nexport class UninitError extends DbError {\n constructor() {\n super('Cannot read or update uninitialized entry. Use write(entry) to initialize first.')\n }\n}\n","import { NotFoundError } from './errors'\nimport type {\n Identifiable,\n DeleteManyOutput,\n PaginationInput,\n PredicateFn,\n UpdaterFn,\n} from './types'\n\nexport abstract class MultiEntryDb<T extends Identifiable> {\n abstract create(entry: T): Promise<T>\n\n abstract getById(id: T['id']): Promise<T | null>\n\n abstract update(id: T['id'], updater: UpdaterFn<T>): Promise<T>\n\n abstract deleteById(id: T['id']): Promise<boolean>\n\n abstract destroy(): Promise<void>\n\n abstract iterEntries(): AsyncIterable<T>\n\n abstract iterIds(): AsyncIterable<T['id']>\n\n async getByIdOrThrow(id: T['id']): Promise<T> {\n const entry = await this.getById(id)\n if (!entry) throw new NotFoundError(`Entry with id '${id}' does not exist`)\n return entry\n }\n\n async getFirstWhere(predicate: PredicateFn<T>): Promise<T | null> {\n const matches = await this.getWhere(predicate, { page: 0, take: 1 })\n return matches.at(0) ?? null\n }\n\n async getFirstWhereOrThrow(predicate: PredicateFn<T>): Promise<T | null> {\n const match = await this.getFirstWhere(predicate)\n if (!match) throw new NotFoundError('No entry matches predicate')\n return match\n }\n\n async getWhere(predicate: PredicateFn<T>, pagination?: PaginationInput): Promise<T[]> {\n let totalMatched = 0\n const entries: T[] = []\n\n if (!pagination) {\n for await (const entry of this.iterEntries()) {\n const isMatch = predicate(entry)\n if (isMatch) entries.push(entry)\n }\n return entries\n }\n\n const { take, page } = pagination\n const skip = pagination.skip ?? 0\n const startIndex = (page - 1) * take + skip\n const endIndex = startIndex + take\n\n for await (const entry of this.iterEntries()) {\n const isMatch = predicate(entry)\n if (isMatch) {\n if (totalMatched >= startIndex && totalMatched < endIndex) {\n entries.push(entry)\n }\n totalMatched++\n\n if (totalMatched >= endIndex) break\n }\n }\n\n return entries\n }\n\n getAll(): Promise<T[]> {\n return this.getWhere(() => true)\n }\n\n async getAllIds(): Promise<T['id'][]> {\n const ids: T['id'][] = []\n for await (const id of this.iterIds()) {\n ids.push(id)\n }\n return ids\n }\n\n deleteByIds(ids: T['id'][]): Promise<DeleteManyOutput> {\n return this.deleteWhere((entry) => ids.includes(entry.id))\n }\n\n async deleteWhere(predicate: PredicateFn<T>): Promise<DeleteManyOutput> {\n const deletedIds: T['id'][] = []\n const ignoredIds: T['id'][] = []\n\n for await (const entry of this.iterEntries()) {\n if (!predicate(entry)) continue\n\n const didDelete = await this.deleteById(entry.id)\n if (didDelete) {\n deletedIds.push(entry.id)\n } else {\n ignoredIds.push(entry.id)\n }\n }\n\n return { deletedIds, ignoredIds }\n }\n\n async exists(id: T['id']): Promise<boolean> {\n const entry = await this.getById(id)\n return entry !== null\n }\n\n countAll(): Promise<number> {\n return this.countWhere(() => true)\n }\n\n async countWhere(predicate: PredicateFn<T>, pagination?: PaginationInput): Promise<number> {\n let totalMatched = 0\n let count = 0\n\n if (!pagination) {\n for await (const entry of this.iterEntries()) {\n const isMatch = predicate(entry)\n if (isMatch) count++\n }\n return count\n }\n\n const { take, page } = pagination\n const skip = pagination.skip ?? 0\n const startIndex = (page - 1) * take + skip\n const endIndex = startIndex + take\n\n for await (const entry of this.iterEntries()) {\n const isMatch = predicate(entry)\n if (isMatch) {\n if (totalMatched >= startIndex && totalMatched < endIndex) count++\n totalMatched++\n\n if (totalMatched >= endIndex) break\n }\n }\n\n return count\n }\n}\n","import type { Promisable, UpdaterFn } from '../common/types'\n\nexport abstract class SingleEntryDb<T> {\n abstract isInited(): Promise<boolean>\n abstract read(): Promise<T>\n abstract write(updaterOrEntry: T | UpdaterFn<T>): Promise<T>\n abstract delete(): Promise<void>\n}\n","export type Identifiable = {\n id: Id\n}\n\nexport type Id = string\n\nexport type Promisable<T> = T | Promise<T>\n\nexport type PaginationInput = {\n take: number\n page: number\n skip?: number | undefined | null\n}\n\nexport type DeleteManyOutput = {\n deletedIds: Id[]\n ignoredIds: Id[]\n}\n\nexport type PredicateFn<T extends Identifiable> = (entry: T) => boolean\n\nexport type UpdaterFn<T> = (entry: T) => Promisable<Partial<T>>\n\nexport type JsonEntryParser<T> = {\n parse: (text: string) => T\n}\n\nexport type MultiEntryFileDbOptions<T> = {\n noPathlikeIds?: boolean\n parser?: JsonEntryParser<T>\n}\n\nexport type FileMeta = {\n path: string\n size: number\n created: Date\n modified: Date\n accessed: Date\n} & (\n | {\n type: FileType.File\n }\n | {\n type: FileType.Directory\n children: FileMeta[]\n }\n)\n\nexport enum FileType {\n File = 'file',\n Directory = 'directory',\n //Symlink: 'symlink'\n}\n","import type { FileMeta } from '../common'\nimport { FileType, FileIoError } from '../common'\nimport * as fs from 'fs/promises'\nimport * as path from 'path'\nimport * as fsSync from 'fs'\nimport * as readline from 'readline'\n\ntype ListOptions = {\n depth?: number\n stripBasepath?: string\n}\n\ntype DeleteOptions = {\n force?: boolean\n recursive?: boolean\n}\n\ntype WriteOptions = {\n encoding?: BufferEncoding\n}\n\ntype ReadOptions = {\n encoding?: BufferEncoding\n lines?: number\n}\n\ntype CopyOptions = {\n recursive?: boolean\n overwrite?: boolean\n}\n\nconst DEFUALT_ENCODING: BufferEncoding = 'utf-8'\n\nexport class Files {\n async move(oldPath: string, newPath: string) {\n await fs.rename(oldPath, newPath)\n }\n\n async copy(sourcePath: string, destinationPath: string, options?: CopyOptions) {\n const { recursive = false, overwrite = true } = options ?? {}\n\n // Check if destination exists and handle overwrite\n if (!overwrite && (await this.exists(destinationPath))) {\n throw new FileIoError(`Destination '${destinationPath}' already exists`)\n }\n\n const sourceStats = await fs.stat(sourcePath)\n\n if (sourceStats.isFile()) {\n const destinationDir = path.dirname(destinationPath)\n await this.mkdirUnsafe(destinationDir)\n await fs.copyFile(sourcePath, destinationPath)\n return\n }\n\n if (sourceStats.isDirectory()) {\n if (!recursive) {\n throw new FileIoError(`'${sourcePath}' is a directory (use recursive option)`)\n }\n await this.copyRecursive(sourcePath, destinationPath)\n }\n }\n\n async copyRecursive(sourcePath: string, destinationPath: string) {\n const sourceStats = await fs.stat(sourcePath)\n\n if (sourceStats.isFile()) {\n const destinationDir = path.dirname(destinationPath)\n await this.mkdirUnsafe(destinationDir)\n await fs.copyFile(sourcePath, destinationPath)\n return\n }\n\n if (sourceStats.isDirectory()) {\n await this.mkdirUnsafe(destinationPath)\n const entries = await fs.readdir(sourcePath)\n\n for (const entry of entries) {\n const sourceEntryPath = path.join(sourcePath, entry)\n const destEntryPath = path.join(destinationPath, entry)\n await this.copyRecursive(sourceEntryPath, destEntryPath)\n }\n }\n }\n\n async mkdir(filepath: string) {\n await this.mkdirUnsafe(filepath)\n }\n\n protected async mkdirUnsafe(filepath: string) {\n await fs.mkdir(filepath, { recursive: true })\n }\n\n async write(filepath: string, content: string, options?: WriteOptions) {\n const { encoding = DEFUALT_ENCODING } = options ?? {}\n\n const parentDirs = path.dirname(filepath)\n await this.mkdirUnsafe(parentDirs)\n\n await fs.writeFile(filepath, content, encoding)\n }\n\n async touch(filepath: string) {\n const exists = await this.exists(filepath)\n if (!exists) await this.write(filepath, '')\n }\n\n async read(filepath: string, options?: ReadOptions) {\n const { encoding = DEFUALT_ENCODING, lines } = options ?? {}\n\n if (lines === undefined) {\n return await fs.readFile(filepath, encoding)\n }\n\n const stream = fsSync.createReadStream(filepath, { encoding })\n const reader = readline.createInterface({\n input: stream,\n crlfDelay: Infinity,\n })\n\n let result = ''\n let linesRead = 0\n for await (const line of reader) {\n if (linesRead >= lines) break\n result += line + '\\n'\n linesRead++\n }\n\n return result\n }\n\n async delete(filepath: string, options?: DeleteOptions) {\n const { force = true, recursive = true } = options ?? {}\n await fs.rm(filepath, { force, recursive })\n }\n\n async exists(filepath: string) {\n try {\n await fs.access(filepath)\n return true\n } catch {\n return false\n }\n }\n\n async isDir(filepath: string) {\n try {\n const stats = await fs.stat(filepath)\n return stats.isDirectory()\n } catch {\n return false\n }\n }\n\n async isFile(filepath: string) {\n try {\n const stats = await fs.stat(filepath)\n return stats.isFile()\n } catch {\n return false\n }\n }\n\n async isSymlink(filepath: string) {\n try {\n const stats = await fs.stat(filepath)\n return stats.isSymbolicLink()\n } catch {\n return false\n }\n }\n\n async getMeta(filepath: string, options?: ListOptions): Promise<FileMeta> {\n const { depth = 0, stripBasepath } = options ?? {}\n const stats = await fs.stat(filepath)\n const isDir = stats.isDirectory()\n const isFile = stats.isFile()\n\n const { size, ctime, mtime, atime } = stats\n const commonMeta = {\n path: this.stripBasepath(filepath, stripBasepath),\n size,\n created: ctime,\n modified: mtime,\n accessed: atime,\n }\n\n if (isDir) {\n const children: FileMeta[] = []\n\n if (depth > 0) {\n const childNames = await this.list(filepath)\n\n for (const child of childNames) {\n const childDepth = Math.max(0, depth - 1)\n const childMeta = await this.getMeta(path.join(filepath, child), {\n depth: childDepth,\n stripBasepath,\n })\n children.push(childMeta)\n }\n }\n\n return {\n ...commonMeta,\n type: FileType.Directory,\n children,\n }\n }\n if (isFile)\n return {\n ...commonMeta,\n type: FileType.File,\n }\n\n throw new FileIoError(`File at ${filepath} is not normal file or directory`)\n }\n\n async list(dirpath: string, options?: ListOptions) {\n const { depth = 0, stripBasepath } = options ?? {}\n if (depth > 0) {\n return await this.listRecursive(dirpath, depth, 0, stripBasepath)\n }\n return await fs.readdir(dirpath)\n }\n\n async *listRead(dirpath: string, options?: ListOptions) {\n const { depth = 0 } = options ?? {}\n\n const files = await this.list(dirpath, { depth })\n\n for (const filepath of files) {\n const isFile = await this.isFile(filepath)\n if (!isFile) continue\n\n try {\n const content = await this.read(filepath)\n yield {\n filepath,\n content,\n }\n } catch {\n // Skip files that can't be read\n continue\n }\n }\n }\n\n protected async listRecursive(\n dirpath: string,\n maxDepth: number,\n currentDepth: number,\n stripBasepath: string | undefined,\n ): Promise<string[]> {\n const results: string[] = []\n const entries = await fs.readdir(dirpath, { withFileTypes: true })\n\n for (const entry of entries) {\n const fullPath = path.join(dirpath, entry.name)\n const strippedPath = this.stripBasepath(fullPath, stripBasepath)\n results.push(strippedPath)\n\n if (entry.isDirectory() && currentDepth < maxDepth) {\n const subResults = await this.listRecursive(\n fullPath,\n maxDepth,\n currentDepth + 1,\n stripBasepath,\n )\n results.push(...subResults)\n }\n }\n\n return results\n }\n\n protected stripBasepath(original: string, pathToStrip: string | undefined): string {\n if (!pathToStrip) return original\n const base = pathToStrip.replace(/^\\/+/, '/').replace(/\\/+$/, '/')\n const stripped = original.replace(base, '')\n return `/${stripped}`\n }\n}\n","import {\n Identifiable,\n DeleteManyOutput,\n Promisable,\n JsonEntryParser,\n MultiEntryFileDbOptions,\n MultiEntryDb,\n InvalidIdError,\n} from '../common'\nimport { Files } from './files'\nimport * as path from 'path'\n\nexport class MultiEntryFileDb<T extends Identifiable> extends MultiEntryDb<T> {\n protected readonly dirpath: string\n protected readonly files: Files\n protected readonly parser: JsonEntryParser<T>\n readonly noPathlikeIds: boolean\n\n constructor(dirpath: string, options?: MultiEntryFileDbOptions<T>) {\n super()\n this.dirpath = dirpath\n this.files = new Files()\n this.parser = options?.parser ?? JSON\n this.noPathlikeIds = options?.noPathlikeIds ?? true\n }\n\n async create(entry: T): Promise<T> {\n await this.writeEntry(entry)\n return entry\n }\n\n async getById(id: T['id']): Promise<T | null> {\n if (!this.isIdValid(id)) throw new InvalidIdError(id)\n\n try {\n const filepath = this.getFilePath(id)\n const text = await this.files.read(filepath)\n const entry = this.parser.parse(text)\n return entry\n } catch (error) {\n console.error('Failed to read entry', error)\n // File doesn't exist or invalid JSON\n return null\n }\n }\n\n async update(id: T['id'], updater: (entry: T) => Promisable<Partial<T>>): Promise<T> {\n const entry = await this.getByIdOrThrow(id)\n\n const updatedEntryFields = await updater(entry)\n const updatedEntry = { ...entry, ...updatedEntryFields }\n await this.writeEntry(updatedEntry)\n\n if (updatedEntry.id !== id) {\n await this.deleteById(id)\n }\n\n return updatedEntry\n }\n\n async deleteById(id: T['id']): Promise<boolean> {\n try {\n const filepath = this.getFilePath(id)\n await this.files.delete(filepath, { force: false })\n return true\n } catch {\n // File might not exist, ignore error\n return false\n }\n }\n\n async deleteByIds(ids: T['id'][]): Promise<DeleteManyOutput> {\n return this.deleteWhere((entry) => ids.includes(entry.id))\n }\n\n async destroy() {\n await this.files.delete(this.dirpath)\n }\n\n protected getFilePath(id: T['id']) {\n return path.join(this.dirpath, `${id}.json`)\n }\n\n protected async writeEntry(entry: T) {\n if (!this.isIdValid(entry.id)) throw new InvalidIdError(entry.id)\n\n const filepath = this.getFilePath(entry.id)\n await this.files.write(filepath, JSON.stringify(entry, null, 2))\n }\n\n isIdValid(id: T['id']): boolean {\n if (typeof id !== 'string') return false\n\n if (!this.noPathlikeIds) return true\n\n if (id.includes('/') || id.includes('\\\\')) return false\n\n return true\n }\n\n async *iterEntries() {\n for await (const id of this.iterIds()) {\n const entry = await this.getById(id)\n if (entry) yield entry\n }\n }\n\n async *iterIds() {\n const filenames = await this.files.list(this.dirpath)\n for (const filename of filenames) {\n if (!filename.endsWith('.json')) continue\n\n const id = filename.replace(/\\.json$/, '')\n if (this.isIdValid(id)) yield id\n }\n }\n}\n","import { SingleEntryDb, JsonEntryParser, Promisable } from '../common'\nimport { Files } from './files'\n\nexport class SingleEntryFileDb<T> extends SingleEntryDb<T> {\n protected readonly files: Files = new Files()\n\n constructor(\n protected readonly filepath: string,\n protected readonly parser: JsonEntryParser<T> = JSON,\n ) {\n super()\n }\n\n path() {\n return this.filepath\n }\n\n async isInited() {\n const exists = await this.files.exists(this.filepath)\n return exists\n }\n\n async read() {\n const text = await this.files.read(this.filepath)\n const entry = this.parser.parse(text)\n return entry\n }\n\n async write(updaterOrEntry: T | ((entry: T) => Promisable<Partial<T>>)): Promise<T> {\n let entry: T\n if (typeof updaterOrEntry === 'function') {\n const updater = updaterOrEntry as (entry: T) => T\n const existing = await this.read()\n\n const updatedFields = await updater(existing)\n entry = { ...existing, ...updatedFields }\n } else {\n entry = updaterOrEntry\n }\n\n await this.files.write(this.filepath, JSON.stringify(entry, null, 2))\n\n return entry\n }\n\n async delete(): Promise<void> {\n await this.files.delete(this.filepath)\n }\n}\n","import { Identifiable, Promisable, MultiEntryDb, JsonEntryParser } from '../common'\nimport { MultiEntryFileDb } from '../file/multiEntryFileDb'\n\nexport class MultiEntryMemDb<T extends Identifiable> extends MultiEntryDb<T> {\n protected entries: Map<T['id'], T> = new Map()\n\n async create(entry: T): Promise<T> {\n this.entries.set(entry.id, entry)\n return entry\n }\n\n async getById(id: T['id']): Promise<T | null> {\n return this.entries.get(id) ?? null\n }\n\n async update(id: T['id'], updater: (entry: T) => Promisable<Partial<T>>): Promise<T> {\n const entry = await this.getByIdOrThrow(id)\n\n const updatedEntryFields = await updater(entry)\n const updatedEntry = { ...entry, ...updatedEntryFields }\n\n this.entries.set(updatedEntry.id, updatedEntry)\n\n if (updatedEntry.id !== id) this.entries.delete(id)\n\n return updatedEntry\n }\n\n async deleteById(id: T['id']): Promise<boolean> {\n return this.entries.delete(id)\n }\n\n async destroy() {\n this.entries.clear()\n }\n\n async *iterEntries() {\n for (const entry of this.entries.values()) {\n yield entry\n }\n }\n\n async *iterIds() {\n for (const id of this.entries.keys()) {\n yield id\n }\n }\n\n async persist(dirpath: string) {\n const fileDb = new MultiEntryFileDb<T>(dirpath)\n await fileDb.destroy()\n\n const values = [...this.entries.values()]\n await Promise.all(values.map((entry) => fileDb.create(entry)))\n }\n\n async load(dirpath: string, parser?: JsonEntryParser<T>) {\n const fileDb = new MultiEntryFileDb<T>(dirpath, { parser })\n\n for await (const entry of fileDb.iterEntries()) {\n await this.create(entry)\n }\n }\n}\n","import { JsonEntryParser, SingleEntryDb, UninitError, UpdaterFn } from '../common'\nimport { SingleEntryFileDb } from '../file/singleEntryFileDb'\n\nexport class SingleEntryMemDb<T> extends SingleEntryDb<T> {\n protected entry: T | null = null\n\n constructor(initialEntry: T | null = null) {\n super()\n this.entry = initialEntry\n }\n\n async isInited() {\n return this.entry !== null\n }\n\n async read() {\n if (this.entry === null) throw new UninitError()\n return this.entry\n }\n\n async write(updaterOrEntry: T | UpdaterFn<T>) {\n let entry: T\n\n if (typeof updaterOrEntry === 'function') {\n const updater = updaterOrEntry as (entry: T) => Partial<T>\n\n if (this.entry === null) throw new UninitError()\n\n const updatedFields = updater(this.entry)\n entry = { ...this.entry, ...updatedFields }\n } else {\n entry = updaterOrEntry\n }\n\n this.entry = entry\n return entry\n }\n\n async delete() {\n this.entry = null\n }\n\n async persist(filepath: string) {\n const fileDb = new SingleEntryFileDb<T>(filepath)\n await fileDb.write(await this.read())\n }\n\n async load(filepath: string, parser?: JsonEntryParser<T>) {\n const fileDb = new SingleEntryFileDb<T>(filepath, parser)\n const persistedEntry = await fileDb.read()\n this.write(persistedEntry)\n }\n}\n"],"names":["FileType","fs","path","fsSync","readline"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAM,MAAO,OAAQ,SAAQ,KAAK,CAAA;AAAG;AAE/B,MAAO,aAAc,SAAQ,OAAO,CAAA;AAAG;AAEvC,MAAO,aAAc,SAAQ,OAAO,CAAA;AAAG;AAEvC,MAAO,WAAY,SAAQ,OAAO,CAAA;AAAG;AAErC,MAAO,cAAe,SAAQ,OAAO,CAAA;AACzC,IAAA,WAAA,CAAY,EAAW,EAAA;AACrB,QAAA,KAAK,CAAC,CAAA,kBAAA,EAAqB,EAAE,CAAA,CAAA,CAAG,CAAC;IACnC;AACD;AAEK,MAAO,WAAY,SAAQ,OAAO,CAAA;AACtC,IAAA,WAAA,GAAA;QACE,KAAK,CAAC,kFAAkF,CAAC;IAC3F;AACD;;MCTqB,YAAY,CAAA;IAehC,MAAM,cAAc,CAAC,EAAW,EAAA;QAC9B,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;AACpC,QAAA,IAAI,CAAC,KAAK;AAAE,YAAA,MAAM,IAAI,aAAa,CAAC,kBAAkB,EAAE,CAAA,gBAAA,CAAkB,CAAC;AAC3E,QAAA,OAAO,KAAK;IACd;IAEA,MAAM,aAAa,CAAC,SAAyB,EAAA;AAC3C,QAAA,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,SAAS,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;QACpE,OAAO,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI;IAC9B;IAEA,MAAM,oBAAoB,CAAC,SAAyB,EAAA;QAClD,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,SAAS,CAAC;AACjD,QAAA,IAAI,CAAC,KAAK;AAAE,YAAA,MAAM,IAAI,aAAa,CAAC,4BAA4B,CAAC;AACjE,QAAA,OAAO,KAAK;IACd;AAEA,IAAA,MAAM,QAAQ,CAAC,SAAyB,EAAE,UAA4B,EAAA;QACpE,IAAI,YAAY,GAAG,CAAC;QACpB,MAAM,OAAO,GAAQ,EAAE;QAEvB,IAAI,CAAC,UAAU,EAAE;YACf,WAAW,MAAM,KAAK,IAAI,IAAI,CAAC,WAAW,EAAE,EAAE;AAC5C,gBAAA,MAAM,OAAO,GAAG,SAAS,CAAC,KAAK,CAAC;AAChC,gBAAA,IAAI,OAAO;AAAE,oBAAA,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC;YAClC;AACA,YAAA,OAAO,OAAO;QAChB;AAEA,QAAA,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,UAAU;AACjC,QAAA,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,IAAI,CAAC;QACjC,MAAM,UAAU,GAAG,CAAC,IAAI,GAAG,CAAC,IAAI,IAAI,GAAG,IAAI;AAC3C,QAAA,MAAM,QAAQ,GAAG,UAAU,GAAG,IAAI;QAElC,WAAW,MAAM,KAAK,IAAI,IAAI,CAAC,WAAW,EAAE,EAAE;AAC5C,YAAA,MAAM,OAAO,GAAG,SAAS,CAAC,KAAK,CAAC;YAChC,IAAI,OAAO,EAAE;gBACX,IAAI,YAAY,IAAI,UAAU,IAAI,YAAY,GAAG,QAAQ,EAAE;AACzD,oBAAA,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC;gBACrB;AACA,gBAAA,YAAY,EAAE;gBAEd,IAAI,YAAY,IAAI,QAAQ;oBAAE;YAChC;QACF;AAEA,QAAA,OAAO,OAAO;IAChB;IAEA,MAAM,GAAA;QACJ,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,IAAI,CAAC;IAClC;AAEA,IAAA,MAAM,SAAS,GAAA;QACb,MAAM,GAAG,GAAc,EAAE;QACzB,WAAW,MAAM,EAAE,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE;AACrC,YAAA,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;QACd;AACA,QAAA,OAAO,GAAG;IACZ;AAEA,IAAA,WAAW,CAAC,GAAc,EAAA;AACxB,QAAA,OAAO,IAAI,CAAC,WAAW,CAAC,CAAC,KAAK,KAAK,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAC5D;IAEA,MAAM,WAAW,CAAC,SAAyB,EAAA;QACzC,MAAM,UAAU,GAAc,EAAE;QAChC,MAAM,UAAU,GAAc,EAAE;QAEhC,WAAW,MAAM,KAAK,IAAI,IAAI,CAAC,WAAW,EAAE,EAAE;AAC5C,YAAA,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC;gBAAE;YAEvB,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;YACjD,IAAI,SAAS,EAAE;AACb,gBAAA,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;YAC3B;iBAAO;AACL,gBAAA,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;YAC3B;QACF;AAEA,QAAA,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE;IACnC;IAEA,MAAM,MAAM,CAAC,EAAW,EAAA;QACtB,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QACpC,OAAO,KAAK,KAAK,IAAI;IACvB;IAEA,QAAQ,GAAA;QACN,OAAO,IAAI,CAAC,UAAU,CAAC,MAAM,IAAI,CAAC;IACpC;AAEA,IAAA,MAAM,UAAU,CAAC,SAAyB,EAAE,UAA4B,EAAA;QACtE,IAAI,YAAY,GAAG,CAAC;QACpB,IAAI,KAAK,GAAG,CAAC;QAEb,IAAI,CAAC,UAAU,EAAE;YACf,WAAW,MAAM,KAAK,IAAI,IAAI,CAAC,WAAW,EAAE,EAAE;AAC5C,gBAAA,MAAM,OAAO,GAAG,SAAS,CAAC,KAAK,CAAC;AAChC,gBAAA,IAAI,OAAO;AAAE,oBAAA,KAAK,EAAE;YACtB;AACA,YAAA,OAAO,KAAK;QACd;AAEA,QAAA,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,UAAU;AACjC,QAAA,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,IAAI,CAAC;QACjC,MAAM,UAAU,GAAG,CAAC,IAAI,GAAG,CAAC,IAAI,IAAI,GAAG,IAAI;AAC3C,QAAA,MAAM,QAAQ,GAAG,UAAU,GAAG,IAAI;QAElC,WAAW,MAAM,KAAK,IAAI,IAAI,CAAC,WAAW,EAAE,EAAE;AAC5C,YAAA,MAAM,OAAO,GAAG,SAAS,CAAC,KAAK,CAAC;YAChC,IAAI,OAAO,EAAE;AACX,gBAAA,IAAI,YAAY,IAAI,UAAU,IAAI,YAAY,GAAG,QAAQ;AAAE,oBAAA,KAAK,EAAE;AAClE,gBAAA,YAAY,EAAE;gBAEd,IAAI,YAAY,IAAI,QAAQ;oBAAE;YAChC;QACF;AAEA,QAAA,OAAO,KAAK;IACd;AACD;;MC/IqB,aAAa,CAAA;AAKlC;;ACyCWA;AAAZ,CAAA,UAAY,QAAQ,EAAA;AAClB,IAAA,QAAA,CAAA,MAAA,CAAA,GAAA,MAAa;AACb,IAAA,QAAA,CAAA,WAAA,CAAA,GAAA,WAAuB;;AAEzB,CAAC,EAJWA,gBAAQ,KAARA,gBAAQ,GAAA,EAAA,CAAA,CAAA;;ACjBpB,MAAM,gBAAgB,GAAmB,OAAO;MAEnC,KAAK,CAAA;AAChB,IAAA,MAAM,IAAI,CAAC,OAAe,EAAE,OAAe,EAAA;QACzC,MAAMC,aAAE,CAAC,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC;IACnC;AAEA,IAAA,MAAM,IAAI,CAAC,UAAkB,EAAE,eAAuB,EAAE,OAAqB,EAAA;AAC3E,QAAA,MAAM,EAAE,SAAS,GAAG,KAAK,EAAE,SAAS,GAAG,IAAI,EAAE,GAAG,OAAO,IAAI,EAAE;;AAG7D,QAAA,IAAI,CAAC,SAAS,KAAK,MAAM,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,EAAE;AACtD,YAAA,MAAM,IAAI,WAAW,CAAC,gBAAgB,eAAe,CAAA,gBAAA,CAAkB,CAAC;QAC1E;QAEA,MAAM,WAAW,GAAG,MAAMA,aAAE,CAAC,IAAI,CAAC,UAAU,CAAC;AAE7C,QAAA,IAAI,WAAW,CAAC,MAAM,EAAE,EAAE;YACxB,MAAM,cAAc,GAAGC,eAAI,CAAC,OAAO,CAAC,eAAe,CAAC;AACpD,YAAA,MAAM,IAAI,CAAC,WAAW,CAAC,cAAc,CAAC;YACtC,MAAMD,aAAE,CAAC,QAAQ,CAAC,UAAU,EAAE,eAAe,CAAC;YAC9C;QACF;AAEA,QAAA,IAAI,WAAW,CAAC,WAAW,EAAE,EAAE;YAC7B,IAAI,CAAC,SAAS,EAAE;AACd,gBAAA,MAAM,IAAI,WAAW,CAAC,IAAI,UAAU,CAAA,uCAAA,CAAyC,CAAC;YAChF;YACA,MAAM,IAAI,CAAC,aAAa,CAAC,UAAU,EAAE,eAAe,CAAC;QACvD;IACF;AAEA,IAAA,MAAM,aAAa,CAAC,UAAkB,EAAE,eAAuB,EAAA;QAC7D,MAAM,WAAW,GAAG,MAAMA,aAAE,CAAC,IAAI,CAAC,UAAU,CAAC;AAE7C,QAAA,IAAI,WAAW,CAAC,MAAM,EAAE,EAAE;YACxB,MAAM,cAAc,GAAGC,eAAI,CAAC,OAAO,CAAC,eAAe,CAAC;AACpD,YAAA,MAAM,IAAI,CAAC,WAAW,CAAC,cAAc,CAAC;YACtC,MAAMD,aAAE,CAAC,QAAQ,CAAC,UAAU,EAAE,eAAe,CAAC;YAC9C;QACF;AAEA,QAAA,IAAI,WAAW,CAAC,WAAW,EAAE,EAAE;AAC7B,YAAA,MAAM,IAAI,CAAC,WAAW,CAAC,eAAe,CAAC;YACvC,MAAM,OAAO,GAAG,MAAMA,aAAE,CAAC,OAAO,CAAC,UAAU,CAAC;AAE5C,YAAA,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE;gBAC3B,MAAM,eAAe,GAAGC,eAAI,CAAC,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC;gBACpD,MAAM,aAAa,GAAGA,eAAI,CAAC,IAAI,CAAC,eAAe,EAAE,KAAK,CAAC;gBACvD,MAAM,IAAI,CAAC,aAAa,CAAC,eAAe,EAAE,aAAa,CAAC;YAC1D;QACF;IACF;IAEA,MAAM,KAAK,CAAC,QAAgB,EAAA;AAC1B,QAAA,MAAM,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC;IAClC;IAEU,MAAM,WAAW,CAAC,QAAgB,EAAA;AAC1C,QAAA,MAAMD,aAAE,CAAC,KAAK,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;IAC/C;AAEA,IAAA,MAAM,KAAK,CAAC,QAAgB,EAAE,OAAe,EAAE,OAAsB,EAAA;QACnE,MAAM,EAAE,QAAQ,GAAG,gBAAgB,EAAE,GAAG,OAAO,IAAI,EAAE;QAErD,MAAM,UAAU,GAAGC,eAAI,CAAC,OAAO,CAAC,QAAQ,CAAC;AACzC,QAAA,MAAM,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC;QAElC,MAAMD,aAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,OAAO,EAAE,QAAQ,CAAC;IACjD;IAEA,MAAM,KAAK,CAAC,QAAgB,EAAA;QAC1B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC;AAC1C,QAAA,IAAI,CAAC,MAAM;YAAE,MAAM,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,EAAE,CAAC;IAC7C;AAEA,IAAA,MAAM,IAAI,CAAC,QAAgB,EAAE,OAAqB,EAAA;QAChD,MAAM,EAAE,QAAQ,GAAG,gBAAgB,EAAE,KAAK,EAAE,GAAG,OAAO,IAAI,EAAE;AAE5D,QAAA,IAAI,KAAK,KAAK,SAAS,EAAE;YACvB,OAAO,MAAMA,aAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;QAC9C;AAEA,QAAA,MAAM,MAAM,GAAGE,iBAAM,CAAC,gBAAgB,CAAC,QAAQ,EAAE,EAAE,QAAQ,EAAE,CAAC;AAC9D,QAAA,MAAM,MAAM,GAAGC,mBAAQ,CAAC,eAAe,CAAC;AACtC,YAAA,KAAK,EAAE,MAAM;AACb,YAAA,SAAS,EAAE,QAAQ;AACpB,SAAA,CAAC;QAEF,IAAI,MAAM,GAAG,EAAE;QACf,IAAI,SAAS,GAAG,CAAC;AACjB,QAAA,WAAW,MAAM,IAAI,IAAI,MAAM,EAAE;YAC/B,IAAI,SAAS,IAAI,KAAK;gBAAE;AACxB,YAAA,MAAM,IAAI,IAAI,GAAG,IAAI;AACrB,YAAA,SAAS,EAAE;QACb;AAEA,QAAA,OAAO,MAAM;IACf;AAEA,IAAA,MAAM,MAAM,CAAC,QAAgB,EAAE,OAAuB,EAAA;AACpD,QAAA,MAAM,EAAE,KAAK,GAAG,IAAI,EAAE,SAAS,GAAG,IAAI,EAAE,GAAG,OAAO,IAAI,EAAE;AACxD,QAAA,MAAMH,aAAE,CAAC,EAAE,CAAC,QAAQ,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC;IAC7C;IAEA,MAAM,MAAM,CAAC,QAAgB,EAAA;AAC3B,QAAA,IAAI;AACF,YAAA,MAAMA,aAAE,CAAC,MAAM,CAAC,QAAQ,CAAC;AACzB,YAAA,OAAO,IAAI;QACb;AAAE,QAAA,MAAM;AACN,YAAA,OAAO,KAAK;QACd;IACF;IAEA,MAAM,KAAK,CAAC,QAAgB,EAAA;AAC1B,QAAA,IAAI;YACF,MAAM,KAAK,GAAG,MAAMA,aAAE,CAAC,IAAI,CAAC,QAAQ,CAAC;AACrC,YAAA,OAAO,KAAK,CAAC,WAAW,EAAE;QAC5B;AAAE,QAAA,MAAM;AACN,YAAA,OAAO,KAAK;QACd;IACF;IAEA,MAAM,MAAM,CAAC,QAAgB,EAAA;AAC3B,QAAA,IAAI;YACF,MAAM,KAAK,GAAG,MAAMA,aAAE,CAAC,IAAI,CAAC,QAAQ,CAAC;AACrC,YAAA,OAAO,KAAK,CAAC,MAAM,EAAE;QACvB;AAAE,QAAA,MAAM;AACN,YAAA,OAAO,KAAK;QACd;IACF;IAEA,MAAM,SAAS,CAAC,QAAgB,EAAA;AAC9B,QAAA,IAAI;YACF,MAAM,KAAK,GAAG,MAAMA,aAAE,CAAC,IAAI,CAAC,QAAQ,CAAC;AACrC,YAAA,OAAO,KAAK,CAAC,cAAc,EAAE;QAC/B;AAAE,QAAA,MAAM;AACN,YAAA,OAAO,KAAK;QACd;IACF;AAEA,IAAA,MAAM,OAAO,CAAC,QAAgB,EAAE,OAAqB,EAAA;QACnD,MAAM,EAAE,KAAK,GAAG,CAAC,EAAE,aAAa,EAAE,GAAG,OAAO,IAAI,EAAE;QAClD,MAAM,KAAK,GAAG,MAAMA,aAAE,CAAC,IAAI,CAAC,QAAQ,CAAC;AACrC,QAAA,MAAM,KAAK,GAAG,KAAK,CAAC,WAAW,EAAE;AACjC,QAAA,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,EAAE;QAE7B,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,KAAK;AAC3C,QAAA,MAAM,UAAU,GAAG;YACjB,IAAI,EAAE,IAAI,CAAC,aAAa,CAAC,QAAQ,EAAE,aAAa,CAAC;YACjD,IAAI;AACJ,YAAA,OAAO,EAAE,KAAK;AACd,YAAA,QAAQ,EAAE,KAAK;AACf,YAAA,QAAQ,EAAE,KAAK;SAChB;QAED,IAAI,KAAK,EAAE;YACT,MAAM,QAAQ,GAAe,EAAE;AAE/B,YAAA,IAAI,KAAK,GAAG,CAAC,EAAE;gBACb,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC;AAE5C,gBAAA,KAAK,MAAM,KAAK,IAAI,UAAU,EAAE;AAC9B,oBAAA,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC;AACzC,oBAAA,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,OAAO,CAACC,eAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,KAAK,CAAC,EAAE;AAC/D,wBAAA,KAAK,EAAE,UAAU;wBACjB,aAAa;AACd,qBAAA,CAAC;AACF,oBAAA,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC;gBAC1B;YACF;YAEA,OAAO;AACL,gBAAA,GAAG,UAAU;gBACb,IAAI,EAAEF,gBAAQ,CAAC,SAAS;gBACxB,QAAQ;aACT;QACH;AACA,QAAA,IAAI,MAAM;YACR,OAAO;AACL,gBAAA,GAAG,UAAU;gBACb,IAAI,EAAEA,gBAAQ,CAAC,IAAI;aACpB;AAEH,QAAA,MAAM,IAAI,WAAW,CAAC,WAAW,QAAQ,CAAA,gCAAA,CAAkC,CAAC;IAC9E;AAEA,IAAA,MAAM,IAAI,CAAC,OAAe,EAAE,OAAqB,EAAA;QAC/C,MAAM,EAAE,KAAK,GAAG,CAAC,EAAE,aAAa,EAAE,GAAG,OAAO,IAAI,EAAE;AAClD,QAAA,IAAI,KAAK,GAAG,CAAC,EAAE;AACb,YAAA,OAAO,MAAM,IAAI,CAAC,aAAa,CAAC,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,aAAa,CAAC;QACnE;AACA,QAAA,OAAO,MAAMC,aAAE,CAAC,OAAO,CAAC,OAAO,CAAC;IAClC;AAEA,IAAA,OAAO,QAAQ,CAAC,OAAe,EAAE,OAAqB,EAAA;QACpD,MAAM,EAAE,KAAK,GAAG,CAAC,EAAE,GAAG,OAAO,IAAI,EAAE;AAEnC,QAAA,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,CAAC;AAEjD,QAAA,KAAK,MAAM,QAAQ,IAAI,KAAK,EAAE;YAC5B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC;AAC1C,YAAA,IAAI,CAAC,MAAM;gBAAE;AAEb,YAAA,IAAI;gBACF,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC;gBACzC,MAAM;oBACJ,QAAQ;oBACR,OAAO;iBACR;YACH;AAAE,YAAA,MAAM;;gBAEN;YACF;QACF;IACF;IAEU,MAAM,aAAa,CAC3B,OAAe,EACf,QAAgB,EAChB,YAAoB,EACpB,aAAiC,EAAA;QAEjC,MAAM,OAAO,GAAa,EAAE;AAC5B,QAAA,MAAM,OAAO,GAAG,MAAMA,aAAE,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC;AAElE,QAAA,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE;AAC3B,YAAA,MAAM,QAAQ,GAAGC,eAAI,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC;YAC/C,MAAM,YAAY,GAAG,IAAI,CAAC,aAAa,CAAC,QAAQ,EAAE,aAAa,CAAC;AAChE,YAAA,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC;YAE1B,IAAI,KAAK,CAAC,WAAW,EAAE,IAAI,YAAY,GAAG,QAAQ,EAAE;AAClD,gBAAA,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,aAAa,CACzC,QAAQ,EACR,QAAQ,EACR,YAAY,GAAG,CAAC,EAChB,aAAa,CACd;AACD,gBAAA,OAAO,CAAC,IAAI,CAAC,GAAG,UAAU,CAAC;YAC7B;QACF;AAEA,QAAA,OAAO,OAAO;IAChB;IAEU,aAAa,CAAC,QAAgB,EAAE,WAA+B,EAAA;AACvE,QAAA,IAAI,CAAC,WAAW;AAAE,YAAA,OAAO,QAAQ;AACjC,QAAA,MAAM,IAAI,GAAG,WAAW,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC;QAClE,MAAM,QAAQ,GAAG,QAAQ,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC;QAC3C,OAAO,CAAA,CAAA,EAAI,QAAQ,CAAA,CAAE;IACvB;AACD;;AC9QK,MAAO,gBAAyC,SAAQ,YAAe,CAAA;AACxD,IAAA,OAAO;AACP,IAAA,KAAK;AACL,IAAA,MAAM;AAChB,IAAA,aAAa;IAEtB,WAAA,CAAY,OAAe,EAAE,OAAoC,EAAA;AAC/D,QAAA,KAAK,EAAE;AACP,QAAA,IAAI,CAAC,OAAO,GAAG,OAAO;AACtB,QAAA,IAAI,CAAC,KAAK,GAAG,IAAI,KAAK,EAAE;QACxB,IAAI,CAAC,MAAM,GAAG,OAAO,EAAE,MAAM,IAAI,IAAI;QACrC,IAAI,CAAC,aAAa,GAAG,OAAO,EAAE,aAAa,IAAI,IAAI;IACrD;IAEA,MAAM,MAAM,CAAC,KAAQ,EAAA;AACnB,QAAA,MAAM,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC;AAC5B,QAAA,OAAO,KAAK;IACd;IAEA,MAAM,OAAO,CAAC,EAAW,EAAA;AACvB,QAAA,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;AAAE,YAAA,MAAM,IAAI,cAAc,CAAC,EAAE,CAAC;AAErD,QAAA,IAAI;YACF,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC;YACrC,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC;YAC5C,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC;AACrC,YAAA,OAAO,KAAK;QACd;QAAE,OAAO,KAAK,EAAE;AACd,YAAA,OAAO,CAAC,KAAK,CAAC,sBAAsB,EAAE,KAAK,CAAC;;AAE5C,YAAA,OAAO,IAAI;QACb;IACF;AAEA,IAAA,MAAM,MAAM,CAAC,EAAW,EAAE,OAA6C,EAAA;QACrE,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,EAAE,CAAC;AAE3C,QAAA,MAAM,kBAAkB,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC;QAC/C,MAAM,YAAY,GAAG,EAAE,GAAG,KAAK,EAAE,GAAG,kBAAkB,EAAE;AACxD,QAAA,MAAM,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC;AAEnC,QAAA,IAAI,YAAY,CAAC,EAAE,KAAK,EAAE,EAAE;AAC1B,YAAA,MAAM,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;QAC3B;AAEA,QAAA,OAAO,YAAY;IACrB;IAEA,MAAM,UAAU,CAAC,EAAW,EAAA;AAC1B,QAAA,IAAI;YACF,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC;AACrC,YAAA,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;AACnD,YAAA,OAAO,IAAI;QACb;AAAE,QAAA,MAAM;;AAEN,YAAA,OAAO,KAAK;QACd;IACF;IAEA,MAAM,WAAW,CAAC,GAAc,EAAA;AAC9B,QAAA,OAAO,IAAI,CAAC,WAAW,CAAC,CAAC,KAAK,KAAK,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAC5D;AAEA,IAAA,MAAM,OAAO,GAAA;QACX,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC;IACvC;AAEU,IAAA,WAAW,CAAC,EAAW,EAAA;AAC/B,QAAA,OAAOA,eAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAA,EAAG,EAAE,CAAA,KAAA,CAAO,CAAC;IAC9C;IAEU,MAAM,UAAU,CAAC,KAAQ,EAAA;QACjC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;AAAE,YAAA,MAAM,IAAI,cAAc,CAAC,KAAK,CAAC,EAAE,CAAC;QAEjE,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE,CAAC;AAC3C,QAAA,MAAM,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IAClE;AAEA,IAAA,SAAS,CAAC,EAAW,EAAA;QACnB,IAAI,OAAO,EAAE,KAAK,QAAQ;AAAE,YAAA,OAAO,KAAK;QAExC,IAAI,CAAC,IAAI,CAAC,aAAa;AAAE,YAAA,OAAO,IAAI;AAEpC,QAAA,IAAI,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC;AAAE,YAAA,OAAO,KAAK;AAEvD,QAAA,OAAO,IAAI;IACb;IAEA,OAAO,WAAW,GAAA;QAChB,WAAW,MAAM,EAAE,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE;YACrC,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;AACpC,YAAA,IAAI,KAAK;AAAE,gBAAA,MAAM,KAAK;QACxB;IACF;IAEA,OAAO,OAAO,GAAA;AACZ,QAAA,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC;AACrD,QAAA,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE;AAChC,YAAA,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC;gBAAE;YAEjC,MAAM,EAAE,GAAG,QAAQ,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC;AAC1C,YAAA,IAAI,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;AAAE,gBAAA,MAAM,EAAE;QAClC;IACF;AACD;;ACjHK,MAAO,iBAAqB,SAAQ,aAAgB,CAAA;AAInC,IAAA,QAAA;AACA,IAAA,MAAA;AAJF,IAAA,KAAK,GAAU,IAAI,KAAK,EAAE;IAE7C,WAAA,CACqB,QAAgB,EAChB,MAAA,GAA6B,IAAI,EAAA;AAEpD,QAAA,KAAK,EAAE;QAHY,IAAA,CAAA,QAAQ,GAAR,QAAQ;QACR,IAAA,CAAA,MAAM,GAAN,MAAM;IAG3B;IAEA,IAAI,GAAA;QACF,OAAO,IAAI,CAAC,QAAQ;IACtB;AAEA,IAAA,MAAM,QAAQ,GAAA;AACZ,QAAA,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC;AACrD,QAAA,OAAO,MAAM;IACf;AAEA,IAAA,MAAM,IAAI,GAAA;AACR,QAAA,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC;QACjD,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC;AACrC,QAAA,OAAO,KAAK;IACd;IAEA,MAAM,KAAK,CAAC,cAA0D,EAAA;AACpE,QAAA,IAAI,KAAQ;AACZ,QAAA,IAAI,OAAO,cAAc,KAAK,UAAU,EAAE;YACxC,MAAM,OAAO,GAAG,cAAiC;AACjD,YAAA,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE;AAElC,YAAA,MAAM,aAAa,GAAG,MAAM,OAAO,CAAC,QAAQ,CAAC;YAC7C,KAAK,GAAG,EAAE,GAAG,QAAQ,EAAE,GAAG,aAAa,EAAE;QAC3C;aAAO;YACL,KAAK,GAAG,cAAc;QACxB;QAEA,MAAM,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;AAErE,QAAA,OAAO,KAAK;IACd;AAEA,IAAA,MAAM,MAAM,GAAA;QACV,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC;IACxC;AACD;;AC7CK,MAAO,eAAwC,SAAQ,YAAe,CAAA;AAChE,IAAA,OAAO,GAAoB,IAAI,GAAG,EAAE;IAE9C,MAAM,MAAM,CAAC,KAAQ,EAAA;QACnB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC;AACjC,QAAA,OAAO,KAAK;IACd;IAEA,MAAM,OAAO,CAAC,EAAW,EAAA;QACvB,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,IAAI;IACrC;AAEA,IAAA,MAAM,MAAM,CAAC,EAAW,EAAE,OAA6C,EAAA;QACrE,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,EAAE,CAAC;AAE3C,QAAA,MAAM,kBAAkB,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC;QAC/C,MAAM,YAAY,GAAG,EAAE,GAAG,KAAK,EAAE,GAAG,kBAAkB,EAAE;QAExD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,EAAE,YAAY,CAAC;AAE/C,QAAA,IAAI,YAAY,CAAC,EAAE,KAAK,EAAE;AAAE,YAAA,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;AAEnD,QAAA,OAAO,YAAY;IACrB;IAEA,MAAM,UAAU,CAAC,EAAW,EAAA;QAC1B,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;IAChC;AAEA,IAAA,MAAM,OAAO,GAAA;AACX,QAAA,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE;IACtB;IAEA,OAAO,WAAW,GAAA;QAChB,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE;AACzC,YAAA,MAAM,KAAK;QACb;IACF;IAEA,OAAO,OAAO,GAAA;QACZ,KAAK,MAAM,EAAE,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE;AACpC,YAAA,MAAM,EAAE;QACV;IACF;IAEA,MAAM,OAAO,CAAC,OAAe,EAAA;AAC3B,QAAA,MAAM,MAAM,GAAG,IAAI,gBAAgB,CAAI,OAAO,CAAC;AAC/C,QAAA,MAAM,MAAM,CAAC,OAAO,EAAE;QAEtB,MAAM,MAAM,GAAG,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;QACzC,MAAM,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,KAAK,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;IAChE;AAEA,IAAA,MAAM,IAAI,CAAC,OAAe,EAAE,MAA2B,EAAA;QACrD,MAAM,MAAM,GAAG,IAAI,gBAAgB,CAAI,OAAO,EAAE,EAAE,MAAM,EAAE,CAAC;QAE3D,WAAW,MAAM,KAAK,IAAI,MAAM,CAAC,WAAW,EAAE,EAAE;AAC9C,YAAA,MAAM,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC;QAC1B;IACF;AACD;;AC5DK,MAAO,gBAAoB,SAAQ,aAAgB,CAAA;IAC7C,KAAK,GAAa,IAAI;AAEhC,IAAA,WAAA,CAAY,eAAyB,IAAI,EAAA;AACvC,QAAA,KAAK,EAAE;AACP,QAAA,IAAI,CAAC,KAAK,GAAG,YAAY;IAC3B;AAEA,IAAA,MAAM,QAAQ,GAAA;AACZ,QAAA,OAAO,IAAI,CAAC,KAAK,KAAK,IAAI;IAC5B;AAEA,IAAA,MAAM,IAAI,GAAA;AACR,QAAA,IAAI,IAAI,CAAC,KAAK,KAAK,IAAI;YAAE,MAAM,IAAI,WAAW,EAAE;QAChD,OAAO,IAAI,CAAC,KAAK;IACnB;IAEA,MAAM,KAAK,CAAC,cAAgC,EAAA;AAC1C,QAAA,IAAI,KAAQ;AAEZ,QAAA,IAAI,OAAO,cAAc,KAAK,UAAU,EAAE;YACxC,MAAM,OAAO,GAAG,cAA0C;AAE1D,YAAA,IAAI,IAAI,CAAC,KAAK,KAAK,IAAI;gBAAE,MAAM,IAAI,WAAW,EAAE;YAEhD,MAAM,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC;YACzC,KAAK,GAAG,EAAE,GAAG,IAAI,CAAC,KAAK,EAAE,GAAG,aAAa,EAAE;QAC7C;aAAO;YACL,KAAK,GAAG,cAAc;QACxB;AAEA,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;AAClB,QAAA,OAAO,KAAK;IACd;AAEA,IAAA,MAAM,MAAM,GAAA;AACV,QAAA,IAAI,CAAC,KAAK,GAAG,IAAI;IACnB;IAEA,MAAM,OAAO,CAAC,QAAgB,EAAA;AAC5B,QAAA,MAAM,MAAM,GAAG,IAAI,iBAAiB,CAAI,QAAQ,CAAC;QACjD,MAAM,MAAM,CAAC,KAAK,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;IACvC;AAEA,IAAA,MAAM,IAAI,CAAC,QAAgB,EAAE,MAA2B,EAAA;QACtD,MAAM,MAAM,GAAG,IAAI,iBAAiB,CAAI,QAAQ,EAAE,MAAM,CAAC;AACzD,QAAA,MAAM,cAAc,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE;AAC1C,QAAA,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC;IAC5B;AACD;;;;;;;;;;;;;"}
|