pax_global_header00006660000000000000000000000064120427221550014512gustar00rootroot0000000000000052 comment=5897e8e0d08e3461e6a7f0c63608accf72375900 COPYING000066400000000000000000000025661204272215500121220ustar00rootroot00000000000000Copyright (c) 2001-2011 Anders Moeller All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ChangeLog000066400000000000000000000134341204272215500126350ustar00rootroot000000000000001.11-7 -> 1.11-8 ================ - caching of isDebug, to avoid synchronized call to System.getProperty - thanks to G. Lundh 1.11-6 -> 1.11-7 ================ - bug fix in Gibson's AutomatonMatcher - thanks to Y. Versley, D. Weiss, and D. Richardson 1.11-5 -> 1.11-6 ================ - performance improvement in Automaton.isFinite - thanks to R. Muir 1.11-4 -> 1.11-5 ================ - bug fix in Gibson's AutomatonMatcher - thanks to H-.M. Adorf and J. Gibson 1.11-3 -> 1.11-4 ================ - bug fix and performance improvement in BasicOperations.concatenate - thanks to R. Muir 1.11-2 -> 1.11-3 ================ - added Automaton.makeStringUnion (Daciuk et al.'s algorithm for constructing a minimal automaton that accepts a union of strings) - contributed by D. Weiss - added call to clearHashCode in Automaton.reduce - thanks to D. Weiss - minimization is now optional in RegExp.toAutomaton - suggested by H. Zauner - SpecialOperations.reverse made public - suggested by Daniel Lowe 1.11-1 -> 1.11-2 ================ - fixed bug in RegExp parser - thanks to A. Meyer 1.10-5 -> 1.11-1 ================ - added AutomatonMatcher - contributed by J. Gibson - fixed bug in SpecialOperations.overlap - thanks to D. Lutterkort 1.10-4 -> 1.10-5 ================ - added RegExp.setAllowMutate (for thread safety) 1.10-3 -> 1.10-4 ================ - fixed bug in recomputation of Automaton hash code 1.10-2 -> 1.10-3 ================ - added Automaton method: getStrings - added setAllowMutate method that controls whether operations are allowed to modify input automata - fixed bug in regexp parser - improved javadoc description of automaton representation 1.10-1 -> 1.10-2 ================ - fixed bug in repeat(int,int) that was introduced in 1.9-1 - thanks to B. Lee 1.9-1 -> 1.10-1 =============== - added Datatypes class with lots of common regular languages (was earlier placed in the dk.brics.schematools package) - added DatatypesAutomatonProvider class so that regexps easily can use the datatypes - added Automaton methods: - makeMaxInteger - makeMinInteger - makeTotalDigits - makeFractionDigits - makeIntegerValue - makeDecimalValue - makeStringMatcher - prefixClose - hexCases - replaceWhitespace - now allowing the empty regexp (which matches the empty string) in RegExp syntax - intersection now works on nondeterministic automata without determinizing - rewritten getShortestExample - fixed bug in subsetOf for nondeterministic automata - removed Makefile (use 'ant' instead) 1.8-8 -> 1.9-1 ============== - moved Automaton methods to other classes (BasicAutomata, BasicOperations, etc.) - Automaton.toString now prints singleton automata as strings without expanding them - Automaton.subsetOf rewritten to make it faster - Automaton.run now works on nondeterministic automata without determinizing 1.8-7 -> 1.8-8 ============== - fixed bug in RunAutomaton.run(String,int) - thanks to J. Moran 1.8-6 -> 1.8-7 ============== - added AutomatonProvider for RegExp.toAutomaton 1.8-5 -> 1.8-6 ============== - fixed bug in subst(Map) 1.8-4 -> 1.8-5 ============== - added Automaton method: overlap - fixed bug in concatenate(List) 1.8-3 -> 1.8-4 ============== - faster singleton mode for various automata operations - added Automaton methods: - minus - shuffleSubsetOf - isEmptyString 1.8-2 -> 1.8-3 ============== - faster construction of automata from large regexps - improved performance of Automaton.repeat(int) and Automaton.repeat(int,int) 1.8-1 -> 1.8-2 ============== - fixed bug in makeInterval (for non-fixed number of digits) - thanks to A. Bakic 1.7-1 -> 1.8-1 ============== - shifted to Java 5 - reorganized source - added Automaton method: subst(char,String) 1.6-6 -> 1.7-1 ============== - added Hopcroft's minimization algorithm (more predictable behavior than Brzozowski's, but typically a bit slower) 1.6-5 -> 1.6-6 ============== - fixed bug in complement of nondeterministic automata 1.6-4 -> 1.6-5 ============== - added Automaton method: subst 1.6-3 -> 1.6-4 ============== - changed to BSD license 1.6.2 -> 1.6-3 ============== - added shuffle (interleaving) operation to Automaton 1.6.1 -> 1.6-2 ============== - fixed bug in Automaton.concatenate(List) 1.5-1 -> 1.6-1 ============== - added numerical intervals to RegExp and Automaton 1.4-1 -> 1.5-1 ============== - added Brzozowski's minimization algorithm 1.3-3 -> 1.4-1 ============== - special fast mode for single string automata - added Automaton method: restoreInvariant 1.3-2 -> 1.3-3 ============== - added Automaton methods: - hashCode (needed by equals) - getCommonPrefix 1.3-1 -> 1.3-2 ============== - added Automaton methods: - getShortestExample - setMinimizeAlways 1.2-7 -> 1.3-1 ============== - State class, Transition class, and various Automaton methods made public to allow manual construction of automata 1.2-6 -> 1.2-7 ============== - added Automaton method: compress 1.2-5 -> 1.2-6 ============== - added build.xml makefile for Ant 1.2-4 -> 1.2-5 ============== - added Automaton methods: - equals - load (from stream or URL) - store (to stream) - Automaton implements Serializable 1.2-3 -> 1.2-4 ============== - added Automaton methods: - projectChars - concatenate (List) - union (List) 1.1 -> 1.2-3 ============ - added Automaton methods: - trim - homomorph - singleChars - isEmpty - isTotal - isFinite - getFiniteStrings - getNumberOfStates - getNumberOfTransitions - subsetOf - added RunAutomaton methods: - load (from stream or URL) - store (to stream) - run (longest accepted substring run) - added getIdentifiers method to RegExp - RunAutomaton implements Serializable 1.0 -> 1.1 ========== - added regular expression parser (RegExp class) - tableized run method in RunAutomaton INSTALL000066400000000000000000000001431204272215500121050ustar00rootroot00000000000000The jar and javadoc files can be built using 'ant'. (The source package includes pre-built files.) README000066400000000000000000000007141204272215500117400ustar00rootroot00000000000000dk.brics.automaton ------------------ Copyright (C) 2001-2011 Anders Moeller This source code in this package may be used under the terms of the BSD license. Please read the file 'COPYING' for details. This package contains a full DFA/NFA implementation with Unicode alphabet and support for all standard regular expression operations. For more information, go to the package home page at http://www.brics.dk/automaton/ Anders Moeller amoeller@cs.au.dk build.xml000066400000000000000000000060551204272215500127050ustar00rootroot00000000000000 API Specification]]> Copyright © 2001-2011 Anders Møller. ]]> src/000077500000000000000000000000001204272215500116455ustar00rootroot00000000000000src/Unicode.txt000066400000000000000000003152211204272215500140000ustar00rootroot000000000000000000 Cc 0001 Cc 0002 Cc 0003 Cc 0004 Cc 0005 Cc 0006 Cc 0007 Cc 0008 Cc 0009 Cc 000A Cc 000B Cc 000C Cc 000D Cc 000E Cc 000F Cc 0010 Cc 0011 Cc 0012 Cc 0013 Cc 0014 Cc 0015 Cc 0016 Cc 0017 Cc 0018 Cc 0019 Cc 001A Cc 001B Cc 001C Cc 001D Cc 001E Cc 001F Cc 0020 Zs 0021 Po 0022 Po 0023 Po 0024 Sc 0025 Po 0026 Po 0027 Po 0028 Ps 0029 Pe 002A Po 002B Sm 002C Po 002D Pd 002E Po 002F Po 0030 Nd 0031 Nd 0032 Nd 0033 Nd 0034 Nd 0035 Nd 0036 Nd 0037 Nd 0038 Nd 0039 Nd 003A Po 003B Po 003C Sm 003D Sm 003E Sm 003F Po 0040 Po 0041 Lu 0042 Lu 0043 Lu 0044 Lu 0045 Lu 0046 Lu 0047 Lu 0048 Lu 0049 Lu 004A Lu 004B Lu 004C Lu 004D Lu 004E Lu 004F Lu 0050 Lu 0051 Lu 0052 Lu 0053 Lu 0054 Lu 0055 Lu 0056 Lu 0057 Lu 0058 Lu 0059 Lu 005A Lu 005B Ps 005C Po 005D Pe 005E Sk 005F Pc 0060 Sk 0061 Ll 0062 Ll 0063 Ll 0064 Ll 0065 Ll 0066 Ll 0067 Ll 0068 Ll 0069 Ll 006A Ll 006B Ll 006C Ll 006D Ll 006E Ll 006F Ll 0070 Ll 0071 Ll 0072 Ll 0073 Ll 0074 Ll 0075 Ll 0076 Ll 0077 Ll 0078 Ll 0079 Ll 007A Ll 007B Ps 007C Sm 007D Pe 007E Sm 007F Cc 0080 Cc 0081 Cc 0082 Cc 0083 Cc 0084 Cc 0085 Cc 0086 Cc 0087 Cc 0088 Cc 0089 Cc 008A Cc 008B Cc 008C Cc 008D Cc 008E Cc 008F Cc 0090 Cc 0091 Cc 0092 Cc 0093 Cc 0094 Cc 0095 Cc 0096 Cc 0097 Cc 0098 Cc 0099 Cc 009A Cc 009B Cc 009C Cc 009D Cc 009E Cc 009F Cc 00A0 Zs 00A1 Po 00A2 Sc 00A3 Sc 00A4 Sc 00A5 Sc 00A6 So 00A7 So 00A8 Sk 00A9 So 00AA Ll 00AB Pi 00AC Sm 00AD Pd 00AE So 00AF Sk 00B0 So 00B1 Sm 00B2 No 00B3 No 00B4 Sk 00B5 Ll 00B6 So 00B7 Po 00B8 Sk 00B9 No 00BA Ll 00BB Pf 00BC No 00BD No 00BE No 00BF Po 00C0 Lu 00C1 Lu 00C2 Lu 00C3 Lu 00C4 Lu 00C5 Lu 00C6 Lu 00C7 Lu 00C8 Lu 00C9 Lu 00CA Lu 00CB Lu 00CC Lu 00CD Lu 00CE Lu 00CF Lu 00D0 Lu 00D1 Lu 00D2 Lu 00D3 Lu 00D4 Lu 00D5 Lu 00D6 Lu 00D7 Sm 00D8 Lu 00D9 Lu 00DA Lu 00DB Lu 00DC Lu 00DD Lu 00DE Lu 00DF Ll 00E0 Ll 00E1 Ll 00E2 Ll 00E3 Ll 00E4 Ll 00E5 Ll 00E6 Ll 00E7 Ll 00E8 Ll 00E9 Ll 00EA Ll 00EB Ll 00EC Ll 00ED Ll 00EE Ll 00EF Ll 00F0 Ll 00F1 Ll 00F2 Ll 00F3 Ll 00F4 Ll 00F5 Ll 00F6 Ll 00F7 Sm 00F8 Ll 00F9 Ll 00FA Ll 00FB Ll 00FC Ll 00FD Ll 00FE Ll 00FF Ll 0100 Lu 0101 Ll 0102 Lu 0103 Ll 0104 Lu 0105 Ll 0106 Lu 0107 Ll 0108 Lu 0109 Ll 010A Lu 010B Ll 010C Lu 010D Ll 010E Lu 010F Ll 0110 Lu 0111 Ll 0112 Lu 0113 Ll 0114 Lu 0115 Ll 0116 Lu 0117 Ll 0118 Lu 0119 Ll 011A Lu 011B Ll 011C Lu 011D Ll 011E Lu 011F Ll 0120 Lu 0121 Ll 0122 Lu 0123 Ll 0124 Lu 0125 Ll 0126 Lu 0127 Ll 0128 Lu 0129 Ll 012A Lu 012B Ll 012C Lu 012D Ll 012E Lu 012F Ll 0130 Lu 0131 Ll 0132 Lu 0133 Ll 0134 Lu 0135 Ll 0136 Lu 0137 Ll 0138 Ll 0139 Lu 013A Ll 013B Lu 013C Ll 013D Lu 013E Ll 013F Lu 0140 Ll 0141 Lu 0142 Ll 0143 Lu 0144 Ll 0145 Lu 0146 Ll 0147 Lu 0148 Ll 0149 Ll 014A Lu 014B Ll 014C Lu 014D Ll 014E Lu 014F Ll 0150 Lu 0151 Ll 0152 Lu 0153 Ll 0154 Lu 0155 Ll 0156 Lu 0157 Ll 0158 Lu 0159 Ll 015A Lu 015B Ll 015C Lu 015D Ll 015E Lu 015F Ll 0160 Lu 0161 Ll 0162 Lu 0163 Ll 0164 Lu 0165 Ll 0166 Lu 0167 Ll 0168 Lu 0169 Ll 016A Lu 016B Ll 016C Lu 016D Ll 016E Lu 016F Ll 0170 Lu 0171 Ll 0172 Lu 0173 Ll 0174 Lu 0175 Ll 0176 Lu 0177 Ll 0178 Lu 0179 Lu 017A Ll 017B Lu 017C Ll 017D Lu 017E Ll 017F Ll 0180 Ll 0181 Lu 0182 Lu 0183 Ll 0184 Lu 0185 Ll 0186 Lu 0187 Lu 0188 Ll 0189 Lu 018A Lu 018B Lu 018C Ll 018D Ll 018E Lu 018F Lu 0190 Lu 0191 Lu 0192 Ll 0193 Lu 0194 Lu 0195 Ll 0196 Lu 0197 Lu 0198 Lu 0199 Ll 019A Ll 019B Ll 019C Lu 019D Lu 019E Ll 019F Lu 01A0 Lu 01A1 Ll 01A2 Lu 01A3 Ll 01A4 Lu 01A5 Ll 01A6 Lu 01A7 Lu 01A8 Ll 01A9 Lu 01AA Ll 01AB Ll 01AC Lu 01AD Ll 01AE Lu 01AF Lu 01B0 Ll 01B1 Lu 01B2 Lu 01B3 Lu 01B4 Ll 01B5 Lu 01B6 Ll 01B7 Lu 01B8 Lu 01B9 Ll 01BA Ll 01BB Lo 01BC Lu 01BD Ll 01BE Ll 01BF Ll 01C0 Lo 01C1 Lo 01C2 Lo 01C3 Lo 01C4 Lu 01C5 Lt 01C6 Ll 01C7 Lu 01C8 Lt 01C9 Ll 01CA Lu 01CB Lt 01CC Ll 01CD Lu 01CE Ll 01CF Lu 01D0 Ll 01D1 Lu 01D2 Ll 01D3 Lu 01D4 Ll 01D5 Lu 01D6 Ll 01D7 Lu 01D8 Ll 01D9 Lu 01DA Ll 01DB Lu 01DC Ll 01DD Ll 01DE Lu 01DF Ll 01E0 Lu 01E1 Ll 01E2 Lu 01E3 Ll 01E4 Lu 01E5 Ll 01E6 Lu 01E7 Ll 01E8 Lu 01E9 Ll 01EA Lu 01EB Ll 01EC Lu 01ED Ll 01EE Lu 01EF Ll 01F0 Ll 01F1 Lu 01F2 Lt 01F3 Ll 01F4 Lu 01F5 Ll 01F6 Lu 01F7 Lu 01F8 Lu 01F9 Ll 01FA Lu 01FB Ll 01FC Lu 01FD Ll 01FE Lu 01FF Ll 0200 Lu 0201 Ll 0202 Lu 0203 Ll 0204 Lu 0205 Ll 0206 Lu 0207 Ll 0208 Lu 0209 Ll 020A Lu 020B Ll 020C Lu 020D Ll 020E Lu 020F Ll 0210 Lu 0211 Ll 0212 Lu 0213 Ll 0214 Lu 0215 Ll 0216 Lu 0217 Ll 0218 Lu 0219 Ll 021A Lu 021B Ll 021C Lu 021D Ll 021E Lu 021F Ll 0222 Lu 0223 Ll 0224 Lu 0225 Ll 0226 Lu 0227 Ll 0228 Lu 0229 Ll 022A Lu 022B Ll 022C Lu 022D Ll 022E Lu 022F Ll 0230 Lu 0231 Ll 0232 Lu 0233 Ll 0250 Ll 0251 Ll 0252 Ll 0253 Ll 0254 Ll 0255 Ll 0256 Ll 0257 Ll 0258 Ll 0259 Ll 025A Ll 025B Ll 025C Ll 025D Ll 025E Ll 025F Ll 0260 Ll 0261 Ll 0262 Ll 0263 Ll 0264 Ll 0265 Ll 0266 Ll 0267 Ll 0268 Ll 0269 Ll 026A Ll 026B Ll 026C Ll 026D Ll 026E Ll 026F Ll 0270 Ll 0271 Ll 0272 Ll 0273 Ll 0274 Ll 0275 Ll 0276 Ll 0277 Ll 0278 Ll 0279 Ll 027A Ll 027B Ll 027C Ll 027D Ll 027E Ll 027F Ll 0280 Ll 0281 Ll 0282 Ll 0283 Ll 0284 Ll 0285 Ll 0286 Ll 0287 Ll 0288 Ll 0289 Ll 028A Ll 028B Ll 028C Ll 028D Ll 028E Ll 028F Ll 0290 Ll 0291 Ll 0292 Ll 0293 Ll 0294 Ll 0295 Ll 0296 Ll 0297 Ll 0298 Ll 0299 Ll 029A Ll 029B Ll 029C Ll 029D Ll 029E Ll 029F Ll 02A0 Ll 02A1 Ll 02A2 Ll 02A3 Ll 02A4 Ll 02A5 Ll 02A6 Ll 02A7 Ll 02A8 Ll 02A9 Ll 02AA Ll 02AB Ll 02AC Ll 02AD Ll 02B0 Lm 02B1 Lm 02B2 Lm 02B3 Lm 02B4 Lm 02B5 Lm 02B6 Lm 02B7 Lm 02B8 Lm 02B9 Sk 02BA Sk 02BB Lm 02BC Lm 02BD Lm 02BE Lm 02BF Lm 02C0 Lm 02C1 Lm 02C2 Sk 02C3 Sk 02C4 Sk 02C5 Sk 02C6 Sk 02C7 Sk 02C8 Sk 02C9 Sk 02CA Sk 02CB Sk 02CC Sk 02CD Sk 02CE Sk 02CF Sk 02D0 Lm 02D1 Lm 02D2 Sk 02D3 Sk 02D4 Sk 02D5 Sk 02D6 Sk 02D7 Sk 02D8 Sk 02D9 Sk 02DA Sk 02DB Sk 02DC Sk 02DD Sk 02DE Sk 02DF Sk 02E0 Lm 02E1 Lm 02E2 Lm 02E3 Lm 02E4 Lm 02E5 Sk 02E6 Sk 02E7 Sk 02E8 Sk 02E9 Sk 02EA Sk 02EB Sk 02EC Sk 02ED Sk 02EE Lm 0300 Mn 0301 Mn 0302 Mn 0303 Mn 0304 Mn 0305 Mn 0306 Mn 0307 Mn 0308 Mn 0309 Mn 030A Mn 030B Mn 030C Mn 030D Mn 030E Mn 030F Mn 0310 Mn 0311 Mn 0312 Mn 0313 Mn 0314 Mn 0315 Mn 0316 Mn 0317 Mn 0318 Mn 0319 Mn 031A Mn 031B Mn 031C Mn 031D Mn 031E Mn 031F Mn 0320 Mn 0321 Mn 0322 Mn 0323 Mn 0324 Mn 0325 Mn 0326 Mn 0327 Mn 0328 Mn 0329 Mn 032A Mn 032B Mn 032C Mn 032D Mn 032E Mn 032F Mn 0330 Mn 0331 Mn 0332 Mn 0333 Mn 0334 Mn 0335 Mn 0336 Mn 0337 Mn 0338 Mn 0339 Mn 033A Mn 033B Mn 033C Mn 033D Mn 033E Mn 033F Mn 0340 Mn 0341 Mn 0342 Mn 0343 Mn 0344 Mn 0345 Mn 0346 Mn 0347 Mn 0348 Mn 0349 Mn 034A Mn 034B Mn 034C Mn 034D Mn 034E Mn 0360 Mn 0361 Mn 0362 Mn 0374 Sk 0375 Sk 037A Lm 037E Po 0384 Sk 0385 Sk 0386 Lu 0387 Po 0388 Lu 0389 Lu 038A Lu 038C Lu 038E Lu 038F Lu 0390 Ll 0391 Lu 0392 Lu 0393 Lu 0394 Lu 0395 Lu 0396 Lu 0397 Lu 0398 Lu 0399 Lu 039A Lu 039B Lu 039C Lu 039D Lu 039E Lu 039F Lu 03A0 Lu 03A1 Lu 03A3 Lu 03A4 Lu 03A5 Lu 03A6 Lu 03A7 Lu 03A8 Lu 03A9 Lu 03AA Lu 03AB Lu 03AC Ll 03AD Ll 03AE Ll 03AF Ll 03B0 Ll 03B1 Ll 03B2 Ll 03B3 Ll 03B4 Ll 03B5 Ll 03B6 Ll 03B7 Ll 03B8 Ll 03B9 Ll 03BA Ll 03BB Ll 03BC Ll 03BD Ll 03BE Ll 03BF Ll 03C0 Ll 03C1 Ll 03C2 Ll 03C3 Ll 03C4 Ll 03C5 Ll 03C6 Ll 03C7 Ll 03C8 Ll 03C9 Ll 03CA Ll 03CB Ll 03CC Ll 03CD Ll 03CE Ll 03D0 Ll 03D1 Ll 03D2 Lu 03D3 Lu 03D4 Lu 03D5 Ll 03D6 Ll 03D7 Ll 03DA Lu 03DB Ll 03DC Lu 03DD Ll 03DE Lu 03DF Ll 03E0 Lu 03E1 Ll 03E2 Lu 03E3 Ll 03E4 Lu 03E5 Ll 03E6 Lu 03E7 Ll 03E8 Lu 03E9 Ll 03EA Lu 03EB Ll 03EC Lu 03ED Ll 03EE Lu 03EF Ll 03F0 Ll 03F1 Ll 03F2 Ll 03F3 Ll 03F4 Lu 03F5 Ll 0400 Lu 0401 Lu 0402 Lu 0403 Lu 0404 Lu 0405 Lu 0406 Lu 0407 Lu 0408 Lu 0409 Lu 040A Lu 040B Lu 040C Lu 040D Lu 040E Lu 040F Lu 0410 Lu 0411 Lu 0412 Lu 0413 Lu 0414 Lu 0415 Lu 0416 Lu 0417 Lu 0418 Lu 0419 Lu 041A Lu 041B Lu 041C Lu 041D Lu 041E Lu 041F Lu 0420 Lu 0421 Lu 0422 Lu 0423 Lu 0424 Lu 0425 Lu 0426 Lu 0427 Lu 0428 Lu 0429 Lu 042A Lu 042B Lu 042C Lu 042D Lu 042E Lu 042F Lu 0430 Ll 0431 Ll 0432 Ll 0433 Ll 0434 Ll 0435 Ll 0436 Ll 0437 Ll 0438 Ll 0439 Ll 043A Ll 043B Ll 043C Ll 043D Ll 043E Ll 043F Ll 0440 Ll 0441 Ll 0442 Ll 0443 Ll 0444 Ll 0445 Ll 0446 Ll 0447 Ll 0448 Ll 0449 Ll 044A Ll 044B Ll 044C Ll 044D Ll 044E Ll 044F Ll 0450 Ll 0451 Ll 0452 Ll 0453 Ll 0454 Ll 0455 Ll 0456 Ll 0457 Ll 0458 Ll 0459 Ll 045A Ll 045B Ll 045C Ll 045D Ll 045E Ll 045F Ll 0460 Lu 0461 Ll 0462 Lu 0463 Ll 0464 Lu 0465 Ll 0466 Lu 0467 Ll 0468 Lu 0469 Ll 046A Lu 046B Ll 046C Lu 046D Ll 046E Lu 046F Ll 0470 Lu 0471 Ll 0472 Lu 0473 Ll 0474 Lu 0475 Ll 0476 Lu 0477 Ll 0478 Lu 0479 Ll 047A Lu 047B Ll 047C Lu 047D Ll 047E Lu 047F Ll 0480 Lu 0481 Ll 0482 So 0483 Mn 0484 Mn 0485 Mn 0486 Mn 0488 Me 0489 Me 048C Lu 048D Ll 048E Lu 048F Ll 0490 Lu 0491 Ll 0492 Lu 0493 Ll 0494 Lu 0495 Ll 0496 Lu 0497 Ll 0498 Lu 0499 Ll 049A Lu 049B Ll 049C Lu 049D Ll 049E Lu 049F Ll 04A0 Lu 04A1 Ll 04A2 Lu 04A3 Ll 04A4 Lu 04A5 Ll 04A6 Lu 04A7 Ll 04A8 Lu 04A9 Ll 04AA Lu 04AB Ll 04AC Lu 04AD Ll 04AE Lu 04AF Ll 04B0 Lu 04B1 Ll 04B2 Lu 04B3 Ll 04B4 Lu 04B5 Ll 04B6 Lu 04B7 Ll 04B8 Lu 04B9 Ll 04BA Lu 04BB Ll 04BC Lu 04BD Ll 04BE Lu 04BF Ll 04C0 Lu 04C1 Lu 04C2 Ll 04C3 Lu 04C4 Ll 04C7 Lu 04C8 Ll 04CB Lu 04CC Ll 04D0 Lu 04D1 Ll 04D2 Lu 04D3 Ll 04D4 Lu 04D5 Ll 04D6 Lu 04D7 Ll 04D8 Lu 04D9 Ll 04DA Lu 04DB Ll 04DC Lu 04DD Ll 04DE Lu 04DF Ll 04E0 Lu 04E1 Ll 04E2 Lu 04E3 Ll 04E4 Lu 04E5 Ll 04E6 Lu 04E7 Ll 04E8 Lu 04E9 Ll 04EA Lu 04EB Ll 04EC Lu 04ED Ll 04EE Lu 04EF Ll 04F0 Lu 04F1 Ll 04F2 Lu 04F3 Ll 04F4 Lu 04F5 Ll 04F8 Lu 04F9 Ll 0531 Lu 0532 Lu 0533 Lu 0534 Lu 0535 Lu 0536 Lu 0537 Lu 0538 Lu 0539 Lu 053A Lu 053B Lu 053C Lu 053D Lu 053E Lu 053F Lu 0540 Lu 0541 Lu 0542 Lu 0543 Lu 0544 Lu 0545 Lu 0546 Lu 0547 Lu 0548 Lu 0549 Lu 054A Lu 054B Lu 054C Lu 054D Lu 054E Lu 054F Lu 0550 Lu 0551 Lu 0552 Lu 0553 Lu 0554 Lu 0555 Lu 0556 Lu 0559 Lm 055A Po 055B Po 055C Po 055D Po 055E Po 055F Po 0561 Ll 0562 Ll 0563 Ll 0564 Ll 0565 Ll 0566 Ll 0567 Ll 0568 Ll 0569 Ll 056A Ll 056B Ll 056C Ll 056D Ll 056E Ll 056F Ll 0570 Ll 0571 Ll 0572 Ll 0573 Ll 0574 Ll 0575 Ll 0576 Ll 0577 Ll 0578 Ll 0579 Ll 057A Ll 057B Ll 057C Ll 057D Ll 057E Ll 057F Ll 0580 Ll 0581 Ll 0582 Ll 0583 Ll 0584 Ll 0585 Ll 0586 Ll 0587 Ll 0589 Po 058A Pd 0591 Mn 0592 Mn 0593 Mn 0594 Mn 0595 Mn 0596 Mn 0597 Mn 0598 Mn 0599 Mn 059A Mn 059B Mn 059C Mn 059D Mn 059E Mn 059F Mn 05A0 Mn 05A1 Mn 05A3 Mn 05A4 Mn 05A5 Mn 05A6 Mn 05A7 Mn 05A8 Mn 05A9 Mn 05AA Mn 05AB Mn 05AC Mn 05AD Mn 05AE Mn 05AF Mn 05B0 Mn 05B1 Mn 05B2 Mn 05B3 Mn 05B4 Mn 05B5 Mn 05B6 Mn 05B7 Mn 05B8 Mn 05B9 Mn 05BB Mn 05BC Mn 05BD Mn 05BE Po 05BF Mn 05C0 Po 05C1 Mn 05C2 Mn 05C3 Po 05C4 Mn 05D0 Lo 05D1 Lo 05D2 Lo 05D3 Lo 05D4 Lo 05D5 Lo 05D6 Lo 05D7 Lo 05D8 Lo 05D9 Lo 05DA Lo 05DB Lo 05DC Lo 05DD Lo 05DE Lo 05DF Lo 05E0 Lo 05E1 Lo 05E2 Lo 05E3 Lo 05E4 Lo 05E5 Lo 05E6 Lo 05E7 Lo 05E8 Lo 05E9 Lo 05EA Lo 05F0 Lo 05F1 Lo 05F2 Lo 05F3 Po 05F4 Po 060C Po 061B Po 061F Po 0621 Lo 0622 Lo 0623 Lo 0624 Lo 0625 Lo 0626 Lo 0627 Lo 0628 Lo 0629 Lo 062A Lo 062B Lo 062C Lo 062D Lo 062E Lo 062F Lo 0630 Lo 0631 Lo 0632 Lo 0633 Lo 0634 Lo 0635 Lo 0636 Lo 0637 Lo 0638 Lo 0639 Lo 063A Lo 0640 Lm 0641 Lo 0642 Lo 0643 Lo 0644 Lo 0645 Lo 0646 Lo 0647 Lo 0648 Lo 0649 Lo 064A Lo 064B Mn 064C Mn 064D Mn 064E Mn 064F Mn 0650 Mn 0651 Mn 0652 Mn 0653 Mn 0654 Mn 0655 Mn 0660 Nd 0661 Nd 0662 Nd 0663 Nd 0664 Nd 0665 Nd 0666 Nd 0667 Nd 0668 Nd 0669 Nd 066A Po 066B Po 066C Po 066D Po 0670 Mn 0671 Lo 0672 Lo 0673 Lo 0674 Lo 0675 Lo 0676 Lo 0677 Lo 0678 Lo 0679 Lo 067A Lo 067B Lo 067C Lo 067D Lo 067E Lo 067F Lo 0680 Lo 0681 Lo 0682 Lo 0683 Lo 0684 Lo 0685 Lo 0686 Lo 0687 Lo 0688 Lo 0689 Lo 068A Lo 068B Lo 068C Lo 068D Lo 068E Lo 068F Lo 0690 Lo 0691 Lo 0692 Lo 0693 Lo 0694 Lo 0695 Lo 0696 Lo 0697 Lo 0698 Lo 0699 Lo 069A Lo 069B Lo 069C Lo 069D Lo 069E Lo 069F Lo 06A0 Lo 06A1 Lo 06A2 Lo 06A3 Lo 06A4 Lo 06A5 Lo 06A6 Lo 06A7 Lo 06A8 Lo 06A9 Lo 06AA Lo 06AB Lo 06AC Lo 06AD Lo 06AE Lo 06AF Lo 06B0 Lo 06B1 Lo 06B2 Lo 06B3 Lo 06B4 Lo 06B5 Lo 06B6 Lo 06B7 Lo 06B8 Lo 06B9 Lo 06BA Lo 06BB Lo 06BC Lo 06BD Lo 06BE Lo 06BF Lo 06C0 Lo 06C1 Lo 06C2 Lo 06C3 Lo 06C4 Lo 06C5 Lo 06C6 Lo 06C7 Lo 06C8 Lo 06C9 Lo 06CA Lo 06CB Lo 06CC Lo 06CD Lo 06CE Lo 06CF Lo 06D0 Lo 06D1 Lo 06D2 Lo 06D3 Lo 06D4 Po 06D5 Lo 06D6 Mn 06D7 Mn 06D8 Mn 06D9 Mn 06DA Mn 06DB Mn 06DC Mn 06DD Me 06DE Me 06DF Mn 06E0 Mn 06E1 Mn 06E2 Mn 06E3 Mn 06E4 Mn 06E5 Lm 06E6 Lm 06E7 Mn 06E8 Mn 06E9 So 06EA Mn 06EB Mn 06EC Mn 06ED Mn 06F0 Nd 06F1 Nd 06F2 Nd 06F3 Nd 06F4 Nd 06F5 Nd 06F6 Nd 06F7 Nd 06F8 Nd 06F9 Nd 06FA Lo 06FB Lo 06FC Lo 06FD So 06FE So 0700 Po 0701 Po 0702 Po 0703 Po 0704 Po 0705 Po 0706 Po 0707 Po 0708 Po 0709 Po 070A Po 070B Po 070C Po 070D Po 070F Cf 0710 Lo 0711 Mn 0712 Lo 0713 Lo 0714 Lo 0715 Lo 0716 Lo 0717 Lo 0718 Lo 0719 Lo 071A Lo 071B Lo 071C Lo 071D Lo 071E Lo 071F Lo 0720 Lo 0721 Lo 0722 Lo 0723 Lo 0724 Lo 0725 Lo 0726 Lo 0727 Lo 0728 Lo 0729 Lo 072A Lo 072B Lo 072C Lo 0730 Mn 0731 Mn 0732 Mn 0733 Mn 0734 Mn 0735 Mn 0736 Mn 0737 Mn 0738 Mn 0739 Mn 073A Mn 073B Mn 073C Mn 073D Mn 073E Mn 073F Mn 0740 Mn 0741 Mn 0742 Mn 0743 Mn 0744 Mn 0745 Mn 0746 Mn 0747 Mn 0748 Mn 0749 Mn 074A Mn 0780 Lo 0781 Lo 0782 Lo 0783 Lo 0784 Lo 0785 Lo 0786 Lo 0787 Lo 0788 Lo 0789 Lo 078A Lo 078B Lo 078C Lo 078D Lo 078E Lo 078F Lo 0790 Lo 0791 Lo 0792 Lo 0793 Lo 0794 Lo 0795 Lo 0796 Lo 0797 Lo 0798 Lo 0799 Lo 079A Lo 079B Lo 079C Lo 079D Lo 079E Lo 079F Lo 07A0 Lo 07A1 Lo 07A2 Lo 07A3 Lo 07A4 Lo 07A5 Lo 07A6 Mn 07A7 Mn 07A8 Mn 07A9 Mn 07AA Mn 07AB Mn 07AC Mn 07AD Mn 07AE Mn 07AF Mn 07B0 Mn 0901 Mn 0902 Mn 0903 Mc 0905 Lo 0906 Lo 0907 Lo 0908 Lo 0909 Lo 090A Lo 090B Lo 090C Lo 090D Lo 090E Lo 090F Lo 0910 Lo 0911 Lo 0912 Lo 0913 Lo 0914 Lo 0915 Lo 0916 Lo 0917 Lo 0918 Lo 0919 Lo 091A Lo 091B Lo 091C Lo 091D Lo 091E Lo 091F Lo 0920 Lo 0921 Lo 0922 Lo 0923 Lo 0924 Lo 0925 Lo 0926 Lo 0927 Lo 0928 Lo 0929 Lo 092A Lo 092B Lo 092C Lo 092D Lo 092E Lo 092F Lo 0930 Lo 0931 Lo 0932 Lo 0933 Lo 0934 Lo 0935 Lo 0936 Lo 0937 Lo 0938 Lo 0939 Lo 093C Mn 093D Lo 093E Mc 093F Mc 0940 Mc 0941 Mn 0942 Mn 0943 Mn 0944 Mn 0945 Mn 0946 Mn 0947 Mn 0948 Mn 0949 Mc 094A Mc 094B Mc 094C Mc 094D Mn 0950 Lo 0951 Mn 0952 Mn 0953 Mn 0954 Mn 0958 Lo 0959 Lo 095A Lo 095B Lo 095C Lo 095D Lo 095E Lo 095F Lo 0960 Lo 0961 Lo 0962 Mn 0963 Mn 0964 Po 0965 Po 0966 Nd 0967 Nd 0968 Nd 0969 Nd 096A Nd 096B Nd 096C Nd 096D Nd 096E Nd 096F Nd 0970 Po 0981 Mn 0982 Mc 0983 Mc 0985 Lo 0986 Lo 0987 Lo 0988 Lo 0989 Lo 098A Lo 098B Lo 098C Lo 098F Lo 0990 Lo 0993 Lo 0994 Lo 0995 Lo 0996 Lo 0997 Lo 0998 Lo 0999 Lo 099A Lo 099B Lo 099C Lo 099D Lo 099E Lo 099F Lo 09A0 Lo 09A1 Lo 09A2 Lo 09A3 Lo 09A4 Lo 09A5 Lo 09A6 Lo 09A7 Lo 09A8 Lo 09AA Lo 09AB Lo 09AC Lo 09AD Lo 09AE Lo 09AF Lo 09B0 Lo 09B2 Lo 09B6 Lo 09B7 Lo 09B8 Lo 09B9 Lo 09BC Mn 09BE Mc 09BF Mc 09C0 Mc 09C1 Mn 09C2 Mn 09C3 Mn 09C4 Mn 09C7 Mc 09C8 Mc 09CB Mc 09CC Mc 09CD Mn 09D7 Mc 09DC Lo 09DD Lo 09DF Lo 09E0 Lo 09E1 Lo 09E2 Mn 09E3 Mn 09E6 Nd 09E7 Nd 09E8 Nd 09E9 Nd 09EA Nd 09EB Nd 09EC Nd 09ED Nd 09EE Nd 09EF Nd 09F0 Lo 09F1 Lo 09F2 Sc 09F3 Sc 09F4 No 09F5 No 09F6 No 09F7 No 09F8 No 09F9 No 09FA So 0A02 Mn 0A05 Lo 0A06 Lo 0A07 Lo 0A08 Lo 0A09 Lo 0A0A Lo 0A0F Lo 0A10 Lo 0A13 Lo 0A14 Lo 0A15 Lo 0A16 Lo 0A17 Lo 0A18 Lo 0A19 Lo 0A1A Lo 0A1B Lo 0A1C Lo 0A1D Lo 0A1E Lo 0A1F Lo 0A20 Lo 0A21 Lo 0A22 Lo 0A23 Lo 0A24 Lo 0A25 Lo 0A26 Lo 0A27 Lo 0A28 Lo 0A2A Lo 0A2B Lo 0A2C Lo 0A2D Lo 0A2E Lo 0A2F Lo 0A30 Lo 0A32 Lo 0A33 Lo 0A35 Lo 0A36 Lo 0A38 Lo 0A39 Lo 0A3C Mn 0A3E Mc 0A3F Mc 0A40 Mc 0A41 Mn 0A42 Mn 0A47 Mn 0A48 Mn 0A4B Mn 0A4C Mn 0A4D Mn 0A59 Lo 0A5A Lo 0A5B Lo 0A5C Lo 0A5E Lo 0A66 Nd 0A67 Nd 0A68 Nd 0A69 Nd 0A6A Nd 0A6B Nd 0A6C Nd 0A6D Nd 0A6E Nd 0A6F Nd 0A70 Mn 0A71 Mn 0A72 Lo 0A73 Lo 0A74 Lo 0A81 Mn 0A82 Mn 0A83 Mc 0A85 Lo 0A86 Lo 0A87 Lo 0A88 Lo 0A89 Lo 0A8A Lo 0A8B Lo 0A8D Lo 0A8F Lo 0A90 Lo 0A91 Lo 0A93 Lo 0A94 Lo 0A95 Lo 0A96 Lo 0A97 Lo 0A98 Lo 0A99 Lo 0A9A Lo 0A9B Lo 0A9C Lo 0A9D Lo 0A9E Lo 0A9F Lo 0AA0 Lo 0AA1 Lo 0AA2 Lo 0AA3 Lo 0AA4 Lo 0AA5 Lo 0AA6 Lo 0AA7 Lo 0AA8 Lo 0AAA Lo 0AAB Lo 0AAC Lo 0AAD Lo 0AAE Lo 0AAF Lo 0AB0 Lo 0AB2 Lo 0AB3 Lo 0AB5 Lo 0AB6 Lo 0AB7 Lo 0AB8 Lo 0AB9 Lo 0ABC Mn 0ABD Lo 0ABE Mc 0ABF Mc 0AC0 Mc 0AC1 Mn 0AC2 Mn 0AC3 Mn 0AC4 Mn 0AC5 Mn 0AC7 Mn 0AC8 Mn 0AC9 Mc 0ACB Mc 0ACC Mc 0ACD Mn 0AD0 Lo 0AE0 Lo 0AE6 Nd 0AE7 Nd 0AE8 Nd 0AE9 Nd 0AEA Nd 0AEB Nd 0AEC Nd 0AED Nd 0AEE Nd 0AEF Nd 0B01 Mn 0B02 Mc 0B03 Mc 0B05 Lo 0B06 Lo 0B07 Lo 0B08 Lo 0B09 Lo 0B0A Lo 0B0B Lo 0B0C Lo 0B0F Lo 0B10 Lo 0B13 Lo 0B14 Lo 0B15 Lo 0B16 Lo 0B17 Lo 0B18 Lo 0B19 Lo 0B1A Lo 0B1B Lo 0B1C Lo 0B1D Lo 0B1E Lo 0B1F Lo 0B20 Lo 0B21 Lo 0B22 Lo 0B23 Lo 0B24 Lo 0B25 Lo 0B26 Lo 0B27 Lo 0B28 Lo 0B2A Lo 0B2B Lo 0B2C Lo 0B2D Lo 0B2E Lo 0B2F Lo 0B30 Lo 0B32 Lo 0B33 Lo 0B36 Lo 0B37 Lo 0B38 Lo 0B39 Lo 0B3C Mn 0B3D Lo 0B3E Mc 0B3F Mn 0B40 Mc 0B41 Mn 0B42 Mn 0B43 Mn 0B47 Mc 0B48 Mc 0B4B Mc 0B4C Mc 0B4D Mn 0B56 Mn 0B57 Mc 0B5C Lo 0B5D Lo 0B5F Lo 0B60 Lo 0B61 Lo 0B66 Nd 0B67 Nd 0B68 Nd 0B69 Nd 0B6A Nd 0B6B Nd 0B6C Nd 0B6D Nd 0B6E Nd 0B6F Nd 0B70 So 0B82 Mn 0B83 Mc 0B85 Lo 0B86 Lo 0B87 Lo 0B88 Lo 0B89 Lo 0B8A Lo 0B8E Lo 0B8F Lo 0B90 Lo 0B92 Lo 0B93 Lo 0B94 Lo 0B95 Lo 0B99 Lo 0B9A Lo 0B9C Lo 0B9E Lo 0B9F Lo 0BA3 Lo 0BA4 Lo 0BA8 Lo 0BA9 Lo 0BAA Lo 0BAE Lo 0BAF Lo 0BB0 Lo 0BB1 Lo 0BB2 Lo 0BB3 Lo 0BB4 Lo 0BB5 Lo 0BB7 Lo 0BB8 Lo 0BB9 Lo 0BBE Mc 0BBF Mc 0BC0 Mn 0BC1 Mc 0BC2 Mc 0BC6 Mc 0BC7 Mc 0BC8 Mc 0BCA Mc 0BCB Mc 0BCC Mc 0BCD Mn 0BD7 Mc 0BE7 Nd 0BE8 Nd 0BE9 Nd 0BEA Nd 0BEB Nd 0BEC Nd 0BED Nd 0BEE Nd 0BEF Nd 0BF0 No 0BF1 No 0BF2 No 0C01 Mc 0C02 Mc 0C03 Mc 0C05 Lo 0C06 Lo 0C07 Lo 0C08 Lo 0C09 Lo 0C0A Lo 0C0B Lo 0C0C Lo 0C0E Lo 0C0F Lo 0C10 Lo 0C12 Lo 0C13 Lo 0C14 Lo 0C15 Lo 0C16 Lo 0C17 Lo 0C18 Lo 0C19 Lo 0C1A Lo 0C1B Lo 0C1C Lo 0C1D Lo 0C1E Lo 0C1F Lo 0C20 Lo 0C21 Lo 0C22 Lo 0C23 Lo 0C24 Lo 0C25 Lo 0C26 Lo 0C27 Lo 0C28 Lo 0C2A Lo 0C2B Lo 0C2C Lo 0C2D Lo 0C2E Lo 0C2F Lo 0C30 Lo 0C31 Lo 0C32 Lo 0C33 Lo 0C35 Lo 0C36 Lo 0C37 Lo 0C38 Lo 0C39 Lo 0C3E Mn 0C3F Mn 0C40 Mn 0C41 Mc 0C42 Mc 0C43 Mc 0C44 Mc 0C46 Mn 0C47 Mn 0C48 Mn 0C4A Mn 0C4B Mn 0C4C Mn 0C4D Mn 0C55 Mn 0C56 Mn 0C60 Lo 0C61 Lo 0C66 Nd 0C67 Nd 0C68 Nd 0C69 Nd 0C6A Nd 0C6B Nd 0C6C Nd 0C6D Nd 0C6E Nd 0C6F Nd 0C82 Mc 0C83 Mc 0C85 Lo 0C86 Lo 0C87 Lo 0C88 Lo 0C89 Lo 0C8A Lo 0C8B Lo 0C8C Lo 0C8E Lo 0C8F Lo 0C90 Lo 0C92 Lo 0C93 Lo 0C94 Lo 0C95 Lo 0C96 Lo 0C97 Lo 0C98 Lo 0C99 Lo 0C9A Lo 0C9B Lo 0C9C Lo 0C9D Lo 0C9E Lo 0C9F Lo 0CA0 Lo 0CA1 Lo 0CA2 Lo 0CA3 Lo 0CA4 Lo 0CA5 Lo 0CA6 Lo 0CA7 Lo 0CA8 Lo 0CAA Lo 0CAB Lo 0CAC Lo 0CAD Lo 0CAE Lo 0CAF Lo 0CB0 Lo 0CB1 Lo 0CB2 Lo 0CB3 Lo 0CB5 Lo 0CB6 Lo 0CB7 Lo 0CB8 Lo 0CB9 Lo 0CBE Mc 0CBF Mn 0CC0 Mc 0CC1 Mc 0CC2 Mc 0CC3 Mc 0CC4 Mc 0CC6 Mn 0CC7 Mc 0CC8 Mc 0CCA Mc 0CCB Mc 0CCC Mn 0CCD Mn 0CD5 Mc 0CD6 Mc 0CDE Lo 0CE0 Lo 0CE1 Lo 0CE6 Nd 0CE7 Nd 0CE8 Nd 0CE9 Nd 0CEA Nd 0CEB Nd 0CEC Nd 0CED Nd 0CEE Nd 0CEF Nd 0D02 Mc 0D03 Mc 0D05 Lo 0D06 Lo 0D07 Lo 0D08 Lo 0D09 Lo 0D0A Lo 0D0B Lo 0D0C Lo 0D0E Lo 0D0F Lo 0D10 Lo 0D12 Lo 0D13 Lo 0D14 Lo 0D15 Lo 0D16 Lo 0D17 Lo 0D18 Lo 0D19 Lo 0D1A Lo 0D1B Lo 0D1C Lo 0D1D Lo 0D1E Lo 0D1F Lo 0D20 Lo 0D21 Lo 0D22 Lo 0D23 Lo 0D24 Lo 0D25 Lo 0D26 Lo 0D27 Lo 0D28 Lo 0D2A Lo 0D2B Lo 0D2C Lo 0D2D Lo 0D2E Lo 0D2F Lo 0D30 Lo 0D31 Lo 0D32 Lo 0D33 Lo 0D34 Lo 0D35 Lo 0D36 Lo 0D37 Lo 0D38 Lo 0D39 Lo 0D3E Mc 0D3F Mc 0D40 Mc 0D41 Mn 0D42 Mn 0D43 Mn 0D46 Mc 0D47 Mc 0D48 Mc 0D4A Mc 0D4B Mc 0D4C Mc 0D4D Mn 0D57 Mc 0D60 Lo 0D61 Lo 0D66 Nd 0D67 Nd 0D68 Nd 0D69 Nd 0D6A Nd 0D6B Nd 0D6C Nd 0D6D Nd 0D6E Nd 0D6F Nd 0D82 Mc 0D83 Mc 0D85 Lo 0D86 Lo 0D87 Lo 0D88 Lo 0D89 Lo 0D8A Lo 0D8B Lo 0D8C Lo 0D8D Lo 0D8E Lo 0D8F Lo 0D90 Lo 0D91 Lo 0D92 Lo 0D93 Lo 0D94 Lo 0D95 Lo 0D96 Lo 0D9A Lo 0D9B Lo 0D9C Lo 0D9D Lo 0D9E Lo 0D9F Lo 0DA0 Lo 0DA1 Lo 0DA2 Lo 0DA3 Lo 0DA4 Lo 0DA5 Lo 0DA6 Lo 0DA7 Lo 0DA8 Lo 0DA9 Lo 0DAA Lo 0DAB Lo 0DAC Lo 0DAD Lo 0DAE Lo 0DAF Lo 0DB0 Lo 0DB1 Lo 0DB3 Lo 0DB4 Lo 0DB5 Lo 0DB6 Lo 0DB7 Lo 0DB8 Lo 0DB9 Lo 0DBA Lo 0DBB Lo 0DBD Lo 0DC0 Lo 0DC1 Lo 0DC2 Lo 0DC3 Lo 0DC4 Lo 0DC5 Lo 0DC6 Lo 0DCA Mn 0DCF Mc 0DD0 Mc 0DD1 Mc 0DD2 Mn 0DD3 Mn 0DD4 Mn 0DD6 Mn 0DD8 Mc 0DD9 Mc 0DDA Mc 0DDB Mc 0DDC Mc 0DDD Mc 0DDE Mc 0DDF Mc 0DF2 Mc 0DF3 Mc 0DF4 Po 0E01 Lo 0E02 Lo 0E03 Lo 0E04 Lo 0E05 Lo 0E06 Lo 0E07 Lo 0E08 Lo 0E09 Lo 0E0A Lo 0E0B Lo 0E0C Lo 0E0D Lo 0E0E Lo 0E0F Lo 0E10 Lo 0E11 Lo 0E12 Lo 0E13 Lo 0E14 Lo 0E15 Lo 0E16 Lo 0E17 Lo 0E18 Lo 0E19 Lo 0E1A Lo 0E1B Lo 0E1C Lo 0E1D Lo 0E1E Lo 0E1F Lo 0E20 Lo 0E21 Lo 0E22 Lo 0E23 Lo 0E24 Lo 0E25 Lo 0E26 Lo 0E27 Lo 0E28 Lo 0E29 Lo 0E2A Lo 0E2B Lo 0E2C Lo 0E2D Lo 0E2E Lo 0E2F Lo 0E30 Lo 0E31 Mn 0E32 Lo 0E33 Lo 0E34 Mn 0E35 Mn 0E36 Mn 0E37 Mn 0E38 Mn 0E39 Mn 0E3A Mn 0E3F Sc 0E40 Lo 0E41 Lo 0E42 Lo 0E43 Lo 0E44 Lo 0E45 Lo 0E46 Lm 0E47 Mn 0E48 Mn 0E49 Mn 0E4A Mn 0E4B Mn 0E4C Mn 0E4D Mn 0E4E Mn 0E4F Po 0E50 Nd 0E51 Nd 0E52 Nd 0E53 Nd 0E54 Nd 0E55 Nd 0E56 Nd 0E57 Nd 0E58 Nd 0E59 Nd 0E5A Po 0E5B Po 0E81 Lo 0E82 Lo 0E84 Lo 0E87 Lo 0E88 Lo 0E8A Lo 0E8D Lo 0E94 Lo 0E95 Lo 0E96 Lo 0E97 Lo 0E99 Lo 0E9A Lo 0E9B Lo 0E9C Lo 0E9D Lo 0E9E Lo 0E9F Lo 0EA1 Lo 0EA2 Lo 0EA3 Lo 0EA5 Lo 0EA7 Lo 0EAA Lo 0EAB Lo 0EAD Lo 0EAE Lo 0EAF Lo 0EB0 Lo 0EB1 Mn 0EB2 Lo 0EB3 Lo 0EB4 Mn 0EB5 Mn 0EB6 Mn 0EB7 Mn 0EB8 Mn 0EB9 Mn 0EBB Mn 0EBC Mn 0EBD Lo 0EC0 Lo 0EC1 Lo 0EC2 Lo 0EC3 Lo 0EC4 Lo 0EC6 Lm 0EC8 Mn 0EC9 Mn 0ECA Mn 0ECB Mn 0ECC Mn 0ECD Mn 0ED0 Nd 0ED1 Nd 0ED2 Nd 0ED3 Nd 0ED4 Nd 0ED5 Nd 0ED6 Nd 0ED7 Nd 0ED8 Nd 0ED9 Nd 0EDC Lo 0EDD Lo 0F00 Lo 0F01 So 0F02 So 0F03 So 0F04 Po 0F05 Po 0F06 Po 0F07 Po 0F08 Po 0F09 Po 0F0A Po 0F0B Po 0F0C Po 0F0D Po 0F0E Po 0F0F Po 0F10 Po 0F11 Po 0F12 Po 0F13 So 0F14 So 0F15 So 0F16 So 0F17 So 0F18 Mn 0F19 Mn 0F1A So 0F1B So 0F1C So 0F1D So 0F1E So 0F1F So 0F20 Nd 0F21 Nd 0F22 Nd 0F23 Nd 0F24 Nd 0F25 Nd 0F26 Nd 0F27 Nd 0F28 Nd 0F29 Nd 0F2A No 0F2B No 0F2C No 0F2D No 0F2E No 0F2F No 0F30 No 0F31 No 0F32 No 0F33 No 0F34 So 0F35 Mn 0F36 So 0F37 Mn 0F38 So 0F39 Mn 0F3A Ps 0F3B Pe 0F3C Ps 0F3D Pe 0F3E Mc 0F3F Mc 0F40 Lo 0F41 Lo 0F42 Lo 0F43 Lo 0F44 Lo 0F45 Lo 0F46 Lo 0F47 Lo 0F49 Lo 0F4A Lo 0F4B Lo 0F4C Lo 0F4D Lo 0F4E Lo 0F4F Lo 0F50 Lo 0F51 Lo 0F52 Lo 0F53 Lo 0F54 Lo 0F55 Lo 0F56 Lo 0F57 Lo 0F58 Lo 0F59 Lo 0F5A Lo 0F5B Lo 0F5C Lo 0F5D Lo 0F5E Lo 0F5F Lo 0F60 Lo 0F61 Lo 0F62 Lo 0F63 Lo 0F64 Lo 0F65 Lo 0F66 Lo 0F67 Lo 0F68 Lo 0F69 Lo 0F6A Lo 0F71 Mn 0F72 Mn 0F73 Mn 0F74 Mn 0F75 Mn 0F76 Mn 0F77 Mn 0F78 Mn 0F79 Mn 0F7A Mn 0F7B Mn 0F7C Mn 0F7D Mn 0F7E Mn 0F7F Mc 0F80 Mn 0F81 Mn 0F82 Mn 0F83 Mn 0F84 Mn 0F85 Po 0F86 Mn 0F87 Mn 0F88 Lo 0F89 Lo 0F8A Lo 0F8B Lo 0F90 Mn 0F91 Mn 0F92 Mn 0F93 Mn 0F94 Mn 0F95 Mn 0F96 Mn 0F97 Mn 0F99 Mn 0F9A Mn 0F9B Mn 0F9C Mn 0F9D Mn 0F9E Mn 0F9F Mn 0FA0 Mn 0FA1 Mn 0FA2 Mn 0FA3 Mn 0FA4 Mn 0FA5 Mn 0FA6 Mn 0FA7 Mn 0FA8 Mn 0FA9 Mn 0FAA Mn 0FAB Mn 0FAC Mn 0FAD Mn 0FAE Mn 0FAF Mn 0FB0 Mn 0FB1 Mn 0FB2 Mn 0FB3 Mn 0FB4 Mn 0FB5 Mn 0FB6 Mn 0FB7 Mn 0FB8 Mn 0FB9 Mn 0FBA Mn 0FBB Mn 0FBC Mn 0FBE So 0FBF So 0FC0 So 0FC1 So 0FC2 So 0FC3 So 0FC4 So 0FC5 So 0FC6 Mn 0FC7 So 0FC8 So 0FC9 So 0FCA So 0FCB So 0FCC So 0FCF So 1000 Lo 1001 Lo 1002 Lo 1003 Lo 1004 Lo 1005 Lo 1006 Lo 1007 Lo 1008 Lo 1009 Lo 100A Lo 100B Lo 100C Lo 100D Lo 100E Lo 100F Lo 1010 Lo 1011 Lo 1012 Lo 1013 Lo 1014 Lo 1015 Lo 1016 Lo 1017 Lo 1018 Lo 1019 Lo 101A Lo 101B Lo 101C Lo 101D Lo 101E Lo 101F Lo 1020 Lo 1021 Lo 1023 Lo 1024 Lo 1025 Lo 1026 Lo 1027 Lo 1029 Lo 102A Lo 102C Mc 102D Mn 102E Mn 102F Mn 1030 Mn 1031 Mc 1032 Mn 1036 Mn 1037 Mn 1038 Mc 1039 Mn 1040 Nd 1041 Nd 1042 Nd 1043 Nd 1044 Nd 1045 Nd 1046 Nd 1047 Nd 1048 Nd 1049 Nd 104A Po 104B Po 104C Po 104D Po 104E Po 104F Po 1050 Lo 1051 Lo 1052 Lo 1053 Lo 1054 Lo 1055 Lo 1056 Mc 1057 Mc 1058 Mn 1059 Mn 10A0 Lu 10A1 Lu 10A2 Lu 10A3 Lu 10A4 Lu 10A5 Lu 10A6 Lu 10A7 Lu 10A8 Lu 10A9 Lu 10AA Lu 10AB Lu 10AC Lu 10AD Lu 10AE Lu 10AF Lu 10B0 Lu 10B1 Lu 10B2 Lu 10B3 Lu 10B4 Lu 10B5 Lu 10B6 Lu 10B7 Lu 10B8 Lu 10B9 Lu 10BA Lu 10BB Lu 10BC Lu 10BD Lu 10BE Lu 10BF Lu 10C0 Lu 10C1 Lu 10C2 Lu 10C3 Lu 10C4 Lu 10C5 Lu 10D0 Lo 10D1 Lo 10D2 Lo 10D3 Lo 10D4 Lo 10D5 Lo 10D6 Lo 10D7 Lo 10D8 Lo 10D9 Lo 10DA Lo 10DB Lo 10DC Lo 10DD Lo 10DE Lo 10DF Lo 10E0 Lo 10E1 Lo 10E2 Lo 10E3 Lo 10E4 Lo 10E5 Lo 10E6 Lo 10E7 Lo 10E8 Lo 10E9 Lo 10EA Lo 10EB Lo 10EC Lo 10ED Lo 10EE Lo 10EF Lo 10F0 Lo 10F1 Lo 10F2 Lo 10F3 Lo 10F4 Lo 10F5 Lo 10F6 Lo 10FB Po 1100 Lo 1101 Lo 1102 Lo 1103 Lo 1104 Lo 1105 Lo 1106 Lo 1107 Lo 1108 Lo 1109 Lo 110A Lo 110B Lo 110C Lo 110D Lo 110E Lo 110F Lo 1110 Lo 1111 Lo 1112 Lo 1113 Lo 1114 Lo 1115 Lo 1116 Lo 1117 Lo 1118 Lo 1119 Lo 111A Lo 111B Lo 111C Lo 111D Lo 111E Lo 111F Lo 1120 Lo 1121 Lo 1122 Lo 1123 Lo 1124 Lo 1125 Lo 1126 Lo 1127 Lo 1128 Lo 1129 Lo 112A Lo 112B Lo 112C Lo 112D Lo 112E Lo 112F Lo 1130 Lo 1131 Lo 1132 Lo 1133 Lo 1134 Lo 1135 Lo 1136 Lo 1137 Lo 1138 Lo 1139 Lo 113A Lo 113B Lo 113C Lo 113D Lo 113E Lo 113F Lo 1140 Lo 1141 Lo 1142 Lo 1143 Lo 1144 Lo 1145 Lo 1146 Lo 1147 Lo 1148 Lo 1149 Lo 114A Lo 114B Lo 114C Lo 114D Lo 114E Lo 114F Lo 1150 Lo 1151 Lo 1152 Lo 1153 Lo 1154 Lo 1155 Lo 1156 Lo 1157 Lo 1158 Lo 1159 Lo 115F Lo 1160 Lo 1161 Lo 1162 Lo 1163 Lo 1164 Lo 1165 Lo 1166 Lo 1167 Lo 1168 Lo 1169 Lo 116A Lo 116B Lo 116C Lo 116D Lo 116E Lo 116F Lo 1170 Lo 1171 Lo 1172 Lo 1173 Lo 1174 Lo 1175 Lo 1176 Lo 1177 Lo 1178 Lo 1179 Lo 117A Lo 117B Lo 117C Lo 117D Lo 117E Lo 117F Lo 1180 Lo 1181 Lo 1182 Lo 1183 Lo 1184 Lo 1185 Lo 1186 Lo 1187 Lo 1188 Lo 1189 Lo 118A Lo 118B Lo 118C Lo 118D Lo 118E Lo 118F Lo 1190 Lo 1191 Lo 1192 Lo 1193 Lo 1194 Lo 1195 Lo 1196 Lo 1197 Lo 1198 Lo 1199 Lo 119A Lo 119B Lo 119C Lo 119D Lo 119E Lo 119F Lo 11A0 Lo 11A1 Lo 11A2 Lo 11A8 Lo 11A9 Lo 11AA Lo 11AB Lo 11AC Lo 11AD Lo 11AE Lo 11AF Lo 11B0 Lo 11B1 Lo 11B2 Lo 11B3 Lo 11B4 Lo 11B5 Lo 11B6 Lo 11B7 Lo 11B8 Lo 11B9 Lo 11BA Lo 11BB Lo 11BC Lo 11BD Lo 11BE Lo 11BF Lo 11C0 Lo 11C1 Lo 11C2 Lo 11C3 Lo 11C4 Lo 11C5 Lo 11C6 Lo 11C7 Lo 11C8 Lo 11C9 Lo 11CA Lo 11CB Lo 11CC Lo 11CD Lo 11CE Lo 11CF Lo 11D0 Lo 11D1 Lo 11D2 Lo 11D3 Lo 11D4 Lo 11D5 Lo 11D6 Lo 11D7 Lo 11D8 Lo 11D9 Lo 11DA Lo 11DB Lo 11DC Lo 11DD Lo 11DE Lo 11DF Lo 11E0 Lo 11E1 Lo 11E2 Lo 11E3 Lo 11E4 Lo 11E5 Lo 11E6 Lo 11E7 Lo 11E8 Lo 11E9 Lo 11EA Lo 11EB Lo 11EC Lo 11ED Lo 11EE Lo 11EF Lo 11F0 Lo 11F1 Lo 11F2 Lo 11F3 Lo 11F4 Lo 11F5 Lo 11F6 Lo 11F7 Lo 11F8 Lo 11F9 Lo 1200 Lo 1201 Lo 1202 Lo 1203 Lo 1204 Lo 1205 Lo 1206 Lo 1208 Lo 1209 Lo 120A Lo 120B Lo 120C Lo 120D Lo 120E Lo 120F Lo 1210 Lo 1211 Lo 1212 Lo 1213 Lo 1214 Lo 1215 Lo 1216 Lo 1217 Lo 1218 Lo 1219 Lo 121A Lo 121B Lo 121C Lo 121D Lo 121E Lo 121F Lo 1220 Lo 1221 Lo 1222 Lo 1223 Lo 1224 Lo 1225 Lo 1226 Lo 1227 Lo 1228 Lo 1229 Lo 122A Lo 122B Lo 122C Lo 122D Lo 122E Lo 122F Lo 1230 Lo 1231 Lo 1232 Lo 1233 Lo 1234 Lo 1235 Lo 1236 Lo 1237 Lo 1238 Lo 1239 Lo 123A Lo 123B Lo 123C Lo 123D Lo 123E Lo 123F Lo 1240 Lo 1241 Lo 1242 Lo 1243 Lo 1244 Lo 1245 Lo 1246 Lo 1248 Lo 124A Lo 124B Lo 124C Lo 124D Lo 1250 Lo 1251 Lo 1252 Lo 1253 Lo 1254 Lo 1255 Lo 1256 Lo 1258 Lo 125A Lo 125B Lo 125C Lo 125D Lo 1260 Lo 1261 Lo 1262 Lo 1263 Lo 1264 Lo 1265 Lo 1266 Lo 1267 Lo 1268 Lo 1269 Lo 126A Lo 126B Lo 126C Lo 126D Lo 126E Lo 126F Lo 1270 Lo 1271 Lo 1272 Lo 1273 Lo 1274 Lo 1275 Lo 1276 Lo 1277 Lo 1278 Lo 1279 Lo 127A Lo 127B Lo 127C Lo 127D Lo 127E Lo 127F Lo 1280 Lo 1281 Lo 1282 Lo 1283 Lo 1284 Lo 1285 Lo 1286 Lo 1288 Lo 128A Lo 128B Lo 128C Lo 128D Lo 1290 Lo 1291 Lo 1292 Lo 1293 Lo 1294 Lo 1295 Lo 1296 Lo 1297 Lo 1298 Lo 1299 Lo 129A Lo 129B Lo 129C Lo 129D Lo 129E Lo 129F Lo 12A0 Lo 12A1 Lo 12A2 Lo 12A3 Lo 12A4 Lo 12A5 Lo 12A6 Lo 12A7 Lo 12A8 Lo 12A9 Lo 12AA Lo 12AB Lo 12AC Lo 12AD Lo 12AE Lo 12B0 Lo 12B2 Lo 12B3 Lo 12B4 Lo 12B5 Lo 12B8 Lo 12B9 Lo 12BA Lo 12BB Lo 12BC Lo 12BD Lo 12BE Lo 12C0 Lo 12C2 Lo 12C3 Lo 12C4 Lo 12C5 Lo 12C8 Lo 12C9 Lo 12CA Lo 12CB Lo 12CC Lo 12CD Lo 12CE Lo 12D0 Lo 12D1 Lo 12D2 Lo 12D3 Lo 12D4 Lo 12D5 Lo 12D6 Lo 12D8 Lo 12D9 Lo 12DA Lo 12DB Lo 12DC Lo 12DD Lo 12DE Lo 12DF Lo 12E0 Lo 12E1 Lo 12E2 Lo 12E3 Lo 12E4 Lo 12E5 Lo 12E6 Lo 12E7 Lo 12E8 Lo 12E9 Lo 12EA Lo 12EB Lo 12EC Lo 12ED Lo 12EE Lo 12F0 Lo 12F1 Lo 12F2 Lo 12F3 Lo 12F4 Lo 12F5 Lo 12F6 Lo 12F7 Lo 12F8 Lo 12F9 Lo 12FA Lo 12FB Lo 12FC Lo 12FD Lo 12FE Lo 12FF Lo 1300 Lo 1301 Lo 1302 Lo 1303 Lo 1304 Lo 1305 Lo 1306 Lo 1307 Lo 1308 Lo 1309 Lo 130A Lo 130B Lo 130C Lo 130D Lo 130E Lo 1310 Lo 1312 Lo 1313 Lo 1314 Lo 1315 Lo 1318 Lo 1319 Lo 131A Lo 131B Lo 131C Lo 131D Lo 131E Lo 1320 Lo 1321 Lo 1322 Lo 1323 Lo 1324 Lo 1325 Lo 1326 Lo 1327 Lo 1328 Lo 1329 Lo 132A Lo 132B Lo 132C Lo 132D Lo 132E Lo 132F Lo 1330 Lo 1331 Lo 1332 Lo 1333 Lo 1334 Lo 1335 Lo 1336 Lo 1337 Lo 1338 Lo 1339 Lo 133A Lo 133B Lo 133C Lo 133D Lo 133E Lo 133F Lo 1340 Lo 1341 Lo 1342 Lo 1343 Lo 1344 Lo 1345 Lo 1346 Lo 1348 Lo 1349 Lo 134A Lo 134B Lo 134C Lo 134D Lo 134E Lo 134F Lo 1350 Lo 1351 Lo 1352 Lo 1353 Lo 1354 Lo 1355 Lo 1356 Lo 1357 Lo 1358 Lo 1359 Lo 135A Lo 1361 Po 1362 Po 1363 Po 1364 Po 1365 Po 1366 Po 1367 Po 1368 Po 1369 Nd 136A Nd 136B Nd 136C Nd 136D Nd 136E Nd 136F Nd 1370 Nd 1371 Nd 1372 No 1373 No 1374 No 1375 No 1376 No 1377 No 1378 No 1379 No 137A No 137B No 137C No 13A0 Lo 13A1 Lo 13A2 Lo 13A3 Lo 13A4 Lo 13A5 Lo 13A6 Lo 13A7 Lo 13A8 Lo 13A9 Lo 13AA Lo 13AB Lo 13AC Lo 13AD Lo 13AE Lo 13AF Lo 13B0 Lo 13B1 Lo 13B2 Lo 13B3 Lo 13B4 Lo 13B5 Lo 13B6 Lo 13B7 Lo 13B8 Lo 13B9 Lo 13BA Lo 13BB Lo 13BC Lo 13BD Lo 13BE Lo 13BF Lo 13C0 Lo 13C1 Lo 13C2 Lo 13C3 Lo 13C4 Lo 13C5 Lo 13C6 Lo 13C7 Lo 13C8 Lo 13C9 Lo 13CA Lo 13CB Lo 13CC Lo 13CD Lo 13CE Lo 13CF Lo 13D0 Lo 13D1 Lo 13D2 Lo 13D3 Lo 13D4 Lo 13D5 Lo 13D6 Lo 13D7 Lo 13D8 Lo 13D9 Lo 13DA Lo 13DB Lo 13DC Lo 13DD Lo 13DE Lo 13DF Lo 13E0 Lo 13E1 Lo 13E2 Lo 13E3 Lo 13E4 Lo 13E5 Lo 13E6 Lo 13E7 Lo 13E8 Lo 13E9 Lo 13EA Lo 13EB Lo 13EC Lo 13ED Lo 13EE Lo 13EF Lo 13F0 Lo 13F1 Lo 13F2 Lo 13F3 Lo 13F4 Lo 1401 Lo 1402 Lo 1403 Lo 1404 Lo 1405 Lo 1406 Lo 1407 Lo 1408 Lo 1409 Lo 140A Lo 140B Lo 140C Lo 140D Lo 140E Lo 140F Lo 1410 Lo 1411 Lo 1412 Lo 1413 Lo 1414 Lo 1415 Lo 1416 Lo 1417 Lo 1418 Lo 1419 Lo 141A Lo 141B Lo 141C Lo 141D Lo 141E Lo 141F Lo 1420 Lo 1421 Lo 1422 Lo 1423 Lo 1424 Lo 1425 Lo 1426 Lo 1427 Lo 1428 Lo 1429 Lo 142A Lo 142B Lo 142C Lo 142D Lo 142E Lo 142F Lo 1430 Lo 1431 Lo 1432 Lo 1433 Lo 1434 Lo 1435 Lo 1436 Lo 1437 Lo 1438 Lo 1439 Lo 143A Lo 143B Lo 143C Lo 143D Lo 143E Lo 143F Lo 1440 Lo 1441 Lo 1442 Lo 1443 Lo 1444 Lo 1445 Lo 1446 Lo 1447 Lo 1448 Lo 1449 Lo 144A Lo 144B Lo 144C Lo 144D Lo 144E Lo 144F Lo 1450 Lo 1451 Lo 1452 Lo 1453 Lo 1454 Lo 1455 Lo 1456 Lo 1457 Lo 1458 Lo 1459 Lo 145A Lo 145B Lo 145C Lo 145D Lo 145E Lo 145F Lo 1460 Lo 1461 Lo 1462 Lo 1463 Lo 1464 Lo 1465 Lo 1466 Lo 1467 Lo 1468 Lo 1469 Lo 146A Lo 146B Lo 146C Lo 146D Lo 146E Lo 146F Lo 1470 Lo 1471 Lo 1472 Lo 1473 Lo 1474 Lo 1475 Lo 1476 Lo 1477 Lo 1478 Lo 1479 Lo 147A Lo 147B Lo 147C Lo 147D Lo 147E Lo 147F Lo 1480 Lo 1481 Lo 1482 Lo 1483 Lo 1484 Lo 1485 Lo 1486 Lo 1487 Lo 1488 Lo 1489 Lo 148A Lo 148B Lo 148C Lo 148D Lo 148E Lo 148F Lo 1490 Lo 1491 Lo 1492 Lo 1493 Lo 1494 Lo 1495 Lo 1496 Lo 1497 Lo 1498 Lo 1499 Lo 149A Lo 149B Lo 149C Lo 149D Lo 149E Lo 149F Lo 14A0 Lo 14A1 Lo 14A2 Lo 14A3 Lo 14A4 Lo 14A5 Lo 14A6 Lo 14A7 Lo 14A8 Lo 14A9 Lo 14AA Lo 14AB Lo 14AC Lo 14AD Lo 14AE Lo 14AF Lo 14B0 Lo 14B1 Lo 14B2 Lo 14B3 Lo 14B4 Lo 14B5 Lo 14B6 Lo 14B7 Lo 14B8 Lo 14B9 Lo 14BA Lo 14BB Lo 14BC Lo 14BD Lo 14BE Lo 14BF Lo 14C0 Lo 14C1 Lo 14C2 Lo 14C3 Lo 14C4 Lo 14C5 Lo 14C6 Lo 14C7 Lo 14C8 Lo 14C9 Lo 14CA Lo 14CB Lo 14CC Lo 14CD Lo 14CE Lo 14CF Lo 14D0 Lo 14D1 Lo 14D2 Lo 14D3 Lo 14D4 Lo 14D5 Lo 14D6 Lo 14D7 Lo 14D8 Lo 14D9 Lo 14DA Lo 14DB Lo 14DC Lo 14DD Lo 14DE Lo 14DF Lo 14E0 Lo 14E1 Lo 14E2 Lo 14E3 Lo 14E4 Lo 14E5 Lo 14E6 Lo 14E7 Lo 14E8 Lo 14E9 Lo 14EA Lo 14EB Lo 14EC Lo 14ED Lo 14EE Lo 14EF Lo 14F0 Lo 14F1 Lo 14F2 Lo 14F3 Lo 14F4 Lo 14F5 Lo 14F6 Lo 14F7 Lo 14F8 Lo 14F9 Lo 14FA Lo 14FB Lo 14FC Lo 14FD Lo 14FE Lo 14FF Lo 1500 Lo 1501 Lo 1502 Lo 1503 Lo 1504 Lo 1505 Lo 1506 Lo 1507 Lo 1508 Lo 1509 Lo 150A Lo 150B Lo 150C Lo 150D Lo 150E Lo 150F Lo 1510 Lo 1511 Lo 1512 Lo 1513 Lo 1514 Lo 1515 Lo 1516 Lo 1517 Lo 1518 Lo 1519 Lo 151A Lo 151B Lo 151C Lo 151D Lo 151E Lo 151F Lo 1520 Lo 1521 Lo 1522 Lo 1523 Lo 1524 Lo 1525 Lo 1526 Lo 1527 Lo 1528 Lo 1529 Lo 152A Lo 152B Lo 152C Lo 152D Lo 152E Lo 152F Lo 1530 Lo 1531 Lo 1532 Lo 1533 Lo 1534 Lo 1535 Lo 1536 Lo 1537 Lo 1538 Lo 1539 Lo 153A Lo 153B Lo 153C Lo 153D Lo 153E Lo 153F Lo 1540 Lo 1541 Lo 1542 Lo 1543 Lo 1544 Lo 1545 Lo 1546 Lo 1547 Lo 1548 Lo 1549 Lo 154A Lo 154B Lo 154C Lo 154D Lo 154E Lo 154F Lo 1550 Lo 1551 Lo 1552 Lo 1553 Lo 1554 Lo 1555 Lo 1556 Lo 1557 Lo 1558 Lo 1559 Lo 155A Lo 155B Lo 155C Lo 155D Lo 155E Lo 155F Lo 1560 Lo 1561 Lo 1562 Lo 1563 Lo 1564 Lo 1565 Lo 1566 Lo 1567 Lo 1568 Lo 1569 Lo 156A Lo 156B Lo 156C Lo 156D Lo 156E Lo 156F Lo 1570 Lo 1571 Lo 1572 Lo 1573 Lo 1574 Lo 1575 Lo 1576 Lo 1577 Lo 1578 Lo 1579 Lo 157A Lo 157B Lo 157C Lo 157D Lo 157E Lo 157F Lo 1580 Lo 1581 Lo 1582 Lo 1583 Lo 1584 Lo 1585 Lo 1586 Lo 1587 Lo 1588 Lo 1589 Lo 158A Lo 158B Lo 158C Lo 158D Lo 158E Lo 158F Lo 1590 Lo 1591 Lo 1592 Lo 1593 Lo 1594 Lo 1595 Lo 1596 Lo 1597 Lo 1598 Lo 1599 Lo 159A Lo 159B Lo 159C Lo 159D Lo 159E Lo 159F Lo 15A0 Lo 15A1 Lo 15A2 Lo 15A3 Lo 15A4 Lo 15A5 Lo 15A6 Lo 15A7 Lo 15A8 Lo 15A9 Lo 15AA Lo 15AB Lo 15AC Lo 15AD Lo 15AE Lo 15AF Lo 15B0 Lo 15B1 Lo 15B2 Lo 15B3 Lo 15B4 Lo 15B5 Lo 15B6 Lo 15B7 Lo 15B8 Lo 15B9 Lo 15BA Lo 15BB Lo 15BC Lo 15BD Lo 15BE Lo 15BF Lo 15C0 Lo 15C1 Lo 15C2 Lo 15C3 Lo 15C4 Lo 15C5 Lo 15C6 Lo 15C7 Lo 15C8 Lo 15C9 Lo 15CA Lo 15CB Lo 15CC Lo 15CD Lo 15CE Lo 15CF Lo 15D0 Lo 15D1 Lo 15D2 Lo 15D3 Lo 15D4 Lo 15D5 Lo 15D6 Lo 15D7 Lo 15D8 Lo 15D9 Lo 15DA Lo 15DB Lo 15DC Lo 15DD Lo 15DE Lo 15DF Lo 15E0 Lo 15E1 Lo 15E2 Lo 15E3 Lo 15E4 Lo 15E5 Lo 15E6 Lo 15E7 Lo 15E8 Lo 15E9 Lo 15EA Lo 15EB Lo 15EC Lo 15ED Lo 15EE Lo 15EF Lo 15F0 Lo 15F1 Lo 15F2 Lo 15F3 Lo 15F4 Lo 15F5 Lo 15F6 Lo 15F7 Lo 15F8 Lo 15F9 Lo 15FA Lo 15FB Lo 15FC Lo 15FD Lo 15FE Lo 15FF Lo 1600 Lo 1601 Lo 1602 Lo 1603 Lo 1604 Lo 1605 Lo 1606 Lo 1607 Lo 1608 Lo 1609 Lo 160A Lo 160B Lo 160C Lo 160D Lo 160E Lo 160F Lo 1610 Lo 1611 Lo 1612 Lo 1613 Lo 1614 Lo 1615 Lo 1616 Lo 1617 Lo 1618 Lo 1619 Lo 161A Lo 161B Lo 161C Lo 161D Lo 161E Lo 161F Lo 1620 Lo 1621 Lo 1622 Lo 1623 Lo 1624 Lo 1625 Lo 1626 Lo 1627 Lo 1628 Lo 1629 Lo 162A Lo 162B Lo 162C Lo 162D Lo 162E Lo 162F Lo 1630 Lo 1631 Lo 1632 Lo 1633 Lo 1634 Lo 1635 Lo 1636 Lo 1637 Lo 1638 Lo 1639 Lo 163A Lo 163B Lo 163C Lo 163D Lo 163E Lo 163F Lo 1640 Lo 1641 Lo 1642 Lo 1643 Lo 1644 Lo 1645 Lo 1646 Lo 1647 Lo 1648 Lo 1649 Lo 164A Lo 164B Lo 164C Lo 164D Lo 164E Lo 164F Lo 1650 Lo 1651 Lo 1652 Lo 1653 Lo 1654 Lo 1655 Lo 1656 Lo 1657 Lo 1658 Lo 1659 Lo 165A Lo 165B Lo 165C Lo 165D Lo 165E Lo 165F Lo 1660 Lo 1661 Lo 1662 Lo 1663 Lo 1664 Lo 1665 Lo 1666 Lo 1667 Lo 1668 Lo 1669 Lo 166A Lo 166B Lo 166C Lo 166D Po 166E Po 166F Lo 1670 Lo 1671 Lo 1672 Lo 1673 Lo 1674 Lo 1675 Lo 1676 Lo 1680 Zs 1681 Lo 1682 Lo 1683 Lo 1684 Lo 1685 Lo 1686 Lo 1687 Lo 1688 Lo 1689 Lo 168A Lo 168B Lo 168C Lo 168D Lo 168E Lo 168F Lo 1690 Lo 1691 Lo 1692 Lo 1693 Lo 1694 Lo 1695 Lo 1696 Lo 1697 Lo 1698 Lo 1699 Lo 169A Lo 169B Ps 169C Pe 16A0 Lo 16A1 Lo 16A2 Lo 16A3 Lo 16A4 Lo 16A5 Lo 16A6 Lo 16A7 Lo 16A8 Lo 16A9 Lo 16AA Lo 16AB Lo 16AC Lo 16AD Lo 16AE Lo 16AF Lo 16B0 Lo 16B1 Lo 16B2 Lo 16B3 Lo 16B4 Lo 16B5 Lo 16B6 Lo 16B7 Lo 16B8 Lo 16B9 Lo 16BA Lo 16BB Lo 16BC Lo 16BD Lo 16BE Lo 16BF Lo 16C0 Lo 16C1 Lo 16C2 Lo 16C3 Lo 16C4 Lo 16C5 Lo 16C6 Lo 16C7 Lo 16C8 Lo 16C9 Lo 16CA Lo 16CB Lo 16CC Lo 16CD Lo 16CE Lo 16CF Lo 16D0 Lo 16D1 Lo 16D2 Lo 16D3 Lo 16D4 Lo 16D5 Lo 16D6 Lo 16D7 Lo 16D8 Lo 16D9 Lo 16DA Lo 16DB Lo 16DC Lo 16DD Lo 16DE Lo 16DF Lo 16E0 Lo 16E1 Lo 16E2 Lo 16E3 Lo 16E4 Lo 16E5 Lo 16E6 Lo 16E7 Lo 16E8 Lo 16E9 Lo 16EA Lo 16EB Po 16EC Po 16ED Po 16EE Nl 16EF Nl 16F0 Nl 1780 Lo 1781 Lo 1782 Lo 1783 Lo 1784 Lo 1785 Lo 1786 Lo 1787 Lo 1788 Lo 1789 Lo 178A Lo 178B Lo 178C Lo 178D Lo 178E Lo 178F Lo 1790 Lo 1791 Lo 1792 Lo 1793 Lo 1794 Lo 1795 Lo 1796 Lo 1797 Lo 1798 Lo 1799 Lo 179A Lo 179B Lo 179C Lo 179D Lo 179E Lo 179F Lo 17A0 Lo 17A1 Lo 17A2 Lo 17A3 Lo 17A4 Lo 17A5 Lo 17A6 Lo 17A7 Lo 17A8 Lo 17A9 Lo 17AA Lo 17AB Lo 17AC Lo 17AD Lo 17AE Lo 17AF Lo 17B0 Lo 17B1 Lo 17B2 Lo 17B3 Lo 17B4 Mc 17B5 Mc 17B6 Mc 17B7 Mn 17B8 Mn 17B9 Mn 17BA Mn 17BB Mn 17BC Mn 17BD Mn 17BE Mc 17BF Mc 17C0 Mc 17C1 Mc 17C2 Mc 17C3 Mc 17C4 Mc 17C5 Mc 17C6 Mn 17C7 Mc 17C8 Mc 17C9 Mn 17CA Mn 17CB Mn 17CC Mn 17CD Mn 17CE Mn 17CF Mn 17D0 Mn 17D1 Mn 17D2 Mn 17D3 Mn 17D4 Po 17D5 Po 17D6 Po 17D7 Po 17D8 Po 17D9 Po 17DA Po 17DB Sc 17DC Po 17E0 Nd 17E1 Nd 17E2 Nd 17E3 Nd 17E4 Nd 17E5 Nd 17E6 Nd 17E7 Nd 17E8 Nd 17E9 Nd 1800 Po 1801 Po 1802 Po 1803 Po 1804 Po 1805 Po 1806 Pd 1807 Po 1808 Po 1809 Po 180A Po 180B Cf 180C Cf 180D Cf 180E Cf 1810 Nd 1811 Nd 1812 Nd 1813 Nd 1814 Nd 1815 Nd 1816 Nd 1817 Nd 1818 Nd 1819 Nd 1820 Lo 1821 Lo 1822 Lo 1823 Lo 1824 Lo 1825 Lo 1826 Lo 1827 Lo 1828 Lo 1829 Lo 182A Lo 182B Lo 182C Lo 182D Lo 182E Lo 182F Lo 1830 Lo 1831 Lo 1832 Lo 1833 Lo 1834 Lo 1835 Lo 1836 Lo 1837 Lo 1838 Lo 1839 Lo 183A Lo 183B Lo 183C Lo 183D Lo 183E Lo 183F Lo 1840 Lo 1841 Lo 1842 Lo 1843 Lm 1844 Lo 1845 Lo 1846 Lo 1847 Lo 1848 Lo 1849 Lo 184A Lo 184B Lo 184C Lo 184D Lo 184E Lo 184F Lo 1850 Lo 1851 Lo 1852 Lo 1853 Lo 1854 Lo 1855 Lo 1856 Lo 1857 Lo 1858 Lo 1859 Lo 185A Lo 185B Lo 185C Lo 185D Lo 185E Lo 185F Lo 1860 Lo 1861 Lo 1862 Lo 1863 Lo 1864 Lo 1865 Lo 1866 Lo 1867 Lo 1868 Lo 1869 Lo 186A Lo 186B Lo 186C Lo 186D Lo 186E Lo 186F Lo 1870 Lo 1871 Lo 1872 Lo 1873 Lo 1874 Lo 1875 Lo 1876 Lo 1877 Lo 1880 Lo 1881 Lo 1882 Lo 1883 Lo 1884 Lo 1885 Lo 1886 Lo 1887 Lo 1888 Lo 1889 Lo 188A Lo 188B Lo 188C Lo 188D Lo 188E Lo 188F Lo 1890 Lo 1891 Lo 1892 Lo 1893 Lo 1894 Lo 1895 Lo 1896 Lo 1897 Lo 1898 Lo 1899 Lo 189A Lo 189B Lo 189C Lo 189D Lo 189E Lo 189F Lo 18A0 Lo 18A1 Lo 18A2 Lo 18A3 Lo 18A4 Lo 18A5 Lo 18A6 Lo 18A7 Lo 18A8 Lo 18A9 Mn 1E00 Lu 1E01 Ll 1E02 Lu 1E03 Ll 1E04 Lu 1E05 Ll 1E06 Lu 1E07 Ll 1E08 Lu 1E09 Ll 1E0A Lu 1E0B Ll 1E0C Lu 1E0D Ll 1E0E Lu 1E0F Ll 1E10 Lu 1E11 Ll 1E12 Lu 1E13 Ll 1E14 Lu 1E15 Ll 1E16 Lu 1E17 Ll 1E18 Lu 1E19 Ll 1E1A Lu 1E1B Ll 1E1C Lu 1E1D Ll 1E1E Lu 1E1F Ll 1E20 Lu 1E21 Ll 1E22 Lu 1E23 Ll 1E24 Lu 1E25 Ll 1E26 Lu 1E27 Ll 1E28 Lu 1E29 Ll 1E2A Lu 1E2B Ll 1E2C Lu 1E2D Ll 1E2E Lu 1E2F Ll 1E30 Lu 1E31 Ll 1E32 Lu 1E33 Ll 1E34 Lu 1E35 Ll 1E36 Lu 1E37 Ll 1E38 Lu 1E39 Ll 1E3A Lu 1E3B Ll 1E3C Lu 1E3D Ll 1E3E Lu 1E3F Ll 1E40 Lu 1E41 Ll 1E42 Lu 1E43 Ll 1E44 Lu 1E45 Ll 1E46 Lu 1E47 Ll 1E48 Lu 1E49 Ll 1E4A Lu 1E4B Ll 1E4C Lu 1E4D Ll 1E4E Lu 1E4F Ll 1E50 Lu 1E51 Ll 1E52 Lu 1E53 Ll 1E54 Lu 1E55 Ll 1E56 Lu 1E57 Ll 1E58 Lu 1E59 Ll 1E5A Lu 1E5B Ll 1E5C Lu 1E5D Ll 1E5E Lu 1E5F Ll 1E60 Lu 1E61 Ll 1E62 Lu 1E63 Ll 1E64 Lu 1E65 Ll 1E66 Lu 1E67 Ll 1E68 Lu 1E69 Ll 1E6A Lu 1E6B Ll 1E6C Lu 1E6D Ll 1E6E Lu 1E6F Ll 1E70 Lu 1E71 Ll 1E72 Lu 1E73 Ll 1E74 Lu 1E75 Ll 1E76 Lu 1E77 Ll 1E78 Lu 1E79 Ll 1E7A Lu 1E7B Ll 1E7C Lu 1E7D Ll 1E7E Lu 1E7F Ll 1E80 Lu 1E81 Ll 1E82 Lu 1E83 Ll 1E84 Lu 1E85 Ll 1E86 Lu 1E87 Ll 1E88 Lu 1E89 Ll 1E8A Lu 1E8B Ll 1E8C Lu 1E8D Ll 1E8E Lu 1E8F Ll 1E90 Lu 1E91 Ll 1E92 Lu 1E93 Ll 1E94 Lu 1E95 Ll 1E96 Ll 1E97 Ll 1E98 Ll 1E99 Ll 1E9A Ll 1E9B Ll 1EA0 Lu 1EA1 Ll 1EA2 Lu 1EA3 Ll 1EA4 Lu 1EA5 Ll 1EA6 Lu 1EA7 Ll 1EA8 Lu 1EA9 Ll 1EAA Lu 1EAB Ll 1EAC Lu 1EAD Ll 1EAE Lu 1EAF Ll 1EB0 Lu 1EB1 Ll 1EB2 Lu 1EB3 Ll 1EB4 Lu 1EB5 Ll 1EB6 Lu 1EB7 Ll 1EB8 Lu 1EB9 Ll 1EBA Lu 1EBB Ll 1EBC Lu 1EBD Ll 1EBE Lu 1EBF Ll 1EC0 Lu 1EC1 Ll 1EC2 Lu 1EC3 Ll 1EC4 Lu 1EC5 Ll 1EC6 Lu 1EC7 Ll 1EC8 Lu 1EC9 Ll 1ECA Lu 1ECB Ll 1ECC Lu 1ECD Ll 1ECE Lu 1ECF Ll 1ED0 Lu 1ED1 Ll 1ED2 Lu 1ED3 Ll 1ED4 Lu 1ED5 Ll 1ED6 Lu 1ED7 Ll 1ED8 Lu 1ED9 Ll 1EDA Lu 1EDB Ll 1EDC Lu 1EDD Ll 1EDE Lu 1EDF Ll 1EE0 Lu 1EE1 Ll 1EE2 Lu 1EE3 Ll 1EE4 Lu 1EE5 Ll 1EE6 Lu 1EE7 Ll 1EE8 Lu 1EE9 Ll 1EEA Lu 1EEB Ll 1EEC Lu 1EED Ll 1EEE Lu 1EEF Ll 1EF0 Lu 1EF1 Ll 1EF2 Lu 1EF3 Ll 1EF4 Lu 1EF5 Ll 1EF6 Lu 1EF7 Ll 1EF8 Lu 1EF9 Ll 1F00 Ll 1F01 Ll 1F02 Ll 1F03 Ll 1F04 Ll 1F05 Ll 1F06 Ll 1F07 Ll 1F08 Lu 1F09 Lu 1F0A Lu 1F0B Lu 1F0C Lu 1F0D Lu 1F0E Lu 1F0F Lu 1F10 Ll 1F11 Ll 1F12 Ll 1F13 Ll 1F14 Ll 1F15 Ll 1F18 Lu 1F19 Lu 1F1A Lu 1F1B Lu 1F1C Lu 1F1D Lu 1F20 Ll 1F21 Ll 1F22 Ll 1F23 Ll 1F24 Ll 1F25 Ll 1F26 Ll 1F27 Ll 1F28 Lu 1F29 Lu 1F2A Lu 1F2B Lu 1F2C Lu 1F2D Lu 1F2E Lu 1F2F Lu 1F30 Ll 1F31 Ll 1F32 Ll 1F33 Ll 1F34 Ll 1F35 Ll 1F36 Ll 1F37 Ll 1F38 Lu 1F39 Lu 1F3A Lu 1F3B Lu 1F3C Lu 1F3D Lu 1F3E Lu 1F3F Lu 1F40 Ll 1F41 Ll 1F42 Ll 1F43 Ll 1F44 Ll 1F45 Ll 1F48 Lu 1F49 Lu 1F4A Lu 1F4B Lu 1F4C Lu 1F4D Lu 1F50 Ll 1F51 Ll 1F52 Ll 1F53 Ll 1F54 Ll 1F55 Ll 1F56 Ll 1F57 Ll 1F59 Lu 1F5B Lu 1F5D Lu 1F5F Lu 1F60 Ll 1F61 Ll 1F62 Ll 1F63 Ll 1F64 Ll 1F65 Ll 1F66 Ll 1F67 Ll 1F68 Lu 1F69 Lu 1F6A Lu 1F6B Lu 1F6C Lu 1F6D Lu 1F6E Lu 1F6F Lu 1F70 Ll 1F71 Ll 1F72 Ll 1F73 Ll 1F74 Ll 1F75 Ll 1F76 Ll 1F77 Ll 1F78 Ll 1F79 Ll 1F7A Ll 1F7B Ll 1F7C Ll 1F7D Ll 1F80 Ll 1F81 Ll 1F82 Ll 1F83 Ll 1F84 Ll 1F85 Ll 1F86 Ll 1F87 Ll 1F88 Lt 1F89 Lt 1F8A Lt 1F8B Lt 1F8C Lt 1F8D Lt 1F8E Lt 1F8F Lt 1F90 Ll 1F91 Ll 1F92 Ll 1F93 Ll 1F94 Ll 1F95 Ll 1F96 Ll 1F97 Ll 1F98 Lt 1F99 Lt 1F9A Lt 1F9B Lt 1F9C Lt 1F9D Lt 1F9E Lt 1F9F Lt 1FA0 Ll 1FA1 Ll 1FA2 Ll 1FA3 Ll 1FA4 Ll 1FA5 Ll 1FA6 Ll 1FA7 Ll 1FA8 Lt 1FA9 Lt 1FAA Lt 1FAB Lt 1FAC Lt 1FAD Lt 1FAE Lt 1FAF Lt 1FB0 Ll 1FB1 Ll 1FB2 Ll 1FB3 Ll 1FB4 Ll 1FB6 Ll 1FB7 Ll 1FB8 Lu 1FB9 Lu 1FBA Lu 1FBB Lu 1FBC Lt 1FBD Sk 1FBE Ll 1FBF Sk 1FC0 Sk 1FC1 Sk 1FC2 Ll 1FC3 Ll 1FC4 Ll 1FC6 Ll 1FC7 Ll 1FC8 Lu 1FC9 Lu 1FCA Lu 1FCB Lu 1FCC Lt 1FCD Sk 1FCE Sk 1FCF Sk 1FD0 Ll 1FD1 Ll 1FD2 Ll 1FD3 Ll 1FD6 Ll 1FD7 Ll 1FD8 Lu 1FD9 Lu 1FDA Lu 1FDB Lu 1FDD Sk 1FDE Sk 1FDF Sk 1FE0 Ll 1FE1 Ll 1FE2 Ll 1FE3 Ll 1FE4 Ll 1FE5 Ll 1FE6 Ll 1FE7 Ll 1FE8 Lu 1FE9 Lu 1FEA Lu 1FEB Lu 1FEC Lu 1FED Sk 1FEE Sk 1FEF Sk 1FF2 Ll 1FF3 Ll 1FF4 Ll 1FF6 Ll 1FF7 Ll 1FF8 Lu 1FF9 Lu 1FFA Lu 1FFB Lu 1FFC Lt 1FFD Sk 1FFE Sk 2000 Zs 2001 Zs 2002 Zs 2003 Zs 2004 Zs 2005 Zs 2006 Zs 2007 Zs 2008 Zs 2009 Zs 200A Zs 200B Zs 200C Cf 200D Cf 200E Cf 200F Cf 2010 Pd 2011 Pd 2012 Pd 2013 Pd 2014 Pd 2015 Pd 2016 Po 2017 Po 2018 Pi 2019 Pf 201A Ps 201B Pi 201C Pi 201D Pf 201E Ps 201F Pi 2020 Po 2021 Po 2022 Po 2023 Po 2024 Po 2025 Po 2026 Po 2027 Po 2028 Zl 2029 Zp 202A Cf 202B Cf 202C Cf 202D Cf 202E Cf 202F Zs 2030 Po 2031 Po 2032 Po 2033 Po 2034 Po 2035 Po 2036 Po 2037 Po 2038 Po 2039 Pi 203A Pf 203B Po 203C Po 203D Po 203E Po 203F Pc 2040 Pc 2041 Po 2042 Po 2043 Po 2044 Sm 2045 Ps 2046 Pe 2048 Po 2049 Po 204A Po 204B Po 204C Po 204D Po 206A Cf 206B Cf 206C Cf 206D Cf 206E Cf 206F Cf 2070 No 2074 No 2075 No 2076 No 2077 No 2078 No 2079 No 207A Sm 207B Sm 207C Sm 207D Ps 207E Pe 207F Ll 2080 No 2081 No 2082 No 2083 No 2084 No 2085 No 2086 No 2087 No 2088 No 2089 No 208A Sm 208B Sm 208C Sm 208D Ps 208E Pe 20A0 Sc 20A1 Sc 20A2 Sc 20A3 Sc 20A4 Sc 20A5 Sc 20A6 Sc 20A7 Sc 20A8 Sc 20A9 Sc 20AA Sc 20AB Sc 20AC Sc 20AD Sc 20AE Sc 20AF Sc 20D0 Mn 20D1 Mn 20D2 Mn 20D3 Mn 20D4 Mn 20D5 Mn 20D6 Mn 20D7 Mn 20D8 Mn 20D9 Mn 20DA Mn 20DB Mn 20DC Mn 20DD Me 20DE Me 20DF Me 20E0 Me 20E1 Mn 20E2 Me 20E3 Me 2100 So 2101 So 2102 Lu 2103 So 2104 So 2105 So 2106 So 2107 Lu 2108 So 2109 So 210A Ll 210B Lu 210C Lu 210D Lu 210E Ll 210F Ll 2110 Lu 2111 Lu 2112 Lu 2113 Ll 2114 So 2115 Lu 2116 So 2117 So 2118 So 2119 Lu 211A Lu 211B Lu 211C Lu 211D Lu 211E So 211F So 2120 So 2121 So 2122 So 2123 So 2124 Lu 2125 So 2126 Lu 2127 So 2128 Lu 2129 So 212A Lu 212B Lu 212C Lu 212D Lu 212E So 212F Ll 2130 Lu 2131 Lu 2132 So 2133 Lu 2134 Ll 2135 Lo 2136 Lo 2137 Lo 2138 Lo 2139 Ll 213A So 2153 No 2154 No 2155 No 2156 No 2157 No 2158 No 2159 No 215A No 215B No 215C No 215D No 215E No 215F No 2160 Nl 2161 Nl 2162 Nl 2163 Nl 2164 Nl 2165 Nl 2166 Nl 2167 Nl 2168 Nl 2169 Nl 216A Nl 216B Nl 216C Nl 216D Nl 216E Nl 216F Nl 2170 Nl 2171 Nl 2172 Nl 2173 Nl 2174 Nl 2175 Nl 2176 Nl 2177 Nl 2178 Nl 2179 Nl 217A Nl 217B Nl 217C Nl 217D Nl 217E Nl 217F Nl 2180 Nl 2181 Nl 2182 Nl 2183 Nl 2190 Sm 2191 Sm 2192 Sm 2193 Sm 2194 Sm 2195 So 2196 So 2197 So 2198 So 2199 So 219A Sm 219B Sm 219C So 219D So 219E So 219F So 21A0 Sm 21A1 So 21A2 So 21A3 Sm 21A4 So 21A5 So 21A6 Sm 21A7 So 21A8 So 21A9 So 21AA So 21AB So 21AC So 21AD So 21AE Sm 21AF So 21B0 So 21B1 So 21B2 So 21B3 So 21B4 So 21B5 So 21B6 So 21B7 So 21B8 So 21B9 So 21BA So 21BB So 21BC So 21BD So 21BE So 21BF So 21C0 So 21C1 So 21C2 So 21C3 So 21C4 So 21C5 So 21C6 So 21C7 So 21C8 So 21C9 So 21CA So 21CB So 21CC So 21CD So 21CE Sm 21CF Sm 21D0 So 21D1 So 21D2 Sm 21D3 So 21D4 Sm 21D5 So 21D6 So 21D7 So 21D8 So 21D9 So 21DA So 21DB So 21DC So 21DD So 21DE So 21DF So 21E0 So 21E1 So 21E2 So 21E3 So 21E4 So 21E5 So 21E6 So 21E7 So 21E8 So 21E9 So 21EA So 21EB So 21EC So 21ED So 21EE So 21EF So 21F0 So 21F1 So 21F2 So 21F3 So 2200 Sm 2201 Sm 2202 Sm 2203 Sm 2204 Sm 2205 Sm 2206 Sm 2207 Sm 2208 Sm 2209 Sm 220A Sm 220B Sm 220C Sm 220D Sm 220E Sm 220F Sm 2210 Sm 2211 Sm 2212 Sm 2213 Sm 2214 Sm 2215 Sm 2216 Sm 2217 Sm 2218 Sm 2219 Sm 221A Sm 221B Sm 221C Sm 221D Sm 221E Sm 221F Sm 2220 Sm 2221 Sm 2222 Sm 2223 Sm 2224 Sm 2225 Sm 2226 Sm 2227 Sm 2228 Sm 2229 Sm 222A Sm 222B Sm 222C Sm 222D Sm 222E Sm 222F Sm 2230 Sm 2231 Sm 2232 Sm 2233 Sm 2234 Sm 2235 Sm 2236 Sm 2237 Sm 2238 Sm 2239 Sm 223A Sm 223B Sm 223C Sm 223D Sm 223E Sm 223F Sm 2240 Sm 2241 Sm 2242 Sm 2243 Sm 2244 Sm 2245 Sm 2246 Sm 2247 Sm 2248 Sm 2249 Sm 224A Sm 224B Sm 224C Sm 224D Sm 224E Sm 224F Sm 2250 Sm 2251 Sm 2252 Sm 2253 Sm 2254 Sm 2255 Sm 2256 Sm 2257 Sm 2258 Sm 2259 Sm 225A Sm 225B Sm 225C Sm 225D Sm 225E Sm 225F Sm 2260 Sm 2261 Sm 2262 Sm 2263 Sm 2264 Sm 2265 Sm 2266 Sm 2267 Sm 2268 Sm 2269 Sm 226A Sm 226B Sm 226C Sm 226D Sm 226E Sm 226F Sm 2270 Sm 2271 Sm 2272 Sm 2273 Sm 2274 Sm 2275 Sm 2276 Sm 2277 Sm 2278 Sm 2279 Sm 227A Sm 227B Sm 227C Sm 227D Sm 227E Sm 227F Sm 2280 Sm 2281 Sm 2282 Sm 2283 Sm 2284 Sm 2285 Sm 2286 Sm 2287 Sm 2288 Sm 2289 Sm 228A Sm 228B Sm 228C Sm 228D Sm 228E Sm 228F Sm 2290 Sm 2291 Sm 2292 Sm 2293 Sm 2294 Sm 2295 Sm 2296 Sm 2297 Sm 2298 Sm 2299 Sm 229A Sm 229B Sm 229C Sm 229D Sm 229E Sm 229F Sm 22A0 Sm 22A1 Sm 22A2 Sm 22A3 Sm 22A4 Sm 22A5 Sm 22A6 Sm 22A7 Sm 22A8 Sm 22A9 Sm 22AA Sm 22AB Sm 22AC Sm 22AD Sm 22AE Sm 22AF Sm 22B0 Sm 22B1 Sm 22B2 Sm 22B3 Sm 22B4 Sm 22B5 Sm 22B6 Sm 22B7 Sm 22B8 Sm 22B9 Sm 22BA Sm 22BB Sm 22BC Sm 22BD Sm 22BE Sm 22BF Sm 22C0 Sm 22C1 Sm 22C2 Sm 22C3 Sm 22C4 Sm 22C5 Sm 22C6 Sm 22C7 Sm 22C8 Sm 22C9 Sm 22CA Sm 22CB Sm 22CC Sm 22CD Sm 22CE Sm 22CF Sm 22D0 Sm 22D1 Sm 22D2 Sm 22D3 Sm 22D4 Sm 22D5 Sm 22D6 Sm 22D7 Sm 22D8 Sm 22D9 Sm 22DA Sm 22DB Sm 22DC Sm 22DD Sm 22DE Sm 22DF Sm 22E0 Sm 22E1 Sm 22E2 Sm 22E3 Sm 22E4 Sm 22E5 Sm 22E6 Sm 22E7 Sm 22E8 Sm 22E9 Sm 22EA Sm 22EB Sm 22EC Sm 22ED Sm 22EE Sm 22EF Sm 22F0 Sm 22F1 Sm 2300 So 2301 So 2302 So 2303 So 2304 So 2305 So 2306 So 2307 So 2308 Sm 2309 Sm 230A Sm 230B Sm 230C So 230D So 230E So 230F So 2310 So 2311 So 2312 So 2313 So 2314 So 2315 So 2316 So 2317 So 2318 So 2319 So 231A So 231B So 231C So 231D So 231E So 231F So 2320 Sm 2321 Sm 2322 So 2323 So 2324 So 2325 So 2326 So 2327 So 2328 So 2329 Ps 232A Pe 232B So 232C So 232D So 232E So 232F So 2330 So 2331 So 2332 So 2333 So 2334 So 2335 So 2336 So 2337 So 2338 So 2339 So 233A So 233B So 233C So 233D So 233E So 233F So 2340 So 2341 So 2342 So 2343 So 2344 So 2345 So 2346 So 2347 So 2348 So 2349 So 234A So 234B So 234C So 234D So 234E So 234F So 2350 So 2351 So 2352 So 2353 So 2354 So 2355 So 2356 So 2357 So 2358 So 2359 So 235A So 235B So 235C So 235D So 235E So 235F So 2360 So 2361 So 2362 So 2363 So 2364 So 2365 So 2366 So 2367 So 2368 So 2369 So 236A So 236B So 236C So 236D So 236E So 236F So 2370 So 2371 So 2372 So 2373 So 2374 So 2375 So 2376 So 2377 So 2378 So 2379 So 237A So 237B So 237D So 237E So 237F So 2380 So 2381 So 2382 So 2383 So 2384 So 2385 So 2386 So 2387 So 2388 So 2389 So 238A So 238B So 238C So 238D So 238E So 238F So 2390 So 2391 So 2392 So 2393 So 2394 So 2395 So 2396 So 2397 So 2398 So 2399 So 239A So 2400 So 2401 So 2402 So 2403 So 2404 So 2405 So 2406 So 2407 So 2408 So 2409 So 240A So 240B So 240C So 240D So 240E So 240F So 2410 So 2411 So 2412 So 2413 So 2414 So 2415 So 2416 So 2417 So 2418 So 2419 So 241A So 241B So 241C So 241D So 241E So 241F So 2420 So 2421 So 2422 So 2423 So 2424 So 2425 So 2426 So 2440 So 2441 So 2442 So 2443 So 2444 So 2445 So 2446 So 2447 So 2448 So 2449 So 244A So 2460 No 2461 No 2462 No 2463 No 2464 No 2465 No 2466 No 2467 No 2468 No 2469 No 246A No 246B No 246C No 246D No 246E No 246F No 2470 No 2471 No 2472 No 2473 No 2474 No 2475 No 2476 No 2477 No 2478 No 2479 No 247A No 247B No 247C No 247D No 247E No 247F No 2480 No 2481 No 2482 No 2483 No 2484 No 2485 No 2486 No 2487 No 2488 No 2489 No 248A No 248B No 248C No 248D No 248E No 248F No 2490 No 2491 No 2492 No 2493 No 2494 No 2495 No 2496 No 2497 No 2498 No 2499 No 249A No 249B No 249C So 249D So 249E So 249F So 24A0 So 24A1 So 24A2 So 24A3 So 24A4 So 24A5 So 24A6 So 24A7 So 24A8 So 24A9 So 24AA So 24AB So 24AC So 24AD So 24AE So 24AF So 24B0 So 24B1 So 24B2 So 24B3 So 24B4 So 24B5 So 24B6 So 24B7 So 24B8 So 24B9 So 24BA So 24BB So 24BC So 24BD So 24BE So 24BF So 24C0 So 24C1 So 24C2 So 24C3 So 24C4 So 24C5 So 24C6 So 24C7 So 24C8 So 24C9 So 24CA So 24CB So 24CC So 24CD So 24CE So 24CF So 24D0 So 24D1 So 24D2 So 24D3 So 24D4 So 24D5 So 24D6 So 24D7 So 24D8 So 24D9 So 24DA So 24DB So 24DC So 24DD So 24DE So 24DF So 24E0 So 24E1 So 24E2 So 24E3 So 24E4 So 24E5 So 24E6 So 24E7 So 24E8 So 24E9 So 24EA No 2500 So 2501 So 2502 So 2503 So 2504 So 2505 So 2506 So 2507 So 2508 So 2509 So 250A So 250B So 250C So 250D So 250E So 250F So 2510 So 2511 So 2512 So 2513 So 2514 So 2515 So 2516 So 2517 So 2518 So 2519 So 251A So 251B So 251C So 251D So 251E So 251F So 2520 So 2521 So 2522 So 2523 So 2524 So 2525 So 2526 So 2527 So 2528 So 2529 So 252A So 252B So 252C So 252D So 252E So 252F So 2530 So 2531 So 2532 So 2533 So 2534 So 2535 So 2536 So 2537 So 2538 So 2539 So 253A So 253B So 253C So 253D So 253E So 253F So 2540 So 2541 So 2542 So 2543 So 2544 So 2545 So 2546 So 2547 So 2548 So 2549 So 254A So 254B So 254C So 254D So 254E So 254F So 2550 So 2551 So 2552 So 2553 So 2554 So 2555 So 2556 So 2557 So 2558 So 2559 So 255A So 255B So 255C So 255D So 255E So 255F So 2560 So 2561 So 2562 So 2563 So 2564 So 2565 So 2566 So 2567 So 2568 So 2569 So 256A So 256B So 256C So 256D So 256E So 256F So 2570 So 2571 So 2572 So 2573 So 2574 So 2575 So 2576 So 2577 So 2578 So 2579 So 257A So 257B So 257C So 257D So 257E So 257F So 2580 So 2581 So 2582 So 2583 So 2584 So 2585 So 2586 So 2587 So 2588 So 2589 So 258A So 258B So 258C So 258D So 258E So 258F So 2590 So 2591 So 2592 So 2593 So 2594 So 2595 So 25A0 So 25A1 So 25A2 So 25A3 So 25A4 So 25A5 So 25A6 So 25A7 So 25A8 So 25A9 So 25AA So 25AB So 25AC So 25AD So 25AE So 25AF So 25B0 So 25B1 So 25B2 So 25B3 So 25B4 So 25B5 So 25B6 So 25B7 Sm 25B8 So 25B9 So 25BA So 25BB So 25BC So 25BD So 25BE So 25BF So 25C0 So 25C1 Sm 25C2 So 25C3 So 25C4 So 25C5 So 25C6 So 25C7 So 25C8 So 25C9 So 25CA So 25CB So 25CC So 25CD So 25CE So 25CF So 25D0 So 25D1 So 25D2 So 25D3 So 25D4 So 25D5 So 25D6 So 25D7 So 25D8 So 25D9 So 25DA So 25DB So 25DC So 25DD So 25DE So 25DF So 25E0 So 25E1 So 25E2 So 25E3 So 25E4 So 25E5 So 25E6 So 25E7 So 25E8 So 25E9 So 25EA So 25EB So 25EC So 25ED So 25EE So 25EF So 25F0 So 25F1 So 25F2 So 25F3 So 25F4 So 25F5 So 25F6 So 25F7 So 2600 So 2601 So 2602 So 2603 So 2604 So 2605 So 2606 So 2607 So 2608 So 2609 So 260A So 260B So 260C So 260D So 260E So 260F So 2610 So 2611 So 2612 So 2613 So 2619 So 261A So 261B So 261C So 261D So 261E So 261F So 2620 So 2621 So 2622 So 2623 So 2624 So 2625 So 2626 So 2627 So 2628 So 2629 So 262A So 262B So 262C So 262D So 262E So 262F So 2630 So 2631 So 2632 So 2633 So 2634 So 2635 So 2636 So 2637 So 2638 So 2639 So 263A So 263B So 263C So 263D So 263E So 263F So 2640 So 2641 So 2642 So 2643 So 2644 So 2645 So 2646 So 2647 So 2648 So 2649 So 264A So 264B So 264C So 264D So 264E So 264F So 2650 So 2651 So 2652 So 2653 So 2654 So 2655 So 2656 So 2657 So 2658 So 2659 So 265A So 265B So 265C So 265D So 265E So 265F So 2660 So 2661 So 2662 So 2663 So 2664 So 2665 So 2666 So 2667 So 2668 So 2669 So 266A So 266B So 266C So 266D So 266E So 266F Sm 2670 So 2671 So 2701 So 2702 So 2703 So 2704 So 2706 So 2707 So 2708 So 2709 So 270C So 270D So 270E So 270F So 2710 So 2711 So 2712 So 2713 So 2714 So 2715 So 2716 So 2717 So 2718 So 2719 So 271A So 271B So 271C So 271D So 271E So 271F So 2720 So 2721 So 2722 So 2723 So 2724 So 2725 So 2726 So 2727 So 2729 So 272A So 272B So 272C So 272D So 272E So 272F So 2730 So 2731 So 2732 So 2733 So 2734 So 2735 So 2736 So 2737 So 2738 So 2739 So 273A So 273B So 273C So 273D So 273E So 273F So 2740 So 2741 So 2742 So 2743 So 2744 So 2745 So 2746 So 2747 So 2748 So 2749 So 274A So 274B So 274D So 274F So 2750 So 2751 So 2752 So 2756 So 2758 So 2759 So 275A So 275B So 275C So 275D So 275E So 2761 So 2762 So 2763 So 2764 So 2765 So 2766 So 2767 So 2776 No 2777 No 2778 No 2779 No 277A No 277B No 277C No 277D No 277E No 277F No 2780 No 2781 No 2782 No 2783 No 2784 No 2785 No 2786 No 2787 No 2788 No 2789 No 278A No 278B No 278C No 278D No 278E No 278F No 2790 No 2791 No 2792 No 2793 No 2794 So 2798 So 2799 So 279A So 279B So 279C So 279D So 279E So 279F So 27A0 So 27A1 So 27A2 So 27A3 So 27A4 So 27A5 So 27A6 So 27A7 So 27A8 So 27A9 So 27AA So 27AB So 27AC So 27AD So 27AE So 27AF So 27B1 So 27B2 So 27B3 So 27B4 So 27B5 So 27B6 So 27B7 So 27B8 So 27B9 So 27BA So 27BB So 27BC So 27BD So 27BE So 2800 So 2801 So 2802 So 2803 So 2804 So 2805 So 2806 So 2807 So 2808 So 2809 So 280A So 280B So 280C So 280D So 280E So 280F So 2810 So 2811 So 2812 So 2813 So 2814 So 2815 So 2816 So 2817 So 2818 So 2819 So 281A So 281B So 281C So 281D So 281E So 281F So 2820 So 2821 So 2822 So 2823 So 2824 So 2825 So 2826 So 2827 So 2828 So 2829 So 282A So 282B So 282C So 282D So 282E So 282F So 2830 So 2831 So 2832 So 2833 So 2834 So 2835 So 2836 So 2837 So 2838 So 2839 So 283A So 283B So 283C So 283D So 283E So 283F So 2840 So 2841 So 2842 So 2843 So 2844 So 2845 So 2846 So 2847 So 2848 So 2849 So 284A So 284B So 284C So 284D So 284E So 284F So 2850 So 2851 So 2852 So 2853 So 2854 So 2855 So 2856 So 2857 So 2858 So 2859 So 285A So 285B So 285C So 285D So 285E So 285F So 2860 So 2861 So 2862 So 2863 So 2864 So 2865 So 2866 So 2867 So 2868 So 2869 So 286A So 286B So 286C So 286D So 286E So 286F So 2870 So 2871 So 2872 So 2873 So 2874 So 2875 So 2876 So 2877 So 2878 So 2879 So 287A So 287B So 287C So 287D So 287E So 287F So 2880 So 2881 So 2882 So 2883 So 2884 So 2885 So 2886 So 2887 So 2888 So 2889 So 288A So 288B So 288C So 288D So 288E So 288F So 2890 So 2891 So 2892 So 2893 So 2894 So 2895 So 2896 So 2897 So 2898 So 2899 So 289A So 289B So 289C So 289D So 289E So 289F So 28A0 So 28A1 So 28A2 So 28A3 So 28A4 So 28A5 So 28A6 So 28A7 So 28A8 So 28A9 So 28AA So 28AB So 28AC So 28AD So 28AE So 28AF So 28B0 So 28B1 So 28B2 So 28B3 So 28B4 So 28B5 So 28B6 So 28B7 So 28B8 So 28B9 So 28BA So 28BB So 28BC So 28BD So 28BE So 28BF So 28C0 So 28C1 So 28C2 So 28C3 So 28C4 So 28C5 So 28C6 So 28C7 So 28C8 So 28C9 So 28CA So 28CB So 28CC So 28CD So 28CE So 28CF So 28D0 So 28D1 So 28D2 So 28D3 So 28D4 So 28D5 So 28D6 So 28D7 So 28D8 So 28D9 So 28DA So 28DB So 28DC So 28DD So 28DE So 28DF So 28E0 So 28E1 So 28E2 So 28E3 So 28E4 So 28E5 So 28E6 So 28E7 So 28E8 So 28E9 So 28EA So 28EB So 28EC So 28ED So 28EE So 28EF So 28F0 So 28F1 So 28F2 So 28F3 So 28F4 So 28F5 So 28F6 So 28F7 So 28F8 So 28F9 So 28FA So 28FB So 28FC So 28FD So 28FE So 28FF So 2E80 So 2E81 So 2E82 So 2E83 So 2E84 So 2E85 So 2E86 So 2E87 So 2E88 So 2E89 So 2E8A So 2E8B So 2E8C So 2E8D So 2E8E So 2E8F So 2E90 So 2E91 So 2E92 So 2E93 So 2E94 So 2E95 So 2E96 So 2E97 So 2E98 So 2E99 So 2E9B So 2E9C So 2E9D So 2E9E So 2E9F So 2EA0 So 2EA1 So 2EA2 So 2EA3 So 2EA4 So 2EA5 So 2EA6 So 2EA7 So 2EA8 So 2EA9 So 2EAA So 2EAB So 2EAC So 2EAD So 2EAE So 2EAF So 2EB0 So 2EB1 So 2EB2 So 2EB3 So 2EB4 So 2EB5 So 2EB6 So 2EB7 So 2EB8 So 2EB9 So 2EBA So 2EBB So 2EBC So 2EBD So 2EBE So 2EBF So 2EC0 So 2EC1 So 2EC2 So 2EC3 So 2EC4 So 2EC5 So 2EC6 So 2EC7 So 2EC8 So 2EC9 So 2ECA So 2ECB So 2ECC So 2ECD So 2ECE So 2ECF So 2ED0 So 2ED1 So 2ED2 So 2ED3 So 2ED4 So 2ED5 So 2ED6 So 2ED7 So 2ED8 So 2ED9 So 2EDA So 2EDB So 2EDC So 2EDD So 2EDE So 2EDF So 2EE0 So 2EE1 So 2EE2 So 2EE3 So 2EE4 So 2EE5 So 2EE6 So 2EE7 So 2EE8 So 2EE9 So 2EEA So 2EEB So 2EEC So 2EED So 2EEE So 2EEF So 2EF0 So 2EF1 So 2EF2 So 2EF3 So 2F00 So 2F01 So 2F02 So 2F03 So 2F04 So 2F05 So 2F06 So 2F07 So 2F08 So 2F09 So 2F0A So 2F0B So 2F0C So 2F0D So 2F0E So 2F0F So 2F10 So 2F11 So 2F12 So 2F13 So 2F14 So 2F15 So 2F16 So 2F17 So 2F18 So 2F19 So 2F1A So 2F1B So 2F1C So 2F1D So 2F1E So 2F1F So 2F20 So 2F21 So 2F22 So 2F23 So 2F24 So 2F25 So 2F26 So 2F27 So 2F28 So 2F29 So 2F2A So 2F2B So 2F2C So 2F2D So 2F2E So 2F2F So 2F30 So 2F31 So 2F32 So 2F33 So 2F34 So 2F35 So 2F36 So 2F37 So 2F38 So 2F39 So 2F3A So 2F3B So 2F3C So 2F3D So 2F3E So 2F3F So 2F40 So 2F41 So 2F42 So 2F43 So 2F44 So 2F45 So 2F46 So 2F47 So 2F48 So 2F49 So 2F4A So 2F4B So 2F4C So 2F4D So 2F4E So 2F4F So 2F50 So 2F51 So 2F52 So 2F53 So 2F54 So 2F55 So 2F56 So 2F57 So 2F58 So 2F59 So 2F5A So 2F5B So 2F5C So 2F5D So 2F5E So 2F5F So 2F60 So 2F61 So 2F62 So 2F63 So 2F64 So 2F65 So 2F66 So 2F67 So 2F68 So 2F69 So 2F6A So 2F6B So 2F6C So 2F6D So 2F6E So 2F6F So 2F70 So 2F71 So 2F72 So 2F73 So 2F74 So 2F75 So 2F76 So 2F77 So 2F78 So 2F79 So 2F7A So 2F7B So 2F7C So 2F7D So 2F7E So 2F7F So 2F80 So 2F81 So 2F82 So 2F83 So 2F84 So 2F85 So 2F86 So 2F87 So 2F88 So 2F89 So 2F8A So 2F8B So 2F8C So 2F8D So 2F8E So 2F8F So 2F90 So 2F91 So 2F92 So 2F93 So 2F94 So 2F95 So 2F96 So 2F97 So 2F98 So 2F99 So 2F9A So 2F9B So 2F9C So 2F9D So 2F9E So 2F9F So 2FA0 So 2FA1 So 2FA2 So 2FA3 So 2FA4 So 2FA5 So 2FA6 So 2FA7 So 2FA8 So 2FA9 So 2FAA So 2FAB So 2FAC So 2FAD So 2FAE So 2FAF So 2FB0 So 2FB1 So 2FB2 So 2FB3 So 2FB4 So 2FB5 So 2FB6 So 2FB7 So 2FB8 So 2FB9 So 2FBA So 2FBB So 2FBC So 2FBD So 2FBE So 2FBF So 2FC0 So 2FC1 So 2FC2 So 2FC3 So 2FC4 So 2FC5 So 2FC6 So 2FC7 So 2FC8 So 2FC9 So 2FCA So 2FCB So 2FCC So 2FCD So 2FCE So 2FCF So 2FD0 So 2FD1 So 2FD2 So 2FD3 So 2FD4 So 2FD5 So 2FF0 So 2FF1 So 2FF2 So 2FF3 So 2FF4 So 2FF5 So 2FF6 So 2FF7 So 2FF8 So 2FF9 So 2FFA So 2FFB So 3000 Zs 3001 Po 3002 Po 3003 Po 3004 So 3005 Lm 3006 Lo 3007 Nl 3008 Ps 3009 Pe 300A Ps 300B Pe 300C Ps 300D Pe 300E Ps 300F Pe 3010 Ps 3011 Pe 3012 So 3013 So 3014 Ps 3015 Pe 3016 Ps 3017 Pe 3018 Ps 3019 Pe 301A Ps 301B Pe 301C Pd 301D Ps 301E Pe 301F Pe 3020 So 3021 Nl 3022 Nl 3023 Nl 3024 Nl 3025 Nl 3026 Nl 3027 Nl 3028 Nl 3029 Nl 302A Mn 302B Mn 302C Mn 302D Mn 302E Mn 302F Mn 3030 Pd 3031 Lm 3032 Lm 3033 Lm 3034 Lm 3035 Lm 3036 So 3037 So 3038 Nl 3039 Nl 303A Nl 303E So 303F So 3041 Lo 3042 Lo 3043 Lo 3044 Lo 3045 Lo 3046 Lo 3047 Lo 3048 Lo 3049 Lo 304A Lo 304B Lo 304C Lo 304D Lo 304E Lo 304F Lo 3050 Lo 3051 Lo 3052 Lo 3053 Lo 3054 Lo 3055 Lo 3056 Lo 3057 Lo 3058 Lo 3059 Lo 305A Lo 305B Lo 305C Lo 305D Lo 305E Lo 305F Lo 3060 Lo 3061 Lo 3062 Lo 3063 Lo 3064 Lo 3065 Lo 3066 Lo 3067 Lo 3068 Lo 3069 Lo 306A Lo 306B Lo 306C Lo 306D Lo 306E Lo 306F Lo 3070 Lo 3071 Lo 3072 Lo 3073 Lo 3074 Lo 3075 Lo 3076 Lo 3077 Lo 3078 Lo 3079 Lo 307A Lo 307B Lo 307C Lo 307D Lo 307E Lo 307F Lo 3080 Lo 3081 Lo 3082 Lo 3083 Lo 3084 Lo 3085 Lo 3086 Lo 3087 Lo 3088 Lo 3089 Lo 308A Lo 308B Lo 308C Lo 308D Lo 308E Lo 308F Lo 3090 Lo 3091 Lo 3092 Lo 3093 Lo 3094 Lo 3099 Mn 309A Mn 309B Sk 309C Sk 309D Lm 309E Lm 30A1 Lo 30A2 Lo 30A3 Lo 30A4 Lo 30A5 Lo 30A6 Lo 30A7 Lo 30A8 Lo 30A9 Lo 30AA Lo 30AB Lo 30AC Lo 30AD Lo 30AE Lo 30AF Lo 30B0 Lo 30B1 Lo 30B2 Lo 30B3 Lo 30B4 Lo 30B5 Lo 30B6 Lo 30B7 Lo 30B8 Lo 30B9 Lo 30BA Lo 30BB Lo 30BC Lo 30BD Lo 30BE Lo 30BF Lo 30C0 Lo 30C1 Lo 30C2 Lo 30C3 Lo 30C4 Lo 30C5 Lo 30C6 Lo 30C7 Lo 30C8 Lo 30C9 Lo 30CA Lo 30CB Lo 30CC Lo 30CD Lo 30CE Lo 30CF Lo 30D0 Lo 30D1 Lo 30D2 Lo 30D3 Lo 30D4 Lo 30D5 Lo 30D6 Lo 30D7 Lo 30D8 Lo 30D9 Lo 30DA Lo 30DB Lo 30DC Lo 30DD Lo 30DE Lo 30DF Lo 30E0 Lo 30E1 Lo 30E2 Lo 30E3 Lo 30E4 Lo 30E5 Lo 30E6 Lo 30E7 Lo 30E8 Lo 30E9 Lo 30EA Lo 30EB Lo 30EC Lo 30ED Lo 30EE Lo 30EF Lo 30F0 Lo 30F1 Lo 30F2 Lo 30F3 Lo 30F4 Lo 30F5 Lo 30F6 Lo 30F7 Lo 30F8 Lo 30F9 Lo 30FA Lo 30FB Pc 30FC Lm 30FD Lm 30FE Lm 3105 Lo 3106 Lo 3107 Lo 3108 Lo 3109 Lo 310A Lo 310B Lo 310C Lo 310D Lo 310E Lo 310F Lo 3110 Lo 3111 Lo 3112 Lo 3113 Lo 3114 Lo 3115 Lo 3116 Lo 3117 Lo 3118 Lo 3119 Lo 311A Lo 311B Lo 311C Lo 311D Lo 311E Lo 311F Lo 3120 Lo 3121 Lo 3122 Lo 3123 Lo 3124 Lo 3125 Lo 3126 Lo 3127 Lo 3128 Lo 3129 Lo 312A Lo 312B Lo 312C Lo 3131 Lo 3132 Lo 3133 Lo 3134 Lo 3135 Lo 3136 Lo 3137 Lo 3138 Lo 3139 Lo 313A Lo 313B Lo 313C Lo 313D Lo 313E Lo 313F Lo 3140 Lo 3141 Lo 3142 Lo 3143 Lo 3144 Lo 3145 Lo 3146 Lo 3147 Lo 3148 Lo 3149 Lo 314A Lo 314B Lo 314C Lo 314D Lo 314E Lo 314F Lo 3150 Lo 3151 Lo 3152 Lo 3153 Lo 3154 Lo 3155 Lo 3156 Lo 3157 Lo 3158 Lo 3159 Lo 315A Lo 315B Lo 315C Lo 315D Lo 315E Lo 315F Lo 3160 Lo 3161 Lo 3162 Lo 3163 Lo 3164 Lo 3165 Lo 3166 Lo 3167 Lo 3168 Lo 3169 Lo 316A Lo 316B Lo 316C Lo 316D Lo 316E Lo 316F Lo 3170 Lo 3171 Lo 3172 Lo 3173 Lo 3174 Lo 3175 Lo 3176 Lo 3177 Lo 3178 Lo 3179 Lo 317A Lo 317B Lo 317C Lo 317D Lo 317E Lo 317F Lo 3180 Lo 3181 Lo 3182 Lo 3183 Lo 3184 Lo 3185 Lo 3186 Lo 3187 Lo 3188 Lo 3189 Lo 318A Lo 318B Lo 318C Lo 318D Lo 318E Lo 3190 So 3191 So 3192 No 3193 No 3194 No 3195 No 3196 So 3197 So 3198 So 3199 So 319A So 319B So 319C So 319D So 319E So 319F So 31A0 Lo 31A1 Lo 31A2 Lo 31A3 Lo 31A4 Lo 31A5 Lo 31A6 Lo 31A7 Lo 31A8 Lo 31A9 Lo 31AA Lo 31AB Lo 31AC Lo 31AD Lo 31AE Lo 31AF Lo 31B0 Lo 31B1 Lo 31B2 Lo 31B3 Lo 31B4 Lo 31B5 Lo 31B6 Lo 31B7 Lo 3200 So 3201 So 3202 So 3203 So 3204 So 3205 So 3206 So 3207 So 3208 So 3209 So 320A So 320B So 320C So 320D So 320E So 320F So 3210 So 3211 So 3212 So 3213 So 3214 So 3215 So 3216 So 3217 So 3218 So 3219 So 321A So 321B So 321C So 3220 No 3221 No 3222 No 3223 No 3224 No 3225 No 3226 No 3227 No 3228 No 3229 No 322A So 322B So 322C So 322D So 322E So 322F So 3230 So 3231 So 3232 So 3233 So 3234 So 3235 So 3236 So 3237 So 3238 So 3239 So 323A So 323B So 323C So 323D So 323E So 323F So 3240 So 3241 So 3242 So 3243 So 3260 So 3261 So 3262 So 3263 So 3264 So 3265 So 3266 So 3267 So 3268 So 3269 So 326A So 326B So 326C So 326D So 326E So 326F So 3270 So 3271 So 3272 So 3273 So 3274 So 3275 So 3276 So 3277 So 3278 So 3279 So 327A So 327B So 327F So 3280 No 3281 No 3282 No 3283 No 3284 No 3285 No 3286 No 3287 No 3288 No 3289 No 328A So 328B So 328C So 328D So 328E So 328F So 3290 So 3291 So 3292 So 3293 So 3294 So 3295 So 3296 So 3297 So 3298 So 3299 So 329A So 329B So 329C So 329D So 329E So 329F So 32A0 So 32A1 So 32A2 So 32A3 So 32A4 So 32A5 So 32A6 So 32A7 So 32A8 So 32A9 So 32AA So 32AB So 32AC So 32AD So 32AE So 32AF So 32B0 So 32C0 So 32C1 So 32C2 So 32C3 So 32C4 So 32C5 So 32C6 So 32C7 So 32C8 So 32C9 So 32CA So 32CB So 32D0 So 32D1 So 32D2 So 32D3 So 32D4 So 32D5 So 32D6 So 32D7 So 32D8 So 32D9 So 32DA So 32DB So 32DC So 32DD So 32DE So 32DF So 32E0 So 32E1 So 32E2 So 32E3 So 32E4 So 32E5 So 32E6 So 32E7 So 32E8 So 32E9 So 32EA So 32EB So 32EC So 32ED So 32EE So 32EF So 32F0 So 32F1 So 32F2 So 32F3 So 32F4 So 32F5 So 32F6 So 32F7 So 32F8 So 32F9 So 32FA So 32FB So 32FC So 32FD So 32FE So 3300 So 3301 So 3302 So 3303 So 3304 So 3305 So 3306 So 3307 So 3308 So 3309 So 330A So 330B So 330C So 330D So 330E So 330F So 3310 So 3311 So 3312 So 3313 So 3314 So 3315 So 3316 So 3317 So 3318 So 3319 So 331A So 331B So 331C So 331D So 331E So 331F So 3320 So 3321 So 3322 So 3323 So 3324 So 3325 So 3326 So 3327 So 3328 So 3329 So 332A So 332B So 332C So 332D So 332E So 332F So 3330 So 3331 So 3332 So 3333 So 3334 So 3335 So 3336 So 3337 So 3338 So 3339 So 333A So 333B So 333C So 333D So 333E So 333F So 3340 So 3341 So 3342 So 3343 So 3344 So 3345 So 3346 So 3347 So 3348 So 3349 So 334A So 334B So 334C So 334D So 334E So 334F So 3350 So 3351 So 3352 So 3353 So 3354 So 3355 So 3356 So 3357 So 3358 So 3359 So 335A So 335B So 335C So 335D So 335E So 335F So 3360 So 3361 So 3362 So 3363 So 3364 So 3365 So 3366 So 3367 So 3368 So 3369 So 336A So 336B So 336C So 336D So 336E So 336F So 3370 So 3371 So 3372 So 3373 So 3374 So 3375 So 3376 So 337B So 337C So 337D So 337E So 337F So 3380 So 3381 So 3382 So 3383 So 3384 So 3385 So 3386 So 3387 So 3388 So 3389 So 338A So 338B So 338C So 338D So 338E So 338F So 3390 So 3391 So 3392 So 3393 So 3394 So 3395 So 3396 So 3397 So 3398 So 3399 So 339A So 339B So 339C So 339D So 339E So 339F So 33A0 So 33A1 So 33A2 So 33A3 So 33A4 So 33A5 So 33A6 So 33A7 So 33A8 So 33A9 So 33AA So 33AB So 33AC So 33AD So 33AE So 33AF So 33B0 So 33B1 So 33B2 So 33B3 So 33B4 So 33B5 So 33B6 So 33B7 So 33B8 So 33B9 So 33BA So 33BB So 33BC So 33BD So 33BE So 33BF So 33C0 So 33C1 So 33C2 So 33C3 So 33C4 So 33C5 So 33C6 So 33C7 So 33C8 So 33C9 So 33CA So 33CB So 33CC So 33CD So 33CE So 33CF So 33D0 So 33D1 So 33D2 So 33D3 So 33D4 So 33D5 So 33D6 So 33D7 So 33D8 So 33D9 So 33DA So 33DB So 33DC So 33DD So 33E0 So 33E1 So 33E2 So 33E3 So 33E4 So 33E5 So 33E6 So 33E7 So 33E8 So 33E9 So 33EA So 33EB So 33EC So 33ED So 33EE So 33EF So 33F0 So 33F1 So 33F2 So 33F3 So 33F4 So 33F5 So 33F6 So 33F7 So 33F8 So 33F9 So 33FA So 33FB So 33FC So 33FD So 33FE So 3400 Lo 4DB5 Lo 4E00 Lo 9FA5 Lo A000 Lo A001 Lo A002 Lo A003 Lo A004 Lo A005 Lo A006 Lo A007 Lo A008 Lo A009 Lo A00A Lo A00B Lo A00C Lo A00D Lo A00E Lo A00F Lo A010 Lo A011 Lo A012 Lo A013 Lo A014 Lo A015 Lo A016 Lo A017 Lo A018 Lo A019 Lo A01A Lo A01B Lo A01C Lo A01D Lo A01E Lo A01F Lo A020 Lo A021 Lo A022 Lo A023 Lo A024 Lo A025 Lo A026 Lo A027 Lo A028 Lo A029 Lo A02A Lo A02B Lo A02C Lo A02D Lo A02E Lo A02F Lo A030 Lo A031 Lo A032 Lo A033 Lo A034 Lo A035 Lo A036 Lo A037 Lo A038 Lo A039 Lo A03A Lo A03B Lo A03C Lo A03D Lo A03E Lo A03F Lo A040 Lo A041 Lo A042 Lo A043 Lo A044 Lo A045 Lo A046 Lo A047 Lo A048 Lo A049 Lo A04A Lo A04B Lo A04C Lo A04D Lo A04E Lo A04F Lo A050 Lo A051 Lo A052 Lo A053 Lo A054 Lo A055 Lo A056 Lo A057 Lo A058 Lo A059 Lo A05A Lo A05B Lo A05C Lo A05D Lo A05E Lo A05F Lo A060 Lo A061 Lo A062 Lo A063 Lo A064 Lo A065 Lo A066 Lo A067 Lo A068 Lo A069 Lo A06A Lo A06B Lo A06C Lo A06D Lo A06E Lo A06F Lo A070 Lo A071 Lo A072 Lo A073 Lo A074 Lo A075 Lo A076 Lo A077 Lo A078 Lo A079 Lo A07A Lo A07B Lo A07C Lo A07D Lo A07E Lo A07F Lo A080 Lo A081 Lo A082 Lo A083 Lo A084 Lo A085 Lo A086 Lo A087 Lo A088 Lo A089 Lo A08A Lo A08B Lo A08C Lo A08D Lo A08E Lo A08F Lo A090 Lo A091 Lo A092 Lo A093 Lo A094 Lo A095 Lo A096 Lo A097 Lo A098 Lo A099 Lo A09A Lo A09B Lo A09C Lo A09D Lo A09E Lo A09F Lo A0A0 Lo A0A1 Lo A0A2 Lo A0A3 Lo A0A4 Lo A0A5 Lo A0A6 Lo A0A7 Lo A0A8 Lo A0A9 Lo A0AA Lo A0AB Lo A0AC Lo A0AD Lo A0AE Lo A0AF Lo A0B0 Lo A0B1 Lo A0B2 Lo A0B3 Lo A0B4 Lo A0B5 Lo A0B6 Lo A0B7 Lo A0B8 Lo A0B9 Lo A0BA Lo A0BB Lo A0BC Lo A0BD Lo A0BE Lo A0BF Lo A0C0 Lo A0C1 Lo A0C2 Lo A0C3 Lo A0C4 Lo A0C5 Lo A0C6 Lo A0C7 Lo A0C8 Lo A0C9 Lo A0CA Lo A0CB Lo A0CC Lo A0CD Lo A0CE Lo A0CF Lo A0D0 Lo A0D1 Lo A0D2 Lo A0D3 Lo A0D4 Lo A0D5 Lo A0D6 Lo A0D7 Lo A0D8 Lo A0D9 Lo A0DA Lo A0DB Lo A0DC Lo A0DD Lo A0DE Lo A0DF Lo A0E0 Lo A0E1 Lo A0E2 Lo A0E3 Lo A0E4 Lo A0E5 Lo A0E6 Lo A0E7 Lo A0E8 Lo A0E9 Lo A0EA Lo A0EB Lo A0EC Lo A0ED Lo A0EE Lo A0EF Lo A0F0 Lo A0F1 Lo A0F2 Lo A0F3 Lo A0F4 Lo A0F5 Lo A0F6 Lo A0F7 Lo A0F8 Lo A0F9 Lo A0FA Lo A0FB Lo A0FC Lo A0FD Lo A0FE Lo A0FF Lo A100 Lo A101 Lo A102 Lo A103 Lo A104 Lo A105 Lo A106 Lo A107 Lo A108 Lo A109 Lo A10A Lo A10B Lo A10C Lo A10D Lo A10E Lo A10F Lo A110 Lo A111 Lo A112 Lo A113 Lo A114 Lo A115 Lo A116 Lo A117 Lo A118 Lo A119 Lo A11A Lo A11B Lo A11C Lo A11D Lo A11E Lo A11F Lo A120 Lo A121 Lo A122 Lo A123 Lo A124 Lo A125 Lo A126 Lo A127 Lo A128 Lo A129 Lo A12A Lo A12B Lo A12C Lo A12D Lo A12E Lo A12F Lo A130 Lo A131 Lo A132 Lo A133 Lo A134 Lo A135 Lo A136 Lo A137 Lo A138 Lo A139 Lo A13A Lo A13B Lo A13C Lo A13D Lo A13E Lo A13F Lo A140 Lo A141 Lo A142 Lo A143 Lo A144 Lo A145 Lo A146 Lo A147 Lo A148 Lo A149 Lo A14A Lo A14B Lo A14C Lo A14D Lo A14E Lo A14F Lo A150 Lo A151 Lo A152 Lo A153 Lo A154 Lo A155 Lo A156 Lo A157 Lo A158 Lo A159 Lo A15A Lo A15B Lo A15C Lo A15D Lo A15E Lo A15F Lo A160 Lo A161 Lo A162 Lo A163 Lo A164 Lo A165 Lo A166 Lo A167 Lo A168 Lo A169 Lo A16A Lo A16B Lo A16C Lo A16D Lo A16E Lo A16F Lo A170 Lo A171 Lo A172 Lo A173 Lo A174 Lo A175 Lo A176 Lo A177 Lo A178 Lo A179 Lo A17A Lo A17B Lo A17C Lo A17D Lo A17E Lo A17F Lo A180 Lo A181 Lo A182 Lo A183 Lo A184 Lo A185 Lo A186 Lo A187 Lo A188 Lo A189 Lo A18A Lo A18B Lo A18C Lo A18D Lo A18E Lo A18F Lo A190 Lo A191 Lo A192 Lo A193 Lo A194 Lo A195 Lo A196 Lo A197 Lo A198 Lo A199 Lo A19A Lo A19B Lo A19C Lo A19D Lo A19E Lo A19F Lo A1A0 Lo A1A1 Lo A1A2 Lo A1A3 Lo A1A4 Lo A1A5 Lo A1A6 Lo A1A7 Lo A1A8 Lo A1A9 Lo A1AA Lo A1AB Lo A1AC Lo A1AD Lo A1AE Lo A1AF Lo A1B0 Lo A1B1 Lo A1B2 Lo A1B3 Lo A1B4 Lo A1B5 Lo A1B6 Lo A1B7 Lo A1B8 Lo A1B9 Lo A1BA Lo A1BB Lo A1BC Lo A1BD Lo A1BE Lo A1BF Lo A1C0 Lo A1C1 Lo A1C2 Lo A1C3 Lo A1C4 Lo A1C5 Lo A1C6 Lo A1C7 Lo A1C8 Lo A1C9 Lo A1CA Lo A1CB Lo A1CC Lo A1CD Lo A1CE Lo A1CF Lo A1D0 Lo A1D1 Lo A1D2 Lo A1D3 Lo A1D4 Lo A1D5 Lo A1D6 Lo A1D7 Lo A1D8 Lo A1D9 Lo A1DA Lo A1DB Lo A1DC Lo A1DD Lo A1DE Lo A1DF Lo A1E0 Lo A1E1 Lo A1E2 Lo A1E3 Lo A1E4 Lo A1E5 Lo A1E6 Lo A1E7 Lo A1E8 Lo A1E9 Lo A1EA Lo A1EB Lo A1EC Lo A1ED Lo A1EE Lo A1EF Lo A1F0 Lo A1F1 Lo A1F2 Lo A1F3 Lo A1F4 Lo A1F5 Lo A1F6 Lo A1F7 Lo A1F8 Lo A1F9 Lo A1FA Lo A1FB Lo A1FC Lo A1FD Lo A1FE Lo A1FF Lo A200 Lo A201 Lo A202 Lo A203 Lo A204 Lo A205 Lo A206 Lo A207 Lo A208 Lo A209 Lo A20A Lo A20B Lo A20C Lo A20D Lo A20E Lo A20F Lo A210 Lo A211 Lo A212 Lo A213 Lo A214 Lo A215 Lo A216 Lo A217 Lo A218 Lo A219 Lo A21A Lo A21B Lo A21C Lo A21D Lo A21E Lo A21F Lo A220 Lo A221 Lo A222 Lo A223 Lo A224 Lo A225 Lo A226 Lo A227 Lo A228 Lo A229 Lo A22A Lo A22B Lo A22C Lo A22D Lo A22E Lo A22F Lo A230 Lo A231 Lo A232 Lo A233 Lo A234 Lo A235 Lo A236 Lo A237 Lo A238 Lo A239 Lo A23A Lo A23B Lo A23C Lo A23D Lo A23E Lo A23F Lo A240 Lo A241 Lo A242 Lo A243 Lo A244 Lo A245 Lo A246 Lo A247 Lo A248 Lo A249 Lo A24A Lo A24B Lo A24C Lo A24D Lo A24E Lo A24F Lo A250 Lo A251 Lo A252 Lo A253 Lo A254 Lo A255 Lo A256 Lo A257 Lo A258 Lo A259 Lo A25A Lo A25B Lo A25C Lo A25D Lo A25E Lo A25F Lo A260 Lo A261 Lo A262 Lo A263 Lo A264 Lo A265 Lo A266 Lo A267 Lo A268 Lo A269 Lo A26A Lo A26B Lo A26C Lo A26D Lo A26E Lo A26F Lo A270 Lo A271 Lo A272 Lo A273 Lo A274 Lo A275 Lo A276 Lo A277 Lo A278 Lo A279 Lo A27A Lo A27B Lo A27C Lo A27D Lo A27E Lo A27F Lo A280 Lo A281 Lo A282 Lo A283 Lo A284 Lo A285 Lo A286 Lo A287 Lo A288 Lo A289 Lo A28A Lo A28B Lo A28C Lo A28D Lo A28E Lo A28F Lo A290 Lo A291 Lo A292 Lo A293 Lo A294 Lo A295 Lo A296 Lo A297 Lo A298 Lo A299 Lo A29A Lo A29B Lo A29C Lo A29D Lo A29E Lo A29F Lo A2A0 Lo A2A1 Lo A2A2 Lo A2A3 Lo A2A4 Lo A2A5 Lo A2A6 Lo A2A7 Lo A2A8 Lo A2A9 Lo A2AA Lo A2AB Lo A2AC Lo A2AD Lo A2AE Lo A2AF Lo A2B0 Lo A2B1 Lo A2B2 Lo A2B3 Lo A2B4 Lo A2B5 Lo A2B6 Lo A2B7 Lo A2B8 Lo A2B9 Lo A2BA Lo A2BB Lo A2BC Lo A2BD Lo A2BE Lo A2BF Lo A2C0 Lo A2C1 Lo A2C2 Lo A2C3 Lo A2C4 Lo A2C5 Lo A2C6 Lo A2C7 Lo A2C8 Lo A2C9 Lo A2CA Lo A2CB Lo A2CC Lo A2CD Lo A2CE Lo A2CF Lo A2D0 Lo A2D1 Lo A2D2 Lo A2D3 Lo A2D4 Lo A2D5 Lo A2D6 Lo A2D7 Lo A2D8 Lo A2D9 Lo A2DA Lo A2DB Lo A2DC Lo A2DD Lo A2DE Lo A2DF Lo A2E0 Lo A2E1 Lo A2E2 Lo A2E3 Lo A2E4 Lo A2E5 Lo A2E6 Lo A2E7 Lo A2E8 Lo A2E9 Lo A2EA Lo A2EB Lo A2EC Lo A2ED Lo A2EE Lo A2EF Lo A2F0 Lo A2F1 Lo A2F2 Lo A2F3 Lo A2F4 Lo A2F5 Lo A2F6 Lo A2F7 Lo A2F8 Lo A2F9 Lo A2FA Lo A2FB Lo A2FC Lo A2FD Lo A2FE Lo A2FF Lo A300 Lo A301 Lo A302 Lo A303 Lo A304 Lo A305 Lo A306 Lo A307 Lo A308 Lo A309 Lo A30A Lo A30B Lo A30C Lo A30D Lo A30E Lo A30F Lo A310 Lo A311 Lo A312 Lo A313 Lo A314 Lo A315 Lo A316 Lo A317 Lo A318 Lo A319 Lo A31A Lo A31B Lo A31C Lo A31D Lo A31E Lo A31F Lo A320 Lo A321 Lo A322 Lo A323 Lo A324 Lo A325 Lo A326 Lo A327 Lo A328 Lo A329 Lo A32A Lo A32B Lo A32C Lo A32D Lo A32E Lo A32F Lo A330 Lo A331 Lo A332 Lo A333 Lo A334 Lo A335 Lo A336 Lo A337 Lo A338 Lo A339 Lo A33A Lo A33B Lo A33C Lo A33D Lo A33E Lo A33F Lo A340 Lo A341 Lo A342 Lo A343 Lo A344 Lo A345 Lo A346 Lo A347 Lo A348 Lo A349 Lo A34A Lo A34B Lo A34C Lo A34D Lo A34E Lo A34F Lo A350 Lo A351 Lo A352 Lo A353 Lo A354 Lo A355 Lo A356 Lo A357 Lo A358 Lo A359 Lo A35A Lo A35B Lo A35C Lo A35D Lo A35E Lo A35F Lo A360 Lo A361 Lo A362 Lo A363 Lo A364 Lo A365 Lo A366 Lo A367 Lo A368 Lo A369 Lo A36A Lo A36B Lo A36C Lo A36D Lo A36E Lo A36F Lo A370 Lo A371 Lo A372 Lo A373 Lo A374 Lo A375 Lo A376 Lo A377 Lo A378 Lo A379 Lo A37A Lo A37B Lo A37C Lo A37D Lo A37E Lo A37F Lo A380 Lo A381 Lo A382 Lo A383 Lo A384 Lo A385 Lo A386 Lo A387 Lo A388 Lo A389 Lo A38A Lo A38B Lo A38C Lo A38D Lo A38E Lo A38F Lo A390 Lo A391 Lo A392 Lo A393 Lo A394 Lo A395 Lo A396 Lo A397 Lo A398 Lo A399 Lo A39A Lo A39B Lo A39C Lo A39D Lo A39E Lo A39F Lo A3A0 Lo A3A1 Lo A3A2 Lo A3A3 Lo A3A4 Lo A3A5 Lo A3A6 Lo A3A7 Lo A3A8 Lo A3A9 Lo A3AA Lo A3AB Lo A3AC Lo A3AD Lo A3AE Lo A3AF Lo A3B0 Lo A3B1 Lo A3B2 Lo A3B3 Lo A3B4 Lo A3B5 Lo A3B6 Lo A3B7 Lo A3B8 Lo A3B9 Lo A3BA Lo A3BB Lo A3BC Lo A3BD Lo A3BE Lo A3BF Lo A3C0 Lo A3C1 Lo A3C2 Lo A3C3 Lo A3C4 Lo A3C5 Lo A3C6 Lo A3C7 Lo A3C8 Lo A3C9 Lo A3CA Lo A3CB Lo A3CC Lo A3CD Lo A3CE Lo A3CF Lo A3D0 Lo A3D1 Lo A3D2 Lo A3D3 Lo A3D4 Lo A3D5 Lo A3D6 Lo A3D7 Lo A3D8 Lo A3D9 Lo A3DA Lo A3DB Lo A3DC Lo A3DD Lo A3DE Lo A3DF Lo A3E0 Lo A3E1 Lo A3E2 Lo A3E3 Lo A3E4 Lo A3E5 Lo A3E6 Lo A3E7 Lo A3E8 Lo A3E9 Lo A3EA Lo A3EB Lo A3EC Lo A3ED Lo A3EE Lo A3EF Lo A3F0 Lo A3F1 Lo A3F2 Lo A3F3 Lo A3F4 Lo A3F5 Lo A3F6 Lo A3F7 Lo A3F8 Lo A3F9 Lo A3FA Lo A3FB Lo A3FC Lo A3FD Lo A3FE Lo A3FF Lo A400 Lo A401 Lo A402 Lo A403 Lo A404 Lo A405 Lo A406 Lo A407 Lo A408 Lo A409 Lo A40A Lo A40B Lo A40C Lo A40D Lo A40E Lo A40F Lo A410 Lo A411 Lo A412 Lo A413 Lo A414 Lo A415 Lo A416 Lo A417 Lo A418 Lo A419 Lo A41A Lo A41B Lo A41C Lo A41D Lo A41E Lo A41F Lo A420 Lo A421 Lo A422 Lo A423 Lo A424 Lo A425 Lo A426 Lo A427 Lo A428 Lo A429 Lo A42A Lo A42B Lo A42C Lo A42D Lo A42E Lo A42F Lo A430 Lo A431 Lo A432 Lo A433 Lo A434 Lo A435 Lo A436 Lo A437 Lo A438 Lo A439 Lo A43A Lo A43B Lo A43C Lo A43D Lo A43E Lo A43F Lo A440 Lo A441 Lo A442 Lo A443 Lo A444 Lo A445 Lo A446 Lo A447 Lo A448 Lo A449 Lo A44A Lo A44B Lo A44C Lo A44D Lo A44E Lo A44F Lo A450 Lo A451 Lo A452 Lo A453 Lo A454 Lo A455 Lo A456 Lo A457 Lo A458 Lo A459 Lo A45A Lo A45B Lo A45C Lo A45D Lo A45E Lo A45F Lo A460 Lo A461 Lo A462 Lo A463 Lo A464 Lo A465 Lo A466 Lo A467 Lo A468 Lo A469 Lo A46A Lo A46B Lo A46C Lo A46D Lo A46E Lo A46F Lo A470 Lo A471 Lo A472 Lo A473 Lo A474 Lo A475 Lo A476 Lo A477 Lo A478 Lo A479 Lo A47A Lo A47B Lo A47C Lo A47D Lo A47E Lo A47F Lo A480 Lo A481 Lo A482 Lo A483 Lo A484 Lo A485 Lo A486 Lo A487 Lo A488 Lo A489 Lo A48A Lo A48B Lo A48C Lo A490 So A491 So A492 So A493 So A494 So A495 So A496 So A497 So A498 So A499 So A49A So A49B So A49C So A49D So A49E So A49F So A4A0 So A4A1 So A4A4 So A4A5 So A4A6 So A4A7 So A4A8 So A4A9 So A4AA So A4AB So A4AC So A4AD So A4AE So A4AF So A4B0 So A4B1 So A4B2 So A4B3 So A4B5 So A4B6 So A4B7 So A4B8 So A4B9 So A4BA So A4BB So A4BC So A4BD So A4BE So A4BF So A4C0 So A4C2 So A4C3 So A4C4 So A4C6 So AC00 Lo D7A3 Lo D800 Cs DB7F Cs DB80 Cs DBFF Cs DC00 Cs DFFF Cs E000 Co F8FF Co F900 Lo F901 Lo F902 Lo F903 Lo F904 Lo F905 Lo F906 Lo F907 Lo F908 Lo F909 Lo F90A Lo F90B Lo F90C Lo F90D Lo F90E Lo F90F Lo F910 Lo F911 Lo F912 Lo F913 Lo F914 Lo F915 Lo F916 Lo F917 Lo F918 Lo F919 Lo F91A Lo F91B Lo F91C Lo F91D Lo F91E Lo F91F Lo F920 Lo F921 Lo F922 Lo F923 Lo F924 Lo F925 Lo F926 Lo F927 Lo F928 Lo F929 Lo F92A Lo F92B Lo F92C Lo F92D Lo F92E Lo F92F Lo F930 Lo F931 Lo F932 Lo F933 Lo F934 Lo F935 Lo F936 Lo F937 Lo F938 Lo F939 Lo F93A Lo F93B Lo F93C Lo F93D Lo F93E Lo F93F Lo F940 Lo F941 Lo F942 Lo F943 Lo F944 Lo F945 Lo F946 Lo F947 Lo F948 Lo F949 Lo F94A Lo F94B Lo F94C Lo F94D Lo F94E Lo F94F Lo F950 Lo F951 Lo F952 Lo F953 Lo F954 Lo F955 Lo F956 Lo F957 Lo F958 Lo F959 Lo F95A Lo F95B Lo F95C Lo F95D Lo F95E Lo F95F Lo F960 Lo F961 Lo F962 Lo F963 Lo F964 Lo F965 Lo F966 Lo F967 Lo F968 Lo F969 Lo F96A Lo F96B Lo F96C Lo F96D Lo F96E Lo F96F Lo F970 Lo F971 Lo F972 Lo F973 Lo F974 Lo F975 Lo F976 Lo F977 Lo F978 Lo F979 Lo F97A Lo F97B Lo F97C Lo F97D Lo F97E Lo F97F Lo F980 Lo F981 Lo F982 Lo F983 Lo F984 Lo F985 Lo F986 Lo F987 Lo F988 Lo F989 Lo F98A Lo F98B Lo F98C Lo F98D Lo F98E Lo F98F Lo F990 Lo F991 Lo F992 Lo F993 Lo F994 Lo F995 Lo F996 Lo F997 Lo F998 Lo F999 Lo F99A Lo F99B Lo F99C Lo F99D Lo F99E Lo F99F Lo F9A0 Lo F9A1 Lo F9A2 Lo F9A3 Lo F9A4 Lo F9A5 Lo F9A6 Lo F9A7 Lo F9A8 Lo F9A9 Lo F9AA Lo F9AB Lo F9AC Lo F9AD Lo F9AE Lo F9AF Lo F9B0 Lo F9B1 Lo F9B2 Lo F9B3 Lo F9B4 Lo F9B5 Lo F9B6 Lo F9B7 Lo F9B8 Lo F9B9 Lo F9BA Lo F9BB Lo F9BC Lo F9BD Lo F9BE Lo F9BF Lo F9C0 Lo F9C1 Lo F9C2 Lo F9C3 Lo F9C4 Lo F9C5 Lo F9C6 Lo F9C7 Lo F9C8 Lo F9C9 Lo F9CA Lo F9CB Lo F9CC Lo F9CD Lo F9CE Lo F9CF Lo F9D0 Lo F9D1 Lo F9D2 Lo F9D3 Lo F9D4 Lo F9D5 Lo F9D6 Lo F9D7 Lo F9D8 Lo F9D9 Lo F9DA Lo F9DB Lo F9DC Lo F9DD Lo F9DE Lo F9DF Lo F9E0 Lo F9E1 Lo F9E2 Lo F9E3 Lo F9E4 Lo F9E5 Lo F9E6 Lo F9E7 Lo F9E8 Lo F9E9 Lo F9EA Lo F9EB Lo F9EC Lo F9ED Lo F9EE Lo F9EF Lo F9F0 Lo F9F1 Lo F9F2 Lo F9F3 Lo F9F4 Lo F9F5 Lo F9F6 Lo F9F7 Lo F9F8 Lo F9F9 Lo F9FA Lo F9FB Lo F9FC Lo F9FD Lo F9FE Lo F9FF Lo FA00 Lo FA01 Lo FA02 Lo FA03 Lo FA04 Lo FA05 Lo FA06 Lo FA07 Lo FA08 Lo FA09 Lo FA0A Lo FA0B Lo FA0C Lo FA0D Lo FA0E Lo FA0F Lo FA10 Lo FA11 Lo FA12 Lo FA13 Lo FA14 Lo FA15 Lo FA16 Lo FA17 Lo FA18 Lo FA19 Lo FA1A Lo FA1B Lo FA1C Lo FA1D Lo FA1E Lo FA1F Lo FA20 Lo FA21 Lo FA22 Lo FA23 Lo FA24 Lo FA25 Lo FA26 Lo FA27 Lo FA28 Lo FA29 Lo FA2A Lo FA2B Lo FA2C Lo FA2D Lo FB00 Ll FB01 Ll FB02 Ll FB03 Ll FB04 Ll FB05 Ll FB06 Ll FB13 Ll FB14 Ll FB15 Ll FB16 Ll FB17 Ll FB1D Lo FB1E Mn FB1F Lo FB20 Lo FB21 Lo FB22 Lo FB23 Lo FB24 Lo FB25 Lo FB26 Lo FB27 Lo FB28 Lo FB29 Sm FB2A Lo FB2B Lo FB2C Lo FB2D Lo FB2E Lo FB2F Lo FB30 Lo FB31 Lo FB32 Lo FB33 Lo FB34 Lo FB35 Lo FB36 Lo FB38 Lo FB39 Lo FB3A Lo FB3B Lo FB3C Lo FB3E Lo FB40 Lo FB41 Lo FB43 Lo FB44 Lo FB46 Lo FB47 Lo FB48 Lo FB49 Lo FB4A Lo FB4B Lo FB4C Lo FB4D Lo FB4E Lo FB4F Lo FB50 Lo FB51 Lo FB52 Lo FB53 Lo FB54 Lo FB55 Lo FB56 Lo FB57 Lo FB58 Lo FB59 Lo FB5A Lo FB5B Lo FB5C Lo FB5D Lo FB5E Lo FB5F Lo FB60 Lo FB61 Lo FB62 Lo FB63 Lo FB64 Lo FB65 Lo FB66 Lo FB67 Lo FB68 Lo FB69 Lo FB6A Lo FB6B Lo FB6C Lo FB6D Lo FB6E Lo FB6F Lo FB70 Lo FB71 Lo FB72 Lo FB73 Lo FB74 Lo FB75 Lo FB76 Lo FB77 Lo FB78 Lo FB79 Lo FB7A Lo FB7B Lo FB7C Lo FB7D Lo FB7E Lo FB7F Lo FB80 Lo FB81 Lo FB82 Lo FB83 Lo FB84 Lo FB85 Lo FB86 Lo FB87 Lo FB88 Lo FB89 Lo FB8A Lo FB8B Lo FB8C Lo FB8D Lo FB8E Lo FB8F Lo FB90 Lo FB91 Lo FB92 Lo FB93 Lo FB94 Lo FB95 Lo FB96 Lo FB97 Lo FB98 Lo FB99 Lo FB9A Lo FB9B Lo FB9C Lo FB9D Lo FB9E Lo FB9F Lo FBA0 Lo FBA1 Lo FBA2 Lo FBA3 Lo FBA4 Lo FBA5 Lo FBA6 Lo FBA7 Lo FBA8 Lo FBA9 Lo FBAA Lo FBAB Lo FBAC Lo FBAD Lo FBAE Lo FBAF Lo FBB0 Lo FBB1 Lo FBD3 Lo FBD4 Lo FBD5 Lo FBD6 Lo FBD7 Lo FBD8 Lo FBD9 Lo FBDA Lo FBDB Lo FBDC Lo FBDD Lo FBDE Lo FBDF Lo FBE0 Lo FBE1 Lo FBE2 Lo FBE3 Lo FBE4 Lo FBE5 Lo FBE6 Lo FBE7 Lo FBE8 Lo FBE9 Lo FBEA Lo FBEB Lo FBEC Lo FBED Lo FBEE Lo FBEF Lo FBF0 Lo FBF1 Lo FBF2 Lo FBF3 Lo FBF4 Lo FBF5 Lo FBF6 Lo FBF7 Lo FBF8 Lo FBF9 Lo FBFA Lo FBFB Lo FBFC Lo FBFD Lo FBFE Lo FBFF Lo FC00 Lo FC01 Lo FC02 Lo FC03 Lo FC04 Lo FC05 Lo FC06 Lo FC07 Lo FC08 Lo FC09 Lo FC0A Lo FC0B Lo FC0C Lo FC0D Lo FC0E Lo FC0F Lo FC10 Lo FC11 Lo FC12 Lo FC13 Lo FC14 Lo FC15 Lo FC16 Lo FC17 Lo FC18 Lo FC19 Lo FC1A Lo FC1B Lo FC1C Lo FC1D Lo FC1E Lo FC1F Lo FC20 Lo FC21 Lo FC22 Lo FC23 Lo FC24 Lo FC25 Lo FC26 Lo FC27 Lo FC28 Lo FC29 Lo FC2A Lo FC2B Lo FC2C Lo FC2D Lo FC2E Lo FC2F Lo FC30 Lo FC31 Lo FC32 Lo FC33 Lo FC34 Lo FC35 Lo FC36 Lo FC37 Lo FC38 Lo FC39 Lo FC3A Lo FC3B Lo FC3C Lo FC3D Lo FC3E Lo FC3F Lo FC40 Lo FC41 Lo FC42 Lo FC43 Lo FC44 Lo FC45 Lo FC46 Lo FC47 Lo FC48 Lo FC49 Lo FC4A Lo FC4B Lo FC4C Lo FC4D Lo FC4E Lo FC4F Lo FC50 Lo FC51 Lo FC52 Lo FC53 Lo FC54 Lo FC55 Lo FC56 Lo FC57 Lo FC58 Lo FC59 Lo FC5A Lo FC5B Lo FC5C Lo FC5D Lo FC5E Lo FC5F Lo FC60 Lo FC61 Lo FC62 Lo FC63 Lo FC64 Lo FC65 Lo FC66 Lo FC67 Lo FC68 Lo FC69 Lo FC6A Lo FC6B Lo FC6C Lo FC6D Lo FC6E Lo FC6F Lo FC70 Lo FC71 Lo FC72 Lo FC73 Lo FC74 Lo FC75 Lo FC76 Lo FC77 Lo FC78 Lo FC79 Lo FC7A Lo FC7B Lo FC7C Lo FC7D Lo FC7E Lo FC7F Lo FC80 Lo FC81 Lo FC82 Lo FC83 Lo FC84 Lo FC85 Lo FC86 Lo FC87 Lo FC88 Lo FC89 Lo FC8A Lo FC8B Lo FC8C Lo FC8D Lo FC8E Lo FC8F Lo FC90 Lo FC91 Lo FC92 Lo FC93 Lo FC94 Lo FC95 Lo FC96 Lo FC97 Lo FC98 Lo FC99 Lo FC9A Lo FC9B Lo FC9C Lo FC9D Lo FC9E Lo FC9F Lo FCA0 Lo FCA1 Lo FCA2 Lo FCA3 Lo FCA4 Lo FCA5 Lo FCA6 Lo FCA7 Lo FCA8 Lo FCA9 Lo FCAA Lo FCAB Lo FCAC Lo FCAD Lo FCAE Lo FCAF Lo FCB0 Lo FCB1 Lo FCB2 Lo FCB3 Lo FCB4 Lo FCB5 Lo FCB6 Lo FCB7 Lo FCB8 Lo FCB9 Lo FCBA Lo FCBB Lo FCBC Lo FCBD Lo FCBE Lo FCBF Lo FCC0 Lo FCC1 Lo FCC2 Lo FCC3 Lo FCC4 Lo FCC5 Lo FCC6 Lo FCC7 Lo FCC8 Lo FCC9 Lo FCCA Lo FCCB Lo FCCC Lo FCCD Lo FCCE Lo FCCF Lo FCD0 Lo FCD1 Lo FCD2 Lo FCD3 Lo FCD4 Lo FCD5 Lo FCD6 Lo FCD7 Lo FCD8 Lo FCD9 Lo FCDA Lo FCDB Lo FCDC Lo FCDD Lo FCDE Lo FCDF Lo FCE0 Lo FCE1 Lo FCE2 Lo FCE3 Lo FCE4 Lo FCE5 Lo FCE6 Lo FCE7 Lo FCE8 Lo FCE9 Lo FCEA Lo FCEB Lo FCEC Lo FCED Lo FCEE Lo FCEF Lo FCF0 Lo FCF1 Lo FCF2 Lo FCF3 Lo FCF4 Lo FCF5 Lo FCF6 Lo FCF7 Lo FCF8 Lo FCF9 Lo FCFA Lo FCFB Lo FCFC Lo FCFD Lo FCFE Lo FCFF Lo FD00 Lo FD01 Lo FD02 Lo FD03 Lo FD04 Lo FD05 Lo FD06 Lo FD07 Lo FD08 Lo FD09 Lo FD0A Lo FD0B Lo FD0C Lo FD0D Lo FD0E Lo FD0F Lo FD10 Lo FD11 Lo FD12 Lo FD13 Lo FD14 Lo FD15 Lo FD16 Lo FD17 Lo FD18 Lo FD19 Lo FD1A Lo FD1B Lo FD1C Lo FD1D Lo FD1E Lo FD1F Lo FD20 Lo FD21 Lo FD22 Lo FD23 Lo FD24 Lo FD25 Lo FD26 Lo FD27 Lo FD28 Lo FD29 Lo FD2A Lo FD2B Lo FD2C Lo FD2D Lo FD2E Lo FD2F Lo FD30 Lo FD31 Lo FD32 Lo FD33 Lo FD34 Lo FD35 Lo FD36 Lo FD37 Lo FD38 Lo FD39 Lo FD3A Lo FD3B Lo FD3C Lo FD3D Lo FD3E Ps FD3F Pe FD50 Lo FD51 Lo FD52 Lo FD53 Lo FD54 Lo FD55 Lo FD56 Lo FD57 Lo FD58 Lo FD59 Lo FD5A Lo FD5B Lo FD5C Lo FD5D Lo FD5E Lo FD5F Lo FD60 Lo FD61 Lo FD62 Lo FD63 Lo FD64 Lo FD65 Lo FD66 Lo FD67 Lo FD68 Lo FD69 Lo FD6A Lo FD6B Lo FD6C Lo FD6D Lo FD6E Lo FD6F Lo FD70 Lo FD71 Lo FD72 Lo FD73 Lo FD74 Lo FD75 Lo FD76 Lo FD77 Lo FD78 Lo FD79 Lo FD7A Lo FD7B Lo FD7C Lo FD7D Lo FD7E Lo FD7F Lo FD80 Lo FD81 Lo FD82 Lo FD83 Lo FD84 Lo FD85 Lo FD86 Lo FD87 Lo FD88 Lo FD89 Lo FD8A Lo FD8B Lo FD8C Lo FD8D Lo FD8E Lo FD8F Lo FD92 Lo FD93 Lo FD94 Lo FD95 Lo FD96 Lo FD97 Lo FD98 Lo FD99 Lo FD9A Lo FD9B Lo FD9C Lo FD9D Lo FD9E Lo FD9F Lo FDA0 Lo FDA1 Lo FDA2 Lo FDA3 Lo FDA4 Lo FDA5 Lo FDA6 Lo FDA7 Lo FDA8 Lo FDA9 Lo FDAA Lo FDAB Lo FDAC Lo FDAD Lo FDAE Lo FDAF Lo FDB0 Lo FDB1 Lo FDB2 Lo FDB3 Lo FDB4 Lo FDB5 Lo FDB6 Lo FDB7 Lo FDB8 Lo FDB9 Lo FDBA Lo FDBB Lo FDBC Lo FDBD Lo FDBE Lo FDBF Lo FDC0 Lo FDC1 Lo FDC2 Lo FDC3 Lo FDC4 Lo FDC5 Lo FDC6 Lo FDC7 Lo FDF0 Lo FDF1 Lo FDF2 Lo FDF3 Lo FDF4 Lo FDF5 Lo FDF6 Lo FDF7 Lo FDF8 Lo FDF9 Lo FDFA Lo FDFB Lo FE20 Mn FE21 Mn FE22 Mn FE23 Mn FE30 Po FE31 Pd FE32 Pd FE33 Pc FE34 Pc FE35 Ps FE36 Pe FE37 Ps FE38 Pe FE39 Ps FE3A Pe FE3B Ps FE3C Pe FE3D Ps FE3E Pe FE3F Ps FE40 Pe FE41 Ps FE42 Pe FE43 Ps FE44 Pe FE49 Po FE4A Po FE4B Po FE4C Po FE4D Pc FE4E Pc FE4F Pc FE50 Po FE51 Po FE52 Po FE54 Po FE55 Po FE56 Po FE57 Po FE58 Pd FE59 Ps FE5A Pe FE5B Ps FE5C Pe FE5D Ps FE5E Pe FE5F Po FE60 Po FE61 Po FE62 Sm FE63 Pd FE64 Sm FE65 Sm FE66 Sm FE68 Po FE69 Sc FE6A Po FE6B Po FE70 Lo FE71 Lo FE72 Lo FE74 Lo FE76 Lo FE77 Lo FE78 Lo FE79 Lo FE7A Lo FE7B Lo FE7C Lo FE7D Lo FE7E Lo FE7F Lo FE80 Lo FE81 Lo FE82 Lo FE83 Lo FE84 Lo FE85 Lo FE86 Lo FE87 Lo FE88 Lo FE89 Lo FE8A Lo FE8B Lo FE8C Lo FE8D Lo FE8E Lo FE8F Lo FE90 Lo FE91 Lo FE92 Lo FE93 Lo FE94 Lo FE95 Lo FE96 Lo FE97 Lo FE98 Lo FE99 Lo FE9A Lo FE9B Lo FE9C Lo FE9D Lo FE9E Lo FE9F Lo FEA0 Lo FEA1 Lo FEA2 Lo FEA3 Lo FEA4 Lo FEA5 Lo FEA6 Lo FEA7 Lo FEA8 Lo FEA9 Lo FEAA Lo FEAB Lo FEAC Lo FEAD Lo FEAE Lo FEAF Lo FEB0 Lo FEB1 Lo FEB2 Lo FEB3 Lo FEB4 Lo FEB5 Lo FEB6 Lo FEB7 Lo FEB8 Lo FEB9 Lo FEBA Lo FEBB Lo FEBC Lo FEBD Lo FEBE Lo FEBF Lo FEC0 Lo FEC1 Lo FEC2 Lo FEC3 Lo FEC4 Lo FEC5 Lo FEC6 Lo FEC7 Lo FEC8 Lo FEC9 Lo FECA Lo FECB Lo FECC Lo FECD Lo FECE Lo FECF Lo FED0 Lo FED1 Lo FED2 Lo FED3 Lo FED4 Lo FED5 Lo FED6 Lo FED7 Lo FED8 Lo FED9 Lo FEDA Lo FEDB Lo FEDC Lo FEDD Lo FEDE Lo FEDF Lo FEE0 Lo FEE1 Lo FEE2 Lo FEE3 Lo FEE4 Lo FEE5 Lo FEE6 Lo FEE7 Lo FEE8 Lo FEE9 Lo FEEA Lo FEEB Lo FEEC Lo FEED Lo FEEE Lo FEEF Lo FEF0 Lo FEF1 Lo FEF2 Lo FEF3 Lo FEF4 Lo FEF5 Lo FEF6 Lo FEF7 Lo FEF8 Lo FEF9 Lo FEFA Lo FEFB Lo FEFC Lo FEFF Cf FF01 Po FF02 Po FF03 Po FF04 Sc FF05 Po FF06 Po FF07 Po FF08 Ps FF09 Pe FF0A Po FF0B Sm FF0C Po FF0D Pd FF0E Po FF0F Po FF10 Nd FF11 Nd FF12 Nd FF13 Nd FF14 Nd FF15 Nd FF16 Nd FF17 Nd FF18 Nd FF19 Nd FF1A Po FF1B Po FF1C Sm FF1D Sm FF1E Sm FF1F Po FF20 Po FF21 Lu FF22 Lu FF23 Lu FF24 Lu FF25 Lu FF26 Lu FF27 Lu FF28 Lu FF29 Lu FF2A Lu FF2B Lu FF2C Lu FF2D Lu FF2E Lu FF2F Lu FF30 Lu FF31 Lu FF32 Lu FF33 Lu FF34 Lu FF35 Lu FF36 Lu FF37 Lu FF38 Lu FF39 Lu FF3A Lu FF3B Ps FF3C Po FF3D Pe FF3E Sk FF3F Pc FF40 Sk FF41 Ll FF42 Ll FF43 Ll FF44 Ll FF45 Ll FF46 Ll FF47 Ll FF48 Ll FF49 Ll FF4A Ll FF4B Ll FF4C Ll FF4D Ll FF4E Ll FF4F Ll FF50 Ll FF51 Ll FF52 Ll FF53 Ll FF54 Ll FF55 Ll FF56 Ll FF57 Ll FF58 Ll FF59 Ll FF5A Ll FF5B Ps FF5C Sm FF5D Pe FF5E Sm FF61 Po FF62 Ps FF63 Pe FF64 Po FF65 Pc FF66 Lo FF67 Lo FF68 Lo FF69 Lo FF6A Lo FF6B Lo FF6C Lo FF6D Lo FF6E Lo FF6F Lo FF70 Lm FF71 Lo FF72 Lo FF73 Lo FF74 Lo FF75 Lo FF76 Lo FF77 Lo FF78 Lo FF79 Lo FF7A Lo FF7B Lo FF7C Lo FF7D Lo FF7E Lo FF7F Lo FF80 Lo FF81 Lo FF82 Lo FF83 Lo FF84 Lo FF85 Lo FF86 Lo FF87 Lo FF88 Lo FF89 Lo FF8A Lo FF8B Lo FF8C Lo FF8D Lo FF8E Lo FF8F Lo FF90 Lo FF91 Lo FF92 Lo FF93 Lo FF94 Lo FF95 Lo FF96 Lo FF97 Lo FF98 Lo FF99 Lo FF9A Lo FF9B Lo FF9C Lo FF9D Lo FF9E Lm FF9F Lm FFA0 Lo FFA1 Lo FFA2 Lo FFA3 Lo FFA4 Lo FFA5 Lo FFA6 Lo FFA7 Lo FFA8 Lo FFA9 Lo FFAA Lo FFAB Lo FFAC Lo FFAD Lo FFAE Lo FFAF Lo FFB0 Lo FFB1 Lo FFB2 Lo FFB3 Lo FFB4 Lo FFB5 Lo FFB6 Lo FFB7 Lo FFB8 Lo FFB9 Lo FFBA Lo FFBB Lo FFBC Lo FFBD Lo FFBE Lo FFC2 Lo FFC3 Lo FFC4 Lo FFC5 Lo FFC6 Lo FFC7 Lo FFCA Lo FFCB Lo FFCC Lo FFCD Lo FFCE Lo FFCF Lo FFD2 Lo FFD3 Lo FFD4 Lo FFD5 Lo FFD6 Lo FFD7 Lo FFDA Lo FFDB Lo FFDC Lo FFE0 Sc FFE1 Sc FFE2 Sm FFE3 Sk FFE4 So FFE5 Sc FFE6 Sc FFE8 So FFE9 Sm FFEA Sm FFEB Sm FFEC Sm FFED So FFEE So FFF9 Cf FFFA Cf FFFB Cf FFFC So FFFD So 10300 Lo 10301 Lo 10302 Lo 10303 Lo 10304 Lo 10305 Lo 10306 Lo 10307 Lo 10308 Lo 10309 Lo 1030A Lo 1030B Lo 1030C Lo 1030D Lo 1030E Lo 1030F Lo 10310 Lo 10311 Lo 10312 Lo 10313 Lo 10314 Lo 10315 Lo 10316 Lo 10317 Lo 10318 Lo 10319 Lo 1031A Lo 1031B Lo 1031C Lo 1031D Lo 1031E Lo 10320 No 10321 No 10322 No 10323 No 10330 Lo 10331 Lo 10332 Lo 10333 Lo 10334 Lo 10335 Lo 10336 Lo 10337 Lo 10338 Lo 10339 Lo 1033A Lo 1033B Lo 1033C Lo 1033D Lo 1033E Lo 1033F Lo 10340 Lo 10341 Lo 10342 Lo 10343 Lo 10344 Lo 10345 Lo 10346 Lo 10347 Lo 10348 Lo 10349 Lo 1034A Nl 10400 Lu 10401 Lu 10402 Lu 10403 Lu 10404 Lu 10405 Lu 10406 Lu 10407 Lu 10408 Lu 10409 Lu 1040A Lu 1040B Lu 1040C Lu 1040D Lu 1040E Lu 1040F Lu 10410 Lu 10411 Lu 10412 Lu 10413 Lu 10414 Lu 10415 Lu 10416 Lu 10417 Lu 10418 Lu 10419 Lu 1041A Lu 1041B Lu 1041C Lu 1041D Lu 1041E Lu 1041F Lu 10420 Lu 10421 Lu 10422 Lu 10423 Lu 10424 Lu 10425 Lu 10428 Ll 10429 Ll 1042A Ll 1042B Ll 1042C Ll 1042D Ll 1042E Ll 1042F Ll 10430 Ll 10431 Ll 10432 Ll 10433 Ll 10434 Ll 10435 Ll 10436 Ll 10437 Ll 10438 Ll 10439 Ll 1043A Ll 1043B Ll 1043C Ll 1043D Ll 1043E Ll 1043F Ll 10440 Ll 10441 Ll 10442 Ll 10443 Ll 10444 Ll 10445 Ll 10446 Ll 10447 Ll 10448 Ll 10449 Ll 1044A Ll 1044B Ll 1044C Ll 1044D Ll 1D000 So 1D001 So 1D002 So 1D003 So 1D004 So 1D005 So 1D006 So 1D007 So 1D008 So 1D009 So 1D00A So 1D00B So 1D00C So 1D00D So 1D00E So 1D00F So 1D010 So 1D011 So 1D012 So 1D013 So 1D014 So 1D015 So 1D016 So 1D017 So 1D018 So 1D019 So 1D01A So 1D01B So 1D01C So 1D01D So 1D01E So 1D01F So 1D020 So 1D021 So 1D022 So 1D023 So 1D024 So 1D025 So 1D026 So 1D027 So 1D028 So 1D029 So 1D02A So 1D02B So 1D02C So 1D02D So 1D02E So 1D02F So 1D030 So 1D031 So 1D032 So 1D033 So 1D034 So 1D035 So 1D036 So 1D037 So 1D038 So 1D039 So 1D03A So 1D03B So 1D03C So 1D03D So 1D03E So 1D03F So 1D040 So 1D041 So 1D042 So 1D043 So 1D044 So 1D045 So 1D046 So 1D047 So 1D048 So 1D049 So 1D04A So 1D04B So 1D04C So 1D04D So 1D04E So 1D04F So 1D050 So 1D051 So 1D052 So 1D053 So 1D054 So 1D055 So 1D056 So 1D057 So 1D058 So 1D059 So 1D05A So 1D05B So 1D05C So 1D05D So 1D05E So 1D05F So 1D060 So 1D061 So 1D062 So 1D063 So 1D064 So 1D065 So 1D066 So 1D067 So 1D068 So 1D069 So 1D06A So 1D06B So 1D06C So 1D06D So 1D06E So 1D06F So 1D070 So 1D071 So 1D072 So 1D073 So 1D074 So 1D075 So 1D076 So 1D077 So 1D078 So 1D079 So 1D07A So 1D07B So 1D07C So 1D07D So 1D07E So 1D07F So 1D080 So 1D081 So 1D082 So 1D083 So 1D084 So 1D085 So 1D086 So 1D087 So 1D088 So 1D089 So 1D08A So 1D08B So 1D08C So 1D08D So 1D08E So 1D08F So 1D090 So 1D091 So 1D092 So 1D093 So 1D094 So 1D095 So 1D096 So 1D097 So 1D098 So 1D099 So 1D09A So 1D09B So 1D09C So 1D09D So 1D09E So 1D09F So 1D0A0 So 1D0A1 So 1D0A2 So 1D0A3 So 1D0A4 So 1D0A5 So 1D0A6 So 1D0A7 So 1D0A8 So 1D0A9 So 1D0AA So 1D0AB So 1D0AC So 1D0AD So 1D0AE So 1D0AF So 1D0B0 So 1D0B1 So 1D0B2 So 1D0B3 So 1D0B4 So 1D0B5 So 1D0B6 So 1D0B7 So 1D0B8 So 1D0B9 So 1D0BA So 1D0BB So 1D0BC So 1D0BD So 1D0BE So 1D0BF So 1D0C0 So 1D0C1 So 1D0C2 So 1D0C3 So 1D0C4 So 1D0C5 So 1D0C6 So 1D0C7 So 1D0C8 So 1D0C9 So 1D0CA So 1D0CB So 1D0CC So 1D0CD So 1D0CE So 1D0CF So 1D0D0 So 1D0D1 So 1D0D2 So 1D0D3 So 1D0D4 So 1D0D5 So 1D0D6 So 1D0D7 So 1D0D8 So 1D0D9 So 1D0DA So 1D0DB So 1D0DC So 1D0DD So 1D0DE So 1D0DF So 1D0E0 So 1D0E1 So 1D0E2 So 1D0E3 So 1D0E4 So 1D0E5 So 1D0E6 So 1D0E7 So 1D0E8 So 1D0E9 So 1D0EA So 1D0EB So 1D0EC So 1D0ED So 1D0EE So 1D0EF So 1D0F0 So 1D0F1 So 1D0F2 So 1D0F3 So 1D0F4 So 1D0F5 So 1D100 So 1D101 So 1D102 So 1D103 So 1D104 So 1D105 So 1D106 So 1D107 So 1D108 So 1D109 So 1D10A So 1D10B So 1D10C So 1D10D So 1D10E So 1D10F So 1D110 So 1D111 So 1D112 So 1D113 So 1D114 So 1D115 So 1D116 So 1D117 So 1D118 So 1D119 So 1D11A So 1D11B So 1D11C So 1D11D So 1D11E So 1D11F So 1D120 So 1D121 So 1D122 So 1D123 So 1D124 So 1D125 So 1D126 So 1D12A So 1D12B So 1D12C So 1D12D So 1D12E So 1D12F So 1D130 So 1D131 So 1D132 So 1D133 So 1D134 So 1D135 So 1D136 So 1D137 So 1D138 So 1D139 So 1D13A So 1D13B So 1D13C So 1D13D So 1D13E So 1D13F So 1D140 So 1D141 So 1D142 So 1D143 So 1D144 So 1D145 So 1D146 So 1D147 So 1D148 So 1D149 So 1D14A So 1D14B So 1D14C So 1D14D So 1D14E So 1D14F So 1D150 So 1D151 So 1D152 So 1D153 So 1D154 So 1D155 So 1D156 So 1D157 So 1D158 So 1D159 So 1D15A So 1D15B So 1D15C So 1D15D So 1D15E So 1D15F So 1D160 So 1D161 So 1D162 So 1D163 So 1D164 So 1D165 Mc 1D166 Mc 1D167 Mn 1D168 Mn 1D169 Mn 1D16A So 1D16B So 1D16C So 1D16D Mc 1D16E Mc 1D16F Mc 1D170 Mc 1D171 Mc 1D172 Mc 1D173 Cf 1D174 Cf 1D175 Cf 1D176 Cf 1D177 Cf 1D178 Cf 1D179 Cf 1D17A Cf 1D17B Mn 1D17C Mn 1D17D Mn 1D17E Mn 1D17F Mn 1D180 Mn 1D181 Mn 1D182 Mn 1D183 So 1D184 So 1D185 Mn 1D186 Mn 1D187 Mn 1D188 Mn 1D189 Mn 1D18A Mn 1D18B Mn 1D18C So 1D18D So 1D18E So 1D18F So 1D190 So 1D191 So 1D192 So 1D193 So 1D194 So 1D195 So 1D196 So 1D197 So 1D198 So 1D199 So 1D19A So 1D19B So 1D19C So 1D19D So 1D19E So 1D19F So 1D1A0 So 1D1A1 So 1D1A2 So 1D1A3 So 1D1A4 So 1D1A5 So 1D1A6 So 1D1A7 So 1D1A8 So 1D1A9 So 1D1AA Mn 1D1AB Mn 1D1AC Mn 1D1AD Mn 1D1AE So 1D1AF So 1D1B0 So 1D1B1 So 1D1B2 So 1D1B3 So 1D1B4 So 1D1B5 So 1D1B6 So 1D1B7 So 1D1B8 So 1D1B9 So 1D1BA So 1D1BB So 1D1BC So 1D1BD So 1D1BE So 1D1BF So 1D1C0 So 1D1C1 So 1D1C2 So 1D1C3 So 1D1C4 So 1D1C5 So 1D1C6 So 1D1C7 So 1D1C8 So 1D1C9 So 1D1CA So 1D1CB So 1D1CC So 1D1CD So 1D1CE So 1D1CF So 1D1D0 So 1D1D1 So 1D1D2 So 1D1D3 So 1D1D4 So 1D1D5 So 1D1D6 So 1D1D7 So 1D1D8 So 1D1D9 So 1D1DA So 1D1DB So 1D1DC So 1D1DD So 1D400 Lu 1D401 Lu 1D402 Lu 1D403 Lu 1D404 Lu 1D405 Lu 1D406 Lu 1D407 Lu 1D408 Lu 1D409 Lu 1D40A Lu 1D40B Lu 1D40C Lu 1D40D Lu 1D40E Lu 1D40F Lu 1D410 Lu 1D411 Lu 1D412 Lu 1D413 Lu 1D414 Lu 1D415 Lu 1D416 Lu 1D417 Lu 1D418 Lu 1D419 Lu 1D41A Ll 1D41B Ll 1D41C Ll 1D41D Ll 1D41E Ll 1D41F Ll 1D420 Ll 1D421 Ll 1D422 Ll 1D423 Ll 1D424 Ll 1D425 Ll 1D426 Ll 1D427 Ll 1D428 Ll 1D429 Ll 1D42A Ll 1D42B Ll 1D42C Ll 1D42D Ll 1D42E Ll 1D42F Ll 1D430 Ll 1D431 Ll 1D432 Ll 1D433 Ll 1D434 Lu 1D435 Lu 1D436 Lu 1D437 Lu 1D438 Lu 1D439 Lu 1D43A Lu 1D43B Lu 1D43C Lu 1D43D Lu 1D43E Lu 1D43F Lu 1D440 Lu 1D441 Lu 1D442 Lu 1D443 Lu 1D444 Lu 1D445 Lu 1D446 Lu 1D447 Lu 1D448 Lu 1D449 Lu 1D44A Lu 1D44B Lu 1D44C Lu 1D44D Lu 1D44E Ll 1D44F Ll 1D450 Ll 1D451 Ll 1D452 Ll 1D453 Ll 1D454 Ll 1D456 Ll 1D457 Ll 1D458 Ll 1D459 Ll 1D45A Ll 1D45B Ll 1D45C Ll 1D45D Ll 1D45E Ll 1D45F Ll 1D460 Ll 1D461 Ll 1D462 Ll 1D463 Ll 1D464 Ll 1D465 Ll 1D466 Ll 1D467 Ll 1D468 Lu 1D469 Lu 1D46A Lu 1D46B Lu 1D46C Lu 1D46D Lu 1D46E Lu 1D46F Lu 1D470 Lu 1D471 Lu 1D472 Lu 1D473 Lu 1D474 Lu 1D475 Lu 1D476 Lu 1D477 Lu 1D478 Lu 1D479 Lu 1D47A Lu 1D47B Lu 1D47C Lu 1D47D Lu 1D47E Lu 1D47F Lu 1D480 Lu 1D481 Lu 1D482 Ll 1D483 Ll 1D484 Ll 1D485 Ll 1D486 Ll 1D487 Ll 1D488 Ll 1D489 Ll 1D48A Ll 1D48B Ll 1D48C Ll 1D48D Ll 1D48E Ll 1D48F Ll 1D490 Ll 1D491 Ll 1D492 Ll 1D493 Ll 1D494 Ll 1D495 Ll 1D496 Ll 1D497 Ll 1D498 Ll 1D499 Ll 1D49A Ll 1D49B Ll 1D49C Lu 1D49E Lu 1D49F Lu 1D4A2 Lu 1D4A5 Lu 1D4A6 Lu 1D4A9 Lu 1D4AA Lu 1D4AB Lu 1D4AC Lu 1D4AE Lu 1D4AF Lu 1D4B0 Lu 1D4B1 Lu 1D4B2 Lu 1D4B3 Lu 1D4B4 Lu 1D4B5 Lu 1D4B6 Ll 1D4B7 Ll 1D4B8 Ll 1D4B9 Ll 1D4BB Ll 1D4BD Ll 1D4BE Ll 1D4BF Ll 1D4C0 Ll 1D4C2 Ll 1D4C3 Ll 1D4C5 Ll 1D4C6 Ll 1D4C7 Ll 1D4C8 Ll 1D4C9 Ll 1D4CA Ll 1D4CB Ll 1D4CC Ll 1D4CD Ll 1D4CE Ll 1D4CF Ll 1D4D0 Lu 1D4D1 Lu 1D4D2 Lu 1D4D3 Lu 1D4D4 Lu 1D4D5 Lu 1D4D6 Lu 1D4D7 Lu 1D4D8 Lu 1D4D9 Lu 1D4DA Lu 1D4DB Lu 1D4DC Lu 1D4DD Lu 1D4DE Lu 1D4DF Lu 1D4E0 Lu 1D4E1 Lu 1D4E2 Lu 1D4E3 Lu 1D4E4 Lu 1D4E5 Lu 1D4E6 Lu 1D4E7 Lu 1D4E8 Lu 1D4E9 Lu 1D4EA Ll 1D4EB Ll 1D4EC Ll 1D4ED Ll 1D4EE Ll 1D4EF Ll 1D4F0 Ll 1D4F1 Ll 1D4F2 Ll 1D4F3 Ll 1D4F4 Ll 1D4F5 Ll 1D4F6 Ll 1D4F7 Ll 1D4F8 Ll 1D4F9 Ll 1D4FA Ll 1D4FB Ll 1D4FC Ll 1D4FD Ll 1D4FE Ll 1D4FF Ll 1D500 Ll 1D501 Ll 1D502 Ll 1D503 Ll 1D504 Lu 1D505 Lu 1D507 Lu 1D508 Lu 1D509 Lu 1D50A Lu 1D50D Lu 1D50E Lu 1D50F Lu 1D510 Lu 1D511 Lu 1D512 Lu 1D513 Lu 1D514 Lu 1D516 Lu 1D517 Lu 1D518 Lu 1D519 Lu 1D51A Lu 1D51B Lu 1D51C Lu 1D51E Ll 1D51F Ll 1D520 Ll 1D521 Ll 1D522 Ll 1D523 Ll 1D524 Ll 1D525 Ll 1D526 Ll 1D527 Ll 1D528 Ll 1D529 Ll 1D52A Ll 1D52B Ll 1D52C Ll 1D52D Ll 1D52E Ll 1D52F Ll 1D530 Ll 1D531 Ll 1D532 Ll 1D533 Ll 1D534 Ll 1D535 Ll 1D536 Ll 1D537 Ll 1D538 Lu 1D539 Lu 1D53B Lu 1D53C Lu 1D53D Lu 1D53E Lu 1D540 Lu 1D541 Lu 1D542 Lu 1D543 Lu 1D544 Lu 1D546 Lu 1D54A Lu 1D54B Lu 1D54C Lu 1D54D Lu 1D54E Lu 1D54F Lu 1D550 Lu 1D552 Ll 1D553 Ll 1D554 Ll 1D555 Ll 1D556 Ll 1D557 Ll 1D558 Ll 1D559 Ll 1D55A Ll 1D55B Ll 1D55C Ll 1D55D Ll 1D55E Ll 1D55F Ll 1D560 Ll 1D561 Ll 1D562 Ll 1D563 Ll 1D564 Ll 1D565 Ll 1D566 Ll 1D567 Ll 1D568 Ll 1D569 Ll 1D56A Ll 1D56B Ll 1D56C Lu 1D56D Lu 1D56E Lu 1D56F Lu 1D570 Lu 1D571 Lu 1D572 Lu 1D573 Lu 1D574 Lu 1D575 Lu 1D576 Lu 1D577 Lu 1D578 Lu 1D579 Lu 1D57A Lu 1D57B Lu 1D57C Lu 1D57D Lu 1D57E Lu 1D57F Lu 1D580 Lu 1D581 Lu 1D582 Lu 1D583 Lu 1D584 Lu 1D585 Lu 1D586 Ll 1D587 Ll 1D588 Ll 1D589 Ll 1D58A Ll 1D58B Ll 1D58C Ll 1D58D Ll 1D58E Ll 1D58F Ll 1D590 Ll 1D591 Ll 1D592 Ll 1D593 Ll 1D594 Ll 1D595 Ll 1D596 Ll 1D597 Ll 1D598 Ll 1D599 Ll 1D59A Ll 1D59B Ll 1D59C Ll 1D59D Ll 1D59E Ll 1D59F Ll 1D5A0 Lu 1D5A1 Lu 1D5A2 Lu 1D5A3 Lu 1D5A4 Lu 1D5A5 Lu 1D5A6 Lu 1D5A7 Lu 1D5A8 Lu 1D5A9 Lu 1D5AA Lu 1D5AB Lu 1D5AC Lu 1D5AD Lu 1D5AE Lu 1D5AF Lu 1D5B0 Lu 1D5B1 Lu 1D5B2 Lu 1D5B3 Lu 1D5B4 Lu 1D5B5 Lu 1D5B6 Lu 1D5B7 Lu 1D5B8 Lu 1D5B9 Lu 1D5BA Ll 1D5BB Ll 1D5BC Ll 1D5BD Ll 1D5BE Ll 1D5BF Ll 1D5C0 Ll 1D5C1 Ll 1D5C2 Ll 1D5C3 Ll 1D5C4 Ll 1D5C5 Ll 1D5C6 Ll 1D5C7 Ll 1D5C8 Ll 1D5C9 Ll 1D5CA Ll 1D5CB Ll 1D5CC Ll 1D5CD Ll 1D5CE Ll 1D5CF Ll 1D5D0 Ll 1D5D1 Ll 1D5D2 Ll 1D5D3 Ll 1D5D4 Lu 1D5D5 Lu 1D5D6 Lu 1D5D7 Lu 1D5D8 Lu 1D5D9 Lu 1D5DA Lu 1D5DB Lu 1D5DC Lu 1D5DD Lu 1D5DE Lu 1D5DF Lu 1D5E0 Lu 1D5E1 Lu 1D5E2 Lu 1D5E3 Lu 1D5E4 Lu 1D5E5 Lu 1D5E6 Lu 1D5E7 Lu 1D5E8 Lu 1D5E9 Lu 1D5EA Lu 1D5EB Lu 1D5EC Lu 1D5ED Lu 1D5EE Ll 1D5EF Ll 1D5F0 Ll 1D5F1 Ll 1D5F2 Ll 1D5F3 Ll 1D5F4 Ll 1D5F5 Ll 1D5F6 Ll 1D5F7 Ll 1D5F8 Ll 1D5F9 Ll 1D5FA Ll 1D5FB Ll 1D5FC Ll 1D5FD Ll 1D5FE Ll 1D5FF Ll 1D600 Ll 1D601 Ll 1D602 Ll 1D603 Ll 1D604 Ll 1D605 Ll 1D606 Ll 1D607 Ll 1D608 Lu 1D609 Lu 1D60A Lu 1D60B Lu 1D60C Lu 1D60D Lu 1D60E Lu 1D60F Lu 1D610 Lu 1D611 Lu 1D612 Lu 1D613 Lu 1D614 Lu 1D615 Lu 1D616 Lu 1D617 Lu 1D618 Lu 1D619 Lu 1D61A Lu 1D61B Lu 1D61C Lu 1D61D Lu 1D61E Lu 1D61F Lu 1D620 Lu 1D621 Lu 1D622 Ll 1D623 Ll 1D624 Ll 1D625 Ll 1D626 Ll 1D627 Ll 1D628 Ll 1D629 Ll 1D62A Ll 1D62B Ll 1D62C Ll 1D62D Ll 1D62E Ll 1D62F Ll 1D630 Ll 1D631 Ll 1D632 Ll 1D633 Ll 1D634 Ll 1D635 Ll 1D636 Ll 1D637 Ll 1D638 Ll 1D639 Ll 1D63A Ll 1D63B Ll 1D63C Lu 1D63D Lu 1D63E Lu 1D63F Lu 1D640 Lu 1D641 Lu 1D642 Lu 1D643 Lu 1D644 Lu 1D645 Lu 1D646 Lu 1D647 Lu 1D648 Lu 1D649 Lu 1D64A Lu 1D64B Lu 1D64C Lu 1D64D Lu 1D64E Lu 1D64F Lu 1D650 Lu 1D651 Lu 1D652 Lu 1D653 Lu 1D654 Lu 1D655 Lu 1D656 Ll 1D657 Ll 1D658 Ll 1D659 Ll 1D65A Ll 1D65B Ll 1D65C Ll 1D65D Ll 1D65E Ll 1D65F Ll 1D660 Ll 1D661 Ll 1D662 Ll 1D663 Ll 1D664 Ll 1D665 Ll 1D666 Ll 1D667 Ll 1D668 Ll 1D669 Ll 1D66A Ll 1D66B Ll 1D66C Ll 1D66D Ll 1D66E Ll 1D66F Ll 1D670 Lu 1D671 Lu 1D672 Lu 1D673 Lu 1D674 Lu 1D675 Lu 1D676 Lu 1D677 Lu 1D678 Lu 1D679 Lu 1D67A Lu 1D67B Lu 1D67C Lu 1D67D Lu 1D67E Lu 1D67F Lu 1D680 Lu 1D681 Lu 1D682 Lu 1D683 Lu 1D684 Lu 1D685 Lu 1D686 Lu 1D687 Lu 1D688 Lu 1D689 Lu 1D68A Ll 1D68B Ll 1D68C Ll 1D68D Ll 1D68E Ll 1D68F Ll 1D690 Ll 1D691 Ll 1D692 Ll 1D693 Ll 1D694 Ll 1D695 Ll 1D696 Ll 1D697 Ll 1D698 Ll 1D699 Ll 1D69A Ll 1D69B Ll 1D69C Ll 1D69D Ll 1D69E Ll 1D69F Ll 1D6A0 Ll 1D6A1 Ll 1D6A2 Ll 1D6A3 Ll 1D6A8 Lu 1D6A9 Lu 1D6AA Lu 1D6AB Lu 1D6AC Lu 1D6AD Lu 1D6AE Lu 1D6AF Lu 1D6B0 Lu 1D6B1 Lu 1D6B2 Lu 1D6B3 Lu 1D6B4 Lu 1D6B5 Lu 1D6B6 Lu 1D6B7 Lu 1D6B8 Lu 1D6B9 Lu 1D6BA Lu 1D6BB Lu 1D6BC Lu 1D6BD Lu 1D6BE Lu 1D6BF Lu 1D6C0 Lu 1D6C1 Sm 1D6C2 Ll 1D6C3 Ll 1D6C4 Ll 1D6C5 Ll 1D6C6 Ll 1D6C7 Ll 1D6C8 Ll 1D6C9 Ll 1D6CA Ll 1D6CB Ll 1D6CC Ll 1D6CD Ll 1D6CE Ll 1D6CF Ll 1D6D0 Ll 1D6D1 Ll 1D6D2 Ll 1D6D3 Ll 1D6D4 Ll 1D6D5 Ll 1D6D6 Ll 1D6D7 Ll 1D6D8 Ll 1D6D9 Ll 1D6DA Ll 1D6DB Sm 1D6DC Ll 1D6DD Ll 1D6DE Ll 1D6DF Ll 1D6E0 Ll 1D6E1 Ll 1D6E2 Lu 1D6E3 Lu 1D6E4 Lu 1D6E5 Lu 1D6E6 Lu 1D6E7 Lu 1D6E8 Lu 1D6E9 Lu 1D6EA Lu 1D6EB Lu 1D6EC Lu 1D6ED Lu 1D6EE Lu 1D6EF Lu 1D6F0 Lu 1D6F1 Lu 1D6F2 Lu 1D6F3 Lu 1D6F4 Lu 1D6F5 Lu 1D6F6 Lu 1D6F7 Lu 1D6F8 Lu 1D6F9 Lu 1D6FA Lu 1D6FB Sm 1D6FC Ll 1D6FD Ll 1D6FE Ll 1D6FF Ll 1D700 Ll 1D701 Ll 1D702 Ll 1D703 Ll 1D704 Ll 1D705 Ll 1D706 Ll 1D707 Ll 1D708 Ll 1D709 Ll 1D70A Ll 1D70B Ll 1D70C Ll 1D70D Ll 1D70E Ll 1D70F Ll 1D710 Ll 1D711 Ll 1D712 Ll 1D713 Ll 1D714 Ll 1D715 Sm 1D716 Ll 1D717 Ll 1D718 Ll 1D719 Ll 1D71A Ll 1D71B Ll 1D71C Lu 1D71D Lu 1D71E Lu 1D71F Lu 1D720 Lu 1D721 Lu 1D722 Lu 1D723 Lu 1D724 Lu 1D725 Lu 1D726 Lu 1D727 Lu 1D728 Lu 1D729 Lu 1D72A Lu 1D72B Lu 1D72C Lu 1D72D Lu 1D72E Lu 1D72F Lu 1D730 Lu 1D731 Lu 1D732 Lu 1D733 Lu 1D734 Lu 1D735 Sm 1D736 Ll 1D737 Ll 1D738 Ll 1D739 Ll 1D73A Ll 1D73B Ll 1D73C Ll 1D73D Ll 1D73E Ll 1D73F Ll 1D740 Ll 1D741 Ll 1D742 Ll 1D743 Ll 1D744 Ll 1D745 Ll 1D746 Ll 1D747 Ll 1D748 Ll 1D749 Ll 1D74A Ll 1D74B Ll 1D74C Ll 1D74D Ll 1D74E Ll 1D74F Sm 1D750 Ll 1D751 Ll 1D752 Ll 1D753 Ll 1D754 Ll 1D755 Ll 1D756 Lu 1D757 Lu 1D758 Lu 1D759 Lu 1D75A Lu 1D75B Lu 1D75C Lu 1D75D Lu 1D75E Lu 1D75F Lu 1D760 Lu 1D761 Lu 1D762 Lu 1D763 Lu 1D764 Lu 1D765 Lu 1D766 Lu 1D767 Lu 1D768 Lu 1D769 Lu 1D76A Lu 1D76B Lu 1D76C Lu 1D76D Lu 1D76E Lu 1D76F Sm 1D770 Ll 1D771 Ll 1D772 Ll 1D773 Ll 1D774 Ll 1D775 Ll 1D776 Ll 1D777 Ll 1D778 Ll 1D779 Ll 1D77A Ll 1D77B Ll 1D77C Ll 1D77D Ll 1D77E Ll 1D77F Ll 1D780 Ll 1D781 Ll 1D782 Ll 1D783 Ll 1D784 Ll 1D785 Ll 1D786 Ll 1D787 Ll 1D788 Ll 1D789 Sm 1D78A Ll 1D78B Ll 1D78C Ll 1D78D Ll 1D78E Ll 1D78F Ll 1D790 Lu 1D791 Lu 1D792 Lu 1D793 Lu 1D794 Lu 1D795 Lu 1D796 Lu 1D797 Lu 1D798 Lu 1D799 Lu 1D79A Lu 1D79B Lu 1D79C Lu 1D79D Lu 1D79E Lu 1D79F Lu 1D7A0 Lu 1D7A1 Lu 1D7A2 Lu 1D7A3 Lu 1D7A4 Lu 1D7A5 Lu 1D7A6 Lu 1D7A7 Lu 1D7A8 Lu 1D7A9 Sm 1D7AA Ll 1D7AB Ll 1D7AC Ll 1D7AD Ll 1D7AE Ll 1D7AF Ll 1D7B0 Ll 1D7B1 Ll 1D7B2 Ll 1D7B3 Ll 1D7B4 Ll 1D7B5 Ll 1D7B6 Ll 1D7B7 Ll 1D7B8 Ll 1D7B9 Ll 1D7BA Ll 1D7BB Ll 1D7BC Ll 1D7BD Ll 1D7BE Ll 1D7BF Ll 1D7C0 Ll 1D7C1 Ll 1D7C2 Ll 1D7C3 Sm 1D7C4 Ll 1D7C5 Ll 1D7C6 Ll 1D7C7 Ll 1D7C8 Ll 1D7C9 Ll 1D7CE Nd 1D7CF Nd 1D7D0 Nd 1D7D1 Nd 1D7D2 Nd 1D7D3 Nd 1D7D4 Nd 1D7D5 Nd 1D7D6 Nd 1D7D7 Nd 1D7D8 Nd 1D7D9 Nd 1D7DA Nd 1D7DB Nd 1D7DC Nd 1D7DD Nd 1D7DE Nd 1D7DF Nd 1D7E0 Nd 1D7E1 Nd 1D7E2 Nd 1D7E3 Nd 1D7E4 Nd 1D7E5 Nd 1D7E6 Nd 1D7E7 Nd 1D7E8 Nd 1D7E9 Nd 1D7EA Nd 1D7EB Nd 1D7EC Nd 1D7ED Nd 1D7EE Nd 1D7EF Nd 1D7F0 Nd 1D7F1 Nd 1D7F2 Nd 1D7F3 Nd 1D7F4 Nd 1D7F5 Nd 1D7F6 Nd 1D7F7 Nd 1D7F8 Nd 1D7F9 Nd 1D7FA Nd 1D7FB Nd 1D7FC Nd 1D7FD Nd 1D7FE Nd 1D7FF Nd 20000 Lo 2A6D6 Lo 2F800 Lo 2F801 Lo 2F802 Lo 2F803 Lo 2F804 Lo 2F805 Lo 2F806 Lo 2F807 Lo 2F808 Lo 2F809 Lo 2F80A Lo 2F80B Lo 2F80C Lo 2F80D Lo 2F80E Lo 2F80F Lo 2F810 Lo 2F811 Lo 2F812 Lo 2F813 Lo 2F814 Lo 2F815 Lo 2F816 Lo 2F817 Lo 2F818 Lo 2F819 Lo 2F81A Lo 2F81B Lo 2F81C Lo 2F81D Lo 2F81E Lo 2F81F Lo 2F820 Lo 2F821 Lo 2F822 Lo 2F823 Lo 2F824 Lo 2F825 Lo 2F826 Lo 2F827 Lo 2F828 Lo 2F829 Lo 2F82A Lo 2F82B Lo 2F82C Lo 2F82D Lo 2F82E Lo 2F82F Lo 2F830 Lo 2F831 Lo 2F832 Lo 2F833 Lo 2F834 Lo 2F835 Lo 2F836 Lo 2F837 Lo 2F838 Lo 2F839 Lo 2F83A Lo 2F83B Lo 2F83C Lo 2F83D Lo 2F83E Lo 2F83F Lo 2F840 Lo 2F841 Lo 2F842 Lo 2F843 Lo 2F844 Lo 2F845 Lo 2F846 Lo 2F847 Lo 2F848 Lo 2F849 Lo 2F84A Lo 2F84B Lo 2F84C Lo 2F84D Lo 2F84E Lo 2F84F Lo 2F850 Lo 2F851 Lo 2F852 Lo 2F853 Lo 2F854 Lo 2F855 Lo 2F856 Lo 2F857 Lo 2F858 Lo 2F859 Lo 2F85A Lo 2F85B Lo 2F85C Lo 2F85D Lo 2F85E Lo 2F85F Lo 2F860 Lo 2F861 Lo 2F862 Lo 2F863 Lo 2F864 Lo 2F865 Lo 2F866 Lo 2F867 Lo 2F868 Lo 2F869 Lo 2F86A Lo 2F86B Lo 2F86C Lo 2F86D Lo 2F86E Lo 2F86F Lo 2F870 Lo 2F871 Lo 2F872 Lo 2F873 Lo 2F874 Lo 2F875 Lo 2F876 Lo 2F877 Lo 2F878 Lo 2F879 Lo 2F87A Lo 2F87B Lo 2F87C Lo 2F87D Lo 2F87E Lo 2F87F Lo 2F880 Lo 2F881 Lo 2F882 Lo 2F883 Lo 2F884 Lo 2F885 Lo 2F886 Lo 2F887 Lo 2F888 Lo 2F889 Lo 2F88A Lo 2F88B Lo 2F88C Lo 2F88D Lo 2F88E Lo 2F88F Lo 2F890 Lo 2F891 Lo 2F892 Lo 2F893 Lo 2F894 Lo 2F895 Lo 2F896 Lo 2F897 Lo 2F898 Lo 2F899 Lo 2F89A Lo 2F89B Lo 2F89C Lo 2F89D Lo 2F89E Lo 2F89F Lo 2F8A0 Lo 2F8A1 Lo 2F8A2 Lo 2F8A3 Lo 2F8A4 Lo 2F8A5 Lo 2F8A6 Lo 2F8A7 Lo 2F8A8 Lo 2F8A9 Lo 2F8AA Lo 2F8AB Lo 2F8AC Lo 2F8AD Lo 2F8AE Lo 2F8AF Lo 2F8B0 Lo 2F8B1 Lo 2F8B2 Lo 2F8B3 Lo 2F8B4 Lo 2F8B5 Lo 2F8B6 Lo 2F8B7 Lo 2F8B8 Lo 2F8B9 Lo 2F8BA Lo 2F8BB Lo 2F8BC Lo 2F8BD Lo 2F8BE Lo 2F8BF Lo 2F8C0 Lo 2F8C1 Lo 2F8C2 Lo 2F8C3 Lo 2F8C4 Lo 2F8C5 Lo 2F8C6 Lo 2F8C7 Lo 2F8C8 Lo 2F8C9 Lo 2F8CA Lo 2F8CB Lo 2F8CC Lo 2F8CD Lo 2F8CE Lo 2F8CF Lo 2F8D0 Lo 2F8D1 Lo 2F8D2 Lo 2F8D3 Lo 2F8D4 Lo 2F8D5 Lo 2F8D6 Lo 2F8D7 Lo 2F8D8 Lo 2F8D9 Lo 2F8DA Lo 2F8DB Lo 2F8DC Lo 2F8DD Lo 2F8DE Lo 2F8DF Lo 2F8E0 Lo 2F8E1 Lo 2F8E2 Lo 2F8E3 Lo 2F8E4 Lo 2F8E5 Lo 2F8E6 Lo 2F8E7 Lo 2F8E8 Lo 2F8E9 Lo 2F8EA Lo 2F8EB Lo 2F8EC Lo 2F8ED Lo 2F8EE Lo 2F8EF Lo 2F8F0 Lo 2F8F1 Lo 2F8F2 Lo 2F8F3 Lo 2F8F4 Lo 2F8F5 Lo 2F8F6 Lo 2F8F7 Lo 2F8F8 Lo 2F8F9 Lo 2F8FA Lo 2F8FB Lo 2F8FC Lo 2F8FD Lo 2F8FE Lo 2F8FF Lo 2F900 Lo 2F901 Lo 2F902 Lo 2F903 Lo 2F904 Lo 2F905 Lo 2F906 Lo 2F907 Lo 2F908 Lo 2F909 Lo 2F90A Lo 2F90B Lo 2F90C Lo 2F90D Lo 2F90E Lo 2F90F Lo 2F910 Lo 2F911 Lo 2F912 Lo 2F913 Lo 2F914 Lo 2F915 Lo 2F916 Lo 2F917 Lo 2F918 Lo 2F919 Lo 2F91A Lo 2F91B Lo 2F91C Lo 2F91D Lo 2F91E Lo 2F91F Lo 2F920 Lo 2F921 Lo 2F922 Lo 2F923 Lo 2F924 Lo 2F925 Lo 2F926 Lo 2F927 Lo 2F928 Lo 2F929 Lo 2F92A Lo 2F92B Lo 2F92C Lo 2F92D Lo 2F92E Lo 2F92F Lo 2F930 Lo 2F931 Lo 2F932 Lo 2F933 Lo 2F934 Lo 2F935 Lo 2F936 Lo 2F937 Lo 2F938 Lo 2F939 Lo 2F93A Lo 2F93B Lo 2F93C Lo 2F93D Lo 2F93E Lo 2F93F Lo 2F940 Lo 2F941 Lo 2F942 Lo 2F943 Lo 2F944 Lo 2F945 Lo 2F946 Lo 2F947 Lo 2F948 Lo 2F949 Lo 2F94A Lo 2F94B Lo 2F94C Lo 2F94D Lo 2F94E Lo 2F94F Lo 2F950 Lo 2F951 Lo 2F952 Lo 2F953 Lo 2F954 Lo 2F955 Lo 2F956 Lo 2F957 Lo 2F958 Lo 2F959 Lo 2F95A Lo 2F95B Lo 2F95C Lo 2F95D Lo 2F95E Lo 2F95F Lo 2F960 Lo 2F961 Lo 2F962 Lo 2F963 Lo 2F964 Lo 2F965 Lo 2F966 Lo 2F967 Lo 2F968 Lo 2F969 Lo 2F96A Lo 2F96B Lo 2F96C Lo 2F96D Lo 2F96E Lo 2F96F Lo 2F970 Lo 2F971 Lo 2F972 Lo 2F973 Lo 2F974 Lo 2F975 Lo 2F976 Lo 2F977 Lo 2F978 Lo 2F979 Lo 2F97A Lo 2F97B Lo 2F97C Lo 2F97D Lo 2F97E Lo 2F97F Lo 2F980 Lo 2F981 Lo 2F982 Lo 2F983 Lo 2F984 Lo 2F985 Lo 2F986 Lo 2F987 Lo 2F988 Lo 2F989 Lo 2F98A Lo 2F98B Lo 2F98C Lo 2F98D Lo 2F98E Lo 2F98F Lo 2F990 Lo 2F991 Lo 2F992 Lo 2F993 Lo 2F994 Lo 2F995 Lo 2F996 Lo 2F997 Lo 2F998 Lo 2F999 Lo 2F99A Lo 2F99B Lo 2F99C Lo 2F99D Lo 2F99E Lo 2F99F Lo 2F9A0 Lo 2F9A1 Lo 2F9A2 Lo 2F9A3 Lo 2F9A4 Lo 2F9A5 Lo 2F9A6 Lo 2F9A7 Lo 2F9A8 Lo 2F9A9 Lo 2F9AA Lo 2F9AB Lo 2F9AC Lo 2F9AD Lo 2F9AE Lo 2F9AF Lo 2F9B0 Lo 2F9B1 Lo 2F9B2 Lo 2F9B3 Lo 2F9B4 Lo 2F9B5 Lo 2F9B6 Lo 2F9B7 Lo 2F9B8 Lo 2F9B9 Lo 2F9BA Lo 2F9BB Lo 2F9BC Lo 2F9BD Lo 2F9BE Lo 2F9BF Lo 2F9C0 Lo 2F9C1 Lo 2F9C2 Lo 2F9C3 Lo 2F9C4 Lo 2F9C5 Lo 2F9C6 Lo 2F9C7 Lo 2F9C8 Lo 2F9C9 Lo 2F9CA Lo 2F9CB Lo 2F9CC Lo 2F9CD Lo 2F9CE Lo 2F9CF Lo 2F9D0 Lo 2F9D1 Lo 2F9D2 Lo 2F9D3 Lo 2F9D4 Lo 2F9D5 Lo 2F9D6 Lo 2F9D7 Lo 2F9D8 Lo 2F9D9 Lo 2F9DA Lo 2F9DB Lo 2F9DC Lo 2F9DD Lo 2F9DE Lo 2F9DF Lo 2F9E0 Lo 2F9E1 Lo 2F9E2 Lo 2F9E3 Lo 2F9E4 Lo 2F9E5 Lo 2F9E6 Lo 2F9E7 Lo 2F9E8 Lo 2F9E9 Lo 2F9EA Lo 2F9EB Lo 2F9EC Lo 2F9ED Lo 2F9EE Lo 2F9EF Lo 2F9F0 Lo 2F9F1 Lo 2F9F2 Lo 2F9F3 Lo 2F9F4 Lo 2F9F5 Lo 2F9F6 Lo 2F9F7 Lo 2F9F8 Lo 2F9F9 Lo 2F9FA Lo 2F9FB Lo 2F9FC Lo 2F9FD Lo 2F9FE Lo 2F9FF Lo 2FA00 Lo 2FA01 Lo 2FA02 Lo 2FA03 Lo 2FA04 Lo 2FA05 Lo 2FA06 Lo 2FA07 Lo 2FA08 Lo 2FA09 Lo 2FA0A Lo 2FA0B Lo 2FA0C Lo 2FA0D Lo 2FA0E Lo 2FA0F Lo 2FA10 Lo 2FA11 Lo 2FA12 Lo 2FA13 Lo 2FA14 Lo 2FA15 Lo 2FA16 Lo 2FA17 Lo 2FA18 Lo 2FA19 Lo 2FA1A Lo 2FA1B Lo 2FA1C Lo 2FA1D Lo E0001 Cf E0020 Cf E0021 Cf E0022 Cf E0023 Cf E0024 Cf E0025 Cf E0026 Cf E0027 Cf E0028 Cf E0029 Cf E002A Cf E002B Cf E002C Cf E002D Cf E002E Cf E002F Cf E0030 Cf E0031 Cf E0032 Cf E0033 Cf E0034 Cf E0035 Cf E0036 Cf E0037 Cf E0038 Cf E0039 Cf E003A Cf E003B Cf E003C Cf E003D Cf E003E Cf E003F Cf E0040 Cf E0041 Cf E0042 Cf E0043 Cf E0044 Cf E0045 Cf E0046 Cf E0047 Cf E0048 Cf E0049 Cf E004A Cf E004B Cf E004C Cf E004D Cf E004E Cf E004F Cf E0050 Cf E0051 Cf E0052 Cf E0053 Cf E0054 Cf E0055 Cf E0056 Cf E0057 Cf E0058 Cf E0059 Cf E005A Cf E005B Cf E005C Cf E005D Cf E005E Cf E005F Cf E0060 Cf E0061 Cf E0062 Cf E0063 Cf E0064 Cf E0065 Cf E0066 Cf E0067 Cf E0068 Cf E0069 Cf E006A Cf E006B Cf E006C Cf E006D Cf E006E Cf E006F Cf E0070 Cf E0071 Cf E0072 Cf E0073 Cf E0074 Cf E0075 Cf E0076 Cf E0077 Cf E0078 Cf E0079 Cf E007A Cf E007B Cf E007C Cf E007D Cf E007E Cf E007F Cf F0000 Co FFFFD Co 100000 Co 10FFFD Co src/dk/000077500000000000000000000000001204272215500122435ustar00rootroot00000000000000src/dk/brics/000077500000000000000000000000001204272215500133455ustar00rootroot00000000000000src/dk/brics/automaton/000077500000000000000000000000001204272215500153545ustar00rootroot00000000000000src/dk/brics/automaton/Automaton.java000066400000000000000000000734661204272215500202060ustar00rootroot00000000000000/* * dk.brics.automaton * * Copyright (c) 2001-2011 Anders Moeller * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package dk.brics.automaton; import java.io.IOException; import java.io.InputStream; import java.io.InvalidClassException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.OptionalDataException; import java.io.OutputStream; import java.io.Serializable; import java.net.URL; import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashSet; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; /** * Finite-state automaton with regular expression operations. *

* Class invariants: *

*

* If the states or transitions are manipulated manually, the {@link #restoreInvariant()} * and {@link #setDeterministic(boolean)} methods should be used afterwards to restore * representation invariants that are assumed by the built-in automata operations. * * @author Anders Møller <amoeller@cs.au.dk> */ public class Automaton implements Serializable, Cloneable { static final long serialVersionUID = 10001; /** * Minimize using Huffman's O(n2) algorithm. * This is the standard text-book algorithm. * @see #setMinimization(int) */ public static final int MINIMIZE_HUFFMAN = 0; /** * Minimize using Brzozowski's O(2n) algorithm. * This algorithm uses the reverse-determinize-reverse-determinize trick, which has a bad * worst-case behavior but often works very well in practice * (even better than Hopcroft's!). * @see #setMinimization(int) */ public static final int MINIMIZE_BRZOZOWSKI = 1; /** * Minimize using Hopcroft's O(n log n) algorithm. * This is regarded as one of the most generally efficient algorithms that exist. * @see #setMinimization(int) */ public static final int MINIMIZE_HOPCROFT = 2; /** Selects minimization algorithm (default: MINIMIZE_HOPCROFT). */ static int minimization = MINIMIZE_HOPCROFT; /** Initial state of this automaton. */ State initial; /** If true, then this automaton is definitely deterministic (i.e., there are no choices for any run, but a run may crash). */ boolean deterministic; /** Extra data associated with this automaton. */ transient Object info; /** Hash code. Recomputed by {@link #minimize()}. */ int hash_code; /** Singleton string. Null if not applicable. */ String singleton; /** Minimize always flag. */ static boolean minimize_always = false; /** Selects whether operations may modify the input automata (default: false). */ static boolean allow_mutation = false; /** Caches the isDebug state. */ static Boolean is_debug = null; /** * Constructs a new automaton that accepts the empty language. * Using this constructor, automata can be constructed manually from * {@link State} and {@link Transition} objects. * @see #setInitialState(State) * @see State * @see Transition */ public Automaton() { initial = new State(); deterministic = true; singleton = null; } boolean isDebug() { if (is_debug == null) is_debug = Boolean.valueOf(System.getProperty("dk.brics.automaton.debug") != null); return is_debug.booleanValue(); } /** * Selects minimization algorithm (default: MINIMIZE_HOPCROFT). * @param algorithm minimization algorithm */ static public void setMinimization(int algorithm) { minimization = algorithm; } /** * Sets or resets minimize always flag. * If this flag is set, then {@link #minimize()} will automatically * be invoked after all operations that otherwise may produce non-minimal automata. * By default, the flag is not set. * @param flag if true, the flag is set */ static public void setMinimizeAlways(boolean flag) { minimize_always = flag; } /** * Sets or resets allow mutate flag. * If this flag is set, then all automata operations may modify automata given as input; * otherwise, operations will always leave input automata languages unmodified. * By default, the flag is not set. * @param flag if true, the flag is set * @return previous value of the flag */ static public boolean setAllowMutate(boolean flag) { boolean b = allow_mutation; allow_mutation = flag; return b; } /** * Returns the state of the allow mutate flag. * If this flag is set, then all automata operations may modify automata given as input; * otherwise, operations will always leave input automata languages unmodified. * By default, the flag is not set. * @return current value of the flag */ static boolean getAllowMutate() { return allow_mutation; } void checkMinimizeAlways() { if (minimize_always) minimize(); } boolean isSingleton() { return singleton!=null; } /** * Returns the singleton string for this automaton. * An automaton that accepts exactly one string may be represented * in singleton mode. In that case, this method may be used to obtain the string. * @return string, null if this automaton is not in singleton mode. */ public String getSingleton() { return singleton; } /** * Sets initial state. * @param s state */ public void setInitialState(State s) { initial = s; singleton = null; } /** * Gets initial state. * @return state */ public State getInitialState() { expandSingleton(); return initial; } /** * Returns deterministic flag for this automaton. * @return true if the automaton is definitely deterministic, false if the automaton * may be nondeterministic */ public boolean isDeterministic() { return deterministic; } /** * Sets deterministic flag for this automaton. * This method should (only) be used if automata are constructed manually. * @param deterministic true if the automaton is definitely deterministic, false if the automaton * may be nondeterministic */ public void setDeterministic(boolean deterministic) { this.deterministic = deterministic; } /** * Associates extra information with this automaton. * @param info extra information */ public void setInfo(Object info) { this.info = info; } /** * Returns extra information associated with this automaton. * @return extra information * @see #setInfo(Object) */ public Object getInfo() { return info; } /** * Returns the set of states that are reachable from the initial state. * @return set of {@link State} objects */ public Set getStates() { expandSingleton(); Set visited; if (isDebug()) visited = new LinkedHashSet(); else visited = new HashSet(); LinkedList worklist = new LinkedList(); worklist.add(initial); visited.add(initial); while (worklist.size() > 0) { State s = worklist.removeFirst(); Collection tr; if (isDebug()) tr = s.getSortedTransitions(false); else tr = s.transitions; for (Transition t : tr) if (!visited.contains(t.to)) { visited.add(t.to); worklist.add(t.to); } } return visited; } /** * Returns the set of reachable accept states. * @return set of {@link State} objects */ public Set getAcceptStates() { expandSingleton(); HashSet accepts = new HashSet(); HashSet visited = new HashSet(); LinkedList worklist = new LinkedList(); worklist.add(initial); visited.add(initial); while (worklist.size() > 0) { State s = worklist.removeFirst(); if (s.accept) accepts.add(s); for (Transition t : s.transitions) if (!visited.contains(t.to)) { visited.add(t.to); worklist.add(t.to); } } return accepts; } /** * Assigns consecutive numbers to the given states. */ static void setStateNumbers(Set states) { int number = 0; for (State s : states) s.number = number++; } /** * Adds transitions to explicit crash state to ensure that transition function is total. */ void totalize() { State s = new State(); s.transitions.add(new Transition(Character.MIN_VALUE, Character.MAX_VALUE, s)); for (State p : getStates()) { int maxi = Character.MIN_VALUE; for (Transition t : p.getSortedTransitions(false)) { if (t.min > maxi) p.transitions.add(new Transition((char)maxi, (char)(t.min - 1), s)); if (t.max + 1 > maxi) maxi = t.max + 1; } if (maxi <= Character.MAX_VALUE) p.transitions.add(new Transition((char)maxi, Character.MAX_VALUE, s)); } } /** * Restores representation invariant. * This method must be invoked before any built-in automata operation is performed * if automaton states or transitions are manipulated manually. * @see #setDeterministic(boolean) */ public void restoreInvariant() { removeDeadTransitions(); } /** * Reduces this automaton. * An automaton is "reduced" by combining overlapping and adjacent edge intervals with same destination. */ public void reduce() { if (isSingleton()) return; Set states = getStates(); setStateNumbers(states); for (State s : states) { List st = s.getSortedTransitions(true); s.resetTransitions(); State p = null; int min = -1, max = -1; for (Transition t : st) { if (p == t.to) { if (t.min <= max + 1) { if (t.max > max) max = t.max; } else { if (p != null) s.transitions.add(new Transition((char)min, (char)max, p)); min = t.min; max = t.max; } } else { if (p != null) s.transitions.add(new Transition((char)min, (char)max, p)); p = t.to; min = t.min; max = t.max; } } if (p != null) s.transitions.add(new Transition((char)min, (char)max, p)); } clearHashCode(); } /** * Returns sorted array of all interval start points. */ char[] getStartPoints() { Set pointset = new HashSet(); for (State s : getStates()) { pointset.add(Character.MIN_VALUE); for (Transition t : s.transitions) { pointset.add(t.min); if (t.max < Character.MAX_VALUE) pointset.add((char)(t.max + 1)); } } char[] points = new char[pointset.size()]; int n = 0; for (Character m : pointset) points[n++] = m; Arrays.sort(points); return points; } /** * Returns the set of live states. A state is "live" if an accept state is reachable from it. * @return set of {@link State} objects */ public Set getLiveStates() { expandSingleton(); return getLiveStates(getStates()); } private Set getLiveStates(Set states) { HashMap> map = new HashMap>(); for (State s : states) map.put(s, new HashSet()); for (State s : states) for (Transition t : s.transitions) map.get(t.to).add(s); Set live = new HashSet(getAcceptStates()); LinkedList worklist = new LinkedList(live); while (worklist.size() > 0) { State s = worklist.removeFirst(); for (State p : map.get(s)) if (!live.contains(p)) { live.add(p); worklist.add(p); } } return live; } /** * Removes transitions to dead states and calls {@link #reduce()} and {@link #clearHashCode()}. * (A state is "dead" if no accept state is reachable from it.) */ public void removeDeadTransitions() { clearHashCode(); if (isSingleton()) return; Set states = getStates(); Set live = getLiveStates(states); for (State s : states) { Set st = s.transitions; s.resetTransitions(); for (Transition t : st) if (live.contains(t.to)) s.transitions.add(t); } reduce(); } /** * Returns a sorted array of transitions for each state (and sets state numbers). */ static Transition[][] getSortedTransitions(Set states) { setStateNumbers(states); Transition[][] transitions = new Transition[states.size()][]; for (State s : states) transitions[s.number] = s.getSortedTransitionArray(false); return transitions; } /** * Expands singleton representation to normal representation. * Does nothing if not in singleton representation. */ public void expandSingleton() { if (isSingleton()) { State p = new State(); initial = p; for (int i = 0; i < singleton.length(); i++) { State q = new State(); p.transitions.add(new Transition(singleton.charAt(i), q)); p = q; } p.accept = true; deterministic = true; singleton = null; } } /** * Returns the number of states in this automaton. */ public int getNumberOfStates() { if (isSingleton()) return singleton.length() + 1; return getStates().size(); } /** * Returns the number of transitions in this automaton. This number is counted * as the total number of edges, where one edge may be a character interval. */ public int getNumberOfTransitions() { if (isSingleton()) return singleton.length(); int c = 0; for (State s : getStates()) c += s.transitions.size(); return c; } /** * Returns true if the language of this automaton is equal to the language * of the given automaton. Implemented using hashCode and * subsetOf. */ @Override public boolean equals(Object obj) { if (obj == this) return true; if (!(obj instanceof Automaton)) return false; Automaton a = (Automaton)obj; if (isSingleton() && a.isSingleton()) return singleton.equals(a.singleton); return hashCode() == a.hashCode() && subsetOf(a) && a.subsetOf(this); } /** * Returns hash code for this automaton. The hash code is based on the * number of states and transitions in the minimized automaton. * Invoking this method may involve minimizing the automaton. */ @Override public int hashCode() { if (hash_code == 0) minimize(); return hash_code; } /** * Recomputes the hash code. * The automaton must be minimal when this operation is performed. */ void recomputeHashCode() { hash_code = getNumberOfStates() * 3 + getNumberOfTransitions() * 2; if (hash_code == 0) hash_code = 1; } /** * Must be invoked when the stored hash code may no longer be valid. */ void clearHashCode() { hash_code = 0; } /** * Returns a string representation of this automaton. */ @Override public String toString() { StringBuilder b = new StringBuilder(); if (isSingleton()) { b.append("singleton: "); for (char c : singleton.toCharArray()) Transition.appendCharString(c, b); b.append("\n"); } else { Set states = getStates(); setStateNumbers(states); b.append("initial state: ").append(initial.number).append("\n"); for (State s : states) b.append(s.toString()); } return b.toString(); } /** * Returns Graphviz Dot * representation of this automaton. */ public String toDot() { StringBuilder b = new StringBuilder("digraph Automaton {\n"); b.append(" rankdir = LR;\n"); Set states = getStates(); setStateNumbers(states); for (State s : states) { b.append(" ").append(s.number); if (s.accept) b.append(" [shape=doublecircle,label=\"\"];\n"); else b.append(" [shape=circle,label=\"\"];\n"); if (s == initial) { b.append(" initial [shape=plaintext,label=\"\"];\n"); b.append(" initial -> ").append(s.number).append("\n"); } for (Transition t : s.transitions) { b.append(" ").append(s.number); t.appendDot(b); } } return b.append("}\n").toString(); } /** * Returns a clone of this automaton, expands if singleton. */ Automaton cloneExpanded() { Automaton a = clone(); a.expandSingleton(); return a; } /** * Returns a clone of this automaton unless allow_mutation is set, expands if singleton. */ Automaton cloneExpandedIfRequired() { if (allow_mutation) { expandSingleton(); return this; } else return cloneExpanded(); } /** * Returns a clone of this automaton. */ @Override public Automaton clone() { try { Automaton a = (Automaton)super.clone(); if (!isSingleton()) { HashMap m = new HashMap(); Set states = getStates(); for (State s : states) m.put(s, new State()); for (State s : states) { State p = m.get(s); p.accept = s.accept; if (s == initial) a.initial = p; for (Transition t : s.transitions) p.transitions.add(new Transition(t.min, t.max, m.get(t.to))); } } return a; } catch (CloneNotSupportedException e) { throw new RuntimeException(e); } } /** * Returns a clone of this automaton, or this automaton itself if allow_mutation flag is set. */ Automaton cloneIfRequired() { if (allow_mutation) return this; else return clone(); } /** * Retrieves a serialized Automaton located by a URL. * @param url URL of serialized automaton * @exception IOException if input/output related exception occurs * @exception OptionalDataException if the data is not a serialized object * @exception InvalidClassException if the class serial number does not match * @exception ClassCastException if the data is not a serialized Automaton * @exception ClassNotFoundException if the class of the serialized object cannot be found */ public static Automaton load(URL url) throws IOException, OptionalDataException, ClassCastException, ClassNotFoundException, InvalidClassException { return load(url.openStream()); } /** * Retrieves a serialized Automaton from a stream. * @param stream input stream with serialized automaton * @exception IOException if input/output related exception occurs * @exception OptionalDataException if the data is not a serialized object * @exception InvalidClassException if the class serial number does not match * @exception ClassCastException if the data is not a serialized Automaton * @exception ClassNotFoundException if the class of the serialized object cannot be found */ public static Automaton load(InputStream stream) throws IOException, OptionalDataException, ClassCastException, ClassNotFoundException, InvalidClassException { ObjectInputStream s = new ObjectInputStream(stream); return (Automaton)s.readObject(); } /** * Writes this Automaton to the given stream. * @param stream output stream for serialized automaton * @exception IOException if input/output related exception occurs */ public void store(OutputStream stream) throws IOException { ObjectOutputStream s = new ObjectOutputStream(stream); s.writeObject(this); s.flush(); } /** * See {@link BasicAutomata#makeEmpty()}. */ public static Automaton makeEmpty() { return BasicAutomata.makeEmpty(); } /** * See {@link BasicAutomata#makeEmptyString()}. */ public static Automaton makeEmptyString() { return BasicAutomata.makeEmptyString(); } /** * See {@link BasicAutomata#makeAnyString()}. */ public static Automaton makeAnyString() { return BasicAutomata.makeAnyString(); } /** * See {@link BasicAutomata#makeAnyChar()}. */ public static Automaton makeAnyChar() { return BasicAutomata.makeAnyChar(); } /** * See {@link BasicAutomata#makeChar(char)}. */ public static Automaton makeChar(char c) { return BasicAutomata.makeChar(c); } /** * See {@link BasicAutomata#makeCharRange(char, char)}. */ public static Automaton makeCharRange(char min, char max) { return BasicAutomata.makeCharRange(min, max); } /** * See {@link BasicAutomata#makeCharSet(String)}. */ public static Automaton makeCharSet(String set) { return BasicAutomata.makeCharSet(set); } /** * See {@link BasicAutomata#makeInterval(int, int, int)}. */ public static Automaton makeInterval(int min, int max, int digits) throws IllegalArgumentException { return BasicAutomata.makeInterval(min, max, digits); } /** * See {@link BasicAutomata#makeString(String)}. */ public static Automaton makeString(String s) { return BasicAutomata.makeString(s); } /** * See {@link BasicAutomata#makeStringUnion(CharSequence...)}. */ public static Automaton makeStringUnion(CharSequence... strings) { return BasicAutomata.makeStringUnion(strings); } /** * See {@link BasicAutomata#makeMaxInteger(String)}. */ public static Automaton makeMaxInteger(String n) { return BasicAutomata.makeMaxInteger(n); } /** * See {@link BasicAutomata#makeMinInteger(String)}. */ public static Automaton makeMinInteger(String n) { return BasicAutomata.makeMinInteger(n); } /** * See {@link BasicAutomata#makeTotalDigits(int)}. */ public static Automaton makeTotalDigits(int i) { return BasicAutomata.makeTotalDigits(i); } /** * See {@link BasicAutomata#makeFractionDigits(int)}. */ public static Automaton makeFractionDigits(int i) { return BasicAutomata.makeFractionDigits(i); } /** * See {@link BasicAutomata#makeIntegerValue(String)}. */ public static Automaton makeIntegerValue(String value) { return BasicAutomata.makeIntegerValue(value); } /** * See {@link BasicAutomata#makeDecimalValue(String)}. */ public static Automaton makeDecimalValue(String value) { return BasicAutomata.makeDecimalValue(value); } /** * See {@link BasicAutomata#makeStringMatcher(String)}. */ public static Automaton makeStringMatcher(String s) { return BasicAutomata.makeStringMatcher(s); } /** * See {@link BasicOperations#concatenate(Automaton, Automaton)}. */ public Automaton concatenate(Automaton a) { return BasicOperations.concatenate(this, a); } /** * See {@link BasicOperations#concatenate(List)}. */ static public Automaton concatenate(List l) { return BasicOperations.concatenate(l); } /** * See {@link BasicOperations#optional(Automaton)}. */ public Automaton optional() { return BasicOperations.optional(this); } /** * See {@link BasicOperations#repeat(Automaton)}. */ public Automaton repeat() { return BasicOperations.repeat(this); } /** * See {@link BasicOperations#repeat(Automaton, int)}. */ public Automaton repeat(int min) { return BasicOperations.repeat(this, min); } /** * See {@link BasicOperations#repeat(Automaton, int, int)}. */ public Automaton repeat(int min, int max) { return BasicOperations.repeat(this, min, max); } /** * See {@link BasicOperations#complement(Automaton)}. */ public Automaton complement() { return BasicOperations.complement(this); } /** * See {@link BasicOperations#minus(Automaton, Automaton)}. */ public Automaton minus(Automaton a) { return BasicOperations.minus(this, a); } /** * See {@link BasicOperations#intersection(Automaton, Automaton)}. */ public Automaton intersection(Automaton a) { return BasicOperations.intersection(this, a); } /** * See {@link BasicOperations#subsetOf(Automaton, Automaton)}. */ public boolean subsetOf(Automaton a) { return BasicOperations.subsetOf(this, a); } /** * See {@link BasicOperations#union(Automaton, Automaton)}. */ public Automaton union(Automaton a) { return BasicOperations.union(this, a); } /** * See {@link BasicOperations#union(Collection)}. */ static public Automaton union(Collection l) { return BasicOperations.union(l); } /** * See {@link BasicOperations#determinize(Automaton)}. */ public void determinize() { BasicOperations.determinize(this); } /** * See {@link BasicOperations#addEpsilons(Automaton, Collection)}. */ public void addEpsilons(Collection pairs) { BasicOperations.addEpsilons(this, pairs); } /** * See {@link BasicOperations#isEmptyString(Automaton)}. */ public boolean isEmptyString() { return BasicOperations.isEmptyString(this); } /** * See {@link BasicOperations#isEmpty(Automaton)}. */ public boolean isEmpty() { return BasicOperations.isEmpty(this); } /** * See {@link BasicOperations#isTotal(Automaton)}. */ public boolean isTotal() { return BasicOperations.isTotal(this); } /** * See {@link BasicOperations#getShortestExample(Automaton, boolean)}. */ public String getShortestExample(boolean accepted) { return BasicOperations.getShortestExample(this, accepted); } /** * See {@link BasicOperations#run(Automaton, String)}. */ public boolean run(String s) { return BasicOperations.run(this, s); } /** * See {@link MinimizationOperations#minimize(Automaton)}. */ public void minimize() { MinimizationOperations.minimize(this); } /** * See {@link MinimizationOperations#minimize(Automaton)}. * Returns the automaton being given as argument. */ public static Automaton minimize(Automaton a) { a.minimize(); return a; } /** * See {@link SpecialOperations#overlap(Automaton, Automaton)}. */ public Automaton overlap(Automaton a) { return SpecialOperations.overlap(this, a); } /** * See {@link SpecialOperations#singleChars(Automaton)}. */ public Automaton singleChars() { return SpecialOperations.singleChars(this); } /** * See {@link SpecialOperations#trim(Automaton, String, char)}. */ public Automaton trim(String set, char c) { return SpecialOperations.trim(this, set, c); } /** * See {@link SpecialOperations#compress(Automaton, String, char)}. */ public Automaton compress(String set, char c) { return SpecialOperations.compress(this, set, c); } /** * See {@link SpecialOperations#subst(Automaton, Map)}. */ public Automaton subst(Map> map) { return SpecialOperations.subst(this, map); } /** * See {@link SpecialOperations#subst(Automaton, char, String)}. */ public Automaton subst(char c, String s) { return SpecialOperations.subst(this, c, s); } /** * See {@link SpecialOperations#homomorph(Automaton, char[], char[])}. */ public Automaton homomorph(char[] source, char[] dest) { return SpecialOperations.homomorph(this, source, dest); } /** * See {@link SpecialOperations#projectChars(Automaton, Set)}. */ public Automaton projectChars(Set chars) { return SpecialOperations.projectChars(this, chars); } /** * See {@link SpecialOperations#isFinite(Automaton)}. */ public boolean isFinite() { return SpecialOperations.isFinite(this); } /** * See {@link SpecialOperations#getStrings(Automaton, int)}. */ public Set getStrings(int length) { return SpecialOperations.getStrings(this, length); } /** * See {@link SpecialOperations#getFiniteStrings(Automaton)}. */ public Set getFiniteStrings() { return SpecialOperations.getFiniteStrings(this); } /** * See {@link SpecialOperations#getFiniteStrings(Automaton, int)}. */ public Set getFiniteStrings(int limit) { return SpecialOperations.getFiniteStrings(this, limit); } /** * See {@link SpecialOperations#getCommonPrefix(Automaton)}. */ public String getCommonPrefix() { return SpecialOperations.getCommonPrefix(this); } /** * See {@link SpecialOperations#prefixClose(Automaton)}. */ public void prefixClose() { SpecialOperations.prefixClose(this); } /** * See {@link SpecialOperations#hexCases(Automaton)}. */ public static Automaton hexCases(Automaton a) { return SpecialOperations.hexCases(a); } /** * See {@link SpecialOperations#replaceWhitespace(Automaton)}. */ public static Automaton replaceWhitespace(Automaton a) { return SpecialOperations.replaceWhitespace(a); } /** * See {@link ShuffleOperations#shuffleSubsetOf(Collection, Automaton, Character, Character)}. */ public static String shuffleSubsetOf(Collection ca, Automaton a, Character suspend_shuffle, Character resume_shuffle) { return ShuffleOperations.shuffleSubsetOf(ca, a, suspend_shuffle, resume_shuffle); } /** * See {@link ShuffleOperations#shuffle(Automaton, Automaton)}. */ public Automaton shuffle(Automaton a) { return ShuffleOperations.shuffle(this, a); } } src/dk/brics/automaton/AutomatonMatcher.java000066400000000000000000000214301204272215500214720ustar00rootroot00000000000000/* * dk.brics.automaton - AutomatonMatcher * * Copyright (c) 2008-2011 John Gibson * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package dk.brics.automaton; import java.util.regex.MatchResult; /** * A tool that performs match operations on a given character sequence using * a compiled automaton. * * @author John Gibson <jgibson@mitre.org> * @see RunAutomaton#newMatcher(java.lang.CharSequence) * @see RunAutomaton#newMatcher(java.lang.CharSequence, int, int) */ public class AutomatonMatcher implements MatchResult { AutomatonMatcher(final CharSequence chars, final RunAutomaton automaton) { this.chars = chars; this.automaton = automaton; } private final RunAutomaton automaton; private final CharSequence chars; private int matchStart = -1; private int matchEnd = -1; /** * Find the next matching subsequence of the input. *
* This also updates the values for the {@code start}, {@code end}, and * {@code group} methods. * * @return {@code true} if there is a matching subsequence. */ public boolean find() { int begin; switch(getMatchStart()) { case -2: return false; case -1: begin = 0; break; default: begin = getMatchEnd(); // This occurs when a previous find() call matched the empty string. This can happen when the pattern is a* for example. if(begin == getMatchStart()) { begin += 1; if(begin > getChars().length()) { setMatch(-2, -2); return false; } } } int match_start; int match_end; if (automaton.isAccept(automaton.getInitialState())) { match_start = begin; match_end = begin; } else { match_start = -1; match_end = -1; } int l = getChars().length(); while (begin < l) { int p = automaton.getInitialState(); for (int i = begin; i < l; i++) { final int new_state = automaton.step(p, getChars().charAt(i)); if (new_state == -1) { break; } else if (automaton.isAccept(new_state)) { // found a match from begin to (i+1) match_start = begin; match_end=(i+1); } p = new_state; } if (match_start != -1) { setMatch(match_start, match_end); return true; } begin += 1; } if (match_start != -1) { setMatch(match_start, match_end); return true; } else { setMatch(-2, -2); return false; } } private void setMatch(final int matchStart, final int matchEnd) throws IllegalArgumentException { if (matchStart > matchEnd) { throw new IllegalArgumentException("Start must be less than or equal to end: " + matchStart + ", " + matchEnd); } this.matchStart = matchStart; this.matchEnd = matchEnd; } private int getMatchStart() { return matchStart; } private int getMatchEnd() { return matchEnd; } private CharSequence getChars() { return chars; } /** * Returns the offset after the last character matched. * * @return The offset after the last character matched. * @throws IllegalStateException if there has not been a match attempt or * if the last attempt yielded no results. */ public int end() throws IllegalStateException { matchGood(); return matchEnd; } /** * Returns the offset after the last character matched of the specified * capturing group. *
* Note that because the automaton does not support capturing groups the * only valid group is 0 (the entire match). * * @param group the desired capturing group. * @return The offset after the last character matched of the specified * capturing group. * @throws IllegalStateException if there has not been a match attempt or * if the last attempt yielded no results. * @throws IndexOutOfBoundsException if the specified capturing group does * not exist in the underlying automaton. */ public int end(final int group) throws IndexOutOfBoundsException, IllegalStateException { onlyZero(group); return end(); } /** * Returns the subsequence of the input found by the previous match. * * @return The subsequence of the input found by the previous match. * @throws IllegalStateException if there has not been a match attempt or * if the last attempt yielded no results. */ public String group() throws IllegalStateException { matchGood(); return chars.subSequence(matchStart, matchEnd).toString(); } /** * Returns the subsequence of the input found by the specified capturing * group during the previous match operation. *
* Note that because the automaton does not support capturing groups the * only valid group is 0 (the entire match). * * @param group the desired capturing group. * @return The subsequence of the input found by the specified capturing * group during the previous match operation the previous match. Or * {@code null} if the given group did match. * @throws IllegalStateException if there has not been a match attempt or * if the last attempt yielded no results. * @throws IndexOutOfBoundsException if the specified capturing group does * not exist in the underlying automaton. */ public String group(final int group) throws IndexOutOfBoundsException, IllegalStateException { onlyZero(group); return group(); } /** * Returns the number of capturing groups in the underlying automaton. *
* Note that because the automaton does not support capturing groups this * method will always return 0. * * @return The number of capturing groups in the underlying automaton. */ public int groupCount() { return 0; } /** * Returns the offset of the first character matched. * * @return The offset of the first character matched. * @throws IllegalStateException if there has not been a match attempt or * if the last attempt yielded no results. */ public int start() throws IllegalStateException { matchGood(); return matchStart; } /** * Returns the offset of the first character matched of the specified * capturing group. *
* Note that because the automaton does not support capturing groups the * only valid group is 0 (the entire match). * * @param group the desired capturing group. * @return The offset of the first character matched of the specified * capturing group. * @throws IllegalStateException if there has not been a match attempt or * if the last attempt yielded no results. * @throws IndexOutOfBoundsException if the specified capturing group does * not exist in the underlying automaton. */ public int start(int group) throws IndexOutOfBoundsException, IllegalStateException { onlyZero(group); return start(); } /** * Returns the current state of this {@code AutomatonMatcher} as a * {@code MatchResult}. * The result is unaffected by subsequent operations on this object. * * @return a {@code MatchResult} with the state of this * {@code AutomatonMatcher}. */ public MatchResult toMatchResult() { final AutomatonMatcher match = new AutomatonMatcher(chars, automaton); match.matchStart = this.matchStart; match.matchEnd = this.matchEnd; return match; } /** Helper method that requires the group argument to be 0. */ private static void onlyZero(final int group) throws IndexOutOfBoundsException { if (group != 0) { throw new IndexOutOfBoundsException("The only group supported is 0."); } } /** Helper method to check that the last match attempt was valid. */ private void matchGood() throws IllegalStateException { if ((matchStart < 0) || (matchEnd < 0)) { throw new IllegalStateException("There was no available match."); } } } src/dk/brics/automaton/AutomatonProvider.java000066400000000000000000000035671204272215500217140ustar00rootroot00000000000000/* * dk.brics.automaton * * Copyright (c) 2001-2011 Anders Moeller * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package dk.brics.automaton; import java.io.IOException; /** * Automaton provider for RegExp.{@link RegExp#toAutomaton(AutomatonProvider)} */ public interface AutomatonProvider { /** * Returns automaton of the given name. * @param name automaton name * @return automaton * @throws IOException if errors occur */ public Automaton getAutomaton(String name) throws IOException; } src/dk/brics/automaton/BasicAutomata.java000066400000000000000000000362461204272215500207470ustar00rootroot00000000000000/* * dk.brics.automaton * * Copyright (c) 2001-2011 Anders Moeller * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package dk.brics.automaton; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.HashSet; import java.util.Set; /** * Construction of basic automata. */ final public class BasicAutomata { private BasicAutomata() {} /** * Returns a new (deterministic) automaton with the empty language. */ public static Automaton makeEmpty() { Automaton a = new Automaton(); State s = new State(); a.initial = s; a.deterministic = true; return a; } /** * Returns a new (deterministic) automaton that accepts only the empty string. */ public static Automaton makeEmptyString() { Automaton a = new Automaton(); a.singleton = ""; a.deterministic = true; return a; } /** * Returns a new (deterministic) automaton that accepts all strings. */ public static Automaton makeAnyString() { Automaton a = new Automaton(); State s = new State(); a.initial = s; s.accept = true; s.transitions.add(new Transition(Character.MIN_VALUE, Character.MAX_VALUE, s)); a.deterministic = true; return a; } /** * Returns a new (deterministic) automaton that accepts any single character. */ public static Automaton makeAnyChar() { return makeCharRange(Character.MIN_VALUE, Character.MAX_VALUE); } /** * Returns a new (deterministic) automaton that accepts a single character of the given value. */ public static Automaton makeChar(char c) { Automaton a = new Automaton(); a.singleton = Character.toString(c); a.deterministic = true; return a; } /** * Returns a new (deterministic) automaton that accepts a single char * whose value is in the given interval (including both end points). */ public static Automaton makeCharRange(char min, char max) { if (min == max) return makeChar(min); Automaton a = new Automaton(); State s1 = new State(); State s2 = new State(); a.initial = s1; s2.accept = true; if (min <= max) s1.transitions.add(new Transition(min, max, s2)); a.deterministic = true; return a; } /** * Returns a new (deterministic) automaton that accepts a single character in the given set. */ public static Automaton makeCharSet(String set) { if (set.length() == 1) return makeChar(set.charAt(0)); Automaton a = new Automaton(); State s1 = new State(); State s2 = new State(); a.initial = s1; s2.accept = true; for (int i = 0; i < set.length(); i++) s1.transitions.add(new Transition(set.charAt(i), s2)); a.deterministic = true; a.reduce(); return a; } /** * Constructs sub-automaton corresponding to decimal numbers of * length x.substring(n).length(). */ private static State anyOfRightLength(String x, int n) { State s = new State(); if (x.length() == n) s.setAccept(true); else s.addTransition(new Transition('0', '9', anyOfRightLength(x, n + 1))); return s; } /** * Constructs sub-automaton corresponding to decimal numbers of value * at least x.substring(n) and length x.substring(n).length(). */ private static State atLeast(String x, int n, Collection initials, boolean zeros) { State s = new State(); if (x.length() == n) s.setAccept(true); else { if (zeros) initials.add(s); char c = x.charAt(n); s.addTransition(new Transition(c, atLeast(x, n + 1, initials, zeros && c == '0'))); if (c < '9') s.addTransition(new Transition((char)(c + 1), '9', anyOfRightLength(x, n + 1))); } return s; } /** * Constructs sub-automaton corresponding to decimal numbers of value * at most x.substring(n) and length x.substring(n).length(). */ private static State atMost(String x, int n) { State s = new State(); if (x.length() == n) s.setAccept(true); else { char c = x.charAt(n); s.addTransition(new Transition(c, atMost(x, (char)n + 1))); if (c > '0') s.addTransition(new Transition('0', (char)(c - 1), anyOfRightLength(x, n + 1))); } return s; } /** * Constructs sub-automaton corresponding to decimal numbers of value * between x.substring(n) and y.substring(n) and of * length x.substring(n).length() (which must be equal to y.substring(n).length()). */ private static State between(String x, String y, int n, Collection initials, boolean zeros) { State s = new State(); if (x.length() == n) s.setAccept(true); else { if (zeros) initials.add(s); char cx = x.charAt(n); char cy = y.charAt(n); if (cx == cy) s.addTransition(new Transition(cx, between(x, y, n + 1, initials, zeros && cx == '0'))); else { // cx0, use fixed number of digits (strings must be prefixed * by 0's to obtain the right length) - * otherwise, the number of digits is not fixed * @exception IllegalArgumentException if min>max or if numbers in the interval cannot be expressed * with the given fixed number of digits */ public static Automaton makeInterval(int min, int max, int digits) throws IllegalArgumentException { Automaton a = new Automaton(); String x = Integer.toString(min); String y = Integer.toString(max); if (min > max || (digits > 0 && y.length() > digits)) throw new IllegalArgumentException(); int d; if (digits > 0) d = digits; else d = y.length(); StringBuilder bx = new StringBuilder(); for (int i = x.length(); i < d; i++) bx.append('0'); bx.append(x); x = bx.toString(); StringBuilder by = new StringBuilder(); for (int i = y.length(); i < d; i++) by.append('0'); by.append(y); y = by.toString(); Collection initials = new ArrayList(); a.initial = between(x, y, 0, initials, digits <= 0); if (digits <= 0) { ArrayList pairs = new ArrayList(); for (State p : initials) if (a.initial != p) pairs.add(new StatePair(a.initial, p)); a.addEpsilons(pairs); a.initial.addTransition(new Transition('0', a.initial)); a.deterministic = false; } else a.deterministic = true; a.checkMinimizeAlways(); return a; } /** * Returns a new (deterministic) automaton that accepts the single given string. */ public static Automaton makeString(String s) { Automaton a = new Automaton(); a.singleton = s; a.deterministic = true; return a; } /** * Returns a new (deterministic and minimal) automaton that accepts the union of the * given set of strings. The input character sequences are internally sorted in-place, * so the input array is modified. * @see StringUnionOperations */ public static Automaton makeStringUnion(CharSequence... strings) { if (strings.length == 0) return makeEmpty(); Arrays.sort(strings, StringUnionOperations.LEXICOGRAPHIC_ORDER); Automaton a = new Automaton(); a.setInitialState(StringUnionOperations.build(strings)); a.setDeterministic(true); a.reduce(); a.recomputeHashCode(); return a; } /** * Constructs automaton that accept strings representing nonnegative integers * that are not larger than the given value. * @param n string representation of maximum value */ public static Automaton makeMaxInteger(String n) { int i = 0; while (i < n.length() && n.charAt(i) == '0') i++; StringBuilder b = new StringBuilder(); b.append("0*(0|"); if (i < n.length()) b.append("[0-9]{1," + (n.length() - i - 1) + "}|"); maxInteger(n.substring(i), 0, b); b.append(")"); return Automaton.minimize((new RegExp(b.toString())).toAutomaton()); } private static void maxInteger(String n, int i, StringBuilder b) { b.append('('); if (i < n.length()) { char c = n.charAt(i); if (c != '0') b.append("[0-" + (char)(c-1) + "][0-9]{" + (n.length() - i - 1) + "}|"); b.append(c); maxInteger(n, i + 1, b); } b.append(')'); } /** * Constructs automaton that accept strings representing nonnegative integers * that are not less that the given value. * @param n string representation of minimum value */ public static Automaton makeMinInteger(String n) { int i = 0; while (i + 1 < n.length() && n.charAt(i) == '0') i++; StringBuilder b = new StringBuilder(); b.append("0*"); minInteger(n.substring(i), 0, b); b.append("[0-9]*"); return Automaton.minimize((new RegExp(b.toString())).toAutomaton()); } private static void minInteger(String n, int i, StringBuilder b) { b.append('('); if (i < n.length()) { char c = n.charAt(i); if (c != '9') b.append("[" + (char)(c+1) + "-9][0-9]{" + (n.length() - i - 1) + "}|"); b.append(c); minInteger(n, i + 1, b); } b.append(')'); } /** * Constructs automaton that accept strings representing decimal numbers * that can be written with at most the given number of digits. * Surrounding whitespace is permitted. * @param i max number of necessary digits */ public static Automaton makeTotalDigits(int i) { return Automaton.minimize((new RegExp("[ \t\n\r]*[-+]?0*([0-9]{0," + i + "}|((([0-9]\\.*){0," + i + "})&@\\.@)0*)[ \t\n\r]*")).toAutomaton()); } /** * Constructs automaton that accept strings representing decimal numbers * that can be written with at most the given number of digits in the fraction part. * Surrounding whitespace is permitted. * @param i max number of necessary fraction digits */ public static Automaton makeFractionDigits(int i) { return Automaton.minimize((new RegExp("[ \t\n\r]*[-+]?[0-9]+(\\.[0-9]{0," + i + "}0*)?[ \t\n\r]*")).toAutomaton()); } /** * Constructs automaton that accept strings representing the given integer. * Surrounding whitespace is permitted. * @param value string representation of integer */ public static Automaton makeIntegerValue(String value) { boolean minus = false; int i = 0; while (i < value.length()) { char c = value.charAt(i); if (c == '-') minus = true; if (c >= '1' && c <= '9') break; i++; } StringBuilder b = new StringBuilder(); b.append(value.substring(i)); if (b.length() == 0) b.append("0"); Automaton s; if (minus) s = Automaton.makeChar('-'); else s = Automaton.makeChar('+').optional(); Automaton ws = Datatypes.getWhitespaceAutomaton(); return Automaton.minimize(ws.concatenate(s.concatenate(Automaton.makeChar('0').repeat()).concatenate(Automaton.makeString(b.toString()))).concatenate(ws)); } /** * Constructs automaton that accept strings representing the given decimal number. * Surrounding whitespace is permitted. * @param value string representation of decimal number */ public static Automaton makeDecimalValue(String value) { boolean minus = false; int i = 0; while (i < value.length()) { char c = value.charAt(i); if (c == '-') minus = true; if ((c >= '1' && c <= '9') || c == '.') break; i++; } StringBuilder b1 = new StringBuilder(); StringBuilder b2 = new StringBuilder(); int p = value.indexOf('.', i); if (p == -1) b1.append(value.substring(i)); else { b1.append(value.substring(i, p)); i = value.length() - 1; while (i > p) { char c = value.charAt(i); if (c >= '1' && c <= '9') break; i--; } b2.append(value.substring(p + 1, i + 1)); } if (b1.length() == 0) b1.append("0"); Automaton s; if (minus) s = Automaton.makeChar('-'); else s = Automaton.makeChar('+').optional(); Automaton d; if (b2.length() == 0) d = Automaton.makeChar('.').concatenate(Automaton.makeChar('0').repeat(1)).optional(); else d = Automaton.makeChar('.').concatenate(Automaton.makeString(b2.toString())).concatenate(Automaton.makeChar('0').repeat()); Automaton ws = Datatypes.getWhitespaceAutomaton(); return Automaton.minimize(ws.concatenate(s.concatenate(Automaton.makeChar('0').repeat()).concatenate(Automaton.makeString(b1.toString())).concatenate(d)).concatenate(ws)); } /** * Constructs deterministic automaton that matches strings that contain the given substring. */ public static Automaton makeStringMatcher(String s) { Automaton a = new Automaton(); State[] states = new State[s.length() + 1]; states[0] = a.initial; for (int i = 0; i < s.length(); i++) states[i+1] = new State(); State f = states[s.length()]; f.accept = true; f.transitions.add(new Transition(Character.MIN_VALUE, Character.MAX_VALUE, f)); for (int i = 0; i < s.length(); i++) { Set done = new HashSet(); char c = s.charAt(i); states[i].transitions.add(new Transition(c, states[i+1])); done.add(c); for (int j = i; j >= 1; j--) { char d = s.charAt(j-1); if (!done.contains(d) && s.substring(0, j-1).equals(s.substring(i-j+1, i))) { states[i].transitions.add(new Transition(d, states[j])); done.add(d); } } char[] da = new char[done.size()]; int h = 0; for (char w : done) da[h++] = w; Arrays.sort(da); int from = Character.MIN_VALUE; int k = 0; while (from <= Character.MAX_VALUE) { while (k < da.length && da[k] == from) { k++; from++; } if (from <= Character.MAX_VALUE) { int to = Character.MAX_VALUE; if (k < da.length) { to = da[k]-1; k++; } states[i].transitions.add(new Transition((char)from, (char)to, states[0])); from = to+2; } } } a.deterministic = true; return a; } } src/dk/brics/automaton/BasicOperations.java000066400000000000000000000500051204272215500213040ustar00rootroot00000000000000/* * dk.brics.automaton * * Copyright (c) 2001-2011 Anders Moeller * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package dk.brics.automaton; import java.util.ArrayList; import java.util.BitSet; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; /** * Basic automata operations. */ final public class BasicOperations { private BasicOperations() {} /** * Returns an automaton that accepts the concatenation of the languages of * the given automata. *

* Complexity: linear in number of states. */ static public Automaton concatenate(Automaton a1, Automaton a2) { if (a1.isSingleton() && a2.isSingleton()) return BasicAutomata.makeString(a1.singleton + a2.singleton); if (isEmpty(a1) || isEmpty(a2)) return BasicAutomata.makeEmpty(); boolean deterministic = a1.isSingleton() && a2.isDeterministic(); if (a1 == a2) { a1 = a1.cloneExpanded(); a2 = a2.cloneExpanded(); } else { a1 = a1.cloneExpandedIfRequired(); a2 = a2.cloneExpandedIfRequired(); } for (State s : a1.getAcceptStates()) { s.accept = false; s.addEpsilon(a2.initial); } a1.deterministic = deterministic; a1.clearHashCode(); a1.checkMinimizeAlways(); return a1; } /** * Returns an automaton that accepts the concatenation of the languages of * the given automata. *

* Complexity: linear in total number of states. */ static public Automaton concatenate(List l) { if (l.isEmpty()) return BasicAutomata.makeEmptyString(); boolean all_singleton = true; for (Automaton a : l) if (!a.isSingleton()) { all_singleton = false; break; } if (all_singleton) { StringBuilder b = new StringBuilder(); for (Automaton a : l) b.append(a.singleton); return BasicAutomata.makeString(b.toString()); } else { for (Automaton a : l) if (a.isEmpty()) return BasicAutomata.makeEmpty(); Set ids = new HashSet(); for (Automaton a : l) ids.add(System.identityHashCode(a)); boolean has_aliases = ids.size() != l.size(); Automaton b = l.get(0); if (has_aliases) b = b.cloneExpanded(); else b = b.cloneExpandedIfRequired(); Set ac = b.getAcceptStates(); boolean first = true; for (Automaton a : l) if (first) first = false; else { if (a.isEmptyString()) continue; Automaton aa = a; if (has_aliases) aa = aa.cloneExpanded(); else aa = aa.cloneExpandedIfRequired(); Set ns = aa.getAcceptStates(); for (State s : ac) { s.accept = false; s.addEpsilon(aa.initial); if (s.accept) ns.add(s); } ac = ns; } b.deterministic = false; b.clearHashCode(); b.checkMinimizeAlways(); return b; } } /** * Returns an automaton that accepts the union of the empty string and the * language of the given automaton. *

* Complexity: linear in number of states. */ static public Automaton optional(Automaton a) { a = a.cloneExpandedIfRequired(); State s = new State(); s.addEpsilon(a.initial); s.accept = true; a.initial = s; a.deterministic = false; a.clearHashCode(); a.checkMinimizeAlways(); return a; } /** * Returns an automaton that accepts the Kleene star (zero or more * concatenated repetitions) of the language of the given automaton. * Never modifies the input automaton language. *

* Complexity: linear in number of states. */ static public Automaton repeat(Automaton a) { a = a.cloneExpanded(); State s = new State(); s.accept = true; s.addEpsilon(a.initial); for (State p : a.getAcceptStates()) p.addEpsilon(s); a.initial = s; a.deterministic = false; a.clearHashCode(); a.checkMinimizeAlways(); return a; } /** * Returns an automaton that accepts min or more * concatenated repetitions of the language of the given automaton. *

* Complexity: linear in number of states and in min. */ static public Automaton repeat(Automaton a, int min) { if (min == 0) return repeat(a); List as = new ArrayList(); while (min-- > 0) as.add(a); as.add(repeat(a)); return concatenate(as); } /** * Returns an automaton that accepts between min and * max (including both) concatenated repetitions of the * language of the given automaton. *

* Complexity: linear in number of states and in min and * max. */ static public Automaton repeat(Automaton a, int min, int max) { if (min > max) return BasicAutomata.makeEmpty(); max -= min; a.expandSingleton(); Automaton b; if (min == 0) b = BasicAutomata.makeEmptyString(); else if (min == 1) b = a.clone(); else { List as = new ArrayList(); while (min-- > 0) as.add(a); b = concatenate(as); } if (max > 0) { Automaton d = a.clone(); while (--max > 0) { Automaton c = a.clone(); for (State p : c.getAcceptStates()) p.addEpsilon(d.initial); d = c; } for (State p : b.getAcceptStates()) p.addEpsilon(d.initial); b.deterministic = false; b.clearHashCode(); b.checkMinimizeAlways(); } return b; } /** * Returns a (deterministic) automaton that accepts the complement of the * language of the given automaton. *

* Complexity: linear in number of states (if already deterministic). */ static public Automaton complement(Automaton a) { a = a.cloneExpandedIfRequired(); a.determinize(); a.totalize(); for (State p : a.getStates()) p.accept = !p.accept; a.removeDeadTransitions(); return a; } /** * Returns a (deterministic) automaton that accepts the intersection of * the language of a1 and the complement of the language of * a2. As a side-effect, the automata may be determinized, if not * already deterministic. *

* Complexity: quadratic in number of states (if already deterministic). */ static public Automaton minus(Automaton a1, Automaton a2) { if (a1.isEmpty() || a1 == a2) return BasicAutomata.makeEmpty(); if (a2.isEmpty()) return a1.cloneIfRequired(); if (a1.isSingleton()) { if (a2.run(a1.singleton)) return BasicAutomata.makeEmpty(); else return a1.cloneIfRequired(); } return intersection(a1, a2.complement()); } /** * Returns an automaton that accepts the intersection of * the languages of the given automata. * Never modifies the input automata languages. *

* Complexity: quadratic in number of states. */ static public Automaton intersection(Automaton a1, Automaton a2) { if (a1.isSingleton()) { if (a2.run(a1.singleton)) return a1.cloneIfRequired(); else return BasicAutomata.makeEmpty(); } if (a2.isSingleton()) { if (a1.run(a2.singleton)) return a2.cloneIfRequired(); else return BasicAutomata.makeEmpty(); } if (a1 == a2) return a1.cloneIfRequired(); Transition[][] transitions1 = Automaton.getSortedTransitions(a1.getStates()); Transition[][] transitions2 = Automaton.getSortedTransitions(a2.getStates()); Automaton c = new Automaton(); LinkedList worklist = new LinkedList(); HashMap newstates = new HashMap(); StatePair p = new StatePair(c.initial, a1.initial, a2.initial); worklist.add(p); newstates.put(p, p); while (worklist.size() > 0) { p = worklist.removeFirst(); p.s.accept = p.s1.accept && p.s2.accept; Transition[] t1 = transitions1[p.s1.number]; Transition[] t2 = transitions2[p.s2.number]; for (int n1 = 0, b2 = 0; n1 < t1.length; n1++) { while (b2 < t2.length && t2[b2].max < t1[n1].min) b2++; for (int n2 = b2; n2 < t2.length && t1[n1].max >= t2[n2].min; n2++) if (t2[n2].max >= t1[n1].min) { StatePair q = new StatePair(t1[n1].to, t2[n2].to); StatePair r = newstates.get(q); if (r == null) { q.s = new State(); worklist.add(q); newstates.put(q, q); r = q; } char min = t1[n1].min > t2[n2].min ? t1[n1].min : t2[n2].min; char max = t1[n1].max < t2[n2].max ? t1[n1].max : t2[n2].max; p.s.transitions.add(new Transition(min, max, r.s)); } } } c.deterministic = a1.deterministic && a2.deterministic; c.removeDeadTransitions(); c.checkMinimizeAlways(); return c; } /** * Returns true if the language of a1 is a subset of the * language of a2. * As a side-effect, a2 is determinized if not already marked as * deterministic. *

* Complexity: quadratic in number of states. */ public static boolean subsetOf(Automaton a1, Automaton a2) { if (a1 == a2) return true; if (a1.isSingleton()) { if (a2.isSingleton()) return a1.singleton.equals(a2.singleton); return a2.run(a1.singleton); } a2.determinize(); Transition[][] transitions1 = Automaton.getSortedTransitions(a1.getStates()); Transition[][] transitions2 = Automaton.getSortedTransitions(a2.getStates()); LinkedList worklist = new LinkedList(); HashSet visited = new HashSet(); StatePair p = new StatePair(a1.initial, a2.initial); worklist.add(p); visited.add(p); while (worklist.size() > 0) { p = worklist.removeFirst(); if (p.s1.accept && !p.s2.accept) return false; Transition[] t1 = transitions1[p.s1.number]; Transition[] t2 = transitions2[p.s2.number]; for (int n1 = 0, b2 = 0; n1 < t1.length; n1++) { while (b2 < t2.length && t2[b2].max < t1[n1].min) b2++; int min1 = t1[n1].min, max1 = t1[n1].max; for (int n2 = b2; n2 < t2.length && t1[n1].max >= t2[n2].min; n2++) { if (t2[n2].min > min1) return false; if (t2[n2].max < Character.MAX_VALUE) min1 = t2[n2].max + 1; else { min1 = Character.MAX_VALUE; max1 = Character.MIN_VALUE; } StatePair q = new StatePair(t1[n1].to, t2[n2].to); if (!visited.contains(q)) { worklist.add(q); visited.add(q); } } if (min1 <= max1) return false; } } return true; } /** * Returns an automaton that accepts the union of the languages of the given automata. *

* Complexity: linear in number of states. */ public static Automaton union(Automaton a1, Automaton a2) { if ((a1.isSingleton() && a2.isSingleton() && a1.singleton.equals(a2.singleton)) || a1 == a2) return a1.cloneIfRequired(); if (a1 == a2) { a1 = a1.cloneExpanded(); a2 = a2.cloneExpanded(); } else { a1 = a1.cloneExpandedIfRequired(); a2 = a2.cloneExpandedIfRequired(); } State s = new State(); s.addEpsilon(a1.initial); s.addEpsilon(a2.initial); a1.initial = s; a1.deterministic = false; a1.clearHashCode(); a1.checkMinimizeAlways(); return a1; } /** * Returns an automaton that accepts the union of the languages of the given automata. *

* Complexity: linear in number of states. */ public static Automaton union(Collection l) { Set ids = new HashSet(); for (Automaton a : l) ids.add(System.identityHashCode(a)); boolean has_aliases = ids.size() != l.size(); State s = new State(); for (Automaton b : l) { if (b.isEmpty()) continue; Automaton bb = b; if (has_aliases) bb = bb.cloneExpanded(); else bb = bb.cloneExpandedIfRequired(); s.addEpsilon(bb.initial); } Automaton a = new Automaton(); a.initial = s; a.deterministic = false; a.clearHashCode(); a.checkMinimizeAlways(); return a; } /** * Determinizes the given automaton. *

* Complexity: exponential in number of states. */ public static void determinize(Automaton a) { if (a.deterministic || a.isSingleton()) return; Set initialset = new HashSet(); initialset.add(a.initial); determinize(a, initialset); } /** * Determinizes the given automaton using the given set of initial states. */ static void determinize(Automaton a, Set initialset) { char[] points = a.getStartPoints(); // subset construction Map, Set> sets = new HashMap, Set>(); LinkedList> worklist = new LinkedList>(); Map, State> newstate = new HashMap, State>(); sets.put(initialset, initialset); worklist.add(initialset); a.initial = new State(); newstate.put(initialset, a.initial); while (worklist.size() > 0) { Set s = worklist.removeFirst(); State r = newstate.get(s); for (State q : s) if (q.accept) { r.accept = true; break; } for (int n = 0; n < points.length; n++) { Set p = new HashSet(); for (State q : s) for (Transition t : q.transitions) if (t.min <= points[n] && points[n] <= t.max) p.add(t.to); if (!sets.containsKey(p)) { sets.put(p, p); worklist.add(p); newstate.put(p, new State()); } State q = newstate.get(p); char min = points[n]; char max; if (n + 1 < points.length) max = (char)(points[n + 1] - 1); else max = Character.MAX_VALUE; r.transitions.add(new Transition(min, max, q)); } } a.deterministic = true; a.removeDeadTransitions(); } /** * Adds epsilon transitions to the given automaton. * This method adds extra character interval transitions that are equivalent to the given * set of epsilon transitions. * @param pairs collection of {@link StatePair} objects representing pairs of source/destination states * where epsilon transitions should be added */ public static void addEpsilons(Automaton a, Collection pairs) { a.expandSingleton(); HashMap> forward = new HashMap>(); HashMap> back = new HashMap>(); for (StatePair p : pairs) { HashSet to = forward.get(p.s1); if (to == null) { to = new HashSet(); forward.put(p.s1, to); } to.add(p.s2); HashSet from = back.get(p.s2); if (from == null) { from = new HashSet(); back.put(p.s2, from); } from.add(p.s1); } // calculate epsilon closure LinkedList worklist = new LinkedList(pairs); HashSet workset = new HashSet(pairs); while (!worklist.isEmpty()) { StatePair p = worklist.removeFirst(); workset.remove(p); HashSet to = forward.get(p.s2); HashSet from = back.get(p.s1); if (to != null) { for (State s : to) { StatePair pp = new StatePair(p.s1, s); if (!pairs.contains(pp)) { pairs.add(pp); forward.get(p.s1).add(s); back.get(s).add(p.s1); worklist.add(pp); workset.add(pp); if (from != null) { for (State q : from) { StatePair qq = new StatePair(q, p.s1); if (!workset.contains(qq)) { worklist.add(qq); workset.add(qq); } } } } } } } // add transitions for (StatePair p : pairs) p.s1.addEpsilon(p.s2); a.deterministic = false; a.clearHashCode(); a.checkMinimizeAlways(); } /** * Returns true if the given automaton accepts the empty string and nothing else. */ public static boolean isEmptyString(Automaton a) { if (a.isSingleton()) return a.singleton.length() == 0; else return a.initial.accept && a.initial.transitions.isEmpty(); } /** * Returns true if the given automaton accepts no strings. */ public static boolean isEmpty(Automaton a) { if (a.isSingleton()) return false; return !a.initial.accept && a.initial.transitions.isEmpty(); } /** * Returns true if the given automaton accepts all strings. */ public static boolean isTotal(Automaton a) { if (a.isSingleton()) return false; if (a.initial.accept && a.initial.transitions.size() == 1) { Transition t = a.initial.transitions.iterator().next(); return t.to == a.initial && t.min == Character.MIN_VALUE && t.max == Character.MAX_VALUE; } return false; } /** * Returns a shortest accepted/rejected string. * If more than one shortest string is found, the lexicographically first of the shortest strings is returned. * @param accepted if true, look for accepted strings; otherwise, look for rejected strings * @return the string, null if none found */ public static String getShortestExample(Automaton a, boolean accepted) { if (a.isSingleton()) { if (accepted) return a.singleton; else if (a.singleton.length() > 0) return ""; else return "\u0000"; } return getShortestExample(a.getInitialState(), accepted); } static String getShortestExample(State s, boolean accepted) { Map path = new HashMap(); LinkedList queue = new LinkedList(); path.put(s, ""); queue.add(s); String best = null; while (!queue.isEmpty()) { State q = queue.removeFirst(); String p = path.get(q); if (q.accept == accepted) { if (best == null || p.length() < best.length() || (p.length() == best.length() && p.compareTo(best) < 0)) best = p; } else for (Transition t : q.getTransitions()) { String tp = path.get(t.to); String np = p + t.min; if (tp == null || (tp.length() == np.length() && np.compareTo(tp) < 0)) { if (tp == null) queue.addLast(t.to); path.put(t.to, np); } } } return best; } /** * Returns true if the given string is accepted by the automaton. *

* Complexity: linear in the length of the string. *

* Note: for full performance, use the {@link RunAutomaton} class. */ public static boolean run(Automaton a, String s) { if (a.isSingleton()) return s.equals(a.singleton); if (a.deterministic) { State p = a.initial; for (int i = 0; i < s.length(); i++) { State q = p.step(s.charAt(i)); if (q == null) return false; p = q; } return p.accept; } else { Set states = a.getStates(); Automaton.setStateNumbers(states); LinkedList pp = new LinkedList(); LinkedList pp_other = new LinkedList(); BitSet bb = new BitSet(states.size()); BitSet bb_other = new BitSet(states.size()); pp.add(a.initial); ArrayList dest = new ArrayList(); boolean accept = a.initial.accept; for (int i = 0; i < s.length(); i++) { char c = s.charAt(i); accept = false; pp_other.clear(); bb_other.clear(); for (State p : pp) { dest.clear(); p.step(c, dest); for (State q : dest) { if (q.accept) accept = true; if (!bb_other.get(q.number)) { bb_other.set(q.number); pp_other.add(q); } } } LinkedList tp = pp; pp = pp_other; pp_other = tp; BitSet tb = bb; bb = bb_other; bb_other = tb; } return accept; } } } src/dk/brics/automaton/Datatypes.java000066400000000000000000001574271204272215500201750ustar00rootroot00000000000000/* * dk.brics.automaton * * Copyright (c) 2001-2011 Anders Moeller * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package dk.brics.automaton; import java.io.*; import java.net.URL; import java.util.*; /** * Basic automata for representing common datatypes * related to Unicode, XML, and XML Schema. */ final public class Datatypes { private static final Map automata; private static final Automaton ws; private static final Set unicodeblock_names; private static final Set unicodecategory_names; private static final Set xml_names; private static final String[] unicodeblock_names_array = { "BasicLatin", "Latin-1Supplement", "LatinExtended-A", "LatinExtended-B", "IPAExtensions", "SpacingModifierLetters", "CombiningDiacriticalMarks", "Greek", "Cyrillic", "Armenian", "Hebrew", "Arabic", "Syriac", "Thaana", "Devanagari", "Bengali", "Gurmukhi", "Gujarati", "Oriya", "Tamil", "Telugu", "Kannada", "Malayalam", "Sinhala", "Thai", "Lao", "Tibetan", "Myanmar", "Georgian", "HangulJamo", "Ethiopic", "Cherokee", "UnifiedCanadianAboriginalSyllabics", "Ogham", "Runic", "Khmer", "Mongolian", "LatinExtendedAdditional", "GreekExtended", "GeneralPunctuation", "SuperscriptsandSubscripts", "CurrencySymbols", "CombiningMarksforSymbols", "LetterlikeSymbols", "NumberForms", "Arrows", "MathematicalOperators", "MiscellaneousTechnical", "ControlPictures", "OpticalCharacterRecognition", "EnclosedAlphanumerics", "BoxDrawing", "BlockElements", "GeometricShapes", "MiscellaneousSymbols", "Dingbats", "BraillePatterns", "CJKRadicalsSupplement", "KangxiRadicals", "IdeographicDescriptionCharacters", "CJKSymbolsandPunctuation", "Hiragana", "Katakana", "Bopomofo", "HangulCompatibilityJamo", "Kanbun", "BopomofoExtended", "EnclosedCJKLettersandMonths", "CJKCompatibility", "CJKUnifiedIdeographsExtensionA", "CJKUnifiedIdeographs", "YiSyllables", "YiRadicals", "HangulSyllables", "CJKCompatibilityIdeographs", "AlphabeticPresentationForms", "ArabicPresentationForms-A", "CombiningHalfMarks", "CJKCompatibilityForms", "SmallFormVariants", "ArabicPresentationForms-B", "Specials", "HalfwidthandFullwidthForms", "Specials", "OldItalic", "Gothic", "Deseret", "ByzantineMusicalSymbols", "MusicalSymbols", "MathematicalAlphanumericSymbols", "CJKUnifiedIdeographsExtensionB", "CJKCompatibilityIdeographsSupplement", "Tags" }; private static final String[] unicodecategory_names_array = { "Lu", "Ll", "Lt", "Lm", "Lo", "L", "Mn", "Mc", "Me", "M", "Nd", "Nl", "No", "N", "Pc", "Pd", "Ps", "Pe", "Pi", "Pf", "Po", "P", "Zs", "Zl", "Zp", "Z", "Sm", "Sc", "Sk", "So", "S", "Cc", "Cf", "Co", "Cn", "C" }; private static final String[] xml_names_array = { "NCName", "QName", "Char", "NameChar", "URI", "anyname", "noap", "whitespace", "whitespacechar", "string", "boolean", "decimal", "float", "integer", "duration", "dateTime", "time", "date", "gYearMonth", "gYear", "gMonthDay", "gDay", "hexBinary", "base64Binary", "NCName2", "NCNames", "QName2", "Nmtoken2", "Nmtokens", "Name2", "Names", "language" }; static { automata = new HashMap(); ws = Automaton.minimize(Automaton.makeCharSet(" \t\n\r").repeat()); unicodeblock_names = new HashSet(Arrays.asList(unicodeblock_names_array)); unicodecategory_names = new HashSet(Arrays.asList(unicodecategory_names_array)); xml_names = new HashSet(Arrays.asList(xml_names_array)); } private Datatypes() {} /** * Invoke during compilation to pre-build automata. * Automata are stored in the directory specified by the system property dk.brics.automaton.datatypes. * (Default: build, relative to the current working directory.) */ public static void main(String[] args) { long t = System.currentTimeMillis(); boolean b = Automaton.setAllowMutate(true); buildAll(); Automaton.setAllowMutate(b); System.out.println("Storing automata..."); for (Map.Entry e : automata.entrySet()) store(e.getKey(), e.getValue()); System.out.println("Time for building automata: " + (System.currentTimeMillis() - t) + "ms"); } /** * Returns pre-built automaton. * Automata are loaded as resources from the class loader of the Datatypes class. * (Typically, the pre-built automata are stored in the same jar as this class.) *

* The following automata are available: * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
NameDescription
NCNameNCName from XML Namespaces 1.0
QNameQName from XML Namespaces 1.0
CharChar from XML 1.0
NameCharNameChar from XML 1.0
URIURI from RFC2396 with * amendments from RFC2373
anynameoptional URI enclosed by brackets, followed by NCName
noapstrings not containing '@' and '%'
whitespaceoptional S from XML 1.0
whitespacechara single whitespace character from XML 1.0
stringstring from XML Schema Part 2
booleanboolean from XML Schema Part 2
decimaldecimal from XML Schema Part 2
floatfloat from XML Schema Part 2
integerinteger from XML Schema Part 2
durationduration from XML Schema Part 2
dateTimedateTime from XML Schema Part 2
timetime from XML Schema Part 2
datedate from XML Schema Part 2
gYearMonthgYearMonth from XML Schema Part 2
gYeargYear from XML Schema Part 2
gMonthDaygMonthDay from XML Schema Part 2
gDaygDay from XML Schema Part 2
hexBinaryhexBinary from XML Schema Part 2
base64Binarybase64Binary from XML Schema Part 2
NCName2NCName from XML Schema Part 2
NCNameslist of NCNames from XML Schema Part 2
QName2QName from XML Schema Part 2
Nmtoken2NMTOKEN from XML Schema Part 2
NmtokensNMTOKENS from XML Schema Part 2
Name2Name from XML Schema Part 2
Nameslist of Names from XML Schema Part 2
languagelanguage from XML Schema Part 2
BasicLatinBasicLatin block from Unicode 3.1
Latin-1SupplementLatin-1Supplement block from Unicode 3.1
LatinExtended-ALatinExtended-A block from Unicode 3.1
LatinExtended-BLatinExtended-B block from Unicode 3.1
IPAExtensionsIPAExtensions block from Unicode 3.1
SpacingModifierLettersSpacingModifierLetters block from Unicode 3.1
CombiningDiacriticalMarksCombiningDiacriticalMarks block from Unicode 3.1
GreekGreek block from Unicode 3.1
CyrillicCyrillic block from Unicode 3.1
ArmenianArmenian block from Unicode 3.1
HebrewHebrew block from Unicode 3.1
ArabicArabic block from Unicode 3.1
SyriacSyriac block from Unicode 3.1
ThaanaThaana block from Unicode 3.1
DevanagariDevanagari block from Unicode 3.1
BengaliBengali block from Unicode 3.1
GurmukhiGurmukhi block from Unicode 3.1
GujaratiGujarati block from Unicode 3.1
OriyaOriya block from Unicode 3.1
TamilTamil block from Unicode 3.1
TeluguTelugu block from Unicode 3.1
KannadaKannada block from Unicode 3.1
MalayalamMalayalam block from Unicode 3.1
SinhalaSinhala block from Unicode 3.1
ThaiThai block from Unicode 3.1
LaoLao block from Unicode 3.1
TibetanTibetan block from Unicode 3.1
MyanmarMyanmar block from Unicode 3.1
GeorgianGeorgian block from Unicode 3.1
HangulJamoHangulJamo block from Unicode 3.1
EthiopicEthiopic block from Unicode 3.1
CherokeeCherokee block from Unicode 3.1
UnifiedCanadianAboriginalSyllabicsUnifiedCanadianAboriginalSyllabics block from Unicode 3.1
OghamOgham block from Unicode 3.1
RunicRunic block from Unicode 3.1
KhmerKhmer block from Unicode 3.1
MongolianMongolian block from Unicode 3.1
LatinExtendedAdditionalLatinExtendedAdditional block from Unicode 3.1
GreekExtendedGreekExtended block from Unicode 3.1
GeneralPunctuationGeneralPunctuation block from Unicode 3.1
SuperscriptsandSubscriptsSuperscriptsandSubscripts block from Unicode 3.1
CurrencySymbolsCurrencySymbols block from Unicode 3.1
CombiningMarksforSymbolsCombiningMarksforSymbols block from Unicode 3.1
LetterlikeSymbolsLetterlikeSymbols block from Unicode 3.1
NumberFormsNumberForms block from Unicode 3.1
ArrowsArrows block from Unicode 3.1
MathematicalOperatorsMathematicalOperators block from Unicode 3.1
MiscellaneousTechnicalMiscellaneousTechnical block from Unicode 3.1
ControlPicturesControlPictures block from Unicode 3.1
OpticalCharacterRecognitionOpticalCharacterRecognition block from Unicode 3.1
EnclosedAlphanumericsEnclosedAlphanumerics block from Unicode 3.1
BoxDrawingBoxDrawing block from Unicode 3.1
BlockElementsBlockElements block from Unicode 3.1
GeometricShapesGeometricShapes block from Unicode 3.1
MiscellaneousSymbolsMiscellaneousSymbols block from Unicode 3.1
DingbatsDingbats block from Unicode 3.1
BraillePatternsBraillePatterns block from Unicode 3.1
CJKRadicalsSupplementCJKRadicalsSupplement block from Unicode 3.1
KangxiRadicalsKangxiRadicals block from Unicode 3.1
IdeographicDescriptionCharactersIdeographicDescriptionCharacters block from Unicode 3.1
CJKSymbolsandPunctuationCJKSymbolsandPunctuation block from Unicode 3.1
HiraganaHiragana block from Unicode 3.1
KatakanaKatakana block from Unicode 3.1
BopomofoBopomofo block from Unicode 3.1
HangulCompatibilityJamoHangulCompatibilityJamo block from Unicode 3.1
KanbunKanbun block from Unicode 3.1
BopomofoExtendedBopomofoExtended block from Unicode 3.1
EnclosedCJKLettersandMonthsEnclosedCJKLettersandMonths block from Unicode 3.1
CJKCompatibilityCJKCompatibility block from Unicode 3.1
CJKUnifiedIdeographsExtensionACJKUnifiedIdeographsExtensionA block from Unicode 3.1
CJKUnifiedIdeographsCJKUnifiedIdeographs block from Unicode 3.1
YiSyllablesYiSyllables block from Unicode 3.1
YiRadicalsYiRadicals block from Unicode 3.1
HangulSyllablesHangulSyllables block from Unicode 3.1
CJKCompatibilityIdeographsCJKCompatibilityIdeographs block from Unicode 3.1
AlphabeticPresentationFormsAlphabeticPresentationForms block from Unicode 3.1
ArabicPresentationForms-AArabicPresentationForms-A block from Unicode 3.1
CombiningHalfMarksCombiningHalfMarks block from Unicode 3.1
CJKCompatibilityFormsCJKCompatibilityForms block from Unicode 3.1
SmallFormVariantsSmallFormVariants block from Unicode 3.1
ArabicPresentationForms-BArabicPresentationForms-B block from Unicode 3.1
SpecialsSpecials block from Unicode 3.1
HalfwidthandFullwidthFormsHalfwidthandFullwidthForms block from Unicode 3.1
SpecialsSpecials block from Unicode 3.1
OldItalicOldItalic block from Unicode 3.1
GothicGothic block from Unicode 3.1
DeseretDeseret block from Unicode 3.1
ByzantineMusicalSymbolsByzantineMusicalSymbols block from Unicode 3.1
MusicalSymbolsMusicalSymbols block from Unicode 3.1
MathematicalAlphanumericSymbolsMathematicalAlphanumericSymbols block from Unicode 3.1
CJKUnifiedIdeographsExtensionBCJKUnifiedIdeographsExtensionB block from Unicode 3.1
CJKCompatibilityIdeographsSupplementCJKCompatibilityIdeographsSupplement block from Unicode 3.1
TagsTags block from Unicode 3.1
LuLu category from Unicode 3.1
LlLl category from Unicode 3.1
LtLt category from Unicode 3.1
LmLm category from Unicode 3.1
LoLo category from Unicode 3.1
LL category from Unicode 3.1
MnMn category from Unicode 3.1
McMc category from Unicode 3.1
MeMe category from Unicode 3.1
MM category from Unicode 3.1
NdNd category from Unicode 3.1
NlNl category from Unicode 3.1
NoNo category from Unicode 3.1
NN category from Unicode 3.1
PcPc category from Unicode 3.1
PdPd category from Unicode 3.1
PsPs category from Unicode 3.1
PePe category from Unicode 3.1
PiPi category from Unicode 3.1
PfPf category from Unicode 3.1
PoPo category from Unicode 3.1
PP category from Unicode 3.1
ZsZs category from Unicode 3.1
ZlZl category from Unicode 3.1
ZpZp category from Unicode 3.1
ZZ category from Unicode 3.1
SmSm category from Unicode 3.1
ScSc category from Unicode 3.1
SkSk category from Unicode 3.1
SoSo category from Unicode 3.1
SS category from Unicode 3.1
CcCc category from Unicode 3.1
CfCf category from Unicode 3.1
CoCo category from Unicode 3.1
CnCn category from Unicode 3.1
CC category from Unicode 3.1
*

Loaded automata are cached in memory. * @param name name of automaton * @return automaton */ public static Automaton get(String name) { Automaton a = automata.get(name); if (a == null) { a = load(name); automata.put(name, a); } return a; } /** * Checks whether the given string is the name of a Unicode block (see {@link #get(String)}). */ public static boolean isUnicodeBlockName(String name) { return unicodeblock_names.contains(name); } /** * Checks whether the given string is the name of a Unicode category (see {@link #get(String)}). */ public static boolean isUnicodeCategoryName(String name) { return unicodecategory_names.contains(name); } /** * Checks whether the given string is the name of an XML / XML Schema automaton (see {@link #get(String)}). */ public static boolean isXMLName(String name) { return xml_names.contains(name); } /** * Checks whether a given automaton is available. * @param name automaton name * @return true if the automaton is available */ public static boolean exists(String name) { try { Datatypes.class.getClassLoader().getResource(name + ".aut").openStream().close(); } catch (IOException e) { return false; } return true; } private static Automaton load(String name) { try { URL url = Datatypes.class.getClassLoader().getResource(name + ".aut"); return Automaton.load(url.openStream()); } catch (IOException e) { e.printStackTrace(); return null; } catch (ClassNotFoundException e) { e.printStackTrace(); return null; } } private static void store(String name, Automaton a) { String dir = System.getProperty("dk.brics.automaton.datatypes"); if (dir == null) dir = "build"; try { a.store((new FileOutputStream(dir + "/" + name + ".aut"))); } catch (IOException e) { e.printStackTrace(); } } private static void buildAll() { String[] xmlexps = { "Extender", "[\u3031-\u3035\u309D-\u309E\u30FC-\u30FE\u00B7\u02D0\u02D1\u0387\u0640\u0E46\u0EC6\u3005]", "CombiningChar", "[\u0300-\u0345\u0360-\u0361\u0483-\u0486\u0591-\u05A1\u05A3-\u05B9\u05BB-\u05BD\u05C1-\u05C2\u064B-\u0652" + "\u06D6-\u06DC\u06DD-\u06DF\u06E0-\u06E4\u06E7-\u06E8\u06EA-\u06ED\u0901-\u0903\u093E-\u094C\u0951-\u0954" + "\u0962-\u0963\u0981-\u0983\u09C0-\u09C4\u09C7-\u09C8\u09CB-\u09CD\u09E2-\u09E3\u0A40-\u0A42\u0A47-\u0A48" + "\u0A4B-\u0A4D\u0A70-\u0A71\u0A81-\u0A83\u0ABE-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0B01-\u0B03\u0B3E-\u0B43" + "\u0B47-\u0B48\u0B4B-\u0B4D\u0B56-\u0B57\u0B82-\u0B83\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0C01-\u0C03" + "\u0C3E-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55-\u0C56\u0C82-\u0C83\u0CBE-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD" + "\u0CD5-\u0CD6\u0D02-\u0D03\u0D3E-\u0D43\u0D46-\u0D48\u0D4A-\u0D4D\u0E34-\u0E3A\u0E47-\u0E4E\u0EB4-\u0EB9" + "\u0EBB-\u0EBC\u0EC8-\u0ECD\u0F18-\u0F19\u0F71-\u0F84\u0F86-\u0F8B\u0F90-\u0F95\u0F99-\u0FAD\u0FB1-\u0FB7" + "\u20D0-\u20DC\u302A-\u302F\u05BF\u05C4\u0670\u093C\u094D\u09BC\u09BE\u09BF\u09D7\u0A02\u0A3C\u0A3E\u0A3F" + "\u0ABC\u0B3C\u0BD7\u0D57\u0E31\u0EB1\u0F35\u0F37\u0F39\u0F3E\u0F3F\u0F97\u0FB9\u20E1\u3099\u309A]", "Digit", "[\u0030-\u0039\u0660-\u0669\u06F0-\u06F9\u0966-\u096F\u09E6-\u09EF\u0A66-\u0A6F\u0AE6-\u0AEF\u0B66-\u0B6F" + "\u0BE7-\u0BEF\u0C66-\u0C6F\u0CE6-\u0CEF\u0D66-\u0D6F\u0E50-\u0E59\u0ED0-\u0ED9\u0F20-\u0F29]", "Ideographic", "[\u4E00-\u9FA5\u3021-\u3029\u3007]", "BaseChar", "[\u0041-\u005A\u0061-\u007A\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u00FF\u0100-\u0131\u0134-\u013E\u0141-\u0148" + "\u014A-\u017E\u0180-\u01C3\u01CD-\u01F0\u01F4-\u01F5\u01FA-\u0217\u0250-\u02A8\u02BB-\u02C1\u0388-\u038A" + "\u038E-\u03A1\u03A3-\u03CE\u03D0-\u03D6\u03E2-\u03F3\u0401-\u040C\u040E-\u044F\u0451-\u045C\u045E-\u0481" + "\u0490-\u04C4\u04C7-\u04C8\u04CB-\u04CC\u04D0-\u04EB\u04EE-\u04F5\u04F8-\u04F9\u0531-\u0556\u0561-\u0586" + "\u05D0-\u05EA\u05F0-\u05F2\u0621-\u063A\u0641-\u064A\u0671-\u06B7\u06BA-\u06BE\u06C0-\u06CE\u06D0-\u06D3" + "\u06E5-\u06E6\u0905-\u0939\u0958-\u0961\u0985-\u098C\u098F-\u0990\u0993-\u09A8\u09AA-\u09B0\u09B6-\u09B9" + "\u09DC-\u09DD\u09DF-\u09E1\u09F0-\u09F1\u0A05-\u0A0A\u0A0F-\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32-\u0A33" + "\u0A35-\u0A36\u0A38-\u0A39\u0A59-\u0A5C\u0A72-\u0A74\u0A85-\u0A8B\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0" + "\u0AB2-\u0AB3\u0AB5-\u0AB9\u0B05-\u0B0C\u0B0F-\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32-\u0B33\u0B36-\u0B39" + "\u0B5C-\u0B5D\u0B5F-\u0B61\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99-\u0B9A\u0B9E-\u0B9F\u0BA3-\u0BA4" + "\u0BA8-\u0BAA\u0BAE-\u0BB5\u0BB7-\u0BB9\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39" + "\u0C60-\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CE0-\u0CE1\u0D05-\u0D0C" + "\u0D0E-\u0D10\u0D12-\u0D28\u0D2A-\u0D39\u0D60-\u0D61\u0E01-\u0E2E\u0E32-\u0E33\u0E40-\u0E45\u0E81-\u0E82" + "\u0E87-\u0E88\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EAA-\u0EAB\u0EAD-\u0EAE\u0EB2-\u0EB3\u0EC0-\u0EC4" + "\u0F40-\u0F47\u0F49-\u0F69\u10A0-\u10C5\u10D0-\u10F6\u1102-\u1103\u1105-\u1107\u110B-\u110C\u110E-\u1112" + "\u1154-\u1155\u115F-\u1161\u116D-\u116E\u1172-\u1173\u11AE-\u11AF\u11B7-\u11B8\u11BC-\u11C2\u1E00-\u1E9B" + "\u1EA0-\u1EF9\u1F00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F5F-\u1F7D\u1F80-\u1FB4" + "\u1FB6-\u1FBC\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC" + "\u212A-\u212B\u2180-\u2182\u3041-\u3094\u30A1-\u30FA\u3105-\u312C\uAC00-\uD7A3" + "\u0386\u038C\u03DA\u03DC\u03DE\u03E0\u0559\u06D5\u093D\u09B2\u0A5E\u0A8D\u0ABD\u0AE0\u0B3D\u0B9C\u0CDE\u0E30\u0E84\u0E8A" + "\u0E8D\u0EA5\u0EA7\u0EB0\u0EBD\u1100\u1109\u113C\u113E\u1140\u114C\u114E\u1150\u1159\u1163\u1165\u1167\u1169\u1175\u119E" + "\u11A8\u11AB\u11BA\u11EB\u11F0\u11F9\u1F59\u1F5B\u1F5D\u1FBE\u2126\u212E]", "Letter", "|", "NCNameChar", "||[-._]||", "NameChar", "|:", "Nmtoken", "+", "NCName", "(|_)*", "Name", "(|[_:])*", "QName", "(:)?", "Char", "[\t\n\r\u0020-\uD7FF\ue000-\ufffd]|[\uD800-\uDBFF][\uDC00-\uDFFF]", "whitespacechar", "[ \t\n\r]" }; System.out.println("Building XML automata..."); Map t = buildMap(xmlexps); putFrom("NCName", t); putFrom("QName", t); putFrom("Char", t); putFrom("NameChar", t); putFrom("Letter", t); putFrom("whitespacechar", t); put(automata, "whitespace", ws); String[] uriexps = { "digit", "[0-9]", "upalpha", "[A-Z]", "lowalpha", "[a-z]", "alpha", "|", "alphanum", "|", "hex", "|[a-f]|[A-F]", "escaped", "%", "mark", "[-_.!~*'()]", "unreserved", "|", // "reserved", "[;/?:@&=+$,]", "reserved", "[;/?:@&=+$,\\[\\]]",// RFC 2732 "uric", "||", "fragment", "*", "query", "*", "pchar", "||[:@&=+$,]", "param", "*", "segment", "*(;)*", "path_segments", "(/)*", "abs_path", "/", "uric_no_slash", "||[;?:@&=+$,]", "opaque_part", "*", //"path", "(|)?", // not used "port", "*", // "IPv4address", "({1,}\\.){3}{1,}", "IPv4address", "({1,3}\\.){3}{1,3}", // RFC 2732 / 2373 "hexseq", "{1,4}(:{1,4})*", // RFC 2373 "hexpart", "|::?|::", // RFC 2373 "IPv6address", "(:)?", // RFC 2373 "toplabel", "|((|-)*)", "domainlabel", "|((|-)*)", "hostname", "(\\.)*\\.?", // "host", "|", "host", "||\\[\\]", // RFC 2732 "hostport", "(:)?", "userinfo", "(||[;:&=+$,])*", "server", "((\\@)?)?", "reg_name", "(||[$,;:@&=+])+", "authority", "|", "scheme", "(||[-+.])*", "rel_segment", "(||[;@&=+$,])+", "rel_path", "?", "net_path", "//?", "hier_part", "(|)(\\?)?", "relativeURI", "(||)(\\?)?", "absoluteURI", ":(|)", "URI", "(|)?(\\#)?" }; System.out.println("Building URI automaton..."); putFrom("URI", buildMap(uriexps)); put(automata, "anyname", Automaton.minimize(Automaton.makeChar('{').concatenate(automata.get("URI").clone()).concatenate(Automaton.makeChar('}')).optional().concatenate(automata.get("NCName").clone()))); put(automata, "noap", new RegExp("~(@[@%]@)").toAutomaton()); String[] xsdmisc = { "_", "[ \t\n\r]*", "d", "[0-9]", "Z", "[-+](<00-13>:<00-59>|14:00)|Z", "Y", "({4,})&~(0000)", "M", "<01-12>", "D", "<01-31>", "T", "<00-23>:<00-59>:<00-59>|24:00:00", "B64", "[A-Za-z0-9+/]", "B16", "[AEIMQUYcgkosw048]", "B04", "[AQgw]", "B04S", " ?", "B16S", " ?", "B64S", " ?", }; String[] xsdexps = { "boolean", "<_>(true|false|1|0)<_>", "decimal", "<_>([-+]?+(\\.+)?)<_>", "float", "<_>([-+]?+(\\.+)?([Ee][-+]?+)?|INF|-INF|NaN)<_>", "integer", "<_>[-+]?[0-9]+<_>", "duration", "<_>(-?P(((+Y)?(+M)?(+D)?(T(((+H)?(+M)?(+(\\.+)?S)?)&~()))?)&~()))<_>", "dateTime", "<_>(-?--T(\\.+)??)<_>", "time", "<_>((\\.+)??)<_>", "date", "<_>(-?--?)<_>", "gYearMonth", "<_>(-?-?)<_>", "gYear", "<_>(-??)<_>", "gMonthDay", "<_>(---?)<_>", "gDay", "<_>(--?)<_>", "gMonth", "<_>(--?)<_>", "hexBinary", "<_>([0-9a-fA-F]{2}*)<_>", "base64Binary", "<_>((()*(()|(=)|(= ?=)))?)<_>", "language", "<_>[a-zA-Z]{1,8}(-[a-zA-Z0-9]{1,8})*<_>", "nonPositiveInteger", "<_>(0+|-+)<_>", "negativeInteger", "<_>(-[1-9]*)<_>", "nonNegativeInteger", "<_>(+)<_>", "positiveInteger", "<_>([1-9]*)<_>", }; System.out.println("Building XML Schema automata..."); Map m = buildMap(xsdmisc); putWith(xsdexps, m); put(m, "UNSIGNEDLONG", Automaton.makeMaxInteger("18446744073709551615")); put(m, "UNSIGNEDINT", Automaton.makeMaxInteger("4294967295")); put(m, "UNSIGNEDSHORT", Automaton.makeMaxInteger("65535")); put(m, "UNSIGNEDBYTE", Automaton.makeMaxInteger("255")); put(m, "LONG", Automaton.makeMaxInteger("9223372036854775807")); put(m, "LONG_NEG", Automaton.makeMaxInteger("9223372036854775808")); put(m, "INT", Automaton.makeMaxInteger("2147483647")); put(m, "INT_NEG", Automaton.makeMaxInteger("2147483648")); put(m, "SHORT", Automaton.makeMaxInteger("32767")); put(m, "SHORT_NEG", Automaton.makeMaxInteger("32768")); put(m, "BYTE", Automaton.makeMaxInteger("127")); put(m, "BYTE_NEG", Automaton.makeMaxInteger("128")); Map u = new HashMap(); u.putAll(t); u.putAll(m); String[] xsdexps2 = { "Nmtoken2", "<_><_>", "Name2", "<_><_>", "NCName2", "<_><_>", "QName2", "<_><_>", "Nmtokens", "<_>(<_>)+", "NCNames", "<_>(<_>)+", "Names", "<_>(<_>)+", "unsignedLong", "<_><_>", "unsignedInt", "<_><_>", "unsignedShort", "<_><_>", "unsignedByte", "<_><_>", "long", "<_>(|-)<_>", "int", "<_>(|-)<_>", "short", "<_>(|-)<_>", "byte", "<_>(|-)<_>", "string", "*" }; putWith(xsdexps2, u); System.out.println("Building Unicode block automata..."); put(automata, "BasicLatin", Automaton.makeCharRange('\u0000', '\u007F')); put(automata, "Latin-1Supplement", Automaton.makeCharRange('\u0080', '\u00FF')); put(automata, "LatinExtended-A", Automaton.makeCharRange('\u0100', '\u017F')); put(automata, "LatinExtended-B", Automaton.makeCharRange('\u0180', '\u024F')); put(automata, "IPAExtensions", Automaton.makeCharRange('\u0250', '\u02AF')); put(automata, "SpacingModifierLetters", Automaton.makeCharRange('\u02B0', '\u02FF')); put(automata, "CombiningDiacriticalMarks", Automaton.makeCharRange('\u0300', '\u036F')); put(automata, "Greek", Automaton.makeCharRange('\u0370', '\u03FF')); put(automata, "Cyrillic", Automaton.makeCharRange('\u0400', '\u04FF')); put(automata, "Armenian", Automaton.makeCharRange('\u0530', '\u058F')); put(automata, "Hebrew", Automaton.makeCharRange('\u0590', '\u05FF')); put(automata, "Arabic", Automaton.makeCharRange('\u0600', '\u06FF')); put(automata, "Syriac", Automaton.makeCharRange('\u0700', '\u074F')); put(automata, "Thaana", Automaton.makeCharRange('\u0780', '\u07BF')); put(automata, "Devanagari", Automaton.makeCharRange('\u0900', '\u097F')); put(automata, "Bengali", Automaton.makeCharRange('\u0980', '\u09FF')); put(automata, "Gurmukhi", Automaton.makeCharRange('\u0A00', '\u0A7F')); put(automata, "Gujarati", Automaton.makeCharRange('\u0A80', '\u0AFF')); put(automata, "Oriya", Automaton.makeCharRange('\u0B00', '\u0B7F')); put(automata, "Tamil", Automaton.makeCharRange('\u0B80', '\u0BFF')); put(automata, "Telugu", Automaton.makeCharRange('\u0C00', '\u0C7F')); put(automata, "Kannada", Automaton.makeCharRange('\u0C80', '\u0CFF')); put(automata, "Malayalam", Automaton.makeCharRange('\u0D00', '\u0D7F')); put(automata, "Sinhala", Automaton.makeCharRange('\u0D80', '\u0DFF')); put(automata, "Thai", Automaton.makeCharRange('\u0E00', '\u0E7F')); put(automata, "Lao", Automaton.makeCharRange('\u0E80', '\u0EFF')); put(automata, "Tibetan", Automaton.makeCharRange('\u0F00', '\u0FFF')); put(automata, "Myanmar", Automaton.makeCharRange('\u1000', '\u109F')); put(automata, "Georgian", Automaton.makeCharRange('\u10A0', '\u10FF')); put(automata, "HangulJamo", Automaton.makeCharRange('\u1100', '\u11FF')); put(automata, "Ethiopic", Automaton.makeCharRange('\u1200', '\u137F')); put(automata, "Cherokee", Automaton.makeCharRange('\u13A0', '\u13FF')); put(automata, "UnifiedCanadianAboriginalSyllabics", Automaton.makeCharRange('\u1400', '\u167F')); put(automata, "Ogham", Automaton.makeCharRange('\u1680', '\u169F')); put(automata, "Runic", Automaton.makeCharRange('\u16A0', '\u16FF')); put(automata, "Khmer", Automaton.makeCharRange('\u1780', '\u17FF')); put(automata, "Mongolian", Automaton.makeCharRange('\u1800', '\u18AF')); put(automata, "LatinExtendedAdditional", Automaton.makeCharRange('\u1E00', '\u1EFF')); put(automata, "GreekExtended", Automaton.makeCharRange('\u1F00', '\u1FFF')); put(automata, "GeneralPunctuation", Automaton.makeCharRange('\u2000', '\u206F')); put(automata, "SuperscriptsandSubscripts", Automaton.makeCharRange('\u2070', '\u209F')); put(automata, "CurrencySymbols", Automaton.makeCharRange('\u20A0', '\u20CF')); put(automata, "CombiningMarksforSymbols", Automaton.makeCharRange('\u20D0', '\u20FF')); put(automata, "LetterlikeSymbols", Automaton.makeCharRange('\u2100', '\u214F')); put(automata, "NumberForms", Automaton.makeCharRange('\u2150', '\u218F')); put(automata, "Arrows", Automaton.makeCharRange('\u2190', '\u21FF')); put(automata, "MathematicalOperators", Automaton.makeCharRange('\u2200', '\u22FF')); put(automata, "MiscellaneousTechnical", Automaton.makeCharRange('\u2300', '\u23FF')); put(automata, "ControlPictures", Automaton.makeCharRange('\u2400', '\u243F')); put(automata, "OpticalCharacterRecognition", Automaton.makeCharRange('\u2440', '\u245F')); put(automata, "EnclosedAlphanumerics", Automaton.makeCharRange('\u2460', '\u24FF')); put(automata, "BoxDrawing", Automaton.makeCharRange('\u2500', '\u257F')); put(automata, "BlockElements", Automaton.makeCharRange('\u2580', '\u259F')); put(automata, "GeometricShapes", Automaton.makeCharRange('\u25A0', '\u25FF')); put(automata, "MiscellaneousSymbols", Automaton.makeCharRange('\u2600', '\u26FF')); put(automata, "Dingbats", Automaton.makeCharRange('\u2700', '\u27BF')); put(automata, "BraillePatterns", Automaton.makeCharRange('\u2800', '\u28FF')); put(automata, "CJKRadicalsSupplement", Automaton.makeCharRange('\u2E80', '\u2EFF')); put(automata, "KangxiRadicals", Automaton.makeCharRange('\u2F00', '\u2FDF')); put(automata, "IdeographicDescriptionCharacters", Automaton.makeCharRange('\u2FF0', '\u2FFF')); put(automata, "CJKSymbolsandPunctuation", Automaton.makeCharRange('\u3000', '\u303F')); put(automata, "Hiragana", Automaton.makeCharRange('\u3040', '\u309F')); put(automata, "Katakana", Automaton.makeCharRange('\u30A0', '\u30FF')); put(automata, "Bopomofo", Automaton.makeCharRange('\u3100', '\u312F')); put(automata, "HangulCompatibilityJamo", Automaton.makeCharRange('\u3130', '\u318F')); put(automata, "Kanbun", Automaton.makeCharRange('\u3190', '\u319F')); put(automata, "BopomofoExtended", Automaton.makeCharRange('\u31A0', '\u31BF')); put(automata, "EnclosedCJKLettersandMonths", Automaton.makeCharRange('\u3200', '\u32FF')); put(automata, "CJKCompatibility", Automaton.makeCharRange('\u3300', '\u33FF')); put(automata, "CJKUnifiedIdeographsExtensionA", Automaton.makeCharRange('\u3400', '\u4DB5')); put(automata, "CJKUnifiedIdeographs", Automaton.makeCharRange('\u4E00', '\u9FFF')); put(automata, "YiSyllables", Automaton.makeCharRange('\uA000', '\uA48F')); put(automata, "YiRadicals", Automaton.makeCharRange('\uA490', '\uA4CF')); put(automata, "HangulSyllables", Automaton.makeCharRange('\uAC00', '\uD7A3')); put(automata, "CJKCompatibilityIdeographs", Automaton.makeCharRange('\uF900', '\uFAFF')); put(automata, "AlphabeticPresentationForms", Automaton.makeCharRange('\uFB00', '\uFB4F')); put(automata, "ArabicPresentationForms-A", Automaton.makeCharRange('\uFB50', '\uFDFF')); put(automata, "CombiningHalfMarks", Automaton.makeCharRange('\uFE20', '\uFE2F')); put(automata, "CJKCompatibilityForms", Automaton.makeCharRange('\uFE30', '\uFE4F')); put(automata, "SmallFormVariants", Automaton.makeCharRange('\uFE50', '\uFE6F')); put(automata, "ArabicPresentationForms-B", Automaton.makeCharRange('\uFE70', '\uFEFE')); put(automata, "Specials", Automaton.makeCharRange('\uFEFF', '\uFEFF')); put(automata, "HalfwidthandFullwidthForms", Automaton.makeCharRange('\uFF00', '\uFFEF')); put(automata, "Specials", Automaton.makeCharRange('\uFFF0', '\uFFFD')); put(automata, "OldItalic", Automaton.makeChar('\ud800').concatenate(Automaton.makeCharRange('\udf00', '\udf2f'))); put(automata, "Gothic", Automaton.makeChar('\ud800').concatenate(Automaton.makeCharRange('\udf30', '\udf4f'))); put(automata, "Deseret", Automaton.makeChar('\ud801').concatenate(Automaton.makeCharRange('\udc00', '\udc4f'))); put(automata, "ByzantineMusicalSymbols", Automaton.makeChar('\ud834').concatenate(Automaton.makeCharRange('\udc00', '\udcff'))); put(automata, "MusicalSymbols", Automaton.makeChar('\ud834').concatenate(Automaton.makeCharRange('\udd00', '\uddff'))); put(automata, "MathematicalAlphanumericSymbols", Automaton.makeChar('\ud835').concatenate(Automaton.makeCharRange('\udc00', '\udfff'))); put(automata, "CJKUnifiedIdeographsExtensionB", Automaton.makeCharRange('\ud840', '\ud868').concatenate(Automaton.makeCharRange('\udc00', '\udfff')) .union(Automaton.makeChar('\ud869').concatenate(Automaton.makeCharRange('\udc00', '\uded6')))); put(automata, "CJKCompatibilityIdeographsSupplement", Automaton.makeChar('\ud87e').concatenate(Automaton.makeCharRange('\udc00', '\ude1f'))); put(automata, "Tags", Automaton.makeChar('\udb40').concatenate(Automaton.makeCharRange('\udc00', '\udc7f'))); put(automata, "PrivateUse", Automaton.makeCharRange('\uE000', '\uF8FF') .union(Automaton.makeCharRange('\udb80', '\udbbe').concatenate(Automaton.makeCharRange('\udc00', '\udfff')) .union(Automaton.makeChar('\udbbf').concatenate(Automaton.makeCharRange('\udc00', '\udffd')))) .union(Automaton.makeCharRange('\udbc0', '\udbfe').concatenate(Automaton.makeCharRange('\udc00', '\udfff')) .union(Automaton.makeChar('\udbff').concatenate(Automaton.makeCharRange('\udc00', '\udffd'))))); System.out.println("Building Unicode category automata..."); Map> categories = new HashMap>(); try { StreamTokenizer st = new StreamTokenizer(new BufferedReader(new FileReader("src/Unicode.txt"))); st.resetSyntax(); st.whitespaceChars(';', ';'); st.whitespaceChars('\n', ' '); st.wordChars('0', '9'); st.wordChars('a', 'z'); st.wordChars('A', 'Z'); while (st.nextToken() != StreamTokenizer.TT_EOF) { int cp = Integer.parseInt(st.sval, 16); st.nextToken(); String cat = st.sval; Set c = categories.get(cat); if (c == null) { c = new TreeSet(); categories.put(cat, c); } c.add(cp); String ccat = cat.substring(0, 1); c = categories.get(ccat); if (c == null) { c = new TreeSet(); categories.put(ccat, c); } c.add(cp); } } catch (IOException e) { e.printStackTrace(); System.exit(-1); } List assigned = new ArrayList(); for (Map.Entry> me : categories.entrySet()) { List la1 = new ArrayList(); List la2 = new ArrayList(); for (Integer cp : me.getValue()) { la1.add(makeCodePoint(cp)); if (la1.size() == 50) { la2.add(Automaton.minimize(Automaton.union(la1))); la1.clear(); } } la2.add(Automaton.union(la1)); Automaton a = Automaton.minimize(Automaton.union(la2)); put(automata, me.getKey(), a); assigned.add(a); } Automaton cn = Automaton.minimize(automata.get("Char").clone().intersection(Automaton.union(assigned).complement())); put(automata, "Cn", cn); put(automata, "C", automata.get("C").clone().union(cn)); } private static Automaton makeCodePoint(int cp) { if (cp >= 0x10000) { cp -= 0x10000; char[] cu = { (char)(0xd800 + (cp >> 10)), (char)(0xdc00 + (cp & 0x3ff)) }; return Automaton.makeString(new String(cu)); } else return Automaton.makeChar((char)cp); } private static Map buildMap(String[] exps) { Map map = new HashMap(); int i = 0; while (i + 1 < exps.length) put(map, exps[i++], new RegExp(exps[i++]).toAutomaton(map)); return map; } private static void putWith(String[] exps, Map use) { int i = 0; while (i + 1 < exps.length) put(automata, exps[i++], new RegExp(exps[i++]).toAutomaton(use)); } private static void putFrom(String name, Map from) { automata.put(name, from.get(name)); } private static void put(Map map, String name, Automaton a) { map.put(name, a); System.out.println(" " + name + ": " + a.getNumberOfStates() + " states, " + a.getNumberOfTransitions() + " transitions"); } static Automaton getWhitespaceAutomaton() { return ws; } } src/dk/brics/automaton/DatatypesAutomatonProvider.java000066400000000000000000000054511204272215500235650ustar00rootroot00000000000000/* * dk.brics.automaton * * Copyright (c) 2001-2011 Anders Moeller * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package dk.brics.automaton; /** * Automaton provider based on {@link Datatypes}. */ public class DatatypesAutomatonProvider implements AutomatonProvider { private boolean enable_unicodeblocks, enable_unicodecategories, enable_xml; /** * Constructs a new automaton provider that recognizes all names * from {@link Datatypes#get(String)}. */ public DatatypesAutomatonProvider() { enable_unicodeblocks = enable_unicodecategories = enable_xml = true; } /** * Constructs a new automaton provider that recognizes some of the names * from {@link Datatypes#get(String)} * @param enable_unicodeblocks if true, enable Unicode block names * @param enable_unicodecategories if true, enable Unicode category names * @param enable_xml if true, enable XML related names */ public DatatypesAutomatonProvider(boolean enable_unicodeblocks, boolean enable_unicodecategories, boolean enable_xml) { this.enable_unicodeblocks = enable_unicodeblocks; this.enable_unicodecategories = enable_unicodecategories; this.enable_xml = enable_xml; } public Automaton getAutomaton(String name) { if ((enable_unicodeblocks && Datatypes.isUnicodeBlockName(name)) || (enable_unicodecategories && Datatypes.isUnicodeCategoryName(name)) || (enable_xml && Datatypes.isXMLName(name))) return Datatypes.get(name); return null; } } src/dk/brics/automaton/MinimizationOperations.java000066400000000000000000000312361204272215500227370ustar00rootroot00000000000000/* * dk.brics.automaton * * Copyright (c) 2001-2011 Anders Moeller * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package dk.brics.automaton; import java.util.ArrayList; import java.util.HashSet; import java.util.LinkedList; import java.util.Set; /** * Operations for minimizing automata. */ final public class MinimizationOperations { private MinimizationOperations() {} /** * Minimizes (and determinizes if not already deterministic) the given automaton. * @see Automaton#setMinimization(int) */ public static void minimize(Automaton a) { if (!a.isSingleton()) { switch (Automaton.minimization) { case Automaton.MINIMIZE_HUFFMAN: minimizeHuffman(a); break; case Automaton.MINIMIZE_BRZOZOWSKI: minimizeBrzozowski(a); break; default: minimizeHopcroft(a); } } a.recomputeHashCode(); } private static boolean statesAgree(Transition[][] transitions, boolean[][] mark, int n1, int n2) { Transition[] t1 = transitions[n1]; Transition[] t2 = transitions[n2]; for (int k1 = 0, k2 = 0; k1 < t1.length && k2 < t2.length;) { if (t1[k1].max < t2[k2].min) k1++; else if (t2[k2].max < t1[k1].min) k2++; else { int m1 = t1[k1].to.number; int m2 = t2[k2].to.number; if (m1 > m2) { int t = m1; m1 = m2; m2 = t; } if (mark[m1][m2]) return false; if (t1[k1].max < t2[k2].max) k1++; else k2++; } } return true; } private static void addTriggers(Transition[][] transitions, ArrayList>> triggers, int n1, int n2) { Transition[] t1 = transitions[n1]; Transition[] t2 = transitions[n2]; for (int k1 = 0, k2 = 0; k1 < t1.length && k2 < t2.length;) { if (t1[k1].max < t2[k2].min) k1++; else if (t2[k2].max < t1[k1].min) k2++; else { if (t1[k1].to != t2[k2].to) { int m1 = t1[k1].to.number; int m2 = t2[k2].to.number; if (m1 > m2) { int t = m1; m1 = m2; m2 = t; } if (triggers.get(m1).get(m2) == null) triggers.get(m1).set(m2, new HashSet()); triggers.get(m1).get(m2).add(new IntPair(n1, n2)); } if (t1[k1].max < t2[k2].max) k1++; else k2++; } } } private static void markPair(boolean[][] mark, ArrayList>> triggers, int n1, int n2) { mark[n1][n2] = true; if (triggers.get(n1).get(n2) != null) { for (IntPair p : triggers.get(n1).get(n2)) { int m1 = p.n1; int m2 = p.n2; if (m1 > m2) { int t = m1; m1 = m2; m2 = t; } if (!mark[m1][m2]) markPair(mark, triggers, m1, m2); } } } private static void initialize(ArrayList list, int size) { for (int i = 0; i < size; i++) list.add(null); } /** * Minimizes the given automaton using Huffman's algorithm. */ public static void minimizeHuffman(Automaton a) { a.determinize(); a.totalize(); Set ss = a.getStates(); Transition[][] transitions = new Transition[ss.size()][]; State[] states = ss.toArray(new State[ss.size()]); boolean[][] mark = new boolean[states.length][states.length]; ArrayList>> triggers = new ArrayList>>(); for (int n1 = 0; n1 < states.length; n1++) { ArrayList> v = new ArrayList>(); initialize(v, states.length); triggers.add(v); } // initialize marks based on acceptance status and find transition arrays for (int n1 = 0; n1 < states.length; n1++) { states[n1].number = n1; transitions[n1] = states[n1].getSortedTransitionArray(false); for (int n2 = n1 + 1; n2 < states.length; n2++) if (states[n1].accept != states[n2].accept) mark[n1][n2] = true; } // for all pairs, see if states agree for (int n1 = 0; n1 < states.length; n1++) for (int n2 = n1 + 1; n2 < states.length; n2++) if (!mark[n1][n2]) { if (statesAgree(transitions, mark, n1, n2)) addTriggers(transitions, triggers, n1, n2); else markPair(mark, triggers, n1, n2); } // assign equivalence class numbers to states int numclasses = 0; for (int n = 0; n < states.length; n++) states[n].number = -1; for (int n1 = 0; n1 < states.length; n1++) if (states[n1].number == -1) { states[n1].number = numclasses; for (int n2 = n1 + 1; n2 < states.length; n2++) if (!mark[n1][n2]) states[n2].number = numclasses; numclasses++; } // make a new state for each equivalence class State[] newstates = new State[numclasses]; for (int n = 0; n < numclasses; n++) newstates[n] = new State(); // select a class representative for each class and find the new initial // state for (int n = 0; n < states.length; n++) { newstates[states[n].number].number = n; if (states[n] == a.initial) a.initial = newstates[states[n].number]; } // build transitions and set acceptance for (int n = 0; n < numclasses; n++) { State s = newstates[n]; s.accept = states[s.number].accept; for (Transition t : states[s.number].transitions) s.transitions.add(new Transition(t.min, t.max, newstates[t.to.number])); } a.removeDeadTransitions(); } /** * Minimizes the given automaton using Brzozowski's algorithm. */ public static void minimizeBrzozowski(Automaton a) { if (a.isSingleton()) return; BasicOperations.determinize(a, SpecialOperations.reverse(a)); BasicOperations.determinize(a, SpecialOperations.reverse(a)); } /** * Minimizes the given automaton using Hopcroft's algorithm. */ public static void minimizeHopcroft(Automaton a) { a.determinize(); Set tr = a.initial.getTransitions(); if (tr.size() == 1) { Transition t = tr.iterator().next(); if (t.to == a.initial && t.min == Character.MIN_VALUE && t.max == Character.MAX_VALUE) return; } a.totalize(); // make arrays for numbered states and effective alphabet Set ss = a.getStates(); State[] states = new State[ss.size()]; int number = 0; for (State q : ss) { states[number] = q; q.number = number++; } char[] sigma = a.getStartPoints(); // initialize data structures ArrayList>> reverse = new ArrayList>>(); for (int q = 0; q < states.length; q++) { ArrayList> v = new ArrayList>(); initialize(v, sigma.length); reverse.add(v); } boolean[][] reverse_nonempty = new boolean[states.length][sigma.length]; ArrayList> partition = new ArrayList>(); initialize(partition, states.length); int[] block = new int[states.length]; StateList[][] active = new StateList[states.length][sigma.length]; StateListNode[][] active2 = new StateListNode[states.length][sigma.length]; LinkedList pending = new LinkedList(); boolean[][] pending2 = new boolean[sigma.length][states.length]; ArrayList split = new ArrayList(); boolean[] split2 = new boolean[states.length]; ArrayList refine = new ArrayList(); boolean[] refine2 = new boolean[states.length]; ArrayList> splitblock = new ArrayList>(); initialize(splitblock, states.length); for (int q = 0; q < states.length; q++) { splitblock.set(q, new ArrayList()); partition.set(q, new LinkedList()); for (int x = 0; x < sigma.length; x++) { reverse.get(q).set(x, new LinkedList()); active[q][x] = new StateList(); } } // find initial partition and reverse edges for (int q = 0; q < states.length; q++) { State qq = states[q]; int j; if (qq.accept) j = 0; else j = 1; partition.get(j).add(qq); block[qq.number] = j; for (int x = 0; x < sigma.length; x++) { char y = sigma[x]; State p = qq.step(y); reverse.get(p.number).get(x).add(qq); reverse_nonempty[p.number][x] = true; } } // initialize active sets for (int j = 0; j <= 1; j++) for (int x = 0; x < sigma.length; x++) for (State qq : partition.get(j)) if (reverse_nonempty[qq.number][x]) active2[qq.number][x] = active[j][x].add(qq); // initialize pending for (int x = 0; x < sigma.length; x++) { int a0 = active[0][x].size; int a1 = active[1][x].size; int j; if (a0 <= a1) j = 0; else j = 1; pending.add(new IntPair(j, x)); pending2[x][j] = true; } // process pending until fixed point int k = 2; while (!pending.isEmpty()) { IntPair ip = pending.removeFirst(); int p = ip.n1; int x = ip.n2; pending2[x][p] = false; // find states that need to be split off their blocks for (StateListNode m = active[p][x].first; m != null; m = m.next) for (State s : reverse.get(m.q.number).get(x)) if (!split2[s.number]) { split2[s.number] = true; split.add(s); int j = block[s.number]; splitblock.get(j).add(s); if (!refine2[j]) { refine2[j] = true; refine.add(j); } } // refine blocks for (int j : refine) { if (splitblock.get(j).size() < partition.get(j).size()) { LinkedList b1 = partition.get(j); LinkedList b2 = partition.get(k); for (State s : splitblock.get(j)) { b1.remove(s); b2.add(s); block[s.number] = k; for (int c = 0; c < sigma.length; c++) { StateListNode sn = active2[s.number][c]; if (sn != null && sn.sl == active[j][c]) { sn.remove(); active2[s.number][c] = active[k][c].add(s); } } } // update pending for (int c = 0; c < sigma.length; c++) { int aj = active[j][c].size; int ak = active[k][c].size; if (!pending2[c][j] && 0 < aj && aj <= ak) { pending2[c][j] = true; pending.add(new IntPair(j, c)); } else { pending2[c][k] = true; pending.add(new IntPair(k, c)); } } k++; } for (State s : splitblock.get(j)) split2[s.number] = false; refine2[j] = false; splitblock.get(j).clear(); } split.clear(); refine.clear(); } // make a new state for each equivalence class, set initial state State[] newstates = new State[k]; for (int n = 0; n < newstates.length; n++) { State s = new State(); newstates[n] = s; for (State q : partition.get(n)) { if (q == a.initial) a.initial = s; s.accept = q.accept; s.number = q.number; // select representative q.number = n; } } // build transitions and set acceptance for (int n = 0; n < newstates.length; n++) { State s = newstates[n]; s.accept = states[s.number].accept; for (Transition t : states[s.number].transitions) s.transitions.add(new Transition(t.min, t.max, newstates[t.to.number])); } a.removeDeadTransitions(); } static class IntPair { int n1, n2; IntPair(int n1, int n2) { this.n1 = n1; this.n2 = n2; } } static class StateList { int size; StateListNode first, last; StateListNode add(State q) { return new StateListNode(q, this); } } static class StateListNode { State q; StateListNode next, prev; StateList sl; StateListNode(State q, StateList sl) { this.q = q; this.sl = sl; if (sl.size++ == 0) sl.first = sl.last = this; else { sl.last.next = this; prev = sl.last; sl.last = this; } } void remove() { sl.size--; if (sl.first == this) sl.first = next; else prev.next = next; if (sl.last == this) sl.last = prev; else next.prev = prev; } } } src/dk/brics/automaton/RegExp.java000066400000000000000000000663031204272215500174210ustar00rootroot00000000000000/* * dk.brics.automaton * * Copyright (c) 2001-2011 Anders Moeller * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package dk.brics.automaton; import java.io.IOException; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; /** * Regular Expression extension to Automaton. *

* Regular expressions are built from the following abstract syntax:

* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
regexp::=unionexp
|
unionexp::=interexp | unionexp(union)
|interexp
interexp::=concatexp & interexp(intersection)[OPTIONAL]
|concatexp
concatexp::=repeatexp concatexp(concatenation)
|repeatexp
repeatexp::=repeatexp ?(zero or one occurrence)
|repeatexp *(zero or more occurrences)
|repeatexp +(one or more occurrences)
|repeatexp {n}(n occurrences)
|repeatexp {n,}(n or more occurrences)
|repeatexp {n,m}(n to m occurrences, including both)
|complexp
complexp::=~ complexp(complement)[OPTIONAL]
|charclassexp
charclassexp::=[ charclasses ](character class)
|[^ charclasses ](negated character class)
|simpleexp
charclasses::=charclass charclasses
|charclass
charclass::=charexp - charexp(character range, including end-points)
|charexp
simpleexp::=charexp
|.(any single character)
|#(the empty language)[OPTIONAL]
|@(any string)[OPTIONAL]
|" <Unicode string without double-quotes> "(a string)
|( )(the empty string)
|( unionexp )(precedence override)
|< <identifier> >(named automaton)[OPTIONAL]
|<n-m>(numerical interval)[OPTIONAL]
charexp::=<Unicode character>(a single non-reserved character)
|\ <Unicode character> (a single character)
*

* The productions marked [OPTIONAL] are only allowed * if specified by the syntax flags passed to the RegExp * constructor. The reserved characters used in the (enabled) syntax * must be escaped with backslash (\) or double-quotes * ("..."). (In contrast to other regexp syntaxes, * this is required also in character classes.) Be aware that * dash (-) has a special meaning in charclass expressions. * An identifier is a string not containing right angle bracket * (>) or dash (-). Numerical intervals are * specified by non-negative decimal integers and include both end * points, and if n and m have the * same number of digits, then the conforming strings must have that * length (i.e. prefixed by 0's). * @author Anders Møller <amoeller@cs.au.dk> * */ public class RegExp { enum Kind { REGEXP_UNION, REGEXP_CONCATENATION, REGEXP_INTERSECTION, REGEXP_OPTIONAL, REGEXP_REPEAT, REGEXP_REPEAT_MIN, REGEXP_REPEAT_MINMAX, REGEXP_COMPLEMENT, REGEXP_CHAR, REGEXP_CHAR_RANGE, REGEXP_ANYCHAR, REGEXP_EMPTY, REGEXP_STRING, REGEXP_ANYSTRING, REGEXP_AUTOMATON, REGEXP_INTERVAL } /** * Syntax flag, enables intersection (&). */ public static final int INTERSECTION = 0x0001; /** * Syntax flag, enables complement (~). */ public static final int COMPLEMENT = 0x0002; /** * Syntax flag, enables empty language (#). */ public static final int EMPTY = 0x0004; /** * Syntax flag, enables anystring (@). */ public static final int ANYSTRING = 0x0008; /** * Syntax flag, enables named automata (<identifier>). */ public static final int AUTOMATON = 0x0010; /** * Syntax flag, enables numerical intervals (<n-m>). */ public static final int INTERVAL = 0x0020; /** * Syntax flag, enables all optional regexp syntax. */ public static final int ALL = 0xffff; /** * Syntax flag, enables no optional regexp syntax. */ public static final int NONE = 0x0000; private static boolean allow_mutation = false; Kind kind; RegExp exp1, exp2; String s; char c; int min, max, digits; char from, to; String b; int flags; int pos; RegExp() {} /** * Constructs new RegExp from a string. * Same as RegExp(s, ALL). * @param s regexp string * @exception IllegalArgumentException if an error occured while parsing the regular expression */ public RegExp(String s) throws IllegalArgumentException { this(s, ALL); } /** * Constructs new RegExp from a string. * @param s regexp string * @param syntax_flags boolean 'or' of optional syntax constructs to be enabled * @exception IllegalArgumentException if an error occured while parsing the regular expression */ public RegExp(String s, int syntax_flags) throws IllegalArgumentException { b = s; flags = syntax_flags; RegExp e; if (s.length() == 0) e = makeString(""); else { e = parseUnionExp(); if (pos < b.length()) throw new IllegalArgumentException("end-of-string expected at position " + pos); } kind = e.kind; exp1 = e.exp1; exp2 = e.exp2; this.s = e.s; c = e.c; min = e.min; max = e.max; digits = e.digits; from = e.from; to = e.to; b = null; } /** * Constructs new Automaton from this RegExp. * Same as toAutomaton(null) (empty automaton map). */ public Automaton toAutomaton() { return toAutomatonAllowMutate(null, null, true); } /** * Constructs new Automaton from this RegExp. * Same as toAutomaton(null,minimize) (empty automaton map). */ public Automaton toAutomaton(boolean minimize) { return toAutomatonAllowMutate(null, null, minimize); } /** * Constructs new Automaton from this RegExp. * The constructed automaton is minimal and deterministic and has no * transitions to dead states. * @param automaton_provider provider of automata for named identifiers * @exception IllegalArgumentException if this regular expression uses * a named identifier that is not available from the automaton provider */ public Automaton toAutomaton(AutomatonProvider automaton_provider) throws IllegalArgumentException { return toAutomatonAllowMutate(null, automaton_provider, true); } /** * Constructs new Automaton from this RegExp. * The constructed automaton has no transitions to dead states. * @param automaton_provider provider of automata for named identifiers * @param minimize if set, the automaton is minimized and determinized * @exception IllegalArgumentException if this regular expression uses * a named identifier that is not available from the automaton provider */ public Automaton toAutomaton(AutomatonProvider automaton_provider, boolean minimize) throws IllegalArgumentException { return toAutomatonAllowMutate(null, automaton_provider, minimize); } /** * Constructs new Automaton from this RegExp. * The constructed automaton is minimal and deterministic and has no * transitions to dead states. * @param automata a map from automaton identifiers to automata * (of type Automaton). * @exception IllegalArgumentException if this regular expression uses * a named identifier that does not occur in the automaton map */ public Automaton toAutomaton(Map automata) throws IllegalArgumentException { return toAutomatonAllowMutate(automata, null, true); } /** * Constructs new Automaton from this RegExp. * The constructed automaton has no transitions to dead states. * @param automata a map from automaton identifiers to automata * (of type Automaton). * @param minimize if set, the automaton is minimized and determinized * @exception IllegalArgumentException if this regular expression uses * a named identifier that does not occur in the automaton map */ public Automaton toAutomaton(Map automata, boolean minimize) throws IllegalArgumentException { return toAutomatonAllowMutate(automata, null, minimize); } /** * Sets or resets allow mutate flag. * If this flag is set, then automata construction uses mutable automata, * which is slightly faster but not thread safe. * By default, the flag is not set. * @param flag if true, the flag is set * @return previous value of the flag */ public boolean setAllowMutate(boolean flag) { boolean b = allow_mutation; allow_mutation = flag; return b; } private Automaton toAutomatonAllowMutate(Map automata, AutomatonProvider automaton_provider, boolean minimize) throws IllegalArgumentException { boolean b = false; if (allow_mutation) b = Automaton.setAllowMutate(true); // thread unsafe Automaton a = toAutomaton(automata, automaton_provider, minimize); if (allow_mutation) Automaton.setAllowMutate(b); return a; } private Automaton toAutomaton(Map automata, AutomatonProvider automaton_provider, boolean minimize) throws IllegalArgumentException { List list; Automaton a = null; switch (kind) { case REGEXP_UNION: list = new ArrayList(); findLeaves(exp1, Kind.REGEXP_UNION, list, automata, automaton_provider, minimize); findLeaves(exp2, Kind.REGEXP_UNION, list, automata, automaton_provider, minimize); a = BasicOperations.union(list); a.minimize(); break; case REGEXP_CONCATENATION: list = new ArrayList(); findLeaves(exp1, Kind.REGEXP_CONCATENATION, list, automata, automaton_provider, minimize); findLeaves(exp2, Kind.REGEXP_CONCATENATION, list, automata, automaton_provider, minimize); a = BasicOperations.concatenate(list); a.minimize(); break; case REGEXP_INTERSECTION: a = exp1.toAutomaton(automata, automaton_provider, minimize).intersection(exp2.toAutomaton(automata, automaton_provider, minimize)); a.minimize(); break; case REGEXP_OPTIONAL: a = exp1.toAutomaton(automata, automaton_provider, minimize).optional(); a.minimize(); break; case REGEXP_REPEAT: a = exp1.toAutomaton(automata, automaton_provider, minimize).repeat(); a.minimize(); break; case REGEXP_REPEAT_MIN: a = exp1.toAutomaton(automata, automaton_provider, minimize).repeat(min); a.minimize(); break; case REGEXP_REPEAT_MINMAX: a = exp1.toAutomaton(automata, automaton_provider, minimize).repeat(min, max); a.minimize(); break; case REGEXP_COMPLEMENT: a = exp1.toAutomaton(automata, automaton_provider, minimize).complement(); a.minimize(); break; case REGEXP_CHAR: a = BasicAutomata.makeChar(c); break; case REGEXP_CHAR_RANGE: a = BasicAutomata.makeCharRange(from, to); break; case REGEXP_ANYCHAR: a = BasicAutomata.makeAnyChar(); break; case REGEXP_EMPTY: a = BasicAutomata.makeEmpty(); break; case REGEXP_STRING: a = BasicAutomata.makeString(s); break; case REGEXP_ANYSTRING: a = BasicAutomata.makeAnyString(); break; case REGEXP_AUTOMATON: Automaton aa = null; if (automata != null) aa = automata.get(s); if (aa == null && automaton_provider != null) try { aa = automaton_provider.getAutomaton(s); } catch (IOException e) { throw new IllegalArgumentException(e); } if (aa == null) throw new IllegalArgumentException("'" + s + "' not found"); a = aa.clone(); // always clone here (ignore allow_mutate) break; case REGEXP_INTERVAL: a = BasicAutomata.makeInterval(min, max, digits); break; } return a; } private void findLeaves(RegExp exp, Kind kind, List list, Map automata, AutomatonProvider automaton_provider, boolean minimize) { if (exp.kind == kind) { findLeaves(exp.exp1, kind, list, automata, automaton_provider, minimize); findLeaves(exp.exp2, kind, list, automata, automaton_provider, minimize); } else list.add(exp.toAutomaton(automata, automaton_provider, minimize)); } /** * Constructs string from parsed regular expression. */ @Override public String toString() { return toStringBuilder(new StringBuilder()).toString(); } StringBuilder toStringBuilder(StringBuilder b) { switch (kind) { case REGEXP_UNION: b.append("("); exp1.toStringBuilder(b); b.append("|"); exp2.toStringBuilder(b); b.append(")"); break; case REGEXP_CONCATENATION: exp1.toStringBuilder(b); exp2.toStringBuilder(b); break; case REGEXP_INTERSECTION: b.append("("); exp1.toStringBuilder(b); b.append("&"); exp2.toStringBuilder(b); b.append(")"); break; case REGEXP_OPTIONAL: b.append("("); exp1.toStringBuilder(b); b.append(")?"); break; case REGEXP_REPEAT: b.append("("); exp1.toStringBuilder(b); b.append(")*"); break; case REGEXP_REPEAT_MIN: b.append("("); exp1.toStringBuilder(b); b.append("){").append(min).append(",}"); break; case REGEXP_REPEAT_MINMAX: b.append("("); exp1.toStringBuilder(b); b.append("){").append(min).append(",").append(max).append("}"); break; case REGEXP_COMPLEMENT: b.append("~("); exp1.toStringBuilder(b); b.append(")"); break; case REGEXP_CHAR: b.append("\\").append(c); break; case REGEXP_CHAR_RANGE: b.append("[\\").append(from).append("-\\").append(to).append("]"); break; case REGEXP_ANYCHAR: b.append("."); break; case REGEXP_EMPTY: b.append("#"); break; case REGEXP_STRING: b.append("\"").append(s).append("\""); break; case REGEXP_ANYSTRING: b.append("@"); break; case REGEXP_AUTOMATON: b.append("<").append(s).append(">"); break; case REGEXP_INTERVAL: String s1 = Integer.toString(min); String s2 = Integer.toString(max); b.append("<"); if (digits > 0) for (int i = s1.length(); i < digits; i++) b.append('0'); b.append(s1).append("-"); if (digits > 0) for (int i = s2.length(); i < digits; i++) b.append('0'); b.append(s2).append(">"); break; } return b; } /** * Returns set of automaton identifiers that occur in this regular expression. */ public Set getIdentifiers() { HashSet set = new HashSet(); getIdentifiers(set); return set; } void getIdentifiers(Set set) { switch (kind) { case REGEXP_UNION: case REGEXP_CONCATENATION: case REGEXP_INTERSECTION: exp1.getIdentifiers(set); exp2.getIdentifiers(set); break; case REGEXP_OPTIONAL: case REGEXP_REPEAT: case REGEXP_REPEAT_MIN: case REGEXP_REPEAT_MINMAX: case REGEXP_COMPLEMENT: exp1.getIdentifiers(set); break; case REGEXP_AUTOMATON: set.add(s); break; default: } } static RegExp makeUnion(RegExp exp1, RegExp exp2) { RegExp r = new RegExp(); r.kind = Kind.REGEXP_UNION; r.exp1 = exp1; r.exp2 = exp2; return r; } static RegExp makeConcatenation(RegExp exp1, RegExp exp2) { if ((exp1.kind == Kind.REGEXP_CHAR || exp1.kind == Kind.REGEXP_STRING) && (exp2.kind == Kind.REGEXP_CHAR || exp2.kind == Kind.REGEXP_STRING)) return makeString(exp1, exp2); RegExp r = new RegExp(); r.kind = Kind.REGEXP_CONCATENATION; if (exp1.kind == Kind.REGEXP_CONCATENATION && (exp1.exp2.kind == Kind.REGEXP_CHAR || exp1.exp2.kind == Kind.REGEXP_STRING) && (exp2.kind == Kind.REGEXP_CHAR || exp2.kind == Kind.REGEXP_STRING)) { r.exp1 = exp1.exp1; r.exp2 = makeString(exp1.exp2, exp2); } else if ((exp1.kind == Kind.REGEXP_CHAR || exp1.kind == Kind.REGEXP_STRING) && exp2.kind == Kind.REGEXP_CONCATENATION && (exp2.exp1.kind == Kind.REGEXP_CHAR || exp2.exp1.kind == Kind.REGEXP_STRING)) { r.exp1 = makeString(exp1, exp2.exp1); r.exp2 = exp2.exp2; } else { r.exp1 = exp1; r.exp2 = exp2; } return r; } static private RegExp makeString(RegExp exp1, RegExp exp2) { StringBuilder b = new StringBuilder(); if (exp1.kind == Kind.REGEXP_STRING) b.append(exp1.s); else b.append(exp1.c); if (exp2.kind == Kind.REGEXP_STRING) b.append(exp2.s); else b.append(exp2.c); return makeString(b.toString()); } static RegExp makeIntersection(RegExp exp1, RegExp exp2) { RegExp r = new RegExp(); r.kind = Kind.REGEXP_INTERSECTION; r.exp1 = exp1; r.exp2 = exp2; return r; } static RegExp makeOptional(RegExp exp) { RegExp r = new RegExp(); r.kind = Kind.REGEXP_OPTIONAL; r.exp1 = exp; return r; } static RegExp makeRepeat(RegExp exp) { RegExp r = new RegExp(); r.kind = Kind.REGEXP_REPEAT; r.exp1 = exp; return r; } static RegExp makeRepeat(RegExp exp, int min) { RegExp r = new RegExp(); r.kind = Kind.REGEXP_REPEAT_MIN; r.exp1 = exp; r.min = min; return r; } static RegExp makeRepeat(RegExp exp, int min, int max) { RegExp r = new RegExp(); r.kind = Kind.REGEXP_REPEAT_MINMAX; r.exp1 = exp; r.min = min; r.max = max; return r; } static RegExp makeComplement(RegExp exp) { RegExp r = new RegExp(); r.kind = Kind.REGEXP_COMPLEMENT; r.exp1 = exp; return r; } static RegExp makeChar(char c) { RegExp r = new RegExp(); r.kind = Kind.REGEXP_CHAR; r.c = c; return r; } static RegExp makeCharRange(char from, char to) { RegExp r = new RegExp(); r.kind = Kind.REGEXP_CHAR_RANGE; r.from = from; r.to = to; return r; } static RegExp makeAnyChar() { RegExp r = new RegExp(); r.kind = Kind.REGEXP_ANYCHAR; return r; } static RegExp makeEmpty() { RegExp r = new RegExp(); r.kind = Kind.REGEXP_EMPTY; return r; } static RegExp makeString(String s) { RegExp r = new RegExp(); r.kind = Kind.REGEXP_STRING; r.s = s; return r; } static RegExp makeAnyString() { RegExp r = new RegExp(); r.kind = Kind.REGEXP_ANYSTRING; return r; } static RegExp makeAutomaton(String s) { RegExp r = new RegExp(); r.kind = Kind.REGEXP_AUTOMATON; r.s = s; return r; } static RegExp makeInterval(int min, int max, int digits) { RegExp r = new RegExp(); r.kind = Kind.REGEXP_INTERVAL; r.min = min; r.max = max; r.digits = digits; return r; } private boolean peek(String s) { return more() && s.indexOf(b.charAt(pos)) != -1; } private boolean match(char c) { if (pos >= b.length()) return false; if (b.charAt(pos) == c) { pos++; return true; } return false; } private boolean more() { return pos < b.length(); } private char next() throws IllegalArgumentException { if (!more()) throw new IllegalArgumentException("unexpected end-of-string"); return b.charAt(pos++); } private boolean check(int flag) { return (flags & flag) != 0; } final RegExp parseUnionExp() throws IllegalArgumentException { RegExp e = parseInterExp(); if (match('|')) e = makeUnion(e, parseUnionExp()); return e; } final RegExp parseInterExp() throws IllegalArgumentException { RegExp e = parseConcatExp(); if (check(INTERSECTION) && match('&')) e = makeIntersection(e, parseInterExp()); return e; } final RegExp parseConcatExp() throws IllegalArgumentException { RegExp e = parseRepeatExp(); if (more() && !peek(")|") && (!check(INTERSECTION) || !peek("&"))) e = makeConcatenation(e, parseConcatExp()); return e; } final RegExp parseRepeatExp() throws IllegalArgumentException { RegExp e = parseComplExp(); while (peek("?*+{")) { if (match('?')) e = makeOptional(e); else if (match('*')) e = makeRepeat(e); else if (match('+')) e = makeRepeat(e, 1); else if (match('{')) { int start = pos; while (peek("0123456789")) next(); if (start == pos) throw new IllegalArgumentException("integer expected at position " + pos); int n = Integer.parseInt(b.substring(start, pos)); int m = -1; if (match(',')) { start = pos; while (peek("0123456789")) next(); if (start != pos) m = Integer.parseInt(b.substring(start, pos)); } else m = n; if (!match('}')) throw new IllegalArgumentException("expected '}' at position " + pos); if (m == -1) e = makeRepeat(e, n); else e = makeRepeat(e, n, m); } } return e; } final RegExp parseComplExp() throws IllegalArgumentException { if (check(COMPLEMENT) && match('~')) return makeComplement(parseComplExp()); else return parseCharClassExp(); } final RegExp parseCharClassExp() throws IllegalArgumentException { if (match('[')) { boolean negate = false; if (match('^')) negate = true; RegExp e = parseCharClasses(); if (negate) e = makeIntersection(makeAnyChar(), makeComplement(e)); if (!match(']')) throw new IllegalArgumentException("expected ']' at position " + pos); return e; } else return parseSimpleExp(); } final RegExp parseCharClasses() throws IllegalArgumentException { RegExp e = parseCharClass(); while (more() && !peek("]")) e = makeUnion(e, parseCharClass()); return e; } final RegExp parseCharClass() throws IllegalArgumentException { char c = parseCharExp(); if (match('-')) if (peek("]")) return makeUnion(makeChar(c), makeChar('-')); else return makeCharRange(c, parseCharExp()); else return makeChar(c); } final RegExp parseSimpleExp() throws IllegalArgumentException { if (match('.')) return makeAnyChar(); else if (check(EMPTY) && match('#')) return makeEmpty(); else if (check(ANYSTRING) && match('@')) return makeAnyString(); else if (match('"')) { int start = pos; while (more() && !peek("\"")) next(); if (!match('"')) throw new IllegalArgumentException("expected '\"' at position " + pos); return makeString(b.substring(start, pos - 1)); } else if (match('(')) { if (match(')')) return makeString(""); RegExp e = parseUnionExp(); if (!match(')')) throw new IllegalArgumentException("expected ')' at position " + pos); return e; } else if ((check(AUTOMATON) || check(INTERVAL)) && match('<')) { int start = pos; while (more() && !peek(">")) next(); if (!match('>')) throw new IllegalArgumentException("expected '>' at position " + pos); String s = b.substring(start, pos - 1); int i = s.indexOf('-'); if (i == -1) { if (!check(AUTOMATON)) throw new IllegalArgumentException("interval syntax error at position " + (pos - 1)); return makeAutomaton(s); } else { if (!check(INTERVAL)) throw new IllegalArgumentException("illegal identifier at position " + (pos - 1)); try { if (i == 0 || i == s.length() - 1 || i != s.lastIndexOf('-')) throw new NumberFormatException(); String smin = s.substring(0, i); String smax = s.substring(i + 1, s.length()); int imin = Integer.parseInt(smin); int imax = Integer.parseInt(smax); int digits; if (smin.length() == smax.length()) digits = smin.length(); else digits = 0; if (imin > imax) { int t = imin; imin = imax; imax = t; } return makeInterval(imin, imax, digits); } catch (NumberFormatException e) { throw new IllegalArgumentException("interval syntax error at position " + (pos - 1)); } } } else return makeChar(parseCharExp()); } final char parseCharExp() throws IllegalArgumentException { match('\\'); return next(); } } src/dk/brics/automaton/RunAutomaton.java000066400000000000000000000224661204272215500206650ustar00rootroot00000000000000/* * dk.brics.automaton * * Copyright (c) 2001-2011 Anders Moeller * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package dk.brics.automaton; import java.io.IOException; import java.io.InputStream; import java.io.InvalidClassException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.OptionalDataException; import java.io.OutputStream; import java.io.Serializable; import java.net.URL; import java.util.Set; /** * Finite-state automaton with fast run operation. * @author Anders Møller <amoeller@cs.au.dk> */ public class RunAutomaton implements Serializable { static final long serialVersionUID = 20001; int size; boolean[] accept; int initial; int[] transitions; // delta(state,c) = transitions[state*points.length + getCharClass(c)] char[] points; // char interval start points int[] classmap; // map from char number to class class /** * Sets alphabet table for optimal run performance. */ final void setAlphabet() { classmap = new int[Character.MAX_VALUE - Character.MIN_VALUE + 1]; int i = 0; for (int j = 0; j <= Character.MAX_VALUE - Character.MIN_VALUE; j++) { if (i + 1 < points.length && j == points[i + 1]) i++; classmap[j] = i; } } /** * Returns a string representation of this automaton. */ @Override public String toString() { StringBuilder b = new StringBuilder(); b.append("initial state: ").append(initial).append("\n"); for (int i = 0; i < size; i++) { b.append("state " + i); if (accept[i]) b.append(" [accept]:\n"); else b.append(" [reject]:\n"); for (int j = 0; j < points.length; j++) { int k = transitions[i * points.length + j]; if (k != -1) { char min = points[j]; char max; if (j + 1 < points.length) max = (char)(points[j + 1] - 1); else max = Character.MAX_VALUE; b.append(" "); Transition.appendCharString(min, b); if (min != max) { b.append("-"); Transition.appendCharString(max, b); } b.append(" -> ").append(k).append("\n"); } } } return b.toString(); } /** * Returns number of states in automaton. */ public int getSize() { return size; } /** * Returns acceptance status for given state. */ public boolean isAccept(int state) { return accept[state]; } /** * Returns initial state. */ public int getInitialState() { return initial; } /** * Returns array of character class interval start points. The array should * not be modified by the caller. */ public char[] getCharIntervals() { return points.clone(); } /** * Gets character class of given char. */ int getCharClass(char c) { return SpecialOperations.findIndex(c, points); } @SuppressWarnings("unused") private RunAutomaton() {} /** * Constructs a new RunAutomaton from a deterministic * Automaton. Same as RunAutomaton(a, true). * @param a an automaton */ public RunAutomaton(Automaton a) { this(a, true); } /** * Retrieves a serialized RunAutomaton located by a URL. * @param url URL of serialized automaton * @exception IOException if input/output related exception occurs * @exception OptionalDataException if the data is not a serialized object * @exception InvalidClassException if the class serial number does not match * @exception ClassCastException if the data is not a serialized RunAutomaton * @exception ClassNotFoundException if the class of the serialized object cannot be found */ public static RunAutomaton load(URL url) throws IOException, OptionalDataException, ClassCastException, ClassNotFoundException, InvalidClassException { return load(url.openStream()); } /** * Retrieves a serialized RunAutomaton from a stream. * @param stream input stream with serialized automaton * @exception IOException if input/output related exception occurs * @exception OptionalDataException if the data is not a serialized object * @exception InvalidClassException if the class serial number does not match * @exception ClassCastException if the data is not a serialized RunAutomaton * @exception ClassNotFoundException if the class of the serialized object cannot be found */ public static RunAutomaton load(InputStream stream) throws IOException, OptionalDataException, ClassCastException, ClassNotFoundException, InvalidClassException { ObjectInputStream s = new ObjectInputStream(stream); return (RunAutomaton) s.readObject(); } /** * Writes this RunAutomaton to the given stream. * @param stream output stream for serialized automaton * @exception IOException if input/output related exception occurs */ public void store(OutputStream stream) throws IOException { ObjectOutputStream s = new ObjectOutputStream(stream); s.writeObject(this); s.flush(); } /** * Constructs a new RunAutomaton from a deterministic * Automaton. If the given automaton is not deterministic, * it is determinized first. * @param a an automaton * @param tableize if true, a transition table is created which makes the run * method faster in return of a higher memory usage */ public RunAutomaton(Automaton a, boolean tableize) { a.determinize(); points = a.getStartPoints(); Set states = a.getStates(); Automaton.setStateNumbers(states); initial = a.initial.number; size = states.size(); accept = new boolean[size]; transitions = new int[size * points.length]; for (int n = 0; n < size * points.length; n++) transitions[n] = -1; for (State s : states) { int n = s.number; accept[n] = s.accept; for (int c = 0; c < points.length; c++) { State q = s.step(points[c]); if (q != null) transitions[n * points.length + c] = q.number; } } if (tableize) setAlphabet(); } /** * Returns the state obtained by reading the given char from the given * state. Returns -1 if not obtaining any such state. (If the original * Automaton had no dead states, -1 is returned here if and * only if a dead state is entered in an equivalent automaton with a total * transition function.) */ public int step(int state, char c) { if (classmap == null) return transitions[state * points.length + getCharClass(c)]; else return transitions[state * points.length + classmap[c - Character.MIN_VALUE]]; } /** * Returns true if the given string is accepted by this automaton. */ public boolean run(String s) { int p = initial; int l = s.length(); for (int i = 0; i < l; i++) { p = step(p, s.charAt(i)); if (p == -1) return false; } return accept[p]; } /** * Returns the length of the longest accepted run of the given string * starting at the given offset. * @param s the string * @param offset offset into s where the run starts * @return length of the longest accepted run, -1 if no run is accepted */ public int run(String s, int offset) { int p = initial; int l = s.length(); int max = -1; for (int r = 0; offset <= l; offset++, r++) { if (accept[p]) max = r; if (offset == l) break; p = step(p, s.charAt(offset)); if (p == -1) break; } return max; } /** * Creates a new automaton matcher for the given input. * @param s the CharSequence to search * @return A new automaton matcher for the given input */ public AutomatonMatcher newMatcher(CharSequence s) { return new AutomatonMatcher(s, this); } /** * Creates a new automaton matcher for the given input. * @param s the CharSequence to search * @param startOffset the starting offset of the given character sequence * @param endOffset the ending offset of the given character sequence * @return A new automaton matcher for the given input */ public AutomatonMatcher newMatcher(CharSequence s, int startOffset, int endOffset) { return new AutomatonMatcher(s.subSequence(startOffset, endOffset), this); } } src/dk/brics/automaton/ShuffleOperations.java000066400000000000000000000274431204272215500216710ustar00rootroot00000000000000/* * dk.brics.automaton * * Copyright (c) 2001-2011 Anders Moeller * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package dk.brics.automaton; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Set; /** * Automata operations involving shuffling. */ final public class ShuffleOperations { private ShuffleOperations() {} /** * Returns an automaton that accepts the shuffle (interleaving) of * the languages of the given automata. * As a side-effect, both automata are determinized, if not already deterministic. * Never modifies the input automata languages. *

* Complexity: quadratic in number of states (if already deterministic). *

*

Author:
Torben Ruby * <ruby@daimi.au.dk>
*/ public static Automaton shuffle(Automaton a1, Automaton a2) { a1.determinize(); a2.determinize(); Transition[][] transitions1 = Automaton.getSortedTransitions(a1.getStates()); Transition[][] transitions2 = Automaton.getSortedTransitions(a2.getStates()); Automaton c = new Automaton(); LinkedList worklist = new LinkedList(); HashMap newstates = new HashMap(); State s = new State(); c.initial = s; StatePair p = new StatePair(s, a1.initial, a2.initial); worklist.add(p); newstates.put(p, p); while (worklist.size() > 0) { p = worklist.removeFirst(); p.s.accept = p.s1.accept && p.s2.accept; Transition[] t1 = transitions1[p.s1.number]; for (int n1 = 0; n1 < t1.length; n1++) { StatePair q = new StatePair(t1[n1].to, p.s2); StatePair r = newstates.get(q); if (r == null) { q.s = new State(); worklist.add(q); newstates.put(q, q); r = q; } p.s.transitions.add(new Transition(t1[n1].min, t1[n1].max, r.s)); } Transition[] t2 = transitions2[p.s2.number]; for (int n2 = 0; n2 < t2.length; n2++) { StatePair q = new StatePair(p.s1, t2[n2].to); StatePair r = newstates.get(q); if (r == null) { q.s = new State(); worklist.add(q); newstates.put(q, q); r = q; } p.s.transitions.add(new Transition(t2[n2].min, t2[n2].max, r.s)); } } c.deterministic = false; c.removeDeadTransitions(); c.checkMinimizeAlways(); return c; } /** * Returns a string that is an interleaving of strings that are accepted by * ca but not by a. If no such string * exists, null is returned. As a side-effect, a is determinized, * if not already deterministic. Only interleavings that respect * the suspend/resume markers (two BMP private code points) are considered if the markers are non-null. * Also, interleavings never split surrogate pairs. *

* Complexity: proportional to the product of the numbers of states (if a * is already deterministic). */ public static String shuffleSubsetOf(Collection ca, Automaton a, Character suspend_shuffle, Character resume_shuffle) { if (ca.size() == 0) return null; if (ca.size() == 1) { Automaton a1 = ca.iterator().next(); if (a1.isSingleton()) { if (a.run(a1.singleton)) return null; else return a1.singleton; } if (a1 == a) return null; } a.determinize(); Transition[][][] ca_transitions = new Transition[ca.size()][][]; int i = 0; for (Automaton a1 : ca) ca_transitions[i++] = Automaton.getSortedTransitions(a1.getStates()); Transition[][] a_transitions = Automaton.getSortedTransitions(a.getStates()); TransitionComparator tc = new TransitionComparator(false); ShuffleConfiguration init = new ShuffleConfiguration(ca, a); LinkedList pending = new LinkedList(); Set visited = new HashSet(); pending.add(init); visited.add(init); while (!pending.isEmpty()) { ShuffleConfiguration c = pending.removeFirst(); boolean good = true; for (int i1 = 0; i1 < ca.size(); i1++) if (!c.ca_states[i1].accept) { good = false; break; } if (c.a_state.accept) good = false; if (good) { StringBuilder sb = new StringBuilder(); while (c.prev != null) { sb.append(c.min); c = c.prev; } StringBuilder sb2 = new StringBuilder(); for (int j = sb.length() - 1; j >= 0; j--) sb2.append(sb.charAt(j)); return sb2.toString(); } Transition[] ta2 = a_transitions[c.a_state.number]; for (int i1 = 0; i1 < ca.size(); i1++) { if (c.shuffle_suspended) i1 = c.suspended1; loop: for (Transition t1 : ca_transitions[i1][c.ca_states[i1].number]) { List lt = new ArrayList(); int j = Arrays.binarySearch(ta2, t1, tc); if (j < 0) j = -j - 1; if (j > 0 && ta2[j - 1].max >= t1.min) j--; while (j < ta2.length) { Transition t2 = ta2[j++]; char min = t1.min; char max = t1.max; if (t2.min > min) min = t2.min; if (t2.max < max) max = t2.max; if (min <= max) { add(suspend_shuffle, resume_shuffle, pending, visited, c, i1, t1, t2, min, max); lt.add(new Transition(min, max, null)); } else break; } Transition[] at = lt.toArray(new Transition[lt.size()]); Arrays.sort(at, tc); char min = t1.min; for (int k = 0; k < at.length; k++) { if (at[k].min > min) break; if (at[k].max >= t1.max) continue loop; min = (char)(at[k].max + 1); } ShuffleConfiguration nc = new ShuffleConfiguration(c, i1, t1.to, min); StringBuilder sb = new StringBuilder(); ShuffleConfiguration b = nc; while (b.prev != null) { sb.append(b.min); b = b.prev; } StringBuilder sb2 = new StringBuilder(); for (int m = sb.length() - 1; m >= 0; m--) sb2.append(sb.charAt(m)); if (c.shuffle_suspended) sb2.append(BasicOperations.getShortestExample(nc.ca_states[c.suspended1], true)); for (i1 = 0; i1 < ca.size(); i1++) if (!c.shuffle_suspended || i1 != c.suspended1) sb2.append(BasicOperations.getShortestExample(nc.ca_states[i1], true)); return sb2.toString(); } if (c.shuffle_suspended) break; } } return null; } private static void add(Character suspend_shuffle, Character resume_shuffle, LinkedList pending, Set visited, ShuffleConfiguration c, int i1, Transition t1, Transition t2, char min, char max) { final char HIGH_SURROGATE_BEGIN = '\uD800'; final char HIGH_SURROGATE_END = '\uDBFF'; if (suspend_shuffle != null && min <= suspend_shuffle && suspend_shuffle <= max && min != max) { if (min < suspend_shuffle) add(suspend_shuffle, resume_shuffle, pending, visited, c, i1, t1, t2, min, (char)(suspend_shuffle - 1)); add(suspend_shuffle, resume_shuffle, pending, visited, c, i1, t1, t2, suspend_shuffle, suspend_shuffle); if (suspend_shuffle < max) add(suspend_shuffle, resume_shuffle, pending, visited, c, i1, t1, t2, (char)(suspend_shuffle + 1), max); } else if (resume_shuffle != null && min <= resume_shuffle && resume_shuffle <= max && min != max) { if (min < resume_shuffle) add(suspend_shuffle, resume_shuffle, pending, visited, c, i1, t1, t2, min, (char)(resume_shuffle - 1)); add(suspend_shuffle, resume_shuffle, pending, visited, c, i1, t1, t2, resume_shuffle, resume_shuffle); if (resume_shuffle < max) add(suspend_shuffle, resume_shuffle, pending, visited, c, i1, t1, t2, (char)(resume_shuffle + 1), max); } else if (min < HIGH_SURROGATE_BEGIN && max >= HIGH_SURROGATE_BEGIN) { add(suspend_shuffle, resume_shuffle, pending, visited, c, i1, t1, t2, min, (char)(HIGH_SURROGATE_BEGIN - 1)); add(suspend_shuffle, resume_shuffle, pending, visited, c, i1, t1, t2, HIGH_SURROGATE_BEGIN, max); } else if (min <= HIGH_SURROGATE_END && max > HIGH_SURROGATE_END) { add(suspend_shuffle, resume_shuffle, pending, visited, c, i1, t1, t2, min, HIGH_SURROGATE_END); add(suspend_shuffle, resume_shuffle, pending, visited, c, i1, t1, t2, (char)(HIGH_SURROGATE_END + 1), max); } else { ShuffleConfiguration nc = new ShuffleConfiguration(c, i1, t1.to, t2.to, min); if (suspend_shuffle != null && min == suspend_shuffle) { nc.shuffle_suspended = true; nc.suspended1 = i1; } else if (resume_shuffle != null && min == resume_shuffle) nc.shuffle_suspended = false; if (min >= HIGH_SURROGATE_BEGIN && min <= HIGH_SURROGATE_BEGIN) { nc.shuffle_suspended = true; nc.suspended1 = i1; nc.surrogate = true; } if (!visited.contains(nc)) { pending.add(nc); visited.add(nc); } } } static class ShuffleConfiguration { ShuffleConfiguration prev; State[] ca_states; State a_state; char min; int hash; boolean shuffle_suspended; boolean surrogate; int suspended1; @SuppressWarnings("unused") private ShuffleConfiguration() {} ShuffleConfiguration(Collection ca, Automaton a) { ca_states = new State[ca.size()]; int i = 0; for (Automaton a1 : ca) ca_states[i++] = a1.getInitialState(); a_state = a.getInitialState(); computeHash(); } ShuffleConfiguration(ShuffleConfiguration c, int i1, State s1, char min) { prev = c; ca_states = c.ca_states.clone(); a_state = c.a_state; ca_states[i1] = s1; this.min = min; computeHash(); } ShuffleConfiguration(ShuffleConfiguration c, int i1, State s1, State s2, char min) { prev = c; ca_states = c.ca_states.clone(); a_state = c.a_state; ca_states[i1] = s1; a_state = s2; this.min = min; if (!surrogate) { shuffle_suspended = c.shuffle_suspended; suspended1 = c.suspended1; } computeHash(); } @Override public boolean equals(Object obj) { if (obj instanceof ShuffleConfiguration) { ShuffleConfiguration c = (ShuffleConfiguration)obj; return shuffle_suspended == c.shuffle_suspended && surrogate == c.surrogate && suspended1 == c.suspended1 && Arrays.equals(ca_states, c.ca_states) && a_state == c.a_state; } return false; } @Override public int hashCode() { return hash; } private void computeHash() { hash = 0; for (int i = 0; i < ca_states.length; i++) hash ^= ca_states[i].hashCode(); hash ^= a_state.hashCode() * 100; if (shuffle_suspended || surrogate) hash += suspended1; } } } src/dk/brics/automaton/SpecialOperations.java000066400000000000000000000450301204272215500216450ustar00rootroot00000000000000/* * dk.brics.automaton * * Copyright (c) 2001-2011 Anders Moeller * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package dk.brics.automaton; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import java.util.TreeSet; /** * Special automata operations. */ final public class SpecialOperations { private SpecialOperations() {} /** * Reverses the language of the given (non-singleton) automaton while returning * the set of new initial states. */ public static Set reverse(Automaton a) { // reverse all edges HashMap> m = new HashMap>(); Set states = a.getStates(); Set accept = a.getAcceptStates(); for (State r : states) { m.put(r, new HashSet()); r.accept = false; } for (State r : states) for (Transition t : r.getTransitions()) m.get(t.to).add(new Transition(t.min, t.max, r)); for (State r : states) r.transitions = m.get(r); // make new initial+final states a.initial.accept = true; a.initial = new State(); for (State r : accept) a.initial.addEpsilon(r); // ensures that all initial states are reachable a.deterministic = false; return accept; } /** * Returns an automaton that accepts the overlap of strings that in more than one way can be split into * a left part being accepted by a1 and a right part being accepted by * a2. */ public static Automaton overlap(Automaton a1, Automaton a2) { Automaton b1 = a1.cloneExpanded(); b1.determinize(); acceptToAccept(b1); Automaton b2 = a2.cloneExpanded(); reverse(b2); b2.determinize(); acceptToAccept(b2); reverse(b2); b2.determinize(); return b1.intersection(b2).minus(BasicAutomata.makeEmptyString()); } private static void acceptToAccept(Automaton a) { State s = new State(); for (State r : a.getAcceptStates()) s.addEpsilon(r); a.initial = s; a.deterministic = false; } /** * Returns an automaton that accepts the single chars that occur * in strings that are accepted by the given automaton. * Never modifies the input automaton. */ public static Automaton singleChars(Automaton a) { Automaton b = new Automaton(); State s = new State(); b.initial = s; State q = new State(); q.accept = true; if (a.isSingleton()) for (int i = 0; i < a.singleton.length(); i++) s.transitions.add(new Transition(a.singleton.charAt(i), q)); else for (State p : a.getStates()) for (Transition t : p.transitions) s.transitions.add(new Transition(t.min, t.max, q)); b.deterministic = true; b.removeDeadTransitions(); return b; } /** * Returns an automaton that accepts the trimmed language of the given * automaton. The resulting automaton is constructed as follows: 1) Whenever * a c character is allowed in the original automaton, one or * more set characters are allowed in the new automaton. 2) * The automaton is prefixed and postfixed with any number of * set characters. * @param set set of characters to be trimmed * @param c canonical trim character (assumed to be in set) */ public static Automaton trim(Automaton a, String set, char c) { a = a.cloneExpandedIfRequired(); State f = new State(); addSetTransitions(f, set, f); f.accept = true; for (State s : a.getStates()) { State r = s.step(c); if (r != null) { // add inner State q = new State(); addSetTransitions(q, set, q); addSetTransitions(s, set, q); q.addEpsilon(r); } // add postfix if (s.accept) s.addEpsilon(f); } // add prefix State p = new State(); addSetTransitions(p, set, p); p.addEpsilon(a.initial); a.initial = p; a.deterministic = false; a.removeDeadTransitions(); a.checkMinimizeAlways(); return a; } private static void addSetTransitions(State s, String set, State p) { for (int n = 0; n < set.length(); n++) s.transitions.add(new Transition(set.charAt(n), p)); } /** * Returns an automaton that accepts the compressed language of the given * automaton. Whenever a c character is allowed in the * original automaton, one or more set characters are allowed * in the new automaton. * @param set set of characters to be compressed * @param c canonical compress character (assumed to be in set) */ public static Automaton compress(Automaton a, String set, char c) { a = a.cloneExpandedIfRequired(); for (State s : a.getStates()) { State r = s.step(c); if (r != null) { // add inner State q = new State(); addSetTransitions(q, set, q); addSetTransitions(s, set, q); q.addEpsilon(r); } } // add prefix a.deterministic = false; a.removeDeadTransitions(); a.checkMinimizeAlways(); return a; } /** * Returns an automaton where all transition labels have been substituted. *

* Each transition labeled c is changed to a set of * transitions, one for each character in map(c). If * map(c) is null, then the transition is unchanged. * @param map map from characters to sets of characters (where characters * are Character objects) */ public static Automaton subst(Automaton a, Map> map) { if (map.isEmpty()) return a.cloneIfRequired(); Set ckeys = new TreeSet(map.keySet()); char[] keys = new char[ckeys.size()]; int j = 0; for (Character c : ckeys) keys[j++] = c; a = a.cloneExpandedIfRequired(); for (State s : a.getStates()) { Set st = s.transitions; s.resetTransitions(); for (Transition t : st) { int index = findIndex(t.min, keys); while (t.min <= t.max) { if (keys[index] > t.min) { char m = (char)(keys[index] - 1); if (t.max < m) m = t.max; s.transitions.add(new Transition(t.min, m, t.to)); if (m + 1 > Character.MAX_VALUE) break; t.min = (char)(m + 1); } else if (keys[index] < t.min) { char m; if (index + 1 < keys.length) m = (char)(keys[++index] - 1); else m = Character.MAX_VALUE; if (t.max < m) m = t.max; s.transitions.add(new Transition(t.min, m, t.to)); if (m + 1 > Character.MAX_VALUE) break; t.min = (char)(m + 1); } else { // found t.min in substitution map for (Character c : map.get(t.min)) s.transitions.add(new Transition(c, t.to)); if (t.min + 1 > Character.MAX_VALUE) break; t.min++; if (index + 1 < keys.length && keys[index + 1] == t.min) index++; } } } } a.deterministic = false; a.removeDeadTransitions(); a.checkMinimizeAlways(); return a; } /** * Finds the largest entry whose value is less than or equal to c, * or 0 if there is no such entry. */ static int findIndex(char c, char[] points) { int a = 0; int b = points.length; while (b - a > 1) { int d = (a + b) >>> 1; if (points[d] > c) b = d; else if (points[d] < c) a = d; else return d; } return a; } /** * Returns an automaton where all transitions of the given char are replaced by a string. * @param c char * @param s string * @return new automaton */ public static Automaton subst(Automaton a, char c, String s) { a = a.cloneExpandedIfRequired(); Set epsilons = new HashSet(); for (State p : a.getStates()) { Set st = p.transitions; p.resetTransitions(); for (Transition t : st) if (t.max < c || t.min > c) p.transitions.add(t); else { if (t.min < c) p.transitions.add(new Transition(t.min, (char)(c - 1), t.to)); if (t.max > c) p.transitions.add(new Transition((char)(c + 1), t.max, t.to)); if (s.length() == 0) epsilons.add(new StatePair(p, t.to)); else { State q = p; for (int i = 0; i < s.length(); i++) { State r; if (i + 1 == s.length()) r = t.to; else r = new State(); q.transitions.add(new Transition(s.charAt(i), r)); q = r; } } } } a.addEpsilons(epsilons); a.deterministic = false; a.removeDeadTransitions(); a.checkMinimizeAlways(); return a; } /** * Returns an automaton accepting the homomorphic image of the given automaton * using the given function. *

* This method maps each transition label to a new value. * source and dest are assumed to be arrays of * same length, and source must be sorted in increasing order * and contain no duplicates. source defines the starting * points of char intervals, and the corresponding entries in * dest define the starting points of corresponding new * intervals. */ public static Automaton homomorph(Automaton a, char[] source, char[] dest) { a = a.cloneExpandedIfRequired(); for (State s : a.getStates()) { Set st = s.transitions; s.resetTransitions(); for (Transition t : st) { int min = t.min; while (min <= t.max) { int n = findIndex((char)min, source); char nmin = (char)(dest[n] + min - source[n]); int end = (n + 1 == source.length) ? Character.MAX_VALUE : source[n + 1] - 1; int length; if (end < t.max) length = end + 1 - min; else length = t.max + 1 - min; s.transitions.add(new Transition(nmin, (char)(nmin + length - 1), t.to)); min += length; } } } a.deterministic = false; a.removeDeadTransitions(); a.checkMinimizeAlways(); return a; } /** * Returns an automaton with projected alphabet. The new automaton accepts * all strings that are projections of strings accepted by the given automaton * onto the given characters (represented by Character). If * null is in the set, it abbreviates the intervals * u0000-uDFFF and uF900-uFFFF (i.e., the non-private code points). It is * assumed that all other characters from chars are in the * interval uE000-uF8FF. */ public static Automaton projectChars(Automaton a, Set chars) { Character[] c = chars.toArray(new Character[chars.size()]); char[] cc = new char[c.length]; boolean normalchars = false; for (int i = 0; i < c.length; i++) if (c[i] == null) normalchars = true; else cc[i] = c[i]; Arrays.sort(cc); if (a.isSingleton()) { for (int i = 0; i < a.singleton.length(); i++) { char sc = a.singleton.charAt(i); if (!(normalchars && (sc <= '\udfff' || sc >= '\uf900') || Arrays.binarySearch(cc, sc) >= 0)) return BasicAutomata.makeEmpty(); } return a.cloneIfRequired(); } else { HashSet epsilons = new HashSet(); a = a.cloneExpandedIfRequired(); for (State s : a.getStates()) { HashSet new_transitions = new HashSet(); for (Transition t : s.transitions) { boolean addepsilon = false; if (t.min < '\uf900' && t.max > '\udfff') { int w1 = Arrays.binarySearch(cc, t.min > '\ue000' ? t.min : '\ue000'); if (w1 < 0) { w1 = -w1 - 1; addepsilon = true; } int w2 = Arrays.binarySearch(cc, t.max < '\uf8ff' ? t.max : '\uf8ff'); if (w2 < 0) { w2 = -w2 - 2; addepsilon = true; } for (int w = w1; w <= w2; w++) { new_transitions.add(new Transition(cc[w], t.to)); if (w > w1 && cc[w - 1] + 1 != cc[w]) addepsilon = true; } } if (normalchars) { if (t.min <= '\udfff') new_transitions.add(new Transition(t.min, t.max < '\udfff' ? t.max : '\udfff', t.to)); if (t.max >= '\uf900') new_transitions.add(new Transition(t.min > '\uf900' ? t.min : '\uf900', t.max, t.to)); } else if (t.min <= '\udfff' || t.max >= '\uf900') addepsilon = true; if (addepsilon) epsilons.add(new StatePair(s, t.to)); } s.transitions = new_transitions; } a.reduce(); a.addEpsilons(epsilons); a.removeDeadTransitions(); a.checkMinimizeAlways(); return a; } } /** * Returns true if the language of this automaton is finite. */ public static boolean isFinite(Automaton a) { if (a.isSingleton()) return true; return isFinite(a.initial, new HashSet(), new HashSet()); } /** * Checks whether there is a loop containing s. (This is sufficient since * there are never transitions to dead states.) */ private static boolean isFinite(State s, HashSet path, HashSet visited) { path.add(s); for (Transition t : s.transitions) if (path.contains(t.to) || (!visited.contains(t.to) && !isFinite(t.to, path, visited))) return false; path.remove(s); visited.add(s); return true; } /** * Returns the set of accepted strings of the given length. */ public static Set getStrings(Automaton a, int length) { HashSet strings = new HashSet(); if (a.isSingleton() && a.singleton.length() == length) strings.add(a.singleton); else if (length >= 0) getStrings(a.initial, strings, new StringBuilder(), length); return strings; } private static void getStrings(State s, Set strings, StringBuilder path, int length) { if (length == 0) { if (s.accept) strings.add(path.toString()); } else for (Transition t : s.transitions) for (int n = t.min; n <= t.max; n++) { path.append((char)n); getStrings(t.to, strings, path, length - 1); path.deleteCharAt(path.length() - 1); } } /** * Returns the set of accepted strings, assuming this automaton has a finite * language. If the language is not finite, null is returned. */ public static Set getFiniteStrings(Automaton a) { HashSet strings = new HashSet(); if (a.isSingleton()) strings.add(a.singleton); else if (!getFiniteStrings(a.initial, new HashSet(), strings, new StringBuilder(), -1)) return null; return strings; } /** * Returns the set of accepted strings, assuming that at most limit * strings are accepted. If more than limit strings are * accepted, null is returned. If limit<0, then this * methods works like {@link #getFiniteStrings(Automaton)}. */ public static Set getFiniteStrings(Automaton a, int limit) { HashSet strings = new HashSet(); if (a.isSingleton()) { if (limit > 0) strings.add(a.singleton); else return null; } else if (!getFiniteStrings(a.initial, new HashSet(), strings, new StringBuilder(), limit)) return null; return strings; } /** * Returns the strings that can be produced from the given state, or false if more than * limit strings are found. limit<0 means "infinite". * */ private static boolean getFiniteStrings(State s, HashSet pathstates, HashSet strings, StringBuilder path, int limit) { pathstates.add(s); for (Transition t : s.transitions) { if (pathstates.contains(t.to)) return false; for (int n = t.min; n <= t.max; n++) { path.append((char)n); if (t.to.accept) { strings.add(path.toString()); if (limit >= 0 && strings.size() > limit) return false; } if (!getFiniteStrings(t.to, pathstates, strings, path, limit)) return false; path.deleteCharAt(path.length() - 1); } } pathstates.remove(s); return true; } /** * Returns the longest string that is a prefix of all accepted strings and * visits each state at most once. * @return common prefix */ public static String getCommonPrefix(Automaton a) { if (a.isSingleton()) return a.singleton; StringBuilder b = new StringBuilder(); HashSet visited = new HashSet(); State s = a.initial; boolean done; do { done = true; visited.add(s); if (!s.accept && s.transitions.size() == 1) { Transition t = s.transitions.iterator().next(); if (t.min == t.max && !visited.contains(t.to)) { b.append(t.min); s = t.to; done = false; } } } while (!done); return b.toString(); } /** * Prefix closes the given automaton. */ public static void prefixClose(Automaton a) { for (State s : a.getStates()) s.setAccept(true); a.clearHashCode(); a.checkMinimizeAlways(); } /** * Constructs automaton that accepts the same strings as the given automaton * but ignores upper/lower case of A-F. * @param a automaton * @return automaton */ public static Automaton hexCases(Automaton a) { Map> map = new HashMap>(); for (char c1 = 'a', c2 = 'A'; c1 <= 'f'; c1++, c2++) { Set ws = new HashSet(); ws.add(c1); ws.add(c2); map.put(c1, ws); map.put(c2, ws); } Automaton ws = Datatypes.getWhitespaceAutomaton(); return ws.concatenate(a.subst(map)).concatenate(ws); } /** * Constructs automaton that accepts 0x20, 0x9, 0xa, and 0xd in place of each 0x20 transition * in the given automaton. * @param a automaton * @return automaton */ public static Automaton replaceWhitespace(Automaton a) { Map> map = new HashMap>(); Set ws = new HashSet(); ws.add(' '); ws.add('\t'); ws.add('\n'); ws.add('\r'); map.put(' ', ws); return a.subst(map); } } src/dk/brics/automaton/State.java000066400000000000000000000122071204272215500173010ustar00rootroot00000000000000/* * dk.brics.automaton * * Copyright (c) 2001-2011 Anders Moeller * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package dk.brics.automaton; import java.io.Serializable; import java.util.Arrays; import java.util.Collection; import java.util.HashSet; import java.util.List; import java.util.Set; /** * Automaton state. * @author Anders Møller <amoeller@cs.au.dk> */ public class State implements Serializable, Comparable { static final long serialVersionUID = 30001; boolean accept; Set transitions; int number; int id; static int next_id; /** * Constructs a new state. Initially, the new state is a reject state. */ public State() { resetTransitions(); id = next_id++; } /** * Resets transition set. */ final void resetTransitions() { transitions = new HashSet(); } /** * Returns the set of outgoing transitions. * Subsequent changes are reflected in the automaton. * @return transition set */ public Set getTransitions() { return transitions; } /** * Adds an outgoing transition. * @param t transition */ public void addTransition(Transition t) { transitions.add(t); } /** * Sets acceptance for this state. * @param accept if true, this state is an accept state */ public void setAccept(boolean accept) { this.accept = accept; } /** * Returns acceptance status. * @return true is this is an accept state */ public boolean isAccept() { return accept; } /** * Performs lookup in transitions, assuming determinism. * @param c character to look up * @return destination state, null if no matching outgoing transition * @see #step(char, Collection) */ public State step(char c) { for (Transition t : transitions) if (t.min <= c && c <= t.max) return t.to; return null; } /** * Performs lookup in transitions, allowing nondeterminism. * @param c character to look up * @param dest collection where destination states are stored * @see #step(char) */ public void step(char c, Collection dest) { for (Transition t : transitions) if (t.min <= c && c <= t.max) dest.add(t.to); } void addEpsilon(State to) { if (to.accept) accept = true; for (Transition t : to.transitions) transitions.add(t); } /** Returns transitions sorted by (min, reverse max, to) or (to, min, reverse max) */ Transition[] getSortedTransitionArray(boolean to_first) { Transition[] e = transitions.toArray(new Transition[transitions.size()]); Arrays.sort(e, new TransitionComparator(to_first)); return e; } /** * Returns sorted list of outgoing transitions. * @param to_first if true, order by (to, min, reverse max); otherwise (min, reverse max, to) * @return transition list */ public List getSortedTransitions(boolean to_first) { return Arrays.asList(getSortedTransitionArray(to_first)); } /** * Returns string describing this state. Normally invoked via * {@link Automaton#toString()}. */ @Override public String toString() { StringBuilder b = new StringBuilder(); b.append("state ").append(number); if (accept) b.append(" [accept]"); else b.append(" [reject]"); b.append(":\n"); for (Transition t : transitions) b.append(" ").append(t.toString()).append("\n"); return b.toString(); } /** * Compares this object with the specified object for order. * States are ordered by the time of construction. */ public int compareTo(State s) { return s.id - id; } /** * See {@link java.lang.Object#equals(java.lang.Object)}. */ @Override public boolean equals(Object obj) { return super.equals(obj); } /** * See {@link java.lang.Object#hashCode()}. */ @Override public int hashCode() { return super.hashCode(); } } src/dk/brics/automaton/StatePair.java000066400000000000000000000052311204272215500201140ustar00rootroot00000000000000/* * dk.brics.automaton * * Copyright (c) 2001-2011 Anders Moeller * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package dk.brics.automaton; /** * Pair of states. * @author Anders Møller <amoeller@cs.au.dk> */ public class StatePair { State s; State s1; State s2; StatePair(State s, State s1, State s2) { this.s = s; this.s1 = s1; this.s2 = s2; } /** * Constructs a new state pair. * @param s1 first state * @param s2 second state */ public StatePair(State s1, State s2) { this.s1 = s1; this.s2 = s2; } /** * Returns first component of this pair. * @return first state */ public State getFirstState() { return s1; } /** * Returns second component of this pair. * @return second state */ public State getSecondState() { return s2; } /** * Checks for equality. * @param obj object to compare with * @return true if obj represents the same pair of states as this pair */ @Override public boolean equals(Object obj) { if (obj instanceof StatePair) { StatePair p = (StatePair)obj; return p.s1 == s1 && p.s2 == s2; } else return false; } /** * Returns hash code. * @return hash code */ @Override public int hashCode() { return s1.hashCode() + s2.hashCode(); } } src/dk/brics/automaton/StringUnionOperations.java000066400000000000000000000224031204272215500225430ustar00rootroot00000000000000package dk.brics.automaton; import java.util.Arrays; import java.util.Comparator; import java.util.HashMap; import java.util.IdentityHashMap; /** * Operations for building minimal deterministic automata from sets of strings. * The algorithm requires sorted input data, but is very fast (nearly linear with the input size). * * @author Dawid Weiss */ final public class StringUnionOperations { /** * Lexicographic order of input sequences. */ public final static Comparator LEXICOGRAPHIC_ORDER = new Comparator() { public int compare(CharSequence s1, CharSequence s2) { final int lens1 = s1.length(); final int lens2 = s2.length(); final int max = Math.min(lens1, lens2); for (int i = 0; i < max; i++) { final char c1 = s1.charAt(i); final char c2 = s2.charAt(i); if (c1 != c2) return c1 - c2; } return lens1 - lens2; } }; /** * State with char labels on transitions. */ final static class State { /** An empty set of labels. */ private final static char[] NO_LABELS = new char[0]; /** An empty set of states. */ private final static State[] NO_STATES = new State[0]; /** * Labels of outgoing transitions. Indexed identically to {@link #states}. * Labels must be sorted lexicographically. */ char[] labels = NO_LABELS; /** * States reachable from outgoing transitions. Indexed identically to * {@link #labels}. */ State[] states = NO_STATES; /** * true if this state corresponds to the end of at least one * input sequence. */ boolean is_final; /** * Returns the target state of a transition leaving this state and labeled * with label. If no such transition exists, returns * null. */ public State getState(char label) { final int index = Arrays.binarySearch(labels, label); return index >= 0 ? states[index] : null; } /** * Returns an array of outgoing transition labels. The array is sorted in * lexicographic order and indexes correspond to states returned from * {@link #getStates()}. */ public char [] getTransitionLabels() { return this.labels; } /** * Returns an array of outgoing transitions from this state. The returned * array must not be changed. */ public State[] getStates() { return this.states; } /** * Two states are equal if: *

    *
  • they have an identical number of outgoing transitions, labeled with * the same labels
  • *
  • corresponding outgoing transitions lead to the same states (to states * with an identical right-language). *
*/ @Override public boolean equals(Object obj) { final State other = (State) obj; return is_final == other.is_final && Arrays.equals(this.labels, other.labels) && referenceEquals(this.states, other.states); } /** * Return true if this state has any children (outgoing * transitions). */ public boolean hasChildren() { return labels.length > 0; } /** * Is this state a final state in the automaton? */ public boolean isFinal() { return is_final; } /** * Compute the hash code of the current status of this state. */ @Override public int hashCode() { int hash = is_final ? 1 : 0; hash ^= hash * 31 + this.labels.length; for (char c : this.labels) hash ^= hash * 31 + c; /* * Compare the right-language of this state using reference-identity of * outgoing states. This is possible because states are interned (stored * in registry) and traversed in post-order, so any outgoing transitions * are already interned. */ for (State s : this.states) { hash ^= System.identityHashCode(s); } return hash; } /** * Create a new outgoing transition labeled label and return * the newly created target state for this transition. */ State newState(char label) { assert Arrays.binarySearch(labels, label) < 0 : "State already has transition labeled: " + label; labels = copyOf(labels, labels.length + 1); states = copyOf(states, states.length + 1); labels[labels.length - 1] = label; return states[states.length - 1] = new State(); } /** * Return the most recent transitions's target state. */ State lastChild() { assert hasChildren() : "No outgoing transitions."; return states[states.length - 1]; } /** * Return the associated state if the most recent transition * is labeled with label. */ State lastChild(char label) { final int index = labels.length - 1; State s = null; if (index >= 0 && labels[index] == label) { s = states[index]; } assert s == getState(label); return s; } /** * Replace the last added outgoing transition's target state with the given * state. */ void replaceLastChild(State state) { assert hasChildren() : "No outgoing transitions."; states[states.length - 1] = state; } /** * JDK1.5-replacement of {@link Arrays#copyOf(char[], int)} */ private static char[] copyOf(char[] original, int newLength) { char[] copy = new char[newLength]; System.arraycopy(original, 0, copy, 0, Math.min(original.length, newLength)); return copy; } /** * JDK1.5-replacement of {@link Arrays#copyOf(char[], int)} */ public static State[] copyOf(State[] original, int newLength) { State[] copy = new State[newLength]; System.arraycopy(original, 0, copy, 0, Math.min(original.length, newLength)); return copy; } /** * Compare two lists of objects for reference-equality. */ private static boolean referenceEquals(Object[] a1, Object[] a2) { if (a1.length != a2.length) return false; for (int i = 0; i < a1.length; i++) if (a1[i] != a2[i]) return false; return true; } } /** * "register" for state interning. */ private HashMap register = new HashMap(); /** * Root automaton state. */ private State root = new State(); /** * Previous sequence added to the automaton in {@link #add(CharSequence)}. */ private StringBuilder previous; /** * Add another character sequence to this automaton. The sequence must be * lexicographically larger or equal compared to any previous sequences * added to this automaton (the input must be sorted). */ public void add(CharSequence current) { assert register != null : "Automaton already built."; assert current.length() > 0 : "Input sequences must not be empty."; assert previous == null || LEXICOGRAPHIC_ORDER.compare(previous, current) <= 0 : "Input must be sorted: " + previous + " >= " + current; assert setPrevious(current); // Descend in the automaton (find matching prefix). int pos = 0, max = current.length(); State next, state = root; while (pos < max && (next = state.lastChild(current.charAt(pos))) != null) { state = next; pos++; } if (state.hasChildren()) replaceOrRegister(state); addSuffix(state, current, pos); } /** * Finalize the automaton and return the root state. No more strings can be * added to the builder after this call. * * @return Root automaton state. */ public State complete() { if (this.register == null) throw new IllegalStateException(); if (root.hasChildren()) replaceOrRegister(root); register = null; return root; } /** * Internal recursive traversal for conversion. */ private static dk.brics.automaton.State convert(State s, IdentityHashMap visited) { dk.brics.automaton.State converted = visited.get(s); if (converted != null) return converted; converted = new dk.brics.automaton.State(); converted.setAccept(s.is_final); visited.put(s, converted); int i = 0; char [] labels = s.labels; for (StringUnionOperations.State target : s.states) { converted.addTransition(new Transition(labels[i++], convert(target, visited))); } return converted; } /** * Build a minimal, deterministic automaton from a sorted list of strings. */ public static dk.brics.automaton.State build(CharSequence[] input) { final StringUnionOperations builder = new StringUnionOperations(); for (CharSequence chs : input) builder.add(chs); return convert(builder.complete(), new IdentityHashMap()); } /** * Copy current into an internal buffer. */ private boolean setPrevious(CharSequence current) { if (previous == null) previous = new StringBuilder(); previous.setLength(0); previous.append(current); return true; } /** * Replace last child of state with an already registered * state or register the last child state. */ private void replaceOrRegister(State state) { final State child = state.lastChild(); if (child.hasChildren()) replaceOrRegister(child); final State registered = register.get(child); if (registered != null) { state.replaceLastChild(registered); } else { register.put(child, child); } } /** * Add a suffix of current starting at fromIndex * (inclusive) to state state. */ private void addSuffix(State state, CharSequence current, int fromIndex) { final int len = current.length(); for (int i = fromIndex; i < len; i++) { state = state.newState(current.charAt(i)); } state.is_final = true; } } src/dk/brics/automaton/Transition.java000066400000000000000000000112201204272215500203450ustar00rootroot00000000000000/* * dk.brics.automaton * * Copyright (c) 2001-2011 Anders Moeller * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package dk.brics.automaton; import java.io.Serializable; /** * Automaton transition. *

* A transition, which belongs to a source state, consists of a Unicode character interval * and a destination state. * @author Anders Møller <amoeller@cs.au.dk> */ public class Transition implements Serializable, Cloneable { static final long serialVersionUID = 40001; /* * CLASS INVARIANT: min<=max */ char min; char max; State to; /** * Constructs a new singleton interval transition. * @param c transition character * @param to destination state */ public Transition(char c, State to) { min = max = c; this.to = to; } /** * Constructs a new transition. * Both end points are included in the interval. * @param min transition interval minimum * @param max transition interval maximum * @param to destination state */ public Transition(char min, char max, State to) { if (max < min) { char t = max; max = min; min = t; } this.min = min; this.max = max; this.to = to; } /** Returns minimum of this transition interval. */ public char getMin() { return min; } /** Returns maximum of this transition interval. */ public char getMax() { return max; } /** Returns destination of this transition. */ public State getDest() { return to; } /** * Checks for equality. * @param obj object to compare with * @return true if obj is a transition with same * character interval and destination state as this transition. */ @Override public boolean equals(Object obj) { if (obj instanceof Transition) { Transition t = (Transition)obj; return t.min == min && t.max == max && t.to == to; } else return false; } /** * Returns hash code. * The hash code is based on the character interval (not the destination state). * @return hash code */ @Override public int hashCode() { return min * 2 + max * 3; } /** * Clones this transition. * @return clone with same character interval and destination state */ @Override public Transition clone() { try { return (Transition)super.clone(); } catch (CloneNotSupportedException e) { throw new RuntimeException(e); } } static void appendCharString(char c, StringBuilder b) { if (c >= 0x21 && c <= 0x7e && c != '\\' && c != '"') b.append(c); else { b.append("\\u"); String s = Integer.toHexString(c); if (c < 0x10) b.append("000").append(s); else if (c < 0x100) b.append("00").append(s); else if (c < 0x1000) b.append("0").append(s); else b.append(s); } } /** * Returns a string describing this state. Normally invoked via * {@link Automaton#toString()}. */ @Override public String toString() { StringBuilder b = new StringBuilder(); appendCharString(min, b); if (min != max) { b.append("-"); appendCharString(max, b); } b.append(" -> ").append(to.number); return b.toString(); } void appendDot(StringBuilder b) { b.append(" -> ").append(to.number).append(" [label=\""); appendCharString(min, b); if (min != max) { b.append("-"); appendCharString(max, b); } b.append("\"]\n"); } } src/dk/brics/automaton/TransitionComparator.java000066400000000000000000000050541204272215500224050ustar00rootroot00000000000000/* * dk.brics.automaton * * Copyright (c) 2001-2011 Anders Moeller * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package dk.brics.automaton; import java.io.Serializable; import java.util.Comparator; class TransitionComparator implements Comparator, Serializable { static final long serialVersionUID = 10001; boolean to_first; TransitionComparator(boolean to_first) { this.to_first = to_first; } /** * Compares by (min, reverse max, to) or (to, min, reverse max). */ public int compare(Transition t1, Transition t2) { if (to_first) { if (t1.to != t2.to) { if (t1.to == null) return -1; else if (t2.to == null) return 1; else if (t1.to.number < t2.to.number) return -1; else if (t1.to.number > t2.to.number) return 1; } } if (t1.min < t2.min) return -1; if (t1.min > t2.min) return 1; if (t1.max > t2.max) return -1; if (t1.max < t2.max) return 1; if (!to_first) { if (t1.to != t2.to) { if (t1.to == null) return -1; else if (t2.to == null) return 1; else if (t1.to.number < t2.to.number) return -1; else if (t1.to.number > t2.to.number) return 1; } } return 0; } } src/dk/brics/automaton/package.html000066400000000000000000000010701204272215500176330ustar00rootroot00000000000000 Finite-state automaton for regular expressions.

This package contains a full DFA/NFA implementation with Unicode alphabet and support for all standard (and a number of non-standard) regular expression operations.

The most commonly used functionality is located in the classes Automaton and RegExp.

For more information, go to the package home page at http://www.brics.dk/automaton/.