1 line
12 KiB
JavaScript
1 line
12 KiB
JavaScript
|
|
function appendBits(t,e,r){if(e<0||e>31||t>>>e!==0)throw new RangeError("Value out of range");for(let o=e-1;o>=0;o--)r.push(t>>>o&1)}function getBit(t,e){return!!(t>>>e&1)}function assert(t){if(!t)throw new Error("Assertion error")}export class Mode{constructor(t,e){this.modeBits=t,this.numBitsCharCount=e}numCharCountBits(t){return this.numBitsCharCount[Math.floor((t+7)/17)]}}Mode.NUMERIC=new Mode(1,[10,12,14]),Mode.ALPHANUMERIC=new Mode(2,[9,11,13]),Mode.BYTE=new Mode(4,[8,16,16]),Mode.KANJI=new Mode(8,[8,10,12]),Mode.ECI=new Mode(7,[0,0,0]);export class Ecc{constructor(t,e){this.ordinal=t,this.formatBits=e}}Ecc.LOW=new Ecc(0,1),Ecc.MEDIUM=new Ecc(1,0),Ecc.QUARTILE=new Ecc(2,3),Ecc.HIGH=new Ecc(3,2);export class QrSegment{constructor(t,e,r){if(this.mode=t,this.numChars=e,this.bitData=r,e<0)throw new RangeError("Invalid argument");this.bitData=r.slice()}static makeBytes(t){const e=[];for(const r of t)appendBits(r,8,e);return new QrSegment(Mode.BYTE,t.length,e)}static makeNumeric(t){if(!QrSegment.isNumeric(t))throw new RangeError("String contains non-numeric characters");const e=[];for(let r=0;r<t.length;){const o=Math.min(t.length-r,3);appendBits(parseInt(t.substring(r,r+o),10),3*o+1,e),r+=o}return new QrSegment(Mode.NUMERIC,t.length,e)}static makeAlphanumeric(t){if(!QrSegment.isAlphanumeric(t))throw new RangeError("String contains unencodable characters in alphanumeric mode");const e=[];let r;for(r=0;r+2<=t.length;r+=2){let o=45*QrSegment.ALPHANUMERIC_CHARSET.indexOf(t.charAt(r));o+=QrSegment.ALPHANUMERIC_CHARSET.indexOf(t.charAt(r+1)),appendBits(o,11,e)}return r<t.length&&appendBits(QrSegment.ALPHANUMERIC_CHARSET.indexOf(t.charAt(r)),6,e),new QrSegment(Mode.ALPHANUMERIC,t.length,e)}static makeSegments(t){return""===t?[]:QrSegment.isNumeric(t)?[QrSegment.makeNumeric(t)]:QrSegment.isAlphanumeric(t)?[QrSegment.makeAlphanumeric(t)]:[QrSegment.makeBytes(QrSegment.toUtf8ByteArray(t))]}static makeEci(t){const e=[];if(t<0)throw new RangeError("ECI assignment value out of range");if(t<128)appendBits(t,8,e);else if(t<16384)appendBits(2,2,e),appendBits(t,14,e);else{if(!(t<1e6))throw new RangeError("ECI assignment value out of range");appendBits(6,3,e),appendBits(t,21,e)}return new QrSegment(Mode.ECI,0,e)}static isNumeric(t){return QrSegment.NUMERIC_REGEX.test(t)}static isAlphanumeric(t){return QrSegment.ALPHANUMERIC_REGEX.test(t)}getData(){return this.bitData.slice()}static getTotalBits(t,e){let r=0;for(const o of t){const t=o.mode.numCharCountBits(e);if(o.numChars>=1<<t)return 1/0;r+=4+t+o.bitData.length}return r}static toUtf8ByteArray(t){const e=encodeURI(t),r=[];for(let t=0;t<e.length;t++)"%"!==e.charAt(t)?r.push(e.charCodeAt(t)):(r.push(parseInt(e.substring(t+1,t+3),16)),t+=2);return r}}QrSegment.NUMERIC_REGEX=/^[0-9]*$/,QrSegment.ALPHANUMERIC_REGEX=/^[A-Z0-9 $%*+.\/:-]*$/,QrSegment.ALPHANUMERIC_CHARSET="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:";export class QrCode{constructor(t,e,r,o){this.modules=[],this.isFunction=[];let s=o;if(this.version=t,this.errorCorrectionLevel=e,t<QrCode.MIN_VERSION||t>QrCode.MAX_VERSION)throw new RangeError("Version value out of range");if(s<-1||s>7)throw new RangeError("Mask value out of range");this.size=4*t+17;const n=[];for(let t=0;t<this.size;t++)n.push(!1);for(let t=0;t<this.size;t++)this.modules.push(n.slice()),this.isFunction.push(n.slice());this.drawFunctionPatterns();const i=this.addEccAndInterleave(r);if(this.drawCodewords(i),-1===s){let t=1e9;for(let e=0;e<8;e++){this.applyMask(e),this.drawFormatBits(e);const r=this.getPenaltyScore();r<t&&(s=e,t=r),this.applyMask(e)}}assert(s>=0&&s<=7),this.mask=s,this.applyMask(s),this.drawFormatBits(s),this.isFunction=[]}static encodeText(t,e){const r=QrSegment.makeSegments(t);return QrCode.encodeSegments(r,e)}static encodeBinary(t,e){const r=QrSegment.makeBytes(t);return QrCode.encodeSegments([r],e)}static encodeSegments(t,e,r=1,o=40,s=-1,n=!0){if(!(QrCode.MIN_VERSION<=r&&r<=o&&o<=QrCode.MAX_VERSION)||s<-1||s>7)throw new RangeError("Invalid value");let i,a;for(i=r;;i++){const r=8*QrCode.getNumDataCodewords(i,e),s=QrSegment.getTotalBits(t,i);if
|