create-textmode 1.0.6 → 1.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +661 -21
- package/README.md +120 -86
- package/bin/index.js +8 -8
- package/package.json +70 -54
- package/src/args.js +57 -30
- package/src/banner.js +57 -57
- package/src/cli.js +166 -154
- package/src/constants.js +59 -23
- package/src/fs-utils.js +136 -85
- package/src/packageManager.js +18 -18
- package/src/prompts.js +102 -90
- package/src/runCommand.js +46 -46
- package/src/summary.js +43 -33
- package/src/textmodeVersion.js +57 -45
- package/src/usage.js +21 -18
- package/src/versions.js +56 -52
- package/templates/vanilla-js/.prettierrc +8 -8
- package/templates/vanilla-js/_gitignore +2 -2
- package/templates/vanilla-js/eslint.config.js +22 -22
- package/templates/vanilla-js/index.html +25 -25
- package/templates/vanilla-js/package.json +26 -26
- package/templates/vanilla-js/src/sketch.js +28 -28
- package/templates/vanilla-js/vite.config.js +7 -7
- package/templates/vanilla-js-tweakpane/_gitignore +2 -2
- package/templates/vanilla-js-tweakpane/eslint.config.js +22 -22
- package/templates/vanilla-js-tweakpane/index.html +37 -37
- package/templates/vanilla-js-tweakpane/package.json +27 -27
- package/templates/vanilla-js-tweakpane/src/sketch.js +62 -62
- package/templates/vanilla-js-tweakpane/vite.config.js +7 -7
- package/templates/vanilla-ts/.prettierrc +8 -8
- package/templates/vanilla-ts/_gitignore +1 -1
- package/templates/vanilla-ts/eslint.config.js +23 -23
- package/templates/vanilla-ts/index.html +26 -26
- package/templates/vanilla-ts/package.json +30 -30
- package/templates/vanilla-ts/src/sketch.ts +28 -28
- package/templates/vanilla-ts/tsconfig.json +15 -15
- package/templates/vanilla-ts/vite.config.ts +7 -7
- package/templates/vanilla-ts-tweakpane/_gitignore +2 -2
- package/templates/vanilla-ts-tweakpane/eslint.config.js +23 -23
- package/templates/vanilla-ts-tweakpane/index.html +37 -37
- package/templates/vanilla-ts-tweakpane/package.json +32 -32
- package/templates/vanilla-ts-tweakpane/src/sketch.ts +72 -72
- package/templates/vanilla-ts-tweakpane/tsconfig.json +15 -15
- package/templates/vanilla-ts-tweakpane/vite.config.ts +7 -7
- package/templates/vanilla-js-fxhash/_gitignore +0 -2
- package/templates/vanilla-js-fxhash/eslint.config.js +0 -22
- package/templates/vanilla-js-fxhash/index.html +0 -27
- package/templates/vanilla-js-fxhash/package.json +0 -26
- package/templates/vanilla-js-fxhash/public/fxhash.min.js +0 -1
- package/templates/vanilla-js-fxhash/src/sketch.js +0 -101
- package/templates/vanilla-js-fxhash/vite.config.js +0 -7
- package/templates/vanilla-ts-fxhash/_gitignore +0 -2
- package/templates/vanilla-ts-fxhash/eslint.config.js +0 -23
- package/templates/vanilla-ts-fxhash/index.html +0 -27
- package/templates/vanilla-ts-fxhash/package.json +0 -30
- package/templates/vanilla-ts-fxhash/public/fxhash.min.js +0 -1
- package/templates/vanilla-ts-fxhash/src/fxhash.d.ts +0 -54
- package/templates/vanilla-ts-fxhash/src/sketch.ts +0 -108
- package/templates/vanilla-ts-fxhash/tsconfig.json +0 -15
- package/templates/vanilla-ts-fxhash/vite.config.ts +0 -7
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "{{name}}",
|
|
3
|
-
"version": "0.0.0",
|
|
4
|
-
"private": true,
|
|
5
|
-
"type": "module",
|
|
6
|
-
"scripts": {
|
|
7
|
-
"dev": "vite",
|
|
8
|
-
"build": "vite build",
|
|
9
|
-
"preview": "vite preview",
|
|
10
|
-
"format": "prettier --write \"src/**/*.{js,ts}\"",
|
|
11
|
-
"format:check": "prettier --check \"src/**/*.{js,ts}\"",
|
|
12
|
-
"lint": "eslint src --ext .js",
|
|
13
|
-
"lint:fix": "eslint src --ext .js --fix"
|
|
14
|
-
},
|
|
15
|
-
"dependencies": {
|
|
16
|
-
"textmode.js": "latest"
|
|
17
|
-
},
|
|
18
|
-
"devDependencies": {
|
|
19
|
-
"@eslint/js": "^9.39.1",
|
|
20
|
-
"eslint": "^9.39.1",
|
|
21
|
-
"eslint-config-prettier": "^10.1.8",
|
|
22
|
-
"globals": "^15.14.0",
|
|
23
|
-
"prettier": "^3.7.4",
|
|
24
|
-
"vite": "^7.2.7"
|
|
25
|
-
}
|
|
26
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";(()=>{var p="123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";function A(){return`tz1${Array.from({length:33},()=>p[Math.random()*p.length|0]).join("")}`}function b(t){if(t.length!==36||!/^(tz|KT)[1-4]/.test(t))return!1;for(let r=0;r<t.length;r++)if(!p.includes(t[r]))return!1;return!0}function T(t){return/^(0x)?[0-9a-fA-F]{40}$/.test(t)}function v(){return`oo${Array.from({length:49},()=>p[Math.random()*p.length|0]).join("")}`}function P(t){return/^(0x)?([A-Fa-f0-9]{64})$/.test(t)}function j(t){return[...t].reduce(function(r,e){return r*p.length+p.indexOf(e)|0},0)}function U([t,r,e,n]){return function(){t|=0,r|=0,e|=0,n|=0;let s=(t+r|0)+n|0;return n=n+1|0,t=r^r>>>9,r=e+(e<<3)|0,e=e<<21|e>>>11,e=e+s|0,(s>>>0)/4294967296}}function I(t,r,e=j){return t.slice(r).match(new RegExp(".{"+(t.length-r>>2)+"}","g")).map(e)}function C(t){return P(t)||T(t)?I(t,2,r=>Number(BigInt(`0x${r}`)%BigInt(4294967295))):b(t)?I(t,3):I(t,2)}function l(t){let r=C(t);return U(r)}function H(t){let r=t.replace("#","");return r.length===6&&(r=`${r}ff`),r.length===3&&(r=`${r[0]}${r[0]}${r[1]}${r[1]}${r[2]}${r[2]}ff`),r}var w=function(t){let r="";for(let e=0;e<t.length;e++)r+=t.charCodeAt(e).toString(16).padStart(4,"0");return r},O=function(t){let r=t.match(/.{1,4}/g)||[],e="";for(let n=0;n<r.length;n++){let s=parseInt(r[n],16);if(s===0)break;e+=String.fromCharCode(s)}return e},k=BigInt("-9223372036854775808"),R=BigInt("9223372036854775807"),h={number:{serialize:t=>{let r=new DataView(new ArrayBuffer(8));return r.setFloat64(0,t),r.getBigUint64(0).toString(16).padStart(16,"0")},deserialize:t=>{let r=new DataView(new ArrayBuffer(8));for(let e=0;e<8;e++)r.setUint8(e,parseInt(t.substring(e*2,e*2+2),16));return r.getFloat64(0)},bytesLength:()=>8,constrain:(t,r)=>{let e=Number.MIN_SAFE_INTEGER;typeof r.options?.min<"u"&&(e=Number(r.options.min));let n=Number.MAX_SAFE_INTEGER;typeof r.options?.max<"u"&&(n=Number(r.options.max)),n=Math.min(n,Number.MAX_SAFE_INTEGER),e=Math.max(e,Number.MIN_SAFE_INTEGER);let s=Math.min(Math.max(t,e),n);if(r?.options?.step){let a=1/r?.options?.step;return Math.round(s*a)/a}return s},random:t=>{let r=Number.MIN_SAFE_INTEGER;typeof t.options?.min<"u"&&(r=Number(t.options.min));let e=Number.MAX_SAFE_INTEGER;typeof t.options?.max<"u"&&(e=Number(t.options.max)),e=Math.min(e,Number.MAX_SAFE_INTEGER),r=Math.max(r,Number.MIN_SAFE_INTEGER);let n=Math.random()*(e-r)+r;if(t?.options?.step){let s=1/t?.options?.step;return Math.round(n*s)/s}return n}},bigint:{serialize:t=>{let r=new DataView(new ArrayBuffer(8));return r.setBigInt64(0,BigInt(t)),r.getBigUint64(0).toString(16).padStart(16,"0")},deserialize:t=>{let r=new DataView(new ArrayBuffer(8));for(let e=0;e<8;e++)r.setUint8(e,parseInt(t.substring(e*2,e*2+2),16));return r.getBigInt64(0)},bytesLength:()=>8,random:t=>{let r=k,e=R;typeof t.options?.min<"u"&&(r=BigInt(t.options.min)),typeof t.options?.max<"u"&&(e=BigInt(t.options.max));let n=e-r,s=n.toString(2).length,a;do a=BigInt("0b"+Array.from(crypto.getRandomValues(new Uint8Array(Math.ceil(s/8)))).map(u=>u.toString(2).padStart(8,"0")).join(""));while(a>n);return a+r}},boolean:{serialize:t=>typeof t=="boolean"?t?"01":"00":typeof t=="string"&&t==="true"?"01":"00",deserialize:t=>t!=="00",bytesLength:()=>1,random:()=>Math.random()<.5},color:{serialize:t=>H(t),deserialize:t=>t,bytesLength:()=>4,transform:t=>{let r=H(t),e=parseInt(r.slice(0,2),16),n=parseInt(r.slice(2,4),16),s=parseInt(r.slice(4,6),16),a=parseInt(r.slice(6,8),16);return{hex:{rgb:"#"+t.slice(0,6),rgba:"#"+t},obj:{rgb:{r:e,g:n,b:s},rgba:{r:e,g:n,b:s,a}},arr:{rgb:[e,n,s],rgba:[e,n,s,a]}}},constrain:t=>t.replace("#","").slice(0,8).padEnd(8,"f"),random:()=>`${[...Array(8)].map(()=>Math.floor(Math.random()*16).toString(16)).join("")}`},string:{serialize:(t,r)=>{if(!r.version){let s=w(t.substring(0,64));return s=s.padEnd(64*4,"0"),s}let e=64;typeof r.options?.maxLength<"u"&&(e=Number(r.options.maxLength));let n=w(t.substring(0,e));return n=n.padEnd(e*4,"0"),n},deserialize:t=>O(t),bytesLength:t=>t.version&&typeof t.options?.maxLength<"u"?Number(t.options.maxLength)*2:64*2,random:t=>{let r=0;typeof t.options?.minLength<"u"&&(r=t.options.minLength);let e=64;typeof t.options?.maxLength<"u"&&(e=t.options.maxLength);let n=Math.round(Math.random()*(e-r)+r);return[...Array(n)].map(s=>(~~(Math.random()*36)).toString(36)).join("")},constrain:(t,r)=>{let e=0;typeof r.options?.minLength<"u"&&(e=r.options.minLength);let n=64;typeof r.options?.maxLength<"u"&&(n=r.options.maxLength);let s=t.slice(0,n);return s.length<e?s.padEnd(e):s}},bytes:{serialize:(t,r)=>Array.from(t).map(e=>e.toString(16).padStart(2,"0")).join(""),deserialize:(t,r)=>{let e=t.length/2,n=new Uint8Array(e),s;for(let a=0;a<e;a++)s=a*2,n[a]=parseInt(`${t[s]}${t[s+1]}`,16);return n},bytesLength:t=>t.options.length,random:t=>{let r=t.options?.length||0,e=new Uint8Array(r);for(let n=0;n<r;n++)e[n]=Math.random()*255|0;return e}},select:{serialize:(t,r)=>Math.min(255,r.options?.options?.indexOf(t)||0).toString(16).padStart(2,"0"),deserialize:(t,r)=>{let e=parseInt(t,16);return r.options?.options?.[e]||r.options?.options?.[0]||""},bytesLength:()=>1,constrain:(t,r)=>r.options.options.includes(t)?t:r.options.options[0],random:t=>{let r=Math.round(Math.random()*(t.options.options.length-1)+0);return t?.options?.options[r]}}};function M(t,r){let e="";if(!r)return e;for(let n of r){let{id:s,type:a}=n,u=h[a],m=t[s],g=typeof m<"u"?m:typeof n.default<"u"?n.default:u.random(n),d=u.serialize(g,n);e+=d}return e}function F(t,r,e){let n={};for(let s of r){let a=h[s.type],u=e.withTransform&&a[e.transformType||"transform"];if(!t){let x;typeof s.default>"u"?x=a.random(s):x=s.default,n[s.id]=u?u(x,s):x;continue}let m=a.bytesLength(s),g=t.substring(0,m*2);t=t.substring(m*2);let d=a.deserialize(g,s);n[s.id]=u?u(d,s):d}return n}var z=(t,r,e,n)=>{let s=e.find(m=>m.id===t),u=h[s.type][n];return u?.(r,s)||r},E=(t,r,e)=>{let n={};for(let s of r){let a=h[s.type],u=t[s.id],m=a[e];n[s.id]=m?.(u,s)||u}return n};function V(t,r){let{parent:e}=t,n=new URLSearchParams(t.location.search),s=n.get("fxhash")||v(),a=l(s),u=n.get("fxminter")||A(),m=l(u),g=n.get("preview")==="1";function d(){t.dispatchEvent(new Event("fxhash-preview")),setTimeout(()=>d(),500)}let $=t.location.hash?.replace("#0x",""),_={_version:"4.0.1",_processors:h,_params:void 0,_features:void 0,_paramValues:{},_listeners:{},_receiveUpdateParams:async function(o,i){let c=await this.propagateEvent("params:update",o);c.forEach(([f,y])=>{typeof f=="boolean"&&!f||(this._updateParams(o),i?.()),y?.(f,o)}),c.length===0&&(this._updateParams(o),i?.())},_updateParams:function(o){let i=E({...this._rawValues,...o},this._params,"constrain");Object.keys(i).forEach(c=>{this._rawValues[c]=i[c]}),this._paramValues=E(this._rawValues,this._params,"transform"),this._updateInputBytes()},_updateInputBytes:function(){let o=M(this._rawValues,this._params);this.inputBytes=o},_emitParams:function(o){let i=Object.keys(o).reduce((c,f)=>(c[f]=z(f,o[f],this._params,"constrain"),c),{});this._receiveUpdateParams(i,()=>{e.postMessage({id:"fxhash_emit:params:update",data:{params:i}},"*")})},hash:s,rand:a,minter:u,randminter:m,iteration:Number(n.get("fxiteration"))||1,context:n.get("fxcontext")||"standalone",preview:d,isPreview:g,params:function(o){this._params=o.map(i=>({...i,version:this._version})),this._rawValues=F($,this._params,{withTransform:!0,transformType:"constrain"}),this._paramValues=E(this._rawValues,this._params,"transform"),this._updateInputBytes()},features:function(o){this._features=o},getFeature:function(o){return this._features[o]},getFeatures:function(){return this._features},getParam:function(o){return this._paramValues[o]},getParams:function(){return this._paramValues},getRawParam:function(o){return this._rawValues[o]},getRawParams:function(){return this._rawValues},getRandomParam:function(o){let i=this._params.find(f=>f.id===o);return h[i.type].random(i)},getDefinitions:function(){return this._params},stringifyParams:function(o){return JSON.stringify(o||this._rawValues,(i,c)=>typeof c=="bigint"?c.toString():c,2)},on:function(o,i,c){return this._listeners[o]||(this._listeners[o]=[]),this._listeners[o].push([i,c]),()=>{let f=this._listeners[o].findIndex(([y])=>y===i);f>-1&&this._listeners[o].splice(f,1)}},propagateEvent:async function(o,i){let c=[];if(this._listeners?.[o])for(let[f,y]of this._listeners[o]){let S=f(i);c.push([S instanceof Promise?await S:S,y])}return c},emit:function(o,i){switch(o){case"params:update":this._emitParams(i);break;default:console.log("$fx.emit called with unknown id:",o);break}}},B=()=>{a=l(s),_.rand=a,a.reset=B};a.reset=B;let N=()=>{m=l(u),_.randminter=m,m.reset=N};return m.reset=N,t.addEventListener("message",o=>{if(o.data==="fxhash_getInfo"&&e.postMessage({id:"fxhash_getInfo",data:{version:t.$fx._version,hash:t.$fx.hash,iteration:t.$fx.iteration,features:t.$fx.getFeatures(),params:{definitions:t.$fx.getDefinitions(),values:t.$fx.getRawParams()},minter:t.$fx.minter}},"*"),o.data?.id==="fxhash_params:update"){let{params:i}=o.data.data;i&&t.$fx._receiveUpdateParams(i)}}),_}window.$fx=V(window,{});})();
|
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
/* global $fx */
|
|
2
|
-
import { textmode } from 'textmode.js';
|
|
3
|
-
|
|
4
|
-
const palettes = [
|
|
5
|
-
{
|
|
6
|
-
name: 'Electric Bloom',
|
|
7
|
-
bg: [6, 6, 12],
|
|
8
|
-
colors: [
|
|
9
|
-
[246, 70, 104],
|
|
10
|
-
[255, 191, 0],
|
|
11
|
-
[89, 247, 255]
|
|
12
|
-
],
|
|
13
|
-
glyphs: ['▓', '▒', '░']
|
|
14
|
-
},
|
|
15
|
-
{
|
|
16
|
-
name: 'Monotone Void',
|
|
17
|
-
bg: [10, 10, 12],
|
|
18
|
-
colors: [
|
|
19
|
-
[240, 240, 240],
|
|
20
|
-
[180, 180, 180],
|
|
21
|
-
[120, 120, 120]
|
|
22
|
-
],
|
|
23
|
-
glyphs: ['█', '▓', '░']
|
|
24
|
-
},
|
|
25
|
-
{
|
|
26
|
-
name: 'Emerald Night',
|
|
27
|
-
bg: [4, 10, 8],
|
|
28
|
-
colors: [
|
|
29
|
-
[122, 217, 147],
|
|
30
|
-
[48, 163, 84],
|
|
31
|
-
[10, 102, 85]
|
|
32
|
-
],
|
|
33
|
-
glyphs: ['▒', '░', '▓']
|
|
34
|
-
}
|
|
35
|
-
];
|
|
36
|
-
|
|
37
|
-
const palette = pick(palettes);
|
|
38
|
-
const symmetry = $fx.rand() > 0.5 ? 'mirror' : 'radial';
|
|
39
|
-
const density = Math.floor($fx.rand() * 5) + 3; // 3..7 controls spacing
|
|
40
|
-
const jitter = $fx.rand() > 0.5;
|
|
41
|
-
|
|
42
|
-
$fx.features({
|
|
43
|
-
Palette: palette.name,
|
|
44
|
-
Symmetry: symmetry,
|
|
45
|
-
Density: density,
|
|
46
|
-
Jitter: jitter ? 'yes' : 'no'
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
const tm = textmode.create({ width: window.innerWidth, height: window.innerHeight });
|
|
50
|
-
const seed = $fx.rand() * 10000;
|
|
51
|
-
let previewSent = false;
|
|
52
|
-
|
|
53
|
-
function pick(items) {
|
|
54
|
-
const idx = Math.floor($fx.rand() * items.length);
|
|
55
|
-
return items[idx];
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
function waveNoise(x, y, t) {
|
|
59
|
-
const base = Math.sin(x * 0.45 + y * 0.35 + seed + t);
|
|
60
|
-
const ripple = Math.sin(Math.sqrt(x * x + y * y) * 0.35 + t * 0.5 + seed * 0.3);
|
|
61
|
-
return 0.5 + 0.25 * base + 0.25 * ripple;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
tm.draw(() => {
|
|
65
|
-
tm.background(...palette.bg);
|
|
66
|
-
|
|
67
|
-
const halfCols = Math.floor(tm.grid.cols / 2) + 1;
|
|
68
|
-
const halfRows = Math.floor(tm.grid.rows / 2) + 1;
|
|
69
|
-
|
|
70
|
-
for (let y = -halfRows; y < halfRows; y++) {
|
|
71
|
-
for (let x = -halfCols; x < halfCols; x++) {
|
|
72
|
-
if ((Math.abs(x) + Math.abs(y)) % density !== 0) continue;
|
|
73
|
-
|
|
74
|
-
const sx = symmetry === 'mirror' ? Math.abs(x) : x;
|
|
75
|
-
const t = tm.frameCount * 0.02;
|
|
76
|
-
const wobble = jitter ? waveNoise(x * 0.05, y * 0.05, t * 1.5) - 0.5 : 0;
|
|
77
|
-
const n = waveNoise(sx * 0.35, y * 0.35, t) + wobble;
|
|
78
|
-
const colorIdx = Math.floor(Math.abs(n * palette.colors.length)) % palette.colors.length;
|
|
79
|
-
const glyph = palette.glyphs[colorIdx % palette.glyphs.length];
|
|
80
|
-
const [r, g, b] = palette.colors[colorIdx];
|
|
81
|
-
|
|
82
|
-
tm.push();
|
|
83
|
-
tm.translate(x, y, 0);
|
|
84
|
-
tm.char(glyph);
|
|
85
|
-
tm.charColor(r, g, b);
|
|
86
|
-
tm.point();
|
|
87
|
-
tm.pop();
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
if (!previewSent && tm.frameCount > 12) {
|
|
92
|
-
$fx.preview();
|
|
93
|
-
previewSent = true;
|
|
94
|
-
}
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
tm.windowResized(() => {
|
|
98
|
-
tm.resizeCanvas(window.innerWidth, window.innerHeight);
|
|
99
|
-
});
|
|
100
|
-
|
|
101
|
-
console.log('fxhash:', $fx.hash);
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import js from "@eslint/js";
|
|
2
|
-
import globals from "globals";
|
|
3
|
-
import prettierConfig from "eslint-config-prettier";
|
|
4
|
-
import tseslint from "typescript-eslint";
|
|
5
|
-
|
|
6
|
-
export default tseslint.config(
|
|
7
|
-
{
|
|
8
|
-
ignores: ["dist/**", "node_modules/**"],
|
|
9
|
-
},
|
|
10
|
-
js.configs.recommended,
|
|
11
|
-
...tseslint.configs.recommended,
|
|
12
|
-
prettierConfig,
|
|
13
|
-
{
|
|
14
|
-
files: ["**/*.{ts,tsx}"],
|
|
15
|
-
languageOptions: {
|
|
16
|
-
ecmaVersion: "latest",
|
|
17
|
-
sourceType: "module",
|
|
18
|
-
globals: {
|
|
19
|
-
...globals.browser,
|
|
20
|
-
},
|
|
21
|
-
},
|
|
22
|
-
}
|
|
23
|
-
);
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
<!doctype html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
|
|
4
|
-
<head>
|
|
5
|
-
<meta charset="UTF-8" />
|
|
6
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
|
-
<title>{{name}}</title>
|
|
8
|
-
|
|
9
|
-
<style>
|
|
10
|
-
html,
|
|
11
|
-
body {
|
|
12
|
-
margin: 0;
|
|
13
|
-
padding: 0;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
canvas {
|
|
17
|
-
display: block;
|
|
18
|
-
}
|
|
19
|
-
</style>
|
|
20
|
-
</head>
|
|
21
|
-
|
|
22
|
-
<body>
|
|
23
|
-
<script src="/fxhash.min.js"></script>
|
|
24
|
-
<script type="module" src="/src/sketch.ts"></script>
|
|
25
|
-
</body>
|
|
26
|
-
|
|
27
|
-
</html>
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "{{name}}",
|
|
3
|
-
"version": "0.0.0",
|
|
4
|
-
"private": true,
|
|
5
|
-
"type": "module",
|
|
6
|
-
"scripts": {
|
|
7
|
-
"dev": "vite",
|
|
8
|
-
"build": "vite build",
|
|
9
|
-
"preview": "vite preview",
|
|
10
|
-
"format": "prettier --write \"src/**/*.{js,ts}\"",
|
|
11
|
-
"format:check": "prettier --check \"src/**/*.{js,ts}\"",
|
|
12
|
-
"lint": "eslint src --ext .ts",
|
|
13
|
-
"lint:fix": "eslint src --ext .ts --fix",
|
|
14
|
-
"typecheck": "tsc --noEmit"
|
|
15
|
-
},
|
|
16
|
-
"dependencies": {
|
|
17
|
-
"textmode.js": "latest"
|
|
18
|
-
},
|
|
19
|
-
"devDependencies": {
|
|
20
|
-
"@eslint/js": "^9.39.1",
|
|
21
|
-
"@types/node": "^24.10.2",
|
|
22
|
-
"eslint": "^9.39.1",
|
|
23
|
-
"eslint-config-prettier": "^10.1.8",
|
|
24
|
-
"globals": "^15.14.0",
|
|
25
|
-
"prettier": "^3.7.4",
|
|
26
|
-
"typescript": "^5.9.3",
|
|
27
|
-
"typescript-eslint": "^8.49.0",
|
|
28
|
-
"vite": "^7.2.7"
|
|
29
|
-
}
|
|
30
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";(()=>{var p="123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";function A(){return`tz1${Array.from({length:33},()=>p[Math.random()*p.length|0]).join("")}`}function b(t){if(t.length!==36||!/^(tz|KT)[1-4]/.test(t))return!1;for(let r=0;r<t.length;r++)if(!p.includes(t[r]))return!1;return!0}function T(t){return/^(0x)?[0-9a-fA-F]{40}$/.test(t)}function v(){return`oo${Array.from({length:49},()=>p[Math.random()*p.length|0]).join("")}`}function P(t){return/^(0x)?([A-Fa-f0-9]{64})$/.test(t)}function j(t){return[...t].reduce(function(r,e){return r*p.length+p.indexOf(e)|0},0)}function U([t,r,e,n]){return function(){t|=0,r|=0,e|=0,n|=0;let s=(t+r|0)+n|0;return n=n+1|0,t=r^r>>>9,r=e+(e<<3)|0,e=e<<21|e>>>11,e=e+s|0,(s>>>0)/4294967296}}function I(t,r,e=j){return t.slice(r).match(new RegExp(".{"+(t.length-r>>2)+"}","g")).map(e)}function C(t){return P(t)||T(t)?I(t,2,r=>Number(BigInt(`0x${r}`)%BigInt(4294967295))):b(t)?I(t,3):I(t,2)}function l(t){let r=C(t);return U(r)}function H(t){let r=t.replace("#","");return r.length===6&&(r=`${r}ff`),r.length===3&&(r=`${r[0]}${r[0]}${r[1]}${r[1]}${r[2]}${r[2]}ff`),r}var w=function(t){let r="";for(let e=0;e<t.length;e++)r+=t.charCodeAt(e).toString(16).padStart(4,"0");return r},O=function(t){let r=t.match(/.{1,4}/g)||[],e="";for(let n=0;n<r.length;n++){let s=parseInt(r[n],16);if(s===0)break;e+=String.fromCharCode(s)}return e},k=BigInt("-9223372036854775808"),R=BigInt("9223372036854775807"),h={number:{serialize:t=>{let r=new DataView(new ArrayBuffer(8));return r.setFloat64(0,t),r.getBigUint64(0).toString(16).padStart(16,"0")},deserialize:t=>{let r=new DataView(new ArrayBuffer(8));for(let e=0;e<8;e++)r.setUint8(e,parseInt(t.substring(e*2,e*2+2),16));return r.getFloat64(0)},bytesLength:()=>8,constrain:(t,r)=>{let e=Number.MIN_SAFE_INTEGER;typeof r.options?.min<"u"&&(e=Number(r.options.min));let n=Number.MAX_SAFE_INTEGER;typeof r.options?.max<"u"&&(n=Number(r.options.max)),n=Math.min(n,Number.MAX_SAFE_INTEGER),e=Math.max(e,Number.MIN_SAFE_INTEGER);let s=Math.min(Math.max(t,e),n);if(r?.options?.step){let a=1/r?.options?.step;return Math.round(s*a)/a}return s},random:t=>{let r=Number.MIN_SAFE_INTEGER;typeof t.options?.min<"u"&&(r=Number(t.options.min));let e=Number.MAX_SAFE_INTEGER;typeof t.options?.max<"u"&&(e=Number(t.options.max)),e=Math.min(e,Number.MAX_SAFE_INTEGER),r=Math.max(r,Number.MIN_SAFE_INTEGER);let n=Math.random()*(e-r)+r;if(t?.options?.step){let s=1/t?.options?.step;return Math.round(n*s)/s}return n}},bigint:{serialize:t=>{let r=new DataView(new ArrayBuffer(8));return r.setBigInt64(0,BigInt(t)),r.getBigUint64(0).toString(16).padStart(16,"0")},deserialize:t=>{let r=new DataView(new ArrayBuffer(8));for(let e=0;e<8;e++)r.setUint8(e,parseInt(t.substring(e*2,e*2+2),16));return r.getBigInt64(0)},bytesLength:()=>8,random:t=>{let r=k,e=R;typeof t.options?.min<"u"&&(r=BigInt(t.options.min)),typeof t.options?.max<"u"&&(e=BigInt(t.options.max));let n=e-r,s=n.toString(2).length,a;do a=BigInt("0b"+Array.from(crypto.getRandomValues(new Uint8Array(Math.ceil(s/8)))).map(u=>u.toString(2).padStart(8,"0")).join(""));while(a>n);return a+r}},boolean:{serialize:t=>typeof t=="boolean"?t?"01":"00":typeof t=="string"&&t==="true"?"01":"00",deserialize:t=>t!=="00",bytesLength:()=>1,random:()=>Math.random()<.5},color:{serialize:t=>H(t),deserialize:t=>t,bytesLength:()=>4,transform:t=>{let r=H(t),e=parseInt(r.slice(0,2),16),n=parseInt(r.slice(2,4),16),s=parseInt(r.slice(4,6),16),a=parseInt(r.slice(6,8),16);return{hex:{rgb:"#"+t.slice(0,6),rgba:"#"+t},obj:{rgb:{r:e,g:n,b:s},rgba:{r:e,g:n,b:s,a}},arr:{rgb:[e,n,s],rgba:[e,n,s,a]}}},constrain:t=>t.replace("#","").slice(0,8).padEnd(8,"f"),random:()=>`${[...Array(8)].map(()=>Math.floor(Math.random()*16).toString(16)).join("")}`},string:{serialize:(t,r)=>{if(!r.version){let s=w(t.substring(0,64));return s=s.padEnd(64*4,"0"),s}let e=64;typeof r.options?.maxLength<"u"&&(e=Number(r.options.maxLength));let n=w(t.substring(0,e));return n=n.padEnd(e*4,"0"),n},deserialize:t=>O(t),bytesLength:t=>t.version&&typeof t.options?.maxLength<"u"?Number(t.options.maxLength)*2:64*2,random:t=>{let r=0;typeof t.options?.minLength<"u"&&(r=t.options.minLength);let e=64;typeof t.options?.maxLength<"u"&&(e=t.options.maxLength);let n=Math.round(Math.random()*(e-r)+r);return[...Array(n)].map(s=>(~~(Math.random()*36)).toString(36)).join("")},constrain:(t,r)=>{let e=0;typeof r.options?.minLength<"u"&&(e=r.options.minLength);let n=64;typeof r.options?.maxLength<"u"&&(n=r.options.maxLength);let s=t.slice(0,n);return s.length<e?s.padEnd(e):s}},bytes:{serialize:(t,r)=>Array.from(t).map(e=>e.toString(16).padStart(2,"0")).join(""),deserialize:(t,r)=>{let e=t.length/2,n=new Uint8Array(e),s;for(let a=0;a<e;a++)s=a*2,n[a]=parseInt(`${t[s]}${t[s+1]}`,16);return n},bytesLength:t=>t.options.length,random:t=>{let r=t.options?.length||0,e=new Uint8Array(r);for(let n=0;n<r;n++)e[n]=Math.random()*255|0;return e}},select:{serialize:(t,r)=>Math.min(255,r.options?.options?.indexOf(t)||0).toString(16).padStart(2,"0"),deserialize:(t,r)=>{let e=parseInt(t,16);return r.options?.options?.[e]||r.options?.options?.[0]||""},bytesLength:()=>1,constrain:(t,r)=>r.options.options.includes(t)?t:r.options.options[0],random:t=>{let r=Math.round(Math.random()*(t.options.options.length-1)+0);return t?.options?.options[r]}}};function M(t,r){let e="";if(!r)return e;for(let n of r){let{id:s,type:a}=n,u=h[a],m=t[s],g=typeof m<"u"?m:typeof n.default<"u"?n.default:u.random(n),d=u.serialize(g,n);e+=d}return e}function F(t,r,e){let n={};for(let s of r){let a=h[s.type],u=e.withTransform&&a[e.transformType||"transform"];if(!t){let x;typeof s.default>"u"?x=a.random(s):x=s.default,n[s.id]=u?u(x,s):x;continue}let m=a.bytesLength(s),g=t.substring(0,m*2);t=t.substring(m*2);let d=a.deserialize(g,s);n[s.id]=u?u(d,s):d}return n}var z=(t,r,e,n)=>{let s=e.find(m=>m.id===t),u=h[s.type][n];return u?.(r,s)||r},E=(t,r,e)=>{let n={};for(let s of r){let a=h[s.type],u=t[s.id],m=a[e];n[s.id]=m?.(u,s)||u}return n};function V(t,r){let{parent:e}=t,n=new URLSearchParams(t.location.search),s=n.get("fxhash")||v(),a=l(s),u=n.get("fxminter")||A(),m=l(u),g=n.get("preview")==="1";function d(){t.dispatchEvent(new Event("fxhash-preview")),setTimeout(()=>d(),500)}let $=t.location.hash?.replace("#0x",""),_={_version:"4.0.1",_processors:h,_params:void 0,_features:void 0,_paramValues:{},_listeners:{},_receiveUpdateParams:async function(o,i){let c=await this.propagateEvent("params:update",o);c.forEach(([f,y])=>{typeof f=="boolean"&&!f||(this._updateParams(o),i?.()),y?.(f,o)}),c.length===0&&(this._updateParams(o),i?.())},_updateParams:function(o){let i=E({...this._rawValues,...o},this._params,"constrain");Object.keys(i).forEach(c=>{this._rawValues[c]=i[c]}),this._paramValues=E(this._rawValues,this._params,"transform"),this._updateInputBytes()},_updateInputBytes:function(){let o=M(this._rawValues,this._params);this.inputBytes=o},_emitParams:function(o){let i=Object.keys(o).reduce((c,f)=>(c[f]=z(f,o[f],this._params,"constrain"),c),{});this._receiveUpdateParams(i,()=>{e.postMessage({id:"fxhash_emit:params:update",data:{params:i}},"*")})},hash:s,rand:a,minter:u,randminter:m,iteration:Number(n.get("fxiteration"))||1,context:n.get("fxcontext")||"standalone",preview:d,isPreview:g,params:function(o){this._params=o.map(i=>({...i,version:this._version})),this._rawValues=F($,this._params,{withTransform:!0,transformType:"constrain"}),this._paramValues=E(this._rawValues,this._params,"transform"),this._updateInputBytes()},features:function(o){this._features=o},getFeature:function(o){return this._features[o]},getFeatures:function(){return this._features},getParam:function(o){return this._paramValues[o]},getParams:function(){return this._paramValues},getRawParam:function(o){return this._rawValues[o]},getRawParams:function(){return this._rawValues},getRandomParam:function(o){let i=this._params.find(f=>f.id===o);return h[i.type].random(i)},getDefinitions:function(){return this._params},stringifyParams:function(o){return JSON.stringify(o||this._rawValues,(i,c)=>typeof c=="bigint"?c.toString():c,2)},on:function(o,i,c){return this._listeners[o]||(this._listeners[o]=[]),this._listeners[o].push([i,c]),()=>{let f=this._listeners[o].findIndex(([y])=>y===i);f>-1&&this._listeners[o].splice(f,1)}},propagateEvent:async function(o,i){let c=[];if(this._listeners?.[o])for(let[f,y]of this._listeners[o]){let S=f(i);c.push([S instanceof Promise?await S:S,y])}return c},emit:function(o,i){switch(o){case"params:update":this._emitParams(i);break;default:console.log("$fx.emit called with unknown id:",o);break}}},B=()=>{a=l(s),_.rand=a,a.reset=B};a.reset=B;let N=()=>{m=l(u),_.randminter=m,m.reset=N};return m.reset=N,t.addEventListener("message",o=>{if(o.data==="fxhash_getInfo"&&e.postMessage({id:"fxhash_getInfo",data:{version:t.$fx._version,hash:t.$fx.hash,iteration:t.$fx.iteration,features:t.$fx.getFeatures(),params:{definitions:t.$fx.getDefinitions(),values:t.$fx.getRawParams()},minter:t.$fx.minter}},"*"),o.data?.id==="fxhash_params:update"){let{params:i}=o.data.data;i&&t.$fx._receiveUpdateParams(i)}}),_}window.$fx=V(window,{});})();
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
type FxFeatureValue = string | number | boolean;
|
|
2
|
-
type FxFeatures = Record<string, FxFeatureValue>;
|
|
3
|
-
|
|
4
|
-
interface FxRandFn {
|
|
5
|
-
(): number;
|
|
6
|
-
reset(): void;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
type FxParamType = 'number' | 'bigint' | 'boolean' | 'color' | 'string' | 'bytes' | 'select';
|
|
10
|
-
|
|
11
|
-
type FxParamUpdate = 'page-reload' | 'sync' | 'code-driven';
|
|
12
|
-
|
|
13
|
-
type FxParamDefinition = {
|
|
14
|
-
id: string;
|
|
15
|
-
name?: string;
|
|
16
|
-
type: FxParamType;
|
|
17
|
-
options?: Record<string, unknown>;
|
|
18
|
-
default?: unknown;
|
|
19
|
-
update?: FxParamUpdate;
|
|
20
|
-
version?: string;
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
type FxParamDefinitions = FxParamDefinition[];
|
|
24
|
-
type FxParamsObject = Record<string, unknown>;
|
|
25
|
-
type FxParamEventId = 'params:update' | string;
|
|
26
|
-
|
|
27
|
-
interface FxApi {
|
|
28
|
-
hash: string;
|
|
29
|
-
minter: string;
|
|
30
|
-
iteration: number;
|
|
31
|
-
context: 'standalone' | 'capture' | 'minting' | string;
|
|
32
|
-
isPreview: boolean;
|
|
33
|
-
lineage?: string[];
|
|
34
|
-
depth?: number;
|
|
35
|
-
rand: FxRandFn;
|
|
36
|
-
randminter: FxRandFn;
|
|
37
|
-
randAt?: (depth: number) => number;
|
|
38
|
-
features: (features: FxFeatures) => void;
|
|
39
|
-
getFeature: (name: string) => FxFeatureValue | undefined;
|
|
40
|
-
getFeatures: () => FxFeatures;
|
|
41
|
-
preview: () => void;
|
|
42
|
-
params: (definitions: FxParamDefinitions) => void;
|
|
43
|
-
getParam: (id: string) => unknown;
|
|
44
|
-
getParams: () => FxParamsObject;
|
|
45
|
-
getRawParam: (id: string) => string | undefined;
|
|
46
|
-
emit: (eventId: FxParamEventId, data?: FxParamsObject) => void;
|
|
47
|
-
on: (
|
|
48
|
-
eventId: FxParamEventId,
|
|
49
|
-
handler: (...args: any[]) => boolean | Promise<boolean>,
|
|
50
|
-
onDone?: (optInDefault: boolean, ...args: any[]) => void
|
|
51
|
-
) => () => void;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
declare const $fx: FxApi;
|
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
/* global $fx */
|
|
2
|
-
import { textmode } from 'textmode.js';
|
|
3
|
-
|
|
4
|
-
type Palette = {
|
|
5
|
-
name: string;
|
|
6
|
-
bg: [number, number, number];
|
|
7
|
-
colors: [number, number, number][];
|
|
8
|
-
glyphs: string[];
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
const palettes: Palette[] = [
|
|
12
|
-
{
|
|
13
|
-
name: 'Electric Bloom',
|
|
14
|
-
bg: [6, 6, 12],
|
|
15
|
-
colors: [
|
|
16
|
-
[246, 70, 104],
|
|
17
|
-
[255, 191, 0],
|
|
18
|
-
[89, 247, 255]
|
|
19
|
-
],
|
|
20
|
-
glyphs: ['▓', '▒', '░']
|
|
21
|
-
},
|
|
22
|
-
{
|
|
23
|
-
name: 'Monotone Void',
|
|
24
|
-
bg: [10, 10, 12],
|
|
25
|
-
colors: [
|
|
26
|
-
[240, 240, 240],
|
|
27
|
-
[180, 180, 180],
|
|
28
|
-
[120, 120, 120]
|
|
29
|
-
],
|
|
30
|
-
glyphs: ['█', '▓', '░']
|
|
31
|
-
},
|
|
32
|
-
{
|
|
33
|
-
name: 'Emerald Night',
|
|
34
|
-
bg: [4, 10, 8],
|
|
35
|
-
colors: [
|
|
36
|
-
[122, 217, 147],
|
|
37
|
-
[48, 163, 84],
|
|
38
|
-
[10, 102, 85]
|
|
39
|
-
],
|
|
40
|
-
glyphs: ['▒', '░', '▓']
|
|
41
|
-
}
|
|
42
|
-
];
|
|
43
|
-
|
|
44
|
-
const palette = pick(palettes);
|
|
45
|
-
const symmetry = $fx.rand() > 0.5 ? 'mirror' : 'radial';
|
|
46
|
-
const density = Math.floor($fx.rand() * 5) + 3; // 3..7 controls spacing
|
|
47
|
-
const jitter = $fx.rand() > 0.5;
|
|
48
|
-
|
|
49
|
-
$fx.features({
|
|
50
|
-
Palette: palette.name,
|
|
51
|
-
Symmetry: symmetry,
|
|
52
|
-
Density: density,
|
|
53
|
-
Jitter: jitter ? 'yes' : 'no'
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
const tm = textmode.create({ width: window.innerWidth, height: window.innerHeight });
|
|
57
|
-
const seed = $fx.rand() * 10000;
|
|
58
|
-
let previewSent = false;
|
|
59
|
-
|
|
60
|
-
function pick<T>(items: T[]): T {
|
|
61
|
-
const idx = Math.floor($fx.rand() * items.length);
|
|
62
|
-
return items[idx];
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
function waveNoise(x: number, y: number, t: number): number {
|
|
66
|
-
const base = Math.sin(x * 0.45 + y * 0.35 + seed + t);
|
|
67
|
-
const ripple = Math.sin(Math.sqrt(x * x + y * y) * 0.35 + t * 0.5 + seed * 0.3);
|
|
68
|
-
return 0.5 + 0.25 * base + 0.25 * ripple;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
tm.draw(() => {
|
|
72
|
-
tm.background(...palette.bg);
|
|
73
|
-
|
|
74
|
-
const halfCols = Math.floor(tm.grid.cols / 2) + 1;
|
|
75
|
-
const halfRows = Math.floor(tm.grid.rows / 2) + 1;
|
|
76
|
-
|
|
77
|
-
for (let y = -halfRows; y < halfRows; y++) {
|
|
78
|
-
for (let x = -halfCols; x < halfCols; x++) {
|
|
79
|
-
if ((Math.abs(x) + Math.abs(y)) % density !== 0) continue;
|
|
80
|
-
|
|
81
|
-
const sx = symmetry === 'mirror' ? Math.abs(x) : x;
|
|
82
|
-
const t = tm.frameCount * 0.02;
|
|
83
|
-
const wobble = jitter ? waveNoise(x * 0.05, y * 0.05, t * 1.5) - 0.5 : 0;
|
|
84
|
-
const n = waveNoise(sx * 0.35, y * 0.35, t) + wobble;
|
|
85
|
-
const colorIdx = Math.floor(Math.abs(n * palette.colors.length)) % palette.colors.length;
|
|
86
|
-
const glyph = palette.glyphs[colorIdx % palette.glyphs.length];
|
|
87
|
-
const [r, g, b] = palette.colors[colorIdx];
|
|
88
|
-
|
|
89
|
-
tm.push();
|
|
90
|
-
tm.translate(x, y, 0);
|
|
91
|
-
tm.char(glyph);
|
|
92
|
-
tm.charColor(r, g, b);
|
|
93
|
-
tm.point();
|
|
94
|
-
tm.pop();
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
if (!previewSent && tm.frameCount > 12) {
|
|
99
|
-
$fx.preview();
|
|
100
|
-
previewSent = true;
|
|
101
|
-
}
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
tm.windowResized(() => {
|
|
105
|
-
tm.resizeCanvas(window.innerWidth, window.innerHeight);
|
|
106
|
-
});
|
|
107
|
-
|
|
108
|
-
console.log('fxhash:', $fx.hash);
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"target": "ESNext",
|
|
4
|
-
"useDefineForClassFields": true,
|
|
5
|
-
"module": "ESNext",
|
|
6
|
-
"moduleResolution": "Node",
|
|
7
|
-
"strict": true,
|
|
8
|
-
"jsx": "preserve",
|
|
9
|
-
"esModuleInterop": true,
|
|
10
|
-
"skipLibCheck": true,
|
|
11
|
-
"types": ["vite/client"]
|
|
12
|
-
},
|
|
13
|
-
"include": ["src"],
|
|
14
|
-
"references": []
|
|
15
|
-
}
|