UNPKG

solid-qr-code

Version:

Solid component to generate QR codes, based on qrcode.react

1,169 lines (1,158 loc) 31.2 kB
import { insert, createComponent, effect, setAttribute, use, spread, mergeProps as mergeProps$1, template } from 'solid-js/web'; import { mergeProps, createMemo, For, createEffect, splitProps } from 'solid-js'; // src/index.tsx // node_modules/.pnpm/scannable@1.1.0/node_modules/scannable/dist/qr/utils/bitUtils.js function getBytes(buffer) { const result = []; while (result.length * 8 < buffer.length) result.push(0); buffer.forEach((b, i) => result[i >>> 3] |= b << 7 - (i & 7)); return result; } function appendBits(buffer, val, len) { if (len < 0 || len > 31 || val >>> len != 0) throw "Value out of range"; for (let i = len - 1; i >= 0; i--) buffer.push(val >>> i & 1); } // node_modules/.pnpm/scannable@1.1.0/node_modules/scannable/dist/qr/utils/constants.js var ECC_CODEWORDS_PER_BLOCK = Object.freeze([ // Version: (note that index 0 is for padding, and is set to an illegal value) //0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40 Error correction level [ -1, 7, 10, 15, 20, 26, 18, 20, 24, 30, 18, 20, 24, 26, 30, 22, 24, 28, 30, 28, 28, 28, 28, 30, 30, 26, 28, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30 ], [ -1, 10, 16, 26, 18, 24, 16, 18, 22, 22, 26, 30, 22, 22, 24, 24, 28, 28, 26, 26, 26, 26, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28 ], [ -1, 13, 22, 18, 26, 18, 24, 18, 22, 20, 24, 28, 26, 24, 20, 30, 24, 28, 28, 26, 30, 28, 30, 30, 30, 30, 28, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30 ], [ -1, 17, 28, 22, 16, 22, 28, 26, 26, 24, 28, 24, 28, 22, 24, 24, 30, 28, 28, 26, 28, 30, 24, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30 ] // High ]); var MIN_VERSION = 1; var MAX_VERSION = 40; var NUM_ERROR_CORRECTION_BLOCKS = Object.freeze([ // Version: (note that index 0 is for padding, and is set to an illegal value) //0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40 Error correction level [ -1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 4, 4, 4, 4, 4, 6, 6, 6, 6, 7, 8, 8, 9, 9, 10, 12, 12, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 24, 25 ], [ -1, 1, 1, 1, 2, 2, 4, 4, 4, 5, 5, 5, 8, 9, 9, 10, 10, 11, 13, 14, 16, 17, 17, 18, 20, 21, 23, 25, 26, 28, 29, 31, 33, 35, 37, 38, 40, 43, 45, 47, 49 ], [ -1, 1, 1, 2, 2, 4, 4, 6, 6, 8, 8, 8, 10, 12, 16, 12, 17, 16, 18, 21, 20, 23, 23, 25, 27, 29, 34, 34, 35, 38, 40, 43, 45, 48, 51, 53, 56, 59, 62, 65, 68 ], [ -1, 1, 1, 2, 4, 4, 4, 5, 6, 8, 8, 11, 11, 16, 16, 18, 16, 19, 21, 25, 25, 25, 34, 30, 32, 35, 37, 40, 42, 45, 48, 51, 54, 57, 60, 63, 66, 70, 74, 77, 81 ] // High ]); // node_modules/.pnpm/scannable@1.1.0/node_modules/scannable/dist/qr/utils/errorCorrection.js function errorCorrection(ordinal, formatBits) { return { ordinal, formatBits }; } var CONSTANTS = Object.freeze({ LOW: errorCorrection(0, 1), MEDIUM: errorCorrection(1, 0), QUARTILE: errorCorrection(2, 3), HIGH: errorCorrection(3, 2) }); function toErrorCorrectionLevel(level) { return CONSTANTS[level.toUpperCase()]; } // node_modules/.pnpm/scannable@1.1.0/node_modules/scannable/dist/qr/utils/reedSolomon.js function multiply(x, y) { if (x >>> 8 != 0 || y >>> 8 != 0) throw "Byte out of range"; let z = 0; for (let i = 7; i >= 0; i--) { z = z << 1 ^ (z >>> 7) * 285; z ^= (y >>> i & 1) * x; } if (z >>> 8 != 0) throw "Assertion error"; return z; } var ReedSolomonGenerator = class { // Coefficients of the divisor polynomial, stored from highest to lowest power, excluding the leading term which // is always 1. For example the polynomial x^3 + 255x^2 + 8x + 93 is stored as the uint8 array {255, 8, 93}. coefficients = []; // Creates a Reed-Solomon ECC generator for the given degree. This could be implemented // as a lookup table over all possible parameter values, instead of as an algorithm. constructor(degree) { if (degree < 1 || degree > 255) throw new RangeError("Degree out of range (1 to 255)"); const coefs = this.coefficients; for (let i = 0; i < degree - 1; i++) coefs.push(0); coefs.push(1); let root = 1; for (let i = 0; i < degree; i++) { for (let j = 0; j < coefs.length; j++) { coefs[j] = multiply(coefs[j], root); if (j + 1 < coefs.length) coefs[j] ^= coefs[j + 1]; } root = multiply(root, 2); } } // Computes and returns the Reed-Solomon error correction codewords for the given // sequence of data codewords. The returned object is always a new byte array. // This method does not alter this object's state (because it is immutable). getRemainder(data) { const result = [...this.coefficients].fill(0); data.forEach((b) => { const factor = b ^ result.shift(); result.push(0); for (let i = 0; i < result.length; i++) result[i] ^= multiply(this.coefficients[i], factor); }); return result; } }; // node_modules/.pnpm/scannable@1.1.0/node_modules/scannable/dist/qr/utils/segmentMode.js function segmentMode(modeBits, numBitsCharCount) { return { modeBits, numBitsCharCount }; } function numCharCountBits(segment, ver) { if (1 <= ver && ver <= 9) return segment.numBitsCharCount[0]; else if (10 <= ver && ver <= 26) return segment.numBitsCharCount[1]; else if (27 <= ver && ver <= 40) return segment.numBitsCharCount[2]; else throw RangeError("Version number out of range (1-40)"); } var CONSTANTS2 = Object.freeze({ NUMERIC: segmentMode(1, [10, 12, 14]), ALPHANUMERIC: segmentMode(2, [9, 11, 13]), BYTE: segmentMode(4, [8, 16, 16]), KANJI: segmentMode(8, [8, 10, 12]), ECI: segmentMode(7, [0, 0, 0]) }); // node_modules/.pnpm/scannable@1.1.0/node_modules/scannable/dist/qr/utils/segment.js var NUMERIC_REGEX = /^[0-9]*$/; var ALPHANUMERIC_REGEX = /^[A-Z0-9 $%*+./:-]*$/; var ALPHANUMERIC_CHARSET = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:"; function qrSegment(mode, numChars, bitData) { if (numChars < 0) throw "Invalid argument"; return { mode, numChars, bitData }; } function makeBytes(data) { const bb = []; data.forEach((b) => appendBits(bb, b, 8)); return qrSegment(CONSTANTS2.BYTE, data.length, bb); } function makeNumeric(digits) { if (!NUMERIC_REGEX.test(digits)) throw "String contains non-numeric characters"; const bb = []; let i; for (i = 0; i + 3 <= digits.length; i += 3) appendBits(bb, parseInt(digits.substr(i, 3), 10), 10); const rem = digits.length - i; if (rem > 0) appendBits(bb, parseInt(digits.substring(i), 10), rem * 3 + 1); return qrSegment(CONSTANTS2.NUMERIC, digits.length, bb); } function makeAlphanumeric(text) { if (!ALPHANUMERIC_REGEX.test(text)) throw "String contains unencodable characters in alphanumeric mode"; const bb = []; let i; for (i = 0; i + 2 <= text.length; i += 2) { let temp = ALPHANUMERIC_CHARSET.indexOf(text.charAt(i)) * 45; temp += ALPHANUMERIC_CHARSET.indexOf(text.charAt(i + 1)); appendBits(bb, temp, 11); } if (i < text.length) appendBits(bb, ALPHANUMERIC_CHARSET.indexOf(text.charAt(i)), 6); return qrSegment(CONSTANTS2.ALPHANUMERIC, text.length, bb); } function getTotalBits(segs, version) { if (version < MIN_VERSION || version > MAX_VERSION) throw "Version number out of range"; let result = 0; for (const seg of segs) { const ccbits = numCharCountBits(seg.mode, version); if (seg.numChars >= 1 << ccbits) return null; result += 4 + ccbits + seg.bitData.length; } return result; } function toUtf8ByteArray(str) { str = encodeURI(str); const result = []; for (let i = 0; i < str.length; i++) { if (str.charAt(i) != "%") result.push(str.charCodeAt(i)); else { result.push(parseInt(str.substr(i + 1, 2), 16)); i += 2; } } return result; } function makeSegments(text) { if (text == "") return []; else if (NUMERIC_REGEX.test(text)) return [makeNumeric(text)]; else if (ALPHANUMERIC_REGEX.test(text)) return [makeAlphanumeric(text)]; else return [makeBytes(toUtf8ByteArray(text))]; } // node_modules/.pnpm/scannable@1.1.0/node_modules/scannable/dist/qr/internal.js function getBit(x, i) { return (x >>> i & 1) != 0; } function getAlignmentPatternPositions(version) { if (version < MIN_VERSION || version > MAX_VERSION) throw "Version number out of range"; else if (version == 1) return []; else { const size = version * 4 + 17; const numAlign = Math.floor(version / 7) + 2; const step = version == 32 ? 26 : Math.ceil((size - 13) / (numAlign * 2 - 2)) * 2; const result = [6]; for (let i = 0, pos = size - 7; i < numAlign - 1; i++, pos -= step) result.splice(1, 0, pos); return result; } } function getNumRawDataModules(ver) { if (ver < MIN_VERSION || ver > MAX_VERSION) throw "Version number out of range"; let result = (16 * ver + 128) * ver + 64; if (ver >= 2) { const numAlign = Math.floor(ver / 7) + 2; result -= (25 * numAlign - 10) * numAlign - 55; if (ver >= 7) result -= 18 * 2; } return result; } function getNumDataCodewords(ver, ecl) { if (ver < MIN_VERSION || ver > MAX_VERSION) throw "Version number out of range"; return Math.floor(getNumRawDataModules(ver) / 8) - ECC_CODEWORDS_PER_BLOCK[ecl.ordinal][ver] * NUM_ERROR_CORRECTION_BLOCKS[ecl.ordinal][ver]; } var PENALTY_N1 = 3; var PENALTY_N2 = 3; var PENALTY_N3 = 40; var PENALTY_N4 = 10; function setFunctionModule(x, y, isBlack, modules, isFunction) { modules[y][x] = isBlack; isFunction[y][x] = true; } function drawFormatBits(mask, errorCorrectionLevel, size, modules, isFunction) { const data = errorCorrectionLevel.formatBits << 3 | mask; let rem = data; for (let i = 0; i < 10; i++) rem = rem << 1 ^ (rem >>> 9) * 1335; const bits = (data << 10 | rem) ^ 21522; if (bits >>> 15 != 0) throw "Assertion error"; for (let i = 0; i <= 5; i++) setFunctionModule(8, i, getBit(bits, i), modules, isFunction); setFunctionModule(8, 7, getBit(bits, 6), modules, isFunction); setFunctionModule(8, 8, getBit(bits, 7), modules, isFunction); setFunctionModule(7, 8, getBit(bits, 8), modules, isFunction); for (let i = 9; i < 15; i++) setFunctionModule(14 - i, 8, getBit(bits, i), modules, isFunction); for (let i = 0; i <= 7; i++) setFunctionModule(size - 1 - i, 8, getBit(bits, i), modules, isFunction); for (let i = 8; i < 15; i++) setFunctionModule(8, size - 15 + i, getBit(bits, i), modules, isFunction); setFunctionModule(8, size - 8, true, modules, isFunction); } function drawVersion(version, size, modules, isFunction) { if (version < 7) return; let rem = version; for (let i = 0; i < 12; i++) rem = rem << 1 ^ (rem >>> 11) * 7973; const bits = version << 12 | rem; if (bits >>> 18 != 0) throw "Assertion error"; for (let i = 0; i < 18; i++) { const bt = getBit(bits, i); const a = size - 11 + i % 3; const b = Math.floor(i / 3); setFunctionModule(a, b, bt, modules, isFunction); setFunctionModule(b, a, bt, modules, isFunction); } } function drawFinderPattern(x, y, size, modules, isFunction) { for (let i = -4; i <= 4; i++) { for (let j = -4; j <= 4; j++) { const dist = Math.max(Math.abs(i), Math.abs(j)); const xx = x + j; const yy = y + i; if (0 <= xx && xx < size && 0 <= yy && yy < size) setFunctionModule(xx, yy, dist != 2 && dist != 4, modules, isFunction); } } } function drawAlignmentPattern(x, y, modules, isFunction) { for (let i = -2; i <= 2; i++) { for (let j = -2; j <= 2; j++) setFunctionModule(x + j, y + i, Math.max(Math.abs(i), Math.abs(j)) != 1, modules, isFunction); } } function drawFunctionPatterns(size, version, errorCorrectionLevel, modules, isFunction) { for (let i = 0; i < size; i++) { setFunctionModule(6, i, i % 2 == 0, modules, isFunction); setFunctionModule(i, 6, i % 2 == 0, modules, isFunction); } drawFinderPattern(3, 3, size, modules, isFunction); drawFinderPattern(size - 4, 3, size, modules, isFunction); drawFinderPattern(3, size - 4, size, modules, isFunction); const alignPatPos = getAlignmentPatternPositions(version); const numAlign = alignPatPos.length; for (let i = 0; i < numAlign; i++) { for (let j = 0; j < numAlign; j++) { if (!(i == 0 && j == 0 || i == 0 && j == numAlign - 1 || i == numAlign - 1 && j == 0)) drawAlignmentPattern(alignPatPos[i], alignPatPos[j], modules, isFunction); } } drawFormatBits(0, errorCorrectionLevel, size, modules, isFunction); drawVersion(version, size, modules, isFunction); } function addEccAndInterleave(data, version, errorCorrectionLevel) { if (data.length != getNumDataCodewords(version, errorCorrectionLevel)) throw "Invalid argument"; const numBlocks = NUM_ERROR_CORRECTION_BLOCKS[errorCorrectionLevel.ordinal][version]; const blockEccLen = ECC_CODEWORDS_PER_BLOCK[errorCorrectionLevel.ordinal][version]; const rawCodewords = Math.floor(getNumRawDataModules(version) / 8); const numShortBlocks = numBlocks - rawCodewords % numBlocks; const shortBlockLen = Math.floor(rawCodewords / numBlocks); const blocks = []; const rs = new ReedSolomonGenerator(blockEccLen); for (let i = 0, k = 0; i < numBlocks; i++) { const dat = data.slice(k, k + shortBlockLen - blockEccLen + (i < numShortBlocks ? 0 : 1)); k += dat.length; const ecc = rs.getRemainder(dat); if (i < numShortBlocks) dat.push(0); ecc.forEach((b) => dat.push(b)); blocks.push(dat); } const result = []; for (let i = 0; i < blocks[0].length; i++) { for (let j = 0; j < blocks.length; j++) { if (i != shortBlockLen - blockEccLen || j >= numShortBlocks) result.push(blocks[j][i]); } } if (result.length != rawCodewords) throw "Assertion error"; return result; } function drawCodewords(data, version, size, isFunction, modules) { if (data.length != Math.floor(getNumRawDataModules(version) / 8)) throw "Invalid argument"; let i = 0; for (let right = size - 1; right >= 1; right -= 2) { if (right == 6) right = 5; for (let vert = 0; vert < size; vert++) { for (let j = 0; j < 2; j++) { const x = right - j; const upward = (right + 1 & 2) == 0; const y = upward ? size - 1 - vert : vert; if (!isFunction[y][x] && i < data.length * 8) { modules[y][x] = getBit(data[i >>> 3], 7 - (i & 7)); i++; } } } } if (i != data.length * 8) throw "Assertion error"; } function applyMask(mask, size, modules, isFunction) { if (mask < 0 || mask > 7) throw "Mask value out of range"; for (let y = 0; y < size; y++) { for (let x = 0; x < size; x++) { let invert; switch (mask) { case 0: invert = (x + y) % 2 == 0; break; case 1: invert = y % 2 == 0; break; case 2: invert = x % 3 == 0; break; case 3: invert = (x + y) % 3 == 0; break; case 4: invert = (Math.floor(x / 3) + Math.floor(y / 2)) % 2 == 0; break; case 5: invert = x * y % 2 + x * y % 3 == 0; break; case 6: invert = (x * y % 2 + x * y % 3) % 2 == 0; break; case 7: invert = ((x + y) % 2 + x * y % 3) % 2 == 0; break; default: throw "Assertion error"; } if (invert && !isFunction[y][x]) modules[y][x] = !modules[y][x]; } } } function getPenaltyScore(size, modules) { let result = 0; for (let y = 0; y < size; y++) { for (let x = 0, runX = 0, colorX = false; x < size; x++) { if (x == 0 || modules[y][x] != colorX) { colorX = modules[y][x]; runX = 1; } else { runX++; if (runX == 5) result += PENALTY_N1; else if (runX > 5) result++; } } } for (let x = 0; x < size; x++) { for (let y = 0, runY = 0, colorY = false; y < size; y++) { if (y == 0 || modules[y][x] != colorY) { colorY = modules[y][x]; runY = 1; } else { runY++; if (runY == 5) result += PENALTY_N1; else if (runY > 5) result++; } } } for (let y = 0; y < size - 1; y++) { for (let x = 0; x < size - 1; x++) { const color = modules[y][x]; if (color == modules[y][x + 1] && color == modules[y + 1][x] && color == modules[y + 1][x + 1]) result += PENALTY_N2; } } for (let y = 0; y < size; y++) { for (let x = 0, bits = 0; x < size; x++) { bits = bits << 1 & 2047 | (modules[y][x] ? 1 : 0); if (x >= 10 && (bits == 93 || bits == 1488)) result += PENALTY_N3; } } for (let x = 0; x < size; x++) { for (let y = 0, bits = 0; y < size; y++) { bits = bits << 1 & 2047 | (modules[y][x] ? 1 : 0); if (y >= 10 && (bits == 93 || bits == 1488)) result += PENALTY_N3; } } let black = 0; modules.forEach((row) => { row.forEach((color) => { if (color) black++; }); }); const total = size * size; const k = Math.ceil(Math.abs(black * 20 - total * 10) / total) - 1; result += k * PENALTY_N4; return result; } function qrCode(datacodewords, mask, version, errorCorrectionLevel) { if (mask < -1 || mask > 7) throw "Mask value out of range"; if (version < MIN_VERSION || version > MAX_VERSION) throw "Version value out of range"; const size = version * 4 + 17; const modules = []; const isFunction = []; const row = []; for (let i = 0; i < size; i++) row.push(false); for (let i = 0; i < size; i++) { modules.push(row.slice()); isFunction.push(row.slice()); } drawFunctionPatterns(size, version, errorCorrectionLevel, modules, isFunction); const allCodewords = addEccAndInterleave(datacodewords, version, errorCorrectionLevel); drawCodewords(allCodewords, version, size, isFunction, modules); if (mask == -1) { let minPenalty = Number.MAX_SAFE_INTEGER; for (let i = 0; i < 8; i++) { drawFormatBits(i, errorCorrectionLevel, size, modules, isFunction); applyMask(i, size, modules, isFunction); const penalty = getPenaltyScore(size, modules); if (penalty < minPenalty) { mask = i; minPenalty = penalty; } applyMask(i, size, modules, isFunction); } } if (mask < 0 || mask > 7) throw "Assertion error"; drawFormatBits(mask, errorCorrectionLevel, size, modules, isFunction); applyMask(mask, size, modules, isFunction); return { version, size, mask, errorCorrectionLevel, modules, isFunction }; } function encodeSegments(segs, ecl, minVersion = 1, maxVersion = 40, mask = -1, boostEcl = true) { if (!(MIN_VERSION <= minVersion && minVersion <= maxVersion && maxVersion <= MAX_VERSION) || mask < -1 || mask > 7) throw "Invalid value"; let version; let dataUsedBits; for (version = minVersion; ; version++) { const dataCapacityBits2 = getNumDataCodewords(version, ecl) * 8; const usedBits = getTotalBits(segs, version); if (usedBits != null && usedBits <= dataCapacityBits2) { dataUsedBits = usedBits; break; } if (version >= maxVersion) throw `Data too long (> ${dataCapacityBits2 / 8} bytes)`; } [ CONSTANTS.MEDIUM, CONSTANTS.QUARTILE, CONSTANTS.HIGH ].forEach((newEcl) => { if (boostEcl && dataUsedBits <= getNumDataCodewords(version, newEcl) * 8) ecl = newEcl; }); const bb = []; segs.forEach((seg) => { appendBits(bb, seg.mode.modeBits, 4); appendBits(bb, seg.numChars, numCharCountBits(seg.mode, version)); seg.bitData.forEach((b) => bb.push(b)); }); const dataCapacityBits = getNumDataCodewords(version, ecl) * 8; if (bb.length > dataCapacityBits) throw "Assertion error"; appendBits(bb, 0, Math.min(4, dataCapacityBits - bb.length)); appendBits(bb, 0, (8 - bb.length % 8) % 8); if (bb.length % 8 != 0) throw "Assertion error"; for (let padByte = 236; bb.length < dataCapacityBits; padByte ^= 236 ^ 17) appendBits(bb, padByte, 8); return qrCode(getBytes(bb), mask, version, ecl); } function encodeText(text, ecl) { const segs = makeSegments(text); return encodeSegments(segs, ecl); } // node_modules/.pnpm/scannable@1.1.0/node_modules/scannable/dist/qr/Frame.js var MaskType; (function(MaskType3) { MaskType3[MaskType3["ALTERNATING_TILES"] = 0] = "ALTERNATING_TILES"; MaskType3[MaskType3["ALTERNATING_HORIZONTAL_LINES"] = 1] = "ALTERNATING_HORIZONTAL_LINES"; MaskType3[MaskType3["ALTERNATING_VERTICAL_LINES_TWO_GAP"] = 2] = "ALTERNATING_VERTICAL_LINES_TWO_GAP"; MaskType3[MaskType3["DIAGONAL"] = 3] = "DIAGONAL"; MaskType3[MaskType3["FOUR_BY_TWO_RECTANGLE_ALTERNATING"] = 4] = "FOUR_BY_TWO_RECTANGLE_ALTERNATING"; MaskType3[MaskType3["FLOWER_IN_SQAURE"] = 5] = "FLOWER_IN_SQAURE"; MaskType3[MaskType3["DIAGONAL_SQUARE"] = 6] = "DIAGONAL_SQUARE"; MaskType3[MaskType3["ALTERNATING_PUZZLE_PIECE"] = 7] = "ALTERNATING_PUZZLE_PIECE"; })(MaskType || (MaskType = {})); var defaultFrameOptions = Object.freeze({ level: CONSTANTS.LOW }); function generateFrame(options) { const level = options.level ?? defaultFrameOptions.level; const qrCode2 = encodeText(options.value, typeof level == "string" ? toErrorCorrectionLevel(level) : level); return { buffer: Uint8Array.from(qrCode2.modules.map((row) => row.map((bit) => bit ? 1 : 0)).flat()), size: qrCode2.size, version: qrCode2.version }; } var _tmpl$ = /* @__PURE__ */ template(`<svg>`); var _tmpl$2 = /* @__PURE__ */ template(`<svg><rect></svg>`, false, true); var _tmpl$3 = /* @__PURE__ */ template(`<canvas>`); var _tmpl$4 = /* @__PURE__ */ template(`<h1>`); var ErrorCorrectionLevel = { LOW: "low", MEDIUM: "medium", QUARTILE: "quartile", HIGH: "high" }; var MaskType2 = { ALTERNATING_TILES: 0, ALTERNATING_HORIZONTAL_LINES: 1, ALTERNATING_VERTICAL_LINES_TWO_GAP: 2, DIAGONAL: 3, FOUR_BY_TWO_RECTANGLE_ALTERNATING: 4, FLOWER_IN_SQAURE: 5, DIAGONAL_SQUARE: 6, ALTERNATING_PUZZLE_PIECE: 7 }; var QRCodeSVG = (_props) => { const props = mergeProps({ ...defaultFrameOptions, backgroundColor: "white", backgroundAlpha: 1, foregroundColor: "black", foregroundAlpha: 1, width: 100, height: 100 }, _props); const frame = createMemo(() => generateFrame(props)); const moduleSizeWidth = createMemo(() => props.width / frame().size); const moduleSizeHeight = createMemo(() => props.height / frame().size); const rectangles = createMemo(() => { let rects = []; for (let i = 0; i < frame().size; i++) { for (let j = 0; j < frame().size; j++) { rects = [...rects, { x: moduleSizeWidth() * i, y: moduleSizeHeight() * j, enabled: frame().buffer[j * frame().size + i] === 1 }]; } } return rects; }); return (() => { var _el$ = _tmpl$(); insert(_el$, createComponent(For, { get each() { return rectangles(); }, children: (rectangle) => (() => { var _el$2 = _tmpl$2(); effect((_p$) => { var _v$3 = moduleSizeWidth(), _v$4 = moduleSizeHeight(), _v$5 = rectangle.x, _v$6 = rectangle.y, _v$7 = rectangle.enabled ? props.foregroundColor : props.backgroundColor, _v$8 = rectangle.enabled ? props.foregroundAlpha : props.backgroundAlpha; _v$3 !== _p$.e && setAttribute(_el$2, "width", _p$.e = _v$3); _v$4 !== _p$.t && setAttribute(_el$2, "height", _p$.t = _v$4); _v$5 !== _p$.a && setAttribute(_el$2, "x", _p$.a = _v$5); _v$6 !== _p$.o && setAttribute(_el$2, "y", _p$.o = _v$6); _v$7 !== _p$.i && ((_p$.i = _v$7) != null ? _el$2.style.setProperty("fill", _v$7) : _el$2.style.removeProperty("fill")); _v$8 !== _p$.n && ((_p$.n = _v$8) != null ? _el$2.style.setProperty("opacity", _v$8) : _el$2.style.removeProperty("opacity")); return _p$; }, { e: void 0, t: void 0, a: void 0, o: void 0, i: void 0, n: void 0 }); return _el$2; })() })); effect((_p$) => { var _v$ = props.width, _v$2 = props.height; _v$ !== _p$.e && setAttribute(_el$, "width", _p$.e = _v$); _v$2 !== _p$.t && setAttribute(_el$, "height", _p$.t = _v$2); return _p$; }, { e: void 0, t: void 0 }); return _el$; })(); }; var QRCodeCanvas = (_props) => { const props = mergeProps({ ...defaultFrameOptions, backgroundColor: "white", backgroundAlpha: 1, foregroundColor: "black", foregroundAlpha: 1, width: 100, height: 100, x: 0, y: 0 }, _props); let ref; const frame = createMemo(() => generateFrame(props)); const rawModuleSizeWidth = createMemo(() => props.width / frame().size); const rawModuleSizeHeight = createMemo(() => props.height / frame().size); const offsetX = createMemo(() => rawModuleSizeWidth() % 1 * frame().size / 2); const offsetY = createMemo(() => rawModuleSizeHeight() % 1 * frame().size / 2); const moduleSizeWidth = createMemo(() => Math.floor(rawModuleSizeWidth())); const moduleSizeHeight = createMemo(() => Math.floor(rawModuleSizeHeight())); createEffect(() => { const context = ref.getContext("2d"); if (!context) { return; } context.clearRect(0, 0, ref.width, ref.height); for (let i = 0; i < frame().size; i++) { for (let j = 0; j < frame().size; j++) { if (frame().buffer[j * frame().size + i]) { context.fillStyle = props.foregroundColor; context.globalAlpha = props.foregroundAlpha; context.fillRect(offsetX() + moduleSizeWidth() * i + props.x, offsetY() + moduleSizeHeight() * j + props.y, moduleSizeWidth(), moduleSizeHeight()); } else { context.fillStyle = props.backgroundColor; context.globalAlpha = props.backgroundAlpha; context.fillRect(offsetX() + moduleSizeWidth() * i + props.x, offsetY() + moduleSizeHeight() * j + props.y, moduleSizeWidth(), moduleSizeHeight()); } } } }); return (() => { var _el$3 = _tmpl$3(); use((e) => ref = e, _el$3); effect((_p$) => { var _v$9 = props.height, _v$10 = props.width; _v$9 !== _p$.e && setAttribute(_el$3, "height", _p$.e = _v$9); _v$10 !== _p$.t && setAttribute(_el$3, "width", _p$.t = _v$10); return _p$; }, { e: void 0, t: void 0 }); return _el$3; })(); }; var QRCodeText = (_props) => { const props = mergeProps({ ...defaultFrameOptions, foregroundChar: "#", backgroundChar: " " }, _props); const [, rest] = splitProps(props, ["foregroundChar", "backgroundChar", "value", "level", "maskType", "innerHTML", "style"]); const frame = createMemo(() => generateFrame(props)); const qrText = createMemo(() => { let str = ""; for (let i = 0; i < frame().size; i++) { for (let j = 0; j < frame().size; j++) { if (frame().buffer[j * frame().size + i]) { str += props.foregroundChar; } else { str += props.backgroundChar; } } if (i !== frame().size - 1) { str += "\n"; } } str = str.replaceAll("\n", "<br/>").replaceAll(" ", "&nbsp;"); return str; }); return (() => { var _el$4 = _tmpl$4(); spread(_el$4, mergeProps$1({ get style() { return { "line-height": "8px", "letter-spacing": "0", "font-size": "12px", "margin-top": "2.5rem", "margin-bottom": "2.5rem", "font-family": "monospace", ...typeof props.style === "object" ? props.style : {} }; }, get innerHTML() { return qrText(); } }, rest), false, false); return _el$4; })(); }; var QRCodeTwoTone = (_props) => { const props = mergeProps({ ...defaultFrameOptions, solidCharacter: "\u2588", solidTopCharacter: "\u2580", solidBottomCharacter: "\u2584", emptyCharacter: " " }, _props); const [, rest] = splitProps(props, ["value", "level", "maskType", "innerHTML", "style", "solidCharacter", "solidBottomCharacter", "solidTopCharacter", "emptyCharacter"]); const qrText = createMemo(() => { const frame = generateFrame(props); let str = ""; for (let i = 0; i < frame.size; i += 2) { for (let j = 0; j < frame.size; j++) { const topExists = frame.buffer[i * frame.size + j]; const bottomExists = frame.buffer[(i + 1) * frame.size + j]; if (topExists && bottomExists) { str += props.solidCharacter; } else if (!topExists && bottomExists) { str += props.solidBottomCharacter; } else if (topExists && !bottomExists) { str += props.solidTopCharacter; } else { str += props.emptyCharacter; } } if (i !== frame.size - 1) { str += "\n"; } } str = str.replaceAll("\n", "<br/>").replaceAll(" ", "&nbsp;"); return str; }); return (() => { var _el$5 = _tmpl$4(); spread(_el$5, mergeProps$1({ get style() { return { "line-height": "12px", "font-size": "12px", "margin-top": "2.5rem", "margin-bottom": "2.5rem", "font-family": "monospace", ...typeof props.style === "object" ? props.style : {} }; }, get innerHTML() { return qrText(); } }, rest), false, false); return _el$5; })(); }; export { ErrorCorrectionLevel, MaskType2 as MaskType, QRCodeCanvas, QRCodeSVG, QRCodeText, QRCodeTwoTone };