Author: toad
Date: 2007-05-10 17:38:21 +0000 (Thu, 10 May 2007)
New Revision: 13199

Added:
   trunk/freenet/src/freenet/clients/http/filter/UnknownCharsetException.java
Modified:
   trunk/freenet/src/freenet/clients/http/filter/CSSReadFilter.java
   trunk/freenet/src/freenet/clients/http/filter/CSSTokenizerFilter.java
   trunk/freenet/src/freenet/clients/http/filter/CSSTokenizerFilter.jflex
   trunk/freenet/src/freenet/clients/http/filter/GIFFilter.java
   trunk/freenet/src/freenet/clients/http/filter/GenericReadFilterCallback.java
   trunk/freenet/src/freenet/clients/http/filter/HTMLFilter.java
   trunk/freenet/src/freenet/clients/http/filter/JPEGFilter.java
   
trunk/freenet/src/freenet/clients/http/filter/KnownUnsafeContentTypeException.java
   trunk/freenet/src/freenet/clients/http/filter/PNGFilter.java
   
trunk/freenet/src/freenet/clients/http/filter/UnknownContentTypeException.java
   trunk/freenet/src/freenet/l10n/freenet.l10n.en.properties
Log:
L10n keys for the client filter layer (and some minor related changes)

Modified: trunk/freenet/src/freenet/clients/http/filter/CSSReadFilter.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/filter/CSSReadFilter.java    
2007-05-10 13:51:45 UTC (rev 13198)
+++ trunk/freenet/src/freenet/clients/http/filter/CSSReadFilter.java    
2007-05-10 17:38:21 UTC (rev 13199)
@@ -48,13 +48,7 @@
                } catch (UnsupportedEncodingException e) {
                        os.close();
                        strm.close();
-                       HTMLNode explanation = new HTMLNode("p");
-                       String explTitle = l10nDF("unknownCharsetTitle");
-                       String expl = l10nDF("unknownCharset");
-                       explanation.addChild("b", explTitle);
-                       explanation.addChild("#", " " + expl);
-                       String warning = l10nDF("warningUnknownCharsetTitle", 
"charset", charset);
-                       throw new DataFilterException(warning, warning, 
explTitle + " " + expl, explanation);
+                       throw UnknownCharsetException.create(e, charset);
                }
                CSSParser parser = new CSSParser(r, w, false, cb);
                parser.parse();
@@ -63,16 +57,6 @@
                return temp;
        }

-       private static String l10nDF(String key) {
-               // All the strings here are generic
-               return L10n.getString("ContentDataFilter."+key);
-       }
-
-       private static String l10nDF(String key, String pattern, String value) {
-               // All the strings here are generic
-               return L10n.getString("ContentDataFilter."+key, pattern, value);
-       }
-
        public Bucket writeFilter(Bucket data, BucketFactory bf, String charset,
                        HashMap otherParams, FilterCallback cb) throws 
DataFilterException,
                        IOException {

Modified: trunk/freenet/src/freenet/clients/http/filter/CSSTokenizerFilter.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/filter/CSSTokenizerFilter.java       
2007-05-10 13:51:45 UTC (rev 13198)
+++ trunk/freenet/src/freenet/clients/http/filter/CSSTokenizerFilter.java       
2007-05-10 17:38:21 UTC (rev 13199)
@@ -1,865 +1,866 @@
-/* The following code was generated by JFlex 1.4.1 on 5/7/07 5:56 AM */
-
+/* The following code was generated by JFlex 1.4.1 on 10/05/07 18:37 */
+
 /* This code is part of Freenet. It is distributed under the GNU General
  * Public License, version 2 (or at your option any later version). See
  * http://www.gnu.org/ for further details of the GPL. */ 
 package freenet.clients.http.filter;
 import java.io.*;
 import java.util.*;
+import freenet.l10n.L10n;
 /* This class tokenizes a CSS2 Reader stream, writes it out to the output 
Writer, and filters any URLs found */
 // WARNING: this is not as thorough as the HTML parser - new versions of the 
standard could lead to anonymity risks. See comments in SaferFilter.java
 // FIXME: Rewrite this as a proper whitelist filter. It's about half way 
there, it
 // just needs somebody to go over the standard carefully and eliminate 
everything that isn't sufficiently specific (e.g. matching a '-' on its own).
 // Mostly from http://www.w3.org/TR/REC-CSS2/grammar.html

-
-/**
- * This class is a scanner generated by 
- * <a href="http://www.jflex.de/";>JFlex</a> 1.4.1
- * on 5/7/07 5:56 AM from the specification file
- * <tt>freenet/clients/http/filter/CSSTokenizerFilter.jflex</tt>
- */
-class CSSTokenizerFilter {
-
-  /** This character denotes the end of file */
-  public static final int YYEOF = -1;
-
-  /** initial size of the lookahead buffer */
-  private static final int ZZ_BUFFERSIZE = 16384;
-
-  /** lexical states */
-  public static final int YYINITIAL = 0;
-
-  /** 
-   * Translates characters to character classes
-   */
-  private static final String ZZ_CMAP_PACKED = 
-    "\11\0\1\3\1\3\1\0\1\3\1\3\22\0\1\5\1\41\1\11"+
-    "\1\17\1\4\1\64\1\4\1\12\1\23\1\15\1\37\1\56\1\24"+
-    "\1\13\1\14\1\36\12\1\1\46\1\33\1\40\1\44\1\42\1\16"+
-    "\1\25\1\47\1\6\1\55\1\52\1\51\1\53\1\50\1\61\1\26"+
-    "\1\7\1\63\1\22\1\27\1\54\1\31\1\30\1\7\1\21\1\60"+
-    "\1\32\1\20\2\7\1\57\1\7\1\62\1\4\1\2\2\4\1\10"+
-    "\1\4\1\47\1\6\1\55\1\52\1\51\1\53\1\50\1\61\1\26"+
-    "\1\7\1\63\1\22\1\27\1\54\1\31\1\30\1\7\1\21\1\60"+
-    "\1\32\1\20\2\7\1\57\1\7\1\62\1\34\1\45\1\35\1\43"+
-    "\uff81\0";
-
-  /** 
-   * Translates characters to character classes
-   */
-  private static final char [] ZZ_CMAP = zzUnpackCMap(ZZ_CMAP_PACKED);
-
-  /** 
-   * Translates DFA states to action switch labels.
-   */
-  private static final int [] ZZ_ACTION = zzUnpackAction();
-
-  private static final String ZZ_ACTION_PACKED_0 =
-    "\1\0\1\1\1\2\1\1\1\3\1\2\2\1\2\4"+
-    "\1\5\1\1\1\2\1\4\1\1\1\6\1\7\1\10"+
-    "\1\4\4\1\3\0\1\11\1\0\1\12\1\13\1\2"+
-    "\2\0\1\14\2\0\1\15\2\0\1\16\1\17\1\0"+
-    "\1\17\1\2\1\0\1\20\1\0\5\20\4\0\1\21"+
-    "\1\22\2\0\1\2\2\14\2\0\1\15\1\23\12\0"+
-    "\2\17\1\2\2\24\6\20\4\0\1\2\1\0\1\15"+
-    "\2\0\1\25\1\17\1\11\1\24\1\0\1\24\6\20"+
-    "\1\26\1\27\2\0\1\2\1\0\1\15\2\17\5\0"+
-    "\1\30\2\24\1\31\3\20\1\32\2\20\2\0\1\2"+
-    "\1\0\1\15\2\17\1\30\3\0\2\24\1\31\5\20"+
-    "\2\0\1\2\1\0\1\15\1\25\1\17\2\0\2\24"+
-    "\1\31\2\20\1\33\2\0\2\20\6\0\1\34\1\15"+
-    "\1\17\2\30\2\24\1\31\1\20\1\0\1\20\4\0"+
-    "\1\20\1\35\2\33\2\20\2\0\1\34\3\0\1\31"+
-    "\1\0\2\20\1\35\4\0\1\20\1\33\1\20\6\0"+
-    "\1\31\1\20\5\0\1\35\1\0\1\20\1\33\1\36"+
-    "\3\0\1\37\2\34\1\20\4\0\1\35\5\0\1\35"+
-    "\1\0\1\33\1\0\1\40\1\0\1\20\15\0\1\33"+
-    "\2\40\1\20\11\0\1\33\1\20\6\0\1\35\23\0"+
-    "\1\35\3\0\1\35\32\0";
-
-  private static int [] zzUnpackAction() {
-    int [] result = new int[343];
-    int offset = 0;
-    offset = zzUnpackAction(ZZ_ACTION_PACKED_0, offset, result);
-    return result;
-  }
-
-  private static int zzUnpackAction(String packed, int offset, int [] result) {
-    int i = 0;       /* index in packed string  */
-    int j = offset;  /* index in unpacked array */
-    int l = packed.length();
-    while (i < l) {
-      int count = packed.charAt(i++);
-      int value = packed.charAt(i++);
-      do result[j++] = value; while (--count > 0);
-    }
-    return j;
-  }
-
-
-  /** 
-   * Translates a state to a row index in the transition table
-   */
-  private static final int [] ZZ_ROWMAP = zzUnpackRowMap();
-
-  private static final String ZZ_ROWMAP_PACKED_0 =
-    "\0\0\0\65\0\152\0\237\0\324\0\u0109\0\u013e\0\u0173"+
-    "\0\u01a8\0\u01dd\0\65\0\u0212\0\u0247\0\65\0\u027c\0\65"+
-    "\0\u02b1\0\u02e6\0\u031b\0\u0350\0\u0385\0\u03ba\0\u03ef\0\237"+
-    "\0\u0424\0\u01dd\0\65\0\u0459\0\65\0\65\0\u048e\0\u013e"+
-    "\0\u04c3\0\65\0\u0173\0\u04f8\0\u052d\0\u0562\0\u0597\0\u05cc"+
-    "\0\u0601\0\u0636\0\u066b\0\u06a0\0\u06d5\0\u070a\0\u073f\0\u0774"+
-    "\0\u07a9\0\u07de\0\u0813\0\u0848\0\u087d\0\u08b2\0\u0385\0\u08e7"+
-    "\0\65\0\65\0\u091c\0\u0951\0\u0986\0\u013e\0\u0173\0\u09bb"+
-    "\0\u09f0\0\u0a25\0\65\0\u0a5a\0\u0a8f\0\u0ac4\0\u0af9\0\u0b2e"+
-    "\0\u0b63\0\u0b98\0\u0bcd\0\u0c02\0\u0c37\0\u0c6c\0\u0ca1\0\u0cd6"+
-    "\0\u0d0b\0\u0d40\0\u0d75\0\u0daa\0\u0ddf\0\u0e14\0\u0e49\0\u0e7e"+
-    "\0\u0eb3\0\u0ee8\0\u0f1d\0\u0f52\0\u0f87\0\u0fbc\0\u0ff1\0\u1026"+
-    "\0\u105b\0\u1090\0\u10c5\0\u10fa\0\u112f\0\u1164\0\u1199\0\u11ce"+
-    "\0\u1203\0\u1238\0\u126d\0\u12a2\0\u12d7\0\65\0\65\0\u130c"+
-    "\0\u1341\0\u1376\0\u13ab\0\u13e0\0\u1415\0\u144a\0\u147f\0\u14b4"+
-    "\0\u10fa\0\u14e9\0\u151e\0\65\0\u1553\0\u1588\0\u15bd\0\u15f2"+
-    "\0\u1627\0\u165c\0\u070a\0\u1691\0\u16c6\0\u16fb\0\u1730\0\u1765"+
-    "\0\u179a\0\u17cf\0\u1804\0\u1839\0\u147f\0\u186e\0\u18a3\0\u18d8"+
-    "\0\u190d\0\u1942\0\u1977\0\u19ac\0\u19e1\0\u1a16\0\u1a4b\0\u1a80"+
-    "\0\u1ab5\0\u1aea\0\u1b1f\0\u1b54\0\u1b89\0\u066b\0\u1bbe\0\u1bf3"+
-    "\0\u1c28\0\u1c5d\0\u1c92\0\u1cc7\0\u1cfc\0\u1d31\0\u1d66\0\u1d9b"+
-    "\0\u1dd0\0\u1e05\0\u1e3a\0\u1e6f\0\u1ea4\0\u1ed9\0\u1f0e\0\u1f43"+
-    "\0\u1f78\0\65\0\u1fad\0\u1fe2\0\u14e9\0\u151e\0\u2017\0\65"+
-    "\0\u204c\0\u2081\0\u20b6\0\u20eb\0\u2120\0\u2155\0\u218a\0\u21bf"+
-    "\0\u21f4\0\u20b6\0\u2229\0\u225e\0\u2293\0\u22c8\0\u22fd\0\u2332"+
-    "\0\u1ed9\0\u2367\0\u239c\0\u23d1\0\u2406\0\u243b\0\u2470\0\u24a5"+
-    "\0\u20eb\0\u24da\0\u250f\0\u2544\0\u2579\0\u25ae\0\u25e3\0\u2618"+
-    "\0\u264d\0\u2682\0\u26b7\0\u26ec\0\u2721\0\u2756\0\65\0\u278b"+
-    "\0\u27c0\0\u27f5\0\u282a\0\u285f\0\u2894\0\65\0\u28c9\0\u28fe"+
-    "\0\u2933\0\u070a\0\u2968\0\u299d\0\u29d2\0\65\0\u1f43\0\u1f78"+
-    "\0\u2a07\0\u2a3c\0\u2a71\0\u2aa6\0\u2adb\0\u218a\0\u2b10\0\u2b45"+
-    "\0\u2b7a\0\u2baf\0\u2be4\0\u21bf\0\u2c19\0\u2c4e\0\u2c83\0\65"+
-    "\0\u2cb8\0\u2ced\0\u2d22\0\u2d57\0\u2d8c\0\u2dc1\0\u2df6\0\u2e2b"+
-    "\0\u2e60\0\u2e95\0\u2eca\0\u2eff\0\u2f34\0\u2f69\0\u2f9e\0\u2fd3"+
-    "\0\u2682\0\u26b7\0\u3008\0\u303d\0\u3072\0\u30a7\0\u30dc\0\u3111"+
-    "\0\u3146\0\u317b\0\u31b0\0\u31e5\0\u321a\0\u324f\0\u3284\0\u32b9"+
-    "\0\u32ee\0\u3323\0\u3358\0\u338d\0\u2eff\0\u33c2\0\u33f7\0\u342c"+
-    "\0\u3461\0\u3496\0\u34cb\0\u3500\0\u3535\0\u356a\0\u359f\0\u35d4"+
-    "\0\u3609\0\u363e\0\u3673\0\u36a8\0\u36dd\0\u3712\0\u3747\0\u377c"+
-    "\0\u2f69\0\u37b1\0\u37e6\0\u381b\0\u2f9e\0\u3850\0\u3885\0\u38ba"+
-    "\0\u38ef\0\u3924\0\u3959\0\u398e\0\u39c3\0\u39f8\0\u3a2d\0\u3a62"+
-    "\0\u3a97\0\u3acc\0\u3b01\0\u3b36\0\u3b6b\0\u3ba0\0\u3bd5\0\u3c0a"+
-    "\0\u3c3f\0\u3c74\0\u3ca9\0\u3cde\0\u3d13\0\u3d48\0\u3d7d";
-
-  private static int [] zzUnpackRowMap() {
-    int [] result = new int[343];
-    int offset = 0;
-    offset = zzUnpackRowMap(ZZ_ROWMAP_PACKED_0, offset, result);
-    return result;
-  }
-
-  private static int zzUnpackRowMap(String packed, int offset, int [] result) {
-    int i = 0;  /* index in packed string  */
-    int j = offset;  /* index in unpacked array */
-    int l = packed.length();
-    while (i < l) {
-      int high = packed.charAt(i++) << 16;
-      result[j++] = high | packed.charAt(i++);
-    }
-    return j;
-  }
-
-  /** 
-   * The transition table of the DFA
-   */
-  private static final int [] ZZ_TRANS = zzUnpackTrans();
-
-  private static final String ZZ_TRANS_PACKED_0 =
-    "\1\2\1\3\1\4\1\5\1\2\1\5\2\6\1\2"+
-    "\1\7\1\10\1\11\1\12\1\13\1\2\1\14\1\15"+
-    "\2\6\1\2\1\16\1\17\5\6\1\20\1\21\1\22"+
-    "\1\23\1\16\1\24\1\25\1\16\1\26\1\2\1\27"+
-    "\1\16\7\6\1\16\5\6\1\2\66\0\1\3\1\30"+
-    "\1\31\1\0\1\31\3\6\2\0\1\6\1\32\3\0"+
-    "\3\6\1\33\1\34\1\0\5\6\1\35\13\0\7\6"+
-    "\1\0\5\6\1\36\1\0\1\37\1\6\1\0\2\6"+
-    "\1\37\40\6\1\37\1\6\3\37\1\6\1\37\7\6"+
-    "\3\0\1\5\1\0\1\5\26\0\1\21\1\22\30\0"+
-    "\1\6\1\30\1\31\1\0\1\31\3\6\2\0\1\6"+
-    "\4\0\3\6\1\33\1\34\1\0\5\6\1\35\13\0"+
-    "\7\6\1\0\5\6\1\0\2\40\1\41\6\40\1\42"+
-    "\53\40\2\43\1\44\7\43\1\42\52\43\1\0\1\45"+
-    "\1\46\3\0\2\45\3\0\1\47\4\0\3\45\3\0"+
-    "\5\45\14\0\7\45\1\0\5\45\2\0\1\50\64\0"+
-    "\1\51\1\52\3\0\1\51\2\53\2\0\1\53\4\0"+
-    "\3\53\3\0\5\53\14\0\1\51\1\53\3\51\1\53"+
-    "\1\51\1\0\5\53\2\0\1\6\1\30\1\31\1\0"+
-    "\1\31\3\6\2\0\1\6\4\0\1\6\1\54\1\6"+
-    "\1\33\1\34\1\0\5\6\1\35\13\0\7\6\1\55"+
-    "\5\6\2\0\1\56\1\57\3\0\2\56\10\0\3\56"+
-    "\3\0\1\60\1\61\1\62\2\56\14\0\4\56\1\63"+
-    "\1\56\1\64\1\0\5\56\4\0\1\21\1\0\1\21"+
-    "\62\0\1\22\1\0\1\22\116\0\1\65\66\0\1\66"+
-    "\26\0\1\67\1\0\1\67\20\0\1\70\102\0\1\71"+
-    "\64\0\1\72\23\0\1\31\1\0\1\31\16\0\1\34"+
-    "\6\0\1\35\32\0\1\73\1\74\1\34\1\0\1\34"+
-    "\2\73\10\0\3\73\3\0\5\73\14\0\7\73\1\0"+
-    "\5\73\2\0\1\75\1\30\1\6\1\0\1\6\1\75"+
-    "\2\6\2\0\1\6\4\0\3\6\1\33\1\34\1\0"+
-    "\5\6\1\35\13\0\1\75\1\6\3\75\1\6\1\75"+
-    "\1\0\5\6\1\0\2\40\1\41\6\40\1\76\53\40"+
-    "\2\43\1\44\7\43\1\77\52\43\1\0\1\45\1\46"+
-    "\1\100\1\0\1\100\3\45\2\0\1\45\4\0\3\45"+
-    "\3\0\5\45\13\0\1\101\7\45\1\0\5\45\2\0"+
-    "\1\102\1\45\1\0\2\45\1\102\40\45\1\102\1\45"+
-    "\3\102\1\45\1\102\7\45\42\0\1\103\23\0\1\50"+
-    "\17\0\1\104\4\0\1\105\1\106\1\107\17\0\1\110"+
-    "\1\111\1\112\2\0\1\113\2\0\1\36\1\114\1\0"+
-    "\1\115\1\36\1\0\1\116\1\52\3\0\1\116\2\53"+
-    "\2\0\1\53\4\0\3\53\3\0\5\53\14\0\1\116"+
-    "\1\53\3\116\1\53\1\116\1\0\5\53\2\0\1\117"+
-    "\1\53\1\0\2\53\1\117\40\53\1\117\1\53\3\117"+
-    "\1\53\1\117\7\53\1\0\1\53\1\52\3\0\3\53"+
-    "\2\0\1\53\4\0\3\53\3\0\5\53\14\0\7\53"+
-    "\1\0\5\53\2\0\1\6\1\30\1\31\1\0\1\31"+
-    "\3\6\2\0\1\6\4\0\2\6\1\120\1\33\1\34"+
-    "\1\0\5\6\1\35\13\0\7\6\1\0\5\6\2\0"+
-    "\1\121\4\0\1\121\7\0\1\122\30\0\1\121\1\0"+
-    "\3\121\1\0\1\121\10\0\1\56\1\57\3\0\3\56"+
-    "\2\0\1\56\4\0\3\56\3\0\5\56\14\0\7\56"+
-    "\1\0\5\56\2\0\1\123\1\56\1\0\2\56\1\123"+
-    "\40\56\1\123\1\56\3\123\1\56\1\123\7\56\1\0"+
-    "\1\56\1\57\3\0\3\56\2\0\1\56\4\0\3\56"+
-    "\3\0\1\56\1\124\3\56\14\0\7\56\1\0\5\56"+
-    "\2\0\1\56\1\57\3\0\3\56\2\0\1\56\4\0"+
-    "\3\56\3\0\5\56\14\0\2\56\1\125\4\56\1\0"+
-    "\5\56\2\0\1\56\1\57\3\0\3\56\2\0\1\56"+
-    "\4\0\3\56\3\0\5\56\14\0\1\126\6\56\1\0"+
-    "\5\56\2\0\1\56\1\57\3\0\3\56\2\0\1\56"+
-    "\4\0\3\56\3\0\3\56\1\127\1\56\14\0\7\56"+
-    "\1\0\5\56\2\0\1\56\1\57\3\0\3\56\2\0"+
-    "\1\56\4\0\3\56\3\0\5\56\14\0\7\56\1\0"+
-    "\2\56\1\130\2\56\1\0\37\65\1\131\25\65\13\0"+
-    "\1\132\100\0\1\133\36\0\1\73\1\74\1\31\1\0"+
-    "\1\31\3\73\2\0\1\73\4\0\3\73\1\0\1\34"+
-    "\1\0\5\73\1\35\13\0\7\73\1\0\5\73\2\0"+
-    "\1\134\1\73\1\0\2\73\1\134\40\73\1\134\1\73"+
-    "\3\134\1\73\1\134\7\73\1\0\1\135\1\30\1\6"+
-    "\1\0\1\6\1\135\2\6\2\0\1\6\4\0\3\6"+
-    "\1\33\1\34\1\0\5\6\1\35\13\0\1\135\1\6"+
-    "\3\135\1\6\1\135\1\0\5\6\4\0\1\100\1\0"+
-    "\1\100\40\0\1\101\21\0\1\101\1\0\1\101\12\0"+
-    "\1\136\45\0\1\137\1\46\1\45\1\0\1\45\1\137"+
-    "\2\45\2\0\1\45\4\0\3\45\3\0\5\45\13\0"+
-    "\1\101\1\137\1\45\3\137\1\45\1\137\1\0\5\45"+
-    "\50\0\1\140\71\0\1\36\37\0\1\36\30\0\1\36"+
-    "\61\0\1\36\1\0\1\36\26\0\1\104\72\0\1\36"+
-    "\27\0\1\36\56\0\1\141\42\0\1\36\117\0\1\36"+
-    "\63\0\1\114\4\0\1\142\1\52\3\0\1\142\2\53"+
-    "\2\0\1\53\4\0\3\53\3\0\5\53\14\0\1\142"+
-    "\1\53\3\142\1\53\1\142\1\0\5\53\2\0\1\143"+
-    "\1\52\1\53\1\0\1\53\1\143\2\53\2\0\1\53"+
-    "\4\0\3\53\3\0\5\53\14\0\1\143\1\53\3\143"+
-    "\1\53\1\143\1\0\5\53\2\0\1\6\1\30\1\31"+
-    "\1\0\1\31\3\6\2\0\1\6\4\0\3\6\1\144"+
-    "\1\34\1\0\5\6\1\35\13\0\7\6\1\0\5\6"+
-    "\2\0\1\145\4\0\1\145\4\0\1\146\2\0\1\147"+
-    "\30\0\1\145\1\0\3\145\1\0\1\145\25\0\1\147"+
-    "\47\0\1\150\1\57\1\56\1\0\1\56\1\150\2\56"+
-    "\2\0\1\56\4\0\3\56\3\0\5\56\14\0\1\150"+
-    "\1\56\3\150\1\56\1\150\1\0\5\56\2\0\1\56"+
-    "\1\57\3\0\3\56\2\0\1\56\4\0\3\56\3\0"+
-    "\2\56\1\151\2\56\14\0\7\56\1\0\5\56\2\0"+
-    "\1\56\1\57\3\0\3\56\2\0\1\56\4\0\3\56"+
-    "\3\0\5\56\14\0\3\56\1\152\3\56\1\0\5\56"+
-    "\2\0\1\56\1\57\3\0\3\56\2\0\1\56\4\0"+
-    "\3\56\3\0\5\56\14\0\1\56\1\153\5\56\1\0"+
-    "\5\56\2\0\1\56\1\57\3\0\3\56\2\0\1\56"+
-    "\4\0\3\56\3\0\5\56\14\0\5\56\1\154\1\56"+
-    "\1\0\5\56\2\0\1\56\1\57\3\0\3\56\2\0"+
-    "\1\56\4\0\3\56\3\0\5\56\14\0\1\155\6\56"+
-    "\1\0\5\56\1\0\36\65\1\156\1\131\25\65\13\0"+
-    "\1\157\101\0\1\160\35\0\1\161\1\74\1\73\1\0"+
-    "\1\73\1\161\2\73\2\0\1\73\4\0\3\73\1\0"+
-    "\1\34\1\0\5\73\1\35\13\0\1\161\1\73\3\161"+
-    "\1\73\1\161\1\0\5\73\2\0\1\162\1\30\1\6"+
-    "\1\0\1\6\1\162\2\6\2\0\1\6\4\0\3\6"+
-    "\1\33\1\34\1\0\5\6\1\35\13\0\1\162\1\6"+
-    "\3\162\1\6\1\162\1\0\5\6\22\0\1\163\44\0"+
-    "\1\164\1\46\1\45\1\0\1\45\1\164\2\45\2\0"+
-    "\1\45\4\0\3\45\3\0\5\45\13\0\1\101\1\164"+
-    "\1\45\3\164\1\45\1\164\1\0\5\45\53\0\1\36"+
-    "\62\0\1\36\15\0\1\165\1\52\3\0\1\165\2\53"+
-    "\2\0\1\53\4\0\3\53\3\0\5\53\14\0\1\165"+
-    "\1\53\3\165\1\53\1\165\1\0\5\53\2\0\1\166"+
-    "\1\52\1\53\1\0\1\53\1\166\2\53\2\0\1\53"+
-    "\4\0\3\53\3\0\5\53\14\0\1\166\1\53\3\166"+
-    "\1\53\1\166\1\0\5\53\1\0\2\167\1\170\1\171"+
-    "\1\167\1\171\3\167\1\172\1\173\2\167\1\174\5\167"+
-    "\1\0\41\167\1\0\1\175\4\0\1\175\4\0\1\146"+
-    "\2\0\1\176\30\0\1\175\1\0\3\175\1\0\1\175"+
-    "\10\0\1\177\4\0\1\177\40\0\1\177\1\0\3\177"+
-    "\1\0\1\177\25\0\1\176\47\0\1\200\1\57\1\56"+
-    "\1\0\1\56\1\200\2\56\2\0\1\56\4\0\3\56"+
-    "\3\0\5\56\14\0\1\200\1\56\3\200\1\56\1\200"+
-    "\1\0\5\56\2\0\1\56\1\57\3\0\3\56\2\0"+
-    "\1\56\4\0\3\56\3\0\3\56\1\201\1\56\14\0"+
-    "\7\56\1\0\5\56\2\0\1\56\1\57\3\0\3\56"+
-    "\2\0\1\56\4\0\3\56\3\0\1\202\4\56\14\0"+
-    "\7\56\1\0\5\56\2\0\1\56\1\57\3\0\3\56"+
-    "\2\0\1\56\4\0\3\56\3\0\5\56\14\0\2\56"+
-    "\1\203\4\56\1\0\5\56\2\0\1\56\1\57\3\0"+
-    "\3\56\2\0\1\56\4\0\3\56\3\0\4\56\1\204"+
-    "\14\0\7\56\1\0\5\56\2\0\1\56\1\57\3\0"+
-    "\3\56\2\0\1\56\4\0\1\56\1\205\1\56\3\0"+
-    "\5\56\14\0\7\56\1\0\5\56\32\0\1\206\34\0"+
-    "\1\207\1\74\1\73\1\0\1\73\1\207\2\73\2\0"+
-    "\1\73\4\0\3\73\1\0\1\34\1\0\5\73\1\35"+
-    "\13\0\1\207\1\73\3\207\1\73\1\207\1\0\5\73"+
-    "\2\0\1\210\1\30\1\6\1\0\1\6\1\210\2\6"+
-    "\2\0\1\6\4\0\3\6\1\33\1\34\1\0\5\6"+
-    "\1\35\13\0\1\210\1\6\3\210\1\6\1\210\1\0"+
-    "\5\6\23\0\1\211\43\0\1\212\1\46\1\45\1\0"+
-    "\1\45\1\212\2\45\2\0\1\45\4\0\3\45\3\0"+
-    "\5\45\13\0\1\101\1\212\1\45\3\212\1\45\1\212"+
-    "\1\0\5\45\2\0\1\213\1\52\3\0\1\213\2\53"+
-    "\2\0\1\53\4\0\3\53\3\0\5\53\14\0\1\213"+
-    "\1\53\3\213\1\53\1\213\1\0\5\53\2\0\1\214"+
-    "\1\52\1\53\1\0\1\53\1\214\2\53\2\0\1\53"+
-    "\4\0\3\53\3\0\5\53\14\0\1\214\1\53\3\214"+
-    "\1\53\1\214\1\0\5\53\1\0\2\167\1\170\6\167"+
-    "\2\0\2\167\1\174\5\167\1\0\43\167\1\170\12\167"+
-    "\1\215\47\167\2\172\1\216\6\172\1\217\53\172\2\173"+
-    "\1\220\7\173\1\217\52\173\1\0\1\221\4\0\1\221"+
-    "\4\0\1\146\2\0\1\222\30\0\1\221\1\0\3\221"+
-    "\1\0\1\221\25\0\1\222\47\0\1\223\4\0\1\223"+
-    "\40\0\1\223\1\0\3\223\1\0\1\223\10\0\1\224"+
-    "\1\57\1\56\1\0\1\56\1\224\2\56\2\0\1\56"+
-    "\4\0\3\56\3\0\5\56\14\0\1\224\1\56\3\224"+
-    "\1\56\1\224\1\0\5\56\2\0\1\56\1\57\3\0"+
-    "\3\56\2\0\1\56\4\0\1\56\1\225\1\56\3\0"+
-    "\5\56\14\0\7\56\1\0\5\56\2\0\1\56\1\57"+
-    "\3\0\3\56\2\0\1\56\4\0\3\56\3\0\5\56"+
-    "\14\0\1\226\6\56\1\0\5\56\2\0\1\56\1\57"+
-    "\3\0\3\56\2\0\1\227\4\0\3\56\3\0\5\56"+
-    "\14\0\7\56\1\0\5\56\2\0\1\56\1\57\3\0"+
-    "\3\56\2\0\1\56\4\0\3\56\3\0\5\56\14\0"+
-    "\7\56\1\0\1\56\1\230\3\56\22\0\1\231\44\0"+
-    "\1\232\1\74\1\73\1\0\1\73\1\232\2\73\2\0"+
-    "\1\73\4\0\3\73\1\0\1\34\1\0\5\73\1\35"+
-    "\13\0\1\232\1\73\3\232\1\73\1\232\1\0\5\73"+
-    "\2\0\1\233\1\30\1\6\1\0\1\6\1\233\2\6"+
-    "\2\0\1\6\4\0\3\6\1\33\1\34\1\0\5\6"+
-    "\1\35\13\0\1\233\1\6\3\233\1\6\1\233\1\0"+
-    "\5\6\24\0\1\234\42\0\1\235\1\46\1\45\1\0"+
-    "\1\45\1\235\2\45\2\0\1\45\4\0\3\45\3\0"+
-    "\5\45\13\0\1\101\1\235\1\45\3\235\1\45\1\235"+
-    "\1\0\5\45\2\0\1\236\1\52\3\0\1\236\2\53"+
-    "\2\0\1\53\4\0\3\53\3\0\5\53\14\0\1\236"+
-    "\1\53\3\236\1\53\1\236\1\0\5\53\2\0\1\237"+
-    "\1\52\1\53\1\0\1\53\1\237\2\53\2\0\1\53"+
-    "\4\0\3\53\3\0\5\53\14\0\1\237\1\53\3\237"+
-    "\1\53\1\237\1\0\5\53\1\0\2\172\1\216\6\172"+
-    "\1\240\53\172\3\0\1\217\1\0\1\217\7\0\1\174"+
-    "\47\0\2\173\1\220\7\173\1\241\52\173\1\0\1\242"+
-    "\4\0\1\242\4\0\1\146\2\0\1\243\30\0\1\242"+
-    "\1\0\3\242\1\0\1\242\25\0\1\243\47\0\1\244"+
-    "\4\0\1\244\40\0\1\244\1\0\3\244\1\0\1\244"+
-    "\10\0\1\245\1\57\1\56\1\0\1\56\1\245\2\56"+
-    "\2\0\1\56\4\0\3\56\3\0\5\56\14\0\1\245"+
-    "\1\56\3\245\1\56\1\245\1\0\5\56\2\0\1\56"+
-    "\1\57\3\0\3\56\2\0\1\56\4\0\3\56\3\0"+
-    "\4\56\1\246\14\0\7\56\1\0\5\56\2\0\1\247"+
-    "\1\250\1\251\1\0\1\251\2\247\1\56\2\0\1\56"+
-    "\4\0\3\247\3\0\5\247\14\0\7\247\1\0\5\247"+
-    "\2\0\1\56\1\57\3\0\3\56\2\0\1\56\4\0"+
-    "\3\56\3\0\5\56\14\0\4\56\1\252\2\56\1\0"+
-    "\5\56\2\0\1\56\1\57\3\0\3\56\2\0\1\56"+
-    "\4\0\3\56\3\0\5\56\14\0\2\56\1\253\4\56"+
-    "\1\0\5\56\33\0\1\254\33\0\1\255\1\74\1\73"+
-    "\1\0\1\73\1\255\2\73\2\0\1\73\4\0\3\73"+
-    "\1\0\1\34\1\0\5\73\1\35\13\0\1\255\1\73"+
-    "\3\255\1\73\1\255\1\0\5\73\2\0\1\6\1\30"+
-    "\1\6\1\0\4\6\2\0\1\6\4\0\3\6\1\33"+
-    "\1\34\1\0\5\6\1\35\13\0\7\6\1\0\5\6"+
-    "\1\0\2\256\1\257\1\234\1\256\1\234\3\256\1\260"+
-    "\1\261\2\256\1\262\5\256\1\0\41\256\1\0\1\263"+
-    "\1\46\1\45\1\0\1\45\1\263\2\45\2\0\1\45"+
-    "\4\0\3\45\3\0\5\45\13\0\1\101\1\263\1\45"+
-    "\3\263\1\45\1\263\1\0\5\45\2\0\1\264\1\52"+
-    "\1\53\1\0\1\53\1\264\2\53\2\0\1\53\4\0"+
-    "\3\53\3\0\5\53\14\0\1\264\1\53\3\264\1\53"+
-    "\1\264\1\0\5\53\1\0\2\172\1\216\1\240\1\172"+
-    "\1\240\3\172\1\217\3\172\1\265\47\172\2\173\1\220"+
-    "\1\241\1\173\1\241\4\173\1\217\2\173\1\266\47\173"+
-    "\1\0\1\267\4\0\1\267\4\0\1\146\2\0\1\270"+
-    "\30\0\1\267\1\0\3\267\1\0\1\267\25\0\1\270"+
-    "\47\0\1\271\4\0\1\271\40\0\1\271\1\0\3\271"+
-    "\1\0\1\271\10\0\1\272\1\57\1\56\1\0\1\56"+
-    "\1\272\2\56\2\0\1\56\4\0\3\56\3\0\5\56"+
-    "\14\0\1\272\1\56\3\272\1\56\1\272\1\0\5\56"+
-    "\1\0\1\273\1\274\1\275\1\276\1\273\1\276\3\274"+
-    "\1\277\1\300\1\274\1\273\1\0\2\273\1\301\2\274"+
-    "\1\0\2\273\5\274\1\302\13\273\7\274\1\273\5\274"+
-    "\1\273\1\0\1\247\1\250\1\303\1\0\1\303\3\247"+
-    "\2\0\1\247\4\0\3\247\1\0\1\251\1\0\5\247"+
-    "\14\0\7\247\1\0\5\247\2\0\1\304\1\247\1\0"+
-    "\2\247\1\304\40\247\1\304\1\247\3\304\1\247\1\304"+
-    "\7\247\1\0\1\247\1\250\1\251\1\0\1\251\2\247"+
-    "\10\0\3\247\3\0\5\247\14\0\7\247\1\0\5\247"+
-    "\2\0\1\56\1\57\3\0\3\56\2\0\1\56\4\0"+
-    "\3\56\3\0\5\56\14\0\1\305\6\56\1\0\5\56"+
-    "\2\0\1\56\1\57\3\0\3\56\2\0\1\56\4\0"+
-    "\3\56\3\0\4\56\1\306\14\0\7\56\1\0\5\56"+
-    "\50\0\1\307\16\0\1\310\1\74\1\73\1\0\1\73"+
-    "\1\310\2\73\2\0\1\73\4\0\3\73\1\0\1\34"+
-    "\1\0\5\73\1\35\13\0\1\310\1\73\3\310\1\73"+
-    "\1\310\1\0\5\73\1\0\2\256\1\257\6\256\2\0"+
-    "\2\256\1\262\5\256\1\0\43\256\1\257\12\256\1\311"+
-    "\47\256\2\260\1\312\6\260\1\313\53\260\2\261\1\314"+
-    "\7\261\1\313\52\261\1\0\1\45\1\46\1\45\1\0"+
-    "\4\45\2\0\1\45\4\0\3\45\3\0\5\45\13\0"+
-    "\1\101\7\45\1\0\5\45\2\0\1\53\1\52\1\53"+
-    "\1\0\4\53\2\0\1\53\4\0\3\53\3\0\5\53"+
-    "\14\0\7\53\1\0\5\53\14\0\1\146\52\0\1\315"+
-    "\4\0\1\315\40\0\1\315\1\0\3\315\1\0\1\315"+
-    "\10\0\1\56\1\57\1\56\1\0\4\56\2\0\1\56"+
-    "\4\0\3\56\3\0\5\56\14\0\7\56\1\0\5\56"+
-    "\1\0\2\273\1\316\6\273\2\0\2\273\1\0\5\273"+
-    "\1\0\7\273\1\302\32\273\1\274\1\275\3\273\3\274"+
-    "\2\0\1\274\1\273\1\0\2\273\3\274\1\0\2\273"+
-    "\5\274\1\302\13\273\7\274\1\273\5\274\2\273\1\317"+
-    "\1\320\1\273\2\274\1\317\24\274\1\321\13\274\1\317"+
-    "\1\274\3\317\1\274\1\317\7\274\2\273\1\316\1\276"+
-    "\1\273\1\276\3\273\1\277\1\300\2\273\1\0\2\273"+
-    "\1\322\2\273\1\0\7\273\1\302\31\273\2\277\1\323"+
-    "\6\277\1\324\53\277\2\300\1\325\7\300\1\324\52\300"+
-    "\1\273\1\274\1\275\3\273\3\274\2\0\1\274\1\273"+
-    "\1\0\2\273\1\274\1\326\1\274\1\0\2\273\5\274"+
-    "\1\302\13\273\7\274\1\273\5\274\1\273\3\0\1\303"+
-    "\1\0\1\303\16\0\1\251\41\0\1\327\1\250\1\247"+
-    "\1\0\1\247\1\327\2\247\2\0\1\247\4\0\3\247"+
-    "\1\0\1\251\1\0\5\247\14\0\1\327\1\247\3\327"+
-    "\1\247\1\327\1\0\5\247\2\0\1\56\1\57\3\0"+
-    "\3\56\2\0\1\56\4\0\3\56\3\0\5\56\14\0"+
-    "\6\56\1\330\1\0\5\56\2\0\1\56\1\57\1\331"+
-    "\1\0\1\331\3\56\1\332\1\333\1\56\4\0\3\56"+
-    "\3\0\5\56\14\0\7\56\1\0\5\56\55\0\1\334"+
-    "\11\0\1\73\1\74\1\73\1\0\4\73\2\0\1\73"+
-    "\4\0\3\73\1\0\1\34\1\0\5\73\1\35\13\0"+
-    "\7\73\1\0\5\73\1\0\2\260\1\312\6\260\1\335"+
-    "\53\260\3\0\1\313\1\0\1\313\7\0\1\262\47\0"+
-    "\2\261\1\314\7\261\1\336\52\261\1\0\1\337\4\0"+
-    "\1\337\40\0\1\337\1\0\3\337\1\0\1\337\7\0"+
-    "\2\273\1\316\30\273\1\302\32\273\1\340\1\275\1\274"+
-    "\1\273\1\274\1\340\2\274\2\0\1\274\1\273\1\0"+
-    "\2\273\3\274\1\0\2\273\5\274\1\302\13\273\1\340"+
-    "\1\274\3\340\1\274\1\340\1\273\5\274\2\273\1\274"+
-    "\1\275\3\273\3\274\2\273\1\274\4\273\3\274\3\273"+
-    "\5\274\1\302\13\273\7\274\1\273\5\274\3\273\1\316"+
-    "\6\273\2\0\2\273\1\0\3\273\1\341\1\273\1\0"+
-    "\7\273\1\302\31\273\2\277\1\323\6\277\1\342\53\277"+
-    "\1\0\1\343\1\344\1\345\1\0\1\345\2\343\10\0"+
-    "\3\343\3\0\5\343\1\346\13\0\7\343\1\0\5\343"+
-    "\1\0\2\300\1\325\7\300\1\347\52\300\1\273\1\274"+
-    "\1\275\3\273\3\274\2\0\1\274\1\273\1\0\2\273"+
-    "\2\274\1\350\1\0\2\273\5\274\1\302\13\273\7\274"+
-    "\1\273\5\274\1\273\1\0\1\351\1\250\1\247\1\0"+
-    "\1\247\1\351\2\247\2\0\1\247\4\0\3\247\1\0"+
-    "\1\251\1\0\5\247\14\0\1\351\1\247\3\351\1\247"+
-    "\1\351\1\0\5\247\2\0\1\56\1\57\3\0\3\56"+
-    "\2\0\1\56\4\0\3\56\3\0\5\56\14\0\2\56"+
-    "\1\352\4\56\1\0\5\56\4\0\1\331\1\0\1\331"+
-    "\3\0\1\332\1\333\52\0\2\332\1\353\6\332\1\354"+
-    "\53\332\2\333\1\355\7\333\1\354\52\333\32\0\1\356"+
-    "\32\0\2\260\1\312\1\335\1\260\1\335\3\260\1\313"+
-    "\3\260\1\357\47\260\2\261\1\314\1\336\1\261\1\336"+
-    "\4\261\1\313\2\261\1\360\47\261\1\273\1\361\1\275"+
-    "\1\274\1\273\1\274\1\361\2\274\2\0\1\274\1\273"+
-    "\1\0\2\273\3\274\1\0\2\273\5\274\1\302\13\273"+
-    "\1\361\1\274\3\361\1\274\1\361\1\273\5\274\3\273"+
-    "\1\316\6\273\2\0\2\273\1\0\4\273\1\362\1\0"+
-    "\7\273\1\302\31\273\1\277\1\363\1\364\1\365\1\277"+
-    "\1\365\2\363\1\277\1\324\6\277\3\363\3\277\5\363"+
-    "\1\366\13\277\7\363\1\277\5\363\1\277\1\0\1\343"+
-    "\1\344\1\367\1\0\1\367\3\343\2\0\1\343\4\0"+
-    "\3\343\1\0\1\345\1\0\5\343\1\346\13\0\7\343"+
-    "\1\0\5\343\2\0\1\370\1\343\1\0\2\343\1\370"+
-    "\40\343\1\370\1\343\3\370\1\343\1\370\7\343\1\0"+
-    "\1\343\1\344\1\345\1\0\1\345\2\343\10\0\3\343"+
-    "\3\0\5\343\14\0\7\343\1\0\5\343\1\0\1\300"+
-    "\1\371\1\372\1\373\1\300\1\373\2\371\2\300\1\324"+
-    "\5\300\3\371\3\300\5\371\1\374\13\300\7\371\1\300"+
-    "\5\371\1\300\1\273\1\274\1\275\3\273\3\274\2\0"+
-    "\1\274\1\273\1\0\2\273\3\274\1\375\2\273\5\274"+
-    "\1\302\13\273\7\274\1\273\5\274\1\273\1\0\1\376"+
-    "\1\250\1\247\1\0\1\247\1\376\2\247\2\0\1\247"+
-    "\4\0\3\247\1\0\1\251\1\0\5\247\14\0\1\376"+
-    "\1\247\3\376\1\247\1\376\1\0\5\247\1\0\2\332"+
-    "\1\353\6\332\1\377\53\332\3\0\1\354\1\0\1\354"+
-    "\25\0\1\u0100\31\0\2\333\1\355\7\333\1\u0101\52\333"+
-    "\1\273\1\u0102\1\275\1\274\1\273\1\274\1\u0102\2\274"+
-    "\2\0\1\274\1\273\1\0\2\273\3\274\1\0\2\273"+
-    "\5\274\1\302\13\273\1\u0102\1\274\3\u0102\1\274\1\u0102"+
-    "\1\273\5\274\3\273\1\316\6\273\2\0\2\273\1\0"+
-    "\5\273\1\375\7\273\1\302\31\273\1\277\1\363\1\364"+
-    "\1\u0103\1\277\1\u0103\3\363\1\324\1\277\1\363\4\277"+
-    "\3\363\1\277\1\365\1\277\5\363\1\366\13\277\7\363"+
-    "\1\277\5\363\2\277\1\u0104\1\u0105\1\277\2\363\1\u0104"+
-    "\2\363\1\u0106\35\363\1\u0104\1\363\3\u0104\1\363\1\u0104"+
-    "\7\363\1\277\1\363\1\364\1\365\1\277\1\365\2\363"+
-    "\1\277\1\324\6\277\3\363\3\277\5\363\14\277\7\363"+
-    "\1\277\5\363\1\277\3\0\1\367\1\0\1\367\16\0"+
-    "\1\345\6\0\1\346\32\0\1\u0107\1\344\1\343\1\0"+
-    "\1\343\1\u0107\2\343\2\0\1\343\4\0\3\343\1\0"+
-    "\1\345\1\0\5\343\1\346\13\0\1\u0107\1\343\3\u0107"+
-    "\1\343\1\u0107\1\0\5\343\1\0\1\300\1\371\1\372"+
-    "\1\u0108\1\300\1\u0108\3\371\1\300\1\324\1\371\4\300"+
-    "\3\371\1\300\1\373\1\300\5\371\1\374\13\300\7\371"+
-    "\1\300\5\371\2\300\1\u0109\1\u010a\1\300\2\371\1\u0109"+
-    "\3\371\1\u010b\34\371\1\u0109\1\371\3\u0109\1\371\1\u0109"+
-    "\7\371\1\300\1\371\1\372\1\373\1\300\1\373\2\371"+
-    "\2\300\1\324\5\300\3\371\3\300\5\371\14\300\7\371"+
-    "\1\300\5\371\1\300\2\u010c\1\u010d\1\375\1\u010c\1\375"+
-    "\3\u010c\1\u010e\1\u010f\2\u010c\1\324\5\u010c\1\0\41\u010c"+
-    "\1\0\1\u0110\1\250\1\247\1\0\1\247\1\u0110\2\247"+
-    "\2\0\1\247\4\0\3\247\1\0\1\251\1\0\5\247"+
-    "\14\0\1\u0110\1\247\3\u0110\1\247\1\u0110\1\0\5\247"+
-    "\1\0\2\332\1\353\1\377\1\332\1\377\3\332\1\354"+
-    "\21\332\1\u0111\31\332\2\333\1\355\1\u0101\1\333\1\u0101"+
-    "\4\333\1\354\20\333\1\u0112\31\333\1\273\1\u0113\1\275"+
-    "\1\274\1\273\1\274\1\u0113\2\274\2\0\1\274\1\273"+
-    "\1\0\2\273\3\274\1\0\2\273\5\274\1\302\13\273"+
-    "\1\u0113\1\274\3\u0113\1\274\1\u0113\1\273\5\274\1\273"+
-    "\2\277\1\323\1\u0103\1\277\1\u0103\3\277\1\324\12\277"+
-    "\1\365\6\277\1\366\32\277\1\u0114\1\364\1\363\1\277"+
-    "\1\363\1\u0114\2\363\1\324\1\277\1\363\4\277\3\363"+
-    "\1\277\1\365\1\277\5\363\1\366\13\277\1\u0114\1\363"+
-    "\3\u0114\1\363\1\u0114\1\277\5\363\2\277\1\363\1\364"+
-    "\1\u0103\1\277\1\u0103\3\363\1\342\1\277\1\363\4\277"+
-    "\3\363\1\277\1\365\1\277\5\363\1\366\13\277\7\363"+
-    "\1\277\5\363\2\277\1\363\1\364\1\u0115\1\277\1\u0115"+
-    "\3\363\1\324\1\277\1\363\4\277\3\363\1\277\1\365"+
-    "\1\277\5\363\1\366\13\277\7\363\1\277\5\363\1\277"+
-    "\1\0\1\u0116\1\344\1\343\1\0\1\343\1\u0116\2\343"+
-    "\2\0\1\343\4\0\3\343\1\0\1\345\1\0\5\343"+
-    "\1\346\13\0\1\u0116\1\343\3\u0116\1\343\1\u0116\1\0"+
-    "\5\343\1\0\2\300\1\325\1\u0108\1\300\1\u0108\4\300"+
-    "\1\324\11\300\1\373\6\300\1\374\32\300\1\u0117\1\372"+
-    "\1\371\1\300\1\371\1\u0117\2\371\1\300\1\324\1\371"+
-    "\4\300\3\371\1\300\1\373\1\300\5\371\1\374\13\300"+
-    "\1\u0117\1\371\3\u0117\1\371\1\u0117\1\300\5\371\2\300"+
-    "\1\371\1\372\1\u0108\1\300\1\u0108\3\371\1\300\1\347"+
-    "\1\371\4\300\3\371\1\300\1\373\1\300\5\371\1\374"+
-    "\13\300\7\371\1\300\5\371\2\300\1\371\1\372\1\u0118"+
-    "\1\300\1\u0118\3\371\1\300\1\324\1\371\4\300\3\371"+
-    "\1\300\1\373\1\300\5\371\1\374\13\300\7\371\1\300"+
-    "\5\371\1\300\2\u010c\1\u010d\6\u010c\2\0\2\u010c\1\324"+
-    "\5\u010c\1\0\43\u010c\1\u010d\12\u010c\1\u0119\47\u010c\2\u010e"+
-    "\1\u011a\6\u010e\1\u011b\53\u010e\2\u010f\1\u011c\7\u010f\1\u011b"+
-    "\52\u010f\1\0\1\u011d\1\250\1\247\1\0\1\247\1\u011d"+
-    "\2\247\2\0\1\247\4\0\3\247\1\0\1\251\1\0"+
-    "\5\247\14\0\1\u011d\1\247\3\u011d\1\247\1\u011d\1\0"+
-    "\5\247\1\0\1\273\1\u011e\1\275\1\274\1\273\1\274"+
-    "\1\u011e\2\274\2\0\1\274\1\273\1\0\2\273\3\274"+
-    "\1\0\2\273\5\274\1\302\13\273\1\u011e\1\274\3\u011e"+
-    "\1\274\1\u011e\1\273\5\274\1\273\1\277\1\u011f\1\364"+
-    "\1\363\1\277\1\363\1\u011f\2\363\1\324\1\277\1\363"+
-    "\4\277\3\363\1\277\1\365\1\277\5\363\1\366\13\277"+
-    "\1\u011f\1\363\3\u011f\1\363\1\u011f\1\277\5\363\2\277"+
-    "\1\363\1\364\1\u0115\1\277\1\u0115\2\363\1\277\1\324"+
-    "\6\277\3\363\1\277\1\365\1\277\5\363\1\366\13\277"+
-    "\7\363\1\277\5\363\1\277\1\0\1\u0120\1\344\1\343"+
-    "\1\0\1\343\1\u0120\2\343\2\0\1\343\4\0\3\343"+
-    "\1\0\1\345\1\0\5\343\1\346\13\0\1\u0120\1\343"+
-    "\3\u0120\1\343\1\u0120\1\0\5\343\1\0\1\300\1\u0121"+
-    "\1\372\1\371\1\300\1\371\1\u0121\2\371\1\300\1\324"+
-    "\1\371\4\300\3\371\1\300\1\373\1\300\5\371\1\374"+
-    "\13\300\1\u0121\1\371\3\u0121\1\371\1\u0121\1\300\5\371"+
-    "\2\300\1\371\1\372\1\u0118\1\300\1\u0118\2\371\2\300"+
-    "\1\324\5\300\3\371\1\300\1\373\1\300\5\371\1\374"+
-    "\13\300\7\371\1\300\5\371\1\300\1\u010c\1\u0122\1\u0123"+
-    "\1\u0124\1\u010c\1\u0124\2\u0122\1\u010c\2\0\2\u010c\1\324"+
-    "\2\u010c\3\u0122\1\0\2\u010c\5\u0122\1\u0125\13\u010c\7\u0122"+
-    "\1\u010c\5\u0122\1\u010c\2\u010e\1\u011a\6\u010e\1\u0126\53\u010e"+
-    "\3\0\1\u011b\1\0\1\u011b\7\0\1\324\47\0\2\u010f"+
-    "\1\u011c\7\u010f\1\u0127\52\u010f\1\0\1\247\1\250\1\247"+
-    "\1\0\4\247\2\0\1\247\4\0\3\247\1\0\1\251"+
-    "\1\0\5\247\14\0\7\247\1\0\5\247\1\0\1\273"+
-    "\1\274\1\275\1\274\1\273\4\274\2\0\1\274\1\273"+
-    "\1\0\2\273\3\274\1\0\2\273\5\274\1\302\13\273"+
-    "\7\274\1\273\5\274\1\273\1\277\1\u0128\1\364\1\363"+
-    "\1\277\1\363\1\u0128\2\363\1\324\1\277\1\363\4\277"+
-    "\3\363\1\277\1\365\1\277\5\363\1\366\13\277\1\u0128"+
-    "\1\363\3\u0128\1\363\1\u0128\1\277\5\363\1\277\1\0"+
-    "\1\u0129\1\344\1\343\1\0\1\343\1\u0129\2\343\2\0"+
-    "\1\343\4\0\3\343\1\0\1\345\1\0\5\343\1\346"+
-    "\13\0\1\u0129\1\343\3\u0129\1\343\1\u0129\1\0\5\343"+
-    "\1\0\1\300\1\u012a\1\372\1\371\1\300\1\371\1\u012a"+
-    "\2\371\1\300\1\324\1\371\4\300\3\371\1\300\1\373"+
-    "\1\300\5\371\1\374\13\300\1\u012a\1\371\3\u012a\1\371"+
-    "\1\u012a\1\300\5\371\1\300\1\u010c\1\u0122\1\u0123\1\u012b"+
-    "\1\u010c\1\u012b\3\u0122\2\0\1\u0122\1\u010c\1\324\2\u010c"+
-    "\3\u0122\1\0\1\u0124\1\u010c\5\u0122\1\u0125\13\u010c\7\u0122"+
-    "\1\u010c\5\u0122\2\u010c\1\u012c\1\u012d\1\u010c\2\u0122\1\u012c"+
-    "\6\u0122\1\u012e\31\u0122\1\u012c\1\u0122\3\u012c\1\u0122\1\u012c"+
-    "\7\u0122\1\u010c\1\u0122\1\u0123\1\u0124\1\u010c\1\u0124\2\u0122"+
-    "\1\u010c\2\0\2\u010c\1\324\2\u010c\3\u0122\1\0\2\u010c"+
-    "\5\u0122\14\u010c\7\u0122\1\u010c\5\u0122\1\u010c\2\u010e\1\u011a"+
-    "\1\u0126\1\u010e\1\u0126\3\u010e\1\u011b\3\u010e\1\u012f\47\u010e"+
-    "\2\u010f\1\u011c\1\u0127\1\u010f\1\u0127\4\u010f\1\u011b\2\u010f"+
-    "\1\u0130\47\u010f\1\277\1\u0131\1\364\1\363\1\277\1\363"+
-    "\1\u0131\2\363\1\324\1\277\1\363\4\277\3\363\1\277"+
-    "\1\365\1\277\5\363\1\366\13\277\1\u0131\1\363\3\u0131"+
-    "\1\363\1\u0131\1\277\5\363\1\277\1\0\1\u0132\1\344"+
-    "\1\343\1\0\1\343\1\u0132\2\343\2\0\1\343\4\0"+
-    "\3\343\1\0\1\345\1\0\5\343\1\346\13\0\1\u0132"+
-    "\1\343\3\u0132\1\343\1\u0132\1\0\5\343\1\0\1\300"+
-    "\1\u0133\1\372\1\371\1\300\1\371\1\u0133\2\371\1\300"+
-    "\1\324\1\371\4\300\3\371\1\300\1\373\1\300\5\371"+
-    "\1\374\13\300\1\u0133\1\371\3\u0133\1\371\1\u0133\1\300"+
-    "\5\371\1\300\2\u010c\1\u010d\1\u012b\1\u010c\1\u012b\3\u010c"+
-    "\2\0\2\u010c\1\324\5\u010c\1\0\1\u0124\6\u010c\1\u0125"+
-    "\32\u010c\1\u0134\1\u0123\1\u0122\1\u010c\1\u0122\1\u0134\2\u0122"+
-    "\2\0\1\u0122\1\u010c\1\324\2\u010c\3\u0122\1\0\1\u0124"+
-    "\1\u010c\5\u0122\1\u0125\13\u010c\1\u0134\1\u0122\3\u0134\1\u0122"+
-    "\1\u0134\1\u010c\5\u0122\2\u010c\1\u0122\1\u0123\1\u012b\1\u010c"+
-    "\1\u012b\3\u0122\2\u010c\1\u0122\1\u010c\1\u0119\2\u010c\3\u0122"+
-    "\1\u010c\1\u0124\1\u010c\5\u0122\1\u0125\13\u010c\7\u0122\1\u010c"+
-    "\5\u0122\2\u010c\1\u0122\1\u0123\1\u0135\1\u010c\1\u0135\3\u0122"+
-    "\2\0\1\u0122\1\u010c\1\324\2\u010c\3\u0122\1\0\1\u0124"+
-    "\1\u010c\5\u0122\1\u0125\13\u010c\7\u0122\1\u010c\5\u0122\1\u010c"+
-    "\1\u010e\1\u0136\1\u0137\1\u0138\1\u010e\1\u0138\2\u0136\1\u010e"+
-    "\1\u011b\6\u010e\3\u0136\3\u010e\5\u0136\1\u0139\13\u010e\7\u0136"+
-    "\1\u010e\5\u0136\1\u010e\1\u010f\1\u013a\1\u013b\1\u013c\1\u010f"+
-    "\1\u013c\2\u013a\2\u010f\1\u011b\5\u010f\3\u013a\3\u010f\5\u013a"+
-    "\1\u013d\13\u010f\7\u013a\1\u010f\5\u013a\1\u010f\1\277\1\u013e"+
-    "\1\364\1\363\1\277\1\363\1\u013e\2\363\1\324\1\277"+
-    "\1\363\4\277\3\363\1\277\1\365\1\277\5\363\1\366"+
-    "\13\277\1\u013e\1\363\3\u013e\1\363\1\u013e\1\277\5\363"+
-    "\1\277\1\0\1\343\1\344\1\343\1\0\4\343\2\0"+
-    "\1\343\4\0\3\343\1\0\1\345\1\0\5\343\1\346"+
-    "\13\0\7\343\1\0\5\343\1\0\1\300\1\u013f\1\372"+
-    "\1\371\1\300\1\371\1\u013f\2\371\1\300\1\324\1\371"+
-    "\4\300\3\371\1\300\1\373\1\300\5\371\1\374\13\300"+
-    "\1\u013f\1\371\3\u013f\1\371\1\u013f\1\300\5\371\1\300"+
-    "\1\u010c\1\u0140\1\u0123\1\u0122\1\u010c\1\u0122\1\u0140\2\u0122"+
-    "\2\0\1\u0122\1\u010c\1\324\2\u010c\3\u0122\1\0\1\u0124"+
-    "\1\u010c\5\u0122\1\u0125\13\u010c\1\u0140\1\u0122\3\u0140\1\u0122"+
-    "\1\u0140\1\u010c\5\u0122\2\u010c\1\u0122\1\u0123\1\u0135\1\u010c"+
-    "\1\u0135\2\u0122\1\u010c\2\0\2\u010c\1\324\2\u010c\3\u0122"+
-    "\1\0\1\u0124\1\u010c\5\u0122\1\u0125\13\u010c\7\u0122\1\u010c"+
-    "\5\u0122\1\u010c\1\u010e\1\u0136\1\u0137\1\u0141\1\u010e\1\u0141"+
-    "\3\u0136\1\u011b\1\u010e\1\u0136\4\u010e\3\u0136\1\u010e\1\u0138"+
-    "\1\u010e\5\u0136\1\u0139\13\u010e\7\u0136\1\u010e\5\u0136\2\u010e"+
-    "\1\u0142\1\u0143\1\u010e\2\u0136\1\u0142\2\u0136\1\u0144\35\u0136"+
-    "\1\u0142\1\u0136\3\u0142\1\u0136\1\u0142\7\u0136\1\u010e\1\u0136"+
-    "\1\u0137\1\u0138\1\u010e\1\u0138\2\u0136\1\u010e\1\u011b\6\u010e"+
-    "\3\u0136\3\u010e\5\u0136\14\u010e\7\u0136\1\u010e\5\u0136\1\u010e"+
-    "\1\u010f\1\u013a\1\u013b\1\u0145\1\u010f\1\u0145\3\u013a\1\u010f"+
-    "\1\u011b\1\u013a\4\u010f\3\u013a\1\u010f\1\u013c\1\u010f\5\u013a"+
-    "\1\u013d\13\u010f\7\u013a\1\u010f\5\u013a\2\u010f\1\u0146\1\u0147"+
-    "\1\u010f\2\u013a\1\u0146\3\u013a\1\u0148\34\u013a\1\u0146\1\u013a"+
-    "\3\u0146\1\u013a\1\u0146\7\u013a\1\u010f\1\u013a\1\u013b\1\u013c"+
-    "\1\u010f\1\u013c\2\u013a\2\u010f\1\u011b\5\u010f\3\u013a\3\u010f"+
-    "\5\u013a\14\u010f\7\u013a\1\u010f\5\u013a\1\u010f\1\277\1\363"+
-    "\1\364\1\363\1\277\4\363\1\324\1\277\1\363\4\277"+
-    "\3\363\1\277\1\365\1\277\5\363\1\366\13\277\7\363"+
-    "\1\277\5\363\1\277\1\300\1\371\1\372\1\371\1\300"+
-    "\4\371\1\300\1\324\1\371\4\300\3\371\1\300\1\373"+
-    "\1\300\5\371\1\374\13\300\7\371\1\300\5\371\1\300"+
-    "\1\u010c\1\u0149\1\u0123\1\u0122\1\u010c\1\u0122\1\u0149\2\u0122"+
-    "\2\0\1\u0122\1\u010c\1\324\2\u010c\3\u0122\1\0\1\u0124"+
-    "\1\u010c\5\u0122\1\u0125\13\u010c\1\u0149\1\u0122\3\u0149\1\u0122"+
-    "\1\u0149\1\u010c\5\u0122\1\u010c\2\u010e\1\u011a\1\u0141\1\u010e"+
-    "\1\u0141\3\u010e\1\u011b\12\u010e\1\u0138\6\u010e\1\u0139\32\u010e"+
-    "\1\u014a\1\u0137\1\u0136\1\u010e\1\u0136\1\u014a\2\u0136\1\u011b"+
-    "\1\u010e\1\u0136\4\u010e\3\u0136\1\u010e\1\u0138\1\u010e\5\u0136"+
-    "\1\u0139\13\u010e\1\u014a\1\u0136\3\u014a\1\u0136\1\u014a\1\u010e"+
-    "\5\u0136\2\u010e\1\u0136\1\u0137\1\u0141\1\u010e\1\u0141\3\u0136"+
-    "\1\u0126\1\u010e\1\u0136\4\u010e\3\u0136\1\u010e\1\u0138\1\u010e"+
-    "\5\u0136\1\u0139\13\u010e\7\u0136\1\u010e\5\u0136\2\u010e\1\u0136"+
-    "\1\u0137\1\u014b\1\u010e\1\u014b\3\u0136\1\u011b\1\u010e\1\u0136"+
-    "\1\u010e\1\u012f\2\u010e\3\u0136\1\u010e\1\u0138\1\u010e\5\u0136"+
-    "\1\u0139\13\u010e\7\u0136\1\u010e\5\u0136\1\u010e\2\u010f\1\u011c"+
-    "\1\u0145\1\u010f\1\u0145\4\u010f\1\u011b\11\u010f\1\u013c\6\u010f"+
-    "\1\u013d\32\u010f\1\u014c\1\u013b\1\u013a\1\u010f\1\u013a\1\u014c"+
-    "\2\u013a\1\u010f\1\u011b\1\u013a\4\u010f\3\u013a\1\u010f\1\u013c"+
-    "\1\u010f\5\u013a\1\u013d\13\u010f\1\u014c\1\u013a\3\u014c\1\u013a"+
-    "\1\u014c\1\u010f\5\u013a\2\u010f\1\u013a\1\u013b\1\u0145\1\u010f"+
-    "\1\u0145\3\u013a\1\u010f\1\u0127\1\u013a\4\u010f\3\u013a\1\u010f"+
-    "\1\u013c\1\u010f\5\u013a\1\u013d\13\u010f\7\u013a\1\u010f\5\u013a"+
-    "\2\u010f\1\u013a\1\u013b\1\u014d\1\u010f\1\u014d\3\u013a\1\u010f"+
-    "\1\u011b\1\u013a\1\u010f\1\u0130\2\u010f\3\u013a\1\u010f\1\u013c"+
-    "\1\u010f\5\u013a\1\u013d\13\u010f\7\u013a\1\u010f\5\u013a\1\u010f"+
-    "\1\u010c\1\u014e\1\u0123\1\u0122\1\u010c\1\u0122\1\u014e\2\u0122"+
-    "\2\0\1\u0122\1\u010c\1\324\2\u010c\3\u0122\1\0\1\u0124"+
-    "\1\u010c\5\u0122\1\u0125\13\u010c\1\u014e\1\u0122\3\u014e\1\u0122"+
-    "\1\u014e\1\u010c\5\u0122\1\u010c\1\u010e\1\u014f\1\u0137\1\u0136"+
-    "\1\u010e\1\u0136\1\u014f\2\u0136\1\u011b\1\u010e\1\u0136\4\u010e"+
-    "\3\u0136\1\u010e\1\u0138\1\u010e\5\u0136\1\u0139\13\u010e\1\u014f"+
-    "\1\u0136\3\u014f\1\u0136\1\u014f\1\u010e\5\u0136\3\u010e\1\u011a"+
-    "\1\u014b\1\u010e\1\u014b\3\u010e\1\u011b\3\u010e\1\u012f\6\u010e"+
-    "\1\u0138\6\u010e\1\u0139\31\u010e\1\u010f\1\u0150\1\u013b\1\u013a"+
-    "\1\u010f\1\u013a\1\u0150\2\u013a\1\u010f\1\u011b\1\u013a\4\u010f"+
-    "\3\u013a\1\u010f\1\u013c\1\u010f\5\u013a\1\u013d\13\u010f\1\u0150"+
-    "\1\u013a\3\u0150\1\u013a\1\u0150\1\u010f\5\u013a\3\u010f\1\u011c"+
-    "\1\u014d\1\u010f\1\u014d\4\u010f\1\u011b\2\u010f\1\u0130\6\u010f"+
-    "\1\u013c\6\u010f\1\u013d\31\u010f\1\u010c\1\u0151\1\u0123\1\u0122"+
-    "\1\u010c\1\u0122\1\u0151\2\u0122\2\0\1\u0122\1\u010c\1\324"+
-    "\2\u010c\3\u0122\1\0\1\u0124\1\u010c\5\u0122\1\u0125\13\u010c"+
-    "\1\u0151\1\u0122\3\u0151\1\u0122\1\u0151\1\u010c\5\u0122\1\u010c"+
-    "\1\u010e\1\u0152\1\u0137\1\u0136\1\u010e\1\u0136\1\u0152\2\u0136"+
-    "\1\u011b\1\u010e\1\u0136\4\u010e\3\u0136\1\u010e\1\u0138\1\u010e"+
-    "\5\u0136\1\u0139\13\u010e\1\u0152\1\u0136\3\u0152\1\u0136\1\u0152"+
-    "\1\u010e\5\u0136\1\u010e\1\u010f\1\u0153\1\u013b\1\u013a\1\u010f"+
-    "\1\u013a\1\u0153\2\u013a\1\u010f\1\u011b\1\u013a\4\u010f\3\u013a"+
-    "\1\u010f\1\u013c\1\u010f\5\u013a\1\u013d\13\u010f\1\u0153\1\u013a"+
-    "\3\u0153\1\u013a\1\u0153\1\u010f\5\u013a\1\u010f\1\u010c\1\u0122"+
-    "\1\u0123\1\u0122\1\u010c\4\u0122\2\0\1\u0122\1\u010c\1\324"+
-    "\2\u010c\3\u0122\1\0\1\u0124\1\u010c\5\u0122\1\u0125\13\u010c"+
-    "\7\u0122\1\u010c\5\u0122\1\u010c\1\u010e\1\u0154\1\u0137\1\u0136"+
-    "\1\u010e\1\u0136\1\u0154\2\u0136\1\u011b\1\u010e\1\u0136\4\u010e"+
-    "\3\u0136\1\u010e\1\u0138\1\u010e\5\u0136\1\u0139\13\u010e\1\u0154"+
-    "\1\u0136\3\u0154\1\u0136\1\u0154\1\u010e\5\u0136\1\u010e\1\u010f"+
-    "\1\u0155\1\u013b\1\u013a\1\u010f\1\u013a\1\u0155\2\u013a\1\u010f"+
-    "\1\u011b\1\u013a\4\u010f\3\u013a\1\u010f\1\u013c\1\u010f\5\u013a"+
-    "\1\u013d\13\u010f\1\u0155\1\u013a\3\u0155\1\u013a\1\u0155\1\u010f"+
-    "\5\u013a\1\u010f\1\u010e\1\u0156\1\u0137\1\u0136\1\u010e\1\u0136"+
-    "\1\u0156\2\u0136\1\u011b\1\u010e\1\u0136\4\u010e\3\u0136\1\u010e"+
-    "\1\u0138\1\u010e\5\u0136\1\u0139\13\u010e\1\u0156\1\u0136\3\u0156"+
-    "\1\u0136\1\u0156\1\u010e\5\u0136\1\u010e\1\u010f\1\u0157\1\u013b"+
-    "\1\u013a\1\u010f\1\u013a\1\u0157\2\u013a\1\u010f\1\u011b\1\u013a"+
-    "\4\u010f\3\u013a\1\u010f\1\u013c\1\u010f\5\u013a\1\u013d\13\u010f"+
-    "\1\u0157\1\u013a\3\u0157\1\u013a\1\u0157\1\u010f\5\u013a\1\u010f"+
-    "\1\u010e\1\u0136\1\u0137\1\u0136\1\u010e\4\u0136\1\u011b\1\u010e"+
-    "\1\u0136\4\u010e\3\u0136\1\u010e\1\u0138\1\u010e\5\u0136\1\u0139"+
-    "\13\u010e\7\u0136\1\u010e\5\u0136\1\u010e\1\u010f\1\u013a\1\u013b"+
-    "\1\u013a\1\u010f\4\u013a\1\u010f\1\u011b\1\u013a\4\u010f\3\u013a"+
-    "\1\u010f\1\u013c\1\u010f\5\u013a\1\u013d\13\u010f\7\u013a\1\u010f"+
-    "\5\u013a\1\u010f";
-
-  private static int [] zzUnpackTrans() {
-    int [] result = new int[15794];
-    int offset = 0;
-    offset = zzUnpackTrans(ZZ_TRANS_PACKED_0, offset, result);
-    return result;
-  }
-
-  private static int zzUnpackTrans(String packed, int offset, int [] result) {
-    int i = 0;       /* index in packed string  */
-    int j = offset;  /* index in unpacked array */
-    int l = packed.length();
-    while (i < l) {
-      int count = packed.charAt(i++);
-      int value = packed.charAt(i++);
-      value--;
-      do result[j++] = value; while (--count > 0);
-    }
-    return j;
-  }
-
-
-  /* error codes */
-  private static final int ZZ_UNKNOWN_ERROR = 0;
-  private static final int ZZ_NO_MATCH = 1;
-  private static final int ZZ_PUSHBACK_2BIG = 2;
-
-  /* error messages for the codes above */
-  private static final String ZZ_ERROR_MSG[] = {
-    "Unkown internal scanner error",
-    "Error: could not match input",
-    "Error: pushback value was too large"
-  };
-
-  /**
-   * ZZ_ATTRIBUTE[aState] contains the attributes of state <code>aState</code>
-   */
-  private static final int [] ZZ_ATTRIBUTE = zzUnpackAttribute();
-
-  private static final String ZZ_ATTRIBUTE_PACKED_0 =
-    "\1\0\1\11\10\1\1\11\2\1\1\11\1\1\1\11"+
-    "\7\1\3\0\1\11\1\0\2\11\1\1\2\0\1\11"+
-    "\2\0\1\1\2\0\2\1\1\0\2\1\1\0\1\1"+
-    "\1\0\5\1\4\0\2\11\2\0\3\1\2\0\1\1"+
-    "\1\11\12\0\13\1\4\0\1\1\1\0\1\1\2\0"+
-    "\4\1\1\0\7\1\2\11\2\0\1\1\1\0\3\1"+
-    "\5\0\1\11\11\1\2\0\1\1\1\0\4\1\3\0"+
-    "\10\1\2\0\1\1\1\0\3\1\2\0\6\1\2\0"+
-    "\2\1\6\0\1\11\5\1\1\11\2\1\1\0\1\1"+
-    "\4\0\6\1\2\0\1\1\3\0\1\1\1\0\3\1"+
-    "\4\0\3\1\6\0\1\11\1\1\5\0\1\11\1\0"+
-    "\3\1\3\0\1\11\3\1\4\0\1\1\5\0\1\1"+
-    "\1\0\1\1\1\0\1\11\1\0\1\1\15\0\4\1"+
-    "\11\0\2\1\6\0\1\1\23\0\1\1\3\0\1\1"+
-    "\32\0";
-
-  private static int [] zzUnpackAttribute() {
-    int [] result = new int[343];
-    int offset = 0;
-    offset = zzUnpackAttribute(ZZ_ATTRIBUTE_PACKED_0, offset, result);
-    return result;
-  }
-
-  private static int zzUnpackAttribute(String packed, int offset, int [] 
result) {
-    int i = 0;       /* index in packed string  */
-    int j = offset;  /* index in unpacked array */
-    int l = packed.length();
-    while (i < l) {
-      int count = packed.charAt(i++);
-      int value = packed.charAt(i++);
-      do result[j++] = value; while (--count > 0);
-    }
-    return j;
-  }
-
-  /** the input device */
-  private java.io.Reader zzReader;
-
-  /** the current state of the DFA */
-  private int zzState;
-
-  /** the current lexical state */
-  private int zzLexicalState = YYINITIAL;
-
-  /** this buffer contains the current text to be matched and is
-      the source of the yytext() string */
-  private char zzBuffer[] = new char[ZZ_BUFFERSIZE];
-
-  /** the textposition at the last accepting state */
-  private int zzMarkedPos;
-
-  /** the textposition at the last state to be included in yytext */
-  private int zzPushbackPos;
-
-  /** the current text position in the buffer */
-  private int zzCurrentPos;
-
-  /** startRead marks the beginning of the yytext() string in the buffer */
-  private int zzStartRead;
-
-  /** endRead marks the last character in the buffer, that has been read
-      from input */
-  private int zzEndRead;
-
-  /** number of newlines encountered up to the start of the matched text */
-  private int yyline;
-
-  /** the number of characters up to the start of the matched text */
-  private int yychar;
-
-  /**
-   * the number of characters from the last newline up to the start of the 
-   * matched text
-   */
-  private int yycolumn;
-
-  /** 
-   * zzAtBOL == true <=> the scanner is currently at the beginning of a line
-   */
-  private boolean zzAtBOL = true;
-
-  /** zzAtEOF == true <=> the scanner is at the EOF */
-  private boolean zzAtEOF;
-
-  /* user code: */
+
+/**
+ * This class is a scanner generated by 
+ * <a href="http://www.jflex.de/";>JFlex</a> 1.4.1
+ * on 10/05/07 18:37 from the specification file
+ * <tt>freenet/clients/http/filter/CSSTokenizerFilter.jflex</tt>
+ */
+class CSSTokenizerFilter {
+
+  /** This character denotes the end of file */
+  public static final int YYEOF = -1;
+
+  /** initial size of the lookahead buffer */
+  private static final int ZZ_BUFFERSIZE = 16384;
+
+  /** lexical states */
+  public static final int YYINITIAL = 0;
+
+  /** 
+   * Translates characters to character classes
+   */
+  private static final String ZZ_CMAP_PACKED = 
+    "\11\0\1\3\1\3\1\0\1\3\1\3\22\0\1\5\1\41\1\11"+
+    "\1\17\1\4\1\64\1\4\1\12\1\23\1\15\1\37\1\56\1\24"+
+    "\1\13\1\14\1\36\12\1\1\46\1\33\1\40\1\44\1\42\1\16"+
+    "\1\25\1\47\1\6\1\55\1\52\1\51\1\53\1\50\1\61\1\26"+
+    "\1\7\1\63\1\22\1\27\1\54\1\31\1\30\1\7\1\21\1\60"+
+    "\1\32\1\20\2\7\1\57\1\7\1\62\1\4\1\2\2\4\1\10"+
+    "\1\4\1\47\1\6\1\55\1\52\1\51\1\53\1\50\1\61\1\26"+
+    "\1\7\1\63\1\22\1\27\1\54\1\31\1\30\1\7\1\21\1\60"+
+    "\1\32\1\20\2\7\1\57\1\7\1\62\1\34\1\45\1\35\1\43"+
+    "\uff81\0";
+
+  /** 
+   * Translates characters to character classes
+   */
+  private static final char [] ZZ_CMAP = zzUnpackCMap(ZZ_CMAP_PACKED);
+
+  /** 
+   * Translates DFA states to action switch labels.
+   */
+  private static final int [] ZZ_ACTION = zzUnpackAction();
+
+  private static final String ZZ_ACTION_PACKED_0 =
+    "\1\0\1\1\1\2\1\1\1\3\1\2\2\1\2\4"+
+    "\1\5\1\1\1\2\1\4\1\1\1\6\1\7\1\10"+
+    "\1\4\4\1\3\0\1\11\1\0\1\12\1\13\1\2"+
+    "\2\0\1\14\2\0\1\15\2\0\1\16\1\17\1\0"+
+    "\1\17\1\2\1\0\1\20\1\0\5\20\4\0\1\21"+
+    "\1\22\2\0\1\2\2\14\2\0\1\15\1\23\12\0"+
+    "\2\17\1\2\2\24\6\20\4\0\1\2\1\0\1\15"+
+    "\2\0\1\25\1\17\1\11\1\24\1\0\1\24\6\20"+
+    "\1\26\1\27\2\0\1\2\1\0\1\15\2\17\5\0"+
+    "\1\30\2\24\1\31\3\20\1\32\2\20\2\0\1\2"+
+    "\1\0\1\15\2\17\1\30\3\0\2\24\1\31\5\20"+
+    "\2\0\1\2\1\0\1\15\1\25\1\17\2\0\2\24"+
+    "\1\31\2\20\1\33\2\0\2\20\6\0\1\34\1\15"+
+    "\1\17\2\30\2\24\1\31\1\20\1\0\1\20\4\0"+
+    "\1\20\1\35\2\33\2\20\2\0\1\34\3\0\1\31"+
+    "\1\0\2\20\1\35\4\0\1\20\1\33\1\20\6\0"+
+    "\1\31\1\20\5\0\1\35\1\0\1\20\1\33\1\36"+
+    "\3\0\1\37\2\34\1\20\4\0\1\35\5\0\1\35"+
+    "\1\0\1\33\1\0\1\40\1\0\1\20\15\0\1\33"+
+    "\2\40\1\20\11\0\1\33\1\20\6\0\1\35\23\0"+
+    "\1\35\3\0\1\35\32\0";
+
+  private static int [] zzUnpackAction() {
+    int [] result = new int[343];
+    int offset = 0;
+    offset = zzUnpackAction(ZZ_ACTION_PACKED_0, offset, result);
+    return result;
+  }
+
+  private static int zzUnpackAction(String packed, int offset, int [] result) {
+    int i = 0;       /* index in packed string  */
+    int j = offset;  /* index in unpacked array */
+    int l = packed.length();
+    while (i < l) {
+      int count = packed.charAt(i++);
+      int value = packed.charAt(i++);
+      do result[j++] = value; while (--count > 0);
+    }
+    return j;
+  }
+
+
+  /** 
+   * Translates a state to a row index in the transition table
+   */
+  private static final int [] ZZ_ROWMAP = zzUnpackRowMap();
+
+  private static final String ZZ_ROWMAP_PACKED_0 =
+    "\0\0\0\65\0\152\0\237\0\324\0\u0109\0\u013e\0\u0173"+
+    "\0\u01a8\0\u01dd\0\65\0\u0212\0\u0247\0\65\0\u027c\0\65"+
+    "\0\u02b1\0\u02e6\0\u031b\0\u0350\0\u0385\0\u03ba\0\u03ef\0\237"+
+    "\0\u0424\0\u01dd\0\65\0\u0459\0\65\0\65\0\u048e\0\u013e"+
+    "\0\u04c3\0\65\0\u0173\0\u04f8\0\u052d\0\u0562\0\u0597\0\u05cc"+
+    "\0\u0601\0\u0636\0\u066b\0\u06a0\0\u06d5\0\u070a\0\u073f\0\u0774"+
+    "\0\u07a9\0\u07de\0\u0813\0\u0848\0\u087d\0\u08b2\0\u0385\0\u08e7"+
+    "\0\65\0\65\0\u091c\0\u0951\0\u0986\0\u013e\0\u0173\0\u09bb"+
+    "\0\u09f0\0\u0a25\0\65\0\u0a5a\0\u0a8f\0\u0ac4\0\u0af9\0\u0b2e"+
+    "\0\u0b63\0\u0b98\0\u0bcd\0\u0c02\0\u0c37\0\u0c6c\0\u0ca1\0\u0cd6"+
+    "\0\u0d0b\0\u0d40\0\u0d75\0\u0daa\0\u0ddf\0\u0e14\0\u0e49\0\u0e7e"+
+    "\0\u0eb3\0\u0ee8\0\u0f1d\0\u0f52\0\u0f87\0\u0fbc\0\u0ff1\0\u1026"+
+    "\0\u105b\0\u1090\0\u10c5\0\u10fa\0\u112f\0\u1164\0\u1199\0\u11ce"+
+    "\0\u1203\0\u1238\0\u126d\0\u12a2\0\u12d7\0\65\0\65\0\u130c"+
+    "\0\u1341\0\u1376\0\u13ab\0\u13e0\0\u1415\0\u144a\0\u147f\0\u14b4"+
+    "\0\u10fa\0\u14e9\0\u151e\0\65\0\u1553\0\u1588\0\u15bd\0\u15f2"+
+    "\0\u1627\0\u165c\0\u070a\0\u1691\0\u16c6\0\u16fb\0\u1730\0\u1765"+
+    "\0\u179a\0\u17cf\0\u1804\0\u1839\0\u147f\0\u186e\0\u18a3\0\u18d8"+
+    "\0\u190d\0\u1942\0\u1977\0\u19ac\0\u19e1\0\u1a16\0\u1a4b\0\u1a80"+
+    "\0\u1ab5\0\u1aea\0\u1b1f\0\u1b54\0\u1b89\0\u066b\0\u1bbe\0\u1bf3"+
+    "\0\u1c28\0\u1c5d\0\u1c92\0\u1cc7\0\u1cfc\0\u1d31\0\u1d66\0\u1d9b"+
+    "\0\u1dd0\0\u1e05\0\u1e3a\0\u1e6f\0\u1ea4\0\u1ed9\0\u1f0e\0\u1f43"+
+    "\0\u1f78\0\65\0\u1fad\0\u1fe2\0\u14e9\0\u151e\0\u2017\0\65"+
+    "\0\u204c\0\u2081\0\u20b6\0\u20eb\0\u2120\0\u2155\0\u218a\0\u21bf"+
+    "\0\u21f4\0\u20b6\0\u2229\0\u225e\0\u2293\0\u22c8\0\u22fd\0\u2332"+
+    "\0\u1ed9\0\u2367\0\u239c\0\u23d1\0\u2406\0\u243b\0\u2470\0\u24a5"+
+    "\0\u20eb\0\u24da\0\u250f\0\u2544\0\u2579\0\u25ae\0\u25e3\0\u2618"+
+    "\0\u264d\0\u2682\0\u26b7\0\u26ec\0\u2721\0\u2756\0\65\0\u278b"+
+    "\0\u27c0\0\u27f5\0\u282a\0\u285f\0\u2894\0\65\0\u28c9\0\u28fe"+
+    "\0\u2933\0\u070a\0\u2968\0\u299d\0\u29d2\0\65\0\u1f43\0\u1f78"+
+    "\0\u2a07\0\u2a3c\0\u2a71\0\u2aa6\0\u2adb\0\u218a\0\u2b10\0\u2b45"+
+    "\0\u2b7a\0\u2baf\0\u2be4\0\u21bf\0\u2c19\0\u2c4e\0\u2c83\0\65"+
+    "\0\u2cb8\0\u2ced\0\u2d22\0\u2d57\0\u2d8c\0\u2dc1\0\u2df6\0\u2e2b"+
+    "\0\u2e60\0\u2e95\0\u2eca\0\u2eff\0\u2f34\0\u2f69\0\u2f9e\0\u2fd3"+
+    "\0\u2682\0\u26b7\0\u3008\0\u303d\0\u3072\0\u30a7\0\u30dc\0\u3111"+
+    "\0\u3146\0\u317b\0\u31b0\0\u31e5\0\u321a\0\u324f\0\u3284\0\u32b9"+
+    "\0\u32ee\0\u3323\0\u3358\0\u338d\0\u2eff\0\u33c2\0\u33f7\0\u342c"+
+    "\0\u3461\0\u3496\0\u34cb\0\u3500\0\u3535\0\u356a\0\u359f\0\u35d4"+
+    "\0\u3609\0\u363e\0\u3673\0\u36a8\0\u36dd\0\u3712\0\u3747\0\u377c"+
+    "\0\u2f69\0\u37b1\0\u37e6\0\u381b\0\u2f9e\0\u3850\0\u3885\0\u38ba"+
+    "\0\u38ef\0\u3924\0\u3959\0\u398e\0\u39c3\0\u39f8\0\u3a2d\0\u3a62"+
+    "\0\u3a97\0\u3acc\0\u3b01\0\u3b36\0\u3b6b\0\u3ba0\0\u3bd5\0\u3c0a"+
+    "\0\u3c3f\0\u3c74\0\u3ca9\0\u3cde\0\u3d13\0\u3d48\0\u3d7d";
+
+  private static int [] zzUnpackRowMap() {
+    int [] result = new int[343];
+    int offset = 0;
+    offset = zzUnpackRowMap(ZZ_ROWMAP_PACKED_0, offset, result);
+    return result;
+  }
+
+  private static int zzUnpackRowMap(String packed, int offset, int [] result) {
+    int i = 0;  /* index in packed string  */
+    int j = offset;  /* index in unpacked array */
+    int l = packed.length();
+    while (i < l) {
+      int high = packed.charAt(i++) << 16;
+      result[j++] = high | packed.charAt(i++);
+    }
+    return j;
+  }
+
+  /** 
+   * The transition table of the DFA
+   */
+  private static final int [] ZZ_TRANS = zzUnpackTrans();
+
+  private static final String ZZ_TRANS_PACKED_0 =
+    "\1\2\1\3\1\4\1\5\1\2\1\5\2\6\1\2"+
+    "\1\7\1\10\1\11\1\12\1\13\1\2\1\14\1\15"+
+    "\2\6\1\2\1\16\1\17\5\6\1\20\1\21\1\22"+
+    "\1\23\1\16\1\24\1\25\1\16\1\26\1\2\1\27"+
+    "\1\16\7\6\1\16\5\6\1\2\66\0\1\3\1\30"+
+    "\1\31\1\0\1\31\3\6\2\0\1\6\1\32\3\0"+
+    "\3\6\1\33\1\34\1\0\5\6\1\35\13\0\7\6"+
+    "\1\0\5\6\1\36\1\0\1\37\1\6\1\0\2\6"+
+    "\1\37\40\6\1\37\1\6\3\37\1\6\1\37\7\6"+
+    "\3\0\1\5\1\0\1\5\26\0\1\21\1\22\30\0"+
+    "\1\6\1\30\1\31\1\0\1\31\3\6\2\0\1\6"+
+    "\4\0\3\6\1\33\1\34\1\0\5\6\1\35\13\0"+
+    "\7\6\1\0\5\6\1\0\2\40\1\41\6\40\1\42"+
+    "\53\40\2\43\1\44\7\43\1\42\52\43\1\0\1\45"+
+    "\1\46\3\0\2\45\3\0\1\47\4\0\3\45\3\0"+
+    "\5\45\14\0\7\45\1\0\5\45\2\0\1\50\64\0"+
+    "\1\51\1\52\3\0\1\51\2\53\2\0\1\53\4\0"+
+    "\3\53\3\0\5\53\14\0\1\51\1\53\3\51\1\53"+
+    "\1\51\1\0\5\53\2\0\1\6\1\30\1\31\1\0"+
+    "\1\31\3\6\2\0\1\6\4\0\1\6\1\54\1\6"+
+    "\1\33\1\34\1\0\5\6\1\35\13\0\7\6\1\55"+
+    "\5\6\2\0\1\56\1\57\3\0\2\56\10\0\3\56"+
+    "\3\0\1\60\1\61\1\62\2\56\14\0\4\56\1\63"+
+    "\1\56\1\64\1\0\5\56\4\0\1\21\1\0\1\21"+
+    "\62\0\1\22\1\0\1\22\116\0\1\65\66\0\1\66"+
+    "\26\0\1\67\1\0\1\67\20\0\1\70\102\0\1\71"+
+    "\64\0\1\72\23\0\1\31\1\0\1\31\16\0\1\34"+
+    "\6\0\1\35\32\0\1\73\1\74\1\34\1\0\1\34"+
+    "\2\73\10\0\3\73\3\0\5\73\14\0\7\73\1\0"+
+    "\5\73\2\0\1\75\1\30\1\6\1\0\1\6\1\75"+
+    "\2\6\2\0\1\6\4\0\3\6\1\33\1\34\1\0"+
+    "\5\6\1\35\13\0\1\75\1\6\3\75\1\6\1\75"+
+    "\1\0\5\6\1\0\2\40\1\41\6\40\1\76\53\40"+
+    "\2\43\1\44\7\43\1\77\52\43\1\0\1\45\1\46"+
+    "\1\100\1\0\1\100\3\45\2\0\1\45\4\0\3\45"+
+    "\3\0\5\45\13\0\1\101\7\45\1\0\5\45\2\0"+
+    "\1\102\1\45\1\0\2\45\1\102\40\45\1\102\1\45"+
+    "\3\102\1\45\1\102\7\45\42\0\1\103\23\0\1\50"+
+    "\17\0\1\104\4\0\1\105\1\106\1\107\17\0\1\110"+
+    "\1\111\1\112\2\0\1\113\2\0\1\36\1\114\1\0"+
+    "\1\115\1\36\1\0\1\116\1\52\3\0\1\116\2\53"+
+    "\2\0\1\53\4\0\3\53\3\0\5\53\14\0\1\116"+
+    "\1\53\3\116\1\53\1\116\1\0\5\53\2\0\1\117"+
+    "\1\53\1\0\2\53\1\117\40\53\1\117\1\53\3\117"+
+    "\1\53\1\117\7\53\1\0\1\53\1\52\3\0\3\53"+
+    "\2\0\1\53\4\0\3\53\3\0\5\53\14\0\7\53"+
+    "\1\0\5\53\2\0\1\6\1\30\1\31\1\0\1\31"+
+    "\3\6\2\0\1\6\4\0\2\6\1\120\1\33\1\34"+
+    "\1\0\5\6\1\35\13\0\7\6\1\0\5\6\2\0"+
+    "\1\121\4\0\1\121\7\0\1\122\30\0\1\121\1\0"+
+    "\3\121\1\0\1\121\10\0\1\56\1\57\3\0\3\56"+
+    "\2\0\1\56\4\0\3\56\3\0\5\56\14\0\7\56"+
+    "\1\0\5\56\2\0\1\123\1\56\1\0\2\56\1\123"+
+    "\40\56\1\123\1\56\3\123\1\56\1\123\7\56\1\0"+
+    "\1\56\1\57\3\0\3\56\2\0\1\56\4\0\3\56"+
+    "\3\0\1\56\1\124\3\56\14\0\7\56\1\0\5\56"+
+    "\2\0\1\56\1\57\3\0\3\56\2\0\1\56\4\0"+
+    "\3\56\3\0\5\56\14\0\2\56\1\125\4\56\1\0"+
+    "\5\56\2\0\1\56\1\57\3\0\3\56\2\0\1\56"+
+    "\4\0\3\56\3\0\5\56\14\0\1\126\6\56\1\0"+
+    "\5\56\2\0\1\56\1\57\3\0\3\56\2\0\1\56"+
+    "\4\0\3\56\3\0\3\56\1\127\1\56\14\0\7\56"+
+    "\1\0\5\56\2\0\1\56\1\57\3\0\3\56\2\0"+
+    "\1\56\4\0\3\56\3\0\5\56\14\0\7\56\1\0"+
+    "\2\56\1\130\2\56\1\0\37\65\1\131\25\65\13\0"+
+    "\1\132\100\0\1\133\36\0\1\73\1\74\1\31\1\0"+
+    "\1\31\3\73\2\0\1\73\4\0\3\73\1\0\1\34"+
+    "\1\0\5\73\1\35\13\0\7\73\1\0\5\73\2\0"+
+    "\1\134\1\73\1\0\2\73\1\134\40\73\1\134\1\73"+
+    "\3\134\1\73\1\134\7\73\1\0\1\135\1\30\1\6"+
+    "\1\0\1\6\1\135\2\6\2\0\1\6\4\0\3\6"+
+    "\1\33\1\34\1\0\5\6\1\35\13\0\1\135\1\6"+
+    "\3\135\1\6\1\135\1\0\5\6\4\0\1\100\1\0"+
+    "\1\100\40\0\1\101\21\0\1\101\1\0\1\101\12\0"+
+    "\1\136\45\0\1\137\1\46\1\45\1\0\1\45\1\137"+
+    "\2\45\2\0\1\45\4\0\3\45\3\0\5\45\13\0"+
+    "\1\101\1\137\1\45\3\137\1\45\1\137\1\0\5\45"+
+    "\50\0\1\140\71\0\1\36\37\0\1\36\30\0\1\36"+
+    "\61\0\1\36\1\0\1\36\26\0\1\104\72\0\1\36"+
+    "\27\0\1\36\56\0\1\141\42\0\1\36\117\0\1\36"+
+    "\63\0\1\114\4\0\1\142\1\52\3\0\1\142\2\53"+
+    "\2\0\1\53\4\0\3\53\3\0\5\53\14\0\1\142"+
+    "\1\53\3\142\1\53\1\142\1\0\5\53\2\0\1\143"+
+    "\1\52\1\53\1\0\1\53\1\143\2\53\2\0\1\53"+
+    "\4\0\3\53\3\0\5\53\14\0\1\143\1\53\3\143"+
+    "\1\53\1\143\1\0\5\53\2\0\1\6\1\30\1\31"+
+    "\1\0\1\31\3\6\2\0\1\6\4\0\3\6\1\144"+
+    "\1\34\1\0\5\6\1\35\13\0\7\6\1\0\5\6"+
+    "\2\0\1\145\4\0\1\145\4\0\1\146\2\0\1\147"+
+    "\30\0\1\145\1\0\3\145\1\0\1\145\25\0\1\147"+
+    "\47\0\1\150\1\57\1\56\1\0\1\56\1\150\2\56"+
+    "\2\0\1\56\4\0\3\56\3\0\5\56\14\0\1\150"+
+    "\1\56\3\150\1\56\1\150\1\0\5\56\2\0\1\56"+
+    "\1\57\3\0\3\56\2\0\1\56\4\0\3\56\3\0"+
+    "\2\56\1\151\2\56\14\0\7\56\1\0\5\56\2\0"+
+    "\1\56\1\57\3\0\3\56\2\0\1\56\4\0\3\56"+
+    "\3\0\5\56\14\0\3\56\1\152\3\56\1\0\5\56"+
+    "\2\0\1\56\1\57\3\0\3\56\2\0\1\56\4\0"+
+    "\3\56\3\0\5\56\14\0\1\56\1\153\5\56\1\0"+
+    "\5\56\2\0\1\56\1\57\3\0\3\56\2\0\1\56"+
+    "\4\0\3\56\3\0\5\56\14\0\5\56\1\154\1\56"+
+    "\1\0\5\56\2\0\1\56\1\57\3\0\3\56\2\0"+
+    "\1\56\4\0\3\56\3\0\5\56\14\0\1\155\6\56"+
+    "\1\0\5\56\1\0\36\65\1\156\1\131\25\65\13\0"+
+    "\1\157\101\0\1\160\35\0\1\161\1\74\1\73\1\0"+
+    "\1\73\1\161\2\73\2\0\1\73\4\0\3\73\1\0"+
+    "\1\34\1\0\5\73\1\35\13\0\1\161\1\73\3\161"+
+    "\1\73\1\161\1\0\5\73\2\0\1\162\1\30\1\6"+
+    "\1\0\1\6\1\162\2\6\2\0\1\6\4\0\3\6"+
+    "\1\33\1\34\1\0\5\6\1\35\13\0\1\162\1\6"+
+    "\3\162\1\6\1\162\1\0\5\6\22\0\1\163\44\0"+
+    "\1\164\1\46\1\45\1\0\1\45\1\164\2\45\2\0"+
+    "\1\45\4\0\3\45\3\0\5\45\13\0\1\101\1\164"+
+    "\1\45\3\164\1\45\1\164\1\0\5\45\53\0\1\36"+
+    "\62\0\1\36\15\0\1\165\1\52\3\0\1\165\2\53"+
+    "\2\0\1\53\4\0\3\53\3\0\5\53\14\0\1\165"+
+    "\1\53\3\165\1\53\1\165\1\0\5\53\2\0\1\166"+
+    "\1\52\1\53\1\0\1\53\1\166\2\53\2\0\1\53"+
+    "\4\0\3\53\3\0\5\53\14\0\1\166\1\53\3\166"+
+    "\1\53\1\166\1\0\5\53\1\0\2\167\1\170\1\171"+
+    "\1\167\1\171\3\167\1\172\1\173\2\167\1\174\5\167"+
+    "\1\0\41\167\1\0\1\175\4\0\1\175\4\0\1\146"+
+    "\2\0\1\176\30\0\1\175\1\0\3\175\1\0\1\175"+
+    "\10\0\1\177\4\0\1\177\40\0\1\177\1\0\3\177"+
+    "\1\0\1\177\25\0\1\176\47\0\1\200\1\57\1\56"+
+    "\1\0\1\56\1\200\2\56\2\0\1\56\4\0\3\56"+
+    "\3\0\5\56\14\0\1\200\1\56\3\200\1\56\1\200"+
+    "\1\0\5\56\2\0\1\56\1\57\3\0\3\56\2\0"+
+    "\1\56\4\0\3\56\3\0\3\56\1\201\1\56\14\0"+
+    "\7\56\1\0\5\56\2\0\1\56\1\57\3\0\3\56"+
+    "\2\0\1\56\4\0\3\56\3\0\1\202\4\56\14\0"+
+    "\7\56\1\0\5\56\2\0\1\56\1\57\3\0\3\56"+
+    "\2\0\1\56\4\0\3\56\3\0\5\56\14\0\2\56"+
+    "\1\203\4\56\1\0\5\56\2\0\1\56\1\57\3\0"+
+    "\3\56\2\0\1\56\4\0\3\56\3\0\4\56\1\204"+
+    "\14\0\7\56\1\0\5\56\2\0\1\56\1\57\3\0"+
+    "\3\56\2\0\1\56\4\0\1\56\1\205\1\56\3\0"+
+    "\5\56\14\0\7\56\1\0\5\56\32\0\1\206\34\0"+
+    "\1\207\1\74\1\73\1\0\1\73\1\207\2\73\2\0"+
+    "\1\73\4\0\3\73\1\0\1\34\1\0\5\73\1\35"+
+    "\13\0\1\207\1\73\3\207\1\73\1\207\1\0\5\73"+
+    "\2\0\1\210\1\30\1\6\1\0\1\6\1\210\2\6"+
+    "\2\0\1\6\4\0\3\6\1\33\1\34\1\0\5\6"+
+    "\1\35\13\0\1\210\1\6\3\210\1\6\1\210\1\0"+
+    "\5\6\23\0\1\211\43\0\1\212\1\46\1\45\1\0"+
+    "\1\45\1\212\2\45\2\0\1\45\4\0\3\45\3\0"+
+    "\5\45\13\0\1\101\1\212\1\45\3\212\1\45\1\212"+
+    "\1\0\5\45\2\0\1\213\1\52\3\0\1\213\2\53"+
+    "\2\0\1\53\4\0\3\53\3\0\5\53\14\0\1\213"+
+    "\1\53\3\213\1\53\1\213\1\0\5\53\2\0\1\214"+
+    "\1\52\1\53\1\0\1\53\1\214\2\53\2\0\1\53"+
+    "\4\0\3\53\3\0\5\53\14\0\1\214\1\53\3\214"+
+    "\1\53\1\214\1\0\5\53\1\0\2\167\1\170\6\167"+
+    "\2\0\2\167\1\174\5\167\1\0\43\167\1\170\12\167"+
+    "\1\215\47\167\2\172\1\216\6\172\1\217\53\172\2\173"+
+    "\1\220\7\173\1\217\52\173\1\0\1\221\4\0\1\221"+
+    "\4\0\1\146\2\0\1\222\30\0\1\221\1\0\3\221"+
+    "\1\0\1\221\25\0\1\222\47\0\1\223\4\0\1\223"+
+    "\40\0\1\223\1\0\3\223\1\0\1\223\10\0\1\224"+
+    "\1\57\1\56\1\0\1\56\1\224\2\56\2\0\1\56"+
+    "\4\0\3\56\3\0\5\56\14\0\1\224\1\56\3\224"+
+    "\1\56\1\224\1\0\5\56\2\0\1\56\1\57\3\0"+
+    "\3\56\2\0\1\56\4\0\1\56\1\225\1\56\3\0"+
+    "\5\56\14\0\7\56\1\0\5\56\2\0\1\56\1\57"+
+    "\3\0\3\56\2\0\1\56\4\0\3\56\3\0\5\56"+
+    "\14\0\1\226\6\56\1\0\5\56\2\0\1\56\1\57"+
+    "\3\0\3\56\2\0\1\227\4\0\3\56\3\0\5\56"+
+    "\14\0\7\56\1\0\5\56\2\0\1\56\1\57\3\0"+
+    "\3\56\2\0\1\56\4\0\3\56\3\0\5\56\14\0"+
+    "\7\56\1\0\1\56\1\230\3\56\22\0\1\231\44\0"+
+    "\1\232\1\74\1\73\1\0\1\73\1\232\2\73\2\0"+
+    "\1\73\4\0\3\73\1\0\1\34\1\0\5\73\1\35"+
+    "\13\0\1\232\1\73\3\232\1\73\1\232\1\0\5\73"+
+    "\2\0\1\233\1\30\1\6\1\0\1\6\1\233\2\6"+
+    "\2\0\1\6\4\0\3\6\1\33\1\34\1\0\5\6"+
+    "\1\35\13\0\1\233\1\6\3\233\1\6\1\233\1\0"+
+    "\5\6\24\0\1\234\42\0\1\235\1\46\1\45\1\0"+
+    "\1\45\1\235\2\45\2\0\1\45\4\0\3\45\3\0"+
+    "\5\45\13\0\1\101\1\235\1\45\3\235\1\45\1\235"+
+    "\1\0\5\45\2\0\1\236\1\52\3\0\1\236\2\53"+
+    "\2\0\1\53\4\0\3\53\3\0\5\53\14\0\1\236"+
+    "\1\53\3\236\1\53\1\236\1\0\5\53\2\0\1\237"+
+    "\1\52\1\53\1\0\1\53\1\237\2\53\2\0\1\53"+
+    "\4\0\3\53\3\0\5\53\14\0\1\237\1\53\3\237"+
+    "\1\53\1\237\1\0\5\53\1\0\2\172\1\216\6\172"+
+    "\1\240\53\172\3\0\1\217\1\0\1\217\7\0\1\174"+
+    "\47\0\2\173\1\220\7\173\1\241\52\173\1\0\1\242"+
+    "\4\0\1\242\4\0\1\146\2\0\1\243\30\0\1\242"+
+    "\1\0\3\242\1\0\1\242\25\0\1\243\47\0\1\244"+
+    "\4\0\1\244\40\0\1\244\1\0\3\244\1\0\1\244"+
+    "\10\0\1\245\1\57\1\56\1\0\1\56\1\245\2\56"+
+    "\2\0\1\56\4\0\3\56\3\0\5\56\14\0\1\245"+
+    "\1\56\3\245\1\56\1\245\1\0\5\56\2\0\1\56"+
+    "\1\57\3\0\3\56\2\0\1\56\4\0\3\56\3\0"+
+    "\4\56\1\246\14\0\7\56\1\0\5\56\2\0\1\247"+
+    "\1\250\1\251\1\0\1\251\2\247\1\56\2\0\1\56"+
+    "\4\0\3\247\3\0\5\247\14\0\7\247\1\0\5\247"+
+    "\2\0\1\56\1\57\3\0\3\56\2\0\1\56\4\0"+
+    "\3\56\3\0\5\56\14\0\4\56\1\252\2\56\1\0"+
+    "\5\56\2\0\1\56\1\57\3\0\3\56\2\0\1\56"+
+    "\4\0\3\56\3\0\5\56\14\0\2\56\1\253\4\56"+
+    "\1\0\5\56\33\0\1\254\33\0\1\255\1\74\1\73"+
+    "\1\0\1\73\1\255\2\73\2\0\1\73\4\0\3\73"+
+    "\1\0\1\34\1\0\5\73\1\35\13\0\1\255\1\73"+
+    "\3\255\1\73\1\255\1\0\5\73\2\0\1\6\1\30"+
+    "\1\6\1\0\4\6\2\0\1\6\4\0\3\6\1\33"+
+    "\1\34\1\0\5\6\1\35\13\0\7\6\1\0\5\6"+
+    "\1\0\2\256\1\257\1\234\1\256\1\234\3\256\1\260"+
+    "\1\261\2\256\1\262\5\256\1\0\41\256\1\0\1\263"+
+    "\1\46\1\45\1\0\1\45\1\263\2\45\2\0\1\45"+
+    "\4\0\3\45\3\0\5\45\13\0\1\101\1\263\1\45"+
+    "\3\263\1\45\1\263\1\0\5\45\2\0\1\264\1\52"+
+    "\1\53\1\0\1\53\1\264\2\53\2\0\1\53\4\0"+
+    "\3\53\3\0\5\53\14\0\1\264\1\53\3\264\1\53"+
+    "\1\264\1\0\5\53\1\0\2\172\1\216\1\240\1\172"+
+    "\1\240\3\172\1\217\3\172\1\265\47\172\2\173\1\220"+
+    "\1\241\1\173\1\241\4\173\1\217\2\173\1\266\47\173"+
+    "\1\0\1\267\4\0\1\267\4\0\1\146\2\0\1\270"+
+    "\30\0\1\267\1\0\3\267\1\0\1\267\25\0\1\270"+
+    "\47\0\1\271\4\0\1\271\40\0\1\271\1\0\3\271"+
+    "\1\0\1\271\10\0\1\272\1\57\1\56\1\0\1\56"+
+    "\1\272\2\56\2\0\1\56\4\0\3\56\3\0\5\56"+
+    "\14\0\1\272\1\56\3\272\1\56\1\272\1\0\5\56"+
+    "\1\0\1\273\1\274\1\275\1\276\1\273\1\276\3\274"+
+    "\1\277\1\300\1\274\1\273\1\0\2\273\1\301\2\274"+
+    "\1\0\2\273\5\274\1\302\13\273\7\274\1\273\5\274"+
+    "\1\273\1\0\1\247\1\250\1\303\1\0\1\303\3\247"+
+    "\2\0\1\247\4\0\3\247\1\0\1\251\1\0\5\247"+
+    "\14\0\7\247\1\0\5\247\2\0\1\304\1\247\1\0"+
+    "\2\247\1\304\40\247\1\304\1\247\3\304\1\247\1\304"+
+    "\7\247\1\0\1\247\1\250\1\251\1\0\1\251\2\247"+
+    "\10\0\3\247\3\0\5\247\14\0\7\247\1\0\5\247"+
+    "\2\0\1\56\1\57\3\0\3\56\2\0\1\56\4\0"+
+    "\3\56\3\0\5\56\14\0\1\305\6\56\1\0\5\56"+
+    "\2\0\1\56\1\57\3\0\3\56\2\0\1\56\4\0"+
+    "\3\56\3\0\4\56\1\306\14\0\7\56\1\0\5\56"+
+    "\50\0\1\307\16\0\1\310\1\74\1\73\1\0\1\73"+
+    "\1\310\2\73\2\0\1\73\4\0\3\73\1\0\1\34"+
+    "\1\0\5\73\1\35\13\0\1\310\1\73\3\310\1\73"+
+    "\1\310\1\0\5\73\1\0\2\256\1\257\6\256\2\0"+
+    "\2\256\1\262\5\256\1\0\43\256\1\257\12\256\1\311"+
+    "\47\256\2\260\1\312\6\260\1\313\53\260\2\261\1\314"+
+    "\7\261\1\313\52\261\1\0\1\45\1\46\1\45\1\0"+
+    "\4\45\2\0\1\45\4\0\3\45\3\0\5\45\13\0"+
+    "\1\101\7\45\1\0\5\45\2\0\1\53\1\52\1\53"+
+    "\1\0\4\53\2\0\1\53\4\0\3\53\3\0\5\53"+
+    "\14\0\7\53\1\0\5\53\14\0\1\146\52\0\1\315"+
+    "\4\0\1\315\40\0\1\315\1\0\3\315\1\0\1\315"+
+    "\10\0\1\56\1\57\1\56\1\0\4\56\2\0\1\56"+
+    "\4\0\3\56\3\0\5\56\14\0\7\56\1\0\5\56"+
+    "\1\0\2\273\1\316\6\273\2\0\2\273\1\0\5\273"+
+    "\1\0\7\273\1\302\32\273\1\274\1\275\3\273\3\274"+
+    "\2\0\1\274\1\273\1\0\2\273\3\274\1\0\2\273"+
+    "\5\274\1\302\13\273\7\274\1\273\5\274\2\273\1\317"+
+    "\1\320\1\273\2\274\1\317\24\274\1\321\13\274\1\317"+
+    "\1\274\3\317\1\274\1\317\7\274\2\273\1\316\1\276"+
+    "\1\273\1\276\3\273\1\277\1\300\2\273\1\0\2\273"+
+    "\1\322\2\273\1\0\7\273\1\302\31\273\2\277\1\323"+
+    "\6\277\1\324\53\277\2\300\1\325\7\300\1\324\52\300"+
+    "\1\273\1\274\1\275\3\273\3\274\2\0\1\274\1\273"+
+    "\1\0\2\273\1\274\1\326\1\274\1\0\2\273\5\274"+
+    "\1\302\13\273\7\274\1\273\5\274\1\273\3\0\1\303"+
+    "\1\0\1\303\16\0\1\251\41\0\1\327\1\250\1\247"+
+    "\1\0\1\247\1\327\2\247\2\0\1\247\4\0\3\247"+
+    "\1\0\1\251\1\0\5\247\14\0\1\327\1\247\3\327"+
+    "\1\247\1\327\1\0\5\247\2\0\1\56\1\57\3\0"+
+    "\3\56\2\0\1\56\4\0\3\56\3\0\5\56\14\0"+
+    "\6\56\1\330\1\0\5\56\2\0\1\56\1\57\1\331"+
+    "\1\0\1\331\3\56\1\332\1\333\1\56\4\0\3\56"+
+    "\3\0\5\56\14\0\7\56\1\0\5\56\55\0\1\334"+
+    "\11\0\1\73\1\74\1\73\1\0\4\73\2\0\1\73"+
+    "\4\0\3\73\1\0\1\34\1\0\5\73\1\35\13\0"+
+    "\7\73\1\0\5\73\1\0\2\260\1\312\6\260\1\335"+
+    "\53\260\3\0\1\313\1\0\1\313\7\0\1\262\47\0"+
+    "\2\261\1\314\7\261\1\336\52\261\1\0\1\337\4\0"+
+    "\1\337\40\0\1\337\1\0\3\337\1\0\1\337\7\0"+
+    "\2\273\1\316\30\273\1\302\32\273\1\340\1\275\1\274"+
+    "\1\273\1\274\1\340\2\274\2\0\1\274\1\273\1\0"+
+    "\2\273\3\274\1\0\2\273\5\274\1\302\13\273\1\340"+
+    "\1\274\3\340\1\274\1\340\1\273\5\274\2\273\1\274"+
+    "\1\275\3\273\3\274\2\273\1\274\4\273\3\274\3\273"+
+    "\5\274\1\302\13\273\7\274\1\273\5\274\3\273\1\316"+
+    "\6\273\2\0\2\273\1\0\3\273\1\341\1\273\1\0"+
+    "\7\273\1\302\31\273\2\277\1\323\6\277\1\342\53\277"+
+    "\1\0\1\343\1\344\1\345\1\0\1\345\2\343\10\0"+
+    "\3\343\3\0\5\343\1\346\13\0\7\343\1\0\5\343"+
+    "\1\0\2\300\1\325\7\300\1\347\52\300\1\273\1\274"+
+    "\1\275\3\273\3\274\2\0\1\274\1\273\1\0\2\273"+
+    "\2\274\1\350\1\0\2\273\5\274\1\302\13\273\7\274"+
+    "\1\273\5\274\1\273\1\0\1\351\1\250\1\247\1\0"+
+    "\1\247\1\351\2\247\2\0\1\247\4\0\3\247\1\0"+
+    "\1\251\1\0\5\247\14\0\1\351\1\247\3\351\1\247"+
+    "\1\351\1\0\5\247\2\0\1\56\1\57\3\0\3\56"+
+    "\2\0\1\56\4\0\3\56\3\0\5\56\14\0\2\56"+
+    "\1\352\4\56\1\0\5\56\4\0\1\331\1\0\1\331"+
+    "\3\0\1\332\1\333\52\0\2\332\1\353\6\332\1\354"+
+    "\53\332\2\333\1\355\7\333\1\354\52\333\32\0\1\356"+
+    "\32\0\2\260\1\312\1\335\1\260\1\335\3\260\1\313"+
+    "\3\260\1\357\47\260\2\261\1\314\1\336\1\261\1\336"+
+    "\4\261\1\313\2\261\1\360\47\261\1\273\1\361\1\275"+
+    "\1\274\1\273\1\274\1\361\2\274\2\0\1\274\1\273"+
+    "\1\0\2\273\3\274\1\0\2\273\5\274\1\302\13\273"+
+    "\1\361\1\274\3\361\1\274\1\361\1\273\5\274\3\273"+
+    "\1\316\6\273\2\0\2\273\1\0\4\273\1\362\1\0"+
+    "\7\273\1\302\31\273\1\277\1\363\1\364\1\365\1\277"+
+    "\1\365\2\363\1\277\1\324\6\277\3\363\3\277\5\363"+
+    "\1\366\13\277\7\363\1\277\5\363\1\277\1\0\1\343"+
+    "\1\344\1\367\1\0\1\367\3\343\2\0\1\343\4\0"+
+    "\3\343\1\0\1\345\1\0\5\343\1\346\13\0\7\343"+
+    "\1\0\5\343\2\0\1\370\1\343\1\0\2\343\1\370"+
+    "\40\343\1\370\1\343\3\370\1\343\1\370\7\343\1\0"+
+    "\1\343\1\344\1\345\1\0\1\345\2\343\10\0\3\343"+
+    "\3\0\5\343\14\0\7\343\1\0\5\343\1\0\1\300"+
+    "\1\371\1\372\1\373\1\300\1\373\2\371\2\300\1\324"+
+    "\5\300\3\371\3\300\5\371\1\374\13\300\7\371\1\300"+
+    "\5\371\1\300\1\273\1\274\1\275\3\273\3\274\2\0"+
+    "\1\274\1\273\1\0\2\273\3\274\1\375\2\273\5\274"+
+    "\1\302\13\273\7\274\1\273\5\274\1\273\1\0\1\376"+
+    "\1\250\1\247\1\0\1\247\1\376\2\247\2\0\1\247"+
+    "\4\0\3\247\1\0\1\251\1\0\5\247\14\0\1\376"+
+    "\1\247\3\376\1\247\1\376\1\0\5\247\1\0\2\332"+
+    "\1\353\6\332\1\377\53\332\3\0\1\354\1\0\1\354"+
+    "\25\0\1\u0100\31\0\2\333\1\355\7\333\1\u0101\52\333"+
+    "\1\273\1\u0102\1\275\1\274\1\273\1\274\1\u0102\2\274"+
+    "\2\0\1\274\1\273\1\0\2\273\3\274\1\0\2\273"+
+    "\5\274\1\302\13\273\1\u0102\1\274\3\u0102\1\274\1\u0102"+
+    "\1\273\5\274\3\273\1\316\6\273\2\0\2\273\1\0"+
+    "\5\273\1\375\7\273\1\302\31\273\1\277\1\363\1\364"+
+    "\1\u0103\1\277\1\u0103\3\363\1\324\1\277\1\363\4\277"+
+    "\3\363\1\277\1\365\1\277\5\363\1\366\13\277\7\363"+
+    "\1\277\5\363\2\277\1\u0104\1\u0105\1\277\2\363\1\u0104"+
+    "\2\363\1\u0106\35\363\1\u0104\1\363\3\u0104\1\363\1\u0104"+
+    "\7\363\1\277\1\363\1\364\1\365\1\277\1\365\2\363"+
+    "\1\277\1\324\6\277\3\363\3\277\5\363\14\277\7\363"+
+    "\1\277\5\363\1\277\3\0\1\367\1\0\1\367\16\0"+
+    "\1\345\6\0\1\346\32\0\1\u0107\1\344\1\343\1\0"+
+    "\1\343\1\u0107\2\343\2\0\1\343\4\0\3\343\1\0"+
+    "\1\345\1\0\5\343\1\346\13\0\1\u0107\1\343\3\u0107"+
+    "\1\343\1\u0107\1\0\5\343\1\0\1\300\1\371\1\372"+
+    "\1\u0108\1\300\1\u0108\3\371\1\300\1\324\1\371\4\300"+
+    "\3\371\1\300\1\373\1\300\5\371\1\374\13\300\7\371"+
+    "\1\300\5\371\2\300\1\u0109\1\u010a\1\300\2\371\1\u0109"+
+    "\3\371\1\u010b\34\371\1\u0109\1\371\3\u0109\1\371\1\u0109"+
+    "\7\371\1\300\1\371\1\372\1\373\1\300\1\373\2\371"+
+    "\2\300\1\324\5\300\3\371\3\300\5\371\14\300\7\371"+
+    "\1\300\5\371\1\300\2\u010c\1\u010d\1\375\1\u010c\1\375"+
+    "\3\u010c\1\u010e\1\u010f\2\u010c\1\324\5\u010c\1\0\41\u010c"+
+    "\1\0\1\u0110\1\250\1\247\1\0\1\247\1\u0110\2\247"+
+    "\2\0\1\247\4\0\3\247\1\0\1\251\1\0\5\247"+
+    "\14\0\1\u0110\1\247\3\u0110\1\247\1\u0110\1\0\5\247"+
+    "\1\0\2\332\1\353\1\377\1\332\1\377\3\332\1\354"+
+    "\21\332\1\u0111\31\332\2\333\1\355\1\u0101\1\333\1\u0101"+
+    "\4\333\1\354\20\333\1\u0112\31\333\1\273\1\u0113\1\275"+
+    "\1\274\1\273\1\274\1\u0113\2\274\2\0\1\274\1\273"+
+    "\1\0\2\273\3\274\1\0\2\273\5\274\1\302\13\273"+
+    "\1\u0113\1\274\3\u0113\1\274\1\u0113\1\273\5\274\1\273"+
+    "\2\277\1\323\1\u0103\1\277\1\u0103\3\277\1\324\12\277"+
+    "\1\365\6\277\1\366\32\277\1\u0114\1\364\1\363\1\277"+
+    "\1\363\1\u0114\2\363\1\324\1\277\1\363\4\277\3\363"+
+    "\1\277\1\365\1\277\5\363\1\366\13\277\1\u0114\1\363"+
+    "\3\u0114\1\363\1\u0114\1\277\5\363\2\277\1\363\1\364"+
+    "\1\u0103\1\277\1\u0103\3\363\1\342\1\277\1\363\4\277"+
+    "\3\363\1\277\1\365\1\277\5\363\1\366\13\277\7\363"+
+    "\1\277\5\363\2\277\1\363\1\364\1\u0115\1\277\1\u0115"+
+    "\3\363\1\324\1\277\1\363\4\277\3\363\1\277\1\365"+
+    "\1\277\5\363\1\366\13\277\7\363\1\277\5\363\1\277"+
+    "\1\0\1\u0116\1\344\1\343\1\0\1\343\1\u0116\2\343"+
+    "\2\0\1\343\4\0\3\343\1\0\1\345\1\0\5\343"+
+    "\1\346\13\0\1\u0116\1\343\3\u0116\1\343\1\u0116\1\0"+
+    "\5\343\1\0\2\300\1\325\1\u0108\1\300\1\u0108\4\300"+
+    "\1\324\11\300\1\373\6\300\1\374\32\300\1\u0117\1\372"+
+    "\1\371\1\300\1\371\1\u0117\2\371\1\300\1\324\1\371"+
+    "\4\300\3\371\1\300\1\373\1\300\5\371\1\374\13\300"+
+    "\1\u0117\1\371\3\u0117\1\371\1\u0117\1\300\5\371\2\300"+
+    "\1\371\1\372\1\u0108\1\300\1\u0108\3\371\1\300\1\347"+
+    "\1\371\4\300\3\371\1\300\1\373\1\300\5\371\1\374"+
+    "\13\300\7\371\1\300\5\371\2\300\1\371\1\372\1\u0118"+
+    "\1\300\1\u0118\3\371\1\300\1\324\1\371\4\300\3\371"+
+    "\1\300\1\373\1\300\5\371\1\374\13\300\7\371\1\300"+
+    "\5\371\1\300\2\u010c\1\u010d\6\u010c\2\0\2\u010c\1\324"+
+    "\5\u010c\1\0\43\u010c\1\u010d\12\u010c\1\u0119\47\u010c\2\u010e"+
+    "\1\u011a\6\u010e\1\u011b\53\u010e\2\u010f\1\u011c\7\u010f\1\u011b"+
+    "\52\u010f\1\0\1\u011d\1\250\1\247\1\0\1\247\1\u011d"+
+    "\2\247\2\0\1\247\4\0\3\247\1\0\1\251\1\0"+
+    "\5\247\14\0\1\u011d\1\247\3\u011d\1\247\1\u011d\1\0"+
+    "\5\247\1\0\1\273\1\u011e\1\275\1\274\1\273\1\274"+
+    "\1\u011e\2\274\2\0\1\274\1\273\1\0\2\273\3\274"+
+    "\1\0\2\273\5\274\1\302\13\273\1\u011e\1\274\3\u011e"+
+    "\1\274\1\u011e\1\273\5\274\1\273\1\277\1\u011f\1\364"+
+    "\1\363\1\277\1\363\1\u011f\2\363\1\324\1\277\1\363"+
+    "\4\277\3\363\1\277\1\365\1\277\5\363\1\366\13\277"+
+    "\1\u011f\1\363\3\u011f\1\363\1\u011f\1\277\5\363\2\277"+
+    "\1\363\1\364\1\u0115\1\277\1\u0115\2\363\1\277\1\324"+
+    "\6\277\3\363\1\277\1\365\1\277\5\363\1\366\13\277"+
+    "\7\363\1\277\5\363\1\277\1\0\1\u0120\1\344\1\343"+
+    "\1\0\1\343\1\u0120\2\343\2\0\1\343\4\0\3\343"+
+    "\1\0\1\345\1\0\5\343\1\346\13\0\1\u0120\1\343"+
+    "\3\u0120\1\343\1\u0120\1\0\5\343\1\0\1\300\1\u0121"+
+    "\1\372\1\371\1\300\1\371\1\u0121\2\371\1\300\1\324"+
+    "\1\371\4\300\3\371\1\300\1\373\1\300\5\371\1\374"+
+    "\13\300\1\u0121\1\371\3\u0121\1\371\1\u0121\1\300\5\371"+
+    "\2\300\1\371\1\372\1\u0118\1\300\1\u0118\2\371\2\300"+
+    "\1\324\5\300\3\371\1\300\1\373\1\300\5\371\1\374"+
+    "\13\300\7\371\1\300\5\371\1\300\1\u010c\1\u0122\1\u0123"+
+    "\1\u0124\1\u010c\1\u0124\2\u0122\1\u010c\2\0\2\u010c\1\324"+
+    "\2\u010c\3\u0122\1\0\2\u010c\5\u0122\1\u0125\13\u010c\7\u0122"+
+    "\1\u010c\5\u0122\1\u010c\2\u010e\1\u011a\6\u010e\1\u0126\53\u010e"+
+    "\3\0\1\u011b\1\0\1\u011b\7\0\1\324\47\0\2\u010f"+
+    "\1\u011c\7\u010f\1\u0127\52\u010f\1\0\1\247\1\250\1\247"+
+    "\1\0\4\247\2\0\1\247\4\0\3\247\1\0\1\251"+
+    "\1\0\5\247\14\0\7\247\1\0\5\247\1\0\1\273"+
+    "\1\274\1\275\1\274\1\273\4\274\2\0\1\274\1\273"+
+    "\1\0\2\273\3\274\1\0\2\273\5\274\1\302\13\273"+
+    "\7\274\1\273\5\274\1\273\1\277\1\u0128\1\364\1\363"+
+    "\1\277\1\363\1\u0128\2\363\1\324\1\277\1\363\4\277"+
+    "\3\363\1\277\1\365\1\277\5\363\1\366\13\277\1\u0128"+
+    "\1\363\3\u0128\1\363\1\u0128\1\277\5\363\1\277\1\0"+
+    "\1\u0129\1\344\1\343\1\0\1\343\1\u0129\2\343\2\0"+
+    "\1\343\4\0\3\343\1\0\1\345\1\0\5\343\1\346"+
+    "\13\0\1\u0129\1\343\3\u0129\1\343\1\u0129\1\0\5\343"+
+    "\1\0\1\300\1\u012a\1\372\1\371\1\300\1\371\1\u012a"+
+    "\2\371\1\300\1\324\1\371\4\300\3\371\1\300\1\373"+
+    "\1\300\5\371\1\374\13\300\1\u012a\1\371\3\u012a\1\371"+
+    "\1\u012a\1\300\5\371\1\300\1\u010c\1\u0122\1\u0123\1\u012b"+
+    "\1\u010c\1\u012b\3\u0122\2\0\1\u0122\1\u010c\1\324\2\u010c"+
+    "\3\u0122\1\0\1\u0124\1\u010c\5\u0122\1\u0125\13\u010c\7\u0122"+
+    "\1\u010c\5\u0122\2\u010c\1\u012c\1\u012d\1\u010c\2\u0122\1\u012c"+
+    "\6\u0122\1\u012e\31\u0122\1\u012c\1\u0122\3\u012c\1\u0122\1\u012c"+
+    "\7\u0122\1\u010c\1\u0122\1\u0123\1\u0124\1\u010c\1\u0124\2\u0122"+
+    "\1\u010c\2\0\2\u010c\1\324\2\u010c\3\u0122\1\0\2\u010c"+
+    "\5\u0122\14\u010c\7\u0122\1\u010c\5\u0122\1\u010c\2\u010e\1\u011a"+
+    "\1\u0126\1\u010e\1\u0126\3\u010e\1\u011b\3\u010e\1\u012f\47\u010e"+
+    "\2\u010f\1\u011c\1\u0127\1\u010f\1\u0127\4\u010f\1\u011b\2\u010f"+
+    "\1\u0130\47\u010f\1\277\1\u0131\1\364\1\363\1\277\1\363"+
+    "\1\u0131\2\363\1\324\1\277\1\363\4\277\3\363\1\277"+
+    "\1\365\1\277\5\363\1\366\13\277\1\u0131\1\363\3\u0131"+
+    "\1\363\1\u0131\1\277\5\363\1\277\1\0\1\u0132\1\344"+
+    "\1\343\1\0\1\343\1\u0132\2\343\2\0\1\343\4\0"+
+    "\3\343\1\0\1\345\1\0\5\343\1\346\13\0\1\u0132"+
+    "\1\343\3\u0132\1\343\1\u0132\1\0\5\343\1\0\1\300"+
+    "\1\u0133\1\372\1\371\1\300\1\371\1\u0133\2\371\1\300"+
+    "\1\324\1\371\4\300\3\371\1\300\1\373\1\300\5\371"+
+    "\1\374\13\300\1\u0133\1\371\3\u0133\1\371\1\u0133\1\300"+
+    "\5\371\1\300\2\u010c\1\u010d\1\u012b\1\u010c\1\u012b\3\u010c"+
+    "\2\0\2\u010c\1\324\5\u010c\1\0\1\u0124\6\u010c\1\u0125"+
+    "\32\u010c\1\u0134\1\u0123\1\u0122\1\u010c\1\u0122\1\u0134\2\u0122"+
+    "\2\0\1\u0122\1\u010c\1\324\2\u010c\3\u0122\1\0\1\u0124"+
+    "\1\u010c\5\u0122\1\u0125\13\u010c\1\u0134\1\u0122\3\u0134\1\u0122"+
+    "\1\u0134\1\u010c\5\u0122\2\u010c\1\u0122\1\u0123\1\u012b\1\u010c"+
+    "\1\u012b\3\u0122\2\u010c\1\u0122\1\u010c\1\u0119\2\u010c\3\u0122"+
+    "\1\u010c\1\u0124\1\u010c\5\u0122\1\u0125\13\u010c\7\u0122\1\u010c"+
+    "\5\u0122\2\u010c\1\u0122\1\u0123\1\u0135\1\u010c\1\u0135\3\u0122"+
+    "\2\0\1\u0122\1\u010c\1\324\2\u010c\3\u0122\1\0\1\u0124"+
+    "\1\u010c\5\u0122\1\u0125\13\u010c\7\u0122\1\u010c\5\u0122\1\u010c"+
+    "\1\u010e\1\u0136\1\u0137\1\u0138\1\u010e\1\u0138\2\u0136\1\u010e"+
+    "\1\u011b\6\u010e\3\u0136\3\u010e\5\u0136\1\u0139\13\u010e\7\u0136"+
+    "\1\u010e\5\u0136\1\u010e\1\u010f\1\u013a\1\u013b\1\u013c\1\u010f"+
+    "\1\u013c\2\u013a\2\u010f\1\u011b\5\u010f\3\u013a\3\u010f\5\u013a"+
+    "\1\u013d\13\u010f\7\u013a\1\u010f\5\u013a\1\u010f\1\277\1\u013e"+
+    "\1\364\1\363\1\277\1\363\1\u013e\2\363\1\324\1\277"+
+    "\1\363\4\277\3\363\1\277\1\365\1\277\5\363\1\366"+
+    "\13\277\1\u013e\1\363\3\u013e\1\363\1\u013e\1\277\5\363"+
+    "\1\277\1\0\1\343\1\344\1\343\1\0\4\343\2\0"+
+    "\1\343\4\0\3\343\1\0\1\345\1\0\5\343\1\346"+
+    "\13\0\7\343\1\0\5\343\1\0\1\300\1\u013f\1\372"+
+    "\1\371\1\300\1\371\1\u013f\2\371\1\300\1\324\1\371"+
+    "\4\300\3\371\1\300\1\373\1\300\5\371\1\374\13\300"+
+    "\1\u013f\1\371\3\u013f\1\371\1\u013f\1\300\5\371\1\300"+
+    "\1\u010c\1\u0140\1\u0123\1\u0122\1\u010c\1\u0122\1\u0140\2\u0122"+
+    "\2\0\1\u0122\1\u010c\1\324\2\u010c\3\u0122\1\0\1\u0124"+
+    "\1\u010c\5\u0122\1\u0125\13\u010c\1\u0140\1\u0122\3\u0140\1\u0122"+
+    "\1\u0140\1\u010c\5\u0122\2\u010c\1\u0122\1\u0123\1\u0135\1\u010c"+
+    "\1\u0135\2\u0122\1\u010c\2\0\2\u010c\1\324\2\u010c\3\u0122"+
+    "\1\0\1\u0124\1\u010c\5\u0122\1\u0125\13\u010c\7\u0122\1\u010c"+
+    "\5\u0122\1\u010c\1\u010e\1\u0136\1\u0137\1\u0141\1\u010e\1\u0141"+
+    "\3\u0136\1\u011b\1\u010e\1\u0136\4\u010e\3\u0136\1\u010e\1\u0138"+
+    "\1\u010e\5\u0136\1\u0139\13\u010e\7\u0136\1\u010e\5\u0136\2\u010e"+
+    "\1\u0142\1\u0143\1\u010e\2\u0136\1\u0142\2\u0136\1\u0144\35\u0136"+
+    "\1\u0142\1\u0136\3\u0142\1\u0136\1\u0142\7\u0136\1\u010e\1\u0136"+
+    "\1\u0137\1\u0138\1\u010e\1\u0138\2\u0136\1\u010e\1\u011b\6\u010e"+
+    "\3\u0136\3\u010e\5\u0136\14\u010e\7\u0136\1\u010e\5\u0136\1\u010e"+
+    "\1\u010f\1\u013a\1\u013b\1\u0145\1\u010f\1\u0145\3\u013a\1\u010f"+
+    "\1\u011b\1\u013a\4\u010f\3\u013a\1\u010f\1\u013c\1\u010f\5\u013a"+
+    "\1\u013d\13\u010f\7\u013a\1\u010f\5\u013a\2\u010f\1\u0146\1\u0147"+
+    "\1\u010f\2\u013a\1\u0146\3\u013a\1\u0148\34\u013a\1\u0146\1\u013a"+
+    "\3\u0146\1\u013a\1\u0146\7\u013a\1\u010f\1\u013a\1\u013b\1\u013c"+
+    "\1\u010f\1\u013c\2\u013a\2\u010f\1\u011b\5\u010f\3\u013a\3\u010f"+
+    "\5\u013a\14\u010f\7\u013a\1\u010f\5\u013a\1\u010f\1\277\1\363"+
+    "\1\364\1\363\1\277\4\363\1\324\1\277\1\363\4\277"+
+    "\3\363\1\277\1\365\1\277\5\363\1\366\13\277\7\363"+
+    "\1\277\5\363\1\277\1\300\1\371\1\372\1\371\1\300"+
+    "\4\371\1\300\1\324\1\371\4\300\3\371\1\300\1\373"+
+    "\1\300\5\371\1\374\13\300\7\371\1\300\5\371\1\300"+
+    "\1\u010c\1\u0149\1\u0123\1\u0122\1\u010c\1\u0122\1\u0149\2\u0122"+
+    "\2\0\1\u0122\1\u010c\1\324\2\u010c\3\u0122\1\0\1\u0124"+
+    "\1\u010c\5\u0122\1\u0125\13\u010c\1\u0149\1\u0122\3\u0149\1\u0122"+
+    "\1\u0149\1\u010c\5\u0122\1\u010c\2\u010e\1\u011a\1\u0141\1\u010e"+
+    "\1\u0141\3\u010e\1\u011b\12\u010e\1\u0138\6\u010e\1\u0139\32\u010e"+
+    "\1\u014a\1\u0137\1\u0136\1\u010e\1\u0136\1\u014a\2\u0136\1\u011b"+
+    "\1\u010e\1\u0136\4\u010e\3\u0136\1\u010e\1\u0138\1\u010e\5\u0136"+
+    "\1\u0139\13\u010e\1\u014a\1\u0136\3\u014a\1\u0136\1\u014a\1\u010e"+
+    "\5\u0136\2\u010e\1\u0136\1\u0137\1\u0141\1\u010e\1\u0141\3\u0136"+
+    "\1\u0126\1\u010e\1\u0136\4\u010e\3\u0136\1\u010e\1\u0138\1\u010e"+
+    "\5\u0136\1\u0139\13\u010e\7\u0136\1\u010e\5\u0136\2\u010e\1\u0136"+
+    "\1\u0137\1\u014b\1\u010e\1\u014b\3\u0136\1\u011b\1\u010e\1\u0136"+
+    "\1\u010e\1\u012f\2\u010e\3\u0136\1\u010e\1\u0138\1\u010e\5\u0136"+
+    "\1\u0139\13\u010e\7\u0136\1\u010e\5\u0136\1\u010e\2\u010f\1\u011c"+
+    "\1\u0145\1\u010f\1\u0145\4\u010f\1\u011b\11\u010f\1\u013c\6\u010f"+
+    "\1\u013d\32\u010f\1\u014c\1\u013b\1\u013a\1\u010f\1\u013a\1\u014c"+
+    "\2\u013a\1\u010f\1\u011b\1\u013a\4\u010f\3\u013a\1\u010f\1\u013c"+
+    "\1\u010f\5\u013a\1\u013d\13\u010f\1\u014c\1\u013a\3\u014c\1\u013a"+
+    "\1\u014c\1\u010f\5\u013a\2\u010f\1\u013a\1\u013b\1\u0145\1\u010f"+
+    "\1\u0145\3\u013a\1\u010f\1\u0127\1\u013a\4\u010f\3\u013a\1\u010f"+
+    "\1\u013c\1\u010f\5\u013a\1\u013d\13\u010f\7\u013a\1\u010f\5\u013a"+
+    "\2\u010f\1\u013a\1\u013b\1\u014d\1\u010f\1\u014d\3\u013a\1\u010f"+
+    "\1\u011b\1\u013a\1\u010f\1\u0130\2\u010f\3\u013a\1\u010f\1\u013c"+
+    "\1\u010f\5\u013a\1\u013d\13\u010f\7\u013a\1\u010f\5\u013a\1\u010f"+
+    "\1\u010c\1\u014e\1\u0123\1\u0122\1\u010c\1\u0122\1\u014e\2\u0122"+
+    "\2\0\1\u0122\1\u010c\1\324\2\u010c\3\u0122\1\0\1\u0124"+
+    "\1\u010c\5\u0122\1\u0125\13\u010c\1\u014e\1\u0122\3\u014e\1\u0122"+
+    "\1\u014e\1\u010c\5\u0122\1\u010c\1\u010e\1\u014f\1\u0137\1\u0136"+
+    "\1\u010e\1\u0136\1\u014f\2\u0136\1\u011b\1\u010e\1\u0136\4\u010e"+
+    "\3\u0136\1\u010e\1\u0138\1\u010e\5\u0136\1\u0139\13\u010e\1\u014f"+
+    "\1\u0136\3\u014f\1\u0136\1\u014f\1\u010e\5\u0136\3\u010e\1\u011a"+
+    "\1\u014b\1\u010e\1\u014b\3\u010e\1\u011b\3\u010e\1\u012f\6\u010e"+
+    "\1\u0138\6\u010e\1\u0139\31\u010e\1\u010f\1\u0150\1\u013b\1\u013a"+
+    "\1\u010f\1\u013a\1\u0150\2\u013a\1\u010f\1\u011b\1\u013a\4\u010f"+
+    "\3\u013a\1\u010f\1\u013c\1\u010f\5\u013a\1\u013d\13\u010f\1\u0150"+
+    "\1\u013a\3\u0150\1\u013a\1\u0150\1\u010f\5\u013a\3\u010f\1\u011c"+
+    "\1\u014d\1\u010f\1\u014d\4\u010f\1\u011b\2\u010f\1\u0130\6\u010f"+
+    "\1\u013c\6\u010f\1\u013d\31\u010f\1\u010c\1\u0151\1\u0123\1\u0122"+
+    "\1\u010c\1\u0122\1\u0151\2\u0122\2\0\1\u0122\1\u010c\1\324"+
+    "\2\u010c\3\u0122\1\0\1\u0124\1\u010c\5\u0122\1\u0125\13\u010c"+
+    "\1\u0151\1\u0122\3\u0151\1\u0122\1\u0151\1\u010c\5\u0122\1\u010c"+
+    "\1\u010e\1\u0152\1\u0137\1\u0136\1\u010e\1\u0136\1\u0152\2\u0136"+
+    "\1\u011b\1\u010e\1\u0136\4\u010e\3\u0136\1\u010e\1\u0138\1\u010e"+
+    "\5\u0136\1\u0139\13\u010e\1\u0152\1\u0136\3\u0152\1\u0136\1\u0152"+
+    "\1\u010e\5\u0136\1\u010e\1\u010f\1\u0153\1\u013b\1\u013a\1\u010f"+
+    "\1\u013a\1\u0153\2\u013a\1\u010f\1\u011b\1\u013a\4\u010f\3\u013a"+
+    "\1\u010f\1\u013c\1\u010f\5\u013a\1\u013d\13\u010f\1\u0153\1\u013a"+
+    "\3\u0153\1\u013a\1\u0153\1\u010f\5\u013a\1\u010f\1\u010c\1\u0122"+
+    "\1\u0123\1\u0122\1\u010c\4\u0122\2\0\1\u0122\1\u010c\1\324"+
+    "\2\u010c\3\u0122\1\0\1\u0124\1\u010c\5\u0122\1\u0125\13\u010c"+
+    "\7\u0122\1\u010c\5\u0122\1\u010c\1\u010e\1\u0154\1\u0137\1\u0136"+
+    "\1\u010e\1\u0136\1\u0154\2\u0136\1\u011b\1\u010e\1\u0136\4\u010e"+
+    "\3\u0136\1\u010e\1\u0138\1\u010e\5\u0136\1\u0139\13\u010e\1\u0154"+
+    "\1\u0136\3\u0154\1\u0136\1\u0154\1\u010e\5\u0136\1\u010e\1\u010f"+
+    "\1\u0155\1\u013b\1\u013a\1\u010f\1\u013a\1\u0155\2\u013a\1\u010f"+
+    "\1\u011b\1\u013a\4\u010f\3\u013a\1\u010f\1\u013c\1\u010f\5\u013a"+
+    "\1\u013d\13\u010f\1\u0155\1\u013a\3\u0155\1\u013a\1\u0155\1\u010f"+
+    "\5\u013a\1\u010f\1\u010e\1\u0156\1\u0137\1\u0136\1\u010e\1\u0136"+
+    "\1\u0156\2\u0136\1\u011b\1\u010e\1\u0136\4\u010e\3\u0136\1\u010e"+
+    "\1\u0138\1\u010e\5\u0136\1\u0139\13\u010e\1\u0156\1\u0136\3\u0156"+
+    "\1\u0136\1\u0156\1\u010e\5\u0136\1\u010e\1\u010f\1\u0157\1\u013b"+
+    "\1\u013a\1\u010f\1\u013a\1\u0157\2\u013a\1\u010f\1\u011b\1\u013a"+
+    "\4\u010f\3\u013a\1\u010f\1\u013c\1\u010f\5\u013a\1\u013d\13\u010f"+
+    "\1\u0157\1\u013a\3\u0157\1\u013a\1\u0157\1\u010f\5\u013a\1\u010f"+
+    "\1\u010e\1\u0136\1\u0137\1\u0136\1\u010e\4\u0136\1\u011b\1\u010e"+
+    "\1\u0136\4\u010e\3\u0136\1\u010e\1\u0138\1\u010e\5\u0136\1\u0139"+
+    "\13\u010e\7\u0136\1\u010e\5\u0136\1\u010e\1\u010f\1\u013a\1\u013b"+
+    "\1\u013a\1\u010f\4\u013a\1\u010f\1\u011b\1\u013a\4\u010f\3\u013a"+
+    "\1\u010f\1\u013c\1\u010f\5\u013a\1\u013d\13\u010f\7\u013a\1\u010f"+
+    "\5\u013a\1\u010f";
+
+  private static int [] zzUnpackTrans() {
+    int [] result = new int[15794];
+    int offset = 0;
+    offset = zzUnpackTrans(ZZ_TRANS_PACKED_0, offset, result);
+    return result;
+  }
+
+  private static int zzUnpackTrans(String packed, int offset, int [] result) {
+    int i = 0;       /* index in packed string  */
+    int j = offset;  /* index in unpacked array */
+    int l = packed.length();
+    while (i < l) {
+      int count = packed.charAt(i++);
+      int value = packed.charAt(i++);
+      value--;
+      do result[j++] = value; while (--count > 0);
+    }
+    return j;
+  }
+
+
+  /* error codes */
+  private static final int ZZ_UNKNOWN_ERROR = 0;
+  private static final int ZZ_NO_MATCH = 1;
+  private static final int ZZ_PUSHBACK_2BIG = 2;
+
+  /* error messages for the codes above */
+  private static final String ZZ_ERROR_MSG[] = {
+    "Unkown internal scanner error",
+    "Error: could not match input",
+    "Error: pushback value was too large"
+  };
+
+  /**
+   * ZZ_ATTRIBUTE[aState] contains the attributes of state <code>aState</code>
+   */
+  private static final int [] ZZ_ATTRIBUTE = zzUnpackAttribute();
+
+  private static final String ZZ_ATTRIBUTE_PACKED_0 =
+    "\1\0\1\11\10\1\1\11\2\1\1\11\1\1\1\11"+
+    "\7\1\3\0\1\11\1\0\2\11\1\1\2\0\1\11"+
+    "\2\0\1\1\2\0\2\1\1\0\2\1\1\0\1\1"+
+    "\1\0\5\1\4\0\2\11\2\0\3\1\2\0\1\1"+
+    "\1\11\12\0\13\1\4\0\1\1\1\0\1\1\2\0"+
+    "\4\1\1\0\7\1\2\11\2\0\1\1\1\0\3\1"+
+    "\5\0\1\11\11\1\2\0\1\1\1\0\4\1\3\0"+
+    "\10\1\2\0\1\1\1\0\3\1\2\0\6\1\2\0"+
+    "\2\1\6\0\1\11\5\1\1\11\2\1\1\0\1\1"+
+    "\4\0\6\1\2\0\1\1\3\0\1\1\1\0\3\1"+
+    "\4\0\3\1\6\0\1\11\1\1\5\0\1\11\1\0"+
+    "\3\1\3\0\1\11\3\1\4\0\1\1\5\0\1\1"+
+    "\1\0\1\1\1\0\1\11\1\0\1\1\15\0\4\1"+
+    "\11\0\2\1\6\0\1\1\23\0\1\1\3\0\1\1"+
+    "\32\0";
+
+  private static int [] zzUnpackAttribute() {
+    int [] result = new int[343];
+    int offset = 0;
+    offset = zzUnpackAttribute(ZZ_ATTRIBUTE_PACKED_0, offset, result);
+    return result;
+  }
+
+  private static int zzUnpackAttribute(String packed, int offset, int [] 
result) {
+    int i = 0;       /* index in packed string  */
+    int j = offset;  /* index in unpacked array */
+    int l = packed.length();
+    while (i < l) {
+      int count = packed.charAt(i++);
+      int value = packed.charAt(i++);
+      do result[j++] = value; while (--count > 0);
+    }
+    return j;
+  }
+
+  /** the input device */
+  private java.io.Reader zzReader;
+
+  /** the current state of the DFA */
+  private int zzState;
+
+  /** the current lexical state */
+  private int zzLexicalState = YYINITIAL;
+
+  /** this buffer contains the current text to be matched and is
+      the source of the yytext() string */
+  private char zzBuffer[] = new char[ZZ_BUFFERSIZE];
+
+  /** the textposition at the last accepting state */
+  private int zzMarkedPos;
+
+  /** the textposition at the last state to be included in yytext */
+  private int zzPushbackPos;
+
+  /** the current text position in the buffer */
+  private int zzCurrentPos;
+
+  /** startRead marks the beginning of the yytext() string in the buffer */
+  private int zzStartRead;
+
+  /** endRead marks the last character in the buffer, that has been read
+      from input */
+  private int zzEndRead;
+
+  /** number of newlines encountered up to the start of the matched text */
+  private int yyline;
+
+  /** the number of characters up to the start of the matched text */
+  private int yychar;
+
+  /**
+   * the number of characters from the last newline up to the start of the 
+   * matched text
+   */
+  private int yycolumn;
+
+  /** 
+   * zzAtBOL == true <=> the scanner is currently at the beginning of a line
+   */
+  private boolean zzAtBOL = true;
+
+  /** zzAtEOF == true <=> the scanner is at the EOF */
+  private boolean zzAtEOF;
+
+  /* user code: */
        // Put stuff to include in the class here
        String detectedCharset;

@@ -923,6 +924,10 @@
                        '0' <= c && c <= '9');
        }

+       static String l10n(String key) {
+               return L10n.getString("CSSTokenizerFilter."+key);
+       }
+       
        class DecodedStringThingy {
                char quote; // " " means not quoted
                boolean url; // in a url() ?
@@ -966,9 +971,10 @@
                                                // Ignore one whitespace char 
after an escape
                                                int d = 
Integer.parseInt(hexEscape.toString(),
                                                                         16);
+                                               // FIXME once we can use 1.5, 
use Characters.toChars(int).
                                                if(d > 0xFFFF) {
                                                        String error = 
-                                                           "UCS-4 CHARACTERS 
OVER 0xFFFF NOT SUPPORTED!";
+                                                               
l10n("supplementalCharsNotSupported");
                                                        logError(error);
                                                        try {
                                                                w.write("/* 
"+error+"*/");
@@ -982,9 +988,10 @@
                                        } else {
                                                int d = 
Integer.parseInt(hexEscape.toString(),
                                                                         16);
+                                               // FIXME once we can use 1.5, 
use Characters.toChars(int).
                                                if(d > 0xFFFF) {
                                                        String error = 
-                                                           "UCS-4 CHARACTERS 
OVER 0xFFFF NOT SUPPORTED!";
+                                                               
l10n("supplementalCharsNotSupported");
                                                        logError(error);
                                                        try {
                                                                w.write("/* 
"+error+"*/");
@@ -1053,296 +1060,296 @@
                }
                return sb.toString();
        }
-
-
-  /**
-   * Creates a new scanner
-   * There is also a java.io.InputStream version of this constructor.
-   *
-   * @param   in  the java.io.Reader to read input from.
-   */
-  CSSTokenizerFilter(java.io.Reader in) {
-    this.zzReader = in;
-  }
-
-  /**
-   * Creates a new scanner.
-   * There is also java.io.Reader version of this constructor.
-   *
-   * @param   in  the java.io.Inputstream to read input from.
-   */
-  CSSTokenizerFilter(java.io.InputStream in) {
-    this(new java.io.InputStreamReader(in));
-  }
-
-  /** 
-   * Unpacks the compressed character translation table.
-   *
-   * @param packed   the packed character translation table
-   * @return         the unpacked character translation table
-   */
-  private static char [] zzUnpackCMap(String packed) {
-    char [] map = new char[0x10000];
-    int i = 0;  /* index in packed string  */
-    int j = 0;  /* index in unpacked array */
-    while (i < 182) {
-      int  count = packed.charAt(i++);
-      char value = packed.charAt(i++);
-      do map[j++] = value; while (--count > 0);
-    }
-    return map;
-  }
-
-
-  /**
-   * Refills the input buffer.
-   *
-   * @return      <code>false</code>, iff there was new input.
-   * 
-   * @exception   java.io.IOException  if any I/O-Error occurs
-   */
-  private boolean zzRefill() throws java.io.IOException {
-
-    /* first: make room (if you can) */
-    if (zzStartRead > 0) {
-      System.arraycopy(zzBuffer, zzStartRead,
-                       zzBuffer, 0,
-                       zzEndRead-zzStartRead);
-
-      /* translate stored positions */
-      zzEndRead-= zzStartRead;
-      zzCurrentPos-= zzStartRead;
-      zzMarkedPos-= zzStartRead;
-      zzPushbackPos-= zzStartRead;
-      zzStartRead = 0;
-    }
-
-    /* is the buffer big enough? */
-    if (zzCurrentPos >= zzBuffer.length) {
-      /* if not: blow it up */
-      char newBuffer[] = new char[zzCurrentPos*2];
-      System.arraycopy(zzBuffer, 0, newBuffer, 0, zzBuffer.length);
-      zzBuffer = newBuffer;
-    }
-
-    /* finally: fill the buffer with new input */
-    int numRead = zzReader.read(zzBuffer, zzEndRead,
-                                            zzBuffer.length-zzEndRead);
-
-    if (numRead < 0) {
-      return true;
-    }
-    else {
-      zzEndRead+= numRead;
-      return false;
-    }
-  }
-
-    
-  /**
-   * Closes the input stream.
-   */
-  public final void yyclose() throws java.io.IOException {
-    zzAtEOF = true;            /* indicate end of file */
-    zzEndRead = zzStartRead;  /* invalidate buffer    */
-
-    if (zzReader != null)
-      zzReader.close();
-  }
-
-
-  /**
-   * Resets the scanner to read from a new input stream.
-   * Does not close the old reader.
-   *
-   * All internal variables are reset, the old input stream 
-   * <b>cannot</b> be reused (internal buffer is discarded and lost).
-   * Lexical state is set to <tt>ZZ_INITIAL</tt>.
-   *
-   * @param reader   the new input stream 
-   */
-  public final void yyreset(java.io.Reader reader) {
-    zzReader = reader;
-    zzAtBOL  = true;
-    zzAtEOF  = false;
-    zzEndRead = zzStartRead = 0;
-    zzCurrentPos = zzMarkedPos = zzPushbackPos = 0;
-    yyline = yychar = yycolumn = 0;
-    zzLexicalState = YYINITIAL;
-  }
-
-
-  /**
-   * Returns the current lexical state.
-   */
-  public final int yystate() {
-    return zzLexicalState;
-  }
-
-
-  /**
-   * Enters a new lexical state
-   *
-   * @param newState the new lexical state
-   */
-  public final void yybegin(int newState) {
-    zzLexicalState = newState;
-  }
-
-
-  /**
-   * Returns the text matched by the current regular expression.
-   */
-  public final String yytext() {
-    return new String( zzBuffer, zzStartRead, zzMarkedPos-zzStartRead );
-  }
-
-
-  /**
-   * Returns the character at position <tt>pos</tt> from the 
-   * matched text. 
-   * 
-   * It is equivalent to yytext().charAt(pos), but faster
-   *
-   * @param pos the position of the character to fetch. 
-   *            A value from 0 to yylength()-1.
-   *
-   * @return the character at position pos
-   */
-  public final char yycharat(int pos) {
-    return zzBuffer[zzStartRead+pos];
-  }
-
-
-  /**
-   * Returns the length of the matched text region.
-   */
-  public final int yylength() {
-    return zzMarkedPos-zzStartRead;
-  }
-
-
-  /**
-   * Reports an error that occured while scanning.
-   *
-   * In a wellformed scanner (no or only correct usage of 
-   * yypushback(int) and a match-all fallback rule) this method 
-   * will only be called with things that "Can't Possibly Happen".
-   * If this method is called, something is seriously wrong
-   * (e.g. a JFlex bug producing a faulty scanner etc.).
-   *
-   * Usual syntax/scanner level error handling should be done
-   * in error fallback rules.
-   *
-   * @param   errorCode  the code of the errormessage to display
-   */
-  private void zzScanError(int errorCode) {
-    String message;
-    try {
-      message = ZZ_ERROR_MSG[errorCode];
-    }
-    catch (ArrayIndexOutOfBoundsException e) {
-      message = ZZ_ERROR_MSG[ZZ_UNKNOWN_ERROR];
-    }
-
-    throw new Error(message);
-  } 
-
-
-  /**
-   * Pushes the specified amount of characters back into the input stream.
-   *
-   * They will be read again by then next call of the scanning method
-   *
-   * @param number  the number of characters to be read again.
-   *                This number must not be greater than yylength()!
-   */
-  public void yypushback(int number)  {
-    if ( number > yylength() )
-      zzScanError(ZZ_PUSHBACK_2BIG);
-
-    zzMarkedPos -= number;
-  }
-
-
-  /**
-   * Resumes scanning until the next regular expression is matched,
-   * the end of input is encountered or an I/O-Error occurs.
-   *
-   * @return      the next token
-   * @exception   java.io.IOException  if any I/O-Error occurs
-   */
-  public Yytoken yylex() throws java.io.IOException {
-    int zzInput;
-    int zzAction;
-
-    // cached fields:
-    int zzCurrentPosL;
-    int zzMarkedPosL;
-    int zzEndReadL = zzEndRead;
-    char [] zzBufferL = zzBuffer;
-    char [] zzCMapL = ZZ_CMAP;
-
-    int [] zzTransL = ZZ_TRANS;
-    int [] zzRowMapL = ZZ_ROWMAP;
-    int [] zzAttrL = ZZ_ATTRIBUTE;
-
-    while (true) {
-      zzMarkedPosL = zzMarkedPos;
-
-      zzAction = -1;
-
-      zzCurrentPosL = zzCurrentPos = zzStartRead = zzMarkedPosL;
-  
-      zzState = zzLexicalState;
-
-
-      zzForAction: {
-        while (true) {
-    
-          if (zzCurrentPosL < zzEndReadL)
-            zzInput = zzBufferL[zzCurrentPosL++];
-          else if (zzAtEOF) {
-            zzInput = YYEOF;
-            break zzForAction;
-          }
-          else {
-            // store back cached positions
-            zzCurrentPos  = zzCurrentPosL;
-            zzMarkedPos   = zzMarkedPosL;
-            boolean eof = zzRefill();
-            // get translated positions and possibly new buffer
-            zzCurrentPosL  = zzCurrentPos;
-            zzMarkedPosL   = zzMarkedPos;
-            zzBufferL      = zzBuffer;
-            zzEndReadL     = zzEndRead;
-            if (eof) {
-              zzInput = YYEOF;
-              break zzForAction;
-            }
-            else {
-              zzInput = zzBufferL[zzCurrentPosL++];
-            }
-          }
-          int zzNext = zzTransL[ zzRowMapL[zzState] + zzCMapL[zzInput] ];
-          if (zzNext == -1) break zzForAction;
-          zzState = zzNext;
-
-          int zzAttributes = zzAttrL[zzState];
-          if ( (zzAttributes & 1) == 1 ) {
-            zzAction = zzState;
-            zzMarkedPosL = zzCurrentPosL;
-            if ( (zzAttributes & 8) == 8 ) break zzForAction;
-          }
-
-        }
-      }
-
-      // store back cached position
-      zzMarkedPos = zzMarkedPosL;
-
-      switch (zzAction < 0 ? zzAction : ZZ_ACTION[zzAction]) {
-        case 24: 
+
+
+  /**
+   * Creates a new scanner
+   * There is also a java.io.InputStream version of this constructor.
+   *
+   * @param   in  the java.io.Reader to read input from.
+   */
+  CSSTokenizerFilter(java.io.Reader in) {
+    this.zzReader = in;
+  }
+
+  /**
+   * Creates a new scanner.
+   * There is also java.io.Reader version of this constructor.
+   *
+   * @param   in  the java.io.Inputstream to read input from.
+   */
+  CSSTokenizerFilter(java.io.InputStream in) {
+    this(new java.io.InputStreamReader(in));
+  }
+
+  /** 
+   * Unpacks the compressed character translation table.
+   *
+   * @param packed   the packed character translation table
+   * @return         the unpacked character translation table
+   */
+  private static char [] zzUnpackCMap(String packed) {
+    char [] map = new char[0x10000];
+    int i = 0;  /* index in packed string  */
+    int j = 0;  /* index in unpacked array */
+    while (i < 182) {
+      int  count = packed.charAt(i++);
+      char value = packed.charAt(i++);
+      do map[j++] = value; while (--count > 0);
+    }
+    return map;
+  }
+
+
+  /**
+   * Refills the input buffer.
+   *
+   * @return      <code>false</code>, iff there was new input.
+   * 
+   * @exception   java.io.IOException  if any I/O-Error occurs
+   */
+  private boolean zzRefill() throws java.io.IOException {
+
+    /* first: make room (if you can) */
+    if (zzStartRead > 0) {
+      System.arraycopy(zzBuffer, zzStartRead,
+                       zzBuffer, 0,
+                       zzEndRead-zzStartRead);
+
+      /* translate stored positions */
+      zzEndRead-= zzStartRead;
+      zzCurrentPos-= zzStartRead;
+      zzMarkedPos-= zzStartRead;
+      zzPushbackPos-= zzStartRead;
+      zzStartRead = 0;
+    }
+
+    /* is the buffer big enough? */
+    if (zzCurrentPos >= zzBuffer.length) {
+      /* if not: blow it up */
+      char newBuffer[] = new char[zzCurrentPos*2];
+      System.arraycopy(zzBuffer, 0, newBuffer, 0, zzBuffer.length);
+      zzBuffer = newBuffer;
+    }
+
+    /* finally: fill the buffer with new input */
+    int numRead = zzReader.read(zzBuffer, zzEndRead,
+                                            zzBuffer.length-zzEndRead);
+
+    if (numRead < 0) {
+      return true;
+    }
+    else {
+      zzEndRead+= numRead;
+      return false;
+    }
+  }
+
+    
+  /**
+   * Closes the input stream.
+   */
+  public final void yyclose() throws java.io.IOException {
+    zzAtEOF = true;            /* indicate end of file */
+    zzEndRead = zzStartRead;  /* invalidate buffer    */
+
+    if (zzReader != null)
+      zzReader.close();
+  }
+
+
+  /**
+   * Resets the scanner to read from a new input stream.
+   * Does not close the old reader.
+   *
+   * All internal variables are reset, the old input stream 
+   * <b>cannot</b> be reused (internal buffer is discarded and lost).
+   * Lexical state is set to <tt>ZZ_INITIAL</tt>.
+   *
+   * @param reader   the new input stream 
+   */
+  public final void yyreset(java.io.Reader reader) {
+    zzReader = reader;
+    zzAtBOL  = true;
+    zzAtEOF  = false;
+    zzEndRead = zzStartRead = 0;
+    zzCurrentPos = zzMarkedPos = zzPushbackPos = 0;
+    yyline = yychar = yycolumn = 0;
+    zzLexicalState = YYINITIAL;
+  }
+
+
+  /**
+   * Returns the current lexical state.
+   */
+  public final int yystate() {
+    return zzLexicalState;
+  }
+
+
+  /**
+   * Enters a new lexical state
+   *
+   * @param newState the new lexical state
+   */
+  public final void yybegin(int newState) {
+    zzLexicalState = newState;
+  }
+
+
+  /**
+   * Returns the text matched by the current regular expression.
+   */
+  public final String yytext() {
+    return new String( zzBuffer, zzStartRead, zzMarkedPos-zzStartRead );
+  }
+
+
+  /**
+   * Returns the character at position <tt>pos</tt> from the 
+   * matched text. 
+   * 
+   * It is equivalent to yytext().charAt(pos), but faster
+   *
+   * @param pos the position of the character to fetch. 
+   *            A value from 0 to yylength()-1.
+   *
+   * @return the character at position pos
+   */
+  public final char yycharat(int pos) {
+    return zzBuffer[zzStartRead+pos];
+  }
+
+
+  /**
+   * Returns the length of the matched text region.
+   */
+  public final int yylength() {
+    return zzMarkedPos-zzStartRead;
+  }
+
+
+  /**
+   * Reports an error that occured while scanning.
+   *
+   * In a wellformed scanner (no or only correct usage of 
+   * yypushback(int) and a match-all fallback rule) this method 
+   * will only be called with things that "Can't Possibly Happen".
+   * If this method is called, something is seriously wrong
+   * (e.g. a JFlex bug producing a faulty scanner etc.).
+   *
+   * Usual syntax/scanner level error handling should be done
+   * in error fallback rules.
+   *
+   * @param   errorCode  the code of the errormessage to display
+   */
+  private void zzScanError(int errorCode) {
+    String message;
+    try {
+      message = ZZ_ERROR_MSG[errorCode];
+    }
+    catch (ArrayIndexOutOfBoundsException e) {
+      message = ZZ_ERROR_MSG[ZZ_UNKNOWN_ERROR];
+    }
+
+    throw new Error(message);
+  } 
+
+
+  /**
+   * Pushes the specified amount of characters back into the input stream.
+   *
+   * They will be read again by then next call of the scanning method
+   *
+   * @param number  the number of characters to be read again.
+   *                This number must not be greater than yylength()!
+   */
+  public void yypushback(int number)  {
+    if ( number > yylength() )
+      zzScanError(ZZ_PUSHBACK_2BIG);
+
+    zzMarkedPos -= number;
+  }
+
+
+  /**
+   * Resumes scanning until the next regular expression is matched,
+   * the end of input is encountered or an I/O-Error occurs.
+   *
+   * @return      the next token
+   * @exception   java.io.IOException  if any I/O-Error occurs
+   */
+  public Yytoken yylex() throws java.io.IOException {
+    int zzInput;
+    int zzAction;
+
+    // cached fields:
+    int zzCurrentPosL;
+    int zzMarkedPosL;
+    int zzEndReadL = zzEndRead;
+    char [] zzBufferL = zzBuffer;
+    char [] zzCMapL = ZZ_CMAP;
+
+    int [] zzTransL = ZZ_TRANS;
+    int [] zzRowMapL = ZZ_ROWMAP;
+    int [] zzAttrL = ZZ_ATTRIBUTE;
+
+    while (true) {
+      zzMarkedPosL = zzMarkedPos;
+
+      zzAction = -1;
+
+      zzCurrentPosL = zzCurrentPos = zzStartRead = zzMarkedPosL;
+  
+      zzState = zzLexicalState;
+
+
+      zzForAction: {
+        while (true) {
+    
+          if (zzCurrentPosL < zzEndReadL)
+            zzInput = zzBufferL[zzCurrentPosL++];
+          else if (zzAtEOF) {
+            zzInput = YYEOF;
+            break zzForAction;
+          }
+          else {
+            // store back cached positions
+            zzCurrentPos  = zzCurrentPosL;
+            zzMarkedPos   = zzMarkedPosL;
+            boolean eof = zzRefill();
+            // get translated positions and possibly new buffer
+            zzCurrentPosL  = zzCurrentPos;
+            zzMarkedPosL   = zzMarkedPos;
+            zzBufferL      = zzBuffer;
+            zzEndReadL     = zzEndRead;
+            if (eof) {
+              zzInput = YYEOF;
+              break zzForAction;
+            }
+            else {
+              zzInput = zzBufferL[zzCurrentPosL++];
+            }
+          }
+          int zzNext = zzTransL[ zzRowMapL[zzState] + zzCMapL[zzInput] ];
+          if (zzNext == -1) break zzForAction;
+          zzState = zzNext;
+
+          int zzAttributes = zzAttrL[zzState];
+          if ( (zzAttributes & 1) == 1 ) {
+            zzAction = zzState;
+            zzMarkedPosL = zzCurrentPosL;
+            if ( (zzAttributes & 8) == 8 ) break zzForAction;
+          }
+
+        }
+      }
+
+      // store back cached position
+      zzMarkedPos = zzMarkedPosL;
+
+      switch (zzAction < 0 ? zzAction : ZZ_ACTION[zzAction]) {
+        case 24: 
           { // This is horrible. However it seems that there is no other way 
to do it with either jflex or CUP, as {URL} cannot be an unambiguous token :(
        String s = yytext();
        if(debug) log("Recognized URL: "+s);
@@ -1372,126 +1379,117 @@
                }
        } catch (CommentException e) {
                w.write("/* "+commentEncode(e.getMessage())+" */");
-       }
-          }
-        case 33: break;
-        case 20: 
+       }
+          }
+        case 33: break;
+        case 20: 
           { String s = yytext();
        w.write(s);
-       if(debug) log("Matched unicode: "+s);
-          }
-        case 34: break;
-        case 8: 
+       if(debug) log("Matched unicode: "+s);
+          }
+        case 34: break;
+        case 28: 
+          { if(debug) log("Deleted unofficial ident with url: "+yytext());
+       w.write("/* " + l10n("deletedUnofficialIdentWithURL") + " */");
+          }
+        case 35: break;
+        case 8: 
           { String s = yytext();
        w.write(s);
-       if(debug) log("Matched close braces: "+s);
-          }
-        case 35: break;
-        case 23: 
+       if(debug) log("Matched close braces: "+s);
+          }
+        case 36: break;
+        case 23: 
           { String s = yytext();
        w.write(s);
-       if(debug) log("Matched HTML comment: "+s);
-          }
-        case 36: break;
-        case 13: 
-          { if(debug) log("Deleted unofficial ident: "+yytext());
-       w.write("/* Deleted unofficial ident */");
-          }
-        case 37: break;
-        case 17: 
+       if(debug) log("Matched HTML comment: "+s);
+          }
+        case 37: break;
+        case 12: 
           { String s = yytext();
-       w.write(s); 
-       if(debug) log("Matched ~=: "+s);
-          }
-        case 38: break;
-        case 12: 
-          { String s = yytext();
        if(debug) log("Matched string: "+s);
        if(paranoidStringCheck && s.indexOf(':') != -1) {
-               w.write("/* Deleted disallowed string */");
+               w.write("/* "+l10n("deletedDisallowedString")+" */");
                log("Deleted disallowed string: "+s);
        } else {
                w.write(s);
-       }
-          }
-        case 39: break;
-        case 26: 
+       }
+          }
+        case 38: break;
+        case 17: 
           { String s = yytext();
+       w.write(s); 
+       if(debug) log("Matched ~=: "+s);
+          }
+        case 39: break;
+        case 26: 
+          { String s = yytext();
        w.write(s);
-       if(debug) log("Matched @page: "+s);
-          }
-        case 40: break;
-        case 14: 
+       if(debug) log("Matched @page: "+s);
+          }
+        case 40: break;
+        case 14: 
           { String s = yytext();
        w.write(s);
-       if(debug) log("Matched number: "+s);
-          }
-        case 41: break;
-        case 1: 
+       if(debug) log("Matched number: "+s);
+          }
+        case 41: break;
+        case 6: 
           { String s = yytext();
-       char c = s.charAt(0);
-       log("Matched anything: "+yytext()+" - ignoring");
-       w.write("/* ignored unmatched char: "+c+" */"); // single char cannot 
break out of comment
-          }
-        case 42: break;
-        case 6: 
-          { String s = yytext();
        w.write(s);
-       if(debug) log("Matched semicolon: "+s);
-          }
-        case 43: break;
-        case 21: 
+       if(debug) log("Matched semicolon: "+s);
+          }
+        case 42: break;
+        case 21: 
           { String s = yytext();
        if(debug) log("Got hexcolor: "+s);
-       w.write(s);
-          }
-        case 44: break;
-        case 7: 
+       w.write(s);
+          }
+        case 43: break;
+        case 7: 
           { String s = yytext();
        w.write(s);
-       if(debug) log("Matched open braces: "+s);
-          }
-        case 45: break;
-        case 27: 
+       if(debug) log("Matched open braces: "+s);
+          }
+        case 44: break;
+        case 27: 
           { String s = yytext();
        s = s.substring("@media".length()).trim();
        w.write("@media "+s+" ");
-       if(debug) log("Matched @media: "+s);
-          }
-        case 46: break;
-        case 2: 
+       if(debug) log("Matched @media: "+s);
+          }
+        case 45: break;
+        case 2: 
           { String s = yytext();
        w.write(s);
-       if(debug) log("Matched ident: "+s);
-          }
-        case 47: break;
-        case 25: 
+       if(debug) log("Matched ident: "+s);
+          }
+        case 46: break;
+        case 25: 
           { String s = yytext();
        w.write(s);
-       if(debug) log("Matched unicode range: "+s);
-          }
-        case 48: break;
-        case 30: 
+       if(debug) log("Matched unicode range: "+s);
+          }
+        case 47: break;
+        case 30: 
           { String s = yytext();
        w.write(s);
-       if(debug) log("Matched @font-face: "+s);
-          }
-        case 49: break;
-        case 19: 
+       if(debug) log("Matched @font-face: "+s);
+          }
+        case 48: break;
+        case 13: 
+          { if(debug) log("Deleted unofficial ident: "+yytext());
+       w.write("/* " + l10n("deletedUnofficialIdent") + " */");
+          }
+        case 49: break;
+        case 19: 
           { String s = yytext();
        w.write(s); 
-       if(debug) log("Matched HTML comment: "+s);
-          }
-        case 50: break;
-        case 9: 
+       if(debug) log("Matched HTML comment: "+s);
+          }
+        case 50: break;
+        case 29: 
           { String s = yytext();
-       if(s.startsWith("url")) throwError("Invalid contents of url()");
-       w.write(s);
-       if(debug) log("Matched function start: "+s);
-          }
-        case 51: break;
-        case 29: 
-          { String s = yytext();
        if(debug) log("Found @import: "+s);
        s = s.substring("@import".length());
        s = s.trim();
@@ -1512,22 +1510,29 @@
                        if(debug) log("Dropped @import");
        } catch (CommentException e) {
                w.write("/* " + commentEncode(e.getMessage()) + " */");
-       }
-          }
-        case 52: break;
-        case 3: 
+       }
+          }
+        case 51: break;
+        case 3: 
           { String s = yytext();
        w.write(s);
-       if(debug) log("Matched whitespace: "+s);
-          }
-        case 53: break;
-        case 31: 
+       if(debug) log("Matched whitespace: "+s);
+          }
+        case 52: break;
+        case 1: 
           { String s = yytext();
+       char c = s.charAt(0);
+       log("Matched anything: "+yytext()+" - ignoring");
+       w.write("/* "+l10n("deletedUnmatchedChar")+" "+c+" */"); // single char 
cannot break out of comment
+          }
+        case 53: break;
+        case 31: 
+          { String s = yytext();
        w.write(s);
-       if(debug) log("Matched important: "+s);
-          }
-        case 54: break;
-        case 22: 
+       if(debug) log("Matched important: "+s);
+          }
+        case 54: break;
+        case 22: 
           { String s = yytext();
        StringBuffer sb = new StringBuffer(s.length());
        sb.append("/* ");
@@ -1549,44 +1554,39 @@
                sb.deleteCharAt(sb.length()-1);
        sb.append(" */");
        w.write(sb.toString());
-       if(debug) log("Matched comment: "+s+" -> "+sb.toString());
-          }
-        case 55: break;
-        case 28: 
-          { if(debug) log("Deleted unofficial ident with url: "+yytext());
-       w.write("/* Deleted unofficial ident with url */");
-          }
-        case 56: break;
-        case 16: 
+       if(debug) log("Matched comment: "+s+" -> "+sb.toString());
+          }
+        case 55: break;
+        case 16: 
           { if(!deleteErrors) {
-               throwError("Unknown @identifier "+yytext());
+               throwError(l10n("unknownAtIdentifierLabel")+" "+yytext());
        } else {
                String s = yytext();
                if(debug) log("Discarded identifier: "+s);
                // Ignore
-       }
-          }
-        case 57: break;
-        case 11: 
+       }
+          }
+        case 56: break;
+        case 11: 
           { String s = yytext();
        w.write(s);
-       if(debug) log("Matched measurement: "+s);
-          }
-        case 58: break;
-        case 18: 
+       if(debug) log("Matched measurement: "+s);
+          }
+        case 57: break;
+        case 18: 
           { String s = yytext();
        w.write(s);
-       if(debug) log("Matched |=: "+s);
-          }
-        case 59: break;
-        case 32: 
+       if(debug) log("Matched |=: "+s);
+          }
+        case 58: break;
+        case 32: 
           { String s = yytext();
        detectedCharset = s;
        if(debug) log("Matched and ignoring charset: "+s);
-       // Ignore
-          }
-        case 60: break;
-        case 10: 
+       // Ignore
+          }
+        case 59: break;
+        case 10: 
           { if(postBadImportFlag) {
                // Ignore
                postBadImportFlag = false;
@@ -1596,38 +1596,45 @@
                String s = yytext();
                w.write(s);
                if(debug) log("Matched and passing on mediums list: "+s);
-       }
-          }
-        case 61: break;
-        case 4: 
+       }
+          }
+        case 60: break;
+        case 9: 
           { String s = yytext();
+       if(s.startsWith("url")) throwError(l10n("invalidURLContents"));
        w.write(s);
-       if(debug) log("Matched single char: "+s);
-          }
-        case 62: break;
-        case 15: 
+       if(debug) log("Matched function start: "+s);
+          }
+        case 61: break;
+        case 4: 
           { String s = yytext();
        w.write(s);
-       if(debug) log("Matched #name: "+s);
-          }
-        case 63: break;
-        case 5: 
+       if(debug) log("Matched single char: "+s);
+          }
+        case 62: break;
+        case 15: 
           { String s = yytext();
        w.write(s);
-       if(debug) log("Matched function end: "+s);
-          }
-        case 64: break;
-        default: 
-          if (zzInput == YYEOF && zzStartRead == zzCurrentPos) {
-            zzAtEOF = true;
-            return null;
-          } 
-          else {
-            zzScanError(ZZ_NO_MATCH);
-          }
-      }
-    }
-  }
-
-
-}
+       if(debug) log("Matched #name: "+s);
+          }
+        case 63: break;
+        case 5: 
+          { String s = yytext();
+       w.write(s);
+       if(debug) log("Matched function end: "+s);
+          }
+        case 64: break;
+        default: 
+          if (zzInput == YYEOF && zzStartRead == zzCurrentPos) {
+            zzAtEOF = true;
+            return null;
+          } 
+          else {
+            zzScanError(ZZ_NO_MATCH);
+          }
+      }
+    }
+  }
+
+
+}

Modified: trunk/freenet/src/freenet/clients/http/filter/CSSTokenizerFilter.jflex
===================================================================
--- trunk/freenet/src/freenet/clients/http/filter/CSSTokenizerFilter.jflex      
2007-05-10 13:51:45 UTC (rev 13198)
+++ trunk/freenet/src/freenet/clients/http/filter/CSSTokenizerFilter.jflex      
2007-05-10 17:38:21 UTC (rev 13199)
@@ -4,6 +4,7 @@
 package freenet.clients.http.filter;
 import java.io.*;
 import java.util.*;
+import freenet.l10n.L10n;
 /* This class tokenizes a CSS2 Reader stream, writes it out to the output 
Writer, and filters any URLs found */
 // WARNING: this is not as thorough as the HTML parser - new versions of the 
standard could lead to anonymity risks. See comments in SaferFilter.java
 // FIXME: Rewrite this as a proper whitelist filter. It's about half way 
there, it
@@ -76,6 +77,10 @@
                        '0' <= c && c <= '9');
        }

+       static String l10n(String key) {
+               return L10n.getString("CSSTokenizerFilter."+key);
+       }
+       
        class DecodedStringThingy {
                char quote; // " " means not quoted
                boolean url; // in a url() ?
@@ -119,9 +124,10 @@
                                                // Ignore one whitespace char 
after an escape
                                                int d = 
Integer.parseInt(hexEscape.toString(),
                                                                         16);
+                                               // FIXME once we can use 1.5, 
use Characters.toChars(int).
                                                if(d > 0xFFFF) {
                                                        String error = 
-                                                           "UCS-4 CHARACTERS 
OVER 0xFFFF NOT SUPPORTED!";
+                                                               
l10n("supplementalCharsNotSupported");
                                                        logError(error);
                                                        try {
                                                                w.write("/* 
"+error+"*/");
@@ -135,9 +141,10 @@
                                        } else {
                                                int d = 
Integer.parseInt(hexEscape.toString(),
                                                                         16);
+                                               // FIXME once we can use 1.5, 
use Characters.toChars(int).
                                                if(d > 0xFFFF) {
                                                        String error = 
-                                                           "UCS-4 CHARACTERS 
OVER 0xFFFF NOT SUPPORTED!";
+                                                               
l10n("supplementalCharsNotSupported");
                                                        logError(error);
                                                        try {
                                                                w.write("/* 
"+error+"*/");
@@ -386,11 +393,11 @@
 }
 {UNOFFICIAL_IDENT} {
        if(debug) log("Deleted unofficial ident: "+yytext());
-       w.write("/* Deleted unofficial ident */");
+       w.write("/* " + l10n("deletedUnofficialIdent") + " */");
 }
 {UNOFFICIAL_IDENT}{W}":"{W}{REALURL} {
        if(debug) log("Deleted unofficial ident with url: "+yytext());
-       w.write("/* Deleted unofficial ident with url */");
+       w.write("/* " + l10n("deletedUnofficialIdentWithURL") + " */");
 }
 "@page" {
        String s = yytext();
@@ -460,7 +467,7 @@
 }
 {IDENT}"(" {
        String s = yytext();
-       if(s.startsWith("url")) throwError("Invalid contents of url()");
+       if(s.startsWith("url")) throwError(l10n("invalidURLContents"));
        w.write(s);
        if(debug) log("Matched function start: "+s);
 }
@@ -478,7 +485,7 @@
        String s = yytext();
        if(debug) log("Matched string: "+s);
        if(paranoidStringCheck && s.indexOf(':') != -1) {
-               w.write("/* Deleted disallowed string */");
+               w.write("/* "+l10n("deletedDisallowedString")+" */");
                log("Deleted disallowed string: "+s);
        } else {
                w.write(s);
@@ -497,7 +504,7 @@
 // @-directives above (@page, @media). Since these can have sub-{}'s this 
probably isn't possible.
 "@"{IDENT} {
        if(!deleteErrors) {
-               throwError("Unknown @identifier "+yytext());
+               throwError(l10n("unknownAtIdentifierLabel")+" "+yytext());
        } else {
                String s = yytext();
                if(debug) log("Discarded identifier: "+s);
@@ -509,5 +516,5 @@
        String s = yytext();
        char c = s.charAt(0);
        log("Matched anything: "+yytext()+" - ignoring");
-       w.write("/* ignored unmatched char: "+c+" */"); // single char cannot 
break out of comment
+       w.write("/* "+l10n("deletedUnmatchedChar")+" "+c+" */"); // single char 
cannot break out of comment
 }

Modified: trunk/freenet/src/freenet/clients/http/filter/GIFFilter.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/filter/GIFFilter.java        
2007-05-10 13:51:45 UTC (rev 13198)
+++ trunk/freenet/src/freenet/clients/http/filter/GIFFilter.java        
2007-05-10 17:38:21 UTC (rev 13199)
@@ -10,6 +10,7 @@
 import java.util.Arrays;
 import java.util.HashMap;

+import freenet.l10n.L10n;
 import freenet.support.HTMLNode;
 import freenet.support.api.Bucket;
 import freenet.support.api.BucketFactory;
@@ -20,11 +21,6 @@
  */
 public class GIFFilter implements ContentDataFilter {

-       static final String ERROR_MESSAGE = 
-               "The file you tried to fetch is not a GIF. "+
-               "It might be some other file format, and your browser may do 
something dangerous with it, "+
-               "therefore we have blocked it.";
-       
        static final int HEADER_SIZE = 6;
        static final byte[] gif87aHeader =
                { (byte)'G', (byte)'I', (byte)'F', (byte)'8', (byte)'7', 
(byte)'a' };
@@ -36,7 +32,7 @@
                        HashMap otherParams, FilterCallback cb) throws 
DataFilterException,
                        IOException {
                if(data.size() < 6) {
-                       throwHeaderError("Too short", "The file is too short to 
be a GIF.");
+                       throwHeaderError(l10n("tooShortTitle"), 
l10n("tooShort"));
                }
                InputStream is = data.getInputStream();
                BufferedInputStream bis = new BufferedInputStream(is);
@@ -46,7 +42,7 @@
                        byte[] headerCheck = new byte[HEADER_SIZE];
                        dis.read(headerCheck);
                        if((!Arrays.equals(headerCheck, gif87aHeader)) && 
(!Arrays.equals(headerCheck, gif89aHeader))) {
-                               throwHeaderError("Invalid header", "The file 
does not contain a valid GIF header.");
+                               throwHeaderError(l10n("invalidHeaderTitle"), 
l10n("invalidHeader"));
                        }
                } finally {
                        dis.close();
@@ -54,9 +50,13 @@
                return data;
        }

+       private static String l10n(String key) {
+               return L10n.getString("GIFFilter."+key);
+       }
+
        private void throwHeaderError(String shortReason, String reason) throws 
DataFilterException {
                // Throw an exception
-               String message = ERROR_MESSAGE;
+               String message = l10n("notGif");
                if(reason != null) message += ' ' + reason;
                if(shortReason != null)
                        message += " - (" + shortReason + ')';

Modified: 
trunk/freenet/src/freenet/clients/http/filter/GenericReadFilterCallback.java
===================================================================
--- 
trunk/freenet/src/freenet/clients/http/filter/GenericReadFilterCallback.java    
    2007-05-10 13:51:45 UTC (rev 13198)
+++ 
trunk/freenet/src/freenet/clients/http/filter/GenericReadFilterCallback.java    
    2007-05-10 17:38:21 UTC (rev 13199)
@@ -12,6 +12,7 @@

 import freenet.clients.http.HTTPRequestImpl;
 import freenet.keys.FreenetURI;
+import freenet.l10n.L10n;
 import freenet.support.HTMLEncoder;
 import freenet.support.Logger;
 import freenet.support.URIPreEncoder;
@@ -71,7 +72,7 @@
                        if(logMINOR) Logger.minor(this, "Resolved: "+resolved);
                } catch (URISyntaxException e1) {
                        if(logMINOR) Logger.minor(this, "Failed to parse URI: 
"+e1);
-                       throw new CommentException("Filter could not parse URI: 
"+e1.getMessage());
+                       throw new 
CommentException(l10n("couldNotParseURIWithError", "error", 
e1.getLocalizedMessage()));
                }
                String path = uri.getPath();

@@ -98,60 +99,76 @@

                String rpath = uri.getPath();

+               boolean isAbsolute = false;
+               
                if(rpath != null) {
                        if(logMINOR) Logger.minor(this, "Resolved URI (rpath 
absolute): "+rpath);

                        // Valid FreenetURI?
                        try {
                                String p = rpath;
-                               while(p.startsWith("/")) p = p.substring(1);
+                               while(p.startsWith("/")) {
+                                       isAbsolute = true;
+                                       p = p.substring(1);
+                               }
                                FreenetURI furi = new FreenetURI(p);
                                if(logMINOR) Logger.minor(this, "Parsed: 
"+furi);
                                return processURI(furi, uri, overrideType, 
noRelative);
                        } catch (MalformedURLException e) {
                                // Not a FreenetURI
                                if(logMINOR) Logger.minor(this, "Malformed URL 
(a): "+e, e);
-                               reason = "Malformed URL (absolute): 
"+e.getMessage();
-                               if(e.getMessage() == null) {
-                                       reason = "Could not be parsed as a 
Freenet URI";
+                               if(e.getMessage() != null) {
+                                       reason = l10n("malformedAbsoluteURL", 
"error", e.getLocalizedMessage());
+                               } else {
+                                       reason = 
l10n("couldNotParseAbsoluteFreenetURI");
                                }
                        }
                }

-               // Probably a relative URI.
+               if(!isAbsolute) {

-               rpath = resolved.getPath();
-               if(rpath == null) throw new CommentException("No URI");
-               if(logMINOR) Logger.minor(this, "Resolved URI (rpath relative): 
"+rpath);
+                       // Relative URI
+                       
+                       rpath = resolved.getPath();
+                       if(rpath == null) throw new CommentException("No URI");
+                       if(logMINOR) Logger.minor(this, "Resolved URI (rpath 
relative): "+rpath);
+                       
+                       // Valid FreenetURI?
+                       try {
+                               String p = rpath;
+                               while(p.startsWith("/")) p = p.substring(1);
+                               FreenetURI furi = new FreenetURI(p);
+                               if(logMINOR) Logger.minor(this, "Parsed: 
"+furi);
+                               return processURI(furi, uri, overrideType, 
noRelative);
+                       } catch (MalformedURLException e) {
+                               if(logMINOR) Logger.minor(this, "Malformed URL 
(b): "+e, e);
+                               if(e.getMessage() != null) {
+                                       reason = l10n("malformedRelativeURL", 
"error", e.getLocalizedMessage());
+                               } else {
+                                       reason = 
l10n("couldNotParseRelativeFreenetURI");
+                               }
+                       }

-               // Valid FreenetURI?
-               try {
-                       String p = rpath;
-                       while(p.startsWith("/")) p = p.substring(1);
-                       FreenetURI furi = new FreenetURI(p);
-                       if(logMINOR) Logger.minor(this, "Parsed: "+furi);
-                       return processURI(furi, uri, overrideType, noRelative);
-               } catch (MalformedURLException e) {
-                       if(logMINOR) Logger.minor(this, "Malformed URL (b): 
"+e, e);
-                       if(reason.length() > 0)
-                               reason += " , ";
-                       if(e.getMessage() != null)
-                               reason += "Malformed URL (relative): 
"+e.getMessage();
-                       else
-                               reason += "Could not be parsed as a (relative) 
Freenet URI";
-                       // Not a FreenetURI
                }

                
if(GenericReadFilterCallback.allowedProtocols.contains(uri.getScheme()))
                        return 
"/?"+GenericReadFilterCallback.magicHTTPEscapeString+ '=' +uri;
                else {
                        if(uri.getScheme() == null) {
-                               throw new CommentException("Invalid Freenet 
URL: "+reason);
+                               throw new CommentException(reason);
                        }
-                       throw new CommentException("Not an escaped protocol: 
"+uri.getScheme());
+                       throw new CommentException(l10n("protocolNotEscaped", 
"protocol", uri.getScheme()));
                }
        }

+       private static String l10n(String key, String pattern, String value) {
+               return L10n.getString("GenericReadFilterCallback."+key, 
pattern, value);
+       }
+
+       private static String l10n(String key) {
+               return L10n.getString("GenericReadFilterCallback."+key);
+       }
+
        private String finishProcess(HTTPRequest req, String overrideType, 
String path, URI u, boolean noRelative) {
                String typeOverride = req.getParam("type", null);
                if(overrideType != null)
@@ -242,17 +259,17 @@
                try {
                        URI uri = URIPreEncoder.encodeURI(action);
                        if(uri.getScheme() != null || uri.getHost() != null || 
uri.getPort() != -1 || uri.getUserInfo() != null)
-                               throw new CommentException("Invalid form URI 
had scheme, user-info, host or port");
+                               throw new 
CommentException(l10n("invalidFormURI"));
                        String path = uri.getPath();
                        if(path.startsWith(PLUGINS_PREFIX)) {
                                String after = 
path.substring(PLUGINS_PREFIX.length());
                                if(after.indexOf("../") > -1)
-                                       throw new CommentException("Attempt to 
escape directory structure");
+                                       throw new 
CommentException(l10n("invalidFormURIAttemptToEscape"));
                                if(after.matches("[A-Za-z0-9\\.]+"))
                                        return uri.toASCIIString();
                        }
                } catch (URISyntaxException e) {
-                       throw new CommentException("Could not encode form URI");
+                       throw new 
CommentException(l10n("couldNotParseFormURIWithError", "error", 
e.getLocalizedMessage()));
                }
                // Otherwise disallow.
                return null;

Modified: trunk/freenet/src/freenet/clients/http/filter/HTMLFilter.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/filter/HTMLFilter.java       
2007-05-10 13:51:45 UTC (rev 13198)
+++ trunk/freenet/src/freenet/clients/http/filter/HTMLFilter.java       
2007-05-10 17:38:21 UTC (rev 13199)
@@ -24,6 +24,7 @@
 import java.util.StringTokenizer;
 import java.util.Vector;

+import freenet.l10n.L10n;
 import freenet.support.HTMLDecoder;
 import freenet.support.HTMLEncoder;
 import freenet.support.HTMLNode;
@@ -55,12 +56,7 @@
                } catch (UnsupportedEncodingException e) {
                        os.close();
                        strm.close();
-                       HTMLNode explanation = new HTMLNode("p");
-                       explanation.addChild("b", "Unknown character set!");
-                       explanation.addChild("#", " The page you are about to 
display has an unknown character set. This means that we are not able to filter 
the page, and it may compromize your anonymity.");
-                       throw new DataFilterException("Warning: Unknown 
character set ("+charset+ ')', "Warning: Unknown character set 
("+HTMLEncoder.encode(charset)+ ')',
-                                       "<p><b>Unknown character set</b> The 
page you are about to display has an unknown character set. "+
-                                       "This means that we are not able to 
filter the page, and it may compromize your anonymity.", explanation);
+                       throw UnknownCharsetException.create(e, charset);
                }
                HTMLParseContext pc = new HTMLParseContext(r, w, charset, cb);
                pc.run(temp);
@@ -375,7 +371,7 @@
                                        pc.writeStyleScriptWithTag = false;
                                        String style = 
pc.currentStyleScriptChunk;
                                        if ((style == null) || (style.length() 
== 0))
-                                               pc.writeAfterTag.append("<!-- 
deleted unknown style -->");
+                                               pc.writeAfterTag.append("<!-- 
"+l10n("deletedUnknownStyle")+" -->");
                                        else
                                                w.write(style);
                                        pc.currentStyleScriptChunk = "";
@@ -431,11 +427,10 @@
                w.write(" -->");
        }

-       static void throwFilterException(String s) throws DataFilterException {
+       static void throwFilterException(String msg) throws DataFilterException 
{
                // FIXME
-               throw new DataFilterException(s, s,
-                               "The HTML filter failed to parse the page: "+s,
-                               new HTMLNode("div", "The HTML filter failed to 
parse the page: " + s));
+               String longer = l10n("failedToParseLabel");
+               throw new DataFilterException(longer, longer, msg, new 
HTMLNode("div", msg));
        }

        static class ParsedTag {
@@ -496,20 +491,9 @@
                                if (deleteWierdStuff) {
                                        return null;
                                } else {
-                                       String err = "<!-- unknown tag ";
-                                       boolean safe = true;
-                                       for (int x = 0; x < element.length(); 
x++) {
-                                               if 
(!Character.isLetter(element.charAt(x))) {
-                                                       safe = false;
-                                                       break;
-                                               }
-                                       }
-                                       if (safe)
-                                               err += element + ' ';
-                                       err += "-->";
+                                       String err = "<!-- 
"+HTMLEncoder.encode(l10n("unknownTag", "tag", element))+ " -->";
                                        if (!deleteErrors)
-                                               throwFilterException(
-                                                       "Unknown tag: " + 
HTMLEncoder.encode(err));
+                                               
throwFilterException(l10n("unknownTagLabel") + ' ' + err);
                                        return null;
                                }
                        }
@@ -1241,9 +1225,9 @@
                        if (pc.styleScriptRecurseCount < 0) {
                                if (deleteErrors)
                                        pc.writeAfterTag.append(
-                                               "<!-- Too many nested style or 
script tags - ambiguous or invalid parsing -->");
+                                               "<!-- " + 
l10n("tooManyNestedStyleOrScriptTags") + " -->");
                                else
-                                       throwFilterException("Too many nested 
</style> tags - ambiguous or invalid parsing, can't reliably filter so removing 
the inner tags - garbage may appear in browser");
+                                       
throwFilterException(l10n("tooManyNestedStyleOrScriptTagsLong"));
                                return null;
                        }
                        if(!pc.killStyle) {
@@ -1263,10 +1247,9 @@
                        pc.styleScriptRecurseCount++;
                        if (pc.styleScriptRecurseCount > 1) {
                                if (deleteErrors)
-                                       pc.writeAfterTag.append(
-                                               "<!-- Too many nested style or 
script tags -->");
+                                       pc.writeAfterTag.append("<!-- " + 
l10n("tooManyNestedStyleOrScriptTags") + " -->");
                                else
-                                       throwFilterException("Too many nested 
</style> tags - ambiguous or invalid parsing, can't reliably filter so removing 
the inner tags - garbage may appear in browser");
+                                       
throwFilterException(l10n("tooManyNestedStyleOrScriptTagsLong"));
                                return null;
                        }
                        setStyle(true, pc);
@@ -1848,7 +1831,7 @@
                                        HTMLFilter.class,
                                        "CSS Parse Error!",
                                        e);
-                               return "/* Could not match input style */";
+                               return "/* "+l10n("couldNotParseStyle")+" */";
                        } else
                                throw e;
                }
@@ -1979,4 +1962,12 @@
                        return null;
        }

+       private static String l10n(String key) {
+               return L10n.getString("HTMLFilter."+key);
+       }
+
+       private static String l10n(String key, String pattern, String value) {
+               return L10n.getString("HTMLFilter."+key, pattern, value);
+       }
+
 }

Modified: trunk/freenet/src/freenet/clients/http/filter/JPEGFilter.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/filter/JPEGFilter.java       
2007-05-10 13:51:45 UTC (rev 13198)
+++ trunk/freenet/src/freenet/clients/http/filter/JPEGFilter.java       
2007-05-10 17:38:21 UTC (rev 13199)
@@ -15,6 +15,7 @@
 import java.util.Arrays;
 import java.util.HashMap;

+import freenet.l10n.L10n;
 import freenet.support.HTMLNode;
 import freenet.support.Logger;
 import freenet.support.api.Bucket;
@@ -29,7 +30,9 @@
  * Also the JFIF spec.
  * Also http://cs.haifa.ac.il/~nimrod/Compression/JPEG/J6sntx2005.pdf
  * http://svn.xiph.org/experimental/giles/jpegdump.c
- * 
+ *
+ * L10n: Only the overall explanation message and the "too short" messages are 
localised.
+ * It's probably not worth doing the others, they're way too detailed.
  */
 public class JPEGFilter implements ContentDataFilter {

@@ -46,11 +49,6 @@
                this.deleteExif = deleteExif;
        }

-       static final String ERROR_MESSAGE = 
-               "The file you tried to fetch is not a JPEG. "+
-               "It might be some other file format, and your browser may do 
something dangerous with it, "+
-               "therefore we have blocked it.";
-       
        static final byte[] soi = new byte[] {
                (byte)0xFF, (byte)0xD8 // Start of Image
        };
@@ -79,7 +77,7 @@
                boolean logMINOR = Logger.shouldLog(Logger.MINOR, this);
                long length = data.size();
                if(length < 6) {
-                       throwError("Too short", "The file is too short to be a 
JPEG.");
+                       throwError(l10n("tooShortTitle"), l10n("tooShort"));
                }
                InputStream is = data.getInputStream();
                BufferedInputStream bis = new BufferedInputStream(is);
@@ -297,6 +295,10 @@
                return data;
        }

+       private static String l10n(String key) {
+               return L10n.getString("JPEGFilter."+key);
+       }
+
        private void writeNullTerminatedString(ByteArrayOutputStream baos, 
String type) throws IOException {
                try {
                        byte[] data = type.getBytes("ISO-8859-1"); // ascii, 
near enough
@@ -360,7 +362,7 @@

        private void throwError(String shortReason, String reason) throws 
DataFilterException {
                // Throw an exception
-               String message = ERROR_MESSAGE;
+               String message = l10n("notJpeg");
                if(reason != null) 
                        message += ' ' + reason;
                if(shortReason != null)

Modified: 
trunk/freenet/src/freenet/clients/http/filter/KnownUnsafeContentTypeException.java
===================================================================
--- 
trunk/freenet/src/freenet/clients/http/filter/KnownUnsafeContentTypeException.java
  2007-05-10 13:51:45 UTC (rev 13198)
+++ 
trunk/freenet/src/freenet/clients/http/filter/KnownUnsafeContentTypeException.java
  2007-05-10 17:38:21 UTC (rev 13199)
@@ -3,6 +3,8 @@
  * http://www.gnu.org/ for further details of the GPL. */
 package freenet.clients.http.filter;

+import freenet.l10n.L10n;
+import freenet.support.HTMLEncoder;
 import freenet.support.HTMLNode;

 public class KnownUnsafeContentTypeException extends 
UnsafeContentTypeException {
@@ -17,27 +19,21 @@
                StringBuffer sb = new StringBuffer();
                sb.append("<p><b>");
                sb.append(type.readDescription);
-               sb.append("</b></p>\n" +
-                       "<p>This is a potentially dangerous MIME type. If the 
node lets it through, your browser may " +
-                       "do bad things leading to compromize of your anonymity, 
and your IP address being exposed in "+
-                       "connection with this page. In particular:<ul>");
+               sb.append("</b></p>\n" + "<p>" + l10n("knownUnsafe") + "<ul>");
                if(type.dangerousInlines) 
-                       sb.append("<li><font color=\"red\"><b>Dangerous 
inlines:</b></font> This type of content can contain inline images or "+
-                                       "videos, and can therefore load content 
from the non-anonymous open Web, exposing your "+
-                                       "IP address.</li>");
+                       sb.append("<li><font color=\"red\"><b>" + 
l10n("dangerousInlinesLabel") +
+                                       "</b></font> 
"+l10n("dangerousInline")+"</li>");
                if(type.dangerousLinks)
-                       sb.append("<li><font color=\"red\"><b>Dangerous 
links:</b></font> This type of content can contain links to the "+
-                                       "non-anonymous Web; if you click on 
them (and they may be disguised), this may expose "+
-                                       "your IP address.</li>");
+                       sb.append("<li><font color=\"red\"><b>" + 
l10n("dangerousLinksLabel") +
+                                       "</b></font> " + l10n("dangerousLinks") 
+ "</li>");
                if(type.dangerousScripting)
-                       sb.append("<li><font color=\"red\"><b>Dangerous 
scripting:</b></font> This type of content can contain dangerous scripts "+
-                                       "which when executed may compromize 
your anonymity by connecting to the open Web or "+
-                                       "otherwise breach security.</li>");
+                       sb.append("<li><font color=\"red\"><b>" + 
l10n("dangerousScriptsLabel") +
+                                       "</b></font> " + 
l10n("dangerousScripts") + "</li>");
                if(type.dangerousReadMetadata)
-                       sb.append("<li><font color=\"red\"><b>Dangerous 
metadata:</b></font> This type of content can contain metadata which may "+
-                                       "be displayed by some browsers or other 
software, which may contain dangerous links or inlines.</li>");
+                       sb.append("<li><font color=\"red\"><b>" + 
l10n("dangerousMetadataLabel") +
+                                       "</b></font> " + 
l10n("dangerousMetadata") + "</li>");

-               sb.append("</ul>Since there is no built-in filter for this 
data, you should take the utmost of care!");
+               sb.append("</ul>" + l10n("noFilter"));

                return sb.toString();
        }
@@ -45,39 +41,38 @@
        public HTMLNode getHTMLExplanation() {
                HTMLNode explanation = new HTMLNode("div");
                explanation.addChild("p").addChild("b", type.readDescription);
-               explanation.addChild("p", "This is a potentially dangerous MIME 
type. If the node lets it through, your browser may " +
-                       "do bad things leading to compromize of your anonymity, 
and your IP address being exposed in "+
-                       "connection with this page. In particular:");
+               explanation.addChild("p", l10n("knownUnsafe"));
                HTMLNode list = explanation.addChild("ul");
                HTMLNode reason = list.addChild("li");
-               reason.addChild("span", "class", "warning", "Dangerous 
inlines:");
-               reason.addChild("#", " This type of content can contain inline 
images or " +
-                                       "videos, and can therefore load content 
from the non-anonymous open Web, exposing your " +
-                                       "IP address.");
+               reason.addChild("span", "class", "warning", 
l10n("dangerousInlinesLabel"));
+               reason.addChild("#", " "+l10n("dangerousInlines"));
                reason = list.addChild("li");
-               reason.addChild("span", "class", "warning", "Dangerous links:");
-               reason.addChild("#", " This type of content can contain links 
to the " +
-                                       "non-anonymous Web; if you click on 
them (and they may be disguised), this may expose " +
-                                       "your IP address.");
+               reason.addChild("span", "class", "warning", 
l10n("dangerousLinksLabel"));
+               reason.addChild("#", " "+l10n("dangerousLinks"));
                reason = list.addChild("li");
-               reason.addChild("span", "class", "warning", "Dangerous 
scripting:");
-               reason.addChild("#", " This type of content can contain 
dangerous scripts "+
-                                       "which when executed may compromize 
your anonymity by connecting to the open Web or "+
-                                       "otherwise breach security.");
+               reason.addChild("span", "class", "warning", 
l10n("dangerousScriptsLabel"));
+               reason.addChild("#", " "+l10n("dangerousScripts"));
                reason = list.addChild("li");
-               reason.addChild("span", "class", "warning", "Dangerous 
metadata:");
-               reason.addChild("#", " This type of content can contain 
metadata which may "+
-                                       "be displayed by some browsers or other 
software, which may contain dangerous links or inlines.");
-               explanation.addChild("p", "Since there is no built-in filter 
for this data, you should take the utmost of care!");
+               reason.addChild("span", "class", "warning", 
l10n("dangerousMetadataLabel"));
+               reason.addChild("#", " "+l10n("dangerousMetadata"));
+               explanation.addChild("p", l10n("noFilter"));
                return explanation;
        }

        public String getHTMLEncodedTitle() {
-               return "Known dangerous type: "+type.primaryMimeType;
+               return l10n("title", "type", 
HTMLEncoder.encode(type.primaryMimeType));
        }

        public String getRawTitle() {
-               return "Known dangerous type: "+type.primaryMimeType;
+               return l10n("title", "type", type.primaryMimeType);
        }
+       
+       private static String l10n(String key) {
+               return L10n.getString("KnownUnsafeContentTypeException."+key);
+       }

+       private static String l10n(String key, String pattern, String value) {
+               return L10n.getString("KnownUnsafeContentTypeException."+key, 
pattern, value);
+       }
+
 }

Modified: trunk/freenet/src/freenet/clients/http/filter/PNGFilter.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/filter/PNGFilter.java        
2007-05-10 13:51:45 UTC (rev 13198)
+++ trunk/freenet/src/freenet/clients/http/filter/PNGFilter.java        
2007-05-10 17:38:21 UTC (rev 13199)
@@ -10,6 +10,7 @@
 import java.util.Arrays;
 import java.util.HashMap;

+import freenet.l10n.L10n;
 import freenet.support.HTMLNode;
 import freenet.support.api.Bucket;
 import freenet.support.api.BucketFactory;
@@ -35,11 +36,9 @@
                        dis.read(headerCheck);
                        if(!Arrays.equals(headerCheck, pngHeader)) {
                                // Throw an exception
-                               String message = 
-                                       "The file you tried to fetch is not a 
PNG. It does not include a valid PNG header. "+
-                                       "It might be some other file format, 
and your browser may do something dangerous with it, "+
-                                       "therefore we have blocked it."; 
-                               throw new DataFilterException("Not a PNG - 
invalid header", "Not a PNG - invalid header",
+                               String message = l10n("invalidHeader");
+                               String title = l10n("invalidHeaderTitle");
+                               throw new DataFilterException(title, title,
                                                "<p>"+message+"</p>", new 
HTMLNode("p").addChild("#", message));
                        }
                } finally {
@@ -48,6 +47,10 @@
                return data;
        }

+       private String l10n(String key) {
+               return L10n.getString("PNGFilter."+key);
+       }
+
        public Bucket writeFilter(Bucket data, BucketFactory bf, String charset,
                        HashMap otherParams, FilterCallback cb) throws 
DataFilterException,
                        IOException {

Added: 
trunk/freenet/src/freenet/clients/http/filter/UnknownCharsetException.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/filter/UnknownCharsetException.java  
                        (rev 0)
+++ trunk/freenet/src/freenet/clients/http/filter/UnknownCharsetException.java  
2007-05-10 17:38:21 UTC (rev 13199)
@@ -0,0 +1,37 @@
+package freenet.clients.http.filter;
+
+import java.io.UnsupportedEncodingException;
+
+import freenet.l10n.L10n;
+import freenet.support.HTMLNode;
+
+public class UnknownCharsetException extends DataFilterException {
+
+       public final String charset;
+       
+       private UnknownCharsetException(String warning, String warning2, String 
string, HTMLNode explanation, String charset) {
+               super(warning, warning2, string, explanation);
+               this.charset = charset;
+       }
+
+       public static UnknownCharsetException 
create(UnsupportedEncodingException e, String charset) {
+               HTMLNode explanation = new HTMLNode("p");
+               String explTitle = l10nDF("unknownCharsetTitle");
+               String expl = l10nDF("unknownCharset");
+               explanation.addChild("b", explTitle);
+               explanation.addChild("#", " " + expl);
+               String warning = l10nDF("warningUnknownCharsetTitle", 
"charset", charset);
+               return new UnknownCharsetException(warning, warning, explTitle 
+ " " + expl, explanation, charset);
+       }
+
+       private static String l10nDF(String key) {
+               // All the strings here are generic
+               return L10n.getString("ContentDataFilter."+key);
+       }
+
+       private static String l10nDF(String key, String pattern, String value) {
+               // All the strings here are generic
+               return L10n.getString("ContentDataFilter."+key, pattern, value);
+       }
+
+}

Modified: 
trunk/freenet/src/freenet/clients/http/filter/UnknownContentTypeException.java
===================================================================
--- 
trunk/freenet/src/freenet/clients/http/filter/UnknownContentTypeException.java  
    2007-05-10 13:51:45 UTC (rev 13198)
+++ 
trunk/freenet/src/freenet/clients/http/filter/UnknownContentTypeException.java  
    2007-05-10 17:38:21 UTC (rev 13199)
@@ -3,6 +3,7 @@
  * http://www.gnu.org/ for further details of the GPL. */
 package freenet.clients.http.filter;

+import freenet.l10n.L10n;
 import freenet.support.HTMLEncoder;
 import freenet.support.HTMLNode;

@@ -21,31 +22,27 @@
        }

        public String getHTMLEncodedTitle() {
-               return "Unknown and potentially dangerous content type: 
"+encodedType;
+               return l10n("title", "type", encodedType);
        }

        public String getRawTitle() {
-               return "Unknown and potentially dangerous content type: "+type;
+               return l10n("title", "type", type);
        }

        public String getExplanation() {
-               return "<p>Your Freenet node does not know anything about this 
MIME type. " +
-                               "This means that your browser might do 
something dangerous in response " +
-                               "to downloading this file. For example, many 
formats can contain embedded images " +
-                               "or videos, which are downloaded from the web; 
this is by no means innocuous, " +
-                               "because they can ruin your anonymity and 
expose your IP address (if the attacker " +
-                               "runs the web site or has access to its logs). 
Hyperlinks to the Web can also be a " +
-                               "threat, for much the same reason, as can 
scripting, for this and other reasons.</p>";
+               return l10n("explanation");
        }

        public HTMLNode getHTMLExplanation() {
-               return new HTMLNode("div", "Your Freenet node does not know 
anything about this MIME type. " +
-                               "This means that your browser might do 
something dangerous in response " +
-                               "to downloading this file. For example, many 
formats can contain embedded images " +
-                               "or videos, which are downloaded from the web; 
this is by no means innocuous, " +
-                               "because they can ruin your anonymity and 
expose your IP address (if the attacker " +
-                               "runs the web site or has access to its logs). 
Hyperlinks to the Web can also be a " +
-                               "threat, for much the same reason, as can 
scripting, for this and other reasons.");
+               return new HTMLNode("div", l10n("explanation"));
        }
+
+       private static String l10n(String key) {
+               return L10n.getString("UnknownContentTypeException."+key);
+       }

+       private static String l10n(String key, String pattern, String value) {
+               return L10n.getString("UnknownContentTypeException."+key, 
pattern, value);
+       }
+       
 }

Modified: trunk/freenet/src/freenet/l10n/freenet.l10n.en.properties
===================================================================
--- trunk/freenet/src/freenet/l10n/freenet.l10n.en.properties   2007-05-10 
13:51:45 UTC (rev 13198)
+++ trunk/freenet/src/freenet/l10n/freenet.l10n.en.properties   2007-05-10 
17:38:21 UTC (rev 13199)
@@ -859,5 +859,49 @@
 ContentDataFilter.unknownCharsetTitle=Unknown character set!
 ContentDataFilter.unknownCharset=The page you are about to display has an 
unknown character set. This means that we are not able to filter the page, and 
it may compromize your anonymity.
 ContentDataFilter.warningUnknownCharsetTitle=Warning: Unknown character set 
(${charset})
-ContentDataFilter.warningUnknownCharset=
+GenericReadFilterCallback.couldNotParseURIWithError=Filter could not parse 
URI: ${error}
+GenericReadFilterCallback.couldNotParseFormURIWithError=Filter could not parse 
form URI: ${error}
+GenericReadFilterCallback.malformedAbsoluteURL=Malformed URL (absolute): 
${error}
+GenericReadFilterCallback.malformedRelativeURL=Malformed URL (relative): 
${error}
+GenericReadFilterCallback.couldNotParseRelativeFreenetURI=Could not parse as a 
relative Freenet URI
+GenericReadFilterCallback.couldNotParseAbsoluteFreenetURI=Could not parse as 
an absolute Freenet URI
+GenericReadFilterCallback.protocolNotEscaped=Not an escaped protocol: 
${protocol}
+GenericReadFilterCallback.invalidFormURI=Invalid form URI had scheme, 
user-info, host or port
+GenericReadFilterCallback.invalidFormURIAttemptToEscape=Attempt to escape 
directory structure
+GIFFilter.notGif=The file you tried to fetch is not a GIF. It might be some 
other file format, and your browser may do something dangerous with it, 
therefore we have blocked it.
+GIFFilter.tooShortTitle=Too short
+GIFFilter.tooShort=The file is too short to be a GIF.
+GIFFilter.invalidHeaderTitle=Invalid header
+GIFFilter.invalidHeader=The file does not contain a valid GIF header.
+HTMLFilter.deletedUnknownStyle=deleted unknown style
+HTMLFilter.failedToParseLabel=The HTML filter failed to parse the page
+HTMLFilter.unknownTag=unknown tag ${tag}
+HTMLFilter.tooManyNestedStyleOrScriptTags=Too many nested style or script tags 
- ambiguous or invalid parsing
+HTMLFilter.tooManyNestedStyleOrScriptTagsLong=Too many nested </style> tags - 
ambiguous or invalid parsing, can't reliably filter so removing the inner tags 
- garbage may appear in browser
+HTMLFilter.couldNotParseStyle=Could not match input style
+JPEGFilter.notJpeg=The file you tried to fetch is not a JPEG. It might be some 
other file format, and your browser may do something dangerous with it, 
therefore we have blocked it.
+JPEGFilter.tooShortTitle=Too short
+JPEGFilter.tooShort=The file is too short to be a JPEG.
+PNGFilter.invalidHeaderTitle=Not a PNG - invalid header
+PNGFilter.invalidHeader=The file you tried to fetch is not a PNG. It does not 
include a valid PNG header. It might be some other file format, and your 
browser may do something dangerous with it, therefore we have blocked it.
+KnownUnsafeContentTypeException.knownUnsafe=This is a potentially dangerous 
MIME type. If the node lets it through, your browser may do bad things leading 
to compromize of your anonymity, and your IP address being exposed in 
connection with this page. In particular:
+KnownUnsafeContentTypeException.dangerousInlinesLabel=Dangerous inlines:
+KnownUnsafeContentTypeException.dangerousInlines=This type of content can 
contain inline images or videos, and can therefore load content from the 
non-anonymous open Web, exposing your IP address.
+KnownUnsafeContentTypeException.dangerousLinksLabel=Dangerous links:
+KnownUnsafeContentTypeException.dangerousLinks=This type of content can 
contain links to the non-anonymous Web; if you click on them (and they may be 
disguised), this may expose your IP address.
+KnownUnsafeContentTypeException.dangerousScriptsLabel=Dangerous scripting:
+KnownUnsafeContentTypeException.dangerousScripts=This type of content can 
contain dangerous scripts which when executed may compromize your anonymity by 
connecting to the open Web or otherwise breach security.
+KnownUnsafeContentTypeException.dangerousMetadataLabel=Dangerous metadata:
+KnownUnsafeContentTypeException.dangerousMetadata=This type of content can 
contain metadata which may be displayed by some browsers or other software, 
which may contain dangerous links or inlines.
+KnownUnsafeContentTypeException.noFilter=Since there is no built-in filter for 
this data, you should take the utmost of care!
+KnownUnsafeContentTypeException.title=Known dangerous type: ${type}
+UnknownContentTypeException.title=Unknown and potentially dangerous content 
type: ${type}
+UnknownContentTypeException.explanation=Your Freenet node does not know 
anything about this MIME type. This means that your browser might do something 
dangerous in response to downloading this file. For example, many formats can 
contain embedded images or videos, which are downloaded from the web; this is 
by no means innocuous, because they can ruin your anonymity and expose your IP 
address (if the attacker runs the web site or has access to its logs). 
Hyperlinks to the Web can also be a threat, for much the same reason, as can 
scripting, for this and other reasons.
+CSSTokenizerFilter.supplementalCharsNotSupported=UCS-4 CHARACTERS OVER 0xFFFF 
NOT SUPPORTED!
+CSSTokenizerFilter.deletedUnofficialIdent=Deleted unofficial ident
+CSSTokenizerFilter.deletedUnofficialIdentWithURL=Deleted unofficial ident with 
url
+CSSTokenizerFilter.deletedDisallowedString=Deleted disallowed string
+CSSTokenizerFilter.deletedUnmatchedChar=ignored unmatched char:
+CSSTokenizerFilter.invalidURLContents=Invalid contents of url()
+CSSTokenizerFilter.unknownAtIdentifierLabel=Unknown @identifier:
 End
\ No newline at end of file


Reply via email to