function main(t,n){function o(t){var n=d3.scaleLinear().domain([0,1]).range([.4,1]);return function(o){var i=d3.rgb(t(n(o)));return[i.r/255,i.g/255,i.b/255]}}function i(t){var o=n({frag:"\n\t\t precision highp float;\n\t\t\tvarying vec3 fragColor;\n\n\t\t\tvoid main() {\n\t\t\t\tfloat x = gl_PointCoord.x;\n\t\t\t\tfloat y = gl_PointCoord.y;\n\n\t\t\t\t// Measure distance from center\n\t\t\t\tvec2 uv = vec2(x, y) * 2. - 1.;\n\t\t\t\tfloat point_dist = length(uv);\n\n\t\t\t\tif (point_dist > 1.000) {\n\t\t\t\t\tdiscard;\n\t\t\t\t}\n\t\t\t\tgl_FragColor = vec4(fragColor, 1.0);\n\t\t\t}\n\t\t\t",vert:"\n\t\t\tattribute vec2 positionStart;\n\t\t\tattribute vec2 positionEnd;\n\t\t\tattribute float index;\n\t\t\tattribute vec3 colorStart;\n\t\t\tattribute vec3 colorEnd;\n\n\t\t\tvarying vec3 fragColor;\n\n\t\t\tuniform float pointWidth;\n\t\t\tuniform float stageWidth;\n\t\t\tuniform float stageHeight;\n\t\t\tuniform float elapsed;\n\t\t\tuniform float duration;\n\t\t\tuniform float delayByIndex;\n\t\t\tvoid main() {\n\t\t\t\tgl_PointSize = pointWidth;\n\n\t\t\t\tfloat delay = delayByIndex * index;\n\t float t;\n\n\t // drawing without animation, so show end state immediately\n\t if (duration == 0.0) {\n\t t = 1.0;\n\n\t // still delaying before animating\n\t } else if (elapsed < delay) {\n\t t = 0.0;\n\t } else {\n\t t = 2.0 * ((elapsed - delay) / duration);\n\n\t // cubic easing (cubicInOut) -- note there are glslify things for this toPhyllotaxis\n\t // this is copied from d3.\n\t t = (t <= 1.0 ? t * t * t : (t -= 2.0) * t * t + 2.0) / 2.0;\n\n\t if (t > 1.0) {\n\t t = 1.0;\n\t }\n\t }\n\n\t\t\t\t// interpolate position\n\t float x = mix(positionStart[0], positionEnd[0], t);\n\t float y = mix(positionStart[1], positionEnd[1], t);\n\n\t // interpolate color\n\t fragColor = mix(colorStart, colorEnd, t);\n\n\t\t\t\t// scale to normalized device coordinates (-1, -1) to (1, 1)\n\t gl_Position = vec4(\n\t\t 2.0 * ((x / stageWidth) - 0.5),\n\t\t // invert y since we think [0,0] is bottom left in pixel space (needed for d3.zoom)\n\t\t -(2.0 * ((y / stageHeight) - 0.5)),\n\t\t 0.0,\n\t\t 1.0);\n\t\t\t}\n\t\t\t",attributes:{positionStart:t.map(function(t){return[t.sx,t.sy]}),positionEnd:t.map(function(t){return[t.tx,t.ty]}),colorStart:t.map(function(t){return t.colorStart}),colorEnd:t.map(function(t){return t.colorEnd}),index:d3.range(t.length)},uniforms:{pointWidth:n.prop("pointWidth"),stageWidth:n.prop("stageWidth"),stageHeight:n.prop("stageHeight"),delayByIndex:n.prop("delayByIndex"),duration:n.prop("duration"),elapsed:function(t,n){var o=t.time,i=n.startTime;return void 0===i&&(i=0),1e3*(o-i)}},count:t.length,primitive:"points"});return o}function e(t,o){console.log("animating with new layout"),o.forEach(function(t){t.sx=t.tx,t.sy=t.ty,t.colorStart=t.colorEnd}),t(o);var r=S[b];o.forEach(function(t,n){t.tx=t.x,t.ty=t.y,t.colorEnd=r(n/o.length)});var d=i(o);a=n.frame(function(t){var i=t.time;null===E&&(E=i),n.clear({color:[0,0,0,1],depth:1}),d({pointWidth:l,stageWidth:s,stageHeight:c,duration:u,delayByIndex:f,startTime:E}),i-E>g/1e3&&(console.log("done animating, moving to next layout"),a.cancel(),x=(x+1)%v.length,E=null,b=(b+1)%S.length,e(v[x],o))})}var a,r=1e4,l=20,d=1,s=window.innerWidth,c=window.innerHeight,u=1500,f=500/r,g=u+f*r,p=function(t){return phyllotaxisLayout(t,l+d,s/2,c/2)},h=function(t){return gridLayout(t,l+d,s)},m=function(t){return sineLayout(t,l+d,s,c)},y=function(t){return spiralLayout(t,l+d,s,c)},v=[p,h,m,y],x=0,E=null,S=[d3.scaleSequential(d3.interpolateViridis),d3.scaleSequential(d3.interpolateMagma),d3.scaleSequential(d3.interpolateInferno),d3.scaleSequential(d3.interpolateCool)].map(o),b=0,w=createPoints(r,l,s,c);window.points=w,w.forEach(function(t,n){t.tx=s/2,t.ty=c/2,t.colorEnd=S[b](n/w.length)}),e(v[x],w)}regl({extensions:["OES_texture_float"],onDone:main}); //# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInNjcmlwdC5qcyJdLCJuYW1lcyI6WyJtYWluIiwiZXJyIiwicmVnbCIsIndyYXBDb2xvclNjYWxlIiwic2NhbGUiLCJjb25zdCIsInRTY2FsZSIsImQzIiwic2NhbGVMaW5lYXIiLCJkb21haW4iLCJyYW5nZSIsInQiLCJyZ2IiLCJyIiwiZyIsImIiLCJjcmVhdGVEcmF3UG9pbnRzIiwicG9pbnRzIiwiZHJhd1BvaW50cyIsImZyYWciLCJ2ZXJ0IiwiYXR0cmlidXRlcyIsInBvc2l0aW9uU3RhcnQiLCJtYXAiLCJkIiwic3giLCJzeSIsInBvc2l0aW9uRW5kIiwidHgiLCJ0eSIsImNvbG9yU3RhcnQiLCJjb2xvckVuZCIsImluZGV4IiwibGVuZ3RoIiwidW5pZm9ybXMiLCJwb2ludFdpZHRoIiwicHJvcCIsInN0YWdlV2lkdGgiLCJzdGFnZUhlaWdodCIsImRlbGF5QnlJbmRleCIsImR1cmF0aW9uIiwiZWxhcHNlZCIsInJlZiIsInJlZiQxIiwidGltZSIsInN0YXJ0VGltZSIsInByaW1pdGl2ZSIsImFuaW1hdGUiLCJsYXlvdXQiLCJjb25zb2xlIiwibG9nIiwiZm9yRWFjaCIsImNvbG9yU2NhbGUiLCJjb2xvclNjYWxlcyIsImN1cnJlbnRDb2xvclNjYWxlIiwiaSIsIngiLCJ5IiwiZnJhbWVMb29wIiwiZnJhbWUiLCJjbGVhciIsImNvbG9yIiwiZGVwdGgiLCJ3aWR0aCIsImhlaWdodCIsIm1heER1cmF0aW9uIiwiY2FuY2VsIiwiY3VycmVudExheW91dCIsImxheW91dHMiLCJudW1Qb2ludHMiLCJwb2ludE1hcmdpbiIsIndpbmRvdyIsImlubmVyV2lkdGgiLCJpbm5lckhlaWdodCIsInRvUGh5bGxvdGF4aXMiLCJwaHlsbG90YXhpc0xheW91dCIsInRvR3JpZCIsImdyaWRMYXlvdXQiLCJ0b1NpbmUiLCJzaW5lTGF5b3V0IiwidG9TcGlyYWwiLCJzcGlyYWxMYXlvdXQiLCJzY2FsZVNlcXVlbnRpYWwiLCJpbnRlcnBvbGF0ZVZpcmlkaXMiLCJpbnRlcnBvbGF0ZU1hZ21hIiwiaW50ZXJwb2xhdGVJbmZlcm5vIiwiaW50ZXJwb2xhdGVDb29sIiwiY3JlYXRlUG9pbnRzIiwiZXh0ZW5zaW9ucyIsIm9uRG9uZSJdLCJtYXBwaW5ncyI6IkFBQUEsUUFBU0EsTUFBS0MsRUFBS0MsR0F1QmxCLFFBQVNDLEdBQWVDLEdBQ3ZCQyxHQUFNQyxHQUFXQyxHQUFDQyxjQUFjQyxRQUFTLEVBQUksSUFBRUMsT0FBTyxHQUFPLEdBQzdELE9BQU8sVUFBQUMsR0FDTk4sR0FBTU8sR0FBUUwsR0FBQ0ssSUFBSVIsRUFBTUUsRUFBU0ssSUFDbEMsUUFBUUMsRUFBSUMsRUFBSSxJQUFLRCxFQUFJRSxFQUFJLElBQUtGLEVBQUlHLEVBQUksTUFhNUMsUUFBU0MsR0FBaUJDLEdBQ3pCWixHQUFNYSxHQUFhaEIsR0FDbEJpQixLQUFNLDhaQW1CTkMsS0FBTSxpcERBeUROQyxZQWtFQ0MsY0FBQUwsRUFBQU0sSUFBWSxTQUFBQyxHQUFBLE9BQUFBLEVBQUFDLEdBQUFELEVBQUFFLE1BQ1pDLFlBQUFWLEVBQVNNLElBQUEsU0FBQUMsR0FBQSxPQUFBQSxFQUFBSSxHQUFBSixFQUFBSyxNQUNUQyxXQUFFYixFQUFBTSxJQUFBLFNBQUFDLEdBQUEsTUFBQUEsR0FBQU0sYUFoRUZDLFNBQVVkLEVBQU9NLElBQUksU0FBQUMsR0FBRSxNQUFHQSxHQUFFTyxXQWtFN0JDLE1BQVF6QixHQUFHRyxNQUFBTyxFQUFhZ0IsU0E5RHhCQyxVQWtFQ0MsV0FBQWpDLEVBQWlCa0MsS0FBQSxjQUNqQkMsV0FBWW5DLEVBQUtrQyxLQUFBLGNBQ2pCRSxZQUFBcEMsRUFBaUJrQyxLQUFJLGVBQ3JCRyxhQUFRckMsRUFBUWtDLEtBQUEsZ0JBQ2hCSSxTQUFBdEMsRUFBQWtDLEtBQUEsWUE5REdLLFFBQVMsU0FBQ0MsRUFBVUMsTUFBUkMsR0FBSUYsRUFBQUUseUNBQWtCLEdBQTZCLEtBQXBCQSxFQUFPQyxLQW9FeER4QyxNQUFNWSxFQUFTZ0IsT0FDZmEsVUFBYSxVQUdaLE9BQU81QixHQUlSLFFBQVE2QixHQUFRQyxFQUFBL0IsR0FDaEJnQyxRQUFBQyxJQUFBLDZCQS9EQ2pDLEVBQU9rQyxRQUFRLFNBQUEzQixHQUNkQSxFQUFFQyxHQUFLRCxFQUFFSSxHQWtFWkosRUFBS0UsR0FBQUYsRUFBQUssR0FoRUZMLEVBQUVNLFdBQWFOLEVBQUVPLFdBSWxCaUIsRUFBTy9CLEVBb0VQWixJQUFDK0MsR0FBQUMsRUFBQUMsRUFoRURyQyxHQUFPa0MsUUFBUSxTQUFDM0IsRUFBRytCLEdBQ2xCL0IsRUFBRUksR0FBS0osRUFBRWdDLEVBQ1RoQyxFQUFFSyxHQUFLTCxFQUFFaUMsRUFDVGpDLEVBQUVPLFNBQVdxQixFQUFXRyxFQUFJdEMsRUFBT2dCLFNBSXBDNUIsSUFBTWEsR0FBYUYsRUFBaUJDLEVBRXBDeUMsR0FBWXhELEVBQUt5RCxNQUFNLFNBQUNqQixNQUFFRSxHQUFJRixFQUFBRSxJQUNYLFFBQWRDLElBQ0hBLEVBQVlELEdBR2IxQyxFQUFLMEQsT0FFSkMsT0FBUSxFQUFHLEVBQUcsRUFBRyxHQUNqQkMsTUFBTyxJQUdSNUMsR0FDQ2lCLFdBQUFBLEVBQ0FFLFdBQVkwQixFQUNaekIsWUFBYTBCLEVBQ2J4QixTQUFBQSxFQUNBRCxhQUFBQSxFQUNBTSxVQUFBQSxJQUdHRCxFQUFPQyxFQUFhb0IsRUFBYyxNQUNyQ2hCLFFBQVFDLElBQUkseUNBQ1pRLEVBQVVRLFNBRVZDLEdBQWlCQSxFQUFnQixHQUFLQyxFQUFRbkMsT0FDOUNZLEVBQVksS0FDWlMsR0FBcUJBLEVBQW9CLEdBQUtELEVBQVlwQixPQUMxRGMsRUFBUXFCLEVBQVFELEdBQWdCbEQsTUFsTW5DWixHQWtCSXFELEdBbEJFVyxFQUFZLElBQ1psQyxFQUFlLEdBQ2ZtQyxFQUFnQixFQUNoQlAsRUFBUVEsT0FBT0MsV0FDZlIsRUFBU08sT0FBT0UsWUFDaEJqQyxFQUFXLEtBQ1hELEVBQWUsSUFBTThCLEVBQ3JCSixFQUFjekIsRUFBV0QsRUFBZThCLEVBRXhDSyxFQUFnQixTQUFBekQsR0FBQyxNQUFBMEQsbUJBQVcxRCxFQUFBa0IsRUFBMEJtQyxFQUFhUCxFQUFBLEVBQVdDLEVBQU8sSUFDckZZLEVBQVMsU0FBQTNELEdBQUMsTUFBQTRELFlBQVE1RCxFQUFHa0IsRUFBbUJtQyxFQUFhUCxJQUNyRGUsRUFBUyxTQUFBN0QsR0FBQyxNQUFBOEQsWUFBUTlELEVBQUdrQixFQUFtQm1DLEVBQWFQLEVBQUFDLElBQ3JEZ0IsRUFBVyxTQUFBL0QsR0FBQyxNQUFBZ0UsY0FBV2hFLEVBQUFrQixFQUFxQm1DLEVBQWFQLEVBQUFDLElBRXpESSxHQUFXTSxFQUFlRSxFQUFRRSxFQUFRRSxHQUM1Q2IsRUFBZ0IsRUFDaEJ0QixFQUFZLEtBY1ZRLEdBQ0w5QyxHQUFHMkUsZ0JBQWdCM0UsR0FBRzRFLG9CQUN0QjVFLEdBQUcyRSxnQkFBZ0IzRSxHQUFHNkUsa0JBQ3RCN0UsR0FBRzJFLGdCQUFnQjNFLEdBQUc4RSxvQkFDdEI5RSxHQUFHMkUsZ0JBQWdCM0UsR0FBRytFLGtCQUNyQi9ELElBQUlwQixHQUNGbUQsRUFBb0IsRUFxS2xCckMsRUFBU3NFLGFBQWFsQixFQUFXbEMsRUFBWTRCLEVBQU9DLEVBQzFETyxRQUFPdEQsT0FBU0EsRUFDaEJBLEVBQU9rQyxRQUFRLFNBQUMzQixFQUFHK0IsR0FDbEIvQixFQUFFSSxHQUFLbUMsRUFBUSxFQUNmdkMsRUFBRUssR0FBS21DLEVBQVMsRUFDaEJ4QyxFQUFFTyxTQUFXc0IsRUFBWUMsR0FBbUJDLEVBQUl0QyxFQUFPZ0IsVUFHeERjLEVBQVFxQixFQUFRRCxHQUFnQmxELEdBS2pDZixNQUVFc0YsWUFDRSxxQkFJRkMsT0FBUXpGIiwiZmlsZSI6InNjcmlwdC5qcyIsInNvdXJjZXNDb250ZW50IjpbImZ1bmN0aW9uIG1haW4oZXJyLCByZWdsKSB7XG5cdGNvbnN0IG51bVBvaW50cyA9IDEwMDAwO1xuXHRjb25zdCBwb2ludFdpZHRoID0gMjA7XG5cdGNvbnN0IHBvaW50TWFyZ2luID0gMTtcblx0Y29uc3Qgd2lkdGggPSB3aW5kb3cuaW5uZXJXaWR0aDtcblx0Y29uc3QgaGVpZ2h0ID0gd2luZG93LmlubmVySGVpZ2h0O1xuXHRjb25zdCBkdXJhdGlvbiA9IDE1MDA7XG5cdGNvbnN0IGRlbGF5QnlJbmRleCA9IDUwMCAvIG51bVBvaW50cztcblx0Y29uc3QgbWF4RHVyYXRpb24gPSBkdXJhdGlvbiArIGRlbGF5QnlJbmRleCAqIG51bVBvaW50czsgLy8gaW5jbHVkZSBtYXggZGVsYXkgaW4gaGVyZVxuXG5cdGNvbnN0IHRvUGh5bGxvdGF4aXMgPSAocG9pbnRzKSA9PiBwaHlsbG90YXhpc0xheW91dChwb2ludHMsIHBvaW50V2lkdGggKyBwb2ludE1hcmdpbiwgd2lkdGggLyAyLCBoZWlnaHQgLyAyKTtcblx0Y29uc3QgdG9HcmlkID0gKHBvaW50cykgPT4gZ3JpZExheW91dChwb2ludHMsIHBvaW50V2lkdGggKyBwb2ludE1hcmdpbiwgd2lkdGgpO1xuXHRjb25zdCB0b1NpbmUgPSAocG9pbnRzKSA9PiBzaW5lTGF5b3V0KHBvaW50cywgcG9pbnRXaWR0aCArIHBvaW50TWFyZ2luLCB3aWR0aCwgaGVpZ2h0KTtcblx0Y29uc3QgdG9TcGlyYWwgPSAocG9pbnRzKSA9PiBzcGlyYWxMYXlvdXQocG9pbnRzLCBwb2ludFdpZHRoICsgcG9pbnRNYXJnaW4sIHdpZHRoLCBoZWlnaHQpO1xuXG5cdGNvbnN0IGxheW91dHMgPSBbdG9QaHlsbG90YXhpcywgdG9HcmlkLCB0b1NpbmUsIHRvU3BpcmFsXTtcblx0bGV0IGN1cnJlbnRMYXlvdXQgPSAwO1xuXHRsZXQgc3RhcnRUaW1lID0gbnVsbDsgLy8gaW4gc2Vjb25kc1xuXHQvLyBzdGFydCBhbmltYXRpb24gbG9vcCAobm90ZTogdGltZSBpcyBpbiBzZWNvbmRzKVxuXHRsZXQgZnJhbWVMb29wO1xuXG5cdC8vIHdyYXAgZDMgY29sb3Igc2NhbGVzIHNvIHRoZXkgcHJvZHVjZSB2ZWMzcyB3aXRoIHZhbHVlcyAwLTFcblx0Ly8gYWxzbyBsaW1pdCB0aGUgdCB2YWx1ZSB0byByZW1vdmUgZGFya2VzdCBjb2xvclxuXHRmdW5jdGlvbiB3cmFwQ29sb3JTY2FsZShzY2FsZSkge1xuXHRcdGNvbnN0IHRTY2FsZSA9IGQzLnNjYWxlTGluZWFyKCkuZG9tYWluKFswLCAxXSkucmFuZ2UoWzAuNCwgMV0pO1xuXHRcdHJldHVybiB0ID0+IHtcblx0XHRcdGNvbnN0IHJnYiA9IGQzLnJnYihzY2FsZSh0U2NhbGUodCkpKTtcblx0XHRcdHJldHVybiBbcmdiLnIgLyAyNTUsIHJnYi5nIC8gMjU1LCByZ2IuYiAvIDI1NV07XG5cdFx0fTtcblx0fVxuXG5cdGNvbnN0IGNvbG9yU2NhbGVzID0gW1xuXHRcdGQzLnNjYWxlU2VxdWVudGlhbChkMy5pbnRlcnBvbGF0ZVZpcmlkaXMpLFxuXHRcdGQzLnNjYWxlU2VxdWVudGlhbChkMy5pbnRlcnBvbGF0ZU1hZ21hKSxcblx0XHRkMy5zY2FsZVNlcXVlbnRpYWwoZDMuaW50ZXJwb2xhdGVJbmZlcm5vKSxcblx0XHRkMy5zY2FsZVNlcXVlbnRpYWwoZDMuaW50ZXJwb2xhdGVDb29sKSxcblx0XS5tYXAod3JhcENvbG9yU2NhbGUpO1xuXHRsZXQgY3VycmVudENvbG9yU2NhbGUgPSAwO1xuXG5cdC8vIGZ1bmN0aW9uIHRvIGNvbXBpbGUgYSBkcmF3IHBvaW50cyByZWdsIGZ1bmNcblx0ZnVuY3Rpb24gY3JlYXRlRHJhd1BvaW50cyhwb2ludHMpIHtcblx0XHRjb25zdCBkcmF3UG9pbnRzID0gcmVnbCh7XG5cdFx0XHRmcmFnOiBgXG5cdFx0ICBwcmVjaXNpb24gaGlnaHAgZmxvYXQ7XG5cdFx0XHR2YXJ5aW5nIHZlYzMgZnJhZ0NvbG9yO1xuXG5cdFx0XHR2b2lkIG1haW4oKSB7XG5cdFx0XHRcdGZsb2F0IHggPSBnbF9Qb2ludENvb3JkLng7XG5cdFx0XHRcdGZsb2F0IHkgPSBnbF9Qb2ludENvb3JkLnk7XG5cblx0XHRcdFx0Ly8gTWVhc3VyZSBkaXN0YW5jZSBmcm9tIGNlbnRlclxuXHRcdFx0XHR2ZWMyIHV2ID0gdmVjMih4LCB5KSAqIDIuIC0gMS47XG5cdFx0XHRcdGZsb2F0IHBvaW50X2Rpc3QgPSBsZW5ndGgodXYpO1xuXG5cdFx0XHRcdGlmIChwb2ludF9kaXN0ID4gMS4wMDApIHtcblx0XHRcdFx0XHRkaXNjYXJkO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGdsX0ZyYWdDb2xvciA9IHZlYzQoZnJhZ0NvbG9yLCAxLjApO1xuXHRcdFx0fVxuXHRcdFx0YCxcblxuXHRcdFx0dmVydDogYFxuXHRcdFx0YXR0cmlidXRlIHZlYzIgcG9zaXRpb25TdGFydDtcblx0XHRcdGF0dHJpYnV0ZSB2ZWMyIHBvc2l0aW9uRW5kO1xuXHRcdFx0YXR0cmlidXRlIGZsb2F0IGluZGV4O1xuXHRcdFx0YXR0cmlidXRlIHZlYzMgY29sb3JTdGFydDtcblx0XHRcdGF0dHJpYnV0ZSB2ZWMzIGNvbG9yRW5kO1xuXG5cdFx0XHR2YXJ5aW5nIHZlYzMgZnJhZ0NvbG9yO1xuXG5cdFx0XHR1bmlmb3JtIGZsb2F0IHBvaW50V2lkdGg7XG5cdFx0XHR1bmlmb3JtIGZsb2F0IHN0YWdlV2lkdGg7XG5cdFx0XHR1bmlmb3JtIGZsb2F0IHN0YWdlSGVpZ2h0O1xuXHRcdFx0dW5pZm9ybSBmbG9hdCBlbGFwc2VkO1xuXHRcdFx0dW5pZm9ybSBmbG9hdCBkdXJhdGlvbjtcblx0XHRcdHVuaWZvcm0gZmxvYXQgZGVsYXlCeUluZGV4O1xuXHRcdFx0dm9pZCBtYWluKCkge1xuXHRcdFx0XHRnbF9Qb2ludFNpemUgPSBwb2ludFdpZHRoO1xuXG5cdFx0XHRcdGZsb2F0IGRlbGF5ID0gZGVsYXlCeUluZGV4ICogaW5kZXg7XG5cdCAgICAgIGZsb2F0IHQ7XG5cblx0ICAgICAgLy8gZHJhd2luZyB3aXRob3V0IGFuaW1hdGlvbiwgc28gc2hvdyBlbmQgc3RhdGUgaW1tZWRpYXRlbHlcblx0ICAgICAgaWYgKGR1cmF0aW9uID09IDAuMCkge1xuXHQgICAgICAgIHQgPSAxLjA7XG5cblx0ICAgICAgLy8gc3RpbGwgZGVsYXlpbmcgYmVmb3JlIGFuaW1hdGluZ1xuXHQgICAgICB9IGVsc2UgaWYgKGVsYXBzZWQgPCBkZWxheSkge1xuXHQgICAgICAgIHQgPSAwLjA7XG5cdCAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgdCA9IDIuMCAqICgoZWxhcHNlZCAtIGRlbGF5KSAvIGR1cmF0aW9uKTtcblxuXHQgICAgICAgIC8vIGN1YmljIGVhc2luZyAoY3ViaWNJbk91dCkgLS0gbm90ZSB0aGVyZSBhcmUgZ2xzbGlmeSB0aGluZ3MgZm9yIHRoaXMgdG9QaHlsbG90YXhpc1xuXHQgICAgICAgIC8vIHRoaXMgaXMgY29waWVkIGZyb20gZDMuXG5cdCAgICAgICAgdCA9ICh0IDw9IDEuMCA/IHQgKiB0ICogdCA6ICh0IC09IDIuMCkgKiB0ICogdCArIDIuMCkgLyAyLjA7XG5cblx0ICAgICAgICBpZiAodCA+IDEuMCkge1xuXHQgICAgICAgICAgdCA9IDEuMDtcblx0ICAgICAgICB9XG5cdCAgICAgIH1cblxuXHRcdFx0XHQvLyBpbnRlcnBvbGF0ZSBwb3NpdGlvblxuXHQgICAgICBmbG9hdCB4ID0gbWl4KHBvc2l0aW9uU3RhcnRbMF0sIHBvc2l0aW9uRW5kWzBdLCB0KTtcblx0ICAgICAgZmxvYXQgeSA9IG1peChwb3NpdGlvblN0YXJ0WzFdLCBwb3NpdGlvbkVuZFsxXSwgdCk7XG5cblx0ICAgICAgLy8gaW50ZXJwb2xhdGUgY29sb3Jcblx0ICAgICAgZnJhZ0NvbG9yID0gbWl4KGNvbG9yU3RhcnQsIGNvbG9yRW5kLCB0KTtcblxuXHRcdFx0XHQvLyBzY2FsZSB0byBub3JtYWxpemVkIGRldmljZSBjb29yZGluYXRlcyAoLTEsIC0xKSB0byAoMSwgMSlcblx0ICAgICAgZ2xfUG9zaXRpb24gPSB2ZWM0KFxuXHRcdCAgICAgIDIuMCAqICgoeCAvIHN0YWdlV2lkdGgpIC0gMC41KSxcblx0XHQgICAgICAvLyBpbnZlcnQgeSBzaW5jZSB3ZSB0aGluayBbMCwwXSBpcyBib3R0b20gbGVmdCBpbiBwaXhlbCBzcGFjZSAobmVlZGVkIGZvciBkMy56b29tKVxuXHRcdCAgICAgIC0oMi4wICogKCh5IC8gc3RhZ2VIZWlnaHQpIC0gMC41KSksXG5cdFx0ICAgICAgMC4wLFxuXHRcdCAgICAgIDEuMCk7XG5cdFx0XHR9XG5cdFx0XHRgLFxuXG5cdFx0XHRhdHRyaWJ1dGVzOiB7XG5cdFx0XHRcdHBvc2l0aW9uU3RhcnQ6IHBvaW50cy5tYXAoZCA9PiBbZC5zeCwgZC5zeV0pLFxuXHRcdFx0XHRwb3NpdGlvbkVuZDogcG9pbnRzLm1hcChkID0+IFtkLnR4LCBkLnR5XSksXG5cdFx0XHRcdGNvbG9yU3RhcnQ6IHBvaW50cy5tYXAoZCA9PiBkLmNvbG9yU3RhcnQpLFxuXHRcdFx0XHRjb2xvckVuZDogcG9pbnRzLm1hcChkID0+IGQuY29sb3JFbmQpLFxuXHRcdFx0XHRpbmRleDogZDMucmFuZ2UocG9pbnRzLmxlbmd0aCksXG5cdFx0XHR9LFxuXG5cdFx0XHR1bmlmb3Jtczoge1xuXHRcdFx0XHRwb2ludFdpZHRoOiByZWdsLnByb3AoJ3BvaW50V2lkdGgnKSxcblx0XHRcdFx0c3RhZ2VXaWR0aDogcmVnbC5wcm9wKCdzdGFnZVdpZHRoJyksXG5cdFx0XHRcdHN0YWdlSGVpZ2h0OiByZWdsLnByb3AoJ3N0YWdlSGVpZ2h0JyksXG5cdFx0XHRcdGRlbGF5QnlJbmRleDogcmVnbC5wcm9wKCdkZWxheUJ5SW5kZXgnKSxcblx0ICAgICAgZHVyYXRpb246IHJlZ2wucHJvcCgnZHVyYXRpb24nKSxcblxuXHQgICAgICAvLyB0aW1lIGluIG1pbGxpc2Vjb25kcyBzaW5jZSB0aGUgcHJvcCBzdGFydFRpbWUgKGkuZS4gdGltZSBlbGFwc2VkKVxuXHQgICAgICBlbGFwc2VkOiAoeyB0aW1lIH0sIHsgc3RhcnRUaW1lID0gMCB9KSA9PiAodGltZSAtIHN0YXJ0VGltZSkgKiAxMDAwLFxuXHRcdFx0fSxcblxuXHRcdFx0Y291bnQ6IHBvaW50cy5sZW5ndGgsXG5cdFx0XHRwcmltaXRpdmU6ICdwb2ludHMnLFxuXHRcdH0pO1xuXG5cdFx0cmV0dXJuIGRyYXdQb2ludHM7XG5cdH1cblxuXG5cdGZ1bmN0aW9uIGFuaW1hdGUobGF5b3V0LCBwb2ludHMpIHtcblx0XHRjb25zb2xlLmxvZygnYW5pbWF0aW5nIHdpdGggbmV3IGxheW91dCcpO1xuXHRcdC8vIG1ha2UgcHJldmlvdXMgZW5kIHRoZSBuZXcgYmVnaW5uaW5nXG5cdFx0cG9pbnRzLmZvckVhY2goZCA9PiB7XG5cdFx0XHRkLnN4ID0gZC50eDtcblx0XHRcdGQuc3kgPSBkLnR5O1xuXHRcdFx0ZC5jb2xvclN0YXJ0ID0gZC5jb2xvckVuZDtcblx0XHR9KTtcblxuXHRcdC8vIGxheW91dCBwb2ludHNcblx0XHRsYXlvdXQocG9pbnRzKTtcblxuXHRcdC8vIGNvcHkgbGF5b3V0IHggeSB0byBlbmQgcG9zaXRpb25zXG5cdFx0Y29uc3QgY29sb3JTY2FsZSA9IGNvbG9yU2NhbGVzW2N1cnJlbnRDb2xvclNjYWxlXTtcblx0XHRwb2ludHMuZm9yRWFjaCgoZCwgaSkgPT4ge1xuXHRcdFx0ZC50eCA9IGQueDtcblx0XHRcdGQudHkgPSBkLnk7XG5cdFx0XHRkLmNvbG9yRW5kID0gY29sb3JTY2FsZShpIC8gcG9pbnRzLmxlbmd0aClcblx0XHR9KTtcblxuXHRcdC8vIGNyZWF0ZSB0aGUgcmVnbCBmdW5jdGlvbiB3aXRoIHRoZSBuZXcgc3RhcnQgYW5kIGVuZCBwb2ludHNcblx0XHRjb25zdCBkcmF3UG9pbnRzID0gY3JlYXRlRHJhd1BvaW50cyhwb2ludHMpO1xuXG5cdFx0ZnJhbWVMb29wID0gcmVnbC5mcmFtZSgoeyB0aW1lIH0pID0+IHtcblx0XHRcdGlmIChzdGFydFRpbWUgPT09IG51bGwpIHtcblx0XHRcdFx0c3RhcnRUaW1lID0gdGltZTtcblx0XHRcdH1cblxuXHRcdFx0cmVnbC5jbGVhcih7XG5cdFx0XHRcdC8vIGJhY2tncm91bmQgY29sb3IgKGJsYWNrKVxuXHRcdFx0XHRjb2xvcjogWzAsIDAsIDAsIDFdLFxuXHRcdFx0XHRkZXB0aDogMSxcblx0XHRcdH0pO1xuXG5cdFx0XHRkcmF3UG9pbnRzKHtcblx0XHRcdFx0cG9pbnRXaWR0aCxcblx0XHRcdFx0c3RhZ2VXaWR0aDogd2lkdGgsXG5cdFx0XHRcdHN0YWdlSGVpZ2h0OiBoZWlnaHQsXG5cdFx0XHRcdGR1cmF0aW9uLFxuXHRcdFx0XHRkZWxheUJ5SW5kZXgsXG5cdFx0XHRcdHN0YXJ0VGltZSxcblx0XHRcdH0pO1xuXG5cdFx0XHRpZiAodGltZSAtIHN0YXJ0VGltZSA+IChtYXhEdXJhdGlvbiAvIDEwMDApKSB7XG5cdFx0XHRcdGNvbnNvbGUubG9nKCdkb25lIGFuaW1hdGluZywgbW92aW5nIHRvIG5leHQgbGF5b3V0Jyk7XG5cdFx0XHRcdGZyYW1lTG9vcC5jYW5jZWwoKTtcblxuXHRcdFx0XHRjdXJyZW50TGF5b3V0ID0gKGN1cnJlbnRMYXlvdXQgKyAxKSAlIGxheW91dHMubGVuZ3RoO1xuXHRcdFx0XHRzdGFydFRpbWUgPSBudWxsO1xuXHRcdFx0XHRjdXJyZW50Q29sb3JTY2FsZSA9IChjdXJyZW50Q29sb3JTY2FsZSArIDEpICUgY29sb3JTY2FsZXMubGVuZ3RoO1xuXHRcdFx0XHRhbmltYXRlKGxheW91dHNbY3VycmVudExheW91dF0sIHBvaW50cyk7XG5cdFx0XHR9XG5cdFx0fSk7XG5cdH1cblxuXG5cdC8vIGNyZWF0ZSBpbml0aWFsIHNldCBvZiBwb2ludHNcblx0Y29uc3QgcG9pbnRzID0gY3JlYXRlUG9pbnRzKG51bVBvaW50cywgcG9pbnRXaWR0aCwgd2lkdGgsIGhlaWdodCk7XG5cdHdpbmRvdy5wb2ludHMgPSBwb2ludHM7XG5cdHBvaW50cy5mb3JFYWNoKChkLCBpKSA9PiB7XG5cdFx0ZC50eCA9IHdpZHRoIC8gMjtcblx0XHRkLnR5ID0gaGVpZ2h0IC8gMjtcblx0XHRkLmNvbG9yRW5kID0gY29sb3JTY2FsZXNbY3VycmVudENvbG9yU2NhbGVdKGkgLyBwb2ludHMubGVuZ3RoKTtcblx0fSk7XG5cblx0YW5pbWF0ZShsYXlvdXRzW2N1cnJlbnRMYXlvdXRdLCBwb2ludHMpO1xufVxuXG5cbi8vIGluaXRpYWxpemUgcmVnbFxucmVnbCh7XG5cdC8vIGVuYWJsZSB0aGUgdGV4dHVyZSBmbG9hdCBleHRlbnNpb24gdG8gc3RvcmUgcG9zaXRpb25zIGluIGJ1ZmZlcnNcbiAgZXh0ZW5zaW9uczogW1xuICAgICdPRVNfdGV4dHVyZV9mbG9hdCcsXG4gIF0sXG5cbiAgLy8gY2FsbGJhY2sgd2hlbiByZWdsIGlzIGluaXRpYWxpemVkXG4gIG9uRG9uZTogbWFpblxufSk7XG4iXX0=