Download src/lib/zip.ts from noodcon/PI: direct link, hf CLI and curl.
- Browser
- Download file 2.69 kB
-
https://huggingface.co/spaces/noodcon/PI/resolve/main/src/lib/zip.ts
- Command line
-
hf download hf://spaces/noodcon/PI/src/lib/zip.ts
-
curl -L -o zip.ts https://huggingface.co/spaces/noodcon/PI/resolve/main/src/lib/zip.ts
2.69 kB
| // Ghi file ZIP không nén (đủ để xuất workspace) — không cần thư viện ngoài. | |
| const CRC_TABLE = (() => { | |
| const t = new Uint32Array(256); | |
| for (let n = 0; n < 256; n++) { | |
| let c = n; | |
| for (let k = 0; k < 8; k++) c = c & 1 ? 0xedb88320 ^ (c >>> 1) : c >>> 1; | |
| t[n] = c >>> 0; | |
| } | |
| return t; | |
| })(); | |
| export function crc32(data: Uint8Array): number { | |
| let c = 0xffffffff; | |
| for (let i = 0; i < data.length; i++) c = CRC_TABLE[(c ^ data[i]) & 0xff] ^ (c >>> 8); | |
| return (c ^ 0xffffffff) >>> 0; | |
| } | |
| /** files: đường dẫn → nội dung văn bản. */ | |
| export function makeZip(files: Record<string, string>): Blob { | |
| const enc = new TextEncoder(); | |
| const parts: Uint8Array[] = []; | |
| const central: Uint8Array[] = []; | |
| let offset = 0; | |
| const now = new Date(); | |
| const time = (now.getHours() << 11) | (now.getMinutes() << 5) | (now.getSeconds() >> 1); | |
| const date = ((now.getFullYear() - 1980) << 9) | ((now.getMonth() + 1) << 5) | now.getDate(); | |
| for (const [path, text] of Object.entries(files)) { | |
| const name = enc.encode(path.replace(/^\/+/, '')); | |
| const data = enc.encode(text); | |
| const crc = crc32(data); | |
| const local = new Uint8Array(30 + name.length); | |
| const lv = new DataView(local.buffer); | |
| lv.setUint32(0, 0x04034b50, true); | |
| lv.setUint16(4, 20, true); | |
| lv.setUint16(6, 0x0800, true); | |
| lv.setUint16(8, 0, true); | |
| lv.setUint16(10, time, true); | |
| lv.setUint16(12, date, true); | |
| lv.setUint32(14, crc, true); | |
| lv.setUint32(18, data.length, true); | |
| lv.setUint32(22, data.length, true); | |
| lv.setUint16(26, name.length, true); | |
| local.set(name, 30); | |
| const cd = new Uint8Array(46 + name.length); | |
| const cv = new DataView(cd.buffer); | |
| cv.setUint32(0, 0x02014b50, true); | |
| cv.setUint16(4, 20, true); | |
| cv.setUint16(6, 20, true); | |
| cv.setUint16(8, 0x0800, true); | |
| cv.setUint16(10, 0, true); | |
| cv.setUint16(12, time, true); | |
| cv.setUint16(14, date, true); | |
| cv.setUint32(16, crc, true); | |
| cv.setUint32(20, data.length, true); | |
| cv.setUint32(24, data.length, true); | |
| cv.setUint16(28, name.length, true); | |
| cv.setUint32(42, offset, true); | |
| cd.set(name, 46); | |
| parts.push(local, data); | |
| central.push(cd); | |
| offset += local.length + data.length; | |
| } | |
| const cdSize = central.reduce((n, c) => n + c.length, 0); | |
| const end = new Uint8Array(22); | |
| const ev = new DataView(end.buffer); | |
| ev.setUint32(0, 0x06054b50, true); | |
| ev.setUint16(8, central.length, true); | |
| ev.setUint16(10, central.length, true); | |
| ev.setUint32(12, cdSize, true); | |
| ev.setUint32(16, offset, true); | |
| return new Blob([...parts, ...central, end] as BlobPart[], { type: 'application/zip' }); | |
| } | |