{"version":3,"sources":["color.js","faceFeatureDetect.js","facedetect.js","fb.js","fbq.js","ga.js","pageManager.js","polyfills.js","tracer.js","utils.js"],"names":["FakeCation","ns","Color","r","g","b","a","this","red","parseInt","green","blue","alpha","parseFloat","prototype","isValid","toString","result","join","RED","GREEN","BLUE","YELLOW","MAGENTA","CYAN","WHITE","BLACK","invert","toHex","toHsl","h","s","l","d","max","Math","min","similarHsl","color","hdiff","sdiff","ldiff","hsl1","hsl2","abs","similarRgb","threshold","diff","similar","same","countSimilars","canvas","i","tmpc","ctx","getContext","imgData","getImageData","width","height","data","num","length","diffHsl","diffRgb","rd","gd","bd","sqrt","average","clist","colorUtils","getColor","x","y","offset","setColor","getColors","points","map","point","floodFill","startX","startY","fillColor","matcherFn","colorFn","newPos","currentColor","lastColor","reachLeft","reachRight","startColor","drawingBoundLeft","drawingBoundTop","drawingBoundRight","drawingBoundBottom","pixelStack","cColor","sColor","fColor","lColor","iData","cx","cy","pop","push","histogram","c","a256","dValue","arr","normalize","apply","v","rHist","gHist","bHist","bwHist","grayscale","rawred","rawgreen","rawblue","rawgrayscale","drawHistogram","w","w1","h1","fillStyle","forEach","fillRect","histogramBorders","border","histData","borders","numPixels","findMinMax","thr","bdr","component","transformHistogram","from","to","transformColor","f","t","cFrom","cTo","strechContrast","getRefColor","radius","j","cl","getPixels","context","idata","clm","pModel","faceFeatureDetect","faceRectangle","Promise","resolve","reject","defaultResolve","console","log","trackLostHandler","obj","tracker","stop","removeHandlers","trackNotFoundHandler","trackConvergedHandler","iterationPosition","window","cancelAnimationFrame","drawRequest","document","removeEventListener","debugCtx","sourceCtx","target","createElement","source","isRunning","ClmTracker","stopOnConvergence","init","_update","requestAnimationFrame","_pos","getCurrentPosition","utils","dump","draw","start","box","addEventListener","findClickPoints","pt_left","pt_right","pt_bottom","bounds","v_c","m","r1","r2","center","d1","distance","d2","bx","by","n","pts","step","PI","theta","cos","sin","filter","p","faceDetect","setTimeout","e","detector","rects","candidates","selectedRect","D","objectdetect","treshold","frontalface","detect","sort","rect","FC","HOST","VERSION","fb","getLoginStatus","FB","response","status","authResponse","userID","accessToken","uid","login","opts","uploadPhoto","caption","imageBlob","formData","FormData","xhr","XMLHttpRequest","append","open","send","pageId","fbq","callMethod","arguments","queue","_fbq","loaded","version","async","src","getElementsByTagName","parentNode","insertBefore","cname","type","content_name","stageId","prodId","location","hostname","o","q","Date","ga","param","fc","pageManager","pages","urlIndex","add","page","name","url","getByName","getByUrl","Page","section","sectionElement","bound","$","selector","querySelectorAll","$$","querySelector","fallbackFromMatches","compareToTargetNode","node","nodes","Array","slice","call","render","html","innerHTML","run","next","bind","eventHandlers","eventHandler","event","targetSelector","handler","matches","destroy","create","HTMLCanvasElement","toBlob","Object","defineProperty","value","callback","quality","binStr","atob","toDataURL","split","len","Uint8Array","charCodeAt","Blob","MooreNeighbour","start_point","clockwise_next","positions","next_cell","cell","old_cell","dx","dy","inside","contour","image_data","match_color","pixel_pos","components","poly","lower_y","dummyForLint","moore","undefined","createMask","tracer","draw_poly","strokeStyle","lineWidth","beginPath","moveTo","lineTo","closePath","stroke","contract","scale","middleX","middleY","bounding","top","Infinity","left","right","bottom","greenboxOnPixels","pointArray","references","stops","checkSimilar","refColor","isStopColor","refColors","blank","stopColors","counter","isSimilarToRefcolors","some","traceCountours","imageData","iteration","iter","currentIteration","mask","Uint8ClampedArray","removedPixels","draw_contour","traceContours","filters","blenders","webRTCSupported","navigator","getUserMedia","STATE","webcamEl","canvasEl","inputEl","DEBUG_CANVAS","registerFilter","getFilter","getFilterNames","keys","doFilter","cb","config","getCanvas","canvas2imgData","pleaseFilter","registerBlender","blender","getBlender","getBlenderNames","doBlend","background","pleaseBlend","createWebcam","placeholder","id","webcam","placeholderEl","getElementById","appendChild","error","createCanvas","createImageInput","input","accept","capture","initWebcam","getWebcam","video","webcamSuccess","err","stream","autoplay","URL","createObjectURL","videoPlayingCB","videoWidth","videoHeight","getInput","video2canvas","drawImage","image2canvas","image","img","Image","onload","img2canvas","input2canvas","mWidth","mHeight","file","files","loadImage","parseMetaData","time","timeEnd","orientation","exif","get","maxWidth","maxHeight","p1","p2","pow","canvasId","body","_length","createImageData","putImageData"],"mappings":"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","file":"utils.js","sourcesContent":["var FakeCation = FakeCation || {};\n\n// From:\n// https://bitbucket.org/dyuri/colordetect.js\n\n(function (ns) {\n \"use strict\";\n\n /**\n * Color class\n * @constructor\n * @param {number} r red component (0-255)\n * @param {number} g green component (0-255)\n * @param {number} b blue component (0-255)\n * @param {number=} a alpha (0-1)\n */\n var Color = function (r, g, b, a) {\n this.red = parseInt(r, 10);\n this.green = parseInt(g, 10);\n this.blue = parseInt(b, 10);\n this.alpha = a === 0 ? 0 : parseFloat(a || 1);\n };\n\n /**\n * check if the color is valid\n * @return {boolean}\n */\n Color.prototype.isValid = function () {\n return this.red >= 0 && this.red <= 255 &&\n this.green >= 0 && this.green <= 255 &&\n this.blue >= 0 && this.blue <= 255 &&\n this.alpha <= 1 && this.alpha >= 0;\n };\n\n /**\n * toString for colors\n * @return {string}\n */\n Color.prototype.toString = function () {\n var result;\n if (this.alpha !== 1) {\n result = \"rgba(\" + [this.red, this.green, this.blue, this.alpha].join(\", \") + \")\";\n } else {\n result = \"rgb(\" + [this.red, this.green, this.blue].join(\", \") + \")\";\n }\n return result;\n };\n\n /**\n * Some constant colors\n */\n Color.RED = new Color(255, 0, 0);\n Color.GREEN = new Color(0, 255, 0);\n Color.BLUE = new Color(0, 0, 255);\n Color.YELLOW = new Color(255, 255, 0);\n Color.MAGENTA = new Color(255, 0, 255);\n Color.CYAN = new Color(0, 255, 255);\n Color.WHITE = new Color(255, 255, 255);\n Color.BLACK = new Color(0, 0, 0);\n\n /**\n * return the complementer color\n * @return {Color}\n */\n Color.prototype.invert = function () {\n return new Color(255 - this.red, 255 - this.green, 255 - this.blue, this.alpha);\n };\n\n /**\n * Hex code of the color\n * @return {string} the hex code\n */\n Color.prototype.toHex = function () {\n var r = this.red >= 16 ? this.red.toString(16) : '0' + this.red.toString(16),\n g = this.green >= 16 ? this.green.toString(16) : '0' + this.green.toString(16),\n b = this.blue >= 16 ? this.blue.toString(16) : '0' + this.blue.toString(16);\n\n return '#' + r + g + b;\n };\n\n /**\n * HSL values of the color\n * @return {Array.} [hue, saturation, lightning]\n */\n Color.prototype.toHsl = function () {\n // caching\n if (this.h && this.s && this.l) {\n return [this.h, this.s, this.l];\n }\n\n var r = this.red / 255,\n g = this.green / 255,\n b = this.blue / 255,\n max = Math.max(r, g, b),\n min = Math.min(r, g, b),\n d, h, s, l = (max + min) / 2;\n\n if (max === min) {\n h = s = 0;\n } else {\n d = max - min;\n s = l > 0.5 ? d / (2 - max - min) : d / (max + min);\n switch (max) {\n case r:\n h = (g - b) / d + (g < b ? 6 : 0);\n break;\n case g:\n h = (b - r) / d + 2;\n break;\n case b:\n h = (r - g) / d + 4;\n break;\n }\n h = h / 6;\n }\n\n this.h = h;\n this.s = s;\n this.l = l;\n return [h, s, l];\n };\n\n /**\n * Compares two color objects if they are similar depending on the given parameters\n * @param {Color} color the color to compare\n * @param {number=} hdiff max hue difference\n * @param {number=} sdiff max saturation difference\n * @param {number=} ldiff max lightness difference\n * @return {boolean} true if they are similar, false otherwise\n */\n Color.prototype.similarHsl = function (color, hdiff, sdiff, ldiff) {\n // hue - max 0.01 difference\n // saturation - max 0.2 difference\n var hsl1 = this.toHsl(),\n hsl2 = color.toHsl();\n\n hdiff = hdiff || 0.01;\n sdiff = sdiff || 0.2;\n ldiff = ldiff || 0.5;\n\n return Math.abs(hsl1[0] - hsl2[0]) < hdiff && Math.abs(hsl1[1] - hsl2[1]) < sdiff && Math.abs(hsl1[2] - hsl2[2]) < ldiff;\n };\n\n /**\n * Compares two color based on RGB values\n * not as good as similarHsl, but much quicker\n * @param {Color} color\n * @param {number=} threshold\n */\n Color.prototype.similarRgb = function (color, threshold) {\n threshold = threshold || 40;\n return this.diff(color) < threshold;\n };\n\n Color.prototype.similar = Color.prototype.similarHsl;\n\n /**\n * Compares two color based on RGB values if they are the same or not\n * @param {Color} color\n */\n Color.prototype.same = function (color) {\n return this.diff(color) === 0;\n };\n\n /**\n * counts the similar pixels on a canvas\n * returns if optional maximum value reached\n * @param {HTMLCanvasElement} canvas\n * @param {number=} max\n * @return {number}\n */\n Color.prototype.countSimilars = function (canvas, max) {\n var ctx = canvas.getContext(\"2d\"),\n imgData = ctx.getImageData(0, 0, canvas.width, canvas.height),\n data = imgData.data,\n i, tmpc, num = 0;\n\n for (i = 0; i < data.length; i += 4) {\n tmpc = new Color(data[i], data[i + 1], data[i + 2]);\n if (tmpc.similar(this)) {\n num++;\n if (max && num >= max) {\n break;\n }\n }\n }\n\n return max ? num >= max : num;\n };\n\n /**\n * \"Difference\" between colors\n * @param {Color} color the color to compare\n * @return {number} the difference\n */\n Color.prototype.diffHsl = function (color) {\n var hsl1 = this.toHsl(),\n hsl2 = color.toHsl();\n\n return Math.abs(hsl1[0] - hsl2[0]) * 10 + Math.abs(hsl1[1] - hsl2[1]);\n };\n\n /**\n * \"Difference\" between colors, based on rgb values\n * @param {Color} color the color to compare\n * @return {number} the difference\n */\n Color.prototype.diffRgb = function (color) {\n var rd = this.red - color.red,\n gd = this.green - color.green,\n bd = this.blue - color.blue;\n\n return Math.sqrt(rd * rd + gd * gd + bd * bd);\n };\n\n Color.prototype.diff = Color.prototype.diffRgb;\n\n /**\n * Return a new color object with the \"average color\" of the given list\n * @param {Array.} clist list of colors\n * @return {Color} the average color\n */\n Color.average = function (clist) {\n var r = 0,\n g = 0,\n b = 0,\n a = 0,\n i, l = clist.length;\n\n for (i = 0; i < l; i++) {\n r += clist[i].red;\n g += clist[i].green;\n b += clist[i].blue;\n a += clist[i].alpha;\n }\n\n return new Color(r / l, g / l, b / l, a / l);\n };\n\n /**\n * Utilities for Color class\n */\n var colorUtils = {};\n\n /**\n * get color from the given position of an imgData object\n * @param {ImageData} imgData\n * @param {number} x\n * @param {number} y\n * @return {Color}\n */\n colorUtils.getColor = function (imgData, x, y) {\n var offset = (y * imgData.width + x) * 4,\n d = imgData.data;\n\n return new Color(d[offset], d[offset + 1], d[offset + 2], d[offset + 3] / 255);\n };\n\n /**\n * set color of the given position of an imgData object\n * @param {ImageData} imgData\n * @param {number} x\n * @param {number} y\n * @param {Color} color\n */\n colorUtils.setColor = function (imgData, x, y, color) {\n var offset = (y * imgData.width + x) * 4;\n imgData.data[offset] = color.red;\n imgData.data[offset + 1] = color.green;\n imgData.data[offset + 2] = color.blue;\n imgData.data[offset + 3] = +(color.alpha * 255) | 0;\n };\n\n colorUtils.getColors = function (imgData, points) {\n return points.map(point => colorUtils.getColor(imgData, parseInt(point[0], 10), parseInt(point[1], 10)));\n };\n\n /**\n * flood fill the selected area with the given color\n * @param {ImageData} imgData\n * @param {number} startX\n * @param {number} startY\n * @param {Color} fillColor\n * @param {function} matcherFn (currentColor, startColor, fillColor, lastColor, imgData, x, y)\n * @param {function} colorFn (currentColor, startColor, fillColor, lastColor, imgData, x, y)\n */\n colorUtils.floodFill = function (imgData, startX, startY, fillColor, matcherFn, colorFn) {\n var newPos,\n x, y,\n currentColor,\n startColor = colorUtils.getColor(imgData, startX, startY),\n lastColor,\n reachLeft,\n reachRight,\n drawingBoundLeft = 0,\n drawingBoundTop = 0,\n drawingBoundRight = imgData.width - 1,\n drawingBoundBottom = imgData.height - 1,\n pixelStack = [\n {x: startX, y: startY}\n ];\n\n matcherFn = matcherFn || function (cColor, sColor, fColor) {\n return !fColor.same(cColor) && sColor.similarRgb(cColor);\n };\n\n colorFn = colorFn || function (cColor, sColor, fColor, lColor, iData, cx, cy) {\n colorUtils.setColor(iData, cx, cy, fColor);\n };\n\n while (pixelStack.length) {\n newPos = pixelStack.pop();\n x = newPos.x;\n y = newPos.y;\n lastColor = newPos.lastColor;\n\n currentColor = colorUtils.getColor(imgData, x, y);\n\n while (y >= drawingBoundTop && matcherFn(currentColor, startColor, fillColor, lastColor, imgData, x, y)) {\n y -= 1;\n lastColor = currentColor;\n currentColor = colorUtils.getColor(imgData, x, y);\n }\n\n y += 1;\n reachLeft = false;\n reachRight = false;\n currentColor = colorUtils.getColor(imgData, x, y);\n\n while (y <= drawingBoundBottom && matcherFn(currentColor, startColor, fillColor, lastColor, imgData, x, y)) {\n\n colorFn(currentColor, startColor, fillColor, lastColor, imgData, x, y);\n\n if (x > drawingBoundLeft) {\n if (matcherFn(colorUtils.getColor(imgData, x - 1, y), startColor, fillColor, lastColor, imgData, x - 1, y)) {\n if (!reachLeft) {\n pixelStack.push({x: x - 1, y: y, lastColor: lastColor});\n reachLeft = true;\n }\n } else if (reachLeft) {\n reachLeft = false;\n }\n }\n\n if (x < drawingBoundRight) {\n if (matcherFn(colorUtils.getColor(imgData, x + 1, y), startColor, fillColor, lastColor, imgData, x + 1, y)) {\n if (!reachRight) {\n pixelStack.push({x: x + 1, y: y, lastColor: lastColor});\n reachRight = true;\n }\n } else if (reachRight) {\n reachRight = false;\n }\n }\n\n y += 1;\n lastColor = currentColor;\n currentColor = colorUtils.getColor(imgData, x, y);\n }\n }\n\n return imgData;\n };\n\n /**\n * r/g/b histogram\n * @param {ImageData} imgData\n */\n colorUtils.histogram = function (imgData) {\n var a256 = function (dValue) {\n var i, arr = [];\n for (i = 0; i < 256; i++) {\n arr[i] = dValue;\n }\n return arr;\n },\n normalize = function (arr) {\n var max = Math.max.apply(null, arr);\n\n return arr.map(function (v) {\n return 100 * v / max;\n });\n },\n rHist = a256(0),\n gHist = a256(0),\n bHist = a256(0),\n bwHist = a256(0),\n x, y, c;\n\n for (y = 0; y < imgData.height; y++) {\n for (x = 0; x < imgData.width; x++) {\n c = colorUtils.getColor(imgData, x, y);\n rHist[c.red]++;\n gHist[c.green]++;\n bHist[c.blue]++;\n bwHist[parseInt((c.red+c.green+c.blue)/3, 10)]++;\n }\n }\n\n return {\n red: normalize(rHist),\n green: normalize(gHist),\n blue: normalize(bHist),\n grayscale: normalize(bwHist),\n rawred: rHist,\n rawgreen: gHist,\n rawblue: bHist,\n rawgrayscale: bwHist\n };\n };\n\n /**\n * draw histogram on a canvas\n * @param {Array.} histogram\n * @param {Color} color drawing color\n * @param {HTMLCanvas} canvas canvas to draw on\n * @param {number=} x x of top left coordinate\n * @param {number=} y y of top left coordinate\n * @param {number=} w width of the histogram\n * @param {number=} h height of the histogram\n */\n colorUtils.drawHistogram = function (histogram, color, canvas, x, y, w, h) {\n var ctx = canvas.getContext('2d'), w1, h1;\n\n x = x || 0;\n y = y || 0;\n h = h || 100;\n w = w || 256;\n\n w1 = w/256;\n h1 = h/100;\n\n ctx.fillStyle = color.toString();\n histogram.forEach(function (v, i) {\n ctx.fillRect(x+w1*i|0, y+h|0, w1|0, -h1*v|0);\n });\n };\n\n /**\n * get histogram borders\n * @param {ImageData} imgData\n * @return {ImageData}\n */\n colorUtils.histogramBorders = function (imgData, threshold, border) {\n var histData = colorUtils.histogram(imgData),\n borders = {},\n numPixels = imgData.width * imgData.height,\n findMinMax = function (arr, thr, bdr) {\n var min = bdr, max = 255 - bdr;\n\n while (min < 128 && arr[min] < thr * numPixels) { min++; }\n while (max > 128 && arr[max] < thr * numPixels) { max--; }\n\n return {min: min, max: max};\n };\n\n threshold = threshold === 0 ? 0 : threshold || 0.001;\n border = border === 0 ? 0 : border || 2;\n\n // find min / max values above threshold\n ['red', 'green', 'blue'].forEach(function (component) {\n borders[component] = findMinMax(histData['raw'+component], threshold, border);\n });\n\n return borders;\n };\n\n /**\n * transform histogram\n * @param {ImageData} imgData\n * @param {Object} from histogram range to transform from\n * @param {Object} to histogram range to transform to\n * @return {ImageData}\n */\n colorUtils.transformHistogram = function (imgData, from, to) {\n var x, y, color,\n transformColor = function (c, f, t) {\n ['red', 'green', 'blue'].forEach(function (component) {\n var cFrom = f[component],\n cTo = t[component];\n\n c[component] = Math.max(Math.min(cTo.min + cTo.max * (c[component] - cFrom.min) / (cFrom.max - cFrom.min), 255), 0);\n });\n\n return c;\n };\n\n to = to || {\n red: {min: 0, max: 255},\n green: {min: 0, max: 255},\n blue: {min: 0, max: 255}\n };\n\n for (y = 0; y < imgData.height; y++) {\n for (x = 0; x < imgData.width; x++) {\n color = colorUtils.getColor(imgData, x, y);\n colorUtils.setColor(imgData, x, y, transformColor(color, from, to));\n }\n }\n\n return imgData;\n };\n\n /**\n * strech rgb contrast\n * @param {ImageData} imgData\n * @param {number=} threshold histogram minimum threshold to ignore\n * @param {Object} border low/high borders of histogram mapping\n * @return {ImageData}\n */\n colorUtils.strechContrast = function (imgData, threshold, border) {\n var borders = colorUtils.histogramBorders(imgData, threshold, border);\n\n return colorUtils.transformHistogram(imgData, borders);\n };\n\n /**\n * get the average color from the given area of an imgData object\n * @param {ImageData} imgData\n * @param {number} x\n * @param {number} y\n * @param {number=} radius radius of the area\n * @return {Color}\n */\n colorUtils.getRefColor = function (imgData, x, y, radius) {\n var i, j, cl = [];\n\n radius = radius || 3;\n\n for (i = x - radius; x + radius >= i; i++) {\n for (j = y - radius; y + radius >= j; j++) {\n cl.push(colorUtils.getColor(imgData, i, j));\n }\n }\n\n return Color.average(cl);\n };\n\n colorUtils.getPixels = function (context, color) {\n var idata, width, height,\n x, y, offset,\n result = [];\n\n if (context.getImageData) {\n idata = context.getImageData(0, 0, context.canvas.width, context.canvas.height);\n } else if (context.data && context.height && context.width) {\n idata = context;\n }\n\n width = idata.width;\n height = idata.height;\n\n for (y = 0; y < height; y++) {\n for (x = 0; x < width; x++) {\n offset = (y * width + x) * 4;\n if (idata.data[offset] === color.red &&\n idata.data[offset + 1] === color.green &&\n idata.data[offset + 2] === color.blue &&\n idata.data[offset + 3] === (+(color.alpha * 255) | 0)) {\n result.push([x, y]);\n }\n }\n }\n\n return result;\n };\n\n colorUtils.Color = Color;\n ns.colorUtils = colorUtils;\n\n}(FakeCation));\n","/*global Promise, clm, pModel, document, window */\nvar FakeCation = FakeCation || {};\n\n(function (ns, clm, pModel) {\n \"use strict\";\n\n var ClmTracker = clm.tracker;\n\n function faceFeatureDetect(canvas, faceRectangle) {\n return new Promise(function (resolve, reject) {\n var target = document.createElement('canvas'),\n debugCtx, sourceCtx;\n\n var obj = {\n source: canvas,\n target: target,\n isRunning: false\n };\n\n sourceCtx = canvas.getContext('2d');\n\n obj.tracker = new ClmTracker({\n stopOnConvergence: true\n });\n obj.tracker.init(pModel);\n var _update = function () {\n obj.drawRequest = window.requestAnimationFrame(_update);\n var _pos = obj.tracker.getCurrentPosition();\n if (_pos) {\n obj.iterationPosition = _pos;\n debugCtx = ns.utils.dump(sourceCtx);\n obj.tracker.draw(debugCtx.canvas);\n }\n };\n\n obj.start = function (box) {\n console.log(box);\n this.tracker.start(this.source, box);\n _update();\n };\n\n function defaultResolve () {\n var w = canvas.width,\n h = canvas.height;\n\n console.log('defaultResolve');\n resolve([\n [10, 10],\n [w - 10, 10],\n [10, h/2|0],\n [w - 10, h/2|0],\n [w/2|0, 10]\n ]);\n }\n\n function trackLostHandler() {\n obj.tracker.stop();\n removeHandlers();\n console.log(\"tracker lost\");\n // reject(); // instead of reject we use some border points\n defaultResolve();\n }\n\n function trackNotFoundHandler() {\n obj.tracker.stop();\n removeHandlers();\n console.log(\"The tracking had problems with finding a face in this image. Try selecting the face in the image manually.\");\n // reject(); // instead of reject we use some border points\n defaultResolve();\n }\n\n function trackConvergedHandler() {\n removeHandlers();\n console.log(\"tracker done\");\n obj.iterationPosition.push([obj.iterationPosition[14][0], faceRectangle[1]]);\n obj.iterationPosition.push([obj.iterationPosition[0][0], faceRectangle[1]]);\n resolve(obj.iterationPosition.map(point => [parseInt(point[0], 10), parseInt(point[1], 10)]));\n }\n\n function removeHandlers() {\n window.cancelAnimationFrame(obj.drawRequest);\n document.removeEventListener(\"clmtrackrLost\", trackLostHandler, false);\n document.removeEventListener(\"clmtrackrNotFound\", trackNotFoundHandler, false);\n document.removeEventListener(\"clmtrackrConverged\", trackConvergedHandler, false);\n }\n\n document.addEventListener(\"clmtrackrLost\", trackLostHandler, false);\n document.addEventListener(\"clmtrackrNotFound\", trackNotFoundHandler, false);\n document.addEventListener(\"clmtrackrConverged\", trackConvergedHandler, false);\n\n obj.start(faceRectangle);\n\n });\n }\n \n function findClickPoints(width, height, pt_left, pt_right, pt_bottom) {\n var center = [(pt_right[0] + pt_left[0]) / 2, (pt_right[1] + pt_left[1]) / 2];\n\n var d1 = ns.utils.distance(pt_left, pt_right);\n var d2 = ns.utils.distance(center, pt_bottom);\n\n function bounds(v_c, r, m) {\n var r1 = 0.4 * v_c + 0.4 * r;\n var r2 = 0.4 * (m - v_c) + 0.4 * r;\n return [r1, r2];\n }\n\n var bx = bounds(center[0], d1, width);\n d1 = Math.min(d1, bx[0]);\n d1 = Math.min(d1, bx[1]);\n\n var by = bounds(center[1], d2, height);\n d2 = Math.min(d2, by[0]);\n d2 = Math.min(d2, by[1]);\n\n // calculate the points of upper half ellipse\n var points = (function (c, a, b, n) {\n var pts = [];\n\n var step = Math.PI / n;\n\n var theta = Math.PI;\n\n var x, y;\n\n while (theta < 2 * Math.PI) {\n x = c[0] + a * Math.cos(theta);\n y = c[1] + b * Math.sin(theta);\n pts.push([x, y]);\n\n theta += step;\n }\n\n return pts;\n })(center, d1, d2 * 2, 20)\n .filter(function (p) {\n return p[0] >= 0 && p[0] < width && p[1] >= 0 && p[1] < height;\n });\n\n return points;\n }\n\n \n\n ns.faceFeatureDetect = faceFeatureDetect;\n ns.findClickPoints = findClickPoints;\n\n}(FakeCation, clm, pModel));\n","/*global objectdetect */\nvar FakeCation = FakeCation || {};\n\n(function (ns) {\n \"use strict\";\n\n function faceDetect(canvas) {\n return new Promise(function (resolve, reject) {\n setTimeout(function (c, r, e) {\n var D = objectdetect.detector,\n width = c.width,\n height = c.height,\n detector,\n treshold = width * height / 100,\n rects, candidates, selectedRect;\n\n detector = new D(width, height, 1.3, objectdetect.frontalface);\n rects = detector.detect(c);\n candidates = rects\n .sort(function (r1, r2) {\n return r1[2] * r1[3] - r2[2] * r2[3];\n })\n .filter(function (rect) {\n return rect[2] * rect[3] > treshold;\n });\n selectedRect = candidates.pop();\n\n if(selectedRect) {\n r(selectedRect); \n } else {\n // e();\n r([0, 0, width-1, height-1]);\n }\n }, 50, canvas, resolve, reject);\n });\n\n }\n\n ns.faceDetect = faceDetect;\n\n}(FakeCation));\n","/*global FakeCation, document, FB */\n(function (FC) {\n \"use strict\";\n\n const HOST = 'https://graph.facebook.com/';\n const VERSION = 'v2.5/';\n var fb = {};\n\n fb.getLoginStatus = function () {\n return new Promise(function (resolve, reject) {\n FB.getLoginStatus(function (response) {\n if (response.status === 'connected') {\n var uid = response.authResponse.userID;\n var accessToken = response.authResponse.accessToken;\n resolve({\n uid: response.authResponse.userID,\n accessToken: response.authResponse.accessToken\n });\n } else {\n reject(response);\n }\n });\n });\n };\n\n fb.login = function (opts) {\n return new Promise(function (resolve, reject) {\n FB.login(function (response) {\n if (response.authResponse) {\n resolve(response);\n } else {\n reject(response);\n }\n }, opts);\n });\n };\n\n fb.uploadPhoto = function (caption, imageBlob, accessToken) {\n return new Promise(function (resolve, reject) {\n var formData = new FormData(),\n xhr = new XMLHttpRequest();\n formData.append(\"attachment\", imageBlob);\n formData.append(\"access_token\", accessToken);\n formData.append(\"caption\", caption);\n xhr.open(\"POST\",HOST+VERSION+'me/photos');\n xhr.send(formData);\n xhr.addEventListener('load', resolve);\n xhr.addEventListener('error', reject);\n xhr.addEventListener('abort', reject);\n });\n };\n\n FC.fb = fb;\n\n}(FakeCation));\n","/*global FakeCation, document, fbq */\n(function (FC) {\n \"use strict\";\n var pageId = '887658944645950';\n\n /* eslint-disable */\n !function(f,b,e,v,n,t,s){if(f.fbq)return;n=f.fbq=function(){n.callMethod?\n n.callMethod.apply(n,arguments):n.queue.push(arguments)};if(!f._fbq)f._fbq=n;\n n.push=n;n.loaded=!0;n.version='2.0';n.queue=[];t=b.createElement(e);t.async=!0;\n t.src=v;s=b.getElementsByTagName(e)[0];s.parentNode.insertBefore(t,s)}(window,\n document,'script','//connect.facebook.net/en_US/fbevents.js');\n /* eslint-enable */\n\n fbq('init', pageId);\n // fbq('track', 'PageView');\n\n FC.fbq = function(cname, type) {\n type = type || 'ViewContent';\n fbq('track', type, {\n content_name: cname || 'Unknown'\n });\n };\n\n // initial page view tracking\n // FC.fbq('Welcome Page');\n\n}(FakeCation));\n","/*global FakeCation, document, ga */\n(function (FC) {\n \"use strict\";\n const stageId = 'UA-45874495-6';\n const prodId = 'UA-45874495-5';\n \n var pageId = stageId;\n \n if(location.hostname === 'selfiehop.euedge.com') {\n pageId = prodId;\n }\n\n /* eslint-disable */\n (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){\n (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),\n m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)\n })(window,document,'script','//www.google-analytics.com/analytics.js','ga');\n\n ga('create', pageId , 'auto');\n ga('send', 'pageview'); \n /* eslint-enable */\n\n FC.ga = function(param) {\n ga('set','page',param);\n ga('send','pageview');\n };\n \n}(FakeCation));\n","/*global page */\nvar FakeCation = window.FakeCation || {};\n\n(function (fc) {\n \"use strict\";\n\n var pageManager = {\n pages: {},\n urlIndex: {}\n };\n\n pageManager.add = function (page) {\n var name = page.name,\n url = page.url;\n pageManager.pages[name] = page;\n pageManager.urlIndex[url] = page;\n\n };\n\n pageManager.getByName = function (name) {\n return pageManager.pages[name];\n };\n\n pageManager.getByUrl = function (url) {\n return pageManager.urlIndex[url];\n };\n\n pageManager.Page = function (name, url, section) {\n this.name = name;\n this.url = url;\n this.section = section;\n this.sectionElement = null;\n this.bound = false;\n };\n\n pageManager.Page.prototype = {\n $:function(selector) {\n return this.sectionElement.querySelectorAll(selector);\n },\n $$:function(selector) {\n return this.sectionElement.querySelector(selector);\n },\n fallbackFromMatches: function (target, selector) {\n var nodes = (target.parentNode || target.document).querySelectorAll(selector);\n \n function compareToTargetNode(node){\n return node === target;\n }\n \n nodes = Array.prototype.slice.call(nodes);\n \n if (nodes.filter(compareToTargetNode).length >= 1) {\n return true; \n }\n },\n render: function () {\n if (!this.sectionElement) {\n this.sectionElement = document.querySelector(this.section);\n }\n if (this.html) {\n this.sectionElement.innerHTML = this.html;\n }\n },\n run: function (ctx, next) {\n console.log(this.name, this.url, ctx);\n },\n bind: function (ctx, next) {\n if (!this.bound) {\n if (this.eventHandlers && this.sectionElement) {\n this.eventHandlers.forEach(function (eventHandler) {\n this.sectionElement.addEventListener(eventHandler.event, function (targetSelector, handler, e) { \n if (typeof e.target.matches === 'function') {\n if (e.target.matches(targetSelector)) {\n handler.call(this, e);\n }\n } else {\n if(this.fallbackFromMatches(e.target, targetSelector)) {\n handler.call(this, e);\n }\n }\n \n }.bind(this, eventHandler.target, eventHandler.handler));\n \n }.bind(this));\n }\n this.bound = true;\n } else {\n console.log(this.name + ' already bound');\n }\n },\n destroy: function () {\n\n }\n };\n\n pageManager.Page.create = function (name, url, section) {\n var page = new pageManager.Page(name, url, section);\n page.super = {};\n page.super.render = pageManager.Page.prototype.render.bind(page);\n page.super.run = pageManager.Page.prototype.run.bind(page);\n page.super.destroy = pageManager.Page.prototype.destroy.bind(page);\n return page;\n };\n\n fc.pageManager = pageManager;\n\n}(FakeCation));\n","if (!HTMLCanvasElement.prototype.toBlob) {\n Object.defineProperty(HTMLCanvasElement.prototype, 'toBlob', {\n value: function (callback, type, quality) {\n\n var binStr = atob( this.toDataURL(type, quality).split(',')[1] ),\n len = binStr.length,\n arr = new Uint8Array(len);\n\n for (var i=0; i [2, 3]\n function MooreNeighbour(start_point) {\n //clockwise order\n var positions = [\n [0, 1],\n [-1, 1],\n [-1, 0],\n [-1, -1],\n [0, -1],\n [1, -1],\n [1, 0],\n [1, 1]\n ];\n\n var x = start_point[0];\n var y = start_point[1];\n var old_cell = [x, y + 1];\n\n // based on diff return the next position clockwise\n function clockwise_next(diff) {\n for (var i = 0; i < 8; ++i) {\n var d = positions[i];\n if (d[0] === diff[0] && d[1] === diff[1]) {\n return positions[(i + 1) % 8];\n }\n }\n }\n\n // with current cell and old_cell return new cell to test\n function next_cell(cell, old_cell) {\n var dx = cell[0] - old_cell[0];\n var dy = cell[1] - old_cell[1];\n var i = clockwise_next([-dx, -dy]);\n return [cell[0] + i[0], cell[1] + i[1]];\n }\n\n // return next contour cell, undefined if no new cell\n this.next = function (inside) {\n var c = 8; // max 8 positions to test\n while (c--) {\n var n = next_cell([x, y], old_cell);\n if (inside(n[0], n[1])) {\n //console.log(\"curr\", [x, y], \"to\", n, \"old\", old_cell);\n x = n[0];\n y = n[1];\n return [x, y];\n }\n old_cell = n;\n }\n };\n }\n\n /**\n this function finds contour for a bunch of pixel given\n color of an image.\n Uses the Moore-Neighbor Tracing.\n Returns poligon whitout any processing\n usage:\n var poly = countour(ctx_imagedata.data, ctx.with, ctx.height, pointx, pointy)\n */\n function contour(image_data, width, height, x, y) {\n\n var components = 4; //rgba\n\n // get color to match\n var pixel_pos = (y * width + x) * components;\n var color = [image_data[pixel_pos],\n image_data[pixel_pos + 1],\n image_data[pixel_pos + 2]\n ];\n\n // helper\n function match_color(x, y) {\n if (x < 0 || x >= width || y < 0 || y >= height) {\n return false;\n }\n\n var pixel_pos = (y * width + x) * components;\n return color[0] === image_data[pixel_pos] &&\n color[1] === image_data[pixel_pos + 1] &&\n color[2] === image_data[pixel_pos + 2];\n }\n\n var poly = [];\n\n // first find the starting point\n var lower_y = y;\n var dummyForLint = 0;\n while (match_color(x, ++lower_y)) {\n dummyForLint++;\n }\n --lower_y;\n var start_point = [x, lower_y];\n\n // start with moore-neightbor\n var moore = new MooreNeighbour(start_point);\n var point;\n do {\n point = moore.next(match_color);\n poly.push(point);\n } while (!(start_point[0] === point[0] && start_point[1] === point[1]) && point !== undefined);\n return poly;\n }\n\n function createMask(imgData, width, height) {\n var x, y, offset, w = imgData.width || width,\n h = imgData.height || height,\n data = imgData.length ? imgData : imgData.data;\n\n for (y = 0; y < h; y++) {\n for (x = 0; x < w; x++) {\n offset = (y * w + x) * 4;\n if (data[offset + 3] > 0) {\n data[offset] = 255;\n data[offset + 1] = 0;\n data[offset + 2] = 0;\n data[offset + 3] = 255;\n } else {\n data[offset] = 0;\n data[offset + 1] = 255;\n data[offset + 2] = 0;\n data[offset + 3] = 255;\n }\n }\n }\n }\n\n function tracer(imgData, cx, cy, width, height) {\n var result;\n\n result = contour(imgData.length ? imgData : imgData.data, imgData.width || width, imgData.height || height, parseInt(cx, 10), parseInt(cy, 10));\n\n return result;\n }\n\n function draw_poly(ctx, poly, color, width) {\n ctx.strokeStyle = color || \"rgb(255, 0, 128)\";\n ctx.lineWidth = width || 1;\n ctx.beginPath();\n var p = poly[0];\n ctx.moveTo(p[0], p[1]);\n for (var i = 1; i < poly.length; ++i) {\n p = poly[i];\n ctx.lineTo(p[0], p[1]);\n }\n ctx.closePath();\n ctx.stroke();\n }\n\n function contract(poly, scale, ctx) {\n var middleX, middleY,\n bounding = {\n top: Infinity,\n left: Infinity,\n right: 0,\n bottom: 0\n };\n\n poly.forEach(function (p) {\n var x = p[0],\n y = p[1];\n\n if (y < bounding.top) {\n bounding.top = y;\n }\n if (y > bounding.bottom) {\n bounding.bottom = y;\n }\n\n if (x < bounding.left) {\n bounding.left = x;\n }\n\n if (x > bounding.right) {\n bounding.right = x;\n }\n });\n\n middleX = parseInt(bounding.left + (bounding.right - bounding.left) / 2, 10);\n middleY = parseInt(bounding.top + (bounding.bottom - bounding.top) / 2, 10);\n\n if (ctx) {\n ctx.strokeStyle = \"yellow\";\n ctx.rect(bounding.left, bounding.top, bounding.right - bounding.left, bounding.bottom - bounding.top);\n\n ctx.rect(middleX - 5, middleY - 5, 10, 10);\n ctx.stroke();\n\n }\n\n return poly.map(function (p) {\n var x = p[0],\n y = p[1];\n\n return [(x - middleX) * scale + middleX, (y - middleY) * scale + middleY];\n });\n }\n\n function greenboxOnPixels(imgData, pointArray, references, stops) {\n var points = [],\n refColors = references || [FakeCation.colorUtils.getColor(imgData, 100, 100)],\n blank = new FakeCation.colorUtils.Color(255, 0, 0, 0),\n stopColors = stops || false,\n isStopColor,\n counter = 0;\n\n function checkSimilar(refColor) {\n return refColor.similarHsl(this);\n }\n\n (pointArray || []).forEach(function (point) {\n var l = point[0] - 2,\n t = point[0] - 2,\n r = l + 5,\n b = t + 5,\n i, o;\n\n l = l < 0 ? 0 : l;\n t = t < 0 ? 0 : t;\n b = b > imgData.height ? imgData.height : b;\n r = r > imgData.width ? imgData.width : r;\n\n for (i = l; i < r; i++) {\n for (o = t; o < b; o++) {\n points.push([i, o]);\n }\n }\n });\n\n points.forEach(function (point) {\n var x = point[0],\n y = point[1],\n currentColor,\n isSimilarToRefcolors = false;\n\n isStopColor = stopColors !== false;\n currentColor = FakeCation.colorUtils.getColor(imgData, x, y);\n\n if (isStopColor) {\n isStopColor = stopColors.some(checkSimilar, currentColor);\n }\n\n if (!isStopColor) {\n isSimilarToRefcolors = refColors.some(checkSimilar, currentColor);\n }\n\n if (isSimilarToRefcolors) {\n FakeCation.colorUtils.setColor(imgData, x, y, blank);\n counter++;\n }\n\n });\n return counter;\n }\n\n function traceCountours(imageData, cx, cy, iteration, references, stops) {\n var currentIteration = 0,\n removedPixels,\n width = imageData.width,\n height = imageData.height;\n\n function iter() {\n console.log('traceCountours iteration:' + currentIteration + '/' + iteration);\n let mask = new Uint8ClampedArray(imageData.data);\n createMask(mask, width, height);\n let poly = contour(mask, width, height, parseInt(cx, 10), parseInt(cy, 10));\n\n poly.forEach(function (point) {\n var x = point[0],\n y = point[1];\n var offset = (y * width + x) * 4;\n mask[offset] = 0;\n mask[offset + 1] = 0;\n mask[offset + 2] = 255;\n mask[offset + 3] = 255;\n\n });\n\n FakeCation.utils.dump(mask);\n\n removedPixels = greenboxOnPixels(imageData, poly, references, stops);\n currentIteration++;\n console.log('removedPixels: ' + removedPixels);\n if (currentIteration < iteration) {\n window.requestAnimationFrame(iter);\n }\n }\n\n window.requestAnimationFrame(iter);\n\n }\n\n ns.tracer = tracer;\n ns.draw_contour = draw_poly;\n ns.contract = contract;\n ns.createMask = createMask;\n ns.greenboxOnPixels = greenboxOnPixels;\n ns.traceContours = traceCountours;\n\n}(FakeCation));\n","/*global loadImage*/\nvar FakeCation = window.FakeCation || {};\n\n(function (fc) {\n \"use strict\";\n\n var utils = {};\n\n utils.filters = {};\n utils.blenders = {};\n utils.webRTCSupported = !!navigator.getUserMedia && false;\n utils.STATE = {\n webcamEl: null,\n canvasEl: null,\n inputEl: null\n };\n utils.DEBUG_CANVAS = 'debug';\n\n utils.registerFilter = function (name, filter) {\n this.filters[name] = filter;\n };\n\n utils.getFilter = function (name) {\n return this.filters[name];\n };\n\n utils.getFilterNames = function () {\n return Object.keys(this.filters);\n };\n\n utils.doFilter = function (name, canvas, cb, config) {\n var filter = this.getFilter(name);\n\n canvas = canvas || this.getCanvas();\n\n if (filter) {\n filter(this.canvas2imgData(canvas), cb, config);\n } else {\n cb();\n }\n };\n\n utils.pleaseFilter = function (name, canvas, config) {\n return new Promise(\n function (resolve, reject) {\n var filter = this.getFilter(name),\n c = config || {};\n\n canvas = canvas || this.getCanvas();\n c.reject = reject;\n if (filter) {\n if (canvas.data) {\n filter(canvas, resolve, c);\n } else {\n filter(this.canvas2imgData(canvas), resolve, c);\n }\n } else {\n reject();\n }\n }.bind(this));\n };\n\n utils.registerBlender = function (name, blender) {\n this.blenders[name] = blender;\n };\n\n utils.getBlender = function (name) {\n return this.blenders[name];\n };\n\n utils.getBlenderNames = function () {\n return Object.keys(this.blenders);\n };\n\n utils.doBlend = function (name, canvas, background, cb, config) {\n var blender = this.getBlender(name);\n\n canvas = canvas || this.getCanvas();\n\n if (blender) {\n blender(this.canvas2imgData(canvas), background, cb, config);\n } else {\n cb();\n }\n };\n\n utils.pleaseBlend = function (name, canvas, background, config) {\n return new Promise(\n function (resolve, reject) {\n var blender = this.getBlender(name);\n\n canvas = canvas || this.getCanvas();\n\n if (blender) {\n if (canvas.data) {\n blender(canvas, background, resolve, config);\n } else {\n blender(this.canvas2imgData(canvas), background, resolve, config);\n }\n } else {\n reject();\n }\n }.bind(this));\n };\n\n utils.createWebcam = function (placeholder, id, width, height) {\n var webcam,\n placeholderEl;\n\n // check webRTC support\n if (!navigator.getUserMedia) {\n return null;\n }\n\n webcam = document.createElement('video');\n webcam.id = id || 'webcam';\n webcam.width = width || 640;\n webcam.height = height || 480;\n\n placeholder = placeholder || 'webcamHolder';\n placeholderEl = typeof placeholder === 'string' ? document.getElementById(placeholder) : placeholder;\n\n try {\n placeholderEl.appendChild(webcam);\n this.STATE.webcamEl = webcam;\n } catch (e) {\n console.error('Webcam creation failed: ' + e);\n }\n\n return webcam;\n };\n\n utils.createCanvas = function (placeholder, id, width, height) {\n var canvas = document.createElement('canvas'),\n placeholderEl;\n\n canvas.id = id || 'canvas';\n canvas.width = width || 640;\n canvas.height = height || 480;\n\n placeholder = placeholder || 'canvasHolder';\n placeholderEl = typeof placeholder === 'string' ? document.getElementById(placeholder) : placeholder;\n\n try {\n placeholderEl.appendChild(canvas);\n this.STATE.canvasEl = canvas;\n } catch (e) {\n console.error('Canvas creation failed: ' + e);\n }\n\n return canvas;\n };\n\n utils.createImageInput = function (placeholder, id) {\n var input = document.createElement('input'),\n placeholderEl;\n\n input.id = id || 'imageInput';\n input.type = 'file';\n input.accept = 'image/*';\n input.capture = 'camera';\n input.placeholder = 'Take a photo!';\n\n placeholder = placeholder || 'imageInputHolder';\n placeholderEl = typeof placeholder === 'string' ? document.getElementById(placeholder) : placeholder;\n\n try {\n placeholderEl.appendChild(input);\n this.STATE.inputEl = input;\n } catch (e) {\n console.error('Image input creation failed: ' + e);\n }\n\n return input;\n };\n\n utils.initWebcam = function (webcam) {\n // check webRTC support\n if (!navigator.getUserMedia) {\n return null;\n }\n\n webcam = webcam || this.getWebcam();\n\n navigator.getUserMedia({\n video: true\n },\n utils.webcamSuccess.bind(utils),\n function (err) {\n console.log('Webcam initialization failed: ' + err);\n }\n );\n };\n\n utils.webcamSuccess = function (stream) {\n var video = this.getWebcam();\n\n video.autoplay = true;\n video.src = window.URL.createObjectURL(stream);\n\n video.addEventListener('playing', this.videoPlayingCB.bind(this));\n };\n\n utils.videoPlayingCB = function () {\n setTimeout(function () {\n var video = utils.getWebcam();\n\n if (video.width !== video.videoWidth || video.height !== video.videoHeight) {\n video.width = video.videoWidth;\n video.height = video.videoHeight;\n }\n\n }, 100);\n };\n\n utils.getWebcam = function () {\n return this.STATE.webcamEl;\n };\n utils.getCanvas = function () {\n return this.STATE.canvasEl;\n };\n utils.getInput = function () {\n return this.STATE.inputEl;\n };\n\n utils.video2canvas = function (video, canvas, callback) {\n video = video || this.getWebcam();\n canvas = canvas || this.getCanvas();\n\n canvas.width = video.width;\n canvas.height = video.height;\n\n canvas.getContext('2d').drawImage(video, 0, 0, video.width, video.height, 0, 0, canvas.width, canvas.height);\n\n if (callback) {\n callback(canvas);\n }\n };\n\n utils.image2canvas = function (image, canvas, callback) {\n var img = new Image();\n\n canvas = canvas || this.getCanvas();\n img.src = image;\n\n img.onload = function () {\n utils.img2canvas(img, canvas, callback);\n };\n };\n\n utils.img2canvas = function (img, canvas, callback) {\n canvas = canvas || this.getCanvas();\n\n canvas.width = img.width;\n canvas.height = img.height;\n canvas.getContext('2d').drawImage(img, 0, 0);\n\n if (callback) {\n callback(canvas);\n }\n };\n\n utils.input2canvas = function (input, canvas, mWidth, mHeight, callback) {\n var file;\n\n canvas = canvas || this.getCanvas();\n input = input || this.getInput();\n\n if (!input.files || !input.files.length) {\n return null;\n }\n\n file = input.files[0];\n\n loadImage.parseMetaData(\n file,\n function (data) {\n // exif info is available here\n loadImage(\n file,\n function (img) {\n console.time('loadImage');\n utils.img2canvas(img, canvas, callback);\n console.timeEnd('loadImage');\n }, {\n canvas: true,\n orientation: data && data.exif && data.exif.get('Orientation'),\n maxWidth: mWidth,\n maxHeight: mHeight\n }\n );\n }\n );\n\n };\n\n utils.canvas2imgData = function (canvas) {\n var ctx;\n\n canvas = canvas || this.getCanvas();\n\n ctx = canvas.getContext(\"2d\");\n\n return ctx.getImageData(0, 0, canvas.width, canvas.height);\n };\n\n fc.utils = utils;\n\n /**\n * A simple math function that calculates Euclidean distance\n * between two two-dimensional points.\n *\n * @param p1 Array of coordinates\n * @param p2 Array of coordinates\n *\n * @return distance\n */\n utils.distance = function (p1, p2) {\n return Math.sqrt(\n Math.pow(p1[0] - p2[0], 2) +\n Math.pow(p1[1] - p2[1], 2)\n );\n };\n\n utils.dump = function (imgData, canvasId, width, height) {\n var id = canvasId || utils.DEBUG_CANVAS,\n canvas = document.getElementById(id),\n ctx, idata;\n\n if (!canvas) {\n canvas = document.createElement('canvas');\n canvas.id = id;\n document.body.appendChild(canvas);\n }\n ctx = canvas.getContext('2d');\n\n if (imgData.getContext) {\n canvas.width = imgData.width;\n canvas.height = imgData.height;\n ctx.drawImage(imgData, 0, 0);\n return ctx;\n } else {\n if (imgData.rect) {\n idata = imgData.getImageData(0, 0, imgData.canvas.width, imgData.canvas.height);\n } else if (imgData.length) {\n let i, length = imgData.length;\n idata = ctx.createImageData(width, height);\n for (i = 0; i < length; i++) {\n idata.data[i] = imgData[i];\n }\n } else {\n idata = imgData;\n }\n canvas.width = idata.width;\n canvas.height = idata.height;\n ctx.putImageData(idata, 0, 0);\n return ctx;\n }\n };\n\n}(FakeCation));\n"],"sourceRoot":"/source/"}