@strands.gg/accui 2.1.5 → 2.1.7

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 (173) hide show
  1. package/dist/index.d.ts +1 -6
  2. package/dist/js/auth-components-BJhPF4dS.js +8195 -0
  3. package/dist/js/auth-components-BJhPF4dS.js.br +0 -0
  4. package/dist/js/auth-components-BJhPF4dS.js.gz +0 -0
  5. package/dist/js/auth-components-CXT-W3fG.js +1 -0
  6. package/dist/js/auth-components-CXT-W3fG.js.br +0 -0
  7. package/dist/js/auth-components-CXT-W3fG.js.gz +0 -0
  8. package/dist/js/composables-BqIRpDGP.js +1609 -0
  9. package/dist/js/composables-BqIRpDGP.js.br +0 -0
  10. package/dist/js/composables-BqIRpDGP.js.gz +0 -0
  11. package/dist/js/composables-BqLSXNon.js +1 -0
  12. package/dist/js/composables-BqLSXNon.js.br +0 -0
  13. package/dist/js/composables-BqLSXNon.js.gz +0 -0
  14. package/dist/js/icons-CQ3z-CUv.js +398 -0
  15. package/dist/js/icons-CQ3z-CUv.js.br +0 -0
  16. package/dist/js/icons-CQ3z-CUv.js.gz +0 -0
  17. package/dist/js/icons-MGGFfB13.js +1 -0
  18. package/dist/js/index-87OecKtg.js +1 -0
  19. package/dist/js/index-B113vWue.js +106 -0
  20. package/dist/js/nuxt/module-BA8ZjBpp.js +1 -0
  21. package/dist/{nuxt/module.es.js → js/nuxt/module-YfdoaPCb.js} +2 -0
  22. package/dist/{nuxt/runtime/composables/useAuthenticatedFetch.es.js → js/nuxt/runtime/composables/useAuthenticatedFetch-DToDCO6a.js} +1 -1
  23. package/dist/js/nuxt/runtime/composables/useAuthenticatedFetch-qYkd06Dm.js +1 -0
  24. package/dist/{nuxt/runtime/composables/useStrandsAuth.es.js → js/nuxt/runtime/composables/useStrandsAuth-8b_bomlH.js} +1 -1
  25. package/dist/js/nuxt/runtime/composables/useStrandsAuth-Dn15YEQw.js +1 -0
  26. package/dist/{nuxt/runtime/middleware/auth.global.es.js → js/nuxt/runtime/middleware/auth.global-_2xq-SvK.js} +1 -1
  27. package/dist/js/nuxt/runtime/middleware/auth.global-dZpk-3-I.js +1 -0
  28. package/dist/js/nuxt/runtime/plugin.client-D7S6ulTg.js +1 -0
  29. package/dist/{nuxt/runtime/plugin.client.es.js → js/nuxt/runtime/plugin.client-KK_pCEfA.js} +2 -4
  30. package/dist/js/nuxt/runtime/plugin.server-BpSAN5Gh.js +1 -0
  31. package/dist/{nuxt/runtime/plugin.server.es.js → js/nuxt/runtime/plugin.server-CGdeJOoz.js} +1 -1
  32. package/dist/js/nuxt/runtime/plugins/auth-interceptor.client-BQu0eR16.js +1 -0
  33. package/dist/{nuxt/runtime/plugins/auth-interceptor.client.es.js → js/nuxt/runtime/plugins/auth-interceptor.client-DIa4pC59.js} +1 -1
  34. package/dist/js/nuxt-DqhAWeo-.js +1 -0
  35. package/dist/{nuxt.es.js → js/nuxt-MUpTW0D9.js} +3 -3
  36. package/dist/{nuxt-v4/module.es.js → js/nuxt-v4/module-CCvkwSrU.js} +2 -0
  37. package/dist/js/nuxt-v4/module-CDtxGAn8.js +1 -0
  38. package/dist/{nuxt-v4/runtime/composables/useAuthenticatedFetch.es.js → js/nuxt-v4/runtime/composables/useAuthenticatedFetch-I0BKB43E.js} +1 -1
  39. package/dist/js/nuxt-v4/runtime/composables/useAuthenticatedFetch-fAO6ieYd.js +1 -0
  40. package/dist/{nuxt-v4/runtime/composables/useStrandsAuth.es.js → js/nuxt-v4/runtime/composables/useStrandsAuth-BZe8CTx0.js} +1 -1
  41. package/dist/js/nuxt-v4/runtime/composables/useStrandsAuth-DPGVMZ-e.js +1 -0
  42. package/dist/js/nuxt-v4/runtime/middleware/auth.global-B0pyByUu.js +1 -0
  43. package/dist/{nuxt-v4/runtime/middleware/auth.global.es.js → js/nuxt-v4/runtime/middleware/auth.global-C_saJaMU.js} +1 -1
  44. package/dist/{nuxt-v4/runtime/plugin.client.es.js → js/nuxt-v4/runtime/plugin.client-CxLmYQfu.js} +2 -4
  45. package/dist/js/nuxt-v4/runtime/plugin.client-DGO53i-e.js +1 -0
  46. package/dist/{nuxt-v4/runtime/plugin.server.es.js → js/nuxt-v4/runtime/plugin.server-BM6HYyiZ.js} +1 -1
  47. package/dist/js/nuxt-v4/runtime/plugin.server-D_dUMHYo.js +1 -0
  48. package/dist/js/nuxt-v4/runtime/plugins/auth-interceptor.client-CUNOTFBp.js +1 -0
  49. package/dist/{nuxt-v4/runtime/plugins/auth-interceptor.client.es.js → js/nuxt-v4/runtime/plugins/auth-interceptor.client-Qht8QSLW.js} +1 -1
  50. package/dist/{nuxt-v4.es.js → js/nuxt-v4-C5JN4uyM.js} +3 -3
  51. package/dist/js/nuxt-v4-DuwGUuhX.js +1 -0
  52. package/dist/js/ui-components-BC1UK39i.js +5204 -0
  53. package/dist/js/ui-components-BC1UK39i.js.br +0 -0
  54. package/dist/js/ui-components-BC1UK39i.js.gz +0 -0
  55. package/dist/js/ui-components-CocLXkUI.js +1 -0
  56. package/dist/js/ui-components-CocLXkUI.js.br +0 -0
  57. package/dist/js/ui-components-CocLXkUI.js.gz +0 -0
  58. package/dist/js/utils-B9zcSW52.js +1 -0
  59. package/dist/js/utils-B9zcSW52.js.br +0 -0
  60. package/dist/js/utils-B9zcSW52.js.gz +0 -0
  61. package/dist/js/utils-BZHeJkZf.js +1080 -0
  62. package/dist/js/utils-BZHeJkZf.js.br +0 -0
  63. package/dist/js/utils-BZHeJkZf.js.gz +0 -0
  64. package/dist/nuxt/module.d.ts +1 -5
  65. package/dist/nuxt/runtime/composables/useAuthenticatedFetch.d.ts +1 -20
  66. package/dist/nuxt/runtime/composables/useStrandsAuth.d.ts +1 -142
  67. package/dist/nuxt/runtime/middleware/auth.global.d.ts +1 -3
  68. package/dist/nuxt/runtime/plugin.client.d.ts +1 -3
  69. package/dist/nuxt/runtime/plugin.server.d.ts +1 -3
  70. package/dist/nuxt/runtime/plugins/auth-interceptor.client.d.ts +1 -3
  71. package/dist/nuxt-v4/module.d.ts +1 -5
  72. package/dist/nuxt-v4/runtime/composables/useAuthenticatedFetch.d.ts +1 -20
  73. package/dist/nuxt-v4/runtime/composables/useStrandsAuth.d.ts +1 -27
  74. package/dist/nuxt-v4/runtime/middleware/auth.global.d.ts +1 -3
  75. package/dist/nuxt-v4/runtime/plugin.client.d.ts +1 -3
  76. package/dist/nuxt-v4/runtime/plugin.server.d.ts +1 -3
  77. package/dist/nuxt-v4/runtime/plugins/auth-interceptor.client.d.ts +1 -3
  78. package/dist/nuxt-v4.d.ts +1 -4
  79. package/dist/nuxt.d.ts +1 -4
  80. package/dist/robots.txt +4 -0
  81. package/dist/sitemap.xml +9 -0
  82. package/dist/styles/accui-DF7zRGFD.css +1 -0
  83. package/dist/styles/accui-DF7zRGFD.css.br +0 -0
  84. package/dist/styles/accui-DF7zRGFD.css.gz +0 -0
  85. package/package.json +5 -1
  86. package/dist/accui.css +0 -1
  87. package/dist/nuxt/module.cjs.js +0 -1
  88. package/dist/nuxt/runtime/composables/useAuthenticatedFetch.cjs.js +0 -1
  89. package/dist/nuxt/runtime/composables/useStrandsAuth.cjs.js +0 -1
  90. package/dist/nuxt/runtime/middleware/auth.d.ts +0 -7
  91. package/dist/nuxt/runtime/middleware/auth.global.cjs.js +0 -1
  92. package/dist/nuxt/runtime/middleware/guest.d.ts +0 -7
  93. package/dist/nuxt/runtime/plugin.client.cjs.js +0 -1
  94. package/dist/nuxt/runtime/plugin.server.cjs.js +0 -1
  95. package/dist/nuxt/runtime/plugins/auth-interceptor.client.cjs.js +0 -1
  96. package/dist/nuxt/types.d.ts +0 -45
  97. package/dist/nuxt-v4/module.cjs.js +0 -1
  98. package/dist/nuxt-v4/runtime/composables/useAuthenticatedFetch.cjs.js +0 -1
  99. package/dist/nuxt-v4/runtime/composables/useStrandsAuth.cjs.js +0 -1
  100. package/dist/nuxt-v4/runtime/middleware/auth.global.cjs.js +0 -1
  101. package/dist/nuxt-v4/runtime/plugin.client.cjs.js +0 -1
  102. package/dist/nuxt-v4/runtime/plugin.server.cjs.js +0 -1
  103. package/dist/nuxt-v4/runtime/plugins/auth-interceptor.client.cjs.js +0 -1
  104. package/dist/nuxt-v4/types.d.ts +0 -63
  105. package/dist/nuxt-v4.cjs.js +0 -1
  106. package/dist/nuxt.cjs.js +0 -1
  107. package/dist/shared/defaults.d.ts +0 -2
  108. package/dist/strands-auth-ui.cjs.js +0 -1
  109. package/dist/strands-auth-ui.es.js +0 -10561
  110. package/dist/types/index.d.ts +0 -236
  111. package/dist/useStrandsAuth-CTlaiFqK.cjs +0 -1
  112. package/dist/useStrandsAuth-Cev-PTun.js +0 -899
  113. package/dist/useStrandsConfig-Cxb360Os.js +0 -179
  114. package/dist/useStrandsConfig-Z9_36OcV.cjs +0 -1
  115. package/dist/utils/index.d.ts +0 -1
  116. package/dist/utils/slots.d.ts +0 -1
  117. package/dist/utils/validation.d.ts +0 -12
  118. package/dist/vue/components/SignedIn.vue.d.ts +0 -54
  119. package/dist/vue/components/SignedOut.vue.d.ts +0 -54
  120. package/dist/vue/components/StrandsAuth.vue.d.ts +0 -25
  121. package/dist/vue/components/StrandsBackupCodesModal.vue.d.ts +0 -12
  122. package/dist/vue/components/StrandsCompleteSignUp.vue.d.ts +0 -21
  123. package/dist/vue/components/StrandsConfigProvider.vue.d.ts +0 -22
  124. package/dist/vue/components/StrandsConfirmModal.vue.d.ts +0 -22
  125. package/dist/vue/components/StrandsEmailMfaSetupModal.vue.d.ts +0 -12
  126. package/dist/vue/components/StrandsHardwareKeySetupModal.vue.d.ts +0 -15
  127. package/dist/vue/components/StrandsLogo.vue.d.ts +0 -8
  128. package/dist/vue/components/StrandsMFASetup.vue.d.ts +0 -16
  129. package/dist/vue/components/StrandsMfaModal.vue.d.ts +0 -12
  130. package/dist/vue/components/StrandsMfaVerification.vue.d.ts +0 -17
  131. package/dist/vue/components/StrandsPasswordReset.vue.d.ts +0 -15
  132. package/dist/vue/components/StrandsSecuredFooter.vue.d.ts +0 -22
  133. package/dist/vue/components/StrandsSessionsModal.vue.d.ts +0 -14
  134. package/dist/vue/components/StrandsSettingsModal.vue.d.ts +0 -18
  135. package/dist/vue/components/StrandsSignIn.vue.d.ts +0 -21
  136. package/dist/vue/components/StrandsSignUp.vue.d.ts +0 -19
  137. package/dist/vue/components/StrandsTotpSetupModal.vue.d.ts +0 -12
  138. package/dist/vue/components/StrandsUserButton.vue.d.ts +0 -30
  139. package/dist/vue/components/StrandsUserProfile.vue.d.ts +0 -26
  140. package/dist/vue/components/SvgIcon.vue.d.ts +0 -17
  141. package/dist/vue/components/VirtualList.vue.d.ts +0 -37
  142. package/dist/vue/components/icons/IconGithub.vue.d.ts +0 -3
  143. package/dist/vue/components/icons/IconGoogle.vue.d.ts +0 -3
  144. package/dist/vue/components/icons/index.d.ts +0 -2
  145. package/dist/vue/components/index.d.ts +0 -26
  146. package/dist/vue/composables/useAuthenticatedFetch.d.ts +0 -20
  147. package/dist/vue/composables/useOAuthProviders.d.ts +0 -74
  148. package/dist/vue/composables/useStrandsAuth.d.ts +0 -130
  149. package/dist/vue/composables/useStrandsConfig.d.ts +0 -11
  150. package/dist/vue/composables/useStrandsMfa.d.ts +0 -38
  151. package/dist/vue/index.d.ts +0 -12
  152. package/dist/vue/plugins/StrandsUIPlugin.d.ts +0 -19
  153. package/dist/vue/ui/UiAlert.vue.d.ts +0 -31
  154. package/dist/vue/ui/UiAvatarEditor.vue.d.ts +0 -25
  155. package/dist/vue/ui/UiButton.vue.d.ts +0 -54
  156. package/dist/vue/ui/UiCard.vue.d.ts +0 -29
  157. package/dist/vue/ui/UiInput.vue.d.ts +0 -48
  158. package/dist/vue/ui/UiLevelProgress.vue.d.ts +0 -19
  159. package/dist/vue/ui/UiLink.vue.d.ts +0 -42
  160. package/dist/vue/ui/UiLoader.vue.d.ts +0 -15
  161. package/dist/vue/ui/UiModal.vue.d.ts +0 -33
  162. package/dist/vue/ui/UiTabs.vue.d.ts +0 -17
  163. package/dist/vue/ui/UiToggle.vue.d.ts +0 -15
  164. package/dist/vue/ui/index.d.ts +0 -29
  165. package/dist/vue/utils/contrast.d.ts +0 -79
  166. package/dist/vue/utils/debounce.d.ts +0 -12
  167. package/dist/vue/utils/fontPreloader.d.ts +0 -19
  168. package/dist/vue/utils/iconProps.d.ts +0 -9
  169. package/dist/vue/utils/lazyComponents.d.ts +0 -2
  170. package/dist/vue/utils/levels.d.ts +0 -27
  171. package/dist/vue/utils/performanceInit.d.ts +0 -40
  172. package/dist/vue/utils/requestCache.d.ts +0 -49
  173. package/dist/vue/utils/sounds.d.ts +0 -56
@@ -0,0 +1,1080 @@
1
+ class SoundEffects {
2
+ static audioContext = null;
3
+ /**
4
+ * Get or create a shared AudioContext
5
+ */
6
+ static getAudioContext() {
7
+ try {
8
+ if (!this.audioContext) {
9
+ this.audioContext = new (window.AudioContext || window.webkitAudioContext)();
10
+ }
11
+ if (this.audioContext.state === "suspended") {
12
+ this.audioContext.resume();
13
+ }
14
+ return this.audioContext;
15
+ } catch (error) {
16
+ console.warn("Audio context not available:", error);
17
+ return null;
18
+ }
19
+ }
20
+ /**
21
+ * Play a level up sound effect
22
+ * A pleasant major chord with arpeggio and bell overtones
23
+ */
24
+ static playLevelUp(level, userSettings) {
25
+ const milestones = [10, 25, 50, 100, 150, 200];
26
+ const isMilestone = level && milestones.includes(level);
27
+ if (userSettings) {
28
+ if (isMilestone && userSettings.milestoneSounds === false) {
29
+ return;
30
+ }
31
+ if (!isMilestone && userSettings.levelUpSounds === false) {
32
+ return;
33
+ }
34
+ }
35
+ if (isMilestone) {
36
+ this.playMilestoneLevelUp();
37
+ } else {
38
+ this.playRegularLevelUp();
39
+ }
40
+ }
41
+ /**
42
+ * Play regular level up sound for normal levels
43
+ * A gentle, smooth celebration sound
44
+ */
45
+ static playRegularLevelUp() {
46
+ const audioContext = this.getAudioContext();
47
+ if (!audioContext) return;
48
+ const now = audioContext.currentTime;
49
+ const melody = [
50
+ { freq: 523.25, time: 0 },
51
+ // C5
52
+ { freq: 659.25, time: 0.15 },
53
+ // E5
54
+ { freq: 783.99, time: 0.3 }
55
+ // G5
56
+ ];
57
+ melody.forEach((note) => {
58
+ const oscillator = audioContext.createOscillator();
59
+ const gainNode = audioContext.createGain();
60
+ oscillator.connect(gainNode);
61
+ gainNode.connect(audioContext.destination);
62
+ oscillator.type = "sine";
63
+ oscillator.frequency.setValueAtTime(note.freq, now + note.time);
64
+ oscillator.frequency.exponentialRampToValueAtTime(note.freq * 1.02, now + note.time + 0.1);
65
+ oscillator.frequency.exponentialRampToValueAtTime(note.freq, now + note.time + 0.4);
66
+ gainNode.gain.setValueAtTime(0, now + note.time);
67
+ gainNode.gain.linearRampToValueAtTime(0.08, now + note.time + 0.03);
68
+ gainNode.gain.linearRampToValueAtTime(0.06, now + note.time + 0.2);
69
+ gainNode.gain.exponentialRampToValueAtTime(0.01, now + note.time + 0.5);
70
+ oscillator.start(now + note.time);
71
+ oscillator.stop(now + note.time + 0.5);
72
+ });
73
+ const harmony = audioContext.createOscillator();
74
+ const harmonyGain = audioContext.createGain();
75
+ harmony.connect(harmonyGain);
76
+ harmonyGain.connect(audioContext.destination);
77
+ harmony.type = "triangle";
78
+ harmony.frequency.setValueAtTime(261.63, now);
79
+ harmonyGain.gain.setValueAtTime(0, now);
80
+ harmonyGain.gain.linearRampToValueAtTime(0.04, now + 0.1);
81
+ harmonyGain.gain.linearRampToValueAtTime(0.03, now + 0.4);
82
+ harmonyGain.gain.exponentialRampToValueAtTime(0.01, now + 0.8);
83
+ harmony.start(now);
84
+ harmony.stop(now + 0.8);
85
+ const sparkle = audioContext.createOscillator();
86
+ const sparkleGain = audioContext.createGain();
87
+ sparkle.connect(sparkleGain);
88
+ sparkleGain.connect(audioContext.destination);
89
+ sparkle.type = "sine";
90
+ sparkle.frequency.setValueAtTime(1046.5, now + 0.2);
91
+ sparkleGain.gain.setValueAtTime(0, now + 0.2);
92
+ sparkleGain.gain.linearRampToValueAtTime(0.03, now + 0.25);
93
+ sparkleGain.gain.exponentialRampToValueAtTime(1e-3, now + 0.6);
94
+ sparkle.start(now + 0.2);
95
+ sparkle.stop(now + 0.6);
96
+ }
97
+ /**
98
+ * Play epic milestone level up sound for special levels (10, 25, 50, 100, 150, 200)
99
+ * A beautiful, uplifting celebration sound for major achievements
100
+ */
101
+ static playMilestoneLevelUp() {
102
+ const audioContext = this.getAudioContext();
103
+ if (!audioContext) return;
104
+ const now = audioContext.currentTime;
105
+ const duration = 2.5;
106
+ const mainNotes = [
107
+ { freq: 261.63, time: 0 },
108
+ // C4
109
+ { freq: 329.63, time: 0.2 },
110
+ // E4
111
+ { freq: 392, time: 0.4 },
112
+ // G4
113
+ { freq: 523.25, time: 0.6 },
114
+ // C5
115
+ { freq: 659.25, time: 0.8 }
116
+ // E5
117
+ ];
118
+ mainNotes.forEach((note) => {
119
+ const osc = audioContext.createOscillator();
120
+ const gain = audioContext.createGain();
121
+ osc.connect(gain);
122
+ gain.connect(audioContext.destination);
123
+ osc.type = "sine";
124
+ osc.frequency.setValueAtTime(note.freq, now + note.time);
125
+ gain.gain.setValueAtTime(0, now + note.time);
126
+ gain.gain.linearRampToValueAtTime(0.15, now + note.time + 0.05);
127
+ gain.gain.exponentialRampToValueAtTime(0.01, now + note.time + 0.8);
128
+ osc.start(now + note.time);
129
+ osc.stop(now + note.time + 0.8);
130
+ });
131
+ const harmony = [
132
+ { freq: 130.81, time: 0, duration: 1.5 },
133
+ // C3
134
+ { freq: 196, time: 0.8, duration: 1.7 }
135
+ // G3
136
+ ];
137
+ harmony.forEach((note) => {
138
+ const osc = audioContext.createOscillator();
139
+ const gain = audioContext.createGain();
140
+ osc.connect(gain);
141
+ gain.connect(audioContext.destination);
142
+ osc.type = "triangle";
143
+ osc.frequency.setValueAtTime(note.freq, now + note.time);
144
+ gain.gain.setValueAtTime(0, now + note.time);
145
+ gain.gain.linearRampToValueAtTime(0.08, now + note.time + 0.3);
146
+ gain.gain.exponentialRampToValueAtTime(0.01, now + note.time + note.duration);
147
+ osc.start(now + note.time);
148
+ osc.stop(now + note.time + note.duration);
149
+ });
150
+ const sparkle = [
151
+ { freq: 1046.5, time: 1 },
152
+ // C6
153
+ { freq: 1318.51, time: 1.3 },
154
+ // E6
155
+ { freq: 1567.98, time: 1.6 }
156
+ // G6
157
+ ];
158
+ sparkle.forEach((note) => {
159
+ const osc = audioContext.createOscillator();
160
+ const gain = audioContext.createGain();
161
+ osc.connect(gain);
162
+ gain.connect(audioContext.destination);
163
+ osc.type = "sine";
164
+ osc.frequency.setValueAtTime(note.freq, now + note.time);
165
+ gain.gain.setValueAtTime(0, now + note.time);
166
+ gain.gain.linearRampToValueAtTime(0.1, now + note.time + 0.02);
167
+ gain.gain.exponentialRampToValueAtTime(0.01, now + note.time + 0.4);
168
+ osc.start(now + note.time);
169
+ osc.stop(now + note.time + 0.4);
170
+ });
171
+ const finalChord = [261.63, 329.63, 392, 523.25];
172
+ finalChord.forEach((freq) => {
173
+ const osc = audioContext.createOscillator();
174
+ const gain = audioContext.createGain();
175
+ osc.connect(gain);
176
+ gain.connect(audioContext.destination);
177
+ osc.type = "sine";
178
+ osc.frequency.setValueAtTime(freq, now + 1.8);
179
+ gain.gain.setValueAtTime(0, now + 1.8);
180
+ gain.gain.linearRampToValueAtTime(0.12, now + 1.9);
181
+ gain.gain.exponentialRampToValueAtTime(0.01, now + duration);
182
+ osc.start(now + 1.8);
183
+ osc.stop(now + duration);
184
+ });
185
+ }
186
+ /**
187
+ * Play a success/completion sound
188
+ * A short, bright confirmation tone
189
+ */
190
+ static playSuccess() {
191
+ const audioContext = this.getAudioContext();
192
+ if (!audioContext) return;
193
+ const now = audioContext.currentTime;
194
+ const frequencies = [659.25, 830.61];
195
+ frequencies.forEach((freq, index) => {
196
+ const oscillator = audioContext.createOscillator();
197
+ const gainNode = audioContext.createGain();
198
+ oscillator.connect(gainNode);
199
+ gainNode.connect(audioContext.destination);
200
+ oscillator.type = "sine";
201
+ oscillator.frequency.setValueAtTime(freq, now);
202
+ const delay = index * 0.1;
203
+ const duration = 0.15;
204
+ gainNode.gain.setValueAtTime(0, now);
205
+ gainNode.gain.linearRampToValueAtTime(0.2, now + delay + 0.01);
206
+ gainNode.gain.exponentialRampToValueAtTime(0.01, now + delay + duration);
207
+ oscillator.start(now + delay);
208
+ oscillator.stop(now + delay + duration);
209
+ });
210
+ }
211
+ /**
212
+ * Play an error/failure sound
213
+ * A low, descending tone
214
+ */
215
+ static playError() {
216
+ const audioContext = this.getAudioContext();
217
+ if (!audioContext) return;
218
+ const now = audioContext.currentTime;
219
+ const oscillator = audioContext.createOscillator();
220
+ const gainNode = audioContext.createGain();
221
+ oscillator.connect(gainNode);
222
+ gainNode.connect(audioContext.destination);
223
+ oscillator.type = "sawtooth";
224
+ oscillator.frequency.setValueAtTime(200, now);
225
+ oscillator.frequency.exponentialRampToValueAtTime(100, now + 0.3);
226
+ gainNode.gain.setValueAtTime(0.15, now);
227
+ gainNode.gain.exponentialRampToValueAtTime(0.01, now + 0.3);
228
+ oscillator.start(now);
229
+ oscillator.stop(now + 0.3);
230
+ }
231
+ /**
232
+ * Play a click/button press sound
233
+ * A very short, soft click
234
+ */
235
+ static playClick() {
236
+ const audioContext = this.getAudioContext();
237
+ if (!audioContext) return;
238
+ const now = audioContext.currentTime;
239
+ const oscillator = audioContext.createOscillator();
240
+ const gainNode = audioContext.createGain();
241
+ oscillator.connect(gainNode);
242
+ gainNode.connect(audioContext.destination);
243
+ oscillator.type = "sine";
244
+ oscillator.frequency.setValueAtTime(1e3, now);
245
+ gainNode.gain.setValueAtTime(0.1, now);
246
+ gainNode.gain.exponentialRampToValueAtTime(0.01, now + 0.03);
247
+ oscillator.start(now);
248
+ oscillator.stop(now + 0.03);
249
+ }
250
+ /**
251
+ * Play a notification sound
252
+ * A gentle two-tone chime
253
+ */
254
+ static playNotification() {
255
+ const audioContext = this.getAudioContext();
256
+ if (!audioContext) return;
257
+ const now = audioContext.currentTime;
258
+ const frequencies = [880, 1174.66];
259
+ frequencies.forEach((freq, index) => {
260
+ const oscillator = audioContext.createOscillator();
261
+ const gainNode = audioContext.createGain();
262
+ oscillator.connect(gainNode);
263
+ gainNode.connect(audioContext.destination);
264
+ oscillator.type = "sine";
265
+ oscillator.frequency.setValueAtTime(freq, now);
266
+ const delay = index * 0.15;
267
+ gainNode.gain.setValueAtTime(0, now);
268
+ gainNode.gain.linearRampToValueAtTime(0.12, now + delay + 0.02);
269
+ gainNode.gain.exponentialRampToValueAtTime(0.01, now + delay + 0.4);
270
+ oscillator.start(now + delay);
271
+ oscillator.stop(now + delay + 0.4);
272
+ });
273
+ }
274
+ /**
275
+ * Play an XP gain sound
276
+ * A quick, ascending glissando
277
+ */
278
+ static playXpGain() {
279
+ const audioContext = this.getAudioContext();
280
+ if (!audioContext) return;
281
+ const now = audioContext.currentTime;
282
+ const oscillator = audioContext.createOscillator();
283
+ const gainNode = audioContext.createGain();
284
+ oscillator.connect(gainNode);
285
+ gainNode.connect(audioContext.destination);
286
+ oscillator.type = "sine";
287
+ oscillator.frequency.setValueAtTime(440, now);
288
+ oscillator.frequency.exponentialRampToValueAtTime(880, now + 0.15);
289
+ gainNode.gain.setValueAtTime(0, now);
290
+ gainNode.gain.linearRampToValueAtTime(0.15, now + 0.01);
291
+ gainNode.gain.exponentialRampToValueAtTime(0.01, now + 0.2);
292
+ oscillator.start(now);
293
+ oscillator.stop(now + 0.2);
294
+ }
295
+ }
296
+ const playLevelUp = (level, userSettings) => SoundEffects.playLevelUp(level, userSettings);
297
+ const tailwindColors = {
298
+ "#000000": {
299
+ label: "Black"
300
+ },
301
+ "#ffffff": {
302
+ label: "White"
303
+ },
304
+ "#64748b": {
305
+ label: "Tailwind Slate",
306
+ shades: [
307
+ "#f8fafc",
308
+ // slate-50
309
+ "#f1f5f9",
310
+ // slate-100
311
+ "#e2e8f0",
312
+ // slate-200
313
+ "#cbd5e1",
314
+ // slate-300
315
+ "#94a3b8",
316
+ // slate-400
317
+ "#64748b",
318
+ // slate-500
319
+ "#475569",
320
+ // slate-600
321
+ "#334155",
322
+ // slate-700
323
+ "#1e293b",
324
+ // slate-800
325
+ "#0f172a",
326
+ // slate-900
327
+ "#020617"
328
+ // slate-950
329
+ ]
330
+ },
331
+ "#6b7280": {
332
+ label: "Tailwind Gray",
333
+ shades: [
334
+ "#f9fafb",
335
+ // gray-50
336
+ "#f3f4f6",
337
+ // gray-100
338
+ "#e5e7eb",
339
+ // gray-200
340
+ "#d1d5db",
341
+ // gray-300
342
+ "#9ca3af",
343
+ // gray-400
344
+ "#6b7280",
345
+ // gray-500
346
+ "#4b5563",
347
+ // gray-600
348
+ "#374151",
349
+ // gray-700
350
+ "#1f2937",
351
+ // gray-800
352
+ "#111827",
353
+ // gray-900
354
+ "#030712"
355
+ // gray-950
356
+ ]
357
+ },
358
+ "#71717a": {
359
+ label: "Tailwind Zinc",
360
+ shades: [
361
+ "#fafafa",
362
+ // zinc-50
363
+ "#f4f4f5",
364
+ // zinc-100
365
+ "#e4e4e7",
366
+ // zinc-200
367
+ "#d4d4d8",
368
+ // zinc-300
369
+ "#a1a1aa",
370
+ // zinc-400
371
+ "#71717a",
372
+ // zinc-500
373
+ "#52525b",
374
+ // zinc-600
375
+ "#3f3f46",
376
+ // zinc-700
377
+ "#27272a",
378
+ // zinc-800
379
+ "#18181b",
380
+ // zinc-900
381
+ "#09090b"
382
+ // zinc-950
383
+ ]
384
+ },
385
+ "#737373": {
386
+ label: "Tailwind Neutral",
387
+ shades: [
388
+ "#fafafa",
389
+ // neutral-50
390
+ "#f5f5f5",
391
+ // neutral-100
392
+ "#e5e5e5",
393
+ // neutral-200
394
+ "#d4d4d4",
395
+ // neutral-300
396
+ "#a3a3a3",
397
+ // neutral-400
398
+ "#737373",
399
+ // neutral-500
400
+ "#525252",
401
+ // neutral-600
402
+ "#404040",
403
+ // neutral-700
404
+ "#262626",
405
+ // neutral-800
406
+ "#171717",
407
+ // neutral-900
408
+ "#0a0a0a"
409
+ // neutral-950
410
+ ]
411
+ },
412
+ "#78716c": {
413
+ label: "Tailwind Stone",
414
+ shades: [
415
+ "#fafaf9",
416
+ // stone-50
417
+ "#f5f5f4",
418
+ // stone-100
419
+ "#e7e5e4",
420
+ // stone-200
421
+ "#d6d3d1",
422
+ // stone-300
423
+ "#a8a29e",
424
+ // stone-400
425
+ "#78716c",
426
+ // stone-500
427
+ "#57534e",
428
+ // stone-600
429
+ "#44403c",
430
+ // stone-700
431
+ "#292524",
432
+ // stone-800
433
+ "#1c1917",
434
+ // stone-900
435
+ "#0c0a09"
436
+ // stone-950
437
+ ]
438
+ },
439
+ "#ef4444": {
440
+ label: "Tailwind Red",
441
+ shades: [
442
+ "#fef2f2",
443
+ // red-50
444
+ "#fee2e2",
445
+ // red-100
446
+ "#fecaca",
447
+ // red-200
448
+ "#fca5a5",
449
+ // red-300
450
+ "#f87171",
451
+ // red-400
452
+ "#ef4444",
453
+ // red-500
454
+ "#dc2626",
455
+ // red-600
456
+ "#b91c1c",
457
+ // red-700
458
+ "#991b1b",
459
+ // red-800
460
+ "#7f1d1d",
461
+ // red-900
462
+ "#450a0a"
463
+ // red-950
464
+ ]
465
+ },
466
+ "#f97316": {
467
+ label: "Tailwind Orange",
468
+ shades: [
469
+ "#fff7ed",
470
+ // orange-50
471
+ "#ffedd5",
472
+ // orange-100
473
+ "#fed7aa",
474
+ // orange-200
475
+ "#fdba74",
476
+ // orange-300
477
+ "#fb923c",
478
+ // orange-400
479
+ "#f97316",
480
+ // orange-500
481
+ "#ea580c",
482
+ // orange-600
483
+ "#c2410c",
484
+ // orange-700
485
+ "#9a3412",
486
+ // orange-800
487
+ "#7c2d12",
488
+ // orange-900
489
+ "#431407"
490
+ // orange-950
491
+ ]
492
+ },
493
+ "#f59e0b": {
494
+ label: "Tailwind Amber",
495
+ shades: [
496
+ "#fffbeb",
497
+ // amber-50
498
+ "#fef3c7",
499
+ // amber-100
500
+ "#fde68a",
501
+ // amber-200
502
+ "#fcd34d",
503
+ // amber-300
504
+ "#fbbf24",
505
+ // amber-400
506
+ "#f59e0b",
507
+ // amber-500
508
+ "#d97706",
509
+ // amber-600
510
+ "#b45309",
511
+ // amber-700
512
+ "#92400e",
513
+ // amber-800
514
+ "#78350f",
515
+ // amber-900
516
+ "#451a03"
517
+ // amber-950
518
+ ]
519
+ },
520
+ "#eab308": {
521
+ label: "Tailwind Yellow",
522
+ shades: [
523
+ "#fefce8",
524
+ // yellow-50
525
+ "#fef3c7",
526
+ // yellow-100
527
+ "#fde68a",
528
+ // yellow-200
529
+ "#fcd34d",
530
+ // yellow-300
531
+ "#fbbf24",
532
+ // yellow-400
533
+ "#eab308",
534
+ // yellow-500
535
+ "#ca8a04",
536
+ // yellow-600
537
+ "#a16207",
538
+ // yellow-700
539
+ "#854d0e",
540
+ // yellow-800
541
+ "#713f12",
542
+ // yellow-900
543
+ "#422006"
544
+ // yellow-950
545
+ ]
546
+ },
547
+ "#84cc16": {
548
+ label: "Tailwind Lime",
549
+ shades: [
550
+ "#f7fee7",
551
+ // lime-50
552
+ "#ecfccb",
553
+ // lime-100
554
+ "#d9f99d",
555
+ // lime-200
556
+ "#bef264",
557
+ // lime-300
558
+ "#a3e635",
559
+ // lime-400
560
+ "#84cc16",
561
+ // lime-500
562
+ "#65a30d",
563
+ // lime-600
564
+ "#4d7c0f",
565
+ // lime-700
566
+ "#365314",
567
+ // lime-800
568
+ "#1a2e05",
569
+ // lime-900
570
+ "#0a0f02"
571
+ // lime-950
572
+ ]
573
+ },
574
+ "#22c55e": {
575
+ label: "Tailwind Green",
576
+ shades: [
577
+ "#f0fdf4",
578
+ // green-50
579
+ "#dcfce7",
580
+ // green-100
581
+ "#bbf7d0",
582
+ // green-200
583
+ "#86efac",
584
+ // green-300
585
+ "#4ade80",
586
+ // green-400
587
+ "#22c55e",
588
+ // green-500
589
+ "#16a34a",
590
+ // green-600
591
+ "#15803d",
592
+ // green-700
593
+ "#166534",
594
+ // green-800
595
+ "#14532d",
596
+ // green-900
597
+ "#052e16"
598
+ // green-950
599
+ ]
600
+ },
601
+ "#10b981": {
602
+ label: "Tailwind Emerald",
603
+ shades: [
604
+ "#ecfdf5",
605
+ // emerald-50
606
+ "#d1fae5",
607
+ // emerald-100
608
+ "#a7f3d0",
609
+ // emerald-200
610
+ "#6ee7b7",
611
+ // emerald-300
612
+ "#34d399",
613
+ // emerald-400
614
+ "#10b981",
615
+ // emerald-500
616
+ "#059669",
617
+ // emerald-600
618
+ "#047857",
619
+ // emerald-700
620
+ "#065f46",
621
+ // emerald-800
622
+ "#064e3b",
623
+ // emerald-900
624
+ "#022c22"
625
+ // emerald-950
626
+ ]
627
+ },
628
+ "#14b8a6": {
629
+ label: "Tailwind Teal",
630
+ shades: [
631
+ "#f0fdfa",
632
+ // teal-50
633
+ "#ccfbf1",
634
+ // teal-100
635
+ "#99f6e4",
636
+ // teal-200
637
+ "#5eead4",
638
+ // teal-300
639
+ "#2dd4bf",
640
+ // teal-400
641
+ "#14b8a6",
642
+ // teal-500
643
+ "#0d9488",
644
+ // teal-600
645
+ "#0f766e",
646
+ // teal-700
647
+ "#115e59",
648
+ // teal-800
649
+ "#134e4a",
650
+ // teal-900
651
+ "#042f2e"
652
+ // teal-950
653
+ ]
654
+ },
655
+ "#06b6d4": {
656
+ label: "Tailwind Cyan",
657
+ shades: [
658
+ "#ecfeff",
659
+ // cyan-50
660
+ "#cffafe",
661
+ // cyan-100
662
+ "#a5f3fc",
663
+ // cyan-200
664
+ "#67e8f9",
665
+ // cyan-300
666
+ "#22d3ee",
667
+ // cyan-400
668
+ "#06b6d4",
669
+ // cyan-500
670
+ "#0891b2",
671
+ // cyan-600
672
+ "#0e7490",
673
+ // cyan-700
674
+ "#155e75",
675
+ // cyan-800
676
+ "#164e63",
677
+ // cyan-900
678
+ "#083344"
679
+ // cyan-950
680
+ ]
681
+ },
682
+ "#0ea5e9": {
683
+ label: "Tailwind Sky",
684
+ shades: [
685
+ "#f0f9ff",
686
+ // sky-50
687
+ "#e0f2fe",
688
+ // sky-100
689
+ "#bae6fd",
690
+ // sky-200
691
+ "#7dd3fc",
692
+ // sky-300
693
+ "#38bdf8",
694
+ // sky-400
695
+ "#0ea5e9",
696
+ // sky-500
697
+ "#0284c7",
698
+ // sky-600
699
+ "#0369a1",
700
+ // sky-700
701
+ "#075985",
702
+ // sky-800
703
+ "#0c4a6e",
704
+ // sky-900
705
+ "#082f49"
706
+ // sky-950
707
+ ]
708
+ },
709
+ "#3b82f6": {
710
+ label: "Tailwind Blue",
711
+ shades: [
712
+ "#eff6ff",
713
+ // blue-50
714
+ "#dbeafe",
715
+ // blue-100
716
+ "#bfdbfe",
717
+ // blue-200
718
+ "#93c5fd",
719
+ // blue-300
720
+ "#60a5fa",
721
+ // blue-400
722
+ "#3b82f6",
723
+ // blue-500
724
+ "#2563eb",
725
+ // blue-600
726
+ "#1d4ed8",
727
+ // blue-700
728
+ "#1e40af",
729
+ // blue-800
730
+ "#1e3a8a",
731
+ // blue-900
732
+ "#172554"
733
+ // blue-950
734
+ ]
735
+ },
736
+ "#6366f1": {
737
+ label: "Tailwind Indigo",
738
+ shades: [
739
+ "#eef2ff",
740
+ // indigo-50
741
+ "#e0e7ff",
742
+ // indigo-100
743
+ "#c7d2fe",
744
+ // indigo-200
745
+ "#a5b4fc",
746
+ // indigo-300
747
+ "#818cf8",
748
+ // indigo-400
749
+ "#6366f1",
750
+ // indigo-500
751
+ "#4f46e5",
752
+ // indigo-600
753
+ "#4338ca",
754
+ // indigo-700
755
+ "#3730a3",
756
+ // indigo-800
757
+ "#312e81",
758
+ // indigo-900
759
+ "#1e1b4b"
760
+ // indigo-950
761
+ ]
762
+ },
763
+ "#8b5cf6": {
764
+ label: "Tailwind Violet",
765
+ shades: [
766
+ "#f5f3ff",
767
+ // violet-50
768
+ "#ede9fe",
769
+ // violet-100
770
+ "#ddd6fe",
771
+ // violet-200
772
+ "#c4b5fd",
773
+ // violet-300
774
+ "#a78bfa",
775
+ // violet-400
776
+ "#8b5cf6",
777
+ // violet-500
778
+ "#7c3aed",
779
+ // violet-600
780
+ "#6d28d9",
781
+ // violet-700
782
+ "#5b21b6",
783
+ // violet-800
784
+ "#4c1d95",
785
+ // violet-900
786
+ "#2e1065"
787
+ // violet-950
788
+ ]
789
+ },
790
+ "#a855f7": {
791
+ label: "Tailwind Purple",
792
+ shades: [
793
+ "#faf5ff",
794
+ // purple-50
795
+ "#f3e8ff",
796
+ // purple-100
797
+ "#e9d5ff",
798
+ // purple-200
799
+ "#d8b4fe",
800
+ // purple-300
801
+ "#c084fc",
802
+ // purple-400
803
+ "#a855f7",
804
+ // purple-500
805
+ "#9333ea",
806
+ // purple-600
807
+ "#7c3aed",
808
+ // purple-700
809
+ "#6b21a8",
810
+ // purple-800
811
+ "#581c87",
812
+ // purple-900
813
+ "#3b0764"
814
+ // purple-950
815
+ ]
816
+ },
817
+ "#d946ef": {
818
+ label: "Tailwind Fuchsia",
819
+ shades: [
820
+ "#fdf4ff",
821
+ // fuchsia-50
822
+ "#fae8ff",
823
+ // fuchsia-100
824
+ "#f5d0fe",
825
+ // fuchsia-200
826
+ "#f0abfc",
827
+ // fuchsia-300
828
+ "#e879f9",
829
+ // fuchsia-400
830
+ "#d946ef",
831
+ // fuchsia-500
832
+ "#c026d3",
833
+ // fuchsia-600
834
+ "#a21caf",
835
+ // fuchsia-700
836
+ "#86198f",
837
+ // fuchsia-800
838
+ "#701a75",
839
+ // fuchsia-900
840
+ "#4a044e"
841
+ // fuchsia-950
842
+ ]
843
+ },
844
+ "#ec4899": {
845
+ label: "Tailwind Pink",
846
+ shades: [
847
+ "#fdf2f8",
848
+ // pink-50
849
+ "#fce7f3",
850
+ // pink-100
851
+ "#fbcfe8",
852
+ // pink-200
853
+ "#f9a8d4",
854
+ // pink-300
855
+ "#f472b6",
856
+ // pink-400
857
+ "#ec4899",
858
+ // pink-500
859
+ "#db2777",
860
+ // pink-600
861
+ "#be185d",
862
+ // pink-700
863
+ "#9d174d",
864
+ // pink-800
865
+ "#831843",
866
+ // pink-900
867
+ "#500724"
868
+ // pink-950
869
+ ]
870
+ },
871
+ "#f43f5e": {
872
+ label: "Tailwind Rose",
873
+ shades: [
874
+ "#fff1f2",
875
+ // rose-50
876
+ "#ffe4e6",
877
+ // rose-100
878
+ "#fecdd3",
879
+ // rose-200
880
+ "#fda4af",
881
+ // rose-300
882
+ "#fb7185",
883
+ // rose-400
884
+ "#f43f5e",
885
+ // rose-500
886
+ "#e11d48",
887
+ // rose-600
888
+ "#be123c",
889
+ // rose-700
890
+ "#9f1239",
891
+ // rose-800
892
+ "#881337",
893
+ // rose-900
894
+ "#4c0519"
895
+ // rose-950
896
+ ]
897
+ }
898
+ };
899
+ const slotHasContent = (slotName, slots) => {
900
+ const slot = slots[slotName];
901
+ if (!slot) return false;
902
+ if (typeof slot === "function") {
903
+ const vnodes = slot();
904
+ return Array.isArray(vnodes) && vnodes.length > 0;
905
+ }
906
+ return Array.isArray(slot) && slot.length > 0;
907
+ };
908
+ class RequestCache {
909
+ cache = /* @__PURE__ */ new Map();
910
+ DEFAULT_TTL = 5 * 60 * 1e3;
911
+ // 5 minutes
912
+ /**
913
+ * Memoized fetch - prevents duplicate requests and caches results
914
+ */
915
+ async fetch(key, fetcher, ttl = this.DEFAULT_TTL) {
916
+ const now = Date.now();
917
+ const entry = this.cache.get(key);
918
+ if (entry && now - entry.timestamp < entry.ttl) {
919
+ return entry.promise;
920
+ }
921
+ this.cleanExpired();
922
+ const promise = fetcher().finally(() => {
923
+ setTimeout(() => {
924
+ this.cache.delete(key);
925
+ }, ttl);
926
+ });
927
+ this.cache.set(key, {
928
+ promise,
929
+ timestamp: now,
930
+ ttl
931
+ });
932
+ return promise;
933
+ }
934
+ /**
935
+ * Clear all cached entries
936
+ */
937
+ clear() {
938
+ this.cache.clear();
939
+ }
940
+ /**
941
+ * Remove a specific cache entry
942
+ */
943
+ invalidate(key) {
944
+ this.cache.delete(key);
945
+ }
946
+ /**
947
+ * Clean expired cache entries
948
+ */
949
+ cleanExpired() {
950
+ const now = Date.now();
951
+ for (const [key, entry] of this.cache.entries()) {
952
+ if (now - entry.timestamp > entry.ttl) {
953
+ this.cache.delete(key);
954
+ }
955
+ }
956
+ }
957
+ /**
958
+ * Get cache statistics (for debugging)
959
+ */
960
+ getStats() {
961
+ return {
962
+ size: this.cache.size,
963
+ entries: Array.from(this.cache.keys())
964
+ };
965
+ }
966
+ }
967
+ const requestCache = new RequestCache();
968
+ function useRequestCache() {
969
+ return {
970
+ fetch: requestCache.fetch.bind(requestCache),
971
+ clear: requestCache.clear.bind(requestCache),
972
+ invalidate: requestCache.invalidate.bind(requestCache),
973
+ getStats: requestCache.getStats.bind(requestCache)
974
+ };
975
+ }
976
+ function debounce$1(func, wait) {
977
+ let timeout = null;
978
+ return (...args) => {
979
+ if (timeout) {
980
+ clearTimeout(timeout);
981
+ }
982
+ timeout = setTimeout(() => {
983
+ func(...args);
984
+ }, wait);
985
+ };
986
+ }
987
+ const debouncedSetItem = debounce$1((key, value) => {
988
+ if (typeof window !== "undefined") {
989
+ localStorage.setItem(key, value);
990
+ }
991
+ }, 300);
992
+ const preloadCriticalComponents = () => {
993
+ };
994
+ const isValidEmail = (email) => {
995
+ const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
996
+ return emailRegex.test(email);
997
+ };
998
+ const validatePassword = (password) => {
999
+ const errors = [];
1000
+ let score = 0;
1001
+ if (password.length < 8) {
1002
+ errors.push("Password must be at least 8 characters long");
1003
+ } else {
1004
+ score += 1;
1005
+ }
1006
+ if (!/[A-Z]/.test(password)) {
1007
+ errors.push("Password must contain at least one uppercase letter");
1008
+ } else {
1009
+ score += 1;
1010
+ }
1011
+ if (!/[a-z]/.test(password)) {
1012
+ errors.push("Password must contain at least one lowercase letter");
1013
+ } else {
1014
+ score += 1;
1015
+ }
1016
+ if (!/\d/.test(password)) {
1017
+ errors.push("Password must contain at least one number");
1018
+ } else {
1019
+ score += 1;
1020
+ }
1021
+ if (!/[!@#$%^&*(),.?":{}|<>]/.test(password)) {
1022
+ errors.push("Password must contain at least one special character");
1023
+ } else {
1024
+ score += 1;
1025
+ }
1026
+ const isValid = errors.length === 0;
1027
+ let strength = "weak";
1028
+ if (score >= 4) {
1029
+ strength = "strong";
1030
+ } else if (score >= 3) {
1031
+ strength = "medium";
1032
+ }
1033
+ return { isValid, strength, errors };
1034
+ };
1035
+ const isValidName = (name) => {
1036
+ return name.trim().length >= 2;
1037
+ };
1038
+ const isRequired = (value) => {
1039
+ return value.trim().length > 0;
1040
+ };
1041
+ const passwordsMatch = (password, confirmation) => {
1042
+ return password === confirmation;
1043
+ };
1044
+ const getInitials = (firstName, lastName) => {
1045
+ const first = firstName?.charAt(0).toUpperCase() || "";
1046
+ const last = lastName?.charAt(0).toUpperCase() || "";
1047
+ return first + last || "U";
1048
+ };
1049
+ const formatDate = (date) => {
1050
+ const d = typeof date === "string" ? new Date(date) : date;
1051
+ return d.toLocaleDateString("en-US", {
1052
+ year: "numeric",
1053
+ month: "long",
1054
+ day: "numeric"
1055
+ });
1056
+ };
1057
+ const debounce = (func, wait) => {
1058
+ let timeout;
1059
+ return (...args) => {
1060
+ clearTimeout(timeout);
1061
+ timeout = setTimeout(() => func(...args), wait);
1062
+ };
1063
+ };
1064
+ export {
1065
+ SoundEffects as S,
1066
+ preloadCriticalComponents as a,
1067
+ isValidName as b,
1068
+ isRequired as c,
1069
+ debouncedSetItem as d,
1070
+ passwordsMatch as e,
1071
+ formatDate as f,
1072
+ getInitials as g,
1073
+ debounce as h,
1074
+ isValidEmail as i,
1075
+ playLevelUp as p,
1076
+ slotHasContent as s,
1077
+ tailwindColors as t,
1078
+ useRequestCache as u,
1079
+ validatePassword as v
1080
+ };