diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..e43b0f9
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+.DS_Store
diff --git a/README.md b/README.md
index af78eb2..50d2d1f 100644
--- a/README.md
+++ b/README.md
@@ -1,10 +1,41 @@
-# HTML5-QRCode jQuery
-A cross-platform HTML5 QR code reader as a jQuery plugin.
+# Html5-QRCode
+A cross-platform HTML5 QR code reader.
+Use this light-weight Javascript library `(52 Kb)` to add QR Code scanning capability in your web application.
+
+## Supported platforms
+Working on adding support for more and more platforms. If you find a platform or browser where the library is not working please feel free to file an issue. Check the [demo link]((https://blog.minhazav.dev/research/html5-qrcode.html)) to test out.
+
+##### Legends
+ -  Means supported
+ -  Means work in progress to add support
+
+### PC / Mac
+
+| 
Firefox | 
Chrome | 
Safari | 
Opera | 
Edge
+| --------- | --------- | --------- | --------- | ------- |
+|| | |  | 
+
+### Android
+
+| 
Chrome | 
Firefox | 
Edge | 
Opera Mini
+| --------- | --------- | --------- | --------- |
+|| | | 
+
+### IOS
+> There is an ongoing issue on fixing the support for iOS - [issue/14](https://github.com/mebjas/html5-qrcode/issues/14)
+
+| 
Safari | 
Chrome | 
Firefox | 
Edge | 
Opera Touch
+| --------- | --------- | --------- | --------- | ------- |
+|| | |  | 
+
## Description - [View Demo](https://blog.minhazav.dev/research/html5-qrcode.html)
-This is a cross-platform jQuery library to create a QRcode reader for HTML5 compatible browser.
-It comes with the option to `scan QR Code`, `Stop scanning`, `Switch Camera` and `get info on camera`.
+This is a cross-platform javascript library to create a QRcode reader for HTML5 compatible browser.
+
+Supports:
+ - Querying all camera in the device (With user permissions)
+ - Using any camera for scanning QR Code.
## How to use?
Add an element you want to use as placeholder for QR Code scanner
@@ -12,107 +43,125 @@ Add an element you want to use as placeholder for QR Code scanner
```
-Add `jQuery library`, `jsqrcode-combined.js` and `html5-qrcode.js` (or their minified versions).
+Add `minified/html5-qrcode.min.js` in your web page.
+> I would recommend using the minified version as it's transformed to standard javascript. The `html5-qrcode.js` is written with ECMAScript and may not be supported in older version of the browsers. I wrote in this as it's easier to maintain!
+
```html
-
-
-
+
+
```
-To get a list of supported cameras, query it using
+To get a list of supported cameras, query it using static method `Html5Qrcode.getCameras()`. This method returns a `Promise` with list of devices supported in format `{ id: "id", label: "label" }`.
```js
-$(document).html5_qrcode_getSupportedCameras(
- function (devices) {
- /**
- * devices would be an array of objects of type:
- * { id: "id", label: "label" }
- */
- if (devices && devices.length) {
- var cameraId = devices[0].id;
- // .. use this to start scanning.
- }
- }, function (error) {
- // handle errors
+// This method will trigger user permissions
+Html5Qrcode.getCameras().then(cameras => {
+ /**
+ * devices would be an array of objects of type:
+ * { id: "id", label: "label" }
+ */
+ if (devices && devices.length) {
+ var cameraId = devices[0].id;
+ // .. use this to start scanning.
}
-);
+}).catch(err => {
+ // handle err
+});
```
-Once you have the camera id from `device.id`, start camera using
+Once you have the camera id from `device.id`, start camera using `Html5Qrcode#start(..)`. This method returns a `Promise` with Qr code scanning initiation.
```js
-$('#reader').html5_qrcode(
- cameraId,
- function (qrCodeMessage) {
- /* do something when code is read */
- }, function (errorMessage) {
- /* show read errors */
- }, function (errorMessage){
- /* the video stream could be opened */
+const html5QrCode = new Html5Qrcode(/* element id */ "reader");
+html5QrCode.start(
+ cameraId,
+ { fps: 10 },
+ qrCodeMessage => {
+ // do something when code is read
},
- { fps: 10 });
+ errorMessage => {
+ // parse error, ignore it.
+ })
+.catch(err => {
+ // Start failed, handle it.
+});
```
-To stop using camera and thus stop scanning, call
+To stop using camera and thus stop scanning, call `Html5Qrcode#stop()` which returns a `Promise` for stopping the video feed and scanning.
```js
-$('#reader').html5_qrcode_stop();
+html5QrCode.stop().then(ignore => {
+ // QR Code scanning is stopped.
+}).catch(err => {
+ // Stop failed, handle it.
+});
```
## Demo
[blog.minhazav.dev/research/html5-qrcode.html](https://blog.minhazav.dev/research/html5-qrcode.html)
### For more information
Check this article on how to use this library
-[](https://blog.minhazav.dev/qr-code-scanner-using-html-and-javascript/)
+[](https://blog.minhazav.dev/qr-code-scanner-using-html-and-javascript/)
[https://blog.minhazav.dev/qr-code-scanner-using-html-and-javascript/](https://blog.minhazav.dev/qr-code-scanner-using-html-and-javascript/)
## Screenshots
-
+
_Figure: Screenshot from Google Chrome running on Macbook Pro_
-
-_Figure: Screenshot from Google Chrome running on Android-based Pixel 3_
-
## Documentation
Following methods are available in this library
```js
-/**
- * Initializes QR code scanning on given element.
- *
- * @param: cameraId (int) - which camera to use
- * @param: qrcodeSuccessCallback (function) - callback on success
- * type: function (qrCodeMessage) {}
- * @param: qrcodeErrorCallback (function) - callback on QR parse error
- * type: function (errorMessage) {}
- * @param: videoErrorCallback (function) - callback on video error
- * type: function (errorMessage) {}
- * @param: config extra configurations to tune QR code scanner.
- * Supported fields:
- * - fps: expected framerate of qr code scanning. example { fps: 2 }
- * means the scanning would be done every 500 ms.
- */
-html5_qrcode: function(
- cameraId,
- qrcodeSuccessCallback,
- qrcodeErrorCallback,
- videoErrorCallback,
- config) {}
-
-/**
- * Stops streaming QR Code video and scanning.
- */
-html5_qrcode_stop: function() {}
-
-/**
- * Gets the count of number of available cameras.
- *
- * @param onSuccessCallback (Function) called when camera count is available.
- * type: Function (Array [{ id: String, label: String }]) {}
- * This argument is required.
- * @param onErrorCallback (function) called when enumerating cameras fails.
- * type: Function (String)
- */
-html5_qrcode_getSupportedCameras: function(
- onSuccessCallback, onErrorCallback) {}
-
+class Html5Qrcode {
+ /**
+ * Returns a Promise with list of all cameras supported by the device.
+ *
+ * The returned object is a list of result object of type:
+ * [{
+ * id: String; // Id of the camera.
+ * label: String; // Human readable name of the camera.
+ * }]
+ */
+ static getCameras() // Returns a Promise
+
+ /**
+ * Initialize QR Code scanner.
+ *
+ * @param {String} elementId - Id of the HTML element.
+ */
+ constructor(elementId)
+
+ /**
+ * Start scanning QR Code for given camera.
+ *
+ * @param {String} cameraId Id of the camera to use.
+ * @param {Object} config extra configurations to tune QR code scanner.
+ * Supported Fields:
+ * - fps: expected framerate of qr code scanning. example { fps: 2 }
+ * means the scanning would be done every 500 ms.
+ * @param {Function} qrCodeSuccessCallback callback on QR Code found.
+ * Example:
+ * function(qrCodeMessage) {}
+ * @param {Function} qrCodeErrorCallback callback on QR Code parse error.
+ * Example:
+ * function(errorMessage) {}
+ *
+ * @returns Promise for starting the scan. The Promise can fail if the user
+ * doesn't grant permission or some API is not supported by the browser.
+ */
+ start(cameraId,
+ configuration,
+ qrCodeSuccessCallback,
+ qrCodeErrorCallback) // Returns a Promise
+
+ /**
+ * Stops streaming QR Code video and scanning.
+ *
+ * @returns Promise for safely closing the video stream.
+ */
+ stop() // Returns a Promise
+}
```
## Credits
diff --git a/screenshots/1.jpg b/assets/1.jpg
similarity index 100%
rename from screenshots/1.jpg
rename to assets/1.jpg
diff --git a/screenshots/2.jpg b/assets/2.jpg
similarity index 100%
rename from screenshots/2.jpg
rename to assets/2.jpg
diff --git a/screenshots/3.jpg b/assets/3.jpg
similarity index 100%
rename from screenshots/3.jpg
rename to assets/3.jpg
diff --git a/assets/README.md b/assets/README.md
new file mode 100644
index 0000000..9a13dd3
--- /dev/null
+++ b/assets/README.md
@@ -0,0 +1,3 @@
+This directory is just for storing images used in https://github.com/mebjas/html5-qrcode Readme.
+
+The assets are not needed for running the library.
\ No newline at end of file
diff --git a/assets/done.png b/assets/done.png
new file mode 100644
index 0000000..b8a6d61
Binary files /dev/null and b/assets/done.png differ
diff --git a/assets/progress.png b/assets/progress.png
new file mode 100644
index 0000000..0b6b8ad
Binary files /dev/null and b/assets/progress.png differ
diff --git a/html5-qrcode.js b/html5-qrcode.js
index c2730ab..85ce282 100644
--- a/html5-qrcode.js
+++ b/html5-qrcode.js
@@ -1,183 +1,223 @@
-(function($) {
- var TIMEOUT_TAG = "TIMEOUT_TAG";
- var STREAM_TAG = "STREAM_TAG";
- var DEFAULT_HEIGHT = 250;
- var DEFAULT_HEIGHT_OFFSET = 2;
- var DEFAULT_WIDTH = 300;
- var DEFAULT_WIDTH_OFFSET = 2;
- var SCAN_DEFAULT_FPS = 2;
-
- window.URL = window.URL || window.webkitURL || window.mozURL || window.msURL;
- navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia
- || navigator.mozGetUserMedia || navigator.msGetUserMedia;
-
- function createVideoElement(width, height) {
- return '';
- }
+/**
+ * HTML5 QR code scanning library.
+ *
+ * Note that ECMA Script is not supported by all browsers. Use minified/html5-qrcode.min.js for better
+ * browser support. The code is currently transformed using https://babeljs.io.
+ *
+ * TODO(mebjas): Add support for autmated transpiling using babel.
+ */
+class Html5Qrcode {
+ static DEFAULT_HEIGHT = 250;
+ static DEFAULT_HEIGHT_OFFSET = 2;
+ static DEFAULT_WIDTH = 300;
+ static DEFAULT_WIDTH_OFFSET = 2;
+ static SCAN_DEFAULT_FPS = 2;
+ static VERBOSE = false;
- function createCanvasElement(width, height) {
- return '';
+ /**
+ * Initialize QR Code scanner.
+ *
+ * @param {String} elementId - Id of the HTML element.
+ */
+ constructor(elementId) {
+ this._elementId = elementId;
+ this._foreverScanTimeout = null;
+ this._localMediaStream = null;
+ this._shouldScan = true;
+ this._url = window.URL || window.webkitURL || window.mozURL || window.msURL;
+ this._userMedia = navigator.getUserMedia || navigator.webkitGetUserMedia
+ || navigator.mozGetUserMedia || navigator.msGetUserMedia;
}
- function getTimeoutFromFps(fps) {
- return 1000 / fps;
- }
+ /**
+ * Start scanning QR Code for given camera.
+ *
+ * @param {String} cameraId Id of the camera to use.
+ * @param {Object} config extra configurations to tune QR code scanner.
+ * Supported Fields:
+ * - fps: expected framerate of qr code scanning. example { fps: 2 }
+ * means the scanning would be done every 500 ms.
+ * @param {Function} qrCodeSuccessCallback callback on QR Code found.
+ * Example:
+ * function(qrCodeMessage) {}
+ * @param {Function} qrCodeErrorCallback callback on QR Code parse error.
+ * Example:
+ * function(errorMessage) {}
+ *
+ * @returns Promise for starting the scan. The Promise can fail if the user
+ * doesn't grant permission or some API is not supported by the browser.
+ */
+ start(cameraId,
+ configuration,
+ qrCodeSuccessCallback,
+ qrCodeErrorCallback) {
+ if (!cameraId) {
+ throw "cameraId is required";
+ }
- jQuery.fn.extend({
- /**
- * Initializes QR code scanning on given element.
- *
- * @param: cameraId (int) - which camera to use
- * @param: qrcodeSuccessCallback (function) - callback on success
- * type: function (qrCodeMessage) {}
- * @param: qrcodeErrorCallback (function) - callback on QR parse error
- * type: function (errorMessage) {}
- * @param: videoErrorCallback (function) - callback on video error
- * type: function (errorMessage) {}
- * @param: config extra configurations to tune QR code scanner.
- * Supported fields:
- * - fps: expected framerate of qr code scanning. example { fps: 2 }
- * means the scanning would be done every 500 ms.
- */
- html5_qrcode: function(
- cameraId,
- qrcodeSuccessCallback,
- qrcodeErrorCallback,
- videoErrorCallback,
- config) {
- return this.each(function() {
- if (cameraId == undefined) {
- throw "cameraId is required"
- }
+ if (!qrCodeSuccessCallback || typeof qrCodeSuccessCallback != "function") {
+ throw "qrCodeSuccessCallback is required and should be a function."
+ }
- // Initialize the callbacks
- qrcodeSuccessCallback = typeof qrcodeSuccessCallback === 'function'
- ? qrcodeSuccessCallback
- : function (ignore) {
- console.log('QR Code Success callback is undefined or not a function.');
- }
- qrcodeErrorCallback = qrcodeErrorCallback ? qrcodeErrorCallback : function (error, stream) {}
- videoErrorCallback = typeof videoErrorCallback === 'function' ? videoErrorCallback : function (error) {
- console.log('Error callback is undefined or not a function.', error);
- }
+ if (!qrCodeErrorCallback) {
+ qrCodeErrorCallback = console.log;
+ }
- config = config ? config : {};
- config.fps = config.fps ? config.fps : SCAN_DEFAULT_FPS;
-
- var currentElem = $(this);
- // Empty current item explicitly:
- currentElem.html("");
-
- var height = currentElem.height() == null ? DEFAULT_HEIGHT : currentElem.height();
- var width = currentElem.width() == null ? DEFAULT_WIDTH : currentElem.width();
- var vidElem = $(createVideoElement(width, height)).appendTo(currentElem);
- var canvasElem = $(createCanvasElement(width, height)).appendTo(currentElem);
-
- var video = vidElem[0];
- var canvas = canvasElem[0];
- var context = canvas.getContext('2d');
- var localMediaStream;
- var scan = function() {
- if (localMediaStream) {
- context.drawImage(video, 0, 0, width, height);
- try {
- qrcode.decode();
- } catch (exception) {
- qrcodeErrorCallback(exception, localMediaStream);
- }
- }
- $.data(currentElem[0], TIMEOUT_TAG, setTimeout(scan, getTimeoutFromFps(config.fps)));
- }; //end snapshot function
-
- var successCallback = function (stream) {
- video.srcObject = stream;
- localMediaStream = stream;
- $.data(currentElem[0], STREAM_TAG, stream);
- $.data(currentElem[0], TIMEOUT_TAG, setTimeout(scan, getTimeoutFromFps(config.fps)));
- video.play();
- };
-
- // Call the getUserMedia method with our callback functions
- if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
- navigator.mediaDevices.getUserMedia(
- { audio: false, video: { deviceId: { exact: cameraId}}})
- .then(successCallback)
- .catch(successCallback);
- } else if (navigator.getUserMedia) {
- qrcodeConfig = { video: { optional: [{ sourceId: cameraId }]}};
- navigator.getUserMedia(
- qrcodeConfig, successCallback, videoErrorCallback);
- } else {
- videoErrorCallback(
- "Native web camera streaming (getUserMedia) not supported in this browser.");
+ const $this = this;
+
+ // Create configuration by merging default and input settings.
+ const config = configuration ? configuration : {};
+ config.fps = config.fps ? config.fps : Html5Qrcode.SCAN_DEFAULT_FPS;
+
+
+ const element = document.getElementById(this._elementId);
+ const width = element.clientWidth ? element.clientWidth : Html5Qrcode.DEFAULT_WIDTH;
+ const height = element.clientHeight ? element.clientHeight : Html5Qrcode.DEFAULT_HEIGHT;
+ const videoElement = this._createVideoElement(width, height);
+ const canvasElement = this._createCanvasElement(width, height);
+ const context = canvasElement.getContext('2d');
+ context.canvas.width = width;
+ context.canvas.height = height;
+
+ element.append(videoElement);
+ element.append(canvasElement);
+
+ // save local states
+ this._element = element;
+ this._videoElement = videoElement;
+ this._canvasElement = canvasElement;
+
+ // Setup QR code.
+ this._shouldScan = true;
+ qrcode.callback = qrCodeSuccessCallback;
+
+ // Method that scans forever.
+ const foreverScan = () => {
+ if (!$this._shouldScan) {
+ // Stop scanning.
+ return;
+ }
+ if ($this._localMediaStream) {
+ context.drawImage(videoElement, 0, 0, videoElement.clientWidth, videoElement.clientHeight);
+ try {
+ qrcode.decode();
+ } catch (exception) {
+ qrCodeErrorCallback(`QR code parse error, error = ${exception}`);
}
+ }
+ $this._foreverScanTimeout = setTimeout(foreverScan, Html5Qrcode._getTimeoutFps(config.fps));
+ }
- qrcode.callback = qrcodeSuccessCallback;
- }); // end of html5_qrcode
- },
- /**
- * Stops streaming QR Code video and scanning.
- */
- html5_qrcode_stop: function() {
- return this.each(function() {
- // stop the stream and cancel timeouts
- $(this).data(STREAM_TAG).getVideoTracks().forEach(function (videoTrack) {
- videoTrack.stop();
- });
-
- $(this).children('video').remove();
- $(this).children('canvas').remove();
- clearTimeout($(this).data(TIMEOUT_TAG));
- });
- },
- /**
- * Gets the count of number of available cameras.
- *
- * @param onSuccessCallback (Function) called when camera count is available.
- * type: Function (Array [{ id: String, label: String }]) {}
- * This argument is required.
- * @param onErrorCallback (function) called when enumerating cameras fails.
- * type: Function (String)
- */
- html5_qrcode_getSupportedCameras: function(onSuccessCallback, onErrorCallback) {
- if (typeof onSuccessCallback != 'function') {
- throw "onSuccessCallback (1st argument) should be a function."
+ // success callback when user media (Camera) is attached.
+ const getUserMediaSuccessCallback = stream => {
+ videoElement.srcObject = stream;
+ videoElement.play();
+ $this._localMediaStream = stream;
+ foreverScan();
+ }
+
+ return new Promise((resolve, reject) => {
+ if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
+ navigator.mediaDevices.getUserMedia(
+ { audio: false, video: { deviceId: { exact: cameraId }}})
+ .then(stream => {
+ getUserMediaSuccessCallback(stream);
+ resolve();
+ })
+ .catch(err => {
+ reject(`Error getting userMedia, error = ${err}`);
+ });
+ } else if (navigator.getUserMedia) {
+ const getCameraConfig = { video: { optional: [{ sourceId: cameraId }]}};
+ navigator.getUserMedia(getCameraConfig,
+ stream => {
+ getUserMediaSuccessCallback(stream);
+ resolve();
+ }, err => {
+ reject(`Error getting userMedia, error = ${err}`);
+ });
+ } else {
+ reject("Web camera streaming not supported by the browser.");
+ }
+ });
+ }
+
+ /**
+ * Stops streaming QR Code video and scanning.
+ *
+ * @returns Promise for safely closing the video stream.
+ */
+ stop() {
+ // TODO(mebjas): fail fast if the start() wasn't called.
+ this._shouldScan = false;
+ clearTimeout(this._foreverScanTimeout);
+
+ const $this = this;
+ return new Promise((resolve, /* ignore */ reject) => {
+ const tracksToClose = $this._localMediaStream.getVideoTracks().length;
+ var tracksClosed = 0;
+
+ const onAllTracksClosed = () => {
+ $this._localMediaStream = null;
+ $this._element.removeChild($this._videoElement);
+ $this._element.removeChild($this._canvasElement);
+ resolve(true);
}
- onErrorCallback = typeof onErrorCallback == 'function'
- ? onErrorCallback
- : function (error) {
- console.error("Unable to retreive supported cameras. Reason: ", error);
+ $this._localMediaStream.getVideoTracks().forEach(videoTrack => {
+ videoTrack.stop();
+ ++tracksClosed;
+
+ if (tracksClosed >= tracksToClose) {
+ onAllTracksClosed();
}
-
- if (navigator.mediaDevices && navigator.mediaDevices.enumerateDevices) {
- navigator.mediaDevices.enumerateDevices()
- .then(function (devices) {
- var results = [];
- for (i = 0; i < devices.length; i++) {
- var device = devices[i];
- if (device.kind == "videoinput") {
- results.push({
- id: device.deviceId,
- label: device.label
- });
+ });
+ });
+ }
+
+ /**
+ * Returns a Promise with list of all cameras supported by the device.
+ *
+ * The returned object is a list of result object of type:
+ * [{
+ * id: String; // Id of the camera.
+ * label: String; // Human readable name of the camera.
+ * }]
+ */
+ static getCameras() {
+ return new Promise((resolve, reject) => {
+ if (navigator.mediaDevices
+ && navigator.mediaDevices.enumerateDevices
+ && navigator.mediaDevices.getUserMedia) {
+ this._log("navigator.mediaDevices used");
+ navigator.mediaDevices.getUserMedia({audio: false, video: true}).then(ignore => {
+ navigator.mediaDevices.enumerateDevices()
+ .then(devices => {
+ const results = [];
+ for (var i = 0; i < devices.length; i++) {
+ const device = devices[i];
+ if (device.kind == "videoinput") {
+ results.push({
+ id: device.deviceId,
+ label: device.label
+ });
+ }
}
- }
- onSuccessCallback(results);
+ this._log(`${results.length} results found`);
+ resolve(results);
+ })
+ .catch(err => {
+ reject(`${err.name} : ${err.message}`);
+ });
+ }).catch(err => {
+ reject(`${err.name} : ${err.message}`);
})
- .catch(function (err) {
- onErrorCallback(err.name + ": " + err.message);
- });
- } else if (typeof MediaStreamTrack != 'undefined'
- && typeof MediaStreamTrack.getSources != 'undefined') {
- var callback = function (sourceInfos) {
- var results = [];
- for (i = 0; i !== sourceInfos.length; ++i) {
- var sourceInfo = sourceInfos[i];
+ } else if (MediaStreamTrack && MediaStreamTrack.getSources) {
+ this._log("MediaStreamTrack.getSources used");
+ const callback = sourceInfos => {
+ const results = [];
+ for (var i = 0; i !== sourceInfos.length; ++i) {
+ const sourceInfo = sourceInfos[i];
if (sourceInfo.kind === 'video') {
results.push({
id: sourceInfo.id,
@@ -185,12 +225,43 @@
});
}
}
- onSuccessCallback(results);
+ this._log(`${results.length} results found`);
+ resolve(results);
}
MediaStreamTrack.getSources(callback);
} else {
- onErrorCallback("unable to query supported devices.");
+ this._log("unable to query supported devices.");
+ reject("unable to query supported devices.");
}
+ });
+ }
+
+ _createCanvasElement(width, height) {
+ const canvasWidth = width;// - Html5Qrcode.DEFAULT_WIDTH_OFFSET;
+ const canvasHeight = height;// - Html5Qrcode.DEFAULT_HEIGHT_OFFSET;
+ const canvasElement = document.createElement('canvas');
+ canvasElement.style.width = `${canvasWidth}px`;
+ canvasElement.style.height = `${canvasHeight}px`;
+ canvasElement.style.display = "none";
+ // This id is set by lazarsoft/jsqrcode
+ canvasElement.id = 'qr-canvas';
+ return canvasElement;
+ }
+
+ _createVideoElement(width, height) {
+ const videoElement = document.createElement('video');
+ videoElement.style.height = `${height}px`;
+ videoElement.style.width = `${width}px`;
+ return videoElement;
+ }
+
+ static _getTimeoutFps(fps) {
+ return 1000 / fps;
+ }
+
+ static _log(message) {
+ if (Html5Qrcode.VERBOSE) {
+ console.log(message);
}
- });
-})(jQuery);
\ No newline at end of file
+ }
+}
diff --git a/minified/html5-qrcode.min.js b/minified/html5-qrcode.min.js
index f62ed2a..7f6bd8e 100644
--- a/minified/html5-qrcode.min.js
+++ b/minified/html5-qrcode.min.js
@@ -1 +1,17 @@
-!function(g){var p="TIMEOUT_TAG",m="STREAM_TAG";function w(e){return 1e3/e}window.URL=window.URL||window.webkitURL||window.mozURL||window.msURL,navigator.getUserMedia=navigator.getUserMedia||navigator.webkitGetUserMedia||navigator.mozGetUserMedia||navigator.msGetUserMedia,jQuery.fn.extend({html5_qrcode:function(u,f,v,l,h){return this.each(function(){if(null==u)throw"cameraId is required";f="function"==typeof f?f:function(e){console.log("QR Code Success callback is undefined or not a function.")},v=v||function(e,i){},l="function"==typeof l?l:function(e){console.log("Error callback is undefined or not a function.",e)},(h=h||{}).fps=h.fps?h.fps:2;var i=g(this);i.html("");function e(e){c.srcObject=e,t=e,g.data(i[0],m,e),g.data(i[0],p,setTimeout(s,w(h.fps))),c.play()}var t,a=null==i.height()?250:i.height(),n=null==i.width()?300:i.width(),o=g('').appendTo(i),r=g('').appendTo(i),c=o[0],d=r[0].getContext("2d"),s=function(){if(t){d.drawImage(c,0,0,n,a);try{qrcode.decode()}catch(e){v(e,t)}}g.data(i[0],p,setTimeout(s,w(h.fps)))};navigator.mediaDevices&&navigator.mediaDevices.getUserMedia?navigator.mediaDevices.getUserMedia({audio:!1,video:{deviceId:{exact:u}}}).then(e).catch(e):navigator.getUserMedia?(qrcodeConfig={video:{optional:[{sourceId:u}]}},navigator.getUserMedia(qrcodeConfig,e,l)):l("Native web camera streaming (getUserMedia) not supported in this browser."),qrcode.callback=f})},html5_qrcode_stop:function(){return this.each(function(){g(this).data(m).getVideoTracks().forEach(function(e){e.stop()}),g(this).children("video").remove(),g(this).children("canvas").remove(),clearTimeout(g(this).data(p))})},html5_qrcode_getSupportedCameras:function(n,t){if("function"!=typeof n)throw"onSuccessCallback (1st argument) should be a function.";if(t="function"==typeof t?t:function(e){console.error("Unable to retreive supported cameras. Reason: ",e)},navigator.mediaDevices&&navigator.mediaDevices.enumerateDevices)navigator.mediaDevices.enumerateDevices().then(function(e){var t=[];for(i=0;ii;i++)for(var r=this.alignmentPatternCenters[i]-2,o=0;n>o;o++)0==i&&(0==o||o==n-1)||i==n-1&&0==o||t.setRegion(this.alignmentPatternCenters[o]-2,r,5,5);return t.setRegion(6,9,1,e-17),t.setRegion(9,6,e-17,1),6f;f+=2){var d=e[f],w=e[f+1],u=r*d+a*w+l;e[f]=(n*d+o*w+h)/u,e[f+1]=(i*d+s*w+c)/u}},this.transformPoints2=function(e,t){for(var n=e.length,i=0;n>i;i++){var r=e[i],o=t[i],s=this.a13*r+this.a23*o+this.a33;e[i]=(this.a11*r+this.a21*o+this.a31)/s,t[i]=(this.a12*r+this.a22*o+this.a32)/s}},this.buildAdjoint=function(){return new PerspectiveTransform(this.a22*this.a33-this.a23*this.a32,this.a23*this.a31-this.a21*this.a33,this.a21*this.a32-this.a22*this.a31,this.a13*this.a32-this.a12*this.a33,this.a11*this.a33-this.a13*this.a31,this.a12*this.a31-this.a11*this.a32,this.a12*this.a23-this.a13*this.a22,this.a13*this.a21-this.a11*this.a23,this.a11*this.a22-this.a12*this.a21)},this.times=function(e){return new PerspectiveTransform(this.a11*e.a11+this.a21*e.a12+this.a31*e.a13,this.a11*e.a21+this.a21*e.a22+this.a31*e.a23,this.a11*e.a31+this.a21*e.a32+this.a31*e.a33,this.a12*e.a11+this.a22*e.a12+this.a32*e.a13,this.a12*e.a21+this.a22*e.a22+this.a32*e.a23,this.a12*e.a31+this.a22*e.a32+this.a32*e.a33,this.a13*e.a11+this.a23*e.a12+this.a33*e.a13,this.a13*e.a21+this.a23*e.a22+this.a33*e.a23,this.a13*e.a31+this.a23*e.a32+this.a33*e.a33)}}function DetectorResult(e,t){this.bits=e,this.points=t}function Detector(e){this.image=e,this.resultPointCallback=null,this.sizeOfBlackWhiteBlackRun=function(e,t,n,i){var r=Math.abs(i-t)>Math.abs(n-e);if(r){var o=e;e=t,t=o,o=n,n=i,i=o}for(var s=Math.abs(n-e),a=Math.abs(i-t),h=-s>>1,c=i>t?1:-1,l=n>e?1:-1,f=0,d=e,o=t;d!=n;d+=l){var w=r?o:d,u=r?d:o;if(1==f?this.image[w+u*qrcode.width]&&f++:this.image[w+u*qrcode.width]||f++,3==f)return i=d-e,t=o-t,Math.sqrt(i*i+t*t);if(h+=a,h>0){if(o==i)break;o+=c,h-=s}}return e=n-e,t=i-t,Math.sqrt(e*e+t*t)},this.sizeOfBlackWhiteBlackRunBothWays=function(e,t,n,i){var r=this.sizeOfBlackWhiteBlackRun(e,t,n,i),o=1;return n=e-(n-e),0>n?(o=e/(e-n),n=0):n>=qrcode.width&&(o=(qrcode.width-1-e)/(n-e),n=qrcode.width-1),i=Math.floor(t-(i-t)*o),o=1,0>i?(o=t/(t-i),i=0):i>=qrcode.height&&(o=(qrcode.height-1-t)/(i-t),i=qrcode.height-1),n=Math.floor(e+(n-e)*o),r+=this.sizeOfBlackWhiteBlackRun(e,t,n,i),r-1},this.calculateModuleSizeOneWay=function(e,t){var n=this.sizeOfBlackWhiteBlackRunBothWays(Math.floor(e.X),Math.floor(e.Y),Math.floor(t.X),Math.floor(t.Y)),i=this.sizeOfBlackWhiteBlackRunBothWays(Math.floor(t.X),Math.floor(t.Y),Math.floor(e.X),Math.floor(e.Y));return isNaN(n)?i/7:isNaN(i)?n/7:(n+i)/14},this.calculateModuleSize=function(e,t,n){return(this.calculateModuleSizeOneWay(e,t)+this.calculateModuleSizeOneWay(e,n))/2},this.distance=function(e,t){return xDiff=e.X-t.X,yDiff=e.Y-t.Y,Math.sqrt(xDiff*xDiff+yDiff*yDiff)},this.computeDimension=function(e,t,n,i){switch(t=Math.round(this.distance(e,t)/i),e=Math.round(this.distance(e,n)/i),e=(t+e>>1)+7,3&e){case 0:e++;break;case 2:e--;break;case 3:throw"Error"}return e},this.findAlignmentInRegion=function(e,t,n,i){var r=Math.floor(i*e);if(i=Math.max(0,t-r),t=Math.min(qrcode.width-1,t+r),3*e>t-i)throw"Error";var o=Math.max(0,n-r);return n=Math.min(qrcode.height-1,n+r),new AlignmentPatternFinder(this.image,i,o,t-i,n-o,e,this.resultPointCallback).find()},this.createTransform=function(e,t,n,i,r){r-=3.5;var o,s,a;return null!=i?(o=i.X,i=i.Y,s=a=r-3):(o=t.X-e.X+n.X,i=t.Y-e.Y+n.Y,s=a=r),PerspectiveTransform.quadrilateralToQuadrilateral(3.5,3.5,r,3.5,s,a,3.5,r,e.X,e.Y,t.X,t.Y,o,i,n.X,n.Y)},this.sampleGrid=function(e,t,n){return GridSampler.sampleGrid3(e,n,t)},this.processFinderPatternInfo=function(e){var t=e.TopLeft,n=e.TopRight;e=e.BottomLeft;var i=this.calculateModuleSize(t,n,e);if(1>i)throw"Error";var r=this.computeDimension(t,n,e,i),o=Version.getProvisionalVersionForDimension(r),s=o.DimensionForVersion-7,a=null;if(0>3&3),this.dataMask=7&e,this.__defineGetter__("ErrorCorrectionLevel",function(){return this.errorCorrectionLevel}),this.__defineGetter__("DataMask",function(){return this.dataMask}),this.GetHashCode=function(){return this.errorCorrectionLevel.ordinal()<<3|dataMask},this.Equals=function(e){return this.errorCorrectionLevel==e.errorCorrectionLevel&&this.dataMask==e.dataMask}}function ErrorCorrectionLevel(e,t,n){this.ordinal_Renamed_Field=e,this.bits=t,this.name=n,this.__defineGetter__("Bits",function(){return this.bits}),this.__defineGetter__("Name",function(){return this.name}),this.ordinal=function(){return this.ordinal_Renamed_Field}}function BitMatrix(e,t){if(t||(t=e),1>e||1>t)throw"Both dimensions must be greater than 0";this.width=e,this.height=t;var n=e>>5;for(0!=(31&e)&&n++,this.rowSize=n,this.bits=Array(n*t),n=0;n>5)],31&e))},this.set_Renamed=function(e,t){this.bits[t*this.rowSize+(e>>5)]|=1<<(31&e)},this.flip=function(e,t){this.bits[t*this.rowSize+(e>>5)]^=1<<(31&e)},this.clear=function(){for(var e=this.bits.length,t=0;e>t;t++)this.bits[t]=0},this.setRegion=function(e,t,n,i){if(0>t||0>e)throw"Left and top must be nonnegative";if(1>i||1>n)throw"Height and width must be at least 1";if(n=e+n,i=t+i,i>this.height||n>this.width)throw"The region must fit inside the matrix";for(;i>t;t++)for(var r=t*this.rowSize,o=e;n>o;o++)this.bits[r+(o>>5)]|=1<<(31&o)}}function DataBlock(e,t){this.numDataCodewords=e,this.codewords=t,this.__defineGetter__("NumDataCodewords",function(){return this.numDataCodewords}),this.__defineGetter__("Codewords",function(){return this.codewords})}function BitMatrixParser(e){var t=e.Dimension;if(21>t||1!=(3&t))throw"Error BitMatrixParser";this.bitMatrix=e,this.parsedFormatInfo=this.parsedVersion=null,this.copyBit=function(e,t,n){return this.bitMatrix.get_Renamed(e,t)?n<<1|1:n<<1},this.readFormatInformation=function(){if(null!=this.parsedFormatInfo)return this.parsedFormatInfo;for(var e=0,t=0;6>t;t++)e=this.copyBit(t,8,e);for(e=this.copyBit(7,8,e),e=this.copyBit(8,8,e),e=this.copyBit(8,7,e),t=5;t>=0;t--)e=this.copyBit(8,t,e);if(this.parsedFormatInfo=FormatInformation.decodeFormatInformation(e),null!=this.parsedFormatInfo)return this.parsedFormatInfo;for(var n=this.bitMatrix.Dimension,e=0,i=n-8,t=n-1;t>=i;t--)e=this.copyBit(t,8,e);for(t=n-7;n>t;t++)e=this.copyBit(8,t,e);if(this.parsedFormatInfo=FormatInformation.decodeFormatInformation(e),null!=this.parsedFormatInfo)return this.parsedFormatInfo;throw"Error readFormatInformation"},this.readVersion=function(){if(null!=this.parsedVersion)return this.parsedVersion;var e=this.bitMatrix.Dimension,t=e-17>>2;if(6>=t)return Version.getVersionForNumber(t);for(var t=0,n=e-11,i=5;i>=0;i--)for(var r=e-9;r>=n;r--)t=this.copyBit(r,i,t);if(this.parsedVersion=Version.decodeVersionInformation(t),null!=this.parsedVersion&&this.parsedVersion.DimensionForVersion==e)return this.parsedVersion;for(t=0,r=5;r>=0;r--)for(i=e-9;i>=n;i--)t=this.copyBit(r,i,t);if(this.parsedVersion=Version.decodeVersionInformation(t),null!=this.parsedVersion&&this.parsedVersion.DimensionForVersion==e)return this.parsedVersion;throw"Error readVersion"},this.readCodewords=function(){var e=this.readFormatInformation(),t=this.readVersion(),n=DataMask.forReference(e.DataMask),e=this.bitMatrix.Dimension;n.unmaskBitMatrix(this.bitMatrix,e);for(var n=t.buildFunctionPattern(),i=!0,r=Array(t.TotalCodewords),o=0,s=0,a=0,h=e-1;h>0;h-=2){6==h&&h--;for(var c=0;e>c;c++)for(var l=i?e-1-c:c,f=0;2>f;f++)n.get_Renamed(h-f,l)||(a++,s<<=1,this.bitMatrix.get_Renamed(h-f,l)&&(s|=1),8==a&&(r[o++]=s,s=a=0));i^=1}if(o!=t.TotalCodewords)throw"Error readCodewords";return r}}function DataMask000(){this.unmaskBitMatrix=function(e,t){for(var n=0;t>n;n++)for(var i=0;t>i;i++)this.isMasked(n,i)&&e.flip(i,n)},this.isMasked=function(e,t){return 0==(e+t&1)}}function DataMask001(){this.unmaskBitMatrix=function(e,t){for(var n=0;t>n;n++)for(var i=0;t>i;i++)this.isMasked(n,i)&&e.flip(i,n)},this.isMasked=function(e){return 0==(1&e)}}function DataMask010(){this.unmaskBitMatrix=function(e,t){for(var n=0;t>n;n++)for(var i=0;t>i;i++)this.isMasked(n,i)&&e.flip(i,n)},this.isMasked=function(e,t){return 0==t%3}}function DataMask011(){this.unmaskBitMatrix=function(e,t){for(var n=0;t>n;n++)for(var i=0;t>i;i++)this.isMasked(n,i)&&e.flip(i,n)},this.isMasked=function(e,t){return 0==(e+t)%3}}function DataMask100(){this.unmaskBitMatrix=function(e,t){for(var n=0;t>n;n++)for(var i=0;t>i;i++)this.isMasked(n,i)&&e.flip(i,n)},this.isMasked=function(e,t){return 0==(URShift(e,1)+t/3&1)}}function DataMask101(){this.unmaskBitMatrix=function(e,t){for(var n=0;t>n;n++)for(var i=0;t>i;i++)this.isMasked(n,i)&&e.flip(i,n)},this.isMasked=function(e,t){var n=e*t;return 0==(1&n)+n%3}}function DataMask110(){this.unmaskBitMatrix=function(e,t){for(var n=0;t>n;n++)for(var i=0;t>i;i++)this.isMasked(n,i)&&e.flip(i,n)},this.isMasked=function(e,t){var n=e*t;return 0==((1&n)+n%3&1)}}function DataMask111(){this.unmaskBitMatrix=function(e,t){for(var n=0;t>n;n++)for(var i=0;t>i;i++)this.isMasked(n,i)&&e.flip(i,n)},this.isMasked=function(e,t){return 0==((e+t&1)+e*t%3&1)}}function ReedSolomonDecoder(e){this.field=e,this.decode=function(e,t){for(var n=new GF256Poly(this.field,e),i=Array(t),r=0;rr;r++){var s=n.evaluateAt(this.field.exp(r));i[i.length-1-r]=s,0!=s&&(o=!1)}if(!o)for(r=new GF256Poly(this.field,i),n=this.runEuclideanAlgorithm(this.field.buildMonomial(t,1),r,t),r=n[1],n=this.findErrorLocations(n[0]),i=this.findErrorMagnitudes(r,n,!1),r=0;ro)throw"ReedSolomonException Bad error location";e[o]=GF256.addOrSubtract(e[o],i[r])}},this.runEuclideanAlgorithm=function(e,t,n){if(e.Degree=Math.floor(n/2);){var a=e,h=i,c=o;if(e=t,i=r,o=s,e.Zero)throw"r_{i-1} was zero";for(t=a,s=this.field.Zero,r=e.getCoefficient(e.Degree),r=this.field.inverse(r);t.Degree>=e.Degree&&!t.Zero;){var a=t.Degree-e.Degree,l=this.field.multiply(t.getCoefficient(t.Degree),r),s=s.addOrSubtract(this.field.buildMonomial(a,l));t=t.addOrSubtract(e.multiplyByMonomial(a,l))}r=s.multiply1(i).addOrSubtract(h),s=s.multiply1(o).addOrSubtract(c)}if(n=s.getCoefficient(0),0==n)throw"ReedSolomonException sigmaTilde(0) was zero";return n=this.field.inverse(n),e=s.multiply2(n),n=t.multiply2(n),[e,n]},this.findErrorLocations=function(e){var t=e.Degree;if(1==t)return Array(e.getCoefficient(1));for(var n=Array(t),i=0,r=1;256>r&&t>i;r++)0==e.evaluateAt(r)&&(n[i]=this.field.inverse(r),i++);if(i!=t)throw"Error locator degree does not match number of roots";return n},this.findErrorMagnitudes=function(e,t,n){for(var i=t.length,r=Array(i),o=0;i>o;o++){for(var s=this.field.inverse(t[o]),a=1,h=0;i>h;h++)o!=h&&(a=this.field.multiply(a,GF256.addOrSubtract(1,this.field.multiply(t[h],s))));r[o]=this.field.multiply(e.evaluateAt(s),this.field.inverse(a)),n&&(r[o]=this.field.multiply(r[o],s))}return r}}function GF256Poly(e,t){if(null==t||0==t.length)throw"System.ArgumentException";this.field=e;var n=t.length;if(n>1&&0==t[0]){for(var i=1;n>i&&0==t[i];)i++;if(i==n)this.coefficients=e.Zero.coefficients;else{for(this.coefficients=Array(n-i),n=0;nn;n++)e=GF256.addOrSubtract(e,this.coefficients[n]);return e}for(var i=this.coefficients[0],n=1;t>n;n++)i=GF256.addOrSubtract(this.field.multiply(e,i),this.coefficients[n]);return i},this.addOrSubtract=function(t){if(this.field!=t.field)throw"GF256Polys do not have same GF256 field";if(this.Zero)return t;if(t.Zero)return this;var n=this.coefficients;if(t=t.coefficients,n.length>t.length){var i=n,n=t;t=i}for(var i=Array(t.length),r=t.length-n.length,o=0;r>o;o++)i[o]=t[o];for(o=r;oo;o++)for(var s=t[o],a=0;i>a;a++)r[o+a]=GF256.addOrSubtract(r[o+a],this.field.multiply(s,e[a]));return new GF256Poly(this.field,r)},this.multiply2=function(e){if(0==e)return this.field.Zero;if(1==e)return this;for(var t=this.coefficients.length,n=Array(t),i=0;t>i;i++)n[i]=this.field.multiply(this.coefficients[i],e);return new GF256Poly(this.field,n)},this.multiplyByMonomial=function(e,t){if(0>e)throw"System.ArgumentException";if(0==t)return this.field.Zero;for(var n=this.coefficients.length,i=Array(n+e),r=0;rr;r++)i[r]=this.field.multiply(this.coefficients[r],t);return new GF256Poly(this.field,i)},this.divide=function(e){if(this.field!=e.field)throw"GF256Polys do not have same GF256 field";if(e.Zero)throw"Divide by 0";for(var t=this.field.Zero,n=this,i=e.getCoefficient(e.Degree),i=this.field.inverse(i);n.Degree>=e.Degree&&!n.Zero;)var r=n.Degree-e.Degree,o=this.field.multiply(n.getCoefficient(n.Degree),i),s=e.multiplyByMonomial(r,o),r=this.field.buildMonomial(r,o),t=t.addOrSubtract(r),n=n.addOrSubtract(s);return[t,n]}}function GF256(e){this.expTable=Array(256),this.logTable=Array(256);for(var t=1,n=0;256>n;n++)this.expTable[n]=t,t<<=1,t>=256&&(t^=e);for(n=0;255>n;n++)this.logTable[this.expTable[n]]=n;e=Array(1),e[0]=0,this.zero=new GF256Poly(this,Array(e)),e=Array(1),e[0]=1,this.one=new GF256Poly(this,Array(e)),this.__defineGetter__("Zero",function(){return this.zero}),this.__defineGetter__("One",function(){return this.one}),this.buildMonomial=function(e,t){if(0>e)throw"System.ArgumentException";if(0==t)return zero;for(var n=Array(e+1),i=0;i=0?e>>t:(e>>t)+(2<<~t)}function FinderPattern(e,t,n){this.x=e,this.y=t,this.count=1,this.estimatedModuleSize=n,this.__defineGetter__("EstimatedModuleSize",function(){return this.estimatedModuleSize}),this.__defineGetter__("Count",function(){return this.count}),this.__defineGetter__("X",function(){return this.x}),this.__defineGetter__("Y",function(){return this.y}),this.incrementCount=function(){this.count++},this.aboutEquals=function(e,t,n){return Math.abs(t-this.y)<=e&&Math.abs(n-this.x)<=e?(e=Math.abs(e-this.estimatedModuleSize),1>=e||1>=e/this.estimatedModuleSize):!1}}function FinderPatternInfo(e){this.bottomLeft=e[0],this.topLeft=e[1],this.topRight=e[2],this.__defineGetter__("BottomLeft",function(){return this.bottomLeft}),this.__defineGetter__("TopLeft",function(){return this.topLeft}),this.__defineGetter__("TopRight",function(){return this.topRight})}function FinderPatternFinder(){this.image=null,this.possibleCenters=[],this.hasSkipped=!1,this.crossCheckStateCount=[0,0,0,0,0],this.resultPointCallback=null,this.__defineGetter__("CrossCheckStateCount",function(){return this.crossCheckStateCount[0]=0,this.crossCheckStateCount[1]=0,this.crossCheckStateCount[2]=0,this.crossCheckStateCount[3]=0,this.crossCheckStateCount[4]=0,this.crossCheckStateCount}),this.foundPatternCross=function(e){for(var t=0,n=0;5>n;n++){var i=e[n];if(0==i)return!1;t+=i}return 7>t?!1:(t=Math.floor((t<=0&&r[t+a*qrcode.width];)s[2]++,a--;if(0>a)return 0/0;for(;a>=0&&!r[t+a*qrcode.width]&&s[1]<=n;)s[1]++,a--;if(0>a||s[1]>n)return 0/0;for(;a>=0&&r[t+a*qrcode.width]&&s[0]<=n;)s[0]++,a--;if(s[0]>n)return 0/0;for(a=e+1;o>a&&r[t+a*qrcode.width];)s[2]++,a++;if(a==o)return 0/0;for(;o>a&&!r[t+a*qrcode.width]&&s[3]=n)return 0/0;for(;o>a&&r[t+a*qrcode.width]&&s[4]=n||5*Math.abs(s[0]+s[1]+s[2]+s[3]+s[4]-i)>=2*i?0/0:this.foundPatternCross(s)?this.centerFromEnd(s,a):0/0},this.crossCheckHorizontal=function(e,t,n,i){for(var r=this.image,o=qrcode.width,s=this.CrossCheckStateCount,a=e;a>=0&&r[a+t*qrcode.width];)s[2]++,a--;if(0>a)return 0/0;for(;a>=0&&!r[a+t*qrcode.width]&&s[1]<=n;)s[1]++,a--;if(0>a||s[1]>n)return 0/0;for(;a>=0&&r[a+t*qrcode.width]&&s[0]<=n;)s[0]++,a--;if(s[0]>n)return 0/0;for(a=e+1;o>a&&r[a+t*qrcode.width];)s[2]++,a++;if(a==o)return 0/0;for(;o>a&&!r[a+t*qrcode.width]&&s[3]=n)return 0/0;for(;o>a&&r[a+t*qrcode.width]&&s[4]=n||5*Math.abs(s[0]+s[1]+s[2]+s[3]+s[4]-i)>=i?0/0:this.foundPatternCross(s)?this.centerFromEnd(s,a):0/0},this.handlePossibleCenter=function(e,t,n){var i=e[0]+e[1]+e[2]+e[3]+e[4];if(n=this.centerFromEnd(e,n),t=this.crossCheckVertical(t,Math.floor(n),e[2],i),!isNaN(t)&&(n=this.crossCheckHorizontal(Math.floor(n),Math.floor(t),e[2],i),!isNaN(n))){e=i/7;for(var i=!1,r=this.possibleCenters.length,o=0;r>o;o++){var s=this.possibleCenters[o];if(s.aboutEquals(e,t,n)){s.incrementCount(),i=!0;break}}return i||(n=new FinderPattern(n,t,e),this.possibleCenters.push(n),null!=this.resultPointCallback&&this.resultPointCallback.foundPossibleResultPoint(n)),!0}return!1},this.selectBestPatterns=function(){var e=this.possibleCenters.length;if(3>e)throw"Couldn't find enough finder patterns";if(e>3){for(var t=0,n=0;e>n;n++)t+=this.possibleCenters[n].EstimatedModuleSize;for(e=t/e,n=0;n.2*e&&(this.possibleCenters.remove(n),n--)}return[this.possibleCenters[0],this.possibleCenters[1],this.possibleCenters[2]]},this.findRowSkip=function(){var e=this.possibleCenters.length;if(1>=e)return 0;for(var t=null,n=0;e>n;n++){var i=this.possibleCenters[n];if(i.Count>=CENTER_QUORUM){if(null!=t)return this.hasSkipped=!0,Math.floor((Math.abs(t.X-i.X)-Math.abs(t.Y-i.Y))/2);t=i}}return 0},this.haveMultiplyConfirmedCenters=function(){for(var e=0,t=0,n=this.possibleCenters.length,i=0;n>i;i++){var r=this.possibleCenters[i];r.Count>=CENTER_QUORUM&&(e++,t+=r.EstimatedModuleSize)}if(3>e)return!1;for(var e=t/n,o=0,i=0;n>i;i++)r=this.possibleCenters[i],o+=Math.abs(r.EstimatedModuleSize-e);return.05*t>=o},this.findFinderPattern=function(e){this.image=e;var t=qrcode.height,n=qrcode.width,i=Math.floor(3*t/(4*MAX_MODULES));MIN_SKIP>i&&(i=MIN_SKIP);for(var r=!1,o=Array(5),s=i-1;t>s&&!r;s+=i){o[0]=0,o[1]=0,o[2]=0,o[3]=0;for(var a=o[4]=0,h=0;n>h;h++)if(e[h+s*qrcode.width])1==(1&a)&&a++,o[a]++;else if(0==(1&a))if(4==a)if(this.foundPatternCross(o)){if(a=this.handlePossibleCenter(o,s,h))i=2,this.hasSkipped?r=this.haveMultiplyConfirmedCenters():(a=this.findRowSkip(),a>o[2]&&(s+=a-o[2]-i,h=n-1));else{do h++;while(n>h&&!e[h+s*qrcode.width]);h--}a=0,o[0]=0,o[1]=0,o[2]=0,o[3]=0,o[4]=0}else o[0]=o[2],o[1]=o[3],o[2]=o[4],o[3]=1,o[4]=0,a=3;else o[++a]++;else o[a]++;this.foundPatternCross(o)&&this.handlePossibleCenter(o,s,n)&&(i=o[0],this.hasSkipped&&(r=haveMultiplyConfirmedCenters()))}return e=this.selectBestPatterns(),qrcode.orderBestPatterns(e),new FinderPatternInfo(e)}}function AlignmentPattern(e,t,n){this.x=e,this.y=t,this.count=1,this.estimatedModuleSize=n,this.__defineGetter__("EstimatedModuleSize",function(){return this.estimatedModuleSize}),this.__defineGetter__("Count",function(){return this.count}),this.__defineGetter__("X",function(){return Math.floor(this.x)}),this.__defineGetter__("Y",function(){return Math.floor(this.y)}),this.incrementCount=function(){this.count++},this.aboutEquals=function(e,t,n){return Math.abs(t-this.y)<=e&&Math.abs(n-this.x)<=e?(e=Math.abs(e-this.estimatedModuleSize),1>=e||1>=e/this.estimatedModuleSize):!1}}function AlignmentPatternFinder(e,t,n,i,r,o,s){this.image=e,this.possibleCenters=[],this.startX=t,this.startY=n,this.width=i,this.height=r,this.moduleSize=o,this.crossCheckStateCount=[0,0,0],this.resultPointCallback=s,this.centerFromEnd=function(e,t){return t-e[2]-e[1]/2},this.foundPatternCross=function(e){for(var t=this.moduleSize,n=t/2,i=0;3>i;i++)if(Math.abs(t-e[i])>=n)return!1;return!0},this.crossCheckVertical=function(e,t,n,i){var r=this.image,o=qrcode.height,s=this.crossCheckStateCount;
+s[0]=0,s[1]=0,s[2]=0;for(var a=e;a>=0&&r[t+a*qrcode.width]&&s[1]<=n;)s[1]++,a--;if(0>a||s[1]>n)return 0/0;for(;a>=0&&!r[t+a*qrcode.width]&&s[0]<=n;)s[0]++,a--;if(s[0]>n)return 0/0;for(a=e+1;o>a&&r[t+a*qrcode.width]&&s[1]<=n;)s[1]++,a++;if(a==o||s[1]>n)return 0/0;for(;o>a&&!r[t+a*qrcode.width]&&s[2]<=n;)s[2]++,a++;return s[2]>n||5*Math.abs(s[0]+s[1]+s[2]-i)>=2*i?0/0:this.foundPatternCross(s)?this.centerFromEnd(s,a):0/0},this.handlePossibleCenter=function(e,t,n){var i=e[0]+e[1]+e[2];if(n=this.centerFromEnd(e,n),t=this.crossCheckVertical(t,Math.floor(n),2*e[1],i),!isNaN(t)){e=(e[0]+e[1]+e[2])/3;for(var i=this.possibleCenters.length,r=0;i>r;r++)if(this.possibleCenters[r].aboutEquals(e,t,n))return new AlignmentPattern(n,t,e);n=new AlignmentPattern(n,t,e),this.possibleCenters.push(n),null!=this.resultPointCallback&&this.resultPointCallback.foundPossibleResultPoint(n)}return null},this.find=function(){for(var t=this.startX,r=this.height,o=t+i,s=n+(r>>1),a=[0,0,0],h=0;r>h;h++){var c=s+(0==(1&h)?h+1>>1:-(h+1>>1));a[0]=0,a[1]=0,a[2]=0;for(var l=t;o>l&&!e[l+qrcode.width*c];)l++;for(var f=0;o>l;){if(e[l+c*qrcode.width])if(1==f)a[f]++;else if(2==f){if(this.foundPatternCross(a)&&(f=this.handlePossibleCenter(a,c,l),null!=f))return f;a[0]=a[2],a[1]=1,a[2]=0,f=1}else a[++f]++;else 1==f&&f++,a[f]++;l++}if(this.foundPatternCross(a)&&(f=this.handlePossibleCenter(a,c,o),null!=f))return f}if(0!=this.possibleCenters.length)return this.possibleCenters[0];throw"Couldn't find enough alignment patterns"}}function QRCodeDataBlockReader(e,t,n){this.blockPointer=0,this.bitPointer=7,this.dataLength=0,this.blocks=e,this.numErrorCorrectionCode=n,9>=t?this.dataLengthMode=0:t>=10&&26>=t?this.dataLengthMode=1:t>=27&&40>=t&&(this.dataLengthMode=2),this.getNextBits=function(e){var t=0;if(et;t++)n+=1<>this.bitPointer-e+1,this.bitPointer-=e,t}if(e>8-(e-(this.bitPointer+1)),this.bitPointer-=e%8,0>this.bitPointer&&(this.bitPointer=8+this.bitPointer),t}if(e>8-(e-(this.bitPointer+1+8))),this.bitPointer-=(e-8)%8,0>this.bitPointer&&(this.bitPointer=8+this.bitPointer),t}return 0},this.NextMode=function(){return this.blockPointer>this.blocks.length-this.numErrorCorrectionCode-2?0:this.getNextBits(4)},this.getDataLength=function(e){for(var t=0;1!=e>>t;)t++;return this.getNextBits(qrcode.sizeOfDataLengthInfo[this.dataLengthMode][t])},this.getRomanAndFigureString=function(e){var t=0,n="",i="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:".split("");do if(e>1){var t=this.getNextBits(11),r=t%45,n=n+i[Math.floor(t/45)],n=n+i[r];e-=2}else 1==e&&(t=this.getNextBits(6),n+=i[t],e-=1);while(e>0);return n},this.getFigureString=function(e){var t=0,n="";do e>=3?(t=this.getNextBits(10),100>t&&(n+="0"),10>t&&(n+="0"),e-=3):2==e?(t=this.getNextBits(7),10>t&&(n+="0"),e-=2):1==e&&(t=this.getNextBits(4),e-=1),n+=t;while(e>0);return n},this.get8bitByteArray=function(e){var t=0,n=[];do t=this.getNextBits(8),n.push(t),e--;while(e>0);return n},this.getKanjiString=function(e){var t=0,n="";do{var t=getNextBits(13),t=(t/192<<8)+t%192,i=0,i=40956>=t+33088?t+33088:t+49472,n=n+String.fromCharCode(i);e--}while(e>0);return n},this.__defineGetter__("DataByte",function(){for(var e=[];;){var t=this.NextMode();if(0==t){if(0dataLength)throw"Invalid data length: "+dataLength;switch(t){case 1:for(var t=this.getFigureString(dataLength),n=Array(t.length),i=0;is||s>n||-1>a||a>i)throw"Error.checkAndNudgePoints ";r=!1,-1==s?(t[o]=0,r=!0):s==n&&(t[o]=n-1,r=!0),-1==a?(t[o+1]=0,r=!0):a==i&&(t[o+1]=i-1,r=!0)}for(r=!0,o=t.Length-2;o>=0&&r;o-=2){if(s=Math.floor(t[o]),a=Math.floor(t[o+1]),-1>s||s>n||-1>a||a>i)throw"Error.checkAndNudgePoints ";r=!1,-1==s?(t[o]=0,r=!0):s==n&&(t[o]=n-1,r=!0),-1==a?(t[o+1]=0,r=!0):a==i&&(t[o+1]=i-1,r=!0)}},sampleGrid3:function(e,t,n){for(var i=new BitMatrix(t),r=Array(t<<1),o=0;t>o;o++){for(var s=r.length,a=o+.5,h=0;s>h;h+=2)r[h]=(h>>1)+.5,r[h+1]=a;n.transformPoints1(r),GridSampler.checkAndNudgePoints(e,r);try{for(h=0;s>h;h+=2){var c=4*Math.floor(r[h])+4*Math.floor(r[h+1])*qrcode.width,l=e[Math.floor(r[h])+qrcode.width*Math.floor(r[h+1])];qrcode.imagedata.data[c]=l?255:0,qrcode.imagedata.data[c+1]=l?255:0,qrcode.imagedata.data[c+2]=0,qrcode.imagedata.data[c+3]=255,l&&i.set_Renamed(h>>1,o)}}catch(f){throw"Error.checkAndNudgePoints"}}return i},sampleGridx:function(e,t,n,i,r,o,s,a,h,c,l,f,d,w,u,C,E,B){return n=PerspectiveTransform.quadrilateralToQuadrilateral(n,i,r,o,s,a,h,c,l,f,d,w,u,C,E,B),GridSampler.sampleGrid3(e,t,n)}},Version.VERSION_DECODE_INFO=[31892,34236,39577,42195,48118,51042,55367,58893,63784,68472,70749,76311,79154,84390,87683,92361,96236,102084,102881,110507,110734,117786,119615,126325,127568,133589,136944,141498,145311,150283,152622,158308,161089,167017],Version.VERSIONS=buildVersions(),Version.getVersionForNumber=function(e){if(1>e||e>40)throw"ArgumentException";return Version.VERSIONS[e-1]},Version.getProvisionalVersionForDimension=function(e){if(1!=e%4)throw"Error getProvisionalVersionForDimension";try{return Version.getVersionForNumber(e-17>>2)}catch(t){throw"Error getVersionForNumber"}},Version.decodeVersionInformation=function(e){for(var t=4294967295,n=0,i=0;ir&&(n=i+7,t=r)}return 3>=t?this.getVersionForNumber(n):null},PerspectiveTransform.quadrilateralToQuadrilateral=function(e,t,n,i,r,o,s,a,h,c,l,f,d,w,u,C){return e=this.quadrilateralToSquare(e,t,n,i,r,o,s,a),this.squareToQuadrilateral(h,c,l,f,d,w,u,C).times(e)},PerspectiveTransform.squareToQuadrilateral=function(e,t,n,i,r,o,s,a){return dy2=a-o,dy3=t-i+o-a,0==dy2&&0==dy3?new PerspectiveTransform(n-e,r-n,e,i-t,o-i,t,0,0,1):(dx1=n-r,dx2=s-r,dx3=e-n+r-s,dy1=i-o,denominator=dx1*dy2-dx2*dy1,a13=(dx3*dy2-dx2*dy3)/denominator,a23=(dx1*dy3-dx3*dy1)/denominator,new PerspectiveTransform(n-e+a13*n,s-e+a23*s,e,i-t+a13*i,a-t+a23*a,t,a13,a23,1))},PerspectiveTransform.quadrilateralToSquare=function(e,t,n,i,r,o,s,a){return this.squareToQuadrilateral(e,t,n,i,r,o,s,a).buildAdjoint()};var FORMAT_INFO_MASK_QR=21522,FORMAT_INFO_DECODE_LOOKUP=[[21522,0],[20773,1],[24188,2],[23371,3],[17913,4],[16590,5],[20375,6],[19104,7],[30660,8],[29427,9],[32170,10],[30877,11],[26159,12],[25368,13],[27713,14],[26998,15],[5769,16],[5054,17],[7399,18],[6608,19],[1890,20],[597,21],[3340,22],[2107,23],[13663,24],[12392,25],[16177,26],[14854,27],[9396,28],[8579,29],[11994,30],[11245,31]],BITS_SET_IN_HALF_BYTE=[0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4];FormatInformation.numBitsDiffering=function(e,t){return e^=t,BITS_SET_IN_HALF_BYTE[15&e]+BITS_SET_IN_HALF_BYTE[15&URShift(e,4)]+BITS_SET_IN_HALF_BYTE[15&URShift(e,8)]+BITS_SET_IN_HALF_BYTE[15&URShift(e,12)]+BITS_SET_IN_HALF_BYTE[15&URShift(e,16)]+BITS_SET_IN_HALF_BYTE[15&URShift(e,20)]+BITS_SET_IN_HALF_BYTE[15&URShift(e,24)]+BITS_SET_IN_HALF_BYTE[15&URShift(e,28)]},FormatInformation.decodeFormatInformation=function(e){var t=FormatInformation.doDecodeFormatInformation(e);return null!=t?t:FormatInformation.doDecodeFormatInformation(e^FORMAT_INFO_MASK_QR)},FormatInformation.doDecodeFormatInformation=function(e){for(var t=4294967295,n=0,i=0;io&&(n=r[1],t=o)}return 3>=t?new FormatInformation(n):null},ErrorCorrectionLevel.forBits=function(e){if(0>e||e>=FOR_BITS.Length)throw"ArgumentException";return FOR_BITS[e]};var L=new ErrorCorrectionLevel(0,1,"L"),M=new ErrorCorrectionLevel(1,0,"M"),Q=new ErrorCorrectionLevel(2,3,"Q"),H=new ErrorCorrectionLevel(3,2,"H"),FOR_BITS=[M,L,H,Q];DataBlock.getDataBlocks=function(e,t,n){if(e.length!=t.TotalCodewords)throw"ArgumentException";var i=t.getECBlocksForLevel(n);n=0;var r=i.getECBlocks();for(t=0;t=0&&n[r].codewords.length!=t;)r--;for(r++,i=t-i.ECCodewordsPerBlock,t=a=0;i>t;t++)for(s=0;o>s;s++)n[s].codewords[t]=e[a++];for(s=r;o>s;s++)n[s].codewords[i]=e[a++];for(h=n[0].codewords.length,t=i;h>t;t++)for(s=0;o>s;s++)n[s].codewords[r>s?t:t+1]=e[a++];return n},DataMask={forReference:function(e){if(0>e||e>7)throw"System.ArgumentException";return DataMask.DATA_MASKS[e]}},DataMask.DATA_MASKS=[new DataMask000,new DataMask001,new DataMask010,new DataMask011,new DataMask100,new DataMask101,new DataMask110,new DataMask111],GF256.QR_CODE_FIELD=new GF256(285),GF256.DATA_MATRIX_FIELD=new GF256(301),GF256.addOrSubtract=function(e,t){return e^t},Decoder={},Decoder.rsDecoder=new ReedSolomonDecoder(GF256.QR_CODE_FIELD),Decoder.correctErrors=function(e,t){for(var n=e.length,i=Array(n),r=0;n>r;r++)i[r]=255&e[r];n=e.length-t;try{Decoder.rsDecoder.decode(i,n)}catch(o){throw o}for(r=0;t>r;r++)e[r]=i[r]},Decoder.decode=function(e){var t=new BitMatrixParser(e);e=t.readVersion();for(var n=t.readFormatInformation().ErrorCorrectionLevel,t=t.readCodewords(),t=DataBlock.getDataBlocks(t,e,n),i=0,r=0;rr;r++)i[o++]=a[r]}return new QRCodeDataBlockReader(i,e.VersionNumber,n.Bits)},qrcode={imagedata:null,width:0,height:0,qrCodeSymbol:null,debug:!1,sizeOfDataLengthInfo:[[10,9,8,8],[12,11,16,10],[14,13,16,12]],callback:null,decode:function(e){if(0==arguments.length){var t=document.getElementById("qr-canvas"),n=t.getContext("2d");return qrcode.width=t.width,qrcode.height=t.height,qrcode.imagedata=n.getImageData(0,0,qrcode.width,qrcode.height),qrcode.result=qrcode.process(n),null!=qrcode.callback&&qrcode.callback(qrcode.result),qrcode.result}var i=new Image;i.onload=function(){var e=document.createElement("canvas"),t=e.getContext("2d"),n=document.getElementById("out-canvas");null!=n&&(n=n.getContext("2d"),n.clearRect(0,0,320,240),n.drawImage(i,0,0,320,240)),e.width=i.width,e.height=i.height,t.drawImage(i,0,0),qrcode.width=i.width,qrcode.height=i.height;try{qrcode.imagedata=t.getImageData(0,0,i.width,i.height)}catch(r){return qrcode.result="Cross domain image reading not supported in your browser! Save it to your computer then drag and drop the file!",void(null!=qrcode.callback&&qrcode.callback(qrcode.result))}try{qrcode.result=qrcode.process(t)}catch(o){console.log(o),qrcode.result="error decoding QR Code"}null!=qrcode.callback&&qrcode.callback(qrcode.result)},i.src=e},decode_utf8:function(e){return decodeURIComponent(escape(e))},process:function(e){var t=(new Date).getTime(),n=qrcode.grayScaleToBitmap(qrcode.grayscale());if(qrcode.debug){for(var i=0;i=r?!0:!1}return t},getMiddleBrightnessPerArea:function(e){for(var t=Math.floor(qrcode.width/4),n=Math.floor(qrcode.height/4),i=Array(4),r=0;4>r;r++){i[r]=Array(4);for(var o=0;4>o;o++)i[r][o]=[0,0]}for(r=0;4>r;r++)for(o=0;4>o;o++){i[o][r][0]=255;for(var s=0;n>s;s++)for(var a=0;t>a;a++){var h=e[t*o+a+(n*r+s)*qrcode.width];hi[o][r][1]&&(i[o][r][1]=h)}}for(e=Array(4),t=0;4>t;t++)e[t]=Array(4);for(r=0;4>r;r++)for(o=0;4>o;o++)e[o][r]=Math.floor((i[o][r][0]+i[o][r][1])/2);return e},grayScaleToBitmap:function(e){for(var t=qrcode.getMiddleBrightnessPerArea(e),n=t.length,i=Math.floor(qrcode.width/n),r=Math.floor(qrcode.height/n),o=Array(qrcode.height*qrcode.width),s=0;n>s;s++)for(var a=0;n>a;a++)for(var h=0;r>h;h++)for(var c=0;i>c;c++)o[i*a+c+(r*s+h)*qrcode.width]=e[i*a+c+(r*s+h)*qrcode.width]e?this.length+e:e,this.push.apply(this,n)};var MIN_SKIP=3,MAX_MODULES=57,INTEGER_MATH_SHIFT=8,CENTER_QUORUM=2;qrcode.orderBestPatterns=function(e){function t(e,t){return xDiff=e.X-t.X,yDiff=e.Y-t.Y,Math.sqrt(xDiff*xDiff+yDiff*yDiff)}var n=t(e[0],e[1]),i=t(e[1],e[2]),r=t(e[0],e[2]);i>=n&&i>=r?(i=e[0],n=e[1],r=e[2]):r>=i&&r>=n?(i=e[1],n=e[0],r=e[2]):(i=e[2],n=e[0],r=e[1]);var o=i.x,s=i.y;0>(r.x-o)*(n.y-s)-(r.y-s)*(n.x-o)&&(o=n,n=r,r=o),e[0]=n,e[1]=i,e[2]=r};
+
+function _instanceof(left,right){if(right!=null&&typeof Symbol!=="undefined"&&right[Symbol.hasInstance]){return!!right[Symbol.hasInstance](left)}else{return left instanceof right}}
+function _classCallCheck(instance,Constructor){if(!_instanceof(instance,Constructor)){throw new TypeError("Cannot call a class as a function")}}
+function _defineProperties(target,props){for(var i=0;i=tracksToClose){onAllTracksClosed()}})})}},{key:"_createCanvasElement",value:function _createCanvasElement(width,height){var canvasWidth=width;var canvasHeight=height;var canvasElement=document.createElement('canvas');canvasElement.style.width="".concat(canvasWidth,"px");canvasElement.style.height="".concat(canvasHeight,"px");canvasElement.style.display="none";canvasElement.id='qr-canvas';return canvasElement}},{key:"_createVideoElement",value:function _createVideoElement(width,height){var videoElement=document.createElement('video');videoElement.style.height="".concat(height,"px");videoElement.style.width="".concat(width,"px");return videoElement}}],[{key:"getCameras",value:function getCameras(){var _this=this;return new Promise(function(resolve,reject){if(navigator.mediaDevices&&navigator.mediaDevices.enumerateDevices&&navigator.mediaDevices.getUserMedia){_this._log("navigator.mediaDevices used");navigator.mediaDevices.getUserMedia({audio:!1,video:!0}).then(function(ignore){navigator.mediaDevices.enumerateDevices().then(function(devices){var results=[];for(var i=0;ii;i++)for(var r=this.alignmentPatternCenters[i]-2,o=0;n>o;o++)0==i&&(0==o||o==n-1)||i==n-1&&0==o||t.setRegion(this.alignmentPatternCenters[o]-2,r,5,5);return t.setRegion(6,9,1,e-17),t.setRegion(9,6,e-17,1),6f;f+=2){var d=e[f],w=e[f+1],u=r*d+a*w+l;e[f]=(n*d+o*w+h)/u,e[f+1]=(i*d+s*w+c)/u}},this.transformPoints2=function(e,t){for(var n=e.length,i=0;n>i;i++){var r=e[i],o=t[i],s=this.a13*r+this.a23*o+this.a33;e[i]=(this.a11*r+this.a21*o+this.a31)/s,t[i]=(this.a12*r+this.a22*o+this.a32)/s}},this.buildAdjoint=function(){return new PerspectiveTransform(this.a22*this.a33-this.a23*this.a32,this.a23*this.a31-this.a21*this.a33,this.a21*this.a32-this.a22*this.a31,this.a13*this.a32-this.a12*this.a33,this.a11*this.a33-this.a13*this.a31,this.a12*this.a31-this.a11*this.a32,this.a12*this.a23-this.a13*this.a22,this.a13*this.a21-this.a11*this.a23,this.a11*this.a22-this.a12*this.a21)},this.times=function(e){return new PerspectiveTransform(this.a11*e.a11+this.a21*e.a12+this.a31*e.a13,this.a11*e.a21+this.a21*e.a22+this.a31*e.a23,this.a11*e.a31+this.a21*e.a32+this.a31*e.a33,this.a12*e.a11+this.a22*e.a12+this.a32*e.a13,this.a12*e.a21+this.a22*e.a22+this.a32*e.a23,this.a12*e.a31+this.a22*e.a32+this.a32*e.a33,this.a13*e.a11+this.a23*e.a12+this.a33*e.a13,this.a13*e.a21+this.a23*e.a22+this.a33*e.a23,this.a13*e.a31+this.a23*e.a32+this.a33*e.a33)}}function DetectorResult(e,t){this.bits=e,this.points=t}function Detector(e){this.image=e,this.resultPointCallback=null,this.sizeOfBlackWhiteBlackRun=function(e,t,n,i){var r=Math.abs(i-t)>Math.abs(n-e);if(r){var o=e;e=t,t=o,o=n,n=i,i=o}for(var s=Math.abs(n-e),a=Math.abs(i-t),h=-s>>1,c=i>t?1:-1,l=n>e?1:-1,f=0,d=e,o=t;d!=n;d+=l){var w=r?o:d,u=r?d:o;if(1==f?this.image[w+u*qrcode.width]&&f++:this.image[w+u*qrcode.width]||f++,3==f)return i=d-e,t=o-t,Math.sqrt(i*i+t*t);if(h+=a,h>0){if(o==i)break;o+=c,h-=s}}return e=n-e,t=i-t,Math.sqrt(e*e+t*t)},this.sizeOfBlackWhiteBlackRunBothWays=function(e,t,n,i){var r=this.sizeOfBlackWhiteBlackRun(e,t,n,i),o=1;return n=e-(n-e),0>n?(o=e/(e-n),n=0):n>=qrcode.width&&(o=(qrcode.width-1-e)/(n-e),n=qrcode.width-1),i=Math.floor(t-(i-t)*o),o=1,0>i?(o=t/(t-i),i=0):i>=qrcode.height&&(o=(qrcode.height-1-t)/(i-t),i=qrcode.height-1),n=Math.floor(e+(n-e)*o),r+=this.sizeOfBlackWhiteBlackRun(e,t,n,i),r-1},this.calculateModuleSizeOneWay=function(e,t){var n=this.sizeOfBlackWhiteBlackRunBothWays(Math.floor(e.X),Math.floor(e.Y),Math.floor(t.X),Math.floor(t.Y)),i=this.sizeOfBlackWhiteBlackRunBothWays(Math.floor(t.X),Math.floor(t.Y),Math.floor(e.X),Math.floor(e.Y));return isNaN(n)?i/7:isNaN(i)?n/7:(n+i)/14},this.calculateModuleSize=function(e,t,n){return(this.calculateModuleSizeOneWay(e,t)+this.calculateModuleSizeOneWay(e,n))/2},this.distance=function(e,t){return xDiff=e.X-t.X,yDiff=e.Y-t.Y,Math.sqrt(xDiff*xDiff+yDiff*yDiff)},this.computeDimension=function(e,t,n,i){switch(t=Math.round(this.distance(e,t)/i),e=Math.round(this.distance(e,n)/i),e=(t+e>>1)+7,3&e){case 0:e++;break;case 2:e--;break;case 3:throw"Error"}return e},this.findAlignmentInRegion=function(e,t,n,i){var r=Math.floor(i*e);if(i=Math.max(0,t-r),t=Math.min(qrcode.width-1,t+r),3*e>t-i)throw"Error";var o=Math.max(0,n-r);return n=Math.min(qrcode.height-1,n+r),new AlignmentPatternFinder(this.image,i,o,t-i,n-o,e,this.resultPointCallback).find()},this.createTransform=function(e,t,n,i,r){r-=3.5;var o,s,a;return null!=i?(o=i.X,i=i.Y,s=a=r-3):(o=t.X-e.X+n.X,i=t.Y-e.Y+n.Y,s=a=r),PerspectiveTransform.quadrilateralToQuadrilateral(3.5,3.5,r,3.5,s,a,3.5,r,e.X,e.Y,t.X,t.Y,o,i,n.X,n.Y)},this.sampleGrid=function(e,t,n){return GridSampler.sampleGrid3(e,n,t)},this.processFinderPatternInfo=function(e){var t=e.TopLeft,n=e.TopRight;e=e.BottomLeft;var i=this.calculateModuleSize(t,n,e);if(1>i)throw"Error";var r=this.computeDimension(t,n,e,i),o=Version.getProvisionalVersionForDimension(r),s=o.DimensionForVersion-7,a=null;if(0>3&3),this.dataMask=7&e,this.__defineGetter__("ErrorCorrectionLevel",function(){return this.errorCorrectionLevel}),this.__defineGetter__("DataMask",function(){return this.dataMask}),this.GetHashCode=function(){return this.errorCorrectionLevel.ordinal()<<3|dataMask},this.Equals=function(e){return this.errorCorrectionLevel==e.errorCorrectionLevel&&this.dataMask==e.dataMask}}function ErrorCorrectionLevel(e,t,n){this.ordinal_Renamed_Field=e,this.bits=t,this.name=n,this.__defineGetter__("Bits",function(){return this.bits}),this.__defineGetter__("Name",function(){return this.name}),this.ordinal=function(){return this.ordinal_Renamed_Field}}function BitMatrix(e,t){if(t||(t=e),1>e||1>t)throw"Both dimensions must be greater than 0";this.width=e,this.height=t;var n=e>>5;for(0!=(31&e)&&n++,this.rowSize=n,this.bits=Array(n*t),n=0;n>5)],31&e))},this.set_Renamed=function(e,t){this.bits[t*this.rowSize+(e>>5)]|=1<<(31&e)},this.flip=function(e,t){this.bits[t*this.rowSize+(e>>5)]^=1<<(31&e)},this.clear=function(){for(var e=this.bits.length,t=0;e>t;t++)this.bits[t]=0},this.setRegion=function(e,t,n,i){if(0>t||0>e)throw"Left and top must be nonnegative";if(1>i||1>n)throw"Height and width must be at least 1";if(n=e+n,i=t+i,i>this.height||n>this.width)throw"The region must fit inside the matrix";for(;i>t;t++)for(var r=t*this.rowSize,o=e;n>o;o++)this.bits[r+(o>>5)]|=1<<(31&o)}}function DataBlock(e,t){this.numDataCodewords=e,this.codewords=t,this.__defineGetter__("NumDataCodewords",function(){return this.numDataCodewords}),this.__defineGetter__("Codewords",function(){return this.codewords})}function BitMatrixParser(e){var t=e.Dimension;if(21>t||1!=(3&t))throw"Error BitMatrixParser";this.bitMatrix=e,this.parsedFormatInfo=this.parsedVersion=null,this.copyBit=function(e,t,n){return this.bitMatrix.get_Renamed(e,t)?n<<1|1:n<<1},this.readFormatInformation=function(){if(null!=this.parsedFormatInfo)return this.parsedFormatInfo;for(var e=0,t=0;6>t;t++)e=this.copyBit(t,8,e);for(e=this.copyBit(7,8,e),e=this.copyBit(8,8,e),e=this.copyBit(8,7,e),t=5;t>=0;t--)e=this.copyBit(8,t,e);if(this.parsedFormatInfo=FormatInformation.decodeFormatInformation(e),null!=this.parsedFormatInfo)return this.parsedFormatInfo;for(var n=this.bitMatrix.Dimension,e=0,i=n-8,t=n-1;t>=i;t--)e=this.copyBit(t,8,e);for(t=n-7;n>t;t++)e=this.copyBit(8,t,e);if(this.parsedFormatInfo=FormatInformation.decodeFormatInformation(e),null!=this.parsedFormatInfo)return this.parsedFormatInfo;throw"Error readFormatInformation"},this.readVersion=function(){if(null!=this.parsedVersion)return this.parsedVersion;var e=this.bitMatrix.Dimension,t=e-17>>2;if(6>=t)return Version.getVersionForNumber(t);for(var t=0,n=e-11,i=5;i>=0;i--)for(var r=e-9;r>=n;r--)t=this.copyBit(r,i,t);if(this.parsedVersion=Version.decodeVersionInformation(t),null!=this.parsedVersion&&this.parsedVersion.DimensionForVersion==e)return this.parsedVersion;for(t=0,r=5;r>=0;r--)for(i=e-9;i>=n;i--)t=this.copyBit(r,i,t);if(this.parsedVersion=Version.decodeVersionInformation(t),null!=this.parsedVersion&&this.parsedVersion.DimensionForVersion==e)return this.parsedVersion;throw"Error readVersion"},this.readCodewords=function(){var e=this.readFormatInformation(),t=this.readVersion(),n=DataMask.forReference(e.DataMask),e=this.bitMatrix.Dimension;n.unmaskBitMatrix(this.bitMatrix,e);for(var n=t.buildFunctionPattern(),i=!0,r=Array(t.TotalCodewords),o=0,s=0,a=0,h=e-1;h>0;h-=2){6==h&&h--;for(var c=0;e>c;c++)for(var l=i?e-1-c:c,f=0;2>f;f++)n.get_Renamed(h-f,l)||(a++,s<<=1,this.bitMatrix.get_Renamed(h-f,l)&&(s|=1),8==a&&(r[o++]=s,s=a=0));i^=1}if(o!=t.TotalCodewords)throw"Error readCodewords";return r}}function DataMask000(){this.unmaskBitMatrix=function(e,t){for(var n=0;t>n;n++)for(var i=0;t>i;i++)this.isMasked(n,i)&&e.flip(i,n)},this.isMasked=function(e,t){return 0==(e+t&1)}}function DataMask001(){this.unmaskBitMatrix=function(e,t){for(var n=0;t>n;n++)for(var i=0;t>i;i++)this.isMasked(n,i)&&e.flip(i,n)},this.isMasked=function(e){return 0==(1&e)}}function DataMask010(){this.unmaskBitMatrix=function(e,t){for(var n=0;t>n;n++)for(var i=0;t>i;i++)this.isMasked(n,i)&&e.flip(i,n)},this.isMasked=function(e,t){return 0==t%3}}function DataMask011(){this.unmaskBitMatrix=function(e,t){for(var n=0;t>n;n++)for(var i=0;t>i;i++)this.isMasked(n,i)&&e.flip(i,n)},this.isMasked=function(e,t){return 0==(e+t)%3}}function DataMask100(){this.unmaskBitMatrix=function(e,t){for(var n=0;t>n;n++)for(var i=0;t>i;i++)this.isMasked(n,i)&&e.flip(i,n)},this.isMasked=function(e,t){return 0==(URShift(e,1)+t/3&1)}}function DataMask101(){this.unmaskBitMatrix=function(e,t){for(var n=0;t>n;n++)for(var i=0;t>i;i++)this.isMasked(n,i)&&e.flip(i,n)},this.isMasked=function(e,t){var n=e*t;return 0==(1&n)+n%3}}function DataMask110(){this.unmaskBitMatrix=function(e,t){for(var n=0;t>n;n++)for(var i=0;t>i;i++)this.isMasked(n,i)&&e.flip(i,n)},this.isMasked=function(e,t){var n=e*t;return 0==((1&n)+n%3&1)}}function DataMask111(){this.unmaskBitMatrix=function(e,t){for(var n=0;t>n;n++)for(var i=0;t>i;i++)this.isMasked(n,i)&&e.flip(i,n)},this.isMasked=function(e,t){return 0==((e+t&1)+e*t%3&1)}}function ReedSolomonDecoder(e){this.field=e,this.decode=function(e,t){for(var n=new GF256Poly(this.field,e),i=Array(t),r=0;rr;r++){var s=n.evaluateAt(this.field.exp(r));i[i.length-1-r]=s,0!=s&&(o=!1)}if(!o)for(r=new GF256Poly(this.field,i),n=this.runEuclideanAlgorithm(this.field.buildMonomial(t,1),r,t),r=n[1],n=this.findErrorLocations(n[0]),i=this.findErrorMagnitudes(r,n,!1),r=0;ro)throw"ReedSolomonException Bad error location";e[o]=GF256.addOrSubtract(e[o],i[r])}},this.runEuclideanAlgorithm=function(e,t,n){if(e.Degree=Math.floor(n/2);){var a=e,h=i,c=o;if(e=t,i=r,o=s,e.Zero)throw"r_{i-1} was zero";for(t=a,s=this.field.Zero,r=e.getCoefficient(e.Degree),r=this.field.inverse(r);t.Degree>=e.Degree&&!t.Zero;){var a=t.Degree-e.Degree,l=this.field.multiply(t.getCoefficient(t.Degree),r),s=s.addOrSubtract(this.field.buildMonomial(a,l));t=t.addOrSubtract(e.multiplyByMonomial(a,l))}r=s.multiply1(i).addOrSubtract(h),s=s.multiply1(o).addOrSubtract(c)}if(n=s.getCoefficient(0),0==n)throw"ReedSolomonException sigmaTilde(0) was zero";return n=this.field.inverse(n),e=s.multiply2(n),n=t.multiply2(n),[e,n]},this.findErrorLocations=function(e){var t=e.Degree;if(1==t)return Array(e.getCoefficient(1));for(var n=Array(t),i=0,r=1;256>r&&t>i;r++)0==e.evaluateAt(r)&&(n[i]=this.field.inverse(r),i++);if(i!=t)throw"Error locator degree does not match number of roots";return n},this.findErrorMagnitudes=function(e,t,n){for(var i=t.length,r=Array(i),o=0;i>o;o++){for(var s=this.field.inverse(t[o]),a=1,h=0;i>h;h++)o!=h&&(a=this.field.multiply(a,GF256.addOrSubtract(1,this.field.multiply(t[h],s))));r[o]=this.field.multiply(e.evaluateAt(s),this.field.inverse(a)),n&&(r[o]=this.field.multiply(r[o],s))}return r}}function GF256Poly(e,t){if(null==t||0==t.length)throw"System.ArgumentException";this.field=e;var n=t.length;if(n>1&&0==t[0]){for(var i=1;n>i&&0==t[i];)i++;if(i==n)this.coefficients=e.Zero.coefficients;else{for(this.coefficients=Array(n-i),n=0;nn;n++)e=GF256.addOrSubtract(e,this.coefficients[n]);return e}for(var i=this.coefficients[0],n=1;t>n;n++)i=GF256.addOrSubtract(this.field.multiply(e,i),this.coefficients[n]);return i},this.addOrSubtract=function(t){if(this.field!=t.field)throw"GF256Polys do not have same GF256 field";if(this.Zero)return t;if(t.Zero)return this;var n=this.coefficients;if(t=t.coefficients,n.length>t.length){var i=n,n=t;t=i}for(var i=Array(t.length),r=t.length-n.length,o=0;r>o;o++)i[o]=t[o];for(o=r;oo;o++)for(var s=t[o],a=0;i>a;a++)r[o+a]=GF256.addOrSubtract(r[o+a],this.field.multiply(s,e[a]));return new GF256Poly(this.field,r)},this.multiply2=function(e){if(0==e)return this.field.Zero;if(1==e)return this;for(var t=this.coefficients.length,n=Array(t),i=0;t>i;i++)n[i]=this.field.multiply(this.coefficients[i],e);return new GF256Poly(this.field,n)},this.multiplyByMonomial=function(e,t){if(0>e)throw"System.ArgumentException";if(0==t)return this.field.Zero;for(var n=this.coefficients.length,i=Array(n+e),r=0;rr;r++)i[r]=this.field.multiply(this.coefficients[r],t);return new GF256Poly(this.field,i)},this.divide=function(e){if(this.field!=e.field)throw"GF256Polys do not have same GF256 field";if(e.Zero)throw"Divide by 0";for(var t=this.field.Zero,n=this,i=e.getCoefficient(e.Degree),i=this.field.inverse(i);n.Degree>=e.Degree&&!n.Zero;)var r=n.Degree-e.Degree,o=this.field.multiply(n.getCoefficient(n.Degree),i),s=e.multiplyByMonomial(r,o),r=this.field.buildMonomial(r,o),t=t.addOrSubtract(r),n=n.addOrSubtract(s);return[t,n]}}function GF256(e){this.expTable=Array(256),this.logTable=Array(256);for(var t=1,n=0;256>n;n++)this.expTable[n]=t,t<<=1,t>=256&&(t^=e);for(n=0;255>n;n++)this.logTable[this.expTable[n]]=n;e=Array(1),e[0]=0,this.zero=new GF256Poly(this,Array(e)),e=Array(1),e[0]=1,this.one=new GF256Poly(this,Array(e)),this.__defineGetter__("Zero",function(){return this.zero}),this.__defineGetter__("One",function(){return this.one}),this.buildMonomial=function(e,t){if(0>e)throw"System.ArgumentException";if(0==t)return zero;for(var n=Array(e+1),i=0;i=0?e>>t:(e>>t)+(2<<~t)}function FinderPattern(e,t,n){this.x=e,this.y=t,this.count=1,this.estimatedModuleSize=n,this.__defineGetter__("EstimatedModuleSize",function(){return this.estimatedModuleSize}),this.__defineGetter__("Count",function(){return this.count}),this.__defineGetter__("X",function(){return this.x}),this.__defineGetter__("Y",function(){return this.y}),this.incrementCount=function(){this.count++},this.aboutEquals=function(e,t,n){return Math.abs(t-this.y)<=e&&Math.abs(n-this.x)<=e?(e=Math.abs(e-this.estimatedModuleSize),1>=e||1>=e/this.estimatedModuleSize):!1}}function FinderPatternInfo(e){this.bottomLeft=e[0],this.topLeft=e[1],this.topRight=e[2],this.__defineGetter__("BottomLeft",function(){return this.bottomLeft}),this.__defineGetter__("TopLeft",function(){return this.topLeft}),this.__defineGetter__("TopRight",function(){return this.topRight})}function FinderPatternFinder(){this.image=null,this.possibleCenters=[],this.hasSkipped=!1,this.crossCheckStateCount=[0,0,0,0,0],this.resultPointCallback=null,this.__defineGetter__("CrossCheckStateCount",function(){return this.crossCheckStateCount[0]=0,this.crossCheckStateCount[1]=0,this.crossCheckStateCount[2]=0,this.crossCheckStateCount[3]=0,this.crossCheckStateCount[4]=0,this.crossCheckStateCount}),this.foundPatternCross=function(e){for(var t=0,n=0;5>n;n++){var i=e[n];if(0==i)return!1;t+=i}return 7>t?!1:(t=Math.floor((t<=0&&r[t+a*qrcode.width];)s[2]++,a--;if(0>a)return 0/0;for(;a>=0&&!r[t+a*qrcode.width]&&s[1]<=n;)s[1]++,a--;if(0>a||s[1]>n)return 0/0;for(;a>=0&&r[t+a*qrcode.width]&&s[0]<=n;)s[0]++,a--;if(s[0]>n)return 0/0;for(a=e+1;o>a&&r[t+a*qrcode.width];)s[2]++,a++;if(a==o)return 0/0;for(;o>a&&!r[t+a*qrcode.width]&&s[3]=n)return 0/0;for(;o>a&&r[t+a*qrcode.width]&&s[4]=n||5*Math.abs(s[0]+s[1]+s[2]+s[3]+s[4]-i)>=2*i?0/0:this.foundPatternCross(s)?this.centerFromEnd(s,a):0/0},this.crossCheckHorizontal=function(e,t,n,i){for(var r=this.image,o=qrcode.width,s=this.CrossCheckStateCount,a=e;a>=0&&r[a+t*qrcode.width];)s[2]++,a--;if(0>a)return 0/0;for(;a>=0&&!r[a+t*qrcode.width]&&s[1]<=n;)s[1]++,a--;if(0>a||s[1]>n)return 0/0;for(;a>=0&&r[a+t*qrcode.width]&&s[0]<=n;)s[0]++,a--;if(s[0]>n)return 0/0;for(a=e+1;o>a&&r[a+t*qrcode.width];)s[2]++,a++;if(a==o)return 0/0;for(;o>a&&!r[a+t*qrcode.width]&&s[3]=n)return 0/0;for(;o>a&&r[a+t*qrcode.width]&&s[4]=n||5*Math.abs(s[0]+s[1]+s[2]+s[3]+s[4]-i)>=i?0/0:this.foundPatternCross(s)?this.centerFromEnd(s,a):0/0},this.handlePossibleCenter=function(e,t,n){var i=e[0]+e[1]+e[2]+e[3]+e[4];if(n=this.centerFromEnd(e,n),t=this.crossCheckVertical(t,Math.floor(n),e[2],i),!isNaN(t)&&(n=this.crossCheckHorizontal(Math.floor(n),Math.floor(t),e[2],i),!isNaN(n))){e=i/7;for(var i=!1,r=this.possibleCenters.length,o=0;r>o;o++){var s=this.possibleCenters[o];if(s.aboutEquals(e,t,n)){s.incrementCount(),i=!0;break}}return i||(n=new FinderPattern(n,t,e),this.possibleCenters.push(n),null!=this.resultPointCallback&&this.resultPointCallback.foundPossibleResultPoint(n)),!0}return!1},this.selectBestPatterns=function(){var e=this.possibleCenters.length;if(3>e)throw"Couldn't find enough finder patterns";if(e>3){for(var t=0,n=0;e>n;n++)t+=this.possibleCenters[n].EstimatedModuleSize;for(e=t/e,n=0;n.2*e&&(this.possibleCenters.remove(n),n--)}return[this.possibleCenters[0],this.possibleCenters[1],this.possibleCenters[2]]},this.findRowSkip=function(){var e=this.possibleCenters.length;if(1>=e)return 0;for(var t=null,n=0;e>n;n++){var i=this.possibleCenters[n];if(i.Count>=CENTER_QUORUM){if(null!=t)return this.hasSkipped=!0,Math.floor((Math.abs(t.X-i.X)-Math.abs(t.Y-i.Y))/2);t=i}}return 0},this.haveMultiplyConfirmedCenters=function(){for(var e=0,t=0,n=this.possibleCenters.length,i=0;n>i;i++){var r=this.possibleCenters[i];r.Count>=CENTER_QUORUM&&(e++,t+=r.EstimatedModuleSize)}if(3>e)return!1;for(var e=t/n,o=0,i=0;n>i;i++)r=this.possibleCenters[i],o+=Math.abs(r.EstimatedModuleSize-e);return.05*t>=o},this.findFinderPattern=function(e){this.image=e;var t=qrcode.height,n=qrcode.width,i=Math.floor(3*t/(4*MAX_MODULES));MIN_SKIP>i&&(i=MIN_SKIP);for(var r=!1,o=Array(5),s=i-1;t>s&&!r;s+=i){o[0]=0,o[1]=0,o[2]=0,o[3]=0;for(var a=o[4]=0,h=0;n>h;h++)if(e[h+s*qrcode.width])1==(1&a)&&a++,o[a]++;else if(0==(1&a))if(4==a)if(this.foundPatternCross(o)){if(a=this.handlePossibleCenter(o,s,h))i=2,this.hasSkipped?r=this.haveMultiplyConfirmedCenters():(a=this.findRowSkip(),a>o[2]&&(s+=a-o[2]-i,h=n-1));else{do h++;while(n>h&&!e[h+s*qrcode.width]);h--}a=0,o[0]=0,o[1]=0,o[2]=0,o[3]=0,o[4]=0}else o[0]=o[2],o[1]=o[3],o[2]=o[4],o[3]=1,o[4]=0,a=3;else o[++a]++;else o[a]++;this.foundPatternCross(o)&&this.handlePossibleCenter(o,s,n)&&(i=o[0],this.hasSkipped&&(r=haveMultiplyConfirmedCenters()))}return e=this.selectBestPatterns(),qrcode.orderBestPatterns(e),new FinderPatternInfo(e)}}function AlignmentPattern(e,t,n){this.x=e,this.y=t,this.count=1,this.estimatedModuleSize=n,this.__defineGetter__("EstimatedModuleSize",function(){return this.estimatedModuleSize}),this.__defineGetter__("Count",function(){return this.count}),this.__defineGetter__("X",function(){return Math.floor(this.x)}),this.__defineGetter__("Y",function(){return Math.floor(this.y)}),this.incrementCount=function(){this.count++},this.aboutEquals=function(e,t,n){return Math.abs(t-this.y)<=e&&Math.abs(n-this.x)<=e?(e=Math.abs(e-this.estimatedModuleSize),1>=e||1>=e/this.estimatedModuleSize):!1}}function AlignmentPatternFinder(e,t,n,i,r,o,s){this.image=e,this.possibleCenters=[],this.startX=t,this.startY=n,this.width=i,this.height=r,this.moduleSize=o,this.crossCheckStateCount=[0,0,0],this.resultPointCallback=s,this.centerFromEnd=function(e,t){return t-e[2]-e[1]/2},this.foundPatternCross=function(e){for(var t=this.moduleSize,n=t/2,i=0;3>i;i++)if(Math.abs(t-e[i])>=n)return!1;return!0},this.crossCheckVertical=function(e,t,n,i){var r=this.image,o=qrcode.height,s=this.crossCheckStateCount;
-s[0]=0,s[1]=0,s[2]=0;for(var a=e;a>=0&&r[t+a*qrcode.width]&&s[1]<=n;)s[1]++,a--;if(0>a||s[1]>n)return 0/0;for(;a>=0&&!r[t+a*qrcode.width]&&s[0]<=n;)s[0]++,a--;if(s[0]>n)return 0/0;for(a=e+1;o>a&&r[t+a*qrcode.width]&&s[1]<=n;)s[1]++,a++;if(a==o||s[1]>n)return 0/0;for(;o>a&&!r[t+a*qrcode.width]&&s[2]<=n;)s[2]++,a++;return s[2]>n||5*Math.abs(s[0]+s[1]+s[2]-i)>=2*i?0/0:this.foundPatternCross(s)?this.centerFromEnd(s,a):0/0},this.handlePossibleCenter=function(e,t,n){var i=e[0]+e[1]+e[2];if(n=this.centerFromEnd(e,n),t=this.crossCheckVertical(t,Math.floor(n),2*e[1],i),!isNaN(t)){e=(e[0]+e[1]+e[2])/3;for(var i=this.possibleCenters.length,r=0;i>r;r++)if(this.possibleCenters[r].aboutEquals(e,t,n))return new AlignmentPattern(n,t,e);n=new AlignmentPattern(n,t,e),this.possibleCenters.push(n),null!=this.resultPointCallback&&this.resultPointCallback.foundPossibleResultPoint(n)}return null},this.find=function(){for(var t=this.startX,r=this.height,o=t+i,s=n+(r>>1),a=[0,0,0],h=0;r>h;h++){var c=s+(0==(1&h)?h+1>>1:-(h+1>>1));a[0]=0,a[1]=0,a[2]=0;for(var l=t;o>l&&!e[l+qrcode.width*c];)l++;for(var f=0;o>l;){if(e[l+c*qrcode.width])if(1==f)a[f]++;else if(2==f){if(this.foundPatternCross(a)&&(f=this.handlePossibleCenter(a,c,l),null!=f))return f;a[0]=a[2],a[1]=1,a[2]=0,f=1}else a[++f]++;else 1==f&&f++,a[f]++;l++}if(this.foundPatternCross(a)&&(f=this.handlePossibleCenter(a,c,o),null!=f))return f}if(0!=this.possibleCenters.length)return this.possibleCenters[0];throw"Couldn't find enough alignment patterns"}}function QRCodeDataBlockReader(e,t,n){this.blockPointer=0,this.bitPointer=7,this.dataLength=0,this.blocks=e,this.numErrorCorrectionCode=n,9>=t?this.dataLengthMode=0:t>=10&&26>=t?this.dataLengthMode=1:t>=27&&40>=t&&(this.dataLengthMode=2),this.getNextBits=function(e){var t=0;if(et;t++)n+=1<>this.bitPointer-e+1,this.bitPointer-=e,t}if(e>8-(e-(this.bitPointer+1)),this.bitPointer-=e%8,0>this.bitPointer&&(this.bitPointer=8+this.bitPointer),t}if(e>8-(e-(this.bitPointer+1+8))),this.bitPointer-=(e-8)%8,0>this.bitPointer&&(this.bitPointer=8+this.bitPointer),t}return 0},this.NextMode=function(){return this.blockPointer>this.blocks.length-this.numErrorCorrectionCode-2?0:this.getNextBits(4)},this.getDataLength=function(e){for(var t=0;1!=e>>t;)t++;return this.getNextBits(qrcode.sizeOfDataLengthInfo[this.dataLengthMode][t])},this.getRomanAndFigureString=function(e){var t=0,n="",i="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:".split("");do if(e>1){var t=this.getNextBits(11),r=t%45,n=n+i[Math.floor(t/45)],n=n+i[r];e-=2}else 1==e&&(t=this.getNextBits(6),n+=i[t],e-=1);while(e>0);return n},this.getFigureString=function(e){var t=0,n="";do e>=3?(t=this.getNextBits(10),100>t&&(n+="0"),10>t&&(n+="0"),e-=3):2==e?(t=this.getNextBits(7),10>t&&(n+="0"),e-=2):1==e&&(t=this.getNextBits(4),e-=1),n+=t;while(e>0);return n},this.get8bitByteArray=function(e){var t=0,n=[];do t=this.getNextBits(8),n.push(t),e--;while(e>0);return n},this.getKanjiString=function(e){var t=0,n="";do{var t=getNextBits(13),t=(t/192<<8)+t%192,i=0,i=40956>=t+33088?t+33088:t+49472,n=n+String.fromCharCode(i);e--}while(e>0);return n},this.__defineGetter__("DataByte",function(){for(var e=[];;){var t=this.NextMode();if(0==t){if(0dataLength)throw"Invalid data length: "+dataLength;switch(t){case 1:for(var t=this.getFigureString(dataLength),n=Array(t.length),i=0;is||s>n||-1>a||a>i)throw"Error.checkAndNudgePoints ";r=!1,-1==s?(t[o]=0,r=!0):s==n&&(t[o]=n-1,r=!0),-1==a?(t[o+1]=0,r=!0):a==i&&(t[o+1]=i-1,r=!0)}for(r=!0,o=t.Length-2;o>=0&&r;o-=2){if(s=Math.floor(t[o]),a=Math.floor(t[o+1]),-1>s||s>n||-1>a||a>i)throw"Error.checkAndNudgePoints ";r=!1,-1==s?(t[o]=0,r=!0):s==n&&(t[o]=n-1,r=!0),-1==a?(t[o+1]=0,r=!0):a==i&&(t[o+1]=i-1,r=!0)}},sampleGrid3:function(e,t,n){for(var i=new BitMatrix(t),r=Array(t<<1),o=0;t>o;o++){for(var s=r.length,a=o+.5,h=0;s>h;h+=2)r[h]=(h>>1)+.5,r[h+1]=a;n.transformPoints1(r),GridSampler.checkAndNudgePoints(e,r);try{for(h=0;s>h;h+=2){var c=4*Math.floor(r[h])+4*Math.floor(r[h+1])*qrcode.width,l=e[Math.floor(r[h])+qrcode.width*Math.floor(r[h+1])];qrcode.imagedata.data[c]=l?255:0,qrcode.imagedata.data[c+1]=l?255:0,qrcode.imagedata.data[c+2]=0,qrcode.imagedata.data[c+3]=255,l&&i.set_Renamed(h>>1,o)}}catch(f){throw"Error.checkAndNudgePoints"}}return i},sampleGridx:function(e,t,n,i,r,o,s,a,h,c,l,f,d,w,u,C,E,B){return n=PerspectiveTransform.quadrilateralToQuadrilateral(n,i,r,o,s,a,h,c,l,f,d,w,u,C,E,B),GridSampler.sampleGrid3(e,t,n)}},Version.VERSION_DECODE_INFO=[31892,34236,39577,42195,48118,51042,55367,58893,63784,68472,70749,76311,79154,84390,87683,92361,96236,102084,102881,110507,110734,117786,119615,126325,127568,133589,136944,141498,145311,150283,152622,158308,161089,167017],Version.VERSIONS=buildVersions(),Version.getVersionForNumber=function(e){if(1>e||e>40)throw"ArgumentException";return Version.VERSIONS[e-1]},Version.getProvisionalVersionForDimension=function(e){if(1!=e%4)throw"Error getProvisionalVersionForDimension";try{return Version.getVersionForNumber(e-17>>2)}catch(t){throw"Error getVersionForNumber"}},Version.decodeVersionInformation=function(e){for(var t=4294967295,n=0,i=0;ir&&(n=i+7,t=r)}return 3>=t?this.getVersionForNumber(n):null},PerspectiveTransform.quadrilateralToQuadrilateral=function(e,t,n,i,r,o,s,a,h,c,l,f,d,w,u,C){return e=this.quadrilateralToSquare(e,t,n,i,r,o,s,a),this.squareToQuadrilateral(h,c,l,f,d,w,u,C).times(e)},PerspectiveTransform.squareToQuadrilateral=function(e,t,n,i,r,o,s,a){return dy2=a-o,dy3=t-i+o-a,0==dy2&&0==dy3?new PerspectiveTransform(n-e,r-n,e,i-t,o-i,t,0,0,1):(dx1=n-r,dx2=s-r,dx3=e-n+r-s,dy1=i-o,denominator=dx1*dy2-dx2*dy1,a13=(dx3*dy2-dx2*dy3)/denominator,a23=(dx1*dy3-dx3*dy1)/denominator,new PerspectiveTransform(n-e+a13*n,s-e+a23*s,e,i-t+a13*i,a-t+a23*a,t,a13,a23,1))},PerspectiveTransform.quadrilateralToSquare=function(e,t,n,i,r,o,s,a){return this.squareToQuadrilateral(e,t,n,i,r,o,s,a).buildAdjoint()};var FORMAT_INFO_MASK_QR=21522,FORMAT_INFO_DECODE_LOOKUP=[[21522,0],[20773,1],[24188,2],[23371,3],[17913,4],[16590,5],[20375,6],[19104,7],[30660,8],[29427,9],[32170,10],[30877,11],[26159,12],[25368,13],[27713,14],[26998,15],[5769,16],[5054,17],[7399,18],[6608,19],[1890,20],[597,21],[3340,22],[2107,23],[13663,24],[12392,25],[16177,26],[14854,27],[9396,28],[8579,29],[11994,30],[11245,31]],BITS_SET_IN_HALF_BYTE=[0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4];FormatInformation.numBitsDiffering=function(e,t){return e^=t,BITS_SET_IN_HALF_BYTE[15&e]+BITS_SET_IN_HALF_BYTE[15&URShift(e,4)]+BITS_SET_IN_HALF_BYTE[15&URShift(e,8)]+BITS_SET_IN_HALF_BYTE[15&URShift(e,12)]+BITS_SET_IN_HALF_BYTE[15&URShift(e,16)]+BITS_SET_IN_HALF_BYTE[15&URShift(e,20)]+BITS_SET_IN_HALF_BYTE[15&URShift(e,24)]+BITS_SET_IN_HALF_BYTE[15&URShift(e,28)]},FormatInformation.decodeFormatInformation=function(e){var t=FormatInformation.doDecodeFormatInformation(e);return null!=t?t:FormatInformation.doDecodeFormatInformation(e^FORMAT_INFO_MASK_QR)},FormatInformation.doDecodeFormatInformation=function(e){for(var t=4294967295,n=0,i=0;io&&(n=r[1],t=o)}return 3>=t?new FormatInformation(n):null},ErrorCorrectionLevel.forBits=function(e){if(0>e||e>=FOR_BITS.Length)throw"ArgumentException";return FOR_BITS[e]};var L=new ErrorCorrectionLevel(0,1,"L"),M=new ErrorCorrectionLevel(1,0,"M"),Q=new ErrorCorrectionLevel(2,3,"Q"),H=new ErrorCorrectionLevel(3,2,"H"),FOR_BITS=[M,L,H,Q];DataBlock.getDataBlocks=function(e,t,n){if(e.length!=t.TotalCodewords)throw"ArgumentException";var i=t.getECBlocksForLevel(n);n=0;var r=i.getECBlocks();for(t=0;t=0&&n[r].codewords.length!=t;)r--;for(r++,i=t-i.ECCodewordsPerBlock,t=a=0;i>t;t++)for(s=0;o>s;s++)n[s].codewords[t]=e[a++];for(s=r;o>s;s++)n[s].codewords[i]=e[a++];for(h=n[0].codewords.length,t=i;h>t;t++)for(s=0;o>s;s++)n[s].codewords[r>s?t:t+1]=e[a++];return n},DataMask={forReference:function(e){if(0>e||e>7)throw"System.ArgumentException";return DataMask.DATA_MASKS[e]}},DataMask.DATA_MASKS=[new DataMask000,new DataMask001,new DataMask010,new DataMask011,new DataMask100,new DataMask101,new DataMask110,new DataMask111],GF256.QR_CODE_FIELD=new GF256(285),GF256.DATA_MATRIX_FIELD=new GF256(301),GF256.addOrSubtract=function(e,t){return e^t},Decoder={},Decoder.rsDecoder=new ReedSolomonDecoder(GF256.QR_CODE_FIELD),Decoder.correctErrors=function(e,t){for(var n=e.length,i=Array(n),r=0;n>r;r++)i[r]=255&e[r];n=e.length-t;try{Decoder.rsDecoder.decode(i,n)}catch(o){throw o}for(r=0;t>r;r++)e[r]=i[r]},Decoder.decode=function(e){var t=new BitMatrixParser(e);e=t.readVersion();for(var n=t.readFormatInformation().ErrorCorrectionLevel,t=t.readCodewords(),t=DataBlock.getDataBlocks(t,e,n),i=0,r=0;rr;r++)i[o++]=a[r]}return new QRCodeDataBlockReader(i,e.VersionNumber,n.Bits)},qrcode={imagedata:null,width:0,height:0,qrCodeSymbol:null,debug:!1,sizeOfDataLengthInfo:[[10,9,8,8],[12,11,16,10],[14,13,16,12]],callback:null,decode:function(e){if(0==arguments.length){var t=document.getElementById("qr-canvas"),n=t.getContext("2d");return qrcode.width=t.width,qrcode.height=t.height,qrcode.imagedata=n.getImageData(0,0,qrcode.width,qrcode.height),qrcode.result=qrcode.process(n),null!=qrcode.callback&&qrcode.callback(qrcode.result),qrcode.result}var i=new Image;i.onload=function(){var e=document.createElement("canvas"),t=e.getContext("2d"),n=document.getElementById("out-canvas");null!=n&&(n=n.getContext("2d"),n.clearRect(0,0,320,240),n.drawImage(i,0,0,320,240)),e.width=i.width,e.height=i.height,t.drawImage(i,0,0),qrcode.width=i.width,qrcode.height=i.height;try{qrcode.imagedata=t.getImageData(0,0,i.width,i.height)}catch(r){return qrcode.result="Cross domain image reading not supported in your browser! Save it to your computer then drag and drop the file!",void(null!=qrcode.callback&&qrcode.callback(qrcode.result))}try{qrcode.result=qrcode.process(t)}catch(o){console.log(o),qrcode.result="error decoding QR Code"}null!=qrcode.callback&&qrcode.callback(qrcode.result)},i.src=e},decode_utf8:function(e){return decodeURIComponent(escape(e))},process:function(e){var t=(new Date).getTime(),n=qrcode.grayScaleToBitmap(qrcode.grayscale());if(qrcode.debug){for(var i=0;i=r?!0:!1}return t},getMiddleBrightnessPerArea:function(e){for(var t=Math.floor(qrcode.width/4),n=Math.floor(qrcode.height/4),i=Array(4),r=0;4>r;r++){i[r]=Array(4);for(var o=0;4>o;o++)i[r][o]=[0,0]}for(r=0;4>r;r++)for(o=0;4>o;o++){i[o][r][0]=255;for(var s=0;n>s;s++)for(var a=0;t>a;a++){var h=e[t*o+a+(n*r+s)*qrcode.width];hi[o][r][1]&&(i[o][r][1]=h)}}for(e=Array(4),t=0;4>t;t++)e[t]=Array(4);for(r=0;4>r;r++)for(o=0;4>o;o++)e[o][r]=Math.floor((i[o][r][0]+i[o][r][1])/2);return e},grayScaleToBitmap:function(e){for(var t=qrcode.getMiddleBrightnessPerArea(e),n=t.length,i=Math.floor(qrcode.width/n),r=Math.floor(qrcode.height/n),o=Array(qrcode.height*qrcode.width),s=0;n>s;s++)for(var a=0;n>a;a++)for(var h=0;r>h;h++)for(var c=0;i>c;c++)o[i*a+c+(r*s+h)*qrcode.width]=e[i*a+c+(r*s+h)*qrcode.width]e?this.length+e:e,this.push.apply(this,n)};var MIN_SKIP=3,MAX_MODULES=57,INTEGER_MATH_SHIFT=8,CENTER_QUORUM=2;qrcode.orderBestPatterns=function(e){function t(e,t){return xDiff=e.X-t.X,yDiff=e.Y-t.Y,Math.sqrt(xDiff*xDiff+yDiff*yDiff)}var n=t(e[0],e[1]),i=t(e[1],e[2]),r=t(e[0],e[2]);i>=n&&i>=r?(i=e[0],n=e[1],r=e[2]):r>=i&&r>=n?(i=e[1],n=e[0],r=e[2]):(i=e[2],n=e[0],r=e[1]);var o=i.x,s=i.y;0>(r.x-o)*(n.y-s)-(r.y-s)*(n.x-o)&&(o=n,n=r,r=o),e[0]=n,e[1]=i,e[2]=r};
\ No newline at end of file