jaml-ui 0.24.20 → 0.25.1

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 -1
  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 +2 -2
  42. package/dist/hooks/useSearch.d.ts +2 -2
  43. package/dist/index.d.ts +29 -31
  44. package/dist/index.js +16725 -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,106 +0,0 @@
1
- const CLAUSE_VISUAL_TYPES = {
2
- joker: "joker",
3
- jokers: "joker",
4
- commonJoker: "joker",
5
- commonJokers: "joker",
6
- uncommonJoker: "joker",
7
- uncommonJokers: "joker",
8
- rareJoker: "joker",
9
- rareJokers: "joker",
10
- mixedJoker: "joker",
11
- mixedJokers: "joker",
12
- soulJoker: "joker",
13
- legendaryJoker: "joker",
14
- voucher: "voucher",
15
- vouchers: "voucher",
16
- tarot: "consumable",
17
- tarotCard: "consumable",
18
- spectral: "consumable",
19
- spectralCard: "consumable",
20
- planet: "consumable",
21
- planetCard: "consumable",
22
- boss: "boss",
23
- bosses: "boss",
24
- tag: "tag",
25
- tags: "tag",
26
- smallBlindTag: "tag",
27
- bigBlindTag: "tag",
28
- };
29
- function createEmptyGroups() {
30
- return { must: [], should: [], mustNot: [] };
31
- }
32
- function stripWrappingQuotes(value) {
33
- if ((value.startsWith('"') && value.endsWith('"')) ||
34
- (value.startsWith("'") && value.endsWith("'"))) {
35
- return value.slice(1, -1).trim();
36
- }
37
- return value;
38
- }
39
- function normalizeCandidateValue(value) {
40
- const normalized = stripWrappingQuotes(value.trim()).replace(/,$/, "").trim();
41
- if (!normalized)
42
- return null;
43
- if (normalized === "Any")
44
- return null;
45
- return normalized;
46
- }
47
- function parseInlineValues(raw) {
48
- const trimmed = raw.trim();
49
- if (!trimmed)
50
- return [];
51
- if (trimmed.startsWith("[") && trimmed.includes("]")) {
52
- const body = trimmed.slice(1, trimmed.indexOf("]"));
53
- return body
54
- .split(",")
55
- .map((value) => normalizeCandidateValue(value))
56
- .filter((value) => Boolean(value));
57
- }
58
- const normalized = normalizeCandidateValue(trimmed);
59
- return normalized ? [normalized] : [];
60
- }
61
- export function extractVisualJamlItems(jaml) {
62
- const groups = createEmptyGroups();
63
- const seen = new Set();
64
- const safeJaml = jaml || "";
65
- const lines = safeJaml.replace(/\r\n/g, "\n").split("\n");
66
- let currentSection = null;
67
- for (const rawLine of lines) {
68
- const trimmed = rawLine.trim();
69
- if (!trimmed || trimmed.startsWith("#"))
70
- continue;
71
- const sectionMatch = /^(must|should|mustNot):\s*$/.exec(trimmed);
72
- if (sectionMatch) {
73
- currentSection = sectionMatch[1];
74
- continue;
75
- }
76
- const indent = rawLine.search(/\S|$/);
77
- if (indent === 0 && /^[A-Za-z][A-Za-z0-9]*:\s*/.test(trimmed)) {
78
- currentSection = null;
79
- }
80
- if (!currentSection)
81
- continue;
82
- const clauseMatch = /^-?\s*([A-Za-z][A-Za-z0-9]*):\s*(.*?)\s*$/.exec(trimmed);
83
- if (!clauseMatch)
84
- continue;
85
- const clauseKey = clauseMatch[1];
86
- const visualType = CLAUSE_VISUAL_TYPES[clauseKey];
87
- if (!visualType)
88
- continue;
89
- const values = parseInlineValues(clauseMatch[2]);
90
- for (const value of values) {
91
- const dedupeKey = `${currentSection}:${visualType}:${value.toLowerCase()}`;
92
- if (seen.has(dedupeKey))
93
- continue;
94
- seen.add(dedupeKey);
95
- groups[currentSection].push({
96
- id: dedupeKey,
97
- section: currentSection,
98
- clauseKey,
99
- visualType,
100
- value,
101
- source: rawLine,
102
- });
103
- }
104
- }
105
- return groups;
106
- }
@@ -1,210 +0,0 @@
1
- /**
2
- * Utilities for converting between JAML text and JamlVisualFilter.
3
- *
4
- * Intentionally does NOT depend on a YAML library — uses the same
5
- * line-by-line approach as jamlMapPreview.ts to stay zero-dep.
6
- */
7
- // ─── Text → Filter ────────────────────────────────────────────────────────────
8
- function stripQuotes(s) {
9
- if ((s.startsWith('"') && s.endsWith('"')) || (s.startsWith("'") && s.endsWith("'"))) {
10
- return s.slice(1, -1).trim();
11
- }
12
- return s;
13
- }
14
- function parseScalarValue(raw) {
15
- const v = stripQuotes(raw.trim().replace(/,$/, "").trim());
16
- return v || null;
17
- }
18
- function parseInlineList(raw) {
19
- const t = raw.trim();
20
- if (t.startsWith("[") && t.includes("]")) {
21
- const body = t.slice(1, t.indexOf("]"));
22
- return body
23
- .split(",")
24
- .map((s) => parseScalarValue(s))
25
- .filter((s) => s !== null);
26
- }
27
- const v = parseScalarValue(t);
28
- return v ? [v] : [];
29
- }
30
- function topLevelScalar(lines, key) {
31
- for (const line of lines) {
32
- const m = new RegExp(`^${key}:\\s*(.+)$`).exec(line.trim());
33
- if (m)
34
- return stripQuotes(m[1].trim());
35
- }
36
- return undefined;
37
- }
38
- const CLAUSE_ZONE_KEYS = new Set([
39
- "joker", "jokers", "commonJoker", "commonJokers", "uncommonJoker", "uncommonJokers",
40
- "rareJoker", "rareJokers", "mixedJoker", "mixedJokers", "soulJoker", "legendaryJoker",
41
- "voucher", "vouchers",
42
- "tarot", "tarotCard", "spectral", "spectralCard", "planet", "planetCard",
43
- "boss", "bosses",
44
- "tag", "tags", "smallBlindTag", "bigBlindTag", "smallblindtag", "bigblindtag",
45
- ]);
46
- // JAML uses "mustnot" as zone key in some contexts; the visual filter uses "mustnot".
47
- // The text format may use "mustnot" or "must_not" — handle both, normalise to "mustnot".
48
- function sectionToZone(raw) {
49
- if (raw === "must")
50
- return "must";
51
- if (raw === "should")
52
- return "should";
53
- if (raw === "mustnot" || raw === "must_not" || raw === "mustNot")
54
- return "mustnot";
55
- return null;
56
- }
57
- let _uid = 0;
58
- function uid() {
59
- return `clause-${++_uid}`;
60
- }
61
- export function jamlTextToVisualFilter(text) {
62
- const safeText = text || "";
63
- const lines = safeText.replace(/\r\n/g, "\n").split("\n");
64
- const filter = { must: [], should: [], mustnot: [] };
65
- filter.name = topLevelScalar(lines, "name");
66
- filter.author = topLevelScalar(lines, "author");
67
- filter.description = topLevelScalar(lines, "description");
68
- filter.deck = topLevelScalar(lines, "deck");
69
- filter.stake = topLevelScalar(lines, "stake");
70
- let zone = null;
71
- let current = null;
72
- const seen = new Set();
73
- function flushClause() {
74
- if (!current || !zone)
75
- return;
76
- const dedupeKey = `${zone}:${current.type}:${current.value.toLowerCase()}`;
77
- if (!seen.has(dedupeKey)) {
78
- seen.add(dedupeKey);
79
- const clause = { id: uid(), type: current.type, value: current.value };
80
- if (current.antes && current.antes.length > 0)
81
- clause.antes = current.antes;
82
- if (current.boosterPacks && current.boosterPacks.length > 0)
83
- clause.boosterPacks = current.boosterPacks;
84
- if (current.score !== undefined)
85
- clause.score = current.score;
86
- if (current.edition)
87
- clause.edition = current.edition;
88
- clause.label = current.value;
89
- filter[zone].push(clause);
90
- }
91
- current = null;
92
- }
93
- for (const rawLine of lines) {
94
- const trimmed = rawLine.trim();
95
- if (!trimmed || trimmed.startsWith("#"))
96
- continue;
97
- // Top-level section header: must:/should:/mustnot:
98
- const sectionMatch = /^(must|should|mustnot|must_not|mustNot):\s*$/.exec(trimmed);
99
- if (sectionMatch) {
100
- flushClause();
101
- zone = sectionToZone(sectionMatch[1]);
102
- continue;
103
- }
104
- // Top-level key (non-section) resets zone
105
- const indent = rawLine.search(/\S|$/);
106
- if (indent === 0 && /^[A-Za-z]/.test(trimmed) && !trimmed.startsWith("-")) {
107
- flushClause();
108
- if (!sectionToZone(trimmed.replace(/:.*/, "")))
109
- zone = null;
110
- continue;
111
- }
112
- if (!zone)
113
- continue;
114
- // New clause start: " - rareJoker: Blueprint"
115
- const clauseStart = /^-\s*([A-Za-z][A-Za-z0-9]*):\s*(.*?)\s*$/.exec(trimmed);
116
- if (clauseStart) {
117
- flushClause();
118
- const type = clauseStart[1];
119
- const rawVal = clauseStart[2];
120
- if (!CLAUSE_ZONE_KEYS.has(type))
121
- continue;
122
- const value = parseScalarValue(rawVal) ?? "Any";
123
- current = { type, value };
124
- continue;
125
- }
126
- // Continuation line inside a clause: " antes: [1,2,3]"
127
- if (current && indent > 0 && !trimmed.startsWith("-")) {
128
- const contMatch = /^([A-Za-z_][A-Za-z0-9_]*):\s*(.*?)\s*$/.exec(trimmed);
129
- if (contMatch) {
130
- const key = contMatch[1];
131
- const val = contMatch[2];
132
- if (key === "antes") {
133
- const nums = parseInlineList(val)
134
- .map(Number)
135
- .filter((n) => !isNaN(n));
136
- current.antes = nums;
137
- }
138
- else if (key === "boosterPacks") {
139
- const nums = parseInlineList(val)
140
- .map(Number)
141
- .filter((n) => !isNaN(n));
142
- current.boosterPacks = nums;
143
- }
144
- else if (key === "score") {
145
- const n = Number(val);
146
- if (!isNaN(n))
147
- current.score = n;
148
- }
149
- else if (key === "edition") {
150
- current.edition = parseScalarValue(val) ?? undefined;
151
- }
152
- else if (key === "sources") {
153
- // handled by subsequent nested lines like `boosterPacks: [0, 1]`
154
- }
155
- }
156
- }
157
- }
158
- flushClause();
159
- return filter;
160
- }
161
- // ─── Filter → Text ───────────────────────────────────────────────────────────
162
- function q(s) {
163
- if (!s)
164
- return "";
165
- return /[:#[\]{}|>&*!,'"?]/.test(s) ? `"${s.replace(/"/g, '\\"')}"` : s;
166
- }
167
- function serializeClause(clause) {
168
- let out = ` - ${clause.type}: ${q(clause.value)}\n`;
169
- if (clause.antes && clause.antes.length > 0) {
170
- out += ` antes: [${clause.antes.join(", ")}]\n`;
171
- }
172
- if (clause.boosterPacks && clause.boosterPacks.length > 0) {
173
- out += ` sources:\n`;
174
- out += ` boosterPacks: [${clause.boosterPacks.join(", ")}]\n`;
175
- }
176
- if (clause.score !== undefined) {
177
- out += ` score: ${clause.score}\n`;
178
- }
179
- if (clause.edition) {
180
- out += ` edition: ${q(clause.edition)}\n`;
181
- }
182
- return out;
183
- }
184
- export function visualFilterToJamlText(filter) {
185
- const parts = [];
186
- if (filter.name)
187
- parts.push(`name: ${q(filter.name)}`);
188
- if (filter.author)
189
- parts.push(`author: ${q(filter.author)}`);
190
- if (filter.description)
191
- parts.push(`description: ${q(filter.description)}`);
192
- if (filter.deck)
193
- parts.push(`deck: ${q(filter.deck)}`);
194
- if (filter.stake)
195
- parts.push(`stake: ${q(filter.stake)}`);
196
- const zones = [
197
- { key: "must", label: "must", clauses: filter.must },
198
- { key: "should", label: "should", clauses: filter.should },
199
- { key: "mustnot", label: "mustnot", clauses: filter.mustnot },
200
- ];
201
- for (const { label, clauses } of zones) {
202
- if (clauses.length > 0) {
203
- parts.push(`${label}:`);
204
- for (const c of clauses) {
205
- parts.push(serializeClause(c).trimEnd());
206
- }
207
- }
208
- }
209
- return parts.join("\n") + "\n";
210
- }