zayef 0.2.0 → 0.2.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.
data/REFACTORING.md ADDED
@@ -0,0 +1,220 @@
1
+ # Zayef Generator Refactoring Summary
2
+
3
+ ## 🎯 Overview
4
+
5
+ The Zayef generator has been completely refactored to follow the "Less Code, Better Result" philosophy, reducing repetition, improving maintainability, and adding better consistency.
6
+
7
+ ## ✅ Key Improvements
8
+
9
+ ### 1. Generic Helper Methods
10
+ - **`pick(list)`**: Replaces repetitive `.sample` calls
11
+ - **`random_number(min:, max:)`**: Consistent number generation
12
+ - **`random_code(format:)`**: Pattern-based code generation (CNI, IBAN, etc.)
13
+ - **`weighted_pick(weights_hash)`**: Realistic distribution sampling
14
+
15
+ ### 2. External Data Files
16
+ - **`moroccan_names.json`**: First names (male/female) and last names
17
+ - **`moroccan_geography.json`**: Cities, regions, districts, landmarks
18
+ - **`moroccan_culture.json`**: Dishes, spices, festivals, hobbies, etc.
19
+ - **`moroccan_business.json`**: Banks, industries, professions, etc.
20
+
21
+ ### 3. Data Loader Module
22
+ - **Cached loading**: Data loaded once and cached for performance
23
+ - **Convenience methods**: Direct access to specific data categories
24
+ - **Error handling**: Graceful fallbacks for missing files
25
+ - **Reload capability**: Clear cache and reload data when needed
26
+
27
+ ### 4. Parameterization Support
28
+ ```ruby
29
+ # Age constraints
30
+ profile = Zayef::Generator.profile(age_min: 25, age_max: 35)
31
+
32
+ # City constraints
33
+ profile = Zayef::Generator.profile(city: "Rabat")
34
+
35
+ # Gender constraints
36
+ profile = Zayef::Generator.profile(gender: "Female")
37
+
38
+ # Combined constraints
39
+ profile = Zayef::Generator.profile(age_min: 30, age_max: 40, city: "Casablanca", gender: "Male")
40
+ ```
41
+
42
+ ### 5. Consistency Improvements
43
+ - **City-District matching**: Districts always match their cities
44
+ - **Email consistency**: Uses generated first/last names
45
+ - **Address consistency**: Addresses use the same city as the profile
46
+ - **Gender-specific names**: First names can be gender-specific
47
+
48
+ ### 6. Weighted Sampling
49
+ ```ruby
50
+ # Realistic nationality distribution
51
+ nationality = Zayef::Generator.nationality # 85% Moroccan, 5% French, etc.
52
+
53
+ # Custom weighted sampling
54
+ result = Zayef::Generator.weighted_pick({
55
+ "Option A" => 70,
56
+ "Option B" => 20,
57
+ "Option C" => 10
58
+ })
59
+ ```
60
+
61
+ ### 7. Streaming Support
62
+ ```ruby
63
+ # Large dataset generation without memory issues
64
+ Zayef::Generator.stream_json(10000, 'personal') do |chunk|
65
+ file.write(chunk)
66
+ end
67
+
68
+ Zayef::Generator.stream_csv(50000, 'business') do |line|
69
+ csv_file.write(line)
70
+ end
71
+ ```
72
+
73
+ ## 📊 Before vs After
74
+
75
+ ### Before (Repetitive)
76
+ ```ruby
77
+ def first_name
78
+ MOROCCAN_FIRST_NAMES.sample
79
+ end
80
+
81
+ def last_name
82
+ MOROCCAN_LAST_NAMES.sample
83
+ end
84
+
85
+ def city
86
+ MOROCCAN_CITIES.sample
87
+ end
88
+
89
+ def cni_number
90
+ letters = ('A'..'Z').to_a.sample(2).join
91
+ numbers = rand(100000..999999)
92
+ "#{letters}#{numbers}"
93
+ end
94
+ ```
95
+
96
+ ### After (DRY & Generic)
97
+ ```ruby
98
+ def first_name(gender = nil)
99
+ pick(DataLoader.first_names(gender))
100
+ end
101
+
102
+ def last_name
103
+ pick(DataLoader.last_names)
104
+ end
105
+
106
+ def city
107
+ pick(DataLoader.cities)
108
+ end
109
+
110
+ def cni_number
111
+ random_code(format: 'AA######')
112
+ end
113
+ ```
114
+
115
+ ## 🚀 Usage Examples
116
+
117
+ ### Basic Generation
118
+ ```ruby
119
+ # Simple data generation
120
+ name = Zayef::Generator.name
121
+ email = Zayef::Generator.email
122
+ phone = Zayef::Generator.phone
123
+ ```
124
+
125
+ ### Profile Generation
126
+ ```ruby
127
+ # Complete profile with constraints
128
+ profile = Zayef::Generator.profile(
129
+ age_min: 25,
130
+ age_max: 35,
131
+ city: "Rabat",
132
+ gender: "Female"
133
+ )
134
+ ```
135
+
136
+ ### Bulk Generation
137
+ ```ruby
138
+ # Generate multiple profiles
139
+ profiles = Zayef::Generator.bulk_data(100, 'personal', city: "Casablanca")
140
+
141
+ # Export to JSON
142
+ json_data = Zayef::Generator.export_to_json(50, 'medical')
143
+
144
+ # Export to CSV
145
+ csv_data = Zayef::Generator.export_to_csv(200, 'business')
146
+ ```
147
+
148
+ ### Streaming Large Datasets
149
+ ```ruby
150
+ # Generate 10,000 records without loading all in memory
151
+ File.open('large_dataset.json', 'w') do |file|
152
+ Zayef::Generator.stream_json(10000, 'personal') do |chunk|
153
+ file.write(chunk)
154
+ end
155
+ end
156
+ ```
157
+
158
+ ## 🔧 Data Management
159
+
160
+ ### Adding New Data
161
+ 1. Edit the appropriate JSON file in `data/` directory
162
+ 2. Add convenience method to `DataLoader` if needed
163
+ 3. Use `DataLoader.reload!` to refresh cached data
164
+
165
+ ### Custom Data Sources
166
+ ```ruby
167
+ # Load custom data
168
+ custom_data = Zayef::DataLoader.load_json('custom_data.json')
169
+
170
+ # Use in generator
171
+ def custom_field
172
+ pick(custom_data[:custom_list])
173
+ end
174
+ ```
175
+
176
+ ## 📈 Performance Improvements
177
+
178
+ - **Cached data loading**: Data loaded once and reused
179
+ - **Generic helpers**: Reduced method call overhead
180
+ - **Streaming support**: Memory-efficient large dataset generation
181
+ - **Weighted sampling**: Realistic distributions without repetition
182
+
183
+ ## 🎨 Code Quality
184
+
185
+ - **DRY principle**: Eliminated repetitive code patterns
186
+ - **Single responsibility**: Each method has a clear purpose
187
+ - **Consistent naming**: All methods follow the same conventions
188
+ - **Error handling**: Graceful fallbacks for missing data
189
+ - **Documentation**: Clear comments and examples
190
+
191
+ ## 🔮 Future Enhancements
192
+
193
+ - **YAML support**: Alternative data format
194
+ - **Database integration**: Load data from databases
195
+ - **Custom distributions**: User-defined weighted sampling
196
+ - **Validation**: Data consistency checks
197
+ - **Internationalization**: Support for other countries
198
+
199
+ ## 📝 Migration Guide
200
+
201
+ ### For Existing Code
202
+ 1. Replace `.sample` calls with `pick()`
203
+ 2. Use `random_number(min:, max:)` for ranges
204
+ 3. Use `random_code(format:)` for formatted codes
205
+ 4. Add parameterization to profile methods
206
+ 5. Use `DataLoader` for direct data access
207
+
208
+ ### Breaking Changes
209
+ - Some method signatures changed to support parameters
210
+ - Data constants moved to external files
211
+ - Profile methods now return consistent data
212
+
213
+ ## 🧪 Testing
214
+
215
+ Run the example script to see all improvements in action:
216
+ ```bash
217
+ ruby examples/refactored_usage.rb
218
+ ```
219
+
220
+ This demonstrates all the new features and improvements in a practical way.
@@ -0,0 +1,97 @@
1
+ {
2
+ "banks": [
3
+ "Attijariwafa Bank", "Banque Centrale Populaire",
4
+ "BMCI", "Banque Marocaine pour le Commerce et l'Industrie",
5
+ "Société Générale Maroc", "Crédit du Maroc",
6
+ "Banque Marocaine du Commerce Extérieur", "CIH Bank",
7
+ "Crédit Immobilier et Hôtelier", "Al Barid Bank",
8
+ "Bank Al Maghrib", "CFG Bank",
9
+ "Crédit Agricole du Maroc", "Umnia Bank"
10
+ ],
11
+ "industries": [
12
+ "Agriculture", "Textile", "Tourisme", "Immobilier",
13
+ "Banque et Finance", "Télécommunications", "Énergie",
14
+ "Mines", "Transport", "Commerce", "Santé", "Éducation",
15
+ "Technologie", "Artisanat", "Pêche", "Construction"
16
+ ],
17
+ "company_sizes": [
18
+ "1-10 employés", "11-50 employés", "51-200 employés",
19
+ "201-500 employés", "501-1000 employés", "1000+ employés"
20
+ ],
21
+ "business_types": [
22
+ "SARL", "SA", "SNC", "SAS", "Auto-entrepreneur",
23
+ "Coopérative", "Association", "Fondation", "ONG"
24
+ ],
25
+ "job_titles": [
26
+ "Directeur Général", "Directeur Commercial", "Directeur RH",
27
+ "Chef de Projet", "Ingénieur", "Développeur", "Designer",
28
+ "Comptable", "Secrétaire", "Commercial", "Technicien",
29
+ "Ouvrier", "Agent de Sécurité", "Réceptionniste",
30
+ "Chef de Cuisine", "Serveur", "Chauffeur", "Nettoyeur"
31
+ ],
32
+ "professions": [
33
+ "Médecin", "Ingénieur", "Enseignant",
34
+ "Avocat", "Notaire", "Architecte",
35
+ "Pharmacien", "Commerçant", "Artisan",
36
+ "Agriculteur", "Fonctionnaire", "Journaliste",
37
+ "Banquier", "Comptable", "Informaticien",
38
+ "Électricien", "Plombier", "Menuisier",
39
+ "Coiffeur", "Serveur", "Chauffeur",
40
+ "Garde-malade", "Secrétaire", "Traducteur",
41
+ "Guide touristique", "Vendeur"
42
+ ],
43
+ "work_schedules": [
44
+ "Temps plein", "Temps partiel", "CDI", "CDD",
45
+ "Stage", "Freelance", "Consultant", "Télétravail"
46
+ ],
47
+ "medical_specialties": [
48
+ "Médecine générale", "Pédiatrie", "Cardiologie",
49
+ "Dermatologie", "Ophtalmologie", "ORL",
50
+ "Gynécologie Obstétrique", "Chirurgie générale",
51
+ "Médecine interne", "Psychiatrie", "Radiologie",
52
+ "Anesthésie-réanimation", "Néphrologie",
53
+ "Hépatologie", "Gastro-entérologie", "Endocrinologie",
54
+ "Rhumatologie", "Neurologie", "Urologie",
55
+ "Traumatologie", "Orthopédie", "Chirurgie plastique",
56
+ "Chirurgie vasculaire", "Médecine du travail",
57
+ "Médecine légale", "Médecine nucléaire",
58
+ "Médecine physique", "Oncologie"
59
+ ],
60
+ "education_levels": [
61
+ "Analphabète", "Primaire", "Collège", "Lycée",
62
+ "Baccalauréat", "BTS", "Licence", "Master", "Doctorat"
63
+ ],
64
+ "income_ranges": [
65
+ "0-3000 MAD", "3000-6000 MAD", "6000-10000 MAD",
66
+ "10000-15000 MAD", "15000-25000 MAD", "25000+ MAD"
67
+ ],
68
+ "languages": [
69
+ "Arabe", "Français", "Amazigh", "Anglais", "Espagnol",
70
+ "Italien", "Allemand", "Néerlandais", "Portugais"
71
+ ],
72
+ "marital_statuses": [
73
+ "Célibataire", "Marié", "Divorcé", "Veuf"
74
+ ],
75
+ "blood_types": [
76
+ "A+", "A-", "B+", "B-", "AB+", "AB-", "O+", "O-"
77
+ ],
78
+ "eye_colors": [
79
+ "Marron", "Noir", "Bleu", "Vert"
80
+ ],
81
+ "hair_colors": [
82
+ "Noir", "Brun", "Châtain", "Blond"
83
+ ],
84
+ "religions": [
85
+ "Musulman", "Chrétien", "Juif", "Autre"
86
+ ],
87
+ "nationalities": {
88
+ "Marocaine": 85,
89
+ "Française": 5,
90
+ "Algérienne": 3,
91
+ "Tunisienne": 2,
92
+ "Espagnole": 2,
93
+ "Italienne": 1,
94
+ "Belge": 1,
95
+ "Autre": 1
96
+ }
97
+ }
@@ -0,0 +1,127 @@
1
+ {
2
+ "traditional_dishes": [
3
+ "Couscous", "Tagine", "Pastilla", "Harira",
4
+ "Rfissa", "Tanjia", "Mechoui", "Briouates",
5
+ "Msemen", "Meloui", "Baghrir", "Khobz",
6
+ "Bissara", "Lentilles aux merguez",
7
+ "Khlia", "Merguez", "Sardines grillées",
8
+ "Daqous aux olives", "Kefta aux œufs",
9
+ "Poulet aux citrons confits",
10
+ "Tajine aux pruneaux", "Tajine aux abricots",
11
+ "Chorba frik", "Soupe de poisson",
12
+ "Maâqouda", "Zaalouk"
13
+ ],
14
+ "spices": [
15
+ "Ras-el-hanout", "Safran", "Cannelle",
16
+ "Curcuma", "Gingembre", "Paprika",
17
+ "Cumin", "Coriandre", "Cardamome",
18
+ "Muscade", "Poivre noir", "Piment",
19
+ "Fenouil", "Anis étoilé", "Clous de girofle",
20
+ "Laurier", "Citron confit", "Olives",
21
+ "Amandes", "Pistaches", "Noix",
22
+ "Miel d'oranger", "Fleur d'oranger",
23
+ "Huile d'argan", "Beurre clarifié"
24
+ ],
25
+ "souks": [
26
+ "Souk Semmarine", "Souk El Kébir", "Souk El Attarine",
27
+ "Souk Zitoun El Jdid", "Souk El Hadadine",
28
+ "Souk El Bahia", "Souk Smarine", "Souk El Ghezel",
29
+ "Souk El Koutoubine", "Souk El Abid",
30
+ "Souk Sebbaghine", "Souk Cherratine",
31
+ "Souk Nejjarine", "Marché Central",
32
+ "Souk Al Fassia", "Souk El Joutia"
33
+ ],
34
+ "restaurants": [
35
+ "Café Clock", "Nomad", "Le Jardin",
36
+ "Café Bousafsaf", "Dar Moha", "Al Fassia",
37
+ "Café de France", "Le Jardin d'Essai",
38
+ "Café Hafa", "Nomad Café", "Dar Essalam",
39
+ "Café Central", "Le Jardin Secret",
40
+ "Café Arabe", "Dar El Hana"
41
+ ],
42
+ "hotels": [
43
+ "Riad Kniza", "Palmeraie Palace",
44
+ "Hotel Sahrai", "Riad Al Fassia",
45
+ "Hotel El Andalous", "Riad El Cadi",
46
+ "Hotel Atlas Medina", "Riad Dar Anika",
47
+ "Hotel Nomade", "Riad Zitouna",
48
+ "Hotel Al Fassia", "Riad Les Jardin"
49
+ ],
50
+ "mosques": [
51
+ "Mosquée Hassan II", "Mosquée Koutoubia",
52
+ "Mosquée Al Quaraouiyine", "Mosquée Bahia",
53
+ "Mosquée Saadian", "Mosquée Moulay Idriss",
54
+ "Mosquée El Badi", "Mosquée Lalla Aouda",
55
+ "Mosquée Tin Mal", "Mosquée Nejjarine",
56
+ "Mosquée Cherratine", "Mosquée El Glaoui"
57
+ ],
58
+ "schools": [
59
+ "Lycée Descartes", "Lycée Lyautey",
60
+ "Lycée Moulay Youssef", "Lycée Mohammed V",
61
+ "École Américaine", "Lycée Français",
62
+ "École Mission La Sallle", "Lycée Victor Hugo",
63
+ "École Sainte Marie", "Lycée Ibn Khaldoun",
64
+ "École Al Khansaa", "Lycée Ibn Sina"
65
+ ],
66
+ "universities": [
67
+ "Université Mohammed V de Rabat", "Université Hassan II de Casablanca",
68
+ "Université Ibn Tofail de Kénitra", "Université Cadi Ayyad de Marrakech",
69
+ "Université Abdelmalek Essaâdi de Tanger", "Université Sidi Mohammed Ben Abdellah de Fès",
70
+ "Université Ibn Zohr d'Agadir", "Université Chouaib Doukkali d'El Jadida",
71
+ "Université Sultan Moulay Slimane de Beni Mellal", "Université Mohammed Premier d'Oujda",
72
+ "Université Hassan Ier de Settat", "École Polytechnique de l'Université Internationale de Rabat"
73
+ ],
74
+ "newspapers": [
75
+ "Le Matin", "L'Économiste",
76
+ "Libération", "Aujourd'hui le Maroc",
77
+ "Al Alam", "Assabah",
78
+ "Bayane Al Yaoum", "Al Akhbar",
79
+ "Al Massae", "Al Ahdath Al Maghribia",
80
+ "Al Ittihad Al Ichtiraki", "Rissalat Al Oumma"
81
+ ],
82
+ "festivals": [
83
+ "Festival de Marrakech", "Festival de Fès",
84
+ "Festival de Tan-Tan", "Festival de Rabat",
85
+ "Festival Mawazine", "Festival Jazzablanca",
86
+ "Festival de Taroudant", "Festival de Meknès",
87
+ "Festival de Ouarzazate", "Festival de Tanger",
88
+ "Festival de Chefchaouen", "Festival de Asilah"
89
+ ],
90
+ "music_genres": [
91
+ "Chaabi", "Gnawa", "Rai", "Pop", "Rock", "Hip-Hop",
92
+ "Rap", "Jazz", "Classique", "Électronique", "Reggae",
93
+ "Blues", "Country", "Folk", "Metal", "R&B"
94
+ ],
95
+ "movie_genres": [
96
+ "Action", "Comédie", "Drame", "Romance", "Thriller",
97
+ "Horreur", "Science-fiction", "Fantasy", "Documentaire",
98
+ "Animation", "Biographie", "Guerre", "Western", "Musical"
99
+ ],
100
+ "hobbies": [
101
+ "Football", "Basketball", "Tennis", "Natation", "Course à pied",
102
+ "Musique", "Danse", "Lecture", "Cinéma", "Voyage", "Cuisine",
103
+ "Photographie", "Peinture", "Jardinage", "Jeux vidéo",
104
+ "Échecs", "Pêche", "Randonnée", "Yoga", "Méditation"
105
+ ],
106
+ "sports": [
107
+ "Football", "Basketball", "Tennis", "Natation", "Athlétisme",
108
+ "Boxe", "Judo", "Karate", "Cyclisme", "Volleyball",
109
+ "Handball", "Rugby", "Golf", "Équitation", "Escalade"
110
+ ],
111
+ "social_media": [
112
+ "Facebook", "Instagram", "Twitter", "TikTok", "YouTube",
113
+ "LinkedIn", "Snapchat", "WhatsApp", "Telegram", "Discord"
114
+ ],
115
+ "transportation": [
116
+ "Voiture personnelle", "Taxi", "Bus", "Train", "Tramway",
117
+ "Moto", "Vélo", "Marche", "Covoiturage", "Uber/Careem"
118
+ ],
119
+ "pets": [
120
+ "Chat", "Chien", "Oiseau", "Poisson", "Hamster",
121
+ "Lapin", "Tortue", "Serpent", "Aucun animal"
122
+ ],
123
+ "colors": [
124
+ "Rouge", "Bleu", "Vert", "Jaune", "Orange", "Violet",
125
+ "Rose", "Noir", "Blanc", "Gris", "Marron", "Turquoise"
126
+ ]
127
+ }
@@ -0,0 +1,99 @@
1
+ {
2
+ "cities": [
3
+ "Casablanca", "Rabat", "Marrakech", "Fès", "Meknès", "Agadir", "Tanger",
4
+ "Oujda", "Kenitra", "Tétouan", "Safi", "Mohammedia", "El Jadida",
5
+ "Beni Mellal", "Khouribga", "Settat", "Larache", "Ksar El Kebir",
6
+ "Nador", "Berkane", "Errachidia", "Khemisset", "Ifrane", "Azrou",
7
+ "Chefchaouen", "Al Hoceima", "Taza", "Sidi Kacem", "El Kelaa",
8
+ "Ben Slimane", "Khémisset", "Sidi Bennour", "Youssoufia",
9
+ "Guelmim", "Taroudant", "Tinghir", "Zagora", "Sidi Ifni",
10
+ "Laâyoune", "Dakhla", "Boujdour", "Tan-Tan",
11
+ "Taourirt", "Ouarzazate", "Midelt", "Figuig", "Jerada",
12
+ "Sefrou", "Boulemane", "Taounate", "Guercif", "Imzouren",
13
+ "Fnideq", "Martil", "Saidia", "Ahfir", "Aklim",
14
+ "Tiznit", "Chtouka", "Ait Baha", "Biougra",
15
+ "Tata", "Foum Zguid", "Assa", "Zag",
16
+ "Smara", "Boukraa", "Bir Anzarane",
17
+ "Skhirat", "Temara", "Sale", "Skhirat",
18
+ "Bouskoura", "Mediouna", "Tit Mellil",
19
+ "Aïn Harrouda", "Harhoura", "Moulay Bousselham",
20
+ "Souk El Arbaa", "El Jadida", "Dar Bouazza",
21
+ "El Mansouria", "Bouskoura", "Mediouna",
22
+ "Nouaceur", "Berrechid", "Ben Ahmed",
23
+ "El Gara", "Bouknadel", "Skhirat", "Temara"
24
+ ],
25
+ "regions": [
26
+ "Casablanca-Settat", "Rabat-Salé-Kénitra",
27
+ "Fès-Meknès", "Marrakech-Safi",
28
+ "Tanger-Tétouan-Al Hoceïma",
29
+ "Oriental", "Béni Mellal-Khénifra",
30
+ "Drâa-Tafilalet", "Souss-Massa",
31
+ "Guelmim-Oued Noun", "Laâyoune-Sakia El Hamra",
32
+ "Dakhla-Oued Ed-Dahab"
33
+ ],
34
+ "provinces": [
35
+ "Casablanca", "Rabat", "Marrakech", "Fès", "Meknès",
36
+ "Agadir", "Tanger", "Oujda", "Kenitra", "Tétouan",
37
+ "Safi", "Mohammedia", "El Jadida", "Beni Mellal",
38
+ "Khouribga", "Settat", "Larache", "Nador", "Berkane",
39
+ "Errachidia", "Khemisset", "Ifrane", "Chefchaouen",
40
+ "Al Hoceima", "Taza", "Guelmim", "Taroudant",
41
+ "Laâyoune", "Dakhla", "Ouarzazate", "Midelt",
42
+ "Essaouira", "Azilal", "Boujdour", "Sidi Ifni",
43
+ "Tan-Tan", "Smara", "Fquih Ben Salah", "Sidi Kacem",
44
+ "Sidi Slimane", "Tinghir", "Zagora", "Taourirt",
45
+ "Jerada", "Guercif", "Chichaoua", "Youssoufia"
46
+ ],
47
+ "districts_by_city": {
48
+ "Casablanca": [
49
+ "Casablanca-Anfa", "Casablanca-Aïn Sebaa", "Casablanca-Hay Mohammadi",
50
+ "Casablanca-Sidi Bernoussi", "Casablanca-Mers Sultan", "Casablanca-Moulay Rachid",
51
+ "Casablanca-Sidi Othmane", "Casablanca-Ben M'sick", "Casablanca-Sidi Maarouf"
52
+ ],
53
+ "Rabat": [
54
+ "Rabat-Agdal", "Rabat-Hassan", "Rabat-Yacoub El Mansour",
55
+ "Rabat-Souissi", "Rabat-Océan", "Rabat-Medina"
56
+ ],
57
+ "Marrakech": [
58
+ "Marrakech-Médina", "Marrakech-Gueliz",
59
+ "Marrakech-Menara", "Marrakech-Sidi Youssef Ben Ali"
60
+ ],
61
+ "Fès": [
62
+ "Fès-Médina", "Fès-El Jdid-Dar Dbibegh", "Fès-Saïss", "Fès-Zouagha"
63
+ ],
64
+ "Agadir": [
65
+ "Agadir-Cité Dakhla", "Agadir-Talborjt", "Agadir-Ben Sergao", "Inezgane-Aït Melloul"
66
+ ],
67
+ "Tanger": [
68
+ "Tanger-Assilah", "Tanger-Médina", "Tanger-Marchan", "Tanger-Maghogha"
69
+ ],
70
+ "Meknès": [
71
+ "Meknès-Hamria", "Meknès-Medina", "Meknès-El Menzeh"
72
+ ]
73
+ },
74
+ "neighborhoods": [
75
+ "Medina", "Gueliz", "Maarif", "Anfa", "Derb Sultan",
76
+ "Hay Hassani", "Sbata", "Lissasfa", "Ain Diab",
77
+ "Racine", "Bourgogne", "Palmier", "Californie",
78
+ "Ouasis", "Sidi Bernoussi", "Mers Sultan",
79
+ "Agdal", "Yacoub El Mansour", "Hassan",
80
+ "Souissi", "La Gironde", "El Oulfa",
81
+ "L'Hivernage", "Marjane", "Touarga",
82
+ "Massira", "Sidi Moumen", "Hay Mohammadi",
83
+ "Ben M'sick", "Sidi Othman", "El Harti",
84
+ "Tabriquet", "Les Princes", "Sidi Maârouf",
85
+ "Diour", "Jamaâ", "Hay El Hanaa",
86
+ "Errahma", "Hay El Farah"
87
+ ],
88
+ "landmarks": [
89
+ "Mosquée Hassan II", "Place Jemaa el-Fnaa", "Médina de Fès",
90
+ "Chefchaouen", "Désert du Sahara", "Atlas", "Cascades d'Ouzoud",
91
+ "Gorges du Todra", "Vallée du Draa", "Merzouga",
92
+ "Aït Benhaddou", "Volubilis", "Médina de Marrakech",
93
+ "Kasbah des Oudayas", "Jardin Majorelle", "Palais Bahia",
94
+ "Kasbah Taourirt", "Chellah", "Plage d'Agadir", "Cap Spartel",
95
+ "Tétouan-Medina", "Mosquée Moulay Ismail", "Bab Mansour",
96
+ "Ouzoud Waterfalls", "Dades Valley", "Legzira Beach",
97
+ "Rabat Royal Palace", "Guelmim Desert Festival", "Erg Chebbi Dunes"
98
+ ]
99
+ }
@@ -0,0 +1,65 @@
1
+ {
2
+ "first_names": {
3
+ "male": [
4
+ "Ayoub", "Youssef", "Mohamed", "Ahmed", "Omar", "Hassan", "Ali", "Khalid", "Rachid",
5
+ "Abdelkader", "Abdelmoumen", "Abdelhak", "Abdelaziz", "Abdelouahed",
6
+ "Mustapha", "Brahim", "Reda", "Karim", "Anas", "Adil", "Yassine", "Nabil",
7
+ "Said", "Ismail", "Jamal", "Saad", "Soufiane", "Hamza", "Bilal", "Mehdi",
8
+ "Younes", "Ilyas", "Zakaria", "Ilyesse", "Tarik", "Noureddine", "Abdelilah",
9
+ "Mohammed", "Brahim", "Idriss", "Abdeljalil", "Abdelghani", "Abdelmajid",
10
+ "Othmane", "Amine", "Marouane", "Hicham", "Fouad", "Mourad", "Samir", "Imad",
11
+ "Hatim", "Rayan", "Ayman", "Idris", "Nacer", "Nizar", "Achraf", "Walid",
12
+ "Yassir", "Ihab", "Lotfi", "Chafik", "Abderrahim", "Abderrazak",
13
+ "Abdeslam", "Abdessamad"
14
+ ],
15
+ "female": [
16
+ "Fatima", "Zahra", "Aicha", "Khadija", "Malika", "Noura", "Salma", "Imane",
17
+ "Amina", "Soukaina", "Kawtar", "Houda", "Naima", "Hanane", "Latifa", "Zineb",
18
+ "Jamila", "Zakia", "Samira", "Nadia", "Farida", "Rachida", "Hakima",
19
+ "Laila", "Leila", "Hind", "Sana", "Sanaa", "Leila", "Sabah", "Meryem",
20
+ "Karima", "Fatiha", "Najat", "Hayat", "Hayat", "Rabia", "Asmaa",
21
+ "Nouria", "Badia", "Bahia", "Faiza", "Widad", "Wafa", "Asma",
22
+ "Rahma", "Safia", "Halima", "Abla", "Basma", "Loubna", "Nouha",
23
+ "Safaa", "Najwa", "Najiba", "Mouna", "Mounia", "Raja", "Rajaa",
24
+ "Sabah", "Sabah", "Racha", "Racha", "Rima", "Rim", "Lina", "Lyna",
25
+ "Sara", "Sarah", "Yasmina", "Yasmeen", "Lamia", "Lamya", "Laila",
26
+ "Ghita", "Chaimae", "Amal", "Siham", "Souad", "Ikram", "Saloua", "Rokia",
27
+ "Sonia", "Ilham", "Fadoua", "Kawthar", "Rania", "Meriem", "Houaria",
28
+ "Oumayma", "Yousra", "Douaa", "Iman", "Houdaifa", "Najoua", "Oumaima",
29
+ "Samah", "Nissrine"
30
+ ]
31
+ },
32
+ "last_names": [
33
+ "Amqor"," Amkor", "Alaoui", "Bennani", "El Fassi", "Idrissi", "Kabbaj", "Lamrani", "Mansouri",
34
+ "Benjelloun", "Chakir", "El Idrissi", "Haddouchi", "Kettani", "Laraki",
35
+ "Belhaj", "Belkadi", "Benkirane", "Benchekroun", "Benabdellah",
36
+ "Cherkaoui", "El Moutawakil", "El Amrani", "El Ouafi", "El Bachiri",
37
+ "Benali", "Benmansour", "Benhassan", "Benbrahim", "Benmoussa",
38
+ "El Khadiri", "El Yousfi", "El Haddadi", "El Kabbaj", "El Mansouri",
39
+ "Chraibi", "Berrada", "El Amraoui", "El Haouzi", "El Ouazzani",
40
+ "Tazi", "Alaoui", "Bennouna", "El Glaoui", "Bouazza",
41
+ "Bouabid", "Bouazza", "El Azzouzi", "El Arrousi",
42
+ "El Malki", "El Mansouri", "El Ouardi", "El Ouazzani",
43
+ "Benabbou", "Benabdeljalil", "Benachour", "Benadada",
44
+ "Benallal", "Benamara", "Benamghar", "Benanou",
45
+ "Benbachir", "Benbarka", "Benbouazza", "Benbrahim",
46
+ "Benchekroun", "Bendaoud", "Bendriss", "Benfares",
47
+ "Benhaddou", "Benhamou", "Benharbit", "Benjelloun",
48
+ "Benkirane", "Benmoha", "Benmoussa", "Bennani",
49
+ "Bennouna", "Benomar", "Benouhoud", "Bensalem",
50
+ "Benslimane", "Bentaleb", "Berada", "Berrada",
51
+ "Bouachrine", "Bouazza", "Bouazzati", "Boudraa",
52
+ "Boufous", "Bouhaddou", "Bouhlal", "Boujemaa",
53
+ "Boukhalef", "Boukhris", "Boulaich", "Boulahfa",
54
+ "Boumakh", "Boumediene", "Bounaim", "Bououid",
55
+ "Boussaid", "Boussetta", "Boutaleb", "Bouyaghchi",
56
+ "Chahboun", "Chahine", "Chaoui", "Cherkaoui",
57
+ "Chraibi", "Dahbi", "Dahmani", "Darif",
58
+ "Dkhissi", "Doukkali", "Echkoun", "El Adraoui",
59
+ "El Alaoui", "El Amraoui", "El Amrani", "El Azzouzi",
60
+ "El Bachiri", "El Bakkali", "El Barkani", "El Bouhali",
61
+ "El Fadili", "El Fassi", "El Glaoui", "El Hachimi",
62
+ "El Idrissi", "El Kadiri", "El Khattabi", "El Malki",
63
+ "El Mansouri", "El Ouafi", "El Ouazzani", "El Yamani"
64
+ ]
65
+ }