0x9297…0b05

All memos sent from and to 0x9297…0b05.

# Seedlings "A young plant, especially one raised from a seed." Each Seedling grows delicately on a windowsill gazing outside. A Seedling's natural environment–whether a grassy prairie, a rocky mountain, or by a river–is but a memory now, leaving a faded imprint on the canvas' outer border. Some Seedlings resemble trees and flowers, others may appear to be geometric abstractions and fractals–yet all feature interplay between filled patterned regions (leaves and petals) and lines of solid color (stems and branches). Other abstractions also make an appearance: circles representing fruits, stars, or the sun and moon; and a gradient sky with foggy clouds beyond the frames of the window. ## Foundation The idea for Seedlings was sown in 2019 and was my first foray into Generative Art. It began as a study of fractal trees where each depth level was individually parametrized (angle of rotation, length, etc.). Initially just a hobbyist project in the pre-Art Blocks era, I returned to Seedlings in 2022 to develop it into the longform series, I believe, that most effectively highlights the underlying algorithm's potential. So, I rewrote Seedlings from scratch, turning its simple monochromatic line renderer into a WebGL shader renderer capable of transforming Bézier curves into abstract stems, branches, leaves, and petals with diverse and colorful palettes. ## Inspiration Having lived much of my life in New York, one of the most urbanized cities in the world, I developed a significant appreciation for green spaces. The city's parks became a refuge from the urban sprawl–where one could touch some grass, breathe fresh air, and pretend they were somewhere else. In an attempt to fill more of my life with green, I placed some plants on my windowsill. The joy they bring my home inspired Seedlings. Over the course of its development, Seedlings collected many stylistic influences, including Hokusai's trees, Charles Demuth's crisscrossing polygonal regions, and Alphonse Mucha's curves. As such, you will find elements of Ukiyo-e and Art Nouveau across the collection. Seedlings also contains stylistic elements found in my other work, such as ink-like outlining and the concept of shape overlap. Additionally, I drew inspiration from contemporary longform Generative Art that aims to create complex emergent behaviors from the interactions of a small set of primitives. The structural patterns that form each Seedling are created purely from the probabilistic placement of their branches and petals. ## Dedication Seedlings has been a labor of love and has particular sentimental value to me as the inception of my Generative Art practice. It feels fitting and very exciting to be given the opportunity to release Seedlings on Art Blocks, the original longform Generative Art platform. Thank you to everyone who helped and supported me during this journey.
75,.25]);let a=0;const n=()=>{const e=t.levels.pop();t.levels.pop(),t.levels.push(e)};for(;(o>i||o<307)&&a<=100;)o>i?n():t.addLevels(P(y.CONFIG.getProp("constantTree")?void 0:{angle:Math.PI*e.random(T(.5,1.75,.1)),branchFactor:Math.round(e.random(2,6))},void 0,void 0,Number(t.levels[t.levels.length-1].type===s.Petals))),o=t.getNumBranches(),a++;for(;a>100&&o>i;)n(),o=t.getNumBranches();t.levels[t.levels.length-1].type===s.Petals&&t.levels[t.levels.length-2].type===s.Petals&&t.levels.pop(),r=e.color(0),y.mainLayer.stroke(r),S=new u(t),S.compute()};const k=(e,t,r,o,i=y.mainLayer)=>{const a=(Math.cos(1e3*e+o)+1)/2*2,n=(Math.sin(1e3*t+o)+1)/2*2,s=i.noise(a,n),l=i.map(s,0,1,.5,1.5);return{diamX:r*l*Math.cos(o),diamY:r*l*Math.sin(o)}},M=({x:e,y:t,n:r,side:o=.2,reeds:i=!0,pg:a})=>{const n=.25;r=(r=2*r-1)>-n&&r<0?-n:r<n&&r>0?n:0==r?a.random(-n,n):r;const s=(.1+a.random(-.003,.003))*(r*o),l=a.map((r+1)/2,0,1,.1,.2);E(e,t,s,l,.1,!!i&&a.random()<.2,a)},B=({x:e,y:o,n:i,pg:a})=>{a.push(),a.strokeWeight(1.05*t),((e,o,i,a=y.mainLayer)=>{a.beginShape();const n=[];for(let t=0;t<15;t++){const r=a.TWO_PI/15*t,{diamX:s,diamY:l}=k(e,o,i,r,a),c=e+s,d=o+l;n.push([c,d])}for(let e of[...n,...n.slice(0,4)])a.curveVertex(e[0]*a.width,e[1]*a.height);a.endShape(),a.push(),a.noStroke(),a.fill(r);for(let r=.75*i;r>.25*i;r-=i/8)for(let n=0;n<15;n++){const s=a.TWO_PI/15*n,{diamX:l,diamY:c}=k(e,o,r,s,a);a.random()<i/.02*.5*a.map(r/i,0,1,.25,1)&&a.circle((e+l+a.random(-i/10,i/10))*a.width,(o+c+a.random(-i/10,i/10))*a.height,a.constrain(.1*i*a.width,.002*a.width,.003*a.width)*t*.65)}a.pop()})(e,o,.015*a.map(i,0,1,.5,1),a),a.pop()},D=({x:e,y:r,wind:o,pg:i})=>{((e,r,o,i=20,a=.005,n=.3,s=1.05,l=y.mainLayer)=>{l.push(),l.strokeWeight(y.scaleFactor*t*.75),l.noFill(),l.beginShape(),l.vertex(e*l.width,r*l.width),n=Math.PI*n;for(let t=0;t<i;t++){const t=o(e,r),i=l.map(t,0,1,Math.PI*s-n,Math.PI*s+n),c=e-a*(1-t)*Math.cos(i),d=r-a*(1-t)*Math.sin(i);l.curveVertex(c*l.width,d*l.width),e=c,r=d}l.endShape(),l.pop()})(e,r,((e,t)=>i.noise(e*o,t*o)))},G=(e,t=!0,r=20,o=.01,i=.02,a=0,n=y.mainLayer)=>{const s=[];for(let e=-.1;e<1.1;e+=o)s.push(e);t&&n.shuffle(s,!0);for(let t=-.1+a;t<1.1;t+=i/2)for(let a of s){const s=n.noise(a*r,t*r),l=n.noise(a*r,t*r,1e3),c={x:a+n.random(-o/2,o/2),y:t+n.random(-i/2,i/2),n:s,wind:r,n2:l,pg:n};e.length>1?(l>.5&&e[0](c),e[1](c)):e[0](c)}},E=(t,r,o,i,a,n=!1,s=y.mainLayer)=>{const l=t+o,c=r-i;let d=t-o,h=r-i/2;if(s.beginShape(),s.vertex(t*s.width,r*s.height),s.bezierVertex(d*s.width,h*s.height,d*s.width,h*s.height,l*s.width,c*s.height),d=t-o*a,s.bezierVertex(d*s.width,h*s.height,d*s.width,h*s.height,(t+o/4)*s.width,r*s.height),s.vertex((t+o/4)*s.width,r*s.height),s.endShape(s.CLOSE),n){s.push();const t=l-d,r=c-h;s.translate(l*s.width,c*s.height);const o=-e.createVector(t,r).angleBetween(s.createVector(0,1));s.rotate(o),s.translate(-l*s.width,-c*s.height);const i=.005*s.width;s.translate(s.createVector(i/2,0).rotate(o)),s.rect(l*s.width,c*s.height,i,-.02*s.height),s.pop()}},A=()=>{y.drawPost(`${m}\n${h}\n${d}\nconst float thick = 0.0007;float bricks(vec2 st) {st*=5.;st += ${e.random().toPrecision(4)}+1.;vec2 origSt = st;st = st*2.-1.;float repeat = 5.;float yStretch = 0.5;float d = min(abs(fract(st.x*yStretch*repeat+steps(origSt.y, repeat*2.)*repeat)-0.5), abs(fract((st.y+0.5)*repeat)-0.5)*yStretch);return clamp((d-(noise(st*5.)-0.35)*0.01)*50., 0.,1.);}`,"outColor = vec4(vec3(tex.rgb == vec3(1.) ? vec3(bricks(st)) : tex.rrr), 1.);",(()=>({})),"bricks")};function*L(){var e,r;((e=y.mainLayer)=>{e.background("white"),e.scale(1.5),e.strokeWeight(y.scaleFactor*t);const r=y.CONFIG.getProp("bgPattern");"prairie"===r?G([e=>M({...e,side:.35,reeds:!1})],!0,10):"forest"===r?G([M,B]):"marsh"===r?(G([D]),G([M,()=>{}],!1)):"beach"===r?G([B,D]):"mountain"===r?G([B],!0):"river"===r?G([D],!1,void 0,.01,.01):"urban"===r?A():"urbanOvergrown"===r&&(e.fill("red"),G([M,B],void 0,void 0,void 0,void 0,.65),A())})(),e=.25,r=8e-4,y.drawPost(`uniform float blurChance; uniform float blurOff; ${d}`,"outColor = vec4(texture(tex0, rand(st) < blurChance ? uv + (rand(st) * 2. - 1.)*(blurOff*scaleFactor) : uv ).rgb, 1.);",(()=>({blurChance:e,blurOff:r})),"postBlur"),S.renderGl(),y.drawFxaa(),y.drawGrainGL(.1)}let R=0;return e.draw=()=>{y.drawLoadWrapper(L)},I}));
se(st*vec2(1, 3)*5.), noise(st*vec2(1, 5)*10.), 0.25);float clouds = steps(fract(cloudsSdf*2.), 10.);oCol = (insideBox && !insideFill && outsidePetals && outsideCircles) ? mix(mix(bgCol, midCol, clamp(origSt.y, 0.,1.)), bgCol, 1.-clamp((1.-origSt.y)*2.+clouds,0.,1.)): oCol;oCol = (outsidePetals && insideFill && outsideCircles) ? mix(fgCol, vec3(1), 0.25): oCol;oCol = !outsideCircles ? midCol : oCol;outline += thick*(1.-clamp(blended, 0.0, 1.));outline = clamp(smoothstep(0., thick*2., outline), 0., 1.);float outsideOutline = sdfToOutline(outsideFill, thick);float bOutline = sdfToOutline(box - boxOutlineThick, boxOutlineThick);vec3 outlineCol = darkestCol;vec3 innerOutlineCol = mix(outlineCol, vec3(0), 0.4);vec3 outerOutlineCol = mix(outlineCol, vec3(0), 0.55);vec3 lightOutlineCol = mix(outerOutlineCol, fgCol, 0.35);oCol = outsideCircles ? mix(innerOutlineCol, oCol, outline) : oCol;oCol = box_ - boxRound - boxOutlineThick*4. < 0. && !insideFill && !insidePetals ? mix(lightOutlineCol, oCol, bOutline) : oCol;oCol = outsideCircles && outsidePetals ? mix(outerOutlineCol, oCol, outsideOutline) : oCol;oCol = mix(outerOutlineCol, oCol, circlesOutline);outColor = vec4(vec3(oCol), 1.); `,this.glUniformInit,"ft",void 0,!0,!0)}getFlippedBranch(e){const[t,r]=[e.control,this.branches[e.parentId].dst].map((e=>y.vecToP5Vec(e))),o=function(e,t,r){const o=p5.Vector.sub(y.vecToP5Vec(r),t),i=p5.Vector.dot(e,o),a=o.copy().mult(Math.sign(i)*i/p5.Vector.dot(o,o)).add(t),n=p5.Vector.sub(a,e),s=p5.Vector.normalize(o),l=p5.Vector.sub(n,s.copy().mult(2*p5.Vector.dot(s,n)));return p5.Vector.add(l,a)}(t,r,e.dst);return{...e,control:{x:o.x,y:o.y}}}getScreenParams(){if(this.screenParams)return this.screenParams;let e=1/0,t=1/0,r=-1/0,o=-1/0,a=[];for(let e of this.branches){if(e.level.fill===i.Full){const t=this.getFlippedBranch(e);a.push(t)}}let n=0;for(let i of[...this.branches,...a]){const a=this.getSrc(i),s=.03*i.level.stroke,l=f(a.x,a.y,i.control.x,i.control.y,i.dst.x,i.dst.y);e=Math.min(e,l.x.min-s),t=Math.min(t,l.y.min-s),r=Math.max(r,l.x.max+s),o=Math.max(o,l.y.max+s),n++}let s=r-e,l=o-t;s=r-e,l=o-t;let c=Math.max(s,l)/2*(1+this.outerMargin),d=-(e+s/2),h=-(t+l/2);n=0;for(let i of[...this.branches,...a]){const a=this.getControlSizeGL(i);a&&(e=Math.min(e,n<this.branches.length?i.control.x-a*c:1/0),t=Math.min(t,n<this.branches.length?i.control.y-a*c:1/0),r=Math.max(r,n<this.branches.length?i.control.x+a*c:-1/0),o=Math.max(o,n<this.branches.length?i.control.y+a*c:-1/0),n++)}const m=this.margin*Math.max(s,l);e-=m,t-=m,r+=m,o+=m,s=r-e,l=o-t,c=Math.max(s,l)/2*(1+this.outerMargin),d=-(e+s/2),h=-(t+l/2);const p={minX:e,minY:t,maxX:r,maxY:o,sizeX:s,sizeY:l,middleX:d,middleY:h,scale:c,margin:m};return this.screenParams=p,p}getControlSize(e){return.03*Math.pow(e.level.length,2)}getControlSizeGL(t){return t.level.type!==s.Stem?e.map(this.getControlSize(t),this.getMinControlSize(),this.getMaxControlSize(),.005,.04):0}}const g=e=>"#"+e,v=e=>e.map(g),x=(e,...t)=>(e.splice(t[0],0,...t.slice(1)),e);let b;let y;const F=()=>{let[t,r]=(()=>{const t={rare:["poppy","lemon"],low:[e.random(["mulberry","lissitzky"]),"orange","hokusai","anna","strawberry","spring"],mid:["mango","dew","river","cucumber","mucha","woods"],hi:["blueberry","raspberry","sunset","mondrian","dragonFruit","demuth"]},r=e.random(t[y.weightedRandom(["rare","low","mid","hi"],[.04,.27,.31,.38])]);return[r,o.getPaletteOrdered(o.addHashTags(b[r]))]})();y.CONFIG.addProp("paletteName",{val:t,name:"Palette"}),y.CONFIG.addPrivProp("palette",r)},C=t=>{const r=t?t.length*e.random(T(.8,.9,.05)):1;return{branchFactor:y.CONFIG.getProp("constantTree")?y.CONFIG.getProp("constantTreeBf"):Math.round(e.random(2,4)),angle:y.CONFIG.getProp("constantTree")?y.CONFIG.getProp("constantTreeAngle"):Math.PI*e.random(T(.85,1.5,.1)),length:r,stroke:Math.max(1,t?.85*t.stroke:2.25),curvature:y.weightedRandom([e.random(.2,.4),e.random(.5,.8)],[.2,.8]),fill:y.CONFIG.getProp("constantTree")&&2===y.CONFIG.getProp("constantTreeBf")?y.weightedRandom([i.None,i.Full,i.Half],[.5,.25,.25]):i.None,type:s.None}},w=(t=1)=>{let r;return[...new Array(t)].map(((t,o)=>t=>(r=((t,r=!1)=>{const o=e.random([i.Half,i.Full]),a=e.random([2,4]),n=e.random(T(a/2*.25,1.25,.1)),l=Number(2==a&&n<=.5?e.random()<.5:r);return{...C(t),branchFactor:a,angle:Math.PI*n,angleOff:Math.PI*l,fill:o,pop:1,curvature:e.random([.5,.75])*(l<=0?1:-1),length:t?t.length*y.CONFIG.getProp("petalLength"):1,type:s.Petals}})(t),{...r,pop:1})))},P=(t,r=(y.CONFIG.getProp("constantTree")?0:y.weightedRandom([1,2],[.6,.4])),o=!0,i=0)=>[...[...new Array(e.random([1,2]))].map((()=>e=>({...C(e),...t}))),...[...new Array(r?Math.round(e.constrain(Math.abs(e.randomGaussian(i,.75*r)),i,r)):0)].map((()=>e=>(e=>({...C(e),branchFactor:1,angle:0,type:s.Spacer}))(e))),...o?w():[]],T=(e,t,r=.2)=>a.range(e,t,r);let S;const I=t=>{y=t;const r=y.weightedRandom(["growing","developed"],[.2,.8]);y.CONFIG.addProp("treeStage",{val:r,name:"Age"});const o=e.random()<.05;y.CONFIG.addProp("diamond",o);const a=o?"fit":y.weightedRandom(["thin","fit","max"],[.5,.4,.1]);y.CONFIG.addProp("windowMargin",a);const n=y.weightedRandom([0,.5],[.7,.3]);y.CONFIG.addPrivProp("windowBars",n),n&&y.CONFIG.addProp("windowBarsPerspective",y.weightedRandom(["center",e.random(["in","out"])],[.5,.5]));const l=e.random()<.05&&"developed"===r;y.CONFIG.addProp("constantTree",l),l&&y.CONFIG.addProp("constantTreeBf",{val:y.weightedRandom([2,3,4],[.6,.1,.3]),name:"Constant Tree Branching Factor"}),y.CONFIG.addPrivProp("constantTreeAngle",l?Math.PI*(y.CONFIG.getProp("constantTreeBf")>=4?1.5:y.CONFIG.getProp("constantTreeBf")>=3?1.25:(y.CONFIG.getProp("constantTreeBf"),.5)):0);const c=e.random(T(.75,.95,.01));let d;if(y.CONFIG.addPrivProp("petalLength",c),"max"!==a&&y.CONFIG.addProp("bgPattern",{name:"Origin",val:y.weightedRandom([e.random(["prairie","mountain","river","urban"]),e.random(["forest","marsh","beach","urbanOvergrown"])],[.7,.3])}),b={dragonFruit:{colors:["E9B0AF","FCDA5F","b63d34","8e1529","698996"],order:e.random([[0,3,1,...e.shuffle([4,2])],[4,3,1,...e.shuffle([0,2])]])},cucumber:{order:x(e.shuffle([0,2,3]),1,1),colors:["A5CEA1","741A29","fffacc","D9969C"]},orange:{order:y.weightedRandom([x(e.shuffle([3,2]),1,4,1,0),(()=>{const t=e.shuffle([3,2]);return x(x(x([...e.shuffle([4,0]),1],0,t[0]),2,t[1]),4,t[2])})()],[.3,.6]),colors:["EE6930","FFA647","f3e9e7","9BC2E0","1697B1"]},demuth:{order:e.random([[1,2,0,3],[0,2,1,3],[3,0,1,2]]),colors:["e3a953","fff1ab","bc3234","437988"]},sunset:{order:x(x(e.shuffle([4,3,2]),e.random([1,2,3]),1),1,0),colors:["264653","2a9d8f","e9c46a","f4a261","e76f51"]},river:{order:e.random([(()=>{const t=[...e.shuffle([2,3]),...e.shuffle([0,1])];return[t[0],t[2],t[1],t[3]]})()]),colors:["005f73","0BAAAD","A9DBCA","e9d8a6"]},mucha:{order:(()=>{const t=e.shuffle([3,4]);return x(x(e.shuffle([0,1,2]),1,t[0]),3,t[1])})(),colors:["8CB46A","f4e285","f4a259","588978","bc4b51"]},mulberry:{order:e.random([[1,2,0,3],[1,3,0,2]]),colors:["F3EEE2","cac3b3","747167","1d1e1b"]},mango:{order:(()=>{const t=e.shuffle([4,3]);return x(x(x(e.shuffle([0,1,2]),2,3),1,t[0]),4,t[1])})(),colors:["f2f3ae","edd382","fc9e4f","FF531F","020122"]},dew:{order:x(e.shuffle([1,2]),1,0,3),colors:["313715","7BB2D9","9AB752","F0FBDA"]},raspberry:{order:x(e.shuffle([1,2,3]),1,0),colors:["301a4b","72A9C2","ffeaec","f39a9d"]},blueberry:{order:x(x(e.shuffle([0,3]),1,1),e.random([2,3]),2),colors:["e9d8a6","0d1b1e","7798ab","EDC0D1"]},spring:{order:(()=>{const t=e.shuffle([1,3]);return x(x(e.shuffle([0,3]),t[0],2),t[1],1)})(),colors:["FFD3AD","69a2b0","659157","ADC893"]},mondrian:{order:e.random([[3,4,...e.shuffle([1,0]),2],x(x(e.shuffle([0,1,3]),2,4),1,2)]),colors:["e5dcc8","ebaf23","cc3b38","3372a8","1c1d1b"]},woods:{colors:["606c38","283618","E2B178","bc6c25","efb82c"],order:e.random([[0,1,4,2,3],[2,1,4,0,3]])},lissitzky:{order:e.random([[1,4,0,3,2],[1,3,0,4,2]]),colors:["F1EEE2","F3EDE2","747167","1d1e1b","980606"]},poppy:{order:[1,2,3,0],colors:["a10045","eeeeee","ffffff","ffffff"]},hokusai:{order:(()=>{const t=e.shuffle([2,3]);return[1,t[0],0,t[1]]})(),colors:["FFD9C2","d99e73","633818","3E5D78"]},anna:{order:(()=>{const t=[4,3];return x(x([2,...e.shuffle([0,1])],2,t[0]),e.random([3,4]),t[1])})(),colors:["8C94C7","DF5D5D","d77c90","f18d90","F6CCB7"]},strawberry:{order:[1,...x(e.shuffle([0,3]),1,2)],colors:["DD4831","5b5f97","E2F1AF","66101F"]},lemon:{order:[1,3,2,0],colors:["629E64","e5b329","f4e7a4","dca119"]}},F(),!l){d=y.weightedRandom([2,3,4,5,6],[.4,.3,.15,.1,.05]);const e={val:d,name:"Main Branching Factor"};"developed"===r?y.CONFIG.addProp("flairBf",e):y.CONFIG.addPrivProp("flairBf",e)}const h=new p,m=e.random(T(1,2,.1));y.CONFIG.addPrivProp("stemFact",m);const u=y.weightedRandom([1,2],[.6,.4]);y.CONFIG.addProp("numStems",{val:u+1,name:"Stem Curves"});const f=y.weightedRandom([[e.random([.15,0,3.85]),"up"],[e.random(T(.25,1.5,.25)),"left"],[e.random(T(2.5,3.75,.25)),"right"],[e.random([1.75,1.85,2.15,2.25]),"down"]],[.2,.35,.35,.1]),g=f[0];y.CONFIG.addProp("facingDir",{name:"Facing Direction",val:f[1]});let v=0;h.addLevels([...[...new Array(u)].map(((t,r,o)=>t=>{const a=C(t),n=.35,l=Math.min(Math.abs(2-g),n);let c=g>=2?e.random(T(-l,n,.1)):e.random(T(-.35,+l,.1)),d=((e,t=4)=>((e%=t)<0&&(e=t- -e),e))(g+(r<u-1?c:0)-v);return v+=d,0===r&&(y.CONFIG.addPrivProp("stemCurveP",(0===g?e.random([1,-1]):d<=2&&g<=2?1:-1)*y.weightedRandom([.2,.5,1,1.5,2],[.1,.2,.3,.3,.1])),y.CONFIG.addProp("stemCurvature",Math.abs(y.CONFIG.getProp("stemCurveP")))),{...a,branchFactor:1,angle:Math.PI*d,fill:i.None,length:a.length*m,type:r===o.length-1?s.MainStem:s.Stem}})),...e.random()<.5?w(e.random([1,2])).map((e=>t=>({...e(t),length:.5*t.length}))):[],...d?[...P({branchFactor:d,angle:Math.PI*e.random(T(e.map(Math.pow((d-2)/4,2),0,1,.5,1),1.5,.1)),fill:e.random()<.5?e.random([i.Half,i.Full]):i.None,type:s.Flair},1,0===R,1),...P({fill:e.random()<.5?e.random([i.Half,i.Full]):i.None},1,void 0,1)].flat():[]]),y.CONFIG.addPrivProp("ftConfig",{name:"config",val:h})},O=Math.min(window.innerWidth,window.innerHeight)>1800?2400:1800,N=O/1800*.75;e.setup=()=>{y=new l([e],"PROD",void 0,"Seedlings",I,N,O/N);const t=y.CONFIG.getProp("ftConfig");let o=t.getNumBranches();const i=y.weightedRandom([600,800],[.
esFromLevel(e))}computeBranch(t,r){const o=this.getSrc(t),[i,a,n]=[o,t.dst,t.control].map((e=>y.vecToP5Vec(e))),l=p5.Vector.sub(a,i).normalize();let c=e.atan2(l.y,l.x);const d=r.angle,h=d/Math.max(1,r.branchFactor-1)+2*Math.PI,m=r.angleOff??0,p=[],u=e.shuffle([...new Array(r.branchFactor)].map(((t,o)=>o<=Math.round(e.random(.25*r.branchFactor,r.branchFactor)))));for(let e=0;e<r.branchFactor;e++){const o=r.length,l=h*(r.type!==s.None&&r.type!==s.Flair||!(u[e]||4===r.branchFactor&&r.angle===1.5*Math.PI)||"growing"!==y.CONFIG.getProp("treeStage")?e:0)+c+m-d/2,f={dst:{x:a.x+o*Math.cos(l),y:a.y+o*Math.sin(l)},control:p5.Vector.add(a,p5.Vector.sub(a,r.type===s.Petals?i:n).normalize().mult(r.curvature*o+.00137)),parentId:t.id,level:r,id:this.branches.length};p.push(f),this.branches.push(f)}return p}computeBranches(e){this.branchLevelIndices=new Array(e.levels.length);const t=[...e.levels];for(let e=0;e<t.length;e++){let r=this.branches.length;const o=this.getBranchesFromLevel(e-1);let i=t[e];if(!(i.length<=0)){for(const e of o)this.computeBranch(e,i);this.branchLevelIndices[e]=[r,this.branches.length],i.pop&&(e-=i.pop,t.splice(e+1,i.pop))}}return this.branches}toScreen(t){return(t+1)/2*e.width}toNdcTrans(e,t,r){return(e+t)/r}getSrc(e){return{x:e.parentId>=0?this.branches[e.parentId].dst.x:0,y:e.parentId>=0?this.branches[e.parentId].dst.y:1e-4}}getMaxControlSize(){return this.getControlSize(this.getMainStem())}getMinControlSize(){return this.getControlSize(this.getLastBranch())}getMainStem(){return this.branches[this.branches.findIndex((e=>e.level.type===s.MainStem))]}getLastBranch(){return this.branches[this.branches.length-1]}glUniformInit=t=>{const{maxY:r,middleX:o,middleY:a,scale:n}=this.getScreenParams();let s=this.branches.map((e=>{let t=this.toNdcTrans(...e.parentId>=0?[this.getSrc(e).y,a,n]:[r,a,n]);return e.parentId<0&&(t=1.05),[this.toNdcTrans(e.dst.x,o,n),this.toNdcTrans(e.dst.y,a,n),this.toNdcTrans(this.getSrc(e).x,o,n),t]})).flat();const l=this.branches.map((e=>{const{middleX:t,middleY:r,scale:o}=this.getScreenParams(),i=e.level;return[this.toNdcTrans(e.control.x,t,o),this.toNdcTrans(e.control.y,r,o),this.getControlSizeGL(e),i.stroke]})).flat(),c=t.memo.combineTex,d=c._renderer.GL,h=this.branches.length,m=e=>({height:1,width:h,texData:e}),p={dataType:d.FLOAT,format:d.RGBA,internalFormat:d.RGBA32F,minFilter:d.NEAREST,magFilter:d.NEAREST,wrapS:d.CLAMP_TO_EDGE,wrapT:d.CLAMP_TO_EDGE},u=new p5.Texture(c._renderer,m(new Float32Array(s)),p),f=new p5.Texture(c._renderer,m(new Float32Array(l)),p),g={...p,dataType:d.UNSIGNED_BYTE,internalFormat:d.RGBA,wrapS:d.REPEAT,wrapT:d.REPEAT},v=t.CONFIG.getProp("palette"),x=v[v.length-1],b=new p5.Texture(c._renderer,{height:1,width:v.length,texData:new Uint8Array([...v.map((e=>[...t.p5ColorToByteArr(e),1]))].flat())},g),y=new p5.Texture(c._renderer,{height:1,width:v.length-1,texData:new Uint8Array([...v.slice(1).map((e=>[...t.p5ColorToByteArr(e),1]))].flat())},g),F=new Uint8Array(this.branches.map((e=>{const t=e.level;return 0!==t.curvature?t.fill:i.None}))),C=new p5.Texture(c._renderer,m(F),{...p,dataType:d.UNSIGNED_BYTE,format:d.RED_INTEGER,internalFormat:d.R8UI,wrapS:d.REPEAT,wrapT:d.REPEAT});return{branches:u,controls:f,palette:b,paletteWOutBg:y,bgCol:t.p5ColorToArr(x),fills:C,boxDims:[...this.getBoxDims()],darkestCol:t.p5ColorToArr([...t.CONFIG.getProp("palette")].sort(((r,o)=>t.luma(e.color(r))-t.luma(e.color(o))))[0])}};getBoxDims=()=>{const{minX:t,maxX:r,maxY:o,minY:i,middleX:n,middleY:s,scale:l,margin:c}=this.getScreenParams(),d=this.toNdcTrans(t,n,l),h=this.toNdcTrans(i,s,l),m=[(this.toNdcTrans(r,n,l)-d)/2,(this.toNdcTrans(o,s,l)-h)/2],p=this.branches[0],u=f(this.getSrc(p).x,this.getSrc(p).y,p.control.x,p.control.y,p.dst.x,p.dst.y),g=this.toNdcTrans(u.x.min,n,l),v=this.toNdcTrans(u.x.max,n,l),x=Math.max(v,Math.abs(g)),b=e.shuffle(["fit"!==y.CONFIG.getProp("windowMargin")?.55:1,1].map(((e,t)=>({dim:e,i:t})))),F=b.sort(((e,t)=>m[e.i]-m[t.i])).map(((e,t)=>e.dim*m[t]));return F[0]=1!==b[0].dim?(()=>{const e=c/l;return Math.abs(x-F[0])<e?x+e:F[0]})():F[0],F.map(((e,t)=>1!==b[t].dim?a.steps(e,32,!0):e))};renderGl(){y.drawPost(`\n${h}\n${d}\n${m}\nfloat luma(vec3 color){return dot(color, vec3(0.299, 0.587, 0.114));}\nuniform sampler2D branches;uniform sampler2D controls;uniform sampler2D palette;uniform vec3 bgCol;uniform usampler2D fills;uniform vec2 boxDims;uniform vec3 darkestCol;float alpha = 0.39999;float thick = 0.0007;uint None = uint(0);uint Full = uint(1);uint Half = uint(2);struct Ret {float outline;vec3 blended;float patternFill;float outsideFill;float circles;float circlesWOutBorder;};vec3 blendSub(float d1, vec3 col, vec4 col1) {float alpha = col1.a;float antialiasEdges = 0.002;d1 = smoothstep(-antialiasEdges, antialiasEdges, d1);return d1 <= 0. ? col - col1.a : col.rgb;}Ret f(vec2 st) {float outline = 10.;vec3 blended = vec3(1.);float patternFill = 10.;float outsideFill = 10.;float circles = 10.;float circlesWOutBorder = 10.;for (int i = 0; i < ${this.branches.length}; i++) {vec4 branch = texelFetch(branches, ivec2(i,0), 0);vec2 dst = branch.xy;vec2 parentDst = branch.zw;\t\tvec4 control = texelFetch(controls, ivec2(i,0), 0);float d;uint isFilled = texelFetch(fills, ivec2(i,0), 0).r;float curve = sdBezier(st, dst, control.xy, parentDst)-thick;float line = sdSegment(st, dst, parentDst)-thick * 0.65;float curves = -1.;float innerPattern = -1.; float outerThickFact = 6.;d = sdFilledBezier(st, dst, control.xy, parentDst); float outerThick = thick * outerThickFact;if (isFilled == Full || isFilled == Half){vec2 projecting = control.xy;vec2 projectingOn = dst - parentDst;\t\t\tfloat dotted = dot(projecting, projectingOn);vec2 projected = sign(dotted) * dotted / dot(projectingOn, projectingOn) * (projectingOn) + parentDst;vec2 reflectVec = reflect(projected - projecting, normalize(projectingOn));vec2 flippedControl = reflectVec + projected; float curve1 = sdBezier(st, dst, flippedControl, parentDst)-thick;curves = opUnion(curve, curve1);bool controlBranchParallel = abs(dot(normalize(dst-parentDst), normalize(control.xy-parentDst))) >= 0.999;if (controlBranchParallel) { outsideFill = opUnion(outsideFill, curve - thick*4. * control.w); continue; } innerPattern = opSmoothUnion(curve, curve1, 0.015);if (isFilled == Full) {d = opUnion(d, sdFilledBezier(st, dst, flippedControl, parentDst));\t\t\t\toutsideFill = opUnion(outsideFill, curve1 - outerThick);} else {outsideFill = opUnion(outsideFill, line - outerThick);}outsideFill = opUnion(outsideFill, curve - outerThick);\t\t\tfloat bandaidThickness = thick * 8.;float bandaid = sdSegment(st, dst, parentDst)-bandaidThickness;d = d <= 0. ? opUnion(d, bandaid) : d;blended = blendSub(d+thick, blended, vec4(vec3(0), alpha));\t\t\tif (isFilled == Full){outline = opUnion(outline, curves);} else if (isFilled == Half) {outline = opUnion(outline, opUnion(line, curve));}} else {outsideFill = opUnion(outsideFill, curve - thick*4. * control.w);if (i == 0) {outsideFill -= pow(map(st.y, branch.y, 1., 0., 1.) * 0.02,1.5);}}\t\tif (innerPattern != -1.) {patternFill =\td <= 0. ? opUnion(patternFill, innerPattern) : patternFill;}\t\tfloat radius = control.z;if (i > 0 && radius > 0.) {float circle = sdCircle(st - control.xy, radius);float subCircle = sdCircle(st - control.xy, max(radius + thick*2.*map(radius,0.005,0.04,0.75,1.), radius+thick));circlesWOutBorder = min(circlesWOutBorder, subCircle);circle = opSubtraction(circle, subCircle);circles = min(circles, circle);}} return Ret(outline, blended, patternFill, outsideFill, circles, circlesWOutBorder);}\n`,`vec2 origSt = st;st = uv * 2. - 1.;Ret ret = f(st);float outline = ret.outline;float blended = ret.blended.r;float blendedNorm = fract(ret.blended.r);float circles = ret.circles;float circlesWOutBorder = ret.circlesWOutBorder;float patternFill = ret.patternFill;float outsideFill = ret.outsideFill;patternFill = abs(patternFill) < 0.005 ? patternFill : fract(pow(patternFill, 0.5) * 10.);float boxRound = 0.03;float maxDim = max(boxDims.x, boxDims.y);float box_ = ${"max"!==y.CONFIG.getProp("windowMargin")?y.CONFIG.getProp("diamond")?"sdBox(rotateVec(st, PI*.25), vec2(maxDim/1.4121)-boxRound)":"sdBox(st, boxDims-boxRound)":"0."};\n${y.CONFIG.getProp("windowBars")?`vec2 repeat = vec2(${(()=>{const t=y.CONFIG.getProp("windowBars"),r=this.getBoxDims();return"max"===y.CONFIG.getProp("windowMargin")?y.CONFIG.getProp("windowBars"):e.map(Math.min(...r)/Math.max(...r),0,1,t-.2,t)})()}${"center"===y.CONFIG.getProp("windowBarsPerspective")?"":"left"===y.CONFIG.getProp("windowBarsPerspective")||"right"===y.CONFIG.getProp("windowBarsPerspective")?`*map(${"left"!==y.CONFIG.getProp("windowBarsPerspective")?"1.-":""}uv.x,0.,1.,0.5,1.)`:`*map(${"out"===y.CONFIG.getProp("windowBarsPerspective")?"1.-":""}abs(st.x),0.,1.,0.65,1.)`}); float barRound = boxRound*0.5/max(repeat.x, repeat.y);float barThick = 0.53;`:""}float box = ${y.CONFIG.getProp("windowBars")?"max(box_-boxRound, (sdBox(vec2(mod(st, repeat) - repeat + repeat/2.) / repeat, vec2(maxDim*barThick-barRound))-barRound))":"box_-boxRound"};float boxOutlineThick = thick;bool insideBox = box <= boxOutlineThick;bool outsideCircles = circlesWOutBorder > 0.;float circlesOutline = clamp(circles / fwidth(circles * (scaleFactor * 0.75)), 0.,1.); outline = outsideCircles ? outline : circlesOutline;blended = outsideCircles ? blended : 0.5;bool outsidePetals = blended >= 0.999;bool insidePetals = !outsidePetals;bool insideFill = outsideFill-thick < 0.;float colSteps = 4.;vec3 oCol;vec3 bgCol = texture(palette, vec2(1., 0)).rgb;vec3 fgCol = texture(palette, vec2(0., 0)).rgb;vec3 midCol = texture(palette, vec2(0.5)).rgb;oCol = !insidePetals && !insideFill ? fgCol : oCol;float lumaBg = luma(oCol);float bgOutlineCol = lumaBg < 0.45 ? 1. : lumaBg > 0.55 ? 0. : step(0.5, ${e.random().toPrecision(2)});oCol = mix(vec3(bgOutlineCol), oCol, negMult(tex.r, 0.15));float innerPattern = (insidePetals && outsideCircles) ? blendedNorm > 0. ? fract(((blendedNorm + steps(patternFill, 3.)) ) + 0.75) : 0. : blended;oCol = insidePetals ? texture(palette, vec2(innerPattern)).rgb : oCol;${"max"!==y.CONFIG.getProp("windowMargin")?"origSt.y += (1.-boxDims.y)*0.5;":""}float cloudsSdf = map(1.-origSt.y, 0., 1., 0.25, 1.) * mix(noi
14159;in vec2 vTexCoord;out vec4 outColor;uniform sampler2D randTex;uniform sampler2D tex0;uniform float scaleFactor;uniform float seed;float map(float value, float min1, float max1, float min2, float max2) {return min2 + (value - min1) * (max2 - min2) / (max1 - min1);}\n${e} void main() {vec2 uv = vTexCoord;uv.y = 1.0 - uv.y;vec2 st = vTexCoord;${a?"vec4 tex = texture(tex0, uv);":""}${t}}`));let l=this.memo.postShader[o].shader;if(void 0===l)throw new Error("Post Shader Undefined");r&&(this.memo.postShader[o].uniforms=r(this));const d=this.memo.postShader[o].uniforms;if(void 0===d)throw new Error("Uniforms Undefined");if(n){s.shader(l);for(let[e,t]of Object.entries(d))l.setUniform(e,t);l.setUniform("seed",this.getShaderSeed()),l.setUniform("scaleFactor",this.scaleFactor/this.initScaleFactor),a&&l.setUniform("tex0",i||s),s.rect(0,0,s.width,s.height)}}drawFxaa(){this.drawPost("/*MIT LICENSE*/#define A (1.0/ 128.0)\n#define B (1.0 / 8.0)\n#define C 8.0\nuniform vec2 resolution;void D(vec2 E,vec2 resolution,out vec2 F,out vec2 G,out vec2 H,out vec2 I,out vec2 J){vec2 K=1./resolution.xy;F=(E+vec2(-1.,-1.))*K;G=(E+vec2(1.,-1.))*K;H=(E+vec2(-1.,1.))*K;I=(E+vec2(1.,1.))*K;J=vec2(E*K);}vec4 L(sampler2D M,vec2 E,vec2 resolution,vec2 F,vec2 G,vec2 H,vec2 I,vec2 J){vec4 N;mediump vec2 K=vec2(1./resolution.x,1./resolution.y);vec3 O=texture(M,F).xyz;vec3 P=texture(M,G).xyz;vec3 Q=texture(M,H).xyz;vec3 R=texture(M,I).xyz;vec4 S=texture(M,J);vec3 T=S.xyz;vec3 U=vec3(0.299,0.587,0.114);float V=dot(O,U);float W=dot(P,U);float X=dot(Q,U);float Y=dot(R,U);float Z=dot(T,U);float a=min(Z,min(min(V,W),min(X,Y)));float b=max(Z,max(max(V,W),max(X,Y)));mediump vec2 c;c.x=-((V+W)-(X+Y));c.y=((V+X)-(W+Y));float d=max((V+W+X+Y)*(0.25*B),A);float e=1./(min(abs(c.x),abs(c.y))+d);c=min(vec2(C,C),max(vec2(-C,-C),c*e))*K;vec3 f=0.5*(texture(M,E*K+c*(1./3.-0.5)).xyz+texture(M,E*K+c*(2./3.-0.5)).xyz);vec3 g=f*0.5+0.25*(texture(M,E*K+c*-0.5).xyz+texture(M,E*K+c*0.5).xyz);float h=dot(g,U);if((h<a)||(h>b))N=vec4(f,S.a);else N=vec4(g,S.a);return N;}vec4 L(sampler2D M,vec2 E,vec2 resolution){mediump vec2 F;mediump vec2 G;mediump vec2 H;mediump vec2 I;mediump vec2 J;D(E,resolution,F,G,H,I,J);return L(M,E,resolution,F,G,H,I,J);}","vec2 fragCoord = uv * resolution;\noutColor = L(tex0, fragCoord, resolution);",(()=>({resolution:[this.dim,this.dim]})),"fxaa")}vecToP5Vec({x:e,y:t}){return this.p.createVector(e,t)}p5ColorToArr(e){return[this.p.red(e)/255,this.p.green(e)/255,this.p.blue(e)/255]}p5ColorToByteArr(e){return[this.p.red(e),this.p.green(e),this.p.blue(e)]}getSeed(){return parseInt(this.CONFIG.getProp("artName").slice(2,9),16)}saveOutput(){const e=`${this.collection.toLowerCase().replace(" ","-")}_${this.CONFIG.getProp("artName")}`;this.p.saveCanvas(e,"jpg")}canvasCssDim(e=this.p.windowWidth,t=this.p.windowHeight){const r=Math.min(e,t);this.p.drawingContext.canvas.style.width=`${r}px`,this.p.drawingContext.canvas.style.height=`${r}px`}addCSSStyles(){document.body.style.backgroundColor="black";var e=document.createElement("style");e.innerText="body {margin: 0;display: flex;justify-content: center;align-items: center;overflow: hidden;} #loader {position: absolute;color: white;width: 100vw;height: 100vh;display: flex;font-size: 3rem;justify-content: center;align-items: center;} @media (max-width: 600px) {#loader {font-size: 2rem;}",document.head.appendChild(e)}beginLoading(){if(!this.loadingDiv){this.loadingDiv=document.createElement("div"),this.loadingDiv.id="loader";const e=document.createElement("div");e.style.textAlign="center",e.innerHTML=`<div>Creating a <span style="font-style: italic">${this.collection}</span></div><div>Please Wait...</div>`,this.loadingDiv.appendChild(e),document.body.appendChild(this.loadingDiv)}this.loadingDiv.style.display="inherit",this.loading=!0}endLoading(){this.loadingDiv.style.display="none",this.loading=!1}drawLoadWrapper(e){if(this.loading){this.drawer||(this.drawer={fn:e(),ran:0});const t=this.drawer.fn.next();return t.done&&(this.p.noLoop(),this.endFrame(),this.endLoading(),this.printTimeElapse()),this.drawer.ran++,t.done}return this.p.loop(),this.beginLoading(),this.loading=!0,!1}print(){console.log(`${this.collection} By VES3L`),console.log(`width: ${this.dim}px`,`height: ${this.dim}px`)}}const c="#version 300 es \nin vec3 aPosition;in vec2 aTexCoord;out vec2 vTexCoord;void main(){vTexCoord=aTexCoord;vec4 a=vec4(aPosition,1.);a.xy=a.xy*2.-1.,gl_Position=a;}",d="highp float rand(vec2 co){highp float a=12.9898,b=78.233,c=43758.5453,dt=dot(co.xy,vec2(a,b)),sn=mod(dt,3.14);return fract(sin(sn)*c);} float mod289(float x){return x-floor(x*.00346)*289.;}vec4 mod289(vec4 x){return x-floor(x*.00346)*289.;}vec4 perm(vec4 x){return mod289((x*34.+1.)*x);}float noise(vec3 p){vec3 a=floor(p),d=p-a;d=d*d*(3.-2.*d);vec4 b=a.xxyy+vec4(0.,1.,0.,1.),k1=perm(b.xyxy),k2=perm(k1.xyxy+b.zzww),c=k2+a.zzzz,k3=perm(c),k4=perm(c+1.),o1=fract(k3*.02439),o2=fract(k4*.02439),o3=o2*d.z+o1*(1.-d.z);vec2 o4=o3.yw*d.x+o3.xz*(1.-d.x);return o4.y*d.y+o4.x*(1.-d.y);} float noise(vec2 p) {return noise(vec3(p, seed));}",h="float dot2(in vec2 v){return dot(v,v);}float cro(in vec2 a,in vec2 b){return a.x*b.y-a.y*b.x;}float ndot(vec2 a,vec2 b){return a.x*b.x-a.y*b.y;}float opUnion(float d1,float d2){return min(d1,d2);}float opSubtraction(float d1,float d2){return max(-d1,d2);}float opIntersection(float d1,float d2){return max(d1,d2);}float sdCircle(vec2 p,float r){return length(p)-r;}float sdSegment(in vec2 p,in vec2 a,in vec2 b){vec2 pa=p-a,ba=b-a;float h=clamp(dot(pa,ba)/dot(ba,ba),0.,1.);return length(pa-ba*h);}float sdBox(in vec2 p,in vec2 b){vec2 d=abs(p)-b;return length(max(d,0.))+min(max(d.x,d.y),0.);}float opSmoothUnion(float a,float b,float k){float h=max(k-abs(a-b),0.)/k;return min(a,b)-h*h*k*.25;}float sdBezier(in vec2 pos,in vec2 A,in vec2 B,in vec2 C){vec2 a=B-A,b=A-2.*B+C,c=a*2.,d=A-pos;float kk=1./dot(b,b),kx=kk*dot(a,b),ky=kk*(2.*dot(a,a)+dot(d,b))/3.,kz=kk*dot(d,a),res=0.,p=ky-kx*kx,p3=p*p*p,q=kx*(2.*kx*kx-3.*ky)+kz,h=q*q+4.*p3;if(h>=0.){h=sqrt(h);vec2 x=(vec2(h,-h)-q)/2.,uv=sign(x)*pow(abs(x),vec2(.333333));float t=clamp(uv.x+uv.y-kx,0.,1.);res=dot2(d+(c+b*t)*t);}else{float z=sqrt(-p),v=acos(q/(p*z*2.))/3.,m=cos(v),n=sin(v)*1.732051;vec3 t=clamp(vec3(m+m,-n-m,n-m)*z-kx,0.,1.);res=min(dot2(d+(c+b*t.x)*t.x),dot2(d+(c+b*t.y)*t.y));}return sqrt(res);}float sdSignedBezier(in vec2 pos,in vec2 A,in vec2 B,in vec2 C){vec2 a=B-A,b=A-2.*B+C,c=a*2.,d=A-pos;float kk=1./dot(b,b),kx=kk*dot(a,b),ky=kk*(2.*dot(a,a)+dot(d,b))/3.,kz=kk*dot(d,a),res=0.,sgn=0.,p=ky-kx*kx,q=kx*(2.*kx*kx-3.*ky)+kz,p3=p*p*p,q2=q*q,h=q2+4.*p3;if(h>=0.){h=sqrt(h);vec2 x=(vec2(h,-h)-q)/2.,uv=sign(x)*pow(abs(x),vec2(.333333));float t=clamp(uv.x+uv.y-kx,0.,1.);vec2 q=d+(c+b*t)*t;res=dot2(q),sgn=cro(c+2.*b*t,q);}else{float z=sqrt(-p),v=acos(q/(p*z*2.))/3.,m=cos(v),n=sin(v)*1.732051;vec3 t=clamp(vec3(m+m,-n-m,n-m)*z-kx,0.,1.);vec2 qx=d+(c+b*t.x)*t.x;float dx=dot2(qx),sx=cro(c+2.*b*t.x,qx);vec2 qy=d+(c+b*t.y)*t.y;float dy=dot2(qy),sy=cro(c+2.*b*t.y,qy);dx<dy?(res=dx,sgn=sx):(res=dy,sgn=sy);}return sqrt(res)*sign(sgn);}vec4 bboxBezier(in vec2 p0,in vec2 p1,in vec2 p2){vec2 mi=min(p0,p2),ma=max(p0,p2);if(p1.x<mi.x||p1.x>ma.x||p1.y<mi.y||p1.y>ma.y){vec2 t=clamp((p0-p1)/(p0-2.*p1+p2),0.,1.),s=1.-t,q=s*s*p0+2.*s*t*p1+t*t*p2;mi=min(mi,q),ma=max(ma,q);}return vec4(mi,ma);}vec2 rotateVec(vec2 st,float a){return vec2(cos(a)*st.x-sin(a)*st.y,sin(a)*st.x+cos(a)*st.y);}float sdFilledBezier(in vec2 st,in vec2 a,in vec2 b,in vec2 c){vec2 dis=c-a;float rot=-atan(dis.y,dis.x);vec2 n=vec2(dis.y,-dis.x);float sgn=dot(b-st,n),d=sdSignedBezier(st,a,b,c)*sgn,bez=sdBezier(st,a,b,c),bottomline=sdSegment(st,a,c);a=rotateVec(a,rot),b=rotateVec(b,rot),c=rotateVec(c,rot);vec4 bb=bboxBezier(a,b,c);float box=sdBox(rotateVec(st,rot)-(bb.xy+bb.zw)*.5,(bb.zw-bb.xy)*.5),line=sgn*dot(st,-n);const float weight=2.;d=min(max(d*1e+4,box),bez/weight),d=min(d,bottomline);return d*weight;}float sdfToOutline(float outsideFill,float thick){float newOutsideFill=abs(outsideFill)-thick;return mix(clamp(abs(outsideFill)/fwidth(outsideFill)/(scaleFactor*(thick*2000.)),0.,1.),clamp(newOutsideFill/(fwidth(newOutsideFill)*(scaleFactor*.5)),0.,1.),.5);}",m=`\nfloat negMult(float n, float mult){return 1.-((1. - n) * mult);}\n${["float","vec2"].map((e=>`${e} steps(${e} val, ${e} steps) {\nreturn float(int(val*steps)) / steps;\n}`)).join("\n")}\n`;function p(e,t){this.x=e,this.y=t}function u(e,t,r,o){if(o<0||1<o||isNaN(o))return!1;var i=new p(e.x+(t.x-e.x)*o,e.y+(t.y-e.y)*o),a=new p(t.x+(r.x-t.x)*o,t.y+(r.y-t.y)*o);return new p(i.x+(a.x-i.x)*o,i.y+(a.y-i.y)*o)}function f(e,t,r,o,i,a){var n=new p(e,t),s=new p(r,o),l=new p(i,a),c=(n.x-s.x)/(n.x-2*s.x+l.x),d=(n.y-s.y)/(n.y-2*s.y+l.y),h=u(n,s,l,c),m=h?Math.min(n.x,l.x,h.x):Math.min(n.x,l.x),f=h?Math.max(n.x,l.x,h.x):Math.max(n.x,l.x),g=u(n,s,l,d);return{x:{min:m,max:f},y:{min:g?Math.min(n.y,l.y,g.y):Math.min(n.y,l.y),max:g?Math.max(n.y,l.y,g.y):Math.max(n.y,l.y)}}}new p5((e=>{const t=.8;let r;const o={getPaletteOrdered:({colors:e,order:t})=>e.map(((e,t)=>[e,t])).sort(((e,r)=>t.indexOf(e[1])-t.indexOf(r[1]))).map((e=>e[0])),addHashTags(e){const t=JSON.parse(JSON.stringify(e));return t.colors=v(t.colors),t}};let i;var n;let s;var c;(n=i||(i={}))[n.None=0]="None",n[n.Full=1]="Full",n[n.Half=2]="Half",(c=s||(s={}))[c.None=0]="None",c[c.Stem=1]="Stem",c[c.MainStem=2]="MainStem",c[c.Petals=3]="Petals",c[c.Flair=4]="Flair",c[c.Spacer=5]="Spacer";class p{constructor(){this.levels=[]}addLevel(e){let t=this.levels.length-1;for(;t>0&&this.levels[t]&&this.levels[t].type===s.Petals;)t--;return this.levels.push(e(this.levels[t])),this}addLevels(e){for(const t of e)this.addLevel(t);return this}getNumBranches(){const e=new u(this);return e.compute(),e.branches.length}}class u{branches=[{dst:{x:0,y:0},control:{x:y.CONFIG.getProp("stemCurveP"),y:1.5},parentId:-1,id:0,level:{length:1,curvature:0,stroke:2.25,angle:0,branchFactor:1,fill:i.None,type:s.Stem}}];margin="max"!==y.CONFIG.getProp("windowMargin")?.03:0;outerMargin=.08;constructor(e){this.config=e}compute(){this.computeBranches(this.config)}getBranchIndicesFromLevel(e){return e>=0?this.branchLevelIndices[e]:[0,1]}getBranchesFromLevel(e){return this.branches.slice(...this.getBranchIndic
const e=function(e){var t=/\(\s*([^)]+?)\s*\)/.exec(e.slice(e.indexOf("("),e.indexOf(")")+1));return t&&(t=t[1].split(/\s*,\s*/)),[...t||[],(e=e.slice(e.indexOf("{"),e.lastIndexOf("}")+1)).slice(1,e.length-1)]};p5.RendererGL.prototype._initContext=Function(...e(String(p5.RendererGL.prototype._initContext).replace("webgl","webgl2")));let t,r=p5.Texture.prototype;p5.Texture=function(e,t,r){this._renderer=e;const o=this._renderer.GL;r=r||{},this.src=t,this.glTex=void 0,this.glTarget=o.TEXTURE_2D,this.glFormat=r.format||o.RGBA,this.glInternalFormat=r.internalFormat||this.glFormat,this.mipmaps=!1,this.glMinFilter=r.minFilter||o.LINEAR,this.glMagFilter=r.magFilter||o.LINEAR,this.glDataType=r.dataType||o.UNSIGNED_BYTE,this.isSrcMediaElement=void 0!==p5.MediaElement&&t instanceof p5.MediaElement,this._videoPrevUpdateTime=0,this.isSrcP5Image=t instanceof p5.Image,this.isSrcP5Graphics=t instanceof p5.Graphics,this.isImageData="undefined"!=typeof ImageData&&t instanceof ImageData,this.isTexture=void 0!==t.texData;const i=this._getTextureDataFromSource();return this.width=i.width,this.height=i.height,this.init(i),this},p5.Texture.prototype=r,p5.Texture.prototype.init=function(e){const t=this._renderer.GL;this.glTex=t.createTexture(),this.glWrapS=this._renderer.textureWrapX,this.glWrapT=this._renderer.textureWrapY,this.setWrapMode(this.glWrapS,this.glWrapT),this.bindTexture(),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MAG_FILTER,this.glMagFilter),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MIN_FILTER,this.glMinFilter),t.texImage2D(this.glTarget,0,this.glInternalFormat,this.width,this.height,0,this.glFormat,this.glDataType,e.texData)},p5.Texture.prototype._getTextureDataFromSource=function(){let e;return e=this.isSrcP5Image?this.src.canvas:this.isSrcMediaElement||this.isSrcP5Graphics||this.isSrcHTMLElement?this.src.elt:this.src,e},p5.Texture.prototype.update=function(){const e=this.src,t=this._getTextureDataFromSource(),r=this._renderer.GL;return this.bindTexture(),this.isTexture?r.texImage2D(this.glTarget,0,this.glInternalFormat,this.width,this.height,0,this.glFormat,this.glDataType,e.texData):r.texImage2D(this.glTarget,0,this.glFormat,this.glFormat,this.glDataType,t),!0},p5.Shader.prototype.oldProtoSetUniform=p5.Shader.prototype.setUniform,p5.Shader.prototype.setUniform=function(e,t){this.oldProtoSetUniform(e,t);const r=this.uniforms[e];if(!r)return;const o=this._renderer.GL,i=r.location;switch(this.useProgram(),r.type){case o.SAMPLER_2D:case o.UNSIGNED_INT_SAMPLER_2D:o.activeTexture(o.TEXTURE0+r.samplerIndex),r.texture=t instanceof p5.Texture?t:this._renderer.getTexture(t),o.uniform1i(i,r.samplerIndex)}return this},p5.Shader.prototype._loadUniforms=Function(...e(String(p5.Shader.prototype._loadUniforms).replace("o.type===e.SAMPLER_2D","(o.type===e.SAMPLER_2D||o.type===e.UNSIGNED_INT_SAMPLER_2D)"))),p5.Vector.normalize=function(e,t){return arguments.length<2?t=e.copy():t.set(e),t.normalize()};class o{constructor(e){this.useA=!1;let t=function(e){let t=parseInt(e.substr(0,8),16),r=parseInt(e.substr(8,8),16),o=parseInt(e.substr(16,8),16),i=parseInt(e.substr(24,8),16);return function(){t|=0,r|=0,o|=0,i|=0;let e=(t+r|0)+i|0;return i=i+1|0,t=r^r>>>9,r=o+(o<<3)|0,o=o<<21|o>>>11,o=o+e|0,(e>>>0)/4294967296}};this.prngA=new t(e.hash.substr(2,32)),this.prngB=new t(e.hash.substr(34,32));for(let e=0;e<1e6;e+=2)this.prngA(),this.prngB()}random_dec(){return this.useA=!this.useA,this.useA?this.prngA():this.prngB()}}const i=()=>{t=new o(tokenData)};i(),p5.prototype.random=function(e,r){const o=t.random_dec();if(void 0===e)return o;if(void 0===r)return e instanceof Array?e[Math.floor(o*e.length)]:o*e;if(e>r){var i=e;e=r,r=i}return o*(r-e)+e},p5.prototype.shuffle=function(e,t){const r=ArrayBuffer&&ArrayBuffer.isView&&ArrayBuffer.isView(e);let o,i,a=(e=t||r?e:e.slice()).length;for(;a>1;)o=this.random(0,1)*a|0,i=e[--a],e[a]=e[o],e[o]=i;return e};const a={arrToObj:e=>e.reduce(((e,t)=>(e[t[0]]=t[1],e)),{}),cumSum(e){let t=new Array(e.length);return e.reduce(((e,r,o)=>t[o]=e+r),0),t},range(e,t,r){if(0===e&&0===t)return[];const o=t-e,i=Math.ceil(o/r)+1;return[...new Array(i)].map(((o,i)=>Math.min(t,e+i*r)))},download(e,t,r){var o=new Blob([e],{type:r});if(window.navigator.msSaveOrOpenBlob)window.navigator.msSaveOrOpenBlob(o,t);else{var i=document.createElement("a"),a=URL.createObjectURL(o);i.href=a,i.download=t,document.body.appendChild(i),i.click(),setTimeout((function(){document.body.removeChild(i),window.URL.revokeObjectURL(a)}),0)}},camelCaseToText(e){const t=e.replace(/([A-Z])/g," $1");return t.charAt(0).toUpperCase()+t.slice(1)},steps:(e,t,r)=>Math.floor(e*t)/t+(r?1/t:0)};class n{config={};constructor(e){this.env=e}_addProp(e,t){this.config[e]={val:this.getWithin(t,"val"),pub:t.pub,...t.name?{name:this.getWithin(t,"name")}:{}}}addPropWPub(e,t,r){this._addProp(e,{...t.name?t:{val:t},pub:r})}addPrivProp(e,t){this.addPropWPub(e,t,!1)}addProp(e,t){this.addPropWPub(e,t,!0)}getConfig(e){return a.arrToObj(Object.entries(this.config).filter((([,t])=>t.pub==e)).map((([t,r])=>[r.name?r.name:e?a.camelCaseToText(t):t,(()=>{const t=void 0!==r.val?r.val:r;return e&&"string"==typeof t?a.camelCaseToText(t):t})()])))}get priv(){return this.getConfig(!1)}get pub(){return this.getConfig(!0)}getWithin(e,t="val"){return void 0!==e[t]?e[t]:e}getProp(e){return this.config[e]?this.config[e].val:this.config[e]}}class s{constructor(...e){const t=e[0];for(let r=1;r<e.length;r++)e[r]=t.createGraphics(t.width,t.height);e.push(t.createGraphics(t.width,t.height)),this.layers=e,this.main=e[e.length-1]}pgsFn(e,t){for(let r of this.layers)r[e](...t)}get p(){return this.layers[0]}}class l{memo={};loading=!1;postInited=!1;get p(){return this.layers.p}get mainLayer(){return this.layers.main}constructor(e,t,r,o,i,a=1,n=1080){this.addCSSStyles(),this.layers=new s(...e);const l=Object.fromEntries(new URLSearchParams(window.location.search).entries());this.scaleFactor=l.scaleFactor?Number(l.scaleFactor):a,this.initScaleFactor=this.scaleFactor,this.env=t,this.collection=o??"",this.baseDim=n,this.configInit=i,this.init(r),this.p.windowResized=()=>{this.canvasCssDim()},this.p.keyPressed=()=>{switch(this.p.keyCode){case 85:case 74:{const e=this.scaleFactor;if(85===this.p.keyCode?this.scaleFactor+=.25:74===this.p.keyCode&&(this.scaleFactor-=.25),this.scaleFactor=Math.max(this.scaleFactor,.75),e===this.scaleFactor)return;this.reset(),this.canvasCssDim(),console.log("SCALE_FACTOR:",this.scaleFactor),console.log(`width: ${this.dim}px`,`height: ${this.dim}px`);break}case 83:this.loading||this.saveOutput()}}}reset(){this.init(this.CONFIG.getProp("artName"),!1),this.p.redraw()}init(e=tokenData.hash,t=!0){tokenData.hash=e,this.drawer=void 0,this.setRandShader(),this.dim=this.baseDim*this.scaleFactor,this.p.drawingContext?(this.layers.pgsFn("resizeCanvas",[this.dim,this.dim,!0]),this.memo.combineTex&&this.memo.combineTex.resizeCanvas(this.dim,this.dim)):this.p.createCanvas(this.dim,this.dim),this.layers.pgsFn("pixelDensity",[1]),this.canvasCssDim(),!t&&this.CONFIG||(this.CONFIG=new n(this.env),this.CONFIG.addPrivProp("artName",e),this.CONFIG.addPrivProp("tokenData",tokenData),this.resetSeed(),this.configInit(this),this.print()),this.resetSeed(),document.title=`${this.collection}: ${this.CONFIG.getProp("artName")}`,this.start=Date.now(),this.loading=!1}timeElapsed(){return(Date.now()-this.start)/1e3}printTimeElapse(){console.log("generated in:",this.timeElapsed())}resetSeed(){i(),this.layers.pgsFn("noiseSeed",[this.getSeed()]),this.layers.pgsFn("randomSeed",[this.getSeed()])}weightedRandom(e,t){const r=this.p.random(),o=[...t].map(((e,t)=>[e,t]));let i=0;o.sort(((e,t)=>e[0]-t[0]));const n=a.cumSum(o.map((e=>e[0])));for(let t of n){if(r<t)return e[o[i][1]];i++}return e[o[o.length-1][1]]}luma=e=>{this.p.colorMode(this.p.RGB);const t=this.p.createVector(this.p.red(e)/255,this.p.green(e)/255,this.p.blue(e)/255);return p5.Vector.dot(t,this.p.createVector(.299,.587,.114))};createPostProcTexGL(){void 0===this.memo.combineTex&&(this.memo.combineTex=this.p.createGraphics(this.p.width,this.p.height,this.p.WEBGL))}getShaderSeed(){return 500*(this.getSeed()/Math.pow(10,String(this.getSeed()).length))}setRandShader(){this.memo.randTex&&(this.memo.randTex.shader(this.memo.randShader),this.memo.randShader.setUniform("seed",this.getShaderSeed()),this.memo.randTex.rect(0,0,this.memo.randTex.width,this.memo.randTex.height))}endFrame(){this.postInited=!1,this.memo.combineTex?this.p.image(this.memo.combineTex,0,0,this.p.width,this.p.height):this.p.image(this.mainLayer,0,0,this.p.width,this.p.height)}initPost(){this.createPostProcTexGL(),this.createPostProcShaderGL(),this.postInited||(this.postInited=!0,this.drawPost("","outColor = vec4(vec3(tex.rgb), 1.);",(()=>({})),"copy",this.mainLayer))}drawGrainGL(e=.5){this.initPost();const t=this.memo.combineTex;if(void 0===this.memo.randTex){const e=Math.pow(2,11);this.memo.randTex=this.p.createGraphics(e,e,this.p.WEBGL);const r=`#version 300 es\nprecision highp float;uniform float seed;in vec2 vTexCoord;out vec4 outColor;${d}void main() {vec2 uv = vTexCoord;float randVal = rand(seed + uv * rand(uv));outColor = vec4(vec3(randVal), 1.0 );}`;this.memo.randShader=this.memo.randTex.createShader(c,r),this.memo.combineRandShader=t.createShader(c,"#version 300 es\nprecision highp float;in vec2 vTexCoord;out vec4 outColor;uniform sampler2D randTex;uniform sampler2D tex0;uniform float scaleFactor;uniform float grainIntensity;void main() {vec2 uv = vTexCoord;uv.y = 1.0 - uv.y;float randVal = texture(randTex, uv).r;vec4 tex = texture(tex0, uv);outColor = vec4(tex.rgb + vec3((randVal * 2. - 1.) * grainIntensity), 1.0 );}"),this.setRandShader()}const r=this.memo.randTex,o=this.memo.combineRandShader;t.shader(o),o.setUniform("tex0",t),o.setUniform("scaleFactor",this.scaleFactor/this.initScaleFactor),o.setUniform("randTex",r),o.setUniform("grainIntensity",e),t.rect(0,0,t.width,t.height)}createPostProcShaderGL(){this.memo.postShader||(this.memo.postShader={})}drawPost(e="",t="",r,o="def",i,a=!0,n=!0){this.initPost();const s=this.memo.combineTex;void 0===this.memo.postShader[o]&&(this.memo.postShader[o]={},this.memo.postShader[o].shader=s.createShader(c,`#version 300 es\nprecision highp float;precision lowp usampler2D;float PI = 3.
# Seedlings "A young plant, especially one raised from a seed." Each Seedling grows delicately on a windowsill gazing outside. A Seedling's natural environment–whether a grassy prairie, a rocky mountain, or by a river–is but a memory now, leaving a faded imprint on the canvas' outer border. Some Seedlings resemble trees and flowers, others may appear to be geometric abstractions and fractals–yet all feature interplay between filled patterned regions (leaves and petals) and lines of solid color (stems and branches). Other abstractions also make an appearance: circles representing fruits, stars, or the sun and moon; and a gradient sky with foggy clouds beyond the frames of the window. ## Foundation The idea for Seedlings was sown in 2019 and was my first foray into Generative Art. It began as a study of fractal trees where each depth level was individually parametrized (angle of rotation, length, etc.). Initially just a hobbyist project in the pre-Art Blocks era, I returned to Seedlings in 2022 with the intention of making it into the longform series, I believe, that most effectively highlights the underlying algorithm's potential. So, I rewrote Seedlings from scratch, turning its simple monochromatic line renderer into a WebGL shader renderer capable of transforming Bézier curves into abstract stems, branches, leaves, and petals with diverse and colorful palettes. ## Inspiration Over the course of its development, Seedlings collected many stylistic influences, including Hokusai's trees, Charles Demuth's crisscrossing polygonal regions, and Alphonse Mucha's curves. As such, you will find elements of Ukiyo-e and Art Nouveau across the collection. Seedlings also contains stylistic elements found in my other work, such as ink-like outlining and the concept of shape overlap. Additionally, I drew inspiration from contemporary longform Generative Art that aims to create complex emergent behaviors from the interactions of a small set of primitives. The structural patterns that form each Seedling are created purely from the probabilistic placement of their branches and petals. ## Dedication Seedlings has been a labor of love and has particular sentimental value to me as the inception of my Generative Art practice. It feels fitting and very exciting to be given the opportunity to release Seedlings on Art Blocks, the original longform Generative Art platform. Thank you to everyone who helped and supported me during this journey.