let particles=[];let numParticles;let noiseScale;let gridAngleStep;let time=0;let strokeWeightMode;let maxTrailLengthMode;let selectedPalette;let bgColor;let timeIncrementMode;let globalTimeIncrement;let speedRangeMode;let MASTER_SEED;let seedRandom;let shaderGraphics;let particleGraphics;let selectedShader;let shaderProgram;let kaleidoscopeShader;let kaleidoscopeEnabled=false;let kaleidoscopeMode=0;let kaleidotileShader;let kaleidotileEnabled=false;let kaleidotileMode=0;let breathMultiplier;const CANVAS_SIZE=1000;const palettes=[{name:'Cyberpunk',colors:['#00ff41','#ff0084','#ffff00','#00ffff','#ff00ff']},{name:'Sunset',colors:['#ff6b6b','#f9ca24','#f0932b','#eb4d4b','#6ab04c']},{name:'Ocean',colors:['#00b8d4','#0091ea','#00bfa5','#1de9b6','#64ffda']},{name:'Forest',colors:['#2ecc71','#27ae60','#16a085','#1abc9c','#3498db']},{name:'Monochrome Blue',colors:['#0d47a1','#1565c0','#1976d2','#1e88e5','#2196f3']},{name:'Fire',colors:['#b71c1c','#d32f2f','#f44336','#ff5722','#ff9800']},{name:'Neon',colors:['#ff0080','#00ff00','#ffff00','#00ffff','#ff00ff']},{name:'Electric Burst 1',colors:['#ff00ff','#ff9900','#33cc33','#00ccff','#ff0066']},{name:'Electric Burst 2',colors:['#ff0055','#ffcc00','#00ffcc','#3300ff','#ff00ff']},{name:'Electric Burst 3',colors:['#ffcc00','#ff3399','#33ff66','#3399ff','#ff3300']},{name:'Electric Burst 4',colors:['#00ffcc','#ff33cc','#33ff00','#ff0033','#cc00ff']},{name:'Electric Burst 5',colors:['#ff0066','#ffcc33','#00ccff','#ff3366','#66ff33']},{name:'Electric Burst 6',colors:['#ff0033','#66ff00','#ff0099','#00ff66','#ff33cc']},{name:'Electric Burst 7',colors:['#33ccff','#ff6633','#33ff99','#cc00ff','#ff0033']},{name:'Dark Contrast',colors:['#000000','#1a1a1a','#333333','#4d4d4d','#ffffff']},{name:'Light Contrast',colors:['#ffffff','#f5f5f5','#e0e0e0','#cccccc','#000000']},{name:'Pure Monochrome',colors:['#000000','#000000','#ffffff','#ffffff','#000000']},{name:'All Black',colors:['#000000','#0a0a0a','#141414','#1f1f1f','#050505']},{name:'All White',colors:['#ffffff','#fafafa','#f5f5f5','#f0f0f0','#fcfcfc']},{name:'Monochrome Purple',colors:['#1a0033','#330066','#4d0099','#6600cc','#9933ff']},{name:'Monochrome Red',colors:['#330000','#660000','#990000','#cc0000','#ff0000']},{name:'Monochrome Green',colors:['#001a00','#003300','#004d00','#006600','#00cc00']},{name:'Monochrome Grey',colors:['#404040','#595959','#737373','#8c8c8c','#a6a6a6']}];const shaders={kaleidoscope:{name:'Kaleidoscope',vert:`attribute vec3 aPosition;attribute vec2 aTexCoord;varying vec2 vTexCoord;void main(){vTexCoord=aTexCoord;vec4 positionVec4=vec4(aPosition,1.0);positionVec4.xy=positionVec4.xy*2.0-1.0;gl_Position=positionVec4;}`,frag:`precision mediump float;varying vec2 vTexCoord;uniform sampler2D tex0;uniform float time;uniform float mode;void main(){vec2 center=vec2(0.5,0.5);vec2 pos=vTexCoord-center;float angle=atan(pos.y,pos.x);float radius=length(pos);float segments;float rotationOffset=0.0;if(mode<0.5){segments=3.0;rotationOffset=3.14159/2.0;}else if(mode<1.5){segments=6.0;}else{segments=9.0;}angle+=rotationOffset;angle=mod(angle,2.0*3.14159/segments);angle=abs(angle-3.14159/segments);angle-=rotationOffset;vec2 newPos;newPos.x=radius*cos(angle);newPos.y=radius*sin(angle);vec2 texCoord=newPos+center;texCoord=clamp(texCoord,0.0,1.0);gl_FragColor=texture2D(tex0,texCoord);}`},kaleidotile:{name:'Kaleidotile',vert:`attribute vec3 aPosition;attribute vec2 aTexCoord;varying vec2 vTexCoord;void main(){vTexCoord=aTexCoord;vec4 positionVec4=vec4(aPosition,1.0);positionVec4.xy=positionVec4.xy*2.0-1.0;gl_Position=positionVec4;}`,frag:`precision mediump float;varying vec2 vTexCoord;uniform sampler2D tex0;uniform float time;uniform float mode;void main(){vec2 uv=vTexCoord;float tileSize;if(mode<0.5){tileSize=2.0;}else if(mode<1.5){tileSize=4.0;}else{tileSize=8.0;}vec2 tileCoord=uv*tileSize;vec2 tileIndex=floor(tileCoord);vec2 tileUV=fract(tileCoord);if(mod(tileIndex.x,2.0)==1.0){tileUV.x=1.0-tileUV.x;}if(mod(tileIndex.y,2.0)==1.0){tileUV.y=1.0-tileUV.y;}vec2 sampleUV=tileUV/tileSize;gl_FragColor=texture2D(tex0,sampleUV);}`},none:{name:'None',vert:`attribute vec3 aPosition;attribute vec2 aTexCoord;varying vec2 vTexCoord;void main(){vTexCoord=aTexCoord;vec4 positionVec4=vec4(aPosition,1.0);positionVec4.xy=positionVec4.xy*2.0-1.0;gl_Position=positionVec4;}`,frag:`precision mediump float;varying vec2 vTexCoord;uniform sampler2D tex0;void main(){gl_FragColor=texture2D(tex0,vTexCoord);}`},luminance:{name:'Luminance',vert:`attribute vec3 aPosition;attribute vec2 aTexCoord;varying vec2 vTexCoord;void main(){vTexCoord=aTexCoord;vec4 positionVec4=vec4(aPosition,1.0);positionVec4.xy=positionVec4.xy*2.0-1.0;gl_Position=positionVec4;}`,frag:`precision mediump float;varying vec2 vTexCoord;uniform sampler2D tex0;uniform float time;void main(){vec4 color=texture2D(tex0,vTexCoord);float brightness=dot(color.rgb,vec3(0.299,0.587,0.114));if(brightness>0.1){float glow=sin(time*3.0)*0.2+0.8;color.rgb*=(1.0+glow*brightness);vec2 texelSize=1.0/vec2(1000.0,1000.0);vec4 bloom=vec4(0.0);for(int i=-2;i<=2;i++){for(int j=-2;j<=2;j++){vec2 offset=vec2(float(i),float(j))*texelSize*2.0;bloom+=texture2D(tex0,vTexCoord+offset);}}bloom/=25.0;color.rgb+=bloom.rgb*brightness*0.5;}gl_FragColor=color;}`},pixelate:{name:'Pixelate',vert:`attribute vec3 aPosition;attribute vec2 aTexCoord;varying vec2 vTexCoord;void main(){vTexCoord=aTexCoord;vec4 positionVec4=vec4(aPosition,1.0);positionVec4.xy=positionVec4.xy*2.0-1.0;gl_Position=positionVec4;}`,frag:`precision mediump float;varying vec2 vTexCoord;uniform sampler2D tex0;uniform vec2 resolution;void main(){float pixelSize=8.0;vec2 coord=floor(vTexCoord*resolution/pixelSize)*pixelSize/resolution;gl_FragColor=texture2D(tex0,coord);}`},chromatic:{name:'Chromatic Aberration',vert:`attribute vec3 aPosition;attribute vec2 aTexCoord;varying vec2 vTexCoord;void main(){vTexCoord=aTexCoord;vec4 positionVec4=vec4(aPosition,1.0);positionVec4.xy=positionVec4.xy*2.0-1.0;gl_Position=positionVec4;}`,frag:`precision mediump float;varying vec2 vTexCoord;uniform sampler2D tex0;uniform float time;void main(){vec2 center=vec2(0.5,0.5);vec2 offset=(vTexCoord-center)*0.01;float r=texture2D(tex0,vTexCoord-offset).r;float g=texture2D(tex0,vTexCoord).g;float b=texture2D(tex0,vTexCoord+offset).b;float a=texture2D(tex0,vTexCoord).a;gl_FragColor=vec4(r,g,b,a);}`},vhs:{name:'VHS',vert:`attribute vec3 aPosition;attribute vec2 aTexCoord;varying vec2 vTexCoord;void main(){vTexCoord=aTexCoord;vec4 positionVec4=vec4(aPosition,1.0);positionVec4.xy=positionVec4.xy*2.0-1.0;gl_Position=positionVec4;}`,frag:`precision mediump float;varying vec2 vTexCoord;uniform sampler2D tex0;uniform float time;float noise(vec2 p){return fract(sin(dot(p,vec2(12.9898,78.233)))*43758.5453);}void main(){vec2 uv=vTexCoord;float scanline=sin(uv.y*800.0)*0.09;uv.x+=sin(uv.y*10.0+time*2.0)*0.002;vec4 color=texture2D(tex0,uv);color.r=texture2D(tex0,uv+vec2(0.002,0.0)).r;color.b=texture2D(tex0,uv-vec2(0.002,0.0)).b;color.rgb+=noise(uv*time)*0.05;color.rgb-=scanline;gl_FragColor=color;}`},thermal:{name:'Thermal Vision',vert:`attribute vec3 aPosition;attribute vec2 aTexCoord;varying vec2 vTexCoord;void main(){vTexCoord=aTexCoord;vec4 positionVec4=vec4(aPosition,1.0);positionVec4.xy=positionVec4.xy*2.0-1.0;gl_Position=positionVec4;}`,frag:`precision mediump float;varying vec2 vTexCoord;uniform sampler2D tex0;void main(){vec4 color=texture2D(tex0,vTexCoord);float brightness=dot(color.rgb,vec3(0.299,0.587,0.114));vec3 thermal;if(brightness<0.25){thermal=mix(vec3(0.0,0.0,0.0),vec3(0.0,0.0,1.0),brightness*4.0);}else if(brightness<0.5){thermal=mix(vec3(0.0,0.0,1.0),vec3(0.0,1.0,0.0),(brightness-0.25)*4.0);}else if(brightness<0.75){thermal=mix(vec3(0.0,1.0,0.0),vec3(1.0,1.0,0.0),(brightness-0.5)*4.0);}else{thermal=mix(vec3(1.0,1.0,0.0),vec3(1.0,0.0,0.0),(brightness-0.75)*4.0);}gl_FragColor=vec4(thermal,color.a);}`},edge:{name:'Edge Detection',vert:`attribute vec3 aPosition;attribute vec2 aTexCoord;varying vec2 vTexCoord;void main(){vTexCoord=aTexCoord;vec4 positionVec4=vec4(aPosition,1.0);positionVec4.xy=positionVec4.xy*2.0-1.0;gl_Position=positionVec4;}`,frag:`precision mediump float;varying vec2 vTexCoord;uniform sampler2D tex0;uniform vec2 resolution;void main(){vec2 texelSize=1.0/resolution;vec4 tl=texture2D(tex0,vTexCoord+vec2(-texelSize.x,-texelSize.y));vec4 tm=texture2D(tex0,vTexCoord+vec2(0.0,-texelSize.y));vec4 tr=texture2D(tex0,vTexCoord+vec2(texelSize.x,-texelSize.y));vec4 ml=texture2D(tex0,vTexCoord+vec2(-texelSize.x,0.0));vec4 mm=texture2D(tex0,vTexCoord);vec4 mr=texture2D(tex0,vTexCoord+vec2(texelSize.x,0.0));vec4 bl=texture2D(tex0,vTexCoord+vec2(-texelSize.x,texelSize.y));vec4 bm=texture2D(tex0,vTexCoord+vec2(0.0,texelSize.y));vec4 br=texture2D(tex0,vTexCoord+vec2(texelSize.x,texelSize.y));vec4 h=-tl-2.0*tm-tr+bl+2.0*bm+br;vec4 v=-tl-2.0*ml-bl+tr+2.0*mr+br;vec4 edge=sqrt(h*h+v*v);gl_FragColor=vec4(edge.rgb,mm.a);}`},posterize:{name:'Posterize',vert:`attribute vec3 aPosition;attribute vec2 aTexCoord;varying vec2 vTexCoord;void main(){vTexCoord=aTexCoord;vec4 positionVec4=vec4(aPosition,1.0);positionVec4.xy=positionVec4.xy*2.0-1.0;gl_Position=positionVec4;}`,frag:`precision mediump float;varying vec2 vTexCoord;uniform sampler2D tex0;void main(){vec4 color=texture2D(tex0,vTexCoord);float levels=4.0;color.rgb=floor(color.rgb*levels)/(levels-1.0);gl_FragColor=color;}`},halftone:{name:'Halftone Burst',vert:`attribute vec3 aPosition;attribute vec2 aTexCoord;varying vec2 vTexCoord;void main(){vTexCoord=aTexCoord;vec4 positionVec4=vec4(aPosition,1.0);positionVec4.xy=positionVec4.xy*2.0-1.0;gl_Position=positionVec4;}`,frag:`precision mediump float;varying vec2 vTexCoord;uniform sampler2D tex0;uniform vec2 resolution;uniform float time;vec3 hsv2rgb(vec3 c){vec4 K=vec4(1.0,2.0/3.0,1.0/3.0,3.0);vec3 p=abs(fract(c.xxx+K.xyz)*6.0-K.www);return c.z*mix(K.xxx,clamp(p-K.xxx,0.0,1.0),c.y);}void main(){vec2 dotSize=vec2(8.0);vec2 dotPos=vTexCoord*resolution/dotSize;vec2 dotCenter=floor(dotPos)+vec2(0.5);vec4 centerColor=texture2D(tex0,dotCenter*dotSize/resolution);float brightness=dot(centerColor.rgb,vec3(0.299,0.587,0.114));float dist=length(dotPos-dotCenter);float expandTime=time*2.0+brightness*10.0;float ringCount=3.0;float ringWidth=0.15;vec3 finalColor=vec3(0.0);float totalAlpha=0.0;for(float i=0.0;i0.05){speedRangeMode=seededRandomChoice(['slow','medium','fast']);}const shaderKeys=Object.keys(shaders).filter(key=>key!=='kaleidoscope'&&key!=='kaleidotile'&&key!=='spiral');let selectedShaderKey;if(seededRandom()<0.3){selectedShaderKey='none';}else{if(strokeWeightMode==='uniform-1'||strokeWeightMode==='uniform-2'){const filteredKeys=shaderKeys.filter(key=>key!=='halftone'&&key!=='pixelate'&&key!=='none');if(filteredKeys.length>0){selectedShaderKey=seededRandomChoice(filteredKeys);}else{selectedShaderKey='none';}}else{const filteredKeys=shaderKeys.filter(key=>key!=='none');if(filteredKeys.length>0){selectedShaderKey=seededRandomChoice(filteredKeys);}else{selectedShaderKey='none';}}}selectedShader=shaders[selectedShaderKey];if(!selectedShader){console.error("Shader not found:",selectedShaderKey);selectedShader=shaders['none'];}shaderProgram=shaderGraphics.createShader(selectedShader.vert,selectedShader.frag);kaleidoscopeShader=shaderGraphics.createShader(shaders.kaleidoscope.vert,shaders.kaleidoscope.frag);kaleidotileShader=shaderGraphics.createShader(shaders.kaleidotile.vert,shaders.kaleidotile.frag);if(timeIncrementMode==='uniform-slow'){globalTimeIncrement=0.001;}else if(timeIncrementMode==='uniform-medium'){globalTimeIncrement=0.005;}else if(timeIncrementMode==='uniform-fast'){globalTimeIncrement=0.01;}else{globalTimeIncrement=null;}if(selectedPalette.name==='All Black'){const cyberpunkPalette=palettes.find(p=>p.name==='Cyberpunk');bgColor=color(seededRandomChoice(cyberpunkPalette.colors));}else if(seededRandom()<0.05){bgColor=color(seededRandomChoice(selectedPalette.colors));}else{bgColor=color(0);}particleGraphics.background(bgColor);breathMultiplier=seededRandomChoice([30,200,500]);GENERATION_PARAMS={seed:MASTER_SEED,palette:selectedPalette.name,shader:selectedShader.name,noiseScale:noiseScale,numParticles:numParticles,strokeWeightMode:strokeWeightMode,gridAngleStep:gridAngleStep,maxTrailLengthMode:maxTrailLengthMode,timeIncrementMode:timeIncrementMode,speedRangeMode:speedRangeMode,backgroundIsPaletteColor:(bgColor.toString()!==color(0).toString())};console.log("🎨 GENERATION SUMMARY:");console.log("- Palette:",selectedPalette.name);console.log("- Shader:",selectedShader.name);console.log("- Noise Scale:",noiseScale);console.log("- Particle Count:",numParticles);console.log("- Stroke Weight:",strokeWeightMode);console.log("- Grid Angle Step:",gridAngleStep);console.log("- Max Trail Length:",maxTrailLengthMode);console.log("- Time Increment Mode:",timeIncrementMode);console.log("- Speed Range:",speedRangeMode);console.log("- Background is Palette Color:",GENERATION_PARAMS.backgroundIsPaletteColor);console.log("📋 REPRODUCTION STRING: ?seed="+MASTER_SEED);for(let i=0;i5){this.edges();}else{if(this.traveledDistance>=this.maxTrailLength){this.reset();}else{this.edges();}}}display(){particleGraphics.stroke(this.color);particleGraphics.strokeWeight(this.strokeW);particleGraphics.line(this.prevPosition.x,this.prevPosition.y,this.position.x,this.position.y);this.prevPosition=this.position.copy();}edges(){if(this.strokeW>5){let inLeftBuffer=this.position.x<-250;let inRightBuffer=this.position.x>CANVAS_SIZE+250;let inTopBuffer=this.position.y<-250;let inBottomBuffer=this.position.y>CANVAS_SIZE+250;if(inLeftBuffer||inRightBuffer||inTopBuffer||inBottomBuffer){this.reset();}}else{if(this.position.x>CANVAS_SIZE+250||this.position.x<-250||this.position.y>CANVAS_SIZE+250||this.position.y<-250){this.reset();}}}reset(){if(this.strokeW>5){let edge=seededRandomInt(0,4);let x,y;switch(edge){case 0:x=seededRandom(0,CANVAS_SIZE);y=seededRandom(-250,0);break;case 1:x=seededRandom(CANVAS_SIZE,CANVAS_SIZE+250);y=seededRandom(0,CANVAS_SIZE);break;case 2:x=seededRandom(0,CANVAS_SIZE);y=seededRandom(CANVAS_SIZE,CANVAS_SIZE+250);break;case 3:x=seededRandom(-250,0);y=seededRandom(0,CANVAS_SIZE);break;}this.position=createVector(x,y);}else{this.position=createVector(seededRandom(-250,CANVAS_SIZE+250),seededRandom(-250,CANVAS_SIZE+250));}this.prevPosition=this.position.copy();this.traveledDistance=0;}}function keyPressed(){console.log("Key pressed:",key);if(key==='s'||key==='S'){save('drift_'+MASTER_SEED+'_'+selectedShader.name+'.png');}else if(key==='k'||key==='K'){if(!kaleidoscopeEnabled){kaleidoscopeEnabled=true;kaleidoscopeMode=0;kaleidotileEnabled=false;console.log("🔮 Kaleidoscope: 3-fold symmetry");}else{kaleidoscopeMode++;if(kaleidoscopeMode>=3){kaleidoscopeEnabled=false;kaleidoscopeMode=0;console.log("🔮 Kaleidoscope: OFF");}else{const modeNames=["3-fold symmetry","6-fold symmetry","9-fold symmetry"];console.log("🔮 Kaleidoscope: "+modeNames[kaleidoscopeMode]);}}}else if(key==='t'||key==='T'){if(!kaleidotileEnabled){kaleidotileEnabled=true;kaleidotileMode=0;kaleidoscopeEnabled=false;console.log("🔷 Kaleidotile: Mode 0 (2x2 tiles)");}else{kaleidotileMode++;if(kaleidotileMode>=3){kaleidotileEnabled=false;kaleidotileMode=0;console.log("🔷 Kaleidotile: OFF");}else{console.log("🔷 Kaleidotile: Mode "+kaleidotileMode+" ("+(kaleidotileMode===1?"4x4 tiles":"8x8 tiles")+")");}}}}