diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index c396ddd..1814a77 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -36,7 +36,9 @@ jobs: with: node-version: 22 - name: Install parser test dependencies - run: sudo apt-get update && sudo apt-get install -y dpkg-dev xz-utils zstd + # zstd/bzip2/lzma are decompressed by the vendored pure-JS libs in the + # tests; xz-utils also provides the lzma compressor for legacy fixtures. + run: sudo apt-get update && sudo apt-get install -y dpkg-dev xz-utils bzip2 - name: Run deb parser tests run: node --test test/*.test.js diff --git a/README.md b/README.md index f81eaf7..811daf6 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,8 @@ ``` 浏览器 dev.cardputer.cc - │ ① 选择 .deb → 本地解析(ar/tar/gz/xz/zstd 纯前端解包) + │ ① 选择 .deb → 本地解析(ar/tar 纯前端解包,支持 deb(5) 全部压缩: + │ gz / xz / zstd / bz2 / lzma / 无压缩,解压库全部同域 vendored) │ 展示图标 / 包名 / 版本 / .desktop / 邮箱 / 文件清单 / 安全报告 │ 并对照线上索引预检:包名归属、版本是否重复/倒退 │ ② GitHub OAuth 登录(scope: user:email,读取已验证邮箱) @@ -86,7 +87,8 @@ Cloudflare Workers(不使用 Cloudflare 的 git 集成 / 自动拉取部署) cd worker && wrangler dev # http://localhost:8787,页面 + API 同域 ``` -解析器单元测试(用系统 gzip/xz/zstd 模拟浏览器解压): +解析器单元测试(zstd/bzip2/lzma 直接用页面同款 vendored 纯 JS 库解压, +gzip 用 node:zlib,xz 用系统 xz;需要 `apt install dpkg xz-utils bzip2`): ```bash node --test test/*.test.js diff --git a/site/app.js b/site/app.js index 6621563..10a6544 100644 --- a/site/app.js +++ b/site/app.js @@ -2,27 +2,33 @@ import { parseDeb, compareDebVersions, extractEmail } from "/debparse.js"; -// xz-decompress (WASM) is vendored at /vendor/ and served same-origin, so there -// is zero runtime dependency on a third-party CDN (availability, version drift, -// supply-chain, or network reachability). It is loaded lazily and only when an -// .xz-compressed package is actually parsed: a static top-level import would -// abort the whole module (blanking the page) if the bundle's evaluation or -// export shape ever failed, whereas a dynamic import keeps any such failure -// contained to the xz code path. The bundle is a CommonJS package transformed -// to ESM, so XzReadableStream is exposed on the default export (jsDelivr's -// cjs->esm lexer cannot surface it as a named export); we accept both shapes. -const XZ_URL = "/vendor/xz-decompress.js"; -let _xzPromise = null; -function loadXz() { - if (!_xzPromise) { - _xzPromise = import(/* @vite-ignore */ XZ_URL).then( - (m) => m.XzReadableStream - || (m.default && m.default.XzReadableStream) - || (typeof m.default === "function" ? m.default : null), - ); +// All decompression libraries are vendored at /vendor/ and served same-origin, +// so there is zero runtime dependency on a third-party CDN (availability, +// version drift, supply-chain, or network reachability). Each one is loaded +// lazily and only when a package actually uses that compression: a static +// top-level import would abort the whole module (blanking the page) if a +// bundle's evaluation or export shape ever failed, whereas a dynamic import +// keeps any such failure contained to that one code path. +// xz-decompress (WASM) — .tar.xz (jsDelivr cjs->esm build: the class may +// sit on the default export instead of a named one) +// fzstd (pure JS) — .tar.zst fallback when DecompressionStream("zstd") +// is unavailable (only Chrome 133+ has it natively) +// bz2 (pure JS) — .tar.bz2 (legacy debs) +// LZMA-JS d-min (pure JS)— .tar.lzma (legacy debs, LZMA "alone" format) +const lazyImports = new Map(); +function lazyImport(url, pickExport) { + if (!lazyImports.has(url)) { + lazyImports.set(url, import(/* @vite-ignore */ url).then(pickExport)); } - return _xzPromise; + return lazyImports.get(url); } +const loadXz = () => lazyImport("/vendor/xz-decompress.js", + (m) => m.XzReadableStream + || (m.default && m.default.XzReadableStream) + || (typeof m.default === "function" ? m.default : null)); +const loadFzstd = () => lazyImport("/vendor/fzstd.js", (m) => m.decompress); +const loadBz2 = () => lazyImport("/vendor/bz2.js", (m) => m.decompress); +const loadLzma = () => lazyImport("/vendor/lzma-d.js", (m) => m.LZMA); const INDEX_URL = "https://cardputer.cc/packages/dists/stable/main/binary-arm64/Packages"; @@ -49,31 +55,50 @@ async function streamToBytes(stream) { return out; } +async function loadOrExplain(loader, what) { + let impl = null; + try { + impl = await loader(); + } catch { /* fall through to the user-facing error below */ } + if (!impl) { + throw new Error(`无法加载 ${what} 解压组件(仅用于本地预览),请刷新重试;仍可直接提交,服务器会完成校验`); + } + return impl; +} + const decompressors = { gzip: async (data) => streamToBytes( new Blob([data]).stream().pipeThrough(new DecompressionStream("gzip")), ), xz: async (data) => { - let XzReadableStream; - try { - XzReadableStream = await loadXz(); - } catch { - XzReadableStream = null; - } - if (!XzReadableStream) { - throw new Error("无法加载 xz 解压组件(仅用于本地预览),请刷新重试;仍可直接提交,服务器会完成校验"); - } + const XzReadableStream = await loadOrExplain(loadXz, "xz"); return streamToBytes(new XzReadableStream(new Blob([data]).stream())); }, zstd: async (data) => { - // Chrome 133+/Edge expose zstd in DecompressionStream; fall back with a hint. + // Chrome 133+/Edge expose zstd in DecompressionStream natively; every + // other browser falls back to the vendored pure-JS fzstd decoder. try { return await streamToBytes( new Blob([data]).stream().pipeThrough(new DecompressionStream("zstd")), ); - } catch { - throw new Error("此浏览器不支持 zstd 解压,无法本地预览。建议用 dpkg-deb -Zxz 重新打包,或换 Chrome 133+ 浏览器"); - } + } catch { /* native zstd unavailable (or stream failed) — use fzstd */ } + const fzstdDecompress = await loadOrExplain(loadFzstd, "zstd"); + return fzstdDecompress(data); + }, + bzip2: async (data) => { + const bz2Decompress = await loadOrExplain(loadBz2, "bzip2"); + return bz2Decompress(data); + }, + lzma: async (data) => { + const LZMA = await loadOrExplain(loadLzma, "lzma"); + // LZMA-JS is callback-based; the result is an array of byte values, or a + // string when the payload happens to decode as UTF-8 text. + const result = await new Promise((resolve, reject) => { + LZMA.decompress(data, (out, err) => (err ? reject(new Error(String(err))) : resolve(out))); + }); + return typeof result === "string" + ? new TextEncoder().encode(result) + : new Uint8Array(result); }, }; @@ -276,17 +301,40 @@ async function renderMine() { return; } rows.innerHTML = ""; - for (const p of mine.sort((a, b) => a.name.localeCompare(b.name))) { + for (const p of mine.sort((a, b) => a.name.localeCompare(b.name) || compareDebVersions(a.Version, b.Version))) { const tr = document.createElement("tr"); - tr.innerHTML = `
列表来自线上 APT 索引,只显示 Maintainer 邮箱属于你的包。下架会生成移除 PR。
+列表来自线上 APT 索引,只显示 Maintainer 邮箱属于你的包。可直接下载已发布的 .deb;下架会生成移除 PR。
diff --git a/site/vendor/bz2.js b/site/vendor/bz2.js new file mode 100644 index 0000000..acba07b --- /dev/null +++ b/site/vendor/bz2.js @@ -0,0 +1,356 @@ +/** + * bz2@1.0.1 (https://www.npmjs.com/package/bz2) — pure-JS bzip2 decompressor. + * Original file: https://cdn.jsdelivr.net/npm/bz2@1.0.1/index.js (MIT, SheetJS LLC). + * ESM wrapper: the original IIFE publishes onto `window.bz2` (or module.exports); + * we shadow `window` with a module-local object and re-export from it, so the + * file works as a same-origin ES module in both the page and Node tests. + */ +const window = {}; +/* ---- original bz2@1.0.1 index.js below (unmodified) ---- */ +/*! bz2 (C) 2019-present SheetJS LLC */ + +'use strict'; + +(function bz2() { +// https://www.ncbi.nlm.nih.gov/IEB/ToolBox/CPP_DOC/lxr/source/src/util/compress/bzip2/crctable.c + const crc32Table = [ + 0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005, + 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61, 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd, + 0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9, 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75, + 0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3, 0x709f7b7a, 0x745e66cd, + 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039, 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, + 0xbe2b5b58, 0xbaea46ef, 0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d, + 0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49, 0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95, + 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1, 0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, + 0x34867077, 0x30476dc0, 0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072, + 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, 0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca, + 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde, 0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02, + 0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1, 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba, + 0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b, 0xbb60adfc, 0xb6238b25, 0xb2e29692, + 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6, 0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a, + 0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e, 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2, + 0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34, 0xdc3abded, 0xd8fba05a, + 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637, 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb, + 0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f, 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53, + 0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5, 0x3f9b762c, 0x3b5a6b9b, + 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff, 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, + 0xf12f560e, 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b, + 0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3, + 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7, 0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, + 0x9b3660c6, 0x9ff77d71, 0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3, + 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, 0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c, + 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8, 0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24, + 0x119b4be9, 0x155a565e, 0x18197087, 0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec, + 0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d, 0x2056cd3a, 0x2d15ebe3, 0x29d4f654, + 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0, 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c, + 0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18, 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4, + 0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662, 0x933eb0bb, 0x97ffad0c, + 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668, 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4, + ]; + + // generated from 1 << i, except for 32 + const masks = [ + 0x00000000, 0x00000001, 0x00000003, 0x00000007, + 0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f, + 0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff, + 0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff, + 0x0000ffff, 0x0001ffff, 0x0003ffff, 0x0007ffff, + 0x000fffff, 0x001fffff, 0x003fffff, 0x007fffff, + 0x00ffffff, 0x01ffffff, 0x03ffffff, 0x07ffffff, + 0x0fffffff, 0x1fffffff, 0x3fffffff, -0x80000000, + ]; + + function createOrderedHuffmanTable(lengths) { + const z = []; + for (let i = 0; i < lengths.length; i += 1) { + z.push([i, lengths[i]]); + } + z.push([lengths.length, -1]); + const table = []; + let start = z[0][0]; + let bits = z[0][1]; + for (let i = 0; i < z.length; i += 1) { + const finish = z[i][0]; + const endbits = z[i][1]; + if (bits) { + for (let code = start; code < finish; code += 1) { + table.push({ code, bits, symbol: undefined }); + } + } + start = finish; + bits = endbits; + if (endbits === -1) { + break; + } + } + table.sort((a, b) => ((a.bits - b.bits) || (a.code - b.code))); + let tempBits = 0; + let symbol = -1; + const fastAccess = []; + let current; + for (let i = 0; i < table.length; i += 1) { + const t = table[i]; + symbol += 1; + if (t.bits !== tempBits) { + symbol <<= t.bits - tempBits; + tempBits = t.bits; + current = fastAccess[tempBits] = {}; + } + t.symbol = symbol; + current[symbol] = t; + } + return { + table, + fastAccess, + }; + } + + function bwtReverse(src, primary) { + if (primary < 0 || primary >= src.length) { + throw RangeError('Out of bound'); + } + const unsorted = src.slice(); + src.sort((a, b) => a - b); + const start = {}; + for (let i = src.length - 1; i >= 0; i -= 1) { + start[src[i]] = i; + } + const links = []; + for (let i = 0; i < src.length; i += 1) { + links.push(start[unsorted[i]]++); // eslint-disable-line no-plusplus + } + let i; + const first = src[i = primary]; + const ret = []; + for (let j = 1; j < src.length; j += 1) { + const x = src[i = links[i]]; + if (x === undefined) { + ret.push(255); + } else { + ret.push(x); + } + } + ret.push(first); + ret.reverse(); + return ret; + } + + function decompress(bytes, checkCRC = false) { + let index = 0; + let bitfield = 0; + let bits = 0; + const read = (n) => { + if (n >= 32) { + const nd = n >> 1; + return read(nd) * (1 << nd) + read(n - nd); + } + while (bits < n) { + bitfield = (bitfield << 8) + bytes[index]; + index += 1; + bits += 8; + } + const m = masks[n]; + const r = (bitfield >> (bits - n)) & m; + bits -= n; + bitfield &= ~(m << bits); + return r; + }; + + const magic = read(16); + if (magic !== 0x425A) { // 'BZ' + throw new Error('Invalid magic'); + } + const method = read(8); + if (method !== 0x68) { // h for huffman + throw new Error('Invalid method'); + } + + let blocksize = read(8); + if (blocksize >= 49 && blocksize <= 57) { // 1..9 + blocksize -= 48; + } else { + throw new Error('Invalid blocksize'); + } + + let out = new Uint8Array(bytes.length * 1.5); + let outIndex = 0; + let newCRC = -1; + while (true) { + const blocktype = read(48); + const crc = read(32) | 0; + if (blocktype === 0x314159265359) { + if (read(1)) { + throw new Error('do not support randomised'); + } + const pointer = read(24); + const used = []; + const usedGroups = read(16); + for (let i = 1 << 15; i > 0; i >>= 1) { + if (!(usedGroups & i)) { + for (let j = 0; j < 16; j += 1) { + used.push(false); + } + continue; // eslint-disable-line no-continue + } + const usedChars = read(16); + for (let j = 1 << 15; j > 0; j >>= 1) { + used.push(!!(usedChars & j)); + } + } + const groups = read(3); + if (groups < 2 || groups > 6) { + throw new Error('Invalid number of huffman groups'); + } + const selectorsUsed = read(15); + const selectors = []; + const mtf = Array.from({ length: groups }, (_, i) => i); + for (let i = 0; i < selectorsUsed; i += 1) { + let c = 0; + while (read(1)) { + c += 1; + if (c >= groups) { + throw new Error('MTF table out of range'); + } + } + const v = mtf[c]; + for (let j = c; j > 0; mtf[j] = mtf[--j]) { // eslint-disable-line no-plusplus + // nothing + } + selectors.push(v); + mtf[0] = v; + } + const symbolsInUse = used.reduce((a, b) => a + b, 0) + 2; + const tables = []; + for (let i = 0; i < groups; i += 1) { + let length = read(5); + const lengths = []; + for (let j = 0; j < symbolsInUse; j += 1) { + if (length < 0 || length > 20) { + throw new Error('Huffman group length outside range'); + } + while (read(1)) { + length -= (read(1) * 2) - 1; + } + lengths.push(length); + } + tables.push(createOrderedHuffmanTable(lengths)); + } + const favourites = []; + for (let i = 0; i < used.length - 1; i += 1) { + if (used[i]) { + favourites.push(i); + } + } + let decoded = 0; + let selectorPointer = 0; + let t; + let r; + let repeat = 0; + let repeatPower = 0; + const buffer = []; + while (true) { + decoded -= 1; + if (decoded <= 0) { + decoded = 50; + if (selectorPointer <= selectors.length) { + t = tables[selectors[selectorPointer]]; + selectorPointer += 1; + } + } + for (const b in t.fastAccess) { + if (!Object.prototype.hasOwnProperty.call(t.fastAccess, b)) { + continue; // eslint-disable-line no-continue + } + if (bits < b) { + bitfield = (bitfield << 8) + bytes[index]; + index += 1; + bits += 8; + } + r = t.fastAccess[b][bitfield >> (bits - b)]; + if (r) { + bitfield &= masks[bits -= b]; + r = r.code; + break; + } + } + if (r >= 0 && r <= 1) { + if (repeat === 0) { + repeatPower = 1; + } + repeat += repeatPower << r; + repeatPower <<= 1; + continue; // eslint-disable-line no-continue + } else { + const v = favourites[0]; + for (; repeat > 0; repeat -= 1) { + buffer.push(v); + } + } + if (r === symbolsInUse - 1) { + break; + } else { + const v = favourites[r - 1]; + // eslint-disable-next-line no-plusplus + for (let j = r - 1; j > 0; favourites[j] = favourites[--j]) { + // nothing + } + favourites[0] = v; + buffer.push(v); + } + } + const nt = bwtReverse(buffer, pointer); + let i = 0; + while (i < nt.length) { + const c = nt[i]; + let count = 1; + if ((i < nt.length - 4) + && nt[i + 1] === c + && nt[i + 2] === c + && nt[i + 3] === c) { + count = nt[i + 4] + 4; + i += 5; + } else { + i += 1; + } + if (outIndex + count >= out.length) { + const old = out; + out = new Uint8Array(old.length * 2); + out.set(old); + } + for (let j = 0; j < count; j += 1) { + if (checkCRC) { + newCRC = (newCRC << 8) ^ crc32Table[((newCRC >> 24) ^ c) & 0xff]; + } + out[outIndex] = c; + outIndex += 1; + } + } + if (checkCRC) { + const calculatedCRC = newCRC ^ -1; + if (calculatedCRC !== crc) { + throw new Error(`CRC mismatch: ${calculatedCRC} !== ${crc}`); + } + newCRC = -1; + } + } else if (blocktype === 0x177245385090) { + read(bits & 0x07); // pad align + break; + } else { + throw new Error('Invalid bz2 blocktype'); + } + } + return out.subarray(0, outIndex); + } + + const exports = { decompress }; + + if (typeof window !== 'undefined') { + window.bz2 = exports; // eslint-disable-line no-undef + } else { + module.exports = exports; + } +}()); + +/* ---- end original ---- */ +export const decompress = window.bz2.decompress; +export default window.bz2; diff --git a/site/vendor/fzstd.js b/site/vendor/fzstd.js new file mode 100644 index 0000000..5d3c01b --- /dev/null +++ b/site/vendor/fzstd.js @@ -0,0 +1,753 @@ +// Some numerical data is initialized as -1 even when it doesn't need initialization to help the JIT infer types +// aliases for shorter compressed code (most minifers don't do this) +var ab = ArrayBuffer, u8 = Uint8Array, u16 = Uint16Array, i16 = Int16Array, u32 = Uint32Array, i32 = Int32Array; +var slc = function (v, s, e) { + if (u8.prototype.slice) + return u8.prototype.slice.call(v, s, e); + if (s == null || s < 0) + s = 0; + if (e == null || e > v.length) + e = v.length; + var n = new u8(e - s); + n.set(v.subarray(s, e)); + return n; +}; +var fill = function (v, n, s, e) { + if (u8.prototype.fill) + return u8.prototype.fill.call(v, n, s, e); + if (s == null || s < 0) + s = 0; + if (e == null || e > v.length) + e = v.length; + for (; s < e; ++s) + v[s] = n; + return v; +}; +var cpw = function (v, t, s, e) { + if (u8.prototype.copyWithin) + return u8.prototype.copyWithin.call(v, t, s, e); + if (s == null || s < 0) + s = 0; + if (e == null || e > v.length) + e = v.length; + while (s < e) { + v[t++] = v[s++]; + } +}; +/** + * Codes for errors generated within this library + */ +export var ZstdErrorCode = { + InvalidData: 0, + WindowSizeTooLarge: 1, + InvalidBlockType: 2, + FSEAccuracyTooHigh: 3, + DistanceTooFarBack: 4, + UnexpectedEOF: 5 +}; +// error codes +var ec = [ + 'invalid zstd data', + 'window size too large (>2046MB)', + 'invalid block type', + 'FSE accuracy too high', + 'match distance too far back', + 'unexpected EOF' +]; +var err = function (ind, msg, nt) { + var e = new Error(msg || ec[ind]); + e.code = ind; + if (Error.captureStackTrace) + Error.captureStackTrace(e, err); + if (!nt) + throw e; + return e; +}; +var rb = function (d, b, n) { + var i = 0, o = 0; + for (; i < n; ++i) + o |= d[b++] << (i << 3); + return o; +}; +var b4 = function (d, b) { return (d[b] | (d[b + 1] << 8) | (d[b + 2] << 16) | (d[b + 3] << 24)) >>> 0; }; +// read Zstandard frame header +var rzfh = function (dat, w) { + var n3 = dat[0] | (dat[1] << 8) | (dat[2] << 16); + if (n3 == 0x2FB528 && dat[3] == 253) { + // Zstandard + var flg = dat[4]; + // single segment checksum dict flag frame content flag + var ss = (flg >> 5) & 1, cc = (flg >> 2) & 1, df = flg & 3, fcf = flg >> 6; + if (flg & 8) + err(0); + // byte + var bt = 6 - ss; + // dict bytes + var db = df == 3 ? 4 : df; + // dictionary id + var di = rb(dat, bt, db); + bt += db; + // frame size bytes + var fsb = fcf ? (1 << fcf) : ss; + // frame source size + var fss = rb(dat, bt, fsb) + ((fcf == 1) && 256); + // window size + var ws = fss; + if (!ss) { + // window descriptor + var wb = 1 << (10 + (dat[5] >> 3)); + ws = wb + (wb >> 3) * (dat[5] & 7); + } + if (ws > 2145386496) + err(1); + var buf = new u8((w == 1 ? (fss || ws) : w ? 0 : ws) + 12); + buf[0] = 1, buf[4] = 4, buf[8] = 8; + return { + b: bt + fsb, + y: 0, + l: 0, + d: di, + w: (w && w != 1) ? w : buf.subarray(12), + e: ws, + o: new i32(buf.buffer, 0, 3), + u: fss, + c: cc, + m: Math.min(131072, ws) + }; + } + else if (((n3 >> 4) | (dat[3] << 20)) == 0x184D2A5) { + // skippable + return b4(dat, 4) + 8; + } + err(0); +}; +// most significant bit for nonzero +var msb = function (val) { + var bits = 0; + for (; (1 << bits) <= val; ++bits) + ; + return bits - 1; +}; +// read finite state entropy +var rfse = function (dat, bt, mal) { + // table pos + var tpos = (bt << 3) + 4; + // accuracy log + var al = (dat[bt] & 15) + 5; + if (al > mal) + err(3); + // size + var sz = 1 << al; + // probabilities symbols repeat index high threshold + var probs = sz, sym = -1, re = -1, i = -1, ht = sz; + // optimization: single allocation is much faster + var buf = new ab(512 + (sz << 2)); + var freq = new i16(buf, 0, 256); + // same view as freq + var dstate = new u16(buf, 0, 256); + var nstate = new u16(buf, 512, sz); + var bb1 = 512 + (sz << 1); + var syms = new u8(buf, bb1, sz); + var nbits = new u8(buf, bb1 + sz); + while (sym < 255 && probs > 0) { + var bits = msb(probs + 1); + var cbt = tpos >> 3; + // mask + var msk = (1 << (bits + 1)) - 1; + var val = ((dat[cbt] | (dat[cbt + 1] << 8) | (dat[cbt + 2] << 16)) >> (tpos & 7)) & msk; + // mask (1 fewer bit) + var msk1fb = (1 << bits) - 1; + // max small value + var msv = msk - probs - 1; + // small value + var sval = val & msk1fb; + if (sval < msv) + tpos += bits, val = sval; + else { + tpos += bits + 1; + if (val > msk1fb) + val -= msv; + } + freq[++sym] = --val; + if (val == -1) { + probs += val; + syms[--ht] = sym; + } + else + probs -= val; + if (!val) { + do { + // repeat byte + var rbt = tpos >> 3; + re = ((dat[rbt] | (dat[rbt + 1] << 8)) >> (tpos & 7)) & 3; + tpos += 2; + sym += re; + } while (re == 3); + } + } + if (sym > 255 || probs) + err(0); + var sympos = 0; + // sym step (coprime with sz - formula from zstd source) + var sstep = (sz >> 1) + (sz >> 3) + 3; + // sym mask + var smask = sz - 1; + for (var s = 0; s <= sym; ++s) { + var sf = freq[s]; + if (sf < 1) { + dstate[s] = -sf; + continue; + } + // This is split into two loops in zstd to avoid branching, but as JS is higher-level that is unnecessary + for (i = 0; i < sf; ++i) { + syms[sympos] = s; + do { + sympos = (sympos + sstep) & smask; + } while (sympos >= ht); + } + } + // After spreading symbols, should be zero again + if (sympos) + err(0); + for (i = 0; i < sz; ++i) { + // next state + var ns = dstate[syms[i]]++; + // num bits + var nb = nbits[i] = al - msb(ns); + nstate[i] = (ns << nb) - sz; + } + return [(tpos + 7) >> 3, { + b: al, + s: syms, + n: nbits, + t: nstate + }]; +}; +// read huffman +var rhu = function (dat, bt) { + // index weight count + var i = 0, wc = -1; + // buffer header byte + var buf = new u8(292), hb = dat[bt]; + // huffman weights + var hw = buf.subarray(0, 256); + // rank count + var rc = buf.subarray(256, 268); + // rank index + var ri = new u16(buf.buffer, 268); + // NOTE: at this point bt is 1 less than expected + if (hb < 128) { + // end byte, fse decode table + var _a = rfse(dat, bt + 1, 6), ebt = _a[0], fdt = _a[1]; + bt += hb; + var epos = ebt << 3; + // last byte + var lb = dat[bt]; + if (!lb) + err(0); + // state1 state2 state1 bits state2 bits + var st1 = 0, st2 = 0, btr1 = fdt.b, btr2 = btr1; + // fse pos + // pre-increment to account for original deficit of 1 + var fpos = (++bt << 3) - 8 + msb(lb); + for (;;) { + fpos -= btr1; + if (fpos < epos) + break; + var cbt = fpos >> 3; + st1 += ((dat[cbt] | (dat[cbt + 1] << 8)) >> (fpos & 7)) & ((1 << btr1) - 1); + hw[++wc] = fdt.s[st1]; + fpos -= btr2; + if (fpos < epos) + break; + cbt = fpos >> 3; + st2 += ((dat[cbt] | (dat[cbt + 1] << 8)) >> (fpos & 7)) & ((1 << btr2) - 1); + hw[++wc] = fdt.s[st2]; + btr1 = fdt.n[st1]; + st1 = fdt.t[st1]; + btr2 = fdt.n[st2]; + st2 = fdt.t[st2]; + } + if (++wc > 255) + err(0); + } + else { + wc = hb - 127; + for (; i < wc; i += 2) { + var byte = dat[++bt]; + hw[i] = byte >> 4; + hw[i + 1] = byte & 15; + } + ++bt; + } + // weight exponential sum + var wes = 0; + for (i = 0; i < wc; ++i) { + var wt = hw[i]; + // bits must be at most 11, same as weight + if (wt > 11) + err(0); + wes += wt && (1 << (wt - 1)); + } + // max bits + var mb = msb(wes) + 1; + // table size + var ts = 1 << mb; + // remaining sum + var rem = ts - wes; + // must be power of 2 + if (rem & (rem - 1)) + err(0); + hw[wc++] = msb(rem) + 1; + for (i = 0; i < wc; ++i) { + var wt = hw[i]; + ++rc[hw[i] = wt && (mb + 1 - wt)]; + } + // huf buf + var hbuf = new u8(ts << 1); + // symbols num bits + var syms = hbuf.subarray(0, ts), nb = hbuf.subarray(ts); + ri[mb] = 0; + for (i = mb; i > 0; --i) { + var pv = ri[i]; + fill(nb, i, pv, ri[i - 1] = pv + rc[i] * (1 << (mb - i))); + } + if (ri[0] != ts) + err(0); + for (i = 0; i < wc; ++i) { + var bits = hw[i]; + if (bits) { + var code = ri[bits]; + fill(syms, i, code, ri[bits] = code + (1 << (mb - bits))); + } + } + return [bt, { + n: nb, + b: mb, + s: syms + }]; +}; +// Tables generated using this: +// https://gist.github.com/101arrowz/a979452d4355992cbf8f257cbffc9edd +// default literal length table +var dllt = /*#__PURE__*/ rfse(/*#__PURE__*/ new u8([ + 81, 16, 99, 140, 49, 198, 24, 99, 12, 33, 196, 24, 99, 102, 102, 134, 70, 146, 4 +]), 0, 6)[1]; +// default match length table +var dmlt = /*#__PURE__*/ rfse(/*#__PURE__*/ new u8([ + 33, 20, 196, 24, 99, 140, 33, 132, 16, 66, 8, 33, 132, 16, 66, 8, 33, 68, 68, 68, 68, 68, 68, 68, 68, 36, 9 +]), 0, 6)[1]; +// default offset code table +var doct = /*#__PURE__ */ rfse(/*#__PURE__*/ new u8([ + 32, 132, 16, 66, 102, 70, 68, 68, 68, 68, 36, 73, 2 +]), 0, 5)[1]; +// bits to baseline +var b2bl = function (b, s) { + var len = b.length, bl = new i32(len); + for (var i = 0; i < len; ++i) { + bl[i] = s; + s += 1 << b[i]; + } + return bl; +}; +// literal length bits +var llb = /*#__PURE__ */ new u8(( /*#__PURE__ */new i32([ + 0, 0, 0, 0, 16843009, 50528770, 134678020, 202050057, 269422093 +])).buffer, 0, 36); +// literal length baseline +var llbl = /*#__PURE__ */ b2bl(llb, 0); +// match length bits +var mlb = /*#__PURE__ */ new u8(( /*#__PURE__ */new i32([ + 0, 0, 0, 0, 0, 0, 0, 0, 16843009, 50528770, 117769220, 185207048, 252579084, 16 +])).buffer, 0, 53); +// match length baseline +var mlbl = /*#__PURE__ */ b2bl(mlb, 3); +// decode huffman stream +var dhu = function (dat, out, hu) { + var len = dat.length, ss = out.length, lb = dat[len - 1], msk = (1 << hu.b) - 1, eb = -hu.b; + if (!lb) + err(0); + var st = 0, btr = hu.b, pos = (len << 3) - 8 + msb(lb) - btr, i = -1; + for (; pos > eb && i < ss;) { + var cbt = pos >> 3; + var val = (dat[cbt] | (dat[cbt + 1] << 8) | (dat[cbt + 2] << 16)) >> (pos & 7); + st = ((st << btr) | val) & msk; + out[++i] = hu.s[st]; + pos -= (btr = hu.n[st]); + } + if (pos != eb || i + 1 != ss) + err(0); +}; +// decode huffman stream 4x +// TODO: use workers to parallelize +var dhu4 = function (dat, out, hu) { + var bt = 6; + var ss = out.length, sz1 = (ss + 3) >> 2, sz2 = sz1 << 1, sz3 = sz1 + sz2; + dhu(dat.subarray(bt, bt += dat[0] | (dat[1] << 8)), out.subarray(0, sz1), hu); + dhu(dat.subarray(bt, bt += dat[2] | (dat[3] << 8)), out.subarray(sz1, sz2), hu); + dhu(dat.subarray(bt, bt += dat[4] | (dat[5] << 8)), out.subarray(sz2, sz3), hu); + dhu(dat.subarray(bt), out.subarray(sz3), hu); +}; +// read Zstandard block +var rzb = function (dat, st, out) { + var _a; + var bt = st.b; + // byte 0 block type + var b0 = dat[bt], btype = (b0 >> 1) & 3; + st.l = b0 & 1; + var sz = (b0 >> 3) | (dat[bt + 1] << 5) | (dat[bt + 2] << 13); + // end byte for block + var ebt = (bt += 3) + sz; + if (btype == 1) { + if (bt >= dat.length) + return; + st.b = bt + 1; + if (out) { + fill(out, dat[bt], st.y, st.y += sz); + return out; + } + return fill(new u8(sz), dat[bt]); + } + if (ebt > dat.length) + return; + if (btype == 0) { + st.b = ebt; + if (out) { + out.set(dat.subarray(bt, ebt), st.y); + st.y += sz; + return out; + } + return slc(dat, bt, ebt); + } + if (btype == 2) { + // byte 3 lit btype size format + var b3 = dat[bt], lbt = b3 & 3, sf = (b3 >> 2) & 3; + // lit src size lit cmp sz 4 streams + var lss = b3 >> 4, lcs = 0, s4 = 0; + if (lbt < 2) { + if (sf & 1) + lss |= (dat[++bt] << 4) | ((sf & 2) && (dat[++bt] << 12)); + else + lss = b3 >> 3; + } + else { + s4 = sf; + if (sf < 2) + lss |= ((dat[++bt] & 63) << 4), lcs = (dat[bt] >> 6) | (dat[++bt] << 2); + else if (sf == 2) + lss |= (dat[++bt] << 4) | ((dat[++bt] & 3) << 12), lcs = (dat[bt] >> 2) | (dat[++bt] << 6); + else + lss |= (dat[++bt] << 4) | ((dat[++bt] & 63) << 12), lcs = (dat[bt] >> 6) | (dat[++bt] << 2) | (dat[++bt] << 10); + } + ++bt; + // add literals to end - can never overlap with backreferences because unused literals always appended + var buf = out ? out.subarray(st.y, st.y + st.m) : new u8(st.m); + // starting point for literals + var spl = buf.length - lss; + if (lbt == 0) + buf.set(dat.subarray(bt, bt += lss), spl); + else if (lbt == 1) + fill(buf, dat[bt++], spl); + else { + // huffman table + var hu = st.h; + if (lbt == 2) { + var hud = rhu(dat, bt); + // subtract description length + lcs += bt - (bt = hud[0]); + st.h = hu = hud[1]; + } + else if (!hu) + err(0); + (s4 ? dhu4 : dhu)(dat.subarray(bt, bt += lcs), buf.subarray(spl), hu); + } + // num sequences + var ns = dat[bt++]; + if (ns) { + if (ns == 255) + ns = (dat[bt++] | (dat[bt++] << 8)) + 0x7F00; + else if (ns > 127) + ns = ((ns - 128) << 8) | dat[bt++]; + // symbol compression modes + var scm = dat[bt++]; + if (scm & 3) + err(0); + var dts = [dmlt, doct, dllt]; + for (var i = 2; i > -1; --i) { + var md = (scm >> ((i << 1) + 2)) & 3; + if (md == 1) { + // rle buf + var rbuf = new u8([0, 0, dat[bt++]]); + dts[i] = { + s: rbuf.subarray(2, 3), + n: rbuf.subarray(0, 1), + t: new u16(rbuf.buffer, 0, 1), + b: 0 + }; + } + else if (md == 2) { + // accuracy log 8 for offsets, 9 for others + _a = rfse(dat, bt, 9 - (i & 1)), bt = _a[0], dts[i] = _a[1]; + } + else if (md == 3) { + if (!st.t) + err(0); + dts[i] = st.t[i]; + } + } + var _b = st.t = dts, mlt = _b[0], oct = _b[1], llt = _b[2]; + var lb = dat[ebt - 1]; + if (!lb) + err(0); + var spos = (ebt << 3) - 8 + msb(lb) - llt.b, cbt = spos >> 3, oubt = 0; + var lst = ((dat[cbt] | (dat[cbt + 1] << 8)) >> (spos & 7)) & ((1 << llt.b) - 1); + cbt = (spos -= oct.b) >> 3; + var ost = ((dat[cbt] | (dat[cbt + 1] << 8)) >> (spos & 7)) & ((1 << oct.b) - 1); + cbt = (spos -= mlt.b) >> 3; + var mst = ((dat[cbt] | (dat[cbt + 1] << 8)) >> (spos & 7)) & ((1 << mlt.b) - 1); + for (++ns; --ns;) { + var llc = llt.s[lst]; + var lbtr = llt.n[lst]; + var mlc = mlt.s[mst]; + var mbtr = mlt.n[mst]; + var ofc = oct.s[ost]; + var obtr = oct.n[ost]; + cbt = (spos -= ofc) >> 3; + var ofp = 1 << ofc; + var off = ofp + (((dat[cbt] | (dat[cbt + 1] << 8) | (dat[cbt + 2] << 16) | (dat[cbt + 3] << 24)) >>> (spos & 7)) & (ofp - 1)); + cbt = (spos -= mlb[mlc]) >> 3; + var ml = mlbl[mlc] + (((dat[cbt] | (dat[cbt + 1] << 8) | (dat[cbt + 2] << 16)) >> (spos & 7)) & ((1 << mlb[mlc]) - 1)); + cbt = (spos -= llb[llc]) >> 3; + var ll = llbl[llc] + (((dat[cbt] | (dat[cbt + 1] << 8) | (dat[cbt + 2] << 16)) >> (spos & 7)) & ((1 << llb[llc]) - 1)); + cbt = (spos -= lbtr) >> 3; + lst = llt.t[lst] + (((dat[cbt] | (dat[cbt + 1] << 8)) >> (spos & 7)) & ((1 << lbtr) - 1)); + cbt = (spos -= mbtr) >> 3; + mst = mlt.t[mst] + (((dat[cbt] | (dat[cbt + 1] << 8)) >> (spos & 7)) & ((1 << mbtr) - 1)); + cbt = (spos -= obtr) >> 3; + ost = oct.t[ost] + (((dat[cbt] | (dat[cbt + 1] << 8)) >> (spos & 7)) & ((1 << obtr) - 1)); + if (off > 3) { + st.o[2] = st.o[1]; + st.o[1] = st.o[0]; + st.o[0] = off -= 3; + } + else { + var idx = off - (ll != 0); + if (idx) { + off = idx == 3 ? st.o[0] - 1 : st.o[idx]; + if (idx > 1) + st.o[2] = st.o[1]; + st.o[1] = st.o[0]; + st.o[0] = off; + } + else + off = st.o[0]; + } + for (var i = 0; i < ll; ++i) { + buf[oubt + i] = buf[spl + i]; + } + oubt += ll, spl += ll; + var stin = oubt - off; + if (stin < 0) { + var len = -stin; + var bs = st.e + stin; + if (len > ml) + len = ml; + for (var i = 0; i < len; ++i) { + buf[oubt + i] = st.w[bs + i]; + } + oubt += len, ml -= len, stin = 0; + } + for (var i = 0; i < ml; ++i) { + buf[oubt + i] = buf[stin + i]; + } + oubt += ml; + } + if (oubt != spl) { + while (spl < buf.length) { + buf[oubt++] = buf[spl++]; + } + } + else + oubt = buf.length; + if (out) + st.y += oubt; + else + buf = slc(buf, 0, oubt); + } + else if (out) { + st.y += lss; + if (spl) { + for (var i = 0; i < lss; ++i) { + buf[i] = buf[spl + i]; + } + } + } + else if (spl) + buf = slc(buf, spl); + st.b = ebt; + return buf; + } + err(2); +}; +// concat +var cct = function (bufs, ol) { + if (bufs.length == 1) + return bufs[0]; + var buf = new u8(ol); + for (var i = 0, b = 0; i < bufs.length; ++i) { + var chk = bufs[i]; + buf.set(chk, b); + b += chk.length; + } + return buf; +}; +/** + * Decompresses Zstandard data + * @param dat The input data + * @param buf The output buffer. If unspecified, the function will allocate + * exactly enough memory to fit the decompressed data. If your + * data has multiple frames and you know the output size, specifying + * it will yield better performance. + * @returns The decompressed data + */ +export function decompress(dat, buf) { + var bufs = [], nb = +!buf; + var bt = 0, ol = 0; + for (; dat.length;) { + var st = rzfh(dat, nb || buf); + if (typeof st == 'object') { + if (nb) { + buf = null; + if (st.w.length == st.u) { + bufs.push(buf = st.w); + ol += st.u; + } + } + else { + bufs.push(buf); + st.e = 0; + } + for (; !st.l;) { + var blk = rzb(dat, st, buf); + if (!blk) + err(5); + if (buf) + st.e = st.y; + else { + bufs.push(blk); + ol += blk.length; + cpw(st.w, 0, blk.length); + st.w.set(blk, st.w.length - blk.length); + } + } + bt = st.b + (st.c * 4); + } + else + bt = st; + dat = dat.subarray(bt); + } + return cct(bufs, ol); +} +/** + * Decompressor for Zstandard streamed data + */ +var Decompress = /*#__PURE__*/ (function () { + /** + * Creates a Zstandard decompressor + * @param ondata The handler for stream data + */ + function Decompress(ondata) { + this.ondata = ondata; + this.c = []; + this.l = 0; + this.z = 0; + } + /** + * Pushes data to be decompressed + * @param chunk The chunk of data to push + * @param final Whether or not this is the last chunk in the stream + */ + Decompress.prototype.push = function (chunk, final) { + if (typeof this.s == 'number') { + var sub = Math.min(chunk.length, this.s); + chunk = chunk.subarray(sub); + this.s -= sub; + } + var sl = chunk.length; + var ncs = sl + this.l; + if (!this.s) { + if (final) { + if (!ncs) { + this.ondata(new u8(0), true); + return; + } + // min for frame + one block + if (ncs < 5) + err(5); + } + else if (ncs < 18) { + this.c.push(chunk); + this.l = ncs; + return; + } + if (this.l) { + this.c.push(chunk); + chunk = cct(this.c, ncs); + this.c = []; + this.l = 0; + } + if (typeof (this.s = rzfh(chunk)) == 'number') + return this.push(chunk, final); + } + if (typeof this.s != 'number') { + if (ncs < (this.z || 3)) { + if (final) + err(5); + this.c.push(chunk); + this.l = ncs; + return; + } + if (this.l) { + this.c.push(chunk); + chunk = cct(this.c, ncs); + this.c = []; + this.l = 0; + } + if (!this.z && ncs < (this.z = (chunk[this.s.b] & 2) ? 4 : 3 + ((chunk[this.s.b] >> 3) | (chunk[this.s.b + 1] << 5) | (chunk[this.s.b + 2] << 13)))) { + if (final) + err(5); + this.c.push(chunk); + this.l = ncs; + return; + } + else + this.z = 0; + for (;;) { + var blk = rzb(chunk, this.s); + if (!blk) { + if (final) + err(5); + var adc = chunk.subarray(this.s.b); + this.s.b = 0; + this.c.push(adc), this.l += adc.length; + return; + } + else { + this.ondata(blk, false); + cpw(this.s.w, 0, blk.length); + this.s.w.set(blk, this.s.w.length - blk.length); + } + if (this.s.l) { + var rest = chunk.subarray(this.s.b); + this.s = this.s.c * 4; + this.push(rest, final); + return; + } + } + } + else if (final) + err(5); + }; + return Decompress; +}()); +export { Decompress }; diff --git a/site/vendor/lzma-d.js b/site/vendor/lzma-d.js new file mode 100644 index 0000000..d148620 --- /dev/null +++ b/site/vendor/lzma-d.js @@ -0,0 +1,16 @@ +/** + * LZMA-JS 2.3.2 decompression-only build (https://www.npmjs.com/package/lzma). + * Original file: lzma/src/lzma-d-min.js (MIT, Nathan Rugg). Decodes the LZMA + * alone format (.lzma) used by legacy deb data.tar.lzma members. + * ESM wrapper: the original script assigns `this.LZMA`; we run it with a + * module-local `this` and re-export. LZMA.decompress(bytes, cb) is async: + * cb(result, err) where result is an array of bytes (or a string). + */ +const scope = {}; +(function () { +/* ---- original lzma/src/lzma-d-min.js below (unmodified) ---- */ +var e=function(){"use strict";function r(e,r){postMessage({action:nr,cbn:r,result:e})}function o(e){var r=[];return r[e-1]=void 0,r}function n(e,r){return i(e[0]+r[0],e[1]+r[1])}function t(e,r){var o,n;return e[0]==r[0]&&e[1]==r[1]?0:(o=0>e[1],n=0>r[1],o&&!n?-1:!o&&n?1:d(e,r)[1]<0?-1:1)}function i(e,r){var o,n;for(r%=0x10000000000000000,e%=0x10000000000000000,o=r%ir,n=Math.floor(e/ir)*ir,r=r-o+n,e=e-n+o;0>e;)e+=ir,r-=ir;for(;e>4294967295;)e-=ir,r+=ir;for(r%=0x10000000000000000;r>0x7fffffff00000000;)r-=0x10000000000000000;for(;-0x8000000000000000>r;)r+=0x10000000000000000;return[e,r]}function u(e){return e>=0?[e,0]:[e+ir,-ir]}function s(e){return e[0]>=2147483648?~~Math.max(Math.min(e[0]-ir,2147483647),-2147483648):~~Math.max(Math.min(e[0],2147483647),-2147483648)}function d(e,r){return i(e[0]-r[0],e[1]-r[1])}function c(e,r){return e.ab=r,e.cb=0,e.O=r.length,e}function m(e){return e.cb>=e.O?-1:255&e.ab[e.cb++]}function a(e){return e.ab=o(32),e.O=0,e}function _(e){var r=e.ab;return r.length=e.O,r}function f(e,r,o,n){p(r,o,e.ab,e.O,n),e.O+=n}function p(e,r,o,n,t){for(var i=0;t>i;++i)o[n+i]=e[r+i]}function D(e,r,o){var n,t,i,s,d="",c=[];for(t=0;5>t;++t){if(i=m(r),-1==i)throw Error("truncated input");c[t]=i<<24>>24}if(n=N({}),!z(n,c))throw Error("corrupted input");for(t=0;64>t;t+=8){if(i=m(r),-1==i)throw Error("truncated input");i=i.toString(16),1==i.length&&(i="0"+i),d=i+""+d}/^0+$|^f+$/i.test(d)?e.N=ur:(s=parseInt(d,16),e.N=s>4294967295?ur:u(s)),e.Q=B(n,r,o,e.N)}function l(e,r){return e.S=a({}),D(e,c({},r),e.S),e}function g(e,r,o){var n=e.D-r-1;for(0>n&&(n+=e.c);0!=o;--o)n>=e.c&&(n=0),e.x[e.D++]=e.x[n++],e.D>=e.c&&w(e)}function v(e,r){(null==e.x||e.c!=r)&&(e.x=o(r)),e.c=r,e.D=0,e.w=0}function w(e){var r=e.D-e.w;r&&(f(e.V,e.x,e.w,r),e.D>=e.c&&(e.D=0),e.w=e.D)}function R(e,r){var o=e.D-r-1;return 0>o&&(o+=e.c),e.x[o]}function h(e,r){e.x[e.D++]=r,e.D>=e.c&&w(e)}function P(e){w(e),e.V=null}function C(e){return e-=2,4>e?e:3}function S(e){return 4>e?0:10>e?e-3:e-6}function M(e,r){return e.h=r,e.bb=null,e.X=1,e}function L(e){if(!e.X)throw Error("bad state");if(e.bb)throw Error("No encoding");return y(e),e.X}function y(e){var r=I(e.h);if(-1==r)throw Error("corrupted input");e.$=ur,e.Z=e.h.d,(r||t(e.h.U,sr)>=0&&t(e.h.d,e.h.U)>=0)&&(w(e.h.b),P(e.h.b),e.h.a.K=null,e.X=0)}function B(e,r,o,n){return e.a.K=r,P(e.b),e.b.V=o,b(e),e.f=0,e.l=0,e.T=0,e.R=0,e._=0,e.U=n,e.d=sr,e.I=0,M({},e)}function I(e){var r,o,i,d,c,m;if(m=s(e.d)&e.P,Q(e.a,e.q,(e.f<<4)+m)){if(Q(e.a,e.E,e.f))i=0,Q(e.a,e.s,e.f)?(Q(e.a,e.u,e.f)?(Q(e.a,e.r,e.f)?(o=e._,e._=e.R):o=e.R,e.R=e.T):o=e.T,e.T=e.l,e.l=o):Q(e.a,e.n,(e.f<<4)+m)||(e.f=7>e.f?9:11,i=1),i||(i=x(e.o,e.a,m)+2,e.f=7>e.f?8:11);else if(e._=e.R,e.R=e.T,e.T=e.l,i=2+x(e.C,e.a,m),e.f=7>e.f?7:10,c=q(e.j[C(i)],e.a),c>=4){if(d=(c>>1)-1,e.l=(2|1&c)<