index.js 42 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222
  1. module.exports = (function() {
  2. var __MODS__ = {};
  3. var __DEFINE__ = function(modId, func, req) { var m = { exports: {}, _tempexports: {} }; __MODS__[modId] = { status: 0, func: func, req: req, m: m }; };
  4. var __REQUIRE__ = function(modId, source) { if(!__MODS__[modId]) return require(source); if(!__MODS__[modId].status) { var m = __MODS__[modId].m; m._exports = m._tempexports; var desp = Object.getOwnPropertyDescriptor(m, "exports"); if (desp && desp.configurable) Object.defineProperty(m, "exports", { set: function (val) { if(typeof val === "object" && val !== m._exports) { m._exports.__proto__ = val.__proto__; Object.keys(val).forEach(function (k) { m._exports[k] = val[k]; }); } m._tempexports = val }, get: function () { return m._tempexports; } }); __MODS__[modId].status = 1; __MODS__[modId].func(__MODS__[modId].req, m, m.exports); } return __MODS__[modId].m.exports; };
  5. var __REQUIRE_WILDCARD__ = function(obj) { if(obj && obj.__esModule) { return obj; } else { var newObj = {}; if(obj != null) { for(var k in obj) { if (Object.prototype.hasOwnProperty.call(obj, k)) newObj[k] = obj[k]; } } newObj.default = obj; return newObj; } };
  6. var __REQUIRE_DEFAULT__ = function(obj) { return obj && obj.__esModule ? obj.default : obj; };
  7. __DEFINE__(1618706661370, function(require, module, exports) {
  8. module.exports = require('./demo/utils')
  9. }, function(modId) {var map = {"./demo/utils":1618706661371}; return __REQUIRE__(map[modId], modId); })
  10. __DEFINE__(1618706661371, function(require, module, exports) {
  11. var barcode = require('./barcode');
  12. var qrcode = require('./qrcode');
  13. function convert_length(length) {
  14. return Math.round(wx.getSystemInfoSync().windowWidth * length / 750);
  15. }
  16. function barc(id, code, width, height) {
  17. barcode.code128(wx.createCanvasContext(id), code, convert_length(width), convert_length(height))
  18. }
  19. function qrc(id, code, width, height) {
  20. qrcode.api.draw(code, {
  21. ctx: wx.createCanvasContext(id),
  22. width: convert_length(width),
  23. height: convert_length(height)
  24. })
  25. }
  26. module.exports = {
  27. barcode: barc,
  28. qrcode: qrc
  29. }
  30. }, function(modId) { var map = {"./barcode":1618706661372,"./qrcode":1618706661373}; return __REQUIRE__(map[modId], modId); })
  31. __DEFINE__(1618706661372, function(require, module, exports) {
  32. var CHAR_TILDE = 126;
  33. var CODE_FNC1 = 102;
  34. var SET_STARTA = 103;
  35. var SET_STARTB = 104;
  36. var SET_STARTC = 105;
  37. var SET_SHIFT = 98;
  38. var SET_CODEA = 101;
  39. var SET_CODEB = 100;
  40. var SET_STOP = 106;
  41. var REPLACE_CODES = {
  42. CHAR_TILDE: CODE_FNC1 //~ corresponds to FNC1 in GS1-128 standard
  43. }
  44. var CODESET = {
  45. ANY: 1,
  46. AB: 2,
  47. A: 3,
  48. B: 4,
  49. C: 5
  50. };
  51. function getBytes(str) {
  52. var bytes = [];
  53. for (var i = 0; i < str.length; i++) {
  54. bytes.push(str.charCodeAt(i));
  55. }
  56. return bytes;
  57. }
  58. exports.code128 = function (ctx, text, width, height) {
  59. width = parseInt(width);
  60. height = parseInt(height);
  61. var codes = stringToCode128(text);
  62. var g = new Graphics(ctx, width, height);
  63. var barWeight = g.area.width / ((codes.length - 3) * 11 + 35);
  64. var x = g.area.left;
  65. var y = g.area.top;
  66. for (var i = 0; i < codes.length; i++) {
  67. var c = codes[i];
  68. //two bars at a time: 1 black and 1 white
  69. for (var bar = 0; bar < 8; bar += 2) {
  70. var barW = PATTERNS[c][bar] * barWeight;
  71. // var barH = height - y - this.border;
  72. var barH = height - y;
  73. var spcW = PATTERNS[c][bar + 1] * barWeight;
  74. //no need to draw if 0 width
  75. if (barW > 0) {
  76. g.fillFgRect(x, y, barW, barH);
  77. }
  78. x += barW + spcW;
  79. }
  80. }
  81. ctx.draw();
  82. }
  83. function stringToCode128(text) {
  84. var barc = {
  85. currcs: CODESET.C
  86. };
  87. var bytes = getBytes(text);
  88. //decide starting codeset
  89. var index = bytes[0] == CHAR_TILDE ? 1 : 0;
  90. var csa1 = bytes.length > 0 ? codeSetAllowedFor(bytes[index++]) : CODESET.AB;
  91. var csa2 = bytes.length > 0 ? codeSetAllowedFor(bytes[index++]) : CODESET.AB;
  92. barc.currcs = getBestStartSet(csa1, csa2);
  93. barc.currcs = perhapsCodeC(bytes, barc.currcs);
  94. //if no codeset changes this will end up with bytes.length+3
  95. //start, checksum and stop
  96. var codes = new Array();
  97. switch (barc.currcs) {
  98. case CODESET.A:
  99. codes.push(SET_STARTA);
  100. break;
  101. case CODESET.B:
  102. codes.push(SET_STARTB);
  103. break;
  104. default:
  105. codes.push(SET_STARTC);
  106. break;
  107. }
  108. for (var i = 0; i < bytes.length; i++) {
  109. var b1 = bytes[i]; //get the first of a pair
  110. //should we translate/replace
  111. if (b1 in REPLACE_CODES) {
  112. codes.push(REPLACE_CODES[b1]);
  113. i++ //jump to next
  114. b1 = bytes[i];
  115. }
  116. //get the next in the pair if possible
  117. var b2 = bytes.length > (i + 1) ? bytes[i + 1] : -1;
  118. codes = codes.concat(codesForChar(b1, b2, barc.currcs));
  119. //code C takes 2 chars each time
  120. if (barc.currcs == CODESET.C) i++;
  121. }
  122. //calculate checksum according to Code 128 standards
  123. var checksum = codes[0];
  124. for (var weight = 1; weight < codes.length; weight++) {
  125. checksum += (weight * codes[weight]);
  126. }
  127. codes.push(checksum % 103);
  128. codes.push(SET_STOP);
  129. //encoding should now be complete
  130. return codes;
  131. function getBestStartSet(csa1, csa2) {
  132. //tries to figure out the best codeset
  133. //to start with to get the most compact code
  134. var vote = 0;
  135. vote += csa1 == CODESET.A ? 1 : 0;
  136. vote += csa1 == CODESET.B ? -1 : 0;
  137. vote += csa2 == CODESET.A ? 1 : 0;
  138. vote += csa2 == CODESET.B ? -1 : 0;
  139. //tie goes to B due to my own predudices
  140. return vote > 0 ? CODESET.A : CODESET.B;
  141. }
  142. function perhapsCodeC(bytes, codeset) {
  143. for (var i = 0; i < bytes.length; i++) {
  144. var b = bytes[i]
  145. if ((b < 48 || b > 57) && b != CHAR_TILDE)
  146. return codeset;
  147. }
  148. return CODESET.C;
  149. }
  150. //chr1 is current byte
  151. //chr2 is the next byte to process. looks ahead.
  152. function codesForChar(chr1, chr2, currcs) {
  153. var result = [];
  154. var shifter = -1;
  155. if (charCompatible(chr1, currcs)) {
  156. if (currcs == CODESET.C) {
  157. if (chr2 == -1) {
  158. shifter = SET_CODEB;
  159. currcs = CODESET.B;
  160. }
  161. else if ((chr2 != -1) && !charCompatible(chr2, currcs)) {
  162. //need to check ahead as well
  163. if (charCompatible(chr2, CODESET.A)) {
  164. shifter = SET_CODEA;
  165. currcs = CODESET.A;
  166. }
  167. else {
  168. shifter = SET_CODEB;
  169. currcs = CODESET.B;
  170. }
  171. }
  172. }
  173. }
  174. else {
  175. //if there is a next char AND that next char is also not compatible
  176. if ((chr2 != -1) && !charCompatible(chr2, currcs)) {
  177. //need to switch code sets
  178. switch (currcs) {
  179. case CODESET.A:
  180. shifter = SET_CODEB;
  181. currcs = CODESET.B;
  182. break;
  183. case CODESET.B:
  184. shifter = SET_CODEA;
  185. currcs = CODESET.A;
  186. break;
  187. }
  188. }
  189. else {
  190. //no need to shift code sets, a temporary SHIFT will suffice
  191. shifter = SET_SHIFT;
  192. }
  193. }
  194. //ok some type of shift is nessecary
  195. if (shifter != -1) {
  196. result.push(shifter);
  197. result.push(codeValue(chr2));
  198. }
  199. else {
  200. if (currcs == CODESET.C) {
  201. //include next as well
  202. result.push(codeValue(chr1, chr2));
  203. }
  204. else {
  205. result.push(codeValue(chr1));
  206. }
  207. }
  208. barc.currcs = currcs;
  209. return result;
  210. }
  211. }
  212. //reduce the ascii code to fit into the Code128 char table
  213. function codeValue(chr1, chr2) {
  214. if (typeof chr2 == "undefined") {
  215. return chr1 >= 32 ? chr1 - 32 : chr1 + 64;
  216. }
  217. else {
  218. return parseInt(String.fromCharCode(chr1) + String.fromCharCode(chr2));
  219. }
  220. }
  221. function charCompatible(chr, codeset) {
  222. var csa = codeSetAllowedFor(chr);
  223. if (csa == CODESET.ANY) return true;
  224. //if we need to change from current
  225. if (csa == CODESET.AB) return true;
  226. if (csa == CODESET.A && codeset == CODESET.A) return true;
  227. if (csa == CODESET.B && codeset == CODESET.B) return true;
  228. return false;
  229. }
  230. function codeSetAllowedFor(chr) {
  231. if (chr >= 48 && chr <= 57) {
  232. //0-9
  233. return CODESET.ANY;
  234. }
  235. else if (chr >= 32 && chr <= 95) {
  236. //0-9 A-Z
  237. return CODESET.AB;
  238. }
  239. else {
  240. //if non printable
  241. return chr < 32 ? CODESET.A : CODESET.B;
  242. }
  243. }
  244. var Graphics = function(ctx, width, height) {
  245. this.width = width;
  246. this.height = height;
  247. this.quiet = Math.round(this.width / 40);
  248. this.border_size = 0;
  249. this.padding_width = 0;
  250. this.area = {
  251. width : width - this.padding_width * 2 - this.quiet * 2,
  252. height: height - this.border_size * 2,
  253. top : this.border_size - 4,
  254. left : this.padding_width + this.quiet
  255. };
  256. this.ctx = ctx;
  257. this.fg = "#000000";
  258. this.bg = "#ffffff";
  259. // fill background
  260. this.fillBgRect(0,0, width, height);
  261. // fill center to create border
  262. this.fillBgRect(0, this.border_size, width, height - this.border_size * 2);
  263. }
  264. //use native color
  265. Graphics.prototype._fillRect = function(x, y, width, height, color) {
  266. this.ctx.setFillStyle(color)
  267. this.ctx.fillRect(x, y, width, height)
  268. }
  269. Graphics.prototype.fillFgRect = function(x,y, width, height) {
  270. this._fillRect(x, y, width, height, this.fg);
  271. }
  272. Graphics.prototype.fillBgRect = function(x,y, width, height) {
  273. this._fillRect(x, y, width, height, this.bg);
  274. }
  275. var PATTERNS = [
  276. [2, 1, 2, 2, 2, 2, 0, 0], // 0
  277. [2, 2, 2, 1, 2, 2, 0, 0], // 1
  278. [2, 2, 2, 2, 2, 1, 0, 0], // 2
  279. [1, 2, 1, 2, 2, 3, 0, 0], // 3
  280. [1, 2, 1, 3, 2, 2, 0, 0], // 4
  281. [1, 3, 1, 2, 2, 2, 0, 0], // 5
  282. [1, 2, 2, 2, 1, 3, 0, 0], // 6
  283. [1, 2, 2, 3, 1, 2, 0, 0], // 7
  284. [1, 3, 2, 2, 1, 2, 0, 0], // 8
  285. [2, 2, 1, 2, 1, 3, 0, 0], // 9
  286. [2, 2, 1, 3, 1, 2, 0, 0], // 10
  287. [2, 3, 1, 2, 1, 2, 0, 0], // 11
  288. [1, 1, 2, 2, 3, 2, 0, 0], // 12
  289. [1, 2, 2, 1, 3, 2, 0, 0], // 13
  290. [1, 2, 2, 2, 3, 1, 0, 0], // 14
  291. [1, 1, 3, 2, 2, 2, 0, 0], // 15
  292. [1, 2, 3, 1, 2, 2, 0, 0], // 16
  293. [1, 2, 3, 2, 2, 1, 0, 0], // 17
  294. [2, 2, 3, 2, 1, 1, 0, 0], // 18
  295. [2, 2, 1, 1, 3, 2, 0, 0], // 19
  296. [2, 2, 1, 2, 3, 1, 0, 0], // 20
  297. [2, 1, 3, 2, 1, 2, 0, 0], // 21
  298. [2, 2, 3, 1, 1, 2, 0, 0], // 22
  299. [3, 1, 2, 1, 3, 1, 0, 0], // 23
  300. [3, 1, 1, 2, 2, 2, 0, 0], // 24
  301. [3, 2, 1, 1, 2, 2, 0, 0], // 25
  302. [3, 2, 1, 2, 2, 1, 0, 0], // 26
  303. [3, 1, 2, 2, 1, 2, 0, 0], // 27
  304. [3, 2, 2, 1, 1, 2, 0, 0], // 28
  305. [3, 2, 2, 2, 1, 1, 0, 0], // 29
  306. [2, 1, 2, 1, 2, 3, 0, 0], // 30
  307. [2, 1, 2, 3, 2, 1, 0, 0], // 31
  308. [2, 3, 2, 1, 2, 1, 0, 0], // 32
  309. [1, 1, 1, 3, 2, 3, 0, 0], // 33
  310. [1, 3, 1, 1, 2, 3, 0, 0], // 34
  311. [1, 3, 1, 3, 2, 1, 0, 0], // 35
  312. [1, 1, 2, 3, 1, 3, 0, 0], // 36
  313. [1, 3, 2, 1, 1, 3, 0, 0], // 37
  314. [1, 3, 2, 3, 1, 1, 0, 0], // 38
  315. [2, 1, 1, 3, 1, 3, 0, 0], // 39
  316. [2, 3, 1, 1, 1, 3, 0, 0], // 40
  317. [2, 3, 1, 3, 1, 1, 0, 0], // 41
  318. [1, 1, 2, 1, 3, 3, 0, 0], // 42
  319. [1, 1, 2, 3, 3, 1, 0, 0], // 43
  320. [1, 3, 2, 1, 3, 1, 0, 0], // 44
  321. [1, 1, 3, 1, 2, 3, 0, 0], // 45
  322. [1, 1, 3, 3, 2, 1, 0, 0], // 46
  323. [1, 3, 3, 1, 2, 1, 0, 0], // 47
  324. [3, 1, 3, 1, 2, 1, 0, 0], // 48
  325. [2, 1, 1, 3, 3, 1, 0, 0], // 49
  326. [2, 3, 1, 1, 3, 1, 0, 0], // 50
  327. [2, 1, 3, 1, 1, 3, 0, 0], // 51
  328. [2, 1, 3, 3, 1, 1, 0, 0], // 52
  329. [2, 1, 3, 1, 3, 1, 0, 0], // 53
  330. [3, 1, 1, 1, 2, 3, 0, 0], // 54
  331. [3, 1, 1, 3, 2, 1, 0, 0], // 55
  332. [3, 3, 1, 1, 2, 1, 0, 0], // 56
  333. [3, 1, 2, 1, 1, 3, 0, 0], // 57
  334. [3, 1, 2, 3, 1, 1, 0, 0], // 58
  335. [3, 3, 2, 1, 1, 1, 0, 0], // 59
  336. [3, 1, 4, 1, 1, 1, 0, 0], // 60
  337. [2, 2, 1, 4, 1, 1, 0, 0], // 61
  338. [4, 3, 1, 1, 1, 1, 0, 0], // 62
  339. [1, 1, 1, 2, 2, 4, 0, 0], // 63
  340. [1, 1, 1, 4, 2, 2, 0, 0], // 64
  341. [1, 2, 1, 1, 2, 4, 0, 0], // 65
  342. [1, 2, 1, 4, 2, 1, 0, 0], // 66
  343. [1, 4, 1, 1, 2, 2, 0, 0], // 67
  344. [1, 4, 1, 2, 2, 1, 0, 0], // 68
  345. [1, 1, 2, 2, 1, 4, 0, 0], // 69
  346. [1, 1, 2, 4, 1, 2, 0, 0], // 70
  347. [1, 2, 2, 1, 1, 4, 0, 0], // 71
  348. [1, 2, 2, 4, 1, 1, 0, 0], // 72
  349. [1, 4, 2, 1, 1, 2, 0, 0], // 73
  350. [1, 4, 2, 2, 1, 1, 0, 0], // 74
  351. [2, 4, 1, 2, 1, 1, 0, 0], // 75
  352. [2, 2, 1, 1, 1, 4, 0, 0], // 76
  353. [4, 1, 3, 1, 1, 1, 0, 0], // 77
  354. [2, 4, 1, 1, 1, 2, 0, 0], // 78
  355. [1, 3, 4, 1, 1, 1, 0, 0], // 79
  356. [1, 1, 1, 2, 4, 2, 0, 0], // 80
  357. [1, 2, 1, 1, 4, 2, 0, 0], // 81
  358. [1, 2, 1, 2, 4, 1, 0, 0], // 82
  359. [1, 1, 4, 2, 1, 2, 0, 0], // 83
  360. [1, 2, 4, 1, 1, 2, 0, 0], // 84
  361. [1, 2, 4, 2, 1, 1, 0, 0], // 85
  362. [4, 1, 1, 2, 1, 2, 0, 0], // 86
  363. [4, 2, 1, 1, 1, 2, 0, 0], // 87
  364. [4, 2, 1, 2, 1, 1, 0, 0], // 88
  365. [2, 1, 2, 1, 4, 1, 0, 0], // 89
  366. [2, 1, 4, 1, 2, 1, 0, 0], // 90
  367. [4, 1, 2, 1, 2, 1, 0, 0], // 91
  368. [1, 1, 1, 1, 4, 3, 0, 0], // 92
  369. [1, 1, 1, 3, 4, 1, 0, 0], // 93
  370. [1, 3, 1, 1, 4, 1, 0, 0], // 94
  371. [1, 1, 4, 1, 1, 3, 0, 0], // 95
  372. [1, 1, 4, 3, 1, 1, 0, 0], // 96
  373. [4, 1, 1, 1, 1, 3, 0, 0], // 97
  374. [4, 1, 1, 3, 1, 1, 0, 0], // 98
  375. [1, 1, 3, 1, 4, 1, 0, 0], // 99
  376. [1, 1, 4, 1, 3, 1, 0, 0], // 100
  377. [3, 1, 1, 1, 4, 1, 0, 0], // 101
  378. [4, 1, 1, 1, 3, 1, 0, 0], // 102
  379. [2, 1, 1, 4, 1, 2, 0, 0], // 103
  380. [2, 1, 1, 2, 1, 4, 0, 0], // 104
  381. [2, 1, 1, 2, 3, 2, 0, 0], // 105
  382. [2, 3, 3, 1, 1, 1, 2, 0] // 106
  383. ]
  384. }, function(modId) { var map = {}; return __REQUIRE__(map[modId], modId); })
  385. __DEFINE__(1618706661373, function(require, module, exports) {
  386. var QR = (function () {
  387. // alignment pattern
  388. var adelta = [
  389. 0, 11, 15, 19, 23, 27, 31, // force 1 pat
  390. 16, 18, 20, 22, 24, 26, 28, 20, 22, 24, 24, 26, 28, 28, 22, 24, 24,
  391. 26, 26, 28, 28, 24, 24, 26, 26, 26, 28, 28, 24, 26, 26, 26, 28, 28
  392. ];
  393. // version block
  394. var vpat = [
  395. 0xc94, 0x5bc, 0xa99, 0x4d3, 0xbf6, 0x762, 0x847, 0x60d,
  396. 0x928, 0xb78, 0x45d, 0xa17, 0x532, 0x9a6, 0x683, 0x8c9,
  397. 0x7ec, 0xec4, 0x1e1, 0xfab, 0x08e, 0xc1a, 0x33f, 0xd75,
  398. 0x250, 0x9d5, 0x6f0, 0x8ba, 0x79f, 0xb0b, 0x42e, 0xa64,
  399. 0x541, 0xc69
  400. ];
  401. // final format bits with mask: level << 3 | mask
  402. var fmtword = [
  403. 0x77c4, 0x72f3, 0x7daa, 0x789d, 0x662f, 0x6318, 0x6c41, 0x6976, //L
  404. 0x5412, 0x5125, 0x5e7c, 0x5b4b, 0x45f9, 0x40ce, 0x4f97, 0x4aa0, //M
  405. 0x355f, 0x3068, 0x3f31, 0x3a06, 0x24b4, 0x2183, 0x2eda, 0x2bed, //Q
  406. 0x1689, 0x13be, 0x1ce7, 0x19d0, 0x0762, 0x0255, 0x0d0c, 0x083b //H
  407. ];
  408. // 4 per version: number of blocks 1,2; data width; ecc width
  409. var eccblocks = [
  410. 1, 0, 19, 7, 1, 0, 16, 10, 1, 0, 13, 13, 1, 0, 9, 17,
  411. 1, 0, 34, 10, 1, 0, 28, 16, 1, 0, 22, 22, 1, 0, 16, 28,
  412. 1, 0, 55, 15, 1, 0, 44, 26, 2, 0, 17, 18, 2, 0, 13, 22,
  413. 1, 0, 80, 20, 2, 0, 32, 18, 2, 0, 24, 26, 4, 0, 9, 16,
  414. 1, 0, 108, 26, 2, 0, 43, 24, 2, 2, 15, 18, 2, 2, 11, 22,
  415. 2, 0, 68, 18, 4, 0, 27, 16, 4, 0, 19, 24, 4, 0, 15, 28,
  416. 2, 0, 78, 20, 4, 0, 31, 18, 2, 4, 14, 18, 4, 1, 13, 26,
  417. 2, 0, 97, 24, 2, 2, 38, 22, 4, 2, 18, 22, 4, 2, 14, 26,
  418. 2, 0, 116, 30, 3, 2, 36, 22, 4, 4, 16, 20, 4, 4, 12, 24,
  419. 2, 2, 68, 18, 4, 1, 43, 26, 6, 2, 19, 24, 6, 2, 15, 28,
  420. 4, 0, 81, 20, 1, 4, 50, 30, 4, 4, 22, 28, 3, 8, 12, 24,
  421. 2, 2, 92, 24, 6, 2, 36, 22, 4, 6, 20, 26, 7, 4, 14, 28,
  422. 4, 0, 107, 26, 8, 1, 37, 22, 8, 4, 20, 24, 12, 4, 11, 22,
  423. 3, 1, 115, 30, 4, 5, 40, 24, 11, 5, 16, 20, 11, 5, 12, 24,
  424. 5, 1, 87, 22, 5, 5, 41, 24, 5, 7, 24, 30, 11, 7, 12, 24,
  425. 5, 1, 98, 24, 7, 3, 45, 28, 15, 2, 19, 24, 3, 13, 15, 30,
  426. 1, 5, 107, 28, 10, 1, 46, 28, 1, 15, 22, 28, 2, 17, 14, 28,
  427. 5, 1, 120, 30, 9, 4, 43, 26, 17, 1, 22, 28, 2, 19, 14, 28,
  428. 3, 4, 113, 28, 3, 11, 44, 26, 17, 4, 21, 26, 9, 16, 13, 26,
  429. 3, 5, 107, 28, 3, 13, 41, 26, 15, 5, 24, 30, 15, 10, 15, 28,
  430. 4, 4, 116, 28, 17, 0, 42, 26, 17, 6, 22, 28, 19, 6, 16, 30,
  431. 2, 7, 111, 28, 17, 0, 46, 28, 7, 16, 24, 30, 34, 0, 13, 24,
  432. 4, 5, 121, 30, 4, 14, 47, 28, 11, 14, 24, 30, 16, 14, 15, 30,
  433. 6, 4, 117, 30, 6, 14, 45, 28, 11, 16, 24, 30, 30, 2, 16, 30,
  434. 8, 4, 106, 26, 8, 13, 47, 28, 7, 22, 24, 30, 22, 13, 15, 30,
  435. 10, 2, 114, 28, 19, 4, 46, 28, 28, 6, 22, 28, 33, 4, 16, 30,
  436. 8, 4, 122, 30, 22, 3, 45, 28, 8, 26, 23, 30, 12, 28, 15, 30,
  437. 3, 10, 117, 30, 3, 23, 45, 28, 4, 31, 24, 30, 11, 31, 15, 30,
  438. 7, 7, 116, 30, 21, 7, 45, 28, 1, 37, 23, 30, 19, 26, 15, 30,
  439. 5, 10, 115, 30, 19, 10, 47, 28, 15, 25, 24, 30, 23, 25, 15, 30,
  440. 13, 3, 115, 30, 2, 29, 46, 28, 42, 1, 24, 30, 23, 28, 15, 30,
  441. 17, 0, 115, 30, 10, 23, 46, 28, 10, 35, 24, 30, 19, 35, 15, 30,
  442. 17, 1, 115, 30, 14, 21, 46, 28, 29, 19, 24, 30, 11, 46, 15, 30,
  443. 13, 6, 115, 30, 14, 23, 46, 28, 44, 7, 24, 30, 59, 1, 16, 30,
  444. 12, 7, 121, 30, 12, 26, 47, 28, 39, 14, 24, 30, 22, 41, 15, 30,
  445. 6, 14, 121, 30, 6, 34, 47, 28, 46, 10, 24, 30, 2, 64, 15, 30,
  446. 17, 4, 122, 30, 29, 14, 46, 28, 49, 10, 24, 30, 24, 46, 15, 30,
  447. 4, 18, 122, 30, 13, 32, 46, 28, 48, 14, 24, 30, 42, 32, 15, 30,
  448. 20, 4, 117, 30, 40, 7, 47, 28, 43, 22, 24, 30, 10, 67, 15, 30,
  449. 19, 6, 118, 30, 18, 31, 47, 28, 34, 34, 24, 30, 20, 61, 15, 30
  450. ];
  451. // Galois field log table
  452. var glog = [
  453. 0xff, 0x00, 0x01, 0x19, 0x02, 0x32, 0x1a, 0xc6, 0x03, 0xdf, 0x33, 0xee, 0x1b, 0x68, 0xc7, 0x4b,
  454. 0x04, 0x64, 0xe0, 0x0e, 0x34, 0x8d, 0xef, 0x81, 0x1c, 0xc1, 0x69, 0xf8, 0xc8, 0x08, 0x4c, 0x71,
  455. 0x05, 0x8a, 0x65, 0x2f, 0xe1, 0x24, 0x0f, 0x21, 0x35, 0x93, 0x8e, 0xda, 0xf0, 0x12, 0x82, 0x45,
  456. 0x1d, 0xb5, 0xc2, 0x7d, 0x6a, 0x27, 0xf9, 0xb9, 0xc9, 0x9a, 0x09, 0x78, 0x4d, 0xe4, 0x72, 0xa6,
  457. 0x06, 0xbf, 0x8b, 0x62, 0x66, 0xdd, 0x30, 0xfd, 0xe2, 0x98, 0x25, 0xb3, 0x10, 0x91, 0x22, 0x88,
  458. 0x36, 0xd0, 0x94, 0xce, 0x8f, 0x96, 0xdb, 0xbd, 0xf1, 0xd2, 0x13, 0x5c, 0x83, 0x38, 0x46, 0x40,
  459. 0x1e, 0x42, 0xb6, 0xa3, 0xc3, 0x48, 0x7e, 0x6e, 0x6b, 0x3a, 0x28, 0x54, 0xfa, 0x85, 0xba, 0x3d,
  460. 0xca, 0x5e, 0x9b, 0x9f, 0x0a, 0x15, 0x79, 0x2b, 0x4e, 0xd4, 0xe5, 0xac, 0x73, 0xf3, 0xa7, 0x57,
  461. 0x07, 0x70, 0xc0, 0xf7, 0x8c, 0x80, 0x63, 0x0d, 0x67, 0x4a, 0xde, 0xed, 0x31, 0xc5, 0xfe, 0x18,
  462. 0xe3, 0xa5, 0x99, 0x77, 0x26, 0xb8, 0xb4, 0x7c, 0x11, 0x44, 0x92, 0xd9, 0x23, 0x20, 0x89, 0x2e,
  463. 0x37, 0x3f, 0xd1, 0x5b, 0x95, 0xbc, 0xcf, 0xcd, 0x90, 0x87, 0x97, 0xb2, 0xdc, 0xfc, 0xbe, 0x61,
  464. 0xf2, 0x56, 0xd3, 0xab, 0x14, 0x2a, 0x5d, 0x9e, 0x84, 0x3c, 0x39, 0x53, 0x47, 0x6d, 0x41, 0xa2,
  465. 0x1f, 0x2d, 0x43, 0xd8, 0xb7, 0x7b, 0xa4, 0x76, 0xc4, 0x17, 0x49, 0xec, 0x7f, 0x0c, 0x6f, 0xf6,
  466. 0x6c, 0xa1, 0x3b, 0x52, 0x29, 0x9d, 0x55, 0xaa, 0xfb, 0x60, 0x86, 0xb1, 0xbb, 0xcc, 0x3e, 0x5a,
  467. 0xcb, 0x59, 0x5f, 0xb0, 0x9c, 0xa9, 0xa0, 0x51, 0x0b, 0xf5, 0x16, 0xeb, 0x7a, 0x75, 0x2c, 0xd7,
  468. 0x4f, 0xae, 0xd5, 0xe9, 0xe6, 0xe7, 0xad, 0xe8, 0x74, 0xd6, 0xf4, 0xea, 0xa8, 0x50, 0x58, 0xaf
  469. ];
  470. // Galios field exponent table
  471. var gexp = [
  472. 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1d, 0x3a, 0x74, 0xe8, 0xcd, 0x87, 0x13, 0x26,
  473. 0x4c, 0x98, 0x2d, 0x5a, 0xb4, 0x75, 0xea, 0xc9, 0x8f, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0,
  474. 0x9d, 0x27, 0x4e, 0x9c, 0x25, 0x4a, 0x94, 0x35, 0x6a, 0xd4, 0xb5, 0x77, 0xee, 0xc1, 0x9f, 0x23,
  475. 0x46, 0x8c, 0x05, 0x0a, 0x14, 0x28, 0x50, 0xa0, 0x5d, 0xba, 0x69, 0xd2, 0xb9, 0x6f, 0xde, 0xa1,
  476. 0x5f, 0xbe, 0x61, 0xc2, 0x99, 0x2f, 0x5e, 0xbc, 0x65, 0xca, 0x89, 0x0f, 0x1e, 0x3c, 0x78, 0xf0,
  477. 0xfd, 0xe7, 0xd3, 0xbb, 0x6b, 0xd6, 0xb1, 0x7f, 0xfe, 0xe1, 0xdf, 0xa3, 0x5b, 0xb6, 0x71, 0xe2,
  478. 0xd9, 0xaf, 0x43, 0x86, 0x11, 0x22, 0x44, 0x88, 0x0d, 0x1a, 0x34, 0x68, 0xd0, 0xbd, 0x67, 0xce,
  479. 0x81, 0x1f, 0x3e, 0x7c, 0xf8, 0xed, 0xc7, 0x93, 0x3b, 0x76, 0xec, 0xc5, 0x97, 0x33, 0x66, 0xcc,
  480. 0x85, 0x17, 0x2e, 0x5c, 0xb8, 0x6d, 0xda, 0xa9, 0x4f, 0x9e, 0x21, 0x42, 0x84, 0x15, 0x2a, 0x54,
  481. 0xa8, 0x4d, 0x9a, 0x29, 0x52, 0xa4, 0x55, 0xaa, 0x49, 0x92, 0x39, 0x72, 0xe4, 0xd5, 0xb7, 0x73,
  482. 0xe6, 0xd1, 0xbf, 0x63, 0xc6, 0x91, 0x3f, 0x7e, 0xfc, 0xe5, 0xd7, 0xb3, 0x7b, 0xf6, 0xf1, 0xff,
  483. 0xe3, 0xdb, 0xab, 0x4b, 0x96, 0x31, 0x62, 0xc4, 0x95, 0x37, 0x6e, 0xdc, 0xa5, 0x57, 0xae, 0x41,
  484. 0x82, 0x19, 0x32, 0x64, 0xc8, 0x8d, 0x07, 0x0e, 0x1c, 0x38, 0x70, 0xe0, 0xdd, 0xa7, 0x53, 0xa6,
  485. 0x51, 0xa2, 0x59, 0xb2, 0x79, 0xf2, 0xf9, 0xef, 0xc3, 0x9b, 0x2b, 0x56, 0xac, 0x45, 0x8a, 0x09,
  486. 0x12, 0x24, 0x48, 0x90, 0x3d, 0x7a, 0xf4, 0xf5, 0xf7, 0xf3, 0xfb, 0xeb, 0xcb, 0x8b, 0x0b, 0x16,
  487. 0x2c, 0x58, 0xb0, 0x7d, 0xfa, 0xe9, 0xcf, 0x83, 0x1b, 0x36, 0x6c, 0xd8, 0xad, 0x47, 0x8e, 0x00
  488. ];
  489. // Working buffers:
  490. // data input and ecc append, image working buffer, fixed part of image, run lengths for badness
  491. var strinbuf=[], eccbuf=[], qrframe=[], framask=[], rlens=[];
  492. // Control values - width is based on version, last 4 are from table.
  493. var version, width, neccblk1, neccblk2, datablkw, eccblkwid;
  494. var ecclevel = 2;
  495. // set bit to indicate cell in qrframe is immutable. symmetric around diagonal
  496. function setmask(x, y)
  497. {
  498. var bt;
  499. if (x > y) {
  500. bt = x;
  501. x = y;
  502. y = bt;
  503. }
  504. // y*y = 1+3+5...
  505. bt = y;
  506. bt *= y;
  507. bt += y;
  508. bt >>= 1;
  509. bt += x;
  510. framask[bt] = 1;
  511. }
  512. // enter alignment pattern - black to qrframe, white to mask (later black frame merged to mask)
  513. function putalign(x, y)
  514. {
  515. var j;
  516. qrframe[x + width * y] = 1;
  517. for (j = -2; j < 2; j++) {
  518. qrframe[(x + j) + width * (y - 2)] = 1;
  519. qrframe[(x - 2) + width * (y + j + 1)] = 1;
  520. qrframe[(x + 2) + width * (y + j)] = 1;
  521. qrframe[(x + j + 1) + width * (y + 2)] = 1;
  522. }
  523. for (j = 0; j < 2; j++) {
  524. setmask(x - 1, y + j);
  525. setmask(x + 1, y - j);
  526. setmask(x - j, y - 1);
  527. setmask(x + j, y + 1);
  528. }
  529. }
  530. //========================================================================
  531. // Reed Solomon error correction
  532. // exponentiation mod N
  533. function modnn(x)
  534. {
  535. while (x >= 255) {
  536. x -= 255;
  537. x = (x >> 8) + (x & 255);
  538. }
  539. return x;
  540. }
  541. var genpoly = [];
  542. // Calculate and append ECC data to data block. Block is in strinbuf, indexes to buffers given.
  543. function appendrs(data, dlen, ecbuf, eclen)
  544. {
  545. var i, j, fb;
  546. for (i = 0; i < eclen; i++)
  547. strinbuf[ecbuf + i] = 0;
  548. for (i = 0; i < dlen; i++) {
  549. fb = glog[strinbuf[data + i] ^ strinbuf[ecbuf]];
  550. if (fb != 255) /* fb term is non-zero */
  551. for (j = 1; j < eclen; j++)
  552. strinbuf[ecbuf + j - 1] = strinbuf[ecbuf + j] ^ gexp[modnn(fb + genpoly[eclen - j])];
  553. else
  554. for( j = ecbuf ; j < ecbuf + eclen; j++ )
  555. strinbuf[j] = strinbuf[j + 1];
  556. strinbuf[ ecbuf + eclen - 1] = fb == 255 ? 0 : gexp[modnn(fb + genpoly[0])];
  557. }
  558. }
  559. //========================================================================
  560. // Frame data insert following the path rules
  561. // check mask - since symmetrical use half.
  562. function ismasked(x, y)
  563. {
  564. var bt;
  565. if (x > y) {
  566. bt = x;
  567. x = y;
  568. y = bt;
  569. }
  570. bt = y;
  571. bt += y * y;
  572. bt >>= 1;
  573. bt += x;
  574. return framask[bt];
  575. }
  576. //========================================================================
  577. // Apply the selected mask out of the 8.
  578. function applymask(m)
  579. {
  580. var x, y, r3x, r3y;
  581. switch (m) {
  582. case 0:
  583. for (y = 0; y < width; y++)
  584. for (x = 0; x < width; x++)
  585. if (!((x + y) & 1) && !ismasked(x, y))
  586. qrframe[x + y * width] ^= 1;
  587. break;
  588. case 1:
  589. for (y = 0; y < width; y++)
  590. for (x = 0; x < width; x++)
  591. if (!(y & 1) && !ismasked(x, y))
  592. qrframe[x + y * width] ^= 1;
  593. break;
  594. case 2:
  595. for (y = 0; y < width; y++)
  596. for (r3x = 0, x = 0; x < width; x++, r3x++) {
  597. if (r3x == 3)
  598. r3x = 0;
  599. if (!r3x && !ismasked(x, y))
  600. qrframe[x + y * width] ^= 1;
  601. }
  602. break;
  603. case 3:
  604. for (r3y = 0, y = 0; y < width; y++, r3y++) {
  605. if (r3y == 3)
  606. r3y = 0;
  607. for (r3x = r3y, x = 0; x < width; x++, r3x++) {
  608. if (r3x == 3)
  609. r3x = 0;
  610. if (!r3x && !ismasked(x, y))
  611. qrframe[x + y * width] ^= 1;
  612. }
  613. }
  614. break;
  615. case 4:
  616. for (y = 0; y < width; y++)
  617. for (r3x = 0, r3y = ((y >> 1) & 1), x = 0; x < width; x++, r3x++) {
  618. if (r3x == 3) {
  619. r3x = 0;
  620. r3y = !r3y;
  621. }
  622. if (!r3y && !ismasked(x, y))
  623. qrframe[x + y * width] ^= 1;
  624. }
  625. break;
  626. case 5:
  627. for (r3y = 0, y = 0; y < width; y++, r3y++) {
  628. if (r3y == 3)
  629. r3y = 0;
  630. for (r3x = 0, x = 0; x < width; x++, r3x++) {
  631. if (r3x == 3)
  632. r3x = 0;
  633. if (!((x & y & 1) + !(!r3x | !r3y)) && !ismasked(x, y))
  634. qrframe[x + y * width] ^= 1;
  635. }
  636. }
  637. break;
  638. case 6:
  639. for (r3y = 0, y = 0; y < width; y++, r3y++) {
  640. if (r3y == 3)
  641. r3y = 0;
  642. for (r3x = 0, x = 0; x < width; x++, r3x++) {
  643. if (r3x == 3)
  644. r3x = 0;
  645. if (!(((x & y & 1) + (r3x && (r3x == r3y))) & 1) && !ismasked(x, y))
  646. qrframe[x + y * width] ^= 1;
  647. }
  648. }
  649. break;
  650. case 7:
  651. for (r3y = 0, y = 0; y < width; y++, r3y++) {
  652. if (r3y == 3)
  653. r3y = 0;
  654. for (r3x = 0, x = 0; x < width; x++, r3x++) {
  655. if (r3x == 3)
  656. r3x = 0;
  657. if (!(((r3x && (r3x == r3y)) + ((x + y) & 1)) & 1) && !ismasked(x, y))
  658. qrframe[x + y * width] ^= 1;
  659. }
  660. }
  661. break;
  662. }
  663. return;
  664. }
  665. // Badness coefficients.
  666. var N1 = 3, N2 = 3, N3 = 40, N4 = 10;
  667. // Using the table of the length of each run, calculate the amount of bad image
  668. // - long runs or those that look like finders; called twice, once each for X and Y
  669. function badruns(length)
  670. {
  671. var i;
  672. var runsbad = 0;
  673. for (i = 0; i <= length; i++)
  674. if (rlens[i] >= 5)
  675. runsbad += N1 + rlens[i] - 5;
  676. // BwBBBwB as in finder
  677. for (i = 3; i < length - 1; i += 2)
  678. if (rlens[i - 2] == rlens[i + 2]
  679. && rlens[i + 2] == rlens[i - 1]
  680. && rlens[i - 1] == rlens[i + 1]
  681. && rlens[i - 1] * 3 == rlens[i]
  682. // white around the black pattern? Not part of spec
  683. && (rlens[i - 3] == 0 // beginning
  684. || i + 3 > length // end
  685. || rlens[i - 3] * 3 >= rlens[i] * 4 || rlens[i + 3] * 3 >= rlens[i] * 4)
  686. )
  687. runsbad += N3;
  688. return runsbad;
  689. }
  690. // Calculate how bad the masked image is - blocks, imbalance, runs, or finders.
  691. function badcheck()
  692. {
  693. var x, y, h, b, b1;
  694. var thisbad = 0;
  695. var bw = 0;
  696. // blocks of same color.
  697. for (y = 0; y < width - 1; y++)
  698. for (x = 0; x < width - 1; x++)
  699. if ((qrframe[x + width * y] && qrframe[(x + 1) + width * y]
  700. && qrframe[x + width * (y + 1)] && qrframe[(x + 1) + width * (y + 1)]) // all black
  701. || !(qrframe[x + width * y] || qrframe[(x + 1) + width * y]
  702. || qrframe[x + width * (y + 1)] || qrframe[(x + 1) + width * (y + 1)])) // all white
  703. thisbad += N2;
  704. // X runs
  705. for (y = 0; y < width; y++) {
  706. rlens[0] = 0;
  707. for (h = b = x = 0; x < width; x++) {
  708. if ((b1 = qrframe[x + width * y]) == b)
  709. rlens[h]++;
  710. else
  711. rlens[++h] = 1;
  712. b = b1;
  713. bw += b ? 1 : -1;
  714. }
  715. thisbad += badruns(h);
  716. }
  717. // black/white imbalance
  718. if (bw < 0)
  719. bw = -bw;
  720. var big = bw;
  721. var count = 0;
  722. big += big << 2;
  723. big <<= 1;
  724. while (big > width * width)
  725. big -= width * width, count++;
  726. thisbad += count * N4;
  727. // Y runs
  728. for (x = 0; x < width; x++) {
  729. rlens[0] = 0;
  730. for (h = b = y = 0; y < width; y++) {
  731. if ((b1 = qrframe[x + width * y]) == b)
  732. rlens[h]++;
  733. else
  734. rlens[++h] = 1;
  735. b = b1;
  736. }
  737. thisbad += badruns(h);
  738. }
  739. return thisbad;
  740. }
  741. function genframe(instring)
  742. {
  743. var x, y, k, t, v, i, j, m;
  744. // find the smallest version that fits the string
  745. t = instring.length;
  746. version = 0;
  747. do {
  748. version++;
  749. k = (ecclevel - 1) * 4 + (version - 1) * 16;
  750. neccblk1 = eccblocks[k++];
  751. neccblk2 = eccblocks[k++];
  752. datablkw = eccblocks[k++];
  753. eccblkwid = eccblocks[k];
  754. k = datablkw * (neccblk1 + neccblk2) + neccblk2 - 3 + (version <= 9);
  755. if (t <= k)
  756. break;
  757. } while (version < 40);
  758. // FIXME - insure that it fits insted of being truncated
  759. width = 17 + 4 * version;
  760. // allocate, clear and setup data structures
  761. v = datablkw + (datablkw + eccblkwid) * (neccblk1 + neccblk2) + neccblk2;
  762. for( t = 0; t < v; t++ )
  763. eccbuf[t] = 0;
  764. strinbuf = instring.slice(0);
  765. for( t = 0; t < width * width; t++ )
  766. qrframe[t] = 0;
  767. for( t = 0 ; t < (width * (width + 1) + 1) / 2; t++)
  768. framask[t] = 0;
  769. // insert finders - black to frame, white to mask
  770. for (t = 0; t < 3; t++) {
  771. k = 0;
  772. y = 0;
  773. if (t == 1)
  774. k = (width - 7);
  775. if (t == 2)
  776. y = (width - 7);
  777. qrframe[(y + 3) + width * (k + 3)] = 1;
  778. for (x = 0; x < 6; x++) {
  779. qrframe[(y + x) + width * k] = 1;
  780. qrframe[y + width * (k + x + 1)] = 1;
  781. qrframe[(y + 6) + width * (k + x)] = 1;
  782. qrframe[(y + x + 1) + width * (k + 6)] = 1;
  783. }
  784. for (x = 1; x < 5; x++) {
  785. setmask(y + x, k + 1);
  786. setmask(y + 1, k + x + 1);
  787. setmask(y + 5, k + x);
  788. setmask(y + x + 1, k + 5);
  789. }
  790. for (x = 2; x < 4; x++) {
  791. qrframe[(y + x) + width * (k + 2)] = 1;
  792. qrframe[(y + 2) + width * (k + x + 1)] = 1;
  793. qrframe[(y + 4) + width * (k + x)] = 1;
  794. qrframe[(y + x + 1) + width * (k + 4)] = 1;
  795. }
  796. }
  797. // alignment blocks
  798. if (version > 1) {
  799. t = adelta[version];
  800. y = width - 7;
  801. for (;;) {
  802. x = width - 7;
  803. while (x > t - 3) {
  804. putalign(x, y);
  805. if (x < t)
  806. break;
  807. x -= t;
  808. }
  809. if (y <= t + 9)
  810. break;
  811. y -= t;
  812. putalign(6, y);
  813. putalign(y, 6);
  814. }
  815. }
  816. // single black
  817. qrframe[8 + width * (width - 8)] = 1;
  818. // timing gap - mask only
  819. for (y = 0; y < 7; y++) {
  820. setmask(7, y);
  821. setmask(width - 8, y);
  822. setmask(7, y + width - 7);
  823. }
  824. for (x = 0; x < 8; x++) {
  825. setmask(x, 7);
  826. setmask(x + width - 8, 7);
  827. setmask(x, width - 8);
  828. }
  829. // reserve mask-format area
  830. for (x = 0; x < 9; x++)
  831. setmask(x, 8);
  832. for (x = 0; x < 8; x++) {
  833. setmask(x + width - 8, 8);
  834. setmask(8, x);
  835. }
  836. for (y = 0; y < 7; y++)
  837. setmask(8, y + width - 7);
  838. // timing row/col
  839. for (x = 0; x < width - 14; x++)
  840. if (x & 1) {
  841. setmask(8 + x, 6);
  842. setmask(6, 8 + x);
  843. }
  844. else {
  845. qrframe[(8 + x) + width * 6] = 1;
  846. qrframe[6 + width * (8 + x)] = 1;
  847. }
  848. // version block
  849. if (version > 6) {
  850. t = vpat[version - 7];
  851. k = 17;
  852. for (x = 0; x < 6; x++)
  853. for (y = 0; y < 3; y++, k--)
  854. if (1 & (k > 11 ? version >> (k - 12) : t >> k)) {
  855. qrframe[(5 - x) + width * (2 - y + width - 11)] = 1;
  856. qrframe[(2 - y + width - 11) + width * (5 - x)] = 1;
  857. }
  858. else {
  859. setmask(5 - x, 2 - y + width - 11);
  860. setmask(2 - y + width - 11, 5 - x);
  861. }
  862. }
  863. // sync mask bits - only set above for white spaces, so add in black bits
  864. for (y = 0; y < width; y++)
  865. for (x = 0; x <= y; x++)
  866. if (qrframe[x + width * y])
  867. setmask(x, y);
  868. // convert string to bitstream
  869. // 8 bit data to QR-coded 8 bit data (numeric or alphanum, or kanji not supported)
  870. v = strinbuf.length;
  871. // string to array
  872. for( i = 0 ; i < v; i++ )
  873. eccbuf[i] = strinbuf.charCodeAt(i);
  874. strinbuf = eccbuf.slice(0);
  875. // calculate max string length
  876. x = datablkw * (neccblk1 + neccblk2) + neccblk2;
  877. if (v >= x - 2) {
  878. v = x - 2;
  879. if (version > 9)
  880. v--;
  881. }
  882. // shift and repack to insert length prefix
  883. i = v;
  884. if (version > 9) {
  885. strinbuf[i + 2] = 0;
  886. strinbuf[i + 3] = 0;
  887. while (i--) {
  888. t = strinbuf[i];
  889. strinbuf[i + 3] |= 255 & (t << 4);
  890. strinbuf[i + 2] = t >> 4;
  891. }
  892. strinbuf[2] |= 255 & (v << 4);
  893. strinbuf[1] = v >> 4;
  894. strinbuf[0] = 0x40 | (v >> 12);
  895. }
  896. else {
  897. strinbuf[i + 1] = 0;
  898. strinbuf[i + 2] = 0;
  899. while (i--) {
  900. t = strinbuf[i];
  901. strinbuf[i + 2] |= 255 & (t << 4);
  902. strinbuf[i + 1] = t >> 4;
  903. }
  904. strinbuf[1] |= 255 & (v << 4);
  905. strinbuf[0] = 0x40 | (v >> 4);
  906. }
  907. // fill to end with pad pattern
  908. i = v + 3 - (version < 10);
  909. while (i < x) {
  910. strinbuf[i++] = 0xec;
  911. // buffer has room if (i == x) break;
  912. strinbuf[i++] = 0x11;
  913. }
  914. // calculate and append ECC
  915. // calculate generator polynomial
  916. genpoly[0] = 1;
  917. for (i = 0; i < eccblkwid; i++) {
  918. genpoly[i + 1] = 1;
  919. for (j = i; j > 0; j--)
  920. genpoly[j] = genpoly[j]
  921. ? genpoly[j - 1] ^ gexp[modnn(glog[genpoly[j]] + i)] : genpoly[j - 1];
  922. genpoly[0] = gexp[modnn(glog[genpoly[0]] + i)];
  923. }
  924. for (i = 0; i <= eccblkwid; i++)
  925. genpoly[i] = glog[genpoly[i]]; // use logs for genpoly[] to save calc step
  926. // append ecc to data buffer
  927. k = x;
  928. y = 0;
  929. for (i = 0; i < neccblk1; i++) {
  930. appendrs(y, datablkw, k, eccblkwid);
  931. y += datablkw;
  932. k += eccblkwid;
  933. }
  934. for (i = 0; i < neccblk2; i++) {
  935. appendrs(y, datablkw + 1, k, eccblkwid);
  936. y += datablkw + 1;
  937. k += eccblkwid;
  938. }
  939. // interleave blocks
  940. y = 0;
  941. for (i = 0; i < datablkw; i++) {
  942. for (j = 0; j < neccblk1; j++)
  943. eccbuf[y++] = strinbuf[i + j * datablkw];
  944. for (j = 0; j < neccblk2; j++)
  945. eccbuf[y++] = strinbuf[(neccblk1 * datablkw) + i + (j * (datablkw + 1))];
  946. }
  947. for (j = 0; j < neccblk2; j++)
  948. eccbuf[y++] = strinbuf[(neccblk1 * datablkw) + i + (j * (datablkw + 1))];
  949. for (i = 0; i < eccblkwid; i++)
  950. for (j = 0; j < neccblk1 + neccblk2; j++)
  951. eccbuf[y++] = strinbuf[x + i + j * eccblkwid];
  952. strinbuf = eccbuf;
  953. // pack bits into frame avoiding masked area.
  954. x = y = width - 1;
  955. k = v = 1; // up, minus
  956. /* inteleaved data and ecc codes */
  957. m = (datablkw + eccblkwid) * (neccblk1 + neccblk2) + neccblk2;
  958. for (i = 0; i < m; i++) {
  959. t = strinbuf[i];
  960. for (j = 0; j < 8; j++, t <<= 1) {
  961. if (0x80 & t)
  962. qrframe[x + width * y] = 1;
  963. do { // find next fill position
  964. if (v)
  965. x--;
  966. else {
  967. x++;
  968. if (k) {
  969. if (y != 0)
  970. y--;
  971. else {
  972. x -= 2;
  973. k = !k;
  974. if (x == 6) {
  975. x--;
  976. y = 9;
  977. }
  978. }
  979. }
  980. else {
  981. if (y != width - 1)
  982. y++;
  983. else {
  984. x -= 2;
  985. k = !k;
  986. if (x == 6) {
  987. x--;
  988. y -= 8;
  989. }
  990. }
  991. }
  992. }
  993. v = !v;
  994. } while (ismasked(x, y));
  995. }
  996. }
  997. // save pre-mask copy of frame
  998. strinbuf = qrframe.slice(0);
  999. t = 0; // best
  1000. y = 30000; // demerit
  1001. // for instead of while since in original arduino code
  1002. // if an early mask was "good enough" it wouldn't try for a better one
  1003. // since they get more complex and take longer.
  1004. for (k = 0; k < 8; k++) {
  1005. applymask(k); // returns black-white imbalance
  1006. x = badcheck();
  1007. if (x < y) { // current mask better than previous best?
  1008. y = x;
  1009. t = k;
  1010. }
  1011. if (t == 7)
  1012. break; // don't increment i to a void redoing mask
  1013. qrframe = strinbuf.slice(0); // reset for next pass
  1014. }
  1015. if (t != k) // redo best mask - none good enough, last wasn't t
  1016. applymask(t);
  1017. // add in final mask/ecclevel bytes
  1018. y = fmtword[t + ((ecclevel - 1) << 3)];
  1019. // low byte
  1020. for (k = 0; k < 8; k++, y >>= 1)
  1021. if (y & 1) {
  1022. qrframe[(width - 1 - k) + width * 8] = 1;
  1023. if (k < 6)
  1024. qrframe[8 + width * k] = 1;
  1025. else
  1026. qrframe[8 + width * (k + 1)] = 1;
  1027. }
  1028. // high byte
  1029. for (k = 0; k < 7; k++, y >>= 1)
  1030. if (y & 1) {
  1031. qrframe[8 + width * (width - 7 + k)] = 1;
  1032. if (k)
  1033. qrframe[(6 - k) + width * 8] = 1;
  1034. else
  1035. qrframe[7 + width * 8] = 1;
  1036. }
  1037. // return image
  1038. return qrframe;
  1039. }
  1040. var _canvas = null,
  1041. _size = null;
  1042. var api = {
  1043. get ecclevel () {
  1044. return ecclevel;
  1045. },
  1046. set ecclevel (val) {
  1047. ecclevel = val;
  1048. },
  1049. get size () {
  1050. return _size;
  1051. },
  1052. set size (val) {
  1053. _size = val
  1054. },
  1055. get canvas () {
  1056. return _canvas;
  1057. },
  1058. set canvas (el) {
  1059. _canvas = el;
  1060. },
  1061. getFrame: function (string) {
  1062. return genframe(string);
  1063. },
  1064. draw: function (string, canvas, size, ecc) {
  1065. ecclevel = ecc || ecclevel;
  1066. canvas = canvas || _canvas;
  1067. if (!canvas) {
  1068. console.warn('No canvas provided to draw QR code in!')
  1069. return;
  1070. }
  1071. size = size || _size || Math.min(canvas.width, canvas.height);
  1072. var frame = genframe(string),
  1073. ctx = canvas.ctx,
  1074. px = Math.round(size / (width + 8));
  1075. var roundedSize = px * (width + 8),
  1076. offset = Math.floor((size - roundedSize) / 2);
  1077. size = roundedSize;
  1078. ctx.clearRect(0, 0, canvas.width, canvas.height);
  1079. ctx.setFillStyle('#000000');
  1080. for (var i = 0; i < width; i++) {
  1081. for (var j = 0; j < width; j++) {
  1082. if (frame[j * width + i]) {
  1083. ctx.fillRect(px * (4 + i) + offset, px * (4 + j) + offset, px, px);
  1084. }
  1085. }
  1086. }
  1087. ctx.draw();
  1088. }
  1089. }
  1090. module.exports = {
  1091. api: api
  1092. }
  1093. })()
  1094. }, function(modId) { var map = {}; return __REQUIRE__(map[modId], modId); })
  1095. return __REQUIRE__(1618706661370);
  1096. })()
  1097. //# sourceMappingURL=index.js.map