auditor

Public Website for an auditor
Log | Files | Refs | Submodules | README

qrious.js (71856B)


      1 /*
      2  * QRious v4.0.2
      3  * Copyright (C) 2017 Alasdair Mercer
      4  * Copyright (C) 2010 Tom Zerucha
      5  *
      6  * This program is free software: you can redistribute it and/or modify
      7  * it under the terms of the GNU General Public License as published by
      8  * the Free Software Foundation, either version 3 of the License, or
      9  * (at your option) any later version.
     10  *
     11  * This program is distributed in the hope that it will be useful,
     12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14  * GNU General Public License for more details.
     15  *
     16  * You should have received a copy of the GNU General Public License
     17  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
     18  */
     19 (function (global, factory) {
     20   typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
     21   typeof define === 'function' && define.amd ? define(factory) :
     22   (global.QRious = factory());
     23 }(this, (function () { 'use strict';
     24 
     25   /*
     26    * Copyright (C) 2017 Alasdair Mercer, !ninja
     27    *
     28    * Permission is hereby granted, free of charge, to any person obtaining a copy
     29    * of this software and associated documentation files (the "Software"), to deal
     30    * in the Software without restriction, including without limitation the rights
     31    * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     32    * copies of the Software, and to permit persons to whom the Software is
     33    * furnished to do so, subject to the following conditions:
     34    *
     35    * The above copyright notice and this permission notice shall be included in all
     36    * copies or substantial portions of the Software.
     37    *
     38    * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     39    * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     40    * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
     41    * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     42    * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     43    * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
     44    * SOFTWARE.
     45    */
     46 
     47   /**
     48    * A bare-bones constructor for surrogate prototype swapping.
     49    *
     50    * @private
     51    * @constructor
     52    */
     53   var Constructor = /* istanbul ignore next */ function() {};
     54   /**
     55    * A reference to <code>Object.prototype.hasOwnProperty</code>.
     56    *
     57    * @private
     58    * @type {Function}
     59    */
     60   var hasOwnProperty = Object.prototype.hasOwnProperty;
     61   /**
     62    * A reference to <code>Array.prototype.slice</code>.
     63    *
     64    * @private
     65    * @type {Function}
     66    */
     67   var slice = Array.prototype.slice;
     68 
     69   /**
     70    * Creates an object which inherits the given <code>prototype</code>.
     71    *
     72    * Optionally, the created object can be extended further with the specified <code>properties</code>.
     73    *
     74    * @param {Object} prototype - the prototype to be inherited by the created object
     75    * @param {Object} [properties] - the optional properties to be extended by the created object
     76    * @return {Object} The newly created object.
     77    * @private
     78    */
     79   function createObject(prototype, properties) {
     80     var result;
     81     /* istanbul ignore next */
     82     if (typeof Object.create === 'function') {
     83       result = Object.create(prototype);
     84     } else {
     85       Constructor.prototype = prototype;
     86       result = new Constructor();
     87       Constructor.prototype = null;
     88     }
     89 
     90     if (properties) {
     91       extendObject(true, result, properties);
     92     }
     93 
     94     return result;
     95   }
     96 
     97   /**
     98    * Extends the constructor to which this method is associated with the <code>prototype</code> and/or
     99    * <code>statics</code> provided.
    100    *
    101    * If <code>name</code> is provided, it will be used as the class name and can be accessed via a special
    102    * <code>class_</code> property on the child constructor, otherwise the class name of the super constructor will be used
    103    * instead. The class name may also be used string representation for instances of the child constructor (via
    104    * <code>toString</code>), but this is not applicable to the <i>lite</i> version of Nevis.
    105    *
    106    * If <code>constructor</code> is provided, it will be used as the constructor for the child, otherwise a simple
    107    * constructor which only calls the super constructor will be used instead.
    108    *
    109    * The super constructor can be accessed via a special <code>super_</code> property on the child constructor.
    110    *
    111    * @param {string} [name=this.class_] - the class name to be used for the child constructor
    112    * @param {Function} [constructor] - the constructor for the child
    113    * @param {Object} [prototype] - the prototype properties to be defined for the child
    114    * @param {Object} [statics] - the static properties to be defined for the child
    115    * @return {Function} The child <code>constructor</code> provided or the one created if none was given.
    116    * @public
    117    */
    118   function extend(name, constructor, prototype, statics) {
    119     var superConstructor = this;
    120 
    121     if (typeof name !== 'string') {
    122       statics = prototype;
    123       prototype = constructor;
    124       constructor = name;
    125       name = null;
    126     }
    127 
    128     if (typeof constructor !== 'function') {
    129       statics = prototype;
    130       prototype = constructor;
    131       constructor = function() {
    132         return superConstructor.apply(this, arguments);
    133       };
    134     }
    135 
    136     extendObject(false, constructor, superConstructor, statics);
    137 
    138     constructor.prototype = createObject(superConstructor.prototype, prototype);
    139     constructor.prototype.constructor = constructor;
    140 
    141     constructor.class_ = name || superConstructor.class_;
    142     constructor.super_ = superConstructor;
    143 
    144     return constructor;
    145   }
    146 
    147   /**
    148    * Extends the specified <code>target</code> object with the properties in each of the <code>sources</code> provided.
    149    *
    150    * if any source is <code>null</code> it will be ignored.
    151    *
    152    * @param {boolean} own - <code>true</code> to only copy <b>own</b> properties from <code>sources</code> onto
    153    * <code>target</code>; otherwise <code>false</code>
    154    * @param {Object} target - the target object which should be extended
    155    * @param {...Object} [sources] - the source objects whose properties are to be copied onto <code>target</code>
    156    * @return {void}
    157    * @private
    158    */
    159   function extendObject(own, target, sources) {
    160     sources = slice.call(arguments, 2);
    161 
    162     var property;
    163     var source;
    164 
    165     for (var i = 0, length = sources.length; i < length; i++) {
    166       source = sources[i];
    167 
    168       for (property in source) {
    169         if (!own || hasOwnProperty.call(source, property)) {
    170           target[property] = source[property];
    171         }
    172       }
    173     }
    174   }
    175 
    176   var extend_1 = extend;
    177 
    178   /**
    179    * The base class from which all others should extend.
    180    *
    181    * @public
    182    * @constructor
    183    */
    184   function Nevis() {}
    185   Nevis.class_ = 'Nevis';
    186   Nevis.super_ = Object;
    187 
    188   /**
    189    * Extends the constructor to which this method is associated with the <code>prototype</code> and/or
    190    * <code>statics</code> provided.
    191    *
    192    * If <code>name</code> is provided, it will be used as the class name and can be accessed via a special
    193    * <code>class_</code> property on the child constructor, otherwise the class name of the super constructor will be used
    194    * instead. The class name may also be used string representation for instances of the child constructor (via
    195    * <code>toString</code>), but this is not applicable to the <i>lite</i> version of Nevis.
    196    *
    197    * If <code>constructor</code> is provided, it will be used as the constructor for the child, otherwise a simple
    198    * constructor which only calls the super constructor will be used instead.
    199    *
    200    * The super constructor can be accessed via a special <code>super_</code> property on the child constructor.
    201    *
    202    * @param {string} [name=this.class_] - the class name to be used for the child constructor
    203    * @param {Function} [constructor] - the constructor for the child
    204    * @param {Object} [prototype] - the prototype properties to be defined for the child
    205    * @param {Object} [statics] - the static properties to be defined for the child
    206    * @return {Function} The child <code>constructor</code> provided or the one created if none was given.
    207    * @public
    208    * @static
    209    * @memberof Nevis
    210    */
    211   Nevis.extend = extend_1;
    212 
    213   var nevis = Nevis;
    214 
    215   var lite = nevis;
    216 
    217   /**
    218    * Responsible for rendering a QR code {@link Frame} on a specific type of element.
    219    *
    220    * A renderer may be dependant on the rendering of another element, so the ordering of their execution is important.
    221    *
    222    * The rendering of a element can be deferred by disabling the renderer initially, however, any attempt get the element
    223    * from the renderer will result in it being immediately enabled and the element being rendered.
    224    *
    225    * @param {QRious} qrious - the {@link QRious} instance to be used
    226    * @param {*} element - the element onto which the QR code is to be rendered
    227    * @param {boolean} [enabled] - <code>true</code> this {@link Renderer} is enabled; otherwise <code>false</code>.
    228    * @public
    229    * @class
    230    * @extends Nevis
    231    */
    232   var Renderer = lite.extend(function(qrious, element, enabled) {
    233     /**
    234      * The {@link QRious} instance.
    235      *
    236      * @protected
    237      * @type {QRious}
    238      * @memberof Renderer#
    239      */
    240     this.qrious = qrious;
    241 
    242     /**
    243      * The element onto which this {@link Renderer} is rendering the QR code.
    244      *
    245      * @protected
    246      * @type {*}
    247      * @memberof Renderer#
    248      */
    249     this.element = element;
    250     this.element.qrious = qrious;
    251 
    252     /**
    253      * Whether this {@link Renderer} is enabled.
    254      *
    255      * @protected
    256      * @type {boolean}
    257      * @memberof Renderer#
    258      */
    259     this.enabled = Boolean(enabled);
    260   }, {
    261 
    262     /**
    263      * Draws the specified QR code <code>frame</code> on the underlying element.
    264      *
    265      * Implementations of {@link Renderer} <b>must</b> override this method with their own specific logic.
    266      *
    267      * @param {Frame} frame - the {@link Frame} to be drawn
    268      * @return {void}
    269      * @protected
    270      * @abstract
    271      * @memberof Renderer#
    272      */
    273     draw: function(frame) {},
    274 
    275     /**
    276      * Returns the element onto which this {@link Renderer} is rendering the QR code.
    277      *
    278      * If this method is called while this {@link Renderer} is disabled, it will be immediately enabled and rendered
    279      * before the element is returned.
    280      *
    281      * @return {*} The element.
    282      * @public
    283      * @memberof Renderer#
    284      */
    285     getElement: function() {
    286       if (!this.enabled) {
    287         this.enabled = true;
    288         this.render();
    289       }
    290 
    291       return this.element;
    292     },
    293 
    294     /**
    295      * Calculates the size (in pixel units) to represent an individual module within the QR code based on the
    296      * <code>frame</code> provided.
    297      *
    298      * Any configured padding will be excluded from the returned size.
    299      *
    300      * The returned value will be at least one, even in cases where the size of the QR code does not fit its contents.
    301      * This is done so that the inevitable clipping is handled more gracefully since this way at least something is
    302      * displayed instead of just a blank space filled by the background color.
    303      *
    304      * @param {Frame} frame - the {@link Frame} from which the module size is to be derived
    305      * @return {number} The pixel size for each module in the QR code which will be no less than one.
    306      * @protected
    307      * @memberof Renderer#
    308      */
    309     getModuleSize: function(frame) {
    310       var qrious = this.qrious;
    311       var padding = qrious.padding || 0;
    312       var pixels = Math.floor((qrious.size - (padding * 2)) / frame.width);
    313 
    314       return Math.max(1, pixels);
    315     },
    316 
    317     /**
    318      * Calculates the offset/padding (in pixel units) to be inserted before the QR code based on the <code>frame</code>
    319      * provided.
    320      *
    321      * The returned value will be zero if there is no available offset or if the size of the QR code does not fit its
    322      * contents. It will never be a negative value. This is done so that the inevitable clipping appears more naturally
    323      * and it is not clipped from all directions.
    324      *
    325      * @param {Frame} frame - the {@link Frame} from which the offset is to be derived
    326      * @return {number} The pixel offset for the QR code which will be no less than zero.
    327      * @protected
    328      * @memberof Renderer#
    329      */
    330     getOffset: function(frame) {
    331       var qrious = this.qrious;
    332       var padding = qrious.padding;
    333 
    334       if (padding != null) {
    335         return padding;
    336       }
    337 
    338       var moduleSize = this.getModuleSize(frame);
    339       var offset = Math.floor((qrious.size - (moduleSize * frame.width)) / 2);
    340 
    341       return Math.max(0, offset);
    342     },
    343 
    344     /**
    345      * Renders a QR code on the underlying element based on the <code>frame</code> provided.
    346      *
    347      * @param {Frame} frame - the {@link Frame} to be rendered
    348      * @return {void}
    349      * @public
    350      * @memberof Renderer#
    351      */
    352     render: function(frame) {
    353       if (this.enabled) {
    354         this.resize();
    355         this.reset();
    356         this.draw(frame);
    357       }
    358     },
    359 
    360     /**
    361      * Resets the underlying element, effectively clearing any previously rendered QR code.
    362      *
    363      * Implementations of {@link Renderer} <b>must</b> override this method with their own specific logic.
    364      *
    365      * @return {void}
    366      * @protected
    367      * @abstract
    368      * @memberof Renderer#
    369      */
    370     reset: function() {},
    371 
    372     /**
    373      * Ensures that the size of the underlying element matches that defined on the associated {@link QRious} instance.
    374      *
    375      * Implementations of {@link Renderer} <b>must</b> override this method with their own specific logic.
    376      *
    377      * @return {void}
    378      * @protected
    379      * @abstract
    380      * @memberof Renderer#
    381      */
    382     resize: function() {}
    383 
    384   });
    385 
    386   var Renderer_1 = Renderer;
    387 
    388   /**
    389    * An implementation of {@link Renderer} for working with <code>canvas</code> elements.
    390    *
    391    * @public
    392    * @class
    393    * @extends Renderer
    394    */
    395   var CanvasRenderer = Renderer_1.extend({
    396 
    397     /**
    398      * @override
    399      */
    400     draw: function(frame) {
    401       var i, j;
    402       var qrious = this.qrious;
    403       var moduleSize = this.getModuleSize(frame);
    404       var offset = this.getOffset(frame);
    405       var context = this.element.getContext('2d');
    406 
    407       context.fillStyle = qrious.foreground;
    408       context.globalAlpha = qrious.foregroundAlpha;
    409 
    410       for (i = 0; i < frame.width; i++) {
    411         for (j = 0; j < frame.width; j++) {
    412           if (frame.buffer[(j * frame.width) + i]) {
    413             context.fillRect((moduleSize * i) + offset, (moduleSize * j) + offset, moduleSize, moduleSize);
    414           }
    415         }
    416       }
    417     },
    418 
    419     /**
    420      * @override
    421      */
    422     reset: function() {
    423       var qrious = this.qrious;
    424       var context = this.element.getContext('2d');
    425       var size = qrious.size;
    426 
    427       context.lineWidth = 1;
    428       context.clearRect(0, 0, size, size);
    429       context.fillStyle = qrious.background;
    430       context.globalAlpha = qrious.backgroundAlpha;
    431       context.fillRect(0, 0, size, size);
    432     },
    433 
    434     /**
    435      * @override
    436      */
    437     resize: function() {
    438       var element = this.element;
    439 
    440       element.width = element.height = this.qrious.size;
    441     }
    442 
    443   });
    444 
    445   var CanvasRenderer_1 = CanvasRenderer;
    446 
    447   /* eslint no-multi-spaces: "off" */
    448 
    449 
    450 
    451   /**
    452    * Contains alignment pattern information.
    453    *
    454    * @public
    455    * @class
    456    * @extends Nevis
    457    */
    458   var Alignment = lite.extend(null, {
    459 
    460     /**
    461      * The alignment pattern block.
    462      *
    463      * @public
    464      * @static
    465      * @type {number[]}
    466      * @memberof Alignment
    467      */
    468     BLOCK: [
    469       0,  11, 15, 19, 23, 27, 31,
    470       16, 18, 20, 22, 24, 26, 28, 20, 22, 24, 24, 26, 28, 28, 22, 24, 24,
    471       26, 26, 28, 28, 24, 24, 26, 26, 26, 28, 28, 24, 26, 26, 26, 28, 28
    472     ]
    473 
    474   });
    475 
    476   var Alignment_1 = Alignment;
    477 
    478   /* eslint no-multi-spaces: "off" */
    479 
    480 
    481 
    482   /**
    483    * Contains error correction information.
    484    *
    485    * @public
    486    * @class
    487    * @extends Nevis
    488    */
    489   var ErrorCorrection = lite.extend(null, {
    490 
    491     /**
    492      * The error correction blocks.
    493      *
    494      * There are four elements per version. The first two indicate the number of blocks, then the data width, and finally
    495      * the ECC width.
    496      *
    497      * @public
    498      * @static
    499      * @type {number[]}
    500      * @memberof ErrorCorrection
    501      */
    502     BLOCKS: [
    503       1,  0,  19,  7,     1,  0,  16,  10,    1,  0,  13,  13,    1,  0,  9,   17,
    504       1,  0,  34,  10,    1,  0,  28,  16,    1,  0,  22,  22,    1,  0,  16,  28,
    505       1,  0,  55,  15,    1,  0,  44,  26,    2,  0,  17,  18,    2,  0,  13,  22,
    506       1,  0,  80,  20,    2,  0,  32,  18,    2,  0,  24,  26,    4,  0,  9,   16,
    507       1,  0,  108, 26,    2,  0,  43,  24,    2,  2,  15,  18,    2,  2,  11,  22,
    508       2,  0,  68,  18,    4,  0,  27,  16,    4,  0,  19,  24,    4,  0,  15,  28,
    509       2,  0,  78,  20,    4,  0,  31,  18,    2,  4,  14,  18,    4,  1,  13,  26,
    510       2,  0,  97,  24,    2,  2,  38,  22,    4,  2,  18,  22,    4,  2,  14,  26,
    511       2,  0,  116, 30,    3,  2,  36,  22,    4,  4,  16,  20,    4,  4,  12,  24,
    512       2,  2,  68,  18,    4,  1,  43,  26,    6,  2,  19,  24,    6,  2,  15,  28,
    513       4,  0,  81,  20,    1,  4,  50,  30,    4,  4,  22,  28,    3,  8,  12,  24,
    514       2,  2,  92,  24,    6,  2,  36,  22,    4,  6,  20,  26,    7,  4,  14,  28,
    515       4,  0,  107, 26,    8,  1,  37,  22,    8,  4,  20,  24,    12, 4,  11,  22,
    516       3,  1,  115, 30,    4,  5,  40,  24,    11, 5,  16,  20,    11, 5,  12,  24,
    517       5,  1,  87,  22,    5,  5,  41,  24,    5,  7,  24,  30,    11, 7,  12,  24,
    518       5,  1,  98,  24,    7,  3,  45,  28,    15, 2,  19,  24,    3,  13, 15,  30,
    519       1,  5,  107, 28,    10, 1,  46,  28,    1,  15, 22,  28,    2,  17, 14,  28,
    520       5,  1,  120, 30,    9,  4,  43,  26,    17, 1,  22,  28,    2,  19, 14,  28,
    521       3,  4,  113, 28,    3,  11, 44,  26,    17, 4,  21,  26,    9,  16, 13,  26,
    522       3,  5,  107, 28,    3,  13, 41,  26,    15, 5,  24,  30,    15, 10, 15,  28,
    523       4,  4,  116, 28,    17, 0,  42,  26,    17, 6,  22,  28,    19, 6,  16,  30,
    524       2,  7,  111, 28,    17, 0,  46,  28,    7,  16, 24,  30,    34, 0,  13,  24,
    525       4,  5,  121, 30,    4,  14, 47,  28,    11, 14, 24,  30,    16, 14, 15,  30,
    526       6,  4,  117, 30,    6,  14, 45,  28,    11, 16, 24,  30,    30, 2,  16,  30,
    527       8,  4,  106, 26,    8,  13, 47,  28,    7,  22, 24,  30,    22, 13, 15,  30,
    528       10, 2,  114, 28,    19, 4,  46,  28,    28, 6,  22,  28,    33, 4,  16,  30,
    529       8,  4,  122, 30,    22, 3,  45,  28,    8,  26, 23,  30,    12, 28, 15,  30,
    530       3,  10, 117, 30,    3,  23, 45,  28,    4,  31, 24,  30,    11, 31, 15,  30,
    531       7,  7,  116, 30,    21, 7,  45,  28,    1,  37, 23,  30,    19, 26, 15,  30,
    532       5,  10, 115, 30,    19, 10, 47,  28,    15, 25, 24,  30,    23, 25, 15,  30,
    533       13, 3,  115, 30,    2,  29, 46,  28,    42, 1,  24,  30,    23, 28, 15,  30,
    534       17, 0,  115, 30,    10, 23, 46,  28,    10, 35, 24,  30,    19, 35, 15,  30,
    535       17, 1,  115, 30,    14, 21, 46,  28,    29, 19, 24,  30,    11, 46, 15,  30,
    536       13, 6,  115, 30,    14, 23, 46,  28,    44, 7,  24,  30,    59, 1,  16,  30,
    537       12, 7,  121, 30,    12, 26, 47,  28,    39, 14, 24,  30,    22, 41, 15,  30,
    538       6,  14, 121, 30,    6,  34, 47,  28,    46, 10, 24,  30,    2,  64, 15,  30,
    539       17, 4,  122, 30,    29, 14, 46,  28,    49, 10, 24,  30,    24, 46, 15,  30,
    540       4,  18, 122, 30,    13, 32, 46,  28,    48, 14, 24,  30,    42, 32, 15,  30,
    541       20, 4,  117, 30,    40, 7,  47,  28,    43, 22, 24,  30,    10, 67, 15,  30,
    542       19, 6,  118, 30,    18, 31, 47,  28,    34, 34, 24,  30,    20, 61, 15,  30
    543     ],
    544 
    545     /**
    546      * The final format bits with mask (level << 3 | mask).
    547      *
    548      * @public
    549      * @static
    550      * @type {number[]}
    551      * @memberof ErrorCorrection
    552      */
    553     FINAL_FORMAT: [
    554       // L
    555       0x77c4, 0x72f3, 0x7daa, 0x789d, 0x662f, 0x6318, 0x6c41, 0x6976,
    556       // M
    557       0x5412, 0x5125, 0x5e7c, 0x5b4b, 0x45f9, 0x40ce, 0x4f97, 0x4aa0,
    558       // Q
    559       0x355f, 0x3068, 0x3f31, 0x3a06, 0x24b4, 0x2183, 0x2eda, 0x2bed,
    560       // H
    561       0x1689, 0x13be, 0x1ce7, 0x19d0, 0x0762, 0x0255, 0x0d0c, 0x083b
    562     ],
    563 
    564     /**
    565      * A map of human-readable ECC levels.
    566      *
    567      * @public
    568      * @static
    569      * @type {Object.<string, number>}
    570      * @memberof ErrorCorrection
    571      */
    572     LEVELS: {
    573       L: 1,
    574       M: 2,
    575       Q: 3,
    576       H: 4
    577     }
    578 
    579   });
    580 
    581   var ErrorCorrection_1 = ErrorCorrection;
    582 
    583   /**
    584    * Contains Galois field information.
    585    *
    586    * @public
    587    * @class
    588    * @extends Nevis
    589    */
    590   var Galois = lite.extend(null, {
    591 
    592     /**
    593      * The Galois field exponent table.
    594      *
    595      * @public
    596      * @static
    597      * @type {number[]}
    598      * @memberof Galois
    599      */
    600     EXPONENT: [
    601       0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1d, 0x3a, 0x74, 0xe8, 0xcd, 0x87, 0x13, 0x26,
    602       0x4c, 0x98, 0x2d, 0x5a, 0xb4, 0x75, 0xea, 0xc9, 0x8f, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0,
    603       0x9d, 0x27, 0x4e, 0x9c, 0x25, 0x4a, 0x94, 0x35, 0x6a, 0xd4, 0xb5, 0x77, 0xee, 0xc1, 0x9f, 0x23,
    604       0x46, 0x8c, 0x05, 0x0a, 0x14, 0x28, 0x50, 0xa0, 0x5d, 0xba, 0x69, 0xd2, 0xb9, 0x6f, 0xde, 0xa1,
    605       0x5f, 0xbe, 0x61, 0xc2, 0x99, 0x2f, 0x5e, 0xbc, 0x65, 0xca, 0x89, 0x0f, 0x1e, 0x3c, 0x78, 0xf0,
    606       0xfd, 0xe7, 0xd3, 0xbb, 0x6b, 0xd6, 0xb1, 0x7f, 0xfe, 0xe1, 0xdf, 0xa3, 0x5b, 0xb6, 0x71, 0xe2,
    607       0xd9, 0xaf, 0x43, 0x86, 0x11, 0x22, 0x44, 0x88, 0x0d, 0x1a, 0x34, 0x68, 0xd0, 0xbd, 0x67, 0xce,
    608       0x81, 0x1f, 0x3e, 0x7c, 0xf8, 0xed, 0xc7, 0x93, 0x3b, 0x76, 0xec, 0xc5, 0x97, 0x33, 0x66, 0xcc,
    609       0x85, 0x17, 0x2e, 0x5c, 0xb8, 0x6d, 0xda, 0xa9, 0x4f, 0x9e, 0x21, 0x42, 0x84, 0x15, 0x2a, 0x54,
    610       0xa8, 0x4d, 0x9a, 0x29, 0x52, 0xa4, 0x55, 0xaa, 0x49, 0x92, 0x39, 0x72, 0xe4, 0xd5, 0xb7, 0x73,
    611       0xe6, 0xd1, 0xbf, 0x63, 0xc6, 0x91, 0x3f, 0x7e, 0xfc, 0xe5, 0xd7, 0xb3, 0x7b, 0xf6, 0xf1, 0xff,
    612       0xe3, 0xdb, 0xab, 0x4b, 0x96, 0x31, 0x62, 0xc4, 0x95, 0x37, 0x6e, 0xdc, 0xa5, 0x57, 0xae, 0x41,
    613       0x82, 0x19, 0x32, 0x64, 0xc8, 0x8d, 0x07, 0x0e, 0x1c, 0x38, 0x70, 0xe0, 0xdd, 0xa7, 0x53, 0xa6,
    614       0x51, 0xa2, 0x59, 0xb2, 0x79, 0xf2, 0xf9, 0xef, 0xc3, 0x9b, 0x2b, 0x56, 0xac, 0x45, 0x8a, 0x09,
    615       0x12, 0x24, 0x48, 0x90, 0x3d, 0x7a, 0xf4, 0xf5, 0xf7, 0xf3, 0xfb, 0xeb, 0xcb, 0x8b, 0x0b, 0x16,
    616       0x2c, 0x58, 0xb0, 0x7d, 0xfa, 0xe9, 0xcf, 0x83, 0x1b, 0x36, 0x6c, 0xd8, 0xad, 0x47, 0x8e, 0x00
    617     ],
    618 
    619     /**
    620      * The Galois field log table.
    621      *
    622      * @public
    623      * @static
    624      * @type {number[]}
    625      * @memberof Galois
    626      */
    627     LOG: [
    628       0xff, 0x00, 0x01, 0x19, 0x02, 0x32, 0x1a, 0xc6, 0x03, 0xdf, 0x33, 0xee, 0x1b, 0x68, 0xc7, 0x4b,
    629       0x04, 0x64, 0xe0, 0x0e, 0x34, 0x8d, 0xef, 0x81, 0x1c, 0xc1, 0x69, 0xf8, 0xc8, 0x08, 0x4c, 0x71,
    630       0x05, 0x8a, 0x65, 0x2f, 0xe1, 0x24, 0x0f, 0x21, 0x35, 0x93, 0x8e, 0xda, 0xf0, 0x12, 0x82, 0x45,
    631       0x1d, 0xb5, 0xc2, 0x7d, 0x6a, 0x27, 0xf9, 0xb9, 0xc9, 0x9a, 0x09, 0x78, 0x4d, 0xe4, 0x72, 0xa6,
    632       0x06, 0xbf, 0x8b, 0x62, 0x66, 0xdd, 0x30, 0xfd, 0xe2, 0x98, 0x25, 0xb3, 0x10, 0x91, 0x22, 0x88,
    633       0x36, 0xd0, 0x94, 0xce, 0x8f, 0x96, 0xdb, 0xbd, 0xf1, 0xd2, 0x13, 0x5c, 0x83, 0x38, 0x46, 0x40,
    634       0x1e, 0x42, 0xb6, 0xa3, 0xc3, 0x48, 0x7e, 0x6e, 0x6b, 0x3a, 0x28, 0x54, 0xfa, 0x85, 0xba, 0x3d,
    635       0xca, 0x5e, 0x9b, 0x9f, 0x0a, 0x15, 0x79, 0x2b, 0x4e, 0xd4, 0xe5, 0xac, 0x73, 0xf3, 0xa7, 0x57,
    636       0x07, 0x70, 0xc0, 0xf7, 0x8c, 0x80, 0x63, 0x0d, 0x67, 0x4a, 0xde, 0xed, 0x31, 0xc5, 0xfe, 0x18,
    637       0xe3, 0xa5, 0x99, 0x77, 0x26, 0xb8, 0xb4, 0x7c, 0x11, 0x44, 0x92, 0xd9, 0x23, 0x20, 0x89, 0x2e,
    638       0x37, 0x3f, 0xd1, 0x5b, 0x95, 0xbc, 0xcf, 0xcd, 0x90, 0x87, 0x97, 0xb2, 0xdc, 0xfc, 0xbe, 0x61,
    639       0xf2, 0x56, 0xd3, 0xab, 0x14, 0x2a, 0x5d, 0x9e, 0x84, 0x3c, 0x39, 0x53, 0x47, 0x6d, 0x41, 0xa2,
    640       0x1f, 0x2d, 0x43, 0xd8, 0xb7, 0x7b, 0xa4, 0x76, 0xc4, 0x17, 0x49, 0xec, 0x7f, 0x0c, 0x6f, 0xf6,
    641       0x6c, 0xa1, 0x3b, 0x52, 0x29, 0x9d, 0x55, 0xaa, 0xfb, 0x60, 0x86, 0xb1, 0xbb, 0xcc, 0x3e, 0x5a,
    642       0xcb, 0x59, 0x5f, 0xb0, 0x9c, 0xa9, 0xa0, 0x51, 0x0b, 0xf5, 0x16, 0xeb, 0x7a, 0x75, 0x2c, 0xd7,
    643       0x4f, 0xae, 0xd5, 0xe9, 0xe6, 0xe7, 0xad, 0xe8, 0x74, 0xd6, 0xf4, 0xea, 0xa8, 0x50, 0x58, 0xaf
    644     ]
    645 
    646   });
    647 
    648   var Galois_1 = Galois;
    649 
    650   /**
    651    * Contains version pattern information.
    652    *
    653    * @public
    654    * @class
    655    * @extends Nevis
    656    */
    657   var Version = lite.extend(null, {
    658 
    659     /**
    660      * The version pattern block.
    661      *
    662      * @public
    663      * @static
    664      * @type {number[]}
    665      * @memberof Version
    666      */
    667     BLOCK: [
    668       0xc94, 0x5bc, 0xa99, 0x4d3, 0xbf6, 0x762, 0x847, 0x60d, 0x928, 0xb78, 0x45d, 0xa17, 0x532,
    669       0x9a6, 0x683, 0x8c9, 0x7ec, 0xec4, 0x1e1, 0xfab, 0x08e, 0xc1a, 0x33f, 0xd75, 0x250, 0x9d5,
    670       0x6f0, 0x8ba, 0x79f, 0xb0b, 0x42e, 0xa64, 0x541, 0xc69
    671     ]
    672 
    673   });
    674 
    675   var Version_1 = Version;
    676 
    677   /**
    678    * Generates information for a QR code frame based on a specific value to be encoded.
    679    *
    680    * @param {Frame~Options} options - the options to be used
    681    * @public
    682    * @class
    683    * @extends Nevis
    684    */
    685   var Frame = lite.extend(function(options) {
    686     var dataBlock, eccBlock, index, neccBlock1, neccBlock2;
    687     var valueLength = options.value.length;
    688 
    689     this._badness = [];
    690     this._level = ErrorCorrection_1.LEVELS[options.level];
    691     this._polynomial = [];
    692     this._value = options.value;
    693     this._version = 0;
    694     this._stringBuffer = [];
    695 
    696     while (this._version < 40) {
    697       this._version++;
    698 
    699       index = ((this._level - 1) * 4) + ((this._version - 1) * 16);
    700 
    701       neccBlock1 = ErrorCorrection_1.BLOCKS[index++];
    702       neccBlock2 = ErrorCorrection_1.BLOCKS[index++];
    703       dataBlock = ErrorCorrection_1.BLOCKS[index++];
    704       eccBlock = ErrorCorrection_1.BLOCKS[index];
    705 
    706       index = (dataBlock * (neccBlock1 + neccBlock2)) + neccBlock2 - 3 + (this._version <= 9);
    707 
    708       if (valueLength <= index) {
    709         break;
    710       }
    711     }
    712 
    713     this._dataBlock = dataBlock;
    714     this._eccBlock = eccBlock;
    715     this._neccBlock1 = neccBlock1;
    716     this._neccBlock2 = neccBlock2;
    717 
    718     /**
    719      * The data width is based on version.
    720      *
    721      * @public
    722      * @type {number}
    723      * @memberof Frame#
    724      */
    725     // FIXME: Ensure that it fits instead of being truncated.
    726     var width = this.width = 17 + (4 * this._version);
    727 
    728     /**
    729      * The image buffer.
    730      *
    731      * @public
    732      * @type {number[]}
    733      * @memberof Frame#
    734      */
    735     this.buffer = Frame._createArray(width * width);
    736 
    737     this._ecc = Frame._createArray(dataBlock + ((dataBlock + eccBlock) * (neccBlock1 + neccBlock2)) + neccBlock2);
    738     this._mask = Frame._createArray(((width * (width + 1)) + 1) / 2);
    739 
    740     this._insertFinders();
    741     this._insertAlignments();
    742 
    743     // Insert single foreground cell.
    744     this.buffer[8 + (width * (width - 8))] = 1;
    745 
    746     this._insertTimingGap();
    747     this._reverseMask();
    748     this._insertTimingRowAndColumn();
    749     this._insertVersion();
    750     this._syncMask();
    751     this._convertBitStream(valueLength);
    752     this._calculatePolynomial();
    753     this._appendEccToData();
    754     this._interleaveBlocks();
    755     this._pack();
    756     this._finish();
    757   }, {
    758 
    759     _addAlignment: function(x, y) {
    760       var i;
    761       var buffer = this.buffer;
    762       var width = this.width;
    763 
    764       buffer[x + (width * y)] = 1;
    765 
    766       for (i = -2; i < 2; i++) {
    767         buffer[x + i + (width * (y - 2))] = 1;
    768         buffer[x - 2 + (width * (y + i + 1))] = 1;
    769         buffer[x + 2 + (width * (y + i))] = 1;
    770         buffer[x + i + 1 + (width * (y + 2))] = 1;
    771       }
    772 
    773       for (i = 0; i < 2; i++) {
    774         this._setMask(x - 1, y + i);
    775         this._setMask(x + 1, y - i);
    776         this._setMask(x - i, y - 1);
    777         this._setMask(x + i, y + 1);
    778       }
    779     },
    780 
    781     _appendData: function(data, dataLength, ecc, eccLength) {
    782       var bit, i, j;
    783       var polynomial = this._polynomial;
    784       var stringBuffer = this._stringBuffer;
    785 
    786       for (i = 0; i < eccLength; i++) {
    787         stringBuffer[ecc + i] = 0;
    788       }
    789 
    790       for (i = 0; i < dataLength; i++) {
    791         bit = Galois_1.LOG[stringBuffer[data + i] ^ stringBuffer[ecc]];
    792 
    793         if (bit !== 255) {
    794           for (j = 1; j < eccLength; j++) {
    795             stringBuffer[ecc + j - 1] = stringBuffer[ecc + j] ^
    796               Galois_1.EXPONENT[Frame._modN(bit + polynomial[eccLength - j])];
    797           }
    798         } else {
    799           for (j = ecc; j < ecc + eccLength; j++) {
    800             stringBuffer[j] = stringBuffer[j + 1];
    801           }
    802         }
    803 
    804         stringBuffer[ecc + eccLength - 1] = bit === 255 ? 0 : Galois_1.EXPONENT[Frame._modN(bit + polynomial[0])];
    805       }
    806     },
    807 
    808     _appendEccToData: function() {
    809       var i;
    810       var data = 0;
    811       var dataBlock = this._dataBlock;
    812       var ecc = this._calculateMaxLength();
    813       var eccBlock = this._eccBlock;
    814 
    815       for (i = 0; i < this._neccBlock1; i++) {
    816         this._appendData(data, dataBlock, ecc, eccBlock);
    817 
    818         data += dataBlock;
    819         ecc += eccBlock;
    820       }
    821 
    822       for (i = 0; i < this._neccBlock2; i++) {
    823         this._appendData(data, dataBlock + 1, ecc, eccBlock);
    824 
    825         data += dataBlock + 1;
    826         ecc += eccBlock;
    827       }
    828     },
    829 
    830     _applyMask: function(mask) {
    831       var r3x, r3y, x, y;
    832       var buffer = this.buffer;
    833       var width = this.width;
    834 
    835       switch (mask) {
    836       case 0:
    837         for (y = 0; y < width; y++) {
    838           for (x = 0; x < width; x++) {
    839             if (!((x + y) & 1) && !this._isMasked(x, y)) {
    840               buffer[x + (y * width)] ^= 1;
    841             }
    842           }
    843         }
    844 
    845         break;
    846       case 1:
    847         for (y = 0; y < width; y++) {
    848           for (x = 0; x < width; x++) {
    849             if (!(y & 1) && !this._isMasked(x, y)) {
    850               buffer[x + (y * width)] ^= 1;
    851             }
    852           }
    853         }
    854 
    855         break;
    856       case 2:
    857         for (y = 0; y < width; y++) {
    858           for (r3x = 0, x = 0; x < width; x++, r3x++) {
    859             if (r3x === 3) {
    860               r3x = 0;
    861             }
    862 
    863             if (!r3x && !this._isMasked(x, y)) {
    864               buffer[x + (y * width)] ^= 1;
    865             }
    866           }
    867         }
    868 
    869         break;
    870       case 3:
    871         for (r3y = 0, y = 0; y < width; y++, r3y++) {
    872           if (r3y === 3) {
    873             r3y = 0;
    874           }
    875 
    876           for (r3x = r3y, x = 0; x < width; x++, r3x++) {
    877             if (r3x === 3) {
    878               r3x = 0;
    879             }
    880 
    881             if (!r3x && !this._isMasked(x, y)) {
    882               buffer[x + (y * width)] ^= 1;
    883             }
    884           }
    885         }
    886 
    887         break;
    888       case 4:
    889         for (y = 0; y < width; y++) {
    890           for (r3x = 0, r3y = (y >> 1) & 1, x = 0; x < width; x++, r3x++) {
    891             if (r3x === 3) {
    892               r3x = 0;
    893               r3y = !r3y;
    894             }
    895 
    896             if (!r3y && !this._isMasked(x, y)) {
    897               buffer[x + (y * width)] ^= 1;
    898             }
    899           }
    900         }
    901 
    902         break;
    903       case 5:
    904         for (r3y = 0, y = 0; y < width; y++, r3y++) {
    905           if (r3y === 3) {
    906             r3y = 0;
    907           }
    908 
    909           for (r3x = 0, x = 0; x < width; x++, r3x++) {
    910             if (r3x === 3) {
    911               r3x = 0;
    912             }
    913 
    914             if (!((x & y & 1) + !(!r3x | !r3y)) && !this._isMasked(x, y)) {
    915               buffer[x + (y * width)] ^= 1;
    916             }
    917           }
    918         }
    919 
    920         break;
    921       case 6:
    922         for (r3y = 0, y = 0; y < width; y++, r3y++) {
    923           if (r3y === 3) {
    924             r3y = 0;
    925           }
    926 
    927           for (r3x = 0, x = 0; x < width; x++, r3x++) {
    928             if (r3x === 3) {
    929               r3x = 0;
    930             }
    931 
    932             if (!((x & y & 1) + (r3x && r3x === r3y) & 1) && !this._isMasked(x, y)) {
    933               buffer[x + (y * width)] ^= 1;
    934             }
    935           }
    936         }
    937 
    938         break;
    939       case 7:
    940         for (r3y = 0, y = 0; y < width; y++, r3y++) {
    941           if (r3y === 3) {
    942             r3y = 0;
    943           }
    944 
    945           for (r3x = 0, x = 0; x < width; x++, r3x++) {
    946             if (r3x === 3) {
    947               r3x = 0;
    948             }
    949 
    950             if (!((r3x && r3x === r3y) + (x + y & 1) & 1) && !this._isMasked(x, y)) {
    951               buffer[x + (y * width)] ^= 1;
    952             }
    953           }
    954         }
    955 
    956         break;
    957       }
    958     },
    959 
    960     _calculateMaxLength: function() {
    961       return (this._dataBlock * (this._neccBlock1 + this._neccBlock2)) + this._neccBlock2;
    962     },
    963 
    964     _calculatePolynomial: function() {
    965       var i, j;
    966       var eccBlock = this._eccBlock;
    967       var polynomial = this._polynomial;
    968 
    969       polynomial[0] = 1;
    970 
    971       for (i = 0; i < eccBlock; i++) {
    972         polynomial[i + 1] = 1;
    973 
    974         for (j = i; j > 0; j--) {
    975           polynomial[j] = polynomial[j] ? polynomial[j - 1] ^
    976             Galois_1.EXPONENT[Frame._modN(Galois_1.LOG[polynomial[j]] + i)] : polynomial[j - 1];
    977         }
    978 
    979         polynomial[0] = Galois_1.EXPONENT[Frame._modN(Galois_1.LOG[polynomial[0]] + i)];
    980       }
    981 
    982       // Use logs for generator polynomial to save calculation step.
    983       for (i = 0; i <= eccBlock; i++) {
    984         polynomial[i] = Galois_1.LOG[polynomial[i]];
    985       }
    986     },
    987 
    988     _checkBadness: function() {
    989       var b, b1, h, x, y;
    990       var bad = 0;
    991       var badness = this._badness;
    992       var buffer = this.buffer;
    993       var width = this.width;
    994 
    995       // Blocks of same colour.
    996       for (y = 0; y < width - 1; y++) {
    997         for (x = 0; x < width - 1; x++) {
    998           // All foreground colour.
    999           if ((buffer[x + (width * y)] &&
   1000             buffer[x + 1 + (width * y)] &&
   1001             buffer[x + (width * (y + 1))] &&
   1002             buffer[x + 1 + (width * (y + 1))]) ||
   1003             // All background colour.
   1004             !(buffer[x + (width * y)] ||
   1005             buffer[x + 1 + (width * y)] ||
   1006             buffer[x + (width * (y + 1))] ||
   1007             buffer[x + 1 + (width * (y + 1))])) {
   1008             bad += Frame.N2;
   1009           }
   1010         }
   1011       }
   1012 
   1013       var bw = 0;
   1014 
   1015       // X runs.
   1016       for (y = 0; y < width; y++) {
   1017         h = 0;
   1018 
   1019         badness[0] = 0;
   1020 
   1021         for (b = 0, x = 0; x < width; x++) {
   1022           b1 = buffer[x + (width * y)];
   1023 
   1024           if (b === b1) {
   1025             badness[h]++;
   1026           } else {
   1027             badness[++h] = 1;
   1028           }
   1029 
   1030           b = b1;
   1031           bw += b ? 1 : -1;
   1032         }
   1033 
   1034         bad += this._getBadness(h);
   1035       }
   1036 
   1037       if (bw < 0) {
   1038         bw = -bw;
   1039       }
   1040 
   1041       var count = 0;
   1042       var big = bw;
   1043       big += big << 2;
   1044       big <<= 1;
   1045 
   1046       while (big > width * width) {
   1047         big -= width * width;
   1048         count++;
   1049       }
   1050 
   1051       bad += count * Frame.N4;
   1052 
   1053       // Y runs.
   1054       for (x = 0; x < width; x++) {
   1055         h = 0;
   1056 
   1057         badness[0] = 0;
   1058 
   1059         for (b = 0, y = 0; y < width; y++) {
   1060           b1 = buffer[x + (width * y)];
   1061 
   1062           if (b === b1) {
   1063             badness[h]++;
   1064           } else {
   1065             badness[++h] = 1;
   1066           }
   1067 
   1068           b = b1;
   1069         }
   1070 
   1071         bad += this._getBadness(h);
   1072       }
   1073 
   1074       return bad;
   1075     },
   1076 
   1077     _convertBitStream: function(length) {
   1078       var bit, i;
   1079       var ecc = this._ecc;
   1080       var version = this._version;
   1081 
   1082       // Convert string to bit stream. 8-bit data to QR-coded 8-bit data (numeric, alphanumeric, or kanji not supported).
   1083       for (i = 0; i < length; i++) {
   1084         ecc[i] = this._value.charCodeAt(i);
   1085       }
   1086 
   1087       var stringBuffer = this._stringBuffer = ecc.slice();
   1088       var maxLength = this._calculateMaxLength();
   1089 
   1090       if (length >= maxLength - 2) {
   1091         length = maxLength - 2;
   1092 
   1093         if (version > 9) {
   1094           length--;
   1095         }
   1096       }
   1097 
   1098       // Shift and re-pack to insert length prefix.
   1099       var index = length;
   1100 
   1101       if (version > 9) {
   1102         stringBuffer[index + 2] = 0;
   1103         stringBuffer[index + 3] = 0;
   1104 
   1105         while (index--) {
   1106           bit = stringBuffer[index];
   1107 
   1108           stringBuffer[index + 3] |= 255 & (bit << 4);
   1109           stringBuffer[index + 2] = bit >> 4;
   1110         }
   1111 
   1112         stringBuffer[2] |= 255 & (length << 4);
   1113         stringBuffer[1] = length >> 4;
   1114         stringBuffer[0] = 0x40 | (length >> 12);
   1115       } else {
   1116         stringBuffer[index + 1] = 0;
   1117         stringBuffer[index + 2] = 0;
   1118 
   1119         while (index--) {
   1120           bit = stringBuffer[index];
   1121 
   1122           stringBuffer[index + 2] |= 255 & (bit << 4);
   1123           stringBuffer[index + 1] = bit >> 4;
   1124         }
   1125 
   1126         stringBuffer[1] |= 255 & (length << 4);
   1127         stringBuffer[0] = 0x40 | (length >> 4);
   1128       }
   1129 
   1130       // Fill to end with pad pattern.
   1131       index = length + 3 - (version < 10);
   1132 
   1133       while (index < maxLength) {
   1134         stringBuffer[index++] = 0xec;
   1135         stringBuffer[index++] = 0x11;
   1136       }
   1137     },
   1138 
   1139     _getBadness: function(length) {
   1140       var i;
   1141       var badRuns = 0;
   1142       var badness = this._badness;
   1143 
   1144       for (i = 0; i <= length; i++) {
   1145         if (badness[i] >= 5) {
   1146           badRuns += Frame.N1 + badness[i] - 5;
   1147         }
   1148       }
   1149 
   1150       // FBFFFBF as in finder.
   1151       for (i = 3; i < length - 1; i += 2) {
   1152         if (badness[i - 2] === badness[i + 2] &&
   1153           badness[i + 2] === badness[i - 1] &&
   1154           badness[i - 1] === badness[i + 1] &&
   1155           badness[i - 1] * 3 === badness[i] &&
   1156           // Background around the foreground pattern? Not part of the specs.
   1157           (badness[i - 3] === 0 || i + 3 > length ||
   1158           badness[i - 3] * 3 >= badness[i] * 4 ||
   1159           badness[i + 3] * 3 >= badness[i] * 4)) {
   1160           badRuns += Frame.N3;
   1161         }
   1162       }
   1163 
   1164       return badRuns;
   1165     },
   1166 
   1167     _finish: function() {
   1168       // Save pre-mask copy of frame.
   1169       this._stringBuffer = this.buffer.slice();
   1170 
   1171       var currentMask, i;
   1172       var bit = 0;
   1173       var mask = 30000;
   1174 
   1175       /*
   1176        * Using for instead of while since in original Arduino code if an early mask was "good enough" it wouldn't try for
   1177        * a better one since they get more complex and take longer.
   1178        */
   1179       for (i = 0; i < 8; i++) {
   1180         // Returns foreground-background imbalance.
   1181         this._applyMask(i);
   1182 
   1183         currentMask = this._checkBadness();
   1184 
   1185         // Is current mask better than previous best?
   1186         if (currentMask < mask) {
   1187           mask = currentMask;
   1188           bit = i;
   1189         }
   1190 
   1191         // Don't increment "i" to a void redoing mask.
   1192         if (bit === 7) {
   1193           break;
   1194         }
   1195 
   1196         // Reset for next pass.
   1197         this.buffer = this._stringBuffer.slice();
   1198       }
   1199 
   1200       // Redo best mask as none were "good enough" (i.e. last wasn't bit).
   1201       if (bit !== i) {
   1202         this._applyMask(bit);
   1203       }
   1204 
   1205       // Add in final mask/ECC level bytes.
   1206       mask = ErrorCorrection_1.FINAL_FORMAT[bit + (this._level - 1 << 3)];
   1207 
   1208       var buffer = this.buffer;
   1209       var width = this.width;
   1210 
   1211       // Low byte.
   1212       for (i = 0; i < 8; i++, mask >>= 1) {
   1213         if (mask & 1) {
   1214           buffer[width - 1 - i + (width * 8)] = 1;
   1215 
   1216           if (i < 6) {
   1217             buffer[8 + (width * i)] = 1;
   1218           } else {
   1219             buffer[8 + (width * (i + 1))] = 1;
   1220           }
   1221         }
   1222       }
   1223 
   1224       // High byte.
   1225       for (i = 0; i < 7; i++, mask >>= 1) {
   1226         if (mask & 1) {
   1227           buffer[8 + (width * (width - 7 + i))] = 1;
   1228 
   1229           if (i) {
   1230             buffer[6 - i + (width * 8)] = 1;
   1231           } else {
   1232             buffer[7 + (width * 8)] = 1;
   1233           }
   1234         }
   1235       }
   1236     },
   1237 
   1238     _interleaveBlocks: function() {
   1239       var i, j;
   1240       var dataBlock = this._dataBlock;
   1241       var ecc = this._ecc;
   1242       var eccBlock = this._eccBlock;
   1243       var k = 0;
   1244       var maxLength = this._calculateMaxLength();
   1245       var neccBlock1 = this._neccBlock1;
   1246       var neccBlock2 = this._neccBlock2;
   1247       var stringBuffer = this._stringBuffer;
   1248 
   1249       for (i = 0; i < dataBlock; i++) {
   1250         for (j = 0; j < neccBlock1; j++) {
   1251           ecc[k++] = stringBuffer[i + (j * dataBlock)];
   1252         }
   1253 
   1254         for (j = 0; j < neccBlock2; j++) {
   1255           ecc[k++] = stringBuffer[(neccBlock1 * dataBlock) + i + (j * (dataBlock + 1))];
   1256         }
   1257       }
   1258 
   1259       for (j = 0; j < neccBlock2; j++) {
   1260         ecc[k++] = stringBuffer[(neccBlock1 * dataBlock) + i + (j * (dataBlock + 1))];
   1261       }
   1262 
   1263       for (i = 0; i < eccBlock; i++) {
   1264         for (j = 0; j < neccBlock1 + neccBlock2; j++) {
   1265           ecc[k++] = stringBuffer[maxLength + i + (j * eccBlock)];
   1266         }
   1267       }
   1268 
   1269       this._stringBuffer = ecc;
   1270     },
   1271 
   1272     _insertAlignments: function() {
   1273       var i, x, y;
   1274       var version = this._version;
   1275       var width = this.width;
   1276 
   1277       if (version > 1) {
   1278         i = Alignment_1.BLOCK[version];
   1279         y = width - 7;
   1280 
   1281         for (;;) {
   1282           x = width - 7;
   1283 
   1284           while (x > i - 3) {
   1285             this._addAlignment(x, y);
   1286 
   1287             if (x < i) {
   1288               break;
   1289             }
   1290 
   1291             x -= i;
   1292           }
   1293 
   1294           if (y <= i + 9) {
   1295             break;
   1296           }
   1297 
   1298           y -= i;
   1299 
   1300           this._addAlignment(6, y);
   1301           this._addAlignment(y, 6);
   1302         }
   1303       }
   1304     },
   1305 
   1306     _insertFinders: function() {
   1307       var i, j, x, y;
   1308       var buffer = this.buffer;
   1309       var width = this.width;
   1310 
   1311       for (i = 0; i < 3; i++) {
   1312         j = 0;
   1313         y = 0;
   1314 
   1315         if (i === 1) {
   1316           j = width - 7;
   1317         }
   1318         if (i === 2) {
   1319           y = width - 7;
   1320         }
   1321 
   1322         buffer[y + 3 + (width * (j + 3))] = 1;
   1323 
   1324         for (x = 0; x < 6; x++) {
   1325           buffer[y + x + (width * j)] = 1;
   1326           buffer[y + (width * (j + x + 1))] = 1;
   1327           buffer[y + 6 + (width * (j + x))] = 1;
   1328           buffer[y + x + 1 + (width * (j + 6))] = 1;
   1329         }
   1330 
   1331         for (x = 1; x < 5; x++) {
   1332           this._setMask(y + x, j + 1);
   1333           this._setMask(y + 1, j + x + 1);
   1334           this._setMask(y + 5, j + x);
   1335           this._setMask(y + x + 1, j + 5);
   1336         }
   1337 
   1338         for (x = 2; x < 4; x++) {
   1339           buffer[y + x + (width * (j + 2))] = 1;
   1340           buffer[y + 2 + (width * (j + x + 1))] = 1;
   1341           buffer[y + 4 + (width * (j + x))] = 1;
   1342           buffer[y + x + 1 + (width * (j + 4))] = 1;
   1343         }
   1344       }
   1345     },
   1346 
   1347     _insertTimingGap: function() {
   1348       var x, y;
   1349       var width = this.width;
   1350 
   1351       for (y = 0; y < 7; y++) {
   1352         this._setMask(7, y);
   1353         this._setMask(width - 8, y);
   1354         this._setMask(7, y + width - 7);
   1355       }
   1356 
   1357       for (x = 0; x < 8; x++) {
   1358         this._setMask(x, 7);
   1359         this._setMask(x + width - 8, 7);
   1360         this._setMask(x, width - 8);
   1361       }
   1362     },
   1363 
   1364     _insertTimingRowAndColumn: function() {
   1365       var x;
   1366       var buffer = this.buffer;
   1367       var width = this.width;
   1368 
   1369       for (x = 0; x < width - 14; x++) {
   1370         if (x & 1) {
   1371           this._setMask(8 + x, 6);
   1372           this._setMask(6, 8 + x);
   1373         } else {
   1374           buffer[8 + x + (width * 6)] = 1;
   1375           buffer[6 + (width * (8 + x))] = 1;
   1376         }
   1377       }
   1378     },
   1379 
   1380     _insertVersion: function() {
   1381       var i, j, x, y;
   1382       var buffer = this.buffer;
   1383       var version = this._version;
   1384       var width = this.width;
   1385 
   1386       if (version > 6) {
   1387         i = Version_1.BLOCK[version - 7];
   1388         j = 17;
   1389 
   1390         for (x = 0; x < 6; x++) {
   1391           for (y = 0; y < 3; y++, j--) {
   1392             if (1 & (j > 11 ? version >> j - 12 : i >> j)) {
   1393               buffer[5 - x + (width * (2 - y + width - 11))] = 1;
   1394               buffer[2 - y + width - 11 + (width * (5 - x))] = 1;
   1395             } else {
   1396               this._setMask(5 - x, 2 - y + width - 11);
   1397               this._setMask(2 - y + width - 11, 5 - x);
   1398             }
   1399           }
   1400         }
   1401       }
   1402     },
   1403 
   1404     _isMasked: function(x, y) {
   1405       var bit = Frame._getMaskBit(x, y);
   1406 
   1407       return this._mask[bit] === 1;
   1408     },
   1409 
   1410     _pack: function() {
   1411       var bit, i, j;
   1412       var k = 1;
   1413       var v = 1;
   1414       var width = this.width;
   1415       var x = width - 1;
   1416       var y = width - 1;
   1417 
   1418       // Interleaved data and ECC codes.
   1419       var length = ((this._dataBlock + this._eccBlock) * (this._neccBlock1 + this._neccBlock2)) + this._neccBlock2;
   1420 
   1421       for (i = 0; i < length; i++) {
   1422         bit = this._stringBuffer[i];
   1423 
   1424         for (j = 0; j < 8; j++, bit <<= 1) {
   1425           if (0x80 & bit) {
   1426             this.buffer[x + (width * y)] = 1;
   1427           }
   1428 
   1429           // Find next fill position.
   1430           do {
   1431             if (v) {
   1432               x--;
   1433             } else {
   1434               x++;
   1435 
   1436               if (k) {
   1437                 if (y !== 0) {
   1438                   y--;
   1439                 } else {
   1440                   x -= 2;
   1441                   k = !k;
   1442 
   1443                   if (x === 6) {
   1444                     x--;
   1445                     y = 9;
   1446                   }
   1447                 }
   1448               } else if (y !== width - 1) {
   1449                 y++;
   1450               } else {
   1451                 x -= 2;
   1452                 k = !k;
   1453 
   1454                 if (x === 6) {
   1455                   x--;
   1456                   y -= 8;
   1457                 }
   1458               }
   1459             }
   1460 
   1461             v = !v;
   1462           } while (this._isMasked(x, y));
   1463         }
   1464       }
   1465     },
   1466 
   1467     _reverseMask: function() {
   1468       var x, y;
   1469       var width = this.width;
   1470 
   1471       for (x = 0; x < 9; x++) {
   1472         this._setMask(x, 8);
   1473       }
   1474 
   1475       for (x = 0; x < 8; x++) {
   1476         this._setMask(x + width - 8, 8);
   1477         this._setMask(8, x);
   1478       }
   1479 
   1480       for (y = 0; y < 7; y++) {
   1481         this._setMask(8, y + width - 7);
   1482       }
   1483     },
   1484 
   1485     _setMask: function(x, y) {
   1486       var bit = Frame._getMaskBit(x, y);
   1487 
   1488       this._mask[bit] = 1;
   1489     },
   1490 
   1491     _syncMask: function() {
   1492       var x, y;
   1493       var width = this.width;
   1494 
   1495       for (y = 0; y < width; y++) {
   1496         for (x = 0; x <= y; x++) {
   1497           if (this.buffer[x + (width * y)]) {
   1498             this._setMask(x, y);
   1499           }
   1500         }
   1501       }
   1502     }
   1503 
   1504   }, {
   1505 
   1506     _createArray: function(length) {
   1507       var i;
   1508       var array = [];
   1509 
   1510       for (i = 0; i < length; i++) {
   1511         array[i] = 0;
   1512       }
   1513 
   1514       return array;
   1515     },
   1516 
   1517     _getMaskBit: function(x, y) {
   1518       var bit;
   1519 
   1520       if (x > y) {
   1521         bit = x;
   1522         x = y;
   1523         y = bit;
   1524       }
   1525 
   1526       bit = y;
   1527       bit += y * y;
   1528       bit >>= 1;
   1529       bit += x;
   1530 
   1531       return bit;
   1532     },
   1533 
   1534     _modN: function(x) {
   1535       while (x >= 255) {
   1536         x -= 255;
   1537         x = (x >> 8) + (x & 255);
   1538       }
   1539 
   1540       return x;
   1541     },
   1542 
   1543     // *Badness* coefficients.
   1544     N1: 3,
   1545     N2: 3,
   1546     N3: 40,
   1547     N4: 10
   1548 
   1549   });
   1550 
   1551   var Frame_1 = Frame;
   1552 
   1553   /**
   1554    * The options used by {@link Frame}.
   1555    *
   1556    * @typedef {Object} Frame~Options
   1557    * @property {string} level - The ECC level to be used.
   1558    * @property {string} value - The value to be encoded.
   1559    */
   1560 
   1561   /**
   1562    * An implementation of {@link Renderer} for working with <code>img</code> elements.
   1563    *
   1564    * This depends on {@link CanvasRenderer} being executed first as this implementation simply applies the data URL from
   1565    * the rendered <code>canvas</code> element as the <code>src</code> for the <code>img</code> element being rendered.
   1566    *
   1567    * @public
   1568    * @class
   1569    * @extends Renderer
   1570    */
   1571   var ImageRenderer = Renderer_1.extend({
   1572 
   1573     /**
   1574      * @override
   1575      */
   1576     draw: function() {
   1577       this.element.src = this.qrious.toDataURL();
   1578     },
   1579 
   1580     /**
   1581      * @override
   1582      */
   1583     reset: function() {
   1584       this.element.src = '';
   1585     },
   1586 
   1587     /**
   1588      * @override
   1589      */
   1590     resize: function() {
   1591       var element = this.element;
   1592 
   1593       element.width = element.height = this.qrious.size;
   1594     }
   1595 
   1596   });
   1597 
   1598   var ImageRenderer_1 = ImageRenderer;
   1599 
   1600   /**
   1601    * Defines an available option while also configuring how values are applied to the target object.
   1602    *
   1603    * Optionally, a default value can be specified as well a value transformer for greater control over how the option
   1604    * value is applied.
   1605    *
   1606    * If no value transformer is specified, then any specified option will be applied directly. All values are maintained
   1607    * on the target object itself as a field using the option name prefixed with a single underscore.
   1608    *
   1609    * When an option is specified as modifiable, the {@link OptionManager} will be required to include a setter for the
   1610    * property that is defined on the target object that uses the option name.
   1611    *
   1612    * @param {string} name - the name to be used
   1613    * @param {boolean} [modifiable] - <code>true</code> if the property defined on target objects should include a setter;
   1614    * otherwise <code>false</code>
   1615    * @param {*} [defaultValue] - the default value to be used
   1616    * @param {Option~ValueTransformer} [valueTransformer] - the value transformer to be used
   1617    * @public
   1618    * @class
   1619    * @extends Nevis
   1620    */
   1621   var Option = lite.extend(function(name, modifiable, defaultValue, valueTransformer) {
   1622     /**
   1623      * The name for this {@link Option}.
   1624      *
   1625      * @public
   1626      * @type {string}
   1627      * @memberof Option#
   1628      */
   1629     this.name = name;
   1630 
   1631     /**
   1632      * Whether a setter should be included on the property defined on target objects for this {@link Option}.
   1633      *
   1634      * @public
   1635      * @type {boolean}
   1636      * @memberof Option#
   1637      */
   1638     this.modifiable = Boolean(modifiable);
   1639 
   1640     /**
   1641      * The default value for this {@link Option}.
   1642      *
   1643      * @public
   1644      * @type {*}
   1645      * @memberof Option#
   1646      */
   1647     this.defaultValue = defaultValue;
   1648 
   1649     this._valueTransformer = valueTransformer;
   1650   }, {
   1651 
   1652     /**
   1653      * Transforms the specified <code>value</code> so that it can be applied for this {@link Option}.
   1654      *
   1655      * If a value transformer has been specified for this {@link Option}, it will be called upon to transform
   1656      * <code>value</code>. Otherwise, <code>value</code> will be returned directly.
   1657      *
   1658      * @param {*} value - the value to be transformed
   1659      * @return {*} The transformed value or <code>value</code> if no value transformer is specified.
   1660      * @public
   1661      * @memberof Option#
   1662      */
   1663     transform: function(value) {
   1664       var transformer = this._valueTransformer;
   1665       if (typeof transformer === 'function') {
   1666         return transformer(value, this);
   1667       }
   1668 
   1669       return value;
   1670     }
   1671 
   1672   });
   1673 
   1674   var Option_1 = Option;
   1675 
   1676   /**
   1677    * Returns a transformed value for the specified <code>value</code> to be applied for the <code>option</code> provided.
   1678    *
   1679    * @callback Option~ValueTransformer
   1680    * @param {*} value - the value to be transformed
   1681    * @param {Option} option - the {@link Option} for which <code>value</code> is being transformed
   1682    * @return {*} The transform value.
   1683    */
   1684 
   1685   /**
   1686    * Contains utility methods that are useful throughout the library.
   1687    *
   1688    * @public
   1689    * @class
   1690    * @extends Nevis
   1691    */
   1692   var Utilities = lite.extend(null, {
   1693 
   1694     /**
   1695      * Returns the absolute value of a given number.
   1696      *
   1697      * This method is simply a convenient shorthand for <code>Math.abs</code> while ensuring that nulls are returned as
   1698      * <code>null</code> instead of zero.
   1699      *
   1700      * @param {number} value - the number whose absolute value is to be returned
   1701      * @return {number} The absolute value of <code>value</code> or <code>null</code> if <code>value</code> is
   1702      * <code>null</code>.
   1703      * @public
   1704      * @static
   1705      * @memberof Utilities
   1706      */
   1707     abs: function(value) {
   1708       return value != null ? Math.abs(value) : null;
   1709     },
   1710 
   1711     /**
   1712      * Returns whether the specified <code>object</code> has a property with the specified <code>name</code> as an own
   1713      * (not inherited) property.
   1714      *
   1715      * @param {Object} object - the object on which the property is to be checked
   1716      * @param {string} name - the name of the property to be checked
   1717      * @return {boolean} <code>true</code> if <code>object</code> has an own property with <code>name</code>.
   1718      * @public
   1719      * @static
   1720      * @memberof Utilities
   1721      */
   1722     hasOwn: function(object, name) {
   1723       return Object.prototype.hasOwnProperty.call(object, name);
   1724     },
   1725 
   1726     /**
   1727      * A non-operation method that does absolutely nothing.
   1728      *
   1729      * @return {void}
   1730      * @public
   1731      * @static
   1732      * @memberof Utilities
   1733      */
   1734     noop: function() {},
   1735 
   1736     /**
   1737      * Transforms the specified <code>string</code> to upper case while remaining null-safe.
   1738      *
   1739      * @param {string} string - the string to be transformed to upper case
   1740      * @return {string} <code>string</code> transformed to upper case if <code>string</code> is not <code>null</code>.
   1741      * @public
   1742      * @static
   1743      * @memberof Utilities
   1744      */
   1745     toUpperCase: function(string) {
   1746       return string != null ? string.toUpperCase() : null;
   1747     }
   1748 
   1749   });
   1750 
   1751   var Utilities_1 = Utilities;
   1752 
   1753   /**
   1754    * Manages multiple {@link Option} instances that are intended to be used by multiple implementations.
   1755    *
   1756    * Although the option definitions are shared between targets, the values are maintained on the targets themselves.
   1757    *
   1758    * @param {Option[]} options - the options to be used
   1759    * @public
   1760    * @class
   1761    * @extends Nevis
   1762    */
   1763   var OptionManager = lite.extend(function(options) {
   1764     /**
   1765      * The available options for this {@link OptionManager}.
   1766      *
   1767      * @public
   1768      * @type {Object.<string, Option>}
   1769      * @memberof OptionManager#
   1770      */
   1771     this.options = {};
   1772 
   1773     options.forEach(function(option) {
   1774       this.options[option.name] = option;
   1775     }, this);
   1776   }, {
   1777 
   1778     /**
   1779      * Returns whether an option with the specified <code>name</code> is available.
   1780      *
   1781      * @param {string} name - the name of the {@link Option} whose existence is to be checked
   1782      * @return {boolean} <code>true</code> if an {@link Option} exists with <code>name</code>; otherwise
   1783      * <code>false</code>.
   1784      * @public
   1785      * @memberof OptionManager#
   1786      */
   1787     exists: function(name) {
   1788       return this.options[name] != null;
   1789     },
   1790 
   1791     /**
   1792      * Returns the value of the option with the specified <code>name</code> on the <code>target</code> object provided.
   1793      *
   1794      * @param {string} name - the name of the {@link Option} whose value on <code>target</code> is to be returned
   1795      * @param {Object} target - the object from which the value of the named {@link Option} is to be returned
   1796      * @return {*} The value of the {@link Option} with <code>name</code> on <code>target</code>.
   1797      * @public
   1798      * @memberof OptionManager#
   1799      */
   1800     get: function(name, target) {
   1801       return OptionManager._get(this.options[name], target);
   1802     },
   1803 
   1804     /**
   1805      * Returns a copy of all of the available options on the <code>target</code> object provided.
   1806      *
   1807      * @param {Object} target - the object from which the option name/value pairs are to be returned
   1808      * @return {Object.<string, *>} A hash containing the name/value pairs of all options on <code>target</code>.
   1809      * @public
   1810      * @memberof OptionManager#
   1811      */
   1812     getAll: function(target) {
   1813       var name;
   1814       var options = this.options;
   1815       var result = {};
   1816 
   1817       for (name in options) {
   1818         if (Utilities_1.hasOwn(options, name)) {
   1819           result[name] = OptionManager._get(options[name], target);
   1820         }
   1821       }
   1822 
   1823       return result;
   1824     },
   1825 
   1826     /**
   1827      * Initializes the available options for the <code>target</code> object provided and then applies the initial values
   1828      * within the speciifed <code>options</code>.
   1829      *
   1830      * This method will throw an error if any of the names within <code>options</code> does not match an available option.
   1831      *
   1832      * This involves setting the default values and defining properties for all of the available options on
   1833      * <code>target</code> before finally calling {@link OptionMananger#setAll} with <code>options</code> and
   1834      * <code>target</code>. Any options that are configured to be modifiable will have a setter included in their defined
   1835      * property that will allow its corresponding value to be modified.
   1836      *
   1837      * If a change handler is specified, it will be called whenever the value changes on <code>target</code> for a
   1838      * modifiable option, but only when done so via the defined property's setter.
   1839      *
   1840      * @param {Object.<string, *>} options - the name/value pairs of the initial options to be set
   1841      * @param {Object} target - the object on which the options are to be initialized
   1842      * @param {Function} [changeHandler] - the function to be called whenever the value of an modifiable option changes on
   1843      * <code>target</code>
   1844      * @return {void}
   1845      * @throws {Error} If <code>options</code> contains an invalid option name.
   1846      * @public
   1847      * @memberof OptionManager#
   1848      */
   1849     init: function(options, target, changeHandler) {
   1850       if (typeof changeHandler !== 'function') {
   1851         changeHandler = Utilities_1.noop;
   1852       }
   1853 
   1854       var name, option;
   1855 
   1856       for (name in this.options) {
   1857         if (Utilities_1.hasOwn(this.options, name)) {
   1858           option = this.options[name];
   1859 
   1860           OptionManager._set(option, option.defaultValue, target);
   1861           OptionManager._createAccessor(option, target, changeHandler);
   1862         }
   1863       }
   1864 
   1865       this._setAll(options, target, true);
   1866     },
   1867 
   1868     /**
   1869      * Sets the value of the option with the specified <code>name</code> on the <code>target</code> object provided to
   1870      * <code>value</code>.
   1871      *
   1872      * This method will throw an error if <code>name</code> does not match an available option or matches an option that
   1873      * cannot be modified.
   1874      *
   1875      * If <code>value</code> is <code>null</code> and the {@link Option} has a default value configured, then that default
   1876      * value will be used instead. If the {@link Option} also has a value transformer configured, it will be used to
   1877      * transform whichever value was determined to be used.
   1878      *
   1879      * This method returns whether the value of the underlying field on <code>target</code> was changed as a result.
   1880      *
   1881      * @param {string} name - the name of the {@link Option} whose value is to be set
   1882      * @param {*} value - the value to be set for the named {@link Option} on <code>target</code>
   1883      * @param {Object} target - the object on which <code>value</code> is to be set for the named {@link Option}
   1884      * @return {boolean} <code>true</code> if the underlying field on <code>target</code> was changed; otherwise
   1885      * <code>false</code>.
   1886      * @throws {Error} If <code>name</code> is invalid or is for an option that cannot be modified.
   1887      * @public
   1888      * @memberof OptionManager#
   1889      */
   1890     set: function(name, value, target) {
   1891       return this._set(name, value, target);
   1892     },
   1893 
   1894     /**
   1895      * Sets all of the specified <code>options</code> on the <code>target</code> object provided to their corresponding
   1896      * values.
   1897      *
   1898      * This method will throw an error if any of the names within <code>options</code> does not match an available option
   1899      * or matches an option that cannot be modified.
   1900      *
   1901      * If any value within <code>options</code> is <code>null</code> and the corresponding {@link Option} has a default
   1902      * value configured, then that default value will be used instead. If an {@link Option} also has a value transformer
   1903      * configured, it will be used to transform whichever value was determined to be used.
   1904      *
   1905      * This method returns whether the value for any of the underlying fields on <code>target</code> were changed as a
   1906      * result.
   1907      *
   1908      * @param {Object.<string, *>} options - the name/value pairs of options to be set
   1909      * @param {Object} target - the object on which the options are to be set
   1910      * @return {boolean} <code>true</code> if any of the underlying fields on <code>target</code> were changed; otherwise
   1911      * <code>false</code>.
   1912      * @throws {Error} If <code>options</code> contains an invalid option name or an option that cannot be modiifed.
   1913      * @public
   1914      * @memberof OptionManager#
   1915      */
   1916     setAll: function(options, target) {
   1917       return this._setAll(options, target);
   1918     },
   1919 
   1920     _set: function(name, value, target, allowUnmodifiable) {
   1921       var option = this.options[name];
   1922       if (!option) {
   1923         throw new Error('Invalid option: ' + name);
   1924       }
   1925       if (!option.modifiable && !allowUnmodifiable) {
   1926         throw new Error('Option cannot be modified: ' + name);
   1927       }
   1928 
   1929       return OptionManager._set(option, value, target);
   1930     },
   1931 
   1932     _setAll: function(options, target, allowUnmodifiable) {
   1933       if (!options) {
   1934         return false;
   1935       }
   1936 
   1937       var name;
   1938       var changed = false;
   1939 
   1940       for (name in options) {
   1941         if (Utilities_1.hasOwn(options, name) && this._set(name, options[name], target, allowUnmodifiable)) {
   1942           changed = true;
   1943         }
   1944       }
   1945 
   1946       return changed;
   1947     }
   1948 
   1949   }, {
   1950 
   1951     _createAccessor: function(option, target, changeHandler) {
   1952       var descriptor = {
   1953         get: function() {
   1954           return OptionManager._get(option, target);
   1955         }
   1956       };
   1957 
   1958       if (option.modifiable) {
   1959         descriptor.set = function(value) {
   1960           if (OptionManager._set(option, value, target)) {
   1961             changeHandler(value, option);
   1962           }
   1963         };
   1964       }
   1965 
   1966       Object.defineProperty(target, option.name, descriptor);
   1967     },
   1968 
   1969     _get: function(option, target) {
   1970       return target['_' + option.name];
   1971     },
   1972 
   1973     _set: function(option, value, target) {
   1974       var fieldName = '_' + option.name;
   1975       var oldValue = target[fieldName];
   1976       var newValue = option.transform(value != null ? value : option.defaultValue);
   1977 
   1978       target[fieldName] = newValue;
   1979 
   1980       return newValue !== oldValue;
   1981     }
   1982 
   1983   });
   1984 
   1985   var OptionManager_1 = OptionManager;
   1986 
   1987   /**
   1988    * Called whenever the value of a modifiable {@link Option} is changed on a target object via the defined property's
   1989    * setter.
   1990    *
   1991    * @callback OptionManager~ChangeHandler
   1992    * @param {*} value - the new value for <code>option</code> on the target object
   1993    * @param {Option} option - the modifable {@link Option} whose value has changed on the target object.
   1994    * @return {void}
   1995    */
   1996 
   1997   /**
   1998    * A basic manager for {@link Service} implementations that are mapped to simple names.
   1999    *
   2000    * @public
   2001    * @class
   2002    * @extends Nevis
   2003    */
   2004   var ServiceManager = lite.extend(function() {
   2005     this._services = {};
   2006   }, {
   2007 
   2008     /**
   2009      * Returns the {@link Service} being managed with the specified <code>name</code>.
   2010      *
   2011      * @param {string} name - the name of the {@link Service} to be returned
   2012      * @return {Service} The {@link Service} is being managed with <code>name</code>.
   2013      * @throws {Error} If no {@link Service} is being managed with <code>name</code>.
   2014      * @public
   2015      * @memberof ServiceManager#
   2016      */
   2017     getService: function(name) {
   2018       var service = this._services[name];
   2019       if (!service) {
   2020         throw new Error('Service is not being managed with name: ' + name);
   2021       }
   2022 
   2023       return service;
   2024     },
   2025 
   2026     /**
   2027      * Sets the {@link Service} implementation to be managed for the specified <code>name</code> to the
   2028      * <code>service</code> provided.
   2029      *
   2030      * @param {string} name - the name of the {@link Service} to be managed with <code>name</code>
   2031      * @param {Service} service - the {@link Service} implementation to be managed
   2032      * @return {void}
   2033      * @throws {Error} If a {@link Service} is already being managed with the same <code>name</code>.
   2034      * @public
   2035      * @memberof ServiceManager#
   2036      */
   2037     setService: function(name, service) {
   2038       if (this._services[name]) {
   2039         throw new Error('Service is already managed with name: ' + name);
   2040       }
   2041 
   2042       if (service) {
   2043         this._services[name] = service;
   2044       }
   2045     }
   2046 
   2047   });
   2048 
   2049   var ServiceManager_1 = ServiceManager;
   2050 
   2051   var optionManager = new OptionManager_1([
   2052     new Option_1('background', true, 'white'),
   2053     new Option_1('backgroundAlpha', true, 1, Utilities_1.abs),
   2054     new Option_1('element'),
   2055     new Option_1('foreground', true, 'black'),
   2056     new Option_1('foregroundAlpha', true, 1, Utilities_1.abs),
   2057     new Option_1('level', true, 'L', Utilities_1.toUpperCase),
   2058     new Option_1('mime', true, 'image/png'),
   2059     new Option_1('padding', true, null, Utilities_1.abs),
   2060     new Option_1('size', true, 100, Utilities_1.abs),
   2061     new Option_1('value', true, '')
   2062   ]);
   2063   var serviceManager = new ServiceManager_1();
   2064 
   2065   /**
   2066    * Enables configuration of a QR code generator which uses HTML5 <code>canvas</code> for rendering.
   2067    *
   2068    * @param {QRious~Options} [options] - the options to be used
   2069    * @throws {Error} If any <code>options</code> are invalid.
   2070    * @public
   2071    * @class
   2072    * @extends Nevis
   2073    */
   2074   var QRious = lite.extend(function(options) {
   2075     optionManager.init(options, this, this.update.bind(this));
   2076 
   2077     var element = optionManager.get('element', this);
   2078     var elementService = serviceManager.getService('element');
   2079     var canvas = element && elementService.isCanvas(element) ? element : elementService.createCanvas();
   2080     var image = element && elementService.isImage(element) ? element : elementService.createImage();
   2081 
   2082     this._canvasRenderer = new CanvasRenderer_1(this, canvas, true);
   2083     this._imageRenderer = new ImageRenderer_1(this, image, image === element);
   2084 
   2085     this.update();
   2086   }, {
   2087 
   2088     /**
   2089      * Returns all of the options configured for this {@link QRious}.
   2090      *
   2091      * Any changes made to the returned object will not be reflected in the options themselves or their corresponding
   2092      * underlying fields.
   2093      *
   2094      * @return {Object.<string, *>} A copy of the applied options.
   2095      * @public
   2096      * @memberof QRious#
   2097      */
   2098     get: function() {
   2099       return optionManager.getAll(this);
   2100     },
   2101 
   2102     /**
   2103      * Sets all of the specified <code>options</code> and automatically updates this {@link QRious} if any of the
   2104      * underlying fields are changed as a result.
   2105      *
   2106      * This is the preferred method for updating multiple options at one time to avoid unnecessary updates between
   2107      * changes.
   2108      *
   2109      * @param {QRious~Options} options - the options to be set
   2110      * @return {void}
   2111      * @throws {Error} If any <code>options</code> are invalid or cannot be modified.
   2112      * @public
   2113      * @memberof QRious#
   2114      */
   2115     set: function(options) {
   2116       if (optionManager.setAll(options, this)) {
   2117         this.update();
   2118       }
   2119     },
   2120 
   2121     /**
   2122      * Returns the image data URI for the generated QR code using the <code>mime</code> provided.
   2123      *
   2124      * @param {string} [mime] - the MIME type for the image
   2125      * @return {string} The image data URI for the QR code.
   2126      * @public
   2127      * @memberof QRious#
   2128      */
   2129     toDataURL: function(mime) {
   2130       return this.canvas.toDataURL(mime || this.mime);
   2131     },
   2132 
   2133     /**
   2134      * Updates this {@link QRious} by generating a new {@link Frame} and re-rendering the QR code.
   2135      *
   2136      * @return {void}
   2137      * @protected
   2138      * @memberof QRious#
   2139      */
   2140     update: function() {
   2141       var frame = new Frame_1({
   2142         level: this.level,
   2143         value: this.value
   2144       });
   2145 
   2146       this._canvasRenderer.render(frame);
   2147       this._imageRenderer.render(frame);
   2148     }
   2149 
   2150   }, {
   2151 
   2152     /**
   2153      * Configures the <code>service</code> provided to be used by all {@link QRious} instances.
   2154      *
   2155      * @param {Service} service - the {@link Service} to be configured
   2156      * @return {void}
   2157      * @throws {Error} If a {@link Service} has already been configured with the same name.
   2158      * @public
   2159      * @static
   2160      * @memberof QRious
   2161      */
   2162     use: function(service) {
   2163       serviceManager.setService(service.getName(), service);
   2164     }
   2165 
   2166   });
   2167 
   2168   Object.defineProperties(QRious.prototype, {
   2169 
   2170     canvas: {
   2171       /**
   2172        * Returns the <code>canvas</code> element being used to render the QR code for this {@link QRious}.
   2173        *
   2174        * @return {*} The <code>canvas</code> element.
   2175        * @public
   2176        * @memberof QRious#
   2177        * @alias canvas
   2178        */
   2179       get: function() {
   2180         return this._canvasRenderer.getElement();
   2181       }
   2182     },
   2183 
   2184     image: {
   2185       /**
   2186        * Returns the <code>img</code> element being used to render the QR code for this {@link QRious}.
   2187        *
   2188        * @return {*} The <code>img</code> element.
   2189        * @public
   2190        * @memberof QRious#
   2191        * @alias image
   2192        */
   2193       get: function() {
   2194         return this._imageRenderer.getElement();
   2195       }
   2196     }
   2197 
   2198   });
   2199 
   2200   var QRious_1$2 = QRious;
   2201 
   2202   /**
   2203    * The options used by {@link QRious}.
   2204    *
   2205    * @typedef {Object} QRious~Options
   2206    * @property {string} [background="white"] - The background color to be applied to the QR code.
   2207    * @property {number} [backgroundAlpha=1] - The background alpha to be applied to the QR code.
   2208    * @property {*} [element] - The element to be used to render the QR code which may either be an <code>canvas</code> or
   2209    * <code>img</code>. The element(s) will be created if needed.
   2210    * @property {string} [foreground="black"] - The foreground color to be applied to the QR code.
   2211    * @property {number} [foregroundAlpha=1] - The foreground alpha to be applied to the QR code.
   2212    * @property {string} [level="L"] - The error correction level to be applied to the QR code.
   2213    * @property {string} [mime="image/png"] - The MIME type to be used to render the image for the QR code.
   2214    * @property {number} [padding] - The padding for the QR code in pixels.
   2215    * @property {number} [size=100] - The size of the QR code in pixels.
   2216    * @property {string} [value=""] - The value to be encoded within the QR code.
   2217    */
   2218 
   2219   var index = QRious_1$2;
   2220 
   2221   /**
   2222    * Defines a service contract that must be met by all implementations.
   2223    *
   2224    * @public
   2225    * @class
   2226    * @extends Nevis
   2227    */
   2228   var Service = lite.extend({
   2229 
   2230     /**
   2231      * Returns the name of this {@link Service}.
   2232      *
   2233      * @return {string} The service name.
   2234      * @public
   2235      * @abstract
   2236      * @memberof Service#
   2237      */
   2238     getName: function() {}
   2239 
   2240   });
   2241 
   2242   var Service_1 = Service;
   2243 
   2244   /**
   2245    * A service for working with elements.
   2246    *
   2247    * @public
   2248    * @class
   2249    * @extends Service
   2250    */
   2251   var ElementService = Service_1.extend({
   2252 
   2253     /**
   2254      * Creates an instance of a canvas element.
   2255      *
   2256      * Implementations of {@link ElementService} <b>must</b> override this method with their own specific logic.
   2257      *
   2258      * @return {*} The newly created canvas element.
   2259      * @public
   2260      * @abstract
   2261      * @memberof ElementService#
   2262      */
   2263     createCanvas: function() {},
   2264 
   2265     /**
   2266      * Creates an instance of a image element.
   2267      *
   2268      * Implementations of {@link ElementService} <b>must</b> override this method with their own specific logic.
   2269      *
   2270      * @return {*} The newly created image element.
   2271      * @public
   2272      * @abstract
   2273      * @memberof ElementService#
   2274      */
   2275     createImage: function() {},
   2276 
   2277     /**
   2278      * @override
   2279      */
   2280     getName: function() {
   2281       return 'element';
   2282     },
   2283 
   2284     /**
   2285      * Returns whether the specified <code>element</code> is a canvas.
   2286      *
   2287      * Implementations of {@link ElementService} <b>must</b> override this method with their own specific logic.
   2288      *
   2289      * @param {*} element - the element to be checked
   2290      * @return {boolean} <code>true</code> if <code>element</code> is a canvas; otherwise <code>false</code>.
   2291      * @public
   2292      * @abstract
   2293      * @memberof ElementService#
   2294      */
   2295     isCanvas: function(element) {},
   2296 
   2297     /**
   2298      * Returns whether the specified <code>element</code> is an image.
   2299      *
   2300      * Implementations of {@link ElementService} <b>must</b> override this method with their own specific logic.
   2301      *
   2302      * @param {*} element - the element to be checked
   2303      * @return {boolean} <code>true</code> if <code>element</code> is an image; otherwise <code>false</code>.
   2304      * @public
   2305      * @abstract
   2306      * @memberof ElementService#
   2307      */
   2308     isImage: function(element) {}
   2309 
   2310   });
   2311 
   2312   var ElementService_1 = ElementService;
   2313 
   2314   /**
   2315    * An implementation of {@link ElementService} intended for use within a browser environment.
   2316    *
   2317    * @public
   2318    * @class
   2319    * @extends ElementService
   2320    */
   2321   var BrowserElementService = ElementService_1.extend({
   2322 
   2323     /**
   2324      * @override
   2325      */
   2326     createCanvas: function() {
   2327       return document.createElement('canvas');
   2328     },
   2329 
   2330     /**
   2331      * @override
   2332      */
   2333     createImage: function() {
   2334       return document.createElement('img');
   2335     },
   2336 
   2337     /**
   2338      * @override
   2339      */
   2340     isCanvas: function(element) {
   2341       return element instanceof HTMLCanvasElement;
   2342     },
   2343 
   2344     /**
   2345      * @override
   2346      */
   2347     isImage: function(element) {
   2348       return element instanceof HTMLImageElement;
   2349     }
   2350 
   2351   });
   2352 
   2353   var BrowserElementService_1 = BrowserElementService;
   2354 
   2355   index.use(new BrowserElementService_1());
   2356 
   2357   var QRious_1 = index;
   2358 
   2359   return QRious_1;
   2360 
   2361 })));
   2362 
   2363 //# sourceMappingURL=qrious.js.map