@tsparticles/template-login 4.1.3 → 4.2.0

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 (68) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/README.md +3 -0
  3. package/package.json +4 -3
  4. package/template/angular/package.json +34 -0
  5. package/template/angular/src/app/app.component.css +151 -0
  6. package/template/angular/src/app/app.component.html +32 -0
  7. package/template/angular/src/app/app.component.ts +105 -0
  8. package/template/angular/src/app/app.module.ts +13 -0
  9. package/template/angular-confetti/package.json +36 -0
  10. package/template/angular-confetti/src/app/app.component.css +151 -0
  11. package/template/angular-confetti/src/app/app.component.html +32 -0
  12. package/template/angular-confetti/src/app/app.component.ts +105 -0
  13. package/template/angular-confetti/src/app/app.module.ts +13 -0
  14. package/template/angular-fireworks/package.json +36 -0
  15. package/template/angular-fireworks/src/app/app.component.css +151 -0
  16. package/template/angular-fireworks/src/app/app.component.html +32 -0
  17. package/template/angular-fireworks/src/app/app.component.ts +105 -0
  18. package/template/angular-fireworks/src/app/app.module.ts +13 -0
  19. package/template/astro/package.json +22 -0
  20. package/template/astro/src/pages/index.astro +173 -0
  21. package/template/ember/app/templates/application.hbs +61 -0
  22. package/template/ember/package.json +42 -0
  23. package/template/inferno/package.json +24 -0
  24. package/template/inferno/src/App.css +151 -0
  25. package/template/inferno/src/App.tsx +158 -0
  26. package/template/jquery/package.json +22 -0
  27. package/template/jquery/src/main.ts +110 -0
  28. package/template/jquery/src/style.css +151 -0
  29. package/template/lit/package.json +22 -0
  30. package/template/lit/src/my-app.ts +143 -0
  31. package/template/nextjs/package.json +25 -0
  32. package/template/nextjs/src/app/page.tsx +168 -0
  33. package/template/nextjs/src/app/providers.tsx +13 -0
  34. package/template/nuxt2/package.json +17 -0
  35. package/template/nuxt2/pages/index.vue +303 -0
  36. package/template/nuxt3/app.vue +288 -0
  37. package/template/nuxt3/package.json +21 -0
  38. package/template/nuxt4/app.vue +288 -0
  39. package/template/nuxt4/package.json +21 -0
  40. package/template/preact/package.json +23 -0
  41. package/template/preact/src/App.css +151 -0
  42. package/template/preact/src/App.tsx +140 -0
  43. package/template/qwik/package.json +22 -0
  44. package/template/qwik/src/App.tsx +139 -0
  45. package/template/react/package.json +19 -0
  46. package/template/react/src/App.css +151 -0
  47. package/template/react/src/App.tsx +140 -0
  48. package/template/riot/package.json +24 -0
  49. package/template/riot/src/app.riot +156 -0
  50. package/template/solid/package.json +18 -0
  51. package/template/solid/src/App.tsx +169 -0
  52. package/template/solid/src/index.css +151 -0
  53. package/template/solid/src/main.tsx +9 -0
  54. package/template/stencil/package.json +20 -0
  55. package/template/stencil/src/components/app-home/app-home.tsx +164 -0
  56. package/template/svelte/package.json +20 -0
  57. package/template/svelte/src/App.svelte +325 -0
  58. package/template/svelte/src/main.ts +12 -0
  59. package/template/vanilla/LICENSE +21 -0
  60. package/template/vanilla/src/main.ts +1 -1
  61. package/template/vue2/package.json +24 -0
  62. package/template/vue2/src/App.vue +287 -0
  63. package/template/vue3/package.json +19 -0
  64. package/template/vue3/src/App.vue +286 -0
  65. package/template/vue3/src/main.ts +14 -0
  66. package/template/webcomponents/package.json +21 -0
  67. package/template/webcomponents/src/main.ts +125 -0
  68. package/template/webcomponents/src/style.css +151 -0
@@ -0,0 +1,288 @@
1
+ <template>
2
+ <div>
3
+ <Particles id="tsparticles" :options="options" />
4
+ <div class="auth-container">
5
+ <div class="auth-card">
6
+ <div class="auth-header">
7
+ <h1>{{ isLogin ? 'Login' : 'Register' }}</h1>
8
+ <button class="theme-btn" @click="toggleTheme" aria-label="Toggle theme">{{ theme === 'dark' ? '🌙' : '☀️' }}</button>
9
+ </div>
10
+ <form @submit="handleSubmit" novalidate>
11
+ <div class="form-group">
12
+ <label for="email">Email</label>
13
+ <input id="email" v-model="email" type="email" placeholder="you@example.com" required />
14
+ <span class="error">{{ emailErr }}</span>
15
+ </div>
16
+ <div class="form-group">
17
+ <label for="password">Password</label>
18
+ <input id="password" v-model="password" type="password" placeholder="Enter password" required />
19
+ <span class="error">{{ passErr }}</span>
20
+ </div>
21
+ <div v-if="!isLogin" class="form-group">
22
+ <label for="confirmPassword">Confirm Password</label>
23
+ <input id="confirmPassword" v-model="confirm" type="password" placeholder="Confirm password" />
24
+ <span class="error">{{ confirmErr }}</span>
25
+ </div>
26
+ <button type="submit">{{ isLogin ? 'Sign In' : 'Create Account' }}</button>
27
+ </form>
28
+ <p class="toggle-text">
29
+ <span>{{ isLogin ? "Don't have an account?" : 'Already have an account?' }}</span>
30
+ <a href="#" @click="toggleMode">{{ isLogin ? 'Register' : 'Login' }}</a>
31
+ </p>
32
+ </div>
33
+ </div>
34
+ </div>
35
+ </template>
36
+
37
+ <script setup lang="ts">
38
+ import { ref, onMounted } from "vue";
39
+ import { loadSlim } from "@tsparticles/slim";
40
+ import type { ISourceOptions } from "@tsparticles/engine";
41
+
42
+ const isLogin = ref(true);
43
+ const theme = ref("dark");
44
+ const email = ref("");
45
+ const password = ref("");
46
+ const confirm = ref("");
47
+ const emailErr = ref("");
48
+ const passErr = ref("");
49
+ const confirmErr = ref("");
50
+
51
+ const options: ISourceOptions = {
52
+ background: { color: { value: "transparent" } },
53
+ fpsLimit: 60,
54
+ particles: {
55
+ number: { value: 60, density: { enable: true } },
56
+ color: { value: ["#6c5ce7", "#a29bfe", "#fd79a8", "#00cec9"] },
57
+ shape: { type: "circle" },
58
+ opacity: { value: 0.5, random: true },
59
+ size: { value: { min: 1, max: 3 }, random: true },
60
+ move: { enable: true, speed: 1, direction: "none", random: true, straight: false, outModes: { default: "out" } },
61
+ },
62
+ interactivity: {
63
+ events: { onHover: { enable: true, mode: "bubble" } },
64
+ modes: { bubble: { distance: 200, size: 6, duration: 2, opacity: 0.8 } },
65
+ },
66
+ detectRetina: true,
67
+ };
68
+
69
+ onMounted(() => {
70
+ const saved = localStorage.getItem("theme") || "dark";
71
+ theme.value = saved;
72
+ document.documentElement.setAttribute("data-theme", saved);
73
+ });
74
+
75
+ function toggleTheme(): void {
76
+ const t = theme.value === "dark" ? "light" : "dark";
77
+ theme.value = t;
78
+ document.documentElement.setAttribute("data-theme", t);
79
+ localStorage.setItem("theme", t);
80
+ }
81
+
82
+ function validateEmail(val: string): boolean {
83
+ return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(val);
84
+ }
85
+
86
+ function handleSubmit(e: Event): void {
87
+ e.preventDefault();
88
+ let valid = true;
89
+
90
+ if (!email.value || !validateEmail(email.value)) {
91
+ emailErr.value = "Please enter a valid email address";
92
+ valid = false;
93
+ } else {
94
+ emailErr.value = "";
95
+ }
96
+
97
+ if (!password.value || password.value.length < 6) {
98
+ passErr.value = "Password must be at least 6 characters";
99
+ valid = false;
100
+ } else {
101
+ passErr.value = "";
102
+ }
103
+
104
+ if (!isLogin.value) {
105
+ if (password.value !== confirm.value) {
106
+ confirmErr.value = "Passwords do not match";
107
+ valid = false;
108
+ } else {
109
+ confirmErr.value = "";
110
+ }
111
+ }
112
+
113
+ if (!valid) return;
114
+
115
+ if (isLogin.value) {
116
+ alert("Logged in successfully! (demo)");
117
+ } else {
118
+ alert("Account created successfully! (demo)");
119
+ isLogin.value = true;
120
+ }
121
+
122
+ email.value = "";
123
+ password.value = "";
124
+ confirm.value = "";
125
+ }
126
+
127
+ function toggleMode(e: Event): void {
128
+ e.preventDefault();
129
+ isLogin.value = !isLogin.value;
130
+ emailErr.value = "";
131
+ passErr.value = "";
132
+ confirmErr.value = "";
133
+ }
134
+ </script>
135
+
136
+ <style>
137
+ :root {
138
+ --bg: #0f0f1a;
139
+ --card-bg: rgba(255, 255, 255, 0.05);
140
+ --text: #fff;
141
+ --border: rgba(255, 255, 255, 0.1);
142
+ --input-bg: rgba(255, 255, 255, 0.08);
143
+ --accent: #6c5ce7;
144
+ --accent-hover: #a29bfe;
145
+ --error: #e74c3c;
146
+ }
147
+
148
+ [data-theme="light"] {
149
+ --bg: #f0f0f5;
150
+ --card-bg: rgba(255, 255, 255, 0.8);
151
+ --text: #1a1a2e;
152
+ --border: rgba(0, 0, 0, 0.1);
153
+ --input-bg: rgba(0, 0, 0, 0.05);
154
+ }
155
+
156
+ * {
157
+ box-sizing: border-box;
158
+ }
159
+
160
+ body {
161
+ margin: 0;
162
+ font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
163
+ background: var(--bg);
164
+ color: var(--text);
165
+ transition: background 0.3s, color 0.3s;
166
+ }
167
+
168
+ .auth-container {
169
+ position: absolute;
170
+ top: 50%;
171
+ left: 50%;
172
+ transform: translate(-50%, -50%);
173
+ z-index: 10;
174
+ width: 100%;
175
+ max-width: 400px;
176
+ padding: 1rem;
177
+ }
178
+
179
+ .auth-card {
180
+ background: var(--card-bg);
181
+ backdrop-filter: blur(10px);
182
+ border: 1px solid var(--border);
183
+ border-radius: 16px;
184
+ padding: 2rem;
185
+ box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
186
+ }
187
+
188
+ .auth-header {
189
+ display: flex;
190
+ justify-content: space-between;
191
+ align-items: center;
192
+ margin-bottom: 1.5rem;
193
+ }
194
+
195
+ .auth-header h1 {
196
+ margin: 0;
197
+ font-size: 1.8em;
198
+ }
199
+
200
+ .theme-btn {
201
+ background: none;
202
+ border: 1px solid var(--border);
203
+ border-radius: 8px;
204
+ padding: 0.4em 0.6em;
205
+ font-size: 1.2em;
206
+ cursor: pointer;
207
+ transition: background 0.2s;
208
+ }
209
+
210
+ .theme-btn:hover {
211
+ background: var(--input-bg);
212
+ }
213
+
214
+ .form-group {
215
+ margin-bottom: 1rem;
216
+ }
217
+
218
+ label {
219
+ display: block;
220
+ margin-bottom: 0.3em;
221
+ font-size: 0.9em;
222
+ opacity: 0.8;
223
+ }
224
+
225
+ input {
226
+ width: 100%;
227
+ padding: 0.7em 1em;
228
+ font-size: 1em;
229
+ border: 1px solid var(--border);
230
+ border-radius: 8px;
231
+ background: var(--input-bg);
232
+ color: var(--text);
233
+ outline: none;
234
+ transition: border-color 0.2s;
235
+ }
236
+
237
+ input:focus {
238
+ border-color: var(--accent);
239
+ }
240
+
241
+ input::placeholder {
242
+ color: var(--text);
243
+ opacity: 0.4;
244
+ }
245
+
246
+ .error {
247
+ display: block;
248
+ margin-top: 0.3em;
249
+ font-size: 0.8em;
250
+ color: var(--error);
251
+ min-height: 1em;
252
+ }
253
+
254
+ button[type="submit"] {
255
+ width: 100%;
256
+ padding: 0.8em;
257
+ font-size: 1em;
258
+ font-weight: 600;
259
+ border: none;
260
+ border-radius: 8px;
261
+ background: var(--accent);
262
+ color: #fff;
263
+ cursor: pointer;
264
+ transition: background 0.2s;
265
+ margin-top: 0.5rem;
266
+ }
267
+
268
+ button[type="submit"]:hover {
269
+ background: var(--accent-hover);
270
+ }
271
+
272
+ .toggle-text {
273
+ text-align: center;
274
+ margin-top: 1.5rem;
275
+ font-size: 0.9em;
276
+ opacity: 0.7;
277
+ }
278
+
279
+ .toggle-text a {
280
+ color: var(--accent);
281
+ text-decoration: none;
282
+ margin-left: 0.3em;
283
+ }
284
+
285
+ .toggle-text a:hover {
286
+ text-decoration: underline;
287
+ }
288
+ </style>
@@ -0,0 +1,21 @@
1
+ {
2
+ "name": "{{projectName}}",
3
+ "private": true,
4
+ "version": "1.0.0",
5
+ "type": "module",
6
+ "scripts": {
7
+ "dev": "nuxt dev",
8
+ "build": "nuxt build",
9
+ "preview": "nuxt preview"
10
+ },
11
+ "dependencies": {
12
+ "nuxt": "^3.17.3",
13
+ "@tsparticles/nuxt3": "^4.1.3",
14
+ "@tsparticles/slim": "^4.1.3",
15
+ "@tsparticles/configs": "^4.1.3",
16
+ "@tsparticles/engine": "^4.1.3"
17
+ },
18
+ "devDependencies": {
19
+ "typescript": "^6.0.3"
20
+ }
21
+ }
@@ -0,0 +1,288 @@
1
+ <template>
2
+ <div>
3
+ <Particles id="tsparticles" :options="options" />
4
+ <div class="auth-container">
5
+ <div class="auth-card">
6
+ <div class="auth-header">
7
+ <h1>{{ isLogin ? 'Login' : 'Register' }}</h1>
8
+ <button class="theme-btn" @click="toggleTheme" aria-label="Toggle theme">{{ theme === 'dark' ? '🌙' : '☀️' }}</button>
9
+ </div>
10
+ <form @submit="handleSubmit" novalidate>
11
+ <div class="form-group">
12
+ <label for="email">Email</label>
13
+ <input id="email" v-model="email" type="email" placeholder="you@example.com" required />
14
+ <span class="error">{{ emailErr }}</span>
15
+ </div>
16
+ <div class="form-group">
17
+ <label for="password">Password</label>
18
+ <input id="password" v-model="password" type="password" placeholder="Enter password" required />
19
+ <span class="error">{{ passErr }}</span>
20
+ </div>
21
+ <div v-if="!isLogin" class="form-group">
22
+ <label for="confirmPassword">Confirm Password</label>
23
+ <input id="confirmPassword" v-model="confirm" type="password" placeholder="Confirm password" />
24
+ <span class="error">{{ confirmErr }}</span>
25
+ </div>
26
+ <button type="submit">{{ isLogin ? 'Sign In' : 'Create Account' }}</button>
27
+ </form>
28
+ <p class="toggle-text">
29
+ <span>{{ isLogin ? "Don't have an account?" : 'Already have an account?' }}</span>
30
+ <a href="#" @click="toggleMode">{{ isLogin ? 'Register' : 'Login' }}</a>
31
+ </p>
32
+ </div>
33
+ </div>
34
+ </div>
35
+ </template>
36
+
37
+ <script setup lang="ts">
38
+ import { ref, onMounted } from "vue";
39
+ import { loadSlim } from "@tsparticles/slim";
40
+ import type { ISourceOptions } from "@tsparticles/engine";
41
+
42
+ const isLogin = ref(true);
43
+ const theme = ref("dark");
44
+ const email = ref("");
45
+ const password = ref("");
46
+ const confirm = ref("");
47
+ const emailErr = ref("");
48
+ const passErr = ref("");
49
+ const confirmErr = ref("");
50
+
51
+ const options: ISourceOptions = {
52
+ background: { color: { value: "transparent" } },
53
+ fpsLimit: 60,
54
+ particles: {
55
+ number: { value: 60, density: { enable: true } },
56
+ color: { value: ["#6c5ce7", "#a29bfe", "#fd79a8", "#00cec9"] },
57
+ shape: { type: "circle" },
58
+ opacity: { value: 0.5, random: true },
59
+ size: { value: { min: 1, max: 3 }, random: true },
60
+ move: { enable: true, speed: 1, direction: "none", random: true, straight: false, outModes: { default: "out" } },
61
+ },
62
+ interactivity: {
63
+ events: { onHover: { enable: true, mode: "bubble" } },
64
+ modes: { bubble: { distance: 200, size: 6, duration: 2, opacity: 0.8 } },
65
+ },
66
+ detectRetina: true,
67
+ };
68
+
69
+ onMounted(() => {
70
+ const saved = localStorage.getItem("theme") || "dark";
71
+ theme.value = saved;
72
+ document.documentElement.setAttribute("data-theme", saved);
73
+ });
74
+
75
+ function toggleTheme(): void {
76
+ const t = theme.value === "dark" ? "light" : "dark";
77
+ theme.value = t;
78
+ document.documentElement.setAttribute("data-theme", t);
79
+ localStorage.setItem("theme", t);
80
+ }
81
+
82
+ function validateEmail(val: string): boolean {
83
+ return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(val);
84
+ }
85
+
86
+ function handleSubmit(e: Event): void {
87
+ e.preventDefault();
88
+ let valid = true;
89
+
90
+ if (!email.value || !validateEmail(email.value)) {
91
+ emailErr.value = "Please enter a valid email address";
92
+ valid = false;
93
+ } else {
94
+ emailErr.value = "";
95
+ }
96
+
97
+ if (!password.value || password.value.length < 6) {
98
+ passErr.value = "Password must be at least 6 characters";
99
+ valid = false;
100
+ } else {
101
+ passErr.value = "";
102
+ }
103
+
104
+ if (!isLogin.value) {
105
+ if (password.value !== confirm.value) {
106
+ confirmErr.value = "Passwords do not match";
107
+ valid = false;
108
+ } else {
109
+ confirmErr.value = "";
110
+ }
111
+ }
112
+
113
+ if (!valid) return;
114
+
115
+ if (isLogin.value) {
116
+ alert("Logged in successfully! (demo)");
117
+ } else {
118
+ alert("Account created successfully! (demo)");
119
+ isLogin.value = true;
120
+ }
121
+
122
+ email.value = "";
123
+ password.value = "";
124
+ confirm.value = "";
125
+ }
126
+
127
+ function toggleMode(e: Event): void {
128
+ e.preventDefault();
129
+ isLogin.value = !isLogin.value;
130
+ emailErr.value = "";
131
+ passErr.value = "";
132
+ confirmErr.value = "";
133
+ }
134
+ </script>
135
+
136
+ <style>
137
+ :root {
138
+ --bg: #0f0f1a;
139
+ --card-bg: rgba(255, 255, 255, 0.05);
140
+ --text: #fff;
141
+ --border: rgba(255, 255, 255, 0.1);
142
+ --input-bg: rgba(255, 255, 255, 0.08);
143
+ --accent: #6c5ce7;
144
+ --accent-hover: #a29bfe;
145
+ --error: #e74c3c;
146
+ }
147
+
148
+ [data-theme="light"] {
149
+ --bg: #f0f0f5;
150
+ --card-bg: rgba(255, 255, 255, 0.8);
151
+ --text: #1a1a2e;
152
+ --border: rgba(0, 0, 0, 0.1);
153
+ --input-bg: rgba(0, 0, 0, 0.05);
154
+ }
155
+
156
+ * {
157
+ box-sizing: border-box;
158
+ }
159
+
160
+ body {
161
+ margin: 0;
162
+ font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
163
+ background: var(--bg);
164
+ color: var(--text);
165
+ transition: background 0.3s, color 0.3s;
166
+ }
167
+
168
+ .auth-container {
169
+ position: absolute;
170
+ top: 50%;
171
+ left: 50%;
172
+ transform: translate(-50%, -50%);
173
+ z-index: 10;
174
+ width: 100%;
175
+ max-width: 400px;
176
+ padding: 1rem;
177
+ }
178
+
179
+ .auth-card {
180
+ background: var(--card-bg);
181
+ backdrop-filter: blur(10px);
182
+ border: 1px solid var(--border);
183
+ border-radius: 16px;
184
+ padding: 2rem;
185
+ box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
186
+ }
187
+
188
+ .auth-header {
189
+ display: flex;
190
+ justify-content: space-between;
191
+ align-items: center;
192
+ margin-bottom: 1.5rem;
193
+ }
194
+
195
+ .auth-header h1 {
196
+ margin: 0;
197
+ font-size: 1.8em;
198
+ }
199
+
200
+ .theme-btn {
201
+ background: none;
202
+ border: 1px solid var(--border);
203
+ border-radius: 8px;
204
+ padding: 0.4em 0.6em;
205
+ font-size: 1.2em;
206
+ cursor: pointer;
207
+ transition: background 0.2s;
208
+ }
209
+
210
+ .theme-btn:hover {
211
+ background: var(--input-bg);
212
+ }
213
+
214
+ .form-group {
215
+ margin-bottom: 1rem;
216
+ }
217
+
218
+ label {
219
+ display: block;
220
+ margin-bottom: 0.3em;
221
+ font-size: 0.9em;
222
+ opacity: 0.8;
223
+ }
224
+
225
+ input {
226
+ width: 100%;
227
+ padding: 0.7em 1em;
228
+ font-size: 1em;
229
+ border: 1px solid var(--border);
230
+ border-radius: 8px;
231
+ background: var(--input-bg);
232
+ color: var(--text);
233
+ outline: none;
234
+ transition: border-color 0.2s;
235
+ }
236
+
237
+ input:focus {
238
+ border-color: var(--accent);
239
+ }
240
+
241
+ input::placeholder {
242
+ color: var(--text);
243
+ opacity: 0.4;
244
+ }
245
+
246
+ .error {
247
+ display: block;
248
+ margin-top: 0.3em;
249
+ font-size: 0.8em;
250
+ color: var(--error);
251
+ min-height: 1em;
252
+ }
253
+
254
+ button[type="submit"] {
255
+ width: 100%;
256
+ padding: 0.8em;
257
+ font-size: 1em;
258
+ font-weight: 600;
259
+ border: none;
260
+ border-radius: 8px;
261
+ background: var(--accent);
262
+ color: #fff;
263
+ cursor: pointer;
264
+ transition: background 0.2s;
265
+ margin-top: 0.5rem;
266
+ }
267
+
268
+ button[type="submit"]:hover {
269
+ background: var(--accent-hover);
270
+ }
271
+
272
+ .toggle-text {
273
+ text-align: center;
274
+ margin-top: 1.5rem;
275
+ font-size: 0.9em;
276
+ opacity: 0.7;
277
+ }
278
+
279
+ .toggle-text a {
280
+ color: var(--accent);
281
+ text-decoration: none;
282
+ margin-left: 0.3em;
283
+ }
284
+
285
+ .toggle-text a:hover {
286
+ text-decoration: underline;
287
+ }
288
+ </style>
@@ -0,0 +1,21 @@
1
+ {
2
+ "name": "{{projectName}}",
3
+ "private": true,
4
+ "version": "1.0.0",
5
+ "type": "module",
6
+ "scripts": {
7
+ "dev": "nuxt dev",
8
+ "build": "nuxt build",
9
+ "preview": "nuxt preview"
10
+ },
11
+ "dependencies": {
12
+ "nuxt": "^4.4.2",
13
+ "@tsparticles/nuxt4": "^4.1.3",
14
+ "@tsparticles/slim": "^4.1.3",
15
+ "@tsparticles/configs": "^4.1.3",
16
+ "@tsparticles/engine": "^4.1.3"
17
+ },
18
+ "devDependencies": {
19
+ "typescript": "^6.0.3"
20
+ }
21
+ }
@@ -0,0 +1,23 @@
1
+ {
2
+ "name": "{{projectName}}",
3
+ "private": true,
4
+ "version": "1.0.0",
5
+ "type": "module",
6
+ "scripts": {
7
+ "dev": "vite",
8
+ "build": "tsc && vite build",
9
+ "preview": "vite preview"
10
+ },
11
+ "dependencies": {
12
+ "preact": "^10.19.3",
13
+ "@tsparticles/preact": "^4.1.3",
14
+ "@tsparticles/slim": "^4.1.3",
15
+ "@tsparticles/configs": "^4.1.3",
16
+ "@tsparticles/engine": "^4.1.3"
17
+ },
18
+ "devDependencies": {
19
+ "@preact/preset-vite": "^2.8.1",
20
+ "typescript": "^5.7.2",
21
+ "vite": "^6.0.0"
22
+ }
23
+ }