Soundex::daitchMokotoffWord()   F
last analyzed

Complexity

Conditions 24
Paths 1344

Size

Total Lines 110
Code Lines 61

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 24
eloc 61
nc 1344
nop 1
dl 0
loc 110
rs 0
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/**
4
 * webtrees: online genealogy
5
 * Copyright (C) 2022 webtrees development team
6
 * This program is free software: you can redistribute it and/or modify
7
 * it under the terms of the GNU General Public License as published by
8
 * the Free Software Foundation, either version 3 of the License, or
9
 * (at your option) any later version.
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
 * GNU General Public License for more details.
14
 * You should have received a copy of the GNU General Public License
15
 * along with this program. If not, see <https://www.gnu.org/licenses/>.
16
 */
17
18
declare(strict_types=1);
19
20
namespace Fisharebest\Webtrees;
21
22
/**
23
 * Phonetic matching of strings.
24
 */
25
class Soundex
26
{
27
    // Determine the Daitch–Mokotoff Soundex code for a word
28
    // Original implementation by Gerry Kroll, and analysis by Meliza Amity
29
30
    // Max. table key length (in ASCII bytes -- NOT in UTF-8 characters!)
31
    private const MAXCHAR = 7;
32
33
    /**
34
     * Name transformation arrays.
35
     * Used to transform the Name string to simplify the "sounds like" table.
36
     * This is especially useful in Hebrew.
37
     *
38
     * Each array entry defines the "from" and "to" arguments of an preg($from, $to, $text)
39
     * function call to achieve the desired transformations.
40
     *
41
     * Note about the use of "\x01":
42
     * This code, which can’t legitimately occur in the kind of text we're dealing with,
43
     * is used as a place-holder so that conditional string replacements can be done.
44
     */
45
    private const TRANSFORM_NAMES = [
46
        // Force Yiddish ligatures to be treated as separate letters
47
        [
48
            'װ',
49
            'וו',
50
        ],
51
        [
52
            'ײ',
53
            'יי',
54
        ],
55
        [
56
            'ױ',
57
            'וי',
58
        ],
59
        [
60
            'בו',
61
            'בע',
62
        ],
63
        [
64
            'פו',
65
            'פע',
66
        ],
67
        [
68
            'ומ',
69
            'עמ',
70
        ],
71
        [
72
            'ום',
73
            'עם',
74
        ],
75
        [
76
            'ונ',
77
            'ענ',
78
        ],
79
        [
80
            'ון',
81
            'ען',
82
        ],
83
        [
84
            'וו',
85
            'ב',
86
        ],
87
        [
88
            "\x01",
89
            '',
90
        ],
91
        [
92
            'ייה$',
93
            "\x01ה",
94
        ],
95
        [
96
            'ייע$',
97
            "\x01ע",
98
        ],
99
        [
100
            'יי',
101
            'ע',
102
        ],
103
        [
104
            "\x01",
105
            'יי',
106
        ],
107
    ];
108
109
    /**
110
     * The DM sound coding table is organized this way:
111
     * key: a variable-length string that corresponds to the UTF-8 character sequence
112
     * represented by the table entry. Currently, that string can be up to 7
113
     * bytes long. This maximum length is defined by the value of global variable
114
     * $maxchar.
115
     *
116
     * value: an array as follows:
117
     * [0]:  zero if not a vowel
118
     * [1]:  sound value when this string is at the beginning of the word
119
     * [2]:  sound value when this string is followed by a vowel
120
     * [3]:  sound value for other cases
121
     * [1],[2],[3] can be repeated several times to create branches in the code
122
     * an empty sound value means "ignore in this state"
123
     */
124
    private const DM_SOUNDS = [
125
        'A'       => [
126
            '1',
127
            '0',
128
            '',
129
            '',
130
        ],
131
        'À'       => [
132
            '1',
133
            '0',
134
            '',
135
            '',
136
        ],
137
        'Á'       => [
138
            '1',
139
            '0',
140
            '',
141
            '',
142
        ],
143
        'Â'       => [
144
            '1',
145
            '0',
146
            '',
147
            '',
148
        ],
149
        'Ã'       => [
150
            '1',
151
            '0',
152
            '',
153
            '',
154
        ],
155
        'Ä'       => [
156
            '1',
157
            '0',
158
            '1',
159
            '',
160
            '0',
161
            '',
162
            '',
163
        ],
164
        'Å'       => [
165
            '1',
166
            '0',
167
            '',
168
            '',
169
        ],
170
        'Ă'       => [
171
            '1',
172
            '0',
173
            '',
174
            '',
175
        ],
176
        'Ą'       => [
177
            '1',
178
            '',
179
            '',
180
            '',
181
            '',
182
            '',
183
            '6',
184
        ],
185
        'Ạ'       => [
186
            '1',
187
            '0',
188
            '',
189
            '',
190
        ],
191
        'Ả'       => [
192
            '1',
193
            '0',
194
            '',
195
            '',
196
        ],
197
        'Ấ'       => [
198
            '1',
199
            '0',
200
            '',
201
            '',
202
        ],
203
        'Ầ'       => [
204
            '1',
205
            '0',
206
            '',
207
            '',
208
        ],
209
        'Ẩ'       => [
210
            '1',
211
            '0',
212
            '',
213
            '',
214
        ],
215
        'Ẫ'       => [
216
            '1',
217
            '0',
218
            '',
219
            '',
220
        ],
221
        'Ậ'       => [
222
            '1',
223
            '0',
224
            '',
225
            '',
226
        ],
227
        'Ắ'       => [
228
            '1',
229
            '0',
230
            '',
231
            '',
232
        ],
233
        'Ằ'       => [
234
            '1',
235
            '0',
236
            '',
237
            '',
238
        ],
239
        'Ẳ'       => [
240
            '1',
241
            '0',
242
            '',
243
            '',
244
        ],
245
        'Ẵ'       => [
246
            '1',
247
            '0',
248
            '',
249
            '',
250
        ],
251
        'Ặ'       => [
252
            '1',
253
            '0',
254
            '',
255
            '',
256
        ],
257
        'AE'      => [
258
            '1',
259
            '0',
260
            '1',
261
            '',
262
        ],
263
        'Æ'       => [
264
            '1',
265
            '0',
266
            '1',
267
            '',
268
        ],
269
        'AI'      => [
270
            '1',
271
            '0',
272
            '1',
273
            '',
274
        ],
275
        'AJ'      => [
276
            '1',
277
            '0',
278
            '1',
279
            '',
280
        ],
281
        'AU'      => [
282
            '1',
283
            '0',
284
            '7',
285
            '',
286
        ],
287
        'AV'      => [
288
            '1',
289
            '0',
290
            '7',
291
            '',
292
            '7',
293
            '7',
294
            '7',
295
        ],
296
        'ÄU'      => [
297
            '1',
298
            '0',
299
            '1',
300
            '',
301
        ],
302
        'AY'      => [
303
            '1',
304
            '0',
305
            '1',
306
            '',
307
        ],
308
        'B'       => [
309
            '0',
310
            '7',
311
            '7',
312
            '7',
313
        ],
314
        'C'       => [
315
            '0',
316
            '5',
317
            '5',
318
            '5',
319
            '34',
320
            '4',
321
            '4',
322
        ],
323
        'Ć'       => [
324
            '0',
325
            '4',
326
            '4',
327
            '4',
328
        ],
329
        'Č'       => [
330
            '0',
331
            '4',
332
            '4',
333
            '4',
334
        ],
335
        'Ç'       => [
336
            '0',
337
            '4',
338
            '4',
339
            '4',
340
        ],
341
        'CH'      => [
342
            '0',
343
            '5',
344
            '5',
345
            '5',
346
            '34',
347
            '4',
348
            '4',
349
        ],
350
        'CHS'     => [
351
            '0',
352
            '5',
353
            '54',
354
            '54',
355
        ],
356
        'CK'      => [
357
            '0',
358
            '5',
359
            '5',
360
            '5',
361
            '45',
362
            '45',
363
            '45',
364
        ],
365
        'CCS'     => [
366
            '0',
367
            '4',
368
            '4',
369
            '4',
370
        ],
371
        'CS'      => [
372
            '0',
373
            '4',
374
            '4',
375
            '4',
376
        ],
377
        'CSZ'     => [
378
            '0',
379
            '4',
380
            '4',
381
            '4',
382
        ],
383
        'CZ'      => [
384
            '0',
385
            '4',
386
            '4',
387
            '4',
388
        ],
389
        'CZS'     => [
390
            '0',
391
            '4',
392
            '4',
393
            '4',
394
        ],
395
        'D'       => [
396
            '0',
397
            '3',
398
            '3',
399
            '3',
400
        ],
401
        'Ď'       => [
402
            '0',
403
            '3',
404
            '3',
405
            '3',
406
        ],
407
        'Đ'       => [
408
            '0',
409
            '3',
410
            '3',
411
            '3',
412
        ],
413
        'DRS'     => [
414
            '0',
415
            '4',
416
            '4',
417
            '4',
418
        ],
419
        'DRZ'     => [
420
            '0',
421
            '4',
422
            '4',
423
            '4',
424
        ],
425
        'DS'      => [
426
            '0',
427
            '4',
428
            '4',
429
            '4',
430
        ],
431
        'DSH'     => [
432
            '0',
433
            '4',
434
            '4',
435
            '4',
436
        ],
437
        'DSZ'     => [
438
            '0',
439
            '4',
440
            '4',
441
            '4',
442
        ],
443
        'DT'      => [
444
            '0',
445
            '3',
446
            '3',
447
            '3',
448
        ],
449
        'DDZ'     => [
450
            '0',
451
            '4',
452
            '4',
453
            '4',
454
        ],
455
        'DDZS'    => [
456
            '0',
457
            '4',
458
            '4',
459
            '4',
460
        ],
461
        'DZ'      => [
462
            '0',
463
            '4',
464
            '4',
465
            '4',
466
        ],
467
        'DŹ'      => [
468
            '0',
469
            '4',
470
            '4',
471
            '4',
472
        ],
473
        'DŻ'      => [
474
            '0',
475
            '4',
476
            '4',
477
            '4',
478
        ],
479
        'DZH'     => [
480
            '0',
481
            '4',
482
            '4',
483
            '4',
484
        ],
485
        'DZS'     => [
486
            '0',
487
            '4',
488
            '4',
489
            '4',
490
        ],
491
        'E'       => [
492
            '1',
493
            '0',
494
            '',
495
            '',
496
        ],
497
        'È'       => [
498
            '1',
499
            '0',
500
            '',
501
            '',
502
        ],
503
        'É'       => [
504
            '1',
505
            '0',
506
            '',
507
            '',
508
        ],
509
        'Ê'       => [
510
            '1',
511
            '0',
512
            '',
513
            '',
514
        ],
515
        'Ë'       => [
516
            '1',
517
            '0',
518
            '',
519
            '',
520
        ],
521
        'Ĕ'       => [
522
            '1',
523
            '0',
524
            '',
525
            '',
526
        ],
527
        'Ė'       => [
528
            '1',
529
            '0',
530
            '',
531
            '',
532
        ],
533
        'Ę'       => [
534
            '1',
535
            '',
536
            '',
537
            '6',
538
            '',
539
            '',
540
            '',
541
        ],
542
        'Ẹ'       => [
543
            '1',
544
            '0',
545
            '',
546
            '',
547
        ],
548
        'Ẻ'       => [
549
            '1',
550
            '0',
551
            '',
552
            '',
553
        ],
554
        'Ẽ'       => [
555
            '1',
556
            '0',
557
            '',
558
            '',
559
        ],
560
        'Ế'       => [
561
            '1',
562
            '0',
563
            '',
564
            '',
565
        ],
566
        'Ề'       => [
567
            '1',
568
            '0',
569
            '',
570
            '',
571
        ],
572
        'Ể'       => [
573
            '1',
574
            '0',
575
            '',
576
            '',
577
        ],
578
        'Ễ'       => [
579
            '1',
580
            '0',
581
            '',
582
            '',
583
        ],
584
        'Ệ'       => [
585
            '1',
586
            '0',
587
            '',
588
            '',
589
        ],
590
        'EAU'     => [
591
            '1',
592
            '0',
593
            '',
594
            '',
595
        ],
596
        'EI'      => [
597
            '1',
598
            '0',
599
            '1',
600
            '',
601
        ],
602
        'EJ'      => [
603
            '1',
604
            '0',
605
            '1',
606
            '',
607
        ],
608
        'EU'      => [
609
            '1',
610
            '1',
611
            '1',
612
            '',
613
        ],
614
        'EY'      => [
615
            '1',
616
            '0',
617
            '1',
618
            '',
619
        ],
620
        'F'       => [
621
            '0',
622
            '7',
623
            '7',
624
            '7',
625
        ],
626
        'FB'      => [
627
            '0',
628
            '7',
629
            '7',
630
            '7',
631
        ],
632
        'G'       => [
633
            '0',
634
            '5',
635
            '5',
636
            '5',
637
            '34',
638
            '4',
639
            '4',
640
        ],
641
        'Ğ'       => [
642
            '0',
643
            '',
644
            '',
645
            '',
646
        ],
647
        'GGY'     => [
648
            '0',
649
            '5',
650
            '5',
651
            '5',
652
        ],
653
        'GY'      => [
654
            '0',
655
            '5',
656
            '5',
657
            '5',
658
        ],
659
        'H'       => [
660
            '0',
661
            '5',
662
            '5',
663
            '',
664
            '5',
665
            '5',
666
            '5',
667
        ],
668
        'I'       => [
669
            '1',
670
            '0',
671
            '',
672
            '',
673
        ],
674
        'Ì'       => [
675
            '1',
676
            '0',
677
            '',
678
            '',
679
        ],
680
        'Í'       => [
681
            '1',
682
            '0',
683
            '',
684
            '',
685
        ],
686
        'Î'       => [
687
            '1',
688
            '0',
689
            '',
690
            '',
691
        ],
692
        'Ï'       => [
693
            '1',
694
            '0',
695
            '',
696
            '',
697
        ],
698
        'Ĩ'       => [
699
            '1',
700
            '0',
701
            '',
702
            '',
703
        ],
704
        'Į'       => [
705
            '1',
706
            '0',
707
            '',
708
            '',
709
        ],
710
        'İ'       => [
711
            '1',
712
            '0',
713
            '',
714
            '',
715
        ],
716
        'Ỉ'       => [
717
            '1',
718
            '0',
719
            '',
720
            '',
721
        ],
722
        'Ị'       => [
723
            '1',
724
            '0',
725
            '',
726
            '',
727
        ],
728
        'IA'      => [
729
            '1',
730
            '1',
731
            '',
732
            '',
733
        ],
734
        'IE'      => [
735
            '1',
736
            '1',
737
            '',
738
            '',
739
        ],
740
        'IO'      => [
741
            '1',
742
            '1',
743
            '',
744
            '',
745
        ],
746
        'IU'      => [
747
            '1',
748
            '1',
749
            '',
750
            '',
751
        ],
752
        'J'       => [
753
            '0',
754
            '1',
755
            '',
756
            '',
757
            '4',
758
            '4',
759
            '4',
760
            '5',
761
            '5',
762
            '',
763
        ],
764
        'K'       => [
765
            '0',
766
            '5',
767
            '5',
768
            '5',
769
        ],
770
        'KH'      => [
771
            '0',
772
            '5',
773
            '5',
774
            '5',
775
        ],
776
        'KS'      => [
777
            '0',
778
            '5',
779
            '54',
780
            '54',
781
        ],
782
        'L'       => [
783
            '0',
784
            '8',
785
            '8',
786
            '8',
787
        ],
788
        'Ľ'       => [
789
            '0',
790
            '8',
791
            '8',
792
            '8',
793
        ],
794
        'Ĺ'       => [
795
            '0',
796
            '8',
797
            '8',
798
            '8',
799
        ],
800
        'Ł'       => [
801
            '0',
802
            '7',
803
            '7',
804
            '7',
805
            '8',
806
            '8',
807
            '8',
808
        ],
809
        'LL'      => [
810
            '0',
811
            '8',
812
            '8',
813
            '8',
814
            '58',
815
            '8',
816
            '8',
817
            '1',
818
            '8',
819
            '8',
820
        ],
821
        'LLY'     => [
822
            '0',
823
            '8',
824
            '8',
825
            '8',
826
            '1',
827
            '8',
828
            '8',
829
        ],
830
        'LY'      => [
831
            '0',
832
            '8',
833
            '8',
834
            '8',
835
            '1',
836
            '8',
837
            '8',
838
        ],
839
        'M'       => [
840
            '0',
841
            '6',
842
            '6',
843
            '6',
844
        ],
845
        'MĔ'      => [
846
            '0',
847
            '66',
848
            '66',
849
            '66',
850
        ],
851
        'MN'      => [
852
            '0',
853
            '66',
854
            '66',
855
            '66',
856
        ],
857
        'N'       => [
858
            '0',
859
            '6',
860
            '6',
861
            '6',
862
        ],
863
        'Ń'       => [
864
            '0',
865
            '6',
866
            '6',
867
            '6',
868
        ],
869
        'Ň'       => [
870
            '0',
871
            '6',
872
            '6',
873
            '6',
874
        ],
875
        'Ñ'       => [
876
            '0',
877
            '6',
878
            '6',
879
            '6',
880
        ],
881
        'NM'      => [
882
            '0',
883
            '66',
884
            '66',
885
            '66',
886
        ],
887
        'O'       => [
888
            '1',
889
            '0',
890
            '',
891
            '',
892
        ],
893
        'Ò'       => [
894
            '1',
895
            '0',
896
            '',
897
            '',
898
        ],
899
        'Ó'       => [
900
            '1',
901
            '0',
902
            '',
903
            '',
904
        ],
905
        'Ô'       => [
906
            '1',
907
            '0',
908
            '',
909
            '',
910
        ],
911
        'Õ'       => [
912
            '1',
913
            '0',
914
            '',
915
            '',
916
        ],
917
        'Ö'       => [
918
            '1',
919
            '0',
920
            '',
921
            '',
922
        ],
923
        'Ø'       => [
924
            '1',
925
            '0',
926
            '',
927
            '',
928
        ],
929
        'Ő'       => [
930
            '1',
931
            '0',
932
            '',
933
            '',
934
        ],
935
        'Œ'       => [
936
            '1',
937
            '0',
938
            '',
939
            '',
940
        ],
941
        'Ơ'       => [
942
            '1',
943
            '0',
944
            '',
945
            '',
946
        ],
947
        'Ọ'       => [
948
            '1',
949
            '0',
950
            '',
951
            '',
952
        ],
953
        'Ỏ'       => [
954
            '1',
955
            '0',
956
            '',
957
            '',
958
        ],
959
        'Ố'       => [
960
            '1',
961
            '0',
962
            '',
963
            '',
964
        ],
965
        'Ồ'       => [
966
            '1',
967
            '0',
968
            '',
969
            '',
970
        ],
971
        'Ổ'       => [
972
            '1',
973
            '0',
974
            '',
975
            '',
976
        ],
977
        'Ỗ'       => [
978
            '1',
979
            '0',
980
            '',
981
            '',
982
        ],
983
        'Ộ'       => [
984
            '1',
985
            '0',
986
            '',
987
            '',
988
        ],
989
        'Ớ'       => [
990
            '1',
991
            '0',
992
            '',
993
            '',
994
        ],
995
        'Ờ'       => [
996
            '1',
997
            '0',
998
            '',
999
            '',
1000
        ],
1001
        'Ở'       => [
1002
            '1',
1003
            '0',
1004
            '',
1005
            '',
1006
        ],
1007
        'Ỡ'       => [
1008
            '1',
1009
            '0',
1010
            '',
1011
            '',
1012
        ],
1013
        'Ợ'       => [
1014
            '1',
1015
            '0',
1016
            '',
1017
            '',
1018
        ],
1019
        'OE'      => [
1020
            '1',
1021
            '0',
1022
            '',
1023
            '',
1024
        ],
1025
        'OI'      => [
1026
            '1',
1027
            '0',
1028
            '1',
1029
            '',
1030
        ],
1031
        'OJ'      => [
1032
            '1',
1033
            '0',
1034
            '1',
1035
            '',
1036
        ],
1037
        'OU'      => [
1038
            '1',
1039
            '0',
1040
            '',
1041
            '',
1042
        ],
1043
        'OY'      => [
1044
            '1',
1045
            '0',
1046
            '1',
1047
            '',
1048
        ],
1049
        'P'       => [
1050
            '0',
1051
            '7',
1052
            '7',
1053
            '7',
1054
        ],
1055
        'PF'      => [
1056
            '0',
1057
            '7',
1058
            '7',
1059
            '7',
1060
        ],
1061
        'PH'      => [
1062
            '0',
1063
            '7',
1064
            '7',
1065
            '7',
1066
        ],
1067
        'Q'       => [
1068
            '0',
1069
            '5',
1070
            '5',
1071
            '5',
1072
        ],
1073
        'R'       => [
1074
            '0',
1075
            '9',
1076
            '9',
1077
            '9',
1078
        ],
1079
        'Ř'       => [
1080
            '0',
1081
            '4',
1082
            '4',
1083
            '4',
1084
        ],
1085
        'RS'      => [
1086
            '0',
1087
            '4',
1088
            '4',
1089
            '4',
1090
            '94',
1091
            '94',
1092
            '94',
1093
        ],
1094
        'RZ'      => [
1095
            '0',
1096
            '4',
1097
            '4',
1098
            '4',
1099
            '94',
1100
            '94',
1101
            '94',
1102
        ],
1103
        'S'       => [
1104
            '0',
1105
            '4',
1106
            '4',
1107
            '4',
1108
        ],
1109
        'Ś'       => [
1110
            '0',
1111
            '4',
1112
            '4',
1113
            '4',
1114
        ],
1115
        'Š'       => [
1116
            '0',
1117
            '4',
1118
            '4',
1119
            '4',
1120
        ],
1121
        'Ş'       => [
1122
            '0',
1123
            '4',
1124
            '4',
1125
            '4',
1126
        ],
1127
        'SC'      => [
1128
            '0',
1129
            '2',
1130
            '4',
1131
            '4',
1132
        ],
1133
        'ŠČ'      => [
1134
            '0',
1135
            '2',
1136
            '4',
1137
            '4',
1138
        ],
1139
        'SCH'     => [
1140
            '0',
1141
            '4',
1142
            '4',
1143
            '4',
1144
        ],
1145
        'SCHD'    => [
1146
            '0',
1147
            '2',
1148
            '43',
1149
            '43',
1150
        ],
1151
        'SCHT'    => [
1152
            '0',
1153
            '2',
1154
            '43',
1155
            '43',
1156
        ],
1157
        'SCHTCH'  => [
1158
            '0',
1159
            '2',
1160
            '4',
1161
            '4',
1162
        ],
1163
        'SCHTSCH' => [
1164
            '0',
1165
            '2',
1166
            '4',
1167
            '4',
1168
        ],
1169
        'SCHTSH'  => [
1170
            '0',
1171
            '2',
1172
            '4',
1173
            '4',
1174
        ],
1175
        'SD'      => [
1176
            '0',
1177
            '2',
1178
            '43',
1179
            '43',
1180
        ],
1181
        'SH'      => [
1182
            '0',
1183
            '4',
1184
            '4',
1185
            '4',
1186
        ],
1187
        'SHCH'    => [
1188
            '0',
1189
            '2',
1190
            '4',
1191
            '4',
1192
        ],
1193
        'SHD'     => [
1194
            '0',
1195
            '2',
1196
            '43',
1197
            '43',
1198
        ],
1199
        'SHT'     => [
1200
            '0',
1201
            '2',
1202
            '43',
1203
            '43',
1204
        ],
1205
        'SHTCH'   => [
1206
            '0',
1207
            '2',
1208
            '4',
1209
            '4',
1210
        ],
1211
        'SHTSH'   => [
1212
            '0',
1213
            '2',
1214
            '4',
1215
            '4',
1216
        ],
1217
        'ß'       => [
1218
            '0',
1219
            '',
1220
            '4',
1221
            '4',
1222
        ],
1223
        'ST'      => [
1224
            '0',
1225
            '2',
1226
            '43',
1227
            '43',
1228
        ],
1229
        'STCH'    => [
1230
            '0',
1231
            '2',
1232
            '4',
1233
            '4',
1234
        ],
1235
        'STRS'    => [
1236
            '0',
1237
            '2',
1238
            '4',
1239
            '4',
1240
        ],
1241
        'STRZ'    => [
1242
            '0',
1243
            '2',
1244
            '4',
1245
            '4',
1246
        ],
1247
        'STSCH'   => [
1248
            '0',
1249
            '2',
1250
            '4',
1251
            '4',
1252
        ],
1253
        'STSH'    => [
1254
            '0',
1255
            '2',
1256
            '4',
1257
            '4',
1258
        ],
1259
        'SSZ'     => [
1260
            '0',
1261
            '4',
1262
            '4',
1263
            '4',
1264
        ],
1265
        'SZ'      => [
1266
            '0',
1267
            '4',
1268
            '4',
1269
            '4',
1270
        ],
1271
        'SZCS'    => [
1272
            '0',
1273
            '2',
1274
            '4',
1275
            '4',
1276
        ],
1277
        'SZCZ'    => [
1278
            '0',
1279
            '2',
1280
            '4',
1281
            '4',
1282
        ],
1283
        'SZD'     => [
1284
            '0',
1285
            '2',
1286
            '43',
1287
            '43',
1288
        ],
1289
        'SZT'     => [
1290
            '0',
1291
            '2',
1292
            '43',
1293
            '43',
1294
        ],
1295
        'T'       => [
1296
            '0',
1297
            '3',
1298
            '3',
1299
            '3',
1300
        ],
1301
        'Ť'       => [
1302
            '0',
1303
            '3',
1304
            '3',
1305
            '3',
1306
        ],
1307
        'Ţ'       => [
1308
            '0',
1309
            '3',
1310
            '3',
1311
            '3',
1312
            '4',
1313
            '4',
1314
            '4',
1315
        ],
1316
        'TC'      => [
1317
            '0',
1318
            '4',
1319
            '4',
1320
            '4',
1321
        ],
1322
        'TCH'     => [
1323
            '0',
1324
            '4',
1325
            '4',
1326
            '4',
1327
        ],
1328
        'TH'      => [
1329
            '0',
1330
            '3',
1331
            '3',
1332
            '3',
1333
        ],
1334
        'TRS'     => [
1335
            '0',
1336
            '4',
1337
            '4',
1338
            '4',
1339
        ],
1340
        'TRZ'     => [
1341
            '0',
1342
            '4',
1343
            '4',
1344
            '4',
1345
        ],
1346
        'TS'      => [
1347
            '0',
1348
            '4',
1349
            '4',
1350
            '4',
1351
        ],
1352
        'TSCH'    => [
1353
            '0',
1354
            '4',
1355
            '4',
1356
            '4',
1357
        ],
1358
        'TSH'     => [
1359
            '0',
1360
            '4',
1361
            '4',
1362
            '4',
1363
        ],
1364
        'TSZ'     => [
1365
            '0',
1366
            '4',
1367
            '4',
1368
            '4',
1369
        ],
1370
        'TTCH'    => [
1371
            '0',
1372
            '4',
1373
            '4',
1374
            '4',
1375
        ],
1376
        'TTS'     => [
1377
            '0',
1378
            '4',
1379
            '4',
1380
            '4',
1381
        ],
1382
        'TTSCH'   => [
1383
            '0',
1384
            '4',
1385
            '4',
1386
            '4',
1387
        ],
1388
        'TTSZ'    => [
1389
            '0',
1390
            '4',
1391
            '4',
1392
            '4',
1393
        ],
1394
        'TTZ'     => [
1395
            '0',
1396
            '4',
1397
            '4',
1398
            '4',
1399
        ],
1400
        'TZ'      => [
1401
            '0',
1402
            '4',
1403
            '4',
1404
            '4',
1405
        ],
1406
        'TZS'     => [
1407
            '0',
1408
            '4',
1409
            '4',
1410
            '4',
1411
        ],
1412
        'U'       => [
1413
            '1',
1414
            '0',
1415
            '',
1416
            '',
1417
        ],
1418
        'Ù'       => [
1419
            '1',
1420
            '0',
1421
            '',
1422
            '',
1423
        ],
1424
        'Ú'       => [
1425
            '1',
1426
            '0',
1427
            '',
1428
            '',
1429
        ],
1430
        'Û'       => [
1431
            '1',
1432
            '0',
1433
            '',
1434
            '',
1435
        ],
1436
        'Ü'       => [
1437
            '1',
1438
            '0',
1439
            '',
1440
            '',
1441
        ],
1442
        'Ũ'       => [
1443
            '1',
1444
            '0',
1445
            '',
1446
            '',
1447
        ],
1448
        'Ū'       => [
1449
            '1',
1450
            '0',
1451
            '',
1452
            '',
1453
        ],
1454
        'Ů'       => [
1455
            '1',
1456
            '0',
1457
            '',
1458
            '',
1459
        ],
1460
        'Ű'       => [
1461
            '1',
1462
            '0',
1463
            '',
1464
            '',
1465
        ],
1466
        'Ų'       => [
1467
            '1',
1468
            '0',
1469
            '',
1470
            '',
1471
        ],
1472
        'Ư'       => [
1473
            '1',
1474
            '0',
1475
            '',
1476
            '',
1477
        ],
1478
        'Ụ'       => [
1479
            '1',
1480
            '0',
1481
            '',
1482
            '',
1483
        ],
1484
        'Ủ'       => [
1485
            '1',
1486
            '0',
1487
            '',
1488
            '',
1489
        ],
1490
        'Ứ'       => [
1491
            '1',
1492
            '0',
1493
            '',
1494
            '',
1495
        ],
1496
        'Ừ'       => [
1497
            '1',
1498
            '0',
1499
            '',
1500
            '',
1501
        ],
1502
        'Ử'       => [
1503
            '1',
1504
            '0',
1505
            '',
1506
            '',
1507
        ],
1508
        'Ữ'       => [
1509
            '1',
1510
            '0',
1511
            '',
1512
            '',
1513
        ],
1514
        'Ự'       => [
1515
            '1',
1516
            '0',
1517
            '',
1518
            '',
1519
        ],
1520
        'UE'      => [
1521
            '1',
1522
            '0',
1523
            '',
1524
            '',
1525
        ],
1526
        'UI'      => [
1527
            '1',
1528
            '0',
1529
            '1',
1530
            '',
1531
        ],
1532
        'UJ'      => [
1533
            '1',
1534
            '0',
1535
            '1',
1536
            '',
1537
        ],
1538
        'UY'      => [
1539
            '1',
1540
            '0',
1541
            '1',
1542
            '',
1543
        ],
1544
        'UW'      => [
1545
            '1',
1546
            '0',
1547
            '1',
1548
            '',
1549
            '0',
1550
            '7',
1551
            '7',
1552
        ],
1553
        'V'       => [
1554
            '0',
1555
            '7',
1556
            '7',
1557
            '7',
1558
        ],
1559
        'W'       => [
1560
            '0',
1561
            '7',
1562
            '7',
1563
            '7',
1564
        ],
1565
        'X'       => [
1566
            '0',
1567
            '5',
1568
            '54',
1569
            '54',
1570
        ],
1571
        'Y'       => [
1572
            '1',
1573
            '1',
1574
            '',
1575
            '',
1576
        ],
1577
        'Ý'       => [
1578
            '1',
1579
            '1',
1580
            '',
1581
            '',
1582
        ],
1583
        'Ỳ'       => [
1584
            '1',
1585
            '1',
1586
            '',
1587
            '',
1588
        ],
1589
        'Ỵ'       => [
1590
            '1',
1591
            '1',
1592
            '',
1593
            '',
1594
        ],
1595
        'Ỷ'       => [
1596
            '1',
1597
            '1',
1598
            '',
1599
            '',
1600
        ],
1601
        'Ỹ'       => [
1602
            '1',
1603
            '1',
1604
            '',
1605
            '',
1606
        ],
1607
        'Z'       => [
1608
            '0',
1609
            '4',
1610
            '4',
1611
            '4',
1612
        ],
1613
        'Ź'       => [
1614
            '0',
1615
            '4',
1616
            '4',
1617
            '4',
1618
        ],
1619
        'Ż'       => [
1620
            '0',
1621
            '4',
1622
            '4',
1623
            '4',
1624
        ],
1625
        'Ž'       => [
1626
            '0',
1627
            '4',
1628
            '4',
1629
            '4',
1630
        ],
1631
        'ZD'      => [
1632
            '0',
1633
            '2',
1634
            '43',
1635
            '43',
1636
        ],
1637
        'ZDZ'     => [
1638
            '0',
1639
            '2',
1640
            '4',
1641
            '4',
1642
        ],
1643
        'ZDZH'    => [
1644
            '0',
1645
            '2',
1646
            '4',
1647
            '4',
1648
        ],
1649
        'ZH'      => [
1650
            '0',
1651
            '4',
1652
            '4',
1653
            '4',
1654
        ],
1655
        'ZHD'     => [
1656
            '0',
1657
            '2',
1658
            '43',
1659
            '43',
1660
        ],
1661
        'ZHDZH'   => [
1662
            '0',
1663
            '2',
1664
            '4',
1665
            '4',
1666
        ],
1667
        'ZS'      => [
1668
            '0',
1669
            '4',
1670
            '4',
1671
            '4',
1672
        ],
1673
        'ZSCH'    => [
1674
            '0',
1675
            '4',
1676
            '4',
1677
            '4',
1678
        ],
1679
        'ZSH'     => [
1680
            '0',
1681
            '4',
1682
            '4',
1683
            '4',
1684
        ],
1685
        'ZZS'     => [
1686
            '0',
1687
            '4',
1688
            '4',
1689
            '4',
1690
        ],
1691
        // Cyrillic alphabet
1692
        'А'       => [
1693
            '1',
1694
            '0',
1695
            '',
1696
            '',
1697
        ],
1698
        'Б'       => [
1699
            '0',
1700
            '7',
1701
            '7',
1702
            '7',
1703
        ],
1704
        'В'       => [
1705
            '0',
1706
            '7',
1707
            '7',
1708
            '7',
1709
        ],
1710
        'Г'       => [
1711
            '0',
1712
            '5',
1713
            '5',
1714
            '5',
1715
        ],
1716
        'Д'       => [
1717
            '0',
1718
            '3',
1719
            '3',
1720
            '3',
1721
        ],
1722
        'ДЗ'      => [
1723
            '0',
1724
            '4',
1725
            '4',
1726
            '4',
1727
        ],
1728
        'Е'       => [
1729
            '1',
1730
            '0',
1731
            '',
1732
            '',
1733
        ],
1734
        'Ё'       => [
1735
            '1',
1736
            '0',
1737
            '',
1738
            '',
1739
        ],
1740
        'Ж'       => [
1741
            '0',
1742
            '4',
1743
            '4',
1744
            '4',
1745
        ],
1746
        'З'       => [
1747
            '0',
1748
            '4',
1749
            '4',
1750
            '4',
1751
        ],
1752
        'И'       => [
1753
            '1',
1754
            '0',
1755
            '',
1756
            '',
1757
        ],
1758
        'Й'       => [
1759
            '1',
1760
            '1',
1761
            '',
1762
            '',
1763
            '4',
1764
            '4',
1765
            '4',
1766
        ],
1767
        'К'       => [
1768
            '0',
1769
            '5',
1770
            '5',
1771
            '5',
1772
        ],
1773
        'Л'       => [
1774
            '0',
1775
            '8',
1776
            '8',
1777
            '8',
1778
        ],
1779
        'М'       => [
1780
            '0',
1781
            '6',
1782
            '6',
1783
            '6',
1784
        ],
1785
        'Н'       => [
1786
            '0',
1787
            '6',
1788
            '6',
1789
            '6',
1790
        ],
1791
        'О'       => [
1792
            '1',
1793
            '0',
1794
            '',
1795
            '',
1796
        ],
1797
        'П'       => [
1798
            '0',
1799
            '7',
1800
            '7',
1801
            '7',
1802
        ],
1803
        'Р'       => [
1804
            '0',
1805
            '9',
1806
            '9',
1807
            '9',
1808
        ],
1809
        'РЖ'      => [
1810
            '0',
1811
            '4',
1812
            '4',
1813
            '4',
1814
        ],
1815
        'С'       => [
1816
            '0',
1817
            '4',
1818
            '4',
1819
            '4',
1820
        ],
1821
        'Т'       => [
1822
            '0',
1823
            '3',
1824
            '3',
1825
            '3',
1826
        ],
1827
        'У'       => [
1828
            '1',
1829
            '0',
1830
            '',
1831
            '',
1832
        ],
1833
        'Ф'       => [
1834
            '0',
1835
            '7',
1836
            '7',
1837
            '7',
1838
        ],
1839
        'Х'       => [
1840
            '0',
1841
            '5',
1842
            '5',
1843
            '5',
1844
        ],
1845
        'Ц'       => [
1846
            '0',
1847
            '4',
1848
            '4',
1849
            '4',
1850
        ],
1851
        'Ч'       => [
1852
            '0',
1853
            '4',
1854
            '4',
1855
            '4',
1856
        ],
1857
        'Ш'       => [
1858
            '0',
1859
            '4',
1860
            '4',
1861
            '4',
1862
        ],
1863
        'Щ'       => [
1864
            '0',
1865
            '2',
1866
            '4',
1867
            '4',
1868
        ],
1869
        'Ъ'       => [
1870
            '0',
1871
            '',
1872
            '',
1873
            '',
1874
        ],
1875
        'Ы'       => [
1876
            '0',
1877
            '1',
1878
            '',
1879
            '',
1880
        ],
1881
        'Ь'       => [
1882
            '0',
1883
            '',
1884
            '',
1885
            '',
1886
        ],
1887
        'Э'       => [
1888
            '1',
1889
            '0',
1890
            '',
1891
            '',
1892
        ],
1893
        'Ю'       => [
1894
            '0',
1895
            '1',
1896
            '',
1897
            '',
1898
        ],
1899
        'Я'       => [
1900
            '0',
1901
            '1',
1902
            '',
1903
            '',
1904
        ],
1905
        // Greek alphabet
1906
        'Α'       => [
1907
            '1',
1908
            '0',
1909
            '',
1910
            '',
1911
        ],
1912
        'Ά'       => [
1913
            '1',
1914
            '0',
1915
            '',
1916
            '',
1917
        ],
1918
        'ΑΙ'      => [
1919
            '1',
1920
            '0',
1921
            '1',
1922
            '',
1923
        ],
1924
        'ΑΥ'      => [
1925
            '1',
1926
            '0',
1927
            '1',
1928
            '',
1929
        ],
1930
        'Β'       => [
1931
            '0',
1932
            '7',
1933
            '7',
1934
            '7',
1935
        ],
1936
        'Γ'       => [
1937
            '0',
1938
            '5',
1939
            '5',
1940
            '5',
1941
        ],
1942
        'Δ'       => [
1943
            '0',
1944
            '3',
1945
            '3',
1946
            '3',
1947
        ],
1948
        'Ε'       => [
1949
            '1',
1950
            '0',
1951
            '',
1952
            '',
1953
        ],
1954
        'Έ'       => [
1955
            '1',
1956
            '0',
1957
            '',
1958
            '',
1959
        ],
1960
        'ΕΙ'      => [
1961
            '1',
1962
            '0',
1963
            '1',
1964
            '',
1965
        ],
1966
        'ΕΥ'      => [
1967
            '1',
1968
            '1',
1969
            '1',
1970
            '',
1971
        ],
1972
        'Ζ'       => [
1973
            '0',
1974
            '4',
1975
            '4',
1976
            '4',
1977
        ],
1978
        'Η'       => [
1979
            '1',
1980
            '0',
1981
            '',
1982
            '',
1983
        ],
1984
        'Ή'       => [
1985
            '1',
1986
            '0',
1987
            '',
1988
            '',
1989
        ],
1990
        'Θ'       => [
1991
            '0',
1992
            '3',
1993
            '3',
1994
            '3',
1995
        ],
1996
        'Ι'       => [
1997
            '1',
1998
            '0',
1999
            '',
2000
            '',
2001
        ],
2002
        'Ί'       => [
2003
            '1',
2004
            '0',
2005
            '',
2006
            '',
2007
        ],
2008
        'Ϊ'       => [
2009
            '1',
2010
            '0',
2011
            '',
2012
            '',
2013
        ],
2014
        'ΐ'       => [
2015
            '1',
2016
            '0',
2017
            '',
2018
            '',
2019
        ],
2020
        'Κ'       => [
2021
            '0',
2022
            '5',
2023
            '5',
2024
            '5',
2025
        ],
2026
        'Λ'       => [
2027
            '0',
2028
            '8',
2029
            '8',
2030
            '8',
2031
        ],
2032
        'Μ'       => [
2033
            '0',
2034
            '6',
2035
            '6',
2036
            '6',
2037
        ],
2038
        'ΜΠ'      => [
2039
            '0',
2040
            '7',
2041
            '7',
2042
            '7',
2043
        ],
2044
        'Ν'       => [
2045
            '0',
2046
            '6',
2047
            '6',
2048
            '6',
2049
        ],
2050
        'ΝΤ'      => [
2051
            '0',
2052
            '3',
2053
            '3',
2054
            '3',
2055
        ],
2056
        'Ξ'       => [
2057
            '0',
2058
            '5',
2059
            '54',
2060
            '54',
2061
        ],
2062
        'Ο'       => [
2063
            '1',
2064
            '0',
2065
            '',
2066
            '',
2067
        ],
2068
        'Ό'       => [
2069
            '1',
2070
            '0',
2071
            '',
2072
            '',
2073
        ],
2074
        'ΟΙ'      => [
2075
            '1',
2076
            '0',
2077
            '1',
2078
            '',
2079
        ],
2080
        'ΟΥ'      => [
2081
            '1',
2082
            '0',
2083
            '1',
2084
            '',
2085
        ],
2086
        'Π'       => [
2087
            '0',
2088
            '7',
2089
            '7',
2090
            '7',
2091
        ],
2092
        'Ρ'       => [
2093
            '0',
2094
            '9',
2095
            '9',
2096
            '9',
2097
        ],
2098
        'Σ'       => [
2099
            '0',
2100
            '4',
2101
            '4',
2102
            '4',
2103
        ],
2104
        'ς'       => [
2105
            '0',
2106
            '',
2107
            '',
2108
            '4',
2109
        ],
2110
        'Τ'       => [
2111
            '0',
2112
            '3',
2113
            '3',
2114
            '3',
2115
        ],
2116
        'ΤΖ'      => [
2117
            '0',
2118
            '4',
2119
            '4',
2120
            '4',
2121
        ],
2122
        'ΤΣ'      => [
2123
            '0',
2124
            '4',
2125
            '4',
2126
            '4',
2127
        ],
2128
        'Υ'       => [
2129
            '1',
2130
            '1',
2131
            '',
2132
            '',
2133
        ],
2134
        'Ύ'       => [
2135
            '1',
2136
            '1',
2137
            '',
2138
            '',
2139
        ],
2140
        'Ϋ'       => [
2141
            '1',
2142
            '1',
2143
            '',
2144
            '',
2145
        ],
2146
        'ΰ'       => [
2147
            '1',
2148
            '1',
2149
            '',
2150
            '',
2151
        ],
2152
        'ΥΚ'      => [
2153
            '1',
2154
            '5',
2155
            '5',
2156
            '5',
2157
        ],
2158
        'ΥΥ'      => [
2159
            '1',
2160
            '65',
2161
            '65',
2162
            '65',
2163
        ],
2164
        'Φ'       => [
2165
            '0',
2166
            '7',
2167
            '7',
2168
            '7',
2169
        ],
2170
        'Χ'       => [
2171
            '0',
2172
            '5',
2173
            '5',
2174
            '5',
2175
        ],
2176
        'Ψ'       => [
2177
            '0',
2178
            '7',
2179
            '7',
2180
            '7',
2181
        ],
2182
        'Ω'       => [
2183
            '1',
2184
            '0',
2185
            '',
2186
            '',
2187
        ],
2188
        'Ώ'       => [
2189
            '1',
2190
            '0',
2191
            '',
2192
            '',
2193
        ],
2194
        // Hebrew alphabet
2195
        'א'       => [
2196
            '1',
2197
            '0',
2198
            '',
2199
            '',
2200
        ],
2201
        'או'      => [
2202
            '1',
2203
            '0',
2204
            '7',
2205
            '',
2206
        ],
2207
        'אג'      => [
2208
            '1',
2209
            '4',
2210
            '4',
2211
            '4',
2212
            '5',
2213
            '5',
2214
            '5',
2215
            '34',
2216
            '34',
2217
            '34',
2218
        ],
2219
        'בב'      => [
2220
            '0',
2221
            '7',
2222
            '7',
2223
            '7',
2224
            '77',
2225
            '77',
2226
            '77',
2227
        ],
2228
        'ב'       => [
2229
            '0',
2230
            '7',
2231
            '7',
2232
            '7',
2233
        ],
2234
        'גג'      => [
2235
            '0',
2236
            '4',
2237
            '4',
2238
            '4',
2239
            '5',
2240
            '5',
2241
            '5',
2242
            '45',
2243
            '45',
2244
            '45',
2245
            '55',
2246
            '55',
2247
            '55',
2248
            '54',
2249
            '54',
2250
            '54',
2251
        ],
2252
        'גד'      => [
2253
            '0',
2254
            '43',
2255
            '43',
2256
            '43',
2257
            '53',
2258
            '53',
2259
            '53',
2260
        ],
2261
        'גה'      => [
2262
            '0',
2263
            '45',
2264
            '45',
2265
            '45',
2266
            '55',
2267
            '55',
2268
            '55',
2269
        ],
2270
        'גז'      => [
2271
            '0',
2272
            '44',
2273
            '44',
2274
            '44',
2275
            '45',
2276
            '45',
2277
            '45',
2278
        ],
2279
        'גח'      => [
2280
            '0',
2281
            '45',
2282
            '45',
2283
            '45',
2284
            '55',
2285
            '55',
2286
            '55',
2287
        ],
2288
        'גכ'      => [
2289
            '0',
2290
            '45',
2291
            '45',
2292
            '45',
2293
            '55',
2294
            '55',
2295
            '55',
2296
        ],
2297
        'גך'      => [
2298
            '0',
2299
            '45',
2300
            '45',
2301
            '45',
2302
            '55',
2303
            '55',
2304
            '55',
2305
        ],
2306
        'גצ'      => [
2307
            '0',
2308
            '44',
2309
            '44',
2310
            '44',
2311
            '45',
2312
            '45',
2313
            '45',
2314
        ],
2315
        'גץ'      => [
2316
            '0',
2317
            '44',
2318
            '44',
2319
            '44',
2320
            '45',
2321
            '45',
2322
            '45',
2323
        ],
2324
        'גק'      => [
2325
            '0',
2326
            '45',
2327
            '45',
2328
            '45',
2329
            '54',
2330
            '54',
2331
            '54',
2332
        ],
2333
        'גש'      => [
2334
            '0',
2335
            '44',
2336
            '44',
2337
            '44',
2338
            '54',
2339
            '54',
2340
            '54',
2341
        ],
2342
        'גת'      => [
2343
            '0',
2344
            '43',
2345
            '43',
2346
            '43',
2347
            '53',
2348
            '53',
2349
            '53',
2350
        ],
2351
        'ג'       => [
2352
            '0',
2353
            '4',
2354
            '4',
2355
            '4',
2356
            '5',
2357
            '5',
2358
            '5',
2359
        ],
2360
        'דז'      => [
2361
            '0',
2362
            '4',
2363
            '4',
2364
            '4',
2365
        ],
2366
        'דד'      => [
2367
            '0',
2368
            '3',
2369
            '3',
2370
            '3',
2371
            '33',
2372
            '33',
2373
            '33',
2374
        ],
2375
        'דט'      => [
2376
            '0',
2377
            '33',
2378
            '33',
2379
            '33',
2380
        ],
2381
        'דש'      => [
2382
            '0',
2383
            '4',
2384
            '4',
2385
            '4',
2386
        ],
2387
        'דצ'      => [
2388
            '0',
2389
            '4',
2390
            '4',
2391
            '4',
2392
        ],
2393
        'דץ'      => [
2394
            '0',
2395
            '4',
2396
            '4',
2397
            '4',
2398
        ],
2399
        'ד'       => [
2400
            '0',
2401
            '3',
2402
            '3',
2403
            '3',
2404
        ],
2405
        'הג'      => [
2406
            '0',
2407
            '54',
2408
            '54',
2409
            '54',
2410
            '55',
2411
            '55',
2412
            '55',
2413
        ],
2414
        'הכ'      => [
2415
            '0',
2416
            '55',
2417
            '55',
2418
            '55',
2419
        ],
2420
        'הח'      => [
2421
            '0',
2422
            '55',
2423
            '55',
2424
            '55',
2425
        ],
2426
        'הק'      => [
2427
            '0',
2428
            '55',
2429
            '55',
2430
            '55',
2431
            '5',
2432
            '5',
2433
            '5',
2434
        ],
2435
        'הה'      => [
2436
            '0',
2437
            '5',
2438
            '5',
2439
            '',
2440
            '55',
2441
            '55',
2442
            '',
2443
        ],
2444
        'ה'       => [
2445
            '0',
2446
            '5',
2447
            '5',
2448
            '',
2449
        ],
2450
        'וי'      => [
2451
            '1',
2452
            '',
2453
            '',
2454
            '',
2455
            '7',
2456
            '7',
2457
            '7',
2458
        ],
2459
        'ו'       => [
2460
            '1',
2461
            '7',
2462
            '7',
2463
            '7',
2464
            '7',
2465
            '',
2466
            '',
2467
        ],
2468
        'וו'      => [
2469
            '1',
2470
            '7',
2471
            '7',
2472
            '7',
2473
            '7',
2474
            '',
2475
            '',
2476
        ],
2477
        'וופ'     => [
2478
            '1',
2479
            '7',
2480
            '7',
2481
            '7',
2482
            '77',
2483
            '77',
2484
            '77',
2485
        ],
2486
        'זש'      => [
2487
            '0',
2488
            '4',
2489
            '4',
2490
            '4',
2491
            '44',
2492
            '44',
2493
            '44',
2494
        ],
2495
        'זדז'     => [
2496
            '0',
2497
            '2',
2498
            '4',
2499
            '4',
2500
        ],
2501
        'ז'       => [
2502
            '0',
2503
            '4',
2504
            '4',
2505
            '4',
2506
        ],
2507
        'זג'      => [
2508
            '0',
2509
            '44',
2510
            '44',
2511
            '44',
2512
            '45',
2513
            '45',
2514
            '45',
2515
        ],
2516
        'זז'      => [
2517
            '0',
2518
            '4',
2519
            '4',
2520
            '4',
2521
            '44',
2522
            '44',
2523
            '44',
2524
        ],
2525
        'זס'      => [
2526
            '0',
2527
            '44',
2528
            '44',
2529
            '44',
2530
        ],
2531
        'זצ'      => [
2532
            '0',
2533
            '44',
2534
            '44',
2535
            '44',
2536
        ],
2537
        'זץ'      => [
2538
            '0',
2539
            '44',
2540
            '44',
2541
            '44',
2542
        ],
2543
        'חג'      => [
2544
            '0',
2545
            '54',
2546
            '54',
2547
            '54',
2548
            '53',
2549
            '53',
2550
            '53',
2551
        ],
2552
        'חח'      => [
2553
            '0',
2554
            '5',
2555
            '5',
2556
            '5',
2557
            '55',
2558
            '55',
2559
            '55',
2560
        ],
2561
        'חק'      => [
2562
            '0',
2563
            '55',
2564
            '55',
2565
            '55',
2566
            '5',
2567
            '5',
2568
            '5',
2569
        ],
2570
        'חכ'      => [
2571
            '0',
2572
            '45',
2573
            '45',
2574
            '45',
2575
            '55',
2576
            '55',
2577
            '55',
2578
        ],
2579
        'חס'      => [
2580
            '0',
2581
            '5',
2582
            '54',
2583
            '54',
2584
        ],
2585
        'חש'      => [
2586
            '0',
2587
            '5',
2588
            '54',
2589
            '54',
2590
        ],
2591
        'ח'       => [
2592
            '0',
2593
            '5',
2594
            '5',
2595
            '5',
2596
        ],
2597
        'טש'      => [
2598
            '0',
2599
            '4',
2600
            '4',
2601
            '4',
2602
        ],
2603
        'טד'      => [
2604
            '0',
2605
            '33',
2606
            '33',
2607
            '33',
2608
        ],
2609
        'טי'      => [
2610
            '0',
2611
            '3',
2612
            '3',
2613
            '3',
2614
            '4',
2615
            '4',
2616
            '4',
2617
            '3',
2618
            '3',
2619
            '34',
2620
        ],
2621
        'טת'      => [
2622
            '0',
2623
            '33',
2624
            '33',
2625
            '33',
2626
        ],
2627
        'טט'      => [
2628
            '0',
2629
            '3',
2630
            '3',
2631
            '3',
2632
            '33',
2633
            '33',
2634
            '33',
2635
        ],
2636
        'ט'       => [
2637
            '0',
2638
            '3',
2639
            '3',
2640
            '3',
2641
        ],
2642
        'י'       => [
2643
            '1',
2644
            '1',
2645
            '',
2646
            '',
2647
        ],
2648
        'יא'      => [
2649
            '1',
2650
            '1',
2651
            '',
2652
            '',
2653
            '1',
2654
            '1',
2655
            '1',
2656
        ],
2657
        'כג'      => [
2658
            '0',
2659
            '55',
2660
            '55',
2661
            '55',
2662
            '54',
2663
            '54',
2664
            '54',
2665
        ],
2666
        'כש'      => [
2667
            '0',
2668
            '5',
2669
            '54',
2670
            '54',
2671
        ],
2672
        'כס'      => [
2673
            '0',
2674
            '5',
2675
            '54',
2676
            '54',
2677
        ],
2678
        'ככ'      => [
2679
            '0',
2680
            '5',
2681
            '5',
2682
            '5',
2683
            '55',
2684
            '55',
2685
            '55',
2686
        ],
2687
        'כך'      => [
2688
            '0',
2689
            '5',
2690
            '5',
2691
            '5',
2692
            '55',
2693
            '55',
2694
            '55',
2695
        ],
2696
        'כ'       => [
2697
            '0',
2698
            '5',
2699
            '5',
2700
            '5',
2701
        ],
2702
        'כח'      => [
2703
            '0',
2704
            '55',
2705
            '55',
2706
            '55',
2707
            '5',
2708
            '5',
2709
            '5',
2710
        ],
2711
        'ך'       => [
2712
            '0',
2713
            '',
2714
            '5',
2715
            '5',
2716
        ],
2717
        'ל'       => [
2718
            '0',
2719
            '8',
2720
            '8',
2721
            '8',
2722
        ],
2723
        'לל'      => [
2724
            '0',
2725
            '88',
2726
            '88',
2727
            '88',
2728
            '8',
2729
            '8',
2730
            '8',
2731
        ],
2732
        'מנ'      => [
2733
            '0',
2734
            '66',
2735
            '66',
2736
            '66',
2737
        ],
2738
        'מן'      => [
2739
            '0',
2740
            '66',
2741
            '66',
2742
            '66',
2743
        ],
2744
        'ממ'      => [
2745
            '0',
2746
            '6',
2747
            '6',
2748
            '6',
2749
            '66',
2750
            '66',
2751
            '66',
2752
        ],
2753
        'מם'      => [
2754
            '0',
2755
            '6',
2756
            '6',
2757
            '6',
2758
            '66',
2759
            '66',
2760
            '66',
2761
        ],
2762
        'מ'       => [
2763
            '0',
2764
            '6',
2765
            '6',
2766
            '6',
2767
        ],
2768
        'ם'       => [
2769
            '0',
2770
            '',
2771
            '6',
2772
            '6',
2773
        ],
2774
        'נמ'      => [
2775
            '0',
2776
            '66',
2777
            '66',
2778
            '66',
2779
        ],
2780
        'נם'      => [
2781
            '0',
2782
            '66',
2783
            '66',
2784
            '66',
2785
        ],
2786
        'ננ'      => [
2787
            '0',
2788
            '6',
2789
            '6',
2790
            '6',
2791
            '66',
2792
            '66',
2793
            '66',
2794
        ],
2795
        'נן'      => [
2796
            '0',
2797
            '6',
2798
            '6',
2799
            '6',
2800
            '66',
2801
            '66',
2802
            '66',
2803
        ],
2804
        'נ'       => [
2805
            '0',
2806
            '6',
2807
            '6',
2808
            '6',
2809
        ],
2810
        'ן'       => [
2811
            '0',
2812
            '',
2813
            '6',
2814
            '6',
2815
        ],
2816
        'סתש'     => [
2817
            '0',
2818
            '2',
2819
            '4',
2820
            '4',
2821
        ],
2822
        'סתז'     => [
2823
            '0',
2824
            '2',
2825
            '4',
2826
            '4',
2827
        ],
2828
        'סטז'     => [
2829
            '0',
2830
            '2',
2831
            '4',
2832
            '4',
2833
        ],
2834
        'סטש'     => [
2835
            '0',
2836
            '2',
2837
            '4',
2838
            '4',
2839
        ],
2840
        'סצד'     => [
2841
            '0',
2842
            '2',
2843
            '4',
2844
            '4',
2845
        ],
2846
        'סט'      => [
2847
            '0',
2848
            '2',
2849
            '4',
2850
            '4',
2851
            '43',
2852
            '43',
2853
            '43',
2854
        ],
2855
        'סת'      => [
2856
            '0',
2857
            '2',
2858
            '4',
2859
            '4',
2860
            '43',
2861
            '43',
2862
            '43',
2863
        ],
2864
        'סג'      => [
2865
            '0',
2866
            '44',
2867
            '44',
2868
            '44',
2869
            '4',
2870
            '4',
2871
            '4',
2872
        ],
2873
        'סס'      => [
2874
            '0',
2875
            '4',
2876
            '4',
2877
            '4',
2878
            '44',
2879
            '44',
2880
            '44',
2881
        ],
2882
        'סצ'      => [
2883
            '0',
2884
            '44',
2885
            '44',
2886
            '44',
2887
        ],
2888
        'סץ'      => [
2889
            '0',
2890
            '44',
2891
            '44',
2892
            '44',
2893
        ],
2894
        'סז'      => [
2895
            '0',
2896
            '44',
2897
            '44',
2898
            '44',
2899
        ],
2900
        'סש'      => [
2901
            '0',
2902
            '44',
2903
            '44',
2904
            '44',
2905
        ],
2906
        'ס'       => [
2907
            '0',
2908
            '4',
2909
            '4',
2910
            '4',
2911
        ],
2912
        'ע'       => [
2913
            '1',
2914
            '0',
2915
            '',
2916
            '',
2917
        ],
2918
        'פב'      => [
2919
            '0',
2920
            '7',
2921
            '7',
2922
            '7',
2923
            '77',
2924
            '77',
2925
            '77',
2926
        ],
2927
        'פוו'     => [
2928
            '0',
2929
            '7',
2930
            '7',
2931
            '7',
2932
            '77',
2933
            '77',
2934
            '77',
2935
        ],
2936
        'פפ'      => [
2937
            '0',
2938
            '7',
2939
            '7',
2940
            '7',
2941
            '77',
2942
            '77',
2943
            '77',
2944
        ],
2945
        'פף'      => [
2946
            '0',
2947
            '7',
2948
            '7',
2949
            '7',
2950
            '77',
2951
            '77',
2952
            '77',
2953
        ],
2954
        'פ'       => [
2955
            '0',
2956
            '7',
2957
            '7',
2958
            '7',
2959
        ],
2960
        'ף'       => [
2961
            '0',
2962
            '',
2963
            '7',
2964
            '7',
2965
        ],
2966
        'צג'      => [
2967
            '0',
2968
            '44',
2969
            '44',
2970
            '44',
2971
            '45',
2972
            '45',
2973
            '45',
2974
        ],
2975
        'צז'      => [
2976
            '0',
2977
            '44',
2978
            '44',
2979
            '44',
2980
        ],
2981
        'צס'      => [
2982
            '0',
2983
            '44',
2984
            '44',
2985
            '44',
2986
        ],
2987
        'צצ'      => [
2988
            '0',
2989
            '4',
2990
            '4',
2991
            '4',
2992
            '5',
2993
            '5',
2994
            '5',
2995
            '44',
2996
            '44',
2997
            '44',
2998
            '54',
2999
            '54',
3000
            '54',
3001
            '45',
3002
            '45',
3003
            '45',
3004
        ],
3005
        'צץ'      => [
3006
            '0',
3007
            '4',
3008
            '4',
3009
            '4',
3010
            '5',
3011
            '5',
3012
            '5',
3013
            '44',
3014
            '44',
3015
            '44',
3016
            '54',
3017
            '54',
3018
            '54',
3019
        ],
3020
        'צש'      => [
3021
            '0',
3022
            '44',
3023
            '44',
3024
            '44',
3025
            '4',
3026
            '4',
3027
            '4',
3028
            '5',
3029
            '5',
3030
            '5',
3031
        ],
3032
        'צ'       => [
3033
            '0',
3034
            '4',
3035
            '4',
3036
            '4',
3037
            '5',
3038
            '5',
3039
            '5',
3040
        ],
3041
        'ץ'       => [
3042
            '0',
3043
            '',
3044
            '4',
3045
            '4',
3046
        ],
3047
        'קה'      => [
3048
            '0',
3049
            '55',
3050
            '55',
3051
            '5',
3052
        ],
3053
        'קס'      => [
3054
            '0',
3055
            '5',
3056
            '54',
3057
            '54',
3058
        ],
3059
        'קש'      => [
3060
            '0',
3061
            '5',
3062
            '54',
3063
            '54',
3064
        ],
3065
        'קק'      => [
3066
            '0',
3067
            '5',
3068
            '5',
3069
            '5',
3070
            '55',
3071
            '55',
3072
            '55',
3073
        ],
3074
        'קח'      => [
3075
            '0',
3076
            '55',
3077
            '55',
3078
            '55',
3079
        ],
3080
        'קכ'      => [
3081
            '0',
3082
            '55',
3083
            '55',
3084
            '55',
3085
        ],
3086
        'קך'      => [
3087
            '0',
3088
            '55',
3089
            '55',
3090
            '55',
3091
        ],
3092
        'קג'      => [
3093
            '0',
3094
            '55',
3095
            '55',
3096
            '55',
3097
            '54',
3098
            '54',
3099
            '54',
3100
        ],
3101
        'ק'       => [
3102
            '0',
3103
            '5',
3104
            '5',
3105
            '5',
3106
        ],
3107
        'רר'      => [
3108
            '0',
3109
            '99',
3110
            '99',
3111
            '99',
3112
            '9',
3113
            '9',
3114
            '9',
3115
        ],
3116
        'ר'       => [
3117
            '0',
3118
            '9',
3119
            '9',
3120
            '9',
3121
        ],
3122
        'שטז'     => [
3123
            '0',
3124
            '2',
3125
            '4',
3126
            '4',
3127
        ],
3128
        'שתש'     => [
3129
            '0',
3130
            '2',
3131
            '4',
3132
            '4',
3133
        ],
3134
        'שתז'     => [
3135
            '0',
3136
            '2',
3137
            '4',
3138
            '4',
3139
        ],
3140
        'שטש'     => [
3141
            '0',
3142
            '2',
3143
            '4',
3144
            '4',
3145
        ],
3146
        'שד'      => [
3147
            '0',
3148
            '2',
3149
            '43',
3150
            '43',
3151
        ],
3152
        'שז'      => [
3153
            '0',
3154
            '44',
3155
            '44',
3156
            '44',
3157
        ],
3158
        'שס'      => [
3159
            '0',
3160
            '44',
3161
            '44',
3162
            '44',
3163
        ],
3164
        'שת'      => [
3165
            '0',
3166
            '2',
3167
            '43',
3168
            '43',
3169
        ],
3170
        'שג'      => [
3171
            '0',
3172
            '4',
3173
            '4',
3174
            '4',
3175
            '44',
3176
            '44',
3177
            '44',
3178
            '4',
3179
            '43',
3180
            '43',
3181
        ],
3182
        'שט'      => [
3183
            '0',
3184
            '2',
3185
            '43',
3186
            '43',
3187
            '44',
3188
            '44',
3189
            '44',
3190
        ],
3191
        'שצ'      => [
3192
            '0',
3193
            '44',
3194
            '44',
3195
            '44',
3196
            '45',
3197
            '45',
3198
            '45',
3199
        ],
3200
        'שץ'      => [
3201
            '0',
3202
            '44',
3203
            '',
3204
            '44',
3205
            '45',
3206
            '',
3207
            '45',
3208
        ],
3209
        'שש'      => [
3210
            '0',
3211
            '4',
3212
            '4',
3213
            '4',
3214
            '44',
3215
            '44',
3216
            '44',
3217
        ],
3218
        'ש'       => [
3219
            '0',
3220
            '4',
3221
            '4',
3222
            '4',
3223
        ],
3224
        'תג'      => [
3225
            '0',
3226
            '34',
3227
            '34',
3228
            '34',
3229
        ],
3230
        'תז'      => [
3231
            '0',
3232
            '34',
3233
            '34',
3234
            '34',
3235
        ],
3236
        'תש'      => [
3237
            '0',
3238
            '4',
3239
            '4',
3240
            '4',
3241
        ],
3242
        'תת'      => [
3243
            '0',
3244
            '3',
3245
            '3',
3246
            '3',
3247
            '4',
3248
            '4',
3249
            '4',
3250
            '33',
3251
            '33',
3252
            '33',
3253
            '44',
3254
            '44',
3255
            '44',
3256
            '34',
3257
            '34',
3258
            '34',
3259
            '43',
3260
            '43',
3261
            '43',
3262
        ],
3263
        'ת'       => [
3264
            '0',
3265
            '3',
3266
            '3',
3267
            '3',
3268
            '4',
3269
            '4',
3270
            '4',
3271
        ],
3272
        // Arabic alphabet
3273
        'ا'       => [
3274
            '1',
3275
            '0',
3276
            '',
3277
            '',
3278
        ],
3279
        'ب'       => [
3280
            '0',
3281
            '7',
3282
            '7',
3283
            '7',
3284
        ],
3285
        'ت'       => [
3286
            '0',
3287
            '3',
3288
            '3',
3289
            '3',
3290
        ],
3291
        'ث'       => [
3292
            '0',
3293
            '3',
3294
            '3',
3295
            '3',
3296
        ],
3297
        'ج'       => [
3298
            '0',
3299
            '4',
3300
            '4',
3301
            '4',
3302
        ],
3303
        'ح'       => [
3304
            '0',
3305
            '5',
3306
            '5',
3307
            '5',
3308
        ],
3309
        'خ'       => [
3310
            '0',
3311
            '5',
3312
            '5',
3313
            '5',
3314
        ],
3315
        'د'       => [
3316
            '0',
3317
            '3',
3318
            '3',
3319
            '3',
3320
        ],
3321
        'ذ'       => [
3322
            '0',
3323
            '3',
3324
            '3',
3325
            '3',
3326
        ],
3327
        'ر'       => [
3328
            '0',
3329
            '9',
3330
            '9',
3331
            '9',
3332
        ],
3333
        'ز'       => [
3334
            '0',
3335
            '4',
3336
            '4',
3337
            '4',
3338
        ],
3339
        'س'       => [
3340
            '0',
3341
            '4',
3342
            '4',
3343
            '4',
3344
        ],
3345
        'ش'       => [
3346
            '0',
3347
            '4',
3348
            '4',
3349
            '4',
3350
        ],
3351
        'ص'       => [
3352
            '0',
3353
            '4',
3354
            '4',
3355
            '4',
3356
        ],
3357
        'ض'       => [
3358
            '0',
3359
            '3',
3360
            '3',
3361
            '3',
3362
        ],
3363
        'ط'       => [
3364
            '0',
3365
            '3',
3366
            '3',
3367
            '3',
3368
        ],
3369
        'ظ'       => [
3370
            '0',
3371
            '4',
3372
            '4',
3373
            '4',
3374
        ],
3375
        'ع'       => [
3376
            '1',
3377
            '0',
3378
            '',
3379
            '',
3380
        ],
3381
        'غ'       => [
3382
            '0',
3383
            '0',
3384
            '',
3385
            '',
3386
        ],
3387
        'ف'       => [
3388
            '0',
3389
            '7',
3390
            '7',
3391
            '7',
3392
        ],
3393
        'ق'       => [
3394
            '0',
3395
            '5',
3396
            '5',
3397
            '5',
3398
        ],
3399
        'ك'       => [
3400
            '0',
3401
            '5',
3402
            '5',
3403
            '5',
3404
        ],
3405
        'ل'       => [
3406
            '0',
3407
            '8',
3408
            '8',
3409
            '8',
3410
        ],
3411
        'لا'      => [
3412
            '0',
3413
            '8',
3414
            '8',
3415
            '8',
3416
        ],
3417
        'م'       => [
3418
            '0',
3419
            '6',
3420
            '6',
3421
            '6',
3422
        ],
3423
        'ن'       => [
3424
            '0',
3425
            '6',
3426
            '6',
3427
            '6',
3428
        ],
3429
        'هن'      => [
3430
            '0',
3431
            '66',
3432
            '66',
3433
            '66',
3434
        ],
3435
        'ه'       => [
3436
            '0',
3437
            '5',
3438
            '5',
3439
            '',
3440
        ],
3441
        'و'       => [
3442
            '1',
3443
            '',
3444
            '',
3445
            '',
3446
            '7',
3447
            '',
3448
            '',
3449
        ],
3450
        'ي'       => [
3451
            '0',
3452
            '1',
3453
            '',
3454
            '',
3455
        ],
3456
        'آ'       => [
3457
            '0',
3458
            '1',
3459
            '',
3460
            '',
3461
        ],
3462
        'ة'       => [
3463
            '0',
3464
            '',
3465
            '',
3466
            '3',
3467
        ],
3468
        'ی'       => [
3469
            '0',
3470
            '1',
3471
            '',
3472
            '',
3473
        ],
3474
        'ى'       => [
3475
            '1',
3476
            '1',
3477
            '',
3478
            '',
3479
        ],
3480
    ];
3481
3482
    /**
3483
     * Which algorithms are supported.
3484
     *
3485
     * @return array<string>
3486
     */
3487
    public static function getAlgorithms(): array
3488
    {
3489
        return [
3490
            /* I18N: https://en.wikipedia.org/wiki/Soundex */
3491
            'std' => I18N::translate('Russell'),
3492
            /* I18N: https://en.wikipedia.org/wiki/Daitch–Mokotoff_Soundex */
3493
            'dm'  => I18N::translate('Daitch-Mokotoff'),
3494
        ];
3495
    }
3496
3497
    /**
3498
     * Is there a match between two soundex codes?
3499
     *
3500
     * @param string $soundex1
3501
     * @param string $soundex2
3502
     *
3503
     * @return bool
3504
     */
3505
    public static function compare(string $soundex1, string $soundex2): bool
3506
    {
3507
        if ($soundex1 !== '' && $soundex2 !== '') {
3508
            return array_intersect(explode(':', $soundex1), explode(':', $soundex2)) !== [];
3509
        }
3510
3511
        return false;
3512
    }
3513
3514
    /**
3515
     * Generate Russell soundex codes for a given text.
3516
     *
3517
     * @param string $text
3518
     *
3519
     * @return string
3520
     */
3521
    public static function russell(string $text): string
3522
    {
3523
        $words         = explode(' ', $text);
3524
        $soundex_array = [];
3525
3526
        foreach ($words as $word) {
3527
            $soundex = soundex($word);
3528
3529
            // Only return codes from recognisable sounds
3530
            if ($soundex !== '0000') {
3531
                $soundex_array[] = $soundex;
3532
            }
3533
        }
3534
3535
        // Combine words, e.g. “New York” as “Newyork”
3536
        if (count($words) > 1) {
3537
            $soundex_array[] = soundex(str_replace(' ', '', $text));
3538
        }
3539
3540
        // A varchar(255) column can only hold 51 4-character codes (plus 50 delimiters)
3541
        $soundex_array = array_slice(array_unique($soundex_array), 0, 51);
3542
3543
        return implode(':', $soundex_array);
3544
    }
3545
3546
    /**
3547
     * Generate Daitch–Mokotoff soundex codes for a given text.
3548
     *
3549
     * @param string $text
3550
     *
3551
     * @return string
3552
     */
3553
    public static function daitchMokotoff(string $text): string
3554
    {
3555
        $words         = explode(' ', $text);
3556
        $soundex_array = [];
3557
3558
        foreach ($words as $word) {
3559
            $soundex_array = array_merge($soundex_array, self::daitchMokotoffWord($word));
3560
        }
3561
        // Combine words, e.g. “New York” as “Newyork”
3562
        if (count($words) > 1) {
3563
            $soundex_array = array_merge($soundex_array, self::daitchMokotoffWord(str_replace(' ', '', $text)));
3564
        }
3565
3566
        // A varchar(255) column can only hold 36 6-character codes (plus 35 delimiters)
3567
        $soundex_array = array_slice(array_unique($soundex_array), 0, 36);
3568
3569
        return implode(':', $soundex_array);
3570
    }
3571
3572
    /**
3573
     * Calculate the Daitch-Mokotoff soundex for a word.
3574
     *
3575
     * @param string $name
3576
     *
3577
     * @return array<string> List of possible DM codes for the word.
3578
     */
3579
    private static function daitchMokotoffWord(string $name): array
3580
    {
3581
        // Apply special transformation rules to the input string
3582
        $name = I18N::strtoupper($name);
3583
        foreach (self::TRANSFORM_NAMES as $transformRule) {
3584
            $name = str_replace($transformRule[0], $transformRule[1], $name);
3585
        }
3586
3587
        // Initialize
3588
        $name_script = I18N::textScript($name);
3589
        $noVowels    = $name_script === 'Hebr' || $name_script === 'Arab';
3590
3591
        $lastPos         = strlen($name) - 1;
3592
        $currPos         = 0;
3593
        $state           = 1; // 1: start of input string, 2: before vowel, 3: other
3594
        $result          = []; // accumulate complete 6-digit D-M codes here
3595
        $partialResult   = []; // accumulate incomplete D-M codes here
3596
        $partialResult[] = ['!']; // initialize 1st partial result  ('!' stops "duplicate sound" check)
3597
3598
        // Loop through the input string.
3599
        // Stop when the string is exhausted or when no more partial results remain
3600
        while (count($partialResult) !== 0 && $currPos <= $lastPos) {
3601
            // Find the DM coding table entry for the chunk at the current position
3602
            $thisEntry = substr($name, $currPos, self::MAXCHAR); // Get maximum length chunk
3603
            while ($thisEntry !== '') {
3604
                if (isset(self::DM_SOUNDS[$thisEntry])) {
3605
                    break;
3606
                }
3607
                $thisEntry = substr($thisEntry, 0, -1); // Not in table: try a shorter chunk
3608
            }
3609
            if ($thisEntry === '') {
3610
                $currPos++; // Not in table: advance pointer to next byte
3611
                continue; // and try again
3612
            }
3613
3614
            $soundTableEntry = self::DM_SOUNDS[$thisEntry];
3615
            $workingResult   = $partialResult;
3616
            $partialResult   = [];
3617
            $currPos += strlen($thisEntry);
3618
3619
            // Not at beginning of input string
3620
            if ($state !== 1) {
3621
                if ($currPos <= $lastPos) {
3622
                    // Determine whether the next chunk is a vowel
3623
                    $nextEntry = substr($name, $currPos, self::MAXCHAR); // Get maximum length chunk
3624
                    while ($nextEntry !== '') {
3625
                        if (isset(self::DM_SOUNDS[$nextEntry])) {
3626
                            break;
3627
                        }
3628
                        $nextEntry = substr($nextEntry, 0, -1); // Not in table: try a shorter chunk
3629
                    }
3630
                } else {
3631
                    $nextEntry = '';
3632
                }
3633
                if ($nextEntry !== '' && self::DM_SOUNDS[$nextEntry][0] !== '0') {
3634
                    $state = 2;
3635
                } else {
3636
                    // Next chunk is a vowel
3637
                    $state = 3;
3638
                }
3639
            }
3640
3641
            while ($state < count($soundTableEntry)) {
3642
                // empty means 'ignore this sound in this state'
3643
                if ($soundTableEntry[$state] === '') {
3644
                    foreach ($workingResult as $workingEntry) {
3645
                        $tempEntry                        = $workingEntry;
3646
                        $tempEntry[count($tempEntry) - 1] .= '!'; // Prevent false 'doubles'
3647
                        $partialResult[]                  = $tempEntry;
3648
                    }
3649
                } else {
3650
                    foreach ($workingResult as $workingEntry) {
3651
                        if ($soundTableEntry[$state] !== $workingEntry[count($workingEntry) - 1]) {
3652
                            // Incoming sound isn't a duplicate of the previous sound
3653
                            $workingEntry[] = $soundTableEntry[$state];
3654
                        } elseif ($noVowels) {
3655
                            // Incoming sound is a duplicate of the previous sound
3656
                            // For Hebrew and Arabic, we need to create a pair of D-M sound codes,
3657
                            // one of the pair with only a single occurrence of the duplicate sound,
3658
                            // the other with both occurrences
3659
                            $workingEntry[] = $soundTableEntry[$state];
3660
                        }
3661
3662
                        if (count($workingEntry) < 7) {
3663
                            $partialResult[] = $workingEntry;
3664
                        } else {
3665
                            // This is the 6th code in the sequence
3666
                            // We're looking for 7 entries because the first is '!' and doesn't count
3667
                            $tempResult = str_replace('!', '', implode('', $workingEntry));
3668
                            // Only return codes from recognisable sounds
3669
                            if ($tempResult) {
3670
                                $result[] = substr($tempResult . '000000', 0, 6);
3671
                            }
3672
                        }
3673
                    }
3674
                }
3675
                $state += 3; // Advance to next triplet while keeping the same basic state
3676
            }
3677
        }
3678
3679
        // Zero-fill and copy all remaining partial results
3680
        foreach ($partialResult as $workingEntry) {
3681
            $tempResult = str_replace('!', '', implode('', $workingEntry));
3682
            // Only return codes from recognisable sounds
3683
            if ($tempResult) {
3684
                $result[] = substr($tempResult . '000000', 0, 6);
3685
            }
3686
        }
3687
3688
        return $result;
3689
    }
3690
}
3691