console-rects 0.1.4 → 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 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
- ┌───0────┐
34
- │ │
35
-
36
-
37
- ┏━━━1━━━━┓
38
- │ ┃
39
- │ ┃ │ ┃
40
- │ ┃ │ ┃
41
- │ ┃ ╔═══2════╗
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(getRectsLog([transformer.zoom(2.5, { x: 0, y: 0.5 }, avaliableSize), avaliableSize])).toMatchInlineSnapshot(`
49
+ expect(testLayout(layout)).toMatchInlineSnapshot(`
60
50
  "
61
- [-50, -75]
62
- ┌───────────0───────────┐
63
-
64
-
65
-
66
-
67
-
68
-
69
- ┏━━━━━━━━1━━━━━━━━━┓
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 = ["light", "heavy", "double", "dashed", "dashed-heavy"];
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 logRects(rectangles, { sizePerPoint = 10, showLegend = true, dontLog = false, startWithNewLine = true } = {}) {
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 "No rectangles to draw";
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) / sizePerPoint);
110
- const gridHeight = Math.ceil((maxY - minY) / sizePerPoint);
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, zIndex) => {
144
- const startCol = Math.floor((rect.x - minX) / sizePerPoint);
145
- const startRow = Math.floor((rect.y - minY) / sizePerPoint);
146
- const endCol = Math.ceil((rect.x + rect.width - minX) / sizePerPoint) - 1;
147
- const endRow = Math.ceil((rect.y + rect.height - minY) / sizePerPoint) - 1;
148
- drawHorizontal(startRow, startCol, endCol, zIndex);
149
- drawHorizontal(endRow, startCol, endCol, zIndex);
150
- drawVertical(startCol, startRow, endRow, zIndex);
151
- drawVertical(endCol, startRow, endRow, zIndex);
152
- const indexStr = String(zIndex);
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 || zIndex >= existing.zIndex) {
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
- const lines = [];
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(padding + row.join(""));
254
+ lines.push(row.join(""));
187
255
  }
188
- lines.push(padding + " ".repeat(gridWidth) + " " + bottomRightLabel);
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
@@ -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":"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"}
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 = ["light", "heavy", "double", "dashed", "dashed-heavy"];
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 logRects(rectangles, { sizePerPoint = 10, showLegend = true, dontLog = false, startWithNewLine = true } = {}) {
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 "No rectangles to draw";
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) / sizePerPoint);
108
- const gridHeight = Math.ceil((maxY - minY) / sizePerPoint);
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, zIndex) => {
142
- const startCol = Math.floor((rect.x - minX) / sizePerPoint);
143
- const startRow = Math.floor((rect.y - minY) / sizePerPoint);
144
- const endCol = Math.ceil((rect.x + rect.width - minX) / sizePerPoint) - 1;
145
- const endRow = Math.ceil((rect.y + rect.height - minY) / sizePerPoint) - 1;
146
- drawHorizontal(startRow, startCol, endCol, zIndex);
147
- drawHorizontal(endRow, startCol, endCol, zIndex);
148
- drawVertical(startCol, startRow, endRow, zIndex);
149
- drawVertical(endCol, startRow, endRow, zIndex);
150
- const indexStr = String(zIndex);
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 || zIndex >= existing.zIndex) {
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
- const lines = [];
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(padding + row.join(""));
252
+ lines.push(row.join(""));
185
253
  }
186
- lines.push(padding + " ".repeat(gridWidth) + " " + bottomRightLabel);
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
@@ -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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"}
@@ -7,8 +7,12 @@ interface Rectangle {
7
7
  export interface LogRectsOptions {
8
8
  sizePerPoint?: number;
9
9
  showLegend?: boolean;
10
- dontLog?: boolean;
10
+ listRectangles?: boolean;
11
11
  startWithNewLine?: boolean;
12
+ adjustOutputHeight?: boolean;
12
13
  }
13
- export declare function logRects(rectangles: Rectangle[], { sizePerPoint, showLegend, dontLog, startWithNewLine }?: LogRectsOptions): string;
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.1.4",
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",