jaml-ui 0.24.20 → 0.25.2

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 (233) hide show
  1. package/README.md +0 -13
  2. package/assets/WeeJokerExampleDAilyGame.png +0 -0
  3. package/assets/balatro-stake-chips.png +0 -0
  4. package/dist/assets.d.ts +1 -2
  5. package/dist/chunks/Layer-BBPJFHfs.js +17 -0
  6. package/dist/chunks/Layer-BBPJFHfs.js.map +1 -0
  7. package/dist/chunks/assets-RWUiFSTc.js +37 -0
  8. package/dist/chunks/assets-RWUiFSTc.js.map +1 -0
  9. package/dist/chunks/motelyItemDecoder-CueyZ0XD.js +6039 -0
  10. package/dist/chunks/motelyItemDecoder-CueyZ0XD.js.map +1 -0
  11. package/dist/chunks/spriteMapper-CFjN0_TV.js +2415 -0
  12. package/dist/chunks/spriteMapper-CFjN0_TV.js.map +1 -0
  13. package/dist/chunks/tokens-B65Fzble.js +57 -0
  14. package/dist/chunks/tokens-B65Fzble.js.map +1 -0
  15. package/dist/chunks/ui-5cBy3zAm.js +1387 -0
  16. package/dist/chunks/ui-5cBy3zAm.js.map +1 -0
  17. package/dist/components/AnalyzerExplorer.d.ts +1 -1
  18. package/dist/components/CardFan.d.ts +1 -1
  19. package/dist/components/CardList.d.ts +1 -1
  20. package/dist/components/DeckSprite.d.ts +1 -1
  21. package/dist/components/JamlAestheticSelector.d.ts +1 -1
  22. package/dist/components/JamlAnalyzerFullscreen.d.ts +5 -5
  23. package/dist/components/JamlCurator.d.ts +1 -6
  24. package/dist/components/JamlIde.d.ts +5 -5
  25. package/dist/components/JamlSeedInput.d.ts +1 -1
  26. package/dist/components/JamlSpeedometer.d.ts +1 -1
  27. package/dist/components/MotelyVersionBadge.d.ts +1 -1
  28. package/dist/components/Standardcard.d.ts +1 -1
  29. package/dist/components/jamlMap/CategoryPicker.d.ts +3 -3
  30. package/dist/components/jamlMap/JamlMapEditor.d.ts +1 -1
  31. package/dist/components/jamlMap/JokerPicker.d.ts +1 -1
  32. package/dist/components/jamlMap/MysterySlot.d.ts +2 -2
  33. package/dist/components/jamlMap/index.d.ts +4 -4
  34. package/dist/core.d.ts +5 -5
  35. package/dist/core.js +27 -5
  36. package/dist/core.js.map +1 -0
  37. package/dist/decode/motelyItemDecoder.d.ts +0 -10
  38. package/dist/decode/motelySprite.d.ts +1 -1
  39. package/dist/fonts/m6x11plus.otf +0 -0
  40. package/dist/hooks/analyzerStreamRegistry.d.ts +2 -2
  41. package/dist/hooks/useAnalyzer.d.ts +3 -3
  42. package/dist/hooks/useSearch.d.ts +2 -2
  43. package/dist/index.d.ts +29 -31
  44. package/dist/index.js +16721 -34
  45. package/dist/index.js.map +1 -0
  46. package/dist/lib/const.d.ts +2 -2
  47. package/dist/lib/hooks/useDragScroll.d.ts +1 -1
  48. package/dist/lib/hooks/useJamlFilter.d.ts +2 -2
  49. package/dist/lib/hooks/useSeedAnalyzer.d.ts +2 -2
  50. package/dist/lib/utils.d.ts +1 -1
  51. package/dist/motely.d.ts +4 -3
  52. package/dist/motely.js +65 -3
  53. package/dist/motely.js.map +1 -0
  54. package/dist/motelyBoot.d.ts +2 -0
  55. package/dist/motelyDisplay.d.ts +0 -2
  56. package/dist/r3f/Card3D.d.ts +2 -2
  57. package/dist/r3f/JimboBillboard.d.ts +1 -1
  58. package/dist/r3f.js +235 -3
  59. package/dist/r3f.js.map +1 -0
  60. package/dist/render/CanvasRenderer.d.ts +1 -1
  61. package/dist/sprites/spriteData.d.ts +1 -6
  62. package/dist/sprites/spriteMapper.d.ts +1 -1
  63. package/dist/ui/JimboBadge.d.ts +1 -1
  64. package/dist/ui/JimboFloating.d.ts +1 -1
  65. package/dist/ui/JimboIconButton.d.ts +1 -1
  66. package/dist/ui/JimboSelect.d.ts +1 -1
  67. package/dist/ui/footer.d.ts +2 -3
  68. package/dist/ui/hooks.d.ts +1 -1
  69. package/dist/ui/ide/DeckSprite.d.ts +1 -1
  70. package/dist/ui/jimbo.css +2 -1856
  71. package/dist/ui/jimboApp.d.ts +1 -1
  72. package/dist/ui/jimboFilterBar.d.ts +1 -1
  73. package/dist/ui/jimboFlankNav.d.ts +1 -1
  74. package/dist/ui/jimboInfoCard.d.ts +1 -1
  75. package/dist/ui/jimboInset.d.ts +1 -1
  76. package/dist/ui/jimboStatGrid.d.ts +1 -1
  77. package/dist/ui/jimboText.d.ts +1 -1
  78. package/dist/ui/jimboTooltip.d.ts +2 -2
  79. package/dist/ui/mascot/SeedMascot.d.ts +2 -2
  80. package/dist/ui/panel.d.ts +1 -1
  81. package/dist/ui/radial/RadialBadge.d.ts +1 -2
  82. package/dist/ui/radial/RadialButton.d.ts +1 -2
  83. package/dist/ui/radial/RadialMenu.d.ts +2 -2
  84. package/dist/ui/radial/RadialPill.d.ts +1 -2
  85. package/dist/ui/radial/index.d.ts +16 -16
  86. package/dist/ui/radial/radialMenuStore.d.ts +1 -1
  87. package/dist/ui/showcase.d.ts +1 -1
  88. package/dist/ui/sprites.d.ts +2 -2
  89. package/dist/ui.d.ts +0 -1
  90. package/dist/ui.js +3 -36
  91. package/dist/utils/gameCardUtils.d.ts +1 -1
  92. package/dist/utils/jamlVisualFilter.d.ts +1 -7
  93. package/package.json +13 -25
  94. package/dist/assets.js +0 -48
  95. package/dist/components/AnalyzerExplorer.js +0 -391
  96. package/dist/components/CardFan.js +0 -80
  97. package/dist/components/CardList.js +0 -5
  98. package/dist/components/DeckSprite.js +0 -75
  99. package/dist/components/GameCard.js +0 -355
  100. package/dist/components/JamlAestheticSelector.js +0 -22
  101. package/dist/components/JamlAnalyzerFullscreen.js +0 -263
  102. package/dist/components/JamlCodeEditor.js +0 -137
  103. package/dist/components/JamlCurator.js +0 -64
  104. package/dist/components/JamlCurator.stories.d.ts +0 -6
  105. package/dist/components/JamlCurator.stories.js +0 -14
  106. package/dist/components/JamlIde.js +0 -193
  107. package/dist/components/JamlIdeToolbar.js +0 -23
  108. package/dist/components/JamlIdeVisual.js +0 -218
  109. package/dist/components/JamlMapPreview.js +0 -121
  110. package/dist/components/JamlSeedInput.js +0 -26
  111. package/dist/components/JamlSpeedometer.js +0 -70
  112. package/dist/components/Jimbolate.js +0 -17
  113. package/dist/components/MotelyVersionBadge.js +0 -19
  114. package/dist/components/PaginatedFilterBrowser.js +0 -54
  115. package/dist/components/RunConfigModal.js +0 -59
  116. package/dist/components/Standardcard.js +0 -80
  117. package/dist/components/jamlMap/CategoryPicker.js +0 -135
  118. package/dist/components/jamlMap/JamlMapEditor.js +0 -304
  119. package/dist/components/jamlMap/JamlMapEditor.stories.d.ts +0 -7
  120. package/dist/components/jamlMap/JamlMapEditor.stories.js +0 -26
  121. package/dist/components/jamlMap/JamlMapEditorDemo.d.ts +0 -8
  122. package/dist/components/jamlMap/JamlMapEditorDemo.js +0 -323
  123. package/dist/components/jamlMap/JokerPicker.js +0 -113
  124. package/dist/components/jamlMap/MysterySlot.js +0 -128
  125. package/dist/components/jamlMap/MysterySlot.stories.d.ts +0 -7
  126. package/dist/components/jamlMap/MysterySlot.stories.js +0 -31
  127. package/dist/components/jamlMap/index.js +0 -4
  128. package/dist/decode/motelyItemDecoder.js +0 -164
  129. package/dist/decode/motelySprite.js +0 -84
  130. package/dist/hooks/analyzerStreamRegistry.js +0 -96
  131. package/dist/hooks/searchWorker.d.ts +0 -1
  132. package/dist/hooks/searchWorker.js +0 -119
  133. package/dist/hooks/searchWorkerCode.d.ts +0 -1
  134. package/dist/hooks/searchWorkerCode.js +0 -85
  135. package/dist/hooks/useAnalyzer.js +0 -91
  136. package/dist/hooks/useIntersectionObserver.js +0 -52
  137. package/dist/hooks/useSearch.js +0 -161
  138. package/dist/hooks/useShopStream.js +0 -85
  139. package/dist/lib/SpriteMapper.js +0 -48
  140. package/dist/lib/cardParser.js +0 -67
  141. package/dist/lib/classes/BuyMetaData.js +0 -1
  142. package/dist/lib/config.js +0 -15
  143. package/dist/lib/const.js +0 -521
  144. package/dist/lib/data/constants.js +0 -14
  145. package/dist/lib/hooks/useDragScroll.js +0 -48
  146. package/dist/lib/hooks/useJamlFilter.js +0 -219
  147. package/dist/lib/hooks/useSeedAnalyzer.js +0 -50
  148. package/dist/lib/jaml/jamlCompletion.js +0 -13
  149. package/dist/lib/jaml/jamlData.js +0 -6
  150. package/dist/lib/jaml/jamlObjectives.js +0 -97
  151. package/dist/lib/jaml/jamlParser.js +0 -47
  152. package/dist/lib/jaml/jamlPresets.js +0 -61
  153. package/dist/lib/jaml/jamlSchema.js +0 -91
  154. package/dist/lib/parseDailyRitual.js +0 -70
  155. package/dist/lib/tts/getRevealPos.js +0 -16
  156. package/dist/lib/tts/splitTtsDisplay.js +0 -35
  157. package/dist/lib/types.js +0 -1
  158. package/dist/lib/utils.js +0 -5
  159. package/dist/motelyDisplay.js +0 -59
  160. package/dist/r3f/Card3D.js +0 -72
  161. package/dist/r3f/JimboBillboard.js +0 -32
  162. package/dist/r3f/JimboText3D.js +0 -8
  163. package/dist/render/CanvasRenderer.js +0 -11
  164. package/dist/render/Layer.js +0 -18
  165. package/dist/sprites/spriteData.js +0 -100
  166. package/dist/sprites/spriteMapper.js +0 -75
  167. package/dist/stories/Button.d.ts +0 -15
  168. package/dist/stories/Button.js +0 -7
  169. package/dist/stories/Button.stories.d.ts +0 -24
  170. package/dist/stories/Button.stories.js +0 -50
  171. package/dist/stories/Header.d.ts +0 -12
  172. package/dist/stories/Header.js +0 -4
  173. package/dist/stories/Header.stories.d.ts +0 -18
  174. package/dist/stories/Header.stories.js +0 -26
  175. package/dist/stories/Page.d.ts +0 -3
  176. package/dist/stories/Page.js +0 -8
  177. package/dist/stories/Page.stories.d.ts +0 -12
  178. package/dist/stories/Page.stories.js +0 -24
  179. package/dist/ui/Jimbo.stories.d.ts +0 -7
  180. package/dist/ui/Jimbo.stories.js +0 -28
  181. package/dist/ui/JimboBadge.js +0 -8
  182. package/dist/ui/JimboFloating.js +0 -17
  183. package/dist/ui/JimboIconButton.js +0 -28
  184. package/dist/ui/JimboInputModal.js +0 -66
  185. package/dist/ui/JimboSelect.js +0 -43
  186. package/dist/ui/JimboToggleList.js +0 -5
  187. package/dist/ui/PanelSplitter.js +0 -78
  188. package/dist/ui/codeBlock.js +0 -14
  189. package/dist/ui/footer.js +0 -20
  190. package/dist/ui/hooks.js +0 -634
  191. package/dist/ui/ide/AgnosticSeedCard.d.ts +0 -19
  192. package/dist/ui/ide/AgnosticSeedCard.js +0 -48
  193. package/dist/ui/ide/DeckSprite.js +0 -2
  194. package/dist/ui/ide/JamlBuilder.d.ts +0 -1
  195. package/dist/ui/ide/JamlBuilder.js +0 -112
  196. package/dist/ui/ide/JamlEditor.js +0 -486
  197. package/dist/ui/ide/JamlEditorMonaco.d.ts +0 -8
  198. package/dist/ui/ide/JamlEditorMonaco.js +0 -78
  199. package/dist/ui/ide/WasmStatus.d.ts +0 -1
  200. package/dist/ui/ide/WasmStatus.js +0 -42
  201. package/dist/ui/jimboApp.js +0 -15
  202. package/dist/ui/jimboBackground.js +0 -27
  203. package/dist/ui/jimboCopyRow.js +0 -18
  204. package/dist/ui/jimboFilterBar.js +0 -16
  205. package/dist/ui/jimboFlankNav.js +0 -18
  206. package/dist/ui/jimboInfoCard.js +0 -26
  207. package/dist/ui/jimboInset.js +0 -9
  208. package/dist/ui/jimboSectionHeader.js +0 -9
  209. package/dist/ui/jimboStatGrid.js +0 -9
  210. package/dist/ui/jimboTabs.js +0 -22
  211. package/dist/ui/jimboText.js +0 -33
  212. package/dist/ui/jimboTooltip.js +0 -39
  213. package/dist/ui/jimboWordmark.js +0 -9
  214. package/dist/ui/mascot/JammySpeechBox.js +0 -30
  215. package/dist/ui/mascot/SeedMascot.js +0 -17
  216. package/dist/ui/mascot/index.js +0 -3
  217. package/dist/ui/mascot/menuConfig.js +0 -12
  218. package/dist/ui/panel.js +0 -24
  219. package/dist/ui/radial/RadialBadge.js +0 -43
  220. package/dist/ui/radial/RadialBreadcrumb.js +0 -18
  221. package/dist/ui/radial/RadialButton.js +0 -102
  222. package/dist/ui/radial/RadialMenu.js +0 -168
  223. package/dist/ui/radial/RadialPill.js +0 -15
  224. package/dist/ui/radial/index.js +0 -18
  225. package/dist/ui/radial/radialMenuStore.js +0 -122
  226. package/dist/ui/radial/radialMenuViewport.js +0 -59
  227. package/dist/ui/radial/useRadialMenu.js +0 -107
  228. package/dist/ui/showcase.js +0 -20
  229. package/dist/ui/sprites.js +0 -77
  230. package/dist/ui/tokens.js +0 -64
  231. package/dist/utils/gameCardUtils.js +0 -15
  232. package/dist/utils/jamlMapPreview.js +0 -106
  233. package/dist/utils/jamlVisualFilter.js +0 -210
@@ -1,219 +0,0 @@
1
- import { useState, useCallback, useMemo } from 'react';
2
- import { DECK_OPTIONS, STAKE_OPTIONS, ANTE_OPTIONS, SLOT_OPTIONS, CLAUSE_TYPES, SOURCE_OPTIONS, EDITION_OPTIONS, SEAL_OPTIONS, ENHANCEMENT_OPTIONS } from '../data/constants.js';
3
- export { DECK_OPTIONS, STAKE_OPTIONS, ANTE_OPTIONS, SLOT_OPTIONS, CLAUSE_TYPES, SOURCE_OPTIONS, EDITION_OPTIONS, SEAL_OPTIONS, ENHANCEMENT_OPTIONS };
4
- export function useJamlFilter(initialJaml) {
5
- const [filter, setFilter] = useState(parseJamlToFilter(initialJaml || ''));
6
- const [editingClause, setEditingClause] = useState(null);
7
- // useEffect removed to restore previous UX behavior
8
- // The JAML from server (Rules format) parses to empty clauses,
9
- // causing the UI to lose state after load. we want to keep the initial state.
10
- const jamlText = useMemo(() => filterToJaml(filter), [filter]);
11
- const updateFilter = useCallback((updates) => {
12
- setFilter(prev => ({ ...prev, ...updates }));
13
- }, []);
14
- const addClause = useCallback((bucket, clause) => {
15
- setFilter(prev => ({
16
- ...prev,
17
- [bucket]: [...prev[bucket], clause]
18
- }));
19
- }, []);
20
- const editClause = useCallback((bucket, index, clause) => {
21
- setFilter(prev => ({
22
- ...prev,
23
- [bucket]: prev[bucket].map((c, i) => i === index ? clause : c)
24
- }));
25
- }, []);
26
- const deleteClause = useCallback((bucket, index) => {
27
- setFilter(prev => ({
28
- ...prev,
29
- [bucket]: prev[bucket].filter((_, i) => i !== index)
30
- }));
31
- }, []);
32
- const setFromJaml = useCallback((text) => {
33
- const newFilter = parseJamlToFilter(text);
34
- setFilter(newFilter);
35
- }, []);
36
- return {
37
- filter,
38
- jamlText,
39
- setFromJaml,
40
- updateFilter,
41
- addClause,
42
- editClause,
43
- deleteClause,
44
- editingClause,
45
- setEditingClause
46
- };
47
- }
48
- function parseJamlToFilter(text) {
49
- if (!text.trim())
50
- return createBlankFilter();
51
- try {
52
- const filter = createBlankFilter();
53
- // Reset arrays to empty since we are parsing fresh
54
- filter.must = [];
55
- filter.should = [];
56
- filter.mustNot = [];
57
- const lines = text.split('\n');
58
- let currentSection = null;
59
- let currentClause = null;
60
- for (const line of lines) {
61
- const trimmed = line.trim();
62
- if (!trimmed || trimmed.startsWith('#'))
63
- continue;
64
- // 1. Detect Section Headers
65
- if (trimmed === 'must:') {
66
- currentSection = 'must';
67
- currentClause = null;
68
- continue;
69
- }
70
- if (trimmed === 'should:') {
71
- currentSection = 'should';
72
- currentClause = null;
73
- continue;
74
- }
75
- if (trimmed === 'mustNot:') {
76
- currentSection = 'mustNot';
77
- currentClause = null;
78
- continue;
79
- }
80
- if (trimmed === 'defaults:') {
81
- currentSection = 'defaults';
82
- continue;
83
- }
84
- // 2. Detect Root Properties (indent 0)
85
- const rootMatch = line.match(/^(\w+):\s*(.+)$/);
86
- if (rootMatch && !line.startsWith(' ') && !line.startsWith('-')) {
87
- const [, key, val] = rootMatch;
88
- if (['name', 'deck', 'stake', 'description', 'author'].includes(key)) {
89
- filter[key] = val.trim();
90
- }
91
- continue;
92
- }
93
- // 3. Handle Sections
94
- if (currentSection) {
95
- if (currentSection === 'defaults') {
96
- const propMatch = trimmed.match(/^(\w+):\s*(.+)$/);
97
- if (propMatch) {
98
- const [, key, val] = propMatch;
99
- if (key === 'antes')
100
- filter.defaults.antes = parseNumArray(val);
101
- if (key === 'packSlots')
102
- filter.defaults.packSlots = parseNumArray(val);
103
- if (key === 'shopSlots')
104
- filter.defaults.shopSlots = parseNumArray(val);
105
- if (key === 'score')
106
- filter.defaults.score = parseInt(val) || 0;
107
- }
108
- }
109
- else {
110
- // Start of new clause
111
- const typeMatch = trimmed.match(/^-\s*type:\s*(.+)$/);
112
- if (typeMatch) {
113
- currentClause = { type: typeMatch[1].trim(), value: '' };
114
- filter[currentSection].push(currentClause);
115
- continue;
116
- }
117
- // Properties of current clause
118
- if (currentClause) {
119
- const propMatch = trimmed.match(/^(\w+):\s*(.+)$/);
120
- if (propMatch) {
121
- const [, key, val] = propMatch;
122
- if (key === 'antes')
123
- currentClause.antes = parseNumArray(val);
124
- else if (key === 'sources')
125
- currentClause.sources = parseStringArray(val);
126
- else if (key === 'score')
127
- currentClause.score = parseInt(val) || 0;
128
- else
129
- currentClause[key] = val.trim();
130
- }
131
- }
132
- }
133
- }
134
- }
135
- return filter;
136
- }
137
- catch (e) {
138
- console.warn('JAML Parse Error:', e);
139
- return createBlankFilter();
140
- }
141
- }
142
- function parseNumArray(str) {
143
- return str.replace(/[[\]]/g, '').split(',').map(s => parseInt(s.trim())).filter(n => !isNaN(n));
144
- }
145
- function parseStringArray(str) {
146
- return str.replace(/[[\]]/g, '').split(',').map(s => s.trim()).filter(s => !!s);
147
- }
148
- function filterToJaml(filter) {
149
- const lines = [];
150
- lines.push(`name: ${filter.name}`);
151
- lines.push(`description: ${filter.description || ''}`);
152
- lines.push(`author: ${filter.author || ''}`);
153
- lines.push(`deck: ${filter.deck}`);
154
- lines.push(`stake: ${filter.stake}`);
155
- lines.push('');
156
- lines.push('defaults:');
157
- lines.push(` antes: [${filter.defaults.antes.join(', ')}]`);
158
- lines.push(` packSlots: [${filter.defaults.packSlots.join(', ')}]`);
159
- lines.push(` shopSlots: [${filter.defaults.shopSlots.join(', ')}]`);
160
- lines.push(` score: ${filter.defaults.score}`);
161
- lines.push('');
162
- if (filter.must.length > 0) {
163
- lines.push('must:');
164
- filter.must.forEach(clause => lines.push(...clauseToLines(clause, ' ')));
165
- }
166
- if (filter.should.length > 0) {
167
- lines.push('should:');
168
- filter.should.forEach(clause => lines.push(...clauseToLines(clause, ' ')));
169
- }
170
- if (filter.mustNot.length > 0) {
171
- lines.push('mustNot:');
172
- filter.mustNot.forEach(clause => lines.push(...clauseToLines(clause, ' ')));
173
- }
174
- return lines.join('\n');
175
- }
176
- function clauseToLines(clause, indent) {
177
- const lines = [];
178
- lines.push(`${indent}- type: ${clause.type}`);
179
- lines.push(`${indent} value: ${clause.value}`);
180
- if (clause.label)
181
- lines.push(`${indent} label: ${clause.label}`);
182
- if (clause.antes && clause.antes.length > 0)
183
- lines.push(`${indent} antes: [${clause.antes.join(', ')}]`);
184
- if (clause.score)
185
- lines.push(`${indent} score: ${clause.score}`);
186
- if (clause.edition)
187
- lines.push(`${indent} edition: ${clause.edition}`);
188
- if (clause.seal)
189
- lines.push(`${indent} seal: ${clause.seal}`);
190
- if (clause.enhancement)
191
- lines.push(`${indent} enhancement: ${clause.enhancement}`);
192
- if (clause.rank)
193
- lines.push(`${indent} rank: ${clause.rank}`);
194
- if (clause.suit)
195
- lines.push(`${indent} suit: ${clause.suit}`);
196
- if (clause.sources && clause.sources.length > 0)
197
- lines.push(`${indent} sources: [${clause.sources.join(', ')}]`);
198
- return lines;
199
- }
200
- function createBlankFilter() {
201
- return {
202
- name: 'New Filter',
203
- description: '',
204
- author: '',
205
- deck: 'Erratic',
206
- stake: 'White',
207
- defaults: {
208
- antes: [...ANTE_OPTIONS],
209
- packSlots: [...SLOT_OPTIONS],
210
- shopSlots: [...SLOT_OPTIONS],
211
- score: 1
212
- },
213
- must: [],
214
- should: [
215
- { type: 'joker', value: 'Joker' }
216
- ],
217
- mustNot: []
218
- };
219
- }
@@ -1,50 +0,0 @@
1
- "use client";
2
- import { useState, useEffect } from "react";
3
- export function useSeedAnalyzer(motely, seed) {
4
- const [data, setData] = useState(null);
5
- const [loading, setLoading] = useState(false);
6
- const [error, setError] = useState(null);
7
- const [prevInputs, setPrevInputs] = useState({ seed, motely });
8
- if (seed !== prevInputs.seed || motely !== prevInputs.motely) {
9
- setPrevInputs({ seed, motely });
10
- if (!seed || seed === "LOCKED" || !motely) {
11
- setData(null);
12
- }
13
- }
14
- useEffect(() => {
15
- if (!seed || seed === "LOCKED" || !motely) {
16
- return;
17
- }
18
- const abortController = new AbortController();
19
- const runAnalysis = async () => {
20
- setLoading(true);
21
- setError(null);
22
- try {
23
- const jaml = `version: 1\nconfig:\n deck: Erratic\n stake: White\n`;
24
- const rawResult = motely.MotelyWasm.analyzeJamlSeeds(jaml, [seed]);
25
- if (abortController.signal.aborted)
26
- return;
27
- if (rawResult && rawResult.seeds.length > 0) {
28
- const result = rawResult.seeds[0];
29
- setData(result.analysis || null);
30
- }
31
- else {
32
- throw new Error("No analysis result returned");
33
- }
34
- }
35
- catch (err) {
36
- if (abortController.signal.aborted)
37
- return;
38
- console.error("[useSeedAnalyzer] Analysis error:", err);
39
- setError(err instanceof Error ? err.message : String(err));
40
- }
41
- finally {
42
- if (!abortController.signal.aborted)
43
- setLoading(false);
44
- }
45
- };
46
- runAnalysis();
47
- return () => abortController.abort();
48
- }, [motely, seed]);
49
- return { data, loading, error };
50
- }
@@ -1,13 +0,0 @@
1
- import { JAML_KEYWORDS } from './jamlData';
2
- export class JamlCompletionService {
3
- static getCompletions(currentValue) {
4
- const lower = currentValue.toLowerCase();
5
- return JAML_KEYWORDS
6
- .filter(k => k.toLowerCase().includes(lower))
7
- .map(k => ({
8
- text: k,
9
- displayText: k,
10
- type: 'keyword'
11
- }));
12
- }
13
- }
@@ -1,6 +0,0 @@
1
- import { CLAUSE_TYPE_KEYS } from './jamlSchema.js';
2
- export const CLAUSE_TYPES = [...CLAUSE_TYPE_KEYS];
3
- export const ARRAY_KEYS = ['antes', 'tags', 'labels'];
4
- export const JAML_KEYWORDS = [
5
- 'must', 'should', 'mustNot', 'any', 'Any', ...CLAUSE_TYPES, ...ARRAY_KEYS
6
- ];
@@ -1,97 +0,0 @@
1
- /**
2
- * JAML Objectives Parser
3
- *
4
- * Extracts display-ready objective names from a JAML config string
5
- * using the existing useJamlFilter parser — no hand-rolled regex.
6
- *
7
- * This is the ONLY place JAML → objective extraction should happen.
8
- */
9
- /**
10
- * Parse a JAML config string and extract objectives (must-clause values).
11
- * Returns an array of human-readable objective names.
12
- */
13
- export function parseJamlToObjectives(jamlConfig) {
14
- if (!jamlConfig.trim())
15
- return [];
16
- const objectives = [];
17
- const lines = jamlConfig.split('\n');
18
- let inMustBlock = false;
19
- let currentClause = null;
20
- for (const line of lines) {
21
- const trimmed = line.trim();
22
- if (!trimmed || trimmed.startsWith('#'))
23
- continue;
24
- // Section headers
25
- if (trimmed === 'must:') {
26
- inMustBlock = true;
27
- currentClause = null;
28
- continue;
29
- }
30
- if (trimmed === 'should:' || trimmed === 'mustNot:' || trimmed === 'defaults:') {
31
- // Flush current clause before leaving must block
32
- if (inMustBlock && currentClause) {
33
- const name = currentClause.label || currentClause.value;
34
- if (name)
35
- objectives.push(name);
36
- }
37
- inMustBlock = false;
38
- currentClause = null;
39
- continue;
40
- }
41
- if (!inMustBlock)
42
- continue;
43
- // New clause (starts with -)
44
- if (trimmed.startsWith('-')) {
45
- // Flush previous clause
46
- if (currentClause) {
47
- const name = currentClause.label || currentClause.value;
48
- if (name)
49
- objectives.push(name);
50
- }
51
- currentClause = {};
52
- // Parse inline key:value on same line as dash
53
- const inlineMatch = trimmed.match(/^-\s*(\w+):\s*(.+)$/);
54
- if (inlineMatch) {
55
- const [, key, val] = inlineMatch;
56
- if (key === 'type')
57
- currentClause.type = val.trim();
58
- else if (key === 'value')
59
- currentClause.value = val.trim();
60
- else if (key === 'label')
61
- currentClause.label = val.trim();
62
- else {
63
- // Shorthand: `- joker: Blueprint` means type=joker, value=Blueprint
64
- currentClause.type = key;
65
- currentClause.value = val.trim();
66
- }
67
- }
68
- continue;
69
- }
70
- // Properties of current clause (indented, no dash)
71
- if (currentClause) {
72
- const propMatch = trimmed.match(/^(\w+):\s*(.+)$/);
73
- if (propMatch) {
74
- const [, key, val] = propMatch;
75
- if (key === 'value')
76
- currentClause.value = val.trim();
77
- else if (key === 'label')
78
- currentClause.label = val.trim();
79
- else if (key === 'type')
80
- currentClause.type = val.trim();
81
- else if (!currentClause.value && key !== 'antes' && key !== 'score' && key !== 'sources' && key !== 'edition' && key !== 'seal' && key !== 'enhancement') {
82
- // Shorthand values like `joker: Blueprint` inside a clause
83
- // Only use as value if we don't already have one
84
- currentClause.type = currentClause.type || key;
85
- currentClause.value = val.trim();
86
- }
87
- }
88
- }
89
- }
90
- // Flush final clause
91
- if (inMustBlock && currentClause) {
92
- const name = currentClause.label || currentClause.value;
93
- if (name)
94
- objectives.push(name);
95
- }
96
- return objectives;
97
- }
@@ -1,47 +0,0 @@
1
- /**
2
- * Simple regex-based JAML parser for extracting highlighting rules.
3
- * Handles basic YAML structure:
4
- * Must:
5
- * - joker: WeeJoker
6
- * Should:
7
- * - joker: HangingChad
8
- */
9
- export function parseJamlHighlights(jamlContent) {
10
- const rules = {
11
- highPriority: new Set(),
12
- mediumPriority: new Set()
13
- };
14
- if (!jamlContent)
15
- return rules;
16
- const lines = jamlContent.split('\n');
17
- let currentSection = null;
18
- for (const line of lines) {
19
- const trimmed = line.trim();
20
- if (trimmed.startsWith('Must:')) {
21
- currentSection = 'Must';
22
- continue;
23
- }
24
- if (trimmed.startsWith('Should:')) {
25
- currentSection = 'Should';
26
- continue;
27
- }
28
- // Look for "- joker: Name" or "- souljoker: Name"
29
- const jokerMatch = trimmed.match(/- (?:joker|souljoker): (.+)/);
30
- if (jokerMatch) {
31
- const name = jokerMatch[1].trim();
32
- // Normalize: "WeeJoker" -> "Wee Joker" if needed?
33
- // Blueprint output usually has spaces "Wee Joker".
34
- // JAML uses "WeeJoker".
35
- // We'll normalize by removing spaces for comparison.
36
- const normalized = name.replace(/\s+/g, '').toLowerCase();
37
- if (currentSection === 'Must')
38
- rules.highPriority.add(normalized);
39
- if (currentSection === 'Should')
40
- rules.mediumPriority.add(normalized);
41
- }
42
- }
43
- return rules;
44
- }
45
- export function normalizeName(name) {
46
- return name.replace(/\s+/g, '').toLowerCase();
47
- }
@@ -1,61 +0,0 @@
1
- export const JAML_PRESETS = [
2
- {
3
- id: 'soul-hunter',
4
- label: 'Soul Hunter',
5
- description: 'Find a Spectral Soul card in early Antes.',
6
- jaml: `# The Soul Hunter
7
- name: Soul Hunter
8
- deck: Red
9
- stake: White
10
-
11
- must:
12
- - spectralCard: The Soul
13
- antes: [1, 2, 3]
14
- `
15
- },
16
- {
17
- id: 'negative-blueprint',
18
- label: 'Negative Blueprint',
19
- description: 'Find a Negative Blueprint early.',
20
- jaml: `# Negative Blueprint
21
- name: Negative Blueprint
22
- deck: Red
23
- stake: White
24
-
25
- must:
26
- - joker: Blueprint
27
- edition: Negative
28
- antes: [1, 2, 3, 4]
29
- `
30
- },
31
- {
32
- id: 'mega-tags',
33
- label: 'Mega Tags',
34
- description: 'Find a lot of Investment and Double Tags.',
35
- jaml: `# Mega Tags
36
- name: Mega Tags
37
- deck: Red
38
- stake: White
39
-
40
- must:
41
- - tag: Double Tag
42
- antes: [1, 2]
43
- - tag: Investment Tag
44
- antes: [1, 2]
45
- `
46
- },
47
- {
48
- id: 'black-hole',
49
- label: 'Black Hole',
50
- description: 'Find the elusive Black Hole spectral card.',
51
- jaml: `# Black Hole
52
- name: Black Hole
53
- deck: Red
54
- stake: White
55
-
56
- must:
57
- - spectralCard: Black Hole
58
- antes: [1, 2, 3, 4]
59
- `
60
- }
61
- ];
@@ -1,91 +0,0 @@
1
- /**
2
- * JAML Schema Bridge
3
- *
4
- * Derives all JAML schema constants from motely-wasm/jaml.schema.json.
5
- * All JAML-aware files import from here — single swap point if the API changes.
6
- */
7
- import jamlSchemaJson from '../../../jaml.schema.json';
8
- const schema = jamlSchemaJson;
9
- const clauseDef = schema.definitions?.clause?.properties ?? {};
10
- export const JAML_SCHEMA_VERSION = schema.version ?? 'unknown';
11
- /** The raw JSON schema object. */
12
- export const jamlSchema = schema;
13
- // ── Key groups ─────────────────────────────────────────────────────────────
14
- /** Root-level metadata keys (name, author, deck, etc.) */
15
- export const METADATA_KEYS = [
16
- 'id', 'name', 'description', 'author', 'dateCreated',
17
- 'deck', 'stake', 'seeds', 'hashtags', 'aesthetics', 'defaults',
18
- ];
19
- /** Section keys that contain clause arrays. */
20
- export const SECTION_KEYS = ['must', 'should', 'mustNot'];
21
- /** Clause type keys — the primary discriminators (joker, voucher, tarot, etc.). */
22
- export const CLAUSE_TYPE_KEYS = (clauseDef.type?.enum ?? []);
23
- /** Property keys available inside a clause. */
24
- export const PROPERTY_KEYS = Object.keys(clauseDef);
25
- /** Source-configuration keys (shopItems, boosterPacks, etc.). */
26
- export const SOURCE_KEYS = (() => {
27
- const srcProps = clauseDef.sources?.properties;
28
- return srcProps ? Object.keys(srcProps) : ['shopItems', 'boosterPacks'];
29
- })();
30
- // ── Value lookups ──────────────────────────────────────────────────────────
31
- /**
32
- * Get the valid enum values for a given JAML key.
33
- * Checks top-level properties first, then falls back to clause properties.
34
- */
35
- export function getValidValuesForKey(key) {
36
- // Top-level enum (deck, stake)
37
- const topProp = schema.properties?.[key];
38
- if (topProp?.enum)
39
- return topProp.enum;
40
- if (topProp?.items?.enum)
41
- return topProp.items.enum;
42
- // Clause-level enum
43
- const clauseProp = clauseDef[key];
44
- if (clauseProp?.enum)
45
- return clauseProp.enum;
46
- if (clauseProp?.items?.enum)
47
- return clauseProp.items.enum;
48
- return null;
49
- }
50
- /**
51
- * Get the available properties for a given clause type.
52
- * Returns all clause property keys (the type system doesn't restrict per-type in JSON schema v7).
53
- */
54
- export function getAvailablePropsForType( /* _clauseType */) {
55
- return PROPERTY_KEYS;
56
- }
57
- /**
58
- * Check if a property is invalid for a clause type.
59
- * In the v7 schema, all properties are available on all clause types.
60
- */
61
- export function isInvalidPropForType( /* _prop, _clauseType */) {
62
- return false;
63
- }
64
- /**
65
- * Check if a value is invalid for a property.
66
- */
67
- export function isInvalidValueForProp(value, prop) {
68
- const valid = getValidValuesForKey(prop);
69
- if (!valid)
70
- return false; // No enum constraint — anything goes
71
- return !valid.includes(value);
72
- }
73
- // ── Convenience lookups ────────────────────────────────────────────────────
74
- export const DECK_VALUES = (getValidValuesForKey('deck') ?? []);
75
- export const STAKE_VALUES = (getValidValuesForKey('stake') ?? []);
76
- export const EDITION_VALUES = (getValidValuesForKey('edition') ?? []);
77
- export const SEAL_VALUES = (getValidValuesForKey('seal') ?? []);
78
- export const ENHANCEMENT_VALUES = (getValidValuesForKey('enhancement') ?? []);
79
- export const RANK_VALUES = (getValidValuesForKey('rank') ?? []);
80
- export const SUIT_VALUES = (getValidValuesForKey('suit') ?? []);
81
- export const STICKER_VALUES = (getValidValuesForKey('stickers') ?? []);
82
- /**
83
- * All JAML keywords — sections, metadata keys, clause types, and property keys.
84
- */
85
- export const ALL_JAML_KEYWORDS = [
86
- ...SECTION_KEYS,
87
- ...METADATA_KEYS,
88
- ...CLAUSE_TYPE_KEYS,
89
- ...PROPERTY_KEYS,
90
- ...SOURCE_KEYS,
91
- ];
@@ -1,70 +0,0 @@
1
- /**
2
- * Parser for daily_ritual.json abbreviated format
3
- *
4
- * Expands abbreviated fields like "wj2", "hc1" into full item objects
5
- */
6
- // Mapping of abbreviations to full item data
7
- const ITEM_MAP = {
8
- wj: { id: 'weejoker', name: 'Wee Joker', type: 'joker' },
9
- hc: { id: 'hangingchad', name: 'Hanging Chad', type: 'joker' },
10
- hk: { id: 'hack', name: 'Hack', type: 'joker' },
11
- bp: { id: 'blueprint', name: 'Blueprint', type: 'joker' },
12
- bs: { id: 'brainstorm', name: 'Brainstorm', type: 'joker' },
13
- sh: { id: 'showman', name: 'Showman', type: 'joker' },
14
- cp: { id: 'copy', name: 'Copy', type: 'consumable' }, // Placeholder
15
- // Add more as needed
16
- };
17
- /**
18
- * Parse daily_ritual.json seed format
19
- *
20
- * Example input:
21
- * {"id":"J4SPZMWW","t":"Twosday","j":"Joker","s":206,"w":16,"wj2":1,"hc2":1}
22
- *
23
- * Output:
24
- * {
25
- * seed: "J4SPZMWW",
26
- * title: "Twosday",
27
- * score: 206,
28
- * twos: 16,
29
- * items: [
30
- * { id: 'weejoker', name: 'Wee Joker', type: 'joker', ante: 2 },
31
- * { id: 'hangingchad', name: 'Hanging Chad', type: 'joker', ante: 2 }
32
- * ]
33
- * }
34
- */
35
- export function parseDailyRitualSeed(raw) {
36
- const items = [];
37
- // Parse each field looking for pattern: letters + number (e.g., "wj2", "hc1")
38
- Object.keys(raw).forEach(key => {
39
- if (key === 'id' || key === 't' || key === 's' || key === 'w')
40
- return;
41
- const match = key.match(/^([a-z]+)(\d+)$/);
42
- if (match) {
43
- const [, code, ante] = match;
44
- const itemData = ITEM_MAP[code];
45
- if (itemData) {
46
- items.push({
47
- ...itemData,
48
- ante: Number(ante)
49
- });
50
- }
51
- }
52
- });
53
- return {
54
- seed: raw.id || '',
55
- title: raw.t || '',
56
- score: raw.s || 0,
57
- twos: raw.w || 0,
58
- items
59
- };
60
- }
61
- /**
62
- * Group items by type for rendering
63
- */
64
- export function groupItemsByType(items) {
65
- return {
66
- jokers: items.filter(i => i.type === 'joker'),
67
- consumables: items.filter(i => i.type === 'consumable'),
68
- vouchers: items.filter(i => i.type === 'voucher')
69
- };
70
- }
@@ -1,16 +0,0 @@
1
- /**
2
- * Advance past trailing punctuation and whitespace so reveal snaps to word boundaries.
3
- * Used by both JammySpeechBox (home announcement) and ChatInterface (streaming chat).
4
- */
5
- export function getRevealPos(text, highlightPos) {
6
- if (highlightPos <= 0)
7
- return 0;
8
- if (highlightPos >= text.length)
9
- return text.length;
10
- let i = highlightPos;
11
- while (i < text.length && /[)\]}'"'\u2018\u2019.,!?;:]/.test(text[i]))
12
- i++;
13
- while (i < text.length && /\s/.test(text[i]))
14
- i++;
15
- return i;
16
- }