/** * QR code implementation for the browser. * * Author: Sangmin David Shim. * https://github.com/davidshimjs/qrcodejs * * Licensed under the MIT license. * https://opensource.org/license/mit * * The word `QR Code` is registered trademark of DENSO WAVE INCORPORATED. * https://www.qrcode.com/en/patent.html * * * Modified by @flipeador. * * - Convert to ES6 module. * - Minify most of the code. * - Remove unused and obsolete code. * - Remove the creation of the img element. * - Remove svg support due to poor performance. * * - Change the toUTF8 function to use TextEncoder. * * - Fix index out of bounds exception. * - https://github.com/davidshimjs/qrcodejs/issues/293 * * - Fix QRRSBlock.RS_BLOCK_TABLE. * - https://github.com/davidshimjs/qrcodejs/issues/288 * * - Add full UTF-8 encoding support by 19z. * - https://github.com/19z/qrcodejs-fixUTF8 * - https://github.com/davidshimjs/qrcodejs/issues/266 */ // eslint-disable-next-line function Ɐ(t){return(new TextEncoder).encode(t)}class π{constructor(e){this.χ=t.Ǔ,this.Ƭ=Ɐ(e)}Ǚ(){return this.Ƭ.length}write(t){for(let e=0,o=this.Ƭ.length;e=7&&this.Ƶ(t),null==this.Ȓ&&(this.Ȓ=θ.Ȑ(this.Ǭ,this.Ʋ,this.Ȕ)),this.ψ(this.Ȓ,e)},Ɠ:function(t,e){for(let o=-1;o<=7;o++)if(!(t+o<=-1||this.count<=t+o))for(let r=-1;r<=7;r++)e+r<=-1||this.count<=e+r||(this.Ȥ[t+o][e+r]=0<=o&&o<=6&&(0==r||6==r)||0<=r&&r<=6&&(0==o||6==o)||2<=o&&o<=4&&2<=r&&r<=4)},Ǎ:function(){let t=0,e=0;for(let o=0;o<8;o++){this.Ȧ(!0,o);let r=a.Ǒ(this);(0==o||t>r)&&(t=r,e=o)}return e},Ɲ:function(){for(let t=8;t>o&1);this.Ȥ[Math.floor(o/3)][o%3+this.count-8-3]=r}for(let o=0;o<18;o++){let r=!t&&1==(e>>o&1);this.Ȥ[o%3+this.count-8-3][Math.floor(o/3)]=r}},Ƙ:function(t,e){let o=this.Ʋ<<3|e,r=a.Ƈ(o);for(let e=0;e<15;e++){let o=!t&&1==(r>>e&1);e<6?this.Ȥ[e][8]=o:e<8?this.Ȥ[e+1][8]=o:this.Ȥ[this.count-15+e][8]=o}for(let e=0;e<15;e++){let o=!t&&1==(r>>e&1);e<8?this.Ȥ[8][this.count-e-1]=o:e<9?this.Ȥ[8][15-e-1+1]=o:this.Ȥ[8][15-e-1]=o}this.Ȥ[this.count-8][8]=!t},ψ:function(t,e){let o=-1,r=this.count-1,l=7,n=0;for(let i=this.count-1;i>0;i-=2)for(6==i&&i--;;){for(let o=0;o<2;o++)if(null==this.Ȥ[r][i-o]){let s=!1;n>>l&1)),a.Ǹ(e,r,i-o)&&(s=!s),this.Ȥ[r][i-o]=s,l--,-1==l&&(n++,l=7)}if(r+=o,r<0||this.count<=r){r-=o,o=-o;break}}}},θ.Ǘ=236,θ.ξ=17,θ.Ȑ=function(t,e,o){let r=Ǟ.Ǩ(t,e),l=new λ;for(let e=0;e8*n)throw new Error();for(l.length+4<=8*n&&l.Ȗ(0,4);l.length%8!=0;)l.Ǧ(!1);for(;!(l.length>=8*n||(l.Ȗ(θ.Ǘ,8),l.length>=8*n));)l.Ȗ(θ.ξ,8);return θ.Ȫ(l,r)},θ.Ȫ=function(t,e){let o=0,r=0,l=0,n=new Array(e.length),i=new Array(e.length);for(let s=0;s=0?f.get(e):0}}let s=0;for(let t=0;t=0;)e^=a.Ȉ<=0;)e^=a.Ǵ<>>=1;return e},Ǐ:function(t){return a.Ǖ[t-1]},Ǹ:function(t,e,a){switch(t){case o:return(e+a)%2==0;case r:return e%2==0;case l:return a%3==0;case n:return(e+a)%3==0;case i:return(Math.floor(e/2)+Math.floor(a/3))%2==0;case s:return e*a%2+e*a%3==0;case u:return(e*a%2+e*a%3)%2==0;case h:return(e*a%3+(e+a)%2)%2==0;default:throw new Error()}},Ɗ:function(t){let e=new Ǜ([1],0);for(let o=0;o5&&(o+=3+n-5)}for(let r=0;r=256;)t-=255;return g.Ț[t]},Ț:new Array(256),Ȟ:new Array(256)};for(let t=0;t<8;t++)g.Ț[t]=1<>>7-t%8&1)}Ȗ(t,e){for(let o=0;o>>e-o-1&1))}Ǧ(t){let e=Math.floor(this.length/8);this.Ǥ.length<=e&&this.Ǥ.push(0),t&&(this.Ǥ[e]|=128>>>this.length%8),this.length++}}let f=[[17,14,11,7],[32,26,20,14],[53,42,32,24],[78,62,46,34],[106,84,60,44],[134,106,74,58],[154,122,86,64],[192,152,108,84],[230,180,130,98],[271,213,151,119],[321,251,177,137],[367,287,203,155],[425,331,241,177],[458,362,258,194],[520,412,292,220],[586,450,322,250],[644,504,364,280],[718,560,394,310],[792,624,442,338],[858,666,482,382],[929,711,509,403],[1003,779,565,439],[1091,857,611,461],[1171,911,661,511],[1273,997,715,535],[1367,1059,751,593],[1465,1125,805,625],[1528,1190,868,658],[1628,1264,908,698],[1732,1370,982,742],[1840,1452,1030,790],[1952,1538,1112,842],[2068,1628,1168,898],[2188,1722,1228,958],[2303,1809,1283,983],[2431,1911,1351,1051],[2563,1989,1423,1093],[2699,2099,1499,1139],[2809,2213,1579,1219],[2953,2331,1663,1273]];function z(t,o){let r=1,l=Ɐ(t).length;for(let t=0;tf.length)throw new Error();return r}function createModel(µ,δ){let ζ=new θ(z(µ,e[δ]),e[δ]);ζ.η(µ);ζ.Ω();return ζ;} /** * The size of each cell in the canvas, in pixels. */ export const CELL_SIZE_PX = 12; /** * Get the size of each cell in the canvas, in device pixels. */ function getCellDevicePixelSize({ size }) { return Math.floor((size || CELL_SIZE_PX) * devicePixelRatio); } function fillRect(ctx, x, y, size, color) { if (color && color !== 'transparent') { ctx.fillStyle = color; ctx.fillRect(x * size, y * size, size, size); } } /** * Draws a QR code on a canvas element. * @param {HTMLCanvasElement} $canvas * @param {string} text * @param {object} [options] * @param {'L'|'M'|'Q'|'H'} [options.level] * @param {string} [options.color] * @param {string} [options.background] * @param {string} [options.border] * @param {number} [options.size] * @returns {number} */ export function draw($canvas, text, options={}) { options.level ??= 'L'; options.color ??= 'black'; options.background ??= 'white'; const size = getCellDevicePixelSize(options); const border = options?.border ? 2 * size : 0; const ctx = $canvas.getContext('2d'); const model = createModel(text, options.level); $canvas.width = model.count * size + border; $canvas.height = model.count * size + border; if (border) { ctx.lineWidth = border; ctx.strokeStyle = options.border; ctx.strokeRect(0, 0, $canvas.width, $canvas.height); } const n = border ? 1 : 0; for (let x = 0; x < model.count; x++) for (let y = 0; y < model.count; y++) model.isDark(y, x) ? fillRect(ctx, n+x, n+y, size, options.color) : fillRect(ctx, n+x, n+y, size, options.background); return model.count; }