| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
package Business::ID::VehiclePlate; |
|
2
|
|
|
|
|
|
|
|
|
3
|
2
|
|
|
2
|
|
480683
|
use 5.010001; |
|
|
2
|
|
|
|
|
6
|
|
|
4
|
2
|
|
|
2
|
|
9
|
use warnings; |
|
|
2
|
|
|
|
|
3
|
|
|
|
2
|
|
|
|
|
131
|
|
|
5
|
2
|
|
|
2
|
|
11
|
use strict; |
|
|
2
|
|
|
|
|
11
|
|
|
|
2
|
|
|
|
|
47
|
|
|
6
|
|
|
|
|
|
|
|
|
7
|
2
|
|
|
2
|
|
1926
|
use DateTime; |
|
|
2
|
|
|
|
|
1308668
|
|
|
|
2
|
|
|
|
|
110
|
|
|
8
|
2
|
|
|
2
|
|
19
|
use Exporter 'import'; |
|
|
2
|
|
|
|
|
4
|
|
|
|
2
|
|
|
|
|
2795
|
|
|
9
|
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
our $AUTHORITY = 'cpan:PERLANCAR'; # AUTHORITY |
|
11
|
|
|
|
|
|
|
our $DATE = '2024-08-05'; # DATE |
|
12
|
|
|
|
|
|
|
our $DIST = 'Business-ID-VehiclePlate'; # DIST |
|
13
|
|
|
|
|
|
|
our $VERSION = '0.002'; # VERSION |
|
14
|
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
our @EXPORT_OK = qw(parse_idn_vehicle_plate_number); |
|
16
|
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
# source data: devdata/prefixes.csv |
|
18
|
|
|
|
|
|
|
our %prefixes = ( |
|
19
|
|
|
|
|
|
|
A => { |
|
20
|
|
|
|
|
|
|
iso_prov_codes => "ID-BT", |
|
21
|
|
|
|
|
|
|
region => "Banten", |
|
22
|
|
|
|
|
|
|
summary => "Banten, Cilegon, Serang, Pandeglang, Lebak, Tangerang", |
|
23
|
|
|
|
|
|
|
}, |
|
24
|
|
|
|
|
|
|
AA => { |
|
25
|
|
|
|
|
|
|
iso_prov_codes => "ID-JT", |
|
26
|
|
|
|
|
|
|
region => "Jawa Tengah", |
|
27
|
|
|
|
|
|
|
summary => "Magelang, Purworejo, Temanggung, Kebumen, Wonosobo", |
|
28
|
|
|
|
|
|
|
}, |
|
29
|
|
|
|
|
|
|
AB => { |
|
30
|
|
|
|
|
|
|
iso_prov_codes => "ID-YO", |
|
31
|
|
|
|
|
|
|
region => "DIY", |
|
32
|
|
|
|
|
|
|
summary => "Yogyakarta, Bantul, Gunung Kidul, Sleman, Kulon Progo", |
|
33
|
|
|
|
|
|
|
}, |
|
34
|
|
|
|
|
|
|
AD => { |
|
35
|
|
|
|
|
|
|
iso_prov_codes => "ID-JT", |
|
36
|
|
|
|
|
|
|
region => "Jawa Tengah", |
|
37
|
|
|
|
|
|
|
summary => "Surakarta, Sukoharjo, Boyolali, Klaten, Karanganyar, Sragen, Wonogiri", |
|
38
|
|
|
|
|
|
|
}, |
|
39
|
|
|
|
|
|
|
AE => { |
|
40
|
|
|
|
|
|
|
iso_prov_codes => "ID-JI", |
|
41
|
|
|
|
|
|
|
region => "Jawa Timur", |
|
42
|
|
|
|
|
|
|
summary => "Madiun, Ngawi, Ponorogo, Magetan, Pacitan", |
|
43
|
|
|
|
|
|
|
}, |
|
44
|
|
|
|
|
|
|
AG => { |
|
45
|
|
|
|
|
|
|
iso_prov_codes => "ID-JI", |
|
46
|
|
|
|
|
|
|
region => "Jawa Timur", |
|
47
|
|
|
|
|
|
|
summary => "Kediri, Blitar, Nganjuk, Tulungagung, Trenggalek", |
|
48
|
|
|
|
|
|
|
}, |
|
49
|
|
|
|
|
|
|
B => { |
|
50
|
|
|
|
|
|
|
iso_prov_codes => "ID-JK,ID-JB", |
|
51
|
|
|
|
|
|
|
region => "DKI", |
|
52
|
|
|
|
|
|
|
summary => "Jakarta, Depok, Bekasi", |
|
53
|
|
|
|
|
|
|
}, |
|
54
|
|
|
|
|
|
|
BA => { |
|
55
|
|
|
|
|
|
|
iso_prov_codes => "ID-SB", |
|
56
|
|
|
|
|
|
|
region => "Sumatera", |
|
57
|
|
|
|
|
|
|
summary => "Sumatera Barat", |
|
58
|
|
|
|
|
|
|
}, |
|
59
|
|
|
|
|
|
|
BB => { |
|
60
|
|
|
|
|
|
|
iso_prov_codes => "ID-SU", |
|
61
|
|
|
|
|
|
|
region => "Sumatera", |
|
62
|
|
|
|
|
|
|
summary => "Sumatera Utara bagian barat", |
|
63
|
|
|
|
|
|
|
}, |
|
64
|
|
|
|
|
|
|
BD => { iso_prov_codes => "ID-BE", region => "Sumatera", summary => "Bengkulu" }, |
|
65
|
|
|
|
|
|
|
BE => { iso_prov_codes => "ID-LA", region => "Sumatera", summary => "Lampung" }, |
|
66
|
|
|
|
|
|
|
BG => { |
|
67
|
|
|
|
|
|
|
iso_prov_codes => "ID-SS", |
|
68
|
|
|
|
|
|
|
region => "Sumatera", |
|
69
|
|
|
|
|
|
|
summary => "Sumatera Selatan", |
|
70
|
|
|
|
|
|
|
}, |
|
71
|
|
|
|
|
|
|
BH => { iso_prov_codes => "ID-JA", region => "Sumatera", summary => "Jambi" }, |
|
72
|
|
|
|
|
|
|
BK => { |
|
73
|
|
|
|
|
|
|
iso_prov_codes => "ID-SU", |
|
74
|
|
|
|
|
|
|
region => "Sumatera", |
|
75
|
|
|
|
|
|
|
summary => "Sumatera Utara bagian timur", |
|
76
|
|
|
|
|
|
|
}, |
|
77
|
|
|
|
|
|
|
BL => { iso_prov_codes => "ID-AC", region => "Sumatera", summary => "Aceh" }, |
|
78
|
|
|
|
|
|
|
BM => { iso_prov_codes => "ID-RI", region => "Sumatera", summary => "Riau" }, |
|
79
|
|
|
|
|
|
|
BN => { |
|
80
|
|
|
|
|
|
|
iso_prov_codes => "ID-BB", |
|
81
|
|
|
|
|
|
|
region => "Sumatera", |
|
82
|
|
|
|
|
|
|
summary => "Bangka-Belitung", |
|
83
|
|
|
|
|
|
|
}, |
|
84
|
|
|
|
|
|
|
BP => { |
|
85
|
|
|
|
|
|
|
iso_prov_codes => "ID-KR", |
|
86
|
|
|
|
|
|
|
region => "Sumatera", |
|
87
|
|
|
|
|
|
|
summary => "Kepulauan Riau", |
|
88
|
|
|
|
|
|
|
}, |
|
89
|
|
|
|
|
|
|
D => { iso_prov_codes => "ID-JB", region => "Jawa Barat", summary => "Bandung" }, |
|
90
|
|
|
|
|
|
|
DA => { |
|
91
|
|
|
|
|
|
|
iso_prov_codes => "ID-KS", |
|
92
|
|
|
|
|
|
|
region => "Kalimantan", |
|
93
|
|
|
|
|
|
|
summary => "Banjarmasin", |
|
94
|
|
|
|
|
|
|
}, |
|
95
|
|
|
|
|
|
|
DB => { |
|
96
|
|
|
|
|
|
|
iso_prov_codes => "ID-SA", |
|
97
|
|
|
|
|
|
|
region => "Sulawesi", |
|
98
|
|
|
|
|
|
|
summary => "Manado, Bolaang Mongondow, Minahasa, Bitung", |
|
99
|
|
|
|
|
|
|
}, |
|
100
|
|
|
|
|
|
|
DC => { |
|
101
|
|
|
|
|
|
|
iso_prov_codes => "ID-SR", |
|
102
|
|
|
|
|
|
|
region => "Sulawesi", |
|
103
|
|
|
|
|
|
|
summary => "Majumu, Polewari Mandar, Majene", |
|
104
|
|
|
|
|
|
|
}, |
|
105
|
|
|
|
|
|
|
DD => { |
|
106
|
|
|
|
|
|
|
iso_prov_codes => "ID-SN", |
|
107
|
|
|
|
|
|
|
region => "Sulawesi", |
|
108
|
|
|
|
|
|
|
summary => "Makassar, Takalar, Giwa, Bantaeng", |
|
109
|
|
|
|
|
|
|
}, |
|
110
|
|
|
|
|
|
|
DE => { |
|
111
|
|
|
|
|
|
|
iso_prov_codes => "ID-MA", |
|
112
|
|
|
|
|
|
|
region => "Maluku & Papua", |
|
113
|
|
|
|
|
|
|
summary => "Maluku, Serang, Ambon, Tual", |
|
114
|
|
|
|
|
|
|
}, |
|
115
|
|
|
|
|
|
|
DG => { |
|
116
|
|
|
|
|
|
|
iso_prov_codes => "ID-MU", |
|
117
|
|
|
|
|
|
|
region => "Maluku & Papua", |
|
118
|
|
|
|
|
|
|
summary => "Ternate, Halmahera, Tidore, Murotai", |
|
119
|
|
|
|
|
|
|
}, |
|
120
|
|
|
|
|
|
|
DH => { |
|
121
|
|
|
|
|
|
|
iso_prov_codes => "ID-NT", |
|
122
|
|
|
|
|
|
|
region => "Bali & NT", |
|
123
|
|
|
|
|
|
|
summary => "Pulau Timor, Kupang", |
|
124
|
|
|
|
|
|
|
}, |
|
125
|
|
|
|
|
|
|
DK => { iso_prov_codes => "ID-BA", region => "Bali & NT", summary => "Bali" }, |
|
126
|
|
|
|
|
|
|
DL => { |
|
127
|
|
|
|
|
|
|
iso_prov_codes => "ID-SA", |
|
128
|
|
|
|
|
|
|
region => "Sulawesi", |
|
129
|
|
|
|
|
|
|
summary => "Sahinge, Sitaro, Talaud", |
|
130
|
|
|
|
|
|
|
}, |
|
131
|
|
|
|
|
|
|
DM => { |
|
132
|
|
|
|
|
|
|
iso_prov_codes => "ID-GO", |
|
133
|
|
|
|
|
|
|
region => "Sulawesi", |
|
134
|
|
|
|
|
|
|
summary => "Gorontalo, Bone Bolango", |
|
135
|
|
|
|
|
|
|
}, |
|
136
|
|
|
|
|
|
|
DN => { |
|
137
|
|
|
|
|
|
|
iso_prov_codes => "ID-ST", |
|
138
|
|
|
|
|
|
|
region => "Sulawesi", |
|
139
|
|
|
|
|
|
|
summary => "Donggala, Palu, Poso", |
|
140
|
|
|
|
|
|
|
}, |
|
141
|
|
|
|
|
|
|
DR => { |
|
142
|
|
|
|
|
|
|
iso_prov_codes => "ID-NB", |
|
143
|
|
|
|
|
|
|
region => "Bali & NT", |
|
144
|
|
|
|
|
|
|
summary => "Pulau Lombok, Mataram", |
|
145
|
|
|
|
|
|
|
}, |
|
146
|
|
|
|
|
|
|
DT => { |
|
147
|
|
|
|
|
|
|
iso_prov_codes => "ID-SG", |
|
148
|
|
|
|
|
|
|
region => "Sulawesi", |
|
149
|
|
|
|
|
|
|
summary => "Kolaka, Konawe, Wakatobi, Buton, Kendari", |
|
150
|
|
|
|
|
|
|
}, |
|
151
|
|
|
|
|
|
|
E => { |
|
152
|
|
|
|
|
|
|
iso_prov_codes => "ID-JB", |
|
153
|
|
|
|
|
|
|
region => "Jawa Barat", |
|
154
|
|
|
|
|
|
|
summary => "Cirebon, Majalengka, Indramayu, Kuningan", |
|
155
|
|
|
|
|
|
|
}, |
|
156
|
|
|
|
|
|
|
EA => { |
|
157
|
|
|
|
|
|
|
iso_prov_codes => "ID-NB", |
|
158
|
|
|
|
|
|
|
region => "Bali & NT", |
|
159
|
|
|
|
|
|
|
summary => "Pulau Sumbawa", |
|
160
|
|
|
|
|
|
|
}, |
|
161
|
|
|
|
|
|
|
EB => { |
|
162
|
|
|
|
|
|
|
iso_prov_codes => "ID-NT", |
|
163
|
|
|
|
|
|
|
region => "Bali & NT", |
|
164
|
|
|
|
|
|
|
summary => "Pulau Flores", |
|
165
|
|
|
|
|
|
|
}, |
|
166
|
|
|
|
|
|
|
ED => { |
|
167
|
|
|
|
|
|
|
iso_prov_codes => "ID-NT", |
|
168
|
|
|
|
|
|
|
region => "Bali & NT", |
|
169
|
|
|
|
|
|
|
summary => "Pulau Sumba", |
|
170
|
|
|
|
|
|
|
}, |
|
171
|
|
|
|
|
|
|
F => { |
|
172
|
|
|
|
|
|
|
iso_prov_codes => "ID-JB", |
|
173
|
|
|
|
|
|
|
region => "Jawa Barat", |
|
174
|
|
|
|
|
|
|
summary => "Bogor, Cianjur,\nSukabumi", |
|
175
|
|
|
|
|
|
|
}, |
|
176
|
|
|
|
|
|
|
G => { |
|
177
|
|
|
|
|
|
|
iso_prov_codes => "ID-JT", |
|
178
|
|
|
|
|
|
|
region => "Jawa Tengah", |
|
179
|
|
|
|
|
|
|
summary => "Pekalongan, Pemalang, Batang, Tegal, Brebes", |
|
180
|
|
|
|
|
|
|
}, |
|
181
|
|
|
|
|
|
|
H => { |
|
182
|
|
|
|
|
|
|
iso_prov_codes => "ID-JT", |
|
183
|
|
|
|
|
|
|
region => "Jawa Tengah", |
|
184
|
|
|
|
|
|
|
summary => "Semarang, Kendal, Salatiga, Demak", |
|
185
|
|
|
|
|
|
|
}, |
|
186
|
|
|
|
|
|
|
K => { |
|
187
|
|
|
|
|
|
|
iso_prov_codes => "ID-JT", |
|
188
|
|
|
|
|
|
|
region => "Jawa Tengah", |
|
189
|
|
|
|
|
|
|
summary => "Pati, Jepara, Kudus, Blora, Rembang, Grombogan", |
|
190
|
|
|
|
|
|
|
}, |
|
191
|
|
|
|
|
|
|
KB => { |
|
192
|
|
|
|
|
|
|
iso_prov_codes => "ID-KB", |
|
193
|
|
|
|
|
|
|
region => "Kalimantan", |
|
194
|
|
|
|
|
|
|
summary => "Singkawang, Pontianak", |
|
195
|
|
|
|
|
|
|
}, |
|
196
|
|
|
|
|
|
|
KH => { |
|
197
|
|
|
|
|
|
|
iso_prov_codes => "ID-KT", |
|
198
|
|
|
|
|
|
|
region => "Kalimantan", |
|
199
|
|
|
|
|
|
|
summary => "Palangkaraya, Kotawaringin, Barito", |
|
200
|
|
|
|
|
|
|
}, |
|
201
|
|
|
|
|
|
|
KT => { |
|
202
|
|
|
|
|
|
|
iso_prov_codes => "ID-KI", |
|
203
|
|
|
|
|
|
|
region => "Kalimantan", |
|
204
|
|
|
|
|
|
|
summary => "Balikpapan, Kutai Kartanegara, Samarinda, Bontang, Kutai", |
|
205
|
|
|
|
|
|
|
}, |
|
206
|
|
|
|
|
|
|
KU => { |
|
207
|
|
|
|
|
|
|
iso_prov_codes => "ID-KU", |
|
208
|
|
|
|
|
|
|
region => "Kalimantan", |
|
209
|
|
|
|
|
|
|
summary => "Kalimantan Utara", |
|
210
|
|
|
|
|
|
|
}, |
|
211
|
|
|
|
|
|
|
L => { |
|
212
|
|
|
|
|
|
|
iso_prov_codes => "ID-JI", |
|
213
|
|
|
|
|
|
|
region => "Jawa Timur", |
|
214
|
|
|
|
|
|
|
summary => "Surabaya", |
|
215
|
|
|
|
|
|
|
}, |
|
216
|
|
|
|
|
|
|
M => { iso_prov_codes => "ID-JI", region => "Jawa Timur", summary => "Madura" }, |
|
217
|
|
|
|
|
|
|
N => { |
|
218
|
|
|
|
|
|
|
iso_prov_codes => "ID-JI", |
|
219
|
|
|
|
|
|
|
region => "Jawa Timur", |
|
220
|
|
|
|
|
|
|
summary => "Malang, Pasuruan, Probolinggo, Lumajang", |
|
221
|
|
|
|
|
|
|
}, |
|
222
|
|
|
|
|
|
|
P => { |
|
223
|
|
|
|
|
|
|
iso_prov_codes => "ID-JI", |
|
224
|
|
|
|
|
|
|
region => "Jawa Timur", |
|
225
|
|
|
|
|
|
|
summary => "Bondowoso, Jember, Situbondo, Banyuwangi", |
|
226
|
|
|
|
|
|
|
}, |
|
227
|
|
|
|
|
|
|
PA => { |
|
228
|
|
|
|
|
|
|
iso_prov_codes => "ID-PA", |
|
229
|
|
|
|
|
|
|
region => "Maluku & Papua", |
|
230
|
|
|
|
|
|
|
summary => "Jayapura, Merauke, Mimika, Paniai", |
|
231
|
|
|
|
|
|
|
}, |
|
232
|
|
|
|
|
|
|
PB => { |
|
233
|
|
|
|
|
|
|
iso_prov_codes => "ID-PB", |
|
234
|
|
|
|
|
|
|
region => "Maluku & Papua", |
|
235
|
|
|
|
|
|
|
summary => "Papua Barat", |
|
236
|
|
|
|
|
|
|
}, |
|
237
|
|
|
|
|
|
|
R => { |
|
238
|
|
|
|
|
|
|
iso_prov_codes => "ID-JT", |
|
239
|
|
|
|
|
|
|
region => "Jawa Tengah", |
|
240
|
|
|
|
|
|
|
summary => "Banyumas, Purbalingga, Cilacap, Banjarnegara", |
|
241
|
|
|
|
|
|
|
}, |
|
242
|
|
|
|
|
|
|
S => { |
|
243
|
|
|
|
|
|
|
iso_prov_codes => "ID-JI", |
|
244
|
|
|
|
|
|
|
region => "Jawa Timur", |
|
245
|
|
|
|
|
|
|
summary => "Bojonegoro, Tuban, Mojokerto, Lamongan, Jombang", |
|
246
|
|
|
|
|
|
|
}, |
|
247
|
|
|
|
|
|
|
T => { |
|
248
|
|
|
|
|
|
|
iso_prov_codes => "ID-JB", |
|
249
|
|
|
|
|
|
|
region => "Jawa Barat", |
|
250
|
|
|
|
|
|
|
summary => "Purwakarta, Karawang, Subang", |
|
251
|
|
|
|
|
|
|
}, |
|
252
|
|
|
|
|
|
|
W => { |
|
253
|
|
|
|
|
|
|
iso_prov_codes => "ID-JI", |
|
254
|
|
|
|
|
|
|
region => "Jawa Timur", |
|
255
|
|
|
|
|
|
|
summary => "Gresik, Sidoarjo", |
|
256
|
|
|
|
|
|
|
}, |
|
257
|
|
|
|
|
|
|
Z => { |
|
258
|
|
|
|
|
|
|
iso_prov_codes => "ID-JB", |
|
259
|
|
|
|
|
|
|
region => "Jawa Barat", |
|
260
|
|
|
|
|
|
|
summary => "Garut, Sumedang, Tasikmalaya, Pangandaran, Ciamis, Banjar", |
|
261
|
|
|
|
|
|
|
}, |
|
262
|
|
|
|
|
|
|
); |
|
263
|
|
|
|
|
|
|
|
|
264
|
|
|
|
|
|
|
our %SPEC; |
|
265
|
|
|
|
|
|
|
|
|
266
|
|
|
|
|
|
|
$SPEC{parse_idn_vehicle_plate_number} = { |
|
267
|
|
|
|
|
|
|
v => 1.1, |
|
268
|
|
|
|
|
|
|
summary => 'Parse Indonesian vehicle plate number', |
|
269
|
|
|
|
|
|
|
args => { |
|
270
|
|
|
|
|
|
|
number => { |
|
271
|
|
|
|
|
|
|
summary => 'Input to be parsed', |
|
272
|
|
|
|
|
|
|
schema => 'str*', |
|
273
|
|
|
|
|
|
|
pos => 0, |
|
274
|
|
|
|
|
|
|
req => 1, |
|
275
|
|
|
|
|
|
|
}, |
|
276
|
|
|
|
|
|
|
}, |
|
277
|
|
|
|
|
|
|
}; |
|
278
|
|
|
|
|
|
|
sub parse_idn_vehicle_plate_number { |
|
279
|
2
|
|
|
2
|
1
|
481641
|
my %args = @_; |
|
280
|
|
|
|
|
|
|
|
|
281
|
|
|
|
|
|
|
defined(my $num = $args{number}) |
|
282
|
2
|
100
|
|
|
|
17
|
or return [400, "Please specify number"]; |
|
283
|
1
|
|
|
|
|
4
|
$num = uc $num; |
|
284
|
1
|
|
|
|
|
3
|
my $res = {}; |
|
285
|
|
|
|
|
|
|
|
|
286
|
1
|
|
|
|
|
11
|
$num =~ s/\s+//g; |
|
287
|
|
|
|
|
|
|
|
|
288
|
1
|
50
|
|
|
|
6
|
return [400, "Missing area prefix (1-2 letters)"] unless $num =~ s/\A([A-Z]{1,2})//; |
|
289
|
1
|
|
|
|
|
5
|
my $prefix = $1; |
|
290
|
1
|
|
|
|
|
3
|
$res->{prefix} = $prefix; |
|
291
|
1
|
50
|
|
|
|
7
|
if (my $area = $prefixes{ $prefix }) { |
|
292
|
1
|
|
|
|
|
6
|
$res->{ind_prefix_area} = $area->{summary}; |
|
293
|
1
|
|
|
|
|
4
|
$res->{prefix_iso_prov_codes} = $area->{iso_prov_codes}; |
|
294
|
|
|
|
|
|
|
} else { |
|
295
|
0
|
|
|
|
|
0
|
return [400, "Unknown area prefix: $prefix"]; |
|
296
|
|
|
|
|
|
|
} |
|
297
|
|
|
|
|
|
|
|
|
298
|
1
|
50
|
|
|
|
6
|
return [400, "Missing main number (1-4 digits after prefix)"] unless $num =~ s/\A(\d{1,4})//; |
|
299
|
1
|
|
|
|
|
4
|
my $main = $1; |
|
300
|
1
|
|
|
|
|
3
|
$res->{main} = $main; |
|
301
|
1
|
50
|
|
|
|
7
|
if ($main < 1) { |
|
|
|
50
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
302
|
0
|
|
|
|
|
0
|
return [400, "Main number cannot be 0"]; |
|
303
|
|
|
|
|
|
|
} elsif ($main < 2000) { |
|
304
|
1
|
|
|
|
|
3
|
$res->{ind_main_vehicle_type} = 'Kendaraan penumpang (1-1999)'; |
|
305
|
|
|
|
|
|
|
} elsif ($main < 7000) { |
|
306
|
0
|
|
|
|
|
0
|
$res->{ind_main_vehicle_type} = 'Sepeda motor (2000-6999)'; |
|
307
|
|
|
|
|
|
|
} elsif ($main < 8000) { |
|
308
|
0
|
|
|
|
|
0
|
$res->{ind_main_vehicle_type} = 'Bus (7000-7999)'; |
|
309
|
|
|
|
|
|
|
} else { |
|
310
|
0
|
|
|
|
|
0
|
$res->{ind_main_vehicle_type} = 'Kendaraan beban atau pengangkut (8000-9999)'; |
|
311
|
|
|
|
|
|
|
} |
|
312
|
|
|
|
|
|
|
|
|
313
|
|
|
|
|
|
|
# XXX check whether main number is a pretty number |
|
314
|
|
|
|
|
|
|
|
|
315
|
1
|
|
|
|
|
3
|
my $suffix = ""; |
|
316
|
|
|
|
|
|
|
GET_SUFFIX: { |
|
317
|
1
|
50
|
|
|
|
3
|
last unless $num =~ s/\A([A-Z]{1,3})//; |
|
|
1
|
|
|
|
|
6
|
|
|
318
|
1
|
|
|
|
|
4
|
$suffix = $1; |
|
319
|
|
|
|
|
|
|
} |
|
320
|
1
|
|
|
|
|
6
|
$res->{suffix} = $suffix; |
|
321
|
|
|
|
|
|
|
|
|
322
|
|
|
|
|
|
|
CHECK_RF_SUFFIX: { |
|
323
|
1
|
50
|
|
|
|
17
|
last unless $suffix =~ /\ARF(.)\z/; |
|
|
1
|
|
|
|
|
6
|
|
|
324
|
0
|
|
|
|
|
0
|
my $s = $1; |
|
325
|
0
|
|
|
|
|
0
|
$res->{ind_suffix_vehicle_type} = 'Staf pemerintahan (RF)'; |
|
326
|
0
|
0
|
|
|
|
0
|
if ($s eq 'S') { |
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
327
|
0
|
|
|
|
|
0
|
$res->{ind_suffix_rf_type} = 'Sekretariat Negara (S)'; |
|
328
|
|
|
|
|
|
|
} elsif ($s =~ /\A[OHQ]\z/) { |
|
329
|
0
|
|
|
|
|
0
|
$res->{ind_suffix_rf_type} = 'Pejabat eselon II (O/H/Q)'; |
|
330
|
0
|
0
|
|
|
|
0
|
$res->{ind_suffix_rf_type} .= ' (Kemenhan)' if $s eq 'H'; |
|
331
|
|
|
|
|
|
|
} elsif ($s eq 'P') { |
|
332
|
0
|
|
|
|
|
0
|
$res->{ind_suffix_rf_type} = 'Polri (P)'; |
|
333
|
|
|
|
|
|
|
} elsif ($s eq 'D') { |
|
334
|
0
|
|
|
|
|
0
|
$res->{ind_suffix_rf_type} = 'TNI AD (D)'; |
|
335
|
|
|
|
|
|
|
} elsif ($s eq 'L') { |
|
336
|
0
|
|
|
|
|
0
|
$res->{ind_suffix_rf_type} = 'TNI AL (L)'; |
|
337
|
|
|
|
|
|
|
} elsif ($s eq 'U') { |
|
338
|
0
|
|
|
|
|
0
|
$res->{ind_suffix_rf_type} = 'TNI AU (U)'; |
|
339
|
|
|
|
|
|
|
} else { |
|
340
|
0
|
|
|
|
|
0
|
$res->{ind_suffix_rf_type} = "Tidak dikenal ($s)" |
|
341
|
|
|
|
|
|
|
} |
|
342
|
|
|
|
|
|
|
} |
|
343
|
|
|
|
|
|
|
|
|
344
|
1
|
50
|
|
|
|
6
|
if ($prefix eq 'B') { |
|
345
|
|
|
|
|
|
|
CHECK_JAKARTA_SUFFIX1: { |
|
346
|
0
|
|
|
|
|
0
|
my $s = substr($suffix, 0, 1); |
|
|
0
|
|
|
|
|
0
|
|
|
347
|
0
|
0
|
|
|
|
0
|
if ($s eq 'B') { |
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
348
|
0
|
|
|
|
|
0
|
$res->{suffix1_city} = "Jakarta Barat (B)"; |
|
349
|
|
|
|
|
|
|
} elsif ($s eq 'P') { |
|
350
|
0
|
|
|
|
|
0
|
$res->{suffix1_city} = "Jakarta Pusat (P)"; |
|
351
|
|
|
|
|
|
|
} elsif ($s eq 'S') { |
|
352
|
0
|
|
|
|
|
0
|
$res->{suffix1_city} = "Jakarta Selatan (S)"; |
|
353
|
|
|
|
|
|
|
} elsif ($s eq 'T') { |
|
354
|
0
|
|
|
|
|
0
|
$res->{suffix1_city} = "Jakarta Timue (T)"; |
|
355
|
|
|
|
|
|
|
} elsif ($s eq 'U') { |
|
356
|
0
|
|
|
|
|
0
|
$res->{suffix1_city} = "Jakarta Utara & Kepulauan Seribu (U)"; |
|
357
|
|
|
|
|
|
|
} else { |
|
358
|
0
|
|
|
|
|
0
|
$res->{suffix1_city} = "Unknown ($s)"; |
|
359
|
|
|
|
|
|
|
} |
|
360
|
|
|
|
|
|
|
} |
|
361
|
|
|
|
|
|
|
CHECK_JAKARTA_SUFFIX2: { |
|
362
|
0
|
0
|
|
|
|
0
|
last unless length($suffix) >= 2; |
|
|
0
|
|
|
|
|
0
|
|
|
363
|
0
|
|
|
|
|
0
|
my $s = substr($suffix, 1, 1); |
|
364
|
0
|
0
|
|
|
|
0
|
if ($s eq 'A') { |
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
365
|
0
|
|
|
|
|
0
|
$res->{ind_suffix1_vehicle_type} = "Sedan/pickup (A)"; |
|
366
|
|
|
|
|
|
|
} elsif ($s eq 'D') { |
|
367
|
0
|
|
|
|
|
0
|
$res->{ind_suffix1_vehicle_type} = "Truk (D)"; |
|
368
|
|
|
|
|
|
|
} elsif ($s eq 'F') { |
|
369
|
0
|
|
|
|
|
0
|
$res->{ind_suffix1_vehicle_type} = "Minibus/hatchback/city (F)"; |
|
370
|
|
|
|
|
|
|
} elsif ($s eq 'J') { |
|
371
|
0
|
|
|
|
|
0
|
$res->{ind_suffix1_vehicle_type} = "Jip/SUV (J)"; |
|
372
|
|
|
|
|
|
|
} elsif ($s eq 'Q') { |
|
373
|
0
|
|
|
|
|
0
|
$res->{ind_suffix1_vehicle_type} = "Kendaraan staf pemerintah (Q)"; |
|
374
|
|
|
|
|
|
|
} elsif ($s eq 'T') { |
|
375
|
0
|
|
|
|
|
0
|
$res->{ind_suffix1_vehicle_type} = "Taksi (T)"; |
|
376
|
|
|
|
|
|
|
} elsif ($s eq 'U') { |
|
377
|
0
|
|
|
|
|
0
|
$res->{ind_suffix1_vehicle_type} = "Kendaraan staf pemerintah (U)"; |
|
378
|
|
|
|
|
|
|
} elsif ($s eq 'V') { |
|
379
|
0
|
|
|
|
|
0
|
$res->{ind_suffix1_vehicle_type} = "Minibus(V)"; |
|
380
|
|
|
|
|
|
|
} else { |
|
381
|
0
|
|
|
|
|
0
|
$res->{ind_suffix1_vehicle_type} = "Tidak dikenal ($s)"; |
|
382
|
|
|
|
|
|
|
} |
|
383
|
|
|
|
|
|
|
} |
|
384
|
|
|
|
|
|
|
} |
|
385
|
|
|
|
|
|
|
|
|
386
|
1
|
50
|
|
|
|
4
|
return [400, "Extraneous bits after suffix: $num"] if length $num; |
|
387
|
|
|
|
|
|
|
|
|
388
|
1
|
|
|
|
|
6
|
[200, "OK", $res]; |
|
389
|
|
|
|
|
|
|
} |
|
390
|
|
|
|
|
|
|
|
|
391
|
|
|
|
|
|
|
1; |
|
392
|
|
|
|
|
|
|
# ABSTRACT: Parse Indonesian vehicle plate number |
|
393
|
|
|
|
|
|
|
|
|
394
|
|
|
|
|
|
|
__END__ |
|
395
|
|
|
|
|
|
|
|
|
396
|
|
|
|
|
|
|
=pod |
|
397
|
|
|
|
|
|
|
|
|
398
|
|
|
|
|
|
|
=encoding UTF-8 |
|
399
|
|
|
|
|
|
|
|
|
400
|
|
|
|
|
|
|
=head1 NAME |
|
401
|
|
|
|
|
|
|
|
|
402
|
|
|
|
|
|
|
Business::ID::VehiclePlate - Parse Indonesian vehicle plate number |
|
403
|
|
|
|
|
|
|
|
|
404
|
|
|
|
|
|
|
=head1 VERSION |
|
405
|
|
|
|
|
|
|
|
|
406
|
|
|
|
|
|
|
This document describes version 0.002 of Business::ID::VehiclePlate (from Perl distribution Business-ID-VehiclePlate), released on 2024-08-05. |
|
407
|
|
|
|
|
|
|
|
|
408
|
|
|
|
|
|
|
=head1 SYNOPSIS |
|
409
|
|
|
|
|
|
|
|
|
410
|
|
|
|
|
|
|
use Business::ID::VehiclePlate qw(parse_idn_vehicle_plate_number); |
|
411
|
|
|
|
|
|
|
|
|
412
|
|
|
|
|
|
|
my $res = parse_idn_vehicle_plate_number(number => "B 1234 SJW"); |
|
413
|
|
|
|
|
|
|
|
|
414
|
|
|
|
|
|
|
=head1 DESCRIPTION |
|
415
|
|
|
|
|
|
|
|
|
416
|
|
|
|
|
|
|
Keywords: vehicle plate number, registered plate number |
|
417
|
|
|
|
|
|
|
|
|
418
|
|
|
|
|
|
|
=head1 FUNCTIONS |
|
419
|
|
|
|
|
|
|
|
|
420
|
|
|
|
|
|
|
|
|
421
|
|
|
|
|
|
|
=head2 parse_idn_vehicle_plate_number |
|
422
|
|
|
|
|
|
|
|
|
423
|
|
|
|
|
|
|
Usage: |
|
424
|
|
|
|
|
|
|
|
|
425
|
|
|
|
|
|
|
parse_idn_vehicle_plate_number(%args) -> [$status_code, $reason, $payload, \%result_meta] |
|
426
|
|
|
|
|
|
|
|
|
427
|
|
|
|
|
|
|
Parse Indonesian vehicle plate number. |
|
428
|
|
|
|
|
|
|
|
|
429
|
|
|
|
|
|
|
This function is not exported by default, but exportable. |
|
430
|
|
|
|
|
|
|
|
|
431
|
|
|
|
|
|
|
Arguments ('*' denotes required arguments): |
|
432
|
|
|
|
|
|
|
|
|
433
|
|
|
|
|
|
|
=over 4 |
|
434
|
|
|
|
|
|
|
|
|
435
|
|
|
|
|
|
|
=item * B<number>* => I<str> |
|
436
|
|
|
|
|
|
|
|
|
437
|
|
|
|
|
|
|
Input to be parsed. |
|
438
|
|
|
|
|
|
|
|
|
439
|
|
|
|
|
|
|
|
|
440
|
|
|
|
|
|
|
=back |
|
441
|
|
|
|
|
|
|
|
|
442
|
|
|
|
|
|
|
Returns an enveloped result (an array). |
|
443
|
|
|
|
|
|
|
|
|
444
|
|
|
|
|
|
|
First element ($status_code) is an integer containing HTTP-like status code |
|
445
|
|
|
|
|
|
|
(200 means OK, 4xx caller error, 5xx function error). Second element |
|
446
|
|
|
|
|
|
|
($reason) is a string containing error message, or something like "OK" if status is |
|
447
|
|
|
|
|
|
|
200. Third element ($payload) is the actual result, but usually not present when enveloped result is an error response ($status_code is not 2xx). Fourth |
|
448
|
|
|
|
|
|
|
element (%result_meta) is called result metadata and is optional, a hash |
|
449
|
|
|
|
|
|
|
that contains extra information, much like how HTTP response headers provide additional metadata. |
|
450
|
|
|
|
|
|
|
|
|
451
|
|
|
|
|
|
|
Return value: (any) |
|
452
|
|
|
|
|
|
|
|
|
453
|
|
|
|
|
|
|
=head1 HOMEPAGE |
|
454
|
|
|
|
|
|
|
|
|
455
|
|
|
|
|
|
|
Please visit the project's homepage at L<https://metacpan.org/release/Business-ID-VehiclePlate>. |
|
456
|
|
|
|
|
|
|
|
|
457
|
|
|
|
|
|
|
=head1 SOURCE |
|
458
|
|
|
|
|
|
|
|
|
459
|
|
|
|
|
|
|
Source repository is at L<https://github.com/perlancar/perl-Business-ID-VehiclePlate>. |
|
460
|
|
|
|
|
|
|
|
|
461
|
|
|
|
|
|
|
=head1 AUTHOR |
|
462
|
|
|
|
|
|
|
|
|
463
|
|
|
|
|
|
|
perlancar <perlancar@cpan.org> |
|
464
|
|
|
|
|
|
|
|
|
465
|
|
|
|
|
|
|
=head1 CONTRIBUTING |
|
466
|
|
|
|
|
|
|
|
|
467
|
|
|
|
|
|
|
|
|
468
|
|
|
|
|
|
|
To contribute, you can send patches by email/via RT, or send pull requests on |
|
469
|
|
|
|
|
|
|
GitHub. |
|
470
|
|
|
|
|
|
|
|
|
471
|
|
|
|
|
|
|
Most of the time, you don't need to build the distribution yourself. You can |
|
472
|
|
|
|
|
|
|
simply modify the code, then test via: |
|
473
|
|
|
|
|
|
|
|
|
474
|
|
|
|
|
|
|
% prove -l |
|
475
|
|
|
|
|
|
|
|
|
476
|
|
|
|
|
|
|
If you want to build the distribution (e.g. to try to install it locally on your |
|
477
|
|
|
|
|
|
|
system), you can install L<Dist::Zilla>, |
|
478
|
|
|
|
|
|
|
L<Dist::Zilla::PluginBundle::Author::PERLANCAR>, |
|
479
|
|
|
|
|
|
|
L<Pod::Weaver::PluginBundle::Author::PERLANCAR>, and sometimes one or two other |
|
480
|
|
|
|
|
|
|
Dist::Zilla- and/or Pod::Weaver plugins. Any additional steps required beyond |
|
481
|
|
|
|
|
|
|
that are considered a bug and can be reported to me. |
|
482
|
|
|
|
|
|
|
|
|
483
|
|
|
|
|
|
|
=head1 COPYRIGHT AND LICENSE |
|
484
|
|
|
|
|
|
|
|
|
485
|
|
|
|
|
|
|
This software is copyright (c) 2024 by perlancar <perlancar@cpan.org>. |
|
486
|
|
|
|
|
|
|
|
|
487
|
|
|
|
|
|
|
This is free software; you can redistribute it and/or modify it under |
|
488
|
|
|
|
|
|
|
the same terms as the Perl 5 programming language system itself. |
|
489
|
|
|
|
|
|
|
|
|
490
|
|
|
|
|
|
|
=head1 BUGS |
|
491
|
|
|
|
|
|
|
|
|
492
|
|
|
|
|
|
|
Please report any bugs or feature requests on the bugtracker website L<https://rt.cpan.org/Public/Dist/Display.html?Name=Business-ID-VehiclePlate> |
|
493
|
|
|
|
|
|
|
|
|
494
|
|
|
|
|
|
|
When submitting a bug or request, please include a test-file or a |
|
495
|
|
|
|
|
|
|
patch to an existing test-file that illustrates the bug or desired |
|
496
|
|
|
|
|
|
|
feature. |
|
497
|
|
|
|
|
|
|
|
|
498
|
|
|
|
|
|
|
=cut |