This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
c2745edae58846fe7e881899bcf6c3f844fd9828
[perl5.git] / dist / Module-CoreList / lib / Module / CoreList / Utils.pm
1 package Module::CoreList::Utils;
2
3 use strict;
4 use warnings;
5 use vars qw[$VERSION %utilities];
6 use Module::CoreList;
7 use Module::CoreList::TieHashDelta;
8
9 $VERSION = '5.20150920';
10
11 sub utilities {
12     my $perl = shift;
13     $perl = shift if eval { $perl->isa(__PACKAGE__) };
14     return unless $perl or exists $utilities{$perl};
15     return sort keys %{ $utilities{$perl} };
16 }
17
18 sub _released_order {   # Sort helper, to make '?' sort after everything else
19     (substr($Module::CoreList::released{$a}, 0, 1) eq "?")
20     ? ((substr($Module::CoreList::released{$b}, 0, 1) eq "?")
21         ? 0
22         : 1)
23     : ((substr($Module::CoreList::released{$b}, 0, 1) eq "?")
24         ? -1
25         : $Module::CoreList::released{$a} cmp $Module::CoreList::released{$b} )
26 }
27
28 sub first_release_raw {
29     my $util = shift;
30     $util = shift if eval { $util->isa(__PACKAGE__) };
31       #and scalar @_ and $_[0] =~ m#\A[a-zA-Z_][0-9a-zA-Z_]*(?:(::|')[0-9a-zA-Z_]+)*\z#;
32     my $version = shift;
33
34     my @perls = $version
35         ? grep { exists $utilities{$_}{ $util } &&
36                         $utilities{$_}{ $util } ge $version } keys %utilities
37         : grep { exists $utilities{$_}{ $util }             } keys %utilities;
38
39     return grep { exists $Module::CoreList::released{$_} } @perls;
40 }
41
42 sub first_release_by_date {
43     my @perls = &first_release_raw;
44     return unless @perls;
45     return (sort _released_order @perls)[0];
46 }
47
48 sub first_release {
49     my @perls = &first_release_raw;
50     return unless @perls;
51     return (sort { $a cmp $b } @perls)[0];
52 }
53
54 sub removed_from {
55   my @perls = &removed_raw;
56   return shift @perls;
57 }
58
59 sub removed_from_by_date {
60   my @perls = sort _released_order &removed_raw;
61   return shift @perls;
62 }
63
64 sub removed_raw {
65   my $util = shift;
66   $util = shift if eval { $util->isa(__PACKAGE__) };
67   return unless my @perls = sort { $a cmp $b } first_release_raw($util);
68   @perls = grep { exists $Module::CoreList::released{$_} } @perls;
69   my $last = pop @perls;
70   my @removed = grep { $_ > $last } sort { $a cmp $b } keys %utilities;
71   return @removed;
72 }
73
74 my %delta = (
75     5 => {
76         changed => {
77             'a2p'                   => '1',
78             'c2ph'                  => '1',
79             'cppstdin'              => '1',
80             'find2perl'             => '1',
81             'pstruct'               => '1',
82             's2p'                   => '1',
83         },
84         removed => {
85         }
86     },
87
88     5.001 => {
89         delta_from => 5,
90         changed => {
91             'h2xs'                  => '1',
92         },
93         removed => {
94         }
95     },
96
97     5.002 => {
98         delta_from => 5.001,
99         changed => {
100             'h2ph'                  => '1',
101             'perlbug'               => '1',
102             'perldoc'               => '1',
103             'pod2html'              => '1',
104             'pod2latex'             => '1',
105             'pod2man'               => '1',
106             'pod2text'              => '1',
107         },
108         removed => {
109         }
110     },
111
112     5.00307 => {
113         delta_from => 5.002,
114         changed => {
115             'pl2pm'                 => '1',
116         },
117         removed => {
118            'cppstdin'              => 1,
119            'pstruct'               => 1,
120         }
121     },
122
123     5.004 => {
124         delta_from => 5.00307,
125         changed => {
126             'splain'                => '1',
127         },
128         removed => {
129         }
130     },
131
132     5.005 => {
133         delta_from => 5.00405,
134         changed => {
135             'perlcc'                => '1',
136         },
137         removed => {
138         }
139     },
140
141     5.00503 => {
142         delta_from => 5.005,
143         changed => {
144         },
145         removed => {
146         }
147     },
148
149     5.00405 => {
150         delta_from => 5.004,
151         changed => {
152         },
153         removed => {
154         }
155     },
156
157     5.006 => {
158         delta_from => 5.00504,
159         changed => {
160             'dprofpp'               => '1',
161             'pod2usage'             => '1',
162             'podchecker'            => '1',
163             'podselect'             => '1',
164             'pstruct'               => '1',
165         },
166         removed => {
167         }
168     },
169
170     5.006001 => {
171         delta_from => 5.006,
172         changed => {
173         },
174         removed => {
175         }
176     },
177
178     5.007003 => {
179         delta_from => 5.006002,
180         changed => {
181             'libnetcfg'             => '1',
182             'perlivp'               => '1',
183             'psed'                  => '1',
184             'xsubpp'                => '1',
185         },
186         removed => {
187         }
188     },
189
190     5.008 => {
191         delta_from => 5.007003,
192         changed => {
193             'enc2xs'                => '1',
194             'piconv'                => '1',
195         },
196         removed => {
197         }
198     },
199
200     5.008001 => {
201         delta_from => 5.008,
202         changed => {
203             'cpan'                  => '1',
204         },
205         removed => {
206         }
207     },
208
209     5.009 => {
210         delta_from => 5.008009,
211         changed => {
212         },
213         removed => {
214            'corelist'              => 1,
215            'instmodsh'             => 1,
216            'prove'                 => 1,
217         }
218     },
219
220     5.008002 => {
221         delta_from => 5.008001,
222         changed => {
223         },
224         removed => {
225         }
226     },
227
228     5.006002 => {
229         delta_from => 5.006001,
230         changed => {
231         },
232         removed => {
233         }
234     },
235
236     5.008003 => {
237         delta_from => 5.008002,
238         changed => {
239             'instmodsh'             => '1',
240             'prove'                 => '1',
241         },
242         removed => {
243         }
244     },
245
246     5.00504 => {
247         delta_from => 5.00503,
248         changed => {
249         },
250         removed => {
251         }
252     },
253
254     5.009001 => {
255         delta_from => 5.009,
256         changed => {
257             'instmodsh'             => '1',
258             'prove'                 => '1',
259         },
260         removed => {
261         }
262     },
263
264     5.008004 => {
265         delta_from => 5.008003,
266         changed => {
267         },
268         removed => {
269         }
270     },
271
272     5.008005 => {
273         delta_from => 5.008004,
274         changed => {
275         },
276         removed => {
277         }
278     },
279
280     5.008006 => {
281         delta_from => 5.008005,
282         changed => {
283         },
284         removed => {
285         }
286     },
287
288     5.009002 => {
289         delta_from => 5.009001,
290         changed => {
291             'corelist'              => '1',
292         },
293         removed => {
294         }
295     },
296
297     5.008007 => {
298         delta_from => 5.008006,
299         changed => {
300         },
301         removed => {
302         }
303     },
304
305     5.009003 => {
306         delta_from => 5.009002,
307         changed => {
308             'ptar'                  => '1',
309             'ptardiff'              => '1',
310             'shasum'                => '1',
311         },
312         removed => {
313         }
314     },
315
316     5.008008 => {
317         delta_from => 5.008007,
318         changed => {
319         },
320         removed => {
321         }
322     },
323
324     5.009004 => {
325         delta_from => 5.009003,
326         changed => {
327             'config_data'           => '1',
328         },
329         removed => {
330         }
331     },
332
333     5.009005 => {
334         delta_from => 5.009004,
335         changed => {
336             'cpan2dist'             => '1',
337             'cpanp'                 => '1',
338             'cpanp-run-perl'        => '1',
339         },
340         removed => {
341            'perlcc'                => 1,
342         }
343     },
344
345     5.010000 => {
346         delta_from => 5.009005,
347         changed => {
348         },
349         removed => {
350         }
351     },
352
353     5.008009 => {
354         delta_from => 5.008008,
355         changed => {
356             'corelist'              => '1',
357         },
358         removed => {
359         }
360     },
361
362     5.010001 => {
363         delta_from => 5.010000,
364         changed => {
365         },
366         removed => {
367         }
368     },
369
370     5.011 => {
371         delta_from => 5.010001,
372         changed => {
373         },
374         removed => {
375         }
376     },
377
378     5.011001 => {
379         delta_from => 5.011,
380         changed => {
381         },
382         removed => {
383         }
384     },
385
386     5.011002 => {
387         delta_from => 5.011001,
388         changed => {
389             'perlthanks'            => '1',
390         },
391         removed => {
392         }
393     },
394
395     5.011003 => {
396         delta_from => 5.011002,
397         changed => {
398         },
399         removed => {
400         }
401     },
402
403     5.011004 => {
404         delta_from => 5.011003,
405         changed => {
406         },
407         removed => {
408         }
409     },
410
411     5.011005 => {
412         delta_from => 5.011004,
413         changed => {
414         },
415         removed => {
416         }
417     },
418
419     5.012 => {
420         delta_from => 5.011005,
421         changed => {
422         },
423         removed => {
424         }
425     },
426
427     5.013 => {
428         delta_from => 5.012005,
429         changed => {
430         },
431         removed => {
432         }
433     },
434
435     5.012001 => {
436         delta_from => 5.012,
437         changed => {
438         },
439         removed => {
440         }
441     },
442
443     5.013001 => {
444         delta_from => 5.013,
445         changed => {
446         },
447         removed => {
448         }
449     },
450
451     5.013002 => {
452         delta_from => 5.013001,
453         changed => {
454         },
455         removed => {
456         }
457     },
458
459     5.013003 => {
460         delta_from => 5.013002,
461         changed => {
462         },
463         removed => {
464         }
465     },
466
467     5.013004 => {
468         delta_from => 5.013003,
469         changed => {
470         },
471         removed => {
472         }
473     },
474
475     5.012002 => {
476         delta_from => 5.012001,
477         changed => {
478         },
479         removed => {
480         }
481     },
482
483     5.013005 => {
484         delta_from => 5.013004,
485         changed => {
486         },
487         removed => {
488         }
489     },
490
491     5.013006 => {
492         delta_from => 5.013005,
493         changed => {
494         },
495         removed => {
496         }
497     },
498
499     5.013007 => {
500         delta_from => 5.013006,
501         changed => {
502             'ptargrep'              => '1',
503         },
504         removed => {
505         }
506     },
507
508     5.013008 => {
509         delta_from => 5.013007,
510         changed => {
511         },
512         removed => {
513         }
514     },
515
516     5.013009 => {
517         delta_from => 5.013008,
518         changed => {
519             'json_pp'               => '1',
520         },
521         removed => {
522         }
523     },
524
525     5.012003 => {
526         delta_from => 5.012002,
527         changed => {
528         },
529         removed => {
530         }
531     },
532
533     5.013010 => {
534         delta_from => 5.013009,
535         changed => {
536         },
537         removed => {
538         }
539     },
540
541     5.013011 => {
542         delta_from => 5.013010,
543         changed => {
544         },
545         removed => {
546         }
547     },
548
549     5.014 => {
550         delta_from => 5.013011,
551         changed => {
552         },
553         removed => {
554         }
555     },
556
557     5.014001 => {
558         delta_from => 5.014,
559         changed => {
560         },
561         removed => {
562         }
563     },
564
565     5.015 => {
566         delta_from => 5.014004,
567         changed => {
568         },
569         removed => {
570            'dprofpp'               => 1,
571         }
572     },
573
574     5.012004 => {
575         delta_from => 5.012003,
576         changed => {
577         },
578         removed => {
579         }
580     },
581
582     5.015001 => {
583         delta_from => 5.015,
584         changed => {
585         },
586         removed => {
587         }
588     },
589
590     5.015002 => {
591         delta_from => 5.015001,
592         changed => {
593         },
594         removed => {
595         }
596     },
597
598     5.015003 => {
599         delta_from => 5.015002,
600         changed => {
601         },
602         removed => {
603         }
604     },
605
606     5.014002 => {
607         delta_from => 5.014001,
608         changed => {
609         },
610         removed => {
611         }
612     },
613
614     5.015004 => {
615         delta_from => 5.015003,
616         changed => {
617         },
618         removed => {
619         }
620     },
621
622     5.015005 => {
623         delta_from => 5.015004,
624         changed => {
625         },
626         removed => {
627         }
628     },
629
630     5.015006 => {
631         delta_from => 5.015005,
632         changed => {
633             'zipdetails'            => '1',
634         },
635         removed => {
636         }
637     },
638
639     5.015007 => {
640         delta_from => 5.015006,
641         changed => {
642         },
643         removed => {
644         }
645     },
646
647     5.015008 => {
648         delta_from => 5.015007,
649         changed => {
650         },
651         removed => {
652         }
653     },
654
655     5.015009 => {
656         delta_from => 5.015008,
657         changed => {
658         },
659         removed => {
660         }
661     },
662
663     5.016 => {
664         delta_from => 5.015009,
665         changed => {
666         },
667         removed => {
668         }
669     },
670
671     5.017 => {
672         delta_from => 5.016003,
673         changed => {
674         },
675         removed => {
676         }
677     },
678
679     5.017001 => {
680         delta_from => 5.017,
681         changed => {
682         },
683         removed => {
684         }
685     },
686
687     5.017002 => {
688         delta_from => 5.017001,
689         changed => {
690         },
691         removed => {
692         }
693     },
694
695     5.016001 => {
696         delta_from => 5.016,
697         changed => {
698         },
699         removed => {
700         }
701     },
702
703     5.017003 => {
704         delta_from => 5.017002,
705         changed => {
706         },
707         removed => {
708         }
709     },
710
711     5.017004 => {
712         delta_from => 5.017003,
713         changed => {
714         },
715         removed => {
716         }
717     },
718
719     5.014003 => {
720         delta_from => 5.014002,
721         changed => {
722         },
723         removed => {
724         }
725     },
726
727     5.017005 => {
728         delta_from => 5.017004,
729         changed => {
730         },
731         removed => {
732         }
733     },
734
735     5.016002 => {
736         delta_from => 5.016001,
737         changed => {
738         },
739         removed => {
740         }
741     },
742
743     5.012005 => {
744         delta_from => 5.012004,
745         changed => {
746         },
747         removed => {
748         }
749     },
750
751     5.017006 => {
752         delta_from => 5.017005,
753         changed => {
754         },
755         removed => {
756         }
757     },
758
759     5.017007 => {
760         delta_from => 5.017006,
761         changed => {
762         },
763         removed => {
764         }
765     },
766
767     5.017008 => {
768         delta_from => 5.017007,
769         changed => {
770         },
771         removed => {
772         }
773     },
774
775     5.017009 => {
776         delta_from => 5.017008,
777         changed => {
778         },
779         removed => {
780         }
781     },
782
783     5.014004 => {
784         delta_from => 5.014003,
785         changed => {
786         },
787         removed => {
788         }
789     },
790
791     5.016003 => {
792         delta_from => 5.016002,
793         changed => {
794         },
795         removed => {
796         }
797     },
798
799     5.017010 => {
800         delta_from => 5.017009,
801         changed => {
802         },
803         removed => {
804         }
805     },
806
807     5.017011 => {
808         delta_from => 5.017010,
809         changed => {
810         },
811         removed => {
812         }
813     },
814     5.018000 => {
815         delta_from => 5.017011,
816         changed => {
817         },
818         removed => {
819         }
820     },
821     5.018001 => {
822         delta_from => 5.018000,
823         changed => {
824         },
825         removed => {
826         }
827     },
828     5.018002 => {
829         delta_from => 5.018001,
830         changed => {
831         },
832         removed => {
833         }
834     },
835     5.018003 => {
836         delta_from => 5.018000,
837         changed => {
838         },
839         removed => {
840         }
841     },
842     5.018004 => {
843         delta_from => 5.018000,
844         changed => {
845         },
846         removed => {
847         }
848     },
849     5.019000 => {
850         delta_from => 5.018000,
851         changed => {
852         },
853         removed => {
854             'cpan2dist'             => '1',
855             'cpanp'                 => '1',
856             'cpanp-run-perl'        => '1',
857             'pod2latex'             => '1',
858         }
859     },
860     5.019001 => {
861         delta_from => 5.019000,
862         changed => {
863         },
864         removed => {
865         }
866     },
867     5.019002 => {
868         delta_from => 5.019001,
869         changed => {
870         },
871         removed => {
872         }
873     },
874     5.019003 => {
875         delta_from => 5.019002,
876         changed => {
877         },
878         removed => {
879         }
880     },
881     5.019004 => {
882         delta_from => 5.019003,
883         changed => {
884         },
885         removed => {
886         }
887     },
888     5.019005 => {
889         delta_from => 5.019004,
890         changed => {
891         },
892         removed => {
893         }
894     },
895     5.019006 => {
896         delta_from => 5.019005,
897         changed => {
898         },
899         removed => {
900         }
901     },
902     5.019007 => {
903         delta_from => 5.019006,
904         changed => {
905         },
906         removed => {
907         }
908     },
909     5.019008 => {
910         delta_from => 5.019007,
911         changed => {
912         },
913         removed => {
914         }
915     },
916     5.019009 => {
917         delta_from => 5.019008,
918         changed => {
919         },
920         removed => {
921         }
922     },
923     5.019010 => {
924         delta_from => 5.019009,
925         changed => {
926         },
927         removed => {
928         }
929     },
930     5.019011 => {
931         delta_from => 5.019010,
932         changed => {
933         },
934         removed => {
935         }
936     },
937     5.020000 => {
938         delta_from => 5.019011,
939         changed => {
940         },
941         removed => {
942         }
943     },
944     5.021000 => {
945         delta_from => 5.020000,
946         changed => {
947         },
948         removed => {
949         }
950     },
951     5.021001 => {
952         delta_from => 5.021000,
953         changed => {
954         },
955         removed => {
956             'a2p'                   => 1,
957             'config_data'           => 1,
958             'find2perl'             => 1,
959             'psed'                  => 1,
960             's2p'                   => 1,
961         }
962     },
963     5.021002 => {
964         delta_from => 5.021001,
965         changed => {
966         },
967         removed => {
968         }
969     },
970     5.021003 => {
971         delta_from => 5.021002,
972         changed => {
973         },
974         removed => {
975         }
976     },
977     5.020001 => {
978         delta_from => 5.02,
979         changed => {
980         },
981         removed => {
982         }
983     },
984     5.021004 => {
985         delta_from => 5.021003,
986         changed => {
987         },
988         removed => {
989         }
990     },
991     5.021005 => {
992         delta_from => 5.021004,
993         changed => {
994         },
995         removed => {
996         }
997     },
998     5.021006 => {
999         delta_from => 5.021005,
1000         changed => {
1001         },
1002         removed => {
1003         }
1004     },
1005     5.021007 => {
1006         delta_from => 5.021006,
1007         changed => {
1008         },
1009         removed => {
1010         }
1011     },
1012     5.021008 => {
1013         delta_from => 5.021007,
1014         changed => {
1015         },
1016         removed => {
1017         }
1018     },
1019     5.020002 => {
1020         delta_from => 5.020001,
1021         changed => {
1022         },
1023         removed => {
1024         }
1025     },
1026     5.021009 => {
1027         delta_from => 5.021008,
1028         changed => {
1029             'encguess'              => '1',
1030         },
1031         removed => {
1032         }
1033     },
1034     5.021010 => {
1035         delta_from => 5.021009,
1036         changed => {
1037         },
1038         removed => {
1039         }
1040     },
1041     5.021011 => {
1042         delta_from => 5.02101,
1043         changed => {
1044         },
1045         removed => {
1046         }
1047     },
1048     5.022000 => {
1049         delta_from => 5.021011,
1050         changed => {
1051         },
1052         removed => {
1053         }
1054     },
1055     5.023000 => {
1056         delta_from => 5.022000,
1057         changed => {
1058         },
1059         removed => {
1060         }
1061     },
1062     5.023001 => {
1063         delta_from => 5.023,
1064         changed => {
1065         },
1066         removed => {
1067         }
1068     },
1069     5.023002 => {
1070         delta_from => 5.023001,
1071         changed => {
1072         },
1073         removed => {
1074         }
1075     },
1076     5.023003 => {
1077         delta_from => 5.023002,
1078         changed => {
1079         },
1080         removed => {
1081         }
1082     },
1083 );
1084
1085 for my $version (sort { $a <=> $b } keys %delta) {
1086     my $data = $delta{$version};
1087
1088     tie %{$utilities{$version}}, 'Module::CoreList::TieHashDelta',
1089         $data->{changed}, $data->{removed},
1090         $data->{delta_from} ? $utilities{$data->{delta_from}} : undef;
1091 }
1092
1093 # Create aliases with trailing zeros for $] use
1094
1095 $utilities{'5.000'} = $utilities{5};
1096
1097 _create_aliases(\%utilities);
1098
1099 sub _create_aliases {
1100     my ($hash) = @_;
1101
1102     for my $version (keys %$hash) {
1103         next unless $version >= 5.010;
1104
1105         my $padded = sprintf "%0.6f", $version;
1106
1107         # If the version in string form isn't the same as the numeric version,
1108         # alias it.
1109         if ($padded ne $version && $version == $padded) {
1110             $hash->{$padded} = $hash->{$version};
1111         }
1112     }
1113 }
1114
1115 'foo';
1116
1117 =pod
1118
1119 =head1 NAME
1120
1121 Module::CoreList::Utils - what utilities shipped with versions of perl
1122
1123 =head1 SYNOPSIS
1124
1125  use Module::CoreList::Utils;
1126
1127  print $Module::CoreList::Utils::utilities{5.009003}{ptar}; # prints 1
1128
1129  print Module::CoreList::Utils->first_release('corelist');           # prints 5.008009
1130  print Module::CoreList::Utils->first_release_by_date('corelist');   # prints 5.009002
1131
1132 =head1 DESCRIPTION
1133
1134 Module::CoreList::Utils provides information on which core and dual-life utilities shipped
1135 with each version of L<perl>.
1136
1137 It provides a number of mechanisms for querying this information.
1138
1139 There is a functional programming API available for programmers to query
1140 information.
1141
1142 Programmers may also query the contained hash structure to find relevant
1143 information.
1144
1145 =head1 FUNCTIONS API
1146
1147 These are the functions that are available, they may either be called as functions or class methods:
1148
1149   Module::CoreList::Utils::first_release('corelist'); # as a function
1150
1151   Module::CoreList::Utils->first_release('corelist'); # class method
1152
1153 =over
1154
1155 =item C<utilities>
1156
1157 Requires a perl version as an argument, returns a list of utilities that shipped with
1158 that version of perl, or undef/empty list if that perl doesn't exist.
1159
1160 =item C<first_release( UTILITY )>
1161
1162 Requires a UTILITY name as an argument, returns the perl version when that utility first
1163 appeared in core as ordered by perl version number or undef ( in scalar context )
1164 or an empty list ( in list context ) if that utility is not in core.
1165
1166 =item C<first_release_by_date( UTILITY )>
1167
1168 Requires a UTILITY name as an argument, returns the perl version when that utility first
1169 appeared in core as ordered by release date or undef ( in scalar context )
1170 or an empty list ( in list context ) if that utility is not in core.
1171
1172 =item C<removed_from( UTILITY )>
1173
1174 Takes a UTILITY name as an argument, returns the first perl version where that utility
1175 was removed from core. Returns undef if the given utility was never in core or remains
1176 in core.
1177
1178 =item C<removed_from_by_date( UTILITY )>
1179
1180 Takes a UTILITY name as an argument, returns the first perl version by release date where that
1181 utility was removed from core. Returns undef if the given utility was never in core or remains
1182 in core.
1183
1184 =back
1185
1186 =head1 DATA STRUCTURES
1187
1188 These are the hash data structures that are available:
1189
1190 =over
1191
1192 =item C<%Module::CoreList::Utils::utilities>
1193
1194 A hash of hashes that is keyed on perl version as indicated
1195 in $].  The second level hash is utility / defined pairs.
1196
1197 =back
1198
1199 =head1 AUTHOR
1200
1201 Chris C<BinGOs> Williams <chris@bingosnet.co.uk>
1202
1203 Currently maintained by the perl 5 porters E<lt>perl5-porters@perl.orgE<gt>.
1204
1205 This module is the result of archaeology undertaken during QA Hackathon
1206 in Lancaster, April 2013.
1207
1208 =head1 LICENSE
1209
1210 Copyright (C) 2013 Chris Williams.  All Rights Reserved.
1211
1212 This module is free software; you can redistribute it and/or modify it
1213 under the same terms as Perl itself.
1214
1215 =head1 SEE ALSO
1216
1217 L<corelist>, L<Module::CoreList>, L<perl>, L<http://perlpunks.de/corelist>
1218
1219 =cut