console-rects 0.1.3 → 0.2.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/README.md +60 -51
- package/dist/index.cjs +98 -24
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +98 -24
- package/dist/index.mjs.map +1 -1
- package/dist/types/index.d.ts +6 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -17,9 +17,9 @@ yarn install console-rects
|
|
|
17
17
|
import { logRects, getRectsLog } from "console-rects";
|
|
18
18
|
|
|
19
19
|
const rectangles = [
|
|
20
|
-
{ x: 0, y: 0, width: 100, height: 100 },
|
|
21
|
-
{ x: 40, y: 40, width: 100, height: 100 },
|
|
22
|
-
{ x: 80, y: 80, width: 100, height: 100 },
|
|
20
|
+
{ x: 0, y: 0, width: 100, height: 100 }, // light
|
|
21
|
+
{ x: 40, y: 40, width: 100, height: 100 }, // heavy
|
|
22
|
+
{ x: 80, y: 80, width: 100, height: 100 }, // double
|
|
23
23
|
];
|
|
24
24
|
|
|
25
25
|
logRects(rectangles);
|
|
@@ -29,26 +29,16 @@ getRectsLog(rectangles); // returns the string without logging to console
|
|
|
29
29
|
This will output a visual representation of the rectangles in your console:
|
|
30
30
|
|
|
31
31
|
```
|
|
32
|
-
[0, 0]
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
└───┃───║┘ ┃ ║
|
|
43
|
-
┃ ║ ┃ ║
|
|
44
|
-
┃ ║ ┃ ║
|
|
45
|
-
┃ ║ ┃ ║
|
|
46
|
-
┗━━━║━━━━┛ ║
|
|
47
|
-
║ ║
|
|
48
|
-
║ ║
|
|
49
|
-
║ ║
|
|
50
|
-
╚════════╝
|
|
51
|
-
[180, 180]
|
|
32
|
+
[0, 0] Rectangles (3):
|
|
33
|
+
┏━━━0━━━━┓ 0: [ 0, 0, 100, 100]
|
|
34
|
+
┃ ┌───1────┐ 1: [40, 40, 100, 100]
|
|
35
|
+
┃ │ ┃ │ 2: [80, 80, 100, 100]
|
|
36
|
+
┃ │ ┌╌╌╌2╌╌╌╌┐
|
|
37
|
+
┗━━━│━━━╎┛ │ ╎
|
|
38
|
+
└───╎────┘ ╎
|
|
39
|
+
╎ ╎
|
|
40
|
+
└╌╌╌╌╌╌╌╌┘
|
|
41
|
+
[180, 180]
|
|
52
42
|
```
|
|
53
43
|
|
|
54
44
|
Each rectangle gets a different line style (light, heavy, double, dashed, dashed-heavy) based on its position in the array.
|
|
@@ -56,42 +46,56 @@ Each rectangle gets a different line style (light, heavy, double, dashed, dashed
|
|
|
56
46
|
You can also use it for snapshot testing:
|
|
57
47
|
|
|
58
48
|
```ts
|
|
59
|
-
expect(
|
|
49
|
+
expect(testLayout(layout)).toMatchInlineSnapshot(`
|
|
60
50
|
"
|
|
61
|
-
[
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
┃ ┃ │
|
|
78
|
-
┃ ┃ │
|
|
79
|
-
┗━━━━━━━━━━━━━━━━━━┛ │
|
|
80
|
-
│ │
|
|
81
|
-
│ │
|
|
82
|
-
│ │
|
|
83
|
-
│ │
|
|
84
|
-
│ │
|
|
85
|
-
│ │
|
|
86
|
-
└───────────────────────┘
|
|
87
|
-
[200, 175]"
|
|
51
|
+
[0, 0] Rectangles (3):
|
|
52
|
+
┌╌╌╌╌╌╌╌╌╌╌╌╌╌camera╌╌╌╌╌╌╌╌╌╌╌╌╌┐───────────recording────────────┐ recording: [100, 0, 100, 100]
|
|
53
|
+
╎ ╎ │ camera : [ 0, 0, 100, 100]
|
|
54
|
+
╎ ╎ │
|
|
55
|
+
╎ ╎ │
|
|
56
|
+
╎ ╎ │
|
|
57
|
+
╎ ╎ │
|
|
58
|
+
╎ ╎ │
|
|
59
|
+
╎ ╎ │
|
|
60
|
+
╎ ╎ │
|
|
61
|
+
╎ ╎ │
|
|
62
|
+
╎ ╎ │
|
|
63
|
+
╎ ╎ │
|
|
64
|
+
╎ ╎ │
|
|
65
|
+
└╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┘────────────────────────────────┘
|
|
66
|
+
[200, 100]"
|
|
88
67
|
`);
|
|
89
68
|
```
|
|
90
69
|
|
|
91
70
|
## Options
|
|
92
71
|
|
|
72
|
+
```ts
|
|
73
|
+
interface Rectangle {
|
|
74
|
+
x: number;
|
|
75
|
+
y: number;
|
|
76
|
+
width: number;
|
|
77
|
+
height: number;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export interface LogRectsOptions {
|
|
81
|
+
sizePerPoint?: number;
|
|
82
|
+
showLegend?: boolean;
|
|
83
|
+
listRectangles?: boolean;
|
|
84
|
+
startWithNewLine?: boolean;
|
|
85
|
+
adjustOutputHeight?: boolean;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
type Maybe<T> = T | null | undefined;
|
|
89
|
+
|
|
90
|
+
export type RectsLogInput = Array<Maybe<Rectangle>> | Record<string, Maybe<Rectangle>>;
|
|
91
|
+
|
|
92
|
+
export function getRectsLog(input: RectsLogInput, options?: LogRectsOptions): string | null;
|
|
93
|
+
export function logRects(rectangles: Rectangle[], options?: LogRectsOptions): void;
|
|
94
|
+
```
|
|
95
|
+
|
|
93
96
|
- `sizePerPoint` (default: `10`) - Controls the resolution/scale. Smaller values = higher detail.
|
|
94
97
|
- `showLegend` (default: `true`) - Show coordinate labels at corners.
|
|
98
|
+
- `listRectangles` (default: `true`) - List rectangles in the output.
|
|
95
99
|
- `startWithNewLine` (default: `true`) - Add a newline before the output.
|
|
96
100
|
|
|
97
101
|
```typescript
|
|
@@ -102,6 +106,11 @@ logRects(rectangles, {
|
|
|
102
106
|
});
|
|
103
107
|
```
|
|
104
108
|
|
|
109
|
+
```ts
|
|
110
|
+
const logString = getRectsLog(rectangles, { listRectangles: false });
|
|
111
|
+
console.log(logString);
|
|
112
|
+
```
|
|
113
|
+
|
|
105
114
|
## License
|
|
106
115
|
|
|
107
116
|
MIT
|
package/dist/index.cjs
CHANGED
|
@@ -4,7 +4,19 @@ const UP = 1;
|
|
|
4
4
|
const DOWN = 2;
|
|
5
5
|
const LEFT = 4;
|
|
6
6
|
const RIGHT = 8;
|
|
7
|
-
const STYLES = [
|
|
7
|
+
const STYLES = [
|
|
8
|
+
//
|
|
9
|
+
"heavy",
|
|
10
|
+
// ╹╻╸╺━┃┏┓┛┗┣┫┳┻┼
|
|
11
|
+
"light",
|
|
12
|
+
// ╵╷╴╶─│┌┐└┘├┤┬┴┼
|
|
13
|
+
"dashed",
|
|
14
|
+
// ╎╎╌╌╎┌┐└┘├┤┬┴┼
|
|
15
|
+
"dashed-heavy",
|
|
16
|
+
// ╏╏╍╍╏┏┓┛┗┣┫┳┻┼
|
|
17
|
+
"double"
|
|
18
|
+
// ║║═║╔╗╚╝╠╣╦╩╬
|
|
19
|
+
];
|
|
8
20
|
const STYLE_CHARS = {
|
|
9
21
|
light: {
|
|
10
22
|
[UP]: "╵",
|
|
@@ -92,9 +104,60 @@ const STYLE_CHARS = {
|
|
|
92
104
|
[UP | DOWN | LEFT | RIGHT]: "╋"
|
|
93
105
|
}
|
|
94
106
|
};
|
|
95
|
-
function
|
|
107
|
+
function maxBy(array, selector) {
|
|
108
|
+
return array.reduce((max, item) => {
|
|
109
|
+
const value = selector(item);
|
|
110
|
+
return value > max ? value : max;
|
|
111
|
+
}, -Infinity);
|
|
112
|
+
}
|
|
113
|
+
function createRectsDescriptions(rectangles) {
|
|
114
|
+
const maxNameLength = maxBy(rectangles, (rect) => rect.name.length);
|
|
115
|
+
const maxXLength = maxBy(rectangles, (rect) => rect.x.toString().length);
|
|
116
|
+
const maxYLength = maxBy(rectangles, (rect) => rect.y.toString().length);
|
|
117
|
+
const maxWidthLength = maxBy(rectangles, (rect) => rect.width.toString().length);
|
|
118
|
+
const maxHeightLength = maxBy(rectangles, (rect) => rect.height.toString().length);
|
|
119
|
+
const descriptions = rectangles.map((rect) => {
|
|
120
|
+
const name = rect.name.padEnd(maxNameLength, " ");
|
|
121
|
+
const x = rect.x.toString().padStart(maxXLength, " ");
|
|
122
|
+
const y = rect.y.toString().padStart(maxYLength, " ");
|
|
123
|
+
const width = rect.width.toString().padStart(maxWidthLength, " ");
|
|
124
|
+
const height = rect.height.toString().padStart(maxHeightLength, " ");
|
|
125
|
+
return `${name}: [${x}, ${y}, ${width}, ${height}]`;
|
|
126
|
+
});
|
|
127
|
+
descriptions.unshift(`Rectangles (${rectangles.length}):`);
|
|
128
|
+
return descriptions;
|
|
129
|
+
}
|
|
130
|
+
function addDescriptionsToLines(lines, descriptions, padding = 5) {
|
|
131
|
+
const longestLineLength = maxBy(lines, (line) => line.length);
|
|
132
|
+
for (let i = 0; i < descriptions.length; i++) {
|
|
133
|
+
if (i >= descriptions.length) break;
|
|
134
|
+
const line = lines[i] ?? "";
|
|
135
|
+
lines[i] = line.padEnd(longestLineLength + padding, " ");
|
|
136
|
+
lines[i] += descriptions[i];
|
|
137
|
+
}
|
|
138
|
+
return lines;
|
|
139
|
+
}
|
|
140
|
+
function getIsSet(value) {
|
|
141
|
+
return value !== null && value !== void 0;
|
|
142
|
+
}
|
|
143
|
+
function resolveInput(input) {
|
|
144
|
+
if (Array.isArray(input)) {
|
|
145
|
+
return input.filter(getIsSet).map((rect, index) => ({ ...rect, name: String(index) }));
|
|
146
|
+
}
|
|
147
|
+
return Object.entries(input).filter(([, rect]) => !!rect).map(([name, rect]) => ({ ...rect, name }));
|
|
148
|
+
}
|
|
149
|
+
function getRectsLog(input, {
|
|
150
|
+
sizePerPoint = 10,
|
|
151
|
+
showLegend = true,
|
|
152
|
+
listRectangles = true,
|
|
153
|
+
startWithNewLine = true,
|
|
154
|
+
adjustOutputHeight = true
|
|
155
|
+
} = {}) {
|
|
156
|
+
const rectangles = resolveInput(input);
|
|
157
|
+
const xSizePerPoint = sizePerPoint;
|
|
158
|
+
const ySizePerPoint = adjustOutputHeight ? sizePerPoint * 2 * 1.2 : sizePerPoint;
|
|
96
159
|
if (rectangles.length === 0) {
|
|
97
|
-
return
|
|
160
|
+
return null;
|
|
98
161
|
}
|
|
99
162
|
let minX = Infinity;
|
|
100
163
|
let minY = Infinity;
|
|
@@ -106,8 +169,8 @@ function logRects(rectangles, { sizePerPoint = 10, showLegend = true, dontLog =
|
|
|
106
169
|
maxX = Math.max(maxX, rect.x + rect.width);
|
|
107
170
|
maxY = Math.max(maxY, rect.y + rect.height);
|
|
108
171
|
}
|
|
109
|
-
const gridWidth = Math.ceil((maxX - minX) /
|
|
110
|
-
const gridHeight = Math.ceil((maxY - minY) /
|
|
172
|
+
const gridWidth = Math.ceil((maxX - minX) / xSizePerPoint);
|
|
173
|
+
const gridHeight = Math.ceil((maxY - minY) / ySizePerPoint);
|
|
111
174
|
const grid = Array.from(
|
|
112
175
|
{ length: gridHeight },
|
|
113
176
|
() => Array.from({ length: gridWidth }, () => ({ directions: 0, zIndex: -1 }))
|
|
@@ -140,16 +203,16 @@ function logRects(rectangles, { sizePerPoint = 10, showLegend = true, dontLog =
|
|
|
140
203
|
if (dirs) setCell(row, col, dirs, zIndex);
|
|
141
204
|
}
|
|
142
205
|
};
|
|
143
|
-
rectangles.forEach((rect,
|
|
144
|
-
const startCol = Math.floor((rect.x - minX) /
|
|
145
|
-
const startRow = Math.floor((rect.y - minY) /
|
|
146
|
-
const endCol = Math.ceil((rect.x + rect.width - minX) /
|
|
147
|
-
const endRow = Math.ceil((rect.y + rect.height - minY) /
|
|
148
|
-
drawHorizontal(startRow, startCol, endCol,
|
|
149
|
-
drawHorizontal(endRow, startCol, endCol,
|
|
150
|
-
drawVertical(startCol, startRow, endRow,
|
|
151
|
-
drawVertical(endCol, startRow, endRow,
|
|
152
|
-
const indexStr =
|
|
206
|
+
rectangles.forEach((rect, index) => {
|
|
207
|
+
const startCol = Math.floor((rect.x - minX) / xSizePerPoint);
|
|
208
|
+
const startRow = Math.floor((rect.y - minY) / ySizePerPoint);
|
|
209
|
+
const endCol = Math.ceil((rect.x + rect.width - minX) / xSizePerPoint) - 1;
|
|
210
|
+
const endRow = Math.ceil((rect.y + rect.height - minY) / ySizePerPoint) - 1;
|
|
211
|
+
drawHorizontal(startRow, startCol, endCol, index);
|
|
212
|
+
drawHorizontal(endRow, startCol, endCol, index);
|
|
213
|
+
drawVertical(startCol, startRow, endRow, index);
|
|
214
|
+
drawVertical(endCol, startRow, endRow, index);
|
|
215
|
+
const indexStr = rect.name;
|
|
153
216
|
const edgeWidth = endCol - startCol;
|
|
154
217
|
if (edgeWidth >= indexStr.length + 3) {
|
|
155
218
|
const innerWidth = edgeWidth - 1;
|
|
@@ -158,8 +221,8 @@ function logRects(rectangles, { sizePerPoint = 10, showLegend = true, dontLog =
|
|
|
158
221
|
const col = indexStart + i;
|
|
159
222
|
if (col >= 0 && col < gridWidth && startRow >= 0 && startRow < gridHeight) {
|
|
160
223
|
const existing = indexGrid[startRow][col];
|
|
161
|
-
if (!existing ||
|
|
162
|
-
indexGrid[startRow][col] = { char: indexStr[i], zIndex };
|
|
224
|
+
if (!existing || index >= existing.zIndex) {
|
|
225
|
+
indexGrid[startRow][col] = { char: indexStr[i], zIndex: index };
|
|
163
226
|
}
|
|
164
227
|
}
|
|
165
228
|
}
|
|
@@ -176,29 +239,40 @@ function logRects(rectangles, { sizePerPoint = 10, showLegend = true, dontLog =
|
|
|
176
239
|
return STYLE_CHARS[style][cell.directions] || "?";
|
|
177
240
|
})
|
|
178
241
|
);
|
|
179
|
-
|
|
242
|
+
if (charGrid[0][0] === " ") {
|
|
243
|
+
charGrid[0][0] = "•";
|
|
244
|
+
}
|
|
245
|
+
if (charGrid[charGrid.length - 1][charGrid[0].length - 1] === " ") {
|
|
246
|
+
charGrid[charGrid.length - 1][charGrid[0].length - 1] = "•";
|
|
247
|
+
}
|
|
248
|
+
let lines = [];
|
|
180
249
|
if (showLegend) {
|
|
181
250
|
const topLeftLabel = `[${minX}, ${minY}]`;
|
|
182
251
|
const bottomRightLabel = `[${maxX}, ${maxY}]`;
|
|
183
|
-
const padding = " ".repeat(topLeftLabel.length + 1);
|
|
184
252
|
lines.push(topLeftLabel);
|
|
185
253
|
for (const row of charGrid) {
|
|
186
|
-
lines.push(
|
|
254
|
+
lines.push(row.join(""));
|
|
187
255
|
}
|
|
188
|
-
|
|
256
|
+
const lastPadding = Math.max(0, gridWidth - bottomRightLabel.length);
|
|
257
|
+
lines.push(" ".repeat(lastPadding) + bottomRightLabel);
|
|
189
258
|
} else {
|
|
190
259
|
for (const row of charGrid) {
|
|
191
260
|
lines.push(row.join(""));
|
|
192
261
|
}
|
|
193
262
|
}
|
|
263
|
+
if (listRectangles) {
|
|
264
|
+
const descriptions = createRectsDescriptions(rectangles);
|
|
265
|
+
lines = addDescriptionsToLines(lines, descriptions);
|
|
266
|
+
}
|
|
194
267
|
if (startWithNewLine) {
|
|
195
268
|
lines.unshift("");
|
|
196
269
|
}
|
|
197
270
|
const output = lines.join("\n");
|
|
198
|
-
if (!dontLog) {
|
|
199
|
-
console.info(output);
|
|
200
|
-
}
|
|
201
271
|
return output;
|
|
202
272
|
}
|
|
273
|
+
function logRects(rectangles, options) {
|
|
274
|
+
console.info(getRectsLog(rectangles, options));
|
|
275
|
+
}
|
|
276
|
+
exports.getRectsLog = getRectsLog;
|
|
203
277
|
exports.logRects = logRects;
|
|
204
278
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":["../index.ts"],"sourcesContent":["interface Rectangle {\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\n// Direction bitmasks\nconst UP = 1;\nconst DOWN = 2;\nconst LEFT = 4;\nconst RIGHT = 8;\n\ntype LineStyle = \"light\" | \"heavy\" | \"double\" | \"dashed\" | \"dashed-heavy\";\n\nconst STYLES: LineStyle[] = [\"light\", \"heavy\", \"double\", \"dashed\", \"dashed-heavy\"];\n\n// Box-drawing character maps for each style\nconst STYLE_CHARS: Record<LineStyle, Record<number, string>> = {\n light: {\n [UP]: \"╵\",\n [DOWN]: \"╷\",\n [LEFT]: \"╴\",\n [RIGHT]: \"╶\",\n [LEFT | RIGHT]: \"─\",\n [UP | DOWN]: \"│\",\n [DOWN | RIGHT]: \"┌\",\n [DOWN | LEFT]: \"┐\",\n [UP | RIGHT]: \"└\",\n [UP | LEFT]: \"┘\",\n [UP | DOWN | RIGHT]: \"├\",\n [UP | DOWN | LEFT]: \"┤\",\n [LEFT | RIGHT | DOWN]: \"┬\",\n [LEFT | RIGHT | UP]: \"┴\",\n [UP | DOWN | LEFT | RIGHT]: \"┼\",\n },\n heavy: {\n [UP]: \"╹\",\n [DOWN]: \"╻\",\n [LEFT]: \"╸\",\n [RIGHT]: \"╺\",\n [LEFT | RIGHT]: \"━\",\n [UP | DOWN]: \"┃\",\n [DOWN | RIGHT]: \"┏\",\n [DOWN | LEFT]: \"┓\",\n [UP | RIGHT]: \"┗\",\n [UP | LEFT]: \"┛\",\n [UP | DOWN | RIGHT]: \"┣\",\n [UP | DOWN | LEFT]: \"┫\",\n [LEFT | RIGHT | DOWN]: \"┳\",\n [LEFT | RIGHT | UP]: \"┻\",\n [UP | DOWN | LEFT | RIGHT]: \"╋\",\n },\n double: {\n [UP]: \"║\",\n [DOWN]: \"║\",\n [LEFT]: \"═\",\n [RIGHT]: \"═\",\n [LEFT | RIGHT]: \"═\",\n [UP | DOWN]: \"║\",\n [DOWN | RIGHT]: \"╔\",\n [DOWN | LEFT]: \"╗\",\n [UP | RIGHT]: \"╚\",\n [UP | LEFT]: \"╝\",\n [UP | DOWN | RIGHT]: \"╠\",\n [UP | DOWN | LEFT]: \"╣\",\n [LEFT | RIGHT | DOWN]: \"╦\",\n [LEFT | RIGHT | UP]: \"╩\",\n [UP | DOWN | LEFT | RIGHT]: \"╬\",\n },\n dashed: {\n [UP]: \"╎\",\n [DOWN]: \"╎\",\n [LEFT]: \"╌\",\n [RIGHT]: \"╌\",\n [LEFT | RIGHT]: \"╌\",\n [UP | DOWN]: \"╎\",\n [DOWN | RIGHT]: \"┌\",\n [DOWN | LEFT]: \"┐\",\n [UP | RIGHT]: \"└\",\n [UP | LEFT]: \"┘\",\n [UP | DOWN | RIGHT]: \"├\",\n [UP | DOWN | LEFT]: \"┤\",\n [LEFT | RIGHT | DOWN]: \"┬\",\n [LEFT | RIGHT | UP]: \"┴\",\n [UP | DOWN | LEFT | RIGHT]: \"┼\",\n },\n \"dashed-heavy\": {\n [UP]: \"╏\",\n [DOWN]: \"╏\",\n [LEFT]: \"╍\",\n [RIGHT]: \"╍\",\n [LEFT | RIGHT]: \"╍\",\n [UP | DOWN]: \"╏\",\n [DOWN | RIGHT]: \"┏\",\n [DOWN | LEFT]: \"┓\",\n [UP | RIGHT]: \"┗\",\n [UP | LEFT]: \"┛\",\n [UP | DOWN | RIGHT]: \"┣\",\n [UP | DOWN | LEFT]: \"┫\",\n [LEFT | RIGHT | DOWN]: \"┳\",\n [LEFT | RIGHT | UP]: \"┻\",\n [UP | DOWN | LEFT | RIGHT]: \"╋\",\n },\n};\n\ninterface CellData {\n directions: number;\n zIndex: number;\n}\n\ninterface IndexData {\n char: string;\n zIndex: number;\n}\n\nexport interface LogRectsOptions {\n sizePerPoint?: number;\n showLegend?: boolean;\n dontLog?: boolean;\n startWithNewLine?: boolean;\n}\n\nexport function logRects(\n rectangles: Rectangle[],\n { sizePerPoint = 10, showLegend = true, dontLog = false, startWithNewLine = true }: LogRectsOptions = {}\n): string {\n if (rectangles.length === 0) {\n return \"No rectangles to draw\";\n }\n\n // Find bounding box of all rectangles\n let minX = Infinity;\n let minY = Infinity;\n let maxX = -Infinity;\n let maxY = -Infinity;\n\n for (const rect of rectangles) {\n minX = Math.min(minX, rect.x);\n minY = Math.min(minY, rect.y);\n maxX = Math.max(maxX, rect.x + rect.width);\n maxY = Math.max(maxY, rect.y + rect.height);\n }\n\n // Calculate grid dimensions based on resolution\n const gridWidth = Math.ceil((maxX - minX) / sizePerPoint);\n const gridHeight = Math.ceil((maxY - minY) / sizePerPoint);\n\n // Create grid to track directions and z-index at each cell\n const grid: CellData[][] = Array.from({ length: gridHeight }, () =>\n Array.from({ length: gridWidth }, () => ({ directions: 0, zIndex: -1 }))\n );\n\n // Create index overlay grid\n const indexGrid: (IndexData | null)[][] = Array.from({ length: gridHeight }, () => Array(gridWidth).fill(null));\n\n // Helper to set cell data with z-index awareness\n const setCell = (row: number, col: number, direction: number, zIndex: number) => {\n if (row < 0 || row >= gridHeight || col < 0 || col >= gridWidth) return;\n const cell = grid[row][col];\n if (zIndex >= cell.zIndex) {\n if (zIndex > cell.zIndex) {\n cell.directions = 0;\n cell.zIndex = zIndex;\n }\n cell.directions |= direction;\n }\n };\n\n // Helper to draw a horizontal line segment\n const drawHorizontal = (row: number, colStart: number, colEnd: number, zIndex: number) => {\n for (let col = colStart; col <= colEnd; col++) {\n let dirs = 0;\n if (col > colStart) dirs |= LEFT;\n if (col < colEnd) dirs |= RIGHT;\n if (dirs) setCell(row, col, dirs, zIndex);\n }\n };\n\n // Helper to draw a vertical line segment\n const drawVertical = (col: number, rowStart: number, rowEnd: number, zIndex: number) => {\n for (let row = rowStart; row <= rowEnd; row++) {\n let dirs = 0;\n if (row > rowStart) dirs |= UP;\n if (row < rowEnd) dirs |= DOWN;\n if (dirs) setCell(row, col, dirs, zIndex);\n }\n };\n\n // Draw each rectangle's outline with z-index = array index\n rectangles.forEach((rect, zIndex) => {\n const startCol = Math.floor((rect.x - minX) / sizePerPoint);\n const startRow = Math.floor((rect.y - minY) / sizePerPoint);\n const endCol = Math.ceil((rect.x + rect.width - minX) / sizePerPoint) - 1;\n const endRow = Math.ceil((rect.y + rect.height - minY) / sizePerPoint) - 1;\n\n // Draw the four edges\n drawHorizontal(startRow, startCol, endCol, zIndex);\n drawHorizontal(endRow, startCol, endCol, zIndex);\n drawVertical(startCol, startRow, endRow, zIndex);\n drawVertical(endCol, startRow, endRow, zIndex);\n\n // Place index at center of top edge if there's room\n const indexStr = String(zIndex);\n const edgeWidth = endCol - startCol; // number of segments (cells - 1)\n\n // Need at least 1 line char on each side of the index\n // Inner width (excluding corners) = edgeWidth - 1\n // Required: innerWidth >= indexStr.length + 2\n if (edgeWidth >= indexStr.length + 3) {\n const innerWidth = edgeWidth - 1;\n const indexStart = startCol + 1 + Math.floor((innerWidth - indexStr.length) / 2);\n\n for (let i = 0; i < indexStr.length; i++) {\n const col = indexStart + i;\n if (col >= 0 && col < gridWidth && startRow >= 0 && startRow < gridHeight) {\n const existing = indexGrid[startRow][col];\n if (!existing || zIndex >= existing.zIndex) {\n indexGrid[startRow][col] = { char: indexStr[i], zIndex };\n }\n }\n }\n }\n });\n\n // Convert cell data to characters, respecting z-index for both edges and indices\n const charGrid: string[][] = grid.map((row, rowIdx) =>\n row.map((cell, colIdx) => {\n const indexData = indexGrid[rowIdx][colIdx];\n\n // If there's an index with higher or equal z-index, use it\n if (indexData && indexData.zIndex >= cell.zIndex) {\n return indexData.char;\n }\n\n // Otherwise use edge character\n if (cell.directions === 0) return \" \";\n const style = STYLES[cell.zIndex % STYLES.length];\n return STYLE_CHARS[style][cell.directions] || \"?\";\n })\n );\n\n // Build output string\n const lines: string[] = [];\n\n if (showLegend) {\n const topLeftLabel = `[${minX}, ${minY}]`;\n const bottomRightLabel = `[${maxX}, ${maxY}]`;\n const padding = \" \".repeat(topLeftLabel.length + 1);\n\n lines.push(topLeftLabel);\n for (const row of charGrid) {\n lines.push(padding + row.join(\"\"));\n }\n lines.push(padding + \" \".repeat(gridWidth) + \" \" + bottomRightLabel);\n } else {\n for (const row of charGrid) {\n lines.push(row.join(\"\"));\n }\n }\n\n if (startWithNewLine) {\n lines.unshift(\"\");\n }\n\n const output = lines.join(\"\\n\");\n\n if (!dontLog) {\n console.info(output);\n }\n\n return output;\n}\n"],"names":[],"mappings":";;AAQA,MAAM,KAAK;AACX,MAAM,OAAO;AACb,MAAM,OAAO;AACb,MAAM,QAAQ;AAId,MAAM,SAAsB,CAAC,SAAS,SAAS,UAAU,UAAU,cAAc;AAGjF,MAAM,cAAyD;AAAA,EAC7D,OAAO;AAAA,IACL,CAAC,EAAE,GAAG;AAAA,IACN,CAAC,IAAI,GAAG;AAAA,IACR,CAAC,IAAI,GAAG;AAAA,IACR,CAAC,KAAK,GAAG;AAAA,IACT,CAAC,OAAO,KAAK,GAAG;AAAA,IAChB,CAAC,KAAK,IAAI,GAAG;AAAA,IACb,CAAC,OAAO,KAAK,GAAG;AAAA,IAChB,CAAC,OAAO,IAAI,GAAG;AAAA,IACf,CAAC,KAAK,KAAK,GAAG;AAAA,IACd,CAAC,KAAK,IAAI,GAAG;AAAA,IACb,CAAC,KAAK,OAAO,KAAK,GAAG;AAAA,IACrB,CAAC,KAAK,OAAO,IAAI,GAAG;AAAA,IACpB,CAAC,OAAO,QAAQ,IAAI,GAAG;AAAA,IACvB,CAAC,OAAO,QAAQ,EAAE,GAAG;AAAA,IACrB,CAAC,KAAK,OAAO,OAAO,KAAK,GAAG;AAAA,EAAA;AAAA,EAE9B,OAAO;AAAA,IACL,CAAC,EAAE,GAAG;AAAA,IACN,CAAC,IAAI,GAAG;AAAA,IACR,CAAC,IAAI,GAAG;AAAA,IACR,CAAC,KAAK,GAAG;AAAA,IACT,CAAC,OAAO,KAAK,GAAG;AAAA,IAChB,CAAC,KAAK,IAAI,GAAG;AAAA,IACb,CAAC,OAAO,KAAK,GAAG;AAAA,IAChB,CAAC,OAAO,IAAI,GAAG;AAAA,IACf,CAAC,KAAK,KAAK,GAAG;AAAA,IACd,CAAC,KAAK,IAAI,GAAG;AAAA,IACb,CAAC,KAAK,OAAO,KAAK,GAAG;AAAA,IACrB,CAAC,KAAK,OAAO,IAAI,GAAG;AAAA,IACpB,CAAC,OAAO,QAAQ,IAAI,GAAG;AAAA,IACvB,CAAC,OAAO,QAAQ,EAAE,GAAG;AAAA,IACrB,CAAC,KAAK,OAAO,OAAO,KAAK,GAAG;AAAA,EAAA;AAAA,EAE9B,QAAQ;AAAA,IACN,CAAC,EAAE,GAAG;AAAA,IACN,CAAC,IAAI,GAAG;AAAA,IACR,CAAC,IAAI,GAAG;AAAA,IACR,CAAC,KAAK,GAAG;AAAA,IACT,CAAC,OAAO,KAAK,GAAG;AAAA,IAChB,CAAC,KAAK,IAAI,GAAG;AAAA,IACb,CAAC,OAAO,KAAK,GAAG;AAAA,IAChB,CAAC,OAAO,IAAI,GAAG;AAAA,IACf,CAAC,KAAK,KAAK,GAAG;AAAA,IACd,CAAC,KAAK,IAAI,GAAG;AAAA,IACb,CAAC,KAAK,OAAO,KAAK,GAAG;AAAA,IACrB,CAAC,KAAK,OAAO,IAAI,GAAG;AAAA,IACpB,CAAC,OAAO,QAAQ,IAAI,GAAG;AAAA,IACvB,CAAC,OAAO,QAAQ,EAAE,GAAG;AAAA,IACrB,CAAC,KAAK,OAAO,OAAO,KAAK,GAAG;AAAA,EAAA;AAAA,EAE9B,QAAQ;AAAA,IACN,CAAC,EAAE,GAAG;AAAA,IACN,CAAC,IAAI,GAAG;AAAA,IACR,CAAC,IAAI,GAAG;AAAA,IACR,CAAC,KAAK,GAAG;AAAA,IACT,CAAC,OAAO,KAAK,GAAG;AAAA,IAChB,CAAC,KAAK,IAAI,GAAG;AAAA,IACb,CAAC,OAAO,KAAK,GAAG;AAAA,IAChB,CAAC,OAAO,IAAI,GAAG;AAAA,IACf,CAAC,KAAK,KAAK,GAAG;AAAA,IACd,CAAC,KAAK,IAAI,GAAG;AAAA,IACb,CAAC,KAAK,OAAO,KAAK,GAAG;AAAA,IACrB,CAAC,KAAK,OAAO,IAAI,GAAG;AAAA,IACpB,CAAC,OAAO,QAAQ,IAAI,GAAG;AAAA,IACvB,CAAC,OAAO,QAAQ,EAAE,GAAG;AAAA,IACrB,CAAC,KAAK,OAAO,OAAO,KAAK,GAAG;AAAA,EAAA;AAAA,EAE9B,gBAAgB;AAAA,IACd,CAAC,EAAE,GAAG;AAAA,IACN,CAAC,IAAI,GAAG;AAAA,IACR,CAAC,IAAI,GAAG;AAAA,IACR,CAAC,KAAK,GAAG;AAAA,IACT,CAAC,OAAO,KAAK,GAAG;AAAA,IAChB,CAAC,KAAK,IAAI,GAAG;AAAA,IACb,CAAC,OAAO,KAAK,GAAG;AAAA,IAChB,CAAC,OAAO,IAAI,GAAG;AAAA,IACf,CAAC,KAAK,KAAK,GAAG;AAAA,IACd,CAAC,KAAK,IAAI,GAAG;AAAA,IACb,CAAC,KAAK,OAAO,KAAK,GAAG;AAAA,IACrB,CAAC,KAAK,OAAO,IAAI,GAAG;AAAA,IACpB,CAAC,OAAO,QAAQ,IAAI,GAAG;AAAA,IACvB,CAAC,OAAO,QAAQ,EAAE,GAAG;AAAA,IACrB,CAAC,KAAK,OAAO,OAAO,KAAK,GAAG;AAAA,EAAA;AAEhC;AAmBO,SAAS,SACd,YACA,EAAE,eAAe,IAAI,aAAa,MAAM,UAAU,OAAO,mBAAmB,KAAA,IAA0B,CAAA,GAC9F;AACR,MAAI,WAAW,WAAW,GAAG;AAC3B,WAAO;AAAA,EACT;AAGA,MAAI,OAAO;AACX,MAAI,OAAO;AACX,MAAI,OAAO;AACX,MAAI,OAAO;AAEX,aAAW,QAAQ,YAAY;AAC7B,WAAO,KAAK,IAAI,MAAM,KAAK,CAAC;AAC5B,WAAO,KAAK,IAAI,MAAM,KAAK,CAAC;AAC5B,WAAO,KAAK,IAAI,MAAM,KAAK,IAAI,KAAK,KAAK;AACzC,WAAO,KAAK,IAAI,MAAM,KAAK,IAAI,KAAK,MAAM;AAAA,EAC5C;AAGA,QAAM,YAAY,KAAK,MAAM,OAAO,QAAQ,YAAY;AACxD,QAAM,aAAa,KAAK,MAAM,OAAO,QAAQ,YAAY;AAGzD,QAAM,OAAqB,MAAM;AAAA,IAAK,EAAE,QAAQ,WAAA;AAAA,IAAc,MAC5D,MAAM,KAAK,EAAE,QAAQ,UAAA,GAAa,OAAO,EAAE,YAAY,GAAG,QAAQ,KAAK;AAAA,EAAA;AAIzE,QAAM,YAAoC,MAAM,KAAK,EAAE,QAAQ,cAAc,MAAM,MAAM,SAAS,EAAE,KAAK,IAAI,CAAC;AAG9G,QAAM,UAAU,CAAC,KAAa,KAAa,WAAmB,WAAmB;AAC/E,QAAI,MAAM,KAAK,OAAO,cAAc,MAAM,KAAK,OAAO,UAAW;AACjE,UAAM,OAAO,KAAK,GAAG,EAAE,GAAG;AAC1B,QAAI,UAAU,KAAK,QAAQ;AACzB,UAAI,SAAS,KAAK,QAAQ;AACxB,aAAK,aAAa;AAClB,aAAK,SAAS;AAAA,MAChB;AACA,WAAK,cAAc;AAAA,IACrB;AAAA,EACF;AAGA,QAAM,iBAAiB,CAAC,KAAa,UAAkB,QAAgB,WAAmB;AACxF,aAAS,MAAM,UAAU,OAAO,QAAQ,OAAO;AAC7C,UAAI,OAAO;AACX,UAAI,MAAM,SAAU,SAAQ;AAC5B,UAAI,MAAM,OAAQ,SAAQ;AAC1B,UAAI,KAAM,SAAQ,KAAK,KAAK,MAAM,MAAM;AAAA,IAC1C;AAAA,EACF;AAGA,QAAM,eAAe,CAAC,KAAa,UAAkB,QAAgB,WAAmB;AACtF,aAAS,MAAM,UAAU,OAAO,QAAQ,OAAO;AAC7C,UAAI,OAAO;AACX,UAAI,MAAM,SAAU,SAAQ;AAC5B,UAAI,MAAM,OAAQ,SAAQ;AAC1B,UAAI,KAAM,SAAQ,KAAK,KAAK,MAAM,MAAM;AAAA,IAC1C;AAAA,EACF;AAGA,aAAW,QAAQ,CAAC,MAAM,WAAW;AACnC,UAAM,WAAW,KAAK,OAAO,KAAK,IAAI,QAAQ,YAAY;AAC1D,UAAM,WAAW,KAAK,OAAO,KAAK,IAAI,QAAQ,YAAY;AAC1D,UAAM,SAAS,KAAK,MAAM,KAAK,IAAI,KAAK,QAAQ,QAAQ,YAAY,IAAI;AACxE,UAAM,SAAS,KAAK,MAAM,KAAK,IAAI,KAAK,SAAS,QAAQ,YAAY,IAAI;AAGzE,mBAAe,UAAU,UAAU,QAAQ,MAAM;AACjD,mBAAe,QAAQ,UAAU,QAAQ,MAAM;AAC/C,iBAAa,UAAU,UAAU,QAAQ,MAAM;AAC/C,iBAAa,QAAQ,UAAU,QAAQ,MAAM;AAG7C,UAAM,WAAW,OAAO,MAAM;AAC9B,UAAM,YAAY,SAAS;AAK3B,QAAI,aAAa,SAAS,SAAS,GAAG;AACpC,YAAM,aAAa,YAAY;AAC/B,YAAM,aAAa,WAAW,IAAI,KAAK,OAAO,aAAa,SAAS,UAAU,CAAC;AAE/E,eAAS,IAAI,GAAG,IAAI,SAAS,QAAQ,KAAK;AACxC,cAAM,MAAM,aAAa;AACzB,YAAI,OAAO,KAAK,MAAM,aAAa,YAAY,KAAK,WAAW,YAAY;AACzE,gBAAM,WAAW,UAAU,QAAQ,EAAE,GAAG;AACxC,cAAI,CAAC,YAAY,UAAU,SAAS,QAAQ;AAC1C,sBAAU,QAAQ,EAAE,GAAG,IAAI,EAAE,MAAM,SAAS,CAAC,GAAG,OAAA;AAAA,UAClD;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF,CAAC;AAGD,QAAM,WAAuB,KAAK;AAAA,IAAI,CAAC,KAAK,WAC1C,IAAI,IAAI,CAAC,MAAM,WAAW;AACxB,YAAM,YAAY,UAAU,MAAM,EAAE,MAAM;AAG1C,UAAI,aAAa,UAAU,UAAU,KAAK,QAAQ;AAChD,eAAO,UAAU;AAAA,MACnB;AAGA,UAAI,KAAK,eAAe,EAAG,QAAO;AAClC,YAAM,QAAQ,OAAO,KAAK,SAAS,OAAO,MAAM;AAChD,aAAO,YAAY,KAAK,EAAE,KAAK,UAAU,KAAK;AAAA,IAChD,CAAC;AAAA,EAAA;AAIH,QAAM,QAAkB,CAAA;AAExB,MAAI,YAAY;AACd,UAAM,eAAe,IAAI,IAAI,KAAK,IAAI;AACtC,UAAM,mBAAmB,IAAI,IAAI,KAAK,IAAI;AAC1C,UAAM,UAAU,IAAI,OAAO,aAAa,SAAS,CAAC;AAElD,UAAM,KAAK,YAAY;AACvB,eAAW,OAAO,UAAU;AAC1B,YAAM,KAAK,UAAU,IAAI,KAAK,EAAE,CAAC;AAAA,IACnC;AACA,UAAM,KAAK,UAAU,IAAI,OAAO,SAAS,IAAI,MAAM,gBAAgB;AAAA,EACrE,OAAO;AACL,eAAW,OAAO,UAAU;AAC1B,YAAM,KAAK,IAAI,KAAK,EAAE,CAAC;AAAA,IACzB;AAAA,EACF;AAEA,MAAI,kBAAkB;AACpB,UAAM,QAAQ,EAAE;AAAA,EAClB;AAEA,QAAM,SAAS,MAAM,KAAK,IAAI;AAE9B,MAAI,CAAC,SAAS;AACZ,YAAQ,KAAK,MAAM;AAAA,EACrB;AAEA,SAAO;AACT;;"}
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../index.ts"],"sourcesContent":["interface Rectangle {\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\n// Direction bitmasks\nconst UP = 1;\nconst DOWN = 2;\nconst LEFT = 4;\nconst RIGHT = 8;\n\ntype LineStyle = \"light\" | \"heavy\" | \"double\" | \"dashed\" | \"dashed-heavy\";\n\nconst STYLES: LineStyle[] = [\n //\n \"heavy\", // ╹╻╸╺━┃┏┓┛┗┣┫┳┻┼\n \"light\", // ╵╷╴╶─│┌┐└┘├┤┬┴┼\n \"dashed\", // ╎╎╌╌╎┌┐└┘├┤┬┴┼\n \"dashed-heavy\", // ╏╏╍╍╏┏┓┛┗┣┫┳┻┼\n \"double\", // ║║═║╔╗╚╝╠╣╦╩╬\n];\n\n// Box-drawing character maps for each style\nconst STYLE_CHARS: Record<LineStyle, Record<number, string>> = {\n light: {\n [UP]: \"╵\",\n [DOWN]: \"╷\",\n [LEFT]: \"╴\",\n [RIGHT]: \"╶\",\n [LEFT | RIGHT]: \"─\",\n [UP | DOWN]: \"│\",\n [DOWN | RIGHT]: \"┌\",\n [DOWN | LEFT]: \"┐\",\n [UP | RIGHT]: \"└\",\n [UP | LEFT]: \"┘\",\n [UP | DOWN | RIGHT]: \"├\",\n [UP | DOWN | LEFT]: \"┤\",\n [LEFT | RIGHT | DOWN]: \"┬\",\n [LEFT | RIGHT | UP]: \"┴\",\n [UP | DOWN | LEFT | RIGHT]: \"┼\",\n },\n heavy: {\n [UP]: \"╹\",\n [DOWN]: \"╻\",\n [LEFT]: \"╸\",\n [RIGHT]: \"╺\",\n [LEFT | RIGHT]: \"━\",\n [UP | DOWN]: \"┃\",\n [DOWN | RIGHT]: \"┏\",\n [DOWN | LEFT]: \"┓\",\n [UP | RIGHT]: \"┗\",\n [UP | LEFT]: \"┛\",\n [UP | DOWN | RIGHT]: \"┣\",\n [UP | DOWN | LEFT]: \"┫\",\n [LEFT | RIGHT | DOWN]: \"┳\",\n [LEFT | RIGHT | UP]: \"┻\",\n [UP | DOWN | LEFT | RIGHT]: \"╋\",\n },\n double: {\n [UP]: \"║\",\n [DOWN]: \"║\",\n [LEFT]: \"═\",\n [RIGHT]: \"═\",\n [LEFT | RIGHT]: \"═\",\n [UP | DOWN]: \"║\",\n [DOWN | RIGHT]: \"╔\",\n [DOWN | LEFT]: \"╗\",\n [UP | RIGHT]: \"╚\",\n [UP | LEFT]: \"╝\",\n [UP | DOWN | RIGHT]: \"╠\",\n [UP | DOWN | LEFT]: \"╣\",\n [LEFT | RIGHT | DOWN]: \"╦\",\n [LEFT | RIGHT | UP]: \"╩\",\n [UP | DOWN | LEFT | RIGHT]: \"╬\",\n },\n dashed: {\n [UP]: \"╎\",\n [DOWN]: \"╎\",\n [LEFT]: \"╌\",\n [RIGHT]: \"╌\",\n [LEFT | RIGHT]: \"╌\",\n [UP | DOWN]: \"╎\",\n [DOWN | RIGHT]: \"┌\",\n [DOWN | LEFT]: \"┐\",\n [UP | RIGHT]: \"└\",\n [UP | LEFT]: \"┘\",\n [UP | DOWN | RIGHT]: \"├\",\n [UP | DOWN | LEFT]: \"┤\",\n [LEFT | RIGHT | DOWN]: \"┬\",\n [LEFT | RIGHT | UP]: \"┴\",\n [UP | DOWN | LEFT | RIGHT]: \"┼\",\n },\n \"dashed-heavy\": {\n [UP]: \"╏\",\n [DOWN]: \"╏\",\n [LEFT]: \"╍\",\n [RIGHT]: \"╍\",\n [LEFT | RIGHT]: \"╍\",\n [UP | DOWN]: \"╏\",\n [DOWN | RIGHT]: \"┏\",\n [DOWN | LEFT]: \"┓\",\n [UP | RIGHT]: \"┗\",\n [UP | LEFT]: \"┛\",\n [UP | DOWN | RIGHT]: \"┣\",\n [UP | DOWN | LEFT]: \"┫\",\n [LEFT | RIGHT | DOWN]: \"┳\",\n [LEFT | RIGHT | UP]: \"┻\",\n [UP | DOWN | LEFT | RIGHT]: \"╋\",\n },\n};\n\ninterface CellData {\n directions: number;\n zIndex: number;\n}\n\ninterface IndexData {\n char: string;\n zIndex: number;\n}\n\nexport interface LogRectsOptions {\n sizePerPoint?: number;\n showLegend?: boolean;\n listRectangles?: boolean;\n startWithNewLine?: boolean;\n adjustOutputHeight?: boolean;\n}\n\nfunction maxBy<T>(array: T[], selector: (item: T) => number): number {\n return array.reduce((max, item) => {\n const value = selector(item);\n return value > max ? value : max;\n }, -Infinity);\n}\n\nfunction createRectsDescriptions(rectangles: NamedRectangle[]) {\n const maxNameLength = maxBy(rectangles, (rect) => rect.name.length);\n const maxXLength = maxBy(rectangles, (rect) => rect.x.toString().length);\n const maxYLength = maxBy(rectangles, (rect) => rect.y.toString().length);\n const maxWidthLength = maxBy(rectangles, (rect) => rect.width.toString().length);\n const maxHeightLength = maxBy(rectangles, (rect) => rect.height.toString().length);\n\n const descriptions = rectangles.map((rect) => {\n const name = rect.name.padEnd(maxNameLength, \" \");\n const x = rect.x.toString().padStart(maxXLength, \" \");\n const y = rect.y.toString().padStart(maxYLength, \" \");\n const width = rect.width.toString().padStart(maxWidthLength, \" \");\n const height = rect.height.toString().padStart(maxHeightLength, \" \");\n return `${name}: [${x}, ${y}, ${width}, ${height}]`;\n });\n\n descriptions.unshift(`Rectangles (${rectangles.length}):`);\n\n return descriptions;\n}\n\nfunction addDescriptionsToLines(lines: string[], descriptions: string[], padding: number = 5) {\n const longestLineLength = maxBy(lines, (line) => line.length);\n for (let i = 0; i < descriptions.length; i++) {\n if (i >= descriptions.length) break;\n\n const line = lines[i] ?? \"\";\n\n lines[i] = line.padEnd(longestLineLength + padding, \" \");\n lines[i] += descriptions[i];\n }\n return lines;\n}\n\ntype Maybe<T> = T | null | undefined;\n\nexport type RectsLogInput = Array<Maybe<Rectangle>> | Record<string, Maybe<Rectangle>>;\n\nfunction getIsSet<T>(value: Maybe<T>): value is T {\n return value !== null && value !== undefined;\n}\n\ninterface NamedRectangle extends Rectangle {\n name: string;\n}\n\nfunction resolveInput(input: RectsLogInput): NamedRectangle[] {\n if (Array.isArray(input)) {\n return input.filter(getIsSet).map((rect, index) => ({ ...rect, name: String(index) }));\n }\n\n return Object.entries(input)\n .filter(([, rect]) => !!rect)\n .map(([name, rect]) => ({ ...rect!, name }));\n}\n\nexport function getRectsLog(\n input: RectsLogInput,\n {\n sizePerPoint = 10,\n showLegend = true,\n listRectangles = true,\n startWithNewLine = true,\n adjustOutputHeight = true,\n }: LogRectsOptions = {}\n): string | null {\n const rectangles = resolveInput(input);\n\n const xSizePerPoint = sizePerPoint;\n const ySizePerPoint = adjustOutputHeight ? sizePerPoint * 2 * 1.2 : sizePerPoint;\n\n if (rectangles.length === 0) {\n return null;\n }\n\n // Find bounding box of all rectangles\n let minX = Infinity;\n let minY = Infinity;\n let maxX = -Infinity;\n let maxY = -Infinity;\n\n for (const rect of rectangles) {\n minX = Math.min(minX, rect.x);\n minY = Math.min(minY, rect.y);\n maxX = Math.max(maxX, rect.x + rect.width);\n maxY = Math.max(maxY, rect.y + rect.height);\n }\n\n // Calculate grid dimensions based on resolution\n const gridWidth = Math.ceil((maxX - minX) / xSizePerPoint);\n const gridHeight = Math.ceil((maxY - minY) / ySizePerPoint);\n\n // Create grid to track directions and z-index at each cell\n const grid: CellData[][] = Array.from({ length: gridHeight }, () =>\n Array.from({ length: gridWidth }, () => ({ directions: 0, zIndex: -1 }))\n );\n\n // Create index overlay grid\n const indexGrid: (IndexData | null)[][] = Array.from({ length: gridHeight }, () => Array(gridWidth).fill(null));\n\n // Helper to set cell data with z-index awareness\n const setCell = (row: number, col: number, direction: number, zIndex: number) => {\n if (row < 0 || row >= gridHeight || col < 0 || col >= gridWidth) return;\n const cell = grid[row][col];\n if (zIndex >= cell.zIndex) {\n if (zIndex > cell.zIndex) {\n cell.directions = 0;\n cell.zIndex = zIndex;\n }\n cell.directions |= direction;\n }\n };\n\n // Helper to draw a horizontal line segment\n const drawHorizontal = (row: number, colStart: number, colEnd: number, zIndex: number) => {\n for (let col = colStart; col <= colEnd; col++) {\n let dirs = 0;\n if (col > colStart) dirs |= LEFT;\n if (col < colEnd) dirs |= RIGHT;\n if (dirs) setCell(row, col, dirs, zIndex);\n }\n };\n\n // Helper to draw a vertical line segment\n const drawVertical = (col: number, rowStart: number, rowEnd: number, zIndex: number) => {\n for (let row = rowStart; row <= rowEnd; row++) {\n let dirs = 0;\n if (row > rowStart) dirs |= UP;\n if (row < rowEnd) dirs |= DOWN;\n if (dirs) setCell(row, col, dirs, zIndex);\n }\n };\n\n // Draw each rectangle's outline with z-index = array index\n rectangles.forEach((rect, index) => {\n const startCol = Math.floor((rect.x - minX) / xSizePerPoint);\n const startRow = Math.floor((rect.y - minY) / ySizePerPoint);\n const endCol = Math.ceil((rect.x + rect.width - minX) / xSizePerPoint) - 1;\n const endRow = Math.ceil((rect.y + rect.height - minY) / ySizePerPoint) - 1;\n\n // Draw the four edges\n drawHorizontal(startRow, startCol, endCol, index);\n drawHorizontal(endRow, startCol, endCol, index);\n drawVertical(startCol, startRow, endRow, index);\n drawVertical(endCol, startRow, endRow, index);\n\n // Place index at center of top edge if there's room\n const indexStr = rect.name;\n const edgeWidth = endCol - startCol; // number of segments (cells - 1)\n\n // Need at least 1 line char on each side of the index\n // Inner width (excluding corners) = edgeWidth - 1\n // Required: innerWidth >= indexStr.length + 2\n if (edgeWidth >= indexStr.length + 3) {\n const innerWidth = edgeWidth - 1;\n const indexStart = startCol + 1 + Math.floor((innerWidth - indexStr.length) / 2);\n\n for (let i = 0; i < indexStr.length; i++) {\n const col = indexStart + i;\n if (col >= 0 && col < gridWidth && startRow >= 0 && startRow < gridHeight) {\n const existing = indexGrid[startRow][col];\n if (!existing || index >= existing.zIndex) {\n indexGrid[startRow][col] = { char: indexStr[i], zIndex: index };\n }\n }\n }\n }\n });\n\n // Convert cell data to characters, respecting z-index for both edges and indices\n const charGrid: string[][] = grid.map((row, rowIdx) =>\n row.map((cell, colIdx) => {\n const indexData = indexGrid[rowIdx][colIdx];\n\n // If there's an index with higher or equal z-index, use it\n if (indexData && indexData.zIndex >= cell.zIndex) {\n return indexData.char;\n }\n\n // Otherwise use edge character\n if (cell.directions === 0) return \" \";\n const style = STYLES[cell.zIndex % STYLES.length];\n return STYLE_CHARS[style][cell.directions] || \"?\";\n })\n );\n\n const CORNER_CHAR_DOT_ASCII = \"•\";\n\n if (charGrid[0][0] === \" \") {\n charGrid[0][0] = \"•\";\n }\n\n if (charGrid[charGrid.length - 1][charGrid[0].length - 1] === \" \") {\n charGrid[charGrid.length - 1][charGrid[0].length - 1] = \"•\";\n }\n\n // Build output string\n let lines: string[] = [];\n\n if (showLegend) {\n const topLeftLabel = `[${minX}, ${minY}]`;\n const bottomRightLabel = `[${maxX}, ${maxY}]`;\n\n lines.push(topLeftLabel);\n for (const row of charGrid) {\n lines.push(row.join(\"\"));\n }\n const lastPadding = Math.max(0, gridWidth - bottomRightLabel.length);\n lines.push(\" \".repeat(lastPadding) + bottomRightLabel);\n } else {\n for (const row of charGrid) {\n lines.push(row.join(\"\"));\n }\n }\n\n if (listRectangles) {\n const descriptions = createRectsDescriptions(rectangles);\n lines = addDescriptionsToLines(lines, descriptions);\n }\n\n if (startWithNewLine) {\n lines.unshift(\"\");\n }\n\n const output = lines.join(\"\\n\");\n\n return output;\n}\n\nexport function logRects(rectangles: Rectangle[], options?: LogRectsOptions): void {\n console.info(getRectsLog(rectangles, options));\n}\n"],"names":[],"mappings":"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"}
|
package/dist/index.mjs
CHANGED
|
@@ -2,7 +2,19 @@ const UP = 1;
|
|
|
2
2
|
const DOWN = 2;
|
|
3
3
|
const LEFT = 4;
|
|
4
4
|
const RIGHT = 8;
|
|
5
|
-
const STYLES = [
|
|
5
|
+
const STYLES = [
|
|
6
|
+
//
|
|
7
|
+
"heavy",
|
|
8
|
+
// ╹╻╸╺━┃┏┓┛┗┣┫┳┻┼
|
|
9
|
+
"light",
|
|
10
|
+
// ╵╷╴╶─│┌┐└┘├┤┬┴┼
|
|
11
|
+
"dashed",
|
|
12
|
+
// ╎╎╌╌╎┌┐└┘├┤┬┴┼
|
|
13
|
+
"dashed-heavy",
|
|
14
|
+
// ╏╏╍╍╏┏┓┛┗┣┫┳┻┼
|
|
15
|
+
"double"
|
|
16
|
+
// ║║═║╔╗╚╝╠╣╦╩╬
|
|
17
|
+
];
|
|
6
18
|
const STYLE_CHARS = {
|
|
7
19
|
light: {
|
|
8
20
|
[UP]: "╵",
|
|
@@ -90,9 +102,60 @@ const STYLE_CHARS = {
|
|
|
90
102
|
[UP | DOWN | LEFT | RIGHT]: "╋"
|
|
91
103
|
}
|
|
92
104
|
};
|
|
93
|
-
function
|
|
105
|
+
function maxBy(array, selector) {
|
|
106
|
+
return array.reduce((max, item) => {
|
|
107
|
+
const value = selector(item);
|
|
108
|
+
return value > max ? value : max;
|
|
109
|
+
}, -Infinity);
|
|
110
|
+
}
|
|
111
|
+
function createRectsDescriptions(rectangles) {
|
|
112
|
+
const maxNameLength = maxBy(rectangles, (rect) => rect.name.length);
|
|
113
|
+
const maxXLength = maxBy(rectangles, (rect) => rect.x.toString().length);
|
|
114
|
+
const maxYLength = maxBy(rectangles, (rect) => rect.y.toString().length);
|
|
115
|
+
const maxWidthLength = maxBy(rectangles, (rect) => rect.width.toString().length);
|
|
116
|
+
const maxHeightLength = maxBy(rectangles, (rect) => rect.height.toString().length);
|
|
117
|
+
const descriptions = rectangles.map((rect) => {
|
|
118
|
+
const name = rect.name.padEnd(maxNameLength, " ");
|
|
119
|
+
const x = rect.x.toString().padStart(maxXLength, " ");
|
|
120
|
+
const y = rect.y.toString().padStart(maxYLength, " ");
|
|
121
|
+
const width = rect.width.toString().padStart(maxWidthLength, " ");
|
|
122
|
+
const height = rect.height.toString().padStart(maxHeightLength, " ");
|
|
123
|
+
return `${name}: [${x}, ${y}, ${width}, ${height}]`;
|
|
124
|
+
});
|
|
125
|
+
descriptions.unshift(`Rectangles (${rectangles.length}):`);
|
|
126
|
+
return descriptions;
|
|
127
|
+
}
|
|
128
|
+
function addDescriptionsToLines(lines, descriptions, padding = 5) {
|
|
129
|
+
const longestLineLength = maxBy(lines, (line) => line.length);
|
|
130
|
+
for (let i = 0; i < descriptions.length; i++) {
|
|
131
|
+
if (i >= descriptions.length) break;
|
|
132
|
+
const line = lines[i] ?? "";
|
|
133
|
+
lines[i] = line.padEnd(longestLineLength + padding, " ");
|
|
134
|
+
lines[i] += descriptions[i];
|
|
135
|
+
}
|
|
136
|
+
return lines;
|
|
137
|
+
}
|
|
138
|
+
function getIsSet(value) {
|
|
139
|
+
return value !== null && value !== void 0;
|
|
140
|
+
}
|
|
141
|
+
function resolveInput(input) {
|
|
142
|
+
if (Array.isArray(input)) {
|
|
143
|
+
return input.filter(getIsSet).map((rect, index) => ({ ...rect, name: String(index) }));
|
|
144
|
+
}
|
|
145
|
+
return Object.entries(input).filter(([, rect]) => !!rect).map(([name, rect]) => ({ ...rect, name }));
|
|
146
|
+
}
|
|
147
|
+
function getRectsLog(input, {
|
|
148
|
+
sizePerPoint = 10,
|
|
149
|
+
showLegend = true,
|
|
150
|
+
listRectangles = true,
|
|
151
|
+
startWithNewLine = true,
|
|
152
|
+
adjustOutputHeight = true
|
|
153
|
+
} = {}) {
|
|
154
|
+
const rectangles = resolveInput(input);
|
|
155
|
+
const xSizePerPoint = sizePerPoint;
|
|
156
|
+
const ySizePerPoint = adjustOutputHeight ? sizePerPoint * 2 * 1.2 : sizePerPoint;
|
|
94
157
|
if (rectangles.length === 0) {
|
|
95
|
-
return
|
|
158
|
+
return null;
|
|
96
159
|
}
|
|
97
160
|
let minX = Infinity;
|
|
98
161
|
let minY = Infinity;
|
|
@@ -104,8 +167,8 @@ function logRects(rectangles, { sizePerPoint = 10, showLegend = true, dontLog =
|
|
|
104
167
|
maxX = Math.max(maxX, rect.x + rect.width);
|
|
105
168
|
maxY = Math.max(maxY, rect.y + rect.height);
|
|
106
169
|
}
|
|
107
|
-
const gridWidth = Math.ceil((maxX - minX) /
|
|
108
|
-
const gridHeight = Math.ceil((maxY - minY) /
|
|
170
|
+
const gridWidth = Math.ceil((maxX - minX) / xSizePerPoint);
|
|
171
|
+
const gridHeight = Math.ceil((maxY - minY) / ySizePerPoint);
|
|
109
172
|
const grid = Array.from(
|
|
110
173
|
{ length: gridHeight },
|
|
111
174
|
() => Array.from({ length: gridWidth }, () => ({ directions: 0, zIndex: -1 }))
|
|
@@ -138,16 +201,16 @@ function logRects(rectangles, { sizePerPoint = 10, showLegend = true, dontLog =
|
|
|
138
201
|
if (dirs) setCell(row, col, dirs, zIndex);
|
|
139
202
|
}
|
|
140
203
|
};
|
|
141
|
-
rectangles.forEach((rect,
|
|
142
|
-
const startCol = Math.floor((rect.x - minX) /
|
|
143
|
-
const startRow = Math.floor((rect.y - minY) /
|
|
144
|
-
const endCol = Math.ceil((rect.x + rect.width - minX) /
|
|
145
|
-
const endRow = Math.ceil((rect.y + rect.height - minY) /
|
|
146
|
-
drawHorizontal(startRow, startCol, endCol,
|
|
147
|
-
drawHorizontal(endRow, startCol, endCol,
|
|
148
|
-
drawVertical(startCol, startRow, endRow,
|
|
149
|
-
drawVertical(endCol, startRow, endRow,
|
|
150
|
-
const indexStr =
|
|
204
|
+
rectangles.forEach((rect, index) => {
|
|
205
|
+
const startCol = Math.floor((rect.x - minX) / xSizePerPoint);
|
|
206
|
+
const startRow = Math.floor((rect.y - minY) / ySizePerPoint);
|
|
207
|
+
const endCol = Math.ceil((rect.x + rect.width - minX) / xSizePerPoint) - 1;
|
|
208
|
+
const endRow = Math.ceil((rect.y + rect.height - minY) / ySizePerPoint) - 1;
|
|
209
|
+
drawHorizontal(startRow, startCol, endCol, index);
|
|
210
|
+
drawHorizontal(endRow, startCol, endCol, index);
|
|
211
|
+
drawVertical(startCol, startRow, endRow, index);
|
|
212
|
+
drawVertical(endCol, startRow, endRow, index);
|
|
213
|
+
const indexStr = rect.name;
|
|
151
214
|
const edgeWidth = endCol - startCol;
|
|
152
215
|
if (edgeWidth >= indexStr.length + 3) {
|
|
153
216
|
const innerWidth = edgeWidth - 1;
|
|
@@ -156,8 +219,8 @@ function logRects(rectangles, { sizePerPoint = 10, showLegend = true, dontLog =
|
|
|
156
219
|
const col = indexStart + i;
|
|
157
220
|
if (col >= 0 && col < gridWidth && startRow >= 0 && startRow < gridHeight) {
|
|
158
221
|
const existing = indexGrid[startRow][col];
|
|
159
|
-
if (!existing ||
|
|
160
|
-
indexGrid[startRow][col] = { char: indexStr[i], zIndex };
|
|
222
|
+
if (!existing || index >= existing.zIndex) {
|
|
223
|
+
indexGrid[startRow][col] = { char: indexStr[i], zIndex: index };
|
|
161
224
|
}
|
|
162
225
|
}
|
|
163
226
|
}
|
|
@@ -174,31 +237,42 @@ function logRects(rectangles, { sizePerPoint = 10, showLegend = true, dontLog =
|
|
|
174
237
|
return STYLE_CHARS[style][cell.directions] || "?";
|
|
175
238
|
})
|
|
176
239
|
);
|
|
177
|
-
|
|
240
|
+
if (charGrid[0][0] === " ") {
|
|
241
|
+
charGrid[0][0] = "•";
|
|
242
|
+
}
|
|
243
|
+
if (charGrid[charGrid.length - 1][charGrid[0].length - 1] === " ") {
|
|
244
|
+
charGrid[charGrid.length - 1][charGrid[0].length - 1] = "•";
|
|
245
|
+
}
|
|
246
|
+
let lines = [];
|
|
178
247
|
if (showLegend) {
|
|
179
248
|
const topLeftLabel = `[${minX}, ${minY}]`;
|
|
180
249
|
const bottomRightLabel = `[${maxX}, ${maxY}]`;
|
|
181
|
-
const padding = " ".repeat(topLeftLabel.length + 1);
|
|
182
250
|
lines.push(topLeftLabel);
|
|
183
251
|
for (const row of charGrid) {
|
|
184
|
-
lines.push(
|
|
252
|
+
lines.push(row.join(""));
|
|
185
253
|
}
|
|
186
|
-
|
|
254
|
+
const lastPadding = Math.max(0, gridWidth - bottomRightLabel.length);
|
|
255
|
+
lines.push(" ".repeat(lastPadding) + bottomRightLabel);
|
|
187
256
|
} else {
|
|
188
257
|
for (const row of charGrid) {
|
|
189
258
|
lines.push(row.join(""));
|
|
190
259
|
}
|
|
191
260
|
}
|
|
261
|
+
if (listRectangles) {
|
|
262
|
+
const descriptions = createRectsDescriptions(rectangles);
|
|
263
|
+
lines = addDescriptionsToLines(lines, descriptions);
|
|
264
|
+
}
|
|
192
265
|
if (startWithNewLine) {
|
|
193
266
|
lines.unshift("");
|
|
194
267
|
}
|
|
195
268
|
const output = lines.join("\n");
|
|
196
|
-
if (!dontLog) {
|
|
197
|
-
console.info(output);
|
|
198
|
-
}
|
|
199
269
|
return output;
|
|
200
270
|
}
|
|
271
|
+
function logRects(rectangles, options) {
|
|
272
|
+
console.info(getRectsLog(rectangles, options));
|
|
273
|
+
}
|
|
201
274
|
export {
|
|
275
|
+
getRectsLog,
|
|
202
276
|
logRects
|
|
203
277
|
};
|
|
204
278
|
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","sources":["../index.ts"],"sourcesContent":["interface Rectangle {\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\n// Direction bitmasks\nconst UP = 1;\nconst DOWN = 2;\nconst LEFT = 4;\nconst RIGHT = 8;\n\ntype LineStyle = \"light\" | \"heavy\" | \"double\" | \"dashed\" | \"dashed-heavy\";\n\nconst STYLES: LineStyle[] = [\"light\", \"heavy\", \"double\", \"dashed\", \"dashed-heavy\"];\n\n// Box-drawing character maps for each style\nconst STYLE_CHARS: Record<LineStyle, Record<number, string>> = {\n light: {\n [UP]: \"╵\",\n [DOWN]: \"╷\",\n [LEFT]: \"╴\",\n [RIGHT]: \"╶\",\n [LEFT | RIGHT]: \"─\",\n [UP | DOWN]: \"│\",\n [DOWN | RIGHT]: \"┌\",\n [DOWN | LEFT]: \"┐\",\n [UP | RIGHT]: \"└\",\n [UP | LEFT]: \"┘\",\n [UP | DOWN | RIGHT]: \"├\",\n [UP | DOWN | LEFT]: \"┤\",\n [LEFT | RIGHT | DOWN]: \"┬\",\n [LEFT | RIGHT | UP]: \"┴\",\n [UP | DOWN | LEFT | RIGHT]: \"┼\",\n },\n heavy: {\n [UP]: \"╹\",\n [DOWN]: \"╻\",\n [LEFT]: \"╸\",\n [RIGHT]: \"╺\",\n [LEFT | RIGHT]: \"━\",\n [UP | DOWN]: \"┃\",\n [DOWN | RIGHT]: \"┏\",\n [DOWN | LEFT]: \"┓\",\n [UP | RIGHT]: \"┗\",\n [UP | LEFT]: \"┛\",\n [UP | DOWN | RIGHT]: \"┣\",\n [UP | DOWN | LEFT]: \"┫\",\n [LEFT | RIGHT | DOWN]: \"┳\",\n [LEFT | RIGHT | UP]: \"┻\",\n [UP | DOWN | LEFT | RIGHT]: \"╋\",\n },\n double: {\n [UP]: \"║\",\n [DOWN]: \"║\",\n [LEFT]: \"═\",\n [RIGHT]: \"═\",\n [LEFT | RIGHT]: \"═\",\n [UP | DOWN]: \"║\",\n [DOWN | RIGHT]: \"╔\",\n [DOWN | LEFT]: \"╗\",\n [UP | RIGHT]: \"╚\",\n [UP | LEFT]: \"╝\",\n [UP | DOWN | RIGHT]: \"╠\",\n [UP | DOWN | LEFT]: \"╣\",\n [LEFT | RIGHT | DOWN]: \"╦\",\n [LEFT | RIGHT | UP]: \"╩\",\n [UP | DOWN | LEFT | RIGHT]: \"╬\",\n },\n dashed: {\n [UP]: \"╎\",\n [DOWN]: \"╎\",\n [LEFT]: \"╌\",\n [RIGHT]: \"╌\",\n [LEFT | RIGHT]: \"╌\",\n [UP | DOWN]: \"╎\",\n [DOWN | RIGHT]: \"┌\",\n [DOWN | LEFT]: \"┐\",\n [UP | RIGHT]: \"└\",\n [UP | LEFT]: \"┘\",\n [UP | DOWN | RIGHT]: \"├\",\n [UP | DOWN | LEFT]: \"┤\",\n [LEFT | RIGHT | DOWN]: \"┬\",\n [LEFT | RIGHT | UP]: \"┴\",\n [UP | DOWN | LEFT | RIGHT]: \"┼\",\n },\n \"dashed-heavy\": {\n [UP]: \"╏\",\n [DOWN]: \"╏\",\n [LEFT]: \"╍\",\n [RIGHT]: \"╍\",\n [LEFT | RIGHT]: \"╍\",\n [UP | DOWN]: \"╏\",\n [DOWN | RIGHT]: \"┏\",\n [DOWN | LEFT]: \"┓\",\n [UP | RIGHT]: \"┗\",\n [UP | LEFT]: \"┛\",\n [UP | DOWN | RIGHT]: \"┣\",\n [UP | DOWN | LEFT]: \"┫\",\n [LEFT | RIGHT | DOWN]: \"┳\",\n [LEFT | RIGHT | UP]: \"┻\",\n [UP | DOWN | LEFT | RIGHT]: \"╋\",\n },\n};\n\ninterface CellData {\n directions: number;\n zIndex: number;\n}\n\ninterface IndexData {\n char: string;\n zIndex: number;\n}\n\nexport interface LogRectsOptions {\n sizePerPoint?: number;\n showLegend?: boolean;\n dontLog?: boolean;\n startWithNewLine?: boolean;\n}\n\nexport function logRects(\n rectangles: Rectangle[],\n { sizePerPoint = 10, showLegend = true, dontLog = false, startWithNewLine = true }: LogRectsOptions = {}\n): string {\n if (rectangles.length === 0) {\n return \"No rectangles to draw\";\n }\n\n // Find bounding box of all rectangles\n let minX = Infinity;\n let minY = Infinity;\n let maxX = -Infinity;\n let maxY = -Infinity;\n\n for (const rect of rectangles) {\n minX = Math.min(minX, rect.x);\n minY = Math.min(minY, rect.y);\n maxX = Math.max(maxX, rect.x + rect.width);\n maxY = Math.max(maxY, rect.y + rect.height);\n }\n\n // Calculate grid dimensions based on resolution\n const gridWidth = Math.ceil((maxX - minX) / sizePerPoint);\n const gridHeight = Math.ceil((maxY - minY) / sizePerPoint);\n\n // Create grid to track directions and z-index at each cell\n const grid: CellData[][] = Array.from({ length: gridHeight }, () =>\n Array.from({ length: gridWidth }, () => ({ directions: 0, zIndex: -1 }))\n );\n\n // Create index overlay grid\n const indexGrid: (IndexData | null)[][] = Array.from({ length: gridHeight }, () => Array(gridWidth).fill(null));\n\n // Helper to set cell data with z-index awareness\n const setCell = (row: number, col: number, direction: number, zIndex: number) => {\n if (row < 0 || row >= gridHeight || col < 0 || col >= gridWidth) return;\n const cell = grid[row][col];\n if (zIndex >= cell.zIndex) {\n if (zIndex > cell.zIndex) {\n cell.directions = 0;\n cell.zIndex = zIndex;\n }\n cell.directions |= direction;\n }\n };\n\n // Helper to draw a horizontal line segment\n const drawHorizontal = (row: number, colStart: number, colEnd: number, zIndex: number) => {\n for (let col = colStart; col <= colEnd; col++) {\n let dirs = 0;\n if (col > colStart) dirs |= LEFT;\n if (col < colEnd) dirs |= RIGHT;\n if (dirs) setCell(row, col, dirs, zIndex);\n }\n };\n\n // Helper to draw a vertical line segment\n const drawVertical = (col: number, rowStart: number, rowEnd: number, zIndex: number) => {\n for (let row = rowStart; row <= rowEnd; row++) {\n let dirs = 0;\n if (row > rowStart) dirs |= UP;\n if (row < rowEnd) dirs |= DOWN;\n if (dirs) setCell(row, col, dirs, zIndex);\n }\n };\n\n // Draw each rectangle's outline with z-index = array index\n rectangles.forEach((rect, zIndex) => {\n const startCol = Math.floor((rect.x - minX) / sizePerPoint);\n const startRow = Math.floor((rect.y - minY) / sizePerPoint);\n const endCol = Math.ceil((rect.x + rect.width - minX) / sizePerPoint) - 1;\n const endRow = Math.ceil((rect.y + rect.height - minY) / sizePerPoint) - 1;\n\n // Draw the four edges\n drawHorizontal(startRow, startCol, endCol, zIndex);\n drawHorizontal(endRow, startCol, endCol, zIndex);\n drawVertical(startCol, startRow, endRow, zIndex);\n drawVertical(endCol, startRow, endRow, zIndex);\n\n // Place index at center of top edge if there's room\n const indexStr = String(zIndex);\n const edgeWidth = endCol - startCol; // number of segments (cells - 1)\n\n // Need at least 1 line char on each side of the index\n // Inner width (excluding corners) = edgeWidth - 1\n // Required: innerWidth >= indexStr.length + 2\n if (edgeWidth >= indexStr.length + 3) {\n const innerWidth = edgeWidth - 1;\n const indexStart = startCol + 1 + Math.floor((innerWidth - indexStr.length) / 2);\n\n for (let i = 0; i < indexStr.length; i++) {\n const col = indexStart + i;\n if (col >= 0 && col < gridWidth && startRow >= 0 && startRow < gridHeight) {\n const existing = indexGrid[startRow][col];\n if (!existing || zIndex >= existing.zIndex) {\n indexGrid[startRow][col] = { char: indexStr[i], zIndex };\n }\n }\n }\n }\n });\n\n // Convert cell data to characters, respecting z-index for both edges and indices\n const charGrid: string[][] = grid.map((row, rowIdx) =>\n row.map((cell, colIdx) => {\n const indexData = indexGrid[rowIdx][colIdx];\n\n // If there's an index with higher or equal z-index, use it\n if (indexData && indexData.zIndex >= cell.zIndex) {\n return indexData.char;\n }\n\n // Otherwise use edge character\n if (cell.directions === 0) return \" \";\n const style = STYLES[cell.zIndex % STYLES.length];\n return STYLE_CHARS[style][cell.directions] || \"?\";\n })\n );\n\n // Build output string\n const lines: string[] = [];\n\n if (showLegend) {\n const topLeftLabel = `[${minX}, ${minY}]`;\n const bottomRightLabel = `[${maxX}, ${maxY}]`;\n const padding = \" \".repeat(topLeftLabel.length + 1);\n\n lines.push(topLeftLabel);\n for (const row of charGrid) {\n lines.push(padding + row.join(\"\"));\n }\n lines.push(padding + \" \".repeat(gridWidth) + \" \" + bottomRightLabel);\n } else {\n for (const row of charGrid) {\n lines.push(row.join(\"\"));\n }\n }\n\n if (startWithNewLine) {\n lines.unshift(\"\");\n }\n\n const output = lines.join(\"\\n\");\n\n if (!dontLog) {\n console.info(output);\n }\n\n return output;\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","sources":["../index.ts"],"sourcesContent":["interface Rectangle {\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\n// Direction bitmasks\nconst UP = 1;\nconst DOWN = 2;\nconst LEFT = 4;\nconst RIGHT = 8;\n\ntype LineStyle = \"light\" | \"heavy\" | \"double\" | \"dashed\" | \"dashed-heavy\";\n\nconst STYLES: LineStyle[] = [\n //\n \"heavy\", // ╹╻╸╺━┃┏┓┛┗┣┫┳┻┼\n \"light\", // ╵╷╴╶─│┌┐└┘├┤┬┴┼\n \"dashed\", // ╎╎╌╌╎┌┐└┘├┤┬┴┼\n \"dashed-heavy\", // ╏╏╍╍╏┏┓┛┗┣┫┳┻┼\n \"double\", // ║║═║╔╗╚╝╠╣╦╩╬\n];\n\n// Box-drawing character maps for each style\nconst STYLE_CHARS: Record<LineStyle, Record<number, string>> = {\n light: {\n [UP]: \"╵\",\n [DOWN]: \"╷\",\n [LEFT]: \"╴\",\n [RIGHT]: \"╶\",\n [LEFT | RIGHT]: \"─\",\n [UP | DOWN]: \"│\",\n [DOWN | RIGHT]: \"┌\",\n [DOWN | LEFT]: \"┐\",\n [UP | RIGHT]: \"└\",\n [UP | LEFT]: \"┘\",\n [UP | DOWN | RIGHT]: \"├\",\n [UP | DOWN | LEFT]: \"┤\",\n [LEFT | RIGHT | DOWN]: \"┬\",\n [LEFT | RIGHT | UP]: \"┴\",\n [UP | DOWN | LEFT | RIGHT]: \"┼\",\n },\n heavy: {\n [UP]: \"╹\",\n [DOWN]: \"╻\",\n [LEFT]: \"╸\",\n [RIGHT]: \"╺\",\n [LEFT | RIGHT]: \"━\",\n [UP | DOWN]: \"┃\",\n [DOWN | RIGHT]: \"┏\",\n [DOWN | LEFT]: \"┓\",\n [UP | RIGHT]: \"┗\",\n [UP | LEFT]: \"┛\",\n [UP | DOWN | RIGHT]: \"┣\",\n [UP | DOWN | LEFT]: \"┫\",\n [LEFT | RIGHT | DOWN]: \"┳\",\n [LEFT | RIGHT | UP]: \"┻\",\n [UP | DOWN | LEFT | RIGHT]: \"╋\",\n },\n double: {\n [UP]: \"║\",\n [DOWN]: \"║\",\n [LEFT]: \"═\",\n [RIGHT]: \"═\",\n [LEFT | RIGHT]: \"═\",\n [UP | DOWN]: \"║\",\n [DOWN | RIGHT]: \"╔\",\n [DOWN | LEFT]: \"╗\",\n [UP | RIGHT]: \"╚\",\n [UP | LEFT]: \"╝\",\n [UP | DOWN | RIGHT]: \"╠\",\n [UP | DOWN | LEFT]: \"╣\",\n [LEFT | RIGHT | DOWN]: \"╦\",\n [LEFT | RIGHT | UP]: \"╩\",\n [UP | DOWN | LEFT | RIGHT]: \"╬\",\n },\n dashed: {\n [UP]: \"╎\",\n [DOWN]: \"╎\",\n [LEFT]: \"╌\",\n [RIGHT]: \"╌\",\n [LEFT | RIGHT]: \"╌\",\n [UP | DOWN]: \"╎\",\n [DOWN | RIGHT]: \"┌\",\n [DOWN | LEFT]: \"┐\",\n [UP | RIGHT]: \"└\",\n [UP | LEFT]: \"┘\",\n [UP | DOWN | RIGHT]: \"├\",\n [UP | DOWN | LEFT]: \"┤\",\n [LEFT | RIGHT | DOWN]: \"┬\",\n [LEFT | RIGHT | UP]: \"┴\",\n [UP | DOWN | LEFT | RIGHT]: \"┼\",\n },\n \"dashed-heavy\": {\n [UP]: \"╏\",\n [DOWN]: \"╏\",\n [LEFT]: \"╍\",\n [RIGHT]: \"╍\",\n [LEFT | RIGHT]: \"╍\",\n [UP | DOWN]: \"╏\",\n [DOWN | RIGHT]: \"┏\",\n [DOWN | LEFT]: \"┓\",\n [UP | RIGHT]: \"┗\",\n [UP | LEFT]: \"┛\",\n [UP | DOWN | RIGHT]: \"┣\",\n [UP | DOWN | LEFT]: \"┫\",\n [LEFT | RIGHT | DOWN]: \"┳\",\n [LEFT | RIGHT | UP]: \"┻\",\n [UP | DOWN | LEFT | RIGHT]: \"╋\",\n },\n};\n\ninterface CellData {\n directions: number;\n zIndex: number;\n}\n\ninterface IndexData {\n char: string;\n zIndex: number;\n}\n\nexport interface LogRectsOptions {\n sizePerPoint?: number;\n showLegend?: boolean;\n listRectangles?: boolean;\n startWithNewLine?: boolean;\n adjustOutputHeight?: boolean;\n}\n\nfunction maxBy<T>(array: T[], selector: (item: T) => number): number {\n return array.reduce((max, item) => {\n const value = selector(item);\n return value > max ? value : max;\n }, -Infinity);\n}\n\nfunction createRectsDescriptions(rectangles: NamedRectangle[]) {\n const maxNameLength = maxBy(rectangles, (rect) => rect.name.length);\n const maxXLength = maxBy(rectangles, (rect) => rect.x.toString().length);\n const maxYLength = maxBy(rectangles, (rect) => rect.y.toString().length);\n const maxWidthLength = maxBy(rectangles, (rect) => rect.width.toString().length);\n const maxHeightLength = maxBy(rectangles, (rect) => rect.height.toString().length);\n\n const descriptions = rectangles.map((rect) => {\n const name = rect.name.padEnd(maxNameLength, \" \");\n const x = rect.x.toString().padStart(maxXLength, \" \");\n const y = rect.y.toString().padStart(maxYLength, \" \");\n const width = rect.width.toString().padStart(maxWidthLength, \" \");\n const height = rect.height.toString().padStart(maxHeightLength, \" \");\n return `${name}: [${x}, ${y}, ${width}, ${height}]`;\n });\n\n descriptions.unshift(`Rectangles (${rectangles.length}):`);\n\n return descriptions;\n}\n\nfunction addDescriptionsToLines(lines: string[], descriptions: string[], padding: number = 5) {\n const longestLineLength = maxBy(lines, (line) => line.length);\n for (let i = 0; i < descriptions.length; i++) {\n if (i >= descriptions.length) break;\n\n const line = lines[i] ?? \"\";\n\n lines[i] = line.padEnd(longestLineLength + padding, \" \");\n lines[i] += descriptions[i];\n }\n return lines;\n}\n\ntype Maybe<T> = T | null | undefined;\n\nexport type RectsLogInput = Array<Maybe<Rectangle>> | Record<string, Maybe<Rectangle>>;\n\nfunction getIsSet<T>(value: Maybe<T>): value is T {\n return value !== null && value !== undefined;\n}\n\ninterface NamedRectangle extends Rectangle {\n name: string;\n}\n\nfunction resolveInput(input: RectsLogInput): NamedRectangle[] {\n if (Array.isArray(input)) {\n return input.filter(getIsSet).map((rect, index) => ({ ...rect, name: String(index) }));\n }\n\n return Object.entries(input)\n .filter(([, rect]) => !!rect)\n .map(([name, rect]) => ({ ...rect!, name }));\n}\n\nexport function getRectsLog(\n input: RectsLogInput,\n {\n sizePerPoint = 10,\n showLegend = true,\n listRectangles = true,\n startWithNewLine = true,\n adjustOutputHeight = true,\n }: LogRectsOptions = {}\n): string | null {\n const rectangles = resolveInput(input);\n\n const xSizePerPoint = sizePerPoint;\n const ySizePerPoint = adjustOutputHeight ? sizePerPoint * 2 * 1.2 : sizePerPoint;\n\n if (rectangles.length === 0) {\n return null;\n }\n\n // Find bounding box of all rectangles\n let minX = Infinity;\n let minY = Infinity;\n let maxX = -Infinity;\n let maxY = -Infinity;\n\n for (const rect of rectangles) {\n minX = Math.min(minX, rect.x);\n minY = Math.min(minY, rect.y);\n maxX = Math.max(maxX, rect.x + rect.width);\n maxY = Math.max(maxY, rect.y + rect.height);\n }\n\n // Calculate grid dimensions based on resolution\n const gridWidth = Math.ceil((maxX - minX) / xSizePerPoint);\n const gridHeight = Math.ceil((maxY - minY) / ySizePerPoint);\n\n // Create grid to track directions and z-index at each cell\n const grid: CellData[][] = Array.from({ length: gridHeight }, () =>\n Array.from({ length: gridWidth }, () => ({ directions: 0, zIndex: -1 }))\n );\n\n // Create index overlay grid\n const indexGrid: (IndexData | null)[][] = Array.from({ length: gridHeight }, () => Array(gridWidth).fill(null));\n\n // Helper to set cell data with z-index awareness\n const setCell = (row: number, col: number, direction: number, zIndex: number) => {\n if (row < 0 || row >= gridHeight || col < 0 || col >= gridWidth) return;\n const cell = grid[row][col];\n if (zIndex >= cell.zIndex) {\n if (zIndex > cell.zIndex) {\n cell.directions = 0;\n cell.zIndex = zIndex;\n }\n cell.directions |= direction;\n }\n };\n\n // Helper to draw a horizontal line segment\n const drawHorizontal = (row: number, colStart: number, colEnd: number, zIndex: number) => {\n for (let col = colStart; col <= colEnd; col++) {\n let dirs = 0;\n if (col > colStart) dirs |= LEFT;\n if (col < colEnd) dirs |= RIGHT;\n if (dirs) setCell(row, col, dirs, zIndex);\n }\n };\n\n // Helper to draw a vertical line segment\n const drawVertical = (col: number, rowStart: number, rowEnd: number, zIndex: number) => {\n for (let row = rowStart; row <= rowEnd; row++) {\n let dirs = 0;\n if (row > rowStart) dirs |= UP;\n if (row < rowEnd) dirs |= DOWN;\n if (dirs) setCell(row, col, dirs, zIndex);\n }\n };\n\n // Draw each rectangle's outline with z-index = array index\n rectangles.forEach((rect, index) => {\n const startCol = Math.floor((rect.x - minX) / xSizePerPoint);\n const startRow = Math.floor((rect.y - minY) / ySizePerPoint);\n const endCol = Math.ceil((rect.x + rect.width - minX) / xSizePerPoint) - 1;\n const endRow = Math.ceil((rect.y + rect.height - minY) / ySizePerPoint) - 1;\n\n // Draw the four edges\n drawHorizontal(startRow, startCol, endCol, index);\n drawHorizontal(endRow, startCol, endCol, index);\n drawVertical(startCol, startRow, endRow, index);\n drawVertical(endCol, startRow, endRow, index);\n\n // Place index at center of top edge if there's room\n const indexStr = rect.name;\n const edgeWidth = endCol - startCol; // number of segments (cells - 1)\n\n // Need at least 1 line char on each side of the index\n // Inner width (excluding corners) = edgeWidth - 1\n // Required: innerWidth >= indexStr.length + 2\n if (edgeWidth >= indexStr.length + 3) {\n const innerWidth = edgeWidth - 1;\n const indexStart = startCol + 1 + Math.floor((innerWidth - indexStr.length) / 2);\n\n for (let i = 0; i < indexStr.length; i++) {\n const col = indexStart + i;\n if (col >= 0 && col < gridWidth && startRow >= 0 && startRow < gridHeight) {\n const existing = indexGrid[startRow][col];\n if (!existing || index >= existing.zIndex) {\n indexGrid[startRow][col] = { char: indexStr[i], zIndex: index };\n }\n }\n }\n }\n });\n\n // Convert cell data to characters, respecting z-index for both edges and indices\n const charGrid: string[][] = grid.map((row, rowIdx) =>\n row.map((cell, colIdx) => {\n const indexData = indexGrid[rowIdx][colIdx];\n\n // If there's an index with higher or equal z-index, use it\n if (indexData && indexData.zIndex >= cell.zIndex) {\n return indexData.char;\n }\n\n // Otherwise use edge character\n if (cell.directions === 0) return \" \";\n const style = STYLES[cell.zIndex % STYLES.length];\n return STYLE_CHARS[style][cell.directions] || \"?\";\n })\n );\n\n const CORNER_CHAR_DOT_ASCII = \"•\";\n\n if (charGrid[0][0] === \" \") {\n charGrid[0][0] = \"•\";\n }\n\n if (charGrid[charGrid.length - 1][charGrid[0].length - 1] === \" \") {\n charGrid[charGrid.length - 1][charGrid[0].length - 1] = \"•\";\n }\n\n // Build output string\n let lines: string[] = [];\n\n if (showLegend) {\n const topLeftLabel = `[${minX}, ${minY}]`;\n const bottomRightLabel = `[${maxX}, ${maxY}]`;\n\n lines.push(topLeftLabel);\n for (const row of charGrid) {\n lines.push(row.join(\"\"));\n }\n const lastPadding = Math.max(0, gridWidth - bottomRightLabel.length);\n lines.push(\" \".repeat(lastPadding) + bottomRightLabel);\n } else {\n for (const row of charGrid) {\n lines.push(row.join(\"\"));\n }\n }\n\n if (listRectangles) {\n const descriptions = createRectsDescriptions(rectangles);\n lines = addDescriptionsToLines(lines, descriptions);\n }\n\n if (startWithNewLine) {\n lines.unshift(\"\");\n }\n\n const output = lines.join(\"\\n\");\n\n return output;\n}\n\nexport function logRects(rectangles: Rectangle[], options?: LogRectsOptions): void {\n console.info(getRectsLog(rectangles, options));\n}\n"],"names":[],"mappings":"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"}
|
package/dist/types/index.d.ts
CHANGED
|
@@ -7,8 +7,12 @@ interface Rectangle {
|
|
|
7
7
|
export interface LogRectsOptions {
|
|
8
8
|
sizePerPoint?: number;
|
|
9
9
|
showLegend?: boolean;
|
|
10
|
-
|
|
10
|
+
listRectangles?: boolean;
|
|
11
11
|
startWithNewLine?: boolean;
|
|
12
|
+
adjustOutputHeight?: boolean;
|
|
12
13
|
}
|
|
13
|
-
|
|
14
|
+
type Maybe<T> = T | null | undefined;
|
|
15
|
+
export type RectsLogInput = Array<Maybe<Rectangle>> | Record<string, Maybe<Rectangle>>;
|
|
16
|
+
export declare function getRectsLog(input: RectsLogInput, { sizePerPoint, showLegend, listRectangles, startWithNewLine, adjustOutputHeight, }?: LogRectsOptions): string | null;
|
|
17
|
+
export declare function logRects(rectangles: Rectangle[], options?: LogRectsOptions): void;
|
|
14
18
|
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "console-rects",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Visualize rectangles in the console using box-drawing characters. Perfect for debugging geometry code, visualizing overlapping rectangles, or drawing rectangles in terminal.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|