@rushstack/zipsync 0.2.13 → 0.3.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/CHANGELOG.json +41 -0
- package/CHANGELOG.md +13 -1
- package/bin/zipsync +1 -1
- package/lib-esm/cli/ZipSyncCommandLineParser.js +93 -0
- package/lib-esm/cli/ZipSyncCommandLineParser.js.map +1 -0
- package/lib-esm/compress.js +115 -0
- package/lib-esm/compress.js.map +1 -0
- package/lib-esm/crc32.js +32 -0
- package/lib-esm/crc32.js.map +1 -0
- package/lib-esm/fs.js +48 -0
- package/lib-esm/fs.js.map +1 -0
- package/lib-esm/hash.js +39 -0
- package/lib-esm/hash.js.map +1 -0
- package/lib-esm/index.js +5 -0
- package/lib-esm/index.js.map +1 -0
- package/lib-esm/pack.js +379 -0
- package/lib-esm/pack.js.map +1 -0
- package/lib-esm/packWorker.js +58 -0
- package/lib-esm/packWorker.js.map +1 -0
- package/lib-esm/packWorkerAsync.js +43 -0
- package/lib-esm/packWorkerAsync.js.map +1 -0
- package/lib-esm/perf.js +49 -0
- package/lib-esm/perf.js.map +1 -0
- package/lib-esm/start.js +17 -0
- package/lib-esm/start.js.map +1 -0
- package/lib-esm/unpack.js +334 -0
- package/lib-esm/unpack.js.map +1 -0
- package/lib-esm/unpackWorker.js +54 -0
- package/lib-esm/unpackWorker.js.map +1 -0
- package/lib-esm/unpackWorkerAsync.js +43 -0
- package/lib-esm/unpackWorkerAsync.js.map +1 -0
- package/lib-esm/zipSyncUtils.js +6 -0
- package/lib-esm/zipSyncUtils.js.map +1 -0
- package/lib-esm/zipUtils.js +292 -0
- package/lib-esm/zipUtils.js.map +1 -0
- package/package.json +33 -6
- /package/{lib → lib-commonjs}/cli/ZipSyncCommandLineParser.js +0 -0
- /package/{lib → lib-commonjs}/cli/ZipSyncCommandLineParser.js.map +0 -0
- /package/{lib → lib-commonjs}/compress.js +0 -0
- /package/{lib → lib-commonjs}/compress.js.map +0 -0
- /package/{lib → lib-commonjs}/crc32.js +0 -0
- /package/{lib → lib-commonjs}/crc32.js.map +0 -0
- /package/{lib → lib-commonjs}/fs.js +0 -0
- /package/{lib → lib-commonjs}/fs.js.map +0 -0
- /package/{lib → lib-commonjs}/hash.js +0 -0
- /package/{lib → lib-commonjs}/hash.js.map +0 -0
- /package/{lib → lib-commonjs}/index.js +0 -0
- /package/{lib → lib-commonjs}/index.js.map +0 -0
- /package/{lib → lib-commonjs}/pack.js +0 -0
- /package/{lib → lib-commonjs}/pack.js.map +0 -0
- /package/{lib → lib-commonjs}/packWorker.js +0 -0
- /package/{lib → lib-commonjs}/packWorker.js.map +0 -0
- /package/{lib → lib-commonjs}/packWorkerAsync.js +0 -0
- /package/{lib → lib-commonjs}/packWorkerAsync.js.map +0 -0
- /package/{lib → lib-commonjs}/perf.js +0 -0
- /package/{lib → lib-commonjs}/perf.js.map +0 -0
- /package/{lib → lib-commonjs}/start.js +0 -0
- /package/{lib → lib-commonjs}/start.js.map +0 -0
- /package/{lib → lib-commonjs}/unpack.js +0 -0
- /package/{lib → lib-commonjs}/unpack.js.map +0 -0
- /package/{lib → lib-commonjs}/unpackWorker.js +0 -0
- /package/{lib → lib-commonjs}/unpackWorker.js.map +0 -0
- /package/{lib → lib-commonjs}/unpackWorkerAsync.js +0 -0
- /package/{lib → lib-commonjs}/unpackWorkerAsync.js.map +0 -0
- /package/{lib → lib-commonjs}/zipSyncUtils.js +0 -0
- /package/{lib → lib-commonjs}/zipSyncUtils.js.map +0 -0
- /package/{lib → lib-commonjs}/zipUtils.js +0 -0
- /package/{lib → lib-commonjs}/zipUtils.js.map +0 -0
- /package/{lib → lib-dts}/cli/ZipSyncCommandLineParser.d.ts +0 -0
- /package/{lib → lib-dts}/cli/ZipSyncCommandLineParser.d.ts.map +0 -0
- /package/{lib → lib-dts}/compress.d.ts +0 -0
- /package/{lib → lib-dts}/compress.d.ts.map +0 -0
- /package/{lib → lib-dts}/crc32.d.ts +0 -0
- /package/{lib → lib-dts}/crc32.d.ts.map +0 -0
- /package/{lib → lib-dts}/fs.d.ts +0 -0
- /package/{lib → lib-dts}/fs.d.ts.map +0 -0
- /package/{lib → lib-dts}/hash.d.ts +0 -0
- /package/{lib → lib-dts}/hash.d.ts.map +0 -0
- /package/{lib → lib-dts}/index.d.ts +0 -0
- /package/{lib → lib-dts}/index.d.ts.map +0 -0
- /package/{lib → lib-dts}/pack.d.ts +0 -0
- /package/{lib → lib-dts}/pack.d.ts.map +0 -0
- /package/{lib → lib-dts}/packWorker.d.ts +0 -0
- /package/{lib → lib-dts}/packWorker.d.ts.map +0 -0
- /package/{lib → lib-dts}/packWorkerAsync.d.ts +0 -0
- /package/{lib → lib-dts}/packWorkerAsync.d.ts.map +0 -0
- /package/{lib → lib-dts}/perf.d.ts +0 -0
- /package/{lib → lib-dts}/perf.d.ts.map +0 -0
- /package/{lib → lib-dts}/start.d.ts +0 -0
- /package/{lib → lib-dts}/start.d.ts.map +0 -0
- /package/{lib → lib-dts}/unpack.d.ts +0 -0
- /package/{lib → lib-dts}/unpack.d.ts.map +0 -0
- /package/{lib → lib-dts}/unpackWorker.d.ts +0 -0
- /package/{lib → lib-dts}/unpackWorker.d.ts.map +0 -0
- /package/{lib → lib-dts}/unpackWorkerAsync.d.ts +0 -0
- /package/{lib → lib-dts}/unpackWorkerAsync.d.ts.map +0 -0
- /package/{lib → lib-dts}/zipSyncUtils.d.ts +0 -0
- /package/{lib → lib-dts}/zipSyncUtils.d.ts.map +0 -0
- /package/{lib → lib-dts}/zipUtils.d.ts +0 -0
- /package/{lib → lib-dts}/zipUtils.d.ts.map +0 -0
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
|
|
2
|
+
// See LICENSE in the project root for license information.
|
|
3
|
+
/**
|
|
4
|
+
* Low-level ZIP structure helpers used by the zipsync pack/unpack pipeline.
|
|
5
|
+
*
|
|
6
|
+
* Spec reference: https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Local file header signature PK\x03\x04
|
|
10
|
+
*/
|
|
11
|
+
const LOCAL_FILE_HEADER_SIGNATURE = 0x04034b50; // PK\x03\x04
|
|
12
|
+
/**
|
|
13
|
+
* Central directory file header signature PK\x01\x02
|
|
14
|
+
*/
|
|
15
|
+
const CENTRAL_DIR_HEADER_SIGNATURE = 0x02014b50; // PK\x01\x02
|
|
16
|
+
/**
|
|
17
|
+
* End of central directory signature PK\x05\x06
|
|
18
|
+
*/
|
|
19
|
+
const END_OF_CENTRAL_DIR_SIGNATURE = 0x06054b50; // PK\x05\x06
|
|
20
|
+
/**
|
|
21
|
+
* Data descriptor signature PK\x07\x08
|
|
22
|
+
*/
|
|
23
|
+
const DATA_DESCRIPTOR_SIGNATURE = 0x08074b50; // PK\x07\x08
|
|
24
|
+
export const STORE_COMPRESSION = 0;
|
|
25
|
+
export const DEFLATE_COMPRESSION = 8;
|
|
26
|
+
export const ZSTD_COMPRESSION = 93;
|
|
27
|
+
function writeUInt32LE(buffer, value, offset) {
|
|
28
|
+
buffer.writeUInt32LE(value, offset);
|
|
29
|
+
}
|
|
30
|
+
function writeUInt16LE(buffer, value, offset) {
|
|
31
|
+
buffer.writeUInt16LE(value, offset);
|
|
32
|
+
}
|
|
33
|
+
function readUInt32LE(buffer, offset) {
|
|
34
|
+
return buffer.readUInt32LE(offset);
|
|
35
|
+
}
|
|
36
|
+
function readUInt16LE(buffer, offset) {
|
|
37
|
+
return buffer.readUInt16LE(offset);
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Convert a JS Date into packed DOS time/date fields used by classic ZIP.
|
|
41
|
+
* Seconds are stored /2 (range 0-29 => 0-58s). Years are offset from 1980.
|
|
42
|
+
*/
|
|
43
|
+
export function dosDateTime(date) {
|
|
44
|
+
/* eslint-disable no-bitwise */
|
|
45
|
+
const time = ((date.getHours() & 0x1f) << 11) | ((date.getMinutes() & 0x3f) << 5) | ((date.getSeconds() / 2) & 0x1f);
|
|
46
|
+
const dateVal = (((date.getFullYear() - 1980) & 0x7f) << 9) |
|
|
47
|
+
(((date.getMonth() + 1) & 0xf) << 5) |
|
|
48
|
+
(date.getDate() & 0x1f);
|
|
49
|
+
/* eslint-enable no-bitwise */
|
|
50
|
+
return { time, date: dateVal };
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Reusable scratch buffer for the fixed-length local file header (30 bytes).
|
|
54
|
+
* Using a single Buffer avoids per-file allocations; callers must copy/use synchronously.
|
|
55
|
+
*/
|
|
56
|
+
const localFileHeaderBuffer = Buffer.allocUnsafe(30);
|
|
57
|
+
/**
|
|
58
|
+
* Write the fixed portion of a local file header for an entry (with data descriptor flag set) and
|
|
59
|
+
* return the header buffer plus the variable-length filename buffer.
|
|
60
|
+
*
|
|
61
|
+
* Layout (little-endian):
|
|
62
|
+
* signature(4) versionNeeded(2) flags(2) method(2) modTime(2) modDate(2)
|
|
63
|
+
* crc32(4) compSize(4) uncompSize(4) nameLen(2) extraLen(2)
|
|
64
|
+
*
|
|
65
|
+
* Because we set bit 3 of the general purpose flag, crc32/compSize/uncompSize are zero here and the
|
|
66
|
+
* actual values appear later in a trailing data descriptor record. This enables streaming without
|
|
67
|
+
* buffering entire file contents beforehand.
|
|
68
|
+
*/
|
|
69
|
+
export function writeLocalFileHeader(entry) {
|
|
70
|
+
const filenameBuffer = Buffer.from(entry.filename, 'utf8');
|
|
71
|
+
const { time, date } = entry.dosDateTime;
|
|
72
|
+
let offset = 0;
|
|
73
|
+
writeUInt32LE(localFileHeaderBuffer, LOCAL_FILE_HEADER_SIGNATURE, offset);
|
|
74
|
+
offset += 4;
|
|
75
|
+
writeUInt16LE(localFileHeaderBuffer, 20, offset); // version needed
|
|
76
|
+
offset += 2;
|
|
77
|
+
// General purpose bit flag: set bit 3 (0x0008) to indicate presence of data descriptor
|
|
78
|
+
// Per APPNOTE: when bit 3 is set, CRC-32 and sizes in local header are set to zero and
|
|
79
|
+
// the actual values are stored in the data descriptor that follows the file data.
|
|
80
|
+
writeUInt16LE(localFileHeaderBuffer, 0x0008, offset); // flags (data descriptor)
|
|
81
|
+
offset += 2;
|
|
82
|
+
writeUInt16LE(localFileHeaderBuffer, entry.compressionMethod, offset); // compression method (0=store,8=deflate)
|
|
83
|
+
offset += 2;
|
|
84
|
+
writeUInt16LE(localFileHeaderBuffer, time, offset); // last mod time
|
|
85
|
+
offset += 2;
|
|
86
|
+
writeUInt16LE(localFileHeaderBuffer, date, offset); // last mod date
|
|
87
|
+
offset += 2;
|
|
88
|
+
// With bit 3 set, these three fields MUST be zero in the local header
|
|
89
|
+
writeUInt32LE(localFileHeaderBuffer, 0, offset); // crc32 (placeholder, real value in data descriptor)
|
|
90
|
+
offset += 4;
|
|
91
|
+
writeUInt32LE(localFileHeaderBuffer, 0, offset); // compressed size (placeholder)
|
|
92
|
+
offset += 4;
|
|
93
|
+
writeUInt32LE(localFileHeaderBuffer, 0, offset); // uncompressed size (placeholder)
|
|
94
|
+
offset += 4;
|
|
95
|
+
writeUInt16LE(localFileHeaderBuffer, filenameBuffer.length, offset); // filename length
|
|
96
|
+
offset += 2;
|
|
97
|
+
writeUInt16LE(localFileHeaderBuffer, 0, offset); // extra field length
|
|
98
|
+
offset += 2;
|
|
99
|
+
return [localFileHeaderBuffer, filenameBuffer];
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Reusable scratch buffer for central directory entries (fixed-length 46 bytes before filename)
|
|
103
|
+
*/
|
|
104
|
+
const centralDirHeaderBuffer = Buffer.allocUnsafe(46);
|
|
105
|
+
/**
|
|
106
|
+
* Write a central directory header referencing an already written local file entry.
|
|
107
|
+
* Central directory consolidates the final CRC + sizes (always present here) and provides a table
|
|
108
|
+
* for fast enumeration without scanning the archive sequentially.
|
|
109
|
+
*/
|
|
110
|
+
export function writeCentralDirectoryHeader(entry) {
|
|
111
|
+
const filenameBuffer = Buffer.from(entry.filename, 'utf8');
|
|
112
|
+
const now = new Date();
|
|
113
|
+
const { time, date } = dosDateTime(now);
|
|
114
|
+
let offset = 0;
|
|
115
|
+
writeUInt32LE(centralDirHeaderBuffer, CENTRAL_DIR_HEADER_SIGNATURE, offset);
|
|
116
|
+
offset += 4;
|
|
117
|
+
writeUInt16LE(centralDirHeaderBuffer, 20, offset); // version made by
|
|
118
|
+
offset += 2;
|
|
119
|
+
writeUInt16LE(centralDirHeaderBuffer, 20, offset); // version needed
|
|
120
|
+
offset += 2;
|
|
121
|
+
// Mirror flags used in local header (bit 3 set to indicate data descriptor was used)
|
|
122
|
+
writeUInt16LE(centralDirHeaderBuffer, 0x0008, offset); // flags
|
|
123
|
+
offset += 2;
|
|
124
|
+
writeUInt16LE(centralDirHeaderBuffer, entry.compressionMethod, offset); // compression method
|
|
125
|
+
offset += 2;
|
|
126
|
+
writeUInt16LE(centralDirHeaderBuffer, time, offset); // last mod time
|
|
127
|
+
offset += 2;
|
|
128
|
+
writeUInt16LE(centralDirHeaderBuffer, date, offset); // last mod date
|
|
129
|
+
offset += 2;
|
|
130
|
+
writeUInt32LE(centralDirHeaderBuffer, entry.crc32, offset); // crc32
|
|
131
|
+
offset += 4;
|
|
132
|
+
writeUInt32LE(centralDirHeaderBuffer, entry.compressedSize, offset); // compressed size
|
|
133
|
+
offset += 4;
|
|
134
|
+
writeUInt32LE(centralDirHeaderBuffer, entry.size, offset); // uncompressed size
|
|
135
|
+
offset += 4;
|
|
136
|
+
writeUInt16LE(centralDirHeaderBuffer, filenameBuffer.length, offset); // filename length
|
|
137
|
+
offset += 2;
|
|
138
|
+
writeUInt16LE(centralDirHeaderBuffer, 0, offset); // extra field length
|
|
139
|
+
offset += 2;
|
|
140
|
+
writeUInt16LE(centralDirHeaderBuffer, 0, offset); // comment length
|
|
141
|
+
offset += 2;
|
|
142
|
+
writeUInt16LE(centralDirHeaderBuffer, 0, offset); // disk number start
|
|
143
|
+
offset += 2;
|
|
144
|
+
writeUInt16LE(centralDirHeaderBuffer, 0, offset); // internal file attributes
|
|
145
|
+
offset += 2;
|
|
146
|
+
writeUInt32LE(centralDirHeaderBuffer, 0, offset); // external file attributes
|
|
147
|
+
offset += 4;
|
|
148
|
+
writeUInt32LE(centralDirHeaderBuffer, entry.localHeaderOffset, offset); // local header offset
|
|
149
|
+
offset += 4;
|
|
150
|
+
return [centralDirHeaderBuffer, filenameBuffer];
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Data descriptor: signature(4) crc32(4) compSize(4) uncompSize(4)
|
|
154
|
+
*/
|
|
155
|
+
const dataDescriptorBuffer = Buffer.allocUnsafe(16);
|
|
156
|
+
/**
|
|
157
|
+
* Write the trailing data descriptor for an entry. Only used because we set flag bit 3 in the
|
|
158
|
+
* local file header allowing deferred CRC/size calculation.
|
|
159
|
+
*/
|
|
160
|
+
export function writeDataDescriptor(entry) {
|
|
161
|
+
let offset = 0;
|
|
162
|
+
writeUInt32LE(dataDescriptorBuffer, DATA_DESCRIPTOR_SIGNATURE, offset); // signature PK\x07\x08
|
|
163
|
+
offset += 4;
|
|
164
|
+
writeUInt32LE(dataDescriptorBuffer, entry.crc32, offset); // crc32
|
|
165
|
+
offset += 4;
|
|
166
|
+
writeUInt32LE(dataDescriptorBuffer, entry.compressedSize, offset); // compressed size
|
|
167
|
+
offset += 4;
|
|
168
|
+
writeUInt32LE(dataDescriptorBuffer, entry.size, offset); // uncompressed size
|
|
169
|
+
return dataDescriptorBuffer;
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* End of central directory (EOCD) record (22 bytes when comment length = 0)
|
|
173
|
+
*/
|
|
174
|
+
const endOfCentralDirBuffer = Buffer.allocUnsafe(22);
|
|
175
|
+
/**
|
|
176
|
+
* Write the EOCD record referencing the accumulated central directory. We omit archive comments
|
|
177
|
+
* and do not support ZIP64 (sufficient for build cache archive sizes today).
|
|
178
|
+
*/
|
|
179
|
+
export function writeEndOfCentralDirectory(centralDirOffset, centralDirSize, entryCount) {
|
|
180
|
+
let offset = 0;
|
|
181
|
+
writeUInt32LE(endOfCentralDirBuffer, END_OF_CENTRAL_DIR_SIGNATURE, offset);
|
|
182
|
+
offset += 4;
|
|
183
|
+
writeUInt16LE(endOfCentralDirBuffer, 0, offset); // disk number
|
|
184
|
+
offset += 2;
|
|
185
|
+
writeUInt16LE(endOfCentralDirBuffer, 0, offset); // central dir start disk
|
|
186
|
+
offset += 2;
|
|
187
|
+
writeUInt16LE(endOfCentralDirBuffer, entryCount, offset); // central dir records on disk
|
|
188
|
+
offset += 2;
|
|
189
|
+
writeUInt16LE(endOfCentralDirBuffer, entryCount, offset); // total central dir records
|
|
190
|
+
offset += 2;
|
|
191
|
+
writeUInt32LE(endOfCentralDirBuffer, centralDirSize, offset); // central dir size
|
|
192
|
+
offset += 4;
|
|
193
|
+
writeUInt32LE(endOfCentralDirBuffer, centralDirOffset, offset); // central dir offset
|
|
194
|
+
offset += 4;
|
|
195
|
+
writeUInt16LE(endOfCentralDirBuffer, 0, offset); // comment length
|
|
196
|
+
return endOfCentralDirBuffer;
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Parse a local file header at the provided offset. Minimal validation: signature check only.
|
|
200
|
+
* Returns header plus the offset pointing just past the variable-length name+extra field.
|
|
201
|
+
*/
|
|
202
|
+
export function parseLocalFileHeader(buffer, offset) {
|
|
203
|
+
const signature = readUInt32LE(buffer, offset);
|
|
204
|
+
if (signature !== LOCAL_FILE_HEADER_SIGNATURE) {
|
|
205
|
+
throw new Error(`Unexpected local file header signature at offset ${offset.toString(16)}: ${signature.toString(16)}`);
|
|
206
|
+
}
|
|
207
|
+
const header = {
|
|
208
|
+
signature,
|
|
209
|
+
versionNeeded: readUInt16LE(buffer, offset + 4),
|
|
210
|
+
flags: readUInt16LE(buffer, offset + 6),
|
|
211
|
+
compressionMethod: readUInt16LE(buffer, offset + 8),
|
|
212
|
+
lastModTime: readUInt16LE(buffer, offset + 10),
|
|
213
|
+
lastModDate: readUInt16LE(buffer, offset + 12),
|
|
214
|
+
crc32: readUInt32LE(buffer, offset + 14),
|
|
215
|
+
compressedSize: readUInt32LE(buffer, offset + 18),
|
|
216
|
+
uncompressedSize: readUInt32LE(buffer, offset + 22),
|
|
217
|
+
filenameLength: readUInt16LE(buffer, offset + 26),
|
|
218
|
+
extraFieldLength: readUInt16LE(buffer, offset + 28)
|
|
219
|
+
};
|
|
220
|
+
return {
|
|
221
|
+
header,
|
|
222
|
+
nextOffset: offset + 30 + header.filenameLength + header.extraFieldLength
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Parse a central directory header at the given offset (within a sliced central directory buffer).
|
|
227
|
+
* Returns header, filename string, and nextOffset pointing to the next structure.
|
|
228
|
+
*/
|
|
229
|
+
export function parseCentralDirectoryHeader(buffer, offset) {
|
|
230
|
+
const signature = readUInt32LE(buffer, offset);
|
|
231
|
+
if (signature !== CENTRAL_DIR_HEADER_SIGNATURE) {
|
|
232
|
+
throw new Error(`Unexpected central directory signature at offset ${offset.toString(16)}: ${signature.toString(16)}`);
|
|
233
|
+
}
|
|
234
|
+
const header = {
|
|
235
|
+
signature,
|
|
236
|
+
versionMadeBy: readUInt16LE(buffer, offset + 4),
|
|
237
|
+
versionNeeded: readUInt16LE(buffer, offset + 6),
|
|
238
|
+
flags: readUInt16LE(buffer, offset + 8),
|
|
239
|
+
compressionMethod: readUInt16LE(buffer, offset + 10),
|
|
240
|
+
lastModTime: readUInt16LE(buffer, offset + 12),
|
|
241
|
+
lastModDate: readUInt16LE(buffer, offset + 14),
|
|
242
|
+
crc32: readUInt32LE(buffer, offset + 16),
|
|
243
|
+
compressedSize: readUInt32LE(buffer, offset + 20),
|
|
244
|
+
uncompressedSize: readUInt32LE(buffer, offset + 24),
|
|
245
|
+
filenameLength: readUInt16LE(buffer, offset + 28),
|
|
246
|
+
extraFieldLength: readUInt16LE(buffer, offset + 30),
|
|
247
|
+
commentLength: readUInt16LE(buffer, offset + 32),
|
|
248
|
+
diskNumberStart: readUInt16LE(buffer, offset + 34),
|
|
249
|
+
internalFileAttributes: readUInt16LE(buffer, offset + 36),
|
|
250
|
+
externalFileAttributes: readUInt32LE(buffer, offset + 38),
|
|
251
|
+
localHeaderOffset: readUInt32LE(buffer, offset + 42)
|
|
252
|
+
};
|
|
253
|
+
offset += 46;
|
|
254
|
+
const filename = buffer.toString('utf8', offset, offset + header.filenameLength);
|
|
255
|
+
return {
|
|
256
|
+
header,
|
|
257
|
+
filename,
|
|
258
|
+
nextOffset: offset + header.filenameLength + header.extraFieldLength + header.commentLength
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* Locate the EOCD record by reverse scanning. Since we never write a comment the EOCD will be the
|
|
263
|
+
* first matching signature encountered scanning backwards from the end.
|
|
264
|
+
*/
|
|
265
|
+
export function findEndOfCentralDirectory(buffer) {
|
|
266
|
+
for (let i = buffer.length - 22; i >= 0; i--) {
|
|
267
|
+
if (readUInt32LE(buffer, i) === END_OF_CENTRAL_DIR_SIGNATURE) {
|
|
268
|
+
return {
|
|
269
|
+
signature: readUInt32LE(buffer, i),
|
|
270
|
+
diskNumber: readUInt16LE(buffer, i + 4),
|
|
271
|
+
centralDirStartDisk: readUInt16LE(buffer, i + 6),
|
|
272
|
+
centralDirRecordsOnDisk: readUInt16LE(buffer, i + 8),
|
|
273
|
+
totalCentralDirRecords: readUInt16LE(buffer, i + 10),
|
|
274
|
+
centralDirSize: readUInt32LE(buffer, i + 12),
|
|
275
|
+
centralDirOffset: readUInt32LE(buffer, i + 16),
|
|
276
|
+
commentLength: readUInt16LE(buffer, i + 20)
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
throw new Error('End of central directory not found');
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* Slice out the (possibly compressed) file data bytes for a central directory entry.
|
|
284
|
+
* Caller will decompress if needed based on entry.header.compressionMethod.
|
|
285
|
+
*/
|
|
286
|
+
export function getFileFromZip(zipBuffer, entry) {
|
|
287
|
+
const { header: localFileHeader } = parseLocalFileHeader(zipBuffer, entry.header.localHeaderOffset);
|
|
288
|
+
const localDataOffset = entry.header.localHeaderOffset + 30 + localFileHeader.filenameLength + localFileHeader.extraFieldLength;
|
|
289
|
+
const fileZipBuffer = zipBuffer.subarray(localDataOffset, localDataOffset + entry.header.compressedSize);
|
|
290
|
+
return fileZipBuffer;
|
|
291
|
+
}
|
|
292
|
+
//# sourceMappingURL=zipUtils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"zipUtils.js","sourceRoot":"","sources":["../src/zipUtils.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\n/**\n * Low-level ZIP structure helpers used by the zipsync pack/unpack pipeline.\n *\n * Spec reference: https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT\n */\n\n/**\n * Local file header signature PK\\x03\\x04\n */\nconst LOCAL_FILE_HEADER_SIGNATURE: number = 0x04034b50; // PK\\x03\\x04\n/**\n * Central directory file header signature PK\\x01\\x02\n */\nconst CENTRAL_DIR_HEADER_SIGNATURE: number = 0x02014b50; // PK\\x01\\x02\n/**\n * End of central directory signature PK\\x05\\x06\n */\nconst END_OF_CENTRAL_DIR_SIGNATURE: number = 0x06054b50; // PK\\x05\\x06\n/**\n * Data descriptor signature PK\\x07\\x08\n */\nconst DATA_DESCRIPTOR_SIGNATURE: number = 0x08074b50; // PK\\x07\\x08\n\nexport const STORE_COMPRESSION: 0 = 0;\nexport const DEFLATE_COMPRESSION: 8 = 8;\nexport const ZSTD_COMPRESSION: 93 = 93;\nexport type ZipMetaCompressionMethod =\n | typeof STORE_COMPRESSION\n | typeof DEFLATE_COMPRESSION\n | typeof ZSTD_COMPRESSION;\n\nexport interface IFileEntry {\n filename: string;\n size: number;\n compressedSize: number;\n crc32: number;\n sha1Hash: string;\n localHeaderOffset: number;\n compressionMethod: ZipMetaCompressionMethod;\n dosDateTime: { time: number; date: number };\n}\n\nexport interface ILocalFileHeader {\n signature: number;\n versionNeeded: number;\n flags: number;\n compressionMethod: number;\n lastModTime: number;\n lastModDate: number;\n crc32: number;\n compressedSize: number;\n uncompressedSize: number;\n filenameLength: number;\n extraFieldLength: number;\n}\n\nexport interface ICentralDirectoryHeader {\n signature: number;\n versionMadeBy: number;\n versionNeeded: number;\n flags: number;\n compressionMethod: number;\n lastModTime: number;\n lastModDate: number;\n crc32: number;\n compressedSize: number;\n uncompressedSize: number;\n filenameLength: number;\n extraFieldLength: number;\n commentLength: number;\n diskNumberStart: number;\n internalFileAttributes: number;\n externalFileAttributes: number;\n localHeaderOffset: number;\n}\n\nexport interface IEndOfCentralDirectory {\n signature: number;\n diskNumber: number;\n centralDirStartDisk: number;\n centralDirRecordsOnDisk: number;\n totalCentralDirRecords: number;\n centralDirSize: number;\n centralDirOffset: number;\n commentLength: number;\n}\n\nfunction writeUInt32LE(buffer: Buffer, value: number, offset: number): void {\n buffer.writeUInt32LE(value, offset);\n}\n\nfunction writeUInt16LE(buffer: Buffer, value: number, offset: number): void {\n buffer.writeUInt16LE(value, offset);\n}\n\nfunction readUInt32LE(buffer: Buffer, offset: number): number {\n return buffer.readUInt32LE(offset);\n}\n\nfunction readUInt16LE(buffer: Buffer, offset: number): number {\n return buffer.readUInt16LE(offset);\n}\n\n/**\n * Convert a JS Date into packed DOS time/date fields used by classic ZIP.\n * Seconds are stored /2 (range 0-29 => 0-58s). Years are offset from 1980.\n */\nexport function dosDateTime(date: Date): { time: number; date: number } {\n /* eslint-disable no-bitwise */\n const time: number =\n ((date.getHours() & 0x1f) << 11) | ((date.getMinutes() & 0x3f) << 5) | ((date.getSeconds() / 2) & 0x1f);\n\n const dateVal: number =\n (((date.getFullYear() - 1980) & 0x7f) << 9) |\n (((date.getMonth() + 1) & 0xf) << 5) |\n (date.getDate() & 0x1f);\n /* eslint-enable no-bitwise */\n\n return { time, date: dateVal };\n}\n\n/**\n * Reusable scratch buffer for the fixed-length local file header (30 bytes).\n * Using a single Buffer avoids per-file allocations; callers must copy/use synchronously.\n */\nconst localFileHeaderBuffer: Buffer = Buffer.allocUnsafe(30);\n/**\n * Write the fixed portion of a local file header for an entry (with data descriptor flag set) and\n * return the header buffer plus the variable-length filename buffer.\n *\n * Layout (little-endian):\n * signature(4) versionNeeded(2) flags(2) method(2) modTime(2) modDate(2)\n * crc32(4) compSize(4) uncompSize(4) nameLen(2) extraLen(2)\n *\n * Because we set bit 3 of the general purpose flag, crc32/compSize/uncompSize are zero here and the\n * actual values appear later in a trailing data descriptor record. This enables streaming without\n * buffering entire file contents beforehand.\n */\nexport function writeLocalFileHeader(\n entry: IFileEntry\n): [fileHeaderWithoutVariableLengthData: Buffer, fileHeaderVariableLengthData: Buffer] {\n const filenameBuffer: Buffer = Buffer.from(entry.filename, 'utf8');\n\n const { time, date } = entry.dosDateTime;\n\n let offset: number = 0;\n writeUInt32LE(localFileHeaderBuffer, LOCAL_FILE_HEADER_SIGNATURE, offset);\n offset += 4;\n writeUInt16LE(localFileHeaderBuffer, 20, offset); // version needed\n offset += 2;\n // General purpose bit flag: set bit 3 (0x0008) to indicate presence of data descriptor\n // Per APPNOTE: when bit 3 is set, CRC-32 and sizes in local header are set to zero and\n // the actual values are stored in the data descriptor that follows the file data.\n writeUInt16LE(localFileHeaderBuffer, 0x0008, offset); // flags (data descriptor)\n offset += 2;\n writeUInt16LE(localFileHeaderBuffer, entry.compressionMethod, offset); // compression method (0=store,8=deflate)\n offset += 2;\n writeUInt16LE(localFileHeaderBuffer, time, offset); // last mod time\n offset += 2;\n writeUInt16LE(localFileHeaderBuffer, date, offset); // last mod date\n offset += 2;\n // With bit 3 set, these three fields MUST be zero in the local header\n writeUInt32LE(localFileHeaderBuffer, 0, offset); // crc32 (placeholder, real value in data descriptor)\n offset += 4;\n writeUInt32LE(localFileHeaderBuffer, 0, offset); // compressed size (placeholder)\n offset += 4;\n writeUInt32LE(localFileHeaderBuffer, 0, offset); // uncompressed size (placeholder)\n offset += 4;\n writeUInt16LE(localFileHeaderBuffer, filenameBuffer.length, offset); // filename length\n offset += 2;\n writeUInt16LE(localFileHeaderBuffer, 0, offset); // extra field length\n offset += 2;\n\n return [localFileHeaderBuffer, filenameBuffer];\n}\n\n/**\n * Reusable scratch buffer for central directory entries (fixed-length 46 bytes before filename)\n */\nconst centralDirHeaderBuffer: Buffer = Buffer.allocUnsafe(46);\n/**\n * Write a central directory header referencing an already written local file entry.\n * Central directory consolidates the final CRC + sizes (always present here) and provides a table\n * for fast enumeration without scanning the archive sequentially.\n */\nexport function writeCentralDirectoryHeader(entry: IFileEntry): Buffer[] {\n const filenameBuffer: Buffer = Buffer.from(entry.filename, 'utf8');\n\n const now: Date = new Date();\n const { time, date } = dosDateTime(now);\n\n let offset: number = 0;\n writeUInt32LE(centralDirHeaderBuffer, CENTRAL_DIR_HEADER_SIGNATURE, offset);\n offset += 4;\n writeUInt16LE(centralDirHeaderBuffer, 20, offset); // version made by\n offset += 2;\n writeUInt16LE(centralDirHeaderBuffer, 20, offset); // version needed\n offset += 2;\n // Mirror flags used in local header (bit 3 set to indicate data descriptor was used)\n writeUInt16LE(centralDirHeaderBuffer, 0x0008, offset); // flags\n offset += 2;\n writeUInt16LE(centralDirHeaderBuffer, entry.compressionMethod, offset); // compression method\n offset += 2;\n writeUInt16LE(centralDirHeaderBuffer, time, offset); // last mod time\n offset += 2;\n writeUInt16LE(centralDirHeaderBuffer, date, offset); // last mod date\n offset += 2;\n writeUInt32LE(centralDirHeaderBuffer, entry.crc32, offset); // crc32\n offset += 4;\n writeUInt32LE(centralDirHeaderBuffer, entry.compressedSize, offset); // compressed size\n offset += 4;\n writeUInt32LE(centralDirHeaderBuffer, entry.size, offset); // uncompressed size\n offset += 4;\n writeUInt16LE(centralDirHeaderBuffer, filenameBuffer.length, offset); // filename length\n offset += 2;\n writeUInt16LE(centralDirHeaderBuffer, 0, offset); // extra field length\n offset += 2;\n writeUInt16LE(centralDirHeaderBuffer, 0, offset); // comment length\n offset += 2;\n writeUInt16LE(centralDirHeaderBuffer, 0, offset); // disk number start\n offset += 2;\n writeUInt16LE(centralDirHeaderBuffer, 0, offset); // internal file attributes\n offset += 2;\n writeUInt32LE(centralDirHeaderBuffer, 0, offset); // external file attributes\n offset += 4;\n writeUInt32LE(centralDirHeaderBuffer, entry.localHeaderOffset, offset); // local header offset\n offset += 4;\n\n return [centralDirHeaderBuffer, filenameBuffer];\n}\n\n/**\n * Data descriptor: signature(4) crc32(4) compSize(4) uncompSize(4)\n */\nconst dataDescriptorBuffer: Buffer = Buffer.allocUnsafe(16);\n/**\n * Write the trailing data descriptor for an entry. Only used because we set flag bit 3 in the\n * local file header allowing deferred CRC/size calculation.\n */\nexport function writeDataDescriptor(entry: IFileEntry): Buffer {\n let offset: number = 0;\n writeUInt32LE(dataDescriptorBuffer, DATA_DESCRIPTOR_SIGNATURE, offset); // signature PK\\x07\\x08\n offset += 4;\n writeUInt32LE(dataDescriptorBuffer, entry.crc32, offset); // crc32\n offset += 4;\n writeUInt32LE(dataDescriptorBuffer, entry.compressedSize, offset); // compressed size\n offset += 4;\n writeUInt32LE(dataDescriptorBuffer, entry.size, offset); // uncompressed size\n return dataDescriptorBuffer;\n}\n\n/**\n * End of central directory (EOCD) record (22 bytes when comment length = 0)\n */\nconst endOfCentralDirBuffer: Buffer = Buffer.allocUnsafe(22);\n/**\n * Write the EOCD record referencing the accumulated central directory. We omit archive comments\n * and do not support ZIP64 (sufficient for build cache archive sizes today).\n */\nexport function writeEndOfCentralDirectory(\n centralDirOffset: number,\n centralDirSize: number,\n entryCount: number\n): Buffer {\n let offset: number = 0;\n writeUInt32LE(endOfCentralDirBuffer, END_OF_CENTRAL_DIR_SIGNATURE, offset);\n offset += 4;\n writeUInt16LE(endOfCentralDirBuffer, 0, offset); // disk number\n offset += 2;\n writeUInt16LE(endOfCentralDirBuffer, 0, offset); // central dir start disk\n offset += 2;\n writeUInt16LE(endOfCentralDirBuffer, entryCount, offset); // central dir records on disk\n offset += 2;\n writeUInt16LE(endOfCentralDirBuffer, entryCount, offset); // total central dir records\n offset += 2;\n writeUInt32LE(endOfCentralDirBuffer, centralDirSize, offset); // central dir size\n offset += 4;\n writeUInt32LE(endOfCentralDirBuffer, centralDirOffset, offset); // central dir offset\n offset += 4;\n writeUInt16LE(endOfCentralDirBuffer, 0, offset); // comment length\n\n return endOfCentralDirBuffer;\n}\n\ninterface ILocalFileHeaderParseResult {\n header: ILocalFileHeader;\n nextOffset: number;\n}\n\n/**\n * Parse a local file header at the provided offset. Minimal validation: signature check only.\n * Returns header plus the offset pointing just past the variable-length name+extra field.\n */\nexport function parseLocalFileHeader(buffer: Buffer, offset: number): ILocalFileHeaderParseResult {\n const signature: number = readUInt32LE(buffer, offset);\n if (signature !== LOCAL_FILE_HEADER_SIGNATURE) {\n throw new Error(\n `Unexpected local file header signature at offset ${offset.toString(16)}: ${signature.toString(16)}`\n );\n }\n const header: ILocalFileHeader = {\n signature,\n versionNeeded: readUInt16LE(buffer, offset + 4),\n flags: readUInt16LE(buffer, offset + 6),\n compressionMethod: readUInt16LE(buffer, offset + 8),\n lastModTime: readUInt16LE(buffer, offset + 10),\n lastModDate: readUInt16LE(buffer, offset + 12),\n crc32: readUInt32LE(buffer, offset + 14),\n compressedSize: readUInt32LE(buffer, offset + 18),\n uncompressedSize: readUInt32LE(buffer, offset + 22),\n filenameLength: readUInt16LE(buffer, offset + 26),\n extraFieldLength: readUInt16LE(buffer, offset + 28)\n };\n\n return {\n header,\n nextOffset: offset + 30 + header.filenameLength + header.extraFieldLength\n };\n}\n\nexport interface ICentralDirectoryHeaderParseResult {\n header: ICentralDirectoryHeader;\n filename: string;\n nextOffset: number;\n}\n\n/**\n * Parse a central directory header at the given offset (within a sliced central directory buffer).\n * Returns header, filename string, and nextOffset pointing to the next structure.\n */\nexport function parseCentralDirectoryHeader(\n buffer: Buffer,\n offset: number\n): ICentralDirectoryHeaderParseResult {\n const signature: number = readUInt32LE(buffer, offset);\n if (signature !== CENTRAL_DIR_HEADER_SIGNATURE) {\n throw new Error(\n `Unexpected central directory signature at offset ${offset.toString(16)}: ${signature.toString(16)}`\n );\n }\n const header: ICentralDirectoryHeader = {\n signature,\n versionMadeBy: readUInt16LE(buffer, offset + 4),\n versionNeeded: readUInt16LE(buffer, offset + 6),\n flags: readUInt16LE(buffer, offset + 8),\n compressionMethod: readUInt16LE(buffer, offset + 10),\n lastModTime: readUInt16LE(buffer, offset + 12),\n lastModDate: readUInt16LE(buffer, offset + 14),\n crc32: readUInt32LE(buffer, offset + 16),\n compressedSize: readUInt32LE(buffer, offset + 20),\n uncompressedSize: readUInt32LE(buffer, offset + 24),\n filenameLength: readUInt16LE(buffer, offset + 28),\n extraFieldLength: readUInt16LE(buffer, offset + 30),\n commentLength: readUInt16LE(buffer, offset + 32),\n diskNumberStart: readUInt16LE(buffer, offset + 34),\n internalFileAttributes: readUInt16LE(buffer, offset + 36),\n externalFileAttributes: readUInt32LE(buffer, offset + 38),\n localHeaderOffset: readUInt32LE(buffer, offset + 42)\n };\n\n offset += 46;\n\n const filename: string = buffer.toString('utf8', offset, offset + header.filenameLength);\n\n return {\n header,\n filename,\n nextOffset: offset + header.filenameLength + header.extraFieldLength + header.commentLength\n };\n}\n\n/**\n * Locate the EOCD record by reverse scanning. Since we never write a comment the EOCD will be the\n * first matching signature encountered scanning backwards from the end.\n */\nexport function findEndOfCentralDirectory(buffer: Buffer): IEndOfCentralDirectory {\n for (let i: number = buffer.length - 22; i >= 0; i--) {\n if (readUInt32LE(buffer, i) === END_OF_CENTRAL_DIR_SIGNATURE) {\n return {\n signature: readUInt32LE(buffer, i),\n diskNumber: readUInt16LE(buffer, i + 4),\n centralDirStartDisk: readUInt16LE(buffer, i + 6),\n centralDirRecordsOnDisk: readUInt16LE(buffer, i + 8),\n totalCentralDirRecords: readUInt16LE(buffer, i + 10),\n centralDirSize: readUInt32LE(buffer, i + 12),\n centralDirOffset: readUInt32LE(buffer, i + 16),\n commentLength: readUInt16LE(buffer, i + 20)\n };\n }\n }\n\n throw new Error('End of central directory not found');\n}\n\n/**\n * Slice out the (possibly compressed) file data bytes for a central directory entry.\n * Caller will decompress if needed based on entry.header.compressionMethod.\n */\nexport function getFileFromZip(zipBuffer: Buffer, entry: ICentralDirectoryHeaderParseResult): Buffer {\n const { header: localFileHeader } = parseLocalFileHeader(zipBuffer, entry.header.localHeaderOffset);\n const localDataOffset: number =\n entry.header.localHeaderOffset + 30 + localFileHeader.filenameLength + localFileHeader.extraFieldLength;\n const fileZipBuffer: Buffer = zipBuffer.subarray(\n localDataOffset,\n localDataOffset + entry.header.compressedSize\n );\n return fileZipBuffer;\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rushstack/zipsync",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "CLI tool for creating and extracting ZIP archives with intelligent filesystem synchronization",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -13,15 +13,42 @@
|
|
|
13
13
|
"license": "MIT",
|
|
14
14
|
"dependencies": {
|
|
15
15
|
"typescript": "~5.8.2",
|
|
16
|
-
"@rushstack/terminal": "0.
|
|
17
|
-
"@rushstack/
|
|
18
|
-
"@rushstack/
|
|
16
|
+
"@rushstack/terminal": "0.22.0",
|
|
17
|
+
"@rushstack/ts-command-line": "5.3.0",
|
|
18
|
+
"@rushstack/lookup-by-path": "0.9.0"
|
|
19
19
|
},
|
|
20
20
|
"devDependencies": {
|
|
21
21
|
"eslint": "~9.37.0",
|
|
22
|
-
"
|
|
23
|
-
"
|
|
22
|
+
"local-node-rig": "1.0.0",
|
|
23
|
+
"@rushstack/heft": "1.2.0"
|
|
24
24
|
},
|
|
25
|
+
"main": "./lib-commonjs/index.js",
|
|
26
|
+
"module": "./lib-esm/index.js",
|
|
27
|
+
"types": "./lib-dts/index.d.ts",
|
|
28
|
+
"exports": {
|
|
29
|
+
".": {
|
|
30
|
+
"types": "./lib-dts/index.d.ts",
|
|
31
|
+
"import": "./lib-esm/index.js",
|
|
32
|
+
"require": "./lib-commonjs/index.js"
|
|
33
|
+
},
|
|
34
|
+
"./lib/*": {
|
|
35
|
+
"types": "./lib-dts/*.d.ts",
|
|
36
|
+
"import": "./lib-esm/*.js",
|
|
37
|
+
"require": "./lib-commonjs/*.js"
|
|
38
|
+
},
|
|
39
|
+
"./package.json": "./package.json"
|
|
40
|
+
},
|
|
41
|
+
"typesVersions": {
|
|
42
|
+
"*": {
|
|
43
|
+
"lib/*": [
|
|
44
|
+
"lib-dts/*"
|
|
45
|
+
]
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
"sideEffects": [
|
|
49
|
+
"lib-commonjs/start.js",
|
|
50
|
+
"lib-esm/start.js"
|
|
51
|
+
],
|
|
25
52
|
"scripts": {
|
|
26
53
|
"start": "node lib/start",
|
|
27
54
|
"build": "heft build --clean",
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
/package/{lib → lib-dts}/fs.d.ts
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|