choas 1.0.0
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/dist/index.d.ts +7 -0
- package/dist/index.js +103 -0
- package/package.json +18 -0
- package/src/index.ts +122 -0
- package/tsconfig.json +17 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
declare const colors: string[];
|
|
2
|
+
declare const RESET = "\u001B[0m";
|
|
3
|
+
declare const chars = " .:-=+*#%@";
|
|
4
|
+
declare function mandelbrot(cReal: number, cImag: number, maxIter: number): number;
|
|
5
|
+
declare function getColor(iter: number, maxIter: number): string;
|
|
6
|
+
declare function getChar(iter: number, maxIter: number): string;
|
|
7
|
+
declare function renderMandelbrot(): void;
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Mandelbrot ASCII Art Generator
|
|
3
|
+
// Uses ANSI escape codes for colors - no external libraries needed
|
|
4
|
+
// ANSI color codes for a gradient palette
|
|
5
|
+
const colors = [
|
|
6
|
+
'\x1b[38;5;16m', // Black (inside the set)
|
|
7
|
+
'\x1b[38;5;17m', // Dark blue
|
|
8
|
+
'\x1b[38;5;18m', // Blue
|
|
9
|
+
'\x1b[38;5;19m', // Medium blue
|
|
10
|
+
'\x1b[38;5;20m', // Lighter blue
|
|
11
|
+
'\x1b[38;5;21m', // Blue
|
|
12
|
+
'\x1b[38;5;27m', // Bright blue
|
|
13
|
+
'\x1b[38;5;33m', // Cyan-blue
|
|
14
|
+
'\x1b[38;5;39m', // Cyan
|
|
15
|
+
'\x1b[38;5;45m', // Light cyan
|
|
16
|
+
'\x1b[38;5;51m', // Bright cyan
|
|
17
|
+
'\x1b[38;5;50m', // Teal
|
|
18
|
+
'\x1b[38;5;49m', // Green-cyan
|
|
19
|
+
'\x1b[38;5;48m', // Green
|
|
20
|
+
'\x1b[38;5;47m', // Bright green
|
|
21
|
+
'\x1b[38;5;46m', // Lime
|
|
22
|
+
'\x1b[38;5;82m', // Yellow-green
|
|
23
|
+
'\x1b[38;5;118m', // Light green
|
|
24
|
+
'\x1b[38;5;154m', // Yellow-green
|
|
25
|
+
'\x1b[38;5;190m', // Yellow
|
|
26
|
+
'\x1b[38;5;226m', // Bright yellow
|
|
27
|
+
'\x1b[38;5;220m', // Gold
|
|
28
|
+
'\x1b[38;5;214m', // Orange
|
|
29
|
+
'\x1b[38;5;208m', // Dark orange
|
|
30
|
+
'\x1b[38;5;202m', // Red-orange
|
|
31
|
+
'\x1b[38;5;196m', // Red
|
|
32
|
+
'\x1b[38;5;197m', // Pink-red
|
|
33
|
+
'\x1b[38;5;198m', // Pink
|
|
34
|
+
'\x1b[38;5;199m', // Magenta-pink
|
|
35
|
+
'\x1b[38;5;200m', // Magenta
|
|
36
|
+
'\x1b[38;5;201m', // Bright magenta
|
|
37
|
+
'\x1b[38;5;165m', // Purple
|
|
38
|
+
];
|
|
39
|
+
const RESET = '\x1b[0m';
|
|
40
|
+
// ASCII characters for density visualization
|
|
41
|
+
const chars = ' .:-=+*#%@';
|
|
42
|
+
function mandelbrot(cReal, cImag, maxIter) {
|
|
43
|
+
let zReal = 0;
|
|
44
|
+
let zImag = 0;
|
|
45
|
+
let iter = 0;
|
|
46
|
+
while (iter < maxIter && zReal * zReal + zImag * zImag < 4) {
|
|
47
|
+
const tempReal = zReal * zReal - zImag * zImag + cReal;
|
|
48
|
+
zImag = 2 * zReal * zImag + cImag;
|
|
49
|
+
zReal = tempReal;
|
|
50
|
+
iter++;
|
|
51
|
+
}
|
|
52
|
+
return iter;
|
|
53
|
+
}
|
|
54
|
+
function getColor(iter, maxIter) {
|
|
55
|
+
if (iter === maxIter) {
|
|
56
|
+
return colors[0]; // Inside the set - darkest color
|
|
57
|
+
}
|
|
58
|
+
const colorIndex = Math.floor((iter / maxIter) * (colors.length - 1)) + 1;
|
|
59
|
+
return colors[Math.min(colorIndex, colors.length - 1)];
|
|
60
|
+
}
|
|
61
|
+
function getChar(iter, maxIter) {
|
|
62
|
+
if (iter === maxIter) {
|
|
63
|
+
return ' '; // Inside the set
|
|
64
|
+
}
|
|
65
|
+
const charIndex = Math.floor((iter / maxIter) * (chars.length - 1));
|
|
66
|
+
return chars[Math.min(charIndex, chars.length - 1)];
|
|
67
|
+
}
|
|
68
|
+
function renderMandelbrot() {
|
|
69
|
+
// Get terminal size, with fallbacks
|
|
70
|
+
const width = process.stdout.columns || 80;
|
|
71
|
+
const height = process.stdout.rows || 24;
|
|
72
|
+
// Mandelbrot set bounds (classic view)
|
|
73
|
+
const xMin = -2.5;
|
|
74
|
+
const xMax = 1.0;
|
|
75
|
+
const yMin = -1.0;
|
|
76
|
+
const yMax = 1.0;
|
|
77
|
+
// Adjust for aspect ratio (terminal characters are taller than wide)
|
|
78
|
+
const aspectRatio = 2.0; // Approximate character aspect ratio
|
|
79
|
+
const maxIter = 100;
|
|
80
|
+
// Clear screen and move cursor to top-left
|
|
81
|
+
process.stdout.write('\x1b[2J\x1b[H');
|
|
82
|
+
let output = '';
|
|
83
|
+
for (let row = 0; row < height - 1; row++) { // Leave one row for prompt
|
|
84
|
+
for (let col = 0; col < width; col++) {
|
|
85
|
+
// Map pixel position to complex plane
|
|
86
|
+
const cReal = xMin + (col / width) * (xMax - xMin);
|
|
87
|
+
const cImag = yMax - (row / (height - 1)) * (yMax - yMin) * aspectRatio + (yMax - yMin) * (aspectRatio - 1) / 2;
|
|
88
|
+
const iter = mandelbrot(cReal, cImag, maxIter);
|
|
89
|
+
const color = getColor(iter, maxIter);
|
|
90
|
+
const char = getChar(iter, maxIter);
|
|
91
|
+
output += color + char;
|
|
92
|
+
}
|
|
93
|
+
if (row < height - 2) {
|
|
94
|
+
output += RESET + '\n';
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
output += RESET;
|
|
98
|
+
process.stdout.write(output);
|
|
99
|
+
// Add choas to the output
|
|
100
|
+
console.log('\nchoas');
|
|
101
|
+
}
|
|
102
|
+
// Run the visualization
|
|
103
|
+
renderMandelbrot();
|
package/package.json
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "choas",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Colorful Mandelbrot ASCII art generator",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"build": "tsc",
|
|
8
|
+
"start": "node dist/index.js",
|
|
9
|
+
"typecheck": "tsc --noEmit",
|
|
10
|
+
"test": "echo \"No tests specified\" && exit 0"
|
|
11
|
+
},
|
|
12
|
+
"keywords": ["mandelbrot", "ascii", "art"],
|
|
13
|
+
"license": "MIT",
|
|
14
|
+
"devDependencies": {
|
|
15
|
+
"typescript": "^5.3.0",
|
|
16
|
+
"@types/node": "^20.10.0"
|
|
17
|
+
}
|
|
18
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
// Mandelbrot ASCII Art Generator
|
|
2
|
+
// Uses ANSI escape codes for colors - no external libraries needed
|
|
3
|
+
|
|
4
|
+
// ANSI color codes for a gradient palette
|
|
5
|
+
const colors = [
|
|
6
|
+
'\x1b[38;5;16m', // Black (inside the set)
|
|
7
|
+
'\x1b[38;5;17m', // Dark blue
|
|
8
|
+
'\x1b[38;5;18m', // Blue
|
|
9
|
+
'\x1b[38;5;19m', // Medium blue
|
|
10
|
+
'\x1b[38;5;20m', // Lighter blue
|
|
11
|
+
'\x1b[38;5;21m', // Blue
|
|
12
|
+
'\x1b[38;5;27m', // Bright blue
|
|
13
|
+
'\x1b[38;5;33m', // Cyan-blue
|
|
14
|
+
'\x1b[38;5;39m', // Cyan
|
|
15
|
+
'\x1b[38;5;45m', // Light cyan
|
|
16
|
+
'\x1b[38;5;51m', // Bright cyan
|
|
17
|
+
'\x1b[38;5;50m', // Teal
|
|
18
|
+
'\x1b[38;5;49m', // Green-cyan
|
|
19
|
+
'\x1b[38;5;48m', // Green
|
|
20
|
+
'\x1b[38;5;47m', // Bright green
|
|
21
|
+
'\x1b[38;5;46m', // Lime
|
|
22
|
+
'\x1b[38;5;82m', // Yellow-green
|
|
23
|
+
'\x1b[38;5;118m', // Light green
|
|
24
|
+
'\x1b[38;5;154m', // Yellow-green
|
|
25
|
+
'\x1b[38;5;190m', // Yellow
|
|
26
|
+
'\x1b[38;5;226m', // Bright yellow
|
|
27
|
+
'\x1b[38;5;220m', // Gold
|
|
28
|
+
'\x1b[38;5;214m', // Orange
|
|
29
|
+
'\x1b[38;5;208m', // Dark orange
|
|
30
|
+
'\x1b[38;5;202m', // Red-orange
|
|
31
|
+
'\x1b[38;5;196m', // Red
|
|
32
|
+
'\x1b[38;5;197m', // Pink-red
|
|
33
|
+
'\x1b[38;5;198m', // Pink
|
|
34
|
+
'\x1b[38;5;199m', // Magenta-pink
|
|
35
|
+
'\x1b[38;5;200m', // Magenta
|
|
36
|
+
'\x1b[38;5;201m', // Bright magenta
|
|
37
|
+
'\x1b[38;5;165m', // Purple
|
|
38
|
+
];
|
|
39
|
+
|
|
40
|
+
const RESET = '\x1b[0m';
|
|
41
|
+
|
|
42
|
+
// ASCII characters for density visualization
|
|
43
|
+
const chars = ' .:-=+*#%@';
|
|
44
|
+
|
|
45
|
+
function mandelbrot(cReal: number, cImag: number, maxIter: number): number {
|
|
46
|
+
let zReal = 0;
|
|
47
|
+
let zImag = 0;
|
|
48
|
+
let iter = 0;
|
|
49
|
+
|
|
50
|
+
while (iter < maxIter && zReal * zReal + zImag * zImag < 4) {
|
|
51
|
+
const tempReal = zReal * zReal - zImag * zImag + cReal;
|
|
52
|
+
zImag = 2 * zReal * zImag + cImag;
|
|
53
|
+
zReal = tempReal;
|
|
54
|
+
iter++;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return iter;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function getColor(iter: number, maxIter: number): string {
|
|
61
|
+
if (iter === maxIter) {
|
|
62
|
+
return colors[0]; // Inside the set - darkest color
|
|
63
|
+
}
|
|
64
|
+
const colorIndex = Math.floor((iter / maxIter) * (colors.length - 1)) + 1;
|
|
65
|
+
return colors[Math.min(colorIndex, colors.length - 1)];
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function getChar(iter: number, maxIter: number): string {
|
|
69
|
+
if (iter === maxIter) {
|
|
70
|
+
return ' '; // Inside the set
|
|
71
|
+
}
|
|
72
|
+
const charIndex = Math.floor((iter / maxIter) * (chars.length - 1));
|
|
73
|
+
return chars[Math.min(charIndex, chars.length - 1)];
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function renderMandelbrot(): void {
|
|
77
|
+
// Get terminal size, with fallbacks
|
|
78
|
+
const width = process.stdout.columns || 80;
|
|
79
|
+
const height = process.stdout.rows || 24;
|
|
80
|
+
|
|
81
|
+
// Mandelbrot set bounds (classic view)
|
|
82
|
+
const xMin = -2.5;
|
|
83
|
+
const xMax = 1.0;
|
|
84
|
+
const yMin = -1.0;
|
|
85
|
+
const yMax = 1.0;
|
|
86
|
+
|
|
87
|
+
// Adjust for aspect ratio (terminal characters are taller than wide)
|
|
88
|
+
const aspectRatio = 2.0; // Approximate character aspect ratio
|
|
89
|
+
|
|
90
|
+
const maxIter = 100;
|
|
91
|
+
|
|
92
|
+
// Clear screen and move cursor to top-left
|
|
93
|
+
process.stdout.write('\x1b[2J\x1b[H');
|
|
94
|
+
|
|
95
|
+
let output = '';
|
|
96
|
+
|
|
97
|
+
for (let row = 0; row < height - 1; row++) { // Leave one row for prompt
|
|
98
|
+
for (let col = 0; col < width; col++) {
|
|
99
|
+
// Map pixel position to complex plane
|
|
100
|
+
const cReal = xMin + (col / width) * (xMax - xMin);
|
|
101
|
+
const cImag = yMax - (row / (height - 1)) * (yMax - yMin) * aspectRatio + (yMax - yMin) * (aspectRatio - 1) / 2;
|
|
102
|
+
|
|
103
|
+
const iter = mandelbrot(cReal, cImag, maxIter);
|
|
104
|
+
const color = getColor(iter, maxIter);
|
|
105
|
+
const char = getChar(iter, maxIter);
|
|
106
|
+
|
|
107
|
+
output += color + char;
|
|
108
|
+
}
|
|
109
|
+
if (row < height - 2) {
|
|
110
|
+
output += RESET + '\n';
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
output += RESET;
|
|
115
|
+
process.stdout.write(output);
|
|
116
|
+
|
|
117
|
+
// Add choas to the output
|
|
118
|
+
console.log('\nchoas');
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// Run the visualization
|
|
122
|
+
renderMandelbrot();
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2020",
|
|
4
|
+
"module": "commonjs",
|
|
5
|
+
"lib": ["ES2020"],
|
|
6
|
+
"outDir": "./dist",
|
|
7
|
+
"rootDir": "./src",
|
|
8
|
+
"strict": true,
|
|
9
|
+
"esModuleInterop": true,
|
|
10
|
+
"skipLibCheck": true,
|
|
11
|
+
"forceConsistentCasingInFileNames": true,
|
|
12
|
+
"resolveJsonModule": true,
|
|
13
|
+
"declaration": true
|
|
14
|
+
},
|
|
15
|
+
"include": ["src/**/*"],
|
|
16
|
+
"exclude": ["node_modules", "dist"]
|
|
17
|
+
}
|