0xedc8a720…fea4sent to0x99a9b7c1…b069·#16,544,802·view on Etherscan
class Vector{constructor(t,e,i){this.x=t||0,this.y=e||0,this.z=i||0}static zero(){return new Vector(0,0,0)}static fromAngle(t){return new Vector(Math.cos(t),Math.sin(t))}static random2D(){return Vector.fromAngle(Math.random()*Math.PI*2)}static add(t,e){return new Vector(t.x+e.x,t.y+e.y,t.z+e.z)}static sub(t,e){return new Vector(t.x-e.x,t.y-e.y,t.z-e.z)}static div(t,e){return new Vector(t.x/e,t.y/e,t.z/e)}static mult(t,e){return new Vector(t.x*e,t.y*e,t.z*e)}static average(t){if(0===t.length)return;let e=new Vector;return t.forEach((t=>e.addVector(t))),e.div(t.length),e}static distXY(t,e,i,s){let r=Math.abs(e-t),n=Math.abs(s-i);return Math.sqrt(n*n+r*r)}dist(t){let e=t.x-this.x,i=t.y-this.y,s=t.z-this.z;return Math.sqrt(e*e+i*i+s*s)}distXY(t,e){let i=t-this.x,s=e-this.y;return Math.sqrt(i*i+s*s)}addVector(t){return this.x+=t.x,this.y+=t.y,this.z+=t.z,this}add(t,e,i){return this.x+=t,this.y+=e,this.z+=i,this}subVector(t){return this.x-=t.x,this.y-=t.y,this.z-=t.z,this}sub(t,e,i){return this.x-=t,this.y-=e,this.z-=i,this}mult(t){return this.x*=t,this.y*=t,this.z*=t,this}div(t){return this.x/=t,this.y/=t,this.z/=t,this}magnitude(){return Math.sqrt(this.x*this.x+this.y*this.y)}magnitudeSquared(){return this.x*this.x+this.y*this.y+this.z*this.z}heading2D(){return Math.atan2(this.y,this.x)}normal(){let t=Math.sqrt(this.x*this.x+this.y*this.y);return new Vector(this.x/t,this.y/t,0)}normalize(){let t=this.magnitude();return this.div(t),this}normalizeTo(t){let e=this.magnitude();return e>0&&(e=t/e,this.mult(e)),this}setMag(t){return this.normalize(),this.mult(t),this}copy(){return new Vector(this.x,this.y,this.z)}rotate(t,e){let i=Math.PI/180*e,s=Math.cos(i),r=Math.sin(i),n=s*(this.x-t.x)+r*(this.y-t.y)+t.x,o=s*(this.y-t.y)-r*(this.x-t.x)+t.y;return new Vector(n,o,0)}zero(){this.x=this.y=this.z=0}set(t,e,i){this.x=t,this.y=e,this.z=i}setFromVector(t){this.x=t.x,this.y=t.y,this.z=t.z}setXYZ(t,e,i){this.x=t,this.y=e,this.z=i}swapXY(){let t=this.x;this.x=this.y,this.y=t}toString(){return"<"+this.x+", "+this.y+", "+this.z+">"}}class Point{constructor(t,e,i,s){this.pos=new Vector(t,e,0),this.oldpos=new Vector(t,e,0),this.vel=new Vector(0,0,0),this.pinned=!1,this.grabbed=!1,this.grabbable=!1,this.friction=FRICTION,this.bounce=.9,this.index=0,this.isCollided=!1,this.gravity=new Vector(0,0,0),this.radius=i,this.color=s,this.mass=1}pin(){return this.pinned=!0,this}unpin(){return this.pinned=!1,this}applyImpulse(t,e,i){this.applyForce(new Vector(t,e,i))}applyForce(t){this.pos.addVector(t)}collide(t,e){this.index=e;for(let e=0;e<t.length;e++){let i=t[e];if(i.index!=this.index){let t=Math.abs(i.pos.x-this.pos.x),e=Math.abs(i.pos.y-this.pos.y),s=Math.sqrt(Math.pow(t,2)+Math.pow(e,2));if(s<this.radius+i.radius){let t=this.pos.copy();t=t.subVector(i.pos),t=t.div(s),t=t.mult(s-(this.radius+i.radius)),t=t.mult(-this.bounce),this.pos=this.pos.addVector(t),i.pos=i.pos.subVector(t)}}}}resolveBehaviors(t,e=this.radius,i=1){let s=Vector.sub(this.pos,t.pos),r=s.magnitudeSquared(),n=e*e;if(r<n){var o=s.normalizeTo(1-r/n).mult(i);this.applyForce(o)}}update(t,e,i,s){this.pinned||(this.grabbable&&s?this.grabbed=!0:s||(this.grabbed=!1),this.grabbed?(this.pos.x=e,this.pos.y=i,this.oldpos.setXYZ(this.pos.x,this.pos.y,0)):(this.vel=Vector.sub(this.pos,this.oldpos),this.vel.mult(this.friction),this.oldpos.setXYZ(this.pos.x,this.pos.y,0),this.pos.addVector(this.vel),this.pos.addVector(this.gravity)))}constrain(t,e){this.vel=Vector.sub(this.pos,this.oldpos),this.vel.mult(this.friction),this.pos.x>t.width-e-this.radius&&(this.pos.x=t.width-e-this.radius,this.oldpos.x=this.pos.x+this.vel.x*this.restitution),this.pos.x<this.radius+e&&(this.pos.x=this.radius+e,this.oldpos.x=this.pos.x+this.vel.x*this.restitution),this.pos.y>t.height-e-this.radius&&(this.pos.y=t.height-e-this.radius,this.oldpos.y=this.pos.y+this.vel.y*this.restitution),this.pos.y<this.radius+e&&(this.pos.y=this.radius+e,this.oldpos.y=this.pos.y+this.vel.y*this.restitution)}}class Spring{constructor(t,e,i,s){this.startPoint=t,this.endPoint=e,this.stiffness=i,this.color=s,this.weight=1,length?this.length=length:this.length=this.startPoint.pos.dist(this.endPoint.pos)}update(){let t=this.endPoint.pos.x-this.startPoint.pos.x,e=this.endPoint.pos.y-this.startPoint.pos.y,i=Math.sqrt(t*t+e*e),s=(this.length-i)/i*this.stiffness,r=t*s*.1,n=e*s*.1,o=this.startPoint.mass+this.endPoint.mass,a=this.startPoint.mass/o;o=this.endPoint.mass/o,this.startPoint.pinned||(this.startPoint.pos.x-=r*o,this.startPoint.pos.y-=n*o),this.endPoint.pinned||(this.endPoint.pos.x+=r*a,this.endPoint.pos.y+=n*a)}drawPixelCtx(t,e,i,s){t[Math.floor(i)*Math.floor(192)+Math.floor(e)]=s,SHADOW&&(t[Math.floor(i-2)*Math.floor(192)+Math.floor(e-0)]=0)}pixelLine(t,e,i,s,r){let n,o,a,h,l,d,g,p,c,u,x;if(a=s-e,h=r-i,l=Math.abs(a),d=Math.abs(h),g=2*d-l,p=2*l-d,d<=l)for(a>=0?(n=e,o=i,c=s):(n=s,o=r,c=e),this.drawPixelCtx(t,n,o,this.color),x=0;n<c;x++)n+=1,g<0?g+=2*d:(a<0&&h<0||a>0&&h>0?o+=1:o-=1,g+=2*(d-l)),this.drawPixelCtx(t,n,o,this.color);else for(h>=0?(n=e,o=i,u=r):(n=s,o=r,u=i),this.drawPixelCtx(t,n,o,this.color),x=0;o<u;x++)o+=1,p<=0?p+=2*l:(a<0&&h<0||a>0&&h>0?n+=1:n-=1,p+=2*(l-d)),this.drawPixelCtx(t,n,o,this.color)}render(t){this.pixelLine(t,this.startPoint.pos.x,this.startPoint.pos.y,this.endPoint.pos.x,this.endPoint.pos.y)}}class Body{constructor(t){this.points=[],this.springs=[],this.iterations=t||4}addPoint(t,e,i,s){this.points.push(new Point(t,e,i,s))}addSpring(t,e,i,s,r){this.springs.push(new Spring(t,e,i,s,r))}removeSpring(t){this.springs.splice(this.springs.indexOf(t),1)}trackPoints(t,e){for(let i=0;i<this.points.length;i++){let s=t-this.points[i].pos.x,r=e-this.points[i].pos.y;s*s/Math.pow(this.points[i].radius,2)+r*r/Math.pow(this.points[i].radius,2)<=1?this.points.find((t=>1==t.grabbed))||(this.points[i].grabbable=!0):this.points[i].grabbable=!1}}collidePoints(){for(let t=0;t<this.points.length;t++){this.points[t].collide(this.points,t)}}updatePoints(t,e,i,s){for(let r=0;r<this.points.length;r++)this.points[r].update(t,e,i,s)}updateSprings(){for(let t=0;t<this.springs.length;t++)this.springs[t].update()}updateConstraints(t,e){for(let i=0;i<this.points.length;i++)this.points[i].constrain(t,e)}renderSprings(t,e){for(let i=0;i<this.springs.length;i++)this.springs[i].render(t,e)}update(t,e,i,s,r){this.trackPoints(i,s),this.updatePoints(e,i,s,r);for(let t=0;t<this.iterations;t++)this.collidePoints(),this.updateSprings(),this.updateConstraints(e,MARGIN);this.renderSprings(t,e)}}class wormJoint{constructor(t,e){this.points=t,this.springs=[],this.targetVolume=this.getArea(),this.color=e;for(let t=1;t<this.points.length-1;t++)this.addSprings(t)}getArea(){let t=0;t+=this.points[this.points.length-1].pos.x*this.points[0].pos.y-this.points[0].pos.x*this.points[this.points.length-1].pos.y;for(let e=0;e<this.points.length-1;e++)t+=this.points[e].pos.x*this.points[e+1].pos.y-this.points[e+1].pos.x*this.points[e].pos.y;return t*=.5,t}getConnectedPts(t){let e,i;return 0==t?e=this.points[this.points.length-1]:t>=1&&(e=this.points[t-1]),t==this.points.length-1?i=this.points[0]:t<=this.points.length-1&&(i=this.points[t+1]),{previousPt:e,nextPt:i}}addSprings(t){let e=this.getConnectedPts(t);e.previousPt.pos.x,e.nextPt.pos.x,e.previousPt.pos.y,e.nextPt.pos.y,e.previousPt.pos.dist(e.nextPt.pos);this.springs.push(new Spring(e.previousPt,e.nextPt,5,this.color))}update(){for(let t=0;t<this.springs.length;t++)this.springs[t].update()}}class World{constructor(){this.bodies=[],this.joints=[]}joinBodies(...t){let e=new Body(this.iterations),i=[],s=[];for(let e=0;e<t.length;e++){i.push(t[e].points),s.push(t[e].springs);let r=this.bodies.indexOf(t[e]);this.bodies.splice(r,1)}return i=[].concat.apply([],i),s=[].concat.apply([],s),e.points=i,e.springs=s,this.addBody(e),e}addBody(t){this.bodies.push(t)}addJoint(t){this.joints.push(t)}update(t,e,i,s,r){for(let t=0;t<this.joints.length;t++)this.joints[t].update();for(let n=0;n<this.bodies.length;n++)this.bodies[n].update(t,e,i,s,r)}}function Grad(t,e,i){this.x=t,this.y=e,this.z=i}Grad.prototype.dot2=function(t,e){return this.x*t+this.y*e};let grad3=[new Grad(1,1,0),new Grad(-1,1,0),new Grad(1,-1,0),new Grad(-1,-1,0),new Grad(1,0,1),new Grad(-1,0,1),new Grad(1,0,-1),new Grad(-1,0,-1),new Grad(0,1,1),new Grad(0,-1,1),new Grad(0,1,-1),new Grad(0,-1,-1)],p=[151,160,137,91,90,15,131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23,190,6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33,88,237,149,56,87,174,20,125,136,171,168,68,175,74,165,71,134,139,48,27,166,77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244,102,143,54,65,25,63,161,1,216,80,73,209,76,132,187,208,89,18,169,200,196,135,130,116,188,159,86,164,100,109,198,173,186,3,64,52,217,226,250,124,123,5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42,223,183,170,213,119,248,152,2,44,154,163,70,221,153,101,155,167,43,172,9,129,22,39,253,19,98,108,110,79,113,224,232,178,185,112,104,218,246,97,228,251,34,242,193,238,210,144,12,191,179,162,241,81,51,145,235,249,14,239,107,49,192,214,31,181,199,106,157,184,84,204,176,115,121,50,45,127,4,150,254,138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180],perm=new Array(512),gradP=new Array(512);for(let t=0;t<256;t++){let e;e=0^p[t],perm[t]=perm[t+256]=e,gradP[t]=gradP[t+256]=grad3[e%12]}let F2=.5*(Math.sqrt(3)-1),G2=(3-Math.sqrt(3))/6;class Simplex{get(t,e){let i,s,r,n,o,a=(t+e)*F2,h=Math.floor(t+a),l=Math.floor(e+a),d=(h+l)*G2,g=t-h+d,p=e-l+d;g>p?(n=1,o=0):(n=0,o=1);let c=g-n+G2,u=p-o+G2,x=g-1+2*G2,w=p-1+2*G2;h&=255,l&=255;let m=gradP[h+perm[l]],y=gradP[h+n+perm[l+o]],f=gradP[h+1+perm[l+1]],b=.5-g*g-p*p;b<0?i=0:(b*=b,i=b*b*m.dot2(g,p));let v=.5-c*c-u*u;v<0?s=0:(v*=v,s=v*v*y.dot2(c,u));let E=.5-x*x-w*w;return E<0?r=0:(E*=E,r=E*E*f.dot2(x,w)),70*(i+s+r)}}function distSquared(t,e,i,s){return(t=i-t)*t+(e=s-e)*e}class qPoint{constructor(t,e){this.x=t,this.y=e}}class Rectangle{constructor(t,e,i,s){this.x=t,this.y=e,this.w=i,this.h=s}contains(t){return t[0]>=this.x-this.w&&t[0]<this.x+this.w&&t[1]>=this.y-this.h&&t[1]<this.y+this.h}intersects(t){return!(t.x-t.w>this.x+this.w||t.x+t.w<this.x-this.w||t.y-t.h>this.y+this.h||t.y+t.h<this.y-this.h)}}class Circle{constructor(t,e,i){this.x=t,this.y=e,this.r=2*i,this.rSquared=this.r*this.r}contains(t){return distSquared(this.x,this.y,t.x,t.y)<=this.rSquared}}class QuadTree{constructor(t,e){this.bnd=t,this.capacity=e,this.points=[],this.divided=!1}subdivide(){let t=this.bnd.x,e=this.bnd.y,i=this.bnd.w,s=this.bnd.h,r=new Rectangle(t+i/2,e-s/2,i/2,s/2);this.ne=new QuadTree(r,this.capacity);let n=new Rectangle(t-i/2,e-s/2,i/2,s/2);this.nw=new QuadTree(n,this.capacity);let o=new Rectangle(t+i/2,e+s/2,i/2,s/2);this.se=new QuadTree(o,this.capacity);let a=new Rectangle(t-i/2,e+s/2,i/2,s/2);this.sw=new QuadTree(a,this.capacity),this.divided=!0}insert(t){return!!this.bnd.contains(t)&&(this.points.length<this.capacity?(this.points.push(t),!0):(this.divided||this.subdivide(),!!this.ne.insert(t)||(!!this.nw.insert(t)||(!!this.se.insert(t)||(!!this.sw.insert(t)||void 0)))))}query(t,e){if(e||(e=[]),this.bnd.intersects(t)){for(let i of this.points)t.contains(i)&&e.push(i);return this.divided&&(this.nw.query(t,e),this.ne.query(t,e),this.sw.query(t,e),this.se.query(t,e)),e}}}class Random{constructor(){this.useA=!1;let t=function(t){let e=parseInt(t.substr(0,8),16),i=parseInt(t.substr(8,8),16),s=parseInt(t.substr(16,8),16),r=parseInt(t.substr(24,8),16);return function(){e|=0,i|=0,s|=0,r|=0;let t=(e+i|0)+r|0;return r=r+1|0,e=i^i>>>9,i=s+(s<<3)|0,s=s<<21|s>>>11,s=s+t|0,(t>>>0)/4294967296}};this.prngA=new t(tokenData.hash.substr(2,32)),this.prngB=new t(tokenData.hash.substr(34,32));for(let t=0;t<1e6;t+=2)this.prngA(),this.prngB()}r_d(){return this.useA=!this.useA,this.useA?this.prngA():this.prngB()}r_n(t,e){return t+(e-t)*this.r_d()}r_i(t,e){return Math.floor(this.r_n(t,e+1))}r_b(t){return this.r_d()<t}r_c(t){return t[this.r_i(0,t.length-1)]}}function color(){let t=R.r_d(),e=R.r_d(),i=R.r_d();return Math.round(255)<<24|Math.round(255*t)<<16|Math.round(255*e)<<8|Math.round(255*i)}function constrain(t,e,i){return Math.max(Math.min(t,i),e)}function map(t,e,i,s,r,n){const o=(t-e)/(i-e)*(r-s)+s;return n?s<r?constrain(o,s,r):constrain(o,r,s):o}function random(t,e){return(e-t)*R.r_d()+t}function radians(t){return t*(Math.PI/180)}function dist(t,e,i,s){let r=i-t,n=s-e;return Math.sqrt(n*n+r*r)}function fbm(t,e,i,s,r,n,o){let a=0,h=1,l=r,d=0;for(let r=0;r<t;r++)d+=noise.get(e*l+XOFF,i*l+YOFF)*h,a+=h,h*=s,l*=2;return d/=a,d=d*(o-n)/2+(o+n)/2,d}let projectNumber=Math.floor(parseInt(tokenData.tokenId)/1e6),mintNumber=parseInt(tokenData.tokenId)%1e6,R=new Random,noise=new Simplex;const C=document.createElement("canvas");document.body.appendChild(C);let w,h,devicePixelRatio=window.devicePixelRatio||1;window.innerHeight<=window.innerWidth?(w=.75*Math.max(window.innerHeight,1),h=Math.max(window.innerHeight,1)):(w=Math.max(window.innerWidth,1),h=Math.max(window.innerWidth,1)/.75),C.width=w,C.height=h;const idata=new ImageData(192,256);let u32=new Uint32Array(idata.data.buffer);const gl=C.getContext("webgl",{antialias:!1,preserveDrawingBuffer:!0});let program,numVtx;C.style.imageRendering="pixelated",C.imageSmoothingEnabled=!1;let time=0;const drawCan=document.createElement("canvas"),ctx=drawCan.getContext("2d");ctx.imageSmoothingEnabled=!1,drawCan.width=192,drawCan.height=256;let qtree,mouseX=0,mouseY=0,grabbing=!1,polygons=[],points=[];const eps=2,THETA=R.r_c([1,5,30]),DELTA=R.r_c([1,360]),N=R.r_c([.01,.1,.3,.6,.7]),FRICTION=R.r_c([.99,.95]),SHADOW=R.r_d()>.8,BG=color(),MARGIN=R.r_c([4,8,12,18]),XOFF=R.r_i(0,9999),YOFF=R.r_i(0,9999),LEN=R.r_c([drawCan.width,drawCan.width/2]),FLOW=R.r_d(),PINDEX=parseInt(10*R.r_d()),colorPalettes={riso:[145/256,78/256,114/256,0,.46875,191/256,255/256,116/256,119/256,241/256,.3125,.375,118/256,91/256,167/256,255/256,102/256,94/256,255/256,.90625,0,210/256,81/256,94/256,255/256,108/256,47/256,210/256,81/256,94/256],midnight:[.96875,249/256,250/256,233/256,236/256,239/256,222/256,226/256,230/256,206/256,212/256,218/256,173/256,181/256,189/256,73/256,130/256,207/256,73/256,.3125,87/256,52/256,58/256,.25,33/256,37/256,41/256,27/256,28/256,29/256],poster:[0,.1875,73/256,214/256,40/256,40/256,247/256,127/256,0,252/256,191/256,73/256,234/256,226/256,183/256,244/256,241/256,222/256,.875,122/256,95/256,61/256,.25,91/256,129/256,178/256,154/256,242/256,204/256,143/256],ancient:[0,18/256,25/256,0,95/256,115/256,10/256,147/256,150/256,148/256,210/256,189/256,233/256,.84375,166/256,238/256,155/256,0,202/256,103/256,2/256,187/256,62/256,3/256,174/256,.125,18/256,155/256,34/256,38/256],inca:[214/256,.25,69/256,233/256,255/256,249/256,158/256,.84375,219/256,70/256,117/256,153/256,29/256,51/256,84/256,21/256,.375,100/256,0,196/256,154/256,.96875,225/256,108/256,255/256,194/256,180/256,251/256,143/256,103/256],midcentury:[61/256,49/256,91/256,68/256,75/256,110/256,.4375,139/256,117/256,154/256,.71875,122/256,.96875,249/256,145/256,58/256,46/256,57/256,30/256,85/256,92/256,244/256,.84375,205/256,237/256,177/256,131/256,241/256,81/256,82/256],dreamy:[255/256,205/256,178/256,255/256,180/256,162/256,229/256,.59375,155/256,181/256,131/256,141/256,109/256,.40625,117/256,188/256,212/256,222/256,165/256,204/256,209/256,.625,185/256,191/256,157/256,172/256,178/256,148/256,155/256,.625],gameboy:[95/256,99/256,79/256,155/256,196/256,203/256,207/256,235/256,223/256,226/256,250/256,219/256,219/256,239/256,188/256,245/256,253/256,198/256,245/256,195/256,150/256,.8125,177/256,122/256,.65625,159/256,.40625,65/256,82/256,31/256],fruity:[255/256,116/256,119/256,249/256,65/256,68/256,.4375,116/256,124/256,98/256,.65625,229/256,73/256,130/256,207/256,249/256,199/256,79/256,246/256,.625,77/256,238/256,127/256,75/256,25/256,151/256,93/256,.71875,199/256,196/256],hollywood:[.96875,249/256,250/256,233/256,236/256,239/256,222/256,226/256,230/256,206/256,212/256,218/256,173/256,181/256,189/256,249/256,65/256,68/256,73/256,.3125,87/256,52/256,58/256,.25,33/256,37/256,41/256,27/256,28/256,29/256]},palettes=Object.keys(colorPalettes),palette=colorPalettes[palettes[PINDEX]];let world;function drawLine(t){let e=new Body(1),i=color();for(let s=0;s<t.length;s++)e.addPoint(t[s][0],t[s][1],2,i);for(let s=0;s<t.length-1;s++)e.addSpring(e.points[s],e.points[s+1],.999,i);let s=new wormJoint(e.points,color());return world.addJoint(s),e}document.body.style.backgroundColor=`rgb(${255*palette[12]}, ${255*palette[13]}, ${255*palette[14]})`,C.style.boxShadow=`0px 0px 30px rgb(${255*palette[27]}, ${255*palette[28]}, ${255*palette[29]})`;const start=t=>{let e=BG,i=new Rectangle(0,0,drawCan.width,drawCan.height);qtree=new QuadTree(i,2),world=new World(4);let s=[];for(let t=0;t<2e3;t++){let t=generatePolygon();if(canPutPoly(t,points)&&polygons.length<100){polygons.push(t);for(let e=0;e<t.length;e++)qtree.insert(t[e])}}for(let t=0;t<polygons.length;t++)s.push(drawLine(polygons[t]));world.joinBodies(...s),s=[];for(let t=0;t<u32.buffer.byteLength;t++)u32[t]=e},mmove=t=>{let e=C.getBoundingClientRect();mouseX=map(t.clientX-e.left,0,C.width,0,drawCan.width),mouseY=map(t.clientY-e.top,0,C.height,0,drawCan.height)},grab=t=>{grabbing=!0},stop=t=>{grabbing=!1};function generatePolygon(){let t=random(0,drawCan.width),e=random(0,drawCan.height),i=Math.floor(random(3,LEN)),s=[t,e],r=random(0,2*Math.PI),n=[];n.push([t,e]);for(let e=0;e<i;e++){let o;o=FLOW>.3?snapAngle(fbm(32,s[0],s[1],.5,.002,0,1)*Math.PI*18*N,THETA):FLOW<.2?snapAngle(r,DELTA):snapAngle(r*(e/i*2)+t,1);let a=[-Math.cos(o),-Math.sin(o)];a[0]*=5,a[1]*=5;let h=s;h[0]+=a[0],h[1]+=a[1],n.push([h[0],h[1]]),s=[h[0],h[1]]}return n}function canPutPoly(t){if(polygonIsOut(t))return!1;for(let e=0;e<t.length;e++){let i=new Rectangle(t[e][0],t[e][1],4,4),s=qtree.query(i);for(let i=0;i<s.length;i++)if(dist(s[i][0],s[i][1],t[e][0],t[e][1])<2)return!1}return!0}function canPlace(t){if(polygonIsOut(t))return!1;for(let e of polygons)if(polygonsIntersect(t,e))return!1;return!0}function polygonIsOut(t){for(let e of t)if(e[0]<MARGIN||e[0]>drawCan.width-MARGIN||e[1]<MARGIN||e[1]>drawCan.height-MARGIN)return!0;return!1}function snapAngle(t,e){let i=radians(e);return Math.round(t/i)*i}const verts="\nattribute vec2 aVertexPosition;\nvoid main() {\ngl_Position = vec4(aVertexPosition, 0.0, 1.0);\n}",frags="\n#ifdef GL_ES\nprecision highp float;\n#endif\n\nuniform sampler2D t0;\nuniform vec2 ur;\nuniform vec3 p[10];\nvec3 rgb2hsv(vec3 c)\n{\n vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);\n vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));\n vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));\n\n float d = q.x - min(q.w, q.y);\n float e = 1.0e-10;\n return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);\n}\nvec3 closestColor(vec3 color) {\n vec3 targetHSV = rgb2hsv(color);\n vec3 closest = p[0];\n float minDist = 999.0;\n\n for (int i = 0; i < 10; i++) {\n vec3 col = p[i];\n vec3 colHSV = rgb2hsv(col);\n float dr = abs(color.r - col.r);\n float dg = abs(color.g - col.g);\n float db = abs(color.b - col.b);\n float dist = sqrt(dr * dr + dg * dg + db * db);\n if (dist < minDist) {\n closest = col;\n minDist = dist;\n }\n }\n return closest;\n}\nfloat I(vec2 pixel) {\n const float a1 = 0.75487766624669276;\n const float a2 = 0.569840290998;\n return fract(a1 * pixel.x + a2 * pixel.y);\n}\nfloat D(vec2 coords, float color, float grey) {\n float noised = (2.0/grey) * (I(coords)) + color - (1.0/grey);\n float levels = clamp(floor(grey * noised) / (grey-1.0), 0.0, 1.0);\n return levels;\n}\nvoid main(void) {\nfloat gm = 2.2;\nvec2 uv = gl_FragCoord.xy / ur.xy;\nfloat h = 0.0;\nif (ur.y < 1024.) {\n h = floor(ur.y / ur.y);\n} else {\n h = floor(ur.y / 1024.);\n}\nvec2 pb = gl_FragCoord.xy / h;\nvec2 tl = ur.xy / h;\nvec2 vuv = floor(pb) / tl;\nfloat gr = 2.0;\nvec3 c = pow(texture2D(t0, vuv).rgb, vec3(gm));\nc += vec3((texture2D(t0, vuv).rgb - texture2D(t0, vuv+(vec2(cos(radians(30.)),sin(radians(30.))) * 0.001)).rgb) * 9.);\nc += vec3((texture2D(t0, vuv).rgb - texture2D(t0, vuv-(vec2(cos(radians(30.)),sin(radians(30.))) * 0.001)).rgb) * -9.);\nvec2 xp = floor(pb);\nvec3 col = vec3(D(xp, c.r, gr), D(xp, c.g, gr), D(xp, c.b, gr));\ncol.rgb = pow(col, vec3(1.0/gm));\ngl_FragColor = vec4(closestColor(col), 1.0);\n}",initGL=()=>{gl.blendFunc(gl.ONE,gl.ONE_MINUS_SRC_ALPHA),gl.disable(gl.BLEND),gl.disable(gl.DEPTH_TEST),gl.clearColor(1,1,1,1),gl.viewport(0,0,C.width,C.height)},initShaders=()=>{const t=gl.createShader(gl.VERTEX_SHADER);gl.shaderSource(t,verts),gl.compileShader(t);const e=gl.createShader(gl.FRAGMENT_SHADER);gl.shaderSource(e,frags),gl.compileShader(e),program=gl.createProgram(),gl.attachShader(program,t),gl.attachShader(program,e),gl.linkProgram(program);const i=new Float32Array([-1,1,1,1,1,-1,-1,1,1,-1,-1,-1]),s=gl.createBuffer();gl.bindBuffer(gl.ARRAY_BUFFER,s),gl.bufferData(gl.ARRAY_BUFFER,i,gl.STATIC_DRAW);numVtx=i.length/2,program.aVertexPosition=gl.getAttribLocation(program,"aVertexPosition"),gl.enableVertexAttribArray(program.aVertexPosition),gl.vertexAttribPointer(program.aVertexPosition,2,gl.FLOAT,!1,0,0),gl.useProgram(program),gl.bindBuffer(gl.ARRAY_BUFFER,s)},img=gl.createTexture(),initDrawCtx=()=>{ctx.clearRect(0,0,drawCan.width,drawCan.height),img.image=drawCan,gl.bindTexture(gl.TEXTURE_2D,img),gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_WRAP_S,gl.CLAMP_TO_EDGE),gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_WRAP_T,gl.CLAMP_TO_EDGE),gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MIN_FILTER,gl.NEAREST),gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MAG_FILTER,gl.NEAREST),gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL,!0),gl.texImage2D(gl.TEXTURE_2D,0,gl.RGBA,gl.RGBA,gl.UNSIGNED_BYTE,drawCan),render(),console.log("SKEUOMORPHS by galo canizares (b. 1989)")},render=()=>{gl.viewport(0,0,C.width,C.height),gl.clearColor(0,0,0,0),gl.clear(gl.COLOR_BUFFER_BIT),program.uResolution=gl.getUniformLocation(program,"ur"),gl.uniform2fv(program.uResolution,[C.width,C.height]),gl.uniform3fv(gl.getUniformLocation(program,"p"),palette),gl.uniform1i(gl.getUniformLocation(program,"t0"),0),gl.activeTexture(gl.TEXTURE0),gl.bindTexture(gl.TEXTURE_2D,img),gl.activeTexture(gl.TEXTURE1),gl.drawArrays(gl.TRIANGLES,0,numVtx),gl.bindTexture(gl.TEXTURE_2D,img),gl.texImage2D(gl.TEXTURE_2D,0,gl.RGBA,gl.RGBA,gl.UNSIGNED_BYTE,drawCan),world.update(u32,drawCan,mouseX,mouseY,grabbing),ctx.putImageData(idata,0,0,0,0,drawCan.width,drawCan.height),requestAnimationFrame(render)},screenshot=t=>{"s"===t.key&&saveAsImage()},saveAsImage=()=>{let t;try{let e="image/png";t=C.toDataURL(e,1),saveFile(t.replace(e,"image/octet-stream"),"SKEUOMORPHS-"+tokenData.hash+".png")}catch(t){return void console.log(t)}},saveFile=function(t,e){let i=document.createElement("a");"string"==typeof i.download?(document.body.appendChild(i),i.download=e,i.href=t,i.click(),document.body.removeChild(i)):location.replace(uri)};document.addEventListener("keydown",screenshot),window.addEventListener("mousedown",grab),window.addEventListener("mousemove",mmove),window.addEventListener("mouseup",stop),window.addEventListener("touchstart",(t=>{t.preventDefault(),grab(t.touches[0])}),{passive:!1}),window.addEventListener("touchmove",(t=>{t.preventDefault(),mmove(t.touches[0])}),{passive:!1}),window.addEventListener("touchend",(t=>{t.preventDefault(),stop(t.touches[0])}),{passive:!1}),start(),gl.blendFunc(gl.ONE,gl.ONE_MINUS_SRC_ALPHA),gl.disable(gl.BLEND),gl.disable(gl.DEPTH_TEST),gl.clearColor(1,1,1,1),gl.viewport(0,0,C.width,C.height),initShaders(),ctx.clearRect(0,0,drawCan.width,drawCan.height),img.image=drawCan,gl.bindTexture(gl.TEXTURE_2D,img),gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_WRAP_S,gl.CLAMP_TO_EDGE),gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_WRAP_T,gl.CLAMP_TO_EDGE),gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MIN_FILTER,gl.NEAREST),gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MAG_FILTER,gl.NEAREST),gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL,!0),gl.texImage2D(gl.TEXTURE_2D,0,gl.RGBA,gl.RGBA,gl.UNSIGNED_BYTE,drawCan),render(),console.log("SKEUOMORPHS by galo canizares (b. 1989)");