eleven-solutions-common-website-unique-web 21.0.56 → 22.0.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 (61) hide show
  1. package/dist/App.d.ts +0 -3
  2. package/dist/App.js +0 -2
  3. package/dist/components/admin/Sidebar.d.ts +0 -1
  4. package/dist/components/admin/Sidebar.js +2 -2
  5. package/dist/components/admin/UserForm.js +6 -5
  6. package/dist/components/admin/Users.js +4 -3
  7. package/dist/components/footer/Footer.d.ts +3 -2
  8. package/dist/components/footer/Footer.js +2 -3
  9. package/dist/components/index.d.ts +3 -2
  10. package/dist/components/index.js +3 -2
  11. package/dist/components/login/GoogleButton.js +4 -1
  12. package/dist/components/login/Header.d.ts +3 -1
  13. package/dist/components/login/Header.js +135 -31
  14. package/dist/components/login/Login.d.ts +2 -1
  15. package/dist/components/login/Login.js +15 -65
  16. package/dist/components/login/Setcookie.d.ts +2 -0
  17. package/dist/components/login/Setcookie.js +7 -0
  18. package/dist/components/redux/slices/types/types.d.ts +3 -0
  19. package/dist/components/redux/slices/types/types.js +1 -0
  20. package/dist/components/redux/slices/userSlice.d.ts +20 -0
  21. package/dist/components/redux/slices/userSlice.js +90 -0
  22. package/dist/components/useraccount/UpdateUserDetails.d.ts +1 -0
  23. package/dist/components/useraccount/UpdateUserDetails.js +15 -22
  24. package/package.json +9 -4
  25. package/.github/workflows/main.yml +0 -22
  26. package/azure-pipelines.yml +0 -20
  27. package/dist/components/Navbar.d.ts +0 -6
  28. package/dist/components/Navbar.js +0 -5
  29. package/dist/components/login/View.d.ts +0 -2
  30. package/dist/components/login/View.js +0 -10
  31. package/dist/components/useraccount/AddMissingDetails.d.ts +0 -9
  32. package/dist/components/useraccount/AddMissingDetails.js +0 -56
  33. package/dist/components/useraccount/AddUserDetails.d.ts +0 -9
  34. package/dist/components/useraccount/AddUserDetails.js +0 -21
  35. package/src/App.tsx +0 -21
  36. package/src/components/Navbar.tsx +0 -21
  37. package/src/components/admin/Dashboard.tsx +0 -7
  38. package/src/components/admin/Editor.tsx +0 -25
  39. package/src/components/admin/Sidebar.tsx +0 -102
  40. package/src/components/admin/Taxionomies.tsx +0 -314
  41. package/src/components/admin/TaxonomyForm.tsx +0 -744
  42. package/src/components/admin/Template.tsx +0 -304
  43. package/src/components/admin/TemplateForm.tsx +0 -141
  44. package/src/components/admin/UserForm.tsx +0 -231
  45. package/src/components/admin/Users.tsx +0 -479
  46. package/src/components/api/api.ts +0 -59
  47. package/src/components/api/taxonomy.ts +0 -201
  48. package/src/components/api/template.ts +0 -114
  49. package/src/components/api/updateuser.ts +0 -53
  50. package/src/components/api/user.ts +0 -133
  51. package/src/components/footer/Footer.tsx +0 -128
  52. package/src/components/footer/Privacy.tsx +0 -82
  53. package/src/components/footer/Terms.tsx +0 -156
  54. package/src/components/index.ts +0 -19
  55. package/src/components/login/GoogleButton.tsx +0 -85
  56. package/src/components/login/Header.tsx +0 -340
  57. package/src/components/login/Login.tsx +0 -277
  58. package/src/components/useraccount/AddUserDetails.tsx +0 -136
  59. package/src/components/useraccount/UpdateUserDetails.tsx +0 -214
  60. package/src/index.ts +0 -1
  61. package/tsconfig.json +0 -15
@@ -1,479 +0,0 @@
1
- import React from "react";
2
- import { useState, useEffect } from "react";
3
-
4
- import { FaPlus } from "react-icons/fa";
5
-
6
- import { fetchUsersApi, deleteUserApi } from "../api/user";
7
-
8
- interface UsersProps {
9
- url: string;
10
- }
11
-
12
- const Users = ({ url }: UsersProps) => {
13
- const [users, setUsers] = useState<any[]>([]);
14
- const [searchTerm, setSearchTerm] = useState<string>("");
15
-
16
- const [filterModal, setFilterModal] = useState(false);
17
- const [selectedRoleType, setSelectedRoleType] = useState<string>("");
18
-
19
- const fetchUsersData = async () => {
20
- const data = await fetchUsersApi(url);
21
- if (data) {
22
- setUsers(data as any[]);
23
- } else {
24
- console.error("Failed to fetch users");
25
- }
26
- };
27
-
28
- useEffect(() => {
29
- fetchUsersData();
30
- }, []);
31
-
32
- const handleNavigation = (event: React.MouseEvent, path: string) => {
33
- event.preventDefault();
34
- window.history.pushState({}, "", path);
35
- window.dispatchEvent(new PopStateEvent("popstate"));
36
- };
37
-
38
- const [currentPage, setCurrentPage] = useState(1);
39
- const itemsPerPage = 10;
40
-
41
- const filteredUsers = users.filter((user) => {
42
- const matchesSearch =
43
- searchTerm.length < 2 ||
44
- user.name?.toLowerCase().includes(searchTerm) ||
45
- user.email?.toLowerCase().includes(searchTerm) ||
46
- user.mobile?.toString().includes(searchTerm);
47
-
48
- const matchesRoleType =
49
- selectedRoleType === "" ||
50
- user.roleType === parseInt(selectedRoleType, 10);
51
-
52
- return matchesSearch && matchesRoleType;
53
- });
54
-
55
- const handleRoleTypeChange = (
56
- event: React.ChangeEvent<HTMLSelectElement>
57
- ) => {
58
- setSelectedRoleType(event.target.value);
59
- setCurrentPage(1);
60
- };
61
-
62
- const resetFilter = () => {
63
- setSelectedRoleType("");
64
- };
65
-
66
- const totalPages = Math.ceil(filteredUsers.length / itemsPerPage);
67
-
68
- const handleNextPage = () => {
69
- if (currentPage < totalPages) {
70
- setCurrentPage(currentPage + 1);
71
- }
72
- };
73
-
74
- const handlePreviousPage = () => {
75
- if (currentPage > 1) {
76
- setCurrentPage(currentPage - 1);
77
- }
78
- };
79
-
80
- const handlePageClick = (pageNumber: number) => {
81
- setCurrentPage(pageNumber);
82
- };
83
-
84
- const paginatedUsers = filteredUsers.slice(
85
- (currentPage - 1) * itemsPerPage,
86
- currentPage * itemsPerPage
87
- );
88
-
89
- const handleDeleteClick = async (id: string) => {
90
- try {
91
- await deleteUserApi(url, id);
92
- alert("User deleted successfully");
93
-
94
- fetchUsersData();
95
- } catch (error) {
96
- console.error("Error deleting User:", error);
97
- }
98
- };
99
-
100
- const handleEditClick = (
101
- event: React.MouseEvent,
102
- path: string,
103
- id: string
104
- ) => {
105
- event.preventDefault();
106
- window.history.pushState({}, "", path + id);
107
- window.dispatchEvent(new PopStateEvent("popstate"));
108
- };
109
-
110
- const handleSearchChange = (event: React.ChangeEvent<HTMLInputElement>) => {
111
- const value = event.target.value.toLowerCase();
112
- setSearchTerm(value);
113
- if (value.length < 2) {
114
- setCurrentPage(1);
115
- }
116
- };
117
-
118
- const handleSearchSubmit = (event: React.FormEvent<HTMLFormElement>) => {
119
- event.preventDefault();
120
- setCurrentPage(1);
121
- };
122
- return (
123
- <div className="container px-4 mx-auto mt-6">
124
- <div className="w-3/4">
125
- <h1 className="text-3xl font-bold text-blue-600 mb-5">Users</h1>
126
- </div>
127
- <div className="flex items-center w-full">
128
- <form className="flex-grow" onSubmit={handleSearchSubmit}>
129
- <label
130
- htmlFor="default-search"
131
- className="mb-2 text-sm font-medium text-gray-900 sr-only dark:text-white"
132
- >
133
- Search
134
- </label>
135
- <div className="relative">
136
- <div className="absolute inset-y-0 start-0 flex items-center ps-3 pointer-events-none">
137
- <svg
138
- className="w-4 h-4 text-gray-500 dark:text-gray-400"
139
- aria-hidden="true"
140
- xmlns="http://www.w3.org/2000/svg"
141
- fill="none"
142
- viewBox="0 0 20 20"
143
- >
144
- <path
145
- stroke="currentColor"
146
- strokeLinecap="round"
147
- strokeLinejoin="round"
148
- strokeWidth="2"
149
- d="m19 19-4-4m0-7A7 7 0 1 1 1 8a7 7 0 0 1 14 0Z"
150
- />
151
- </svg>
152
- </div>
153
- <input
154
- type="search"
155
- id="default-search"
156
- className="w-full p-3 ps-10 outline-none text-sm text-gray-900 border border-gray-300 rounded-lg bg-gray-50 focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
157
- placeholder="Search by Name, Email or Mobile"
158
- value={searchTerm}
159
- onChange={handleSearchChange}
160
- required
161
- />
162
- <button
163
- type="button"
164
- className="text-white absolute end-1.5 bottom-1.5 bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm px-4 py-2 dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800"
165
- >
166
- Search
167
- </button>
168
- </div>
169
- </form>
170
- <button
171
- onClick={() => setFilterModal(true)}
172
- className="ml-5 text-white bg-blue-700 hover:bg-blue-800 focus:ring-2 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm px-4 py-2 dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800"
173
- aria-label="Toggle Menu"
174
- >
175
- <svg
176
- xmlns="http://www.w3.org/2000/svg"
177
- width="24"
178
- height="24"
179
- viewBox="0 0 24 24"
180
- fill="none"
181
- stroke="currentColor"
182
- strokeWidth="2"
183
- strokeLinecap="round"
184
- strokeLinejoin="round"
185
- className="icon icon-tabler icons-tabler-outline icon-tabler-filter"
186
- >
187
- <path stroke="none" d="M0 0h24v24H0z" fill="none" />
188
- <path d="M4 4h16v2.172a2 2 0 0 1 -.586 1.414l-4.414 4.414v7l-6 2v-8.5l-4.48 -4.928a2 2 0 0 1 -.52 -1.345v-2.227z" />
189
- </svg>
190
- </button>
191
- </div>
192
-
193
- <div className="flex-grow ml-0 w-3/4">
194
- <form className="w-auto">{/* Search Form */}</form>
195
- </div>
196
- <div className="flex-grow ml-0 mt-4 w-full">
197
- <div className="overflow-hidden border border-gray-200 dark:border-gray-700 md:rounded-lg mt-6">
198
- <table className="min-w-full divide-y divide-gray-200 dark:divide-gray-700">
199
- <thead className="bg-gray-50 dark:bg-gray-800">
200
- <tr>
201
- <th
202
- scope="col"
203
- className="px-4 py-3.5 text-md font-normal text-left rtl:text-right text-gray-500 dark:text-gray-400"
204
- >
205
- Actions
206
- </th>
207
- <th
208
- scope="col"
209
- className="py-3.5 px-4 text-md font-normal text-left rtl:text-right text-gray-500 dark:text-gray-400"
210
- >
211
- <div className="flex items-center gap-x-3">
212
- <span>Name</span>
213
- </div>
214
- </th>
215
-
216
- <th
217
- scope="col"
218
- className="px-4 py-3.5 text-md font-normal text-left rtl:text-right text-gray-500 dark:text-gray-400"
219
- >
220
- <button className="flex items-center gap-x-2">
221
- <span>Email</span>
222
- </button>
223
- </th>
224
-
225
- <th
226
- scope="col"
227
- className="px-4 py-3.5 text-md font-normal text-left rtl:text-right text-gray-500 dark:text-gray-400"
228
- >
229
- <button className="flex items-center gap-x-2">
230
- <span>Mobile</span>
231
- </button>
232
- </th>
233
-
234
- <th
235
- scope="col"
236
- className="px-4 py-3.5 text-md font-normal text-left rtl:text-right text-gray-500 dark:text-gray-400"
237
- >
238
- Address
239
- </th>
240
-
241
- <th
242
- scope="col"
243
- className="px-4 py-3.5 text-md font-normal text-left rtl:text-right text-gray-500 dark:text-gray-400"
244
- >
245
- Gender
246
- </th>
247
- <th
248
- scope="col"
249
- className="px-4 py-3.5 text-md font-normal text-left rtl:text-right text-gray-500 dark:text-gray-400"
250
- >
251
- Role Type
252
- </th>
253
- <th
254
- scope="col"
255
- className="px-4 py-3.5 text-md font-normal text-left rtl:text-right text-gray-500 dark:text-gray-400"
256
- >
257
- Registered On
258
- </th>
259
- </tr>
260
- </thead>
261
- <tbody className="bg-white divide-y divide-gray-200 dark:divide-gray-700 dark:bg-gray-900">
262
- {paginatedUsers.map((user, index) => (
263
- <tr key={user.id || index}>
264
- <td className="px-4 py-4 text-sm whitespace-nowrap">
265
- <div className="flex items-center gap-x-6">
266
- <button
267
- onClick={() => handleDeleteClick(user.id)}
268
- className="text-gray-500 transition-colors duration-200 dark:hover:text-red-600 dark:text-gray-300 hover:text-red-500 focus:outline-none"
269
- >
270
- <svg
271
- xmlns="http://www.w3.org/2000/svg"
272
- fill="none"
273
- viewBox="0 0 24 24"
274
- stroke-width="1.5"
275
- stroke="currentColor"
276
- className="w-5 h-5"
277
- >
278
- <path
279
- stroke-linecap="round"
280
- stroke-linejoin="round"
281
- d="M14.74 9l-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 01-2.244 2.077H8.084a2.25 2.25 0 01-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 00-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 013.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 00-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 00-7.5 0"
282
- />
283
- </svg>
284
- </button>
285
-
286
- <button
287
- onClick={(event) =>
288
- handleEditClick(
289
- event,
290
- "/admin/users/userform?id=",
291
- user.id
292
- )
293
- }
294
- className="text-gray-500 transition-colors duration-200 dark:hover:text-yellow-500 dark:text-gray-300 hover:text-yellow-500 focus:outline-none"
295
- >
296
- <svg
297
- xmlns="http://www.w3.org/2000/svg"
298
- fill="none"
299
- viewBox="0 0 24 24"
300
- strokeWidth="1.5"
301
- stroke="currentColor"
302
- className="w-5 h-5"
303
- >
304
- <path
305
- strokeLinecap="round"
306
- strokeLinejoin="round"
307
- d="M16.862 4.487l1.687-1.688a1.875 1.875 0 112.652 2.652L10.582 16.07a4.5 4.5 0 01-1.897 1.13L6 18l.8-2.685a4.5 4.5 0 011.13-1.897l8.932-8.931zm0 0L19.5 7.125M18 14v4.75A2.25 2.25 0 0115.75 21H5.25A2.25 2.25 0 013 18.75V8.25A2.25 2.25 0 015.25 6H10"
308
- />
309
- </svg>
310
- </button>
311
- </div>
312
- </td>
313
- <td className="px-4 py-4 text-sm font-medium text-gray-700 whitespace-nowrap">
314
- <div className="inline-flex items-center gap-x-3">
315
- <div className="flex items-center gap-x-2">
316
- <div>
317
- <h2 className=" text-sm font-medium text-gray-800 dark:text-white ">
318
- {user.name}
319
- </h2>
320
- </div>
321
- </div>
322
- </div>
323
- </td>
324
- <td className="px-4 py-4 text-sm text-gray-500 dark:text-gray-300 whitespace-nowrap">
325
- {user.email}
326
- </td>
327
- <td className="px-4 py-4 text-sm text-gray-500 dark:text-gray-300 whitespace-nowrap">
328
- {user.mobile}
329
- </td>
330
- <td className="px-4 py-4 text-sm text-gray-500 dark:text-gray-300 whitespace-nowrap">
331
- {user.address}
332
- </td>
333
- <td className="px-4 py-4 text-sm text-gray-500 dark:text-gray-300 whitespace-nowrap">
334
- {user.gender != null
335
- ? user.gender === 1
336
- ? "Male"
337
- : "Female"
338
- : "Not Provided"}
339
- </td>
340
- <td className="px-4 py-4 text-sm text-gray-500 dark:text-gray-300 whitespace-nowrap">
341
- {user.roleType === 1 ? "Guest" : "Admin"}
342
- </td>
343
- <td className="px-4 py-4 text-sm text-gray-500 dark:text-gray-300 whitespace-nowrap">
344
- {/* {user.createdOn} */}
345
- {new Date(user.createdOn).toLocaleDateString("en-GB", {
346
- day: "2-digit",
347
- month: "2-digit",
348
- year: "numeric",
349
- })}
350
- </td>
351
- </tr>
352
- ))}
353
- </tbody>
354
- </table>
355
- </div>
356
-
357
- <div className="flex items-center justify-between mt-6">
358
- <button
359
- onClick={handlePreviousPage}
360
- disabled={currentPage === 1}
361
- className="flex items-center px-5 py-2 text-sm text-gray-700 capitalize transition-colors duration-200 bg-white border rounded-md gap-x-2 hover:bg-gray-100 dark:bg-gray-900 dark:text-gray-200 dark:border-gray-700 dark:hover:bg-gray-800"
362
- >
363
- <svg
364
- xmlns="http://www.w3.org/2000/svg"
365
- fill="none"
366
- viewBox="0 0 24 24"
367
- stroke-width="1.5"
368
- stroke="currentColor"
369
- className="w-5 h-5 rtl:-scale-x-100"
370
- >
371
- <path
372
- stroke-linecap="round"
373
- stroke-linejoin="round"
374
- d="M6.75 15.75L3 12m0 0l3.75-3.75M3 12h18"
375
- />
376
- </svg>
377
-
378
- <span>previous</span>
379
- </button>
380
-
381
- <div className="items-center hidden lg:flex gap-x-3">
382
- {Array.from({ length: totalPages }, (_, index) => (
383
- <button
384
- key={index + 1}
385
- onClick={() => handlePageClick(index + 1)}
386
- className={`px-2 py-1 text-sm ${
387
- currentPage === index + 1
388
- ? "text-blue-500 bg-blue-100"
389
- : "text-gray-500 hover:bg-gray-100"
390
- } rounded-md`}
391
- >
392
- {index + 1}
393
- </button>
394
- ))}
395
- </div>
396
- <button
397
- onClick={handleNextPage}
398
- disabled={currentPage === totalPages}
399
- className="flex items-center px-5 py-2 text-sm text-gray-700 capitalize transition-colors duration-200 bg-white border rounded-md gap-x-2 hover:bg-gray-100 dark:bg-gray-900 dark:text-gray-200 dark:border-gray-700 dark:hover:bg-gray-800"
400
- >
401
- <span>Next</span>
402
-
403
- <svg
404
- xmlns="http://www.w3.org/2000/svg"
405
- fill="none"
406
- viewBox="0 0 24 24"
407
- stroke-width="1.5"
408
- stroke="currentColor"
409
- className="w-5 h-5 rtl:-scale-x-100"
410
- >
411
- <path
412
- stroke-linecap="round"
413
- stroke-linejoin="round"
414
- d="M17.25 8.25L21 12m0 0l-3.75 3.75M21 12H3"
415
- />
416
- </svg>
417
- </button>
418
- </div>
419
-
420
- <div className="flex-grow ml-0 mt-4 w-0">
421
- <button
422
- type="button"
423
- onClick={(event) =>
424
- handleNavigation(event, "/admin/users/userform")
425
- }
426
- className="flex items-center justify-center px-6 py-2 font-medium tracking-wide text-white capitalize transition-colors duration-300 transform bg-blue-600 rounded-lg hover:bg-blue-500 focus:outline-none focus:ring focus:ring-blue-300 focus:ring-opacity-80"
427
- >
428
- <FaPlus className="mr-2 font-medium" />
429
- User
430
- </button>
431
- </div>
432
- </div>
433
- <div className="inset-0 bg-gray-800 bg-opacity-50 z-50 transition-opacity duration-300">
434
- <div
435
- className={`fixed top-0 right-0 h-full w-[300px] bg-white p-4 rounded-md shadow-lg transform transition-transform duration-500 ease-in-out
436
- ${filterModal ? "translate-x-0" : "translate-x-full"}`}
437
- >
438
- <h1 className="text-2xl md:text-3xl font-bold text-blue-600 mb-4 md:mb-6">
439
- Filter
440
- </h1>
441
- <button
442
- onClick={() => setFilterModal(false)}
443
- className="absolute top-1 right-3 text-gray-400 hover:text-gray-600 text-2xl"
444
- >
445
- &times;
446
- </button>
447
-
448
- <div className="flex flex-col">
449
- <div className="mb-4 flex flex-col">
450
- <label className="block text-gray-700 mb-2">Role Type</label>
451
- <div className="w-full">
452
- <select
453
- value={Number(selectedRoleType)}
454
- onChange={handleRoleTypeChange}
455
- required
456
- className="w-full px-4 py-2 text-gray-800 bg-white border border-gray-400 rounded-md dark:bg-gray-800 dark:text-gray-300 dark:border-gray-800 focus:border-blue-400 focus:ring-blue-300 focus:ring-opacity-40 dark:focus:border-blue-300 focus:outline-none focus:ring"
457
- >
458
- <option value="">All</option>
459
- <option value="1">Guest</option>
460
- <option value="2">Admin</option>
461
- </select>
462
- </div>
463
- </div>
464
- <div className="flex flex-row gap-3">
465
- <button
466
- onClick={resetFilter}
467
- className="mt-2 px-4 py-2 bg-blue-500 text-white rounded-md w-32"
468
- >
469
- Reset
470
- </button>
471
- </div>
472
- </div>
473
- </div>
474
- </div>
475
- </div>
476
- );
477
- };
478
-
479
- export default Users;
@@ -1,59 +0,0 @@
1
- import axios from "axios";
2
- import Cookies from "universal-cookie";
3
- const cookies = new Cookies();
4
- // const token = cookies.get("authToken");
5
- interface AuthResponse {
6
- token: string;
7
- }
8
- export const registerApi = async (
9
- url: string,
10
- name: string,
11
- email: string,
12
- mobile: string,
13
- password: string
14
- ) => {
15
- try {
16
- const response = await axios.post<AuthResponse>(`${url}/login/Create`, {
17
- LoginType: 1,
18
- name,
19
- email,
20
- mobile,
21
- password,
22
- });
23
- cookies.set("authToken", response.data.token, { maxAge: 86400 });
24
- // console.log("registering", response);
25
- return response;
26
- } catch (error) {
27
- console.error("Error during API call:", error);
28
- throw error;
29
- }
30
- };
31
- export const loginApi = async (
32
- url: string,
33
- email: string,
34
- password: string
35
- ) => {
36
- try {
37
- const response = await axios.post<AuthResponse>(`${url}/login`, {
38
- Type: 1,
39
- email,
40
- password,
41
- });
42
-
43
- if (response.status === 200 && response.data?.token) {
44
- // console.log(response.data);
45
- cookies.set("authToken", response.data.token, { maxAge: 86400 });
46
-
47
- return response;
48
- } else {
49
- return false;
50
- }
51
- } catch (error: any) {
52
- if (error.response) {
53
- return error.response.data;
54
- } else {
55
- console.error("Login error:", error);
56
- return false;
57
- }
58
- }
59
- };