pak-geodata 0.1.0 → 0.2.2

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/dist/index.cjs CHANGED
@@ -25,13 +25,24 @@ __export(index_exports, {
25
25
  getAllAreas: () => getAllAreas,
26
26
  getAllCities: () => getAllCities,
27
27
  getAllProvinces: () => getAllProvinces,
28
+ getAreaName: () => getAreaName,
29
+ getAreasAsLocationItems: () => getAreasAsLocationItems,
28
30
  getAreasByCity: () => getAreasByCity,
31
+ getCitiesAsLocationItems: () => getCitiesAsLocationItems,
29
32
  getCitiesByProvince: () => getCitiesByProvince,
30
33
  getCityById: () => getCityById,
31
- getNearestArea: () => getNearestArea2,
34
+ getCityName: () => getCityName,
35
+ getNearestArea: () => getNearestArea,
32
36
  getProvinceById: () => getProvinceById,
37
+ getProvincesAsLocationItems: () => getProvincesAsLocationItems,
33
38
  haversineDistanceKm: () => haversineDistanceKm,
34
- searchAreas: () => searchAreas2
39
+ normalizeUrduText: () => normalizeUrduText,
40
+ searchAreas: () => searchAreas,
41
+ searchLocationItems: () => searchLocationItems,
42
+ stripUrduDiacritics: () => stripUrduDiacritics,
43
+ toEasternDigits: () => toEasternDigits,
44
+ toLocationItem: () => toLocationItem,
45
+ toWesternDigits: () => toWesternDigits
35
46
  });
36
47
  module.exports = __toCommonJS(index_exports);
37
48
 
@@ -182,6 +193,75 @@ var cities = [
182
193
  },
183
194
  "totalAreasCount": 0
184
195
  },
196
+ {
197
+ "id": "bhimber",
198
+ "name": "Bhimber",
199
+ "urduName": "\u0628\u06BE\u0645\u0628\u0631",
200
+ "provinceId": "ajk",
201
+ "division": "Mirpur Division",
202
+ "district": "Bhimber",
203
+ "coordinates": {
204
+ "lat": 32.9745,
205
+ "lng": 74.0789
206
+ },
207
+ "postalCodeRange": [
208
+ "10050",
209
+ "10099"
210
+ ],
211
+ "bounds": {
212
+ "minLat": 32.93,
213
+ "maxLat": 33.02,
214
+ "minLng": 74.03,
215
+ "maxLng": 74.13
216
+ },
217
+ "totalAreasCount": 0
218
+ },
219
+ {
220
+ "id": "bagh",
221
+ "name": "Bagh",
222
+ "urduName": "\u0628\u0627\u063A",
223
+ "provinceId": "ajk",
224
+ "division": "Poonch Division",
225
+ "district": "Bagh",
226
+ "coordinates": {
227
+ "lat": 33.98,
228
+ "lng": 73.79
229
+ },
230
+ "postalCodeRange": [
231
+ "12500",
232
+ "12550"
233
+ ],
234
+ "bounds": {
235
+ "minLat": 33.94,
236
+ "maxLat": 34.02,
237
+ "minLng": 73.74,
238
+ "maxLng": 73.84
239
+ },
240
+ "totalAreasCount": 0
241
+ },
242
+ {
243
+ "id": "pallandri",
244
+ "name": "Pallandri",
245
+ "urduName": "\u067E\u0644\u0646\u062F\u0631\u06CC",
246
+ "provinceId": "ajk",
247
+ "division": "Poonch Division",
248
+ "district": "Sudhanoti",
249
+ "coordinates": {
250
+ "lat": 33.7128,
251
+ "lng": 73.6892
252
+ },
253
+ "postalCodeRange": [
254
+ "12050",
255
+ "12099"
256
+ ],
257
+ "bounds": {
258
+ "minLat": 33.67,
259
+ "maxLat": 33.76,
260
+ "minLng": 73.64,
261
+ "maxLng": 73.74
262
+ },
263
+ "totalAreasCount": 0
264
+ },
185
265
  {
186
266
  "id": "quetta",
187
267
  "name": "Quetta",
@@ -297,6 +377,121 @@ var cities = [
297
377
  },
298
378
  "totalAreasCount": 0
299
379
  },
380
+ {
381
+ "id": "chaman",
382
+ "name": "Chaman",
383
+ "urduName": "\u0686\u0645\u0646",
384
+ "provinceId": "balochistan",
385
+ "division": "Quetta Division",
386
+ "district": "Chaman",
387
+ "coordinates": {
388
+ "lat": 30.921,
389
+ "lng": 66.4597
390
+ },
391
+ "postalCodeRange": [
392
+ "86000",
393
+ "86050"
394
+ ],
395
+ "bounds": {
396
+ "minLat": 30.87,
397
+ "maxLat": 30.97,
398
+ "minLng": 66.41,
399
+ "maxLng": 66.51
400
+ },
401
+ "totalAreasCount": 0
402
+ },
403
+ {
404
+ "id": "sibi",
405
+ "name": "Sibi",
406
+ "urduName": "\u0633\u0628\u06CC",
407
+ "provinceId": "balochistan",
408
+ "division": "Sibi Division",
409
+ "district": "Sibi",
410
+ "coordinates": {
411
+ "lat": 29.5448,
412
+ "lng": 67.8764
413
+ },
414
+ "postalCodeRange": [
415
+ "82000",
416
+ "82050"
417
+ ],
418
+ "bounds": {
419
+ "minLat": 29.5,
420
+ "maxLat": 29.59,
421
+ "minLng": 67.83,
422
+ "maxLng": 67.92
423
+ },
424
+ "totalAreasCount": 0
425
+ },
426
+ {
427
+ "id": "zhob",
428
+ "name": "Zhob",
429
+ "urduName": "\u0698\u0648\u0628",
430
+ "provinceId": "balochistan",
431
+ "division": "Zhob Division",
432
+ "district": "Zhob",
433
+ "coordinates": {
434
+ "lat": 31.3417,
435
+ "lng": 69.4486
436
+ },
437
+ "postalCodeRange": [
438
+ "85200",
439
+ "85250"
440
+ ],
441
+ "bounds": {
442
+ "minLat": 31.3,
443
+ "maxLat": 31.39,
444
+ "minLng": 69.4,
445
+ "maxLng": 69.5
446
+ },
447
+ "totalAreasCount": 0
448
+ },
449
+ {
450
+ "id": "loralai",
451
+ "name": "Loralai",
452
+ "urduName": "\u0644\u0648\u0631\u0627\u0644\u0627\u0626\u06CC",
453
+ "provinceId": "balochistan",
454
+ "division": "Loralai Division",
455
+ "district": "Loralai",
456
+ "coordinates": {
457
+ "lat": 30.3705,
458
+ "lng": 68.5979
459
+ },
460
+ "postalCodeRange": [
461
+ "84800",
462
+ "84850"
463
+ ],
464
+ "bounds": {
465
+ "minLat": 30.33,
466
+ "maxLat": 30.42,
467
+ "minLng": 68.55,
468
+ "maxLng": 68.65
469
+ },
470
+ "totalAreasCount": 0
471
+ },
472
+ {
473
+ "id": "dera-murad-jamali",
474
+ "name": "Dera Murad Jamali",
475
+ "urduName": "\u0688\u06CC\u0631\u06C1 \u0645\u0631\u0627\u062F \u062C\u0645\u0627\u0644\u06CC",
476
+ "provinceId": "balochistan",
477
+ "division": "Nasirabad Division",
478
+ "district": "Nasirabad",
479
+ "coordinates": {
480
+ "lat": 28.5466,
481
+ "lng": 68.2231
482
+ },
483
+ "postalCodeRange": [
484
+ "80100",
485
+ "80150"
486
+ ],
487
+ "bounds": {
488
+ "minLat": 28.5,
489
+ "maxLat": 28.59,
490
+ "minLng": 68.18,
491
+ "maxLng": 68.27
492
+ },
493
+ "totalAreasCount": 0
494
+ },
300
495
  {
301
496
  "id": "gilgit",
302
497
  "name": "Gilgit",
@@ -389,6 +584,75 @@ var cities = [
389
584
  },
390
585
  "totalAreasCount": 0
391
586
  },
587
+ {
588
+ "id": "aliabad-hunza",
589
+ "name": "Aliabad",
590
+ "urduName": "\u0639\u0644\u06CC \u0622\u0628\u0627\u062F",
591
+ "provinceId": "gilgit-baltistan",
592
+ "division": "Gilgit Division",
593
+ "district": "Hunza",
594
+ "coordinates": {
595
+ "lat": 36.3075,
596
+ "lng": 74.6158
597
+ },
598
+ "postalCodeRange": [
599
+ "15710",
600
+ "15740"
601
+ ],
602
+ "bounds": {
603
+ "minLat": 36.27,
604
+ "maxLat": 36.34,
605
+ "minLng": 74.57,
606
+ "maxLng": 74.66
607
+ },
608
+ "totalAreasCount": 0
609
+ },
610
+ {
611
+ "id": "gahkuch",
612
+ "name": "Gahkuch",
613
+ "urduName": "\u06AF\u0627\u06C1\u06A9\u0648\u0686",
614
+ "provinceId": "gilgit-baltistan",
615
+ "division": "Gilgit Division",
616
+ "district": "Ghizer",
617
+ "coordinates": {
618
+ "lat": 36.1736,
619
+ "lng": 73.7656
620
+ },
621
+ "postalCodeRange": [
622
+ "15200",
623
+ "15250"
624
+ ],
625
+ "bounds": {
626
+ "minLat": 36.14,
627
+ "maxLat": 36.21,
628
+ "minLng": 73.72,
629
+ "maxLng": 73.81
630
+ },
631
+ "totalAreasCount": 0
632
+ },
633
+ {
634
+ "id": "khaplu",
635
+ "name": "Khaplu",
636
+ "urduName": "\u062E\u067E\u0644\u0648",
637
+ "provinceId": "gilgit-baltistan",
638
+ "division": "Baltistan Division",
639
+ "district": "Ghanche",
640
+ "coordinates": {
641
+ "lat": 35.155,
642
+ "lng": 76.335
643
+ },
644
+ "postalCodeRange": [
645
+ "16300",
646
+ "16350"
647
+ ],
648
+ "bounds": {
649
+ "minLat": 35.12,
650
+ "maxLat": 35.19,
651
+ "minLng": 76.29,
652
+ "maxLng": 76.38
653
+ },
654
+ "totalAreasCount": 0
655
+ },
392
656
  {
393
657
  "id": "islamabad",
394
658
  "name": "Islamabad",
@@ -550,6 +814,75 @@ var cities = [
550
814
  },
551
815
  "totalAreasCount": 0
552
816
  },
817
+ {
818
+ "id": "nowshera",
819
+ "name": "Nowshera",
820
+ "urduName": "\u0646\u0648\u0634\u06C1\u0631\u06C1",
821
+ "provinceId": "kpk",
822
+ "division": "Peshawar Division",
823
+ "district": "Nowshera",
824
+ "coordinates": {
825
+ "lat": 34.0153,
826
+ "lng": 71.9747
827
+ },
828
+ "postalCodeRange": [
829
+ "24100",
830
+ "24199"
831
+ ],
832
+ "bounds": {
833
+ "minLat": 33.96,
834
+ "maxLat": 34.07,
835
+ "minLng": 71.92,
836
+ "maxLng": 72.03
837
+ },
838
+ "totalAreasCount": 0
839
+ },
840
+ {
841
+ "id": "swabi",
842
+ "name": "Swabi",
843
+ "urduName": "\u0635\u0648\u0627\u0628\u06CC",
844
+ "provinceId": "kpk",
845
+ "division": "Mardan Division",
846
+ "district": "Swabi",
847
+ "coordinates": {
848
+ "lat": 34.1202,
849
+ "lng": 72.4698
850
+ },
851
+ "postalCodeRange": [
852
+ "23430",
853
+ "23499"
854
+ ],
855
+ "bounds": {
856
+ "minLat": 34.07,
857
+ "maxLat": 34.17,
858
+ "minLng": 72.41,
859
+ "maxLng": 72.52
860
+ },
861
+ "totalAreasCount": 0
862
+ },
863
+ {
864
+ "id": "mansehra",
865
+ "name": "Mansehra",
866
+ "urduName": "\u0645\u0627\u0646\u0633\u06C1\u0631\u06C1",
867
+ "provinceId": "kpk",
868
+ "division": "Hazara Division",
869
+ "district": "Mansehra",
870
+ "coordinates": {
871
+ "lat": 34.3333,
872
+ "lng": 73.2
873
+ },
874
+ "postalCodeRange": [
875
+ "21300",
876
+ "21399"
877
+ ],
878
+ "bounds": {
879
+ "minLat": 34.28,
880
+ "maxLat": 34.39,
881
+ "minLng": 73.15,
882
+ "maxLng": 73.26
883
+ },
884
+ "totalAreasCount": 0
885
+ },
553
886
  {
554
887
  "id": "lahore",
555
888
  "name": "Lahore",
@@ -781,94 +1114,623 @@ var cities = [
781
1114
  "totalAreasCount": 0
782
1115
  },
783
1116
  {
784
- "id": "sahiwal",
785
- "name": "Sahiwal",
786
- "urduName": "\u0633\u0627\u06C1\u06CC\u0648\u0627\u0644",
1117
+ "id": "sahiwal",
1118
+ "name": "Sahiwal",
1119
+ "urduName": "\u0633\u0627\u06C1\u06CC\u0648\u0627\u0644",
1120
+ "provinceId": "punjab",
1121
+ "division": "Sahiwal Division",
1122
+ "district": "Sahiwal",
1123
+ "coordinates": {
1124
+ "lat": 30.6682,
1125
+ "lng": 73.1114
1126
+ },
1127
+ "postalCodeRange": [
1128
+ "57000",
1129
+ "57099"
1130
+ ],
1131
+ "bounds": {
1132
+ "minLat": 30.6,
1133
+ "maxLat": 30.73,
1134
+ "minLng": 73.04,
1135
+ "maxLng": 73.18
1136
+ },
1137
+ "totalAreasCount": 0
1138
+ },
1139
+ {
1140
+ "id": "jhelum",
1141
+ "name": "Jhelum",
1142
+ "urduName": "\u062C\u06C1\u0644\u0645",
1143
+ "provinceId": "punjab",
1144
+ "division": "Rawalpindi Division",
1145
+ "district": "Jhelum",
1146
+ "coordinates": {
1147
+ "lat": 32.9425,
1148
+ "lng": 73.7257
1149
+ },
1150
+ "postalCodeRange": [
1151
+ "49600",
1152
+ "49699"
1153
+ ],
1154
+ "bounds": {
1155
+ "minLat": 32.88,
1156
+ "maxLat": 33,
1157
+ "minLng": 73.66,
1158
+ "maxLng": 73.79
1159
+ },
1160
+ "totalAreasCount": 0
1161
+ },
1162
+ {
1163
+ "id": "kasur",
1164
+ "name": "Kasur",
1165
+ "urduName": "\u0642\u0635\u0648\u0631",
1166
+ "provinceId": "punjab",
1167
+ "division": "Lahore Division",
1168
+ "district": "Kasur",
1169
+ "coordinates": {
1170
+ "lat": 31.1179,
1171
+ "lng": 74.4461
1172
+ },
1173
+ "postalCodeRange": [
1174
+ "55050",
1175
+ "55099"
1176
+ ],
1177
+ "bounds": {
1178
+ "minLat": 31.06,
1179
+ "maxLat": 31.17,
1180
+ "minLng": 74.39,
1181
+ "maxLng": 74.5
1182
+ },
1183
+ "totalAreasCount": 0
1184
+ },
1185
+ {
1186
+ "id": "rahim-yar-khan",
1187
+ "name": "Rahim Yar Khan",
1188
+ "urduName": "\u0631\u062D\u06CC\u0645 \u06CC\u0627\u0631 \u062E\u0627\u0646",
1189
+ "provinceId": "punjab",
1190
+ "division": "Bahawalpur Division",
1191
+ "district": "Rahim Yar Khan",
1192
+ "coordinates": {
1193
+ "lat": 28.4195,
1194
+ "lng": 70.3024
1195
+ },
1196
+ "postalCodeRange": [
1197
+ "64200",
1198
+ "64299"
1199
+ ],
1200
+ "bounds": {
1201
+ "minLat": 28.36,
1202
+ "maxLat": 28.48,
1203
+ "minLng": 70.24,
1204
+ "maxLng": 70.36
1205
+ },
1206
+ "totalAreasCount": 0
1207
+ },
1208
+ {
1209
+ "id": "attock",
1210
+ "name": "Attock",
1211
+ "urduName": "\u0627\u0679\u06A9",
1212
+ "provinceId": "punjab",
1213
+ "division": "Rawalpindi Division",
1214
+ "district": "Attock",
1215
+ "coordinates": {
1216
+ "lat": 33.766,
1217
+ "lng": 72.3609
1218
+ },
1219
+ "postalCodeRange": [
1220
+ "43600",
1221
+ "43699"
1222
+ ],
1223
+ "bounds": {
1224
+ "minLat": 33.7,
1225
+ "maxLat": 33.82,
1226
+ "minLng": 72.3,
1227
+ "maxLng": 72.42
1228
+ },
1229
+ "totalAreasCount": 0
1230
+ },
1231
+ {
1232
+ "id": "bahawalnagar",
1233
+ "name": "Bahawalnagar",
1234
+ "urduName": "\u0628\u06C1\u0627\u0648\u0644\u0646\u06AF\u0631",
1235
+ "provinceId": "punjab",
1236
+ "division": "Bahawalpur Division",
1237
+ "district": "Bahawalnagar",
1238
+ "coordinates": {
1239
+ "lat": 29.9961,
1240
+ "lng": 73.2536
1241
+ },
1242
+ "postalCodeRange": [
1243
+ "62300",
1244
+ "62399"
1245
+ ],
1246
+ "bounds": {
1247
+ "minLat": 29.93,
1248
+ "maxLat": 30.06,
1249
+ "minLng": 73.19,
1250
+ "maxLng": 73.31
1251
+ },
1252
+ "totalAreasCount": 0
1253
+ },
1254
+ {
1255
+ "id": "chakwal",
1256
+ "name": "Chakwal",
1257
+ "urduName": "\u0686\u06A9\u0648\u0627\u0644",
1258
+ "provinceId": "punjab",
1259
+ "division": "Rawalpindi Division",
1260
+ "district": "Chakwal",
1261
+ "coordinates": {
1262
+ "lat": 32.9328,
1263
+ "lng": 72.863
1264
+ },
1265
+ "postalCodeRange": [
1266
+ "48800",
1267
+ "48899"
1268
+ ],
1269
+ "bounds": {
1270
+ "minLat": 32.88,
1271
+ "maxLat": 32.98,
1272
+ "minLng": 72.8,
1273
+ "maxLng": 72.92
1274
+ },
1275
+ "totalAreasCount": 0
1276
+ },
1277
+ {
1278
+ "id": "chiniot",
1279
+ "name": "Chiniot",
1280
+ "urduName": "\u0686\u0646\u06CC\u0648\u0679",
1281
+ "provinceId": "punjab",
1282
+ "division": "Faisalabad Division",
1283
+ "district": "Chiniot",
1284
+ "coordinates": {
1285
+ "lat": 31.72,
1286
+ "lng": 72.9789
1287
+ },
1288
+ "postalCodeRange": [
1289
+ "35400",
1290
+ "35499"
1291
+ ],
1292
+ "bounds": {
1293
+ "minLat": 31.66,
1294
+ "maxLat": 31.78,
1295
+ "minLng": 72.92,
1296
+ "maxLng": 73.04
1297
+ },
1298
+ "totalAreasCount": 0
1299
+ },
1300
+ {
1301
+ "id": "chishtian",
1302
+ "name": "Chishtian",
1303
+ "urduName": "\u0686\u0634\u062A\u06CC\u0627\u06BA",
1304
+ "provinceId": "punjab",
1305
+ "division": "Bahawalpur Division",
1306
+ "district": "Bahawalnagar",
1307
+ "coordinates": {
1308
+ "lat": 29.7972,
1309
+ "lng": 72.8578
1310
+ },
1311
+ "postalCodeRange": [
1312
+ "62250",
1313
+ "62299"
1314
+ ],
1315
+ "bounds": {
1316
+ "minLat": 29.74,
1317
+ "maxLat": 29.85,
1318
+ "minLng": 72.8,
1319
+ "maxLng": 72.91
1320
+ },
1321
+ "totalAreasCount": 0
1322
+ },
1323
+ {
1324
+ "id": "daska",
1325
+ "name": "Daska",
1326
+ "urduName": "\u0688\u0633\u06A9\u06C1",
1327
+ "provinceId": "punjab",
1328
+ "division": "Gujranwala Division",
1329
+ "district": "Sialkot",
1330
+ "coordinates": {
1331
+ "lat": 32.3242,
1332
+ "lng": 74.3503
1333
+ },
1334
+ "postalCodeRange": [
1335
+ "51010",
1336
+ "51049"
1337
+ ],
1338
+ "bounds": {
1339
+ "minLat": 32.27,
1340
+ "maxLat": 32.37,
1341
+ "minLng": 74.3,
1342
+ "maxLng": 74.4
1343
+ },
1344
+ "totalAreasCount": 0
1345
+ },
1346
+ {
1347
+ "id": "dera-ghazi-khan",
1348
+ "name": "Dera Ghazi Khan",
1349
+ "urduName": "\u0688\u06CC\u0631\u06C1 \u063A\u0627\u0632\u06CC \u062E\u0627\u0646",
1350
+ "provinceId": "punjab",
1351
+ "division": "Dera Ghazi Khan Division",
1352
+ "district": "Dera Ghazi Khan",
1353
+ "coordinates": {
1354
+ "lat": 30.0561,
1355
+ "lng": 70.6348
1356
+ },
1357
+ "postalCodeRange": [
1358
+ "32200",
1359
+ "32299"
1360
+ ],
1361
+ "bounds": {
1362
+ "minLat": 29.99,
1363
+ "maxLat": 30.12,
1364
+ "minLng": 70.57,
1365
+ "maxLng": 70.7
1366
+ },
1367
+ "totalAreasCount": 0
1368
+ },
1369
+ {
1370
+ "id": "gojra",
1371
+ "name": "Gojra",
1372
+ "urduName": "\u06AF\u0648\u062C\u0631\u06C1",
1373
+ "provinceId": "punjab",
1374
+ "division": "Faisalabad Division",
1375
+ "district": "Toba Tek Singh",
1376
+ "coordinates": {
1377
+ "lat": 31.1492,
1378
+ "lng": 72.6836
1379
+ },
1380
+ "postalCodeRange": [
1381
+ "36120",
1382
+ "36149"
1383
+ ],
1384
+ "bounds": {
1385
+ "minLat": 31.1,
1386
+ "maxLat": 31.2,
1387
+ "minLng": 72.63,
1388
+ "maxLng": 72.74
1389
+ },
1390
+ "totalAreasCount": 0
1391
+ },
1392
+ {
1393
+ "id": "hafizabad",
1394
+ "name": "Hafizabad",
1395
+ "urduName": "\u062D\u0627\u0641\u0638 \u0622\u0628\u0627\u062F",
1396
+ "provinceId": "punjab",
1397
+ "division": "Gujranwala Division",
1398
+ "district": "Hafizabad",
1399
+ "coordinates": {
1400
+ "lat": 32.0679,
1401
+ "lng": 73.6872
1402
+ },
1403
+ "postalCodeRange": [
1404
+ "52110",
1405
+ "52199"
1406
+ ],
1407
+ "bounds": {
1408
+ "minLat": 32.01,
1409
+ "maxLat": 32.12,
1410
+ "minLng": 73.63,
1411
+ "maxLng": 73.74
1412
+ },
1413
+ "totalAreasCount": 0
1414
+ },
1415
+ {
1416
+ "id": "jhang",
1417
+ "name": "Jhang",
1418
+ "urduName": "\u062C\u06BE\u0646\u06AF",
1419
+ "provinceId": "punjab",
1420
+ "division": "Faisalabad Division",
1421
+ "district": "Jhang",
1422
+ "coordinates": {
1423
+ "lat": 31.2781,
1424
+ "lng": 72.3167
1425
+ },
1426
+ "postalCodeRange": [
1427
+ "35200",
1428
+ "35299"
1429
+ ],
1430
+ "bounds": {
1431
+ "minLat": 31.21,
1432
+ "maxLat": 31.34,
1433
+ "minLng": 72.26,
1434
+ "maxLng": 72.38
1435
+ },
1436
+ "totalAreasCount": 0
1437
+ },
1438
+ {
1439
+ "id": "jaranwala",
1440
+ "name": "Jaranwala",
1441
+ "urduName": "\u062C\u0691\u0627\u0646\u0648\u0627\u0644\u06C1",
1442
+ "provinceId": "punjab",
1443
+ "division": "Faisalabad Division",
1444
+ "district": "Faisalabad",
1445
+ "coordinates": {
1446
+ "lat": 31.3342,
1447
+ "lng": 73.4194
1448
+ },
1449
+ "postalCodeRange": [
1450
+ "37200",
1451
+ "37299"
1452
+ ],
1453
+ "bounds": {
1454
+ "minLat": 31.28,
1455
+ "maxLat": 31.39,
1456
+ "minLng": 73.36,
1457
+ "maxLng": 73.47
1458
+ },
1459
+ "totalAreasCount": 0
1460
+ },
1461
+ {
1462
+ "id": "kamalia",
1463
+ "name": "Kamalia",
1464
+ "urduName": "\u06A9\u0645\u0627\u0644\u06CC\u06C1",
1465
+ "provinceId": "punjab",
1466
+ "division": "Faisalabad Division",
1467
+ "district": "Toba Tek Singh",
1468
+ "coordinates": {
1469
+ "lat": 30.7258,
1470
+ "lng": 72.6447
1471
+ },
1472
+ "postalCodeRange": [
1473
+ "36350",
1474
+ "36399"
1475
+ ],
1476
+ "bounds": {
1477
+ "minLat": 30.68,
1478
+ "maxLat": 30.77,
1479
+ "minLng": 72.59,
1480
+ "maxLng": 72.7
1481
+ },
1482
+ "totalAreasCount": 0
1483
+ },
1484
+ {
1485
+ "id": "khanewal",
1486
+ "name": "Khanewal",
1487
+ "urduName": "\u062E\u0627\u0646\u06CC\u0648\u0627\u0644",
1488
+ "provinceId": "punjab",
1489
+ "division": "Multan Division",
1490
+ "district": "Khanewal",
1491
+ "coordinates": {
1492
+ "lat": 30.3017,
1493
+ "lng": 71.9321
1494
+ },
1495
+ "postalCodeRange": [
1496
+ "58150",
1497
+ "58199"
1498
+ ],
1499
+ "bounds": {
1500
+ "minLat": 30.25,
1501
+ "maxLat": 30.36,
1502
+ "minLng": 71.88,
1503
+ "maxLng": 71.99
1504
+ },
1505
+ "totalAreasCount": 0
1506
+ },
1507
+ {
1508
+ "id": "kot-addu",
1509
+ "name": "Kot Addu",
1510
+ "urduName": "\u06A9\u0648\u0679 \u0627\u062F\u0648",
1511
+ "provinceId": "punjab",
1512
+ "division": "Dera Ghazi Khan Division",
1513
+ "district": "Kot Addu",
1514
+ "coordinates": {
1515
+ "lat": 30.47,
1516
+ "lng": 70.9644
1517
+ },
1518
+ "postalCodeRange": [
1519
+ "34050",
1520
+ "34099"
1521
+ ],
1522
+ "bounds": {
1523
+ "minLat": 30.42,
1524
+ "maxLat": 30.52,
1525
+ "minLng": 70.91,
1526
+ "maxLng": 71.02
1527
+ },
1528
+ "totalAreasCount": 0
1529
+ },
1530
+ {
1531
+ "id": "mandi-bahauddin",
1532
+ "name": "Mandi Bahauddin",
1533
+ "urduName": "\u0645\u0646\u0688\u06CC \u0628\u06C1\u0627\u0624\u0627\u0644\u062F\u06CC\u0646",
1534
+ "provinceId": "punjab",
1535
+ "division": "Gujranwala Division",
1536
+ "district": "Mandi Bahauddin",
1537
+ "coordinates": {
1538
+ "lat": 32.587,
1539
+ "lng": 73.4912
1540
+ },
1541
+ "postalCodeRange": [
1542
+ "50400",
1543
+ "50499"
1544
+ ],
1545
+ "bounds": {
1546
+ "minLat": 32.53,
1547
+ "maxLat": 32.64,
1548
+ "minLng": 73.43,
1549
+ "maxLng": 73.54
1550
+ },
1551
+ "totalAreasCount": 0
1552
+ },
1553
+ {
1554
+ "id": "muridke",
1555
+ "name": "Muridke",
1556
+ "urduName": "\u0645\u0631\u06CC\u062F\u06A9\u06D2",
1557
+ "provinceId": "punjab",
1558
+ "division": "Lahore Division",
1559
+ "district": "Sheikhupura",
1560
+ "coordinates": {
1561
+ "lat": 31.802,
1562
+ "lng": 74.255
1563
+ },
1564
+ "postalCodeRange": [
1565
+ "39010",
1566
+ "39049"
1567
+ ],
1568
+ "bounds": {
1569
+ "minLat": 31.75,
1570
+ "maxLat": 31.85,
1571
+ "minLng": 74.2,
1572
+ "maxLng": 74.31
1573
+ },
1574
+ "totalAreasCount": 0
1575
+ },
1576
+ {
1577
+ "id": "muzaffargarh",
1578
+ "name": "Muzaffargarh",
1579
+ "urduName": "\u0645\u0638\u0641\u0631 \u06AF\u0691\u06BE",
1580
+ "provinceId": "punjab",
1581
+ "division": "Dera Ghazi Khan Division",
1582
+ "district": "Muzaffargarh",
1583
+ "coordinates": {
1584
+ "lat": 30.075,
1585
+ "lng": 71.192
1586
+ },
1587
+ "postalCodeRange": [
1588
+ "34200",
1589
+ "34299"
1590
+ ],
1591
+ "bounds": {
1592
+ "minLat": 30.02,
1593
+ "maxLat": 30.13,
1594
+ "minLng": 71.13,
1595
+ "maxLng": 71.25
1596
+ },
1597
+ "totalAreasCount": 0
1598
+ },
1599
+ {
1600
+ "id": "okara",
1601
+ "name": "Okara",
1602
+ "urduName": "\u0627\u0648\u06A9\u0627\u0691\u06C1",
1603
+ "provinceId": "punjab",
1604
+ "division": "Sahiwal Division",
1605
+ "district": "Okara",
1606
+ "coordinates": {
1607
+ "lat": 30.808,
1608
+ "lng": 73.4458
1609
+ },
1610
+ "postalCodeRange": [
1611
+ "56300",
1612
+ "56399"
1613
+ ],
1614
+ "bounds": {
1615
+ "minLat": 30.75,
1616
+ "maxLat": 30.86,
1617
+ "minLng": 73.39,
1618
+ "maxLng": 73.5
1619
+ },
1620
+ "totalAreasCount": 0
1621
+ },
1622
+ {
1623
+ "id": "samundri",
1624
+ "name": "Samundri",
1625
+ "urduName": "\u0633\u0645\u0646\u062F\u0631\u06CC",
1626
+ "provinceId": "punjab",
1627
+ "division": "Faisalabad Division",
1628
+ "district": "Faisalabad",
1629
+ "coordinates": {
1630
+ "lat": 31.0633,
1631
+ "lng": 72.9525
1632
+ },
1633
+ "postalCodeRange": [
1634
+ "37300",
1635
+ "37349"
1636
+ ],
1637
+ "bounds": {
1638
+ "minLat": 31.01,
1639
+ "maxLat": 31.11,
1640
+ "minLng": 72.9,
1641
+ "maxLng": 73
1642
+ },
1643
+ "totalAreasCount": 0
1644
+ },
1645
+ {
1646
+ "id": "taxila",
1647
+ "name": "Taxila",
1648
+ "urduName": "\u0679\u06CC\u06A9\u0633\u0644\u0627",
787
1649
  "provinceId": "punjab",
788
- "division": "Sahiwal Division",
789
- "district": "Sahiwal",
1650
+ "division": "Rawalpindi Division",
1651
+ "district": "Rawalpindi",
790
1652
  "coordinates": {
791
- "lat": 30.6682,
792
- "lng": 73.1114
1653
+ "lat": 33.746,
1654
+ "lng": 72.8397
793
1655
  },
794
1656
  "postalCodeRange": [
795
- "57000",
796
- "57099"
1657
+ "47080",
1658
+ "47099"
797
1659
  ],
798
1660
  "bounds": {
799
- "minLat": 30.6,
800
- "maxLat": 30.73,
801
- "minLng": 73.04,
802
- "maxLng": 73.18
1661
+ "minLat": 33.7,
1662
+ "maxLat": 33.79,
1663
+ "minLng": 72.79,
1664
+ "maxLng": 72.89
803
1665
  },
804
1666
  "totalAreasCount": 0
805
1667
  },
806
1668
  {
807
- "id": "jhelum",
808
- "name": "Jhelum",
809
- "urduName": "\u062C\u06C1\u0644\u0645",
1669
+ "id": "vehari",
1670
+ "name": "Vehari",
1671
+ "urduName": "\u0648\u06C1\u0627\u0691\u06CC",
810
1672
  "provinceId": "punjab",
811
- "division": "Rawalpindi Division",
812
- "district": "Jhelum",
1673
+ "division": "Multan Division",
1674
+ "district": "Vehari",
813
1675
  "coordinates": {
814
- "lat": 32.9425,
815
- "lng": 73.7257
1676
+ "lat": 30.0419,
1677
+ "lng": 72.3528
816
1678
  },
817
1679
  "postalCodeRange": [
818
- "49600",
819
- "49699"
1680
+ "61100",
1681
+ "61199"
820
1682
  ],
821
1683
  "bounds": {
822
- "minLat": 32.88,
823
- "maxLat": 33,
824
- "minLng": 73.66,
825
- "maxLng": 73.79
1684
+ "minLat": 29.99,
1685
+ "maxLat": 30.09,
1686
+ "minLng": 72.3,
1687
+ "maxLng": 72.4
826
1688
  },
827
1689
  "totalAreasCount": 0
828
1690
  },
829
1691
  {
830
- "id": "kasur",
831
- "name": "Kasur",
832
- "urduName": "\u0642\u0635\u0648\u0631",
1692
+ "id": "wah-cantt",
1693
+ "name": "Wah Cantt",
1694
+ "urduName": "\u0648\u0627\u06C1 \u06A9\u06CC\u0646\u0679",
833
1695
  "provinceId": "punjab",
834
- "division": "Lahore Division",
835
- "district": "Kasur",
1696
+ "division": "Rawalpindi Division",
1697
+ "district": "Rawalpindi",
836
1698
  "coordinates": {
837
- "lat": 31.1179,
838
- "lng": 74.4461
1699
+ "lat": 33.7715,
1700
+ "lng": 72.7511
839
1701
  },
840
1702
  "postalCodeRange": [
841
- "55050",
842
- "55099"
1703
+ "47040",
1704
+ "47079"
843
1705
  ],
844
1706
  "bounds": {
845
- "minLat": 31.06,
846
- "maxLat": 31.17,
847
- "minLng": 74.39,
848
- "maxLng": 74.5
1707
+ "minLat": 33.72,
1708
+ "maxLat": 33.82,
1709
+ "minLng": 72.7,
1710
+ "maxLng": 72.8
849
1711
  },
850
1712
  "totalAreasCount": 0
851
1713
  },
852
1714
  {
853
- "id": "rahim-yar-khan",
854
- "name": "Rahim Yar Khan",
855
- "urduName": "\u0631\u062D\u06CC\u0645 \u06CC\u0627\u0631 \u062E\u0627\u0646",
1715
+ "id": "wazirabad",
1716
+ "name": "Wazirabad",
1717
+ "urduName": "\u0648\u0632\u06CC\u0631 \u0622\u0628\u0627\u062F",
856
1718
  "provinceId": "punjab",
857
- "division": "Bahawalpur Division",
858
- "district": "Rahim Yar Khan",
1719
+ "division": "Gujranwala Division",
1720
+ "district": "Wazirabad",
859
1721
  "coordinates": {
860
- "lat": 28.4195,
861
- "lng": 70.3024
1722
+ "lat": 32.4432,
1723
+ "lng": 74.1197
862
1724
  },
863
1725
  "postalCodeRange": [
864
- "64200",
865
- "64299"
1726
+ "52000",
1727
+ "52049"
866
1728
  ],
867
1729
  "bounds": {
868
- "minLat": 28.36,
869
- "maxLat": 28.48,
870
- "minLng": 70.24,
871
- "maxLng": 70.36
1730
+ "minLat": 32.39,
1731
+ "maxLat": 32.49,
1732
+ "minLng": 74.07,
1733
+ "maxLng": 74.17
872
1734
  },
873
1735
  "totalAreasCount": 0
874
1736
  },
@@ -1009,6 +1871,52 @@ var cities = [
1009
1871
  "maxLng": 69.07
1010
1872
  },
1011
1873
  "totalAreasCount": 0
1874
+ },
1875
+ {
1876
+ "id": "jacobabad",
1877
+ "name": "Jacobabad",
1878
+ "urduName": "\u062C\u06CC\u06A9\u0628 \u0622\u0628\u0627\u062F",
1879
+ "provinceId": "sindh",
1880
+ "division": "Larkana Division",
1881
+ "district": "Jacobabad",
1882
+ "coordinates": {
1883
+ "lat": 28.2835,
1884
+ "lng": 68.4388
1885
+ },
1886
+ "postalCodeRange": [
1887
+ "79200",
1888
+ "79299"
1889
+ ],
1890
+ "bounds": {
1891
+ "minLat": 28.23,
1892
+ "maxLat": 28.34,
1893
+ "minLng": 68.38,
1894
+ "maxLng": 68.49
1895
+ },
1896
+ "totalAreasCount": 0
1897
+ },
1898
+ {
1899
+ "id": "shikarpur",
1900
+ "name": "Shikarpur",
1901
+ "urduName": "\u0634\u06A9\u0627\u0631\u067E\u0648\u0631",
1902
+ "provinceId": "sindh",
1903
+ "division": "Larkana Division",
1904
+ "district": "Shikarpur",
1905
+ "coordinates": {
1906
+ "lat": 27.957,
1907
+ "lng": 68.638
1908
+ },
1909
+ "postalCodeRange": [
1910
+ "78100",
1911
+ "78199"
1912
+ ],
1913
+ "bounds": {
1914
+ "minLat": 27.91,
1915
+ "maxLat": 28.01,
1916
+ "minLng": 68.58,
1917
+ "maxLng": 68.69
1918
+ },
1919
+ "totalAreasCount": 0
1012
1920
  }
1013
1921
  ];
1014
1922
 
@@ -5255,67 +6163,247 @@ var allAreas = [
5255
6163
  ...rawalpindiAreas
5256
6164
  ];
5257
6165
 
5258
- // src/geo.ts
6166
+ // src/urdu.ts
6167
+ var EASTERN_TO_WESTERN_DIGITS = {
6168
+ // Eastern Arabic-Indic digits (Urdu/Persian: \u06F0-\u06F9)
6169
+ "\u06F0": "0",
6170
+ "\u06F1": "1",
6171
+ "\u06F2": "2",
6172
+ "\u06F3": "3",
6173
+ "\u06F4": "4",
6174
+ "\u06F5": "5",
6175
+ "\u06F6": "6",
6176
+ "\u06F7": "7",
6177
+ "\u06F8": "8",
6178
+ "\u06F9": "9",
6179
+ // Standard Arabic-Indic digits (\u0660-\u0669)
6180
+ "\u0660": "0",
6181
+ "\u0661": "1",
6182
+ "\u0662": "2",
6183
+ "\u0663": "3",
6184
+ "\u0664": "4",
6185
+ "\u0665": "5",
6186
+ "\u0666": "6",
6187
+ "\u0667": "7",
6188
+ "\u0668": "8",
6189
+ "\u0669": "9"
6190
+ };
6191
+ var WESTERN_TO_EASTERN_DIGITS = {
6192
+ "0": "\u06F0",
6193
+ "1": "\u06F1",
6194
+ "2": "\u06F2",
6195
+ "3": "\u06F3",
6196
+ "4": "\u06F4",
6197
+ "5": "\u06F5",
6198
+ "6": "\u06F6",
6199
+ "7": "\u06F7",
6200
+ "8": "\u06F8",
6201
+ "9": "\u06F9"
6202
+ };
6203
+ function toWesternDigits(text) {
6204
+ if (typeof text !== "string") return "";
6205
+ return text.replace(/[۰-۹\u0660-\u0669]/g, (char) => EASTERN_TO_WESTERN_DIGITS[char] || char);
6206
+ }
6207
+ function toEasternDigits(text) {
6208
+ if (typeof text !== "string") return "";
6209
+ return text.replace(/[0-9]/g, (char) => WESTERN_TO_EASTERN_DIGITS[char] || char);
6210
+ }
6211
+ function stripUrduDiacritics(text) {
6212
+ if (typeof text !== "string") return "";
6213
+ return text.replace(/[\u0640\u064B-\u065F\u0670]/g, "");
6214
+ }
6215
+ function normalizeUrduText(text) {
6216
+ if (typeof text !== "string") return "";
6217
+ let str = stripUrduDiacritics(text);
6218
+ str = str.replace(/[\u064A\u0649]/g, "\u06CC");
6219
+ str = str.replace(/\u0643/g, "\u06A9");
6220
+ str = str.replace(/\u0647/g, "\u06C1");
6221
+ str = toWesternDigits(str);
6222
+ return str.trim().replace(/\s+/g, " ");
6223
+ }
6224
+
6225
+ // src/hierarchy.ts
6226
+ var cityLookupMap = /* @__PURE__ */ new Map();
6227
+ for (const c of cities) {
6228
+ cityLookupMap.set(c.id.toLowerCase().trim(), c);
6229
+ cityLookupMap.set(c.name.toLowerCase().trim(), c);
6230
+ if (c.urduName) {
6231
+ cityLookupMap.set(c.urduName.trim(), c);
6232
+ cityLookupMap.set(toEasternDigits(c.urduName).trim(), c);
6233
+ const normUrdu = normalizeUrduText(c.urduName);
6234
+ if (normUrdu) {
6235
+ cityLookupMap.set(normUrdu, c);
6236
+ }
6237
+ }
6238
+ }
5259
6239
  var areasByCityMap = /* @__PURE__ */ new Map();
5260
6240
  for (const a of allAreas) {
5261
- const cityKey = a.cityId.toLowerCase();
5262
- const list = areasByCityMap.get(cityKey) || [];
6241
+ const cKey = a.cityId.toLowerCase();
6242
+ const list = areasByCityMap.get(cKey) || [];
5263
6243
  list.push(a);
5264
- areasByCityMap.set(cityKey, list);
6244
+ areasByCityMap.set(cKey, list);
5265
6245
  }
5266
- function haversineDistanceKm(c1, c2) {
5267
- if (c1.lat === c2.lat && c1.lng === c2.lng) {
5268
- return 0;
6246
+ function canonicalAreaSlug(area) {
6247
+ const romanMatch = area.name.match(/\b([IVXLCDM]+)$/i);
6248
+ if (romanMatch) {
6249
+ const romanLower = romanMatch[1].toLowerCase();
6250
+ return area.id.replace(/-\d+$/, `-${romanLower}`);
5269
6251
  }
5270
- const R = 6371;
5271
- const dLat = (c2.lat - c1.lat) * Math.PI / 180;
5272
- const dLng = (c2.lng - c1.lng) * Math.PI / 180;
5273
- const lat1Rad = c1.lat * Math.PI / 180;
5274
- const lat2Rad = c2.lat * Math.PI / 180;
5275
- const a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.cos(lat1Rad) * Math.cos(lat2Rad) * Math.sin(dLng / 2) * Math.sin(dLng / 2);
5276
- const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
5277
- return R * c;
6252
+ return area.id;
5278
6253
  }
5279
- function getNearestArea(coords, options, candidateAreas = allAreas) {
5280
- let filtered = candidateAreas;
5281
- if (options?.cityId && typeof options.cityId === "string") {
5282
- const cityId = options.cityId.toLowerCase().trim();
5283
- if (candidateAreas === allAreas) {
5284
- filtered = areasByCityMap.get(cityId) || [];
5285
- } else {
5286
- filtered = filtered.filter((a) => a.cityId.toLowerCase() === cityId);
6254
+ var areaCompoundLookupMap = /* @__PURE__ */ new Map();
6255
+ for (const a of allAreas) {
6256
+ const cityId = a.cityId.toLowerCase();
6257
+ const city = cityLookupMap.get(cityId);
6258
+ const cityKeys = /* @__PURE__ */ new Set([cityId]);
6259
+ if (city?.name) {
6260
+ cityKeys.add(city.name.toLowerCase().trim());
6261
+ }
6262
+ const variants = /* @__PURE__ */ new Set();
6263
+ const rawId = a.id.toLowerCase().trim();
6264
+ variants.add(rawId);
6265
+ if (rawId.startsWith(`${cityId}-`)) {
6266
+ variants.add(rawId.slice(cityId.length + 1));
6267
+ }
6268
+ const canonSlug = canonicalAreaSlug(a).toLowerCase().trim();
6269
+ variants.add(canonSlug);
6270
+ if (canonSlug.startsWith(`${cityId}-`)) {
6271
+ variants.add(canonSlug.slice(cityId.length + 1));
6272
+ }
6273
+ const rawName = a.name.toLowerCase().trim();
6274
+ variants.add(rawName);
6275
+ const slugifiedName = rawName.replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
6276
+ variants.add(slugifiedName);
6277
+ variants.add(`${cityId}-${slugifiedName}`);
6278
+ for (const alias of a.aliases) {
6279
+ const lowerAlias = alias.toLowerCase().trim();
6280
+ variants.add(lowerAlias);
6281
+ const slugAlias = lowerAlias.replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
6282
+ variants.add(slugAlias);
6283
+ variants.add(`${cityId}-${slugAlias}`);
6284
+ }
6285
+ if (a.urduName) {
6286
+ variants.add(a.urduName.trim());
6287
+ variants.add(toEasternDigits(a.urduName).trim());
6288
+ const norm = normalizeUrduText(a.urduName);
6289
+ if (norm) {
6290
+ variants.add(norm);
5287
6291
  }
5288
6292
  }
5289
- if (options?.provinceId && typeof options.provinceId === "string") {
5290
- const provinceId = options.provinceId.toLowerCase().trim();
5291
- filtered = filtered.filter((a) => a.provinceId.toLowerCase() === provinceId);
6293
+ if (cityId === "lahore" && a.id === "lahore-gulberg-3") {
6294
+ variants.add("gulberg");
6295
+ variants.add("lahore-gulberg");
5292
6296
  }
5293
- if (filtered.length === 0) {
5294
- return null;
6297
+ for (const cKey of cityKeys) {
6298
+ for (const v of variants) {
6299
+ const compoundKey = `${cKey}:${v}`;
6300
+ if (!areaCompoundLookupMap.has(compoundKey)) {
6301
+ areaCompoundLookupMap.set(compoundKey, a);
6302
+ }
6303
+ }
5295
6304
  }
5296
- let nearest = null;
5297
- let minDistance = Infinity;
5298
- for (const area of filtered) {
5299
- const dist = haversineDistanceKm(coords, area.coordinates);
5300
- if (dist < minDistance) {
5301
- minDistance = dist;
5302
- nearest = area;
6305
+ }
6306
+ function getCityName(key, lang = "en") {
6307
+ if (typeof key !== "string") return "";
6308
+ const trimmed = key.trim();
6309
+ if (!trimmed) return "";
6310
+ let city = cityLookupMap.get(trimmed.toLowerCase());
6311
+ if (!city) {
6312
+ city = cityLookupMap.get(normalizeUrduText(trimmed));
6313
+ }
6314
+ if (!city) return key;
6315
+ return lang === "ur" ? toEasternDigits(city.urduName) : city.name;
6316
+ }
6317
+ function getAreaName(cityKey, areaKey, lang = "en") {
6318
+ if (typeof areaKey !== "string") return "";
6319
+ if (typeof cityKey !== "string") return areaKey;
6320
+ const trimmedArea = areaKey.trim();
6321
+ const trimmedCity = cityKey.trim();
6322
+ if (!trimmedArea) return areaKey;
6323
+ if (!trimmedCity) return areaKey;
6324
+ let match = areaCompoundLookupMap.get(`${trimmedCity.toLowerCase()}:${trimmedArea.toLowerCase()}`);
6325
+ if (!match) {
6326
+ const city = cityLookupMap.get(trimmedCity.toLowerCase()) || cityLookupMap.get(normalizeUrduText(trimmedCity));
6327
+ if (city) {
6328
+ match = areaCompoundLookupMap.get(`${city.id}:${trimmedArea.toLowerCase()}`);
5303
6329
  }
5304
6330
  }
5305
- if (options?.maxDistanceKm !== void 0 && minDistance > options.maxDistanceKm) {
5306
- return null;
6331
+ if (!match) {
6332
+ const normArea = normalizeUrduText(trimmedArea);
6333
+ if (normArea) {
6334
+ match = areaCompoundLookupMap.get(`${trimmedCity.toLowerCase()}:${normArea}`);
6335
+ if (!match) {
6336
+ const city = cityLookupMap.get(trimmedCity.toLowerCase()) || cityLookupMap.get(normalizeUrduText(trimmedCity));
6337
+ if (city) {
6338
+ match = areaCompoundLookupMap.get(`${city.id}:${normArea}`);
6339
+ }
6340
+ }
6341
+ }
5307
6342
  }
5308
- return nearest;
6343
+ if (!match) return areaKey;
6344
+ return lang === "ur" ? toEasternDigits(match.urduName || match.name) : match.name;
6345
+ }
6346
+ function toLocationItem(entity) {
6347
+ if (!entity || typeof entity !== "object") {
6348
+ throw new TypeError("Expected a valid location entity");
6349
+ }
6350
+ if ("capitalCityId" in entity) {
6351
+ return {
6352
+ id: entity.id,
6353
+ nameEn: entity.name,
6354
+ nameUr: toEasternDigits(entity.urduName),
6355
+ type: "province",
6356
+ parentId: void 0,
6357
+ coordinates: void 0
6358
+ };
6359
+ }
6360
+ if ("district" in entity && !("cityId" in entity)) {
6361
+ return {
6362
+ id: entity.id,
6363
+ nameEn: entity.name,
6364
+ nameUr: toEasternDigits(entity.urduName),
6365
+ type: "district",
6366
+ parentId: entity.provinceId,
6367
+ coordinates: entity.coordinates
6368
+ };
6369
+ }
6370
+ if ("cityId" in entity && "name" in entity) {
6371
+ const area = entity;
6372
+ return {
6373
+ id: canonicalAreaSlug(area),
6374
+ nameEn: area.name,
6375
+ nameUr: toEasternDigits(area.urduName || area.name),
6376
+ type: "area",
6377
+ parentId: area.cityId,
6378
+ coordinates: area.coordinates
6379
+ };
6380
+ }
6381
+ throw new TypeError(
6382
+ "Unrecognized location entity format: expected province, city, or area object"
6383
+ );
6384
+ }
6385
+ function getProvincesAsLocationItems() {
6386
+ return provinces.map(toLocationItem);
6387
+ }
6388
+ function getCitiesAsLocationItems(provinceId) {
6389
+ let list = cities;
6390
+ if (provinceId && typeof provinceId === "string") {
6391
+ const provKey = provinceId.toLowerCase().trim();
6392
+ list = cities.filter((c) => c.provinceId.toLowerCase() === provKey);
6393
+ }
6394
+ return list.map(toLocationItem);
6395
+ }
6396
+ function getAreasAsLocationItems(cityKey) {
6397
+ if (typeof cityKey !== "string") return [];
6398
+ const trimmed = cityKey.trim();
6399
+ if (!trimmed) return [];
6400
+ const city = cityLookupMap.get(trimmed.toLowerCase());
6401
+ const cityId = city ? city.id : trimmed.toLowerCase();
6402
+ const areas = areasByCityMap.get(cityId) || [];
6403
+ return areas.map(toLocationItem);
5309
6404
  }
5310
6405
 
5311
6406
  // src/search.ts
5312
- var areasByCityMap2 = /* @__PURE__ */ new Map();
5313
- for (const a of allAreas) {
5314
- const cityKey = a.cityId.toLowerCase();
5315
- const list = areasByCityMap2.get(cityKey) || [];
5316
- list.push(a);
5317
- areasByCityMap2.set(cityKey, list);
5318
- }
5319
6407
  function normalizeString(str) {
5320
6408
  return str.toLowerCase().trim().replace(/[-_.,/]/g, " ").replace(/\s+/g, " ");
5321
6409
  }
@@ -5338,7 +6426,59 @@ function levenshteinDistance(a, b) {
5338
6426
  }
5339
6427
  return matrix[b.length];
5340
6428
  }
5341
- function searchAreas(query, options, candidateAreas = allAreas) {
6429
+ function createNormalizedCandidate(area) {
6430
+ const normName = normalizeString(area.name);
6431
+ const normId = normalizeString(area.id);
6432
+ const rawUrdu = area.urduName ? area.urduName.trim() : "";
6433
+ const normUrdu = area.urduName ? normalizeUrduText(area.urduName) : "";
6434
+ const normAliases = area.aliases.map((a) => normalizeString(a));
6435
+ const allText = `${normName} ${normId} ${normAliases.join(" ")} ${normUrdu} ${rawUrdu}`.trim();
6436
+ return {
6437
+ area,
6438
+ normName,
6439
+ normId,
6440
+ normUrdu,
6441
+ rawUrdu,
6442
+ normAliases,
6443
+ allText
6444
+ };
6445
+ }
6446
+ var normalizedCandidates = allAreas.map(createNormalizedCandidate);
6447
+ var candidateByAreaMap = /* @__PURE__ */ new Map();
6448
+ for (const c of normalizedCandidates) {
6449
+ candidateByAreaMap.set(c.area, c);
6450
+ }
6451
+ var normalizedByCityMap = /* @__PURE__ */ new Map();
6452
+ for (const c of normalizedCandidates) {
6453
+ const cityKey = c.area.cityId.toLowerCase();
6454
+ const list = normalizedByCityMap.get(cityKey) || [];
6455
+ list.push(c);
6456
+ normalizedByCityMap.set(cityKey, list);
6457
+ }
6458
+ function getCandidatePool(options, candidateAreas = allAreas) {
6459
+ let list;
6460
+ if (candidateAreas === allAreas) {
6461
+ if (options?.cityId && typeof options.cityId === "string") {
6462
+ const cityId = options.cityId.toLowerCase().trim();
6463
+ list = normalizedByCityMap.get(cityId) || [];
6464
+ } else {
6465
+ list = normalizedCandidates;
6466
+ }
6467
+ } else {
6468
+ let filtered = candidateAreas;
6469
+ if (options?.cityId && typeof options.cityId === "string") {
6470
+ const cityId = options.cityId.toLowerCase().trim();
6471
+ filtered = filtered.filter((a) => a.cityId.toLowerCase() === cityId);
6472
+ }
6473
+ list = filtered.map((a) => candidateByAreaMap.get(a) || createNormalizedCandidate(a));
6474
+ }
6475
+ if (options?.provinceId && typeof options.provinceId === "string") {
6476
+ const provinceId = options.provinceId.toLowerCase().trim();
6477
+ list = list.filter((c) => c.area.provinceId.toLowerCase() === provinceId);
6478
+ }
6479
+ return list;
6480
+ }
6481
+ function classicSearchAreas(query, options, candidateAreas = allAreas) {
5342
6482
  if (typeof query !== "string") {
5343
6483
  return [];
5344
6484
  }
@@ -5347,70 +6487,69 @@ function searchAreas(query, options, candidateAreas = allAreas) {
5347
6487
  return [];
5348
6488
  }
5349
6489
  const normQuery = normalizeString(trimmed);
6490
+ const normUrduQuery = normalizeUrduText(trimmed);
5350
6491
  const queryTokens = normQuery.split(" ").filter(Boolean);
5351
- let filtered = candidateAreas;
5352
- if (options?.cityId && typeof options.cityId === "string") {
5353
- const cityId = options.cityId.toLowerCase().trim();
5354
- if (candidateAreas === allAreas) {
5355
- filtered = areasByCityMap2.get(cityId) || [];
5356
- } else {
5357
- filtered = filtered.filter((a) => a.cityId.toLowerCase() === cityId);
5358
- }
5359
- }
5360
- if (options?.provinceId && typeof options.provinceId === "string") {
5361
- const provinceId = options.provinceId.toLowerCase().trim();
5362
- filtered = filtered.filter((a) => a.provinceId.toLowerCase() === provinceId);
5363
- }
6492
+ const urduTokens = normUrduQuery ? normUrduQuery.split(" ").filter(Boolean) : [];
6493
+ const pool = getCandidatePool(options, candidateAreas);
5364
6494
  const scored = [];
5365
- for (const area of filtered) {
6495
+ for (const c of pool) {
5366
6496
  let score = 0;
5367
- const normName = normalizeString(area.name);
5368
- const normId = normalizeString(area.id);
5369
- const normUrdu = area.urduName ? area.urduName.trim() : "";
5370
- const normAliases = area.aliases.map((a) => normalizeString(a));
5371
- if (normName === normQuery) {
6497
+ if (c.normName === normQuery) {
5372
6498
  score = Math.max(score, 1e3);
5373
- } else if (normId === normQuery) {
6499
+ } else if (c.normId === normQuery) {
5374
6500
  score = Math.max(score, 950);
5375
- } else if (normUrdu && normUrdu === trimmed) {
6501
+ } else if (c.normUrdu && c.normUrdu === normUrduQuery || c.rawUrdu && c.rawUrdu === trimmed) {
5376
6502
  score = Math.max(score, 900);
5377
- } else if (normAliases.some((al) => al === normQuery)) {
6503
+ } else if (c.normAliases.some((al) => al === normQuery)) {
5378
6504
  score = Math.max(score, 850);
5379
6505
  }
5380
6506
  if (score < 800) {
5381
- if (normName.startsWith(normQuery)) {
5382
- score = Math.max(score, 700 + normQuery.length / normName.length * 50);
5383
- } else if (normUrdu && normUrdu.startsWith(trimmed)) {
6507
+ if (c.normName.startsWith(normQuery)) {
6508
+ score = Math.max(score, 700 + normQuery.length / c.normName.length * 50);
6509
+ } else if (c.normUrdu && normUrduQuery && c.normUrdu.startsWith(normUrduQuery) || c.rawUrdu && c.rawUrdu.startsWith(trimmed)) {
5384
6510
  score = Math.max(score, 650);
5385
- } else if (normAliases.some((al) => al.startsWith(normQuery))) {
6511
+ } else if (c.normAliases.some((al) => al.startsWith(normQuery))) {
5386
6512
  score = Math.max(score, 600);
5387
6513
  }
5388
6514
  }
5389
6515
  if (score < 600) {
5390
- if (normName.includes(normQuery)) {
6516
+ if (c.normName.includes(normQuery)) {
5391
6517
  score = Math.max(score, 500);
5392
- } else if (normUrdu && normUrdu.includes(trimmed)) {
6518
+ } else if (c.normUrdu && normUrduQuery && c.normUrdu.includes(normUrduQuery) || c.rawUrdu && c.rawUrdu.includes(trimmed)) {
5393
6519
  score = Math.max(score, 450);
5394
- } else if (normAliases.some((al) => al.includes(normQuery))) {
6520
+ } else if (c.normAliases.some((al) => al.includes(normQuery))) {
5395
6521
  score = Math.max(score, 400);
5396
- } else if (queryTokens.length > 0) {
5397
- const areaAllText = `${normName} ${normId} ${normAliases.join(" ")}`;
5398
- const matchedTokens = queryTokens.filter((token) => areaAllText.includes(token));
5399
- if (matchedTokens.length === queryTokens.length) {
5400
- score = Math.max(score, 300 + queryTokens.length * 20);
5401
- } else if (matchedTokens.length > 0) {
5402
- score = Math.max(score, 100 + matchedTokens.length / queryTokens.length * 100);
6522
+ } else {
6523
+ let tokenScore = 0;
6524
+ if (queryTokens.length > 0) {
6525
+ const matched = queryTokens.filter((token) => c.allText.includes(token));
6526
+ if (matched.length === queryTokens.length) {
6527
+ tokenScore = Math.max(tokenScore, 300 + queryTokens.length * 20);
6528
+ } else if (matched.length > 0) {
6529
+ tokenScore = Math.max(tokenScore, 100 + matched.length / queryTokens.length * 100);
6530
+ }
6531
+ }
6532
+ if (urduTokens.length > 0) {
6533
+ const matchedUrdu = urduTokens.filter((token) => c.allText.includes(token));
6534
+ if (matchedUrdu.length === urduTokens.length) {
6535
+ tokenScore = Math.max(tokenScore, 300 + urduTokens.length * 20);
6536
+ } else if (matchedUrdu.length > 0) {
6537
+ tokenScore = Math.max(tokenScore, 100 + matchedUrdu.length / urduTokens.length * 100);
6538
+ }
6539
+ }
6540
+ if (tokenScore > 0) {
6541
+ score = Math.max(score, tokenScore);
5403
6542
  }
5404
6543
  }
5405
6544
  }
5406
6545
  if (score === 0 && normQuery.length >= 4 && normQuery.length <= 40) {
5407
- const dist = levenshteinDistance(normQuery, normName);
5408
- const maxLen = Math.max(normQuery.length, normName.length);
6546
+ const dist = levenshteinDistance(normQuery, c.normName);
6547
+ const maxLen = Math.max(normQuery.length, c.normName.length);
5409
6548
  const similarity = 1 - dist / maxLen;
5410
6549
  if (similarity >= 0.72) {
5411
6550
  score = Math.max(score, 150 * similarity);
5412
6551
  } else {
5413
- for (const al of normAliases) {
6552
+ for (const al of c.normAliases) {
5414
6553
  if (al.length >= 3) {
5415
6554
  const aliasDist = levenshteinDistance(normQuery, al);
5416
6555
  const aliasMaxLen = Math.max(normQuery.length, al.length);
@@ -5424,16 +6563,16 @@ function searchAreas(query, options, candidateAreas = allAreas) {
5424
6563
  }
5425
6564
  }
5426
6565
  if (score > 0) {
5427
- scored.push({ area, score });
6566
+ scored.push({ candidate: c, score });
5428
6567
  }
5429
6568
  }
5430
6569
  scored.sort((a, b) => {
5431
6570
  if (b.score !== a.score) {
5432
6571
  return b.score - a.score;
5433
6572
  }
5434
- return a.area.name.localeCompare(b.area.name);
6573
+ return a.candidate.area.name.localeCompare(b.candidate.area.name);
5435
6574
  });
5436
- const results = scored.map((s) => s.area);
6575
+ const results = scored.map((s) => s.candidate.area);
5437
6576
  if (options?.limit !== void 0) {
5438
6577
  if (options.limit <= 0) {
5439
6578
  return [];
@@ -5442,6 +6581,115 @@ function searchAreas(query, options, candidateAreas = allAreas) {
5442
6581
  }
5443
6582
  return results;
5444
6583
  }
6584
+ function searchLocationItems(cityKey, query, _lang) {
6585
+ if (typeof cityKey !== "string" || typeof query !== "string") return [];
6586
+ const trimmedCity = cityKey.trim();
6587
+ const trimmedQuery = query.trim();
6588
+ if (!trimmedCity || !trimmedQuery) return [];
6589
+ const city = cityLookupMap.get(trimmedCity.toLowerCase()) || cityLookupMap.get(normalizeUrduText(trimmedCity));
6590
+ if (!city) return [];
6591
+ const results = classicSearchAreas(trimmedQuery, { cityId: city.id });
6592
+ return results.map(toLocationItem);
6593
+ }
6594
+ function searchAreas(firstArg, secondArg, thirdArg) {
6595
+ if (typeof secondArg === "string") {
6596
+ const cityKey = firstArg;
6597
+ const query2 = secondArg;
6598
+ const lang = thirdArg === "ur" ? "ur" : "en";
6599
+ return searchLocationItems(cityKey, query2, lang);
6600
+ }
6601
+ const query = firstArg;
6602
+ const options = typeof secondArg === "object" && secondArg !== null ? secondArg : void 0;
6603
+ const candidateAreas = Array.isArray(thirdArg) ? thirdArg : allAreas;
6604
+ return classicSearchAreas(query, options, candidateAreas);
6605
+ }
6606
+
6607
+ // src/geo.ts
6608
+ var areasByCityMap2 = /* @__PURE__ */ new Map();
6609
+ for (const a of allAreas) {
6610
+ const cityKey = a.cityId.toLowerCase();
6611
+ const list = areasByCityMap2.get(cityKey) || [];
6612
+ list.push(a);
6613
+ areasByCityMap2.set(cityKey, list);
6614
+ }
6615
+ function isPointInBoundingBox(coords, bounds) {
6616
+ if (!coords || typeof coords.lat !== "number" || typeof coords.lng !== "number") {
6617
+ return false;
6618
+ }
6619
+ if (!bounds || typeof bounds.minLat !== "number" || typeof bounds.maxLat !== "number" || typeof bounds.minLng !== "number" || typeof bounds.maxLng !== "number") {
6620
+ return false;
6621
+ }
6622
+ return coords.lat >= bounds.minLat && coords.lat <= bounds.maxLat && coords.lng >= bounds.minLng && coords.lng <= bounds.maxLng;
6623
+ }
6624
+ function haversineDistanceKm(c1, c2) {
6625
+ if (c1.lat === c2.lat && c1.lng === c2.lng) {
6626
+ return 0;
6627
+ }
6628
+ const R = 6371;
6629
+ const dLat = (c2.lat - c1.lat) * Math.PI / 180;
6630
+ const dLng = (c2.lng - c1.lng) * Math.PI / 180;
6631
+ const lat1Rad = c1.lat * Math.PI / 180;
6632
+ const lat2Rad = c2.lat * Math.PI / 180;
6633
+ const a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.cos(lat1Rad) * Math.cos(lat2Rad) * Math.sin(dLng / 2) * Math.sin(dLng / 2);
6634
+ const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
6635
+ return R * c;
6636
+ }
6637
+ function getNearestArea(coords, options, candidateAreas = allAreas) {
6638
+ if (!coords || typeof coords.lat !== "number" || typeof coords.lng !== "number") {
6639
+ return null;
6640
+ }
6641
+ const provKey = options?.provinceId && typeof options.provinceId === "string" ? options.provinceId.toLowerCase().trim() : void 0;
6642
+ let filtered = candidateAreas;
6643
+ if (options?.cityId && typeof options.cityId === "string") {
6644
+ const cityId = options.cityId.toLowerCase().trim();
6645
+ if (candidateAreas === allAreas) {
6646
+ filtered = areasByCityMap2.get(cityId) || [];
6647
+ } else {
6648
+ filtered = filtered.filter((a) => a.cityId.toLowerCase() === cityId);
6649
+ }
6650
+ if (provKey) {
6651
+ filtered = filtered.filter((a) => a.provinceId.toLowerCase() === provKey);
6652
+ }
6653
+ } else {
6654
+ const matchingCities = cities.filter(
6655
+ (c) => c.bounds && (!provKey || c.provinceId.toLowerCase() === provKey) && isPointInBoundingBox(coords, c.bounds)
6656
+ );
6657
+ if (matchingCities.length > 0) {
6658
+ const pooledAreas = [];
6659
+ for (const mc of matchingCities) {
6660
+ const cityId = mc.id.toLowerCase();
6661
+ let cityAreas = candidateAreas === allAreas ? areasByCityMap2.get(cityId) || [] : candidateAreas.filter((a) => a.cityId.toLowerCase() === cityId);
6662
+ if (provKey) {
6663
+ cityAreas = cityAreas.filter((a) => a.provinceId.toLowerCase() === provKey);
6664
+ }
6665
+ pooledAreas.push(...cityAreas);
6666
+ }
6667
+ if (pooledAreas.length > 0) {
6668
+ filtered = pooledAreas;
6669
+ } else {
6670
+ filtered = provKey ? candidateAreas.filter((a) => a.provinceId.toLowerCase() === provKey) : candidateAreas;
6671
+ }
6672
+ } else if (provKey) {
6673
+ filtered = candidateAreas.filter((a) => a.provinceId.toLowerCase() === provKey);
6674
+ }
6675
+ }
6676
+ if (filtered.length === 0) {
6677
+ return null;
6678
+ }
6679
+ let nearest = null;
6680
+ let minDistance = Infinity;
6681
+ for (const area of filtered) {
6682
+ const dist = haversineDistanceKm(coords, area.coordinates);
6683
+ if (dist < minDistance) {
6684
+ minDistance = dist;
6685
+ nearest = area;
6686
+ }
6687
+ }
6688
+ if (options?.maxDistanceKm !== void 0 && minDistance > options.maxDistanceKm) {
6689
+ return null;
6690
+ }
6691
+ return nearest;
6692
+ }
5445
6693
 
5446
6694
  // src/index.ts
5447
6695
  var provinceByIdMap = /* @__PURE__ */ new Map();
@@ -5507,20 +6755,6 @@ function findAreasByPostalCode(postalCode) {
5507
6755
  if (typeof postalCode !== "string" && typeof postalCode !== "number") return [];
5508
6756
  return [...areasByPostalCodeMap.get(String(postalCode).trim()) || []];
5509
6757
  }
5510
- function searchAreas2(query, options, candidateAreas) {
5511
- let pool = candidateAreas;
5512
- if (!pool && options?.cityId && typeof options.cityId === "string") {
5513
- pool = areasByCityMap3.get(options.cityId.toLowerCase().trim()) || [];
5514
- }
5515
- return searchAreas(query, options, pool);
5516
- }
5517
- function getNearestArea2(coords, options, candidateAreas) {
5518
- let pool = candidateAreas;
5519
- if (!pool && options?.cityId && typeof options.cityId === "string") {
5520
- pool = areasByCityMap3.get(options.cityId.toLowerCase().trim()) || [];
5521
- }
5522
- return getNearestArea(coords, options, pool);
5523
- }
5524
6758
  // Annotate the CommonJS export names for ESM import in node:
5525
6759
  0 && (module.exports = {
5526
6760
  findAreaByPostalCode,
@@ -5528,11 +6762,22 @@ function getNearestArea2(coords, options, candidateAreas) {
5528
6762
  getAllAreas,
5529
6763
  getAllCities,
5530
6764
  getAllProvinces,
6765
+ getAreaName,
6766
+ getAreasAsLocationItems,
5531
6767
  getAreasByCity,
6768
+ getCitiesAsLocationItems,
5532
6769
  getCitiesByProvince,
5533
6770
  getCityById,
6771
+ getCityName,
5534
6772
  getNearestArea,
5535
6773
  getProvinceById,
6774
+ getProvincesAsLocationItems,
5536
6775
  haversineDistanceKm,
5537
- searchAreas
6776
+ normalizeUrduText,
6777
+ searchAreas,
6778
+ searchLocationItems,
6779
+ stripUrduDiacritics,
6780
+ toEasternDigits,
6781
+ toLocationItem,
6782
+ toWesternDigits
5538
6783
  });