diff --git a/README.md b/README.md index da71c2c..70fc8d4 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ Please report any issue you have with those (only for mainstream browsers) Also, use this if you plan to use b4k's archive. - [Install 4chanX (recommended)](https://www.4chan-x.net/builds/4chan-X.user.js) -- Install the correct WebExtension for your Browser ([Firefox](https://git.coom.tech/fuckjannies/lolipiss/raw/branch/%E4%B8%AD%E5%87%BA%E3%81%97/pngextraembedder-0.279.xpi) or [Chrome-based](https://chrome.google.com/webstore/detail/pngextraembedder/bfhpobiikighljcapcfmfganodihbicj)) +- Install the correct WebExtension for your Browser ([Firefox](https://git.coom.tech/fuckjannies/lolipiss/raw/branch/%E4%B8%AD%E5%87%BA%E3%81%97/pngextraembedder-0.281.xpi) or [Chrome-based](https://chrome.google.com/webstore/detail/pngextraembedder/bfhpobiikighljcapcfmfganodihbicj)) For FF users, the extension is signed so you can just drag and drop it on your about:addons tab. diff --git a/chrome/dist/main.js b/chrome/dist/main.js index eda17e7..74b8486 100644 --- a/chrome/dist/main.js +++ b/chrome/dist/main.js @@ -73,7 +73,7 @@ var define_BUILD_VERSION_default; var init_define_BUILD_VERSION = __esm({ ""() { - define_BUILD_VERSION_default = [0, 280]; + define_BUILD_VERSION_default = [0, 281]; } }); @@ -12109,7 +12109,7 @@ var dctSqrt1d2 = 2896; function constructor() { } - function buildHuffmanTable(codeLengths, values) { + function buildHuffmanTable2(codeLengths, values) { var k = 0, code = [], i, j, length = 16; while (length > 0 && !codeLengths[length - 1]) length--; @@ -12745,7 +12745,7 @@ for (j = 0; j < codeLengthSum; j++, offset++) huffmanValues[j] = data[offset]; i += 17 + codeLengthSum; - (huffmanTableSpec >> 4 === 0 ? huffmanTablesDC : huffmanTablesAC)[huffmanTableSpec & 15] = buildHuffmanTable(codeLengths, huffmanValues); + (huffmanTableSpec >> 4 === 0 ? huffmanTablesDC : huffmanTablesAC)[huffmanTableSpec & 15] = buildHuffmanTable2(codeLengths, huffmanValues); } break; case 65501: @@ -13987,7 +13987,7 @@ var initial_settings = localLoad("settingsv2", { loop: true, dh: false, - pmeth: 4, + pmeth: 5, xpv: false, xpi: false, hyd: false, @@ -14132,8 +14132,10 @@ var import_crc_32 = __toESM(require_crc32(), 1); var import_buffer = __toESM(require_buffer(), 1); var PNGDecoder = class { - constructor(reader) { + constructor(reader, strict = true) { this.reader = reader; + this.strict = strict; + this.stopped = false; this.req = 8; this.ptr = 8; this.repr = import_buffer.Buffer.from([]); @@ -14142,7 +14144,10 @@ while (this.repr.byteLength < this.req) { const chunk = await this.reader.read(); if (chunk.done) { - throw new Error(`Unexpected EOF, got ${this.repr.byteLength}, required ${this.req}, ${chunk.value}`); + this.stopped = true; + if (this.strict) + throw new Error(`Unexpected EOF, got ${this.repr.byteLength}, required ${this.req}, ${chunk.value}`); + return; } this.repr = import_buffer.Buffer.concat([this.repr, chunk.value]); } @@ -14151,6 +14156,8 @@ while (true) { this.req += 8; await this.catchup(); + if (this.stopped) + break; const length = this.repr.readUInt32BE(this.ptr); const name = this.repr.slice(this.ptr + 4, this.ptr + 8).toString(); this.ptr += 4; @@ -14169,6 +14176,8 @@ this.ptr ]; this.ptr += length + 8; + if (this.stopped) + break; if (name == "IEND") break; } @@ -16585,11 +16594,15 @@ cthreadDataCache = newval; }); var refreshThreadDataCache = async (board, op) => { + console.log("refreshing thread info cache..."); threadDataCache.set(await getThreadInfo(board, op)); }; var getThreadDataCache = async (board, op) => { if (!cthreadDataCache) await refreshThreadDataCache(board, op); + else { + console.log("skipped thread cache refresh..."); + } return threadDataCache; }; var getEmbedsFromCache = async (board, op, pid) => { @@ -16801,6 +16814,1056 @@ // src/pngv3.ts var bs58 = __toESM(require_bs58(), 1); + + // src/bitstream.ts + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/index.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/bitstream/index.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/bitstream/reader.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + var __awaiter = function(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function(resolve2) { + resolve2(value); + }); + } + return new (P || (P = Promise))(function(resolve2, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve2(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + var BitstreamReader = class { + constructor() { + this.buffers = []; + this.bufferedLength = 0; + this.blockedRequest = null; + this._offsetIntoBuffer = 0; + this._bufferIndex = 0; + this._offset = 0; + this._spentBufferSize = 0; + this.retainBuffers = false; + this.textDecoder = new TextDecoder(); + this.skippedLength = 0; + } + get bufferIndex() { + return this._bufferIndex; + } + get offset() { + return this._offset; + } + get spentBufferSize() { + return this._spentBufferSize; + } + set offset(value) { + if (value < this._spentBufferSize) { + throw new Error(`Offset ${value} points into a discarded buffer! If you need to seek backwards outside the current buffer, make sure to set retainBuffers=true`); + } + let offsetIntoBuffer = value - this._spentBufferSize; + let bufferIndex = 0; + for (let i = 0, max = this.buffers.length; i < max; ++i) { + let buf2 = this.buffers[i]; + let size = buf2.length * 8; + if (offsetIntoBuffer < size) { + this._bufferIndex = bufferIndex; + this._offset = value; + this._offsetIntoBuffer = offsetIntoBuffer; + this.bufferedLength = buf2.length * 8 - this._offsetIntoBuffer; + for (let j = i + 1; j < max; ++j) + this.bufferedLength += this.buffers[j].length * 8; + return; + } + offsetIntoBuffer -= size; + ++bufferIndex; + } + } + clean(count) { + let buffers = this.buffers.splice(0, count !== void 0 ? Math.min(count, this._bufferIndex) : this._bufferIndex); + this._spentBufferSize += buffers.map((b) => b.length * 8).reduce((pv, cv) => pv + cv, 0); + this._bufferIndex -= buffers.length; + } + get available() { + return this.bufferedLength - this.skippedLength; + } + isAvailable(length) { + return this.bufferedLength >= length; + } + ensureNoReadPending() { + if (this.blockedRequest) + throw new Error(`Only one read() can be outstanding at a time.`); + } + readString(length, options) { + return __awaiter(this, void 0, void 0, function* () { + this.ensureNoReadPending(); + yield this.assure(8 * length); + return this.readStringSync(length, options); + }); + } + readStringSync(length, options) { + var _a, _b; + if (!options) + options = {}; + this.ensureNoReadPending(); + let buffer = new Uint8Array(length); + let firstTerminator = -1; + let charLength = 1; + let encoding = (_a = options.encoding) !== null && _a !== void 0 ? _a : "utf-8"; + if (["utf16le", "ucs-2", "ucs2"].includes(encoding)) { + charLength = 2; + } + for (let i = 0, max = length; i < max; ++i) { + buffer[i] = this.readSync(8); + } + for (let i = 0, max = length; i < max; i += charLength) { + let char = buffer[i]; + if (charLength === 2) + char = char << 8 | ((_b = buffer[i + 1]) !== null && _b !== void 0 ? _b : 0); + if (char === 0) { + firstTerminator = i; + break; + } + } + if (options.nullTerminated !== false) { + if (firstTerminator >= 0) { + buffer = buffer.subarray(0, firstTerminator); + } + } + if (encoding === "utf-8") { + return this.textDecoder.decode(buffer); + } else { + if (typeof Buffer2 === "undefined") + throw new Error(`Encoding '${encoding}' is not supported: No Node.js Buffer implementation and TextDecoder only supports utf-8`); + return Buffer2.from(buffer).toString(encoding); + } + } + peekSync(length) { + return this.readCoreSync(length, false); + } + skip(length) { + this.skippedLength += length; + } + readSync(length) { + return this.readCoreSync(length, true); + } + *readBytes(buffer, offset = 0, length) { + length !== null && length !== void 0 ? length : length = buffer.length - offset; + for (let i = offset, max = Math.min(buffer.length, offset + length); i < max; ++i) { + if (!this.isAvailable(8)) + yield max - i; + buffer[i] = this.readSync(8); + } + return buffer; + } + readBytesSync(buffer, offset = 0, length) { + length !== null && length !== void 0 ? length : length = buffer.length - offset; + let gen = this.readBytes(buffer, offset, length); + while (true) { + let result = gen.next(); + if (result.done === false) + throw new Error(`underrun: Not enough bits are available (requested ${length} bytes)`); + else + break; + } + return buffer; + } + readBytesBlocking(buffer, offset = 0, length) { + return __awaiter(this, void 0, void 0, function* () { + length !== null && length !== void 0 ? length : length = buffer.length - offset; + let gen = this.readBytes(buffer, offset, length); + while (true) { + let result = gen.next(); + if (result.done === false) + yield this.assure(result.value * 8); + else + break; + } + return buffer; + }); + } + readSignedSync(length) { + const u = this.readSync(length); + const signBit = 2 ** (length - 1); + const mask = signBit - 1; + return (u & signBit) === 0 ? u : -((~(u - 1) & mask) >>> 0); + } + readFloatSync(length) { + if (length !== 32 && length !== 64) + throw new TypeError(`Invalid length (${length} bits) Only 4-byte (32 bit / single-precision) and 8-byte (64 bit / double-precision) IEEE 754 values are supported`); + if (!this.isAvailable(length)) + throw new Error(`underrun: Not enough bits are available (requested=${length}, available=${this.bufferedLength}, buffers=${this.buffers.length})`); + let buf2 = new ArrayBuffer(length / 8); + let view = new DataView(buf2); + for (let i = 0, max = buf2.byteLength; i < max; ++i) + view.setUint8(i, this.readSync(8)); + if (length === 32) + return view.getFloat32(0, false); + else if (length === 64) + return view.getFloat64(0, false); + } + readCoreSync(length, consume) { + this.ensureNoReadPending(); + let value = BigInt(0); + let remainingLength = length; + if (this.available < length) + throw new Error(`underrun: Not enough bits are available (requested=${length}, available=${this.bufferedLength}, buffers=${this.buffers.length})`); + this.adjustSkip(); + let offset = this._offsetIntoBuffer; + let bufferIndex = this._bufferIndex; + let bitLength = 0; + while (remainingLength > 0) { + if (bufferIndex >= this.buffers.length) + throw new Error(`Internal error: Buffer index out of range (index=${bufferIndex}, count=${this.buffers.length}), offset=${this.offset}, readLength=${length}, available=${this.available})`); + let buffer = this.buffers[bufferIndex]; + let byteOffset = Math.floor(offset / 8); + if (byteOffset >= buffer.length) + throw new Error(`Internal error: Current buffer (index ${bufferIndex}) has length ${buffer.length} but our position within the buffer is ${byteOffset}! offset=${this.offset}, bufs=${this.buffers.length}`); + let byte = BigInt(buffer[byteOffset]); + let bitOffset = offset % 8; + let bitContribution = Math.min(8 - bitOffset, remainingLength); + let mask = Math.pow(2, bitContribution) - 1; + value = value << BigInt(bitContribution) | byte >> BigInt(8) - BigInt(bitContribution) - BigInt(bitOffset) & BigInt(mask); + offset += bitContribution; + remainingLength -= bitContribution; + bitLength += bitContribution; + if (offset >= buffer.length * 8) { + bufferIndex += 1; + offset = 0; + } + } + if (consume) { + this.bufferedLength -= length; + this._offsetIntoBuffer = offset; + this._offset += bitLength; + this._bufferIndex = bufferIndex; + if (!this.retainBuffers) { + this.clean(); + } + } + return Number(value); + } + adjustSkip() { + if (this.skippedLength <= 0) + return; + while (this.buffers && this.skippedLength > this.buffers[0].length * 8 - this._offsetIntoBuffer) { + this.skippedLength -= this.buffers[0].length * 8 - this._offsetIntoBuffer; + this._offsetIntoBuffer = 0; + this.buffers.shift(); + } + if (this.buffers.length > 0) { + this._offsetIntoBuffer += this.skippedLength; + this.skippedLength = 0; + } + } + assure(length) { + this.ensureNoReadPending(); + if (this.bufferedLength >= length) { + return Promise.resolve(); + } + let request2 = { resolve: null, length, peek: true }; + let promise2 = new Promise((resolve2) => request2.resolve = resolve2); + this.blockedRequest = request2; + return promise2.then(() => { + }); + } + read(length) { + this.ensureNoReadPending(); + if (this.available >= length) { + return Promise.resolve(this.readSync(length)); + } else { + let request2 = { resolve: null, length, peek: false }; + let promise2 = new Promise((resolve2) => request2.resolve = resolve2); + this.blockedRequest = request2; + return promise2; + } + } + readSigned(length) { + this.ensureNoReadPending(); + if (this.available >= length) { + return Promise.resolve(this.readSignedSync(length)); + } else { + let request2 = { resolve: null, length, peek: false, signed: true }; + let promise2 = new Promise((resolve2) => request2.resolve = resolve2); + this.blockedRequest = request2; + return promise2; + } + } + readFloat(length) { + this.ensureNoReadPending(); + if (this.available >= length) { + return Promise.resolve(this.readFloatSync(length)); + } else { + let request2 = { resolve: null, length, peek: false, float: true }; + let promise2 = new Promise((resolve2) => request2.resolve = resolve2); + this.blockedRequest = request2; + return promise2; + } + } + peek(length) { + return __awaiter(this, void 0, void 0, function* () { + yield this.assure(length); + return this.peekSync(length); + }); + } + addBuffer(buffer) { + this.buffers.push(buffer); + this.bufferedLength += buffer.length * 8; + if (this.blockedRequest && this.blockedRequest.length <= this.available) { + let request2 = this.blockedRequest; + this.blockedRequest = null; + if (request2.peek) { + request2.resolve(0); + } else if (request2.signed) { + request2.resolve(this.readSignedSync(request2.length)); + } else if (request2.float) { + request2.resolve(this.readFloatSync(request2.length)); + } else { + request2.resolve(this.readSync(request2.length)); + } + } + } + }; + + // node_modules/@astronautlabs/bitstream/dist.esm/bitstream/string-encoding-options.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/bitstream/writer.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + var BitstreamWriter = class { + constructor(stream, bufferSize = 1) { + this.stream = stream; + this.bufferSize = bufferSize; + this.pendingByte = BigInt(0); + this.pendingBits = 0; + this.bufferedBytes = 0; + this._offset = 0; + this.textEncoder = new TextEncoder(); + this.buffer = new Uint8Array(bufferSize); + } + get offset() { + return this._offset; + } + get byteOffset() { + return this.pendingBits; + } + end() { + this.finishByte(); + this.flush(); + } + reset() { + this._offset = 0; + } + finishByte() { + if (this.pendingBits > 0) { + this.buffer[this.bufferedBytes++] = Number(this.pendingByte); + this.pendingBits = 0; + this.pendingByte = BigInt(0); + } + } + flush() { + if (this.bufferedBytes > 0) { + this.stream.write(Buffer2.from(this.buffer.slice(0, this.bufferedBytes))); + this.bufferedBytes = 0; + } + } + writeString(byteCount, value, encoding = "utf-8") { + if (encoding === "utf-8") { + let buffer = new Uint8Array(byteCount); + let strBuf = this.textEncoder.encode(value); + buffer.set(strBuf, 0); + this.writeBytes(buffer); + } else { + if (typeof Buffer2 === "undefined") { + throw new Error(`Encoding '${encoding}' is not supported: No Node.js Buffer implementation found, web standard TextEncoder only supports utf-8`); + } + let buffer = Buffer2.alloc(byteCount); + Buffer2.from(value, encoding).copy(buffer); + this.writeBuffer(buffer); + } + } + writeBuffer(buffer) { + this.writeBytes(buffer); + } + writeBytes(chunk, offset = 0, length) { + length !== null && length !== void 0 ? length : length = chunk.length - offset; + if (this.byteOffset === 0) { + while (chunk.length > 0) { + let writableLength = Math.min(chunk.length, this.buffer.length - this.bufferedBytes); + this.buffer.set(chunk.subarray(0, writableLength), this.bufferedBytes); + this.bufferedBytes += writableLength; + chunk = chunk.subarray(writableLength); + if (this.bufferedBytes >= this.buffer.length) + this.flush(); + } + return; + } + for (let i = offset, max = Math.min(chunk.length, offset + length); i < max; ++i) + this.write(8, chunk[i]); + } + min(a, b) { + if (a < b) + return a; + else + return b; + } + write(length, value) { + if (value === void 0 || value === null) + value = 0; + value = Number(value); + if (Number.isNaN(value)) + throw new Error(`Cannot write to bitstream: Value ${value} is not a number`); + if (!Number.isFinite(value)) + throw new Error(`Cannot write to bitstream: Value ${value} must be finite`); + let valueN = BigInt(value % Math.pow(2, length)); + let remainingLength = length; + while (remainingLength > 0) { + let shift = BigInt(8 - this.pendingBits - remainingLength); + let contribution = shift >= 0 ? valueN << shift : valueN >> -shift; + let writtenLength = Number(shift >= 0 ? remainingLength : this.min(-shift, BigInt(8 - this.pendingBits))); + this.pendingByte = this.pendingByte | contribution; + this.pendingBits += writtenLength; + this._offset += writtenLength; + remainingLength -= writtenLength; + valueN = valueN % BigInt(Math.pow(2, remainingLength)); + if (this.pendingBits === 8) { + this.finishByte(); + if (this.bufferedBytes >= this.buffer.length) { + this.flush(); + } + } + } + } + writeSigned(length, value) { + if (value === void 0 || value === null) + value = 0; + const originalValue = value; + const max = 2 ** (length - 1) - 1; + const min = -(2 ** (length - 1)); + value = Number(value); + if (Number.isNaN(value)) + throw new Error(`Cannot write to bitstream: Value ${originalValue} is not a number`); + if (!Number.isFinite(value)) + throw new Error(`Cannot write to bitstream: Value ${value} must be finite`); + if (value > max) + throw new TypeError(`Cannot represent ${value} in I${length} format: Value too large (min=${min}, max=${max})`); + if (value < min) + throw new TypeError(`Cannot represent ${value} in I${length} format: Negative value too small (min=${min}, max=${max})`); + return this.write(length, value >= 0 ? value : ~-value + 1 >>> 0); + } + writeFloat(length, value) { + if (length !== 32 && length !== 64) + throw new TypeError(`Invalid length (${length} bits) Only 4-byte (32 bit / single-precision) and 8-byte (64 bit / double-precision) IEEE 754 values are supported`); + let buf2 = new ArrayBuffer(length / 8); + let view = new DataView(buf2); + if (length === 32) + view.setFloat32(0, value); + else if (length === 64) + view.setFloat64(0, value); + for (let i = 0, max = buf2.byteLength; i < max; ++i) + this.write(8, view.getUint8(i)); + } + }; + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/index.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/array-options.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/array-serializer.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/resolve-length.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/structure-serializer.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/utils.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/boolean-options.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/boolean-serializer.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/buffer-options.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/buffer-serializer.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/element.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/common/index.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/common/buffered-writable.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/common/constructor.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/common/discriminant.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/common/writable.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/common/incomplete-read-result.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/element.js + var _parent; + var _readFields; + var _isBeingRead; + var _fieldBeingComputed; + var _fieldBeingComputedIntrospectable; + var SERIALIZE_WRITERS = Symbol("Writers used by Bitstream#serialize() for this element type."); + _parent = /* @__PURE__ */ new WeakMap(), _readFields = /* @__PURE__ */ new WeakMap(), _isBeingRead = /* @__PURE__ */ new WeakMap(), _fieldBeingComputed = /* @__PURE__ */ new WeakMap(), _fieldBeingComputedIntrospectable = /* @__PURE__ */ new WeakMap(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/field-definition.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/field-options.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/field.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/null-serializer.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/number-serializer.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/string-serializer.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/length-determinant.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/number-options.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/serializer.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/value-determinant.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/variant-definition.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/variant-options.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/variant.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/reserved.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/reserved-low.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/marker.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // src/bitstream.ts + var revbyte = (n, len = 8) => { + let acc = 0; + let n2 = n; + let len2 = len; + while (len2) { + acc = acc * 2 + (n2 & 1); + n2 >>= 1; + len2--; + } + return acc; + }; + var BitstreamReader2 = class extends BitstreamReader { + constructor() { + super(...arguments); + this.rtotal = 0; + } + addBuffer(hidden) { + const inp = Buffer2.from(hidden); + for (let i = 0; i < inp.byteLength; ++i) + inp[i] = revbyte(inp[i]); + super.addBuffer(inp); + } + readSync(len) { + const v = super.readSync(len); + this.rtotal += len; + return revbyte(v, len); + } + }; + var BitstreamWriter2 = class extends BitstreamWriter { + constructor(w) { + super({ + write: (c) => { + const inp = Buffer2.from(c); + for (let i = 0; i < inp.byteLength; ++i) + inp[i] = revbyte(inp[i]); + this.w.write(inp); + } + }); + this.w = w; + this.wtotal = 0; + } + write(length, value) { + this.wtotal += length; + if (length) { + value = revbyte(value, length); + } + super.write(length, value); + } + }; + + // src/dh-deflate.ts + init_define_BUILD_VERSION(); + init_esbuild_inject(); + var TINF_OK = 0; + var Tree = class { + constructor() { + this.table = new Uint16Array(16); + this.trans = new Uint16Array(288); + } + }; + var getPathTo = (tree, value) => { + if (tree[0] === value) + return "0"; + if (tree[1] === value) + return "1"; + let p; + if (typeof tree[0] != "number") + p = getPathTo(tree[0], value); + let b = "0"; + if (!p) { + if (tree[1] && typeof tree[1] != "number") + p = getPathTo(tree[1], value); + b = "1"; + } + if (p) + return b + p; + }; + function buildHuffmanTable(codeLengths, values) { + let k = 0, code = [], i, j, length = 16; + while (length > 0 && !codeLengths[length - 1]) + length--; + code.push({ children: [], index: 0 }); + let p = code[0], q; + for (i = 0; i < length; i++) { + for (j = 0; j < codeLengths[i]; j++) { + p = code.pop(); + p.children[p.index] = values[k]; + while (p.index > 0) { + if (code.length === 0) + throw new Error("Could not recreate Huffman Table"); + p = code.pop(); + } + p.index++; + code.push(p); + while (code.length <= i) { + code.push(q = { children: [], index: 0 }); + p.children[p.index] = q.children; + p = q; + } + k++; + } + if (i + 1 < length) { + code.push(q = { children: [], index: 0 }); + p.children[p.index] = q.children; + p = q; + } + } + return code[0].children; + } + var Data = class { + constructor(source, dests, to_hide, hidden) { + this.source = source; + this.dests = dests; + this.to_hide = to_hide; + this.hidden = hidden; + this.dest = []; + this.ltree = new Tree(); + this.dtree = new Tree(); + } + computeReverse() { + this.rltree = buildHuffmanTable(this.ltree.table, this.ltree.trans)[0]; + this.rdtree = buildHuffmanTable(this.dtree.table, this.dtree.trans)[0]; + } + }; + var sltree = new Tree(); + var sdtree = new Tree(); + var rltree; + var rdtree; + var length_bits = new Uint8Array(30); + var length_base = new Uint16Array(30); + var dist_bits = new Uint8Array(30); + var dist_base = new Uint16Array(30); + var clcidx = new Uint8Array([ + 16, + 17, + 18, + 0, + 8, + 7, + 9, + 6, + 10, + 5, + 11, + 4, + 12, + 3, + 13, + 2, + 14, + 1, + 15 + ]); + var code_tree = new Tree(); + var lengths = new Uint8Array(288 + 32); + function tinf_build_bits_base(bits, base, delta, first) { + let i, sum; + for (i = 0; i < delta; ++i) + bits[i] = 0; + for (i = 0; i < 30 - delta; ++i) + bits[i + delta] = i / delta | 0; + for (sum = first, i = 0; i < 30; ++i) { + base[i] = sum; + sum += 1 << bits[i]; + } + } + function tinf_build_fixed_trees(lt, dt) { + let i; + for (i = 0; i < 7; ++i) + lt.table[i] = 0; + lt.table[7] = 24; + lt.table[8] = 152; + lt.table[9] = 112; + for (i = 0; i < 24; ++i) + lt.trans[i] = 256 + i; + for (i = 0; i < 144; ++i) + lt.trans[24 + i] = i; + for (i = 0; i < 8; ++i) + lt.trans[24 + 144 + i] = 280 + i; + for (i = 0; i < 112; ++i) + lt.trans[24 + 144 + 8 + i] = 144 + i; + for (i = 0; i < 5; ++i) + dt.table[i] = 0; + dt.table[5] = 32; + for (i = 0; i < 32; ++i) + dt.trans[i] = i; + } + var offs = new Uint16Array(16); + function tinf_build_tree(t, lengths2, off, num) { + let i, sum; + for (i = 0; i < 16; ++i) + t.table[i] = 0; + for (i = 0; i < num; ++i) + t.table[lengths2[off + i]]++; + t.table[0] = 0; + for (sum = 0, i = 0; i < 16; ++i) { + offs[i] = sum; + sum += t.table[i]; + } + for (i = 0; i < num; ++i) { + if (lengths2[off + i]) + t.trans[offs[lengths2[off + i]]++] = i; + } + } + function tinf_getbit(d) { + return d.source.readSync(1); + } + function tinf_read_bits(d, num, base) { + if (!num) + return base; + const v = d.source.readSync(num) + base; + return v; + } + function tinf_decode_symbol(d, t, copy = true, ext = {}) { + let sum = 0, cur = 0, len = 0; + let s = 0; + do { + const b = d.source.readSync(1); + copy && d.hidden.write(1, b); + s = s << 1 | b; + cur = 2 * cur + b; + ++len; + sum += t.table[len]; + cur -= t.table[len]; + } while (cur >= 0); + ext.length = len; + ext.sym = s; + return t.trans[sum + cur]; + } + function tinf_decode_trees(d, lt, dt) { + let i, num, length; + const hlit = tinf_read_bits(d, 5, 257); + d.hidden?.write(5, hlit - 257); + const hdist = tinf_read_bits(d, 5, 1); + d.hidden?.write(5, hdist - 1); + const hclen = tinf_read_bits(d, 4, 4); + d.hidden?.write(4, hclen - 4); + for (i = 0; i < 19; ++i) + lengths[i] = 0; + for (i = 0; i < hclen; ++i) { + const clen = tinf_read_bits(d, 3, 0); + d.hidden?.write(3, clen); + lengths[clcidx[i]] = clen; + } + tinf_build_tree(code_tree, lengths, 0, 19); + for (num = 0; num < hlit + hdist; ) { + const sym = tinf_decode_symbol(d, code_tree); + let prev; + switch (sym) { + case 16: + prev = lengths[num - 1]; + length = tinf_read_bits(d, 2, 3); + d.hidden?.write(2, length - 3); + for (; length; --length) { + lengths[num++] = prev; + } + break; + case 17: + length = tinf_read_bits(d, 3, 3); + d.hidden?.write(3, length - 3); + for (; length; --length) { + lengths[num++] = 0; + } + break; + case 18: + length = tinf_read_bits(d, 7, 11); + d.hidden?.write(7, length - 11); + for (; length; --length) { + lengths[num++] = 0; + } + break; + default: + lengths[num++] = sym; + break; + } + } + tinf_build_tree(lt, lengths, 0, hlit); + tinf_build_tree(dt, lengths, hlit, hdist); + } + var get_symbol = (value, bits_table, base_table) => { + let i = 0; + for (i = 0; i < base_table.length; ++i) { + if (base_table[i] > value) { + i--; + return [i, bits_table[i], value - base_table[i]]; + } + } + i--; + return [i, bits_table[i], value - base_table[i]]; + }; + var encode_symbol = (sym, tree) => { + const code = getPathTo(tree, sym); + return { + length: code?.length, + val: parseInt(code, 2) + }; + }; + var capacity = 0; + function tinf_inflate_block_data(d, lt, dt) { + let finished = false; + while (1) { + if (finished) { + return true; + } + let sym = tinf_decode_symbol(d, lt); + if (sym === 256) { + return TINF_OK; + } + if (sym < 256) { + d.dest.push(sym); + } else { + sym -= 257; + const length = tinf_read_bits(d, length_bits[sym], length_base[sym]); + if (length_bits[sym]) + d.hidden.write(length_bits[sym], length - length_base[sym]); + const ext = { length: 0, sym: 0 }; + const dist = tinf_decode_symbol(d, dt, false, ext); + let backoffset = tinf_read_bits(d, dist_bits[dist], dist_base[dist]); + const offs2 = d.dest.length - backoffset; + const match = Buffer2.from(d.dest.slice(offs2, offs2 + length)); + if (match.length == length) { + let begin = d.dest.length - 32768; + if (begin < 0) + begin = 0; + let matches = []; + let o = 0; + const slic = Buffer2.from(d.dest.slice(begin + o, d.dest.length)); + while (begin + o < d.dest.length) { + const r = slic.slice(o, d.dest.length).indexOf(match); + if (r >= 0) { + matches.push(r + begin + o); + o += r; + } else { + break; + } + o++; + } + if (matches.length > 1) { + matches = matches.map((e) => -(e - d.dest.length)); + matches.reverse(); + const v = Math.floor(Math.log2(matches.length)); + capacity += v; + if (d.to_hide instanceof BitstreamReader2) { + if (d.to_hide.available) { + const s = d.to_hide.readSync(Math.min(d.to_hide.available, v)); + backoffset = matches[s]; + } else { + finished = true; + } + } else { + const idx = matches.indexOf(backoffset); + d.to_hide.write(v, idx); + } + } + } + const [dsym, dlen, doff] = get_symbol(backoffset, dist_bits, dist_base); + const encdist = encode_symbol(dsym, d.rdtree); + d.hidden.write(encdist.length, revbyte(encdist.val, encdist.length)); + d.hidden.write(dlen, doff); + for (let i = offs2; i < offs2 + length; ++i) { + d.dest.push(d.dest[i]); + } + } + } + } + function tinf_inflate_uncompressed_block(d) { + const length = d.source.readSync(16); + const invlength = d.source.readSync(16); + if (length !== (~invlength & 65535)) + return -4; + for (let i = length; i; --i) + d.dest.push(d.source.readSync(8)); + return TINF_OK; + } + function tinf_uncompress(source, decompressed, to_hide, hidden) { + const decomp = new BitstreamWriter2({ write: decompressed || (() => { + }) }); + const hid = new BitstreamWriter2({ write: hidden || (() => { + }) }); + const d = new Data(source, decomp, to_hide, hid); + let res; + let bfinal, btype; + do { + if (to_hide instanceof BitstreamReader2) { + if (to_hide.available == 0) { + while (source.available && source.offset & 7) { + hid.write(1, source.readSync(1)); + } + return source.offset >> 3; + } + } + bfinal = tinf_getbit(d); + d.hidden.write(1, bfinal); + btype = tinf_read_bits(d, 2, 0); + d.hidden?.write(2, btype); + switch (btype) { + case 0: + res = tinf_inflate_uncompressed_block(d); + break; + case 1: + d.rdtree = rdtree; + d.rltree = rltree; + res = tinf_inflate_block_data(d, sltree, sdtree); + if (res === true) { + continue; + } + break; + case 2: + tinf_decode_trees(d, d.ltree, d.dtree); + d.computeReverse(); + res = tinf_inflate_block_data(d, d.ltree, d.dtree); + if (res === true) { + continue; + } + break; + default: + res = -2; + } + if (res !== TINF_OK) + throw new Error("Data error " + res); + } while (!bfinal); + decomp.end(); + hid.end(); + } + tinf_build_fixed_trees(sltree, sdtree); + tinf_build_bits_base(length_bits, length_base, 4, 3); + tinf_build_bits_base(dist_bits, dist_base, 2, 1); + rltree = buildHuffmanTable(sltree.table, sltree.trans)[0]; + rdtree = buildHuffmanTable(sdtree.table, sdtree.trans)[0]; + length_bits[28] = 0; + length_base[28] = 258; + + // src/pngv3.ts var csettings2; settings.subscribe((b) => { csettings2 = b; @@ -16840,14 +17903,40 @@ "t": "take-me-to.space", "z": "z.zz.fo" }; + var extractFromRawDeflate = (b) => { + const src = new BitstreamReader2(); + src.addBuffer(b); + const chnks = []; + const hidden = new BitstreamWriter2({ + write(chunk) { + for (const i of chunk) { + if (i) + chnks.push(i); + else + throw "Finish"; + } + } + }); + try { + tinf_uncompress(src, () => { + }, hidden, () => { + }); + } catch (e) { + if (e == "Finish") + return import_buffer3.Buffer.from(chnks); + } + return false; + }; var extract = async (png) => { const reader = BufferReadStream(png).getReader(); - const sneed = new PNGDecoder(reader); + const sneed = new PNGDecoder(reader, false); const ret = []; let w; if (!csettings2) throw new Error("Settings uninit"); try { + let complete = false; + const idats = []; for await (const [name, chunk, crc, offset] of sneed.chunks()) { let buff; switch (name) { @@ -16894,12 +17983,27 @@ } break; case "IDAT": + if (ret.length) + return ret; + buff = await chunk(); + idats.push(buff.slice(4)); case "IEND": - return ret.slice(0, csettings2.maxe); + complete = true; default: break; } } + if (idats.length) { + let decoded; + if ((decoded = extractFromRawDeflate(import_buffer3.Buffer.concat(idats).slice(2))) === false) + return false; + const dec = decoded.toString().split(" ").map((e) => { + if (!(e[0] in rprefs)) + throw "Uhh"; + return `https://${rprefs[e[0]]}/${e.slice(1)}`; + }).join(" "); + return decodeCoom3Payload(import_buffer3.Buffer.from(dec)); + } } catch (e) { console.error(e); } finally { @@ -16921,46 +18025,85 @@ }); return [ret, () => b]; }; + var embedInRawDeflate = (b, h) => { + const src = new BitstreamReader2(); + const hid = new BitstreamReader2(); + hid.addBuffer(h); + src.addBuffer(b); + const chnks = []; + const endo = tinf_uncompress(src, () => { + }, hid, (c) => chnks.push(c)); + if (endo) + chnks.push(b.slice(endo)); + return import_buffer3.Buffer.concat(chnks); + }; var inject_data = async (container, injb) => { if (!csettings2) throw new Error("Settings uninit"); - let magic4 = false; + if (csettings2.pmeth < 5) { + let magic4 = false; + const [writestream2, extract8] = BufferWriteStream2(); + const encoder = new PNGEncoder(writestream2); + const decoder = new PNGDecoder(container.stream().getReader()); + for await (const [name, chunk, crc, offset] of decoder.chunks()) { + if (magic4 && name != "IDAT") + break; + if (!magic4 && name == "IDAT") { + const passed = import_buffer3.Buffer.from(injb); + switch (csettings2.pmeth) { + case 0: + await encoder.insertchunk(["tEXt", async () => buildChunk("tEXt", import_buffer3.Buffer.concat([CUM3, passed])), () => Promise.resolve(0), 0]); + break; + case 1: + xor(passed, password); + await encoder.insertchunk(["tEXt", async () => buildChunk("tEXt", import_buffer3.Buffer.concat([CUM4, import_buffer3.Buffer.from(import_buffer3.Buffer.from(passed).toString("base64"))])), () => Promise.resolve(0), 0]); + break; + case 2: + await encoder.insertchunk(["tEXt", async () => buildChunk("tEXt", import_buffer3.Buffer.concat([CUM5, import_buffer3.Buffer.from(import_buffer3.Buffer.from(passed).toString("base64"))])), () => Promise.resolve(0), 0]); + break; + case 3: + await encoder.insertchunk(["tEXt", async () => buildChunk("tEXt", import_buffer3.Buffer.concat([CUM6, import_buffer3.Buffer.from(import_buffer3.Buffer.from(passed).toString("base64"))])), () => Promise.resolve(0), 0]); + break; + case 4: + await encoder.insertchunk(["tEXt", async () => buildChunk("tEXt", import_buffer3.Buffer.concat([CUM7, import_buffer3.Buffer.from(bs58.encode(passed))])), () => Promise.resolve(0), 0]); + break; + } + magic4 = true; + } + await encoder.insertchunk([name, chunk, crc, offset]); + } + await encoder.insertchunk([ + "IEND", + async () => Promise.resolve(buildChunk("IEND", import_buffer3.Buffer.from([]))), + async () => Promise.resolve(0), + 0 + ]); + return extract8(); + } + let pdec = new PNGDecoder(container.stream().getReader()); + const concat = []; + for await (const chk of pdec.chunks()) + if (chk[0] == "IDAT") + concat.push((await chk[1]()).slice(4)); + const comp = import_buffer3.Buffer.concat(concat); + const head = comp.slice(0, 2); + const chksum = comp.slice(-4); + const idatblk = embedInRawDeflate(comp.slice(2, -4), injb); + const bws = BufferWriteStream2(); const [writestream, extract7] = BufferWriteStream2(); - const encoder = new PNGEncoder(writestream); - const decoder = new PNGDecoder(container.stream().getReader()); - for await (const [name, chunk, crc, offset] of decoder.chunks()) { - if (magic4 && name != "IDAT") - break; - if (!magic4 && name == "IDAT") { - const passed = import_buffer3.Buffer.from(injb); - switch (csettings2.pmeth) { - case 0: - await encoder.insertchunk(["tEXt", async () => buildChunk("tEXt", import_buffer3.Buffer.concat([CUM3, passed])), () => Promise.resolve(0), 0]); - break; - case 1: - xor(passed, password); - await encoder.insertchunk(["tEXt", async () => buildChunk("tEXt", import_buffer3.Buffer.concat([CUM4, import_buffer3.Buffer.from(import_buffer3.Buffer.from(passed).toString("base64"))])), () => Promise.resolve(0), 0]); - break; - case 2: - await encoder.insertchunk(["tEXt", async () => buildChunk("tEXt", import_buffer3.Buffer.concat([CUM5, import_buffer3.Buffer.from(import_buffer3.Buffer.from(passed).toString("base64"))])), () => Promise.resolve(0), 0]); - break; - case 3: - await encoder.insertchunk(["tEXt", async () => buildChunk("tEXt", import_buffer3.Buffer.concat([CUM6, import_buffer3.Buffer.from(import_buffer3.Buffer.from(passed).toString("base64"))])), () => Promise.resolve(0), 0]); - break; - case 4: - await encoder.insertchunk(["tEXt", async () => buildChunk("tEXt", import_buffer3.Buffer.concat([CUM7, import_buffer3.Buffer.from(bs58.encode(passed))])), () => Promise.resolve(0), 0]); - break; + const penc = new PNGEncoder(writestream); + pdec = new PNGDecoder(container.stream().getReader()); + let ins = false; + for await (const chk of pdec.chunks()) { + if (chk[0] != "IDAT") { + await penc.insertchunk(chk); + } else { + if (!ins) { + await penc.insertchunk(["IDAT", async () => import_buffer3.Buffer.concat([import_buffer3.Buffer.from("IDAT"), head, idatblk, chksum]), () => Promise.resolve(0), 0]); + ins = true; } - magic4 = true; } - await encoder.insertchunk([name, chunk, crc, offset]); } - await encoder.insertchunk([ - "IEND", - async () => Promise.resolve(buildChunk("IEND", import_buffer3.Buffer.from([]))), - async () => Promise.resolve(0), - 0 - ]); return extract7(); }; var inject = async (container, links) => { @@ -16977,49 +18120,8 @@ return inject_data(container, injb); }; var has_embed = async (png) => { - const reader = BufferReadStream(png).getReader(); - const sneed = new PNGDecoder(reader); - try { - for await (const [name, chunk, crc, offset] of sneed.chunks()) { - let buff; - switch (name) { - case "tEXt": - buff = await chunk(); - if (buff.slice(4, 4 + CUM3.length).equals(CUM3)) - return true; - if (buff.slice(4, 4 + CUM4.length).equals(CUM4)) - return true; - if (buff.slice(4, 4 + CUM5.length).equals(CUM5)) - return true; - if (buff.slice(4, 4 + CUM6.length).equals(CUM6)) { - const passed = buff.slice(4 + CUM6.length).toString(); - if (passed.match(/^[0-9a-zA-Z+/=]+$/g)) { - if (import_buffer3.Buffer.from(passed, "base64").toString().split(" ").every((l) => l[0] in rprefs)) - return true; - } - } - if (buff.slice(4, 4 + CUM7.length).equals(CUM7)) { - const passed = buff.slice(4 + CUM7.length).toString(); - if (passed.match(/^[0-9a-zA-Z+/=]+$/g)) { - if (import_buffer3.Buffer.from(passed, "base64").toString().split(" ").every((l) => l[0] in rprefs)) - return true; - if (import_buffer3.Buffer.from(bs58.decode(passed)).toString().split(" ").every((l) => l[0] in rprefs)) - return true; - } - } - break; - case "IDAT": - case "IEND": - return false; - default: - break; - } - } - } catch (e) { - return; - } finally { - reader.releaseLock(); - } + const r = await extract(png); + return !!r; }; var pngv3_default = { extract, @@ -23548,9 +24650,9 @@ let select; let mounted; let dispose; - let each_value = [0, 1, 2, 3, 4]; + let each_value = [0, 1, 2, 3, 4, 5]; let each_blocks = []; - for (let i = 0; i < 5; i += 1) { + for (let i = 0; i < 6; i += 1) { each_blocks[i] = create_each_block2(get_each_context2(ctx, each_value, i)); } return { @@ -23558,7 +24660,7 @@ label = element("label"); t = text("PNG Embedding method\n "); select = element("select"); - for (let i = 0; i < 5; i += 1) { + for (let i = 0; i < 6; i += 1) { each_blocks[i].c(); } if (ctx[7].pmeth === void 0) @@ -23568,7 +24670,7 @@ insert(target, label, anchor); append(label, t); append(label, select); - for (let i = 0; i < 5; i += 1) { + for (let i = 0; i < 6; i += 1) { each_blocks[i].m(select, null); } select_option(select, ctx[7].pmeth); diff --git a/chrome/manifest.json b/chrome/manifest.json index 21415ed..ea57c17 100644 --- a/chrome/manifest.json +++ b/chrome/manifest.json @@ -2,7 +2,7 @@ "manifest_version": 3, "name": "PngExtraEmbedder", "description": "Discover embedded files on 4chan and archives!", - "version": "0.280", + "version": "0.281", "icons": { "64": "1449696017588.png" }, diff --git a/dist/main.js b/dist/main.js index f294a1c..ff4d8a5 100644 --- a/dist/main.js +++ b/dist/main.js @@ -73,7 +73,7 @@ var define_BUILD_VERSION_default; var init_define_BUILD_VERSION = __esm({ ""() { - define_BUILD_VERSION_default = [0, 280]; + define_BUILD_VERSION_default = [0, 281]; } }); @@ -12109,7 +12109,7 @@ var dctSqrt1d2 = 2896; function constructor() { } - function buildHuffmanTable(codeLengths, values) { + function buildHuffmanTable2(codeLengths, values) { var k = 0, code = [], i, j, length = 16; while (length > 0 && !codeLengths[length - 1]) length--; @@ -12745,7 +12745,7 @@ for (j = 0; j < codeLengthSum; j++, offset++) huffmanValues[j] = data[offset]; i += 17 + codeLengthSum; - (huffmanTableSpec >> 4 === 0 ? huffmanTablesDC : huffmanTablesAC)[huffmanTableSpec & 15] = buildHuffmanTable(codeLengths, huffmanValues); + (huffmanTableSpec >> 4 === 0 ? huffmanTablesDC : huffmanTablesAC)[huffmanTableSpec & 15] = buildHuffmanTable2(codeLengths, huffmanValues); } break; case 65501: @@ -13987,7 +13987,7 @@ var initial_settings = localLoad("settingsv2", { loop: true, dh: false, - pmeth: 4, + pmeth: 5, xpv: false, xpi: false, hyd: false, @@ -14132,8 +14132,10 @@ var import_crc_32 = __toESM(require_crc32(), 1); var import_buffer = __toESM(require_buffer(), 1); var PNGDecoder = class { - constructor(reader) { + constructor(reader, strict = true) { this.reader = reader; + this.strict = strict; + this.stopped = false; this.req = 8; this.ptr = 8; this.repr = import_buffer.Buffer.from([]); @@ -14142,7 +14144,10 @@ while (this.repr.byteLength < this.req) { const chunk = await this.reader.read(); if (chunk.done) { - throw new Error(`Unexpected EOF, got ${this.repr.byteLength}, required ${this.req}, ${chunk.value}`); + this.stopped = true; + if (this.strict) + throw new Error(`Unexpected EOF, got ${this.repr.byteLength}, required ${this.req}, ${chunk.value}`); + return; } this.repr = import_buffer.Buffer.concat([this.repr, chunk.value]); } @@ -14151,6 +14156,8 @@ while (true) { this.req += 8; await this.catchup(); + if (this.stopped) + break; const length = this.repr.readUInt32BE(this.ptr); const name = this.repr.slice(this.ptr + 4, this.ptr + 8).toString(); this.ptr += 4; @@ -14169,6 +14176,8 @@ this.ptr ]; this.ptr += length + 8; + if (this.stopped) + break; if (name == "IEND") break; } @@ -16420,11 +16429,15 @@ cthreadDataCache = newval; }); var refreshThreadDataCache = async (board, op) => { + console.log("refreshing thread info cache..."); threadDataCache.set(await getThreadInfo(board, op)); }; var getThreadDataCache = async (board, op) => { if (!cthreadDataCache) await refreshThreadDataCache(board, op); + else { + console.log("skipped thread cache refresh..."); + } return threadDataCache; }; var getEmbedsFromCache = async (board, op, pid) => { @@ -16636,6 +16649,1056 @@ // src/pngv3.ts var bs58 = __toESM(require_bs58(), 1); + + // src/bitstream.ts + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/index.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/bitstream/index.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/bitstream/reader.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + var __awaiter = function(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function(resolve2) { + resolve2(value); + }); + } + return new (P || (P = Promise))(function(resolve2, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve2(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + var BitstreamReader = class { + constructor() { + this.buffers = []; + this.bufferedLength = 0; + this.blockedRequest = null; + this._offsetIntoBuffer = 0; + this._bufferIndex = 0; + this._offset = 0; + this._spentBufferSize = 0; + this.retainBuffers = false; + this.textDecoder = new TextDecoder(); + this.skippedLength = 0; + } + get bufferIndex() { + return this._bufferIndex; + } + get offset() { + return this._offset; + } + get spentBufferSize() { + return this._spentBufferSize; + } + set offset(value) { + if (value < this._spentBufferSize) { + throw new Error(`Offset ${value} points into a discarded buffer! If you need to seek backwards outside the current buffer, make sure to set retainBuffers=true`); + } + let offsetIntoBuffer = value - this._spentBufferSize; + let bufferIndex = 0; + for (let i = 0, max = this.buffers.length; i < max; ++i) { + let buf2 = this.buffers[i]; + let size = buf2.length * 8; + if (offsetIntoBuffer < size) { + this._bufferIndex = bufferIndex; + this._offset = value; + this._offsetIntoBuffer = offsetIntoBuffer; + this.bufferedLength = buf2.length * 8 - this._offsetIntoBuffer; + for (let j = i + 1; j < max; ++j) + this.bufferedLength += this.buffers[j].length * 8; + return; + } + offsetIntoBuffer -= size; + ++bufferIndex; + } + } + clean(count) { + let buffers = this.buffers.splice(0, count !== void 0 ? Math.min(count, this._bufferIndex) : this._bufferIndex); + this._spentBufferSize += buffers.map((b) => b.length * 8).reduce((pv, cv) => pv + cv, 0); + this._bufferIndex -= buffers.length; + } + get available() { + return this.bufferedLength - this.skippedLength; + } + isAvailable(length) { + return this.bufferedLength >= length; + } + ensureNoReadPending() { + if (this.blockedRequest) + throw new Error(`Only one read() can be outstanding at a time.`); + } + readString(length, options) { + return __awaiter(this, void 0, void 0, function* () { + this.ensureNoReadPending(); + yield this.assure(8 * length); + return this.readStringSync(length, options); + }); + } + readStringSync(length, options) { + var _a, _b; + if (!options) + options = {}; + this.ensureNoReadPending(); + let buffer = new Uint8Array(length); + let firstTerminator = -1; + let charLength = 1; + let encoding = (_a = options.encoding) !== null && _a !== void 0 ? _a : "utf-8"; + if (["utf16le", "ucs-2", "ucs2"].includes(encoding)) { + charLength = 2; + } + for (let i = 0, max = length; i < max; ++i) { + buffer[i] = this.readSync(8); + } + for (let i = 0, max = length; i < max; i += charLength) { + let char = buffer[i]; + if (charLength === 2) + char = char << 8 | ((_b = buffer[i + 1]) !== null && _b !== void 0 ? _b : 0); + if (char === 0) { + firstTerminator = i; + break; + } + } + if (options.nullTerminated !== false) { + if (firstTerminator >= 0) { + buffer = buffer.subarray(0, firstTerminator); + } + } + if (encoding === "utf-8") { + return this.textDecoder.decode(buffer); + } else { + if (typeof Buffer2 === "undefined") + throw new Error(`Encoding '${encoding}' is not supported: No Node.js Buffer implementation and TextDecoder only supports utf-8`); + return Buffer2.from(buffer).toString(encoding); + } + } + peekSync(length) { + return this.readCoreSync(length, false); + } + skip(length) { + this.skippedLength += length; + } + readSync(length) { + return this.readCoreSync(length, true); + } + *readBytes(buffer, offset = 0, length) { + length !== null && length !== void 0 ? length : length = buffer.length - offset; + for (let i = offset, max = Math.min(buffer.length, offset + length); i < max; ++i) { + if (!this.isAvailable(8)) + yield max - i; + buffer[i] = this.readSync(8); + } + return buffer; + } + readBytesSync(buffer, offset = 0, length) { + length !== null && length !== void 0 ? length : length = buffer.length - offset; + let gen = this.readBytes(buffer, offset, length); + while (true) { + let result = gen.next(); + if (result.done === false) + throw new Error(`underrun: Not enough bits are available (requested ${length} bytes)`); + else + break; + } + return buffer; + } + readBytesBlocking(buffer, offset = 0, length) { + return __awaiter(this, void 0, void 0, function* () { + length !== null && length !== void 0 ? length : length = buffer.length - offset; + let gen = this.readBytes(buffer, offset, length); + while (true) { + let result = gen.next(); + if (result.done === false) + yield this.assure(result.value * 8); + else + break; + } + return buffer; + }); + } + readSignedSync(length) { + const u = this.readSync(length); + const signBit = 2 ** (length - 1); + const mask = signBit - 1; + return (u & signBit) === 0 ? u : -((~(u - 1) & mask) >>> 0); + } + readFloatSync(length) { + if (length !== 32 && length !== 64) + throw new TypeError(`Invalid length (${length} bits) Only 4-byte (32 bit / single-precision) and 8-byte (64 bit / double-precision) IEEE 754 values are supported`); + if (!this.isAvailable(length)) + throw new Error(`underrun: Not enough bits are available (requested=${length}, available=${this.bufferedLength}, buffers=${this.buffers.length})`); + let buf2 = new ArrayBuffer(length / 8); + let view = new DataView(buf2); + for (let i = 0, max = buf2.byteLength; i < max; ++i) + view.setUint8(i, this.readSync(8)); + if (length === 32) + return view.getFloat32(0, false); + else if (length === 64) + return view.getFloat64(0, false); + } + readCoreSync(length, consume) { + this.ensureNoReadPending(); + let value = BigInt(0); + let remainingLength = length; + if (this.available < length) + throw new Error(`underrun: Not enough bits are available (requested=${length}, available=${this.bufferedLength}, buffers=${this.buffers.length})`); + this.adjustSkip(); + let offset = this._offsetIntoBuffer; + let bufferIndex = this._bufferIndex; + let bitLength = 0; + while (remainingLength > 0) { + if (bufferIndex >= this.buffers.length) + throw new Error(`Internal error: Buffer index out of range (index=${bufferIndex}, count=${this.buffers.length}), offset=${this.offset}, readLength=${length}, available=${this.available})`); + let buffer = this.buffers[bufferIndex]; + let byteOffset = Math.floor(offset / 8); + if (byteOffset >= buffer.length) + throw new Error(`Internal error: Current buffer (index ${bufferIndex}) has length ${buffer.length} but our position within the buffer is ${byteOffset}! offset=${this.offset}, bufs=${this.buffers.length}`); + let byte = BigInt(buffer[byteOffset]); + let bitOffset = offset % 8; + let bitContribution = Math.min(8 - bitOffset, remainingLength); + let mask = Math.pow(2, bitContribution) - 1; + value = value << BigInt(bitContribution) | byte >> BigInt(8) - BigInt(bitContribution) - BigInt(bitOffset) & BigInt(mask); + offset += bitContribution; + remainingLength -= bitContribution; + bitLength += bitContribution; + if (offset >= buffer.length * 8) { + bufferIndex += 1; + offset = 0; + } + } + if (consume) { + this.bufferedLength -= length; + this._offsetIntoBuffer = offset; + this._offset += bitLength; + this._bufferIndex = bufferIndex; + if (!this.retainBuffers) { + this.clean(); + } + } + return Number(value); + } + adjustSkip() { + if (this.skippedLength <= 0) + return; + while (this.buffers && this.skippedLength > this.buffers[0].length * 8 - this._offsetIntoBuffer) { + this.skippedLength -= this.buffers[0].length * 8 - this._offsetIntoBuffer; + this._offsetIntoBuffer = 0; + this.buffers.shift(); + } + if (this.buffers.length > 0) { + this._offsetIntoBuffer += this.skippedLength; + this.skippedLength = 0; + } + } + assure(length) { + this.ensureNoReadPending(); + if (this.bufferedLength >= length) { + return Promise.resolve(); + } + let request2 = { resolve: null, length, peek: true }; + let promise2 = new Promise((resolve2) => request2.resolve = resolve2); + this.blockedRequest = request2; + return promise2.then(() => { + }); + } + read(length) { + this.ensureNoReadPending(); + if (this.available >= length) { + return Promise.resolve(this.readSync(length)); + } else { + let request2 = { resolve: null, length, peek: false }; + let promise2 = new Promise((resolve2) => request2.resolve = resolve2); + this.blockedRequest = request2; + return promise2; + } + } + readSigned(length) { + this.ensureNoReadPending(); + if (this.available >= length) { + return Promise.resolve(this.readSignedSync(length)); + } else { + let request2 = { resolve: null, length, peek: false, signed: true }; + let promise2 = new Promise((resolve2) => request2.resolve = resolve2); + this.blockedRequest = request2; + return promise2; + } + } + readFloat(length) { + this.ensureNoReadPending(); + if (this.available >= length) { + return Promise.resolve(this.readFloatSync(length)); + } else { + let request2 = { resolve: null, length, peek: false, float: true }; + let promise2 = new Promise((resolve2) => request2.resolve = resolve2); + this.blockedRequest = request2; + return promise2; + } + } + peek(length) { + return __awaiter(this, void 0, void 0, function* () { + yield this.assure(length); + return this.peekSync(length); + }); + } + addBuffer(buffer) { + this.buffers.push(buffer); + this.bufferedLength += buffer.length * 8; + if (this.blockedRequest && this.blockedRequest.length <= this.available) { + let request2 = this.blockedRequest; + this.blockedRequest = null; + if (request2.peek) { + request2.resolve(0); + } else if (request2.signed) { + request2.resolve(this.readSignedSync(request2.length)); + } else if (request2.float) { + request2.resolve(this.readFloatSync(request2.length)); + } else { + request2.resolve(this.readSync(request2.length)); + } + } + } + }; + + // node_modules/@astronautlabs/bitstream/dist.esm/bitstream/string-encoding-options.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/bitstream/writer.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + var BitstreamWriter = class { + constructor(stream, bufferSize = 1) { + this.stream = stream; + this.bufferSize = bufferSize; + this.pendingByte = BigInt(0); + this.pendingBits = 0; + this.bufferedBytes = 0; + this._offset = 0; + this.textEncoder = new TextEncoder(); + this.buffer = new Uint8Array(bufferSize); + } + get offset() { + return this._offset; + } + get byteOffset() { + return this.pendingBits; + } + end() { + this.finishByte(); + this.flush(); + } + reset() { + this._offset = 0; + } + finishByte() { + if (this.pendingBits > 0) { + this.buffer[this.bufferedBytes++] = Number(this.pendingByte); + this.pendingBits = 0; + this.pendingByte = BigInt(0); + } + } + flush() { + if (this.bufferedBytes > 0) { + this.stream.write(Buffer2.from(this.buffer.slice(0, this.bufferedBytes))); + this.bufferedBytes = 0; + } + } + writeString(byteCount, value, encoding = "utf-8") { + if (encoding === "utf-8") { + let buffer = new Uint8Array(byteCount); + let strBuf = this.textEncoder.encode(value); + buffer.set(strBuf, 0); + this.writeBytes(buffer); + } else { + if (typeof Buffer2 === "undefined") { + throw new Error(`Encoding '${encoding}' is not supported: No Node.js Buffer implementation found, web standard TextEncoder only supports utf-8`); + } + let buffer = Buffer2.alloc(byteCount); + Buffer2.from(value, encoding).copy(buffer); + this.writeBuffer(buffer); + } + } + writeBuffer(buffer) { + this.writeBytes(buffer); + } + writeBytes(chunk, offset = 0, length) { + length !== null && length !== void 0 ? length : length = chunk.length - offset; + if (this.byteOffset === 0) { + while (chunk.length > 0) { + let writableLength = Math.min(chunk.length, this.buffer.length - this.bufferedBytes); + this.buffer.set(chunk.subarray(0, writableLength), this.bufferedBytes); + this.bufferedBytes += writableLength; + chunk = chunk.subarray(writableLength); + if (this.bufferedBytes >= this.buffer.length) + this.flush(); + } + return; + } + for (let i = offset, max = Math.min(chunk.length, offset + length); i < max; ++i) + this.write(8, chunk[i]); + } + min(a, b) { + if (a < b) + return a; + else + return b; + } + write(length, value) { + if (value === void 0 || value === null) + value = 0; + value = Number(value); + if (Number.isNaN(value)) + throw new Error(`Cannot write to bitstream: Value ${value} is not a number`); + if (!Number.isFinite(value)) + throw new Error(`Cannot write to bitstream: Value ${value} must be finite`); + let valueN = BigInt(value % Math.pow(2, length)); + let remainingLength = length; + while (remainingLength > 0) { + let shift = BigInt(8 - this.pendingBits - remainingLength); + let contribution = shift >= 0 ? valueN << shift : valueN >> -shift; + let writtenLength = Number(shift >= 0 ? remainingLength : this.min(-shift, BigInt(8 - this.pendingBits))); + this.pendingByte = this.pendingByte | contribution; + this.pendingBits += writtenLength; + this._offset += writtenLength; + remainingLength -= writtenLength; + valueN = valueN % BigInt(Math.pow(2, remainingLength)); + if (this.pendingBits === 8) { + this.finishByte(); + if (this.bufferedBytes >= this.buffer.length) { + this.flush(); + } + } + } + } + writeSigned(length, value) { + if (value === void 0 || value === null) + value = 0; + const originalValue = value; + const max = 2 ** (length - 1) - 1; + const min = -(2 ** (length - 1)); + value = Number(value); + if (Number.isNaN(value)) + throw new Error(`Cannot write to bitstream: Value ${originalValue} is not a number`); + if (!Number.isFinite(value)) + throw new Error(`Cannot write to bitstream: Value ${value} must be finite`); + if (value > max) + throw new TypeError(`Cannot represent ${value} in I${length} format: Value too large (min=${min}, max=${max})`); + if (value < min) + throw new TypeError(`Cannot represent ${value} in I${length} format: Negative value too small (min=${min}, max=${max})`); + return this.write(length, value >= 0 ? value : ~-value + 1 >>> 0); + } + writeFloat(length, value) { + if (length !== 32 && length !== 64) + throw new TypeError(`Invalid length (${length} bits) Only 4-byte (32 bit / single-precision) and 8-byte (64 bit / double-precision) IEEE 754 values are supported`); + let buf2 = new ArrayBuffer(length / 8); + let view = new DataView(buf2); + if (length === 32) + view.setFloat32(0, value); + else if (length === 64) + view.setFloat64(0, value); + for (let i = 0, max = buf2.byteLength; i < max; ++i) + this.write(8, view.getUint8(i)); + } + }; + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/index.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/array-options.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/array-serializer.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/resolve-length.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/structure-serializer.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/utils.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/boolean-options.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/boolean-serializer.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/buffer-options.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/buffer-serializer.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/element.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/common/index.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/common/buffered-writable.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/common/constructor.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/common/discriminant.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/common/writable.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/common/incomplete-read-result.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/element.js + var _parent; + var _readFields; + var _isBeingRead; + var _fieldBeingComputed; + var _fieldBeingComputedIntrospectable; + var SERIALIZE_WRITERS = Symbol("Writers used by Bitstream#serialize() for this element type."); + _parent = /* @__PURE__ */ new WeakMap(), _readFields = /* @__PURE__ */ new WeakMap(), _isBeingRead = /* @__PURE__ */ new WeakMap(), _fieldBeingComputed = /* @__PURE__ */ new WeakMap(), _fieldBeingComputedIntrospectable = /* @__PURE__ */ new WeakMap(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/field-definition.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/field-options.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/field.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/null-serializer.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/number-serializer.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/string-serializer.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/length-determinant.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/number-options.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/serializer.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/value-determinant.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/variant-definition.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/variant-options.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/variant.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/reserved.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/reserved-low.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/marker.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // src/bitstream.ts + var revbyte = (n, len = 8) => { + let acc = 0; + let n2 = n; + let len2 = len; + while (len2) { + acc = acc * 2 + (n2 & 1); + n2 >>= 1; + len2--; + } + return acc; + }; + var BitstreamReader2 = class extends BitstreamReader { + constructor() { + super(...arguments); + this.rtotal = 0; + } + addBuffer(hidden) { + const inp = Buffer2.from(hidden); + for (let i = 0; i < inp.byteLength; ++i) + inp[i] = revbyte(inp[i]); + super.addBuffer(inp); + } + readSync(len) { + const v = super.readSync(len); + this.rtotal += len; + return revbyte(v, len); + } + }; + var BitstreamWriter2 = class extends BitstreamWriter { + constructor(w) { + super({ + write: (c) => { + const inp = Buffer2.from(c); + for (let i = 0; i < inp.byteLength; ++i) + inp[i] = revbyte(inp[i]); + this.w.write(inp); + } + }); + this.w = w; + this.wtotal = 0; + } + write(length, value) { + this.wtotal += length; + if (length) { + value = revbyte(value, length); + } + super.write(length, value); + } + }; + + // src/dh-deflate.ts + init_define_BUILD_VERSION(); + init_esbuild_inject(); + var TINF_OK = 0; + var Tree = class { + constructor() { + this.table = new Uint16Array(16); + this.trans = new Uint16Array(288); + } + }; + var getPathTo = (tree, value) => { + if (tree[0] === value) + return "0"; + if (tree[1] === value) + return "1"; + let p; + if (typeof tree[0] != "number") + p = getPathTo(tree[0], value); + let b = "0"; + if (!p) { + if (tree[1] && typeof tree[1] != "number") + p = getPathTo(tree[1], value); + b = "1"; + } + if (p) + return b + p; + }; + function buildHuffmanTable(codeLengths, values) { + let k = 0, code = [], i, j, length = 16; + while (length > 0 && !codeLengths[length - 1]) + length--; + code.push({ children: [], index: 0 }); + let p = code[0], q; + for (i = 0; i < length; i++) { + for (j = 0; j < codeLengths[i]; j++) { + p = code.pop(); + p.children[p.index] = values[k]; + while (p.index > 0) { + if (code.length === 0) + throw new Error("Could not recreate Huffman Table"); + p = code.pop(); + } + p.index++; + code.push(p); + while (code.length <= i) { + code.push(q = { children: [], index: 0 }); + p.children[p.index] = q.children; + p = q; + } + k++; + } + if (i + 1 < length) { + code.push(q = { children: [], index: 0 }); + p.children[p.index] = q.children; + p = q; + } + } + return code[0].children; + } + var Data = class { + constructor(source, dests, to_hide, hidden) { + this.source = source; + this.dests = dests; + this.to_hide = to_hide; + this.hidden = hidden; + this.dest = []; + this.ltree = new Tree(); + this.dtree = new Tree(); + } + computeReverse() { + this.rltree = buildHuffmanTable(this.ltree.table, this.ltree.trans)[0]; + this.rdtree = buildHuffmanTable(this.dtree.table, this.dtree.trans)[0]; + } + }; + var sltree = new Tree(); + var sdtree = new Tree(); + var rltree; + var rdtree; + var length_bits = new Uint8Array(30); + var length_base = new Uint16Array(30); + var dist_bits = new Uint8Array(30); + var dist_base = new Uint16Array(30); + var clcidx = new Uint8Array([ + 16, + 17, + 18, + 0, + 8, + 7, + 9, + 6, + 10, + 5, + 11, + 4, + 12, + 3, + 13, + 2, + 14, + 1, + 15 + ]); + var code_tree = new Tree(); + var lengths = new Uint8Array(288 + 32); + function tinf_build_bits_base(bits, base, delta, first) { + let i, sum; + for (i = 0; i < delta; ++i) + bits[i] = 0; + for (i = 0; i < 30 - delta; ++i) + bits[i + delta] = i / delta | 0; + for (sum = first, i = 0; i < 30; ++i) { + base[i] = sum; + sum += 1 << bits[i]; + } + } + function tinf_build_fixed_trees(lt, dt) { + let i; + for (i = 0; i < 7; ++i) + lt.table[i] = 0; + lt.table[7] = 24; + lt.table[8] = 152; + lt.table[9] = 112; + for (i = 0; i < 24; ++i) + lt.trans[i] = 256 + i; + for (i = 0; i < 144; ++i) + lt.trans[24 + i] = i; + for (i = 0; i < 8; ++i) + lt.trans[24 + 144 + i] = 280 + i; + for (i = 0; i < 112; ++i) + lt.trans[24 + 144 + 8 + i] = 144 + i; + for (i = 0; i < 5; ++i) + dt.table[i] = 0; + dt.table[5] = 32; + for (i = 0; i < 32; ++i) + dt.trans[i] = i; + } + var offs = new Uint16Array(16); + function tinf_build_tree(t, lengths2, off, num) { + let i, sum; + for (i = 0; i < 16; ++i) + t.table[i] = 0; + for (i = 0; i < num; ++i) + t.table[lengths2[off + i]]++; + t.table[0] = 0; + for (sum = 0, i = 0; i < 16; ++i) { + offs[i] = sum; + sum += t.table[i]; + } + for (i = 0; i < num; ++i) { + if (lengths2[off + i]) + t.trans[offs[lengths2[off + i]]++] = i; + } + } + function tinf_getbit(d) { + return d.source.readSync(1); + } + function tinf_read_bits(d, num, base) { + if (!num) + return base; + const v = d.source.readSync(num) + base; + return v; + } + function tinf_decode_symbol(d, t, copy = true, ext = {}) { + let sum = 0, cur = 0, len = 0; + let s = 0; + do { + const b = d.source.readSync(1); + copy && d.hidden.write(1, b); + s = s << 1 | b; + cur = 2 * cur + b; + ++len; + sum += t.table[len]; + cur -= t.table[len]; + } while (cur >= 0); + ext.length = len; + ext.sym = s; + return t.trans[sum + cur]; + } + function tinf_decode_trees(d, lt, dt) { + let i, num, length; + const hlit = tinf_read_bits(d, 5, 257); + d.hidden?.write(5, hlit - 257); + const hdist = tinf_read_bits(d, 5, 1); + d.hidden?.write(5, hdist - 1); + const hclen = tinf_read_bits(d, 4, 4); + d.hidden?.write(4, hclen - 4); + for (i = 0; i < 19; ++i) + lengths[i] = 0; + for (i = 0; i < hclen; ++i) { + const clen = tinf_read_bits(d, 3, 0); + d.hidden?.write(3, clen); + lengths[clcidx[i]] = clen; + } + tinf_build_tree(code_tree, lengths, 0, 19); + for (num = 0; num < hlit + hdist; ) { + const sym = tinf_decode_symbol(d, code_tree); + let prev; + switch (sym) { + case 16: + prev = lengths[num - 1]; + length = tinf_read_bits(d, 2, 3); + d.hidden?.write(2, length - 3); + for (; length; --length) { + lengths[num++] = prev; + } + break; + case 17: + length = tinf_read_bits(d, 3, 3); + d.hidden?.write(3, length - 3); + for (; length; --length) { + lengths[num++] = 0; + } + break; + case 18: + length = tinf_read_bits(d, 7, 11); + d.hidden?.write(7, length - 11); + for (; length; --length) { + lengths[num++] = 0; + } + break; + default: + lengths[num++] = sym; + break; + } + } + tinf_build_tree(lt, lengths, 0, hlit); + tinf_build_tree(dt, lengths, hlit, hdist); + } + var get_symbol = (value, bits_table, base_table) => { + let i = 0; + for (i = 0; i < base_table.length; ++i) { + if (base_table[i] > value) { + i--; + return [i, bits_table[i], value - base_table[i]]; + } + } + i--; + return [i, bits_table[i], value - base_table[i]]; + }; + var encode_symbol = (sym, tree) => { + const code = getPathTo(tree, sym); + return { + length: code?.length, + val: parseInt(code, 2) + }; + }; + var capacity = 0; + function tinf_inflate_block_data(d, lt, dt) { + let finished = false; + while (1) { + if (finished) { + return true; + } + let sym = tinf_decode_symbol(d, lt); + if (sym === 256) { + return TINF_OK; + } + if (sym < 256) { + d.dest.push(sym); + } else { + sym -= 257; + const length = tinf_read_bits(d, length_bits[sym], length_base[sym]); + if (length_bits[sym]) + d.hidden.write(length_bits[sym], length - length_base[sym]); + const ext = { length: 0, sym: 0 }; + const dist = tinf_decode_symbol(d, dt, false, ext); + let backoffset = tinf_read_bits(d, dist_bits[dist], dist_base[dist]); + const offs2 = d.dest.length - backoffset; + const match = Buffer2.from(d.dest.slice(offs2, offs2 + length)); + if (match.length == length) { + let begin = d.dest.length - 32768; + if (begin < 0) + begin = 0; + let matches = []; + let o = 0; + const slic = Buffer2.from(d.dest.slice(begin + o, d.dest.length)); + while (begin + o < d.dest.length) { + const r = slic.slice(o, d.dest.length).indexOf(match); + if (r >= 0) { + matches.push(r + begin + o); + o += r; + } else { + break; + } + o++; + } + if (matches.length > 1) { + matches = matches.map((e) => -(e - d.dest.length)); + matches.reverse(); + const v = Math.floor(Math.log2(matches.length)); + capacity += v; + if (d.to_hide instanceof BitstreamReader2) { + if (d.to_hide.available) { + const s = d.to_hide.readSync(Math.min(d.to_hide.available, v)); + backoffset = matches[s]; + } else { + finished = true; + } + } else { + const idx = matches.indexOf(backoffset); + d.to_hide.write(v, idx); + } + } + } + const [dsym, dlen, doff] = get_symbol(backoffset, dist_bits, dist_base); + const encdist = encode_symbol(dsym, d.rdtree); + d.hidden.write(encdist.length, revbyte(encdist.val, encdist.length)); + d.hidden.write(dlen, doff); + for (let i = offs2; i < offs2 + length; ++i) { + d.dest.push(d.dest[i]); + } + } + } + } + function tinf_inflate_uncompressed_block(d) { + const length = d.source.readSync(16); + const invlength = d.source.readSync(16); + if (length !== (~invlength & 65535)) + return -4; + for (let i = length; i; --i) + d.dest.push(d.source.readSync(8)); + return TINF_OK; + } + function tinf_uncompress(source, decompressed, to_hide, hidden) { + const decomp = new BitstreamWriter2({ write: decompressed || (() => { + }) }); + const hid = new BitstreamWriter2({ write: hidden || (() => { + }) }); + const d = new Data(source, decomp, to_hide, hid); + let res; + let bfinal, btype; + do { + if (to_hide instanceof BitstreamReader2) { + if (to_hide.available == 0) { + while (source.available && source.offset & 7) { + hid.write(1, source.readSync(1)); + } + return source.offset >> 3; + } + } + bfinal = tinf_getbit(d); + d.hidden.write(1, bfinal); + btype = tinf_read_bits(d, 2, 0); + d.hidden?.write(2, btype); + switch (btype) { + case 0: + res = tinf_inflate_uncompressed_block(d); + break; + case 1: + d.rdtree = rdtree; + d.rltree = rltree; + res = tinf_inflate_block_data(d, sltree, sdtree); + if (res === true) { + continue; + } + break; + case 2: + tinf_decode_trees(d, d.ltree, d.dtree); + d.computeReverse(); + res = tinf_inflate_block_data(d, d.ltree, d.dtree); + if (res === true) { + continue; + } + break; + default: + res = -2; + } + if (res !== TINF_OK) + throw new Error("Data error " + res); + } while (!bfinal); + decomp.end(); + hid.end(); + } + tinf_build_fixed_trees(sltree, sdtree); + tinf_build_bits_base(length_bits, length_base, 4, 3); + tinf_build_bits_base(dist_bits, dist_base, 2, 1); + rltree = buildHuffmanTable(sltree.table, sltree.trans)[0]; + rdtree = buildHuffmanTable(sdtree.table, sdtree.trans)[0]; + length_bits[28] = 0; + length_base[28] = 258; + + // src/pngv3.ts var csettings2; settings.subscribe((b) => { csettings2 = b; @@ -16675,14 +17738,40 @@ "t": "take-me-to.space", "z": "z.zz.fo" }; + var extractFromRawDeflate = (b) => { + const src = new BitstreamReader2(); + src.addBuffer(b); + const chnks = []; + const hidden = new BitstreamWriter2({ + write(chunk) { + for (const i of chunk) { + if (i) + chnks.push(i); + else + throw "Finish"; + } + } + }); + try { + tinf_uncompress(src, () => { + }, hidden, () => { + }); + } catch (e) { + if (e == "Finish") + return import_buffer3.Buffer.from(chnks); + } + return false; + }; var extract = async (png) => { const reader = BufferReadStream(png).getReader(); - const sneed = new PNGDecoder(reader); + const sneed = new PNGDecoder(reader, false); const ret = []; let w; if (!csettings2) throw new Error("Settings uninit"); try { + let complete = false; + const idats = []; for await (const [name, chunk, crc, offset] of sneed.chunks()) { let buff; switch (name) { @@ -16729,12 +17818,27 @@ } break; case "IDAT": + if (ret.length) + return ret; + buff = await chunk(); + idats.push(buff.slice(4)); case "IEND": - return ret.slice(0, csettings2.maxe); + complete = true; default: break; } } + if (idats.length) { + let decoded; + if ((decoded = extractFromRawDeflate(import_buffer3.Buffer.concat(idats).slice(2))) === false) + return false; + const dec = decoded.toString().split(" ").map((e) => { + if (!(e[0] in rprefs)) + throw "Uhh"; + return `https://${rprefs[e[0]]}/${e.slice(1)}`; + }).join(" "); + return decodeCoom3Payload(import_buffer3.Buffer.from(dec)); + } } catch (e) { console.error(e); } finally { @@ -16756,46 +17860,85 @@ }); return [ret, () => b]; }; + var embedInRawDeflate = (b, h) => { + const src = new BitstreamReader2(); + const hid = new BitstreamReader2(); + hid.addBuffer(h); + src.addBuffer(b); + const chnks = []; + const endo = tinf_uncompress(src, () => { + }, hid, (c) => chnks.push(c)); + if (endo) + chnks.push(b.slice(endo)); + return import_buffer3.Buffer.concat(chnks); + }; var inject_data = async (container, injb) => { if (!csettings2) throw new Error("Settings uninit"); - let magic4 = false; + if (csettings2.pmeth < 5) { + let magic4 = false; + const [writestream2, extract8] = BufferWriteStream2(); + const encoder = new PNGEncoder(writestream2); + const decoder = new PNGDecoder(container.stream().getReader()); + for await (const [name, chunk, crc, offset] of decoder.chunks()) { + if (magic4 && name != "IDAT") + break; + if (!magic4 && name == "IDAT") { + const passed = import_buffer3.Buffer.from(injb); + switch (csettings2.pmeth) { + case 0: + await encoder.insertchunk(["tEXt", async () => buildChunk("tEXt", import_buffer3.Buffer.concat([CUM3, passed])), () => Promise.resolve(0), 0]); + break; + case 1: + xor(passed, password); + await encoder.insertchunk(["tEXt", async () => buildChunk("tEXt", import_buffer3.Buffer.concat([CUM4, import_buffer3.Buffer.from(import_buffer3.Buffer.from(passed).toString("base64"))])), () => Promise.resolve(0), 0]); + break; + case 2: + await encoder.insertchunk(["tEXt", async () => buildChunk("tEXt", import_buffer3.Buffer.concat([CUM5, import_buffer3.Buffer.from(import_buffer3.Buffer.from(passed).toString("base64"))])), () => Promise.resolve(0), 0]); + break; + case 3: + await encoder.insertchunk(["tEXt", async () => buildChunk("tEXt", import_buffer3.Buffer.concat([CUM6, import_buffer3.Buffer.from(import_buffer3.Buffer.from(passed).toString("base64"))])), () => Promise.resolve(0), 0]); + break; + case 4: + await encoder.insertchunk(["tEXt", async () => buildChunk("tEXt", import_buffer3.Buffer.concat([CUM7, import_buffer3.Buffer.from(bs58.encode(passed))])), () => Promise.resolve(0), 0]); + break; + } + magic4 = true; + } + await encoder.insertchunk([name, chunk, crc, offset]); + } + await encoder.insertchunk([ + "IEND", + async () => Promise.resolve(buildChunk("IEND", import_buffer3.Buffer.from([]))), + async () => Promise.resolve(0), + 0 + ]); + return extract8(); + } + let pdec = new PNGDecoder(container.stream().getReader()); + const concat = []; + for await (const chk of pdec.chunks()) + if (chk[0] == "IDAT") + concat.push((await chk[1]()).slice(4)); + const comp = import_buffer3.Buffer.concat(concat); + const head = comp.slice(0, 2); + const chksum = comp.slice(-4); + const idatblk = embedInRawDeflate(comp.slice(2, -4), injb); + const bws = BufferWriteStream2(); const [writestream, extract7] = BufferWriteStream2(); - const encoder = new PNGEncoder(writestream); - const decoder = new PNGDecoder(container.stream().getReader()); - for await (const [name, chunk, crc, offset] of decoder.chunks()) { - if (magic4 && name != "IDAT") - break; - if (!magic4 && name == "IDAT") { - const passed = import_buffer3.Buffer.from(injb); - switch (csettings2.pmeth) { - case 0: - await encoder.insertchunk(["tEXt", async () => buildChunk("tEXt", import_buffer3.Buffer.concat([CUM3, passed])), () => Promise.resolve(0), 0]); - break; - case 1: - xor(passed, password); - await encoder.insertchunk(["tEXt", async () => buildChunk("tEXt", import_buffer3.Buffer.concat([CUM4, import_buffer3.Buffer.from(import_buffer3.Buffer.from(passed).toString("base64"))])), () => Promise.resolve(0), 0]); - break; - case 2: - await encoder.insertchunk(["tEXt", async () => buildChunk("tEXt", import_buffer3.Buffer.concat([CUM5, import_buffer3.Buffer.from(import_buffer3.Buffer.from(passed).toString("base64"))])), () => Promise.resolve(0), 0]); - break; - case 3: - await encoder.insertchunk(["tEXt", async () => buildChunk("tEXt", import_buffer3.Buffer.concat([CUM6, import_buffer3.Buffer.from(import_buffer3.Buffer.from(passed).toString("base64"))])), () => Promise.resolve(0), 0]); - break; - case 4: - await encoder.insertchunk(["tEXt", async () => buildChunk("tEXt", import_buffer3.Buffer.concat([CUM7, import_buffer3.Buffer.from(bs58.encode(passed))])), () => Promise.resolve(0), 0]); - break; + const penc = new PNGEncoder(writestream); + pdec = new PNGDecoder(container.stream().getReader()); + let ins = false; + for await (const chk of pdec.chunks()) { + if (chk[0] != "IDAT") { + await penc.insertchunk(chk); + } else { + if (!ins) { + await penc.insertchunk(["IDAT", async () => import_buffer3.Buffer.concat([import_buffer3.Buffer.from("IDAT"), head, idatblk, chksum]), () => Promise.resolve(0), 0]); + ins = true; } - magic4 = true; } - await encoder.insertchunk([name, chunk, crc, offset]); } - await encoder.insertchunk([ - "IEND", - async () => Promise.resolve(buildChunk("IEND", import_buffer3.Buffer.from([]))), - async () => Promise.resolve(0), - 0 - ]); return extract7(); }; var inject = async (container, links) => { @@ -16812,49 +17955,8 @@ return inject_data(container, injb); }; var has_embed = async (png) => { - const reader = BufferReadStream(png).getReader(); - const sneed = new PNGDecoder(reader); - try { - for await (const [name, chunk, crc, offset] of sneed.chunks()) { - let buff; - switch (name) { - case "tEXt": - buff = await chunk(); - if (buff.slice(4, 4 + CUM3.length).equals(CUM3)) - return true; - if (buff.slice(4, 4 + CUM4.length).equals(CUM4)) - return true; - if (buff.slice(4, 4 + CUM5.length).equals(CUM5)) - return true; - if (buff.slice(4, 4 + CUM6.length).equals(CUM6)) { - const passed = buff.slice(4 + CUM6.length).toString(); - if (passed.match(/^[0-9a-zA-Z+/=]+$/g)) { - if (import_buffer3.Buffer.from(passed, "base64").toString().split(" ").every((l) => l[0] in rprefs)) - return true; - } - } - if (buff.slice(4, 4 + CUM7.length).equals(CUM7)) { - const passed = buff.slice(4 + CUM7.length).toString(); - if (passed.match(/^[0-9a-zA-Z+/=]+$/g)) { - if (import_buffer3.Buffer.from(passed, "base64").toString().split(" ").every((l) => l[0] in rprefs)) - return true; - if (import_buffer3.Buffer.from(bs58.decode(passed)).toString().split(" ").every((l) => l[0] in rprefs)) - return true; - } - } - break; - case "IDAT": - case "IEND": - return false; - default: - break; - } - } - } catch (e) { - return; - } finally { - reader.releaseLock(); - } + const r = await extract(png); + return !!r; }; var pngv3_default = { extract, @@ -23383,9 +24485,9 @@ let select; let mounted; let dispose; - let each_value = [0, 1, 2, 3, 4]; + let each_value = [0, 1, 2, 3, 4, 5]; let each_blocks = []; - for (let i = 0; i < 5; i += 1) { + for (let i = 0; i < 6; i += 1) { each_blocks[i] = create_each_block2(get_each_context2(ctx, each_value, i)); } return { @@ -23393,7 +24495,7 @@ label = element("label"); t = text("PNG Embedding method\n "); select = element("select"); - for (let i = 0; i < 5; i += 1) { + for (let i = 0; i < 6; i += 1) { each_blocks[i].c(); } if (ctx[7].pmeth === void 0) @@ -23403,7 +24505,7 @@ insert(target, label, anchor); append(label, t); append(label, select); - for (let i = 0; i < 5; i += 1) { + for (let i = 0; i < 6; i += 1) { each_blocks[i].m(select, null); } select_option(select, ctx[7].pmeth); diff --git a/efdb47d2f0e04144bbaa-0.281.xpi b/efdb47d2f0e04144bbaa-0.281.xpi new file mode 100644 index 0000000..e41b4d6 Binary files /dev/null and b/efdb47d2f0e04144bbaa-0.281.xpi differ diff --git a/firefox/dist/main.js b/firefox/dist/main.js index 0a5f323..0bb6220 100644 --- a/firefox/dist/main.js +++ b/firefox/dist/main.js @@ -73,7 +73,7 @@ var define_BUILD_VERSION_default; var init_define_BUILD_VERSION = __esm({ ""() { - define_BUILD_VERSION_default = [0, 279]; + define_BUILD_VERSION_default = [0, 281]; } }); @@ -12109,7 +12109,7 @@ var dctSqrt1d2 = 2896; function constructor() { } - function buildHuffmanTable(codeLengths, values) { + function buildHuffmanTable2(codeLengths, values) { var k = 0, code = [], i, j, length = 16; while (length > 0 && !codeLengths[length - 1]) length--; @@ -12745,7 +12745,7 @@ for (j = 0; j < codeLengthSum; j++, offset++) huffmanValues[j] = data[offset]; i += 17 + codeLengthSum; - (huffmanTableSpec >> 4 === 0 ? huffmanTablesDC : huffmanTablesAC)[huffmanTableSpec & 15] = buildHuffmanTable(codeLengths, huffmanValues); + (huffmanTableSpec >> 4 === 0 ? huffmanTablesDC : huffmanTablesAC)[huffmanTableSpec & 15] = buildHuffmanTable2(codeLengths, huffmanValues); } break; case 65501: @@ -13956,7 +13956,14 @@ // src/stores.ts var localLoad = async (key2, def) => { const isinls = "__pee__" + key2 in localStorage; - const ret = isinls ? { ...def, ...JSON.parse(localStorage.getItem("__pee__" + key2)) } : def; + let ret; + if (isinls) { + let it = localStorage.getItem("__pee__" + key2); + if (it === "undefined") + it = null; + ret = { ...def, ...JSON.parse(it || "{}") }; + } else + ret = def; if (true) { if (isinls) { delete localStorage["__pee__" + key2]; @@ -13980,7 +13987,7 @@ var initial_settings = localLoad("settingsv2", { loop: true, dh: false, - pmeth: 4, + pmeth: 5, xpv: false, xpi: false, hyd: false, @@ -14125,8 +14132,10 @@ var import_crc_32 = __toESM(require_crc32(), 1); var import_buffer = __toESM(require_buffer(), 1); var PNGDecoder = class { - constructor(reader) { + constructor(reader, strict = true) { this.reader = reader; + this.strict = strict; + this.stopped = false; this.req = 8; this.ptr = 8; this.repr = import_buffer.Buffer.from([]); @@ -14135,7 +14144,10 @@ while (this.repr.byteLength < this.req) { const chunk = await this.reader.read(); if (chunk.done) { - throw new Error(`Unexpected EOF, got ${this.repr.byteLength}, required ${this.req}, ${chunk.value}`); + this.stopped = true; + if (this.strict) + throw new Error(`Unexpected EOF, got ${this.repr.byteLength}, required ${this.req}, ${chunk.value}`); + return; } this.repr = import_buffer.Buffer.concat([this.repr, chunk.value]); } @@ -14144,6 +14156,8 @@ while (true) { this.req += 8; await this.catchup(); + if (this.stopped) + break; const length = this.repr.readUInt32BE(this.ptr); const name = this.repr.slice(this.ptr + 4, this.ptr + 8).toString(); this.ptr += 4; @@ -14162,6 +14176,8 @@ this.ptr ]; this.ptr += length + 8; + if (this.stopped) + break; if (name == "IEND") break; } @@ -16555,11 +16571,15 @@ cthreadDataCache = newval; }); var refreshThreadDataCache = async (board, op) => { + console.log("refreshing thread info cache..."); threadDataCache.set(await getThreadInfo(board, op)); }; var getThreadDataCache = async (board, op) => { if (!cthreadDataCache) await refreshThreadDataCache(board, op); + else { + console.log("skipped thread cache refresh..."); + } return threadDataCache; }; var getEmbedsFromCache = async (board, op, pid) => { @@ -16771,6 +16791,1056 @@ // src/pngv3.ts var bs58 = __toESM(require_bs58(), 1); + + // src/bitstream.ts + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/index.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/bitstream/index.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/bitstream/reader.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + var __awaiter = function(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function(resolve2) { + resolve2(value); + }); + } + return new (P || (P = Promise))(function(resolve2, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve2(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + var BitstreamReader = class { + constructor() { + this.buffers = []; + this.bufferedLength = 0; + this.blockedRequest = null; + this._offsetIntoBuffer = 0; + this._bufferIndex = 0; + this._offset = 0; + this._spentBufferSize = 0; + this.retainBuffers = false; + this.textDecoder = new TextDecoder(); + this.skippedLength = 0; + } + get bufferIndex() { + return this._bufferIndex; + } + get offset() { + return this._offset; + } + get spentBufferSize() { + return this._spentBufferSize; + } + set offset(value) { + if (value < this._spentBufferSize) { + throw new Error(`Offset ${value} points into a discarded buffer! If you need to seek backwards outside the current buffer, make sure to set retainBuffers=true`); + } + let offsetIntoBuffer = value - this._spentBufferSize; + let bufferIndex = 0; + for (let i = 0, max = this.buffers.length; i < max; ++i) { + let buf2 = this.buffers[i]; + let size = buf2.length * 8; + if (offsetIntoBuffer < size) { + this._bufferIndex = bufferIndex; + this._offset = value; + this._offsetIntoBuffer = offsetIntoBuffer; + this.bufferedLength = buf2.length * 8 - this._offsetIntoBuffer; + for (let j = i + 1; j < max; ++j) + this.bufferedLength += this.buffers[j].length * 8; + return; + } + offsetIntoBuffer -= size; + ++bufferIndex; + } + } + clean(count) { + let buffers = this.buffers.splice(0, count !== void 0 ? Math.min(count, this._bufferIndex) : this._bufferIndex); + this._spentBufferSize += buffers.map((b) => b.length * 8).reduce((pv, cv) => pv + cv, 0); + this._bufferIndex -= buffers.length; + } + get available() { + return this.bufferedLength - this.skippedLength; + } + isAvailable(length) { + return this.bufferedLength >= length; + } + ensureNoReadPending() { + if (this.blockedRequest) + throw new Error(`Only one read() can be outstanding at a time.`); + } + readString(length, options) { + return __awaiter(this, void 0, void 0, function* () { + this.ensureNoReadPending(); + yield this.assure(8 * length); + return this.readStringSync(length, options); + }); + } + readStringSync(length, options) { + var _a, _b; + if (!options) + options = {}; + this.ensureNoReadPending(); + let buffer = new Uint8Array(length); + let firstTerminator = -1; + let charLength = 1; + let encoding = (_a = options.encoding) !== null && _a !== void 0 ? _a : "utf-8"; + if (["utf16le", "ucs-2", "ucs2"].includes(encoding)) { + charLength = 2; + } + for (let i = 0, max = length; i < max; ++i) { + buffer[i] = this.readSync(8); + } + for (let i = 0, max = length; i < max; i += charLength) { + let char = buffer[i]; + if (charLength === 2) + char = char << 8 | ((_b = buffer[i + 1]) !== null && _b !== void 0 ? _b : 0); + if (char === 0) { + firstTerminator = i; + break; + } + } + if (options.nullTerminated !== false) { + if (firstTerminator >= 0) { + buffer = buffer.subarray(0, firstTerminator); + } + } + if (encoding === "utf-8") { + return this.textDecoder.decode(buffer); + } else { + if (typeof Buffer2 === "undefined") + throw new Error(`Encoding '${encoding}' is not supported: No Node.js Buffer implementation and TextDecoder only supports utf-8`); + return Buffer2.from(buffer).toString(encoding); + } + } + peekSync(length) { + return this.readCoreSync(length, false); + } + skip(length) { + this.skippedLength += length; + } + readSync(length) { + return this.readCoreSync(length, true); + } + *readBytes(buffer, offset = 0, length) { + length !== null && length !== void 0 ? length : length = buffer.length - offset; + for (let i = offset, max = Math.min(buffer.length, offset + length); i < max; ++i) { + if (!this.isAvailable(8)) + yield max - i; + buffer[i] = this.readSync(8); + } + return buffer; + } + readBytesSync(buffer, offset = 0, length) { + length !== null && length !== void 0 ? length : length = buffer.length - offset; + let gen = this.readBytes(buffer, offset, length); + while (true) { + let result = gen.next(); + if (result.done === false) + throw new Error(`underrun: Not enough bits are available (requested ${length} bytes)`); + else + break; + } + return buffer; + } + readBytesBlocking(buffer, offset = 0, length) { + return __awaiter(this, void 0, void 0, function* () { + length !== null && length !== void 0 ? length : length = buffer.length - offset; + let gen = this.readBytes(buffer, offset, length); + while (true) { + let result = gen.next(); + if (result.done === false) + yield this.assure(result.value * 8); + else + break; + } + return buffer; + }); + } + readSignedSync(length) { + const u = this.readSync(length); + const signBit = 2 ** (length - 1); + const mask = signBit - 1; + return (u & signBit) === 0 ? u : -((~(u - 1) & mask) >>> 0); + } + readFloatSync(length) { + if (length !== 32 && length !== 64) + throw new TypeError(`Invalid length (${length} bits) Only 4-byte (32 bit / single-precision) and 8-byte (64 bit / double-precision) IEEE 754 values are supported`); + if (!this.isAvailable(length)) + throw new Error(`underrun: Not enough bits are available (requested=${length}, available=${this.bufferedLength}, buffers=${this.buffers.length})`); + let buf2 = new ArrayBuffer(length / 8); + let view = new DataView(buf2); + for (let i = 0, max = buf2.byteLength; i < max; ++i) + view.setUint8(i, this.readSync(8)); + if (length === 32) + return view.getFloat32(0, false); + else if (length === 64) + return view.getFloat64(0, false); + } + readCoreSync(length, consume) { + this.ensureNoReadPending(); + let value = BigInt(0); + let remainingLength = length; + if (this.available < length) + throw new Error(`underrun: Not enough bits are available (requested=${length}, available=${this.bufferedLength}, buffers=${this.buffers.length})`); + this.adjustSkip(); + let offset = this._offsetIntoBuffer; + let bufferIndex = this._bufferIndex; + let bitLength = 0; + while (remainingLength > 0) { + if (bufferIndex >= this.buffers.length) + throw new Error(`Internal error: Buffer index out of range (index=${bufferIndex}, count=${this.buffers.length}), offset=${this.offset}, readLength=${length}, available=${this.available})`); + let buffer = this.buffers[bufferIndex]; + let byteOffset = Math.floor(offset / 8); + if (byteOffset >= buffer.length) + throw new Error(`Internal error: Current buffer (index ${bufferIndex}) has length ${buffer.length} but our position within the buffer is ${byteOffset}! offset=${this.offset}, bufs=${this.buffers.length}`); + let byte = BigInt(buffer[byteOffset]); + let bitOffset = offset % 8; + let bitContribution = Math.min(8 - bitOffset, remainingLength); + let mask = Math.pow(2, bitContribution) - 1; + value = value << BigInt(bitContribution) | byte >> BigInt(8) - BigInt(bitContribution) - BigInt(bitOffset) & BigInt(mask); + offset += bitContribution; + remainingLength -= bitContribution; + bitLength += bitContribution; + if (offset >= buffer.length * 8) { + bufferIndex += 1; + offset = 0; + } + } + if (consume) { + this.bufferedLength -= length; + this._offsetIntoBuffer = offset; + this._offset += bitLength; + this._bufferIndex = bufferIndex; + if (!this.retainBuffers) { + this.clean(); + } + } + return Number(value); + } + adjustSkip() { + if (this.skippedLength <= 0) + return; + while (this.buffers && this.skippedLength > this.buffers[0].length * 8 - this._offsetIntoBuffer) { + this.skippedLength -= this.buffers[0].length * 8 - this._offsetIntoBuffer; + this._offsetIntoBuffer = 0; + this.buffers.shift(); + } + if (this.buffers.length > 0) { + this._offsetIntoBuffer += this.skippedLength; + this.skippedLength = 0; + } + } + assure(length) { + this.ensureNoReadPending(); + if (this.bufferedLength >= length) { + return Promise.resolve(); + } + let request2 = { resolve: null, length, peek: true }; + let promise2 = new Promise((resolve2) => request2.resolve = resolve2); + this.blockedRequest = request2; + return promise2.then(() => { + }); + } + read(length) { + this.ensureNoReadPending(); + if (this.available >= length) { + return Promise.resolve(this.readSync(length)); + } else { + let request2 = { resolve: null, length, peek: false }; + let promise2 = new Promise((resolve2) => request2.resolve = resolve2); + this.blockedRequest = request2; + return promise2; + } + } + readSigned(length) { + this.ensureNoReadPending(); + if (this.available >= length) { + return Promise.resolve(this.readSignedSync(length)); + } else { + let request2 = { resolve: null, length, peek: false, signed: true }; + let promise2 = new Promise((resolve2) => request2.resolve = resolve2); + this.blockedRequest = request2; + return promise2; + } + } + readFloat(length) { + this.ensureNoReadPending(); + if (this.available >= length) { + return Promise.resolve(this.readFloatSync(length)); + } else { + let request2 = { resolve: null, length, peek: false, float: true }; + let promise2 = new Promise((resolve2) => request2.resolve = resolve2); + this.blockedRequest = request2; + return promise2; + } + } + peek(length) { + return __awaiter(this, void 0, void 0, function* () { + yield this.assure(length); + return this.peekSync(length); + }); + } + addBuffer(buffer) { + this.buffers.push(buffer); + this.bufferedLength += buffer.length * 8; + if (this.blockedRequest && this.blockedRequest.length <= this.available) { + let request2 = this.blockedRequest; + this.blockedRequest = null; + if (request2.peek) { + request2.resolve(0); + } else if (request2.signed) { + request2.resolve(this.readSignedSync(request2.length)); + } else if (request2.float) { + request2.resolve(this.readFloatSync(request2.length)); + } else { + request2.resolve(this.readSync(request2.length)); + } + } + } + }; + + // node_modules/@astronautlabs/bitstream/dist.esm/bitstream/string-encoding-options.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/bitstream/writer.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + var BitstreamWriter = class { + constructor(stream, bufferSize = 1) { + this.stream = stream; + this.bufferSize = bufferSize; + this.pendingByte = BigInt(0); + this.pendingBits = 0; + this.bufferedBytes = 0; + this._offset = 0; + this.textEncoder = new TextEncoder(); + this.buffer = new Uint8Array(bufferSize); + } + get offset() { + return this._offset; + } + get byteOffset() { + return this.pendingBits; + } + end() { + this.finishByte(); + this.flush(); + } + reset() { + this._offset = 0; + } + finishByte() { + if (this.pendingBits > 0) { + this.buffer[this.bufferedBytes++] = Number(this.pendingByte); + this.pendingBits = 0; + this.pendingByte = BigInt(0); + } + } + flush() { + if (this.bufferedBytes > 0) { + this.stream.write(Buffer2.from(this.buffer.slice(0, this.bufferedBytes))); + this.bufferedBytes = 0; + } + } + writeString(byteCount, value, encoding = "utf-8") { + if (encoding === "utf-8") { + let buffer = new Uint8Array(byteCount); + let strBuf = this.textEncoder.encode(value); + buffer.set(strBuf, 0); + this.writeBytes(buffer); + } else { + if (typeof Buffer2 === "undefined") { + throw new Error(`Encoding '${encoding}' is not supported: No Node.js Buffer implementation found, web standard TextEncoder only supports utf-8`); + } + let buffer = Buffer2.alloc(byteCount); + Buffer2.from(value, encoding).copy(buffer); + this.writeBuffer(buffer); + } + } + writeBuffer(buffer) { + this.writeBytes(buffer); + } + writeBytes(chunk, offset = 0, length) { + length !== null && length !== void 0 ? length : length = chunk.length - offset; + if (this.byteOffset === 0) { + while (chunk.length > 0) { + let writableLength = Math.min(chunk.length, this.buffer.length - this.bufferedBytes); + this.buffer.set(chunk.subarray(0, writableLength), this.bufferedBytes); + this.bufferedBytes += writableLength; + chunk = chunk.subarray(writableLength); + if (this.bufferedBytes >= this.buffer.length) + this.flush(); + } + return; + } + for (let i = offset, max = Math.min(chunk.length, offset + length); i < max; ++i) + this.write(8, chunk[i]); + } + min(a, b) { + if (a < b) + return a; + else + return b; + } + write(length, value) { + if (value === void 0 || value === null) + value = 0; + value = Number(value); + if (Number.isNaN(value)) + throw new Error(`Cannot write to bitstream: Value ${value} is not a number`); + if (!Number.isFinite(value)) + throw new Error(`Cannot write to bitstream: Value ${value} must be finite`); + let valueN = BigInt(value % Math.pow(2, length)); + let remainingLength = length; + while (remainingLength > 0) { + let shift = BigInt(8 - this.pendingBits - remainingLength); + let contribution = shift >= 0 ? valueN << shift : valueN >> -shift; + let writtenLength = Number(shift >= 0 ? remainingLength : this.min(-shift, BigInt(8 - this.pendingBits))); + this.pendingByte = this.pendingByte | contribution; + this.pendingBits += writtenLength; + this._offset += writtenLength; + remainingLength -= writtenLength; + valueN = valueN % BigInt(Math.pow(2, remainingLength)); + if (this.pendingBits === 8) { + this.finishByte(); + if (this.bufferedBytes >= this.buffer.length) { + this.flush(); + } + } + } + } + writeSigned(length, value) { + if (value === void 0 || value === null) + value = 0; + const originalValue = value; + const max = 2 ** (length - 1) - 1; + const min = -(2 ** (length - 1)); + value = Number(value); + if (Number.isNaN(value)) + throw new Error(`Cannot write to bitstream: Value ${originalValue} is not a number`); + if (!Number.isFinite(value)) + throw new Error(`Cannot write to bitstream: Value ${value} must be finite`); + if (value > max) + throw new TypeError(`Cannot represent ${value} in I${length} format: Value too large (min=${min}, max=${max})`); + if (value < min) + throw new TypeError(`Cannot represent ${value} in I${length} format: Negative value too small (min=${min}, max=${max})`); + return this.write(length, value >= 0 ? value : ~-value + 1 >>> 0); + } + writeFloat(length, value) { + if (length !== 32 && length !== 64) + throw new TypeError(`Invalid length (${length} bits) Only 4-byte (32 bit / single-precision) and 8-byte (64 bit / double-precision) IEEE 754 values are supported`); + let buf2 = new ArrayBuffer(length / 8); + let view = new DataView(buf2); + if (length === 32) + view.setFloat32(0, value); + else if (length === 64) + view.setFloat64(0, value); + for (let i = 0, max = buf2.byteLength; i < max; ++i) + this.write(8, view.getUint8(i)); + } + }; + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/index.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/array-options.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/array-serializer.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/resolve-length.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/structure-serializer.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/utils.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/boolean-options.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/boolean-serializer.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/buffer-options.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/buffer-serializer.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/element.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/common/index.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/common/buffered-writable.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/common/constructor.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/common/discriminant.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/common/writable.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/common/incomplete-read-result.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/element.js + var _parent; + var _readFields; + var _isBeingRead; + var _fieldBeingComputed; + var _fieldBeingComputedIntrospectable; + var SERIALIZE_WRITERS = Symbol("Writers used by Bitstream#serialize() for this element type."); + _parent = /* @__PURE__ */ new WeakMap(), _readFields = /* @__PURE__ */ new WeakMap(), _isBeingRead = /* @__PURE__ */ new WeakMap(), _fieldBeingComputed = /* @__PURE__ */ new WeakMap(), _fieldBeingComputedIntrospectable = /* @__PURE__ */ new WeakMap(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/field-definition.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/field-options.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/field.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/null-serializer.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/number-serializer.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/string-serializer.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/length-determinant.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/number-options.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/serializer.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/value-determinant.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/variant-definition.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/variant-options.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/variant.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/reserved.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/reserved-low.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/marker.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // src/bitstream.ts + var revbyte = (n, len = 8) => { + let acc = 0; + let n2 = n; + let len2 = len; + while (len2) { + acc = acc * 2 + (n2 & 1); + n2 >>= 1; + len2--; + } + return acc; + }; + var BitstreamReader2 = class extends BitstreamReader { + constructor() { + super(...arguments); + this.rtotal = 0; + } + addBuffer(hidden) { + const inp = Buffer2.from(hidden); + for (let i = 0; i < inp.byteLength; ++i) + inp[i] = revbyte(inp[i]); + super.addBuffer(inp); + } + readSync(len) { + const v = super.readSync(len); + this.rtotal += len; + return revbyte(v, len); + } + }; + var BitstreamWriter2 = class extends BitstreamWriter { + constructor(w) { + super({ + write: (c) => { + const inp = Buffer2.from(c); + for (let i = 0; i < inp.byteLength; ++i) + inp[i] = revbyte(inp[i]); + this.w.write(inp); + } + }); + this.w = w; + this.wtotal = 0; + } + write(length, value) { + this.wtotal += length; + if (length) { + value = revbyte(value, length); + } + super.write(length, value); + } + }; + + // src/dh-deflate.ts + init_define_BUILD_VERSION(); + init_esbuild_inject(); + var TINF_OK = 0; + var Tree = class { + constructor() { + this.table = new Uint16Array(16); + this.trans = new Uint16Array(288); + } + }; + var getPathTo = (tree, value) => { + if (tree[0] === value) + return "0"; + if (tree[1] === value) + return "1"; + let p; + if (typeof tree[0] != "number") + p = getPathTo(tree[0], value); + let b = "0"; + if (!p) { + if (tree[1] && typeof tree[1] != "number") + p = getPathTo(tree[1], value); + b = "1"; + } + if (p) + return b + p; + }; + function buildHuffmanTable(codeLengths, values) { + let k = 0, code = [], i, j, length = 16; + while (length > 0 && !codeLengths[length - 1]) + length--; + code.push({ children: [], index: 0 }); + let p = code[0], q; + for (i = 0; i < length; i++) { + for (j = 0; j < codeLengths[i]; j++) { + p = code.pop(); + p.children[p.index] = values[k]; + while (p.index > 0) { + if (code.length === 0) + throw new Error("Could not recreate Huffman Table"); + p = code.pop(); + } + p.index++; + code.push(p); + while (code.length <= i) { + code.push(q = { children: [], index: 0 }); + p.children[p.index] = q.children; + p = q; + } + k++; + } + if (i + 1 < length) { + code.push(q = { children: [], index: 0 }); + p.children[p.index] = q.children; + p = q; + } + } + return code[0].children; + } + var Data = class { + constructor(source, dests, to_hide, hidden) { + this.source = source; + this.dests = dests; + this.to_hide = to_hide; + this.hidden = hidden; + this.dest = []; + this.ltree = new Tree(); + this.dtree = new Tree(); + } + computeReverse() { + this.rltree = buildHuffmanTable(this.ltree.table, this.ltree.trans)[0]; + this.rdtree = buildHuffmanTable(this.dtree.table, this.dtree.trans)[0]; + } + }; + var sltree = new Tree(); + var sdtree = new Tree(); + var rltree; + var rdtree; + var length_bits = new Uint8Array(30); + var length_base = new Uint16Array(30); + var dist_bits = new Uint8Array(30); + var dist_base = new Uint16Array(30); + var clcidx = new Uint8Array([ + 16, + 17, + 18, + 0, + 8, + 7, + 9, + 6, + 10, + 5, + 11, + 4, + 12, + 3, + 13, + 2, + 14, + 1, + 15 + ]); + var code_tree = new Tree(); + var lengths = new Uint8Array(288 + 32); + function tinf_build_bits_base(bits, base, delta, first) { + let i, sum; + for (i = 0; i < delta; ++i) + bits[i] = 0; + for (i = 0; i < 30 - delta; ++i) + bits[i + delta] = i / delta | 0; + for (sum = first, i = 0; i < 30; ++i) { + base[i] = sum; + sum += 1 << bits[i]; + } + } + function tinf_build_fixed_trees(lt, dt) { + let i; + for (i = 0; i < 7; ++i) + lt.table[i] = 0; + lt.table[7] = 24; + lt.table[8] = 152; + lt.table[9] = 112; + for (i = 0; i < 24; ++i) + lt.trans[i] = 256 + i; + for (i = 0; i < 144; ++i) + lt.trans[24 + i] = i; + for (i = 0; i < 8; ++i) + lt.trans[24 + 144 + i] = 280 + i; + for (i = 0; i < 112; ++i) + lt.trans[24 + 144 + 8 + i] = 144 + i; + for (i = 0; i < 5; ++i) + dt.table[i] = 0; + dt.table[5] = 32; + for (i = 0; i < 32; ++i) + dt.trans[i] = i; + } + var offs = new Uint16Array(16); + function tinf_build_tree(t, lengths2, off, num) { + let i, sum; + for (i = 0; i < 16; ++i) + t.table[i] = 0; + for (i = 0; i < num; ++i) + t.table[lengths2[off + i]]++; + t.table[0] = 0; + for (sum = 0, i = 0; i < 16; ++i) { + offs[i] = sum; + sum += t.table[i]; + } + for (i = 0; i < num; ++i) { + if (lengths2[off + i]) + t.trans[offs[lengths2[off + i]]++] = i; + } + } + function tinf_getbit(d) { + return d.source.readSync(1); + } + function tinf_read_bits(d, num, base) { + if (!num) + return base; + const v = d.source.readSync(num) + base; + return v; + } + function tinf_decode_symbol(d, t, copy = true, ext = {}) { + let sum = 0, cur = 0, len = 0; + let s = 0; + do { + const b = d.source.readSync(1); + copy && d.hidden.write(1, b); + s = s << 1 | b; + cur = 2 * cur + b; + ++len; + sum += t.table[len]; + cur -= t.table[len]; + } while (cur >= 0); + ext.length = len; + ext.sym = s; + return t.trans[sum + cur]; + } + function tinf_decode_trees(d, lt, dt) { + let i, num, length; + const hlit = tinf_read_bits(d, 5, 257); + d.hidden?.write(5, hlit - 257); + const hdist = tinf_read_bits(d, 5, 1); + d.hidden?.write(5, hdist - 1); + const hclen = tinf_read_bits(d, 4, 4); + d.hidden?.write(4, hclen - 4); + for (i = 0; i < 19; ++i) + lengths[i] = 0; + for (i = 0; i < hclen; ++i) { + const clen = tinf_read_bits(d, 3, 0); + d.hidden?.write(3, clen); + lengths[clcidx[i]] = clen; + } + tinf_build_tree(code_tree, lengths, 0, 19); + for (num = 0; num < hlit + hdist; ) { + const sym = tinf_decode_symbol(d, code_tree); + let prev; + switch (sym) { + case 16: + prev = lengths[num - 1]; + length = tinf_read_bits(d, 2, 3); + d.hidden?.write(2, length - 3); + for (; length; --length) { + lengths[num++] = prev; + } + break; + case 17: + length = tinf_read_bits(d, 3, 3); + d.hidden?.write(3, length - 3); + for (; length; --length) { + lengths[num++] = 0; + } + break; + case 18: + length = tinf_read_bits(d, 7, 11); + d.hidden?.write(7, length - 11); + for (; length; --length) { + lengths[num++] = 0; + } + break; + default: + lengths[num++] = sym; + break; + } + } + tinf_build_tree(lt, lengths, 0, hlit); + tinf_build_tree(dt, lengths, hlit, hdist); + } + var get_symbol = (value, bits_table, base_table) => { + let i = 0; + for (i = 0; i < base_table.length; ++i) { + if (base_table[i] > value) { + i--; + return [i, bits_table[i], value - base_table[i]]; + } + } + i--; + return [i, bits_table[i], value - base_table[i]]; + }; + var encode_symbol = (sym, tree) => { + const code = getPathTo(tree, sym); + return { + length: code?.length, + val: parseInt(code, 2) + }; + }; + var capacity = 0; + function tinf_inflate_block_data(d, lt, dt) { + let finished = false; + while (1) { + if (finished) { + return true; + } + let sym = tinf_decode_symbol(d, lt); + if (sym === 256) { + return TINF_OK; + } + if (sym < 256) { + d.dest.push(sym); + } else { + sym -= 257; + const length = tinf_read_bits(d, length_bits[sym], length_base[sym]); + if (length_bits[sym]) + d.hidden.write(length_bits[sym], length - length_base[sym]); + const ext = { length: 0, sym: 0 }; + const dist = tinf_decode_symbol(d, dt, false, ext); + let backoffset = tinf_read_bits(d, dist_bits[dist], dist_base[dist]); + const offs2 = d.dest.length - backoffset; + const match = Buffer2.from(d.dest.slice(offs2, offs2 + length)); + if (match.length == length) { + let begin = d.dest.length - 32768; + if (begin < 0) + begin = 0; + let matches = []; + let o = 0; + const slic = Buffer2.from(d.dest.slice(begin + o, d.dest.length)); + while (begin + o < d.dest.length) { + const r = slic.slice(o, d.dest.length).indexOf(match); + if (r >= 0) { + matches.push(r + begin + o); + o += r; + } else { + break; + } + o++; + } + if (matches.length > 1) { + matches = matches.map((e) => -(e - d.dest.length)); + matches.reverse(); + const v = Math.floor(Math.log2(matches.length)); + capacity += v; + if (d.to_hide instanceof BitstreamReader2) { + if (d.to_hide.available) { + const s = d.to_hide.readSync(Math.min(d.to_hide.available, v)); + backoffset = matches[s]; + } else { + finished = true; + } + } else { + const idx = matches.indexOf(backoffset); + d.to_hide.write(v, idx); + } + } + } + const [dsym, dlen, doff] = get_symbol(backoffset, dist_bits, dist_base); + const encdist = encode_symbol(dsym, d.rdtree); + d.hidden.write(encdist.length, revbyte(encdist.val, encdist.length)); + d.hidden.write(dlen, doff); + for (let i = offs2; i < offs2 + length; ++i) { + d.dest.push(d.dest[i]); + } + } + } + } + function tinf_inflate_uncompressed_block(d) { + const length = d.source.readSync(16); + const invlength = d.source.readSync(16); + if (length !== (~invlength & 65535)) + return -4; + for (let i = length; i; --i) + d.dest.push(d.source.readSync(8)); + return TINF_OK; + } + function tinf_uncompress(source, decompressed, to_hide, hidden) { + const decomp = new BitstreamWriter2({ write: decompressed || (() => { + }) }); + const hid = new BitstreamWriter2({ write: hidden || (() => { + }) }); + const d = new Data(source, decomp, to_hide, hid); + let res; + let bfinal, btype; + do { + if (to_hide instanceof BitstreamReader2) { + if (to_hide.available == 0) { + while (source.available && source.offset & 7) { + hid.write(1, source.readSync(1)); + } + return source.offset >> 3; + } + } + bfinal = tinf_getbit(d); + d.hidden.write(1, bfinal); + btype = tinf_read_bits(d, 2, 0); + d.hidden?.write(2, btype); + switch (btype) { + case 0: + res = tinf_inflate_uncompressed_block(d); + break; + case 1: + d.rdtree = rdtree; + d.rltree = rltree; + res = tinf_inflate_block_data(d, sltree, sdtree); + if (res === true) { + continue; + } + break; + case 2: + tinf_decode_trees(d, d.ltree, d.dtree); + d.computeReverse(); + res = tinf_inflate_block_data(d, d.ltree, d.dtree); + if (res === true) { + continue; + } + break; + default: + res = -2; + } + if (res !== TINF_OK) + throw new Error("Data error " + res); + } while (!bfinal); + decomp.end(); + hid.end(); + } + tinf_build_fixed_trees(sltree, sdtree); + tinf_build_bits_base(length_bits, length_base, 4, 3); + tinf_build_bits_base(dist_bits, dist_base, 2, 1); + rltree = buildHuffmanTable(sltree.table, sltree.trans)[0]; + rdtree = buildHuffmanTable(sdtree.table, sdtree.trans)[0]; + length_bits[28] = 0; + length_base[28] = 258; + + // src/pngv3.ts var csettings2; settings.subscribe((b) => { csettings2 = b; @@ -16810,14 +17880,40 @@ "t": "take-me-to.space", "z": "z.zz.fo" }; + var extractFromRawDeflate = (b) => { + const src = new BitstreamReader2(); + src.addBuffer(b); + const chnks = []; + const hidden = new BitstreamWriter2({ + write(chunk) { + for (const i of chunk) { + if (i) + chnks.push(i); + else + throw "Finish"; + } + } + }); + try { + tinf_uncompress(src, () => { + }, hidden, () => { + }); + } catch (e) { + if (e == "Finish") + return import_buffer3.Buffer.from(chnks); + } + return false; + }; var extract = async (png) => { const reader = BufferReadStream(png).getReader(); - const sneed = new PNGDecoder(reader); + const sneed = new PNGDecoder(reader, false); const ret = []; let w; if (!csettings2) throw new Error("Settings uninit"); try { + let complete = false; + const idats = []; for await (const [name, chunk, crc, offset] of sneed.chunks()) { let buff; switch (name) { @@ -16864,12 +17960,27 @@ } break; case "IDAT": + if (ret.length) + return ret; + buff = await chunk(); + idats.push(buff.slice(4)); case "IEND": - return ret.slice(0, csettings2.maxe); + complete = true; default: break; } } + if (idats.length) { + let decoded; + if ((decoded = extractFromRawDeflate(import_buffer3.Buffer.concat(idats).slice(2))) === false) + return false; + const dec = decoded.toString().split(" ").map((e) => { + if (!(e[0] in rprefs)) + throw "Uhh"; + return `https://${rprefs[e[0]]}/${e.slice(1)}`; + }).join(" "); + return decodeCoom3Payload(import_buffer3.Buffer.from(dec)); + } } catch (e) { console.error(e); } finally { @@ -16891,46 +18002,85 @@ }); return [ret, () => b]; }; + var embedInRawDeflate = (b, h) => { + const src = new BitstreamReader2(); + const hid = new BitstreamReader2(); + hid.addBuffer(h); + src.addBuffer(b); + const chnks = []; + const endo = tinf_uncompress(src, () => { + }, hid, (c) => chnks.push(c)); + if (endo) + chnks.push(b.slice(endo)); + return import_buffer3.Buffer.concat(chnks); + }; var inject_data = async (container, injb) => { if (!csettings2) throw new Error("Settings uninit"); - let magic4 = false; + if (csettings2.pmeth < 5) { + let magic4 = false; + const [writestream2, extract8] = BufferWriteStream2(); + const encoder = new PNGEncoder(writestream2); + const decoder = new PNGDecoder(container.stream().getReader()); + for await (const [name, chunk, crc, offset] of decoder.chunks()) { + if (magic4 && name != "IDAT") + break; + if (!magic4 && name == "IDAT") { + const passed = import_buffer3.Buffer.from(injb); + switch (csettings2.pmeth) { + case 0: + await encoder.insertchunk(["tEXt", async () => buildChunk("tEXt", import_buffer3.Buffer.concat([CUM3, passed])), () => Promise.resolve(0), 0]); + break; + case 1: + xor(passed, password); + await encoder.insertchunk(["tEXt", async () => buildChunk("tEXt", import_buffer3.Buffer.concat([CUM4, import_buffer3.Buffer.from(import_buffer3.Buffer.from(passed).toString("base64"))])), () => Promise.resolve(0), 0]); + break; + case 2: + await encoder.insertchunk(["tEXt", async () => buildChunk("tEXt", import_buffer3.Buffer.concat([CUM5, import_buffer3.Buffer.from(import_buffer3.Buffer.from(passed).toString("base64"))])), () => Promise.resolve(0), 0]); + break; + case 3: + await encoder.insertchunk(["tEXt", async () => buildChunk("tEXt", import_buffer3.Buffer.concat([CUM6, import_buffer3.Buffer.from(import_buffer3.Buffer.from(passed).toString("base64"))])), () => Promise.resolve(0), 0]); + break; + case 4: + await encoder.insertchunk(["tEXt", async () => buildChunk("tEXt", import_buffer3.Buffer.concat([CUM7, import_buffer3.Buffer.from(bs58.encode(passed))])), () => Promise.resolve(0), 0]); + break; + } + magic4 = true; + } + await encoder.insertchunk([name, chunk, crc, offset]); + } + await encoder.insertchunk([ + "IEND", + async () => Promise.resolve(buildChunk("IEND", import_buffer3.Buffer.from([]))), + async () => Promise.resolve(0), + 0 + ]); + return extract8(); + } + let pdec = new PNGDecoder(container.stream().getReader()); + const concat = []; + for await (const chk of pdec.chunks()) + if (chk[0] == "IDAT") + concat.push((await chk[1]()).slice(4)); + const comp = import_buffer3.Buffer.concat(concat); + const head = comp.slice(0, 2); + const chksum = comp.slice(-4); + const idatblk = embedInRawDeflate(comp.slice(2, -4), injb); + const bws = BufferWriteStream2(); const [writestream, extract7] = BufferWriteStream2(); - const encoder = new PNGEncoder(writestream); - const decoder = new PNGDecoder(container.stream().getReader()); - for await (const [name, chunk, crc, offset] of decoder.chunks()) { - if (magic4 && name != "IDAT") - break; - if (!magic4 && name == "IDAT") { - const passed = import_buffer3.Buffer.from(injb); - switch (csettings2.pmeth) { - case 0: - await encoder.insertchunk(["tEXt", async () => buildChunk("tEXt", import_buffer3.Buffer.concat([CUM3, passed])), () => Promise.resolve(0), 0]); - break; - case 1: - xor(passed, password); - await encoder.insertchunk(["tEXt", async () => buildChunk("tEXt", import_buffer3.Buffer.concat([CUM4, import_buffer3.Buffer.from(import_buffer3.Buffer.from(passed).toString("base64"))])), () => Promise.resolve(0), 0]); - break; - case 2: - await encoder.insertchunk(["tEXt", async () => buildChunk("tEXt", import_buffer3.Buffer.concat([CUM5, import_buffer3.Buffer.from(import_buffer3.Buffer.from(passed).toString("base64"))])), () => Promise.resolve(0), 0]); - break; - case 3: - await encoder.insertchunk(["tEXt", async () => buildChunk("tEXt", import_buffer3.Buffer.concat([CUM6, import_buffer3.Buffer.from(import_buffer3.Buffer.from(passed).toString("base64"))])), () => Promise.resolve(0), 0]); - break; - case 4: - await encoder.insertchunk(["tEXt", async () => buildChunk("tEXt", import_buffer3.Buffer.concat([CUM7, import_buffer3.Buffer.from(bs58.encode(passed))])), () => Promise.resolve(0), 0]); - break; + const penc = new PNGEncoder(writestream); + pdec = new PNGDecoder(container.stream().getReader()); + let ins = false; + for await (const chk of pdec.chunks()) { + if (chk[0] != "IDAT") { + await penc.insertchunk(chk); + } else { + if (!ins) { + await penc.insertchunk(["IDAT", async () => import_buffer3.Buffer.concat([import_buffer3.Buffer.from("IDAT"), head, idatblk, chksum]), () => Promise.resolve(0), 0]); + ins = true; } - magic4 = true; } - await encoder.insertchunk([name, chunk, crc, offset]); } - await encoder.insertchunk([ - "IEND", - async () => Promise.resolve(buildChunk("IEND", import_buffer3.Buffer.from([]))), - async () => Promise.resolve(0), - 0 - ]); return extract7(); }; var inject = async (container, links) => { @@ -16947,49 +18097,8 @@ return inject_data(container, injb); }; var has_embed = async (png) => { - const reader = BufferReadStream(png).getReader(); - const sneed = new PNGDecoder(reader); - try { - for await (const [name, chunk, crc, offset] of sneed.chunks()) { - let buff; - switch (name) { - case "tEXt": - buff = await chunk(); - if (buff.slice(4, 4 + CUM3.length).equals(CUM3)) - return true; - if (buff.slice(4, 4 + CUM4.length).equals(CUM4)) - return true; - if (buff.slice(4, 4 + CUM5.length).equals(CUM5)) - return true; - if (buff.slice(4, 4 + CUM6.length).equals(CUM6)) { - const passed = buff.slice(4 + CUM6.length).toString(); - if (passed.match(/^[0-9a-zA-Z+/=]+$/g)) { - if (import_buffer3.Buffer.from(passed, "base64").toString().split(" ").every((l) => l[0] in rprefs)) - return true; - } - } - if (buff.slice(4, 4 + CUM7.length).equals(CUM7)) { - const passed = buff.slice(4 + CUM7.length).toString(); - if (passed.match(/^[0-9a-zA-Z+/=]+$/g)) { - if (import_buffer3.Buffer.from(passed, "base64").toString().split(" ").every((l) => l[0] in rprefs)) - return true; - if (import_buffer3.Buffer.from(bs58.decode(passed)).toString().split(" ").every((l) => l[0] in rprefs)) - return true; - } - } - break; - case "IDAT": - case "IEND": - return false; - default: - break; - } - } - } catch (e) { - return; - } finally { - reader.releaseLock(); - } + const r = await extract(png); + return !!r; }; var pngv3_default = { extract, @@ -23518,9 +24627,9 @@ let select; let mounted; let dispose; - let each_value = [0, 1, 2, 3, 4]; + let each_value = [0, 1, 2, 3, 4, 5]; let each_blocks = []; - for (let i = 0; i < 5; i += 1) { + for (let i = 0; i < 6; i += 1) { each_blocks[i] = create_each_block2(get_each_context2(ctx, each_value, i)); } return { @@ -23528,7 +24637,7 @@ label = element("label"); t = text("PNG Embedding method\n "); select = element("select"); - for (let i = 0; i < 5; i += 1) { + for (let i = 0; i < 6; i += 1) { each_blocks[i].c(); } if (ctx[7].pmeth === void 0) @@ -23538,7 +24647,7 @@ insert(target, label, anchor); append(label, t); append(label, select); - for (let i = 0; i < 5; i += 1) { + for (let i = 0; i < 6; i += 1) { each_blocks[i].m(select, null); } select_option(select, ctx[7].pmeth); @@ -25608,7 +26717,7 @@ }; var FoolFuuka = { getFileThumbnail: (post) => post.classList.contains("post_is_op") ? post.querySelector(".thread_image_link") : post.querySelector(".thread_image_box"), - getPost: (post) => post.querySelector(".post_wrapper"), + getPost: (post) => post.querySelector(".post_wrapper") || post, postsWithFiles: (h) => [...(h || document).querySelectorAll('article[class*="thread"], article[class*="has_image"]')], settingsHost: () => document.querySelector(".letters"), catalogControlHost: () => document.getElementById("index-options"), diff --git a/firefox/manifest.json b/firefox/manifest.json index fba830e..3cbad73 100644 --- a/firefox/manifest.json +++ b/firefox/manifest.json @@ -7,7 +7,7 @@ }, "name": "PngExtraEmbedder", "description": "Discover embedded files on 4chan and archives!", - "version": "0.279", + "version": "0.281", "icons": { "64": "1449696017588.png" }, diff --git a/firefox_update.json b/firefox_update.json index df80871..801ba43 100644 --- a/firefox_update.json +++ b/firefox_update.json @@ -1 +1 @@ -{"addons":{"{34ac4994-07f2-44d2-8599-682516a6c6a6}":{"updates":[{"version":"0.279","update_link":"https://git.coom.tech/fuckjannies/lolipiss/raw/branch/%E4%B8%AD%E5%87%BA%E3%81%97/pngextraembedder-0.279.xpi"}]}}} \ No newline at end of file +{"addons":{"{34ac4994-07f2-44d2-8599-682516a6c6a6}":{"updates":[{"version":"0.281","update_link":"https://git.coom.tech/fuckjannies/lolipiss/raw/branch/%E4%B8%AD%E5%87%BA%E3%81%97/pngextraembedder-0.281.xpi"}]}}} \ No newline at end of file diff --git a/main.meta.js b/main.meta.js index 3f8c69e..9cd23a0 100644 --- a/main.meta.js +++ b/main.meta.js @@ -1,7 +1,7 @@ // ==UserScript== // @name PNGExtraEmbed // @namespace https://coom.tech/ -// @version 0.280 +// @version 0.281 // @description uhh // @author You // @match https://boards.4channel.org/* diff --git a/main.user.js b/main.user.js index 9748cfc..4912fb4 100644 --- a/main.user.js +++ b/main.user.js @@ -1,7 +1,7 @@ // ==UserScript== // @name PNGExtraEmbed // @namespace https://coom.tech/ -// @version 0.280 +// @version 0.281 // @description uhh // @author You // @match https://boards.4channel.org/* @@ -109,7 +109,7 @@ const _DOMParser = DOMParser; var define_BUILD_VERSION_default; var init_define_BUILD_VERSION = __esm({ ""() { - define_BUILD_VERSION_default = [0, 280]; + define_BUILD_VERSION_default = [0, 281]; } }); @@ -12145,7 +12145,7 @@ const _DOMParser = DOMParser; var dctSqrt1d2 = 2896; function constructor() { } - function buildHuffmanTable(codeLengths, values) { + function buildHuffmanTable2(codeLengths, values) { var k = 0, code = [], i, j, length = 16; while (length > 0 && !codeLengths[length - 1]) length--; @@ -12781,7 +12781,7 @@ const _DOMParser = DOMParser; for (j = 0; j < codeLengthSum; j++, offset++) huffmanValues[j] = data[offset]; i += 17 + codeLengthSum; - (huffmanTableSpec >> 4 === 0 ? huffmanTablesDC : huffmanTablesAC)[huffmanTableSpec & 15] = buildHuffmanTable(codeLengths, huffmanValues); + (huffmanTableSpec >> 4 === 0 ? huffmanTablesDC : huffmanTablesAC)[huffmanTableSpec & 15] = buildHuffmanTable2(codeLengths, huffmanValues); } break; case 65501: @@ -14023,7 +14023,7 @@ const _DOMParser = DOMParser; var initial_settings = localLoad("settingsv2", { loop: true, dh: false, - pmeth: 4, + pmeth: 5, xpv: false, xpi: false, hyd: false, @@ -14168,8 +14168,10 @@ const _DOMParser = DOMParser; var import_crc_32 = __toESM(require_crc32(), 1); var import_buffer = __toESM(require_buffer(), 1); var PNGDecoder = class { - constructor(reader) { + constructor(reader, strict = true) { this.reader = reader; + this.strict = strict; + this.stopped = false; this.req = 8; this.ptr = 8; this.repr = import_buffer.Buffer.from([]); @@ -14178,7 +14180,10 @@ const _DOMParser = DOMParser; while (this.repr.byteLength < this.req) { const chunk = await this.reader.read(); if (chunk.done) { - throw new Error(`Unexpected EOF, got ${this.repr.byteLength}, required ${this.req}, ${chunk.value}`); + this.stopped = true; + if (this.strict) + throw new Error(`Unexpected EOF, got ${this.repr.byteLength}, required ${this.req}, ${chunk.value}`); + return; } this.repr = import_buffer.Buffer.concat([this.repr, chunk.value]); } @@ -14187,6 +14192,8 @@ const _DOMParser = DOMParser; while (true) { this.req += 8; await this.catchup(); + if (this.stopped) + break; const length = this.repr.readUInt32BE(this.ptr); const name = this.repr.slice(this.ptr + 4, this.ptr + 8).toString(); this.ptr += 4; @@ -14205,6 +14212,8 @@ const _DOMParser = DOMParser; this.ptr ]; this.ptr += length + 8; + if (this.stopped) + break; if (name == "IEND") break; } @@ -16456,11 +16465,15 @@ const _DOMParser = DOMParser; cthreadDataCache = newval; }); var refreshThreadDataCache = async (board, op) => { + console.log("refreshing thread info cache..."); threadDataCache.set(await getThreadInfo(board, op)); }; var getThreadDataCache = async (board, op) => { if (!cthreadDataCache) await refreshThreadDataCache(board, op); + else { + console.log("skipped thread cache refresh..."); + } return threadDataCache; }; var getEmbedsFromCache = async (board, op, pid) => { @@ -16672,6 +16685,1056 @@ const _DOMParser = DOMParser; // src/pngv3.ts var bs58 = __toESM(require_bs58(), 1); + + // src/bitstream.ts + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/index.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/bitstream/index.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/bitstream/reader.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + var __awaiter = function(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function(resolve2) { + resolve2(value); + }); + } + return new (P || (P = Promise))(function(resolve2, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve2(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + var BitstreamReader = class { + constructor() { + this.buffers = []; + this.bufferedLength = 0; + this.blockedRequest = null; + this._offsetIntoBuffer = 0; + this._bufferIndex = 0; + this._offset = 0; + this._spentBufferSize = 0; + this.retainBuffers = false; + this.textDecoder = new TextDecoder(); + this.skippedLength = 0; + } + get bufferIndex() { + return this._bufferIndex; + } + get offset() { + return this._offset; + } + get spentBufferSize() { + return this._spentBufferSize; + } + set offset(value) { + if (value < this._spentBufferSize) { + throw new Error(`Offset ${value} points into a discarded buffer! If you need to seek backwards outside the current buffer, make sure to set retainBuffers=true`); + } + let offsetIntoBuffer = value - this._spentBufferSize; + let bufferIndex = 0; + for (let i = 0, max = this.buffers.length; i < max; ++i) { + let buf2 = this.buffers[i]; + let size = buf2.length * 8; + if (offsetIntoBuffer < size) { + this._bufferIndex = bufferIndex; + this._offset = value; + this._offsetIntoBuffer = offsetIntoBuffer; + this.bufferedLength = buf2.length * 8 - this._offsetIntoBuffer; + for (let j = i + 1; j < max; ++j) + this.bufferedLength += this.buffers[j].length * 8; + return; + } + offsetIntoBuffer -= size; + ++bufferIndex; + } + } + clean(count) { + let buffers = this.buffers.splice(0, count !== void 0 ? Math.min(count, this._bufferIndex) : this._bufferIndex); + this._spentBufferSize += buffers.map((b) => b.length * 8).reduce((pv, cv) => pv + cv, 0); + this._bufferIndex -= buffers.length; + } + get available() { + return this.bufferedLength - this.skippedLength; + } + isAvailable(length) { + return this.bufferedLength >= length; + } + ensureNoReadPending() { + if (this.blockedRequest) + throw new Error(`Only one read() can be outstanding at a time.`); + } + readString(length, options) { + return __awaiter(this, void 0, void 0, function* () { + this.ensureNoReadPending(); + yield this.assure(8 * length); + return this.readStringSync(length, options); + }); + } + readStringSync(length, options) { + var _a, _b; + if (!options) + options = {}; + this.ensureNoReadPending(); + let buffer = new Uint8Array(length); + let firstTerminator = -1; + let charLength = 1; + let encoding = (_a = options.encoding) !== null && _a !== void 0 ? _a : "utf-8"; + if (["utf16le", "ucs-2", "ucs2"].includes(encoding)) { + charLength = 2; + } + for (let i = 0, max = length; i < max; ++i) { + buffer[i] = this.readSync(8); + } + for (let i = 0, max = length; i < max; i += charLength) { + let char = buffer[i]; + if (charLength === 2) + char = char << 8 | ((_b = buffer[i + 1]) !== null && _b !== void 0 ? _b : 0); + if (char === 0) { + firstTerminator = i; + break; + } + } + if (options.nullTerminated !== false) { + if (firstTerminator >= 0) { + buffer = buffer.subarray(0, firstTerminator); + } + } + if (encoding === "utf-8") { + return this.textDecoder.decode(buffer); + } else { + if (typeof Buffer2 === "undefined") + throw new Error(`Encoding '${encoding}' is not supported: No Node.js Buffer implementation and TextDecoder only supports utf-8`); + return Buffer2.from(buffer).toString(encoding); + } + } + peekSync(length) { + return this.readCoreSync(length, false); + } + skip(length) { + this.skippedLength += length; + } + readSync(length) { + return this.readCoreSync(length, true); + } + *readBytes(buffer, offset = 0, length) { + length !== null && length !== void 0 ? length : length = buffer.length - offset; + for (let i = offset, max = Math.min(buffer.length, offset + length); i < max; ++i) { + if (!this.isAvailable(8)) + yield max - i; + buffer[i] = this.readSync(8); + } + return buffer; + } + readBytesSync(buffer, offset = 0, length) { + length !== null && length !== void 0 ? length : length = buffer.length - offset; + let gen = this.readBytes(buffer, offset, length); + while (true) { + let result = gen.next(); + if (result.done === false) + throw new Error(`underrun: Not enough bits are available (requested ${length} bytes)`); + else + break; + } + return buffer; + } + readBytesBlocking(buffer, offset = 0, length) { + return __awaiter(this, void 0, void 0, function* () { + length !== null && length !== void 0 ? length : length = buffer.length - offset; + let gen = this.readBytes(buffer, offset, length); + while (true) { + let result = gen.next(); + if (result.done === false) + yield this.assure(result.value * 8); + else + break; + } + return buffer; + }); + } + readSignedSync(length) { + const u = this.readSync(length); + const signBit = 2 ** (length - 1); + const mask = signBit - 1; + return (u & signBit) === 0 ? u : -((~(u - 1) & mask) >>> 0); + } + readFloatSync(length) { + if (length !== 32 && length !== 64) + throw new TypeError(`Invalid length (${length} bits) Only 4-byte (32 bit / single-precision) and 8-byte (64 bit / double-precision) IEEE 754 values are supported`); + if (!this.isAvailable(length)) + throw new Error(`underrun: Not enough bits are available (requested=${length}, available=${this.bufferedLength}, buffers=${this.buffers.length})`); + let buf2 = new ArrayBuffer(length / 8); + let view = new DataView(buf2); + for (let i = 0, max = buf2.byteLength; i < max; ++i) + view.setUint8(i, this.readSync(8)); + if (length === 32) + return view.getFloat32(0, false); + else if (length === 64) + return view.getFloat64(0, false); + } + readCoreSync(length, consume) { + this.ensureNoReadPending(); + let value = BigInt(0); + let remainingLength = length; + if (this.available < length) + throw new Error(`underrun: Not enough bits are available (requested=${length}, available=${this.bufferedLength}, buffers=${this.buffers.length})`); + this.adjustSkip(); + let offset = this._offsetIntoBuffer; + let bufferIndex = this._bufferIndex; + let bitLength = 0; + while (remainingLength > 0) { + if (bufferIndex >= this.buffers.length) + throw new Error(`Internal error: Buffer index out of range (index=${bufferIndex}, count=${this.buffers.length}), offset=${this.offset}, readLength=${length}, available=${this.available})`); + let buffer = this.buffers[bufferIndex]; + let byteOffset = Math.floor(offset / 8); + if (byteOffset >= buffer.length) + throw new Error(`Internal error: Current buffer (index ${bufferIndex}) has length ${buffer.length} but our position within the buffer is ${byteOffset}! offset=${this.offset}, bufs=${this.buffers.length}`); + let byte = BigInt(buffer[byteOffset]); + let bitOffset = offset % 8; + let bitContribution = Math.min(8 - bitOffset, remainingLength); + let mask = Math.pow(2, bitContribution) - 1; + value = value << BigInt(bitContribution) | byte >> BigInt(8) - BigInt(bitContribution) - BigInt(bitOffset) & BigInt(mask); + offset += bitContribution; + remainingLength -= bitContribution; + bitLength += bitContribution; + if (offset >= buffer.length * 8) { + bufferIndex += 1; + offset = 0; + } + } + if (consume) { + this.bufferedLength -= length; + this._offsetIntoBuffer = offset; + this._offset += bitLength; + this._bufferIndex = bufferIndex; + if (!this.retainBuffers) { + this.clean(); + } + } + return Number(value); + } + adjustSkip() { + if (this.skippedLength <= 0) + return; + while (this.buffers && this.skippedLength > this.buffers[0].length * 8 - this._offsetIntoBuffer) { + this.skippedLength -= this.buffers[0].length * 8 - this._offsetIntoBuffer; + this._offsetIntoBuffer = 0; + this.buffers.shift(); + } + if (this.buffers.length > 0) { + this._offsetIntoBuffer += this.skippedLength; + this.skippedLength = 0; + } + } + assure(length) { + this.ensureNoReadPending(); + if (this.bufferedLength >= length) { + return Promise.resolve(); + } + let request2 = { resolve: null, length, peek: true }; + let promise2 = new Promise((resolve2) => request2.resolve = resolve2); + this.blockedRequest = request2; + return promise2.then(() => { + }); + } + read(length) { + this.ensureNoReadPending(); + if (this.available >= length) { + return Promise.resolve(this.readSync(length)); + } else { + let request2 = { resolve: null, length, peek: false }; + let promise2 = new Promise((resolve2) => request2.resolve = resolve2); + this.blockedRequest = request2; + return promise2; + } + } + readSigned(length) { + this.ensureNoReadPending(); + if (this.available >= length) { + return Promise.resolve(this.readSignedSync(length)); + } else { + let request2 = { resolve: null, length, peek: false, signed: true }; + let promise2 = new Promise((resolve2) => request2.resolve = resolve2); + this.blockedRequest = request2; + return promise2; + } + } + readFloat(length) { + this.ensureNoReadPending(); + if (this.available >= length) { + return Promise.resolve(this.readFloatSync(length)); + } else { + let request2 = { resolve: null, length, peek: false, float: true }; + let promise2 = new Promise((resolve2) => request2.resolve = resolve2); + this.blockedRequest = request2; + return promise2; + } + } + peek(length) { + return __awaiter(this, void 0, void 0, function* () { + yield this.assure(length); + return this.peekSync(length); + }); + } + addBuffer(buffer) { + this.buffers.push(buffer); + this.bufferedLength += buffer.length * 8; + if (this.blockedRequest && this.blockedRequest.length <= this.available) { + let request2 = this.blockedRequest; + this.blockedRequest = null; + if (request2.peek) { + request2.resolve(0); + } else if (request2.signed) { + request2.resolve(this.readSignedSync(request2.length)); + } else if (request2.float) { + request2.resolve(this.readFloatSync(request2.length)); + } else { + request2.resolve(this.readSync(request2.length)); + } + } + } + }; + + // node_modules/@astronautlabs/bitstream/dist.esm/bitstream/string-encoding-options.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/bitstream/writer.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + var BitstreamWriter = class { + constructor(stream, bufferSize = 1) { + this.stream = stream; + this.bufferSize = bufferSize; + this.pendingByte = BigInt(0); + this.pendingBits = 0; + this.bufferedBytes = 0; + this._offset = 0; + this.textEncoder = new TextEncoder(); + this.buffer = new Uint8Array(bufferSize); + } + get offset() { + return this._offset; + } + get byteOffset() { + return this.pendingBits; + } + end() { + this.finishByte(); + this.flush(); + } + reset() { + this._offset = 0; + } + finishByte() { + if (this.pendingBits > 0) { + this.buffer[this.bufferedBytes++] = Number(this.pendingByte); + this.pendingBits = 0; + this.pendingByte = BigInt(0); + } + } + flush() { + if (this.bufferedBytes > 0) { + this.stream.write(Buffer2.from(this.buffer.slice(0, this.bufferedBytes))); + this.bufferedBytes = 0; + } + } + writeString(byteCount, value, encoding = "utf-8") { + if (encoding === "utf-8") { + let buffer = new Uint8Array(byteCount); + let strBuf = this.textEncoder.encode(value); + buffer.set(strBuf, 0); + this.writeBytes(buffer); + } else { + if (typeof Buffer2 === "undefined") { + throw new Error(`Encoding '${encoding}' is not supported: No Node.js Buffer implementation found, web standard TextEncoder only supports utf-8`); + } + let buffer = Buffer2.alloc(byteCount); + Buffer2.from(value, encoding).copy(buffer); + this.writeBuffer(buffer); + } + } + writeBuffer(buffer) { + this.writeBytes(buffer); + } + writeBytes(chunk, offset = 0, length) { + length !== null && length !== void 0 ? length : length = chunk.length - offset; + if (this.byteOffset === 0) { + while (chunk.length > 0) { + let writableLength = Math.min(chunk.length, this.buffer.length - this.bufferedBytes); + this.buffer.set(chunk.subarray(0, writableLength), this.bufferedBytes); + this.bufferedBytes += writableLength; + chunk = chunk.subarray(writableLength); + if (this.bufferedBytes >= this.buffer.length) + this.flush(); + } + return; + } + for (let i = offset, max = Math.min(chunk.length, offset + length); i < max; ++i) + this.write(8, chunk[i]); + } + min(a, b) { + if (a < b) + return a; + else + return b; + } + write(length, value) { + if (value === void 0 || value === null) + value = 0; + value = Number(value); + if (Number.isNaN(value)) + throw new Error(`Cannot write to bitstream: Value ${value} is not a number`); + if (!Number.isFinite(value)) + throw new Error(`Cannot write to bitstream: Value ${value} must be finite`); + let valueN = BigInt(value % Math.pow(2, length)); + let remainingLength = length; + while (remainingLength > 0) { + let shift = BigInt(8 - this.pendingBits - remainingLength); + let contribution = shift >= 0 ? valueN << shift : valueN >> -shift; + let writtenLength = Number(shift >= 0 ? remainingLength : this.min(-shift, BigInt(8 - this.pendingBits))); + this.pendingByte = this.pendingByte | contribution; + this.pendingBits += writtenLength; + this._offset += writtenLength; + remainingLength -= writtenLength; + valueN = valueN % BigInt(Math.pow(2, remainingLength)); + if (this.pendingBits === 8) { + this.finishByte(); + if (this.bufferedBytes >= this.buffer.length) { + this.flush(); + } + } + } + } + writeSigned(length, value) { + if (value === void 0 || value === null) + value = 0; + const originalValue = value; + const max = 2 ** (length - 1) - 1; + const min = -(2 ** (length - 1)); + value = Number(value); + if (Number.isNaN(value)) + throw new Error(`Cannot write to bitstream: Value ${originalValue} is not a number`); + if (!Number.isFinite(value)) + throw new Error(`Cannot write to bitstream: Value ${value} must be finite`); + if (value > max) + throw new TypeError(`Cannot represent ${value} in I${length} format: Value too large (min=${min}, max=${max})`); + if (value < min) + throw new TypeError(`Cannot represent ${value} in I${length} format: Negative value too small (min=${min}, max=${max})`); + return this.write(length, value >= 0 ? value : ~-value + 1 >>> 0); + } + writeFloat(length, value) { + if (length !== 32 && length !== 64) + throw new TypeError(`Invalid length (${length} bits) Only 4-byte (32 bit / single-precision) and 8-byte (64 bit / double-precision) IEEE 754 values are supported`); + let buf2 = new ArrayBuffer(length / 8); + let view = new DataView(buf2); + if (length === 32) + view.setFloat32(0, value); + else if (length === 64) + view.setFloat64(0, value); + for (let i = 0, max = buf2.byteLength; i < max; ++i) + this.write(8, view.getUint8(i)); + } + }; + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/index.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/array-options.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/array-serializer.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/resolve-length.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/structure-serializer.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/utils.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/boolean-options.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/boolean-serializer.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/buffer-options.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/buffer-serializer.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/element.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/common/index.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/common/buffered-writable.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/common/constructor.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/common/discriminant.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/common/writable.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/common/incomplete-read-result.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/element.js + var _parent; + var _readFields; + var _isBeingRead; + var _fieldBeingComputed; + var _fieldBeingComputedIntrospectable; + var SERIALIZE_WRITERS = Symbol("Writers used by Bitstream#serialize() for this element type."); + _parent = /* @__PURE__ */ new WeakMap(), _readFields = /* @__PURE__ */ new WeakMap(), _isBeingRead = /* @__PURE__ */ new WeakMap(), _fieldBeingComputed = /* @__PURE__ */ new WeakMap(), _fieldBeingComputedIntrospectable = /* @__PURE__ */ new WeakMap(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/field-definition.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/field-options.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/field.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/null-serializer.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/number-serializer.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/string-serializer.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/length-determinant.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/number-options.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/serializer.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/value-determinant.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/variant-definition.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/variant-options.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/variant.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/reserved.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/reserved-low.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // node_modules/@astronautlabs/bitstream/dist.esm/elements/marker.js + init_define_BUILD_VERSION(); + init_esbuild_inject(); + + // src/bitstream.ts + var revbyte = (n, len = 8) => { + let acc = 0; + let n2 = n; + let len2 = len; + while (len2) { + acc = acc * 2 + (n2 & 1); + n2 >>= 1; + len2--; + } + return acc; + }; + var BitstreamReader2 = class extends BitstreamReader { + constructor() { + super(...arguments); + this.rtotal = 0; + } + addBuffer(hidden) { + const inp = Buffer2.from(hidden); + for (let i = 0; i < inp.byteLength; ++i) + inp[i] = revbyte(inp[i]); + super.addBuffer(inp); + } + readSync(len) { + const v = super.readSync(len); + this.rtotal += len; + return revbyte(v, len); + } + }; + var BitstreamWriter2 = class extends BitstreamWriter { + constructor(w) { + super({ + write: (c) => { + const inp = Buffer2.from(c); + for (let i = 0; i < inp.byteLength; ++i) + inp[i] = revbyte(inp[i]); + this.w.write(inp); + } + }); + this.w = w; + this.wtotal = 0; + } + write(length, value) { + this.wtotal += length; + if (length) { + value = revbyte(value, length); + } + super.write(length, value); + } + }; + + // src/dh-deflate.ts + init_define_BUILD_VERSION(); + init_esbuild_inject(); + var TINF_OK = 0; + var Tree = class { + constructor() { + this.table = new Uint16Array(16); + this.trans = new Uint16Array(288); + } + }; + var getPathTo = (tree, value) => { + if (tree[0] === value) + return "0"; + if (tree[1] === value) + return "1"; + let p; + if (typeof tree[0] != "number") + p = getPathTo(tree[0], value); + let b = "0"; + if (!p) { + if (tree[1] && typeof tree[1] != "number") + p = getPathTo(tree[1], value); + b = "1"; + } + if (p) + return b + p; + }; + function buildHuffmanTable(codeLengths, values) { + let k = 0, code = [], i, j, length = 16; + while (length > 0 && !codeLengths[length - 1]) + length--; + code.push({ children: [], index: 0 }); + let p = code[0], q; + for (i = 0; i < length; i++) { + for (j = 0; j < codeLengths[i]; j++) { + p = code.pop(); + p.children[p.index] = values[k]; + while (p.index > 0) { + if (code.length === 0) + throw new Error("Could not recreate Huffman Table"); + p = code.pop(); + } + p.index++; + code.push(p); + while (code.length <= i) { + code.push(q = { children: [], index: 0 }); + p.children[p.index] = q.children; + p = q; + } + k++; + } + if (i + 1 < length) { + code.push(q = { children: [], index: 0 }); + p.children[p.index] = q.children; + p = q; + } + } + return code[0].children; + } + var Data = class { + constructor(source, dests, to_hide, hidden) { + this.source = source; + this.dests = dests; + this.to_hide = to_hide; + this.hidden = hidden; + this.dest = []; + this.ltree = new Tree(); + this.dtree = new Tree(); + } + computeReverse() { + this.rltree = buildHuffmanTable(this.ltree.table, this.ltree.trans)[0]; + this.rdtree = buildHuffmanTable(this.dtree.table, this.dtree.trans)[0]; + } + }; + var sltree = new Tree(); + var sdtree = new Tree(); + var rltree; + var rdtree; + var length_bits = new Uint8Array(30); + var length_base = new Uint16Array(30); + var dist_bits = new Uint8Array(30); + var dist_base = new Uint16Array(30); + var clcidx = new Uint8Array([ + 16, + 17, + 18, + 0, + 8, + 7, + 9, + 6, + 10, + 5, + 11, + 4, + 12, + 3, + 13, + 2, + 14, + 1, + 15 + ]); + var code_tree = new Tree(); + var lengths = new Uint8Array(288 + 32); + function tinf_build_bits_base(bits, base, delta, first) { + let i, sum; + for (i = 0; i < delta; ++i) + bits[i] = 0; + for (i = 0; i < 30 - delta; ++i) + bits[i + delta] = i / delta | 0; + for (sum = first, i = 0; i < 30; ++i) { + base[i] = sum; + sum += 1 << bits[i]; + } + } + function tinf_build_fixed_trees(lt, dt) { + let i; + for (i = 0; i < 7; ++i) + lt.table[i] = 0; + lt.table[7] = 24; + lt.table[8] = 152; + lt.table[9] = 112; + for (i = 0; i < 24; ++i) + lt.trans[i] = 256 + i; + for (i = 0; i < 144; ++i) + lt.trans[24 + i] = i; + for (i = 0; i < 8; ++i) + lt.trans[24 + 144 + i] = 280 + i; + for (i = 0; i < 112; ++i) + lt.trans[24 + 144 + 8 + i] = 144 + i; + for (i = 0; i < 5; ++i) + dt.table[i] = 0; + dt.table[5] = 32; + for (i = 0; i < 32; ++i) + dt.trans[i] = i; + } + var offs = new Uint16Array(16); + function tinf_build_tree(t, lengths2, off, num) { + let i, sum; + for (i = 0; i < 16; ++i) + t.table[i] = 0; + for (i = 0; i < num; ++i) + t.table[lengths2[off + i]]++; + t.table[0] = 0; + for (sum = 0, i = 0; i < 16; ++i) { + offs[i] = sum; + sum += t.table[i]; + } + for (i = 0; i < num; ++i) { + if (lengths2[off + i]) + t.trans[offs[lengths2[off + i]]++] = i; + } + } + function tinf_getbit(d) { + return d.source.readSync(1); + } + function tinf_read_bits(d, num, base) { + if (!num) + return base; + const v = d.source.readSync(num) + base; + return v; + } + function tinf_decode_symbol(d, t, copy = true, ext = {}) { + let sum = 0, cur = 0, len = 0; + let s = 0; + do { + const b = d.source.readSync(1); + copy && d.hidden.write(1, b); + s = s << 1 | b; + cur = 2 * cur + b; + ++len; + sum += t.table[len]; + cur -= t.table[len]; + } while (cur >= 0); + ext.length = len; + ext.sym = s; + return t.trans[sum + cur]; + } + function tinf_decode_trees(d, lt, dt) { + let i, num, length; + const hlit = tinf_read_bits(d, 5, 257); + d.hidden?.write(5, hlit - 257); + const hdist = tinf_read_bits(d, 5, 1); + d.hidden?.write(5, hdist - 1); + const hclen = tinf_read_bits(d, 4, 4); + d.hidden?.write(4, hclen - 4); + for (i = 0; i < 19; ++i) + lengths[i] = 0; + for (i = 0; i < hclen; ++i) { + const clen = tinf_read_bits(d, 3, 0); + d.hidden?.write(3, clen); + lengths[clcidx[i]] = clen; + } + tinf_build_tree(code_tree, lengths, 0, 19); + for (num = 0; num < hlit + hdist; ) { + const sym = tinf_decode_symbol(d, code_tree); + let prev; + switch (sym) { + case 16: + prev = lengths[num - 1]; + length = tinf_read_bits(d, 2, 3); + d.hidden?.write(2, length - 3); + for (; length; --length) { + lengths[num++] = prev; + } + break; + case 17: + length = tinf_read_bits(d, 3, 3); + d.hidden?.write(3, length - 3); + for (; length; --length) { + lengths[num++] = 0; + } + break; + case 18: + length = tinf_read_bits(d, 7, 11); + d.hidden?.write(7, length - 11); + for (; length; --length) { + lengths[num++] = 0; + } + break; + default: + lengths[num++] = sym; + break; + } + } + tinf_build_tree(lt, lengths, 0, hlit); + tinf_build_tree(dt, lengths, hlit, hdist); + } + var get_symbol = (value, bits_table, base_table) => { + let i = 0; + for (i = 0; i < base_table.length; ++i) { + if (base_table[i] > value) { + i--; + return [i, bits_table[i], value - base_table[i]]; + } + } + i--; + return [i, bits_table[i], value - base_table[i]]; + }; + var encode_symbol = (sym, tree) => { + const code = getPathTo(tree, sym); + return { + length: code?.length, + val: parseInt(code, 2) + }; + }; + var capacity = 0; + function tinf_inflate_block_data(d, lt, dt) { + let finished = false; + while (1) { + if (finished) { + return true; + } + let sym = tinf_decode_symbol(d, lt); + if (sym === 256) { + return TINF_OK; + } + if (sym < 256) { + d.dest.push(sym); + } else { + sym -= 257; + const length = tinf_read_bits(d, length_bits[sym], length_base[sym]); + if (length_bits[sym]) + d.hidden.write(length_bits[sym], length - length_base[sym]); + const ext = { length: 0, sym: 0 }; + const dist = tinf_decode_symbol(d, dt, false, ext); + let backoffset = tinf_read_bits(d, dist_bits[dist], dist_base[dist]); + const offs2 = d.dest.length - backoffset; + const match = Buffer2.from(d.dest.slice(offs2, offs2 + length)); + if (match.length == length) { + let begin = d.dest.length - 32768; + if (begin < 0) + begin = 0; + let matches = []; + let o = 0; + const slic = Buffer2.from(d.dest.slice(begin + o, d.dest.length)); + while (begin + o < d.dest.length) { + const r = slic.slice(o, d.dest.length).indexOf(match); + if (r >= 0) { + matches.push(r + begin + o); + o += r; + } else { + break; + } + o++; + } + if (matches.length > 1) { + matches = matches.map((e) => -(e - d.dest.length)); + matches.reverse(); + const v = Math.floor(Math.log2(matches.length)); + capacity += v; + if (d.to_hide instanceof BitstreamReader2) { + if (d.to_hide.available) { + const s = d.to_hide.readSync(Math.min(d.to_hide.available, v)); + backoffset = matches[s]; + } else { + finished = true; + } + } else { + const idx = matches.indexOf(backoffset); + d.to_hide.write(v, idx); + } + } + } + const [dsym, dlen, doff] = get_symbol(backoffset, dist_bits, dist_base); + const encdist = encode_symbol(dsym, d.rdtree); + d.hidden.write(encdist.length, revbyte(encdist.val, encdist.length)); + d.hidden.write(dlen, doff); + for (let i = offs2; i < offs2 + length; ++i) { + d.dest.push(d.dest[i]); + } + } + } + } + function tinf_inflate_uncompressed_block(d) { + const length = d.source.readSync(16); + const invlength = d.source.readSync(16); + if (length !== (~invlength & 65535)) + return -4; + for (let i = length; i; --i) + d.dest.push(d.source.readSync(8)); + return TINF_OK; + } + function tinf_uncompress(source, decompressed, to_hide, hidden) { + const decomp = new BitstreamWriter2({ write: decompressed || (() => { + }) }); + const hid = new BitstreamWriter2({ write: hidden || (() => { + }) }); + const d = new Data(source, decomp, to_hide, hid); + let res; + let bfinal, btype; + do { + if (to_hide instanceof BitstreamReader2) { + if (to_hide.available == 0) { + while (source.available && source.offset & 7) { + hid.write(1, source.readSync(1)); + } + return source.offset >> 3; + } + } + bfinal = tinf_getbit(d); + d.hidden.write(1, bfinal); + btype = tinf_read_bits(d, 2, 0); + d.hidden?.write(2, btype); + switch (btype) { + case 0: + res = tinf_inflate_uncompressed_block(d); + break; + case 1: + d.rdtree = rdtree; + d.rltree = rltree; + res = tinf_inflate_block_data(d, sltree, sdtree); + if (res === true) { + continue; + } + break; + case 2: + tinf_decode_trees(d, d.ltree, d.dtree); + d.computeReverse(); + res = tinf_inflate_block_data(d, d.ltree, d.dtree); + if (res === true) { + continue; + } + break; + default: + res = -2; + } + if (res !== TINF_OK) + throw new Error("Data error " + res); + } while (!bfinal); + decomp.end(); + hid.end(); + } + tinf_build_fixed_trees(sltree, sdtree); + tinf_build_bits_base(length_bits, length_base, 4, 3); + tinf_build_bits_base(dist_bits, dist_base, 2, 1); + rltree = buildHuffmanTable(sltree.table, sltree.trans)[0]; + rdtree = buildHuffmanTable(sdtree.table, sdtree.trans)[0]; + length_bits[28] = 0; + length_base[28] = 258; + + // src/pngv3.ts var csettings2; settings.subscribe((b) => { csettings2 = b; @@ -16711,14 +17774,40 @@ const _DOMParser = DOMParser; "t": "take-me-to.space", "z": "z.zz.fo" }; + var extractFromRawDeflate = (b) => { + const src = new BitstreamReader2(); + src.addBuffer(b); + const chnks = []; + const hidden = new BitstreamWriter2({ + write(chunk) { + for (const i of chunk) { + if (i) + chnks.push(i); + else + throw "Finish"; + } + } + }); + try { + tinf_uncompress(src, () => { + }, hidden, () => { + }); + } catch (e) { + if (e == "Finish") + return import_buffer3.Buffer.from(chnks); + } + return false; + }; var extract = async (png) => { const reader = BufferReadStream(png).getReader(); - const sneed = new PNGDecoder(reader); + const sneed = new PNGDecoder(reader, false); const ret = []; let w; if (!csettings2) throw new Error("Settings uninit"); try { + let complete = false; + const idats = []; for await (const [name, chunk, crc, offset] of sneed.chunks()) { let buff; switch (name) { @@ -16765,12 +17854,27 @@ const _DOMParser = DOMParser; } break; case "IDAT": + if (ret.length) + return ret; + buff = await chunk(); + idats.push(buff.slice(4)); case "IEND": - return ret.slice(0, csettings2.maxe); + complete = true; default: break; } } + if (idats.length) { + let decoded; + if ((decoded = extractFromRawDeflate(import_buffer3.Buffer.concat(idats).slice(2))) === false) + return false; + const dec = decoded.toString().split(" ").map((e) => { + if (!(e[0] in rprefs)) + throw "Uhh"; + return `https://${rprefs[e[0]]}/${e.slice(1)}`; + }).join(" "); + return decodeCoom3Payload(import_buffer3.Buffer.from(dec)); + } } catch (e) { console.error(e); } finally { @@ -16792,46 +17896,85 @@ const _DOMParser = DOMParser; }); return [ret, () => b]; }; + var embedInRawDeflate = (b, h) => { + const src = new BitstreamReader2(); + const hid = new BitstreamReader2(); + hid.addBuffer(h); + src.addBuffer(b); + const chnks = []; + const endo = tinf_uncompress(src, () => { + }, hid, (c) => chnks.push(c)); + if (endo) + chnks.push(b.slice(endo)); + return import_buffer3.Buffer.concat(chnks); + }; var inject_data = async (container, injb) => { if (!csettings2) throw new Error("Settings uninit"); - let magic4 = false; + if (csettings2.pmeth < 5) { + let magic4 = false; + const [writestream2, extract8] = BufferWriteStream2(); + const encoder = new PNGEncoder(writestream2); + const decoder = new PNGDecoder(container.stream().getReader()); + for await (const [name, chunk, crc, offset] of decoder.chunks()) { + if (magic4 && name != "IDAT") + break; + if (!magic4 && name == "IDAT") { + const passed = import_buffer3.Buffer.from(injb); + switch (csettings2.pmeth) { + case 0: + await encoder.insertchunk(["tEXt", async () => buildChunk("tEXt", import_buffer3.Buffer.concat([CUM3, passed])), () => Promise.resolve(0), 0]); + break; + case 1: + xor(passed, password); + await encoder.insertchunk(["tEXt", async () => buildChunk("tEXt", import_buffer3.Buffer.concat([CUM4, import_buffer3.Buffer.from(import_buffer3.Buffer.from(passed).toString("base64"))])), () => Promise.resolve(0), 0]); + break; + case 2: + await encoder.insertchunk(["tEXt", async () => buildChunk("tEXt", import_buffer3.Buffer.concat([CUM5, import_buffer3.Buffer.from(import_buffer3.Buffer.from(passed).toString("base64"))])), () => Promise.resolve(0), 0]); + break; + case 3: + await encoder.insertchunk(["tEXt", async () => buildChunk("tEXt", import_buffer3.Buffer.concat([CUM6, import_buffer3.Buffer.from(import_buffer3.Buffer.from(passed).toString("base64"))])), () => Promise.resolve(0), 0]); + break; + case 4: + await encoder.insertchunk(["tEXt", async () => buildChunk("tEXt", import_buffer3.Buffer.concat([CUM7, import_buffer3.Buffer.from(bs58.encode(passed))])), () => Promise.resolve(0), 0]); + break; + } + magic4 = true; + } + await encoder.insertchunk([name, chunk, crc, offset]); + } + await encoder.insertchunk([ + "IEND", + async () => Promise.resolve(buildChunk("IEND", import_buffer3.Buffer.from([]))), + async () => Promise.resolve(0), + 0 + ]); + return extract8(); + } + let pdec = new PNGDecoder(container.stream().getReader()); + const concat = []; + for await (const chk of pdec.chunks()) + if (chk[0] == "IDAT") + concat.push((await chk[1]()).slice(4)); + const comp = import_buffer3.Buffer.concat(concat); + const head = comp.slice(0, 2); + const chksum = comp.slice(-4); + const idatblk = embedInRawDeflate(comp.slice(2, -4), injb); + const bws = BufferWriteStream2(); const [writestream, extract7] = BufferWriteStream2(); - const encoder = new PNGEncoder(writestream); - const decoder = new PNGDecoder(container.stream().getReader()); - for await (const [name, chunk, crc, offset] of decoder.chunks()) { - if (magic4 && name != "IDAT") - break; - if (!magic4 && name == "IDAT") { - const passed = import_buffer3.Buffer.from(injb); - switch (csettings2.pmeth) { - case 0: - await encoder.insertchunk(["tEXt", async () => buildChunk("tEXt", import_buffer3.Buffer.concat([CUM3, passed])), () => Promise.resolve(0), 0]); - break; - case 1: - xor(passed, password); - await encoder.insertchunk(["tEXt", async () => buildChunk("tEXt", import_buffer3.Buffer.concat([CUM4, import_buffer3.Buffer.from(import_buffer3.Buffer.from(passed).toString("base64"))])), () => Promise.resolve(0), 0]); - break; - case 2: - await encoder.insertchunk(["tEXt", async () => buildChunk("tEXt", import_buffer3.Buffer.concat([CUM5, import_buffer3.Buffer.from(import_buffer3.Buffer.from(passed).toString("base64"))])), () => Promise.resolve(0), 0]); - break; - case 3: - await encoder.insertchunk(["tEXt", async () => buildChunk("tEXt", import_buffer3.Buffer.concat([CUM6, import_buffer3.Buffer.from(import_buffer3.Buffer.from(passed).toString("base64"))])), () => Promise.resolve(0), 0]); - break; - case 4: - await encoder.insertchunk(["tEXt", async () => buildChunk("tEXt", import_buffer3.Buffer.concat([CUM7, import_buffer3.Buffer.from(bs58.encode(passed))])), () => Promise.resolve(0), 0]); - break; + const penc = new PNGEncoder(writestream); + pdec = new PNGDecoder(container.stream().getReader()); + let ins = false; + for await (const chk of pdec.chunks()) { + if (chk[0] != "IDAT") { + await penc.insertchunk(chk); + } else { + if (!ins) { + await penc.insertchunk(["IDAT", async () => import_buffer3.Buffer.concat([import_buffer3.Buffer.from("IDAT"), head, idatblk, chksum]), () => Promise.resolve(0), 0]); + ins = true; } - magic4 = true; } - await encoder.insertchunk([name, chunk, crc, offset]); } - await encoder.insertchunk([ - "IEND", - async () => Promise.resolve(buildChunk("IEND", import_buffer3.Buffer.from([]))), - async () => Promise.resolve(0), - 0 - ]); return extract7(); }; var inject = async (container, links) => { @@ -16848,49 +17991,8 @@ const _DOMParser = DOMParser; return inject_data(container, injb); }; var has_embed = async (png) => { - const reader = BufferReadStream(png).getReader(); - const sneed = new PNGDecoder(reader); - try { - for await (const [name, chunk, crc, offset] of sneed.chunks()) { - let buff; - switch (name) { - case "tEXt": - buff = await chunk(); - if (buff.slice(4, 4 + CUM3.length).equals(CUM3)) - return true; - if (buff.slice(4, 4 + CUM4.length).equals(CUM4)) - return true; - if (buff.slice(4, 4 + CUM5.length).equals(CUM5)) - return true; - if (buff.slice(4, 4 + CUM6.length).equals(CUM6)) { - const passed = buff.slice(4 + CUM6.length).toString(); - if (passed.match(/^[0-9a-zA-Z+/=]+$/g)) { - if (import_buffer3.Buffer.from(passed, "base64").toString().split(" ").every((l) => l[0] in rprefs)) - return true; - } - } - if (buff.slice(4, 4 + CUM7.length).equals(CUM7)) { - const passed = buff.slice(4 + CUM7.length).toString(); - if (passed.match(/^[0-9a-zA-Z+/=]+$/g)) { - if (import_buffer3.Buffer.from(passed, "base64").toString().split(" ").every((l) => l[0] in rprefs)) - return true; - if (import_buffer3.Buffer.from(bs58.decode(passed)).toString().split(" ").every((l) => l[0] in rprefs)) - return true; - } - } - break; - case "IDAT": - case "IEND": - return false; - default: - break; - } - } - } catch (e) { - return; - } finally { - reader.releaseLock(); - } + const r = await extract(png); + return !!r; }; var pngv3_default = { extract, @@ -23419,9 +24521,9 @@ const _DOMParser = DOMParser; let select; let mounted; let dispose; - let each_value = [0, 1, 2, 3, 4]; + let each_value = [0, 1, 2, 3, 4, 5]; let each_blocks = []; - for (let i = 0; i < 5; i += 1) { + for (let i = 0; i < 6; i += 1) { each_blocks[i] = create_each_block2(get_each_context2(ctx, each_value, i)); } return { @@ -23429,7 +24531,7 @@ const _DOMParser = DOMParser; label = element("label"); t = text("PNG Embedding method\n "); select = element("select"); - for (let i = 0; i < 5; i += 1) { + for (let i = 0; i < 6; i += 1) { each_blocks[i].c(); } if (ctx[7].pmeth === void 0) @@ -23439,7 +24541,7 @@ const _DOMParser = DOMParser; insert(target, label, anchor); append(label, t); append(label, select); - for (let i = 0; i < 5; i += 1) { + for (let i = 0; i < 6; i += 1) { each_blocks[i].m(select, null); } select_option(select, ctx[7].pmeth); diff --git a/package-lock.json b/package-lock.json index 036d179..8304b8c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,6 +9,7 @@ "version": "1.0.0", "license": "ISC", "dependencies": { + "@astronautlabs/bitstream": "^4.1.2", "base58": "^2.0.1", "blockhash": "^0.2.0", "bs58": "^5.0.0", @@ -48,6 +49,14 @@ "web-ext-types": "^3.2.1" } }, + "node_modules/@astronautlabs/bitstream": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/@astronautlabs/bitstream/-/bitstream-4.1.2.tgz", + "integrity": "sha512-4mkxvaM9O1SLEKAoPaGifEwIGrzArzGNu9FFVv0JPf/KA2u029ufqLVVlGp6GBxiKdb4Ulk5+d3HgW81MjJdxQ==", + "peerDependencies": { + "reflect-metadata": "^0.1.13" + } + }, "node_modules/@babel/code-frame": { "version": "7.16.7", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz", @@ -7359,6 +7368,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/reflect-metadata": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz", + "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==", + "peer": true + }, "node_modules/regenerator-runtime": { "version": "0.13.9", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", @@ -9306,6 +9321,12 @@ } }, "dependencies": { + "@astronautlabs/bitstream": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/@astronautlabs/bitstream/-/bitstream-4.1.2.tgz", + "integrity": "sha512-4mkxvaM9O1SLEKAoPaGifEwIGrzArzGNu9FFVv0JPf/KA2u029ufqLVVlGp6GBxiKdb4Ulk5+d3HgW81MjJdxQ==", + "requires": {} + }, "@babel/code-frame": { "version": "7.16.7", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz", @@ -14735,6 +14756,12 @@ "strip-indent": "^4.0.0" } }, + "reflect-metadata": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz", + "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==", + "peer": true + }, "regenerator-runtime": { "version": "0.13.9", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", diff --git a/package.json b/package.json index 1063816..46f82a1 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "author": "", "license": "ISC", "dependencies": { + "@astronautlabs/bitstream": "^4.1.2", "base58": "^2.0.1", "blockhash": "^0.2.0", "bs58": "^5.0.0", diff --git a/pngextraembedder-0.281.xpi b/pngextraembedder-0.281.xpi new file mode 100644 index 0000000..e41b4d6 Binary files /dev/null and b/pngextraembedder-0.281.xpi differ diff --git a/src/Components/App.svelte b/src/Components/App.svelte index 3d882f6..d041cf8 100644 --- a/src/Components/App.svelte +++ b/src/Components/App.svelte @@ -413,7 +413,7 @@