// WebcamJS v1.0.25 - http://github.com/jhuckaby/webcamjs - MIT Licensed (function(e) { var t; function a() { var e = Error.apply(this, arguments); e.name = this.name = "FlashError"; this.stack = e.stack; this.message = e.message } function i() { var e = Error.apply(this, arguments); e.name = this.name = "WebcamError"; this.stack = e.stack; this.message = e.message } var s = function() {}; s.prototype = Error.prototype; a.prototype = new s; i.prototype = new s; var Webcam = { version: "1.0.26", protocol: location.protocol.match(/https/i) ? "https" : "http", loaded: false, live: false, userMedia: true, iOS: /iPad|iPhone|iPod/.test(navigator.userAgent) && !e.MSStream, params: { width: 0, height: 0, dest_width: 0, dest_height: 0, image_format: "jpeg", jpeg_quality: 90, enable_flash: true, force_flash: false, flip_horiz: false, fps: 30, upload_name: "webcam", constraints: null, swfURL: "", flashNotDetectedText: "ERROR: No Adobe Flash Player detected. Webcam.js relies on Flash for browsers that do not support getUserMedia (like yours).", noInterfaceFoundText: "No supported webcam interface found.", unfreeze_snap: true, iosPlaceholderText: "Click here to open camera.", user_callback: null, user_canvas: null }, errors: { FlashError: a, WebcamError: i }, hooks: {}, init: function() { var t = this; this.mediaDevices = navigator.mediaDevices && navigator.mediaDevices.getUserMedia ? navigator.mediaDevices : navigator.mozGetUserMedia || navigator.webkitGetUserMedia ? { getUserMedia: function(e) { return new Promise(function(t, a) { (navigator.mozGetUserMedia || navigator.webkitGetUserMedia).call(navigator, e, t, a) } ) } } : null; e.URL = e.URL || e.webkitURL || e.mozURL || e.msURL; this.userMedia = this.userMedia && !!this.mediaDevices && !!e.URL; if (navigator.userAgent.match(/Firefox\D+(\d+)/)) { if (parseInt(RegExp.$1, 10) < 21) this.userMedia = null } if (this.userMedia) { e.addEventListener("beforeunload", function(e) { t.reset() }) } }, exifOrientation: function(e) { var t = new DataView(e); if (t.getUint8(0) != 255 || t.getUint8(1) != 216) { console.log("Not a valid JPEG file"); return 0 } var a = 2; var i = null; while (a < e.byteLength) { if (t.getUint8(a) != 255) { console.log("Not a valid marker at offset " + a + ", found: " + t.getUint8(a)); return 0 } i = t.getUint8(a + 1); if (i == 225) { a += 4; var s = ""; for (n = 0; n < 4; n++) { s += String.fromCharCode(t.getUint8(a + n)) } if (s != "Exif") { console.log("Not valid EXIF data found"); return 0 } a += 6; var r = null; if (t.getUint16(a) == 18761) { r = false } else if (t.getUint16(a) == 19789) { r = true } else { console.log("Not valid TIFF data! (no 0x4949 or 0x4D4D)"); return 0 } if (t.getUint16(a + 2, !r) != 42) { console.log("Not valid TIFF data! (no 0x002A)"); return 0 } var o = t.getUint32(a + 4, !r); if (o < 8) { console.log("Not valid TIFF data! (First offset less than 8)", t.getUint32(a + 4, !r)); return 0 } var l = a + o; var h = t.getUint16(l, !r); for (var c = 0; c < h; c++) { var d = l + c * 12 + 2; if (t.getUint16(d, !r) == 274) { var f = t.getUint16(d + 2, !r); var m = t.getUint32(d + 4, !r); if (f != 3 && m != 1) { console.log("Invalid EXIF orientation value type (" + f + ") or count (" + m + ")"); return 0 } var p = t.getUint16(d + 8, !r); if (p < 1 || p > 8) { console.log("Invalid EXIF orientation value (" + p + ")"); return 0 } return p } } } else { a += 2 + t.getUint16(a + 2) } } return 0 }, fixOrientation: function(e, t, a) { var i = new Image; i.addEventListener("load", function(e) { var s = document.createElement("canvas"); var r = s.getContext("2d"); if (t < 5) { s.width = i.width; s.height = i.height } else { s.width = i.height; s.height = i.width } switch (t) { case 2: r.transform(-1, 0, 0, 1, i.width, 0); break; case 3: r.transform(-1, 0, 0, -1, i.width, i.height); break; case 4: r.transform(1, 0, 0, -1, 0, i.height); break; case 5: r.transform(0, 1, 1, 0, 0, 0); break; case 6: r.transform(0, 1, -1, 0, i.height, 0); break; case 7: r.transform(0, -1, -1, 0, i.height, i.width); break; case 8: r.transform(0, -1, 1, 0, 0, i.width); break } r.drawImage(i, 0, 0); a.src = s.toDataURL() }, false); i.src = e }, attach: function(a) { if (typeof a == "string") { a = document.getElementById(a) || document.querySelector(a) } if (!a) { return this.dispatch("error", new i("Could not locate DOM element to attach to.")) } this.container = a; a.innerHTML = ""; var s = document.createElement("div"); a.appendChild(s); this.peg = s; if (!this.params.width) this.params.width = a.offsetWidth; if (!this.params.height) this.params.height = a.offsetHeight; if (!this.params.width || !this.params.height) { return this.dispatch("error", new i("No width and/or height for webcam. Please call set() first, or attach to a visible element.")) } if (!this.params.dest_width) this.params.dest_width = this.params.width; if (!this.params.dest_height) this.params.dest_height = this.params.height; this.userMedia = t === undefined ? this.userMedia : t; if (this.params.force_flash) { t = this.userMedia; this.userMedia = null } if (typeof this.params.fps !== "number") this.params.fps = 30; var r = this.params.width / this.params.dest_width; var o = this.params.height / this.params.dest_height; if (this.userMedia) { var n = document.createElement("video"); n.setAttribute("autoplay", "autoplay"); n.setAttribute("playsinline", "playsinline"); n.style.width = "" + this.params.dest_width + "px"; n.style.height = "" + this.params.dest_height + "px"; if (r != 1 || o != 1) { a.style.overflow = "hidden"; n.style.webkitTransformOrigin = "0px 0px"; n.style.mozTransformOrigin = "0px 0px"; n.style.msTransformOrigin = "0px 0px"; n.style.oTransformOrigin = "0px 0px"; n.style.transformOrigin = "0px 0px"; n.style.webkitTransform = "scaleX(" + r + ") scaleY(" + o + ")"; n.style.mozTransform = "scaleX(" + r + ") scaleY(" + o + ")"; n.style.msTransform = "scaleX(" + r + ") scaleY(" + o + ")"; n.style.oTransform = "scaleX(" + r + ") scaleY(" + o + ")"; n.style.transform = "scaleX(" + r + ") scaleY(" + o + ")" } a.appendChild(n); this.video = n; var l = this; this.mediaDevices.getUserMedia({ audio: false, video: this.params.constraints || { mandatory: { minWidth: this.params.dest_width, minHeight: this.params.dest_height } } }).then(function(t) { n.onloadedmetadata = function(e) { l.stream = t; l.loaded = true; l.live = true; l.dispatch("load"); l.dispatch("live"); l.flip() } ; if ("srcObject"in n) { n.srcObject = t } else { n.src = e.URL.createObjectURL(t) } }).catch(function(e) { if (l.params.enable_flash && l.detectFlash()) { setTimeout(function() { l.params.force_flash = 1; l.attach(a) }, 1) } else { l.dispatch("error", e) } }) } else if (this.iOS) { var h = document.createElement("div"); h.id = this.container.id + "-ios_div"; h.className = "webcamjs-ios-placeholder"; h.style.width = "" + this.params.width + "px"; h.style.height = "" + this.params.height + "px"; h.style.textAlign = "center"; h.style.display = "table-cell"; h.style.verticalAlign = "middle"; h.style.backgroundRepeat = "no-repeat"; h.style.backgroundSize = "contain"; h.style.backgroundPosition = "center"; var c = document.createElement("span"); c.className = "webcamjs-ios-text"; c.innerHTML = this.params.iosPlaceholderText; h.appendChild(c); var d = document.createElement("img"); d.id = this.container.id + "-ios_img"; d.style.width = "" + this.params.dest_width + "px"; d.style.height = "" + this.params.dest_height + "px"; d.style.display = "none"; h.appendChild(d); var f = document.createElement("input"); f.id = this.container.id + "-ios_input"; f.setAttribute("type", "file"); f.setAttribute("accept", "image/*"); f.setAttribute("capture", "camera"); var l = this; var m = this.params; f.addEventListener("change", function(e) { if (e.target.files.length > 0 && e.target.files[0].type.indexOf("image/") == 0) { var t = URL.createObjectURL(e.target.files[0]); var a = new Image; a.addEventListener("load", function(e) { var t = document.createElement("canvas"); t.width = m.dest_width; t.height = m.dest_height; var i = t.getContext("2d"); ratio = Math.min(a.width / m.dest_width, a.height / m.dest_height); var s = m.dest_width * ratio; var r = m.dest_height * ratio; var o = (a.width - s) / 2; var n = (a.height - r) / 2; i.drawImage(a, o, n, s, r, 0, 0, m.dest_width, m.dest_height); var l = t.toDataURL(); d.src = l; h.style.backgroundImage = "url('" + l + "')" }, false); var i = new FileReader; i.addEventListener("load", function(e) { var i = l.exifOrientation(e.target.result); if (i > 1) { l.fixOrientation(t, i, a) } else { a.src = t } }, false); var s = new XMLHttpRequest; s.open("GET", t, true); s.responseType = "blob"; s.onload = function(e) { if (this.status == 200 || this.status === 0) { i.readAsArrayBuffer(this.response) } } ; s.send() } }, false); f.style.display = "none"; a.appendChild(f); h.addEventListener("click", function(e) { if (m.user_callback) { l.snap(m.user_callback, m.user_canvas) } else { f.style.display = "block"; f.focus(); f.click(); f.style.display = "none" } }, false); a.appendChild(h); this.loaded = true; this.live = true } else if (this.params.enable_flash && this.detectFlash()) { e.Webcam = Webcam; var h = document.createElement("div"); h.innerHTML = this.getSWFHTML(); a.appendChild(h) } else { this.dispatch("error", new i(this.params.noInterfaceFoundText)) } if (this.params.crop_width && this.params.crop_height) { var p = Math.floor(this.params.crop_width * r); var u = Math.floor(this.params.crop_height * o); a.style.width = "" + p + "px"; a.style.height = "" + u + "px"; a.style.overflow = "hidden"; a.scrollLeft = Math.floor(this.params.width / 2 - p / 2); a.scrollTop = Math.floor(this.params.height / 2 - u / 2) } else { a.style.width = "" + this.params.width + "px"; a.style.height = "" + this.params.height + "px" } }, reset: function() { if (this.preview_active) this.unfreeze(); this.unflip(); if (this.userMedia) { if (this.stream) { if (this.stream.getVideoTracks) { var e = this.stream.getVideoTracks(); if (e && e[0] && e[0].stop) e[0].stop() } else if (this.stream.stop) { this.stream.stop() } } delete this.stream; delete this.video } if (this.userMedia !== true && this.loaded && !this.iOS) { var t = this.getMovie(); if (t && t._releaseCamera) t._releaseCamera() } if (this.container) { this.container.innerHTML = ""; delete this.container } this.loaded = false; this.live = false }, set: function() { if (arguments.length == 1) { for (var e in arguments[0]) { this.params[e] = arguments[0][e] } } else { this.params[arguments[0]] = arguments[1] } }, on: function(e, t) { e = e.replace(/^on/i, "").toLowerCase(); if (!this.hooks[e]) this.hooks[e] = []; this.hooks[e].push(t) }, off: function(e, t) { e = e.replace(/^on/i, "").toLowerCase(); if (this.hooks[e]) { if (t) { var a = this.hooks[e].indexOf(t); if (a > -1) this.hooks[e].splice(a, 1) } else { this.hooks[e] = [] } } }, dispatch: function() { var t = arguments[0].replace(/^on/i, "").toLowerCase(); var s = Array.prototype.slice.call(arguments, 1); if (this.hooks[t] && this.hooks[t].length) { for (var r = 0, o = this.hooks[t].length; r < o; r++) { var n = this.hooks[t][r]; if (typeof n == "function") { n.apply(this, s) } else if (typeof n == "object" && n.length == 2) { n[0][n[1]].apply(n[0], s) } else if (e[n]) { e[n].apply(e, s) } } return true } else if (t == "error") { var l; if (s[0]instanceof a || s[0]instanceof i) { l = s[0].message } else { l = "Could not access webcam: " + s[0].name + ": " + s[0].message + " " + s[0].toString() } alert("Webcam.js Error: " + l) } return false }, setSWFLocation: function(e) { this.set("swfURL", e) }, detectFlash: function() { var t = "Shockwave Flash" , a = "ShockwaveFlash.ShockwaveFlash" , i = "application/x-shockwave-flash" , s = e , r = navigator , o = false; if (typeof r.plugins !== "undefined" && typeof r.plugins[t] === "object") { var n = r.plugins[t].description; if (n && (typeof r.mimeTypes !== "undefined" && r.mimeTypes[i] && r.mimeTypes[i].enabledPlugin)) { o = true } } else if (typeof s.ActiveXObject !== "undefined") { try { var l = new ActiveXObject(a); if (l) { var h = l.GetVariable("$version"); if (h) o = true } } catch (e) {} } return o }, getSWFHTML: function() { var t = "" , i = this.params.swfURL; if (location.protocol.match(/file/)) { this.dispatch("error", new a("Flash does not work from local disk. Please run from a web server.")); return '