0xb81bf680…7cf2·#25,052,493·view on Etherscan
W_R`@_ U_R`@_ U_R`@_ U`Wa
faCfV[a
naEPV[c8Wa!-aCfV[a!5aEPV[`ABCDEFGHIJKLMNOPQRSTUVWXYZabcdef`ghijklmnopqrstuvwxyz0123456789-_MELANCHOLIA is a library of dyna` mic text-image compositions stor`@ed and generated entirely on the`` blockchain. Each composition re`appropriates an historical print` from a master of its era and tr`W_R`@_ U_R`@_ U_R`a9EV[PPPPPPPPPa9[V[PUa9[V[PPPPPPPa9[V[PUa9[V[PPPPPa9[V[PPWa>őaE4V[a>TV[`a>#V[PPPPPPPa>8V[PPPPPPUa>8V[PPPPPa>8V[PPPPUa>8V[PPPPa>8V[PUPa>8V[PhaD*V[a=<V[`@Qcf\{\u00000123456789abcdefbtno0123456789abcdef` <!doctype html><meta charset=utf-8><style>
html,body{margin:0;height:100%}body{background:#000;color:#fff;overflow:hidden;display:flex;align-items:center;justify-content:center}
pre{margin:0;font-family:ui-monospace,monospace;letter-spacing:-0.175em;font-feature-settings:"liga" 0;text-shadow:0 0 .5px #fff,0 0 .5px #fff;-webkit-text-stroke:.5px #fff}
</style><pre id=o></pre><script>
// Params: window.P (contract-injected) or URL query (testing).
(()=>{
const q=new URLSearchParams(location.search),g=k=>window.P&&k in window.P?window.P[k]:q.get(k);
const n=(k,d)=>{const v=g(k);return v==null||isNaN(+v)?d:+v};
const P={src:g('src')||'https://upload.wikimedia.org/wikipedia/commons/thumb/d/d7/Albrecht_D%C3%9CRer_-_Melencolia_I_-_Google_Art_Project.jpg/1920px-Albrecht_D%C3%9CRer_-_Melencolia_I_-_Google_Art_Project.jpg',scale:n('scale',0.15),contrast:n('contrast',0.255),brightness:n('brightness',0.4),gamma:n('gamma',0.93),threshold:n('threshold',109),blur:n('blur',0.5),sharpen:n('sharpen',0.53),downscale:n('downscale',0.91),font:n('font',5),cropL:n('cropL',0),cropR:n('cropR',0),cropT:n('cropT',0),cropB:n('cropB',0),invert:g('invert')==='true'||g('invert')===true};
const D=[[1,2,4,64],[8,16,32,128]],O=document.getElementById('o');
O.style.fontSize=P.font+'px';O.style.lineHeight=Math.max(1,Math.round(P.font*0.95))+'px';
// Deterministic pipeline: createImageBitmap with colorSpaceConversion:'none'
// (no Safari ICC color management on JPEG decode), JS box resample (no
// browser-specific imageSmoothingQuality kernel), JS gaussian blur (no
// ctx.filter quirks). Identical bytes in Chrome and Safari.
function bx(s,sw,sh,tw,th){if(tw===sw&&th===sh)return s;const o=new Float32Array(tw*th*3),sx=sw/tw,sy=sh/th;for(let y=0;y<th;y++){const y0=y*sy,y1=(y+1)*sy,iy0=Math.floor(y0),iy1=Math.min(sh,Math.ceil(y1));for(let x=0;x<tw;x++){const x0=x*sx,x1=(x+1)*sx,ix0=Math.floor(x0),ix1=Math.min(sw,Math.ceil(x1));let r=0,g=0,b=0,w=0;for(let yy=iy0;yy<iy1;yy++){const fy=Math.min(y1,yy+1)-Math.max(y0,yy);for(let xx=ix0;xx<ix1;xx++){const fx=Math.min(x1,xx+1)-Math.max(x0,xx),ww=fy*fx,i=(yy*sw+xx)*3;r+=s[i]*ww;g+=s[i+1]*ww;b+=s[i+2]*ww;w+=ww}}const j=(y*tw+x)*3;o[j]=r/w;o[j+1]=g/w;o[j+2]=b/w}}return o}
function gb(b,w,h,sg){if(sg<=0)return;const r=Math.max(1,Math.ceil(sg*3)),k=new Float32Array(r*2+1),s2=2*sg*sg;let ks=0;for(let i=-r;i<=r;i++){const v=Math.exp(-(i*i)/s2);k[i+r]=v;ks+=v}for(let i=0;i<k.length;i++)k[i]/=ks;const t=new Float32Array(b.length);for(let y=0;y<h;y++)for(let x=0;x<w;x++){let v=0;for(let i=-r;i<=r;i++){const xx=x+i<0?0:x+i>=w?w-1:x+i;v+=b[y*w+xx]*k[i+r]}t[y*w+x]=v}for(let y=0;y<h;y++)for(let x=0;x<w;x++){let v=0;for(let i=-r;i<=r;i++){const yy=y+i<0?0:y+i>=h?h-1:y+i;v+=t[yy*w+x]*k[i+r]}b[y*w+x]=v}}
(async()=>{
let bm;try{const rs=await fetch(P.src,{mode:'cors'});if(!rs.ok)throw 0;bm=await createImageBitmap(await rs.blob(),{colorSpaceConversion:'none'})}catch(e){O.textContent='[the source image seems to be unavailable, replace it with another]';return}
let sw=bm.width,sh=bm.height;
const c=document.createElement('canvas');c.width=sw;c.height=sh;const cx=c.getContext('2d',{willReadFrequently:true,colorSpace:'srgb'});cx.drawImage(bm,0,0);const id=cx.getImageData(0,0,sw,sh).data;
let rgb=new Float32Array(sw*sh*3);for(let i=0,j=0;j<id.length;i+=3,j+=4){rgb[i]=id[j];rgb[i+1]=id[j+1];rgb[i+2]=id[j+2]}
if(P.cropL>0||P.cropR>0||P.cropT>0||P.cropB>0){const x0=Math.round(sw*P.cropL),y0=Math.round(sh*P.cropT),w=Math.max(1,Math.round(sw*(1-P.cropL-P.cropR))),h=Math.max(1,Math.round(sh*(1-P.cropT-P.cropB))),cc=new Float32Array(w*h*3);for(let y=0;y<h;y++)for(let x=0;x<w;x++){const si=((y0+y)*sw+(x0+x))*3,di=(y*w+x)*3;cc[di]=rgb[si];cc[di+1]=rgb[si+1];cc[di+2]=rgb[si+2]}rgb=cc;sw=w;sh=h}
let pw=sw,ph=sh;
if(P.downscale<1){const r=sw/sh,t=Math.round(Math.max(sw,sh)*P.downscale),dw=r>=1?t:Math.round(t*r),dh=r>=1?Math.round(t/r):t;rgb=bx(rgb,pw,ph,dw,dh);pw=dw;ph=dh}
const cw=Math.max(1,Math.round(sw*P.scale)),ch=Math.max(1,Math.round(sh*P.scale/2)),W=cw*2,H=ch*4;
const sm=bx(rgb,pw,ph,W,H);
const b=new Float32Array(W*H);for(let i=0,j=0;i<b.length;i++,j+=3)b[i]=0.299*sm[j]+0.587*sm[j+1]+0.114*sm[j+2];
gb(b,W,H,P.blur);
const cf=(1+P.contrast)/Math.max(1e-6,1-P.contrast);
for(let i=0;i<b.length;i++){let v=b[i]/255;v=Math.pow(Math.max(0,v),1/P.gamma);v=(v-0.5)*cf+0.5+P.brightness;if(P.invert)v=1-v;b[i]=Math.max(0,Math.min(1,v))*255}
if(P.sharpen>0){const k=P.sharpen,s2=new Float32Array(b);for(let y=1;y<H-1;y++)for(let x=1;x<W-1;x++){const i=y*W+x,v=s2[i]*(1+4*k)-k*(s2[i-1]+s2[i+1]+s2[i-W]+s2[i+W]);b[i]=Math.max(0,Math.min(255,v))}}
const t=128+P.threshold,bn=new Uint8Array(W*H);
for(let y=0;y<H;y++)for(let x=0;x<W;x++){const i=y*W+x,o=b[i],n=o<t?0:255;bn[i]=n?1:0;const e=(o-n)/8,f=(dx,dy)=>{const nx=x+dx,ny=y+dy;if(nx>=0&&nx<W&&ny>=0&&ny<H)b[ny*W+nx]+=e};f(1,0);f(2,0);f(-1,1);f(0,1);f(1,1);f(0,2)}
let s='';for(let cy=0;cy<ch;cy++){for(let cx=0;cx<cw;cx++){let c=0;for(let dx=0;dx<2;dx++)for(let dy=0;dy<4;dy++)if(!bn[(cy*4+dy)*W+cx*2+dx])c|=D[dx][dy];s+=String.fromCharCode(0x2800+c)}if(cy<ch-1)s+='\n'}
O.textContent=s;fit();
})();
function fit(){O.style.transform='';const r=O.getBoundingClientRect();if(!r.width||!r.height)return;const lh=parseInt(O.style.lineHeight)||1,w=Math.min(innerWidth/r.width,innerHeight/r.height,1),sn=Math.floor(lh*w),sc=sn>=1?sn/lh:w;if(sc<1)O.style.transform='scale('+sc+')'}
addEventListener('resize',fit);
})();
</script>