| 1 | /******************************************************************************* | |
| 2 | * Copyhacked (H) 2012-2025. | |
| 3 | * This program and the accompanying materials | |
| 4 | * are made available under no term at all, use it like | |
| 5 | * you want, but share and discuss it | |
| 6 | * every time possible with every body. | |
| 7 | * | |
| 8 | * Contributors: | |
| 9 | * ron190 at ymail dot com - initial implementation | |
| 10 | ******************************************************************************/ | |
| 11 | package com.jsql.util; | |
| 12 | ||
| 13 | import com.jsql.util.bruter.Base58; | |
| 14 | import org.apache.commons.codec.binary.Base16; | |
| 15 | import org.apache.commons.codec.binary.Base32; | |
| 16 | import org.apache.commons.lang3.ArrayUtils; | |
| 17 | import org.apache.commons.lang3.StringUtils; | |
| 18 | import org.apache.commons.text.StringEscapeUtils; | |
| 19 | import org.apache.logging.log4j.LogManager; | |
| 20 | import org.apache.logging.log4j.Logger; | |
| 21 | ||
| 22 | import java.awt.*; | |
| 23 | import java.io.*; | |
| 24 | import java.net.URLDecoder; | |
| 25 | import java.net.URLEncoder; | |
| 26 | import java.nio.charset.StandardCharsets; | |
| 27 | import java.util.ArrayList; | |
| 28 | import java.util.Base64; | |
| 29 | import java.util.List; | |
| 30 | import java.util.Objects; | |
| 31 | import java.util.zip.DeflaterOutputStream; | |
| 32 | import java.util.zip.InflaterOutputStream; | |
| 33 | ||
| 34 | /** | |
| 35 | * Utility class adding String operations like join() which are not | |
| 36 | * part of standard JVM. | |
| 37 | */ | |
| 38 | public final class StringUtil { | |
| 39 | | |
| 40 | private static final Logger LOGGER = LogManager.getRootLogger(); | |
| 41 | | |
| 42 | // Define the schema of conversion to html entities | |
| 43 | private static final CharEncoder DECIMAL_HTML_ENCODER = new CharEncoder("&#", ";", 10); | |
| 44 | public static final String GET = "GET"; | |
| 45 | public static final String POST = "POST"; | |
| 46 | public static final String INFORMATION_SCHEMA = "information_schema"; | |
| 47 | public static final String APP_NAME = "jSQL Injection"; | |
| 48 | ||
| 49 | /** | |
| 50 | * This utility class defines a schema used to encode a text into a specialized | |
| 51 | * representation | |
| 52 | */ | |
| 53 | private record CharEncoder(String prefix, String suffix, int radix) { | |
| 54 | private void encode(char c, StringBuilder buff) { | |
| 55 | buff.append(this.prefix) | |
| 56 | .append(Integer.toString(c, this.radix)) | |
| 57 | .append(this.suffix); | |
| 58 | } | |
| 59 | } | |
| 60 | ||
| 61 | private StringUtil() { | |
| 62 | // Utility class | |
| 63 | } | |
| 64 | | |
| 65 | /** | |
| 66 | * Convert special characters like Chinese and Arabic letters to the corresponding html entities. | |
| 67 | * @param text string to encode | |
| 68 | * @return string encoded in html entities | |
| 69 | */ | |
| 70 | public static String toHtmlDecimal(String text) { | |
| 71 |
1
1. toHtmlDecimal : replaced return value with "" for com/jsql/util/StringUtil::toHtmlDecimal → KILLED |
return StringUtil.encode(text); |
| 72 | } | |
| 73 | | |
| 74 | /** | |
| 75 | * Non-trivial methods to convert Unicode characters to html entities. | |
| 76 | * @param text string to encode | |
| 77 | * @return string representation using the encoder schema | |
| 78 | */ | |
| 79 | private static String encode(String text) { | |
| 80 | var buff = new StringBuilder(); | |
| 81 |
2
1. encode : changed conditional boundary → KILLED 2. encode : negated conditional → KILLED |
for (var i = 0 ; i < text.length() ; i++) { |
| 82 |
2
1. encode : changed conditional boundary → SURVIVED 2. encode : negated conditional → KILLED |
if (text.charAt(i) > 128) { |
| 83 |
1
1. encode : removed call to com/jsql/util/StringUtil$CharEncoder::encode → KILLED |
StringUtil.DECIMAL_HTML_ENCODER.encode(text.charAt(i), buff); |
| 84 | } else { | |
| 85 | buff.append(text.charAt(i)); | |
| 86 | } | |
| 87 | } | |
| 88 |
1
1. encode : replaced return value with "" for com/jsql/util/StringUtil::encode → KILLED |
return buff.toString(); |
| 89 | } | |
| 90 | ||
| 91 | /** | |
| 92 | * Convert a hexadecimal String to String. | |
| 93 | * @param hex Hexadecimal String to convert | |
| 94 | * @return The string converted from hex | |
| 95 | */ | |
| 96 | public static String hexstr(String hex) { | |
| 97 |
1
1. hexstr : Replaced integer division with multiplication → KILLED |
var bytes = new byte[hex.length() / 2]; |
| 98 |
2
1. hexstr : negated conditional → KILLED 2. hexstr : changed conditional boundary → KILLED |
for (var i = 0 ; i < bytes.length ; i++) { |
| 99 |
3
1. hexstr : Replaced integer multiplication with division → KILLED 2. hexstr : Replaced integer addition with subtraction → KILLED 3. hexstr : Replaced integer multiplication with division → KILLED |
bytes[i] = (byte) Integer.parseInt(hex.substring(2 * i, 2 * i + 2), 16); |
| 100 | } | |
| 101 |
1
1. hexstr : replaced return value with "" for com/jsql/util/StringUtil::hexstr → KILLED |
return new String(bytes, StandardCharsets.UTF_8); |
| 102 | } | |
| 103 | | |
| 104 | public static String detectUtf8(String text) { | |
| 105 |
1
1. detectUtf8 : negated conditional → KILLED |
if (text == null) { |
| 106 | return StringUtils.EMPTY; | |
| 107 | } | |
| 108 | String result = text; | |
| 109 |
1
1. detectUtf8 : negated conditional → SURVIVED |
if (StringUtil.containsNonStandardScripts(text)) { |
| 110 | result = new String(text.getBytes(StandardCharsets.UTF_8), StandardCharsets.UTF_8); | |
| 111 | } | |
| 112 |
1
1. detectUtf8 : replaced return value with "" for com/jsql/util/StringUtil::detectUtf8 → KILLED |
return result; |
| 113 | } | |
| 114 | ||
| 115 | public static boolean containsNonStandardScripts(String text) { | |
| 116 |
1
1. containsNonStandardScripts : negated conditional → KILLED |
if (text == null) { |
| 117 |
1
1. containsNonStandardScripts : replaced boolean return with true for com/jsql/util/StringUtil::containsNonStandardScripts → KILLED |
return false; |
| 118 | } | |
| 119 |
2
1. containsNonStandardScripts : replaced boolean return with false for com/jsql/util/StringUtil::containsNonStandardScripts → SURVIVED 2. containsNonStandardScripts : replaced boolean return with true for com/jsql/util/StringUtil::containsNonStandardScripts → KILLED |
return text.codePoints().anyMatch(codePoint -> { |
| 120 | Character.UnicodeScript script = Character.UnicodeScript.of(codePoint); | |
| 121 | // Check for scripts other than Latin | |
| 122 |
3
1. lambda$containsNonStandardScripts$0 : negated conditional → NO_COVERAGE 2. lambda$containsNonStandardScripts$0 : replaced boolean return with true for com/jsql/util/StringUtil::lambda$containsNonStandardScripts$0 → KILLED 3. lambda$containsNonStandardScripts$0 : negated conditional → KILLED |
return script != Character.UnicodeScript.LATIN && script != Character.UnicodeScript.COMMON; |
| 123 | }); | |
| 124 | } | |
| 125 | | |
| 126 | public static String base32Encode(String s) { | |
| 127 | var base32 = new Base32(); | |
| 128 |
1
1. base32Encode : replaced return value with "" for com/jsql/util/StringUtil::base32Encode → KILLED |
return base32.encodeToString(StringUtil.getBytesUtf8(s)); |
| 129 | } | |
| 130 | | |
| 131 | public static String base32Decode(String s) { | |
| 132 | var base32 = new Base32(); | |
| 133 |
1
1. base32Decode : replaced return value with "" for com/jsql/util/StringUtil::base32Decode → KILLED |
return StringUtil.newStringUtf8(base32.decode(s)); |
| 134 | } | |
| 135 | | |
| 136 | public static String base58Encode(String s) { | |
| 137 |
1
1. base58Encode : replaced return value with "" for com/jsql/util/StringUtil::base58Encode → KILLED |
return Base58.encode(StringUtil.getBytesUtf8(s)); |
| 138 | } | |
| 139 | | |
| 140 | public static String base58Decode(String s) { | |
| 141 |
1
1. base58Decode : replaced return value with "" for com/jsql/util/StringUtil::base58Decode → KILLED |
return StringUtil.newStringUtf8(Base58.decode(s)); |
| 142 | } | |
| 143 | | |
| 144 | public static String base16Encode(String s) { | |
| 145 | var base16 = new Base16(); | |
| 146 |
1
1. base16Encode : replaced return value with "" for com/jsql/util/StringUtil::base16Encode → KILLED |
return base16.encodeToString(StringUtil.getBytesUtf8(s)); |
| 147 | } | |
| 148 | | |
| 149 | public static String base16Decode(String s) { | |
| 150 | var base16 = new Base16(); | |
| 151 |
1
1. base16Decode : replaced return value with "" for com/jsql/util/StringUtil::base16Decode → KILLED |
return StringUtil.newStringUtf8(base16.decode(s)); |
| 152 | } | |
| 153 | ||
| 154 | public static String base64Decode(String s) { | |
| 155 |
1
1. base64Decode : replaced return value with "" for com/jsql/util/StringUtil::base64Decode → KILLED |
return StringUtil.newStringUtf8(Base64.getDecoder().decode(s)); |
| 156 | } | |
| 157 | ||
| 158 | public static String base64Encode(String s) { | |
| 159 |
1
1. base64Encode : replaced return value with "" for com/jsql/util/StringUtil::base64Encode → KILLED |
return Base64.getEncoder().encodeToString(StringUtil.getBytesUtf8(s)); |
| 160 | } | |
| 161 | ||
| 162 | public static String toHex(String text) { | |
| 163 |
1
1. toHex : replaced return value with "" for com/jsql/util/StringUtil::toHex → KILLED |
return StringUtil.encodeHexString(text.getBytes(StandardCharsets.UTF_8)); |
| 164 | } | |
| 165 | | |
| 166 | public static String fromHex(String text) { | |
| 167 | byte[] hex = StringUtil.decodeHexString(text); | |
| 168 |
1
1. fromHex : replaced return value with "" for com/jsql/util/StringUtil::fromHex → KILLED |
return new String(hex, StandardCharsets.UTF_8); |
| 169 | } | |
| 170 | | |
| 171 | public static String toHexZip(String text) throws IOException { | |
| 172 | byte[] zip = StringUtil.compress(text); | |
| 173 |
1
1. toHexZip : replaced return value with "" for com/jsql/util/StringUtil::toHexZip → KILLED |
return StringUtil.encodeHexString(zip); |
| 174 | } | |
| 175 | ||
| 176 | public static String fromHexZip(String text) throws IOException { | |
| 177 |
1
1. fromHexZip : replaced return value with "" for com/jsql/util/StringUtil::fromHexZip → KILLED |
return new String(StringUtil.decompress(StringUtil.decodeHexString(text)), StandardCharsets.UTF_8); |
| 178 | } | |
| 179 | | |
| 180 | public static String toBase64Zip(String text) throws IOException { | |
| 181 |
1
1. toBase64Zip : replaced return value with "" for com/jsql/util/StringUtil::toBase64Zip → KILLED |
return new String(Base64.getEncoder().encode(StringUtil.compress(text))); |
| 182 | } | |
| 183 | | |
| 184 | public static String fromBase64Zip(String text) throws IOException { | |
| 185 | byte[] decompressedBArray = StringUtil.decompress(Base64.getDecoder().decode(text)); | |
| 186 |
1
1. fromBase64Zip : replaced return value with "" for com/jsql/util/StringUtil::fromBase64Zip → KILLED |
return new String(decompressedBArray, StandardCharsets.UTF_8); |
| 187 | } | |
| 188 | | |
| 189 | public static String toHtml(String text) { | |
| 190 |
1
1. toHtml : replaced return value with "" for com/jsql/util/StringUtil::toHtml → KILLED |
return StringEscapeUtils.escapeHtml4(text); |
| 191 | } | |
| 192 | | |
| 193 | public static String fromHtml(String text) { | |
| 194 |
1
1. fromHtml : replaced return value with "" for com/jsql/util/StringUtil::fromHtml → KILLED |
return StringEscapeUtils.unescapeHtml4(text); |
| 195 | } | |
| 196 | | |
| 197 | public static String toUrl(String text) { | |
| 198 |
1
1. toUrl : replaced return value with "" for com/jsql/util/StringUtil::toUrl → KILLED |
return URLEncoder.encode(text, StandardCharsets.UTF_8); |
| 199 | } | |
| 200 | | |
| 201 | public static String fromUrl(String text) { | |
| 202 |
1
1. fromUrl : replaced return value with "" for com/jsql/util/StringUtil::fromUrl → KILLED |
return URLDecoder.decode(text, StandardCharsets.UTF_8); |
| 203 | } | |
| 204 | | |
| 205 | public static String cleanSql(String query) { | |
| 206 |
1
1. cleanSql : replaced return value with "" for com/jsql/util/StringUtil::cleanSql → KILLED |
return StringUtil.removeSqlComment(query) |
| 207 | .replaceAll("(?s)([^\\s\\w])(\\s+)", "$1") // Remove spaces after a word | |
| 208 | .replaceAll("(?s)(\\s+)([^\\s\\w])", "$2") // Remove spaces before a word | |
| 209 | .replaceAll("(?s)\\s+", " ") // Replace spaces | |
| 210 | .trim(); | |
| 211 | } | |
| 212 | ||
| 213 | /** | |
| 214 | * Remove SQL comments except tamper /**\/ /*!...*\/ | |
| 215 | * Negative lookahead: don't match tamper empty comment /**\/ or version comment /*!...*\/ | |
| 216 | * JavaScript: (?!\/\*!.*\*\/|\/\*\*\/)\/\*.*\*\/ | |
| 217 | */ | |
| 218 | public static String removeSqlComment(String query) { | |
| 219 |
1
1. removeSqlComment : replaced return value with "" for com/jsql/util/StringUtil::removeSqlComment → KILLED |
return query.replaceAll( |
| 220 | "(?s)(?!/\\*\\*/|/\\*!.*\\*/)/\\*.*?\\*/", | |
| 221 | StringUtils.EMPTY | |
| 222 | ); | |
| 223 | } | |
| 224 | ||
| 225 | public static String formatReport(Color color, String text) { | |
| 226 |
1
1. formatReport : replaced return value with "" for com/jsql/util/StringUtil::formatReport → NO_COVERAGE |
return String.format( |
| 227 | "<span style=color:rgb(%s,%s,%s)>%s</span>", | |
| 228 | color.getRed(), | |
| 229 | color.getGreen(), | |
| 230 | color.getBlue(), | |
| 231 | text | |
| 232 | ); | |
| 233 | } | |
| 234 | ||
| 235 | ||
| 236 | // Utils | |
| 237 | ||
| 238 | private static byte[] compress(String text) throws IOException { | |
| 239 | ByteArrayOutputStream os = new ByteArrayOutputStream(); | |
| 240 | try (DeflaterOutputStream dos = new DeflaterOutputStream(os)) { | |
| 241 |
1
1. compress : removed call to java/util/zip/DeflaterOutputStream::write → KILLED |
dos.write(text.getBytes()); |
| 242 | } | |
| 243 |
1
1. compress : replaced return value with null for com/jsql/util/StringUtil::compress → KILLED |
return os.toByteArray(); |
| 244 | } | |
| 245 | ||
| 246 | private static byte[] decompress(byte[] compressedTxt) throws IOException { | |
| 247 | ByteArrayOutputStream os = new ByteArrayOutputStream(); | |
| 248 | try (OutputStream ios = new InflaterOutputStream(os)) { | |
| 249 |
1
1. decompress : removed call to java/io/OutputStream::write → KILLED |
ios.write(compressedTxt); |
| 250 | } | |
| 251 |
1
1. decompress : replaced return value with null for com/jsql/util/StringUtil::decompress → KILLED |
return os.toByteArray(); |
| 252 | } | |
| 253 | ||
| 254 | private static byte hexToByte(String hexString) { | |
| 255 | int firstDigit = StringUtil.toDigit(hexString.charAt(0)); | |
| 256 | int secondDigit = StringUtil.toDigit(hexString.charAt(1)); | |
| 257 |
3
1. hexToByte : Replaced integer addition with subtraction → KILLED 2. hexToByte : replaced byte return with 0 for com/jsql/util/StringUtil::hexToByte → KILLED 3. hexToByte : Replaced Shift Left with Shift Right → KILLED |
return (byte) ((firstDigit << 4) + secondDigit); |
| 258 | } | |
| 259 | ||
| 260 | private static int toDigit(char hexChar) { | |
| 261 | int digit = Character.digit(hexChar, 16); | |
| 262 |
1
1. toDigit : negated conditional → KILLED |
if (digit == -1) { |
| 263 | throw new IllegalArgumentException("Invalid Hexadecimal Character: "+ hexChar); | |
| 264 | } | |
| 265 |
1
1. toDigit : replaced int return with 0 for com/jsql/util/StringUtil::toDigit → KILLED |
return digit; |
| 266 | } | |
| 267 | ||
| 268 | private static String byteToHex(byte num) { | |
| 269 | char[] hexDigits = new char[2]; | |
| 270 |
2
1. byteToHex : Replaced Shift Right with Shift Left → KILLED 2. byteToHex : Replaced bitwise AND with OR → KILLED |
hexDigits[0] = Character.forDigit((num >> 4) & 0xF, 16); |
| 271 |
1
1. byteToHex : Replaced bitwise AND with OR → KILLED |
hexDigits[1] = Character.forDigit(num & 0xF, 16); |
| 272 |
1
1. byteToHex : replaced return value with "" for com/jsql/util/StringUtil::byteToHex → KILLED |
return new String(hexDigits); |
| 273 | } | |
| 274 | ||
| 275 | private static String encodeHexString(byte[] byteArray) { | |
| 276 | StringBuilder hexStringBuffer = new StringBuilder(); | |
| 277 | for (byte b : byteArray) { | |
| 278 | hexStringBuffer.append(StringUtil.byteToHex(b)); | |
| 279 | } | |
| 280 |
1
1. encodeHexString : replaced return value with "" for com/jsql/util/StringUtil::encodeHexString → KILLED |
return hexStringBuffer.toString(); |
| 281 | } | |
| 282 | ||
| 283 | private static byte[] decodeHexString(String hexString) { | |
| 284 |
2
1. decodeHexString : Replaced integer modulus with multiplication → SURVIVED 2. decodeHexString : negated conditional → KILLED |
if (hexString.length() % 2 == 1) { |
| 285 | throw new IllegalArgumentException("Invalid hexadecimal String supplied."); | |
| 286 | } | |
| 287 |
1
1. decodeHexString : Replaced integer division with multiplication → KILLED |
byte[] bytes = new byte[hexString.length() / 2]; |
| 288 |
2
1. decodeHexString : negated conditional → KILLED 2. decodeHexString : changed conditional boundary → KILLED |
for (int i = 0 ; i < hexString.length() ; i += 2) { |
| 289 |
2
1. decodeHexString : Replaced integer division with multiplication → KILLED 2. decodeHexString : Replaced integer addition with subtraction → KILLED |
bytes[i / 2] = StringUtil.hexToByte(hexString.substring(i, i + 2)); |
| 290 | } | |
| 291 |
1
1. decodeHexString : replaced return value with null for com/jsql/util/StringUtil::decodeHexString → KILLED |
return bytes; |
| 292 | } | |
| 293 | ||
| 294 | private static byte[] getBytesUtf8(String string) { | |
| 295 |
2
1. getBytesUtf8 : negated conditional → KILLED 2. getBytesUtf8 : replaced return value with null for com/jsql/util/StringUtil::getBytesUtf8 → KILLED |
return string == null ? null : string.getBytes(StandardCharsets.UTF_8); |
| 296 | } | |
| 297 | ||
| 298 | private static String newStringUtf8(byte[] bytes) { | |
| 299 |
2
1. newStringUtf8 : replaced return value with "" for com/jsql/util/StringUtil::newStringUtf8 → KILLED 2. newStringUtf8 : negated conditional → KILLED |
return bytes == null ? null : new String(bytes, StandardCharsets.UTF_8); |
| 300 | } | |
| 301 | ||
| 302 | public static byte[] xor(byte[] plaintext, int key) { | |
| 303 | var ciphertext = new byte[plaintext.length]; | |
| 304 |
2
1. xor : negated conditional → NO_COVERAGE 2. xor : changed conditional boundary → NO_COVERAGE |
for (var i = 0 ; i < plaintext.length ; i++) { |
| 305 |
4
1. xor : Replaced Unsigned Shift Right with Shift Left → NO_COVERAGE 2. xor : Replaced integer multiplication with division → NO_COVERAGE 3. xor : Replaced integer modulus with multiplication → NO_COVERAGE 4. xor : Replaced XOR with AND → NO_COVERAGE |
ciphertext[i] = (byte) (Byte.toUnsignedInt(plaintext[i]) ^ (key >>> (8 * (i % 4)))); |
| 306 | } | |
| 307 |
1
1. xor : replaced return value with null for com/jsql/util/StringUtil::xor → NO_COVERAGE |
return ciphertext; |
| 308 | } | |
| 309 | ||
| 310 | public static List<String> toHexChunks(byte[] fileData) { | |
| 311 | StringBuilder hexString = new StringBuilder(); | |
| 312 | for (byte b : fileData) { | |
| 313 | hexString.append(String.format("%02X", b)); | |
| 314 | } | |
| 315 | int chunkSize = 900; // 450 bytes = 900 hex characters | |
| 316 | List<String> chunks = new ArrayList<>(); | |
| 317 |
3
1. toHexChunks : changed conditional boundary → NO_COVERAGE 2. toHexChunks : Replaced integer addition with subtraction → NO_COVERAGE 3. toHexChunks : negated conditional → NO_COVERAGE |
for (int i = 0 ; i < hexString.length() ; i += chunkSize) { |
| 318 |
1
1. toHexChunks : Replaced integer addition with subtraction → NO_COVERAGE |
int endIndex = Math.min(i + chunkSize, hexString.length()); |
| 319 | chunks.add(hexString.substring(i, endIndex)); | |
| 320 | } | |
| 321 |
1
1. toHexChunks : replaced return value with Collections.emptyList for com/jsql/util/StringUtil::toHexChunks → NO_COVERAGE |
return chunks; |
| 322 | } | |
| 323 | ||
| 324 | public static String getFile(String path) { | |
| 325 | var content = new StringBuilder(); | |
| 326 | try ( | |
| 327 | var inputStream = PreferencesUtil.class.getClassLoader().getResourceAsStream(path); | |
| 328 | var inputStreamReader = new InputStreamReader(Objects.requireNonNull(inputStream), StandardCharsets.UTF_8); | |
| 329 | var reader = new BufferedReader(inputStreamReader) | |
| 330 | ) { | |
| 331 | String line; | |
| 332 |
1
1. getFile : negated conditional → KILLED |
while ((line = reader.readLine()) != null) { |
| 333 | content.append(line).append("\n"); // required to prevent \n<text>\r on edit | |
| 334 | } | |
| 335 | } catch (IOException e) { | |
| 336 | LOGGER.log(LogLevelUtil.CONSOLE_JAVA, e, e); | |
| 337 | } | |
| 338 |
1
1. getFile : replaced return value with "" for com/jsql/util/StringUtil::getFile → KILLED |
return content.toString(); |
| 339 | } | |
| 340 | ||
| 341 | public static byte[] uncloak(byte[] fileData) { | |
| 342 | byte[] fileDataUncloaked = StringUtil.xor(fileData, 353837730); | |
| 343 |
1
1. uncloak : removed call to org/apache/commons/lang3/ArrayUtils::reverse → NO_COVERAGE |
ArrayUtils.reverse(fileDataUncloaked); |
| 344 |
1
1. uncloak : replaced return value with null for com/jsql/util/StringUtil::uncloak → NO_COVERAGE |
return fileDataUncloaked; |
| 345 | } | |
| 346 | } | |
Mutations | ||
| 71 |
1.1 |
|
| 81 |
1.1 2.2 |
|
| 82 |
1.1 2.2 |
|
| 83 |
1.1 |
|
| 88 |
1.1 |
|
| 97 |
1.1 |
|
| 98 |
1.1 2.2 |
|
| 99 |
1.1 2.2 3.3 |
|
| 101 |
1.1 |
|
| 105 |
1.1 |
|
| 109 |
1.1 |
|
| 112 |
1.1 |
|
| 116 |
1.1 |
|
| 117 |
1.1 |
|
| 119 |
1.1 2.2 |
|
| 122 |
1.1 2.2 3.3 |
|
| 128 |
1.1 |
|
| 133 |
1.1 |
|
| 137 |
1.1 |
|
| 141 |
1.1 |
|
| 146 |
1.1 |
|
| 151 |
1.1 |
|
| 155 |
1.1 |
|
| 159 |
1.1 |
|
| 163 |
1.1 |
|
| 168 |
1.1 |
|
| 173 |
1.1 |
|
| 177 |
1.1 |
|
| 181 |
1.1 |
|
| 186 |
1.1 |
|
| 190 |
1.1 |
|
| 194 |
1.1 |
|
| 198 |
1.1 |
|
| 202 |
1.1 |
|
| 206 |
1.1 |
|
| 219 |
1.1 |
|
| 226 |
1.1 |
|
| 241 |
1.1 |
|
| 243 |
1.1 |
|
| 249 |
1.1 |
|
| 251 |
1.1 |
|
| 257 |
1.1 2.2 3.3 |
|
| 262 |
1.1 |
|
| 265 |
1.1 |
|
| 270 |
1.1 2.2 |
|
| 271 |
1.1 |
|
| 272 |
1.1 |
|
| 280 |
1.1 |
|
| 284 |
1.1 2.2 |
|
| 287 |
1.1 |
|
| 288 |
1.1 2.2 |
|
| 289 |
1.1 2.2 |
|
| 291 |
1.1 |
|
| 295 |
1.1 2.2 |
|
| 299 |
1.1 2.2 |
|
| 304 |
1.1 2.2 |
|
| 305 |
1.1 2.2 3.3 4.4 |
|
| 307 |
1.1 |
|
| 317 |
1.1 2.2 3.3 |
|
| 318 |
1.1 |
|
| 321 |
1.1 |
|
| 332 |
1.1 |
|
| 338 |
1.1 |
|
| 343 |
1.1 |
|
| 344 |
1.1 |