/** * Kendo UI v2016.1.112 (http://www.telerik.com/kendo-ui) * Copyright 2016 Telerik AD. All rights reserved. * * Kendo UI commercial licenses may be obtained at * http://www.telerik.com/purchase/license-agreement/kendo-ui-complete * If you do not own a commercial license, this file shall be governed by the trial license terms. */ (function (f, define) { define('util/main', ['kendo.core'], f); }(function () { (function () { var math = Math, kendo = window.kendo, deepExtend = kendo.deepExtend; var DEG_TO_RAD = math.PI / 180, MAX_NUM = Number.MAX_VALUE, MIN_NUM = -Number.MAX_VALUE, UNDEFINED = 'undefined'; function defined(value) { return typeof value !== UNDEFINED; } function round(value, precision) { var power = pow(precision); return math.round(value * power) / power; } function pow(p) { if (p) { return math.pow(10, p); } else { return 1; } } function limitValue(value, min, max) { return math.max(math.min(value, max), min); } function rad(degrees) { return degrees * DEG_TO_RAD; } function deg(radians) { return radians / DEG_TO_RAD; } function isNumber(val) { return typeof val === 'number' && !isNaN(val); } function valueOrDefault(value, defaultValue) { return defined(value) ? value : defaultValue; } function sqr(value) { return value * value; } function objectKey(object) { var parts = []; for (var key in object) { parts.push(key + object[key]); } return parts.sort().join(''); } function hashKey(str) { var hash = 2166136261; for (var i = 0; i < str.length; ++i) { hash += (hash << 1) + (hash << 4) + (hash << 7) + (hash << 8) + (hash << 24); hash ^= str.charCodeAt(i); } return hash >>> 0; } function hashObject(object) { return hashKey(objectKey(object)); } var now = Date.now; if (!now) { now = function () { return new Date().getTime(); }; } function arrayLimits(arr) { var length = arr.length, i, min = MAX_NUM, max = MIN_NUM; for (i = 0; i < length; i++) { max = math.max(max, arr[i]); min = math.min(min, arr[i]); } return { min: min, max: max }; } function arrayMin(arr) { return arrayLimits(arr).min; } function arrayMax(arr) { return arrayLimits(arr).max; } function sparseArrayMin(arr) { return sparseArrayLimits(arr).min; } function sparseArrayMax(arr) { return sparseArrayLimits(arr).max; } function sparseArrayLimits(arr) { var min = MAX_NUM, max = MIN_NUM; for (var i = 0, length = arr.length; i < length; i++) { var n = arr[i]; if (n !== null && isFinite(n)) { min = math.min(min, n); max = math.max(max, n); } } return { min: min === MAX_NUM ? undefined : min, max: max === MIN_NUM ? undefined : max }; } function last(array) { if (array) { return array[array.length - 1]; } } function append(first, second) { first.push.apply(first, second); return first; } function renderTemplate(text) { return kendo.template(text, { useWithBlock: false, paramName: 'd' }); } function renderAttr(name, value) { return defined(value) && value !== null ? ' ' + name + '=\'' + value + '\' ' : ''; } function renderAllAttr(attrs) { var output = ''; for (var i = 0; i < attrs.length; i++) { output += renderAttr(attrs[i][0], attrs[i][1]); } return output; } function renderStyle(attrs) { var output = ''; for (var i = 0; i < attrs.length; i++) { var value = attrs[i][1]; if (defined(value)) { output += attrs[i][0] + ':' + value + ';'; } } if (output !== '') { return output; } } function renderSize(size) { if (typeof size !== 'string') { size += 'px'; } return size; } function renderPos(pos) { var result = []; if (pos) { var parts = kendo.toHyphens(pos).split('-'); for (var i = 0; i < parts.length; i++) { result.push('k-pos-' + parts[i]); } } return result.join(' '); } function isTransparent(color) { return color === '' || color === null || color === 'none' || color === 'transparent' || !defined(color); } function arabicToRoman(n) { var literals = { 1: 'i', 10: 'x', 100: 'c', 2: 'ii', 20: 'xx', 200: 'cc', 3: 'iii', 30: 'xxx', 300: 'ccc', 4: 'iv', 40: 'xl', 400: 'cd', 5: 'v', 50: 'l', 500: 'd', 6: 'vi', 60: 'lx', 600: 'dc', 7: 'vii', 70: 'lxx', 700: 'dcc', 8: 'viii', 80: 'lxxx', 800: 'dccc', 9: 'ix', 90: 'xc', 900: 'cm', 1000: 'm' }; var values = [ 1000, 900, 800, 700, 600, 500, 400, 300, 200, 100, 90, 80, 70, 60, 50, 40, 30, 20, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 ]; var roman = ''; while (n > 0) { if (n < values[0]) { values.shift(); } else { roman += literals[values[0]]; n -= values[0]; } } return roman; } function romanToArabic(r) { r = r.toLowerCase(); var digits = { i: 1, v: 5, x: 10, l: 50, c: 100, d: 500, m: 1000 }; var value = 0, prev = 0; for (var i = 0; i < r.length; ++i) { var v = digits[r.charAt(i)]; if (!v) { return null; } value += v; if (v > prev) { value -= 2 * prev; } prev = v; } return value; } function memoize(f) { var cache = Object.create(null); return function () { var id = ''; for (var i = arguments.length; --i >= 0;) { id += ':' + arguments[i]; } if (id in cache) { return cache[id]; } return f.apply(this, arguments); }; } function ucs2decode(string) { var output = [], counter = 0, length = string.length, value, extra; while (counter < length) { value = string.charCodeAt(counter++); if (value >= 55296 && value <= 56319 && counter < length) { extra = string.charCodeAt(counter++); if ((extra & 64512) == 56320) { output.push(((value & 1023) << 10) + (extra & 1023) + 65536); } else { output.push(value); counter--; } } else { output.push(value); } } return output; } function ucs2encode(array) { return array.map(function (value) { var output = ''; if (value > 65535) { value -= 65536; output += String.fromCharCode(value >>> 10 & 1023 | 55296); value = 56320 | value & 1023; } output += String.fromCharCode(value); return output; }).join(''); } deepExtend(kendo, { util: { MAX_NUM: MAX_NUM, MIN_NUM: MIN_NUM, append: append, arrayLimits: arrayLimits, arrayMin: arrayMin, arrayMax: arrayMax, defined: defined, deg: deg, hashKey: hashKey, hashObject: hashObject, isNumber: isNumber, isTransparent: isTransparent, last: last, limitValue: limitValue, now: now, objectKey: objectKey, round: round, rad: rad, renderAttr: renderAttr, renderAllAttr: renderAllAttr, renderPos: renderPos, renderSize: renderSize, renderStyle: renderStyle, renderTemplate: renderTemplate, sparseArrayLimits: sparseArrayLimits, sparseArrayMin: sparseArrayMin, sparseArrayMax: sparseArrayMax, sqr: sqr, valueOrDefault: valueOrDefault, romanToArabic: romanToArabic, arabicToRoman: arabicToRoman, memoize: memoize, ucs2encode: ucs2encode, ucs2decode: ucs2decode } }); kendo.drawing.util = kendo.util; kendo.dataviz.util = kendo.util; }()); return window.kendo; }, typeof define == 'function' && define.amd ? define : function (a1, a2, a3) { (a3 || a2)(); })); (function (f, define) { define('util/text-metrics', [ 'kendo.core', 'util/main' ], f); }(function () { (function ($) { var doc = document, kendo = window.kendo, Class = kendo.Class, util = kendo.util, defined = util.defined; var LRUCache = Class.extend({ init: function (size) { this._size = size; this._length = 0; this._map = {}; }, put: function (key, value) { var lru = this, map = lru._map, entry = { key: key, value: value }; map[key] = entry; if (!lru._head) { lru._head = lru._tail = entry; } else { lru._tail.newer = entry; entry.older = lru._tail; lru._tail = entry; } if (lru._length >= lru._size) { map[lru._head.key] = null; lru._head = lru._head.newer; lru._head.older = null; } else { lru._length++; } }, get: function (key) { var lru = this, entry = lru._map[key]; if (entry) { if (entry === lru._head && entry !== lru._tail) { lru._head = entry.newer; lru._head.older = null; } if (entry !== lru._tail) { if (entry.older) { entry.older.newer = entry.newer; entry.newer.older = entry.older; } entry.older = lru._tail; entry.newer = null; lru._tail.newer = entry; lru._tail = entry; } return entry.value; } } }); var defaultMeasureBox = $('
')[0]; var TextMetrics = Class.extend({ init: function (options) { this._cache = new LRUCache(1000); this._initOptions(options); }, options: { baselineMarkerSize: 1 }, measure: function (text, style, box) { var styleKey = util.objectKey(style), cacheKey = util.hashKey(text + styleKey), cachedResult = this._cache.get(cacheKey); if (cachedResult) { return cachedResult; } var size = { width: 0, height: 0, baseline: 0 }; var measureBox = box ? box : defaultMeasureBox; var baselineMarker = this._baselineMarker().cloneNode(false); for (var key in style) { var value = style[key]; if (defined(value)) { measureBox.style[key] = value; } } $(measureBox).text(text); measureBox.appendChild(baselineMarker); doc.body.appendChild(measureBox); if ((text + '').length) { size.width = measureBox.offsetWidth - this.options.baselineMarkerSize; size.height = measureBox.offsetHeight; size.baseline = baselineMarker.offsetTop + this.options.baselineMarkerSize; } if (size.width > 0 && size.height > 0) { this._cache.put(cacheKey, size); } measureBox.parentNode.removeChild(measureBox); return size; }, _baselineMarker: function () { return $('')[0]; } }); TextMetrics.current = new TextMetrics(); function measureText(text, style, measureBox) { return TextMetrics.current.measure(text, style, measureBox); } kendo.util.TextMetrics = TextMetrics; kendo.util.LRUCache = LRUCache; kendo.util.measureText = measureText; }(window.kendo.jQuery)); }, typeof define == 'function' && define.amd ? define : function (a1, a2, a3) { (a3 || a2)(); })); (function (f, define) { define('util/base64', ['util/main'], f); }(function () { (function () { var kendo = window.kendo, deepExtend = kendo.deepExtend, fromCharCode = String.fromCharCode; var KEY_STR = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='; function encodeBase64(input) { var output = ''; var chr1, chr2, chr3, enc1, enc2, enc3, enc4; var i = 0; input = encodeUTF8(input); while (i < input.length) { chr1 = input.charCodeAt(i++); chr2 = input.charCodeAt(i++); chr3 = input.charCodeAt(i++); enc1 = chr1 >> 2; enc2 = (chr1 & 3) << 4 | chr2 >> 4; enc3 = (chr2 & 15) << 2 | chr3 >> 6; enc4 = chr3 & 63; if (isNaN(chr2)) { enc3 = enc4 = 64; } else if (isNaN(chr3)) { enc4 = 64; } output = output + KEY_STR.charAt(enc1) + KEY_STR.charAt(enc2) + KEY_STR.charAt(enc3) + KEY_STR.charAt(enc4); } return output; } function encodeUTF8(input) { var output = ''; for (var i = 0; i < input.length; i++) { var c = input.charCodeAt(i); if (c < 128) { output += fromCharCode(c); } else if (c < 2048) { output += fromCharCode(192 | c >>> 6); output += fromCharCode(128 | c & 63); } else if (c < 65536) { output += fromCharCode(224 | c >>> 12); output += fromCharCode(128 | c >>> 6 & 63); output += fromCharCode(128 | c & 63); } } return output; } deepExtend(kendo.util, { encodeBase64: encodeBase64, encodeUTF8: encodeUTF8 }); }()); return window.kendo; }, typeof define == 'function' && define.amd ? define : function (a1, a2, a3) { (a3 || a2)(); })); (function (f, define) { define('mixins/observers', ['kendo.core'], f); }(function () { (function ($) { var math = Math, kendo = window.kendo, deepExtend = kendo.deepExtend, inArray = $.inArray; var ObserversMixin = { observers: function () { this._observers = this._observers || []; return this._observers; }, addObserver: function (element) { if (!this._observers) { this._observers = [element]; } else { this._observers.push(element); } return this; }, removeObserver: function (element) { var observers = this.observers(); var index = inArray(element, observers); if (index != -1) { observers.splice(index, 1); } return this; }, trigger: function (methodName, event) { var observers = this._observers; var observer; var idx; if (observers && !this._suspended) { for (idx = 0; idx < observers.length; idx++) { observer = observers[idx]; if (observer[methodName]) { observer[methodName](event); } } } return this; }, optionsChange: function (e) { this.trigger('optionsChange', e); }, geometryChange: function (e) { this.trigger('geometryChange', e); }, suspend: function () { this._suspended = (this._suspended || 0) + 1; return this; }, resume: function () { this._suspended = math.max((this._suspended || 0) - 1, 0); return this; }, _observerField: function (field, value) { if (this[field]) { this[field].removeObserver(this); } this[field] = value; value.addObserver(this); } }; deepExtend(kendo, { mixins: { ObserversMixin: ObserversMixin } }); }(window.kendo.jQuery)); return window.kendo; }, typeof define == 'function' && define.amd ? define : function (a1, a2, a3) { (a3 || a2)(); })); (function (f, define) { define('kendo.dataviz.qrcode', [ 'kendo.dataviz.core', 'kendo.drawing' ], f); }(function () { var __meta__ = { id: 'dataviz.qrcode', name: 'QRCode', category: 'dataviz', description: 'QRCode widget.', depends: [ 'dataviz.core', 'drawing' ] }; (function ($, undefined) { var kendo = window.kendo, extend = $.extend, draw = kendo.drawing, dataviz = kendo.dataviz, Widget = kendo.ui.Widget, Box2D = dataviz.Box2D, terminator = '0000', NUMERIC = 'numeric', ALPHA_NUMERIC = 'alphanumeric', BYTE = 'byte', powersOfTwo = { '1': 0 }, powersOfTwoResult = { '0': 1 }, generatorPolynomials = [ [ 1, 0 ], [ 1, 25, 0 ] ], irregularAlignmentPatternsStartDistance = { 15: 20, 16: 20, 18: 24, 19: 24, 22: 20, 24: 22, 26: 24, 28: 20, 30: 20, 31: 24, 32: 28, 33: 24, 36: 18, 37: 22, 39: 20, 40: 24 }, versionsCodewordsInformation = [ { L: { groups: [[ 1, 19 ]], totalDataCodewords: 19, errorCodewordsPerBlock: 7 }, M: { groups: [[ 1, 16 ]], totalDataCodewords: 16, errorCodewordsPerBlock: 10 }, Q: { groups: [[ 1, 13 ]], totalDataCodewords: 13, errorCodewordsPerBlock: 13 }, H: { groups: [[ 1, 9 ]], totalDataCodewords: 9, errorCodewordsPerBlock: 17 } }, { L: { groups: [[ 1, 34 ]], totalDataCodewords: 34, errorCodewordsPerBlock: 10 }, M: { groups: [[ 1, 28 ]], totalDataCodewords: 28, errorCodewordsPerBlock: 16 }, Q: { groups: [[ 1, 22 ]], totalDataCodewords: 22, errorCodewordsPerBlock: 22 }, H: { groups: [[ 1, 16 ]], totalDataCodewords: 16, errorCodewordsPerBlock: 28 } }, { L: { groups: [[ 1, 55 ]], totalDataCodewords: 55, errorCodewordsPerBlock: 15 }, M: { groups: [[ 1, 44 ]], totalDataCodewords: 44, errorCodewordsPerBlock: 26 }, Q: { groups: [[ 2, 17 ]], totalDataCodewords: 34, errorCodewordsPerBlock: 18 }, H: { groups: [[ 2, 13 ]], totalDataCodewords: 26, errorCodewordsPerBlock: 22 } }, { L: { groups: [[ 1, 80 ]], totalDataCodewords: 80, errorCodewordsPerBlock: 20 }, M: { groups: [[ 2, 32 ]], totalDataCodewords: 64, errorCodewordsPerBlock: 18 }, Q: { groups: [[ 2, 24 ]], totalDataCodewords: 48, errorCodewordsPerBlock: 26 }, H: { groups: [[ 4, 9 ]], totalDataCodewords: 36, errorCodewordsPerBlock: 16 } }, { L: { groups: [[ 1, 108 ]], totalDataCodewords: 108, errorCodewordsPerBlock: 26 }, M: { groups: [[ 2, 43 ]], totalDataCodewords: 86, errorCodewordsPerBlock: 24 }, Q: { groups: [ [ 2, 15 ], [ 2, 16 ] ], totalDataCodewords: 62, errorCodewordsPerBlock: 18 }, H: { groups: [ [ 2, 11 ], [ 2, 12 ] ], totalDataCodewords: 46, errorCodewordsPerBlock: 22 } }, { L: { groups: [[ 2, 68 ]], totalDataCodewords: 136, errorCodewordsPerBlock: 18 }, M: { groups: [[ 4, 27 ]], totalDataCodewords: 108, errorCodewordsPerBlock: 16 }, Q: { groups: [[ 4, 19 ]], totalDataCodewords: 76, errorCodewordsPerBlock: 24 }, H: { groups: [[ 4, 15 ]], totalDataCodewords: 60, errorCodewordsPerBlock: 28 } }, { L: { groups: [[ 2, 78 ]], totalDataCodewords: 156, errorCodewordsPerBlock: 20 }, M: { groups: [[ 4, 31 ]], totalDataCodewords: 124, errorCodewordsPerBlock: 18 }, Q: { groups: [ [ 2, 14 ], [ 4, 15 ] ], totalDataCodewords: 88, errorCodewordsPerBlock: 18 }, H: { groups: [ [ 4, 13 ], [ 1, 14 ] ], totalDataCodewords: 66, errorCodewordsPerBlock: 26 } }, { L: { groups: [[ 2, 97 ]], totalDataCodewords: 194, errorCodewordsPerBlock: 24 }, M: { groups: [ [ 2, 38 ], [ 2, 39 ] ], totalDataCodewords: 154, errorCodewordsPerBlock: 22 }, Q: { groups: [ [ 4, 18 ], [ 2, 19 ] ], totalDataCodewords: 110, errorCodewordsPerBlock: 22 }, H: { groups: [ [ 4, 14 ], [ 2, 15 ] ], totalDataCodewords: 86, errorCodewordsPerBlock: 26 } }, { L: { groups: [[ 2, 116 ]], totalDataCodewords: 232, errorCodewordsPerBlock: 30 }, M: { groups: [ [ 3, 36 ], [ 2, 37 ] ], totalDataCodewords: 182, errorCodewordsPerBlock: 22 }, Q: { groups: [ [ 4, 16 ], [ 4, 17 ] ], totalDataCodewords: 132, errorCodewordsPerBlock: 20 }, H: { groups: [ [ 4, 12 ], [ 4, 13 ] ], totalDataCodewords: 100, errorCodewordsPerBlock: 24 } }, { L: { groups: [ [ 2, 68 ], [ 2, 69 ] ], totalDataCodewords: 274, errorCodewordsPerBlock: 18 }, M: { groups: [ [ 4, 43 ], [ 1, 44 ] ], totalDataCodewords: 216, errorCodewordsPerBlock: 26 }, Q: { groups: [ [ 6, 19 ], [ 2, 20 ] ], totalDataCodewords: 154, errorCodewordsPerBlock: 24 }, H: { groups: [ [ 6, 15 ], [ 2, 16 ] ], totalDataCodewords: 122, errorCodewordsPerBlock: 28 } }, { L: { groups: [[ 4, 81 ]], totalDataCodewords: 324, errorCodewordsPerBlock: 20 }, M: { groups: [ [ 1, 50 ], [ 4, 51 ] ], totalDataCodewords: 254, errorCodewordsPerBlock: 30 }, Q: { groups: [ [ 4, 22 ], [ 4, 23 ] ], totalDataCodewords: 180, errorCodewordsPerBlock: 28 }, H: { groups: [ [ 3, 12 ], [ 8, 13 ] ], totalDataCodewords: 140, errorCodewordsPerBlock: 24 } }, { L: { groups: [ [ 2, 92 ], [ 2, 93 ] ], totalDataCodewords: 370, errorCodewordsPerBlock: 24 }, M: { groups: [ [ 6, 36 ], [ 2, 37 ] ], totalDataCodewords: 290, errorCodewordsPerBlock: 22 }, Q: { groups: [ [ 4, 20 ], [ 6, 21 ] ], totalDataCodewords: 206, errorCodewordsPerBlock: 26 }, H: { groups: [ [ 7, 14 ], [ 4, 15 ] ], totalDataCodewords: 158, errorCodewordsPerBlock: 28 } }, { L: { groups: [[ 4, 107 ]], totalDataCodewords: 428, errorCodewordsPerBlock: 26 }, M: { groups: [ [ 8, 37 ], [ 1, 38 ] ], totalDataCodewords: 334, errorCodewordsPerBlock: 22 }, Q: { groups: [ [ 8, 20 ], [ 4, 21 ] ], totalDataCodewords: 244, errorCodewordsPerBlock: 24 }, H: { groups: [ [ 12, 11 ], [ 4, 12 ] ], totalDataCodewords: 180, errorCodewordsPerBlock: 22 } }, { L: { groups: [ [ 3, 115 ], [ 1, 116 ] ], totalDataCodewords: 461, errorCodewordsPerBlock: 30 }, M: { groups: [ [ 4, 40 ], [ 5, 41 ] ], totalDataCodewords: 365, errorCodewordsPerBlock: 24 }, Q: { groups: [ [ 11, 16 ], [ 5, 17 ] ], totalDataCodewords: 261, errorCodewordsPerBlock: 20 }, H: { groups: [ [ 11, 12 ], [ 5, 13 ] ], totalDataCodewords: 197, errorCodewordsPerBlock: 24 } }, { L: { groups: [ [ 5, 87 ], [ 1, 88 ] ], totalDataCodewords: 523, errorCodewordsPerBlock: 22 }, M: { groups: [ [ 5, 41 ], [ 5, 42 ] ], totalDataCodewords: 415, errorCodewordsPerBlock: 24 }, Q: { groups: [ [ 5, 24 ], [ 7, 25 ] ], totalDataCodewords: 295, errorCodewordsPerBlock: 30 }, H: { groups: [ [ 11, 12 ], [ 7, 13 ] ], totalDataCodewords: 223, errorCodewordsPerBlock: 24 } }, { L: { groups: [ [ 5, 98 ], [ 1, 99 ] ], totalDataCodewords: 589, errorCodewordsPerBlock: 24 }, M: { groups: [ [ 7, 45 ], [ 3, 46 ] ], totalDataCodewords: 453, errorCodewordsPerBlock: 28 }, Q: { groups: [ [ 15, 19 ], [ 2, 20 ] ], totalDataCodewords: 325, errorCodewordsPerBlock: 24 }, H: { groups: [ [ 3, 15 ], [ 13, 16 ] ], totalDataCodewords: 253, errorCodewordsPerBlock: 30 } }, { L: { groups: [ [ 1, 107 ], [ 5, 108 ] ], totalDataCodewords: 647, errorCodewordsPerBlock: 28 }, M: { groups: [ [ 10, 46 ], [ 1, 47 ] ], totalDataCodewords: 507, errorCodewordsPerBlock: 28 }, Q: { groups: [ [ 1, 22 ], [ 15, 23 ] ], totalDataCodewords: 367, errorCodewordsPerBlock: 28 }, H: { groups: [ [ 2, 14 ], [ 17, 15 ] ], totalDataCodewords: 283, errorCodewordsPerBlock: 28 } }, { L: { groups: [ [ 5, 120 ], [ 1, 121 ] ], totalDataCodewords: 721, errorCodewordsPerBlock: 30 }, M: { groups: [ [ 9, 43 ], [ 4, 44 ] ], totalDataCodewords: 563, errorCodewordsPerBlock: 26 }, Q: { groups: [ [ 17, 22 ], [ 1, 23 ] ], totalDataCodewords: 397, errorCodewordsPerBlock: 28 }, H: { groups: [ [ 2, 14 ], [ 19, 15 ] ], totalDataCodewords: 313, errorCodewordsPerBlock: 28 } }, { L: { groups: [ [ 3, 113 ], [ 4, 114 ] ], totalDataCodewords: 795, errorCodewordsPerBlock: 28 }, M: { groups: [ [ 3, 44 ], [ 11, 45 ] ], totalDataCodewords: 627, errorCodewordsPerBlock: 26 }, Q: { groups: [ [ 17, 21 ], [ 4, 22 ] ], totalDataCodewords: 445, errorCodewordsPerBlock: 26 }, H: { groups: [ [ 9, 13 ], [ 16, 14 ] ], totalDataCodewords: 341, errorCodewordsPerBlock: 26 } }, { L: { groups: [ [ 3, 107 ], [ 5, 108 ] ], totalDataCodewords: 861, errorCodewordsPerBlock: 28 }, M: { groups: [ [ 3, 41 ], [ 13, 42 ] ], totalDataCodewords: 669, errorCodewordsPerBlock: 26 }, Q: { groups: [ [ 15, 24 ], [ 5, 25 ] ], totalDataCodewords: 485, errorCodewordsPerBlock: 30 }, H: { groups: [ [ 15, 15 ], [ 10, 16 ] ], totalDataCodewords: 385, errorCodewordsPerBlock: 28 } }, { L: { groups: [ [ 4, 116 ], [ 4, 117 ] ], totalDataCodewords: 932, errorCodewordsPerBlock: 28 }, M: { groups: [[ 17, 42 ]], totalDataCodewords: 714, errorCodewordsPerBlock: 26 }, Q: { groups: [ [ 17, 22 ], [ 6, 23 ] ], totalDataCodewords: 512, errorCodewordsPerBlock: 28 }, H: { groups: [ [ 19, 16 ], [ 6, 17 ] ], totalDataCodewords: 406, errorCodewordsPerBlock: 30 } }, { L: { groups: [ [ 2, 111 ], [ 7, 112 ] ], totalDataCodewords: 1006, errorCodewordsPerBlock: 28 }, M: { groups: [[ 17, 46 ]], totalDataCodewords: 782, errorCodewordsPerBlock: 28 }, Q: { groups: [ [ 7, 24 ], [ 16, 25 ] ], totalDataCodewords: 568, errorCodewordsPerBlock: 30 }, H: { groups: [[ 34, 13 ]], totalDataCodewords: 442, errorCodewordsPerBlock: 24 } }, { L: { groups: [ [ 4, 121 ], [ 5, 122 ] ], totalDataCodewords: 1094, errorCodewordsPerBlock: 30 }, M: { groups: [ [ 4, 47 ], [ 14, 48 ] ], totalDataCodewords: 860, errorCodewordsPerBlock: 28 }, Q: { groups: [ [ 11, 24 ], [ 14, 25 ] ], totalDataCodewords: 614, errorCodewordsPerBlock: 30 }, H: { groups: [ [ 16, 15 ], [ 14, 16 ] ], totalDataCodewords: 464, errorCodewordsPerBlock: 30 } }, { L: { groups: [ [ 6, 117 ], [ 4, 118 ] ], totalDataCodewords: 1174, errorCodewordsPerBlock: 30 }, M: { groups: [ [ 6, 45 ], [ 14, 46 ] ], totalDataCodewords: 914, errorCodewordsPerBlock: 28 }, Q: { groups: [ [ 11, 24 ], [ 16, 25 ] ], totalDataCodewords: 664, errorCodewordsPerBlock: 30 }, H: { groups: [ [ 30, 16 ], [ 2, 17 ] ], totalDataCodewords: 514, errorCodewordsPerBlock: 30 } }, { L: { groups: [ [ 8, 106 ], [ 4, 107 ] ], totalDataCodewords: 1276, errorCodewordsPerBlock: 26 }, M: { groups: [ [ 8, 47 ], [ 13, 48 ] ], totalDataCodewords: 1000, errorCodewordsPerBlock: 28 }, Q: { groups: [ [ 7, 24 ], [ 22, 25 ] ], totalDataCodewords: 718, errorCodewordsPerBlock: 30 }, H: { groups: [ [ 22, 15 ], [ 13, 16 ] ], totalDataCodewords: 538, errorCodewordsPerBlock: 30 } }, { L: { groups: [ [ 10, 114 ], [ 2, 115 ] ], totalDataCodewords: 1370, errorCodewordsPerBlock: 28 }, M: { groups: [ [ 19, 46 ], [ 4, 47 ] ], totalDataCodewords: 1062, errorCodewordsPerBlock: 28 }, Q: { groups: [ [ 28, 22 ], [ 6, 23 ] ], totalDataCodewords: 754, errorCodewordsPerBlock: 28 }, H: { groups: [ [ 33, 16 ], [ 4, 17 ] ], totalDataCodewords: 596, errorCodewordsPerBlock: 30 } }, { L: { groups: [ [ 8, 122 ], [ 4, 123 ] ], totalDataCodewords: 1468, errorCodewordsPerBlock: 30 }, M: { groups: [ [ 22, 45 ], [ 3, 46 ] ], totalDataCodewords: 1128, errorCodewordsPerBlock: 28 }, Q: { groups: [ [ 8, 23 ], [ 26, 24 ] ], totalDataCodewords: 808, errorCodewordsPerBlock: 30 }, H: { groups: [ [ 12, 15 ], [ 28, 16 ] ], totalDataCodewords: 628, errorCodewordsPerBlock: 30 } }, { L: { groups: [ [ 3, 117 ], [ 10, 118 ] ], totalDataCodewords: 1531, errorCodewordsPerBlock: 30 }, M: { groups: [ [ 3, 45 ], [ 23, 46 ] ], totalDataCodewords: 1193, errorCodewordsPerBlock: 28 }, Q: { groups: [ [ 4, 24 ], [ 31, 25 ] ], totalDataCodewords: 871, errorCodewordsPerBlock: 30 }, H: { groups: [ [ 11, 15 ], [ 31, 16 ] ], totalDataCodewords: 661, errorCodewordsPerBlock: 30 } }, { L: { groups: [ [ 7, 116 ], [ 7, 117 ] ], totalDataCodewords: 1631, errorCodewordsPerBlock: 30 }, M: { groups: [ [ 21, 45 ], [ 7, 46 ] ], totalDataCodewords: 1267, errorCodewordsPerBlock: 28 }, Q: { groups: [ [ 1, 23 ], [ 37, 24 ] ], totalDataCodewords: 911, errorCodewordsPerBlock: 30 }, H: { groups: [ [ 19, 15 ], [ 26, 16 ] ], totalDataCodewords: 701, errorCodewordsPerBlock: 30 } }, { L: { groups: [ [ 5, 115 ], [ 10, 116 ] ], totalDataCodewords: 1735, errorCodewordsPerBlock: 30 }, M: { groups: [ [ 19, 47 ], [ 10, 48 ] ], totalDataCodewords: 1373, errorCodewordsPerBlock: 28 }, Q: { groups: [ [ 15, 24 ], [ 25, 25 ] ], totalDataCodewords: 985, errorCodewordsPerBlock: 30 }, H: { groups: [ [ 23, 15 ], [ 25, 16 ] ], totalDataCodewords: 745, errorCodewordsPerBlock: 30 } }, { L: { groups: [ [ 13, 115 ], [ 3, 116 ] ], totalDataCodewords: 1843, errorCodewordsPerBlock: 30 }, M: { groups: [ [ 2, 46 ], [ 29, 47 ] ], totalDataCodewords: 1455, errorCodewordsPerBlock: 28 }, Q: { groups: [ [ 42, 24 ], [ 1, 25 ] ], totalDataCodewords: 1033, errorCodewordsPerBlock: 30 }, H: { groups: [ [ 23, 15 ], [ 28, 16 ] ], totalDataCodewords: 793, errorCodewordsPerBlock: 30 } }, { L: { groups: [[ 17, 115 ]], totalDataCodewords: 1955, errorCodewordsPerBlock: 30 }, M: { groups: [ [ 10, 46 ], [ 23, 47 ] ], totalDataCodewords: 1541, errorCodewordsPerBlock: 28 }, Q: { groups: [ [ 10, 24 ], [ 35, 25 ] ], totalDataCodewords: 1115, errorCodewordsPerBlock: 30 }, H: { groups: [ [ 19, 15 ], [ 35, 16 ] ], totalDataCodewords: 845, errorCodewordsPerBlock: 30 } }, { L: { groups: [ [ 17, 115 ], [ 1, 116 ] ], totalDataCodewords: 2071, errorCodewordsPerBlock: 30 }, M: { groups: [ [ 14, 46 ], [ 21, 47 ] ], totalDataCodewords: 1631, errorCodewordsPerBlock: 28 }, Q: { groups: [ [ 29, 24 ], [ 19, 25 ] ], totalDataCodewords: 1171, errorCodewordsPerBlock: 30 }, H: { groups: [ [ 11, 15 ], [ 46, 16 ] ], totalDataCodewords: 901, errorCodewordsPerBlock: 30 } }, { L: { groups: [ [ 13, 115 ], [ 6, 116 ] ], totalDataCodewords: 2191, errorCodewordsPerBlock: 30 }, M: { groups: [ [ 14, 46 ], [ 23, 47 ] ], totalDataCodewords: 1725, errorCodewordsPerBlock: 28 }, Q: { groups: [ [ 44, 24 ], [ 7, 25 ] ], totalDataCodewords: 1231, errorCodewordsPerBlock: 30 }, H: { groups: [ [ 59, 16 ], [ 1, 17 ] ], totalDataCodewords: 961, errorCodewordsPerBlock: 30 } }, { L: { groups: [ [ 12, 121 ], [ 7, 122 ] ], totalDataCodewords: 2306, errorCodewordsPerBlock: 30 }, M: { groups: [ [ 12, 47 ], [ 26, 48 ] ], totalDataCodewords: 1812, errorCodewordsPerBlock: 28 }, Q: { groups: [ [ 39, 24 ], [ 14, 25 ] ], totalDataCodewords: 1286, errorCodewordsPerBlock: 30 }, H: { groups: [ [ 22, 15 ], [ 41, 16 ] ], totalDataCodewords: 986, errorCodewordsPerBlock: 30 } }, { L: { groups: [ [ 6, 121 ], [ 14, 122 ] ], totalDataCodewords: 2434, errorCodewordsPerBlock: 30 }, M: { groups: [ [ 6, 47 ], [ 34, 48 ] ], totalDataCodewords: 1914, errorCodewordsPerBlock: 28 }, Q: { groups: [ [ 46, 24 ], [ 10, 25 ] ], totalDataCodewords: 1354, errorCodewordsPerBlock: 30 }, H: { groups: [ [ 2, 15 ], [ 64, 16 ] ], totalDataCodewords: 1054, errorCodewordsPerBlock: 30 } }, { L: { groups: [ [ 17, 122 ], [ 4, 123 ] ], totalDataCodewords: 2566, errorCodewordsPerBlock: 30 }, M: { groups: [ [ 29, 46 ], [ 14, 47 ] ], totalDataCodewords: 1992, errorCodewordsPerBlock: 28 }, Q: { groups: [ [ 49, 24 ], [ 10, 25 ] ], totalDataCodewords: 1426, errorCodewordsPerBlock: 30 }, H: { groups: [ [ 24, 15 ], [ 46, 16 ] ], totalDataCodewords: 1096, errorCodewordsPerBlock: 30 } }, { L: { groups: [ [ 4, 122 ], [ 18, 123 ] ], totalDataCodewords: 2702, errorCodewordsPerBlock: 30 }, M: { groups: [ [ 13, 46 ], [ 32, 47 ] ], totalDataCodewords: 2102, errorCodewordsPerBlock: 28 }, Q: { groups: [ [ 48, 24 ], [ 14, 25 ] ], totalDataCodewords: 1502, errorCodewordsPerBlock: 30 }, H: { groups: [ [ 42, 15 ], [ 32, 16 ] ], totalDataCodewords: 1142, errorCodewordsPerBlock: 30 } }, { L: { groups: [ [ 20, 117 ], [ 4, 118 ] ], totalDataCodewords: 2812, errorCodewordsPerBlock: 30 }, M: { groups: [ [ 40, 47 ], [ 7, 48 ] ], totalDataCodewords: 2216, errorCodewordsPerBlock: 28 }, Q: { groups: [ [ 43, 24 ], [ 22, 25 ] ], totalDataCodewords: 1582, errorCodewordsPerBlock: 30 }, H: { groups: [ [ 10, 15 ], [ 67, 16 ] ], totalDataCodewords: 1222, errorCodewordsPerBlock: 30 } }, { L: { groups: [ [ 19, 118 ], [ 6, 119 ] ], totalDataCodewords: 2956, errorCodewordsPerBlock: 30 }, M: { groups: [ [ 18, 47 ], [ 31, 48 ] ], totalDataCodewords: 2334, errorCodewordsPerBlock: 28 }, Q: { groups: [ [ 34, 24 ], [ 34, 25 ] ], totalDataCodewords: 1666, errorCodewordsPerBlock: 30 }, H: { groups: [ [ 20, 15 ], [ 61, 16 ] ], totalDataCodewords: 1276, errorCodewordsPerBlock: 30 } } ], finderPattern = [ 1, 0, 1, 1, 1 ], alignmentPattern = [ 1, 0, 1 ], errorCorrectionPatterns = { L: '01', M: '00', Q: '11', H: '10' }, formatMaskPattern = '101010000010010', formatGeneratorPolynomial = '10100110111', versionGeneratorPolynomial = '1111100100101', paddingCodewords = [ '11101100', '00010001' ], finderPatternValue = 93, maskPatternConditions = [ function (row, column) { return (row + column) % 2 === 0; }, function (row) { return row % 2 === 0; }, function (row, column) { return column % 3 === 0; }, function (row, column) { return (row + column) % 3 === 0; }, function (row, column) { return (Math.floor(row / 2) + Math.floor(column / 3)) % 2 === 0; }, function (row, column) { return row * column % 2 + row * column % 3 === 0; }, function (row, column) { return (row * column % 2 + row * column % 3) % 2 === 0; }, function (row, column) { return ((row + column) % 2 + row * column % 3) % 2 === 0; } ], numberRegex = /^\d+/, alphaPattern = 'A-Z0-9 $%*+./:-', alphaExclusiveSet = 'A-Z $%*+./:-', alphaRegex = new RegExp('^[' + alphaExclusiveSet + ']+'), alphaNumericRegex = new RegExp('^[' + alphaPattern + ']+'), byteRegex = new RegExp('^[^' + alphaPattern + ']+'), initMinNumericBeforeAlpha = 8, initMinNumericBeforeByte = 5, initMinAlphaBeforeByte = 8, minNumericBeforeAlpha = 17, minNumericBeforeByte = 9, minAlphaBeforeByte = 16, round = Math.round; function toDecimal(value) { return parseInt(value, 2); } function toBitsString(value, length) { var result = Number(value).toString(2); if (result.length < length) { result = new Array(length - result.length + 1).join(0) + result; } return result; } function splitInto(str, n) { var result = [], idx = 0; while (idx < str.length) { result.push(str.substring(idx, idx + n)); idx += n; } return result; } var QRDataMode = kendo.Class.extend({ getVersionIndex: function (version) { if (version < 10) { return 0; } else if (version > 26) { return 2; } return 1; }, getBitsCharacterCount: function (version) { var mode = this; return mode.bitsInCharacterCount[mode.getVersionIndex(version || 40)]; }, getModeCountString: function (length, version) { var mode = this; return mode.modeIndicator + toBitsString(length, mode.getBitsCharacterCount(version)); }, encode: function () { }, getStringBitsLength: function () { }, getValue: function () { }, modeIndicator: '', bitsInCharacterCount: [] }); var modes = {}; modes[NUMERIC] = QRDataMode.extend({ bitsInCharacterCount: [ 10, 12, 14 ], modeIndicator: '0001', getValue: function (character) { return parseInt(character, 10); }, encode: function (str, version) { var mode = this, parts = splitInto(str, 3), result = mode.getModeCountString(str.length, version); for (var i = 0; i < parts.length - 1; i++) { result += toBitsString(parts[i], 10); } return result + toBitsString(parts[i], 1 + 3 * parts[i].length); }, getStringBitsLength: function (inputLength, version) { var mod3 = inputLength % 3; return 4 + this.getBitsCharacterCount(version) + 10 * Math.floor(inputLength / 3) + 3 * mod3 + (mod3 === 0 ? 0 : 1); } }); modes[ALPHA_NUMERIC] = QRDataMode.extend({ characters: { '0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9, 'A': 10, 'B': 11, 'C': 12, 'D': 13, 'E': 14, 'F': 15, 'G': 16, 'H': 17, 'I': 18, 'J': 19, 'K': 20, 'L': 21, 'M': 22, 'N': 23, 'O': 24, 'P': 25, 'Q': 26, 'R': 27, 'S': 28, 'T': 29, 'U': 30, 'V': 31, 'W': 32, 'X': 33, 'Y': 34, 'Z': 35, ' ': 36, '$': 37, '%': 38, '*': 39, '+': 40, '-': 41, '.': 42, '/': 43, ':': 44 }, bitsInCharacterCount: [ 9, 11, 13 ], modeIndicator: '0010', getValue: function (character) { return this.characters[character]; }, encode: function (str, version) { var mode = this, parts = splitInto(str, 2), result = mode.getModeCountString(str.length, version), value; for (var i = 0; i < parts.length - 1; i++) { value = 45 * mode.getValue(parts[i].charAt(0)) + mode.getValue(parts[i].charAt(1)); result += toBitsString(value, 11); } value = parts[i].length == 2 ? 45 * mode.getValue(parts[i].charAt(0)) + mode.getValue(parts[i].charAt(1)) : mode.getValue(parts[i].charAt(0)); return result + toBitsString(value, 1 + 5 * parts[i].length); }, getStringBitsLength: function (inputLength, version) { return 4 + this.getBitsCharacterCount(version) + 11 * Math.floor(inputLength / 2) + 6 * (inputLength % 2); } }); modes[BYTE] = QRDataMode.extend({ bitsInCharacterCount: [ 8, 16, 16 ], modeIndicator: '0100', getValue: function (character) { var code = character.charCodeAt(0); if (code <= 127 || 160 <= code && code <= 255) { return code; } else { throw new Error('Unsupported character: ' + character); } }, encode: function (str, version) { var mode = this, result = mode.getModeCountString(str.length, version); for (var i = 0; i < str.length; i++) { result += toBitsString(mode.getValue(str.charAt(i)), 8); } return result; }, getStringBitsLength: function (inputLength, version) { return 4 + this.getBitsCharacterCount(version) + 8 * inputLength; } }); var modeInstances = {}; for (var mode in modes) { modeInstances[mode] = new modes[mode](); } var FreeCellVisitor = function (matrix) { var that = this, row = matrix.length - 1, column = matrix.length - 1, startColumn = column, dir = -1, c = 0; that.move = function () { row += dir * c; c ^= 1; column = startColumn - c; }; that.getNextCell = function () { while (matrix[row][column] !== undefined) { that.move(); if (row < 0 || row >= matrix.length) { dir = -dir; startColumn -= startColumn != 8 ? 2 : 3; column = startColumn; row = dir < 0 ? matrix.length - 1 : 0; } } return { row: row, column: column }; }; that.getNextRemainderCell = function () { that.move(); if (matrix[row][column] === undefined) { return { row: row, column: column }; } }; }; function fillFunctionCell(matrices, bit, x, y) { for (var i = 0; i < matrices.length; i++) { matrices[i][x][y] = bit; } } function fillDataCell(matrices, bit, x, y) { for (var i = 0; i < maskPatternConditions.length; i++) { matrices[i][x][y] = maskPatternConditions[i](x, y) ? bit ^ 1 : parseInt(bit, 10); } } var fillData = function (matrices, blocks) { var cellVisitor = new FreeCellVisitor(matrices[0]), block, codewordIdx, cell; for (var blockIdx = 0; blockIdx < blocks.length; blockIdx++) { block = blocks[blockIdx]; codewordIdx = 0; while (block.length > 0) { for (var i = 0; i < block.length; i++) { for (var j = 0; j < 8; j++) { cell = cellVisitor.getNextCell(); fillDataCell(matrices, block[i][codewordIdx].charAt(j), cell.row, cell.column); } } codewordIdx++; while (block[0] && codewordIdx == block[0].length) { block.splice(0, 1); } } } while (cell = cellVisitor.getNextRemainderCell()) { fillDataCell(matrices, 0, cell.row, cell.column); } }; var padDataString = function (dataString, totalDataCodewords) { var dataBitsCount = totalDataCodewords * 8, terminatorIndex = 0, paddingCodewordIndex = 0; while (dataString.length < dataBitsCount && terminatorIndex < terminator.length) { dataString += terminator.charAt(terminatorIndex++); } if (dataString.length % 8 !== 0) { dataString += new Array(9 - dataString.length % 8).join('0'); } while (dataString.length < dataBitsCount) { dataString += paddingCodewords[paddingCodewordIndex]; paddingCodewordIndex ^= 1; } return dataString; }; function generatePowersOfTwo() { var result; for (var power = 1; power < 255; power++) { result = powersOfTwoResult[power - 1] * 2; if (result > 255) { result = result ^ 285; } powersOfTwoResult[power] = result; powersOfTwo[result] = power; } result = powersOfTwoResult[power - 1] * 2 ^ 285; powersOfTwoResult[power] = result; powersOfTwoResult[-1] = 0; } var xorPolynomials = function (x, y) { var result = [], idx = x.length - 2; for (var i = idx; i >= 0; i--) { result[i] = x[i] ^ y[i]; } return result; }; var multiplyPolynomials = function (x, y) { var result = []; for (var i = 0; i < x.length; i++) { for (var j = 0; j < y.length; j++) { if (result[i + j] === undefined) { result[i + j] = (x[i] + (y[j] >= 0 ? y[j] : 0)) % 255; } else { result[i + j] = powersOfTwo[powersOfTwoResult[result[i + j]] ^ powersOfTwoResult[(x[i] + y[j]) % 255]]; } } } return result; }; function generateGeneratorPolynomials() { var maxErrorCorrectionCodeWordsCount = 68; for (var idx = 2; idx <= maxErrorCorrectionCodeWordsCount; idx++) { var firstPolynomial = generatorPolynomials[idx - 1], secondPolynomial = [ idx, 0 ]; generatorPolynomials[idx] = multiplyPolynomials(firstPolynomial, secondPolynomial); } } generatePowersOfTwo(); generateGeneratorPolynomials(); function multiplyByConstant(polynomial, power) { var result = [], idx = polynomial.length - 1; do { result[idx] = powersOfTwoResult[(polynomial[idx] + power) % 255]; idx--; } while (polynomial[idx] !== undefined); return result; } var generateErrorCodewords = function (data, errorCodewordsCount) { var generator = generatorPolynomials[errorCodewordsCount - 1], result = new Array(errorCodewordsCount).concat(data), generatorPolynomial = new Array(result.length - generator.length).concat(generator), steps = data.length, errorCodewords = [], divisor, idx; for (idx = 0; idx < steps; idx++) { divisor = multiplyByConstant(generatorPolynomial, powersOfTwo[result[result.length - 1]]); generatorPolynomial.splice(0, 1); result = xorPolynomials(divisor, result); } for (idx = result.length - 1; idx >= 0; idx--) { errorCodewords[errorCodewordsCount - 1 - idx] = toBitsString(result[idx], 8); } return errorCodewords; }; var getBlocks = function (dataStream, versionCodewordsInformation) { var codewordStart = 0, dataBlocks = [], errorBlocks = [], dataBlock, versionGroups = versionCodewordsInformation.groups, blockCodewordsCount, groupBlocksCount, messagePolynomial, codeword; for (var groupIdx = 0; groupIdx < versionGroups.length; groupIdx++) { groupBlocksCount = versionGroups[groupIdx][0]; for (var blockIdx = 0; blockIdx < groupBlocksCount; blockIdx++) { blockCodewordsCount = versionGroups[groupIdx][1]; dataBlock = []; messagePolynomial = []; for (var codewordIdx = 1; codewordIdx <= blockCodewordsCount; codewordIdx++) { codeword = dataStream.substring(codewordStart, codewordStart + 8); dataBlock.push(codeword); messagePolynomial[blockCodewordsCount - codewordIdx] = toDecimal(codeword); codewordStart += 8; } dataBlocks.push(dataBlock); errorBlocks.push(generateErrorCodewords(messagePolynomial, versionCodewordsInformation.errorCodewordsPerBlock)); } } return [ dataBlocks, errorBlocks ]; }; var chooseMode = function (str, minNumericBeforeAlpha, minNumericBeforeByte, minAlphaBeforeByte, previousMode) { var numeric = numberRegex.exec(str), numericMatch = numeric ? numeric[0] : '', alpha = alphaRegex.exec(str), alphaMatch = alpha ? alpha[0] : '', alphaNumeric = alphaNumericRegex.exec(str), alphaNumericMatch = alphaNumeric ? alphaNumeric[0] : '', mode, modeString; if (numericMatch && (numericMatch.length >= minNumericBeforeAlpha || str.length == numericMatch.length || numericMatch.length >= minNumericBeforeByte && !alphaNumericRegex.test(str.charAt(numericMatch.length)))) { mode = NUMERIC; modeString = numericMatch; } else if (alphaNumericMatch && (str.length == alphaNumericMatch.length || alphaNumericMatch.length >= minAlphaBeforeByte || previousMode == ALPHA_NUMERIC)) { mode = ALPHA_NUMERIC; modeString = numericMatch || alphaMatch; } else { mode = BYTE; if (alphaNumericMatch) { modeString = alphaNumericMatch + byteRegex.exec(str.substring(alphaNumericMatch.length))[0]; } else { modeString = byteRegex.exec(str)[0]; } } return { mode: mode, modeString: modeString }; }; var getModes = function (str) { var modes = [], previousMode, idx = 0; modes.push(chooseMode(str, initMinNumericBeforeAlpha, initMinNumericBeforeByte, initMinAlphaBeforeByte, previousMode)); previousMode = modes[0].mode; str = str.substr(modes[0].modeString.length); while (str.length > 0) { var nextMode = chooseMode(str, minNumericBeforeAlpha, minNumericBeforeByte, minAlphaBeforeByte, previousMode); if (nextMode.mode != previousMode) { previousMode = nextMode.mode; modes.push(nextMode); idx++; } else { modes[idx].modeString += nextMode.modeString; } str = str.substr(nextMode.modeString.length); } return modes; }; var getDataCodewordsCount = function (modes) { var length = 0, mode; for (var i = 0; i < modes.length; i++) { mode = modeInstances[modes[i].mode]; length += mode.getStringBitsLength(modes[i].modeString.length); } return Math.ceil(length / 8); }; var getVersion = function (dataCodewordsCount, errorCorrectionLevel) { var x = 0, y = versionsCodewordsInformation.length - 1, version = Math.floor(versionsCodewordsInformation.length / 2); do { if (dataCodewordsCount < versionsCodewordsInformation[version][errorCorrectionLevel].totalDataCodewords) { y = version; } else { x = version; } version = x + Math.floor((y - x) / 2); } while (y - x > 1); if (dataCodewordsCount <= versionsCodewordsInformation[x][errorCorrectionLevel].totalDataCodewords) { return version + 1; } return y + 1; }; var getDataString = function (modes, version) { var dataString = '', mode; for (var i = 0; i < modes.length; i++) { mode = modeInstances[modes[i].mode]; dataString += mode.encode(modes[i].modeString, version); } return dataString; }; var encodeFormatInformation = function (format) { var formatNumber = toDecimal(format), encodedString, result = ''; if (formatNumber === 0) { return '101010000010010'; } else { encodedString = encodeBCH(toDecimal(format), formatGeneratorPolynomial, 15); } for (var i = 0; i < encodedString.length; i++) { result += encodedString.charAt(i) ^ formatMaskPattern.charAt(i); } return result; }; var encodeBCH = function (value, generatorPolynomial, codeLength) { var generatorNumber = toDecimal(generatorPolynomial), polynomialLength = generatorPolynomial.length - 1, valueNumber = value << polynomialLength, length = codeLength - polynomialLength, valueString = toBitsString(value, length), result = dividePolynomials(valueNumber, generatorNumber); result = valueString + toBitsString(result, polynomialLength); return result; }; var dividePolynomials = function (numberX, numberY) { var yLength = numberY.toString(2).length, xLength = numberX.toString(2).length; do { numberX ^= numberY << xLength - yLength; xLength = numberX.toString(2).length; } while (xLength >= yLength); return numberX; }; function getNumberAt(str, idx) { return parseInt(str.charAt(idx), 10); } var initMatrices = function (version) { var matrices = [], modules = 17 + 4 * version; for (var i = 0; i < maskPatternConditions.length; i++) { matrices[i] = new Array(modules); for (var j = 0; j < modules; j++) { matrices[i][j] = new Array(modules); } } return matrices; }; var addFormatInformation = function (matrices, formatString) { var matrix = matrices[0], x, y, idx = 0, length = formatString.length; for (x = 0, y = 8; x <= 8; x++) { if (x !== 6) { fillFunctionCell(matrices, getNumberAt(formatString, length - 1 - idx++), x, y); } } for (x = 8, y = 7; y >= 0; y--) { if (y !== 6) { fillFunctionCell(matrices, getNumberAt(formatString, length - 1 - idx++), x, y); } } idx = 0; for (y = matrix.length - 1, x = 8; y >= matrix.length - 8; y--) { fillFunctionCell(matrices, getNumberAt(formatString, length - 1 - idx++), x, y); } fillFunctionCell(matrices, 1, matrix.length - 8, 8); for (x = matrix.length - 7, y = 8; x < matrix.length; x++) { fillFunctionCell(matrices, getNumberAt(formatString, length - 1 - idx++), x, y); } }; var encodeVersionInformation = function (version) { return encodeBCH(version, versionGeneratorPolynomial, 18); }; var addVersionInformation = function (matrices, dataString) { var matrix = matrices[0], modules = matrix.length, x1 = 0, y1 = modules - 11, x2 = modules - 11, y2 = 0, quotient, mod, value; for (var idx = 0; idx < dataString.length; idx++) { quotient = Math.floor(idx / 3); mod = idx % 3; value = getNumberAt(dataString, dataString.length - idx - 1); fillFunctionCell(matrices, value, x1 + quotient, y1 + mod); fillFunctionCell(matrices, value, x2 + mod, y2 + quotient); } }; var addCentricPattern = function (matrices, pattern, x, y) { var size = pattern.length + 2, length = pattern.length + 1, value; for (var i = 0; i < pattern.length; i++) { for (var j = i; j < size - i; j++) { value = pattern[i]; fillFunctionCell(matrices, value, x + j, y + i); fillFunctionCell(matrices, value, x + i, y + j); fillFunctionCell(matrices, value, x + length - j, y + length - i); fillFunctionCell(matrices, value, x + length - i, y + length - j); } } }; var addFinderSeparator = function (matrices, direction, x, y) { var nextX = x, nextY = y, matrix = matrices[0]; do { fillFunctionCell(matrices, 0, nextX, y); fillFunctionCell(matrices, 0, x, nextY); nextX += direction[0]; nextY += direction[1]; } while (nextX >= 0 && nextX < matrix.length); }; var addFinderPatterns = function (matrices) { var modules = matrices[0].length; addCentricPattern(matrices, finderPattern, 0, 0); addFinderSeparator(matrices, [ -1, -1 ], 7, 7); addCentricPattern(matrices, finderPattern, modules - 7, 0); addFinderSeparator(matrices, [ 1, -1 ], modules - 8, 7); addCentricPattern(matrices, finderPattern, 0, modules - 7); addFinderSeparator(matrices, [ -1, 1 ], 7, modules - 8); }; var addAlignmentPatterns = function (matrices, version) { if (version < 2) { return; } var matrix = matrices[0], modules = matrix.length, pointsCount = Math.floor(version / 7), points = [6], startDistance, distance, idx = 0; if (startDistance = irregularAlignmentPatternsStartDistance[version]) { distance = (modules - 13 - startDistance) / pointsCount; } else { startDistance = distance = (modules - 13) / (pointsCount + 1); } points.push(points[idx++] + startDistance); while (points[idx] + distance < modules) { points.push(points[idx++] + distance); } for (var i = 0; i < points.length; i++) { for (var j = 0; j < points.length; j++) { if (matrix[points[i]][points[j]] === undefined) { addCentricPattern(matrices, alignmentPattern, points[i] - 2, points[j] - 2); } } } }; var addTimingFunctions = function (matrices) { var row = 6, column = 6, value = 1, modules = matrices[0].length; for (var i = 8; i < modules - 8; i++) { fillFunctionCell(matrices, value, row, i); fillFunctionCell(matrices, value, i, column); value ^= 1; } }; var scoreMaskMatrixes = function (matrices) { var scores = [], previousBits = [], darkModules = [], patterns = [], adjacentSameBits = [], matrix, i, row = 0, column = 1, modules = matrices[0].length; for (i = 0; i < matrices.length; i++) { scores[i] = 0; darkModules[i] = 0; adjacentSameBits[i] = [ 0, 0 ]; patterns[i] = [ 0, 0 ]; previousBits[i] = []; } for (i = 0; i < modules; i++) { for (var j = 0; j < modules; j++) { for (var k = 0; k < matrices.length; k++) { matrix = matrices[k]; darkModules[k] += parseInt(matrix[i][j], 10); if (previousBits[k][row] === matrix[i][j] && i + 1 < modules && j - 1 >= 0 && matrix[i + 1][j] == previousBits[k][row] && matrix[i + 1][j - 1] == previousBits[k][row]) { scores[k] += 3; } scoreFinderPatternOccurance(k, patterns, scores, row, matrix[i][j]); scoreFinderPatternOccurance(k, patterns, scores, column, matrix[j][i]); scoreAdjacentSameBits(k, scores, previousBits, matrix[i][j], adjacentSameBits, row); scoreAdjacentSameBits(k, scores, previousBits, matrix[j][i], adjacentSameBits, column); } } } var total = modules * modules, minIdx, min = Number.MAX_VALUE; for (i = 0; i < scores.length; i++) { scores[i] += calculateDarkModulesRatioScore(darkModules[i], total); if (scores[i] < min) { min = scores[i]; minIdx = i; } } return minIdx; }; function scoreFinderPatternOccurance(idx, patterns, scores, rowColumn, bit) { patterns[idx][rowColumn] = (patterns[idx][rowColumn] << 1 ^ bit) % 128; if (patterns[idx][rowColumn] == finderPatternValue) { scores[idx] += 40; } } function scoreAdjacentSameBits(idx, scores, previousBits, bit, adjacentBits, rowColumn) { if (previousBits[idx][rowColumn] == bit) { adjacentBits[idx][rowColumn]++; } else { previousBits[idx][rowColumn] = bit; if (adjacentBits[idx][rowColumn] >= 5) { scores[idx] += 3 + adjacentBits[idx][rowColumn] - 5; } adjacentBits[idx][rowColumn] = 1; } } function calculateDarkModulesRatioScore(darkModules, total) { var percent = Math.floor(darkModules / total * 100), mod5 = percent % 5, previous = Math.abs(percent - mod5 - 50), next = Math.abs(percent + 5 - mod5 - 50), score = 10 * Math.min(previous / 5, next / 5); return score; } var EncodingResult = function (dataString, version) { this.dataString = dataString; this.version = version; }; var IsoEncoder = function () { this.getEncodingResult = function (inputString, errorCorrectionLevel) { var modes = getModes(inputString), dataCodewordsCount = getDataCodewordsCount(modes), version = getVersion(dataCodewordsCount, errorCorrectionLevel), dataString = getDataString(modes, version); return new EncodingResult(dataString, version); }; }; var UTF8Encoder = function () { this.mode = modeInstances[this.encodingMode]; }; UTF8Encoder.fn = UTF8Encoder.prototype = { encodingMode: BYTE, utfBOM: '111011111011101110111111', initialModeCountStringLength: 20, getEncodingResult: function (inputString, errorCorrectionLevel) { var that = this, data = that.encode(inputString), dataCodewordsCount = that.getDataCodewordsCount(data), version = getVersion(dataCodewordsCount, errorCorrectionLevel), dataString = that.mode.getModeCountString(data.length / 8, version) + data; return new EncodingResult(dataString, version); }, getDataCodewordsCount: function (data) { var that = this, dataLength = data.length, dataCodewordsCount = Math.ceil((that.initialModeCountStringLength + dataLength) / 8); return dataCodewordsCount; }, encode: function (str) { var that = this, result = that.utfBOM; for (var i = 0; i < str.length; i++) { result += that.encodeCharacter(str.charCodeAt(i)); } return result; }, encodeCharacter: function (code) { var bytesCount = this.getBytesCount(code), bc = bytesCount - 1, result = ''; if (bytesCount == 1) { result = toBitsString(code, 8); } else { var significantOnes = 8 - bytesCount; for (var i = 0; i < bc; i++) { result = toBitsString(code >> i * 6 & 63 | 128, 8) + result; } result = (code >> bc * 6 | 255 >> significantOnes << significantOnes).toString(2) + result; } return result; }, getBytesCount: function (code) { var ranges = this.ranges; for (var i = 0; i < ranges.length; i++) { if (code < ranges[i]) { return i + 1; } } }, ranges: [ 128, 2048, 65536, 2097152, 67108864 ] }; var QRCodeDataEncoder = function (encoding) { if (encoding && encoding.toLowerCase().indexOf('utf_8') >= 0) { return new UTF8Encoder(); } else { return new IsoEncoder(); } }; var encodeData = function (inputString, errorCorrectionLevel, encoding) { var encoder = new QRCodeDataEncoder(encoding), encodingResult = encoder.getEncodingResult(inputString, errorCorrectionLevel), version = encodingResult.version, versionInformation = versionsCodewordsInformation[version - 1][errorCorrectionLevel], dataString = padDataString(encodingResult.dataString, versionInformation.totalDataCodewords), blocks = getBlocks(dataString, versionInformation), matrices = initMatrices(version); addFinderPatterns(matrices); addAlignmentPatterns(matrices, version); addTimingFunctions(matrices); if (version >= 7) { addVersionInformation(matrices, toBitsString(0, 18)); } addFormatInformation(matrices, toBitsString(0, 15)); fillData(matrices, blocks); var minIdx = scoreMaskMatrixes(matrices), optimalMatrix = matrices[minIdx]; if (version >= 7) { addVersionInformation([optimalMatrix], encodeVersionInformation(version)); } var formatString = errorCorrectionPatterns[errorCorrectionLevel] + toBitsString(minIdx, 3); addFormatInformation([optimalMatrix], encodeFormatInformation(formatString)); return optimalMatrix; }; var QRCodeDefaults = { DEFAULT_SIZE: 200, QUIET_ZONE_LENGTH: 4, DEFAULT_ERROR_CORRECTION_LEVEL: 'L', DEFAULT_BACKGROUND: '#fff', DEFAULT_DARK_MODULE_COLOR: '#000', MIN_BASE_UNIT_SIZE: 1 }; var QRCode = Widget.extend({ init: function (element, options) { var that = this; Widget.fn.init.call(that, element, options); that.element = $(element); that.wrapper = that.element; that.element.addClass('k-qrcode'); that.surfaceWrap = $('').css('position', 'relative').appendTo(this.element); that.surface = draw.Surface.create(that.surfaceWrap, { type: that.options.renderAs }); that.setOptions(options); }, redraw: function () { var size = this._getSize(); this.surfaceWrap.css({ width: size, height: size }); this.surface.clear(); this.createVisual(); this.surface.draw(this.visual); }, getSize: function () { return kendo.dimensions(this.element); }, _resize: function () { this.redraw(); }, createVisual: function () { this.visual = this._render(); }, exportVisual: function () { return this._render(); }, _render: function () { var that = this, value = that._value, baseUnit, border = that.options.border || {}, padding = that.options.padding || 0, borderWidth = border.width || 0, quietZoneSize, matrix, size, dataSize, contentSize; border.width = borderWidth; var visual = new draw.Group(); if (value) { matrix = encodeData(value, that.options.errorCorrection, that.options.encoding); size = that._getSize(); contentSize = size - 2 * (borderWidth + padding); baseUnit = that._calculateBaseUnit(contentSize, matrix.length); dataSize = matrix.length * baseUnit; quietZoneSize = borderWidth + padding + (contentSize - dataSize) / 2; visual.append(that._renderBackground(size, border)); visual.append(that._renderMatrix(matrix, baseUnit, quietZoneSize)); } return visual; }, _getSize: function () { var that = this, size; if (that.options.size) { size = parseInt(that.options.size, 10); } else { var element = that.element, min = Math.min(element.width(), element.height()); if (min > 0) { size = min; } else { size = QRCodeDefaults.DEFAULT_SIZE; } } return size; }, _calculateBaseUnit: function (size, matrixSize) { var baseUnit = Math.floor(size / matrixSize); if (baseUnit < QRCodeDefaults.MIN_BASE_UNIT_SIZE) { throw new Error('Insufficient size.'); } if (baseUnit * matrixSize >= size && baseUnit - 1 >= QRCodeDefaults.MIN_BASE_UNIT_SIZE) { baseUnit--; } return baseUnit; }, _renderMatrix: function (matrix, baseUnit, quietZoneSize) { var path = new draw.MultiPath({ fill: { color: this.options.color }, stroke: null }); for (var row = 0; row < matrix.length; row++) { var y = quietZoneSize + row * baseUnit; var column = 0; while (column < matrix.length) { while (matrix[row][column] === 0 && column < matrix.length) { column++; } if (column < matrix.length) { var x = column; while (matrix[row][column] == 1) { column++; } var x1 = round(quietZoneSize + x * baseUnit); var y1 = round(y); var x2 = round(quietZoneSize + column * baseUnit); var y2 = round(y + baseUnit); path.moveTo(x1, y1).lineTo(x1, y2).lineTo(x2, y2).lineTo(x2, y1).close(); } } } return path; }, _renderBackground: function (size, border) { var box = Box2D(0, 0, size, size).unpad(border.width / 2); return draw.Path.fromRect(box.toRect(), { fill: { color: this.options.background }, stroke: { color: border.color, width: border.width } }); }, setOptions: function (options) { var that = this; options = options || {}; that.options = extend(that.options, options); if (options.value !== undefined) { that._value = that.options.value + ''; } that.redraw(); }, value: function (value) { var that = this; if (value === undefined) { return that._value; } that._value = value + ''; that.redraw(); }, options: { name: 'QRCode', renderAs: 'svg', encoding: 'ISO_8859_1', value: '', errorCorrection: QRCodeDefaults.DEFAULT_ERROR_CORRECTION_LEVEL, background: QRCodeDefaults.DEFAULT_BACKGROUND, color: QRCodeDefaults.DEFAULT_DARK_MODULE_COLOR, size: '', padding: 0, border: { color: '', width: 0 } } }); dataviz.ExportMixin.extend(QRCode.fn); dataviz.ui.plugin(QRCode); kendo.deepExtend(dataviz, { QRCode: QRCode, QRCodeDefaults: QRCodeDefaults, QRCodeFunctions: { FreeCellVisitor: FreeCellVisitor, fillData: fillData, padDataString: padDataString, generateErrorCodewords: generateErrorCodewords, xorPolynomials: xorPolynomials, getBlocks: getBlocks, multiplyPolynomials: multiplyPolynomials, chooseMode: chooseMode, getModes: getModes, getDataCodewordsCount: getDataCodewordsCount, getVersion: getVersion, getDataString: getDataString, encodeFormatInformation: encodeFormatInformation, encodeBCH: encodeBCH, dividePolynomials: dividePolynomials, initMatrices: initMatrices, addFormatInformation: addFormatInformation, encodeVersionInformation: encodeVersionInformation, addVersionInformation: addVersionInformation, addCentricPattern: addCentricPattern, addFinderSeparator: addFinderSeparator, addFinderPatterns: addFinderPatterns, addAlignmentPatterns: addAlignmentPatterns, addTimingFunctions: addTimingFunctions, scoreMaskMatrixes: scoreMaskMatrixes, encodeData: encodeData, UTF8Encoder: UTF8Encoder }, QRCodeFields: { modes: modeInstances, powersOfTwo: powersOfTwo, powersOfTwoResult: powersOfTwoResult, generatorPolynomials: generatorPolynomials } }); }(window.kendo.jQuery)); return window.kendo; }, typeof define == 'function' && define.amd ? define : function (a1, a2, a3) { (a3 || a2)(); }));