{"version":3,"sources":["jsdelivr-header.js","/npm/steg@0.1.5/index.js"],"names":[],"mappings":"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","file":"/npm/steg@0.1.5/index.js","sourceRoot":"","sourcesContent":["/**\n * Minified by jsDelivr using Terser v5.39.0.\n * Original file: /npm/steg@0.1.5/index.js\n *\n * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files\n */\n","import aes, { utils as aesUtils } from 'micro-aes-gcm';\nconst ENCRYPTED_METADATA_SIZE = 28;\nfunction validateBits(bitsTaken) {\n    const b = bitsTaken;\n    if (!(Number.isSafeInteger(b) && b >= 1 && b <= 8))\n        throw new Error('Bits taken must be >= 1 and <= 8');\n}\nfunction clearBits(n, bits) {\n    return (n >> bits) << bits;\n}\nfunction readBit(byte, pos) {\n    return (byte >> (7 - pos)) & 1;\n}\nfunction isAlpha(pixel) {\n    return pixel % 4 === 3;\n}\nfunction getRandomByte() {\n    return aesUtils.randomBytes(1)[0];\n}\nexport const createView = (arr) => new DataView(arr.buffer, arr.byteOffset, arr.byteLength);\nexport class RawFile {\n    constructor(data, name) {\n        this.data = data;\n        this.name = name;\n        this.size = data.byteLength;\n        if (!this.name)\n            this.name = `file-${this.size}.file`;\n    }\n    static fromPacked(packed) {\n        const padded = Uint8Array.from(packed);\n        const view = createView(padded);\n        let offset = 0;\n        const nsize = view.getUint8(offset);\n        offset += 1;\n        if (nsize < 1)\n            throw new Error('file name must contain at least 1 character');\n        const name = utils.bytesToUtf8(padded.subarray(offset, offset + nsize));\n        offset += nsize;\n        const fsize = view.getUint32(offset);\n        offset += 4;\n        const unpadded = padded.subarray(offset, offset + fsize);\n        return new RawFile(unpadded, name);\n    }\n    static async fromFileInput(element) {\n        return new Promise((resolve, reject) => {\n            const file = FileReader && element.files && element.files[0];\n            if (!file)\n                return reject();\n            const reader = new FileReader();\n            reader.addEventListener('load', () => {\n                let res = reader.result;\n                if (typeof res === 'string')\n                    res = utils.utf8ToBytes(res);\n                if (!res)\n                    return reject(new Error('No file'));\n                resolve(new RawFile(new Uint8Array(res), file.name));\n            });\n            reader.addEventListener('error', reject);\n            reader.readAsArrayBuffer(file);\n        });\n    }\n    createHeader() {\n        const nbytes = utils.utf8ToBytes(this.name);\n        const nsize = nbytes.byteLength;\n        if (nsize < 1 || nsize > 255)\n            throw new Error('File name must be 1-255 chars');\n        const metadataSize = 1 + nsize + 4;\n        const meta = new Uint8Array(metadataSize);\n        const view = createView(meta);\n        let offset = 0;\n        view.setUint8(offset, nsize);\n        offset += 1;\n        meta.set(nbytes, offset);\n        offset += nsize;\n        view.setUint32(offset, this.size);\n        offset += 4;\n        return meta;\n    }\n    pack() {\n        const header = this.createHeader();\n        const packed = new Uint8Array(header.byteLength + this.size);\n        packed.set(header);\n        packed.set(this.data, header.byteLength);\n        return packed;\n    }\n    packWithPadding(requiredLength) {\n        const packed = this.pack();\n        const difference = requiredLength - packed.length;\n        if (difference < 0)\n            throw new Error('requiredLength is lesser than result');\n        const padded = new Uint8Array(packed.length + difference);\n        padded.set(packed, 0);\n        return padded;\n    }\n    download() {\n        utils.downloadFile(utils.bytesToURL(this.data), this.name);\n    }\n}\nexport class StegImage {\n    constructor(image) {\n        this.image = image;\n        const { canvas, imageData } = this.createCanvas(image);\n        this.canvas = canvas;\n        this.imageData = imageData;\n    }\n    static async fromBytesOrURL(urlOrBytes) {\n        const image = new Image();\n        const src = urlOrBytes instanceof Uint8Array ? utils.bytesToURL(urlOrBytes) : urlOrBytes;\n        await utils.setImageSource(image, src, true);\n        return new StegImage(image);\n    }\n    createCanvas(image = this.image) {\n        const canvas = document.createElement('canvas');\n        canvas.width = image.width;\n        canvas.height = image.height;\n        const context = canvas.getContext('2d');\n        if (!context)\n            throw new Error('Invalid context');\n        context.drawImage(image, 0, 0);\n        const imageData = context.getImageData(0, 0, image.width, image.height);\n        return { canvas, imageData };\n    }\n    reset() {\n        const { canvas, imageData } = this.createCanvas();\n        this.canvas = canvas;\n        this.imageData = imageData;\n    }\n    calcCapacity(bitsTaken) {\n        validateBits(bitsTaken);\n        const channels = this.imageData.data;\n        const rgba = 4;\n        const channelsNoFirst = channels.length - rgba;\n        const pixels = channelsNoFirst / rgba;\n        const rgb = 3;\n        const bits = pixels * rgb * bitsTaken;\n        const bytes = Math.floor(bits / 8);\n        return { bits, bytes };\n    }\n    async hide(rawFile, key, bitsTaken = 1) {\n        const capacity = this.calcCapacity(bitsTaken).bytes;\n        const packed = rawFile.packWithPadding(capacity - ENCRYPTED_METADATA_SIZE);\n        const ciphertext = await aes.encrypt(key, packed);\n        if (ciphertext.byteLength !== capacity)\n            throw new Error('Encrypted blob must be equal to total data length');\n        return await this.hideBlob(ciphertext, bitsTaken);\n    }\n    async reveal(key) {\n        const ciphertext = await this.revealBlob();\n        const packed = await aes.decrypt(key, ciphertext);\n        return RawFile.fromPacked(packed);\n    }\n    async hideBlob(hData, bitsTaken = 1) {\n        if (!(hData instanceof Uint8Array))\n            throw new Error('Uint8Array expected');\n        const canvas = this.canvas;\n        const channels = this.imageData.data;\n        const channelsLen = channels.length;\n        const hDataLen = hData.byteLength;\n        validateBits(bitsTaken);\n        const cap = this.calcCapacity(bitsTaken).bytes;\n        if (hDataLen > cap)\n            throw new Error('StegImage#hideBlob: ' +\n                `Can't hide ${hDataLen} bytes in ${cap} bytes at ${bitsTaken} bits taken`);\n        let channelId = 0;\n        function writeChannel(data, bits = bitsTaken) {\n            const curr = channels[channelId];\n            channels[channelId++] = clearBits(curr, bits) | data;\n            if (isAlpha(channelId))\n                channels[channelId++] = 256;\n        }\n        while (channelId < 3)\n            writeChannel(readBit(bitsTaken - 1, 8 - 3 + channelId), 1);\n        let buf = 0;\n        let bufBits = 0;\n        for (let byte = 0; byte < hData.length; byte++) {\n            let hiddenDataByte = hData[byte];\n            for (let bit = 0; bit < 8; bit++) {\n                buf = (buf << 1) | readBit(hiddenDataByte, bit);\n                bufBits++;\n                if (bufBits === bitsTaken) {\n                    writeChannel(buf);\n                    buf = 0;\n                    bufBits = 0;\n                }\n            }\n        }\n        if (bufBits) {\n            const randomByte = getRandomByte();\n            const leftoverBits = bitsTaken - bufBits;\n            for (let i = 0; i < leftoverBits; i++) {\n                if (i > 7)\n                    throw new Error('StegImage#hideBlob: Need more than 7 random bits');\n                const randomBit = readBit(randomByte, i);\n                buf = (buf << 1) | randomBit;\n                bufBits++;\n            }\n            if (bufBits !== bitsTaken)\n                throw new Error('StegImage#hideBlob: bufBits !== bitsTaken');\n            writeChannel(buf);\n        }\n        while (channelId < channelsLen) {\n            const randomByte = getRandomByte();\n            const bitsTakenMask = 2 ** bitsTaken - 1;\n            writeChannel(randomByte & bitsTakenMask);\n        }\n        if (channelId !== channelsLen) {\n            throw new Error('StegImage#hideBlob: Current pixel length ' +\n                `${channelId} is different from total capacity ${channelsLen}`);\n        }\n        const vctx = canvas.getContext('2d');\n        if (!vctx)\n            throw new Error('StegImage#hideBlob: No context');\n        vctx.putImageData(this.imageData, 0, 0);\n        const vchannels = vctx.getImageData(0, 0, canvas.width, canvas.height).data;\n        for (let i = 0; i < channelsLen; i++) {\n            const v1 = channels[i];\n            const v2 = vchannels[i];\n            if (v1 !== v2) {\n                throw new Error(`StegImage#hideBlob: Mismatch after verification; idx=${i} v1=${v1} v2=${v2} pos=${i % 4}`);\n            }\n        }\n        return await new Promise((resolve, reject) => {\n            canvas.toBlob((b) => {\n                if (b)\n                    resolve(URL.createObjectURL(b));\n                else\n                    reject(new Error('StegImage#hideBlob: No blob'));\n                this.reset();\n            });\n        });\n    }\n    revealBitsTaken() {\n        const channels = this.imageData.data;\n        const bit0 = readBit(channels[0], 7) << 2;\n        const bit1 = readBit(channels[1], 7) << 1;\n        const bit2 = readBit(channels[2], 7);\n        const bitsTaken = 1 + (bit0 | bit1 | bit2);\n        validateBits(bitsTaken);\n        return bitsTaken;\n    }\n    async revealBlob() {\n        const channels = this.imageData.data;\n        const bitsTaken = this.revealBitsTaken();\n        const { bytes } = this.calcCapacity(bitsTaken);\n        const mask = 2 ** bitsTaken - 1;\n        let buf = 0;\n        let bufBits = 0;\n        const out = new Uint8Array(bytes);\n        let outPos = 0;\n        for (let channelId = 4; channelId < channels.length; channelId++) {\n            if (isAlpha(channelId))\n                channelId++;\n            buf = (buf << bitsTaken) | (channels[channelId] & mask);\n            bufBits += bitsTaken;\n            if (bufBits >= 8) {\n                const leftBits = bufBits - 8;\n                out[outPos++] = buf >> leftBits;\n                buf = buf & (2 ** leftBits - 1);\n                bufBits = leftBits;\n            }\n        }\n        return out;\n    }\n}\nexport const utils = {\n    utf8ToBytes(str) {\n        return new TextEncoder().encode(str);\n    },\n    bytesToUtf8(bytes) {\n        return new TextDecoder().decode(bytes);\n    },\n    bytesToURL(bytes) {\n        return URL.createObjectURL(new Blob([bytes]));\n    },\n    setImageSource(el, url, revoke = false) {\n        return new Promise((resolve) => {\n            el.src = url;\n            el.addEventListener('load', () => {\n                if (revoke)\n                    URL.revokeObjectURL(url);\n                resolve();\n            });\n        });\n    },\n    downloadFile(url, fileName = `hidden-${new Date().toISOString()}.png`) {\n        const link = document.createElement('a');\n        link.href = url;\n        link.textContent = 'Download';\n        link.setAttribute('download', fileName);\n        link.click();\n    },\n    formatSize(bytes) {\n        const KB = 1024;\n        const MB = 1024 * 1024;\n        if (bytes < KB)\n            return `${bytes}B`;\n        if (bytes < MB)\n            return `${(bytes / KB).toFixed(2)}KB`;\n        return `${(bytes / MB).toFixed(2)}MB`;\n    }\n};\n"]}