Spaces:
Running
Running
Download lib/zip.js from CyberMax-tools/clipwhit: direct link, hf CLI and curl.
- Browser
- Download file 2.45 kB
-
https://huggingface.co/spaces/CyberMax-tools/clipwhit/resolve/main/lib/zip.js
- Command line
-
hf download hf://spaces/CyberMax-tools/clipwhit/lib/zip.js
-
curl -L -o zip.js https://huggingface.co/spaces/CyberMax-tools/clipwhit/resolve/main/lib/zip.js
2.45 kB
| // Minimal ZIP writer (stored, no compression: MP4s don't compress). Returns a Blob. © 2026 CyberMax. All rights reserved. | |
| const 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(bytes) { | |
| let c = 0xFFFFFFFF; | |
| for (let i = 0; i < bytes.length; i++) c = TABLE[(c ^ bytes[i]) & 0xFF] ^ (c >>> 8); | |
| return (c ^ 0xFFFFFFFF) >>> 0; | |
| } | |
| /** files: [{name, data: Uint8Array | string}] -> Uint8Array parts of a .zip (Blob-ready). */ | |
| export function zipParts(files, date = new Date()) { | |
| const enc = new TextEncoder(); | |
| const dosTime = (date.getHours() << 11) | (date.getMinutes() << 5) | (date.getSeconds() >> 1); | |
| const dosDate = ((date.getFullYear() - 1980) << 9) | ((date.getMonth() + 1) << 5) | date.getDate(); | |
| const parts = [], central = []; | |
| let offset = 0; | |
| for (const f of files) { | |
| const name = enc.encode(f.name); | |
| const data = typeof f.data === 'string' ? enc.encode(f.data) : f.data; | |
| const crc = crc32(data); | |
| const h = new DataView(new ArrayBuffer(30)); | |
| h.setUint32(0, 0x04034b50, true); h.setUint16(4, 20, true); h.setUint16(6, 0x0800, true); h.setUint16(8, 0, true); | |
| h.setUint16(10, dosTime, true); h.setUint16(12, dosDate, true); h.setUint32(14, crc, true); | |
| h.setUint32(18, data.length, true); h.setUint32(22, data.length, true); h.setUint16(26, name.length, true); h.setUint16(28, 0, true); | |
| parts.push(new Uint8Array(h.buffer), name, data); | |
| const c = new DataView(new ArrayBuffer(46)); | |
| c.setUint32(0, 0x02014b50, true); c.setUint16(4, 20, true); c.setUint16(6, 20, true); c.setUint16(8, 0x0800, true); c.setUint16(10, 0, true); | |
| c.setUint16(12, dosTime, true); c.setUint16(14, dosDate, true); c.setUint32(16, crc, true); c.setUint32(20, data.length, true); | |
| c.setUint32(24, data.length, true); c.setUint16(28, name.length, true); c.setUint32(42, offset, true); | |
| central.push(new Uint8Array(c.buffer), name); | |
| offset += 30 + name.length + data.length; | |
| } | |
| const size = central.reduce((a, b) => a + b.length, 0); | |
| const end = new DataView(new ArrayBuffer(22)); | |
| end.setUint32(0, 0x06054b50, true); end.setUint16(8, files.length, true); end.setUint16(10, files.length, true); | |
| end.setUint32(12, size, true); end.setUint32(16, offset, true); | |
| return [...parts, ...central, new Uint8Array(end.buffer)]; | |
| } | |