@carmaclouds/core 2.3.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 (118) hide show
  1. package/dist/cache/CacheManager.d.ts.map +1 -0
  2. package/dist/cache/CacheManager.js +131 -0
  3. package/dist/cache/CacheManager.js.map +1 -0
  4. package/dist/index.d.ts +18 -0
  5. package/dist/index.d.ts.map +1 -0
  6. package/dist/index.js +22 -0
  7. package/dist/index.js.map +1 -0
  8. package/dist/ir/index.d.ts +11 -0
  9. package/dist/ir/index.d.ts.map +1 -0
  10. package/dist/ir/index.js +9 -0
  11. package/dist/ir/index.js.map +1 -0
  12. package/dist/ir/normalize.d.ts +10 -0
  13. package/dist/ir/normalize.d.ts.map +1 -0
  14. package/dist/ir/normalize.js +207 -0
  15. package/dist/ir/normalize.js.map +1 -0
  16. package/dist/ir/persistence.d.ts +26 -0
  17. package/dist/ir/persistence.d.ts.map +1 -0
  18. package/dist/ir/persistence.js +21 -0
  19. package/dist/ir/persistence.js.map +1 -0
  20. package/dist/ir/sync.d.ts +12 -0
  21. package/dist/ir/sync.d.ts.map +1 -0
  22. package/dist/ir/sync.js +36 -0
  23. package/dist/ir/sync.js.map +1 -0
  24. package/dist/ir/types.d.ts +143 -0
  25. package/dist/ir/types.d.ts.map +1 -0
  26. package/dist/ir/types.js +13 -0
  27. package/dist/ir/types.js.map +1 -0
  28. package/dist/ir/views/dnd5e.d.ts +40 -0
  29. package/dist/ir/views/dnd5e.d.ts.map +1 -0
  30. package/dist/ir/views/dnd5e.js +50 -0
  31. package/dist/ir/views/dnd5e.js.map +1 -0
  32. package/dist/render/character.d.ts +19 -0
  33. package/dist/render/character.d.ts.map +1 -0
  34. package/dist/render/character.js +156 -0
  35. package/dist/render/character.js.map +1 -0
  36. package/dist/render/h.d.ts +27 -0
  37. package/dist/render/h.d.ts.map +1 -0
  38. package/dist/render/h.js +64 -0
  39. package/dist/render/h.js.map +1 -0
  40. package/dist/render/index.d.ts +11 -0
  41. package/dist/render/index.d.ts.map +1 -0
  42. package/dist/render/index.js +8 -0
  43. package/dist/render/index.js.map +1 -0
  44. package/dist/render/mount.d.ts +31 -0
  45. package/dist/render/mount.d.ts.map +1 -0
  46. package/dist/render/mount.js +63 -0
  47. package/dist/render/mount.js.map +1 -0
  48. package/dist/supabase/fields.d.ts.map +1 -0
  49. package/dist/supabase/fields.js +120 -0
  50. package/dist/supabase/fields.js.map +1 -0
  51. package/dist/types/character.d.ts.map +1 -0
  52. package/dist/types/character.js +5 -0
  53. package/dist/types/character.js.map +1 -0
  54. package/package.json +73 -0
  55. package/src/browser.js +51 -0
  56. package/src/cache/CacheManager.ts +174 -0
  57. package/src/common/browser-polyfill.js +319 -0
  58. package/src/common/debug.js +123 -0
  59. package/src/common/html-utils.js +134 -0
  60. package/src/common/theme-manager.js +265 -0
  61. package/src/index.ts +25 -0
  62. package/src/ir/__fixtures__/dnd5e-character.json +75962 -0
  63. package/src/ir/__fixtures__/non-dnd-character.json +14218 -0
  64. package/src/ir/index.ts +10 -0
  65. package/src/ir/normalize.ts +245 -0
  66. package/src/ir/persistence.ts +37 -0
  67. package/src/ir/sync.ts +49 -0
  68. package/src/ir/types.ts +161 -0
  69. package/src/ir/views/dnd5e.ts +94 -0
  70. package/src/lib/indexeddb-cache.js +320 -0
  71. package/src/modules/action-announcements.js +102 -0
  72. package/src/modules/action-display.js +1557 -0
  73. package/src/modules/action-executor.js +860 -0
  74. package/src/modules/action-filters.js +167 -0
  75. package/src/modules/action-options.js +117 -0
  76. package/src/modules/card-creator.js +142 -0
  77. package/src/modules/character-portrait.js +169 -0
  78. package/src/modules/character-trait-popups.js +959 -0
  79. package/src/modules/character-traits.js +814 -0
  80. package/src/modules/class-feature-edge-cases.js +1320 -0
  81. package/src/modules/color-utils.js +69 -0
  82. package/src/modules/combat-maneuver-edge-cases.js +660 -0
  83. package/src/modules/companions-manager.js +178 -0
  84. package/src/modules/concentration-tracker.js +178 -0
  85. package/src/modules/data-manager.js +514 -0
  86. package/src/modules/dice-roller.js +719 -0
  87. package/src/modules/effects-manager.js +743 -0
  88. package/src/modules/feature-modals.js +1264 -0
  89. package/src/modules/formula-resolver.js +444 -0
  90. package/src/modules/gm-mode.js +184 -0
  91. package/src/modules/health-modals.js +399 -0
  92. package/src/modules/hp-management.js +752 -0
  93. package/src/modules/inventory-manager.js +242 -0
  94. package/src/modules/macro-system.js +825 -0
  95. package/src/modules/notification-system.js +92 -0
  96. package/src/modules/racial-feature-edge-cases.js +746 -0
  97. package/src/modules/resource-manager.js +775 -0
  98. package/src/modules/sheet-builder.js +654 -0
  99. package/src/modules/spell-action-modals.js +583 -0
  100. package/src/modules/spell-cards.js +602 -0
  101. package/src/modules/spell-casting.js +723 -0
  102. package/src/modules/spell-display.js +314 -0
  103. package/src/modules/spell-edge-cases.js +509 -0
  104. package/src/modules/spell-macros.js +201 -0
  105. package/src/modules/spell-modals.js +1221 -0
  106. package/src/modules/spell-slots.js +224 -0
  107. package/src/modules/status-bar-bridge.js +101 -0
  108. package/src/modules/ui-utilities.js +284 -0
  109. package/src/modules/warlock-invocations.js +219 -0
  110. package/src/modules/window-management.js +211 -0
  111. package/src/render/character.ts +234 -0
  112. package/src/render/h.ts +74 -0
  113. package/src/render/index.ts +10 -0
  114. package/src/render/mount.ts +94 -0
  115. package/src/supabase/client.js +1383 -0
  116. package/src/supabase/config.js +60 -0
  117. package/src/supabase/fields.ts +129 -0
  118. package/src/types/character.ts +85 -0
@@ -0,0 +1,201 @@
1
+ /**
2
+ * Spell Macros Module
3
+ *
4
+ * Handles custom macro system for spells.
5
+ * - Get/save custom macros from localStorage
6
+ * - Configure custom macro buttons modal
7
+ * - Allows spells to have custom Roll20 macro buttons
8
+ *
9
+ * Loaded as a plain script (no ES6 modules) to export to globalThis.
10
+ */
11
+
12
+ (function() {
13
+ 'use strict';
14
+
15
+ /**
16
+ * Get custom macros for a spell from localStorage
17
+ * @param {string} spellName - Name of the spell
18
+ * @returns {object|null} Custom macros object or null
19
+ */
20
+ function getCustomMacros(spellName) {
21
+ const key = `customMacros_${characterData.name}`;
22
+ const allMacros = JSON.parse(localStorage.getItem(key) || '{}');
23
+ return allMacros[spellName] || null;
24
+ }
25
+
26
+ /**
27
+ * Save custom macros for a spell to localStorage
28
+ * @param {string} spellName - Name of the spell
29
+ * @param {object|null} macros - Custom macros object or null to clear
30
+ */
31
+ function saveCustomMacros(spellName, macros) {
32
+ const key = `customMacros_${characterData.name}`;
33
+ const allMacros = JSON.parse(localStorage.getItem(key) || '{}');
34
+
35
+ if (macros && macros.buttons && macros.buttons.length > 0) {
36
+ allMacros[spellName] = macros;
37
+ } else {
38
+ delete allMacros[spellName]; // Remove if no macros defined
39
+ }
40
+
41
+ localStorage.setItem(key, JSON.stringify(allMacros));
42
+
43
+ const debug = window.debug || console;
44
+ debug.log(`💾 Saved custom macros for "${spellName}":`, macros);
45
+ }
46
+
47
+ /**
48
+ * Show custom macro configuration modal
49
+ * @param {object} spell - Spell object
50
+ * @param {number} spellIndex - Spell index
51
+ */
52
+ function showCustomMacroModal(spell, spellIndex) {
53
+ const overlay = document.createElement('div');
54
+ overlay.style.cssText = 'position: fixed; top: 0; left: 0; right: 0; bottom: 0; background: rgba(0,0,0,0.7); display: flex; align-items: center; justify-content: center; z-index: 10000;';
55
+
56
+ const modal = document.createElement('div');
57
+ modal.style.cssText = 'background: var(--bg-secondary); color: var(--text-primary); padding: 24px; border-radius: 8px; max-width: 600px; width: 90%; max-height: 80vh; overflow-y: auto; box-shadow: 0 4px 20px rgba(0,0,0,0.3);';
58
+
59
+ const existingMacros = getCustomMacros(spell.name);
60
+ const skipNormalButtons = existingMacros?.skipNormalButtons || false;
61
+
62
+ modal.innerHTML = `
63
+ <h2 style="margin: 0 0 16px 0; color: #333;">Custom Macros: ${spell.name}</h2>
64
+ <p style="margin: 0 0 16px 0; color: #666; font-size: 14px;">
65
+ Configure custom macro buttons for this spell. Use this for magic item spells or custom variants that don't work with the default buttons.
66
+ </p>
67
+
68
+ <div style="margin-bottom: 16px;">
69
+ <label style="display: flex; align-items: center; gap: 8px; cursor: pointer;">
70
+ <input type="checkbox" id="skipNormalButtons" ${skipNormalButtons ? 'checked' : ''} style="width: 18px; height: 18px;">
71
+ <span style="font-weight: bold;">Replace default buttons (hide attack/damage buttons)</span>
72
+ </label>
73
+ <p style="margin: 4px 0 0 26px; color: #666; font-size: 13px;">
74
+ Check this to only show your custom macros, hiding the default spell buttons
75
+ </p>
76
+ </div>
77
+
78
+ <div id="macro-buttons-container" style="margin-bottom: 16px;">
79
+ <!-- Macro buttons will be added here -->
80
+ </div>
81
+
82
+ <button id="add-macro-btn" style="padding: 8px 16px; background: #27ae60; color: white; border: none; border-radius: 4px; cursor: pointer; font-weight: bold; margin-bottom: 16px;">
83
+ ➕ Add Macro Button
84
+ </button>
85
+
86
+ <div style="margin-top: 24px; padding-top: 16px; border-top: 2px solid #eee; display: flex; gap: 12px; justify-content: flex-end;">
87
+ <button id="clear-macros-btn" style="padding: 10px 20px; background: #e74c3c; color: white; border: none; border-radius: 6px; cursor: pointer; font-weight: bold;">
88
+ 🗑️ Clear All
89
+ </button>
90
+ <button id="cancel-macros-btn" style="padding: 10px 20px; background: #95a5a6; color: white; border: none; border-radius: 6px; cursor: pointer; font-weight: bold;">
91
+ Cancel
92
+ </button>
93
+ <button id="save-macros-btn" style="padding: 10px 20px; background: #3498db; color: white; border: none; border-radius: 6px; cursor: pointer; font-weight: bold;">
94
+ 💾 Save
95
+ </button>
96
+ </div>
97
+ `;
98
+
99
+ overlay.appendChild(modal);
100
+ document.body.appendChild(overlay);
101
+
102
+ const container = modal.querySelector('#macro-buttons-container');
103
+ const addBtn = modal.querySelector('#add-macro-btn');
104
+ const clearBtn = modal.querySelector('#clear-macros-btn');
105
+ const cancelBtn = modal.querySelector('#cancel-macros-btn');
106
+ const saveBtn = modal.querySelector('#save-macros-btn');
107
+
108
+ let macroCounter = 0;
109
+
110
+ function addMacroButton(label = '', macro = '') {
111
+ const macroDiv = document.createElement('div');
112
+ macroDiv.className = 'macro-button-config';
113
+ macroDiv.style.cssText = 'padding: 12px; background: #f8f9fa; border-radius: 6px; margin-bottom: 12px; border: 2px solid #dee2e6;';
114
+ macroDiv.dataset.macroId = macroCounter++;
115
+
116
+ macroDiv.innerHTML = `
117
+ <div style="margin-bottom: 8px;">
118
+ <label style="display: block; font-weight: bold; margin-bottom: 4px; color: #333;">Button Label:</label>
119
+ <input type="text" class="macro-label" value="${label}" placeholder="e.g., ⚔️ Attack, 💥 Damage, ✨ Cast" style="width: 100%; padding: 8px; border: 2px solid #ddd; border-radius: 4px; font-size: 14px;">
120
+ </div>
121
+ <div style="margin-bottom: 8px;">
122
+ <label style="display: block; font-weight: bold; margin-bottom: 4px; color: #333;">Macro Text:</label>
123
+ <textarea class="macro-text" placeholder="&{template:default} {{name=My Spell}} {{effect=Custom effect}}" style="width: 100%; padding: 8px; border: 2px solid #ddd; border-radius: 4px; font-size: 13px; font-family: monospace; min-height: 80px;">${macro}</textarea>
124
+ </div>
125
+ <button class="remove-macro-btn" style="padding: 6px 12px; background: #e74c3c; color: white; border: none; border-radius: 4px; cursor: pointer; font-size: 12px;">
126
+ ❌ Remove
127
+ </button>
128
+ `;
129
+
130
+ const removeBtn = macroDiv.querySelector('.remove-macro-btn');
131
+ removeBtn.addEventListener('click', () => {
132
+ macroDiv.remove();
133
+ });
134
+
135
+ container.appendChild(macroDiv);
136
+ }
137
+
138
+ // Add existing macros or one empty macro
139
+ if (existingMacros && existingMacros.buttons && existingMacros.buttons.length > 0) {
140
+ existingMacros.buttons.forEach(btn => {
141
+ addMacroButton(btn.label, btn.macro);
142
+ });
143
+ } else {
144
+ addMacroButton();
145
+ }
146
+
147
+ addBtn.addEventListener('click', () => addMacroButton());
148
+
149
+ clearBtn.addEventListener('click', () => {
150
+ if (confirm(`Clear all custom macros for "${spell.name}"?`)) {
151
+ saveCustomMacros(spell.name, null);
152
+ document.body.removeChild(overlay);
153
+ if (typeof showNotification === 'function') {
154
+ showNotification(`🗑️ Cleared custom macros for ${spell.name}`, 'success');
155
+ }
156
+ }
157
+ });
158
+
159
+ cancelBtn.addEventListener('click', () => {
160
+ document.body.removeChild(overlay);
161
+ });
162
+
163
+ saveBtn.addEventListener('click', () => {
164
+ const macroConfigs = Array.from(container.querySelectorAll('.macro-button-config'));
165
+ const buttons = macroConfigs.map(config => {
166
+ const label = config.querySelector('.macro-label').value.trim();
167
+ const macro = config.querySelector('.macro-text').value.trim();
168
+ return { label, macro };
169
+ }).filter(btn => btn.label && btn.macro); // Only save if both label and macro are provided
170
+
171
+ const skipNormalButtons = modal.querySelector('#skipNormalButtons').checked;
172
+
173
+ saveCustomMacros(spell.name, {
174
+ buttons,
175
+ skipNormalButtons
176
+ });
177
+
178
+ document.body.removeChild(overlay);
179
+ if (typeof showNotification === 'function') {
180
+ showNotification(`💾 Saved custom macros for ${spell.name}`, 'success');
181
+ }
182
+ });
183
+
184
+ // Close on overlay click
185
+ overlay.addEventListener('click', (e) => {
186
+ if (e.target === overlay) {
187
+ document.body.removeChild(overlay);
188
+ }
189
+ });
190
+ }
191
+
192
+ // Export functions to globalThis
193
+ Object.assign(globalThis, {
194
+ getCustomMacros,
195
+ saveCustomMacros,
196
+ showCustomMacroModal
197
+ });
198
+
199
+ console.log('✅ Spell Macros module loaded');
200
+
201
+ })();