Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: com/eireneh/bible/passage/Books.java


1   
2   package com.eireneh.bible.passage;
3   
4   import java.util.*;
5   
6   import com.eireneh.util.*;
7   import com.eireneh.util.LogicError;
8   
9   /**
10   * Books is a static class that deals with Book number conversions and similar.
11   * We start counting at 1 for books, chapters and verses (so Genesis=1, Revelation=66).
12   * However internally books start counting at 0 and go up to 65.
13   * <p>I've considered merging Books and PassageUtil since they are both supporting
14   * static only classes. However they are both non-trivial, so together they would
15   * be large, and there is a good dividing line between the 2.
16   *
17   * <table border='1' cellPadding='3' cellSpacing='0' width="100%">
18   * <tr><td bgColor='white'class='TableRowColor'><font size='-7'>
19   * Distribution Licence:<br />
20   * Project B is free software; you can redistribute it
21   * and/or modify it under the terms of the GNU General Public License,
22   * version 2 as published by the Free Software Foundation.<br />
23   * This program is distributed in the hope that it will be useful,
24   * but WITHOUT ANY WARRANTY; without even the implied warranty of
25   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
26   * General Public License for more details.<br />
27   * The License is available on the internet
28   * <a href='http://www.gnu.org/copyleft/gpl.html'>here</a>, by writing to
29   * <i>Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
30   * MA 02111-1307, USA</i>, Or locally at the Licence link below.<br />
31   * The copyright to this program is held by it's authors.
32   * </font></td></tr></table>
33   * @see <a href='http://www.eireneh.com/servlets/Web'>Project B Home</a>
34   * @see docs.Licence
35   * @author Joe Walker
36   * @version D9.I9.T7
37   * @stereotype utility
38   */
39  public class Books implements PassageConstants
40  {
41      /**
42       * Ensure that we can not be instansiated
43       */
44      private Books()
45      {
46      }
47  
48      /**
49       * How do we report the names of the books?.
50       * These are static. This is on the assumption that we will not want to have
51       * different sections of the app using a different format. I expect this to
52       * be a good assumption, and it saves passing a Book class around everywhere.
53       * Books.MIXED is not allowed
54       * @param book_case The new case to use for reporting book names
55       * @exception IllegalArgumentException If the case is not between 0 and 2
56       * @see Passage
57       * @see #getCase
58       */
59      public final static void setCase(int book_case)
60      {
61          if (book_case < 0 || book_case > 2)
62          {
63              Object[] params = new Object[] { new Integer(book_case) };
64              throw new IllegalArgumentException(PassageUtil.getResource("books_error_case", params));
65          }
66  
67          Books.book_case = book_case;
68      }
69  
70      /**
71       * How do we report the names of the books?.
72       * @return The current case setting
73       * @see Passage
74       * @see #setCase
75       */
76      public final static int getCase()
77      {
78          return Books.book_case;
79      }
80  
81      /**
82       * Get the full name of a book (e.g. "Genesis").
83       * Altered by the case setting (see setBookCase())
84       * @param idx The book number (1-66)
85       * @return The full name of the book
86       * @exception NoSuchVerseException If the book number is not valid
87       */
88      public final static String getLongBookName(int book) throws NoSuchVerseException
89      {
90          try
91          {
92              switch (book_case)
93              {
94              case CASE_LOWER:
95                  return full_books_lower[book-1];
96              case CASE_UPPER:
97                  return full_books_upper[book-1];
98              default:
99                  return full_books[book-1];
100             }
101         }
102         catch (ArrayIndexOutOfBoundsException ex)
103         {
104             // This is faster than doing the check explicitly, unless
105             // The exception is actually thrown, then it is a lot slower
106             // I'd like to think that the norm is to get it right
107             throw new NoSuchVerseException("passg_books_book",
108                 new Object[] { new Integer(book) });
109         }
110     }
111 
112     /**
113      * Get the short name of a book (e.g. "Gen").
114      * Altered by the case setting (see setBookCase())
115      * @param idx The book number (1-66)
116      * @return The short name of the book
117      * @exception NoSuchVerseException If the book number is not valid
118      */
119     public final static String getShortBookName(int book) throws NoSuchVerseException
120     {
121         try
122         {
123             switch (book_case)
124             {
125             case CASE_LOWER:
126                 return short_books_lower[book-1];
127             case CASE_UPPER:
128                 return short_books_upper[book-1];
129             default:
130                 return short_books[book-1];
131             }
132         }
133         catch (ArrayIndexOutOfBoundsException ex)
134         {
135             // This is faster than doing the check explicitly, unless
136             // The exception is actually thrown, then it is a lot slower
137             // I'd like to think that the norm is to get it right
138             throw new NoSuchVerseException("passg_books_book",
139                 new Object[] { new Integer(book) });
140         }
141     }
142 
143     /**
144      * Get the memory jogger letters for a book.
145      * @param idx The book number (1-66)
146      * @return A 2 character string containing the memory jogger characters
147      * @exception NoSuchVerseException If the book number is not valid
148      */
149     public final static String getBookJogger(int book) throws NoSuchVerseException
150     {
151         try
152         {
153             return jog_books[book-1];
154         }
155         catch (ArrayIndexOutOfBoundsException ex)
156         {
157             // This is faster than doing the check explicitly, unless
158             // The exception is actually thrown, then it is a lot slower
159             // I'd like to think that the norm is to get it right
160             throw new NoSuchVerseException("passg_books_book",
161                 new Object[] { new Integer(book) });
162         }
163     }
164 
165     /**
166      * Get the Short name of a book
167      * @param idx The book number (1-66)
168      * @return A string containing the memory jogger characters
169      * @exception IllegalArgumentException If the number is negative
170      */
171     public final static String getNumberJogger(long number)
172     {
173         if (number < 0)
174         {
175             Object[] params = new Object[] { new Long(number) };
176             throw new IllegalArgumentException(PassageUtil.getResource("books_error_jogger", params));
177         }
178 
179         String num = ""+number;
180         String retcode = "";
181 
182         for (int i=0; i<num.length(); i++)
183         {
184             retcode = retcode + jog_numbers[Character.getNumericValue(num.charAt(i))];
185         }
186 
187         return retcode;
188     }
189 
190     /**
191      * Get number of a book from its name.
192      * @param find The string to identify
193      * @return The book number (1 to 66)
194      * @exception NoSuchVerseException If the text can not be matched
195      */
196     public final static int getBookNumber(String find) throws NoSuchVerseException
197     {
198         String match = find.toLowerCase();
199 
200         // Check this isn't a number.
201         // And that it does not start with any of the numeric book markers
202         if (!PassageUtil.containsLetter(find))
203         {
204             boolean numeric_book = false;
205             for (int i=0; i<VERSE_NUMERIC_BOOK.length; i++)
206             {
207                 if (find.startsWith(VERSE_NUMERIC_BOOK[i]))
208                     numeric_book = true;
209             }
210 
211             if (!numeric_book)
212                 throw new NoSuchVerseException("passg_books_number", new Object[] { find });
213         }
214 
215         // Does it match a long version of the book
216         // or a short version
217         for (int i=0; i<full_books.length; i++)
218         {
219             if (full_books_lower[i].startsWith(match)) return i+1;
220             if (match.startsWith(short_books_lower[i])) return i+1;
221         }
222 
223         // The alternative versions
224         for (int i=0; i<alt_books.length; i++)
225         {
226             for (int j=0; j<alt_books[i].length; j++)
227             {
228                 if (match.startsWith(alt_books_lower[i][j])) return i+1;
229             }
230         }
231 
232         // if we start with a book number id mark
233         for (int i=0; i<VERSE_NUMERIC_BOOK.length; i++)
234         {
235             if (find.startsWith(VERSE_NUMERIC_BOOK[i]))
236             {
237                 int book = Integer.parseInt(find.substring(VERSE_NUMERIC_BOOK[i].length()));
238                 if (book < 1 || book > 66)
239                 {
240                     throw new NoSuchVerseException("passg_books_book",
241                         new Object[] { new Integer(book) });
242                 }
243                 return book;
244             }
245         }
246 
247         throw new NoSuchVerseException("passg_books_find",
248             new Object[] { find });
249     }
250 
251     /**
252      * Is the given string a valid book name. If this method returns true then
253      * getBookNumber() will return a number and not throw an exception.
254      * @param find The string to identify
255      * @return The book number (1 to 66)
256      * @exception NoSuchVerseException If the text can not be matched
257      */
258     public final static boolean isBookName(String find) throws NoSuchVerseException
259     {
260         String match = find.toLowerCase();
261 
262         if (!PassageUtil.containsLetter(find)) return false;
263 
264         // This could be sped up with less of the toLowerCase()
265         for (int i=0; i<full_books.length; i++)
266         {
267             if (full_books_lower[i].startsWith(match)) return true;
268             if (match.startsWith(short_books_lower[i])) return true;
269 
270             for (int j=0; j<alt_books[i].length; j++)
271             {
272                 if (match.startsWith(alt_books_lower[i][j])) return true;
273             }
274         }
275 
276         return false;
277     }
278 
279     /**
280      * Count the books in the Bible.
281      * @return 66 always - the number of books in the Bible
282      */
283     public final static int booksInBible()
284     {
285         return books_in_bible;
286     }
287 
288     /**
289      * Count the chapters in the Bible.
290      * @return 1189 always - the number of chapters in the Bible
291      */
292     public final static int chaptersInBible()
293     {
294         return chapters_in_bible;
295     }
296 
297     /**
298      * Count the verses in the Bible.
299      * This counts possible verses, so this number is not affected
300      * by some versions missing out some verses as 'there in error'
301      * @return 31102 always - the number of verses in the Bible
302      */
303     public final static int versesInBible()
304     {
305         return verses_in_bible;
306     }
307 
308     /**
309      * Count the chapters in this book.
310      * @param book The book part of the reference.
311      * @return The number of chapters
312      * @exception NoSuchVerseException If the book number is not valid
313      */
314     public final static int chaptersInBook(int book) throws NoSuchVerseException
315     {
316         try
317         {
318             return chapters_in_book[book-1];
319         }
320         catch (ArrayIndexOutOfBoundsException ex)
321         {
322             // This is faster than doing the check explicitly, unless
323             // The exception is actually thrown, then it is a lot slower
324             // I'd like to think that the norm is to get it right
325             throw new NoSuchVerseException("passg_books_book",
326                 new Object[] { new Integer(book) });
327         }
328     }
329 
330     /**
331      * Count the verses in a chapter.
332      * @param book The book part of the reference.
333      * @param chapter The current chapter
334      * @return The number of verses
335      * @exception NoSuchVerseException If the book or chapter number is not valid
336      */
337     public final static int versesInChapter(int book, int chapter) throws NoSuchVerseException
338     {
339         try
340         {
341             return verses_in_chapter[book-1][chapter-1];
342         }
343         catch (ArrayIndexOutOfBoundsException ex)
344         {
345             // This is faster than doing the check explicitly, unless
346             // The exception is actually thrown, then it is a lot slower
347             // I'd like to think that the norm is to get it right
348 
349             Object[] params = new Object[] { new Integer(book), new Integer(chapter) };
350             throw new NoSuchVerseException("passg_books_bookchap", params);
351         }
352     }
353 
354     /**
355      * Count the verses in a book.
356      * @param book The book part of the reference.
357      * @return The number of verses
358      * @exception NoSuchVerseException If the book number is not valid
359      */
360     public final static int versesInBook(int book) throws NoSuchVerseException
361     {
362         try
363         {
364             return verses_in_book[book-1];
365         }
366         catch (ArrayIndexOutOfBoundsException ex)
367         {
368             // This is faster than doing the check explicitly, unless
369             // The exception is actually thrown, then it is a lot slower
370             // I'd like to think that the norm is to get it right
371             throw new NoSuchVerseException("passg_books_book",
372                 new Object[] { new Integer(book) });
373         }
374     }
375 
376     /**
377      * Where does this verse come in the Bible. Starting with Gen 1:1 as
378      * number 1 counting up one per verse and not resetting at each new
379      * chapter.
380      * @param book The book part of the reference.
381      * @param chapter The current chapter
382      * @param verse The current verse
383      * @return The ordinal number of verses
384      * @exception NoSuchVerseException If the reference is illegal
385      */
386     public final static int verseOrdinal(int book, int chapter, int verse) throws NoSuchVerseException
387     {
388         validate(book, chapter, verse);
389         return ordinal_at_start_of_chapter[book-1][chapter-1] + verse - 1;
390     }
391 
392     /**
393      * Where does this verse come in the Bible. Starting with Gen 1:1 as
394      * number 1 counting up one per verse and not resetting at each new
395      * chapter.
396      * @param ref An array of 3 ints, book, chapter, verse
397      * @return The ordinal number of the verse
398      * @exception com.eireneh.bible.passage.NoSuchVerseException If the reference is illegal
399      */
400     public final static int verseOrdinal(int[] ref) throws NoSuchVerseException
401     {
402         if (ref.length != 3)
403             throw new NoSuchVerseException("passg_books_ordinal");
404 
405         return verseOrdinal(ref[0], ref[1], ref[2]);
406     }
407 
408     /**
409      * Where does this verse come in the Bible. Starting with Gen 1:1 as
410      * number 1 counting up one per verse and not resetting at each new
411      * chapter.
412      * @param ordinal The ordinal number of the verse
413      * @return An array of 3 ints, book, chapter, verse
414      * @exception NoSuchVerseException If the reference is illegal
415      */
416     public final static int[] decodeOrdinal(int ordinal) throws NoSuchVerseException
417     {
418         if (ordinal < 1 || ordinal > Books.versesInBible())
419         {
420             Object[] params = new Object[] { new Integer(Books.versesInBible()), new Integer(ordinal) };
421             throw new NoSuchVerseException("passg_books_decode", params);
422         }
423 
424         for (int b=books_in_bible; b>0; b--)
425         {
426             if (ordinal >= ordinal_at_start_of_book[b-1])
427             {
428                 int cib = Books.chaptersInBook(b);
429                 for (int c=cib; c>0; c--)
430                 {
431                     if (ordinal >= ordinal_at_start_of_chapter[b-1][c-1])
432                     {
433                         return new int[] { b, c, ordinal - ordinal_at_start_of_chapter[b-1][c-1] + 1 };
434                     }
435                 }
436             }
437         }
438 
439         throw new LogicError();
440     }
441 
442     /**
443      * Does the following represent a real verse? It is code like this
444      * that makes me wonder if I18 is done well/worth doing. All this
445      * code does is check if the numbers are valid, but the exception
446      * handling code is huge :(
447      * @param book The book part of the reference.
448      * @param chapter The chapter part of the reference.
449      * @param verse The verse part of the reference.
450      * @exception NoSuchVerseException If the reference is illegal
451      */
452     public final static void validate(int book, int chapter, int verse) throws NoSuchVerseException
453     {
454         // Check the book
455         if (book < 1 || book > books_in_bible)
456         {
457             throw new NoSuchVerseException("passg_books_book",
458                 new Object[] { new Integer(book) });
459         }
460 
461         // Check the chapter
462         if (chapter < 1 || chapter > chaptersInBook(book))
463         {
464             Object[] params = new Object[]
465                                  {
466                                  new Integer(chaptersInBook(book)),
467                                  full_books[book-1], new Integer(chapter),
468                                  };
469             throw new NoSuchVerseException("passg_books_chapter", params);
470         }
471 
472         // Check the verse
473         if (verse < 1 || verse > versesInChapter(book, chapter))
474         {
475             Object[] params = new Object[]
476                                  {
477                                  new Integer(versesInChapter(book, chapter)),
478                                  full_books[book-1],
479                                  new Integer(chapter),
480                                  new Integer(verse),
481                                  };
482             throw new NoSuchVerseException("passg_books_verse", params);
483         }
484     }
485 
486     /**
487      * Does the following represent a real verse?
488      * @param ref An array of 3 ints, book, chapter, verse
489      * @exception NoSuchVerseException If the reference is illegal
490      */
491     public final static void validate(int[] ref) throws NoSuchVerseException
492     {
493         if (ref.length != 3)
494             throw new NoSuchVerseException("passg_books_ordinal");
495 
496         validate(ref[BOOK], ref[CHAPTER], ref[VERSE]);
497     }
498 
499     /**
500      * Fix up these verses so that they are as valid a possible. This is currently
501      * done so that we can say "Gen 1:1" + 31 = "Gen 1:32" and "Gen 1:32".patch()
502      * is "Gen 2:1".
503      * <p>There is another patch system that allows us to use large numbers to
504      * mean "the end of" so "Gen 1:32".otherPatch() gives "Gen 1:31". This could
505      * be useful to allow the user to enter things like "Gen 1:99" meaning
506      * the end of the chapter. Or  "Isa 99:1" to mean the last chapter in Isaiah
507      * verse 1 or even "Rev 99:99" to mean the last verse in the Bible.
508      * <p>However I have not implemented this because I've used a different convention:
509      * "Gen 1:$" (OLB compatible) or "Gen 1:ff" (common comentary usage) to
510      * mean the end of the chapter - So the functionality is there anyway.
511      * <p>I think that getting into the habit of typing "Gen 1:99" is bad. It could
512      * be the source of surprises "Psa 119:99" is not what you'd might expect,
513      * and neither is "Psa 99:1" is you wanted the last chapter in Psalms - expecting
514      * us to type "Psa 999:1" seems like we're getting silly.
515      * <p>However dispite this maybe we should provide the functionality anyway.
516      * @param ref An array of 3 ints, book, chapter, verse. This array will be changed.
517      * @return The original array that has been patched.
518      */
519     public final static int[] patch(int[] ref)
520     {
521         try
522         {
523             // If they are too small
524             if (ref[BOOK] <= 0) ref[BOOK] = 1;
525             if (ref[CHAPTER] <= 0) ref[CHAPTER] = 1;
526             if (ref[VERSE] <= 0) ref[VERSE] = 1;
527 
528             // If they are too big
529             if (ref[BOOK] > books_in_bible)
530             {
531                 ref[BOOK] = Names.Revelation;
532                 ref[CHAPTER] = chaptersInBook(ref[BOOK]);
533                 ref[VERSE] = versesInChapter(ref[BOOK], ref[CHAPTER]);
534                 return ref;
535             }
536 
537             while (ref[CHAPTER] > chaptersInBook(ref[BOOK]))
538             {
539                 ref[CHAPTER] -= chaptersInBook(ref[BOOK]);
540                 ref[BOOK] += 1;
541 
542                 if (ref[BOOK] > books_in_bible)
543                 {
544                     ref[BOOK] = Names.Revelation;
545                     ref[CHAPTER] = chaptersInBook(ref[BOOK]);
546                     ref[VERSE] = versesInChapter(ref[BOOK], ref[CHAPTER]);
547                     return ref;
548                 }
549             }
550 
551             while (ref[VERSE] > versesInChapter(ref[BOOK], ref[CHAPTER]))
552             {
553                 ref[VERSE] -= versesInChapter(ref[BOOK], ref[CHAPTER]);
554                 ref[CHAPTER] += 1;
555 
556                 if (ref[CHAPTER] > chaptersInBook(ref[BOOK]))
557                 {
558                     ref[CHAPTER] -= chaptersInBook(ref[BOOK]);
559                     ref[BOOK] += 1;
560 
561                     if (ref[BOOK] > books_in_bible)
562                     {
563                         ref[BOOK] = Names.Revelation;
564                         ref[CHAPTER] = chaptersInBook(ref[BOOK]);
565                         ref[VERSE] = versesInChapter(ref[BOOK], ref[CHAPTER]);
566                         return ref;
567                     }
568                 }
569             }
570 
571             return ref;
572         }
573         catch (Exception ex)
574         {
575             throw new LogicError(ex);
576         }
577     }
578 
579     /**
580      * How many verses between ref1 and ref2 (inclusive).
581      * @param book1 The book part of the first reference.
582      * @param chapter1 The chapter part of the first reference.
583      * @param verse1 The verse part of the first reference.
584      * @param book2 The book part of the second reference.
585      * @param chapter2 The chapter part of the second reference.
586      * @param verse2 The verse part of the second reference.
587      * @exception NoSuchVerseException If either reference is illegal
588      */
589     public final static int verseCount(int book1, int chapter1, int verse1, int book2, int chapter2, int verse2) throws NoSuchVerseException
590     {
591         int verse_ord1 = verseOrdinal(book1, chapter1, verse1);
592         int verse_ord2 = verseOrdinal(book2, chapter2, verse2);
593 
594         return verse_ord2 - verse_ord1 + 1;
595     }
596 
597     /**
598      * How many verses between ref1 and ref2 (inclusive).
599      * @param ref1 An array of 3 ints, book, chapter, verse for the first reference.
600      * @param ref2 An array of 3 ints, book, chapter, verse for the second reference.
601      * @exception NoSuchVerseException If either reference is illegal
602      */
603     public final static int verseCount(int[] ref1, int[] ref2) throws NoSuchVerseException
604     {
605         if (ref1.length != 3 || ref2.length != 3)
606             throw new NoSuchVerseException("books_error_ordinal");
607 
608         return verseCount(ref1[0], ref1[1], ref1[2], ref2[0], ref2[1], ref2[2]);
609     }
610 
611     /**
612      * Is this book part of the Pentateuch?
613      * @param book The book to test
614      * @return True if this book is a part of this section
615      */
616     public final static boolean isPentateuch(int book)
617     {
618         return book >= Names.Genesis && book <= Names.Deuteronomy;
619     }
620 
621     /**
622      * Is this book part of the OT History?
623      * @param book The book to test
624      * @return True if this book is a part of this section
625      */
626     public final static boolean isHistory(int book)
627     {
628         return book >= Names.Joshua && book <= Names.Esther;
629     }
630 
631     /**
632      * Is this book part of the OT History?
633      * @param book The book to test
634      * @return True if this book is a part of this section
635      */
636     public final static boolean isPoetry(int book)
637     {
638         return book >= Names.Job && book <= Names.SongOfSolomon;
639     }
640 
641     /**
642      * Is this book part of the major prophets?
643      * @param book The book to test
644      * @return True if this book is a part of this section
645      */
646     public final static boolean isMajorProphet(int book)
647     {
648         return book >= Names.Isaiah && book <= Names.Daniel;
649     }
650 
651     /**
652      * Is this book part of the minor prophets?
653      * @param book The book to test
654      * @return True if this book is a part of this section
655      */
656     public final static boolean isMinorProphet(int book)
657     {
658         return book >= Names.Hosea && book <= Names.Malachi;
659     }
660 
661     /**
662      * Is this book part of the Gospels?
663      * @param book The book to test
664      * @return True if this book is a part of this section
665      */
666     public final static boolean isGospel(int book)
667     {
668         return book >= Names.Matthew && book <= Names.John;
669     }
670 
671     /**
672      * Is this book part of the Gospels or Acts?
673      * @param book The book to test
674      * @return True if this book is a part of this section
675      */
676     public final static boolean isGospelOrActs(int book)
677     {
678         return book >= Names.Matthew && book <= Names.Acts;
679     }
680 
681     /**
682      * Is this book part of the letters?
683      * @param book The book to test
684      * @return True if this book is a part of this section
685      */
686     public final static boolean isLetter(int book)
687     {
688         return book >= Names.Romans && book <= Names.Jude;
689     }
690 
691     /**
692      * What section is this book a part of?
693      * @param book The book to test
694      * @return True The section
695      * @see Books.Section
696      */
697     public final static int getSection(int book)
698     {
699         // Ordered by section size for speed
700         if (isLetter(book))       return Section.Letters;        // 21
701         if (isHistory(book))      return Section.History;        // 12
702         if (isMinorProphet(book)) return Section.MinorProphets;  // 12
703         if (isGospelOrActs(book)) return Section.GospelsAndActs; // 5
704         if (isPentateuch(book))   return Section.Pentateuch;     // 5
705         if (isPoetry(book))       return Section.Poetry;         // 5
706         if (isMajorProphet(book)) return Section.MajorProphets;  // 5
707         return Section.Revelation;
708     }
709 
710     /**
711      * How many books are there in each of the above sections
712      * @param section The section
713      * @return The number of books in the given section
714      * @see getSection(int)
715      */
716     public final static int booksInSection(int section)
717     {
718         return books_in_section[section];
719     }
720 
721     /**
722      * Get the full name of a book (e.g. "Genesis").
723      * Altered by the case setting (see setBookCase())
724      * @param idx The book number (1-66)
725      * @return The full name of the book
726      * @exception NoSuchVerseException If the book number is not valid
727      */
728     public final static String getSectionName(int section) throws NoSuchVerseException
729     {
730         if (section == 0)
731             throw new NoSuchVerseException("passg_books_section", new Object[] { new Integer(section) });
732 
733         try
734         {
735             switch (book_case)
736             {
737             case CASE_LOWER:
738                 return sections_lower[section-1];
739             case CASE_UPPER:
740                 return sections_upper[section-1];
741             default:
742                 return sections[section-1];
743             }
744         }
745         catch (ArrayIndexOutOfBoundsException ex)
746         {
747             // This is faster than doing the check explicitly, unless
748             // The exception is actually thrown, then it is a lot slower
749             // I'd like to think that the norm is to get it right
750             throw new NoSuchVerseException("passg_books_section",
751                 new Object[] { new Integer(section) });
752         }
753     }
754 
755     /** How the book names are reported */
756     private static int book_case = CASE_SENTANCE;
757 
758     /** The resource file, for book names */
759     private static ResourceBundle resources;
760 
761     /**
762      * Handy section finder. There is a bit of moderately bad programming
763      * here because com.eireneh.bible.control.map.swing.GroupVerseColor
764      * uses these numbers as an index into an array, so we shouldn't
765      * change these numbers without fixing that, however I don't imagine
766      * that this section could ever change without breaking
767      * GroupVerseColor anyway so I don't see it as a big problem.
768      */
769     public static class Section
770     {
771         public static final byte Pentateuch = 1;
772         public static final byte History = 2;
773         public static final byte Poetry = 3;
774         public static final byte MajorProphets = 4;
775         public static final byte MinorProphets = 5;
776         public static final byte GospelsAndActs = 6;
777         public static final byte Letters = 7;
778         public static final byte Revelation = 8;
779     }
780 
781     /**
782      * Handy book finder
783      */
784     public static class Names
785     {
786         public static final byte Genesis = 1;
787         public static final byte Exodus = 2;
788         public static final byte Leviticus = 3;
789         public static final byte Numbers = 4;
790         public static final byte Deuteronomy = 5;
791         public static final byte Joshua = 6;
792         public static final byte Judges = 7;
793         public static final byte Ruth = 8;
794         public static final byte Samuel1 = 9;
795         public static final byte Samuel2 = 10;
796         public static final byte Kings1 = 11;
797         public static final byte Kings2 = 12;
798         public static final byte Chronicles1 = 13;
799         public static final byte Chronicles2 = 14;
800         public static final byte Ezra = 15;
801         public static final byte Nehemiah = 16;
802         public static final byte Esther = 17;
803         public static final byte Job = 18;
804         public static final byte Psalms = 19;
805         public static final byte Proberbs = 20;
806         public static final byte Ecclesiastes = 21;
807         public static final byte SongOfSolomon = 22;
808         public static final byte Isaiah = 23;
809         public static final byte Jeremiah = 24;
810         public static final byte Lamentations = 25;
811         public static final byte Ezekiel = 26;
812         public static final byte Daniel = 27;
813         public static final byte Hosea = 28;
814         public static final byte Joel = 29;
815         public static final byte Amos = 30;
816         public static final byte Obdiah = 31;
817         public static final byte Jonah = 32;
818         public static final byte Micah = 33;
819         public static final byte Nahum = 34;
820         public static final byte Habakuk = 35;
821         public static final byte Zephaniah = 36;
822         public static final byte Haggai = 37;
823         public static final byte Zechariah = 38;
824         public static final byte Malachi = 39;
825         public static final byte Matthew = 40;
826         public static final byte Mark = 41;
827         public static final byte Luke = 42;
828         public static final byte John = 43;
829         public static final byte Acts = 44;
830         public static final byte Romans = 45;
831         public static final byte Corinthians1 = 46;
832         public static final byte Corinthians2 = 47;
833         public static final byte Galatians = 48;
834         public static final byte Ephesians = 49;
835         public static final byte Philippians = 50;
836         public static final byte Colossians = 51;
837         public static final byte Thessalonians1 = 52;
838         public static final byte Thessalonians2 = 53;
839         public static final byte Timothy1 = 54;
840         public static final byte Timothy2 = 55;
841         public static final byte Titus = 56;
842         public static final byte Philemon = 57;
843         public static final byte Hebrews = 58;
844         public static final byte James = 59;
845         public static final byte Peter1 = 60;
846         public static final byte Peter2 = 61;
847         public static final byte John1 = 62;
848         public static final byte John2 = 63;
849         public static final byte John3 = 64;
850         public static final byte Jude = 65;
851         public static final byte Revelation = 66;
852     }
853 
854     /** Used for methods with int[3] parameters, for the book */
855     public static final int BOOK = 0;
856 
857     /** Used for methods with int[3] parameters, for the chapter */
858     public static final int CHAPTER = 1;
859 
860     /** Used for methods with int[3] parameters, for the verse */
861     public static final int VERSE = 2;
862 
863     /** The full names of the book of the Bible, in mixed case */
864     private static String[] full_books =
865     {
866         "Genesis",      "Exodus",       "Leviticus",    "Numbers",      "Deuteronomy",
867         "Joshua",       "Judges",       "Ruth",         "1 Samuel",     "2 Samuel",
868         "1 Kings",      "2 Kings",      "1 Chronicles", "2 Chronicles",
869         "Ezra",         "Nehemiah",     "Esther",
870         "Job",          "Psalms",       "Proberbs",     "Ecclesiastes", "Song of Solomon",
871         "Isaiah",       "Jeremiah",     "Lamentations",
872         "Ezekiel",      "Daniel",       "Hosea",        "Joel",         "Amos",
873         "Obdiah",       "Jonah",        "Micah",        "Nahum",
874         "Habakuk",      "Zephaniah",    "Haggai",       "Zechariah",    "Malachi",
875         "Matthew",      "Mark",         "Luke",         "John",         "Acts",
876         "Romans",       "1 Corinthians","2 Corinthians","Galatians",    "Ephesians",
877         "Philippians",  "Colossians",   "1 Thessalonians","2 Thessalonians",
878         "1 Timothy",    "2 Timothy",    "Titus",        "Philemon",     "Hebrews",
879         "James",        "1 Peter",      "2 Peter",
880         "1 John",       "2 John",       "3 John",       "Jude",         "Revelation",
881     };
882 
883     /** Standard shortened names for the book of the Bible, in mixed case */
884     private static String[] short_books =
885     {
886         "Gen",  "Exo",  "Lev",  "Num",  "Deu",  "Jos",  "Judg", "Rut",  "1Sa",  "2Sa",
887         "1Ki",  "2Ki",  "1Ch",  "2Ch",  "Ezr",  "Neh",  "Est",  "Job",  "Psa",  "Pro",
888         "Ecc",  "Son",  "Isa",  "Jer",  "Lam",  "Eze",  "Dan",  "Hos",  "Joe",  "Amo",
889         "Obd",  "Jon",  "Mic",  "Nah",  "Hab",  "Zep",  "Hag",  "Zec",  "Mal",  "Mat",
890         "Mar",  "Luk",  "Joh",  "Act",  "Rom",  "1Co",  "2Co",  "Gal",  "Eph",  "Phili",
891         "Col",  "1Th",  "2Th",  "1Ti",  "2Ti",  "Tit",  "Phile","Heb",  "Jam",  "1Pe",
892         "2Pe",  "1Jo",  "2Jo",  "3Jo",  "Jude", "Rev",
893     };
894 
895     /** Standard names for the sections */
896     private static String[] sections =
897     {
898         "Pentateuch",
899         "History",
900         "Poetry",
901         "MajorProphets",
902         "MinorProphets",
903         "GospelsAndActs",
904         "Letters",
905         "Revelation",
906     };
907 
908     /** Alternative shortened names for the book of the Bible, in mixed case */
909     private static String[][] alt_books =
910     {
911         /* Gen */   { },
912         /* Exo */   { },
913         /* Lev */   { },
914         /* Num */   { },
915         /* Deu */   { "Dt" },
916         /* Jos */   { },
917         /* Judg */  { "Jdg" },
918         /* Rut */   { "Rth" },
919         /* 1Sa */   { },
920         /* 2Sa */   { },
921         /* 1Ki */   { },
922         /* 2Ki */   { },
923         /* 1Ch */   { },
924         /* 2Ch */   { },
925         /* Ezr */   { },
926         /* Neh */   { },
927         /* Est */   { },
928         /* Job */   { },
929         /* Psa */   { },
930         /* Pro */   { },
931         /* Ecc */   { },
932         /* Son */   { "SS" },
933         /* Isa */   { },
934         /* Jer */   { },
935         /* Lam */   { },
936         /* Eze */   { },
937         /* Dan */   { },
938         /* Hos */   { },
939         /* Joe */   { },
940         /* Amo */   { },
941         /* Obd */   { },
942         /* Jon */   { "Jnh" },
943         /* Mic */   { },
944         /* Nah */   { },
945         /* Hab */   { },
946         /* Zep */   { },
947         /* Hag */   { },
948         /* Zec */   { },
949         /* Mal */   { },
950         /* Mat */   { "Mt" },
951         /* Mar */   { "Mk" },
952         /* Luk */   { "Lk" },
953         /* Joh */   { "Jn", "Jhn" },
954         /* Act */   { },
955         /* Rom */   { },
956         /* 1Co */   { },
957         /* 2Co */   { },
958         /* Gal */   { },
959         /* Eph */   { },
960         /* Phili */ { "Php" },
961         /* Col */   { },
962         /* 1Th */   { },
963         /* 2Th */   { },
964         /* 1Ti */   { "1Tm" },
965         /* 2Ti */   { "2Tm" },
966         /* Tit */   { },
967         /* Phile */ { "Phm" },
968         /* Heb */   { },
969         /* Jam */   { "Jas" },
970         /* 1Pe */   { "1Pt" },
971         /* 2Pe */   { "1Pt" },
972         /* 1Jo */   { "1Jn" },
973         /* 2Jo */   { "2Jn" },
974         /* 3Jo */   { "3Jn" },
975         /* Jude */  { },
976         /* Rev */   { "Rv" },
977     };
978 
979     /** The full names of the book of the Bible, in lower case, generated at run time */
980     private static String[] full_books_lower;
981 
982     /** Standard shortened names for the book of the Bible, in lower case, generated at run time */
983     private static String[] short_books_lower;
984 
985     /** Alternative shortened names for the book of the Bible, in lower case, generated at run time */
986     private static String[][] alt_books_lower;
987 
988     /** The full names of the book of the Bible, in upper case, generated at run time */
989     private static String[] full_books_upper;
990 
991     /** Standard shortened names for the book of the Bible, in upper case, generated at run time */
992     private static String[] short_books_upper;
993 
994     /** Standard Bible section names, in upper case, generated at run time */
995     private static String[] sections_upper;
996 
997     /** Standard Bible section names, in lower case, generated at run time */
998     private static String[] sections_lower;
999 
1000    /* Alternative shortened names for the book of the Bible, in upper case, generated at run time */
1001    // Not needed as the lower version was only there to speed up searching.
1002    // private static String[][] alt_books_upper;
1003
1004    /** The memory jogger names for the books of the Bible */
1005    private static final String[] jog_books =
1006    {
1007        "LT", "LN", "LM", "LR", "LL", "JT", "JN", "JM", "KT", "KN",
1008        "KM", "KR", "KL", "KG", "RT", "RN", "RM", "ST", "SN", "SM",
1009        "SR", "SL", "PT", "PN", "PM", "PR", "PL", "MT", "MN", "MM",
1010        "MR", "ML", "MG", "NT", "NN", "NM", "NT", "NL", "NG", "GT",
1011        "GN", "GM", "GR", "GL", "ST", "SN", "SM", "SR", "SL", "SG",
1012        "SK", "TT", "TN", "TM", "TR", "TL", "TG", "TK", "DT", "DN",
1013        "DM", "DR", "DL", "DG", "DK", "DB",
1014    };
1015
1016    /** The memory jogger names for the numbers */
1017    private static final String[] jog_numbers =
1018    {
1019        "S", "T", "N", "M", "R", "L", "G", "K", "B", "P",
1020    };
1021
1022    /** Constant for the number of books in the Bible */
1023    private static final int books_in_bible = 66;
1024
1025    /** Constant for the number of chapters in the Bible */
1026    private static final int chapters_in_bible = 1189;
1027
1028    /** Constant for the number of chapters in each book */
1029    private static final int[] chapters_in_book =
1030    {
1031        50, 40, 27, 36, 34, 24, 21,  4, 31, 24,
1032        22, 25, 29, 36, 10, 13, 10, 42,150, 31,
1033        12,  8, 66, 52,  5, 48, 12, 14,  3,  9,
1034        1,  4,  7,  3,  3,  3,  2, 14,  4, 28,
1035        16, 24, 21, 28, 16, 16, 13,  6,  6,  4,
1036        4,  5,  3,  6,  4,  3,  1, 13,  5,  5,
1037        3,  5,  1,  1,  1, 22,
1038    };
1039
1040    /** Constant for the number of verses in the Bible */
1041    private static final int verses_in_bible = 31102;
1042
1043    /** Constant for the number of verses in each book */
1044    private static final int[] verses_in_book =
1045    {
1046        1533, 1213,  859, 1288,  959,  658,  618,   85,  810,  695,
1047        816,  719,  942,  822,  280,  406,  167, 1070, 2461,  915,
1048        222,  117, 1292, 1364,  154, 1273,  357,  197,   73,  146,
1049        21,   48,  105,   47,   56,   53,   38,  211,   55, 1071,
1050        678, 1151,  879, 1007,  433,  437,  257,  149,  155,  104,
1051        95,   89,   47,  113,   83,   46,   25,  303,  108,  105,
1052        61,  105,   13,   14,   25,  404,
1053    };
1054
1055    /** Constant for the number of verses in each chapter */
1056    private static final int[][] verses_in_chapter =
1057    {
1058        { 31, 25, 24, 26, 32, 22, 24, 22, 29, 32, 32, 20, 18, 24, 21, 16, 27, 33, 38, 18, 34, 24, 20, 67, 34, 35, 46, 22, 35, 43, 55, 32, 20, 31, 29, 43, 36, 30, 23, 23, 57, 38, 34, 34, 28, 34, 31, 22, 33, 26 },
1059        { 22, 25, 22, 31, 23, 30, 25, 32, 35, 29, 10, 51, 22, 31, 27, 36, 16, 27, 25, 26, 36, 31, 33, 18, 40, 37, 21, 43, 46, 38, 18, 35, 23, 35, 35, 38, 29, 31, 43, 38 },
1060        { 17, 16, 17, 35, 19, 30, 38, 36, 24, 20, 47,  8, 59, 57, 33, 34, 16, 30, 37, 27, 24, 33, 44, 23, 55, 46, 34 },
1061        { 54, 34, 51, 49, 31, 27, 89, 26, 23, 36, 35, 16, 33, 45, 41, 50, 13, 32, 22, 29, 35, 41, 30, 25, 18, 65, 23, 31, 40, 16, 54, 42, 56, 29, 34, 13 },
1062        { 46, 37, 29, 49, 33, 25, 26, 20, 29, 22, 32, 32, 18, 29, 23, 22, 20, 22, 21, 20, 23, 30, 25, 22, 19, 19, 26, 68, 29, 20, 30, 52, 29, 12 },
1063        { 18, 24, 17, 24, 15, 27, 26, 35, 27, 43, 23, 24, 33, 15, 63, 10, 18, 28, 51,  9, 45, 34, 16, 33 },
1064        { 36, 23, 31, 24, 31, 40, 25, 35, 57, 18, 40, 15, 25, 20, 20, 31, 13, 31, 30, 48, 25 },
1065        { 22, 23, 18, 22 },
1066        { 28, 36, 21, 22, 12, 21, 17, 22, 27, 27, 15, 25, 23, 52, 35, 23, 58, 30, 24, 42, 15, 23, 29, 22, 44, 25, 12, 25, 11, 31, 13 },
1067        { 27, 32, 39, 12, 25, 23, 29, 18, 13, 19, 27, 31, 39, 33, 37, 23, 29, 33, 43, 26, 22, 51, 39, 25 },
1068        { 53, 46, 28, 34, 18, 38, 51, 66, 28, 29, 43, 33, 34, 31, 34, 34, 24, 46, 21, 43, 29, 53 },
1069        { 18, 25, 27, 44, 27, 33, 20, 29, 37, 36, 21, 21, 25, 29, 38, 20, 41, 37, 37, 21, 26, 20, 37, 20, 30 },
1070        { 54, 55, 24, 43, 26, 81, 40, 40, 44, 14, 47, 40, 14, 17, 29, 43, 27, 17, 19,  8, 30, 19, 32, 31, 31, 32, 34, 21, 30 },
1071        { 17, 18, 17, 22, 14, 42, 22, 18, 31, 19, 23, 16, 22, 15, 19, 14, 19, 34, 11, 37, 20, 12, 21, 27, 28, 23,  9, 27, 36, 27, 21, 33, 25, 33, 27, 23 },
1072        { 11, 70, 13, 24, 17, 22, 28, 36, 15, 44 },
1073        { 11, 20, 32, 23, 19, 19, 73, 18, 38, 39, 36, 47, 31 },
1074        { 22, 23, 15, 17, 14, 14, 10, 17, 32, 03 },
1075        { 22, 13, 26, 21, 27, 30, 21, 22, 35, 22, 20, 25, 28, 22, 35, 22, 16, 21, 29, 29, 34, 30, 17, 25,  6, 14, 23, 28, 25, 31, 40, 22, 33, 37, 16, 33, 24, 41, 30, 24, 34, 17 },
1076        {  6, 12,  8,  8, 12, 10, 17,  9, 20, 18,  7,  8,  6,  7,  5, 11, 15, 50, 14,  9, 13, 31,  6, 10, 22, 12, 14,  9, 11, 12, 24, 11, 22, 22, 28, 12, 40, 22, 13, 17, 13, 11,  5, 26, 17, 11,  9, 14, 20, 23, 19,  9,  6,  7, 23, 13, 11, 11, 17, 12,  8, 12, 11, 10, 13, 20,  7, 35, 36,  5, 24, 20, 28, 23, 10, 12, 20, 72, 13, 19, 16,  8, 18, 12, 13, 17,  7, 18, 52, 17, 16, 15,  5, 23, 11, 13, 12,  9,  9,  5,  8, 28, 22, 35, 45, 48, 43, 13, 31,  7, 10, 10,  9,  8, 18, 19,  2, 29,176,  7,  8,  9,  4,  8,  5,  6,  5,  6,  8,  8,  3, 18,  3,  3, 21, 26, 9,  8, 24, 13, 10,  7, 12, 15, 21, 10, 20, 14,  9,  6 },
1077        { 33, 22, 35, 27, 23, 35, 27, 36, 18, 32, 31, 28, 25, 35, 33, 33, 28, 24, 29, 30, 31, 29, 35, 34, 28, 28, 27, 28, 27, 33, 31 },
1078        { 18, 26, 22, 16, 20, 12, 29, 17, 18, 20, 10, 14 },
1079        { 17, 17, 11, 16, 16, 13, 13, 14 },
1080        { 31, 22, 26, 06, 30, 13, 25, 22, 21, 34, 16, 06, 22, 32,  9, 14, 14, 07, 25, 06, 17, 25, 18, 23, 12, 21, 13, 29, 24, 33,  9, 20, 24, 17, 10, 22, 38, 22,  8, 31, 29, 25, 28, 28, 25, 13, 15, 22, 26, 11, 23, 15, 12, 17, 13, 12, 21, 14, 21, 22, 11, 12, 19, 12, 25, 24 },
1081        { 19, 37, 25, 31, 31, 30, 34, 22, 26, 25, 23, 17, 27, 22, 21, 21, 27, 23, 15, 18, 14, 30, 40, 10, 38, 24, 22, 17, 32, 24, 40, 44, 26, 22, 19, 32, 21, 28, 18, 16, 18, 22, 13, 30,  5, 28,  7, 47, 39, 46, 64, 34 },
1082        { 22, 22, 66, 22, 22 },
1083        { 28, 10, 27, 17, 17, 14, 27, 18, 11, 22, 25, 28, 23, 23,  8, 63, 24, 32, 14, 49, 32, 31, 49, 27, 17, 21, 36, 26, 21, 26, 18, 32, 33, 31, 15, 38, 28, 23, 29, 49, 26, 20, 27, 31, 25, 24, 23, 35 },
1084        { 21, 49, 30, 37, 31, 28, 28, 27, 27, 21, 45, 13 },
1085        { 11, 23, 05, 19, 15, 11, 16, 14, 17, 15, 12, 14, 16,  9 },
1086        { 20, 32, 21 },
1087        { 15, 16, 15, 13, 27, 14, 17, 14, 15 },
1088        { 21 },
1089        { 17, 10, 10, 11 },
1090        { 16, 13, 12, 13, 15, 16, 20 },
1091        { 15, 13, 19 },
1092        { 17, 20, 19 },
1093        { 18, 15, 20 },
1094        { 15, 23 },
1095        { 21, 13, 10, 14, 11, 15, 14, 23, 17, 12, 17, 14,  9, 21 },
1096        { 14, 17, 18, 06 },
1097        { 25, 23, 17, 25, 48, 34, 29, 34, 38, 42, 30, 50, 58, 36, 39, 28, 27, 35, 30, 34, 46, 46, 39, 51, 46, 75, 66, 20 },
1098        { 45, 28, 35, 41, 43, 56, 37, 38, 50, 52, 33, 44, 37, 72, 47, 20 },
1099        { 80, 52, 38, 44, 39, 49, 50, 56, 62, 42, 54, 59, 35, 35, 32, 31, 37, 43, 48, 47, 38, 71, 56, 53 },
1100        { 51, 25, 36, 54, 47, 71, 53, 59, 41, 42, 57, 50, 38, 31, 27, 33, 26, 40, 42, 31, 25 },
1101        { 26, 47, 26, 37, 42, 15, 60, 40, 43, 48, 30, 25, 52, 28, 41, 40, 34, 28, 41, 38, 40, 30, 35, 27, 27, 32, 44, 31 },
1102        { 32, 29, 31, 25, 21, 23, 25, 39, 33, 21, 36, 21, 14, 23, 33, 27 },
1103        { 31, 16, 23, 21, 13, 20, 40, 13, 27, 33, 34, 31, 13, 40, 58, 24 },
1104        { 24, 17, 18, 18, 21, 18, 16, 24, 15, 18, 33, 21, 14 },
1105        { 24, 21, 29, 31, 26, 18 },
1106        { 23, 22, 21, 32, 33, 24 },
1107        { 30, 30, 21, 23 },
1108        { 29, 23, 25, 18 },
1109        { 10, 20, 13, 18, 28 },
1110        { 12, 17, 18 },
1111        { 20, 15, 16, 16, 25, 21 },
1112        { 18, 26, 17, 22 },
1113        { 16, 15, 15 },
1114        { 25 },
1115        { 14, 18, 19, 16, 14, 20, 28, 13, 28, 39, 40, 29, 25 },
1116        { 27, 26, 18, 17, 20 },
1117        { 25, 25, 22, 19, 14 },
1118        { 21, 22, 18 },
1119        { 10, 29, 24, 21, 21 },
1120        { 13 },
1121        { 14 },
1122        { 25 },
1123        { 20, 29, 22, 11, 14, 17, 17, 13, 21, 11, 19, 17, 18, 20,  8, 21, 18, 24, 21, 15, 27, 21 }
1124    };
1125
1126    /** Constant for the ordinal number of the first verse in each book */
1127    private static final int[] ordinal_at_start_of_book =
1128    {
1129        1,  1534,  2747,  3606,  4894,  5853,  6511,  7129,  7214,  8024,
1130        8719,  9535, 10254, 11196, 12018, 12298, 12704, 12871, 13941, 16402,
1131        17317, 17539, 17656, 18948, 20312, 20466, 21739, 22096, 22293, 22366,
1132        22512, 22533, 22581, 22686, 22733, 22789, 22842, 22880, 23091, 23146,
1133        24217, 24895, 26046, 26925, 27932, 28365, 28802, 29059, 29208, 29363,
1134        29467, 29562, 29651, 29698, 29811, 29894, 29940, 29965, 30268, 30376,
1135        30481, 30542, 30647, 30660, 30674, 30699,
1136    };
1137
1138    /**
1139     * Constant for the ordinal number of the first verse in each chapter.
1140     * Warning if you regenerate this code (from the code at the bottom of
1141     * this module) then you will need to cut the psalms line in half to
1142     * get it to compile under JBuilder.
1143     */
1144    private static final int[][] ordinal_at_start_of_chapter =
1145    {
1146        {     1,    32,    57,    81,   107,   139,   161,   185,   207,   236,   268,   300,   320,   338,   362,   383,   399,   426,   459,   497,   515,   549,   573,   593,   660,   694,   729,   775,   797,   832,   875,   930,   962,   982,  1013,  1042,  1085,  1121,  1151,  1174,  1197,  1254,  1292,  1326,  1360,  1388,  1422,  1453,  1475,  1508, },
1147        {  1534,  1556,  1581,  1603,  1634,  1657,  1687,  1712,  1744,  1779,  1808,  1818,  1869,  1891,  1922,  1949,  1985,  2001,  2028,  2053,  2079,  2115,  2146,  2179,  2197,  2237,  2274,  2295,  2338,  2384,  2422,  2440,  2475,  2498,  2533,  2568,  2606,  2635,  2666,  2709, },
1148        {  2747,  2764,  2780,  2797,  2832,  2851,  2881,  2919,  2955,  2979,  2999,  3