Skip to content

Instantly share code, notes, and snippets.

@akre54
Last active August 29, 2015 14:04
Show Gist options
  • Save akre54/fedabcdc8b0d59d6093c to your computer and use it in GitHub Desktop.
Save akre54/fedabcdc8b0d59d6093c to your computer and use it in GitHub Desktop.
Draw circles on canvas
{requestInterval, clearRequestInterval} = require './animation-helpers'
NUM_CIRCLES = 2500
MAX_RADIUS = 80
MIN_RADIUS = 4
bgCanvas = document.getElementById "bg"
fgCanvas = document.getElementById "fg"
bg = bgCanvas.getContext "2d"
fg = fgCanvas.getContext "2d"
width = bgCanvas.width = fgCanvas.width = window.innerWidth
height = bgCanvas.height = fgCanvas.height = window.innerHeight
rand = (lower, upper) -> lower + Math.floor Math.random() * upper
dr = (i) -> .4 * Math.pow 1.5, i
class Circle
constructor: (@radius = MIN_RADIUS) ->
@x = rand 0, width
@y = rand 0, height
@color = if rand(0, 2) then '#ff0000' else '#0000ff'
circles = (new Circle for c in [0..NUM_CIRCLES])
activeCircles = []
animate = ->
fg.clearRect 0, 0, width, height
drawCircle fg, circle for circle in activeCircles
return
drawCircle = (ctx, circle) ->
ctx.beginPath()
ctx.arc circle.x, circle.y, circle.radius, 0, Math.PI * 2, true
ctx.lineWidth = 5
# line color
if circle.radius == MIN_RADIUS
ctx.fillStyle = circle.color
ctx.fill()
else
ctx.strokeStyle = circle.color
ctx.stroke()
ctx.closePath()
addCircle = ->
circle = new Circle MAX_RADIUS
activeCircles.push circle
iterations = 0
shrinkRadius = ->
iterations++
circle.radius -= dr iterations
if circle.radius < 0
clearRequestInterval newCircleInterval
circle.radius = MIN_RADIUS
# when done animating, draw it to the background canvas
## activeCircles.splice activeCircles.indexOf(circle), 1
drawCircle bg, circle
circles.push circle
newCircleInterval = requestInterval shrinkRadius, 20
# initialize the background canvas with original circles
drawCircle bg, circle for circle in circles
requestInterval animate, 20
requestInterval addCircle, 1500
!function(n){function t(i){if(e[i])return e[i].exports;var o=e[i]={exports:{},id:i,loaded:!1};return n[i].call(o.exports,o,o.exports,t),o.loaded=!0,o.exports}var e={};return t.m=n,t.c=e,t.p="public/",t(0)}([function(n,t,e){var i,o,r,a,u,c,l,d,w,f,s,m,h,v,p,g,q,A,F,y,x,I,R,b;for(b=e(1),y=b.requestInterval,h=b.clearRequestInterval,a=2500,o=80,r=4,w=document.getElementById("bg"),q=document.getElementById("fg"),d=w.getContext("2d"),g=q.getContext("2d"),x=w.width=q.width=window.innerWidth,A=w.height=q.height=window.innerHeight,F=function(n,t){return n+Math.floor(Math.random()*t)},v=function(n){return.4*Math.pow(1.5,n)},i=function(){function n(n){this.radius=null!=n?n:r,this.x=F(0,x),this.y=F(0,A),this.color=F(0,2)?"#ff0000":"#0000ff"}return n}(),m=function(){var n,t;for(t=[],f=n=0;a>=0?a>=n:n>=a;f=a>=0?++n:--n)t.push(new i);return t}(),u=[],l=function(){var n,t,e;for(g.clearRect(0,0,x,A),t=0,e=u.length;e>t;t++)n=u[t],p(g,n)},p=function(n,t){return n.beginPath(),n.arc(t.x,t.y,t.radius,0,2*Math.PI,!0),n.lineWidth=5,t.radius===r?(n.fillStyle=t.color,n.fill()):(n.strokeStyle=t.color,n.stroke()),n.closePath()},c=function(){var n,t,e,a;return n=new i(o),u.push(n),t=0,a=function(){return t++,n.radius-=v(t),n.radius<0?(h(e),n.radius=r,p(d,n),m.push(n)):void 0},e=y(a,20)},I=0,R=m.length;R>I;I++)s=m[I],p(d,s);y(l,20),y(c,1500)},function(n,t){t.requestInterval=function(n,t){var e,i,o,r;return r=Date.now(),i=function(){var e,a,u;e=Date.now(),a=e-r,a>=t&&(n(),r=Date.now()),u=o(i)},o=function(){return window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame}(),o?e=o(i):setInterval(n,t)},t.clearRequestInterval=function(n){("function"==typeof window.cancelAnimationFrame?window.cancelAnimationFrame(n):void 0)||("function"==typeof window.webkitCancelAnimationFrame?window.webkitCancelAnimationFrame(n):void 0)||("function"==typeof window.webkitCancelRequestAnimationFrame?window.webkitCancelRequestAnimationFrame(n):void 0)||("function"==typeof window.mozCancelRequestAnimationFrame?window.mozCancelRequestAnimationFrame(n):void 0)||clearInterval(n)}}]);
/*
//@ sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2lyY2xlLXRlc3QuanMiLCJzb3VyY2VzIjpbImNpcmNsZS10ZXN0LmpzIiwid2VicGFjay9ib290c3RyYXAgOGE0YjI2ODY2M2ExNzZkZmY2ZjMiLCIuL2FwcC9qcy9jaXJjbGUtdGVzdC5jb2ZmZWUiLCIuL2FwcC9qcy9jaXJjbGUtdGVzdC5jb2ZmZWUqIiwiLi9hcHAvanMvYW5pbWF0aW9uLWhlbHBlcnMuY29mZmVlIiwiLi9hcHAvanMvYW5pbWF0aW9uLWhlbHBlcnMuY29mZmVlKiJdLCJuYW1lcyI6WyJtb2R1bGVzIiwiX193ZWJwYWNrX3JlcXVpcmVfXyIsIm1vZHVsZUlkIiwiaW5zdGFsbGVkTW9kdWxlcyIsImV4cG9ydHMiLCJtb2R1bGUiLCJpZCIsImxvYWRlZCIsImNhbGwiLCJtIiwiYyIsInAiLCJDaXJjbGUiLCJNQVhfUkFESVVTIiwiTUlOX1JBRElVUyIsIk5VTV9DSVJDTEVTIiwiYWN0aXZlQ2lyY2xlcyIsImFkZENpcmNsZSIsImFuaW1hdGUiLCJiZyIsImJnQ2FudmFzIiwiY2lyY2xlIiwiY2lyY2xlcyIsImNsZWFyUmVxdWVzdEludGVydmFsIiwiZHIiLCJkcmF3Q2lyY2xlIiwiZmciLCJmZ0NhbnZhcyIsImhlaWdodCIsInJhbmQiLCJyZXF1ZXN0SW50ZXJ2YWwiLCJ3aWR0aCIsIl9pIiwiX2xlbiIsIl9yZWYiLCJkb2N1bWVudCIsImdldEVsZW1lbnRCeUlkIiwiZ2V0Q29udGV4dCIsIndpbmRvdyIsImlubmVyV2lkdGgiLCJpbm5lckhlaWdodCIsImxvd2VyIiwidXBwZXIiLCJNYXRoIiwiZmxvb3IiLCJyYW5kb20iLCJpIiwicG93IiwicmFkaXVzIiwidGhpcyIsIngiLCJ5IiwiY29sb3IiLCJfcmVzdWx0cyIsInB1c2giLCJjbGVhclJlY3QiLCJsZW5ndGgiLCJjdHgiLCJiZWdpblBhdGgiLCJhcmMiLCJQSSIsImxpbmVXaWR0aCIsImZpbGxTdHlsZSIsImZpbGwiLCJzdHJva2VTdHlsZSIsInN0cm9rZSIsImNsb3NlUGF0aCIsIml0ZXJhdGlvbnMiLCJuZXdDaXJjbGVJbnRlcnZhbCIsInNocmlua1JhZGl1cyIsImZuIiwiZGVsYXkiLCJpbnRlcnZhbCIsImxhdGVyIiwicmVxdWVzdEFuaW1GcmFtZSIsInN0YXJ0IiwiRGF0ZSIsIm5vdyIsImN1cnJlbnQiLCJkZWx0YSIsInJlcXVlc3RBbmltYXRpb25GcmFtZSIsIndlYmtpdFJlcXVlc3RBbmltYXRpb25GcmFtZSIsIm1velJlcXVlc3RBbmltYXRpb25GcmFtZSIsInNldEludGVydmFsIiwiaGFuZGxlIiwiY2FuY2VsQW5pbWF0aW9uRnJhbWUiLCJ3ZWJraXRDYW5jZWxBbmltYXRpb25GcmFtZSIsIndlYmtpdENhbmNlbFJlcXVlc3RBbmltYXRpb25GcmFtZSIsIm1vekNhbmNlbFJlcXVlc3RBbmltYXRpb25GcmFtZSIsImNsZWFySW50ZXJ2YWwiXSwibWFwcGluZ3MiOiJDQUFTLFNBQVVBLEdDS25CLFFBQUFDLEdBQUFDLEdBRUEsR0FBQUMsRUFBQUQsR0FDQSxNQUFBQyxHQUFBRCxHQUFBRSxPQUdBLElBQUFDLEdBQUFGLEVBQUFELElBQ0FFLFdBQ0FFLEdBQUFKLEVBQ0FLLFFBQUEsRUFVQSxPQU5BUCxHQUFBRSxHQUFBTSxLQUFBSCxFQUFBRCxRQUFBQyxJQUFBRCxRQUFBSCxHQUdBSSxFQUFBRSxRQUFBLEVBR0FGLEVBQUFELFFBdEJBLEdBQUFELEtBcUNBLE9BVkFGLEdBQUFRLEVBQUFULEVBR0FDLEVBQUFTLEVBQUFQLEVBR0FGLEVBQUFVLEVBQUEsVUFJQVYsRUFBQSxLRE1NLFNBQVNJLEVBQVFELEVBQVNILEdFN0NoQyxHQUFBVyxHQUFBQyxFQUFBQyxFQUFBQyxFQUFBQyxFQUFBQyxFQUFBQyxFQUFBQyxFQUFBQyxFQUFBVixFQUFBVyxFQUFBQyxFQUFBQyxFQUFBQyxFQUFBQyxFQUFBQyxFQUFBQyxFQUFBQyxFQUFBQyxFQUFBQyxFQUFBQyxFQUFBQyxFQUFBQyxFQUFBQyxDQWtFQSxLQWxFQUEsRUFBQWpDLEVBQUEsR0FBQTZCLEVBQUFJLEVBQUFKLGdCQUFBUCxF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QUFBQyxJQWJGbkUsRUFBQW1CLHFCQUFBLFNBQUE2RCxJQWtCRSxrQkFBQTlDLFFBQUErQyxxQkFBQS9DLE9BQUErQyxxQkFBQUQsR0FBQSw0QkFBQTlDLFFBQUFnRCwyQkFBQWhELE9BQUFnRCwyQkFBQUYsR0FBQSw0QkFBQTlDLFFBQUFpRCxrQ0FBQWpELE9BQUFpRCxrQ0FBQUgsR0FBQSw0QkFBQTlDLFFBQUFrRCwrQkFBQWxELE9BQUFrRCwrQkFBQUosR0FBQSxTQUFBSyxjQUFBTCIsInNvdXJjZXNDb250ZW50IjpbIi8qKioqKiovIChmdW5jdGlvbihtb2R1bGVzKSB7IC8vIHdlYnBhY2tCb290c3RyYXBcbi8qKioqKiovIFx0XG4vKioqKioqLyBcdC8vIFRoZSBtb2R1bGUgY2FjaGVcbi8qKioqKiovIFx0dmFyIGluc3RhbGxlZE1vZHVsZXMgPSB7fTtcbi8qKioqKiovIFx0XG4vKioqKioqLyBcdC8vIFRoZSByZXF1aXJlIGZ1bmN0aW9uXG4vKioqKioqLyBcdGZ1bmN0aW9uIF9fd2VicGFja19yZXF1aXJlX18obW9kdWxlSWQpIHtcbi8qKioqKiovIFx0XHQvLyBDaGVjayBpZiBtb2R1bGUgaXMgaW4gY2FjaGVcbi8qKioqKiovIFx0XHRpZihpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXSlcbi8qKioqKiovIFx0XHRcdHJldHVybiBpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXS5leHBvcnRzO1xuLyoqKioqKi8gXHRcdFxuLyoqKioqKi8gXHRcdC8vIENyZWF0ZSBhIG5ldyBtb2R1bGUgKGFuZCBwdXQgaXQgaW50byB0aGUgY2FjaGUpXG4vKioqKioqLyBcdFx0dmFyIG1vZHVsZSA9IGluc3RhbGxlZE1vZHVsZXNbbW9kdWxlSWRdID0ge1xuLyoqKioqKi8gXHRcdFx0ZXhwb3J0czoge30sXG4vKioqKioqLyBcdFx0XHRpZDogbW9kdWxlSWQsXG4vKioqKioqLyBcdFx0XHRsb2FkZWQ6IGZhbHNlXG4vKioqKioqLyBcdFx0fTtcbi8qKioqKiovIFx0XHRcbi8qKioqKiovIFx0XHQvLyBFeGVjdXRlIHRoZSBtb2R1bGUgZnVuY3Rpb25cbi8qKioqKiovIFx0XHRtb2R1bGVzW21vZHVsZUlkXS5jYWxsKG1vZHVsZS5leHBvcnRzLCBtb2R1bGUsIG1vZHVsZS5leHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKTtcbi8qKioqKiovIFx0XHRcbi8qKioqKiovIFx0XHQvLyBGbGFnIHRoZSBtb2R1bGUgYXMgbG9hZGVkXG4vKioqKioqLyBcdFx0bW9kdWxlLmxvYWRlZCA9IHRydWU7XG4vKioqKioqLyBcdFx0XG4vKioqKioqLyBcdFx0Ly8gUmV0dXJuIHRoZSBleHBvcnRzIG9mIHRoZSBtb2R1bGVcbi8qKioqKiovIFx0XHRyZXR1cm4gbW9kdWxlLmV4cG9ydHM7XG4vKioqKioqLyBcdH1cbi8qKioqKiovIFx0XG4vKioqKioqLyBcdFxuLyoqKioqKi8gXHQvLyBleHBvc2UgdGhlIG1vZHVsZXMgb2JqZWN0IChfX3dlYnBhY2tfbW9kdWxlc19fKVxuLyoqKioqKi8gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLm0gPSBtb2R1bGVzO1xuLyoqKioqKi8gXHRcbi8qKioqKiovIFx0Ly8gZXhwb3NlIHRoZSBtb2R1bGUgY2FjaGVcbi8qKioqKiovIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5jID0gaW5zdGFsbGVkTW9kdWxlcztcbi8qKioqKiovIFx0XG4vKioqKioqLyBcdC8vIF9fd2VicGFja19wdWJsaWNfcGF0aF9fXG4vKioqKioqLyBcdF9fd2VicGFja19yZXF1aXJlX18ucCA9IFwicHVibGljL1wiO1xuLyoqKioqKi8gXHRcbi8qKioqKiovIFx0XG4vKioqKioqLyBcdC8vIExvYWQgZW50cnkgbW9kdWxlIGFuZCByZXR1cm4gZXhwb3J0c1xuLyoqKioqKi8gXHRyZXR1cm4gX193ZWJwYWNrX3JlcXVpcmVfXygwKTtcbi8qKioqKiovIH0pXG4vKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuLyoqKioqKi8gKFtcbi8qIDAgKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5cdHZhciBDaXJjbGUsIE1BWF9SQURJVVMsIE1JTl9SQURJVVMsIE5VTV9DSVJDTEVTLCBhY3RpdmVDaXJjbGVzLCBhZGRDaXJjbGUsIGFuaW1hdGUsIGJnLCBiZ0NhbnZhcywgYywgY2lyY2xlLCBjaXJjbGVzLCBjbGVhclJlcXVlc3RJbnRlcnZhbCwgZHIsIGRyYXdDaXJjbGUsIGZnLCBmZ0NhbnZhcywgaGVpZ2h0LCByYW5kLCByZXF1ZXN0SW50ZXJ2YWwsIHdpZHRoLCBfaSwgX2xlbiwgX3JlZjtcblx0XG5cdF9yZWYgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDEpLCByZXF1ZXN0SW50ZXJ2YWwgPSBfcmVmLnJlcXVlc3RJbnRlcnZhbCwgY2xlYXJSZXF1ZXN0SW50ZXJ2YWwgPSBfcmVmLmNsZWFyUmVxdWVzdEludGVydmFsO1xuXHRcblx0TlVNX0NJUkNMRVMgPSAyNTAwO1xuXHRcblx0TUFYX1JBRElVUyA9IDgwO1xuXHRcblx0TUlOX1JBRElVUyA9IDQ7XG5cdFxuXHRiZ0NhbnZhcyA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFwiYmdcIik7XG5cdFxuXHRmZ0NhbnZhcyA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFwiZmdcIik7XG5cdFxuXHRiZyA9IGJnQ2FudmFzLmdldENvbnRleHQoXCIyZFwiKTtcblx0XG5cdGZnID0gZmdDYW52YXMuZ2V0Q29udGV4dChcIjJkXCIpO1xuXHRcblx0d2lkdGggPSBiZ0NhbnZhcy53aWR0aCA9IGZnQ2FudmFzLndpZHRoID0gd2luZG93LmlubmVyV2lkdGg7XG5cdFxuXHRoZWlnaHQgPSBiZ0NhbnZhcy5oZWlnaHQgPSBmZ0NhbnZhcy5oZWlnaHQgPSB3aW5kb3cuaW5uZXJIZWlnaHQ7XG5cdFxuXHRyYW5kID0gZnVuY3Rpb24obG93ZXIsIHVwcGVyKSB7XG5cdCAgcmV0dXJuIGxvd2VyICsgTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogdXBwZXIpO1xuXHR9O1xuXHRcblx0ZHIgPSBmdW5jdGlvbihpKSB7XG5cdCAgcmV0dXJuIC40ICogTWF0aC5wb3coMS41LCBpKTtcblx0fTtcblx0XG5cdENpcmNsZSA9IChmdW5jdGlvbigpIHtcblx0ICBmdW5jdGlvbiBDaXJjbGUocmFkaXVzKSB7XG5cdCAgICB0aGlzLnJhZGl1cyA9IHJhZGl1cyAhPSBudWxsID8gcmFkaXVzIDogTUlOX1JBRElVUztcblx0ICAgIHRoaXMueCA9IHJhbmQoMCwgd2lkdGgpO1xuXHQgICAgdGhpcy55ID0gcmFuZCgwLCBoZWlnaHQpO1xuXHQgICAgdGhpcy5jb2xvciA9IHJhbmQoMCwgMikgPyAnI2ZmMDAwMCcgOiAnIzAwMDBmZic7XG5cdCAgfVxuXHRcblx0ICByZXR1cm4gQ2lyY2xlO1xuXHRcblx0fSkoKTtcblx0XG5cdGNpcmNsZXMgPSAoZnVuY3Rpb24oKSB7XG5cdCAgdmFyIF9pLCBfcmVzdWx0cztcblx0ICBfcmVzdWx0cyA9IFtdO1xuXHQgIGZvciAoYyA9IF9pID0gMDsgMCA8PSBOVU1fQ0lSQ0xFUyA/IF9pIDw9IE5VTV9DSVJDTEVTIDogX2kgPj0gTlVNX0NJUkNMRVM7IGMgPSAwIDw9IE5VTV9DSVJDTEVTID8gKytfaSA6IC0tX2kpIHtcblx0ICAgIF9yZXN1bHRzLnB1c2gobmV3IENpcmNsZSk7XG5cdCAgfVxuXHQgIHJldHVybiBfcmVzdWx0cztcblx0fSkoKTtcblx0XG5cdGFjdGl2ZUNpcmNsZXMgPSBbXTtcblx0XG5cdGFuaW1hdGUgPSBmdW5jdGlvbigpIHtcblx0ICB2YXIgY2lyY2xlLCBfaSwgX2xlbjtcblx0ICBmZy5jbGVhclJlY3QoMCwgMCwgd2lkdGgsIGhlaWdodCk7XG5cdCAgZm9yIChfaSA9IDAsIF9sZW4gPSBhY3RpdmVDaXJjbGVzLmxlbmd0aDsgX2kgPCBfbGVuOyBfaSsrKSB7XG5cdCAgICBjaXJjbGUgPSBhY3RpdmVDaXJjbGVzW19pXTtcblx0ICAgIGRyYXdDaXJjbGUoZmcsIGNpcmNsZSk7XG5cdCAgfVxuXHR9O1xuXHRcblx0ZHJhd0NpcmNsZSA9IGZ1bmN0aW9uKGN0eCwgY2lyY2xlKSB7XG5cdCAgY3R4LmJlZ2luUGF0aCgpO1xuXHQgIGN0eC5hcmMoY2lyY2xlLngsIGNpcmNsZS55LCBjaXJjbGUucmFkaXVzLCAwLCBNYXRoLlBJICogMiwgdHJ1ZSk7XG5cdCAgY3R4LmxpbmVXaWR0aCA9IDU7XG5cdCAgaWYgKGNpcmNsZS5yYWRpdXMgPT09IE1JTl9SQURJVVMpIHtcblx0ICAgIGN0eC5maWxsU3R5bGUgPSBjaXJjbGUuY29sb3I7XG5cdCAgICBjdHguZmlsbCgpO1xuXHQgIH0gZWxzZSB7XG5cdCAgICBjdHguc3Ryb2tlU3R5bGUgPSBjaXJjbGUuY29sb3I7XG5cdCAgICBjdHguc3Ryb2tlKCk7XG5cdCAgfVxuXHQgIHJldHVybiBjdHguY2xvc2VQYXRoKCk7XG5cdH07XG5cdFxuXHRhZGRDaXJjbGUgPSBmdW5jdGlvbigpIHtcblx0ICB2YXIgY2lyY2xlLCBpdGVyYXRpb25zLCBuZXdDaXJjbGVJbnRlcnZhbCwgc2hyaW5rUmFkaXVzO1xuXHQgIGNpcmNsZSA9IG5ldyBDaXJjbGUoTUFYX1JBRElVUyk7XG5cdCAgYWN0aXZlQ2lyY2xlcy5wdXNoKGNpcmNsZSk7XG5cdCAgaXRlcmF0aW9ucyA9IDA7XG5cdCAgc2hyaW5rUmFkaXVzID0gZnVuY3Rpb24oKSB7XG5cdCAgICBpdGVyYXRpb25zKys7XG5cdCAgICBjaXJjbGUucmFkaXVzIC09IGRyKGl0ZXJhdGlvbnMpO1xuXHQgICAgaWYgKGNpcmNsZS5yYWRpdXMgPCAwKSB7XG5cdCAgICAgIGNsZWFyUmVxdWVzdEludGVydmFsKG5ld0NpcmNsZUludGVydmFsKTtcblx0ICAgICAgY2lyY2xlLnJhZGl1cyA9IE1JTl9SQURJVVM7XG5cdCAgICAgIGRyYXdDaXJjbGUoYmcsIGNpcmNsZSk7XG5cdCAgICAgIHJldHVybiBjaXJjbGVzLnB1c2goY2lyY2xlKTtcblx0ICAgIH1cblx0ICB9O1xuXHQgIHJldHVybiBuZXdDaXJjbGVJbnRlcnZhbCA9IHJlcXVlc3RJbnRlcnZhbChzaHJpbmtSYWRpdXMsIDIwKTtcblx0fTtcblx0XG5cdGZvciAoX2kgPSAwLCBfbGVuID0gY2lyY2xlcy5sZW5ndGg7IF9pIDwgX2xlbjsgX2krKykge1xuXHQgIGNpcmNsZSA9IGNpcmNsZXNbX2ldO1xuXHQgIGRyYXdDaXJjbGUoYmcsIGNpcmNsZSk7XG5cdH1cblx0XG5cdHJlcXVlc3RJbnRlcnZhbChhbmltYXRlLCAyMCk7XG5cdFxuXHRyZXF1ZXN0SW50ZXJ2YWwoYWRkQ2lyY2xlLCAxNTAwKTtcblxuXG4vKioqLyB9LFxuLyogMSAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cblx0ZXhwb3J0cy5yZXF1ZXN0SW50ZXJ2YWwgPSBmdW5jdGlvbihmbiwgZGVsYXkpIHtcblx0ICB2YXIgaW50ZXJ2YWwsIGxhdGVyLCByZXF1ZXN0QW5pbUZyYW1lLCBzdGFydDtcblx0ICBzdGFydCA9IERhdGUubm93KCk7XG5cdCAgbGF0ZXIgPSBmdW5jdGlvbigpIHtcblx0ICAgIHZhciBjdXJyZW50LCBkZWx0YSwgaW50ZXJ2YWw7XG5cdCAgICBjdXJyZW50ID0gRGF0ZS5ub3coKTtcblx0ICAgIGRlbHRhID0gY3VycmVudCAtIHN0YXJ0O1xuXHQgICAgaWYgKGRlbHRhID49IGRlbGF5KSB7XG5cdCAgICAgIGZuKCk7XG5cdCAgICAgIHN0YXJ0ID0gRGF0ZS5ub3coKTtcblx0ICAgIH1cblx0ICAgIGludGVydmFsID0gcmVxdWVzdEFuaW1GcmFtZShsYXRlcik7XG5cdCAgfTtcblx0ICByZXF1ZXN0QW5pbUZyYW1lID0gKGZ1bmN0aW9uKCkge1xuXHQgICAgcmV0dXJuIHdpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUgfHwgd2luZG93LndlYmtpdFJlcXVlc3RBbmltYXRpb25GcmFtZSB8fCB3aW5kb3cubW96UmVxdWVzdEFuaW1hdGlvbkZyYW1lO1xuXHQgIH0pKCk7XG5cdCAgaWYgKCFyZXF1ZXN0QW5pbUZyYW1lKSB7XG5cdCAgICByZXR1cm4gc2V0SW50ZXJ2YWwoZm4sIGRlbGF5KTtcblx0ICB9XG5cdCAgcmV0dXJuIGludGVydmFsID0gcmVxdWVzdEFuaW1GcmFtZShsYXRlcik7XG5cdH07XG5cdFxuXHRleHBvcnRzLmNsZWFyUmVxdWVzdEludGVydmFsID0gZnVuY3Rpb24oaGFuZGxlKSB7XG5cdCAgKHR5cGVvZiB3aW5kb3cuY2FuY2VsQW5pbWF0aW9uRnJhbWUgPT09IFwiZnVuY3Rpb25cIiA/IHdpbmRvdy5jYW5jZWxBbmltYXRpb25GcmFtZShoYW5kbGUpIDogdm9pZCAwKSB8fCAodHlwZW9mIHdpbmRvdy53ZWJraXRDYW5jZWxBbmltYXRpb25GcmFtZSA9PT0gXCJmdW5jdGlvblwiID8gd2luZG93LndlYmtpdENhbmNlbEFuaW1hdGlvbkZyYW1lKGhhbmRsZSkgOiB2b2lkIDApIHx8ICh0eXBlb2Ygd2luZG93LndlYmtpdENhbmNlbFJlcXVlc3RBbmltYXRpb25GcmFtZSA9PT0gXCJmdW5jdGlvblwiID8gd2luZG93LndlYmtpdENhbmNlbFJlcXVlc3RBbmltYXRpb25GcmFtZShoYW5kbGUpIDogdm9pZCAwKSB8fCAodHlwZW9mIHdpbmRvdy5tb3pDYW5jZWxSZXF1ZXN0QW5pbWF0aW9uRnJhbWUgPT09IFwiZnVuY3Rpb25cIiA/IHdpbmRvdy5tb3pDYW5jZWxSZXF1ZXN0QW5pbWF0aW9uRnJhbWUoaGFuZGxlKSA6IHZvaWQgMCkgfHwgY2xlYXJJbnRlcnZhbChoYW5kbGUpO1xuXHR9O1xuXG5cbi8qKiovIH1cbi8qKioqKiovIF0pIiwiXG4vLyBUaGUgbW9kdWxlIGNhY2hlXG52YXIgaW5zdGFsbGVkTW9kdWxlcyA9IHt9O1xuXG4vLyBUaGUgcmVxdWlyZSBmdW5jdGlvblxuZnVuY3Rpb24gX193ZWJwYWNrX3JlcXVpcmVfXyhtb2R1bGVJZCkge1xuXHQvLyBDaGVjayBpZiBtb2R1bGUgaXMgaW4gY2FjaGVcblx0aWYoaW5zdGFsbGVkTW9kdWxlc1ttb2R1bGVJZF0pXG5cdFx0cmV0dXJuIGluc3RhbGxlZE1vZHVsZXNbbW9kdWxlSWRdLmV4cG9ydHM7XG5cdFxuXHQvLyBDcmVhdGUgYSBuZXcgbW9kdWxlIChhbmQgcHV0IGl0IGludG8gdGhlIGNhY2hlKVxuXHR2YXIgbW9kdWxlID0gaW5zdGFsbGVkTW9kdWxlc1ttb2R1bGVJZF0gPSB7XG5cdFx0ZXhwb3J0czoge30sXG5cdFx0aWQ6IG1vZHVsZUlkLFxuXHRcdGxvYWRlZDogZmFsc2Vcblx0fTtcblx0XG5cdC8vIEV4ZWN1dGUgdGhlIG1vZHVsZSBmdW5jdGlvblxuXHRtb2R1bGVzW21vZHVsZUlkXS5jYWxsKG1vZHVsZS5leHBvcnRzLCBtb2R1bGUsIG1vZHVsZS5leHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKTtcblx0XG5cdC8vIEZsYWcgdGhlIG1vZHVsZSBhcyBsb2FkZWRcblx0bW9kdWxlLmxvYWRlZCA9IHRydWU7XG5cdFxuXHQvLyBSZXR1cm4gdGhlIGV4cG9ydHMgb2YgdGhlIG1vZHVsZVxuXHRyZXR1cm4gbW9kdWxlLmV4cG9ydHM7XG59XG5cblxuLy8gZXhwb3NlIHRoZSBtb2R1bGVzIG9iamVjdCAoX193ZWJwYWNrX21vZHVsZXNfXylcbl9fd2VicGFja19yZXF1aXJlX18ubSA9IG1vZHVsZXM7XG5cbi8vIGV4cG9zZSB0aGUgbW9kdWxlIGNhY2hlXG5fX3dlYnBhY2tfcmVxdWlyZV9fLmMgPSBpbnN0YWxsZWRNb2R1bGVzO1xuXG4vLyBfX3dlYnBhY2tfcHVibGljX3BhdGhfX1xuX193ZWJwYWNrX3JlcXVpcmVfXy5wID0gXCJwdWJsaWMvXCI7XG5cblxuLy8gTG9hZCBlbnRyeSBtb2R1bGUgYW5kIHJldHVybiBleHBvcnRzXG5yZXR1cm4gX193ZWJwYWNrX3JlcXVpcmVfXygwKTsiLCJ7cmVxdWVzdEludGVydmFsLCBjbGVhclJlcXVlc3RJbnRlcnZhbH0gPSByZXF1aXJlICcuL2FuaW1hdGlvbi1oZWxwZXJzJ1xuXG5OVU1fQ0lSQ0xFUyA9IDI1MDBcbk1BWF9SQURJVVMgPSA4MFxuTUlOX1JBRElVUyA9IDRcblxuYmdDYW52YXMgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCBcImJnXCJcbmZnQ2FudmFzID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQgXCJmZ1wiXG5iZyA9IGJnQ2FudmFzLmdldENvbnRleHQgXCIyZFwiXG5mZyA9IGZnQ2FudmFzLmdldENvbnRleHQgXCIyZFwiXG5cbndpZHRoICA9IGJnQ2FudmFzLndpZHRoICA9IGZnQ2FudmFzLndpZHRoICA9IHdpbmRvdy5pbm5lcldpZHRoXG5oZWlnaHQgPSBiZ0NhbnZhcy5oZWlnaHQgPSBmZ0NhbnZhcy5oZWlnaHQgPSB3aW5kb3cuaW5uZXJIZWlnaHRcblxucmFuZCA9IChsb3dlciwgdXBwZXIpIC0+IGxvd2VyICsgTWF0aC5mbG9vciBNYXRoLnJhbmRvbSgpICogdXBwZXJcbmRyID0gKGkpIC0+IC40ICogTWF0aC5wb3cgMS41LCBpXG5cbmNsYXNzIENpcmNsZVxuICBjb25zdHJ1Y3RvcjogKEByYWRpdXMgPSBNSU5fUkFESVVTKSAtPlxuICAgIEB4ID0gcmFuZCAwLCB3aWR0aFxuICAgIEB5ID0gcmFuZCAwLCBoZWlnaHRcbiAgICBAY29sb3IgPSBpZiByYW5kKDAsIDIpIHRoZW4gJyNmZjAwMDAnIGVsc2UgJyMwMDAwZmYnXG5cbmNpcmNsZXMgPSAobmV3IENpcmNsZSBmb3IgYyBpbiBbMC4uTlVNX0NJUkNMRVNdKVxuYWN0aXZlQ2lyY2xlcyA9IFtdXG5cbmFuaW1hdGUgPSAtPlxuICBmZy5jbGVhclJlY3QgMCwgMCwgd2lkdGgsIGhlaWdodFxuICBkcmF3Q2lyY2xlIGZnLCBjaXJjbGUgZm9yIGNpcmNsZSBpbiBhY3RpdmVDaXJjbGVzXG4gIHJldHVyblxuXG5kcmF3Q2lyY2xlID0gKGN0eCwgY2lyY2xlKSAtPlxuICBjdHguYmVnaW5QYXRoKClcbiAgY3R4LmFyYyBjaXJjbGUueCwgY2lyY2xlLnksIGNpcmNsZS5yYWRpdXMsIDAsIE1hdGguUEkgKiAyLCB0cnVlXG4gIGN0eC5saW5lV2lkdGggPSA1XG5cbiAgIyBsaW5lIGNvbG9yXG4gIGlmIGNpcmNsZS5yYWRpdXMgPT0gTUlOX1JBRElVU1xuICAgIGN0eC5maWxsU3R5bGUgPSBjaXJjbGUuY29sb3JcbiAgICBjdHguZmlsbCgpXG4gIGVsc2VcbiAgICBjdHguc3Ryb2tlU3R5bGUgPSBjaXJjbGUuY29sb3JcbiAgICBjdHguc3Ryb2tlKClcbiAgY3R4LmNsb3NlUGF0aCgpXG5cbmFkZENpcmNsZSA9IC0+XG4gIGNpcmNsZSA9IG5ldyBDaXJjbGUgTUFYX1JBRElVU1xuICBhY3RpdmVDaXJjbGVzLnB1c2ggY2lyY2xlXG5cbiAgaXRlcmF0aW9ucyA9IDBcblxuICBzaHJpbmtSYWRpdXMgPSAtPlxuICAgIGl0ZXJhdGlvbnMrK1xuICAgIGNpcmNsZS5yYWRpdXMgLT0gZHIgaXRlcmF0aW9uc1xuXG4gICAgaWYgY2lyY2xlLnJhZGl1cyA8IDBcbiAgICAgIGNsZWFyUmVxdWVzdEludGVydmFsIG5ld0NpcmNsZUludGVydmFsXG4gICAgICBjaXJjbGUucmFkaXVzID0gTUlOX1JBRElVU1xuICAgICAgIyB3aGVuIGRvbmUgYW5pbWF0aW5nLCBkcmF3IGl0IHRvIHRoZSBiYWNrZ3JvdW5kIGNhbnZhc1xuICAgICAgIyMgYWN0aXZlQ2lyY2xlcy5zcGxpY2UgYWN0aXZlQ2lyY2xlcy5pbmRleE9mKGNpcmNsZSksIDFcbiAgICAgIGRyYXdDaXJjbGUgYmcsIGNpcmNsZVxuICAgICAgY2lyY2xlcy5wdXNoIGNpcmNsZVxuXG4gIG5ld0NpcmNsZUludGVydmFsID0gcmVxdWVzdEludGVydmFsIHNocmlua1JhZGl1cywgMjBcblxuIyBpbml0aWFsaXplIHRoZSBiYWNrZ3JvdW5kIGNhbnZhcyB3aXRoIG9yaWdpbmFsIGNpcmNsZXNcbmRyYXdDaXJjbGUgYmcsIGNpcmNsZSBmb3IgY2lyY2xlIGluIGNpcmNsZXNcblxucmVxdWVzdEludGVydmFsIGFuaW1hdGUsIDIwXG5yZXF1ZXN0SW50ZXJ2YWwgYWRkQ2lyY2xlLCAxNTAwXG4iLCJ2YXIgQ2lyY2xlLCBNQVhfUkFESVVTLCBNSU5fUkFESVVTLCBOVU1fQ0lSQ0xFUywgYWN0aXZlQ2lyY2xlcywgYWRkQ2lyY2xlLCBhbmltYXRlLCBiZywgYmdDYW52YXMsIGMsIGNpcmNsZSwgY2lyY2xlcywgY2xlYXJSZXF1ZXN0SW50ZXJ2YWwsIGRyLCBkcmF3Q2lyY2xlLCBmZywgZmdDYW52YXMsIGhlaWdodCwgcmFuZCwgcmVxdWVzdEludGVydmFsLCB3aWR0aCwgX2ksIF9sZW4sIF9yZWY7XG5cbl9yZWYgPSByZXF1aXJlKCcuL2FuaW1hdGlvbi1oZWxwZXJzJyksIHJlcXVlc3RJbnRlcnZhbCA9IF9yZWYucmVxdWVzdEludGVydmFsLCBjbGVhclJlcXVlc3RJbnRlcnZhbCA9IF9yZWYuY2xlYXJSZXF1ZXN0SW50ZXJ2YWw7XG5cbk5VTV9DSVJDTEVTID0gMjUwMDtcblxuTUFYX1JBRElVUyA9IDgwO1xuXG5NSU5fUkFESVVTID0gNDtcblxuYmdDYW52YXMgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChcImJnXCIpO1xuXG5mZ0NhbnZhcyA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFwiZmdcIik7XG5cbmJnID0gYmdDYW52YXMuZ2V0Q29udGV4dChcIjJkXCIpO1xuXG5mZyA9IGZnQ2FudmFzLmdldENvbnRleHQoXCIyZFwiKTtcblxud2lkdGggPSBiZ0NhbnZhcy53aWR0aCA9IGZnQ2FudmFzLndpZHRoID0gd2luZG93LmlubmVyV2lkdGg7XG5cbmhlaWdodCA9IGJnQ2FudmFzLmhlaWdodCA9IGZnQ2FudmFzLmhlaWdodCA9IHdpbmRvdy5pbm5lckhlaWdodDtcblxucmFuZCA9IGZ1bmN0aW9uKGxvd2VyLCB1cHBlcikge1xuICByZXR1cm4gbG93ZXIgKyBNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiB1cHBlcik7XG59O1xuXG5kciA9IGZ1bmN0aW9uKGkpIHtcbiAgcmV0dXJuIC40ICogTWF0aC5wb3coMS41LCBpKTtcbn07XG5cbkNpcmNsZSA9IChmdW5jdGlvbigpIHtcbiAgZnVuY3Rpb24gQ2lyY2xlKHJhZGl1cykge1xuICAgIHRoaXMucmFkaXVzID0gcmFkaXVzICE9IG51bGwgPyByYWRpdXMgOiBNSU5fUkFESVVTO1xuICAgIHRoaXMueCA9IHJhbmQoMCwgd2lkdGgpO1xuICAgIHRoaXMueSA9IHJhbmQoMCwgaGVpZ2h0KTtcbiAgICB0aGlzLmNvbG9yID0gcmFuZCgwLCAyKSA/ICcjZmYwMDAwJyA6ICcjMDAwMGZmJztcbiAgfVxuXG4gIHJldHVybiBDaXJjbGU7XG5cbn0pKCk7XG5cbmNpcmNsZXMgPSAoZnVuY3Rpb24oKSB7XG4gIHZhciBfaSwgX3Jlc3VsdHM7XG4gIF9yZXN1bHRzID0gW107XG4gIGZvciAoYyA9IF9pID0gMDsgMCA8PSBOVU1fQ0lSQ0xFUyA/IF9pIDw9IE5VTV9DSVJDTEVTIDogX2kgPj0gTlVNX0NJUkNMRVM7IGMgPSAwIDw9IE5VTV9DSVJDTEVTID8gKytfaSA6IC0tX2kpIHtcbiAgICBfcmVzdWx0cy5wdXNoKG5ldyBDaXJjbGUpO1xuICB9XG4gIHJldHVybiBfcmVzdWx0cztcbn0pKCk7XG5cbmFjdGl2ZUNpcmNsZXMgPSBbXTtcblxuYW5pbWF0ZSA9IGZ1bmN0aW9uKCkge1xuICB2YXIgY2lyY2xlLCBfaSwgX2xlbjtcbiAgZmcuY2xlYXJSZWN0KDAsIDAsIHdpZHRoLCBoZWlnaHQpO1xuICBmb3IgKF9pID0gMCwgX2xlbiA9IGFjdGl2ZUNpcmNsZXMubGVuZ3RoOyBfaSA8IF9sZW47IF9pKyspIHtcbiAgICBjaXJjbGUgPSBhY3RpdmVDaXJjbGVzW19pXTtcbiAgICBkcmF3Q2lyY2xlKGZnLCBjaXJjbGUpO1xuICB9XG59O1xuXG5kcmF3Q2lyY2xlID0gZnVuY3Rpb24oY3R4LCBjaXJjbGUpIHtcbiAgY3R4LmJlZ2luUGF0aCgpO1xuICBjdHguYXJjKGNpcmNsZS54LCBjaXJjbGUueSwgY2lyY2xlLnJhZGl1cywgMCwgTWF0aC5QSSAqIDIsIHRydWUpO1xuICBjdHgubGluZVdpZHRoID0gNTtcbiAgaWYgKGNpcmNsZS5yYWRpdXMgPT09IE1JTl9SQURJVVMpIHtcbiAgICBjdHguZmlsbFN0eWxlID0gY2lyY2xlLmNvbG9yO1xuICAgIGN0eC5maWxsKCk7XG4gIH0gZWxzZSB7XG4gICAgY3R4LnN0cm9rZVN0eWxlID0gY2lyY2xlLmNvbG9yO1xuICAgIGN0eC5zdHJva2UoKTtcbiAgfVxuICByZXR1cm4gY3R4LmNsb3NlUGF0aCgpO1xufTtcblxuYWRkQ2lyY2xlID0gZnVuY3Rpb24oKSB7XG4gIHZhciBjaXJjbGUsIGl0ZXJhdGlvbnMsIG5ld0NpcmNsZUludGVydmFsLCBzaHJpbmtSYWRpdXM7XG4gIGNpcmNsZSA9IG5ldyBDaXJjbGUoTUFYX1JBRElVUyk7XG4gIGFjdGl2ZUNpcmNsZXMucHVzaChjaXJjbGUpO1xuICBpdGVyYXRpb25zID0gMDtcbiAgc2hyaW5rUmFkaXVzID0gZnVuY3Rpb24oKSB7XG4gICAgaXRlcmF0aW9ucysrO1xuICAgIGNpcmNsZS5yYWRpdXMgLT0gZHIoaXRlcmF0aW9ucyk7XG4gICAgaWYgKGNpcmNsZS5yYWRpdXMgPCAwKSB7XG4gICAgICBjbGVhclJlcXVlc3RJbnRlcnZhbChuZXdDaXJjbGVJbnRlcnZhbCk7XG4gICAgICBjaXJjbGUucmFkaXVzID0gTUlOX1JBRElVUztcbiAgICAgIGRyYXdDaXJjbGUoYmcsIGNpcmNsZSk7XG4gICAgICByZXR1cm4gY2lyY2xlcy5wdXNoKGNpcmNsZSk7XG4gICAgfVxuICB9O1xuICByZXR1cm4gbmV3Q2lyY2xlSW50ZXJ2YWwgPSByZXF1ZXN0SW50ZXJ2YWwoc2hyaW5rUmFkaXVzLCAyMCk7XG59O1xuXG5mb3IgKF9pID0gMCwgX2xlbiA9IGNpcmNsZXMubGVuZ3RoOyBfaSA8IF9sZW47IF9pKyspIHtcbiAgY2lyY2xlID0gY2lyY2xlc1tfaV07XG4gIGRyYXdDaXJjbGUoYmcsIGNpcmNsZSk7XG59XG5cbnJlcXVlc3RJbnRlcnZhbChhbmltYXRlLCAyMCk7XG5cbnJlcXVlc3RJbnRlcnZhbChhZGRDaXJjbGUsIDE1MDApO1xuIiwiZXhwb3J0cy5yZXF1ZXN0SW50ZXJ2YWwgPSAoZm4sIGRlbGF5KSAtPlxuICBzdGFydCA9IERhdGUubm93KClcbiAgbGF0ZXIgPSAtPlxuICAgIGN1cnJlbnQgPSBEYXRlLm5vdygpXG4gICAgZGVsdGEgPSBjdXJyZW50IC0gc3RhcnRcbiAgICBpZiBkZWx0YSA+PSBkZWxheVxuICAgICAgZm4oKVxuICAgICAgc3RhcnQgPSBEYXRlLm5vdygpXG4gICAgaW50ZXJ2YWwgPSByZXF1ZXN0QW5pbUZyYW1lIGxhdGVyXG4gICAgcmV0dXJuXG4gIHJlcXVlc3RBbmltRnJhbWUgPSBkbyAtPlxuICAgIHdpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUgb3Igd2luZG93LndlYmtpdFJlcXVlc3RBbmltYXRpb25GcmFtZSBvciB3aW5kb3cubW96UmVxdWVzdEFuaW1hdGlvbkZyYW1lXG5cbiAgcmV0dXJuIHNldEludGVydmFsKGZuLCBkZWxheSkgdW5sZXNzIHJlcXVlc3RBbmltRnJhbWVcbiAgaW50ZXJ2YWwgPSByZXF1ZXN0QW5pbUZyYW1lIGxhdGVyXG5cblxuZXhwb3J0cy5jbGVhclJlcXVlc3RJbnRlcnZhbCA9IChoYW5kbGUpIC0+XG4gIHdpbmRvdy5jYW5jZWxBbmltYXRpb25GcmFtZT8oaGFuZGxlKSBvclxuICB3aW5kb3cud2Via2l0Q2FuY2VsQW5pbWF0aW9uRnJhbWU/KGhhbmRsZSkgb3JcbiAgd2luZG93LndlYmtpdENhbmNlbFJlcXVlc3RBbmltYXRpb25GcmFtZT8oaGFuZGxlKSBvclxuICB3aW5kb3cubW96Q2FuY2VsUmVxdWVzdEFuaW1hdGlvbkZyYW1lPyhoYW5kbGUpIG9yXG4gIGNsZWFySW50ZXJ2YWwoaGFuZGxlKVxuICByZXR1cm4iLCJleHBvcnRzLnJlcXVlc3RJbnRlcnZhbCA9IGZ1bmN0aW9uKGZuLCBkZWxheSkge1xuICB2YXIgaW50ZXJ2YWwsIGxhdGVyLCByZXF1ZXN0QW5pbUZyYW1lLCBzdGFydDtcbiAgc3RhcnQgPSBEYXRlLm5vdygpO1xuICBsYXRlciA9IGZ1bmN0aW9uKCkge1xuICAgIHZhciBjdXJyZW50LCBkZWx0YSwgaW50ZXJ2YWw7XG4gICAgY3VycmVudCA9IERhdGUubm93KCk7XG4gICAgZGVsdGEgPSBjdXJyZW50IC0gc3RhcnQ7XG4gICAgaWYgKGRlbHRhID49IGRlbGF5KSB7XG4gICAgICBmbigpO1xuICAgICAgc3RhcnQgPSBEYXRlLm5vdygpO1xuICAgIH1cbiAgICBpbnRlcnZhbCA9IHJlcXVlc3RBbmltRnJhbWUobGF0ZXIpO1xuICB9O1xuICByZXF1ZXN0QW5pbUZyYW1lID0gKGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB3aW5kb3cucmVxdWVzdEFuaW1hdGlvbkZyYW1lIHx8IHdpbmRvdy53ZWJraXRSZXF1ZXN0QW5pbWF0aW9uRnJhbWUgfHwgd2luZG93Lm1velJlcXVlc3RBbmltYXRpb25GcmFtZTtcbiAgfSkoKTtcbiAgaWYgKCFyZXF1ZXN0QW5pbUZyYW1lKSB7XG4gICAgcmV0dXJuIHNldEludGVydmFsKGZuLCBkZWxheSk7XG4gIH1cbiAgcmV0dXJuIGludGVydmFsID0gcmVxdWVzdEFuaW1GcmFtZShsYXRlcik7XG59O1xuXG5leHBvcnRzLmNsZWFyUmVxdWVzdEludGVydmFsID0gZnVuY3Rpb24oaGFuZGxlKSB7XG4gICh0eXBlb2Ygd2luZG93LmNhbmNlbEFuaW1hdGlvbkZyYW1lID09PSBcImZ1bmN0aW9uXCIgPyB3aW5kb3cuY2FuY2VsQW5pbWF0aW9uRnJhbWUoaGFuZGxlKSA6IHZvaWQgMCkgfHwgKHR5cGVvZiB3aW5kb3cud2Via2l0Q2FuY2VsQW5pbWF0aW9uRnJhbWUgPT09IFwiZnVuY3Rpb25cIiA/IHdpbmRvdy53ZWJraXRDYW5jZWxBbmltYXRpb25GcmFtZShoYW5kbGUpIDogdm9pZCAwKSB8fCAodHlwZW9mIHdpbmRvdy53ZWJraXRDYW5jZWxSZXF1ZXN0QW5pbWF0aW9uRnJhbWUgPT09IFwiZnVuY3Rpb25cIiA/IHdpbmRvdy53ZWJraXRDYW5jZWxSZXF1ZXN0QW5pbWF0aW9uRnJhbWUoaGFuZGxlKSA6IHZvaWQgMCkgfHwgKHR5cGVvZiB3aW5kb3cubW96Q2FuY2VsUmVxdWVzdEFuaW1hdGlvbkZyYW1lID09PSBcImZ1bmN0aW9uXCIgPyB3aW5kb3cubW96Q2FuY2VsUmVxdWVzdEFuaW1hdGlvbkZyYW1lKGhhbmRsZSkgOiB2b2lkIDApIHx8IGNsZWFySW50ZXJ2YWwoaGFuZGxlKTtcbn07XG4iXSwic291cmNlUm9vdCI6IndlYnBhY2stbW9kdWxlOi8vIn0=
*/
<html>
<head>
</head>
<body>
<canvas id="bg" style="position: absolute; z-index: 0"></canvas>
<canvas id="fg" style="position: absolute; z-index: 1"></canvas>
<script src="draw-circles.js"></script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment