calculate-packing 0.0.18 → 0.0.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +43 -2
- package/dist/index.js +325 -1
- package/package.json +4 -2
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { GraphicsObject, Point as Point$1 } from 'graphics-debug';
|
|
2
2
|
import { CircuitJson } from 'circuit-json';
|
|
3
|
+
import { Bounds } from '@tscircuit/math-utils';
|
|
3
4
|
|
|
4
5
|
type ComponentId = string;
|
|
5
6
|
type PadId = string;
|
|
@@ -42,11 +43,12 @@ interface PackedComponent extends InputComponent {
|
|
|
42
43
|
ccwRotationDegrees?: number;
|
|
43
44
|
pads: OutputPad[];
|
|
44
45
|
}
|
|
46
|
+
type PackPlacementStrategy = "shortest_connection_along_outline" | "minimum_sum_distance_to_network" | "minimum_sum_squared_distance_to_network";
|
|
45
47
|
interface PackInput {
|
|
46
48
|
components: InputComponent[];
|
|
47
49
|
minGap: number;
|
|
48
50
|
packOrderStrategy: "largest_to_smallest";
|
|
49
|
-
packPlacementStrategy:
|
|
51
|
+
packPlacementStrategy: PackPlacementStrategy;
|
|
50
52
|
disconnectedPackDirection?: "left" | "right" | "up" | "down" | "nearest_to_center";
|
|
51
53
|
packFirst?: ComponentId[];
|
|
52
54
|
}
|
|
@@ -188,4 +190,43 @@ declare const getGraphicsFromPackOutput: (packOutput: PackOutput) => GraphicsObj
|
|
|
188
190
|
*/
|
|
189
191
|
declare const convertPackOutputToPackInput: (packed: PackOutput) => PackInput;
|
|
190
192
|
|
|
191
|
-
|
|
193
|
+
type Rect = {
|
|
194
|
+
x: number;
|
|
195
|
+
y: number;
|
|
196
|
+
w: number;
|
|
197
|
+
h: number;
|
|
198
|
+
};
|
|
199
|
+
|
|
200
|
+
type GlobalBounds = Bounds;
|
|
201
|
+
declare class LargestRectOutsideOutlineFromPointSolver extends BaseSolver {
|
|
202
|
+
fullOutline: Point[];
|
|
203
|
+
origin: Point;
|
|
204
|
+
globalBounds: Bounds;
|
|
205
|
+
largestRect: Rect | null;
|
|
206
|
+
constructor(params: {
|
|
207
|
+
fullOutline: Point[];
|
|
208
|
+
origin: Point;
|
|
209
|
+
globalBounds: Bounds;
|
|
210
|
+
});
|
|
211
|
+
getConstructorParams(): {
|
|
212
|
+
fullOutline: Point[];
|
|
213
|
+
origin: Point;
|
|
214
|
+
globalBounds: Bounds;
|
|
215
|
+
};
|
|
216
|
+
_setup(): void;
|
|
217
|
+
_step(): void;
|
|
218
|
+
private computeLargestRectOutside;
|
|
219
|
+
private almostEqual;
|
|
220
|
+
private makeEdges;
|
|
221
|
+
private isVertical;
|
|
222
|
+
private isHorizontal;
|
|
223
|
+
private scanlineIntervalsAtY;
|
|
224
|
+
private clipIntervals;
|
|
225
|
+
private regionIntervalsAtY;
|
|
226
|
+
private largestRectContainingPointRegion;
|
|
227
|
+
getLargestRect(): Rect | null;
|
|
228
|
+
getLargestRectBounds(): Bounds;
|
|
229
|
+
visualize(): GraphicsObject;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
export { type ComponentId, type GlobalBounds, type InputComponent, type InputPad, LargestRectOutsideOutlineFromPointSolver, type NetworkId, type OutputPad, type PackInput, type PackOutput, type PackPlacementStrategy, type PackedComponent, type PadId, PhasedPackSolver, type Point, type Rect, convertCircuitJsonToPackOutput, convertPackOutputToPackInput, getGraphicsFromPackOutput, pack };
|
package/dist/index.js
CHANGED
|
@@ -132,6 +132,69 @@ var rotatePoint = (point, angle, origin = { x: 0, y: 0 }) => {
|
|
|
132
132
|
};
|
|
133
133
|
};
|
|
134
134
|
|
|
135
|
+
// lib/math/cross.ts
|
|
136
|
+
var cross = (O, A, B) => (A.x - O.x) * (B.y - O.y) - (A.y - O.y) * (B.x - O.x);
|
|
137
|
+
|
|
138
|
+
// lib/geometry/simplify-collinear-segments.ts
|
|
139
|
+
function simplifyCollinearSegments(outline, tolerance = 1e-10) {
|
|
140
|
+
if (outline.length <= 1) {
|
|
141
|
+
return outline;
|
|
142
|
+
}
|
|
143
|
+
const simplified = [];
|
|
144
|
+
let currentSegmentStart = outline[0][0];
|
|
145
|
+
let currentSegmentEnd = outline[0][1];
|
|
146
|
+
for (let i = 1; i < outline.length; i++) {
|
|
147
|
+
const nextSegment = outline[i];
|
|
148
|
+
const [nextStart, nextEnd] = nextSegment;
|
|
149
|
+
const connectionTolerance = 1e-10;
|
|
150
|
+
const isConnected = Math.abs(currentSegmentEnd.x - nextStart.x) < connectionTolerance && Math.abs(currentSegmentEnd.y - nextStart.y) < connectionTolerance;
|
|
151
|
+
if (!isConnected) {
|
|
152
|
+
simplified.push([currentSegmentStart, currentSegmentEnd]);
|
|
153
|
+
currentSegmentStart = nextStart;
|
|
154
|
+
currentSegmentEnd = nextEnd;
|
|
155
|
+
continue;
|
|
156
|
+
}
|
|
157
|
+
const crossProduct = cross(currentSegmentStart, currentSegmentEnd, nextEnd);
|
|
158
|
+
if (Math.abs(crossProduct) < tolerance) {
|
|
159
|
+
currentSegmentEnd = nextEnd;
|
|
160
|
+
} else {
|
|
161
|
+
simplified.push([currentSegmentStart, currentSegmentEnd]);
|
|
162
|
+
currentSegmentStart = nextStart;
|
|
163
|
+
currentSegmentEnd = nextEnd;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
if (outline.length > 2) {
|
|
167
|
+
const firstSegment = simplified[0];
|
|
168
|
+
const lastSegmentCandidate = [
|
|
169
|
+
currentSegmentStart,
|
|
170
|
+
currentSegmentEnd
|
|
171
|
+
];
|
|
172
|
+
if (firstSegment && simplified.length > 0) {
|
|
173
|
+
const connectionTolerance = 1e-10;
|
|
174
|
+
const isLastConnectedToFirst = Math.abs(currentSegmentEnd.x - firstSegment[0].x) < connectionTolerance && Math.abs(currentSegmentEnd.y - firstSegment[0].y) < connectionTolerance;
|
|
175
|
+
if (isLastConnectedToFirst) {
|
|
176
|
+
const crossProduct = cross(
|
|
177
|
+
currentSegmentStart,
|
|
178
|
+
currentSegmentEnd,
|
|
179
|
+
firstSegment[1]
|
|
180
|
+
);
|
|
181
|
+
if (Math.abs(crossProduct) < tolerance) {
|
|
182
|
+
simplified[0] = [currentSegmentStart, firstSegment[1]];
|
|
183
|
+
} else {
|
|
184
|
+
simplified.push(lastSegmentCandidate);
|
|
185
|
+
}
|
|
186
|
+
} else {
|
|
187
|
+
simplified.push(lastSegmentCandidate);
|
|
188
|
+
}
|
|
189
|
+
} else {
|
|
190
|
+
simplified.push(lastSegmentCandidate);
|
|
191
|
+
}
|
|
192
|
+
} else {
|
|
193
|
+
simplified.push([currentSegmentStart, currentSegmentEnd]);
|
|
194
|
+
}
|
|
195
|
+
return simplified;
|
|
196
|
+
}
|
|
197
|
+
|
|
135
198
|
// lib/constructOutlinesFromPackedComponents.ts
|
|
136
199
|
var createPadPolygons = (component, minGap) => {
|
|
137
200
|
return component.pads.map((pad) => {
|
|
@@ -185,7 +248,8 @@ var constructOutlinesFromPackedComponents = (components, opts = {}) => {
|
|
|
185
248
|
]);
|
|
186
249
|
edge = edge.next;
|
|
187
250
|
} while (edge !== face.first);
|
|
188
|
-
|
|
251
|
+
const simplifiedOutline = simplifyCollinearSegments(outline);
|
|
252
|
+
outlines.push(simplifiedOutline);
|
|
189
253
|
}
|
|
190
254
|
return outlines;
|
|
191
255
|
};
|
|
@@ -1581,7 +1645,267 @@ var convertPackOutputToPackInput = (packed) => {
|
|
|
1581
1645
|
components: strippedComponents
|
|
1582
1646
|
};
|
|
1583
1647
|
};
|
|
1648
|
+
|
|
1649
|
+
// lib/LargestRectOutsideOutlineFromPointSolver.ts
|
|
1650
|
+
var LargestRectOutsideOutlineFromPointSolver = class extends BaseSolver {
|
|
1651
|
+
fullOutline;
|
|
1652
|
+
origin;
|
|
1653
|
+
globalBounds;
|
|
1654
|
+
largestRect = null;
|
|
1655
|
+
constructor(params) {
|
|
1656
|
+
super();
|
|
1657
|
+
this.fullOutline = params.fullOutline;
|
|
1658
|
+
this.origin = params.origin;
|
|
1659
|
+
this.globalBounds = params.globalBounds;
|
|
1660
|
+
}
|
|
1661
|
+
getConstructorParams() {
|
|
1662
|
+
return {
|
|
1663
|
+
fullOutline: this.fullOutline,
|
|
1664
|
+
origin: this.origin,
|
|
1665
|
+
globalBounds: this.globalBounds
|
|
1666
|
+
};
|
|
1667
|
+
}
|
|
1668
|
+
_setup() {
|
|
1669
|
+
}
|
|
1670
|
+
_step() {
|
|
1671
|
+
this.largestRect = this.computeLargestRectOutside();
|
|
1672
|
+
this.solved = true;
|
|
1673
|
+
}
|
|
1674
|
+
computeLargestRectOutside() {
|
|
1675
|
+
const edges = this.makeEdges(this.fullOutline);
|
|
1676
|
+
const bounds = {
|
|
1677
|
+
x: this.globalBounds.minX,
|
|
1678
|
+
y: this.globalBounds.minY,
|
|
1679
|
+
w: this.globalBounds.maxX - this.globalBounds.minX,
|
|
1680
|
+
h: this.globalBounds.maxY - this.globalBounds.minY
|
|
1681
|
+
};
|
|
1682
|
+
return this.largestRectContainingPointRegion(
|
|
1683
|
+
edges,
|
|
1684
|
+
this.origin,
|
|
1685
|
+
bounds,
|
|
1686
|
+
"outside"
|
|
1687
|
+
);
|
|
1688
|
+
}
|
|
1689
|
+
almostEqual(a, b, eps = 1e-9) {
|
|
1690
|
+
return Math.abs(a - b) <= eps;
|
|
1691
|
+
}
|
|
1692
|
+
makeEdges(poly) {
|
|
1693
|
+
const edges = [];
|
|
1694
|
+
for (let i = 0; i < poly.length; i++) {
|
|
1695
|
+
const a = poly[i];
|
|
1696
|
+
const b = poly[(i + 1) % poly.length];
|
|
1697
|
+
if (!a || !b) continue;
|
|
1698
|
+
if (this.almostEqual(a.x, b.x) && this.almostEqual(a.y, b.y)) continue;
|
|
1699
|
+
edges.push([a, b]);
|
|
1700
|
+
}
|
|
1701
|
+
return edges;
|
|
1702
|
+
}
|
|
1703
|
+
isVertical(e) {
|
|
1704
|
+
return this.almostEqual(e[0].x, e[1].x);
|
|
1705
|
+
}
|
|
1706
|
+
isHorizontal(e) {
|
|
1707
|
+
return this.almostEqual(e[0].y, e[1].y);
|
|
1708
|
+
}
|
|
1709
|
+
scanlineIntervalsAtY(edges, y0) {
|
|
1710
|
+
const xs = [];
|
|
1711
|
+
for (const e of edges) {
|
|
1712
|
+
if (!this.isVertical(e)) continue;
|
|
1713
|
+
const y1 = e[0].y;
|
|
1714
|
+
const y2 = e[1].y;
|
|
1715
|
+
const x = e[0].x;
|
|
1716
|
+
const ymin = Math.min(y1, y2);
|
|
1717
|
+
const ymax = Math.max(y1, y2);
|
|
1718
|
+
if (ymin <= y0 && y0 < ymax) {
|
|
1719
|
+
xs.push(x);
|
|
1720
|
+
}
|
|
1721
|
+
}
|
|
1722
|
+
xs.sort((a, b) => a - b);
|
|
1723
|
+
const intervals = [];
|
|
1724
|
+
for (let i = 0; i + 1 < xs.length; i += 2) {
|
|
1725
|
+
const x1 = xs[i];
|
|
1726
|
+
const x2 = xs[i + 1];
|
|
1727
|
+
if (x1 !== void 0 && x2 !== void 0) {
|
|
1728
|
+
intervals.push([x1, x2]);
|
|
1729
|
+
}
|
|
1730
|
+
}
|
|
1731
|
+
return intervals;
|
|
1732
|
+
}
|
|
1733
|
+
clipIntervals(intervals, a, b) {
|
|
1734
|
+
const out = [];
|
|
1735
|
+
for (const [L, R] of intervals) {
|
|
1736
|
+
const l = Math.max(a, L);
|
|
1737
|
+
const r = Math.min(b, R);
|
|
1738
|
+
if (r > l) out.push([l, r]);
|
|
1739
|
+
}
|
|
1740
|
+
return out;
|
|
1741
|
+
}
|
|
1742
|
+
regionIntervalsAtY(edges, y0, bx1, bx2, mode) {
|
|
1743
|
+
const inside = this.clipIntervals(
|
|
1744
|
+
this.scanlineIntervalsAtY(edges, y0),
|
|
1745
|
+
bx1,
|
|
1746
|
+
bx2
|
|
1747
|
+
);
|
|
1748
|
+
const outs = [];
|
|
1749
|
+
let prev = bx1;
|
|
1750
|
+
for (const [L, R] of inside) {
|
|
1751
|
+
if (L > prev) outs.push([prev, L]);
|
|
1752
|
+
prev = Math.max(prev, R);
|
|
1753
|
+
}
|
|
1754
|
+
if (prev < bx2) outs.push([prev, bx2]);
|
|
1755
|
+
return outs;
|
|
1756
|
+
}
|
|
1757
|
+
largestRectContainingPointRegion(edges, p, bounds, mode) {
|
|
1758
|
+
const BX1 = bounds.x;
|
|
1759
|
+
const BX2 = bounds.x + bounds.w;
|
|
1760
|
+
const BY1 = bounds.y;
|
|
1761
|
+
const BY2 = bounds.y + bounds.h;
|
|
1762
|
+
const intervals = this.regionIntervalsAtY(edges, p.y, BX1, BX2, mode);
|
|
1763
|
+
const interval = intervals.find(
|
|
1764
|
+
([xL, xR]) => xL - 1e-9 <= p.x && p.x <= xR + 1e-9
|
|
1765
|
+
);
|
|
1766
|
+
if (!interval) return null;
|
|
1767
|
+
let [X_L, X_R] = interval;
|
|
1768
|
+
const xset = /* @__PURE__ */ new Set([X_L, X_R]);
|
|
1769
|
+
for (const e of edges) {
|
|
1770
|
+
if (!this.isVertical(e)) continue;
|
|
1771
|
+
const x = e[0].x;
|
|
1772
|
+
if (X_L < x && x < X_R) xset.add(x);
|
|
1773
|
+
}
|
|
1774
|
+
const xs = Array.from(xset).sort((a, b) => a - b);
|
|
1775
|
+
const m = xs.length - 1;
|
|
1776
|
+
if (m <= 0) return null;
|
|
1777
|
+
const top = Array(m).fill(-Infinity);
|
|
1778
|
+
const bot = Array(m).fill(Infinity);
|
|
1779
|
+
for (let i = 0; i < m; i++) {
|
|
1780
|
+
const xi = xs[i];
|
|
1781
|
+
const xi1 = xs[i + 1];
|
|
1782
|
+
if (xi === void 0 || xi1 === void 0) continue;
|
|
1783
|
+
let xm = 0.5 * (xi + xi1);
|
|
1784
|
+
if (xset.has(xm)) xm += 1e-6;
|
|
1785
|
+
let minAbove = BY2;
|
|
1786
|
+
let maxBelow = BY1;
|
|
1787
|
+
for (const e of edges) {
|
|
1788
|
+
if (!this.isHorizontal(e)) continue;
|
|
1789
|
+
const y = e[0].y;
|
|
1790
|
+
const x1 = Math.min(e[0].x, e[1].x);
|
|
1791
|
+
const x2 = Math.max(e[0].x, e[1].x);
|
|
1792
|
+
if (x1 - 1e-9 <= xm && xm <= x2 + 1e-9) {
|
|
1793
|
+
if (y > p.y) minAbove = Math.min(minAbove, y);
|
|
1794
|
+
if (y < p.y) maxBelow = Math.max(maxBelow, y);
|
|
1795
|
+
}
|
|
1796
|
+
}
|
|
1797
|
+
if (!(maxBelow < minAbove)) {
|
|
1798
|
+
top[i] = -Infinity;
|
|
1799
|
+
bot[i] = Infinity;
|
|
1800
|
+
} else {
|
|
1801
|
+
top[i] = minAbove;
|
|
1802
|
+
bot[i] = maxBelow;
|
|
1803
|
+
}
|
|
1804
|
+
}
|
|
1805
|
+
let s0 = -1;
|
|
1806
|
+
for (let i = 0; i < m; i++) {
|
|
1807
|
+
const xi = xs[i];
|
|
1808
|
+
const xi1 = xs[i + 1];
|
|
1809
|
+
if (xi === void 0 || xi1 === void 0) continue;
|
|
1810
|
+
if (xi - 1e-9 <= p.x && p.x <= xi1 + 1e-9) {
|
|
1811
|
+
s0 = i;
|
|
1812
|
+
break;
|
|
1813
|
+
}
|
|
1814
|
+
}
|
|
1815
|
+
if (s0 === -1) return null;
|
|
1816
|
+
let best = null;
|
|
1817
|
+
let bestArea = -1;
|
|
1818
|
+
for (let i = 0; i <= s0; i++) {
|
|
1819
|
+
let minTop = Infinity;
|
|
1820
|
+
let maxBot = -Infinity;
|
|
1821
|
+
for (let j = i; j < m; j++) {
|
|
1822
|
+
const topJ = top[j];
|
|
1823
|
+
const botJ = bot[j];
|
|
1824
|
+
if (topJ === void 0 || botJ === void 0) continue;
|
|
1825
|
+
minTop = Math.min(minTop, topJ);
|
|
1826
|
+
maxBot = Math.max(maxBot, botJ);
|
|
1827
|
+
if (j < s0) continue;
|
|
1828
|
+
const height = Math.max(0, minTop - maxBot);
|
|
1829
|
+
if (height <= 0) continue;
|
|
1830
|
+
const xi = xs[i];
|
|
1831
|
+
const xj1 = xs[j + 1];
|
|
1832
|
+
if (xi === void 0 || xj1 === void 0) continue;
|
|
1833
|
+
const width = xj1 - xi;
|
|
1834
|
+
const area = width * height;
|
|
1835
|
+
if (area > bestArea) {
|
|
1836
|
+
bestArea = area;
|
|
1837
|
+
best = { x: xi, y: maxBot, w: width, h: height };
|
|
1838
|
+
}
|
|
1839
|
+
}
|
|
1840
|
+
}
|
|
1841
|
+
return best;
|
|
1842
|
+
}
|
|
1843
|
+
getLargestRect() {
|
|
1844
|
+
if (!this.solved) {
|
|
1845
|
+
this.solve();
|
|
1846
|
+
}
|
|
1847
|
+
return this.largestRect;
|
|
1848
|
+
}
|
|
1849
|
+
getLargestRectBounds() {
|
|
1850
|
+
if (!this.solved) {
|
|
1851
|
+
this.solve();
|
|
1852
|
+
}
|
|
1853
|
+
if (!this.largestRect) {
|
|
1854
|
+
return { minX: 0, minY: 0, maxX: 0, maxY: 0 };
|
|
1855
|
+
}
|
|
1856
|
+
return {
|
|
1857
|
+
minX: this.largestRect.x,
|
|
1858
|
+
minY: this.largestRect.y,
|
|
1859
|
+
maxX: this.largestRect.x + this.largestRect.w,
|
|
1860
|
+
maxY: this.largestRect.y + this.largestRect.h
|
|
1861
|
+
};
|
|
1862
|
+
}
|
|
1863
|
+
visualize() {
|
|
1864
|
+
const graphics = {
|
|
1865
|
+
lines: [],
|
|
1866
|
+
points: [],
|
|
1867
|
+
rects: [],
|
|
1868
|
+
circles: []
|
|
1869
|
+
};
|
|
1870
|
+
for (let i = 0; i < this.fullOutline.length; i++) {
|
|
1871
|
+
const p1 = this.fullOutline[i];
|
|
1872
|
+
const p2 = this.fullOutline[(i + 1) % this.fullOutline.length];
|
|
1873
|
+
if (p1 && p2) {
|
|
1874
|
+
graphics.lines.push({
|
|
1875
|
+
points: [p1, p2],
|
|
1876
|
+
strokeColor: "rgba(0,0,0,0.5)"
|
|
1877
|
+
});
|
|
1878
|
+
}
|
|
1879
|
+
}
|
|
1880
|
+
graphics.lines.push({
|
|
1881
|
+
points: [...this.fullOutline, this.fullOutline[0]],
|
|
1882
|
+
strokeColor: "rgba(200, 200, 200, 0.5)",
|
|
1883
|
+
strokeDash: [10, 5]
|
|
1884
|
+
});
|
|
1885
|
+
graphics.circles.push({
|
|
1886
|
+
center: this.origin,
|
|
1887
|
+
radius: 0.05,
|
|
1888
|
+
fill: "#f44336",
|
|
1889
|
+
label: "Origin"
|
|
1890
|
+
});
|
|
1891
|
+
if (this.largestRect) {
|
|
1892
|
+
graphics.rects.push({
|
|
1893
|
+
center: {
|
|
1894
|
+
x: this.largestRect.x + this.largestRect.w / 2,
|
|
1895
|
+
y: this.largestRect.y + this.largestRect.h / 2
|
|
1896
|
+
},
|
|
1897
|
+
width: this.largestRect.w,
|
|
1898
|
+
height: this.largestRect.h,
|
|
1899
|
+
fill: "rgba(0, 255, 0, 0.3)",
|
|
1900
|
+
stroke: "#4CAF50",
|
|
1901
|
+
label: `Largest Rectangle (Area: ${(this.largestRect.w * this.largestRect.h).toFixed(3)})`
|
|
1902
|
+
});
|
|
1903
|
+
}
|
|
1904
|
+
return graphics;
|
|
1905
|
+
}
|
|
1906
|
+
};
|
|
1584
1907
|
export {
|
|
1908
|
+
LargestRectOutsideOutlineFromPointSolver,
|
|
1585
1909
|
PhasedPackSolver,
|
|
1586
1910
|
convertCircuitJsonToPackOutput,
|
|
1587
1911
|
convertPackOutputToPackInput,
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "calculate-packing",
|
|
3
3
|
"main": "dist/index.js",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"version": "0.0.
|
|
5
|
+
"version": "0.0.20",
|
|
6
6
|
"description": "Calculate a packing layout with support for different strategy configurations",
|
|
7
7
|
"scripts": {
|
|
8
8
|
"start": "cosmos",
|
|
@@ -25,8 +25,10 @@
|
|
|
25
25
|
"@types/bun": "latest",
|
|
26
26
|
"@types/react": "^19.1.8",
|
|
27
27
|
"@types/react-dom": "^19.1.6",
|
|
28
|
+
"@vitejs/plugin-react": "^5.0.0",
|
|
28
29
|
"bun-match-svg": "^0.0.12",
|
|
29
30
|
"circuit-json": "^0.0.220",
|
|
31
|
+
"framer-motion": "^12.23.12",
|
|
30
32
|
"graphics-debug": "^0.0.62",
|
|
31
33
|
"react": "^19.1.0",
|
|
32
34
|
"react-cosmos": "^7.0.0",
|
|
@@ -34,7 +36,7 @@
|
|
|
34
36
|
"react-dom": "^19.1.0",
|
|
35
37
|
"tscircuit": "^0.0.562",
|
|
36
38
|
"tsup": "^8.5.0",
|
|
37
|
-
"vite": "^7.
|
|
39
|
+
"vite": "^7.1.2"
|
|
38
40
|
},
|
|
39
41
|
"peerDependencies": {
|
|
40
42
|
"typescript": "^5",
|