/**
* @fileoverview
* - using the 'qrcode for javascript library'
* - fixed dataset of 'qrcode for javascript library' for support full-spec.
* - this library has no dependencies.
*
* @author davidshimjs
* @see http://www.d-project.com/
* @see http://jeromeetienne.github.com/jquery-qrcode/
*/
var qrcode;
(function () {
//---------------------------------------------------------------------
// qrcode for javascript
//
// copyright (c) 2009 kazuhiko arase
//
// url: http://www.d-project.com/
//
// licensed under the mit license:
// http://www.opensource.org/licenses/mit-license.php
//
// the word "qr code" is registered trademark of
// denso wave incorporated
// http://www.denso-wave.com/qrcode/faqpatent-e.html
//
//---------------------------------------------------------------------
function qr8bitbyte(data) {
this.mode = qrmode.mode_8bit_byte;
this.data = data;
this.parseddata = [];
// added to support utf-8 characters
for (var i = 0, l = this.data.length; i < l; i++) {
var bytearray = [];
var code = this.data.charcodeat(i);
if (code > 0x10000) {
bytearray[0] = 0xf0 | ((code & 0x1c0000) >>> 18);
bytearray[1] = 0x80 | ((code & 0x3f000) >>> 12);
bytearray[2] = 0x80 | ((code & 0xfc0) >>> 6);
bytearray[3] = 0x80 | (code & 0x3f);
} else if (code > 0x800) {
bytearray[0] = 0xe0 | ((code & 0xf000) >>> 12);
bytearray[1] = 0x80 | ((code & 0xfc0) >>> 6);
bytearray[2] = 0x80 | (code & 0x3f);
} else if (code > 0x80) {
bytearray[0] = 0xc0 | ((code & 0x7c0) >>> 6);
bytearray[1] = 0x80 | (code & 0x3f);
} else {
bytearray[0] = code;
}
this.parseddata.push(bytearray);
}
this.parseddata = array.prototype.concat.apply([], this.parseddata);
if (this.parseddata.length != this.data.length) {
this.parseddata.unshift(191);
this.parseddata.unshift(187);
this.parseddata.unshift(239);
}
}
qr8bitbyte.prototype = {
getlength: function (buffer) {
return this.parseddata.length;
},
write: function (buffer) {
for (var i = 0, l = this.parseddata.length; i < l; i++) {
buffer.put(this.parseddata[i], 8);
}
}
};
function qrcodemodel(typenumber, errorcorrectlevel) {
this.typenumber = typenumber;
this.errorcorrectlevel = errorcorrectlevel;
this.modules = null;
this.modulecount = 0;
this.datacache = null;
this.datalist = [];
}
qrcodemodel.prototype={adddata:function(data){var newdata=new qr8bitbyte(data);this.datalist.push(newdata);this.datacache=null;},isdark:function(row,col){if(row<0||this.modulecount<=row||col<0||this.modulecount<=col){throw new error(row+","+col);}
return this.modules[row][col];},getmodulecount:function(){return this.modulecount;},make:function(){this.makeimpl(false,this.getbestmaskpattern());},makeimpl:function(test,maskpattern){this.modulecount=this.typenumber*4+17;this.modules=new array(this.modulecount);for(var row=0;row=7){this.setuptypenumber(test);}
if(this.datacache==null){this.datacache=qrcodemodel.createdata(this.typenumber,this.errorcorrectlevel,this.datalist);}
this.mapdata(this.datacache,maskpattern);},setuppositionprobepattern:function(row,col){for(var r=-1;r<=7;r++){if(row+r<=-1||this.modulecount<=row+r)continue;for(var c=-1;c<=7;c++){if(col+c<=-1||this.modulecount<=col+c)continue;if((0<=r&&r<=6&&(c==0||c==6))||(0<=c&&c<=6&&(r==0||r==6))||(2<=r&&r<=4&&2<=c&&c<=4)){this.modules[row+r][col+c]=true;}else{this.modules[row+r][col+c]=false;}}}},getbestmaskpattern:function(){var minlostpoint=0;var pattern=0;for(var i=0;i<8;i++){this.makeimpl(true,i);var lostpoint=qrutil.getlostpoint(this);if(i==0||minlostpoint>lostpoint){minlostpoint=lostpoint;pattern=i;}}
return pattern;},createmovieclip:function(target_mc,instance_name,depth){var qr_mc=target_mc.createemptymovieclip(instance_name,depth);var cs=1;this.make();for(var row=0;row>i)&1)==1);this.modules[math.floor(i/3)][i%3+this.modulecount-8-3]=mod;}
for(var i=0;i<18;i++){var mod=(!test&&((bits>>i)&1)==1);this.modules[i%3+this.modulecount-8-3][math.floor(i/3)]=mod;}},setuptypeinfo:function(test,maskpattern){var data=(this.errorcorrectlevel<<3)|maskpattern;var bits=qrutil.getbchtypeinfo(data);for(var i=0;i<15;i++){var mod=(!test&&((bits>>i)&1)==1);if(i<6){this.modules[i][8]=mod;}else if(i<8){this.modules[i+1][8]=mod;}else{this.modules[this.modulecount-15+i][8]=mod;}}
for(var i=0;i<15;i++){var mod=(!test&&((bits>>i)&1)==1);if(i<8){this.modules[8][this.modulecount-i-1]=mod;}else if(i<9){this.modules[8][15-i-1+1]=mod;}else{this.modules[8][15-i-1]=mod;}}
this.modules[this.modulecount-8][8]=(!test);},mapdata:function(data,maskpattern){var inc=-1;var row=this.modulecount-1;var bitindex=7;var byteindex=0;for(var col=this.modulecount-1;col>0;col-=2){if(col==6)col--;while(true){for(var c=0;c<2;c++){if(this.modules[row][col-c]==null){var dark=false;if(byteindex>>bitindex)&1)==1);}
var mask=qrutil.getmask(maskpattern,row,col-c);if(mask){dark=!dark;}
this.modules[row][col-c]=dark;bitindex--;if(bitindex==-1){byteindex++;bitindex=7;}}}
row+=inc;if(row<0||this.modulecount<=row){row-=inc;inc=-inc;break;}}}}};qrcodemodel.pad0=0xec;qrcodemodel.pad1=0x11;qrcodemodel.createdata=function(typenumber,errorcorrectlevel,datalist){var rsblocks=qrrsblock.getrsblocks(typenumber,errorcorrectlevel);var buffer=new qrbitbuffer();for(var i=0;itotaldatacount*8){throw new error("code length overflow. ("
+buffer.getlengthinbits()
+">"
+totaldatacount*8
+")");}
if(buffer.getlengthinbits()+4<=totaldatacount*8){buffer.put(0,4);}
while(buffer.getlengthinbits()%8!=0){buffer.putbit(false);}
while(true){if(buffer.getlengthinbits()>=totaldatacount*8){break;}
buffer.put(qrcodemodel.pad0,8);if(buffer.getlengthinbits()>=totaldatacount*8){break;}
buffer.put(qrcodemodel.pad1,8);}
return qrcodemodel.createbytes(buffer,rsblocks);};qrcodemodel.createbytes=function(buffer,rsblocks){var offset=0;var maxdccount=0;var maxeccount=0;var dcdata=new array(rsblocks.length);var ecdata=new array(rsblocks.length);for(var r=0;r=0)?modpoly.get(modindex):0;}}
var totalcodecount=0;for(var i=0;i=0){d^=(qrutil.g15<<(qrutil.getbchdigit(d)-qrutil.getbchdigit(qrutil.g15)));}
return((data<<10)|d)^qrutil.g15_mask;},getbchtypenumber:function(data){var d=data<<12;while(qrutil.getbchdigit(d)-qrutil.getbchdigit(qrutil.g18)>=0){d^=(qrutil.g18<<(qrutil.getbchdigit(d)-qrutil.getbchdigit(qrutil.g18)));}
return(data<<12)|d;},getbchdigit:function(data){var digit=0;while(data!=0){digit++;data>>>=1;}
return digit;},getpatternposition:function(typenumber){return qrutil.pattern_position_table[typenumber-1];},getmask:function(maskpattern,i,j){switch(maskpattern){case qrmaskpattern.pattern000:return(i+j)%2==0;case qrmaskpattern.pattern001:return i%2==0;case qrmaskpattern.pattern010:return j%3==0;case qrmaskpattern.pattern011:return(i+j)%3==0;case qrmaskpattern.pattern100:return(math.floor(i/2)+math.floor(j/3))%2==0;case qrmaskpattern.pattern101:return(i*j)%2+(i*j)%3==0;case qrmaskpattern.pattern110:return((i*j)%2+(i*j)%3)%2==0;case qrmaskpattern.pattern111:return((i*j)%3+(i+j)%2)%2==0;default:throw new error("bad maskpattern:"+maskpattern);}},geterrorcorrectpolynomial:function(errorcorrectlength){var a=new qrpolynomial([1],0);for(var i=0;i5){lostpoint+=(3+samecount-5);}}}
for(var row=0;row=256){n-=255;}
return qrmath.exp_table[n];},exp_table:new array(256),log_table:new array(256)};for(var i=0;i<8;i++){qrmath.exp_table[i]=1<>>(7-index%8))&1)==1;},put:function(num,length){for(var i=0;i>>(length-i-1))&1)==1);}},getlengthinbits:function(){return this.length;},putbit:function(bit){var bufindex=math.floor(this.length/8);if(this.buffer.length<=bufindex){this.buffer.push(0);}
if(bit){this.buffer[bufindex]|=(0x80>>>(this.length%8));}
this.length++;}};var qrcodelimitlength=[[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 _issupportcanvas() {
return typeof canvasrenderingcontext2d != "undefined";
}
// android 2.x doesn't support data-uri spec
function _getandroid() {
var android = false;
var sagent = navigator.useragent;
if (/android/i.test(sagent)) { // android
android = true;
var amat = sagent.tostring().match(/android ([0-9]\.[0-9])/i);
if (amat && amat[1]) {
android = parsefloat(amat[1]);
}
}
return android;
}
var svgdrawer = (function() {
var drawing = function (el, htoption) {
this._el = el;
this._htoption = htoption;
};
drawing.prototype.draw = function (oqrcode) {
var _htoption = this._htoption;
var _el = this._el;
var ncount = oqrcode.getmodulecount();
var nwidth = math.floor(_htoption.width / ncount);
var nheight = math.floor(_htoption.height / ncount);
this.clear();
function makesvg(tag, attrs) {
var el = document.createelementns('http://www.w3.org/2000/svg', tag);
for (var k in attrs)
if (attrs.hasownproperty(k)) el.setattribute(k, attrs[k]);
return el;
}
var svg = makesvg("svg" , {'viewbox': '0 0 ' + string(ncount) + " " + string(ncount), 'width': '100%', 'height': '100%', 'fill': _htoption.colorlight});
svg.setattributens("http://www.w3.org/2000/xmlns/", "xmlns:xlink", "http://www.w3.org/1999/xlink");
_el.appendchild(svg);
svg.appendchild(makesvg("rect", {"fill": _htoption.colorlight, "width": "100%", "height": "100%"}));
svg.appendchild(makesvg("rect", {"fill": _htoption.colordark, "width": "1", "height": "1", "id": "template"}));
for (var row = 0; row < ncount; row++) {
for (var col = 0; col < ncount; col++) {
if (oqrcode.isdark(row, col)) {
var child = makesvg("use", {"x": string(col), "y": string(row)});
child.setattributens("http://www.w3.org/1999/xlink", "href", "#template")
svg.appendchild(child);
}
}
}
};
drawing.prototype.clear = function () {
while (this._el.haschildnodes())
this._el.removechild(this._el.lastchild);
};
return drawing;
})();
var usesvg = document.documentelement.tagname.tolowercase() === "svg";
// drawing in dom by using table tag
var drawing = usesvg ? svgdrawer : !_issupportcanvas() ? (function () {
var drawing = function (el, htoption) {
this._el = el;
this._htoption = htoption;
};
/**
* draw the qrcode
*
* @param {qrcode} oqrcode
*/
drawing.prototype.draw = function (oqrcode) {
var _htoption = this._htoption;
var _el = this._el;
var ncount = oqrcode.getmodulecount();
var nwidth = math.floor(_htoption.width / ncount);
var nheight = math.floor(_htoption.height / ncount);
var ahtml = [''];
for (var row = 0; row < ncount; row++) {
ahtml.push('');
for (var col = 0; col < ncount; col++) {
ahtml.push(' | ');
}
ahtml.push('
');
}
ahtml.push('
');
_el.innerhtml = ahtml.join('');
// fix the margin values as real size.
var eltable = _el.childnodes[0];
var nleftmargintable = (_htoption.width - eltable.offsetwidth) / 2;
var ntopmargintable = (_htoption.height - eltable.offsetheight) / 2;
if (nleftmargintable > 0 && ntopmargintable > 0) {
eltable.style.margin = ntopmargintable + "px " + nleftmargintable + "px";
}
};
/**
* clear the qrcode
*/
drawing.prototype.clear = function () {
this._el.innerhtml = '';
};
return drawing;
})() : (function () { // drawing in canvas
function _onmakeimage() {
this._elimage.src = this._elcanvas.todataurl("image/png");
this._elimage.style.display = "block";
this._elcanvas.style.display = "none";
}
// android 2.1 bug workaround
// http://code.google.com/p/android/issues/detail?id=5141
if (this._android && this._android <= 2.1) {
var factor = 1 / window.devicepixelratio;
var drawimage = canvasrenderingcontext2d.prototype.drawimage;
canvasrenderingcontext2d.prototype.drawimage = function (image, sx, sy, sw, sh, dx, dy, dw, dh) {
if (("nodename" in image) && /img/i.test(image.nodename)) {
for (var i = arguments.length - 1; i >= 1; i--) {
arguments[i] = arguments[i] * factor;
}
} else if (typeof dw == "undefined") {
arguments[1] *= factor;
arguments[2] *= factor;
arguments[3] *= factor;
arguments[4] *= factor;
}
drawimage.apply(this, arguments);
};
}
/**
* check whether the user's browser supports data uri or not
*
* @private
* @param {function} fsuccess occurs if it supports data uri
* @param {function} ffail occurs if it doesn't support data uri
*/
function _safesetdatauri(fsuccess, ffail) {
var self = this;
self._ffail = ffail;
self._fsuccess = fsuccess;
// check it just once
if (self._bsupportdatauri === null) {
var el = document.createelement("img");
var fonerror = function() {
self._bsupportdatauri = false;
if (self._ffail) {
self._ffail.call(self);
}
};
var fonsuccess = function() {
self._bsupportdatauri = true;
if (self._fsuccess) {
self._fsuccess.call(self);
}
};
el.onabort = fonerror;
el.onerror = fonerror;
el.onload = fonsuccess;
el.src = "data:image/gif;base64,ivborw0kggoaaaansuheugaaaauaaaafcayaaacnbyblaaaaheleqvqi12p4//8/w38giaxdibke0dhxgljnbaao9txl0y4ohwaaaabjru5erkjggg=="; // the image contains 1px data.
return;
} else if (self._bsupportdatauri === true && self._fsuccess) {
self._fsuccess.call(self);
} else if (self._bsupportdatauri === false && self._ffail) {
self._ffail.call(self);
}
};
/**
* drawing qrcode by using canvas
*
* @constructor
* @param {htmlelement} el
* @param {object} htoption qrcode options
*/
var drawing = function (el, htoption) {
this._bispainted = false;
this._android = _getandroid();
this._htoption = htoption;
this._elcanvas = document.createelement("canvas");
this._elcanvas.width = htoption.width;
this._elcanvas.height = htoption.height;
el.appendchild(this._elcanvas);
this._el = el;
this._ocontext = this._elcanvas.getcontext("2d");
this._bispainted = false;
this._elimage = document.createelement("img");
this._elimage.alt = "scan me!";
this._elimage.style.display = "none";
this._el.appendchild(this._elimage);
this._bsupportdatauri = null;
};
/**
* draw the qrcode
*
* @param {qrcode} oqrcode
*/
drawing.prototype.draw = function (oqrcode) {
var _elimage = this._elimage;
var _ocontext = this._ocontext;
var _htoption = this._htoption;
var ncount = oqrcode.getmodulecount();
var nwidth = _htoption.width / ncount;
var nheight = _htoption.height / ncount;
var nroundedwidth = math.round(nwidth);
var nroundedheight = math.round(nheight);
_elimage.style.display = "none";
this.clear();
for (var row = 0; row < ncount; row++) {
for (var col = 0; col < ncount; col++) {
var bisdark = oqrcode.isdark(row, col);
var nleft = col * nwidth;
var ntop = row * nheight;
_ocontext.strokestyle = bisdark ? _htoption.colordark : _htoption.colorlight;
_ocontext.linewidth = 1;
_ocontext.fillstyle = bisdark ? _htoption.colordark : _htoption.colorlight;
_ocontext.fillrect(nleft, ntop, nwidth, nheight);
// 안티 앨리어싱 방지 처리
_ocontext.strokerect(
math.floor(nleft) + 0.5,
math.floor(ntop) + 0.5,
nroundedwidth,
nroundedheight
);
_ocontext.strokerect(
math.ceil(nleft) - 0.5,
math.ceil(ntop) - 0.5,
nroundedwidth,
nroundedheight
);
}
}
this._bispainted = true;
};
/**
* make the image from canvas if the browser supports data uri.
*/
drawing.prototype.makeimage = function () {
if (this._bispainted) {
_safesetdatauri.call(this, _onmakeimage);
}
};
/**
* return whether the qrcode is painted or not
*
* @return {boolean}
*/
drawing.prototype.ispainted = function () {
return this._bispainted;
};
/**
* clear the qrcode
*/
drawing.prototype.clear = function () {
this._ocontext.clearrect(0, 0, this._elcanvas.width, this._elcanvas.height);
this._bispainted = false;
};
/**
* @private
* @param {number} nnumber
*/
drawing.prototype.round = function (nnumber) {
if (!nnumber) {
return nnumber;
}
return math.floor(nnumber * 1000) / 1000;
};
return drawing;
})();
/**
* get the type by string length
*
* @private
* @param {string} stext
* @param {number} ncorrectlevel
* @return {number} type
*/
function _gettypenumber(stext, ncorrectlevel) {
var ntype = 1;
var length = _getutf8length(stext);
for (var i = 0, len = qrcodelimitlength.length; i <= len; i++) {
var nlimit = 0;
switch (ncorrectlevel) {
case qrerrorcorrectlevel.l :
nlimit = qrcodelimitlength[i][0];
break;
case qrerrorcorrectlevel.m :
nlimit = qrcodelimitlength[i][1];
break;
case qrerrorcorrectlevel.q :
nlimit = qrcodelimitlength[i][2];
break;
case qrerrorcorrectlevel.h :
nlimit = qrcodelimitlength[i][3];
break;
}
if (length <= nlimit) {
break;
} else {
ntype++;
}
}
if (ntype > qrcodelimitlength.length) {
throw new error("too long data");
}
return ntype;
}
function _getutf8length(stext) {
var replacedtext = encodeuri(stext).tostring().replace(/\%[0-9a-fa-f]{2}/g, 'a');
return replacedtext.length + (replacedtext.length != stext ? 3 : 0);
}
/**
* @class qrcode
* @constructor
* @example
* new qrcode(document.getelementbyid("test"), "http://jindo.dev.naver.com/collie");
*
* @example
* var oqrcode = new qrcode("test", {
* text : "http://naver.com",
* width : 128,
* height : 128
* });
*
* oqrcode.clear(); // clear the qrcode.
* oqrcode.makecode("http://map.naver.com"); // re-create the qrcode.
*
* @param {htmlelement|string} el target element or 'id' attribute of element.
* @param {object|string} voption
* @param {string} voption.text qrcode link data
* @param {number} [voption.width=256]
* @param {number} [voption.height=256]
* @param {string} [voption.colordark="#000000"]
* @param {string} [voption.colorlight="#ffffff"]
* @param {qrcode.correctlevel} [voption.correctlevel=qrcode.correctlevel.h] [l|m|q|h]
*/
qrcode = function (el, voption) {
this._htoption = {
width : 256,
height : 256,
typenumber : 4,
colordark : "#000000",
colorlight : "#ffffff",
correctlevel : qrerrorcorrectlevel.h
};
if (typeof voption === 'string') {
voption = {
text : voption
};
}
// overwrites options
if (voption) {
for (var i in voption) {
this._htoption[i] = voption[i];
}
}
if (typeof el == "string") {
el = document.getelementbyid(el);
}
if (this._htoption.usesvg) {
drawing = svgdrawer;
}
this._android = _getandroid();
this._el = el;
this._oqrcode = null;
this._odrawing = new drawing(this._el, this._htoption);
if (this._htoption.text) {
this.makecode(this._htoption.text);
}
};
/**
* make the qrcode
*
* @param {string} stext link data
*/
qrcode.prototype.makecode = function (stext) {
this._oqrcode = new qrcodemodel(_gettypenumber(stext, this._htoption.correctlevel), this._htoption.correctlevel);
this._oqrcode.adddata(stext);
this._oqrcode.make();
this._el.title = stext;
this._odrawing.draw(this._oqrcode);
this.makeimage();
};
/**
* make the image from canvas element
* - it occurs automatically
* - android below 3 doesn't support data-uri spec.
*
* @private
*/
qrcode.prototype.makeimage = function () {
if (typeof this._odrawing.makeimage == "function" && (!this._android || this._android >= 3)) {
this._odrawing.makeimage();
}
};
/**
* clear the qrcode
*/
qrcode.prototype.clear = function () {
this._odrawing.clear();
};
/**
* @name qrcode.correctlevel
*/
qrcode.correctlevel = qrerrorcorrectlevel;
})();
if (typeof module != "undefined") {
module.exports = qrcode;
}