@tscircuit/runframe 0.0.994 → 0.0.996

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.
@@ -83,7 +83,7 @@ TabsContent.displayName = TabsPrimitive.Content.displayName;
83
83
 
84
84
  // lib/components/CircuitJsonPreview/CircuitJsonPreview.tsx
85
85
  import { CadViewer } from "@tscircuit/3d-viewer";
86
- import { useCallback as useCallback2, useEffect as useEffect12, useState as useState15, useMemo as useMemo7 } from "react";
86
+ import { useCallback as useCallback8, useEffect as useEffect12, useState as useState19, useMemo as useMemo8 } from "react";
87
87
 
88
88
  // lib/components/ErrorFallback.tsx
89
89
  import "react";
@@ -1067,7 +1067,7 @@ import {
1067
1067
  CheckIcon,
1068
1068
  EllipsisIcon,
1069
1069
  FullscreenIcon,
1070
- Loader2 as Loader23,
1070
+ Loader2 as Loader25,
1071
1071
  LoaderCircleIcon,
1072
1072
  MinimizeIcon,
1073
1073
  Circle as Circle2
@@ -1522,7 +1522,7 @@ var useEvalVersions = (allowSelecting) => {
1522
1522
  };
1523
1523
 
1524
1524
  // lib/components/FileMenuLeftHeader.tsx
1525
- import { useEffect as useEffect11, useMemo as useMemo6, useState as useState14 } from "react";
1525
+ import { useEffect as useEffect11, useMemo as useMemo7, useState as useState18 } from "react";
1526
1526
 
1527
1527
  // lib/components/RunFrameWithApi/store.ts
1528
1528
  import { applyEditEventsToManualEditsFile } from "@tscircuit/core";
@@ -1937,9 +1937,9 @@ var Checkbox = React8.forwardRef(({ className, ...props }, ref) => /* @__PURE__
1937
1937
  ));
1938
1938
  Checkbox.displayName = CheckboxPrimitive.Root.displayName;
1939
1939
 
1940
- // lib/components/ImportComponentDialog/ImportComponentDialog.tsx
1941
- import "react";
1942
- import { useState as useState8, useEffect as useEffect7 } from "react";
1940
+ // lib/components/ImportComponentDialog2/ImportComponentDialog2.tsx
1941
+ import * as React11 from "react";
1942
+ import { Loader2 as Loader23 } from "lucide-react";
1943
1943
 
1944
1944
  // lib/components/ui/dialog.tsx
1945
1945
  import * as React9 from "react";
@@ -2025,378 +2025,876 @@ var DialogDescription = React9.forwardRef(({ className, ...props }, ref) => /* @
2025
2025
  ));
2026
2026
  DialogDescription.displayName = DialogPrimitive.Description.displayName;
2027
2027
 
2028
- // lib/components/ImportComponentDialog/ImportComponentDialog.tsx
2029
- import { Loader2, Search, ExternalLink } from "lucide-react";
2028
+ // lib/components/ImportComponentDialog2/config.ts
2029
+ var SOURCE_CONFIG = {
2030
+ "tscircuit.com": {
2031
+ label: "tscircuit.com",
2032
+ placeholder: "Search tscircuit packages...",
2033
+ emptyMessage: "No packages found"
2034
+ },
2035
+ jlcpcb: {
2036
+ label: "JLCPCB Parts",
2037
+ placeholder: "Search JLCPCB parts (e.g. C14663)...",
2038
+ emptyMessage: "No parts found"
2039
+ },
2040
+ kicad: {
2041
+ label: "KiCad Footprints",
2042
+ placeholder: "Search KiCad footprints...",
2043
+ emptyMessage: "No footprints found"
2044
+ }
2045
+ };
2030
2046
 
2031
- // lib/components/ImportComponentDialog/jlc-api.ts
2032
- var searchJLCComponents = async (query, limit = 10) => {
2033
- try {
2034
- const encodedQuery = encodeURIComponent(query);
2035
- const response = await fetch(
2036
- `https://jlcsearch.tscircuit.com/api/search?limit=${limit}&q=${encodedQuery}`
2047
+ // lib/components/ImportComponentDialog2/api/jlcpcb.ts
2048
+ import { fetchEasyEDAComponent, convertRawEasyToTsx } from "easyeda/browser";
2049
+ var searchJlcpcbComponents = async (query, limit = 10) => {
2050
+ const encodedQuery = encodeURIComponent(query);
2051
+ const response = await fetch(
2052
+ `https://jlcsearch.tscircuit.com/api/search?limit=${limit}&q=${encodedQuery}`
2053
+ );
2054
+ if (!response.ok) {
2055
+ throw new Error(`JLCPCB API error: ${response.status}`);
2056
+ }
2057
+ const data = await response.json();
2058
+ return data.components ?? [];
2059
+ };
2060
+ var mapJlcpcbComponentToSummary = (component) => ({
2061
+ lcscId: component.lcsc,
2062
+ manufacturer: component.mfr,
2063
+ description: component.description,
2064
+ partNumber: `C${component.lcsc}`,
2065
+ package: component.package,
2066
+ price: component.price
2067
+ });
2068
+ var loadJlcpcbComponentTsx = async (partNumber, opts) => {
2069
+ const component = await fetchEasyEDAComponent(partNumber, {
2070
+ // @ts-ignore
2071
+ fetch: (url, options) => fetch(`${API_BASE}/proxy`, {
2072
+ ...options,
2073
+ headers: {
2074
+ ...options?.headers,
2075
+ "X-Target-Url": url.toString(),
2076
+ "X-Sender-Origin": options?.headers?.origin ?? "",
2077
+ "X-Sender-Host": options?.headers?.host ?? "https://easyeda.com",
2078
+ "X-Sender-Referer": options?.headers?.referer ?? "",
2079
+ "X-Sender-User-Agent": options?.headers?.userAgent ?? "",
2080
+ "X-Sender-Cookie": options?.headers?.cookie ?? "",
2081
+ ...opts?.headers
2082
+ }
2083
+ })
2084
+ });
2085
+ return convertRawEasyToTsx(component);
2086
+ };
2087
+
2088
+ // lib/components/ImportComponentDialog2/components/SearchBar.tsx
2089
+ import * as React10 from "react";
2090
+ import { Loader2, Search } from "lucide-react";
2091
+ import { Fragment as Fragment3, jsx as jsx21, jsxs as jsxs15 } from "react/jsx-runtime";
2092
+ var SearchBar = ({
2093
+ query,
2094
+ placeholder,
2095
+ isSearching,
2096
+ onQueryChange,
2097
+ onSubmit
2098
+ }) => {
2099
+ const handleKeyDown = React10.useCallback(
2100
+ (event) => {
2101
+ if (event.key === "Enter") {
2102
+ event.preventDefault();
2103
+ onSubmit();
2104
+ }
2105
+ },
2106
+ [onSubmit]
2107
+ );
2108
+ return /* @__PURE__ */ jsxs15("div", { className: "rf-flex rf-items-center rf-gap-2 rf-mt-4", children: [
2109
+ /* @__PURE__ */ jsxs15("div", { className: "rf-relative rf-flex-grow", children: [
2110
+ /* @__PURE__ */ jsx21(Search, { className: "rf-absolute rf-left-2 rf-top-2.5 rf-h-4 rf-w-4 rf-text-muted-foreground" }),
2111
+ /* @__PURE__ */ jsx21(
2112
+ Input,
2113
+ {
2114
+ placeholder,
2115
+ className: "rf-pl-8",
2116
+ spellCheck: false,
2117
+ autoComplete: "off",
2118
+ value: query,
2119
+ onChange: (event) => onQueryChange(event.target.value),
2120
+ onKeyDown: handleKeyDown
2121
+ }
2122
+ )
2123
+ ] }),
2124
+ /* @__PURE__ */ jsx21(
2125
+ Button,
2126
+ {
2127
+ onClick: onSubmit,
2128
+ disabled: isSearching || query.trim().length < 1,
2129
+ className: "sm:rf-px-4 rf-px-3",
2130
+ children: isSearching ? /* @__PURE__ */ jsx21(Loader2, { className: "rf-h-4 rf-w-4 rf-animate-spin" }) : /* @__PURE__ */ jsxs15(Fragment3, { children: [
2131
+ /* @__PURE__ */ jsx21(Search, { className: "rf-h-4 rf-w-4 sm:rf-hidden" }),
2132
+ /* @__PURE__ */ jsx21("span", { className: "rf-hidden sm:rf-inline", children: "Search" })
2133
+ ] })
2134
+ }
2135
+ )
2136
+ ] });
2137
+ };
2138
+
2139
+ // lib/components/ImportComponentDialog2/components/SearchResultsList.tsx
2140
+ import { jsx as jsx22, jsxs as jsxs16 } from "react/jsx-runtime";
2141
+ var getResultKey = (result) => {
2142
+ switch (result.source) {
2143
+ case "tscircuit.com": {
2144
+ const pkg = result.package;
2145
+ const identifier = pkg.package_id ?? `${pkg.owner_github_username ?? "unknown"}-${pkg.unscoped_name ?? pkg.name ?? "package"}`;
2146
+ return `tscircuit-${identifier}`;
2147
+ }
2148
+ case "jlcpcb":
2149
+ return `jlc-${result.component.lcscId}`;
2150
+ case "kicad":
2151
+ return `kicad-${result.footprint.path}`;
2152
+ default:
2153
+ return "unknown";
2154
+ }
2155
+ };
2156
+ var getPrimaryText = (result) => {
2157
+ switch (result.source) {
2158
+ case "tscircuit.com":
2159
+ return result.package.unscoped_name;
2160
+ case "jlcpcb":
2161
+ return result.component.manufacturer;
2162
+ case "kicad":
2163
+ return result.footprint.qualifiedName;
2164
+ }
2165
+ };
2166
+ var getSecondaryText = (result) => {
2167
+ switch (result.source) {
2168
+ case "tscircuit.com":
2169
+ return result.package.description || (result.package.owner_github_username ? `Component by ${result.package.owner_github_username}` : void 0);
2170
+ case "jlcpcb":
2171
+ return result.component.description;
2172
+ case "kicad":
2173
+ return result.footprint.description;
2174
+ }
2175
+ };
2176
+ var getPartNumberLabel = (result) => {
2177
+ switch (result.source) {
2178
+ case "tscircuit.com":
2179
+ return result.package.name;
2180
+ case "jlcpcb":
2181
+ return result.component.partNumber;
2182
+ case "kicad":
2183
+ return void 0;
2184
+ }
2185
+ };
2186
+ var SearchResultsList = ({
2187
+ results,
2188
+ selected,
2189
+ onSelect,
2190
+ onShowDetails
2191
+ }) => {
2192
+ const selectedKey = selected ? getResultKey(selected) : null;
2193
+ return /* @__PURE__ */ jsx22("div", { className: "rf-divide-y", children: results.map((result) => {
2194
+ const key = getResultKey(result);
2195
+ const isSelected = selectedKey === key;
2196
+ const primary = getPrimaryText(result);
2197
+ const secondary = getSecondaryText(result);
2198
+ const partNumber = getPartNumberLabel(result);
2199
+ return /* @__PURE__ */ jsxs16(
2200
+ "div",
2201
+ {
2202
+ className: `rf-p-3 rf-flex rf-flex-col sm:rf-grid sm:rf-grid-cols-[1fr_auto] rf-items-start sm:rf-items-center rf-cursor-pointer hover:rf-bg-zinc-100 rf-gap-2 ${isSelected ? "rf-bg-zinc-100" : ""}`,
2203
+ onClick: () => onSelect(result),
2204
+ children: [
2205
+ /* @__PURE__ */ jsxs16("div", { className: "rf-min-w-0 rf-overflow-hidden", children: [
2206
+ /* @__PURE__ */ jsx22("div", { className: "rf-font-medium rf-text-sm rf-truncate", children: primary }),
2207
+ /* @__PURE__ */ jsxs16("div", { className: "rf-text-xs rf-text-zinc-500 rf-truncate", children: [
2208
+ partNumber ? /* @__PURE__ */ jsx22("span", { className: "rf-mr-2", children: partNumber }) : null,
2209
+ secondary
2210
+ ] })
2211
+ ] }),
2212
+ result.source === "tscircuit.com" && onShowDetails ? /* @__PURE__ */ jsx22("div", { className: "rf-flex rf-gap-2 rf-flex-shrink-0 rf-w-full sm:rf-w-auto", children: /* @__PURE__ */ jsx22(
2213
+ Button,
2214
+ {
2215
+ variant: "outline",
2216
+ size: "sm",
2217
+ className: "rf-text-xs rf-w-full sm:rf-w-auto",
2218
+ onClick: (event) => {
2219
+ event.stopPropagation();
2220
+ onShowDetails(result);
2221
+ },
2222
+ children: "See Details"
2223
+ }
2224
+ ) }) : null
2225
+ ]
2226
+ },
2227
+ key
2037
2228
  );
2038
- if (!response.ok) {
2039
- throw new Error(
2040
- `JLC API error: ${response.status} ${response.statusText}`
2229
+ }) });
2230
+ };
2231
+
2232
+ // lib/components/ImportComponentDialog2/components/TscircuitPackageDetailsDialog.tsx
2233
+ import { ExternalLink, Loader2 as Loader22 } from "lucide-react";
2234
+ import { jsx as jsx23, jsxs as jsxs17 } from "react/jsx-runtime";
2235
+ var buildPreviewUrl = (pkg, tab) => {
2236
+ if (!pkg?.owner_github_username || !pkg?.unscoped_name) return null;
2237
+ return `https://registry-api.tscircuit.com/packages/images/${pkg.owner_github_username}/${pkg.unscoped_name}/${tab}.png`;
2238
+ };
2239
+ var TscircuitPackageDetailsDialog = ({
2240
+ packageResult,
2241
+ isOpen,
2242
+ onOpenChange,
2243
+ isLoading,
2244
+ details,
2245
+ previewTab,
2246
+ onPreviewTabChange,
2247
+ isSubmitting,
2248
+ onImport
2249
+ }) => {
2250
+ const pkg = packageResult?.package ?? null;
2251
+ const pcbPreviewUrl = buildPreviewUrl(pkg, "pcb");
2252
+ const schematicPreviewUrl = buildPreviewUrl(pkg, "schematic");
2253
+ const packageName = pkg?.unscoped_name?.split("/").pop() ?? pkg?.unscoped_name;
2254
+ const ownerUsername = pkg?.owner_github_username ?? void 0;
2255
+ const ownerUrl = ownerUsername ? `https://tscircuit.com/${ownerUsername}` : void 0;
2256
+ const packageUrl = ownerUsername && packageName ? `https://tscircuit.com/${ownerUsername}/${packageName}` : void 0;
2257
+ return /* @__PURE__ */ jsx23(Dialog, { open: isOpen, onOpenChange, children: /* @__PURE__ */ jsxs17(
2258
+ DialogContent,
2259
+ {
2260
+ showOverlay: false,
2261
+ style: { width: "calc(100vw - 2rem)" },
2262
+ className: "rf-max-w-5xl !rf-overflow-y-auto rf-max-h-[90vh] rf-overflow-hidden rf-flex rf-flex-col rf-rounded-sm",
2263
+ children: [
2264
+ /* @__PURE__ */ jsx23(DialogHeader, { className: "rf-pb-4 rf-border-b", children: /* @__PURE__ */ jsx23("div", { className: "rf-flex rf-items-start rf-justify-between rf-gap-4", children: /* @__PURE__ */ jsxs17("div", { className: "rf-flex-1 rf-min-w-0", children: [
2265
+ /* @__PURE__ */ jsx23(DialogTitle, { className: "rf-text-xl rf-font-semibold rf-truncate", children: packageName }),
2266
+ /* @__PURE__ */ jsx23(DialogDescription, { children: pkg?.description })
2267
+ ] }) }) }),
2268
+ /* @__PURE__ */ jsxs17("div", { className: "rf-flex-1 rf-overflow-y-auto rf-py-4 rf-space-y-6", children: [
2269
+ ownerUsername ? /* @__PURE__ */ jsxs17("div", { children: [
2270
+ /* @__PURE__ */ jsx23("span", { className: "rf-text-xs rf-font-medium rf-text-gray-500 rf-uppercase rf-tracking-wide", children: "Created by" }),
2271
+ /* @__PURE__ */ jsx23("div", { className: "rf-mt-1 rf-text-sm rf-font-medium", children: ownerUrl ? /* @__PURE__ */ jsx23(
2272
+ "a",
2273
+ {
2274
+ href: ownerUrl,
2275
+ target: "_blank",
2276
+ rel: "noopener noreferrer",
2277
+ className: "rf-text-black hover:rf-underline",
2278
+ children: ownerUsername
2279
+ }
2280
+ ) : ownerUsername })
2281
+ ] }) : null,
2282
+ /* @__PURE__ */ jsxs17("div", { children: [
2283
+ /* @__PURE__ */ jsx23("h3", { className: "rf-text-lg rf-font-semibold rf-mb-4", children: "Preview" }),
2284
+ /* @__PURE__ */ jsxs17(
2285
+ Tabs,
2286
+ {
2287
+ value: previewTab,
2288
+ onValueChange: (value) => onPreviewTabChange(value),
2289
+ children: [
2290
+ /* @__PURE__ */ jsxs17(TabsList, { className: "rf-inline-flex rf-h-9 rf-items-center rf-justify-center rf-rounded-lg rf-bg-zinc-100 rf-p-1 rf-text-zinc-500 dark:rf-bg-zinc-800 dark:rf-text-zinc-400", children: [
2291
+ /* @__PURE__ */ jsx23(TabsTrigger, { value: "pcb", children: "PCB" }),
2292
+ /* @__PURE__ */ jsx23(TabsTrigger, { value: "schematic", children: "Schematic" })
2293
+ ] }),
2294
+ /* @__PURE__ */ jsxs17("div", { className: "rf-mt-4", children: [
2295
+ /* @__PURE__ */ jsx23(
2296
+ TabsContent,
2297
+ {
2298
+ value: "pcb",
2299
+ className: "rf-border rf-rounded-lg rf-overflow-hidden rf-bg-gray-50",
2300
+ children: pcbPreviewUrl ? /* @__PURE__ */ jsx23(
2301
+ "img",
2302
+ {
2303
+ src: pcbPreviewUrl,
2304
+ alt: `${packageName ?? "package"} PCB preview`,
2305
+ className: "rf-w-full rf-h-full rf-object-contain rf-bg-white rf-p-4"
2306
+ }
2307
+ ) : null
2308
+ }
2309
+ ),
2310
+ /* @__PURE__ */ jsx23(
2311
+ TabsContent,
2312
+ {
2313
+ value: "schematic",
2314
+ className: "rf-border rf-rounded-lg rf-overflow-hidden rf-bg-gray-50",
2315
+ children: schematicPreviewUrl ? /* @__PURE__ */ jsx23(
2316
+ "img",
2317
+ {
2318
+ src: schematicPreviewUrl,
2319
+ alt: `${packageName ?? "package"} schematic preview`,
2320
+ className: "rf-w-full rf-h-full rf-object-contain rf-bg-white rf-p-4"
2321
+ }
2322
+ ) : null
2323
+ }
2324
+ )
2325
+ ] })
2326
+ ]
2327
+ }
2328
+ )
2329
+ ] }),
2330
+ details?.ai_description ? /* @__PURE__ */ jsxs17("section", { children: [
2331
+ /* @__PURE__ */ jsx23("h3", { className: "rf-text-lg rf-font-semibold rf-mb-3", children: "AI Description" }),
2332
+ /* @__PURE__ */ jsx23("div", { className: "rf-bg-gray-50 rf-border rf-border-gray-200 rf-rounded-lg rf-p-4", children: /* @__PURE__ */ jsx23("p", { className: "rf-text-sm rf-text-gray-700 rf-leading-relaxed", children: details.ai_description }) })
2333
+ ] }) : null,
2334
+ details?.ai_usage_instructions ? /* @__PURE__ */ jsxs17("section", { children: [
2335
+ /* @__PURE__ */ jsx23("h3", { className: "rf-text-lg rf-font-semibold rf-mb-3", children: "Usage Instructions" }),
2336
+ /* @__PURE__ */ jsx23("div", { className: "rf-bg-gray-50 rf-border rf-border-gray-200 rf-rounded-lg rf-p-4", children: /* @__PURE__ */ jsx23("p", { className: "rf-text-sm rf-text-gray-700 rf-leading-relaxed rf-whitespace-pre-wrap", children: details.ai_usage_instructions }) })
2337
+ ] }) : null,
2338
+ isLoading ? /* @__PURE__ */ jsxs17("div", { className: "rf-flex rf-justify-center rf-items-center rf-gap-2 rf-text-gray-500", children: [
2339
+ /* @__PURE__ */ jsx23(Loader22, { className: "rf-h-4 rf-w-4 rf-animate-spin" }),
2340
+ /* @__PURE__ */ jsx23("span", { className: "rf-text-sm", children: "Loading package details..." })
2341
+ ] }) : null
2342
+ ] }),
2343
+ /* @__PURE__ */ jsxs17(DialogFooter, { className: "rf-pt-4 rf-border-t rf-flex rf-flex-col sm:rf-flex-row rf-justify-between rf-gap-2", children: [
2344
+ /* @__PURE__ */ jsx23("div", { className: "rf-flex-1", children: packageUrl ? /* @__PURE__ */ jsxs17(
2345
+ Button,
2346
+ {
2347
+ variant: "outline",
2348
+ size: "sm",
2349
+ className: "rf-gap-2 rf-w-full sm:rf-w-auto",
2350
+ onClick: () => window.open(packageUrl, "_blank"),
2351
+ children: [
2352
+ /* @__PURE__ */ jsx23(ExternalLink, { className: "rf-h-4 rf-w-4" }),
2353
+ "View on tscircuit.com"
2354
+ ]
2355
+ }
2356
+ ) : null }),
2357
+ /* @__PURE__ */ jsxs17("div", { className: "rf-flex rf-flex-col sm:rf-flex-row rf-gap-2", children: [
2358
+ /* @__PURE__ */ jsx23(
2359
+ Button,
2360
+ {
2361
+ variant: "outline",
2362
+ onClick: () => onOpenChange(false),
2363
+ className: "rf-order-2 sm:rf-order-1",
2364
+ children: "Close"
2365
+ }
2366
+ ),
2367
+ /* @__PURE__ */ jsx23(
2368
+ Button,
2369
+ {
2370
+ onClick: onImport,
2371
+ disabled: isSubmitting,
2372
+ className: "rf-bg-blue-600 hover:rf-bg-blue-700",
2373
+ children: isSubmitting ? /* @__PURE__ */ jsx23(Loader22, { className: "rf-h-4 rf-w-4 rf-animate-spin" }) : "Import Component"
2374
+ }
2375
+ )
2376
+ ] })
2377
+ ] })
2378
+ ]
2379
+ }
2380
+ ) });
2381
+ };
2382
+
2383
+ // lib/components/ImportComponentDialog2/hooks/useTscircuitPackageDetails.ts
2384
+ import { useCallback as useCallback2, useState as useState8 } from "react";
2385
+ var useTscircuitPackageDetails = () => {
2386
+ const [details, setDetails] = useState8(null);
2387
+ const [isLoading, setIsLoading] = useState8(false);
2388
+ const fetchDetails = useCallback2(async (owner, name) => {
2389
+ setIsLoading(true);
2390
+ try {
2391
+ const response = await fetch(
2392
+ `https://api.tscircuit.com/packages/get?name=${encodeURIComponent(`${owner}/${name}`)}`
2393
+ );
2394
+ if (!response.ok) {
2395
+ throw new Error(`Failed to load package details: ${response.status}`);
2396
+ }
2397
+ const data = await response.json();
2398
+ setDetails(
2399
+ data.package ?? null
2041
2400
  );
2401
+ } catch (error) {
2402
+ console.error("Failed to fetch package details", error);
2403
+ setDetails(null);
2404
+ } finally {
2405
+ setIsLoading(false);
2042
2406
  }
2043
- const data = await response.json();
2044
- return data.components || [];
2045
- } catch (error) {
2046
- console.error("Error searching JLC components:", error);
2047
- throw error;
2407
+ }, []);
2408
+ const reset = useCallback2(() => {
2409
+ setDetails(null);
2410
+ setIsLoading(false);
2411
+ }, []);
2412
+ return {
2413
+ details,
2414
+ isLoading,
2415
+ fetchDetails,
2416
+ reset
2417
+ };
2418
+ };
2419
+
2420
+ // lib/components/ImportComponentDialog2/hooks/useTscircuitPackageSearch.ts
2421
+ import { useCallback as useCallback3, useState as useState9 } from "react";
2422
+
2423
+ // lib/components/ImportComponentDialog2/api/tscircuit.ts
2424
+ var searchTscircuitPackages = async (query) => {
2425
+ const response = await fetch(
2426
+ "https://registry-api.tscircuit.com/packages/search",
2427
+ {
2428
+ method: "POST",
2429
+ headers: {
2430
+ "Content-Type": "application/json"
2431
+ },
2432
+ body: JSON.stringify({ query })
2433
+ }
2434
+ );
2435
+ if (!response.ok) {
2436
+ throw new Error(`tscircuit registry error: ${response.status}`);
2048
2437
  }
2438
+ const data = await response.json();
2439
+ return data.packages ?? [];
2049
2440
  };
2050
- var mapJLCComponentToSearchResult = (jlcComponent) => {
2441
+
2442
+ // lib/components/ImportComponentDialog2/hooks/useTscircuitPackageSearch.ts
2443
+ var useTscircuitPackageSearch = () => {
2444
+ const [results, setResults] = useState9([]);
2445
+ const [isSearching, setIsSearching] = useState9(false);
2446
+ const [error, setError] = useState9(null);
2447
+ const [hasSearched, setHasSearched] = useState9(false);
2448
+ const search = useCallback3(async (query) => {
2449
+ const trimmedQuery = query.trim();
2450
+ if (!trimmedQuery) return [];
2451
+ setIsSearching(true);
2452
+ setError(null);
2453
+ try {
2454
+ const packages = await searchTscircuitPackages(trimmedQuery);
2455
+ const mappedResults = packages.map((pkg) => ({
2456
+ source: "tscircuit.com",
2457
+ package: pkg
2458
+ }));
2459
+ setResults(mappedResults);
2460
+ return mappedResults;
2461
+ } catch (error2) {
2462
+ console.error("Error searching tscircuit packages", error2);
2463
+ setResults([]);
2464
+ setError(
2465
+ error2 instanceof Error ? error2.message : "Failed to search tscircuit packages"
2466
+ );
2467
+ return [];
2468
+ } finally {
2469
+ setIsSearching(false);
2470
+ setHasSearched(true);
2471
+ }
2472
+ }, []);
2473
+ const reset = useCallback3(() => {
2474
+ setResults([]);
2475
+ setIsSearching(false);
2476
+ setError(null);
2477
+ setHasSearched(false);
2478
+ }, []);
2051
2479
  return {
2052
- id: `jlc-${jlcComponent.lcsc}`,
2053
- name: jlcComponent.mfr,
2054
- description: jlcComponent.description,
2055
- source: "jlcpcb",
2056
- partNumber: `C${jlcComponent.lcsc}`,
2057
- package: jlcComponent.package,
2058
- price: jlcComponent.price
2480
+ results,
2481
+ isSearching,
2482
+ error,
2483
+ hasSearched,
2484
+ search,
2485
+ reset
2059
2486
  };
2060
2487
  };
2061
2488
 
2062
- // lib/components/ImportComponentDialog/kicad-api.ts
2489
+ // lib/components/ImportComponentDialog2/hooks/useJlcpcbComponentSearch.ts
2490
+ import { useCallback as useCallback4, useState as useState10 } from "react";
2491
+ var normalizeQuery = (query) => {
2492
+ const trimmedQuery = query.trim();
2493
+ const isPartNumber = /^C\d+/i.test(trimmedQuery);
2494
+ if (isPartNumber) {
2495
+ return trimmedQuery.replace(/^C/i, "");
2496
+ }
2497
+ return trimmedQuery;
2498
+ };
2499
+ var useJlcpcbComponentSearch = () => {
2500
+ const [results, setResults] = useState10([]);
2501
+ const [isSearching, setIsSearching] = useState10(false);
2502
+ const [error, setError] = useState10(null);
2503
+ const [hasSearched, setHasSearched] = useState10(false);
2504
+ const search = useCallback4(async (query) => {
2505
+ const normalizedQuery = normalizeQuery(query);
2506
+ if (!normalizedQuery) return [];
2507
+ setIsSearching(true);
2508
+ setError(null);
2509
+ try {
2510
+ const components = await searchJlcpcbComponents(normalizedQuery, 10);
2511
+ const mappedResults = components.map((component) => ({
2512
+ source: "jlcpcb",
2513
+ component: mapJlcpcbComponentToSummary(component)
2514
+ }));
2515
+ setResults(mappedResults);
2516
+ return mappedResults;
2517
+ } catch (error2) {
2518
+ console.error("Error searching JLCPCB components", error2);
2519
+ setResults([]);
2520
+ setError(
2521
+ error2 instanceof Error ? error2.message : "Failed to search JLCPCB components"
2522
+ );
2523
+ return [];
2524
+ } finally {
2525
+ setIsSearching(false);
2526
+ setHasSearched(true);
2527
+ }
2528
+ }, []);
2529
+ const reset = useCallback4(() => {
2530
+ setResults([]);
2531
+ setIsSearching(false);
2532
+ setError(null);
2533
+ setHasSearched(false);
2534
+ }, []);
2535
+ return {
2536
+ results,
2537
+ isSearching,
2538
+ error,
2539
+ hasSearched,
2540
+ search,
2541
+ reset
2542
+ };
2543
+ };
2544
+
2545
+ // lib/components/ImportComponentDialog2/hooks/useKicadFootprintSearch.ts
2546
+ import { useCallback as useCallback5, useState as useState11 } from "react";
2547
+
2548
+ // lib/components/ImportComponentDialog2/api/kicad.ts
2063
2549
  import Fuse from "fuse.js";
2064
- var KICAD_FOOTPRINTS = null;
2065
- var KICAD_FOOTPRINTS_PROMISE = null;
2066
- var getKicadFootprints = async () => {
2067
- if (KICAD_FOOTPRINTS) return KICAD_FOOTPRINTS;
2068
- if (KICAD_FOOTPRINTS_PROMISE) return KICAD_FOOTPRINTS_PROMISE;
2069
- KICAD_FOOTPRINTS_PROMISE = fetch(
2550
+ var footprintsCache = null;
2551
+ var footprintsPromise = null;
2552
+ var fuse = null;
2553
+ var ensureFootprints = async () => {
2554
+ if (footprintsCache) return footprintsCache;
2555
+ if (footprintsPromise) return footprintsPromise;
2556
+ footprintsPromise = fetch(
2070
2557
  "https://kicad-mod-cache.tscircuit.com/kicad_files.json"
2071
- ).then((r) => r.json()).then((footprints) => {
2072
- KICAD_FOOTPRINTS = footprints;
2073
- KICAD_FOOTPRINTS_PROMISE = null;
2558
+ ).then((response) => response.json()).then((footprints) => {
2559
+ footprintsCache = footprints;
2560
+ footprintsPromise = null;
2074
2561
  return footprints;
2075
2562
  });
2076
- return KICAD_FOOTPRINTS_PROMISE;
2563
+ return footprintsPromise;
2077
2564
  };
2078
- var fuse = null;
2079
2565
  var searchKicadFootprints = async (query, limit = 20) => {
2080
- const footprints = await getKicadFootprints();
2566
+ const footprints = await ensureFootprints();
2081
2567
  if (!fuse) {
2082
2568
  fuse = new Fuse(footprints);
2083
2569
  }
2084
- return fuse.search(query).slice(0, limit).map((r) => r.item);
2570
+ return fuse.search(query).slice(0, limit).map((result) => result.item);
2085
2571
  };
2086
- var mapKicadFootprintToSearchResult = (footprintPath) => {
2572
+ var mapKicadFootprintToSummary = (footprintPath) => {
2087
2573
  const cleanedFootprint = footprintPath.replace(".pretty/", ":").replace(".kicad_mod", "");
2088
2574
  const footprintString = `kicad:${cleanedFootprint}`;
2089
2575
  return {
2090
- id: `kicad-${footprintPath}`,
2091
- name: footprintString,
2092
- description: cleanedFootprint,
2093
- source: "kicad"
2576
+ path: footprintPath,
2577
+ qualifiedName: footprintString,
2578
+ description: cleanedFootprint
2094
2579
  };
2095
2580
  };
2096
2581
 
2097
- // lib/components/ImportComponentDialog/tscircuit-registry-api.ts
2098
- var searchTscircuitComponents = async (query) => {
2099
- try {
2100
- const response = await fetch(
2101
- "https://registry-api.tscircuit.com/packages/search",
2102
- {
2103
- method: "POST",
2104
- headers: {
2105
- "Content-Type": "application/json"
2106
- },
2107
- body: JSON.stringify({ query })
2108
- }
2109
- );
2110
- if (!response.ok) {
2111
- throw new Error(
2112
- `tscircuit Registry API error: ${response.status} ${response.statusText}`
2582
+ // lib/components/ImportComponentDialog2/hooks/useKicadFootprintSearch.ts
2583
+ var useKicadFootprintSearch = () => {
2584
+ const [results, setResults] = useState11([]);
2585
+ const [isSearching, setIsSearching] = useState11(false);
2586
+ const [error, setError] = useState11(null);
2587
+ const [hasSearched, setHasSearched] = useState11(false);
2588
+ const search = useCallback5(async (query) => {
2589
+ const trimmedQuery = query.trim();
2590
+ if (!trimmedQuery) return [];
2591
+ setIsSearching(true);
2592
+ setError(null);
2593
+ try {
2594
+ const footprints = await searchKicadFootprints(trimmedQuery, 20);
2595
+ const mappedResults = footprints.map((footprintPath) => ({
2596
+ source: "kicad",
2597
+ footprint: mapKicadFootprintToSummary(footprintPath)
2598
+ }));
2599
+ setResults(mappedResults);
2600
+ return mappedResults;
2601
+ } catch (error2) {
2602
+ console.error("Error searching KiCad footprints", error2);
2603
+ setResults([]);
2604
+ setError(
2605
+ error2 instanceof Error ? error2.message : "Failed to search KiCad footprints"
2113
2606
  );
2607
+ return [];
2608
+ } finally {
2609
+ setIsSearching(false);
2610
+ setHasSearched(true);
2114
2611
  }
2115
- const data = await response.json();
2116
- return data.packages || [];
2117
- } catch (error) {
2118
- console.error("Error searching tscircuit components:", error);
2119
- throw error;
2120
- }
2121
- };
2122
- var mapTscircuitSnippetToSearchResult = (tscircuitSnippet) => {
2612
+ }, []);
2613
+ const reset = useCallback5(() => {
2614
+ setResults([]);
2615
+ setIsSearching(false);
2616
+ setError(null);
2617
+ setHasSearched(false);
2618
+ }, []);
2123
2619
  return {
2124
- id: `tscircuit-${tscircuitSnippet.package_id}`,
2125
- name: tscircuitSnippet.unscoped_name,
2126
- description: tscircuitSnippet.description || `Component by ${tscircuitSnippet.owner_github_username}`,
2127
- source: "tscircuit.com",
2128
- partNumber: tscircuitSnippet.name,
2129
- owner: String(tscircuitSnippet.owner_github_username)
2620
+ results,
2621
+ isSearching,
2622
+ error,
2623
+ hasSearched,
2624
+ search,
2625
+ reset
2130
2626
  };
2131
2627
  };
2132
2628
 
2133
- // lib/optional-features/importing/import-component-from-jlcpcb.ts
2134
- import { fetchEasyEDAComponent, convertRawEasyToTsx } from "easyeda/browser";
2135
- import ky from "ky";
2136
- var importComponentFromJlcpcb = async (jlcpcbPartNumber, opts) => {
2137
- const component = await fetchEasyEDAComponent(jlcpcbPartNumber, {
2138
- // @ts-ignore
2139
- fetch: (url, options) => {
2140
- return fetch(`${API_BASE}/proxy`, {
2141
- ...options,
2142
- headers: {
2143
- ...options?.headers,
2144
- "X-Target-Url": url.toString(),
2145
- "X-Sender-Origin": options?.headers?.origin ?? "",
2146
- "X-Sender-Host": options?.headers?.host ?? "https://easyeda.com",
2147
- "X-Sender-Referer": options?.headers?.referer ?? "",
2148
- "X-Sender-User-Agent": options?.headers?.userAgent ?? "",
2149
- "X-Sender-Cookie": options?.headers?.cookie ?? "",
2150
- ...opts?.headers
2151
- }
2152
- });
2153
- }
2154
- });
2155
- const tsx = await convertRawEasyToTsx(component);
2156
- const fileName = tsx.match(/export const (\w+) = .*/)?.[1];
2157
- if (!fileName) {
2158
- console.error("COULD NOT DETERMINE FILE NAME OF CONVERTED COMPONENT:", tsx);
2159
- throw new Error(`Could not determine file name of converted component`);
2160
- }
2161
- const filePath = `imports/${fileName}.tsx`;
2162
- await ky.post(`${API_BASE}/files/upsert`, {
2163
- json: {
2164
- file_path: filePath,
2165
- text_content: tsx
2166
- }
2167
- });
2168
- return { filePath };
2629
+ // lib/components/ImportComponentDialog2/ImportComponentDialog2.tsx
2630
+ import { jsx as jsx24, jsxs as jsxs18 } from "react/jsx-runtime";
2631
+ var computeAvailableSources = ({
2632
+ onTscircuitPackageSelected,
2633
+ onJlcpcbComponentTsxLoaded,
2634
+ onKicadStringSelected
2635
+ }) => {
2636
+ const sources = [];
2637
+ if (onTscircuitPackageSelected) sources.push("tscircuit.com");
2638
+ if (onJlcpcbComponentTsxLoaded) sources.push("jlcpcb");
2639
+ if (onKicadStringSelected) sources.push("kicad");
2640
+ return sources;
2169
2641
  };
2170
-
2171
- // lib/utils/toast.ts
2172
- import { toast } from "react-hot-toast";
2173
-
2174
- // lib/components/ImportComponentDialog/ImportComponentDialog.tsx
2175
- import Debug2 from "debug";
2176
- import { Fragment as Fragment3, jsx as jsx21, jsxs as jsxs15 } from "react/jsx-runtime";
2177
- var debug3 = Debug2("run-frame:ImportComponentDialog");
2178
- var ImportComponentDialog = ({
2642
+ var ImportComponentDialog2 = ({
2179
2643
  isOpen,
2180
2644
  onClose,
2181
- proxyRequestHeaders,
2182
- onImport
2645
+ jlcpcbProxyRequestHeaders,
2646
+ onKicadStringSelected,
2647
+ onTscircuitPackageSelected,
2648
+ onJlcpcbComponentTsxLoaded
2183
2649
  }) => {
2184
- const [searchQuery, setSearchQuery] = useState8("");
2185
- const [searchResults, setSearchResults] = useState8(
2186
- []
2650
+ const availableSources = React11.useMemo(
2651
+ () => computeAvailableSources({
2652
+ onKicadStringSelected,
2653
+ onTscircuitPackageSelected,
2654
+ onJlcpcbComponentTsxLoaded
2655
+ }),
2656
+ [
2657
+ onKicadStringSelected,
2658
+ onTscircuitPackageSelected,
2659
+ onJlcpcbComponentTsxLoaded
2660
+ ]
2187
2661
  );
2188
- const [hasSearched, setHasSearched] = useState8(false);
2189
- const [isLoading, setIsLoading] = useState8(false);
2190
- const [selectedComponent, setSelectedComponent] = useState8(null);
2191
- const [activeTab, setActiveTab] = useState8("tscircuit.com");
2192
- const [detailsOpen, setDetailsOpen] = useState8(false);
2193
- const [detailsComponent, setDetailsComponent] = useState8(null);
2194
- const [packageDetails, setPackageDetails] = useState8(null);
2195
- const [packageDetailsLoading, setPackageDetailsLoading] = useState8(false);
2196
- const [previewActiveTab, setPreviewActiveTab] = useState8(
2197
- "pcb"
2662
+ const hasSources = availableSources.length > 0;
2663
+ const [activeSource, setActiveSource] = React11.useState(
2664
+ availableSources[0] ?? "tscircuit.com"
2198
2665
  );
2199
- const pushEvent = useRunFrameStore((s) => s.pushEvent);
2200
- const handleImport = onImport ? (component) => onImport(component) : (component) => {
2201
- toast.promise(
2202
- async () => {
2203
- if (component.source === "tscircuit.com") {
2204
- await pushEvent({
2205
- event_type: "INSTALL_PACKAGE",
2206
- full_package_name: `@tsci/${component.owner}.${component.name}`
2207
- });
2208
- throw new Error("Not implemented");
2209
- } else if (component.source === "jlcpcb") {
2210
- const { filePath } = await importComponentFromJlcpcb(
2211
- component.partNumber,
2212
- { headers: proxyRequestHeaders }
2213
- );
2214
- return { filePath };
2215
- } else if (component.source === "kicad") {
2216
- await navigator.clipboard.writeText(component.name);
2217
- return { footprint: component.name };
2218
- }
2219
- },
2220
- {
2221
- loading: `Importing component: "${component.name}"`,
2222
- error: (error) => {
2223
- console.error("IMPORT ERROR", error);
2224
- return `Error importing component: "${component.name}": ${error.toString()}`;
2225
- },
2226
- success: (data) => {
2227
- if (data?.footprint) {
2228
- return `Copied "${data.footprint}" to clipboard`;
2229
- }
2230
- return data?.filePath ? `Imported to "${data.filePath}"` : "Import Successful";
2231
- }
2232
- }
2233
- );
2666
+ const [searchQuery, setSearchQuery] = React11.useState("");
2667
+ const [selectedSearchResult, setSelectedSearchResult] = React11.useState(null);
2668
+ const {
2669
+ results: tscircuitResults,
2670
+ isSearching: isTscircuitSearching,
2671
+ error: tscircuitError,
2672
+ hasSearched: hasTscircuitSearched,
2673
+ search: searchTscircuit,
2674
+ reset: resetTscircuitSearch
2675
+ } = useTscircuitPackageSearch();
2676
+ const {
2677
+ results: jlcpcbResults,
2678
+ isSearching: isJlcpcbSearching,
2679
+ error: jlcpcbError,
2680
+ hasSearched: hasJlcpcbSearched,
2681
+ search: searchJlcpcb,
2682
+ reset: resetJlcpcbSearch
2683
+ } = useJlcpcbComponentSearch();
2684
+ const {
2685
+ results: kicadResults,
2686
+ isSearching: isKicadSearching,
2687
+ error: kicadError,
2688
+ hasSearched: hasKicadSearched,
2689
+ search: searchKicad,
2690
+ reset: resetKicadSearch
2691
+ } = useKicadFootprintSearch();
2692
+ const {
2693
+ details: packageDetails,
2694
+ isLoading: isPackageDetailsLoading,
2695
+ fetchDetails: fetchPackageDetails,
2696
+ reset: resetPackageDetails
2697
+ } = useTscircuitPackageDetails();
2698
+ const [componentForDetails, setComponentForDetails] = React11.useState(null);
2699
+ const [isDetailsDialogOpen, setIsDetailsDialogOpen] = React11.useState(false);
2700
+ const [detailsPreviewTab, setDetailsPreviewTab] = React11.useState("pcb");
2701
+ const [importErrorMessage, setImportErrorMessage] = React11.useState(null);
2702
+ const [isSubmittingImport, setIsSubmittingImport] = React11.useState(false);
2703
+ React11.useEffect(() => {
2704
+ setImportErrorMessage(null);
2705
+ }, [selectedSearchResult]);
2706
+ const resetAllSearches = React11.useCallback(() => {
2707
+ resetTscircuitSearch();
2708
+ resetJlcpcbSearch();
2709
+ resetKicadSearch();
2710
+ setSelectedSearchResult(null);
2711
+ }, [resetJlcpcbSearch, resetKicadSearch, resetTscircuitSearch]);
2712
+ React11.useEffect(() => {
2713
+ if (!isOpen) {
2714
+ resetAllSearches();
2715
+ setSearchQuery("");
2716
+ setIsDetailsDialogOpen(false);
2717
+ setComponentForDetails(null);
2718
+ setImportErrorMessage(null);
2719
+ }
2720
+ }, [isOpen, resetAllSearches]);
2721
+ React11.useEffect(() => {
2722
+ setSearchQuery("");
2723
+ setSelectedSearchResult(null);
2724
+ if (activeSource === "tscircuit.com") {
2725
+ resetTscircuitSearch();
2726
+ } else if (activeSource === "jlcpcb") {
2727
+ resetJlcpcbSearch();
2728
+ } else if (activeSource === "kicad") {
2729
+ resetKicadSearch();
2730
+ }
2731
+ }, [activeSource, resetJlcpcbSearch, resetKicadSearch, resetTscircuitSearch]);
2732
+ const handleShowDetails = (component) => {
2733
+ setSelectedSearchResult(component);
2734
+ setComponentForDetails(component);
2735
+ setDetailsPreviewTab("pcb");
2736
+ setIsDetailsDialogOpen(true);
2737
+ resetPackageDetails();
2738
+ const owner = component.package.owner_github_username;
2739
+ const unscopedName = component.package.unscoped_name;
2740
+ if (owner && unscopedName) {
2741
+ const packageName = unscopedName.split("/").pop() ?? unscopedName;
2742
+ fetchPackageDetails(owner, packageName);
2743
+ }
2234
2744
  };
2235
- const fetchPackageDetails = async (owner, name) => {
2236
- setPackageDetailsLoading(true);
2237
- try {
2238
- const response = await fetch(
2239
- `https://registry-api.tscircuit.com/packages/get?name=${encodeURIComponent(`${owner}/${name}`)}`
2240
- );
2241
- if (response.ok) {
2242
- const data = await response.json();
2243
- setPackageDetails(data.package || null);
2244
- }
2245
- } catch (error) {
2246
- console.error("Error fetching package details:", error);
2247
- setPackageDetails(null);
2248
- } finally {
2249
- setPackageDetailsLoading(false);
2745
+ const performSearch = async () => {
2746
+ const trimmedQuery = searchQuery.trim();
2747
+ if (!trimmedQuery) return;
2748
+ setSelectedSearchResult(null);
2749
+ if (activeSource === "tscircuit.com") {
2750
+ await searchTscircuit(searchQuery);
2751
+ } else if (activeSource === "jlcpcb") {
2752
+ await searchJlcpcb(searchQuery);
2753
+ } else if (activeSource === "kicad") {
2754
+ await searchKicad(searchQuery);
2250
2755
  }
2251
2756
  };
2252
- const handleSearch = async () => {
2253
- if (!searchQuery.trim()) return;
2254
- setIsLoading(true);
2255
- const isJlcPartNumber = /^C\d+/.test(searchQuery);
2757
+ const performActionForComponent = async (result) => {
2256
2758
  try {
2257
- if (activeTab === "jlcpcb") {
2258
- const query = isJlcPartNumber ? searchQuery.substring(1) : searchQuery;
2259
- const jlcComponents = await searchJLCComponents(query, 10);
2260
- const mappedResults = jlcComponents.map(mapJLCComponentToSearchResult);
2261
- setSearchResults(mappedResults);
2262
- } else if (activeTab === "kicad") {
2263
- const kicadFootprints = await searchKicadFootprints(searchQuery, 20);
2264
- const mappedResults = kicadFootprints.map(
2265
- mapKicadFootprintToSearchResult
2266
- );
2267
- setSearchResults(mappedResults);
2268
- } else {
2269
- const tscircuitComponents = await searchTscircuitComponents(searchQuery);
2270
- const mappedResults = tscircuitComponents.map(
2271
- mapTscircuitSnippetToSearchResult
2272
- );
2273
- setSearchResults(mappedResults);
2759
+ setImportErrorMessage(null);
2760
+ setIsSubmittingImport(true);
2761
+ if (result.source === "kicad") {
2762
+ if (!onKicadStringSelected) {
2763
+ throw new Error("KiCad handler not provided");
2764
+ }
2765
+ await onKicadStringSelected({
2766
+ result,
2767
+ footprint: result.footprint.qualifiedName
2768
+ });
2769
+ } else if (result.source === "jlcpcb") {
2770
+ if (!onJlcpcbComponentTsxLoaded) {
2771
+ throw new Error("JLCPCB handler not provided");
2772
+ }
2773
+ const tsx = await loadJlcpcbComponentTsx(result.component.partNumber, {
2774
+ headers: jlcpcbProxyRequestHeaders
2775
+ });
2776
+ await onJlcpcbComponentTsxLoaded({ result, tsx });
2777
+ } else if (result.source === "tscircuit.com") {
2778
+ if (!onTscircuitPackageSelected) {
2779
+ throw new Error("tscircuit package handler not provided");
2780
+ }
2781
+ const owner = result.package.owner_github_username;
2782
+ const unscopedName = result.package.unscoped_name;
2783
+ if (!owner || !unscopedName) {
2784
+ throw new Error("Missing package metadata");
2785
+ }
2786
+ const packageName = unscopedName.split("/").pop() ?? unscopedName;
2787
+ const fullPackageName = `@tsci/${owner}.${packageName}`;
2788
+ await onTscircuitPackageSelected({
2789
+ result,
2790
+ fullPackageName
2791
+ });
2274
2792
  }
2793
+ return true;
2275
2794
  } catch (error) {
2276
- console.error("Error searching components:", error);
2277
- setSearchResults([]);
2795
+ console.error("Failed to import component", error);
2796
+ setImportErrorMessage(
2797
+ error instanceof Error ? error.message : "Failed to import component"
2798
+ );
2799
+ return false;
2278
2800
  } finally {
2279
- setIsLoading(false);
2280
- setHasSearched(true);
2801
+ setIsSubmittingImport(false);
2281
2802
  }
2282
2803
  };
2283
- const handleKeyDown = (e) => {
2284
- if (e.key === "Enter") {
2285
- handleSearch();
2804
+ let searchResults = [];
2805
+ let isSearching = false;
2806
+ let searchError = null;
2807
+ let hasExecutedSearch = false;
2808
+ if (activeSource === "tscircuit.com") {
2809
+ searchResults = tscircuitResults;
2810
+ isSearching = isTscircuitSearching;
2811
+ searchError = tscircuitError;
2812
+ hasExecutedSearch = hasTscircuitSearched;
2813
+ } else if (activeSource === "jlcpcb") {
2814
+ searchResults = jlcpcbResults;
2815
+ isSearching = isJlcpcbSearching;
2816
+ searchError = jlcpcbError;
2817
+ hasExecutedSearch = hasJlcpcbSearched;
2818
+ } else if (activeSource === "kicad") {
2819
+ searchResults = kicadResults;
2820
+ isSearching = isKicadSearching;
2821
+ searchError = kicadError;
2822
+ hasExecutedSearch = hasKicadSearched;
2823
+ }
2824
+ const handleConfirm = async () => {
2825
+ if (!selectedSearchResult) return;
2826
+ const succeeded = await performActionForComponent(selectedSearchResult);
2827
+ if (succeeded) {
2828
+ onClose();
2829
+ resetAllSearches();
2830
+ setSearchQuery("");
2831
+ }
2832
+ };
2833
+ const handleDialogClose = (open) => {
2834
+ if (!open) {
2835
+ onClose();
2286
2836
  }
2287
2837
  };
2288
- useEffect7(() => {
2289
- setSearchResults([]);
2290
- setSelectedComponent(null);
2291
- }, [activeTab]);
2292
- const showDetails = (component) => {
2293
- setDetailsComponent(component);
2294
- setDetailsOpen(true);
2295
- setPackageDetails(null);
2296
- setPreviewActiveTab("pcb");
2297
- if (component.source === "tscircuit.com" && component.owner) {
2298
- const packageName = component.name.split("/").pop() || component.name;
2299
- fetchPackageDetails(component.owner, packageName);
2838
+ const handleDetailsClose = (open) => {
2839
+ setIsDetailsDialogOpen(open);
2840
+ if (!open) {
2841
+ setComponentForDetails(null);
2300
2842
  }
2301
2843
  };
2302
- return /* @__PURE__ */ jsxs15(Dialog, { open: isOpen, onOpenChange: () => onClose(), children: [
2303
- /* @__PURE__ */ jsxs15(
2844
+ return /* @__PURE__ */ jsxs18(Dialog, { open: isOpen, onOpenChange: handleDialogClose, children: [
2845
+ /* @__PURE__ */ jsxs18(
2304
2846
  DialogContent,
2305
2847
  {
2306
- style: {
2307
- width: "calc(100vw - 2rem)"
2308
- },
2848
+ style: { width: "calc(100vw - 2rem)" },
2309
2849
  className: "rf-rounded-sm rf-max-h-[90vh] rf-overflow-y-auto rf-flex rf-flex-col",
2310
2850
  children: [
2311
- /* @__PURE__ */ jsxs15(DialogHeader, { children: [
2312
- /* @__PURE__ */ jsx21(DialogTitle, { className: "rf-text-lg sm:rf-text-xl", children: "Import Component" }),
2313
- /* @__PURE__ */ jsx21(DialogDescription, { className: "rf-text-sm", children: "Search for components from tscircuit.com or JLCPCB parts library." })
2851
+ /* @__PURE__ */ jsxs18(DialogHeader, { children: [
2852
+ /* @__PURE__ */ jsx24(DialogTitle, { className: "rf-text-lg sm:rf-text-xl", children: "Import Component" }),
2853
+ /* @__PURE__ */ jsx24(DialogDescription, { className: "rf-text-sm", children: hasSources ? "Search for components from available sources." : "Import options are disabled because no handlers were provided." })
2314
2854
  ] }),
2315
- /* @__PURE__ */ jsxs15(
2855
+ hasSources ? /* @__PURE__ */ jsxs18(
2316
2856
  Tabs,
2317
2857
  {
2318
- value: activeTab,
2319
- onValueChange: (value) => setActiveTab(value),
2858
+ value: activeSource,
2859
+ onValueChange: (value) => setActiveSource(value),
2320
2860
  children: [
2321
- /* @__PURE__ */ jsxs15(TabsList, { className: "rf-grid rf-w-full rf-grid-cols-1 sm:rf-grid-cols-3 rf-h-auto", children: [
2322
- /* @__PURE__ */ jsx21(
2323
- TabsTrigger,
2324
- {
2325
- value: "tscircuit.com",
2326
- className: "rf-text-xs sm:rf-text-sm",
2327
- children: "tscircuit.com"
2328
- }
2329
- ),
2330
- /* @__PURE__ */ jsx21(TabsTrigger, { value: "jlcpcb", className: "rf-text-xs sm:rf-text-sm", children: "JLCPCB Parts" }),
2331
- /* @__PURE__ */ jsx21(TabsTrigger, { value: "kicad", className: "rf-text-xs sm:rf-text-sm", children: "KiCad" })
2332
- ] }),
2333
- /* @__PURE__ */ jsxs15("div", { className: "rf-flex rf-items-center rf-gap-2 rf-mt-4", children: [
2334
- /* @__PURE__ */ jsxs15("div", { className: "rf-relative rf-flex-grow", children: [
2335
- /* @__PURE__ */ jsx21(Search, { className: "rf-absolute rf-left-2 rf-top-2.5 rf-h-4 rf-w-4 rf-text-muted-foreground" }),
2336
- /* @__PURE__ */ jsx21(
2337
- Input,
2338
- {
2339
- placeholder: activeTab === "tscircuit.com" ? "Search components..." : activeTab === "kicad" ? "Search KiCad footprints..." : "Search JLCPCB parts (e.g. C14663)...",
2340
- className: "rf-pl-8",
2341
- spellCheck: false,
2342
- autoComplete: "off",
2343
- value: searchQuery,
2344
- onChange: (e) => setSearchQuery(e.target.value),
2345
- onKeyDown: handleKeyDown
2346
- }
2347
- )
2348
- ] }),
2349
- /* @__PURE__ */ jsx21(
2350
- Button,
2351
- {
2352
- onClick: handleSearch,
2353
- disabled: isLoading || searchQuery.trim().length < 1,
2354
- className: "sm:rf-px-4 rf-px-3",
2355
- children: isLoading ? /* @__PURE__ */ jsx21(Loader2, { className: "rf-h-4 rf-w-4 rf-animate-spin" }) : /* @__PURE__ */ jsxs15(Fragment3, { children: [
2356
- /* @__PURE__ */ jsx21(Search, { className: "rf-h-4 rf-w-4 sm:rf-hidden" }),
2357
- /* @__PURE__ */ jsx21("span", { className: "rf-hidden sm:rf-inline", children: "Search" })
2358
- ] })
2359
- }
2360
- )
2361
- ] }),
2362
- /* @__PURE__ */ jsx21("div", { className: "rf-mt-4 rf-flex-1 rf-min-h-[200px] !rf-max-h-[40vh] !rf-overflow-y-auto rf-border rf-rounded-md", children: searchResults.length > 0 ? /* @__PURE__ */ jsx21("div", { className: "rf-divide-y", children: searchResults.map((result) => /* @__PURE__ */ jsxs15(
2363
- "div",
2861
+ /* @__PURE__ */ jsx24(TabsList, { className: "rf-flex rf-w-full rf-gap-2", children: availableSources.map((source) => /* @__PURE__ */ jsx24(
2862
+ TabsTrigger,
2364
2863
  {
2365
- className: `rf-p-3 rf-flex rf-flex-col sm:rf-grid sm:rf-grid-cols-[1fr_auto] rf-items-start sm:rf-items-center rf-cursor-pointer hover:rf-bg-zinc-100 rf-gap-2 ${selectedComponent?.id === result.id ? "rf-bg-zinc-100" : ""}`,
2366
- onClick: () => setSelectedComponent(result),
2367
- children: [
2368
- /* @__PURE__ */ jsxs15("div", { className: "rf-min-w-0 rf-overflow-hidden", children: [
2369
- /* @__PURE__ */ jsx21("div", { className: "rf-font-medium rf-text-sm rf-truncate", children: result.name }),
2370
- /* @__PURE__ */ jsxs15("div", { className: "rf-text-xs rf-text-zinc-500 rf-truncate", children: [
2371
- result.partNumber && /* @__PURE__ */ jsx21("span", { className: "rf-mr-2", children: result.partNumber }),
2372
- result.description
2373
- ] })
2374
- ] }),
2375
- /* @__PURE__ */ jsx21("div", { className: "rf-flex rf-gap-2 rf-flex-shrink-0 rf-w-full sm:rf-w-auto", children: result.source === "tscircuit.com" && /* @__PURE__ */ jsx21(
2376
- Button,
2377
- {
2378
- variant: "outline",
2379
- size: "sm",
2380
- className: "rf-text-xs rf-w-full sm:rf-w-auto",
2381
- onClick: (e) => {
2382
- e.stopPropagation();
2383
- showDetails(result);
2384
- },
2385
- children: "See Details"
2386
- }
2387
- ) })
2388
- ]
2864
+ value: source,
2865
+ className: "rf-flex-1 rf-text-xs sm:rf-text-sm",
2866
+ children: SOURCE_CONFIG[source].label
2389
2867
  },
2390
- result.id
2391
- )) }) : isLoading ? /* @__PURE__ */ jsxs15("div", { className: "rf-p-8 rf-text-center rf-text-zinc-500", children: [
2392
- /* @__PURE__ */ jsx21(Loader2, { className: "rf-h-8 rf-w-8 rf-animate-spin rf-mx-auto rf-mb-2" }),
2393
- /* @__PURE__ */ jsx21("p", { children: "Searching..." })
2394
- ] }) : /* @__PURE__ */ jsx21("div", { className: "rf-p-8 rf-text-center rf-text-zinc-500", children: hasSearched ? "No results found" : "Enter a search term to find components" }) })
2868
+ source
2869
+ )) }),
2870
+ /* @__PURE__ */ jsx24(
2871
+ SearchBar,
2872
+ {
2873
+ query: searchQuery,
2874
+ placeholder: SOURCE_CONFIG[activeSource].placeholder,
2875
+ isSearching,
2876
+ onQueryChange: setSearchQuery,
2877
+ onSubmit: performSearch
2878
+ }
2879
+ ),
2880
+ /* @__PURE__ */ jsx24("div", { className: "rf-mt-4 rf-flex-1 rf-min-h-[200px] !rf-max-h-[40vh] !rf-overflow-y-auto rf-border rf-rounded-md", children: isSearching ? /* @__PURE__ */ jsxs18("div", { className: "rf-p-8 rf-text-center rf-text-zinc-500", children: [
2881
+ /* @__PURE__ */ jsx24(Loader23, { className: "rf-h-8 rf-w-8 rf-animate-spin rf-mx-auto rf-mb-2" }),
2882
+ /* @__PURE__ */ jsx24("p", { children: "Searching..." })
2883
+ ] }) : searchResults.length > 0 ? /* @__PURE__ */ jsx24(
2884
+ SearchResultsList,
2885
+ {
2886
+ results: searchResults,
2887
+ selected: selectedSearchResult,
2888
+ onSelect: setSelectedSearchResult,
2889
+ onShowDetails: activeSource === "tscircuit.com" ? handleShowDetails : void 0
2890
+ }
2891
+ ) : /* @__PURE__ */ jsx24("div", { className: "rf-p-8 rf-text-center rf-text-zinc-500", children: searchError ? `Error: ${searchError}` : hasExecutedSearch ? SOURCE_CONFIG[activeSource].emptyMessage : "Enter a search term to find components" }) })
2395
2892
  ]
2396
2893
  }
2397
- ),
2398
- /* @__PURE__ */ jsxs15(DialogFooter, { className: "rf-flex rf-flex-col sm:rf-flex-row rf-gap-2", children: [
2399
- /* @__PURE__ */ jsx21(
2894
+ ) : null,
2895
+ importErrorMessage ? /* @__PURE__ */ jsx24("div", { className: "rf-text-sm rf-text-red-600 rf-mt-2", children: importErrorMessage }) : null,
2896
+ /* @__PURE__ */ jsxs18(DialogFooter, { className: "rf-flex rf-flex-col sm:rf-flex-row rf-gap-2", children: [
2897
+ /* @__PURE__ */ jsx24(
2400
2898
  Button,
2401
2899
  {
2402
2900
  variant: "outline",
@@ -2405,202 +2903,116 @@ var ImportComponentDialog = ({
2405
2903
  children: "Cancel"
2406
2904
  }
2407
2905
  ),
2408
- /* @__PURE__ */ jsx21(
2906
+ /* @__PURE__ */ jsx24(
2409
2907
  Button,
2410
2908
  {
2411
- onClick: () => {
2412
- if (selectedComponent) {
2413
- handleImport(selectedComponent);
2414
- onClose();
2415
- }
2416
- },
2417
- disabled: !selectedComponent,
2418
- children: selectedComponent?.source === "kicad" ? "Copy Footprint" : "Import Component"
2909
+ onClick: handleConfirm,
2910
+ disabled: !selectedSearchResult || isSubmittingImport,
2911
+ className: "rf-order-1 sm:rf-order-2",
2912
+ children: isSubmittingImport ? /* @__PURE__ */ jsx24(Loader23, { className: "rf-h-4 rf-w-4 rf-animate-spin" }) : "Import"
2419
2913
  }
2420
2914
  )
2421
2915
  ] })
2422
2916
  ]
2423
2917
  }
2424
2918
  ),
2425
- /* @__PURE__ */ jsx21(Dialog, { open: detailsOpen, onOpenChange: setDetailsOpen, children: /* @__PURE__ */ jsxs15(
2426
- DialogContent,
2919
+ /* @__PURE__ */ jsx24(
2920
+ TscircuitPackageDetailsDialog,
2427
2921
  {
2428
- showOverlay: false,
2429
- style: {
2430
- width: "calc(100vw - 2rem)"
2431
- },
2432
- className: "rf-max-w-5xl !rf-overflow-y-auto rf-max-h-[90vh] rf-overflow-hidden rf-flex rf-flex-col rf-rounded-sm",
2433
- children: [
2434
- /* @__PURE__ */ jsx21(DialogHeader, { className: "rf-pb-4 rf-border-b", children: /* @__PURE__ */ jsx21("div", { className: "rf-flex rf-items-start rf-justify-between rf-gap-4", children: /* @__PURE__ */ jsx21("div", { className: "rf-flex-1 rf-min-w-0", children: /* @__PURE__ */ jsx21(DialogTitle, { className: "rf-text-xl rf-font-semibold rf-truncate", children: detailsComponent?.source === "kicad" ? detailsComponent?.name : /* @__PURE__ */ jsx21(
2435
- "a",
2436
- {
2437
- href: `https://tscircuit.com/${detailsComponent?.owner}/${detailsComponent?.name}`,
2438
- target: "_blank",
2439
- rel: "noopener noreferrer",
2440
- className: "rf-text-black hover:rf-underline",
2441
- children: detailsComponent?.name?.split("/").pop() || detailsComponent?.name
2922
+ packageResult: componentForDetails,
2923
+ isOpen: isDetailsDialogOpen,
2924
+ onOpenChange: handleDetailsClose,
2925
+ isLoading: isPackageDetailsLoading,
2926
+ details: packageDetails,
2927
+ previewTab: detailsPreviewTab,
2928
+ onPreviewTabChange: (value) => setDetailsPreviewTab(value),
2929
+ isSubmitting: isSubmittingImport,
2930
+ onImport: () => {
2931
+ if (!componentForDetails) return;
2932
+ performActionForComponent(componentForDetails).then((succeeded) => {
2933
+ if (succeeded) {
2934
+ setIsDetailsDialogOpen(false);
2935
+ onClose();
2936
+ resetAllSearches();
2937
+ setSearchQuery("");
2442
2938
  }
2443
- ) }) }) }) }),
2444
- /* @__PURE__ */ jsx21("div", { className: "rf-flex-1 rf-overflow-y-auto rf-py-4 rf-space-y-6", children: detailsComponent?.source === "tscircuit.com" ? /* @__PURE__ */ jsxs15(Fragment3, { children: [
2445
- /* @__PURE__ */ jsx21("div", { children: /* @__PURE__ */ jsx21("div", { className: "rf-space-y-3", children: detailsComponent?.owner && /* @__PURE__ */ jsxs15("div", { children: [
2446
- /* @__PURE__ */ jsx21("label", { className: "rf-text-xs rf-font-medium rf-text-gray-500 rf-uppercase rf-tracking-wide", children: "Created by" }),
2447
- /* @__PURE__ */ jsx21("div", { className: "rf-mt-1 rf-text-sm rf-font-medium", children: /* @__PURE__ */ jsx21(
2448
- "a",
2449
- {
2450
- href: `https://tscircuit.com/${detailsComponent?.owner}`,
2451
- target: "_blank",
2452
- rel: "noopener noreferrer",
2453
- className: "rf-text-black hover:rf-underline",
2454
- children: detailsComponent?.owner
2455
- }
2456
- ) })
2457
- ] }) }) }),
2458
- /* @__PURE__ */ jsxs15("div", { children: [
2459
- /* @__PURE__ */ jsx21("h3", { className: "rf-text-lg rf-font-semibold rf-mb-4", children: "Preview" }),
2460
- /* @__PURE__ */ jsxs15(
2461
- Tabs,
2462
- {
2463
- value: previewActiveTab,
2464
- onValueChange: (value) => setPreviewActiveTab(value),
2465
- children: [
2466
- /* @__PURE__ */ jsxs15(TabsList, { className: "rf-inline-flex rf-h-9 rf-items-center rf-justify-center rf-rounded-lg rf-bg-zinc-100 rf-p-1 rf-text-zinc-500 dark:rf-bg-zinc-800 dark:rf-text-zinc-400", children: [
2467
- /* @__PURE__ */ jsx21(
2468
- TabsTrigger,
2469
- {
2470
- value: "pcb",
2471
- className: "rf-inline-flex rf-items-center rf-justify-center rf-whitespace-nowrap rf-rounded-md rf-px-3 rf-py-1 rf-text-sm rf-font-medium rf-ring-offset-white rf-transition-all focus-visible:rf-outline-none focus-visible:rf-ring-2 focus-visible:rf-ring-zinc-950 focus-visible:rf-ring-offset-2 disabled:rf-pointer-events-none disabled:rf-opacity-50 data-[state=active]:rf-bg-white data-[state=active]:rf-text-zinc-950 data-[state=active]:rf-shadow dark:rf-ring-offset-zinc-950 dark:focus-visible:rf-ring-zinc-300 dark:data-[state=active]:rf-bg-zinc-950 dark:data-[state=active]:rf-text-zinc-50",
2472
- children: "PCB"
2473
- }
2474
- ),
2475
- /* @__PURE__ */ jsx21(
2476
- TabsTrigger,
2477
- {
2478
- value: "schematic",
2479
- className: "rf-inline-flex rf-items-center rf-justify-center rf-whitespace-nowrap rf-rounded-md rf-px-3 rf-py-1 rf-text-sm rf-font-medium rf-ring-offset-white rf-transition-all focus-visible:rf-outline-none focus-visible:rf-ring-2 focus-visible:rf-ring-zinc-950 focus-visible:rf-ring-offset-2 disabled:rf-pointer-events-none disabled:rf-opacity-50 data-[state=active]:rf-bg-white data-[state=active]:rf-text-zinc-950 data-[state=active]:rf-shadow dark:rf-ring-offset-zinc-950 dark:focus-visible:rf-ring-zinc-300 dark:data-[state=active]:rf-bg-zinc-950 dark:data-[state=active]:rf-text-zinc-50",
2480
- children: "Schematic"
2481
- }
2482
- )
2483
- ] }),
2484
- /* @__PURE__ */ jsxs15("div", { className: "rf-mt-4", children: [
2485
- /* @__PURE__ */ jsx21(
2486
- TabsContent,
2487
- {
2488
- value: "pcb",
2489
- className: "rf-border rf-rounded-lg rf-overflow-hidden rf-bg-gray-50",
2490
- children: detailsComponent?.owner && detailsComponent?.name ? /* @__PURE__ */ jsx21("div", { className: "rf-w-full rf-h-fit rf-min-h-[300px] rf-bg-white rf-flex rf-items-center rf-justify-center rf-p-4", children: /* @__PURE__ */ jsx21(
2491
- "img",
2492
- {
2493
- src: `https://registry-api.tscircuit.com/packages/images/${detailsComponent.owner}/${detailsComponent.name}/pcb.png`,
2494
- alt: `${detailsComponent.name} PCB preview`,
2495
- className: "rf-max-w-full rf-max-h-full rf-object-contain rf-rounded",
2496
- onError: (e) => {
2497
- const target = e.target;
2498
- target.style.display = "none";
2499
- const parent = target.parentElement;
2500
- if (parent) {
2501
- parent.innerHTML = '<div class="rf-text-center rf-text-gray-500"><div class="rf-text-sm rf-font-medium">PCB preview not available</div><div class="rf-text-xs rf-mt-1">Preview cannot be generated</div></div>';
2502
- }
2503
- }
2504
- }
2505
- ) }) : /* @__PURE__ */ jsx21("div", { className: "rf-h-[400px] rf-flex rf-items-center rf-justify-center rf-text-gray-500", children: /* @__PURE__ */ jsxs15("div", { className: "rf-text-center", children: [
2506
- /* @__PURE__ */ jsx21("div", { className: "rf-text-sm rf-font-medium", children: "No PCB preview available" }),
2507
- /* @__PURE__ */ jsx21("div", { className: "rf-text-xs rf-mt-1", children: "Preview cannot be generated" })
2508
- ] }) })
2509
- }
2510
- ),
2511
- /* @__PURE__ */ jsx21(
2512
- TabsContent,
2513
- {
2514
- value: "schematic",
2515
- className: "rf-border rf-rounded-lg rf-overflow-hidden rf-bg-gray-50",
2516
- children: detailsComponent?.owner && detailsComponent?.name ? /* @__PURE__ */ jsx21("div", { className: "rf-w-full rf-h-fit rf-min-h-[300px] rf-bg-white rf-flex rf-items-center rf-justify-center rf-p-4", children: /* @__PURE__ */ jsx21(
2517
- "img",
2518
- {
2519
- src: `https://registry-api.tscircuit.com/packages/images/${detailsComponent.owner}/${detailsComponent.name}/schematic.png`,
2520
- alt: `${detailsComponent.name} schematic preview`,
2521
- className: "rf-max-w-full rf-max-h-full rf-object-contain rf-rounded",
2522
- onError: (e) => {
2523
- const target = e.target;
2524
- target.style.display = "none";
2525
- const parent = target.parentElement;
2526
- if (parent) {
2527
- parent.innerHTML = '<div class="rf-text-center rf-text-gray-500"><div class="rf-text-sm rf-font-medium">Schematic preview not available</div><div class="rf-text-xs rf-mt-1">Preview cannot be generated</div></div>';
2528
- }
2529
- }
2530
- }
2531
- ) }) : /* @__PURE__ */ jsx21("div", { className: "rf-h-[400px] rf-flex rf-items-center rf-justify-center rf-text-gray-500", children: /* @__PURE__ */ jsxs15("div", { className: "rf-text-center", children: [
2532
- /* @__PURE__ */ jsx21("div", { className: "rf-text-sm rf-font-medium", children: "No schematic preview available" }),
2533
- /* @__PURE__ */ jsx21("div", { className: "rf-text-xs rf-mt-1", children: "Preview cannot be generated" })
2534
- ] }) })
2535
- }
2536
- )
2537
- ] })
2538
- ]
2539
- }
2540
- )
2541
- ] }),
2542
- packageDetails?.ai_description && /* @__PURE__ */ jsxs15("div", { children: [
2543
- /* @__PURE__ */ jsx21("h3", { className: "rf-text-lg rf-font-semibold rf-mb-3", children: "AI Description" }),
2544
- /* @__PURE__ */ jsx21("div", { className: "rf-bg-gray-50 rf-border rf-border-gray-200 rf-rounded-lg rf-p-4", children: /* @__PURE__ */ jsx21("p", { className: "rf-text-sm rf-text-gray-700 rf-leading-relaxed", children: packageDetails.ai_description }) })
2545
- ] }),
2546
- packageDetails?.ai_usage_instructions && /* @__PURE__ */ jsxs15("div", { children: [
2547
- /* @__PURE__ */ jsx21("h3", { className: "rf-text-lg rf-font-semibold rf-mb-3", children: "Usage Instructions" }),
2548
- /* @__PURE__ */ jsx21("div", { className: "rf-bg-gray-50 rf-border rf-border-gray-200 rf-rounded-lg rf-p-4", children: /* @__PURE__ */ jsx21("p", { className: "rf-text-sm rf-text-gray-700 rf-leading-relaxed rf-whitespace-pre-wrap", children: packageDetails.ai_usage_instructions }) })
2549
- ] }),
2550
- packageDetailsLoading && /* @__PURE__ */ jsxs15("div", { className: "rf-flex rf-justify-center rf-text-center rf-items-center rf-gap-2 rf-text-gray-500", children: [
2551
- /* @__PURE__ */ jsx21(Loader2, { className: "rf-h-4 rf-w-4 rf-animate-spin" }),
2552
- /* @__PURE__ */ jsx21("span", { className: "rf-text-sm", children: "Loading package details..." })
2553
- ] })
2554
- ] }) : null }),
2555
- /* @__PURE__ */ jsxs15(DialogFooter, { className: "rf-pt-4 rf-border-t rf-flex rf-flex-col sm:rf-flex-row rf-justify-between rf-items-stretch sm:rf-items-center rf-gap-2", children: [
2556
- /* @__PURE__ */ jsx21("div", { className: "rf-flex-1 rf-order-3 sm:rf-order-1", children: detailsComponent?.source === "tscircuit.com" && /* @__PURE__ */ jsxs15(
2557
- Button,
2558
- {
2559
- variant: "outline",
2560
- size: "sm",
2561
- className: "rf-gap-2 rf-w-full sm:rf-w-auto",
2562
- onClick: () => {
2563
- const url = `https://tscircuit.com/${detailsComponent?.owner}/${detailsComponent?.name.split("/").pop()}`;
2564
- window.open(url, "_blank");
2565
- },
2566
- children: [
2567
- /* @__PURE__ */ jsx21(ExternalLink, { className: "rf-h-4 rf-w-4" }),
2568
- "View on tscircuit.com"
2569
- ]
2570
- }
2571
- ) }),
2572
- /* @__PURE__ */ jsxs15("div", { className: "rf-flex rf-flex-col sm:rf-flex-row rf-gap-2 sm:rf-gap-3 rf-order-1 sm:rf-order-2", children: [
2573
- /* @__PURE__ */ jsx21(
2574
- Button,
2575
- {
2576
- variant: "outline",
2577
- onClick: () => setDetailsOpen(false),
2578
- className: "rf-order-2 sm:rf-order-1",
2579
- children: "Close"
2580
- }
2581
- ),
2582
- /* @__PURE__ */ jsx21(
2583
- Button,
2584
- {
2585
- onClick: () => {
2586
- setDetailsOpen(false);
2587
- if (detailsComponent) {
2588
- handleImport(detailsComponent);
2589
- onClose();
2590
- }
2591
- },
2592
- className: "rf-bg-blue-600 hover:rf-bg-blue-700 rf-order-1 sm:rf-order-2",
2593
- children: detailsComponent?.source === "kicad" ? "Copy Footprint" : "Import Component"
2594
- }
2595
- )
2596
- ] })
2597
- ] })
2598
- ]
2939
+ });
2940
+ }
2599
2941
  }
2600
- ) })
2942
+ )
2601
2943
  ] });
2602
2944
  };
2603
2945
 
2946
+ // lib/components/ImportComponentDialog2/ImportComponentDialogForCli.tsx
2947
+ import "react";
2948
+
2949
+ // lib/utils/toast.ts
2950
+ import { toast } from "react-hot-toast";
2951
+
2952
+ // lib/components/ImportComponentDialog2/ImportComponentDialogForCli.tsx
2953
+ import { jsx as jsx25 } from "react/jsx-runtime";
2954
+ var extractComponentName = (tsx) => {
2955
+ const match = tsx.match(/export const (\w+) =/);
2956
+ if (!match) {
2957
+ throw new Error("Could not determine component name from TSX contents");
2958
+ }
2959
+ return match[1];
2960
+ };
2961
+ var ImportComponentDialogForCli = (props) => {
2962
+ const pushEvent = useRunFrameStore((state) => state.pushEvent);
2963
+ const upsertFile = useRunFrameStore((state) => state.upsertFile);
2964
+ const handleTscircuitPackageSelected = async ({
2965
+ result,
2966
+ fullPackageName
2967
+ }) => {
2968
+ const packageName = result.package.unscoped_name;
2969
+ const displayName = packageName ?? result.package.name;
2970
+ await toast.promise(
2971
+ pushEvent({
2972
+ event_type: "INSTALL_PACKAGE",
2973
+ full_package_name: fullPackageName
2974
+ }),
2975
+ {
2976
+ loading: `Requesting install for "${displayName}"`,
2977
+ success: `Install requested for "${displayName}"`,
2978
+ error: (error) => `Failed to request install: ${error instanceof Error ? error.message : String(error)}`
2979
+ }
2980
+ );
2981
+ throw new Error("Not implemented");
2982
+ };
2983
+ const handleKicadStringSelected = async ({
2984
+ footprint
2985
+ }) => {
2986
+ await toast.promise(navigator.clipboard.writeText(footprint), {
2987
+ loading: `Copying "${footprint}"`,
2988
+ success: `Copied "${footprint}" to clipboard`,
2989
+ error: (error) => `Failed to copy footprint: ${error instanceof Error ? error.message : String(error)}`
2990
+ });
2991
+ };
2992
+ const handleJlcpcbComponentTsxLoaded = async ({
2993
+ result,
2994
+ tsx
2995
+ }) => {
2996
+ const componentName = extractComponentName(tsx);
2997
+ const filePath = `imports/${componentName}.tsx`;
2998
+ await toast.promise(upsertFile(filePath, tsx), {
2999
+ loading: `Importing ${result.component.partNumber}`,
3000
+ success: `Imported to "${filePath}"`,
3001
+ error: (error) => `Failed to import component: ${error instanceof Error ? error.message : String(error)}`
3002
+ });
3003
+ };
3004
+ return /* @__PURE__ */ jsx25(
3005
+ ImportComponentDialog2,
3006
+ {
3007
+ ...props,
3008
+ onTscircuitPackageSelected: handleTscircuitPackageSelected,
3009
+ onKicadStringSelected: handleKicadStringSelected,
3010
+ onJlcpcbComponentTsxLoaded: handleJlcpcbComponentTsxLoaded
3011
+ }
3012
+ );
3013
+ };
3014
+ ImportComponentDialogForCli.displayName = "ImportComponentDialogForCli";
3015
+
2604
3016
  // lib/optional-features/exporting/formats/export-fabrication-files.ts
2605
3017
  import JSZip from "jszip";
2606
3018
  import {
@@ -2727,20 +3139,20 @@ var exportAndDownload = async ({
2727
3139
  };
2728
3140
 
2729
3141
  // lib/components/AiReviewDialog/AiReviewDialog.tsx
2730
- import { useState as useState11 } from "react";
3142
+ import { useState as useState15 } from "react";
2731
3143
 
2732
3144
  // lib/components/AiReviewDialog/ListAiReviewsView.tsx
2733
- import { useEffect as useEffect8, useState as useState9 } from "react";
3145
+ import { useEffect as useEffect8, useState as useState13 } from "react";
2734
3146
 
2735
3147
  // lib/utils/get-registry-ky.ts
2736
- import ky2 from "ky";
3148
+ import ky from "ky";
2737
3149
  function getWindowVar(name) {
2738
3150
  return typeof window !== "undefined" ? window[name] : null;
2739
3151
  }
2740
3152
  function getRegistryKy() {
2741
3153
  const registryApiBaseUrl = getWindowVar("TSCIRCUIT_REGISTRY_API_BASE_URL") || import.meta.env.VITE_TSCIRCUIT_REGISTRY_API_BASE_URL || "https://registry-api.tscircuit.com";
2742
3154
  const registryToken = getWindowVar("TSCIRCUIT_REGISTRY_TOKEN");
2743
- return ky2.create({
3155
+ return ky.create({
2744
3156
  prefixUrl: registryApiBaseUrl,
2745
3157
  headers: {
2746
3158
  Authorization: `Bearer ${registryToken}`
@@ -2760,16 +3172,16 @@ var registryKy = {
2760
3172
  };
2761
3173
 
2762
3174
  // lib/components/AiReviewDialog/ListAiReviewsView.tsx
2763
- import { Fragment as Fragment4, jsx as jsx22, jsxs as jsxs16 } from "react/jsx-runtime";
3175
+ import { Fragment as Fragment4, jsx as jsx26, jsxs as jsxs19 } from "react/jsx-runtime";
2764
3176
  var AiReviewListView = ({
2765
3177
  packageName,
2766
3178
  onSelectReview
2767
3179
  }) => {
2768
3180
  const fsMap = useRunFrameStore((s) => s.fsMap);
2769
3181
  const circuitJson = useRunFrameStore((s) => s.circuitJson);
2770
- const [reviews, setReviews] = useState9([]);
2771
- const [loading, setLoading] = useState9(false);
2772
- const [creating, setCreating] = useState9(false);
3182
+ const [reviews, setReviews] = useState13([]);
3183
+ const [loading, setLoading] = useState13(false);
3184
+ const [creating, setCreating] = useState13(false);
2773
3185
  useEffect8(() => {
2774
3186
  if (!packageName || !hasRegistryToken()) return;
2775
3187
  setLoading(true);
@@ -2806,12 +3218,12 @@ var AiReviewListView = ({
2806
3218
  setCreating(false);
2807
3219
  }
2808
3220
  };
2809
- return /* @__PURE__ */ jsxs16(Fragment4, { children: [
2810
- /* @__PURE__ */ jsxs16(DialogHeader, { children: [
2811
- /* @__PURE__ */ jsx22(DialogTitle, { children: "AI Review" }),
2812
- /* @__PURE__ */ jsx22(DialogDescription, { children: "Select an AI review or request a new one." })
3221
+ return /* @__PURE__ */ jsxs19(Fragment4, { children: [
3222
+ /* @__PURE__ */ jsxs19(DialogHeader, { children: [
3223
+ /* @__PURE__ */ jsx26(DialogTitle, { children: "AI Review" }),
3224
+ /* @__PURE__ */ jsx26(DialogDescription, { children: "Select an AI review or request a new one." })
2813
3225
  ] }),
2814
- /* @__PURE__ */ jsx22("div", { className: "rf-flex rf-gap-4 rf-mt-4", children: /* @__PURE__ */ jsx22("div", { className: "rf-w-48 rf-h-64 rf-overflow-y-auto rf-border rf-rounded rf-p-2 rf-flex-shrink-0", children: loading ? /* @__PURE__ */ jsx22("div", { className: "rf-text-sm", children: "Loading..." }) : reviews.length > 0 ? reviews.map((review) => /* @__PURE__ */ jsx22(
3226
+ /* @__PURE__ */ jsx26("div", { className: "rf-flex rf-gap-4 rf-mt-4", children: /* @__PURE__ */ jsx26("div", { className: "rf-w-48 rf-h-64 rf-overflow-y-auto rf-border rf-rounded rf-p-2 rf-flex-shrink-0", children: loading ? /* @__PURE__ */ jsx26("div", { className: "rf-text-sm", children: "Loading..." }) : reviews.length > 0 ? reviews.map((review) => /* @__PURE__ */ jsx26(
2815
3227
  "div",
2816
3228
  {
2817
3229
  className: "rf-text-sm rf-p-2 rf-cursor-pointer rf-rounded hover:rf-bg-zinc-100",
@@ -2819,20 +3231,20 @@ var AiReviewListView = ({
2819
3231
  children: new Date(review.created_at || "").toLocaleString()
2820
3232
  },
2821
3233
  review.ai_review_id
2822
- )) : /* @__PURE__ */ jsx22("div", { className: "rf-text-sm rf-text-muted-foreground", children: "No AI reviews found." }) }) }),
2823
- /* @__PURE__ */ jsx22(DialogFooter, { className: "rf-mt-4", children: /* @__PURE__ */ jsx22(Button, { onClick: requestReview, disabled: creating, children: creating ? "Requesting..." : "Review my Board" }) })
3234
+ )) : /* @__PURE__ */ jsx26("div", { className: "rf-text-sm rf-text-muted-foreground", children: "No AI reviews found." }) }) }),
3235
+ /* @__PURE__ */ jsx26(DialogFooter, { className: "rf-mt-4", children: /* @__PURE__ */ jsx26(Button, { onClick: requestReview, disabled: creating, children: creating ? "Requesting..." : "Review my Board" }) })
2824
3236
  ] });
2825
3237
  };
2826
3238
 
2827
3239
  // lib/components/AiReviewDialog/ViewAiReviewView.tsx
2828
- import { useEffect as useEffect9, useMemo as useMemo3, useState as useState10 } from "react";
3240
+ import { useEffect as useEffect9, useMemo as useMemo4, useState as useState14 } from "react";
2829
3241
  import { marked } from "marked";
2830
- import { Fragment as Fragment5, jsx as jsx23, jsxs as jsxs17 } from "react/jsx-runtime";
3242
+ import { Fragment as Fragment5, jsx as jsx27, jsxs as jsxs20 } from "react/jsx-runtime";
2831
3243
  var AiReviewViewView = ({
2832
3244
  review,
2833
3245
  onBack
2834
3246
  }) => {
2835
- const [aiReviewText, setAiReviewText] = useState10(
3247
+ const [aiReviewText, setAiReviewText] = useState14(
2836
3248
  review.ai_review_text ?? null
2837
3249
  );
2838
3250
  const registryKy2 = getRegistryKy();
@@ -2861,23 +3273,23 @@ var AiReviewViewView = ({
2861
3273
  timeout = setTimeout(loadAiReviewText, 1e3);
2862
3274
  return () => clearTimeout(timeout);
2863
3275
  }, [aiReviewId]);
2864
- const html = useMemo3(
3276
+ const html = useMemo4(
2865
3277
  () => marked.parse(review.ai_review_text || ""),
2866
3278
  [review.ai_review_text]
2867
3279
  );
2868
- return /* @__PURE__ */ jsxs17(Fragment5, { children: [
2869
- /* @__PURE__ */ jsxs17(DialogHeader, { className: "rf-flex rf-flex-row rf-items-center rf-justify-between", children: [
2870
- /* @__PURE__ */ jsx23(Button, { variant: "ghost", size: "sm", onClick: onBack, children: "Back" }),
2871
- /* @__PURE__ */ jsx23(DialogTitle, { children: "AI Review" })
3280
+ return /* @__PURE__ */ jsxs20(Fragment5, { children: [
3281
+ /* @__PURE__ */ jsxs20(DialogHeader, { className: "rf-flex rf-flex-row rf-items-center rf-justify-between", children: [
3282
+ /* @__PURE__ */ jsx27(Button, { variant: "ghost", size: "sm", onClick: onBack, children: "Back" }),
3283
+ /* @__PURE__ */ jsx27(DialogTitle, { children: "AI Review" })
2872
3284
  ] }),
2873
- aiReviewText ? /* @__PURE__ */ jsx23(
3285
+ aiReviewText ? /* @__PURE__ */ jsx27(
2874
3286
  "div",
2875
3287
  {
2876
3288
  className: "rf-h-64 rf-overflow-y-auto rf-prose rf-max-w-none rf-mt-2",
2877
3289
  dangerouslySetInnerHTML: { __html: html }
2878
3290
  }
2879
- ) : /* @__PURE__ */ jsx23("div", { className: "rf-h-64 rf-overflow-y-auto rf-prose rf-max-w-none rf-mt-2", children: /* @__PURE__ */ jsxs17("div", { className: "rf-flex rf-items-center rf-justify-center rf-h-full", children: [
2880
- /* @__PURE__ */ jsxs17(
3291
+ ) : /* @__PURE__ */ jsx27("div", { className: "rf-h-64 rf-overflow-y-auto rf-prose rf-max-w-none rf-mt-2", children: /* @__PURE__ */ jsxs20("div", { className: "rf-flex rf-items-center rf-justify-center rf-h-full", children: [
3292
+ /* @__PURE__ */ jsxs20(
2881
3293
  "svg",
2882
3294
  {
2883
3295
  className: "rf-animate-spin rf-h-6 rf-w-6 rf-text-zinc-400 rf-mr-2",
@@ -2886,7 +3298,7 @@ var AiReviewViewView = ({
2886
3298
  viewBox: "0 0 24 24",
2887
3299
  "aria-hidden": "true",
2888
3300
  children: [
2889
- /* @__PURE__ */ jsx23(
3301
+ /* @__PURE__ */ jsx27(
2890
3302
  "circle",
2891
3303
  {
2892
3304
  className: "rf-opacity-25",
@@ -2897,7 +3309,7 @@ var AiReviewViewView = ({
2897
3309
  strokeWidth: "4"
2898
3310
  }
2899
3311
  ),
2900
- /* @__PURE__ */ jsx23(
3312
+ /* @__PURE__ */ jsx27(
2901
3313
  "path",
2902
3314
  {
2903
3315
  className: "rf-opacity-75",
@@ -2908,27 +3320,27 @@ var AiReviewViewView = ({
2908
3320
  ]
2909
3321
  }
2910
3322
  ),
2911
- /* @__PURE__ */ jsx23("span", { children: "Loading..." })
3323
+ /* @__PURE__ */ jsx27("span", { children: "Loading..." })
2912
3324
  ] }) })
2913
3325
  ] });
2914
3326
  };
2915
3327
 
2916
3328
  // lib/components/AiReviewDialog/AiReviewDialog.tsx
2917
- import { jsx as jsx24, jsxs as jsxs18 } from "react/jsx-runtime";
3329
+ import { jsx as jsx28, jsxs as jsxs21 } from "react/jsx-runtime";
2918
3330
  var AiReviewDialog = ({
2919
3331
  isOpen,
2920
3332
  onClose,
2921
3333
  packageName
2922
3334
  }) => {
2923
- const [stage, setStage] = useState11(
3335
+ const [stage, setStage] = useState15(
2924
3336
  "list_reviews"
2925
3337
  );
2926
- const [selectedReview, setSelectedReview] = useState11(null);
3338
+ const [selectedReview, setSelectedReview] = useState15(null);
2927
3339
  const handleSelect = (review) => {
2928
3340
  setSelectedReview(review);
2929
3341
  setStage("view_review");
2930
3342
  };
2931
- return /* @__PURE__ */ jsx24(
3343
+ return /* @__PURE__ */ jsx28(
2932
3344
  Dialog,
2933
3345
  {
2934
3346
  open: isOpen,
@@ -2939,15 +3351,15 @@ var AiReviewDialog = ({
2939
3351
  onClose();
2940
3352
  }
2941
3353
  },
2942
- children: /* @__PURE__ */ jsxs18(DialogContent, { className: "rf-max-w-2xl", children: [
2943
- stage === "list_reviews" && /* @__PURE__ */ jsx24(
3354
+ children: /* @__PURE__ */ jsxs21(DialogContent, { className: "rf-max-w-2xl", children: [
3355
+ stage === "list_reviews" && /* @__PURE__ */ jsx28(
2944
3356
  AiReviewListView,
2945
3357
  {
2946
3358
  packageName,
2947
3359
  onSelectReview: handleSelect
2948
3360
  }
2949
3361
  ),
2950
- stage === "view_review" && selectedReview && /* @__PURE__ */ jsx24(
3362
+ stage === "view_review" && selectedReview && /* @__PURE__ */ jsx28(
2951
3363
  AiReviewViewView,
2952
3364
  {
2953
3365
  review: selectedReview,
@@ -2966,13 +3378,13 @@ import { Toaster } from "react-hot-toast";
2966
3378
  import { QueryClient, QueryClientProvider } from "react-query";
2967
3379
 
2968
3380
  // lib/components/OrderDialog/InitialOrder.tsx
2969
- import { Loader2 as Loader22 } from "lucide-react";
3381
+ import { Loader2 as Loader24 } from "lucide-react";
2970
3382
  import { GitHubLogoIcon as GitHubLogoIcon2 } from "@radix-ui/react-icons";
2971
- import { useEffect as useEffect10, useMemo as useMemo4, useState as useState12 } from "react";
3383
+ import { useEffect as useEffect10, useMemo as useMemo5, useState as useState16 } from "react";
2972
3384
 
2973
3385
  // lib/components/OrderDialog/VendorQuoteCard.tsx
2974
3386
  import { Truck, Package } from "lucide-react";
2975
- import { jsx as jsx25, jsxs as jsxs19 } from "react/jsx-runtime";
3387
+ import { jsx as jsx29, jsxs as jsxs22 } from "react/jsx-runtime";
2976
3388
  function VendorQuoteCard({
2977
3389
  orderQuote,
2978
3390
  selectedShippingCarrier,
@@ -2982,27 +3394,27 @@ function VendorQuoteCard({
2982
3394
  const selectedShipping = selectedShippingCarrier ? orderQuote.shipping_options.find(
2983
3395
  (ship) => ship.carrier === selectedShippingCarrier
2984
3396
  ) : null;
2985
- return /* @__PURE__ */ jsxs19("div", { className: "rf-rounded-xl rf-bg-white rf-shadow-lg rf-border rf-border-gray-200", children: [
2986
- /* @__PURE__ */ jsxs19("div", { className: "rf-flex rf-items-center rf-justify-between rf-px-6 rf-pt-4 rf-pb-2", children: [
2987
- /* @__PURE__ */ jsxs19("div", { className: "rf-flex rf-items-center rf-gap-2", children: [
2988
- /* @__PURE__ */ jsx25(Package, { className: "rf-w-6 rf-h-6 rf-text-blue-500" }),
2989
- /* @__PURE__ */ jsx25("span", { className: "rf-font-semibold rf-text-lg", children: orderQuote.vendor_name.toUpperCase() })
3397
+ return /* @__PURE__ */ jsxs22("div", { className: "rf-rounded-xl rf-bg-white rf-shadow-lg rf-border rf-border-gray-200", children: [
3398
+ /* @__PURE__ */ jsxs22("div", { className: "rf-flex rf-items-center rf-justify-between rf-px-6 rf-pt-4 rf-pb-2", children: [
3399
+ /* @__PURE__ */ jsxs22("div", { className: "rf-flex rf-items-center rf-gap-2", children: [
3400
+ /* @__PURE__ */ jsx29(Package, { className: "rf-w-6 rf-h-6 rf-text-blue-500" }),
3401
+ /* @__PURE__ */ jsx29("span", { className: "rf-font-semibold rf-text-lg", children: orderQuote.vendor_name.toUpperCase() })
2990
3402
  ] }),
2991
- /* @__PURE__ */ jsxs19("div", { className: "rf-flex rf-flex-col rf-items-end", children: [
2992
- /* @__PURE__ */ jsx25("span", { className: "rf-text-gray-500 rf-text-sm", children: "Fully Assembled PCB" }),
2993
- /* @__PURE__ */ jsxs19("div", { className: "rf-flex rf-items-center rf-gap-2", children: [
2994
- /* @__PURE__ */ jsxs19("span", { className: "rf-text-gray-400 rf-line-through rf-text-base", children: [
3403
+ /* @__PURE__ */ jsxs22("div", { className: "rf-flex rf-flex-col rf-items-end", children: [
3404
+ /* @__PURE__ */ jsx29("span", { className: "rf-text-gray-500 rf-text-sm", children: "Fully Assembled PCB" }),
3405
+ /* @__PURE__ */ jsxs22("div", { className: "rf-flex rf-items-center rf-gap-2", children: [
3406
+ /* @__PURE__ */ jsxs22("span", { className: "rf-text-gray-400 rf-line-through rf-text-base", children: [
2995
3407
  "$",
2996
3408
  lowestShippingCarrierCost.toFixed(2)
2997
3409
  ] }),
2998
- /* @__PURE__ */ jsx25("span", { className: "rf-font-bold rf-text-xl rf-text-blue-600", children: "$50.00" })
3410
+ /* @__PURE__ */ jsx29("span", { className: "rf-font-bold rf-text-xl rf-text-blue-600", children: "$50.00" })
2999
3411
  ] })
3000
3412
  ] })
3001
3413
  ] }),
3002
- /* @__PURE__ */ jsx25("hr", { className: "rf-border-gray-200" }),
3003
- /* @__PURE__ */ jsxs19("div", { className: "rf-px-6 rf-pt-4 rf-pb-2", children: [
3004
- /* @__PURE__ */ jsx25("div", { className: "rf-mb-2 rf-text-sm rf-font-bold rf-text-gray-700", children: "Shipping Options:" }),
3005
- /* @__PURE__ */ jsx25("div", { className: "rf-flex rf-flex-col rf-gap-2 rf-mb-2", children: orderQuote.shipping_options.map((ship, idx) => /* @__PURE__ */ jsxs19(
3414
+ /* @__PURE__ */ jsx29("hr", { className: "rf-border-gray-200" }),
3415
+ /* @__PURE__ */ jsxs22("div", { className: "rf-px-6 rf-pt-4 rf-pb-2", children: [
3416
+ /* @__PURE__ */ jsx29("div", { className: "rf-mb-2 rf-text-sm rf-font-bold rf-text-gray-700", children: "Shipping Options:" }),
3417
+ /* @__PURE__ */ jsx29("div", { className: "rf-flex rf-flex-col rf-gap-2 rf-mb-2", children: orderQuote.shipping_options.map((ship, idx) => /* @__PURE__ */ jsxs22(
3006
3418
  "button",
3007
3419
  {
3008
3420
  type: "button",
@@ -3012,31 +3424,31 @@ function VendorQuoteCard({
3012
3424
  ),
3013
3425
  onClick: () => onSelectShippingCarrier(ship.carrier),
3014
3426
  children: [
3015
- /* @__PURE__ */ jsx25(Truck, { className: "rf-w-5 rf-h-5 rf-text-yellow-500" }),
3016
- /* @__PURE__ */ jsxs19("div", { className: "rf-text-left rf-flex-1", children: [
3017
- /* @__PURE__ */ jsx25("div", { className: "rf-leading-tight rf-font-medium", children: ship.carrier }),
3018
- /* @__PURE__ */ jsx25("div", { className: "rf-text-xs rf-text-gray-500", children: "Express, 5-12 days" })
3427
+ /* @__PURE__ */ jsx29(Truck, { className: "rf-w-5 rf-h-5 rf-text-yellow-500" }),
3428
+ /* @__PURE__ */ jsxs22("div", { className: "rf-text-left rf-flex-1", children: [
3429
+ /* @__PURE__ */ jsx29("div", { className: "rf-leading-tight rf-font-medium", children: ship.carrier }),
3430
+ /* @__PURE__ */ jsx29("div", { className: "rf-text-xs rf-text-gray-500", children: "Express, 5-12 days" })
3019
3431
  ] }),
3020
- /* @__PURE__ */ jsxs19("div", { className: "rf-flex rf-flex-col rf-items-end rf-ml-2", children: [
3021
- /* @__PURE__ */ jsxs19("span", { className: "rf-text-gray-400 rf-line-through rf-text-sm", children: [
3432
+ /* @__PURE__ */ jsxs22("div", { className: "rf-flex rf-flex-col rf-items-end rf-ml-2", children: [
3433
+ /* @__PURE__ */ jsxs22("span", { className: "rf-text-gray-400 rf-line-through rf-text-sm", children: [
3022
3434
  "$",
3023
3435
  ship.cost.toFixed(2)
3024
3436
  ] }),
3025
- /* @__PURE__ */ jsx25("span", { className: "rf-text-xs rf-text-blue-600 rf-font-medium", children: "waived" })
3437
+ /* @__PURE__ */ jsx29("span", { className: "rf-text-xs rf-text-blue-600 rf-font-medium", children: "waived" })
3026
3438
  ] })
3027
3439
  ]
3028
3440
  },
3029
3441
  ship.carrier + idx
3030
3442
  )) })
3031
3443
  ] }),
3032
- selectedShippingCarrier !== null && selectedShipping && /* @__PURE__ */ jsx25("div", { className: "rf-px-6 rf-pb-4 rf-pt-2", children: /* @__PURE__ */ jsxs19("div", { className: "rf-flex rf-justify-between rf-items-center rf-mt-3 rf-mb-2", children: [
3033
- /* @__PURE__ */ jsx25("span", { className: "rf-text-gray-700 rf-font-bold", children: "Total (incl. shipping):" }),
3034
- /* @__PURE__ */ jsxs19("div", { className: "rf-flex rf-flex-col rf-items-end", children: [
3035
- /* @__PURE__ */ jsxs19("div", { className: "rf-text-gray-400 rf-line-through rf-text-base", children: [
3444
+ selectedShippingCarrier !== null && selectedShipping && /* @__PURE__ */ jsx29("div", { className: "rf-px-6 rf-pb-4 rf-pt-2", children: /* @__PURE__ */ jsxs22("div", { className: "rf-flex rf-justify-between rf-items-center rf-mt-3 rf-mb-2", children: [
3445
+ /* @__PURE__ */ jsx29("span", { className: "rf-text-gray-700 rf-font-bold", children: "Total (incl. shipping):" }),
3446
+ /* @__PURE__ */ jsxs22("div", { className: "rf-flex rf-flex-col rf-items-end", children: [
3447
+ /* @__PURE__ */ jsxs22("div", { className: "rf-text-gray-400 rf-line-through rf-text-base", children: [
3036
3448
  "$",
3037
3449
  (orderQuote.total_cost_without_shipping + selectedShipping.cost).toFixed(2)
3038
3450
  ] }),
3039
- /* @__PURE__ */ jsx25("div", { className: "rf-flex rf-items-center", children: /* @__PURE__ */ jsx25("span", { className: "rf-font-bold rf-text-xl rf-text-blue-600", children: "$50.00" }) })
3451
+ /* @__PURE__ */ jsx29("div", { className: "rf-flex rf-items-center", children: /* @__PURE__ */ jsx29("span", { className: "rf-font-bold rf-text-xl rf-text-blue-600", children: "$50.00" }) })
3040
3452
  ] })
3041
3453
  ] }) })
3042
3454
  ] });
@@ -3124,15 +3536,15 @@ var useOrderQuotePolling = (orderQuoteId) => {
3124
3536
  };
3125
3537
 
3126
3538
  // lib/components/OrderDialog/InitialOrder.tsx
3127
- import { Fragment as Fragment6, jsx as jsx26, jsxs as jsxs20 } from "react/jsx-runtime";
3539
+ import { Fragment as Fragment6, jsx as jsx30, jsxs as jsxs23 } from "react/jsx-runtime";
3128
3540
  var InitialOrderScreen = ({
3129
3541
  onCancel,
3130
3542
  packageReleaseId,
3131
3543
  signIn,
3132
3544
  isLoggedIn
3133
3545
  }) => {
3134
- const [selectedShippingCarrier, setSelectedShippingCarrier] = useState12(null);
3135
- const [orderQuoteId, setOrderQuoteId] = useState12(null);
3546
+ const [selectedShippingCarrier, setSelectedShippingCarrier] = useState16(null);
3547
+ const [orderQuoteId, setOrderQuoteId] = useState16(null);
3136
3548
  const { mutate: createOrderQuote2, error: createOrderQuoteError } = useCreateOrderQuote();
3137
3549
  useEffect10(() => {
3138
3550
  if (packageReleaseId) {
@@ -3161,7 +3573,7 @@ var InitialOrderScreen = ({
3161
3573
  setSelectedShippingCarrier(lowest?.carrier || null);
3162
3574
  }
3163
3575
  }, [orderQuote]);
3164
- const lowestShippingCarrierCost = useMemo4(() => {
3576
+ const lowestShippingCarrierCost = useMemo5(() => {
3165
3577
  return orderQuote && Array.isArray(orderQuote.shipping_options) && orderQuote.shipping_options.length > 0 ? orderQuote.shipping_options.reduce(
3166
3578
  (min, curr) => curr.cost < min.cost ? curr : min,
3167
3579
  orderQuote.shipping_options[0]
@@ -3169,20 +3581,20 @@ var InitialOrderScreen = ({
3169
3581
  }, [orderQuote]);
3170
3582
  const isNoTokenError = createOrderQuoteError && createOrderQuoteError.error?.error_code?.includes("no_token") || orderQuote?.error?.error_code?.includes("no_token") && signIn;
3171
3583
  if (!isLoggedIn || isNoTokenError) {
3172
- return /* @__PURE__ */ jsx26(SignInView, { signIn });
3584
+ return /* @__PURE__ */ jsx30(SignInView, { signIn });
3173
3585
  }
3174
- return /* @__PURE__ */ jsxs20("div", { className: "rf-max-w-lg rf-mx-auto rf-bg-white rf-rounded-2xl rf-py-8 rf-flex rf-flex-col rf-gap-3", children: [
3175
- /* @__PURE__ */ jsx26("h2", { className: "rf-text-3xl rf-font-bold rf-text-center", children: "Order PCB" }),
3176
- !(createOrderQuoteError || orderQuote?.error) && (!orderQuoteId || !orderQuote || orderQuote?.is_processing) && /* @__PURE__ */ jsx26(LoadingMessage, { message: "Fetching quotes..." }),
3177
- (createOrderQuoteError || orderQuote?.error) && /* @__PURE__ */ jsx26(
3586
+ return /* @__PURE__ */ jsxs23("div", { className: "rf-max-w-lg rf-mx-auto rf-bg-white rf-rounded-2xl rf-py-8 rf-flex rf-flex-col rf-gap-3", children: [
3587
+ /* @__PURE__ */ jsx30("h2", { className: "rf-text-3xl rf-font-bold rf-text-center", children: "Order PCB" }),
3588
+ !(createOrderQuoteError || orderQuote?.error) && (!orderQuoteId || !orderQuote || orderQuote?.is_processing) && /* @__PURE__ */ jsx30(LoadingMessage, { message: "Fetching quotes..." }),
3589
+ (createOrderQuoteError || orderQuote?.error) && /* @__PURE__ */ jsx30(
3178
3590
  ErrorMessage,
3179
3591
  {
3180
3592
  message: createOrderQuoteError && createOrderQuoteError.error?.message || orderQuote?.error?.message || "Failed to fetch quotes"
3181
3593
  }
3182
3594
  ),
3183
- orderQuote?.is_completed && !createOrderQuoteError && !orderQuote?.error && Array.isArray(orderQuote?.shipping_options) && orderQuote.shipping_options.length > 0 && /* @__PURE__ */ jsxs20(Fragment6, { children: [
3184
- /* @__PURE__ */ jsx26("div", { className: "rf-bg-blue-100 rf-text-blue-800 rf-p-3 rf-rounded-md rf-text-center rf-text-sm", children: "This board is eligible for the tscircuit Flat Fee" }),
3185
- /* @__PURE__ */ jsx26(
3595
+ orderQuote?.is_completed && !createOrderQuoteError && !orderQuote?.error && Array.isArray(orderQuote?.shipping_options) && orderQuote.shipping_options.length > 0 && /* @__PURE__ */ jsxs23(Fragment6, { children: [
3596
+ /* @__PURE__ */ jsx30("div", { className: "rf-bg-blue-100 rf-text-blue-800 rf-p-3 rf-rounded-md rf-text-center rf-text-sm", children: "This board is eligible for the tscircuit Flat Fee" }),
3597
+ /* @__PURE__ */ jsx30(
3186
3598
  VendorQuoteCard,
3187
3599
  {
3188
3600
  orderQuote,
@@ -3193,8 +3605,8 @@ var InitialOrderScreen = ({
3193
3605
  orderQuote?.order_quote_id
3194
3606
  )
3195
3607
  ] }),
3196
- /* @__PURE__ */ jsxs20("div", { className: "rf-flex rf-justify-between rf-mt-5 rf-gap-4", children: [
3197
- /* @__PURE__ */ jsx26(
3608
+ /* @__PURE__ */ jsxs23("div", { className: "rf-flex rf-justify-between rf-mt-5 rf-gap-4", children: [
3609
+ /* @__PURE__ */ jsx30(
3198
3610
  Button,
3199
3611
  {
3200
3612
  variant: "outline",
@@ -3204,7 +3616,7 @@ var InitialOrderScreen = ({
3204
3616
  children: "Cancel"
3205
3617
  }
3206
3618
  ),
3207
- /* @__PURE__ */ jsx26(
3619
+ /* @__PURE__ */ jsx30(
3208
3620
  Button,
3209
3621
  {
3210
3622
  type: "button",
@@ -3223,27 +3635,27 @@ var InitialOrderScreen = ({
3223
3635
  }
3224
3636
  )
3225
3637
  ] }),
3226
- /* @__PURE__ */ jsx26("div", { className: "rf-text-xs rf-text-center rf-text-gray-400 rf-mt-4", children: "Pricing may vary based on specifications." })
3638
+ /* @__PURE__ */ jsx30("div", { className: "rf-text-xs rf-text-center rf-text-gray-400 rf-mt-4", children: "Pricing may vary based on specifications." })
3227
3639
  ] });
3228
3640
  };
3229
- var LoadingMessage = ({ message }) => /* @__PURE__ */ jsxs20("div", { className: "rf-flex rf-flex-col rf-items-center rf-gap-2 rf-my-12", children: [
3230
- /* @__PURE__ */ jsx26(Loader22, { className: "rf-animate-spin rf-w-8 rf-h-8 rf-text-gray-400" }),
3231
- /* @__PURE__ */ jsx26("p", { className: "rf-text-gray-600", children: message })
3641
+ var LoadingMessage = ({ message }) => /* @__PURE__ */ jsxs23("div", { className: "rf-flex rf-flex-col rf-items-center rf-gap-2 rf-my-12", children: [
3642
+ /* @__PURE__ */ jsx30(Loader24, { className: "rf-animate-spin rf-w-8 rf-h-8 rf-text-gray-400" }),
3643
+ /* @__PURE__ */ jsx30("p", { className: "rf-text-gray-600", children: message })
3232
3644
  ] });
3233
- var ErrorMessage = ({ message }) => /* @__PURE__ */ jsx26("div", { className: "rf-text-red-600 rf-text-center rf-py-12", children: message });
3234
- var SignInView = ({ signIn }) => /* @__PURE__ */ jsxs20("div", { className: "rf-max-w-lg rf-mx-auto rf-bg-white rf-rounded-2xl rf-py-8 rf-flex rf-flex-col rf-gap-3", children: [
3235
- /* @__PURE__ */ jsx26("h2", { className: "rf-text-3xl rf-font-bold rf-text-center", children: "Order PCB" }),
3236
- /* @__PURE__ */ jsxs20("div", { className: "rf-flex rf-flex-col rf-items-center rf-gap-4 rf-py-8", children: [
3237
- /* @__PURE__ */ jsx26("p", { className: "rf-text-gray-600", children: "Please sign in to continue" }),
3238
- /* @__PURE__ */ jsxs20(Button, { onClick: signIn, className: "rf-flex rf-items-center rf-gap-2", children: [
3239
- /* @__PURE__ */ jsx26(GitHubLogoIcon2, { className: "rf-w-5 rf-h-5" }),
3645
+ var ErrorMessage = ({ message }) => /* @__PURE__ */ jsx30("div", { className: "rf-text-red-600 rf-text-center rf-py-12", children: message });
3646
+ var SignInView = ({ signIn }) => /* @__PURE__ */ jsxs23("div", { className: "rf-max-w-lg rf-mx-auto rf-bg-white rf-rounded-2xl rf-py-8 rf-flex rf-flex-col rf-gap-3", children: [
3647
+ /* @__PURE__ */ jsx30("h2", { className: "rf-text-3xl rf-font-bold rf-text-center", children: "Order PCB" }),
3648
+ /* @__PURE__ */ jsxs23("div", { className: "rf-flex rf-flex-col rf-items-center rf-gap-4 rf-py-8", children: [
3649
+ /* @__PURE__ */ jsx30("p", { className: "rf-text-gray-600", children: "Please sign in to continue" }),
3650
+ /* @__PURE__ */ jsxs23(Button, { onClick: signIn, className: "rf-flex rf-items-center rf-gap-2", children: [
3651
+ /* @__PURE__ */ jsx30(GitHubLogoIcon2, { className: "rf-w-5 rf-h-5" }),
3240
3652
  "Sign in with GitHub"
3241
3653
  ] })
3242
3654
  ] })
3243
3655
  ] });
3244
3656
 
3245
3657
  // lib/components/OrderDialog/OrderDialog.tsx
3246
- import { jsx as jsx27 } from "react/jsx-runtime";
3658
+ import { jsx as jsx31 } from "react/jsx-runtime";
3247
3659
  var queryClient = new QueryClient();
3248
3660
  var OrderDialog = ({
3249
3661
  isOpen,
@@ -3255,14 +3667,14 @@ var OrderDialog = ({
3255
3667
  signIn,
3256
3668
  isLoggedIn
3257
3669
  }) => {
3258
- return /* @__PURE__ */ jsx27(QueryClientProvider, { client: queryClient, children: /* @__PURE__ */ jsx27(
3670
+ return /* @__PURE__ */ jsx31(QueryClientProvider, { client: queryClient, children: /* @__PURE__ */ jsx31(
3259
3671
  Dialog,
3260
3672
  {
3261
3673
  open: isOpen,
3262
3674
  onOpenChange: (open) => {
3263
3675
  if (!open) onClose();
3264
3676
  },
3265
- children: /* @__PURE__ */ jsx27(DialogContent, { className: "!rf-max-w-[660px] !rf-p-0 !rf-z-[101]", children: /* @__PURE__ */ jsx27("div", { className: "rf-relative rf-w-full", children: stage === "initial" && /* @__PURE__ */ jsx27(
3677
+ children: /* @__PURE__ */ jsx31(DialogContent, { className: "!rf-max-w-[660px] !rf-p-0 !rf-z-[101]", children: /* @__PURE__ */ jsx31("div", { className: "rf-relative rf-w-full", children: stage === "initial" && /* @__PURE__ */ jsx31(
3266
3678
  InitialOrderScreen,
3267
3679
  {
3268
3680
  onCancel: onClose,
@@ -3277,7 +3689,7 @@ var OrderDialog = ({
3277
3689
  };
3278
3690
 
3279
3691
  // lib/components/OrderDialog/CliOrderDialog.tsx
3280
- import { jsx as jsx28 } from "react/jsx-runtime";
3692
+ import { jsx as jsx32 } from "react/jsx-runtime";
3281
3693
  var CliOrderDialog = ({
3282
3694
  isOpen,
3283
3695
  onClose,
@@ -3287,7 +3699,7 @@ var CliOrderDialog = ({
3287
3699
  isLoggedIn
3288
3700
  }) => {
3289
3701
  const circuitJson = useRunFrameStore((state) => state.circuitJson);
3290
- return /* @__PURE__ */ jsx28(
3702
+ return /* @__PURE__ */ jsx32(
3291
3703
  OrderDialog,
3292
3704
  {
3293
3705
  signIn,
@@ -3302,11 +3714,11 @@ var CliOrderDialog = ({
3302
3714
  };
3303
3715
 
3304
3716
  // lib/components/OrderDialog/useOrderDialog.tsx
3305
- import { useState as useState13, useMemo as useMemo5, useCallback } from "react";
3306
- import { jsx as jsx29 } from "react/jsx-runtime";
3717
+ import { useState as useState17, useMemo as useMemo6, useCallback as useCallback7 } from "react";
3718
+ import { jsx as jsx33 } from "react/jsx-runtime";
3307
3719
  var useOrderDialogCli = () => {
3308
- const [isOpen, setIsOpen] = useState13(false);
3309
- const [stage, setStage] = useState13("initial");
3720
+ const [isOpen, setIsOpen] = useState17(false);
3721
+ const [stage, setStage] = useState17("initial");
3310
3722
  const handleClose = () => {
3311
3723
  setIsOpen(false);
3312
3724
  setStage("initial");
@@ -3326,15 +3738,15 @@ var useOrderDialog = ({
3326
3738
  packageReleaseId
3327
3739
  }) => {
3328
3740
  useStyles();
3329
- const [isOpen, setIsOpen] = useState13(false);
3330
- const [stage, setStage] = useState13("initial");
3331
- const handleClose = useCallback(() => {
3741
+ const [isOpen, setIsOpen] = useState17(false);
3742
+ const [stage, setStage] = useState17("initial");
3743
+ const handleClose = useCallback7(() => {
3332
3744
  setIsOpen(false);
3333
3745
  setStage("initial");
3334
3746
  }, []);
3335
- const open = useCallback(() => setIsOpen(true), []);
3336
- const MemoizedOrderDialog = useMemo5(() => {
3337
- return (props) => /* @__PURE__ */ jsx29(
3747
+ const open = useCallback7(() => setIsOpen(true), []);
3748
+ const MemoizedOrderDialog = useMemo6(() => {
3749
+ return (props) => /* @__PURE__ */ jsx33(
3338
3750
  OrderDialog,
3339
3751
  {
3340
3752
  ...props,
@@ -3355,30 +3767,30 @@ var useOrderDialog = ({
3355
3767
  };
3356
3768
 
3357
3769
  // lib/components/FileMenuLeftHeader.tsx
3358
- import { Fragment as Fragment7, jsx as jsx30, jsxs as jsxs21 } from "react/jsx-runtime";
3770
+ import { Fragment as Fragment7, jsx as jsx34, jsxs as jsxs24 } from "react/jsx-runtime";
3359
3771
  var FileMenuLeftHeader = (props) => {
3360
3772
  const lastRunEvalVersion = useRunnerStore((s) => s.lastRunEvalVersion);
3361
- const [snippetName, setSnippetName] = useState14(null);
3362
- const [hasUnsavedChanges, setHasUnsavedChanges] = useState14(false);
3363
- const [hasNeverBeenSaved, setHasNeverBeenSaved] = useState14(true);
3364
- const [isSaving, setIsSaving] = useState14(false);
3365
- const [requestToSaveSentAt, setRequestToSaveSentAt] = useState14(
3773
+ const [snippetName, setSnippetName] = useState18(null);
3774
+ const [hasUnsavedChanges, setHasUnsavedChanges] = useState18(false);
3775
+ const [hasNeverBeenSaved, setHasNeverBeenSaved] = useState18(true);
3776
+ const [isSaving, setIsSaving] = useState18(false);
3777
+ const [requestToSaveSentAt, setRequestToSaveSentAt] = useState18(
3366
3778
  null
3367
3779
  );
3368
- const [availableSnippets, setAvailableSnippets] = useState14(
3780
+ const [availableSnippets, setAvailableSnippets] = useState18(
3369
3781
  null
3370
3782
  );
3371
- const [isSelectSnippetDialogOpen, setIsSelectSnippetDialogOpen] = useState14(false);
3372
- const [notificationMessage, setNotificationMessage] = useState14(
3783
+ const [isSelectSnippetDialogOpen, setIsSelectSnippetDialogOpen] = useState18(false);
3784
+ const [notificationMessage, setNotificationMessage] = useState18(
3373
3785
  null
3374
3786
  );
3375
- const [errorMessage, setErrorMessage] = useState14(null);
3376
- const [isError, setIsError] = useState14(false);
3377
- const [isExporting, setisExporting] = useState14(false);
3787
+ const [errorMessage, setErrorMessage] = useState18(null);
3788
+ const [isError, setIsError] = useState18(false);
3789
+ const [isExporting, setisExporting] = useState18(false);
3378
3790
  const orderDialog = useOrderDialogCli();
3379
3791
  const pushEvent = useRunFrameStore((state) => state.pushEvent);
3380
3792
  const recentEvents = useRunFrameStore((state) => state.recentEvents);
3381
- const firstRenderTime = useMemo6(() => Date.now(), []);
3793
+ const firstRenderTime = useMemo7(() => Date.now(), []);
3382
3794
  useEventHandler((event) => {
3383
3795
  if (new Date(event.created_at).valueOf() < firstRenderTime + 500) return;
3384
3796
  if (event.event_type === "FILE_UPDATED") {
@@ -3446,14 +3858,14 @@ var FileMenuLeftHeader = (props) => {
3446
3858
  };
3447
3859
  const storeCircuitJson = useRunFrameStore((state) => state.circuitJson);
3448
3860
  const circuitJson = storeCircuitJson ?? props.circuitJson;
3449
- const [isImportDialogOpen, setIsImportDialogOpen] = useState14(false);
3450
- const [isAiReviewDialogOpen, setIsAiReviewDialogOpen] = useState14(false);
3451
- return /* @__PURE__ */ jsxs21(Fragment7, { children: [
3452
- /* @__PURE__ */ jsxs21(DropdownMenu, { children: [
3453
- /* @__PURE__ */ jsx30(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsx30("div", { className: "rf-whitespace-nowrap rf-text-xs font-medium rf-p-2 rf-mx-1 rf-cursor-pointer rf-relative", children: "File" }) }),
3454
- /* @__PURE__ */ jsxs21(DropdownMenuContent, { className: "rf-z-[101]", children: [
3455
- !props.isWebEmbedded && /* @__PURE__ */ jsxs21(Fragment7, { children: [
3456
- /* @__PURE__ */ jsx30(
3861
+ const [isImportDialogOpen, setIsImportDialogOpen] = useState18(false);
3862
+ const [isAiReviewDialogOpen, setIsAiReviewDialogOpen] = useState18(false);
3863
+ return /* @__PURE__ */ jsxs24(Fragment7, { children: [
3864
+ /* @__PURE__ */ jsxs24(DropdownMenu, { children: [
3865
+ /* @__PURE__ */ jsx34(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsx34("div", { className: "rf-whitespace-nowrap rf-text-xs font-medium rf-p-2 rf-mx-1 rf-cursor-pointer rf-relative", children: "File" }) }),
3866
+ /* @__PURE__ */ jsxs24(DropdownMenuContent, { className: "rf-z-[101]", children: [
3867
+ !props.isWebEmbedded && /* @__PURE__ */ jsxs24(Fragment7, { children: [
3868
+ /* @__PURE__ */ jsx34(
3457
3869
  DropdownMenuItem,
3458
3870
  {
3459
3871
  className: "rf-text-xs",
@@ -3462,7 +3874,7 @@ var FileMenuLeftHeader = (props) => {
3462
3874
  children: isSaving ? "Saving..." : "Push"
3463
3875
  }
3464
3876
  ),
3465
- parseInt(window.location.port) > 5e3 && /* @__PURE__ */ jsx30(
3877
+ parseInt(window.location.port) > 5e3 && /* @__PURE__ */ jsx34(
3466
3878
  DropdownMenuItem,
3467
3879
  {
3468
3880
  className: "rf-text-xs",
@@ -3472,7 +3884,7 @@ var FileMenuLeftHeader = (props) => {
3472
3884
  children: "Order"
3473
3885
  }
3474
3886
  ),
3475
- /* @__PURE__ */ jsx30(
3887
+ /* @__PURE__ */ jsx34(
3476
3888
  DropdownMenuItem,
3477
3889
  {
3478
3890
  className: "rf-text-xs",
@@ -3481,7 +3893,7 @@ var FileMenuLeftHeader = (props) => {
3481
3893
  children: "Import"
3482
3894
  }
3483
3895
  ),
3484
- /* @__PURE__ */ jsx30(
3896
+ /* @__PURE__ */ jsx34(
3485
3897
  DropdownMenuItem,
3486
3898
  {
3487
3899
  className: "rf-text-xs",
@@ -3496,8 +3908,8 @@ var FileMenuLeftHeader = (props) => {
3496
3908
  }
3497
3909
  )
3498
3910
  ] }),
3499
- /* @__PURE__ */ jsxs21(DropdownMenuSub, { children: [
3500
- /* @__PURE__ */ jsx30(
3911
+ /* @__PURE__ */ jsxs24(DropdownMenuSub, { children: [
3912
+ /* @__PURE__ */ jsx34(
3501
3913
  DropdownMenuSubTrigger,
3502
3914
  {
3503
3915
  className: "rf-text-xs",
@@ -3505,7 +3917,7 @@ var FileMenuLeftHeader = (props) => {
3505
3917
  children: isExporting ? "Exporting..." : "Export"
3506
3918
  }
3507
3919
  ),
3508
- /* @__PURE__ */ jsx30(DropdownMenuPortal, { children: /* @__PURE__ */ jsx30(DropdownMenuSubContent, { children: availableExports.map((exp, i) => /* @__PURE__ */ jsx30(
3920
+ /* @__PURE__ */ jsx34(DropdownMenuPortal, { children: /* @__PURE__ */ jsx34(DropdownMenuSubContent, { children: availableExports.map((exp, i) => /* @__PURE__ */ jsx34(
3509
3921
  DropdownMenuItem,
3510
3922
  {
3511
3923
  onSelect: () => {
@@ -3520,16 +3932,16 @@ var FileMenuLeftHeader = (props) => {
3520
3932
  });
3521
3933
  },
3522
3934
  disabled: isExporting,
3523
- children: /* @__PURE__ */ jsx30("span", { className: "rf-text-xs", children: exp.name })
3935
+ children: /* @__PURE__ */ jsx34("span", { className: "rf-text-xs", children: exp.name })
3524
3936
  },
3525
3937
  i
3526
3938
  )) }) })
3527
3939
  ] }),
3528
- !props.isWebEmbedded && /* @__PURE__ */ jsxs21(DropdownMenuSub, { children: [
3529
- /* @__PURE__ */ jsx30(DropdownMenuSubTrigger, { className: "rf-text-xs", children: "Advanced" }),
3530
- /* @__PURE__ */ jsx30(DropdownMenuPortal, { children: /* @__PURE__ */ jsxs21(DropdownMenuSubContent, { children: [
3531
- /* @__PURE__ */ jsx30(DropdownMenuItem, { className: "rf-flex rf-items-center rf-gap-2", children: /* @__PURE__ */ jsxs21("div", { className: "rf-flex rf-items-center rf-gap-2", children: [
3532
- /* @__PURE__ */ jsx30(
3940
+ !props.isWebEmbedded && /* @__PURE__ */ jsxs24(DropdownMenuSub, { children: [
3941
+ /* @__PURE__ */ jsx34(DropdownMenuSubTrigger, { className: "rf-text-xs", children: "Advanced" }),
3942
+ /* @__PURE__ */ jsx34(DropdownMenuPortal, { children: /* @__PURE__ */ jsxs24(DropdownMenuSubContent, { children: [
3943
+ /* @__PURE__ */ jsx34(DropdownMenuItem, { className: "rf-flex rf-items-center rf-gap-2", children: /* @__PURE__ */ jsxs24("div", { className: "rf-flex rf-items-center rf-gap-2", children: [
3944
+ /* @__PURE__ */ jsx34(
3533
3945
  Checkbox,
3534
3946
  {
3535
3947
  id: "load-latest-eval",
@@ -3539,7 +3951,7 @@ var FileMenuLeftHeader = (props) => {
3539
3951
  }
3540
3952
  }
3541
3953
  ),
3542
- /* @__PURE__ */ jsx30(
3954
+ /* @__PURE__ */ jsx34(
3543
3955
  "label",
3544
3956
  {
3545
3957
  htmlFor: "load-latest-eval",
@@ -3548,31 +3960,31 @@ var FileMenuLeftHeader = (props) => {
3548
3960
  }
3549
3961
  )
3550
3962
  ] }) }),
3551
- lastRunEvalVersion && /* @__PURE__ */ jsx30(DropdownMenuItem, { className: "rf-flex rf-items-center rf-gap-2", children: /* @__PURE__ */ jsx30("div", { className: "rf-flex rf-items-center rf-gap-2", children: /* @__PURE__ */ jsxs21("span", { className: "rf-text-xs", children: [
3963
+ lastRunEvalVersion && /* @__PURE__ */ jsx34(DropdownMenuItem, { className: "rf-flex rf-items-center rf-gap-2", children: /* @__PURE__ */ jsx34("div", { className: "rf-flex rf-items-center rf-gap-2", children: /* @__PURE__ */ jsxs24("span", { className: "rf-text-xs", children: [
3552
3964
  "@tscircuit/eval@",
3553
3965
  lastRunEvalVersion
3554
3966
  ] }) }) }),
3555
- /* @__PURE__ */ jsx30(
3967
+ /* @__PURE__ */ jsx34(
3556
3968
  DropdownMenuItem,
3557
3969
  {
3558
3970
  className: "rf-flex rf-items-center rf-gap-2",
3559
3971
  onClick: () => {
3560
3972
  window.open("/api/admin", "_blank");
3561
3973
  },
3562
- children: /* @__PURE__ */ jsx30("div", { className: "rf-flex rf-items-center rf-gap-2", children: /* @__PURE__ */ jsx30("span", { className: "rf-text-xs", children: "CLI Admin Panel" }) })
3974
+ children: /* @__PURE__ */ jsx34("div", { className: "rf-flex rf-items-center rf-gap-2", children: /* @__PURE__ */ jsx34("span", { className: "rf-text-xs", children: "CLI Admin Panel" }) })
3563
3975
  }
3564
3976
  )
3565
3977
  ] }) })
3566
3978
  ] })
3567
3979
  ] }),
3568
- /* @__PURE__ */ jsx30(AlertDialog, { open: isError, onOpenChange: setIsError, children: /* @__PURE__ */ jsxs21(AlertDialogContent, { children: [
3569
- /* @__PURE__ */ jsxs21(AlertDialogHeader, { children: [
3570
- /* @__PURE__ */ jsx30(AlertDialogTitle, { children: "Error Saving Snippet" }),
3571
- /* @__PURE__ */ jsx30(AlertDialogDescription, { children: errorMessage })
3980
+ /* @__PURE__ */ jsx34(AlertDialog, { open: isError, onOpenChange: setIsError, children: /* @__PURE__ */ jsxs24(AlertDialogContent, { children: [
3981
+ /* @__PURE__ */ jsxs24(AlertDialogHeader, { children: [
3982
+ /* @__PURE__ */ jsx34(AlertDialogTitle, { children: "Error Saving Snippet" }),
3983
+ /* @__PURE__ */ jsx34(AlertDialogDescription, { children: errorMessage })
3572
3984
  ] }),
3573
- /* @__PURE__ */ jsx30(AlertDialogFooter, { children: /* @__PURE__ */ jsx30(AlertDialogCancel, { onClick: () => setIsError(false), children: "Dismiss" }) })
3985
+ /* @__PURE__ */ jsx34(AlertDialogFooter, { children: /* @__PURE__ */ jsx34(AlertDialogCancel, { onClick: () => setIsError(false), children: "Dismiss" }) })
3574
3986
  ] }) }),
3575
- /* @__PURE__ */ jsx30(
3987
+ /* @__PURE__ */ jsx34(
3576
3988
  SelectSnippetDialog,
3577
3989
  {
3578
3990
  snippetNames: availableSnippets ?? [],
@@ -3591,14 +4003,14 @@ var FileMenuLeftHeader = (props) => {
3591
4003
  }
3592
4004
  )
3593
4005
  ] }),
3594
- /* @__PURE__ */ jsx30(
3595
- ImportComponentDialog,
4006
+ /* @__PURE__ */ jsx34(
4007
+ ImportComponentDialogForCli,
3596
4008
  {
3597
4009
  isOpen: isImportDialogOpen,
3598
4010
  onClose: () => setIsImportDialogOpen(false)
3599
4011
  }
3600
4012
  ),
3601
- /* @__PURE__ */ jsx30(
4013
+ /* @__PURE__ */ jsx34(
3602
4014
  AiReviewDialog,
3603
4015
  {
3604
4016
  isOpen: isAiReviewDialogOpen,
@@ -3606,7 +4018,7 @@ var FileMenuLeftHeader = (props) => {
3606
4018
  packageName: snippetName
3607
4019
  }
3608
4020
  ),
3609
- /* @__PURE__ */ jsx30(
4021
+ /* @__PURE__ */ jsx34(
3610
4022
  Toaster,
3611
4023
  {
3612
4024
  position: "top-center",
@@ -3618,7 +4030,7 @@ var FileMenuLeftHeader = (props) => {
3618
4030
  }
3619
4031
  }
3620
4032
  ),
3621
- /* @__PURE__ */ jsx30(
4033
+ /* @__PURE__ */ jsx34(
3622
4034
  orderDialog.OrderDialog,
3623
4035
  {
3624
4036
  isOpen: orderDialog.isOpen,
@@ -3631,7 +4043,7 @@ var FileMenuLeftHeader = (props) => {
3631
4043
  };
3632
4044
 
3633
4045
  // lib/components/CircuitJsonPreview/CircuitJsonPreview.tsx
3634
- import { jsx as jsx31, jsxs as jsxs22 } from "react/jsx-runtime";
4046
+ import { jsx as jsx35, jsxs as jsxs25 } from "react/jsx-runtime";
3635
4047
  var dropdownMenuItems = [
3636
4048
  "assembly",
3637
4049
  "pinout",
@@ -3690,13 +4102,13 @@ var CircuitJsonPreview = ({
3690
4102
  setSearch: setEvalSearch,
3691
4103
  selectVersion: selectEvalVersion
3692
4104
  } = useEvalVersions(allowSelectingVersion);
3693
- const circuitJsonErrors = useMemo7(() => {
4105
+ const circuitJsonErrors = useMemo8(() => {
3694
4106
  if (!circuitJson) return null;
3695
4107
  return circuitJson.filter(
3696
4108
  (e) => e && "error_type" in e || e.type.includes("error")
3697
4109
  );
3698
4110
  }, [circuitJson]);
3699
- const circuitJsonWarnings = useMemo7(() => {
4111
+ const circuitJsonWarnings = useMemo8(() => {
3700
4112
  if (!circuitJson) return null;
3701
4113
  return circuitJson.filter(
3702
4114
  (e) => e && "warning_type" in e || e.type.includes("warning")
@@ -3707,13 +4119,13 @@ var CircuitJsonPreview = ({
3707
4119
  errorStack,
3708
4120
  circuitJsonErrors
3709
4121
  });
3710
- const [activeTab, setActiveTabState] = useState15(
4122
+ const [activeTab, setActiveTabState] = useState19(
3711
4123
  defaultActiveTab ?? defaultTab ?? availableTabs?.[0] ?? "pcb"
3712
4124
  );
3713
- const [lastActiveTab, setLastActiveTab] = useState15(null);
3714
- const [isFullScreen, setIsFullScreen] = useState15(defaultToFullScreen);
4125
+ const [lastActiveTab, setLastActiveTab] = useState19(null);
4126
+ const [isFullScreen, setIsFullScreen] = useState19(defaultToFullScreen);
3715
4127
  useFullscreenBodyScroll(isFullScreen);
3716
- const setActiveTab = useCallback2(
4128
+ const setActiveTab = useCallback8(
3717
4129
  (tab) => {
3718
4130
  setActiveTabState(tab);
3719
4131
  onActiveTabChange?.(tab);
@@ -3738,31 +4150,31 @@ var CircuitJsonPreview = ({
3738
4150
  );
3739
4151
  }
3740
4152
  }, [circuitJson]);
3741
- const setCadViewerRef = useCallback2((value) => {
4153
+ const setCadViewerRef = useCallback8((value) => {
3742
4154
  window.TSCIRCUIT_3D_OBJECT_REF = value === null ? void 0 : value;
3743
4155
  }, []);
3744
- return /* @__PURE__ */ jsx31(
4156
+ return /* @__PURE__ */ jsx35(
3745
4157
  "div",
3746
4158
  {
3747
4159
  className: cn(
3748
4160
  "flex flex-col relative rf-overflow-x-hidden rf-h-full",
3749
4161
  className
3750
4162
  ),
3751
- children: /* @__PURE__ */ jsx31(
4163
+ children: /* @__PURE__ */ jsx35(
3752
4164
  "div",
3753
4165
  {
3754
4166
  className: cn(
3755
4167
  "rf-md:sticky rf-md:top-2 rf-h-full",
3756
4168
  isFullScreen && "rf-fixed rf-top-0 rf-left-0 rf-w-full rf-h-full rf-bg-white rf-overflow-hidden"
3757
4169
  ),
3758
- children: /* @__PURE__ */ jsxs22(
4170
+ children: /* @__PURE__ */ jsxs25(
3759
4171
  Tabs,
3760
4172
  {
3761
4173
  value: activeTab,
3762
4174
  onValueChange: setActiveTab,
3763
4175
  className: "rf-flex-grow rf-flex rf-flex-col rf-h-full",
3764
4176
  children: [
3765
- /* @__PURE__ */ jsxs22(
4177
+ /* @__PURE__ */ jsxs25(
3766
4178
  "div",
3767
4179
  {
3768
4180
  className: cn(
@@ -3771,7 +4183,7 @@ var CircuitJsonPreview = ({
3771
4183
  ),
3772
4184
  children: [
3773
4185
  leftHeaderContent,
3774
- showFileMenu && !leftHeaderContent && /* @__PURE__ */ jsx31(
4186
+ showFileMenu && !leftHeaderContent && /* @__PURE__ */ jsx35(
3775
4187
  FileMenuLeftHeader,
3776
4188
  {
3777
4189
  isWebEmbedded,
@@ -3779,18 +4191,18 @@ var CircuitJsonPreview = ({
3779
4191
  projectName
3780
4192
  }
3781
4193
  ),
3782
- (leftHeaderContent || showFileMenu) && /* @__PURE__ */ jsx31("div", { className: "rf-flex-grow" }),
3783
- !leftHeaderContent && !showFileMenu && isRunningCode && /* @__PURE__ */ jsx31(Loader23, { className: "rf-w-4 rf-h-4 rf-animate-spin" }),
3784
- !leftHeaderContent && !showFileMenu && /* @__PURE__ */ jsx31("div", { className: "rf-flex-grow" }),
3785
- renderLog && renderLog.progress !== 1 && !errorMessage && /* @__PURE__ */ jsxs22("div", { className: "rf-flex rf-items-center rf-gap-2 rf-min-w-0 rf-max-w-xs", children: [
3786
- activeEffectName ? /* @__PURE__ */ jsx31(
4194
+ (leftHeaderContent || showFileMenu) && /* @__PURE__ */ jsx35("div", { className: "rf-flex-grow" }),
4195
+ !leftHeaderContent && !showFileMenu && isRunningCode && /* @__PURE__ */ jsx35(Loader25, { className: "rf-w-4 rf-h-4 rf-animate-spin" }),
4196
+ !leftHeaderContent && !showFileMenu && /* @__PURE__ */ jsx35("div", { className: "rf-flex-grow" }),
4197
+ renderLog && renderLog.progress !== 1 && !errorMessage && /* @__PURE__ */ jsxs25("div", { className: "rf-flex rf-items-center rf-gap-2 rf-min-w-0 rf-max-w-xs", children: [
4198
+ activeEffectName ? /* @__PURE__ */ jsx35(
3787
4199
  "div",
3788
4200
  {
3789
4201
  className: "rf-text-xs rf-text-gray-500 rf-truncate rf-min-w-0",
3790
4202
  title: activeEffectName,
3791
4203
  children: activeEffectName
3792
4204
  }
3793
- ) : renderLog.lastRenderEvent && /* @__PURE__ */ jsx31(
4205
+ ) : renderLog.lastRenderEvent && /* @__PURE__ */ jsx35(
3794
4206
  "div",
3795
4207
  {
3796
4208
  className: "rf-text-xs rf-text-gray-500 rf-truncate rf-min-w-0",
@@ -3798,16 +4210,16 @@ var CircuitJsonPreview = ({
3798
4210
  children: renderLog.lastRenderEvent?.phase ?? ""
3799
4211
  }
3800
4212
  ),
3801
- /* @__PURE__ */ jsx31("div", { className: "rf-w-4 rf-h-4 rf-bg-blue-500 rf-opacity-50 rf-rounded-full rf-text-white rf-flex-shrink-0", children: /* @__PURE__ */ jsx31(LoaderCircleIcon, { className: "rf-w-4 rf-h-4 rf-animate-spin" }) }),
3802
- /* @__PURE__ */ jsxs22("div", { className: "rf-text-xs rf-font-bold rf-text-gray-700 rf-tabular-nums rf-flex-shrink-0", children: [
4213
+ /* @__PURE__ */ jsx35("div", { className: "rf-w-4 rf-h-4 rf-bg-blue-500 rf-opacity-50 rf-rounded-full rf-text-white rf-flex-shrink-0", children: /* @__PURE__ */ jsx35(LoaderCircleIcon, { className: "rf-w-4 rf-h-4 rf-animate-spin" }) }),
4214
+ /* @__PURE__ */ jsxs25("div", { className: "rf-text-xs rf-font-bold rf-text-gray-700 rf-tabular-nums rf-flex-shrink-0", children: [
3803
4215
  ((renderLog.progress ?? 0) * 100).toFixed(1),
3804
4216
  "%"
3805
4217
  ] })
3806
4218
  ] }),
3807
- showRightHeaderContent && /* @__PURE__ */ jsxs22(TabsList, { children: [
3808
- showCodeTab && /* @__PURE__ */ jsx31(TabsTrigger, { value: "code", children: "Code" }),
3809
- !availableTabs || availableTabs.includes("pcb") ? /* @__PURE__ */ jsxs22(TabsTrigger, { value: "pcb", className: "rf-whitespace-nowrap", children: [
3810
- circuitJson && /* @__PURE__ */ jsx31(
4219
+ showRightHeaderContent && /* @__PURE__ */ jsxs25(TabsList, { children: [
4220
+ showCodeTab && /* @__PURE__ */ jsx35(TabsTrigger, { value: "code", children: "Code" }),
4221
+ !availableTabs || availableTabs.includes("pcb") ? /* @__PURE__ */ jsxs25(TabsTrigger, { value: "pcb", className: "rf-whitespace-nowrap", children: [
4222
+ circuitJson && /* @__PURE__ */ jsx35(
3811
4223
  "span",
3812
4224
  {
3813
4225
  className: cn(
@@ -3818,13 +4230,13 @@ var CircuitJsonPreview = ({
3818
4230
  ),
3819
4231
  "PCB"
3820
4232
  ] }) : null,
3821
- !availableTabs || availableTabs.includes("schematic") ? /* @__PURE__ */ jsxs22(
4233
+ !availableTabs || availableTabs.includes("schematic") ? /* @__PURE__ */ jsxs25(
3822
4234
  TabsTrigger,
3823
4235
  {
3824
4236
  value: "schematic",
3825
4237
  className: "rf-whitespace-nowrap",
3826
4238
  children: [
3827
- circuitJson && /* @__PURE__ */ jsx31(
4239
+ circuitJson && /* @__PURE__ */ jsx35(
3828
4240
  "span",
3829
4241
  {
3830
4242
  className: cn(
@@ -3837,8 +4249,8 @@ var CircuitJsonPreview = ({
3837
4249
  ]
3838
4250
  }
3839
4251
  ) : null,
3840
- !availableTabs || availableTabs.includes("cad") ? /* @__PURE__ */ jsxs22(TabsTrigger, { value: "cad", children: [
3841
- circuitJson && /* @__PURE__ */ jsx31(
4252
+ !availableTabs || availableTabs.includes("cad") ? /* @__PURE__ */ jsxs25(TabsTrigger, { value: "cad", children: [
4253
+ circuitJson && /* @__PURE__ */ jsx35(
3842
4254
  "span",
3843
4255
  {
3844
4256
  className: cn(
@@ -3849,34 +4261,34 @@ var CircuitJsonPreview = ({
3849
4261
  ),
3850
4262
  "3D"
3851
4263
  ] }) : null,
3852
- !["pcb", "cad", "schematic"].includes(activeTab) && /* @__PURE__ */ jsx31(TabsTrigger, { value: activeTab, children: capitalizeFirstLetters(activeTab) }),
3853
- /* @__PURE__ */ jsxs22(DropdownMenu, { children: [
3854
- /* @__PURE__ */ jsx31(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxs22("div", { className: "rf-whitespace-nowrap rf-p-2 rf-mr-1 rf-cursor-pointer rf-relative", children: [
3855
- /* @__PURE__ */ jsx31(EllipsisIcon, { className: "rf-w-4 rf-h-4" }),
3856
- (circuitJsonErrors && circuitJsonErrors.length > 0 || errorMessage) && /* @__PURE__ */ jsx31("span", { className: "rf-inline-flex rf-absolute rf-top-[6px] rf-right-[4px] rf-items-center rf-justify-center rf-w-1 rf-h-1 rf-ml-2 rf-text-[8px] rf-font-bold rf-text-white rf-bg-red-500 rf-rounded-full" })
4264
+ !["pcb", "cad", "schematic"].includes(activeTab) && /* @__PURE__ */ jsx35(TabsTrigger, { value: activeTab, children: capitalizeFirstLetters(activeTab) }),
4265
+ /* @__PURE__ */ jsxs25(DropdownMenu, { children: [
4266
+ /* @__PURE__ */ jsx35(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxs25("div", { className: "rf-whitespace-nowrap rf-p-2 rf-mr-1 rf-cursor-pointer rf-relative", children: [
4267
+ /* @__PURE__ */ jsx35(EllipsisIcon, { className: "rf-w-4 rf-h-4" }),
4268
+ (circuitJsonErrors && circuitJsonErrors.length > 0 || errorMessage) && /* @__PURE__ */ jsx35("span", { className: "rf-inline-flex rf-absolute rf-top-[6px] rf-right-[4px] rf-items-center rf-justify-center rf-w-1 rf-h-1 rf-ml-2 rf-text-[8px] rf-font-bold rf-text-white rf-bg-red-500 rf-rounded-full" })
3857
4269
  ] }) }),
3858
- /* @__PURE__ */ jsxs22(DropdownMenuContent, { className: "rf-*:text-xs rf-z-[101]", children: [
4270
+ /* @__PURE__ */ jsxs25(DropdownMenuContent, { className: "rf-*:text-xs rf-z-[101]", children: [
3859
4271
  dropdownMenuItems.filter(
3860
4272
  (item) => !availableTabs || availableTabs.includes(item)
3861
- ).map((item) => /* @__PURE__ */ jsxs22(
4273
+ ).map((item) => /* @__PURE__ */ jsxs25(
3862
4274
  DropdownMenuItem,
3863
4275
  {
3864
4276
  onSelect: () => setActiveTab(item),
3865
4277
  children: [
3866
- activeTab !== item && /* @__PURE__ */ jsx31(Circle2, { className: "rf-w-3 rf-h-3 rf-opacity-30" }),
3867
- activeTab === item && /* @__PURE__ */ jsx31(CheckIcon, { className: "rf-w-3 rf-h-3" }),
3868
- /* @__PURE__ */ jsx31("div", { className: "rf-pr-2", children: capitalizeFirstLetters(item) }),
3869
- item === "errors" && (circuitJsonErrors && circuitJsonErrors.length > 0 || errorMessage) && /* @__PURE__ */ jsx31("span", { className: "rf-inline-flex rf-items-center rf-justify-center rf-w-3 rf-h-3 rf-ml-2 rf-text-[8px] rf-font-bold rf-text-white rf-bg-red-500 rf-rounded-full", children: errorMessage ? 1 : circuitJsonErrors?.length })
4278
+ activeTab !== item && /* @__PURE__ */ jsx35(Circle2, { className: "rf-w-3 rf-h-3 rf-opacity-30" }),
4279
+ activeTab === item && /* @__PURE__ */ jsx35(CheckIcon, { className: "rf-w-3 rf-h-3" }),
4280
+ /* @__PURE__ */ jsx35("div", { className: "rf-pr-2", children: capitalizeFirstLetters(item) }),
4281
+ item === "errors" && (circuitJsonErrors && circuitJsonErrors.length > 0 || errorMessage) && /* @__PURE__ */ jsx35("span", { className: "rf-inline-flex rf-items-center rf-justify-center rf-w-3 rf-h-3 rf-ml-2 rf-text-[8px] rf-font-bold rf-text-white rf-bg-red-500 rf-rounded-full", children: errorMessage ? 1 : circuitJsonErrors?.length })
3870
4282
  ]
3871
4283
  },
3872
4284
  item
3873
4285
  )),
3874
- /* @__PURE__ */ jsx31(
4286
+ /* @__PURE__ */ jsx35(
3875
4287
  DropdownMenuItem,
3876
4288
  {
3877
4289
  disabled: true,
3878
4290
  className: "rf-opacity-60 rf-cursor-default rf-select-none",
3879
- children: /* @__PURE__ */ jsxs22("div", { className: "rf-pr-2 rf-text-xs rf-text-gray-500", children: [
4291
+ children: /* @__PURE__ */ jsxs25("div", { className: "rf-pr-2 rf-text-xs rf-text-gray-500", children: [
3880
4292
  "@tscircuit/runframe@",
3881
4293
  version.split(".").map(
3882
4294
  (part, i) => i === 2 ? parseInt(part) + 1 : part
@@ -3884,17 +4296,17 @@ var CircuitJsonPreview = ({
3884
4296
  ] })
3885
4297
  }
3886
4298
  ),
3887
- allowSelectingVersion ? /* @__PURE__ */ jsxs22(
4299
+ allowSelectingVersion ? /* @__PURE__ */ jsxs25(
3888
4300
  DropdownMenuSub,
3889
4301
  {
3890
4302
  onOpenChange: (open) => !open && setEvalSearch(""),
3891
4303
  children: [
3892
- /* @__PURE__ */ jsx31(DropdownMenuSubTrigger, { className: "rf-text-xs rf-opacity-60", children: /* @__PURE__ */ jsxs22("div", { className: "rf-pr-2 rf-text-xs rf-text-gray-500", children: [
4304
+ /* @__PURE__ */ jsx35(DropdownMenuSubTrigger, { className: "rf-text-xs rf-opacity-60", children: /* @__PURE__ */ jsxs25("div", { className: "rf-pr-2 rf-text-xs rf-text-gray-500", children: [
3893
4305
  "@tscircuit/eval@",
3894
4306
  lastRunEvalVersion ?? latestVersion ?? "latest"
3895
4307
  ] }) }),
3896
- /* @__PURE__ */ jsx31(DropdownMenuPortal, { children: /* @__PURE__ */ jsxs22(DropdownMenuSubContent, { className: "rf-*:text-xs rf-w-40 rf-max-h-[200px] rf-overflow-y-auto", children: [
3897
- /* @__PURE__ */ jsx31("div", { className: "rf-p-1", children: /* @__PURE__ */ jsx31(
4308
+ /* @__PURE__ */ jsx35(DropdownMenuPortal, { children: /* @__PURE__ */ jsxs25(DropdownMenuSubContent, { className: "rf-*:text-xs rf-w-40 rf-max-h-[200px] rf-overflow-y-auto", children: [
4309
+ /* @__PURE__ */ jsx35("div", { className: "rf-p-1", children: /* @__PURE__ */ jsx35(
3898
4310
  Input,
3899
4311
  {
3900
4312
  value: evalSearch,
@@ -3903,15 +4315,15 @@ var CircuitJsonPreview = ({
3903
4315
  className: "rf-h-7 rf-text-xs"
3904
4316
  }
3905
4317
  ) }),
3906
- /* @__PURE__ */ jsx31(DropdownMenuSeparator, {}),
3907
- /* @__PURE__ */ jsx31(
4318
+ /* @__PURE__ */ jsx35(DropdownMenuSeparator, {}),
4319
+ /* @__PURE__ */ jsx35(
3908
4320
  DropdownMenuItem,
3909
4321
  {
3910
4322
  onSelect: () => selectEvalVersion(null),
3911
4323
  children: latestVersion ? `${latestVersion} (latest)` : "latest"
3912
4324
  }
3913
4325
  ),
3914
- evalVersions.map((v) => /* @__PURE__ */ jsx31(
4326
+ evalVersions.map((v) => /* @__PURE__ */ jsx35(
3915
4327
  DropdownMenuItem,
3916
4328
  {
3917
4329
  onSelect: () => selectEvalVersion(v),
@@ -3922,12 +4334,12 @@ var CircuitJsonPreview = ({
3922
4334
  ] }) })
3923
4335
  ]
3924
4336
  }
3925
- ) : lastRunEvalVersion && /* @__PURE__ */ jsx31(
4337
+ ) : lastRunEvalVersion && /* @__PURE__ */ jsx35(
3926
4338
  DropdownMenuItem,
3927
4339
  {
3928
4340
  disabled: true,
3929
4341
  className: "rf-opacity-60 rf-cursor-default rf-select-none",
3930
- children: /* @__PURE__ */ jsxs22("div", { className: "rf-pr-2 rf-text-xs rf-text-gray-500", children: [
4342
+ children: /* @__PURE__ */ jsxs25("div", { className: "rf-pr-2 rf-text-xs rf-text-gray-500", children: [
3931
4343
  "@tscircuit/eval@",
3932
4344
  lastRunEvalVersion
3933
4345
  ] })
@@ -3936,33 +4348,33 @@ var CircuitJsonPreview = ({
3936
4348
  ] })
3937
4349
  ] })
3938
4350
  ] }),
3939
- showToggleFullScreen && /* @__PURE__ */ jsx31(Button, { onClick: toggleFullScreen, variant: "ghost", children: isFullScreen ? /* @__PURE__ */ jsx31(MinimizeIcon, { size: 16 }) : /* @__PURE__ */ jsx31(FullscreenIcon, { size: 16 }) })
4351
+ showToggleFullScreen && /* @__PURE__ */ jsx35(Button, { onClick: toggleFullScreen, variant: "ghost", children: isFullScreen ? /* @__PURE__ */ jsx35(MinimizeIcon, { size: 16 }) : /* @__PURE__ */ jsx35(FullscreenIcon, { size: 16 }) })
3940
4352
  ]
3941
4353
  }
3942
4354
  ),
3943
- showCodeTab && /* @__PURE__ */ jsx31(
4355
+ showCodeTab && /* @__PURE__ */ jsx35(
3944
4356
  TabsContent,
3945
4357
  {
3946
4358
  value: "code",
3947
4359
  className: "rf-flex-grow rf-overflow-hidden",
3948
- children: /* @__PURE__ */ jsx31("div", { className: "rf-h-full", children: codeTabContent })
4360
+ children: /* @__PURE__ */ jsx35("div", { className: "rf-h-full", children: codeTabContent })
3949
4361
  }
3950
4362
  ),
3951
- (!availableTabs || availableTabs.includes("pcb")) && /* @__PURE__ */ jsx31(TabsContent, { value: "pcb", children: /* @__PURE__ */ jsx31(
4363
+ (!availableTabs || availableTabs.includes("pcb")) && /* @__PURE__ */ jsx35(TabsContent, { value: "pcb", children: /* @__PURE__ */ jsx35(
3952
4364
  "div",
3953
4365
  {
3954
4366
  className: cn(
3955
4367
  "rf-overflow-hidden",
3956
4368
  isFullScreen ? "rf-h-[calc(100vh-52px)]" : "rf-h-full"
3957
4369
  ),
3958
- children: /* @__PURE__ */ jsx31(
4370
+ children: /* @__PURE__ */ jsx35(
3959
4371
  ErrorBoundary,
3960
4372
  {
3961
- fallbackRender: ({ error }) => /* @__PURE__ */ jsx31("div", { className: "rf-mt-4 rf-bg-red-50 rf-rounded-md rf-border rf-border-red-200", children: /* @__PURE__ */ jsxs22("div", { className: "rf-p-4", children: [
3962
- /* @__PURE__ */ jsx31("h3", { className: "rf-text-lg rf-font-semibold rf-text-red-800 rf-mb-3", children: "Error loading PCB viewer" }),
3963
- /* @__PURE__ */ jsx31("p", { className: "rf-text-xs rf-font-mono rf-whitespace-pre-wrap rf-text-red-600 rf-mt-2", children: error?.message || "An unknown error occurred" })
4373
+ fallbackRender: ({ error }) => /* @__PURE__ */ jsx35("div", { className: "rf-mt-4 rf-bg-red-50 rf-rounded-md rf-border rf-border-red-200", children: /* @__PURE__ */ jsxs25("div", { className: "rf-p-4", children: [
4374
+ /* @__PURE__ */ jsx35("h3", { className: "rf-text-lg rf-font-semibold rf-text-red-800 rf-mb-3", children: "Error loading PCB viewer" }),
4375
+ /* @__PURE__ */ jsx35("p", { className: "rf-text-xs rf-font-mono rf-whitespace-pre-wrap rf-text-red-600 rf-mt-2", children: error?.message || "An unknown error occurred" })
3964
4376
  ] }) }),
3965
- children: circuitJson ? /* @__PURE__ */ jsx31(
4377
+ children: circuitJson ? /* @__PURE__ */ jsx35(
3966
4378
  PcbViewerWithContainerHeight,
3967
4379
  {
3968
4380
  focusOnHover: false,
@@ -3980,19 +4392,19 @@ var CircuitJsonPreview = ({
3980
4392
  }
3981
4393
  }
3982
4394
  }
3983
- ) : /* @__PURE__ */ jsx31(PreviewEmptyState_default, { onRunClicked })
4395
+ ) : /* @__PURE__ */ jsx35(PreviewEmptyState_default, { onRunClicked })
3984
4396
  }
3985
4397
  )
3986
4398
  }
3987
4399
  ) }),
3988
- (!availableTabs || availableTabs.includes("assembly")) && /* @__PURE__ */ jsx31(TabsContent, { value: "assembly", children: /* @__PURE__ */ jsx31(
4400
+ (!availableTabs || availableTabs.includes("assembly")) && /* @__PURE__ */ jsx35(TabsContent, { value: "assembly", children: /* @__PURE__ */ jsx35(
3989
4401
  "div",
3990
4402
  {
3991
4403
  className: cn(
3992
4404
  "rf-overflow-auto",
3993
4405
  isFullScreen ? "rf-h-screen" : "rf-h-full rf-min-h-[620px]"
3994
4406
  ),
3995
- children: /* @__PURE__ */ jsx31(ErrorBoundary, { fallback: /* @__PURE__ */ jsx31("div", { children: "Error loading Assembly" }), children: circuitJson ? /* @__PURE__ */ jsx31(
4407
+ children: /* @__PURE__ */ jsx35(ErrorBoundary, { fallback: /* @__PURE__ */ jsx35("div", { children: "Error loading Assembly" }), children: circuitJson ? /* @__PURE__ */ jsx35(
3996
4408
  AssemblyViewer,
3997
4409
  {
3998
4410
  circuitJson,
@@ -4002,21 +4414,21 @@ var CircuitJsonPreview = ({
4002
4414
  editingEnabled: true,
4003
4415
  debugGrid: true
4004
4416
  }
4005
- ) : /* @__PURE__ */ jsx31(PreviewEmptyState_default, { onRunClicked }) })
4417
+ ) : /* @__PURE__ */ jsx35(PreviewEmptyState_default, { onRunClicked }) })
4006
4418
  }
4007
4419
  ) }),
4008
- (!availableTabs || availableTabs.includes("pinout")) && /* @__PURE__ */ jsx31(TabsContent, { value: "pinout", children: /* @__PURE__ */ jsx31(
4420
+ (!availableTabs || availableTabs.includes("pinout")) && /* @__PURE__ */ jsx35(TabsContent, { value: "pinout", children: /* @__PURE__ */ jsx35(
4009
4421
  "div",
4010
4422
  {
4011
4423
  className: cn(
4012
4424
  "rf-overflow-auto",
4013
4425
  isFullScreen ? "rf-h-screen" : "rf-h-full rf-min-h-[620px]"
4014
4426
  ),
4015
- children: /* @__PURE__ */ jsx31(
4427
+ children: /* @__PURE__ */ jsx35(
4016
4428
  ErrorBoundary,
4017
4429
  {
4018
- fallback: /* @__PURE__ */ jsx31("div", { children: "Error loading Pinout Viewer" }),
4019
- children: circuitJson ? /* @__PURE__ */ jsx31(
4430
+ fallback: /* @__PURE__ */ jsx35("div", { children: "Error loading Pinout Viewer" }),
4431
+ children: circuitJson ? /* @__PURE__ */ jsx35(
4020
4432
  PinoutViewer,
4021
4433
  {
4022
4434
  circuitJson,
@@ -4024,26 +4436,26 @@ var CircuitJsonPreview = ({
4024
4436
  height: "100%"
4025
4437
  }
4026
4438
  }
4027
- ) : /* @__PURE__ */ jsx31(PreviewEmptyState_default, { onRunClicked })
4439
+ ) : /* @__PURE__ */ jsx35(PreviewEmptyState_default, { onRunClicked })
4028
4440
  }
4029
4441
  )
4030
4442
  }
4031
4443
  ) }),
4032
- (!availableTabs || availableTabs.includes("schematic")) && /* @__PURE__ */ jsx31(TabsContent, { value: "schematic", children: /* @__PURE__ */ jsx31(
4444
+ (!availableTabs || availableTabs.includes("schematic")) && /* @__PURE__ */ jsx35(TabsContent, { value: "schematic", children: /* @__PURE__ */ jsx35(
4033
4445
  "div",
4034
4446
  {
4035
4447
  className: cn(
4036
4448
  "rf-overflow-auto rf-bg-white",
4037
4449
  isFullScreen ? "rf-h-screen" : "rf-h-full rf-min-h-[620px]"
4038
4450
  ),
4039
- children: /* @__PURE__ */ jsx31(
4451
+ children: /* @__PURE__ */ jsx35(
4040
4452
  ErrorBoundary,
4041
4453
  {
4042
- fallbackRender: ({ error }) => /* @__PURE__ */ jsx31("div", { className: "rf-mt-4 rf-bg-red-50 rf-rounded-md rf-border rf-border-red-200", children: /* @__PURE__ */ jsxs22("div", { className: "rf-p-4", children: [
4043
- /* @__PURE__ */ jsx31("h3", { className: "rf-text-lg rf-font-semibold rf-text-red-800 rf-mb-3", children: "Error loading Schematic" }),
4044
- /* @__PURE__ */ jsx31("p", { className: "rf-text-xs rf-font-mono rf-whitespace-pre-wrap rf-text-red-600 rf-mt-2", children: error?.message || "An unknown error occurred" })
4454
+ fallbackRender: ({ error }) => /* @__PURE__ */ jsx35("div", { className: "rf-mt-4 rf-bg-red-50 rf-rounded-md rf-border rf-border-red-200", children: /* @__PURE__ */ jsxs25("div", { className: "rf-p-4", children: [
4455
+ /* @__PURE__ */ jsx35("h3", { className: "rf-text-lg rf-font-semibold rf-text-red-800 rf-mb-3", children: "Error loading Schematic" }),
4456
+ /* @__PURE__ */ jsx35("p", { className: "rf-text-xs rf-font-mono rf-whitespace-pre-wrap rf-text-red-600 rf-mt-2", children: error?.message || "An unknown error occurred" })
4045
4457
  ] }) }),
4046
- children: circuitJson ? /* @__PURE__ */ jsx31(
4458
+ children: circuitJson ? /* @__PURE__ */ jsx35(
4047
4459
  SchematicViewer,
4048
4460
  {
4049
4461
  spiceSimulationEnabled: true,
@@ -4057,65 +4469,65 @@ var CircuitJsonPreview = ({
4057
4469
  },
4058
4470
  debugGrid: showSchematicDebugGrid
4059
4471
  }
4060
- ) : /* @__PURE__ */ jsx31(PreviewEmptyState_default, { onRunClicked })
4472
+ ) : /* @__PURE__ */ jsx35(PreviewEmptyState_default, { onRunClicked })
4061
4473
  }
4062
4474
  )
4063
4475
  }
4064
4476
  ) }),
4065
- (!availableTabs || availableTabs.includes("cad")) && /* @__PURE__ */ jsx31(TabsContent, { value: "cad", children: /* @__PURE__ */ jsx31(
4477
+ (!availableTabs || availableTabs.includes("cad")) && /* @__PURE__ */ jsx35(TabsContent, { value: "cad", children: /* @__PURE__ */ jsx35(
4066
4478
  "div",
4067
4479
  {
4068
4480
  className: cn(
4069
4481
  "rf-overflow-auto",
4070
4482
  isFullScreen ? "rf-h-screen" : "rf-h-full rf-min-h-[620px]"
4071
4483
  ),
4072
- children: /* @__PURE__ */ jsx31(ErrorBoundary, { FallbackComponent: ErrorFallback, children: circuitJson ? /* @__PURE__ */ jsx31(
4484
+ children: /* @__PURE__ */ jsx35(ErrorBoundary, { FallbackComponent: ErrorFallback, children: circuitJson ? /* @__PURE__ */ jsx35(
4073
4485
  CadViewer,
4074
4486
  {
4075
4487
  ref: setCadViewerRef,
4076
4488
  circuitJson,
4077
4489
  autoRotateDisabled: autoRotate3dViewerDisabled
4078
4490
  }
4079
- ) : /* @__PURE__ */ jsx31(PreviewEmptyState_default, { onRunClicked }) })
4491
+ ) : /* @__PURE__ */ jsx35(PreviewEmptyState_default, { onRunClicked }) })
4080
4492
  }
4081
4493
  ) }),
4082
- (!availableTabs || availableTabs.includes("bom")) && /* @__PURE__ */ jsx31(TabsContent, { value: "bom", children: /* @__PURE__ */ jsx31(
4494
+ (!availableTabs || availableTabs.includes("bom")) && /* @__PURE__ */ jsx35(TabsContent, { value: "bom", children: /* @__PURE__ */ jsx35(
4083
4495
  "div",
4084
4496
  {
4085
4497
  className: cn(
4086
4498
  "rf-overflow-auto",
4087
4499
  isFullScreen ? "rf-h-screen" : "rf-h-full rf-min-h-[620px]"
4088
4500
  ),
4089
- children: /* @__PURE__ */ jsx31(
4501
+ children: /* @__PURE__ */ jsx35(
4090
4502
  ErrorBoundary,
4091
4503
  {
4092
- fallbackRender: ({ error }) => /* @__PURE__ */ jsx31("div", { className: "rf-mt-4 rf-bg-red-50 rf-rounded-md rf-border rf-border-red-200", children: /* @__PURE__ */ jsxs22("div", { className: "rf-p-4", children: [
4093
- /* @__PURE__ */ jsx31("h3", { className: "rf-text-lg rf-font-semibold rf-text-red-800 rf-mb-3", children: "Error loading Bill of Materials" }),
4094
- /* @__PURE__ */ jsx31("p", { className: "rf-text-xs rf-font-mono rf-whitespace-pre-wrap rf-text-red-600 rf-mt-2", children: error?.message || "An unknown error occurred" })
4504
+ fallbackRender: ({ error }) => /* @__PURE__ */ jsx35("div", { className: "rf-mt-4 rf-bg-red-50 rf-rounded-md rf-border rf-border-red-200", children: /* @__PURE__ */ jsxs25("div", { className: "rf-p-4", children: [
4505
+ /* @__PURE__ */ jsx35("h3", { className: "rf-text-lg rf-font-semibold rf-text-red-800 rf-mb-3", children: "Error loading Bill of Materials" }),
4506
+ /* @__PURE__ */ jsx35("p", { className: "rf-text-xs rf-font-mono rf-whitespace-pre-wrap rf-text-red-600 rf-mt-2", children: error?.message || "An unknown error occurred" })
4095
4507
  ] }) }),
4096
- children: circuitJson ? /* @__PURE__ */ jsx31(BomTable, { circuitJson }) : /* @__PURE__ */ jsx31(PreviewEmptyState_default, { onRunClicked })
4508
+ children: circuitJson ? /* @__PURE__ */ jsx35(BomTable, { circuitJson }) : /* @__PURE__ */ jsx35(PreviewEmptyState_default, { onRunClicked })
4097
4509
  }
4098
4510
  )
4099
4511
  }
4100
4512
  ) }),
4101
- (!availableTabs || availableTabs.includes("circuit_json")) && /* @__PURE__ */ jsx31(TabsContent, { value: "circuit_json", children: /* @__PURE__ */ jsx31(
4513
+ (!availableTabs || availableTabs.includes("circuit_json")) && /* @__PURE__ */ jsx35(TabsContent, { value: "circuit_json", children: /* @__PURE__ */ jsx35(
4102
4514
  "div",
4103
4515
  {
4104
4516
  className: cn(
4105
4517
  "rf-overflow-auto",
4106
4518
  isFullScreen ? "rf-h-screen" : "rf-h-full rf-min-h-[620px]"
4107
4519
  ),
4108
- children: /* @__PURE__ */ jsx31(ErrorBoundary, { fallback: /* @__PURE__ */ jsx31("div", { children: "Error loading JSON viewer" }), children: circuitJson ? /* @__PURE__ */ jsx31(CircuitJsonTableViewer, { elements: circuitJson }) : /* @__PURE__ */ jsx31(PreviewEmptyState_default, { onRunClicked }) })
4520
+ children: /* @__PURE__ */ jsx35(ErrorBoundary, { fallback: /* @__PURE__ */ jsx35("div", { children: "Error loading JSON viewer" }), children: circuitJson ? /* @__PURE__ */ jsx35(CircuitJsonTableViewer, { elements: circuitJson }) : /* @__PURE__ */ jsx35(PreviewEmptyState_default, { onRunClicked }) })
4109
4521
  }
4110
4522
  ) }),
4111
- (!availableTabs || availableTabs.includes("errors")) && /* @__PURE__ */ jsx31(TabsContent, { value: "errors", children: /* @__PURE__ */ jsx31(
4523
+ (!availableTabs || availableTabs.includes("errors")) && /* @__PURE__ */ jsx35(TabsContent, { value: "errors", children: /* @__PURE__ */ jsx35(
4112
4524
  "div",
4113
4525
  {
4114
4526
  className: cn(
4115
4527
  "rf-overflow-auto",
4116
4528
  isFullScreen ? "rf-h-screen" : "rf-h-full rf-min-h-[620px]"
4117
4529
  ),
4118
- children: errorMessage || circuitJsonErrors && circuitJsonErrors.length > 0 || circuitJson ? /* @__PURE__ */ jsx31(
4530
+ children: errorMessage || circuitJsonErrors && circuitJsonErrors.length > 0 || circuitJson ? /* @__PURE__ */ jsx35(
4119
4531
  ErrorTabContent,
4120
4532
  {
4121
4533
  code,
@@ -4129,10 +4541,10 @@ var CircuitJsonPreview = ({
4129
4541
  autoroutingLog,
4130
4542
  onReportAutoroutingLog
4131
4543
  }
4132
- ) : /* @__PURE__ */ jsx31(PreviewEmptyState_default, { onRunClicked })
4544
+ ) : /* @__PURE__ */ jsx35(PreviewEmptyState_default, { onRunClicked })
4133
4545
  }
4134
4546
  ) }),
4135
- showRenderLogTab && (!availableTabs || availableTabs.includes("render_log")) && /* @__PURE__ */ jsx31(TabsContent, { value: "render_log", children: /* @__PURE__ */ jsx31(
4547
+ showRenderLogTab && (!availableTabs || availableTabs.includes("render_log")) && /* @__PURE__ */ jsx35(TabsContent, { value: "render_log", children: /* @__PURE__ */ jsx35(
4136
4548
  RenderLogViewer,
4137
4549
  {
4138
4550
  renderLog,
@@ -4155,9 +4567,14 @@ import { SchematicViewer as SchematicViewer2 } from "@tscircuit/schematic-viewer
4155
4567
 
4156
4568
  export {
4157
4569
  cn,
4570
+ Tabs,
4571
+ TabsList,
4572
+ TabsTrigger,
4573
+ TabsContent,
4158
4574
  Button,
4159
4575
  linkify,
4160
4576
  BomTable,
4577
+ Input,
4161
4578
  PcbViewerWithContainerHeight,
4162
4579
  useStyles,
4163
4580
  useLocalStorageState,
@@ -4165,11 +4582,15 @@ export {
4165
4582
  debug_default,
4166
4583
  API_BASE,
4167
4584
  useRunFrameStore,
4168
- searchJLCComponents,
4169
- mapJLCComponentToSearchResult,
4170
- searchTscircuitComponents,
4171
- mapTscircuitSnippetToSearchResult,
4172
- ImportComponentDialog,
4585
+ Dialog,
4586
+ DialogContent,
4587
+ DialogHeader,
4588
+ DialogFooter,
4589
+ DialogTitle,
4590
+ DialogDescription,
4591
+ ImportComponentDialog2,
4592
+ toast,
4593
+ ImportComponentDialogForCli,
4173
4594
  registryKy,
4174
4595
  useOrderDialogCli,
4175
4596
  useOrderDialog,