@push.rocks/smartarchive 4.2.4 → 5.0.1

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.
Files changed (39) hide show
  1. package/dist_ts/00_commitinfo_data.js +1 -1
  2. package/dist_ts/bzip2/bititerator.d.ts +6 -1
  3. package/dist_ts/bzip2/bititerator.js +30 -24
  4. package/dist_ts/bzip2/bzip2.d.ts +27 -12
  5. package/dist_ts/bzip2/bzip2.js +325 -263
  6. package/dist_ts/bzip2/index.d.ts +4 -1
  7. package/dist_ts/bzip2/index.js +36 -38
  8. package/dist_ts/classes.archiveanalyzer.d.ts +25 -5
  9. package/dist_ts/classes.archiveanalyzer.js +19 -8
  10. package/dist_ts/classes.bzip2tools.d.ts +1 -1
  11. package/dist_ts/classes.gziptools.d.ts +43 -6
  12. package/dist_ts/classes.gziptools.js +76 -24
  13. package/dist_ts/classes.smartarchive.d.ts +198 -16
  14. package/dist_ts/classes.smartarchive.js +652 -79
  15. package/dist_ts/classes.tartools.d.ts +31 -4
  16. package/dist_ts/classes.tartools.js +93 -32
  17. package/dist_ts/classes.ziptools.d.ts +47 -12
  18. package/dist_ts/classes.ziptools.js +128 -23
  19. package/dist_ts/errors.d.ts +44 -0
  20. package/dist_ts/errors.js +62 -0
  21. package/dist_ts/index.d.ts +4 -0
  22. package/dist_ts/index.js +9 -1
  23. package/dist_ts/interfaces.d.ts +119 -0
  24. package/dist_ts/interfaces.js +2 -0
  25. package/package.json +1 -1
  26. package/readme.hints.md +69 -23
  27. package/readme.md +360 -274
  28. package/ts/00_commitinfo_data.ts +1 -1
  29. package/ts/bzip2/bititerator.ts +43 -27
  30. package/ts/bzip2/bzip2.ts +289 -171
  31. package/ts/bzip2/index.ts +52 -50
  32. package/ts/classes.archiveanalyzer.ts +42 -28
  33. package/ts/classes.gziptools.ts +91 -33
  34. package/ts/classes.smartarchive.ts +765 -140
  35. package/ts/classes.tartools.ts +124 -52
  36. package/ts/classes.ziptools.ts +147 -34
  37. package/ts/errors.ts +70 -0
  38. package/ts/index.ts +11 -0
  39. package/ts/interfaces.ts +136 -0
@@ -1,87 +1,280 @@
1
1
  import * as plugins from './plugins.js';
2
- import * as paths from './paths.js';
3
2
  import { Bzip2Tools } from './classes.bzip2tools.js';
4
3
  import { GzipTools } from './classes.gziptools.js';
5
4
  import { TarTools } from './classes.tartools.js';
6
5
  import { ZipTools } from './classes.ziptools.js';
7
- import { ArchiveAnalyzer, } from './classes.archiveanalyzer.js';
6
+ import { ArchiveAnalyzer } from './classes.archiveanalyzer.js';
7
+ /**
8
+ * Main class for archive manipulation with fluent API
9
+ * Supports TAR, ZIP, GZIP, and BZIP2 formats
10
+ *
11
+ * @example Extraction from URL
12
+ * ```typescript
13
+ * await SmartArchive.create()
14
+ * .url('https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz')
15
+ * .stripComponents(1)
16
+ * .extract('./node_modules/lodash');
17
+ * ```
18
+ *
19
+ * @example Creation with thenable
20
+ * ```typescript
21
+ * const archive = await SmartArchive.create()
22
+ * .format('tar.gz')
23
+ * .compression(9)
24
+ * .entry('config.json', JSON.stringify(config))
25
+ * .directory('./src');
26
+ * ```
27
+ */
8
28
  export class SmartArchive {
9
- // STATIC
10
- static async fromArchiveUrl(urlArg) {
11
- const smartArchiveInstance = new SmartArchive();
12
- smartArchiveInstance.sourceUrl = urlArg;
13
- return smartArchiveInstance;
14
- }
15
- static async fromArchiveFile(filePathArg) {
16
- const smartArchiveInstance = new SmartArchive();
17
- smartArchiveInstance.sourceFilePath = filePathArg;
18
- return smartArchiveInstance;
19
- }
20
- static async fromArchiveStream(streamArg) {
21
- const smartArchiveInstance = new SmartArchive();
22
- smartArchiveInstance.sourceStream = streamArg;
23
- return smartArchiveInstance;
29
+ // ============================================
30
+ // STATIC ENTRY POINT
31
+ // ============================================
32
+ /**
33
+ * Create a new SmartArchive instance for fluent configuration
34
+ */
35
+ static create() {
36
+ return new SmartArchive();
24
37
  }
25
38
  constructor() {
26
- // INSTANCE
39
+ // ============================================
40
+ // TOOLS (public for internal use)
41
+ // ============================================
27
42
  this.tarTools = new TarTools();
28
43
  this.zipTools = new ZipTools();
29
44
  this.gzipTools = new GzipTools();
30
45
  this.bzip2Tools = new Bzip2Tools(this);
31
46
  this.archiveAnalyzer = new ArchiveAnalyzer(this);
32
- this.singleFileMode = false;
33
- this.addedDirectories = [];
34
- this.addedFiles = [];
35
- this.addedUrls = [];
47
+ this._compressionLevel = 6;
48
+ this.pendingEntries = [];
49
+ this.pendingDirectories = [];
50
+ // ============================================
51
+ // FLUENT STATE
52
+ // ============================================
53
+ this._mode = null;
54
+ this._filters = [];
55
+ this._excludePatterns = [];
56
+ this._includePatterns = [];
57
+ this._stripComponents = 0;
58
+ this._overwrite = false;
36
59
  }
60
+ // ============================================
61
+ // SOURCE METHODS (set extraction mode)
62
+ // ============================================
37
63
  /**
38
- * gets the original archive stream
64
+ * Load archive from URL
39
65
  */
40
- async getArchiveStream() {
41
- if (this.sourceStream) {
42
- return this.sourceStream;
43
- }
44
- if (this.sourceUrl) {
45
- const response = await plugins.smartrequest.SmartRequest.create()
46
- .url(this.sourceUrl)
47
- .get();
48
- const webStream = response.stream();
49
- // @ts-ignore - Web stream to Node.js stream conversion
50
- const urlStream = plugins.stream.Readable.fromWeb(webStream);
51
- return urlStream;
52
- }
53
- if (this.sourceFilePath) {
54
- const fileStream = plugins.fs.createReadStream(this.sourceFilePath);
55
- return fileStream;
66
+ url(urlArg) {
67
+ this.ensureNotInCreateMode('url');
68
+ this._mode = 'extract';
69
+ this.sourceUrl = urlArg;
70
+ return this;
71
+ }
72
+ /**
73
+ * Load archive from file path
74
+ */
75
+ file(pathArg) {
76
+ this.ensureNotInCreateMode('file');
77
+ this._mode = 'extract';
78
+ this.sourceFilePath = pathArg;
79
+ return this;
80
+ }
81
+ /**
82
+ * Load archive from readable stream
83
+ */
84
+ stream(streamArg) {
85
+ this.ensureNotInCreateMode('stream');
86
+ this._mode = 'extract';
87
+ this.sourceStream = streamArg;
88
+ return this;
89
+ }
90
+ /**
91
+ * Load archive from buffer
92
+ */
93
+ buffer(bufferArg) {
94
+ this.ensureNotInCreateMode('buffer');
95
+ this._mode = 'extract';
96
+ this.sourceStream = plugins.stream.Readable.from(bufferArg);
97
+ return this;
98
+ }
99
+ // ============================================
100
+ // FORMAT METHODS (set creation mode)
101
+ // ============================================
102
+ /**
103
+ * Set output format for archive creation
104
+ */
105
+ format(fmt) {
106
+ this.ensureNotInExtractMode('format');
107
+ this._mode = 'create';
108
+ this.creationFormat = fmt;
109
+ return this;
110
+ }
111
+ /**
112
+ * Set compression level (0-9)
113
+ */
114
+ compression(level) {
115
+ this._compressionLevel = level;
116
+ return this;
117
+ }
118
+ // ============================================
119
+ // CONTENT METHODS (creation mode)
120
+ // ============================================
121
+ /**
122
+ * Add a single file entry to the archive
123
+ */
124
+ entry(archivePath, content) {
125
+ this.ensureNotInExtractMode('entry');
126
+ if (!this._mode)
127
+ this._mode = 'create';
128
+ this.pendingEntries.push({ archivePath, content });
129
+ return this;
130
+ }
131
+ /**
132
+ * Add multiple entries to the archive
133
+ */
134
+ entries(entriesArg) {
135
+ this.ensureNotInExtractMode('entries');
136
+ if (!this._mode)
137
+ this._mode = 'create';
138
+ for (const e of entriesArg) {
139
+ this.pendingEntries.push({ archivePath: e.archivePath, content: e.content });
56
140
  }
141
+ return this;
142
+ }
143
+ /**
144
+ * Add an entire directory to the archive (queued, resolved at build time)
145
+ */
146
+ directory(sourcePath, archiveBase) {
147
+ this.ensureNotInExtractMode('directory');
148
+ if (!this._mode)
149
+ this._mode = 'create';
150
+ this.pendingDirectories.push({ sourcePath, archiveBase });
151
+ return this;
57
152
  }
58
- async exportToTarGzStream() {
59
- const tarPackStream = await this.tarTools.getPackStream();
60
- const gzipStream = await this.gzipTools.getCompressionStream();
61
- // const archiveStream = tarPackStream.pipe(gzipStream);
62
- // return archiveStream;
153
+ /**
154
+ * Add a SmartFile to the archive
155
+ */
156
+ addSmartFile(fileArg, archivePath) {
157
+ this.ensureNotInExtractMode('addSmartFile');
158
+ if (!this._mode)
159
+ this._mode = 'create';
160
+ this.pendingEntries.push({
161
+ archivePath: archivePath || fileArg.relative,
162
+ content: fileArg,
163
+ });
164
+ return this;
165
+ }
166
+ /**
167
+ * Add a StreamFile to the archive
168
+ */
169
+ addStreamFile(fileArg, archivePath) {
170
+ this.ensureNotInExtractMode('addStreamFile');
171
+ if (!this._mode)
172
+ this._mode = 'create';
173
+ this.pendingEntries.push({
174
+ archivePath: archivePath || fileArg.relativeFilePath,
175
+ content: fileArg,
176
+ });
177
+ return this;
178
+ }
179
+ // ============================================
180
+ // FILTER METHODS (both modes)
181
+ // ============================================
182
+ /**
183
+ * Filter entries by predicate function
184
+ */
185
+ filter(predicate) {
186
+ this._filters.push(predicate);
187
+ return this;
63
188
  }
64
- async exportToFs(targetDir, fileNameArg) {
189
+ /**
190
+ * Include only entries matching the pattern
191
+ */
192
+ include(pattern) {
193
+ const regex = typeof pattern === 'string' ? new RegExp(pattern) : pattern;
194
+ this._includePatterns.push(regex);
195
+ return this;
196
+ }
197
+ /**
198
+ * Exclude entries matching the pattern
199
+ */
200
+ exclude(pattern) {
201
+ const regex = typeof pattern === 'string' ? new RegExp(pattern) : pattern;
202
+ this._excludePatterns.push(regex);
203
+ return this;
204
+ }
205
+ // ============================================
206
+ // EXTRACTION OPTIONS
207
+ // ============================================
208
+ /**
209
+ * Strip N leading path components from extracted files
210
+ */
211
+ stripComponents(n) {
212
+ this._stripComponents = n;
213
+ return this;
214
+ }
215
+ /**
216
+ * Overwrite existing files during extraction
217
+ */
218
+ overwrite(value = true) {
219
+ this._overwrite = value;
220
+ return this;
221
+ }
222
+ /**
223
+ * Set output filename for single-file archives (gz, bz2)
224
+ */
225
+ fileName(name) {
226
+ this._fileName = name;
227
+ return this;
228
+ }
229
+ // ============================================
230
+ // TERMINAL METHODS - EXTRACTION
231
+ // ============================================
232
+ /**
233
+ * Extract archive to filesystem directory
234
+ */
235
+ async extract(targetDir) {
236
+ this.ensureExtractionSource();
65
237
  const done = plugins.smartpromise.defer();
66
- const streamFileStream = await this.exportToStreamOfStreamFiles();
238
+ const streamFileStream = await this.toStreamFiles();
67
239
  streamFileStream.pipe(new plugins.smartstream.SmartDuplex({
68
240
  objectMode: true,
69
- writeFunction: async (streamFileArg, streamtools) => {
70
- const done = plugins.smartpromise.defer();
71
- console.log(streamFileArg.relativeFilePath
72
- ? streamFileArg.relativeFilePath
73
- : 'no relative path');
241
+ writeFunction: async (streamFileArg) => {
242
+ const innerDone = plugins.smartpromise.defer();
74
243
  const streamFile = streamFileArg;
244
+ let relativePath = streamFile.relativeFilePath || this._fileName || 'extracted_file';
245
+ // Apply stripComponents
246
+ if (this._stripComponents > 0) {
247
+ const parts = relativePath.split('/');
248
+ relativePath = parts.slice(this._stripComponents).join('/');
249
+ if (!relativePath) {
250
+ innerDone.resolve();
251
+ return;
252
+ }
253
+ }
254
+ // Apply filter
255
+ const filterFn = this.buildFilterFunction();
256
+ if (filterFn) {
257
+ const entryInfo = {
258
+ path: relativePath,
259
+ size: 0,
260
+ isDirectory: false,
261
+ isFile: true,
262
+ };
263
+ if (!filterFn(entryInfo)) {
264
+ innerDone.resolve();
265
+ return;
266
+ }
267
+ }
75
268
  const readStream = await streamFile.createReadStream();
76
269
  await plugins.fsPromises.mkdir(targetDir, { recursive: true });
77
- const writePath = plugins.path.join(targetDir, streamFile.relativeFilePath || fileNameArg);
270
+ const writePath = plugins.path.join(targetDir, relativePath);
78
271
  await plugins.fsPromises.mkdir(plugins.path.dirname(writePath), { recursive: true });
79
272
  const writeStream = plugins.fs.createWriteStream(writePath);
80
273
  readStream.pipe(writeStream);
81
274
  writeStream.on('finish', () => {
82
- done.resolve();
275
+ innerDone.resolve();
83
276
  });
84
- await done.promise;
277
+ await innerDone.promise;
85
278
  },
86
279
  finalFunction: async () => {
87
280
  done.resolve();
@@ -89,41 +282,44 @@ export class SmartArchive {
89
282
  }));
90
283
  return done.promise;
91
284
  }
92
- async exportToStreamOfStreamFiles() {
285
+ /**
286
+ * Extract archive to a stream of StreamFile objects
287
+ */
288
+ async toStreamFiles() {
289
+ this.ensureExtractionSource();
93
290
  const streamFileIntake = new plugins.smartstream.StreamIntake({
94
291
  objectMode: true,
95
292
  });
96
- const archiveStream = await this.getArchiveStream();
293
+ // Guard to prevent multiple signalEnd calls
294
+ let hasSignaledEnd = false;
295
+ const safeSignalEnd = () => {
296
+ if (!hasSignaledEnd) {
297
+ hasSignaledEnd = true;
298
+ streamFileIntake.signalEnd();
299
+ }
300
+ };
301
+ const archiveStream = await this.getSourceStream();
97
302
  const createAnalyzedStream = () => this.archiveAnalyzer.getAnalyzedStream();
98
- // lets create a function that can be called multiple times to unpack layers of archives
99
303
  const createUnpackStream = () => plugins.smartstream.createTransformFunction(async (analyzedResultChunk) => {
100
304
  if (analyzedResultChunk.fileType?.mime === 'application/x-tar') {
101
305
  const tarStream = analyzedResultChunk.decompressionStream;
102
306
  tarStream.on('entry', async (header, stream, next) => {
103
307
  if (header.type === 'directory') {
104
- console.log(`tar stream directory: ${header.name} ... skipping!`);
105
- stream.resume(); // Consume directory stream
308
+ stream.resume();
106
309
  stream.on('end', () => next());
107
310
  return;
108
311
  }
109
- console.log(`tar stream file: ${header.name}`);
110
- // Create a PassThrough stream to buffer the data
111
312
  const passThrough = new plugins.stream.PassThrough();
112
313
  const streamfile = plugins.smartfile.StreamFile.fromStream(passThrough, header.name);
113
- // Push the streamfile immediately
114
314
  streamFileIntake.push(streamfile);
115
- // Pipe the tar entry stream to the passthrough
116
315
  stream.pipe(passThrough);
117
- // Move to next entry when this one ends
118
316
  stream.on('end', () => {
119
317
  passThrough.end();
120
318
  next();
121
319
  });
122
320
  });
123
- tarStream.on('finish', function () {
124
- console.log('tar extraction finished');
125
- // Only signal end if this is the final stream
126
- streamFileIntake.signalEnd();
321
+ tarStream.on('finish', () => {
322
+ safeSignalEnd();
127
323
  });
128
324
  analyzedResultChunk.resultStream.pipe(analyzedResultChunk.decompressionStream);
129
325
  }
@@ -132,33 +328,410 @@ export class SmartArchive {
132
328
  .pipe(analyzedResultChunk.decompressionStream)
133
329
  .pipe(new plugins.smartstream.SmartDuplex({
134
330
  objectMode: true,
135
- writeFunction: async (streamFileArg, streamtools) => {
331
+ writeFunction: async (streamFileArg) => {
136
332
  streamFileIntake.push(streamFileArg);
137
333
  },
138
334
  finalFunction: async () => {
139
- streamFileIntake.signalEnd();
335
+ safeSignalEnd();
140
336
  },
141
337
  }));
142
338
  }
143
- else if (analyzedResultChunk.isArchive &&
144
- analyzedResultChunk.decompressionStream) {
339
+ else if (analyzedResultChunk.isArchive && analyzedResultChunk.decompressionStream) {
145
340
  // For nested archives (like gzip containing tar)
146
- const nestedStream = analyzedResultChunk.resultStream
341
+ analyzedResultChunk.resultStream
147
342
  .pipe(analyzedResultChunk.decompressionStream)
148
343
  .pipe(createAnalyzedStream())
149
344
  .pipe(createUnpackStream());
150
- // Don't signal end here - let the nested unpacker handle it
151
345
  }
152
346
  else {
153
347
  const streamFile = plugins.smartfile.StreamFile.fromStream(analyzedResultChunk.resultStream, analyzedResultChunk.fileType?.ext);
154
348
  streamFileIntake.push(streamFile);
155
- streamFileIntake.signalEnd();
349
+ safeSignalEnd();
156
350
  }
157
- }, {
158
- objectMode: true,
159
- });
351
+ }, { objectMode: true });
160
352
  archiveStream.pipe(createAnalyzedStream()).pipe(createUnpackStream());
161
353
  return streamFileIntake;
162
354
  }
355
+ /**
356
+ * Extract archive to an array of SmartFile objects (in-memory)
357
+ */
358
+ async toSmartFiles() {
359
+ this.ensureExtractionSource();
360
+ const streamFiles = await this.toStreamFiles();
361
+ const smartFiles = [];
362
+ const filterFn = this.buildFilterFunction();
363
+ const pendingConversions = [];
364
+ return new Promise((resolve, reject) => {
365
+ streamFiles.on('data', (streamFile) => {
366
+ // Track all async conversions to ensure they complete before resolving
367
+ const conversion = (async () => {
368
+ try {
369
+ const smartFile = await streamFile.toSmartFile();
370
+ // Apply filter if configured
371
+ if (filterFn) {
372
+ const passes = filterFn({
373
+ path: smartFile.relative,
374
+ size: smartFile.contents.length,
375
+ isDirectory: false,
376
+ isFile: true,
377
+ });
378
+ if (!passes)
379
+ return;
380
+ }
381
+ smartFiles.push(smartFile);
382
+ }
383
+ catch (err) {
384
+ reject(err);
385
+ }
386
+ })();
387
+ pendingConversions.push(conversion);
388
+ });
389
+ streamFiles.on('end', async () => {
390
+ // Wait for all conversions to complete before resolving
391
+ await Promise.all(pendingConversions);
392
+ resolve(smartFiles);
393
+ });
394
+ streamFiles.on('error', reject);
395
+ });
396
+ }
397
+ /**
398
+ * Extract a single file from the archive by path
399
+ */
400
+ async extractFile(filePath) {
401
+ this.ensureExtractionSource();
402
+ const streamFiles = await this.toStreamFiles();
403
+ return new Promise((resolve, reject) => {
404
+ let found = false;
405
+ streamFiles.on('data', async (streamFile) => {
406
+ if (streamFile.relativeFilePath === filePath || streamFile.relativeFilePath?.endsWith(filePath)) {
407
+ found = true;
408
+ try {
409
+ const smartFile = await streamFile.toSmartFile();
410
+ resolve(smartFile);
411
+ }
412
+ catch (err) {
413
+ reject(err);
414
+ }
415
+ }
416
+ });
417
+ streamFiles.on('end', () => {
418
+ if (!found) {
419
+ resolve(null);
420
+ }
421
+ });
422
+ streamFiles.on('error', reject);
423
+ });
424
+ }
425
+ // ============================================
426
+ // TERMINAL METHODS - OUTPUT
427
+ // ============================================
428
+ /**
429
+ * Build and finalize the archive, returning this instance
430
+ */
431
+ async build() {
432
+ await this.doBuild();
433
+ return this;
434
+ }
435
+ /**
436
+ * Internal build implementation (avoids thenable recursion)
437
+ */
438
+ async doBuild() {
439
+ if (this._mode === 'extract') {
440
+ // For extraction mode, nothing to build
441
+ return;
442
+ }
443
+ if (this.archiveBuffer) {
444
+ // Already built
445
+ return;
446
+ }
447
+ // For creation mode, build the archive buffer
448
+ this.ensureCreationFormat();
449
+ await this.resolveDirectories();
450
+ const entries = this.getFilteredEntries();
451
+ if (this.creationFormat === 'tar' || this.creationFormat === 'tar.gz' || this.creationFormat === 'tgz') {
452
+ if (this.creationFormat === 'tar') {
453
+ this.archiveBuffer = await this.tarTools.packFiles(entries);
454
+ }
455
+ else {
456
+ this.archiveBuffer = await this.tarTools.packFilesToTarGz(entries, this._compressionLevel);
457
+ }
458
+ }
459
+ else if (this.creationFormat === 'zip') {
460
+ this.archiveBuffer = await this.zipTools.createZip(entries, this._compressionLevel);
461
+ }
462
+ else if (this.creationFormat === 'gz') {
463
+ if (entries.length !== 1) {
464
+ throw new Error('GZIP format only supports a single file');
465
+ }
466
+ let content;
467
+ if (typeof entries[0].content === 'string') {
468
+ content = Buffer.from(entries[0].content);
469
+ }
470
+ else if (Buffer.isBuffer(entries[0].content)) {
471
+ content = entries[0].content;
472
+ }
473
+ else {
474
+ throw new Error('GZIP format requires string or Buffer content');
475
+ }
476
+ this.archiveBuffer = await this.gzipTools.compress(content, this._compressionLevel);
477
+ }
478
+ else {
479
+ throw new Error(`Unsupported format: ${this.creationFormat}`);
480
+ }
481
+ }
482
+ /**
483
+ * Build archive and return as Buffer
484
+ */
485
+ async toBuffer() {
486
+ if (this._mode === 'create' && !this.archiveBuffer) {
487
+ await this.doBuild();
488
+ }
489
+ if (this.archiveBuffer) {
490
+ return this.archiveBuffer;
491
+ }
492
+ // For extraction mode, get the source as buffer
493
+ const stream = await this.getSourceStream();
494
+ return this.streamToBuffer(stream);
495
+ }
496
+ /**
497
+ * Build archive and write to file
498
+ */
499
+ async toFile(filePath) {
500
+ const buffer = await this.toBuffer();
501
+ await plugins.fsPromises.mkdir(plugins.path.dirname(filePath), { recursive: true });
502
+ await plugins.fsPromises.writeFile(filePath, buffer);
503
+ }
504
+ /**
505
+ * Get archive as a readable stream
506
+ */
507
+ async toStream() {
508
+ if (this._mode === 'create' && !this.archiveBuffer) {
509
+ await this.doBuild();
510
+ }
511
+ if (this.archiveBuffer) {
512
+ return plugins.stream.Readable.from(this.archiveBuffer);
513
+ }
514
+ return this.getSourceStream();
515
+ }
516
+ // ============================================
517
+ // TERMINAL METHODS - ANALYSIS
518
+ // ============================================
519
+ /**
520
+ * Analyze the archive and return metadata
521
+ */
522
+ async analyze() {
523
+ this.ensureExtractionSource();
524
+ const stream = await this.getSourceStream();
525
+ const firstChunk = await this.readFirstChunk(stream);
526
+ const fileType = await plugins.fileType.fileTypeFromBuffer(firstChunk);
527
+ let format = null;
528
+ let isCompressed = false;
529
+ let isArchive = false;
530
+ if (fileType) {
531
+ switch (fileType.mime) {
532
+ case 'application/gzip':
533
+ format = 'gz';
534
+ isCompressed = true;
535
+ isArchive = true;
536
+ break;
537
+ case 'application/zip':
538
+ format = 'zip';
539
+ isCompressed = true;
540
+ isArchive = true;
541
+ break;
542
+ case 'application/x-tar':
543
+ format = 'tar';
544
+ isArchive = true;
545
+ break;
546
+ case 'application/x-bzip2':
547
+ format = 'bz2';
548
+ isCompressed = true;
549
+ isArchive = true;
550
+ break;
551
+ }
552
+ }
553
+ return {
554
+ format,
555
+ isCompressed,
556
+ isArchive,
557
+ };
558
+ }
559
+ /**
560
+ * List all entries in the archive
561
+ */
562
+ async list() {
563
+ this.ensureExtractionSource();
564
+ const entries = [];
565
+ const streamFiles = await this.toStreamFiles();
566
+ return new Promise((resolve, reject) => {
567
+ streamFiles.on('data', (streamFile) => {
568
+ entries.push({
569
+ path: streamFile.relativeFilePath || 'unknown',
570
+ size: 0, // Size not available without reading
571
+ isDirectory: false,
572
+ isFile: true,
573
+ });
574
+ });
575
+ streamFiles.on('end', () => resolve(entries));
576
+ streamFiles.on('error', reject);
577
+ });
578
+ }
579
+ /**
580
+ * Check if a specific file exists in the archive
581
+ */
582
+ async hasFile(filePath) {
583
+ this.ensureExtractionSource();
584
+ const entries = await this.list();
585
+ return entries.some((e) => e.path === filePath || e.path.endsWith(filePath));
586
+ }
587
+ // ============================================
588
+ // PRIVATE HELPERS
589
+ // ============================================
590
+ /**
591
+ * Ensure we're not in create mode when calling extraction methods
592
+ */
593
+ ensureNotInCreateMode(methodName) {
594
+ if (this._mode === 'create') {
595
+ throw new Error(`Cannot call .${methodName}() in creation mode. ` +
596
+ `Use extraction methods (.url(), .file(), .stream(), .buffer()) for extraction mode.`);
597
+ }
598
+ }
599
+ /**
600
+ * Ensure we're not in extract mode when calling creation methods
601
+ */
602
+ ensureNotInExtractMode(methodName) {
603
+ if (this._mode === 'extract') {
604
+ throw new Error(`Cannot call .${methodName}() in extraction mode. ` +
605
+ `Use .format() for creation mode.`);
606
+ }
607
+ }
608
+ /**
609
+ * Ensure an extraction source is configured
610
+ */
611
+ ensureExtractionSource() {
612
+ if (!this.sourceUrl && !this.sourceFilePath && !this.sourceStream && !this.archiveBuffer) {
613
+ throw new Error('No source configured. Call .url(), .file(), .stream(), or .buffer() first.');
614
+ }
615
+ }
616
+ /**
617
+ * Ensure a format is configured for creation
618
+ */
619
+ ensureCreationFormat() {
620
+ if (!this.creationFormat) {
621
+ throw new Error('No format specified. Call .format() before creating archive.');
622
+ }
623
+ }
624
+ /**
625
+ * Get the source stream
626
+ */
627
+ async getSourceStream() {
628
+ if (this.archiveBuffer) {
629
+ return plugins.stream.Readable.from(this.archiveBuffer);
630
+ }
631
+ if (this.sourceStream) {
632
+ return this.sourceStream;
633
+ }
634
+ if (this.sourceUrl) {
635
+ const response = await plugins.smartrequest.SmartRequest.create()
636
+ .url(this.sourceUrl)
637
+ .get();
638
+ const webStream = response.stream();
639
+ return plugins.stream.Readable.fromWeb(webStream);
640
+ }
641
+ if (this.sourceFilePath) {
642
+ return plugins.fs.createReadStream(this.sourceFilePath);
643
+ }
644
+ throw new Error('No archive source configured');
645
+ }
646
+ /**
647
+ * Build a combined filter function from all configured filters
648
+ */
649
+ buildFilterFunction() {
650
+ const hasFilters = this._filters.length > 0 ||
651
+ this._includePatterns.length > 0 ||
652
+ this._excludePatterns.length > 0;
653
+ if (!hasFilters) {
654
+ return undefined;
655
+ }
656
+ return (entry) => {
657
+ // Check include patterns (if any specified, at least one must match)
658
+ if (this._includePatterns.length > 0) {
659
+ const included = this._includePatterns.some((p) => p.test(entry.path));
660
+ if (!included)
661
+ return false;
662
+ }
663
+ // Check exclude patterns (none must match)
664
+ for (const pattern of this._excludePatterns) {
665
+ if (pattern.test(entry.path))
666
+ return false;
667
+ }
668
+ // Check custom filters (all must pass)
669
+ for (const filter of this._filters) {
670
+ if (!filter(entry))
671
+ return false;
672
+ }
673
+ return true;
674
+ };
675
+ }
676
+ /**
677
+ * Resolve pending directories to entries
678
+ */
679
+ async resolveDirectories() {
680
+ for (const dir of this.pendingDirectories) {
681
+ const files = await plugins.listFileTree(dir.sourcePath, '**/*');
682
+ for (const filePath of files) {
683
+ const archivePath = dir.archiveBase
684
+ ? plugins.path.join(dir.archiveBase, filePath)
685
+ : filePath;
686
+ const absolutePath = plugins.path.join(dir.sourcePath, filePath);
687
+ const content = await plugins.fsPromises.readFile(absolutePath);
688
+ this.pendingEntries.push({
689
+ archivePath,
690
+ content,
691
+ });
692
+ }
693
+ }
694
+ this.pendingDirectories = [];
695
+ }
696
+ /**
697
+ * Get entries filtered by include/exclude patterns
698
+ */
699
+ getFilteredEntries() {
700
+ const filterFn = this.buildFilterFunction();
701
+ if (!filterFn) {
702
+ return this.pendingEntries;
703
+ }
704
+ return this.pendingEntries.filter((entry) => filterFn({
705
+ path: entry.archivePath,
706
+ size: 0,
707
+ isDirectory: false,
708
+ isFile: true,
709
+ }));
710
+ }
711
+ /**
712
+ * Convert a stream to buffer
713
+ */
714
+ async streamToBuffer(stream) {
715
+ const chunks = [];
716
+ return new Promise((resolve, reject) => {
717
+ stream.on('data', (chunk) => chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk)));
718
+ stream.on('end', () => resolve(Buffer.concat(chunks)));
719
+ stream.on('error', reject);
720
+ });
721
+ }
722
+ /**
723
+ * Read first chunk from stream
724
+ */
725
+ async readFirstChunk(stream) {
726
+ return new Promise((resolve, reject) => {
727
+ const onData = (chunk) => {
728
+ stream.removeListener('data', onData);
729
+ stream.removeListener('error', reject);
730
+ resolve(chunk);
731
+ };
732
+ stream.on('data', onData);
733
+ stream.on('error', reject);
734
+ });
735
+ }
163
736
  }
164
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5zbWFydGFyY2hpdmUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9jbGFzc2VzLnNtYXJ0YXJjaGl2ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGNBQWMsQ0FBQztBQUN4QyxPQUFPLEtBQUssS0FBSyxNQUFNLFlBQVksQ0FBQztBQUVwQyxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDckQsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQ25ELE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUNqRCxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFFakQsT0FBTyxFQUNMLGVBQWUsR0FFaEIsTUFBTSw4QkFBOEIsQ0FBQztBQUl0QyxNQUFNLE9BQU8sWUFBWTtJQUN2QixTQUFTO0lBQ0YsTUFBTSxDQUFDLEtBQUssQ0FBQyxjQUFjLENBQUMsTUFBYztRQUMvQyxNQUFNLG9CQUFvQixHQUFHLElBQUksWUFBWSxFQUFFLENBQUM7UUFDaEQsb0JBQW9CLENBQUMsU0FBUyxHQUFHLE1BQU0sQ0FBQztRQUN4QyxPQUFPLG9CQUFvQixDQUFDO0lBQzlCLENBQUM7SUFFTSxNQUFNLENBQUMsS0FBSyxDQUFDLGVBQWUsQ0FDakMsV0FBbUI7UUFFbkIsTUFBTSxvQkFBb0IsR0FBRyxJQUFJLFlBQVksRUFBRSxDQUFDO1FBQ2hELG9CQUFvQixDQUFDLGNBQWMsR0FBRyxXQUFXLENBQUM7UUFDbEQsT0FBTyxvQkFBb0IsQ0FBQztJQUM5QixDQUFDO0lBRU0sTUFBTSxDQUFDLEtBQUssQ0FBQyxpQkFBaUIsQ0FDbkMsU0FHNEI7UUFFNUIsTUFBTSxvQkFBb0IsR0FBRyxJQUFJLFlBQVksRUFBRSxDQUFDO1FBQ2hELG9CQUFvQixDQUFDLFlBQVksR0FBRyxTQUFTLENBQUM7UUFDOUMsT0FBTyxvQkFBb0IsQ0FBQztJQUM5QixDQUFDO0lBMEJEO1FBeEJBLFdBQVc7UUFDSixhQUFRLEdBQUcsSUFBSSxRQUFRLEVBQUUsQ0FBQztRQUMxQixhQUFRLEdBQUcsSUFBSSxRQUFRLEVBQUUsQ0FBQztRQUMxQixjQUFTLEdBQUcsSUFBSSxTQUFTLEVBQUUsQ0FBQztRQUM1QixlQUFVLEdBQUcsSUFBSSxVQUFVLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDbEMsb0JBQWUsR0FBRyxJQUFJLGVBQWUsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQVU1QyxtQkFBYyxHQUFZLEtBQUssQ0FBQztRQUVoQyxxQkFBZ0IsR0FBYSxFQUFFLENBQUM7UUFDaEMsZUFBVSxHQUdYLEVBQUUsQ0FBQztRQUNGLGNBQVMsR0FBYSxFQUFFLENBQUM7SUFFakIsQ0FBQztJQUVoQjs7T0FFRztJQUNJLEtBQUssQ0FBQyxnQkFBZ0I7UUFDM0IsSUFBSSxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7WUFDdEIsT0FBTyxJQUFJLENBQUMsWUFBWSxDQUFDO1FBQzNCLENBQUM7UUFDRCxJQUFJLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztZQUNuQixNQUFNLFFBQVEsR0FBRyxNQUFNLE9BQU8sQ0FBQyxZQUFZLENBQUMsWUFBWSxDQUFDLE1BQU0sRUFBRTtpQkFDOUQsR0FBRyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUM7aUJBQ25CLEdBQUcsRUFBRSxDQUFDO1lBQ1QsTUFBTSxTQUFTLEdBQUcsUUFBUSxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQ3BDLHVEQUF1RDtZQUN2RCxNQUFNLFNBQVMsR0FBRyxPQUFPLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLENBQUM7WUFDN0QsT0FBTyxTQUFTLENBQUM7UUFDbkIsQ0FBQztRQUNELElBQUksSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDO1lBQ3hCLE1BQU0sVUFBVSxHQUFHLE9BQU8sQ0FBQyxFQUFFLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxDQUFDO1lBQ3BFLE9BQU8sVUFBVSxDQUFDO1FBQ3BCLENBQUM7SUFDSCxDQUFDO0lBRU0sS0FBSyxDQUFDLG1CQUFtQjtRQUM5QixNQUFNLGFBQWEsR0FBRyxNQUFNLElBQUksQ0FBQyxRQUFRLENBQUMsYUFBYSxFQUFFLENBQUM7UUFDMUQsTUFBTSxVQUFVLEdBQUcsTUFBTSxJQUFJLENBQUMsU0FBUyxDQUFDLG9CQUFvQixFQUFFLENBQUM7UUFDL0Qsd0RBQXdEO1FBQ3hELHdCQUF3QjtJQUMxQixDQUFDO0lBRU0sS0FBSyxDQUFDLFVBQVUsQ0FDckIsU0FBaUIsRUFDakIsV0FBb0I7UUFFcEIsTUFBTSxJQUFJLEdBQUcsT0FBTyxDQUFDLFlBQVksQ0FBQyxLQUFLLEVBQVEsQ0FBQztRQUNoRCxNQUFNLGdCQUFnQixHQUFHLE1BQU0sSUFBSSxDQUFDLDJCQUEyQixFQUFFLENBQUM7UUFDbEUsZ0JBQWdCLENBQUMsSUFBSSxDQUNuQixJQUFJLE9BQU8sQ0FBQyxXQUFXLENBQUMsV0FBVyxDQUFDO1lBQ2xDLFVBQVUsRUFBRSxJQUFJO1lBQ2hCLGFBQWEsRUFBRSxLQUFLLEVBQ2xCLGFBQTJDLEVBQzNDLFdBQVcsRUFDWCxFQUFFO2dCQUNGLE1BQU0sSUFBSSxHQUFHLE9BQU8sQ0FBQyxZQUFZLENBQUMsS0FBSyxFQUFRLENBQUM7Z0JBQ2hELE9BQU8sQ0FBQyxHQUFHLENBQ1QsYUFBYSxDQUFDLGdCQUFnQjtvQkFDNUIsQ0FBQyxDQUFDLGFBQWEsQ0FBQyxnQkFBZ0I7b0JBQ2hDLENBQUMsQ0FBQyxrQkFBa0IsQ0FDdkIsQ0FBQztnQkFDRixNQUFNLFVBQVUsR0FBRyxhQUFhLENBQUM7Z0JBQ2pDLE1BQU0sVUFBVSxHQUFHLE1BQU0sVUFBVSxDQUFDLGdCQUFnQixFQUFFLENBQUM7Z0JBQ3ZELE1BQU0sT0FBTyxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsU0FBUyxFQUFFLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7Z0JBQy9ELE1BQU0sU0FBUyxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUNqQyxTQUFTLEVBQ1QsVUFBVSxDQUFDLGdCQUFnQixJQUFJLFdBQVcsQ0FDM0MsQ0FBQztnQkFDRixNQUFNLE9BQU8sQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxFQUFFLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7Z0JBQ3JGLE1BQU0sV0FBVyxHQUFHLE9BQU8sQ0FBQyxFQUFFLENBQUMsaUJBQWlCLENBQUMsU0FBUyxDQUFDLENBQUM7Z0JBQzVELFVBQVUsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7Z0JBQzdCLFdBQVcsQ0FBQyxFQUFFLENBQUMsUUFBUSxFQUFFLEdBQUcsRUFBRTtvQkFDNUIsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO2dCQUNqQixDQUFDLENBQUMsQ0FBQztnQkFDSCxNQUFNLElBQUksQ0FBQyxPQUFPLENBQUM7WUFDckIsQ0FBQztZQUNELGFBQWEsRUFBRSxLQUFLLElBQUksRUFBRTtnQkFDeEIsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQ2pCLENBQUM7U0FDRixDQUFDLENBQ0gsQ0FBQztRQUNGLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQztJQUN0QixDQUFDO0lBRU0sS0FBSyxDQUFDLDJCQUEyQjtRQUN0QyxNQUFNLGdCQUFnQixHQUNwQixJQUFJLE9BQU8sQ0FBQyxXQUFXLENBQUMsWUFBWSxDQUErQjtZQUNqRSxVQUFVLEVBQUUsSUFBSTtTQUNqQixDQUFDLENBQUM7UUFDTCxNQUFNLGFBQWEsR0FBRyxNQUFNLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO1FBQ3BELE1BQU0sb0JBQW9CLEdBQUcsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO1FBRTVFLHdGQUF3RjtRQUN4RixNQUFNLGtCQUFrQixHQUFHLEdBQUcsRUFBRSxDQUM5QixPQUFPLENBQUMsV0FBVyxDQUFDLHVCQUF1QixDQUN6QyxLQUFLLEVBQUUsbUJBQW1CLEVBQUUsRUFBRTtZQUM1QixJQUFJLG1CQUFtQixDQUFDLFFBQVEsRUFBRSxJQUFJLEtBQUssbUJBQW1CLEVBQUUsQ0FBQztnQkFDL0QsTUFBTSxTQUFTLEdBQ2IsbUJBQW1CLENBQUMsbUJBQWdELENBQUM7Z0JBQ3ZFLFNBQVMsQ0FBQyxFQUFFLENBQUMsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxFQUFFO29CQUNuRCxJQUFJLE1BQU0sQ0FBQyxJQUFJLEtBQUssV0FBVyxFQUFFLENBQUM7d0JBQ2hDLE9BQU8sQ0FBQyxHQUFHLENBQ1QseUJBQXlCLE1BQU0sQ0FBQyxJQUFJLGdCQUFnQixDQUNyRCxDQUFDO3dCQUNGLE1BQU0sQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLDJCQUEyQjt3QkFDNUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxLQUFLLEVBQUUsR0FBRyxFQUFFLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQzt3QkFDL0IsT0FBTztvQkFDVCxDQUFDO29CQUNELE9BQU8sQ0FBQyxHQUFHLENBQUMsb0JBQW9CLE1BQU0sQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDO29CQUUvQyxpREFBaUQ7b0JBQ2pELE1BQU0sV0FBVyxHQUFHLElBQUksT0FBTyxDQUFDLE1BQU0sQ0FBQyxXQUFXLEVBQUUsQ0FBQztvQkFDckQsTUFBTSxVQUFVLEdBQUcsT0FBTyxDQUFDLFNBQVMsQ0FBQyxVQUFVLENBQUMsVUFBVSxDQUN4RCxXQUFXLEVBQ1gsTUFBTSxDQUFDLElBQUksQ0FDWixDQUFDO29CQUVGLGtDQUFrQztvQkFDbEMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO29CQUVsQywrQ0FBK0M7b0JBQy9DLE1BQU0sQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7b0JBRXpCLHdDQUF3QztvQkFDeEMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxLQUFLLEVBQUUsR0FBRyxFQUFFO3dCQUNwQixXQUFXLENBQUMsR0FBRyxFQUFFLENBQUM7d0JBQ2xCLElBQUksRUFBRSxDQUFDO29CQUNULENBQUMsQ0FBQyxDQUFDO2dCQUNMLENBQUMsQ0FBQyxDQUFDO2dCQUNILFNBQVMsQ0FBQyxFQUFFLENBQUMsUUFBUSxFQUFFO29CQUNyQixPQUFPLENBQUMsR0FBRyxDQUFDLHlCQUF5QixDQUFDLENBQUM7b0JBQ3ZDLDhDQUE4QztvQkFDOUMsZ0JBQWdCLENBQUMsU0FBUyxFQUFFLENBQUM7Z0JBQy9CLENBQUMsQ0FBQyxDQUFDO2dCQUNILG1CQUFtQixDQUFDLFlBQVksQ0FBQyxJQUFJLENBQ25DLG1CQUFtQixDQUFDLG1CQUFtQixDQUN4QyxDQUFDO1lBQ0osQ0FBQztpQkFBTSxJQUFJLG1CQUFtQixDQUFDLFFBQVEsRUFBRSxJQUFJLEtBQUssaUJBQWlCLEVBQUUsQ0FBQztnQkFDcEUsbUJBQW1CLENBQUMsWUFBWTtxQkFDN0IsSUFBSSxDQUFDLG1CQUFtQixDQUFDLG1CQUFtQixDQUFDO3FCQUM3QyxJQUFJLENBQ0gsSUFBSSxPQUFPLENBQUMsV0FBVyxDQUFDLFdBQVcsQ0FBQztvQkFDbEMsVUFBVSxFQUFFLElBQUk7b0JBQ2hCLGFBQWEsRUFBRSxLQUFLLEVBQ2xCLGFBQTJDLEVBQzNDLFdBQVcsRUFDWCxFQUFFO3dCQUNGLGdCQUFnQixDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQztvQkFDdkMsQ0FBQztvQkFDRCxhQUFhLEVBQUUsS0FBSyxJQUFJLEVBQUU7d0JBQ3hCLGdCQUFnQixDQUFDLFNBQVMsRUFBRSxDQUFDO29CQUMvQixDQUFDO2lCQUNGLENBQUMsQ0FDSCxDQUFDO1lBQ04sQ0FBQztpQkFBTSxJQUNMLG1CQUFtQixDQUFDLFNBQVM7Z0JBQzdCLG1CQUFtQixDQUFDLG1CQUFtQixFQUN2QyxDQUFDO2dCQUNELGlEQUFpRDtnQkFDakQsTUFBTSxZQUFZLEdBQUcsbUJBQW1CLENBQUMsWUFBWTtxQkFDbEQsSUFBSSxDQUFDLG1CQUFtQixDQUFDLG1CQUFtQixDQUFDO3FCQUM3QyxJQUFJLENBQUMsb0JBQW9CLEVBQUUsQ0FBQztxQkFDNUIsSUFBSSxDQUFDLGtCQUFrQixFQUFFLENBQUMsQ0FBQztnQkFFOUIsNERBQTREO1lBQzlELENBQUM7aUJBQU0sQ0FBQztnQkFDTixNQUFNLFVBQVUsR0FBRyxPQUFPLENBQUMsU0FBUyxDQUFDLFVBQVUsQ0FBQyxVQUFVLENBQ3hELG1CQUFtQixDQUFDLFlBQVksRUFDaEMsbUJBQW1CLENBQUMsUUFBUSxFQUFFLEdBQUcsQ0FDbEMsQ0FBQztnQkFDRixnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7Z0JBQ2xDLGdCQUFnQixDQUFDLFNBQVMsRUFBRSxDQUFDO1lBQy9CLENBQUM7UUFDSCxDQUFDLEVBQ0Q7WUFDRSxVQUFVLEVBQUUsSUFBSTtTQUNqQixDQUNGLENBQUM7UUFFSixhQUFhLENBQUMsSUFBSSxDQUFDLG9CQUFvQixFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsa0JBQWtCLEVBQUUsQ0FBQyxDQUFDO1FBQ3RFLE9BQU8sZ0JBQWdCLENBQUM7SUFDMUIsQ0FBQztDQUNGIn0=
737
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5zbWFydGFyY2hpdmUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9jbGFzc2VzLnNtYXJ0YXJjaGl2ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGNBQWMsQ0FBQztBQVV4QyxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDckQsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQ25ELE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUNqRCxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDakQsT0FBTyxFQUFFLGVBQWUsRUFBd0IsTUFBTSw4QkFBOEIsQ0FBQztBQVVyRjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FvQkc7QUFDSCxNQUFNLE9BQU8sWUFBWTtJQUN2QiwrQ0FBK0M7SUFDL0MscUJBQXFCO0lBQ3JCLCtDQUErQztJQUUvQzs7T0FFRztJQUNJLE1BQU0sQ0FBQyxNQUFNO1FBQ2xCLE9BQU8sSUFBSSxZQUFZLEVBQUUsQ0FBQztJQUM1QixDQUFDO0lBMENEO1FBeENBLCtDQUErQztRQUMvQyxrQ0FBa0M7UUFDbEMsK0NBQStDO1FBRXhDLGFBQVEsR0FBRyxJQUFJLFFBQVEsRUFBRSxDQUFDO1FBQzFCLGFBQVEsR0FBRyxJQUFJLFFBQVEsRUFBRSxDQUFDO1FBQzFCLGNBQVMsR0FBRyxJQUFJLFNBQVMsRUFBRSxDQUFDO1FBQzVCLGVBQVUsR0FBRyxJQUFJLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNsQyxvQkFBZSxHQUFHLElBQUksZUFBZSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBZ0IzQyxzQkFBaUIsR0FBc0IsQ0FBQyxDQUFDO1FBQ3pDLG1CQUFjLEdBQW9CLEVBQUUsQ0FBQztRQUNyQyx1QkFBa0IsR0FBd0IsRUFBRSxDQUFDO1FBRXJELCtDQUErQztRQUMvQyxlQUFl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