identity-admin 1.9.1 → 1.10.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 (30) hide show
  1. package/lib/controllers/DashboardController.d.ts +1 -1
  2. package/lib/controllers/DashboardController.js +20 -6
  3. package/lib/helpers/ResourceHelper.d.ts +4 -0
  4. package/lib/helpers/ResourceHelper.js +75 -12
  5. package/lib/locales/en.json +2 -1
  6. package/lib/router/index.js +3 -0
  7. package/lib/types/IResourceFile.d.ts +268 -80
  8. package/lib/types/IResourceResponse.d.ts +99 -0
  9. package/lib/types/IResourceResponse.js +2 -0
  10. package/lib/types/helpers.d.ts +12 -0
  11. package/lib/types/helpers.js +14 -1
  12. package/lib/view/asset-manifest.json +13 -8
  13. package/lib/view/index.html +52 -1
  14. package/lib/view/static/css/main.54de06ef.css +2 -0
  15. package/lib/view/static/css/main.54de06ef.css.map +1 -0
  16. package/lib/view/static/js/{148.b05fe2c8.chunk.js → 574.778b5963.chunk.js} +2 -1
  17. package/lib/view/static/js/574.778b5963.chunk.js.map +1 -0
  18. package/lib/view/static/js/678.521704a3.chunk.js +2 -0
  19. package/lib/view/static/js/678.521704a3.chunk.js.map +1 -0
  20. package/lib/view/static/js/798.54856416.chunk.js +2 -0
  21. package/lib/view/static/js/798.54856416.chunk.js.map +1 -0
  22. package/lib/view/static/js/admin.js +1 -0
  23. package/lib/view/static/js/main.4687f255.js +3 -0
  24. package/lib/view/static/js/{main.da8f09ec.js.LICENSE.txt → main.4687f255.js.LICENSE.txt} +4 -15
  25. package/lib/view/static/js/main.4687f255.js.map +1 -0
  26. package/package.json +1 -1
  27. package/lib/view/static/css/main.18dca458.css +0 -1
  28. package/lib/view/static/js/705.f86db82e.chunk.js +0 -1
  29. package/lib/view/static/js/802.3f287a2c.chunk.js +0 -1
  30. package/lib/view/static/js/main.da8f09ec.js +0 -2
@@ -1,71 +1,72 @@
1
1
  import { Request } from "express";
2
2
  import { Document, Model } from "mongoose";
3
3
  import { IRequest } from "../middlewares/isAuth";
4
- import { ActionTypes, FieldTypes, Virtuals } from "./helpers";
4
+ import { IRepository } from "../repositories/Repository";
5
+ import { ActionNames, ActionTypes, FieldTypes, FileTypes, Virtuals } from "./helpers";
5
6
  declare type orderTypes = 'asc' | 'desc';
6
7
  declare type VirtualFieldTypes = 'password' | 'ref' | 'Array';
7
8
  declare type Severity = 'success' | 'info' | 'warning' | 'error';
8
- interface IAutoScope {
9
- /**
10
- * Key of property as specified in the database
11
- */
12
- key: string;
13
- /**
14
- * Array of values that this key can have
15
- */
16
- options: string[];
17
- }
18
- interface IManualScope {
19
- /**
20
- * Array of values that will be appeared in the scope
21
- */
22
- options: string[];
23
- /**
24
- * A handler that will be called when scope filter is used. This handler should perform a switch case on the specified options values, each case set the filter on its way.
25
- */
26
- handler: (filter: {
27
- [key: string]: any;
28
- }, scope: string) => {
29
- [key: string]: any;
30
- };
31
- }
32
9
  interface Parent {
33
10
  /**
34
- * Name of the parent
35
- */
11
+ * Name of the parent
12
+ */
36
13
  name: string;
37
14
  /**
38
- * Icon of the parent. You can get the icons from
39
- * @link https://mui.com/material-ui/material-icons/
40
- */
15
+ * Icon of the parent. You can get the icons from
16
+ * {@link https://mui.com/material-ui/material-icons/}
17
+ */
41
18
  icon: string;
42
19
  }
43
20
  interface Action {
44
21
  /**
45
- * Specify if this action is accessible or not.
46
- * @default True is the default for show, edit, delete, and new while false for bulk delete. You can ovveride any of these values here.
47
- */
22
+ * Specify if this action is accessible or not.
23
+ * @default True for show, edit, delete, and new.
24
+ * @default false for bulk delete.
25
+ * You can ovveride any of these values here.
26
+ */
48
27
  isAccessible?: boolean;
49
28
  }
50
29
  interface ICrudOperations {
51
30
  index?: {
52
31
  /**
53
- * Before handler that gives you the access to the filter object. You can add to the filter object any key and value that will be used in the filter query before getting the records for list. You should return the filter object
54
- */
55
- before: (req: IRequest, filter: {
32
+ * Before handler that gives you the access to the filter object.
33
+ * You can add to the filter object any key and value that will be used in the filter query before getting the records for list.
34
+ * @returns the filter object
35
+ */
36
+ before?: (req: IRequest, filter: {
56
37
  [key: string]: any;
57
- }, currentUser: Document) => {
38
+ }, currentUser: Document) => Promise<{
58
39
  [key: string]: any;
59
- };
40
+ }>;
41
+ /**
42
+ * After handler that gives you the access to the array of documents.
43
+ * @returns the array of documents
44
+ */
45
+ after?: (req: IRequest, documents: Document[], currentUser: Document) => Promise<Document[]>;
60
46
  };
61
47
  create?: {
62
48
  /**
63
- * Before handler that is called before creating a new record. This function gives you the access to the record params before saving it, you can perform any update to the params before saving it. This function should return the params
64
- */
65
- before: (req: IRequest, params: any, currentUser: Document) => any;
49
+ * Before handler that is called before creating a new record.
50
+ * This function gives you the access to the record params before saving it, you can perform any update to the params before saving it.
51
+ * @returns the params
52
+ */
53
+ before?: (req: IRequest, params: any, currentUser: Document) => Promise<any>;
54
+ /**
55
+ * After handler that gives you the access to the saved document.
56
+ * @returns the saved document
57
+ */
58
+ after?: (req: IRequest, document: Document, currentUser: Document) => Promise<Document>;
59
+ };
60
+ update?: {
61
+ /**
62
+ * Before handler that is called before updating a record.
63
+ * This function gives you the access to the record params before saving it, you can perform any update to the params before saving it.
64
+ * @returns the params
65
+ */
66
+ before?: (req: IRequest, params: any, currentUser: Document) => Promise<any>;
66
67
  };
67
68
  show?: {
68
- after: (req: IRequest, record: Document) => Promise<{
69
+ after?: (req: IRequest, record: Document) => Promise<{
69
70
  record: Document;
70
71
  [key: string]: any;
71
72
  }>;
@@ -73,74 +74,154 @@ interface ICrudOperations {
73
74
  }
74
75
  export interface ActionData {
75
76
  /**
76
- * Record document
77
- */
77
+ * Record document
78
+ */
78
79
  record: any;
79
80
  /**
80
- * Current user data
81
- */
81
+ * Current user data
82
+ */
82
83
  currentUser: Document;
83
84
  /**
84
- * Resource data to which this record belongs
85
- */
85
+ * Resource data to which this record belongs
86
+ */
86
87
  resource: {
87
88
  /**
88
- * Model name of this table.
89
- */
89
+ * Model name of this table.
90
+ */
90
91
  name: string;
91
92
  /**
92
- * Path of the resource to which you can redirect.
93
- */
93
+ * Path of the resource to which you can redirect.
94
+ */
94
95
  path: string;
95
96
  /**
96
- * Repository of this resource.
97
- */
98
- repository: any;
97
+ * Repository of this resource.
98
+ */
99
+ repository: IRepository<Document>;
99
100
  };
100
101
  }
101
102
  interface IFilters {
102
103
  /**
103
- * Scope filter props. If used you should override the scope filter function in the controller of this resource. This filter is not accessible by default
104
- */
104
+ * Scope filter props.
105
+ * Can be either auto or manual. It cannot be both.
106
+ * This filter is not accessible by default
107
+ */
105
108
  scopes?: {
106
109
  /**
107
110
  * Specify if this filter is accessible or not
111
+ * @default false
108
112
  */
109
113
  isAccessible: boolean;
110
114
  /**
111
- * Automatic scope that filters by the specified key with one of the given options
112
- */
115
+ * Automatic scope that filters by the specified key with one of the given options
116
+ * This filter works automatically by mentioning the key as saved in the database along with the values that this key can has.
117
+ * It doesn't need a handler
118
+ */
113
119
  auto?: IAutoScope;
114
120
  /**
115
- * Manual scope by using a handler
116
- */
121
+ * Manual scope by using a handler.
122
+ * In this case you can put the options you like with specifying in the handler what to do with each option.
123
+ */
117
124
  manual?: IManualScope;
118
125
  };
126
+ /**
127
+ * Search bar filter props
128
+ */
119
129
  searchBar?: {
130
+ /**
131
+ * Specify if this filter is accessible or not
132
+ * @default true
133
+ */
120
134
  isAccessible: boolean;
121
135
  };
122
136
  }
137
+ interface IAutoScope {
138
+ /**
139
+ * Key of property as specified in the database
140
+ */
141
+ key: string;
142
+ /**
143
+ * Array of values that this key can have
144
+ */
145
+ options: string[];
146
+ }
147
+ interface IManualScope {
148
+ /**
149
+ * Array of values that will be appeared in the scope
150
+ */
151
+ options: string[];
152
+ /**
153
+ * A handler that will be called when scope filter is used.
154
+ * This handler should perform a switch case on the specified options values, each case set the filter on its way.
155
+ */
156
+ handler: (filter: {
157
+ [key: string]: any;
158
+ }, scope: string) => Promise<{
159
+ [key: string]: any;
160
+ }>;
161
+ }
123
162
  export interface IFieldValue {
163
+ /**
164
+ * If the field is required in the schema and you don't want it to be required in the form, you can override this here.
165
+ * @default 'same as schema'
166
+ */
124
167
  required?: boolean;
168
+ /**
169
+ * Specify either this field can be edited or not.
170
+ * @default true
171
+ */
125
172
  isEditable?: boolean;
126
- type?: string;
127
173
  /**
128
- * Specify the allowed country codes. Only mandatory if the type is phone number
129
- * Alert message appear after executing this action.
130
- * ex: ["sa", "eg", ...]
131
- */
174
+ * Specify the type of the field. Can be used for specifying localized string, image,... etc.
175
+ * @default 'Same as schema''
176
+ */
177
+ type?: FieldTypes;
178
+ /**
179
+ * Specify the allowed country codes.
180
+ * @required if the type is phone number
181
+ * ex: ["sa", "eg", ...]
182
+ */
132
183
  countryCodes?: string[];
184
+ /**
185
+ * Specify the array type if the field is of type array.
186
+ * @default 'Same as schema''
187
+ */
133
188
  arrayType?: FieldTypes;
189
+ /**
190
+ * Can be used only if this field is a reference to the Image collection
191
+ */
134
192
  mediaUploader?: boolean;
193
+ /**
194
+ * Specify the type of the file to be uploaded. Only required if the media uploader is true.
195
+ * @default image
196
+ */
197
+ fileType?: FileTypes;
135
198
  }
136
199
  export interface IVirtualValue {
200
+ /**
201
+ * For now we have some virtual fields that can be added
202
+ * 1) Password: If you want to add password field in the creation form for example
203
+ * 2) ref: If it is a one to many realtion. For example, if you want to get all subCatogeries that belong to a category when you show the category record
204
+ * 3) array: If this field is an array
205
+ */
137
206
  type: VirtualFieldTypes;
207
+ /**
208
+ * Array type exists only if the type is array
209
+ */
138
210
  arrayType?: string;
211
+ /**
212
+ * Defines where this virtaul field need to be appeared
213
+ */
139
214
  showIn: Virtuals;
140
215
  required: boolean;
216
+ /**
217
+ * Define Virtual field's resource in case of ref type or array of ref type
218
+ */
141
219
  resource?: Model<any, any>;
142
220
  }
143
221
  interface IModel {
222
+ /**
223
+ * virtual data props
224
+ */
144
225
  virtuals?: {
145
226
  [key: string]: IVirtualValue;
146
227
  };
@@ -151,62 +232,169 @@ interface ActionOptions {
151
232
  edit?: Action;
152
233
  delete?: Action;
153
234
  bulkDelete?: Action;
235
+ /**
236
+ * Any extra action to be added.
237
+ */
154
238
  extras?: ExtraAction[];
155
239
  }
156
240
  interface ExtraAction {
241
+ /**
242
+ * Key of this action.
243
+ * Should be unique in the same resource file
244
+ */
157
245
  key: string;
246
+ /**
247
+ * Name of this action
248
+ */
158
249
  name: string;
159
250
  /**
160
- * Icon of this action.
161
- * @reference 'https://mui.com/material-ui/material-icons/'
162
- */
251
+ * Icon of this action.
252
+ * {@link https://mui.com/material-ui/material-icons/}
253
+ */
163
254
  icon: string;
255
+ /**
256
+ * Action type if it is record action or resource action.
257
+ */
164
258
  actionType: ActionTypes;
165
259
  /**
166
- * Guard message that appears before executing the action to confirm execution.
167
- * @default 'No guard message'
168
- */
260
+ * Guard message that appears before executing the action to confirm execution.
261
+ * @default 'No guard message'
262
+ */
169
263
  guard?: string;
170
264
  /**
171
- * Alert message appear after executing this action.
172
- * @default 'Action was executed successfully'
265
+ * Alert message appear after executing this action.
266
+ * @default 'Action was executed successfully'
173
267
  */
174
268
  message?: string;
175
269
  /**
176
- * The severity of the alert. This defines the color and icon used.
177
- * @default 'success'
178
- */
270
+ * The severity of the alert. This defines the color and icon used.
271
+ * @default 'success'
272
+ */
179
273
  severity?: Severity;
180
- isVisible?: (data: ActionData) => boolean;
181
- handler: (req: Request, res: any, data: ActionData) => Promise<any>;
274
+ /**
275
+ * @returns boolean value.
276
+ * This value Specifies to which records should this action appears.
277
+ * @default 'Action is shown to all records'
278
+ */
279
+ isVisible?: (data: ActionData) => Promise<boolean>;
280
+ /**
281
+ * Handler function that is executed after clicking the action.
282
+ */
283
+ handler: (req: Request, res: any, data: ActionData) => Promise<IActionHandlerResponse>;
284
+ }
285
+ export interface IActionHandlerResponse {
286
+ /**
287
+ * The action taken after executing the action.
288
+ * For example, if you would like to go to list after executing the action, just set this value by list
289
+ */
290
+ action: ActionNames;
291
+ /**
292
+ * Path of the resource that is intended to redirect.
293
+ * Is set to resource.path if you would like to be in the same table
294
+ */
295
+ path: string;
296
+ /**
297
+ * Id of the record that is used in actions that needs record id like show or edit
298
+ */
299
+ recordId?: string;
182
300
  }
183
301
  export interface IResourceFile {
184
302
  properties: {
303
+ /**
304
+ * The model
305
+ */
185
306
  resource: Model<any, any>;
307
+ /**
308
+ * Model name as saved in the data base.
309
+ */
186
310
  modelName: string;
311
+ /**
312
+ * Name of this model appeared on the nav bar.
313
+ * @default 'Model name'
314
+ */
187
315
  name?: string;
316
+ /**
317
+ * Property of this table that is shown as the link for the record.
318
+ * Used to be searched by in the search bar.
319
+ * If not mentioned explicitly, a search is done on the schema to check for property title, name, or email.
320
+ * If these properties are not found, _id is taken.
321
+ */
188
322
  title?: string;
323
+ /**
324
+ * The property to be sorted by the documents.
325
+ * @default 'The schema title'
326
+ */
189
327
  defaultOrderBy?: string;
190
- defaultrowsPerPage?: number;
328
+ /**
329
+ * The default order
330
+ * @default asc
331
+ */
191
332
  defaultOrder?: orderTypes;
333
+ /**
334
+ * Number of rows per page
335
+ * @default 10
336
+ */
337
+ defaultrowsPerPage?: number;
338
+ /**
339
+ * The parent that this model is belong to in the nav bar.
340
+ * @default 'Set up parent'
341
+ */
192
342
  parent?: Parent;
343
+ /**
344
+ * Array of fields that are completely hidden from all pages
345
+ */
193
346
  hiddenProperties?: string[];
347
+ /**
348
+ * Action options for overriding existing actions accessibility or adding custom actions
349
+ */
194
350
  actions?: ActionOptions;
351
+ /**
352
+ * Filters options
353
+ */
195
354
  filters?: IFilters;
355
+ /**
356
+ * Using before or after handlers of any crud operation
357
+ */
196
358
  crudOperations?: ICrudOperations;
359
+ /**
360
+ * Translation object of the fields' names.
361
+ */
197
362
  keysTranslations?: {
198
363
  [key: string]: any;
199
364
  };
365
+ /**
366
+ * Translation object of the actions' names.
367
+ */
200
368
  actionsTranslations?: {
201
369
  [key: string]: any;
202
370
  };
371
+ /**
372
+ * Override some props of a field's schema structure
373
+ * Add a new virtual property
374
+ */
203
375
  model?: {
204
376
  [key: string]: IFieldValue;
205
377
  } | IModel;
206
378
  };
379
+ /**
380
+ * Array of properties that should be appeared in the list action.
381
+ * @default 'The whole fields'
382
+ */
207
383
  listProperties?: string[];
384
+ /**
385
+ * Arrays of properties that should be appeared in the show action.
386
+ * @default 'The whole fields'
387
+ */
208
388
  showProperties?: string[];
389
+ /**
390
+ * Array of properties that should be appeared in the create/edit form.
391
+ * @default 'The whole fields'
392
+ */
209
393
  formProperties?: string[];
394
+ /**
395
+ * Array of properties that should be appeared in the filter.
396
+ * @default 'The whole fields'
397
+ */
210
398
  filterProperties?: string[];
211
399
  }
212
400
  export {};
@@ -0,0 +1,99 @@
1
+ import { ActionTypes } from "./helpers";
2
+ export default interface IResourceResponse {
3
+ filterProperties: string[];
4
+ formProperties: string[];
5
+ listProperties: IProperty[];
6
+ showProperties: IProperty[];
7
+ properties: IMainProperty;
8
+ }
9
+ interface IProperty {
10
+ key: string;
11
+ value: string;
12
+ path?: string;
13
+ }
14
+ interface IMainProperty {
15
+ title: string;
16
+ path: string;
17
+ name: string;
18
+ modelName: string;
19
+ parent: IParent;
20
+ defaultOrder: orderTypes;
21
+ defaultOrderBy: string;
22
+ defaultrowsPerPage: number;
23
+ filters: IFilter;
24
+ actions: IAction;
25
+ model: {
26
+ [key: string]: any;
27
+ };
28
+ }
29
+ interface IParent {
30
+ icon: string;
31
+ name: string;
32
+ value: string;
33
+ }
34
+ interface IFilter {
35
+ scopes: {
36
+ isAccessible: boolean;
37
+ options?: {
38
+ key: string;
39
+ value: string;
40
+ }[];
41
+ manual?: {
42
+ options: string[];
43
+ };
44
+ auto?: {
45
+ key: string;
46
+ options: string[];
47
+ };
48
+ };
49
+ searchBar: {
50
+ isAccessible: boolean;
51
+ };
52
+ }
53
+ interface IAction {
54
+ bulkDelete: {
55
+ cancelDeleteOption: string;
56
+ confirmDeleteOption: string;
57
+ confirmationMessageBody: string;
58
+ confirmationMessageTitle: string;
59
+ isAccessible: boolean;
60
+ value: string;
61
+ };
62
+ delete: {
63
+ cancelDeleteOption: string;
64
+ confirmDeleteOption: string;
65
+ confirmationMessageBody: string;
66
+ confirmationMessageTitle: string;
67
+ isAccessible: boolean;
68
+ value: string;
69
+ };
70
+ edit: IActionMin;
71
+ new: IActionMin;
72
+ show: IActionMin;
73
+ extras?: IExtras;
74
+ }
75
+ interface IExtras {
76
+ record: {
77
+ [key: string]: IExtarAction;
78
+ };
79
+ resource: {
80
+ [key: string]: IExtarAction;
81
+ };
82
+ }
83
+ interface IExtarAction {
84
+ actionType: ActionTypes;
85
+ guard?: string;
86
+ icon: string;
87
+ key: string;
88
+ keys?: string[];
89
+ name: string;
90
+ severity?: Severity;
91
+ message?: string;
92
+ }
93
+ interface IActionMin {
94
+ isAccessible: boolean;
95
+ value?: string;
96
+ }
97
+ declare type orderTypes = 'asc' | 'desc';
98
+ declare type Severity = 'success' | 'info' | 'warning' | 'error';
99
+ export {};
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -30,3 +30,15 @@ export declare enum FieldTypes {
30
30
  COLOR = "color",
31
31
  TIMEPICKER = "timePicker"
32
32
  }
33
+ export declare enum FileTypes {
34
+ IMAGE = "IMAGE",
35
+ _3D = "3D",
36
+ PDF = "PDF",
37
+ EXCEL = "EXCEL",
38
+ WORD = "WORD",
39
+ VIDEO = "VIDEO",
40
+ TEXT = "TEXT",
41
+ ZIP = "ZIP",
42
+ POWER_POINT = "POWER_POINT",
43
+ AUDIO = "AUDIO"
44
+ }
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.FieldTypes = exports.ActionTypes = exports.ActionNames = exports.Virtuals = void 0;
3
+ exports.FileTypes = exports.FieldTypes = exports.ActionTypes = exports.ActionNames = exports.Virtuals = void 0;
4
4
  var Virtuals;
5
5
  (function (Virtuals) {
6
6
  Virtuals["SHOW"] = "SHOW";
@@ -37,3 +37,16 @@ var FieldTypes;
37
37
  FieldTypes["COLOR"] = "color";
38
38
  FieldTypes["TIMEPICKER"] = "timePicker";
39
39
  })(FieldTypes = exports.FieldTypes || (exports.FieldTypes = {}));
40
+ var FileTypes;
41
+ (function (FileTypes) {
42
+ FileTypes["IMAGE"] = "IMAGE";
43
+ FileTypes["_3D"] = "3D";
44
+ FileTypes["PDF"] = "PDF";
45
+ FileTypes["EXCEL"] = "EXCEL";
46
+ FileTypes["WORD"] = "WORD";
47
+ FileTypes["VIDEO"] = "VIDEO";
48
+ FileTypes["TEXT"] = "TEXT";
49
+ FileTypes["ZIP"] = "ZIP";
50
+ FileTypes["POWER_POINT"] = "POWER_POINT";
51
+ FileTypes["AUDIO"] = "AUDIO";
52
+ })(FileTypes = exports.FileTypes || (exports.FileTypes = {}));
@@ -1,14 +1,19 @@
1
1
  {
2
2
  "files": {
3
- "main.css": "/static/css/main.18dca458.css",
4
- "main.js": "/static/js/main.da8f09ec.js",
5
- "static/js/148.b05fe2c8.chunk.js": "/static/js/148.b05fe2c8.chunk.js",
6
- "static/js/705.f86db82e.chunk.js": "/static/js/705.f86db82e.chunk.js",
7
- "static/js/802.3f287a2c.chunk.js": "/static/js/802.3f287a2c.chunk.js",
8
- "index.html": "/index.html"
3
+ "main.css": "/static/css/main.54de06ef.css",
4
+ "main.js": "/static/js/main.7ca1e0c1.js",
5
+ "static/js/574.778b5963.chunk.js": "/static/js/574.778b5963.chunk.js",
6
+ "static/js/678.521704a3.chunk.js": "/static/js/678.521704a3.chunk.js",
7
+ "static/js/798.54856416.chunk.js": "/static/js/798.54856416.chunk.js",
8
+ "index.html": "/index.html",
9
+ "main.54de06ef.css.map": "/static/css/main.54de06ef.css.map",
10
+ "main.7ca1e0c1.js.map": "/static/js/main.7ca1e0c1.js.map",
11
+ "574.778b5963.chunk.js.map": "/static/js/574.778b5963.chunk.js.map",
12
+ "678.521704a3.chunk.js.map": "/static/js/678.521704a3.chunk.js.map",
13
+ "798.54856416.chunk.js.map": "/static/js/798.54856416.chunk.js.map"
9
14
  },
10
15
  "entrypoints": [
11
- "static/css/main.18dca458.css",
12
- "static/js/main.da8f09ec.js"
16
+ "static/css/main.54de06ef.css",
17
+ "static/js/main.7ca1e0c1.js"
13
18
  ]
14
19
  }