jaml-ui 0.21.2 → 0.21.4

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.
Files changed (119) hide show
  1. package/DESIGN.md +36 -6
  2. package/dist/components/JamlAnalyzerFullscreen.d.ts +1 -1
  3. package/dist/components/JamlAnalyzerFullscreen.js +5 -81
  4. package/dist/components/JamlCurator.js +1 -1
  5. package/dist/components/JamlSpeedometer.d.ts +7 -2
  6. package/dist/components/JamlSpeedometer.js +8 -15
  7. package/dist/components/jamlMap/JamlMapEditor.js +42 -38
  8. package/dist/components/jamlMap/JokerPicker.js +2 -2
  9. package/dist/components/jamlMap/MysterySlot.js +4 -4
  10. package/dist/hooks/useSearch.d.ts +2 -1
  11. package/dist/hooks/useSearch.js +111 -8
  12. package/dist/lib/SpriteMapper.d.ts +10 -0
  13. package/dist/lib/SpriteMapper.js +48 -0
  14. package/dist/lib/cardParser.d.ts +8 -0
  15. package/dist/lib/cardParser.js +65 -0
  16. package/dist/lib/classes/BuyMetaData.d.ts +11 -0
  17. package/dist/lib/classes/BuyMetaData.js +1 -0
  18. package/dist/lib/config.d.ts +13 -0
  19. package/dist/lib/config.js +15 -0
  20. package/dist/lib/const.d.ts +61 -0
  21. package/dist/lib/const.js +521 -0
  22. package/dist/lib/data/constants.d.ts +11 -0
  23. package/dist/lib/data/constants.js +17 -0
  24. package/dist/lib/hooks/useDragScroll.d.ts +4 -0
  25. package/dist/lib/hooks/useDragScroll.js +48 -0
  26. package/dist/lib/hooks/useJamlFilter.d.ts +48 -0
  27. package/dist/lib/hooks/useJamlFilter.js +219 -0
  28. package/dist/lib/hooks/useSeedAnalyzer.d.ts +6 -0
  29. package/dist/lib/hooks/useSeedAnalyzer.js +48 -0
  30. package/dist/lib/jaml/jamlCompletion.d.ts +12 -0
  31. package/dist/lib/jaml/jamlCompletion.js +13 -0
  32. package/dist/lib/jaml/jamlData.d.ts +3 -0
  33. package/dist/lib/jaml/jamlData.js +8 -0
  34. package/dist/lib/jaml/jamlObjectives.d.ts +13 -0
  35. package/dist/lib/jaml/jamlObjectives.js +97 -0
  36. package/dist/lib/jaml/jamlParser.d.ts +14 -0
  37. package/dist/lib/jaml/jamlParser.js +47 -0
  38. package/dist/lib/jaml/jamlPresets.d.ts +8 -0
  39. package/dist/lib/jaml/jamlPresets.js +61 -0
  40. package/dist/lib/jaml/jamlSchema.d.ts +54 -0
  41. package/dist/lib/jaml/jamlSchema.js +91 -0
  42. package/dist/lib/parseDailyRitual.d.ts +45 -0
  43. package/dist/lib/parseDailyRitual.js +69 -0
  44. package/dist/lib/tts/getRevealPos.d.ts +5 -0
  45. package/dist/lib/tts/getRevealPos.js +16 -0
  46. package/dist/lib/tts/splitTtsDisplay.d.ts +19 -0
  47. package/dist/lib/tts/splitTtsDisplay.js +35 -0
  48. package/dist/lib/types.d.ts +121 -0
  49. package/dist/lib/types.js +1 -0
  50. package/dist/lib/utils.d.ts +2 -0
  51. package/dist/lib/utils.js +5 -0
  52. package/dist/ui/JimboIconButton.d.ts +10 -0
  53. package/dist/ui/JimboIconButton.js +28 -0
  54. package/dist/ui/JimboInputModal.d.ts +13 -0
  55. package/dist/ui/JimboInputModal.js +60 -0
  56. package/dist/ui/JimboSelect.d.ts +18 -0
  57. package/dist/ui/JimboSelect.js +43 -0
  58. package/dist/ui/PanelSplitter.d.ts +7 -0
  59. package/dist/ui/PanelSplitter.js +76 -0
  60. package/dist/ui/ide/AgnosticSeedCard.d.ts +19 -0
  61. package/dist/ui/ide/AgnosticSeedCard.js +48 -0
  62. package/dist/ui/ide/DeckSprite.d.ts +1 -0
  63. package/dist/ui/ide/DeckSprite.js +2 -0
  64. package/dist/ui/ide/JamlBuilder.d.ts +1 -0
  65. package/dist/ui/ide/JamlBuilder.js +112 -0
  66. package/dist/ui/ide/JamlEditor.d.ts +7 -0
  67. package/dist/ui/ide/JamlEditor.js +496 -0
  68. package/dist/ui/ide/JamlEditorMonaco.d.ts +8 -0
  69. package/dist/ui/ide/JamlEditorMonaco.js +78 -0
  70. package/dist/ui/ide/WasmStatus.d.ts +1 -0
  71. package/dist/ui/ide/WasmStatus.js +42 -0
  72. package/dist/ui/jimbo.css +336 -31
  73. package/dist/ui/jimboApp.d.ts +12 -0
  74. package/dist/ui/jimboApp.js +15 -0
  75. package/dist/ui/jimboInfoCard.d.ts +31 -0
  76. package/dist/ui/jimboInfoCard.js +26 -0
  77. package/dist/ui/jimboInset.d.ts +9 -0
  78. package/dist/ui/jimboInset.js +9 -0
  79. package/dist/ui/jimboSectionHeader.d.ts +11 -0
  80. package/dist/ui/jimboSectionHeader.js +9 -0
  81. package/dist/ui/jimboStatGrid.d.ts +13 -0
  82. package/dist/ui/jimboStatGrid.js +9 -0
  83. package/dist/ui/jimboWordmark.d.ts +10 -0
  84. package/dist/ui/jimboWordmark.js +9 -0
  85. package/dist/ui/mascot/JammySpeechBox.d.ts +9 -0
  86. package/dist/ui/mascot/JammySpeechBox.js +30 -0
  87. package/dist/ui/mascot/SeedMascot.d.ts +37 -0
  88. package/dist/ui/mascot/SeedMascot.js +17 -0
  89. package/dist/ui/mascot/index.d.ts +3 -0
  90. package/dist/ui/mascot/index.js +3 -0
  91. package/dist/ui/mascot/menuConfig.d.ts +102 -0
  92. package/dist/ui/mascot/menuConfig.js +12 -0
  93. package/dist/ui/panel.d.ts +1 -1
  94. package/dist/ui/panel.js +3 -21
  95. package/dist/ui/radial/RadialBadge.d.ts +17 -0
  96. package/dist/ui/radial/RadialBadge.js +43 -0
  97. package/dist/ui/radial/RadialBreadcrumb.d.ts +12 -0
  98. package/dist/ui/radial/RadialBreadcrumb.js +18 -0
  99. package/dist/ui/radial/RadialButton.d.ts +61 -0
  100. package/dist/ui/radial/RadialButton.js +102 -0
  101. package/dist/ui/radial/RadialMenu.d.ts +38 -0
  102. package/dist/ui/radial/RadialMenu.js +168 -0
  103. package/dist/ui/radial/RadialPill.d.ts +18 -0
  104. package/dist/ui/radial/RadialPill.js +15 -0
  105. package/dist/ui/radial/index.d.ts +16 -0
  106. package/dist/ui/radial/index.js +18 -0
  107. package/dist/ui/radial/radialMenuStore.d.ts +31 -0
  108. package/dist/ui/radial/radialMenuStore.js +122 -0
  109. package/dist/ui/radial/radialMenuViewport.d.ts +6 -0
  110. package/dist/ui/radial/radialMenuViewport.js +59 -0
  111. package/dist/ui/radial/useRadialMenu.d.ts +35 -0
  112. package/dist/ui/radial/useRadialMenu.js +107 -0
  113. package/dist/ui/showcase.d.ts +14 -6
  114. package/dist/ui/showcase.js +13 -21
  115. package/dist/ui/tokens.d.ts +5 -19
  116. package/dist/ui/tokens.js +5 -21
  117. package/dist/ui.d.ts +14 -0
  118. package/dist/ui.js +15 -0
  119. package/package.json +145 -146
@@ -0,0 +1,76 @@
1
+ // PORTABLE — intended for jaml-ui/src/ui/panelSplitter.tsx
2
+ // On paste, replace `from 'jaml-ui'` with `from './tokens.js'`.
3
+ "use client";
4
+ import { jsx as _jsx } from "react/jsx-runtime";
5
+ import { JimboColorOption } from "./tokens.js";
6
+ import { useCallback, useEffect, useRef } from "react";
7
+ const C = JimboColorOption;
8
+ export function PanelSplitter({ orientation = "vertical", onDrag, onKeyAdjust, "aria-label": ariaLabel, }) {
9
+ const draggingRef = useRef(false);
10
+ const lastRef = useRef(0);
11
+ const onDragRef = useRef(onDrag);
12
+ onDragRef.current = onDrag;
13
+ const handlePointerDown = useCallback((e) => {
14
+ e.preventDefault();
15
+ e.target.setPointerCapture(e.pointerId);
16
+ draggingRef.current = true;
17
+ lastRef.current = orientation === "vertical" ? e.clientX : e.clientY;
18
+ }, [orientation]);
19
+ useEffect(() => {
20
+ function move(e) {
21
+ if (!draggingRef.current) {
22
+ return;
23
+ }
24
+ const cur = orientation === "vertical" ? e.clientX : e.clientY;
25
+ const delta = cur - lastRef.current;
26
+ if (delta !== 0) {
27
+ lastRef.current = cur;
28
+ onDragRef.current(delta);
29
+ }
30
+ }
31
+ function up() {
32
+ draggingRef.current = false;
33
+ }
34
+ window.addEventListener("pointermove", move);
35
+ window.addEventListener("pointerup", up);
36
+ window.addEventListener("pointercancel", up);
37
+ return () => {
38
+ window.removeEventListener("pointermove", move);
39
+ window.removeEventListener("pointerup", up);
40
+ window.removeEventListener("pointercancel", up);
41
+ };
42
+ }, [orientation]);
43
+ const step = 16;
44
+ const isVertical = orientation === "vertical";
45
+ return (_jsx("button", { "aria-label": ariaLabel ?? "Resize panel", onKeyDown: (e) => {
46
+ if (!onKeyAdjust) {
47
+ return;
48
+ }
49
+ if (isVertical && e.key === "ArrowLeft") {
50
+ onKeyAdjust(-step);
51
+ }
52
+ if (isVertical && e.key === "ArrowRight") {
53
+ onKeyAdjust(step);
54
+ }
55
+ if (!isVertical && e.key === "ArrowUp") {
56
+ onKeyAdjust(-step);
57
+ }
58
+ if (!isVertical && e.key === "ArrowDown") {
59
+ onKeyAdjust(step);
60
+ }
61
+ }, onPointerDown: handlePointerDown, style: {
62
+ all: "unset",
63
+ display: "block",
64
+ flex: "0 0 auto",
65
+ width: isVertical ? 6 : undefined,
66
+ height: isVertical ? undefined : 6,
67
+ cursor: isVertical ? "col-resize" : "row-resize",
68
+ background: C.PANEL_EDGE,
69
+ borderLeft: isVertical ? `1px solid ${C.BLACK}` : undefined,
70
+ borderRight: isVertical ? `1px solid ${C.BLACK}` : undefined,
71
+ borderTop: isVertical ? undefined : `1px solid ${C.BLACK}`,
72
+ borderBottom: isVertical ? undefined : `1px solid ${C.BLACK}`,
73
+ touchAction: "none",
74
+ userSelect: "none",
75
+ }, type: "button" }));
76
+ }
@@ -0,0 +1,19 @@
1
+ interface AgnosticSeedCardProps {
2
+ seed: string;
3
+ deckSlug?: string;
4
+ stakeSlug?: string;
5
+ className?: string;
6
+ onClick?: () => void;
7
+ analysis?: any;
8
+ result?: any;
9
+ dayNumber?: number;
10
+ ritualId?: string;
11
+ jamlConfig?: string | null;
12
+ isLocked?: boolean;
13
+ onShowHowTo?: () => void;
14
+ onOpenSubmit?: () => void;
15
+ canSubmit?: boolean;
16
+ filter?: any;
17
+ }
18
+ export declare function AgnosticSeedCard({ seed, deckSlug, stakeSlug, isLocked, dayNumber, className, onClick, analysis: propAnalysis, result: propResult, filter }: AgnosticSeedCardProps): import("react/jsx-runtime").JSX.Element;
19
+ export {};
@@ -0,0 +1,48 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useState, useEffect } from 'react';
4
+ import motely, { MotelyWasm } from 'motely-wasm';
5
+ import { cn } from '../../lib/utils';
6
+ import { DeckSprite } from './DeckSprite';
7
+ import { Loader2, Sparkles } from 'lucide-react';
8
+ export function AgnosticSeedCard({ seed, deckSlug = 'Erratic', stakeSlug = 'White', isLocked, dayNumber, className, onClick, analysis: propAnalysis, result: propResult, filter }) {
9
+ const [loading, setLoading] = useState(false);
10
+ const [fetchedAnalysis, setFetchedAnalysis] = useState(null);
11
+ const result = propAnalysis || propResult || fetchedAnalysis;
12
+ useEffect(() => {
13
+ if (propAnalysis || propResult)
14
+ return;
15
+ const analyze = async () => {
16
+ setLoading(true);
17
+ try {
18
+ await motely.boot();
19
+ const jaml = `version: 1\nconfig:\n deck: ${deckSlug}\n stake: ${stakeSlug}\n`;
20
+ const rawData = MotelyWasm.analyzeJamlSeeds(jaml, [seed]);
21
+ if (rawData && rawData.seeds.length > 0) {
22
+ const seedData = rawData.seeds[0];
23
+ // The UI needs score and matches. The WASM provides score and tallies, but no matches yet.
24
+ // If filter logic is still desired, it needs to be updated. For now, pass what we have.
25
+ setFetchedAnalysis({
26
+ score: seedData.score,
27
+ matches: [], // TODO: C# Agent needs to provide matches in the WASM response if required.
28
+ analysis: seedData.analysis
29
+ });
30
+ }
31
+ }
32
+ catch (err) {
33
+ console.error(err);
34
+ }
35
+ finally {
36
+ setLoading(false);
37
+ }
38
+ };
39
+ analyze();
40
+ }, [seed, deckSlug, stakeSlug, propAnalysis, propResult, filter]);
41
+ if (isLocked) {
42
+ return (_jsxs("div", { className: cn("balatro-panel flex flex-col items-center justify-center text-center", "w-[315px] h-[340px] shrink-0", "border-dashed border-white/10 opacity-60 grayscale", "animate-sway", // Move sway to container
43
+ className), children: [_jsx("div", { className: "mb-4", children: _jsx(DeckSprite, { deck: deckSlug, stake: stakeSlug, size: 84 }) }), _jsx("h3", { className: "font-header text-2xl text-[var(--balatro-grey)] tracking-widest uppercase mb-2", children: "PREVIEW ONLY" }), _jsx("p", { className: "font-pixel text-[10px] text-white/30 max-w-[200px]", children: "This seed unlocks tomorrow. You can view the deck, but the strategy is hidden!" }), _jsx("div", { className: "mt-6 px-4 py-2 bg-black/60 rounded-xl border-2 border-white/10 shadow-[0_4px_0_rgba(0,0,0,0.5)]", children: _jsxs("span", { className: "font-header text-xl text-[var(--balatro-gold)] text-shadow-balatro", children: ["UNLOCKS DAY ", dayNumber] }) })] }));
44
+ }
45
+ return (_jsxs("div", { className: cn("balatro-panel flex flex-col cursor-pointer", "w-[315px] h-[340px] shrink-0", // ONE SIZE RULE
46
+ "animate-sway", // Preserve the cute breathing/sway
47
+ className), onClick: onClick, children: [_jsxs("div", { className: "flex items-start gap-3 pb-4 border-b border-white/10", children: [_jsx("div", { className: "animate-juice-pop", children: _jsx(DeckSprite, { deck: deckSlug, stake: stakeSlug, size: 64 }) }), _jsxs("div", { className: "flex-1 min-w-0", children: [_jsx("h3", { className: "font-header text-3xl text-white leading-tight mb-1 truncate", children: seed }), _jsxs("p", { className: "font-pixel text-xs text-white/40 tracking-wider", children: [deckSlug, " \u2022 ", stakeSlug] })] }), loading ? (_jsx(Loader2, { className: "animate-spin text-[var(--balatro-gold)] shrink-0", size: 28 })) : (_jsx(Sparkles, { className: "text-[var(--balatro-gold)] shrink-0", size: 28 }))] }), _jsxs("div", { className: "grid grid-cols-2 gap-3 py-6", children: [_jsxs("div", { className: "bg-black/40 rounded-xl p-5 border border-white/5 flex flex-col items-center justify-center", children: [_jsx("span", { className: "block text-[11px] font-pixel text-white/30 mb-2", children: "PRIMARY MATCH" }), _jsx("div", { className: "font-header text-xl text-[var(--balatro-blue)] leading-tight text-center", children: result?.matches?.[0]?.item?.name || result?.matches?.[0]?.name || "N/A" })] }), _jsxs("div", { className: "bg-black/40 rounded-xl p-5 border border-white/5 flex flex-col items-center justify-center", children: [_jsx("span", { className: "block text-[11px] font-pixel text-white/30 mb-2", children: "SIM SCORE" }), _jsx("div", { className: "font-header text-xl text-[var(--balatro-green)] leading-tight text-center", children: result?.score?.toLocaleString() || "0" })] })] }), _jsx("div", { className: "mt-auto flex items-center justify-center pt-3 border-t border-white/5", children: _jsx("span", { className: "font-header text-lg text-[var(--balatro-gold)] group-hover:text-white transition-colors text-shadow-balatro", children: "CLICK TO VIEW STRATEGY" }) })] }));
48
+ }
@@ -0,0 +1 @@
1
+ export { DeckSprite, DECK_SPRITE_POS as DECK_MAP, STAKE_SPRITE_POS as STAKE_MAP, type DeckSpriteProps, } from "../../components/DeckSprite.js";
@@ -0,0 +1,2 @@
1
+ "use client";
2
+ export { DeckSprite, DECK_SPRITE_POS as DECK_MAP, STAKE_SPRITE_POS as STAKE_MAP, } from "../../components/DeckSprite.js";
@@ -0,0 +1 @@
1
+ export default function JamlBuilder(): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,112 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useState, useRef, useEffect } from 'react';
4
+ import { useJamlFilter } from '../../lib/hooks/useJamlFilter';
5
+ import JamlEditor from './JamlEditor';
6
+ import { Loader2, Search, Copy, RotateCcw, Sparkles } from 'lucide-react';
7
+ import { AgnosticSeedCard } from './AgnosticSeedCard';
8
+ import { WasmStatus } from './WasmStatus';
9
+ export default function JamlBuilder() {
10
+ const { filter, jamlText, setFromJaml, updateFilter, addClause, editClause, deleteClause, editingClause, setEditingClause } = useJamlFilter();
11
+ const [isSearching, setIsSearching] = useState(false);
12
+ const [searchResults, setSearchResults] = useState([]);
13
+ const [searchError, setSearchError] = useState(null);
14
+ const [seedsProcessed, setSeedsProcessed] = useState(0);
15
+ const stopRef = useRef(false);
16
+ const searchCleanupRef = useRef(null);
17
+ useEffect(() => {
18
+ return () => {
19
+ if (searchCleanupRef.current)
20
+ searchCleanupRef.current();
21
+ handleStop();
22
+ };
23
+ }, []);
24
+ const pollRef = useRef(null);
25
+ const workerRef = useRef(null);
26
+ const handleSearch = async () => {
27
+ // Stop any existing search
28
+ if (isSearching) {
29
+ handleStop();
30
+ }
31
+ setIsSearching(true);
32
+ setSearchError(null);
33
+ setSearchResults([]);
34
+ setSeedsProcessed(0);
35
+ stopRef.current = false;
36
+ try {
37
+ // Import worker using Vite's ?worker syntax
38
+ const Worker = (await import('../../hooks/searchWorker?worker')).default;
39
+ const worker = new Worker();
40
+ workerRef.current = worker;
41
+ worker.onmessage = (e) => {
42
+ const event = e.data;
43
+ if (event.type === 'result') {
44
+ setSearchResults(prev => {
45
+ // Prevent duplicates
46
+ if (prev.some(r => r.seed === event.seed))
47
+ return prev;
48
+ return [...prev, {
49
+ seed: event.seed,
50
+ score: event.score,
51
+ tallies: event.tallyColumns || []
52
+ }];
53
+ });
54
+ }
55
+ else if (event.type === 'progress') {
56
+ setSeedsProcessed(Number(event.searched) || 0);
57
+ }
58
+ else if (event.type === 'complete') {
59
+ setIsSearching(false);
60
+ worker.terminate();
61
+ workerRef.current = null;
62
+ }
63
+ else if (event.type === 'error') {
64
+ setSearchError(event.message || 'Unknown error');
65
+ setIsSearching(false);
66
+ worker.terminate();
67
+ workerRef.current = null;
68
+ }
69
+ else if (event.type === 'cancelled') {
70
+ worker.terminate();
71
+ workerRef.current = null;
72
+ }
73
+ };
74
+ worker.postMessage({
75
+ type: 'start',
76
+ mode: 'random',
77
+ jaml: jamlText,
78
+ count: 1000 // A default random count, adjust as needed
79
+ });
80
+ }
81
+ catch (e) {
82
+ console.error("Local search error:", e);
83
+ setSearchError(e.message || 'Local search failed');
84
+ setIsSearching(false);
85
+ }
86
+ };
87
+ const handleStop = async () => {
88
+ stopRef.current = true;
89
+ setIsSearching(false);
90
+ if (workerRef.current) {
91
+ workerRef.current.postMessage({ type: 'stop' });
92
+ // The worker will reply with 'cancelled' and terminate itself
93
+ }
94
+ if (searchCleanupRef.current) {
95
+ searchCleanupRef.current();
96
+ searchCleanupRef.current = null;
97
+ }
98
+ };
99
+ const handleCopyJaml = () => {
100
+ if (typeof navigator !== 'undefined' && navigator.clipboard) {
101
+ navigator.clipboard.writeText(jamlText).catch(err => {
102
+ console.error('Failed to copy text: ', err);
103
+ });
104
+ }
105
+ };
106
+ const handleResetJaml = () => {
107
+ if (confirm("Reset editor to default JAML?")) {
108
+ setFromJaml(""); // useJamlFilter handles the default
109
+ }
110
+ };
111
+ return (_jsxs("div", { className: "w-full max-w-[1400px] mx-auto p-4 flex-1 overflow-hidden flex flex-col gap-4 bg-[var(--balatro-black)]/40", children: [_jsxs("div", { className: "flex flex-col lg:grid lg:grid-cols-[1fr_400px] gap-6 h-full overflow-hidden", children: [_jsxs("div", { className: "flex flex-col gap-6 overflow-hidden min-h-0", children: [_jsx("div", { className: "balatro-panel border-[var(--balatro-grey)] bg-black/40 py-4", children: _jsxs("div", { className: "flex justify-between items-center", children: [_jsxs("div", { className: "flex gap-4 items-center", children: [_jsxs("div", { children: [_jsx("h2", { className: "text-white text-xl font-header mb-1 uppercase tracking-widest leading-none", children: "JAML IDE" }), _jsx("p", { className: "text-white/60 font-pixel text-[10px] uppercase tracking-wide", children: "Ritual Factory v2.0" })] }), _jsx("div", { className: "h-8 w-px bg-white/10 mx-2" }), _jsxs("div", { className: "flex gap-1", children: [_jsx("button", { onClick: handleCopyJaml, className: "p-2 hover:bg-white/5 rounded text-white/30 hover:text-white/80 transition-colors", title: "Copy JAML", children: _jsx(Copy, { size: 16 }) }), _jsx("button", { onClick: handleResetJaml, className: "p-2 hover:bg-white/5 rounded text-white/30 hover:text-white/80 transition-colors", title: "Reset Editor", children: _jsx(RotateCcw, { size: 16 }) })] })] }), _jsxs("div", { className: "flex gap-2 items-center", children: [isSearching && (_jsxs("div", { className: "flex items-center gap-2 mr-2 px-3 py-1 bg-black/40 rounded border border-white/5 font-pixel text-[10px] text-white/50", children: [_jsx(Loader2, { size: 12, className: "animate-spin text-[var(--balatro-gold)]" }), _jsx("span", { children: "SEARCHING..." })] })), _jsxs("button", { onClick: handleSearch, disabled: isSearching, className: "balatro-button balatro-button-gold !py-2 !px-4 !text-sm flex items-center gap-2", children: [isSearching ? _jsx(Loader2, { size: 14, className: "animate-spin" }) : _jsx(Search, { size: 14 }), "RUN SEARCH"] }), isSearching && (_jsx("button", { onClick: handleStop, className: "balatro-button balatro-button-red !py-2 !px-4 !text-sm", children: "STOP" }))] })] }) }), _jsx("div", { className: "flex-1 min-h-0 bg-black/20 rounded-2xl border border-white/5 overflow-hidden shadow-inner flex flex-col", children: _jsx(JamlEditor, { initialJaml: jamlText, onJamlChange: (val) => setFromJaml(val), className: "flex-1" }) })] }), _jsx("div", { className: "flex flex-col gap-6 overflow-hidden pb-10", children: _jsxs("div", { className: "h-full balatro-panel border-[var(--balatro-gold)] overflow-hidden flex flex-col", children: [_jsxs("div", { className: "flex justify-between items-center mb-4", children: [_jsxs("div", { className: "flex items-center gap-3", children: [_jsxs("h3", { className: "text-[var(--balatro-gold)] text-xl font-header drop-shadow-md uppercase", children: ["Results ", searchResults.length > 0 && `(${searchResults.length})`] }), isSearching && (_jsxs("div", { className: "flex items-center gap-2 font-pixel text-[10px] text-[var(--balatro-blue)] animate-pulse", children: [_jsx(Sparkles, { size: 12, className: "animate-spin" }), _jsx("span", { children: seedsProcessed })] }))] }), isSearching && _jsx(Loader2, { size: 16, className: "animate-spin text-[var(--balatro-blue)]" })] }), isSearching && (_jsx("div", { className: "w-full h-1 bg-black/40 rounded-full mb-4 overflow-hidden border border-white/5", children: _jsx("div", { className: "h-full bg-gradient-to-r from-blue-500 via-purple-500 to-pink-500 animate-gradient-x transition-all duration-300", style: { width: `${Math.min((searchResults.length / 50) * 100, 100)}%` } }) })), _jsx("div", { className: "flex-1 overflow-y-auto custom-scrollbar p-1", children: searchResults.length > 0 ? (_jsx("div", { className: "grid grid-cols-1 gap-4", children: searchResults.map((result) => (_jsx(AgnosticSeedCard, { seed: result.seed, result: result, className: "!scale-95 !origin-top" }, result.seed))) })) : (_jsx("div", { className: "h-full flex flex-col items-center justify-center italic font-pixel text-sm border-2 border-dashed border-white/5 rounded-2xl p-4 text-center", children: searchError ? (_jsxs("div", { className: "text-[var(--balatro-red)] bg-red-950/20 p-4 rounded text-center", children: [_jsx("div", { className: "font-header text-lg mb-1", children: "SEARCH FAILED" }), _jsx("div", { className: "opacity-60", children: searchError })] })) : (_jsx("div", { className: "opacity-30 text-white/50", children: isSearching ? 'SEEKING...' : 'RESULTS WILL APPEAR HERE' })) })) })] }) })] }), _jsx(WasmStatus, {})] }));
112
+ }
@@ -0,0 +1,7 @@
1
+ interface InteractiveJamlEditorProps {
2
+ initialJaml?: string;
3
+ onJamlChange?: (jamlYaml: string, parsed: unknown, isValid: boolean) => void;
4
+ className?: string;
5
+ }
6
+ export default function JamlEditor({ initialJaml, onJamlChange, className }: InteractiveJamlEditorProps): import("react/jsx-runtime").JSX.Element;
7
+ export {};