angular-generate 2.2.1 → 2.2.3
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.
- package/README.md +433 -87
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,149 +1,495 @@
|
|
|
1
1
|
# AngularGenerate
|
|
2
|
-
**AngularGenerate** vous permet de générer une application Angular complète en quelques clics.
|
|
3
|
-
**Votre projet** sera composé de:
|
|
4
|
-
- Frontend (Angular) → Généré avec la bibliothèque **AngularGenerate** ( https://www.npmjs.com/package/angular-generate)
|
|
5
|
-
- Backend (LARAVEL) → Généré automatiquement à partir d'une base de données avec **ControllerGenerate** ( https://packagist.org/packages/saloum45/controllergenerate )
|
|
6
2
|
|
|
3
|
+
**AngularGenerate** est un package Angular qui permet de générer automatiquement une application Angular complète à partir d'un fichier de configuration.
|
|
7
4
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
5
|
+
|
|
6
|
+
AngularGenerate fonctionne avec un backend Laravel généré automatiquement grâce au package [**ControllerGenerate**](https://packagist.org/packages/saloum45/controllergenerate)
|
|
7
|
+
|
|
8
|
+
#### Packages utilisés :
|
|
9
|
+
|
|
10
|
+
* Frontend : **AngularGenerate**
|
|
11
|
+
* Backend : [**ControllerGenerate**](https://packagist.org/packages/saloum45/controllergenerate)
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Comment ça marche 👉🏽😇
|
|
16
|
+
|
|
17
|
+
AngularGenerate fonctionne à partir d'un fichier **`config.json`** contenant la configuration de votre application.
|
|
18
|
+
|
|
19
|
+
Le principe est simple :
|
|
20
|
+
|
|
21
|
+
1. Vous créez votre backend Laravel avec [**ControllerGenerate**](https://packagist.org/packages/saloum45/controllergenerate).
|
|
22
|
+
3. Vous récupérez le fichier **`config.json`** généré par le backend dans la racine du projet Laravel.
|
|
23
|
+
4. Copier ce fichier dans la racine de votre projet Angular.
|
|
24
|
+
5. Les composants Angular sont générés en fonction des modules et des tables définis dans `config.json`.
|
|
25
|
+
|
|
26
|
+
Votre structure doit alors ressembler à ceci :
|
|
27
|
+
|
|
28
|
+
```text
|
|
29
|
+
mon-projet-angular/
|
|
30
|
+
├── src/
|
|
31
|
+
├── public/
|
|
32
|
+
├── angular.json
|
|
33
|
+
├── package.json
|
|
34
|
+
├── tsconfig.json
|
|
35
|
+
└── config.json
|
|
12
36
|
```
|
|
37
|
+
|
|
38
|
+
> ⚠️ **Important :** utilisez directement le `config.json` généré par votre backend Laravel afin de garantir que la configuration du frontend corresponde à celle de votre API.
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
### Exemple de `config.json`
|
|
42
|
+
|
|
43
|
+
Le fichier généré par le backend aura une structure similaire à :
|
|
44
|
+
|
|
45
|
+
```json
|
|
13
46
|
{
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
// ici les configuration des tables à générer pour le module public
|
|
28
|
-
]
|
|
29
|
-
}
|
|
30
|
-
]
|
|
47
|
+
"projectName": "projet.angular",
|
|
48
|
+
"description": "Fichier de configuration de AngularGenerate",
|
|
49
|
+
"config_base_url": "http://localhost:8000",
|
|
50
|
+
"les_modules": [
|
|
51
|
+
{
|
|
52
|
+
"module": "home",
|
|
53
|
+
"les_tables": []
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
"module": "public",
|
|
57
|
+
"les_tables": []
|
|
58
|
+
}
|
|
59
|
+
]
|
|
31
60
|
}
|
|
32
61
|
```
|
|
33
|
-
|
|
34
|
-
|
|
62
|
+
Vous pouvez ainsi partir de deux packages et obtenir rapidement une structure complète **Backend Laravel + Frontend Angular**.
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
# Prérequis
|
|
67
|
+
|
|
68
|
+
Avant d'utiliser AngularGenerate, assurez-vous d'avoir installé :
|
|
69
|
+
|
|
70
|
+
* **Node.js**
|
|
71
|
+
* **npm**
|
|
72
|
+
* **Angular CLI**
|
|
73
|
+
* Un projet Angular
|
|
74
|
+
* Un backend Laravel utilisant [**ControllerGenerate**](https://packagist.org/packages/saloum45/controllergenerate)
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
# Installation
|
|
79
|
+
|
|
80
|
+
## 2️⃣ Installer AngularGenerate
|
|
81
|
+
|
|
82
|
+
Installez le package avec npm :
|
|
83
|
+
|
|
84
|
+
```bash
|
|
35
85
|
npm install angular-generate
|
|
36
86
|
```
|
|
37
|
-
|
|
38
|
-
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
## 3️⃣ Installer Angular JWT
|
|
91
|
+
|
|
92
|
+
AngularGenerate utilise `@auth0/angular-jwt` pour la gestion du token d'authentification.
|
|
93
|
+
|
|
94
|
+
```bash
|
|
39
95
|
npm install @auth0/angular-jwt
|
|
40
96
|
```
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
```
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
## 4️⃣ Installer NG-Select
|
|
101
|
+
|
|
102
|
+
Installez `@ng-select/ng-select` :
|
|
103
|
+
|
|
104
|
+
```bash
|
|
50
105
|
npm install @ng-select/ng-select
|
|
51
106
|
```
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
107
|
+
|
|
108
|
+
### Compatibilité Angular / NG-Select
|
|
109
|
+
|
|
110
|
+
Veillez à utiliser une version compatible avec votre version d'Angular :
|
|
111
|
+
|
|
112
|
+
| Angular | NG-Select |
|
|
113
|
+
| ------------------ | --------- |
|
|
114
|
+
| `>=20.0.0 <21.0.0` | `v15.x` |
|
|
115
|
+
| `>=19.0.0 <20.0.0` | `v14.x` |
|
|
116
|
+
| `>=18.0.0 <19.0.0` | `v13.x` |
|
|
117
|
+
| `>=17.0.0 <18.0.0` | `v12.x` |
|
|
118
|
+
|
|
119
|
+
Documentation officielle :
|
|
120
|
+
|
|
121
|
+
https://www.npmjs.com/package/@ng-select/ng-select
|
|
122
|
+
|
|
123
|
+
### Importer les styles NG-Select
|
|
124
|
+
|
|
125
|
+
Dans votre fichier `style.css` ou `style.scss` :
|
|
126
|
+
|
|
127
|
+
```scss
|
|
128
|
+
/* Importing NG-Select styles */
|
|
129
|
+
@import url('../node_modules/@ng-select/ng-select/themes/default.theme.css');
|
|
58
130
|
```
|
|
131
|
+
|
|
132
|
+
---
|
|
133
|
+
|
|
134
|
+
## 5️⃣ Installer SweetAlert2
|
|
135
|
+
|
|
136
|
+
SweetAlert2 est utilisé pour afficher des notifications et des messages interactifs.
|
|
137
|
+
|
|
138
|
+
```bash
|
|
59
139
|
npm install sweetalert2
|
|
60
140
|
```
|
|
61
|
-
|
|
62
|
-
|
|
141
|
+
|
|
142
|
+
---
|
|
143
|
+
|
|
144
|
+
## 6️⃣ Installer ng-bootstrap
|
|
145
|
+
|
|
146
|
+
Installez `ng-bootstrap` :
|
|
147
|
+
|
|
148
|
+
```bash
|
|
63
149
|
ng add @ng-bootstrap/ng-bootstrap
|
|
64
150
|
```
|
|
65
|
-
|
|
66
|
-
|
|
151
|
+
|
|
152
|
+
Documentation :
|
|
153
|
+
|
|
154
|
+
https://ng-bootstrap.github.io
|
|
155
|
+
|
|
156
|
+
---
|
|
157
|
+
|
|
158
|
+
## 7️⃣ Installer Bootstrap et Bootstrap Icons
|
|
159
|
+
|
|
160
|
+
```bash
|
|
67
161
|
npm install bootstrap bootstrap-icons
|
|
68
162
|
```
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
163
|
+
|
|
164
|
+
Puis importez les styles dans `style.css` ou `style.scss` :
|
|
165
|
+
|
|
166
|
+
```scss
|
|
167
|
+
/* Importing Bootstrap CSS */
|
|
72
168
|
@import 'bootstrap/dist/css/bootstrap.css';
|
|
73
|
-
|
|
169
|
+
|
|
170
|
+
/* Importing Bootstrap Icons */
|
|
74
171
|
@import 'bootstrap-icons/font/bootstrap-icons.css';
|
|
75
|
-
|
|
76
|
-
|
|
172
|
+
|
|
173
|
+
/* Importing NG-Select styles */
|
|
174
|
+
@import url('../node_modules/@ng-select/ng-select/themes/default.theme.css');
|
|
77
175
|
```
|
|
176
|
+
---
|
|
177
|
+
|
|
178
|
+
# Configuration de HttpClient
|
|
78
179
|
|
|
79
|
-
|
|
180
|
+
AngularGenerate utilise `HttpClient` pour communiquer avec l'API Laravel.
|
|
181
|
+
|
|
182
|
+
Dans votre fichier :
|
|
183
|
+
|
|
184
|
+
```text
|
|
185
|
+
app.config.ts
|
|
80
186
|
```
|
|
81
|
-
|
|
187
|
+
|
|
188
|
+
ajoutez `provideHttpClient()`.
|
|
189
|
+
|
|
190
|
+
Exemple :
|
|
191
|
+
|
|
192
|
+
```typescript
|
|
193
|
+
import { ApplicationConfig } from '@angular/core';
|
|
82
194
|
import { provideHttpClient } from '@angular/common/http';
|
|
83
195
|
import { provideRouter, withHashLocation } from '@angular/router';
|
|
84
196
|
|
|
197
|
+
import { routes } from './app.routes';
|
|
198
|
+
|
|
85
199
|
export const appConfig: ApplicationConfig = {
|
|
86
|
-
|
|
200
|
+
providers: [
|
|
201
|
+
provideRouter(routes, withHashLocation()),
|
|
202
|
+
provideHttpClient()
|
|
203
|
+
]
|
|
87
204
|
};
|
|
88
205
|
```
|
|
89
206
|
|
|
90
|
-
|
|
91
|
-
|
|
207
|
+
---
|
|
208
|
+
|
|
209
|
+
# Génération de l'application
|
|
210
|
+
|
|
211
|
+
Une fois la configuration terminée, AngularGenerate permet de générer automatiquement votre application.
|
|
212
|
+
|
|
213
|
+
## 1️⃣ Générer complètement l'application
|
|
214
|
+
|
|
215
|
+
Pour générer tous les modules et composants définis dans `config.json` :
|
|
216
|
+
|
|
217
|
+
```bash
|
|
92
218
|
ng generate angular-generate:config
|
|
93
219
|
```
|
|
94
|
-
|
|
95
|
-
|
|
220
|
+
|
|
221
|
+
Cette commande analyse votre configuration et génère automatiquement les éléments nécessaires.
|
|
222
|
+
|
|
223
|
+
---
|
|
224
|
+
|
|
225
|
+
# Générer un module spécifique
|
|
226
|
+
|
|
227
|
+
Supposons que votre configuration contient un module :
|
|
228
|
+
|
|
229
|
+
```text
|
|
230
|
+
public
|
|
96
231
|
```
|
|
232
|
+
|
|
233
|
+
avec plusieurs tables.
|
|
234
|
+
|
|
235
|
+
Pour générer uniquement ce module :
|
|
236
|
+
|
|
237
|
+
```bash
|
|
97
238
|
ng generate angular-generate:config --module public
|
|
98
239
|
```
|
|
99
|
-
|
|
100
|
-
|
|
240
|
+
|
|
241
|
+
AngularGenerate génère alors les composants associés au module `public`.
|
|
242
|
+
|
|
243
|
+
---
|
|
244
|
+
|
|
245
|
+
# Générer les composants d'une table
|
|
246
|
+
|
|
247
|
+
Supposons que votre configuration contient une table :
|
|
248
|
+
|
|
249
|
+
```text
|
|
250
|
+
agent
|
|
101
251
|
```
|
|
252
|
+
|
|
253
|
+
Pour générer tous les composants associés à cette table :
|
|
254
|
+
|
|
255
|
+
```bash
|
|
102
256
|
ng generate angular-generate:config --table agent
|
|
103
257
|
```
|
|
104
|
-
|
|
105
|
-
|
|
258
|
+
|
|
259
|
+
AngularGenerate génère alors les différents composants disponibles pour cette table.
|
|
260
|
+
|
|
261
|
+
---
|
|
262
|
+
|
|
263
|
+
# Générer un composant spécifique
|
|
264
|
+
|
|
265
|
+
Vous pouvez également générer uniquement un type de composant.
|
|
266
|
+
|
|
267
|
+
Par exemple, pour générer la liste des agents :
|
|
268
|
+
|
|
269
|
+
```bash
|
|
270
|
+
ng generate angular-generate:config --table agent --type list
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
---
|
|
274
|
+
|
|
275
|
+
# Types de composants disponibles
|
|
276
|
+
|
|
277
|
+
AngularGenerate permet de générer plusieurs types de composants.
|
|
278
|
+
|
|
279
|
+
### `list`
|
|
280
|
+
|
|
281
|
+
Affiche la liste des enregistrements d'une table.
|
|
282
|
+
|
|
283
|
+
```bash
|
|
284
|
+
--type list
|
|
106
285
|
```
|
|
286
|
+
|
|
287
|
+
---
|
|
288
|
+
|
|
289
|
+
### `add`
|
|
290
|
+
|
|
291
|
+
Génère le formulaire permettant d'ajouter un nouvel enregistrement.
|
|
292
|
+
|
|
293
|
+
```bash
|
|
294
|
+
--type add
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
---
|
|
298
|
+
|
|
299
|
+
### `edit`
|
|
300
|
+
|
|
301
|
+
Génère le formulaire permettant de modifier un enregistrement existant.
|
|
302
|
+
|
|
303
|
+
```bash
|
|
304
|
+
--type edit
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
---
|
|
308
|
+
|
|
309
|
+
### `details`
|
|
310
|
+
|
|
311
|
+
Génère la page permettant d'afficher les détails d'un enregistrement.
|
|
312
|
+
|
|
313
|
+
```bash
|
|
314
|
+
--type details
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
---
|
|
318
|
+
|
|
319
|
+
# Exemple d'utilisation
|
|
320
|
+
|
|
321
|
+
Supposons que nous avons une table :
|
|
322
|
+
|
|
323
|
+
```text
|
|
324
|
+
agent
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
Nous pouvons générer :
|
|
328
|
+
|
|
329
|
+
### Liste des agents
|
|
330
|
+
|
|
331
|
+
```bash
|
|
107
332
|
ng generate angular-generate:config --table agent --type list
|
|
108
333
|
```
|
|
109
|
-
### NB: Les types de composant disponibles
|
|
110
|
-
- **list** : liste tous les enregistrements de la table
|
|
111
|
-
- **add** : formulaire d'ajout de la table
|
|
112
|
-
- **edit** : formulaire de modification de la table
|
|
113
|
-
- **details** : affiche les details d'un enregistrement de la table
|
|
114
|
-
- **login** : formulaire de connexion
|
|
115
|
-
- **deconnexion** : page de déconnexion à l'application
|
|
116
|
-
- **not-found** : si la page demandée est introuvable
|
|
117
334
|
|
|
118
|
-
###
|
|
335
|
+
### Formulaire d'ajout
|
|
336
|
+
|
|
337
|
+
```bash
|
|
338
|
+
ng generate angular-generate:config --table agent --type add
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
### Formulaire de modification
|
|
342
|
+
|
|
343
|
+
```bash
|
|
344
|
+
ng generate angular-generate:config --table agent --type edit
|
|
119
345
|
```
|
|
346
|
+
|
|
347
|
+
### Détails d'un agent
|
|
348
|
+
|
|
349
|
+
```bash
|
|
350
|
+
ng generate angular-generate:config --table agent --type details
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
---
|
|
354
|
+
|
|
355
|
+
# Gestion des routes
|
|
356
|
+
|
|
357
|
+
AngularGenerate génère également la structure nécessaire à la navigation entre les différents modules.
|
|
358
|
+
|
|
359
|
+
Exemple de fichier `app.routes.ts` :
|
|
360
|
+
|
|
361
|
+
```typescript
|
|
120
362
|
import { Routes } from '@angular/router';
|
|
363
|
+
|
|
121
364
|
import { HomeComponent } from './home/home/home.component';
|
|
122
|
-
import { AuthGuard } from './guard/auth/auth.guard';
|
|
123
365
|
import { PublicComponent } from './public/public/public.component';
|
|
366
|
+
import { AuthGuard } from './guard/auth/auth.guard';
|
|
124
367
|
|
|
125
368
|
export const routes: Routes = [
|
|
126
|
-
|
|
369
|
+
|
|
127
370
|
{
|
|
128
|
-
path:
|
|
371
|
+
path: '',
|
|
372
|
+
pathMatch: 'full',
|
|
373
|
+
redirectTo: 'public'
|
|
374
|
+
},
|
|
375
|
+
|
|
376
|
+
{
|
|
377
|
+
path: 'home',
|
|
129
378
|
component: HomeComponent,
|
|
379
|
+
canActivate: [AuthGuard],
|
|
130
380
|
children: [
|
|
131
381
|
{
|
|
132
|
-
path:
|
|
133
|
-
loadChildren: () =>
|
|
382
|
+
path: '',
|
|
383
|
+
loadChildren: () =>
|
|
384
|
+
import('./home/home.module')
|
|
385
|
+
.then((m) => m.HomeModule)
|
|
134
386
|
}
|
|
135
|
-
]
|
|
136
|
-
canActivate: [AuthGuard]
|
|
387
|
+
]
|
|
137
388
|
},
|
|
389
|
+
|
|
138
390
|
{
|
|
139
|
-
path:
|
|
391
|
+
path: 'public',
|
|
140
392
|
component: PublicComponent,
|
|
141
393
|
children: [
|
|
142
394
|
{
|
|
143
|
-
path:
|
|
144
|
-
loadChildren: () =>
|
|
395
|
+
path: '',
|
|
396
|
+
loadChildren: () =>
|
|
397
|
+
import('./public/public.module')
|
|
398
|
+
.then((m) => m.PublicModule)
|
|
145
399
|
}
|
|
146
|
-
]
|
|
147
|
-
}
|
|
400
|
+
]
|
|
401
|
+
}
|
|
402
|
+
|
|
148
403
|
];
|
|
149
|
-
```
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
---
|
|
407
|
+
|
|
408
|
+
# Exemple d'architecture générée
|
|
409
|
+
|
|
410
|
+
Après génération, votre application peut notamment être organisée de cette manière :
|
|
411
|
+
|
|
412
|
+
```text
|
|
413
|
+
src/
|
|
414
|
+
├── app/
|
|
415
|
+
│ ├── home/
|
|
416
|
+
│ │ ├── home/
|
|
417
|
+
│ │ ├── agent/
|
|
418
|
+
│ │ ├── client/
|
|
419
|
+
│ │ └── home.module.ts
|
|
420
|
+
│ │
|
|
421
|
+
│ ├── public/
|
|
422
|
+
│ │ ├── public/
|
|
423
|
+
│ │ ├── login/
|
|
424
|
+
│ │ ├── agent/
|
|
425
|
+
│ │ └── public.module.ts
|
|
426
|
+
│ │
|
|
427
|
+
│ ├── guard/
|
|
428
|
+
│ │ └── auth/
|
|
429
|
+
│ │
|
|
430
|
+
│ ├── app.config.ts
|
|
431
|
+
│ └── app.routes.ts
|
|
432
|
+
│
|
|
433
|
+
├── assets/
|
|
434
|
+
│
|
|
435
|
+
├── styles.scss
|
|
436
|
+
│
|
|
437
|
+
└── config.json
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
La structure exacte peut varier en fonction de la configuration de votre application.
|
|
441
|
+
|
|
442
|
+
---
|
|
443
|
+
|
|
444
|
+
# Utilisation avec ControllerGenerate
|
|
445
|
+
|
|
446
|
+
AngularGenerate a été pensé pour fonctionner avec un backend Laravel généré automatiquement.
|
|
447
|
+
|
|
448
|
+
Le fonctionnement global est donc :
|
|
449
|
+
|
|
450
|
+
```text
|
|
451
|
+
BASE DE DONNÉES
|
|
452
|
+
│
|
|
453
|
+
▼
|
|
454
|
+
ControllerGenerate
|
|
455
|
+
│
|
|
456
|
+
┌─────────────┼─────────────┐
|
|
457
|
+
▼ ▼ ▼
|
|
458
|
+
Models Controllers Routes
|
|
459
|
+
│
|
|
460
|
+
▼
|
|
461
|
+
Configuration
|
|
462
|
+
│
|
|
463
|
+
▼
|
|
464
|
+
AngularGenerate
|
|
465
|
+
│
|
|
466
|
+
▼
|
|
467
|
+
Application Angular
|
|
468
|
+
│
|
|
469
|
+
┌─────┼─────┐
|
|
470
|
+
▼ ▼ ▼
|
|
471
|
+
Lists Forms Details
|
|
472
|
+
```
|
|
473
|
+
|
|
474
|
+
Cette approche permet de réduire considérablement le temps nécessaire pour mettre en place une application CRUD complète.
|
|
475
|
+
|
|
476
|
+
---
|
|
477
|
+
|
|
478
|
+
# Résultat attendu
|
|
479
|
+
|
|
480
|
+
Après l'utilisation d'AngularGenerate, vous disposez automatiquement d'une base Angular contenant notamment :
|
|
481
|
+
|
|
482
|
+
* **Modules** générés automatiquement ;
|
|
483
|
+
* **Routes** ;
|
|
484
|
+
* **Composants CRUD** ;
|
|
485
|
+
* **Listes** ;
|
|
486
|
+
* **Formulaires d'ajout** ;
|
|
487
|
+
* **Formulaires de modification** ;
|
|
488
|
+
* **Pages de détails** ;
|
|
489
|
+
* **Authentification** ;
|
|
490
|
+
* Gestion des **relations entre tables** ;
|
|
491
|
+
* Communication avec votre **API Laravel**.
|
|
492
|
+
|
|
493
|
+
|
|
494
|
+
|
|
495
|
+
## Bon code 🧑🏽💻 Salem DEV 👈🏽 fait avec beaucoup de ❤️ et ☕️
|