/src/ada-url/build/singleheader/ada.cpp
Line | Count | Source |
1 | | /* auto-generated on 2026-08-11 11:06:41 -0400. Do not edit! */ |
2 | | /* begin file src/ada.cpp */ |
3 | | #include "ada.h" |
4 | | /* begin file src/checkers.cpp */ |
5 | | |
6 | | #include <algorithm> |
7 | | #include <array> |
8 | | #include <string_view> |
9 | | |
10 | | namespace ada::checkers { |
11 | | |
12 | 235k | ada_really_inline constexpr bool is_ipv4(std::string_view view) noexcept { |
13 | | // The string is not empty and does not contain upper case ASCII characters. |
14 | | // |
15 | | // Optimization. To be considered as a possible ipv4, the string must end |
16 | | // with 'x' or a lowercase hex character. |
17 | | // Most of the time, this will be false so this simple check will save a lot |
18 | | // of effort. |
19 | | // If the address ends with a dot, we need to prune it (special case). |
20 | 235k | if (view.ends_with('.')) { |
21 | 1.10k | view.remove_suffix(1); |
22 | 1.10k | if (view.empty()) { |
23 | 486 | return false; |
24 | 486 | } |
25 | 1.10k | } |
26 | 235k | char last_char = view.back(); |
27 | 235k | bool possible_ipv4 = (last_char >= '0' && last_char <= '9') || |
28 | 220k | (last_char >= 'a' && last_char <= 'f') || |
29 | 215k | last_char == 'x'; |
30 | 235k | if (!possible_ipv4) { |
31 | 82.3k | return false; |
32 | 82.3k | } |
33 | | // From the last character, find the last dot. |
34 | 153k | size_t last_dot = view.rfind('.'); |
35 | 153k | if (last_dot != std::string_view::npos) { |
36 | | // We have at least one dot. |
37 | 14.9k | view.remove_prefix(last_dot + 1); |
38 | 14.9k | } |
39 | | /** Optimization opportunity: we have basically identified the last number of |
40 | | the ipv4 if we return true here. We might as well parse it and have at |
41 | | least one number parsed when we get to parse_ipv4. */ |
42 | 153k | if (std::ranges::all_of(view, ada::checkers::is_digit)) { |
43 | 14.1k | return true; |
44 | 14.1k | } |
45 | | // It could be hex (0x), but not if there is a single character. |
46 | 139k | if (view.size() == 1) { |
47 | 133k | return false; |
48 | 133k | } |
49 | | // It must start with 0x. |
50 | 5.16k | if (!view.starts_with("0x")) { |
51 | 3.32k | return false; |
52 | 3.32k | } |
53 | | // We must allow "0x". |
54 | 1.84k | if (view.size() == 2) { |
55 | 141 | return true; |
56 | 141 | } |
57 | | // We have 0x followed by some characters, we need to check that they are |
58 | | // hexadecimals. |
59 | 1.70k | view.remove_prefix(2); |
60 | 1.70k | return std::ranges::all_of(view, ada::unicode::is_lowercase_hex); |
61 | 1.84k | } |
62 | | |
63 | | // for use with path_signature, we include all characters that need percent |
64 | | // encoding. |
65 | | static constexpr std::array<uint8_t, 256> path_signature_table = |
66 | | []() consteval { |
67 | | std::array<uint8_t, 256> result{}; |
68 | | for (size_t i = 0; i < 256; i++) { |
69 | | if (i <= 0x20 || i == 0x22 || i == 0x23 || i == 0x3c || i == 0x3e || |
70 | | i == 0x3f || i == 0x5e || i == 0x60 || i == 0x7b || i == 0x7d || |
71 | | i > 0x7e) { |
72 | | result[i] = 1; |
73 | | } else if (i == 0x25) { |
74 | | result[i] = 8; |
75 | | } else if (i == 0x2e) { |
76 | | result[i] = 4; |
77 | | } else if (i == 0x5c) { |
78 | | result[i] = 2; |
79 | | } else { |
80 | | result[i] = 0; |
81 | | } |
82 | | } |
83 | | return result; |
84 | | }(); |
85 | | |
86 | | ada_really_inline constexpr uint8_t path_signature( |
87 | 170k | std::string_view input) noexcept { |
88 | | // The path percent-encode set is the query percent-encode set and U+003F (?), |
89 | | // U+0060 (`), U+007B ({), and U+007D (}). The query percent-encode set is the |
90 | | // C0 control percent-encode set and U+0020 SPACE, U+0022 ("), U+0023 (#), |
91 | | // U+003C (<), and U+003E (>). The C0 control percent-encode set are the C0 |
92 | | // controls and all code points greater than U+007E (~). |
93 | 170k | size_t i = 0; |
94 | 170k | uint8_t accumulator{}; |
95 | 224k | for (; i + 7 < input.size(); i += 8) { |
96 | 53.9k | accumulator |= uint8_t(path_signature_table[uint8_t(input[i])] | |
97 | 53.9k | path_signature_table[uint8_t(input[i + 1])] | |
98 | 53.9k | path_signature_table[uint8_t(input[i + 2])] | |
99 | 53.9k | path_signature_table[uint8_t(input[i + 3])] | |
100 | 53.9k | path_signature_table[uint8_t(input[i + 4])] | |
101 | 53.9k | path_signature_table[uint8_t(input[i + 5])] | |
102 | 53.9k | path_signature_table[uint8_t(input[i + 6])] | |
103 | 53.9k | path_signature_table[uint8_t(input[i + 7])]); |
104 | 53.9k | } |
105 | 453k | for (; i < input.size(); i++) { |
106 | 282k | accumulator |= uint8_t(path_signature_table[uint8_t(input[i])]); |
107 | 282k | } |
108 | 170k | return accumulator; |
109 | 170k | } |
110 | | |
111 | | ada_really_inline constexpr bool verify_dns_length( |
112 | 0 | std::string_view input) noexcept { |
113 | 0 | if (input.empty()) return false; |
114 | 0 | if (input.back() == '.') { |
115 | 0 | if (input.size() > 254) return false; |
116 | 0 | } else if (input.size() > 253) |
117 | 0 | return false; |
118 | | |
119 | 0 | size_t start = 0; |
120 | 0 | while (start < input.size()) { |
121 | 0 | auto dot_location = input.find('.', start); |
122 | | // If not found, it's likely the end of the domain |
123 | 0 | if (dot_location == std::string_view::npos) dot_location = input.size(); |
124 | |
|
125 | 0 | auto label_size = dot_location - start; |
126 | 0 | if (label_size > 63 || label_size == 0) return false; |
127 | | |
128 | 0 | start = dot_location + 1; |
129 | 0 | } |
130 | | |
131 | 0 | return true; |
132 | 0 | } |
133 | | |
134 | | } // namespace ada::checkers |
135 | | /* end file src/checkers.cpp */ |
136 | | /* begin file src/unicode.cpp */ |
137 | | |
138 | | |
139 | | ADA_PUSH_DISABLE_ALL_WARNINGS |
140 | | /* begin file src/ada_idna.cpp */ |
141 | | /* auto-generated on 2026-07-12 20:34:08 -0400. Do not edit! */ |
142 | | /* begin file src/idna.cpp */ |
143 | | /* begin file src/unicode_transcoding.cpp */ |
144 | | /* begin file include/ada/idna/unicode_transcoding.h */ |
145 | | #ifndef ADA_IDNA_UNICODE_TRANSCODING_H |
146 | | #define ADA_IDNA_UNICODE_TRANSCODING_H |
147 | | |
148 | | #include <string> |
149 | | #include <string_view> |
150 | | |
151 | | namespace ada::idna { |
152 | | |
153 | | size_t utf8_to_utf32(const char* buf, size_t len, char32_t* utf32_output); |
154 | | |
155 | | size_t utf8_length_from_utf32(const char32_t* buf, size_t len); |
156 | | |
157 | | size_t utf32_length_from_utf8(const char* buf, size_t len); |
158 | | |
159 | | size_t utf32_to_utf8(const char32_t* buf, size_t len, char* utf8_output); |
160 | | |
161 | | } // namespace ada::idna |
162 | | |
163 | | #endif // ADA_IDNA_UNICODE_TRANSCODING_H |
164 | | /* end file include/ada/idna/unicode_transcoding.h */ |
165 | | |
166 | | #include <algorithm> |
167 | | #include <cstdint> |
168 | | #include <cstring> |
169 | | |
170 | | namespace ada::idna { |
171 | | |
172 | 9.11k | size_t utf8_to_utf32(const char* buf, size_t len, char32_t* utf32_output) { |
173 | 9.11k | const uint8_t* data = reinterpret_cast<const uint8_t*>(buf); |
174 | 9.11k | size_t pos = 0; |
175 | 9.11k | const char32_t* start{utf32_output}; |
176 | 139k | while (pos < len) { |
177 | | // try to convert the next block of 16 ASCII bytes |
178 | 132k | if (pos + 16 <= len) { // if it is safe to read 16 more |
179 | | // bytes, check that they are ascii |
180 | 84.0k | uint64_t v1; |
181 | 84.0k | std::memcpy(&v1, data + pos, sizeof(uint64_t)); |
182 | 84.0k | uint64_t v2; |
183 | 84.0k | std::memcpy(&v2, data + pos + sizeof(uint64_t), sizeof(uint64_t)); |
184 | 84.0k | uint64_t v{v1 | v2}; |
185 | 84.0k | if ((v & 0x8080808080808080) == 0) { |
186 | 5.78k | size_t final_pos = pos + 16; |
187 | 98.2k | while (pos < final_pos) { |
188 | 92.5k | *utf32_output++ = char32_t(buf[pos]); |
189 | 92.5k | pos++; |
190 | 92.5k | } |
191 | 5.78k | continue; |
192 | 5.78k | } |
193 | 84.0k | } |
194 | 126k | uint8_t leading_byte = data[pos]; // leading byte |
195 | 126k | if (leading_byte < 0b10000000) { |
196 | | // converting one ASCII byte !!! |
197 | 79.8k | *utf32_output++ = char32_t(leading_byte); |
198 | 79.8k | pos++; |
199 | 79.8k | } else if ((leading_byte & 0b11100000) == 0b11000000) { |
200 | | // We have a two-byte UTF-8 |
201 | 9.10k | if (pos + 1 >= len) { |
202 | 204 | return 0; |
203 | 204 | } // minimal bound checking |
204 | 8.90k | if ((data[pos + 1] & 0b11000000) != 0b10000000) { |
205 | 425 | return 0; |
206 | 425 | } |
207 | | // range check |
208 | 8.48k | uint32_t code_point = |
209 | 8.48k | (leading_byte & 0b00011111) << 6 | (data[pos + 1] & 0b00111111); |
210 | 8.48k | if (code_point < 0x80 || 0x7ff < code_point) { |
211 | 21 | return 0; |
212 | 21 | } |
213 | 8.45k | *utf32_output++ = char32_t(code_point); |
214 | 8.45k | pos += 2; |
215 | 37.7k | } else if ((leading_byte & 0b11110000) == 0b11100000) { |
216 | | // We have a three-byte UTF-8 |
217 | 35.3k | if (pos + 2 >= len) { |
218 | 49 | return 0; |
219 | 49 | } // minimal bound checking |
220 | | |
221 | 35.2k | if ((data[pos + 1] & 0b11000000) != 0b10000000) { |
222 | 230 | return 0; |
223 | 230 | } |
224 | 35.0k | if ((data[pos + 2] & 0b11000000) != 0b10000000) { |
225 | 47 | return 0; |
226 | 47 | } |
227 | | // range check |
228 | 35.0k | uint32_t code_point = (leading_byte & 0b00001111) << 12 | |
229 | 35.0k | (data[pos + 1] & 0b00111111) << 6 | |
230 | 35.0k | (data[pos + 2] & 0b00111111); |
231 | 35.0k | if (code_point < 0x800 || 0xffff < code_point || |
232 | 35.0k | (0xd7ff < code_point && code_point < 0xe000)) { |
233 | 27 | return 0; |
234 | 27 | } |
235 | 34.9k | *utf32_output++ = char32_t(code_point); |
236 | 34.9k | pos += 3; |
237 | 34.9k | } else if ((leading_byte & 0b11111000) == 0b11110000) { // 0b11110000 |
238 | | // we have a 4-byte UTF-8 word. |
239 | 1.26k | if (pos + 3 >= len) { |
240 | 77 | return 0; |
241 | 77 | } // minimal bound checking |
242 | 1.18k | if ((data[pos + 1] & 0b11000000) != 0b10000000) { |
243 | 142 | return 0; |
244 | 142 | } |
245 | 1.04k | if ((data[pos + 2] & 0b11000000) != 0b10000000) { |
246 | 28 | return 0; |
247 | 28 | } |
248 | 1.01k | if ((data[pos + 3] & 0b11000000) != 0b10000000) { |
249 | 29 | return 0; |
250 | 29 | } |
251 | | |
252 | | // range check |
253 | 990 | uint32_t code_point = (leading_byte & 0b00000111) << 18 | |
254 | 990 | (data[pos + 1] & 0b00111111) << 12 | |
255 | 990 | (data[pos + 2] & 0b00111111) << 6 | |
256 | 990 | (data[pos + 3] & 0b00111111); |
257 | 990 | if (code_point <= 0xffff || 0x10ffff < code_point) { |
258 | 27 | return 0; |
259 | 27 | } |
260 | 963 | *utf32_output++ = char32_t(code_point); |
261 | 963 | pos += 4; |
262 | 1.13k | } else { |
263 | 1.13k | return 0; |
264 | 1.13k | } |
265 | 126k | } |
266 | 6.67k | return utf32_output - start; |
267 | 9.11k | } |
268 | | |
269 | 803 | size_t utf8_length_from_utf32(const char32_t* buf, size_t len) { |
270 | | // We are not BOM aware. |
271 | 803 | const uint32_t* p = reinterpret_cast<const uint32_t*>(buf); |
272 | 803 | size_t counter{0}; |
273 | 5.53k | for (size_t i = 0; i != len; ++i) { |
274 | 4.72k | ++counter; // ASCII |
275 | 4.72k | counter += static_cast<size_t>(p[i] > 0x7F); // two-byte |
276 | 4.72k | counter += static_cast<size_t>(p[i] > 0x7FF); // three-byte |
277 | 4.72k | counter += static_cast<size_t>(p[i] > 0xFFFF); // four-bytes |
278 | 4.72k | } |
279 | 803 | return counter; |
280 | 803 | } |
281 | | |
282 | 9.20k | size_t utf32_length_from_utf8(const char* buf, size_t len) { |
283 | 9.20k | const int8_t* p = reinterpret_cast<const int8_t*>(buf); |
284 | 399k | return std::count_if(p, std::next(p, len), [](int8_t c) { |
285 | | // -65 is 0b10111111, anything larger in two-complement's |
286 | | // should start a new code point. |
287 | 399k | return c > -65; |
288 | 399k | }); |
289 | 9.20k | } |
290 | | |
291 | 803 | size_t utf32_to_utf8(const char32_t* buf, size_t len, char* utf8_output) { |
292 | 803 | const uint32_t* data = reinterpret_cast<const uint32_t*>(buf); |
293 | 803 | size_t pos = 0; |
294 | 803 | const char* start{utf8_output}; |
295 | 5.34k | while (pos < len) { |
296 | | // try to convert the next block of 2 ASCII characters |
297 | 4.54k | if (pos + 2 <= len) { // if it is safe to read 8 more |
298 | | // bytes, check that they are ascii |
299 | 3.75k | uint64_t v; |
300 | 3.75k | std::memcpy(&v, data + pos, sizeof(uint64_t)); |
301 | 3.75k | if ((v & 0xFFFFFF80FFFFFF80) == 0) { |
302 | 182 | *utf8_output++ = char(buf[pos]); |
303 | 182 | *utf8_output++ = char(buf[pos + 1]); |
304 | 182 | pos += 2; |
305 | 182 | continue; |
306 | 182 | } |
307 | 3.75k | } |
308 | 4.36k | uint32_t word = data[pos]; |
309 | 4.36k | if ((word & 0xFFFFFF80) == 0) { |
310 | | // will generate one UTF-8 bytes |
311 | 224 | *utf8_output++ = char(word); |
312 | 224 | pos++; |
313 | 4.13k | } else if ((word & 0xFFFFF800) == 0) { |
314 | | // will generate two UTF-8 bytes |
315 | | // we have 0b110XXXXX 0b10XXXXXX |
316 | 810 | *utf8_output++ = char((word >> 6) | 0b11000000); |
317 | 810 | *utf8_output++ = char((word & 0b111111) | 0b10000000); |
318 | 810 | pos++; |
319 | 3.32k | } else if ((word & 0xFFFF0000) == 0) { |
320 | | // will generate three UTF-8 bytes |
321 | | // we have 0b1110XXXX 0b10XXXXXX 0b10XXXXXX |
322 | 2.26k | if (word >= 0xD800 && word <= 0xDFFF) { |
323 | 0 | return 0; |
324 | 0 | } |
325 | 2.26k | *utf8_output++ = char((word >> 12) | 0b11100000); |
326 | 2.26k | *utf8_output++ = char(((word >> 6) & 0b111111) | 0b10000000); |
327 | 2.26k | *utf8_output++ = char((word & 0b111111) | 0b10000000); |
328 | 2.26k | pos++; |
329 | 2.26k | } else { |
330 | | // will generate four UTF-8 bytes |
331 | | // we have 0b11110XXX 0b10XXXXXX 0b10XXXXXX |
332 | | // 0b10XXXXXX |
333 | 1.06k | if (word > 0x10FFFF) { |
334 | 0 | return 0; |
335 | 0 | } |
336 | 1.06k | *utf8_output++ = char((word >> 18) | 0b11110000); |
337 | 1.06k | *utf8_output++ = char(((word >> 12) & 0b111111) | 0b10000000); |
338 | 1.06k | *utf8_output++ = char(((word >> 6) & 0b111111) | 0b10000000); |
339 | 1.06k | *utf8_output++ = char((word & 0b111111) | 0b10000000); |
340 | 1.06k | pos++; |
341 | 1.06k | } |
342 | 4.36k | } |
343 | 803 | return utf8_output - start; |
344 | 803 | } |
345 | | } // namespace ada::idna |
346 | | /* end file src/unicode_transcoding.cpp */ |
347 | | /* begin file src/mapping.cpp */ |
348 | | /* begin file include/ada/idna/mapping.h */ |
349 | | #ifndef ADA_IDNA_MAPPING_H |
350 | | #define ADA_IDNA_MAPPING_H |
351 | | |
352 | | #include <string> |
353 | | #include <string_view> |
354 | | |
355 | | namespace ada::idna { |
356 | | |
357 | | // If the input is ascii, then the mapping is just -> lower case. |
358 | | void ascii_map(char* input, size_t length); |
359 | | // Map the characters according to IDNA, returning the empty string on error. |
360 | | std::u32string map(std::u32string_view input); |
361 | | // Map into an existing buffer (cleared on entry). Returns false if any code |
362 | | // point is disallowed. Reusing the buffer avoids repeated heap allocations |
363 | | // when called in a loop over multiple labels. |
364 | | bool map(std::u32string_view input, std::u32string& out); |
365 | | |
366 | | } // namespace ada::idna |
367 | | |
368 | | #endif |
369 | | /* end file include/ada/idna/mapping.h */ |
370 | | |
371 | | #include <array> |
372 | | #include <cstring> |
373 | | #include <cstdint> |
374 | | #include <string> |
375 | | |
376 | | /* begin file src/table_store.hpp */ |
377 | | // Runtime store for compressed Unicode/IDNA tables. |
378 | | // Large tables are DEFLATE-compressed (read-only) and expanded once on first |
379 | | // use into a heap buffer so the working set does not bloat the on-disk binary. |
380 | | // Hot-path lookups use the same O(1) multi-stage layout as the pre-compression |
381 | | // code; compression only affects on-disk size and one-time init. |
382 | | // |
383 | | // Thread-safe without mutex: atomic CAS + spin-wait. ensure_tables() returns |
384 | | // false if initialization fails (OOM, corrupt blob); callers must treat that |
385 | | // as a hard error and not touch table pointers. |
386 | | |
387 | | /* begin file src/raw_inflate.hpp */ |
388 | | // Minimal raw DEFLATE inflater (RFC 1951), enough for zlib raw streams. |
389 | | // Returns number of output bytes written, or 0 on failure. |
390 | | #include <cstdint> |
391 | | #include <cstring> |
392 | | |
393 | | namespace ada::idna::deflate { |
394 | | |
395 | | struct BitReader { |
396 | | const uint8_t* p; |
397 | | const uint8_t* end; |
398 | | uint32_t acc = 0; |
399 | | int bits = 0; |
400 | | |
401 | | explicit BitReader(const uint8_t* data, size_t len) |
402 | 1 | : p(data), end(data + len) {} |
403 | | |
404 | 457k | bool ensure(int n) { |
405 | 520k | while (bits < n) { |
406 | 62.3k | if (p >= end) return false; |
407 | 62.3k | acc |= uint32_t(*p++) << bits; |
408 | 62.3k | bits += 8; |
409 | 62.3k | } |
410 | 457k | return true; |
411 | 457k | } |
412 | 457k | uint32_t get(int n) { |
413 | 457k | if (!ensure(n)) return UINT32_MAX; |
414 | 457k | uint32_t v = acc & ((1u << n) - 1); |
415 | 457k | acc >>= n; |
416 | 457k | bits -= n; |
417 | 457k | return v; |
418 | 457k | } |
419 | 0 | void align_byte() { |
420 | 0 | acc >>= (bits & 7); |
421 | 0 | bits -= (bits & 7); |
422 | 0 | } |
423 | | }; |
424 | | |
425 | | struct Huff { |
426 | | // canonical codes: for each length, list of symbols |
427 | | // Fast path: table for codes up to max_bits |
428 | | static constexpr int MAXBITS = 15; |
429 | | uint8_t lengths[288]{}; |
430 | | int counts[MAXBITS + 1]{}; |
431 | | int first_code[MAXBITS + 1]{}; |
432 | | int16_t symbols[288]{}; |
433 | | int nsymbols = 0; |
434 | | int max_bits = 0; |
435 | | |
436 | | // Base index into symbols[] for each code length (used by decode). |
437 | | int base_idx[MAXBITS + 1]{}; |
438 | | |
439 | 16 | bool build(const uint8_t* lens, int n) { |
440 | 16 | std::memset(counts, 0, sizeof(counts)); |
441 | 16 | std::memset(first_code, 0, sizeof(first_code)); |
442 | 16 | std::memset(base_idx, 0, sizeof(base_idx)); |
443 | 16 | nsymbols = n; |
444 | 16 | max_bits = 0; |
445 | 1.98k | for (int i = 0; i < n; i++) { |
446 | 1.96k | lengths[i] = lens[i]; |
447 | 1.96k | if (lens[i]) { |
448 | 1.91k | counts[lens[i]]++; |
449 | 1.91k | if (lens[i] > max_bits) max_bits = lens[i]; |
450 | 1.91k | } |
451 | 1.96k | } |
452 | | // Canonical first code for each bit length (RFC 1951). |
453 | 16 | int code = 0; |
454 | 256 | for (int bits = 1; bits <= MAXBITS; bits++) { |
455 | 240 | code = (code + counts[bits - 1]) << 1; |
456 | 240 | first_code[bits] = code; |
457 | 240 | } |
458 | 16 | int idx = 0; |
459 | 158 | for (int bits = 1; bits <= max_bits; bits++) { |
460 | 142 | base_idx[bits] = idx; |
461 | | // assign symbols in symbol order for codes of this length |
462 | 21.6k | for (int sym = 0; sym < n; sym++) { |
463 | 21.5k | if (lengths[sym] == bits) { |
464 | 1.91k | symbols[idx++] = static_cast<int16_t>(sym); |
465 | 1.91k | } |
466 | 21.5k | } |
467 | 142 | } |
468 | 16 | return true; |
469 | 16 | } |
470 | | |
471 | 68.3k | int decode(BitReader& br) const { |
472 | 68.3k | if (max_bits == 0) return -1; |
473 | 68.3k | int code = 0; |
474 | 427k | for (int len = 1; len <= max_bits; len++) { |
475 | 427k | uint32_t b = br.get(1); |
476 | 427k | if (b == UINT32_MAX) return -1; |
477 | 427k | code = (code << 1) | int(b); |
478 | 427k | int first = first_code[len]; |
479 | 427k | int cnt = counts[len]; |
480 | 427k | if (cnt && code - first < cnt) { |
481 | 68.3k | return symbols[base_idx[len] + (code - first)]; |
482 | 68.3k | } |
483 | 427k | } |
484 | 0 | return -1; |
485 | 68.3k | } |
486 | | }; |
487 | | |
488 | | // Fixed Huffman tables are built once at dynamic initialization (before main / |
489 | | // single-threaded), so concurrent first-use of inflate cannot race. |
490 | 2 | inline Huff make_fixed_litlen_huff() { |
491 | 2 | Huff h; |
492 | 2 | uint8_t lens[288]; |
493 | | // Fixed Huffman: 0-143:8, 144-255:9, 256-279:7, 280-287:8 |
494 | 290 | for (int i = 0; i <= 143; i++) lens[i] = 8; |
495 | 226 | for (int i = 144; i <= 255; i++) lens[i] = 9; |
496 | 50 | for (int i = 256; i <= 279; i++) lens[i] = 7; |
497 | 18 | for (int i = 280; i <= 287; i++) lens[i] = 8; |
498 | 2 | h.build(lens, 288); |
499 | 2 | return h; |
500 | 2 | } |
501 | | |
502 | 2 | inline Huff make_fixed_dist_huff() { |
503 | 2 | Huff h; |
504 | 2 | uint8_t lens[32]; |
505 | 66 | for (int i = 0; i < 32; i++) lens[i] = 5; |
506 | 2 | h.build(lens, 32); |
507 | 2 | return h; |
508 | 2 | } |
509 | | |
510 | | // NOLINTNEXTLINE(cert-err58-cpp) -- intentional process-lifetime tables |
511 | | inline const Huff kFixedLitLenHuff = make_fixed_litlen_huff(); |
512 | | // NOLINTNEXTLINE(cert-err58-cpp) |
513 | | inline const Huff kFixedDistHuff = make_fixed_dist_huff(); |
514 | | |
515 | 0 | inline int fixed_litlen(BitReader& br) { return kFixedLitLenHuff.decode(br); } |
516 | | |
517 | 0 | inline int fixed_dist(BitReader& br) { return kFixedDistHuff.decode(br); } |
518 | | |
519 | | // length and distance base tables |
520 | | static const uint16_t len_base[29] = { |
521 | | 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, |
522 | | 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258}; |
523 | | static const uint8_t len_extra[29] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, |
524 | | 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, |
525 | | 4, 4, 4, 4, 5, 5, 5, 5, 0}; |
526 | | static const uint16_t dist_base[30] = { |
527 | | 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, |
528 | | 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, |
529 | | 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577}; |
530 | | static const uint8_t dist_extra[30] = {0, 0, 0, 0, 1, 1, 2, 2, 3, 3, |
531 | | 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, |
532 | | 9, 9, 10, 10, 11, 11, 12, 12, 13, 13}; |
533 | | |
534 | | inline size_t inflate_raw(const uint8_t* src, size_t src_len, uint8_t* dst, |
535 | 1 | size_t dst_cap) { |
536 | 1 | BitReader br(src, src_len); |
537 | 1 | size_t out = 0; |
538 | 4 | for (;;) { |
539 | 4 | uint32_t bfinal = br.get(1); |
540 | 4 | uint32_t btype = br.get(2); |
541 | 4 | if (bfinal == UINT32_MAX || btype == UINT32_MAX) return 0; |
542 | 4 | if (btype == 0) { |
543 | | // stored |
544 | 0 | br.align_byte(); |
545 | 0 | if (!br.ensure(16)) return 0; |
546 | | // read 16+16 from bit buffer awkwardly - use byte path |
547 | | // Align: bits is multiple of 8 |
548 | | // Get len from remaining bits then bytes |
549 | 0 | uint32_t len = br.get(16); |
550 | 0 | uint32_t nlen = br.get(16); |
551 | 0 | if (len == UINT32_MAX || nlen == UINT32_MAX) return 0; |
552 | 0 | if ((len ^ 0xFFFF) != nlen) return 0; |
553 | | // After get, may have bits in acc from previous - for stored, should be |
554 | | // byte aligned Copy len bytes from p |
555 | 0 | if (br.bits != 0) { |
556 | | // leftover bits should be 0 if aligned |
557 | 0 | } |
558 | 0 | if (size_t(br.end - br.p) < len) return 0; |
559 | 0 | if (out + len > dst_cap) return 0; |
560 | 0 | std::memcpy(dst + out, br.p, len); |
561 | 0 | br.p += len; |
562 | 0 | out += len; |
563 | 4 | } else if (btype == 1 || btype == 2) { |
564 | 4 | Huff lit, dist; |
565 | 4 | if (btype == 1) { |
566 | | // use fixed via functions |
567 | 4 | } else { |
568 | | // dynamic |
569 | 4 | uint32_t hlit = br.get(5); |
570 | 4 | if (hlit == UINT32_MAX) return 0; |
571 | 4 | hlit += 257; |
572 | 4 | uint32_t hdist = br.get(5); |
573 | 4 | if (hdist == UINT32_MAX) return 0; |
574 | 4 | hdist += 1; |
575 | 4 | uint32_t hclen = br.get(4); |
576 | 4 | if (hclen == UINT32_MAX) return 0; |
577 | 4 | hclen += 4; |
578 | 4 | static const int order[19] = {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, |
579 | 4 | 11, 4, 12, 3, 13, 2, 14, 1, 15}; |
580 | 4 | uint8_t clen[19]{}; |
581 | 69 | for (uint32_t i = 0; i < hclen; i++) { |
582 | 65 | uint32_t v = br.get(3); |
583 | 65 | if (v == UINT32_MAX) return 0; |
584 | 65 | clen[order[i]] = uint8_t(v); |
585 | 65 | } |
586 | 4 | Huff cl; |
587 | 4 | if (!cl.build(clen, 19)) return 0; |
588 | 4 | uint8_t lens[288 + 32]{}; |
589 | 4 | uint32_t n = hlit + hdist; |
590 | 1.09k | for (uint32_t i = 0; i < n;) { |
591 | 1.08k | int sym = cl.decode(br); |
592 | 1.08k | if (sym < 0) return 0; |
593 | 1.08k | if (sym < 16) { |
594 | 1.03k | lens[i++] = uint8_t(sym); |
595 | 1.03k | } else if (sym == 16) { |
596 | 49 | uint32_t rep = br.get(2); |
597 | 49 | if (rep == UINT32_MAX) return 0; |
598 | 49 | rep += 3; |
599 | 49 | if (i == 0) return 0; |
600 | 49 | uint8_t v = lens[i - 1]; |
601 | 263 | while (rep--) lens[i++] = v; |
602 | 49 | } else if (sym == 17) { |
603 | 0 | uint32_t rep = br.get(3); |
604 | 0 | if (rep == UINT32_MAX) return 0; |
605 | 0 | rep += 3; |
606 | 0 | while (rep--) lens[i++] = 0; |
607 | 0 | } else if (sym == 18) { |
608 | 0 | uint32_t rep = br.get(7); |
609 | 0 | if (rep == UINT32_MAX) return 0; |
610 | 0 | rep += 11; |
611 | 0 | while (rep--) lens[i++] = 0; |
612 | 0 | } else |
613 | 0 | return 0; |
614 | 1.08k | } |
615 | 4 | if (!lit.build(lens, int(hlit))) return 0; |
616 | 4 | if (!dist.build(lens + hlit, int(hdist))) return 0; |
617 | 4 | } |
618 | 52.2k | for (;;) { |
619 | 52.2k | int sym; |
620 | 52.2k | if (btype == 1) |
621 | 0 | sym = fixed_litlen(br); |
622 | 52.2k | else |
623 | 52.2k | sym = lit.decode(br); |
624 | 52.2k | if (sym < 0) return 0; |
625 | 52.2k | if (sym < 256) { |
626 | 37.2k | if (out >= dst_cap) return 0; |
627 | 37.2k | dst[out++] = uint8_t(sym); |
628 | 37.2k | } else if (sym == 256) { |
629 | 4 | break; |
630 | 14.9k | } else { |
631 | 14.9k | int len_code = sym - 257; |
632 | 14.9k | if (len_code < 0 || len_code > 28) return 0; |
633 | 14.9k | uint32_t extra = br.get(len_extra[len_code]); |
634 | 14.9k | if (len_extra[len_code] && extra == UINT32_MAX) return 0; |
635 | 14.9k | uint32_t length = |
636 | 14.9k | len_base[len_code] + (len_extra[len_code] ? extra : 0); |
637 | 14.9k | int dsym; |
638 | 14.9k | if (btype == 1) |
639 | 0 | dsym = fixed_dist(br); |
640 | 14.9k | else |
641 | 14.9k | dsym = dist.decode(br); |
642 | 14.9k | if (dsym < 0 || dsym > 29) return 0; |
643 | 14.9k | uint32_t dextra = br.get(dist_extra[dsym]); |
644 | 14.9k | if (dist_extra[dsym] && dextra == UINT32_MAX) return 0; |
645 | 14.9k | uint32_t distance = dist_base[dsym] + (dist_extra[dsym] ? dextra : 0); |
646 | 14.9k | if (distance > out || out + length > dst_cap) return 0; |
647 | 202k | for (uint32_t k = 0; k < length; k++) { |
648 | 187k | dst[out] = dst[out - distance]; |
649 | 187k | out++; |
650 | 187k | } |
651 | 14.9k | } |
652 | 52.2k | } |
653 | 4 | } else { |
654 | 0 | return 0; // reserved |
655 | 0 | } |
656 | 4 | if (bfinal) break; |
657 | 4 | } |
658 | 1 | return out; |
659 | 1 | } |
660 | | |
661 | | } // namespace ada::idna::deflate |
662 | | /* end file src/raw_inflate.hpp */ |
663 | | /* begin file src/table_blob.inc */ |
664 | | // Auto-generated by scripts/pack_tables.py - do not edit. |
665 | | // Compressed Unicode/IDNA tables (raw DEFLATE). |
666 | | // clang-format off |
667 | | #ifndef ADA_IDNA_TABLE_BLOB_H |
668 | | #define ADA_IDNA_TABLE_BLOB_H |
669 | | #include <cstdint> |
670 | | #include <cstddef> |
671 | | namespace ada::idna::table_blob { |
672 | | constexpr size_t uncompressed_size = 224608; |
673 | | constexpr size_t compressed_size = 62377; |
674 | | constexpr uint32_t uncompressed_crc32 = 0x6F4A6B2Eu; |
675 | | constexpr size_t decomposition_block_rows = 67; |
676 | | constexpr size_t decomposition_block_cols = 257; |
677 | | constexpr size_t ccc_block_rows = 67; |
678 | | constexpr size_t ccc_block_cols = 256; |
679 | | constexpr size_t composition_block_rows = 67; |
680 | | constexpr size_t composition_block_cols = 257; |
681 | | constexpr size_t id_continue_count = 1418; |
682 | | constexpr size_t id_start_count = 776; |
683 | | constexpr size_t dir_table_count = 1449; |
684 | | constexpr size_t combining_range_count = 290; |
685 | | // Offsets into the decompressed buffer: |
686 | | constexpr size_t off_idna_stage1 = 0; |
687 | | constexpr size_t count_idna_stage1 = 3282; |
688 | | constexpr size_t off_idna_stage2 = 6564; |
689 | | constexpr size_t count_idna_stage2 = 11456; |
690 | | constexpr size_t off_idna_bool_blocks = 29480; |
691 | | constexpr size_t count_idna_bool_blocks = 225; |
692 | | constexpr size_t off_idna_utf8_mappings = 31280; |
693 | | constexpr size_t count_idna_utf8_mappings = 17383; |
694 | | constexpr size_t off_decomposition_index = 48663; |
695 | | constexpr size_t count_decomposition_index = 4352; |
696 | | constexpr size_t off_decomposition_block = 53016; |
697 | | constexpr size_t count_decomposition_block = 17219; |
698 | | constexpr size_t off_decomposition_data = 87456; |
699 | | constexpr size_t count_decomposition_data = 9102; |
700 | | constexpr size_t off_ccc_index = 123864; |
701 | | constexpr size_t count_ccc_index = 4352; |
702 | | constexpr size_t off_ccc_block = 128216; |
703 | | constexpr size_t count_ccc_block = 17152; |
704 | | constexpr size_t off_composition_index = 145368; |
705 | | constexpr size_t count_composition_index = 4352; |
706 | | constexpr size_t off_composition_block = 149720; |
707 | | constexpr size_t count_composition_block = 17219; |
708 | | constexpr size_t off_composition_data = 184160; |
709 | | constexpr size_t count_composition_data = 1883; |
710 | | constexpr size_t off_id_continue_flat = 191692; |
711 | | constexpr size_t count_id_continue_flat = 2836; |
712 | | constexpr size_t off_id_start_flat = 203036; |
713 | | constexpr size_t count_id_start_flat = 1552; |
714 | | constexpr size_t off_dir_start = 209244; |
715 | | constexpr size_t count_dir_start = 1449; |
716 | | constexpr size_t off_dir_final = 215040; |
717 | | constexpr size_t count_dir_final = 1449; |
718 | | constexpr size_t off_dir_value = 220836; |
719 | | constexpr size_t count_dir_value = 1449; |
720 | | constexpr size_t off_combining_flat = 222288; |
721 | | constexpr size_t count_combining_flat = 580; |
722 | | alignas(8) inline constexpr uint8_t compressed[] = { |
723 | | 0xec,0x9c,0x09,0x40,0x53,0xc7,0xda,0xfe,0x5f,0x08,0x98,0x28,0x4b,0x4c,0xc2,0x12, |
724 | | 0x14,0x09,0x12,0x42,0x12,0x76,0x12,0x20,0xec,0x09,0xd0,0xdd,0x56,0xdb,0xda,0xdd, |
725 | | 0x5b,0x5b,0x97,0x6a,0xdd,0xad,0xb6,0xda,0xc5,0x96,0x23,0xbb,0xa2,0xe0,0xbe,0xb0, |
726 | | 0x8a,0xa8,0xa8,0x88,0x08,0xa8,0xec,0xcb,0x2d,0x2a,0x62,0xad,0x88,0xa8,0xdd,0xeb, |
727 | | 0x56,0x36,0x6d,0x6b,0x5b,0xdb,0xda,0xd6,0x96,0xfc,0x9f,0x73,0x12,0xd4,0xb6,0xf6, |
728 | | 0xb6,0xb7,0xcb,0xfd,0xbe,0xfb,0xfd,0x9b,0xe1,0x37,0x33,0xe7,0x9c,0x99,0x79,0xde, |
729 | | 0x79,0xcf,0x9c,0x73,0x66,0x4e,0x00,0x62,0x88,0x0c,0xc4,0x50,0x33,0x91,0x85,0xc1, |
730 | | 0x82,0xb1,0x68,0xb6,0x20,0x4b,0x83,0x25,0x63,0x49,0x4c,0xb3,0x25,0xf1,0x0c,0x3c, |
731 | | 0x86,0xd7,0xcc,0x23,0x2b,0x83,0x15,0x63,0xd5,0x6c,0x45,0xd6,0x16,0x8c,0x25,0x63, |
732 | | 0xb0,0x26,0x86,0xc7,0x58,0x31,0xd6,0xcc,0x20,0x86,0xcf,0x08,0x98,0xc1,0xcc,0x10, |
733 | | 0xc6,0x86,0x21,0x86,0xb1,0xb6,0x65,0x9a,0xad,0x69,0x90,0x61,0x90,0x1d,0x63,0xcf, |
734 | | 0x08,0x19,0x66,0xd0,0x50,0x46,0xc4,0x88,0x19,0x09,0xe3,0xc0,0x38,0x32,0x4e,0x8c, |
735 | | 0x33,0x23,0x65,0x5c,0x98,0xe6,0x41,0xc3,0x18,0xe2,0x1b,0xf8,0x0c,0xbf,0x99,0x4f, |
736 | | 0x82,0xe1,0xa8,0x47,0x8c,0x41,0xc0,0x08,0xa0,0x27,0x20,0x6e,0xcb,0x95,0x19,0xc1, |
737 | | 0xb8,0x31,0x32,0xc6,0x9d,0x19,0xc9,0xd0,0x60,0xd3,0xbe,0x1f,0x07,0x0f,0x46,0xce, |
738 | | 0x78,0x32,0x0a,0xc6,0x30,0xd8,0x8b,0x61,0x06,0xcb,0x19,0x25,0xa3,0x62,0xd4,0x8c, |
739 | | 0x37,0xe3,0xc3,0xf8,0x32,0x7e,0x8c,0x3f,0x13,0xc0,0x04,0xa2,0x54,0x10,0xd0,0x30, |
740 | | 0x5a,0x26,0x98,0x69,0x1e,0x1c,0xc2,0xd0,0x10,0xc3,0x10,0x66,0x08,0x54,0x86,0x90, |
741 | | 0x8d,0xc1,0x86,0xb1,0x69,0xb6,0x21,0x5b,0x83,0x2d,0x63,0xdb,0x6c,0x4b,0x76,0x06, |
742 | | 0xbb,0x50,0x86,0xb1,0x6b,0xb6,0x23,0x7b,0xd8,0x62,0x6f,0xd2,0x60,0xcc,0xa9,0x8e, |
743 | | 0x69,0xb6,0x27,0xa1,0x41,0x78,0x2b,0x3b,0x6e,0x15,0x18,0x61,0x33,0x5b,0x76,0x28, |
744 | | 0x31,0x61,0xa6,0xbe,0x0d,0x65,0x86,0x36,0x0f,0x25,0x51,0x38,0x63,0x10,0x45,0x30, |
745 | | 0x91,0xd8,0x13,0xc5,0x30,0xa2,0x66,0x11,0x89,0x0d,0x62,0x46,0xdc,0x2c,0x26,0x49, |
746 | | 0x34,0x63,0x90,0x30,0x92,0x66,0x09,0x39,0x18,0x1c,0x62,0x18,0xc6,0xa1,0xd9,0x81, |
747 | | 0x1c,0x0d,0x8e,0x8c,0x63,0xb3,0x23,0x39,0x19,0x9c,0x7e,0xab,0xee,0xdf,0xe1,0xef, |
748 | | 0xf0,0x77,0xf8,0x6b,0x82,0x9e,0x31,0x5c,0xcf,0xc7,0x32,0x8c,0x53,0xb3,0x53,0x1c, |
749 | | 0x43,0xce,0x06,0x67,0xc6,0xb9,0xd9,0x39,0x9e,0x41,0x9e,0xb9,0x0d,0xdc,0x0e,0xee, |
750 | | 0x60,0xee,0x64,0xee,0x42,0x7a,0x37,0x73,0x0f,0x43,0x52,0x83,0x74,0xd4,0xdf,0xde, |
751 | | 0xfb,0x0b,0xc3,0xbd,0xcc,0x7d,0xcc,0xe8,0xbf,0x03,0x17,0x18,0x69,0xb3,0x94,0x5c, |
752 | | 0x0c,0x2e,0x8c,0x4b,0xb3,0x0b,0x0d,0x33,0x0c,0x63,0x86,0x35,0x0f,0xa3,0xe1,0x86, |
753 | | 0xe1,0xcc,0xf0,0xe6,0xe1,0xe4,0x6a,0x70,0x65,0x5c,0x9b,0x5d,0x69,0x84,0x61,0x04, |
754 | | 0x33,0xa2,0x79,0x04,0xb9,0x19,0xdc,0x18,0xb7,0x66,0x37,0x92,0x19,0x64,0x63,0x98, |
755 | | 0xfb,0xe1,0xc9,0x07,0x98,0x07,0x11,0x8f,0x65,0x1e,0xe2,0xda,0x7a,0x98,0x79,0x84, |
756 | | 0x79,0x94,0x79,0x8c,0x79,0x9c,0x79,0x82,0x61,0x64,0x78,0x66,0xca,0xc8,0x7d,0x1c, |
757 | | 0x63,0x70,0x67,0xdc,0xff,0x71,0xdd,0xf7,0x77,0x32,0x4f,0x32,0xcd,0xee,0xa3,0x99, |
758 | | 0xf1,0xcc,0x53,0xcc,0xd3,0xcc,0x04,0x66,0x22,0x33,0x89,0x99,0xcc,0x3c,0xc3,0x4c, |
759 | | 0x61,0xa6,0x32,0xcf,0x32,0xd3,0x98,0xe9,0xcc,0x0c,0x66,0x26,0xda,0x22,0x66,0x16, |
760 | | 0x43,0x23,0x67,0x33,0x73,0x18,0xc3,0xc8,0xb9,0x5c,0xeb,0xcf,0x31,0xf3,0x98,0xf9, |
761 | | 0xcc,0x38,0xe6,0x79,0xe6,0x05,0x66,0x01,0x8e,0x2f,0x64,0x5e,0x64,0x5e,0x62,0x5e, |
762 | | 0x66,0x5e,0x41,0x7e,0x11,0xf3,0x2a,0xf3,0x1a,0x93,0xc0,0x30,0xcc,0x62,0x26,0x91, |
763 | | 0x49,0x62,0x92,0xb1,0x2f,0x05,0xa4,0x72,0x35,0xd3,0xf0,0xec,0x24,0x26,0x9d,0x59, |
764 | | 0xc2,0x2c,0x65,0x32,0x98,0x65,0xdc,0xbe,0xe5,0x6c,0xdf,0x47,0x66,0x32,0x59,0xcc, |
765 | | 0x0a,0x66,0x25,0xb3,0x0a,0xc7,0x57,0x33,0x6b,0x30,0x3f,0x58,0xcb,0xac,0xc3,0x91, |
766 | | 0xf5,0xcc,0x06,0x66,0x23,0x93,0x8d,0x5c,0x0e,0x93,0xcb,0xe4,0x31,0xf9,0x66,0x6f, |
767 | | 0x15,0x30,0x9b,0x98,0x42,0x66,0x33,0x53,0xf4,0x2f,0xc7,0xd7,0x24,0xce,0xfe,0x2d, |
768 | | 0xe6,0xad,0xad,0x7f,0xfa,0x39,0xdb,0xc6,0x14,0xff,0xea,0x18,0xdf,0xce,0xec,0xf8, |
769 | | 0x1f,0xbc,0xc2,0x1e,0xb8,0xc5,0xbe,0x65,0xff,0x27,0xaf,0x9f,0x25,0xbf,0xb3,0xde, |
770 | | 0x4f,0xbd,0x23,0x67,0x76,0x32,0x25,0xcc,0x2e,0xe4,0x4a,0x99,0xdd,0xb7,0x54,0x68, |
771 | | 0x1e,0x49,0x1e,0x65,0x38,0xbe,0x87,0x29,0x67,0x2a,0xfe,0x3f,0xb9,0x53,0x57,0x32, |
772 | | 0x7b,0x39,0x5f,0x15,0xff,0x7d,0xa7,0xfe,0x51,0xd8,0x77,0xdd,0x43,0xfb,0x99,0xaa, |
773 | | 0x9b,0xfc,0xb5,0xfc,0x4f,0x53,0x20,0xa6,0x9a,0x31,0x78,0xfc,0xcf,0xf5,0xd0,0xbc, |
774 | | 0x2a,0xf2,0xb8,0x79,0x34,0xd4,0x30,0xb5,0x4c,0x1d,0x37,0xa7,0xda,0x6a,0xde,0xa3, |
775 | | 0x62,0xea,0x99,0x66,0x0f,0x92,0x1b,0xe4,0xc4,0x34,0xa0,0x56,0x23,0xf6,0x35,0x99, |
776 | | 0x9e,0x6b,0xf2,0x66,0x39,0x79,0x1a,0x3c,0x19,0xcf,0x66,0x4f,0x52,0x18,0x14,0x8c, |
777 | | 0xa2,0x59,0x41,0x5e,0x06,0x2f,0xc6,0xab,0xd9,0x8b,0x94,0x06,0xe5,0xad,0x46,0x5b, |
778 | | 0xf3,0x6f,0xb0,0xeb,0x9f,0x03,0xcf,0x4d,0x65,0xb3,0xf2,0x75,0xa4,0x2d,0xcc,0x81, |
779 | | 0xeb,0xc7,0x0e,0x32,0x87,0x7e,0x52,0xba,0xd5,0x9c,0x1e,0x36,0xa7,0x6d,0xe6,0xf4, |
780 | | 0x88,0x59,0xf1,0x0d,0x86,0x54,0x47,0x7f,0x41,0xe9,0x4d,0xe6,0x18,0xe2,0x76,0xf3, |
781 | | 0x96,0x41,0xc5,0xa8,0x9a,0x55,0xc7,0xaf,0x1f,0xf5,0x41,0xed,0x0e,0xe6,0x04,0x43, |
782 | | 0x6a,0x83,0x9a,0x51,0x77,0x32,0xcd,0x6a,0xf2,0xbe,0xd5,0x7d,0xe5,0xc7,0xe1,0xa4, |
783 | | 0x39,0x3d,0xc5,0x9c,0x66,0xde,0x62,0xde,0x66,0xde,0xb9,0xe9,0xd8,0xbb,0xcc,0x7b, |
784 | | 0xcc,0xfb,0x5c,0xee,0x03,0xc6,0xe0,0xfd,0xef,0xde,0xbf,0xfe,0x0e,0x7f,0x87,0xbf, |
785 | | 0xc3,0xdf,0xe1,0xef,0xf0,0xaf,0xc2,0xb3,0xff,0x6b,0x2c,0xf9,0xf0,0xbf,0xd0,0x7b, |
786 | | 0x75,0xff,0xdf,0x8c,0x93,0x33,0xb7,0xd8,0x17,0xf5,0xe7,0xae,0xfb,0xbd,0x9b,0xbd, |
787 | | 0xc9,0xc7,0xe0,0xc3,0xf8,0x34,0xfb,0x90,0xaf,0xc1,0x97,0xf1,0xfd,0x63,0xeb,0x97, |
788 | | 0xff,0x3d,0xe1,0xec,0xdf,0xf7,0x19,0x2e,0x2c,0x61,0x8c,0x46,0x0b,0xe2,0x91,0x35, |
789 | | 0xf1,0x69,0x30,0xd9,0x90,0x1d,0x09,0x49,0x44,0x12,0x72,0x24,0x67,0x72,0xa1,0xe1, |
790 | | 0x34,0x82,0x64,0x34,0x92,0xe4,0xa4,0x20,0x25,0xa9,0xc9,0x87,0xfc,0x28,0x80,0x82, |
791 | | 0x48,0x4b,0xc6,0x3f,0xed,0xd3,0xff,0x07,0x43,0xc8,0x4f,0x6c,0xd1,0x11,0xdb,0x23, |
792 | | 0x36,0x47,0x88,0x23,0xb9,0x9c,0x9e,0x62,0x29,0x9e,0xee,0xe4,0xf2,0xf7,0xd0,0x68, |
793 | | 0xf4,0xca,0x68,0xbc,0x9f,0x1e,0xa1,0x7f,0x20,0x9d,0x48,0xcf,0xd0,0xb3,0x34,0x83, |
794 | | 0x66,0xd3,0x73,0xf4,0x3c,0x2d,0xa4,0x97,0xe9,0x55,0x38,0x26,0x89,0x52,0x69,0x09, |
795 | | 0x2d,0xa3,0x2c,0x5a,0x45,0x6b,0x69,0x03,0xe5,0x50,0x3e,0x15,0xd2,0x16,0x94,0x2f, |
796 | | 0xa6,0x9d,0x54,0x4a,0x7b,0xa8,0x92,0xf6,0x53,0xcd,0x9f,0xe0,0x87,0x7a,0xb4,0xd1, |
797 | | 0x04,0x5e,0x07,0x07,0xc1,0x61,0xf0,0x06,0x38,0x06,0x3a,0xc0,0x49,0xf0,0x16,0x78, |
798 | | 0x17,0x7c,0x00,0xce,0x82,0x0b,0xa0,0x1b,0xf4,0x81,0x8f,0xc1,0x65,0xf0,0x05,0xf8, |
799 | | 0x0a,0x7c,0x03,0xae,0x81,0x7e,0xd6,0x0f,0x16,0x46,0xa3,0x15,0x10,0x58,0x08,0x2c, |
800 | | 0x6c,0x90,0xda,0x5b,0xb0,0x8a,0x22,0xc4,0x0e,0xc0,0x19,0x0c,0xb3,0x18,0x66,0xe1, |
801 | | 0x86,0x74,0x24,0xf0,0x04,0x4a,0xe0,0x6d,0xe1,0x8f,0x38,0x08,0x04,0x03,0x1d,0x88, |
802 | | 0x00,0xd1,0xc0,0x00,0xe2,0xc1,0x1d,0xe0,0x6e,0x70,0x2f,0x18,0x03,0x1e,0x04,0x0f, |
803 | | 0x83,0xc7,0xc0,0x38,0x30,0x1e,0x4c,0x00,0x93,0xc1,0x54,0x30,0x1d,0xcc,0x02,0x73, |
804 | | 0xc1,0x7c,0x8b,0x05,0x88,0x5f,0x02,0x8b,0x80,0x02,0x56,0x26,0x58,0x24,0x22,0x97, |
805 | | 0x02,0xd2,0x2d,0x32,0x10,0x67,0x5a,0xac,0xb4,0x58,0xc3,0x59,0xba,0xde,0x22,0xdb, |
806 | | 0x22,0xcf,0x62,0x13,0xf2,0x45,0x16,0xdb,0x10,0xef,0xb0,0xd8,0x65,0x51,0x66,0x61, |
807 | | 0xf2,0x5b,0x85,0xc5,0x3e,0xe4,0xaa,0x2d,0xea,0x10,0x37,0x82,0x7f,0x82,0x03,0x16, |
808 | | 0xad,0x88,0x8f,0x70,0x25,0xde,0x44,0x7c,0xdc,0xa2,0x13,0xf1,0x69,0x8b,0x77,0x2c, |
809 | | 0xde,0x47,0x7a,0x06,0x9c,0xb7,0xe8,0x32,0xd7,0xef,0xb5,0xf8,0xf1,0x79,0xb8,0x64, |
810 | | 0xc1,0x86,0xcb,0x5c,0xf8,0x82,0x0b,0x5f,0xa1,0xc4,0x37,0xe0,0x1a,0xe8,0x07,0x16, |
811 | | 0x96,0xf0,0x26,0xe0,0x83,0x21,0x96,0x6c,0x1d,0x3b,0xc4,0x43,0x81,0x04,0x38,0x01, |
812 | | 0x17,0xe0,0x0a,0x64,0xc0,0x03,0x28,0xb8,0x52,0x2a,0x4b,0x36,0xf8,0x20,0xef,0x6f, |
813 | | 0x19,0x64,0x19,0x8c,0x54,0x07,0x22,0x40,0x34,0x30,0x80,0x78,0x70,0x07,0xb8,0x1b, |
814 | | 0xdc,0x0b,0xc6,0x80,0x07,0xc1,0xc3,0xe0,0x31,0x30,0x0e,0x8c,0x07,0x13,0xc0,0x64, |
815 | | 0x30,0x15,0x4c,0x07,0xb3,0xc0,0x5c,0x30,0x1f,0x2c,0x00,0x2f,0x81,0x45,0x20,0x01, |
816 | | 0x24,0x82,0x14,0x90,0x0e,0x32,0x2c,0x7f,0xdc,0xd7,0x4c,0xcb,0x55,0xd8,0xb3,0xd6, |
817 | | 0x72,0x03,0xb7,0x3f,0x17,0x71,0x81,0xe5,0x66,0xcb,0xad,0x96,0xdb,0x91,0x2b,0x01, |
818 | | 0xbb,0x41,0x39,0xd8,0x6b,0x69,0xfc,0xaf,0xff,0x08,0xa9,0xca,0x52,0x82,0x3b,0x58, |
819 | | 0xad,0x65,0x83,0x65,0xb3,0xa5,0x1f,0xee,0x5e,0x7f,0xac,0xbd,0x16,0xcb,0x56,0xcb, |
820 | | 0x37,0x2c,0xdb,0x2d,0x3b,0x2d,0xdf,0xe2,0xbc,0xb3,0xcd,0xc2,0x19,0x77,0xc7,0x00, |
821 | | 0x7a,0xef,0x77,0xfa,0xea,0x43,0xcb,0x73,0xa8,0xf9,0x91,0x65,0x8f,0xe5,0xc7,0xb7, |
822 | | 0x68,0x81,0xfe,0xf0,0x1d,0xe6,0x32,0x5a,0xfd,0x02,0x7c,0x05,0xbe,0xb1,0x34,0xdd, |
823 | | 0x6f,0xaf,0x0d,0x28,0x59,0x5a,0xf0,0x06,0xee,0xa3,0xf1,0x64,0xc5,0x1b,0xc2,0xb3, |
824 | | 0xe3,0x0d,0xe5,0x49,0x78,0x4e,0xd8,0xeb,0x02,0x5c,0x79,0x32,0x1e,0x46,0x32,0x4f, |
825 | | 0xc1,0x53,0xf1,0x7c,0x78,0xfe,0xbc,0x20,0x5e,0x30,0x4f,0xc7,0xfb,0xd8,0x32,0x82, |
826 | | 0x17,0xcd,0xbb,0x93,0x0c,0xbc,0x78,0xde,0x1d,0xbc,0xbb,0x79,0xf7,0xa2,0xe4,0x18, |
827 | | 0xde,0x83,0xbc,0x87,0x79,0x8f,0xf1,0xc6,0xf1,0xc6,0xf3,0x26,0xf0,0x26,0xf3,0xa6, |
828 | | 0xf2,0xfe,0x9c,0xb3,0x37,0x1d,0xda,0x3a,0xb4,0xec,0x8a,0x16,0x1f,0x83,0x16,0xc6, |
829 | | 0x3c,0x98,0x0b,0xe6,0x83,0x05,0xe0,0x25,0xb0,0x08,0x24,0x80,0x44,0x90,0x02,0xd2, |
830 | | 0x41,0x06,0xc8,0x04,0x11,0xb0,0x6f,0x0c,0x52,0x1d,0xec,0x37,0x1a,0x57,0x82,0x31, |
831 | | 0xbc,0x35,0x9c,0x75,0xeb,0x79,0xd9,0xbc,0x3c,0xde,0x26,0x5e,0x11,0x6f,0x1b,0x6f, |
832 | | 0x07,0x6f,0x17,0xaf,0x8c,0x57,0xc1,0xdb,0xc7,0xab,0xe6,0xd5,0xf1,0x1a,0x79,0xff, |
833 | | 0xe4,0x1d,0xe0,0xb5,0xf2,0x8e,0xf0,0xde,0xe4,0x1d,0xe7,0x75,0xf2,0x4e,0xf3,0xde, |
834 | | 0xe1,0xbd,0xcf,0x3b,0xc3,0x3b,0xcf,0xeb,0xe2,0xf5,0xf2,0x2e,0xf1,0x3e,0xe5,0x7d, |
835 | | 0xce,0xfb,0x92,0x77,0x95,0xf7,0x1d,0xef,0x07,0x1e,0xdc,0x66,0x35,0xc8,0x6a,0xb0, |
836 | | 0x95,0xad,0x95,0xd0,0x4a,0x6c,0xe5,0x68,0x25,0xb5,0x1a,0x6e,0xe5,0x66,0x35,0xd2, |
837 | | 0xca,0xd3,0x4a,0x69,0xe5,0x6d,0xe5,0x67,0xf5,0x57,0x8f,0xef,0x40,0x28,0x68,0x41, |
838 | | 0x28,0x08,0x07,0x51,0x40,0x0f,0xe2,0xc0,0xed,0xe0,0x2e,0x30,0x0a,0x8c,0x06,0x0f, |
839 | | 0x80,0x87,0xc0,0xa3,0xe0,0x09,0xf0,0x24,0x78,0xfa,0x16,0x16,0x4e,0xc2,0xbe,0x29, |
840 | | 0x60,0x1a,0x98,0x09,0xe6,0x80,0x79,0xe0,0x05,0xf0,0x22,0x78,0x05,0xbc,0x06,0x16, |
841 | | 0x83,0x64,0x90,0x06,0x96,0x82,0xe5,0x60,0x05,0x58,0x0d,0xd6,0x81,0x8d,0x20,0x17, |
842 | | 0x14,0x80,0xcd,0x60,0x2b,0xd8,0x0e,0x4a,0xc0,0x6e,0x50,0x0e,0xf6,0x5a,0x55,0x21, |
843 | | 0xae,0x05,0x0d,0xa0,0x19,0xb4,0x80,0x43,0xa0,0x8d,0xb3,0xec,0x28,0xe2,0x76,0x70, |
844 | | 0x02,0x9c,0x02,0x6f,0x83,0xf7,0xc0,0x87,0xe0,0x1c,0xf8,0x08,0xf4,0x80,0x8b,0xe0, |
845 | | 0x13,0xf0,0x19,0xb8,0x02,0xbe,0x06,0xdf,0x82,0xef,0xd9,0x56,0x80,0xa5,0xb5,0xd1, |
846 | | 0x68,0x0d,0x04,0xc0,0x06,0xd8,0x03,0x11,0x70,0x00,0xce,0x60,0x18,0x18,0x01,0xdc, |
847 | | 0x81,0x1c,0x78,0x01,0x35,0xf0,0x05,0x01,0x40,0x03,0x42,0x40,0x18,0x88,0x04,0x31, |
848 | | 0x20,0x16,0xdc,0x06,0xee,0x04,0xf7,0x80,0xfb,0xc0,0xfd,0x60,0x2c,0x78,0x04,0x3c, |
849 | | 0x6e,0xcd,0x5e,0x6f,0xff,0xb0,0x7e,0xca,0x7a,0xa2,0xf5,0x33,0xd6,0xcf,0x5a,0xcf, |
850 | | 0xb0,0x9e,0x6d,0xfd,0x9c,0xf5,0xf3,0xd6,0x0b,0xad,0x5f,0xb6,0x7e,0xd5,0x9a,0xb1, |
851 | | 0x4e,0xb2,0x4e,0xb5,0x5e,0x62,0xbd,0xcc,0x3a,0xcb,0x7a,0x95,0xf5,0x5a,0xeb,0x0d, |
852 | | 0xd6,0x39,0xd6,0xf9,0xd6,0x85,0xd6,0x5b,0xac,0x8b,0xad,0x77,0x5a,0x97,0x5a,0xef, |
853 | | 0xb1,0xae,0xb4,0xde,0x6f,0x5d,0x63,0x5d,0x6f,0xdd,0x64,0xfd,0xba,0xf5,0x41,0xeb, |
854 | | 0xc3,0xd6,0x6f,0x58,0xb3,0x57,0xea,0x5f,0xf9,0x39,0x66,0x7d,0x63,0x56,0x36,0x90, |
855 | | 0xfb,0xbf,0xf2,0xe9,0xb4,0x7e,0xdb,0xfa,0x03,0xeb,0xf3,0xd6,0x7f,0xac,0x95,0x1e, |
856 | | 0xeb,0x4f,0xad,0xbf,0xb2,0xfe,0xde,0x9a,0x37,0x68,0xc8,0x20,0xd1,0x20,0xe9,0xa0, |
857 | | 0x3f,0x77,0x26,0xfc,0x63,0xdf,0xff,0x7c,0x76,0x7c,0x63,0x8f,0x6c,0x90,0xd7,0xa0, |
858 | | 0x7e,0xa3,0xdf,0xa0,0x9f,0xd6,0xfe,0x7d,0x9a,0x3f,0x3d,0xcf,0x37,0xf4,0xfe,0xfd, |
859 | | 0x96,0xfb,0x6f,0xb1,0x1d,0x3c,0x88,0x8d,0x23,0x07,0xdd,0xdc,0x62,0xff,0xaf,0xea, |
860 | | 0xfd,0xb4,0xcf,0xa6,0x10,0x37,0xe8,0xee,0x41,0xf7,0x0f,0x62,0xf7,0x3e,0x3a,0xe8, |
861 | | 0xa7,0xde,0xf9,0xf7,0x57,0x1b,0xff,0xca,0xff,0xb7,0x2a,0x39,0xb0,0x35,0x7e,0xd0, |
862 | | 0x33,0x83,0xfa,0x6f,0xe9,0xc9,0xdf,0x6f,0xc1,0x5f,0xf7,0x99,0x39,0xc8,0xf8,0x0b, |
863 | | 0xe7,0xb7,0xff,0xfa,0x39,0xea,0xff,0x17,0xe7,0xf0,0xb7,0x9d,0xf5,0x5f,0xae,0x35, |
864 | | 0x7f,0xd0,0xbf,0x1e,0x7d,0xbf,0xd4,0x42,0xff,0x2f,0xfa,0xf0,0xe5,0x41,0x8b,0x07, |
865 | | 0xfd,0x19,0xeb,0xc7,0x5f,0xfa,0xa4,0x0f,0xfa,0x4f,0xde,0x9b,0x96,0x0d,0xfa,0x79, |
866 | | 0x8f,0x57,0x5f,0xdf,0x97,0x7d,0x3d,0x57,0x78,0x3d,0xb7,0xfd,0x17,0xed,0x2b,0x1b, |
867 | | 0xf4,0xf3,0x6b,0x6a,0x3f,0xf6,0x35,0x0c,0x3a,0x30,0xe8,0x8d,0x41,0xa7,0x06,0xbd, |
868 | | 0xff,0x93,0x9a,0xdd,0xbf,0xa1,0xa7,0x9f,0xdc,0xc2,0xbe,0x2f,0xaf,0xef,0xbb,0x76, |
869 | | 0x3d,0x67,0xc9,0x1f,0xc8,0x0d,0xe6,0xff,0x52,0x5b,0x43,0xf9,0x7f,0xe6,0x93,0xc5, |
870 | | 0x99,0x3f,0x9c,0x2f,0xe3,0xcb,0xf9,0x4a,0xbe,0x0f,0x3f,0x80,0xaf,0xe5,0xeb,0xf8, |
871 | | 0x91,0x7c,0x3d,0x3f,0x9e,0x7f,0x27,0x7f,0x14,0x7f,0x0c,0x7f,0x2c,0xff,0x51,0xfe, |
872 | | 0x38,0xfe,0x53,0xfc,0x49,0xfc,0xa9,0xfc,0x19,0xfc,0x39,0xfc,0xf9,0xfc,0x85,0xfc, |
873 | | 0x57,0xf8,0x09,0xfc,0x24,0x7e,0x1a,0x3f,0x83,0x9f,0xc5,0x5f,0xcd,0x5f,0xcf,0xcf, |
874 | | 0xe1,0x17,0xf0,0x8b,0xf8,0xc5,0xfc,0x12,0x7e,0xbf,0xb1,0x8c,0x7f,0x63,0x64,0x54, |
875 | | 0xf2,0xff,0xca,0xab,0xb3,0x8a,0xff,0x67,0xb4,0x42,0x44,0x64,0xfc,0xaf,0xf9,0xb0, |
876 | | 0xfe,0xac,0xe3,0x37,0xf1,0x5b,0xf8,0xad,0xfc,0x37,0xf8,0xed,0xfc,0xfe,0xff,0xe0, |
877 | | 0xec,0xe2,0xdf,0xf3,0x14,0x5d,0xff,0xfc,0xda,0x3d,0xfc,0x8f,0x7e,0x4e,0x63,0x65, |
878 | | 0xf1,0x1d,0x8f,0x5d,0x43,0x0c,0xc2,0xba,0x41,0x6b,0xd5,0xc9,0x7f,0x8b,0x7f,0xb3, |
879 | | 0xc2,0x7b,0xfc,0x33,0xfc,0x0b,0xfc,0x1e,0xfe,0x25,0xfe,0x65,0xfe,0x15,0xfe,0x55, |
880 | | 0xfe,0x35,0xbe,0x91,0xcf,0x13,0xf0,0x05,0x55,0x7c,0x1b,0x81,0x50,0x20,0x11,0x38, |
881 | | 0x0b,0x86,0x0b,0x64,0x02,0xb9,0x40,0x29,0xf0,0x11,0x04,0x08,0xb4,0x02,0x9d,0x20, |
882 | | 0x52,0xa0,0x17,0xc4,0x0b,0xee,0x14,0x8c,0x12,0x8c,0x11,0x8c,0x15,0x3c,0x2a,0x18, |
883 | | 0x27,0x78,0x4a,0x30,0x49,0x30,0x55,0x30,0x43,0x30,0x47,0x30,0x5f,0xb0,0x50,0xf0, |
884 | | 0x8a,0x20,0x41,0xc0,0xb6,0x9c,0x24,0x48,0x13,0x64,0x08,0xfe,0x2a,0x7f,0x5b,0xd0, |
885 | | 0xf3,0xc4,0x83,0xf7,0xd8,0xf7,0x8a,0xeb,0x2d,0x7e,0xfa,0x5e,0x11,0x73,0x6d,0x9a, |
886 | | 0x6f,0x29,0xc3,0xba,0x9c,0x7d,0xaf,0xe8,0x47,0x16,0x94,0x25,0x58,0x25,0x58,0x2b, |
887 | | 0xe0,0x71,0xef,0x21,0xd9,0xb7,0x3e,0x1b,0x05,0x76,0x28,0xe5,0x88,0xd2,0xfe,0x16, |
888 | | 0x23,0x28,0xdd,0x22,0x57,0xb0,0x49,0x20,0xe3,0x4a,0x6f,0x11,0x54,0x58,0xf8,0xd0, |
889 | | 0x76,0x81,0x69,0x55,0xca,0xae,0x39,0x45,0x68,0x87,0x7d,0x3b,0xc9,0xee,0xb9,0x97, |
890 | | 0xdb,0xf3,0xcb,0x76,0x5d,0xfd,0x53,0x56,0xa6,0xbb,0x04,0xd6,0x54,0x26,0x58,0x45, |
891 | | 0x1b,0x05,0x36,0x54,0x21,0xd8,0x27,0xa8,0x16,0xec,0xb2,0xd8,0x61,0x51,0x27,0x68, |
892 | | 0x14,0xbc,0x2e,0x38,0x28,0x38,0x2c,0x38,0x2a,0x68,0x17,0x9c,0x10,0xec,0xb3,0x38, |
893 | | 0x25,0x78,0x5b,0x50,0x6d,0xf1,0x9e,0xe0,0x43,0xc1,0x11,0x8b,0x73,0x82,0xcd,0x96, |
894 | | 0xa7,0x2d,0x3e,0x12,0xbc,0x63,0xb1,0xd5,0x52,0x4b,0xbd,0x82,0x4b,0x82,0xf3,0x16, |
895 | | 0x3a,0xde,0xa7,0x38,0x03,0x5f,0x80,0xaf,0xc1,0x77,0xa0,0x1f,0x58,0x0e,0x36,0x1a, |
896 | | 0x07,0x81,0x21,0xc0,0x1e,0x88,0x81,0x13,0x18,0x06,0xdc,0x80,0x07,0xf0,0x02,0xde, |
897 | | 0xc0,0x1f,0x68,0x40,0x28,0x88,0x00,0x31,0x20,0x0e,0xdc,0x01,0xee,0x01,0xa3,0xc1, |
898 | | 0x83,0xe0,0x11,0xf0,0x04,0x18,0x0f,0x26,0x82,0x29,0x60,0x3a,0x98,0x0d,0xe6,0x81, |
899 | | 0x05,0xe0,0x65,0xf0,0x1a,0x48,0x04,0xa9,0x60,0x29,0xc8,0x04,0xab,0xc0,0x3a,0x90, |
900 | | 0x0d,0xf2,0xc1,0x66,0xb0,0x0d,0xec,0x04,0xbb,0x41,0x05,0xd8,0x0f,0x6a,0x41,0x23, |
901 | | 0x78,0x1d,0x1c,0x02,0x47,0xc0,0x31,0x70,0x02,0x9c,0x06,0xef,0x82,0x0f,0xc1,0x79, |
902 | | 0xd0,0x0d,0x2e,0x82,0x4f,0xc1,0x17,0xe0,0x6b,0xf0,0x1d,0xe8,0x07,0x96,0x43,0xd0, |
903 | | 0x7f,0x30,0x04,0xd8,0x03,0x31,0x70,0x1a,0x72,0xc3,0xfb,0xc3,0x86,0xb0,0xaa,0xf0, |
904 | | 0x05,0xf6,0x8d,0x04,0x0a,0xa0,0x06,0x7e,0x20,0x08,0x84,0x80,0x70,0x10,0x0d,0x62, |
905 | | 0xc1,0xed,0xe0,0x6e,0x70,0x1f,0x78,0x00,0x3c,0x0c,0x1e,0x07,0x4f,0x82,0x09,0xe0, |
906 | | 0x19,0x30,0x0d,0xcc,0x02,0xcf,0x81,0x17,0xc0,0x4b,0xe0,0x55,0xb0,0x18,0xa4,0x80, |
907 | | 0x25,0x60,0x39,0x58,0x09,0xd6,0x82,0x8d,0x20,0x0f,0x14,0x82,0xad,0x60,0x07,0x28, |
908 | | 0x05,0xe5,0x60,0x1f,0xa8,0x01,0x0d,0xe0,0x9f,0xe0,0x20,0x68,0x03,0x6f,0x82,0x0e, |
909 | | 0x70,0x0a,0xbc,0x03,0x3e,0x18,0xf2,0xf3,0x91,0x75,0x6e,0x48,0xd7,0x90,0xbe,0x21, |
910 | | 0x9f,0x0c,0xf9,0x7c,0xc8,0x57,0x43,0xbe,0x1d,0xf2,0xc3,0x90,0x9f,0xde,0x77,0x2c, |
911 | | 0x6c,0xac,0x6d,0x06,0xdb,0xd8,0xd9,0x88,0x6c,0x1c,0x6d,0x6e,0x75,0xff,0x71,0xb1, |
912 | | 0x19,0x61,0x33,0xd2,0x46,0x61,0xa3,0xb6,0xf1,0xb3,0x09,0xb2,0x09,0xb1,0xf9,0xe9, |
913 | | 0xf1,0x70,0x9b,0x68,0x9b,0x58,0x9b,0xdb,0x6d,0xee,0xb6,0xb9,0xcf,0xe6,0x01,0x9b, |
914 | | 0x87,0x6d,0x7e,0xda,0xfe,0xe3,0x36,0x4f,0xda,0x4c,0xb0,0x79,0xc6,0x66,0x9a,0xcd, |
915 | | 0xac,0x5b,0xb6,0xdf,0x6f,0x7c,0x0e,0xfb,0x5f,0x00,0x2f,0x81,0x57,0x7f,0xd6,0xfe, |
916 | | 0x62,0x9b,0x14,0x9b,0x25,0x36,0xcb,0x6d,0x56,0xda,0xac,0xb5,0xd9,0x68,0x93,0x87, |
917 | | 0xe3,0x43,0x70,0xc5,0x0d,0x05,0x12,0xe0,0x04,0x5c,0x80,0x2b,0x90,0x71,0xef,0x9e, |
918 | | 0x0a,0x6d,0x8a,0x6d,0x4a,0x6d,0x2a,0x6d,0x6a,0x6c,0x9a,0x6c,0x0e,0xda,0xbc,0x61, |
919 | | 0xf3,0xd3,0xed,0x0e,0x9b,0xb7,0x6c,0x3e,0xb0,0xb9,0x60,0xd3,0x67,0x73,0xd9,0xe6, |
920 | | 0x2b,0x9b,0x6b,0x3f,0xdb,0xb6,0xb0,0xe5,0xdb,0xda,0xd9,0x4a,0x6c,0x5d,0x6c,0x65, |
921 | | 0xb6,0x0a,0x5b,0x1f,0xdb,0x9f,0x6e,0xb3,0x36,0x05,0xd9,0xea,0x6c,0xa3,0x6c,0xd9, |
922 | | 0xbe,0xc4,0xda,0xde,0x69,0x3b,0xca,0x76,0x8c,0xed,0x10,0x9e,0xce,0x76,0xac,0xed, |
923 | | 0xc7,0x96,0x63,0x6d,0x1f,0xb5,0x1d,0x67,0x3b,0xc1,0x76,0xaa,0xed,0x4c,0xee,0xf8, |
924 | | 0x73,0xb6,0x0b,0x6d,0x87,0xf2,0x5e,0xb1,0x95,0xf0,0xa6,0xda,0x26,0xd8,0xa6,0xd8, |
925 | | 0x66,0xd8,0x9a,0x7a,0xb5,0xd2,0x76,0xc0,0x17,0x6b,0x6c,0x37,0xd8,0xe6,0xda,0xb2, |
926 | | 0x6f,0xc8,0x36,0xd9,0x6e,0xb3,0xdd,0x65,0x3e,0x5e,0x61,0x3b,0xd0,0xff,0x7d,0xb6, |
927 | | 0x35,0xb6,0x0d,0xb6,0xae,0xbc,0x7f,0xda,0x1e,0xb4,0xb5,0xe2,0xbd,0xc1,0xd5,0x7b, |
928 | | 0xd3,0xb6,0xd3,0xf6,0x6d,0xae,0xfd,0x0f,0x6c,0x2f,0xd8,0xba,0xf0,0x7a,0x6c,0x65, |
929 | | 0xbc,0x4e,0xdb,0x78,0xba,0x64,0xcb,0x7e,0x7f,0x71,0xab,0x60,0x7a,0xee,0x98,0x34, |
930 | | 0x2f,0xdb,0xde,0xf0,0xee,0x15,0xdb,0x7f,0xbd,0xae,0x30,0xfe,0xc2,0xb7,0x23,0x57, |
931 | | 0x6d,0xfb,0x51,0x53,0x60,0x27,0xb4,0xbb,0x3e,0x4e,0x90,0x73,0xb5,0xfb,0x69,0x2b, |
932 | | 0xee,0x76,0x72,0x3b,0x2f,0xbb,0x5f,0xbe,0xef,0xa9,0x7f,0x72,0x2c,0xe4,0xc6,0x83, |
933 | | 0x92,0x6e,0xa8,0xde,0xb4,0x93,0x42,0xed,0x44,0xdc,0x91,0x30,0xbb,0x08,0xbb,0x28, |
934 | | 0xbb,0x18,0x3b,0x83,0x5d,0x9c,0xdd,0x6d,0x76,0x77,0xd8,0xdd,0x63,0x77,0xaf,0xdd, |
935 | | 0x68,0xbb,0xe1,0x38,0x3e,0x9a,0xd8,0xef,0x67,0x6e,0x7d,0x1c,0xe3,0x1d,0xcf,0x83, |
936 | | 0x11,0x14,0x80,0x67,0x82,0xf0,0xfa,0xd3,0x43,0xc6,0x7d,0x1f,0x75,0xeb,0xe7,0xef, |
937 | | 0xfd,0x76,0xff,0xde,0x9d,0x7c,0xac,0xdd,0xa3,0x76,0xd6,0x34,0x0e,0xb5,0x9e,0xb2, |
938 | | 0x9b,0x64,0x97,0xc7,0x7e,0x63,0x61,0xc7,0x3e,0xad,0x4c,0xe1,0x2b,0x3c,0xb5,0x44, |
939 | | 0x50,0x75,0x86,0x1f,0x87,0xd3,0x0c,0xae,0x6d,0xd3,0x37,0x62,0x6c,0x60,0xb7,0x66, |
940 | | 0xdb,0x3d,0x67,0xf7,0x02,0xf6,0xb3,0xdf,0x89,0x4d,0xe0,0x99,0x52,0x47,0x7a,0x8e, |
941 | | 0xfb,0x4e,0x0d,0xb3,0x60,0xee,0x5b,0xb5,0x17,0xed,0x5c,0xd0,0x87,0x45,0x76,0x09, |
942 | | 0x76,0x89,0x76,0x29,0xf0,0x07,0x56,0x17,0x76,0x77,0xe3,0x59,0xa5,0xe2,0xdd,0xcd, |
943 | | 0x5b,0x76,0xdd,0x5e,0x3e,0xf7,0xec,0x63,0x9f,0x92,0x37,0xdb,0xb7,0xc2,0x6e,0x9d, |
944 | | 0x5d,0xae,0x5d,0x91,0xdd,0x0e,0xbb,0x32,0xbb,0x7d,0x76,0x75,0x76,0xff,0xb4,0x6b, |
945 | | 0xb5,0x7b,0xd3,0xae,0xd3,0xee,0x1d,0xbb,0x33,0x76,0x5d,0x76,0x97,0xd0,0xda,0x67, |
946 | | 0x76,0x57,0xec,0xae,0xda,0xf9,0xd0,0x77,0x76,0x3f,0xd8,0x59,0xd8,0x0f,0xb2,0x0f, |
947 | | 0xa0,0xc1,0xf6,0xb6,0xf6,0xce,0xdc,0x77,0x7a,0x2e,0xf4,0x6b,0xc7,0xcd,0x73,0x72, |
948 | | 0xfb,0x1b,0x8a,0x0e,0xf6,0x3f,0x5d,0x3d,0xfc,0x37,0x7e,0x86,0xd9,0x8f,0x44,0x3f, |
949 | | 0x7c,0xec,0x35,0xf6,0xff,0x69,0xe5,0x28,0x7b,0xc3,0x1f,0xd6,0xfc,0xed,0xeb,0xd7, |
950 | | 0x5b,0x5c,0x3d,0xf6,0x77,0xda,0xdf,0x63,0x7f,0x9f,0xfd,0xfd,0xf6,0x63,0xed,0x1f, |
951 | | 0xb1,0x7f,0xdc,0xfe,0x1f,0xf6,0x4f,0xd9,0x4f,0xb4,0x7f,0xc6,0x7e,0x9a,0xfd,0x2c, |
952 | | 0xfb,0xe7,0xec,0x5f,0xb0,0x7f,0xc9,0xfe,0x55,0xfb,0xc5,0xf6,0x29,0xf6,0x4b,0xec, |
953 | | 0x33,0xed,0x57,0xdb,0x6f,0xb0,0xcf,0xb3,0xdf,0x6c,0x5f,0x6c,0xbf,0xcb,0xbe,0xdc, |
954 | | 0x7e,0xbf,0x7d,0x9d,0xfd,0x6f,0xd5,0x6d,0xb6,0x3f,0x60,0x7f,0xd8,0xfe,0xa8,0xfd, |
955 | | 0x71,0xfb,0x93,0xf6,0x6f,0xdb,0xbf,0x6f,0x7f,0xd6,0xfe,0x23,0xfb,0x5e,0xfb,0x8f, |
956 | | 0xed,0x3f,0xb3,0xff,0xd2,0xfe,0x1b,0xfb,0xef,0xed,0x49,0x68,0x25,0x14,0x08,0x6d, |
957 | | 0x85,0x43,0x85,0x0e,0x42,0xa9,0xd0,0x55,0xe8,0x2e,0xf4,0x14,0xfe,0x9e,0x6f,0x9a, |
958 | | 0x7f,0x4f,0x9d,0x50,0xbb,0x3f,0x7e,0x16,0x55,0x42,0xe3,0xff,0xa9,0x4f,0x88,0x30, |
959 | | 0x5c,0x18,0xf5,0x27,0xf6,0xc9,0xf0,0x27,0xb5,0x75,0x87,0xf0,0x1e,0xe1,0x68,0xe1, |
960 | | 0x83,0xc2,0x47,0x84,0x4f,0x08,0xc7,0x0b,0x27,0x0a,0xa7,0x08,0xa7,0x0b,0x67,0x0b, |
961 | | 0xe7,0x09,0x17,0x08,0x5f,0x16,0xbe,0x26,0x4c,0x14,0xa6,0x0a,0x97,0x0a,0x33,0x85, |
962 | | 0xab,0x84,0xeb,0x84,0xd9,0xc2,0x7c,0xe1,0x66,0xe1,0x36,0xe1,0x4e,0xe1,0x6e,0x61, |
963 | | 0x85,0x70,0xbf,0xb0,0x56,0xd8,0x28,0x7c,0x5d,0x78,0x48,0x78,0x44,0x78,0x4c,0x78, |
964 | | 0x42,0x78,0x5a,0xf8,0xae,0xf0,0x43,0xe1,0x79,0x61,0xb7,0xf0,0xa2,0xf0,0x53,0xe1, |
965 | | 0x17,0xc2,0xaf,0x85,0xdf,0x09,0xfb,0x85,0x96,0x43,0xff,0x6a,0xbf,0x0e,0x82,0xc2, |
966 | | 0x90,0xa1,0x76,0x43,0x45,0x9c,0x92,0x03,0x62,0x29,0x70,0x05,0xab,0xb0,0x06,0xc8, |
967 | | 0x12,0xec,0xc2,0x7c,0xde,0x9d,0x3b,0xe6,0xf9,0x23,0x5b,0x24,0x18,0xaf,0xaa,0xa1, |
968 | | 0x3e,0x43,0xfd,0xb1,0x57,0x03,0x42,0x41,0x04,0x88,0x01,0x71,0xe0,0x0e,0x70,0x0f, |
969 | | 0x18,0x0d,0x1e,0x04,0x8f,0x80,0x27,0xc0,0x78,0x30,0x11,0x4c,0x01,0xd3,0xc1,0x6c, |
970 | | 0x30,0x0f,0x2c,0x00,0x2f,0x83,0xd7,0x40,0x22,0x48,0x05,0x4b,0x41,0x26,0x6b,0x09, |
971 | | 0x58,0x07,0xb2,0x41,0x3e,0xd8,0x0c,0xb6,0x81,0x9d,0x60,0x37,0xa8,0x00,0xfb,0x41, |
972 | | 0x2d,0x68,0x04,0xaf,0x83,0x43,0xe0,0x08,0x38,0x06,0x4e,0x80,0xd3,0xe0,0x5d,0xf0, |
973 | | 0x21,0x38,0x0f,0xba,0xc1,0x45,0xf0,0x29,0xf8,0xe2,0x67,0x5e,0xfe,0x1a,0x7b,0xbe, |
974 | | 0xbb,0xbe,0xb7,0x7f,0xa8,0xf1,0x3f,0xf6,0xbe,0xf3,0xc7,0x77,0x29,0x4b,0x91,0xf1, |
975 | | 0x77,0xbd,0xfd,0xfb,0xad,0x6f,0xb8,0x07,0x89,0xfe,0x3b,0xae,0xfe,0x21,0xa2,0x5f, |
976 | | 0xf2,0x80,0xbd,0x48,0x2c,0x72,0x12,0x0d,0x13,0xb9,0x89,0x3c,0x44,0x5e,0x22,0x6f, |
977 | | 0x91,0xbf,0x48,0x23,0x0a,0x15,0x45,0x88,0x62,0x44,0x71,0xa2,0x3b,0x44,0xf7,0x88, |
978 | | 0x46,0x8b,0x1e,0x14,0x3d,0x22,0x7a,0x42,0x34,0x5e,0x34,0x51,0x34,0x45,0x34,0x5d, |
979 | | 0x34,0x5b,0x34,0x4f,0xb4,0x40,0xf4,0xb2,0xe8,0x35,0x51,0xa2,0x28,0x55,0xb4,0x54, |
980 | | 0x94,0x29,0x5a,0x25,0x5a,0x27,0xca,0x16,0xe5,0x8b,0x36,0x8b,0xb6,0x89,0x76,0x8a, |
981 | | 0x76,0x8b,0x2a,0x44,0xfb,0x45,0xb5,0xa2,0x46,0xd1,0xeb,0xa2,0x43,0xa2,0x23,0xa2, |
982 | | 0x63,0xa2,0x13,0xa2,0xd3,0xa2,0x77,0x45,0x1f,0x8a,0xce,0x8b,0xba,0x45,0x17,0x45, |
983 | | 0x9f,0x8a,0xbe,0x10,0x7d,0x2d,0xfa,0x4e,0xd4,0x2f,0xb2,0x14,0x0f,0x12,0x0f,0x11, |
984 | | 0xdb,0x8b,0xc5,0x62,0x27,0xf1,0x30,0xb1,0x9b,0xd8,0x43,0xec,0x25,0xf6,0x16,0xfb, |
985 | | 0x8b,0x35,0xe2,0x50,0x71,0x84,0x38,0x46,0x1c,0x27,0xbe,0x43,0x7c,0x8f,0x78,0xb4, |
986 | | 0xf8,0x41,0xf1,0x23,0xe2,0x27,0xc4,0xe3,0xc5,0x13,0xc5,0x53,0xc4,0xd3,0xc5,0xb3, |
987 | | 0xc5,0xf3,0xc4,0x0b,0xc4,0x2f,0x8b,0x5f,0x13,0x27,0x8a,0x53,0xc5,0x4b,0xc5,0x99, |
988 | | 0xe2,0x55,0xe2,0x75,0xe2,0x6c,0x71,0xbe,0x78,0xb3,0x78,0x9b,0x78,0xa7,0x78,0xb7, |
989 | | 0xb8,0x42,0xbc,0x5f,0x5c,0x2b,0x6e,0x14,0xbf,0x2e,0x3e,0x24,0x3e,0x22,0x3e,0x26, |
990 | | 0x3e,0x21,0x3e,0x2d,0x7e,0x57,0xfc,0xa1,0xf8,0xbc,0xb8,0x5b,0x7c,0x51,0xfc,0xa9, |
991 | | 0xf8,0x0b,0xf1,0xd7,0xe2,0xef,0xc4,0xfd,0x62,0x4b,0xc9,0x20,0xc9,0x10,0x89,0xbd, |
992 | | 0x44,0x2c,0x71,0x92,0x0c,0x93,0xb8,0x49,0x3c,0x24,0x5e,0x12,0x6f,0x89,0xbf,0x44, |
993 | | 0x23,0x09,0x95,0x44,0x48,0x62,0x24,0x71,0x92,0x3b,0x24,0xf7,0x48,0x46,0x4b,0x1e, |
994 | | 0x94,0x3c,0x22,0x79,0x42,0x32,0x5e,0x32,0x51,0x32,0x45,0x32,0x5d,0x32,0x5b,0x32, |
995 | | 0x4f,0xb2,0x40,0xf2,0xb2,0xe4,0x35,0x49,0xa2,0x24,0x55,0xb2,0x54,0x92,0x29,0x59, |
996 | | 0x25,0x59,0x27,0xc9,0x96,0xe4,0x4b,0x36,0x4b,0xb6,0x49,0x76,0x4a,0x76,0x4b,0x2a, |
997 | | 0x24,0xfb,0x25,0xb5,0x92,0x46,0xc9,0xeb,0x92,0x43,0x92,0x23,0x92,0x63,0x92,0x13, |
998 | | 0x92,0xd3,0x92,0x77,0x25,0x1f,0x4a,0xce,0x4b,0xba,0x25,0x17,0x25,0x9f,0x4a,0xbe, |
999 | | 0x90,0x7c,0x2d,0xf9,0x4e,0xd2,0x2f,0xb1,0x74,0x18,0xe4,0x30,0xc4,0xc1,0xde,0x41, |
1000 | | 0xec,0xe0,0xe4,0x30,0xcc,0xc1,0xcd,0xc1,0xc3,0xc1,0xcb,0xc1,0xdb,0xc1,0xdf,0x41, |
1001 | | 0xe3,0x10,0xea,0x10,0xe1,0x10,0xe3,0x10,0xe7,0x70,0x87,0xc3,0x3d,0x0e,0xa3,0x1d, |
1002 | | 0x1e,0x74,0x78,0xc4,0xe1,0x09,0x87,0xf1,0x0e,0x13,0x1d,0xfa,0x8d,0x7f,0x7e,0x60, |
1003 | | 0x57,0x08,0x53,0x1c,0xfe,0x33,0xa3,0xf0,0x59,0xe8,0x4c,0x17,0xcd,0x74,0x98,0xeb, |
1004 | | 0xf0,0x47,0xae,0x6e,0xf6,0xf3,0xbc,0xc3,0x4b,0x5c,0x1b,0xaf,0x39,0xfc,0x77,0x3f, |
1005 | | 0x95,0x53,0x1c,0xfe,0xea,0xfb,0x62,0xbf,0x71,0x99,0xc3,0x0a,0x87,0x35,0x0e,0x1b, |
1006 | | 0x1c,0x72,0x1d,0x36,0x39,0x6c,0x71,0xd8,0xee,0xb0,0xcb,0x61,0x8f,0xc3,0x5e,0x87, |
1007 | | 0x6a,0x87,0x7a,0x87,0x66,0x87,0x03,0x0e,0x87,0x1d,0x8e,0x3a,0x1c,0x77,0x38,0xe9, |
1008 | | 0xf0,0xb6,0xc3,0xfb,0x0e,0x67,0x1d,0x3e,0x72,0xe8,0x75,0xf8,0xd8,0xe1,0x33,0x87, |
1009 | | 0x2f,0x1d,0xbe,0x71,0xf8,0xde,0x81,0x1c,0xad,0x1c,0x05,0x8e,0xb6,0x8e,0x43,0x1d, |
1010 | | 0x1d,0x1c,0xa5,0x8e,0xae,0x8e,0xee,0x8e,0x9e,0x8e,0x2a,0x47,0x5f,0xc7,0x40,0xc7, |
1011 | | 0x60,0xc7,0x30,0xc7,0x28,0x47,0x83,0xe3,0x6d,0x8e,0x77,0x39,0xde,0xeb,0x78,0xbf, |
1012 | | 0xe3,0x43,0x8e,0x44,0x8f,0x39,0xfe,0xc3,0xf1,0x69,0xc7,0xc9,0x8e,0xcf,0x3a,0xce, |
1013 | | 0x74,0x9c,0xeb,0xf8,0xbc,0xe3,0x8b,0x8e,0x8b,0x1c,0x19,0xc7,0x64,0xc7,0x74,0xc7, |
1014 | | 0x65,0x8e,0x2b,0x1c,0xd7,0x38,0x6e,0x70,0xcc,0x75,0xdc,0xe4,0xb8,0xc5,0x71,0xbb, |
1015 | | 0xe3,0x2e,0xc7,0x3d,0x8e,0x7b,0x1d,0xab,0x1d,0xeb,0x1d,0x9b,0x1d,0x0f,0x38,0x1e, |
1016 | | 0x76,0x3c,0xea,0x78,0xdc,0xf1,0xa4,0xe3,0xdb,0x8e,0xef,0x3b,0x9e,0x75,0xfc,0xc8, |
1017 | | 0xb1,0xd7,0xf1,0x63,0xc7,0xcf,0x1c,0xbf,0x74,0xfc,0xc6,0xf1,0x7b,0x47,0x93,0x57, |
1018 | | 0xec,0x71,0x67,0x22,0x27,0x2b,0x27,0x81,0x93,0xad,0xd3,0x50,0x27,0x07,0x27,0x37, |
1019 | | 0x91,0xd4,0xc9,0xd5,0xc9,0xdd,0xc9,0xd3,0xc9,0xff,0x0f,0xdf,0x7f,0x55,0x4e,0xfe, |
1020 | | 0x4e,0xc1,0x4e,0x11,0x4e,0x06,0xa7,0x3b,0x9c,0xee,0x75,0x7a,0xd0,0xe9,0x31,0xa7, |
1021 | | 0xf1,0x4e,0x93,0x9d,0xa6,0x3b,0xcd,0x75,0x5a,0xe0,0xb4,0xc8,0x29,0xd1,0x29,0xdd, |
1022 | | 0x29,0xd3,0x69,0x8d,0x53,0xb6,0xd3,0x26,0xa7,0x6d,0x4e,0xbb,0x9c,0x2a,0x9c,0xaa, |
1023 | | 0x9d,0x1a,0x9d,0x0e,0x38,0x1d,0x71,0x3a,0xee,0x74,0xda,0xe9,0x8c,0x53,0xbf,0xb1, |
1024 | | 0xd7,0xe9,0x53,0xa7,0x2f,0x9d,0xbe,0x73,0x22,0xe7,0x41,0xce,0xb6,0xce,0x62,0x67, |
1025 | | 0xa9,0xb3,0x9b,0xb3,0xa7,0xb3,0xb7,0x73,0xa0,0x73,0xa8,0x73,0x94,0x73,0x9c,0xf3, |
1026 | | 0x5d,0xce,0xa3,0x9d,0x1f,0x72,0x7e,0xc2,0xf9,0x69,0xe7,0x29,0xce,0x33,0x9d,0xe7, |
1027 | | 0x39,0xbf,0xe8,0xfc,0x9a,0x73,0xb2,0xf3,0x52,0xe7,0x15,0xce,0xeb,0x9c,0x73,0x9d, |
1028 | | 0x37,0x3b,0x6f,0x77,0xde,0xed,0xbc,0xd7,0xb9,0xd6,0xb9,0xd9,0xf9,0x80,0xb3,0x93, |
1029 | | 0xf8,0xb0,0xf3,0x4f,0xed,0x3b,0xea,0x7c,0xdc,0xb9,0xd3,0xf9,0xb4,0xf3,0x3b,0xce, |
1030 | | 0xef,0x3b,0x9f,0x71,0x3e,0xef,0xdc,0xe5,0xdc,0xeb,0x7c,0xc9,0xf9,0x53,0xe7,0xcf, |
1031 | | 0x9d,0xbf,0x74,0xbe,0xea,0xfc,0x9d,0xf3,0x32,0x9c,0xd9,0x2d,0x38,0xa7,0xec,0x59, |
1032 | | 0x7c,0x9f,0x3b,0x7f,0x37,0xce,0xde,0x0f,0xce,0x16,0x52,0x6b,0xe9,0x60,0xa9,0x9d, |
1033 | | 0x54,0x24,0x75,0x94,0xba,0x48,0x47,0x48,0x47,0x4a,0x15,0x52,0xb5,0xd4,0x4f,0x1a, |
1034 | | 0x24,0x0d,0x91,0x46,0x49,0xe3,0xa5,0x37,0x7c,0x7b,0xa7,0x74,0x94,0x74,0x8c,0x34, |
1035 | | 0x42,0x34,0x56,0x3a,0x5d,0xa4,0xc1,0xbd,0x76,0x3c,0xee,0xc2,0xdb,0x24,0x4b,0x45, |
1036 | | 0xde,0xe2,0x47,0xa5,0xe3,0xa4,0x4f,0x49,0x27,0x49,0xa7,0x4a,0x67,0x48,0xe7,0x48, |
1037 | | 0xe7,0x4b,0x17,0x4a,0x5f,0x91,0x6e,0x16,0x25,0x48,0x93,0xa4,0x69,0xd2,0x0c,0x69, |
1038 | | 0x96,0x74,0xb5,0x74,0xbd,0x34,0x47,0x6a,0x3a,0x37,0x05,0xd2,0x22,0x69,0xb1,0xb4, |
1039 | | 0x44,0x5a,0x26,0xad,0x94,0x56,0x49,0xeb,0xa4,0x4d,0xd2,0x16,0x69,0xab,0xf4,0x88, |
1040 | | 0xf4,0x4d,0xe9,0x71,0x69,0xa7,0xf4,0xb4,0xf4,0x1d,0xe9,0xfb,0xd2,0x33,0xd2,0xf3, |
1041 | | 0xd2,0x2e,0x69,0xaf,0xf4,0x92,0xf4,0x53,0xe9,0xe7,0xd2,0x2f,0xa5,0xdf,0x4a,0xfb, |
1042 | | 0xa5,0x3c,0x17,0x81,0x8b,0x9d,0x8b,0xd8,0xc5,0xd9,0xc5,0xd5,0x65,0xa4,0x8b,0xd2, |
1043 | | 0xc5,0xcf,0x45,0xeb,0x12,0xea,0x12,0xe1,0x12,0xed,0x12,0xeb,0x72,0xbb,0xcb,0xdd, |
1044 | | 0x2e,0xf7,0xb9,0x3c,0xe0,0xf2,0xb0,0xcb,0xe3,0x2e,0x4f,0xba,0x4c,0x70,0x79,0xc6, |
1045 | | 0x65,0x9a,0xcb,0x2c,0x97,0xe7,0x5c,0x5e,0x70,0x79,0xc9,0xe5,0x55,0x97,0xc5,0x2e, |
1046 | | 0x29,0x2e,0x4b,0x5c,0x96,0xbb,0xac,0x74,0x59,0xeb,0xb2,0xd1,0x25,0xcf,0xa5,0xd0, |
1047 | | 0x65,0xab,0xcb,0x0e,0x97,0x52,0x97,0x72,0x97,0x7d,0x2e,0x35,0x2e,0x0d,0x2e,0xff, |
1048 | | 0x74,0x39,0xe8,0xd2,0xe6,0xf2,0xa6,0x4b,0x87,0xcb,0x29,0x97,0x77,0x5c,0x3e,0x70, |
1049 | | 0x39,0xe7,0xd2,0xe5,0xd2,0xe7,0xf2,0x89,0xcb,0xe7,0x2e,0x5f,0xb9,0x7c,0xeb,0xf2, |
1050 | | 0x83,0x8b,0xd5,0x30,0xd1,0x30,0xb7,0x61,0x3e,0xc3,0x42,0x86,0xc5,0x0d,0xbb,0x77, |
1051 | | 0xd8,0x23,0xc3,0xa6,0x0c,0x9b,0x3f,0xec,0xd5,0x61,0x69,0xc3,0x56,0x0e,0xcb,0x1f, |
1052 | | 0x56,0x32,0x6c,0xdf,0xb0,0xa6,0x61,0x87,0x86,0x1d,0x1f,0xf6,0xc1,0xb0,0x8b,0xc3, |
1053 | | 0x3e,0x1f,0x66,0x31,0xdc,0x61,0xb8,0xe7,0x70,0xff,0xe1,0x31,0xc3,0x47,0x0f,0x1f, |
1054 | | 0x37,0xfc,0x99,0xe1,0x73,0x86,0xbf,0x34,0x3c,0x75,0xf8,0xba,0xe1,0x45,0xc3,0x4b, |
1055 | | 0x87,0x57,0x0d,0xff,0xe7,0xf0,0xc3,0xc3,0xdb,0x87,0x9f,0x1e,0xfe,0xc1,0xf0,0x9e, |
1056 | | 0xe1,0x9f,0x0f,0xb7,0x70,0xb5,0x71,0x95,0xba,0xaa,0x5c,0x35,0xae,0xe1,0xae,0x06, |
1057 | | 0xd7,0xfb,0x5d,0x9f,0x74,0x9d,0xe5,0xba,0xd0,0x35,0xcd,0x35,0xd3,0x75,0x83,0xeb, |
1058 | | 0x66,0xd7,0x5d,0xae,0xfb,0x5d,0x9b,0x5d,0xdf,0x74,0x7d,0xcb,0xf5,0x43,0xd7,0x5e, |
1059 | | 0xd7,0x2f,0x5c,0xbf,0x77,0x1d,0x3c,0x42,0x32,0x62,0xc4,0x08,0xe5,0x08,0xdd,0x88, |
1060 | | 0xdb,0x46,0x8c,0x1a,0x31,0x6e,0xc4,0xc4,0x11,0x73,0x46,0x2c,0x1a,0x91,0x3a,0x62, |
1061 | | 0xc5,0x88,0xec,0x11,0xc5,0x23,0x76,0x8f,0xa8,0x1e,0x71,0x70,0xc4,0xd1,0x11,0xef, |
1062 | | 0x8f,0xe8,0x1e,0x71,0x69,0xc4,0x67,0x23,0xbe,0x1a,0xf1,0xdd,0x08,0xe3,0x08,0x2b, |
1063 | | 0xb7,0xc1,0x6e,0xf6,0x6e,0x12,0x37,0xa9,0x9b,0x9b,0x9b,0xa7,0x9b,0xb7,0x5b,0xa0, |
1064 | | 0x5b,0xa8,0x5b,0x94,0x5b,0x9c,0xdb,0x5d,0x6e,0xa3,0xdd,0x1e,0x72,0x7b,0xc2,0xed, |
1065 | | 0x69,0xb7,0x29,0x6e,0x33,0xdd,0xe6,0xb9,0x2d,0x70,0x7b,0xc9,0x6d,0x91,0x1b,0xe3, |
1066 | | 0x96,0xe4,0x96,0xea,0xb6,0xc4,0x6d,0xb9,0xdb,0x4a,0xb7,0x35,0x6e,0x39,0x6e,0x9b, |
1067 | | 0xdd,0x76,0xb8,0xed,0x71,0x6b,0x70,0x6b,0x76,0x6b,0x71,0x6b,0x75,0x3b,0xe2,0xf6, |
1068 | | 0xa6,0xdb,0x71,0xb7,0x4e,0xb7,0xd3,0x6e,0xef,0xba,0x9d,0x71,0x3b,0xef,0xd6,0xe5, |
1069 | | 0xd6,0xe7,0xf6,0x89,0xdb,0x67,0x6e,0x57,0xdc,0xbe,0x76,0xfb,0xce,0xad,0xdf,0xcd, |
1070 | | 0x52,0x36,0x48,0x36,0x44,0x66,0x27,0x1b,0x2a,0x93,0xc8,0x9c,0x64,0x2e,0xb2,0x11, |
1071 | | 0x32,0x77,0x99,0x5c,0xe6,0x25,0xf3,0x96,0xf9,0xcb,0x82,0x64,0x21,0xb2,0x70,0x59, |
1072 | | 0xb4,0xcc,0x20,0xbb,0x4d,0x76,0x8f,0xac,0xc1,0xed,0x01,0xd9,0xc3,0xb2,0xc7,0x65, |
1073 | | 0x4f,0xca,0x26,0xc8,0xa6,0xc9,0xe6,0xc9,0x5e,0x90,0xbd,0x28,0x5b,0x24,0x4b,0x90, |
1074 | | 0x25,0xca,0x52,0x64,0x4b,0x64,0xcb,0x40,0x96,0x6c,0x95,0x6c,0xad,0x6c,0xa3,0x2c, |
1075 | | 0x17,0x14,0xc8,0x8a,0x64,0xfd,0xc6,0x62,0xd9,0x4e,0x59,0xa9,0x6c,0x0f,0x72,0x55, |
1076 | | 0xb2,0x5a,0x59,0x83,0xac,0x59,0xd6,0x22,0x3b,0x84,0xf6,0xdb,0x64,0x47,0x65,0xed, |
1077 | | 0xb2,0x13,0xb2,0xd3,0xb2,0xe3,0x6e,0xef,0xc8,0x3e,0x90,0x9d,0x43,0x89,0x8f,0x64, |
1078 | | 0xbd,0xb2,0x4b,0xb2,0x4f,0x65,0x9f,0xcb,0xbe,0x94,0x7d,0x27,0x23,0x77,0x6b,0xf7, |
1079 | | 0x21,0xee,0x42,0x77,0x07,0x77,0x17,0x77,0x37,0x77,0xb9,0xbb,0xca,0xdd,0xcf,0x5d, |
1080 | | 0xeb,0x1e,0xee,0xae,0x77,0xbf,0xdd,0x7d,0x94,0xfb,0x03,0xee,0x8f,0xba,0x3f,0xe9, |
1081 | | 0x3e,0xc9,0x7d,0x9a,0xfb,0x1c,0xf7,0x17,0xdc,0x5f,0x71,0x5f,0xec,0x9e,0xe6,0xbe, |
1082 | | 0xdc,0x7d,0xb5,0xfb,0x46,0xf7,0x02,0xf7,0xad,0xee,0x25,0xee,0xe5,0xee,0xfb,0xdc, |
1083 | | 0x8d,0xc6,0x1a,0xd0,0x00,0xfe,0x09,0x0e,0x82,0x4e,0xbe,0xd1,0xd8,0x86,0xf4,0x4d, |
1084 | | 0xd0,0x01,0x4e,0x81,0x77,0xc0,0x07,0xe0,0x1c,0xe8,0x02,0x7d,0xe0,0x13,0xf0,0x39, |
1085 | | 0xf8,0x0a,0x7c,0x0b,0x7e,0x00,0x16,0x23,0x8d,0x46,0x6b,0x30,0x78,0xe4,0x6f,0xbb, |
1086 | | 0xff,0xd8,0xa1,0x9c,0x08,0x38,0x02,0x17,0x30,0x02,0x8c,0x04,0x0a,0xa0,0x06,0x7e, |
1087 | | 0x20,0x08,0x84,0x80,0x70,0x10,0x0d,0x62,0x81,0x9b,0x95,0xa7,0xd5,0xff,0x96,0xa7, |
1088 | | 0xd8,0xed,0xb0,0xe7,0x6e,0x70,0x1f,0x78,0x00,0x3c,0x0c,0x1e,0x07,0x4f,0x9a,0x7d, |
1089 | | 0x30,0x01,0xe9,0x33,0x60,0x1a,0x98,0x05,0x9e,0x03,0x2f,0x80,0x97,0xc0,0xab,0x60, |
1090 | | 0x31,0x48,0x01,0x4b,0xc0,0x72,0xb0,0x12,0xac,0x05,0x1b,0x41,0x1e,0x28,0x04,0x5b, |
1091 | | 0xc1,0x0e,0x50,0x0a,0xca,0xc1,0x3e,0x50,0x03,0x1a,0xc0,0x3f,0xc1,0x41,0xd0,0x06, |
1092 | | 0xde,0x04,0x1d,0xe0,0x14,0x78,0xc7,0xcc,0x8f,0x3f,0x1f,0x60,0xcf,0x39,0xd0,0x35, |
1093 | | 0xb2,0x0f,0xf1,0x27,0xe0,0x73,0xf0,0x15,0xf8,0xf6,0x7a,0xd9,0x1f,0x90,0xab,0xe6, |
1094 | | 0xbe,0x1b,0xb3,0xf0,0xc0,0xf9,0xf4,0x30,0x7f,0xa7,0x8d,0xd4,0x0e,0x88,0x80,0x23, |
1095 | | 0x70,0x01,0x23,0xc0,0x48,0xa0,0x00,0x6a,0xe0,0x07,0xaa,0x2c,0x37,0x0a,0xf6,0x09, |
1096 | | 0x82,0x3c,0xea,0xd0,0x42,0xb0,0x87,0xce,0xe3,0x75,0x41,0x84,0x47,0x0c,0xf6,0xc7, |
1097 | | 0x81,0x3b,0xc0,0x3d,0x60,0x34,0x78,0x10,0x3c,0x02,0x9e,0x00,0xe3,0x3d,0x3e,0x14, |
1098 | | 0x4c,0xf4,0x98,0x82,0xdc,0x74,0x30,0xdb,0xe3,0x39,0xc4,0x2f,0x80,0x97,0xc0,0xab, |
1099 | | 0x60,0x31,0x48,0x01,0x4b,0xc0,0x72,0xb0,0xd2,0xe3,0xb7,0xce,0xf0,0x14,0x64,0x4d, |
1100 | | 0x36,0x34,0x92,0xd6,0x70,0xbd,0xf8,0x8a,0x22,0x2c,0xfe,0x8c,0x73,0x7e,0xdf,0xc8, |
1101 | | 0x0d,0x1e,0x43,0x86,0xe6,0x7a,0xfc,0xfc,0xc8,0x26,0x8f,0x9b,0xd7,0x61,0x45,0x1e, |
1102 | | 0xc5,0x1e,0x25,0x1e,0x65,0x1e,0x95,0x1e,0x55,0x1e,0x75,0x1e,0x4d,0x1e,0x2d,0x1e, |
1103 | | 0xad,0x1e,0x6f,0x78,0xb4,0x7b,0x74,0x7a,0xbc,0xe5,0xf1,0x9e,0xc7,0x19,0x8f,0x0b, |
1104 | | 0x1e,0x3d,0x1e,0x97,0x3c,0x2e,0x7b,0x5c,0xf1,0xb8,0xea,0x71,0xcd,0xc3,0xe8,0xc1, |
1105 | | 0x93,0xf3,0xe5,0x36,0x72,0xa1,0x5c,0x22,0x77,0x96,0x0f,0x97,0xcb,0xe4,0x72,0xb9, |
1106 | | 0x52,0xee,0x23,0x0f,0x90,0x6b,0xe5,0x3a,0x79,0xa4,0x5c,0x2f,0x8f,0x97,0xdf,0x29, |
1107 | | 0x1f,0x25,0x1f,0x23,0x1f,0x2b,0x7f,0x54,0x3e,0x4e,0xfe,0x94,0x7c,0x92,0x7c,0xaa, |
1108 | | 0x7c,0x86,0x7c,0x8e,0x7c,0xbe,0x7c,0xa1,0xfc,0x15,0x79,0x82,0x3c,0x49,0x9e,0x26, |
1109 | | 0xcf,0x90,0x67,0xc9,0x57,0xcb,0xd7,0xcb,0x73,0xe4,0x05,0xf2,0x22,0x79,0xb1,0xbc, |
1110 | | 0x44,0x5e,0x26,0xaf,0x94,0x57,0xc9,0xeb,0xe4,0x4d,0xf2,0x16,0x79,0xab,0xfc,0x0d, |
1111 | | 0x79,0xbb,0xbc,0x53,0xfe,0x96,0xfc,0x3d,0xf9,0x19,0xf9,0x05,0x79,0x8f,0x3c,0x55, |
1112 | | 0x72,0x49,0x7e,0x59,0x7e,0x45,0x7e,0x55,0x3e,0x1e,0xf3,0xec,0x6b,0xf2,0x6d,0x12, |
1113 | | 0xa3,0x9c,0xe7,0xc9,0xf7,0xb4,0xf1,0x14,0x7a,0x4a,0x3c,0x9d,0x3d,0x87,0x7b,0xca, |
1114 | | 0x3c,0xe5,0x9e,0x4a,0x4f,0x1f,0xcf,0x00,0x4f,0xad,0xa7,0xce,0x33,0xd2,0x53,0xef, |
1115 | | 0x19,0xef,0x79,0xa7,0xe7,0x28,0xcf,0x31,0x9e,0x63,0x3d,0x1f,0xf5,0x1c,0xe7,0xf9, |
1116 | | 0x94,0xe7,0x24,0xcf,0xa9,0x9e,0x33,0x3c,0xe7,0x78,0xce,0xf7,0x5c,0xe8,0xf9,0x8a, |
1117 | | 0x67,0x82,0x67,0x92,0x67,0x9a,0x67,0x86,0x67,0x96,0xe7,0x6a,0xcf,0xf5,0x9e,0x39, |
1118 | | 0x9e,0x05,0x9e,0xfd,0xe2,0x22,0xcf,0x62,0xcf,0x12,0xcf,0x32,0xcf,0x4a,0xcf,0x2a, |
1119 | | 0xcf,0x3a,0xcf,0x26,0xcf,0x16,0xcf,0x56,0xcf,0x37,0x3c,0x3d,0x1c,0xda,0x3d,0x3b, |
1120 | | 0x3d,0xdf,0xf2,0x7c,0xcf,0xf3,0x8c,0xe7,0x05,0xcf,0x1e,0xcf,0x4b,0x9e,0x97,0x3d, |
1121 | | 0xaf,0x78,0x5e,0xf5,0xbc,0xe6,0x69,0xf4,0xe4,0x29,0xf8,0x0a,0x1b,0x85,0x50,0x21, |
1122 | | 0x51,0x38,0x2b,0x86,0x2b,0x64,0x0a,0xb9,0x42,0xa9,0xf0,0x51,0x04,0x28,0xb4,0x0a, |
1123 | | 0x9d,0x42,0xee,0x19,0xa9,0xd0,0x2b,0xe2,0x15,0x77,0x2a,0x46,0x29,0xc6,0x28,0xc6, |
1124 | | 0x2a,0x1e,0x55,0x8c,0x53,0x3c,0xa5,0x98,0xa4,0x98,0xaa,0x98,0xa1,0x98,0xa3,0x98, |
1125 | | 0xaf,0x58,0xa8,0x78,0x45,0x91,0xa0,0x48,0x52,0xa4,0x29,0x32,0x25,0x19,0x8a,0x2c, |
1126 | | 0xc5,0x6a,0xc5,0x7a,0x45,0x8e,0xa2,0x40,0x51,0xa4,0x28,0x56,0x94,0x28,0xca,0x14, |
1127 | | 0x95,0x8a,0x2a,0x45,0x9d,0xa2,0x49,0xd1,0xa2,0xd8,0x2c,0x6a,0x55,0xbc,0xa1,0x68, |
1128 | | 0x57,0x74,0x2a,0xde,0x52,0xbc,0xa7,0x38,0xa3,0xb8,0xa0,0x78,0x44,0xd4,0xa3,0xb8, |
1129 | | 0xa4,0xb8,0xac,0xb8,0xa2,0xb8,0xaa,0xb8,0xa6,0x30,0x2a,0x78,0x5e,0x7c,0x2f,0x1b, |
1130 | | 0x2f,0xa1,0x97,0xc4,0xcb,0xd9,0x6b,0xb8,0x97,0xcc,0x4b,0xee,0xa5,0xf4,0xf2,0xf1, |
1131 | | 0x0a,0xf0,0xd2,0x7a,0xe9,0xbc,0x22,0xbd,0x92,0x14,0x7a,0xaf,0x78,0xaf,0x3b,0xbd, |
1132 | | 0x46,0x79,0x8d,0xf1,0x1a,0xeb,0xf5,0xa8,0xd7,0x38,0xaf,0x78,0xc5,0x53,0x5e,0x93, |
1133 | | 0xbc,0xa6,0x7a,0xcd,0xf0,0x9a,0xe3,0x35,0xdf,0x6b,0xa1,0xd7,0x2b,0x5e,0x09,0x5e, |
1134 | | 0x49,0x5e,0x69,0x5e,0x19,0x5e,0x59,0x5e,0xab,0xbd,0xd6,0x7b,0xe5,0x78,0x15,0x78, |
1135 | | 0x15,0x79,0x15,0x7b,0x95,0x78,0xc9,0x3d,0xcb,0xbc,0x2a,0xbd,0xaa,0xbc,0xea,0xbc, |
1136 | | 0x9e,0x70,0x68,0xf2,0x6a,0xf1,0x6a,0xf5,0x7a,0xc3,0xab,0xdd,0xab,0xd3,0xeb,0x2d, |
1137 | | 0xaf,0xf7,0xbc,0xce,0x78,0x5d,0xf0,0xea,0xf1,0xba,0xe4,0x35,0x4a,0x7a,0xd9,0xeb, |
1138 | | 0x8a,0xd7,0x55,0xaf,0x6b,0x5e,0x46,0x2f,0x9e,0x92,0xaf,0xb4,0x51,0x0a,0x95,0xa3, |
1139 | | 0x14,0x12,0xa5,0xb3,0x72,0xb8,0x52,0xa6,0x94,0x2b,0x95,0x4a,0x1f,0x65,0x80,0x52, |
1140 | | 0xab,0xd4,0x29,0x23,0x95,0x7a,0x65,0xbc,0x72,0xb3,0xe4,0x4e,0xe5,0x28,0xe5,0x18, |
1141 | | 0xe5,0x58,0xe5,0xa3,0xca,0x71,0xca,0xa7,0x94,0x93,0x94,0x53,0x95,0x33,0x94,0x73, |
1142 | | 0x94,0xf3,0x95,0x0b,0x95,0x1f,0x8a,0x5f,0x51,0x26,0x28,0x93,0x94,0x69,0xca,0x0c, |
1143 | | 0x65,0x96,0x72,0xb5,0x72,0xbd,0x32,0x47,0x59,0xa0,0x2c,0x52,0x16,0x2b,0x4b,0x94, |
1144 | | 0x65,0xca,0x4a,0x65,0x95,0xf2,0x1e,0x49,0x9d,0xf2,0x11,0x49,0x93,0xb2,0x45,0xd9, |
1145 | | 0xaa,0x64,0xc7,0xf1,0x1b,0x88,0xdb,0xb9,0x5c,0xa7,0xf2,0x2d,0xe5,0x7b,0xca,0x33, |
1146 | | 0xca,0x0b,0xca,0x1e,0xe5,0x25,0xe5,0x65,0xe5,0x15,0xe5,0x77,0x62,0xa3,0xf1,0x2a, |
1147 | | 0x8e,0x5d,0xe3,0x8e,0x1b,0x95,0x3c,0x95,0xf9,0x4d,0xbe,0xca,0x46,0x25,0x54,0x49, |
1148 | | 0x54,0xce,0xaa,0xe1,0x2a,0x99,0x4a,0xae,0x52,0xaa,0x7c,0x54,0x01,0x2a,0xad,0x4a, |
1149 | | 0xa7,0x8a,0x54,0xe9,0x55,0xf1,0xaa,0x3b,0x55,0xa3,0x54,0x8d,0xa2,0x31,0xaa,0xb1, |
1150 | | 0xaa,0x47,0x55,0xe3,0x54,0x4f,0xa9,0x26,0xa9,0xa6,0xaa,0x66,0xa8,0xe6,0xa8,0xe6, |
1151 | | 0xab,0x16,0xaa,0x5e,0x51,0x25,0xa8,0x92,0x54,0x69,0xaa,0xa7,0xa4,0x19,0xaa,0x2c, |
1152 | | 0xd5,0x6a,0xd5,0x7a,0xd5,0x1c,0x69,0x8e,0xaa,0x40,0x55,0xa4,0x2a,0x56,0x95,0xa8, |
1153 | | 0x24,0x5e,0x65,0xaa,0x4a,0x55,0x95,0xaa,0x4e,0xd5,0xa4,0x6a,0x41,0x68,0x55,0xbd, |
1154 | | 0xa1,0x6a,0x57,0x75,0xaa,0xde,0x52,0xbd,0xa7,0x3a,0xa3,0xba,0xa0,0x32,0x2a,0x7b, |
1155 | | 0x54,0x97,0x54,0x97,0x55,0x57,0x54,0x57,0x55,0xdf,0xab,0xb8,0xef,0x62,0xd4,0x56, |
1156 | | 0x6a,0x81,0xda,0x56,0x3d,0x54,0xed,0xa0,0x96,0xaa,0x5d,0xd5,0x3a,0x95,0xbb,0xda, |
1157 | | 0x53,0xad,0x52,0xbf,0xa1,0xf4,0x55,0x07,0xaa,0x83,0xd5,0x61,0xea,0x28,0xb5,0x41, |
1158 | | 0x7d,0x9b,0xfa,0x2e,0xf5,0xbd,0xea,0xfb,0xd5,0x0f,0xa9,0x1f,0x53,0x3f,0xaa,0xfa, |
1159 | | 0x87,0x7a,0x9c,0xea,0x69,0xf5,0x64,0xf5,0xb3,0xea,0x99,0xea,0xb9,0xea,0x76,0xe5, |
1160 | | 0x42,0xcf,0xe7,0xd5,0x2f,0xaa,0xe3,0xc4,0x69,0x8a,0x4e,0xaf,0x45,0x6a,0x46,0xbd, |
1161 | | 0x50,0x95,0xac,0x7e,0x45,0x95,0xae,0x5e,0xa6,0x5e,0xa1,0x7e,0x4b,0xb9,0x46,0xbd, |
1162 | | 0x41,0x9d,0xab,0xde,0xa4,0xde,0xa2,0x7e,0x4f,0xb9,0x5d,0xbd,0x4b,0xbd,0x47,0xbd, |
1163 | | 0x57,0x5d,0xad,0xae,0x57,0x97,0xa8,0x9a,0xd5,0x07,0xd4,0x12,0xaf,0xc3,0xea,0x3a, |
1164 | | 0xd5,0x51,0xf5,0x71,0xf5,0x49,0xf5,0xdb,0xea,0xf7,0xd5,0xed,0xaa,0xb3,0xea,0x6b, |
1165 | | 0xca,0x8f,0xd4,0x9d,0xaa,0x48,0x45,0xaf,0xfa,0x2d,0xd5,0xc7,0xea,0x33,0xaa,0xcf, |
1166 | | 0xd4,0x5f,0xaa,0xbf,0x51,0x7f,0xaf,0x26,0xef,0x1e,0xd5,0x65,0xa5,0x95,0xf7,0x25, |
1167 | | 0x95,0xc0,0xfb,0xb2,0xca,0xd6,0x7b,0xbc,0xc3,0x50,0x6f,0x47,0xef,0x61,0xde,0x32, |
1168 | | 0x6f,0xb9,0xb7,0xd2,0xdb,0xc7,0x3b,0xd0,0x3b,0xc4,0x3b,0xc2,0x3b,0xc6,0xfb,0xcf, |
1169 | | 0x5c,0xff,0xc6,0x79,0xdf,0xee,0x7d,0x97,0xf7,0x28,0xef,0x31,0xde,0x63,0x11,0x7e, |
1170 | | 0xa9,0xd4,0x23,0xde,0xe3,0xbc,0x9f,0xf6,0x7e,0xc6,0x7b,0xfa,0x4d,0x25,0xe6,0x78, |
1171 | | 0x63,0x1d,0xea,0xfd,0x92,0xf7,0x22,0xbb,0x14,0xbb,0x45,0xde,0x09,0xde,0x89,0xde, |
1172 | | 0x29,0xde,0xe9,0xde,0x19,0xde,0xb7,0xd9,0x65,0x7a,0xaf,0xf6,0xde,0xe0,0x5d,0xe0, |
1173 | | 0xbd,0xcd,0xbb,0xc4,0x7b,0x8f,0xf7,0x3e,0xef,0x5a,0xef,0x26,0xef,0x03,0xde,0x6d, |
1174 | | 0xde,0xc7,0x50,0xbb,0xd3,0xfb,0x6d,0xef,0x0f,0xbc,0xcf,0x7b,0xf7,0x20,0xff,0x31, |
1175 | | 0xf8,0xdc,0xfb,0x6b,0xc4,0xd7,0xbc,0xc9,0xa7,0xdf,0x68,0xed,0x33,0xc4,0x47,0xe8, |
1176 | | 0xe3,0xe0,0xe3,0xe2,0xe3,0xe6,0x23,0xf7,0x51,0xf9,0xf8,0xf9,0x68,0x7c,0x74,0x08, |
1177 | | 0x11,0xe6,0x10,0x6d,0x0e,0x06,0x73,0x88,0x37,0x87,0x3b,0xcc,0xe1,0x6e,0x73,0xb8, |
1178 | | 0xd7,0x1c,0xc6,0x98,0xc3,0x83,0xe6,0xf0,0xb0,0x39,0x3c,0x66,0x0e,0xe3,0xcc,0x61, |
1179 | | 0x3c,0xc2,0x04,0x84,0xc9,0x08,0x53,0x11,0xa6,0x23,0xcc,0x42,0x98,0x6b,0x0e,0xf3, |
1180 | | 0xcd,0x61,0x81,0x39,0xbc,0x64,0x0e,0x8b,0x10,0x12,0xcc,0x21,0x11,0x21,0xc5,0x1c, |
1181 | | 0xd2,0xcd,0x21,0x03,0x21,0x13,0xe1,0x8f,0x3f,0x6d,0x56,0xfa,0x98,0xc2,0x1a,0x84, |
1182 | | 0xf5,0x08,0xd9,0x08,0x1f,0x58,0xe7,0xf9,0xe4,0xf9,0x6c,0x42,0x28,0x42,0xd8,0x66, |
1183 | | 0x0e,0x3b,0x10,0x76,0x21,0x94,0x23,0xec,0x47,0xa8,0x43,0x68,0x46,0x38,0x88,0x70, |
1184 | | 0x84,0x0b,0xed,0x5c,0x38,0x69,0x0e,0x6f,0xf9,0xbc,0xef,0x73,0x0e,0xdb,0xdd,0x3e, |
1185 | | 0x97,0x7c,0x3e,0xf3,0xf9,0xca,0xe7,0x3b,0x1f,0xa3,0x8f,0x95,0xef,0x60,0x5f,0x7b, |
1186 | | 0x5f,0x89,0xaf,0xd4,0x77,0x84,0xaf,0x87,0xaf,0xd2,0xd7,0xd7,0x37,0xc8,0x37,0xd4, |
1187 | | 0x37,0xd2,0xd7,0xe0,0x7b,0xbb,0xef,0x3d,0xbe,0x63,0x7c,0x1f,0xf2,0x7d,0xdc,0x77, |
1188 | | 0xbc,0xef,0x24,0xdf,0x67,0x7d,0x67,0xf9,0xce,0xf3,0x5d,0xe8,0xbb,0xc8,0x77,0xb1, |
1189 | | 0x6f,0xaa,0x6f,0x86,0xef,0x0a,0xdf,0xb5,0xbe,0xd9,0xbe,0x05,0xbe,0x5b,0x7c,0x77, |
1190 | | 0xf8,0xee,0xf6,0xad,0xf4,0xad,0xf6,0x6d,0xf0,0x7d,0xdd,0xb7,0xd5,0xf7,0xa8,0x6f, |
1191 | | 0x87,0xef,0x69,0xdf,0xf7,0x7c,0xcf,0xfa,0x76,0xf9,0x5e,0xf4,0xbd,0xec,0xfb,0xa5, |
1192 | | 0xef,0xb7,0xbe,0xfd,0xbe,0x3c,0x3f,0x81,0x9f,0x9d,0x9f,0xd8,0xcf,0xd9,0xcf,0xd5, |
1193 | | 0x6f,0xa4,0x9f,0x97,0x9f,0x8f,0x5f,0xa0,0x5f,0x88,0x5f,0x84,0x9f,0xde,0xef,0x36, |
1194 | | 0xbf,0xbb,0xfd,0x46,0xfb,0x8d,0xf5,0x7b,0xcc,0xef,0x49,0xbf,0x89,0x7e,0x53,0xfd, |
1195 | | 0x66,0xfa,0x3d,0xe7,0xb7,0xc0,0xef,0x15,0x3f,0xc6,0x2f,0xc5,0x6f,0xa9,0x5f,0x96, |
1196 | | 0xdf,0x1a,0xbf,0x8d,0x7e,0xf9,0x7e,0x45,0x7e,0xdb,0xfd,0x76,0xfb,0xed,0xf5,0xab, |
1197 | | 0xf5,0x6b,0xf6,0x3b,0xe4,0x77,0xd4,0xaf,0xc3,0xef,0x9c,0xcf,0x69,0x3f,0xb6,0x27, |
1198 | | 0xef,0xf9,0x9d,0xf5,0xfb,0xce,0xa7,0xcb,0x8f,0xed,0xc9,0x45,0xbf,0xcb,0x7e,0x52, |
1199 | | 0xdf,0x2f,0xfd,0xd8,0x9e,0x7c,0xeb,0xd7,0xef,0xe7,0xeb,0xcb,0xf3,0x67,0x7b,0xc3, |
1200 | | 0x5a,0x65,0xb2,0x68,0xc0,0x16,0x93,0x15,0x02,0xff,0x08,0x3f,0x3b,0x7f,0xb1,0xff, |
1201 | | 0x63,0x7e,0xce,0xfe,0xac,0x7a,0x91,0x9f,0xab,0xff,0x48,0xff,0xa5,0x7e,0x5e,0xfe, |
1202 | | 0xac,0x2e,0xeb,0x2d,0x1f,0xff,0x73,0x3e,0x81,0xfe,0x03,0xde,0x0a,0xf1,0x1f,0xf0, |
1203 | | 0x55,0x84,0xbf,0xef,0x4d,0x3e,0xba,0xd9,0x43,0x7a,0xff,0x9b,0x7d,0xf4,0x73,0x0f, |
1204 | | 0xb1,0xde,0xb9,0xe1,0x97,0x01,0x9f,0xdc,0xe6,0x3f,0xe0,0x91,0x01,0x6f,0xdc,0xed, |
1205 | | 0xcf,0xfa,0x62,0xb4,0xff,0x80,0x27,0xc6,0x72,0x96,0xb0,0x36,0x98,0xd4,0x1f,0xf3, |
1206 | | 0x9f,0xe5,0xfb,0xa4,0xff,0x44,0xff,0xa9,0xfe,0x6c,0x3b,0xae,0x5c,0x0d,0xb6,0xd4, |
1207 | | 0x4c,0xff,0xf9,0xfe,0x2f,0xfb,0x2f,0xf6,0x4f,0xf5,0xcf,0xf0,0x5f,0xe1,0xbf,0xd6, |
1208 | | 0x3f,0xdb,0xbf,0xc0,0x7f,0x8b,0xff,0x0e,0xff,0xdd,0xfe,0x95,0xfe,0xd5,0xfe,0x0d, |
1209 | | 0xfe,0xaf,0xfb,0xb7,0xfa,0x1f,0xf5,0xef,0xf0,0x3f,0xed,0xff,0x9e,0xff,0x59,0xff, |
1210 | | 0x2e,0xff,0x8b,0xfe,0x97,0xd1,0xca,0x97,0xfe,0xdf,0xfa,0xf7,0xfb,0xf3,0x02,0x7e, |
1211 | | 0x6f,0xbd,0x81,0xed,0x27,0x61,0xcf,0x5a,0xb3,0x37,0x4c,0xfb,0xd8,0x51,0x22,0x08, |
1212 | | 0x10,0x04,0xfc,0xa6,0xf5,0x41,0x80,0x03,0xc2,0xf0,0x00,0x8f,0x00,0x75,0x40,0x60, |
1213 | | 0x80,0x2e,0x20,0x06,0xe1,0xf6,0x80,0x7b,0x03,0xc6,0x06,0x3c,0x11,0x30,0x21,0xe0, |
1214 | | 0x59,0x84,0x39,0x01,0x0b,0x10,0x5e,0x45,0x48,0x0e,0xc8,0x40,0x58,0x15,0xb0,0x11, |
1215 | | 0x61,0x13,0x42,0x71,0xc0,0x6e,0x84,0x7d,0x08,0xf5,0x01,0x2d,0x01,0x47,0x02,0x3a, |
1216 | | 0x10,0xde,0x0e,0x38,0x13,0xd0,0x1d,0xf0,0x49,0xc0,0x97,0x08,0xd7,0x02,0x2c,0x03, |
1217 | | 0x07,0x07,0x0e,0x0d,0x74,0x0e,0xc4,0xd2,0x31,0x50,0x81,0xe0,0x8b,0xa0,0x0d,0x8c, |
1218 | | 0x08,0x8c,0x0d,0xbc,0x2b,0x70,0x4c,0xe0,0x23,0x81,0x4f,0x06,0xb2,0x36,0x4c,0x0e, |
1219 | | 0x9c,0x11,0x38,0x2f,0xf0,0xa5,0x40,0x26,0x30,0x0d,0x21,0x33,0x70,0x6d,0x60,0x6e, |
1220 | | 0x60,0x11,0xc2,0xce,0xc0,0xf2,0xc0,0xea,0xc0,0xa6,0xc0,0x43,0x81,0x6f,0x06,0x9e, |
1221 | | 0x0c,0x7c,0x2f,0xf0,0x7c,0x60,0x5f,0xe0,0x67,0x81,0x57,0x03,0xfb,0x03,0xad,0x83, |
1222 | | 0x6c,0x83,0x24,0x41,0xc3,0x82,0x46,0x06,0xa9,0x82,0x02,0x82,0x42,0x83,0xa2,0x83, |
1223 | | 0xae,0x05,0x0c,0x0e,0xbc,0x2d,0x68,0x54,0xd0,0x83,0x41,0x8f,0x07,0x3d,0x1d,0x34, |
1224 | | 0x15,0x3c,0x18,0x34,0x3b,0xe8,0x85,0xa0,0x45,0x41,0x49,0x41,0x4b,0xb1,0x7d,0x04, |
1225 | | 0xd6,0xaf,0x0c,0xda,0x10,0xf4,0xfb,0xbf,0x09,0xbd,0x75,0x28,0x08,0xda,0x16,0x54, |
1226 | | 0x1a,0xb4,0x3f,0xa8,0x29,0xe8,0x70,0x50,0x47,0xd0,0xbb,0x41,0x17,0x82,0x3e,0x0e, |
1227 | | 0xba,0x12,0xe4,0xa8,0x51,0x68,0x7e,0xfa,0x9b,0x7e,0xb7,0xfe,0xf8,0x6b,0x02,0x35, |
1228 | | 0xfd,0xc6,0x60,0x8d,0xd1,0x32,0x54,0x13,0xa6,0x89,0xd0,0xc4,0x68,0xfe,0xbd,0x6f, |
1229 | | 0x10,0xf0,0x84,0xd1,0xdc,0xa1,0xb9,0x07,0x81,0xfd,0x7d,0x86,0x7b,0x35,0xa3,0x35, |
1230 | | 0xf7,0x6b,0x1e,0xd2,0x3c,0xa6,0xf9,0x87,0xe6,0x69,0xcd,0x64,0x0d,0xfb,0x5d,0xf1, |
1231 | | 0xb3,0x9a,0x99,0x9a,0xb9,0x9a,0xe7,0x39,0x7b,0x5e,0xd4,0xbc,0xac,0x71,0xb5,0x33, |
1232 | | 0x85,0x7b,0xb8,0x5a,0x26,0x7d,0xe8,0x58,0x06,0x43,0x3f,0x54,0x13,0xf7,0xa3,0x76, |
1233 | | 0x16,0x69,0x5e,0xd3,0x30,0x9a,0xdb,0xec,0x12,0x35,0xc9,0x9a,0x54,0xcd,0x3d,0x76, |
1234 | | 0xfd,0xc6,0x74,0xcd,0x52,0xcd,0x32,0x4d,0xe6,0x75,0x2b,0x57,0x68,0xd6,0x68,0x36, |
1235 | | 0xa2,0xed,0x3c,0xec,0x29,0xd4,0x6c,0xd5,0xec,0xd4,0xec,0xd6,0x54,0x6a,0xaa,0x34, |
1236 | | 0xf5,0x9a,0x66,0xcd,0x41,0x4d,0x9b,0xe6,0x98,0xa6,0x03,0xe1,0x24,0xc2,0x5b,0x08, |
1237 | | 0xef,0x22,0x7c,0x60,0x0e,0x67,0x11,0x2e,0x98,0x43,0x37,0x42,0x9f,0x39,0x7c,0x6c, |
1238 | | 0x0e,0x97,0xcd,0xe1,0x0b,0x73,0xf8,0xca,0x1c,0xbe,0x41,0xb8,0x86,0xd0,0x8f,0x60, |
1239 | | 0xa1,0xb5,0xd0,0x5a,0x99,0x03,0xdf,0x1c,0x86,0x98,0x83,0x9d,0x39,0x0c,0x35,0x07, |
1240 | | 0x89,0x39,0x38,0x99,0x83,0x8b,0x39,0xb8,0x9a,0x83,0xcc,0x1c,0x3c,0xcc,0x41,0x61, |
1241 | | 0x0e,0x2a,0x73,0xf0,0x31,0x07,0x7f,0x73,0x08,0x42,0x60,0x9f,0x06,0xc1,0x5a,0x53, |
1242 | | 0xd0,0x21,0x44,0x21,0xc4,0x22,0xdc,0x81,0x60,0xfa,0x4d,0x95,0x7e,0x63,0xa8,0x66, |
1243 | | 0x94,0x76,0x11,0xe7,0xb5,0xd7,0x34,0xf7,0x69,0x59,0xef,0xb2,0x1e,0xf5,0xd7,0x24, |
1244 | | 0x6a,0xa6,0x38,0x8c,0xd1,0xde,0xea,0xf7,0x53,0xd8,0xd1,0x90,0x0c,0x6f,0xa7,0xe2, |
1245 | | 0x8c,0x64,0x6a,0x7e,0xcf,0x37,0xd4,0x2f,0x6a,0xd2,0x71,0xa6,0x1f,0xd0,0xde,0xa3, |
1246 | | 0x79,0xc3,0xf6,0xf7,0xd4,0xbf,0x57,0x33,0x56,0x3b,0x5a,0xf3,0xb0,0xf6,0x51,0xed, |
1247 | | 0x38,0xed,0x14,0x07,0x76,0x04,0x05,0x6a,0x9e,0xd2,0x7e,0xeb,0x32,0x49,0x3b,0x55, |
1248 | | 0x3b,0x43,0x3b,0x47,0x3b,0x5f,0xbb,0x50,0xfb,0x8a,0x36,0x41,0x9b,0xa4,0x4d,0xd3, |
1249 | | 0xfe,0x55,0x6f,0xd0,0x32,0xb4,0x59,0xda,0xd5,0x5a,0xa2,0x3f,0xf2,0x7e,0xd9,0x34, |
1250 | | 0x46,0x6f,0x7e,0xcb,0xcc,0x6e,0xdf,0xfc,0xa6,0x99,0xdd,0xbe,0xf9,0x6d,0x33,0xbb, |
1251 | | 0x6d,0x7a,0xe3,0x6c,0xaa,0xbb,0x5e,0x9b,0xad,0xcd,0xd3,0x46,0xd2,0x26,0x6d,0x91, |
1252 | | 0x76,0x1b,0xce,0xe9,0x4e,0xed,0x6e,0x6d,0x85,0x76,0xbf,0xb6,0x56,0xdb,0xa8,0x7d, |
1253 | | 0x5d,0xfb,0xeb,0xf7,0x87,0x43,0xda,0x37,0xb4,0xc7,0xb5,0xa7,0xb4,0xef,0x6a,0xcf, |
1254 | | 0x68,0x3f,0xd2,0xf6,0x69,0x3f,0xd5,0x5e,0xd1,0x7e,0xa3,0xfd,0x41,0x6b,0x19,0xcc, |
1255 | | 0x0f,0xb6,0x0d,0x16,0x05,0x3b,0x05,0x0f,0x0f,0x76,0x0f,0x56,0x04,0x7b,0x07,0x07, |
1256 | | 0x04,0x07,0x07,0x87,0x07,0xc7,0x04,0xc7,0x07,0xdf,0x15,0x7c,0x5f,0xf0,0x83,0xc1, |
1257 | | 0x8f,0x06,0xff,0x23,0x78,0x42,0xf0,0x94,0xe0,0x19,0xc1,0x73,0x83,0x5f,0x08,0x7e, |
1258 | | 0x39,0x38,0x21,0x38,0x39,0x78,0x49,0xf0,0x7f,0xfa,0xf7,0xa9,0x7f,0xed,0x3b,0xd0, |
1259 | | 0xcc,0xe0,0xd5,0xc1,0x1b,0x82,0xf3,0x82,0x37,0x07,0x17,0x07,0xef,0x0a,0x2e,0x0f, |
1260 | | 0xde,0x1f,0x5c,0x17,0xdc,0x1c,0x7c,0x30,0xf8,0x48,0x70,0x7b,0xf0,0xc9,0xe0,0x77, |
1261 | | 0x82,0x3f,0x0c,0xbe,0x10,0xdc,0x1b,0xfc,0x49,0xf0,0x17,0xc1,0x57,0x83,0xbf,0x0f, |
1262 | | 0xb6,0x08,0x19,0x14,0x62,0x13,0x32,0x34,0xc4,0x31,0x64,0x58,0x88,0x2c,0xc4,0x33, |
1263 | | 0x44,0x1d,0xe2,0x1f,0xa2,0x0d,0x09,0x0b,0x89,0x0e,0xf9,0xb3,0xbf,0xa5,0xf8,0xab, |
1264 | | 0xda,0xfb,0xe9,0xdd,0x39,0x2e,0xe4,0xce,0x90,0x7b,0x43,0x1e,0x08,0x79,0x24,0x64, |
1265 | | 0x5c,0xc8,0xd3,0x21,0xcf,0x84,0x4c,0x0f,0x99,0x13,0xf2,0x3c,0x7a,0xf3,0x52,0xc8, |
1266 | | 0x6b,0x21,0x49,0x21,0xe9,0x21,0xcb,0x43,0x56,0x85,0xac,0x0f,0xc9,0x0d,0x29,0x0c, |
1267 | | 0xd9,0x16,0x52,0x12,0xb2,0x27,0x64,0x5f,0x48,0x6d,0x48,0x13,0x8e,0x1f,0x08,0x69, |
1268 | | 0x0b,0x39,0x16,0xd2,0x19,0xf2,0x76,0xc8,0x07,0x21,0xe7,0xb1,0xdd,0x13,0xf2,0x71, |
1269 | | 0x48,0xff,0xaf,0x7e,0x1f,0xfc,0xdb,0x8e,0xf7,0xff,0xe8,0x37,0xf6,0x3e,0x0f,0xf9, |
1270 | | 0x32,0xe4,0x79,0xba,0x1a,0x92,0x60,0xd1,0x6f,0xfc,0x2e,0xe4,0x87,0x10,0x8b,0x50, |
1271 | | 0xab,0x50,0xf6,0x6f,0xe0,0xf9,0xa1,0x36,0xa1,0xf6,0xa1,0xa2,0xd0,0xd9,0x1e,0x0e, |
1272 | | 0xa1,0x45,0x16,0xce,0xa1,0x5f,0xd1,0xb0,0xd0,0x11,0xa1,0xee,0xa1,0xf2,0x50,0xaf, |
1273 | | 0xd0,0x20,0x0f,0x75,0xa8,0x7f,0xa8,0x26,0x34,0x24,0x34,0x22,0x34,0x3a,0xb4,0x98, |
1274 | | 0xe2,0x42,0x6f,0x0f,0x1d,0x49,0x77,0x85,0x8e,0x0a,0x15,0x0d,0xbd,0x3f,0xf4,0x80, |
1275 | | 0xc5,0xd8,0xd0,0x47,0x42,0x1f,0x0f,0x7d,0x32,0xf4,0xb8,0xc5,0xd3,0xa1,0xfd,0xc6, |
1276 | | 0xc9,0xa1,0x53,0x43,0xa7,0x87,0xce,0x0a,0x9d,0x1b,0x3a,0x3f,0x74,0x41,0xe8,0x4b, |
1277 | | 0xa1,0xaf,0x85,0xde,0xf0,0x50,0x52,0x68,0x7a,0xe8,0xf2,0xd0,0x55,0xa1,0xeb,0x43, |
1278 | | 0x73,0x43,0x0b,0x43,0xb7,0x85,0x96,0x84,0xee,0x09,0xdd,0x17,0x5a,0x1b,0xda,0x14, |
1279 | | 0x7a,0x20,0xb4,0x2d,0xf4,0x58,0x68,0x67,0xe8,0xdb,0xa1,0x1f,0x84,0x9e,0x0f,0xed, |
1280 | | 0x09,0xfd,0x38,0xf4,0xf3,0xd0,0xaf,0x43,0xaf,0x85,0x92,0xce,0x5a,0x37,0x44,0x27, |
1281 | | 0xd4,0x39,0xe8,0x5c,0x74,0x6e,0x3a,0xb9,0x4e,0xa5,0xf3,0xd3,0x69,0x74,0x3a,0x5d, |
1282 | | 0x94,0x2e,0x56,0x77,0x87,0x6e,0x94,0xee,0x7e,0xdd,0xc3,0xba,0x27,0x74,0x4f,0xe9, |
1283 | | 0x26,0xeb,0xa6,0xe9,0x66,0xeb,0xe6,0xeb,0x5e,0xd4,0xbd,0xaa,0xfb,0xfd,0xdf,0xc0, |
1284 | | 0x27,0xea,0xd2,0x74,0xcb,0x74,0x2b,0x75,0xeb,0x74,0x39,0xba,0x4d,0xba,0xad,0xba, |
1285 | | 0x9d,0xba,0x32,0xdd,0x5e,0x5d,0x8d,0xae,0x51,0xd7,0xa2,0x3b,0xac,0x7b,0x53,0x77, |
1286 | | 0x42,0xf7,0x96,0xee,0x7d,0xdd,0x39,0x5d,0xb7,0xee,0x92,0xee,0xf7,0x8c,0xa8,0x3f, |
1287 | | 0x3a,0xbf,0xf8,0x4c,0xf7,0x95,0xee,0x3b,0x9d,0x51,0x67,0x15,0x36,0x38,0xcc,0x3e, |
1288 | | 0x4c,0x12,0x26,0x0d,0x1b,0x11,0xe6,0x11,0xa6,0x0c,0xf3,0x0d,0x0b,0x0a,0x0b,0x0d, |
1289 | | 0x8b,0x0c,0x33,0x84,0xdd,0x1e,0x76,0x4f,0xd8,0x98,0xb0,0x87,0xc2,0x1e,0x0f,0x1b, |
1290 | | 0x1f,0x36,0x29,0xec,0xd9,0xb0,0x59,0x61,0xf3,0xc2,0x16,0x86,0x2d,0x0a,0x5b,0x1c, |
1291 | | 0x96,0x1a,0x96,0x11,0xb6,0x22,0x6c,0x6d,0x58,0x76,0x58,0x41,0xd8,0x96,0xb0,0x1d, |
1292 | | 0x61,0xbb,0xc3,0x2a,0xc3,0xaa,0xc3,0x1a,0xc2,0x5e,0x0f,0x6b,0x0d,0x3b,0x1a,0xd6, |
1293 | | 0x11,0x76,0x3a,0xec,0xbd,0xb0,0xb3,0x61,0x5d,0x61,0x17,0xc3,0x2e,0x87,0x7d,0x19, |
1294 | | 0xf6,0x6d,0x58,0x7f,0x18,0x2f,0x5c,0x10,0x6e,0x17,0x2e,0x0e,0x77,0x0e,0x77,0x0d, |
1295 | | 0x1f,0x19,0xee,0x15,0xee,0x13,0xfe,0x3f,0xf7,0x97,0x1c,0xa6,0x10,0x18,0x1e,0x12, |
1296 | | 0x1e,0x11,0xae,0x0f,0xbf,0x2d,0xfc,0xee,0xf0,0xd1,0xe1,0x63,0xc3,0x1f,0x0b,0x7f, |
1297 | | 0x32,0x7c,0x62,0xf8,0xd4,0xf0,0x99,0xe1,0xcf,0x85,0x2f,0x08,0x7f,0x25,0x9c,0x09, |
1298 | | 0x4f,0x09,0x5f,0x1a,0x9e,0x15,0xbe,0x26,0x7c,0x63,0x78,0x7e,0x78,0x51,0xf8,0xf6, |
1299 | | 0xf0,0x5f,0x3b,0x47,0xbf,0x3e,0x3e,0x6e,0xde,0xff,0xf3,0xdf,0x3e,0xfd,0x73,0xfe, |
1300 | | 0xfe,0xeb,0xd6,0x7f,0xd3,0xf0,0x7b,0x7e,0x17,0xed,0xe7,0xf3,0x87,0x1f,0xff,0xc6, |
1301 | | 0xee,0xef,0xff,0x94,0x86,0xef,0x0f,0x6f,0x0a,0x3f,0x1a,0xfe,0x4e,0x78,0x77,0xf8, |
1302 | | 0x95,0xf0,0xdf,0xf6,0xf7,0x2c,0xbf,0xfc,0x57,0x2d,0xff,0xc9,0x0f,0x45,0x0c,0x8e, |
1303 | | 0x10,0x47,0xc8,0x22,0x7c,0x23,0xc2,0x23,0xfe,0xfa,0xdf,0x02,0xfa,0x57,0xe1,0x3f, |
1304 | | 0xf5,0x3b,0x89,0x7f,0xbc,0x4e,0xbf,0xf1,0x7f,0x97,0x6d,0xfd,0x46,0xb6,0x0e,0xeb, |
1305 | | 0x43,0x3b,0x2e,0x66,0xeb,0xb0,0xe9,0x40,0x1d,0xf6,0x9b,0x87,0x5b,0xeb,0xf4,0x1b, |
1306 | | 0x6d,0xc0,0x8f,0x75,0xfa,0x8d,0xff,0xf3,0xbe,0xee,0x37,0xde,0xf0,0xb5,0xa9,0x3f, |
1307 | | 0x37,0xd7,0xf9,0x69,0x7f,0x7e,0xff,0xd8,0xb9,0x59,0xe7,0x46,0x9d,0x7e,0xe3,0x08, |
1308 | | 0x1a,0xf8,0xc6,0xe6,0xcf,0xd1,0xf9,0xbb,0xce,0xdf,0x75,0xfe,0x53,0x75,0xee,0x88, |
1309 | | 0xb8,0x3b,0x82,0x1d,0xbb,0xbf,0xfe,0xdf,0x62,0x74,0xbc,0x1f,0xff,0xb7,0x98,0x7b, |
1310 | | 0x23,0x7e,0xbd,0xce,0x98,0x9f,0xd4,0xb9,0x3f,0xc2,0x1f,0xe5,0x22,0xb0,0x7d,0x2f, |
1311 | | 0x8e,0xff,0xad,0xf9,0x7f,0x4b,0x73,0x3e,0x02,0x3b,0x96,0x6e,0x35,0x77,0xfa,0xb3, |
1312 | | 0xf7,0xfd,0x7b,0x2b,0xb9,0x5b,0xaf,0xba,0xfb,0x7f,0x56,0xf7,0xc6,0xfc,0xe2,0xe7, |
1313 | | 0xff,0x3f,0xc8,0xf4,0xdf,0x83,0x6e,0xfd,0xbf,0x83,0x46,0x72,0xff,0x35,0x68,0xc4, |
1314 | | 0xc8,0xb7,0xad,0x2a,0x78,0xd5,0xbc,0xcf,0xac,0x36,0x5a,0xed,0xb5,0xba,0x75,0x0b, |
1315 | | 0x6c,0x7d,0xde,0x8f,0xea,0xb2,0xff,0x75,0x68,0x26,0xea,0x95,0xf1,0xde,0xe4,0xad, |
1316 | | 0xb6,0xea,0x70,0xcf,0xb5,0xfa,0x2d,0xf3,0x9f,0x87,0x22,0x1e,0x8f,0x18,0x1f,0x31, |
1317 | | 0x29,0xe2,0xd9,0x88,0x59,0x11,0xf3,0x22,0x16,0x46,0x2c,0x8a,0x58,0x1c,0x91,0x1a, |
1318 | | 0x91,0x11,0xb1,0x22,0x62,0x6d,0x44,0x76,0x44,0x41,0xc4,0x96,0x88,0x1d,0x11,0xbb, |
1319 | | 0x23,0x2a,0x23,0xaa,0x23,0x1a,0x22,0x5e,0x8f,0x68,0x8d,0x38,0x1a,0xd1,0x11,0x71, |
1320 | | 0x3a,0xe2,0xbd,0x88,0xb3,0x11,0x5d,0x11,0x17,0x23,0x2e,0x47,0x7c,0x19,0xf1,0xed, |
1321 | | 0x1f,0x9a,0xc1,0xb1,0xef,0x18,0x2f,0x6b,0xbe,0xd1,0xf4,0x1b,0x83,0xb4,0x16,0xda, |
1322 | | 0x2f,0x34,0x43,0xb5,0xc1,0xdc,0xbb,0x3d,0xf6,0x7d,0x9e,0x95,0xd6,0x49,0xeb,0xaa, |
1323 | | 0x1d,0xa2,0x95,0x69,0xfb,0x35,0x7c,0x2d,0xfb,0xe6,0xf1,0x2b,0xcd,0x35,0x8d,0x9d, |
1324 | | 0x56,0xa2,0x75,0xd1,0xf6,0x47,0x2c,0xf2,0xb1,0x88,0xb4,0x8a,0xec,0x37,0xb2,0xf5, |
1325 | | 0xfb,0x8d,0xfe,0xdc,0xbb,0x9e,0x2f,0xd8,0x77,0xb5,0xb7,0xaa,0x6f,0x1c,0xa8,0x8f, |
1326 | | 0xd9,0x0a,0xb6,0x5c,0x7e,0xf4,0x66,0xe8,0xf2,0xf5,0xb7,0xa5,0xa6,0xfa,0x78,0x02, |
1327 | | 0x03,0x53,0xfd,0x7e,0xe3,0x40,0x7d,0xf6,0xf8,0xcd,0xf5,0x17,0xf9,0xf4,0x1b,0x7f, |
1328 | | 0xae,0x6f,0xb2,0xbf,0xdf,0xf8,0xaf,0xf4,0x4d,0xf6,0xe3,0xb9,0x8e,0xda,0x03,0xfd, |
1329 | | 0x67,0xdf,0x57,0x0e,0xf4,0x9f,0xd5,0xff,0xd5,0xfe,0x5f,0xb7,0xfe,0xe7,0xfe,0xfb, |
1330 | | 0xf7,0xea,0xf3,0x23,0x87,0x44,0xda,0x45,0x0e,0x8d,0x94,0x44,0x3a,0x45,0xba,0x44, |
1331 | | 0xba,0x46,0xca,0x22,0x3d,0x22,0x6f,0x9c,0x9f,0xdf,0xf3,0x77,0x3e,0x8a,0x48,0x6b, |
1332 | | 0x3c,0x21,0x4a,0x65,0x7e,0x91,0xbf,0x6f,0xcd,0x14,0x18,0xb9,0x44,0xa6,0x8d,0x0c, |
1333 | | 0x8d,0x0c,0x8f,0x8c,0x8e,0xfc,0x5d,0x7f,0x9b,0x12,0x19,0x1f,0x79,0x47,0xe4,0x9f, |
1334 | | 0xb3,0x92,0xb8,0x3b,0xf2,0xaf,0x5d,0x85,0xdc,0x1b,0x39,0x36,0x72,0x9a,0xcb,0x2f, |
1335 | | 0x1f,0x1f,0x22,0x7e,0x22,0x72,0x7c,0xe4,0xc4,0x48,0x2f,0xd1,0x94,0xc8,0xe9,0x91, |
1336 | | 0xee,0x4e,0xb3,0x23,0xe7,0x45,0x2e,0x88,0x2c,0xf1,0x7a,0x39,0xf2,0xb5,0xc8,0xc4, |
1337 | | 0xc8,0xd4,0xc8,0xa5,0x91,0x99,0x91,0xd9,0xe2,0x55,0x91,0xeb,0x22,0xb3,0x23,0xf3, |
1338 | | 0x23,0x37,0x47,0x6e,0x8b,0xb4,0x17,0x91,0xd3,0xce,0xc8,0x02,0xa9,0xad,0x53,0x91, |
1339 | | 0x74,0x77,0xe4,0xcb,0x92,0x8a,0xc8,0xfd,0x91,0xb5,0x91,0x8d,0x91,0xaf,0x47,0x8e, |
1340 | | 0x93,0x6a,0xc4,0x87,0x22,0x8f,0x44,0x1e,0x8b,0x3c,0x11,0x39,0xd0,0xfe,0xe9,0xc8, |
1341 | | 0xb3,0x91,0x17,0x23,0xbf,0x8c,0xec,0x8f,0x14,0x44,0x89,0xa3,0x5c,0xa3,0xbc,0xa2, |
1342 | | 0x7e,0xac,0x1f,0x18,0x15,0x1c,0xf5,0x5b,0xd7,0xcf,0x7f,0xf5,0xfa,0xfb,0xf7,0x7c, |
1343 | | 0x6e,0x7d,0xcf,0xbf,0xa1,0x1f,0x16,0x15,0x15,0x65,0x88,0xba,0x2d,0xea,0xee,0x28, |
1344 | | 0x99,0xea,0xbe,0xa8,0x07,0xa2,0x1e,0x8e,0x7a,0x3c,0x4a,0xae,0x7a,0x32,0x6a,0x42, |
1345 | | 0xd4,0x33,0x51,0x4a,0xd5,0xf4,0xa8,0xd9,0x51,0xf3,0xa2,0x16,0x44,0xbd,0x12,0x95, |
1346 | | 0x10,0x95,0x18,0x99,0x14,0x95,0x1e,0xb5,0x2c,0x6a,0x45,0xd4,0x9a,0x28,0x2b,0xf5, |
1347 | | 0x86,0xa8,0xd1,0xa2,0xbc,0xa8,0xc2,0xa8,0xad,0x51,0x3b,0xa2,0x8e,0x44,0x96,0x46, |
1348 | | 0x95,0x47,0x49,0xd5,0xec,0x6f,0x79,0xb8,0xaa,0xf7,0x45,0xd5,0x44,0x8d,0x55,0x34, |
1349 | | 0x44,0x69,0x55,0xff,0x8c,0x3a,0x18,0xd5,0x16,0xf5,0x26,0x17,0x3a,0xa2,0x4e,0x47, |
1350 | | 0xbd,0x1b,0xf5,0x61,0xd4,0xf9,0xa8,0x9e,0xa8,0x4b,0x51,0x97,0xa3,0xae,0x44,0x5d, |
1351 | | 0x8d,0xba,0x16,0x65,0x8c,0xe2,0x45,0xf3,0xa3,0x6d,0xa2,0x85,0xd1,0x92,0x68,0x67, |
1352 | | 0x04,0x4f,0xf5,0xf0,0x68,0x59,0xb4,0x3c,0x5a,0x19,0x1d,0xa9,0xf2,0x89,0x0e,0x88, |
1353 | | 0xd6,0x46,0xe7,0x28,0x75,0xd1,0x91,0xd1,0xfa,0xe8,0xf8,0xe8,0x3b,0xa3,0x47,0x45, |
1354 | | 0x8f,0x89,0x1e,0x1b,0xfd,0x68,0xf4,0x3f,0xa2,0x9f,0x8e,0x9e,0x1c,0x3d,0x25,0xf2, |
1355 | | 0xd9,0xe8,0x99,0xd1,0x73,0xa3,0x5f,0x88,0x7e,0x39,0xfa,0xb5,0xe8,0xc4,0xe8,0xd4, |
1356 | | 0xe8,0xa5,0xd1,0x99,0xd1,0xab,0xa2,0xd7,0x45,0x67,0x23,0xe4,0x47,0x17,0x45,0x17, |
1357 | | 0x47,0xc7,0x2b,0x4a,0xa2,0xcb,0xa2,0xf7,0x46,0x57,0x47,0xd7,0x47,0xef,0x17,0x35, |
1358 | | 0x47,0x1f,0x88,0x6e,0x14,0x1d,0x8e,0x3e,0x1a,0x7d,0x3c,0xfa,0x54,0xf4,0x3b,0xd1, |
1359 | | 0x1f,0x46,0x9f,0x8f,0xee,0x8e,0xbe,0x18,0xfd,0x69,0xf4,0x17,0xd1,0x5f,0x47,0x7f, |
1360 | | 0x17,0xdd,0x1f,0x6d,0x19,0x33,0x28,0x66,0x48,0x8c,0x30,0x46,0x12,0xe3,0x1c,0x33, |
1361 | | 0x3c,0x66,0xbe,0xa7,0x2c,0xa6,0x5b,0xe4,0x19,0xe3,0x19,0xa3,0x8e,0xf1,0x43,0x08, |
1362 | | 0x8a,0x09,0x89,0x89,0x88,0xd1,0xc7,0xc4,0xc7,0xdc,0x19,0x33,0x2a,0x66,0x4c,0xcc, |
1363 | | 0xd8,0x98,0x47,0x63,0xc6,0xc5,0x3c,0x15,0x33,0x29,0x66,0x8c,0x6a,0x6a,0xcc,0xcc, |
1364 | | 0x98,0xb9,0x31,0xcf,0xc7,0x3c,0xa4,0x7e,0x3e,0xe6,0xc5,0x98,0x47,0x55,0x8b,0x62, |
1365 | | 0x98,0x98,0xe4,0x98,0xf4,0x98,0x71,0x2a,0xbe,0xe7,0xb2,0x98,0x15,0x31,0x6b,0x62, |
1366 | | 0x36,0xc4,0xe4,0xc6,0x6c,0x8a,0xd9,0x12,0xb3,0x23,0xa6,0x34,0xa6,0x3c,0x66,0x5f, |
1367 | | 0x4c,0x4d,0x4c,0x43,0xcc,0xeb,0x31,0x87,0x62,0x8e,0xc4,0x1c,0x8b,0x39,0x11,0x73, |
1368 | | 0x3a,0xe6,0xdd,0x98,0x0f,0x63,0xce,0xc7,0x3c,0xa5,0xea,0x8e,0xb9,0x18,0x73,0x39, |
1369 | | 0xe6,0x4a,0xcc,0xd5,0x98,0x6b,0x31,0x53,0x55,0xc6,0x18,0x9e,0x9e,0xaf,0xb7,0xd1, |
1370 | | 0x0b,0xf5,0x12,0xbd,0xb3,0x7e,0xb8,0x9e,0xfd,0x5d,0x14,0x99,0x5e,0xae,0x57,0xea, |
1371 | | 0x7d,0xf4,0x81,0xfa,0x60,0x7d,0x98,0x3e,0x4a,0x3f,0x43,0x65,0xd0,0xdf,0xae,0xbf, |
1372 | | 0x5b,0x7f,0x9f,0x5e,0xe6,0xfd,0x80,0xfe,0x61,0xfd,0xe3,0xfa,0x27,0xf5,0x13,0xf4, |
1373 | | 0x53,0xf4,0xd3,0xf5,0xb3,0xf5,0xf3,0xf4,0x0b,0xf5,0xaf,0xe8,0x13,0xf4,0x49,0xfa, |
1374 | | 0x34,0x45,0x9a,0x3e,0x43,0xbf,0x42,0xbf,0x56,0x9f,0xad,0xcf,0xd7,0x17,0xe9,0x8b, |
1375 | | 0xf5,0x25,0xfa,0x32,0x7d,0xa5,0x7e,0x8e,0xaa,0xd3,0xab,0x4a,0x5f,0xa7,0x6f,0xd2, |
1376 | | 0xb7,0xe8,0x0f,0xeb,0x8f,0xea,0x8f,0xeb,0x4f,0xea,0x19,0xf5,0xdb,0xfa,0xf7,0xf5, |
1377 | | 0xe7,0xf4,0x5d,0xfa,0x3e,0xfd,0xa7,0xfa,0x2b,0xfa,0xab,0xfa,0x64,0xf5,0x35,0xbd, |
1378 | | 0x51,0xcf,0x33,0xf0,0x0d,0x36,0x06,0xa1,0x41,0x62,0x90,0x1a,0x5c,0x0d,0x23,0x0d, |
1379 | | 0x0a,0x83,0xb7,0x61,0x99,0xda,0xdf,0xa0,0x31,0xe8,0x0c,0x91,0x06,0xbd,0xe1,0x36, |
1380 | | 0xc3,0xdd,0x86,0xfb,0x0c,0x0f,0x18,0x1e,0x36,0x3c,0x8e,0xf0,0xa4,0x61,0x82,0x61, |
1381 | | 0x8d,0xfa,0x19,0xc3,0x34,0xc3,0x2c,0xc3,0x73,0x86,0x17,0x0c,0x2f,0x1b,0x5e,0x33, |
1382 | | 0x8c,0x51,0x24,0x19,0xd2,0x0d,0xcb,0x0c,0x2b,0x0d,0xeb,0x0c,0x39,0x86,0x02,0xc3, |
1383 | | 0x2e,0x75,0x91,0x61,0xbb,0xa1,0xd4,0x50,0x61,0xa8,0x32,0xd4,0x21,0xec,0x51,0x2b, |
1384 | | 0xbd,0x9b,0x0c,0x2d,0x86,0x56,0xc3,0x1b,0x86,0xe3,0x86,0x3a,0xcf,0x6a,0xf5,0x49, |
1385 | | 0xc3,0xdb,0x86,0xf5,0xaa,0x0f,0x0c,0xe7,0x0d,0x97,0x94,0x3d,0x86,0x4b,0x86,0x22, |
1386 | | 0xd5,0x65,0xc3,0x15,0xc3,0x55,0xc3,0xf7,0x08,0x16,0xb1,0xd6,0xb1,0x83,0x63,0xed, |
1387 | | 0x63,0xc5,0xb1,0x4e,0xb1,0xc3,0x62,0x65,0xb1,0xf2,0x58,0x65,0xac,0x4f,0x6c,0x40, |
1388 | | 0xac,0x36,0x36,0x2c,0x36,0x2a,0xd6,0x10,0x7b,0x5b,0xec,0x5d,0xb1,0xf7,0xc6,0xde, |
1389 | | 0x1f,0xfb,0x70,0xec,0x13,0xb1,0xe3,0x63,0x27,0xc5,0x4e,0x8d,0x9d,0x19,0x3b,0x37, |
1390 | | 0xb6,0x4e,0xf5,0x7c,0xec,0x4b,0xb1,0xaf,0xc5,0x26,0xc6,0xa6,0xc5,0x66,0xc4,0xae, |
1391 | | 0x88,0x5d,0x13,0xbb,0x21,0x36,0x37,0x76,0x53,0xec,0x96,0xd8,0xed,0xb1,0xa5,0xb1, |
1392 | | 0x15,0xb1,0x55,0xb1,0xea,0x98,0xfa,0xd8,0xe6,0xd8,0x03,0xb1,0x87,0x63,0x8f,0xc6, |
1393 | | 0x1e,0x8f,0x3d,0x19,0xfb,0x76,0xec,0xfb,0xb1,0x67,0x63,0x3f,0x8a,0xed,0x8d,0x5d, |
1394 | | 0xad,0xf8,0x24,0xf6,0xf3,0xd8,0xaf,0x62,0xbf,0x8d,0xfd,0x21,0xd6,0x22,0xae,0x55, |
1395 | | 0x65,0x1d,0x37,0x38,0xce,0x2e,0x4e,0x14,0xe7,0x18,0x37,0x2c,0x4e,0x16,0xe7,0x19, |
1396 | | 0xa7,0x8a,0xf3,0x8d,0x0b,0x8c,0x0b,0x8e,0x0b,0x8f,0x8b,0x8e,0x8b,0x8b,0xbb,0x23, |
1397 | | 0xee,0x9e,0xb8,0x31,0x71,0x0f,0xc5,0x3d,0x16,0x57,0xec,0xf9,0x8f,0xb8,0xa7,0xe3, |
1398 | | 0x26,0xc7,0x3d,0x1b,0x37,0x33,0x6e,0x6e,0xdc,0x49,0xf5,0xf3,0x71,0x2f,0xc6,0x2d, |
1399 | | 0x8a,0x63,0xe2,0x92,0xe3,0xd2,0xe3,0x96,0xc5,0xad,0x88,0x1b,0x2d,0x59,0x13,0xb7, |
1400 | | 0x31,0x2e,0x2f,0xae,0x30,0x6e,0x6b,0xdc,0x8e,0xb8,0xd2,0xb8,0x8a,0xb8,0xaa,0xb8, |
1401 | | 0xba,0xb8,0xa6,0xb8,0x5e,0xf5,0xc7,0xea,0xe9,0x92,0x96,0xb8,0xc3,0x71,0x47,0xe3, |
1402 | | 0x8e,0xc7,0x9d,0x8c,0x7b,0x3b,0xee,0x83,0xb8,0xf3,0x71,0xdd,0x71,0x17,0xe3,0x3e, |
1403 | | 0x8d,0xbb,0x12,0xf7,0x99,0xfa,0x6a,0xdc,0xf7,0x71,0x16,0xf1,0xd6,0xf1,0x83,0xe3, |
1404 | | 0xed,0xe2,0xc5,0xf1,0x4e,0xf1,0xc3,0xe2,0xdd,0xe2,0x3d,0xe2,0xbd,0xe2,0xbd,0xe3, |
1405 | | 0xfd,0xe3,0xb5,0xf1,0xba,0xf8,0xc8,0x78,0x7d,0xfc,0x6d,0xf1,0x77,0xc5,0xdf,0x1b, |
1406 | | 0x7f,0x7f,0xfc,0x43,0xf1,0x8f,0xc7,0x8f,0x8f,0x9f,0x18,0x3f,0x25,0x7e,0x7a,0xfc, |
1407 | | 0x9c,0xf8,0xf9,0xf1,0x02,0x6f,0x81,0xf7,0x8b,0xf1,0x8b,0xe2,0x17,0xc7,0xa7,0xc4, |
1408 | | 0x2f,0x89,0x5f,0x1e,0xbf,0x32,0x7e,0x6d,0xfc,0xc6,0xf8,0xbc,0x78,0x5b,0xef,0xcd, |
1409 | | 0xf1,0xdb,0xe2,0x77,0xc6,0xef,0x8e,0xaf,0x88,0xdf,0x1f,0x5f,0x17,0xdf,0x14,0x7f, |
1410 | | 0x20,0xbe,0x2d,0xde,0xdb,0xe1,0x58,0x7c,0x84,0xc3,0x89,0xf8,0xd3,0xf1,0xef,0xc6, |
1411 | | 0x7f,0x18,0x3f,0xda,0xe1,0x7c,0xfc,0x9f,0xf1,0xfb,0x47,0x3f,0x7a,0x1b,0xc7,0xe6, |
1412 | | 0xd2,0x64,0xd4,0x6c,0x34,0x5e,0x36,0xef,0x39,0xc3,0xc5,0x7a,0xf3,0x56,0xcf,0xcd, |
1413 | | 0x77,0x36,0x1e,0xfd,0x68,0xaf,0xde,0x98,0x80,0x78,0x8c,0x91,0xfb,0xbf,0x42,0xcc, |
1414 | | 0xf5,0x52,0xd7,0xd8,0xff,0x20,0x50,0xf0,0xad,0xd1,0xf8,0xc3,0xc1,0x2b,0x9f,0x36, |
1415 | | 0x61,0xeb,0x87,0x4f,0xae,0x34,0x45,0x5a,0x50,0xbb,0x91,0xd7,0xff,0x29,0xb7,0xff, |
1416 | | 0x93,0x2b,0x1f,0xb7,0x46,0x9f,0x96,0xb6,0x1a,0x5b,0x5a,0xa3,0x17,0xb3,0xda,0x7c, |
1417 | | 0xe3,0x99,0x1f,0xb0,0xdf,0x78,0xe5,0x4c,0xf4,0xd3,0xba,0x76,0xb6,0x2d,0x6e,0xfb, |
1418 | | 0x32,0xbb,0x3d,0xb7,0xdd,0x68,0x4f,0xdc,0x36,0x6b,0xdc,0x0f,0x9f,0x19,0xdb,0x91, |
1419 | | 0x7e,0x6a,0x4c,0xf8,0x1e,0x4a,0x01,0x09,0xc9,0x4f,0x19,0x9b,0x8d,0xae,0xac,0x5d, |
1420 | | 0x42,0xae,0x5f,0x67,0x8c,0x7c,0x2e,0x8d,0x4e,0x88,0xe6,0x2a,0x70,0x31,0xbb,0x91, |
1421 | | 0x60,0xb6,0x2e,0xda,0x78,0x53,0x1f,0x64,0x6c,0xa7,0xcc,0x33,0x69,0xd9,0xcd,0xaf, |
1422 | | 0x5d,0xd1,0x39,0x18,0x91,0x40,0x6c,0xb3,0xc6,0x33,0xec,0xff,0x85,0x41,0x6f,0x79, |
1423 | | 0xa6,0xb2,0xc6,0xeb,0xff,0x47,0x49,0xcf,0xee,0x4f,0x30,0x0a,0x8d,0xc2,0xcf,0xb9, |
1424 | | 0x4d,0x99,0xc9,0x3f,0x42,0xae,0xd5,0x56,0x73,0xa1,0x76,0x73,0xca,0x1a,0x50,0xc0, |
1425 | | 0xb5,0xa1,0x37,0x7b,0x4f,0xc8,0xd9,0x7b,0xd3,0x47,0xf8,0x99,0x39,0xf3,0x8d,0xf1, |
1426 | | 0xc2,0x4d,0xe7,0x07,0x8a,0x26,0xcf,0x9b,0xfe,0xcb,0x34,0x4e,0x03,0xdd,0xdc,0x74, |
1427 | | 0x93,0x3b,0xd7,0x3c,0x25,0x98,0x3f,0xd7,0x8d,0xe3,0xde,0x51,0xdf,0xf8,0x70,0xd6, |
1428 | | 0x9a,0x7b,0x99,0x70,0xf3,0xfb,0x58,0xe1,0xf5,0xf1,0x60,0x4a,0x65,0x46,0x9e,0xbe, |
1429 | | 0xd9,0xdc,0x57,0xa3,0x90,0xe1,0xf6,0x34,0x19,0x5b,0xcc,0x7d,0x30,0xd5,0xd6,0x1b, |
1430 | | 0xaf,0x98,0xfe,0x83,0x00,0x7d,0xc3,0x6e,0xbf,0xf6,0xda,0x6b,0x74,0x43,0xd9,0x54, |
1431 | | 0x57,0xc8,0xfe,0xa7,0xe5,0x6f,0x06,0x14,0xcc,0x6f,0x81,0x2f,0x73,0x8d,0x54,0xa1, |
1432 | | 0x8c,0xfe,0xa6,0x71,0xc8,0x4f,0xe3,0x92,0x2c,0xf6,0xa0,0xcc,0xe2,0xc6,0xfb,0x62, |
1433 | | 0xfd,0x0d,0x8b,0xb9,0xbe,0x73,0x7f,0x01,0x2c,0x3c,0x7b,0xfd,0x1c,0xb0,0x71,0x93, |
1434 | | 0xc9,0xe5,0xfa,0x1b,0xb5,0xe8,0x46,0xc7,0xb8,0x5e,0x63,0xbf,0x9e,0x1b,0x3e,0x4d, |
1435 | | 0x2b,0xcd,0xc5,0xb9,0x4e,0x30,0xc6,0x81,0x37,0xd3,0xba,0x6f,0x4c,0xe2,0xc6,0x24, |
1436 | | 0x93,0x77,0xaf,0xdb,0x85,0xf3,0xf1,0x3d,0x97,0x99,0xf3,0xd9,0x65,0xb8,0x52,0x9f, |
1437 | | 0x86,0x91,0x61,0x71,0xf3,0x1b,0x6e,0xae,0xa1,0x6f,0x06,0xbc,0xa9,0xef,0x37,0x99, |
1438 | | 0xcc,0x9a,0xc5,0x73,0xa3,0x7e,0x1c,0xb7,0xb8,0xf9,0xed,0x37,0xff,0x7b,0xb3,0x7d, |
1439 | | 0xf0,0xef,0x8f,0xde,0x8c,0x9b,0x3c,0x17,0xc9,0xa3,0xef,0x4d,0x35,0xbe,0xbf,0x7e, |
1440 | | 0x96,0x07,0xac,0xe1,0xce,0x11,0xeb,0x77,0xf6,0x90,0x7e,0xe0,0x62,0x3b,0xc3,0x27, |
1441 | | 0x6e,0xb4,0xf2,0xae,0x5f,0xba,0x74,0xe3,0xec,0xb2,0xef,0x37,0x4d,0x57,0xa3,0xb9, |
1442 | | 0x19,0x7c,0x12,0x1a,0xe0,0x80,0x81,0xff,0x47,0xc4,0x37,0xf2,0x4c,0xd7,0xe9,0x27, |
1443 | | 0xd7,0x0a,0xc2,0x17,0x9f,0x6d,0x97,0xa1,0xfc,0x28,0xce,0x4f,0xc6,0xad,0x57,0x9b, |
1444 | | 0x2c,0x06,0x99,0x94,0x2f,0xb3,0x75,0x59,0x9b,0x6f,0xf4,0x43,0xcf,0xb6,0xcc,0x43, |
1445 | | 0x34,0xe0,0x27,0xee,0xca,0x10,0x9a,0x8e,0xf7,0xb0,0x67,0x29,0xe1,0xc7,0x6f,0xfd, |
1446 | | 0xcd,0x7f,0xb9,0xcd,0x67,0x12,0xbe,0x98,0xc3,0xb6,0xff,0x6d,0x02,0x5d,0x37,0x89, |
1447 | | 0xcc,0x2e,0xfe,0x5e,0x66,0xd2,0x31,0xde,0xf8,0xef,0x14,0x37,0x19,0xce,0x1d,0x33, |
1448 | | 0xb5,0xc7,0x63,0xb5,0x7f,0x30,0x5d,0x52,0x37,0xc6,0x34,0x1a,0xe9,0xc7,0x35,0xc0, |
1449 | | 0x75,0x37,0x61,0x2f,0x6b,0x6f,0x13,0x5b,0x26,0xe1,0xda,0x80,0x77,0x84,0x03,0x6d, |
1450 | | 0x99,0xae,0x6f,0xae,0x81,0x56,0xd3,0x10,0x1e,0xf8,0x98,0xaf,0x2f,0x23,0xcf,0xe4, |
1451 | | 0xdf,0x04,0x19,0x09,0x6f,0xf9,0xfd,0x05,0x9f,0x06,0x46,0x80,0xf9,0xaa,0x32,0x19, |
1452 | | 0xd3,0x72,0xbd,0x40,0x02,0xa7,0xa9,0xd7,0x63,0x1e,0x68,0xbc,0x06,0x93,0xce,0x1a, |
1453 | | 0xaf,0x8f,0x35,0x53,0x8b,0xc6,0x34,0x73,0x49,0xe6,0xc6,0x37,0x25,0x32,0x4a,0x20, |
1454 | | 0xf3,0x65,0xcb,0x18,0x6f,0xb8,0x10,0x9f,0xcb,0x73,0x4c,0xaa,0x56,0xc8,0x2b,0xe9, |
1455 | | 0xb3,0xeb,0x57,0xcd,0xc0,0xb5,0x21,0xfc,0xde,0x74,0x7d,0x58,0xd0,0xcd,0xf7,0xee, |
1456 | | 0x84,0x7e,0x73,0x6b,0x66,0x5d,0xf3,0x15,0x69,0xea,0xbf,0x90,0xbe,0xe9,0x37,0xfd, |
1457 | | 0xaf,0xe7,0x84,0xb3,0xac,0x07,0x98,0x9b,0x7a,0x29,0x43,0x0b,0x2d,0x37,0x8f,0xce, |
1458 | | 0xeb,0xbd,0x4f,0xa2,0x1f,0xdf,0x81,0xd2,0x4c,0x63,0xd7,0x34,0x9a,0x13,0xe6,0x18, |
1459 | | 0x13,0x0a,0xcc,0x66,0xc3,0xdb,0x2d,0x37,0xff,0x9f,0x16,0xd3,0x47,0x36,0x90,0x33, |
1460 | | 0x9b,0xc5,0x33,0xd9,0x94,0x30,0x30,0x2f,0x37,0xed,0x6e,0x36,0x95,0xf9,0x1c,0x76, |
1461 | | 0x98,0xee,0xcf,0x42,0x0b,0x1a,0x18,0x41,0xec,0x79,0xbd,0x7e,0x8d,0xe3,0x0e,0xca, |
1462 | | 0x33,0x5f,0x61,0xdc,0x1e,0x0c,0xcb,0x81,0xbb,0x6e,0xc2,0x39,0xdc,0x6b,0xd9,0xab, |
1463 | | 0xd5,0x78,0xf5,0xfa,0xed,0xef,0xc6,0x77,0x6a,0x37,0xee,0xe1,0x34,0x81,0x26,0xd2, |
1464 | | 0x24,0x9a,0x4c,0xcf,0xd0,0x14,0x9a,0x4a,0xcf,0xd2,0x34,0x9a,0x4e,0x33,0x68,0x26, |
1465 | | 0xcd,0xa2,0xd9,0x34,0x87,0xe6,0xd2,0x73,0x34,0x8f,0xe6,0xd3,0xf3,0xf4,0x02,0x2d, |
1466 | | 0xa0,0x85,0xf4,0x22,0xbd,0x44,0x2f,0x93,0x3b,0xb9,0x1f,0x4d,0x07,0xc9,0xa4,0xc1, |
1467 | | 0xd2,0xd1,0xfd,0xe8,0x62,0x3a,0x56,0x8f,0xa4,0x18,0x2b,0xc9,0xa0,0xf3,0x8b,0x93, |
1468 | | 0x83,0xb9,0x18,0x87,0xb8,0x7c,0xcb,0x26,0x6a,0x29,0xa4,0x96,0xcd,0xd4,0x52,0x44, |
1469 | | 0x2d,0x5b,0xa8,0x65,0x2b,0xb5,0x6c,0xa3,0x96,0x62,0x6a,0xd9,0x4e,0x2d,0x3b,0xa8, |
1470 | | 0x65,0x27,0xb5,0x94,0x50,0xcb,0x2e,0x6a,0x29,0xa5,0x96,0xdd,0xd4,0x52,0x46,0x2d, |
1471 | | 0x7b,0xa8,0xa5,0x9c,0x5a,0x2a,0xa8,0xa5,0x92,0x5a,0xf6,0x52,0xcb,0x3e,0x6a,0xd9, |
1472 | | 0x4f,0x2d,0xd5,0xd4,0x52,0x43,0x2d,0xb5,0xd4,0x52,0x47,0x2d,0xf5,0xd4,0xd2,0x40, |
1473 | | 0x2d,0x8d,0x74,0x60,0x31,0x1d,0x48,0xa2,0x03,0x29,0x74,0x20,0x8d,0x0e,0x2c,0xa1, |
1474 | | 0x03,0x19,0x74,0x60,0x39,0x1d,0xc8,0xa2,0x03,0x2b,0xe9,0xc0,0x6a,0x3a,0xb0,0x96, |
1475 | | 0x0e,0xac,0xa7,0x03,0x1b,0xe9,0x40,0x0e,0x1d,0xc8,0xa3,0x03,0x05,0x74,0xa0,0x90, |
1476 | | 0x0e,0x14,0xd1,0x81,0xad,0x74,0xa0,0x98,0x0e,0xec,0xa0,0x03,0x25,0x74,0xa0,0x94, |
1477 | | 0x0e,0x94,0xd1,0xb4,0xa3,0x69,0x34,0x6d,0x3a,0x1d,0xd8,0x47,0x07,0xaa,0xe8,0x40, |
1478 | | 0x2d,0x1d,0xa8,0xa7,0x03,0x8d,0x34,0xf3,0xf5,0x2a,0x3a,0x98,0x48,0x07,0x93,0xe9, |
1479 | | 0x60,0x2a,0x1d,0x4c,0xa7,0x23,0xf5,0xb3,0xe9,0x60,0x06,0x1d,0x5c,0x4e,0x07,0xb3, |
1480 | | 0xe8,0xe0,0x4a,0x3a,0xb8,0x9a,0x0e,0xae,0xa5,0x83,0xeb,0xe9,0xe0,0x46,0x3a,0x98, |
1481 | | 0x43,0x07,0xf3,0xe8,0x60,0x01,0x1d,0x2c,0xa4,0x83,0x45,0x74,0x70,0x2b,0x1d,0x2c, |
1482 | | 0xa6,0x83,0x3b,0xe8,0x60,0x09,0x1d,0x2c,0xa5,0x83,0x65,0x74,0xb0,0x9c,0x0e,0x56, |
1483 | | 0xd2,0xc1,0x7d,0x74,0xb0,0x8a,0x5a,0x9a,0xe8,0x60,0x2d,0x1d,0xac,0xa7,0x83,0x8d, |
1484 | | 0xd4,0xb6,0x9a,0x0e,0x25,0xd1,0xa1,0x14,0x6a,0x5b,0x43,0x87,0xd2,0xa9,0x6d,0x1d, |
1485 | | 0xb5,0xad,0xa7,0x43,0xcb,0xa8,0x35,0x8f,0xda,0x36,0x52,0x5b,0x0e,0x1d,0x5a,0x45, |
1486 | | 0x6d,0x9b,0xa8,0xad,0x88,0xda,0x76,0x50,0xdb,0x76,0x3a,0x84,0x9d,0x65,0xd4,0x56, |
1487 | | 0x41,0x6d,0xfb,0xe8,0x50,0x21,0x1d,0x2a,0xa2,0x43,0x5b,0xe9,0x08,0x43,0x87,0xb6, |
1488 | | 0xd3,0x11,0xb4,0x53,0x4a,0x47,0xd2,0xe9,0xd0,0x1e,0x3a,0xb2,0x94,0x8e,0x64,0xd0, |
1489 | | 0xa1,0xbd,0x74,0x68,0x3f,0x1d,0x59,0x45,0x87,0x6a,0xe8,0x50,0x03,0x4d,0x86,0xde, |
1490 | | 0xcc,0xe9,0x34,0x7b,0x3a,0xb5,0x66,0x52,0xeb,0x0a,0x6a,0x5d,0x45,0xad,0x6b,0xa8, |
1491 | | 0x75,0x1d,0xb5,0x6e,0xa0,0xd6,0x6c,0x6a,0xcd,0xa5,0xd6,0x02,0x6a,0x2d,0xa4,0xd6, |
1492 | | 0x22,0x6a,0xdd,0x4a,0xad,0xc5,0xd4,0xba,0x83,0x5a,0x4b,0xa8,0xb5,0x94,0x5a,0xcb, |
1493 | | 0x68,0xf2,0xcb,0xd4,0x0a,0xc9,0xb5,0x74,0xa8,0x89,0x5a,0x6b,0xa8,0xb5,0x8e,0x5a, |
1494 | | 0x1b,0xa8,0xb5,0x89,0x0e,0x2f,0xa6,0xc3,0x49,0x74,0x38,0x85,0x0e,0xa7,0xd1,0xe1, |
1495 | | 0x25,0x74,0x38,0x83,0x0e,0x2f,0xa7,0xc3,0x59,0x74,0x78,0x25,0x1d,0x5e,0x4d,0x87, |
1496 | | 0xd7,0xd2,0xe1,0xf5,0x74,0x78,0x23,0x1d,0xce,0xa1,0xc3,0x79,0x74,0xb8,0x80,0x0e, |
1497 | | 0xe5,0xd3,0xe1,0x22,0x3a,0xbc,0x95,0x0e,0x17,0xd3,0xe1,0x1d,0x74,0xb8,0x84,0x0e, |
1498 | | 0x97,0xd2,0xe1,0x32,0x3a,0x5c,0x4e,0x87,0x2b,0xe9,0x7c,0x39,0x0e,0xd4,0xd3,0xa1, |
1499 | | 0x6c,0xe4,0xb6,0x51,0x5b,0x22,0x1d,0x62,0xe8,0xc8,0x12,0x3a,0xb2,0x8c,0xda,0xd2, |
1500 | | 0xa8,0x6d,0x09,0xb5,0x65,0x50,0xdb,0x72,0x6a,0xcb,0xa2,0x36,0x1c,0xad,0xa1,0xb6, |
1501 | | 0x3a,0x3a,0xb2,0x18,0x03,0x2f,0x15,0xa4,0x81,0xa5,0x60,0x3b,0x48,0x02,0x19,0x74, |
1502 | | 0x64,0x2d,0x1d,0x65,0x08,0x83,0xf3,0xe8,0x6a,0x3a,0x9a,0xce,0x0e,0xd2,0x1a,0x7a, |
1503 | | 0xb3,0x9c,0xde,0xac,0xa4,0x23,0xc8,0x54,0x91,0x3b,0xb6,0x23,0xa9,0xbd,0x92,0x1d, |
1504 | | 0xcc,0xec,0xd1,0x5d,0x84,0x33,0x7e,0xac,0x94,0x8e,0xed,0xa6,0x63,0x65,0xd4,0xbe, |
1505 | | 0x8c,0xda,0x97,0x53,0x7b,0x26,0x1d,0x2b,0xa7,0x63,0x15,0x74,0xac,0x92,0x8e,0xed, |
1506 | | 0xa5,0x63,0xfb,0xe8,0xd8,0x7e,0x3a,0x86,0x62,0xd5,0x74,0xac,0x96,0x8e,0xd5,0xd1, |
1507 | | 0xb1,0x06,0x3a,0xd6,0x48,0xc7,0x9a,0xa8,0x9d,0xa1,0xf6,0xc5,0xd4,0x9e,0x44,0xed, |
1508 | | 0xc9,0xd4,0x9e,0x42,0xed,0xa9,0xd4,0x9e,0x46,0xed,0xe9,0xd4,0xbe,0x84,0xda,0x97, |
1509 | | 0x52,0x7b,0x06,0xb5,0xaf,0xa7,0xf6,0x8d,0xd4,0x9e,0x43,0xed,0x79,0xd4,0x5e,0x40, |
1510 | | 0xed,0x85,0xd4,0x5e,0x44,0xed,0x5b,0xa9,0xbd,0x98,0xda,0x77,0x50,0x7b,0x09,0xb5, |
1511 | | 0x97,0x52,0x3b,0x74,0xab,0xa9,0xbd,0x8e,0xde,0xc4,0x4f,0x3d,0xbd,0xd9,0x40,0x1d, |
1512 | | 0x2b,0xa8,0x63,0x25,0x75,0xac,0xa2,0x8e,0xd5,0xd4,0xb1,0x86,0x3a,0xd6,0x52,0xc7, |
1513 | | 0x3a,0xea,0x58,0x4f,0x1d,0x1b,0xa8,0x63,0x23,0x75,0x64,0x53,0x47,0x0e,0x75,0xe4, |
1514 | | 0x52,0x47,0x1e,0x75,0xe4,0x53,0x47,0x01,0x1d,0xdf,0x43,0xc7,0xcb,0xe9,0x78,0x05, |
1515 | | 0x1d,0xaf,0xa4,0xe3,0x7b,0xe9,0xf8,0x3e,0x3a,0xbe,0x9f,0x8e,0x57,0xd1,0xf1,0x6a, |
1516 | | 0x3a,0x5e,0x43,0xc7,0x6b,0xe9,0x78,0x1d,0x1d,0xaf,0xa7,0xe3,0x0d,0x74,0xbc,0x91, |
1517 | | 0x8e,0x37,0x51,0x07,0x43,0x1d,0x8b,0xa9,0x23,0x91,0x3a,0x92,0xa8,0x23,0x99,0x3a, |
1518 | | 0x52,0xa8,0x23,0x95,0x3a,0xd2,0xa8,0x23,0x9d,0x3a,0x96,0x50,0xc7,0x52,0xea,0xc8, |
1519 | | 0xa0,0x8e,0x65,0xd4,0xb1,0x9c,0x3a,0x32,0xa9,0x23,0x8b,0x3a,0x0a,0xa9,0xa3,0x88, |
1520 | | 0x3a,0xb6,0x52,0x47,0x31,0x75,0xec,0xa0,0x8e,0x12,0xea,0x28,0xa5,0x8e,0x32,0xea, |
1521 | | 0x28,0xa7,0x8e,0x4a,0xea,0xd8,0x47,0x1d,0x55,0xd4,0x51,0x43,0x1d,0x75,0xd4,0x01, |
1522 | | 0xe3,0x9b,0xe8,0xc4,0x62,0x3a,0x91,0x41,0x27,0x96,0xd3,0x89,0x2c,0x3a,0xb1,0x92, |
1523 | | 0x4e,0xac,0xa6,0x13,0x6b,0xe9,0xc4,0x7a,0x3a,0xb1,0x91,0x4e,0xe4,0xd0,0x89,0x3c, |
1524 | | 0x3a,0x51,0x40,0x27,0x0a,0xe9,0x44,0x11,0x9d,0xd8,0x4a,0x27,0x8a,0xe9,0xc4,0x0e, |
1525 | | 0x3a,0x51,0x42,0x27,0x4a,0xe9,0x44,0x19,0x9d,0x28,0xa7,0x13,0x95,0x74,0x62,0x1f, |
1526 | | 0x9d,0xa8,0xa2,0x13,0x35,0x74,0xa2,0x8e,0x4e,0x34,0xd0,0x89,0x26,0xea,0xcc,0xa2, |
1527 | | 0xce,0x44,0xea,0x4c,0xa6,0xce,0x54,0xea,0x4c,0xa7,0xce,0xa5,0xd4,0xb9,0x8c,0x3a, |
1528 | | 0x33,0xa9,0x73,0x25,0x75,0xae,0xa6,0xce,0xb5,0xd4,0xb9,0x9e,0x3a,0x37,0x52,0x67, |
1529 | | 0x0e,0x75,0xe6,0x51,0x67,0x01,0x75,0x16,0x52,0x67,0x11,0x75,0x6e,0xa5,0xce,0x62, |
1530 | | 0xea,0xdc,0x41,0x9d,0x25,0xd4,0x59,0x4a,0x9d,0x65,0xd4,0x59,0x4e,0x9d,0x95,0xd4, |
1531 | | 0xb9,0x8f,0x3a,0xab,0xa8,0xb3,0x86,0x3a,0xeb,0xa8,0xb3,0x81,0x3a,0x9b,0xe8,0xe4, |
1532 | | 0x62,0x3a,0x99,0x44,0x27,0x53,0xe8,0x64,0x1a,0x9d,0x5c,0x42,0x27,0x33,0xe8,0xe4, |
1533 | | 0x72,0x3a,0x99,0x45,0x27,0x57,0xd2,0xc9,0xd5,0x74,0x72,0x2d,0x9d,0x5c,0x4f,0x27, |
1534 | | 0x37,0xd2,0xc9,0x1c,0x3a,0x99,0x47,0x27,0x0b,0xe8,0x64,0x21,0x9d,0x2c,0xa2,0x93, |
1535 | | 0x5b,0xe9,0x64,0x31,0x9d,0xdc,0x41,0x27,0x4b,0xe8,0x64,0x29,0x9d,0x2c,0xa3,0x53, |
1536 | | 0x85,0x74,0x6a,0x33,0x9d,0x2a,0xa2,0x53,0x5b,0xe8,0xd4,0x56,0x3a,0xb5,0x8d,0x4e, |
1537 | | 0x15,0xd3,0xa9,0xed,0x74,0x6a,0x07,0x9d,0xda,0x49,0xa7,0x4a,0xe8,0xd4,0x2e,0x3a, |
1538 | | 0x55,0x4a,0xa7,0x76,0xd3,0x29,0x14,0xde,0x43,0xa7,0xca,0xe9,0x54,0x05,0x9d,0xaa, |
1539 | | 0xa4,0x53,0x7b,0xe9,0xd4,0x3e,0x3a,0xb5,0x9f,0x4e,0x55,0xd1,0xa9,0x6a,0x3a,0x55, |
1540 | | 0x43,0xa7,0x6a,0xe9,0x54,0x1d,0x9d,0xaa,0xa7,0x53,0x0d,0x74,0xaa,0x91,0x4e,0x35, |
1541 | | 0xd1,0x69,0x86,0x4e,0x2f,0xa6,0xd3,0x89,0x74,0x3a,0x89,0x4e,0x27,0xd3,0xe9,0x14, |
1542 | | 0x3a,0x9d,0x0a,0x15,0xec,0x78,0xbb,0xf8,0x9d,0xbd,0xf4,0x4e,0x3a,0xa2,0xf7,0xd2, |
1543 | | 0xd8,0xdc,0x52,0x44,0x67,0xb7,0xac,0x3d,0xbb,0xa5,0x1e,0xc9,0x3a,0x53,0xb2,0xde, |
1544 | | 0x94,0xe4,0x9a,0x92,0x42,0x53,0xb2,0xd9,0x94,0x94,0x98,0x92,0x32,0x2e,0xd9,0x56, |
1545 | | 0x78,0x76,0x1b,0x9b,0x6c,0x36,0x25,0x65,0x5c,0xb2,0xbd,0xe2,0xec,0x76,0x36,0xa9, |
1546 | | 0x36,0x25,0xeb,0x4c,0xc9,0x7a,0x53,0x92,0x6b,0x4a,0x4a,0xb8,0x64,0x57,0xe1,0xd9, |
1547 | | 0x5d,0x6c,0xb2,0x99,0x4b,0x6a,0x96,0x9f,0xad,0xae,0xa0,0xb3,0x75,0xcb,0xcf,0xd6, |
1548 | | 0x22,0xa9,0x2d,0x39,0x5b,0xbb,0xd1,0x94,0x14,0xd2,0xd9,0xfa,0x0c,0x3a,0xdb,0x90, |
1549 | | 0x78,0xb6,0xb1,0x0a,0xc9,0x32,0x53,0xb2,0xd2,0x94,0xac,0x33,0x25,0x39,0xa6,0x84, |
1550 | | 0x39,0xdb,0xb8,0x0f,0x49,0xf9,0xd9,0x86,0x0a,0x53,0x82,0xce,0x35,0x56,0x9c,0x6d, |
1551 | | 0x64,0xb8,0x04,0x3b,0xb8,0x5c,0xe5,0x40,0x62,0xde,0x31,0xb0,0x7f,0x15,0xd7,0x48, |
1552 | | 0x63,0xae,0x29,0x29,0x34,0x25,0xdb,0x4c,0x49,0x89,0x29,0x59,0xc1,0x0a,0x9c,0xdf, |
1553 | | 0xcb,0x80,0xc5,0x20,0x11,0x24,0x81,0x64,0x90,0x02,0x52,0x41,0x1a,0x48,0x07,0x4b, |
1554 | | 0xc0,0x52,0x90,0x01,0x96,0x81,0xe5,0x20,0x13,0x64,0x81,0x15,0x60,0x25,0x58,0x05, |
1555 | | 0x56,0x83,0x35,0x60,0x2d,0x58,0x07,0xd6,0x83,0x0d,0x60,0x23,0xc0,0xad,0x6e,0x6f, |
1556 | | 0x0e,0xc8,0x05,0x79,0x20,0x1f,0x14,0x80,0x4d,0xa0,0x10,0x6c,0x06,0x45,0x60,0x0b, |
1557 | | 0xd8,0x0a,0x8a,0x41,0x29,0x9d,0x4b,0xca,0xa5,0x73,0x59,0x7b,0x40,0x39,0xa8,0x00, |
1558 | | 0x95,0x60,0x2f,0xd8,0x47,0x17,0x37,0x66,0xd0,0xb9,0x8a,0xa5,0x28,0xb3,0x02,0xac, |
1559 | | 0x04,0xab,0xc0,0x6a,0xb0,0x06,0xac,0x05,0xeb,0xc0,0x7a,0xb0,0x01,0x6c,0x04,0xd9, |
1560 | | 0x20,0x07,0xe4,0x81,0x7c,0x50,0x00,0x36,0x81,0x42,0xb0,0x19,0x14,0x81,0x2d,0x60, |
1561 | | 0x2b,0xd8,0x06,0x8a,0xc1,0x76,0xb0,0x03,0xec,0x04,0x25,0x60,0x17,0x60,0xed,0xda, |
1562 | | 0x0d,0xca,0x00,0x6c,0x4b,0x82,0x6d,0x49,0xb0,0x2d,0x09,0xb6,0x25,0xc1,0xb6,0xa4, |
1563 | | 0x7d,0x60,0x3f,0xa8,0x02,0xd5,0xa0,0x06,0xd4,0x82,0x06,0xd0,0x08,0x9a,0xa8,0x6d, |
1564 | | 0x05,0xb5,0xc1,0x62,0x78,0xbd,0x0d,0x1d,0x84,0xb3,0xce,0xc1,0x59,0xe7,0xe0,0x98, |
1565 | | 0x73,0xe8,0x7c,0x1b,0x9e,0x85,0x6b,0xa9,0xad,0x80,0xda,0x0a,0xa9,0x0d,0x9b,0x90, |
1566 | | 0xde,0x87,0x27,0x00,0x1e,0x95,0x10,0xde,0x9f,0x42,0x47,0x70,0xa4,0x9c,0xda,0xf6, |
1567 | | 0x50,0x5b,0x25,0xb5,0xed,0xa5,0xb6,0x6a,0x3a,0x82,0x27,0x08,0x8c,0x83,0x73,0x8f, |
1568 | | 0xac,0xa0,0x23,0x68,0xb8,0x7a,0x31,0x48,0x02,0x29,0x20,0x0d,0x2c,0x01,0x70,0x57, |
1569 | | 0xf5,0x72,0x90,0x05,0xd8,0x32,0x70,0x55,0x35,0xdc,0x54,0x0d,0xe5,0x6a,0xb8,0xa7, |
1570 | | 0x1a,0xae,0xa9,0x86,0x05,0xd5,0x70,0x4b,0x35,0x5c,0x52,0x0d,0x77,0x54,0xc3,0x15, |
1571 | | 0xd5,0x70,0x43,0x35,0x5c,0x50,0x0d,0x85,0x6a,0x58,0x50,0x8d,0x6e,0x57,0xa3,0xcb, |
1572 | | 0xd5,0xe8,0x6e,0x35,0xba,0x5a,0x8d,0x6e,0x56,0xa3,0x8b,0xd5,0x75,0x00,0x5d,0xac, |
1573 | | 0x6e,0xa2,0x73,0x35,0xd0,0xaf,0x81,0x7e,0x0d,0xf4,0x6b,0xa0,0x5f,0x03,0xfd,0x1a, |
1574 | | 0xe8,0xd7,0x40,0xbf,0x06,0xfa,0x35,0xd0,0xaf,0x81,0x7e,0x0d,0xf4,0x6b,0xa0,0x5f, |
1575 | | 0x03,0xfd,0x1a,0xe8,0xd7,0x40,0xbf,0x06,0xfa,0x35,0xd0,0xaf,0x81,0x7e,0x0d,0xf4, |
1576 | | 0x6b,0xa0,0x5f,0x03,0xfd,0x1a,0xe8,0xd7,0x40,0xbf,0x06,0xfa,0x35,0xd0,0xaf,0x81, |
1577 | | 0x7e,0x0d,0xf4,0x6b,0xa0,0x5f,0x03,0xfd,0x1a,0xe8,0xd7,0x40,0xbf,0x06,0xfa,0xb5, |
1578 | | 0xd0,0xaf,0x85,0x7e,0x2d,0xf4,0x6b,0xa1,0x5f,0x0b,0xfd,0x5a,0xe8,0xd7,0x42,0xbf, |
1579 | | 0x16,0xfa,0xb5,0xd0,0xaf,0x85,0x7e,0xed,0x5a,0x9a,0x70,0xa4,0x91,0x5a,0x20,0x89, |
1580 | | 0x8b,0xf3,0x5c,0x2d,0x24,0x6b,0x21,0x59,0x0b,0xc9,0x5a,0x48,0xd6,0x42,0xb2,0x16, |
1581 | | 0x92,0xb5,0x90,0xac,0x85,0x64,0x2d,0x24,0x6b,0x21,0x59,0x0b,0xc9,0x5a,0x48,0xd6, |
1582 | | 0x42,0xb2,0x16,0x92,0xb5,0x90,0xac,0x83,0x64,0x1d,0x24,0xeb,0x20,0x59,0x07,0xc9, |
1583 | | 0x3a,0x48,0xd6,0x41,0xb2,0x0e,0x92,0x75,0x90,0xac,0x83,0x64,0x1d,0x24,0xeb,0xd0, |
1584 | | 0xe5,0x3a,0x74,0xb9,0x0e,0x5d,0xae,0x43,0x97,0xeb,0xd0,0xe5,0x3a,0xe8,0xd7,0x41, |
1585 | | 0xbf,0x0e,0xfa,0x75,0xd0,0xaf,0x83,0x7e,0x1d,0xf4,0xeb,0xa0,0x5f,0x07,0xfd,0x3a, |
1586 | | 0xe8,0xd7,0x41,0xbf,0x0e,0xfa,0x75,0xd0,0xaf,0x83,0x7e,0x1d,0xf4,0xeb,0xa0,0x5f, |
1587 | | 0x07,0xfd,0x3a,0xe8,0xd7,0x33,0x00,0x36,0xd4,0x27,0x02,0xd8,0x51,0x9f,0x0c,0x60, |
1588 | | 0x4b,0x7d,0x2a,0x80,0x3d,0xf5,0xb8,0x4a,0xea,0x61,0x43,0x3d,0xae,0x92,0x7a,0xd8, |
1589 | | 0x51,0x8f,0xab,0xa4,0x1e,0xb6,0xd4,0xe3,0x0a,0xa8,0x87,0x76,0x3d,0xae,0x80,0x7a, |
1590 | | 0xe8,0xd7,0xe3,0x0a,0xa8,0x87,0x0d,0xf5,0xb8,0x02,0xea,0x61,0x47,0x3d,0x46,0x78, |
1591 | | 0x3d,0xb4,0xeb,0x31,0xc2,0xeb,0xa1,0x5f,0x8f,0x11,0x5e,0x0f,0x1b,0xea,0x31,0xc2, |
1592 | | 0xeb,0x61,0x47,0x03,0x74,0x1b,0xa0,0xdb,0x00,0xdd,0x06,0xe8,0x36,0x40,0xb7,0x01, |
1593 | | 0xba,0x0d,0xd0,0x6a,0x80,0x4e,0x03,0x34,0x1a,0xd0,0xdf,0x06,0xe8,0x34,0x40,0xa7, |
1594 | | 0x01,0x3a,0x0d,0xd0,0x69,0x80,0x4e,0x03,0x74,0x1a,0xa0,0xd3,0xc0,0xea,0x30,0x98, |
1595 | | 0xa7,0xa0,0x07,0x5c,0x9c,0xc8,0xc5,0x49,0x5c,0x9c,0xcc,0xc5,0x29,0x5c,0x9c,0xca, |
1596 | | 0xc5,0x69,0x5c,0xbc,0x89,0x8b,0x0b,0xb9,0x78,0x33,0x17,0x17,0x71,0xf1,0x16,0x2e, |
1597 | | 0xde,0xca,0xc5,0xdb,0xb8,0xb8,0x98,0x8d,0x1b,0xb8,0xf2,0x0d,0x5c,0xf9,0x06,0xae, |
1598 | | 0x7c,0x03,0x57,0xbe,0x81,0x2b,0xdf,0xc0,0x95,0x6f,0xe0,0xca,0x37,0x98,0xca,0xef, |
1599 | | 0x41,0x7c,0xac,0x9c,0x8d,0x76,0xb1,0xdb,0x8d,0xfb,0xb9,0x18,0xde,0x68,0x2c,0x67, |
1600 | | 0x8f,0x62,0x3a,0xb5,0x9a,0xdc,0xdf,0x4c,0x64,0xa7,0x55,0x6f,0xb2,0x7d,0xdf,0xcb, |
1601 | | 0x16,0xad,0x62,0xa3,0xdd,0x6c,0xc9,0x26,0xce,0x56,0xdc,0xbd,0x71,0x84,0x2d,0x8b, |
1602 | | 0x39,0x1a,0x1b,0xb3,0xf3,0xb8,0xd5,0x28,0x7f,0x0c,0xa7,0xa3,0x89,0x85,0x75,0xd3, |
1603 | | 0x7e,0xec,0x5c,0xc3,0x15,0x58,0xc3,0x15,0x58,0xc3,0x16,0x80,0x52,0x13,0x7c,0xd6, |
1604 | | 0xc4,0xfa,0x0c,0x77,0x8f,0xa6,0xad,0xdc,0x04,0x8e,0xa1,0xa7,0xb1,0x5d,0x8f,0xb6, |
1605 | | 0xdb,0x97,0xb0,0x51,0x26,0xa7,0xc5,0xd9,0xd6,0x50,0xcd,0x1e,0x61,0xab,0xd3,0x79, |
1606 | | 0x66,0x05,0x52,0x4c,0x34,0x99,0x0a,0xfc,0x98,0x13,0x53,0x6e,0x1f,0x7e,0xcc,0x09, |
1607 | | 0x9b,0x1b,0x39,0x12,0x05,0x53,0x88,0x5d,0xc2,0x8e,0xa4,0x91,0xfa,0x1b,0x45,0xd9, |
1608 | | 0xd2,0x81,0x14,0x4c,0x21,0x14,0x4a,0x3a,0x0a,0xa3,0x70,0xf2,0xa1,0xf3,0xe9,0xab, |
1609 | | 0x28,0x9a,0x54,0xa4,0xa6,0x79,0xf3,0x69,0x42,0xc0,0x24,0x30,0x9f,0x5e,0xdf,0x33, |
1610 | | 0x89,0x26,0x05,0xcc,0x01,0x2f,0x20,0x3f,0x85,0x66,0xcf,0xa1,0xf9,0xb3,0xe8,0xf9, |
1611 | | 0x67,0x66,0xd2,0xf3,0xb3,0xe8,0x7c,0x4a,0x26,0xbd,0xb5,0x82,0xde,0x5a,0x49,0x6f, |
1612 | | 0xad,0xa2,0xb7,0x56,0xd3,0x94,0x09,0x2f,0xa2,0x95,0x95,0xdc,0xca,0x49,0xc7,0xc5, |
1613 | | 0xe1,0x5c,0x1c,0x14,0xc8,0x25,0x5a,0xd2,0x70,0x31,0x9b,0x0f,0xe1,0xf2,0x21,0xdc, |
1614 | | 0xf2,0x2a,0x84,0x82,0xb9,0x98,0xdd,0x1f,0x4a,0x21,0x5c,0xcc,0xe6,0xc3,0xb8,0xa3, |
1615 | | 0x61,0xdc,0x9e,0x30,0xd2,0x71,0x31,0xbb,0x9f,0xa6,0x4d,0xc3,0x0f,0x58,0x40,0x0b, |
1616 | | 0xa6,0xe1,0x87,0x03,0x9b,0x2f,0xd2,0x8b,0xd3,0xf0,0x33,0x8d,0xce,0xa7,0x26,0x53, |
1617 | | 0x20,0x27,0x75,0x3e,0xbd,0x04,0x3f,0xe6,0xc4,0x94,0xdb,0x8d,0x1f,0x73,0xc2,0xe6, |
1618 | | 0x2e,0x30,0xe9,0x60,0x09,0xb1,0x36,0x62,0xe5,0xa7,0xa1,0x20,0x18,0x88,0xc5,0x1f, |
1619 | | 0xcc,0x81,0x15,0xe8,0x05,0x34,0xc3,0x49,0x13,0x48,0xaa,0x20,0x35,0xa9,0x34,0x40, |
1620 | | 0x0b,0x82,0x41,0x08,0x08,0x05,0x3a,0x10,0x06,0xc2,0x41,0x50,0x20,0x1b,0xb1,0x25, |
1621 | | 0x83,0xd8,0xa2,0x41,0x6c,0xd9,0x20,0xb6,0x70,0x10,0x5b,0x3a,0x88,0x2d,0x1e,0xc4, |
1622 | | 0x96,0x0f,0x62,0x2b,0x04,0xb1,0x35,0x34,0x6c,0x8d,0x09,0x60,0x22,0x98,0x04,0x26, |
1623 | | 0x83,0x67,0xc0,0x14,0x30,0x15,0x3c,0x0b,0xa6,0x81,0xe9,0x60,0x06,0x98,0x09,0x66, |
1624 | | 0x81,0xd9,0x60,0x0e,0x98,0x0b,0x9e,0x03,0xf3,0xc0,0x7c,0xf0,0x3c,0x78,0x01,0x2c, |
1625 | | 0x00,0x0b,0xc1,0x8b,0xe0,0x25,0xf0,0xb2,0xfa,0x86,0x1b,0x58,0x4f,0x44,0x44,0x44, |
1626 | | 0x53,0x34,0xfb,0x13,0x4d,0xe7,0x4b,0xf2,0x8e,0x56,0xd3,0xf9,0x3d,0x7b,0x40,0x39, |
1627 | | 0xc0,0x48,0xda,0x83,0xe1,0xb5,0x67,0x2f,0xc0,0x70,0xda,0xb3,0x1f,0x54,0x01,0xb6, |
1628 | | 0x4c,0x0d,0xa8,0x05,0x75,0xa0,0x1e,0x34,0x80,0x46,0xd0,0x84,0xd5,0x0e,0xa6,0x1b, |
1629 | | 0xe5,0x98,0x6e,0x94,0x63,0xba,0x51,0x8e,0xe9,0x46,0x39,0xa6,0x1b,0xe5,0x98,0x6e, |
1630 | | 0x94,0x63,0xba,0x51,0x8e,0xe9,0x46,0x39,0xa6,0x1b,0xe5,0x98,0x6e,0x94,0x63,0xba, |
1631 | | 0x51,0x8e,0xe9,0x46,0x39,0xa6,0x1b,0xe5,0x98,0x6e,0x94,0x63,0xba,0x51,0x8e,0xe9, |
1632 | | 0x46,0x39,0xa6,0x1b,0xe5,0x98,0x6e,0x94,0x63,0xba,0x51,0x8e,0xe9,0x46,0x39,0x86, |
1633 | | 0x7a,0x39,0xa6,0x1b,0xe5,0x98,0x6e,0x94,0x63,0xba,0x51,0x8e,0xe9,0x46,0x39,0xa6, |
1634 | | 0x1b,0xe5,0xec,0xca,0x0a,0xd3,0x8d,0x72,0x4c,0x37,0xca,0x31,0xdd,0x28,0xc7,0x74, |
1635 | | 0xa3,0x1c,0xd3,0x8d,0x72,0x3c,0x51,0x71,0x4f,0xdd,0xd7,0x40,0x6d,0xb0,0xaa,0x7c, |
1636 | | 0x3b,0xd8,0x09,0x76,0x01,0x76,0x55,0xb6,0x9f,0x0e,0xe3,0xd9,0x0c,0x1b,0x2b,0x60, |
1637 | | 0x63,0x05,0xec,0xab,0x80,0x6d,0x15,0xb0,0xab,0x02,0x36,0x55,0xc0,0x9e,0x0a,0xd8, |
1638 | | 0x52,0x01,0x3b,0x2a,0x60,0x43,0x05,0xf4,0x2b,0xa0,0x5d,0x01,0xdd,0x0a,0x68,0x56, |
1639 | | 0x40,0xaf,0x02,0x5a,0x15,0xd0,0xa9,0xc0,0x94,0xa6,0x02,0xd3,0x99,0x0a,0x4c,0x65, |
1640 | | 0x2a,0x30,0x95,0xa9,0xd8,0x01,0x30,0xb4,0x2a,0x4a,0x41,0x19,0x80,0x0f,0x2b,0xa0, |
1641 | | 0x58,0x01,0xdf,0x55,0xc0,0x6f,0x15,0xf0,0x59,0x05,0xfc,0x55,0x01,0xab,0x2a,0xe0, |
1642 | | 0xa7,0x4a,0xe8,0x57,0x42,0xbf,0x12,0xfa,0x95,0xd0,0xaf,0x84,0x7e,0x25,0xf4,0x2b, |
1643 | | 0xa1,0x5f,0x09,0xfd,0x4a,0xe8,0x57,0x42,0xbf,0x12,0xfa,0x95,0xd0,0xaf,0x84,0x7e, |
1644 | | 0x25,0xf4,0x2b,0xa1,0x5f,0x09,0xfd,0x4a,0xe8,0x57,0x42,0xbf,0x12,0x3d,0xab,0xc4, |
1645 | | 0x58,0xae,0x84,0xd6,0xbe,0x42,0xea,0x2e,0x5b,0x4e,0x7d,0x8d,0x05,0xf4,0x51,0x35, |
1646 | | 0x03,0xb6,0x83,0xfd,0xa0,0x89,0x3e,0xc2,0xf3,0xf7,0x23,0x3c,0x2b,0x3f,0xaa,0x5d, |
1647 | | 0x06,0x36,0x81,0x5a,0xea,0x4a,0x6e,0xa2,0xae,0x94,0xad,0xa0,0x84,0xba,0x52,0x13, |
1648 | | 0xc1,0x3a,0x80,0x7c,0xda,0x26,0xb0,0x8f,0xba,0xd2,0x19,0xea,0x5a,0x9a,0x43,0x5d, |
1649 | | 0x19,0x35,0xd4,0xb5,0x6c,0x2d,0xc8,0x06,0xd5,0xd4,0xb5,0x7c,0x31,0xc8,0x05,0x3b, |
1650 | | 0xa8,0x2b,0x13,0xf5,0x32,0xf7,0x53,0x57,0x56,0x3a,0x28,0xa2,0xae,0x9c,0xf5,0xd4, |
1651 | | 0x95,0x5b,0x40,0x5d,0x45,0x68,0x67,0x0b,0x8e,0x6d,0x59,0x0a,0x50,0x77,0x4b,0x31, |
1652 | | 0x75,0x6d,0xad,0xa4,0xae,0xd2,0x15,0xd4,0xb5,0x1b,0xed,0x96,0xa1,0x9d,0x3d,0x59, |
1653 | | 0x60,0x33,0x40,0xbe,0x7c,0x37,0x28,0xa7,0xae,0x2a,0xe8,0x55,0xc1,0xa6,0x2a,0x36, |
1654 | | 0xdf,0x48,0x5d,0x35,0x15,0x00,0xb6,0xe2,0x99,0xdf,0x55,0xb7,0x17,0x60,0x1f,0x66, |
1655 | | 0xd8,0x5d,0x78,0xc0,0x75,0x35,0xa0,0x2d,0x3c,0x70,0xba,0x1a,0xd0,0x6e,0x53,0x12, |
1656 | | 0x75,0xa7,0xa7,0x83,0xfd,0xd4,0xbd,0x24,0x83,0xba,0xd7,0x94,0x81,0xbd,0xd4,0xbd, |
1657 | | 0x2e,0x0d,0xac,0x07,0x5b,0x40,0x0d,0x75,0xaf,0xdf,0x04,0xb6,0x52,0x77,0xce,0x1e, |
1658 | | 0xea,0xce,0x45,0xf9,0xdc,0xed,0xd4,0xbd,0x0b,0xfb,0x4a,0x37,0x03,0x1c,0xdf,0x5d, |
1659 | | 0x09,0x1f,0xa2,0x7e,0xd9,0x1a,0x90,0x43,0xdd,0xb0,0xb1,0x7b,0x0f,0xf2,0xb8,0x0e, |
1660 | | 0x7a,0x16,0x97,0x50,0x4f,0xfa,0x4e,0xb0,0x1f,0xd4,0x81,0x26,0xea,0x59,0x92,0x06, |
1661 | | 0x36,0x82,0x1c,0xea,0x59,0xba,0x8b,0x7a,0x32,0x93,0xc1,0x12,0xea,0x59,0x9d,0x0b, |
1662 | | 0xb6,0x51,0xcf,0x9a,0x0d,0xa0,0x00,0x6c,0x07,0x7b,0xa8,0x67,0x5d,0x06,0x58,0x45, |
1663 | | 0x3d,0x1b,0xd1,0xc6,0xc6,0x06,0xea,0xc9,0xde,0x0d,0xd0,0x4e,0x0e,0xd2,0x02,0xb4, |
1664 | | 0x51,0xb0,0x19,0x54,0x52,0xcf,0x96,0x5a,0xea,0xd9,0x56,0x0d,0x1a,0xa9,0x67,0x07, |
1665 | | 0xb4,0x4b,0x50,0xaf,0xa4,0x86,0x7a,0x30,0x8a,0x7b,0x2a,0xb1,0x1f,0x0f,0xe7,0x1e, |
1666 | | 0x3c,0x80,0x7b,0x1a,0x97,0x82,0x06,0xea,0x65,0x16,0x83,0x65,0x60,0x15,0xa8,0xa4, |
1667 | | 0xde,0xc5,0x4d,0xd4,0x9b,0xb8,0x84,0x7a,0xd3,0x8a,0xc0,0x4e,0x80,0x7d,0x69,0xf5, |
1668 | | 0xd4,0x9b,0x8e,0x32,0xe9,0x39,0xa0,0x80,0x7a,0x97,0xec,0x06,0x15,0xa0,0x9a,0x7a, |
1669 | | 0x37,0x2e,0x07,0x25,0xd4,0x5b,0xc8,0x00,0x94,0x29,0x44,0xbd,0xad,0x8d,0xd4,0xbb, |
1670 | | 0x2d,0x83,0x7a,0x8b,0xd1,0xe6,0x76,0xec,0xc7,0xf5,0xdf,0x8b,0xeb,0xb8,0x17,0xd7, |
1671 | | 0x63,0x6f,0x39,0xea,0xe0,0x5a,0xe8,0xdd,0xb7,0x05,0xec,0xa1,0xde,0xfd,0x68,0x1f, |
1672 | | 0x93,0xa9,0xde,0xba,0xa5,0xd4,0xdb,0x88,0xf6,0xf1,0x18,0xed,0xc5,0xf2,0xa3,0x2f, |
1673 | | 0x71,0x25,0xf5,0xa5,0x2c,0xa1,0xbe,0xb4,0x54,0xb0,0x0c,0x60,0x7b,0x6d,0x15,0xf5, |
1674 | | 0xad,0x63,0xa8,0x6f,0x43,0x2e,0xf5,0x65,0xef,0x07,0x35,0xd4,0x97,0xb3,0x9d,0xfa, |
1675 | | 0xf2,0x70,0x2c,0x2f,0x1f,0x6c,0x06,0x3b,0xa8,0xaf,0x20,0x03,0x94,0x82,0x4a,0xea, |
1676 | | 0xdb,0xb4,0x98,0xfa,0x36,0xa3,0x4c,0x51,0x0e,0x28,0xa0,0xbe,0x6d,0xeb,0xc0,0x46, |
1677 | | 0xb0,0x8b,0xfa,0x76,0x62,0x7f,0xc9,0x06,0x80,0xfd,0xbb,0xb6,0x82,0x32,0x50,0x01, |
1678 | | 0xea,0xa9,0xaf,0x34,0x9b,0xfa,0x2a,0xb1,0x0f,0xf3,0xc8,0x3e,0x8c,0xa1,0x3e,0x4c, |
1679 | | 0xfe,0xfa,0x30,0xa9,0xeb,0xc3,0x44,0xae,0x0f,0x13,0xb7,0x3e,0x4c,0xda,0xfa,0x30, |
1680 | | 0xd1,0xea,0xc3,0x24,0xab,0xaf,0x3e,0x13,0xac,0x06,0x9b,0x00,0xca,0x34,0x2c,0x05, |
1681 | | 0xab,0x70,0x3d,0xb1,0xd7,0x14,0x6c,0x6d,0xdc,0x44,0xfe,0x78,0x4e,0xac,0xc2,0xc8, |
1682 | | 0x4f,0x06,0x29,0xe4,0x7e,0x21,0x71,0x23,0x1b,0x65,0xd3,0x85,0xc4,0xf4,0x0b,0x89, |
1683 | | 0x4b,0x91,0x54,0x5e,0x48,0x4a,0xa7,0x73,0xc9,0x98,0x32,0x25,0x63,0xca,0x94,0x8a, |
1684 | | 0x99,0x7d,0x32,0xa6,0x0e,0xa9,0x58,0x54,0xa4,0x62,0x9a,0x97,0x8c,0xe9,0x53,0x32, |
1685 | | 0xa6,0x4f,0xc9,0x98,0x3e,0xa5,0xe2,0xf1,0x9f,0x8a,0x89,0x46,0x2a,0x26,0x10,0xa9, |
1686 | | 0x98,0x76,0xa5,0x62,0xda,0x95,0x8a,0x69,0x57,0x32,0x16,0x31,0xc9,0x98,0xd2,0x25, |
1687 | | 0x63,0x4a,0x97,0xcc,0xb6,0x85,0xe9,0x41,0x32,0xa6,0x9a,0xc9,0x58,0x08,0x25,0x63, |
1688 | | 0xba,0x99,0xbc,0x0c,0x60,0xca,0x99,0x9c,0x09,0x30,0xed,0x4c,0xc6,0x1c,0x23,0x19, |
1689 | | 0x73,0x8c,0x64,0x4c,0xfb,0x52,0x50,0x36,0x05,0xd3,0xaf,0x14,0x4c,0xbf,0x52,0x30, |
1690 | | 0xfd,0xc2,0xd5,0x7d,0x2e,0x05,0xd3,0xaf,0x14,0x4c,0xbf,0x52,0xb0,0xd0,0x49,0xc1, |
1691 | | 0x94,0x33,0x05,0x36,0xe1,0x8a,0x3f,0x97,0x02,0x9b,0x52,0x60,0x53,0x0a,0x16,0x3a, |
1692 | | 0x29,0x98,0x7e,0xa6,0xc0,0x9e,0x14,0xd8,0x93,0x02,0x7b,0x52,0x60,0x4f,0x0a,0xec, |
1693 | | 0x49,0x61,0xed,0xc1,0x34,0x32,0x19,0x53,0xbc,0x34,0xd8,0x93,0x06,0x7b,0x70,0x16, |
1694 | | 0xcf,0xa5,0x41,0x3b,0x0d,0x53,0xbf,0x34,0x4c,0xfb,0xd2,0x30,0xcd,0x4d,0xc6,0x1a, |
1695 | | 0x27,0x0d,0xd3,0xdc,0x34,0x4c,0x73,0x93,0x91,0x26,0x63,0xf1,0x95,0x8c,0xa9,0x4d, |
1696 | | 0x32,0x6c,0x49,0x86,0x2d,0xc9,0xd0,0x4f,0x86,0x76,0x32,0x74,0x93,0xa1,0x9b,0xcc, |
1697 | | 0xfa,0x02,0xba,0xc9,0xd0,0x4d,0x86,0x5e,0x32,0xa6,0x9a,0x29,0xf0,0x59,0x0a,0x34, |
1698 | | 0x52,0xd8,0xf6,0x61,0x47,0x1a,0x6b,0x07,0xda,0x4f,0xc1,0xe2,0x2e,0x05,0x1a,0x78, |
1699 | | 0x9e,0x9f,0x4b,0x65,0xfd,0x06,0x1b,0x52,0xd1,0xdf,0x54,0xf4,0x37,0x15,0xb6,0xa5, |
1700 | | 0x42,0x2b,0xb5,0x10,0x77,0xb9,0x25,0xb8,0xfb,0xe4,0x20,0x5d,0x0a,0x4a,0x01,0xae, |
1701 | | 0x98,0x35,0x15,0x48,0x71,0xe7,0xc3,0x6a,0xa9,0x6b,0x0b,0xee,0x56,0xb9,0x7b,0x48, |
1702 | | 0x85,0x93,0xa3,0x66,0xe3,0x44,0x2e,0x4e,0xe2,0xe2,0x14,0x2e,0x4e,0xe5,0xe2,0x34, |
1703 | | 0x2e,0x5e,0xc2,0xc5,0x19,0x5c,0xbc,0x8c,0x8b,0x33,0xb9,0x38,0x8b,0x8b,0x57,0x70, |
1704 | | 0xf1,0x4a,0x2e,0x5e,0x85,0xf8,0xe2,0x1e,0xb6,0xcd,0x4b,0x89,0x1b,0xd8,0x38,0x63, |
1705 | | 0x0b,0x1b,0xe7,0xd5,0xb3,0x71,0x71,0x3a,0x1b,0xef,0x59,0x83,0xf8,0xe3,0xc4,0x5d, |
1706 | | 0x6c,0xbc,0x36,0x99,0x8d,0xf3,0xd9,0x16,0x3e,0xde,0xb3,0x9d,0x8d,0x6b,0xf6,0x22, |
1707 | | 0xfe,0x24,0x89,0x6d,0xe1,0x93,0x65,0xac,0xd6,0x27,0x6b,0xd9,0x76,0x3e,0x2e,0x62, |
1708 | | 0x5b,0xf8,0x78,0xc3,0x96,0x8f,0x37,0x25,0x9b,0x32,0x9f,0xe4,0xb0,0x19,0xdc,0xda, |
1709 | | 0xd9,0xb8,0x76,0x19,0x97,0x67,0xed,0x44,0xb7,0xb9,0x3d,0xac,0x4a,0x57,0x4a,0x29, |
1710 | | 0xb7,0x3f,0x89,0xcb,0x97,0xb0,0xf9,0x9a,0x3c,0x36,0xbf,0x7c,0x31,0x62,0xdc,0xf2, |
1711 | | 0x10,0xe3,0x46,0xc6,0xe6,0xf7,0xec,0xe5,0xf6,0xb0,0x36,0xe0,0xb2,0x64,0xcb,0xe4, |
1712 | | 0x16,0xb0,0x7b,0xd6,0x6f,0x65,0xe3,0x4d,0x3b,0xb9,0xa3,0x6c,0xfb,0x3d,0x5b,0x1a, |
1713 | | 0xd9,0xa3,0x2b,0x96,0xb3,0xf9,0x25,0x35,0x88,0x7b,0x2b,0x0a,0xd9,0xfc,0x56,0xae, |
1714 | | 0xe5,0xa5,0x6c,0x3b,0x1f,0xd5,0x15,0xb1,0xf9,0x95,0xac,0xcd,0x5d,0xa5,0xdb,0xd8, |
1715 | | 0xa3,0x39,0xec,0x9e,0x8f,0xea,0x59,0xdd,0xde,0xca,0x34,0xce,0x86,0x35,0x5c,0x2d, |
1716 | | 0xce,0xc2,0x7a,0x56,0x11,0xb7,0x26,0x2e,0xae,0x54,0x53,0xd7,0x5a,0x3c,0x0d,0x6a, |
1717 | | 0xea,0xa9,0x67,0x77,0x16,0xcd,0x7d,0xfe,0x19,0xd2,0x04,0x91,0x46,0x43,0x1a,0xcc, |
1718 | | 0x17,0x83,0x49,0x83,0x99,0x62,0x28,0x69,0x74,0xa4,0x09,0x23,0x4d,0x38,0x69,0x03, |
1719 | | 0x49,0x1b,0x44,0x5a,0x0d,0x69,0xb5,0xa4,0x0d,0x26,0x6d,0x08,0xc1,0xff,0x04,0xef, |
1720 | | 0x13,0x7c,0x4f,0xf0,0x3c,0xc1,0xef,0x04,0xaf,0x13,0x7c,0x4e,0xf0,0x38,0xc1,0xdf, |
1721 | | 0x04,0x6f,0x13,0x7c,0x4d,0xf0,0x34,0xc1,0xcf,0x04,0x2f,0x63,0x5f,0xf5,0xc5,0xca, |
1722 | | 0x4d,0x04,0x57,0x7f,0x9c,0x87,0xad,0xec,0x3d,0x78,0x30,0xae,0xc1,0x03,0x91,0x1d, |
1723 | | 0x3e,0x49,0x78,0x68,0xe6,0x11,0xfc,0x80,0x87,0x04,0x6e,0xe8,0x5b,0xf0,0xe0,0x59, |
1724 | | 0xb1,0x1c,0x37,0xfa,0x1a,0xdc,0xf8,0x0a,0x09,0x7d,0xc7,0xc3,0x11,0x37,0xe6,0x62, |
1725 | | 0xf6,0x06,0x8f,0x1b,0xda,0x62,0x0c,0xaf,0xe4,0x9d,0xb8,0x2d,0xe0,0xc1,0x52,0x89, |
1726 | | 0x1b,0xd2,0x26,0x3c,0x6c,0xb1,0x1a,0xeb,0x4a,0xdd,0x88,0x07,0x0b,0x1e,0x8c,0x55, |
1727 | | 0xdb,0xf0,0x80,0xc4,0x83,0x6a,0x59,0x1d,0x1e,0x80,0x78,0x48,0x96,0xe2,0xe1,0x90, |
1728 | | 0x53,0x84,0x32,0xb8,0x71,0x63,0x02,0x00,0xdf,0x60,0x88,0xe6,0x92,0x36,0x94,0xb4, |
1729 | | 0x3a,0xd2,0x62,0xda,0x1b,0x4e,0xc1,0x98,0x9d,0x07,0x51,0xb0,0x86,0x82,0xb5,0x14, |
1730 | | 0x1c,0x4c,0xc1,0x98,0x23,0x87,0x52,0xb0,0x8e,0x82,0xc3,0x28,0x38,0x9c,0x42,0x30, |
1731 | | 0x59,0x65,0x1f,0x61,0x1a,0x36,0xd2,0xb2,0x51,0x30,0x1b,0x85,0xb0,0x51,0x28,0x1b, |
1732 | | 0xe9,0xd8,0x28,0x8c,0x8d,0xc2,0xd9,0x28,0x28,0x90,0x8b,0xb9,0x3a,0x41,0x5c,0xa5, |
1733 | | 0x67,0xa7,0xd2,0x33,0xf3,0xc0,0x02,0x9a,0xf9,0xfc,0x64,0xdc,0xbb,0x36,0x83,0x2d, |
1734 | | 0x60,0x1b,0xd8,0x0e,0x76,0x82,0x12,0x50,0x0a,0xca,0x40,0x39,0x7b,0x7f,0x03,0xfb, |
1735 | | 0x40,0x15,0xa8,0x01,0x75,0xa0,0x01,0x34,0xd1,0x85,0xa4,0xc5,0x20,0x19,0xa4,0x12, |
1736 | | 0x7b,0x13,0xbc,0x90,0x84,0xfb,0x61,0x52,0x06,0x58,0x06,0x96,0x83,0x4c,0x90,0x05, |
1737 | | 0x56,0x81,0xb5,0x60,0x03,0xc8,0x01,0xf9,0xa0,0x00,0x6c,0x02,0x85,0x00,0x76,0x24, |
1738 | | 0xc1,0x8e,0x24,0xd8,0x91,0x04,0x3b,0x92,0x76,0x00,0xd8,0x92,0x04,0x5b,0x92,0x76, |
1739 | | 0x01,0xd8,0x93,0x04,0x7b,0x92,0xf6,0x00,0xd8,0x94,0x84,0x8b,0xbc,0x6e,0x4b,0xd7, |
1740 | | 0xaa,0x65,0x6c,0x17,0x2e,0x24,0xad,0xbc,0x90,0x54,0xcf,0xe9,0xb3,0x1b,0x25,0x50, |
1741 | | 0xba,0x90,0x58,0x68,0xda,0xc0,0xbd,0x39,0xdb,0xd4,0xcb,0xcd,0x5c,0x19,0xb6,0x6f, |
1742 | | 0x5b,0x60,0x22,0x7b,0x24,0x71,0x8f,0x69,0xa3,0x92,0xeb,0x46,0xe2,0xb6,0x0b,0x89, |
1743 | | 0x3b,0xb0,0xc1,0x3a,0x02,0xfd,0x44,0xf7,0xb9,0x0a,0x4b,0xb8,0x6d,0xe4,0x12,0xd1, |
1744 | | 0x6e,0x3d,0xeb,0x21,0xae,0x6a,0x8d,0x29,0x57,0xcf,0xf5,0x00,0x87,0xd8,0x76,0x38, |
1745 | | 0xdf,0xc1,0xf4,0x0b,0x49,0x49,0x26,0x63,0xb0,0x51,0x8a,0xdd,0xa6,0x7a,0xbb,0xb8, |
1746 | | 0x8d,0x4a,0x53,0xae,0x92,0xf3,0x40,0xe2,0x6e,0x6c,0x70,0x09,0x6b,0x10,0x5b,0x08, |
1747 | | 0x25,0xb6,0x5e,0xaf,0xb1,0x9b,0xeb,0x0b,0x73,0xfd,0x48,0xa9,0x39,0x81,0xe1,0x9c, |
1748 | | 0xca,0xa6,0x81,0xed,0xa4,0x42,0x53,0xff,0x4d,0xdd,0x33,0xed,0x2a,0xbb,0x6e,0xc5, |
1749 | | 0x8d,0xc2,0xe6,0x1c,0x57,0x92,0x35,0xa4,0x8c,0x15,0x48,0xac,0xe7,0x8c,0x2f,0x35, |
1750 | | 0x6d,0x97,0x72,0x2d,0x2d,0x67,0xcf,0x3c,0xd7,0xe9,0x1a,0xd3,0xf3,0xad,0x84,0x3b, |
1751 | | 0xb3,0x6c,0x0e,0x47,0xf3,0xd8,0xf1,0xc0,0x56,0xe2,0x1a,0xe0,0x36,0x38,0x1f,0x5e, |
1752 | | 0x77,0x47,0x15,0xd7,0x05,0xb3,0x83,0xeb,0xae,0x3b,0xd8,0x94,0x63,0x47,0x09,0x33, |
1753 | | 0xd0,0x76,0x52,0x1a,0x37,0xac,0x92,0x96,0x98,0xce,0xb4,0xc9,0xae,0xa4,0xa5,0xa6, |
1754 | | 0x71,0x93,0x39,0xd0,0x85,0xa4,0x2c,0xce,0x44,0x76,0x9c,0x71,0x67,0xfa,0xa6,0x96, |
1755 | | 0x4c,0x67,0x9e,0x3d,0xb2,0x82,0xcb,0xed,0x32,0x35,0xb4,0x86,0x3d,0xdf,0x38,0x89, |
1756 | | 0x66,0x9f,0xb0,0xdb,0x65,0xd7,0x73,0xac,0xc4,0x6a,0xd3,0x16,0x3b,0x50,0x06,0xce, |
1757 | | 0xd8,0x12,0xd3,0x76,0xd1,0xc0,0x58,0x4a,0x5a,0xc7,0xee,0x46,0x67,0x12,0x8b,0x07, |
1758 | | 0x0a,0x27,0x99,0x06,0x48,0xd2,0x06,0xb6,0xb9,0xc4,0xa6,0x81,0x11,0xc5,0x0e,0xb1, |
1759 | | 0x06,0x2e,0x61,0xcf,0xe3,0x2a,0xae,0x00,0xeb,0xb2,0x64,0xd3,0x3e,0xd3,0x70,0x61, |
1760 | | 0x73,0x30,0xbd,0x1a,0xb9,0x8d,0x5c,0x8e,0xbd,0x7c,0xf2,0x06,0x06,0x20,0xab,0x97, |
1761 | | 0xcb,0x55,0x62,0x73,0x39,0x26,0x99,0x3c,0xee,0xd0,0x12,0xd3,0x0e,0xb3,0x94,0x29, |
1762 | | 0xc7,0x1e,0xcd,0x1f,0x38,0x05,0xa5,0x03,0x1b,0x5c,0x81,0x7c,0xae,0x33,0x59,0xa6, |
1763 | | 0x5c,0x09,0x77,0x15,0xb3,0xb9,0x4a,0xee,0xb4,0x14,0x9b,0xaa,0x16,0x0c,0x9c,0x6b, |
1764 | | 0xd3,0x06,0x77,0xa5,0x15,0x70,0x27,0x6d,0xc5,0x75,0xa1,0x42,0x6e,0x6c,0x72,0xc9, |
1765 | | 0xf5,0x13,0x73,0xf3,0x38,0x4b,0xda,0x32,0x70,0x7d,0x98,0x73,0xec,0xbe,0x6d,0xa6, |
1766 | | 0x8b,0x8e,0xb8,0xb6,0x92,0xae,0x17,0xdd,0x69,0xba,0xa0,0x4b,0x58,0xf7,0xb3,0xa3, |
1767 | | 0x99,0xcd,0xd5,0x73,0x0e,0xe6,0xae,0x6f,0xd3,0x6d,0xc0,0x74,0x59,0x60,0x4e,0x55, |
1768 | | 0x61,0x6a,0x61,0x60,0x04,0x07,0xf6,0xc0,0x7d,0x41,0x6c,0xa4,0x61,0x23,0x2d,0x1b, |
1769 | | 0x05,0xb3,0x51,0x08,0x1b,0x85,0xb2,0x91,0x8e,0x8d,0xc2,0xd8,0x28,0x9c,0x2b,0x6c, |
1770 | | 0xaa,0xc2,0xd5,0x09,0xe2,0x2a,0x05,0x71,0xb5,0x82,0xb8,0x6a,0x41,0x5c,0xbd,0x20, |
1771 | | 0xae,0x62,0x10,0x57,0x33,0x88,0xab,0x1a,0xc4,0xd5,0xd5,0x70,0x75,0x35,0x26,0x3d, |
1772 | | 0xae,0xae,0x86,0xab,0xab,0xe1,0xea,0x3e,0x3b,0x77,0x02,0x4d,0x9e,0x40,0x13,0x5e, |
1773 | | 0xa0,0x89,0x13,0xe6,0xd1,0x9c,0x05,0x34,0x77,0x12,0x4d,0x9e,0x85,0x1f,0x0d,0xd0, |
1774 | | 0xd2,0xb4,0x17,0xf0,0x3c,0xab,0xec,0x4e,0x5f,0x41,0xdd,0x1b,0x4a,0xd9,0xbb,0x13, |
1775 | | 0xd6,0x40,0xec,0x93,0xa0,0x7b,0x43,0x66,0x37,0x56,0x82,0x78,0xb0,0x74,0xd5,0x67, |
1776 | | 0x7d,0x54,0x9f,0xcd,0x3e,0x59,0xd0,0xd2,0xec,0x09,0x74,0xac,0x7e,0x02,0xcd,0x9a, |
1777 | | 0x40,0x33,0xf0,0x33,0x91,0x66,0x4d,0xa4,0xa9,0x13,0x69,0xd2,0x84,0x99,0x34,0x83, |
1778 | | 0x8d,0xe6,0x4e,0xa1,0xd9,0x53,0x50,0x82,0x65,0x2a,0xcd,0x9a,0x4a,0x33,0xa6,0xd2, |
1779 | | 0xb3,0x2f,0xd3,0x0c,0x30,0x0b,0x4c,0x05,0xcf,0x83,0x63,0xf5,0x33,0x69,0xd6,0x4c, |
1780 | | 0x9a,0x8c,0x5a,0x33,0x69,0xca,0x2c,0x9a,0x3d,0x0b,0xbb,0x66,0xd1,0xac,0x59,0x34, |
1781 | | 0x69,0x16,0xcd,0x60,0x33,0x1a,0xe4,0x34,0x84,0x9f,0x19,0x6c,0x02,0x3b,0x27,0x01, |
1782 | | 0xfc,0xcc,0x60,0x93,0xf3,0xe9,0x6b,0xe7,0x9b,0x62,0x1c,0x87,0x51,0xb3,0xc0,0x54, |
1783 | | 0x30,0x6f,0xc2,0x64,0x16,0xee,0xb0,0x39,0xd5,0xd0,0xdc,0xf9,0x34,0x7b,0x3e,0x9a, |
1784 | | 0x47,0x8d,0xf9,0x34,0x77,0x01,0xcd,0x5e,0x80,0x8d,0x05,0x34,0x6b,0x01,0xcd,0x80, |
1785 | | 0x2f,0x16,0xd2,0xec,0x85,0xd8,0x5e,0x48,0xb3,0x16,0xd2,0x0c,0xfc,0xb4,0x2f,0xa1, |
1786 | | 0x59,0x60,0xe2,0x73,0x34,0x69,0x12,0x4d,0x9a,0x4c,0x93,0xd0,0x08,0xfa,0x30,0x19, |
1787 | | 0xdd,0x7c,0x89,0x9e,0x9d,0x00,0x6f,0xd2,0xb4,0xd9,0x34,0x63,0x06,0xcd,0x78,0x9e, |
1788 | | 0x66,0xce,0xa2,0x99,0xb3,0x69,0xe6,0x9c,0xa9,0x34,0xf3,0x45,0x9a,0x35,0x0d,0x5d, |
1789 | | 0x9a,0x03,0x0f,0x3c,0x4b,0x73,0xe7,0xce,0xa2,0xb9,0xf3,0x68,0x3e,0x7e,0x16,0xd0, |
1790 | | 0xc2,0x89,0xb4,0x00,0x6d,0xcc,0xa2,0x09,0x5c,0x1c,0xc4,0x2e,0xeb,0x34,0x6c,0xa4, |
1791 | | 0x65,0xa3,0x60,0x36,0x0a,0x61,0xa3,0x50,0x36,0xd2,0xb1,0x51,0x18,0x1b,0x85,0xb3, |
1792 | | 0x11,0x9e,0x85,0x6c,0xcc,0xd5,0x09,0xe2,0x2a,0x05,0x71,0xb5,0x82,0xb8,0x6a,0x41, |
1793 | | 0x5c,0xbd,0x20,0xae,0x62,0x10,0x57,0x33,0x88,0xab,0x1a,0xc4,0xd5,0xd5,0x70,0x75, |
1794 | | 0x35,0x26,0x3d,0xae,0xae,0x86,0xab,0xab,0xe1,0xea,0x6a,0xb8,0xba,0x1a,0xae,0xae, |
1795 | | 0x86,0xab,0xab,0xe1,0xea,0x6a,0xb8,0xba,0x5a,0xae,0xae,0x96,0xab,0x3b,0x15,0x67, |
1796 | | 0xf5,0xe2,0xc6,0xc5,0x20,0x09,0xa4,0x80,0x34,0xb0,0x04,0x2c,0x07,0x59,0x60,0x25, |
1797 | | 0x58,0x0d,0xd6,0x82,0xf5,0x60,0x23,0xc8,0x01,0x79,0xa0,0x00,0x14,0x82,0x22,0xb0, |
1798 | | 0x15,0x14,0x83,0x1d,0xa0,0x04,0x94,0xd2,0xc5,0x6c,0xb4,0x9b,0x8d,0x76,0xb3,0xd1, |
1799 | | 0x6e,0x36,0xda,0xcd,0x46,0xbb,0xd9,0x19,0x00,0x6d,0x67,0xa3,0xed,0x6c,0xb4,0x9d, |
1800 | | 0x8d,0xb6,0xb3,0xd1,0x76,0x36,0xda,0xce,0x46,0xdb,0xd9,0x68,0x3b,0x17,0xed,0xe5, |
1801 | | 0xa2,0xbd,0x5c,0xb4,0x97,0x8b,0xf6,0x72,0xd1,0x5e,0x2e,0xda,0xcb,0x2d,0x03,0x95, |
1802 | | 0x60,0x1f,0xa8,0x02,0x35,0xa0,0x0e,0x34,0x80,0x26,0xba,0x98,0x07,0xbd,0x3c,0xe8, |
1803 | | 0xe5,0x41,0x2f,0x0f,0x7a,0x79,0xd0,0xcb,0x83,0x5e,0x1e,0xf4,0xf2,0xa0,0x87,0xa5, |
1804 | | 0xdd,0xc5,0x3c,0xe8,0xe5,0x41,0x2f,0x0f,0x7a,0x79,0xd0,0xcb,0x83,0x5e,0x1e,0xfa, |
1805 | | 0x92,0x87,0xbe,0xe4,0xa1,0x2f,0x79,0xd0,0xce,0x83,0x76,0x1e,0xb4,0xb1,0xfc,0xbb, |
1806 | | 0x98,0x07,0xed,0x3c,0x68,0xe7,0x41,0x3b,0xaf,0x16,0xd4,0xd3,0xb9,0x7d,0xd0,0xcd, |
1807 | | 0x83,0x5e,0x3e,0xf4,0xf2,0xa1,0x97,0x0f,0xbd,0x7c,0xe8,0xe5,0x2f,0x03,0xd0,0xc8, |
1808 | | 0x87,0x46,0x3e,0xda,0xcf,0x47,0xfb,0xf9,0x68,0x3f,0x1f,0xed,0xe7,0xa3,0xfd,0x7c, |
1809 | | 0xb4,0x9f,0x8f,0xf6,0xf3,0xd1,0x7e,0x3e,0xda,0xcf,0xdf,0x41,0x6d,0xbb,0xe8,0x48, |
1810 | | 0x3e,0x1d,0x41,0xe5,0x52,0xb6,0x12,0x3a,0x96,0x8f,0x8e,0xe5,0x43,0x20,0x1f,0x1d, |
1811 | | 0xcb,0x47,0xc7,0xf2,0x21,0x54,0x00,0xa1,0x02,0x56,0x08,0x2b,0x8d,0xfd,0x99,0xc8, |
1812 | | 0xa7,0x83,0xa5,0xd4,0xb6,0x05,0x09,0xfa,0x56,0x80,0xbe,0x15,0x40,0xb7,0x00,0x4d, |
1813 | | 0x14,0xa0,0x6f,0x05,0xd0,0x2e,0x80,0x36,0x96,0xf2,0x87,0x20,0x5f,0xb0,0x9f,0x2e, |
1814 | | 0xee,0x42,0xab,0xa5,0xab,0xe8,0x08,0x96,0x6c,0x99,0x58,0x12,0x65,0x62,0x89,0x96, |
1815 | | 0x89,0x65,0x51,0x26,0x96,0x45,0x99,0x58,0xa2,0x65,0x62,0x89,0x96,0x89,0x25,0x5a, |
1816 | | 0x26,0x96,0x48,0x99,0x58,0xa2,0x65,0x62,0x99,0x94,0x89,0x25,0x5a,0x26,0x96,0x4a, |
1817 | | 0x99,0x58,0x2a,0x65,0x62,0xa9,0x94,0x89,0xa5,0x52,0x26,0x96,0x4a,0x99,0x58,0xa2, |
1818 | | 0x65,0x62,0x69,0x94,0x89,0xa5,0x51,0x26,0x96,0x68,0x99,0x58,0xa2,0x65,0x62,0x89, |
1819 | | 0x96,0x89,0xe5,0x53,0x66,0x15,0xa8,0x06,0x35,0xa0,0x16,0xd4,0x01,0x78,0x2c,0xb3, |
1820 | | 0x01,0x34,0x82,0x26,0x3a,0x97,0x85,0x25,0x56,0x16,0x96,0xa5,0x59,0x58,0x92,0x66, |
1821 | | 0x61,0x29,0x9a,0x85,0x25,0x55,0x16,0x96,0x54,0x59,0x58,0x6e,0x66,0x61,0xe9,0x95, |
1822 | | 0x85,0xa5,0x55,0x16,0x96,0x9a,0x59,0x58,0x6a,0x66,0x61,0xa9,0x99,0x85,0xa5,0x58, |
1823 | | 0x16,0xec,0xce,0xc2,0x72,0x2f,0x0b,0x4b,0xcd,0x2c,0x2c,0x35,0xb3,0xb0,0xf4,0xca, |
1824 | | 0xc2,0xd2,0x2b,0x0b,0xcb,0xbf,0x2c,0x38,0x25,0x0b,0x4b,0xc3,0xac,0x75,0x00,0x4b, |
1825 | | 0xb5,0x2c,0x2c,0xd5,0xb2,0xb0,0x54,0xcb,0xc2,0x12,0x36,0x2b,0x07,0xb0,0xdf,0xed, |
1826 | | 0x61,0x39,0x98,0x85,0x25,0x5a,0x16,0x96,0x86,0x59,0xe8,0x7f,0x16,0xfa,0x9f,0x85, |
1827 | | 0xfe,0x67,0xa1,0xff,0x59,0xe8,0x7f,0x16,0xfa,0x9f,0x85,0xfe,0x67,0xa1,0xff,0x59, |
1828 | | 0xe8,0x7f,0x16,0xfa,0x9f,0x85,0xfe,0x67,0xa1,0xff,0x59,0xe8,0x7f,0x16,0xfa,0x9f, |
1829 | | 0x85,0xfe,0x67,0x95,0x51,0x6f,0x79,0x3a,0x75,0xe7,0xec,0xc5,0x7c,0x19,0x29,0x16, |
1830 | | 0xee,0x1f,0x55,0x57,0x60,0x4e,0xbd,0x95,0xba,0xb6,0x62,0x9e,0xbd,0x0e,0x73,0xe8, |
1831 | | 0xad,0xd8,0x9f,0xc6,0xbe,0x58,0xd9,0x41,0x3d,0x8d,0x29,0xd4,0xbb,0xa1,0x89,0x7a, |
1832 | | 0xf3,0x6b,0xa9,0xb7,0xa8,0x9a,0xfa,0x12,0xb3,0xa8,0x7b,0x7b,0x22,0x75,0xef,0xcd, |
1833 | | 0xa1,0x9e,0xa4,0x8d,0xd4,0x03,0x9b,0x7a,0x57,0x60,0xd1,0x8f,0xe5,0x70,0x5f,0x71, |
1834 | | 0x39,0xe6,0xfd,0x89,0x98,0x83,0xef,0xa3,0xee,0x5d,0xc9,0xd4,0xc3,0xbe,0x20,0xd9, |
1835 | | 0x50,0x4a,0x7d,0xd5,0xf9,0xd4,0xb5,0x0f,0xf7,0xef,0xa6,0x12,0xea,0x5d,0xbf,0x9c, |
1836 | | 0x7a,0xb7,0x6e,0xa1,0xee,0x0c,0xf6,0xa5,0xca,0x06,0xea,0xdd,0x54,0x40,0x5d,0x75, |
1837 | | 0x4b,0xb1,0x36,0x58,0x4f,0xdd,0xfb,0x76,0x52,0x4f,0x46,0x3d,0xf5,0x61,0xa6,0xf2, |
1838 | | 0x51,0x63,0x2a,0xe6,0xfc,0x55,0xd4,0x95,0x91,0x4f,0xdd,0xab,0x93,0xa9,0xbb,0x64, |
1839 | | 0x35,0xda,0x5b,0x81,0xb9,0x7e,0x31,0xda,0x4c,0xa5,0xde,0x8d,0xb9,0xd4,0x5b,0x55, |
1840 | | 0x46,0x7d,0xb9,0x15,0xd4,0x57,0x8a,0xb4,0xaa,0x96,0x7a,0x36,0x2f,0xc3,0x7a,0xa2, |
1841 | | 0x89,0x7a,0xf6,0x6f,0xa2,0x5e,0xf8,0xbf,0x6f,0x59,0x32,0xf5,0x96,0xac,0xa3,0xae, |
1842 | | 0x22,0x68,0xd4,0xc3,0x9e,0x72,0xec,0x5f,0xdc,0x88,0xb5,0xc7,0x66,0xea,0x29,0x5a, |
1843 | | 0x8a,0xfe,0x27,0x52,0x5f,0x0e,0x34,0x8a,0x36,0x50,0x57,0xf9,0x66,0xf4,0x6b,0x35, |
1844 | | 0x75,0x57,0x65,0x53,0x77,0x7d,0x16,0xf5,0xec,0x2d,0xa3,0x9e,0x6a,0xac,0x47,0x36, |
1845 | | 0x66,0xc0,0x86,0x55,0xd4,0x9b,0x88,0x34,0x2d,0x17,0x40,0x63,0x7b,0x2e,0x34,0x1a, |
1846 | | 0xa1,0x51,0x8e,0xe3,0xfb,0xa8,0x77,0x37,0x83,0xfe,0x64,0x41,0xab,0x11,0xbe,0xac, |
1847 | | 0xa1,0xae,0xb2,0x62,0xea,0x66,0x56,0x51,0x4f,0x66,0x1a,0xf5,0xac,0xdd,0x83,0xb5, |
1848 | | 0xca,0x7a,0xe8,0xd5,0xa1,0x4f,0x4d,0xd4,0xd5,0xb8,0x03,0x65,0x96,0x63,0x6d,0xb3, |
1849 | | 0x8c,0xba,0xd7,0x56,0x43,0x67,0x33,0x7c,0x9f,0x44,0x5d,0x85,0xf9,0xd4,0x93,0x8b, |
1850 | | 0x35,0xcc,0x4a,0xf8,0x65,0x27,0xd6,0x4a,0xbb,0x6b,0xa9,0xbb,0x02,0xe7,0x21,0x03, |
1851 | | 0x3a,0x19,0x5b,0xa9,0x1b,0x63,0xbe,0x67,0xed,0x56,0xf8,0x77,0x37,0xd6,0x55,0x58, |
1852 | | 0x23,0xa5,0x2d,0xa1,0xee,0xcd,0x8b,0xa9,0xa7,0x12,0xfe,0x58,0x82,0x73,0x5a,0xb2, |
1853 | | 0x8a,0xfa,0xd2,0xb0,0xf4,0xcb,0xd8,0x47,0x5d,0x2b,0x71,0x0e,0xea,0x76,0x51,0xf7, |
1854 | | 0xfa,0x14,0xf8,0x1c,0xfd,0xdd,0x82,0x73,0xb3,0x0e,0xe7,0x61,0x07,0xd2,0xda,0xf5, |
1855 | | 0xd4,0x57,0x97,0x89,0xf3,0x9f,0x8a,0xf5,0x54,0x15,0xf5,0x36,0x40,0x1f,0xab,0xb9, |
1856 | | 0xee,0x54,0x9c,0x9f,0x74,0xf4,0x63,0x15,0xdb,0xff,0x22,0xea,0x49,0xc1,0x5a,0x6d, |
1857 | | 0x15,0x28,0x5e,0x4a,0x3d,0x55,0x18,0x2b,0x8b,0xa1,0x51,0xbf,0x8d,0x7a,0x57,0xef, |
1858 | | 0xa6,0x3e,0xa6,0x88,0xfa,0x96,0x2f,0xa5,0xae,0x74,0xac,0xbf,0x96,0x62,0x4d,0xb6, |
1859 | | 0xaa,0x01,0x63,0x21,0x1d,0xe3,0x83,0xd5,0x5d,0x42,0x5d,0x4d,0x38,0xff,0xcb,0xf1, |
1860 | | 0x68,0xde,0xbd,0x9b,0x7a,0xf6,0x40,0x1f,0xe3,0x01,0x2b,0x0b,0xea,0xca,0x81,0x6f, |
1861 | | 0xf6,0xa3,0x5f,0x0c,0xfc,0x87,0x6b,0xaf,0x67,0x25,0x3b,0xbe,0xb2,0xd1,0x76,0x2a, |
1862 | | 0xf5,0xa5,0xef,0xc5,0xb9,0xd8,0x4f,0x7d,0x79,0xe9,0x58,0xf3,0x6d,0x80,0xaf,0x32, |
1863 | | 0xa8,0x67,0x1b,0xb4,0x52,0xb1,0x3f,0xbb,0x9a,0xba,0xb1,0xa2,0xf9,0xa8,0x16,0x63, |
1864 | | 0x22,0x29,0x1b,0xfe,0x85,0x0f,0xf6,0x34,0x51,0xf7,0x3a,0x8c,0xbf,0xb4,0x4c,0x8c, |
1865 | | 0xd3,0x44,0xd8,0x85,0x71,0xb3,0xb8,0x9e,0xba,0xb3,0x51,0x7f,0x03,0x8e,0x2f,0x85, |
1866 | | 0x7f,0xf2,0x60,0x43,0x41,0x25,0xc6,0xd5,0x62,0xea,0xae,0x85,0xe6,0x0a,0xf4,0x67, |
1867 | | 0x2d,0xea,0x14,0x96,0xc0,0xef,0x2b,0xa8,0x0f,0x3e,0xef,0x4e,0x87,0xc6,0xc6,0x6a, |
1868 | | 0xea,0x62,0x4a,0xa8,0x6b,0x2f,0xd6,0x98,0x55,0x3b,0xd1,0x4f,0xac,0x3f,0xa1,0xdf, |
1869 | | 0x9d,0x82,0x71,0xb7,0x09,0xfe,0xca,0x86,0x6e,0x3a,0x7c,0xbe,0x02,0xfe,0x2d,0xc7, |
1870 | | 0xb9,0xd8,0x80,0x71,0x92,0x07,0x1f,0x6e,0xde,0x8e,0xf3,0xb8,0x15,0xed,0xa6,0x52, |
1871 | | 0xcf,0x7a,0x8c,0xa9,0x06,0xac,0x69,0x8b,0x30,0x0e,0x8a,0x0a,0xd1,0x17,0xf8,0x75, |
1872 | | 0x19,0x6c,0x64,0x5f,0x10,0xaf,0xc8,0x83,0x9d,0x18,0xbb,0xab,0x30,0xde,0xd7,0xd7, |
1873 | | 0xfe,0x3f,0xf6,0xde,0x06,0xa8,0xa9,0x6b,0xed,0xfb,0x5e,0x51,0x50,0xa2,0x50,0x82, |
1874 | | 0x82,0x82,0x82,0x05,0x25,0x0a,0x96,0x40,0x52,0x93,0x96,0x20,0xb4,0xa0,0xa0,0x04, |
1875 | | 0x12,0xbe,0xa3,0x44,0x41,0xa1,0x05,0x4c,0x20,0x91,0x04,0x12,0x20,0x90,0x40,0x02, |
1876 | | 0x49,0x48,0x42,0x62,0x49,0x05,0x0a,0x2d,0xb4,0xa0,0xa0,0x60,0xc1,0x8a,0x10,0x05, |
1877 | | 0x0b,0x56,0xee,0x91,0xe7,0x96,0x3e,0x32,0x23,0x33,0x72,0x17,0x5a,0x79,0x47,0x4e, |
1878 | | 0x09,0xc2,0x3d,0xf2,0x0e,0xcc,0xc8,0x8c,0xcc,0xc8,0xcc,0xbb,0x56,0xd8,0xf6,0xf5, |
1879 | | 0x9c,0xe7,0x9c,0xfb,0x7c,0xf5,0x9c,0xe7,0x7c,0x90,0x5f,0xd7,0x7f,0xed,0xf5,0xb1, |
1880 | | 0xf7,0x5e,0xeb,0xba,0xae,0xb5,0xf6,0x8e,0x61,0xa6,0xf0,0x7a,0xd0,0x7e,0xdd,0xf0, |
1881 | | 0xba,0x77,0xbe,0x02,0xb3,0x70,0x97,0x9d,0xbd,0x5d,0x05,0xd7,0x42,0x3b,0x78,0xd6, |
1882 | | 0x09,0x7d,0x7c,0x13,0xc6,0x4d,0x95,0x02,0x3c,0x2b,0x6f,0x00,0x73,0x5d,0xd0,0x0e, |
1883 | | 0xdf,0x2a,0xc0,0x9c,0xe1,0x16,0xbc,0x3f,0xbc,0x8e,0x16,0xae,0xcd,0x3b,0x57,0x60, |
1884 | | 0x4c,0xc0,0xb5,0xd0,0x03,0xe3,0xfa,0x3a,0xf4,0x6f,0x2f,0x9c,0xc3,0xe7,0xd0,0x3f, |
1885 | | 0xe8,0x1f,0xda,0xe0,0x13,0xcf,0xf2,0xed,0x45,0x18,0x1f,0x0a,0x60,0xf9,0x0c,0xa6, |
1886 | | 0x16,0xe8,0xcb,0x86,0x5e,0x18,0x2b,0x30,0xb6,0x0c,0x70,0x6d,0x7d,0x01,0x7d,0xd9, |
1887 | | 0x3a,0x00,0xd7,0x08,0x2c,0xb7,0xc1,0x71,0x5f,0xf9,0x04,0xda,0xbb,0x0e,0xde,0x13, |
1888 | | 0xc6,0x58,0x3d,0x8c,0xf1,0xaf,0xe1,0xfa,0x56,0xc0,0x54,0x01,0xd7,0xf3,0x65,0xb8, |
1889 | | 0xa6,0x2e,0x43,0x9b,0xb6,0xc2,0xef,0xe0,0xb7,0xa0,0x0f,0xe0,0x77,0xab,0xf9,0xcf, |
1890 | | 0x6f,0x43,0xbf,0x40,0xdb,0x56,0x5c,0x85,0xf7,0x80,0xf7,0x82,0x6b,0xd8,0x52,0x05, |
1891 | | 0xfd,0x6a,0x44,0xfb,0x06,0xfc,0x1e,0x0f,0xd7,0xa5,0xa5,0xa1,0x1d,0xde,0x17,0xde, |
1892 | | 0x1b,0xda,0xc6,0xd2,0x0d,0xd7,0x79,0x79,0x0d,0xb4,0x23,0xb4,0x93,0x06,0xda,0xab, |
1893 | | 0xf2,0x26,0x8c,0x79,0xb8,0x7f,0x40,0x5b,0xcd,0xc2,0x27,0xe7,0xec,0x25,0x38,0x7e, |
1894 | | 0xf3,0x6d,0x30,0xdb,0x87,0x62,0x0e,0xda,0x4f,0x0d,0xe3,0x45,0x0b,0x7d,0x53,0x0d, |
1895 | | 0x8f,0x2f,0x99,0xe0,0x18,0xa1,0xbf,0xe0,0x5e,0xf4,0xac,0x0d,0xda,0xae,0x0d,0x8e, |
1896 | | 0xf3,0x8a,0x11,0x26,0xe8,0xef,0x0e,0x68,0x9f,0x6b,0x30,0xf6,0xbf,0x81,0x79,0x1f, |
1897 | | 0xec,0xd3,0x0f,0x8f,0x07,0x6f,0x82,0x39,0x05,0xdc,0xab,0x2a,0xbb,0xe0,0x7a,0x80, |
1898 | | 0x7e,0x30,0x7d,0x06,0xe6,0x5a,0xab,0xc1,0xdc,0x95,0x3a,0x30,0xd7,0x09,0xd7,0x55, |
1899 | | 0x27,0xac,0xeb,0xb9,0x08,0xe6,0x7a,0x61,0x9c,0xde,0x85,0x71,0xf6,0x05,0xf4,0xc1, |
1900 | | 0x57,0xdf,0xc1,0x58,0x83,0x31,0xa2,0x34,0x83,0xc5,0xd6,0xaa,0xeb,0x60,0x4e,0x0b, |
1901 | | 0x0d,0xde,0x77,0x05,0x6e,0x3c,0x70,0x11,0xc1,0x41,0xcf,0xdc,0x85,0x13,0x51,0xab, |
1902 | | 0x61,0x19,0xe6,0x55,0xd0,0xf8,0x55,0xd0,0x09,0xb5,0xb5,0x70,0xb2,0x0d,0xd0,0xc0, |
1903 | | 0xd0,0xc1,0x97,0x7a,0xe0,0x66,0xa9,0x82,0xa9,0x06,0x58,0x3a,0x60,0xb9,0x13,0x4e, |
1904 | | 0xfa,0xdb,0x4f,0x61,0x82,0xed,0x83,0x30,0x60,0xee,0x76,0xc1,0xc0,0xad,0x87,0x06, |
1905 | | 0x80,0x93,0x57,0xc1,0xc5,0xac,0x6e,0x86,0x01,0x07,0x17,0x1b,0x7c,0x60,0xcc,0x56, |
1906 | | 0x37,0x82,0x59,0xd3,0xa7,0xd0,0x20,0x75,0x70,0xf3,0xfb,0x02,0x06,0x14,0xcc,0xbf, |
1907 | | 0x85,0xf9,0xb7,0x30,0xf0,0x15,0xd0,0x41,0xf0,0xf1,0xfa,0x4c,0x6b,0x06,0xcf,0xf4, |
1908 | | 0x70,0x23,0x32,0x75,0x83,0x67,0x35,0x30,0xc8,0x6a,0xbe,0x05,0xcf,0xea,0x61,0x30, |
1909 | | 0xd5,0x7f,0x05,0x9d,0x09,0x37,0x60,0xb8,0x89,0x3f,0x6b,0x82,0x4e,0x6d,0x82,0x86, |
1910 | | 0xb8,0x0c,0x37,0xa6,0x6b,0xb0,0x5f,0x37,0xec,0x63,0x86,0x6d,0x03,0xd0,0xa9,0x46, |
1911 | | 0xe8,0x54,0xb4,0xe1,0x37,0xc1,0xc9,0xb7,0x41,0x23,0x5c,0x81,0x1b,0xe7,0x35,0xb8, |
1912 | | 0x99,0x7f,0x0d,0x03,0xee,0x6b,0x68,0xa8,0xeb,0x70,0x13,0x1c,0x80,0x0e,0x57,0xc2, |
1913 | | 0x4d,0x54,0xd3,0x00,0xe6,0x75,0xd0,0x30,0x0d,0xd0,0xe9,0xf0,0xb1,0x3b,0xdf,0x5c, |
1914 | | 0x05,0xe6,0x3b,0x3f,0x05,0x8b,0x97,0x5a,0xf4,0x48,0x54,0x60,0xf1,0x32,0x7c,0x46, |
1915 | | 0xfd,0x7c,0xbd,0x09,0xcc,0x28,0xa0,0x99,0x14,0xfd,0x60,0xb1,0x4d,0xa7,0x83,0xd2, |
1916 | | 0x53,0x0d,0x16,0xaf,0xc2,0xb0,0x9b,0x1f,0xac,0x00,0xf3,0x77,0x2f,0x80,0xac,0x2c, |
1917 | | 0x90,0xc5,0x03,0x59,0xf0,0xbd,0x19,0x65,0x30,0xcf,0x17,0x83,0xf1,0x5e,0xf4,0xc7, |
1918 | | 0x4b,0xbd,0xe8,0x8f,0x9e,0x7a,0xd1,0xdf,0x39,0xdd,0x5d,0x2b,0x76,0x81,0x1f,0x1a, |
1919 | | 0xfe,0xab,0x17,0xfc,0x70,0xf3,0xbf,0x6e,0x83,0x1f,0x2e,0x81,0x1f,0x6a,0xc0,0x0f, |
1920 | | 0x5f,0x80,0x1f,0x1a,0xc1,0x0f,0x4d,0xe0,0x87,0x76,0xf0,0xc3,0x35,0xf0,0x43,0xc7, |
1921 | | 0x0f,0x4a,0x24,0xe5,0x50,0xfe,0x6b,0xc0,0x7a,0x0c,0x33,0x58,0xaa,0x46,0x67,0x54, |
1922 | | 0xff,0x57,0x1f,0x92,0x01,0xf0,0x83,0x09,0xc9,0xa7,0x48,0x2e,0x22,0xa9,0x41,0x52, |
1923 | | 0x8b,0xa4,0x0e,0x49,0x3d,0x92,0x06,0x24,0x9f,0x23,0xf9,0x02,0x49,0x23,0x92,0x2f, |
1924 | | 0x91,0x34,0x23,0x69,0x41,0x72,0x19,0x49,0x2b,0x92,0x2b,0x48,0xae,0x22,0x69,0x47, |
1925 | | 0xd2,0x81,0xe4,0xda,0xda,0x45,0xfb,0xd1,0xdd,0xbe,0x43,0x57,0xf9,0x0e,0x75,0x86, |
1926 | | 0x52,0x0d,0x47,0x3c,0xd9,0x0d,0x26,0xbf,0x05,0x93,0x77,0xc1,0x8f,0x0a,0x30,0x79, |
1927 | | 0x07,0x4c,0x7e,0x07,0x26,0xfb,0xc1,0x8f,0xad,0xe0,0xc7,0x2b,0xe0,0x47,0x15,0xf8, |
1928 | | 0xb1,0x02,0xfc,0xa8,0x01,0x3f,0x56,0x82,0x1f,0x8d,0xe0,0x47,0x03,0xf8,0xf1,0x02, |
1929 | | 0xf8,0x51,0x0b,0x7e,0xac,0x07,0x3f,0x9a,0xc0,0x8f,0x1d,0xe0,0xc7,0x6f,0xc0,0x8f, |
1930 | | 0x3d,0xe0,0xc7,0x6e,0xf0,0xe3,0x1d,0xf0,0xe3,0xb7,0xe0,0x27,0x05,0xf8,0x49,0x09, |
1931 | | 0x7e,0xbc,0x0b,0x7e,0xfa,0x14,0xfc,0x74,0x11,0xfc,0xd8,0x05,0x7e,0xaa,0x04,0x3f, |
1932 | | 0x69,0xc0,0x4f,0x5a,0xf0,0x53,0x15,0xf8,0x49,0x0d,0x7e,0xd2,0x81,0x9f,0xaa,0xc1, |
1933 | | 0xa4,0x0e,0x4c,0x5c,0x99,0xb8,0x0a,0xe5,0xa7,0x5a,0x28,0x93,0x5a,0x74,0x54,0x89, |
1934 | | 0x44,0x83,0xc4,0x5a,0xac,0x46,0x0d,0xb0,0xb7,0x01,0x75,0xed,0x44,0xd2,0x85,0x6a, |
1935 | | 0xd4,0x48,0xf4,0x60,0xa2,0x1d,0xd5,0xb5,0xa3,0xba,0xf6,0x89,0xeb,0x50,0x50,0x43, |
1936 | | 0x3b,0xba,0x6e,0x3b,0x6a,0xbd,0x86,0x5a,0xaf,0xa1,0xd6,0x6b,0xa8,0xf5,0x1a,0x6a, |
1937 | | 0xbd,0x86,0x5a,0xaf,0xa1,0xd6,0xaf,0x51,0xeb,0xd7,0xa8,0xee,0x6b,0x54,0xf7,0x35, |
1938 | | 0xaa,0xeb,0x44,0x9d,0x3b,0x51,0x5d,0x17,0x6a,0xed,0x42,0x47,0xd7,0xd1,0xd1,0x75, |
1939 | | 0xd4,0x70,0x1d,0x15,0x7b,0x50,0xb1,0x07,0x15,0x7b,0xd0,0x45,0x7b,0x50,0x9d,0x19, |
1940 | | 0x15,0xcd,0xe8,0xe8,0x16,0x6a,0xbd,0x85,0x8a,0xb7,0x50,0xeb,0x2d,0x54,0x77,0x1b, |
1941 | | 0x15,0x6f,0xa3,0xa3,0x3e,0x24,0xfd,0xa8,0x4b,0x3f,0x3a,0xba,0x83,0x8e,0xee,0xc0, |
1942 | | 0xa3,0x49,0x25,0x3c,0x82,0xd2,0x85,0xe4,0x3a,0x14,0x6b,0x1d,0x1c,0x15,0x14,0x3d, |
1943 | | 0x98,0x2c,0x47,0x0d,0xe5,0xa8,0xae,0x1c,0xd5,0x95,0xa3,0xba,0x0a,0x68,0x38,0x28, |
1944 | | 0x9d,0x48,0xba,0x90,0xc0,0xd3,0x2a,0x26,0x55,0x48,0xd4,0x48,0x74,0x48,0x60,0x3f, |
1945 | | 0x15,0xea,0xa2,0x42,0x5d,0x54,0xa8,0x8b,0x0a,0xb5,0xaa,0x50,0xab,0x0a,0xb5,0xaa, |
1946 | | 0x51,0xab,0x1a,0xb5,0xaa,0x51,0xab,0x1a,0xb5,0xaa,0x51,0xab,0x1a,0xb5,0x6a,0x50, |
1947 | | 0xab,0x06,0xb5,0x6a,0x50,0xab,0x06,0xb5,0x6a,0x50,0xab,0x06,0xb5,0x56,0xa2,0xd6, |
1948 | | 0x4a,0x54,0x57,0x89,0xea,0x2a,0x51,0x9d,0x1e,0xd5,0xe9,0xd1,0x19,0x7a,0x74,0x86, |
1949 | | 0x1e,0xb5,0xea,0x51,0xab,0x1e,0x59,0xf7,0xc6,0xe4,0x0d,0x30,0xd1,0x0d,0x65,0x52, |
1950 | | 0x07,0xc5,0x73,0xd2,0x30,0x69,0x82,0x6a,0xb4,0xea,0x05,0xab,0x7e,0x62,0xd5,0x6a, |
1951 | | 0xab,0x9a,0x50,0xef,0x2b,0x13,0xdd,0x48,0x6e,0x22,0x7f,0x6b,0x90,0x97,0xbb,0x91, |
1952 | | 0xdc,0x44,0x0e,0xd6,0x20,0xb7,0x76,0x23,0xb9,0x89,0x3c,0xaa,0x41,0x1e,0xed,0x46, |
1953 | | 0x72,0x13,0x39,0x53,0x83,0xa6,0x74,0x15,0x8d,0xbc,0x1b,0xc9,0x4d,0x34,0x68,0x0d, |
1954 | | 0x1a,0x56,0x37,0x92,0x9b,0x68,0x44,0x28,0xca,0x90,0x93,0xae,0x4c,0x56,0xa2,0xeb, |
1955 | | 0x55,0xa2,0xab,0x54,0x22,0x67,0x5a,0xed,0x54,0x89,0xce,0xa8,0x44,0xf3,0xba,0x81, |
1956 | | 0x3a,0x57,0xa2,0x8b,0x56,0x22,0x7f,0x43,0xe9,0x45,0xde,0xeb,0x45,0xad,0x0a,0xeb, |
1957 | | 0xc0,0x61,0xf6,0xc9,0x5a,0x86,0x86,0x0e,0x7d,0xad,0x43,0xa2,0x47,0x6e,0xd6,0x21, |
1958 | | 0xd1,0x23,0x37,0xeb,0x90,0xe8,0xd1,0x15,0x74,0x48,0xf4,0xe8,0x0a,0x3a,0x24,0x7a, |
1959 | | 0x14,0x68,0x3a,0x24,0x28,0x02,0xd1,0x51,0x27,0x3a,0xba,0x8e,0x8e,0xae,0xa3,0x23, |
1960 | | 0x33,0x3a,0x32,0xa3,0xa3,0x5b,0xe8,0xe8,0x96,0xf5,0x5c,0x14,0x3b,0xbd,0x28,0xb2, |
1961 | | 0x7a,0xd1,0x1c,0x7a,0xd1,0xd4,0x7b,0x90,0x98,0x91,0xdc,0x42,0x72,0x75,0xb2,0xca, |
1962 | | 0xba,0x06,0xac,0x61,0xbf,0x16,0xd0,0xd7,0xd6,0x42,0xfa,0xda,0x5a,0x28,0x5f,0xb3, |
1963 | | 0xfa,0xdf,0x9a,0x75,0xad,0x65,0xd7,0xad,0xd1,0x8f,0x4a,0x5d,0xd6,0x10,0xb0,0x66, |
1964 | | 0x3a,0x6b,0xbc,0xaf,0x85,0x7d,0xe7,0x5a,0xe0,0x77,0xae,0xcd,0xc1,0xda,0xb3,0x67, |
1965 | | 0xed,0x2a,0x3d,0xd6,0xe8,0x41,0x4b,0x01,0x5b,0x0c,0x56,0x1b,0xad,0xdd,0xaf,0x77, |
1966 | | 0x6d,0x46,0xbd,0x6b,0x77,0xe8,0x5d,0x6b,0xbb,0xb5,0x36,0xeb,0x5b,0x6b,0x63,0xb9, |
1967 | | 0xbd,0x76,0xb1,0xdb,0x6b,0x6d,0xb7,0xd7,0xee,0xde,0xbf,0x36,0xf8,0xfe,0xb5,0xca, |
1968 | | 0xfe,0xb5,0xb1,0xdc,0x59,0x2b,0xdd,0x59,0xeb,0x72,0x67,0x2d,0x5e,0x95,0xd6,0xab, |
1969 | | 0xa0,0x45,0x82,0xad,0x15,0x6b,0x9c,0x5b,0xef,0x6e,0xcd,0xf4,0x6b,0x99,0xce,0xba, |
1970 | | 0x20,0xd6,0x96,0xc4,0xf5,0xb5,0xa5,0x80,0x45,0x7f,0x17,0xb6,0x12,0xac,0x2b,0x60, |
1971 | | 0xed,0x04,0xb5,0x75,0xb6,0x28,0x5b,0xab,0xbc,0xbe,0xd6,0xe5,0xfa,0x5a,0xa9,0x13, |
1972 | | 0x85,0x49,0xe5,0xda,0x0a,0xaa,0x5c,0xbb,0x9f,0x66,0xed,0x74,0xcd,0xda,0x8d,0x34, |
1973 | | 0x6b,0xe7,0x69,0xac,0xc6,0x42,0x8b,0xc7,0xba,0xa4,0xd6,0x86,0xab,0x5f,0x9b,0x43, |
1974 | | 0xfb,0x9a,0x7f,0xaf,0xad,0x99,0xe7,0xda,0x9a,0x59,0xaf,0xbd,0xae,0xbc,0xbe,0xb6, |
1975 | | 0x55,0x59,0xa7,0x79,0x6d,0x6d,0xee,0x9d,0x6b,0xa5,0xce,0x35,0xd3,0x75,0xbe,0x76, |
1976 | | 0x8e,0xb5,0xa7,0x79,0x2d,0x80,0x7a,0xd7,0xb2,0x5b,0xaf,0x27,0xdd,0x69,0xcd,0xd6, |
1977 | | 0xee,0xae,0x5f,0xab,0xd4,0xaf,0x55,0xea,0xd7,0x2a,0xd5,0x6b,0x59,0xf9,0xeb,0x35, |
1978 | | 0xdf,0xb5,0x16,0xb8,0xd6,0x52,0xc5,0x2f,0x1b,0x01,0xb6,0x47,0xbc,0xbe,0xa6,0x7a, |
1979 | | 0xad,0x4d,0xbd,0x36,0x16,0xbd,0x75,0xbf,0xc4,0x6c,0x86,0x32,0xe5,0xda,0x38,0xdb, |
1980 | | 0xd7,0xda,0x7a,0xd6,0xce,0xd3,0xac,0x4d,0xd3,0x3c,0xa9,0x82,0xcf,0x05,0x78,0x3f, |
1981 | | 0x94,0xc1,0x20,0x55,0x59,0x17,0x1b,0x3c,0xa8,0xb0,0x2e,0xef,0x35,0x27,0x4c,0x7c, |
1982 | | 0x63,0xed,0xb8,0xb6,0x4f,0x76,0xc3,0xe0,0xd2,0xc2,0xbd,0x0d,0x96,0x54,0xd6,0xa5, |
1983 | | 0x38,0xa9,0x85,0x35,0x2a,0x6b,0xb8,0x59,0x37,0xb3,0xb5,0xcc,0xf3,0xf5,0xc5,0x3c, |
1984 | | 0x5f,0x77,0xf4,0xfc,0xff,0x3b,0x76,0x4e,0xaa,0x3c,0x91,0x58,0xfb,0xc0,0xdb,0x75, |
1985 | | 0xff,0x64,0x40,0x87,0xc0,0x0f,0xfc,0xac,0x50,0x82,0x20,0xe0,0x05,0x3e,0x84,0x47, |
1986 | | 0x75,0x30,0x7d,0x06,0x7e,0xa3,0x40,0x7f,0x56,0x75,0x11,0x9c,0x05,0x25,0x40,0x0e, |
1987 | | 0x6b,0x6a,0x60,0x82,0x2f,0x0e,0x8a,0x6a,0x98,0x4c,0x30,0xe9,0x61,0xaa,0x82,0xc9, |
1988 | | 0x00,0x93,0x11,0xa6,0x0b,0x30,0x7d,0x02,0x4e,0x83,0x54,0xb0,0x0f,0xec,0x07,0x07, |
1989 | | 0x01,0x09,0x04,0x83,0x0f,0x40,0x0a,0xf0,0x06,0x44,0x10,0x0a,0x77,0xb2,0x2a,0xb4, |
1990 | | 0x33,0x54,0xa1,0x0d,0x0f,0x6d,0x77,0x68,0xb3,0xb3,0x6e,0x1c,0x68,0xbf,0xb3,0x6e, |
1991 | | 0x1d,0x68,0xcb,0xb3,0x6e,0x1e,0x68,0xd7,0x43,0x07,0x68,0xfb,0xfb,0x14,0x1d,0x40, |
1992 | | 0x03,0xb5,0x80,0x89,0x4b,0x60,0xe2,0x32,0x98,0x68,0x05,0x13,0x6d,0x70,0xb3,0x02, |
1993 | | 0xe8,0x89,0xd9,0x0e,0x26,0x3a,0x60,0x50,0xc0,0x3d,0x09,0x58,0x9f,0x53,0x00,0xad, |
1994 | | 0x2b,0x68,0x32,0xb4,0xbf,0x02,0xb4,0x01,0xf6,0xc0,0x40,0x80,0x66,0x81,0x71,0x00, |
1995 | | 0x17,0x13,0x7c,0xf0,0x40,0xdb,0xc1,0xb5,0x02,0x1d,0x03,0x0d,0x0f,0x5d,0x07,0xd0, |
1996 | | 0x93,0x02,0x05,0x27,0xb0,0x5a,0x13,0xac,0xb9,0xf5,0x12,0x92,0xcb,0x48,0xda,0x90, |
1997 | | 0x5c,0x05,0x7b,0xc1,0x01,0x10,0x00,0xce,0x00,0x19,0x28,0x05,0xbf,0xb9,0xa2,0x86, |
1998 | | 0x09,0xfd,0xa2,0x83,0x7e,0xe9,0x41,0x3f,0xa4,0x5c,0x86,0xa9,0x0d,0xa6,0xab,0x30, |
1999 | | 0xa1,0x7f,0xc8,0x85,0xe5,0x0a,0x58,0x86,0xef,0xd6,0x3f,0x57,0x54,0x80,0xb5,0x7f, |
2000 | | 0xd2,0x45,0x3f,0x28,0x34,0x00,0xf4,0xc3,0xf8,0x7f,0x5c,0x02,0xff,0x71,0x19,0xfc, |
2001 | | 0x47,0x27,0xf8,0x8f,0x2b,0xe0,0x3f,0xda,0xc0,0x6f,0xe0,0x29,0xbf,0xa9,0x29,0x07, |
2002 | | 0xbf,0x81,0x5f,0xdb,0x7e,0xa3,0x31,0xc1,0xf4,0x29,0x4c,0x17,0xc1,0x6f,0xea,0x9a, |
2003 | | 0xc1,0x6f,0x3e,0xab,0x02,0x8b,0xd5,0xd5,0xed,0x48,0x3a,0x90,0x5c,0x43,0xf2,0x35, |
2004 | | 0x92,0x4e,0x24,0x5d,0x48,0xae,0x23,0xf9,0x06,0xc9,0x0d,0x24,0xdd,0x48,0x6e,0x22, |
2005 | | 0xe9,0x41,0xd2,0x8b,0xc4,0x8c,0xe4,0x16,0x92,0xdb,0x48,0xfa,0x90,0xf4,0x23,0xb9, |
2006 | | 0x83,0xe4,0x5b,0x24,0x03,0x48,0x06,0x91,0xdc,0x45,0xf2,0x1d,0x14,0x93,0x02,0x89, |
2007 | | 0x12,0x49,0x39,0x92,0x0a,0x24,0x2a,0x24,0x6a,0x24,0x1a,0x24,0x95,0x48,0xb4,0x48, |
2008 | | 0x74,0x48,0xf4,0x48,0xd0,0x98,0x4d,0x06,0x24,0x46,0x24,0x17,0x90,0x7c,0x02,0xe5, |
2009 | | 0x62,0x3d,0x92,0x06,0x24,0x9f,0x23,0xf9,0x02,0x49,0x23,0x92,0x26,0x24,0x5f,0x22, |
2010 | | 0xf9,0x0a,0x49,0x33,0x92,0x16,0x24,0x97,0x90,0x5c,0x46,0xd2,0x8a,0xa4,0x0d,0xc9, |
2011 | | 0x15,0x24,0x57,0x91,0x20,0xbb,0x5c,0x44,0x76,0xb9,0x88,0xec,0x72,0x11,0xd9,0xe5, |
2012 | | 0x22,0xb2,0xcb,0x45,0x64,0x97,0x8b,0xc8,0x2e,0x17,0x91,0x5d,0x2e,0x22,0xbb,0x5c, |
2013 | | 0x44,0x76,0xb9,0x88,0xec,0x72,0x11,0xd9,0xe5,0x22,0xb2,0xcb,0x45,0x64,0x97,0x8b, |
2014 | | 0xc8,0x2e,0x17,0x91,0x5d,0x2e,0x22,0xbb,0x5c,0x44,0x76,0xb9,0x88,0xec,0x72,0x11, |
2015 | | 0xd9,0xa5,0xee,0x33,0x24,0x68,0xe0,0x75,0x68,0xe0,0x75,0x68,0xe0,0x75,0x68,0xe0, |
2016 | | 0x75,0x68,0xe0,0x75,0x68,0xe0,0x75,0x68,0xe0,0x75,0x68,0xe0,0x75,0x68,0xe0,0x75, |
2017 | | 0x68,0xe0,0x75,0x68,0xcc,0x75,0x68,0xcc,0x75,0x68,0xcc,0x75,0x68,0xcc,0x75,0x68, |
2018 | | 0xcc,0x75,0x68,0xcc,0x75,0x68,0xcc,0x75,0x68,0xcc,0x75,0x68,0xcc,0x75,0x68,0xcc, |
2019 | | 0x75,0x68,0xcc,0x75,0x68,0xcc,0x75,0x68,0xcc,0x75,0x68,0xcc,0x75,0x68,0xcc,0x75, |
2020 | | 0x68,0xb8,0x75,0x68,0xb8,0x75,0x68,0xb8,0x75,0x68,0xb8,0x75,0x68,0xb8,0x75,0x68, |
2021 | | 0xb8,0x75,0x68,0xb8,0x75,0xd6,0x91,0x0e,0x80,0xff,0x5d,0x0d,0xfe,0xb7,0x09,0x7c, |
2022 | | 0xdf,0x00,0xbe,0xbf,0x0c,0xfe,0xbb,0xeb,0x0a,0xf8,0xbe,0x0d,0x7c,0xdf,0x0a,0xa6, |
2023 | | 0x6f,0x99,0xc0,0x48,0x3d,0x18,0xf9,0x12,0x7c,0xdf,0x01,0x46,0x2e,0x81,0xef,0xbf, |
2024 | | 0x00,0xdf,0x37,0x82,0x91,0xab,0xe0,0x7b,0x15,0xf8,0xfe,0x1a,0xf8,0x1e,0x0e,0xa1, |
2025 | | 0x69,0x40,0x05,0xfe,0xfb,0xcb,0x0b,0x60,0xe4,0x3a,0x3a,0x56,0x83,0xef,0x2f,0xa0, |
2026 | | 0x5c,0x03,0x46,0x6e,0x81,0x91,0xdb,0x60,0xe4,0x0e,0x2a,0x69,0xc1,0xc8,0x5d,0xf0, |
2027 | | 0x7d,0x3b,0xf8,0xfe,0x0a,0xbc,0x36,0x3c,0xf9,0x2a,0xf8,0x4d,0x77,0x37,0xf8,0xfe, |
2028 | | 0x13,0xf0,0x7d,0x0b,0xf8,0x1e,0x5e,0xb5,0x1e,0xfc,0xa7,0x02,0xfc,0xa7,0x12,0xfc, |
2029 | | 0x67,0x39,0xea,0xad,0x47,0x82,0x0c,0xd3,0x83,0x82,0xa8,0x07,0x05,0x51,0x0f,0x0a, |
2030 | | 0xa2,0x1e,0x14,0x44,0x3d,0x28,0x88,0x7a,0x50,0x10,0xf5,0xa0,0x20,0xea,0x41,0x41, |
2031 | | 0xd4,0x83,0x82,0xa8,0x07,0x05,0x51,0x0f,0x0a,0xa2,0x1e,0x14,0x44,0x3d,0x28,0x88, |
2032 | | 0x7a,0x50,0x10,0xf5,0xa0,0x20,0xea,0x41,0x41,0x84,0xbe,0xa2,0x54,0xf7,0x98,0x90, |
2033 | | 0x7c,0x8a,0xe4,0x22,0x92,0x1a,0x24,0xb5,0x48,0xea,0x90,0x20,0x9f,0xf5,0x20,0x9f, |
2034 | | 0xf5,0x20,0x9f,0xf5,0x20,0x9f,0xf5,0x20,0x9f,0xf5,0x20,0x9f,0xf5,0x20,0x9f,0xf5, |
2035 | | 0x58,0x87,0x86,0x7c,0xd6,0x83,0x7c,0xd6,0x83,0x7c,0xd6,0x83,0x82,0xad,0x07,0x39, |
2036 | | 0xae,0x07,0x39,0xae,0x07,0x39,0xae,0x07,0x39,0xae,0x07,0x39,0xae,0x07,0x39,0xae, |
2037 | | 0x07,0x39,0xae,0x07,0x39,0xae,0x07,0x39,0xae,0x07,0x39,0xae,0x07,0x39,0xae,0x07, |
2038 | | 0x39,0xae,0x07,0x39,0xae,0x07,0x39,0xae,0x07,0x39,0xae,0x07,0x05,0x9b,0x19,0x15, |
2039 | | 0xcd,0xa8,0x68,0xb6,0x16,0x91,0x33,0xcd,0xc8,0x99,0x66,0xe4,0x4c,0x33,0x72,0xa6, |
2040 | | 0x19,0x39,0xd3,0x8c,0x9c,0x69,0x46,0xce,0x34,0xa3,0xd8,0x33,0x23,0x8f,0x9a,0xd1, |
2041 | | 0x9a,0x34,0xa3,0x35,0x69,0x46,0x6b,0xd2,0x8c,0xd6,0xe4,0x2d,0x64,0xce,0x5b,0xc8, |
2042 | | 0x9c,0xb7,0x90,0x39,0x6f,0x21,0x73,0xde,0x42,0xe6,0xbc,0x05,0xcd,0x69,0xba,0xac, |
2043 | | 0x40,0xa2,0x44,0x52,0x8e,0xa4,0x02,0x89,0x0a,0x89,0xb5,0x55,0x83,0xa4,0x12,0x89, |
2044 | | 0x16,0x89,0x0e,0x89,0x1e,0x49,0x15,0x12,0x03,0x12,0x23,0x92,0x0b,0x48,0x3e,0x41, |
2045 | | 0x52,0x8d,0xc4,0x84,0xe4,0x53,0x24,0x17,0x91,0xd4,0x20,0xa9,0x45,0x52,0x87,0xe4, |
2046 | | 0x33,0x24,0xf5,0x48,0x1a,0x90,0x7c,0x8e,0xe4,0x0b,0x24,0x8d,0x48,0x9a,0x90,0x7c, |
2047 | | 0x89,0x04,0x1a,0xbb,0xae,0xbf,0x19,0x49,0x0b,0x92,0x4b,0x48,0x2e,0x23,0x69,0x45, |
2048 | | 0xd2,0x86,0xe4,0x0a,0x92,0xab,0x48,0xda,0x91,0x74,0x20,0xb9,0x86,0xe4,0x6b,0x24, |
2049 | | 0x9d,0x48,0xba,0x90,0x5c,0x47,0xf2,0x0d,0x92,0x1b,0x48,0xba,0x91,0xdc,0x44,0xd2, |
2050 | | 0x83,0xa4,0x17,0x89,0x19,0xc9,0x2d,0x24,0xb7,0x91,0xf4,0x21,0xe9,0x47,0x72,0x07, |
2051 | | 0xc9,0xb7,0x48,0x06,0x90,0x0c,0x22,0xb9,0x8b,0x04,0x5a,0xb7,0xee,0x0e,0x6a,0xb8, |
2052 | | 0x83,0x1a,0xee,0xa0,0x86,0x3b,0xa8,0xe1,0x0e,0x6a,0xf8,0x56,0x81,0x44,0x89,0xa4, |
2053 | | 0x1c,0x49,0x05,0x12,0x15,0x12,0x35,0x12,0x0d,0x92,0x4a,0x24,0x5a,0x24,0x3a,0x24, |
2054 | | 0x7a,0x24,0x55,0x48,0x0c,0x48,0x8c,0x48,0x2e,0x20,0xf9,0x04,0x49,0x35,0x12,0x13, |
2055 | | 0x92,0x4f,0x91,0x40,0xc3,0x36,0xa9,0x3f,0x83,0xa9,0x0d,0x1d,0xd4,0xff,0xd6,0x01, |
2056 | | 0x4c,0xd7,0xdf,0x2c,0x7c,0xf3,0x66,0xe1,0xc6,0x9b,0x85,0xee,0x37,0x0b,0xd0,0x20, |
2057 | | 0x4d,0x9a,0x7e,0xec,0x4a,0x9a,0x3b,0xaf,0x0f,0xfa,0xdf,0xb8,0xe4,0x5a,0xed,0xeb, |
2058 | | 0x42,0xff,0x1b,0xd7,0xff,0xa5,0xe5,0x1b,0x70,0xbf,0x1b,0x3c,0xb8,0x0d,0x7e,0xa3, |
2059 | | 0xad,0x84,0x09,0xce,0xfd,0xcb,0xd6,0x4b,0x48,0x2e,0x23,0x69,0x45,0xd2,0x86,0xe4, |
2060 | | 0x0a,0x92,0xab,0x48,0xda,0x91,0x74,0x20,0xb9,0x86,0xe4,0x6b,0x24,0x9d,0x48,0xba, |
2061 | | 0x90,0x5c,0x47,0xf2,0x0d,0x92,0x1b,0x48,0xba,0x91,0xdc,0x44,0xd2,0x83,0xa4,0x17, |
2062 | | 0x89,0x19,0xc9,0x2d,0x24,0xb7,0x91,0xf4,0x21,0xe9,0x47,0x72,0x07,0xc9,0xb7,0x48, |
2063 | | 0x06,0x90,0x0c,0x22,0xb9,0x8b,0x04,0x3a,0xe8,0xcb,0x36,0x05,0x12,0x25,0x12,0x34, |
2064 | | 0xc8,0x36,0xf8,0x60,0xbf,0x0e,0x7e,0x6c,0x01,0x93,0xdf,0x00,0xb2,0x1f,0xa0,0xf8, |
2065 | | 0x81,0x77,0xfd,0xc0,0x21,0x3f,0x40,0xf5,0x03,0x34,0x3f,0xf0,0x9e,0x1f,0x78,0xdf, |
2066 | | 0x0f,0x04,0xfa,0x01,0x3a,0x7a,0xe9,0xa9,0xc9,0x47,0x2f,0x35,0x85,0xc5,0x80,0x5b, |
2067 | | 0x00,0xf2,0x33,0x40,0x7e,0x3e,0x10,0x0a,0x0b,0x40,0xe1,0xc7,0x40,0x00,0xff,0xcb, |
2068 | | 0x00,0x82,0x3c,0x90,0x91,0x0d,0x7e,0x56,0x7e,0xfb,0xb3,0xb2,0xca,0xfa,0x1b,0x7f, |
2069 | | 0x39,0xfa,0x9b,0xcd,0xcf,0x80,0xe5,0x13,0xf4,0x47,0x1c,0x95,0xc0,0xd2,0xfa,0x39, |
2070 | | 0x98,0xbb,0x7a,0x19,0xcc,0xdc,0x69,0x05,0xb3,0xf5,0xcd,0xe0,0x99,0xaa,0x05,0x58, |
2071 | | 0x74,0x46,0x60,0xb9,0x6b,0x00,0x16,0x8d,0x11,0xcc,0xc2,0xad,0xdc,0xa2,0x6d,0x02, |
2072 | | 0xcf,0xcc,0xe5,0x60,0xee,0x66,0x07,0xb0,0x5c,0x86,0x65,0xf8,0xf4,0x9d,0x1d,0xa8, |
2073 | | 0x01,0xb3,0xfa,0x5a,0x30,0x6b,0xac,0x05,0xf3,0x4a,0x3d,0x98,0x35,0x54,0x82,0x59, |
2074 | | 0xdd,0x45,0xf0,0xec,0x8a,0x12,0x3c,0xeb,0x40,0xff,0xd4,0xa8,0x05,0xb3,0x77,0x14, |
2075 | | 0xe0,0x59,0x0d,0xbc,0x9f,0xee,0x26,0xb0,0xc0,0x9d,0x7f,0x5e,0x8d,0xde,0xb2,0x6a, |
2076 | | 0x66,0x1b,0x3b,0xd7,0xde,0xc3,0x6a,0x66,0xfa,0x74,0xaf,0x8f,0xee,0x18,0xb0,0x23, |
2077 | | 0xcb,0xf5,0xd7,0x75,0xcf,0xca,0xfb,0xb1,0x23,0x78,0xe1,0xd7,0x75,0x5f,0x7c,0xf6, |
2078 | | 0xba,0x5f,0x55,0xd3,0xeb,0xd6,0x5a,0x6b,0x9d,0xe5,0x2e,0x9a,0xd5,0x37,0x60,0xa6, |
2079 | | 0x6f,0x10,0xa6,0x3e,0x30,0xd3,0x0f,0xed,0xd9,0xac,0xba,0x04,0x66,0x06,0x9b,0xc1, |
2080 | | 0xcc,0xdd,0x6f,0x81,0x45,0x51,0x0e,0x2c,0x4a,0x38,0x34,0xf8,0x26,0x63,0x41,0xbf, |
2081 | | 0xa1,0x7f,0x0a,0x57,0x76,0x73,0x3d,0xac,0x50,0xa3,0x3f,0x11,0x6a,0x85,0x09,0xfa, |
2082 | | 0xac,0xb9,0xa6,0x11,0xb6,0xf4,0xc3,0x02,0x0c,0x88,0xe6,0xda,0x2a,0x68,0x05,0x78, |
2083 | | 0x5d,0x4d,0x2b,0x98,0xf9,0x16,0x59,0x04,0x06,0x43,0x47,0xe5,0x57,0xd0,0x24,0xf0, |
2084 | | 0xcd,0xe8,0x22,0xca,0xe1,0x75,0x75,0x1a,0x98,0x6e,0x83,0x9f,0x6b,0xd0,0x9f,0xd4, |
2085 | | 0xaa,0x61,0x82,0x65,0xa3,0x0e,0xa6,0xcf,0x61,0x82,0xd3,0x37,0x0e,0xc2,0x04,0xdd, |
2086 | | 0xdc,0xdc,0xde,0x09,0x9e,0x29,0xa1,0xfd,0x3e,0xd1,0xc3,0x04,0x77,0x94,0x66,0xf4, |
2087 | | 0x77,0x44,0x9f,0x7c,0x0d,0x53,0x37,0x34,0x18,0x3c,0x0b,0x8e,0xc8,0x02,0xdf,0x6f, |
2088 | | 0x2c,0xf0,0x9d,0xc4,0x62,0x6a,0x87,0xe5,0x4b,0xc0,0x02,0x9f,0xf0,0x96,0x9a,0x6a, |
2089 | | 0x60,0xa9,0xbd,0x08,0x13,0xec,0x5f,0xa7,0x82,0x09,0x9e,0x03,0x9f,0xac,0x96,0xcf, |
2090 | | 0xe0,0x8c,0x1a,0xeb,0x60,0x82,0x43,0x6c,0x30,0xc1,0xd4,0x0b,0x1d,0x74,0x1d,0x58, |
2091 | | 0xbe,0xba,0x00,0x13,0x3c,0x6e,0x86,0x8e,0xfc,0x12,0x4e,0xa1,0x19,0x3a,0xa0,0x19, |
2092 | | 0xde,0xe3,0x12,0x1c,0x7e,0x0b,0x7c,0x19,0xb1,0x5c,0x86,0x15,0x97,0x6f,0x43,0xef, |
2093 | | 0xc3,0x9b,0xc2,0x25,0x61,0x69,0x83,0xcb,0xa2,0xe5,0x73,0x18,0xfd,0x2d,0x5f,0x5c, |
2094 | | 0x03,0x96,0xab,0x9d,0xc0,0xd2,0xfe,0x05,0x4c,0x57,0xe1,0x71,0x3d,0xb0,0x74,0x5c, |
2095 | | 0x01,0x3f,0x7f,0x71,0x1d,0xa6,0x01,0x60,0xe9,0x84,0x43,0xeb,0x84,0x81,0xdb,0x72, |
2096 | | 0x15,0x1e,0x7c,0x53,0x01,0x13,0xec,0xf0,0x0d,0x5c,0x00,0x2d,0x9d,0xe8,0xe0,0x3b, |
2097 | | 0x60,0xb9,0x01,0xaf,0x39,0x78,0x11,0xfc,0xfc,0xa5,0x12,0x58,0xba,0x9b,0x81,0x05, |
2098 | | 0x3e,0x43,0x2d,0x37,0xe1,0x06,0xd2,0x72,0x1b,0xde,0xd8,0x5c,0x81,0x0e,0xae,0xc0, |
2099 | | 0x03,0x38,0x4c,0x33,0x9c,0x06,0x7c,0x4c,0x58,0x6e,0xc3,0x98,0xbb,0x7d,0x09,0xfc, |
2100 | | 0xdc,0xfc,0x0d,0xcc,0xa1,0xb1,0xfa,0xe0,0xd4,0xa1,0x17,0x2d,0x70,0x0f,0xfd,0xb9, |
2101 | | 0x05,0x8e,0xec,0x92,0x06,0x5a,0xbb,0x05,0x76,0xbc,0x03,0x8d,0x77,0x07,0xce,0xfb, |
2102 | | 0x0e,0x5c,0x61,0xd7,0x2e,0xa0,0x7f,0x13,0x34,0x74,0x83,0x39,0x2d,0xbc,0xd1,0x00, |
2103 | | 0x3c,0x1d,0x3d,0x1c,0x2e,0xeb,0xe1,0x92,0xbb,0x52,0x09,0x2d,0x8f,0x7e,0x4f,0x18, |
2104 | | 0xfc,0x1a,0xd6,0x42,0x9b,0xdd,0x85,0xe5,0xef,0xa0,0x2d,0xbe,0x83,0x76,0xfa,0x0e, |
2105 | | 0x06,0x6f,0xb9,0x12,0xfc,0x0c,0x57,0xe4,0xcf,0xad,0x70,0x97,0xbf,0xf4,0x05,0x8c, |
2106 | | 0x64,0xb8,0x12,0x66,0xd5,0xe8,0xdf,0x45,0x0d,0x30,0xdd,0x01,0xb3,0x9a,0x9b,0x30, |
2107 | | 0xc1,0x15,0xa1,0xf9,0x06,0xcc,0x56,0xa2,0x7f,0x9c,0x47,0x3f,0x4a,0x7c,0x01,0x23, |
2108 | | 0xbc,0x09,0x46,0x7d,0x37,0x98,0xad,0x82,0xe7,0x18,0xe1,0x2e,0x78,0xa9,0x13,0x9e, |
2109 | | 0x60,0x18,0x84,0x15,0x03,0xb0,0xa2,0x1d,0xcc,0x5e,0xa8,0x00,0xb3,0x9f,0xc0,0x9d, |
2110 | | 0xe5,0xd2,0x37,0xb0,0x57,0xf5,0x25,0x58,0x50,0xc3,0x4a,0x38,0x8f,0xf6,0xeb,0x60, |
2111 | | 0xd6,0xd4,0x01,0xd3,0x5d,0x30,0xfb,0x29,0xbc,0x8a,0x09,0x06,0x4c,0x47,0x27,0x98, |
2112 | | 0xad,0x85,0x2e,0xb9,0x0c,0xbf,0x8a,0xcc,0x7e,0x76,0x19,0xcc,0x7e,0xd1,0x07,0x66, |
2113 | | 0x1b,0x74,0xe0,0xe7,0x4e,0xf8,0xae,0x0d,0x0d,0xfd,0xf3,0xd7,0xd0,0x62,0xf0,0x85, |
2114 | | 0xda,0xa2,0x81,0x0b,0xad,0x51,0x01,0x66,0x3f,0x6f,0x04,0x73,0xe5,0x5d,0x60,0xe6, |
2115 | | 0x93,0x06,0x58,0x6e,0x01,0xb3,0x4d,0x70,0x68,0x4d,0x17,0xd1,0x3f,0x88,0x42,0x03, |
2116 | | 0x75,0xe9,0xc0,0xec,0x57,0x70,0xec,0x5f,0xc2,0x3b,0xb6,0x40,0xdb,0x5c,0x36,0x75, |
2117 | | 0x81,0xd9,0x4b,0x17,0xc0,0x6c,0xf3,0x57,0x60,0xb6,0x15,0x0e,0x18,0xee,0x2d,0xb3, |
2118 | | 0x57,0xe0,0x5d,0xae,0x5e,0x03,0xb3,0xd7,0xa0,0xaf,0x2f,0x7f,0x0e,0x0b,0x5f,0x7f, |
2119 | | 0x01,0x7e,0xbe,0x51,0x0f,0x66,0x3b,0xe1,0x73,0xed,0xf2,0xa5,0xab,0x60,0xb6,0x0b, |
2120 | | 0x7e,0x4d,0xea,0x86,0x67,0x75,0x41,0x13,0x5c,0x87,0x67,0x5e,0x87,0x9b,0xd6,0xe5, |
2121 | | 0x6b,0xc8,0x7f,0xbd,0xf0,0x79,0x70,0xf9,0x6b,0x78,0x07,0xd8,0xbc,0x78,0xf9,0x26, |
2122 | | 0x9c,0xf1,0xcd,0xef,0xc0,0x2c,0x7c,0xc3,0x99,0xed,0x86,0xe7,0xf5,0xd6,0xc1,0x04, |
2123 | | 0x27,0x67,0x86,0x93,0x84,0xef,0x03,0xb3,0xe8,0x91,0x7e,0x19,0xfd,0x28,0xd0,0xdb, |
2124 | | 0x0b,0x66,0xfb,0xa0,0x1d,0xe1,0x83,0xef,0xe7,0xde,0x1e,0x30,0x8b,0x1e,0x35,0x97, |
2125 | | 0xe1,0xd3,0x63,0xf6,0x36,0xf4,0xc4,0x20,0xdc,0x53,0x2f,0x0f,0xc2,0x85,0x78,0xf9, |
2126 | | 0x2e,0xbc,0xe7,0x77,0x1a,0xf0,0x4c,0xd1,0x0f,0x13,0x1c,0xd4,0xad,0x3a,0xb8,0x58, |
2127 | | 0xf4,0x30,0x0d,0xc2,0x74,0x1b,0x3c,0x83,0xf3,0x86,0x8b,0xb3,0x0d,0x3c,0x53,0xc3, |
2128 | | 0x0b,0xb7,0xea,0x2e,0x83,0x67,0x1a,0xe8,0xbd,0xd6,0x0b,0xe8,0x6f,0xb8,0xdb,0xc1, |
2129 | | 0x33,0x1d,0xf4,0x46,0x6b,0xbd,0x16,0x3c,0xd3,0xc3,0x4d,0x07,0x6e,0x4c,0x8b,0xad, |
2130 | | 0x8d,0xe8,0x1f,0xd3,0x9b,0x6b,0xc0,0x33,0xe3,0x1d,0xf0,0xec,0x02,0xdc,0xfd,0xee, |
2131 | | 0xa0,0x3f,0xe7,0x86,0xdf,0x6c,0xee,0xf4,0x81,0x67,0xf0,0xd5,0xff,0x99,0xa9,0x11, |
2132 | | 0x3c,0xfb,0x54,0x0d,0x9e,0x5d,0x84,0x5f,0x04,0x07,0xbe,0x80,0x5b,0x15,0xf4,0x5b, |
2133 | | 0xeb,0x8d,0x5b,0xf0,0x00,0xc6,0x77,0xeb,0x4d,0x14,0x5e,0x9a,0xaf,0xc0,0xb3,0x7a, |
2134 | | 0x74,0xe5,0xbb,0x2d,0x48,0x60,0x6c,0xb5,0x29,0x55,0xe0,0xe7,0xef,0x06,0xc0,0x8c, |
2135 | | 0x02,0x3e,0x2c,0xdb,0xe0,0x17,0x23,0x28,0xf0,0x19,0xd0,0xa6,0x6a,0x40,0xd2,0x03, |
2136 | | 0x9e,0x35,0xa2,0xdf,0xcf,0xe0,0x69,0x70,0xdd,0xcd,0x28,0x35,0x60,0xa6,0x1c,0xbe, |
2137 | | 0x67,0xb4,0xa1,0x1f,0x5e,0x5a,0x2e,0x80,0x19,0xf8,0xe5,0x6a,0xb1,0xad,0x1e,0x3e, |
2138 | | 0x6f,0xda,0x3e,0x87,0xaf,0x1a,0x6d,0x5f,0xc0,0xbb,0x5f,0xfd,0x1a,0xcc,0xa8,0xbe, |
2139 | | 0x81,0x9b,0x26,0x9c,0x6b,0x07,0x7c,0xba,0xb6,0xb5,0xc1,0x07,0x44,0xdb,0xb5,0xab, |
2140 | | 0xe0,0xd9,0xd7,0xd7,0xc1,0x0c,0x7a,0x68,0xb5,0x5d,0x87,0x73,0xfc,0x06,0x9a,0xe6, |
2141 | | 0x1b,0x1d,0xac,0x80,0xdb,0x52,0xdb,0x4d,0x38,0x47,0xf8,0x02,0x39,0xa3,0x87,0x1b, |
2142 | | 0x36,0x7c,0xb5,0x7b,0x06,0xdf,0xfb,0x9e,0xf5,0xc2,0x67,0x48,0xdb,0x5d,0xd8,0xcb, |
2143 | | 0x0c,0x77,0x73,0x03,0xdc,0x85,0x6f,0xc3,0x29,0xf6,0x95,0x83,0x67,0xfd,0x6a,0x58, |
2144 | | 0x86,0x0f,0xa7,0x2b,0xd0,0x4c,0x8b,0x57,0x74,0x95,0x60,0xc6,0x08,0xc7,0x7a,0xa5, |
2145 | | 0xaa,0x01,0x3c,0x1b,0x84,0x4f,0xa5,0x2b,0x86,0xbb,0xe0,0xd9,0xdd,0x5a,0xf0,0xec, |
2146 | | 0x3b,0x54,0x40,0xdf,0x6d,0xae,0xd4,0x5c,0x06,0x73,0x4a,0xf8,0xb2,0x73,0x05,0xbe, |
2147 | | 0xef,0xcf,0xc1,0x0d,0x6b,0xf1,0xb2,0xf1,0x2b,0x18,0x74,0xb5,0x30,0xf8,0x6e,0x82, |
2148 | | 0x39,0x55,0x05,0x98,0xa9,0xae,0x82,0xf9,0x5d,0x60,0xb9,0x06,0x6d,0x7c,0xe5,0xcb, |
2149 | | 0xab,0x48,0xe0,0xd1,0xe5,0x0b,0x28,0x16,0x2f,0xc0,0x20,0xd5,0xaa,0xc0,0xdc,0xdd, |
2150 | | 0x2f,0xc1,0x8c,0xe9,0x6b,0x30,0xa7,0x37,0xc1,0x04,0xfb,0xeb,0xd1,0x1f,0x58,0xf6, |
2151 | | 0xc0,0x1c,0x2e,0x59,0x6b,0x3e,0x08,0xe6,0xaa,0xa0,0x29,0xae,0x74,0x0e,0x80,0x39, |
2152 | | 0x43,0x13,0x98,0x33,0xc2,0xdb,0x5e,0xe8,0x82,0xc7,0x28,0x87,0x8d,0x9f,0x5c,0x85, |
2153 | | 0x75,0x17,0x61,0xae,0x87,0xc9,0x00,0x13,0xf4,0xf7,0x15,0xe8,0x9f,0xc5,0x2b,0x70, |
2154 | | 0xe3,0x58,0xbc,0x02,0x5f,0x99,0x67,0x6a,0xe0,0xf5,0xe1,0x77,0xa3,0x39,0xf8,0xad, |
2155 | | 0x68,0xae,0x06,0x1a,0xfa,0x2a,0xea,0x5b,0x0b,0xfd,0x78,0x65,0xa0,0x13,0xcc,0xd4, |
2156 | | 0x36,0xc1,0x04,0x1d,0x77,0xe5,0x2e,0x7c,0x54,0x5f,0xad,0x80,0x06,0xab,0x85,0xfd, |
2157 | | 0x1b,0xaa,0x61,0x82,0x97,0x6e,0xe8,0x00,0x73,0x9f,0xa3,0xa4,0x05,0x73,0x8d,0x17, |
2158 | | 0xc0,0xdc,0x17,0x97,0x60,0x0e,0x27,0xdc,0x04,0xfb,0x7c,0x09,0x1d,0xf7,0xd9,0x67, |
2159 | | 0x60,0xee,0xab,0x16,0x30,0xd7,0xac,0x84,0xc7,0xfd,0x60,0xae,0x05,0x5a,0xe4,0x2a, |
2160 | | 0x3a,0x11,0xbe,0x34,0xce,0xc1,0xb7,0xc2,0x99,0x7a,0x33,0xcc,0xe1,0x2e,0xf2,0x29, |
2161 | | 0x5c,0x21,0x57,0x2f,0xc1,0x40,0xbe,0xda,0x76,0x05,0xcc,0x7c,0x7e,0x17,0xcc,0x7c, |
2162 | | 0x51,0x09,0xe6,0xae,0xa1,0xee,0x37,0xe1,0xf5,0x6e,0xc2,0xeb,0xc1,0xaf,0x10,0x73, |
2163 | | 0xbd,0x5f,0x80,0x39,0xf4,0xb6,0x7c,0x75,0x00,0xbe,0x42,0x34,0x37,0x43,0x0b,0xa1, |
2164 | | 0x9f,0xdb,0x6e,0xc1,0xc9,0xdf,0x86,0x26,0x6e,0x86,0x57,0x9c,0xfb,0x16,0xbe,0x9d, |
2165 | | 0xb6,0x7f,0xf6,0x29,0x92,0x2e,0x30,0x5f,0x5e,0x03,0xe6,0x2b,0xba,0xc1,0xbc,0x0a, |
2166 | | 0xbe,0x69,0xb5,0x37,0x5e,0x87,0x07,0x5f,0x80,0x79,0x6d,0x1f,0x98,0xaf,0xfa,0x0c, |
2167 | | 0xa6,0x7a,0x30,0xaf,0x1b,0x00,0xf3,0x9f,0xf4,0x83,0xf9,0x6a,0x18,0xee,0xed,0xdf, |
2168 | | 0xdc,0x01,0xf3,0x75,0x30,0xe6,0xae,0xc0,0x07,0x32,0xfa,0x86,0xd5,0x0e,0xef,0x35, |
2169 | | 0x73,0xf5,0x0a,0x98,0xff,0x02,0x6e,0xd2,0xb7,0x6e,0x82,0xf9,0x46,0x18,0x7b,0x1d, |
2170 | | 0x68,0xf1,0x74,0x68,0x3f,0x07,0x33,0x1d,0x30,0xb8,0x3a,0xe0,0x33,0xf9,0x2b,0x38, |
2171 | | 0xcc,0x8e,0x6a,0x3d,0x98,0xb9,0x06,0xa3,0xb8,0xe3,0xd3,0x3a,0x30,0xdf,0x0c,0xdf, |
2172 | | 0x7f,0x3a,0xd0,0xe3,0xfa,0x32,0x7c,0x76,0x76,0xf6,0x80,0x79,0xf8,0x42,0x34,0x7f, |
2173 | | 0xe5,0x2a,0x98,0xbf,0x5a,0x0e,0x13,0x9c,0xdd,0x37,0x70,0xf9,0x77,0x74,0xde,0x00, |
2174 | | 0xf3,0xdd,0x0a,0x30,0xdf,0x03,0x9f,0xb6,0xf0,0xfb,0xcd,0x0c,0xfc,0x22,0x31,0x6f, |
2175 | | 0x86,0x81,0x70,0x0d,0xfd,0x66,0xde,0x03,0x17,0xca,0x35,0x15,0xbc,0xd5,0x35,0x2d, |
2176 | | 0xec,0x7b,0x0d,0x46,0xc0,0x8c,0x19,0x5e,0xf9,0xdb,0xbb,0x60,0x1e,0x7e,0x3f,0x9b, |
2177 | | 0x1f,0xf8,0x04,0x26,0xe8,0xad,0x6b,0xf5,0x0a,0x00,0x70,0x1b,0x36,0xda,0xd8,0x6e, |
2178 | | 0xda,0xbc,0xd9,0x0e,0xbf,0x65,0xab,0xbd,0xc3,0x5b,0x8e,0x9b,0x7f,0xf9,0x10,0x36, |
2179 | | 0x3b,0x6d,0xdb,0xee,0xec,0xb2,0x63,0xa7,0xab,0xb5,0xe8,0xb6,0x79,0xd7,0x6e,0x77, |
2180 | | 0x8f,0x3d,0x6f,0x7b,0x7a,0x6d,0xfe,0xbb,0x7f,0xf6,0xee,0x83,0xe2,0xfd,0xab,0x5e, |
2181 | | 0x92,0xb8,0xff,0x80,0x8f,0xef,0xc1,0x77,0xb0,0x92,0xdf,0xeb,0x6a,0x92,0xff,0xe6, |
2182 | | 0x00,0x32,0x05,0x1e,0xbc,0xbb,0xf9,0x9f,0xf3,0x73,0x68,0x33,0x95,0xf6,0xde,0xfb, |
2183 | | 0x81,0xaf,0x8b,0xf4,0x37,0xdb,0x82,0x0e,0x6f,0x0e,0x0e,0xf9,0xe0,0x75,0xe9,0xc3, |
2184 | | 0xcd,0xff,0xc6,0x9f,0xd0,0xb0,0x23,0x9b,0xd7,0x3f,0xeb,0x9f,0xf5,0xcf,0xfa,0x67, |
2185 | | 0xfd,0xb3,0xfe,0x59,0xff,0xac,0x7f,0xd6,0x3f,0xeb,0x9f,0xf5,0xcf,0xfa,0x67,0xfd, |
2186 | | 0xf3,0xef,0xf3,0x01,0x36,0xeb,0xfc,0x55,0xd8,0x02,0xbb,0xdf,0x02,0x0f,0x08,0xc0, |
2187 | | 0x09,0x38,0x63,0xb8,0x00,0x77,0x88,0x07,0xf0,0x02,0x44,0x40,0x02,0x64,0x08,0x05, |
2188 | | 0xd0,0x41,0x08,0x08,0x05,0x61,0x80,0x05,0x38,0x20,0x03,0xc2,0x07,0x62,0x20,0x03, |
2189 | | 0x2a,0x60,0x00,0x35,0x90,0x46,0xd0,0x0a,0x3a,0x41,0x2f,0x18,0x00,0xf7,0xc1,0x43, |
2190 | | 0xf0,0x18,0x3c,0x81,0xcc,0x80,0xe7,0xe0,0x05,0x78,0x05,0x6c,0x70,0xf6,0x56,0x9c, |
2191 | | 0x71,0xee,0x38,0x6f,0x9c,0x1f,0x8e,0x6a,0x25,0x18,0x17,0x8e,0x63,0xe2,0x92,0x70, |
2192 | | 0x29,0xb8,0x0c,0x08,0x1f,0x27,0xc6,0xc9,0x70,0x2a,0x9c,0x01,0x57,0x83,0x6b,0xc4, |
2193 | | 0xb5,0xe2,0x3a,0x21,0xbd,0xb8,0x01,0xdc,0x7d,0xdc,0x43,0xdc,0x63,0xdc,0x13,0x2b, |
2194 | | 0x33,0xb8,0xe7,0xb8,0x17,0xb8,0x57,0x38,0x9b,0x0d,0x36,0x1b,0xec,0x21,0xce,0x1b, |
2195 | | 0xdc,0x37,0x78,0x6f,0xf0,0xdb,0x40,0xdd,0x10,0xbc,0x21,0x7c,0x03,0x73,0x43,0xd2, |
2196 | | 0x86,0x94,0x0d,0x19,0x1b,0xf8,0x1b,0xc4,0x1b,0x64,0x1b,0x54,0x1b,0x0c,0x56,0x6a, |
2197 | | 0x36,0x34,0x6e,0x68,0xdd,0xd0,0xb9,0xa1,0x77,0xc3,0xc0,0x86,0xfb,0x1b,0x1e,0x6e, |
2198 | | 0x78,0xbc,0xe1,0xc9,0x86,0x99,0x0d,0xcf,0x37,0xbc,0xd8,0xf0,0x6a,0x83,0xcd,0x46, |
2199 | | 0xfb,0x8d,0xce,0x1b,0xdd,0x37,0x7a,0x6f,0xf4,0xb3,0x42,0xdd,0x18,0xbc,0x31,0x7c, |
2200 | | 0x23,0x73,0x63,0xd2,0xc6,0x94,0x8d,0x19,0x1b,0xf9,0x1b,0xc5,0x1b,0x25,0x1b,0xe5, |
2201 | | 0x1b,0x55,0x1b,0x0d,0x1b,0x6b,0x36,0x36,0x6e,0x6c,0x85,0x74,0x6e,0xec,0xdd,0x38, |
2202 | | 0xb0,0xf1,0xfe,0xc6,0x87,0x1b,0xc7,0x37,0x4e,0x6d,0x9c,0xb1,0xf2,0x7c,0xe3,0x8b, |
2203 | | 0x8d,0xaf,0x36,0xda,0xd8,0xd8,0xdb,0xb8,0xd8,0xb8,0x5b,0xf1,0xb6,0xf1,0xb3,0xa1, |
2204 | | 0xda,0x04,0xdb,0x84,0xdb,0x30,0xad,0x24,0xd9,0xa4,0xd8,0x64,0xd8,0xf0,0x6d,0xc4, |
2205 | | 0x36,0x32,0x1b,0x95,0x8d,0xc1,0xa6,0xc6,0xa6,0xd1,0xa6,0xd5,0xa6,0xd3,0xa6,0xd7, |
2206 | | 0x66,0xc0,0xe6,0xbe,0xcd,0x43,0x9b,0xc7,0x36,0x4f,0xac,0xcc,0xd8,0x3c,0xb7,0x79, |
2207 | | 0x61,0xf3,0xca,0xc6,0xc6,0xd6,0xde,0xd6,0xd9,0xd6,0xdd,0xd6,0xdb,0xd6,0xcf,0x96, |
2208 | | 0x6a,0x1b,0x6c,0x1b,0x6e,0xcb,0xb4,0x4d,0xb2,0x4d,0xb1,0xcd,0xb0,0xe5,0xdb,0x8a, |
2209 | | 0x6d,0x65,0xb6,0x2a,0x5b,0x83,0x6d,0xad,0x6d,0xfd,0x5f,0x4d,0xb3,0x6d,0xfb,0xff, |
2210 | | 0xc0,0x0d,0xdb,0xbe,0x3f,0x89,0x7e,0xdb,0x61,0xdb,0x31,0xdb,0x29,0x5b,0x8b,0xed, |
2211 | | 0x82,0xed,0xb2,0xed,0xaa,0xad,0xed,0x26,0xfb,0x4d,0xce,0x9b,0xdc,0x37,0x79,0x6f, |
2212 | | 0xf2,0xdb,0x44,0xdd,0x14,0xbc,0x29,0x7c,0x13,0x73,0x53,0xf2,0xa6,0x8c,0x4d,0xc2, |
2213 | | 0x4d,0xb2,0x4d,0xda,0x4d,0x35,0x9b,0x9a,0x37,0x75,0x42,0xfa,0x36,0xdd,0xdf,0xf4, |
2214 | | 0x68,0xd3,0x93,0x4d,0x33,0x9b,0x9e,0x5b,0x79,0xb1,0xe9,0xd5,0x26,0x9b,0xcd,0xf6, |
2215 | | 0x9b,0x9d,0x37,0xbb,0x6f,0xf6,0xd9,0x4c,0xdd,0x1c,0xbc,0x39,0x7c,0x33,0x6b,0x33, |
2216 | | 0x7b,0x73,0xea,0xe6,0x8c,0xcd,0xfc,0xcd,0x62,0x2b,0xb2,0xcd,0xaa,0xcd,0xd5,0x9b, |
2217 | | 0x1b,0x37,0xb7,0x6e,0xee,0xdc,0xdc,0xbb,0x79,0x00,0x72,0x7f,0xf3,0xc3,0xcd,0x8f, |
2218 | | 0x37,0x3f,0xd9,0x3c,0xb3,0xf9,0xf9,0xe6,0x17,0x9b,0x5f,0x6d,0xb6,0xb1,0xb3,0xb7, |
2219 | | 0x73,0xb6,0x73,0xb7,0xf3,0xb6,0xf3,0xb3,0xa3,0xda,0x05,0xdb,0x85,0xdb,0x31,0xed, |
2220 | | 0x92,0xec,0x52,0xec,0x32,0xec,0xf8,0x76,0x62,0x3b,0x99,0x9d,0xca,0xce,0x60,0x57, |
2221 | | 0x63,0xd7,0x68,0xa5,0xd5,0xae,0xf3,0xb7,0xe8,0xb5,0x1b,0xb0,0xbb,0x6f,0xf7,0xd0, |
2222 | | 0x6e,0xc2,0x6e,0xc6,0x6e,0xd1,0xee,0x95,0x9d,0x0d,0xde,0x1e,0xef,0x8a,0xf7,0xc6, |
2223 | | 0xfb,0xe1,0xa9,0xff,0xa6,0xd0,0xf0,0x74,0x7c,0x08,0x3e,0x0c,0x1f,0x81,0x67,0xe0, |
2224 | | 0x59,0xf8,0x78,0x3c,0x1b,0x9f,0xfc,0x57,0xc1,0xc1,0xa7,0xe3,0x79,0x78,0x11,0x5e, |
2225 | | 0x8a,0x57,0xe2,0xb5,0x10,0x1d,0xde,0x88,0x37,0xe1,0x6b,0xf1,0x0d,0xf8,0xc6,0x7f, |
2226 | | 0x5a,0x9a,0xf1,0xad,0x90,0x76,0xfc,0x8d,0xbf,0x31,0xbd,0xbf,0x60,0xc6,0x0f,0x60, |
2227 | | 0xdc,0xfb,0x85,0x21,0xfc,0xf7,0xf8,0x47,0xf8,0x09,0xfc,0x13,0xfc,0x0c,0xfe,0x39, |
2228 | | 0xfe,0x05,0xe4,0x15,0xc4,0x66,0x8b,0xfd,0x16,0xd7,0xbf,0x00,0xcf,0x2d,0x3e,0x5b, |
2229 | | 0xc8,0x5b,0x02,0xb7,0x84,0x6e,0x89,0xdc,0x92,0xf4,0x17,0x90,0xb2,0x25,0x63,0x0b, |
2230 | | 0x7f,0x8b,0x78,0x8b,0x6c,0x8b,0x7c,0x8b,0x72,0x8b,0x7a,0x8b,0x7e,0xcb,0xa7,0x5b, |
2231 | | 0x1a,0xb6,0x34,0x6d,0x69,0xfe,0xb3,0x69,0xd9,0xd2,0xb6,0xa5,0x63,0x4b,0xe7,0x96, |
2232 | | 0xae,0x2d,0xdd,0x5b,0x7a,0xad,0x98,0xb7,0xf4,0xfd,0x0e,0xf7,0xb6,0x3c,0x80,0x3c, |
2233 | | 0xc2,0x98,0xf8,0x85,0xa7,0x5b,0xe6,0xb6,0x2c,0xfe,0x5e,0x5e,0xfe,0x95,0x80,0xad, |
2234 | | 0x7f,0x0e,0x76,0x5b,0x09,0x10,0x57,0x0c,0xcf,0x5f,0xf0,0xd9,0x4a,0xde,0x1a,0xf8, |
2235 | | 0x67,0x12,0xba,0x35,0xf2,0x1f,0x90,0xb8,0xad,0xc9,0xff,0x03,0x69,0x5b,0xb9,0x5b, |
2236 | | 0x85,0x5b,0x8b,0xac,0x28,0xb6,0x6a,0xad,0x54,0x6f,0xad,0xdf,0xda,0xbc,0xb5,0x7d, |
2237 | | 0xeb,0x8d,0xad,0x7d,0x56,0xee,0x6d,0x7d,0xb0,0xf5,0xd1,0xd6,0x89,0xad,0x4f,0xb7, |
2238 | | 0xce,0x59,0x59,0xdc,0xfa,0x72,0x2b,0xb0,0xb7,0xb3,0x27,0xd8,0xbb,0xda,0x7b,0xda, |
2239 | | 0xfb,0xd8,0x93,0xed,0x03,0xed,0x43,0xed,0x23,0xad,0xc4,0xd9,0x27,0xaf,0xf3,0x07, |
2240 | | 0xe1,0xd8,0xa7,0xad,0xf3,0x17,0xc1,0xb5,0x17,0xda,0x17,0xd9,0x2b,0xec,0xb5,0xff, |
2241 | | 0xc0,0xe8,0xec,0x4d,0xf6,0x0d,0xf6,0x2d,0xf6,0xed,0xff,0x60,0xdc,0x80,0xf4,0xfd, |
2242 | | 0x51,0xee,0xfd,0xcd,0x00,0xeb,0x9f,0x7f,0xf3,0xcf,0xdf,0x22,0xaa,0x1e,0xfc,0x0e, |
2243 | | 0x8f,0xac,0x4c,0xfc,0x4a,0x3c,0xb5,0x9f,0xb3,0x5f,0xb4,0x7f,0x69,0x0f,0x1c,0xec, |
2244 | | 0x1c,0x08,0x0e,0xae,0xff,0xa2,0x78,0x3a,0xf8,0xfc,0x11,0xc8,0x0e,0x81,0x90,0xd0, |
2245 | | 0x7f,0x1a,0x22,0xad,0xc4,0xfd,0x2a,0x24,0x3b,0xa4,0x39,0x70,0xad,0x08,0xd7,0xf9, |
2246 | | 0x17,0xa4,0xc8,0x8a,0xc2,0x41,0xfb,0x47,0xa8,0x76,0xa8,0xff,0xbb,0xd2,0xfc,0x77, |
2247 | | 0xa4,0xdd,0xe1,0x86,0x43,0xdf,0xbf,0x2d,0xf7,0xfe,0xcd,0x78,0xf0,0x5b,0x3c,0x72, |
2248 | | 0x98,0x80,0x3c,0x75,0x78,0xfe,0x6f,0xce,0x0b,0x87,0x57,0x0e,0x36,0x6f,0xad,0xf3, |
2249 | | 0x87,0xb0,0x87,0x38,0xbf,0xe5,0xf9,0x96,0xcf,0x3f,0x0d,0xbe,0x6f,0x91,0xff,0xad, |
2250 | | 0xa1,0xbc,0x15,0xf8,0x2b,0x43,0x7f,0x2b,0xec,0xad,0xc8,0xbf,0x29,0x8c,0xb7,0x98, |
2251 | | 0x7f,0x57,0x92,0x7e,0x0f,0x29,0xbf,0x90,0xf1,0x0b,0xfc,0x5f,0x10,0xff,0x41,0x64, |
2252 | | 0xbf,0x07,0x15,0xc4,0xf0,0x56,0xed,0x5b,0xcd,0x6f,0x75,0xbc,0xd5,0xfb,0x3b,0x0c, |
2253 | | 0xfc,0x09,0xdc,0xff,0x3d,0x3c,0xfc,0x85,0xc7,0xbf,0xf0,0xe4,0x17,0x66,0xfe,0x20, |
2254 | | 0xcf,0xff,0x85,0x79,0xb1,0xce,0x3f,0x09,0xcb,0x6f,0xbd,0xfc,0xbd,0x00,0x47,0xe0, |
2255 | | 0x68,0x07,0x21,0x40,0x5c,0x21,0x9e,0x18,0x3e,0xbf,0x3a,0x64,0x48,0xa0,0x95,0x50, |
2256 | | 0xc7,0x48,0x48,0xdc,0x3a,0xff,0x62,0xc4,0x3b,0xb2,0x1d,0x39,0x8e,0x29,0x8e,0xa9, |
2257 | | 0x8e,0xe9,0x8e,0x99,0x8e,0x3c,0x47,0x81,0xa3,0xc8,0x51,0xe2,0x28,0x75,0x94,0x3b, |
2258 | | 0x2a,0x1d,0xd5,0x8e,0x5a,0x47,0x9d,0xa3,0xd1,0xd1,0xe4,0x58,0xeb,0xd8,0xe0,0xd8, |
2259 | | 0xe4,0xd8,0xe2,0xd8,0xe6,0xd8,0xe1,0xd8,0xe5,0xd8,0xed,0x68,0x76,0xec,0x77,0x1c, |
2260 | | 0x74,0x1c,0x72,0x1c,0x76,0x1c,0x71,0x1c,0x75,0x7c,0xe4,0x38,0xe6,0x38,0xee,0x38, |
2261 | | 0xe9,0x38,0xe5,0x38,0xed,0x68,0x71,0x9c,0x77,0x5c,0x70,0x5c,0x72,0x5c,0x76,0x5c, |
2262 | | 0x71,0x5c,0x75,0xc4,0x11,0x6c,0x09,0x78,0x82,0x03,0xc1,0x89,0xe0,0x42,0x70,0x23, |
2263 | | 0x78,0x10,0xbc,0x08,0x44,0x82,0x2f,0x81,0x44,0xa0,0x10,0x68,0x04,0x3a,0x21,0x84, |
2264 | | 0x10,0xfa,0x07,0x09,0x23,0x84,0xff,0x0a,0x44,0x10,0x18,0x04,0x16,0x21,0x9e,0xc0, |
2265 | | 0x26,0x70,0x08,0xa9,0x84,0x74,0x42,0x26,0x81,0x47,0x10,0x10,0x44,0x04,0x09,0x41, |
2266 | | 0x4a,0x90,0x13,0x94,0x04,0x35,0x41,0x47,0x30,0x12,0x4c,0x84,0x5a,0x42,0x03,0xa1, |
2267 | | 0x89,0xd0,0x42,0x68,0x23,0x74,0x10,0xba,0x08,0xdd,0x04,0x33,0xa1,0x9f,0x30,0x48, |
2268 | | 0x18,0x22,0x0c,0x13,0x46,0x08,0xa3,0x84,0x31,0xc2,0x38,0x61,0xe2,0x1f,0x80,0xa7, |
2269 | | 0x84,0x39,0xc2,0x22,0xe1,0x25,0x01,0x38,0xd9,0x39,0x11,0x9c,0x5c,0x9d,0xbc,0x9d, |
2270 | | 0xc8,0x4e,0x81,0x4e,0xa1,0x4e,0x91,0x4e,0x71,0x4e,0xc9,0x4e,0x69,0x4e,0x5c,0x27, |
2271 | | 0xa1,0x53,0x91,0x93,0xc2,0xc9,0xe0,0x54,0xef,0xd4,0xea,0x74,0xc3,0xa9,0xcf,0xe9, |
2272 | | 0x9e,0xd3,0x03,0xa7,0x47,0x4e,0x4f,0x9c,0xe6,0x9c,0x16,0x9d,0x5e,0x3a,0x81,0x6d, |
2273 | | 0x76,0xdb,0x08,0xdb,0x5c,0xb7,0x79,0x6e,0xf3,0xd9,0x46,0xde,0x16,0xb8,0x2d,0x74, |
2274 | | 0x5b,0xe4,0xb6,0xb8,0x6d,0xc9,0xdb,0xd2,0xb6,0x71,0xb7,0x89,0xb7,0x29,0xb6,0x69, |
2275 | | 0xb7,0x55,0x6f,0xab,0xdf,0xd6,0xbc,0xad,0x7d,0xdb,0x8d,0x6d,0x7d,0xdb,0xee,0x6d, |
2276 | | 0x7b,0xb8,0x6d,0x62,0xdb,0xd3,0x6d,0x73,0xdb,0x16,0xb7,0xbd,0xdc,0x06,0xb6,0xdb, |
2277 | | 0x6d,0x27,0x6c,0x77,0xdd,0xee,0xb9,0xdd,0x67,0x3b,0x79,0x7b,0xe0,0xf6,0xd0,0xed, |
2278 | | 0x91,0xdb,0xe3,0xb6,0x27,0x6f,0x4f,0xdb,0xce,0xdd,0x2e,0xde,0xae,0xd8,0x6e,0xd8, |
2279 | | 0x5e,0xbf,0xbd,0x75,0xfb,0x8d,0xed,0x03,0xdb,0x1f,0x6c,0x7f,0xb4,0x7d,0x62,0xfb, |
2280 | | 0xd3,0xed,0x73,0xdb,0x17,0xb7,0xbf,0xdc,0x0e,0x9c,0xed,0x9c,0x9d,0x9d,0x3d,0x9d, |
2281 | | 0x7d,0x9c,0xc9,0xce,0x81,0xce,0xa1,0xce,0x91,0xce,0x71,0xce,0x29,0xce,0x5c,0x67, |
2282 | | 0xb1,0xb3,0xc2,0xd9,0xe0,0x5c,0xef,0xdc,0xec,0xdc,0xee,0x7c,0xc3,0xb9,0xcf,0xf9, |
2283 | | 0x9e,0xf3,0x03,0xe7,0x47,0xce,0x13,0xce,0x4f,0x9d,0xe7,0x9c,0x17,0x9d,0x5f,0x3a, |
2284 | | 0x03,0x17,0x3b,0x17,0x67,0x17,0x4f,0x17,0x3f,0x97,0x40,0x97,0x50,0x97,0x48,0x97, |
2285 | | 0x38,0x97,0x64,0x97,0x34,0x17,0xae,0x8b,0xd0,0xa5,0xc8,0x45,0xe1,0xa2,0x75,0xa9, |
2286 | | 0x76,0xa9,0x77,0x69,0x76,0x69,0x77,0xb9,0xe1,0xd2,0xe7,0x72,0xcf,0xe5,0x81,0xcb, |
2287 | | 0x23,0x97,0x09,0x97,0xa7,0x2e,0x73,0x2e,0x8b,0x2e,0x2f,0x5d,0xc0,0x0e,0xbb,0x1d, |
2288 | | 0x84,0x1d,0xae,0x3b,0x3c,0x77,0xf8,0xee,0x78,0x77,0x47,0xe0,0x2f,0x84,0xee,0x88, |
2289 | | 0xdc,0x11,0xb7,0x23,0x79,0x47,0xc6,0x0e,0xe1,0x0e,0xd9,0x0e,0xed,0x8e,0x9a,0x1d, |
2290 | | 0xcd,0x3b,0x3a,0x77,0xf4,0xed,0xb8,0xbf,0xe3,0xd1,0x8e,0x27,0x3b,0xe6,0x76,0xbc, |
2291 | | 0xd8,0x01,0x76,0xda,0xef,0x74,0xdd,0xe9,0xbd,0x93,0xbc,0x33,0x78,0x67,0xe4,0xce, |
2292 | | 0xb8,0x9d,0xc9,0x3b,0xd3,0x76,0x72,0x77,0x0a,0x77,0x16,0xed,0x54,0xed,0xac,0xde, |
2293 | | 0xd9,0xb8,0xb3,0x7d,0x67,0xef,0xce,0x7b,0x3b,0x1f,0xee,0x9c,0xd8,0x39,0xb3,0x73, |
2294 | | 0x71,0xe7,0xcb,0x9d,0xc0,0xd5,0xce,0x95,0xe0,0xea,0xea,0xea,0xe9,0xea,0xe3,0x4a, |
2295 | | 0x76,0x0d,0x76,0x8d,0x74,0x4d,0x72,0x4d,0x73,0xe5,0xbb,0x16,0xb9,0xaa,0x5c,0xab, |
2296 | | 0x5d,0x1b,0x5d,0xdb,0x5d,0x7b,0x5d,0xef,0xb9,0x3e,0x74,0x9d,0x70,0x9d,0x71,0x5d, |
2297 | | 0x74,0x7d,0xe5,0x6a,0xe7,0xe6,0xec,0xe6,0xe9,0xe6,0xe3,0x46,0x76,0x0b,0x74,0x0b, |
2298 | | 0x75,0x63,0xba,0x25,0xbb,0x65,0xb8,0x09,0xdd,0x64,0x6e,0x5a,0xb7,0x1a,0xb7,0x66, |
2299 | | 0xb7,0x4e,0xb7,0x3e,0xb7,0x7b,0x6e,0x0f,0xdc,0x1e,0xb9,0x4d,0xb8,0x3d,0x75,0x9b, |
2300 | | 0x73,0x5b,0x74,0x7b,0xf9,0x3b,0x80,0x5d,0x76,0xbb,0x9c,0x77,0x79,0xee,0xf2,0xdb, |
2301 | | 0x15,0xb8,0x2b,0x7c,0x57,0xdc,0xae,0xe4,0x5d,0x69,0xbb,0xf8,0xbb,0x8a,0x76,0xa9, |
2302 | | 0x76,0x55,0xef,0x6a,0xdc,0xd5,0xbe,0xeb,0xc6,0xae,0xbe,0x5d,0xf7,0x77,0x3d,0xda, |
2303 | | 0xf5,0x64,0xd7,0x9c,0x95,0xc5,0x5d,0x2f,0x77,0xd9,0xec,0x26,0xec,0x76,0xdf,0xed, |
2304 | | 0x63,0x85,0xbc,0x3b,0x70,0x77,0xf8,0xee,0xb8,0xdd,0x29,0xbb,0xb9,0xbb,0xc5,0xbb, |
2305 | | 0x15,0xbb,0xb5,0xbb,0xab,0x77,0x37,0xee,0x6e,0xdf,0xdd,0xbb,0xfb,0xde,0xee,0x87, |
2306 | | 0xbb,0x27,0x76,0x3f,0xdd,0x3d,0xb7,0xfb,0xc5,0x6e,0xe0,0x6e,0xef,0xee,0xea,0xee, |
2307 | | 0xed,0x4e,0x76,0x0f,0x74,0x0f,0x75,0x67,0xba,0x27,0xbb,0x67,0xb8,0x0b,0xdd,0x65, |
2308 | | 0xee,0x5a,0xf7,0x6a,0xf7,0x7a,0xf7,0x56,0xf7,0x1b,0xee,0x03,0xee,0x0f,0xac,0x3c, |
2309 | | 0x72,0x9f,0x70,0x9f,0x71,0x5f,0x74,0x7f,0xe5,0x6e,0xe7,0x81,0x20,0x78,0xb8,0x7a, |
2310 | | 0x78,0x7b,0x90,0x3d,0x82,0x3d,0x22,0x3d,0x92,0x3c,0xd2,0x20,0x5c,0x88,0x18,0xa2, |
2311 | | 0x80,0x18,0x3c,0x6a,0x3c,0x1a,0x3d,0xda,0x3d,0x7a,0x3d,0xee,0x79,0x3c,0xf4,0x98, |
2312 | | 0xf0,0x98,0xf1,0x78,0xee,0xf1,0xc2,0x03,0xec,0xb1,0xdf,0xe3,0xba,0xc7,0x7b,0x0f, |
2313 | | 0x79,0x4f,0xf0,0x9e,0xf0,0x3d,0xcc,0x3d,0x49,0x7b,0x52,0xf6,0x64,0xec,0xe1,0xef, |
2314 | | 0x11,0xef,0x91,0xed,0x51,0xed,0x31,0xec,0xa9,0xd9,0xd3,0xb8,0xa7,0x75,0x4f,0xa7, |
2315 | | 0x95,0xbe,0x3d,0xf7,0xf7,0x3c,0xde,0x33,0xb3,0xe7,0xc5,0x1e,0x9b,0xb7,0x9d,0xdf, |
2316 | | 0xf6,0x7e,0x9b,0xfc,0x76,0xf0,0xdb,0xcc,0xb7,0x53,0xde,0xe6,0xbf,0x2d,0x7b,0xdb, |
2317 | | 0xf0,0x76,0xe3,0xdb,0xed,0x6f,0xf7,0xbe,0x7d,0xff,0xed,0xc7,0x6f,0xcf,0xbc,0xfd, |
2318 | | 0xe2,0x6d,0x1b,0x4f,0x67,0x4f,0x4f,0x4f,0x3f,0xcf,0x60,0x4f,0xa6,0x67,0x8a,0x27, |
2319 | | 0xdf,0x53,0xe6,0x69,0xf0,0xac,0xf7,0x6c,0xf5,0xec,0xf5,0xbc,0xef,0xf9,0xd8,0x73, |
2320 | | 0xc6,0xf3,0x85,0xa7,0x8d,0x17,0xc1,0xcb,0xdd,0xcb,0xcf,0x2b,0xd8,0x8b,0xe9,0x95, |
2321 | | 0xe2,0xc5,0xf7,0x92,0x79,0xa9,0xbc,0x0c,0x5e,0xf5,0x5e,0xcd,0x5e,0x9d,0x90,0x5e, |
2322 | | 0xaf,0x7b,0x5e,0x0f,0xbc,0x1e,0x79,0x4d,0x78,0x3d,0xf5,0x9a,0xf7,0x5a,0xf4,0x5a, |
2323 | | 0xf6,0x5a,0xf5,0xda,0xb4,0xd7,0x7e,0xaf,0xeb,0x5e,0xcf,0xbd,0x7e,0x10,0xea,0xde, |
2324 | | 0xd0,0xbd,0x91,0x7b,0xe3,0xf6,0x26,0xef,0x4d,0xdb,0x9b,0xbd,0x37,0x6f,0x6f,0xf1, |
2325 | | 0x5e,0xc5,0x5e,0xed,0xde,0xea,0xbd,0x8d,0x7b,0xdb,0xad,0xdc,0xd8,0x3b,0xb0,0xf7, |
2326 | | 0xfe,0xde,0x87,0x7b,0x1f,0xef,0x7d,0xb2,0xf7,0xff,0xd9,0x3b,0xbb,0xf7,0xff,0xdd, |
2327 | | 0xfb,0x62,0xef,0xab,0xbd,0x36,0xfb,0x08,0xfb,0xdc,0xf7,0x79,0xef,0xf3,0xdb,0x47, |
2328 | | 0xdd,0x17,0xba,0x2f,0x72,0x5f,0xdc,0xbe,0xe4,0x7d,0x69,0xfb,0xb2,0xf7,0xe5,0xed, |
2329 | | 0x2b,0xda,0x27,0xb3,0xa2,0xdd,0x57,0xbd,0xaf,0x11,0xd2,0xba,0xef,0xc6,0xbe,0xbe, |
2330 | | 0x7d,0xf7,0xf6,0x3d,0xd8,0xf7,0x68,0xdf,0x8f,0xfb,0xa6,0xf6,0xcd,0xec,0x9b,0x85, |
2331 | | 0xfc,0xf7,0xbe,0x85,0x7d,0x4b,0xfb,0x96,0xf7,0xad,0xec,0x5b,0xdd,0x87,0xf3,0xb6, |
2332 | | 0xf5,0xc6,0x7b,0x3b,0x78,0x13,0xde,0xc0,0xc9,0xdb,0xf9,0x17,0x5c,0xbc,0xdd,0xff, |
2333 | | 0x00,0x1e,0xde,0x5e,0xde,0xbe,0xde,0xd4,0xdf,0x81,0xe6,0x1d,0x68,0x85,0xee,0x1d, |
2334 | | 0xe6,0xcd,0xf4,0x66,0x79,0xb3,0xbd,0xd3,0x30,0xd2,0xbd,0xb9,0xde,0x3c,0x6f,0xe1, |
2335 | | 0xef,0x20,0xf2,0x96,0x7a,0x2b,0xbd,0xb5,0x7f,0x10,0x9d,0x77,0xfd,0x6f,0xd1,0xe0, |
2336 | | 0xdd,0xf8,0x47,0x68,0xf2,0x6e,0xf1,0x6e,0x85,0xb4,0x79,0x77,0x78,0x77,0x79,0x77, |
2337 | | 0x7b,0x9b,0xbd,0xfb,0xbd,0x07,0xbd,0x87,0xbc,0x87,0xbd,0x47,0xbc,0x47,0xbd,0xc7, |
2338 | | 0xbc,0xc7,0xbd,0x27,0xbd,0xa7,0xbc,0xa7,0xbd,0x2d,0xde,0xf3,0xde,0x0b,0xde,0x4b, |
2339 | | 0xde,0xcb,0xde,0x2b,0xde,0xab,0xde,0x38,0xa2,0x2d,0x11,0x4f,0x74,0x20,0x12,0x88, |
2340 | | 0x4e,0x44,0x17,0xa2,0x1b,0xd1,0x83,0xe8,0x45,0x24,0x12,0x7d,0x89,0x24,0x22,0x85, |
2341 | | 0x48,0x23,0xd2,0x89,0x21,0xc4,0x30,0x62,0xf8,0xef,0x25,0x82,0xc8,0xfc,0xa7,0x82, |
2342 | | 0x05,0xe1,0x10,0x33,0x89,0x3c,0xa2,0x90,0x28,0x22,0xca,0x89,0x3a,0xa2,0x81,0x68, |
2343 | | 0x24,0xd6,0x12,0x1b,0x88,0x4d,0xc4,0x16,0x62,0x1b,0xb1,0x83,0xd8,0x45,0xec,0x26, |
2344 | | 0x9a,0x89,0xfd,0xc4,0x01,0xe2,0x20,0x71,0x88,0xf8,0x00,0x32,0x42,0x1c,0x25,0x8e, |
2345 | | 0x11,0xc7,0x89,0x93,0xc4,0x27,0x90,0x29,0xa2,0x85,0xb8,0x44,0x7c,0x49,0x5c,0x21, |
2346 | | 0xbe,0x82,0x80,0xfd,0xb8,0xfd,0x36,0x10,0xbb,0xfd,0x4e,0xfb,0x5d,0xf6,0xbb,0xee, |
2347 | | 0x77,0xdb,0xef,0xb1,0xdf,0x6b,0xbf,0xf7,0x7e,0xe2,0x7e,0xdf,0xfd,0xa4,0xfd,0x94, |
2348 | | 0xfd,0xb4,0xfd,0xf4,0xfd,0x21,0xfb,0x43,0xf7,0x87,0xed,0x67,0xed,0x8f,0xdf,0xcf, |
2349 | | 0xde,0xcf,0xd9,0x9f,0xba,0x3f,0x0d,0x23,0x7d,0x7f,0xe6,0x7e,0xde,0x7e,0xc1,0x7e, |
2350 | | 0xd1,0x7e,0xf1,0x1b,0x48,0xf6,0x2b,0xf7,0x1b,0xf7,0x37,0xed,0xef,0xd8,0x6f,0xde, |
2351 | | 0x3f,0xb4,0x7f,0x74,0xff,0xe4,0x7e,0xcb,0xfe,0xa5,0xfd,0xab,0xfb,0xf1,0x07,0x5c, |
2352 | | 0x0e,0x78,0x1d,0x20,0x1d,0xa0,0x1d,0xa0,0x1f,0x08,0x3b,0xc0,0x3a,0xc0,0x3e,0xc0, |
2353 | | 0x39,0x90,0x7e,0x40,0x70,0x40,0x7e,0x40,0x7d,0x40,0x77,0xc0,0x74,0xa0,0xe9,0x40, |
2354 | | 0xcb,0x81,0xb6,0x03,0x1d,0x07,0xba,0x0e,0x74,0x1f,0xe8,0x3f,0x30,0x7c,0x60,0xf4, |
2355 | | 0xc0,0xd8,0x81,0xc9,0x03,0x96,0x03,0xcb,0x07,0x56,0x0f,0xe0,0x7c,0xf0,0x3e,0x2e, |
2356 | | 0x3e,0x6e,0x3e,0x1e,0x3e,0x5e,0x3e,0xde,0xff,0x07,0x44,0x1f,0xf2,0x1f,0x25,0xd0, |
2357 | | 0x27,0xf4,0x4f,0x22,0xf2,0xaf,0x22,0xce,0x27,0xd9,0x27,0xed,0xef,0x08,0xf7,0x17, |
2358 | | 0x84,0x56,0x8a,0xfe,0x4c,0x14,0x10,0xed,0x2f,0xe8,0x7c,0x4c,0x3e,0x8d,0x3e,0x4d, |
2359 | | 0x3e,0x6d,0x3e,0x37,0xfe,0x28,0x7d,0x56,0xee,0x59,0x79,0x00,0x79,0xf4,0x67,0x31, |
2360 | | 0x01,0x79,0xfa,0x7b,0x99,0xf3,0x59,0xf4,0x79,0xe9,0x03,0x7c,0xed,0xac,0x10,0x7c, |
2361 | | 0x5d,0xad,0x78,0xfa,0xfa,0xfc,0x16,0x64,0xdf,0x40,0x2b,0xa1,0xbe,0x91,0x56,0xe2, |
2362 | | 0x7c,0x93,0x7f,0x15,0xd2,0x7c,0xb9,0xbe,0x42,0xdf,0xa2,0xbf,0x39,0x0a,0x5f,0xad, |
2363 | | 0x6f,0xb5,0x6f,0xfd,0x6f,0xd1,0xec,0xdb,0xee,0x7b,0xc3,0xb7,0xef,0xff,0x1a,0x03, |
2364 | | 0xbe,0xf7,0xd6,0x59,0xe7,0xef,0xc4,0x90,0xef,0xb0,0xef,0x88,0xef,0xa8,0xef,0x98, |
2365 | | 0xef,0xb8,0xef,0xa4,0xef,0x94,0xef,0xb4,0xaf,0xc5,0x77,0xc1,0x77,0xd9,0x77,0xd5, |
2366 | | 0xd7,0xf6,0xa0,0xc3,0x41,0x97,0x83,0x1e,0x07,0x89,0x07,0x49,0x07,0x69,0x07,0x43, |
2367 | | 0x0e,0x32,0x0e,0xb2,0x0f,0xa6,0x1f,0x14,0x1c,0x94,0x1e,0x54,0x1f,0x34,0x1d,0x6c, |
2368 | | 0x3a,0xd8,0x71,0xb0,0xff,0xe0,0xc8,0xc1,0xc9,0x83,0xf3,0x07,0x57,0x0e,0xe2,0xdf, |
2369 | | 0x71,0x7b,0xc7,0xf7,0x1d,0xfa,0x3b,0x8c,0x77,0x38,0xef,0xa4,0xbf,0xc3,0x7b,0x47, |
2370 | | 0xf4,0x8e,0xf4,0x1d,0xe5,0x3b,0xba,0x77,0x4c,0xef,0x34,0xbc,0xd3,0xf2,0x4e,0xd7, |
2371 | | 0x3b,0xfd,0xef,0x0c,0xbf,0x33,0xf6,0xce,0xd4,0x3b,0xf3,0xef,0x2c,0xbf,0x83,0xf3, |
2372 | | 0x73,0xf0,0x73,0xf3,0x23,0xfa,0x51,0xfc,0x42,0xfc,0x18,0x7e,0x6c,0xbf,0x74,0x3f, |
2373 | | 0x81,0x9f,0xd4,0x4f,0xed,0x67,0xf2,0x6b,0xf2,0xeb,0xf0,0x33,0xfb,0x0d,0xf9,0x8d, |
2374 | | 0xfa,0x4d,0xfa,0x59,0xfc,0x96,0xfc,0x56,0xfd,0xf0,0x24,0x17,0x92,0x17,0x89,0x44, |
2375 | | 0xa2,0x93,0x22,0x48,0xf1,0xa4,0x54,0x52,0x3a,0x29,0x93,0xc4,0x23,0x09,0x48,0x22, |
2376 | | 0x92,0x84,0x24,0x25,0xc9,0x49,0x4a,0x92,0x9a,0xa4,0x23,0x19,0x49,0x26,0x52,0x2d, |
2377 | | 0xa9,0x81,0xd4,0x44,0x6a,0x21,0xb5,0x91,0x3a,0x48,0x5d,0xa4,0x6e,0x92,0x99,0xd4, |
2378 | | 0x4f,0x1a,0x24,0x0d,0x91,0x86,0x49,0x23,0xa4,0x51,0xd2,0x18,0x69,0x9c,0x34,0x49, |
2379 | | 0x9a,0x22,0x4d,0x93,0x2c,0xa4,0x79,0xd2,0x02,0x69,0x89,0xb4,0x4c,0x5a,0x21,0xad, |
2380 | | 0x92,0x70,0xfe,0xb6,0xfe,0x78,0x7f,0x07,0x7f,0x27,0x7f,0x17,0x7f,0x37,0x7f,0x0f, |
2381 | | 0x7f,0x2f,0x7f,0xa2,0xbf,0xaf,0x3f,0xc9,0x9f,0xfc,0x2b,0x40,0xf1,0x0f,0xfd,0x97, |
2382 | | 0x22,0xcc,0x9f,0xe5,0xcf,0xf6,0x4f,0xfb,0x17,0x82,0xbb,0xce,0x5f,0x05,0xcf,0x5f, |
2383 | | 0xe0,0x2f,0x5c,0xe7,0x5f,0x1e,0x91,0xbf,0x78,0x9d,0x75,0xfe,0x86,0x48,0xfc,0x8b, |
2384 | | 0xfe,0x29,0x90,0xfa,0xcb,0xfe,0x00,0x72,0x88,0xd2,0x5f,0xed,0xaf,0xf3,0x37,0xfa, |
2385 | | 0x9b,0xfc,0x6b,0xfd,0x1b,0xfc,0x9b,0xfc,0x5b,0xfc,0xdb,0xfc,0x3b,0xfc,0xbb,0xfc, |
2386 | | 0xbb,0xfd,0xcd,0xfe,0xfd,0xfe,0x83,0xfe,0x43,0xfe,0xc3,0xfe,0x23,0xfe,0xa3,0xfe, |
2387 | | 0x63,0xfe,0xe3,0xfe,0x93,0xfe,0x53,0xfe,0xd3,0xfe,0x16,0xff,0x79,0xff,0x05,0xff, |
2388 | | 0x25,0xff,0x65,0xff,0x15,0xff,0x55,0x7f,0x5c,0x80,0x6d,0x00,0x3e,0xc0,0x21,0xc0, |
2389 | | 0x29,0xc0,0x25,0xc0,0x2d,0xc0,0x23,0xc0,0x2b,0x80,0x18,0xe0,0x1b,0x40,0x0a,0xa0, |
2390 | | 0x04,0xd0,0x02,0xe8,0x01,0x21,0x01,0x61,0x01,0x11,0x01,0x8c,0x00,0x56,0x40,0x7c, |
2391 | | 0x00,0x3b,0x80,0x13,0x90,0x1a,0x90,0x1e,0x90,0x19,0xc0,0x0b,0x10,0x04,0x88,0x02, |
2392 | | 0x24,0x01,0xd2,0x00,0x79,0x80,0x32,0x40,0x1d,0xa0,0x0b,0x30,0x06,0x98,0x02,0x6a, |
2393 | | 0x03,0x1a,0x02,0x9a,0x02,0x5a,0x02,0xda,0x02,0x3a,0x02,0xba,0x02,0xba,0x03,0xcc, |
2394 | | 0x01,0xfd,0x01,0x83,0x01,0x43,0x01,0xc3,0x01,0x23,0x01,0xa3,0x01,0x63,0x01,0xe3, |
2395 | | 0x01,0x93,0x01,0x53,0x01,0xd3,0x01,0x96,0x80,0xf9,0x80,0x85,0x80,0xa5,0x80,0xe5, |
2396 | | 0x80,0x95,0x80,0xd5,0x00,0x1c,0xd9,0x96,0x8c,0x27,0x3b,0x90,0x9d,0xc8,0x2e,0x64, |
2397 | | 0x37,0xb2,0x07,0xd9,0x8b,0x4c,0x24,0xfb,0x92,0x49,0x64,0x0a,0x99,0x46,0xa6,0x93, |
2398 | | 0x43,0xc8,0x61,0xe4,0x08,0x32,0x83,0xcc,0x22,0xc7,0x93,0xd9,0x64,0x0e,0x39,0x95, |
2399 | | 0x9c,0x4e,0xce,0x24,0xf3,0xc8,0x02,0xb2,0x88,0x2c,0x21,0x4b,0xc9,0x72,0xb2,0x92, |
2400 | | 0xac,0x26,0xeb,0xc8,0x46,0xb2,0x89,0x5c,0x4b,0x6e,0x20,0x37,0x91,0x5b,0xc8,0x6d, |
2401 | | 0xe4,0x0e,0x72,0x17,0xb9,0x9b,0x6c,0x26,0xf7,0x93,0x07,0xc9,0x43,0xe4,0x61,0xf2, |
2402 | | 0x08,0x79,0x94,0x3c,0x46,0x1e,0x27,0x4f,0x92,0xa7,0xc8,0xd3,0x64,0x0b,0x79,0x9e, |
2403 | | 0xbc,0x40,0x5e,0x22,0x2f,0x93,0x57,0xc8,0xab,0x64,0x1c,0xc5,0x96,0x82,0xa7,0x38, |
2404 | | 0x50,0x9c,0x28,0x2e,0x14,0x37,0x8a,0x07,0xc5,0x8b,0x42,0xa4,0xf8,0x52,0x48,0x14, |
2405 | | 0x0a,0x85,0x46,0xa1,0x53,0x42,0x28,0x61,0x94,0x08,0x0a,0x83,0xc2,0xa2,0xc4,0x53, |
2406 | | 0xd8,0x14,0x0e,0x25,0x95,0x92,0x4e,0xc9,0xa4,0xf0,0x28,0x02,0x8a,0x88,0x22,0xa1, |
2407 | | 0x48,0x29,0x72,0x8a,0x92,0xa2,0xa6,0xe8,0x28,0x46,0x8a,0x89,0x52,0x4b,0x69,0xa0, |
2408 | | 0x34,0x51,0x5a,0x28,0x6d,0x94,0x0e,0x4a,0x17,0xa5,0x9b,0x62,0xa6,0xf4,0x53,0x06, |
2409 | | 0x29,0x43,0x94,0x61,0xca,0x08,0x65,0x94,0x32,0x46,0x79,0xfc,0x37,0x60,0x1c,0x32, |
2410 | | 0xf1,0x77,0x63,0x92,0xf2,0x84,0x32,0x45,0x99,0xa6,0x58,0x28,0x73,0x7f,0x02,0x8b, |
2411 | | 0x90,0x97,0x10,0xf0,0x2e,0x78,0xd7,0x0e,0x42,0x80,0xb8,0x42,0x3c,0x21,0x3e,0x10, |
2412 | | 0x32,0x24,0x10,0x12,0x0a,0x89,0xb4,0x12,0x07,0x49,0x86,0xa4,0xfd,0x16,0xdc,0x77, |
2413 | | 0x85,0x90,0xa2,0x77,0x15,0x10,0xed,0xbb,0xd5,0x90,0xfa,0x77,0x9b,0x21,0xed,0xef, |
2414 | | 0xde,0xf8,0xb3,0xe8,0x7b,0x83,0xfe,0x77,0x87,0xde,0x7d,0x00,0x19,0x7b,0x77,0xe2, |
2415 | | 0x0f,0xf2,0x14,0x32,0x07,0x59,0x84,0xbc,0x84,0x80,0x43,0xe0,0x90,0x1d,0x84,0x00, |
2416 | | 0x71,0x85,0x78,0x42,0x7c,0x20,0x64,0x48,0xa0,0x95,0x50,0x48,0x24,0x24,0xee,0xb7, |
2417 | | 0x48,0x3e,0x94,0x06,0xe1,0x1e,0x12,0x42,0x8a,0x0e,0x29,0x20,0xda,0x43,0xd5,0x90, |
2418 | | 0xfa,0x43,0xcd,0x7f,0x16,0xed,0x56,0x6e,0x1c,0xea,0x3b,0x74,0xef,0xd0,0x03,0x8c, |
2419 | | 0xb1,0x43,0x13,0x7f,0x07,0x26,0x0f,0x4d,0x1d,0x9a,0x3e,0x64,0x39,0x34,0x7f,0x68, |
2420 | | 0xe1,0xd0,0xd2,0xa1,0xe5,0x43,0x2b,0x87,0x56,0x0f,0xe1,0xa8,0xb6,0x54,0x3c,0xd5, |
2421 | | 0x81,0xea,0x44,0x75,0xa1,0xba,0x51,0x3d,0xa8,0x5e,0x54,0x22,0xd5,0x97,0x4a,0xa2, |
2422 | | 0x52,0xa8,0x34,0x2a,0x9d,0x1a,0x42,0x0d,0xa3,0x46,0x50,0x19,0x54,0x16,0x35,0x9e, |
2423 | | 0xca,0xa6,0x72,0xa8,0xa9,0xd4,0x74,0x6a,0x26,0x95,0x47,0x15,0x50,0x45,0x54,0x09, |
2424 | | 0x55,0x4a,0x95,0x53,0x95,0x54,0x35,0x55,0x47,0x35,0x52,0x4d,0xd4,0x5a,0x6a,0x03, |
2425 | | 0xb5,0x89,0xda,0x42,0x6d,0xa3,0x76,0x50,0xbb,0xa8,0xdd,0x54,0x33,0xb5,0x9f,0x3a, |
2426 | | 0x48,0x1d,0xa2,0x0e,0x53,0x47,0xa8,0xa3,0xd4,0x31,0xea,0x38,0x75,0x92,0x3a,0x45, |
2427 | | 0x9d,0xa6,0x5a,0xa8,0xf3,0xd4,0x05,0xea,0x12,0x75,0x99,0xba,0x42,0x5d,0xa5,0xe2, |
2428 | | 0x68,0xb6,0x34,0x3c,0xcd,0x81,0xe6,0x44,0x73,0xa1,0xb9,0xd1,0x3c,0x68,0x5e,0x34, |
2429 | | 0x22,0xcd,0x97,0x46,0xa2,0x51,0x68,0x34,0x1a,0x9d,0x16,0x42,0x0b,0xa3,0x45,0xd0, |
2430 | | 0x18,0x34,0x16,0x2d,0xce,0x4a,0x3c,0x8d,0x4d,0xe3,0xd0,0x52,0x69,0xe9,0xb4,0x4c, |
2431 | | 0x1a,0x8f,0x26,0xa0,0x89,0x68,0x12,0x9a,0x94,0x26,0xa7,0x29,0x69,0x6a,0x9a,0xf6, |
2432 | | 0x9f,0x1c,0x1d,0xa4,0x96,0xd6,0x42,0xeb,0xa2,0xf5,0xd3,0x86,0x69,0x63,0xb4,0x29, |
2433 | | 0xda,0x3c,0x6d,0x99,0x86,0x7b,0xcf,0xe1,0x3d,0xb7,0xf7,0x88,0xef,0x51,0xde,0x0b, |
2434 | | 0x7b,0x2f,0xfe,0xbd,0xf4,0xf7,0x44,0xef,0x29,0xdf,0x33,0xbd,0xd7,0xf2,0x5e,0xf7, |
2435 | | 0x7b,0x43,0xef,0x8d,0xbd,0x37,0xfd,0xde,0xd2,0x7b,0xb8,0xf7,0x9d,0xde,0xf7,0x7a, |
2436 | | 0x3f,0xe4,0xfd,0xa4,0xf7,0xd9,0xef,0xa7,0xbf,0x2f,0x78,0x5f,0xfa,0xbe,0xfa,0x7d, |
2437 | | 0xd3,0xfb,0x4d,0xef,0x77,0xbc,0x6f,0x7e,0x7f,0xe8,0xfd,0xd1,0xf7,0x27,0xdf,0xb7, |
2438 | | 0xbc,0xbf,0xf4,0xfe,0xea,0xfb,0xf8,0x40,0x97,0x40,0xaf,0x40,0x52,0x20,0x3d,0x30, |
2439 | | 0x22,0x30,0x3e,0x30,0x35,0x90,0x17,0x28,0x09,0x54,0x06,0x1a,0x03,0x1b,0x02,0xdb, |
2440 | | 0x02,0xbb,0x03,0x07,0x03,0x47,0x02,0xc7,0x03,0xa7,0x03,0x17,0x02,0x57,0x02,0x6d, |
2441 | | 0xe9,0x78,0xba,0x03,0xdd,0x89,0xee,0xfc,0x3b,0xb8,0xd0,0xbd,0xe8,0xbe,0x74,0x0a, |
2442 | | 0x9d,0x4e,0x0f,0xa3,0x33,0xe8,0xf1,0x74,0x0e,0x3d,0x9d,0xce,0xa3,0x8b,0xe8,0x52, |
2443 | | 0xba,0x92,0xae,0xa3,0x9b,0xe8,0x0d,0xf4,0x26,0x7a,0x0b,0xbd,0x8d,0xde,0x41,0xef, |
2444 | | 0xa2,0x77,0xd3,0xcd,0xf4,0x7e,0xfa,0x20,0x7d,0x88,0x3e,0x4c,0x1f,0xa1,0x8f,0xd2, |
2445 | | 0xc7,0xe8,0x93,0xf4,0x69,0xfa,0x3c,0x7d,0x89,0xbe,0x42,0xc7,0x05,0xe1,0x83,0x9c, |
2446 | | 0x82,0xdc,0x82,0xbc,0x82,0x7c,0x83,0x28,0x41,0xf4,0xa0,0xb0,0x20,0x76,0x50,0x66, |
2447 | | 0x10,0x3f,0x48,0x10,0x24,0x0a,0x92,0x04,0x49,0x83,0xe4,0x41,0xca,0x20,0x75,0x90, |
2448 | | 0x2e,0xc8,0x18,0x64,0x0a,0xaa,0x0d,0x6a,0x08,0x6a,0x0a,0x6a,0x09,0x6a,0x0b,0xea, |
2449 | | 0x08,0xea,0x0a,0xea,0x0e,0x32,0x07,0xf5,0x07,0x0d,0x06,0x0d,0x05,0x0d,0x07,0x8d, |
2450 | | 0x04,0x8d,0x06,0x8d,0x05,0x8d,0x07,0x4d,0x06,0x4d,0x05,0x4d,0x07,0x59,0x82,0xe6, |
2451 | | 0x83,0x16,0x82,0x96,0x82,0x96,0x83,0x56,0x82,0x56,0x83,0x70,0x87,0x6d,0x0f,0xe3, |
2452 | | 0x0f,0x3b,0x1c,0x76,0x3a,0xec,0x72,0xd8,0xed,0xb0,0xc7,0x61,0xaf,0xc3,0xc4,0xc3, |
2453 | | 0xbe,0x87,0x49,0x87,0x29,0x87,0xe9,0x87,0xc3,0x0e,0x33,0x0e,0xc7,0x1f,0xe6,0x1c, |
2454 | | 0x4e,0x3f,0xcc,0x3b,0x2c,0x3a,0x2c,0x3d,0xac,0x3c,0xac,0x3b,0x6c,0x3a,0xdc,0x70, |
2455 | | 0xb8,0xe5,0x70,0xc7,0xe1,0xee,0xc3,0xfd,0x87,0x87,0x0e,0x8f,0x1c,0x1e,0x3b,0x3c, |
2456 | | 0x79,0x78,0xfa,0xf0,0xfc,0xe1,0xa5,0xc3,0xab,0x87,0xf1,0xc1,0x2e,0xc1,0x1e,0xc1, |
2457 | | 0xbe,0xc1,0x94,0xe0,0x90,0xe0,0xb0,0xe0,0x88,0x60,0x46,0x30,0x2b,0x38,0x3e,0x98, |
2458 | | 0x1d,0xcc,0x09,0x4e,0x0d,0x4e,0x0f,0xce,0x0c,0xe6,0x05,0x0b,0x82,0x45,0xc1,0x92, |
2459 | | 0x60,0x69,0xb0,0x3c,0x58,0x19,0xac,0x0e,0xd6,0x05,0x1b,0x83,0x4d,0xc1,0xb5,0xc1, |
2460 | | 0x0d,0xc1,0x4d,0xc1,0x2d,0xc1,0x6d,0xc1,0x1d,0xc1,0x5d,0xc1,0xdd,0xc1,0xe6,0xe0, |
2461 | | 0xfe,0xe0,0xc1,0xe0,0xa1,0xe0,0xe1,0xe0,0x91,0xe0,0xd1,0xe0,0xb1,0xe0,0xf1,0xe0, |
2462 | | 0xc9,0xe0,0xa9,0xe0,0xe9,0x60,0x4b,0xf0,0x7c,0xf0,0x42,0xf0,0x52,0xf0,0x72,0xf0, |
2463 | | 0x4a,0x30,0x2e,0x04,0x17,0xe2,0x12,0x42,0x0c,0xa1,0x87,0x44,0x84,0x70,0x42,0x32, |
2464 | | 0x43,0x44,0x21,0xba,0x90,0x86,0x90,0xb6,0x90,0xee,0x90,0xc1,0x90,0xd1,0x90,0xa9, |
2465 | | 0x90,0x85,0x90,0xd5,0x10,0x87,0x0f,0x3c,0x3e,0x20,0x7d,0x10,0xf1,0x01,0xeb,0x83, |
2466 | | 0xcc,0x0f,0xe4,0x1f,0x98,0x3e,0x68,0xf9,0xa0,0xff,0x83,0xb1,0x0f,0xa6,0x3f,0x58, |
2467 | | 0xf8,0x60,0xe5,0x03,0xfc,0x87,0x6e,0x1f,0x92,0x3e,0x0c,0xfb,0x90,0xf5,0x21,0xe7, |
2468 | | 0x43,0xde,0x87,0x92,0x0f,0x95,0x1f,0xea,0x3e,0x34,0x7d,0xd8,0xf4,0x61,0xc7,0x87, |
2469 | | 0x43,0x1f,0x8e,0x7d,0x68,0xf9,0x70,0xf5,0x43,0x87,0x50,0xb7,0x50,0x62,0x68,0x48, |
2470 | | 0x28,0x2b,0x34,0x33,0x54,0x14,0xaa,0x0e,0x35,0x85,0xb6,0x84,0x76,0x85,0x0e,0x86, |
2471 | | 0x8e,0x85,0x4e,0x87,0x2e,0x87,0xda,0x86,0x39,0x84,0x79,0x85,0x91,0xc2,0xe8,0x61, |
2472 | | 0x8c,0x30,0x76,0x58,0x7a,0x98,0x20,0x4c,0x19,0x66,0x0a,0x6b,0x08,0xeb,0x0e,0x1b, |
2473 | | 0x0c,0x1b,0x0b,0x9b,0x0e,0x5b,0x0a,0x5b,0x0d,0xc3,0x1f,0x71,0x3b,0xe2,0x75,0x84, |
2474 | | 0x72,0x24,0xe2,0x08,0xeb,0x48,0xe6,0x11,0xd1,0x11,0xe9,0x11,0xe5,0x11,0xdd,0x11, |
2475 | | 0xd3,0x91,0x86,0x23,0x2d,0x47,0x3a,0x8e,0x74,0x1f,0xe9,0x3f,0x32,0x74,0x64,0xf4, |
2476 | | 0xc8,0xe4,0x11,0xcb,0x91,0xa5,0x23,0xab,0x47,0xf0,0x47,0x5d,0x8e,0x7a,0x1d,0x25, |
2477 | | 0x1d,0xa5,0x1f,0x8d,0x38,0x1a,0x7f,0x34,0xf5,0x28,0xef,0xa8,0xe4,0xa8,0xf2,0xa8, |
2478 | | 0xee,0xa8,0xe9,0x68,0xd3,0xd1,0xb6,0xa3,0x5d,0x47,0xcd,0x47,0x87,0x8e,0x8e,0x1e, |
2479 | | 0x1d,0x3f,0x3a,0x75,0xd4,0x72,0x74,0xe1,0xe8,0xf2,0x51,0xdb,0x70,0x87,0x70,0x97, |
2480 | | 0x70,0x8f,0x70,0x62,0x38,0x29,0x9c,0x16,0x1e,0x12,0x1e,0x11,0x1e,0x1f,0x9e,0x1e, |
2481 | | 0xce,0x0b,0x17,0x85,0x4b,0xc3,0x95,0xe1,0xba,0x70,0x53,0x78,0x43,0x78,0x5b,0x78, |
2482 | | 0x77,0xf8,0x60,0xf8,0x48,0xf8,0x58,0xf8,0x64,0xf8,0x74,0xf8,0x7c,0xf8,0x52,0xf8, |
2483 | | 0x4a,0x38,0x2e,0x02,0x1f,0xe1,0x14,0xe1,0x16,0x41,0x8c,0xa0,0x44,0xd0,0x23,0x22, |
2484 | | 0x22,0xe2,0x23,0x52,0x23,0x32,0x23,0x44,0x11,0xf2,0x08,0x63,0x44,0x6d,0x44,0x4b, |
2485 | | 0x44,0x57,0x44,0x7f,0xc4,0x70,0xc4,0x64,0xc4,0x52,0xc4,0x4a,0x04,0xee,0x18,0xfe, |
2486 | | 0x98,0xd3,0x31,0xb7,0x63,0x5e,0xc7,0x7c,0x8f,0x51,0x8e,0xd1,0x8f,0x85,0x1d,0x63, |
2487 | | 0x1c,0x8b,0x3f,0xc6,0x39,0x96,0x7e,0x8c,0x77,0x4c,0x74,0x4c,0x7a,0x4c,0x79,0xcc, |
2488 | | 0x74,0xac,0xe1,0x58,0xcb,0xb1,0x8e,0x63,0xfd,0xc7,0x86,0x8f,0x8d,0x1e,0x1b,0x3f, |
2489 | | 0x36,0x75,0xcc,0x72,0x6c,0xe1,0xd8,0xf2,0xb1,0xd5,0x63,0xb6,0xc7,0x1d,0x8e,0xbb, |
2490 | | 0x1c,0xf7,0x3a,0xee,0x7b,0x9c,0x72,0x3c,0xe4,0x38,0xe3,0x78,0xfc,0xf1,0xf4,0xe3, |
2491 | | 0x82,0xe3,0x92,0xe3,0xf2,0xe3,0xea,0xe3,0xc6,0xe3,0x0d,0xc7,0xdb,0x8e,0x77,0x1d, |
2492 | | 0x37,0x1f,0x1f,0x3c,0x3e,0x7c,0x7c,0xf4,0xf8,0xf8,0xf1,0xa9,0xe3,0x96,0xe3,0x0b, |
2493 | | 0xc7,0x57,0x8e,0xdb,0x46,0x3a,0x45,0x7a,0x44,0xfa,0x46,0xd2,0x22,0xc3,0x22,0x59, |
2494 | | 0x91,0x9c,0xc8,0xcc,0x48,0x51,0xa4,0x3c,0x52,0x17,0x59,0x1b,0xd9,0x12,0xd9,0x15, |
2495 | | 0xd9,0x1f,0x39,0x1c,0x39,0x16,0x39,0x15,0x39,0x1f,0xb9,0x1c,0x09,0x18,0xeb,0xfc, |
2496 | | 0x65,0xe0,0x18,0xb6,0x0c,0xbb,0x75,0xfe,0x09,0xc0,0x33,0xec,0xff,0xed,0x71,0x60, |
2497 | | 0x38,0x31,0x5c,0x18,0xae,0x56,0xdc,0x18,0x1e,0x0c,0xcf,0x7f,0x09,0xbc,0x18,0x44, |
2498 | | 0x86,0x2f,0x83,0xc4,0x20,0xff,0x1f,0x50,0x18,0xd4,0x75,0xfe,0x2c,0x02,0x19,0xc1, |
2499 | | 0x8c,0x50,0x46,0x38,0x23,0x92,0xc1,0x64,0xc4,0x31,0x92,0x18,0xc9,0x8c,0x14,0x46, |
2500 | | 0x1a,0x23,0x83,0xc1,0x65,0xf0,0x19,0x42,0x86,0x98,0x51,0xc4,0x90,0x31,0x14,0x0c, |
2501 | | 0x15,0x43,0xcb,0x30,0x30,0xaa,0x19,0x35,0x8c,0x7a,0x46,0x23,0xa3,0x99,0xd1,0xca, |
2502 | | 0x68,0x67,0x74,0x32,0x6e,0x30,0x7a,0x19,0x7d,0x8c,0x01,0xc6,0x3d,0xc6,0x7d,0xc6, |
2503 | | 0x03,0xc6,0x43,0xc6,0x23,0xc6,0x63,0xc6,0x04,0xe3,0x09,0xe3,0x29,0x63,0x86,0x31, |
2504 | | 0xc7,0x78,0xce,0x58,0x64,0xbc,0x60,0xbc,0x64,0xbc,0x62,0x80,0x28,0x9b,0x28,0xbb, |
2505 | | 0x28,0xfb,0x28,0x42,0x94,0x73,0x94,0x6b,0x94,0x7b,0x94,0x67,0x94,0x77,0x94,0x4f, |
2506 | | 0x94,0x5f,0x14,0x39,0x8a,0x1a,0x15,0x18,0x15,0x1c,0x15,0x1a,0x15,0x1e,0x15,0x19, |
2507 | | 0xc5,0x8c,0x8a,0x8b,0x4a,0x8a,0x4a,0x8e,0x4a,0x89,0x4a,0x8b,0xca,0x88,0xe2,0x46, |
2508 | | 0xf1,0xa3,0x84,0x51,0xe2,0xa8,0xa2,0x28,0x59,0x94,0x22,0x4a,0x15,0xa5,0x8d,0x32, |
2509 | | 0x44,0x55,0x47,0xd5,0x44,0xd5,0x47,0x35,0x46,0x35,0x47,0xb5,0x46,0xb5,0x47,0x75, |
2510 | | 0x46,0xdd,0x88,0xea,0x8d,0xea,0x8b,0x1a,0x88,0xba,0x17,0x75,0x3f,0xea,0x41,0xd4, |
2511 | | 0xc3,0xa8,0x47,0x51,0x8f,0xa3,0x26,0xa2,0x9e,0x44,0x3d,0x8d,0x9a,0x89,0x9a,0x8b, |
2512 | | 0x7a,0x1e,0xb5,0x18,0xf5,0x22,0xea,0x65,0xd4,0xab,0x28,0x10,0x6d,0x13,0x6d,0x17, |
2513 | | 0x6d,0x1f,0x4d,0x88,0x76,0x8e,0x76,0x8d,0x76,0x8f,0xf6,0x8c,0xf6,0x8e,0xf6,0x89, |
2514 | | 0xf6,0x8b,0x26,0x47,0x53,0xa3,0x03,0xa3,0x83,0xa3,0x43,0xa3,0xc3,0xa3,0x23,0xa3, |
2515 | | 0x99,0xd1,0x71,0xd1,0x49,0xd1,0xc9,0xd1,0x29,0xd1,0x69,0xd1,0x19,0xd1,0xdc,0x68, |
2516 | | 0x7e,0xb4,0x30,0x5a,0x1c,0x5d,0x14,0x2d,0x8b,0x56,0x44,0xab,0xa2,0xb5,0xd1,0x86, |
2517 | | 0xe8,0xea,0xe8,0x9a,0xe8,0xfa,0xe8,0xc6,0xe8,0xe6,0xe8,0xd6,0xe8,0xf6,0xe8,0xce, |
2518 | | 0xe8,0x1b,0xd1,0xbd,0xd1,0x7d,0xd1,0x03,0xd1,0xf7,0xa2,0xef,0x47,0x3f,0x88,0x7e, |
2519 | | 0x18,0xfd,0x28,0xfa,0x71,0xf4,0x44,0xf4,0x93,0xe8,0xa7,0xd1,0x33,0xd1,0x73,0xd1, |
2520 | | 0xcf,0xa3,0x17,0xa3,0x5f,0x44,0xbf,0x8c,0x7e,0x15,0x0d,0x98,0x36,0x4c,0x3b,0xa6, |
2521 | | 0x3d,0x93,0xc0,0x74,0x66,0xba,0x32,0xdd,0x99,0x9e,0x4c,0x6f,0xa6,0x0f,0xd3,0x8f, |
2522 | | 0x49,0x66,0x52,0x99,0x81,0xcc,0x60,0x66,0x28,0x33,0x9c,0x19,0xc9,0x64,0x32,0xe3, |
2523 | | 0x98,0x49,0xcc,0x64,0x66,0x0a,0x33,0x8d,0x99,0xc1,0xe4,0x32,0xf9,0x4c,0x21,0x53, |
2524 | | 0xcc,0x2c,0x62,0xca,0x98,0x0a,0xa6,0x8a,0xa9,0x65,0x1a,0x98,0xd5,0xcc,0x1a,0x66, |
2525 | | 0x3d,0xb3,0x91,0xd9,0xcc,0x6c,0x65,0xb6,0x33,0x3b,0x99,0x37,0x98,0xbd,0xcc,0x3e, |
2526 | | 0xe6,0x00,0xf3,0x1e,0xf3,0x3e,0xf3,0x01,0xf3,0x21,0xf3,0x11,0xf3,0x31,0x73,0x82, |
2527 | | 0xf9,0x84,0xf9,0x94,0x39,0xc3,0x9c,0x63,0x3e,0x67,0x2e,0x32,0x5f,0x30,0x5f,0x32, |
2528 | | 0x5f,0x31,0x01,0xcb,0x86,0x65,0xc7,0xb2,0x67,0x11,0x58,0xce,0x2c,0x57,0x96,0x3b, |
2529 | | 0xcb,0x93,0xe5,0xcd,0xf2,0x61,0xf9,0xb1,0xc8,0x2c,0xf8,0x85,0x8b,0x15,0xc8,0x0a, |
2530 | | 0x66,0x85,0xb2,0xc2,0x59,0x91,0x2c,0x26,0x2b,0x8e,0x95,0xc4,0x4a,0x66,0xa5,0xb0, |
2531 | | 0xd2,0x58,0x19,0x2c,0x2e,0x8b,0x6f,0x45,0x08,0x11,0x5b,0x29,0x62,0xc9,0x58,0x0a, |
2532 | | 0x96,0x8a,0xa5,0x65,0x19,0x58,0xd5,0xac,0x1a,0x56,0x3d,0xab,0x11,0xd2,0x0c,0x69, |
2533 | | 0xb5,0xd2,0xce,0xea,0xc4,0xb8,0xc1,0xea,0x65,0xf5,0xb1,0x06,0x58,0xf7,0x58,0xf7, |
2534 | | 0x59,0x0f,0x58,0x0f,0x59,0x8f,0x58,0x8f,0x59,0x13,0xac,0x27,0xac,0xa7,0xac,0x19, |
2535 | | 0xd6,0x1c,0xeb,0x39,0x6b,0x91,0xf5,0x82,0xf5,0x92,0xf5,0x8a,0x05,0x62,0x6c,0x62, |
2536 | | 0xec,0x62,0xec,0x63,0x08,0x31,0xce,0x31,0xae,0x31,0xee,0x31,0x9e,0x31,0xde,0x31, |
2537 | | 0x3e,0x31,0x7e,0x31,0xe4,0x18,0x6a,0x4c,0x60,0x4c,0x70,0x4c,0x68,0x4c,0x78,0x4c, |
2538 | | 0x64,0x0c,0x33,0x26,0x2e,0x26,0x29,0x26,0x39,0x26,0x25,0x26,0x2d,0x26,0x23,0x86, |
2539 | | 0x1b,0xc3,0x8f,0x11,0xc6,0x88,0x63,0x8a,0x62,0x64,0x31,0x8a,0x18,0x55,0x8c,0x36, |
2540 | | 0xc6,0x10,0x53,0x1d,0x53,0x13,0x53,0x1f,0xd3,0x18,0xd3,0x1c,0xd3,0x1a,0xd3,0x1e, |
2541 | | 0xd3,0x19,0x73,0x23,0xa6,0x37,0xa6,0x2f,0x66,0xc0,0xca,0xbd,0x98,0xfb,0x31,0x0f, |
2542 | | 0x62,0x1e,0xc6,0x3c,0x8a,0x79,0x1c,0x33,0x11,0xf3,0x24,0xe6,0x69,0xcc,0x4c,0xcc, |
2543 | | 0x5c,0xcc,0xf3,0x98,0xc5,0x98,0x17,0x31,0x2f,0x63,0x5e,0xc5,0x80,0x58,0x9b,0x58, |
2544 | | 0xbb,0x58,0xfb,0x58,0x42,0xac,0x73,0xac,0x6b,0xac,0x7b,0xac,0x67,0xac,0x77,0xac, |
2545 | | 0x4f,0xac,0x5f,0x2c,0x39,0x96,0x1a,0x1b,0x18,0x1b,0x1c,0x1b,0x1a,0x1b,0x1e,0x1b, |
2546 | | 0x19,0xcb,0x8c,0x8d,0x8b,0x4d,0x8a,0x4d,0x8e,0x4d,0x89,0x4d,0x8b,0xcd,0x88,0xe5, |
2547 | | 0xc6,0xf2,0x63,0x85,0xb1,0xe2,0xd8,0xa2,0x58,0x59,0xac,0x22,0x56,0x15,0xab,0x8d, |
2548 | | 0x35,0xc4,0x56,0xc7,0xd6,0xc4,0xd6,0xc7,0x36,0xc6,0x36,0xc7,0xb6,0xc6,0xb6,0xc7, |
2549 | | 0x76,0xc6,0xde,0x88,0xed,0x8d,0xed,0x8b,0x1d,0x88,0xbd,0x17,0x7b,0x3f,0xf6,0x41, |
2550 | | 0xec,0xc3,0xd8,0x47,0xb1,0x8f,0x63,0x27,0x62,0x9f,0xc4,0x3e,0x8d,0x9d,0x89,0x9d, |
2551 | | 0x8b,0x7d,0x1e,0xbb,0x18,0xfb,0x22,0xf6,0x65,0xec,0xab,0x58,0x10,0x67,0x13,0x67, |
2552 | | 0x17,0x67,0x1f,0x47,0x88,0x73,0x8e,0x73,0x8d,0x73,0x8f,0xf3,0x8c,0xf3,0x8e,0xf3, |
2553 | | 0x89,0xf3,0x8b,0x23,0xc7,0x51,0xe3,0x02,0xe3,0x82,0xe3,0x42,0xe3,0xc2,0xe3,0x22, |
2554 | | 0xe3,0x98,0x71,0x71,0x71,0x49,0x71,0xc9,0x71,0x29,0x71,0x69,0x71,0x19,0xbf,0x22, |
2555 | | 0x99,0x10,0x41,0x9c,0x24,0x4e,0x1e,0xa7,0x8b,0xab,0x8d,0x6b,0x8a,0x6b,0xfd,0x03, |
2556 | | 0xb4,0xc5,0x75,0xc5,0x99,0xe3,0x06,0xe3,0x86,0xe3,0x1e,0xbe,0xc1,0x63,0xc8,0x54, |
2557 | | 0xdc,0x74,0x9c,0x25,0x6e,0x3e,0x6e,0x21,0x6e,0x29,0x6e,0x39,0x6e,0x25,0x6e,0x35, |
2558 | | 0x0e,0x17,0x6f,0x13,0x6f,0x1f,0xef,0x1c,0xef,0x19,0xef,0x17,0x4f,0x8d,0x0f,0x8e, |
2559 | | 0x0f,0x8f,0x67,0xc6,0x27,0xc5,0xa7,0xc4,0x67,0xc4,0xf3,0xe3,0xc5,0x10,0x59,0xbc, |
2560 | | 0x2a,0xde,0x10,0x5f,0x13,0xdf,0x08,0x69,0x85,0x74,0xc6,0xf7,0x42,0x06,0xe2,0xef, |
2561 | | 0x43,0x1e,0xc6,0x3f,0x8e,0x7f,0x12,0x3f,0x13,0xff,0x3c,0xfe,0x45,0xfc,0xab,0x78, |
2562 | | 0x9b,0x04,0x87,0x04,0x97,0x04,0xb7,0x04,0x8f,0x04,0xaf,0x04,0x62,0x82,0x6f,0x02, |
2563 | | 0x29,0x81,0x92,0x40,0x4b,0xa0,0x27,0x84,0x24,0x84,0x25,0x44,0x24,0x30,0x12,0x58, |
2564 | | 0x09,0xf1,0x09,0xec,0x04,0x4e,0x42,0x6a,0x42,0x7a,0x42,0x66,0x02,0x2f,0x41,0x90, |
2565 | | 0x20,0x4a,0x90,0x24,0x48,0x13,0xe4,0x09,0xca,0x04,0x75,0x82,0x2e,0xc1,0x98,0x60, |
2566 | | 0x4a,0xa8,0x4d,0x68,0x48,0x68,0x4a,0x68,0x49,0x68,0x4b,0xe8,0x48,0xe8,0x4a,0xe8, |
2567 | | 0x4e,0x30,0x27,0xf4,0x27,0x0c,0x26,0x0c,0x25,0x0c,0x27,0x8c,0x24,0x8c,0x26,0x8c, |
2568 | | 0x25,0x8c,0x27,0x4c,0x26,0x4c,0x25,0x4c,0x27,0x58,0x12,0xe6,0x13,0x16,0x12,0x96, |
2569 | | 0x12,0x96,0x13,0x56,0x12,0x56,0x13,0x70,0x89,0xb6,0x89,0xf8,0x44,0x87,0x44,0xa7, |
2570 | | 0x44,0x97,0x44,0xb7,0x44,0x8f,0x44,0xaf,0x44,0x62,0xa2,0x6f,0x22,0x29,0x91,0x92, |
2571 | | 0x48,0x4b,0xa4,0x27,0x86,0x24,0x86,0x25,0x46,0x24,0x32,0x12,0x59,0x89,0xf1,0x89, |
2572 | | 0xec,0x44,0x4e,0x62,0x6a,0x62,0x7a,0x62,0x66,0xa2,0x20,0x51,0x92,0x28,0x4d,0x94, |
2573 | | 0x27,0x2a,0x13,0xd5,0x89,0xba,0x44,0x63,0xa2,0x29,0xb1,0x36,0xb1,0x21,0xb1,0x29, |
2574 | | 0xb1,0x2d,0xb1,0xf3,0xaf,0xa6,0x2b,0xb1,0x3b,0xd1,0x9c,0xd8,0x9f,0x38,0x98,0x38, |
2575 | | 0x94,0x38,0x9c,0x38,0x92,0x38,0x9a,0x38,0x96,0x38,0x9e,0x38,0x95,0x38,0x9d,0x68, |
2576 | | 0x49,0x9c,0x4f,0x5c,0x48,0x5c,0x4a,0x5c,0x4e,0x5c,0x49,0x5c,0x4d,0xc4,0x25,0xd9, |
2577 | | 0x26,0xe1,0x93,0x1c,0x92,0xdc,0x92,0x88,0x49,0x94,0xa4,0x90,0x24,0x46,0x12,0x3b, |
2578 | | 0x29,0x3d,0x49,0x90,0x24,0x4d,0x52,0x27,0x99,0x92,0x9a,0x92,0x3a,0x92,0xcc,0x49, |
2579 | | 0x43,0x49,0xa3,0x49,0x93,0x49,0x96,0xa4,0xf9,0xa4,0x85,0xa4,0xa5,0xa4,0x65,0x08, |
2580 | | 0x8e,0xed,0xc0,0x76,0x63,0x13,0xd9,0x14,0x36,0x9d,0x1d,0xc6,0x66,0xb0,0xe3,0xd9, |
2581 | | 0x1c,0x76,0x3a,0x9b,0xc7,0x16,0xb1,0xa5,0x6c,0x25,0x5b,0xc7,0x36,0xb1,0x1b,0xd8, |
2582 | | 0x2d,0xec,0x0e,0x76,0x37,0xbb,0x9f,0x3d,0xc4,0x1e,0x61,0x8f,0xb1,0x27,0xd9,0xd3, |
2583 | | 0xec,0x79,0xf6,0x12,0x7b,0x85,0x8d,0x3b,0x81,0x3f,0xe1,0x74,0xc2,0xed,0x84,0xd7, |
2584 | | 0x09,0xdf,0x13,0x94,0x13,0xf4,0x13,0x61,0x27,0x18,0x27,0xe2,0x4f,0x70,0x4e,0xa4, |
2585 | | 0x9f,0xe0,0x9d,0x10,0x9d,0x90,0x9e,0x50,0x9e,0xd0,0x9d,0x30,0x9d,0x68,0x38,0xd1, |
2586 | | 0x72,0xa2,0xe3,0x44,0xf7,0x89,0xfe,0x13,0x43,0x27,0x46,0x4e,0x8c,0x9d,0x98,0x3c, |
2587 | | 0x31,0x7d,0x62,0xfe,0xc4,0xd2,0x89,0x95,0x13,0xb8,0x93,0xf8,0x93,0x4e,0x27,0xdd, |
2588 | | 0x4e,0x7a,0x9d,0xf4,0x3d,0x49,0x39,0x49,0x3f,0x19,0x76,0x92,0x71,0x32,0xfe,0x24, |
2589 | | 0xe7,0x64,0xfa,0x49,0xde,0x49,0xd1,0x49,0xe9,0x49,0xe5,0x49,0xdd,0x49,0xd3,0xc9, |
2590 | | 0x86,0x93,0x2d,0x27,0x3b,0x4e,0x76,0x9f,0xec,0x3f,0x39,0x74,0x72,0xe4,0xe4,0xd8, |
2591 | | 0xc9,0xc9,0x93,0xd3,0x27,0xe7,0x4f,0x2e,0x9d,0x5c,0x39,0x69,0x9b,0xec,0x94,0xec, |
2592 | | 0x91,0xec,0x9b,0x4c,0x4b,0x0e,0x4b,0x66,0x25,0x73,0x92,0x33,0x93,0x45,0xc9,0xf2, |
2593 | | 0x64,0x5d,0xb2,0x29,0xb9,0x21,0xb9,0x25,0xb9,0x23,0xb9,0x3b,0xb9,0x3f,0x79,0x28, |
2594 | | 0x79,0x24,0x79,0x2c,0x79,0x32,0x79,0x3a,0x79,0x3e,0x79,0x29,0x79,0x25,0x19,0xc7, |
2595 | | 0xc1,0x73,0x9c,0x38,0x6e,0x1c,0x2f,0x8e,0x2f,0x87,0xc2,0xa1,0x73,0xc2,0x38,0x0c, |
2596 | | 0x4e,0x3c,0x87,0xc3,0x49,0xe7,0xf0,0x38,0x22,0x8e,0x94,0xa3,0xe4,0xe8,0x38,0x26, |
2597 | | 0x4e,0x03,0xa7,0x85,0xd3,0xc1,0xe9,0xe6,0xf4,0x73,0x86,0x38,0x23,0x9c,0x31,0xce, |
2598 | | 0x24,0x67,0x9a,0x33,0xcf,0x59,0xe2,0xac,0x72,0xf0,0xa7,0x5c,0x4e,0x79,0x9d,0x22, |
2599 | | 0x9d,0xa2,0x9d,0x0a,0x39,0x15,0x71,0x8a,0x75,0x8a,0x7d,0x2a,0xf5,0x54,0xe6,0x29, |
2600 | | 0xc1,0x29,0xc9,0x29,0xf9,0x29,0xf5,0x29,0xe3,0xa9,0xda,0x53,0x4d,0xa7,0xda,0x4e, |
2601 | | 0x75,0x9d,0x32,0x9f,0x1a,0x3c,0x35,0x7c,0x6a,0xf4,0xd4,0xf8,0xa9,0xa9,0x53,0x96, |
2602 | | 0x53,0x0b,0xa7,0x96,0x4f,0xad,0x9e,0xb2,0x3d,0xed,0x70,0xda,0xe5,0xb4,0xc7,0x69, |
2603 | | 0xe2,0x69,0xd2,0x69,0xda,0xe9,0x90,0xd3,0x11,0xa7,0x59,0xa7,0xd9,0xa7,0x53,0x4f, |
2604 | | 0x67,0x9e,0x16,0x9c,0x96,0x9c,0x96,0x9f,0x56,0x9f,0x36,0x9e,0xae,0x3d,0xdd,0x74, |
2605 | | 0xba,0xed,0x74,0xd7,0x69,0xf3,0xe9,0xc1,0xd3,0xc3,0xa7,0x47,0x4f,0x8f,0x9f,0x9e, |
2606 | | 0x3a,0x6d,0x39,0xbd,0x70,0x7a,0xf9,0xf4,0xea,0x69,0xdb,0x14,0x87,0x14,0x97,0x14, |
2607 | | 0x8f,0x14,0x62,0x0a,0x29,0x85,0x96,0x12,0x92,0x12,0x91,0x12,0x9f,0x92,0x9a,0x92, |
2608 | | 0x99,0x22,0x48,0x91,0xa4,0xc8,0x53,0xd4,0x29,0xc6,0x94,0xda,0x94,0xa6,0x94,0xb6, |
2609 | | 0x94,0xae,0x14,0x73,0xca,0x60,0xca,0x70,0xca,0x68,0xca,0x78,0xca,0x54,0x8a,0x25, |
2610 | | 0x65,0x29,0x65,0x35,0x05,0x9f,0xea,0x94,0xea,0x96,0xea,0x95,0xea,0x9b,0x4a,0x49, |
2611 | | 0xa5,0xa7,0x86,0xa5,0x32,0x52,0xe3,0x53,0x39,0xa9,0xe9,0x10,0x5e,0xaa,0x28,0x55, |
2612 | | 0x9a,0xaa,0x4c,0xd5,0xa5,0x9a,0x52,0x1b,0x52,0x5b,0x52,0x3b,0x52,0xbb,0x53,0xfb, |
2613 | | 0x53,0x87,0x52,0x47,0x52,0xc7,0x52,0x27,0x53,0xa7,0x53,0xe7,0x53,0x97,0x52,0x57, |
2614 | | 0x52,0x71,0x67,0xf0,0x67,0x9c,0xce,0xb8,0x9d,0xf1,0x3a,0xe3,0x7b,0x86,0x72,0x86, |
2615 | | 0x7e,0x26,0xec,0x0c,0xe3,0x4c,0xfc,0x19,0xce,0x99,0xf4,0x33,0xbc,0x33,0xa2,0x33, |
2616 | | 0xd2,0x33,0xca,0x33,0xba,0x33,0xa6,0x33,0x0d,0x67,0x5a,0xce,0x74,0x9c,0xe9,0x3e, |
2617 | | 0xd3,0x7f,0x66,0xe8,0xcc,0xc8,0x99,0xb1,0x33,0x93,0x67,0xa6,0xcf,0xcc,0x9f,0x59, |
2618 | | 0x3a,0xb3,0x72,0x06,0x77,0x16,0x7f,0xd6,0xe9,0xac,0xdb,0x59,0xaf,0xb3,0xbe,0x67, |
2619 | | 0x29,0x67,0xe9,0x67,0xc3,0xce,0x32,0xce,0xc6,0xfd,0x09,0xc4,0x9f,0x4d,0x3d,0xcb, |
2620 | | 0x3b,0x2b,0x39,0xab,0x3c,0x6b,0x3c,0xdb,0x70,0xb6,0xed,0x6c,0xf7,0xd9,0xc1,0xb3, |
2621 | | 0x23,0x67,0xc7,0xcf,0x4e,0x9f,0x5d,0x38,0xbb,0x72,0xd6,0x36,0xcd,0x29,0xcd,0x23, |
2622 | | 0xcd,0x37,0x8d,0x96,0x16,0x96,0xc6,0x4a,0xe3,0xa4,0x65,0xa6,0x89,0xd2,0xe4,0x69, |
2623 | | 0xba,0xb4,0xda,0xb4,0x96,0xb4,0xae,0xb4,0xfe,0xb4,0xe1,0xb4,0xb1,0xb4,0xa9,0xb4, |
2624 | | 0xf9,0xb4,0xe5,0x34,0x5c,0xba,0x43,0xba,0x5b,0x3a,0x31,0x9d,0x92,0x1e,0x92,0xce, |
2625 | | 0x48,0x67,0xa7,0xa7,0xa7,0x0b,0xd2,0xa5,0xe9,0xea,0x74,0x53,0x7a,0x53,0x7a,0x47, |
2626 | | 0xba,0x39,0x7d,0x28,0x7d,0x34,0x7d,0x32,0xdd,0x92,0xbe,0x94,0xbe,0x9a,0x8e,0xff, |
2627 | | 0xc8,0xe5,0x23,0xaf,0x8f,0x48,0x1f,0xd1,0x3f,0x8a,0xf8,0x28,0x0e,0x12,0xff,0x51, |
2628 | | 0xea,0x47,0xbc,0x8f,0x24,0x1f,0x29,0x3f,0x32,0x7e,0xd4,0xf0,0x51,0xdb,0x47,0xdd, |
2629 | | 0x1f,0x0d,0x7e,0x34,0xf2,0xd1,0xf8,0x47,0xd3,0x1f,0x2d,0x7c,0xb4,0xf2,0x91,0xed, |
2630 | | 0xc7,0x4e,0x1f,0x7b,0x7c,0xec,0xfb,0x31,0xed,0xe3,0xb0,0x8f,0x59,0x1f,0x73,0x3e, |
2631 | | 0xce,0xfc,0x58,0xf4,0xb1,0xfc,0x63,0xdd,0xc7,0xb5,0x1f,0xb7,0x7c,0xdc,0xf5,0x71, |
2632 | | 0xff,0xc7,0xc3,0x1f,0x8f,0x7d,0x3c,0xf5,0xf1,0xfc,0xc7,0xcb,0x1f,0xe3,0x32,0x1c, |
2633 | | 0x32,0xdc,0x32,0x88,0x19,0x94,0x8c,0x90,0x0c,0x46,0x06,0x3b,0x23,0x3d,0x43,0x90, |
2634 | | 0x21,0xcd,0x50,0x67,0x98,0x32,0x9a,0x32,0x3a,0x32,0xcc,0x19,0x43,0x19,0xa3,0x19, |
2635 | | 0x13,0xbf,0x32,0x93,0x19,0x96,0x8c,0xa5,0x0c,0x5c,0xa6,0x53,0xa6,0x57,0x26,0x25, |
2636 | | 0x33,0x2c,0x33,0x3e,0x33,0x3d,0x53,0x90,0x69,0xce,0x1c,0xcf,0x9c,0xf9,0x13,0xb1, |
2637 | | 0x64,0xce,0x67,0x2e,0x64,0x2e,0x65,0x2e,0x67,0xae,0x64,0xae,0x66,0xe2,0xb2,0x6c, |
2638 | | 0xb3,0xf0,0x59,0xce,0x7f,0x06,0x2e,0x59,0x1e,0x59,0x5e,0x59,0xc4,0x2c,0xdf,0x2c, |
2639 | | 0x52,0x16,0x25,0x8b,0x96,0x45,0xcf,0x0a,0xc9,0x0a,0xcb,0x8a,0xc8,0x62,0x64,0xb1, |
2640 | | 0xb2,0xe2,0xb3,0xd8,0x59,0x9c,0xac,0xd4,0xac,0xf4,0xac,0xcc,0x2c,0x5e,0x16,0x1f, |
2641 | | 0x22,0xc8,0x12,0x65,0x49,0xb2,0xe4,0x59,0xea,0x2c,0x63,0x56,0x6d,0x56,0x43,0x56, |
2642 | | 0x53,0x56,0x4b,0x56,0x5b,0x56,0x47,0x56,0x67,0x56,0x57,0x56,0x77,0x96,0x39,0xab, |
2643 | | 0x3f,0x6b,0x30,0x6b,0x28,0x6b,0x38,0x6b,0x24,0x6b,0x34,0x6b,0x2c,0x6b,0x3c,0x6b, |
2644 | | 0x32,0x6b,0x2a,0x6b,0x3a,0xcb,0x92,0x35,0x9f,0xb5,0x90,0xb5,0x94,0xb5,0x9c,0xf5, |
2645 | | 0x32,0x6b,0x25,0x6b,0x35,0x0b,0x77,0xce,0xf6,0x9c,0x1d,0x06,0xfe,0x9c,0xd3,0x39, |
2646 | | 0xb7,0x73,0x9e,0xe7,0xbc,0xce,0xf9,0x9c,0xf3,0x3d,0x47,0x39,0x47,0x3f,0x17,0x76, |
2647 | | 0x8e,0x71,0x2e,0xfe,0x1c,0xe7,0x5c,0xfa,0x39,0xde,0x39,0xd1,0x39,0xe9,0x39,0xf9, |
2648 | | 0x39,0xf5,0x39,0xe3,0xb9,0xda,0x73,0x4d,0xe7,0xda,0xce,0x75,0x9d,0x33,0x9f,0x1b, |
2649 | | 0x3c,0x37,0x7c,0x6e,0xf4,0xdc,0xf8,0xb9,0xa9,0x73,0xd3,0xe7,0x2c,0xe7,0xe6,0xcf, |
2650 | | 0x2d,0x9c,0x5b,0x3a,0xb7,0x7c,0x6e,0xe5,0xdc,0xea,0x39,0x1c,0xd7,0x96,0x8b,0xe7, |
2651 | | 0x3a,0x70,0x9d,0xb8,0x2e,0x5c,0x37,0xae,0x07,0xd7,0x8b,0x4b,0xe4,0xfa,0x72,0x49, |
2652 | | 0x5c,0x0a,0x97,0xc6,0xa5,0x73,0x43,0xb8,0x61,0xdc,0x08,0x2e,0x83,0xcb,0xe2,0xc6, |
2653 | | 0x73,0xd9,0x5c,0x0e,0x37,0x95,0x9b,0xce,0xcd,0xe4,0xf2,0xb8,0x02,0xae,0x88,0x2b, |
2654 | | 0xe1,0x4a,0xb9,0x72,0xae,0x92,0xab,0xe6,0xea,0xb8,0x46,0xae,0x89,0x5b,0xcb,0x6d, |
2655 | | 0xe0,0x36,0x71,0x5b,0xb8,0x6d,0xdc,0x0e,0x6e,0x17,0xb7,0x9b,0x6b,0xe6,0xf6,0x73, |
2656 | | 0x07,0xb9,0x43,0xdc,0x61,0xee,0x08,0x77,0x94,0x3b,0xc6,0x1d,0xe7,0x4e,0x72,0xa7, |
2657 | | 0xb8,0xd3,0x5c,0x0b,0x77,0x9e,0xbb,0xc0,0x5d,0xe2,0x2e,0x73,0x57,0xb8,0xab,0x5c, |
2658 | | 0x1c,0xcf,0x96,0x87,0xe7,0x39,0xf0,0x9c,0x78,0x2e,0x3c,0x37,0x9e,0x07,0xcf,0x8b, |
2659 | | 0x47,0xe4,0xf9,0xf2,0x48,0x3c,0x0a,0x8f,0xc6,0xa3,0xf3,0x42,0x78,0x61,0xbc,0x08, |
2660 | | 0x1e,0x83,0xc7,0xe2,0xc5,0xf3,0xd8,0x3c,0x0e,0x2f,0x95,0x97,0xce,0xcb,0xe4,0xf1, |
2661 | | 0x78,0x02,0x9e,0x88,0x27,0xe1,0x49,0x79,0x72,0x9e,0x8e,0x57,0xcb,0x6b,0xe1,0x75, |
2662 | | 0xf1,0xfa,0x79,0xc3,0xbc,0x51,0xde,0xe3,0x5f,0x18,0xe7,0x4d,0xf2,0xa6,0x78,0xd3, |
2663 | | 0x3c,0x0b,0x6f,0x9e,0xb7,0xc0,0x5b,0xe2,0x2d,0xf3,0x56,0x78,0xab,0x3c,0x5c,0xb6, |
2664 | | 0x6d,0x36,0x3e,0xdb,0x21,0xdb,0x29,0xdb,0x25,0xdb,0x2d,0xdb,0x23,0xdb,0x2b,0x9b, |
2665 | | 0x98,0xed,0x9b,0x4d,0xca,0xa6,0x64,0xd3,0xb2,0xe9,0xd9,0x21,0xd9,0x61,0xd9,0x11, |
2666 | | 0xd9,0x8c,0x6c,0x56,0x76,0x7c,0x36,0x3b,0x9b,0x93,0x9d,0x9a,0x9d,0x9e,0x9d,0x99, |
2667 | | 0xcd,0xcb,0x16,0x64,0x8b,0xb2,0x25,0xd9,0xd2,0x6c,0x79,0xb6,0x32,0x5b,0x9d,0xad, |
2668 | | 0xcb,0x36,0x66,0x9b,0xb2,0x6b,0xb3,0x1b,0xb2,0x9b,0xb2,0x5b,0xb2,0xdb,0xb2,0x3b, |
2669 | | 0xb2,0xbb,0xb2,0xbb,0xb3,0xcd,0xd9,0xfd,0xd9,0x83,0xd9,0x43,0xd9,0xc3,0xd9,0x23, |
2670 | | 0xd9,0xa3,0xd9,0x63,0xd9,0xe3,0xd9,0x93,0xd9,0x53,0xd9,0xd3,0xd9,0x96,0xec,0xf9, |
2671 | | 0xec,0x85,0xec,0xa5,0xec,0xe5,0xec,0x95,0xec,0xd5,0x6c,0x5c,0x8e,0x6d,0x0e,0x3e, |
2672 | | 0xc7,0x21,0xc7,0x29,0xc7,0x25,0xc7,0x2d,0xc7,0x23,0xc7,0x2b,0x87,0x98,0xe3,0x9b, |
2673 | | 0x43,0xca,0xa1,0xe4,0xd0,0x72,0xe8,0x39,0x21,0x39,0x61,0x39,0x11,0x39,0x8c,0x1c, |
2674 | | 0x56,0x4e,0x7c,0x0e,0x3b,0x87,0x93,0x93,0x9a,0x93,0x9e,0x93,0x99,0xc3,0xcb,0x11, |
2675 | | 0xe4,0x88,0x72,0x24,0x39,0xd2,0x1c,0x79,0x8e,0x32,0x47,0x9d,0xa3,0xcb,0x31,0xe6, |
2676 | | 0x98,0x72,0x6a,0x73,0x1a,0x72,0x9a,0x72,0x5a,0x72,0xda,0x72,0x3a,0x72,0xba,0x72, |
2677 | | 0xba,0x73,0xcc,0x39,0xfd,0x39,0x83,0x39,0x43,0x39,0xc3,0x39,0x23,0x39,0xa3,0x39, |
2678 | | 0x63,0x39,0xe3,0x39,0x93,0x39,0x53,0x39,0xd3,0x39,0x96,0x9c,0xf9,0x9c,0x85,0x9c, |
2679 | | 0xa5,0x9c,0xe5,0x9c,0x95,0x9c,0xd5,0x1c,0x1c,0xdf,0x96,0x8f,0xe7,0x3b,0xf0,0x9d, |
2680 | | 0xf8,0x2e,0x7c,0x37,0xbe,0x07,0xdf,0x8b,0x4f,0xe4,0xfb,0xf2,0x49,0x7c,0x0a,0x9f, |
2681 | | 0xc6,0xa7,0xf3,0x43,0xf8,0x61,0xfc,0x08,0x3e,0x03,0xbe,0x28,0xc7,0xf3,0xd9,0x7c, |
2682 | | 0x0e,0x3f,0x95,0x9f,0xce,0xcf,0xe4,0xf3,0xf8,0x02,0xbe,0x88,0x2f,0xe1,0x4b,0xf9, |
2683 | | 0x72,0xbe,0x92,0xaf,0xe6,0xeb,0xf8,0x46,0xbe,0x89,0x5f,0xcb,0x6f,0xe0,0x37,0xf1, |
2684 | | 0x5b,0xf8,0x6d,0xfc,0x0e,0x7e,0x17,0xbf,0x9b,0x6f,0xe6,0xf7,0xf3,0x07,0xf9,0x43, |
2685 | | 0xfc,0x61,0xfe,0x08,0xff,0xa1,0x95,0x51,0xfe,0x18,0x7f,0x9c,0x3f,0xc9,0x9f,0xe2, |
2686 | | 0x4f,0xf3,0x67,0x20,0x16,0xfe,0x3c,0x7f,0x81,0xbf,0xc4,0x5f,0xe6,0xaf,0xf0,0x5f, |
2687 | | 0x41,0x56,0xf9,0x38,0x81,0xad,0x00,0x2f,0x70,0x10,0x38,0x09,0x9c,0x21,0x2e,0x02, |
2688 | | 0x37,0x81,0x87,0xc0,0xd3,0x8a,0x97,0x80,0x28,0xf0,0x15,0x90,0x04,0x34,0x01,0x5d, |
2689 | | 0x10,0x22,0x08,0x15,0x84,0x09,0x22,0x04,0x0c,0x01,0x4b,0x10,0x2f,0x60,0x0b,0x38, |
2690 | | 0x82,0x94,0x75,0xfe,0x04,0x52,0x05,0xe9,0x82,0x4c,0x01,0x4f,0x20,0x10,0x08,0x05, |
2691 | | 0x22,0x81,0x44,0x20,0x15,0xc8,0x05,0x4a,0x81,0x5a,0xa0,0x13,0x18,0x05,0x26,0x41, |
2692 | | 0xad,0xa0,0x41,0xd0,0x24,0x68,0x11,0xb4,0x09,0x3a,0x04,0x5d,0x82,0x6e,0x81,0x59, |
2693 | | 0xd0,0x2f,0x18,0x14,0x0c,0x09,0x86,0x05,0x23,0x82,0x51,0xc1,0x98,0x60,0x5c,0x30, |
2694 | | 0x29,0x98,0x12,0x4c,0x0b,0x2c,0x82,0x79,0xc1,0x82,0x60,0x49,0xb0,0x2c,0x58,0x11, |
2695 | | 0xac,0x0a,0x70,0xe7,0x6d,0xcf,0xe3,0xcf,0x3b,0x9c,0x77,0x3a,0xef,0x72,0xde,0xf5, |
2696 | | 0xbc,0xdb,0x79,0x8f,0xf3,0x5e,0xe7,0x89,0xe7,0x7d,0xcf,0x93,0xce,0x53,0xce,0xd3, |
2697 | | 0xce,0xd3,0xcf,0x07,0xaf,0xf3,0x4f,0x4e,0x38,0x84,0xf9,0x3f,0x92,0xb4,0x8e,0x95, |
2698 | | 0x94,0xf3,0x19,0xeb,0xac,0xf3,0x17,0xc1,0x3f,0x2f,0x5e,0x67,0x9d,0x7f,0x61,0x64, |
2699 | | 0xe7,0x55,0x10,0xc3,0x3a,0xff,0xa6,0xd4,0x9c,0x6f,0xfc,0x37,0xa6,0x75,0x9d,0x75, |
2700 | | 0x7e,0x35,0x3a,0xcf,0xf7,0x9e,0xbf,0x77,0xfe,0xe1,0xf9,0x89,0xf3,0x33,0xe7,0x17, |
2701 | | 0xff,0xa9,0x78,0x79,0x1e,0xe4,0xda,0xe7,0xba,0xe6,0x7a,0xe7,0x92,0xd7,0x59,0xe7, |
2702 | | 0xff,0x22,0x14,0x08,0x2d,0x97,0x9e,0x1b,0x92,0x1b,0x96,0x1b,0x91,0xcb,0xc8,0x65, |
2703 | | 0xe5,0xc6,0xe7,0xb2,0x73,0x39,0xb9,0xa9,0xb9,0xe9,0xb9,0x99,0xb9,0xbc,0x5c,0x41, |
2704 | | 0xae,0x28,0x57,0x92,0x2b,0xcd,0x95,0xe7,0x2a,0x73,0xd5,0xb9,0xba,0x5c,0x63,0xae, |
2705 | | 0x29,0xb7,0x36,0xb7,0x21,0xb7,0x29,0xb7,0x25,0xb7,0x2d,0xb7,0x23,0xb7,0x2b,0xb7, |
2706 | | 0x3b,0xd7,0x9c,0xdb,0x9f,0x3b,0x98,0x3b,0x94,0x3b,0x9c,0x3b,0x92,0x3b,0x9a,0x3b, |
2707 | | 0x96,0x3b,0x9e,0x3b,0x99,0x3b,0x95,0x3b,0x9d,0x6b,0xc9,0x9d,0xcf,0x5d,0xc8,0x5d, |
2708 | | 0xca,0x5d,0xce,0x5d,0xc9,0x5d,0xcd,0xc5,0x09,0x6d,0x85,0x78,0xa1,0x83,0xd0,0x49, |
2709 | | 0xe8,0x22,0x74,0x13,0x7a,0x08,0xbd,0x84,0x44,0xa1,0xaf,0x90,0x24,0xa4,0x08,0x69, |
2710 | | 0x42,0xba,0x30,0x44,0x18,0x26,0x8c,0x10,0x32,0x84,0x2c,0x61,0xbc,0x90,0x2d,0xe4, |
2711 | | 0x08,0x53,0x85,0xe9,0xc2,0x4c,0x21,0x4f,0x28,0x10,0x8a,0x84,0x12,0xa1,0x54,0x28, |
2712 | | 0x17,0x2a,0x85,0x2a,0xa1,0x5a,0xa8,0x13,0x1a,0x85,0x26,0x61,0xad,0xb0,0x41,0xd8, |
2713 | | 0x24,0x6c,0x11,0xb6,0x09,0x3b,0x84,0x5d,0xc2,0x6e,0xa1,0x59,0xd8,0x2f,0x1c,0x14, |
2714 | | 0x0e,0x09,0x87,0x85,0x23,0xc2,0x51,0xe1,0x98,0x70,0x5c,0x38,0x29,0x9c,0x12,0x4e, |
2715 | | 0x0b,0x2d,0xc2,0x79,0xe1,0x82,0x70,0x49,0xb8,0x2c,0x5c,0x11,0xae,0x0a,0x71,0x22, |
2716 | | 0x5b,0x11,0x5e,0xe4,0x20,0x72,0x12,0xb9,0x88,0xdc,0x44,0x1e,0x22,0x2f,0x11,0x51, |
2717 | | 0xe4,0x2b,0x22,0x89,0x28,0x22,0x9a,0x88,0x2e,0x0a,0x11,0x85,0x89,0x22,0x44,0x0c, |
2718 | | 0x11,0x4b,0x14,0x2f,0x62,0x8b,0x38,0xa2,0x54,0x51,0xba,0x28,0x53,0xc4,0x13,0x09, |
2719 | | 0x44,0x22,0x91,0x44,0x24,0x15,0xc9,0x45,0x4a,0x91,0x5a,0xa4,0x13,0x19,0x45,0x26, |
2720 | | 0x51,0xad,0xa8,0x41,0xd4,0x24,0x6a,0x16,0xb5,0x88,0xda,0x44,0xed,0x90,0x0e,0x51, |
2721 | | 0x27,0xa4,0x4b,0xd4,0x2d,0xea,0x85,0x98,0x45,0xfd,0xa2,0x41,0xd1,0x90,0xe8,0xbe, |
2722 | | 0x68,0x58,0x34,0x22,0x1a,0x15,0x8d,0x89,0xc6,0x45,0x93,0xa2,0x29,0xd1,0xb4,0xc8, |
2723 | | 0x22,0x9a,0x17,0x2d,0x88,0x96,0x44,0x2f,0x44,0xcb,0xa2,0x97,0xa2,0x15,0xd1,0xaa, |
2724 | | 0x08,0x97,0x67,0x9b,0x87,0xcf,0x73,0xc8,0x73,0xca,0x73,0xce,0x73,0xc9,0x73,0xcb, |
2725 | | 0xf3,0xc8,0xf3,0xca,0x23,0xe6,0xf9,0xe6,0x91,0xf2,0x28,0x79,0xb4,0x3c,0x7a,0x5e, |
2726 | | 0x48,0x5e,0x58,0x5e,0x44,0x1e,0x23,0x8f,0x95,0x17,0x9f,0xc7,0xce,0xe3,0xe4,0xa5, |
2727 | | 0xe6,0xa5,0xe7,0x65,0xe6,0xf1,0xf2,0x04,0x79,0xa2,0x3c,0x49,0x9e,0x34,0x4f,0x9e, |
2728 | | 0xa7,0xcc,0x53,0xe7,0xe9,0xf2,0x8c,0x79,0xa6,0xbc,0xda,0xbc,0x86,0xbc,0xa6,0xbc, |
2729 | | 0x96,0xbc,0xb6,0xbc,0x8e,0xbc,0xae,0xbc,0xee,0x3c,0x73,0x5e,0x7f,0xde,0x60,0xde, |
2730 | | 0x50,0xde,0x70,0xde,0x48,0xde,0x68,0xde,0x58,0xde,0x78,0xde,0x64,0xde,0x54,0xde, |
2731 | | 0x74,0x9e,0x25,0x6f,0x3e,0x6f,0x21,0x6f,0x29,0x6f,0x39,0x6f,0x25,0x6f,0x35,0x0f, |
2732 | | 0x97,0x8f,0xcb,0xb7,0xcd,0xc7,0xe7,0x3b,0xe4,0x3b,0xe5,0xbb,0xe4,0xbb,0xe6,0xbb, |
2733 | | 0xe5,0x7b,0xe4,0x7b,0xe5,0x13,0xf3,0x7d,0x20,0xbe,0xf9,0xa4,0x7c,0x4a,0x3e,0x2d, |
2734 | | 0x9f,0x9e,0x1f,0x92,0x1f,0x96,0x1f,0x91,0x1f,0x99,0xcf,0xc8,0x67,0xe5,0xc7,0xe7, |
2735 | | 0xb3,0xf3,0x39,0xf9,0xa9,0xf9,0xe9,0xf9,0x19,0xf9,0x99,0xf9,0xbc,0x7c,0x41,0xbe, |
2736 | | 0x28,0x5f,0x92,0x2f,0xcd,0x97,0xe7,0x2b,0xf3,0xd5,0xf9,0xba,0x7c,0x63,0xbe,0x29, |
2737 | | 0xbf,0x36,0xbf,0x21,0xbf,0x29,0xbf,0x25,0xbf,0x2d,0xbf,0x23,0xbf,0x2b,0xbf,0x3b, |
2738 | | 0xdf,0x9c,0xdf,0x9f,0x3f,0x98,0x3f,0x94,0x3f,0x9c,0x3f,0x92,0x3f,0x9a,0x3f,0x96, |
2739 | | 0xff,0x38,0x7f,0x3c,0x7f,0x32,0x7f,0x2a,0x7f,0x3a,0x7f,0x26,0xdf,0x92,0x3f,0x9f, |
2740 | | 0xbf,0x90,0xbf,0x94,0xbf,0x9c,0xff,0x32,0x7f,0x25,0xff,0x95,0x95,0xd5,0x7c,0x9c, |
2741 | | 0xd8,0x56,0x8c,0x17,0x3b,0x88,0x9d,0xc4,0x2e,0x62,0x57,0xb1,0x9b,0xd8,0x43,0xec, |
2742 | | 0x25,0x26,0x8a,0x7d,0xc5,0x24,0x31,0x45,0x4c,0x13,0xd3,0xc5,0x21,0xe2,0x30,0x71, |
2743 | | 0x84,0x98,0x21,0x66,0x89,0xe3,0xc5,0x6c,0x31,0x47,0x9c,0x2a,0x4e,0x17,0x67,0x8a, |
2744 | | 0x79,0x62,0x81,0x58,0x24,0x96,0x88,0xa5,0x62,0xb9,0x58,0x29,0x56,0x8b,0x75,0x62, |
2745 | | 0xa3,0xd8,0x24,0xae,0x15,0x37,0x88,0x9b,0xc4,0x2d,0xe2,0x36,0x71,0x87,0xb8,0x4b, |
2746 | | 0xdc,0x2d,0x36,0x8b,0xfb,0xc5,0x83,0xe2,0x21,0xf1,0xb0,0x78,0x44,0x3c,0x2a,0x1e, |
2747 | | 0x13,0x8f,0x8b,0x27,0xc5,0x53,0xe2,0x69,0xb1,0x45,0x3c,0x2f,0x5e,0x10,0x2f,0x89, |
2748 | | 0x97,0xc5,0x2b,0xe2,0x55,0x31,0x4e,0x62,0x2b,0xc1,0x4b,0x1c,0x24,0x4e,0x12,0x17, |
2749 | | 0x89,0x9b,0xc4,0x43,0xe2,0x25,0x21,0x4a,0x7c,0x25,0x24,0x09,0x45,0x42,0x93,0xd0, |
2750 | | 0x25,0x21,0x92,0x30,0x49,0x84,0x84,0x21,0x61,0x49,0xe2,0x25,0x6c,0x09,0x47,0x92, |
2751 | | 0x2a,0x49,0x97,0x64,0x4a,0x78,0x12,0x81,0x44,0x24,0x91,0x48,0xa4,0x12,0xb9,0x44, |
2752 | | 0x29,0x51,0x4b,0x74,0x12,0xa3,0xc4,0x24,0xa9,0x95,0x34,0x48,0x9a,0x24,0x2d,0x92, |
2753 | | 0x36,0x49,0x87,0xa4,0x4b,0xd2,0x2d,0x31,0x4b,0xfa,0x25,0x83,0x92,0x21,0xc9,0xb0, |
2754 | | 0x64,0x44,0x32,0x2a,0x19,0x93,0x8c,0x4b,0x26,0x25,0x53,0x92,0x69,0x89,0x45,0x32, |
2755 | | 0x2f,0x59,0x90,0x2c,0x49,0x96,0x25,0x2b,0x92,0x55,0x09,0xae,0xc0,0xb6,0x00,0x5f, |
2756 | | 0xe0,0x50,0xe0,0x54,0xe0,0x52,0xe0,0x56,0xe0,0x51,0xe0,0x55,0x40,0x2c,0xf0,0x2d, |
2757 | | 0x20,0x15,0x50,0x0a,0x68,0x05,0xf4,0x82,0x90,0x82,0xb0,0x82,0x88,0x02,0x46,0x01, |
2758 | | 0xab,0x20,0xbe,0x80,0x5d,0xc0,0x29,0x48,0x2d,0x48,0x2f,0xc8,0x2c,0xe0,0x15,0x08, |
2759 | | 0x0a,0x44,0x05,0x92,0x02,0x69,0x81,0xbc,0x40,0x59,0xa0,0x2e,0xd0,0x15,0x18,0x0b, |
2760 | | 0x4c,0x05,0xb5,0x05,0x0d,0x05,0x4d,0x05,0x2d,0x05,0x6d,0x05,0x1d,0x05,0x5d,0x05, |
2761 | | 0xdd,0x05,0xe6,0x82,0xfe,0x82,0xc1,0x82,0xa1,0x82,0xe1,0x82,0x91,0x82,0xd1,0x82, |
2762 | | 0x31,0xc8,0x78,0xc1,0x64,0xc1,0x54,0xc1,0x74,0x81,0xa5,0x60,0xbe,0x60,0xa1,0x60, |
2763 | | 0xa9,0x60,0xb9,0x60,0xa5,0x60,0xb5,0x00,0x57,0x68,0x5b,0x88,0x2f,0x74,0x28,0x74, |
2764 | | 0x2a,0x74,0x29,0x74,0x2b,0xf4,0x28,0xf4,0x2a,0x24,0x16,0xfa,0x16,0x92,0x0a,0x29, |
2765 | | 0x85,0xb4,0x42,0x7a,0x61,0x48,0x61,0x58,0x61,0x44,0x21,0xa3,0x90,0x55,0x18,0x5f, |
2766 | | 0xc8,0x2e,0xe4,0x14,0xa6,0x16,0xa6,0x17,0x66,0x16,0xf2,0x0a,0x05,0x85,0xa2,0x42, |
2767 | | 0x49,0xa1,0xb4,0x50,0x5e,0xa8,0x2c,0x54,0x17,0xea,0x0a,0x8d,0x85,0xa6,0xc2,0xda, |
2768 | | 0xc2,0x86,0xc2,0xa6,0xc2,0x96,0xc2,0xb6,0xc2,0x8e,0xc2,0xae,0xc2,0xee,0x42,0x73, |
2769 | | 0x61,0x7f,0xe1,0x60,0xe1,0x50,0xe1,0x70,0xe1,0x48,0xe1,0x68,0xe1,0x58,0xe1,0x78, |
2770 | | 0xe1,0x64,0xe1,0x54,0xe1,0x74,0xa1,0xa5,0x70,0xbe,0x70,0xa1,0x70,0xa9,0x70,0xb9, |
2771 | | 0x70,0xa5,0x70,0xb5,0x10,0x57,0x64,0x5b,0x84,0x2f,0x72,0x28,0x72,0x2a,0x72,0x29, |
2772 | | 0x72,0x2b,0xf2,0x28,0xf2,0x2a,0x22,0x16,0xf9,0x16,0x91,0x8a,0x28,0x45,0xb4,0x22, |
2773 | | 0x7a,0x51,0x48,0x51,0x58,0x51,0x44,0x11,0xa3,0x88,0x55,0x14,0x5f,0xc4,0x2e,0xe2, |
2774 | | 0x14,0xa5,0x16,0xa5,0x17,0x65,0x16,0xf1,0x8a,0x04,0x45,0xa2,0x22,0x49,0x91,0xb4, |
2775 | | 0x48,0x5e,0xa4,0x2c,0x52,0x17,0xe9,0x8a,0x8c,0x45,0xa6,0xa2,0xda,0xa2,0x86,0xa2, |
2776 | | 0xa6,0xa2,0x96,0xa2,0xb6,0xa2,0x8e,0xa2,0xae,0xa2,0xee,0x22,0x73,0x51,0x7f,0xd1, |
2777 | | 0x60,0xd1,0x50,0xd1,0x70,0xd1,0x48,0xd1,0x68,0xd1,0x58,0xd1,0x78,0xd1,0x64,0xd1, |
2778 | | 0x54,0xd1,0x74,0x91,0xa5,0x68,0xbe,0x68,0xa1,0x68,0xa9,0x68,0xb9,0x68,0xa5,0x68, |
2779 | | 0xb5,0x08,0x27,0xb5,0x95,0xe2,0xa5,0x0e,0x52,0x27,0xa9,0x8b,0xd4,0x4d,0xea,0x21, |
2780 | | 0xf5,0x92,0x12,0xa5,0xbe,0x52,0x92,0x94,0x22,0xa5,0x49,0xe9,0xd2,0x10,0x69,0x98, |
2781 | | 0x34,0x42,0xca,0x90,0xb2,0xa4,0xf1,0x52,0xb6,0x94,0x23,0x4d,0x95,0xa6,0x4b,0x33, |
2782 | | 0xa5,0x5c,0x08,0x4f,0x2a,0x90,0x8a,0xa4,0x12,0xa9,0x54,0x2a,0x97,0x2a,0xa5,0x6a, |
2783 | | 0xa9,0x4e,0x6a,0x94,0x9a,0xa4,0xb5,0xd2,0x06,0x69,0x93,0xb4,0x45,0xda,0x26,0xed, |
2784 | | 0x90,0x76,0x49,0xbb,0xa5,0x66,0x69,0xbf,0x74,0x50,0x3a,0x24,0x1d,0x96,0x8e,0x48, |
2785 | | 0x47,0xa5,0x63,0xd2,0x71,0xe9,0xa4,0x74,0x4a,0x3a,0x2d,0xb5,0x48,0xe7,0xa5,0x0b, |
2786 | | 0xd2,0x25,0xe9,0xb2,0x74,0x45,0xba,0x2a,0xc5,0x15,0xdb,0x16,0xe3,0x8b,0x1d,0x8a, |
2787 | | 0x9d,0x8a,0x5d,0x8a,0xdd,0x8a,0x3d,0x8a,0xbd,0x8a,0x89,0xc5,0xbe,0xc5,0xa4,0x62, |
2788 | | 0x4a,0x31,0xad,0x98,0x5e,0x1c,0x52,0x1c,0x56,0x1c,0x51,0xcc,0x28,0x66,0x15,0xc7, |
2789 | | 0x17,0xb3,0x8b,0x39,0xc5,0xa9,0xc5,0xe9,0xc5,0x99,0xc5,0xbc,0x62,0x41,0xb1,0xa8, |
2790 | | 0x58,0x52,0x2c,0x2d,0x96,0x17,0x2b,0x8b,0xd5,0xc5,0xba,0x62,0x63,0xb1,0xa9,0xb8, |
2791 | | 0xb6,0xb8,0xa1,0xb8,0xa9,0xb8,0xa5,0xb8,0xad,0xb8,0xa3,0xb8,0xab,0xb8,0xbb,0xd8, |
2792 | | 0x5c,0xdc,0x5f,0x3c,0x58,0x3c,0x54,0x3c,0x5c,0x3c,0x02,0x19,0x2d,0x1e,0x2b,0x1e, |
2793 | | 0x2f,0x9e,0x2c,0x9e,0x2a,0x9e,0x2e,0xb6,0x14,0xcf,0x17,0x2f,0x14,0x2f,0x15,0x2f, |
2794 | | 0x17,0xaf,0x14,0xaf,0x16,0xe3,0x4a,0x6c,0x4b,0xf0,0x25,0x0e,0x25,0x4e,0x25,0x2e, |
2795 | | 0x25,0x6e,0x25,0x1e,0x25,0x5e,0x25,0xc4,0x12,0xdf,0x12,0x52,0x09,0xa5,0x84,0x56, |
2796 | | 0x42,0x2f,0x09,0x29,0x09,0x2b,0x89,0x28,0x61,0x94,0xb0,0x4a,0xe2,0x4b,0xd8,0x25, |
2797 | | 0x9c,0x92,0xd4,0x92,0xf4,0x92,0xcc,0x12,0x5e,0x89,0xa0,0x44,0x54,0x22,0x29,0x91, |
2798 | | 0x96,0xc8,0x4b,0x94,0x25,0xea,0x12,0x5d,0x89,0xb1,0xc4,0x54,0x52,0x5b,0xd2,0x50, |
2799 | | 0xd2,0x54,0xd2,0x52,0xd2,0x56,0xd2,0x51,0xd2,0x55,0xd2,0x5d,0x62,0x2e,0xe9,0x2f, |
2800 | | 0x19,0x2c,0x19,0x2a,0x19,0x2e,0x19,0x29,0x19,0x2d,0x19,0x2b,0x19,0x2f,0x99,0x2c, |
2801 | | 0x99,0x2a,0x99,0x2e,0xb1,0x94,0xcc,0x97,0x2c,0x94,0x2c,0x95,0x2c,0x97,0xac,0x94, |
2802 | | 0xac,0x96,0xe0,0x64,0xb6,0x32,0xbc,0xcc,0x41,0xe6,0x24,0x73,0x91,0xb9,0xc9,0x3c, |
2803 | | 0x64,0x5e,0x32,0xa2,0xcc,0x57,0x46,0x92,0x51,0x64,0x34,0x19,0x5d,0x16,0x22,0x0b, |
2804 | | 0x93,0x45,0xc8,0x18,0x32,0x96,0x2c,0x5e,0xc6,0x96,0x71,0x64,0xa9,0xb2,0x74,0x59, |
2805 | | 0xa6,0x8c,0x27,0x13,0xc8,0x44,0x32,0x89,0x4c,0x2a,0x93,0xcb,0x94,0x32,0xb5,0x4c, |
2806 | | 0x27,0x33,0xca,0x4c,0xb2,0x5a,0x59,0x83,0xac,0x49,0xd6,0x22,0x6b,0x93,0x75,0xc8, |
2807 | | 0xba,0x64,0xdd,0x32,0xb3,0xac,0x5f,0x36,0x28,0x1b,0x92,0x0d,0xcb,0x46,0x64,0xa3, |
2808 | | 0xb2,0x31,0xd9,0xb8,0x6c,0x52,0x36,0x25,0x9b,0x96,0x59,0x64,0xf3,0xb2,0x05,0xd9, |
2809 | | 0x92,0x6c,0x59,0xb6,0x22,0x5b,0x95,0xe1,0xe4,0xb6,0x72,0xbc,0xdc,0x41,0xee,0x24, |
2810 | | 0x77,0x91,0xbb,0xc9,0x3d,0xe4,0x5e,0x72,0xa2,0xdc,0x57,0x4e,0x92,0x53,0xe4,0x34, |
2811 | | 0x39,0x5d,0x1e,0x22,0x0f,0x93,0x47,0xc8,0x19,0x72,0x96,0x3c,0x5e,0xce,0x96,0x73, |
2812 | | 0xe4,0xa9,0xf2,0x74,0x79,0xa6,0x9c,0x27,0x17,0xc8,0x45,0x72,0x89,0x5c,0x2a,0x97, |
2813 | | 0xcb,0x95,0x72,0xb5,0x5c,0x27,0x37,0xca,0x4d,0xf2,0x5a,0x79,0x83,0xbc,0x49,0xde, |
2814 | | 0x22,0x6f,0x93,0x77,0xc8,0xbb,0xe4,0xdd,0x72,0xb3,0xbc,0x5f,0x3e,0x28,0x1f,0x92, |
2815 | | 0x0f,0xcb,0x47,0xe4,0xa3,0xf2,0x31,0xf9,0xb8,0x7c,0x52,0x3e,0x25,0x9f,0x96,0x5b, |
2816 | | 0xe4,0xf3,0xf2,0x05,0xf9,0x92,0x7c,0x59,0xfe,0x12,0xb2,0x22,0x5f,0x95,0xe3,0x4a, |
2817 | | 0x6d,0x4b,0xf1,0xa5,0x0e,0xa5,0x4e,0xa5,0x2e,0xa5,0x6e,0xa5,0x1e,0xa5,0x5e,0xa5, |
2818 | | 0xc4,0x52,0xdf,0x52,0x52,0x29,0xa5,0x94,0x56,0x4a,0x2f,0x0d,0x29,0x0d,0x2b,0x8d, |
2819 | | 0x28,0x65,0x94,0xb2,0x4a,0xe3,0x4b,0xd9,0xa5,0x9c,0xd2,0xd4,0xd2,0xf4,0xd2,0xcc, |
2820 | | 0x52,0x5e,0xa9,0xa0,0x54,0x54,0x2a,0x29,0x95,0x96,0xca,0x4b,0x95,0xa5,0xea,0x52, |
2821 | | 0x5d,0xa9,0xb1,0xd4,0x54,0x5a,0x5b,0xda,0x50,0xda,0x54,0xda,0x52,0xda,0x56,0xda, |
2822 | | 0x51,0xda,0x55,0xda,0x5d,0x6a,0x2e,0xed,0x2f,0x1d,0x2c,0xbd,0xf7,0x37,0x67,0xa8, |
2823 | | 0x74,0xb8,0x74,0xa4,0x74,0xb4,0x74,0xac,0x74,0xbc,0x74,0xb2,0x74,0xaa,0x74,0xba, |
2824 | | 0xd4,0x52,0x3a,0x5f,0xba,0x50,0xba,0x54,0xba,0x5c,0xba,0x52,0xba,0x5a,0x8a,0x2b, |
2825 | | 0xb3,0x2d,0xc3,0x97,0x39,0x94,0x39,0x95,0xb9,0x94,0xb9,0x95,0x79,0x94,0x79,0x95, |
2826 | | 0x11,0xcb,0x7c,0xcb,0x48,0x65,0x94,0x32,0x5a,0x19,0xbd,0x2c,0xa4,0x2c,0xac,0x2c, |
2827 | | 0xa2,0x8c,0x51,0xc6,0x2a,0x8b,0x2f,0x63,0x97,0x71,0xca,0x52,0xcb,0xd2,0xcb,0x32, |
2828 | | 0xcb,0x78,0x65,0x82,0x32,0x51,0x99,0xa4,0x4c,0x5a,0x26,0x2f,0x53,0x96,0xa9,0xcb, |
2829 | | 0x74,0x65,0xc6,0x32,0x53,0x59,0x6d,0x59,0x43,0x59,0x53,0x59,0x4b,0x59,0x5b,0x59, |
2830 | | 0x47,0x59,0x57,0x59,0x77,0x99,0xb9,0xac,0x6f,0x9d,0x75,0xd6,0xf9,0x23,0xf4,0x43, |
2831 | | 0x06,0xcb,0x86,0xca,0x86,0xcb,0x1e,0x94,0x8d,0x94,0x8d,0x96,0x8d,0x95,0x8d,0x97, |
2832 | | 0x4d,0x96,0x4d,0x95,0x4d,0x97,0x59,0xca,0xe6,0xcb,0x16,0xca,0x96,0xca,0x96,0xcb, |
2833 | | 0x56,0xca,0x56,0xcb,0x70,0x0a,0x5b,0x05,0x5e,0xe1,0xa0,0x70,0x52,0xb8,0x28,0xdc, |
2834 | | 0x14,0x1e,0x0a,0x2f,0x05,0x51,0xe1,0xab,0x20,0x29,0x28,0x0a,0xaa,0x82,0xa6,0xa0, |
2835 | | 0x2b,0x82,0x15,0x21,0x8a,0x50,0x48,0x98,0x22,0x5c,0x11,0xa1,0x60,0x28,0x58,0x8a, |
2836 | | 0x78,0x05,0x5b,0xc1,0x51,0xa4,0x2a,0xd2,0x15,0x99,0x0a,0x9e,0x82,0xaf,0x10,0x28, |
2837 | | 0x44,0x0a,0x89,0x42,0xaa,0x90,0x29,0xe4,0x0a,0x85,0x42,0xa9,0x50,0xbd,0x81,0x5a, |
2838 | | 0xa1,0xc5,0xd0,0x29,0x0c,0x0a,0xa3,0xa2,0x5a,0x61,0x52,0xd4,0x28,0x6a,0x15,0x0d, |
2839 | | 0x8a,0x26,0x45,0xb3,0xa2,0x45,0xd1,0xa6,0x68,0x57,0x74,0x28,0x3a,0x21,0x5d,0x8a, |
2840 | | 0x1b,0x8a,0x6e,0x45,0xaf,0xc2,0xac,0xe8,0x53,0xf4,0x2b,0x06,0x14,0x83,0x8a,0x7b, |
2841 | | 0x8a,0x21,0xc5,0xb0,0xe2,0x81,0x62,0x44,0xf1,0x10,0x32,0xaa,0x18,0x53,0x8c,0x2b, |
2842 | | 0x26,0x15,0x4f,0x14,0x53,0x8a,0x69,0x85,0x45,0x31,0xaf,0x58,0x50,0x2c,0x29,0x96, |
2843 | | 0x15,0x2f,0x15,0x2b,0x8a,0x55,0x05,0x4e,0x69,0xab,0xb4,0x53,0xe2,0x95,0x0e,0x4a, |
2844 | | 0x27,0xa5,0x8b,0xd2,0x55,0xe9,0xa6,0x74,0x57,0x7a,0x28,0xbd,0x94,0x44,0xa5,0xaf, |
2845 | | 0x92,0xa4,0xa4,0x28,0x69,0x4a,0xba,0x32,0x44,0x19,0xa6,0x0c,0x57,0x46,0x28,0x19, |
2846 | | 0x4a,0x96,0x32,0x5e,0xc9,0x56,0x72,0x94,0xa9,0xca,0x74,0x65,0xa6,0x92,0xa7,0x14, |
2847 | | 0x28,0x45,0x4a,0x89,0x52,0xaa,0x94,0x2b,0x95,0x4a,0xb5,0x52,0xfb,0x0b,0x3a,0xa5, |
2848 | | 0x51,0x69,0x52,0xd6,0x28,0x6b,0x95,0x0d,0xca,0x26,0x65,0x8b,0xb2,0x4d,0xd9,0xae, |
2849 | | 0xec,0x50,0x76,0x29,0xbb,0x95,0x66,0x65,0xbf,0x72,0x50,0x39,0xa4,0x1c,0x56,0x8e, |
2850 | | 0x28,0x47,0x95,0x63,0xca,0x71,0xe5,0xa4,0x72,0x4a,0x39,0xad,0xb4,0x28,0xe7,0x95, |
2851 | | 0xcf,0xd7,0x59,0xe7,0x1f,0x82,0x05,0xc8,0xb2,0x72,0x55,0x69,0x5b,0xee,0x50,0xee, |
2852 | | 0x52,0xee,0x51,0x4e,0x2c,0x27,0x95,0xd3,0xca,0x43,0xca,0xc3,0x7f,0x21,0xa2,0x3c, |
2853 | | 0xbe,0x3c,0xb5,0x9c,0x57,0x2e,0x29,0x57,0x96,0x1b,0xcb,0x1b,0xca,0xdb,0xca,0xbb, |
2854 | | 0xcb,0x07,0xcb,0x47,0xca,0xc7,0xcb,0xa7,0xcb,0x17,0xca,0x57,0xca,0x6d,0x2b,0x9c, |
2855 | | 0x2a,0x3c,0x2a,0x7c,0x2b,0x68,0x15,0x61,0x15,0xac,0x0a,0x4e,0x45,0x66,0x85,0xa8, |
2856 | | 0x42,0x5e,0xa1,0xab,0x30,0x56,0x98,0x2a,0x1a,0x2a,0x9a,0x2b,0x5a,0x2a,0xda,0x2a, |
2857 | | 0x3a,0x2a,0xba,0x2a,0xba,0x2b,0xcc,0x15,0xfd,0x15,0x83,0x15,0x43,0x15,0xc3,0x15, |
2858 | | 0x23,0x15,0xa3,0x15,0x63,0x15,0xe3,0x15,0x93,0x15,0x53,0x15,0xd3,0x15,0x96,0x8a, |
2859 | | 0xf9,0x8a,0x85,0x8a,0xa5,0x8a,0xe5,0x8a,0x95,0x8a,0xd5,0x0a,0x9c,0xca,0x56,0x85, |
2860 | | 0x57,0x39,0xa9,0xdc,0x54,0x5e,0x2a,0x5f,0x15,0x4d,0x15,0xfc,0x17,0x10,0xa2,0x8a, |
2861 | | 0x50,0xb1,0x54,0x49,0xbf,0x0a,0x6c,0x55,0xca,0xbf,0x34,0xa9,0x90,0x4c,0x95,0x40, |
2862 | | 0x25,0xfc,0x83,0x88,0x54,0x12,0x95,0x54,0x25,0x57,0xa9,0x55,0x3a,0x95,0x51,0x65, |
2863 | | 0x52,0xd5,0xaa,0x1a,0x54,0x4d,0xaa,0x16,0x55,0x9b,0xaa,0x43,0xd5,0xa5,0xea,0x56, |
2864 | | 0x99,0x55,0xfd,0xaa,0x41,0xd5,0x90,0x6a,0x58,0x35,0xa2,0x1a,0x55,0x8d,0xa9,0xc6, |
2865 | | 0x55,0x93,0xaa,0x29,0xd5,0xb4,0xca,0xa2,0x9a,0x57,0x2d,0xa8,0x96,0x54,0xcb,0xaa, |
2866 | | 0x15,0xd5,0xaa,0x0a,0xa7,0xb6,0x55,0xe3,0xd5,0x0e,0x6a,0x27,0xb5,0x8b,0xda,0x4d, |
2867 | | 0xed,0xa1,0xf6,0x52,0x7b,0x63,0x10,0xd5,0x14,0x75,0x88,0x9a,0xa1,0x66,0xab,0xd3, |
2868 | | 0xd5,0x02,0xb5,0x54,0xad,0x56,0x57,0xff,0x16,0x26,0x75,0xad,0xba,0x7e,0x9d,0x75, |
2869 | | 0xd6,0xf9,0x0b,0x69,0x50,0x37,0xa9,0x5b,0xd4,0x6d,0xea,0x0e,0x75,0x97,0xba,0x5b, |
2870 | | 0x6d,0x56,0xf7,0xab,0x07,0xd5,0xf7,0x7e,0x87,0xfb,0xea,0x07,0xea,0x87,0xea,0x47, |
2871 | | 0xea,0xc7,0xea,0x09,0xf5,0x13,0xf5,0x53,0xf5,0x8c,0x7a,0x4e,0xfd,0x5c,0xbd,0xa8, |
2872 | | 0x7e,0xa1,0x7e,0xa9,0x7e,0xa5,0x06,0x1a,0x1b,0x8d,0x9d,0xc6,0x5e,0x43,0xd0,0x38, |
2873 | | 0x6b,0x5c,0x35,0xee,0x1a,0x4f,0x8d,0xb7,0xc6,0x47,0xe3,0xa7,0x21,0x6b,0xa8,0x9a, |
2874 | | 0x40,0x4d,0xb0,0x26,0x54,0x13,0xae,0x89,0xd4,0x30,0x35,0x71,0x9a,0x24,0x4d,0xb2, |
2875 | | 0x26,0x45,0x93,0xa6,0xc9,0xd0,0x70,0x35,0x7c,0x8d,0x50,0x23,0xd6,0x14,0x69,0x64, |
2876 | | 0x1a,0x85,0x46,0xa5,0xd1,0x6a,0x0c,0x9a,0x6a,0x4d,0x8d,0xa6,0x5e,0xd3,0xa8,0x69, |
2877 | | 0xd6,0xb4,0x6a,0xda,0x35,0x9d,0x9a,0x1b,0x9a,0x5e,0x4d,0x9f,0x66,0x40,0x73,0x4f, |
2878 | | 0x73,0x5f,0xf3,0x40,0xf3,0x50,0xf3,0x48,0xf3,0x58,0x33,0xa1,0x79,0xa2,0x79,0xaa, |
2879 | | 0x99,0xd1,0xcc,0x69,0x9e,0x6b,0x16,0x35,0x2f,0x34,0x2f,0x35,0xaf,0x34,0xa0,0xd2, |
2880 | | 0xa6,0xd2,0xae,0xd2,0xbe,0x92,0x50,0xe9,0x5c,0xe9,0x5a,0xe9,0x5e,0xe9,0x59,0xe9, |
2881 | | 0x5d,0xe9,0x53,0xe9,0x57,0x49,0xae,0xa4,0x56,0x06,0x56,0x06,0x57,0x86,0x56,0x86, |
2882 | | 0x57,0x46,0x56,0x32,0x2b,0xe3,0x2a,0x93,0x2a,0x93,0x2b,0x53,0x2a,0xd3,0x2a,0x33, |
2883 | | 0x2a,0xb9,0x95,0xfc,0x4a,0x61,0xa5,0xb8,0xb2,0xa8,0x52,0x56,0xa9,0xa8,0x54,0x55, |
2884 | | 0x6a,0x2b,0x0d,0x95,0xd5,0x95,0x35,0x95,0xf5,0x95,0x8d,0x95,0xcd,0x95,0xad,0x95, |
2885 | | 0xed,0x95,0x9d,0x95,0x37,0x2a,0x7b,0x2b,0xfb,0x2a,0x07,0x2a,0xef,0x55,0xde,0xaf, |
2886 | | 0x7c,0x50,0xf9,0xb0,0xf2,0x51,0xe5,0xe3,0xca,0x89,0xca,0x27,0x95,0x4f,0x2b,0x67, |
2887 | | 0x2a,0xe7,0x2a,0x9f,0x57,0x2e,0x56,0xbe,0xa8,0x7c,0x59,0xf9,0xaa,0x12,0x68,0x6d, |
2888 | | 0xb4,0x76,0x5a,0x7b,0x2d,0x41,0xeb,0xac,0x75,0xd5,0xba,0x6b,0x3d,0xb5,0xde,0x5a, |
2889 | | 0x1f,0xad,0x9f,0x96,0xac,0xa5,0x6a,0x03,0xb5,0xc1,0xda,0x50,0x6d,0xb8,0x36,0x52, |
2890 | | 0xcb,0xd4,0xc6,0x69,0x93,0xb4,0xc9,0xda,0x14,0x6d,0x9a,0x36,0x43,0xcb,0xd5,0xf2, |
2891 | | 0xb5,0x42,0xad,0x58,0x5b,0xa4,0x95,0xc1,0xd7,0x5b,0x95,0x56,0xab,0x35,0x68,0xab, |
2892 | | 0xb5,0x35,0xda,0x7a,0x6d,0xa3,0xb6,0x59,0xdb,0xaa,0x6d,0xd7,0x76,0x6a,0x6f,0x68, |
2893 | | 0x7b,0xb5,0x7d,0xda,0x01,0xed,0x3d,0xed,0x7d,0xed,0x03,0xed,0x43,0xed,0x23,0xed, |
2894 | | 0x63,0xed,0x84,0xf6,0x89,0xf6,0xa9,0x76,0x46,0x3b,0xa7,0x7d,0xae,0x5d,0xd4,0xbe, |
2895 | | 0xd0,0xbe,0xd4,0xbe,0xd2,0x02,0x9d,0x8d,0xce,0x4e,0x67,0xaf,0x23,0xe8,0x9c,0x75, |
2896 | | 0xae,0x3a,0x77,0x9d,0xa7,0xce,0x5b,0xe7,0xa3,0xf3,0xd3,0x91,0x75,0x54,0x5d,0xa0, |
2897 | | 0x2e,0x58,0x17,0xaa,0x0b,0xd7,0x45,0xea,0x98,0xba,0x38,0x5d,0x92,0x2e,0x59,0x97, |
2898 | | 0xa2,0x4b,0xd3,0x65,0xe8,0xb8,0x3a,0xbe,0x4e,0xa8,0x13,0xeb,0x8a,0x74,0x32,0x9d, |
2899 | | 0x42,0xa7,0xd2,0x69,0x75,0x06,0x5d,0xb5,0xae,0x46,0x57,0xaf,0x6b,0xd4,0x35,0xeb, |
2900 | | 0x5a,0x75,0xed,0xba,0x4e,0xdd,0x0d,0x5d,0xaf,0xae,0x4f,0x37,0xa0,0xbb,0x07,0xb9, |
2901 | | 0xaf,0x7b,0xa0,0x7b,0xa8,0x7b,0xa4,0x7b,0xac,0x9b,0xd0,0x3d,0xd1,0x3d,0xd5,0xcd, |
2902 | | 0xe8,0xe6,0x74,0xcf,0x75,0x8b,0xba,0x17,0xba,0x97,0xba,0x57,0x3a,0xa0,0xb7,0xd1, |
2903 | | 0xdb,0xe9,0xed,0xf5,0x04,0xbd,0xb3,0xde,0x55,0xef,0xae,0xf7,0xd4,0x7b,0xeb,0x7d, |
2904 | | 0xf4,0x7e,0x7a,0xb2,0x9e,0xaa,0x0f,0xd4,0x07,0xeb,0x43,0xf5,0xe1,0xfa,0x48,0x3d, |
2905 | | 0x53,0x1f,0xa7,0x4f,0xd2,0x27,0xeb,0x53,0xf4,0x69,0xfa,0x0c,0x3d,0x57,0xcf,0xd7, |
2906 | | 0x0b,0xf5,0x62,0x7d,0x91,0x5e,0xa6,0x57,0xe8,0x55,0x7a,0xad,0xde,0xa0,0xaf,0xd6, |
2907 | | 0xd7,0xe8,0xeb,0xf5,0x8d,0xfa,0x66,0x7d,0xab,0xbe,0x5d,0xdf,0xa9,0xbf,0xa1,0xef, |
2908 | | 0xd5,0xf7,0xe9,0x07,0xf4,0xf7,0xf4,0xf7,0xf5,0x0f,0xf4,0x0f,0xf5,0x8f,0xf4,0x8f, |
2909 | | 0xf5,0x13,0xfa,0x27,0xfa,0xa7,0xfa,0x19,0xfd,0x9c,0xfe,0xb9,0x7e,0x51,0xff,0x42, |
2910 | | 0xff,0x52,0xff,0x4a,0x0f,0xaa,0x6c,0xaa,0xec,0xaa,0xec,0xab,0x08,0x55,0xce,0x55, |
2911 | | 0xae,0x55,0xee,0x55,0x9e,0x55,0xde,0x55,0x3e,0x55,0x7e,0x55,0xe4,0x2a,0x6a,0x55, |
2912 | | 0x60,0x55,0x70,0x55,0x68,0x55,0x78,0x55,0x64,0x15,0xb3,0x2a,0xae,0x2a,0xa9,0x2a, |
2913 | | 0xb9,0x2a,0xa5,0x2a,0xad,0x2a,0xa3,0x8a,0x5b,0xc5,0xaf,0x12,0x56,0x89,0xab,0x8a, |
2914 | | 0xaa,0x64,0x55,0x8a,0x2a,0x55,0x95,0xb6,0xca,0x50,0x55,0x5d,0x55,0x53,0x55,0x5f, |
2915 | | 0xd5,0x58,0xd5,0x5c,0xd5,0x5a,0xd5,0x5e,0xd5,0x59,0x75,0xa3,0xaa,0xb7,0xaa,0xaf, |
2916 | | 0x6a,0xa0,0xea,0x5e,0xd5,0xfd,0xaa,0x07,0x55,0x0f,0xab,0x1e,0x55,0x3d,0xae,0x9a, |
2917 | | 0xa8,0x7a,0x52,0xf5,0xb4,0x6a,0xa6,0x6a,0xae,0xea,0x79,0xd5,0x62,0xd5,0x8b,0xaa, |
2918 | | 0x97,0x55,0xaf,0xaa,0x80,0xc1,0xc6,0x60,0x67,0xb0,0x37,0x10,0x0c,0xce,0x06,0x57, |
2919 | | 0x83,0xbb,0xc1,0xd3,0xe0,0x6d,0xf0,0x31,0xf8,0x19,0xc8,0x06,0xaa,0x21,0xd0,0x10, |
2920 | | 0x6c,0x08,0x35,0x84,0x1b,0x22,0x0d,0x4c,0x43,0x9c,0x21,0xc9,0x90,0x6c,0x48,0x31, |
2921 | | 0xa4,0x19,0x32,0x0c,0x5c,0x03,0xdf,0x20,0x34,0x88,0x0d,0x45,0x06,0x99,0x41,0x61, |
2922 | | 0x50,0x19,0xb4,0x06,0x83,0xa1,0xda,0x50,0x63,0xa8,0x37,0x34,0x1a,0x9a,0x0d,0xad, |
2923 | | 0x86,0x76,0x43,0xa7,0xe1,0x86,0xa1,0xd7,0xd0,0x67,0x18,0x30,0xdc,0x33,0xdc,0x37, |
2924 | | 0x3c,0x30,0x3c,0x34,0x3c,0x32,0x3c,0x36,0x4c,0x18,0x9e,0x18,0x9e,0x1a,0x66,0x0c, |
2925 | | 0x73,0x86,0xe7,0x86,0x45,0xc3,0x0b,0xc3,0x4b,0xc3,0x2b,0x03,0x30,0xda,0x18,0xed, |
2926 | | 0x8c,0xf6,0x46,0x82,0xd1,0xd9,0xe8,0x6a,0x74,0x37,0x7a,0x1a,0xbd,0x8d,0x3e,0x46, |
2927 | | 0x3f,0x23,0xd9,0x48,0x35,0x06,0x1a,0x83,0x8d,0xa1,0xc6,0x70,0x63,0xa4,0x91,0x69, |
2928 | | 0x8c,0x33,0x26,0x19,0x93,0x8d,0x29,0xc6,0x34,0x63,0x86,0x91,0x6b,0xe4,0x1b,0x85, |
2929 | | 0x46,0xb1,0xb1,0xc8,0x28,0x33,0x2a,0x8c,0x2a,0xa3,0xd6,0x68,0x30,0x56,0x1b,0x6b, |
2930 | | 0x8c,0xf5,0xc6,0x46,0x63,0xb3,0xb1,0xd5,0xd8,0x6e,0xec,0x34,0xde,0x30,0xf6,0x1a, |
2931 | | 0xfb,0x8c,0x03,0xc6,0x7b,0x90,0xfb,0xc6,0x07,0xc6,0x87,0xc6,0x47,0xc6,0xc7,0xc6, |
2932 | | 0x09,0xe3,0x13,0xe3,0x53,0xe3,0x8c,0x71,0xce,0xf8,0xdc,0xb8,0x68,0x7c,0x61,0x7c, |
2933 | | 0x69,0x7c,0x65,0x04,0x17,0x6c,0x2e,0xd8,0x5d,0xb0,0xbf,0x40,0xb8,0xe0,0x7c,0xc1, |
2934 | | 0xf5,0x82,0xfb,0x05,0xcf,0x0b,0xde,0x17,0x7c,0x2e,0xf8,0x5d,0x20,0x5f,0xa0,0x5e, |
2935 | | 0x08,0x5c,0xe7,0x5f,0x80,0xb5,0xff,0xf7,0xac,0x27,0x96,0xec,0x36,0x02,0x90,0x8e, |
2936 | | 0x1d,0xdb,0xc0,0xe3,0x77,0x61,0x7e,0x08,0x2b,0xe3,0x60,0x79,0x60,0xe3,0xda,0xf1, |
2937 | | 0x01,0x98,0x53,0x60,0x9e,0x0b,0xd6,0xf2,0x70,0x58,0x49,0x7d,0xe3,0xf8,0xf5,0x79, |
2938 | | 0xaf,0xeb,0xc3,0xd0,0x4d,0x36,0xae,0xe5,0x38,0x2c,0xdf,0x80,0xe5,0x1b,0xb1,0xdc, |
2939 | | 0x0e,0xcb,0xb7,0xc0,0xfc,0x28,0x76,0x8f,0x08,0xec,0xbc,0x08,0xec,0xbc,0x08,0xec, |
2940 | | 0xbc,0x08,0xac,0x3f,0x03,0x6b,0x67,0x60,0xed,0x0c,0xac,0x9d,0x81,0xb5,0xc7,0x60, |
2941 | | 0xd7,0x8f,0xc5,0xfa,0xc5,0x62,0xfd,0x62,0xb1,0x7e,0xb1,0x6f,0xb4,0xa3,0xfe,0x6c, |
2942 | | 0xac,0x1f,0x1b,0xeb,0xc7,0xc6,0xfa,0xb1,0xb1,0x76,0x0e,0x56,0x9f,0x8e,0xf5,0x4b, |
2943 | | 0x7f,0xa3,0xbc,0x01,0xcb,0x37,0x62,0xf9,0x6b,0x5b,0xa2,0xf9,0x7c,0x8c,0xcd,0x27, |
2944 | | 0x13,0x3b,0x2f,0x13,0x3b,0x2f,0x13,0x3b,0x2f,0x13,0xeb,0xcf,0xc3,0xda,0x79,0x58, |
2945 | | 0x3b,0x0f,0x6b,0xe7,0x61,0xed,0xe7,0xb1,0xeb,0xe7,0x62,0xfd,0x72,0xb1,0x7e,0xb9, |
2946 | | 0x58,0xbf,0xdc,0x37,0xda,0x51,0x7f,0x09,0xd6,0x4f,0x82,0xf5,0x93,0x60,0xfd,0x24, |
2947 | | 0x58,0xbb,0x14,0xab,0x97,0xbe,0x61,0x7f,0x1b,0x6c,0xdc,0x36,0x58,0x79,0x13,0x56, |
2948 | | 0xde,0x84,0x95,0x7d,0xb0,0xb2,0x0f,0xe6,0x27,0x1c,0x36,0x3f,0x1c,0x56,0xde,0x80, |
2949 | | 0x95,0x37,0x60,0xe5,0xcd,0x58,0x79,0x33,0x56,0xb6,0xc7,0xca,0x28,0x0f,0xc7,0xf2, |
2950 | | 0x0c,0x2c,0x8f,0xc0,0xee,0x9b,0x89,0xe5,0x11,0xd8,0x7d,0x33,0xb1,0x3c,0x02,0xbb, |
2951 | | 0x4e,0x26,0x96,0x47,0x60,0xe3,0xc8,0xc4,0xf2,0x08,0xec,0x3a,0x99,0x58,0x7e,0x1c, |
2952 | | 0x1b,0xc7,0x39,0x2c,0x3f,0x8e,0x5d,0xe7,0x1c,0x96,0x1f,0xc7,0xae,0x73,0x0e,0xcb, |
2953 | | 0x8f,0x63,0x7e,0x3a,0x87,0xe5,0x91,0xd8,0x79,0xdc,0x37,0xe2,0x6a,0x23,0xe6,0x8f, |
2954 | | 0x8d,0x58,0xd9,0x06,0x2b,0xdb,0x60,0xe5,0x4d,0x58,0x79,0x13,0x56,0xf6,0xc1,0xca, |
2955 | | 0x3e,0x58,0x79,0x33,0x96,0x47,0x81,0xb5,0xfa,0x6c,0xec,0x18,0x5d,0x3f,0x1b,0xcb, |
2956 | | 0xa3,0xb1,0xfb,0xe7,0x60,0x39,0x13,0xb3,0x2f,0x1f,0xcb,0x99,0x58,0x3d,0xff,0x8d, |
2957 | | 0x76,0x7b,0xac,0x6c,0x8f,0x95,0x6f,0x83,0xb5,0x32,0xca,0x63,0xb0,0xf3,0xce,0x63, |
2958 | | 0x79,0x0c,0x76,0xde,0x79,0x2c,0x8f,0xc1,0xce,0x3b,0x8f,0xe5,0x03,0x1b,0xd6,0x8e, |
2959 | | 0x63,0xb1,0x79,0xe5,0x62,0x79,0x2c,0x36,0xaf,0x5c,0x2c,0x47,0xe5,0xad,0x58,0x19, |
2960 | | 0xe5,0x09,0xd8,0xf5,0xf3,0xb0,0x3c,0x01,0xbb,0x7e,0x1e,0x96,0x27,0x60,0xd7,0xcf, |
2961 | | 0xc3,0xf2,0x44,0xac,0x5f,0x3e,0x96,0x27,0x62,0xf3,0xcf,0xc7,0xf2,0x44,0xec,0xbc, |
2962 | | 0x7c,0x2c,0x4f,0xc4,0xce,0xcb,0xc7,0xf2,0x24,0xac,0x5e,0x8c,0xe5,0x49,0x58,0xbd, |
2963 | | 0x18,0xcb,0xd9,0x98,0x9f,0x24,0x58,0xce,0xc6,0xe6,0x21,0xc1,0x72,0x36,0x36,0x0f, |
2964 | | 0x09,0x96,0xb3,0xb1,0xf5,0x2a,0xc1,0x72,0x36,0x36,0x2f,0x09,0x96,0xb3,0x31,0x3f, |
2965 | | 0x4a,0xb0,0xfc,0x24,0x36,0xce,0x42,0x2c,0xe7,0x60,0xb9,0xf4,0x8d,0x32,0x5a,0x57, |
2966 | | 0xa7,0xb0,0xf9,0x15,0x63,0xf9,0x29,0x2c,0x0e,0x8a,0xb1,0xfc,0x14,0x36,0xde,0xe2, |
2967 | | 0x37,0xe6,0x87,0x6c,0xbb,0x1b,0xb3,0xed,0x6e,0xec,0xde,0xbb,0xb1,0x7b,0xef,0xc6, |
2968 | | 0xd6,0xce,0xa9,0x37,0xd6,0x51,0xf1,0x1b,0x6b,0xa9,0xf8,0x8d,0x38,0x40,0xb1,0xc5, |
2969 | | 0xc4,0xe2,0x8c,0x8f,0xe5,0x31,0x58,0x7d,0x0c,0x56,0x3e,0x8f,0xe5,0x61,0xd8,0x79, |
2970 | | 0xe9,0x58,0xce,0xc0,0x72,0x1e,0x96,0xc7,0x62,0x79,0xee,0x1b,0xf6,0xb5,0xc7,0xc6, |
2971 | | 0x64,0xff,0xc6,0x3e,0x69,0xf3,0xc6,0x1e,0x63,0xf3,0x46,0x3d,0xee,0x8d,0x7a,0xdc, |
2972 | | 0x1b,0xf5,0xf6,0x6f,0xd4,0xbf,0x79,0x1d,0xf0,0x46,0x3d,0x78,0xe3,0x39,0x61,0xf3, |
2973 | | 0xc6,0x1e,0xfb,0x7a,0x9f,0xda,0xfc,0x46,0xfd,0xeb,0xe3,0xff,0x85,0xf9,0x79,0x16, |
2974 | | 0xcb,0x8f,0x63,0xe3,0x3c,0x87,0xe5,0xd1,0x58,0x9e,0xf3,0xc6,0xfc,0x7c,0xb0,0xf9, |
2975 | | 0xf9,0xbc,0x51,0xb6,0x79,0xa3,0x0e,0x1d,0xdf,0xc6,0xad,0xf5,0xff,0x74,0xc3,0x5a, |
2976 | | 0x9e,0xfd,0x86,0x1f,0x90,0x4f,0x5e,0xfb,0xe3,0xb5,0x2f,0x8e,0x63,0x7e,0x3f,0xf7, |
2977 | | 0xc6,0xfa,0x03,0xd8,0x7a,0x03,0x6f,0x3c,0xf7,0x70,0x6f,0x3c,0x33,0x70,0xd8,0xf8, |
2978 | | 0x71,0xd8,0xf8,0x51,0x3e,0x81,0xe5,0x2f,0xff,0x3f,0xf6,0xce,0x04,0x40,0xc7,0xe2, |
2979 | | 0xf1,0xe3,0xcf,0xfb,0xee,0xbe,0xbb,0xd6,0x7d,0x76,0x29,0xd7,0x16,0xc2,0xae,0xbd, |
2980 | | 0x59,0xe7,0x5a,0xd6,0x99,0x90,0x90,0x54,0xae,0x90,0x5c,0xeb,0x08,0x95,0xca,0x91, |
2981 | | 0xd2,0x49,0x87,0x4a,0x27,0x9d,0xa4,0x72,0x25,0x54,0xce,0x0a,0x91,0x12,0x15,0x65, |
2982 | | 0x8b,0x90,0x44,0x42,0xba,0x48,0xf5,0xff,0xcc,0x3e,0xdf,0x27,0xe3,0xf9,0xdb,0x1f, |
2983 | | 0xaa,0x5f,0xbf,0x8e,0xf7,0x19,0x1f,0xdf,0x99,0x79,0xe6,0x99,0x67,0x66,0x9e,0x99, |
2984 | | 0x79,0x9e,0xf7,0x99,0x79,0x66,0xad,0xfb,0x68,0x11,0x1d,0x53,0x44,0xee,0x62,0x72, |
2985 | | 0x17,0x53,0x7f,0x58,0x44,0xfd,0x61,0x11,0xb9,0x8b,0xc9,0x5d,0x4c,0xd7,0xb7,0x88, |
2986 | | 0xae,0x6f,0x11,0xb9,0x8b,0xc9,0x5d,0x4c,0xf9,0x2f,0xa2,0xbc,0x17,0x91,0xbb,0x98, |
2987 | | 0xdc,0xc5,0xd4,0x9e,0x8b,0xa8,0x3d,0x17,0x91,0xbb,0x98,0xdc,0xc5,0x74,0x1d,0x8b, |
2988 | | 0xe8,0x1a,0x16,0x91,0xbb,0x98,0xdc,0xc5,0xd4,0x9e,0x2b,0xaa,0xbe,0x57,0x54,0xfb, |
2989 | | 0xad,0xa8,0xf6,0x5b,0x51,0xfd,0x6f,0x41,0xf5,0xbf,0x05,0xad,0xeb,0xdc,0xd5,0xea, |
2990 | | 0xff,0xbd,0xfb,0x6a,0x25,0xeb,0x3e,0x1e,0x69,0xdd,0x03,0x23,0xad,0xfb,0x7c,0xa4, |
2991 | | 0x75,0x8f,0xf4,0xfc,0xa3,0xe5,0x17,0x6d,0xb9,0x23,0x2d,0xbf,0x48,0xb5,0xe3,0x48, |
2992 | | 0xb5,0xeb,0x48,0xa5,0xa7,0x67,0xd0,0xbd,0xee,0x26,0xaf,0x57,0x63,0xbf,0x16,0x46, |
2993 | | 0x05,0xdd,0xbe,0xe0,0x6a,0x3d,0x33,0x45,0xe9,0x79,0x29,0x5a,0x9a,0x5f,0x5a,0x59, |
2994 | | 0x1a,0x21,0x35,0x7d,0x4b,0xf7,0xa0,0xdb,0x3e,0x4d,0x59,0x0c,0x87,0x89,0x41,0xb7, |
2995 | | 0x6e,0x98,0xeb,0x5c,0x22,0xe2,0x48,0x9b,0x59,0x10,0x74,0x8f,0xc9,0xc2,0x5e,0xdb, |
2996 | | 0x7a,0x36,0x9b,0x2a,0xbd,0x4b,0xe1,0x4c,0xbf,0x3f,0x51,0xf6,0xfb,0xa5,0x93,0xa4, |
2997 | | 0x8f,0x49,0x9f,0x92,0x4e,0xf3,0xe2,0xb6,0xce,0x33,0x49,0xf6,0xa7,0xa4,0xb3,0xe4, |
2998 | | 0x3f,0xd7,0x8b,0xdf,0x3a,0xc6,0xe8,0x1b,0x76,0x1a,0x65,0xf7,0xfc,0x16,0x5b,0x61, |
2999 | | 0x8c,0xbe,0x29,0x9d,0x0d,0xf3,0x75,0x8e,0x75,0xf2,0x5b,0xa7,0x63,0x96,0xc3,0x12, |
3000 | | 0x78,0x19,0x96,0xc2,0x32,0x78,0x40,0xe7,0x7f,0x02,0x4a,0x45,0xba,0xe5,0x63,0xd4, |
3001 | | 0x84,0x2f,0x11,0xe9,0x1e,0x1f,0x25,0xf7,0x19,0x72,0x9f,0xa6,0x70,0xb1,0x91,0xee, |
3002 | | 0xf5,0x38,0x4d,0x5a,0x53,0x9a,0xaa,0xfd,0xa9,0x3a,0x2e,0x59,0xc7,0xb5,0x97,0xbb, |
3003 | | 0x96,0xdc,0x35,0x15,0xae,0xa1,0x8e,0x1b,0x12,0xa9,0xba,0x2d,0x3d,0x45,0xfe,0x69, |
3004 | | 0xd2,0xa2,0xd2,0x04,0xcb,0x9d,0x4f,0xee,0x7c,0x4a,0xb7,0x77,0x7e,0xa3,0x1b,0xe5, |
3005 | | 0xff,0xa1,0xf4,0x14,0x69,0x9a,0xf4,0x54,0x69,0x0d,0xa9,0xc9,0x47,0xa4,0xd2,0x15, |
3006 | | 0x29,0x77,0x3e,0xb9,0x8d,0x96,0x91,0xd6,0x93,0xee,0x94,0x7e,0x21,0x8d,0x93,0xb6, |
3007 | | 0x94,0xc6,0x2a,0x9e,0x86,0xd2,0x58,0xf9,0x37,0xb4,0xf6,0x17,0x90,0xdb,0x68,0x25, |
3008 | | 0xf9,0x37,0x91,0x56,0x95,0xb6,0x90,0xf6,0x08,0x39,0xce,0x68,0xa8,0x14,0x45,0x3b, |
3009 | | 0x8f,0x72,0xf5,0x42,0x68,0x2a,0x35,0xee,0x76,0xd0,0xdc,0x72,0x0f,0xd1,0x7e,0xa3, |
3010 | | 0x2b,0xa4,0xcd,0xa5,0xef,0x2b,0xdc,0x52,0xe9,0x3a,0x69,0xe5,0x18,0xc7,0xa9,0x03, |
3011 | | 0x09,0xd2,0x64,0x69,0x29,0xe9,0x29,0xd2,0x53,0xa5,0x67,0x4a,0xcb,0x4b,0x2b,0x48, |
3012 | | 0xab,0x4a,0xab,0x4b,0x57,0xc0,0x22,0xe9,0x06,0x98,0x02,0xaf,0xc2,0xe3,0xd2,0x19, |
3013 | | 0xd2,0xa4,0xfc,0x84,0x87,0x9a,0xd2,0x53,0xa4,0xa7,0x4a,0xcf,0x94,0x56,0x95,0x36, |
3014 | | 0x29,0x40,0xdd,0x2a,0xe0,0x6a,0x3d,0x69,0x07,0x28,0x0f,0x75,0xa0,0x82,0xf4,0x6e, |
3015 | | 0xd8,0x00,0xcb,0x61,0x11,0xac,0x90,0x2e,0x97,0x7f,0xe3,0x82,0xc4,0x03,0x8b,0xe1, |
3016 | | 0x7d,0x58,0x6e,0xe9,0x07,0xd2,0x65,0x96,0x9a,0x7d,0x8d,0x0b,0x71,0x4e,0x68,0x22, |
3017 | | 0x35,0xee,0x0e,0xf0,0x21,0xac,0x92,0xbe,0x63,0xa9,0xe7,0xb7,0x19,0x5a,0x16,0x26, |
3018 | | 0xaf,0xb0,0x06,0x66,0xc3,0x74,0x98,0x24,0x9d,0x02,0x05,0x8a,0x38,0x4e,0x26,0xcc, |
3019 | | 0x83,0xf3,0xa4,0x6d,0xa4,0xed,0xa5,0x9d,0xa4,0x19,0x30,0x17,0x06,0xc2,0x20,0xe9, |
3020 | | 0x10,0x98,0x0d,0x23,0xa5,0x03,0x65,0x9f,0x63,0xa9,0xe7,0xe7,0xe9,0xdd,0x8a,0xef, |
3021 | | 0x61,0xe9,0x14,0xe9,0xd3,0xd2,0xe9,0xd2,0x09,0x3a,0xdf,0x39,0x45,0x1d,0x27,0x1e, |
3022 | | 0x72,0x20,0x54,0x9a,0xb6,0x07,0xd1,0xd2,0x18,0x69,0x01,0x69,0x21,0x69,0x31,0x69, |
3023 | | 0x2d,0x69,0x1d,0x69,0x3d,0x69,0x7d,0x69,0xa6,0xd4,0xdc,0xa3,0xcc,0x7d,0x3b,0x53, |
3024 | | 0xcf,0x01,0xe6,0x1e,0x75,0x67,0xc0,0x7d,0x06,0x30,0xf7,0x33,0xef,0xd9,0xbf,0x85, |
3025 | | 0x9e,0xcb,0x5a,0xea,0x39,0xcc,0xdc,0x7b,0x2a,0xd0,0xb7,0xb7,0x76,0xdc,0xfb,0xa8, |
3026 | | 0xb9,0x17,0x9a,0xfb,0xa5,0x79,0xc6,0x34,0xf7,0xbb,0xd6,0xec,0x6b,0x03,0xc1,0xb3, |
3027 | | 0x1c,0xa7,0x9b,0x9e,0x2d,0xcc,0x7d,0xaf,0x23,0x7e,0x9d,0xe0,0x92,0xa0,0xfb,0x7c, |
3028 | | 0x61,0x9e,0x65,0xfa,0x99,0xf8,0x03,0xee,0x3d,0xec,0x42,0xfc,0x4f,0xe1,0x98,0x53, |
3029 | | 0x21,0xdb,0x71,0xef,0xad,0xe6,0xfe,0x7b,0x16,0xee,0x01,0xec,0x1b,0x8a,0xfd,0x9c, |
3030 | | 0xb3,0xdc,0xbe,0x78,0x0e,0xbc,0xa8,0xbe,0x77,0x85,0x9e,0x03,0x06,0x29,0xbc,0x09, |
3031 | | 0xe7,0x85,0x59,0x6a,0x85,0xa9,0x4b,0x7b,0xbf,0x20,0xe8,0xfe,0xa6,0x6b,0x87,0xee, |
3032 | | 0x73,0xdc,0xb4,0xf4,0x44,0x3b,0xa3,0x5d,0xa1,0x07,0x5c,0x01,0xbd,0xcd,0x3d,0xd3, |
3033 | | 0xdc,0x2b,0x39,0xdf,0x23,0x68,0x3f,0x18,0x8b,0xfd,0x31,0x74,0x20,0x64,0xc3,0x20, |
3034 | | 0x18,0x0c,0x43,0xe0,0x2a,0x18,0x0e,0xa3,0x61,0x0c,0x4c,0x27,0x4f,0xb7,0xa0,0xb7, |
3035 | | 0xc2,0x99,0x1c,0x77,0x1b,0x7a,0x7b,0xd0,0x7d,0xc6,0x9a,0x80,0xde,0x15,0x74,0x9f, |
3036 | | 0xc9,0xe6,0xeb,0x59,0xe1,0x1c,0x3d,0x2b,0x18,0xcd,0xd4,0x7d,0xb8,0x9b,0xd4,0xb8, |
3037 | | 0x63,0xe5,0x8e,0x95,0x3b,0x51,0xee,0x44,0xeb,0x1d,0x44,0xc0,0xfa,0xfd,0x1e,0xd0, |
3038 | | 0x33,0x5e,0xb4,0x9e,0xb3,0xa3,0xe5,0x8e,0x95,0x3b,0x56,0xee,0x44,0xb9,0x13,0xe5, |
3039 | | 0xae,0x24,0x77,0x25,0xb9,0xe3,0xe4,0x8e,0xb3,0x7e,0xf3,0x3a,0xd6,0xef,0x5e,0xc7, |
3040 | | 0xf2,0x0f,0x58,0xfe,0xde,0x3b,0x90,0x38,0xf9,0x79,0xc7,0x27,0xc8,0x9d,0x60,0x3d, |
3041 | | 0x13,0x45,0x59,0xcf,0x45,0xc6,0xde,0x58,0xe9,0xed,0x69,0xfd,0xd6,0x8d,0xd4,0x33, |
3042 | | 0x69,0xa4,0x9e,0xb5,0xa2,0xf5,0x6c,0x13,0x2d,0x77,0xac,0xdc,0xb1,0x72,0xe7,0x93, |
3043 | | 0x3b,0x9f,0xdc,0x95,0xe4,0xf6,0x7e,0x2b,0xc7,0xcb,0x1d,0xaf,0x67,0xc9,0x04,0xd5, |
3044 | | 0xa1,0x04,0xeb,0x9d,0x4c,0xc0,0x7a,0x9f,0x11,0xd0,0x33,0x78,0x40,0xcf,0xe0,0x9e, |
3045 | | 0x3b,0x56,0xee,0x58,0xb9,0x13,0xe5,0x4e,0xd4,0x6f,0x9a,0x58,0xfd,0xd6,0x8d,0xb5, |
3046 | | 0xdc,0x91,0x96,0x5f,0xa4,0xfc,0x13,0xe5,0xe7,0x1d,0x17,0x27,0xb7,0xd1,0x96,0x3a, |
3047 | | 0x5f,0x3f,0x69,0x4b,0xe5,0xbb,0x9f,0xb4,0xa5,0xe2,0xea,0x27,0x3d,0x5f,0xfe,0xfd, |
3048 | | 0xa5,0xe7,0xcb,0xbf,0xbf,0xb5,0x3f,0x51,0xee,0x44,0xb9,0xe3,0xe4,0x8e,0xb3,0x9e, |
3049 | | 0x41,0x03,0xd6,0x33,0x68,0xc0,0xf2,0xcf,0x67,0xf9,0xe7,0x8b,0x38,0xf2,0xdb,0xdb, |
3050 | | 0xb1,0x7e,0x7f,0x3b,0x96,0x7f,0xc0,0xf2,0x37,0xf6,0xd6,0xca,0x47,0xb6,0x73,0xc4, |
3051 | | 0x1d,0x2d,0x77,0xb4,0x9e,0xcd,0xa3,0xf5,0x6c,0xee,0xb9,0x63,0xe5,0x8e,0xb5,0xdc, |
3052 | | 0x91,0x96,0x5f,0xa4,0xfc,0x13,0xe5,0x97,0xa8,0x67,0xf6,0x68,0x3d,0xb3,0x47,0xcb, |
3053 | | 0x1d,0x2b,0x77,0xac,0xf5,0x9b,0x3e,0xda,0xfa,0x5d,0x1f,0x6d,0xfd,0x76,0x8f,0xb6, |
3054 | | 0x7e,0xbf,0xdb,0xc7,0x47,0x5b,0x71,0x44,0xeb,0xb7,0x40,0xb4,0x7e,0x0b,0x78,0xee, |
3055 | | 0x58,0xb9,0x63,0xe5,0x4e,0x94,0x3b,0x51,0xee,0x38,0xb9,0xe3,0xf4,0x5b,0xe3,0x6c, |
3056 | | 0xfd,0xd6,0x38,0x5b,0xee,0x04,0xb9,0x13,0xe4,0x8e,0x93,0x3b,0xce,0x7a,0x57,0x10, |
3057 | | 0xb0,0xde,0x17,0x04,0xac,0x77,0x06,0xf9,0xac,0xf7,0x06,0xc6,0xde,0x5e,0x61,0x86, |
3058 | | 0x4a,0xdb,0x2b,0x5d,0x43,0xa5,0x1d,0xf4,0xdb,0x6e,0x98,0xb4,0x83,0xca,0x62,0x98, |
3059 | | 0xb4,0x83,0xda,0xc0,0x30,0x69,0x07,0xe5,0x73,0x98,0xb4,0x83,0xe2,0x19,0x26,0xbd, |
3060 | | 0x48,0xfe,0xc3,0xa5,0x17,0xe9,0xb8,0xe1,0xd6,0xbb,0xc9,0x68,0xfd,0x46,0xf1,0xde, |
3061 | | 0x29,0x04,0xf5,0x4e,0x21,0x28,0x77,0xac,0xdc,0xb1,0x72,0x27,0xca,0x9d,0xa8,0x76, |
3062 | | 0xeb,0x95,0xa7,0x97,0xae,0xfc,0x8a,0x2f,0xbf,0xfa,0xd1,0x45,0xf4,0xad,0x37,0x04, |
3063 | | 0xdc,0xf8,0x1b,0x28,0x9e,0xae,0x52,0xe3,0x8e,0x91,0x3b,0xc6,0x7a,0xc7,0x6b,0xbf, |
3064 | | 0x1f,0xb5,0xdf,0xfd,0x3a,0x96,0xbf,0x63,0xf9,0xc7,0x58,0xfe,0x76,0x3c,0x11,0x96, |
3065 | | 0x7f,0x84,0x75,0xfe,0xa0,0x95,0x86,0xa0,0xf5,0xce,0x32,0x60,0xbd,0xb7,0x0c,0x58, |
3066 | | 0xfe,0x8e,0xe5,0xef,0x58,0xfe,0x31,0x96,0x7f,0x8c,0xe5,0x1f,0x61,0xf9,0xdb,0xe7, |
3067 | | 0x8d,0xb2,0xce,0xeb,0xbd,0x9b,0x8c,0x55,0x9f,0x1b,0x2b,0x77,0x8c,0xdc,0x31,0x72, |
3068 | | 0x47,0xc8,0x1d,0x61,0xbd,0xcb,0xb6,0xdf,0x03,0xdb,0xef,0xb8,0x1d,0xcb,0xdf,0xb1, |
3069 | | 0xfc,0x63,0x2c,0xff,0x18,0xcb,0x3f,0xc2,0xf2,0x8f,0xb0,0xd2,0x13,0xb4,0xd2,0xe4, |
3070 | | 0xbd,0xc3,0x8c,0x51,0x1f,0x1c,0x23,0x77,0xac,0xdc,0xb1,0xea,0x5f,0x62,0xd5,0xb7, |
3071 | | 0x78,0xee,0x18,0xb9,0x63,0xac,0x77,0xe7,0xf6,0x7b,0x67,0xfb,0x9d,0xba,0x63,0xf9, |
3072 | | 0x3b,0x96,0x7f,0x8c,0xe5,0x6f,0xc7,0x13,0x61,0xf9,0x47,0x58,0xe7,0x0f,0x5a,0x69, |
3073 | | 0xf0,0xde,0xd5,0x97,0xb6,0xce,0x5b,0xda,0x3a,0x6f,0x69,0xeb,0xbc,0xa5,0xad,0xf3, |
3074 | | 0x96,0xb6,0xce,0x5b,0xda,0x3a,0x6f,0x69,0xeb,0xbc,0xa5,0xad,0xf3,0x1a,0x7b,0xac, |
3075 | | 0xe5,0x1f,0xab,0xf6,0x1f,0xab,0xb6,0xef,0xb9,0x63,0xe4,0x8e,0xb1,0xde,0xcb,0x05, |
3076 | | 0xac,0x77,0x73,0x01,0xcb,0xdf,0xb1,0xfc,0x1d,0xcb,0x3f,0xc6,0xf2,0xb7,0xe3,0x89, |
3077 | | 0xb0,0xfc,0x23,0x2c,0xff,0x58,0xcb,0x3f,0x56,0xed,0xdd,0x51,0xfb,0x74,0xe4,0x8e, |
3078 | | 0x95,0xdb,0xdb,0x1f,0x23,0x77,0x8c,0xdc,0x11,0x72,0x47,0xe8,0xf7,0x7c,0x09,0x69, |
3079 | | 0x49,0xcb,0xed,0x58,0x7e,0x8e,0xe5,0x1f,0xb0,0xfc,0x03,0x96,0x7f,0xa6,0xe5,0x9f, |
3080 | | 0xa9,0xf7,0x0f,0x25,0xa4,0x25,0x2d,0xb7,0x63,0xf9,0x39,0x96,0x7f,0xc0,0xf2,0x0f, |
3081 | | 0x58,0xfe,0x99,0x96,0x7f,0xa6,0x7e,0xf7,0x97,0x90,0x96,0xb4,0xdc,0x8e,0xe5,0xe7, |
3082 | | 0x58,0xfe,0x01,0xcb,0xdf,0xd8,0x27,0xca,0x7f,0xa2,0xfc,0x26,0x5a,0xc7,0x4f,0xb4, |
3083 | | 0x8e,0x9f,0x68,0x1d,0x3f,0xd1,0x3a,0x7e,0x9e,0xfc,0xe7,0xc9,0x6f,0x9e,0x75,0xfc, |
3084 | | 0x3c,0xeb,0xf8,0x79,0xd6,0xf1,0xf3,0x8e,0x71,0x7c,0xa6,0xe5,0x9f,0xa9,0x77,0x33, |
3085 | | 0x25,0xa4,0x25,0x2d,0xb7,0x63,0xf9,0x39,0x96,0x7f,0xc0,0xf2,0x0f,0x58,0xfe,0x99, |
3086 | | 0x96,0x7f,0xa6,0xde,0xc1,0x94,0x90,0x96,0xb4,0xdc,0x8e,0xe5,0xe7,0x58,0xfe,0x01, |
3087 | | 0xcb,0x3f,0x60,0xf9,0x67,0x5a,0xfe,0x99,0x7a,0x2f,0x54,0x42,0x5a,0xd2,0x72,0x3b, |
3088 | | 0x96,0x9f,0x63,0xf9,0x07,0x2c,0xff,0x80,0xe5,0x9f,0x69,0xf9,0x67,0xea,0x1d,0x51, |
3089 | | 0x09,0x69,0x49,0xcb,0xed,0x58,0x7e,0x8e,0xe5,0x1f,0xb0,0xfc,0xbd,0x77,0x5a,0x25, |
3090 | | 0xa4,0x25,0x2d,0xb7,0x63,0xf9,0x39,0x96,0x7f,0xc0,0xf2,0xf7,0xde,0x4d,0x95,0x90, |
3091 | | 0x96,0xb4,0xdc,0x8e,0xe5,0xe7,0x58,0xfe,0x01,0xcb,0xdf,0x3e,0x3e,0xd3,0xf2,0xcf, |
3092 | | 0xd4,0xbb,0xad,0x92,0x96,0x3a,0x96,0x3d,0x60,0xd9,0x33,0xf5,0x5e,0xac,0x84,0xb4, |
3093 | | 0xa4,0xe5,0x76,0x2c,0x3f,0xc7,0xf2,0x0f,0x58,0xfe,0x01,0xcb,0x3f,0xd3,0xf2,0xcf, |
3094 | | 0xd4,0xfb,0xbd,0x12,0xd2,0x92,0x96,0xdb,0xb1,0xfc,0x1c,0xcb,0x3f,0x60,0xf9,0x07, |
3095 | | 0x2c,0xff,0x4c,0xcb,0xdf,0x6b,0xf7,0x8e,0xef,0xdd,0xa0,0xe3,0x7b,0x47,0xe8,0xf8, |
3096 | | 0xde,0x15,0x3a,0xd6,0x3b,0xc3,0xc5,0xd6,0x35,0xf5,0xca,0xd0,0xf1,0xbd,0x27,0x74, |
3097 | | 0xac,0xf7,0x85,0x5e,0x9f,0x93,0x65,0xf5,0x39,0x59,0xbe,0xbe,0x2b,0xcb,0xd7,0x7f, |
3098 | | 0x65,0xf9,0xfa,0xb0,0x2c,0x5f,0x3f,0x96,0xe5,0xeb,0xcb,0xb2,0x7c,0xfd,0x59,0x96, |
3099 | | 0xd5,0x27,0x65,0x59,0x7d,0x52,0x96,0xaf,0x6f,0xcb,0xf2,0xf5,0x6f,0x59,0xbe,0x3e, |
3100 | | 0x2e,0xcb,0xd7,0xcf,0x65,0xf9,0xfa,0xba,0x2c,0x5f,0x7f,0x97,0x65,0xf5,0x19,0x59, |
3101 | | 0x56,0x9f,0x91,0xe5,0xeb,0x7b,0xb2,0x7c,0xfd,0x4f,0x96,0xaf,0x0f,0xca,0xf2,0xf5, |
3102 | | 0x43,0x59,0xbe,0xbe,0x28,0xcb,0xd7,0x1f,0x65,0x59,0x7d,0x4a,0x96,0xd5,0xa7,0x64, |
3103 | | 0xf9,0xfa,0xa6,0x2c,0x5f,0xff,0x94,0xe5,0xeb,0xa3,0xb2,0x7c,0xfd,0x54,0x96,0xaf, |
3104 | | 0xaf,0xca,0xf2,0xf5,0x57,0x59,0x56,0xfd,0xcd,0xb2,0xea,0x6f,0x96,0xaf,0x1d,0x64, |
3105 | | 0xf9,0xda,0x42,0x96,0xaf,0x3d,0x64,0xf9,0xda,0x44,0x96,0xaf,0x5d,0x64,0xf9,0xda, |
3106 | | 0x46,0x96,0x55,0xbf,0xb3,0xac,0xfa,0x9d,0xe5,0x6b,0x27,0x59,0xbe,0xb6,0x92,0xe5, |
3107 | | 0x6b,0x2f,0x59,0xbe,0x36,0x93,0xe5,0x6b,0x37,0x59,0xbe,0xb6,0xe3,0xd5,0xb3,0x28, |
3108 | | 0x69,0xa4,0xd5,0x9e,0xbc,0x7d,0x59,0x56,0xdb,0xf2,0xec,0x99,0x96,0x7a,0x75,0x26, |
3109 | | 0x4a,0x1a,0x29,0x75,0xac,0x71,0x80,0xbb,0x14,0xce,0x8c,0x13,0x78,0xf7,0x03,0xcf, |
3110 | | 0x6e,0x34,0x53,0x63,0x07,0x99,0x56,0x7b,0xf5,0xea,0x44,0x96,0xd5,0x76,0x3d,0x7b, |
3111 | | 0xa6,0xa5,0x59,0xba,0x47,0x7a,0xf7,0x4d,0xef,0x7e,0xe4,0x58,0x63,0x0e,0xf7,0x2b, |
3112 | | 0xdc,0xe2,0xb2,0x6a,0xeb,0x65,0xd5,0xf6,0xcb,0x1e,0xb9,0xb7,0x44,0x49,0x23,0xad, |
3113 | | 0xb1,0x03,0xc7,0x37,0x1e,0xb1,0xc0,0xba,0x17,0xe5,0xb3,0xee,0x1f,0x51,0xd2,0x48, |
3114 | | 0xa9,0x63,0x8d,0x73,0xfc,0xac,0x73,0xfe,0x5c,0xf6,0x88,0xdb,0xeb,0x9f,0xa3,0xa4, |
3115 | | 0x91,0xd6,0x38,0x85,0xe3,0x1b,0xc7,0x58,0xaa,0xeb,0xb7,0xd4,0xba,0x27,0x64,0x5a, |
3116 | | 0x61,0xbc,0xfe,0x3d,0x4a,0x1a,0x29,0x75,0xac,0xb1,0x95,0x29,0x3a,0x76,0xaa,0x9e, |
3117 | | 0xd3,0xbc,0x71,0x9a,0x2e,0xce,0x91,0xfe,0xcd,0xab,0x93,0x59,0x56,0x5f,0xe7,0xd9, |
3118 | | 0x33,0x2d,0xcd,0xd2,0x3d,0xcb,0xb1,0xc6,0x70,0xa6,0x59,0x7d,0xb7,0xe7,0x36,0xe1, |
3119 | | 0x5e,0xd4,0xd8,0x90,0x39,0x77,0x10,0x4b,0x44,0xb9,0x23,0xf3,0x7c,0xfe,0x13,0x45, |
3120 | | 0x15,0x2e,0x99,0xe3,0xe2,0x9d,0x63,0x63,0xf6,0x27,0x95,0xfb,0xff,0xa4,0x1e,0x83, |
3121 | | 0xf2,0x8e,0x8b,0x39,0x26,0x44,0x9c,0xf5,0x9d,0x23,0x78,0xfb,0xea,0x1f,0x23,0x3e, |
3122 | | 0x13,0x3e,0x41,0x73,0x24,0xcc,0x1c,0xa2,0x54,0x48,0x83,0x1a,0x50,0x13,0xd2,0xa1, |
3123 | | 0x2a,0x14,0xaf,0xe0,0x38,0x75,0xcd,0x98,0x1a,0x9c,0xab,0xb1,0xec,0x04,0xcd,0x45, |
3124 | | 0xf2,0xe6,0x21,0x9d,0xcc,0xf1,0x5d,0xf5,0x5e,0x75,0x80,0xc6,0xe1,0xcc,0xfb,0xd5, |
3125 | | 0x2b,0xf4,0x5e,0xb5,0xaf,0xde,0xad,0x9a,0x73,0x64,0x6b,0xac,0x6e,0x88,0xde,0xd7, |
3126 | | 0x0e,0xd6,0xb1,0xd5,0x1d,0xf7,0x7d,0xa1,0x67,0x37,0xfe,0xe6,0x5d,0xe2,0x4c,0x69, |
3127 | | 0x77,0xf9,0x0f,0xb0,0xec,0xe6,0xb9,0x7e,0x42,0xc0,0x0d,0x63,0xde,0xd3,0xf5,0xd2, |
3128 | | 0xbb,0x62,0x8f,0xdc,0x77,0x6c,0x01,0xf7,0xb7,0x5a,0x33,0xbd,0x37,0xee,0xab,0xf7, |
3129 | | 0xc6,0xe7,0x2b,0x2e,0xf3,0xbe,0xa7,0x8d,0xd2,0xe2,0xd1,0x56,0xef,0x97,0x2f,0xd4, |
3130 | | 0x7b,0xe8,0xf3,0x64,0x6f,0xa9,0x71,0xea,0x69,0x7a,0x0f,0xd0,0xc2,0x39,0x32,0x06, |
3131 | | 0x9d,0xa9,0x74,0xf6,0xd0,0x31,0x8d,0x15,0xde,0x9c,0x63,0x6d,0xc8,0x71,0xde,0x85, |
3132 | | 0x75,0xb0,0x3e,0xe4,0x5e,0x9b,0xc6,0x3a,0xd6,0xbc,0x8f,0x58,0xa2,0xf7,0xc3,0xf7, |
3133 | | 0xc0,0x64,0x28,0x56,0xc1,0x7d,0xdf,0xe9,0xbd,0xab,0xf6,0xe6,0xbb,0x78,0xf3,0xc4, |
3134 | | 0x6a,0x58,0xf6,0x74,0xcb,0x9e,0x68,0x5d,0x43,0xe3,0x4e,0xd6,0xb5,0xf4,0xec,0x9e, |
3135 | | 0x7f,0xaa,0xe5,0x9f,0x6a,0xcd,0x39,0x4b,0xd5,0x35,0xf7,0xec,0x5e,0xf8,0x34,0xd5, |
3136 | | 0x03,0xcf,0xee,0xf9,0xd7,0xb4,0x8e,0xad,0x69,0x85,0xa9,0xa9,0xfa,0xe2,0xd9,0xbd, |
3137 | | 0xf0,0xde,0x75,0x38,0x16,0xed,0x2d,0x9a,0x59,0xea,0xb7,0x7b,0x5c,0x64,0xd1,0xcc, |
3138 | | 0x52,0xef,0x3a,0x37,0xd4,0x38,0x42,0x4b,0x95,0x5f,0x5e,0x0c,0xb5,0xe8,0x6d,0xa9, |
3139 | | 0xdf,0xee,0x31,0xdc,0xa2,0xb7,0xa5,0xbd,0x55,0xb7,0xba,0xeb,0xba,0xf5,0xd3,0xb5, |
3140 | | 0xf0,0xca,0x7e,0x02,0x0d,0xb6,0xa6,0x99,0xfb,0x20,0xbd,0x57,0xba,0x56,0xfa,0x9e, |
3141 | | 0x74,0x9d,0x34,0xa2,0x82,0xab,0xf9,0xa4,0x05,0xa4,0xb1,0xd2,0x73,0xa4,0x55,0x2b, |
3142 | | 0xfc,0x7f,0xe2,0x8f,0x41,0x1d,0x85,0x6f,0x28,0xcd,0x92,0x36,0x95,0x9a,0xb6,0x6c, |
3143 | | 0xb4,0xab,0xdc,0x2d,0xa5,0x75,0xe4,0x5f,0x4f,0x7a,0xb9,0xfc,0x7b,0x48,0x07,0x49, |
3144 | | 0x07,0x4b,0x87,0x4a,0x87,0x49,0xaf,0x91,0x5e,0x2b,0x1d,0x2d,0x1d,0x23,0xbd,0x49, |
3145 | | 0x7a,0xb3,0xf4,0x71,0xe9,0x54,0xe9,0x34,0xe9,0x74,0xe9,0x08,0xe9,0x75,0xd2,0xbb, |
3146 | | 0xa4,0x77,0x4b,0x67,0x4b,0xe7,0x48,0x5f,0x94,0xce,0xf5,0xca,0x93,0x8b,0x12,0x93, |
3147 | | 0x70,0x62,0xfd,0x9c,0xdd,0x9e,0x12,0xad,0xbe,0x31,0xd1,0x39,0xd2,0x9e,0xbc,0xf9, |
3148 | | 0x9b,0x5e,0x7b,0xf1,0xda,0x87,0xd7,0x46,0xbd,0xfa,0x9f,0xae,0x63,0x13,0xd4,0x67, |
3149 | | 0x26,0xaa,0xdf,0xac,0x2c,0x7f,0xcf,0x9e,0x6c,0xd9,0x53,0x2c,0x7b,0xaa,0x65,0x4f, |
3150 | | 0xb3,0xec,0x35,0x2c,0x7b,0x4d,0xcb,0x9e,0x6e,0xd9,0xbd,0x7c,0xd8,0xee,0x44,0x9f, |
3151 | | 0x3b,0xc9,0xe7,0x4e,0xf6,0xb9,0x53,0x7c,0xee,0x54,0x9f,0x3b,0xcd,0xe7,0xae,0xe1, |
3152 | | 0x73,0xd7,0xf4,0xb9,0xd3,0x7d,0xf9,0xf7,0xd2,0x97,0xa8,0x7b,0x65,0x92,0x34,0x59, |
3153 | | 0x9a,0x22,0x4d,0x95,0xa6,0x49,0x6b,0x48,0x6b,0x4a,0xd3,0xa5,0x5e,0x9e,0xe3,0xad, |
3154 | | 0xfc,0xc6,0x5b,0x79,0x8d,0xb7,0xf2,0x19,0x6f,0xe5,0x31,0xde,0xca,0x5f,0xbc,0x95, |
3155 | | 0xb7,0x78,0x2b,0x5f,0xf1,0x56,0x9e,0xe2,0xad,0xfc,0xc4,0x5b,0x79,0x89,0x57,0xde, |
3156 | | 0xba,0x5a,0xf9,0xec,0x66,0xd9,0xbb,0x5b,0xf6,0xcb,0x2d,0x7b,0x0f,0xcb,0xde,0xd3, |
3157 | | 0xb2,0xf7,0xb2,0xec,0x57,0x58,0xf6,0xde,0x96,0xfd,0x4a,0xcb,0xde,0xc7,0xb2,0xf7, |
3158 | | 0xb5,0xec,0xfd,0x2c,0x7b,0x7f,0xcb,0x3e,0xc0,0xb2,0x67,0x5b,0xf6,0x81,0x96,0x7d, |
3159 | | 0x90,0x65,0x1f,0x6c,0xd9,0x87,0x58,0xf6,0xab,0x2c,0xfb,0x50,0xcb,0x3e,0xcc,0xb2, |
3160 | | 0x0f,0xb7,0xec,0x57,0x5b,0xf6,0x6b,0x64,0x6f,0xe0,0x1c,0xb9,0x9f,0x36,0xb2,0xee, |
3161 | | 0xa7,0x27,0x32,0x16,0x6c,0xdf,0xcf,0xdb,0x5a,0xe3,0xc1,0xed,0x35,0x26,0x6c,0xee, |
3162 | | 0x13,0x1d,0x75,0x1f,0xef,0xaa,0x6b,0xd2,0xdd,0xba,0xd7,0xf6,0x54,0x59,0x5f,0x61, |
3163 | | 0xdd,0x77,0xfd,0xcf,0x30,0x03,0x54,0x46,0x03,0x55,0x26,0x83,0xad,0xf1,0xe1,0xa1, |
3164 | | 0xca,0xeb,0x70,0xe5,0xed,0x1a,0xd5,0x07,0x7f,0x1f,0x5d,0xcb,0x71,0xa9,0x9b,0x07, |
3165 | | 0x1f,0x57,0x71,0xfb,0xab,0x2b,0x95,0xf6,0xae,0x71,0x8e,0xb3,0x86,0x84,0x3c,0xf6, |
3166 | | 0x98,0x9b,0xd9,0xca,0x90,0x06,0xf5,0xa1,0x23,0x8c,0x85,0xdb,0x61,0x32,0xbc,0x6c, |
3167 | | 0xfc,0x29,0x84,0x1e,0xd0,0x07,0x46,0xc3,0x7d,0x30,0x1d,0xb6,0xc0,0xb7,0x2a,0xa0, |
3168 | | 0x87,0xe0,0x20,0x94,0xa2,0xa0,0xce,0x80,0x9a,0xd0,0x00,0x2e,0x81,0xde,0x30,0x1a, |
3169 | | 0x5e,0x82,0x95,0xb0,0x0d,0x36,0x90,0x90,0xb2,0x14,0xe2,0x6e,0x0a,0x31,0x48,0x21, |
3170 | | 0xe6,0x87,0x52,0x50,0x09,0x06,0x43,0xeb,0x4e,0x8e,0x33,0x12,0x7e,0x80,0x22,0x97, |
3171 | | 0x38,0x4e,0x05,0xa8,0x09,0xfd,0x61,0x20,0x6c,0xba,0xd4,0x71,0x3e,0x83,0xfd,0xf0, |
3172 | | 0x33,0x0c,0xba,0x8c,0xf2,0x81,0x1b,0xe0,0x1b,0xf8,0x19,0x0a,0x74,0xe6,0xb7,0x03, |
3173 | | 0xb4,0x86,0xae,0x30,0x18,0x5e,0x83,0x7c,0x5c,0xa8,0x34,0x68,0x01,0xd5,0xb9,0x50, |
3174 | | 0x29,0x70,0x33,0xdc,0x0f,0x4f,0xc2,0x02,0xd8,0x02,0x9f,0xc1,0x3e,0x2e,0x62,0x3e, |
3175 | | 0x2e,0x62,0x65,0x28,0x47,0x99,0x75,0x83,0xab,0x61,0x0e,0xac,0x86,0xf7,0x60,0x13, |
3176 | | 0x14,0xe1,0xa2,0x96,0x84,0x14,0xe8,0xc3,0x05,0xad,0xc2,0xc5,0x4c,0x83,0xda,0x50, |
3177 | | 0x1f,0x9a,0x40,0x47,0xe8,0x04,0xcf,0xc1,0x8d,0x5c,0xe8,0x5b,0x20,0x87,0x8b,0xbd, |
3178 | | 0x03,0x4e,0xe3,0x82,0x97,0x85,0xca,0x90,0x00,0xb7,0xc1,0xdd,0x30,0x94,0x4a,0x70, |
3179 | | 0x1d,0xbc,0x00,0x8b,0xe1,0x2b,0xd8,0x44,0xa5,0xd8,0x0a,0x07,0xa0,0x16,0x15,0x63, |
3180 | | 0x3e,0x2c,0x82,0x21,0x54,0x90,0xd5,0x70,0x10,0x06,0x8f,0xa0,0xec,0x20,0xed,0x06, |
3181 | | 0xea,0x30,0xdc,0x0a,0x0b,0x21,0x30,0xd2,0x71,0x0a,0x42,0x71,0x48,0x86,0x1b,0xe0, |
3182 | | 0x16,0xd8,0x36,0xca,0x71,0x76,0xc1,0x01,0x38,0x0c,0x05,0x47,0x3b,0x4e,0x69,0x28, |
3183 | | 0x0b,0xfd,0x61,0x10,0x0c,0x87,0x96,0x37,0x91,0x3f,0xc8,0x18,0x47,0x7b,0x81,0xee, |
3184 | | 0x70,0xfd,0x2d,0xa4,0x17,0xd6,0x81,0x73,0x2b,0xfd,0xda,0xed,0xb4,0x31,0x68,0x07, |
3185 | | 0xc3,0xe1,0x11,0xb8,0xfc,0x0e,0xea,0x39,0xcc,0x81,0xe9,0x77,0x3a,0xce,0x2a,0x78, |
3186 | | 0x68,0x3c,0xcf,0xdb,0x30,0x17,0xee,0x9a,0x40,0x5b,0xbc,0xcb,0x71,0x96,0xc3,0x5b, |
3187 | | 0xf0,0x2e,0x0c,0x9b,0x48,0x1d,0x80,0x33,0xef,0xa3,0xee,0xc0,0x02,0xd8,0x09,0x6d, |
3188 | | 0xee,0x77,0x9c,0xcb,0xa0,0x1b,0xf4,0x86,0xd5,0xb0,0x07,0x0e,0x40,0xe0,0x01,0xee, |
3189 | | 0xf7,0xb0,0x09,0x36,0xc3,0x7d,0x93,0xf8,0x2d,0x0a,0xcf,0xc1,0xd4,0x07,0x1d,0x67, |
3190 | | 0x23,0x6c,0x86,0x73,0x1e,0xe2,0xda,0x43,0x12,0xd4,0x81,0x8b,0xe1,0xb3,0x87,0x69, |
3191 | | 0x77,0x8f,0x52,0x26,0xf0,0x14,0xbc,0x02,0xaf,0xc1,0x1a,0x78,0x17,0x0e,0xc2,0x4f, |
3192 | | 0x50,0x98,0x76,0x53,0x02,0xca,0x41,0x6d,0x68,0x0e,0x17,0xc0,0x1d,0xf0,0x30,0x4c, |
3193 | | 0x7e,0xcc,0xfd,0xed,0x54,0x3c,0xc1,0x6d,0x03,0x8d,0x20,0x0b,0x5a,0xe0,0x9e,0x04, |
3194 | | 0x2d,0xa5,0xad,0xa4,0x6d,0xa4,0x6d,0xa5,0xed,0xa4,0x1d,0xa4,0x1d,0xa5,0x9d,0xa4, |
3195 | | 0x97,0x4a,0x3b,0x4b,0xbb,0x4a,0x2f,0x97,0xf6,0x94,0x5e,0x21,0x1d,0x60,0xe9,0x83, |
3196 | | 0x30,0x48,0xee,0x41,0x72,0x5f,0x25,0xf7,0x55,0x72,0x0f,0x97,0x7b,0xb8,0xdc,0xd7, |
3197 | | 0xca,0x7d,0xad,0xdc,0x8d,0xe5,0x36,0x79,0xf4,0xd4,0xf8,0x3f,0x22,0xff,0x71,0x70, |
3198 | | 0x2b,0x4c,0x97,0xfb,0x79,0xe9,0x0c,0xe9,0x2c,0xe9,0x1c,0xe9,0x5c,0xe9,0x3c,0xe9, |
3199 | | 0x02,0xe9,0x2b,0xd2,0x85,0xd2,0xc5,0xd2,0xa5,0xd2,0xd7,0xa5,0xcb,0xa5,0x2b,0xa5, |
3200 | | 0xef,0x58,0x6a,0xd2,0xb5,0x4e,0xee,0x75,0x72,0xbf,0x2f,0xf7,0xfb,0x72,0x6f,0x94, |
3201 | | 0x7b,0xa3,0xdc,0x9b,0xe4,0xde,0x24,0xf7,0xd3,0x72,0xef,0x95,0xee,0x93,0xee,0x97, |
3202 | | 0x7e,0x2d,0xfd,0xc9,0xca,0x97,0x49,0x8b,0x53,0x8c,0xfa,0x08,0xcf,0x42,0x10,0x9e, |
3203 | | 0x83,0xe7,0x21,0x02,0x22,0x21,0x04,0x33,0x61,0x16,0xcc,0x86,0x39,0xf0,0x22,0xcc, |
3204 | | 0x85,0x33,0x20,0x0a,0xa2,0x21,0x1f,0x94,0x87,0x18,0xc8,0x0f,0x05,0xa0,0x20,0x14, |
3205 | | 0x82,0xc2,0x50,0x04,0x8a,0x42,0x31,0x28,0x0e,0x5d,0xa1,0x1b,0x74,0x87,0xcb,0xa1, |
3206 | | 0x07,0xf4,0x84,0x5e,0x70,0x05,0xf4,0x86,0x2b,0xa1,0x0f,0xf4,0x85,0x7e,0xd0,0x1f, |
3207 | | 0x06,0x40,0x36,0x0c,0x84,0x41,0x30,0x18,0x86,0xc0,0x55,0xd0,0x05,0x4a,0x42,0x29, |
3208 | | 0x58,0x01,0x2b,0xe1,0x2d,0x78,0x1b,0xd6,0xc3,0x06,0xf8,0x10,0xce,0x84,0x8f,0x61, |
3209 | | 0x33,0x9c,0x05,0x65,0xa0,0x1c,0x54,0x80,0x58,0xa8,0x04,0xe7,0x42,0x55,0xa8,0x06, |
3210 | | 0x71,0x10,0x0f,0xd5,0x21,0x09,0xd2,0x20,0x03,0x9a,0xc0,0x79,0xb0,0x1f,0xbe,0x86, |
3211 | | 0x0e,0x70,0x11,0x74,0x84,0x1b,0x61,0x2c,0x8c,0x83,0xbb,0xe0,0x6e,0xb8,0x17,0x1e, |
3212 | | 0x85,0x29,0xc5,0xdc,0x7b,0x9a,0xb9,0x7f,0xc5,0xc0,0x26,0xee,0x33,0xf9,0xd1,0x38, |
3213 | | 0x28,0x00,0x49,0x57,0xb9,0xf7,0xb8,0xd3,0x21,0x00,0xe7,0x72,0xaf,0x49,0xe8,0xe0, |
3214 | | 0xde,0xe7,0xcc,0x73,0x83,0xb9,0x66,0xde,0x33,0x44,0xd0,0xb2,0x47,0x58,0xf6,0x90, |
3215 | | 0x65,0x8f,0xb2,0xec,0xd1,0x96,0x3d,0xc6,0xb2,0x17,0xb0,0xec,0x05,0x2d,0x7b,0x61, |
3216 | | 0xcb,0x5e,0xc4,0xb2,0x17,0xb5,0xec,0xc5,0x2c,0x7b,0x71,0xcb,0xee,0xe8,0x3a,0xdb, |
3217 | | 0x69,0xed,0xea,0x4b,0x6f,0x57,0x5f,0x9a,0xbb,0xfa,0xd2,0xdd,0xd5,0x97,0xf6,0xae, |
3218 | | 0xbe,0xf4,0x77,0xf5,0xe5,0xa1,0xab,0x2f,0x1f,0x5d,0x7d,0x79,0xe9,0xea,0xcb,0x4f, |
3219 | | 0x57,0x5f,0x9e,0xba,0xfa,0xf2,0xd5,0xd5,0x97,0x37,0x7f,0xfc,0xfd,0x7d,0xe7,0xef, |
3220 | | 0xad,0x7a,0x6f,0xea,0xf3,0xf4,0x63,0xec,0x2b,0xee,0x3b,0xc6,0xd4,0x03,0xcf,0x7e, |
3221 | | 0xbb,0x65,0x8f,0xb1,0xec,0xa6,0x7e,0x78,0xf6,0x7b,0x2d,0xff,0x7e,0x6d,0xac,0xb2, |
3222 | | 0xb4,0xfc,0xfb,0x58,0xfe,0x97,0x5a,0xfe,0xa6,0x9f,0xf7,0xec,0xe6,0x79,0xe1,0xd7, |
3223 | | 0xf0,0xd9,0xd6,0x6f,0xb0,0xbe,0x47,0xec,0x95,0xad,0x30,0xe6,0x5e,0xe7,0xd9,0xcd, |
3224 | | 0x33,0x91,0x67,0x37,0xcf,0x1f,0x9e,0xbd,0xca,0x15,0x56,0xfa,0xad,0x63,0xeb,0x5d, |
3225 | | 0x7d,0xc4,0x5e,0xe8,0x42,0xeb,0x59,0x78,0xd0,0x11,0xfb,0x94,0xdb,0xad,0x34,0x5b, |
3226 | | 0xe1,0x5f,0xbc,0xe0,0x88,0x7d,0x9b,0x95,0x97,0x11,0x56,0x3c,0x3d,0x3b,0x59,0x61, |
3227 | | 0x86,0x1e,0xb1,0x07,0x5a,0x1d,0xb1,0xaf,0xb0,0xe2,0xbf,0xd0,0x2a,0x87,0x7e,0xd6, |
3228 | | 0xb9,0x8a,0x59,0xe1,0xcd,0x73,0x86,0x67,0x3f,0x20,0x7b,0x2b,0x1e,0xac,0x47,0x5c, |
3229 | | 0xe6,0x3e,0x87,0x8d,0xbf,0xd6,0x7d,0xf6,0xf6,0xde,0x99,0x25,0x59,0xbf,0xb5,0x92, |
3230 | | 0xac,0xdf,0xda,0x49,0xfa,0x9d,0x95,0xe4,0x1c,0x79,0x0f,0x95,0x26,0xad,0x21,0xad, |
3231 | | 0x29,0x4d,0xd7,0x31,0x09,0xd6,0xef,0xed,0x64,0x2b,0xae,0x64,0xeb,0xf7,0x7b,0xb2, |
3232 | | 0xe2,0x73,0xd4,0x6f,0x47,0xa8,0xaf,0xf6,0xfa,0xe3,0x18,0xab,0x0f,0x3e,0x56,0xff, |
3233 | | 0xeb,0xb5,0x4d,0xaf,0x4d,0x7a,0x6d,0xd1,0x6b,0x83,0x5e,0xdb,0xf3,0xda,0x9c,0xd7, |
3234 | | 0xd6,0xbc,0x36,0xe6,0xb5,0x2d,0xaf,0x4d,0x79,0x6d,0xc9,0x6b,0x43,0x5e,0xdb,0x29, |
3235 | | 0xee,0x0b,0x37,0x4f,0xe7,0xf6,0xda,0x49,0x7f,0xc5,0x39,0x44,0xda,0xff,0x18,0x7d, |
3236 | | 0xa3,0xa9,0xf3,0xa6,0xae,0x9b,0x3a,0x6e,0xea,0xb6,0xa9,0xd3,0xa6,0x2e,0x9b,0x3a, |
3237 | | 0x6c,0xea,0xae,0xa9,0xb3,0xa6,0xae,0x9a,0x3a,0x6a,0xea,0xa6,0xa9,0x93,0xa6,0x2e, |
3238 | | 0x9a,0x3a,0x68,0xea,0x9e,0xa9,0x73,0xa6,0xae,0x99,0x3a,0x66,0xea,0x96,0xa9,0x53, |
3239 | | 0x1b,0xd1,0x1a,0x57,0xb9,0xcf,0xf1,0xbd,0x79,0xae,0xab,0x42,0xbc,0xd9,0xc4,0xb9, |
3240 | | 0x93,0xb8,0x42,0x0f,0xb8,0x75,0x61,0x12,0x7e,0xdd,0xfb,0x1c,0xdd,0x37,0xef,0xe0, |
3241 | | 0x39,0xfe,0x00,0xe1,0x6a,0xc3,0xfd,0x9d,0xdc,0xba,0x67,0xea,0x9c,0xa9,0x6b,0xa6, |
3242 | | 0x8e,0x99,0xba,0x75,0x66,0x47,0xf7,0xfa,0xa4,0xe9,0x3a,0xd5,0x90,0x7a,0xef,0x0f, |
3243 | | 0xd3,0x75,0x0d,0x13,0xac,0xf7,0x29,0x29,0x56,0x5d,0xf1,0xae,0x71,0x8a,0xf5,0xae, |
3244 | | 0x26,0x45,0xf1,0xa5,0x28,0xbe,0x14,0xc5,0x97,0xa2,0xf8,0x52,0xad,0x77,0x37,0xa6, |
3245 | | 0x5c,0x92,0xa4,0xc9,0xd2,0x14,0x69,0xaa,0x34,0x4d,0x5a,0x43,0x5a,0x53,0x9a,0x2e, |
3246 | | 0xf5,0xde,0x27,0x78,0xf6,0x44,0xcb,0xee,0xc5,0xdd,0x54,0xbf,0x1d,0x7b,0xe8,0x77, |
3247 | | 0xa1,0x67,0x6f,0x6f,0xbd,0x43,0x36,0xbf,0x67,0x1f,0x27,0xa2,0x27,0xf5,0x8c,0x32, |
3248 | | 0x15,0x9e,0xd5,0x73,0xd7,0xf3,0x7a,0xde,0x9a,0xa5,0xe7,0x91,0xb9,0x7a,0xbe,0x5a, |
3249 | | 0xa0,0xe7,0xaa,0x85,0x7a,0x9e,0x5a,0xaa,0xe7,0xa8,0xe5,0x7a,0x66,0x59,0x05,0xab, |
3250 | | 0xe1,0x2d,0x58,0x03,0x6f,0xeb,0x39,0x6a,0x9d,0x9e,0x97,0x36,0xea,0xb9,0xe8,0x13, |
3251 | | 0xd8,0x0c,0x5b,0xe0,0x53,0xd8,0x0a,0xdb,0x61,0x07,0xec,0x84,0x2f,0x60,0x17,0xec, |
3252 | | 0x86,0x2f,0x61,0x8f,0x9e,0x9f,0xf6,0xe9,0xb9,0xc9,0x3c,0x33,0x6d,0x37,0x75,0xf1, |
3253 | | 0x42,0x37,0x0f,0xde,0xb3,0xda,0x61,0xa5,0xe3,0x71,0x1d,0x6b,0xce,0x39,0x45,0xee, |
3254 | | 0x03,0xd6,0x33,0xda,0xe3,0xe2,0xb0,0xc2,0x3d,0xa9,0x74,0x1f,0xb0,0x9e,0x33,0x9f, |
3255 | | 0x94,0x7b,0xa9,0xca,0x67,0x9a,0xdc,0x53,0x55,0x0e,0x33,0xac,0xf3,0x4d,0x92,0xff, |
3256 | | 0x61,0x95,0xdf,0x61,0x95,0xe5,0x01,0x85,0x7d,0x56,0x7e,0x5b,0xb4,0xff,0x49,0xe5, |
3257 | | 0x6f,0xba,0xf2,0xfa,0x9a,0xe2,0x99,0xae,0xbc,0xee,0xb2,0xe2,0x9a,0x24,0xbf,0x03, |
3258 | | 0x96,0xfb,0x80,0xca,0xd0,0x7b,0x36,0xf6,0x3f,0x2b,0xaf,0xd6,0xf1,0xc6,0xfd,0x99, |
3259 | | 0x15,0x9f,0xb7,0x7f,0xb7,0xf5,0x3c,0xec,0xf9,0xef,0xb1,0xd4,0x2b,0x83,0x2f,0x94, |
3260 | | 0x66,0xcf,0xff,0x53,0x2b,0xcf,0xbb,0x2d,0xff,0xbd,0x56,0x1e,0xfc,0xc7,0xfa,0xdd, |
3261 | | 0x2b,0xad,0x72,0xde,0x6d,0x3d,0xa7,0x3f,0x69,0x9d,0x7b,0x8f,0xce,0xb3,0x46,0x75, |
3262 | | 0xf0,0xb0,0xca,0x71,0x8e,0x8e,0x59,0x25,0xfb,0x61,0xeb,0x39,0x7b,0xae,0xe2,0xf0, |
3263 | | 0xe2,0x9d,0x6b,0x5d,0x3f,0xaf,0xec,0xe7,0xa9,0x2c,0xec,0xeb,0xfc,0x8a,0x15,0xce, |
3264 | | 0xb3,0xaf,0xf4,0x95,0xcf,0x02,0xeb,0x77,0xc2,0x3c,0xeb,0x9a,0xef,0xb6,0xf2,0xb3, |
3265 | | 0x4a,0xf5,0xfd,0x6d,0xab,0x2c,0xde,0x51,0x9a,0x5e,0xf7,0xd5,0x51,0xfb,0x3c,0xb6, |
3266 | | 0xff,0xeb,0xd6,0xef,0x8f,0xc3,0xaa,0xfb,0xbb,0xad,0xdf,0x1e,0x8f,0x2b,0x2d,0x2b, |
3267 | | 0x7d,0xfe,0x33,0x7c,0xee,0x39,0xd6,0xef,0x16,0xbb,0x1d,0xd8,0x75,0xcd,0xfb,0x0d, |
3268 | | 0xf3,0x84,0x75,0x4d,0xbd,0xdf,0x36,0xaf,0x29,0x9f,0xcf,0x58,0xc7,0x7f,0x61,0xb5, |
3269 | | 0xa1,0x19,0x2a,0x1f,0xaf,0xfd,0x78,0xed,0x6a,0xa1,0x65,0x5f,0xad,0x34,0x6c,0x54, |
3270 | | 0x98,0xd7,0xad,0x7d,0x5e,0xbb,0xd8,0x68,0xe5,0x7d,0x9e,0xf5,0x3b,0xca,0xcb,0xff, |
3271 | | 0x62,0xeb,0xfa,0x3e,0x69,0x95,0xd9,0x26,0x5f,0xf9,0x6f,0xd2,0xbe,0x4d,0x56,0xfc, |
3272 | | 0x2b,0xad,0xdf,0x61,0x5e,0x3a,0x3d,0xbb,0xd7,0x7e,0x9e,0xb4,0xea,0x9b,0xe7,0xde, |
3273 | | 0x2d,0xfb,0x6b,0xba,0x16,0x9f,0xc8,0x6f,0x86,0xec,0x07,0x94,0xd6,0xcf,0x65,0xdf, |
3274 | | 0x6c,0xc5,0xe1,0xb9,0x77,0x59,0x6a,0x5f,0xcf,0xdd,0x6a,0x43,0x5e,0x7b,0xb5,0xed, |
3275 | | 0x5e,0x3d,0xf2,0xb7,0xb1,0xed,0xbe,0x7e,0x66,0xbb,0x15,0xd7,0x0e,0xab,0x6f,0xdb, |
3276 | | 0x65,0x5d,0xdb,0xdd,0x72,0x7f,0xe1,0xab,0x17,0xde,0x71,0x87,0xad,0x6b,0xed,0xf5, |
3277 | | 0xb1,0x5b,0xa4,0x5e,0xd9,0xcd,0xb2,0xfa,0x1a,0xbb,0x7d,0x9b,0x7b,0xcf,0x82,0x6c, |
3278 | | 0xf7,0x7e,0x63,0x34,0x49,0x9a,0x2c,0x4d,0x91,0xa6,0x4a,0xd3,0xa4,0x35,0xa4,0x35, |
3279 | | 0xa5,0xe9,0x56,0x3c,0x76,0x9c,0x89,0x96,0x3d,0xc9,0xb2,0x27,0x5b,0xf6,0x14,0xcb, |
3280 | | 0x9e,0x6a,0xd9,0xd3,0x2c,0x7b,0x0d,0xcb,0x5e,0xd3,0xb2,0xa7,0x5b,0xe9,0x4e,0xb0, |
3281 | | 0xec,0x76,0x7e,0x92,0x2c,0x7b,0xb2,0x65,0xf7,0xce,0x7b,0x85,0xde,0xef,0x76,0xd5, |
3282 | | 0xfb,0xda,0xae,0x7a,0x57,0xdc,0x4e,0xef,0x71,0xbb,0xea,0xbe,0x3b,0x40,0xf7,0xdc, |
3283 | | 0x6c,0xdf,0x78,0x9c,0xa7,0x49,0x96,0x3d,0x59,0xef,0x93,0x4d,0x1c,0x83,0x79,0x96, |
3284 | | 0x2d,0x4a,0x44,0x71,0x3d,0xdd,0x7b,0x9c,0x79,0xaf,0x69,0x9e,0x77,0x0a,0xe3,0x7e, |
3285 | | 0xa5,0xaf,0xfb,0x0c,0x55,0xa4,0x33,0xbf,0xf3,0x5b,0xb9,0xcf,0x51,0xd9,0x3a,0x7f, |
3286 | | 0x7f,0xe9,0xab,0x9a,0xe7,0xdc,0x4f,0xee,0x3e,0xd2,0x16,0x7a,0x9f,0xdd,0x52,0xda, |
3287 | | 0x44,0xea,0x8d,0x77,0xf7,0x55,0x58,0xdb,0x9d,0xad,0x77,0xde,0xfd,0xa5,0xaf,0x46, |
3288 | | 0x1c,0xd1,0x5e,0x3a,0x87,0xf7,0xdd,0x92,0x37,0xee,0x7d,0x8d,0xdc,0x9e,0xbd,0xa5, |
3289 | | 0x65,0x6f,0x62,0xd9,0x2f,0xb4,0xec,0xaf,0x46,0x1c,0x79,0xb7,0xdd,0x57,0xe5,0xd2, |
3290 | | 0xd7,0x7a,0xe7,0xdd,0xd3,0x7a,0xef,0xdd,0x4f,0xe1,0xfb,0x39,0x47,0xe8,0x2e,0xed, |
3291 | | 0xe3,0x1c,0xed,0x9f,0x64,0xed,0x4b,0xb2,0xb4,0x8f,0xcf,0xcf,0xbb,0x06,0xdd,0x2d, |
3292 | | 0xbb,0xa7,0x7d,0x7c,0x7e,0xa5,0x2a,0xb8,0xef,0xda,0x6d,0x7b,0x92,0x55,0x27,0xfa, |
3293 | | 0x58,0xf6,0x96,0x96,0xbd,0x89,0x65,0x1f,0x64,0xd5,0x1f,0xdb,0xee,0xc5,0x77,0x2c, |
3294 | | 0xbf,0x24,0x6b,0xde,0x42,0x7f,0xe9,0xab,0x11,0x47,0xd2,0x32,0x58,0xfb,0xdb,0x6b, |
3295 | | 0x7f,0x7b,0xed,0x6f,0xaf,0xfd,0xed,0x95,0xb6,0xf6,0x4a,0x97,0x57,0x37,0x3b,0x28, |
3296 | | 0x7c,0x07,0x85,0xef,0xa0,0xf0,0x1d,0x14,0xbe,0x83,0xc2,0x7b,0xee,0x69,0xfa,0xbe, |
3297 | | 0x66,0x9a,0xe6,0xd0,0xc7,0x2b,0x7c,0xbc,0xea,0xd3,0x40,0x95,0x63,0x77,0xab,0xde, |
3298 | | 0x37,0x54,0x3e,0xbc,0x7a,0xd2,0x50,0xed,0x23,0x5e,0xfb,0xbd,0xfa,0x78,0xb5,0xc6, |
3299 | | 0x3c,0xba,0xaa,0x6e,0xb4,0xd6,0xf8,0x47,0x7f,0xd5,0x5f,0x8f,0x96,0x4a,0xcb,0x10, |
3300 | | 0xe7,0xe8,0x7a,0xd3,0x5f,0x3a,0x40,0xe7,0xe9,0xab,0x31,0x90,0x7e,0x6a,0x9b,0xfd, |
3301 | | 0xac,0x31,0xf2,0x7e,0x0a,0xd7,0x57,0xe7,0x69,0xaa,0xf2,0xb0,0xf3,0xd3,0x5a,0x78, |
3302 | | 0xd7,0xd1,0x9b,0x2b,0x32,0x48,0xe3,0x3a,0x43,0x55,0x2e,0xdd,0x54,0x9e,0x26,0x8f, |
3303 | | 0x5e,0xbb,0xf3,0xec,0x89,0xfa,0x3d,0x9e,0x24,0x4d,0x96,0xa6,0x48,0x53,0xa5,0x69, |
3304 | | 0xd2,0x1a,0xd2,0x9a,0xd2,0x74,0xa9,0xd7,0x57,0x7a,0xf6,0x44,0xcb,0x9e,0x64,0xd9, |
3305 | | 0x93,0x2d,0x7b,0x8a,0x65,0x4f,0xb5,0xec,0x69,0x96,0xbd,0x86,0x65,0xaf,0x69,0xd9, |
3306 | | 0xd3,0xad,0x74,0x27,0x58,0x76,0x3b,0x3f,0x49,0x96,0x3d,0xd9,0xb2,0xa7,0x58,0xf6, |
3307 | | 0x54,0xcb,0x9e,0x66,0xd9,0x6b,0x58,0xf6,0x9a,0x96,0x3d,0xdd,0x2a,0xa7,0x04,0xcb, |
3308 | | 0xee,0x9d,0xb7,0x97,0xd5,0x3f,0x35,0x8f,0xe4,0x37,0x0d,0x0c,0x78,0xc6,0xad,0x53, |
3309 | | 0x8d,0x35,0xee,0x56,0x31,0xc0,0xf5,0x81,0x4a,0xf8,0xd7,0x98,0x4e,0x5d,0x09,0x72, |
3310 | | 0xed,0xd0,0x3b,0xd0,0xa6,0xfc,0x1e,0xfc,0xa6,0xa7,0x3b,0x8e,0xb0,0x12,0xfb,0xbb, |
3311 | | 0x54,0x9a,0x24,0x7e,0x4f,0x7c,0xd6,0xd6,0x7d,0x07,0x6f,0x68,0xd3,0xd1,0xfd,0xdd, |
3312 | | 0x7a,0x33,0x1d,0x72,0x53,0xec,0xdf,0x71,0xc2,0xde,0x5c,0xec,0xb1,0x37,0x38,0x4e, |
3313 | | 0xfd,0x9b,0x1c,0xe7,0xe5,0x9b,0x1d,0xe7,0x87,0x71,0x8e,0x33,0x9e,0xdf,0xa8,0xc1, |
3314 | | 0x2b,0x1d,0xa7,0x34,0x17,0xfa,0x43,0x2a,0xcf,0x27,0x54,0x8e,0xba,0x37,0x3a,0xce, |
3315 | | 0x95,0x1c,0xbb,0x7f,0x92,0xe3,0x8c,0x26,0xde,0xab,0x88,0x37,0x92,0xca,0x5a,0x9a, |
3316 | | 0x4a,0x13,0xc7,0xb1,0x65,0x1e,0xa5,0x2e,0xf1,0x7b,0x75,0x37,0x95,0x6f,0xcd,0x58, |
3317 | | 0xea,0xff,0x2d,0x8e,0xf3,0x26,0x15,0x68,0xe3,0x28,0x7e,0x27,0x13,0xe7,0x2a,0xfa, |
3318 | | 0xff,0x53,0xc9,0xe4,0x95,0xc4,0x79,0x98,0x63,0xde,0xe6,0x1c,0x37,0xd1,0xd7,0xcf, |
3319 | | 0x23,0x63,0x9f,0x50,0x01,0x5f,0xa7,0xc1,0xac,0xe7,0x9c,0x45,0xd9,0xf7,0xf9,0x50, |
3320 | | 0x77,0x5c,0x26,0x8a,0x78,0x2f,0x81,0xbd,0x77,0x90,0x97,0xfb,0x29,0x8f,0x87,0x1c, |
3321 | | 0xe7,0xd0,0x23,0xdc,0x3f,0xa8,0xfc,0x37,0xd0,0xa8,0x26,0x5f,0xc7,0x39,0xc6,0x90, |
3322 | | 0x8e,0x7b,0xdc,0x31,0x8a,0x0f,0x6e,0xe5,0x19,0xe5,0x22,0xdc,0xdc,0x47,0xba,0x8c, |
3323 | | 0x70,0x9c,0xeb,0x89,0xa3,0x1b,0xf1,0xad,0x22,0xfc,0x32,0xca,0xe4,0xfb,0xfb,0x48, |
3324 | | 0x0f,0xfb,0xbb,0x5d,0xe2,0x38,0x25,0x38,0xd7,0x47,0xa4,0xa5,0x08,0xe9,0xad,0x4e, |
3325 | | 0x3c,0x35,0xae,0xa7,0x0d,0xb2,0x7f,0x1d,0x69,0xb9,0x8d,0xe3,0x72,0x48,0xd7,0x5b, |
3326 | | 0x70,0x26,0x1d,0xf9,0x22,0xf6,0xef,0xe7,0x3c,0x57,0xb1,0x7f,0xe4,0x6d,0x3c,0xff, |
3327 | | 0x74,0x73,0xcb,0xe7,0x67,0xce,0x97,0x4e,0x59,0x7c,0xce,0xef,0xf2,0xe2,0x5d,0x28, |
3328 | | 0x57,0xca,0x29,0x9b,0xdf,0xf9,0xa7,0x52,0x36,0x3f,0x72,0xce,0xc5,0xe4,0x6f,0x1a, |
3329 | | 0x69,0x29,0x44,0x98,0xb7,0xb8,0xb0,0xc3,0xb9,0xce,0x15,0x88,0xeb,0x35,0xf6,0x5f, |
3330 | | 0x46,0x3a,0x02,0xc3,0xb8,0x3f,0x52,0xae,0xcf,0x12,0xcf,0xcb,0x7d,0xdc,0xb1,0x9f, |
3331 | | 0x71,0x84,0xfb,0x99,0xf8,0x3f,0x1b,0x4d,0xfe,0xe8,0x68,0x7a,0x10,0xdf,0x0b,0x1c, |
3332 | | 0xdf,0x9b,0xb4,0xbc,0x09,0xa3,0xe8,0x48,0x3e,0x27,0x6f,0x03,0xd8,0xbf,0x8e,0xe3, |
3333 | | 0xde,0xe1,0x9a,0x7c,0x4b,0x9a,0x33,0x2f,0x74,0xdf,0x2f,0x7c,0x49,0x39,0xbf,0xc1, |
3334 | | 0x79,0x7e,0x26,0x5f,0x55,0x28,0xa3,0xe7,0x27,0x52,0xe6,0x0f,0x3a,0xce,0xfd,0x94, |
3335 | | 0xcf,0xdb,0x8f,0xba,0xe3,0x92,0xcb,0xa9,0x27,0xc3,0xcc,0xd8,0x1d,0xe7,0x1b,0x42, |
3336 | | 0xf8,0x09,0x1a,0xac,0x7d,0x90,0x6b,0x10,0xcb,0x71,0xcd,0xe8,0xec,0x6e,0xa1,0x13, |
3337 | | 0x5a,0xc5,0xf1,0xdf,0x90,0xde,0x01,0x94,0x47,0x45,0xc2,0x7e,0x45,0x5a,0x63,0xb9, |
3338 | | 0x6e,0xcd,0x29,0xef,0x53,0x89,0xe7,0x09,0x58,0xc8,0x79,0x57,0x52,0x47,0x96,0x8d, |
3339 | | 0x73,0xf3,0xf1,0x26,0xf1,0x7d,0x4b,0x9e,0xaf,0x25,0xed,0x2f,0x70,0x8e,0x7a,0xa4, |
3340 | | 0xf5,0xaa,0xc1,0xee,0x6f,0xdb,0x83,0xed,0xdd,0xb2,0x7a,0x99,0x7a,0x72,0x26,0xe5, |
3341 | | 0x35,0x1b,0xff,0xde,0x9c,0xe7,0x41,0xea,0x5f,0x63,0xce,0x91,0x72,0x37,0x75,0x92, |
3342 | | 0x32,0x6e,0xca,0xb5,0x3e,0xed,0x01,0xae,0x03,0xe5,0xf7,0x82,0x79,0x87,0x42,0x1e, |
3343 | | 0xe7,0xe3,0xff,0x29,0xc7,0xdc,0x44,0x3c,0x1f,0xd1,0x69,0x7d,0x45,0x3c,0xf5,0xb9, |
3344 | | 0x8e,0x93,0x7a,0xb8,0xd7,0xe2,0x6d,0xd2,0x9c,0x49,0xbd,0x39,0x4c,0x1a,0x47,0x4c, |
3345 | | 0x70,0xc7,0x9e,0xc6,0x91,0xcf,0x78,0x8e,0xbb,0x85,0x74,0x5e,0x4b,0xdd,0x3b,0x00, |
3346 | | 0x0d,0xb8,0xe6,0x0f,0xd3,0x36,0x62,0x38,0x6f,0x47,0xca,0xb6,0x0f,0xd7,0xa9,0x28, |
3347 | | 0x79,0xbc,0xec,0x01,0xf7,0xbd,0x4f,0x3c,0xe5,0x30,0x9c,0x63,0xaa,0x72,0x8e,0xd3, |
3348 | | 0x49,0xe7,0x2e,0xc2,0x57,0x21,0xef,0xb7,0x91,0xa7,0x46,0x94,0xd3,0xa9,0x57,0xb8, |
3349 | | 0xd7,0xf9,0x26,0xc2,0x9c,0x4b,0xbc,0x45,0xc8,0x7f,0x0f,0x53,0x9f,0x38,0xd7,0xf9, |
3350 | | 0xc4,0x3f,0x95,0xfd,0x9f,0x71,0x0d,0xa3,0x88,0x7f,0x2b,0xf1,0x5f,0x4d,0xde,0xde, |
3351 | | 0xa1,0x6c,0x3e,0x1d,0xe7,0x8e,0xe3,0x6d,0xe5,0xb8,0xfa,0x5c,0xff,0x97,0x49,0xc3, |
3352 | | 0x59,0x1c,0xbb,0x96,0x74,0x3f,0x40,0xd8,0x43,0xb4,0x99,0x27,0xd8,0xd7,0xe1,0x61, |
3353 | | 0xc7,0x79,0x8c,0xeb,0x74,0x3f,0x71,0xad,0xe6,0xdc,0x3b,0x47,0xb9,0x63,0x98,0xe5, |
3354 | | 0xae,0x75,0x9c,0xbb,0x29,0xcb,0x25,0xd4,0xe7,0x49,0x94,0xf7,0x45,0xd4,0xc3,0x25, |
3355 | | 0x66,0x9c,0x9a,0x7a,0x59,0x8b,0x74,0x44,0xc3,0xd3,0x94,0xfd,0x7a,0xd2,0xff,0x01, |
3356 | | 0xe1,0xc6,0x52,0x3e,0x65,0x38,0xfe,0x45,0xd2,0x55,0x7b,0xbc,0x3b,0x36,0xd9,0xf2, |
3357 | | 0x3e,0x77,0x5c,0x72,0x3d,0xe1,0x32,0xc8,0xeb,0x12,0xfa,0x81,0x8b,0xa9,0x87,0x43, |
3358 | | 0x08,0xf3,0x09,0xee,0x2a,0xe4,0x6b,0x15,0x65,0x58,0x87,0x32,0xbf,0x0c,0x7a,0xc0, |
3359 | | 0x78,0x68,0xcf,0xf5,0x58,0x34,0xc2,0x1d,0x2f,0x2d,0x4e,0x7b,0xfc,0x81,0xeb,0x5c, |
3360 | | 0x93,0x32,0xfe,0x09,0xf6,0x52,0x6e,0x87,0xa1,0x32,0xfd,0xc2,0x8b,0xb4,0xcd,0x4f, |
3361 | | 0xf0,0x9b,0xc7,0x79,0x5e,0xe0,0xda,0x7d,0x4e,0x19,0xb6,0x34,0xf5,0x96,0xb4,0x6d, |
3362 | | 0x87,0x36,0xe4,0xfb,0x11,0xce,0x19,0x45,0x3d,0xb8,0x02,0x32,0x38,0xf7,0x54,0xb8, |
3363 | | 0x5c,0xe3,0xd8,0xf7,0x72,0x7d,0xaf,0xa0,0x8c,0xef,0x84,0xaf,0xa1,0x15,0xd7,0x76, |
3364 | | 0x2b,0xdc,0x45,0xfa,0xc6,0x52,0xae,0xc3,0xc8,0xcf,0x19,0x94,0x5b,0x05,0xea,0x68, |
3365 | | 0x7f,0xca,0xad,0x2a,0x65,0x51,0x81,0xb2,0xbb,0x6b,0xb8,0xfb,0xcc,0xd8,0x0c,0x9a, |
3366 | | 0x42,0x6b,0x93,0xe6,0xab,0xdd,0xf7,0x6f,0x77,0xc0,0x9d,0x90,0x41,0x19,0x8e,0x82, |
3367 | | 0x25,0xd7,0xba,0x75,0x3a,0x86,0xf6,0xde,0x00,0x06,0x91,0xa7,0x10,0x75,0x6f,0x0f, |
3368 | | 0xe5,0x7c,0xf5,0x68,0x97,0x0e,0xd4,0xa1,0xa2,0x94,0xd3,0x7d,0x10,0xa0,0x9c,0xd3, |
3369 | | 0x61,0x3d,0xfd,0x47,0x3e,0xfa,0xa1,0x97,0xc6,0xbb,0x79,0xdf,0x46,0x1e,0x7f,0xa1, |
3370 | | 0x5c,0x6a,0x93,0xf7,0xab,0x48,0xf7,0x57,0x99,0x41,0xe7,0x34,0x8e,0xad,0xc8,0x35, |
3371 | | 0x99,0x4b,0x9e,0xaf,0x80,0x91,0x94,0x41,0x96,0x51,0x58,0x41,0xfe,0x0f,0x5d,0xe0, |
3372 | | 0xe6,0xbf,0x1d,0x4c,0x82,0xad,0x2a,0xff,0x39,0xd0,0x88,0xb6,0x7b,0x21,0x74,0xbb, |
3373 | | 0x98,0xb2,0xe4,0xda,0xad,0xe3,0x1a,0x7d,0x08,0xbd,0xa9,0x77,0xcf,0xc3,0x46,0xce, |
3374 | | 0x71,0x3e,0x65,0x92,0x4f,0xe5,0xd3,0x45,0x65,0x94,0xc2,0xf5,0x7e,0x9d,0xb6,0x76, |
3375 | | 0x26,0x6d,0xf7,0x02,0x68,0xdf,0xc3,0xbd,0x9e,0xa6,0xaf,0x2d,0x0d,0xed,0x7b,0xb9, |
3376 | | 0xe3,0xf3,0xa6,0x7f,0x31,0x75,0x7f,0x13,0xe5,0xb7,0x5a,0x65,0x58,0x26,0xdb,0x2d, |
3377 | | 0xc7,0x67,0xe8,0x87,0x52,0x29,0xcb,0x19,0x83,0xdc,0x3a,0x30,0x90,0x32,0x8d,0xa2, |
3378 | | 0xee,0xd6,0x86,0xb3,0xa8,0x0f,0x65,0x87,0xba,0xf5,0x62,0x13,0x7c,0x03,0xcd,0x09, |
3379 | | 0x9f,0x01,0x6f,0x51,0xee,0xb3,0x54,0xa6,0xd7,0x52,0x3f,0x3a,0x5d,0xe7,0x96,0x6d, |
3380 | | 0x3d,0x95,0xe9,0x05,0xd4,0xcd,0xbd,0x70,0x35,0xf7,0x95,0x06,0x94,0xe5,0x4d,0x2a, |
3381 | | 0xd3,0xc5,0xb7,0xba,0x75,0x68,0xf5,0xad,0x6e,0xf9,0x9a,0x7e,0x74,0xcf,0xad,0x6e, |
3382 | | 0x39,0xdf,0x7a,0x9b,0x5b,0xce,0x35,0x29,0xe7,0x41,0x94,0xf3,0x24,0xda,0xcc,0x50, |
3383 | | 0xfa,0x85,0x11,0xf7,0xb9,0x65,0x6e,0xea,0xe2,0xa6,0xfb,0xdd,0xb2,0x2f,0xf0,0x80, |
3384 | | 0x5b,0xfe,0xc5,0x1f,0x72,0xef,0x6f,0xcd,0x2b,0x07,0x9d,0x46,0xf0,0x7e,0x72,0xd0, |
3385 | | 0x79,0xa4,0x36,0x7d,0x48,0x06,0x71,0x42,0xb3,0x0b,0x82,0xce,0xda,0x4b,0x82,0xce, |
3386 | | 0xfa,0xeb,0x83,0x4e,0x43,0xc2,0xdd,0xf9,0x98,0xfb,0xec,0xed,0xd1,0x5b,0xda,0xf7, |
3387 | | 0x18,0x7e,0x9e,0xbf,0x37,0x0f,0xc5,0xd3,0x21,0x21,0xd2,0x15,0x72,0xb5,0x87,0xb4, |
3388 | | 0x0f,0x5c,0x6f,0xf9,0xf7,0x83,0x0f,0xe1,0x45,0xf8,0x1a,0xe6,0xc1,0xd6,0x90,0x3b, |
3389 | | 0x67,0xd5,0xcc,0x55,0x7d,0x0f,0x36,0x41,0x0e,0x7c,0x0c,0x3b,0x61,0x57,0xc8,0x9d, |
3390 | | 0x03,0xfc,0x05,0xba,0x34,0xe4,0xea,0x32,0xe9,0xab,0x96,0xdf,0xab,0xf2,0x5f,0xab, |
3391 | | 0x78,0x8d,0xce,0x97,0xbe,0xaa,0x39,0xb1,0xaf,0x6a,0x5e,0xec,0xab,0x3a,0xdf,0xab, |
3392 | | 0x3a,0xa7,0xd1,0xf7,0xa5,0x1f,0x48,0x37,0x4a,0x3f,0x94,0x7e,0x24,0xdd,0x24,0xcd, |
3393 | | 0x91,0x7e,0x22,0xdd,0x22,0xfd,0x54,0xba,0x4d,0xba,0x5d,0xba,0x43,0xfa,0xb9,0x74, |
3394 | | 0xa7,0xd4,0x4b,0xfb,0x2e,0x2b,0x1d,0x0b,0x94,0xde,0xc5,0x3a,0xdf,0x62,0xc5,0xb3, |
3395 | | 0x58,0xf9,0x31,0xe7,0x1e,0x18,0xe5,0x72,0xad,0x8f,0xeb,0x7d,0x8c,0xf4,0x71,0x8d, |
3396 | | 0x8f,0x1b,0x7c,0x5c,0xed,0xe3,0x49,0x1f,0x4f,0xfb,0xb8,0xd1,0xc7,0x18,0x1f,0x37, |
3397 | | 0xf9,0xb8,0xd9,0xc7,0x1d,0xe2,0x76,0x71,0xa7,0x18,0x27,0x1e,0x10,0x77,0x89,0x69, |
3398 | | 0x3e,0x66,0xf8,0x98,0xe3,0x63,0x96,0x8f,0x97,0xc5,0x2b,0x3e,0xbc,0xb5,0x6b,0xec, |
3399 | | 0x35,0x6c,0x6c,0x16,0xf9,0x58,0x67,0x61,0xaf,0x75,0xf3,0xbc,0x8f,0x15,0x62,0xb9, |
3400 | | 0x58,0x29,0xbc,0xb5,0x73,0x56,0x8b,0x37,0xc4,0x9b,0x62,0xad,0x8f,0x66,0xc2,0x5e, |
3401 | | 0x8b,0xe7,0x58,0xf6,0xf7,0xf3,0xb0,0x37,0xcd,0xc3,0xbe,0x22,0x0f,0xfb,0xf2,0x3c, |
3402 | | 0xec,0x2b,0xf3,0xb0,0xaf,0x3d,0x01,0x7b,0xb3,0xff,0x60,0x7f,0xcb,0x87,0xb7,0xaf, |
3403 | | 0x9a,0x65,0x8f,0xb3,0xec,0x59,0x79,0xc4,0x65,0xb4,0xb2,0x8e,0xab,0xac,0x63,0x8c, |
3404 | | 0xc6,0x4b,0xb3,0xa4,0xcd,0xa4,0x26,0x7c,0x15,0x85,0xaf,0xa2,0xf0,0x55,0x14,0xbe, |
3405 | | 0x8a,0xc2,0x57,0x51,0xf8,0x2a,0x0a,0x5f,0x55,0xe1,0xab,0x6a,0x7f,0x55,0xed,0xaf, |
3406 | | 0xaa,0xfd,0xd5,0x14,0x4f,0x35,0xed,0x8f,0xb3,0xfc,0xb2,0x14,0x77,0x35,0x69,0x9c, |
3407 | | 0xd4,0xf8,0x27,0xcb,0x3f,0x59,0xfe,0xc9,0xda,0x97,0xac,0xfd,0xa9,0xf2,0x4f,0x95, |
3408 | | 0x3b,0x4d,0xe1,0xd3,0xe4,0x9f,0xa6,0xf0,0x69,0xda,0x5f,0x43,0xfe,0x35,0xe4,0xae, |
3409 | | 0x29,0x4d,0xd7,0x71,0xe9,0x72,0xd7,0x92,0xbb,0x96,0xdc,0x0d,0xe4,0x6e,0xa0,0xe3, |
3410 | | 0x1b,0x28,0xde,0x06,0xd6,0xfe,0x66,0x52,0x93,0xdf,0x4c,0x85,0xcb,0xd4,0xfe,0x4c, |
3411 | | 0xed,0xcf,0xd4,0xfe,0x86,0xaa,0xa3,0x0d,0x15,0x6f,0x43,0x85,0x6f,0xa8,0x78,0x8d, |
3412 | | 0x36,0x92,0x66,0x49,0x9b,0x49,0x9b,0x6b,0x5f,0x35,0x69,0x9c,0x34,0x5e,0x9a,0x25, |
3413 | | 0x6d,0x26,0x6d,0x2e,0x3f,0xbb,0xec,0xb3,0xac,0x32,0xf6,0x68,0x66,0xd5,0xa1,0xc6, |
3414 | | 0x0a,0xdf,0x58,0xe1,0x1b,0x2b,0x7c,0x63,0x85,0x69,0xac,0xf0,0x8d,0x15,0xbe,0x89, |
3415 | | 0xc2,0x37,0xd1,0xfe,0x26,0xda,0xdf,0x44,0xfb,0x9b,0x5b,0xf5,0xd6,0xab,0xb3,0xf1, |
3416 | | 0x56,0xda,0x9a,0x5b,0x75,0xd6,0x90,0x00,0xd9,0x90,0x28,0x6d,0x26,0x35,0xf3,0xa6, |
3417 | | 0xce,0x43,0xdb,0xc8,0xde,0xd2,0xb2,0x9f,0x6f,0xd9,0x5b,0x59,0xf6,0xd6,0x96,0xbd, |
3418 | | 0x8d,0xe2,0xf1,0xda,0x46,0xa2,0x65,0x4f,0xca,0xa3,0x2d,0x35,0x3e,0x4e,0xbb,0x4a, |
3419 | | 0x94,0x26,0xf9,0xda,0x53,0xe3,0x3c,0xda,0x55,0xa2,0x34,0xc9,0xd7,0x9e,0x1a,0xe7, |
3420 | | 0xd1,0xae,0x12,0xa5,0x49,0xbe,0xf6,0xd5,0xf8,0x18,0xed,0xec,0x58,0xf5,0x30,0xaf, |
3421 | | 0x7a,0x77,0xbc,0xfa,0x95,0x57,0x3d,0xaa,0x64,0xd5,0x99,0xc6,0x4a,0x5f,0x63,0xa5, |
3422 | | 0xcf,0xae,0x1f,0x8d,0x8f,0x51,0x4f,0x9a,0x59,0xe5,0xef,0x95,0x7d,0x92,0xaf,0x1e, |
3423 | | 0x34,0x3e,0x46,0x7d,0x38,0x5e,0xdf,0x17,0x9f,0xc7,0xb5,0x6b,0x72,0x82,0x7d,0x5f, |
3424 | | 0x93,0x13,0xec,0xf3,0x9a,0x58,0xd7,0xe0,0x64,0xfa,0xb4,0x93,0xed,0xcb,0xe2,0x7f, |
3425 | | 0x43,0x9f,0xf6,0x47,0xf5,0x65,0xfe,0xbe,0xeb,0x44,0xfb,0xa8,0x13,0xe9,0x93,0x9a, |
3426 | | 0x9c,0x40,0x5f,0x74,0x22,0x7d,0x4f,0x93,0x3c,0xfa,0x9c,0xec,0x13,0xec,0x6b,0x9a, |
3427 | | 0x1c,0xa7,0xbe,0xf8,0xeb,0xc5,0xb1,0xae,0x7f,0x55,0xb9,0x93,0xad,0xeb,0x6b,0xdc, |
3428 | | 0x29,0x72,0xa7,0xc8,0x7d,0xac,0x72,0xca,0x3a,0x46,0x7e,0xfc,0xe9,0xcb,0x88,0x3a, |
3429 | | 0xd2,0xa7,0x19,0x7b,0x2b,0xcb,0xee,0xf5,0x69,0x35,0xd4,0x4e,0x6a,0xe8,0xb8,0x74, |
3430 | | 0xb9,0xd3,0xe5,0xae,0x25,0x77,0x2d,0xb9,0x93,0xe5,0x4e,0x96,0x3b,0x45,0xee,0x14, |
3431 | | 0xab,0xbc,0x9a,0x59,0xe5,0x56,0x4d,0xee,0x6a,0x56,0x39,0x36,0xb3,0xca,0x33,0x55, |
3432 | | 0xee,0x54,0xb9,0xd3,0xe4,0x4e,0xb3,0xe2,0xaf,0x26,0x8d,0x93,0xc6,0xfb,0xca,0x28, |
3433 | | 0x51,0xe9,0x49,0x54,0x3c,0x89,0x3a,0x3e,0xf1,0x5f,0x90,0xbf,0xe3,0x1d,0x6f,0xd7, |
3434 | | 0xa9,0x26,0xd6,0x73,0x4b,0x5e,0x7d,0x49,0x5e,0xf1,0xf9,0x9f,0x77,0x4c,0x1f,0xde, |
3435 | | 0xc2,0xd2,0x2a,0x56,0x9b,0xac,0x62,0xf5,0x65,0xc7,0xb2,0x67,0x59,0x7d,0x63,0x96, |
3436 | | 0xd5,0x3e,0xaa,0x59,0xf6,0x38,0xcb,0x1e,0x7f,0x8c,0x3e,0xd2,0xb3,0xc7,0x59,0x75, |
3437 | | 0x3e,0xce,0x7a,0x0e,0x49,0xb6,0xc2,0x26,0x5b,0xfd,0x6a,0xb2,0x75,0xcd,0x92,0xad, |
3438 | | 0x78,0x8e,0x65,0xaf,0x66,0xd9,0xb3,0x7c,0xf6,0x54,0xeb,0xfc,0x7e,0x7b,0x96,0x75, |
3439 | | 0xed,0xe2,0xf2,0xb0,0x57,0xb3,0xae,0x7f,0x96,0xef,0x9a,0xd9,0xf6,0x2c,0x9f,0x3d, |
3440 | | 0xcd,0xaa,0x83,0x69,0x56,0x19,0xda,0xf6,0x1a,0x56,0x5e,0x8e,0x65,0xb7,0xc3,0x34, |
3441 | | 0xb7,0xfa,0xfb,0x2c,0xab,0xcf,0xcf,0xcb,0xde,0xcc,0xba,0x0f,0x64,0x59,0xf6,0xe6, |
3442 | | 0x96,0xbd,0x99,0x75,0x4f,0xc8,0xf2,0xd9,0x33,0xad,0xf4,0x64,0x5a,0xf1,0x34,0xb2, |
3443 | | 0xca,0xa7,0x91,0xd5,0xbe,0x1a,0x59,0xf9,0xf5,0xee,0x0f,0xd5,0x8e,0x61,0x8f,0xb7, |
3444 | | 0x8e,0x8d,0xf7,0xf5,0x93,0x71,0x3e,0xfb,0xb1,0xea,0x51,0x96,0x65,0x6f,0xee,0xbb, |
3445 | | 0x3f,0xdb,0xf7,0x1b,0x7f,0x7d,0xb4,0xef,0x3b,0xde,0xbd,0xda,0xbe,0x47,0x35,0xf1, |
3446 | | 0xdd,0x97,0xe2,0x7c,0xf6,0x66,0xd6,0xfd,0x2a,0x2b,0x0f,0x7b,0x33,0xab,0xaf,0x6f, |
3447 | | 0x6e,0xd9,0x9b,0x59,0x69,0xcd,0xf2,0xd9,0x2b,0x5b,0x7d,0x50,0x15,0xab,0xbe,0x55, |
3448 | | 0xb1,0xe2,0xac,0xe2,0x0b,0x13,0x6f,0xf9,0x67,0x59,0xfe,0x59,0x56,0x1f,0x97,0xe5, |
3449 | | 0xfb,0x3d,0x66,0xfb,0x37,0xb3,0xfa,0x91,0x66,0x56,0xbb,0x68,0x6e,0xd5,0xff,0xe6, |
3450 | | 0x56,0x1d,0xb6,0x7f,0x87,0xd8,0xcf,0x8c,0xcd,0x7d,0xf7,0x5e,0xfb,0x7e,0xdc,0xfc, |
3451 | | 0x18,0x79,0x6d,0x6e,0xd5,0xa5,0xe6,0x56,0xd9,0x36,0xf7,0xd5,0x37,0xbb,0x8e,0xa5, |
3452 | | 0x5b,0xe1,0x1b,0x1e,0xe3,0x77,0x8b,0xfd,0x5c,0x61,0xa7,0x33,0xcb,0x0a,0x9f,0xe5, |
3453 | | 0xf3,0x6f,0xec,0x7b,0xa6,0x8b,0xb3,0xf2,0x51,0xcd,0x57,0xaf,0x9a,0x5b,0xcf,0x4b, |
3454 | | 0xcd,0xad,0x67,0xcb,0xe6,0xbe,0xf8,0xed,0xb6,0x99,0xea,0xeb,0x8b,0xe2,0x7d,0x69, |
3455 | | 0xf6,0xee,0x37,0x8d,0xf4,0xee,0x24,0xd3,0xb2,0x57,0x92,0xdd,0x7b,0x86,0xf2,0x9e, |
3456 | | 0xe1,0xbd,0xdf,0x1f,0x76,0x3b,0xa8,0x6e,0xc5,0xe3,0x95,0x93,0x77,0x0f,0x6a,0x6a, |
3457 | | 0xf9,0x37,0xb2,0x9e,0x35,0x9a,0x6a,0x7f,0x23,0x2b,0xad,0x8d,0xac,0x7a,0xe0,0xd9, |
3458 | | 0x73,0xff,0x8e,0x8a,0x2f,0x2d,0xc6,0xcf,0x1f,0x9f,0xf1,0xf3,0xc7,0xe9,0xb5,0x75, |
3459 | | 0xb3,0xcf,0xb3,0x57,0xb2,0xe2,0x49,0xd4,0x7b,0x0e,0xcf,0xaf,0x9a,0x99,0x33,0x9d, |
3460 | | 0xe0,0x38,0xc1,0x04,0xf7,0x5b,0xbd,0xda,0xd6,0xba,0x0b,0xa7,0xe0,0x77,0x6a,0xc2, |
3461 | | 0xb1,0xd7,0x79,0x28,0xc9,0x09,0x4a,0x40,0x67,0xc7,0xc5,0x5b,0x23,0xe1,0x5a,0xb8, |
3462 | | 0xce,0xec,0xe7,0xb8,0x52,0x50,0x14,0x8a,0x41,0x7e,0x28,0x90,0x70,0xe4,0xdb,0xe4, |
3463 | | 0x82,0x50,0x08,0x0a,0x43,0x11,0xf3,0x0d,0x91,0x99,0x03,0x6e,0xad,0x05,0x91,0x97, |
3464 | | 0x7a,0xe7,0x33,0x78,0x69,0x8f,0x57,0xba,0x6b,0x59,0x6b,0x47,0x98,0xf4,0xe5,0x95, |
3465 | | 0xa6,0x58,0x33,0x86,0x6b,0xe6,0xae,0x6b,0x9d,0x87,0x38,0xc7,0xfd,0x06,0xbc,0x9e, |
3466 | | 0xbe,0x4b,0xbc,0xc4,0xac,0x0b,0x69,0xd6,0x86,0x85,0x0c,0xa5,0xa9,0x85,0x9e,0x09, |
3467 | | 0x5b,0x58,0xbf,0x8f,0xbd,0xdf,0xc6,0xde,0xef,0x62,0xef,0x59,0xd2,0xfb,0x6d,0xec, |
3468 | | 0x3d,0x4f,0x7a,0xbf,0x8f,0xbd,0x67,0x4a,0xef,0x37,0x72,0x86,0xf5,0x9b,0xf9,0x02, |
3469 | | 0xb9,0x8d,0x96,0x8f,0x3a,0x7a,0x6d,0x6c,0x7b,0x8d,0x6c,0xff,0x5a,0xd9,0xfe,0x35, |
3470 | | 0xb3,0xfd,0x6b,0x67,0xe7,0xa5,0x95,0x44,0x65,0x1f,0xe7,0x8a,0x2a,0x3e,0xaa,0xfa, |
3471 | | 0xa8,0xe6,0x23,0xce,0x47,0xbc,0x8f,0xea,0x22,0x41,0x24,0x8a,0x24,0x91,0xec,0x23, |
3472 | | 0xc5,0x47,0xaa,0x8f,0x34,0x1f,0x35,0x7c,0xd4,0xf4,0x91,0xee,0xa3,0x96,0x8f,0x06, |
3473 | | 0x3e,0x32,0x7d,0x34,0xf4,0xd1,0xc8,0x47,0x96,0x8f,0xc6,0x3e,0x9a,0xf8,0x68,0x2a, |
3474 | | 0x9a,0x1d,0xe3,0x37,0x78,0x73,0xab,0xdd,0xb6,0xcd,0xc3,0x7e,0x61,0x1e,0xf6,0x76, |
3475 | | 0x79,0xd8,0x3d,0x35,0x6d,0xa3,0x82,0xe3,0xb6,0x01,0xaf,0x8e,0x9b,0xb6,0x50,0xc9, |
3476 | | 0x6a,0xc3,0x5e,0xbb,0xa8,0xa6,0xb6,0x11,0xaf,0xb5,0x48,0x4e,0x74,0xed,0x14,0xaf, |
3477 | | 0x1f,0xa9,0xa3,0xf6,0x54,0x4f,0xed,0x32,0xe3,0x4f,0xfc,0xee,0xb9,0x93,0xda,0xb1, |
3478 | | 0xe9,0x53,0x2e,0x53,0x7f,0xd1,0xe5,0x4f,0xfc,0x1e,0xda,0xf4,0x39,0x23,0xd4,0xef, |
3479 | | 0x5c,0x0f,0x63,0x29,0xd8,0x9b,0xce,0x75,0xfb,0x59,0xaf,0xef,0x33,0x7d,0xd7,0x8f, |
3480 | | 0x9a,0x73,0x3e,0x45,0xf3,0x65,0x9f,0xd2,0xdc,0x58,0x33,0x27,0x7c,0x9b,0xe6,0x58, |
3481 | | 0x7f,0xae,0x39,0x92,0x87,0x13,0xfe,0x7e,0xf3,0xea,0x0f,0x68,0xae,0xa7,0x99,0x23, |
3482 | | 0xda,0xa5,0xd8,0x3f,0xeb,0xdb,0xc3,0xc7,0xc9,0xce,0x13,0xf0,0x9c,0xf5,0x77,0xd1, |
3483 | | 0x9e,0x46,0x9f,0x32,0xf3,0xd7,0xf0,0x08,0x9e,0xe3,0xae,0x89,0x72,0x57,0x79,0x77, |
3484 | | 0x4d,0x94,0x7b,0x60,0x32,0x7e,0xab,0x61,0x6d,0xd0,0x71,0xde,0x0d,0xba,0x7f,0xbf, |
3485 | | 0x65,0x12,0xda,0x16,0x9e,0x30,0x6b,0xa3,0x4f,0xe7,0x78,0xf4,0x49,0x68,0x0f,0x1d, |
3486 | | 0xcc,0xda,0xe5,0x67,0x51,0xb7,0xd1,0xcb,0x60,0x1a,0x5c,0x0e,0xdd,0xa0,0x0b,0x3c, |
3487 | | 0x14,0x74,0xd7,0xff,0x79,0xd8,0xac,0xf1,0x0e,0x37,0xc2,0xb3,0x66,0x3d,0x74,0xf3, |
3488 | | 0x37,0x43,0x20,0x72,0x73,0xc0,0xb9,0xf3,0x19,0xf2,0x82,0x3d,0x64,0xec,0x68,0x14, |
3489 | | 0x6a,0xfe,0x4e,0xcc,0x50,0xf3,0x37,0x49,0x82,0x6e,0x9d,0xbe,0x06,0xcd,0x87,0xff, |
3490 | | 0x75,0xe8,0xf5,0x30,0x12,0xa6,0xc2,0xd3,0x26,0x5e,0xd2,0xf4,0x0c,0x3a,0xce,0x84, |
3491 | | 0xa5,0x53,0x18,0x8f,0x4e,0x81,0xc7,0xe1,0x01,0x58,0xc2,0xf9,0x97,0xc2,0x32,0xc8, |
3492 | | 0x4f,0x1c,0x65,0x60,0x52,0xd1,0x80,0xf3,0x32,0x3c,0x24,0x7d,0x4a,0x9a,0x58,0x2c, |
3493 | | 0xe0,0x54,0x82,0x24,0x69,0x93,0x12,0x01,0xa7,0x5e,0x09,0x57,0x3b,0xc0,0x82,0x92, |
3494 | | 0x84,0x2b,0xe9,0xea,0x4c,0xe9,0x42,0x98,0x5f,0x2a,0xe0,0xcc,0x80,0x05,0xd2,0xd4, |
3495 | | 0xd3,0x03,0x4e,0x02,0x74,0x78,0x37,0xe0,0xf4,0x80,0x8b,0x7c,0xda,0xdf,0xb2,0x0f, |
3496 | | 0xb0,0xec,0xd9,0x96,0x7d,0xa0,0x65,0x1f,0x04,0x0b,0x64,0x7f,0x59,0xba,0xc0,0x8a, |
3497 | | 0xeb,0x65,0xcb,0xbe,0xc0,0x8a,0xf7,0x65,0xcb,0xfe,0x4f,0x5b,0xd3,0xe1,0xaf,0x90, |
3498 | | 0x9f,0x7f,0x52,0x5e,0xfe,0xe8,0x6b,0xe3,0xe5,0xa5,0x89,0x95,0x76,0x7f,0x9a,0x4f, |
3499 | | 0x36,0xbd,0x3d,0x8f,0x93,0xce,0x7f,0x7b,0x99,0x67,0x1e,0x23,0x2f,0xc7,0xcb,0xc3, |
3500 | | 0x7f,0x4a,0xff,0xff,0x3a,0xed,0xc7,0xba,0x06,0xad,0xfe,0x62,0x69,0x0e,0xf7,0xa7, |
3501 | | 0xe1,0xfc,0x84,0xf3,0x13,0xce,0xcf,0x3f,0x2d,0x3f,0x89,0x3c,0x2f,0xd7,0x08,0xba, |
3502 | | 0xeb,0xf0,0xde,0xad,0xb5,0x31,0xef,0xd5,0x7a,0xb9,0xf7,0x69,0x7d,0xdc,0x07,0xb4, |
3503 | | 0x66,0xed,0x83,0xf0,0x10,0x3c,0x0c,0x8f,0xc0,0xa3,0x5a,0xe7,0x75,0xb2,0xd6,0x91, |
3504 | | 0x7d,0x40,0x7f,0xfb,0xee,0x49,0xad,0x2f,0xfb,0x34,0x3c,0x63,0xd6,0x18,0xd4,0xba, |
3505 | | 0xaf,0xd1,0x15,0xdc,0xb5,0x81,0xed,0xbf,0xe5,0x64,0xd6,0xe2,0x7e,0x49,0x6b,0xf6, |
3506 | | 0xce,0xd7,0xfa,0xb9,0xe6,0x6f,0xea,0xbd,0xa2,0xbf,0xe7,0xbc,0x10,0x16,0x69,0x0d, |
3507 | | 0xee,0x25,0xd6,0xdf,0xda,0x7b,0x0d,0x5e,0xd7,0x5a,0xb7,0xde,0xdf,0x7a,0x5a,0xa9, |
3508 | | 0xb5,0x68,0x83,0x15,0xdc,0x78,0xe7,0x2b,0xae,0xe5,0x3a,0x6e,0x49,0x44,0x38,0x9f, |
3509 | | 0xe1,0x7c,0x86,0xf3,0xf9,0x57,0xce,0x67,0x0e,0x7c,0x1c,0x71,0xe2,0xef,0xf9,0xfe, |
3510 | | 0xf2,0xe1,0x22,0x09,0x07,0x49,0x91,0xee,0xdf,0xee,0x4c,0x89,0x74,0xff,0xa6,0xa6, |
3511 | | 0xf9,0xbb,0x99,0xe6,0x6f,0x65,0x9a,0xbf,0x87,0x69,0xfe,0x86,0x67,0x6d,0xa8,0x13, |
3512 | | 0xe9,0xfe,0x3d,0xcc,0xfa,0x90,0x01,0x0d,0x20,0x33,0xd2,0xfd,0x9b,0x96,0x8d,0x20, |
3513 | | 0x0b,0x1a,0x47,0xba,0x7f,0xd3,0xb2,0x69,0xa4,0xfb,0xb7,0x2c,0xcd,0xdf,0xc7,0x3c, |
3514 | | 0x1f,0x6e,0x79,0xda,0xfd,0xdb,0x9c,0xe6,0xef,0x82,0x5e,0x14,0xe9,0xfe,0x1d,0xcd, |
3515 | | 0x19,0xf0,0x4e,0xe4,0xc9,0xa5,0xc1,0x3b,0x7f,0x83,0xff,0x70,0xde,0xe6,0x3a,0xf7, |
3516 | | 0x5d,0x3a,0x5f,0x3b,0xe8,0x0c,0xd3,0xa1,0x0d,0xe9,0x98,0x15,0x79,0xe4,0xbd,0x7e, |
3517 | | 0x35,0xbd,0x73,0x6f,0xaa,0x77,0xec,0x71,0xd6,0x1c,0x8f,0x86,0xbe,0x39,0x32,0xc9, |
3518 | | 0x7a,0x2f,0xde,0x40,0xef,0xd7,0x33,0xad,0xb9,0x13,0xde,0xfb,0xff,0x78,0xbd,0xbb, |
3519 | | 0x4f,0xd3,0x3b,0x75,0xf3,0xde,0xbc,0xbf,0xe6,0x35,0x4f,0x81,0x01,0xd6,0x79,0x9b, |
3520 | | 0xf8,0xc6,0xea,0x8e,0x77,0x2e,0xff,0x79,0xd2,0xac,0x39,0x55,0xf6,0x38,0xa8,0x7d, |
3521 | | 0xbc,0x7d,0xac,0x7d,0xcc,0xcb,0x79,0xa4,0xa5,0x86,0x6f,0xec,0xf0,0x64,0xd2,0x62, |
3522 | | 0xe7,0x77,0x4a,0xd4,0xff,0x2f,0xe3,0x26,0x79,0x94,0xf3,0x1f,0x51,0xc6,0xc7,0xbb, |
3523 | | 0x96,0x7f,0xc4,0x39,0xbc,0xf5,0x5c,0x13,0xf4,0xde,0x3f,0x51,0x9a,0x24,0x4d,0x96, |
3524 | | 0xa6,0x48,0x53,0xa5,0x69,0xd2,0x1a,0xd2,0x9a,0xd2,0x74,0x69,0x65,0x3d,0xb7,0x79, |
3525 | | 0xeb,0x2a,0x65,0x5a,0xf6,0x86,0x96,0xbd,0x91,0x65,0xcf,0xb2,0xec,0x8d,0x2d,0x7b, |
3526 | | 0x13,0xcb,0xde,0xd4,0xb2,0x37,0xb3,0xec,0xcd,0x2d,0x7b,0x0b,0xcb,0x7e,0x9e,0x65, |
3527 | | 0x6f,0x69,0xd9,0xcf,0xb7,0xec,0xad,0x2c,0x7b,0x6b,0xcb,0xde,0xc6,0xb2,0x5f,0x60, |
3528 | | 0xd9,0xdb,0x5a,0xf6,0x0b,0x2d,0x7b,0x3b,0xcb,0xde,0xde,0xb2,0x77,0xb0,0xec,0x17, |
3529 | | 0x59,0xf6,0x8e,0x96,0xfd,0x62,0xd9,0xcd,0x58,0xa5,0x89,0xdf,0x8c,0x57,0x36,0xd4, |
3530 | | 0x79,0xbd,0xe7,0xde,0x0e,0x0a,0xf7,0x67,0x3d,0x0f,0x37,0xf5,0x7d,0xd7,0xdd,0x56, |
3531 | | 0xe7,0x6b,0x2b,0xbc,0xef,0x98,0xbd,0x63,0x1b,0x2a,0xac,0xa7,0xde,0x1a,0xe5,0x17, |
3532 | | 0xc8,0x6e,0xd2,0x64,0xd6,0x6c,0x6c,0xa1,0xb1,0x0a,0x6f,0xbc,0xc2,0xac,0x7b,0xda, |
3533 | | 0xa1,0x93,0xe3,0xbc,0xd5,0xf6,0xc8,0x9a,0x28,0x66,0x4d,0xa8,0x33,0x48,0xc8,0xb6, |
3534 | | 0x5b,0xdc,0x35,0xf1,0x9e,0xc4,0x5d,0x8e,0x87,0xf1,0xf2,0x03,0xdd,0x6f,0x0e,0x5b, |
3535 | | 0x12,0xe9,0xed,0x9d,0x1d,0xe7,0x0e,0x32,0x33,0x13,0xf7,0x59,0xe6,0x1b,0xcc,0xeb, |
3536 | | 0xdc,0x35,0x4b,0xa7,0xdd,0xee,0x38,0xfb,0xc8,0x48,0x3a,0x99,0x2b,0xc9,0xc3,0xf9, |
3537 | | 0x44,0xe2,0x6f,0xd7,0xdd,0x2d,0x04,0xb3,0xce,0x54,0xf3,0x09,0xee,0xda,0x4e,0x66, |
3538 | | 0x9d,0x27,0xb3,0xbe,0x53,0x74,0x77,0x77,0x2d,0xd0,0xb6,0x84,0x1b,0xc5,0x43,0xfa, |
3539 | | 0x35,0x3c,0xa4,0xe7,0xe3,0xd8,0x91,0xfd,0xdd,0x75,0xa5,0x72,0xd7,0x56,0x22,0xde, |
3540 | | 0x41,0x9c,0xe3,0x25,0x0a,0xab,0xe5,0x5d,0xee,0x75,0xaa,0xd6,0xcb,0xbd,0x4e,0xc6, |
3541 | | 0x6e,0xe2,0xf5,0xec,0xb7,0x5b,0xf6,0x5b,0x3a,0x1d,0xb1,0x9b,0x75,0x1e,0x3c,0xbb, |
3542 | | 0x39,0x97,0x67,0xdf,0x30,0xf4,0x88,0xfd,0xe3,0x0b,0x8e,0xd8,0x3b,0xf4,0x70,0xed, |
3543 | | 0xf7,0x93,0xcf,0xbd,0x6d,0x4f,0xfc,0xfe,0x57,0x97,0xf3,0xd7,0x34,0xeb,0x66,0x41, |
3544 | | 0x85,0x40,0xd0,0xe9,0xd2,0xca,0xfd,0x1e,0xf0,0x15,0x08,0x72,0xc1,0xae,0x81,0x49, |
3545 | | 0xad,0xdd,0xef,0x03,0xdf,0x81,0x47,0x53,0x4c,0x5f,0x10,0xcc,0xfd,0x56,0xf0,0x42, |
3546 | | 0xb8,0x1c,0x86,0x99,0x6f,0x6f,0x43,0x41,0x67,0x01,0xfb,0x7a,0xb5,0x71,0xcb,0xb9, |
3547 | | 0x05,0xee,0xfb,0xd1,0x27,0xcd,0xb7,0xb9,0xc4,0xfd,0x5c,0x1b,0xf7,0x5b,0xbb,0xcd, |
3548 | | 0x77,0x05,0x73,0xd7,0xdd,0x8d,0x20,0xed,0x9b,0x09,0x5f,0x1b,0x6d,0x7c,0x81,0x5b, |
3549 | | 0x5e,0xc3,0x4c,0x7e,0x52,0xdd,0xef,0xef,0xbc,0xef,0x10,0xcd,0x77,0x78,0x21,0xf2, |
3550 | | 0x13,0xd5,0xd6,0xfd,0x56,0xb7,0x59,0x5b,0xf7,0xdb,0xc4,0x8b,0x61,0x30,0x5c,0x07, |
3551 | | 0x37,0x58,0x54,0xcb,0x1f,0x74,0xb2,0x29,0xbb,0x55,0xd8,0x37,0x43,0xf7,0x02,0x41, |
3552 | | 0x67,0x37,0xba,0xdf,0xc4,0xc1,0x75,0x7a,0x14,0x6a,0x42,0x53,0xb8,0xc2,0xac,0xdf, |
3553 | | 0x04,0xdf,0x41,0x51,0xae,0x55,0x5b,0xe8,0x0e,0x37,0x0a,0xf3,0xdd,0xdf,0x74,0x98, |
3554 | | 0x03,0xcb,0xe0,0x94,0x0e,0xee,0xf7,0x90,0xa7,0xa2,0x6d,0xd0,0x21,0xed,0xdd,0x6f, |
3555 | | 0x39,0xbf,0xa2,0xfe,0xbc,0x8d,0xdf,0x37,0x50,0x08,0xfb,0x6d,0x68,0x12,0x9a,0x08, |
3556 | | 0xcf,0xc1,0xf6,0x92,0x41,0xe7,0x6b,0xf4,0x7b,0x88,0xea,0xe8,0xd6,0xd5,0x0a,0xe6, |
3557 | | 0xfb,0x41,0x98,0x7a,0x4a,0xd0,0xd9,0x05,0x5f,0x62,0x2f,0x4d,0x43,0xaa,0x04,0x1b, |
3558 | | 0xb1,0xf7,0x44,0xbf,0xe2,0x62,0x1d,0x86,0x7c,0xd4,0x8b,0x7a,0x62,0xe5,0xe9,0x41, |
3559 | | 0xe7,0x35,0x74,0x63,0x27,0xf7,0xfb,0xdc,0x03,0x70,0x5a,0xe9,0xa0,0xf3,0x0b,0x1a, |
3560 | | 0x75,0x09,0x79,0xe8,0xec,0xae,0x37,0x3c,0x8a,0x8b,0xdc,0x45,0xdf,0x6a,0x2e,0x81, |
3561 | | 0x3b,0x60,0xfb,0x59,0x41,0xa7,0x21,0x75,0x79,0x07,0xda,0x1f,0xed,0x03,0x23,0xe0, |
3562 | | 0x53,0xd8,0x0a,0xd5,0xa9,0x14,0x3f,0xa1,0x95,0x2f,0xa3,0x5e,0x98,0xef,0x19,0xa1, |
3563 | | 0x1b,0x7e,0x63,0xca,0x07,0x9d,0x11,0xe8,0x4c,0xdc,0x73,0xe0,0xa5,0xcb,0xdc,0x6f, |
3564 | | 0xc4,0xef,0x7e,0x22,0x98,0xbb,0x56,0x71,0x62,0x6c,0x30,0x97,0xc0,0x68,0xce,0xdd, |
3565 | | 0xd9,0x65,0x05,0xe1,0xe7,0x27,0x05,0x9d,0x8f,0xba,0x06,0x9d,0x6e,0xb8,0xfb,0xc0, |
3566 | | 0x36,0xfc,0x1e,0x44,0xd7,0xc0,0x06,0x38,0x08,0xa3,0xba,0x50,0x9f,0xa8,0x88,0x67, |
3567 | | 0xa6,0xbb,0xdf,0x94,0xbe,0x57,0x31,0xe8,0xac,0x40,0x9b,0xf2,0x03,0xfb,0xbc,0xae, |
3568 | | 0xee,0x77,0x94,0x46,0xaf,0xd1,0xb7,0x94,0xb3,0xe1,0x49,0x98,0x01,0x9f,0xe8,0xbb, |
3569 | | 0x4a,0xf3,0x6d,0xbc,0x59,0xaf,0xa4,0x34,0x5c,0x0a,0xb3,0xe0,0x3d,0x68,0x4d,0x5b, |
3570 | | 0x2d,0x58,0x35,0xe8,0xd4,0x45,0x0f,0xe3,0xbe,0x02,0x1d,0x03,0xdb,0x61,0x3f,0xfe, |
3571 | | 0x15,0xf8,0xe1,0xfe,0x06,0xf6,0x69,0x10,0x5f,0x8b,0xfc,0xe2,0xbe,0x1e,0x1e,0x81, |
3572 | | 0x61,0xd0,0xb7,0x96,0xfb,0x5d,0x6b,0xdf,0x1e,0x66,0x6e,0x4a,0xd0,0xd9,0x86,0xfe, |
3573 | | 0x40,0xbf,0xd2,0x0c,0x4e,0xaf,0xed,0x7e,0xeb,0x9a,0x0f,0xdd,0x4e,0xb8,0xbb,0xa9, |
3574 | | 0xd3,0x13,0xdb,0xb8,0x2f,0x00,0x1e,0xc6,0xff,0xf9,0x91,0x3c,0xef,0x35,0x3c,0xf2, |
3575 | | 0x6d,0x67,0x79,0xb8,0x0c,0xda,0xc2,0x6b,0xc9,0x41,0xa7,0x19,0xc7,0x1d,0xc2,0x3e, |
3576 | | 0x16,0x2e,0xb8,0xc2,0xfd,0x66,0xb6,0x5f,0x4a,0xd0,0xb9,0x13,0x2d,0x0b,0x25,0x7b, |
3577 | | 0x3b,0xb9,0xdf,0x45,0x66,0xa2,0x4f,0xc0,0x2e,0x98,0x7a,0x25,0xf6,0xb4,0xa0,0xb3, |
3578 | | 0x09,0x3d,0xad,0x0e,0x71,0xf6,0xe1,0xf7,0x41,0xcd,0xa0,0x73,0x21,0x7a,0x3e,0xee, |
3579 | | 0x41,0x66,0x5d,0x6c,0x7d,0x3f,0xfa,0x0a,0xdc,0x51,0x2b,0xe8,0x14,0xe0,0x5a,0x1f, |
3580 | | 0x42,0xcf,0xef,0xcb,0xef,0x81,0x3a,0x41,0x67,0x31,0xba,0x06,0x7a,0xc1,0x29,0xfd, |
3581 | | 0xa8,0x53,0xfd,0xdc,0x6f,0x75,0xcd,0xf7,0xa6,0xbd,0x61,0x38,0x8c,0x85,0x32,0x75, |
3582 | | 0x83,0x4e,0x0a,0x5a,0x9d,0x7e,0xad,0x3f,0x24,0xd7,0x75,0xbf,0x45,0x5d,0x01,0xef, |
3583 | | 0xd6,0x0b,0x3a,0x07,0xd9,0xd7,0x9f,0xfe,0xf2,0xb2,0xfa,0xa4,0x19,0x96,0x63,0x4f, |
3584 | | 0xcf,0x76,0xbf,0x53,0x2d,0x0d,0xf7,0x11,0xbe,0x39,0x7a,0x1d,0x0c,0x83,0xe7,0xe1, |
3585 | | 0x1c,0xfa,0x84,0x2c,0xfa,0xe4,0xee,0x99,0x41,0xe7,0x61,0x74,0x7a,0xc3,0xa0,0x53, |
3586 | | 0x79,0x90,0xfb,0x3d,0x6b,0x6b,0xc8,0xd7,0x38,0xe8,0x8c,0x44,0x27,0x1a,0xbf,0x26, |
3587 | | 0x41,0xa7,0x64,0xd3,0xa0,0x73,0xcd,0x60,0xda,0x13,0x3c,0x57,0x8f,0xdf,0x44,0xe8, |
3588 | | 0xfc,0x7a,0x2e,0x4d,0x86,0x38,0xce,0x25,0x43,0xdc,0xef,0x5f,0xc7,0x9a,0xef,0xdf, |
3589 | | 0xa1,0x74,0x7d,0xc7,0x39,0x9b,0xbe,0x37,0xed,0xbc,0xa0,0x53,0xcf,0xac,0x41,0x8d, |
3590 | | 0x9a,0x6f,0xfc,0x1f,0xa3,0xfe,0x16,0xa5,0xdf,0x9c,0xd2,0x2a,0xe8,0xcc,0x87,0x46, |
3591 | | 0xad,0x83,0xce,0x61,0xc2,0xe6,0xcb,0x70,0xbf,0x91,0x3d,0x80,0xfb,0x6b,0x38,0xbd, |
3592 | | 0x4d,0xd0,0x49,0x86,0x32,0xc3,0xb8,0x06,0xc2,0x7c,0x3f,0x6b,0xbe,0x4b,0xbd,0x0d, |
3593 | | 0x6d,0x8c,0xde,0x97,0x61,0xbe,0x05,0xa7,0x3c,0x87,0xbb,0x6b,0x1b,0x98,0xef,0x6a, |
3594 | | 0xb7,0xe1,0x57,0xb1,0x7d,0x30,0xf7,0x3b,0xe6,0x07,0xd1,0x37,0xc0,0x7c,0x8b,0xbd, |
3595 | | 0x1b,0xaa,0x37,0x70,0xbf,0x67,0x6e,0x0e,0xad,0x60,0x44,0xc7,0xa0,0xf3,0xcc,0xc5, |
3596 | | 0x2e,0x5f,0xe1,0x0e,0x72,0x73,0x9e,0xde,0x89,0xf2,0xbb,0x96,0x3e,0x0f,0x2a,0xe1, |
3597 | | 0x1e,0x79,0x49,0xd0,0x59,0x37,0x82,0xdf,0x85,0xd8,0x77,0xa2,0xdb,0x34,0x49,0xe0, |
3598 | | 0xa6,0xce,0x41,0xa7,0x3b,0x1a,0xa0,0x5e,0xad,0x40,0x83,0xd7,0x73,0x3f,0x87,0x14, |
3599 | | 0xdc,0x95,0xbb,0x05,0x9d,0x26,0xd0,0x11,0xfb,0x87,0xe8,0x35,0x37,0x70,0x6d,0xbb, |
3600 | | 0x07,0x9d,0x89,0xe8,0x21,0x7d,0xe3,0xfb,0xd1,0xe5,0x41,0x27,0xb6,0x07,0x7d,0x3c, |
3601 | | 0xf6,0xa9,0x68,0x36,0xda,0x99,0xba,0xf8,0x3e,0xc7,0xcc,0xc6,0x1e,0x31,0xca,0x71, |
3602 | | 0x0a,0x70,0xf3,0xad,0x87,0xce,0xa5,0xff,0x79,0xa6,0x57,0xd0,0x99,0x0b,0xf7,0x10, |
3603 | | 0xe6,0xe1,0x64,0xb7,0x7d,0x47,0xc2,0xa3,0xe3,0x69,0xcf,0x84,0xbb,0x0b,0xfb,0x6d, |
3604 | | 0xf0,0x08,0xcc,0xa1,0x1f,0x9c,0x65,0x14,0x16,0xc2,0x0e,0xa8,0xd3,0x27,0x98,0xbb, |
3605 | | 0x36,0xc2,0x59,0x63,0xb8,0xe6,0xf0,0x3c,0xc4,0xc2,0x42,0xf8,0x7c,0x8c,0xfb,0xed, |
3606 | | 0x76,0x5b,0x74,0x15,0xbc,0x05,0x39,0x90,0xd6,0x37,0xe8,0xf4,0xe9,0x47,0x9a,0xd0, |
3607 | | 0xaa,0x3c,0xac,0xec,0x27,0xcc,0x01,0x38,0x65,0x2c,0xe1,0x06,0x07,0x9d,0xcb,0xd1, |
3608 | | 0x6a,0x03,0x82,0xce,0xa5,0xec,0xeb,0x0a,0xb3,0xb0,0xaf,0xcb,0xe6,0x18,0xec,0xad, |
3609 | | 0xb5,0x06,0x45,0x2f,0xe8,0x0d,0xd3,0x60,0x1c,0x14,0xbe,0x99,0xfe,0xed,0x26,0xf7, |
3610 | | 0xdb,0xe6,0xca,0xd0,0x07,0x6e,0x82,0x0d,0x1c,0xf3,0x29,0x1a,0x18,0x47,0x5f,0x84, |
3611 | | 0xbd,0x8b,0xd6,0x04,0xef,0x35,0x34,0xe8,0x6c,0x40,0x3f,0x81,0x54,0x1e,0x96,0x0e, |
3612 | | 0xa1,0xaf,0x70,0xaf,0x7a,0x61,0x78,0xd0,0xe9,0x79,0x75,0xd0,0x59,0x84,0xdf,0x0a, |
3613 | | 0x98,0xac,0x6f,0xa1,0xcd,0x77,0xd0,0x66,0xbd,0xf0,0xa9,0x23,0x82,0xce,0x74,0x74, |
3614 | | 0x29,0x94,0xe6,0x19,0x61,0x18,0x54,0xbf,0x21,0xe8,0x44,0xe6,0x0b,0x3a,0xab,0xb1, |
3615 | | 0xbf,0x0a,0xfb,0xe0,0x13,0xdc,0xef,0xdd,0xe9,0x7e,0x37,0xbd,0x6e,0x6c,0xd0,0xd9, |
3616 | | 0x03,0xf7,0xf2,0x9c,0xb1,0x1f,0x8a,0xf1,0xbc,0x10,0x7f,0x73,0xd0,0x29,0x8d,0xd6, |
3617 | | 0xbc,0x9b,0x34,0xc2,0x46,0xf3,0x4d,0x35,0x1c,0xbc,0x87,0xfb,0xe3,0xbd,0xa4,0xe7, |
3618 | | 0xb6,0xa0,0x73,0xdb,0x44,0xda,0x09,0x0f,0x6f,0xf3,0x26,0x9a,0xf3,0x04,0x9d,0x1d, |
3619 | | 0xd8,0x5f,0xbb,0x8f,0xeb,0x48,0xff,0x1d,0x7b,0x3f,0xf5,0x82,0xfb,0xec,0x19,0x77, |
3620 | | 0xd3,0xcf,0xf3,0x20,0x35,0x14,0xb6,0xe0,0x97,0xff,0xde,0xa0,0x33,0x1b,0xfb,0x7d, |
3621 | | 0xa8,0xf9,0x1e,0xdb,0x70,0x2e,0xbc,0x34,0x31,0xe8,0x6c,0x45,0x93,0x79,0x08,0x3c, |
3622 | | 0x77,0x12,0xd7,0x1d,0x96,0xc1,0xcf,0xf0,0x36,0x7e,0x09,0x0f,0x05,0x73,0xbf,0xdb, |
3623 | | 0xce,0x78,0x98,0xfb,0x03,0xbc,0xcd,0x83,0xe2,0x1e,0xe8,0xf5,0x08,0xf6,0xc9,0x41, |
3624 | | 0xe7,0x07,0xec,0xa1,0x29,0x41,0xa7,0xf0,0xe3,0x41,0xe7,0x2e,0x30,0x6b,0x8f,0xb7, |
3625 | | 0x6f,0xe9,0xae,0x39,0xfe,0x33,0x84,0x1e,0x73,0x9c,0x22,0x70,0x8a,0xd6,0x1c,0xcf, |
3626 | | 0x9d,0x30,0x40,0xb1,0x07,0x23,0x22,0x43,0x51,0xd1,0xf9,0x62,0xf2,0x17,0x28,0x58, |
3627 | | 0xa8,0x30,0x41,0x72,0x97,0xda,0x2d,0x5e,0xa2,0x64,0xa9,0x53,0xe8,0x37,0x9d,0x23, |
3628 | | 0xdb,0x69,0xa7,0x73,0xcf,0x74,0xfe,0x17,0x5b,0x69,0xe7,0xcc,0xb3,0xca,0x94,0xfd, |
3629 | | 0x83,0x23,0x75,0xff,0xaa,0x55,0x85,0xd8,0xb3,0x5d,0xe7,0x39,0x74,0x1e,0x95,0x2a, |
3630 | | 0x9f,0x5b,0xa5,0x6a,0xb5,0xb8,0xf8,0xea,0x09,0x89,0x49,0xc9,0x4e,0x4a,0x6a,0xee, |
3631 | | 0x63,0xda,0x1f,0xb4,0xd5,0xf0,0x1e,0xf5,0xfe,0xb0,0xad,0xd6,0xb1,0x3c,0x6b,0xd7, |
3632 | | 0x39,0xca,0x59,0xb7,0x66,0x3d,0x77,0x3e,0x57,0x03,0x27,0xbc,0x85,0xb7,0xf0,0x16, |
3633 | | 0xde,0xc2,0x5b,0x78,0x0b,0x6f,0xe1,0x2d,0xbc,0x85,0xb7,0xf0,0x16,0xde,0xc2,0x5b, |
3634 | | 0x78,0x0b,0x6f,0xff,0xd2,0x6d,0xc7,0xb1,0xb6,0x9d,0x39,0x6c,0x3b,0x37,0x9a,0xff, |
3635 | | 0x73,0x56,0xad,0x3a,0xf2,0xbf,0xb6,0x80,0xd9,0x8c,0xc5,0x0b,0xbf,0x6f,0x87,0xeb, |
3636 | | 0xc8,0xc9,0x71,0x72,0xff,0xc7,0x41,0x14,0x3b,0xbe,0xd8,0xb5,0xcb,0xfc,0x3b,0x2a, |
3637 | | 0xea,0x70,0x89,0x1f,0xfb,0x12,0x84,0x8b,0x41,0x5b,0x6e,0xa5,0x32,0xff,0x7d,0xa2, |
3638 | | 0xea,0xe5,0xd6,0xb9,0x5c,0xbf,0x4f,0xb6,0xef,0xc8,0x7d,0x47,0x59,0xc4,0xbc,0x9e, |
3639 | | 0xcc,0x7d,0x3f,0x79,0xaa,0x79,0x29,0xb9,0x23,0xc7,0x29,0xfe,0x47,0xb7,0x87,0x32, |
3640 | | 0x65,0xcb,0x9d,0xec,0xa1,0xa5,0xcd,0x3b,0xca,0x72,0xe5,0x2b,0x98,0x24,0xef,0x50, |
3641 | | 0x2e,0x72,0xfc,0x81,0x62,0xff,0xcc,0x56,0xed,0x5a,0x72,0x72,0xd5,0x39,0x56,0x6a, |
3642 | | 0x8e,0xb1,0x9d,0x7d,0x9c,0x98,0xdd,0x2b,0x61,0xae,0x88,0xf9,0x97,0x1b,0xbd,0x6b, |
3643 | | 0x76,0xfc,0x4d,0xba,0xba,0x9c,0x23,0x09,0xcd,0xf9,0x4f,0x41,0x8f,0x74,0x8d,0xce, |
3644 | | 0xaf,0xae,0x93,0xa9,0xc7,0x39,0x39,0xbf,0x2b,0xb1,0xea,0x5e,0x4f,0x32,0x7b,0x39, |
3645 | | 0x76,0xb7,0xac,0xd4,0xeb,0x8a,0xb9,0x7b,0xa9,0xa4,0xaa,0x99,0x39,0xbf,0xbb,0xdf, |
3646 | | 0x89,0xf6,0x7b,0xc4,0xa8,0x82,0xfc,0x49,0x17,0xf4,0x98,0xe7,0x3f,0xb9,0x52,0xfe, |
3647 | | 0x1f,0x9f,0xdf,0x09,0x9f,0xff,0x8f,0xdc,0xfe,0x2a,0xf9,0xbf,0xb0,0xd3,0xbf,0xa1, |
3648 | | 0xfc,0x63,0x62,0xfe,0x52,0xd7,0xff,0xcf,0x3d,0x79,0xaf,0x5e,0x47,0x9f,0xaf,0x0f, |
3649 | | 0xdb,0x9f,0x79,0xfe,0xa1,0x43,0x8f,0x3e,0xff,0x35,0xd7,0x98,0x19,0x70,0x7f,0xe0, |
3650 | | 0x63,0xd8,0x7f,0xba,0x7b,0xe5,0x60,0x36,0xfe,0xc6,0x88,0x47,0x8d,0x76,0x6e,0xcc, |
3651 | | 0xb5,0x8c,0x66,0xe3,0x7f,0xee,0x5b,0x31,0xce,0xef,0xbd,0x65,0xe4,0xfc,0xd9,0x95, |
3652 | | 0x2d,0xfa,0x18,0xb5,0xff,0x0f,0x28,0xf4,0x7f,0xde,0x2f,0x9b,0xbf,0x63,0xb2,0x8f, |
3653 | | 0x77,0x69,0x63,0xfe,0xda,0xa9,0xff,0xa3,0x1e,0x6f,0xfe,0x5a,0xdb,0xf6,0xbf,0x58, |
3654 | | 0x7a,0x3e,0xd9,0xf1,0x4f,0x6b,0xad,0x47,0xff,0xfc,0xf8,0x6f,0xde,0x95,0x8f,0xbc, |
3655 | | 0x0c,0x3a,0xe9,0xd3,0x1c,0xfd,0x4a,0xc0,0xc9,0xc9,0xb1,0x7f,0x6d,0xff,0x49,0xdd, |
3656 | | 0x4d,0xf4,0x6f,0xeb,0x0f,0x76,0xe4,0xfc,0xae,0x77,0x60,0xbf,0xe7,0x86,0x13,0xfd, |
3657 | | 0x07,0xc5,0x93,0xf7,0xa3,0xe7,0x5f,0xe9,0x96,0x13,0xf0,0xaa,0x87,0xf9,0xdf,0x09, |
3658 | | 0xb8,0x9b,0x75,0x7f,0xdd,0x91,0x1b,0xee,0x9f,0x72,0x8b,0xcd,0xf9,0xf5,0xbd,0xc6, |
3659 | | 0x8e,0x5d,0x1f,0xe4,0xac,0xda,0x71,0x22,0xdb,0xce,0xed,0xdb,0x73,0x3e,0xda,0xf1, |
3660 | | 0x45,0xce,0x3f,0xaf,0x0f,0xdb,0xb1,0x23,0x10,0x30,0x39,0x0c,0x18,0xf1,0x2e,0x36, |
3661 | | 0xf6,0x9c,0x1d,0x7a,0x65,0xed,0xfc,0xab,0xb7,0xbf,0xda,0x13,0x59,0xcc,0x9f,0x90, |
3662 | | 0xe1,0xff,0xb8,0x9d,0x78,0x4c,0x1f,0x6d,0xdf,0xf9,0xc9,0x96,0x2d,0x7f,0x5a,0xc9, |
3663 | | 0xe4,0xcb,0xf7,0x8f,0xac,0x7f,0x47,0x5f,0x93,0xe3,0x5f,0xbd,0x3f,0xbe,0x3e,0xfc, |
3664 | | 0xf6,0x6a,0xf8,0x57,0x7d,0xee,0x8f,0x39,0xa9,0xfa,0xff,0x3b,0x5e,0x09,0xe4,0xfc, |
3665 | | 0x25,0x8a,0x29,0xfa,0xef,0xf3,0x5b,0xec,0xbf,0xd1,0x80,0x72,0x87,0x71,0x74,0x19, |
3666 | | 0xcd,0xb8,0xc4,0x5f,0xb2,0xdb,0xfd,0xfb,0x35,0x94,0x63,0x6e,0x67,0x38,0xff,0xf6, |
3667 | | 0x6d,0x87,0x3d,0x08,0x9b,0x13,0x1e,0xa7,0xfe,0x47,0x6d,0x39,0xe1,0x2c,0xfe,0x0f, |
3668 | | 0x5b,0xd5,0x5f,0xb1,0xb0,0x4e,0x38,0x51,0x3b,0x02,0x39,0x7f,0x9f,0x1b,0xc9,0xef, |
3669 | | 0xfc,0x99,0x1b,0x9e,0x9f,0xf3,0x17,0x69,0x34,0x7f,0x78,0x7d,0xcf,0xc9,0xf9,0xa3, |
3670 | | 0x22,0x72,0x27,0xc2,0xfc,0x96,0x08,0x77,0xfc,0x03,0xde,0xc2,0xc4,0xfc,0xd6,0x90, |
3671 | | 0xbf,0xbd,0xff,0x88,0x89,0xfe,0x83,0x2a,0xd5,0x49,0xd7,0xaa,0xdf,0xfb,0x02,0x35, |
3672 | | 0xfa,0xbf,0x53,0xf2,0x7f,0xe2,0x2b,0xd9,0x98,0xe8,0xbf,0x5f,0x15,0x8d,0xfe,0xc3, |
3673 | | 0x6f,0x55,0xd1,0x27,0x3e,0xff,0xe2,0xc8,0x4f,0xef,0x7f,0xde,0x64,0xcf,0x98,0xff, |
3674 | | 0x50,0xf7,0x76,0x84,0x2b,0xe3,0x3f,0x3b,0xf3,0x31,0xff,0xa2,0x6c,0xc7,0x38,0xe1, |
3675 | | 0x2d,0xdc,0xec,0xfe,0xff,0x93,0xc0,0x5f,0xba,0x20,0x62,0xfe,0x9c,0x38,0x63,0xfe, |
3676 | | 0xa5,0xad,0x2d,0xdc,0x27,0xfc,0x77,0xa6,0xc2,0xc5,0xfc,0xcd,0xfa,0x80,0xf0,0xf6, |
3677 | | 0x37,0xd9,0x7e,0x9d,0x0b,0xf2,0xdb,0x7f,0x2f,0x86,0x5f,0x07,0xfd,0x8d,0xb7,0xa8, |
3678 | | 0xa8,0xbf,0x55,0x6d,0xfd,0x67,0x14,0xfa,0xc6,0x8d,0x6e,0xa3,0xdb,0xba,0xd1,0x6c, |
3679 | | 0x9e,0xaf,0xf7,0x39,0xe9,0xaf,0x93,0xfa,0x8e,0xdf,0xf2,0xfe,0x8a,0x99,0xfb,0x7b, |
3680 | | 0xf7,0x06,0xd6,0x27,0x6e,0xfe,0x69,0x02,0x47,0x76,0xfd,0x79,0x6f,0x2d,0xc2,0x1d, |
3681 | | 0xeb,0x7f,0xb1,0x78,0xfe,0xed,0x37,0xae,0x9d,0x3b,0xff,0xf9,0xd3,0xff,0x7e,0xed, |
3682 | | 0x53,0xff,0xf4,0x3e,0x24,0xfc,0x3e,0xe0,0xef,0xf9,0x40,0x9c,0xbb,0xfa,0x67,0x28, |
3683 | | 0x14,0x1d,0xca,0x17,0x93,0x3f,0x14,0x2a,0x10,0xfa,0x75,0x2b,0x18,0x0a,0x15,0x2a, |
3684 | | 0x1c,0x2a,0x52,0x34,0x64,0x6f,0xc5,0x42,0xff,0xec,0xad,0x78,0x89,0x50,0xc9,0x52, |
3685 | | 0xa7,0x60,0x39,0x35,0x14,0xde,0xc2,0x5b,0x78,0x0b,0x6f,0xe1,0x2d,0xbc,0x85,0xb7, |
3686 | | 0xf0,0x16,0xde,0xc2,0x5b,0x78,0x0b,0x6f,0xe1,0x2d,0xbc,0x85,0xb7,0x7f,0xc8,0x16, |
3687 | | 0x70,0xfe,0x57,0x26,0xc2,0x09,0x39,0xd1,0xb9,0xa6,0x92,0x13,0xe7,0xd4,0x70,0x1a, |
3688 | | 0x3a,0x3d,0x9c,0x5e,0xce,0x55,0xce,0x18,0x67,0x8a,0xf3,0x84,0xf3,0xbc,0xb3,0xc0, |
3689 | | 0x59,0xec,0xbc,0xeb,0xec,0x77,0xbe,0xc5,0x84,0x02,0x25,0x02,0xe5,0x03,0x4d,0x02, |
3690 | | 0x2d,0x02,0x1d,0x02,0x9d,0x02,0xfd,0x02,0x57,0x1f,0x65,0x26,0x05,0x1e,0x0b,0x4c, |
3691 | | 0x0b,0xcc,0x0d,0x6c,0x08,0x7c,0x18,0xf8,0x3c,0xf0,0x7d,0xa0,0x44,0xf0,0xd4,0x60, |
3692 | | 0xf9,0x60,0x5c,0x30,0x39,0x98,0x15,0xec,0x11,0xec,0x8d,0xb9,0x3a,0x78,0x73,0xf0, |
3693 | | 0xfe,0xe0,0xc2,0xe0,0xd2,0xe0,0x3b,0xc1,0xf5,0xc1,0xcf,0x83,0x07,0xfe,0x8b,0xe6, |
3694 | | 0xe0,0x6f,0x30,0x81,0x88,0x40,0x44,0x44,0x44,0x28,0x22,0x26,0xa2,0x40,0xae,0x29, |
3695 | | 0xf1,0xab,0x29,0xf5,0xab,0x39,0x2b,0x22,0x36,0xe2,0x1c,0x4c,0x25,0x99,0xea,0x96, |
3696 | | 0xa9,0x81,0x49,0x8f,0xa8,0x1d,0x51,0x3f,0xa2,0x41,0xae,0x69,0xf6,0xab,0x69,0xf1, |
3697 | | 0xab,0x69,0x1b,0xd1,0x31,0xa2,0x13,0xe6,0x52,0x99,0x1e,0x47,0x99,0x7e,0x11,0x57, |
3698 | | 0xfd,0x47,0x73,0x75,0xc4,0x75,0x7f,0xba,0x19,0x15,0x31,0x36,0x4f,0x73,0x73,0xc4, |
3699 | | 0x2d,0xbf,0x9a,0xdb,0x22,0xee,0x38,0xca,0x8c,0x8f,0xb8,0x2b,0xe2,0x9e,0x88,0x89, |
3700 | | 0x27,0x68,0xee,0xff,0xdd,0x66,0x4a,0xc4,0xf4,0xff,0x60,0xe6,0x46,0x2c,0x3e,0xca, |
3701 | | 0x2c,0xfd,0x53,0xcc,0x6b,0x11,0x6f,0xfc,0x8f,0xcc,0x8a,0x88,0x37,0x23,0x56,0x47, |
3702 | | 0xac,0xf9,0xd5,0xbc,0x13,0xf1,0xee,0x3f,0xc2,0xac,0x0f,0x9b,0x7f,0xb5,0xf9,0x54, |
3703 | | 0xe6,0x0b,0xcc,0x01,0x4c,0x20,0xf2,0x88,0x89,0xc1,0x14,0x90,0x39,0x55,0xa6,0x7c, |
3704 | | 0xae,0x89,0xc5,0x9c,0x93,0x6b,0x52,0x65,0xea,0x62,0x9a,0x61,0x3a,0x5a,0xa6,0x2b, |
3705 | | 0xa6,0x87,0xcc,0x55,0x32,0xa3,0x22,0x6f,0x8e,0xbc,0x23,0xd7,0x8c,0x97,0xb9,0xe7, |
3706 | | 0x4f,0x33,0x13,0x8f,0x61,0x26,0xe5,0x9a,0x87,0x30,0x53,0x22,0x9f,0x8a,0x7c,0x26, |
3707 | | 0x72,0x06,0x66,0x96,0xcc,0x9c,0x5f,0xcd,0x2b,0x32,0x0b,0x65,0x16,0x63,0x96,0xe6, |
3708 | | 0x9a,0x37,0x72,0xcd,0x0a,0xcc,0x9a,0xc8,0x77,0x23,0xd7,0x47,0x6e,0xc2,0x7c,0x2c, |
3709 | | 0xb3,0xf9,0x57,0xf3,0xb9,0xcc,0x17,0x32,0xbb,0x31,0x7b,0xfe,0x9f,0xd9,0xfb,0x3b, |
3710 | | 0xcc,0xfe,0xc8,0x03,0xff,0x08,0xf3,0x6d,0xe4,0xf7,0xff,0xd1,0x1c,0x8c,0xfc,0xf1, |
3711 | | 0xa4,0x4c,0x78,0x28,0xf0,0xdf,0xbe,0xfd,0x18,0xf9,0xc7,0x9a,0x40,0xe8,0xf7,0x1a, |
3712 | | 0x1e,0x89,0xff,0x65,0xbf,0xc7,0xa2,0x8f,0x6b,0x62,0x72,0x4d,0x81,0xbf,0x89,0x29, |
3713 | | 0xe4,0x33,0x45,0x72,0x4d,0xb1,0xb0,0x39,0x21,0x53,0xea,0x5f,0x6f,0x4a,0xff,0x25, |
3714 | | 0xcd,0x59,0x7f,0x92,0x29,0x1f,0x8a,0xfd,0x97,0x9b,0x73,0xfe,0x75,0xa6,0xd2,0x51, |
3715 | | 0x26,0x4e,0xa6,0xfa,0xbf,0xd6,0x24,0x87,0x52,0xc3,0xe6,0xb8,0xa6,0x76,0xae,0xa9, |
3716 | | 0xfb,0x17,0x34,0xf5,0xc3,0xe6,0x6f,0x6e,0x1a,0x60,0x1a,0x62,0xb2,0x30,0x4d,0x30, |
3717 | | 0xcd,0x64,0x5a,0xfc,0xe1,0xa6,0x25,0xa6,0x15,0xa6,0x4d,0xa8,0x6d,0xae,0x69,0x17, |
3718 | | 0x36,0xff,0x12,0xd3,0x21,0xd4,0xf1,0x0f,0x31,0x9d,0x42,0x97,0x1e,0x65,0x3a,0x87, |
3719 | | 0xba,0xfe,0xcf,0x4c,0x8f,0x50,0xef,0x93,0x32,0x7d,0x42,0xfd,0x4e,0xc8,0x0c,0x08, |
3720 | | 0x0d,0xfc,0x93,0xcc,0xd5,0xa1,0x51,0xa1,0x31,0xa1,0xb1,0xa1,0x9b,0x43,0xb7,0x84, |
3721 | | 0x6e,0x0b,0xdd,0x11,0x9a,0x18,0x7a,0x24,0xf4,0x58,0x68,0x4a,0xe8,0x89,0xd0,0x53, |
3722 | | 0xa1,0x67,0x42,0xd3,0x42,0xcf,0x87,0x66,0x1d,0x65,0xe6,0x86,0x16,0x1c,0x65,0x96, |
3723 | | 0x86,0xde,0x0c,0xad,0x0e,0xad,0x09,0xbd,0x13,0x7a,0x37,0xb4,0x3e,0xf4,0x7e,0xe8, |
3724 | | 0xe3,0xd0,0x67,0xa1,0xcf,0x43,0x5f,0x84,0x76,0x87,0xf6,0x84,0xf6,0x86,0xf6,0x87, |
3725 | | 0xbe,0x0f,0xfd,0x74,0x94,0x89,0x88,0x8a,0x39,0xca,0x14,0x8a,0x2a,0x76,0x94,0x29, |
3726 | | 0x15,0x75,0xfa,0x51,0xa6,0x6c,0xd4,0x39,0x3e,0x53,0xf5,0x28,0x93,0x1c,0x55,0x3b, |
3727 | | 0xaa,0x6e,0x54,0xfd,0xa8,0x06,0x51,0x0d,0xa3,0xb2,0xa2,0x9a,0x44,0xb5,0x8a,0xea, |
3728 | | 0x10,0xd5,0x31,0xaa,0x53,0xd4,0xa5,0x51,0x9d,0xa3,0xba,0x46,0x75,0x8f,0xea,0x21, |
3729 | | 0xd3,0xcb,0x67,0x7a,0xff,0x0f,0x4c,0x9f,0xff,0x67,0x06,0x1e,0x65,0x06,0xff,0x97, |
3730 | | 0xcd,0x55,0x3e,0x73,0x6d,0xd8,0x9c,0x80,0xb9,0x0e,0x73,0x03,0x66,0xd4,0xff,0xc8, |
3731 | | 0x8c,0xc1,0x8c,0xc5,0xdc,0xfc,0x5f,0x36,0xb7,0xfc,0x6a,0x6e,0xcb,0x35,0x77,0x9c, |
3732 | | 0xa4,0x19,0x8f,0xb9,0xeb,0xa4,0xcc,0x3d,0x47,0x99,0x89,0x98,0xfb,0x73,0xcd,0xa4, |
3733 | | 0x5f,0xcd,0x43,0x27,0x68,0x1e,0xc9,0x35,0x8f,0x45,0x4d,0xc9,0xd3,0x3c,0x11,0xf5, |
3734 | | 0x54,0xae,0x79,0x26,0x6a,0x5a,0xae,0x99,0x1e,0xf5,0x7c,0xd4,0x8c,0xa8,0x59,0xbf, |
3735 | | 0x9a,0x39,0x51,0x73,0x73,0xcd,0xbc,0xa8,0x05,0xc7,0x30,0xaf,0x44,0x2d,0x3c,0x8e, |
3736 | | 0x59,0x6c,0x99,0xa5,0x51,0xaf,0x61,0xde,0x38,0xca,0xac,0x88,0x7a,0x33,0x6a,0x75, |
3737 | | 0xd4,0x9a,0xb0,0x39,0xae,0x79,0xe7,0x57,0xf3,0x2e,0x66,0x3d,0xe6,0x7d,0xcc,0x06, |
3738 | | 0xcc,0x87,0x98,0x4d,0x98,0x8f,0x31,0x9b,0x31,0x9f,0x62,0xb6,0x61,0x3e,0xc3,0x7c, |
3739 | | 0x9e,0x6b,0xbe,0xc0,0xec,0xc6,0xec,0x39,0xca,0xec,0xcf,0x35,0xdf,0xe6,0x9a,0x83, |
3740 | | 0xb9,0xe6,0xa7,0x5c,0x13,0x88,0xfe,0xfd,0x26,0xe2,0xff,0x99,0x23,0x2f,0x72,0xcd, |
3741 | | 0x16,0x83,0x29,0x80,0x29,0x84,0x29,0x82,0x29,0x86,0x29,0x81,0x29,0x85,0x39,0x15, |
3742 | | 0x73,0x3a,0xa6,0x34,0xe6,0xac,0x5c,0x53,0x16,0x53,0x1e,0x13,0x7b,0x94,0xa9,0x94, |
3743 | | 0x6b,0xaa,0xe6,0x9a,0xea,0xb9,0x26,0x39,0xd7,0xd4,0x38,0x41,0x93,0x1e,0x5d,0x3b, |
3744 | | 0xba,0x6e,0x74,0xfd,0x63,0x9a,0x06,0x61,0xf3,0x1b,0x4d,0x43,0x4c,0xd6,0x31,0x4c, |
3745 | | 0x93,0xb0,0xc9,0xc3,0x34,0x8b,0x6e,0x11,0x36,0x61,0x73,0x82,0xa6,0x55,0xd8,0x84, |
3746 | | 0xcd,0x3f,0xde,0xb4,0x0b,0x9b,0x7f,0xb5,0xe9,0x10,0xdd,0xf1,0x5f,0x6b,0x3a,0x85, |
3747 | | 0xcd,0x5f,0xd0,0x84,0x67,0x49,0x85,0xb7,0xf0,0x16,0xde,0xc2,0x5b,0x78,0x0b,0x6f, |
3748 | | 0xe1,0x2d,0xbc,0x85,0xb7,0xf0,0x16,0xde,0xc2,0x5b,0x78,0x0b,0x6f,0xe1,0x2d,0xbc, |
3749 | | 0x85,0xb7,0xf0,0x16,0xde,0xc2,0x5b,0x78,0x0b,0x6f,0xe1,0x2d,0xbc,0x85,0xb7,0xf0, |
3750 | | 0x16,0xde,0xc2,0x5b,0x78,0x0b,0x6f,0xe1,0x2d,0xbc,0x85,0xb7,0xf0,0x16,0xde,0xc2, |
3751 | | 0x5b,0x78,0x0b,0x6f,0xe1,0x2d,0xbc,0x85,0xb7,0xf0,0x16,0xde,0xc2,0x5b,0x78,0x0b, |
3752 | | 0x6f,0xe1,0x2d,0xbc,0x85,0xb7,0xf0,0x16,0xde,0xc2,0x5b,0x78,0x0b,0x6f,0xe1,0x2d, |
3753 | | 0xbc,0x85,0xb7,0xf0,0x16,0xde,0xc2,0x5b,0x78,0x0b,0x6f,0xe1,0x2d,0xbc,0x85,0xb7, |
3754 | | 0xf0,0x16,0xde,0xc2,0x5b,0x78,0x0b,0x6f,0xe1,0x2d,0xbc,0x85,0xb7,0xf0,0x16,0xde, |
3755 | | 0xc2,0x5b,0x78,0x0b,0x6f,0xe1,0x2d,0xbc,0x85,0xb7,0xf0,0x16,0xde,0xc2,0xdb,0xdf, |
3756 | | 0x6f,0xab,0x19,0xe1,0x38,0xfd,0x2b,0xb8,0xda,0x45,0x3a,0x00,0x75,0xd0,0x25,0x48, |
3757 | | 0x00,0x5d,0x8a,0x06,0xd1,0x65,0xc6,0x1b,0x7d,0x0d,0x8d,0x8c,0x30,0x3b,0x1d,0x27, |
3758 | | 0x0a,0x0d,0xa2,0xd1,0x68,0xc5,0xa0,0xe3,0xe4,0x43,0x5f,0x67,0x57,0x0c,0xfa,0x78, |
3759 | | 0x19,0xc7,0xc9,0x8f,0xbe,0x81,0xbb,0x20,0xba,0x86,0x70,0x45,0xcc,0x71,0x84,0x2b, |
3760 | | 0x66,0x8e,0x43,0x63,0xd1,0xc9,0x84,0x3b,0xc7,0xf8,0xa3,0x95,0xd1,0x48,0xc5,0x17, |
3761 | | 0x2c,0xe3,0xee,0x8f,0x44,0x13,0xd1,0xa8,0x32,0x6e,0x7a,0xa2,0x02,0x6e,0x7a,0xf2, |
3762 | | 0x29,0x5c,0xfe,0x80,0x1b,0x7f,0x41,0xb4,0x12,0xba,0xc2,0x91,0x7f,0x19,0xd7,0xbf, |
3763 | | 0x70,0xc0,0x8d,0xa7,0x60,0x19,0x77,0x7f,0x51,0x34,0x0e,0x2d,0xae,0x78,0x0b,0x97, |
3764 | | 0x71,0xf3,0xbb,0x52,0xf9,0x7d,0x53,0xf9,0x5d,0xa5,0xfc,0xbe,0x5a,0xc6,0xcd,0x6f, |
3765 | | 0x71,0xe5,0xb7,0xa4,0xce,0x7b,0x4a,0xc0,0xcd,0xef,0x6a,0xe5,0xf7,0x65,0x9d,0xef, |
3766 | | 0x0c,0xe5,0x33,0x52,0xf9,0x8c,0x52,0x3e,0xe7,0xeb,0xfc,0x95,0x83,0x6e,0x3e,0x4f, |
3767 | | 0x0b,0xb8,0xe9,0x38,0x0d,0xff,0x04,0x73,0x5c,0x19,0x37,0xde,0x32,0xca,0xe7,0x37, |
3768 | | 0xca,0xe7,0x99,0x01,0xf7,0xfc,0xe5,0xca,0xb8,0xe7,0x2f,0xa3,0xf3,0x97,0x53,0xbe, |
3769 | | 0x77,0x28,0xdf,0x15,0x14,0xfe,0x6c,0xed,0xaf,0x50,0xc6,0x4d,0x5f,0x45,0xa5,0xab, |
3770 | | 0x8c,0xd2,0x71,0xb6,0x97,0x0e,0x34,0x1e,0xad,0xa2,0xfc,0xbf,0xa5,0xfc,0xaf,0x51, |
3771 | | 0xfe,0xdf,0x56,0xfe,0x2b,0xeb,0xfc,0x55,0x94,0xff,0x6a,0x8a,0x3f,0x41,0xf9,0x7f, |
3772 | | 0x47,0xf9,0x5f,0xa9,0xf3,0xbc,0xa3,0xfc,0xe7,0x53,0xfe,0xf3,0xeb,0xbc,0xab,0x74, |
3773 | | 0x7d,0xe3,0x03,0x6e,0x7e,0xab,0x95,0x71,0xcf,0x93,0x12,0x70,0xcf,0x9b,0xa0,0xe3, |
3774 | | 0x77,0xea,0x7a,0x25,0x29,0x9d,0x69,0x01,0xf7,0x3a,0xa5,0xa8,0x5c,0xd2,0x95,0xef, |
3775 | | 0xba,0x0a,0x97,0xa6,0x70,0xb5,0x55,0x9e,0x75,0x74,0x5d,0x6b,0x29,0x7c,0x3d,0x95, |
3776 | | 0x6b,0x86,0xea,0x53,0xa6,0xf2,0xfb,0x83,0xce,0xdb,0x30,0xe0,0xe6,0xf3,0x5d,0xd5, |
3777 | | 0x9b,0x46,0x4a,0x47,0x13,0xc5,0xdf,0x58,0xf1,0x67,0x29,0xfe,0xe6,0x8a,0xbf,0xa9, |
3778 | | 0xe2,0x59,0xa7,0x72,0x5b,0xaf,0x72,0x7b,0x4f,0xe5,0xf6,0xbe,0xda,0xc9,0x79,0x2a, |
3779 | | 0xb7,0xf3,0x55,0x6e,0xf1,0x6a,0x27,0x1f,0xa8,0xdc,0xde,0x26,0x9e,0x02,0x68,0x6b, |
3780 | | 0xe5,0xeb,0x5d,0x95,0x5f,0x41,0x95,0x5f,0x61,0xb4,0xb4,0x69,0x27,0x4a,0xcf,0x5b, |
3781 | | 0x2a,0xc7,0x5d,0x4a,0xff,0x85,0xca,0x5f,0x7b,0xe5,0xf7,0x42,0x9d,0xe7,0x22,0xe5, |
3782 | | 0xe3,0x22,0xc5,0x57,0x54,0xf1,0x15,0xd7,0xf5,0xb8,0x58,0xf9,0x6a,0xaf,0xf2,0xbd, |
3783 | | 0x4c,0xc7,0x5f,0xac,0x7a,0x74,0x89,0xe2,0xe9,0xa2,0x78,0xba,0xe8,0xfc,0xdd,0x70, |
3784 | | 0x57,0x34,0xf5,0x36,0xe8,0x1e,0x7f,0x99,0xc2,0x5d,0xa9,0x70,0x97,0x2b,0x5c,0x5f, |
3785 | | 0x85,0x3b,0x43,0xe1,0xba,0xa9,0xfc,0xb2,0x55,0x7e,0xfd,0x55,0x7e,0x1f,0xaa,0xfc, |
3786 | | 0x3e,0x52,0xf9,0x6d,0x52,0xf9,0x5d,0xa1,0x7a,0x77,0xa5,0xca,0xaf,0xaf,0xea,0x5b, |
3787 | | 0x8e,0xca,0x6d,0x87,0xfa,0x97,0xfe,0x01,0xb7,0xfc,0xb2,0x55,0x7e,0xeb,0x95,0xdf, |
3788 | | 0x92,0xca,0xef,0x29,0x2a,0xbf,0x19,0x4a,0xd7,0x76,0x8e,0x3b,0x1b,0x1d,0xa4,0x72, |
3789 | | 0x1c,0xa4,0x74,0x0d,0x55,0x3b,0x1c,0x52,0xc6,0x3d,0xff,0x08,0xd5,0x97,0xeb,0x95, |
3790 | | 0xce,0x91,0x2a,0x9f,0xd1,0xaa,0xb7,0x43,0x94,0xef,0x9b,0xd4,0xce,0x6e,0x54,0xf8, |
3791 | | 0x71,0xba,0x1e,0xb7,0xca,0xff,0x76,0x1d,0xff,0xb5,0x8e,0xff,0x58,0xf9,0x1c,0xaa, |
3792 | | 0x7a,0xf7,0x83,0xfa,0x97,0xa4,0xa0,0x7b,0xdc,0x9d,0x3a,0x6e,0x78,0xc0,0xcd,0xe7, |
3793 | | 0x77,0x8a,0xf7,0x1b,0x1d,0x7f,0xb5,0xae,0xcf,0x04,0x9d,0xe7,0x5a,0xe5,0xfb,0x3a, |
3794 | | 0xe5,0xef,0x6e,0x95,0xef,0xbd,0x3a,0xef,0x16,0x95,0xef,0xa7,0x3a,0xef,0x56,0x95, |
3795 | | 0xef,0x36,0xd5,0xcf,0x80,0xca,0x37,0x42,0xf9,0xa9,0xa4,0xfa,0xb9,0x5d,0xe5,0xfc, |
3796 | | 0x84,0xca,0xf9,0x33,0xf5,0xe3,0x6f,0xab,0x7c,0x03,0x2a,0xdf,0x08,0xd5,0xa7,0x29, |
3797 | | 0xea,0xc7,0x03,0x2a,0xd7,0x90,0xe2,0x8b,0x50,0xfa,0x43,0x4a,0x57,0xb4,0xf2,0x11, |
3798 | | 0xad,0x7c,0xc4,0x28,0x5c,0x01,0xe5,0xa3,0x90,0xfa,0xb3,0xcf,0xd5,0x1e,0x0b,0xa8, |
3799 | | 0x5e,0x15,0x51,0xfe,0x0a,0xa9,0xde,0x16,0x53,0x3f,0x5e,0x42,0xf1,0x16,0x51,0x7e, |
3800 | | 0x77,0x2a,0xbf,0x5f,0x28,0xbf,0xbb,0x94,0xdf,0x85,0x2a,0xe7,0x12,0xca,0x6f,0x29, |
3801 | | 0x9d,0xf7,0x54,0xd5,0xab,0xdd,0xca,0xef,0x2b,0x3a,0x5f,0x69,0xe5,0x33,0xa4,0x7c, |
3802 | | 0x46,0x2b,0x9f,0x0b,0x74,0xfe,0x73,0xd5,0x8f,0x9f,0xae,0xfa,0x73,0xba,0xea,0x4f, |
3803 | | 0x69,0x5d,0x97,0xb2,0xca,0xe7,0xb7,0xca,0xe7,0x59,0xaa,0xcf,0xe5,0xd5,0x8f,0x97, |
3804 | | 0xd5,0xf9,0xcb,0x2b,0xdf,0x9f,0x2b,0xdf,0xb1,0x0a,0x7f,0x8e,0xf6,0xc7,0xaa,0x3e, |
3805 | | 0x54,0x52,0xba,0xca,0x2a,0x1d,0xe7,0x78,0xe9,0x50,0x3f,0x5e,0x55,0xe5,0x70,0x9f, |
3806 | | 0xca,0xe1,0x4b,0x95,0xc3,0x1e,0x95,0xc3,0x57,0x2a,0x87,0x73,0x95,0x8e,0xaa,0x2a, |
3807 | | 0x87,0x38,0xe5,0x7f,0xaf,0xf2,0xff,0xa6,0xce,0xb3,0x56,0xf9,0x8f,0x51,0xfe,0x0b, |
3808 | | 0xe8,0xbc,0xab,0x75,0x7d,0xab,0xab,0x1f,0x8f,0x53,0x7b,0x48,0x55,0x3e,0xf6,0xa9, |
3809 | | 0x5f,0x4a,0x54,0x3c,0x5f,0xe8,0xba,0x25,0x2b,0xbd,0x35,0xd4,0xdf,0xa4,0xaa,0x7c, |
3810 | | 0x6a,0xe9,0xb8,0x7a,0x0a,0x57,0x43,0xe1,0xea,0xa8,0x5c,0xeb,0x2a,0x5f,0xb5,0x15, |
3811 | | 0xbe,0xbe,0xca,0xb7,0x81,0xea,0x55,0x43,0xe5,0xf7,0xa0,0xce,0xdb,0x48,0xed,0x6a, |
3812 | | 0xbf,0xea,0x4f,0x96,0xd2,0xd1,0x54,0xf1,0x37,0x51,0xfc,0x8d,0x15,0x7f,0x0b,0xc5, |
3813 | | 0xdf,0xcc,0x6b,0xa7,0x2a,0xb7,0x03,0x2a,0xb7,0x6f,0x54,0x6e,0xdf,0xaa,0xbd,0xb4, |
3814 | | 0x54,0xb9,0xb5,0xd2,0xf5,0xa9,0xae,0xf6,0xf2,0x9d,0xca,0xef,0x1d,0xf5,0xe7,0x6d, |
3815 | | 0x94,0xaf,0x75,0x2a,0xc7,0x42,0x2a,0xc7,0x22,0xea,0x8f,0xa6,0x28,0x3d,0x6b,0x54, |
3816 | | 0x9e,0xbb,0x95,0xfe,0x76,0xca,0x5f,0x07,0xe5,0xb7,0x9d,0xce,0xd3,0x51,0xf9,0xe8, |
3817 | | 0xa8,0xf8,0x8a,0x29,0xbe,0x12,0xba,0x2e,0x9d,0x94,0xaf,0x0e,0x2a,0xdf,0xce,0x3a, |
3818 | | 0xbe,0x93,0xea,0xd3,0xa5,0x8a,0xa7,0xab,0xe2,0xe9,0xaa,0xf3,0x77,0x57,0x3f,0x7d, |
3819 | | 0xba,0xfa,0xe9,0xce,0x0a,0xd7,0x47,0xf5,0xee,0x7e,0x85,0xef,0xa1,0xf0,0xfd,0x14, |
3820 | | 0xbe,0xb4,0xc2,0x77,0x57,0x39,0x0e,0x54,0x39,0x0e,0xf0,0xae,0x87,0xca,0xf1,0x90, |
3821 | | 0xca,0xf1,0x47,0x95,0x63,0x6f,0xd5,0xbf,0x3e,0x2a,0xc7,0x7e,0xaa,0x7f,0x87,0x55, |
3822 | | 0x7e,0x9f,0xab,0xbf,0x19,0xa0,0x7e,0x7d,0xa0,0xca,0xf1,0x3d,0xe5,0xbb,0x94,0xf2, |
3823 | | 0x7d,0xaa,0xca,0x71,0xa6,0xd2,0xf5,0x99,0xfa,0xf5,0xc1,0x2a,0xcf,0xc1,0x4a,0xd7, |
3824 | | 0x30,0xb5,0xcb,0xab,0xd4,0xaf,0x5f,0xa7,0x7a,0x73,0x83,0xd2,0x39,0x4a,0xe5,0x34, |
3825 | | 0x46,0xf5,0xf8,0x2a,0xe5,0xff,0x66,0xe5,0x7f,0xac,0xd2,0xf3,0x80,0x8e,0xbb,0x45, |
3826 | | 0xd7,0xe7,0x36,0xed,0xbf,0x43,0xf1,0x1c,0x50,0x3c,0x3f,0x29,0xbf,0xc3,0x54,0x0f, |
3827 | | 0x0f,0xaa,0xdf,0x49,0x56,0xff,0x3e,0x5e,0xc7,0xfd,0xa2,0xfc,0x7e,0xaf,0xf8,0x27, |
3828 | | 0x29,0xfe,0x6f,0x15,0xcf,0x35,0xba,0x6e,0x77,0xe9,0x7c,0x23,0x54,0x0e,0xd7,0x2b, |
3829 | | 0xbf,0xf7,0xa8,0xbc,0x27,0xea,0xfc,0x7b,0xca,0xba,0xc7,0x8d,0x35,0xcf,0x38,0xe6, |
3830 | | 0xb9,0xbd,0xac,0xeb,0xff,0xb4,0xe2,0x7b,0x52,0xf9,0x7f,0xb6,0x8c,0x7b,0xde,0xa9, |
3831 | | 0x4a,0xd7,0x27,0xaa,0x77,0x87,0xa4,0x87,0x75,0x7d,0xb6,0xca,0x9d,0x4f,0xf1,0x2f, |
3832 | | 0x51,0x3c,0x8b,0x14,0xcf,0xeb,0x8a,0x67,0x99,0xfc,0xe3,0xbd,0xe7,0x21,0xb9,0xd7, |
3833 | | 0x2a,0xdc,0x07,0x0a,0xf7,0x9e,0xfc,0xcf,0xd3,0x79,0xab,0xa9,0xdd,0x9c,0x2f,0x77, |
3834 | | 0x95,0xa0,0xbb,0xff,0xe7,0x80,0x1b,0xcf,0x26,0x9d,0x7f,0x83,0xd2,0xf3,0xbe,0xf2, |
3835 | | 0xff,0xa1,0xf6,0x3f,0xa3,0xf8,0x9e,0xd2,0x79,0xa6,0xeb,0x3c,0xd3,0x14,0xdf,0x66, |
3836 | | 0x1d,0xff,0xa3,0xf4,0x27,0xc5,0xb3,0x4d,0xee,0x18,0xa5,0x77,0xa9,0xe2,0x59,0xac, |
3837 | | 0x78,0xde,0x50,0x3c,0xaf,0xc9,0xbf,0xba,0xc2,0xad,0x97,0xfb,0x5d,0x85,0xdb,0xa0, |
3838 | | 0x70,0xef,0xcb,0xbf,0xa5,0xce,0x1b,0xa7,0x7c,0xb5,0x92,0xbb,0xaa,0xf2,0xf5,0x8b, |
3839 | | 0xd2,0x9d,0xa3,0xf3,0x6f,0x54,0x7a,0x3e,0x50,0xbe,0x3e,0xd2,0xfe,0x99,0x8a,0xef, |
3840 | | 0x05,0x9d,0xe7,0x45,0x9d,0x67,0xb6,0xd2,0x31,0x4b,0xfb,0x67,0x68,0xff,0x5c,0xed, |
3841 | | 0x9f,0xa3,0xfd,0x25,0xb5,0xff,0x14,0xb9,0x4b,0xc9,0x7d,0xaa,0xdc,0xad,0xe5,0xbe, |
3842 | | 0x40,0xee,0x36,0x72,0xb7,0x55,0x3d,0xbb,0x5c,0xda,0x43,0xda,0x53,0xda,0x4b,0xe1, |
3843 | | 0x86,0x7b,0xcf,0x21,0xaa,0xc7,0xd7,0x48,0xaf,0x55,0xb8,0x87,0x14,0x6f,0x8e,0xc2, |
3844 | | 0x7d,0xa4,0x74,0x6e,0x51,0x3a,0x3f,0x51,0x3d,0xdf,0xaa,0x70,0x1f,0x2b,0xdc,0x26, |
3845 | | 0x85,0xfb,0x54,0xe1,0x36,0x2b,0xdc,0x36,0x85,0xdb,0xa5,0x70,0x3b,0x15,0xee,0x2b, |
3846 | | 0x85,0xfb,0x52,0xe1,0xf6,0x29,0xdc,0x6e,0x85,0xfb,0x42,0xe1,0xf6,0x2a,0xdc,0x1e, |
3847 | | 0x85,0xdb,0xaf,0xfe,0xec,0x2b,0x95,0xff,0x97,0xd2,0x3d,0xd2,0x2d,0xd2,0x4f,0xd5, |
3848 | | 0x3f,0x9d,0xa9,0xfb,0xf5,0x59,0xba,0x9e,0x09,0x41,0x57,0x13,0x83,0x6e,0x3c,0x7b, |
3849 | | 0x75,0xdd,0x5e,0x56,0xfb,0xbb,0x29,0xc2,0xdd,0xbf,0xa0,0xac,0x7b,0xdc,0x7c,0xb4, |
3850 | | 0x84,0x69,0x47,0x68,0x49,0x53,0xef,0xd0,0x2c,0xf3,0xbb,0x52,0xed,0x73,0xa5,0x8e, |
3851 | | 0x1b,0x17,0xe1,0x86,0x3b,0x4d,0xe1,0x4e,0xd7,0xfe,0x55,0xda,0x7f,0x8b,0xf6,0x57, |
3852 | | 0xd6,0xfe,0x73,0x15,0xcf,0x5b,0x0a,0xf7,0x91,0xc2,0xdd,0xaa,0xf3,0x7f,0xa8,0xf3, |
3853 | | 0x6f,0x2c,0xeb,0x5e,0x9f,0x67,0x75,0x7c,0x4d,0x1d,0x9f,0xae,0xe3,0x7e,0xd0,0x71, |
3854 | | 0xb7,0x6b,0x7f,0x53,0xed,0x6f,0x26,0xfd,0x52,0xe1,0x76,0x29,0xdc,0x9d,0x8a,0xff, |
3855 | | 0x0b,0xc5,0xbf,0x53,0xf1,0x4f,0x8f,0x70,0xc3,0x77,0x54,0xf8,0x43,0x0a,0x3f,0x5e, |
3856 | | 0xf1,0x5e,0xa1,0xf8,0x7a,0x2b,0xdd,0x87,0xa5,0x2f,0x4a,0x5f,0xd7,0x71,0xd9,0x3a, |
3857 | | 0xee,0x39,0x9d,0x67,0x96,0xce,0x33,0x53,0xe5,0xe8,0x28,0x9e,0x40,0x59,0xb7,0x9f, |
3858 | | 0x7b,0x49,0xc7,0xcf,0xd1,0xf1,0x83,0x74,0xfc,0xf3,0x3a,0x6f,0x51,0x85,0x2f,0xa6, |
3859 | | 0xfd,0x43,0xb4,0xff,0x05,0xed,0x2f,0xa7,0xfd,0xe5,0x15,0xdf,0x72,0xc5,0xf7,0x9a, |
3860 | | 0xc2,0x0f,0x55,0xf8,0x19,0x4a,0xcf,0xbb,0x4a,0xcf,0x5a,0xe5,0x7b,0x95,0xe2,0x49, |
3861 | | 0x50,0x3c,0x89,0x8a,0xe7,0x03,0x1d,0x3f,0x5c,0xc7,0xbf,0xa5,0x70,0x19,0x0a,0xd7, |
3862 | | 0x40,0xf9,0xd9,0x2e,0xf7,0x67,0x0a,0x7f,0x8d,0xc2,0xaf,0xd1,0xf9,0x3e,0xd5,0xf9, |
3863 | | 0xb6,0xe8,0x7c,0xab,0x15,0x4f,0x6b,0x1d,0xd7,0x46,0xe7,0xdb,0xa1,0xe3,0x47,0xe8, |
3864 | | 0xf8,0xb7,0x15,0xae,0x8b,0xc2,0x75,0x55,0xb8,0xef,0x94,0xbf,0x03,0x0a,0xbf,0x4e, |
3865 | | 0xe1,0x27,0xe8,0xbe,0xb1,0x41,0xfe,0x5b,0xe5,0x3f,0x53,0xfe,0x9f,0xeb,0xb8,0x6f, |
3866 | | 0xe4,0xbf,0x3e,0xc2,0x4d,0xcf,0x7b,0xd2,0xe8,0x48,0x95,0x4b,0xa4,0xeb,0x5e,0x17, |
3867 | | 0xe9,0x86,0x8b,0x88,0x74,0xe3,0x73,0xb4,0xff,0x03,0xed,0x0f,0xc8,0xbd,0x54,0xee, |
3868 | | 0x1c,0xe9,0x27,0x0a,0x5f,0x28,0x52,0xf7,0x21,0x85,0x3b,0x5d,0xfb,0xb7,0x2b,0xde, |
3869 | | 0x82,0x72,0xef,0x50,0xb8,0xaf,0x14,0xae,0xb0,0xfc,0xf7,0x45,0xba,0xcf,0x0f,0x5f, |
3870 | | 0xcb,0xfd,0x8d,0xf4,0x07,0xe9,0x97,0x0a,0xff,0xae,0xdc,0xeb,0x15,0x6f,0x5b,0x9d, |
3871 | | 0xbf,0xb5,0xf6,0x6f,0xd0,0xfe,0x36,0x72,0x2f,0x93,0xfb,0x63,0xe9,0x66,0x85,0xbf, |
3872 | | 0x54,0xe9,0xd8,0xa6,0x70,0xe9,0xda,0xff,0x99,0xe2,0xbd,0x44,0xee,0xcf,0x15,0x6e, |
3873 | | 0xaf,0xc2,0x5d,0x26,0xff,0xfd,0x4a,0xef,0x01,0xb9,0xbf,0x95,0x1e,0x94,0xee,0x91, |
3874 | | 0x76,0x88,0x74,0x9f,0x83,0x86,0x4a,0x87,0xc9,0xff,0x23,0xe9,0x26,0xe9,0x2e,0xe9, |
3875 | | 0x6e,0xb4,0x6d,0x94,0xe3,0x54,0x80,0x0b,0x21,0x16,0xda,0xc1,0x39,0x72,0x9f,0x2d, |
3876 | | 0xad,0x28,0x5d,0x26,0x5d,0x2f,0x5d,0x02,0x75,0x62,0xe8,0x6f,0x62,0x5c,0x4d,0x94, |
3877 | | 0xa6,0xc0,0x22,0x58,0x0d,0x1b,0xe0,0x2d,0xa8,0x57,0x80,0xe7,0x69,0x68,0x0f,0x4d, |
3878 | | 0xa1,0x03,0x9c,0x07,0x1b,0xe0,0x5e,0x58,0x04,0xab,0xe4,0x7e,0x4b,0xee,0xd5,0x26, |
3879 | | 0x7c,0x41,0xc2,0xc3,0xfb,0xb0,0x04,0x96,0xc1,0x2a,0xb9,0x57,0xc0,0x07,0xb0,0x52, |
3880 | | 0xee,0xd5,0x50,0xaf,0x90,0xe3,0x34,0x87,0x0e,0x70,0x5e,0x21,0xd7,0xdd,0x02,0x56, |
3881 | | 0xc1,0x47,0xf0,0x0e,0xe4,0xc0,0x66,0xf8,0x44,0xfe,0x1f,0x43,0x7c,0x51,0xf2,0x09, |
3882 | | 0xa9,0xa5,0x29,0xfb,0xd2,0xae,0xe6,0x93,0xe6,0x97,0x16,0x94,0x16,0x96,0x16,0x97, |
3883 | | 0xd6,0x96,0xd6,0x95,0x66,0x48,0x1b,0x48,0x1b,0x96,0x76,0xaf,0x6b,0x4d,0xdd,0x27, |
3884 | | 0xd2,0xa5,0x97,0x48,0x2f,0xd5,0xfd,0xf1,0x0a,0x69,0x6f,0x3d,0x6f,0x3e,0xa7,0xfb, |
3885 | | 0xcb,0x4b,0x72,0x3f,0x2f,0xf7,0x3c,0xb9,0x97,0x4b,0x57,0x48,0x37,0x4a,0x3f,0xd4, |
3886 | | 0xfd,0x2e,0xa8,0xf6,0x18,0xa9,0xf6,0x1d,0xa5,0x76,0x3a,0x52,0xed,0x38,0x42,0xfb, |
3887 | | 0x43,0xda,0x1f,0xad,0xfd,0xa3,0xa4,0xa3,0xa5,0x63,0xa4,0x37,0x4a,0xc7,0x4a,0x6f, |
3888 | | 0x92,0xde,0xac,0xf8,0xf2,0x2b,0xbe,0x82,0x8a,0xaf,0xb0,0xf6,0x8f,0xd3,0xfe,0x02, |
3889 | | 0xda,0x5f,0x48,0xfb,0x8b,0x68,0xff,0x2d,0xd2,0x5b,0xa5,0xb7,0x49,0x6f,0x97,0xde, |
3890 | | 0x21,0xbd,0x53,0x3a,0x5e,0xf1,0x15,0x57,0x7c,0x25,0xe5,0x2e,0x21,0x77,0x29,0xb9, |
3891 | | 0xcf,0x90,0xfb,0x4c,0xb9,0x4b,0xcb,0x7d,0x96,0xdc,0x15,0xe4,0x3e,0x5b,0xe9,0xa9, |
3892 | | 0xa8,0xf8,0x27,0x68,0x7f,0xac,0xf6,0x9f,0xa3,0xfd,0x95,0xb4,0xff,0x2e,0xe9,0xdd, |
3893 | | 0xd2,0x7b,0xa4,0xf7,0x4a,0x27,0x4a,0xef,0x93,0xde,0xaf,0xf8,0xaa,0x28,0xbe,0x6a, |
3894 | | 0x8a,0x2f,0x5e,0xfb,0x1f,0xd0,0xfe,0xaa,0xda,0x1f,0xa7,0xfd,0xd5,0xb5,0x7f,0x92, |
3895 | | 0xf4,0x41,0xe9,0x43,0xd2,0x87,0xa5,0x8f,0x48,0x1f,0x95,0x3e,0xa6,0xf8,0x92,0x14, |
3896 | | 0x5f,0x8a,0xe2,0x4b,0x93,0x7f,0xb2,0xfc,0x53,0xe5,0x5f,0x43,0xfe,0xb5,0xe4,0x5f, |
3897 | | 0x47,0xfe,0xf5,0xe4,0x5f,0x5b,0xfe,0x75,0xe5,0x5f,0x5f,0xfe,0x99,0xf2,0x6f,0x24, |
3898 | | 0x77,0x43,0xb9,0xb3,0xe4,0x6e,0x2e,0xf7,0x79,0x72,0xb7,0x90,0xbb,0xa5,0xdc,0x17, |
3899 | | 0xc8,0x7d,0xa1,0xe2,0x6d,0x2f,0xff,0xb6,0xf2,0x6f,0x27,0xff,0x0e,0xf2,0xef,0x24, |
3900 | | 0xff,0x4b,0xe5,0xdf,0x59,0xfe,0xdd,0xe4,0x7f,0xb9,0xfc,0x7b,0xaa,0x1c,0x26,0x6b, |
3901 | | 0x7f,0x77,0xed,0xef,0xa1,0xfd,0xbd,0xb4,0x7f,0x8a,0xf4,0x71,0xe9,0x13,0xd2,0x27, |
3902 | | 0xa5,0x4f,0x49,0x9f,0x96,0x3e,0xa3,0xf8,0xae,0x54,0x7c,0x7d,0x15,0x5f,0x7f,0xed, |
3903 | | 0x9f,0xaa,0xfd,0x7d,0xb4,0xbf,0x9f,0xf6,0x0f,0xd0,0xfe,0x69,0xd2,0x67,0xa5,0xd3, |
3904 | | 0xa5,0xcf,0x49,0x9f,0x97,0xbe,0x20,0x9d,0x21,0x9d,0x2d,0x5d,0x26,0xfd,0x5a,0x3a, |
3905 | | 0x4f,0xe7,0x5b,0xe3,0xdd,0xd7,0x75,0xbe,0x77,0xb4,0x7f,0x85,0xf4,0x7b,0x85,0xfb, |
3906 | | 0x58,0xe1,0x3e,0x51,0xb8,0xcd,0x65,0xdd,0x71,0x9d,0x07,0xcb,0xbb,0xfa,0x90,0xf4, |
3907 | | 0x05,0xe9,0x1a,0xe9,0x3b,0xd2,0xb7,0xa5,0x91,0x1a,0x0f,0x8a,0x91,0x16,0x94,0x9e, |
3908 | | 0x2d,0xad,0x28,0x6d,0x20,0x6d,0x24,0x6d,0x22,0x6d,0x26,0xed,0x27,0xed,0x26,0xcd, |
3909 | | 0x96,0x0e,0x94,0x0e,0x91,0x5e,0x25,0x1d,0x2e,0xbd,0x5a,0x3a,0x52,0x3a,0x4a,0xba, |
3910 | | 0x45,0xfa,0xa9,0xf4,0x46,0xe9,0x58,0xe9,0x38,0xe9,0x2d,0xd2,0xad,0xd2,0x6d,0xd2, |
3911 | | 0xe7,0xa4,0xcf,0x4b,0x5f,0x90,0xce,0x90,0xee,0x92,0xee,0x96,0x7e,0x29,0xdd,0x83, |
3912 | | 0x4e,0x4a,0xa0,0xfd,0x27,0xb8,0x7a,0x9e,0xf4,0x7c,0x69,0x6b,0xe9,0x05,0xd2,0x0b, |
3913 | | 0xa5,0xed,0xa5,0x17,0x49,0x2f,0x96,0x5e,0x22,0xbd,0x4c,0xda,0x45,0xda,0x4d,0xda, |
3914 | | 0x43,0xda,0x4b,0xda,0x5b,0x9a,0x0d,0x0f,0xc2,0x40,0xb9,0x07,0xcb,0x3d,0x44,0xee, |
3915 | | 0xa1,0x72,0x0f,0x93,0xfb,0x6a,0xb9,0xaf,0x91,0x7b,0x84,0xdc,0xd7,0xc9,0xfd,0xa8, |
3916 | | 0xf4,0x1b,0xe9,0x73,0xd2,0x17,0xa4,0x33,0xa5,0xb3,0xa5,0x2f,0x4a,0x5f,0x92,0xce, |
3917 | | 0x97,0xbe,0x2c,0x7d,0x55,0xba,0x48,0xba,0x44,0xba,0x4c,0xfa,0x86,0x74,0x85,0xf4, |
3918 | | 0x4d,0xe9,0x5a,0xa5,0xeb,0x5d,0xb9,0xd7,0xcb,0xfd,0x9e,0xdc,0x1f,0xc8,0xbd,0x41, |
3919 | | 0xee,0x0f,0xe5,0xfe,0x48,0xee,0x1c,0xb9,0x3f,0x96,0xfb,0x7b,0xe9,0x0f,0xd2,0x83, |
3920 | | 0xd2,0x43,0xd2,0x9f,0x4d,0x9a,0x8b,0x06,0x9c,0x07,0xc1,0xe8,0xc3,0xd2,0xe9,0x50, |
3921 | | 0xa9,0x58,0xc0,0x89,0x2f,0xe6,0x6a,0x75,0xa8,0x57,0x22,0xe0,0xb4,0x80,0x0e,0x70, |
3922 | | 0x1e,0xcc,0x2c,0x19,0x70,0x5e,0x85,0x97,0xe1,0x15,0x58,0x08,0x8b,0x60,0x46,0x29, |
3923 | | 0xfc,0x4a,0xb9,0xfa,0x0a,0x24,0x9c,0x1e,0x70,0x6a,0x02,0xa7,0x72,0xd2,0xa1,0x01, |
3924 | | 0x5c,0x0c,0x9d,0x45,0x57,0xb8,0x06,0x9e,0x15,0x73,0xc5,0x3c,0xf1,0xb2,0x30,0x63, |
3925 | | 0xb1,0x66,0xbc,0x68,0xa3,0xe3,0xbe,0x67,0xfc,0xc1,0xf8,0xf3,0xbb,0xf3,0x15,0xf1, |
3926 | | 0x2a,0x2c,0x86,0x25,0xf0,0x1a,0xbc,0x0e,0xf7,0xf0,0xfb,0xf4,0x5e,0x98,0x08,0xf7, |
3927 | | 0xc1,0x0c,0x98,0x09,0x4b,0x61,0x39,0xbc,0x0b,0x5b,0x60,0x3b,0x7c,0x29,0xbe,0x12, |
3928 | | 0xa6,0x1f,0x19,0x60,0xda,0xaa,0x79,0x8f,0x66,0xda,0xa8,0x18,0x6a,0x9e,0x37,0xcd, |
3929 | | 0x6f,0x14,0x71,0xad,0x79,0x9f,0x66,0xde,0xa5,0x89,0x9b,0xc4,0xcd,0x62,0x9c,0x7e, |
3930 | | 0x8f,0xde,0x2e,0xcc,0x6f,0xc7,0x29,0xa6,0x0f,0x36,0xcf,0xb7,0xa6,0xcf,0x32,0xed, |
3931 | | 0x9a,0xe7,0xd3,0x31,0x70,0x33,0xdc,0x0a,0xd5,0x43,0x3c,0x63,0x42,0x7b,0xe8,0x28, |
3932 | | 0xba,0xc0,0x38,0xb8,0x0b,0x16,0xc2,0x62,0xb1,0x14,0x96,0xc1,0xeb,0xf0,0x06,0xac, |
3933 | | 0x10,0x6b,0x61,0x17,0xec,0x85,0xaf,0xa1,0x28,0xcf,0xb0,0x67,0x40,0x39,0xa8,0x0f, |
3934 | | 0x19,0xa2,0x01,0x34,0x87,0x16,0xd0,0x19,0xba,0x40,0x6f,0xe8,0x0f,0x03,0x20,0x5b, |
3935 | | 0x0c,0xd4,0xf3,0xf0,0xfb,0xe2,0x03,0xc8,0x81,0xcd,0xb0,0x1d,0x3e,0x83,0x1d,0xf0, |
3936 | | 0x39,0xec,0x84,0x5d,0xb0,0x07,0xbe,0x82,0xbd,0xb0,0x0f,0x0e,0xc2,0x21,0x38,0x0c, |
3937 | | 0xbf,0x88,0xa2,0xd1,0x2e,0xc5,0x44,0x71,0xa8,0x0e,0x09,0xd0,0x1c,0x5a,0xc2,0x53, |
3938 | | 0xf0,0x34,0xcc,0x84,0x59,0x62,0x09,0xbc,0x09,0xab,0x60,0x17,0xec,0x86,0x03,0xf0, |
3939 | | 0x0d,0x7c,0x0b,0x87,0xc4,0x4f,0xc2,0xc9,0xc7,0xf3,0x12,0x9c,0x02,0xa7,0xc3,0x19, |
3940 | | 0xa2,0x34,0xc4,0xc2,0xd9,0xe2,0x1c,0xa8,0x04,0x95,0xc5,0xb9,0x10,0x07,0x19,0x70, |
3941 | | 0x11,0x74,0x84,0x4e,0xd0,0x05,0xae,0x84,0x6c,0xb8,0x19,0x6e,0x81,0xf1,0x70,0x3f, |
3942 | | 0x3c,0x06,0x93,0x61,0x25,0xbc,0x29,0x56,0xc1,0xa7,0xb0,0x0d,0x82,0xfc,0x4e,0x88, |
3943 | | 0x10,0x91,0x90,0x0e,0xb5,0x44,0x6d,0x51,0x47,0xd4,0x15,0xf5,0x20,0x03,0x1a,0x40, |
3944 | | 0x53,0x68,0x06,0xe7,0x41,0x4b,0x71,0x3e,0xb4,0x82,0xd6,0xa2,0x0d,0x74,0x80,0x8b, |
3945 | | 0xa0,0x2b,0x74,0x83,0xee,0xd0,0x13,0x06,0xc0,0x40,0x31,0x08,0x46,0xc2,0x28,0x31, |
3946 | | 0x1a,0xc6,0xc0,0x58,0xb8,0x1d,0xc6,0xc3,0x04,0xb8,0x07,0xa6,0xc2,0xb3,0x30,0x13, |
3947 | | 0x66,0x8b,0x97,0x60,0x01,0xbc,0x2a,0x16,0x0a,0xf3,0xbb,0x68,0x09,0x2c,0x85,0xd7, |
3948 | | 0x61,0x05,0xac,0xd4,0x6f,0x25,0xf3,0x3b,0x69,0x8d,0x78,0x5b,0x6c,0x10,0x39,0xf0, |
3949 | | 0x31,0x6c,0x86,0x4f,0x61,0x2b,0x6c,0x83,0x1d,0xb0,0x17,0xf6,0xc1,0x7e,0x38,0x2c, |
3950 | | 0x7e,0x16,0x81,0xfc,0x94,0x2b,0x44,0x88,0x10,0xe4,0x87,0x22,0x50,0x14,0x4a,0x40, |
3951 | | 0x65,0xa8,0x02,0x09,0x90,0x04,0xc9,0x90,0x0a,0x69,0x50,0x13,0xd2,0xa1,0x8e,0xa8, |
3952 | | 0x07,0x19,0xd0,0x00,0x32,0xa1,0x09,0x34,0x85,0x16,0xd0,0x12,0xda,0x88,0x8e,0x70, |
3953 | | 0x09,0x5c,0x26,0x7a,0xc2,0x00,0xc8,0x86,0x81,0x30,0x08,0x86,0xc0,0x55,0x62,0x14, |
3954 | | 0x8c,0x86,0x31,0x62,0x2c,0xdc,0x01,0xe3,0xe1,0x2e,0xb8,0x07,0xa6,0xc2,0xb3,0x30, |
3955 | | 0x13,0x66,0xc3,0x1c,0x98,0x0b,0x0b,0xe0,0x55,0xb1,0x50,0x2c,0x82,0x25,0xb0,0x14, |
3956 | | 0xde,0x80,0x15,0xb0,0x12,0xde,0x14,0xab,0xe1,0x2d,0x58,0x23,0xd6,0x8a,0x2d,0xf0, |
3957 | | 0x29,0x6c,0x85,0x6d,0xb0,0x03,0xf6,0xc2,0x41,0x71,0x08,0x7e,0x81,0x40,0x01,0x97, |
3958 | | 0x20,0x44,0x40,0x08,0x0a,0x42,0x11,0x28,0x0a,0x25,0xa0,0x32,0x54,0x81,0x04,0x48, |
3959 | | 0x82,0x64,0x48,0x85,0x74,0xa8,0x23,0xea,0x8a,0x7a,0xa2,0xbe,0xc8,0x10,0x0d,0xa0, |
3960 | | 0x11,0x34,0xd1,0xef,0xe6,0x16,0xfa,0xdd,0xdc,0x52,0xb4,0xd3,0x6f,0xea,0x0e,0xe2, |
3961 | | 0x12,0xb8,0x14,0x3a,0x43,0x57,0xe8,0x06,0xdd,0xa1,0x27,0x0c,0x80,0x81,0x62,0xb4, |
3962 | | 0x18,0x23,0xc6,0xc2,0xad,0x70,0x27,0x4c,0x80,0xbb,0x61,0x22,0x4c,0x82,0x07,0xe1, |
3963 | | 0x61,0xf1,0x28,0x3c,0x06,0x4f,0xc0,0x93,0x30,0x15,0x9e,0x85,0x17,0x60,0x81,0x7e, |
3964 | | 0xb7,0x2f,0x86,0x25,0x62,0x29,0x2c,0x83,0xe5,0xb0,0x52,0xbf,0xf1,0xcd,0xef,0xfb, |
3965 | | 0x35,0x62,0xad,0xd8,0x20,0x76,0xc0,0xde,0x02,0x66,0x40,0xd9,0x25,0x00,0x11,0x10, |
3966 | | 0x29,0x42,0x50,0x10,0x0a,0x43,0x51,0x28,0x0e,0x95,0xa1,0x0a,0xa4,0x43,0x1d,0x51, |
3967 | | 0x57,0xd4,0x83,0x0c,0x68,0x00,0x8d,0xa0,0xb1,0xde,0x27,0x34,0x87,0x96,0xd0,0xae, |
3968 | | 0xa0,0xfb,0x8e,0xe1,0x22,0xb8,0x18,0x2e,0x81,0x4b,0xa1,0x0b,0x74,0x85,0x6e,0xd0, |
3969 | | 0x1d,0x7a,0xc2,0x00,0x18,0x29,0x46,0x89,0xd1,0x30,0x06,0xc6,0xc2,0xed,0x70,0x27, |
3970 | | 0x4c,0x80,0xbb,0x61,0x2a,0x3c,0x0b,0x73,0x60,0x2e,0x2c,0x80,0x57,0xc5,0x42,0xb1, |
3971 | | 0x48,0x2c,0x16,0xe6,0x1d,0xc7,0xeb,0xb0,0x5c,0xac,0xd0,0xfb,0x8d,0x55,0x7a,0xbf, |
3972 | | 0xf1,0x16,0xac,0xd1,0xfb,0x0e,0xf3,0xee,0x23,0x07,0x3e,0x81,0x2d,0xf0,0x29,0x6c, |
3973 | | 0x85,0x6d,0xb0,0x03,0xf6,0xc2,0x7e,0xf8,0x1a,0x0e,0x08,0xa7,0x10,0x65,0x0a,0x41, |
3974 | | 0x88,0x80,0x48,0x28,0x08,0x85,0xa1,0x28,0x14,0x87,0x5a,0x50,0x1b,0xea,0x40,0x5d, |
3975 | | 0x61,0xde,0xa3,0x64,0x40,0x03,0x68,0x04,0x8d,0xa1,0xa9,0xde,0xb5,0x98,0xf7,0x2c, |
3976 | | 0x2d,0xc5,0xf9,0xe2,0x42,0x68,0xaf,0xf7,0x30,0x86,0xce,0xd0,0x15,0xba,0x41,0x77, |
3977 | | 0xe8,0x09,0x03,0xe0,0x1a,0xb8,0x01,0x46,0x89,0xd1,0x30,0x06,0xc6,0xc2,0x7d,0xf0, |
3978 | | 0x20,0xcc,0x82,0x39,0xf0,0x0a,0x2c,0x14,0x4b,0x60,0xb9,0xde,0xdf,0xac,0xd2,0x7b, |
3979 | | 0x9d,0x77,0x61,0x1d,0xbc,0x07,0x1f,0x88,0x8d,0x7a,0xd7,0xb3,0x03,0xf6,0xc2,0xd7, |
3980 | | 0x70,0xc0,0x94,0x41,0x61,0xda,0x25,0x24,0x8a,0x24,0x48,0x86,0x14,0xa8,0x05,0x19, |
3981 | | 0x90,0x05,0x8d,0x45,0x13,0x38,0x1f,0x5a,0x43,0x47,0x18,0x05,0xa3,0xe1,0x46,0x71, |
3982 | | 0x13,0xdc,0x0a,0xb7,0xc3,0x13,0xf0,0x94,0x78,0x06,0x66,0xc2,0x2c,0x31,0x1b,0xe6, |
3983 | | 0xc0,0x8b,0xf0,0x2a,0x2c,0x14,0x4b,0xe0,0x75,0x58,0x2e,0x56,0xc2,0xdb,0xb0,0x16, |
3984 | | 0x3e,0x84,0x1c,0xd8,0x0c,0x4e,0x11,0x97,0xd3,0xe0,0x74,0x28,0x07,0xe7,0x42,0xaa, |
3985 | | 0xa8,0x21,0xd2,0x45,0x3d,0xa8,0x0f,0x19,0xd0,0x04,0x9a,0x41,0x5f,0x18,0x08,0xd7, |
3986 | | 0xc3,0x0d,0x62,0x24,0xdc,0x08,0x37,0xc1,0xcd,0x30,0x0e,0x6e,0x87,0x3b,0xe0,0x7e, |
3987 | | 0x98,0x04,0xaf,0xc2,0x72,0xe1,0x14,0xa5,0xcd,0x41,0x55,0xa8,0x06,0x71,0x90,0x00, |
3988 | | 0x89,0x22,0x09,0x6a,0x40,0x4d,0x91,0x0e,0xb5,0xa0,0x36,0xd4,0x81,0xba,0x50,0x0f, |
3989 | | 0xea,0x8b,0x0c,0x68,0x06,0xad,0xa1,0x1d,0xb4,0x87,0x0e,0x70,0x11,0x74,0x84,0x8b, |
3990 | | 0xe1,0x52,0xb8,0x0c,0xba,0x40,0x57,0xd1,0x0d,0x2e,0x87,0x1e,0xd0,0x13,0x7a,0x41, |
3991 | | 0x3f,0xe8,0x0f,0xd9,0x30,0x10,0x86,0xc0,0x55,0x30,0x0a,0x46,0x8b,0x31,0x70,0x23, |
3992 | | 0x8c,0x85,0x9b,0xe0,0x66,0xb8,0x1d,0xee,0x10,0x77,0x8a,0xf1,0x62,0x02,0x4c,0x82, |
3993 | | 0x07,0xe1,0x61,0x78,0x44,0x4c,0x86,0x37,0x60,0x85,0x58,0x23,0xd6,0xc2,0x21,0x38, |
3994 | | 0x2c,0x7e,0x82,0x5f,0xc0,0x29,0x46,0xbb,0x29,0x4e,0xbb,0x81,0x96,0xd0,0x1a,0xda, |
3995 | | 0xc3,0x45,0xe2,0x62,0xb8,0x14,0xba,0xc0,0x38,0xb8,0x15,0xee,0x80,0x09,0x30,0x13, |
3996 | | 0x66,0xc3,0x5c,0x98,0x0f,0x8b,0x60,0x89,0x58,0x06,0x6f,0xc0,0x4a,0xf8,0x00,0x36, |
3997 | | 0x42,0xd1,0x12,0xb4,0x67,0x28,0x05,0xa7,0xc1,0xc5,0x70,0x29,0x74,0x86,0xde,0x30, |
3998 | | 0x10,0x46,0xc2,0x78,0x98,0x0c,0xdf,0xc2,0x0f,0xf0,0x13,0x04,0x4a,0x52,0x4f,0x4e, |
3999 | | 0xa1,0x8d,0xc2,0x0d,0x30,0x0a,0x1e,0x84,0xc9,0xb0,0x0b,0xbe,0x82,0x7d,0xb0,0x1f, |
4000 | | 0x7e,0x00,0xe7,0x54,0xb2,0x06,0xc5,0xa1,0x24,0x94,0x12,0x65,0x21,0x11,0x92,0x20, |
4001 | | 0x19,0x52,0x44,0x06,0xb4,0x81,0x0b,0xa0,0x2d,0x74,0x81,0xbe,0xd0,0x1f,0xb2,0x61, |
4002 | | 0x10,0x0c,0x86,0x91,0x30,0x07,0x5e,0x84,0xb9,0xf0,0x92,0x98,0x07,0x0b,0x61,0x11, |
4003 | | 0xbc,0x01,0xcb,0xc5,0x0a,0x58,0x09,0x6f,0xc2,0x7a,0xd8,0x20,0x72,0xc4,0xc7,0x62, |
4004 | | 0x0b,0x7c,0x01,0x05,0x4e,0xa3,0x4b,0x84,0x22,0xa2,0x28,0x9c,0x0e,0xe5,0x20,0x13, |
4005 | | 0x1a,0x8a,0x46,0x30,0x1c,0x46,0xc2,0x8d,0x30,0x16,0x6e,0x82,0x9b,0x61,0x2a,0x4c, |
4006 | | 0x13,0xcf,0x8a,0x99,0xf0,0x2d,0x38,0xa7,0x3b,0x4e,0x19,0x28,0x07,0x15,0x20,0x16, |
4007 | | 0x2a,0x42,0x25,0xa8,0x0c,0xe7,0x42,0x55,0x48,0x80,0x44,0x48,0x12,0xc9,0x50,0x13, |
4008 | | 0xd2,0xa1,0x36,0x34,0x86,0x56,0xd0,0x1a,0xfa,0x41,0x36,0x0c,0x81,0x91,0x30,0x1d, |
4009 | | 0x66,0xc2,0x9b,0xb0,0x16,0x3e,0x84,0x8f,0x84,0x73,0x06,0xcf,0xf6,0x70,0x2a,0x9c, |
4010 | | 0x06,0xa7,0xc3,0x19,0x50,0x5a,0x94,0x83,0x0b,0xa1,0x9d,0x68,0x2f,0x3a,0x88,0x8b, |
4011 | | 0xe0,0x32,0xe8,0x22,0xba,0x8a,0x6e,0xa2,0x3b,0x5c,0x0e,0x3d,0xa0,0x2f,0xf4,0x83, |
4012 | | 0x41,0x30,0x18,0x46,0xc0,0x0d,0x62,0x24,0xdc,0x02,0x13,0x60,0x12,0x3c,0x23,0x66, |
4013 | | 0xc2,0x42,0x58,0x0c,0x1f,0xc3,0x16,0xd8,0x0d,0x4e,0x69,0xee,0x4f,0xe6,0xbd,0xb9, |
4014 | | 0x08,0x41,0x32,0xa4,0x88,0x54,0x91,0x06,0xb5,0xf4,0x0e,0xde,0x50,0x47,0xd4,0xd5, |
4015 | | 0xfb,0xf7,0x4c,0x61,0xde,0xc1,0x37,0x82,0x2c,0x38,0x0f,0x5a,0x43,0x47,0xe8,0x03, |
4016 | | 0x83,0x61,0x24,0x8c,0x82,0xd1,0x62,0x0c,0x4c,0x86,0x29,0xe2,0x71,0x78,0x0a,0x9e, |
4017 | | 0x86,0x67,0x60,0x2a,0x4c,0x83,0x67,0xc5,0x74,0x78,0x1e,0x5e,0x80,0x19,0x30,0x13, |
4018 | | 0x16,0xc0,0xcb,0xf0,0x19,0xec,0x10,0x9f,0x8b,0x9d,0xf0,0x05,0xec,0x82,0x2f,0x61, |
4019 | | 0x8f,0xf8,0x4a,0xec,0x85,0xfd,0xf0,0x35,0x1c,0x00,0xe7,0x4c,0xea,0x0e,0x9c,0x0d, |
4020 | | 0x55,0xa1,0x1a,0x24,0x43,0x0a,0xa4,0x42,0x1a,0xd4,0x80,0x0c,0x68,0x06,0x2d,0xa1, |
4021 | | 0x15,0xb4,0x86,0x8e,0x70,0x31,0x0c,0x83,0xe1,0x70,0x1d,0x8c,0x84,0x5b,0x61,0x02, |
4022 | | 0xbc,0x0c,0x0b,0x61,0x31,0xac,0x85,0x75,0xf0,0x1e,0x6c,0x81,0x4f,0xc5,0x56,0xd8, |
4023 | | 0x09,0x5f,0xc0,0x97,0xb0,0x47,0x7c,0x05,0x07,0xe0,0x1b,0xf1,0x2d,0x7c,0x07,0xdf, |
4024 | | 0x8b,0x1f,0xe0,0x20,0x1c,0x12,0xce,0x59,0xa4,0x1f,0xaa,0xc1,0x95,0xd0,0x07,0x86, |
4025 | | 0xc1,0x70,0x71,0x35,0x3c,0x08,0x0f,0xc1,0x62,0x58,0x02,0xbf,0x9c,0xe5,0xce,0x01, |
4026 | | 0x37,0xef,0xf5,0xcd,0x18,0xb8,0x79,0x7f,0x6f,0xc6,0x66,0xcd,0x7b,0x66,0x33,0x26, |
4027 | | 0x6d,0xde,0x27,0x9b,0x31,0x4f,0xf3,0x9e,0xb8,0xa3,0xe8,0x24,0x2e,0x15,0xe6,0x5d, |
4028 | | 0xf1,0x75,0x65,0xdd,0xb1,0x0f,0x33,0xae,0x6c,0xc6,0x86,0xcd,0x38,0xfb,0x22,0x61, |
4029 | | 0xde,0xad,0x9a,0x71,0x66,0x33,0xc6,0x6b,0xc6,0xcd,0xcd,0x18,0xee,0xfa,0xb2,0xee, |
4030 | | 0x58,0xed,0xa6,0xb2,0xee,0x18,0xab,0x19,0xef,0x36,0xef,0x5e,0xcd,0x38,0xa7,0x19, |
4031 | | 0x2b,0x35,0xe3,0xd4,0x05,0xcb,0xd1,0x7f,0x40,0x7d,0xc8,0x80,0x0b,0xc5,0x40,0x71, |
4032 | | 0x83,0x98,0x00,0x0f,0xc3,0x5a,0xc8,0x81,0x4f,0xc5,0x67,0xb0,0x0f,0x82,0xe5,0x5d, |
4033 | | 0xa2,0x45,0x7e,0x28,0x01,0xa5,0xc4,0x69,0xe2,0x74,0x38,0x0b,0xce,0x16,0x15,0x45, |
4034 | | 0x65,0x51,0x05,0xe2,0x20,0x5e,0x54,0x87,0x14,0x48,0x35,0xef,0x6e,0x21,0x5d,0xd4, |
4035 | | 0x81,0xfa,0x90,0x05,0xcd,0xe0,0x7c,0xd1,0x05,0x46,0xc3,0x18,0xb8,0x11,0xc6,0xc2, |
4036 | | 0x38,0x70,0xaa,0x39,0xce,0xb5,0x30,0x02,0xae,0x83,0xeb,0x61,0x3b,0xec,0x86,0xaf, |
4037 | | 0x60,0x2f,0xec,0x87,0xaf,0xe1,0x00,0x38,0x71,0x8e,0x73,0x0e,0x54,0x12,0x71,0x22, |
4038 | | 0x01,0x7a,0xc1,0x00,0x71,0x83,0x18,0x09,0xf7,0xc1,0x64,0x78,0x1a,0xa6,0xc2,0x0b, |
4039 | | 0x30,0x13,0x5e,0x82,0xf9,0xb0,0x08,0x96,0xc0,0x72,0x58,0x09,0x6f,0xc3,0x5a,0xf8, |
4040 | | 0x00,0x36,0xc2,0x27,0xb0,0x05,0x7e,0x81,0x50,0x82,0x4b,0x94,0x88,0x16,0xe5,0xe1, |
4041 | | 0x5c,0xa8,0x02,0x71,0x10,0x0f,0xd5,0x21,0x11,0x52,0xa1,0x26,0xd4,0x82,0xda,0xa2, |
4042 | | 0x8e,0x68,0x00,0xf7,0xe9,0xfd,0xa0,0x79,0x97,0xf8,0x10,0x3c,0x0c,0x8f,0xe8,0x3d, |
4043 | | 0xe9,0x63,0x62,0x8a,0xde,0x23,0xfe,0x28,0x0e,0xeb,0x7d,0xe2,0x2f,0x22,0x94,0xc8, |
4044 | | 0xf9,0x20,0x11,0xee,0x84,0xc9,0xb0,0x18,0xf6,0xc1,0x2f,0xe0,0xa4,0xe0,0x6e,0x89, |
4045 | | 0x9e,0xcf,0x7d,0x74,0x32,0xd7,0x5e,0x9c,0x02,0xb7,0x3f,0x49,0x7e,0xe1,0x7b,0xf8, |
4046 | | 0x01,0x7e,0x02,0xe7,0x29,0xee,0x61,0x4f,0x53,0x0f,0x45,0x51,0x28,0x0b,0xe5,0xe0, |
4047 | | 0x5c,0xa8,0x02,0x55,0x21,0x03,0xfa,0x41,0x7f,0x31,0x40,0x0c,0x81,0xeb,0xe0,0x06, |
4048 | | 0x31,0x12,0x1e,0x82,0x87,0xe1,0x11,0x78,0x14,0x1e,0x83,0xc9,0xf0,0x19,0xec,0x80, |
4049 | | 0xbd,0xb0,0x0f,0xf6,0xc3,0xa9,0xcf,0x70,0x3e,0xa8,0x00,0x03,0x20,0x5b,0x0c,0x84, |
4050 | | 0x9b,0x61,0x9c,0xb8,0x0d,0xee,0x84,0xf1,0x62,0x02,0xe4,0xc0,0x7e,0xf8,0x06,0xbe, |
4051 | | 0x85,0xef,0xe0,0x7b,0xf1,0x03,0x1c,0x84,0x43,0xe2,0x47,0x08,0x4c,0xa5,0x8d,0x88, |
4052 | | 0x08,0x08,0x41,0x94,0x88,0x86,0xfc,0x50,0x40,0x14,0x84,0x0a,0x10,0x0b,0x67,0xc3, |
4053 | | 0x39,0x50,0x11,0x2a,0x89,0x6a,0x22,0x03,0x06,0xc3,0x48,0x18,0x05,0xa3,0x61,0x0e, |
4054 | | 0xbc,0x08,0xaf,0xc1,0xeb,0xf0,0x06,0xac,0x85,0x0f,0x61,0x0b,0xec,0x87,0xaf,0xe1, |
4055 | | 0x7b,0xf8,0x51,0xfc,0x04,0x3f,0xc3,0x2f,0xc2,0x99,0xe6,0x38,0x31,0x90,0x1f,0xce, |
4056 | | 0x81,0x8a,0x10,0x07,0x09,0xd0,0x18,0x9a,0x40,0x1b,0xb8,0x00,0xda,0x42,0x17,0x18, |
4057 | | 0x01,0x23,0x61,0x34,0x8c,0x11,0x37,0xc2,0x6c,0x98,0x23,0x5e,0x84,0xb9,0xf0,0x12, |
4058 | | 0x2c,0x80,0x97,0xe1,0x15,0x78,0x15,0x16,0xc2,0x22,0x58,0x02,0xef,0x88,0xb5,0xf0, |
4059 | | 0x21,0x6c,0x81,0xed,0xf0,0x99,0xd8,0x21,0x3e,0x87,0xbd,0xb0,0x0f,0x0e,0xc2,0x21, |
4060 | | 0xf8,0x79,0x9a,0xfb,0xd2,0xb9,0x32,0x9c,0x0b,0xf1,0x50,0x1d,0x12,0x20,0x11,0x92, |
4061 | | 0x20,0x19,0x52,0x20,0x15,0xd2,0x20,0x03,0x32,0xa1,0xa1,0x68,0x04,0x2d,0xe0,0x3c, |
4062 | | 0xd1,0x52,0xb4,0x86,0x8e,0xd0,0x05,0x06,0x40,0xb6,0x18,0x08,0x43,0xe1,0x1a,0x71, |
4063 | | 0xad,0x18,0x21,0xae,0x13,0xd7,0xc3,0x0c,0x98,0x29,0x66,0x89,0xd9,0xf0,0x22,0xcc, |
4064 | | 0x85,0x97,0x60,0x1e,0xcc,0x87,0x05,0xb0,0x10,0x16,0xc1,0x62,0x58,0x22,0x96,0x8a, |
4065 | | 0x65,0x62,0x13,0xe4,0xc0,0xc7,0x62,0x0b,0xec,0x82,0xdd,0xe2,0x4b,0xd8,0x03,0x5f, |
4066 | | 0xc1,0x5e,0xf8,0x5a,0x1c,0x80,0x6f,0xe0,0x5b,0xf1,0x9d,0x08,0x4c,0xa7,0x5e,0x42, |
4067 | | 0x0c,0x14,0x86,0x62,0x70,0x0a,0x94,0x83,0x8a,0x50,0x19,0xe2,0x21,0x01,0x2e,0x86, |
4068 | | 0x4b,0xa0,0x33,0x74,0x81,0x2b,0xa0,0xb7,0xc8,0x86,0xc5,0xb0,0x04,0xb6,0xc2,0x36, |
4069 | | 0xd8,0x0e,0x9f,0x89,0x1d,0xf0,0x39,0xec,0x14,0x5f,0xc0,0x2e,0xf8,0x52,0xec,0x11, |
4070 | | 0xfb,0xe0,0x20,0x38,0xcf,0xf1,0xfb,0x74,0x03,0x65,0x07,0xcb,0x61,0x35,0xfc,0x08, |
4071 | | 0x66,0x52,0x6e,0xbf,0x43,0x9c,0x0f,0x3e,0x34,0x13,0x73,0x7f,0x24,0xfd,0x50,0x02, |
4072 | | 0x4e,0x85,0xb3,0x44,0x19,0x51,0x16,0x2a,0x43,0x15,0x48,0x83,0x9a,0x50,0x07,0xea, |
4073 | | 0x89,0x0c,0x68,0x00,0x0d,0xa1,0x11,0x34,0x86,0x59,0xb0,0x1e,0xea,0xfe,0x44,0x3d, |
4074 | | 0x80,0xf1,0x70,0x37,0xac,0x80,0x7d,0xf0,0xa3,0x99,0x20,0xfb,0x33,0xcf,0xe1,0x50, |
4075 | | 0x0e,0xaa,0x43,0x32,0xa4,0x40,0x4b,0x68,0x05,0xd9,0x30,0x04,0x86,0xc2,0x61,0x28, |
4076 | | 0xfa,0x0b,0xf7,0x44,0x28,0x0f,0xb5,0xa0,0xbe,0x68,0x00,0x17,0x43,0x0f,0xd1,0x13, |
4077 | | 0x06,0x40,0xb6,0x18,0x08,0x8f,0xc0,0xa3,0xf0,0x18,0x4c,0x86,0x45,0xb0,0x0c,0x56, |
4078 | | 0xc0,0x2a,0x78,0x07,0xd6,0xc1,0x06,0xf8,0x08,0x72,0xcc,0xc4,0x5c,0x27,0xe0,0x14, |
4079 | | 0x80,0x42,0x50,0x11,0x2a,0x43,0x2d,0xa8,0x03,0x75,0xa1,0x3e,0xb4,0x84,0xd6,0x70, |
4080 | | 0x29,0x8c,0x84,0x43,0x90,0x11,0x08,0x38,0x43,0xe0,0x27,0x31,0x32,0x18,0x70,0x1e, |
4081 | | 0x86,0xc9,0xb0,0x16,0xb6,0x08,0xf3,0xb1,0x45,0x59,0x88,0x83,0x0c,0x68,0x20,0x32, |
4082 | | 0xa1,0x19,0x34,0x17,0xad,0xe1,0x2a,0x18,0x0a,0xd7,0xc0,0x48,0x78,0x04,0x26,0xc3, |
4083 | | 0x6b,0xb0,0x12,0xde,0x81,0x77,0xe1,0x7d,0xf3,0x01,0x47,0x64,0xc0,0x69,0x05,0xad, |
4084 | | 0xe1,0x11,0x98,0x0c,0xd3,0x60,0x26,0xac,0x87,0x8d,0xf0,0xa3,0xf9,0xc0,0x2e,0x14, |
4085 | | 0x70,0x2a,0x41,0x02,0x74,0x87,0x6c,0xb8,0x06,0x46,0xc0,0xad,0x70,0x3b,0xdc,0x0d, |
4086 | | 0xf7,0xc2,0x44,0xb8,0x1f,0xa6,0xc0,0x13,0x30,0x0b,0xe6,0xc0,0x02,0x78,0x05,0x5e, |
4087 | | 0x85,0x25,0x70,0xc0,0x7c,0xf0,0x11,0x15,0x70,0xd2,0xa2,0xc9,0x13,0xb4,0x83,0x2e, |
4088 | | 0xd0,0x0b,0x46,0xc2,0x58,0xb8,0x19,0x66,0xc2,0x6c,0x78,0xd9,0x7c,0x00,0x92,0x2f, |
4089 | | 0xe0,0x84,0x20,0x9f,0xc8,0x0f,0xa9,0x50,0x03,0x6a,0x42,0x1d,0x51,0x1f,0xda,0x41, |
4090 | | 0x17,0x18,0x0a,0x23,0xe1,0x51,0xd8,0x02,0x5f,0xc3,0x37,0xf0,0xad,0xf9,0x20,0x30, |
4091 | | 0x26,0xe0,0x94,0x82,0x72,0x90,0x0e,0x19,0xd0,0x11,0x46,0xc2,0x3c,0x58,0x04,0x8b, |
4092 | | 0xcd,0x07,0x27,0xf9,0x5d,0x02,0x10,0x01,0x21,0x88,0x82,0x82,0x50,0x04,0x8a,0x42, |
4093 | | 0x09,0x28,0x05,0xa7,0xc2,0xe9,0x90,0x0a,0x35,0xa1,0x16,0xd4,0x17,0x5d,0x60,0x04, |
4094 | | 0x8c,0x84,0x87,0x61,0x09,0xac,0x80,0x37,0x61,0x3b,0x7c,0x06,0x3b,0xcc,0xb9,0x0a, |
4095 | | 0x70,0x3c,0x64,0x40,0x3b,0xe8,0x02,0x83,0x60,0x24,0xdc,0x95,0xfb,0xe1,0x4b,0xc0, |
4096 | | 0x69,0x0a,0x23,0x61,0x36,0x2c,0x81,0xaf,0xcd,0x07,0x8d,0x85,0x02,0x4e,0x2c,0x9c, |
4097 | | 0x0d,0x95,0x20,0x01,0xd2,0x21,0x03,0x9a,0x41,0x73,0x68,0x09,0xe7,0x8b,0x56,0xa2, |
4098 | | 0x35,0xf4,0x80,0xde,0xd0,0x0f,0x06,0x88,0x6c,0x18,0x0b,0x23,0x0b,0x53,0x2f,0x60, |
4099 | | 0x3a,0x3c,0x07,0x33,0x61,0x16,0x2c,0x83,0xd7,0xe1,0x0d,0xb1,0x1c,0x56,0xc0,0x21, |
4100 | | 0xf8,0xc5,0x7c,0x48,0x59,0x24,0xe0,0x9c,0x09,0x95,0x44,0x02,0x64,0x41,0x63,0x68, |
4101 | | 0x0d,0xd9,0x30,0x0a,0x46,0xc3,0x58,0x98,0x09,0xaf,0xc3,0x16,0xf8,0xce,0x7c,0xc0, |
4102 | | 0x53,0xd4,0x25,0x20,0x82,0x22,0x02,0x6a,0x40,0x4d,0x68,0x0c,0x3d,0x61,0x00,0x64, |
4103 | | 0x8b,0x81,0x30,0x08,0x06,0xc3,0x10,0xb8,0x4a,0xdc,0x00,0xa3,0x60,0xb4,0x18,0x03, |
4104 | | 0x33,0x60,0x26,0xcc,0x86,0x39,0xf0,0x12,0xcc,0x83,0xf9,0xb0,0x40,0x63,0xbc,0xcb, |
4105 | | 0xc4,0x5a,0xd8,0x09,0xfb,0xe0,0xa0,0x49,0x5b,0x31,0xd2,0x03,0x11,0x50,0x51,0xe3, |
4106 | | 0xbf,0x55,0xa1,0x9a,0x88,0x83,0x14,0x48,0x83,0xfa,0xd0,0x48,0x64,0x41,0x63,0x68, |
4107 | | 0x22,0x5a,0xc3,0x20,0x18,0x2c,0x86,0x8a,0x91,0x30,0x0a,0x46,0x8b,0x31,0x30,0x1b, |
4108 | | 0xe6,0xc0,0x5c,0x78,0x09,0x16,0xc1,0x62,0x58,0x02,0x4b,0xe1,0x75,0x78,0x13,0xde, |
4109 | | 0x82,0xb7,0xc5,0x3b,0x62,0x2d,0x7c,0x08,0x1f,0x89,0x1c,0x61,0x3e,0x56,0x2d,0x06, |
4110 | | 0x25,0xa0,0x2a,0x54,0x83,0x78,0xa8,0x0e,0x89,0x90,0x04,0xc9,0x90,0x22,0x52,0x45, |
4111 | | 0x1a,0xd4,0x80,0x7a,0xa2,0x3e,0x64,0x40,0x03,0x31,0x12,0x6e,0x82,0x71,0xe2,0x56, |
4112 | | 0xb8,0x03,0xc6,0xc3,0x23,0xf0,0x18,0x4c,0x85,0x99,0xf0,0x09,0x6c,0x16,0x5b,0x60, |
4113 | | 0x2b,0x6c,0x83,0x5d,0xb0,0x0f,0x0e,0x9a,0x0f,0x6a,0x4b,0x50,0x0f,0x20,0x08,0x11, |
4114 | | 0x10,0x82,0x82,0x50,0x04,0x8a,0x42,0x09,0xa8,0x0c,0x55,0x20,0x01,0x92,0x20,0x19, |
4115 | | 0x52,0x21,0x1d,0x6a,0x43,0x1d,0xa8,0x2b,0xcc,0x38,0x7d,0x7d,0xc8,0x10,0x0d,0xa0, |
4116 | | 0x11,0x34,0x81,0xa6,0x1a,0xc3,0x6f,0x09,0xad,0x45,0x07,0x71,0x29,0x74,0x85,0x6e, |
4117 | | 0xd0,0x1d,0x7a,0x42,0x5f,0xc8,0x86,0x21,0x30,0x12,0x6e,0x81,0xdb,0xc4,0x9d,0x62, |
4118 | | 0x02,0xcc,0x85,0x79,0x62,0x3e,0xbc,0x0c,0xaf,0xc0,0x12,0x58,0x26,0xde,0x10,0x2b, |
4119 | | 0x60,0x15,0xbc,0x05,0x6b,0xe0,0x6d,0xf1,0x8e,0x58,0x2b,0xde,0x15,0xeb,0xc4,0x7a, |
4120 | | 0xf1,0x29,0x6c,0x35,0x1f,0xb0,0x95,0xe4,0xba,0x41,0x2a,0xd4,0x80,0x9a,0x50,0x1f, |
4121 | | 0x32,0xa0,0x01,0x64,0x42,0x23,0xc8,0x12,0x8d,0x45,0x13,0x68,0x0e,0xad,0xa1,0x23, |
4122 | | 0x5c,0x26,0x3a,0x43,0x57,0x18,0x69,0xe6,0x30,0x94,0x74,0xe7,0x37,0xcc,0x86,0x39, |
4123 | | 0x30,0x1f,0x16,0x88,0x97,0xad,0x39,0x0f,0x66,0xbe,0xc3,0x62,0x58,0x02,0x4b,0xc5, |
4124 | | 0x32,0x78,0x0d,0x5e,0x87,0x37,0x60,0x85,0x58,0x0b,0x1f,0x9a,0xf8,0x4b,0x05,0x9c, |
4125 | | 0x17,0x34,0x3f,0x62,0x16,0xcc,0x86,0xb9,0x30,0x5f,0xf3,0x25,0x5e,0x85,0x85,0xb0, |
4126 | | 0x48,0x2c,0x86,0x25,0xb0,0x11,0x36,0x41,0x0e,0x7c,0x6c,0x3e,0xdc,0x3b,0x85,0xba, |
4127 | | 0x0c,0x09,0x90,0x04,0xc9,0x50,0x0b,0x6a,0x43,0x1d,0xa8,0x2b,0xea,0x89,0xfa,0x90, |
4128 | | 0x01,0x8d,0x44,0x6b,0xe8,0x08,0x23,0xe1,0x59,0x98,0x2e,0x9e,0x13,0xcf,0x8b,0x17, |
4129 | | 0x60,0x06,0xcc,0x84,0xb9,0xf0,0x92,0x98,0x27,0xe6,0x8b,0x25,0xf0,0x26,0xac,0x85, |
4130 | | 0x6d,0xe6,0xc3,0xf0,0x53,0x03,0xce,0x19,0x70,0x96,0x28,0x23,0xca,0x8a,0x72,0x50, |
4131 | | 0x1e,0x2a,0xc0,0x39,0x50,0x51,0x54,0x82,0xaa,0x90,0x00,0xe9,0x90,0x01,0x8d,0xcd, |
4132 | | 0x07,0x8a,0xa7,0xe1,0x0f,0xd5,0x20,0x1e,0xaa,0x43,0x0d,0xa8,0x29,0xd2,0xa1,0x16, |
4133 | | 0x4c,0x86,0xcd,0xb0,0x05,0xbe,0x80,0x5f,0x20,0xea,0xf4,0x80,0x13,0x23,0x0a,0x42, |
4134 | | 0x09,0x28,0x05,0xa7,0xc0,0x69,0x50,0xfd,0x74,0x77,0x9e,0x4a,0x2a,0xd4,0xd0,0x7c, |
4135 | | 0x95,0xda,0x50,0x07,0xea,0x8a,0x7a,0xa2,0xbe,0xc8,0x10,0x0d,0x44,0xa6,0x68,0x28, |
4136 | | 0x5a,0x43,0x47,0x98,0x0c,0xcf,0xc0,0xb3,0xb0,0x16,0xde,0x85,0xf5,0xf0,0x1e,0x6c, |
4137 | | 0x80,0x8f,0x60,0x13,0xe4,0xc0,0x66,0xd8,0x22,0x3e,0x15,0xdb,0xc4,0x76,0x91,0xfb, |
4138 | | 0x71,0x3d,0x04,0x20,0x3f,0x14,0x80,0x24,0x48,0x86,0x9a,0x90,0x2e,0x6a,0x89,0xda, |
4139 | | 0x50,0x0f,0x9a,0x88,0xd6,0xa2,0x0d,0xb4,0x87,0x0e,0x70,0x11,0x74,0x84,0x4e,0x70, |
4140 | | 0x09,0xdc,0x02,0xb7,0xc2,0x7d,0x70,0xbf,0x78,0x00,0x26,0xc1,0x23,0x62,0x26,0xfc, |
4141 | | 0x00,0x5d,0x4a,0xbb,0x74,0x15,0xdd,0xe0,0x72,0xe8,0x21,0x7a,0x8a,0x5e,0x62,0x09, |
4142 | | 0x6c,0x81,0x7d,0x70,0xd0,0x7c,0x60,0x7a,0x26,0xcf,0x3d,0x90,0x1f,0xe2,0xa1,0xba, |
4143 | | 0x48,0x80,0x34,0xa8,0x09,0x75,0xa1,0x9e,0xa8,0x2f,0x32,0x44,0x6b,0xe8,0x08,0x83, |
4144 | | 0x60,0x3c,0xdc,0x0d,0xcf,0xc0,0x34,0xf1,0x2c,0xcc,0x84,0x59,0x62,0x36,0xcc,0x81, |
4145 | | 0x17,0xc5,0x5c,0x78,0xc9,0x2c,0x30,0x70,0x16,0xf5,0x04,0xf2,0x41,0x0c,0x14,0x80, |
4146 | | 0x04,0x48,0x84,0x34,0xa8,0x25,0xea,0x40,0x5d,0xa8,0x0f,0x59,0xd0,0x58,0x34,0x11, |
4147 | | 0xad,0xa1,0x23,0x74,0x81,0x1e,0xd0,0x0b,0xae,0x80,0x2b,0xe1,0x16,0xb8,0x15,0xee, |
4148 | | 0x84,0x09,0x70,0x17,0xdc,0x03,0xf7,0xc2,0x44,0x71,0x9f,0xb8,0x5f,0x3c,0x20,0x26, |
4149 | | 0xc3,0x34,0x98,0x09,0x1b,0xe1,0x43,0xf1,0x11,0x6c,0x82,0x2d,0xf0,0x85,0xd1,0x32, |
4150 | | 0x3c,0x37,0xc1,0x01,0xf8,0x06,0xbe,0x85,0xef,0xcc,0x82,0x09,0x65,0xa9,0x33,0x10, |
4151 | | 0x14,0x11,0x22,0x12,0x8a,0x42,0x71,0x48,0x86,0x14,0x48,0x85,0x34,0xa8,0x05,0xf5, |
4152 | | 0xa0,0x3e,0x64,0x88,0x06,0x22,0x53,0xb4,0x86,0x8e,0x70,0xb1,0x98,0x29,0xcc,0xe2, |
4153 | | 0x0c,0x93,0xcc,0x87,0xbc,0x67,0x07,0x9c,0xfe,0x30,0x12,0x1a,0x9e,0x43,0xbe,0xab, |
4154 | | 0x73,0xed,0x73,0x3f,0x9c,0xe5,0x3a,0xa7,0x10,0xa7,0x68,0x00,0x8d,0xa1,0x09,0xb4, |
4155 | | 0x83,0x2e,0x70,0xc8,0x2c,0x4c,0xd0,0x08,0x7f,0xf3,0xa1,0x6a,0x57,0xfa,0x11,0x28, |
4156 | | 0x03,0xe7,0x42,0x15,0xa8,0x06,0x71,0x50,0x1d,0x12,0x20,0xdd,0x7c,0xd0,0x79,0x05, |
4157 | | 0x75,0xe6,0x4a,0xe2,0x84,0xcb,0xa0,0x0b,0xf4,0x86,0x6c,0x58,0x04,0x4b,0xe0,0x4d, |
4158 | | 0x58,0x0b,0x7b,0x60,0x1f,0x7c,0x63,0x3e,0xb0,0xef,0x43,0x3c,0x90,0x00,0x69,0x90, |
4159 | | 0x01,0x0d,0xa1,0x35,0x74,0x84,0xee,0x30,0x0c,0xae,0x83,0xf1,0x66,0x7f,0x3f,0xf2, |
4160 | | 0x0f,0x0d,0xe1,0x4a,0xe8,0x03,0x7d,0x21,0x1b,0xae,0x86,0x8c,0xfe,0x3c,0x9b,0xc1, |
4161 | | 0x64,0x98,0x0f,0xaf,0xc0,0x7a,0xf3,0xa1,0xfe,0x00,0xee,0x3f,0xd0,0x4a,0xb4,0x16, |
4162 | | 0x6d,0xe0,0x66,0x18,0x0f,0x77,0xc3,0x3d,0xf0,0x18,0x6c,0x81,0x4f,0x61,0x9b,0xd8, |
4163 | | 0x2e,0xf6,0xc1,0x7e,0xf8,0x1a,0x0e,0xc0,0x37,0xf0,0x9d,0xf9,0x60,0x34,0x9b,0xdf, |
4164 | | 0x41,0xb7,0xd3,0xef,0x41,0x99,0x3b,0x28,0x77,0xf8,0x1a,0xf6,0xcd,0x20,0x1c,0x7c, |
4165 | | 0x0b,0x3f,0xc2,0x4f,0xf0,0xb3,0x59,0x10,0x60,0x26,0x7d,0xf0,0x2c,0xfa,0x10,0xd1, |
4166 | | 0x1a,0x2e,0x80,0x76,0xe2,0x72,0xe8,0x05,0xd9,0xf0,0xe3,0x6c,0x77,0xa2,0xdd,0x95, |
4167 | | 0x90,0x0d,0x23,0x60,0x24,0x8c,0x83,0x09,0x30,0x09,0x1e,0x81,0x47,0x61,0xdf,0x5b, |
4168 | | 0xb4,0x6f,0x30,0x8b,0x61,0xc4,0x41,0x02,0x34,0x86,0x1e,0xef,0xd2,0x1f,0x40,0x2f, |
4169 | | 0xe8,0x0d,0xfd,0x60,0x10,0x5c,0x0b,0xa3,0x61,0x2c,0xdc,0x06,0xcf,0xc2,0xf3,0x90, |
4170 | | 0xb9,0x8e,0xfb,0x95,0xf9,0x80,0xf8,0xbd,0x80,0x73,0x21,0xb4,0x87,0x87,0xe1,0x51, |
4171 | | 0x78,0x0c,0x1e,0x17,0x4f,0xc1,0xd3,0x30,0x0d,0x9e,0x83,0x17,0x60,0x01,0xbc,0x22, |
4172 | | 0x16,0xc2,0x6b,0xf0,0x06,0x84,0xde,0x0f,0x38,0xd1,0x90,0x1f,0x0a,0x41,0x49,0x38, |
4173 | | 0x05,0xce,0x84,0x32,0x90,0x0e,0xb5,0xa1,0x1e,0x64,0x40,0x23,0x68,0x2c,0x9a,0x43, |
4174 | | 0x6b,0xb8,0x00,0x9e,0xfa,0x80,0x67,0x3d,0x58,0x02,0xcb,0xe0,0x23,0xc8,0x81,0x43, |
4175 | | 0x70,0x18,0x4a,0x6e,0x20,0x5e,0x48,0x81,0x34,0x38,0x1f,0x5a,0x43,0x7f,0xc8,0x86, |
4176 | | 0x71,0x70,0x2b,0x4c,0x85,0x67,0x61,0x19,0xbc,0x0e,0xab,0xe1,0x6d,0xf8,0xc5,0x7c, |
4177 | | 0xf8,0xf9,0x11,0xc7,0x42,0x6d,0xe8,0x0b,0x57,0x89,0x1b,0xc5,0x43,0xf0,0x18,0x4c, |
4178 | | 0x81,0x19,0xe6,0x03,0xca,0xcd,0xf4,0x5f,0x90,0x5f,0x14,0x80,0x32,0x70,0x0e,0x54, |
4179 | | 0x31,0x1f,0x84,0x6e,0xa1,0x9f,0x83,0x7c,0x70,0x1a,0x94,0x86,0xf2,0x10,0x0b,0x67, |
4180 | | 0x43,0x45,0xa8,0x02,0x09,0xd0,0x0f,0xc6,0x0b,0xf3,0x31,0x60,0x35,0x48,0x80,0x34, |
4181 | | 0xa8,0x01,0x75,0x21,0x03,0x9a,0xc1,0xf9,0x62,0xc2,0x56,0xae,0x1b,0xbc,0x20,0x96, |
4182 | | 0xc0,0x6e,0xf8,0x12,0xf6,0xc2,0x3e,0x38,0x08,0x6b,0xb7,0xf3,0x1c,0x0c,0xbb,0xc5, |
4183 | | 0x97,0xb0,0x17,0xf6,0xc1,0x41,0x58,0xfb,0x19,0xed,0x13,0xbe,0x82,0xbd,0xb0,0x4f, |
4184 | | 0xec,0x87,0x43,0xb0,0x64,0x07,0xcf,0xd7,0xb0,0x05,0xb6,0xc2,0x36,0xb1,0x1d,0x3e, |
4185 | | 0x83,0x1d,0xe2,0x73,0xd8,0x03,0x5f,0xc1,0x5e,0xd8,0x07,0xdf,0xc0,0xb7,0xe2,0x67, |
4186 | | 0xf1,0x8b,0xd8,0xf2,0x39,0xc7,0xc1,0x4e,0xd8,0x0d,0x7b,0xe0,0x2b,0xd8,0x07,0x3f, |
4187 | | 0x9b,0x05,0x0a,0x76,0x72,0x8d,0x60,0x2d,0x7c,0x60,0x16,0x6a,0xf9,0x82,0x3e,0x00, |
4188 | | 0x1a,0x41,0x73,0x68,0x21,0x5a,0x43,0x47,0xf3,0xe1,0xff,0x57,0xf4,0xb3,0x10,0x82, |
4189 | | 0xb2,0x50,0x1e,0x2a,0xc0,0xd9,0xa2,0x92,0x38,0x17,0x92,0x20,0x05,0x6a,0x40,0xba, |
4190 | | 0xa8,0x2d,0x32,0x45,0x13,0xd1,0x4c,0xb4,0x10,0x2d,0xa1,0x15,0xb4,0x81,0x0b,0xe0, |
4191 | | 0x42,0xd1,0x41,0x74,0x14,0x9d,0xc4,0xa5,0xa2,0xb3,0xe8,0x0a,0xdd,0xe0,0x72,0xd1, |
4192 | | 0x0b,0xae,0x84,0xbe,0x30,0x08,0x86,0xc0,0x30,0xb8,0x1a,0x46,0xc0,0xf5,0x62,0x24, |
4193 | | 0xdc,0x02,0xb7,0xc1,0x43,0x30,0x05,0x9e,0x80,0xa7,0x60,0x1a,0x4c,0x87,0x57,0x60, |
4194 | | 0xdf,0x8f,0x5c,0x57,0xf3,0x21,0xb2,0x13,0x74,0x36,0x3f,0x1d,0x74,0x9c,0x67,0x82, |
4195 | | 0xce,0x59,0xf3,0x83,0x4e,0x39,0x78,0xfe,0xed,0xa0,0x33,0x13,0xb6,0xec,0x0e,0x3a, |
4196 | | 0xfb,0xe0,0x52,0x33,0x01,0xf7,0x07,0xf6,0x1f,0x72,0x27,0xe2,0x36,0x2f,0x11,0xc1, |
4197 | | 0x6f,0x95,0x08,0xe7,0xea,0x94,0x88,0xdc,0x09,0x2d,0x7b,0xc1,0x9b,0x47,0x9c,0xd7, |
4198 | | 0xfc,0xe1,0xff,0xd5,0xbc,0xe1,0xdf,0x3a,0x5f,0xf8,0x44,0xe7,0x09,0x1f,0x6f,0x7e, |
4199 | | 0xb0,0x7f,0xde,0x6f,0x5e,0xf3,0x7d,0xbd,0xf9,0xbd,0xfe,0x79,0xbd,0xde,0x3c,0x5e, |
4200 | | 0x6f,0xde,0x6e,0x5e,0xf3,0x75,0xbd,0x79,0xba,0xde,0xfc,0x5c,0x6f,0x5e,0xae,0x37, |
4201 | | 0x1f,0xd7,0x3f,0x0f,0xd7,0x9b,0x7f,0xeb,0xcd,0xbb,0xf5,0xe6,0xdb,0x7a,0xf3,0x6c, |
4202 | | 0xbd,0xf9,0xb5,0x79,0xcd,0xab,0xf5,0xcf,0xa7,0xf5,0xe6,0xcd,0x7a,0xf3,0x63,0xbd, |
4203 | | 0x79,0xaf,0xde,0x7c,0x57,0xff,0xfc,0xd6,0x93,0x9d,0xcf,0xea,0xcd,0x63,0xf5,0xe6, |
4204 | | 0xa7,0xfa,0xe7,0xa5,0xfa,0xe7,0xa1,0xfe,0xd6,0xf9,0xa6,0xfe,0xf9,0xa3,0xde,0x7c, |
4205 | | 0xd1,0x93,0x9d,0x17,0xea,0xcd,0x07,0xf5,0xcf,0xef,0xf4,0xe6,0x73,0x9e,0xec,0xbc, |
4206 | | 0x4d,0x6f,0xbe,0xa6,0x7f,0x9e,0xa5,0x37,0xaf,0xf2,0x8f,0x9e,0x4f,0xe9,0xcd,0x8f, |
4207 | | 0x3c,0xde,0xbc,0x47,0x6f,0xbe,0x63,0x5e,0xf3,0x18,0xbd,0x79,0x8b,0x27,0x3a,0x4f, |
4208 | | 0xd1,0x9b,0x9f,0xe8,0x9f,0x5f,0xe8,0xcd,0x27,0xcc,0x6b,0xde,0xa0,0x37,0x5f,0xd0, |
4209 | | 0x3f,0x0f,0xd0,0x9b,0xff,0xe7,0xcd,0xf7,0x3b,0xd1,0xf9,0x7d,0xde,0x3c,0x3d,0x6f, |
4210 | | 0x7e,0x9e,0x7f,0x5e,0xde,0xc9,0xce,0xc3,0xf3,0xe6,0xdf,0xe5,0x35,0xef,0xce,0x3f, |
4211 | | 0xcf,0xce,0x3f,0x6f,0xce,0x9b,0x17,0xe7,0xcd,0x7f,0xf3,0xe6,0xaf,0x79,0xf3,0xd6, |
4212 | | 0xbc,0x79,0x6a,0xde,0xfc,0x34,0x6f,0x5e,0x9a,0x37,0x1f,0xcd,0x9b,0x87,0xe6,0xcd, |
4213 | | 0x2f,0xfb,0xbb,0xcd,0x1f,0xfb,0xa3,0xe7,0x8b,0x79,0xf3,0xc3,0xbc,0xf9,0x60,0xfe, |
4214 | | 0x79,0x60,0xde,0xfc,0x2f,0xff,0x3c,0xae,0x93,0x9d,0x9f,0x95,0xd7,0xbc,0xac,0xe3, |
4215 | | 0xcd,0xa7,0xf2,0xe6,0x4f,0x79,0xf3,0xa4,0xbc,0x79,0x4b,0xde,0x7c,0x24,0x6f,0x3e, |
4216 | | 0x91,0x37,0x5f,0xc8,0x9b,0xff,0xe3,0xcd,0xfb,0xf1,0xe6,0xed,0x78,0xf3,0x71,0x4e, |
4217 | | 0x74,0x1e,0x8e,0x37,0xcf,0xc6,0x9b,0x5f,0xe3,0xcd,0xab,0xf9,0xad,0xf3,0x68,0xfe, |
4218 | | 0xaa,0xf3,0x67,0xf2,0x9a,0x27,0xf3,0x77,0x9f,0x0f,0x73,0xb2,0xf3,0x60,0xfe,0xa8, |
4219 | | 0xf9,0x2f,0xc7,0x9b,0xf7,0x72,0xa2,0xf3,0x5c,0x8e,0x37,0xbf,0xe5,0x7f,0x35,0xaf, |
4220 | | 0x25,0xaf,0xf9,0x2c,0x79,0xcd,0x5f,0xf1,0xcf,0x5b,0xf9,0xb3,0xe7,0xab,0x78,0xf3, |
4221 | | 0x54,0xbc,0xf9,0x29,0xde,0xbc,0x14,0x6f,0xde,0x89,0x37,0xdf,0x24,0xaf,0xf9,0x24, |
4222 | | 0xde,0xfc,0x11,0x6f,0xde,0x88,0x37,0x4f,0xc4,0x9b,0x17,0xe2,0xcd,0xf3,0xf0,0xe6, |
4223 | | 0x77,0xf8,0xe7,0x75,0xf8,0xe7,0x73,0x78,0xf3,0x34,0xbc,0xf9,0x19,0xc7,0x9b,0x87, |
4224 | | 0xe1,0xcd,0xb7,0xf0,0xe6,0x59,0x78,0xf3,0x2b,0xbc,0x79,0x15,0xde,0x7c,0x8a,0xe3, |
4225 | | 0xcd,0xa3,0xf0,0xcf,0x97,0xf8,0x6f,0xcd,0x8f,0xf8,0xbd,0xf3,0x1b,0xfe,0x5b,0xf3, |
4226 | | 0x1a,0xfc,0xf3,0x16,0xbc,0xf9,0x0a,0xde,0x3c,0x85,0xbf,0xca,0xfc,0x04,0xff,0xbc, |
4227 | | 0x84,0x93,0x9d,0x8f,0x70,0xb2,0xf3,0x10,0xc2,0xf3,0x0f,0x8e,0x3d,0xff,0x20,0xaf, |
4228 | | 0x79,0x06,0xc7,0x9b,0x57,0xf0,0x7b,0xe7,0x13,0x1c,0x6f,0xde,0x40,0x5e,0xf3,0x05, |
4229 | | 0x8e,0x37,0x4f,0x20,0xaf,0xf9,0x01,0xde,0xbc,0x00,0xff,0x7c,0x00,0x6f,0xdc,0xdf, |
4230 | | 0x1b,0xdf,0xf7,0xc6,0xf5,0xbd,0x71,0x7c,0x6f,0x7c,0xde,0x1b,0x8f,0xf7,0xc6,0xdb, |
4231 | | 0xfd,0xe3,0xec,0xde,0xf8,0xba,0x37,0x9e,0xee,0x8d,0x9b,0x1f,0x6f,0x5c,0xdc,0x1b, |
4232 | | 0xdf,0x3e,0xd9,0x71,0xed,0x93,0x1d,0xa7,0xf6,0xc6,0xa7,0xbd,0x71,0x67,0x6f,0xbc, |
4233 | | 0xf9,0x44,0xc7,0x95,0xbd,0xf1,0x60,0x6f,0x1c,0xd8,0x1b,0xff,0xf5,0xc6,0x73,0xfd, |
4234 | | 0xe3,0xb7,0xfe,0xf1,0x57,0x6f,0xdc,0xd5,0x1b,0x47,0xf5,0xc6,0x4f,0xbd,0xf1,0x50, |
4235 | | 0x6f,0x1c,0xd4,0x1b,0xcf,0xf4,0xc6,0x2f,0xfd,0xe3,0x8f,0xde,0xf8,0xe2,0x89,0x8e, |
4236 | | 0x2b,0x7a,0xe3,0x85,0xde,0x38,0xa1,0x7f,0x3c,0xd0,0x3f,0xce,0xe7,0x8d,0xef,0x79, |
4237 | | 0xe3,0x7a,0xde,0x38,0x9e,0x37,0x6e,0xe7,0x8d,0xcf,0xf9,0xc7,0xe1,0xbc,0x71,0x35, |
4238 | | 0xff,0x78,0x9a,0x37,0x4e,0xe6,0x8d,0x8f,0xe5,0x35,0xce,0xe5,0x8d,0x63,0xe5,0x35, |
4239 | | 0x6e,0xe5,0x8d,0x43,0xe5,0x39,0xfe,0xa4,0x71,0x27,0x6f,0x7c,0xc9,0x3f,0xae,0x74, |
4240 | | 0xb2,0xe3,0x42,0xde,0x78,0x50,0x5e,0xe3,0x40,0xfe,0x71,0x1e,0x6f,0x7c,0xc7,0x1b, |
4241 | | 0xd7,0xf1,0xc6,0x73,0xbc,0x71,0x9c,0x13,0x1d,0xbf,0x39,0xde,0xb8,0x8d,0x37,0x5e, |
4242 | | 0x93,0xd7,0xf8,0xcc,0x5f,0x6d,0x3c,0xe6,0xdf,0x36,0x6e,0x72,0xbc,0xf1,0x0f,0x6f, |
4243 | | 0x5c,0xc3,0x1b,0xcf,0xf0,0xc6,0x31,0xfc,0xe3,0x17,0xde,0xb8,0x85,0x7f,0x9c,0xc2, |
4244 | | 0x1b,0x97,0xf0,0xc6,0x23,0xfc,0xe3,0x10,0xde,0xf8,0x83,0x37,0xee,0xe0,0x8d,0x37, |
4245 | | 0xfc,0xd6,0x71,0x06,0x6f,0x7c,0xc1,0x1b,0x57,0x08,0x8f,0x27,0xb8,0xe3,0x09,0xbf, |
4246 | | 0x7b,0x1c,0xc1,0xac,0x3d,0x0b,0xf9,0xc1,0xfb,0x0c,0xbb,0x10,0x14,0x76,0x5f,0x65, |
4247 | | 0x98,0x25,0x16,0x1d,0x7e,0x9e,0x3b,0xe6,0x27,0x70,0x2c,0x54,0x84,0xaa,0xee,0xcf, |
4248 | | 0x61,0xf3,0x53,0xd7,0x89,0x07,0xb3,0xa6,0x49,0x2d,0xa8,0xad,0x75,0x4d,0x3a,0x69, |
4249 | | 0x3c,0xe2,0x5a,0xb8,0x01,0xc6,0xc2,0x4d,0xc0,0x4f,0x3f,0x67,0x0a,0x3c,0x0e,0x4f, |
4250 | | 0x6b,0x9c,0xc2,0x3c,0xc2,0x3f,0x0f,0x2f,0xc0,0x4c,0x98,0x0d,0x2f,0x6a,0xec,0xe2, |
4251 | | 0x25,0x58,0xa0,0xf1,0x8b,0x57,0x34,0x86,0xb1,0x41,0x63,0x18,0xdf,0x6b,0x0c,0x63, |
4252 | | 0x01,0x59,0x7a,0x05,0x96,0xc1,0x5a,0x58,0xa7,0x31,0x89,0xcf,0x34,0x0e,0xb1,0x57, |
4253 | | 0x6b,0x98,0x64,0x5b,0xe3,0x10,0x66,0xfc,0xe1,0x7a,0x8d,0x3b,0xdc,0x68,0xad,0x53, |
4254 | | 0x32,0xce,0x1a,0x73,0x30,0xe3,0x0d,0xdf,0x69,0xbc,0x61,0x8c,0xc6,0x1b,0x12,0x35, |
4255 | | 0xc6,0x70,0x2b,0xdc,0x01,0xe3,0xb5,0x0e,0xc9,0x22,0xad,0x41,0xb2,0x44,0xeb,0x90, |
4256 | | 0xbc,0xa6,0x75,0x48,0x96,0x5b,0x6b,0x90,0x98,0x71,0x08,0x27,0x8a,0x7f,0x90,0x0f, |
4257 | | 0x62,0xa0,0x00,0x14,0x84,0x42,0x50,0x38,0xca,0x5d,0x9b,0xa4,0x34,0x94,0xd1,0x3a, |
4258 | | 0x24,0x66,0x0d,0x92,0x2b,0xa1,0x0f,0xf4,0xb3,0xd6,0x1f,0x31,0x6b,0x8e,0x7c,0x0c, |
4259 | | 0x9f,0x68,0xdd,0x91,0xcf,0xb4,0xde,0xc8,0x17,0x5a,0x6f,0xe4,0x2b,0xad,0x33,0x62, |
4260 | | 0xc6,0x2c,0x8a,0x58,0xeb,0x89,0x24,0x68,0x9c,0xe2,0x69,0x6b,0xed,0x90,0xdd,0x1a, |
4261 | | 0xa3,0xf8,0xce,0x5a,0x27,0xe4,0xe7,0x68,0x77,0x7d,0x10,0x6f,0x5d,0x10,0x6f,0x3d, |
4262 | | 0x10,0x6f,0x1d,0x90,0x04,0x8d,0x53,0x98,0x35,0x40,0x2e,0xd3,0x58,0x85,0x19,0x97, |
4263 | | 0x78,0x09,0xd6,0xc3,0x56,0xad,0xef,0x11,0x61,0xad,0xe5,0xe1,0xad,0xe1,0xd1,0x40, |
4264 | | 0x6b,0x76,0x78,0x6b,0x75,0xb4,0xd1,0x58,0x85,0x59,0x97,0xe3,0x72,0x6b,0xed,0x8d, |
4265 | | 0xb1,0x1a,0xa3,0xb8,0x47,0x63,0x13,0xde,0x98,0x84,0xb7,0xb6,0xc6,0x52,0xad,0xa5, |
4266 | | 0xb1,0xda,0x5a,0x3f,0xc3,0x5b,0x37,0x63,0xb3,0xd6,0xcb,0x30,0x6b,0x65,0x7c,0x0d, |
4267 | | 0xdf,0xc0,0x8f,0xd6,0x3a,0x19,0x01,0x6b,0x6d,0x8c,0x22,0x1a,0xa3,0xa8,0xa2,0xb1, |
4268 | | 0x89,0x54,0x8d,0x49,0x78,0x6b,0x5f,0x34,0xd0,0x9a,0x17,0x2d,0xac,0x75,0x2e,0xbc, |
4269 | | 0xf5,0x2d,0xb2,0x35,0x4e,0x61,0xd6,0xb3,0x18,0xaa,0x35,0x2d,0xbc,0xb5,0x2c,0xc6, |
4270 | | 0x6b,0xac,0xe2,0x59,0x8d,0x51,0xcc,0xb5,0xd6,0xab,0x58,0xaa,0xf5,0x29,0xbc,0x75, |
4271 | | 0x29,0xd6,0x58,0x63,0x15,0x5b,0xb5,0x06,0xc5,0x7e,0x6b,0xfd,0x09,0x6f,0xdd,0x89, |
4272 | | 0x90,0xc6,0x2d,0x4a,0x68,0xbc,0x22,0x49,0xe3,0x14,0xde,0xba,0x12,0xf5,0xad,0x35, |
4273 | | 0x24,0x9a,0x68,0xed,0x08,0x6f,0xcd,0x08,0x6f,0xad,0x88,0xce,0x5a,0x23,0xa2,0xa7, |
4274 | | 0xb5,0x1e,0xc4,0x58,0x8d,0x5b,0xdc,0xad,0xf1,0x0a,0x6f,0x9c,0xe2,0x09,0x8d,0x4f, |
4275 | | 0xbc,0xa0,0x75,0x1e,0xbc,0xf5,0x1d,0x96,0x6b,0x5d,0x87,0x35,0xd6,0x5a,0x0e,0x66, |
4276 | | 0x1d,0x87,0x03,0x70,0x10,0x0e,0x15,0x38,0xb2,0x96,0x83,0xb7,0x86,0x43,0x61,0x8d, |
4277 | | 0x61,0x54,0xb1,0xd6,0x69,0x68,0xa0,0xf5,0x19,0x9a,0x6b,0x5d,0x86,0x8b,0x34,0x7e, |
4278 | | 0xd1,0x4d,0xeb,0x2f,0x0c,0x83,0xe1,0x70,0x83,0xb5,0xf6,0xc2,0x9d,0x1a,0xc3,0x78, |
4279 | | 0x56,0x63,0x17,0xde,0xda,0x0a,0xcb,0xb5,0x66,0xc2,0x5b,0x5a,0x2b,0xc1,0x1b,0xc3, |
4280 | | 0xd8,0xaa,0xb5,0x11,0xf6,0xab,0x63,0x0b,0x6a,0x0c,0xa3,0xb8,0xd6,0x3c,0xa8,0xab, |
4281 | | 0x35,0x0e,0x1a,0x6b,0x6d,0x83,0x96,0xd6,0x38,0x46,0x37,0xad,0x5b,0xe0,0xad,0x53, |
4282 | | 0x30,0x56,0xe3,0x17,0x73,0xac,0x31,0x0b,0x6f,0x2d,0x82,0x75,0xd6,0xfa,0x03,0x3b, |
4283 | | 0xb4,0xee,0x40,0xc0,0x5a,0x6b,0xc0,0xac,0x33,0x50,0x5f,0xe3,0x19,0x66,0x6d,0x81, |
4284 | | 0x56,0x1a,0xcb,0xf0,0xc6,0x30,0x6e,0xb7,0xc6,0x2d,0xbc,0x75,0x03,0x5e,0xb4,0xc6, |
4285 | | 0x2c,0xbc,0x35,0x02,0xd6,0x6a,0xcc,0xc2,0x5b,0x13,0xe0,0x0c,0xad,0x03,0x90,0xa6, |
4286 | | 0x75,0x00,0x6a,0x6a,0x1d,0x80,0x5a,0x5a,0x0b,0xa0,0x99,0xbe,0xfd,0xf7,0xbe,0xf9, |
4287 | | 0x1f,0xab,0x6f,0xfe,0xc7,0xe9,0x5b,0x7f,0xf3,0x9d,0xff,0x22,0x7d,0xe3,0xbf,0x02, |
4288 | | 0xde,0xd6,0x58,0x47,0x9c,0xf5,0x5d,0xbf,0xf7,0x3d,0x7f,0x6d,0x7d,0xc7,0x5f,0x5f, |
4289 | | 0xdf,0xe9,0x5f,0xac,0xef,0xf3,0xbb,0xea,0xbb,0xfb,0xab,0xac,0x6f,0xed,0xc7,0xea, |
4290 | | 0x1b,0x7b,0xef,0xdb,0x7a,0xf3,0xed,0xfc,0xa3,0xd6,0x98,0x87,0x19,0xef,0x68,0xae, |
4291 | | 0xf1,0x0c,0x6f,0x1c,0xa3,0x8b,0xc6,0x2f,0x26,0x68,0xdc,0x62,0xbe,0x35,0x56,0xb1, |
4292 | | 0x52,0x63,0x14,0xc5,0x35,0x36,0x61,0xbe,0x6b,0xef,0xa2,0xf1,0x89,0x09,0x1a,0x9f, |
4293 | | 0x30,0x63,0x13,0x4e,0x49,0x77,0x6c,0x62,0xa4,0xc6,0x24,0x1e,0xd2,0x98,0x84,0x19, |
4294 | | 0x7f,0x28,0xac,0xef,0xd5,0xcb,0xe9,0xfb,0xf4,0x54,0x8d,0x43,0x5c,0xa0,0x71,0x88, |
4295 | | 0xfe,0xff,0x57,0xd9,0xb9,0x40,0x47,0x59,0x98,0x69,0x78,0x26,0x4c,0x92,0x49,0xc2, |
4296 | | 0x25,0x56,0x11,0xaf,0x88,0x82,0x02,0xa2,0x24,0x87,0x84,0x8b,0x5c,0xe3,0x0a,0xca, |
4297 | | 0xd9,0x2e,0x27,0x41,0x2b,0x95,0x65,0x95,0xb8,0x8a,0x56,0x6a,0x0b,0xd5,0x54,0xad, |
4298 | | 0x5a,0x8c,0xa0,0x45,0x50,0x2c,0xa7,0xab,0xed,0xd1,0xe2,0x82,0x6b,0xbd,0x50,0x45, |
4299 | | 0xc2,0xa2,0xd6,0xae,0x0a,0x51,0xcb,0x6a,0xab,0x14,0x14,0xad,0xbb,0x5a,0x05,0xb4, |
4300 | | 0xed,0x52,0x95,0xca,0x4d,0x91,0x9b,0xd9,0xf7,0x9b,0xff,0xf9,0x92,0x2f,0x63,0x50, |
4301 | | 0x3b,0x39,0x6f,0x12,0x26,0x21,0x33,0xf9,0x33,0x13,0x7e,0xde,0xef,0x7d,0x9f,0x8f, |
4302 | | 0x1e,0x7a,0x23,0xfd,0x73,0xef,0x9d,0xaf,0x0a,0x5d,0x73,0xeb,0x99,0xbf,0x26,0xbd, |
4303 | | 0x15,0xfa,0xe5,0xd6,0x2d,0xdf,0x26,0xa5,0x8e,0x48,0xfa,0xe5,0x5d,0xe9,0x95,0xf7, |
4304 | | 0x62,0x3e,0x71,0x33,0x73,0x89,0xa5,0x61,0x26,0x91,0xa2,0x23,0xde,0x9b,0x6e,0x78, |
4305 | | 0x7f,0x3a,0xe1,0xde,0x05,0xb7,0x1e,0x78,0x8d,0x34,0x96,0x2e,0xf8,0x4c,0x66,0x15, |
4306 | | 0x4d,0x74,0xbe,0xdf,0x61,0x56,0xd1,0x83,0x8e,0xb7,0x75,0xbb,0x7b,0x86,0x2e,0xf7, |
4307 | | 0x79,0xa1,0xbf,0xed,0xbd,0xed,0x69,0xf4,0xb5,0xaf,0x0c,0x1d,0x6d,0xeb,0x67,0x2f, |
4308 | | 0xa1,0x97,0x9d,0xa2,0x7b,0x5d,0x1d,0xba,0xd6,0x23,0x42,0xbf,0xda,0x7b,0xd5,0x75, |
4309 | | 0xf4,0xa8,0x1b,0xe8,0x51,0xcf,0xa6,0x2f,0xfd,0x00,0x3d,0x69,0xef,0x47,0x3f,0x1a, |
4310 | | 0x3a,0xd0,0x5b,0xe8,0x3e,0x6f,0x0d,0x7d,0x67,0xeb,0x3a,0xef,0x3f,0x3a,0xe9,0x36, |
4311 | | 0x57,0xd3,0x69,0x1e,0xc1,0xec,0x64,0x21,0xb3,0x11,0xeb,0x27,0x6f,0xa0,0x9f,0xec, |
4312 | | 0xbd,0xe4,0xbf,0x86,0x2e,0xb2,0x77,0x90,0x3f,0x0d,0x73,0x12,0xeb,0x10,0xef,0x63, |
4313 | | 0x06,0x72,0x04,0xb3,0x8f,0xf1,0xcc,0x3c,0x26,0x87,0x39,0xc7,0x54,0xe6,0x1b,0x36, |
4314 | | 0xdb,0x78,0x86,0xb9,0xc6,0x6a,0x66,0x1b,0x36,0xd7,0x58,0xcb,0x5c,0xc3,0x66,0x1a, |
4315 | | 0x6f,0x33,0xd3,0xd8,0xca,0x4c,0xc3,0xe6,0x19,0x07,0x38,0x39,0x2a,0x93,0xba,0x4a, |
4316 | | 0xdd,0xa4,0x72,0xa9,0x9f,0xd4,0x5f,0x3a,0x59,0x1a,0x20,0x9d,0x22,0x9d,0x2a,0x0d, |
4317 | | 0x94,0x2a,0xa4,0x4a,0x69,0xb0,0x34,0x56,0x1a,0x27,0x4d,0x95,0xea,0xa5,0x4b,0xa4, |
4318 | | 0x4b,0xa5,0x6f,0x49,0x97,0x49,0xd3,0xa5,0x99,0xcc,0x4b,0x1a,0xa4,0x6b,0xa5,0xeb, |
4319 | | 0x99,0x9b,0x34,0x4a,0xf3,0xa5,0xdb,0x98,0xa1,0x2c,0xa1,0x6b,0x9c,0x62,0x8e,0xd2, |
4320 | | 0x89,0x39,0x4a,0x96,0x59,0xca,0x61,0xcc,0x51,0x0e,0x67,0x86,0xd2,0x93,0xf9,0xc9, |
4321 | | 0x89,0xcc,0x4f,0xfa,0x32,0x3f,0xe9,0xcf,0x0c,0xc5,0x67,0x27,0xc3,0x99,0x95,0xd4, |
4322 | | 0x30,0x2b,0xf9,0x47,0xe6,0x24,0x75,0xcc,0x4a,0xe6,0x49,0x0b,0xa5,0xaf,0x9d,0xa0, |
4323 | | 0x7f,0x97,0xa4,0xc3,0xa4,0x21,0x3a,0x51,0xbc,0x4e,0xba,0x53,0xfa,0xa9,0x54,0xd3, |
4324 | | 0x47,0x9f,0x2b,0xdd,0x22,0x2d,0x92,0xde,0x97,0x1e,0xd1,0x89,0xe4,0x32,0x3b,0x99, |
4325 | | 0xec,0x27,0xf5,0xd7,0xbf,0x9f,0x3a,0xa9,0xfc,0x19,0x27,0x96,0x95,0x52,0xbd,0xf4, |
4326 | | 0x67,0xe6,0x2b,0x1f,0x31,0x5f,0xd9,0xc3,0x49,0x67,0xdf,0x30,0x53,0x99,0x11,0xfa, |
4327 | | 0xc4,0x4b,0x98,0xa3,0x34,0x31,0x3f,0x69,0x66,0x6e,0xb2,0x9e,0x79,0xc9,0x26,0x4e, |
4328 | | 0x58,0x1b,0xa5,0x9f,0xdb,0x89,0x6b,0x85,0x9e,0xb7,0x15,0xc9,0x09,0x6c,0x9a,0x39, |
4329 | | 0x4a,0x96,0xd9,0xc9,0xc9,0x74,0x85,0x2b,0x99,0xa1,0x0c,0x61,0x86,0x32,0x8a,0x99, |
4330 | | 0xc9,0x5d,0xcc,0x4c,0x6c,0x5e,0xb2,0x84,0x39,0x89,0xf7,0x7f,0x0b,0x99,0x8b,0x2c, |
4331 | | 0x94,0x9a,0x99,0x89,0x1c,0x3b,0x48,0x0f,0x15,0xa9,0x4e,0xaa,0x97,0xae,0x97,0x6e, |
4332 | | 0x90,0x56,0x48,0xcd,0xd2,0xcb,0xd2,0x7a,0xe9,0xea,0x2a,0x1d,0x3b,0xe9,0x1d,0x69, |
4333 | | 0x93,0xd4,0x52,0x95,0xcc,0x52,0x9a,0x99,0xa5,0xd8,0x49,0xf4,0x42,0xe6,0x27,0x5d, |
4334 | | 0x98,0x93,0xd4,0xd0,0xed,0xbd,0x92,0x7e,0xef,0x2c,0xe6,0x22,0xff,0xce,0x3c,0xc4, |
4335 | | 0xba,0xbb,0x3b,0xec,0x84,0x9b,0x39,0x88,0xcd,0x3b,0xe6,0x49,0xcf,0x31,0xd7,0xf0, |
4336 | | 0x7e,0xad,0xf7,0x6a,0xbd,0x4f,0x7b,0x22,0xdd,0xd9,0x7e,0x74,0x67,0x2b,0xa5,0x61, |
4337 | | 0xcc,0x32,0x1a,0xe8,0xd0,0x5a,0x5f,0xf6,0xf7,0xf4,0x64,0x77,0x84,0x2e,0xac,0xf5, |
4338 | | 0x5f,0x07,0xd2,0x7b,0xb5,0xce,0xeb,0x54,0xba,0xae,0x73,0x42,0xaf,0xf5,0x09,0xfa, |
4339 | | 0xac,0x4f,0xd3,0x63,0xb5,0xb9,0xc6,0x3b,0xa1,0xaf,0x9a,0xa2,0x8f,0x5a,0x41,0x0f, |
4340 | | 0xb5,0x8a,0xfe,0x69,0x4d,0xe8,0x9c,0xfe,0x53,0xe8,0x99,0xfe,0x4b,0xe8,0x8e,0x36, |
4341 | | 0x85,0x9e,0xe8,0xe3,0xf4,0x43,0x7f,0x4d,0x2f,0xb4,0x39,0x74,0x41,0xdf,0xa2,0xeb, |
4342 | | 0xf9,0xb7,0xd0,0xe3,0x2c,0x61,0x3e,0xd1,0x8b,0xb9,0x84,0xcd,0x24,0xa6,0x33,0x7b, |
4343 | | 0xf0,0x0e,0xa6,0x77,0x2f,0xbd,0x6b,0x69,0x73,0x88,0x26,0xe6,0x0f,0xf6,0x1f,0x94, |
4344 | | 0x99,0xcc,0x1c,0x0e,0x0d,0x3d,0x4a,0x9b,0x35,0xf4,0x67,0xd6,0x30,0x2c,0xcc,0x17, |
4345 | | 0xce,0x60,0xae,0x50,0xc7,0x5c,0x61,0x34,0x73,0x85,0x9f,0x30,0x4f,0x38,0x40,0x4f, |
4346 | | 0xb2,0x9c,0x9e,0x64,0xa5,0x54,0x27,0x4d,0x94,0xce,0x96,0xbe,0x21,0x9d,0x2b,0x4d, |
4347 | | 0x92,0xa6,0x4a,0xf5,0xd2,0xbf,0x4a,0x17,0x4b,0xdf,0x92,0x2e,0x93,0xbe,0x4d,0x97, |
4348 | | 0xd2,0xe6,0x11,0x2d,0x52,0xba,0x45,0x3f,0x73,0xa9,0x48,0x2a,0x93,0x3a,0x4b,0x5d, |
4349 | | 0xa4,0xae,0x2d,0x49,0xc7,0xf2,0x28,0xe9,0x68,0x7a,0x96,0x23,0x98,0x5b,0x4c,0x61, |
4350 | | 0x6e,0xf1,0x1c,0xf3,0x88,0x57,0x99,0x43,0x6c,0x92,0xde,0x95,0xfe,0x2c,0x6d,0x91, |
4351 | | 0xf6,0x30,0x97,0xe8,0xc2,0x3c,0x62,0x24,0x73,0x88,0x3a,0xe6,0x0f,0xb6,0x68,0x2a, |
4352 | | 0x2d,0x15,0x48,0xc5,0xd2,0xd0,0x74,0x32,0x8f,0x58,0x20,0x2d,0x94,0x96,0x48,0xeb, |
4353 | | 0x43,0x6f,0x72,0x09,0x5d,0xc9,0xcd,0xcc,0x27,0x4e,0x65,0xfe,0x70,0x15,0xf3,0x87, |
4354 | | 0xc5,0xcc,0x1d,0x52,0xf4,0x1c,0x9b,0x98,0x2f,0xa4,0x98,0x2b,0xcc,0x60,0x1e,0x50, |
4355 | | 0xc3,0x1c,0x20,0x15,0x3c,0xfe,0xa1,0xc1,0xd7,0xff,0xa6,0xf4,0x20,0x5e,0xbe,0xf9, |
4356 | | 0xf8,0xfb,0xa4,0xe3,0xf0,0xf0,0xc7,0xe0,0xdd,0x3f,0x2d,0xbd,0x5a,0x92,0xf4,0x05, |
4357 | | 0x0b,0xe9,0x09,0x96,0xe3,0xdb,0x1f,0x49,0x2f,0xd0,0xfa,0x80,0x35,0x52,0x1d,0xfe, |
4358 | | 0x7d,0x33,0xfd,0xbf,0x0f,0xf0,0xeb,0x4f,0xc3,0xaf,0x3f,0x4f,0xba,0x46,0xba,0x4b, |
4359 | | 0x5a,0x8a,0x57,0xdf,0x88,0x47,0xbf,0x17,0x8f,0xbe,0x0f,0x5d,0xbf,0xfa,0xae,0x89, |
4360 | | 0xf7,0x6e,0x3d,0xbd,0x65,0xf8,0xef,0x29,0x7c,0x75,0xeb,0xdc,0x4d,0xc4,0x53,0xdf, |
4361 | | 0xd4,0xad,0xad,0x57,0x57,0x40,0x8f,0xee,0x2c,0xe9,0x6c,0xba,0x74,0x37,0xd0,0x8f, |
4362 | | 0x5b,0x49,0x17,0xce,0x7a,0x70,0x4f,0x49,0x6b,0xf1,0xd8,0xb7,0xd1,0x7d,0xeb,0x44, |
4363 | | 0xe7,0xcd,0xbb,0x6e,0x43,0xf0,0xd8,0xad,0xc3,0xd6,0x40,0x7f,0x6d,0x36,0x3d,0xb5, |
4364 | | 0xd5,0xf4,0xd2,0xd6,0x86,0x2e,0xda,0x66,0x3c,0xf6,0x43,0xe9,0x9a,0x0d,0x0a,0xfd, |
4365 | | 0x32,0xeb,0x96,0x0d,0xa3,0x57,0xd6,0x18,0x7c,0xf6,0x1f,0xe3,0xaf,0x37,0x85,0xae, |
4366 | | 0xd8,0x7b,0x74,0xc4,0x52,0x74,0xc3,0x0a,0xf1,0xda,0x0f,0xc5,0x63,0x1f,0x84,0xb7, |
4367 | | 0x3e,0x02,0x5f,0xdd,0xbb,0x5e,0x67,0xd1,0xf1,0xaa,0x0b,0xbd,0xae,0x4b,0xe8,0x71, |
4368 | | 0xa5,0xe8,0x49,0xd5,0xd0,0x8f,0x1a,0x17,0x3a,0x51,0xe7,0x87,0x1e,0x54,0x23,0xbd, |
4369 | | 0xa7,0x5f,0x87,0xae,0xd3,0xea,0xd0,0x6f,0xfa,0x0d,0x7d,0xa6,0x46,0xfa,0x4b,0x4f, |
4370 | | 0xd2,0x5b,0xf2,0xbe,0xd2,0xb3,0xf4,0x94,0x52,0xf4,0x92,0x46,0x84,0x2e,0x92,0xf5, |
4371 | | 0x90,0x4e,0xa7,0x7f,0x54,0x8f,0xef,0xfe,0x70,0xe8,0x1c,0x3d,0x4a,0xd7,0xe8,0x89, |
4372 | | 0xd0,0x2f,0x6a,0xc6,0x8f,0x3f,0x96,0xde,0xd0,0x09,0xa1,0x2b,0x54,0x89,0x37,0x5f, |
4373 | | 0x11,0x7a,0x40,0x23,0xf0,0xe9,0xcd,0xa3,0x77,0x6f,0xbe,0x3b,0x9e,0xfc,0x50,0xba, |
4374 | | 0x3d,0xa3,0x42,0x9f,0xc7,0xfa,0x3a,0x63,0xe9,0xec,0x2c,0xc1,0x9b,0x7f,0x8d,0x6e, |
4375 | | 0xce,0x1f,0x43,0x1f,0xc7,0x7b,0x37,0xc5,0x52,0x09,0x1e,0x7d,0x15,0x7d,0x1b,0xeb, |
4376 | | 0xd9,0x8c,0x09,0x1d,0x9b,0x89,0x74,0x6b,0x26,0xe3,0xd9,0xcf,0x0f,0x3d,0x9a,0xbb, |
4377 | | 0xcd,0xaf,0x3f,0x2a,0xf1,0xea,0x4b,0xe9,0xba,0x0c,0xa3,0xdf,0x62,0x7d,0x96,0x99, |
4378 | | 0xf4,0x58,0xbc,0xbf,0xe2,0xbd,0x15,0xef,0xab,0xa4,0xf0,0xef,0xcb,0xe8,0xa7,0x78, |
4379 | | 0x2f,0x65,0x4c,0xe8,0xa2,0xd4,0xe1,0xe5,0x5f,0x8a,0x87,0xbf,0x90,0xae,0xc9,0x9d, |
4380 | | 0xa1,0x5f,0xe2,0xbd,0x92,0x4d,0xf4,0x45,0xac,0x2b,0x62,0x1e,0x7d,0xb3,0xf4,0xba, |
4381 | | 0xf4,0xb6,0xb4,0x59,0x6a,0x39,0x2e,0xf1,0xeb,0x67,0xe2,0xd7,0x9b,0x47,0x5f,0x59, |
4382 | | 0x9d,0x78,0xf2,0xe6,0xc3,0xd7,0xd0,0xb3,0xf8,0x2e,0xfe,0xbb,0x75,0x2a,0x3e,0xc6, |
4383 | | 0x83,0xb7,0x3e,0xc5,0x50,0x7a,0x14,0x53,0xf0,0xe1,0xcd,0x83,0xaf,0xc1,0x53,0xf7, |
4384 | | 0x0e,0xc4,0x8f,0xf1,0xd4,0xcd,0x4f,0x7f,0x37,0x74,0x1d,0xb6,0xe1,0xa1,0xa7,0x6e, |
4385 | | 0x91,0x16,0x24,0xfe,0x78,0x1d,0x3e,0xb8,0x79,0xe0,0x29,0xbc,0xef,0x46,0x3c,0xef, |
4386 | | 0x45,0x74,0x10,0x16,0x4b,0x4b,0xcc,0xff,0xb6,0x25,0x6e,0xaf,0xa4,0x53,0xfd,0xe9, |
4387 | | 0x1c,0x4c,0x97,0xae,0xa4,0x6f,0x30,0x87,0xbe,0xc1,0x6d,0xf4,0x0d,0x1e,0xb5,0xc5, |
4388 | | 0x93,0xaf,0x26,0x9d,0x83,0x71,0xd2,0x26,0xeb,0x1d,0x6c,0xd0,0xf7,0xb6,0x21,0xf1, |
4389 | | 0xd1,0x27,0xe1,0x9f,0xbb,0x6f,0xbe,0x14,0xbf,0xdc,0x7d,0x72,0xf3,0xc8,0x8b,0xf1, |
4390 | | 0xc6,0x0f,0xc7,0x13,0x1f,0x81,0x17,0xee,0x1e,0xb8,0xf9,0xdf,0xe6,0x7d,0xbf,0x85, |
4391 | | 0xe7,0xdd,0x1d,0xaf,0xbb,0x16,0x8f,0x7b,0x1e,0xde,0xf6,0xf3,0x78,0xda,0xd6,0x03, |
4392 | | 0xc8,0x2d,0x4a,0x7a,0x53,0xc7,0x91,0x1e,0xc0,0x77,0xe8,0x00,0x5c,0x45,0x07,0xe0, |
4393 | | 0x66,0x7a,0x00,0xd6,0x01,0x48,0x91,0xed,0x3f,0x9a,0x4c,0xff,0x49,0x78,0xdd,0x95, |
4394 | | 0x78,0xdd,0x35,0xf8,0xdc,0xcd,0x64,0xf2,0x2d,0x8f,0xdf,0xf2,0x6e,0xe2,0x37,0xbf, |
4395 | | 0x40,0xae,0x3d,0x45,0x9e,0xdd,0x73,0xec,0x17,0x48,0xdf,0xfb,0x50,0x8f,0xfd,0xad, |
4396 | | 0x89,0xff,0x5c,0x88,0xef,0xdc,0x27,0x78,0xcd,0xd5,0xc1,0x5f,0xfe,0x87,0xe0,0x29, |
4397 | | 0xbb,0x97,0x3c,0x31,0xf8,0xc7,0x93,0x83,0x67,0xec,0x5e,0xb1,0x7b,0xc4,0x97,0xe3, |
4398 | | 0x0d,0xff,0x20,0xf8,0xc1,0xb7,0xe2,0x03,0xdf,0x8f,0xff,0xbb,0xcd,0xfc,0xdf,0x6d, |
4399 | | 0xfa,0x9e,0xa4,0x25,0xd2,0x0a,0xe9,0x59,0xe9,0x15,0x5b,0xbc,0xb7,0x5d,0xcf,0x0b, |
4400 | | 0xa9,0x5c,0xaa,0x90,0x2a,0xa5,0xe9,0xd2,0x4c,0x69,0x99,0xf4,0x17,0xfb,0xd8,0x0e, |
4401 | | 0x1d,0x07,0xa9,0x4e,0xaa,0x97,0x52,0x3b,0xf5,0xb3,0xfe,0x44,0x5f,0x57,0x4a,0xed, |
4402 | | 0xd6,0x6d,0x4a,0x9b,0x24,0x5b,0x90,0x5a,0x2e,0xd5,0x49,0xf5,0xd2,0x42,0xa9,0xc9, |
4403 | | 0x96,0xa6,0xee,0x49,0xa7,0xae,0x95,0xd6,0x4a,0xf5,0x7b,0xf5,0xb5,0xa5,0x6b,0xa4, |
4404 | | 0x46,0x69,0xa1,0xd4,0x24,0x35,0x4b,0xeb,0x6d,0xa1,0xd8,0xbe,0x74,0xea,0x8e,0x7d, |
4405 | | 0x49,0xfe,0x3d,0xb7,0xf8,0xf7,0xc1,0x82,0x54,0xcd,0xaf,0x12,0xbf,0xda,0xbc,0x6a, |
4406 | | 0xf3,0xa7,0xcd,0xa8,0x4d,0xa7,0xba,0xea,0xbf,0x54,0x5d,0x13,0xf3,0x24,0x95,0x98, |
4407 | | 0x11,0xd9,0x83,0x78,0xd4,0x47,0x27,0xff,0xc5,0x6b,0xf5,0xa8,0x6d,0x5d,0xf1,0x89, |
4408 | | 0xd2,0xc9,0x79,0x1e,0x75,0x05,0xcc,0x6d,0xf3,0xa8,0x6b,0xc8,0xcb,0xd7,0x93,0x97, |
4409 | | 0x9f,0x25,0xdd,0x84,0x47,0xbd,0x38,0x78,0xd4,0xf7,0x27,0xa7,0xb1,0x39,0x8f,0xfa, |
4410 | | 0x11,0x3c,0xea,0xe5,0xd2,0x0a,0x69,0x65,0xf0,0xa8,0x9f,0x0c,0x1e,0xf5,0x6a,0x32, |
4411 | | 0xf6,0x6f,0x90,0xb1,0x37,0x8f,0x5a,0xdf,0x5e,0xea,0xbf,0xc8,0xcc,0xaf,0x23,0x33, |
4412 | | 0xbf,0x91,0xcc,0xfc,0x56,0x3c,0xea,0x96,0x82,0x84,0xb1,0x6d,0x79,0xf9,0xef,0x93, |
4413 | | 0x93,0xff,0x61,0xf0,0xa8,0x6f,0x0e,0x1e,0xb5,0x67,0xe3,0xef,0x25,0x0f,0x6f,0x1e, |
4414 | | 0xf5,0xec,0x8c,0xce,0xe7,0xc9,0xc3,0x5b,0x16,0x7e,0x1e,0x1e,0xf5,0xed,0x78,0xd4, |
4415 | | 0xcf,0xe4,0x79,0xd4,0xcf,0xe1,0x51,0xaf,0x09,0x1e,0xb5,0x65,0xe5,0x77,0x49,0x85, |
4416 | | 0x45,0xfa,0x3f,0x00,0x1e,0x75,0x69,0x9e,0x47,0xdd,0x0d,0x76,0xf6,0x31,0x64,0xe7, |
4417 | | 0xa7,0xc2,0xc8,0x36,0x8f,0xfa,0xf2,0xc0,0xc9,0x7e,0x1d,0x26,0xb6,0x7b,0xd4,0x7f, |
4418 | | 0x22,0x4b,0xbf,0x05,0x8f,0x7a,0x2b,0x99,0x7a,0xe3,0x60,0x77,0x09,0xdc,0xeb,0x0a, |
4419 | | 0x58,0xd7,0xf7,0x07,0xc6,0xf5,0xfb,0xf0,0xac,0x2d,0x43,0xbf,0x27,0x78,0xd4,0xdd, |
4420 | | 0x03,0xbf,0xda,0xb9,0xd5,0xce,0xab,0x36,0x4e,0xf5,0x68,0x72,0xf4,0x53,0xf0,0xa8, |
4421 | | 0x2d,0x4b,0xff,0x98,0xf4,0x02,0xfc,0xe9,0x77,0xe1,0x4f,0x9f,0x96,0xe7,0x51,0xd7, |
4422 | | 0xc0,0x95,0x76,0xa6,0x74,0x1d,0xfc,0xe8,0x0b,0xe1,0x46,0x3b,0x23,0x7a,0x0e,0x39, |
4423 | | 0xfa,0x85,0xe4,0xe7,0x3d,0x3b,0xef,0x0c,0xe8,0x66,0x78,0xcf,0x2f,0x06,0xce,0xb3, |
4424 | | 0x7b,0xd4,0x6f,0x93,0x9d,0x7f,0x8f,0xec,0xfc,0x4e,0x69,0x2f,0x1e,0xf5,0x01,0x3c, |
4425 | | 0x6a,0x67,0x38,0x97,0x92,0xa3,0xef,0x47,0x7e,0xbe,0x8a,0xdc,0xbc,0x33,0x9a,0x6b, |
4426 | | 0xe0,0x32,0x8f,0x0f,0x3c,0x66,0xcf,0xd1,0xcf,0x80,0xbd,0xdc,0x10,0x3c,0x6a,0x67, |
4427 | | 0x2e,0x2f,0x20,0x4f,0xff,0x10,0x39,0xfa,0x95,0x81,0xab,0xdc,0x0c,0x43,0xd9,0xf9, |
4428 | | 0xc9,0x2f,0x07,0x8f,0x7a,0x33,0x9c,0xe4,0x6d,0xc1,0xa3,0x76,0x3e,0x72,0x27,0xb2, |
4429 | | 0xf5,0xe5,0x64,0xea,0x2b,0xc9,0xd2,0x3b,0xff,0x78,0x74,0xf0,0xa8,0xc7,0xc2,0x37, |
4430 | | 0x76,0xb6,0xb1,0x33,0x8d,0xcf,0x27,0x5f,0x6f,0x0c,0xe3,0xab,0x83,0x47,0x3d,0x9f, |
4431 | | 0x5c,0xfd,0x9d,0x21,0x4f,0xbf,0x98,0x0c,0xfd,0x2f,0xc9,0xce,0x3b,0x87,0xf8,0x39, |
4432 | | 0xd8,0xc3,0x2f,0xe7,0x79,0xd4,0x3b,0xa4,0x4f,0xf3,0x3c,0x6a,0x67,0x0d,0x77,0x26, |
4433 | | 0x67,0xdf,0x2f,0xe4,0xeb,0x6b,0x60,0x08,0x8f,0x87,0x1d,0x3c,0x89,0xac,0xfd,0x85, |
4434 | | 0x30,0x82,0x67,0xe0,0x51,0xcf,0x0a,0x8c,0xe0,0xdb,0xc8,0xd9,0x3f,0x44,0xbe,0xde, |
4435 | | 0x19,0xc0,0xbf,0x81,0xeb,0xfb,0x12,0x3c,0xdf,0x3f,0xe0,0x51,0x6f,0x86,0xdf,0xfb, |
4436 | | 0x11,0x39,0xfb,0x34,0x39,0xfb,0x72,0xf2,0xf5,0x23,0xe1,0xf0,0x8e,0x85,0xbf,0xeb, |
4437 | | 0xec,0xdd,0x5a,0xf2,0xf5,0x17,0x05,0x9e,0xee,0x1c,0x32,0xf6,0x2b,0x42,0xb6,0xde, |
4438 | | 0x99,0xb9,0xaf,0x04,0x4e,0xee,0x46,0xd8,0xb8,0xbb,0xba,0xb4,0x31,0x71,0xab,0xe0, |
4439 | | 0xe0,0x8e,0x21,0x67,0x6f,0xec,0xdb,0x29,0x21,0x6b,0x3f,0x3f,0xe4,0xeb,0x9d,0x6f, |
4440 | | 0xbb,0x32,0x30,0x6d,0x3d,0x53,0xbf,0x16,0x7e,0xad,0x65,0xea,0x7b,0xc0,0xac,0xad, |
4441 | | 0x3e,0x88,0x47,0x3d,0x8a,0xac,0xfd,0xe5,0x81,0x4d,0x7b,0x13,0x1e,0xf5,0x5c,0x72, |
4442 | | 0xf7,0x3f,0x83,0x43,0xbb,0x06,0x8f,0xfa,0x65,0xe9,0xcd,0x6e,0x09,0x83,0xd6,0xf9, |
4443 | | 0xb3,0xce,0x9d,0x1d,0x0e,0x6b,0x76,0x34,0x2c,0xd9,0xc9,0x64,0xf3,0xeb,0xc9,0xe2, |
4444 | | 0x37,0x04,0x26,0xec,0x4d,0x70,0x60,0x9d,0x01,0xeb,0x8c,0xd7,0x35,0xc1,0xa3,0x1e, |
4445 | | 0x4f,0xe6,0xde,0xf3,0xf6,0xe7,0x93,0xb1,0x5f,0x40,0xb6,0xfe,0xf1,0x90,0xa9,0x5f, |
4446 | | 0x43,0x8e,0xbe,0x9c,0xfc,0xfc,0x3f,0xc3,0x5d,0xbd,0x9e,0xfc,0xfc,0x5d,0xe4,0xe7, |
4447 | | 0x0f,0xe0,0x51,0x5b,0x66,0xbe,0x91,0xcc,0xfc,0x22,0x32,0xf2,0x9d,0xc9,0xc8,0x1f, |
4448 | | 0x46,0x46,0xde,0xb8,0xa9,0x43,0xc8,0xc9,0x9f,0x43,0x4e,0x7e,0x26,0x9c,0xd4,0x95, |
4449 | | 0x81,0x8f,0xfa,0x4c,0x60,0xa2,0xbe,0x08,0x07,0xf5,0xcd,0x3c,0x8f,0xda,0xd8,0xa7, |
4450 | | 0x7b,0xa4,0x52,0xf8,0xa7,0x5d,0xe1,0x9e,0x5e,0x43,0x7e,0xfe,0x47,0x81,0x6b,0xfa, |
4451 | | 0x4b,0x32,0xf3,0x3d,0x61,0x98,0x9e,0x04,0xbb,0x74,0x40,0x60,0x96,0x0e,0x83,0x53, |
4452 | | 0x6a,0x1e,0xf5,0x38,0x32,0xf5,0x0d,0x64,0xe9,0x7f,0x0b,0x8b,0xb4,0xe5,0xc8,0x24, |
4453 | | 0x4b,0x7f,0x44,0x60,0x90,0x9e,0x1b,0x3c,0xea,0x0b,0xf2,0x3c,0xea,0x8b,0x61,0x8a, |
4454 | | 0x5e,0x11,0x58,0xa2,0xf3,0xe0,0x87,0x2e,0x93,0x9a,0x8f,0x4a,0x18,0xa1,0x55,0xc1, |
4455 | | 0xa3,0x1e,0x1e,0x3c,0x6a,0xe7,0x7f,0x7e,0x5d,0x9a,0x0e,0xe7,0xf3,0x7a,0x38,0x9f, |
4456 | | 0xf7,0xc2,0xf3,0x7c,0x30,0x70,0x3c,0x97,0x05,0x56,0xe7,0xff,0xc1,0xe7,0xfc,0x30, |
4457 | | 0x78,0xd4,0xdb,0x61,0x71,0x0e,0x80,0xbd,0x39,0x18,0xe6,0xa6,0xf1,0x36,0x6f,0x21, |
4458 | | 0xbf,0xff,0x02,0xfc,0xcc,0x0d,0x81,0x9f,0xb9,0x25,0x30,0x33,0x9d,0x95,0xb9,0x3b, |
4459 | | 0x70,0x31,0x2d,0x9f,0xbf,0x07,0xce,0x65,0x77,0xf2,0xf9,0xe3,0xc8,0xe5,0x7f,0x33, |
4460 | | 0xcf,0xa3,0xfe,0x21,0xf9,0xfb,0xa7,0x83,0x47,0xfd,0x2c,0xd9,0x7b,0xcb,0xdd,0xaf, |
4461 | | 0x23,0x77,0x6f,0x99,0xfb,0x8d,0x64,0xee,0x3f,0x22,0x73,0x6f,0x79,0xfb,0xcf,0xa4, |
4462 | | 0x52,0x98,0x95,0xee,0x51,0xf7,0xfd,0x0a,0x1e,0x75,0xb5,0x74,0x06,0x1e,0xf5,0x05, |
4463 | | 0x78,0xd4,0x17,0x77,0xe0,0x51,0xcf,0x08,0x1e,0xf5,0x0f,0xa4,0xeb,0xa4,0x59,0x78, |
4464 | | 0xd4,0xf3,0xa4,0x5b,0xa5,0xdb,0xc9,0xf8,0xaf,0x86,0x7d,0x99,0xc6,0xa3,0x2e,0xc2, |
4465 | | 0xa3,0x2e,0x21,0xeb,0x7f,0x58,0xc8,0xfa,0x5b,0xc6,0xbf,0xf7,0x17,0x78,0xd4,0x9e, |
4466 | | 0xf1,0xb7,0x2c,0xff,0x08,0xb2,0xfc,0x63,0xc9,0xf2,0x4f,0x90,0x6a,0xa5,0xa9,0x64, |
4467 | | 0xf7,0x6f,0x95,0x0e,0x39,0xa1,0xcd,0xa3,0x1e,0xdc,0x5b,0xe7,0x7e,0xd2,0x1d,0x78, |
4468 | | 0xd4,0x27,0xf5,0xd1,0x79,0x87,0x34,0x57,0xfa,0xb9,0xf4,0x57,0xe9,0xe1,0x93,0x12, |
4469 | | 0x8f,0xba,0xa5,0xaf,0xd4,0x4f,0x8f,0x25,0x9d,0x50,0xde,0x29,0xb5,0x48,0x03,0x75, |
4470 | | 0x62,0x79,0x01,0xf9,0xff,0xf7,0xc9,0xff,0x6f,0x27,0xff,0xdf,0x72,0x4a,0x5b,0xfe, |
4471 | | 0xff,0x54,0x32,0xff,0x33,0xf1,0xa8,0x7f,0x4a,0xd6,0xff,0x51,0x32,0xfe,0xab,0xc8, |
4472 | | 0xf6,0xff,0x9e,0x4c,0xff,0x3b,0xb0,0x2c,0xcf,0x1e,0xa8,0xc7,0xbc,0xb4,0x53,0x7a, |
4473 | | 0x5d,0x27,0xaf,0xfb,0xf0,0xa8,0x33,0x64,0xfb,0x7b,0x91,0xed,0x3f,0x15,0x96,0x65, |
4474 | | 0x25,0x19,0xff,0xa1,0x64,0xfa,0xc7,0x90,0xe9,0xbf,0x9b,0x4c,0xff,0x62,0x3c,0x6a, |
4475 | | 0xe7,0x54,0x5a,0x7e,0xbf,0x82,0xdc,0xbe,0x65,0xf6,0xdf,0x93,0x8e,0x19,0xa4,0xe7, |
4476 | | 0xbb,0x54,0x2b,0x4d,0x95,0xae,0x93,0x66,0x49,0x4d,0xd2,0x6a,0xe9,0x25,0x69,0x9d, |
4477 | | 0x74,0x55,0x95,0x8e,0x9d,0xf4,0xb6,0xb4,0x51,0xfa,0x0c,0x8f,0xda,0xb2,0xfe,0x2d, |
4478 | | 0xd2,0xfe,0xc5,0x49,0xbe,0xff,0xbf,0x7f,0x91,0xe4,0xf8,0xbb,0x91,0xdf,0xb7,0xcc, |
4479 | | 0xfe,0x15,0x78,0xd4,0xce,0x9f,0xbc,0x07,0xd6,0xe4,0x47,0xb0,0x25,0x77,0x4b,0xc7, |
4480 | | 0x87,0x5c,0xfe,0x6a,0xe9,0x77,0x81,0x03,0xe9,0xfc,0x47,0xe7,0x3e,0xf6,0x09,0x8c, |
4481 | | 0xc7,0x01,0x78,0xd4,0x43,0xa5,0xd3,0xc8,0xda,0x5f,0x0d,0xd3,0x71,0x0d,0x2c,0xc7, |
4482 | | 0xed,0x81,0xd9,0x78,0x22,0x7c,0xc6,0x33,0xe1,0x32,0x9e,0x43,0xce,0x7e,0x76,0xe0, |
4483 | | 0x2f,0x3e,0x0e,0x73,0xf1,0x29,0x58,0x8b,0x6b,0x61,0x2b,0x3a,0x57,0xd1,0x72,0xf6, |
4484 | | 0xfd,0xe0,0x25,0x56,0xc2,0x49,0xac,0x86,0x8f,0xe8,0x6c,0xc4,0xaf,0x07,0x8f,0x7a, |
4485 | | 0x72,0x60,0x1c,0x2e,0x0f,0x1e,0xf5,0x63,0x64,0xec,0x9f,0x24,0x63,0xbf,0x3a,0xcf, |
4486 | | 0xa3,0xfe,0x00,0x16,0xa1,0xf3,0x06,0x8b,0xc8,0xd0,0x1f,0x4e,0x76,0x7e,0x20,0xd9, |
4487 | | 0xf8,0x6f,0x07,0x56,0xa0,0x33,0x02,0x9d,0x09,0x68,0x2c,0xc0,0xfb,0xc8,0xc8,0x5b, |
4488 | | 0x3e,0xfe,0x3b,0xe4,0xe2,0x8b,0x42,0x1e,0xbe,0x27,0x59,0xf8,0xfe,0x64,0xe1,0x3d, |
4489 | | 0x07,0x7f,0x3a,0xd9,0xf7,0x5a,0xe9,0x59,0x72,0xef,0x63,0xc8,0xbd,0x5b,0xe6,0x7d, |
4490 | | 0x3f,0x1e,0xb5,0x71,0xfc,0x8e,0x84,0xe3,0x57,0x7b,0x10,0x8f,0xfa,0x02,0x3c,0xea, |
4491 | | 0x0b,0xa5,0x8b,0xa4,0x4b,0xf0,0xa8,0xa7,0xe3,0x51,0x37,0x90,0x97,0x37,0x8f,0xba, |
4492 | | 0xa0,0x45,0x3f,0x73,0xa9,0x34,0xcf,0xa3,0xee,0x06,0x03,0xd0,0x3c,0xea,0x5e,0xe4, |
4493 | | 0xea,0x6b,0x02,0xff,0x6f,0x15,0x99,0xf9,0x75,0x64,0xe5,0x2d,0x27,0xbf,0x59,0xfa, |
4494 | | 0x93,0xf4,0x17,0xe9,0x6f,0xd2,0x01,0xfb,0x9a,0x64,0xe6,0x87,0x93,0x95,0x9f,0x40, |
4495 | | 0x46,0x7e,0x6f,0x9e,0x47,0x5d,0x25,0x8d,0x91,0x6e,0x93,0x6e,0x97,0x16,0xe1,0x51, |
4496 | | 0xef,0xc7,0xa3,0x5e,0x14,0x98,0x7e,0xfb,0xa4,0xde,0x64,0xe4,0xbf,0x0f,0xab,0xef, |
4497 | | 0x1e,0xb2,0xf1,0x96,0x87,0xbf,0x07,0x0e,0xdf,0x06,0xf2,0xef,0x7d,0xc9,0xbd,0x9b, |
4498 | | 0x47,0x3d,0x84,0xac,0xba,0xe5,0xd4,0x3d,0x8b,0x3e,0x38,0xe4,0xcf,0xcf,0x25,0x6b, |
4499 | | 0xbe,0x9c,0xac,0xb9,0xe5,0xcc,0x8f,0x2e,0x49,0x3c,0xea,0xd3,0xf0,0xa8,0x2d,0x5b, |
4500 | | 0xbe,0x8e,0x5c,0x79,0x27,0x58,0x76,0xdd,0xc8,0x96,0xf7,0x20,0x53,0xee,0xdc,0xba, |
4501 | | 0xf1,0xd2,0x79,0xd2,0x62,0xb2,0xe4,0xc6,0xa7,0xfb,0xa4,0x34,0xc9,0x93,0x8f,0x21, |
4502 | | 0x4f,0x7e,0x05,0x39,0xf2,0x45,0xd2,0xf2,0xb2,0x24,0x4b,0xfe,0x9f,0x64,0xc8,0x5b, |
4503 | | 0x3a,0x27,0x19,0xf2,0xbe,0xb0,0xe8,0x66,0x91,0x0d,0x7f,0x04,0x8f,0xda,0xf2,0xe1, |
4504 | | 0x7d,0xc9,0x7d,0x1b,0x13,0x6e,0xb2,0xf4,0x52,0xe0,0xbf,0xa5,0xc9,0x7c,0x1b,0xe7, |
4505 | | 0x6d,0x82,0x34,0x0d,0xd6,0xdb,0x8d,0x30,0xdb,0x9e,0x80,0xd5,0x66,0x9c,0xb6,0x67, |
4506 | | 0xf1,0xa8,0xb7,0xc0,0x67,0x2b,0x20,0x07,0xee,0x4c,0xb6,0x6a,0x72,0xe0,0x57,0x04, |
4507 | | 0xce,0xda,0x8d,0xb0,0xd4,0x8c,0xa3,0xf6,0x62,0xe0,0xa6,0x99,0x47,0xbd,0x51,0xda, |
4508 | | 0x75,0x48,0x92,0x01,0x1f,0x08,0x0b,0xad,0x2a,0x78,0xd4,0xc6,0x3e,0x1b,0x85,0x47, |
4509 | | 0xed,0x79,0xf0,0x05,0x64,0xc0,0x97,0x06,0xa6,0xd9,0xbb,0x70,0xcc,0x8c,0x61,0x96, |
4510 | | 0x86,0x5d,0xd6,0x99,0x2c,0x78,0x3f,0x32,0xe0,0x55,0x64,0xbf,0x47,0x06,0x26,0xd9, |
4511 | | 0x58,0x38,0x64,0x13,0x82,0x47,0x7d,0x11,0xac,0x31,0xe3,0x8c,0x0d,0x85,0xe3,0x75, |
4512 | | 0x7a,0xe0,0x77,0x99,0x47,0x3d,0x25,0x78,0xd4,0x17,0xc2,0xe6,0x7a,0x32,0x78,0xd4, |
4513 | | 0xab,0x02,0x87,0xeb,0x79,0x32,0xdf,0xc6,0xdb,0x5a,0x01,0x5f,0xeb,0xa9,0xc0,0xd5, |
4514 | | 0x6a,0x26,0x03,0x6e,0x1c,0xad,0x41,0x70,0xb3,0x46,0x06,0x8f,0xda,0x39,0x59,0xc6, |
4515 | | 0xc7,0xba,0x3c,0xf0,0xb1,0xdc,0xa3,0x5e,0x1e,0x58,0x58,0xee,0x51,0x1b,0xfb,0xea, |
4516 | | 0x28,0xd8,0x56,0xc7,0x07,0xa6,0x95,0xb1,0xac,0xc6,0xf4,0x48,0x98,0x55,0xce,0xab, |
4517 | | 0x1a,0x8e,0x47,0xbd,0x23,0x64,0xc8,0x0f,0x25,0x37,0x3e,0x18,0xfe,0xd4,0xc8,0xe0, |
4518 | | 0x51,0x3b,0x57,0xea,0x4c,0x98,0x52,0x0f,0xc2,0x90,0x7a,0x03,0x76,0x94,0x73,0xa3, |
4519 | | 0x9c,0x0f,0x55,0x24,0x65,0xe1,0x43,0x0d,0x82,0x0b,0x35,0x1c,0x0e,0xd4,0x99,0xc1, |
4520 | | 0xa3,0x9e,0x04,0xfb,0x69,0x0a,0x99,0x72,0xe7,0x3d,0x19,0xe7,0xe9,0x3f,0xc8,0x95, |
4521 | | 0x67,0xe1,0x31,0x0d,0x81,0xc3,0x34,0x4e,0xba,0x9c,0x2c,0xb9,0x73,0x96,0x9c,0xaf, |
4522 | | 0xe4,0x5c,0x25,0xe3,0x29,0x15,0x91,0x2f,0xaf,0x0c,0xfc,0xa4,0x51,0x81,0x99,0x74, |
4523 | | 0x16,0x9c,0xa4,0x69,0xe4,0xcc,0x6f,0x87,0x87,0x74,0x47,0x07,0x1e,0xb5,0x71,0x8f, |
4524 | | 0x76,0xc0,0x33,0xfa,0x14,0x8f,0xfa,0x35,0xe9,0x8f,0xd2,0x26,0x69,0xfb,0x71,0x49, |
4525 | | 0xa6,0xdc,0xf2,0xe4,0x0d,0xe4,0xc9,0x07,0x56,0xeb,0xfb,0xae,0x4e,0x32,0xe3,0xc3, |
4526 | | 0xc8,0x88,0x1b,0x07,0x68,0x06,0xf9,0xf0,0x5d,0x78,0xd4,0x15,0xf0,0x7e,0xc6,0xc1, |
4527 | | 0xf9,0xb9,0x90,0x9c,0xb8,0x65,0xc4,0xef,0xfe,0x6e,0x1b,0xab,0x67,0x2e,0x5c,0x9e, |
4528 | | 0xc5,0xe4,0xbd,0xa3,0x47,0x6d,0x1c,0x9e,0xdd,0x73,0x93,0x9c,0x77,0x76,0x41,0x3a, |
4529 | | 0xd5,0x93,0xcc,0xf6,0xa5,0x64,0xb4,0xa7,0x93,0xcd,0xbe,0x85,0x4c,0xf6,0x22,0x18, |
4530 | | 0x39,0xe6,0x51,0xdf,0x27,0x7d,0xbc,0x5e,0x8f,0x15,0xb8,0x38,0x97,0xc1,0xc3,0xb9, |
4531 | | 0x16,0x1e,0xce,0x4d,0xf0,0x70,0x96,0xc2,0xc3,0xd9,0x22,0x9d,0x0e,0x13,0xc7,0x3c, |
4532 | | 0xea,0x9d,0xd2,0xa4,0x0d,0xe9,0xd4,0x35,0x1b,0x92,0x9c,0xf7,0xa2,0x90,0xef,0x7e, |
4533 | | 0x80,0x4c,0xb7,0xe7,0xb9,0x9f,0x27,0xc3,0x5d,0x4a,0x76,0xfb,0x18,0x32,0xdb,0xa3, |
4534 | | 0x43,0x56,0xbb,0x8e,0x7c,0xf6,0x9b,0x78,0xd4,0x96,0xc5,0xee,0x4e,0x06,0xbb,0x96, |
4535 | | 0xec,0xf5,0x3c,0x32,0xd7,0xcf,0x93,0xb9,0x36,0x4e,0x4d,0xcb,0xff,0x26,0x9c,0x9a, |
4536 | | 0xe1,0x70,0x6a,0x1a,0xf0,0xa8,0xe7,0xe0,0x51,0xdf,0x0a,0xa7,0xc6,0x18,0x35,0x45, |
4537 | | 0xb0,0x67,0x8e,0x87,0x39,0x63,0xbc,0x99,0x53,0xe0,0xca,0x8c,0x82,0x27,0x53,0xbb, |
4538 | | 0x39,0xc9,0x5f,0x7f,0x04,0x2f,0xc6,0x3c,0x6a,0xcb,0x43,0xaf,0x83,0xbb,0x72,0x46, |
4539 | | 0xe0,0xad,0x18,0x67,0x65,0xaa,0xf4,0xd8,0x87,0xfa,0xfb,0x5b,0x93,0x7c,0xf4,0x71, |
4540 | | 0x21,0x17,0xdd,0x97,0x2c,0xf4,0xd0,0x2f,0xf0,0xa8,0x6b,0x43,0xce,0xb9,0x23,0x8f, |
4541 | | 0xda,0xb3,0xcc,0xd3,0xc9,0x2f,0x5f,0x1d,0x72,0xcb,0xf3,0xc8,0x2a,0xdf,0x47,0x46, |
4542 | | 0xd9,0xf2,0xc9,0xdb,0xa5,0x01,0xdb,0xd2,0xa9,0x7f,0x93,0x1e,0x95,0x56,0x4b,0xeb, |
4543 | | 0xa4,0x8f,0xa5,0xd2,0xed,0xfa,0xb7,0x49,0x1a,0x88,0x47,0x7d,0x99,0x34,0x43,0x7a, |
4544 | | 0x04,0x8f,0xba,0x60,0x87,0xee,0xa3,0x34,0x5e,0x9a,0x28,0x4d,0x93,0xde,0xf8,0x24, |
4545 | | 0x9d,0xfa,0x50,0xda,0x2f,0x5d,0xb9,0x3b,0x9d,0xfa,0x1f,0xe9,0x03,0xa9,0xec,0x53, |
4546 | | 0x7d,0x1f,0xd2,0x64,0x69,0xae,0xb4,0x4c,0x5a,0x21,0x5d,0xb3,0x47,0x3f,0x1b,0xe9, |
4547 | | 0x9c,0xbd,0x69,0x9d,0xf3,0xe8,0xe7,0x21,0x5d,0x2b,0xfd,0x48,0x7a,0x48,0x7a,0x42, |
4548 | | 0x7a,0x4e,0xfa,0x83,0xf4,0x93,0x7d,0xe9,0xd4,0xef,0xe0,0xb3,0xbc,0xfd,0x40,0x41, |
4549 | | 0xaa,0xfa,0x57,0x49,0xa6,0xfa,0x5e,0xb2,0xd4,0x96,0x9f,0xb6,0xec,0xb4,0x79,0xd4, |
4550 | | 0x37,0xa4,0x12,0xfe,0xca,0x81,0x96,0x6e,0x52,0x79,0x2a,0x7d,0x78,0xf7,0xc3,0x3b, |
4551 | | 0x77,0x4f,0xeb,0x55,0xa6,0x2c,0xd3,0xa9,0xa0,0x53,0x41,0x61,0x41,0xa6,0x48,0x2f, |
4552 | | 0xe9,0xee,0xe9,0x02,0x5d,0xa3,0x77,0x32,0x65,0x85,0x7a,0x53,0x58,0x94,0x69,0xff, |
4553 | | 0x92,0xd5,0x2b,0xde,0x2f,0xb2,0x77,0xb2,0xf6,0x3a,0x53,0x96,0x2d,0xf6,0x97,0xe2, |
4554 | | 0xd2,0x4c,0x49,0x59,0x49,0x41,0x49,0x26,0x5b,0x52,0x92,0x2d,0x2d,0x2b,0x2d,0xc9, |
4555 | | 0xea,0x8d,0xfe,0x90,0x95,0x0a,0x4b,0xec,0x4f,0x7a,0xd1,0xe7,0x65,0x8a,0xc3,0xdf, |
4556 | | 0xc9,0x16,0x97,0xd8,0x67,0x67,0x8b,0xda,0xbf,0x24,0x97,0xdc,0x7b,0xd9,0xe4,0xbd, |
4557 | | 0x32,0xbd,0x64,0xfd,0x03,0xf6,0x91,0x6c,0xee,0x4f,0x79,0x9f,0x9e,0x7c,0x7e,0x36, |
4558 | | 0x7e,0x2e,0x9f,0xd1,0xfa,0xd9,0x6d,0x97,0x2c,0xd2,0xb7,0xed,0x1f,0xc8,0x7d,0xdd, |
4559 | | 0xdc,0xb5,0x99,0xd6,0x6b,0x5a,0x95,0x0d,0x77,0xa9,0xf5,0x2b,0x65,0xb9,0x25,0xbd, |
4560 | | 0x2d,0x6b,0x7f,0xc7,0x8b,0xda,0xee,0x5f,0x36,0xd3,0xfa,0x5e,0x36,0x5e,0xdd,0xe1, |
4561 | | 0x77,0x5d,0xd4,0xfe,0x2e,0xe6,0x8e,0x7a,0xe7,0xdc,0x51,0x8f,0x37,0x9e,0xbc,0xd8, |
4562 | | 0x4d,0x66,0x32,0xd9,0x74,0xb8,0xcd,0xe4,0xe3,0x99,0xdc,0x4f,0x29,0xf7,0x5d,0xb4, |
4563 | | 0xde,0x2c,0x77,0x35,0x1b,0x6e,0xb0,0x83,0xfb,0x90,0xf5,0x23,0x1e,0xaf,0x8b,0xf7, |
4564 | | 0x2d,0x93,0xdc,0x25,0xde,0x76,0x4e,0x17,0x15,0x67,0x3a,0x77,0xef,0x51,0xde,0xad, |
4565 | | 0x6b,0x97,0x82,0xb2,0x4c,0x81,0xae,0x38,0xec,0x90,0xaf,0x1d,0x9a,0x2e,0x2c,0x2a, |
4566 | | 0xec,0x94,0xc9,0xa9,0x2c,0x9b,0xc9,0x7f,0x2c,0xe9,0x7e,0xb7,0xbe,0x9f,0xe9,0x54, |
4567 | | 0x96,0xbc,0xf5,0x87,0x5c,0xee,0xae,0xdb,0x1d,0xcf,0xb4,0xfe,0x00,0x38,0x18,0x19, |
4568 | | 0xbb,0x74,0xce,0xf0,0xc1,0xdc,0xdb,0xf0,0x80,0xfc,0xfc,0x4b,0xf2,0x4a,0x8f,0xbf, |
4569 | | 0xe4,0x30,0x64,0x5a,0x0f,0x62,0xee,0x4f,0xd9,0xdc,0xbd,0xe8,0xe0,0x60,0xe4,0x1d, |
4570 | | 0xe3,0xa2,0x0e,0x8f,0x4f,0xdb,0xb1,0xe5,0xa2,0x87,0x72,0xa7,0xe2,0xdc,0xa5,0xa4, |
4571 | | 0x24,0xa3,0x07,0x75,0xc6,0x6e,0xb7,0x20,0xf7,0xa2,0x27,0x9a,0x9e,0x29,0xba,0x32, |
4572 | | 0xdd,0xfe,0x39,0x97,0xfb,0x7b,0x65,0xba,0x2e,0xd3,0x76,0x6c,0x73,0x77,0x3a,0xf7, |
4573 | | 0xe0,0xcb,0x16,0xb6,0xfb,0xee,0x73,0xb7,0xd1,0x76,0xc9,0xe4,0x5e,0xeb,0xd1,0x9a, |
4574 | | 0x7b,0x9d,0x7b,0xdf,0xaf,0xcc,0xdd,0x87,0x6c,0x69,0xa9,0x5d,0x53,0x6c,0xcf,0xb9, |
4575 | | 0x62,0xbe,0xfd,0x6c,0xfb,0x1f,0x6e,0xfb,0x47,0x5e,0xbb,0x07,0xe1,0xe7,0x9e,0x85, |
4576 | | 0x45,0xf1,0x81,0x93,0x7f,0xb0,0xda,0x1d,0x9f,0xcc,0xe7,0x3e,0x14,0x8f,0x52,0xdb, |
4577 | | 0xcd,0x1d,0xec,0xf1,0x17,0x9e,0xaa,0x7c,0x91,0x6c,0xb6,0xfd,0xdd,0xf6,0x27,0x6d, |
4578 | | 0xde,0x13,0xa5,0xdd,0xfd,0xcd,0xe4,0x1d,0xb9,0x6c,0x51,0xf2,0x1c,0x49,0xfb,0x0f, |
4579 | | 0xdf,0x0f,0x7f,0xfe,0xa5,0xed,0xd1,0x53,0xd8,0x76,0xaf,0x92,0x4b,0xeb,0xaf,0xa2, |
4580 | | 0xe2,0xe4,0x77,0x97,0xfd,0xea,0xfa,0xb2,0x4b,0x26,0xb9,0x14,0x66,0xc2,0xaf,0xce, |
4581 | | 0x83,0x5e,0x0a,0xb9,0x0f,0x69,0xdd,0xcb,0xa2,0x54,0xdb,0x4e,0xdb,0x39,0xcc,0xcd, |
4582 | | 0xbe,0xea,0x2e,0x59,0xdf,0x1d,0xeb,0x3b,0x62,0x7d,0x27,0x6c,0xfe,0x0e,0xd8,0xfc, |
4583 | | 0xdd,0xaf,0xbe,0xd3,0xd5,0x77,0xb9,0xfa,0x0e,0x57,0xdf,0xd5,0xea,0xbb,0x59,0x7d, |
4584 | | 0x27,0xab,0xef,0x62,0xf5,0x1d,0xac,0xbe,0x7b,0xd5,0x77,0xae,0x6e,0x08,0x3b,0x54, |
4585 | | 0xbd,0x63,0x31,0x92,0xdd,0xa8,0xb5,0x61,0xe7,0xa9,0xef,0x3a,0xf5,0x79,0x95,0xef, |
4586 | | 0x26,0x5d,0xd5,0xc1,0x2e,0xd2,0xb5,0x61,0xf7,0xa8,0xef,0x1a,0xfd,0x2c,0xaf,0x2f, |
4587 | | 0x11,0x77,0x82,0x7e,0xd1,0x2e,0x50,0xdf,0xf9,0x19,0x77,0x7d,0xce,0x09,0x3b,0x3b, |
4588 | | 0x57,0x85,0x1d,0x9d,0xb1,0x03,0xe1,0x3b,0x38,0xf7,0xe6,0xcd,0x94,0x46,0x86,0xf9, |
4589 | | 0x51,0xfe,0x6e,0xcc,0xd8,0x6f,0xf0,0xdd,0x97,0xbe,0xeb,0x72,0x55,0x07,0xbb,0x28, |
4590 | | 0xd7,0x86,0xdd,0x93,0x29,0x66,0x3f,0xa3,0xbf,0x64,0x57,0xa4,0xef,0x84,0xbc,0x91, |
4591 | | 0xdd,0x8f,0xbe,0xd3,0x71,0x55,0xd8,0xdd,0xe8,0x3b,0x1b,0xe3,0xae,0x46,0xdf,0xcd, |
4592 | | 0x98,0x62,0xf7,0xa2,0xef,0x58,0x1c,0xdd,0xc1,0x4e,0xc5,0x09,0x61,0x77,0xa2,0xef, |
4593 | | 0x4c,0xf4,0x99,0x4e,0xdc,0x79,0xd8,0xd1,0xae,0x43,0xdf,0x71,0xe8,0xbb,0x0d,0x7d, |
4594 | | 0xa7,0xa1,0xef,0x30,0xf4,0x5d,0x84,0xbe,0x83,0xf0,0x45,0xe6,0x34,0xbe,0x53,0xf0, |
4595 | | 0xcb,0x76,0x09,0x7e,0x2f,0x6f,0x57,0xe0,0xc1,0x76,0x04,0x0e,0x60,0xf6,0x32,0x89, |
4596 | | 0xd9,0x8b,0xef,0xee,0xf3,0x9d,0x7d,0xbe,0xab,0xcf,0x77,0xf4,0xcd,0x66,0xf6,0xe2, |
4597 | | 0x3b,0xf7,0xee,0x66,0x06,0xe3,0x3b,0xeb,0x7c,0xb7,0xdc,0x20,0x66,0x21,0xbe,0x3b, |
4598 | | 0xce,0x77,0xc5,0x3d,0xc6,0xac,0xc3,0x77,0xbc,0xf9,0x6e,0x37,0x67,0x01,0xf9,0x8e, |
4599 | | 0xb6,0x5e,0x61,0xe7,0x9a,0xcd,0x2c,0x7a,0x84,0x59,0x84,0xcf,0x20,0xe2,0xee,0xb2, |
4600 | | 0x26,0x66,0x0d,0x31,0x0f,0x3f,0x36,0x6f,0x77,0xd8,0x6c,0x66,0x0a,0xcb,0x98,0x1f, |
4601 | | 0xd8,0x9c,0xa0,0x0f,0xf3,0x81,0xb8,0x53,0x6b,0x4b,0xd8,0x9d,0xb5,0x2b,0x6f,0x16, |
4602 | | 0xd0,0xcc,0x1c,0x60,0x1f,0xb3,0x80,0xf5,0xf8,0xe3,0xbe,0x5b,0xc9,0x77,0x25,0xf9, |
4603 | | 0x8e,0xa3,0x93,0xf1,0x7b,0x7d,0x27,0xd1,0x0c,0x3c,0x55,0xdf,0xe9,0xe3,0xbb,0x7b, |
4604 | | 0x7c,0x57,0x8f,0xef,0xce,0xf1,0x9d,0x39,0xbe,0x2b,0xa7,0x77,0xde,0x4e,0x1c,0xdf, |
4605 | | 0x85,0xf3,0x18,0x5e,0xa9,0xef,0xbc,0xf1,0xdd,0x36,0xbe,0xcb,0xe6,0x2c,0x7c,0xd2, |
4606 | | 0x98,0xe3,0x6d,0x0e,0x3b,0x66,0xfa,0xe3,0x7d,0xfa,0x4e,0x18,0xf7,0x3d,0xaf,0x0b, |
4607 | | 0x99,0xdc,0xa6,0xb0,0xbb,0xc5,0x77,0xb6,0xf8,0xae,0x16,0xdf,0xd1,0xf2,0x01,0x3b, |
4608 | | 0x57,0xdc,0xef,0x7c,0x2f,0xec,0x38,0x31,0x2f,0xd3,0x77,0x92,0xe4,0xef,0x0e,0xf1, |
4609 | | 0x5d,0x1b,0xbe,0x5b,0xc3,0x77,0x65,0x1c,0x6c,0xb7,0x43,0xfe,0x0e,0x07,0xdf,0xd1, |
4610 | | 0xe0,0x3b,0x16,0x7c,0x27,0x82,0xef,0x34,0x48,0x85,0x4c,0xe5,0x99,0x21,0x4b,0xd9, |
4611 | | 0x84,0x47,0xe5,0x3b,0x03,0xfa,0xe2,0x47,0xf9,0x2e,0x00,0x67,0xff,0x7b,0x66,0x72, |
4612 | | 0x25,0x4c,0xff,0xdf,0xe6,0x79,0x52,0xa7,0xe4,0x31,0xf7,0x37,0xe2,0x2d,0xa5,0xf0, |
4613 | | 0x95,0x9c,0x71,0x3f,0xfa,0x20,0x2c,0x7b,0x67,0xd8,0x1f,0x8c,0x5d,0x3f,0x18,0x0f, |
4614 | | 0xc9,0x59,0xef,0x4d,0x78,0x44,0xcb,0x03,0x7b,0xbd,0x39,0xb0,0xd5,0x2b,0xf1,0x80, |
4615 | | 0x1e,0xc6,0xdf,0x39,0x16,0x1f,0xe7,0x14,0xbc,0x9b,0x8e,0x58,0xe1,0xa3,0x03,0x13, |
4616 | | 0xdc,0xfd,0x9a,0x57,0x02,0xe3,0x7b,0x53,0x60,0x78,0x3b,0xbb,0x3b,0x66,0x07,0x23, |
4617 | | 0xa3,0x7b,0x22,0x9e,0xcc,0x7c,0xbc,0x98,0x8a,0xc0,0xc2,0x1e,0x93,0xc7,0xb8,0x36, |
4618 | | 0xaf,0xe5,0xcb,0x18,0xd5,0xce,0xa6,0xee,0x88,0x3d,0x6d,0x1e,0xcb,0x4e,0x18,0xd1, |
4619 | | 0xce,0x42,0x76,0x06,0xb2,0x33,0x8a,0xf3,0xd9,0xc4,0xf9,0x0c,0x62,0x67,0xfe,0x4e, |
4620 | | 0xfb,0x7b,0x99,0xbe,0x7f,0x2f,0xdb,0xf6,0xab,0xb2,0x6b,0xf1,0x12,0x9c,0x39,0xeb, |
4621 | | 0xac,0x56,0x67,0xb4,0x3a,0x43,0xf4,0xff,0x01, |
4622 | | }; |
4623 | | } // namespace ada::idna::table_blob |
4624 | | #endif |
4625 | | /* end file src/table_blob.inc */ |
4626 | | |
4627 | | #include <atomic> |
4628 | | #include <bit> |
4629 | | #include <cstdint> |
4630 | | #include <cstddef> |
4631 | | #include <new> |
4632 | | |
4633 | | namespace ada::idna { |
4634 | | |
4635 | | // table_blob.inc is packed little-endian (see scripts/pack_tables.py). After |
4636 | | // inflate the multi-byte sections must be converted to host endianness so |
4637 | | // big-endian platforms (s390x) can load uint16_t/uint32_t/uint64_t natively. |
4638 | | // CRC is checked on the raw little-endian payload before any conversion. |
4639 | | namespace detail { |
4640 | | |
4641 | | template <typename T> |
4642 | 0 | inline void bswap_inplace(T* data, size_t count) noexcept { |
4643 | 0 | if constexpr (std::endian::native == std::endian::little) { |
4644 | 0 | (void)data; |
4645 | 0 | (void)count; |
4646 | 0 | return; |
4647 | 0 | } |
4648 | 0 | for (size_t i = 0; i < count; ++i) { |
4649 | 0 | if constexpr (sizeof(T) == 2) { |
4650 | 0 | #if defined(__GNUC__) || defined(__clang__) |
4651 | 0 | data[i] = |
4652 | 0 | static_cast<T>(__builtin_bswap16(static_cast<uint16_t>(data[i]))); |
4653 | 0 | #else |
4654 | 0 | const auto v = static_cast<uint16_t>(data[i]); |
4655 | 0 | data[i] = static_cast<T>(static_cast<uint16_t>((v >> 8) | (v << 8))); |
4656 | 0 | #endif |
4657 | 0 | } else if constexpr (sizeof(T) == 4) { |
4658 | 0 | #if defined(__GNUC__) || defined(__clang__) |
4659 | 0 | data[i] = |
4660 | 0 | static_cast<T>(__builtin_bswap32(static_cast<uint32_t>(data[i]))); |
4661 | 0 | #else |
4662 | 0 | auto v = static_cast<uint32_t>(data[i]); |
4663 | 0 | v = ((v & 0x000000FFu) << 24) | ((v & 0x0000FF00u) << 8) | |
4664 | 0 | ((v & 0x00FF0000u) >> 8) | ((v & 0xFF000000u) >> 24); |
4665 | 0 | data[i] = static_cast<T>(v); |
4666 | 0 | #endif |
4667 | 0 | } else if constexpr (sizeof(T) == 8) { |
4668 | 0 | #if defined(__GNUC__) || defined(__clang__) |
4669 | 0 | data[i] = |
4670 | 0 | static_cast<T>(__builtin_bswap64(static_cast<uint64_t>(data[i]))); |
4671 | 0 | #else |
4672 | 0 | auto v = static_cast<uint64_t>(data[i]); |
4673 | 0 | v = ((v & 0x00000000000000FFull) << 56) | |
4674 | 0 | ((v & 0x000000000000FF00ull) << 40) | |
4675 | 0 | ((v & 0x0000000000FF0000ull) << 24) | |
4676 | 0 | ((v & 0x00000000FF000000ull) << 8) | |
4677 | 0 | ((v & 0x000000FF00000000ull) >> 8) | |
4678 | 0 | ((v & 0x0000FF0000000000ull) >> 24) | |
4679 | 0 | ((v & 0x00FF000000000000ull) >> 40) | |
4680 | 0 | ((v & 0xFF00000000000000ull) >> 56); |
4681 | 0 | data[i] = static_cast<T>(v); |
4682 | 0 | #endif |
4683 | 0 | } else { |
4684 | 0 | static_assert(sizeof(T) == 2 || sizeof(T) == 4 || sizeof(T) == 8); |
4685 | 0 | } |
4686 | 0 | } |
4687 | 0 | } Unexecuted instantiation: void ada::idna::detail::bswap_inplace<unsigned short>(unsigned short*, unsigned long) Unexecuted instantiation: void ada::idna::detail::bswap_inplace<unsigned int>(unsigned int*, unsigned long) Unexecuted instantiation: void ada::idna::detail::bswap_inplace<unsigned long>(unsigned long*, unsigned long) |
4688 | | |
4689 | | // Convert every multi-byte section of the inflated little-endian blob to host |
4690 | | // order. Single-byte sections are left unchanged. Safe no-op on little-endian. |
4691 | 1 | inline void convert_table_blob_to_host_endian(uint8_t* buffer) noexcept { |
4692 | 1 | if constexpr (std::endian::native == std::endian::little) { |
4693 | 1 | (void)buffer; |
4694 | 1 | return; |
4695 | 1 | } |
4696 | 0 | auto u16 = [&](size_t off, size_t count) { |
4697 | 1 | bswap_inplace(reinterpret_cast<uint16_t*>(buffer + off), count); |
4698 | 1 | }; |
4699 | 1 | auto u32 = [&](size_t off, size_t count) { |
4700 | 1 | bswap_inplace(reinterpret_cast<uint32_t*>(buffer + off), count); |
4701 | 1 | }; |
4702 | 1 | auto u64 = [&](size_t off, size_t count) { |
4703 | 1 | bswap_inplace(reinterpret_cast<uint64_t*>(buffer + off), count); |
4704 | 1 | }; |
4705 | | |
4706 | 1 | u16(table_blob::off_idna_stage1, table_blob::count_idna_stage1); |
4707 | 1 | u16(table_blob::off_idna_stage2, table_blob::count_idna_stage2); |
4708 | 1 | u64(table_blob::off_idna_bool_blocks, table_blob::count_idna_bool_blocks); |
4709 | 1 | u16(table_blob::off_decomposition_block, |
4710 | 1 | table_blob::count_decomposition_block); |
4711 | 1 | u32(table_blob::off_decomposition_data, table_blob::count_decomposition_data); |
4712 | 1 | u16(table_blob::off_composition_block, table_blob::count_composition_block); |
4713 | 1 | u32(table_blob::off_composition_data, table_blob::count_composition_data); |
4714 | 1 | u32(table_blob::off_id_continue_flat, table_blob::count_id_continue_flat); |
4715 | 1 | u32(table_blob::off_id_start_flat, table_blob::count_id_start_flat); |
4716 | 1 | u32(table_blob::off_dir_start, table_blob::count_dir_start); |
4717 | 1 | u32(table_blob::off_dir_final, table_blob::count_dir_final); |
4718 | 1 | u32(table_blob::off_combining_flat, table_blob::count_combining_flat); |
4719 | 1 | } |
4720 | | |
4721 | | } // namespace detail |
4722 | | |
4723 | | // --- Blob layout invariants -------------------------------------------------- |
4724 | | static_assert(table_blob::count_decomposition_index == 4352); |
4725 | | static_assert(table_blob::count_ccc_index == 4352); |
4726 | | static_assert(table_blob::count_composition_index == 4352); |
4727 | | static_assert(table_blob::count_decomposition_block == |
4728 | | table_blob::decomposition_block_rows * |
4729 | | table_blob::decomposition_block_cols); |
4730 | | static_assert(table_blob::count_ccc_block == |
4731 | | table_blob::ccc_block_rows * table_blob::ccc_block_cols); |
4732 | | static_assert(table_blob::count_composition_block == |
4733 | | table_blob::composition_block_rows * |
4734 | | table_blob::composition_block_cols); |
4735 | | static_assert(table_blob::count_dir_start == table_blob::dir_table_count && |
4736 | | table_blob::count_dir_final == table_blob::dir_table_count && |
4737 | | table_blob::count_dir_value == table_blob::dir_table_count); |
4738 | | static_assert(table_blob::count_id_continue_flat == |
4739 | | table_blob::id_continue_count * 2); |
4740 | | static_assert(table_blob::count_id_start_flat == |
4741 | | table_blob::id_start_count * 2); |
4742 | | static_assert(table_blob::count_combining_flat == |
4743 | | table_blob::combining_range_count * 2); |
4744 | | static_assert(table_blob::off_idna_stage1 % alignof(uint16_t) == 0); |
4745 | | static_assert(table_blob::off_idna_stage2 % alignof(uint16_t) == 0); |
4746 | | static_assert(table_blob::off_idna_bool_blocks % alignof(uint64_t) == 0); |
4747 | | static_assert(table_blob::off_decomposition_block % alignof(uint16_t) == 0); |
4748 | | static_assert(table_blob::off_decomposition_data % alignof(char32_t) == 0); |
4749 | | static_assert(table_blob::off_composition_block % alignof(uint16_t) == 0); |
4750 | | static_assert(table_blob::off_composition_data % alignof(char32_t) == 0); |
4751 | | static_assert(table_blob::off_id_continue_flat % alignof(uint32_t) == 0); |
4752 | | static_assert(table_blob::off_id_start_flat % alignof(uint32_t) == 0); |
4753 | | static_assert(table_blob::off_dir_start % alignof(uint32_t) == 0); |
4754 | | static_assert(table_blob::off_dir_final % alignof(uint32_t) == 0); |
4755 | | static_assert(table_blob::off_combining_flat % alignof(uint32_t) == 0); |
4756 | | static_assert(table_blob::compressed_size == sizeof(table_blob::compressed)); |
4757 | | |
4758 | | // Every section must lie entirely inside the uncompressed buffer. |
4759 | | #define ADA_IDNA_SECTION_IN_BOUNDS(off, count, width) \ |
4760 | | static_assert((off) + (count) * (width) <= table_blob::uncompressed_size, \ |
4761 | | #off " overflows uncompressed buffer") |
4762 | | ADA_IDNA_SECTION_IN_BOUNDS(table_blob::off_idna_stage1, |
4763 | | table_blob::count_idna_stage1, 2); |
4764 | | ADA_IDNA_SECTION_IN_BOUNDS(table_blob::off_idna_stage2, |
4765 | | table_blob::count_idna_stage2, 2); |
4766 | | ADA_IDNA_SECTION_IN_BOUNDS(table_blob::off_idna_bool_blocks, |
4767 | | table_blob::count_idna_bool_blocks, 8); |
4768 | | ADA_IDNA_SECTION_IN_BOUNDS(table_blob::off_idna_utf8_mappings, |
4769 | | table_blob::count_idna_utf8_mappings, 1); |
4770 | | ADA_IDNA_SECTION_IN_BOUNDS(table_blob::off_decomposition_index, |
4771 | | table_blob::count_decomposition_index, 1); |
4772 | | ADA_IDNA_SECTION_IN_BOUNDS(table_blob::off_decomposition_block, |
4773 | | table_blob::count_decomposition_block, 2); |
4774 | | ADA_IDNA_SECTION_IN_BOUNDS(table_blob::off_decomposition_data, |
4775 | | table_blob::count_decomposition_data, 4); |
4776 | | ADA_IDNA_SECTION_IN_BOUNDS(table_blob::off_ccc_index, |
4777 | | table_blob::count_ccc_index, 1); |
4778 | | ADA_IDNA_SECTION_IN_BOUNDS(table_blob::off_ccc_block, |
4779 | | table_blob::count_ccc_block, 1); |
4780 | | ADA_IDNA_SECTION_IN_BOUNDS(table_blob::off_composition_index, |
4781 | | table_blob::count_composition_index, 1); |
4782 | | ADA_IDNA_SECTION_IN_BOUNDS(table_blob::off_composition_block, |
4783 | | table_blob::count_composition_block, 2); |
4784 | | ADA_IDNA_SECTION_IN_BOUNDS(table_blob::off_composition_data, |
4785 | | table_blob::count_composition_data, 4); |
4786 | | ADA_IDNA_SECTION_IN_BOUNDS(table_blob::off_id_continue_flat, |
4787 | | table_blob::count_id_continue_flat, 4); |
4788 | | ADA_IDNA_SECTION_IN_BOUNDS(table_blob::off_id_start_flat, |
4789 | | table_blob::count_id_start_flat, 4); |
4790 | | ADA_IDNA_SECTION_IN_BOUNDS(table_blob::off_dir_start, |
4791 | | table_blob::count_dir_start, 4); |
4792 | | ADA_IDNA_SECTION_IN_BOUNDS(table_blob::off_dir_final, |
4793 | | table_blob::count_dir_final, 4); |
4794 | | ADA_IDNA_SECTION_IN_BOUNDS(table_blob::off_dir_value, |
4795 | | table_blob::count_dir_value, 1); |
4796 | | ADA_IDNA_SECTION_IN_BOUNDS(table_blob::off_combining_flat, |
4797 | | table_blob::count_combining_flat, 4); |
4798 | | #undef ADA_IDNA_SECTION_IN_BOUNDS |
4799 | | |
4800 | | // --- Mapping ----------------------------------------------------------------- |
4801 | | inline const uint16_t* idna_stage1 = nullptr; |
4802 | | inline const uint16_t* idna_stage2 = nullptr; |
4803 | | inline const uint64_t* idna_bool_blocks = nullptr; |
4804 | | inline const uint8_t* idna_utf8_mappings = nullptr; |
4805 | | |
4806 | | // --- Normalization (O(1) multi-stage) ---------------------------------------- |
4807 | | inline const uint8_t* decomposition_index = nullptr; |
4808 | | inline const uint16_t* decomposition_block_flat = nullptr; |
4809 | | inline const char32_t* decomposition_data = nullptr; |
4810 | | inline const uint8_t* ccc_index = nullptr; |
4811 | | inline const uint8_t* ccc_block_flat = nullptr; |
4812 | | inline const uint8_t* composition_index = nullptr; |
4813 | | inline const uint16_t* composition_block_flat = nullptr; |
4814 | | inline const char32_t* composition_data = nullptr; |
4815 | | |
4816 | | // --- Identifier -------------------------------------------------------------- |
4817 | | // Pointer-to-array alias. CF17 vs CF22 disagree on spacing inside (*)[2]. |
4818 | | // clang-format off |
4819 | | using range_pair_ptr = const uint32_t(*)[2]; |
4820 | | // clang-format on |
4821 | | inline range_pair_ptr id_continue = nullptr; |
4822 | | inline range_pair_ptr id_start = nullptr; |
4823 | | |
4824 | | // --- Validity (const SoA) ---------------------------------------------------- |
4825 | | inline const uint32_t* dir_start = nullptr; |
4826 | | inline const uint32_t* dir_final = nullptr; |
4827 | | inline const uint8_t* dir_value = nullptr; |
4828 | | inline range_pair_ptr combining_ranges = nullptr; |
4829 | | |
4830 | | inline constexpr size_t id_continue_count = table_blob::id_continue_count; |
4831 | | inline constexpr size_t id_start_count = table_blob::id_start_count; |
4832 | | inline constexpr size_t dir_table_count = table_blob::dir_table_count; |
4833 | | inline constexpr size_t combining_range_count = |
4834 | | table_blob::combining_range_count; |
4835 | | inline constexpr size_t idna_utf8_mappings_size = |
4836 | | table_blob::count_idna_utf8_mappings; |
4837 | | inline constexpr size_t decomposition_data_size = |
4838 | | table_blob::count_decomposition_data; |
4839 | | inline constexpr size_t composition_data_size = |
4840 | | table_blob::count_composition_data; |
4841 | | |
4842 | | inline constexpr size_t kDecompBlockCols = |
4843 | | table_blob::decomposition_block_cols; // 257 |
4844 | | inline constexpr size_t kCccBlockCols = table_blob::ccc_block_cols; // 256 |
4845 | | inline constexpr size_t kCompBlockCols = |
4846 | | table_blob::composition_block_cols; // 257 |
4847 | | inline constexpr size_t kDecompBlockRows = table_blob::decomposition_block_rows; |
4848 | | inline constexpr size_t kCccBlockRows = table_blob::ccc_block_rows; |
4849 | | inline constexpr size_t kCompBlockRows = table_blob::composition_block_rows; |
4850 | | |
4851 | | // Init state: 0=uninit, 1=in progress, 2=ready, 3=failed. |
4852 | | inline constexpr uint8_t kTablesUninit = 0; |
4853 | | inline constexpr uint8_t kTablesInProgress = 1; |
4854 | | inline constexpr uint8_t kTablesReady = 2; |
4855 | | inline constexpr uint8_t kTablesFailed = 3; |
4856 | | |
4857 | | inline std::atomic<uint8_t> tables_init_state{kTablesUninit}; |
4858 | | // Process-lifetime allocation published only by the winning init thread. |
4859 | | // Never freed: shared read-only data for the process. Do not dlclose a DSO |
4860 | | // that owns this buffer while other code may still call into ada::idna. |
4861 | | inline uint8_t* tables_buffer = nullptr; |
4862 | | |
4863 | | // Cap spin-wait so a stuck peer cannot hang the process forever. |
4864 | | inline constexpr uint64_t kTablesSpinLimit = 1'000'000'000ull; |
4865 | | |
4866 | | // ISO HDLC / zlib CRC-32 of the uncompressed table payload. |
4867 | | [[nodiscard]] inline uint32_t crc32_ieee(const uint8_t* data, |
4868 | 1 | size_t len) noexcept { |
4869 | 1 | uint32_t c = 0xFFFFFFFFu; |
4870 | 224k | for (size_t i = 0; i < len; ++i) { |
4871 | 224k | c ^= data[i]; |
4872 | 2.02M | for (int k = 0; k < 8; ++k) { |
4873 | 1.79M | const uint32_t mask = 0u - (c & 1u); |
4874 | 1.79M | c = (c >> 1) ^ (0xEDB88320u & mask); |
4875 | 1.79M | } |
4876 | 224k | } |
4877 | 1 | return ~c; |
4878 | 1 | } |
4879 | | |
4880 | 13.2k | [[nodiscard]] inline bool tables_are_ready() noexcept { |
4881 | 13.2k | return tables_init_state.load(std::memory_order_acquire) == kTablesReady; |
4882 | 13.2k | } |
4883 | | |
4884 | | // Returns true only when all table pointers are safe to use. |
4885 | 52.0k | [[nodiscard]] inline bool ensure_tables() noexcept { |
4886 | 52.0k | uint8_t state = tables_init_state.load(std::memory_order_acquire); |
4887 | 52.0k | if (state == kTablesReady) { |
4888 | 52.0k | return true; |
4889 | 52.0k | } |
4890 | 1 | if (state == kTablesFailed) { |
4891 | 0 | return false; |
4892 | 0 | } |
4893 | | |
4894 | 1 | uint8_t expected = kTablesUninit; |
4895 | 1 | if (tables_init_state.compare_exchange_strong(expected, kTablesInProgress, |
4896 | 1 | std::memory_order_acq_rel, |
4897 | 1 | std::memory_order_acquire)) { |
4898 | 1 | uint8_t* buffer = new (std::nothrow) uint8_t[table_blob::uncompressed_size]; |
4899 | 1 | if (buffer == nullptr) { |
4900 | 0 | tables_init_state.store(kTablesFailed, std::memory_order_release); |
4901 | 0 | return false; |
4902 | 0 | } |
4903 | | |
4904 | 1 | const size_t n = deflate::inflate_raw(table_blob::compressed, |
4905 | 1 | table_blob::compressed_size, buffer, |
4906 | 1 | table_blob::uncompressed_size); |
4907 | 1 | if (n != table_blob::uncompressed_size || |
4908 | 1 | crc32_ieee(buffer, n) != table_blob::uncompressed_crc32) { |
4909 | 0 | delete[] buffer; |
4910 | 0 | tables_init_state.store(kTablesFailed, std::memory_order_release); |
4911 | 0 | return false; |
4912 | 0 | } |
4913 | | |
4914 | | // LE payload verified; convert multi-byte fields for big-endian hosts. |
4915 | 1 | detail::convert_table_blob_to_host_endian(buffer); |
4916 | | |
4917 | 18 | auto at = [&](size_t off) noexcept -> const uint8_t* { |
4918 | 18 | return buffer + off; |
4919 | 18 | }; |
4920 | | |
4921 | | // Publish all non-atomic pointers before READY. Waiters synchronize via |
4922 | | // acquire on tables_init_state and then observe these writes. |
4923 | 1 | idna_stage1 = |
4924 | 1 | reinterpret_cast<const uint16_t*>(at(table_blob::off_idna_stage1)); |
4925 | 1 | idna_stage2 = |
4926 | 1 | reinterpret_cast<const uint16_t*>(at(table_blob::off_idna_stage2)); |
4927 | 1 | idna_bool_blocks = |
4928 | 1 | reinterpret_cast<const uint64_t*>(at(table_blob::off_idna_bool_blocks)); |
4929 | 1 | idna_utf8_mappings = at(table_blob::off_idna_utf8_mappings); |
4930 | | |
4931 | 1 | decomposition_index = at(table_blob::off_decomposition_index); |
4932 | 1 | decomposition_block_flat = reinterpret_cast<const uint16_t*>( |
4933 | 1 | at(table_blob::off_decomposition_block)); |
4934 | 1 | decomposition_data = reinterpret_cast<const char32_t*>( |
4935 | 1 | at(table_blob::off_decomposition_data)); |
4936 | 1 | ccc_index = at(table_blob::off_ccc_index); |
4937 | 1 | ccc_block_flat = at(table_blob::off_ccc_block); |
4938 | 1 | composition_index = at(table_blob::off_composition_index); |
4939 | 1 | composition_block_flat = reinterpret_cast<const uint16_t*>( |
4940 | 1 | at(table_blob::off_composition_block)); |
4941 | 1 | composition_data = |
4942 | 1 | reinterpret_cast<const char32_t*>(at(table_blob::off_composition_data)); |
4943 | | |
4944 | 1 | id_continue = |
4945 | 1 | reinterpret_cast<range_pair_ptr>(at(table_blob::off_id_continue_flat)); |
4946 | 1 | id_start = |
4947 | 1 | reinterpret_cast<range_pair_ptr>(at(table_blob::off_id_start_flat)); |
4948 | | |
4949 | 1 | dir_start = |
4950 | 1 | reinterpret_cast<const uint32_t*>(at(table_blob::off_dir_start)); |
4951 | 1 | dir_final = |
4952 | 1 | reinterpret_cast<const uint32_t*>(at(table_blob::off_dir_final)); |
4953 | 1 | dir_value = at(table_blob::off_dir_value); |
4954 | 1 | combining_ranges = |
4955 | 1 | reinterpret_cast<range_pair_ptr>(at(table_blob::off_combining_flat)); |
4956 | | |
4957 | 1 | tables_buffer = buffer; |
4958 | 1 | tables_init_state.store(kTablesReady, std::memory_order_release); |
4959 | 1 | return true; |
4960 | 1 | } |
4961 | | |
4962 | | // Another thread owns init (or finished between our loads). |
4963 | 0 | for (uint64_t spins = 0; spins < kTablesSpinLimit; ++spins) { |
4964 | 0 | state = tables_init_state.load(std::memory_order_acquire); |
4965 | 0 | if (state == kTablesReady) { |
4966 | 0 | return true; |
4967 | 0 | } |
4968 | 0 | if (state == kTablesFailed) { |
4969 | 0 | return false; |
4970 | 0 | } |
4971 | 0 | #if defined(__x86_64__) || defined(_M_X64) || defined(__i386__) || \ |
4972 | 0 | defined(_M_IX86) |
4973 | 0 | #if defined(__GNUC__) || defined(__clang__) |
4974 | 0 | __builtin_ia32_pause(); |
4975 | 0 | #endif |
4976 | | #elif defined(__aarch64__) || defined(_M_ARM64) |
4977 | | #if defined(__GNUC__) || defined(__clang__) |
4978 | | asm volatile("yield" ::: "memory"); |
4979 | | #endif |
4980 | | #endif |
4981 | 0 | } |
4982 | | // Timed out waiting for a peer - treat as failure rather than hang. |
4983 | 0 | return false; |
4984 | 0 | } |
4985 | | |
4986 | | // O(1) multi-stage accessors. Block indices from the tables are uint8_t and |
4987 | | // theoretically can be out of range if the blob is corrupt; clamp to a valid |
4988 | | // empty/default row (index 0) instead of reading OOB. |
4989 | 388k | inline const uint16_t* decomposition_block_row(uint8_t bi) noexcept { |
4990 | 388k | if (bi >= kDecompBlockRows) { |
4991 | 0 | bi = 0; |
4992 | 0 | } |
4993 | 388k | return decomposition_block_flat + static_cast<size_t>(bi) * kDecompBlockCols; |
4994 | 388k | } |
4995 | | |
4996 | 700k | inline const uint8_t* ccc_block_row(uint8_t bi) noexcept { |
4997 | 700k | if (bi >= kCccBlockRows) { |
4998 | 0 | bi = 0; |
4999 | 0 | } |
5000 | 700k | return ccc_block_flat + static_cast<size_t>(bi) * kCccBlockCols; |
5001 | 700k | } |
5002 | | |
5003 | 319k | inline const uint16_t* composition_block_row(uint8_t bi) noexcept { |
5004 | 319k | if (bi >= kCompBlockRows) { |
5005 | 0 | bi = 0; |
5006 | 0 | } |
5007 | 319k | return composition_block_flat + static_cast<size_t>(bi) * kCompBlockCols; |
5008 | 319k | } |
5009 | | |
5010 | | } // namespace ada::idna |
5011 | | /* end file src/table_store.hpp */ |
5012 | | /* begin file src/mapping_tables.cpp */ |
5013 | | // IDNA 17.0.0 |
5014 | | // Two-level compressed mapping table. |
5015 | | // All constants are derived from the table data; no hardcoded boundaries. |
5016 | | // Total binary size: 48659 bytes (47.5 KB) |
5017 | | // stage1: 6564 bytes (3282 uint16_t entries) |
5018 | | // stage2: 22912 bytes (179 mixed blocks x 64) |
5019 | | // bool_blocks: 1800 bytes (225 uint64_t words) |
5020 | | // utf8 maps: 17383 bytes |
5021 | | |
5022 | | // clang-format off |
5023 | | #ifndef ADA_IDNA_MAPPING_TABLE_H |
5024 | | #define ADA_IDNA_MAPPING_TABLE_H |
5025 | | #include <cstdint> |
5026 | | |
5027 | | namespace ada::idna { |
5028 | | |
5029 | | // Block size for two-level table (2^6 = 64 code points per block). |
5030 | | constexpr uint32_t IDNA_BLOCK_BITS = 6u; |
5031 | | constexpr uint32_t IDNA_BLOCK_SIZE = 64u; |
5032 | | constexpr uint32_t IDNA_BLOCK_MASK = 63u; |
5033 | | |
5034 | | // Sentinel values stored in stage2 / returned by lookup. |
5035 | | constexpr uint16_t IDNA_VALID = 0xFFFF; // code point is valid as-is |
5036 | | constexpr uint16_t IDNA_DISALLOWED = 0xFFFE; // code point is disallowed |
5037 | | constexpr uint16_t IDNA_IGNORED = 0x0000; // ignored (index into empty UTF-8 entry) |
5038 | | |
5039 | | // Bit 15 of a stage1 entry: set = boolean block, clear = mixed block. |
5040 | | constexpr uint16_t IDNA_BOOL_FLAG = 0x8000; |
5041 | | |
5042 | | // Two-level table covers code points [0, IDNA_LOW_RANGE_END). |
5043 | | // Derived from the highest non-disallowed code point below the high-ignored range, |
5044 | | // rounded up to the next 64-code-point block boundary. |
5045 | | constexpr uint32_t IDNA_LOW_RANGE_END = 0x00033480; |
5046 | | |
5047 | | // Variation selectors supplement: U+E0100..U+E01EF are all ignored. |
5048 | | // These are handled with a simple range check; everything else above |
5049 | | // IDNA_LOW_RANGE_END is disallowed. |
5050 | | constexpr uint32_t IDNA_HIGH_IGNORED_START = 0x000E0100; |
5051 | | constexpr uint32_t IDNA_HIGH_IGNORED_END = 0x000E01F0; // exclusive |
5052 | | |
5053 | | // idna_stage1[cp >> 6]: one entry per 64-code-point block. |
5054 | | // Bit 15 set -> lower 15 bits = index into idna_bool_blocks[]. |
5055 | | // Bit 15 clear -> value = base offset into idna_stage2[] for this block. |
5056 | | |
5057 | | } // namespace ada::idna |
5058 | | #endif // ADA_IDNA_MAPPING_TABLE_H |
5059 | | /* end file src/mapping_tables.cpp */ |
5060 | | |
5061 | | namespace ada::idna { |
5062 | | |
5063 | | // --- O(1) two-level table lookup --------------------------------------------- |
5064 | | // |
5065 | | // Returns one of: |
5066 | | // IDNA_VALID - keep code point in output unchanged |
5067 | | // IDNA_DISALLOWED - code point is not allowed (map() returns error) |
5068 | | // IDNA_IGNORED - code point is ignored (index 0 = empty UTF-8 entry) |
5069 | | // other - byte offset into idna_utf8_mappings[] (null-terminated) |
5070 | | // |
5071 | | // Assumes ensure_tables() has already been called by the public entry point. |
5072 | 446k | static uint16_t idna_lookup(uint32_t cp) noexcept { |
5073 | 446k | if (cp < IDNA_LOW_RANGE_END) { |
5074 | 445k | uint16_t ref = idna_stage1[cp >> IDNA_BLOCK_BITS]; |
5075 | 445k | if (ref & IDNA_BOOL_FLAG) { |
5076 | 201k | uint32_t bit_idx = |
5077 | 201k | static_cast<uint32_t>(ref & ~IDNA_BOOL_FLAG) * IDNA_BLOCK_SIZE + |
5078 | 201k | (cp & IDNA_BLOCK_MASK); |
5079 | 201k | bool is_valid = (idna_bool_blocks[bit_idx >> 6] >> (bit_idx & 63u)) & 1u; |
5080 | 201k | return is_valid ? IDNA_VALID : IDNA_DISALLOWED; |
5081 | 201k | } |
5082 | 244k | return idna_stage2[ref + (cp & IDNA_BLOCK_MASK)]; |
5083 | 445k | } |
5084 | | |
5085 | 705 | if (cp >= IDNA_HIGH_IGNORED_START && cp < IDNA_HIGH_IGNORED_END) { |
5086 | 438 | return IDNA_IGNORED; |
5087 | 438 | } |
5088 | | |
5089 | 267 | return IDNA_DISALLOWED; |
5090 | 705 | } |
5091 | | |
5092 | | // Advances *ptr past one well-formed UTF-8 code point from the mapping table. |
5093 | 249k | static char32_t utf8_next(const uint8_t*& ptr) noexcept { |
5094 | 249k | uint8_t b0 = *ptr++; |
5095 | 249k | if (b0 < 0x80u) return static_cast<char32_t>(b0); |
5096 | 216k | if (b0 < 0xE0u) { |
5097 | 109k | uint32_t cp = (b0 & 0x1Fu) << 6; |
5098 | 109k | cp |= (*ptr++ & 0x3Fu); |
5099 | 109k | return static_cast<char32_t>(cp); |
5100 | 109k | } |
5101 | 107k | if (b0 < 0xF0u) { |
5102 | 106k | uint32_t cp = (b0 & 0x0Fu) << 12; |
5103 | 106k | cp |= ((*ptr++ & 0x3Fu) << 6); |
5104 | 106k | cp |= (*ptr++ & 0x3Fu); |
5105 | 106k | return static_cast<char32_t>(cp); |
5106 | 106k | } |
5107 | 1.55k | uint32_t cp = (b0 & 0x07u) << 18; |
5108 | 1.55k | cp |= ((*ptr++ & 0x3Fu) << 12); |
5109 | 1.55k | cp |= ((*ptr++ & 0x3Fu) << 6); |
5110 | 1.55k | cp |= (*ptr++ & 0x3Fu); |
5111 | 1.55k | return static_cast<char32_t>(cp); |
5112 | 107k | } |
5113 | | |
5114 | | // Count UTF-8 code points in a null-terminated mapping string (trusted table). |
5115 | 47.4k | static size_t utf8_count_codepoints(const uint8_t* ptr) noexcept { |
5116 | 47.4k | size_t n = 0; |
5117 | 297k | while (*ptr != 0) { |
5118 | 249k | ++n; |
5119 | 249k | if (*ptr < 0x80u) { |
5120 | 32.4k | ++ptr; |
5121 | 217k | } else if (*ptr < 0xE0u) { |
5122 | 109k | ptr += 2; |
5123 | 109k | } else if (*ptr < 0xF0u) { |
5124 | 106k | ptr += 3; |
5125 | 106k | } else { |
5126 | 1.55k | ptr += 4; |
5127 | 1.55k | } |
5128 | 249k | } |
5129 | 47.4k | return n; |
5130 | 47.4k | } |
5131 | | |
5132 | | // --- ASCII fast path --------------------------------------------------------- |
5133 | 12.5k | void ascii_map(char* input, size_t length) { |
5134 | 37.5k | auto broadcast = [](uint8_t v) -> uint64_t { |
5135 | 37.5k | return 0x101010101010101ull * v; |
5136 | 37.5k | }; |
5137 | 12.5k | uint64_t broadcast_80 = broadcast(0x80); |
5138 | 12.5k | uint64_t broadcast_Ap = broadcast(128 - 'A'); |
5139 | 12.5k | uint64_t broadcast_Zp = broadcast(128 - 'Z' - 1); |
5140 | 12.5k | size_t i = 0; |
5141 | | |
5142 | 51.8k | for (; i + 7 < length; i += 8) { |
5143 | 39.3k | uint64_t word{}; |
5144 | 39.3k | std::memcpy(&word, input + i, sizeof(word)); |
5145 | 39.3k | word ^= |
5146 | 39.3k | (((word + broadcast_Ap) ^ (word + broadcast_Zp)) & broadcast_80) >> 2; |
5147 | 39.3k | std::memcpy(input + i, &word, sizeof(word)); |
5148 | 39.3k | } |
5149 | 12.5k | if (i < length) { |
5150 | 10.5k | uint64_t word{}; |
5151 | 10.5k | std::memcpy(&word, input + i, length - i); |
5152 | 10.5k | word ^= |
5153 | 10.5k | (((word + broadcast_Ap) ^ (word + broadcast_Zp)) & broadcast_80) >> 2; |
5154 | 10.5k | std::memcpy(input + i, &word, length - i); |
5155 | 10.5k | } |
5156 | 12.5k | } |
5157 | | |
5158 | | // Two-pass map: first validate + exact size, then write once (no growth |
5159 | | // realloc). |
5160 | 12.4k | bool map(std::u32string_view input, std::u32string& out) { |
5161 | | // [Map](https://www.unicode.org/reports/tr46/#ProcessingStepMap). |
5162 | 12.4k | out.clear(); |
5163 | 12.4k | if (!ensure_tables()) { |
5164 | 0 | return false; |
5165 | 0 | } |
5166 | | |
5167 | | // Pass 1: validate and compute exact output length. |
5168 | 12.4k | size_t out_size = 0; |
5169 | 223k | for (char32_t x : input) { |
5170 | 223k | uint16_t status = idna_lookup(static_cast<uint32_t>(x)); |
5171 | 223k | if (status == IDNA_DISALLOWED) { |
5172 | 599 | return false; |
5173 | 599 | } |
5174 | 223k | if (status == IDNA_VALID) { |
5175 | 175k | ++out_size; |
5176 | 175k | continue; |
5177 | 175k | } |
5178 | 47.4k | if (static_cast<size_t>(status) >= idna_utf8_mappings_size) { |
5179 | 0 | return false; |
5180 | 0 | } |
5181 | 47.4k | out_size += utf8_count_codepoints(idna_utf8_mappings + status); |
5182 | 47.4k | } |
5183 | | |
5184 | | // Pass 2: write into a single allocation. |
5185 | 11.8k | out.resize(out_size); |
5186 | 11.8k | size_t w = 0; |
5187 | 222k | for (char32_t x : input) { |
5188 | 222k | uint16_t status = idna_lookup(static_cast<uint32_t>(x)); |
5189 | 222k | if (status == IDNA_VALID) { |
5190 | 175k | out[w++] = x; |
5191 | 175k | continue; |
5192 | 175k | } |
5193 | | // IGNORED or mapped (status already validated in pass 1). |
5194 | 47.2k | const uint8_t* ptr = idna_utf8_mappings + status; |
5195 | 296k | while (*ptr != 0) { |
5196 | 249k | out[w++] = utf8_next(ptr); |
5197 | 249k | } |
5198 | 47.2k | } |
5199 | 11.8k | return true; |
5200 | 12.4k | } |
5201 | | |
5202 | 0 | std::u32string map(std::u32string_view input) { |
5203 | 0 | std::u32string answer; |
5204 | 0 | if (!map(input, answer)) { |
5205 | 0 | return {}; |
5206 | 0 | } |
5207 | 0 | return answer; |
5208 | 0 | } |
5209 | | |
5210 | | } // namespace ada::idna |
5211 | | /* end file src/mapping.cpp */ |
5212 | | /* begin file src/normalization.cpp */ |
5213 | | /* begin file include/ada/idna/normalization.h */ |
5214 | | #ifndef ADA_IDNA_NORMALIZATION_H |
5215 | | #define ADA_IDNA_NORMALIZATION_H |
5216 | | |
5217 | | #include <string> |
5218 | | #include <string_view> |
5219 | | |
5220 | | namespace ada::idna { |
5221 | | |
5222 | | // Returns true if `input` is already in Unicode Normalization Form C. |
5223 | | // Requires that internal tables have been loaded (call ensure via normalize |
5224 | | // or map first, or this returns false if tables are unavailable). |
5225 | | [[nodiscard]] bool is_already_nfc(std::u32string_view input) noexcept; |
5226 | | |
5227 | | // Normalize the characters according to IDNA (Unicode Normalization Form C). |
5228 | | // Returns false if the internal Unicode tables could not be loaded; in that |
5229 | | // case `input` is left unchanged. Skips work when the string is already NFC. |
5230 | | [[nodiscard]] bool normalize(std::u32string& input); |
5231 | | |
5232 | | } // namespace ada::idna |
5233 | | #endif |
5234 | | /* end file include/ada/idna/normalization.h */ |
5235 | | /* begin file src/normalization_tables.cpp */ |
5236 | | // Normalization table helpers. |
5237 | | // Array payloads live in the DEFLATE blob (table_store.hpp). |
5238 | | // clang-format off |
5239 | | #ifndef ADA_IDNA_NORMALIZATION_TABLES_H |
5240 | | #define ADA_IDNA_NORMALIZATION_TABLES_H |
5241 | | |
5242 | | namespace ada::idna { |
5243 | | |
5244 | | // Accessors and multi-stage tables are provided by table_store.hpp after |
5245 | | // ensure_tables(). Lookup code matches the classic O(1) uni-algo layout. |
5246 | | |
5247 | | } // namespace ada::idna |
5248 | | #endif // ADA_IDNA_NORMALIZATION_TABLES_H |
5249 | | /* end file src/normalization_tables.cpp */ |
5250 | | |
5251 | | #include <cstdint> |
5252 | | |
5253 | | namespace ada::idna { |
5254 | | |
5255 | | // See |
5256 | | // https://github.com/uni-algo/uni-algo/blob/c612968c5ed3ace39bde4c894c24286c5f2c7fe2/include/uni_algo/impl/impl_norm.h#L467 |
5257 | | constexpr char32_t hangul_sbase = 0xAC00; |
5258 | | constexpr char32_t hangul_tbase = 0x11A7; |
5259 | | constexpr char32_t hangul_vbase = 0x1161; |
5260 | | constexpr char32_t hangul_lbase = 0x1100; |
5261 | | constexpr char32_t hangul_lcount = 19; |
5262 | | constexpr char32_t hangul_vcount = 21; |
5263 | | constexpr char32_t hangul_tcount = 28; |
5264 | | constexpr char32_t hangul_ncount = hangul_vcount * hangul_tcount; |
5265 | | constexpr char32_t hangul_scount = |
5266 | | hangul_lcount * hangul_vcount * hangul_tcount; |
5267 | | |
5268 | | // Canonical decomposition length (0 if none / compatibility-only / Hangul |
5269 | | // syllable). Length 1 means a singleton mapping (character is not NFC form). |
5270 | | // Length >= 2 means a primary composite that is already the NFC form of its |
5271 | | // decomposition (e.g. U+00E9 LATIN SMALL LETTER E WITH ACUTE). |
5272 | 340k | static size_t canonical_decomp_length(char32_t current_character) noexcept { |
5273 | 340k | if (current_character >= hangul_sbase && |
5274 | 12.6k | current_character < hangul_sbase + hangul_scount) { |
5275 | | // Hangul precomposed syllables are NFC. |
5276 | 7.82k | return 0; |
5277 | 7.82k | } |
5278 | 332k | if (current_character >= 0x110000) { |
5279 | 0 | return 0; |
5280 | 0 | } |
5281 | 332k | const uint8_t di = decomposition_index[current_character >> 8]; |
5282 | 332k | const uint16_t* const decomposition = |
5283 | 332k | decomposition_block_row(di) + (current_character % 256); |
5284 | 332k | size_t decomposition_length = |
5285 | 332k | (decomposition[1] >> 2) - (decomposition[0] >> 2); |
5286 | 332k | if ((decomposition_length > 0) && (decomposition[0] & 1)) { |
5287 | 0 | decomposition_length = 0; // compatibility-only: ignored for NFC |
5288 | 0 | } |
5289 | 332k | return decomposition_length; |
5290 | 332k | } |
5291 | | |
5292 | | std::pair<bool, size_t> compute_decomposition_length( |
5293 | 2.83k | const std::u32string_view input) noexcept { |
5294 | 2.83k | bool decomposition_needed{false}; |
5295 | 2.83k | size_t additional_elements{0}; |
5296 | 39.2k | for (char32_t current_character : input) { |
5297 | 39.2k | size_t decomposition_length{0}; |
5298 | | |
5299 | 39.2k | if (current_character >= hangul_sbase && |
5300 | 4.59k | current_character < hangul_sbase + hangul_scount) { |
5301 | | // Full NFD-style Hangul decomp for the decompose() step. |
5302 | 3.40k | decomposition_length = 2; |
5303 | 3.40k | if ((current_character - hangul_sbase) % hangul_tcount) { |
5304 | 2.60k | decomposition_length = 3; |
5305 | 2.60k | } |
5306 | 35.8k | } else if (current_character < 0x110000) { |
5307 | 35.8k | const uint8_t di = decomposition_index[current_character >> 8]; |
5308 | 35.8k | const uint16_t* const decomposition = |
5309 | 35.8k | decomposition_block_row(di) + (current_character % 256); |
5310 | 35.8k | decomposition_length = (decomposition[1] >> 2) - (decomposition[0] >> 2); |
5311 | 35.8k | if ((decomposition_length > 0) && (decomposition[0] & 1)) { |
5312 | 0 | decomposition_length = 0; |
5313 | 0 | } |
5314 | 35.8k | } |
5315 | 39.2k | if (decomposition_length != 0) { |
5316 | 4.41k | decomposition_needed = true; |
5317 | 4.41k | additional_elements += decomposition_length - 1; |
5318 | 4.41k | } |
5319 | 39.2k | } |
5320 | 2.83k | return {decomposition_needed, additional_elements}; |
5321 | 2.83k | } |
5322 | | |
5323 | 1.72k | void decompose(std::u32string& input, size_t additional_elements) { |
5324 | 1.72k | input.resize(input.size() + additional_elements); |
5325 | 1.72k | for (size_t descending_idx = input.size(), |
5326 | 1.72k | input_count = descending_idx - additional_elements; |
5327 | 24.9k | input_count--;) { |
5328 | 23.2k | if (input[input_count] >= hangul_sbase && |
5329 | 3.68k | input[input_count] < hangul_sbase + hangul_scount) { |
5330 | | // Hangul decomposition. |
5331 | 3.40k | char32_t s_index = input[input_count] - hangul_sbase; |
5332 | 3.40k | if (s_index % hangul_tcount != 0) { |
5333 | 2.60k | input[--descending_idx] = hangul_tbase + s_index % hangul_tcount; |
5334 | 2.60k | } |
5335 | 3.40k | input[--descending_idx] = |
5336 | 3.40k | hangul_vbase + (s_index % hangul_ncount) / hangul_tcount; |
5337 | 3.40k | input[--descending_idx] = hangul_lbase + s_index / hangul_ncount; |
5338 | 19.8k | } else if (input[input_count] < 0x110000) { |
5339 | 19.8k | const uint16_t* decomposition = |
5340 | 19.8k | decomposition_block_row( |
5341 | 19.8k | decomposition_index[input[input_count] >> 8]) + |
5342 | 19.8k | (input[input_count] % 256); |
5343 | 19.8k | uint16_t decomposition_length = |
5344 | 19.8k | (decomposition[1] >> 2) - (decomposition[0] >> 2); |
5345 | 19.8k | if (decomposition_length > 0 && (decomposition[0] & 1)) { |
5346 | 0 | decomposition_length = 0; |
5347 | 0 | } |
5348 | 19.8k | if (decomposition_length > 0) { |
5349 | 1.00k | const size_t base = static_cast<size_t>(decomposition[0] >> 2); |
5350 | 1.00k | if (base + decomposition_length > decomposition_data_size) { |
5351 | 0 | input[--descending_idx] = input[input_count]; |
5352 | 1.00k | } else { |
5353 | 3.29k | while (decomposition_length-- > 0) { |
5354 | 2.28k | input[--descending_idx] = |
5355 | 2.28k | decomposition_data[base + decomposition_length]; |
5356 | 2.28k | } |
5357 | 1.00k | } |
5358 | 18.8k | } else { |
5359 | 18.8k | input[--descending_idx] = input[input_count]; |
5360 | 18.8k | } |
5361 | 19.8k | } else { |
5362 | 0 | input[--descending_idx] = input[input_count]; |
5363 | 0 | } |
5364 | 23.2k | } |
5365 | 1.72k | } |
5366 | | |
5367 | 700k | uint8_t get_ccc(char32_t c) noexcept { |
5368 | 700k | if (c >= 0x110000) { |
5369 | 0 | return 0; |
5370 | 0 | } |
5371 | 700k | return ccc_block_row(ccc_index[c >> 8])[c % 256]; |
5372 | 700k | } |
5373 | | |
5374 | 2.83k | void sort_marks(std::u32string& input) { |
5375 | 46.4k | for (size_t idx = 1; idx < input.size(); idx++) { |
5376 | 43.6k | uint8_t ccc = get_ccc(input[idx]); |
5377 | 43.6k | if (ccc == 0) { |
5378 | 38.7k | continue; |
5379 | 38.7k | } |
5380 | 4.92k | auto current_character = input[idx]; |
5381 | 4.92k | size_t back_idx = idx; |
5382 | 6.60k | while (back_idx != 0 && get_ccc(input[back_idx - 1]) > ccc) { |
5383 | 1.68k | input[back_idx] = input[back_idx - 1]; |
5384 | 1.68k | back_idx--; |
5385 | 1.68k | } |
5386 | 4.92k | input[back_idx] = current_character; |
5387 | 4.92k | } |
5388 | 2.83k | } |
5389 | | |
5390 | 2.83k | void decompose_nfc(std::u32string& input) { |
5391 | | /** |
5392 | | * Decompose the domain_name string to Unicode Normalization Form C. |
5393 | | * @see https://www.unicode.org/reports/tr46/#ProcessingStepDecompose |
5394 | | */ |
5395 | 2.83k | auto [decomposition_needed, additional_elements] = |
5396 | 2.83k | compute_decomposition_length(input); |
5397 | 2.83k | if (decomposition_needed) { |
5398 | 1.72k | decompose(input, additional_elements); |
5399 | 1.72k | } |
5400 | 2.83k | sort_marks(input); |
5401 | 2.83k | } |
5402 | | |
5403 | | // Returns true if a composition step would change the string. |
5404 | 12.3k | static bool would_compose(std::u32string_view input) noexcept { |
5405 | 301k | for (size_t input_count = 0; input_count < input.size();) { |
5406 | 293k | const char32_t current = input[input_count]; |
5407 | 293k | if (current >= hangul_lbase && current < hangul_lbase + hangul_lcount) { |
5408 | 1.75k | if (input_count + 1 < input.size() && |
5409 | 1.48k | input[input_count + 1] >= hangul_vbase && |
5410 | 772 | input[input_count + 1] < hangul_vbase + hangul_vcount) { |
5411 | 269 | return true; |
5412 | 269 | } |
5413 | 1.48k | ++input_count; |
5414 | 1.48k | continue; |
5415 | 1.75k | } |
5416 | 292k | if (current >= hangul_sbase && current < hangul_sbase + hangul_scount) { |
5417 | 6.12k | if ((current - hangul_sbase) % hangul_tcount && |
5418 | 4.85k | input_count + 1 < input.size() && |
5419 | 4.55k | input[input_count + 1] > hangul_tbase && |
5420 | 4.17k | input[input_count + 1] < hangul_tbase + hangul_tcount) { |
5421 | 2.22k | return true; |
5422 | 2.22k | } |
5423 | 3.89k | ++input_count; |
5424 | 3.89k | continue; |
5425 | 6.12k | } |
5426 | 285k | if (current < 0x110000) { |
5427 | 285k | const uint16_t* composition = |
5428 | 285k | composition_block_row(composition_index[current >> 8]) + |
5429 | 285k | (current % 256); |
5430 | 285k | int32_t previous_ccc = -1; |
5431 | 285k | size_t j = input_count; |
5432 | 288k | for (; j + 1 < input.size(); ++j) { |
5433 | 281k | uint8_t ccc = get_ccc(input[j + 1]); |
5434 | 281k | if (composition[1] != composition[0] && previous_ccc < ccc) { |
5435 | 62.0k | int left = composition[0]; |
5436 | 62.0k | int right = composition[1]; |
5437 | 62.0k | if (left < 0 || right < left || |
5438 | 62.0k | static_cast<size_t>(right) > composition_data_size) { |
5439 | 0 | break; |
5440 | 0 | } |
5441 | 191k | while (left + 2 < right) { |
5442 | 129k | int middle = left + (((right - left) >> 1) & ~1); |
5443 | 129k | if (composition_data[static_cast<size_t>(middle)] <= input[j + 1]) { |
5444 | 9.01k | left = middle; |
5445 | 9.01k | } |
5446 | 129k | if (composition_data[static_cast<size_t>(middle)] >= input[j + 1]) { |
5447 | 121k | right = middle; |
5448 | 121k | } |
5449 | 129k | } |
5450 | 62.0k | if (static_cast<size_t>(left + 1) < composition_data_size && |
5451 | 62.0k | composition_data[static_cast<size_t>(left)] == input[j + 1]) { |
5452 | 1.86k | return true; |
5453 | 1.86k | } |
5454 | 62.0k | } |
5455 | 279k | if (ccc == 0) { |
5456 | 276k | break; |
5457 | 276k | } |
5458 | 2.61k | previous_ccc = ccc; |
5459 | 2.61k | } |
5460 | 284k | input_count = j + 1; |
5461 | 284k | continue; |
5462 | 285k | } |
5463 | 0 | ++input_count; |
5464 | 0 | } |
5465 | 8.00k | return false; |
5466 | 12.3k | } |
5467 | | |
5468 | 13.2k | bool is_already_nfc(std::u32string_view input) noexcept { |
5469 | 13.2k | if (input.empty()) { |
5470 | 0 | return true; |
5471 | 0 | } |
5472 | 13.2k | if (!tables_are_ready() && !ensure_tables()) { |
5473 | 0 | return false; |
5474 | 0 | } |
5475 | | // 1) Singleton decompositions are never NFC (e.g. U+212B ANGSTROM SIGN). |
5476 | | // Multi-code-point decomps are primary composites that are NFC as-is. |
5477 | 340k | for (char32_t c : input) { |
5478 | 340k | if (canonical_decomp_length(c) == 1) { |
5479 | 0 | return false; |
5480 | 0 | } |
5481 | 340k | } |
5482 | | // 2) Combining marks already in canonical order. |
5483 | 13.2k | uint8_t prev_ccc = 0; |
5484 | 336k | for (char32_t c : input) { |
5485 | 336k | uint8_t ccc = get_ccc(c); |
5486 | 336k | if (ccc != 0 && prev_ccc > ccc) { |
5487 | 869 | return false; |
5488 | 869 | } |
5489 | 335k | prev_ccc = ccc; |
5490 | 335k | } |
5491 | | // 3) No pairwise composition would apply (including Hangul L+V / LV+T). |
5492 | 12.3k | return !would_compose(input); |
5493 | 13.2k | } |
5494 | | |
5495 | 2.83k | void compose(std::u32string& input) { |
5496 | | /** |
5497 | | * Compose the domain_name string to Unicode Normalization Form C. |
5498 | | * @see https://www.unicode.org/reports/tr46/#ProcessingStepCompose |
5499 | | */ |
5500 | 2.83k | size_t input_count{0}; |
5501 | 2.83k | size_t composition_count{0}; |
5502 | 38.2k | for (; input_count < input.size(); input_count++, composition_count++) { |
5503 | 35.4k | input[composition_count] = input[input_count]; |
5504 | 35.4k | if (input[input_count] >= hangul_lbase && |
5505 | 11.3k | input[input_count] < hangul_lbase + hangul_lcount) { |
5506 | 4.41k | if (input_count + 1 < input.size() && |
5507 | 4.32k | input[input_count + 1] >= hangul_vbase && |
5508 | 3.88k | input[input_count + 1] < hangul_vbase + hangul_vcount) { |
5509 | 3.59k | input[composition_count] = |
5510 | 3.59k | hangul_sbase + |
5511 | 3.59k | ((input[input_count] - hangul_lbase) * hangul_vcount + |
5512 | 3.59k | input[input_count + 1] - hangul_vbase) * |
5513 | 3.59k | hangul_tcount; |
5514 | 3.59k | input_count++; |
5515 | 3.59k | if (input_count + 1 < input.size() && |
5516 | 3.33k | input[input_count + 1] > hangul_tbase && |
5517 | 2.85k | input[input_count + 1] < hangul_tbase + hangul_tcount) { |
5518 | 2.60k | input[composition_count] += input[++input_count] - hangul_tbase; |
5519 | 2.60k | } |
5520 | 3.59k | } |
5521 | 30.9k | } else if (input[input_count] >= hangul_sbase && |
5522 | 617 | input[input_count] < hangul_sbase + hangul_scount) { |
5523 | 0 | if ((input[input_count] - hangul_sbase) % hangul_tcount && |
5524 | 0 | input_count + 1 < input.size() && |
5525 | 0 | input[input_count + 1] > hangul_tbase && |
5526 | 0 | input[input_count + 1] < hangul_tbase + hangul_tcount) { |
5527 | 0 | input[composition_count] += input[++input_count] - hangul_tbase; |
5528 | 0 | } |
5529 | 30.9k | } else if (input[input_count] < 0x110000) { |
5530 | 30.9k | const uint16_t* composition = |
5531 | 30.9k | composition_block_row(composition_index[input[input_count] >> 8]) + |
5532 | 30.9k | (input[input_count] % 256); |
5533 | 30.9k | size_t initial_composition_count = composition_count; |
5534 | 35.8k | for (int32_t previous_ccc = -1; input_count + 1 < input.size(); |
5535 | 33.5k | input_count++) { |
5536 | 33.5k | uint8_t ccc = get_ccc(input[input_count + 1]); |
5537 | | |
5538 | 33.5k | if (composition[1] != composition[0] && previous_ccc < ccc) { |
5539 | 12.3k | int left = composition[0]; |
5540 | 12.3k | int right = composition[1]; |
5541 | 12.3k | if (left < 0 || right < left || |
5542 | 12.3k | static_cast<size_t>(right) > composition_data_size) { |
5543 | 0 | break; |
5544 | 0 | } |
5545 | 35.9k | while (left + 2 < right) { |
5546 | 23.5k | int middle = left + (((right - left) >> 1) & ~1); |
5547 | 23.5k | if (composition_data[static_cast<size_t>(middle)] <= |
5548 | 23.5k | input[input_count + 1]) { |
5549 | 4.42k | left = middle; |
5550 | 4.42k | } |
5551 | 23.5k | if (composition_data[static_cast<size_t>(middle)] >= |
5552 | 23.5k | input[input_count + 1]) { |
5553 | 20.7k | right = middle; |
5554 | 20.7k | } |
5555 | 23.5k | } |
5556 | 12.3k | if (static_cast<size_t>(left + 1) < composition_data_size && |
5557 | 12.3k | composition_data[static_cast<size_t>(left)] == |
5558 | 12.3k | input[input_count + 1]) { |
5559 | 2.30k | char32_t composed = composition_data[static_cast<size_t>(left + 1)]; |
5560 | 2.30k | input[initial_composition_count] = composed; |
5561 | 2.30k | composition = |
5562 | 2.30k | composition_block_row(composition_index[composed >> 8]) + |
5563 | 2.30k | (composed % 256); |
5564 | 2.30k | continue; |
5565 | 2.30k | } |
5566 | 12.3k | } |
5567 | | |
5568 | 31.1k | if (ccc == 0) { |
5569 | 28.6k | break; |
5570 | 28.6k | } |
5571 | 2.57k | previous_ccc = ccc; |
5572 | 2.57k | input[++composition_count] = input[input_count + 1]; |
5573 | 2.57k | } |
5574 | 30.9k | } |
5575 | 35.4k | } |
5576 | | |
5577 | 2.83k | if (composition_count < input_count) { |
5578 | 2.50k | input.resize(composition_count); |
5579 | 2.50k | } |
5580 | 2.83k | } |
5581 | | |
5582 | 3.82k | bool normalize(std::u32string& input) { |
5583 | | /** |
5584 | | * Normalize the characters according to IDNA (Unicode Normalization Form C). |
5585 | | * @see https://www.unicode.org/reports/tr46/#ProcessingStepNormalize |
5586 | | */ |
5587 | 3.82k | if (!ensure_tables() || decomposition_index == nullptr || |
5588 | 3.82k | composition_index == nullptr) { |
5589 | 0 | return false; |
5590 | 0 | } |
5591 | 3.82k | if (is_already_nfc(input)) { |
5592 | 991 | return true; |
5593 | 991 | } |
5594 | 2.83k | decompose_nfc(input); |
5595 | 2.83k | compose(input); |
5596 | 2.83k | return true; |
5597 | 3.82k | } |
5598 | | |
5599 | | } // namespace ada::idna |
5600 | | /* end file src/normalization.cpp */ |
5601 | | /* begin file src/punycode.cpp */ |
5602 | | /* begin file include/ada/idna/punycode.h */ |
5603 | | #ifndef ADA_IDNA_PUNYCODE_H |
5604 | | #define ADA_IDNA_PUNYCODE_H |
5605 | | |
5606 | | #include <string> |
5607 | | #include <string_view> |
5608 | | |
5609 | | namespace ada::idna { |
5610 | | |
5611 | | bool punycode_to_utf32(std::string_view input, std::u32string& out); |
5612 | | bool verify_punycode(std::string_view input); |
5613 | | bool utf32_to_punycode(std::u32string_view input, std::string& out); |
5614 | | |
5615 | | } // namespace ada::idna |
5616 | | |
5617 | | #endif // ADA_IDNA_PUNYCODE_H |
5618 | | /* end file include/ada/idna/punycode.h */ |
5619 | | |
5620 | | #include <cstdint> |
5621 | | |
5622 | | namespace ada::idna { |
5623 | | |
5624 | | constexpr int32_t base = 36; |
5625 | | constexpr int32_t tmin = 1; |
5626 | | constexpr int32_t tmax = 26; |
5627 | | constexpr int32_t skew = 38; |
5628 | | constexpr int32_t damp = 700; |
5629 | | constexpr int32_t initial_bias = 72; |
5630 | | constexpr uint32_t initial_n = 128; |
5631 | | |
5632 | 50.2k | static constexpr int32_t char_to_digit_value(char value) { |
5633 | 50.2k | if (value >= 'a' && value <= 'z') return value - 'a'; |
5634 | 12.9k | if (value >= '0' && value <= '9') return value - '0' + 26; |
5635 | 291 | return -1; |
5636 | 12.9k | } |
5637 | | |
5638 | 384k | static constexpr char digit_to_char(int32_t digit) { |
5639 | 384k | return digit < 26 ? char(digit + 97) : char(digit + 22); |
5640 | 384k | } |
5641 | | |
5642 | 160k | static constexpr int32_t adapt(int32_t d, int32_t n, bool firsttime) { |
5643 | 160k | if (firsttime) { |
5644 | 36.2k | d = d / damp; |
5645 | 123k | } else { |
5646 | 123k | d = d / 2; |
5647 | 123k | } |
5648 | 160k | d += d / n; |
5649 | 160k | int32_t k = 0; |
5650 | 243k | while (d > ((base - tmin) * tmax) / 2) { |
5651 | 83.5k | d /= base - tmin; |
5652 | 83.5k | k += base; |
5653 | 83.5k | } |
5654 | 160k | return k + (((base - tmin + 1) * d) / (d + skew)); |
5655 | 160k | } |
5656 | | |
5657 | 6.73k | bool punycode_to_utf32(std::string_view input, std::u32string &out) { |
5658 | 6.73k | int32_t written_out{0}; |
5659 | 6.73k | out.reserve(out.size() + input.size()); |
5660 | 6.73k | uint32_t n = initial_n; |
5661 | 6.73k | int32_t i = 0; |
5662 | 6.73k | int32_t bias = initial_bias; |
5663 | | // grab ascii content |
5664 | 6.73k | size_t end_of_ascii = input.find_last_of('-'); |
5665 | 6.73k | if (end_of_ascii != std::string_view::npos) { |
5666 | 6.97k | for (uint8_t c : input.substr(0, end_of_ascii)) { |
5667 | 6.97k | if (c >= 0x80) { |
5668 | 0 | return false; |
5669 | 0 | } |
5670 | 6.97k | out.push_back(c); |
5671 | 6.97k | written_out++; |
5672 | 6.97k | } |
5673 | 1.47k | input.remove_prefix(end_of_ascii + 1); |
5674 | 1.47k | } |
5675 | 35.2k | while (!input.empty()) { |
5676 | 29.0k | int32_t oldi = i; |
5677 | 29.0k | int32_t w = 1; |
5678 | 50.4k | for (int32_t k = base;; k += base) { |
5679 | 50.4k | if (input.empty()) { |
5680 | 142 | return false; |
5681 | 142 | } |
5682 | 50.2k | uint8_t code_point = input.front(); |
5683 | 50.2k | input.remove_prefix(1); |
5684 | 50.2k | int32_t digit = char_to_digit_value(code_point); |
5685 | 50.2k | if (digit < 0) { |
5686 | 291 | return false; |
5687 | 291 | } |
5688 | 49.9k | if (digit > (0x7fffffff - i) / w) { |
5689 | 41 | return false; |
5690 | 41 | } |
5691 | 49.9k | i = i + digit * w; |
5692 | 49.9k | int32_t t = k <= bias ? tmin : k >= bias + tmax ? tmax : k - bias; |
5693 | 49.9k | if (digit < t) { |
5694 | 28.5k | break; |
5695 | 28.5k | } |
5696 | 21.3k | if (w > 0x7fffffff / (base - t)) { |
5697 | 0 | return false; |
5698 | 0 | } |
5699 | 21.3k | w = w * (base - t); |
5700 | 21.3k | } |
5701 | 28.5k | bias = adapt(i - oldi, written_out + 1, oldi == 0); |
5702 | 28.5k | if (i / (written_out + 1) > int32_t(0x7fffffff - n)) { |
5703 | 58 | return false; |
5704 | 58 | } |
5705 | 28.5k | n = n + i / (written_out + 1); |
5706 | 28.5k | i = i % (written_out + 1); |
5707 | 28.5k | if (n < 0x80) { |
5708 | 0 | return false; |
5709 | 0 | } |
5710 | 28.5k | out.insert(out.begin() + i, n); |
5711 | 28.5k | written_out++; |
5712 | 28.5k | ++i; |
5713 | 28.5k | } |
5714 | | // See https://github.com/whatwg/url/issues/803 |
5715 | | // Reject labels whose decoded form begins with "xn--" (double-encoded ACE). |
5716 | 6.19k | if (out.size() >= 4 && out[0] == U'x' && out[1] == U'n' && out[2] == U'-' && |
5717 | 258 | out[3] == U'-') { |
5718 | 35 | return false; |
5719 | 35 | } |
5720 | 6.16k | return true; |
5721 | 6.19k | } |
5722 | | |
5723 | 0 | bool verify_punycode(std::string_view input) { |
5724 | | // Track only the first 4 decoded code points to check for the "xn--" prefix. |
5725 | | // This avoids heap allocation while still detecting double-encoded ACE |
5726 | | // labels. |
5727 | 0 | uint32_t first4[4]{}; |
5728 | 0 | size_t written_out{0}; |
5729 | 0 | uint32_t n = initial_n; |
5730 | 0 | int32_t i = 0; |
5731 | 0 | int32_t bias = initial_bias; |
5732 | | // grab ascii content |
5733 | 0 | size_t end_of_ascii = input.find_last_of('-'); |
5734 | 0 | if (end_of_ascii != std::string_view::npos) { |
5735 | 0 | for (uint8_t c : input.substr(0, end_of_ascii)) { |
5736 | 0 | if (c >= 0x80) { |
5737 | 0 | return false; |
5738 | 0 | } |
5739 | 0 | if (written_out < 4) { |
5740 | 0 | first4[written_out] = c; |
5741 | 0 | } |
5742 | 0 | written_out++; |
5743 | 0 | } |
5744 | 0 | input.remove_prefix(end_of_ascii + 1); |
5745 | 0 | } |
5746 | 0 | while (!input.empty()) { |
5747 | 0 | int32_t oldi = i; |
5748 | 0 | int32_t w = 1; |
5749 | 0 | for (int32_t k = base;; k += base) { |
5750 | 0 | if (input.empty()) { |
5751 | 0 | return false; |
5752 | 0 | } |
5753 | 0 | uint8_t code_point = input.front(); |
5754 | 0 | input.remove_prefix(1); |
5755 | 0 | int32_t digit = char_to_digit_value(code_point); |
5756 | 0 | if (digit < 0) { |
5757 | 0 | return false; |
5758 | 0 | } |
5759 | 0 | if (digit > (0x7fffffff - i) / w) { |
5760 | 0 | return false; |
5761 | 0 | } |
5762 | 0 | i = i + digit * w; |
5763 | 0 | int32_t t = k <= bias ? tmin : k >= bias + tmax ? tmax : k - bias; |
5764 | 0 | if (digit < t) { |
5765 | 0 | break; |
5766 | 0 | } |
5767 | 0 | if (w > 0x7fffffff / (base - t)) { |
5768 | 0 | return false; |
5769 | 0 | } |
5770 | 0 | w = w * (base - t); |
5771 | 0 | } |
5772 | 0 | bias = adapt(i - oldi, int32_t(written_out + 1), oldi == 0); |
5773 | 0 | if (i / (written_out + 1) > 0x7fffffff - n) { |
5774 | 0 | return false; |
5775 | 0 | } |
5776 | 0 | n = n + i / int32_t(written_out + 1); |
5777 | 0 | i = i % int32_t(written_out + 1); |
5778 | 0 | if (n < 0x80) { |
5779 | 0 | return false; |
5780 | 0 | } |
5781 | | // Simulate insert at position i, maintaining only the first 4 slots. |
5782 | 0 | size_t insert_pos = size_t(i); |
5783 | 0 | if (insert_pos < 4) { |
5784 | 0 | for (size_t j = 3; j > insert_pos; j--) { |
5785 | 0 | first4[j] = first4[j - 1]; |
5786 | 0 | } |
5787 | 0 | first4[insert_pos] = n; |
5788 | 0 | } |
5789 | 0 | written_out++; |
5790 | 0 | ++i; |
5791 | 0 | } |
5792 | | // See https://github.com/whatwg/url/issues/803 |
5793 | | // Reject labels whose decoded form begins with "xn--" (double-encoded ACE). |
5794 | 0 | if (written_out >= 4 && first4[0] == U'x' && first4[1] == U'n' && |
5795 | 0 | first4[2] == U'-' && first4[3] == U'-') { |
5796 | 0 | return false; |
5797 | 0 | } |
5798 | 0 | return true; |
5799 | 0 | } |
5800 | | |
5801 | 30.3k | bool utf32_to_punycode(std::u32string_view input, std::string &out) { |
5802 | 30.3k | out.reserve(input.size() + out.size()); |
5803 | 30.3k | uint32_t n = initial_n; |
5804 | 30.3k | int32_t d = 0; |
5805 | 30.3k | int32_t bias = initial_bias; |
5806 | 30.3k | size_t h = 0; |
5807 | | // first push the ascii content |
5808 | 153k | for (uint32_t c : input) { |
5809 | 153k | if (c < 0x80) { |
5810 | 22.3k | ++h; |
5811 | 22.3k | out.push_back(char(c)); |
5812 | 22.3k | } |
5813 | 153k | if (c > 0x10ffff || (c >= 0xd800 && c < 0xe000)) { |
5814 | 0 | return false; |
5815 | 0 | } |
5816 | 153k | } |
5817 | 30.3k | size_t b = h; |
5818 | 30.3k | if (b > 0) { |
5819 | 5.43k | out.push_back('-'); |
5820 | 5.43k | } |
5821 | 137k | while (h < input.size()) { |
5822 | 107k | uint32_t m = 0x10FFFF; |
5823 | 793k | for (auto code_point : input) { |
5824 | 793k | if (code_point >= n && code_point < m) m = code_point; |
5825 | 793k | } |
5826 | | |
5827 | 107k | if ((m - n) > (0x7fffffff - d) / (h + 1)) { |
5828 | 0 | return false; |
5829 | 0 | } |
5830 | 107k | d = d + int32_t((m - n) * (h + 1)); |
5831 | 107k | n = m; |
5832 | 793k | for (auto c : input) { |
5833 | 793k | if (c < n) { |
5834 | 402k | if (d == 0x7fffffff) { |
5835 | 0 | return false; |
5836 | 0 | } |
5837 | 402k | ++d; |
5838 | 402k | } |
5839 | 793k | if (c == n) { |
5840 | 131k | int32_t q = d; |
5841 | 384k | for (int32_t k = base;; k += base) { |
5842 | 384k | int32_t t = k <= bias ? tmin : k >= bias + tmax ? tmax : k - bias; |
5843 | | |
5844 | 384k | if (q < t) { |
5845 | 131k | break; |
5846 | 131k | } |
5847 | 252k | out.push_back(digit_to_char(t + ((q - t) % (base - t)))); |
5848 | 252k | q = (q - t) / (base - t); |
5849 | 252k | } |
5850 | 131k | out.push_back(digit_to_char(q)); |
5851 | 131k | bias = adapt(d, int32_t(h + 1), h == b); |
5852 | 131k | d = 0; |
5853 | 131k | ++h; |
5854 | 131k | } |
5855 | 793k | } |
5856 | 107k | ++d; |
5857 | 107k | ++n; |
5858 | 107k | } |
5859 | 30.3k | return true; |
5860 | 30.3k | } |
5861 | | |
5862 | | } // namespace ada::idna |
5863 | | /* end file src/punycode.cpp */ |
5864 | | /* begin file src/validity.cpp */ |
5865 | | |
5866 | | #include <algorithm> |
5867 | | #include <span> |
5868 | | #include <string_view> |
5869 | | |
5870 | | namespace ada::idna { |
5871 | | |
5872 | | enum direction : uint8_t { |
5873 | | NONE, |
5874 | | BN, |
5875 | | CS, |
5876 | | ES, |
5877 | | ON, |
5878 | | EN, |
5879 | | L, |
5880 | | R, |
5881 | | NSM, |
5882 | | AL, |
5883 | | AN, |
5884 | | ET, |
5885 | | WS, |
5886 | | RLO, |
5887 | | LRO, |
5888 | | PDF, |
5889 | | RLE, |
5890 | | RLI, |
5891 | | FSI, |
5892 | | PDI, |
5893 | | LRI, |
5894 | | B, |
5895 | | S, |
5896 | | LRE |
5897 | | }; |
5898 | | |
5899 | | // Bidi direction ranges live in the compressed blob as const SoA arrays |
5900 | | // (dir_start / dir_final / dir_value). See table_store.hpp layout asserts. |
5901 | | |
5902 | | // CheckJoiners and CheckBidi are true for URL specification. |
5903 | | |
5904 | | // Assumes ensure_tables() has already been called by is_label_valid(). |
5905 | 208k | inline static direction find_direction(uint32_t code_point) noexcept { |
5906 | | // Binary search on dir_final (sorted upper bounds). |
5907 | 208k | size_t lo = 0, hi = dir_table_count; |
5908 | 2.33M | while (lo < hi) { |
5909 | 2.12M | size_t mid = lo + (hi - lo) / 2; |
5910 | 2.12M | if (dir_final[mid] < code_point) { |
5911 | 942k | lo = mid + 1; |
5912 | 1.17M | } else { |
5913 | 1.17M | hi = mid; |
5914 | 1.17M | } |
5915 | 2.12M | } |
5916 | 208k | if (lo == dir_table_count) { |
5917 | 0 | return direction::NONE; |
5918 | 0 | } |
5919 | 208k | return code_point >= dir_start[lo] ? static_cast<direction>(dir_value[lo]) |
5920 | 208k | : direction::NONE; |
5921 | 208k | } |
5922 | | |
5923 | | inline static size_t find_last_not_of_nsm( |
5924 | 33.6k | const std::u32string_view label) noexcept { |
5925 | 34.7k | for (int i = static_cast<int>(label.size() - 1); i >= 0; i--) |
5926 | 34.7k | if (find_direction(label[i]) != direction::NSM) return i; |
5927 | | |
5928 | 0 | return std::u32string_view::npos; |
5929 | 33.6k | } |
5930 | | |
5931 | | // An RTL label is a label that contains at least one character of type R, AL, |
5932 | | // or AN. https://www.rfc-editor.org/rfc/rfc5893#section-2 |
5933 | 33.6k | inline static bool is_rtl_label(const std::u32string_view label) noexcept { |
5934 | 33.6k | const size_t mask = |
5935 | 33.6k | (1u << direction::R) | (1u << direction::AL) | (1u << direction::AN); |
5936 | | |
5937 | 33.6k | size_t directions = 0; |
5938 | 195k | for (size_t i = 0; i < label.size(); i++) { |
5939 | 161k | directions |= 1u << find_direction(label[i]); |
5940 | 161k | } |
5941 | 33.6k | return (directions & mask) != 0; |
5942 | 33.6k | } |
5943 | | |
5944 | 35.7k | bool is_label_valid(const std::u32string_view label) { |
5945 | 35.7k | if (label.empty()) { |
5946 | 0 | return true; |
5947 | 0 | } |
5948 | 35.7k | if (!ensure_tables() || combining_ranges == nullptr || dir_start == nullptr || |
5949 | 35.7k | dir_final == nullptr || dir_value == nullptr) { |
5950 | 0 | return false; |
5951 | 0 | } |
5952 | | |
5953 | | /////////////// |
5954 | | // We have a normalization step which ensures that we are in NFC. |
5955 | | // If we receive punycode, we normalize and check that the normalized |
5956 | | // version matches the original. |
5957 | | // -------------------------------------- |
5958 | | // The label must be in Unicode Normalization Form NFC. |
5959 | | |
5960 | | // Current URL standard indicatest that CheckHyphens is set to false. |
5961 | | // --------------------------------------- |
5962 | | // If CheckHyphens, the label must not contain a U+002D HYPHEN-MINUS character |
5963 | | // in both the third and fourth positions. If CheckHyphens, the label must |
5964 | | // neither begin nor end with a U+002D HYPHEN-MINUS character. |
5965 | | |
5966 | | // This is not necessary because we segment the |
5967 | | // labels by '.'. |
5968 | | // --------------------------------------- |
5969 | | // The label must not contain a U+002E ( . ) FULL STOP. |
5970 | | // if (label.find('.') != std::string_view::npos) return false; |
5971 | | |
5972 | | // The label must not begin with a combining mark. |
5973 | | // Range membership via lower_bound on range end. |
5974 | 35.7k | const std::span<const uint32_t[2]> comb_span{combining_ranges, |
5975 | 35.7k | combining_range_count}; |
5976 | 35.7k | const auto comb_it = std::ranges::lower_bound( |
5977 | 294k | comb_span, label.front(), {}, [](const auto& range) { return range[1]; }); |
5978 | 35.7k | if (comb_it != comb_span.end() && label.front() >= (*comb_it)[0]) { |
5979 | 170 | return false; |
5980 | 170 | } |
5981 | | // We verify this next step as part of the mapping: |
5982 | | // --------------------------------------------- |
5983 | | // Each code point in the label must only have certain status values |
5984 | | // according to Section 5, IDNA Mapping Table: |
5985 | | // - For Transitional Processing, each value must be valid. |
5986 | | // - For Nontransitional Processing, each value must be either valid or |
5987 | | // deviation. |
5988 | | |
5989 | | // If CheckJoiners, the label must satisfy the ContextJ rules from Appendix |
5990 | | // A, in The Unicode Code Points and Internationalized Domain Names for |
5991 | | // Applications (IDNA) [IDNA2008]. |
5992 | 35.6k | constexpr static uint32_t virama[] = { |
5993 | 35.6k | 0x094D, 0x09CD, 0x0A4D, 0x0ACD, 0x0B4D, 0x0BCD, 0x0C4D, 0x0CCD, |
5994 | 35.6k | 0x0D3B, 0x0D3C, 0x0D4D, 0x0DCA, 0x0E3A, 0x0EBA, 0x0F84, 0x1039, |
5995 | 35.6k | 0x103A, 0x1714, 0x1734, 0x17D2, 0x1A60, 0x1B44, 0x1BAA, 0x1BAB, |
5996 | 35.6k | 0x1BF2, 0x1BF3, 0x2D7F, 0xA806, 0xA82C, 0xA8C4, 0xA953, 0xA9C0, |
5997 | 35.6k | 0xAAF6, 0xABED, 0x10A3F, 0x11046, 0x1107F, 0x110B9, 0x11133, 0x11134, |
5998 | 35.6k | 0x111C0, 0x11235, 0x112EA, 0x1134D, 0x11442, 0x114C2, 0x115BF, 0x1163F, |
5999 | 35.6k | 0x116B6, 0x1172B, 0x11839, 0x1193D, 0x1193E, 0x119E0, 0x11A34, 0x11A47, |
6000 | 35.6k | 0x11A99, 0x11C3F, 0x11D44, 0x11D45, 0x11D97}; |
6001 | 35.6k | constexpr static uint32_t R[] = { |
6002 | 35.6k | 0x622, 0x623, 0x624, 0x625, 0x627, 0x629, 0x62f, 0x630, 0x631, |
6003 | 35.6k | 0x632, 0x648, 0x671, 0x672, 0x673, 0x675, 0x676, 0x677, 0x688, |
6004 | 35.6k | 0x689, 0x68a, 0x68b, 0x68c, 0x68d, 0x68e, 0x68f, 0x690, 0x691, |
6005 | 35.6k | 0x692, 0x693, 0x694, 0x695, 0x696, 0x697, 0x698, 0x699, 0x6c0, |
6006 | 35.6k | 0x6c3, 0x6c4, 0x6c5, 0x6c6, 0x6c7, 0x6c8, 0x6c9, 0x6ca, 0x6cb, |
6007 | 35.6k | 0x6cd, 0x6cf, 0x6d2, 0x6d3, 0x6d5, 0x6ee, 0x6ef, 0x710, 0x715, |
6008 | 35.6k | 0x716, 0x717, 0x718, 0x719, 0x71e, 0x728, 0x72a, 0x72c, 0x72f, |
6009 | 35.6k | 0x74d, 0x759, 0x75a, 0x75b, 0x854, 0x8aa, 0x8ab, 0x8ac}; |
6010 | 35.6k | constexpr static uint32_t L[] = {0xa872}; |
6011 | 35.6k | constexpr static uint32_t D[] = { |
6012 | 35.6k | 0x620, 0x626, 0x628, 0x62a, 0x62b, 0x62c, 0x62d, 0x62e, 0x633, |
6013 | 35.6k | 0x634, 0x635, 0x636, 0x637, 0x638, 0x639, 0x63a, 0x63b, 0x63c, |
6014 | 35.6k | 0x63d, 0x63e, 0x63f, 0x641, 0x642, 0x643, 0x644, 0x645, 0x646, |
6015 | 35.6k | 0x647, 0x649, 0x64a, 0x66e, 0x66f, 0x678, 0x679, 0x67a, 0x67b, |
6016 | 35.6k | 0x67c, 0x67d, 0x67e, 0x67f, 0x680, 0x681, 0x682, 0x683, 0x684, |
6017 | 35.6k | 0x685, 0x686, 0x687, 0x69a, 0x69b, 0x69c, 0x69d, 0x69e, 0x69f, |
6018 | 35.6k | 0x6a0, 0x6a1, 0x6a2, 0x6a3, 0x6a4, 0x6a5, 0x6a6, 0x6a7, 0x6a8, |
6019 | 35.6k | 0x6a9, 0x6aa, 0x6ab, 0x6ac, 0x6ad, 0x6ae, 0x6af, 0x6b0, 0x6b1, |
6020 | 35.6k | 0x6b2, 0x6b3, 0x6b4, 0x6b5, 0x6b6, 0x6b7, 0x6b8, 0x6b9, 0x6ba, |
6021 | 35.6k | 0x6bb, 0x6bc, 0x6bd, 0x6be, 0x6bf, 0x6c1, 0x6c2, 0x6cc, 0x6ce, |
6022 | 35.6k | 0x6d0, 0x6d1, 0x6fa, 0x6fb, 0x6fc, 0x6ff, 0x712, 0x713, 0x714, |
6023 | 35.6k | 0x71a, 0x71b, 0x71c, 0x71d, 0x71f, 0x720, 0x721, 0x722, 0x723, |
6024 | 35.6k | 0x724, 0x725, 0x726, 0x727, 0x729, 0x72b, 0x72d, 0x72e, 0x74e, |
6025 | 35.6k | 0x74f, 0x750, 0x751, 0x752, 0x753, 0x754, 0x755, 0x756, 0x757, |
6026 | 35.6k | 0x758, 0x75c, 0x75d, 0x75e, 0x75f, 0x760, 0x761, 0x762, 0x763, |
6027 | 35.6k | 0x764, 0x765, 0x766, 0x850, 0x851, 0x852, 0x853, 0x855, 0x8a0, |
6028 | 35.6k | 0x8a2, 0x8a3, 0x8a4, 0x8a5, 0x8a6, 0x8a7, 0x8a8, 0x8a9, 0x1807, |
6029 | 35.6k | 0x1820, 0x1821, 0x1822, 0x1823, 0x1824, 0x1825, 0x1826, 0x1827, 0x1828, |
6030 | 35.6k | 0x1829, 0x182a, 0x182b, 0x182c, 0x182d, 0x182e, 0x182f, 0x1830, 0x1831, |
6031 | 35.6k | 0x1832, 0x1833, 0x1834, 0x1835, 0x1836, 0x1837, 0x1838, 0x1839, 0x183a, |
6032 | 35.6k | 0x183b, 0x183c, 0x183d, 0x183e, 0x183f, 0x1840, 0x1841, 0x1842, 0x1843, |
6033 | 35.6k | 0x1844, 0x1845, 0x1846, 0x1847, 0x1848, 0x1849, 0x184a, 0x184b, 0x184c, |
6034 | 35.6k | 0x184d, 0x184e, 0x184f, 0x1850, 0x1851, 0x1852, 0x1853, 0x1854, 0x1855, |
6035 | 35.6k | 0x1856, 0x1857, 0x1858, 0x1859, 0x185a, 0x185b, 0x185c, 0x185d, 0x185e, |
6036 | 35.6k | 0x185f, 0x1860, 0x1861, 0x1862, 0x1863, 0x1864, 0x1865, 0x1866, 0x1867, |
6037 | 35.6k | 0x1868, 0x1869, 0x186a, 0x186b, 0x186c, 0x186d, 0x186e, 0x186f, 0x1870, |
6038 | 35.6k | 0x1871, 0x1872, 0x1873, 0x1874, 0x1875, 0x1876, 0x1877, 0x1887, 0x1888, |
6039 | 35.6k | 0x1889, 0x188a, 0x188b, 0x188c, 0x188d, 0x188e, 0x188f, 0x1890, 0x1891, |
6040 | 35.6k | 0x1892, 0x1893, 0x1894, 0x1895, 0x1896, 0x1897, 0x1898, 0x1899, 0x189a, |
6041 | 35.6k | 0x189b, 0x189c, 0x189d, 0x189e, 0x189f, 0x18a0, 0x18a1, 0x18a2, 0x18a3, |
6042 | 35.6k | 0x18a4, 0x18a5, 0x18a6, 0x18a7, 0x18a8, 0x18aa, 0xa840, 0xa841, 0xa842, |
6043 | 35.6k | 0xa843, 0xa844, 0xa845, 0xa846, 0xa847, 0xa848, 0xa849, 0xa84a, 0xa84b, |
6044 | 35.6k | 0xa84c, 0xa84d, 0xa84e, 0xa84f, 0xa850, 0xa851, 0xa852, 0xa853, 0xa854, |
6045 | 35.6k | 0xa855, 0xa856, 0xa857, 0xa858, 0xa859, 0xa85a, 0xa85b, 0xa85c, 0xa85d, |
6046 | 35.6k | 0xa85e, 0xa85f, 0xa860, 0xa861, 0xa862, 0xa863, 0xa864, 0xa865, 0xa866, |
6047 | 35.6k | 0xa867, 0xa868, 0xa869, 0xa86a, 0xa86b, 0xa86c, 0xa86d, 0xa86e, 0xa86f, |
6048 | 35.6k | 0xa870, 0xa871}; |
6049 | | |
6050 | 204k | for (size_t i = 0; i < label.size(); i++) { |
6051 | 171k | uint32_t c = label[i]; |
6052 | 171k | if (c == 0x200c) { |
6053 | 1.43k | if (i > 0) { |
6054 | 1.34k | if (std::ranges::binary_search(virama, label[i - 1])) { |
6055 | 234 | return true; |
6056 | 234 | } |
6057 | 1.34k | } |
6058 | 1.19k | if ((i == 0) || (i + 1 >= label.size())) { |
6059 | 181 | return false; |
6060 | 181 | } |
6061 | | // we go backward looking for L or D |
6062 | 2.46k | auto is_l_or_d = [](uint32_t code) { |
6063 | 2.46k | return std::ranges::binary_search(L, code) || |
6064 | 2.23k | std::ranges::binary_search(D, code); |
6065 | 2.46k | }; |
6066 | 1.98k | auto is_r_or_d = [](uint32_t code) { |
6067 | 1.98k | return std::ranges::binary_search(R, code) || |
6068 | 1.47k | std::ranges::binary_search(D, code); |
6069 | 1.98k | }; |
6070 | 1.01k | std::u32string_view before = label.substr(0, i); |
6071 | 1.01k | std::u32string_view after = label.substr(i + 1); |
6072 | 1.01k | return (std::find_if(before.begin(), before.end(), is_l_or_d) != |
6073 | 1.01k | before.end()) && |
6074 | 910 | (std::find_if(after.begin(), after.end(), is_r_or_d) != |
6075 | 910 | after.end()); |
6076 | 169k | } else if (c == 0x200d) { |
6077 | 583 | if (i > 0) { |
6078 | 546 | if (std::ranges::binary_search(virama, label[i - 1])) { |
6079 | 446 | return true; |
6080 | 446 | } |
6081 | 546 | } |
6082 | 137 | return false; |
6083 | 583 | } |
6084 | 171k | } |
6085 | | |
6086 | | // If CheckBidi, and if the domain name is a Bidi domain name, then the label |
6087 | | // must satisfy all six of the numbered conditions in [IDNA2008] RFC 5893, |
6088 | | // Section 2. |
6089 | | |
6090 | | // The following rule, consisting of six conditions, applies to labels |
6091 | | // in Bidi domain names. The requirements that this rule satisfies are |
6092 | | // described in Section 3. All of the conditions must be satisfied for |
6093 | | // the rule to be satisfied. |
6094 | | // |
6095 | | // 1. The first character must be a character with Bidi property L, R, |
6096 | | // or AL. If it has the R or AL property, it is an RTL label; if it |
6097 | | // has the L property, it is an LTR label. |
6098 | | // |
6099 | | // 2. In an RTL label, only characters with the Bidi properties R, AL, |
6100 | | // AN, EN, ES, CS, ET, ON, BN, or NSM are allowed. |
6101 | | // |
6102 | | // 3. In an RTL label, the end of the label must be a character with |
6103 | | // Bidi property R, AL, EN, or AN, followed by zero or more |
6104 | | // characters with Bidi property NSM. |
6105 | | // |
6106 | | // 4. In an RTL label, if an EN is present, no AN may be present, and |
6107 | | // vice versa. |
6108 | | // |
6109 | | // 5. In an LTR label, only characters with the Bidi properties L, EN, |
6110 | | // ES, CS, ET, ON, BN, or NSM are allowed. |
6111 | | // |
6112 | | // 6. In an LTR label, the end of the label must be a character with |
6113 | | // Bidi property L or EN, followed by zero or more characters with |
6114 | | // Bidi property NSM. |
6115 | | |
6116 | 33.6k | size_t last_non_nsm_char = find_last_not_of_nsm(label); |
6117 | 33.6k | if (last_non_nsm_char == std::u32string_view::npos) { |
6118 | 0 | return false; |
6119 | 0 | } |
6120 | | |
6121 | | // A "Bidi domain name" is a domain name that contains at least one RTL label. |
6122 | | // The following rule, consisting of six conditions, applies to labels in Bidi |
6123 | | // domain names. |
6124 | 33.6k | if (is_rtl_label(label)) { |
6125 | | // The first character must be a character with Bidi property L, R, |
6126 | | // or AL. If it has the R or AL property, it is an RTL label; if it |
6127 | | // has the L property, it is an LTR label. |
6128 | | |
6129 | 1.92k | if (find_direction(label[0]) == direction::L) { |
6130 | | // Eval as LTR |
6131 | | |
6132 | | // In an LTR label, only characters with the Bidi properties L, EN, |
6133 | | // ES, CS, ET, ON, BN, or NSM are allowed. |
6134 | 3.28k | for (size_t i = 0; i <= last_non_nsm_char; i++) { |
6135 | 3.28k | const direction d = find_direction(label[i]); |
6136 | 3.28k | if (!(d == direction::L || d == direction::EN || d == direction::ES || |
6137 | 1.61k | d == direction::CS || d == direction::ET || d == direction::ON || |
6138 | 869 | d == direction::BN || d == direction::NSM)) { |
6139 | 412 | return false; |
6140 | 412 | } |
6141 | 3.28k | } |
6142 | | |
6143 | 0 | const direction last_dir = find_direction(label[last_non_nsm_char]); |
6144 | 0 | if (!(last_dir == direction::L || last_dir == direction::EN)) { |
6145 | 0 | return false; |
6146 | 0 | } |
6147 | | |
6148 | 0 | return true; |
6149 | |
|
6150 | 1.51k | } else { |
6151 | | // Eval as RTL |
6152 | | |
6153 | | // The first character must be R or AL; a leading AN (or any other |
6154 | | // direction) does not start a valid RTL label. |
6155 | 1.51k | const direction first_dir = find_direction(label[0]); |
6156 | 1.51k | if (first_dir != direction::R && first_dir != direction::AL) { |
6157 | 95 | return false; |
6158 | 95 | } |
6159 | | |
6160 | 1.42k | bool has_an = false; |
6161 | 1.42k | bool has_en = false; |
6162 | 6.46k | for (size_t i = 0; i <= last_non_nsm_char; i++) { |
6163 | 5.29k | const direction d = find_direction(label[i]); |
6164 | | |
6165 | | // In an RTL label, if an EN is present, no AN may be present, and vice |
6166 | | // versa. |
6167 | 5.29k | if ((d == direction::EN && ((has_en = true) && has_an)) || |
6168 | 5.26k | (d == direction::AN && ((has_an = true) && has_en))) { |
6169 | 68 | return false; |
6170 | 68 | } |
6171 | | |
6172 | 5.22k | if (!(d == direction::R || d == direction::AL || d == direction::AN || |
6173 | 2.27k | d == direction::EN || d == direction::ES || d == direction::CS || |
6174 | 1.27k | d == direction::ET || d == direction::ON || d == direction::BN || |
6175 | 317 | d == direction::NSM)) { |
6176 | 93 | return false; |
6177 | 93 | } |
6178 | | |
6179 | 5.13k | if (i == last_non_nsm_char && |
6180 | 1.26k | !(d == direction::R || d == direction::AL || d == direction::AN || |
6181 | 412 | d == direction::EN)) { |
6182 | 87 | return false; |
6183 | 87 | } |
6184 | 5.13k | } |
6185 | | |
6186 | 1.17k | return true; |
6187 | 1.42k | } |
6188 | 1.92k | } |
6189 | | |
6190 | 31.6k | return true; |
6191 | 33.6k | } |
6192 | | |
6193 | | } // namespace ada::idna |
6194 | | /* end file src/validity.cpp */ |
6195 | | /* begin file src/to_ascii.cpp */ |
6196 | | /* begin file include/ada/idna/to_ascii.h */ |
6197 | | #ifndef ADA_IDNA_TO_ASCII_H |
6198 | | #define ADA_IDNA_TO_ASCII_H |
6199 | | |
6200 | | #include <string> |
6201 | | #include <string_view> |
6202 | | |
6203 | | /* begin file include/ada/idna/limits.h */ |
6204 | | #ifndef ADA_IDNA_LIMITS_H |
6205 | | #define ADA_IDNA_LIMITS_H |
6206 | | |
6207 | | #include <cstddef> |
6208 | | |
6209 | | namespace ada::idna { |
6210 | | |
6211 | | // Maximum accepted UTF-8 domain length for to_ascii / to_unicode. |
6212 | | // Bounds heap growth under untrusted input (DoS resistance). DNS wire limits |
6213 | | // are smaller; this allows long Unicode labels used in URL tests/fixtures. |
6214 | | inline constexpr size_t max_domain_input_bytes = 16384; |
6215 | | |
6216 | | } // namespace ada::idna |
6217 | | |
6218 | | #endif // ADA_IDNA_LIMITS_H |
6219 | | /* end file include/ada/idna/limits.h */ |
6220 | | |
6221 | | namespace ada::idna { |
6222 | | |
6223 | | // Converts a domain (e.g., www.google.com) possibly containing international |
6224 | | // characters to an ascii domain (with punycode). It will not do percent |
6225 | | // decoding: percent decoding should be done prior to calling this function. We |
6226 | | // do not remove tabs and spaces, they should have been removed prior to calling |
6227 | | // this function. We also do not trim control characters. We also assume that |
6228 | | // the input is not empty. We return "" on error. Inputs longer than |
6229 | | // max_domain_input_bytes are rejected. |
6230 | | // |
6231 | | // This function may accept or even produce invalid domains (WHATWG carve-outs). |
6232 | | std::string to_ascii(std::string_view ut8_string); |
6233 | | |
6234 | | // Same as to_ascii, but writes into `out` and returns false on error without |
6235 | | // relying on empty-string ambiguity. |
6236 | | [[nodiscard]] bool to_ascii(std::string_view ut8_string, std::string& out); |
6237 | | |
6238 | | // Returns true if the string contains a forbidden code point according to the |
6239 | | // WHATGL URL specification: |
6240 | | // https://url.spec.whatwg.org/#forbidden-domain-code-point |
6241 | | bool contains_forbidden_domain_code_point(std::string_view ascii_string); |
6242 | | |
6243 | | bool constexpr is_ascii(std::u32string_view view); |
6244 | | bool constexpr is_ascii(std::string_view view); |
6245 | | |
6246 | | } // namespace ada::idna |
6247 | | |
6248 | | #endif // ADA_IDNA_TO_ASCII_H |
6249 | | /* end file include/ada/idna/to_ascii.h */ |
6250 | | |
6251 | | #include <algorithm> |
6252 | | #include <cstdint> |
6253 | | #include <cstring> |
6254 | | #include <ranges> |
6255 | | |
6256 | | /* begin file include/ada/idna/validity.h */ |
6257 | | #ifndef ADA_IDNA_VALIDITY_H |
6258 | | #define ADA_IDNA_VALIDITY_H |
6259 | | |
6260 | | #include <string> |
6261 | | #include <string_view> |
6262 | | |
6263 | | namespace ada::idna { |
6264 | | |
6265 | | /** |
6266 | | * @see https://www.unicode.org/reports/tr46/#Validity_Criteria |
6267 | | */ |
6268 | | bool is_label_valid(std::u32string_view label); |
6269 | | |
6270 | | } // namespace ada::idna |
6271 | | |
6272 | | #endif // ADA_IDNA_VALIDITY_H |
6273 | | /* end file include/ada/idna/validity.h */ |
6274 | | |
6275 | | #ifdef ADA_USE_SIMDUTF |
6276 | | #include "simdutf.h" |
6277 | | #endif |
6278 | | |
6279 | | namespace ada::idna { |
6280 | | |
6281 | 51.0k | bool constexpr is_ascii(std::u32string_view view) { |
6282 | 139k | for (uint32_t c : view) { |
6283 | 139k | if (c >= 0x80) { |
6284 | 46.4k | return false; |
6285 | 46.4k | } |
6286 | 139k | } |
6287 | 4.55k | return true; |
6288 | 51.0k | } |
6289 | | |
6290 | 24.6k | bool constexpr is_ascii(std::string_view view) { |
6291 | 465k | for (uint8_t c : view) { |
6292 | 465k | if (c >= 0x80) { |
6293 | 9.35k | return false; |
6294 | 9.35k | } |
6295 | 465k | } |
6296 | 15.3k | return true; |
6297 | 24.6k | } |
6298 | | |
6299 | | constexpr static uint8_t is_forbidden_domain_code_point_table[] = { |
6300 | | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
6301 | | 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, |
6302 | | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, |
6303 | | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, |
6304 | | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
6305 | | 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
6306 | | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
6307 | | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
6308 | | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
6309 | | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
6310 | | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; |
6311 | | |
6312 | | static_assert(sizeof(is_forbidden_domain_code_point_table) == 256); |
6313 | | |
6314 | 0 | inline bool is_forbidden_domain_code_point(const char c) noexcept { |
6315 | 0 | return is_forbidden_domain_code_point_table[uint8_t(c)]; |
6316 | 0 | } |
6317 | | |
6318 | 0 | bool contains_forbidden_domain_code_point(std::string_view view) { |
6319 | 0 | return std::ranges::any_of(view, is_forbidden_domain_code_point); |
6320 | 0 | } |
6321 | | |
6322 | | // Per the WHATWG URL "domain to ASCII" algorithm, when beStrict is false and |
6323 | | // the input domain is an ASCII string, the result is the input lowercased, |
6324 | | // regardless of the outcome of Unicode ToASCII. |
6325 | | // |
6326 | | // See https://url.spec.whatwg.org/#concept-domain-to-ascii |
6327 | 12.5k | static void from_ascii_to_ascii(std::string_view ut8_string, std::string& out) { |
6328 | 12.5k | out.assign(ut8_string); |
6329 | 12.5k | ascii_map(out.data(), out.size()); |
6330 | 12.5k | } |
6331 | | |
6332 | | // Append ASCII code units from a UTF-32 label (all values < 0x80). |
6333 | 7.40k | static void append_ascii_label(std::string& out, std::u32string_view label) { |
6334 | 7.40k | const size_t old = out.size(); |
6335 | 7.40k | out.resize(old + label.size()); |
6336 | 7.40k | char* dest = out.data() + old; |
6337 | 73.6k | for (char32_t c : label) { |
6338 | 73.6k | *dest++ = static_cast<char>(c); |
6339 | 73.6k | } |
6340 | 7.40k | } |
6341 | | |
6342 | | // True if label begins with "xn--" (already lowercased by mapping). |
6343 | 38.7k | static bool is_ace_prefix(std::u32string_view label) noexcept { |
6344 | 38.7k | return label.size() >= 4 && label[0] == U'x' && label[1] == U'n' && |
6345 | 4.46k | label[2] == U'-' && label[3] == U'-'; |
6346 | 38.7k | } |
6347 | | |
6348 | 21.7k | [[nodiscard]] bool to_ascii(std::string_view ut8_string, std::string& out) { |
6349 | 21.7k | out.clear(); |
6350 | 21.7k | if (ut8_string.size() > max_domain_input_bytes) { |
6351 | 0 | return false; |
6352 | 0 | } |
6353 | 21.7k | if (is_ascii(ut8_string)) { |
6354 | 12.5k | from_ascii_to_ascii(ut8_string, out); |
6355 | 12.5k | return true; |
6356 | 12.5k | } |
6357 | | |
6358 | | #ifdef ADA_USE_SIMDUTF |
6359 | | size_t utf32_length = |
6360 | | simdutf::utf32_length_from_utf8(ut8_string.data(), ut8_string.size()); |
6361 | | if (utf32_length == 0 && !ut8_string.empty()) { |
6362 | | return false; |
6363 | | } |
6364 | | std::u32string working(utf32_length, U'\0'); |
6365 | | size_t actual_utf32_length = simdutf::convert_utf8_to_utf32( |
6366 | | ut8_string.data(), ut8_string.size(), working.data()); |
6367 | | #else |
6368 | 9.20k | size_t utf32_length = |
6369 | 9.20k | ada::idna::utf32_length_from_utf8(ut8_string.data(), ut8_string.size()); |
6370 | 9.20k | if (utf32_length == 0 && !ut8_string.empty()) { |
6371 | 84 | return false; |
6372 | 84 | } |
6373 | 9.11k | std::u32string working(utf32_length, U'\0'); |
6374 | 9.11k | size_t actual_utf32_length = ada::idna::utf8_to_utf32( |
6375 | 9.11k | ut8_string.data(), ut8_string.size(), working.data()); |
6376 | 9.11k | #endif |
6377 | 9.11k | if (actual_utf32_length == 0 || actual_utf32_length != utf32_length) { |
6378 | 2.44k | return false; |
6379 | 2.44k | } |
6380 | 6.67k | working.resize(actual_utf32_length); |
6381 | | |
6382 | | // Map into a second buffer with exact sizing (no growth reallocs). |
6383 | 6.67k | std::u32string mapped; |
6384 | 6.67k | if (!ada::idna::map(working, mapped)) { |
6385 | 79 | return false; |
6386 | 79 | } |
6387 | | // Drop UTF-32 input; reuse `working` as scratch for ACE validation below. |
6388 | 6.59k | working.clear(); |
6389 | | |
6390 | | // Skip NFC when already normalized (ASCII is a fast subset of this check). |
6391 | 6.59k | if (!is_ascii(mapped) && !is_already_nfc(mapped)) { |
6392 | 1.20k | if (!normalize(mapped)) { |
6393 | 0 | return false; |
6394 | 0 | } |
6395 | 1.20k | } |
6396 | | |
6397 | | // Estimate ASCII output size (punycode may expand non-ASCII labels). |
6398 | 6.59k | out.reserve(mapped.size() + 8); |
6399 | | |
6400 | | // Walk labels with a single pointer scan (no repeated string::find). |
6401 | 6.59k | const char32_t* p = mapped.data(); |
6402 | 6.59k | const char32_t* const end = p + mapped.size(); |
6403 | 6.59k | std::u32string post_map; |
6404 | | |
6405 | 44.9k | while (p < end) { |
6406 | 40.1k | const char32_t* label_begin = p; |
6407 | 287k | while (p < end && *p != U'.') { |
6408 | 246k | ++p; |
6409 | 246k | } |
6410 | 40.1k | const size_t label_size = static_cast<size_t>(p - label_begin); |
6411 | 40.1k | std::u32string_view label_view(label_begin, label_size); |
6412 | 40.1k | const bool is_last_label = (p == end); |
6413 | 40.1k | if (p < end) { |
6414 | 34.3k | ++p; // skip dot |
6415 | 34.3k | } |
6416 | | |
6417 | 40.1k | if (label_size == 0) { |
6418 | | // empty label |
6419 | 38.7k | } else if (is_ace_prefix(label_view)) { |
6420 | 56.2k | for (char32_t c : label_view) { |
6421 | 56.2k | if (c >= 0x80) { |
6422 | 47 | out.clear(); |
6423 | 47 | return false; |
6424 | 47 | } |
6425 | 56.2k | } |
6426 | 3.94k | append_ascii_label(out, label_view); |
6427 | 3.94k | std::string_view puny_segment_ascii( |
6428 | 3.94k | out.data() + (out.size() - label_size) + 4, label_size - 4); |
6429 | 3.94k | working.clear(); |
6430 | 3.94k | if (!ada::idna::punycode_to_utf32(puny_segment_ascii, working)) { |
6431 | 145 | out.clear(); |
6432 | 145 | return false; |
6433 | 145 | } |
6434 | 3.79k | if (is_ascii(working)) { |
6435 | 135 | out.clear(); |
6436 | 135 | return false; |
6437 | 135 | } |
6438 | 3.66k | if (!ada::idna::map(working, post_map) || working != post_map) { |
6439 | 187 | out.clear(); |
6440 | 187 | return false; |
6441 | 187 | } |
6442 | | // Mapping must be stable; NFC must not change the mapped form either. |
6443 | 3.47k | if (!is_ascii(post_map) && !is_already_nfc(post_map)) { |
6444 | 1.18k | if (!normalize(post_map) || post_map != working) { |
6445 | 173 | out.clear(); |
6446 | 173 | return false; |
6447 | 173 | } |
6448 | 1.18k | } |
6449 | 3.30k | if (post_map.empty() || !is_label_valid(post_map)) { |
6450 | 166 | out.clear(); |
6451 | 166 | return false; |
6452 | 166 | } |
6453 | 34.7k | } else if (is_ascii(label_view)) { |
6454 | 3.45k | append_ascii_label(out, label_view); |
6455 | 31.3k | } else { |
6456 | 31.3k | if (!is_label_valid(label_view)) { |
6457 | 959 | out.clear(); |
6458 | 959 | return false; |
6459 | 959 | } |
6460 | 30.3k | out.append("xn--"); |
6461 | 30.3k | if (!ada::idna::utf32_to_punycode(label_view, out)) { |
6462 | 0 | out.clear(); |
6463 | 0 | return false; |
6464 | 0 | } |
6465 | 30.3k | } |
6466 | 38.3k | if (!is_last_label) { |
6467 | 33.8k | out.push_back('.'); |
6468 | 33.8k | } |
6469 | 38.3k | } |
6470 | 4.78k | return true; |
6471 | 6.59k | } |
6472 | | |
6473 | 21.7k | std::string to_ascii(std::string_view ut8_string) { |
6474 | 21.7k | std::string out; |
6475 | 21.7k | if (!to_ascii(ut8_string, out)) { |
6476 | 4.41k | return {}; |
6477 | 4.41k | } |
6478 | 17.3k | return out; |
6479 | 21.7k | } |
6480 | | } // namespace ada::idna |
6481 | | /* end file src/to_ascii.cpp */ |
6482 | | /* begin file src/to_unicode.cpp */ |
6483 | | /* begin file include/ada/idna/to_unicode.h */ |
6484 | | #ifndef ADA_IDNA_TO_UNICODE_H |
6485 | | #define ADA_IDNA_TO_UNICODE_H |
6486 | | |
6487 | | #include <string> |
6488 | | #include <string_view> |
6489 | | |
6490 | | |
6491 | | namespace ada::idna { |
6492 | | |
6493 | | // UTS #46 ToUnicode. Never fails per the standard: on step failure the original |
6494 | | // label is kept. Inputs longer than max_domain_input_bytes are returned |
6495 | | // unchanged as a safety measure under untrusted input. |
6496 | | std::string to_unicode(std::string_view input); |
6497 | | |
6498 | | // Writes into `out`. Returns false only if the input exceeds |
6499 | | // max_domain_input_bytes (out is left empty). Otherwise always returns true |
6500 | | // (ToUnicode does not fail). |
6501 | | [[nodiscard]] bool to_unicode(std::string_view input, std::string& out); |
6502 | | |
6503 | | } // namespace ada::idna |
6504 | | |
6505 | | #endif // ADA_IDNA_TO_UNICODE_H |
6506 | | /* end file include/ada/idna/to_unicode.h */ |
6507 | | |
6508 | | #include <algorithm> |
6509 | | #include <string> |
6510 | | |
6511 | | /* begin file include/idna.h */ |
6512 | | #ifndef ADA_IDNA_H |
6513 | | #define ADA_IDNA_H |
6514 | | |
6515 | | /* begin file include/ada/idna/identifier.h */ |
6516 | | #ifndef ADA_IDNA_IDENTIFIER_H |
6517 | | #define ADA_IDNA_IDENTIFIER_H |
6518 | | |
6519 | | #include <string> |
6520 | | #include <string_view> |
6521 | | |
6522 | | namespace ada::idna { |
6523 | | |
6524 | | // Verify if it is valid name code point given a Unicode code point and a |
6525 | | // boolean first: If first is true return the result of checking if code point |
6526 | | // is contained in the IdentifierStart set of code points. Otherwise return the |
6527 | | // result of checking if code point is contained in the IdentifierPart set of |
6528 | | // code points. Returns false if the input is empty or the code point is not |
6529 | | // valid. There is minimal Unicode error handling: the input should be valid |
6530 | | // UTF-8. https://urlpattern.spec.whatwg.org/#is-a-valid-name-code-point |
6531 | | bool valid_name_code_point(char32_t code_point, bool first); |
6532 | | |
6533 | | } // namespace ada::idna |
6534 | | |
6535 | | #endif |
6536 | | /* end file include/ada/idna/identifier.h */ |
6537 | | |
6538 | | #endif |
6539 | | /* end file include/idna.h */ |
6540 | | |
6541 | | #ifdef ADA_USE_SIMDUTF |
6542 | | #include "simdutf.h" |
6543 | | #endif |
6544 | | |
6545 | | namespace ada::idna { |
6546 | | |
6547 | 11.0k | [[nodiscard]] bool to_unicode(std::string_view input, std::string& output) { |
6548 | 11.0k | output.clear(); |
6549 | 11.0k | if (input.size() > max_domain_input_bytes) { |
6550 | 0 | return false; |
6551 | 0 | } |
6552 | 11.0k | output.reserve(input.size()); |
6553 | | |
6554 | 11.0k | size_t label_start = 0; |
6555 | 11.0k | std::u32string tmp_buffer; |
6556 | 11.0k | std::u32string post_map; |
6557 | 41.5k | while (label_start < input.size()) { |
6558 | 30.5k | size_t loc_dot = input.find('.', label_start); |
6559 | 30.5k | bool is_last_label = (loc_dot == std::string_view::npos); |
6560 | 30.5k | size_t label_size = |
6561 | 30.5k | is_last_label ? input.size() - label_start : loc_dot - label_start; |
6562 | 30.5k | auto label_view = std::string_view(input.data() + label_start, label_size); |
6563 | | |
6564 | 30.5k | if (label_view.starts_with("xn--") && ada::idna::is_ascii(label_view)) { |
6565 | 2.78k | label_view.remove_prefix(4); |
6566 | 2.78k | tmp_buffer.clear(); |
6567 | 2.78k | if (ada::idna::punycode_to_utf32(label_view, tmp_buffer)) { |
6568 | | // Per UTS #46, the decoded label must be re-validated. Reject decodings |
6569 | | // that are pure ASCII (xn-- encoding of an ASCII-only label), or whose |
6570 | | // mapping/normalization is not stable, or that fail label validity. |
6571 | 2.36k | bool accept_decoded = true; |
6572 | 2.36k | if (ada::idna::is_ascii(tmp_buffer)) { |
6573 | 297 | accept_decoded = false; |
6574 | 2.07k | } else { |
6575 | 2.07k | post_map.clear(); |
6576 | 2.07k | if (!ada::idna::map(tmp_buffer, post_map) || post_map != tmp_buffer) { |
6577 | 637 | accept_decoded = false; |
6578 | 1.43k | } else if (!ada::idna::normalize(post_map) || |
6579 | 1.43k | post_map != tmp_buffer || post_map.empty() || |
6580 | 1.16k | !ada::idna::is_label_valid(post_map)) { |
6581 | 630 | accept_decoded = false; |
6582 | 630 | } |
6583 | 2.07k | } |
6584 | | |
6585 | 2.36k | if (accept_decoded) { |
6586 | | #ifdef ADA_USE_SIMDUTF |
6587 | | auto utf8_size = simdutf::utf8_length_from_utf32(tmp_buffer.data(), |
6588 | | tmp_buffer.size()); |
6589 | | size_t old_size = output.size(); |
6590 | | output.resize(old_size + utf8_size); |
6591 | | size_t written = simdutf::convert_utf32_to_utf8( |
6592 | | tmp_buffer.data(), tmp_buffer.size(), output.data() + old_size); |
6593 | | if (written != utf8_size) { |
6594 | | output.resize(old_size); |
6595 | | output.append( |
6596 | | std::string_view(input.data() + label_start, label_size)); |
6597 | | } |
6598 | | #else |
6599 | 803 | auto utf8_size = ada::idna::utf8_length_from_utf32(tmp_buffer.data(), |
6600 | 803 | tmp_buffer.size()); |
6601 | 803 | size_t old_size = output.size(); |
6602 | 803 | output.resize(old_size + utf8_size); |
6603 | 803 | size_t written = ada::idna::utf32_to_utf8( |
6604 | 803 | tmp_buffer.data(), tmp_buffer.size(), output.data() + old_size); |
6605 | 803 | if (written != utf8_size) { |
6606 | 0 | output.resize(old_size); |
6607 | 0 | output.append( |
6608 | 0 | std::string_view(input.data() + label_start, label_size)); |
6609 | 0 | } |
6610 | 803 | #endif |
6611 | 1.56k | } else { |
6612 | | // ToUnicode never fails. If any step fails, return the original |
6613 | | // input sequence for the label. |
6614 | 1.56k | output.append( |
6615 | 1.56k | std::string_view(input.data() + label_start, label_size)); |
6616 | 1.56k | } |
6617 | 2.36k | } else { |
6618 | 422 | output.append(std::string_view(input.data() + label_start, label_size)); |
6619 | 422 | } |
6620 | 27.7k | } else { |
6621 | 27.7k | output.append(label_view); |
6622 | 27.7k | } |
6623 | | |
6624 | 30.5k | if (!is_last_label) { |
6625 | 20.1k | output.push_back('.'); |
6626 | 20.1k | } |
6627 | | |
6628 | 30.5k | label_start += label_size + 1; |
6629 | 30.5k | } |
6630 | | |
6631 | 11.0k | return true; |
6632 | 11.0k | } |
6633 | | |
6634 | 11.0k | std::string to_unicode(std::string_view input) { |
6635 | 11.0k | std::string output; |
6636 | 11.0k | if (!to_unicode(input, output)) { |
6637 | | // Over-limit input: return original (ToUnicode never fails in the sense of |
6638 | | // producing no answer for valid-length inputs). |
6639 | 0 | return std::string(input); |
6640 | 0 | } |
6641 | 11.0k | return output; |
6642 | 11.0k | } |
6643 | | } // namespace ada::idna |
6644 | | /* end file src/to_unicode.cpp */ |
6645 | | /* begin file src/identifier.cpp */ |
6646 | | |
6647 | | #include <algorithm> |
6648 | | #include <array> |
6649 | | #include <span> |
6650 | | #include <string> |
6651 | | |
6652 | | /* begin file src/id_tables.cpp */ |
6653 | | // IDNA 17.0.0 |
6654 | | // Identifier range tables are stored in the compressed blob (table_store.hpp). |
6655 | | |
6656 | | // clang-format off |
6657 | | #ifndef ADA_IDNA_IDENTIFIER_TABLES_H |
6658 | | #define ADA_IDNA_IDENTIFIER_TABLES_H |
6659 | | #include <cstdint> |
6660 | | |
6661 | | namespace ada::idna { |
6662 | | |
6663 | | // id_continue / id_start pointers and counts are provided by table_store.hpp. |
6664 | | |
6665 | | } // namespace ada::idna |
6666 | | #endif // ADA_IDNA_IDENTIFIER_TABLES_H |
6667 | | /* end file src/id_tables.cpp */ |
6668 | | |
6669 | | namespace ada::idna { |
6670 | 0 | constexpr bool is_ascii_letter(char32_t c) noexcept { |
6671 | 0 | return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'); |
6672 | 0 | } |
6673 | | |
6674 | 0 | constexpr bool is_ascii_letter_or_digit(char32_t c) noexcept { |
6675 | 0 | return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || |
6676 | 0 | (c >= '0' && c <= '9'); |
6677 | 0 | } |
6678 | | |
6679 | 0 | bool valid_name_code_point(char32_t code_point, bool first) { |
6680 | | // https://tc39.es/ecma262/#prod-IdentifierStart |
6681 | | |
6682 | | // Fast paths (no table needed) |
6683 | 0 | if (first && (code_point == U'$' || code_point == U'_' || |
6684 | 0 | is_ascii_letter(code_point))) { |
6685 | 0 | return true; |
6686 | 0 | } |
6687 | 0 | if (!first && (code_point == U'$' || is_ascii_letter_or_digit(code_point))) { |
6688 | 0 | return true; |
6689 | 0 | } |
6690 | | |
6691 | | // Minimal error handling for invalid code point |
6692 | 0 | if (code_point > 0x10FFFF) { |
6693 | 0 | return false; |
6694 | 0 | } |
6695 | 0 | if (code_point >= 0xD800 && code_point <= 0xDFFF) { |
6696 | 0 | return false; |
6697 | 0 | } |
6698 | | |
6699 | 0 | if (!ensure_tables() || id_start == nullptr || id_continue == nullptr) { |
6700 | 0 | return false; |
6701 | 0 | } |
6702 | | |
6703 | | // Slow path: binary search through the appropriate Unicode range table. |
6704 | | // Each entry is a [low, high] inclusive range. |
6705 | 0 | const std::span<const uint32_t[2]> ranges = |
6706 | 0 | first ? std::span<const uint32_t[2]>{ada::idna::id_start, |
6707 | 0 | ada::idna::id_start_count} |
6708 | 0 | : std::span<const uint32_t[2]>{ada::idna::id_continue, |
6709 | 0 | ada::idna::id_continue_count}; |
6710 | |
|
6711 | 0 | const auto iter = std::ranges::lower_bound( |
6712 | 0 | ranges, code_point, {}, |
6713 | 0 | [](const auto& range) { return range[1]; }); // project to range-high |
6714 | |
|
6715 | 0 | return iter != ranges.end() && code_point >= (*iter)[0]; |
6716 | 0 | } |
6717 | | } // namespace ada::idna |
6718 | | /* end file src/identifier.cpp */ |
6719 | | /* end file src/idna.cpp */ |
6720 | | /* end file src/ada_idna.cpp */ |
6721 | | ADA_POP_DISABLE_WARNINGS |
6722 | | |
6723 | | #include <algorithm> |
6724 | | #include <array> |
6725 | | #include <cstring> |
6726 | | #if ADA_SSSE3 |
6727 | | #include <tmmintrin.h> |
6728 | | #elif ADA_NEON |
6729 | | #include <arm_neon.h> |
6730 | | #elif ADA_SSE2 |
6731 | | #include <emmintrin.h> |
6732 | | #elif ADA_LSX |
6733 | | #include <lsxintrin.h> |
6734 | | #elif ADA_RVV |
6735 | | #include <riscv_vector.h> |
6736 | | #endif |
6737 | | |
6738 | | #include <ranges> |
6739 | | |
6740 | | namespace ada::unicode { |
6741 | | |
6742 | 1.18M | constexpr bool is_tabs_or_newline(char c) noexcept { |
6743 | 1.18M | return c == '\r' || c == '\n' || c == '\t'; |
6744 | 1.18M | } |
6745 | | |
6746 | 167k | constexpr uint64_t broadcast(uint8_t v) noexcept { |
6747 | 167k | return 0x101010101010101ull * v; |
6748 | 167k | } |
6749 | | |
6750 | 55.7k | constexpr bool to_lower_ascii(char* input, size_t length) noexcept { |
6751 | 55.7k | uint64_t broadcast_80 = broadcast(0x80); |
6752 | 55.7k | uint64_t broadcast_Ap = broadcast(128 - 'A'); |
6753 | 55.7k | uint64_t broadcast_Zp = broadcast(128 - 'Z' - 1); |
6754 | 55.7k | uint64_t non_ascii = 0; |
6755 | 55.7k | size_t i = 0; |
6756 | | |
6757 | 60.1k | for (; i + 7 < length; i += 8) { |
6758 | 4.41k | uint64_t word{}; |
6759 | 4.41k | memcpy(&word, input + i, sizeof(word)); |
6760 | 4.41k | non_ascii |= (word & broadcast_80); |
6761 | 4.41k | word ^= |
6762 | 4.41k | (((word + broadcast_Ap) ^ (word + broadcast_Zp)) & broadcast_80) >> 2; |
6763 | 4.41k | memcpy(input + i, &word, sizeof(word)); |
6764 | 4.41k | } |
6765 | 55.7k | if (i < length) { |
6766 | 55.5k | uint64_t word{}; |
6767 | 55.5k | memcpy(&word, input + i, length - i); |
6768 | 55.5k | non_ascii |= (word & broadcast_80); |
6769 | 55.5k | word ^= |
6770 | 55.5k | (((word + broadcast_Ap) ^ (word + broadcast_Zp)) & broadcast_80) >> 2; |
6771 | 55.5k | memcpy(input + i, &word, length - i); |
6772 | 55.5k | } |
6773 | 55.7k | return non_ascii == 0; |
6774 | 55.7k | } |
6775 | | #if ADA_SSSE3 |
6776 | | ada_really_inline bool has_tabs_or_newline( |
6777 | | std::string_view user_input) noexcept { |
6778 | | // first check for short strings in which case we do it naively. |
6779 | | if (user_input.size() < 16) { // slow path |
6780 | | return std::ranges::any_of(user_input, is_tabs_or_newline); |
6781 | | } |
6782 | | // fast path for long strings (expected to be common) |
6783 | | // Using SSSE3's _mm_shuffle_epi8 for table lookup (same approach as NEON) |
6784 | | size_t i = 0; |
6785 | | // Lookup table where positions 9, 10, 13 contain their own values |
6786 | | // Everything else is set to 1 so it won't match |
6787 | | const __m128i rnt = |
6788 | | _mm_setr_epi8(1, 0, 0, 0, 0, 0, 0, 0, 0, 9, 10, 0, 0, 13, 0, 0); |
6789 | | __m128i running = _mm_setzero_si128(); |
6790 | | for (; i + 15 < user_input.size(); i += 16) { |
6791 | | __m128i word = _mm_loadu_si128((const __m128i*)(user_input.data() + i)); |
6792 | | // Shuffle the lookup table using input bytes as indices |
6793 | | __m128i shuffled = _mm_shuffle_epi8(rnt, word); |
6794 | | // Compare: if shuffled value matches input, we found \t, \n, or \r |
6795 | | __m128i matches = _mm_cmpeq_epi8(shuffled, word); |
6796 | | running = _mm_or_si128(running, matches); |
6797 | | } |
6798 | | if (i < user_input.size()) { |
6799 | | __m128i word = _mm_loadu_si128( |
6800 | | (const __m128i*)(user_input.data() + user_input.length() - 16)); |
6801 | | __m128i shuffled = _mm_shuffle_epi8(rnt, word); |
6802 | | __m128i matches = _mm_cmpeq_epi8(shuffled, word); |
6803 | | running = _mm_or_si128(running, matches); |
6804 | | } |
6805 | | return _mm_movemask_epi8(running) != 0; |
6806 | | } |
6807 | | #elif ADA_NEON |
6808 | | ada_really_inline bool has_tabs_or_newline( |
6809 | | std::string_view user_input) noexcept { |
6810 | | // first check for short strings in which case we do it naively. |
6811 | | if (user_input.size() < 16) { // slow path |
6812 | | return std::ranges::any_of(user_input, is_tabs_or_newline); |
6813 | | } |
6814 | | // fast path for long strings (expected to be common) |
6815 | | size_t i = 0; |
6816 | | /** |
6817 | | * The fastest way to check for `\t` (==9), '\n'(== 10) and `\r` (==13) relies |
6818 | | * on table lookup instruction. We notice that these are all unique numbers |
6819 | | * between 0..15. Let's prepare a special register, where we put '\t' in the |
6820 | | * 9th position, '\n' - 10th and '\r' - 13th. Then we shuffle this register by |
6821 | | * input register. If the input had `\t` in position X then this shuffled |
6822 | | * register will also have '\t' in that position. Comparing input with this |
6823 | | * shuffled register will mark us all interesting characters in the input. |
6824 | | * |
6825 | | * credit for algorithmic idea: @aqrit, credit for description: |
6826 | | * @DenisYaroshevskiy |
6827 | | */ |
6828 | | static uint8_t rnt_array[16] = {1, 0, 0, 0, 0, 0, 0, 0, |
6829 | | 0, 9, 10, 0, 0, 13, 0, 0}; |
6830 | | const uint8x16_t rnt = vld1q_u8(rnt_array); |
6831 | | // m['0xd', '0xa', '0x9'] |
6832 | | uint8x16_t running{0}; |
6833 | | for (; i + 15 < user_input.size(); i += 16) { |
6834 | | uint8x16_t word = vld1q_u8((const uint8_t*)user_input.data() + i); |
6835 | | |
6836 | | running = vorrq_u8(running, vceqq_u8(vqtbl1q_u8(rnt, word), word)); |
6837 | | } |
6838 | | if (i < user_input.size()) { |
6839 | | uint8x16_t word = |
6840 | | vld1q_u8((const uint8_t*)user_input.data() + user_input.length() - 16); |
6841 | | running = vorrq_u8(running, vceqq_u8(vqtbl1q_u8(rnt, word), word)); |
6842 | | } |
6843 | | // `running` accumulates comparison results, so every lane is 0x00 or 0xFF: |
6844 | | // narrowing to four bits per lane and comparing the result against zero as a |
6845 | | // double is a cheaper "is anything set?" test than a horizontal maximum. |
6846 | | uint8x8_t narrowed = vshrn_n_u16(vreinterpretq_u16_u8(running), 4); |
6847 | | return vdupd_lane_f64(vreinterpret_f64_u8(narrowed), 0) != 0.0; |
6848 | | } |
6849 | | #elif ADA_SSE2 |
6850 | | ada_really_inline bool has_tabs_or_newline( |
6851 | 238k | std::string_view user_input) noexcept { |
6852 | | // first check for short strings in which case we do it naively. |
6853 | 238k | if (user_input.size() < 16) { // slow path |
6854 | 152k | return std::ranges::any_of(user_input, is_tabs_or_newline); |
6855 | 152k | } |
6856 | | // fast path for long strings (expected to be common) |
6857 | 85.3k | size_t i = 0; |
6858 | 85.3k | const __m128i mask1 = _mm_set1_epi8('\r'); |
6859 | 85.3k | const __m128i mask2 = _mm_set1_epi8('\n'); |
6860 | 85.3k | const __m128i mask3 = _mm_set1_epi8('\t'); |
6861 | | // If we supported SSSE3, we could use the algorithm that we use for NEON. |
6862 | 85.3k | __m128i running{0}; |
6863 | 302k | for (; i + 15 < user_input.size(); i += 16) { |
6864 | 216k | __m128i word = _mm_loadu_si128((const __m128i*)(user_input.data() + i)); |
6865 | 216k | running = _mm_or_si128( |
6866 | 216k | _mm_or_si128(running, _mm_or_si128(_mm_cmpeq_epi8(word, mask1), |
6867 | 216k | _mm_cmpeq_epi8(word, mask2))), |
6868 | 216k | _mm_cmpeq_epi8(word, mask3)); |
6869 | 216k | } |
6870 | 85.3k | if (i < user_input.size()) { |
6871 | 82.0k | __m128i word = _mm_loadu_si128( |
6872 | 82.0k | (const __m128i*)(user_input.data() + user_input.length() - 16)); |
6873 | 82.0k | running = _mm_or_si128( |
6874 | 82.0k | _mm_or_si128(running, _mm_or_si128(_mm_cmpeq_epi8(word, mask1), |
6875 | 82.0k | _mm_cmpeq_epi8(word, mask2))), |
6876 | 82.0k | _mm_cmpeq_epi8(word, mask3)); |
6877 | 82.0k | } |
6878 | 85.3k | return _mm_movemask_epi8(running) != 0; |
6879 | 238k | } |
6880 | | #elif ADA_LSX |
6881 | | ada_really_inline bool has_tabs_or_newline( |
6882 | | std::string_view user_input) noexcept { |
6883 | | // first check for short strings in which case we do it naively. |
6884 | | if (user_input.size() < 16) { // slow path |
6885 | | return std::ranges::any_of(user_input, is_tabs_or_newline); |
6886 | | } |
6887 | | // fast path for long strings (expected to be common) |
6888 | | size_t i = 0; |
6889 | | const __m128i mask1 = __lsx_vrepli_b('\r'); |
6890 | | const __m128i mask2 = __lsx_vrepli_b('\n'); |
6891 | | const __m128i mask3 = __lsx_vrepli_b('\t'); |
6892 | | // If we supported SSSE3, we could use the algorithm that we use for NEON. |
6893 | | __m128i running{0}; |
6894 | | for (; i + 15 < user_input.size(); i += 16) { |
6895 | | __m128i word = __lsx_vld((const __m128i*)(user_input.data() + i), 0); |
6896 | | running = __lsx_vor_v( |
6897 | | __lsx_vor_v(running, __lsx_vor_v(__lsx_vseq_b(word, mask1), |
6898 | | __lsx_vseq_b(word, mask2))), |
6899 | | __lsx_vseq_b(word, mask3)); |
6900 | | } |
6901 | | if (i < user_input.size()) { |
6902 | | __m128i word = __lsx_vld( |
6903 | | (const __m128i*)(user_input.data() + user_input.length() - 16), 0); |
6904 | | running = __lsx_vor_v( |
6905 | | __lsx_vor_v(running, __lsx_vor_v(__lsx_vseq_b(word, mask1), |
6906 | | __lsx_vseq_b(word, mask2))), |
6907 | | __lsx_vseq_b(word, mask3)); |
6908 | | } |
6909 | | if (__lsx_bz_v(running)) return false; |
6910 | | return true; |
6911 | | } |
6912 | | #elif ADA_RVV |
6913 | | ada_really_inline bool has_tabs_or_newline( |
6914 | | std::string_view user_input) noexcept { |
6915 | | uint8_t* src = (uint8_t*)user_input.data(); |
6916 | | for (size_t vl, n = user_input.size(); n > 0; n -= vl, src += vl) { |
6917 | | vl = __riscv_vsetvl_e8m1(n); |
6918 | | vuint8m1_t v = __riscv_vle8_v_u8m1(src, vl); |
6919 | | vbool8_t m1 = __riscv_vmseq(v, '\r', vl); |
6920 | | vbool8_t m2 = __riscv_vmseq(v, '\n', vl); |
6921 | | vbool8_t m3 = __riscv_vmseq(v, '\t', vl); |
6922 | | vbool8_t m = __riscv_vmor(__riscv_vmor(m1, m2, vl), m3, vl); |
6923 | | long idx = __riscv_vfirst(m, vl); |
6924 | | if (idx >= 0) return true; |
6925 | | } |
6926 | | return false; |
6927 | | } |
6928 | | #else |
6929 | | ada_really_inline bool has_tabs_or_newline( |
6930 | | std::string_view user_input) noexcept { |
6931 | | auto has_zero_byte = [](uint64_t v) { |
6932 | | return ((v - 0x0101010101010101) & ~(v) & 0x8080808080808080); |
6933 | | }; |
6934 | | size_t i = 0; |
6935 | | uint64_t mask1 = broadcast('\r'); |
6936 | | uint64_t mask2 = broadcast('\n'); |
6937 | | uint64_t mask3 = broadcast('\t'); |
6938 | | uint64_t running{0}; |
6939 | | for (; i + 7 < user_input.size(); i += 8) { |
6940 | | uint64_t word{}; |
6941 | | memcpy(&word, user_input.data() + i, sizeof(word)); |
6942 | | uint64_t xor1 = word ^ mask1; |
6943 | | uint64_t xor2 = word ^ mask2; |
6944 | | uint64_t xor3 = word ^ mask3; |
6945 | | running |= has_zero_byte(xor1) | has_zero_byte(xor2) | has_zero_byte(xor3); |
6946 | | } |
6947 | | if (i < user_input.size()) { |
6948 | | uint64_t word{}; |
6949 | | memcpy(&word, user_input.data() + i, user_input.size() - i); |
6950 | | uint64_t xor1 = word ^ mask1; |
6951 | | uint64_t xor2 = word ^ mask2; |
6952 | | uint64_t xor3 = word ^ mask3; |
6953 | | running |= has_zero_byte(xor1) | has_zero_byte(xor2) | has_zero_byte(xor3); |
6954 | | } |
6955 | | return running; |
6956 | | } |
6957 | | #endif |
6958 | | |
6959 | | // A forbidden host code point is U+0000 NULL, U+0009 TAB, U+000A LF, U+000D CR, |
6960 | | // U+0020 SPACE, U+0023 (#), U+002F (/), U+003A (:), U+003C (<), U+003E (>), |
6961 | | // U+003F (?), U+0040 (@), U+005B ([), U+005C (\), U+005D (]), U+005E (^), or |
6962 | | // U+007C (|). |
6963 | | constexpr static std::array<uint8_t, 256> is_forbidden_host_code_point_table = |
6964 | | []() consteval { |
6965 | | std::array<uint8_t, 256> result{}; |
6966 | | for (uint8_t c : {'\0', '\x09', '\x0a', '\x0d', ' ', '#', '/', ':', '<', |
6967 | | '>', '?', '@', '[', '\\', ']', '^', '|'}) { |
6968 | | result[c] = true; |
6969 | | } |
6970 | | return result; |
6971 | | }(); |
6972 | | |
6973 | | ada_really_inline constexpr bool is_forbidden_host_code_point( |
6974 | 97.7k | const char c) noexcept { |
6975 | 97.7k | return is_forbidden_host_code_point_table[uint8_t(c)]; |
6976 | 97.7k | } |
6977 | | |
6978 | | constexpr static std::array<uint8_t, 256> is_forbidden_domain_code_point_table = |
6979 | | []() consteval { |
6980 | | std::array<uint8_t, 256> result{}; |
6981 | | for (uint8_t c : {'\0', '\x09', '\x0a', '\x0d', ' ', '#', '/', ':', '<', |
6982 | | '>', '?', '@', '[', '\\', ']', '^', '|', '%'}) { |
6983 | | result[c] = true; |
6984 | | } |
6985 | | for (uint8_t c = 0; c <= 32; c++) { |
6986 | | result[c] = true; |
6987 | | } |
6988 | | for (size_t c = 127; c < 256; c++) { |
6989 | | result[c] = true; |
6990 | | } |
6991 | | return result; |
6992 | | }(); |
6993 | | |
6994 | | static_assert(sizeof(is_forbidden_domain_code_point_table) == 256); |
6995 | | |
6996 | | ada_really_inline constexpr bool is_forbidden_domain_code_point( |
6997 | 673k | const char c) noexcept { |
6998 | 673k | return is_forbidden_domain_code_point_table[uint8_t(c)]; |
6999 | 673k | } |
7000 | | |
7001 | | ada_really_inline constexpr bool contains_forbidden_domain_code_point( |
7002 | 8.70k | const char* input, size_t length) noexcept { |
7003 | 8.70k | size_t i = 0; |
7004 | 8.70k | uint8_t accumulator{}; |
7005 | 178k | for (; i + 4 <= length; i += 4) { |
7006 | 169k | accumulator |= is_forbidden_domain_code_point_table[uint8_t(input[i])]; |
7007 | 169k | accumulator |= is_forbidden_domain_code_point_table[uint8_t(input[i + 1])]; |
7008 | 169k | accumulator |= is_forbidden_domain_code_point_table[uint8_t(input[i + 2])]; |
7009 | 169k | accumulator |= is_forbidden_domain_code_point_table[uint8_t(input[i + 3])]; |
7010 | 169k | } |
7011 | 20.7k | for (; i < length; i++) { |
7012 | 12.0k | accumulator |= is_forbidden_domain_code_point_table[uint8_t(input[i])]; |
7013 | 12.0k | } |
7014 | 8.70k | return accumulator; |
7015 | 8.70k | } |
7016 | | |
7017 | | constexpr static std::array<uint8_t, 256> |
7018 | | is_forbidden_domain_code_point_table_or_upper = []() consteval { |
7019 | | std::array<uint8_t, 256> result{}; |
7020 | | for (uint8_t c : {'\0', '\x09', '\x0a', '\x0d', ' ', '#', '/', ':', '<', |
7021 | | '>', '?', '@', '[', '\\', ']', '^', '|', '%'}) { |
7022 | | result[c] = 1; |
7023 | | } |
7024 | | for (uint8_t c = 'A'; c <= 'Z'; c++) { |
7025 | | result[c] = 2; |
7026 | | } |
7027 | | for (uint8_t c = 0; c <= 32; c++) { |
7028 | | result[c] = 1; |
7029 | | } |
7030 | | for (size_t c = 127; c < 256; c++) { |
7031 | | result[c] = 1; |
7032 | | } |
7033 | | return result; |
7034 | | }(); |
7035 | | |
7036 | | ada_really_inline constexpr uint8_t |
7037 | | contains_forbidden_domain_code_point_or_upper(const char* input, |
7038 | 191k | size_t length) noexcept { |
7039 | 191k | size_t i = 0; |
7040 | 191k | uint8_t accumulator{}; |
7041 | 361k | for (; i + 4 <= length; i += 4) { |
7042 | 169k | accumulator |= |
7043 | 169k | is_forbidden_domain_code_point_table_or_upper[uint8_t(input[i])]; |
7044 | 169k | accumulator |= |
7045 | 169k | is_forbidden_domain_code_point_table_or_upper[uint8_t(input[i + 1])]; |
7046 | 169k | accumulator |= |
7047 | 169k | is_forbidden_domain_code_point_table_or_upper[uint8_t(input[i + 2])]; |
7048 | 169k | accumulator |= |
7049 | 169k | is_forbidden_domain_code_point_table_or_upper[uint8_t(input[i + 3])]; |
7050 | 169k | } |
7051 | 367k | for (; i < length; i++) { |
7052 | 175k | accumulator |= |
7053 | 175k | is_forbidden_domain_code_point_table_or_upper[uint8_t(input[i])]; |
7054 | 175k | } |
7055 | 191k | return accumulator; |
7056 | 191k | } |
7057 | | |
7058 | | // std::isalnum(c) || c == '+' || c == '-' || c == '.') is true for |
7059 | | constexpr static std::array<bool, 256> is_alnum_plus_table = []() consteval { |
7060 | | std::array<bool, 256> result{}; |
7061 | | for (size_t c = 0; c < 256; c++) { |
7062 | | result[c] = (c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') || |
7063 | | (c >= 'A' && c <= 'Z') || c == '+' || c == '-' || c == '.'; |
7064 | | } |
7065 | | return result; |
7066 | | }(); |
7067 | | |
7068 | 906k | ada_really_inline constexpr bool is_alnum_plus(const char c) noexcept { |
7069 | 906k | return is_alnum_plus_table[uint8_t(c)]; |
7070 | | // A table is almost surely much faster than the |
7071 | | // following under most compilers: return |
7072 | | // return (std::isalnum(c) || c == '+' || c == '-' || c == '.'); |
7073 | 906k | } |
7074 | | |
7075 | 8.00k | ada_really_inline constexpr bool is_ascii_hex_digit(const char c) noexcept { |
7076 | 8.00k | return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || |
7077 | 2.03k | (c >= 'a' && c <= 'f'); |
7078 | 8.00k | } |
7079 | | |
7080 | 40.1k | ada_really_inline constexpr bool is_ascii_digit(const char c) noexcept { |
7081 | | // An ASCII digit is a code point in the range U+0030 (0) to U+0039 (9), |
7082 | | // inclusive. |
7083 | 40.1k | return (c >= '0' && c <= '9'); |
7084 | 40.1k | } |
7085 | | |
7086 | 0 | ada_really_inline constexpr bool is_ascii(const char32_t c) noexcept { |
7087 | | // If code point is between U+0000 and U+007F inclusive, then return true. |
7088 | 0 | return c <= 0x7F; |
7089 | 0 | } |
7090 | | |
7091 | 368k | ada_really_inline constexpr bool is_c0_control_or_space(const char c) noexcept { |
7092 | 368k | return (unsigned char)c <= ' '; |
7093 | 368k | } |
7094 | | |
7095 | | ada_really_inline constexpr bool is_ascii_tab_or_newline( |
7096 | 1.07M | const char c) noexcept { |
7097 | 1.07M | return c == '\t' || c == '\n' || c == '\r'; |
7098 | 1.07M | } |
7099 | | |
7100 | | constexpr std::string_view table_is_double_dot_path_segment[] = { |
7101 | | "..", "%2e.", ".%2e", "%2e%2e"}; |
7102 | | |
7103 | | ada_really_inline constexpr bool is_double_dot_path_segment( |
7104 | 21.4k | std::string_view input) noexcept { |
7105 | | // This will catch most cases: |
7106 | | // The length must be 2,4 or 6. |
7107 | | // We divide by two and require |
7108 | | // that the result be between 1 and 3 inclusively. |
7109 | 21.4k | uint64_t half_length = uint64_t(input.size()) / 2; |
7110 | 21.4k | if (half_length - 1 > 2) { |
7111 | 11.5k | return false; |
7112 | 11.5k | } |
7113 | | // We have a string of length 2, 4 or 6. |
7114 | | // We now check the first character: |
7115 | 9.84k | if ((input[0] != '.') && (input[0] != '%')) { |
7116 | 2.98k | return false; |
7117 | 2.98k | } |
7118 | | // We are unlikely the get beyond this point. |
7119 | 6.85k | int hash_value = (input.size() + (unsigned)(input[0])) & 3; |
7120 | 6.85k | const std::string_view target = table_is_double_dot_path_segment[hash_value]; |
7121 | 6.85k | if (target.size() != input.size()) { |
7122 | 1.65k | return false; |
7123 | 1.65k | } |
7124 | | // We almost never get here. |
7125 | | // Optimizing the rest is relatively unimportant. |
7126 | 5.20k | auto prefix_equal_unsafe = [](std::string_view a, std::string_view b) { |
7127 | 5.20k | uint16_t A, B; |
7128 | 5.20k | memcpy(&A, a.data(), sizeof(A)); |
7129 | 5.20k | memcpy(&B, b.data(), sizeof(B)); |
7130 | 5.20k | return A == B; |
7131 | 5.20k | }; |
7132 | 5.20k | if (!prefix_equal_unsafe(input, target)) { |
7133 | 557 | return false; |
7134 | 557 | } |
7135 | 7.70k | for (size_t i = 2; i < input.size(); i++) { |
7136 | 3.83k | char c = input[i]; |
7137 | 3.83k | if ((uint8_t((c | 0x20) - 0x61) <= 25 ? (c | 0x20) : c) != target[i]) { |
7138 | 775 | return false; |
7139 | 775 | } |
7140 | 3.83k | } |
7141 | 3.86k | return true; |
7142 | | // The above code might be a bit better than the code below. Compilers |
7143 | | // are not stupid and may use the fact that these strings have length 2,4 and |
7144 | | // 6 and other tricks. |
7145 | | // return input == ".." || |
7146 | | // input == ".%2e" || input == ".%2E" || |
7147 | | // input == "%2e." || input == "%2E." || |
7148 | | // input == "%2e%2e" || input == "%2E%2E" || input == "%2E%2e" || input == |
7149 | | // "%2e%2E"; |
7150 | 4.64k | } |
7151 | | |
7152 | | ada_really_inline constexpr bool is_single_dot_path_segment( |
7153 | 34.9k | std::string_view input) noexcept { |
7154 | 34.9k | return input == "." || input == "%2e" || input == "%2E"; |
7155 | 34.9k | } |
7156 | | |
7157 | 23.9k | ada_really_inline constexpr bool is_lowercase_hex(const char c) noexcept { |
7158 | 23.9k | return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f'); |
7159 | 23.9k | } |
7160 | | |
7161 | | constexpr static char hex_to_binary_table[] = { |
7162 | | 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, 0, 10, 11, |
7163 | | 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
7164 | | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 11, 12, 13, 14, 15}; |
7165 | 6.78k | unsigned constexpr convert_hex_to_binary(const char c) noexcept { |
7166 | 6.78k | return hex_to_binary_table[c - '0']; |
7167 | 6.78k | } |
7168 | | |
7169 | 691 | std::string percent_decode(const std::string_view input, size_t first_percent) { |
7170 | | // next line is for safety only, we expect users to avoid calling |
7171 | | // percent_decode when first_percent is outside the range. |
7172 | 691 | if (first_percent == std::string_view::npos) { |
7173 | 0 | return std::string(input); |
7174 | 0 | } |
7175 | | |
7176 | | // NOLINTNEXTLINE(bugprone-suspicious-stringview-data-usage) |
7177 | 691 | const char* const src = input.data(); |
7178 | 691 | const char* const end = src + input.size(); |
7179 | | |
7180 | | // Decoding never grows the string, so a single pre-sized buffer written via |
7181 | | // bulk memcpy of the plain runs (then shrunk to the final length) avoids the |
7182 | | // byte-at-a-time appends of the naive version. |
7183 | 691 | std::string out(input.size(), '\0'); |
7184 | 691 | char* d = out.data(); |
7185 | 691 | char* const d0 = d; |
7186 | | |
7187 | 691 | std::memcpy(d, src, first_percent); |
7188 | 691 | d += first_percent; |
7189 | | |
7190 | 691 | const char* p = src + first_percent; |
7191 | 3.99k | while (p < end) { |
7192 | 3.30k | if (*p == '%') { |
7193 | | // Decode runs of valid %XX tightly (common for nested/encoded URLs). |
7194 | 5.31k | while (p + 2 < end && *p == '%') { |
7195 | 4.17k | if (!is_ascii_hex_digit(p[1]) || !is_ascii_hex_digit(p[2])) { |
7196 | 786 | break; |
7197 | 786 | } |
7198 | 3.39k | *d++ = static_cast<char>(convert_hex_to_binary(p[1]) * 16 + |
7199 | 3.39k | convert_hex_to_binary(p[2])); |
7200 | 3.39k | p += 3; |
7201 | 3.39k | } |
7202 | 1.92k | if (p < end && *p == '%') { |
7203 | | // Not a valid escape (too few chars left or bad hex): copy '%' |
7204 | | // literally and keep scanning after it. |
7205 | 944 | *d++ = *p++; |
7206 | 944 | } |
7207 | 1.92k | } else { |
7208 | 1.38k | const char* q = static_cast<const char*>( |
7209 | 1.38k | std::memchr(p, '%', static_cast<size_t>(end - p))); |
7210 | 1.38k | const char* run_end = q ? q : end; |
7211 | 1.38k | const size_t n = static_cast<size_t>(run_end - p); |
7212 | 1.38k | std::memcpy(d, p, n); |
7213 | 1.38k | d += n; |
7214 | 1.38k | p = run_end; |
7215 | 1.38k | } |
7216 | 3.30k | } |
7217 | | |
7218 | 691 | out.resize(static_cast<size_t>(d - d0)); |
7219 | 691 | return out; |
7220 | 691 | } |
7221 | | |
7222 | | // 0..15 for hex digits, 0xFF otherwise - validate and decode with two loads. |
7223 | | constexpr static std::array<uint8_t, 256> unhex_table = []() consteval { |
7224 | | std::array<uint8_t, 256> t{}; |
7225 | | for (size_t i = 0; i < 256; ++i) { |
7226 | | t[i] = 0xFF; |
7227 | | } |
7228 | | for (uint8_t i = 0; i < 10; ++i) { |
7229 | | t[static_cast<size_t>('0') + i] = i; |
7230 | | } |
7231 | | for (uint8_t i = 0; i < 6; ++i) { |
7232 | | t[static_cast<size_t>('A') + i] = static_cast<uint8_t>(10 + i); |
7233 | | t[static_cast<size_t>('a') + i] = static_cast<uint8_t>(10 + i); |
7234 | | } |
7235 | | return t; |
7236 | | }(); |
7237 | | |
7238 | 26.1k | std::string form_urlencoded_decode(const std::string_view input) { |
7239 | 26.1k | const size_t len = input.size(); |
7240 | 26.1k | if (len == 0) [[unlikely]] { |
7241 | 1.95k | return {}; |
7242 | 1.95k | } |
7243 | | |
7244 | | // NOLINTNEXTLINE(bugprone-suspicious-stringview-data-usage) |
7245 | 24.1k | const char* const src = input.data(); |
7246 | 24.1k | const char* const end = src + len; |
7247 | 24.1k | const char* p = src; |
7248 | | |
7249 | | // Advance over the untransformed prefix. |
7250 | 477k | while (p < end && *p != '+' && *p != '%') { |
7251 | 453k | ++p; |
7252 | 453k | } |
7253 | 24.1k | if (p == end) { |
7254 | 22.1k | return std::string(input); |
7255 | 22.1k | } |
7256 | | |
7257 | | // Output is always at most as long as the input: write into a single |
7258 | | // pre-sized buffer, then shrink to the final length. |
7259 | 2.04k | std::string out(len, '\0'); |
7260 | 2.04k | char* d = out.data(); |
7261 | 2.04k | char* const d0 = d; |
7262 | | |
7263 | 2.04k | const size_t prefix = static_cast<size_t>(p - src); |
7264 | 2.04k | std::memcpy(d, src, prefix); |
7265 | 2.04k | d += prefix; |
7266 | | |
7267 | 8.41k | while (p < end) { |
7268 | 6.36k | const char c = *p; |
7269 | 6.36k | if (c == '+') { |
7270 | 1.40k | *d++ = ' '; |
7271 | 1.40k | ++p; |
7272 | 4.95k | } else if (c == '%') { |
7273 | | // Decode runs of valid %XX tightly (common for nested URL query values). |
7274 | 4.77k | while (p + 2 < end && *p == '%') { |
7275 | 3.05k | const uint8_t hi = unhex_table[static_cast<uint8_t>(p[1])]; |
7276 | 3.05k | const uint8_t lo = unhex_table[static_cast<uint8_t>(p[2])]; |
7277 | 3.05k | if ((hi | lo) >= 16) { |
7278 | 1.29k | break; |
7279 | 1.29k | } |
7280 | 1.76k | *d++ = static_cast<char>((hi << 4) | lo); |
7281 | 1.76k | p += 3; |
7282 | 1.76k | } |
7283 | 3.01k | if (p < end && *p == '%') { |
7284 | | // Invalid escape: copy '%' literally and continue. |
7285 | 1.94k | *d++ = *p++; |
7286 | 1.94k | } |
7287 | 3.01k | } else { |
7288 | | // Copy a plain run until the next '+' or '%'. |
7289 | 1.94k | const char* start = p; |
7290 | 1.94k | ++p; |
7291 | 26.6k | while (p < end && *p != '+' && *p != '%') { |
7292 | 24.7k | ++p; |
7293 | 24.7k | } |
7294 | 1.94k | const size_t n = static_cast<size_t>(p - start); |
7295 | 1.94k | std::memcpy(d, start, n); |
7296 | 1.94k | d += n; |
7297 | 1.94k | } |
7298 | 6.36k | } |
7299 | | |
7300 | 2.04k | out.resize(static_cast<size_t>(d - d0)); |
7301 | 2.04k | return out; |
7302 | 24.1k | } |
7303 | | |
7304 | | std::string percent_encode(const std::string_view input, |
7305 | 174k | const uint8_t character_set[]) { |
7306 | 833k | auto pointer = std::ranges::find_if(input, [character_set](const char c) { |
7307 | 833k | return character_sets::bit_at(character_set, c); |
7308 | 833k | }); |
7309 | | // Optimization: Don't iterate if percent encode is not required |
7310 | 174k | if (pointer == input.end()) { |
7311 | 151k | return std::string(input); |
7312 | 151k | } |
7313 | | |
7314 | 23.3k | std::string result; |
7315 | 23.3k | result.reserve(input.length()); // in the worst case, percent encoding might |
7316 | | // produce 3 characters. |
7317 | 23.3k | result.append(input.substr(0, std::distance(input.begin(), pointer))); |
7318 | | |
7319 | 586k | for (; pointer != input.end(); pointer++) { |
7320 | 563k | if (character_sets::bit_at(character_set, *pointer)) { |
7321 | 334k | result.append(character_sets::hex + uint8_t(*pointer) * 4, 3); |
7322 | 334k | } else { |
7323 | 228k | result += *pointer; |
7324 | 228k | } |
7325 | 563k | } |
7326 | | |
7327 | 23.3k | return result; |
7328 | 174k | } |
7329 | | |
7330 | | template <bool append> |
7331 | | bool percent_encode(const std::string_view input, const uint8_t character_set[], |
7332 | 143k | std::string& out) { |
7333 | 143k | ada_log("percent_encode ", input, " to output string while ", |
7334 | 143k | append ? "appending" : "overwriting"); |
7335 | 319k | auto pointer = std::ranges::find_if(input, [character_set](const char c) { |
7336 | 319k | return character_sets::bit_at(character_set, c); |
7337 | 319k | }); ada::unicode::percent_encode<false>(std::__1::basic_string_view<char, std::__1::char_traits<char> >, unsigned char const*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&)::{lambda(char)#1}::operator()(char) constLine | Count | Source | 7335 | 27.3k | auto pointer = std::ranges::find_if(input, [character_set](const char c) { | 7336 | 27.3k | return character_sets::bit_at(character_set, c); | 7337 | 27.3k | }); |
ada::unicode::percent_encode<true>(std::__1::basic_string_view<char, std::__1::char_traits<char> >, unsigned char const*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&)::{lambda(char)#1}::operator()(char) constLine | Count | Source | 7335 | 291k | auto pointer = std::ranges::find_if(input, [character_set](const char c) { | 7336 | 291k | return character_sets::bit_at(character_set, c); | 7337 | 291k | }); |
|
7338 | 143k | ada_log("percent_encode done checking, moved to ", |
7339 | 143k | std::distance(input.begin(), pointer)); |
7340 | | |
7341 | | // Optimization: Don't iterate if percent encode is not required |
7342 | 143k | if (pointer == input.end()) { |
7343 | 136k | ada_log("percent_encode encoding not needed."); |
7344 | 136k | return false; |
7345 | 136k | } |
7346 | 6.82k | if constexpr (!append) { |
7347 | 4.35k | out.clear(); |
7348 | 4.35k | } |
7349 | 6.82k | ada_log("percent_encode appending ", std::distance(input.begin(), pointer), |
7350 | 6.82k | " bytes"); |
7351 | | // NOLINTNEXTLINE(bugprone-suspicious-stringview-data-usage) |
7352 | 6.82k | out.append(input.data(), std::distance(input.begin(), pointer)); |
7353 | 6.82k | ada_log("percent_encode processing ", std::distance(pointer, input.end()), |
7354 | 6.82k | " bytes"); |
7355 | 258k | for (; pointer != input.end(); pointer++) { |
7356 | 251k | if (character_sets::bit_at(character_set, *pointer)) { |
7357 | 199k | out.append(character_sets::hex + uint8_t(*pointer) * 4, 3); |
7358 | 199k | } else { |
7359 | 52.2k | out += *pointer; |
7360 | 52.2k | } |
7361 | 251k | } |
7362 | 6.82k | return true; |
7363 | 143k | } bool ada::unicode::percent_encode<false>(std::__1::basic_string_view<char, std::__1::char_traits<char> >, unsigned char const*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&) Line | Count | Source | 7332 | 10.5k | std::string& out) { | 7333 | 10.5k | ada_log("percent_encode ", input, " to output string while ", | 7334 | 10.5k | append ? "appending" : "overwriting"); | 7335 | 10.5k | auto pointer = std::ranges::find_if(input, [character_set](const char c) { | 7336 | 10.5k | return character_sets::bit_at(character_set, c); | 7337 | 10.5k | }); | 7338 | 10.5k | ada_log("percent_encode done checking, moved to ", | 7339 | 10.5k | std::distance(input.begin(), pointer)); | 7340 | | | 7341 | | // Optimization: Don't iterate if percent encode is not required | 7342 | 10.5k | if (pointer == input.end()) { | 7343 | 6.19k | ada_log("percent_encode encoding not needed."); | 7344 | 6.19k | return false; | 7345 | 6.19k | } | 7346 | 4.35k | if constexpr (!append) { | 7347 | 4.35k | out.clear(); | 7348 | 4.35k | } | 7349 | 4.35k | ada_log("percent_encode appending ", std::distance(input.begin(), pointer), | 7350 | 4.35k | " bytes"); | 7351 | | // NOLINTNEXTLINE(bugprone-suspicious-stringview-data-usage) | 7352 | 4.35k | out.append(input.data(), std::distance(input.begin(), pointer)); | 7353 | 4.35k | ada_log("percent_encode processing ", std::distance(pointer, input.end()), | 7354 | 4.35k | " bytes"); | 7355 | 113k | for (; pointer != input.end(); pointer++) { | 7356 | 108k | if (character_sets::bit_at(character_set, *pointer)) { | 7357 | 91.3k | out.append(character_sets::hex + uint8_t(*pointer) * 4, 3); | 7358 | 91.3k | } else { | 7359 | 17.6k | out += *pointer; | 7360 | 17.6k | } | 7361 | 108k | } | 7362 | 4.35k | return true; | 7363 | 10.5k | } |
bool ada::unicode::percent_encode<true>(std::__1::basic_string_view<char, std::__1::char_traits<char> >, unsigned char const*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&) Line | Count | Source | 7332 | 132k | std::string& out) { | 7333 | 132k | ada_log("percent_encode ", input, " to output string while ", | 7334 | 132k | append ? "appending" : "overwriting"); | 7335 | 132k | auto pointer = std::ranges::find_if(input, [character_set](const char c) { | 7336 | 132k | return character_sets::bit_at(character_set, c); | 7337 | 132k | }); | 7338 | 132k | ada_log("percent_encode done checking, moved to ", | 7339 | 132k | std::distance(input.begin(), pointer)); | 7340 | | | 7341 | | // Optimization: Don't iterate if percent encode is not required | 7342 | 132k | if (pointer == input.end()) { | 7343 | 130k | ada_log("percent_encode encoding not needed."); | 7344 | 130k | return false; | 7345 | 130k | } | 7346 | | if constexpr (!append) { | 7347 | | out.clear(); | 7348 | | } | 7349 | 2.47k | ada_log("percent_encode appending ", std::distance(input.begin(), pointer), | 7350 | 2.47k | " bytes"); | 7351 | | // NOLINTNEXTLINE(bugprone-suspicious-stringview-data-usage) | 7352 | 2.47k | out.append(input.data(), std::distance(input.begin(), pointer)); | 7353 | 2.47k | ada_log("percent_encode processing ", std::distance(pointer, input.end()), | 7354 | 2.47k | " bytes"); | 7355 | 145k | for (; pointer != input.end(); pointer++) { | 7356 | 142k | if (character_sets::bit_at(character_set, *pointer)) { | 7357 | 108k | out.append(character_sets::hex + uint8_t(*pointer) * 4, 3); | 7358 | 108k | } else { | 7359 | 34.5k | out += *pointer; | 7360 | 34.5k | } | 7361 | 142k | } | 7362 | 2.47k | return true; | 7363 | 132k | } |
|
7364 | | |
7365 | | bool to_ascii(std::optional<std::string>& out, const std::string_view plain, |
7366 | 10.7k | size_t first_percent) { |
7367 | 10.7k | std::string percent_decoded_buffer; |
7368 | 10.7k | std::string_view input = plain; |
7369 | 10.7k | if (first_percent != std::string_view::npos) { |
7370 | 691 | percent_decoded_buffer = unicode::percent_decode(plain, first_percent); |
7371 | 691 | input = percent_decoded_buffer; |
7372 | 691 | } |
7373 | | // input is a non-empty UTF-8 string, must be percent decoded |
7374 | 10.7k | std::string idna_ascii = ada::idna::to_ascii(input); |
7375 | 10.7k | if (idna_ascii.empty() || contains_forbidden_domain_code_point( |
7376 | 8.70k | idna_ascii.data(), idna_ascii.size())) { |
7377 | 3.54k | return false; |
7378 | 3.54k | } |
7379 | 7.16k | out = std::move(idna_ascii); |
7380 | 7.16k | return true; |
7381 | 10.7k | } |
7382 | | |
7383 | | std::string percent_encode(const std::string_view input, |
7384 | 5.74k | const uint8_t character_set[], size_t index) { |
7385 | 5.74k | std::string out; |
7386 | | // NOLINTNEXTLINE(bugprone-suspicious-stringview-data-usage) |
7387 | 5.74k | out.append(input.data(), index); |
7388 | 5.74k | auto pointer = input.begin() + index; |
7389 | 211k | for (; pointer != input.end(); pointer++) { |
7390 | 205k | if (character_sets::bit_at(character_set, *pointer)) { |
7391 | 145k | out.append(character_sets::hex + uint8_t(*pointer) * 4, 3); |
7392 | 145k | } else { |
7393 | 60.4k | out += *pointer; |
7394 | 60.4k | } |
7395 | 205k | } |
7396 | 5.74k | return out; |
7397 | 5.74k | } |
7398 | | |
7399 | | } // namespace ada::unicode |
7400 | | /* end file src/unicode.cpp */ |
7401 | | /* begin file src/serializers.cpp */ |
7402 | | |
7403 | | #include <array> |
7404 | | #include <cstdint> |
7405 | | #include <cstring> |
7406 | | #include <string> |
7407 | | |
7408 | | namespace ada::serializers { |
7409 | | namespace { |
7410 | | |
7411 | | // Digit pair LUT for fast decimal write: index 0..99 -> two chars. |
7412 | 0 | constexpr std::array<char, 200> make_digit_pairs() noexcept { |
7413 | 0 | std::array<char, 200> t{}; |
7414 | 0 | for (size_t i = 0; i < 100; ++i) { |
7415 | 0 | t[i * 2] = static_cast<char>('0' + i / 10); |
7416 | 0 | t[i * 2 + 1] = static_cast<char>('0' + i % 10); |
7417 | 0 | } |
7418 | 0 | return t; |
7419 | 0 | } |
7420 | | |
7421 | | constexpr auto digit_pairs = make_digit_pairs(); |
7422 | | |
7423 | 12.1k | ada_really_inline char* write_u8(char* p, uint8_t v) noexcept { |
7424 | 12.1k | if (v < 10) { |
7425 | 8.34k | *p++ = static_cast<char>('0' + v); |
7426 | 8.34k | } else if (v < 100) { |
7427 | 809 | std::memcpy(p, &digit_pairs[static_cast<size_t>(v) * 2], 2); |
7428 | 809 | p += 2; |
7429 | 3.03k | } else { |
7430 | 3.03k | *p++ = static_cast<char>('0' + v / 100); |
7431 | 3.03k | std::memcpy(p, &digit_pairs[static_cast<size_t>(v % 100) * 2], 2); |
7432 | 3.03k | p += 2; |
7433 | 3.03k | } |
7434 | 12.1k | return p; |
7435 | 12.1k | } |
7436 | | |
7437 | 3.18k | ada_really_inline char* write_hex_u16(char* p, uint16_t v) noexcept { |
7438 | 3.18k | static constexpr char kHex[] = "0123456789abcdef"; |
7439 | 3.18k | if (v >= 0x1000) { |
7440 | 189 | *p++ = kHex[(v >> 12) & 0xf]; |
7441 | 189 | *p++ = kHex[(v >> 8) & 0xf]; |
7442 | 189 | *p++ = kHex[(v >> 4) & 0xf]; |
7443 | 189 | *p++ = kHex[v & 0xf]; |
7444 | 2.99k | } else if (v >= 0x100) { |
7445 | 278 | *p++ = kHex[(v >> 8) & 0xf]; |
7446 | 278 | *p++ = kHex[(v >> 4) & 0xf]; |
7447 | 278 | *p++ = kHex[v & 0xf]; |
7448 | 2.71k | } else if (v >= 0x10) { |
7449 | 475 | *p++ = kHex[(v >> 4) & 0xf]; |
7450 | 475 | *p++ = kHex[v & 0xf]; |
7451 | 2.24k | } else { |
7452 | 2.24k | *p++ = kHex[v & 0xf]; |
7453 | 2.24k | } |
7454 | 3.18k | return p; |
7455 | 3.18k | } |
7456 | | |
7457 | | } // namespace |
7458 | | |
7459 | | void find_longest_sequence_of_ipv6_pieces( |
7460 | | const std::array<uint16_t, 8>& address, size_t& compress, |
7461 | 1.56k | size_t& compress_length) noexcept { |
7462 | 1.56k | compress = 0; |
7463 | 1.56k | compress_length = 0; |
7464 | 1.56k | size_t i = 0; |
7465 | 6.21k | while (i < 8) { |
7466 | 4.65k | if (address[i] != 0) { |
7467 | 2.94k | ++i; |
7468 | 2.94k | continue; |
7469 | 2.94k | } |
7470 | 1.70k | size_t next = i + 1; |
7471 | 9.56k | while (next < 8 && address[next] == 0) { |
7472 | 7.85k | ++next; |
7473 | 7.85k | } |
7474 | 1.70k | const size_t count = next - i; |
7475 | 1.70k | if (count > compress_length) { |
7476 | 1.57k | compress_length = count; |
7477 | 1.57k | compress = i; |
7478 | 1.57k | } |
7479 | 1.70k | i = next; |
7480 | 1.70k | } |
7481 | 1.56k | } |
7482 | | |
7483 | 1.56k | std::string ipv6(const std::array<uint16_t, 8>& address) { |
7484 | 1.56k | size_t compress = 0; |
7485 | 1.56k | size_t compress_length = 0; |
7486 | 1.56k | find_longest_sequence_of_ipv6_pieces(address, compress, compress_length); |
7487 | | |
7488 | | // Skip compression when the longest zero run is a single piece. |
7489 | 1.56k | if (compress_length <= 1) { |
7490 | 96 | compress = compress_length = 8; |
7491 | 96 | } |
7492 | | |
7493 | | // Max: '[' + 8*4 hex + 7 ':' + ']' = 41 |
7494 | 1.56k | std::string output(4 * 8 + 7 + 2, '\0'); |
7495 | 1.56k | char* point = output.data(); |
7496 | 1.56k | *point++ = '['; |
7497 | 1.56k | size_t piece_index = 0; |
7498 | 3.28k | while (true) { |
7499 | 3.28k | if (piece_index == compress) { |
7500 | 1.46k | *point++ = ':'; |
7501 | | // If we skip a value initially, we need to write '::'. |
7502 | 1.46k | if (piece_index == 0) { |
7503 | 1.32k | *point++ = ':'; |
7504 | 1.32k | } |
7505 | 1.46k | piece_index += compress_length; |
7506 | 1.46k | if (piece_index == 8) { |
7507 | 103 | break; |
7508 | 103 | } |
7509 | 1.46k | } |
7510 | 3.18k | point = write_hex_u16(point, address[piece_index]); |
7511 | 3.18k | ++piece_index; |
7512 | 3.18k | if (piece_index == 8) { |
7513 | 1.46k | break; |
7514 | 1.46k | } |
7515 | 1.72k | *point++ = ':'; |
7516 | 1.72k | } |
7517 | 1.56k | *point++ = ']'; |
7518 | 1.56k | output.resize(static_cast<size_t>(point - output.data())); |
7519 | 1.56k | return output; |
7520 | 1.56k | } |
7521 | | |
7522 | 3.04k | std::string ipv4(const uint64_t address) { |
7523 | 3.04k | std::string output(15, '\0'); |
7524 | 3.04k | char* point = output.data(); |
7525 | 3.04k | point = write_u8(point, static_cast<uint8_t>(address >> 24)); |
7526 | 3.04k | *point++ = '.'; |
7527 | 3.04k | point = write_u8(point, static_cast<uint8_t>(address >> 16)); |
7528 | 3.04k | *point++ = '.'; |
7529 | 3.04k | point = write_u8(point, static_cast<uint8_t>(address >> 8)); |
7530 | 3.04k | *point++ = '.'; |
7531 | 3.04k | point = write_u8(point, static_cast<uint8_t>(address)); |
7532 | 3.04k | output.resize(static_cast<size_t>(point - output.data())); |
7533 | 3.04k | return output; |
7534 | 3.04k | } |
7535 | | |
7536 | | } // namespace ada::serializers |
7537 | | /* end file src/serializers.cpp */ |
7538 | | /* begin file src/implementation.cpp */ |
7539 | | |
7540 | | #include <array> |
7541 | | #include <atomic> |
7542 | | #include <limits> |
7543 | | #include <optional> |
7544 | | #include <string_view> |
7545 | | |
7546 | | |
7547 | | namespace ada { |
7548 | | |
7549 | | static std::atomic<uint32_t> max_input_length_{ |
7550 | | std::numeric_limits<uint32_t>::max()}; |
7551 | | |
7552 | 0 | void set_max_input_length(uint32_t length) { |
7553 | 0 | max_input_length_.store(length, std::memory_order_relaxed); |
7554 | 0 | } |
7555 | | |
7556 | 701k | uint32_t get_max_input_length() { |
7557 | 701k | return max_input_length_.load(std::memory_order_relaxed); |
7558 | 701k | } |
7559 | | |
7560 | | namespace { |
7561 | | |
7562 | | constexpr std::array<uint8_t, 256> clean_http_host_byte = []() consteval { |
7563 | | std::array<uint8_t, 256> result{}; |
7564 | | for (size_t i = 0; i < result.size(); ++i) { |
7565 | | const auto c = static_cast<uint8_t>(i); |
7566 | | result[i] = |
7567 | | static_cast<uint8_t>((c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || |
7568 | | c == '-' || c == '.' || c == '_' || c == '~'); |
7569 | | } |
7570 | | return result; |
7571 | | }(); |
7572 | | |
7573 | | ada_really_inline bool eight_clean_http_host_bytes( |
7574 | 34.8k | const uint8_t* input) noexcept { |
7575 | 34.8k | return clean_http_host_byte[input[0]] & clean_http_host_byte[input[1]] & |
7576 | 34.8k | clean_http_host_byte[input[2]] & clean_http_host_byte[input[3]] & |
7577 | 34.8k | clean_http_host_byte[input[4]] & clean_http_host_byte[input[5]] & |
7578 | 34.8k | clean_http_host_byte[input[6]] & clean_http_host_byte[input[7]]; |
7579 | 34.8k | } |
7580 | | |
7581 | | // Minimal front end for the overwhelmingly common already-canonical HTTP(S) |
7582 | | // case. It deliberately handles fewer inputs than |
7583 | | // try_can_parse_absolute_fast: anything requiring normalization or detailed |
7584 | | // host parsing falls through to that broader validator. |
7585 | 55.0k | std::optional<bool> try_can_parse_clean_http(std::string_view input) noexcept { |
7586 | 55.0k | const auto* bytes = reinterpret_cast<const uint8_t*>(input.data()); |
7587 | 55.0k | const size_t length = input.size(); |
7588 | | |
7589 | 55.0k | size_t authority_start; |
7590 | 55.0k | if (length >= 8 && input.starts_with("https://")) { |
7591 | 22.4k | authority_start = 8; |
7592 | 32.6k | } else if (length >= 7 && input.starts_with("http://")) { |
7593 | 11.5k | authority_start = 7; |
7594 | 21.0k | } else { |
7595 | 21.0k | return std::nullopt; |
7596 | 21.0k | } |
7597 | | |
7598 | 34.0k | if (authority_start >= length) { |
7599 | 2 | return false; |
7600 | 2 | } |
7601 | | |
7602 | 34.0k | size_t cursor = authority_start; |
7603 | 57.2k | while (cursor + 8 <= length && eight_clean_http_host_bytes(bytes + cursor)) { |
7604 | 23.1k | cursor += 8; |
7605 | 23.1k | } |
7606 | 124k | while (cursor < length) { |
7607 | 124k | const uint8_t c = bytes[cursor]; |
7608 | 124k | if (c == '/' || c == '?' || c == '#') { |
7609 | 22.5k | break; |
7610 | 22.5k | } |
7611 | 102k | if (!clean_http_host_byte[c]) { |
7612 | 11.3k | return std::nullopt; |
7613 | 11.3k | } |
7614 | 90.8k | ++cursor; |
7615 | 90.8k | } |
7616 | | |
7617 | 22.6k | const size_t host_length = cursor - authority_start; |
7618 | 22.6k | if (host_length == 0) { |
7619 | | // Extra special-scheme slashes are normalization, not an empty host. |
7620 | 4 | if (bytes[authority_start] == '/' || bytes[authority_start] == '\\') { |
7621 | 3 | return std::nullopt; |
7622 | 3 | } |
7623 | 1 | return false; |
7624 | 4 | } |
7625 | 22.6k | if (host_length > 253 || bytes[cursor - 1] == '.') { |
7626 | 13 | return std::nullopt; |
7627 | 13 | } |
7628 | | |
7629 | 22.6k | const std::string_view host(input.data() + authority_start, host_length); |
7630 | 22.6k | if (checkers::is_ipv4(host) || host.find("xn-") != std::string_view::npos) { |
7631 | 11.2k | return std::nullopt; |
7632 | 11.2k | } |
7633 | | |
7634 | | // Once a special URL has a valid host, path/query/fragment bytes cannot make |
7635 | | // it structurally invalid: the full parser percent-encodes them as needed. |
7636 | 11.3k | return true; |
7637 | 22.6k | } |
7638 | | |
7639 | | // @private |
7640 | | // Fast-path validator for can_parse. |
7641 | | // |
7642 | | // Validates absolute special (non-file) URLs without constructing any |
7643 | | // url_aggregator object and without running the state machine. |
7644 | | // Performs a single forward scan over the input bytes. |
7645 | | // |
7646 | | // Returns: |
7647 | | // true -- URL is structurally valid |
7648 | | // false -- URL is definitely invalid |
7649 | | // nullopt -- edge case; fall through to the full parser |
7650 | | // (credentials, IDNA, IPv4/6, tabs/newlines, relative URLs, ...) |
7651 | | std::optional<bool> try_can_parse_absolute_fast( |
7652 | 43.6k | std::string_view input) noexcept { |
7653 | 43.6k | const uint8_t* b = reinterpret_cast<const uint8_t*>(input.data()); |
7654 | 43.6k | size_t len = input.size(); |
7655 | | |
7656 | | // -- Inline C0 whitespace trim (no allocation) -------------------------- |
7657 | | // Note: \t (0x09), \n (0x0a), \r (0x0d) are all <= 0x20, so any |
7658 | | // leading/trailing tabs or newlines are correctly stripped here, matching |
7659 | | // the WHATWG spec's "remove leading/trailing C0 control and space" step. |
7660 | 46.1k | while (len > 0 && b[0] <= 0x20) { |
7661 | 2.53k | b++; |
7662 | 2.53k | len--; |
7663 | 2.53k | } |
7664 | 45.9k | while (len > 0 && b[len - 1] <= 0x20) { |
7665 | 2.24k | len--; |
7666 | 2.24k | } |
7667 | 43.6k | if (len == 0) return false; |
7668 | | |
7669 | | // -- Scheme detection ----------------------------------------------------- |
7670 | | // Fast path for HTTP and HTTPS (covers ~90%+ of real-world URLs). |
7671 | | // Avoids the general scheme loop, buffer copy, and perfect hash lookup. |
7672 | | // We know HTTP and HTTPS are special non-file schemes, so no further |
7673 | | // scheme_type checks are needed on the fast path -- only `pos` matters. |
7674 | 43.3k | size_t pos; |
7675 | | |
7676 | 43.3k | if (len >= 7 && (b[0] | 0x20) == 'h' && (b[1] | 0x20) == 't' && |
7677 | 23.4k | (b[2] | 0x20) == 't' && (b[3] | 0x20) == 'p') { |
7678 | 23.4k | if (b[4] == ':' && b[5] == '/' && b[6] == '/') { |
7679 | 11.5k | pos = 7; |
7680 | 11.5k | goto skip_extra_slashes; |
7681 | 11.5k | } |
7682 | 11.8k | if (len >= 8 && (b[4] | 0x20) == 's' && b[5] == ':' && b[6] == '/' && |
7683 | 11.3k | b[7] == '/') { |
7684 | 11.2k | pos = 8; |
7685 | 11.2k | goto skip_extra_slashes; |
7686 | 11.2k | } |
7687 | | // Fall through: could be "httpe://", tabs in scheme, etc. |
7688 | 11.8k | } |
7689 | | |
7690 | 20.5k | { |
7691 | | // General scheme detection for ws, wss, ftp, and edge cases. |
7692 | 20.5k | if (!checkers::is_alpha(static_cast<char>(b[0]))) return false; |
7693 | | |
7694 | | // Scan for ':' within the first 7 bytes. All special schemes are <= 5 |
7695 | | // chars ("https"), so any URL whose first ':' is beyond byte 6 is either |
7696 | | // non-special or relative -- both require the full parser. |
7697 | 18.6k | size_t colon_pos = 0; |
7698 | 66.8k | for (size_t i = 1;; ++i) { |
7699 | 66.8k | if (i >= 7 || i >= len) return std::nullopt; |
7700 | 66.0k | const char c = static_cast<char>(b[i]); |
7701 | 66.0k | if (c == ':') { |
7702 | 17.2k | colon_pos = i; |
7703 | 17.2k | break; |
7704 | 17.2k | } |
7705 | | // Tabs/newlines in the scheme require the full parser to strip them. |
7706 | 48.7k | if (c == '\t' || c == '\n' || c == '\r') return std::nullopt; |
7707 | 48.7k | if (!unicode::is_alnum_plus(c)) return false; |
7708 | 48.7k | } |
7709 | | |
7710 | | // Lowercase scheme bytes inline and classify via the existing perfect |
7711 | | // hash. |
7712 | 17.2k | char scheme_buf[6]; |
7713 | 17.2k | scheme_buf[0] = static_cast<char>(b[0] | 0x20); |
7714 | 60.9k | for (size_t i = 1; i < colon_pos; ++i) |
7715 | 43.6k | scheme_buf[i] = static_cast<char>(b[i] | 0x20); |
7716 | | |
7717 | 17.2k | const ada::scheme::type scheme_type = |
7718 | 17.2k | ada::scheme::get_scheme_type({scheme_buf, colon_pos}); |
7719 | | |
7720 | | // Only handle special, non-file schemes. |
7721 | 17.2k | if (scheme_type == ada::scheme::NOT_SPECIAL) return std::nullopt; |
7722 | 15.9k | if (scheme_type == ada::scheme::FILE) return std::nullopt; |
7723 | | |
7724 | | // Per WHATWG, special URLs don't require "//": "http:example.com" is valid |
7725 | | // (SPECIAL_AUTHORITY_IGNORE_SLASHES just skips leading slashes and |
7726 | | // proceeds to AUTHORITY). Defer to the inline fallback for any input |
7727 | | // without "://". |
7728 | 3.78k | pos = colon_pos + 1; |
7729 | 3.78k | if (pos + 2 > len || b[pos] != '/' || b[pos + 1] != '/') { |
7730 | 2.71k | return std::nullopt; |
7731 | 2.71k | } |
7732 | 1.07k | pos += 2; |
7733 | 1.07k | } |
7734 | | |
7735 | 23.8k | skip_extra_slashes: |
7736 | | // SPECIAL_AUTHORITY_IGNORE_SLASHES: the full parser skips any additional |
7737 | | // leading '/' or '\' after the initial "//". Mirror that here so we don't |
7738 | | // mis-identify the host as empty when there are extra slashes. |
7739 | 24.7k | while (pos < len && (b[pos] == '/' || b[pos] == '\\')) { |
7740 | 907 | ++pos; |
7741 | 907 | } |
7742 | | |
7743 | | // Early IPv6 bail-out: if the authority starts with '[', it's an IPv6 |
7744 | | // literal which requires the full parser. Checking here avoids scanning |
7745 | | // the entire bracketed address only to bail out afterward. |
7746 | 23.8k | if (pos < len && b[pos] == '[') return std::nullopt; |
7747 | | |
7748 | | // -- Merged authority + host scan ------------------------------------------ |
7749 | | // A single forward pass over the authority bytes that simultaneously: |
7750 | | // - finds the authority end and port colon |
7751 | | // - validates host characters (forbidden domain code points) |
7752 | | // - tracks IPv4 indicators (all-decimal-dots, last non-dot char) |
7753 | | // - detects xn-- prefixes (IDNA punycode) |
7754 | | // - detects tabs/newlines (which require the full parser to strip) |
7755 | | // This replaces 4 separate scans over the host bytes. |
7756 | 23.7k | const size_t auth_start = pos; |
7757 | 23.7k | size_t auth_end = pos; |
7758 | 23.7k | size_t port_colon = SIZE_MAX; |
7759 | 23.7k | bool all_dec_dots = true; |
7760 | 23.7k | uint8_t last_non_dot = 0; |
7761 | | |
7762 | 245k | for (; auth_end < len; ++auth_end) { |
7763 | 245k | const uint8_t c = b[auth_end]; |
7764 | | |
7765 | | // Non-ASCII -> needs IDNA processing -> full parser. |
7766 | 245k | if (c >= 0x80) return std::nullopt; |
7767 | | |
7768 | | // Authority delimiters. |
7769 | 245k | if (c == '/' || c == '?' || c == '#' || c == '\\') break; |
7770 | | |
7771 | | // Port separator. |
7772 | 233k | if (c == ':') { |
7773 | 11.6k | if (port_colon == SIZE_MAX) port_colon = auth_end; |
7774 | 11.6k | continue; |
7775 | 11.6k | } |
7776 | | |
7777 | | // Credentials or percent-encoding -> full parser. |
7778 | 221k | if (c == '@' || c == '%') return std::nullopt; |
7779 | | |
7780 | | // Tabs/newlines anywhere in the authority require the full parser to |
7781 | | // strip them before validation. Without this, a tab in the port (e.g. |
7782 | | // "http://host:8\t0/") would be mis-rejected by port validation. |
7783 | 210k | if (c == '\t' || c == '\n' || c == '\r') return std::nullopt; |
7784 | | |
7785 | | // Skip remaining host-specific checks for port bytes. Port digits are |
7786 | | // validated separately below, and no forbidden-domain-code-point check |
7787 | | // is needed on port characters. |
7788 | 210k | if (port_colon != SIZE_MAX) continue; |
7789 | | |
7790 | | // -- Host byte validation (inlined) ------------------------------------ |
7791 | | // Forbidden domain code points that are not already caught above: |
7792 | | // C0 controls and space (0x00-0x20), DEL (0x7F), <, >, [, ], ^, |. |
7793 | | // At this stage, the input may still be userinfo or be normalized later |
7794 | | // (e.g., percent-encoded), so we do not reject here and defer to the |
7795 | | // parser. Characters already caught: >= 0x80 (non-ASCII), '/' '?' '#' '\\' |
7796 | | // (delimiters), ':' (port), '@' '%' (bail), '\t' '\n' '\r' (bail). |
7797 | 164k | if (c <= 0x20 || c == 0x7F || c == '<' || c == '>' || c == '[' || |
7798 | 164k | c == ']' || c == '^' || c == '|') { |
7799 | 41 | return std::nullopt; |
7800 | 41 | } |
7801 | | |
7802 | | // Track whether host is all decimal digits and dots (potential IPv4). |
7803 | 164k | if (c != '.' && (c < '0' || c > '9')) all_dec_dots = false; |
7804 | | |
7805 | | // Track last non-dot character for the IPv4 hex/octal heuristic. |
7806 | 164k | if (c != '.') last_non_dot = c; |
7807 | | |
7808 | | // Detect xn-- prefix inline (IDNA punycode -> needs full parser). |
7809 | | // Checking at every position mirrors the original behavior: any |
7810 | | // occurrence of "xn--" in the host (not just at label boundaries) |
7811 | | // triggers a bail-out to the full IDNA validator. |
7812 | 164k | if ((c | 0x20) == 'x' && auth_end + 4 <= len && |
7813 | 1.89k | (b[auth_end + 1] | 0x20) == 'n' && b[auth_end + 2] == '-' && |
7814 | 242 | b[auth_end + 3] == '-') { |
7815 | 159 | return std::nullopt; |
7816 | 159 | } |
7817 | 164k | } |
7818 | | |
7819 | 12.2k | const size_t host_end = (port_colon != SIZE_MAX) ? port_colon : auth_end; |
7820 | | |
7821 | | // Empty host is invalid for special URLs. |
7822 | 12.2k | if (auth_start == host_end) return false; |
7823 | | |
7824 | | // -- IPv4 handling --------------------------------------------------------- |
7825 | 12.2k | const char* host_ptr = reinterpret_cast<const char*>(b + auth_start); |
7826 | 12.2k | const size_t host_len = host_end - auth_start; |
7827 | | |
7828 | 12.2k | if (all_dec_dots) { |
7829 | | // Host is all decimal digits and dots -> try the fast IPv4 parser. |
7830 | 11.3k | if (checkers::try_parse_ipv4_fast({host_ptr, host_len}) != |
7831 | 11.3k | checkers::ipv4_fast_fail) { |
7832 | | // Valid decimal IPv4 host. Do NOT return true yet: the port still |
7833 | | // needs to be validated below before we can declare the URL valid. |
7834 | 11.2k | goto validate_port; |
7835 | 11.2k | } |
7836 | | // Fast IPv4 parsing failed (e.g. host is ".", "..", "1.2.3.500"). |
7837 | | // Such hosts may still be valid domain names; defer to the full parser. |
7838 | 106 | return std::nullopt; |
7839 | 11.3k | } |
7840 | | |
7841 | | // Last-significant-character heuristic for non-decimal IPv4 (hex/octal): |
7842 | | // if the last non-dot char is a digit, 'a'-'f', or 'x' the host might be |
7843 | | // an IPv4 address that the fast path can't validate -- fall through. |
7844 | | // last_non_dot was tracked during the authority scan above. |
7845 | 836 | { |
7846 | 836 | const uint8_t lc = last_non_dot | 0x20; |
7847 | 836 | if ((last_non_dot >= '0' && last_non_dot <= '9') || |
7848 | 630 | (lc >= 'a' && lc <= 'f') || lc == 'x') { |
7849 | 341 | return std::nullopt; |
7850 | 341 | } |
7851 | 836 | } |
7852 | | |
7853 | | // -- Port validation ------------------------------------------------------- |
7854 | 11.7k | validate_port: |
7855 | 11.7k | if (port_colon != SIZE_MAX) { |
7856 | 211 | const uint8_t* pp = b + port_colon + 1; |
7857 | 211 | size_t pl = auth_end - port_colon - 1; |
7858 | 211 | if (pl > 0) { |
7859 | | // Strip leading zeros: "0000001" == 1, "0000000000000" == 0, both valid. |
7860 | | // Only the significant digits count toward the 5-digit maximum. |
7861 | 417 | while (pl > 0 && *pp == '0') { |
7862 | 221 | ++pp; |
7863 | 221 | --pl; |
7864 | 221 | } |
7865 | 196 | if (pl > 5) return false; // significant digits > 99999 |
7866 | 187 | uint32_t pv = 0; |
7867 | 876 | for (size_t i = 0; i < pl; ++i) { |
7868 | 698 | if (pp[i] < '0' || pp[i] > '9') return false; |
7869 | 689 | pv = pv * 10 + (pp[i] - '0'); |
7870 | 689 | } |
7871 | 178 | if (pv > 65535) return false; |
7872 | 178 | } |
7873 | 211 | } |
7874 | | |
7875 | | // Path, query, and fragment are structurally always valid for can_parse -- |
7876 | | // the parser would encode whatever is there. |
7877 | 11.7k | return true; |
7878 | 11.7k | } |
7879 | | |
7880 | | } // namespace |
7881 | | |
7882 | | template <class result_type> |
7883 | | ada_warn_unused tl::expected<result_type, errors> parse( |
7884 | 169k | std::string_view input, const result_type* base_url) { |
7885 | 169k | result_type u = ada::parser::parse_url_impl<result_type>(input, base_url); |
7886 | 169k | if (!u.is_valid) { |
7887 | 13.3k | return tl::unexpected(errors::type_error); |
7888 | 13.3k | } |
7889 | 156k | return u; |
7890 | 169k | } Unexecuted instantiation: tl::expected<ada::url, ada::errors> ada::parse<ada::url>(std::__1::basic_string_view<char, std::__1::char_traits<char> >, ada::url const*) tl::expected<ada::url_aggregator, ada::errors> ada::parse<ada::url_aggregator>(std::__1::basic_string_view<char, std::__1::char_traits<char> >, ada::url_aggregator const*) Line | Count | Source | 7884 | 169k | std::string_view input, const result_type* base_url) { | 7885 | 169k | result_type u = ada::parser::parse_url_impl<result_type>(input, base_url); | 7886 | 169k | if (!u.is_valid) { | 7887 | 13.3k | return tl::unexpected(errors::type_error); | 7888 | 13.3k | } | 7889 | 156k | return u; | 7890 | 169k | } |
|
7891 | | |
7892 | | template ada::result<url> parse<url>(std::string_view input, |
7893 | | const url* base_url = nullptr); |
7894 | | template ada::result<url_aggregator> parse<url_aggregator>( |
7895 | | std::string_view input, const url_aggregator* base_url = nullptr); |
7896 | | |
7897 | 0 | std::string href_from_file(std::string_view input) { |
7898 | | // Match ada::parse / setters: refuse inputs that already exceed the limit. |
7899 | | // Path percent-encoding can still expand the result, so we also check the |
7900 | | // final href below. |
7901 | 0 | const uint32_t max_length = ada::get_max_input_length(); |
7902 | 0 | if (input.size() > max_length) { |
7903 | 0 | return {}; |
7904 | 0 | } |
7905 | | |
7906 | | // This is going to be much faster than constructing a URL. |
7907 | 0 | std::string tmp_buffer; |
7908 | 0 | std::string_view internal_input; |
7909 | 0 | if (unicode::has_tabs_or_newline(input)) { |
7910 | 0 | tmp_buffer = input; |
7911 | 0 | helpers::remove_ascii_tab_or_newline(tmp_buffer); |
7912 | 0 | internal_input = tmp_buffer; |
7913 | 0 | } else { |
7914 | 0 | internal_input = input; |
7915 | 0 | } |
7916 | 0 | std::string path; |
7917 | 0 | if (internal_input.empty()) { |
7918 | 0 | path = "/"; |
7919 | 0 | } else if ((internal_input[0] == '/') || (internal_input[0] == '\\')) { |
7920 | 0 | helpers::parse_prepared_path(internal_input.substr(1), |
7921 | 0 | ada::scheme::type::FILE, path); |
7922 | 0 | } else { |
7923 | 0 | helpers::parse_prepared_path(internal_input, ada::scheme::type::FILE, path); |
7924 | 0 | } |
7925 | 0 | std::string result = "file://" + path; |
7926 | 0 | if (result.size() > max_length) { |
7927 | 0 | return {}; |
7928 | 0 | } |
7929 | 0 | return result; |
7930 | 0 | } |
7931 | | |
7932 | 66.0k | bool can_parse(std::string_view input, const std::string_view* base_input) { |
7933 | | // Must match parse().has_value(), including post-normalization max length. |
7934 | | // Percent-encoding expands a byte by at most 3x, but IDNA expands more: a |
7935 | | // 3-byte UTF-8 label such as U+337F becomes the 17-byte "xn--6oqv20b1zgzxr", |
7936 | | // so a dotted host sustains 4.5x. When the input (plus base, if any) fits in |
7937 | | // max_length/5, the normalized href cannot exceed max_length, so |
7938 | | // validation-only parsing (store_values=false) is safe. |
7939 | | |
7940 | | // Hot path first: absolute special URLs, no base. Avoid loading max_length |
7941 | | // until we need it (common absolute-fast true/false cases). |
7942 | 66.0k | if (base_input == nullptr) { |
7943 | 55.0k | auto r = try_can_parse_clean_http(input); |
7944 | 55.0k | if (!r.has_value()) { |
7945 | 43.6k | r = try_can_parse_absolute_fast(input); |
7946 | 43.6k | } |
7947 | 55.0k | if (r.has_value()) { |
7948 | 25.9k | if (!*r) { |
7949 | 2.82k | return false; |
7950 | 2.82k | } |
7951 | | // size <= max/5 => normalized href cannot exceed max (4.5x expansion). |
7952 | | // Check this first: default max is ~4GB so almost all URLs return true. |
7953 | 23.1k | const uint32_t max_length = ada::get_max_input_length(); |
7954 | 23.1k | if (input.size() <= static_cast<size_t>(max_length) / 5) { |
7955 | 23.1k | return true; |
7956 | 23.1k | } |
7957 | 0 | if (input.size() > max_length) { |
7958 | 0 | return false; |
7959 | 0 | } |
7960 | 0 | return ada::parser::parse_url_impl<ada::url_aggregator, true>(input, |
7961 | 0 | nullptr) |
7962 | 0 | .is_valid; |
7963 | 0 | } |
7964 | 55.0k | } |
7965 | | |
7966 | 40.0k | const uint32_t max_length = ada::get_max_input_length(); |
7967 | 40.0k | if (input.size() > max_length) { |
7968 | 0 | return false; |
7969 | 0 | } |
7970 | 40.0k | if (base_input != nullptr && base_input->size() > max_length) { |
7971 | 0 | return false; |
7972 | 0 | } |
7973 | | |
7974 | | // Relative resolution combines base + input; bound the sum so 4.5x expansion |
7975 | | // of either side cannot push the final href past max_length. |
7976 | 40.0k | const size_t combined = |
7977 | 40.0k | input.size() + (base_input == nullptr ? 0 : base_input->size()); |
7978 | 40.0k | const bool size_safe = combined <= static_cast<size_t>(max_length) / 5; |
7979 | | |
7980 | 40.0k | if (size_safe) { |
7981 | | // Validation-only: no buffer build, host still fully checked. |
7982 | 40.0k | ada::url_aggregator base_agg; |
7983 | 40.0k | ada::url_aggregator* base_ptr = nullptr; |
7984 | 40.0k | if (base_input != nullptr) { |
7985 | 11.0k | base_agg = ada::parser::parse_url_impl<ada::url_aggregator, false>( |
7986 | 11.0k | *base_input, nullptr); |
7987 | 11.0k | if (!base_agg.is_valid) { |
7988 | 7.69k | return false; |
7989 | 7.69k | } |
7990 | 3.31k | base_ptr = &base_agg; |
7991 | 3.31k | } |
7992 | 32.4k | return ada::parser::parse_url_impl<ada::url_aggregator, false>(input, |
7993 | 32.4k | base_ptr) |
7994 | 32.4k | .is_valid; |
7995 | 40.0k | } |
7996 | | |
7997 | | // Near the limit: full parse so post-normalization length matches parse(). |
7998 | 0 | if (base_input == nullptr) { |
7999 | 0 | return ada::parser::parse_url_impl<ada::url_aggregator, true>(input, |
8000 | 0 | nullptr) |
8001 | 0 | .is_valid; |
8002 | 0 | } |
8003 | 0 | ada::url_aggregator base_agg = |
8004 | 0 | ada::parser::parse_url_impl<ada::url_aggregator, true>(*base_input, |
8005 | 0 | nullptr); |
8006 | 0 | if (!base_agg.is_valid) { |
8007 | 0 | return false; |
8008 | 0 | } |
8009 | 0 | return ada::parser::parse_url_impl<ada::url_aggregator, true>(input, |
8010 | 0 | &base_agg) |
8011 | 0 | .is_valid; |
8012 | 0 | } |
8013 | | |
8014 | 0 | ada_warn_unused std::string_view to_string(ada::encoding_type type) { |
8015 | 0 | switch (type) { |
8016 | 0 | case ada::encoding_type::UTF8: |
8017 | 0 | return "UTF-8"; |
8018 | 0 | case ada::encoding_type::UTF_16LE: |
8019 | 0 | return "UTF-16LE"; |
8020 | 0 | case ada::encoding_type::UTF_16BE: |
8021 | 0 | return "UTF-16BE"; |
8022 | 0 | default: |
8023 | 0 | unreachable(); |
8024 | 0 | } |
8025 | 0 | } |
8026 | | |
8027 | | } // namespace ada |
8028 | | /* end file src/implementation.cpp */ |
8029 | | /* begin file src/helpers.cpp */ |
8030 | | #include <cstdint> |
8031 | | #include <cstring> |
8032 | | #include <sstream> |
8033 | | |
8034 | | |
8035 | | #if ADA_SSSE3 |
8036 | | #include <tmmintrin.h> |
8037 | | #endif |
8038 | | |
8039 | | namespace ada::helpers { |
8040 | | |
8041 | | template <typename out_iter> |
8042 | 0 | void encode_json(std::string_view view, out_iter out) { |
8043 | | // trivial implementation. could be faster. |
8044 | 0 | const char* hexvalues = |
8045 | 0 | "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"; |
8046 | 0 | for (uint8_t c : view) { |
8047 | 0 | if (c == '\\') { |
8048 | 0 | *out++ = '\\'; |
8049 | 0 | *out++ = '\\'; |
8050 | 0 | } else if (c == '"') { |
8051 | 0 | *out++ = '\\'; |
8052 | 0 | *out++ = '"'; |
8053 | 0 | } else if (c <= 0x1f) { |
8054 | 0 | *out++ = '\\'; |
8055 | 0 | *out++ = 'u'; |
8056 | 0 | *out++ = '0'; |
8057 | 0 | *out++ = '0'; |
8058 | 0 | *out++ = hexvalues[2 * c]; |
8059 | 0 | *out++ = hexvalues[2 * c + 1]; |
8060 | 0 | } else { |
8061 | 0 | *out++ = c; |
8062 | 0 | } |
8063 | 0 | } |
8064 | 0 | } |
8065 | | |
8066 | 0 | ada_unused std::string get_state(ada::state s) { |
8067 | 0 | switch (s) { |
8068 | 0 | case ada::state::AUTHORITY: |
8069 | 0 | return "Authority"; |
8070 | 0 | case ada::state::SCHEME_START: |
8071 | 0 | return "Scheme Start"; |
8072 | 0 | case ada::state::SCHEME: |
8073 | 0 | return "Scheme"; |
8074 | 0 | case ada::state::HOST: |
8075 | 0 | return "Host"; |
8076 | 0 | case ada::state::NO_SCHEME: |
8077 | 0 | return "No Scheme"; |
8078 | 0 | case ada::state::FRAGMENT: |
8079 | 0 | return "Fragment"; |
8080 | 0 | case ada::state::RELATIVE_SCHEME: |
8081 | 0 | return "Relative Scheme"; |
8082 | 0 | case ada::state::RELATIVE_SLASH: |
8083 | 0 | return "Relative Slash"; |
8084 | 0 | case ada::state::FILE: |
8085 | 0 | return "File"; |
8086 | 0 | case ada::state::FILE_HOST: |
8087 | 0 | return "File Host"; |
8088 | 0 | case ada::state::FILE_SLASH: |
8089 | 0 | return "File Slash"; |
8090 | 0 | case ada::state::PATH_OR_AUTHORITY: |
8091 | 0 | return "Path or Authority"; |
8092 | 0 | case ada::state::SPECIAL_AUTHORITY_IGNORE_SLASHES: |
8093 | 0 | return "Special Authority Ignore Slashes"; |
8094 | 0 | case ada::state::SPECIAL_AUTHORITY_SLASHES: |
8095 | 0 | return "Special Authority Slashes"; |
8096 | 0 | case ada::state::SPECIAL_RELATIVE_OR_AUTHORITY: |
8097 | 0 | return "Special Relative or Authority"; |
8098 | 0 | case ada::state::QUERY: |
8099 | 0 | return "Query"; |
8100 | 0 | case ada::state::PATH: |
8101 | 0 | return "Path"; |
8102 | 0 | case ada::state::PATH_START: |
8103 | 0 | return "Path Start"; |
8104 | 0 | case ada::state::OPAQUE_PATH: |
8105 | 0 | return "Opaque Path"; |
8106 | 0 | case ada::state::PORT: |
8107 | 0 | return "Port"; |
8108 | 0 | default: |
8109 | 0 | return "unknown state"; |
8110 | 0 | } |
8111 | 0 | } |
8112 | | |
8113 | | ada_really_inline std::optional<std::string_view> prune_hash( |
8114 | 188k | std::string_view& input) noexcept { |
8115 | | // compiles down to 20--30 instructions including a class to memchr (C |
8116 | | // function). this function should be quite fast. |
8117 | 188k | size_t location_of_first = input.find('#'); |
8118 | 188k | if (location_of_first == std::string_view::npos) { |
8119 | 151k | return std::nullopt; |
8120 | 151k | } |
8121 | 36.9k | std::string_view hash = input; |
8122 | 36.9k | hash.remove_prefix(location_of_first + 1); |
8123 | 36.9k | input.remove_suffix(input.size() - location_of_first); |
8124 | 36.9k | return hash; |
8125 | 188k | } |
8126 | | |
8127 | 3.86k | ada_really_inline bool shorten_path(std::string& path, ada::scheme::type type) { |
8128 | | // Let path be url's path. |
8129 | | // If url's scheme is "file", path's size is 1, and path[0] is a normalized |
8130 | | // Windows drive letter, then return. |
8131 | 3.86k | if (type == ada::scheme::type::FILE && |
8132 | 2.82k | path.find('/', 1) == std::string_view::npos && !path.empty()) { |
8133 | 1.69k | if (checkers::is_normalized_windows_drive_letter( |
8134 | 1.69k | helpers::substring(path, 1))) { |
8135 | 372 | return false; |
8136 | 372 | } |
8137 | 1.69k | } |
8138 | | |
8139 | | // Remove path's last item, if any. |
8140 | 3.49k | size_t last_delimiter = path.rfind('/'); |
8141 | 3.49k | if (last_delimiter != std::string::npos) { |
8142 | 2.70k | path.erase(last_delimiter); |
8143 | 2.70k | return true; |
8144 | 2.70k | } |
8145 | | |
8146 | 795 | return false; |
8147 | 3.49k | } |
8148 | | |
8149 | | ada_really_inline bool shorten_path(std::string_view& path, |
8150 | 1.02k | ada::scheme::type type) { |
8151 | | // Let path be url's path. |
8152 | | // If url's scheme is "file", path's size is 1, and path[0] is a normalized |
8153 | | // Windows drive letter, then return. |
8154 | 1.02k | if (type == ada::scheme::type::FILE && |
8155 | 228 | path.find('/', 1) == std::string_view::npos && !path.empty()) { |
8156 | 82 | if (checkers::is_normalized_windows_drive_letter( |
8157 | 82 | helpers::substring(path, 1))) { |
8158 | 1 | return false; |
8159 | 1 | } |
8160 | 82 | } |
8161 | | |
8162 | | // Remove path's last item, if any. |
8163 | 1.02k | if (!path.empty()) { |
8164 | 505 | size_t slash_loc = path.rfind('/'); |
8165 | 505 | if (slash_loc != std::string_view::npos) { |
8166 | 505 | path.remove_suffix(path.size() - slash_loc); |
8167 | 505 | return true; |
8168 | 505 | } |
8169 | 505 | } |
8170 | | |
8171 | 518 | return false; |
8172 | 1.02k | } |
8173 | | |
8174 | 283k | ada_really_inline void remove_ascii_tab_or_newline(std::string& input) { |
8175 | | // if this ever becomes a performance issue, we could use an approach similar |
8176 | | // to has_tabs_or_newline |
8177 | 283k | std::erase_if(input, ada::unicode::is_ascii_tab_or_newline); |
8178 | 283k | } |
8179 | | |
8180 | | ada_really_inline constexpr std::string_view substring(std::string_view input, |
8181 | 49.9k | size_t pos) { |
8182 | 49.9k | ADA_ASSERT_TRUE(pos <= input.size()); |
8183 | | // The following is safer but unneeded if we have the above line: |
8184 | | // return pos > input.size() ? std::string_view() : input.substr(pos); |
8185 | 49.9k | return input.substr(pos); |
8186 | 49.9k | } |
8187 | | |
8188 | 19 | ada_really_inline void resize(std::string_view& input, size_t pos) noexcept { |
8189 | 19 | ADA_ASSERT_TRUE(pos <= input.size()); |
8190 | 19 | input.remove_suffix(input.size() - pos); |
8191 | 19 | } |
8192 | | |
8193 | | // computes the number of trailing zeroes |
8194 | | // this is a private inline function only defined in this source file. |
8195 | 14.1k | ada_really_inline int trailing_zeroes(uint32_t input_num) noexcept { |
8196 | | #ifdef ADA_REGULAR_VISUAL_STUDIO |
8197 | | unsigned long ret; |
8198 | | // Search the mask data from least significant bit (LSB) |
8199 | | // to the most significant bit (MSB) for a set bit (1). |
8200 | | _BitScanForward(&ret, input_num); |
8201 | | return (int)ret; |
8202 | | #else // ADA_REGULAR_VISUAL_STUDIO |
8203 | 14.1k | return __builtin_ctzl(input_num); |
8204 | 14.1k | #endif // ADA_REGULAR_VISUAL_STUDIO |
8205 | 14.1k | } |
8206 | | |
8207 | | #if ADA_NEON |
8208 | | // computes the number of trailing zeroes of a 64-bit word |
8209 | | // this is a private inline function only defined in this source file. |
8210 | | ada_really_inline int trailing_zeroes64(uint64_t input_num) noexcept { |
8211 | | #ifdef ADA_REGULAR_VISUAL_STUDIO |
8212 | | unsigned long ret; |
8213 | | _BitScanForward64(&ret, input_num); |
8214 | | return (int)ret; |
8215 | | #else // ADA_REGULAR_VISUAL_STUDIO |
8216 | | return __builtin_ctzll(input_num); |
8217 | | #endif // ADA_REGULAR_VISUAL_STUDIO |
8218 | | } |
8219 | | |
8220 | | // Given a NEON register whose lanes are all either 0x00 or 0xFF (i.e., the |
8221 | | // result of a comparison), produce a 64-bit value with four bits set per |
8222 | | // matching input byte, and zero bits elsewhere. Narrowing by four bits per |
8223 | | // 16-bit lane is cheaper than materializing a 16-bit bitmask, and it keeps |
8224 | | // the value in a vector register so that the "any match?" test can be done |
8225 | | // with a floating-point compare against zero, avoiding a transfer to a |
8226 | | // general-purpose register on the common no-match path. |
8227 | | // |
8228 | | // The floating-point compare is only safe because the lanes are 0x00/0xFF: |
8229 | | // each byte of the narrowed value is then one of 0x00, 0x0F, 0xF0 or 0xFF, |
8230 | | // so the result can never be the negative-zero bit pattern (which would |
8231 | | // compare equal to 0.0). Do not use this on arbitrary vectors. |
8232 | | ada_really_inline uint8x8_t to_nibble_mask(uint8x16_t comparison) noexcept { |
8233 | | return vshrn_n_u16(vreinterpretq_u16_u8(comparison), 4); |
8234 | | } |
8235 | | |
8236 | | ada_really_inline bool any_set(uint8x8_t nibble_mask) noexcept { |
8237 | | return vdupd_lane_f64(vreinterpret_f64_u8(nibble_mask), 0) != 0.0; |
8238 | | } |
8239 | | |
8240 | | // index of the first matching byte; only meaningful when any_set is true. |
8241 | | ada_really_inline size_t first_set(uint8x8_t nibble_mask) noexcept { |
8242 | | return size_t(trailing_zeroes64( |
8243 | | vget_lane_u64(vreinterpret_u64_u8(nibble_mask), 0))) >> |
8244 | | 2; |
8245 | | } |
8246 | | #endif // ADA_NEON |
8247 | | |
8248 | | // starting at index location, this finds the next location of a character |
8249 | | // :, /, \\, ? or [. If none is found, view.size() is returned. |
8250 | | // For use within get_host_delimiter_location. |
8251 | | #if ADA_SSSE3 |
8252 | | ada_really_inline size_t find_next_host_delimiter_special( |
8253 | | std::string_view view, size_t location) noexcept { |
8254 | | // first check for short strings in which case we do it naively. |
8255 | | if (view.size() - location < 16) { // slow path |
8256 | | for (size_t i = location; i < view.size(); i++) { |
8257 | | if (view[i] == ':' || view[i] == '/' || view[i] == '\\' || |
8258 | | view[i] == '?' || view[i] == '[') { |
8259 | | return i; |
8260 | | } |
8261 | | } |
8262 | | return size_t(view.size()); |
8263 | | } |
8264 | | // fast path for long strings (expected to be common) |
8265 | | // Using SSSE3's _mm_shuffle_epi8 for table lookup (same approach as NEON) |
8266 | | size_t i = location; |
8267 | | const __m128i low_mask = |
8268 | | _mm_setr_epi8(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
8269 | | 0x01, 0x04, 0x04, 0x00, 0x00, 0x03); |
8270 | | const __m128i high_mask = |
8271 | | _mm_setr_epi8(0x00, 0x00, 0x02, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, |
8272 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); |
8273 | | const __m128i fmask = _mm_set1_epi8(0xf); |
8274 | | const __m128i zero = _mm_setzero_si128(); |
8275 | | for (; i + 15 < view.size(); i += 16) { |
8276 | | __m128i word = _mm_loadu_si128((const __m128i*)(view.data() + i)); |
8277 | | __m128i lowpart = _mm_shuffle_epi8(low_mask, _mm_and_si128(word, fmask)); |
8278 | | __m128i highpart = _mm_shuffle_epi8( |
8279 | | high_mask, _mm_and_si128(_mm_srli_epi16(word, 4), fmask)); |
8280 | | __m128i classify = _mm_and_si128(lowpart, highpart); |
8281 | | __m128i is_zero = _mm_cmpeq_epi8(classify, zero); |
8282 | | // _mm_movemask_epi8 returns a 16-bit mask in bits 0-15, with bits 16-31 |
8283 | | // zero. After NOT (~), bits 16-31 become 1. We must mask to 16 bits to |
8284 | | // avoid false positives. |
8285 | | int mask = ~_mm_movemask_epi8(is_zero) & 0xFFFF; |
8286 | | if (mask != 0) { |
8287 | | return i + trailing_zeroes(static_cast<uint32_t>(mask)); |
8288 | | } |
8289 | | } |
8290 | | if (i < view.size()) { |
8291 | | __m128i word = |
8292 | | _mm_loadu_si128((const __m128i*)(view.data() + view.length() - 16)); |
8293 | | __m128i lowpart = _mm_shuffle_epi8(low_mask, _mm_and_si128(word, fmask)); |
8294 | | __m128i highpart = _mm_shuffle_epi8( |
8295 | | high_mask, _mm_and_si128(_mm_srli_epi16(word, 4), fmask)); |
8296 | | __m128i classify = _mm_and_si128(lowpart, highpart); |
8297 | | __m128i is_zero = _mm_cmpeq_epi8(classify, zero); |
8298 | | // _mm_movemask_epi8 returns a 16-bit mask in bits 0-15, with bits 16-31 |
8299 | | // zero. After NOT (~), bits 16-31 become 1. We must mask to 16 bits to |
8300 | | // avoid false positives. |
8301 | | int mask = ~_mm_movemask_epi8(is_zero) & 0xFFFF; |
8302 | | if (mask != 0) { |
8303 | | return view.length() - 16 + trailing_zeroes(static_cast<uint32_t>(mask)); |
8304 | | } |
8305 | | } |
8306 | | return size_t(view.size()); |
8307 | | } |
8308 | | #elif ADA_NEON |
8309 | | // The ada_make_uint8x16_t macro is necessary because Visual Studio does not |
8310 | | // support direct initialization of uint8x16_t. See |
8311 | | // https://developercommunity.visualstudio.com/t/error-C2078:-too-many-initializers-whe/402911?q=backend+neon |
8312 | | #ifndef ada_make_uint8x16_t |
8313 | | #define ada_make_uint8x16_t(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, \ |
8314 | | x13, x14, x15, x16) \ |
8315 | | ([=]() { \ |
8316 | | static uint8_t array[16] = {x1, x2, x3, x4, x5, x6, x7, x8, \ |
8317 | | x9, x10, x11, x12, x13, x14, x15, x16}; \ |
8318 | | return vld1q_u8(array); \ |
8319 | | }()) |
8320 | | #endif |
8321 | | |
8322 | | ada_really_inline size_t find_next_host_delimiter_special( |
8323 | | std::string_view view, size_t location) noexcept { |
8324 | | // first check for short strings in which case we do it naively. |
8325 | | if (view.size() - location < 16) { // slow path |
8326 | | for (size_t i = location; i < view.size(); i++) { |
8327 | | if (view[i] == ':' || view[i] == '/' || view[i] == '\\' || |
8328 | | view[i] == '?' || view[i] == '[') { |
8329 | | return i; |
8330 | | } |
8331 | | } |
8332 | | return size_t(view.size()); |
8333 | | } |
8334 | | // fast path for long strings (expected to be common) |
8335 | | size_t i = location; |
8336 | | uint8x16_t low_mask = |
8337 | | ada_make_uint8x16_t(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
8338 | | 0x00, 0x01, 0x04, 0x04, 0x00, 0x00, 0x03); |
8339 | | uint8x16_t high_mask = |
8340 | | ada_make_uint8x16_t(0x00, 0x00, 0x02, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, |
8341 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); |
8342 | | uint8x16_t fmask = vmovq_n_u8(0xf); |
8343 | | for (; i + 15 < view.size(); i += 16) { |
8344 | | uint8x16_t word = vld1q_u8((const uint8_t*)view.data() + i); |
8345 | | uint8x16_t lowpart = vqtbl1q_u8(low_mask, vandq_u8(word, fmask)); |
8346 | | uint8x16_t highpart = vqtbl1q_u8(high_mask, vshrq_n_u8(word, 4)); |
8347 | | // vtstq_u8 gives us 0xFF where (lowpart & highpart) is non-zero and 0x00 |
8348 | | // elsewhere: unlike the plain AND, that is a proper comparison mask, which |
8349 | | // is what to_nibble_mask requires. |
8350 | | uint8x8_t matches = to_nibble_mask(vtstq_u8(lowpart, highpart)); |
8351 | | if (any_set(matches)) { |
8352 | | return i + first_set(matches); |
8353 | | } |
8354 | | } |
8355 | | |
8356 | | if (i < view.size()) { |
8357 | | uint8x16_t word = |
8358 | | vld1q_u8((const uint8_t*)view.data() + view.length() - 16); |
8359 | | uint8x16_t lowpart = vqtbl1q_u8(low_mask, vandq_u8(word, fmask)); |
8360 | | uint8x16_t highpart = vqtbl1q_u8(high_mask, vshrq_n_u8(word, 4)); |
8361 | | uint8x8_t matches = to_nibble_mask(vtstq_u8(lowpart, highpart)); |
8362 | | if (any_set(matches)) { |
8363 | | return view.length() - 16 + first_set(matches); |
8364 | | } |
8365 | | } |
8366 | | return size_t(view.size()); |
8367 | | } |
8368 | | #elif ADA_SSE2 |
8369 | | ada_really_inline size_t find_next_host_delimiter_special( |
8370 | 186k | std::string_view view, size_t location) noexcept { |
8371 | | // first check for short strings in which case we do it naively. |
8372 | 186k | if (view.size() - location < 16) { // slow path |
8373 | 681k | for (size_t i = location; i < view.size(); i++) { |
8374 | 604k | if (view[i] == ':' || view[i] == '/' || view[i] == '\\' || |
8375 | 511k | view[i] == '?' || view[i] == '[') { |
8376 | 94.8k | return i; |
8377 | 94.8k | } |
8378 | 604k | } |
8379 | 77.3k | return size_t(view.size()); |
8380 | 172k | } |
8381 | | // fast path for long strings (expected to be common) |
8382 | 13.9k | size_t i = location; |
8383 | 13.9k | const __m128i mask1 = _mm_set1_epi8(':'); |
8384 | 13.9k | const __m128i mask2 = _mm_set1_epi8('/'); |
8385 | 13.9k | const __m128i mask3 = _mm_set1_epi8('\\'); |
8386 | 13.9k | const __m128i mask4 = _mm_set1_epi8('?'); |
8387 | 13.9k | const __m128i mask5 = _mm_set1_epi8('['); |
8388 | | |
8389 | 34.8k | for (; i + 15 < view.size(); i += 16) { |
8390 | 31.0k | __m128i word = _mm_loadu_si128((const __m128i*)(view.data() + i)); |
8391 | 31.0k | __m128i m1 = _mm_cmpeq_epi8(word, mask1); |
8392 | 31.0k | __m128i m2 = _mm_cmpeq_epi8(word, mask2); |
8393 | 31.0k | __m128i m3 = _mm_cmpeq_epi8(word, mask3); |
8394 | 31.0k | __m128i m4 = _mm_cmpeq_epi8(word, mask4); |
8395 | 31.0k | __m128i m5 = _mm_cmpeq_epi8(word, mask5); |
8396 | 31.0k | __m128i m = _mm_or_si128( |
8397 | 31.0k | _mm_or_si128(_mm_or_si128(m1, m2), _mm_or_si128(m3, m4)), m5); |
8398 | 31.0k | int mask = _mm_movemask_epi8(m); |
8399 | 31.0k | if (mask != 0) { |
8400 | 10.1k | return i + trailing_zeroes(mask); |
8401 | 10.1k | } |
8402 | 31.0k | } |
8403 | 3.78k | if (i < view.size()) { |
8404 | 3.44k | __m128i word = |
8405 | 3.44k | _mm_loadu_si128((const __m128i*)(view.data() + view.length() - 16)); |
8406 | 3.44k | __m128i m1 = _mm_cmpeq_epi8(word, mask1); |
8407 | 3.44k | __m128i m2 = _mm_cmpeq_epi8(word, mask2); |
8408 | 3.44k | __m128i m3 = _mm_cmpeq_epi8(word, mask3); |
8409 | 3.44k | __m128i m4 = _mm_cmpeq_epi8(word, mask4); |
8410 | 3.44k | __m128i m5 = _mm_cmpeq_epi8(word, mask5); |
8411 | 3.44k | __m128i m = _mm_or_si128( |
8412 | 3.44k | _mm_or_si128(_mm_or_si128(m1, m2), _mm_or_si128(m3, m4)), m5); |
8413 | 3.44k | int mask = _mm_movemask_epi8(m); |
8414 | 3.44k | if (mask != 0) { |
8415 | 1.41k | return view.length() - 16 + trailing_zeroes(mask); |
8416 | 1.41k | } |
8417 | 3.44k | } |
8418 | 2.37k | return size_t(view.length()); |
8419 | 3.78k | } |
8420 | | #elif ADA_LSX |
8421 | | ada_really_inline size_t find_next_host_delimiter_special( |
8422 | | std::string_view view, size_t location) noexcept { |
8423 | | // first check for short strings in which case we do it naively. |
8424 | | if (view.size() - location < 16) { // slow path |
8425 | | for (size_t i = location; i < view.size(); i++) { |
8426 | | if (view[i] == ':' || view[i] == '/' || view[i] == '\\' || |
8427 | | view[i] == '?' || view[i] == '[') { |
8428 | | return i; |
8429 | | } |
8430 | | } |
8431 | | return size_t(view.size()); |
8432 | | } |
8433 | | // fast path for long strings (expected to be common) |
8434 | | size_t i = location; |
8435 | | const __m128i mask1 = __lsx_vrepli_b(':'); |
8436 | | const __m128i mask2 = __lsx_vrepli_b('/'); |
8437 | | const __m128i mask3 = __lsx_vrepli_b('\\'); |
8438 | | const __m128i mask4 = __lsx_vrepli_b('?'); |
8439 | | const __m128i mask5 = __lsx_vrepli_b('['); |
8440 | | |
8441 | | for (; i + 15 < view.size(); i += 16) { |
8442 | | __m128i word = __lsx_vld((const __m128i*)(view.data() + i), 0); |
8443 | | __m128i m1 = __lsx_vseq_b(word, mask1); |
8444 | | __m128i m2 = __lsx_vseq_b(word, mask2); |
8445 | | __m128i m3 = __lsx_vseq_b(word, mask3); |
8446 | | __m128i m4 = __lsx_vseq_b(word, mask4); |
8447 | | __m128i m5 = __lsx_vseq_b(word, mask5); |
8448 | | __m128i m = |
8449 | | __lsx_vor_v(__lsx_vor_v(__lsx_vor_v(m1, m2), __lsx_vor_v(m3, m4)), m5); |
8450 | | int mask = __lsx_vpickve2gr_hu(__lsx_vmsknz_b(m), 0); |
8451 | | if (mask != 0) { |
8452 | | return i + trailing_zeroes(mask); |
8453 | | } |
8454 | | } |
8455 | | if (i < view.size()) { |
8456 | | __m128i word = |
8457 | | __lsx_vld((const __m128i*)(view.data() + view.length() - 16), 0); |
8458 | | __m128i m1 = __lsx_vseq_b(word, mask1); |
8459 | | __m128i m2 = __lsx_vseq_b(word, mask2); |
8460 | | __m128i m3 = __lsx_vseq_b(word, mask3); |
8461 | | __m128i m4 = __lsx_vseq_b(word, mask4); |
8462 | | __m128i m5 = __lsx_vseq_b(word, mask5); |
8463 | | __m128i m = |
8464 | | __lsx_vor_v(__lsx_vor_v(__lsx_vor_v(m1, m2), __lsx_vor_v(m3, m4)), m5); |
8465 | | int mask = __lsx_vpickve2gr_hu(__lsx_vmsknz_b(m), 0); |
8466 | | if (mask != 0) { |
8467 | | return view.length() - 16 + trailing_zeroes(mask); |
8468 | | } |
8469 | | } |
8470 | | return size_t(view.length()); |
8471 | | } |
8472 | | #elif ADA_RVV |
8473 | | ada_really_inline size_t find_next_host_delimiter_special( |
8474 | | std::string_view view, size_t location) noexcept { |
8475 | | // The LUT approach was a bit slower on the SpacemiT X60, but I could see it |
8476 | | // being faster on future hardware. |
8477 | | #if 0 |
8478 | | // LUT generated using: s=":/\\?["; list(zip([((ord(c)>>2)&0xF)for c in s],s)) |
8479 | | static const uint8_t tbl[16] = { |
8480 | | 0xF, 0, 0, 0, 0, 0, '[', '\\', 0, 0, 0, '/', 0, 0, ':', '?' |
8481 | | }; |
8482 | | vuint8m1_t vtbl = __riscv_vle8_v_u8m1(tbl, 16); |
8483 | | #endif |
8484 | | uint8_t* src = (uint8_t*)view.data() + location; |
8485 | | for (size_t vl, n = view.size() - location; n > 0; |
8486 | | n -= vl, src += vl, location += vl) { |
8487 | | vl = __riscv_vsetvl_e8m1(n); |
8488 | | vuint8m1_t v = __riscv_vle8_v_u8m1(src, vl); |
8489 | | #if 0 |
8490 | | vuint8m1_t vidx = __riscv_vand(__riscv_vsrl(v, 2, vl), 0xF, vl); |
8491 | | vuint8m1_t vlut = __riscv_vrgather(vtbl, vidx, vl); |
8492 | | vbool8_t m = __riscv_vmseq(v, vlut, vl); |
8493 | | #else |
8494 | | vbool8_t m1 = __riscv_vmseq(v, ':', vl); |
8495 | | vbool8_t m2 = __riscv_vmseq(v, '/', vl); |
8496 | | vbool8_t m3 = __riscv_vmseq(v, '?', vl); |
8497 | | vbool8_t m4 = __riscv_vmseq(v, '[', vl); |
8498 | | vbool8_t m5 = __riscv_vmseq(v, '\\', vl); |
8499 | | vbool8_t m = __riscv_vmor( |
8500 | | __riscv_vmor(__riscv_vmor(m1, m2, vl), __riscv_vmor(m3, m4, vl), vl), |
8501 | | m5, vl); |
8502 | | #endif |
8503 | | long idx = __riscv_vfirst(m, vl); |
8504 | | if (idx >= 0) return location + idx; |
8505 | | } |
8506 | | return size_t(view.size()); |
8507 | | } |
8508 | | #else |
8509 | | // : / [ \\ ? |
8510 | | static constexpr std::array<uint8_t, 256> special_host_delimiters = |
8511 | | []() consteval { |
8512 | | std::array<uint8_t, 256> result{}; |
8513 | | for (int i : {':', '/', '[', '\\', '?'}) { |
8514 | | result[i] = 1; |
8515 | | } |
8516 | | return result; |
8517 | | }(); |
8518 | | // credit: @the-moisrex recommended a table-based approach |
8519 | | ada_really_inline size_t find_next_host_delimiter_special( |
8520 | | std::string_view view, size_t location) noexcept { |
8521 | | auto const str = view.substr(location); |
8522 | | for (auto pos = str.begin(); pos != str.end(); ++pos) { |
8523 | | if (special_host_delimiters[(uint8_t)*pos]) { |
8524 | | return pos - str.begin() + location; |
8525 | | } |
8526 | | } |
8527 | | return size_t(view.size()); |
8528 | | } |
8529 | | #endif |
8530 | | |
8531 | | // starting at index location, this finds the next location of a character |
8532 | | // :, /, ? or [. If none is found, view.size() is returned. |
8533 | | // For use within get_host_delimiter_location. |
8534 | | #if ADA_SSSE3 |
8535 | | ada_really_inline size_t find_next_host_delimiter(std::string_view view, |
8536 | | size_t location) noexcept { |
8537 | | // first check for short strings in which case we do it naively. |
8538 | | if (view.size() - location < 16) { // slow path |
8539 | | for (size_t i = location; i < view.size(); i++) { |
8540 | | if (view[i] == ':' || view[i] == '/' || view[i] == '?' || |
8541 | | view[i] == '[') { |
8542 | | return i; |
8543 | | } |
8544 | | } |
8545 | | return size_t(view.size()); |
8546 | | } |
8547 | | // fast path for long strings (expected to be common) |
8548 | | size_t i = location; |
8549 | | // Lookup tables for bit classification: |
8550 | | // ':' (0x3A): low[0xA]=0x01, high[0x3]=0x01 -> match |
8551 | | // '/' (0x2F): low[0xF]=0x02, high[0x2]=0x02 -> match |
8552 | | // '?' (0x3F): low[0xF]=0x01, high[0x3]=0x01 -> match |
8553 | | // '[' (0x5B): low[0xB]=0x04, high[0x5]=0x04 -> match |
8554 | | const __m128i low_mask = |
8555 | | _mm_setr_epi8(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
8556 | | 0x01, 0x04, 0x00, 0x00, 0x00, 0x03); |
8557 | | const __m128i high_mask = |
8558 | | _mm_setr_epi8(0x00, 0x00, 0x02, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, |
8559 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); |
8560 | | const __m128i fmask = _mm_set1_epi8(0xf); |
8561 | | const __m128i zero = _mm_setzero_si128(); |
8562 | | |
8563 | | for (; i + 15 < view.size(); i += 16) { |
8564 | | __m128i word = _mm_loadu_si128((const __m128i*)(view.data() + i)); |
8565 | | __m128i lowpart = _mm_shuffle_epi8(low_mask, _mm_and_si128(word, fmask)); |
8566 | | __m128i highpart = _mm_shuffle_epi8( |
8567 | | high_mask, _mm_and_si128(_mm_srli_epi16(word, 4), fmask)); |
8568 | | __m128i classify = _mm_and_si128(lowpart, highpart); |
8569 | | __m128i is_zero = _mm_cmpeq_epi8(classify, zero); |
8570 | | // _mm_movemask_epi8 returns a 16-bit mask in bits 0-15, with bits 16-31 |
8571 | | // zero. After NOT (~), bits 16-31 become 1. We must mask to 16 bits to |
8572 | | // avoid false positives. |
8573 | | int mask = ~_mm_movemask_epi8(is_zero) & 0xFFFF; |
8574 | | if (mask != 0) { |
8575 | | return i + trailing_zeroes(static_cast<uint32_t>(mask)); |
8576 | | } |
8577 | | } |
8578 | | |
8579 | | if (i < view.size()) { |
8580 | | __m128i word = |
8581 | | _mm_loadu_si128((const __m128i*)(view.data() + view.length() - 16)); |
8582 | | __m128i lowpart = _mm_shuffle_epi8(low_mask, _mm_and_si128(word, fmask)); |
8583 | | __m128i highpart = _mm_shuffle_epi8( |
8584 | | high_mask, _mm_and_si128(_mm_srli_epi16(word, 4), fmask)); |
8585 | | __m128i classify = _mm_and_si128(lowpart, highpart); |
8586 | | __m128i is_zero = _mm_cmpeq_epi8(classify, zero); |
8587 | | // _mm_movemask_epi8 returns a 16-bit mask in bits 0-15, with bits 16-31 |
8588 | | // zero. After NOT (~), bits 16-31 become 1. We must mask to 16 bits to |
8589 | | // avoid false positives. |
8590 | | int mask = ~_mm_movemask_epi8(is_zero) & 0xFFFF; |
8591 | | if (mask != 0) { |
8592 | | return view.length() - 16 + trailing_zeroes(static_cast<uint32_t>(mask)); |
8593 | | } |
8594 | | } |
8595 | | return size_t(view.size()); |
8596 | | } |
8597 | | #elif ADA_NEON |
8598 | | ada_really_inline size_t find_next_host_delimiter(std::string_view view, |
8599 | | size_t location) noexcept { |
8600 | | // first check for short strings in which case we do it naively. |
8601 | | if (view.size() - location < 16) { // slow path |
8602 | | for (size_t i = location; i < view.size(); i++) { |
8603 | | if (view[i] == ':' || view[i] == '/' || view[i] == '?' || |
8604 | | view[i] == '[') { |
8605 | | return i; |
8606 | | } |
8607 | | } |
8608 | | return size_t(view.size()); |
8609 | | } |
8610 | | // fast path for long strings (expected to be common) |
8611 | | size_t i = location; |
8612 | | uint8x16_t low_mask = |
8613 | | ada_make_uint8x16_t(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
8614 | | 0x00, 0x01, 0x04, 0x00, 0x00, 0x00, 0x03); |
8615 | | uint8x16_t high_mask = |
8616 | | ada_make_uint8x16_t(0x00, 0x00, 0x02, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, |
8617 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); |
8618 | | uint8x16_t fmask = vmovq_n_u8(0xf); |
8619 | | for (; i + 15 < view.size(); i += 16) { |
8620 | | uint8x16_t word = vld1q_u8((const uint8_t*)view.data() + i); |
8621 | | uint8x16_t lowpart = vqtbl1q_u8(low_mask, vandq_u8(word, fmask)); |
8622 | | uint8x16_t highpart = vqtbl1q_u8(high_mask, vshrq_n_u8(word, 4)); |
8623 | | // vtstq_u8 gives us 0xFF where (lowpart & highpart) is non-zero and 0x00 |
8624 | | // elsewhere: unlike the plain AND, that is a proper comparison mask, which |
8625 | | // is what to_nibble_mask requires. |
8626 | | uint8x8_t matches = to_nibble_mask(vtstq_u8(lowpart, highpart)); |
8627 | | if (any_set(matches)) { |
8628 | | return i + first_set(matches); |
8629 | | } |
8630 | | } |
8631 | | |
8632 | | if (i < view.size()) { |
8633 | | uint8x16_t word = |
8634 | | vld1q_u8((const uint8_t*)view.data() + view.length() - 16); |
8635 | | uint8x16_t lowpart = vqtbl1q_u8(low_mask, vandq_u8(word, fmask)); |
8636 | | uint8x16_t highpart = vqtbl1q_u8(high_mask, vshrq_n_u8(word, 4)); |
8637 | | uint8x8_t matches = to_nibble_mask(vtstq_u8(lowpart, highpart)); |
8638 | | if (any_set(matches)) { |
8639 | | return view.length() - 16 + first_set(matches); |
8640 | | } |
8641 | | } |
8642 | | return size_t(view.size()); |
8643 | | } |
8644 | | #elif ADA_SSE2 |
8645 | | ada_really_inline size_t find_next_host_delimiter(std::string_view view, |
8646 | 5.54k | size_t location) noexcept { |
8647 | | // first check for short strings in which case we do it naively. |
8648 | 5.54k | if (view.size() - location < 16) { // slow path |
8649 | 6.57k | for (size_t i = location; i < view.size(); i++) { |
8650 | 5.01k | if (view[i] == ':' || view[i] == '/' || view[i] == '?' || |
8651 | 4.53k | view[i] == '[') { |
8652 | 946 | return i; |
8653 | 946 | } |
8654 | 5.01k | } |
8655 | 1.56k | return size_t(view.size()); |
8656 | 2.50k | } |
8657 | | // fast path for long strings (expected to be common) |
8658 | 3.03k | size_t i = location; |
8659 | 3.03k | const __m128i mask1 = _mm_set1_epi8(':'); |
8660 | 3.03k | const __m128i mask2 = _mm_set1_epi8('/'); |
8661 | 3.03k | const __m128i mask4 = _mm_set1_epi8('?'); |
8662 | 3.03k | const __m128i mask5 = _mm_set1_epi8('['); |
8663 | | |
8664 | 9.39k | for (; i + 15 < view.size(); i += 16) { |
8665 | 8.78k | __m128i word = _mm_loadu_si128((const __m128i*)(view.data() + i)); |
8666 | 8.78k | __m128i m1 = _mm_cmpeq_epi8(word, mask1); |
8667 | 8.78k | __m128i m2 = _mm_cmpeq_epi8(word, mask2); |
8668 | 8.78k | __m128i m4 = _mm_cmpeq_epi8(word, mask4); |
8669 | 8.78k | __m128i m5 = _mm_cmpeq_epi8(word, mask5); |
8670 | 8.78k | __m128i m = _mm_or_si128(_mm_or_si128(m1, m2), _mm_or_si128(m4, m5)); |
8671 | 8.78k | int mask = _mm_movemask_epi8(m); |
8672 | 8.78k | if (mask != 0) { |
8673 | 2.41k | return i + trailing_zeroes(mask); |
8674 | 2.41k | } |
8675 | 8.78k | } |
8676 | 614 | if (i < view.size()) { |
8677 | 447 | __m128i word = |
8678 | 447 | _mm_loadu_si128((const __m128i*)(view.data() + view.length() - 16)); |
8679 | 447 | __m128i m1 = _mm_cmpeq_epi8(word, mask1); |
8680 | 447 | __m128i m2 = _mm_cmpeq_epi8(word, mask2); |
8681 | 447 | __m128i m4 = _mm_cmpeq_epi8(word, mask4); |
8682 | 447 | __m128i m5 = _mm_cmpeq_epi8(word, mask5); |
8683 | 447 | __m128i m = _mm_or_si128(_mm_or_si128(m1, m2), _mm_or_si128(m4, m5)); |
8684 | 447 | int mask = _mm_movemask_epi8(m); |
8685 | 447 | if (mask != 0) { |
8686 | 178 | return view.length() - 16 + trailing_zeroes(mask); |
8687 | 178 | } |
8688 | 447 | } |
8689 | 436 | return size_t(view.length()); |
8690 | 614 | } |
8691 | | #elif ADA_LSX |
8692 | | ada_really_inline size_t find_next_host_delimiter(std::string_view view, |
8693 | | size_t location) noexcept { |
8694 | | // first check for short strings in which case we do it naively. |
8695 | | if (view.size() - location < 16) { // slow path |
8696 | | for (size_t i = location; i < view.size(); i++) { |
8697 | | if (view[i] == ':' || view[i] == '/' || view[i] == '?' || |
8698 | | view[i] == '[') { |
8699 | | return i; |
8700 | | } |
8701 | | } |
8702 | | return size_t(view.size()); |
8703 | | } |
8704 | | // fast path for long strings (expected to be common) |
8705 | | size_t i = location; |
8706 | | const __m128i mask1 = __lsx_vrepli_b(':'); |
8707 | | const __m128i mask2 = __lsx_vrepli_b('/'); |
8708 | | const __m128i mask4 = __lsx_vrepli_b('?'); |
8709 | | const __m128i mask5 = __lsx_vrepli_b('['); |
8710 | | |
8711 | | for (; i + 15 < view.size(); i += 16) { |
8712 | | __m128i word = __lsx_vld((const __m128i*)(view.data() + i), 0); |
8713 | | __m128i m1 = __lsx_vseq_b(word, mask1); |
8714 | | __m128i m2 = __lsx_vseq_b(word, mask2); |
8715 | | __m128i m4 = __lsx_vseq_b(word, mask4); |
8716 | | __m128i m5 = __lsx_vseq_b(word, mask5); |
8717 | | __m128i m = __lsx_vor_v(__lsx_vor_v(m1, m2), __lsx_vor_v(m4, m5)); |
8718 | | int mask = __lsx_vpickve2gr_hu(__lsx_vmsknz_b(m), 0); |
8719 | | if (mask != 0) { |
8720 | | return i + trailing_zeroes(mask); |
8721 | | } |
8722 | | } |
8723 | | if (i < view.size()) { |
8724 | | __m128i word = |
8725 | | __lsx_vld((const __m128i*)(view.data() + view.length() - 16), 0); |
8726 | | __m128i m1 = __lsx_vseq_b(word, mask1); |
8727 | | __m128i m2 = __lsx_vseq_b(word, mask2); |
8728 | | __m128i m4 = __lsx_vseq_b(word, mask4); |
8729 | | __m128i m5 = __lsx_vseq_b(word, mask5); |
8730 | | __m128i m = __lsx_vor_v(__lsx_vor_v(m1, m2), __lsx_vor_v(m4, m5)); |
8731 | | int mask = __lsx_vpickve2gr_hu(__lsx_vmsknz_b(m), 0); |
8732 | | if (mask != 0) { |
8733 | | return view.length() - 16 + trailing_zeroes(mask); |
8734 | | } |
8735 | | } |
8736 | | return size_t(view.length()); |
8737 | | } |
8738 | | #elif ADA_RVV |
8739 | | ada_really_inline size_t find_next_host_delimiter(std::string_view view, |
8740 | | size_t location) noexcept { |
8741 | | uint8_t* src = (uint8_t*)view.data() + location; |
8742 | | for (size_t vl, n = view.size() - location; n > 0; |
8743 | | n -= vl, src += vl, location += vl) { |
8744 | | vl = __riscv_vsetvl_e8m1(n); |
8745 | | vuint8m1_t v = __riscv_vle8_v_u8m1(src, vl); |
8746 | | vbool8_t m1 = __riscv_vmseq(v, ':', vl); |
8747 | | vbool8_t m2 = __riscv_vmseq(v, '/', vl); |
8748 | | vbool8_t m3 = __riscv_vmseq(v, '?', vl); |
8749 | | vbool8_t m4 = __riscv_vmseq(v, '[', vl); |
8750 | | vbool8_t m = |
8751 | | __riscv_vmor(__riscv_vmor(m1, m2, vl), __riscv_vmor(m3, m4, vl), vl); |
8752 | | long idx = __riscv_vfirst(m, vl); |
8753 | | if (idx >= 0) return location + idx; |
8754 | | } |
8755 | | return size_t(view.size()); |
8756 | | } |
8757 | | #else |
8758 | | // : / [ ? |
8759 | | static constexpr std::array<uint8_t, 256> host_delimiters = []() consteval { |
8760 | | std::array<uint8_t, 256> result{}; |
8761 | | for (int i : {':', '/', '?', '['}) { |
8762 | | result[i] = 1; |
8763 | | } |
8764 | | return result; |
8765 | | }(); |
8766 | | // credit: @the-moisrex recommended a table-based approach |
8767 | | ada_really_inline size_t find_next_host_delimiter(std::string_view view, |
8768 | | size_t location) noexcept { |
8769 | | auto const str = view.substr(location); |
8770 | | for (auto pos = str.begin(); pos != str.end(); ++pos) { |
8771 | | if (host_delimiters[(uint8_t)*pos]) { |
8772 | | return pos - str.begin() + location; |
8773 | | } |
8774 | | } |
8775 | | return size_t(view.size()); |
8776 | | } |
8777 | | #endif |
8778 | | |
8779 | | ada_really_inline std::pair<size_t, bool> get_host_delimiter_location( |
8780 | 187k | const bool is_special, std::string_view& view) noexcept { |
8781 | | /** |
8782 | | * The spec at https://url.spec.whatwg.org/#hostname-state expects us to |
8783 | | * compute a variable called insideBrackets but this variable is only used |
8784 | | * once, to check whether a ':' character was found outside brackets. Exact |
8785 | | * text: "Otherwise, if c is U+003A (:) and insideBrackets is false, then:". |
8786 | | * It is conceptually simpler and arguably more efficient to just return a |
8787 | | * Boolean indicating whether ':' was found outside brackets. |
8788 | | */ |
8789 | 187k | const size_t view_size = view.size(); |
8790 | 187k | size_t location = 0; |
8791 | 187k | bool found_colon = false; |
8792 | | /** |
8793 | | * Performance analysis: |
8794 | | * |
8795 | | * We are basically seeking the end of the hostname which can be indicated |
8796 | | * by the end of the view, or by one of the characters ':', '/', '?', '\\' |
8797 | | * (where '\\' is only applicable for special URLs). However, these must |
8798 | | * appear outside a bracket range. E.g., if you have [something?]fd: then the |
8799 | | * '?' does not count. |
8800 | | * |
8801 | | * So we can skip ahead to the next delimiter, as long as we include '[' in |
8802 | | * the set of delimiters, and that we handle it first. |
8803 | | * |
8804 | | * So the trick is to have a fast function that locates the next delimiter. |
8805 | | * Unless we find '[', then it only needs to be called once! Ideally, such a |
8806 | | * function would be provided by the C++ standard library, but it seems that |
8807 | | * find_first_of is not very fast, so we are forced to roll our own. |
8808 | | * |
8809 | | * We do not break into two loops for speed, but for clarity. |
8810 | | */ |
8811 | 187k | if (is_special) { |
8812 | | // We move to the next delimiter. |
8813 | 183k | location = find_next_host_delimiter_special(view, location); |
8814 | | // Unless we find '[' then we are going only going to have to call |
8815 | | // find_next_host_delimiter_special once. |
8816 | 186k | for (; location < view_size; |
8817 | 183k | location = find_next_host_delimiter_special(view, location)) { |
8818 | 106k | if (view[location] == '[') { |
8819 | 2.93k | location = view.find(']', location); |
8820 | 2.93k | if (location == std::string_view::npos) { |
8821 | | // performance: view.find might get translated to a memchr, which |
8822 | | // has no notion of std::string_view::npos, so the code does not |
8823 | | // reflect the assembly. |
8824 | 141 | location = view_size; |
8825 | 141 | break; |
8826 | 141 | } |
8827 | 103k | } else { |
8828 | 103k | found_colon = view[location] == ':'; |
8829 | 103k | break; |
8830 | 103k | } |
8831 | 106k | } |
8832 | 183k | } else { |
8833 | | // We move to the next delimiter. |
8834 | 3.73k | location = find_next_host_delimiter(view, location); |
8835 | | // Unless we find '[' then we are going only going to have to call |
8836 | | // find_next_host_delimiter_special once. |
8837 | 5.54k | for (; location < view_size; |
8838 | 3.73k | location = find_next_host_delimiter(view, location)) { |
8839 | 3.54k | if (view[location] == '[') { |
8840 | 1.86k | location = view.find(']', location); |
8841 | 1.86k | if (location == std::string_view::npos) { |
8842 | | // performance: view.find might get translated to a memchr, which |
8843 | | // has no notion of std::string_view::npos, so the code does not |
8844 | | // reflect the assembly. |
8845 | 52 | location = view_size; |
8846 | 52 | break; |
8847 | 52 | } |
8848 | 1.86k | } else { |
8849 | 1.68k | found_colon = view[location] == ':'; |
8850 | 1.68k | break; |
8851 | 1.68k | } |
8852 | 3.54k | } |
8853 | 3.73k | } |
8854 | | // performance: remove_suffix may translate into a single instruction. |
8855 | 187k | view.remove_suffix(view_size - location); |
8856 | 187k | return {location, found_colon}; |
8857 | 187k | } |
8858 | | |
8859 | 188k | void trim_c0_whitespace(std::string_view& input) noexcept { |
8860 | 196k | while (!input.empty() && |
8861 | 183k | ada::unicode::is_c0_control_or_space(input.front())) { |
8862 | 7.59k | input.remove_prefix(1); |
8863 | 7.59k | } |
8864 | 196k | while (!input.empty() && ada::unicode::is_c0_control_or_space(input.back())) { |
8865 | 8.47k | input.remove_suffix(1); |
8866 | 8.47k | } |
8867 | 188k | } |
8868 | | |
8869 | | ada_really_inline void parse_prepared_path(std::string_view input, |
8870 | | ada::scheme::type type, |
8871 | 0 | std::string& path) { |
8872 | 0 | ada_log("parse_prepared_path ", input); |
8873 | 0 | uint8_t accumulator = checkers::path_signature(input); |
8874 | | // Let us first detect a trivial case. |
8875 | | // If it is special, we check that we have no dot, no %, no \ and no |
8876 | | // character needing percent encoding. Otherwise, we check that we have no %, |
8877 | | // no dot, and no character needing percent encoding. |
8878 | 0 | constexpr uint8_t need_encoding = 1; |
8879 | 0 | constexpr uint8_t backslash_char = 2; |
8880 | 0 | constexpr uint8_t dot_char = 4; |
8881 | 0 | constexpr uint8_t percent_char = 8; |
8882 | 0 | bool special = type != ada::scheme::NOT_SPECIAL; |
8883 | 0 | bool may_need_slow_file_handling = (type == ada::scheme::type::FILE && |
8884 | 0 | checkers::is_windows_drive_letter(input)); |
8885 | 0 | bool trivial_path = |
8886 | 0 | (special ? (accumulator == 0) |
8887 | 0 | : ((accumulator & (need_encoding | dot_char | percent_char)) == |
8888 | 0 | 0)) && |
8889 | 0 | (!may_need_slow_file_handling); |
8890 | 0 | if (accumulator == dot_char && !may_need_slow_file_handling) { |
8891 | | // '4' means that we have at least one dot, but nothing that requires |
8892 | | // percent encoding or decoding. The only part that is not trivial is |
8893 | | // that we may have single dots and double dots path segments. |
8894 | | // If we have such segments, then we either have a path that begins |
8895 | | // with '.' (easy to check), or we have the sequence './'. |
8896 | | // Note: input cannot be empty, it must at least contain one character ('.') |
8897 | | // Note: we know that '\' is not present. |
8898 | 0 | if (input[0] != '.') { |
8899 | 0 | size_t slashdot = 0; |
8900 | 0 | bool dot_is_file = true; |
8901 | 0 | for (;;) { |
8902 | 0 | slashdot = input.find("/.", slashdot); |
8903 | 0 | if (slashdot == std::string_view::npos) { // common case |
8904 | 0 | break; |
8905 | 0 | } else { // uncommon |
8906 | | // only three cases matter: /./, /.. or a final / |
8907 | 0 | slashdot += 2; |
8908 | 0 | dot_is_file &= !(slashdot == input.size() || input[slashdot] == '.' || |
8909 | 0 | input[slashdot] == '/'); |
8910 | 0 | } |
8911 | 0 | } |
8912 | 0 | trivial_path = dot_is_file; |
8913 | 0 | } |
8914 | 0 | } |
8915 | 0 | if (trivial_path) { |
8916 | 0 | ada_log("parse_path trivial"); |
8917 | 0 | path += '/'; |
8918 | 0 | path += input; |
8919 | 0 | return; |
8920 | 0 | } |
8921 | | // We are going to need to look a bit at the path, but let us see if we can |
8922 | | // ignore percent encoding *and* backslashes *and* percent characters. |
8923 | | // Except for the trivial case, this is likely to capture 99% of paths out |
8924 | | // there. |
8925 | 0 | bool fast_path = |
8926 | 0 | (special && |
8927 | 0 | (accumulator & (need_encoding | backslash_char | percent_char)) == 0) && |
8928 | 0 | (type != ada::scheme::type::FILE); |
8929 | 0 | if (fast_path) { |
8930 | 0 | ada_log("parse_prepared_path fast"); |
8931 | | // Here we don't need to worry about \ or percent encoding. |
8932 | | // We also do not have a file protocol. We might have dots, however, |
8933 | | // but dots must as appear as '.', and they cannot be encoded because |
8934 | | // the symbol '%' is not present. |
8935 | 0 | size_t previous_location = 0; // We start at 0. |
8936 | 0 | do { |
8937 | 0 | size_t new_location = input.find('/', previous_location); |
8938 | | // std::string_view path_view = input; |
8939 | | // We process the last segment separately: |
8940 | 0 | if (new_location == std::string_view::npos) { |
8941 | 0 | std::string_view path_view = input.substr(previous_location); |
8942 | 0 | if (path_view == "..") { // The path ends with .. |
8943 | | // e.g., if you receive ".." with an empty path, you go to "/". |
8944 | 0 | if (path.empty()) { |
8945 | 0 | path = '/'; |
8946 | 0 | return; |
8947 | 0 | } |
8948 | | // Fast case where we have nothing to do: |
8949 | 0 | if (path.back() == '/') { |
8950 | 0 | return; |
8951 | 0 | } |
8952 | | // If you have the path "/joe/myfriend", |
8953 | | // then you delete 'myfriend'. |
8954 | 0 | path.resize(path.rfind('/') + 1); |
8955 | 0 | return; |
8956 | 0 | } |
8957 | 0 | path += '/'; |
8958 | 0 | if (path_view != ".") { |
8959 | 0 | path.append(path_view); |
8960 | 0 | } |
8961 | 0 | return; |
8962 | 0 | } else { |
8963 | | // This is a non-final segment. |
8964 | 0 | std::string_view path_view = |
8965 | 0 | input.substr(previous_location, new_location - previous_location); |
8966 | 0 | previous_location = new_location + 1; |
8967 | 0 | if (path_view == "..") { |
8968 | 0 | size_t last_delimiter = path.rfind('/'); |
8969 | 0 | if (last_delimiter != std::string::npos) { |
8970 | 0 | path.erase(last_delimiter); |
8971 | 0 | } |
8972 | 0 | } else if (path_view != ".") { |
8973 | 0 | path += '/'; |
8974 | 0 | path.append(path_view); |
8975 | 0 | } |
8976 | 0 | } |
8977 | 0 | } while (true); |
8978 | 0 | } else { |
8979 | 0 | ada_log("parse_path slow"); |
8980 | | // we have reached the general case |
8981 | 0 | bool needs_percent_encoding = (accumulator & 1); |
8982 | 0 | std::string path_buffer_tmp; |
8983 | 0 | do { |
8984 | 0 | size_t location = (special && (accumulator & 2)) |
8985 | 0 | ? input.find_first_of("/\\") |
8986 | 0 | : input.find('/'); |
8987 | 0 | std::string_view path_view = input; |
8988 | 0 | if (location != std::string_view::npos) { |
8989 | 0 | path_view.remove_suffix(path_view.size() - location); |
8990 | 0 | input.remove_prefix(location + 1); |
8991 | 0 | } |
8992 | | // path_buffer is either path_view or it might point at a percent encoded |
8993 | | // temporary file. |
8994 | 0 | std::string_view path_buffer = |
8995 | 0 | (needs_percent_encoding && |
8996 | 0 | ada::unicode::percent_encode<false>( |
8997 | 0 | path_view, character_sets::PATH_PERCENT_ENCODE, path_buffer_tmp)) |
8998 | 0 | ? path_buffer_tmp |
8999 | 0 | : path_view; |
9000 | 0 | if (unicode::is_double_dot_path_segment(path_buffer)) { |
9001 | 0 | helpers::shorten_path(path, type); |
9002 | 0 | if (location == std::string_view::npos) { |
9003 | 0 | path += '/'; |
9004 | 0 | } |
9005 | 0 | } else if (unicode::is_single_dot_path_segment(path_buffer) && |
9006 | 0 | (location == std::string_view::npos)) { |
9007 | 0 | path += '/'; |
9008 | 0 | } |
9009 | | // Otherwise, if path_buffer is not a single-dot path segment, then: |
9010 | 0 | else if (!unicode::is_single_dot_path_segment(path_buffer)) { |
9011 | | // If url's scheme is "file", url's path is empty, and path_buffer is a |
9012 | | // Windows drive letter, then replace the second code point in |
9013 | | // path_buffer with U+003A (:). |
9014 | 0 | if (type == ada::scheme::type::FILE && path.empty() && |
9015 | 0 | checkers::is_windows_drive_letter(path_buffer)) { |
9016 | 0 | path += '/'; |
9017 | 0 | path += path_buffer[0]; |
9018 | 0 | path += ':'; |
9019 | 0 | path_buffer.remove_prefix(2); |
9020 | 0 | path.append(path_buffer); |
9021 | 0 | } else { |
9022 | | // Append path_buffer to url's path. |
9023 | 0 | path += '/'; |
9024 | 0 | path.append(path_buffer); |
9025 | 0 | } |
9026 | 0 | } |
9027 | 0 | if (location == std::string_view::npos) { |
9028 | 0 | return; |
9029 | 0 | } |
9030 | 0 | } while (true); |
9031 | 0 | } |
9032 | 0 | } |
9033 | | |
9034 | 0 | bool overlaps(std::string_view input1, const std::string& input2) noexcept { |
9035 | 0 | ada_log("helpers::overlaps check if string_view '", input1, "' [", |
9036 | 0 | input1.size(), " bytes] is part of string '", input2, "' [", |
9037 | 0 | input2.size(), " bytes]"); |
9038 | 0 | return !input1.empty() && !input2.empty() && input1.data() >= input2.data() && |
9039 | 0 | input1.data() < input2.data() + input2.size(); |
9040 | 0 | } |
9041 | | |
9042 | | template <class url_type> |
9043 | 4.42k | ada_really_inline void strip_trailing_spaces_from_opaque_path(url_type& url) { |
9044 | 4.42k | ada_log("helpers::strip_trailing_spaces_from_opaque_path"); |
9045 | 4.42k | if (!url.has_opaque_path) return; |
9046 | 648 | if (url.has_hash()) return; |
9047 | 607 | if (url.has_search()) return; |
9048 | | |
9049 | 607 | auto path = std::string(url.get_pathname()); |
9050 | 607 | while (!path.empty() && path.back() == ' ') { |
9051 | 0 | path.resize(path.size() - 1); |
9052 | 0 | } |
9053 | 607 | url.update_base_pathname(path); |
9054 | 607 | } Unexecuted instantiation: void ada::helpers::strip_trailing_spaces_from_opaque_path<ada::url>(ada::url&) void ada::helpers::strip_trailing_spaces_from_opaque_path<ada::url_aggregator>(ada::url_aggregator&) Line | Count | Source | 9043 | 4.42k | ada_really_inline void strip_trailing_spaces_from_opaque_path(url_type& url) { | 9044 | 4.42k | ada_log("helpers::strip_trailing_spaces_from_opaque_path"); | 9045 | 4.42k | if (!url.has_opaque_path) return; | 9046 | 648 | if (url.has_hash()) return; | 9047 | 607 | if (url.has_search()) return; | 9048 | | | 9049 | 607 | auto path = std::string(url.get_pathname()); | 9050 | 607 | while (!path.empty() && path.back() == ' ') { | 9051 | 0 | path.resize(path.size() - 1); | 9052 | 0 | } | 9053 | 607 | url.update_base_pathname(path); | 9054 | 607 | } |
|
9055 | | |
9056 | | // @ / \\ ? |
9057 | | static constexpr std::array<uint8_t, 256> authority_delimiter_special = |
9058 | | []() consteval { |
9059 | | std::array<uint8_t, 256> result{}; |
9060 | | for (uint8_t i : {'@', '/', '\\', '?'}) { |
9061 | | result[i] = 1; |
9062 | | } |
9063 | | return result; |
9064 | | }(); |
9065 | | // credit: @the-moisrex recommended a table-based approach |
9066 | | ada_really_inline size_t |
9067 | 160k | find_authority_delimiter_special(std::string_view view) noexcept { |
9068 | | // performance note: we might be able to gain further performance |
9069 | | // with SIMD intrinsics. |
9070 | 1.33M | for (auto pos = view.begin(); pos != view.end(); ++pos) { |
9071 | 1.33M | if (authority_delimiter_special[(uint8_t)*pos]) { |
9072 | 159k | return pos - view.begin(); |
9073 | 159k | } |
9074 | 1.33M | } |
9075 | 1.09k | return size_t(view.size()); |
9076 | 160k | } |
9077 | | |
9078 | | // @ / ? |
9079 | | static constexpr std::array<uint8_t, 256> authority_delimiter = []() consteval { |
9080 | | std::array<uint8_t, 256> result{}; |
9081 | | for (uint8_t i : {'@', '/', '?'}) { |
9082 | | result[i] = 1; |
9083 | | } |
9084 | | return result; |
9085 | | }(); |
9086 | | // credit: @the-moisrex recommended a table-based approach |
9087 | | ada_really_inline size_t |
9088 | 5.63k | find_authority_delimiter(std::string_view view) noexcept { |
9089 | | // performance note: we might be able to gain further performance |
9090 | | // with SIMD instrinsics. |
9091 | 177k | for (auto pos = view.begin(); pos != view.end(); ++pos) { |
9092 | 177k | if (authority_delimiter[(uint8_t)*pos]) { |
9093 | 5.39k | return pos - view.begin(); |
9094 | 5.39k | } |
9095 | 177k | } |
9096 | 240 | return size_t(view.size()); |
9097 | 5.63k | } |
9098 | | |
9099 | | } // namespace ada::helpers |
9100 | | |
9101 | | namespace ada { |
9102 | 0 | ada_warn_unused std::string to_string(ada::state state) { |
9103 | 0 | return ada::helpers::get_state(state); |
9104 | 0 | } |
9105 | | #undef ada_make_uint8x16_t |
9106 | | } // namespace ada |
9107 | | /* end file src/helpers.cpp */ |
9108 | | /* begin file src/url.cpp */ |
9109 | | /* begin file include/ada/url_ip-inl.h */ |
9110 | | /** |
9111 | | * @file url_ip-inl.h |
9112 | | * @brief Shared IPv4/IPv6 parsing helpers used by url and url_aggregator. |
9113 | | * |
9114 | | * Not part of the public API. Defined inline so the single-TU amalgamation |
9115 | | * (ada.cpp) can include them from multiple translation-unit sources once. |
9116 | | */ |
9117 | | #ifndef ADA_URL_IP_INL_H |
9118 | | #define ADA_URL_IP_INL_H |
9119 | | |
9120 | | |
9121 | | #include <array> |
9122 | | #include <cstdint> |
9123 | | |
9124 | | #if defined(ADA_AVX512) |
9125 | | #include <immintrin.h> |
9126 | | #endif |
9127 | | |
9128 | | namespace ada::detail { |
9129 | | |
9130 | | // 256-entry: 0xff = not hex, else nibble value. |
9131 | 0 | inline constexpr std::array<uint8_t, 256> make_hex_nibble_table() noexcept { |
9132 | 0 | std::array<uint8_t, 256> t{}; |
9133 | 0 | for (size_t i = 0; i < 256; ++i) { |
9134 | 0 | t[i] = 0xff; |
9135 | 0 | } |
9136 | 0 | for (size_t d = 0; d < 10; ++d) { |
9137 | 0 | t[size_t{'0'} + d] = static_cast<uint8_t>(d); |
9138 | 0 | } |
9139 | 0 | for (size_t d = 0; d < 6; ++d) { |
9140 | 0 | t[size_t{'a'} + d] = static_cast<uint8_t>(10 + d); |
9141 | 0 | t[size_t{'A'} + d] = static_cast<uint8_t>(10 + d); |
9142 | 0 | } |
9143 | 0 | return t; |
9144 | 0 | } |
9145 | | |
9146 | | inline constexpr auto hex_nibble = make_hex_nibble_table(); |
9147 | | |
9148 | | inline bool parse_ipv4_number(const char*& p, const char* end, uint64_t& value, |
9149 | 6.32k | bool& is_pure_decimal) noexcept { |
9150 | 6.32k | is_pure_decimal = false; |
9151 | 6.32k | if (p >= end) [[unlikely]] { |
9152 | 0 | return false; |
9153 | 0 | } |
9154 | 6.32k | if (end - p >= 2 && p[0] == '0' && ((p[1] | 0x20) == 'x')) { |
9155 | 2.06k | p += 2; |
9156 | 2.06k | if (p == end || *p == '.') { |
9157 | 190 | value = 0; |
9158 | 190 | return true; |
9159 | 190 | } |
9160 | 1.87k | uint64_t v = 0; |
9161 | 1.87k | int digits = 0; |
9162 | 9.96k | while (p < end && *p != '.') { |
9163 | 8.39k | const uint8_t nib = hex_nibble[static_cast<unsigned char>(*p)]; |
9164 | 8.39k | if (nib == 0xff) [[unlikely]] { |
9165 | 21 | return false; |
9166 | 21 | } |
9167 | 8.37k | if (v > (0xFFFFFFFFULL >> 4)) [[unlikely]] { |
9168 | 285 | return false; |
9169 | 285 | } |
9170 | 8.08k | v = (v << 4) | nib; |
9171 | 8.08k | ++p; |
9172 | 8.08k | ++digits; |
9173 | 8.08k | } |
9174 | 1.56k | if (digits == 0) [[unlikely]] { |
9175 | 0 | return false; |
9176 | 0 | } |
9177 | 1.56k | value = v; |
9178 | 1.56k | return true; |
9179 | 1.56k | } |
9180 | 4.26k | if (end - p >= 2 && p[0] == '0' && p[1] >= '0' && p[1] <= '9') { |
9181 | 367 | ++p; |
9182 | 367 | uint64_t v = 0; |
9183 | 2.66k | while (p < end && *p != '.') { |
9184 | 2.37k | const char c = *p; |
9185 | 2.37k | if (c < '0' || c > '7') [[unlikely]] { |
9186 | 46 | return false; |
9187 | 46 | } |
9188 | 2.33k | if (v > (0xFFFFFFFFULL >> 3)) [[unlikely]] { |
9189 | 32 | return false; |
9190 | 32 | } |
9191 | 2.30k | v = (v << 3) | static_cast<uint64_t>(c - '0'); |
9192 | 2.30k | ++p; |
9193 | 2.30k | } |
9194 | 289 | value = v; |
9195 | 289 | return true; |
9196 | 367 | } |
9197 | 3.89k | if (*p < '0' || *p > '9') [[unlikely]] { |
9198 | 231 | return false; |
9199 | 231 | } |
9200 | 3.66k | is_pure_decimal = true; |
9201 | 3.66k | uint64_t v = static_cast<uint64_t>(*p - '0'); |
9202 | 3.66k | ++p; |
9203 | 8.35k | while (p < end && *p != '.') { |
9204 | 4.87k | const char c = *p; |
9205 | 4.87k | if (c < '0' || c > '9') [[unlikely]] { |
9206 | 103 | return false; |
9207 | 103 | } |
9208 | 4.76k | if (v > 429496729ULL) [[unlikely]] { |
9209 | 66 | return false; |
9210 | 66 | } |
9211 | 4.70k | v = v * 10u + static_cast<uint64_t>(c - '0'); |
9212 | 4.70k | if (v > 0xFFFFFFFFULL) [[unlikely]] { |
9213 | 12 | return false; |
9214 | 12 | } |
9215 | 4.68k | ++p; |
9216 | 4.68k | } |
9217 | 3.48k | value = v; |
9218 | 3.48k | return true; |
9219 | 3.66k | } |
9220 | | |
9221 | | // Parse up to 4 hex digits. Returns digit count (0 if none). |
9222 | | inline int parse_hex_piece(const char*& pointer, const char* end, |
9223 | 3.57k | uint16_t& value) noexcept { |
9224 | 3.57k | if (pointer == end) { |
9225 | 0 | return 0; |
9226 | 0 | } |
9227 | 3.57k | const uint8_t n0 = hex_nibble[static_cast<unsigned char>(*pointer)]; |
9228 | 3.57k | if (n0 == 0xff) { |
9229 | 112 | return 0; |
9230 | 112 | } |
9231 | 3.45k | uint32_t v = n0; |
9232 | 3.45k | ++pointer; |
9233 | 3.45k | int length = 1; |
9234 | 3.45k | if (pointer != end) { |
9235 | 2.28k | const uint8_t n1 = hex_nibble[static_cast<unsigned char>(*pointer)]; |
9236 | 2.28k | if (n1 != 0xff) { |
9237 | 989 | v = (v << 4) | n1; |
9238 | 989 | ++pointer; |
9239 | 989 | ++length; |
9240 | 989 | if (pointer != end) { |
9241 | 906 | const uint8_t n2 = hex_nibble[static_cast<unsigned char>(*pointer)]; |
9242 | 906 | if (n2 != 0xff) { |
9243 | 466 | v = (v << 4) | n2; |
9244 | 466 | ++pointer; |
9245 | 466 | ++length; |
9246 | 466 | if (pointer != end) { |
9247 | 362 | const uint8_t n3 = hex_nibble[static_cast<unsigned char>(*pointer)]; |
9248 | 362 | if (n3 != 0xff) { |
9249 | 185 | v = (v << 4) | n3; |
9250 | 185 | ++pointer; |
9251 | 185 | ++length; |
9252 | 185 | } |
9253 | 362 | } |
9254 | 466 | } |
9255 | 906 | } |
9256 | 989 | } |
9257 | 2.28k | } |
9258 | 3.45k | value = static_cast<uint16_t>(v); |
9259 | 3.45k | return length; |
9260 | 3.57k | } |
9261 | | |
9262 | | #if defined(ADA_AVX512) |
9263 | | // Classify an IPv6 host (no brackets) with one masked 512-bit load. |
9264 | | // Returns false if the colon/dot shape is impossible (e.g. two "::", >8 |
9265 | | // colons, full form without 7 colons). Used as a cheap prefilter before the |
9266 | | // full WHATWG piece parser. |
9267 | | ada_really_inline bool ipv6_structure_plausible(const char* data, |
9268 | | size_t len) noexcept { |
9269 | | if (len < 2 || len > 45) { |
9270 | | return false; |
9271 | | } |
9272 | | const __mmask64 live = static_cast<__mmask64>((1ULL << len) - 1ULL); |
9273 | | const __m512i input = |
9274 | | _mm512_maskz_loadu_epi8(live, reinterpret_cast<const void*>(data)); |
9275 | | const __mmask64 is_colon = |
9276 | | _mm512_mask_cmpeq_epi8_mask(live, input, _mm512_set1_epi8(':')); |
9277 | | const __mmask64 is_dot = |
9278 | | _mm512_mask_cmpeq_epi8_mask(live, input, _mm512_set1_epi8('.')); |
9279 | | const int colons = |
9280 | | static_cast<int>(_mm_popcnt_u64(static_cast<uint64_t>(is_colon))); |
9281 | | if (colons > 8) { |
9282 | | return false; |
9283 | | } |
9284 | | const uint64_t doubles = |
9285 | | static_cast<uint64_t>(is_colon) & (static_cast<uint64_t>(is_colon) << 1); |
9286 | | if (doubles != 0 && (doubles & (doubles - 1)) != 0) { |
9287 | | return false; // more than one "::" (or ":::...") |
9288 | | } |
9289 | | const bool has_double = doubles != 0; |
9290 | | const bool has_dot = is_dot != 0; |
9291 | | if (!has_double && !has_dot && colons != 7) { |
9292 | | return false; |
9293 | | } |
9294 | | return true; |
9295 | | } |
9296 | | #endif // ADA_AVX512 |
9297 | | |
9298 | | } // namespace ada::detail |
9299 | | |
9300 | | #endif // ADA_URL_IP_INL_H |
9301 | | /* end file include/ada/url_ip-inl.h */ |
9302 | | |
9303 | | #include <algorithm> |
9304 | | #include <array> |
9305 | | #include <cstdint> |
9306 | | #include <iterator> |
9307 | | #include <numeric> |
9308 | | #include <ranges> |
9309 | | #include <string> |
9310 | | #include <string_view> |
9311 | | |
9312 | | namespace ada { |
9313 | | |
9314 | 0 | bool url::parse_opaque_host(std::string_view input) { |
9315 | 0 | ada_log("parse_opaque_host ", input, " [", input.size(), " bytes]"); |
9316 | 0 | if (std::ranges::any_of(input, ada::unicode::is_forbidden_host_code_point)) { |
9317 | 0 | return is_valid = false; |
9318 | 0 | } |
9319 | | |
9320 | | // Return the result of running UTF-8 percent-encode on input using the C0 |
9321 | | // control percent-encode set. |
9322 | 0 | host = ada::unicode::percent_encode( |
9323 | 0 | input, ada::character_sets::C0_CONTROL_PERCENT_ENCODE); |
9324 | 0 | return true; |
9325 | 0 | } |
9326 | | |
9327 | 0 | bool url::parse_ipv4(std::string_view input) { |
9328 | 0 | ada_log("parse_ipv4 ", input, " [", input.size(), " bytes]"); |
9329 | 0 | if (input.empty()) { |
9330 | 0 | return is_valid = false; |
9331 | 0 | } |
9332 | 0 | std::string_view original_input = input; |
9333 | 0 | if (original_input.back() == '.') { |
9334 | 0 | original_input.remove_suffix(1); |
9335 | 0 | } |
9336 | 0 | if (input.back() == '.') { |
9337 | 0 | input.remove_suffix(1); |
9338 | 0 | if (input.empty()) { |
9339 | 0 | return is_valid = false; |
9340 | 0 | } |
9341 | 0 | } |
9342 | | |
9343 | 0 | const uint64_t fast = checkers::try_parse_ipv4_fast(input); |
9344 | 0 | if (fast < checkers::ipv4_fast_fail) [[likely]] { |
9345 | 0 | host = original_input; |
9346 | 0 | host_type = IPV4; |
9347 | 0 | return true; |
9348 | 0 | } |
9349 | | |
9350 | 0 | const char* p = input.data(); |
9351 | 0 | const char* end = p + input.size(); |
9352 | 0 | uint64_t ipv4 = 0; |
9353 | 0 | int digit_count = 0; |
9354 | 0 | int pure_decimal_count = 0; |
9355 | |
|
9356 | 0 | for (; digit_count < 4 && p < end; ++digit_count) { |
9357 | 0 | uint64_t segment = 0; |
9358 | 0 | bool pure = false; |
9359 | 0 | if (!detail::parse_ipv4_number(p, end, segment, pure)) { |
9360 | 0 | return is_valid = false; |
9361 | 0 | } |
9362 | 0 | if (pure) { |
9363 | 0 | ++pure_decimal_count; |
9364 | 0 | } |
9365 | 0 | if (p >= end) { |
9366 | 0 | const unsigned shift = static_cast<unsigned>(32 - digit_count * 8); |
9367 | 0 | if (segment >= (uint64_t{1} << shift)) { |
9368 | 0 | return is_valid = false; |
9369 | 0 | } |
9370 | 0 | ipv4 = (ipv4 << shift) | segment; |
9371 | 0 | host = (pure_decimal_count == 4) ? std::string(original_input) |
9372 | 0 | : ada::serializers::ipv4(ipv4); |
9373 | 0 | host_type = IPV4; |
9374 | 0 | return true; |
9375 | 0 | } |
9376 | 0 | if (segment > 255 || *p != '.') { |
9377 | 0 | return is_valid = false; |
9378 | 0 | } |
9379 | 0 | ipv4 = (ipv4 << 8) | segment; |
9380 | 0 | ++p; |
9381 | 0 | } |
9382 | 0 | if (digit_count != 4 || p != end) { |
9383 | 0 | return is_valid = false; |
9384 | 0 | } |
9385 | 0 | host = (pure_decimal_count == 4) ? std::string(original_input) |
9386 | 0 | : ada::serializers::ipv4(ipv4); |
9387 | 0 | host_type = IPV4; |
9388 | 0 | return true; |
9389 | 0 | } |
9390 | | |
9391 | 0 | bool url::parse_ipv6(std::string_view input) { |
9392 | 0 | ada_log("parse_ipv6 ", input, " [", input.size(), " bytes]"); |
9393 | 0 | if (input.empty() || input.size() > 45) [[unlikely]] { |
9394 | 0 | return is_valid = false; |
9395 | 0 | } |
9396 | | #if defined(ADA_AVX512) |
9397 | | // One masked load classifies colon/dot shape; rejects impossible inputs |
9398 | | // before the piece parser (free on AVX-512BW+VL builds). |
9399 | | if (!detail::ipv6_structure_plausible(input.data(), input.size())) |
9400 | | [[unlikely]] { |
9401 | | return is_valid = false; |
9402 | | } |
9403 | | #endif |
9404 | | |
9405 | 0 | std::array<uint16_t, 8> address{}; |
9406 | 0 | const char* pointer = input.data(); |
9407 | 0 | const char* const end = pointer + input.size(); |
9408 | 0 | int piece_index = 0; |
9409 | 0 | int compress = -1; |
9410 | |
|
9411 | 0 | if (*pointer == ':') { |
9412 | 0 | if (input.size() == 1 || pointer[1] != ':') [[unlikely]] { |
9413 | 0 | return is_valid = false; |
9414 | 0 | } |
9415 | 0 | pointer += 2; |
9416 | 0 | compress = ++piece_index; |
9417 | 0 | } |
9418 | | |
9419 | 0 | while (pointer != end) { |
9420 | 0 | if (piece_index == 8) [[unlikely]] { |
9421 | 0 | return is_valid = false; |
9422 | 0 | } |
9423 | 0 | if (*pointer == ':') { |
9424 | 0 | if (compress != -1) [[unlikely]] { |
9425 | 0 | return is_valid = false; |
9426 | 0 | } |
9427 | 0 | ++pointer; |
9428 | 0 | compress = ++piece_index; |
9429 | 0 | continue; |
9430 | 0 | } |
9431 | | |
9432 | 0 | uint16_t value = 0; |
9433 | 0 | const int length = detail::parse_hex_piece(pointer, end, value); |
9434 | |
|
9435 | 0 | if (pointer != end && *pointer == '.') { |
9436 | 0 | if (length == 0) [[unlikely]] { |
9437 | 0 | return is_valid = false; |
9438 | 0 | } |
9439 | 0 | pointer -= length; |
9440 | 0 | if (piece_index > 6) [[unlikely]] { |
9441 | 0 | return is_valid = false; |
9442 | 0 | } |
9443 | | |
9444 | 0 | int numbers_seen = 0; |
9445 | 0 | while (pointer != end) { |
9446 | 0 | int ipv4_piece = -1; |
9447 | 0 | if (numbers_seen > 0) { |
9448 | 0 | if (*pointer == '.' && numbers_seen < 4) { |
9449 | 0 | ++pointer; |
9450 | 0 | } else { |
9451 | 0 | return is_valid = false; |
9452 | 0 | } |
9453 | 0 | } |
9454 | 0 | if (pointer == end || *pointer < '0' || *pointer > '9') [[unlikely]] { |
9455 | 0 | return is_valid = false; |
9456 | 0 | } |
9457 | 0 | ipv4_piece = *pointer - '0'; |
9458 | 0 | ++pointer; |
9459 | 0 | if (pointer != end && *pointer >= '0' && *pointer <= '9') { |
9460 | 0 | if (ipv4_piece == 0) [[unlikely]] { |
9461 | 0 | return is_valid = false; |
9462 | 0 | } |
9463 | 0 | ipv4_piece = ipv4_piece * 10 + (*pointer - '0'); |
9464 | 0 | ++pointer; |
9465 | 0 | if (pointer != end && *pointer >= '0' && *pointer <= '9') { |
9466 | 0 | ipv4_piece = ipv4_piece * 10 + (*pointer - '0'); |
9467 | 0 | ++pointer; |
9468 | 0 | if (ipv4_piece > 255) [[unlikely]] { |
9469 | 0 | return is_valid = false; |
9470 | 0 | } |
9471 | 0 | } |
9472 | 0 | } |
9473 | 0 | address[static_cast<size_t>(piece_index)] = static_cast<uint16_t>( |
9474 | 0 | address[static_cast<size_t>(piece_index)] * 0x100 + |
9475 | 0 | static_cast<uint16_t>(ipv4_piece)); |
9476 | 0 | ++numbers_seen; |
9477 | 0 | if (numbers_seen == 2 || numbers_seen == 4) { |
9478 | 0 | ++piece_index; |
9479 | 0 | } |
9480 | 0 | } |
9481 | 0 | if (numbers_seen != 4) [[unlikely]] { |
9482 | 0 | return is_valid = false; |
9483 | 0 | } |
9484 | 0 | break; |
9485 | 0 | } |
9486 | | |
9487 | 0 | if (length == 0) [[unlikely]] { |
9488 | 0 | return is_valid = false; |
9489 | 0 | } |
9490 | | |
9491 | 0 | if (pointer != end && *pointer == ':') { |
9492 | 0 | ++pointer; |
9493 | 0 | if (pointer == end) [[unlikely]] { |
9494 | 0 | return is_valid = false; |
9495 | 0 | } |
9496 | 0 | } else if (pointer != end) [[unlikely]] { |
9497 | 0 | return is_valid = false; |
9498 | 0 | } |
9499 | | |
9500 | 0 | address[static_cast<size_t>(piece_index)] = value; |
9501 | 0 | ++piece_index; |
9502 | 0 | } |
9503 | | |
9504 | 0 | if (compress != -1) { |
9505 | 0 | const int right = piece_index - compress; |
9506 | 0 | if (right > 0) { |
9507 | 0 | const size_t dest = static_cast<size_t>(8 - right); |
9508 | 0 | const size_t src = static_cast<size_t>(compress); |
9509 | 0 | if (dest != src) { |
9510 | 0 | for (size_t i = static_cast<size_t>(right); i-- > 0;) { |
9511 | 0 | address[dest + i] = address[src + i]; |
9512 | 0 | address[src + i] = 0; |
9513 | 0 | } |
9514 | 0 | } |
9515 | 0 | } |
9516 | 0 | } else if (piece_index != 8) [[unlikely]] { |
9517 | 0 | return is_valid = false; |
9518 | 0 | } |
9519 | | |
9520 | 0 | host = ada::serializers::ipv6(address); |
9521 | 0 | ada_log("parse_ipv6 ", *host); |
9522 | 0 | host_type = IPV6; |
9523 | 0 | return true; |
9524 | 0 | } |
9525 | | |
9526 | | template <bool has_state_override> |
9527 | 0 | ada_really_inline bool url::parse_scheme(const std::string_view input) { |
9528 | 0 | auto parsed_type = ada::scheme::get_scheme_type(input); |
9529 | 0 | bool is_input_special = (parsed_type != ada::scheme::NOT_SPECIAL); |
9530 | | /** |
9531 | | * In the common case, we will immediately recognize a special scheme (e.g., |
9532 | | *http, https), in which case, we can go really fast. |
9533 | | **/ |
9534 | 0 | if (is_input_special) { // fast path!!! |
9535 | 0 | if constexpr (has_state_override) { |
9536 | | // If url's scheme is not a special scheme and buffer is a special scheme, |
9537 | | // then return. |
9538 | 0 | if (is_special() != is_input_special) { |
9539 | 0 | return false; |
9540 | 0 | } |
9541 | | |
9542 | | // If url includes credentials or has a non-null port, and buffer is |
9543 | | // "file", then return. |
9544 | 0 | if ((has_credentials() || port.has_value()) && |
9545 | 0 | parsed_type == ada::scheme::type::FILE) { |
9546 | 0 | return false; |
9547 | 0 | } |
9548 | | |
9549 | | // If url's scheme is "file" and its host is an empty host, then return. |
9550 | | // An empty host is the empty string. |
9551 | 0 | if (type == ada::scheme::type::FILE && host.has_value() && |
9552 | 0 | host->empty()) { |
9553 | 0 | return false; |
9554 | 0 | } |
9555 | 0 | } |
9556 | | |
9557 | 0 | type = parsed_type; |
9558 | |
|
9559 | 0 | if constexpr (has_state_override) { |
9560 | | // This is uncommon. |
9561 | 0 | uint16_t urls_scheme_port = get_special_port(); |
9562 | |
|
9563 | 0 | if (urls_scheme_port) { |
9564 | | // If url's port is url's scheme's default port, then set url's port to |
9565 | | // null. |
9566 | 0 | if (port.has_value() && *port == urls_scheme_port) { |
9567 | 0 | port = std::nullopt; |
9568 | 0 | } |
9569 | 0 | } |
9570 | 0 | } |
9571 | 0 | } else { // slow path |
9572 | 0 | std::string _buffer(input); |
9573 | | // Next function is only valid if the input is ASCII and returns false |
9574 | | // otherwise, but it seems that we always have ascii content so we do not |
9575 | | // need to check the return value. |
9576 | | // bool is_ascii = |
9577 | 0 | unicode::to_lower_ascii(_buffer.data(), _buffer.size()); |
9578 | |
|
9579 | 0 | if constexpr (has_state_override) { |
9580 | | // The state-override validation errors below ("return" in the WHATWG URL |
9581 | | // parser) leave the URL unchanged. The setter contract is |
9582 | | // "true on success, false if the scheme is invalid" -- the fast path |
9583 | | // above already returns false here, so the slow path must agree. |
9584 | | |
9585 | | // If url's scheme is a special scheme and buffer is not a special scheme, |
9586 | | // then return. If url's scheme is not a special scheme and buffer is a |
9587 | | // special scheme, then return. |
9588 | 0 | if (is_special() != ada::scheme::is_special(_buffer)) { |
9589 | 0 | return false; |
9590 | 0 | } |
9591 | | |
9592 | | // If url includes credentials or has a non-null port, and buffer is |
9593 | | // "file", then return. |
9594 | 0 | if ((has_credentials() || port.has_value()) && _buffer == "file") { |
9595 | 0 | return false; |
9596 | 0 | } |
9597 | | |
9598 | | // If url's scheme is "file" and its host is an empty host, then return. |
9599 | | // An empty host is the empty string. |
9600 | 0 | if (type == ada::scheme::type::FILE && host.has_value() && |
9601 | 0 | host->empty()) { |
9602 | 0 | return false; |
9603 | 0 | } |
9604 | 0 | } |
9605 | | |
9606 | 0 | set_scheme(std::move(_buffer)); |
9607 | |
|
9608 | 0 | if constexpr (has_state_override) { |
9609 | | // This is uncommon. |
9610 | 0 | uint16_t urls_scheme_port = get_special_port(); |
9611 | |
|
9612 | 0 | if (urls_scheme_port) { |
9613 | | // If url's port is url's scheme's default port, then set url's port to |
9614 | | // null. |
9615 | 0 | if (port.has_value() && *port == urls_scheme_port) { |
9616 | 0 | port = std::nullopt; |
9617 | 0 | } |
9618 | 0 | } |
9619 | 0 | } |
9620 | 0 | } |
9621 | | |
9622 | 0 | return true; |
9623 | 0 | } Unexecuted instantiation: bool ada::url::parse_scheme<true>(std::__1::basic_string_view<char, std::__1::char_traits<char> >) Unexecuted instantiation: bool ada::url::parse_scheme<false>(std::__1::basic_string_view<char, std::__1::char_traits<char> >) |
9624 | | |
9625 | 0 | ada_really_inline bool url::parse_host(std::string_view input) { |
9626 | 0 | ada_log("parse_host ", input, " [", input.size(), " bytes]"); |
9627 | 0 | if (input.empty()) { |
9628 | 0 | return is_valid = false; |
9629 | 0 | } // technically unnecessary. |
9630 | | // If input starts with U+005B ([), then: |
9631 | 0 | if (input[0] == '[') { |
9632 | | // If input does not end with U+005D (]), validation error, return failure. |
9633 | 0 | if (input.back() != ']') { |
9634 | 0 | return is_valid = false; |
9635 | 0 | } |
9636 | 0 | ada_log("parse_host ipv6"); |
9637 | | |
9638 | | // Return the result of IPv6 parsing input with its leading U+005B ([) and |
9639 | | // trailing U+005D (]) removed. |
9640 | 0 | input.remove_prefix(1); |
9641 | 0 | input.remove_suffix(1); |
9642 | 0 | return parse_ipv6(input); |
9643 | 0 | } |
9644 | | |
9645 | | // If isNotSpecial is true, then return the result of opaque-host parsing |
9646 | | // input. |
9647 | 0 | if (!is_special()) { |
9648 | 0 | return parse_opaque_host(input); |
9649 | 0 | } |
9650 | | |
9651 | | // Fast path: try to parse as pure decimal IPv4(a.b.c.d) first. |
9652 | 0 | const uint64_t fast_result = checkers::try_parse_ipv4_fast(input); |
9653 | 0 | if (fast_result < checkers::ipv4_fast_fail) { |
9654 | | // Fast path succeeded - input is pure decimal IPv4 |
9655 | 0 | if (!input.empty() && input.back() == '.') { |
9656 | 0 | host = input.substr(0, input.size() - 1); |
9657 | 0 | } else { |
9658 | 0 | host = input; |
9659 | 0 | } |
9660 | 0 | host_type = IPV4; |
9661 | 0 | is_valid = true; |
9662 | 0 | ada_log("parse_host fast path decimal ipv4"); |
9663 | 0 | return true; |
9664 | 0 | } |
9665 | | // Let domain be the result of running UTF-8 decode without BOM on the |
9666 | | // percent-decoding of input. Let asciiDomain be the result of running domain |
9667 | | // to ASCII with domain and false. The most common case is an ASCII input, in |
9668 | | // which case we do not need to call the expensive 'to_ascii' if a few |
9669 | | // conditions are met: no '%' and no 'xn-' subsequence. |
9670 | 0 | std::string buffer = std::string(input); |
9671 | | // This next function checks that the result is ascii, but we are going to |
9672 | | // to check anyhow with is_forbidden. |
9673 | | // bool is_ascii = |
9674 | 0 | unicode::to_lower_ascii(buffer.data(), buffer.size()); |
9675 | 0 | bool is_forbidden = unicode::contains_forbidden_domain_code_point( |
9676 | 0 | buffer.data(), buffer.size()); |
9677 | 0 | static constexpr std::string_view xn_dash{"xn-", 3}; |
9678 | 0 | if (is_forbidden == 0 && buffer.find(xn_dash) == std::string_view::npos) { |
9679 | | // fast path |
9680 | 0 | host = std::move(buffer); |
9681 | | |
9682 | | // Check for other IPv4 formats (hex, octal, etc.) |
9683 | 0 | if (checkers::is_ipv4(host.value())) { |
9684 | 0 | ada_log("parse_host fast path ipv4"); |
9685 | 0 | return parse_ipv4(host.value()); |
9686 | 0 | } |
9687 | 0 | ada_log("parse_host fast path ", *host); |
9688 | 0 | is_valid = true; |
9689 | 0 | return true; |
9690 | 0 | } |
9691 | 0 | ada_log("parse_host calling to_ascii"); |
9692 | 0 | is_valid = ada::unicode::to_ascii(host, input, input.find('%')); |
9693 | 0 | if (!is_valid || !host.has_value()) { |
9694 | 0 | ada_log("parse_host to_ascii returns false"); |
9695 | 0 | return is_valid = false; |
9696 | 0 | } |
9697 | 0 | ada_log("parse_host to_ascii succeeded ", *host, " [", host->size(), |
9698 | 0 | " bytes]"); |
9699 | |
|
9700 | 0 | if (std::any_of(host->begin(), host->end(), |
9701 | 0 | ada::unicode::is_forbidden_domain_code_point)) { |
9702 | 0 | host = std::nullopt; |
9703 | 0 | return is_valid = false; |
9704 | 0 | } |
9705 | | |
9706 | | // If asciiDomain ends in a number, then return the result of IPv4 parsing |
9707 | | // asciiDomain. |
9708 | 0 | if (checkers::is_ipv4(*host)) { |
9709 | 0 | ada_log("parse_host got ipv4 ", *host); |
9710 | 0 | return parse_ipv4(*host); |
9711 | 0 | } |
9712 | | |
9713 | 0 | return true; |
9714 | 0 | } |
9715 | | |
9716 | 0 | ada_really_inline void url::parse_path(std::string_view input) { |
9717 | 0 | ada_log("parse_path ", input); |
9718 | 0 | std::string tmp_buffer; |
9719 | 0 | std::string_view internal_input; |
9720 | 0 | if (unicode::has_tabs_or_newline(input)) { |
9721 | 0 | tmp_buffer = input; |
9722 | | // Optimization opportunity: Instead of copying and then pruning, we could |
9723 | | // just directly build the string from user_input. |
9724 | 0 | helpers::remove_ascii_tab_or_newline(tmp_buffer); |
9725 | 0 | internal_input = tmp_buffer; |
9726 | 0 | } else { |
9727 | 0 | internal_input = input; |
9728 | 0 | } |
9729 | | |
9730 | | // If url is special, then: |
9731 | 0 | if (is_special()) { |
9732 | 0 | if (internal_input.empty()) { |
9733 | 0 | path = "/"; |
9734 | 0 | } else if ((internal_input[0] == '/') || (internal_input[0] == '\\')) { |
9735 | 0 | helpers::parse_prepared_path(internal_input.substr(1), type, path); |
9736 | 0 | } else { |
9737 | 0 | helpers::parse_prepared_path(internal_input, type, path); |
9738 | 0 | } |
9739 | 0 | } else if (!internal_input.empty()) { |
9740 | 0 | if (internal_input[0] == '/') { |
9741 | 0 | helpers::parse_prepared_path(internal_input.substr(1), type, path); |
9742 | 0 | } else { |
9743 | 0 | helpers::parse_prepared_path(internal_input, type, path); |
9744 | 0 | } |
9745 | 0 | } else { |
9746 | 0 | if (!host.has_value()) { |
9747 | 0 | path = "/"; |
9748 | 0 | } |
9749 | 0 | } |
9750 | 0 | } |
9751 | | |
9752 | 0 | [[nodiscard]] std::string url::to_string() const { |
9753 | 0 | if (!is_valid) { |
9754 | 0 | return "null"; |
9755 | 0 | } |
9756 | 0 | std::string answer; |
9757 | 0 | auto back = std::back_insert_iterator(answer); |
9758 | 0 | answer.append("{\n"); |
9759 | 0 | answer.append("\t\"protocol\":\""); |
9760 | 0 | helpers::encode_json(get_protocol(), back); |
9761 | 0 | answer.append("\",\n"); |
9762 | 0 | if (has_credentials()) { |
9763 | 0 | answer.append("\t\"username\":\""); |
9764 | 0 | helpers::encode_json(username, back); |
9765 | 0 | answer.append("\",\n"); |
9766 | 0 | answer.append("\t\"password\":\""); |
9767 | 0 | helpers::encode_json(password, back); |
9768 | 0 | answer.append("\",\n"); |
9769 | 0 | } |
9770 | 0 | if (host.has_value()) { |
9771 | 0 | answer.append("\t\"host\":\""); |
9772 | 0 | helpers::encode_json(host.value(), back); |
9773 | 0 | answer.append("\",\n"); |
9774 | 0 | } |
9775 | 0 | if (port.has_value()) { |
9776 | 0 | answer.append("\t\"port\":\""); |
9777 | 0 | answer.append(std::to_string(port.value())); |
9778 | 0 | answer.append("\",\n"); |
9779 | 0 | } |
9780 | 0 | answer.append("\t\"path\":\""); |
9781 | 0 | helpers::encode_json(path, back); |
9782 | 0 | answer.append("\",\n"); |
9783 | 0 | answer.append("\t\"opaque path\":"); |
9784 | 0 | answer.append((has_opaque_path ? "true" : "false")); |
9785 | 0 | if (has_search()) { |
9786 | 0 | answer.append(",\n"); |
9787 | 0 | answer.append("\t\"query\":\""); |
9788 | | // NOLINTNEXTLINE(bugprone-unchecked-optional-access) |
9789 | 0 | helpers::encode_json(query.value(), back); |
9790 | 0 | answer.append("\""); |
9791 | 0 | } |
9792 | 0 | if (hash.has_value()) { |
9793 | 0 | answer.append(",\n"); |
9794 | 0 | answer.append("\t\"hash\":\""); |
9795 | 0 | helpers::encode_json(hash.value(), back); |
9796 | 0 | answer.append("\""); |
9797 | 0 | } |
9798 | 0 | answer.append("\n}"); |
9799 | 0 | return answer; |
9800 | 0 | } |
9801 | | |
9802 | 0 | [[nodiscard]] bool url::has_valid_domain() const noexcept { |
9803 | 0 | if (!host.has_value()) { |
9804 | 0 | return false; |
9805 | 0 | } |
9806 | 0 | return checkers::verify_dns_length(*host); |
9807 | 0 | } |
9808 | | |
9809 | 0 | [[nodiscard]] std::string url::get_origin() const { |
9810 | 0 | if (is_special()) { |
9811 | | // Return a new opaque origin. |
9812 | 0 | if (type == scheme::FILE) { |
9813 | 0 | return "null"; |
9814 | 0 | } |
9815 | 0 | return ada::helpers::concat(get_protocol(), "//", get_host()); |
9816 | 0 | } |
9817 | | |
9818 | 0 | if (non_special_scheme == "blob") { |
9819 | 0 | if (!path.empty()) { |
9820 | 0 | auto result = ada::parse<ada::url>(path); |
9821 | 0 | if (result && |
9822 | 0 | (result->type == scheme::HTTP || result->type == scheme::HTTPS)) { |
9823 | | // If pathURL's scheme is not "http" and not "https", then return a |
9824 | | // new opaque origin. |
9825 | 0 | return ada::helpers::concat(result->get_protocol(), "//", |
9826 | 0 | result->get_host()); |
9827 | 0 | } |
9828 | 0 | } |
9829 | 0 | } |
9830 | | |
9831 | | // Return a new opaque origin. |
9832 | 0 | return "null"; |
9833 | 0 | } |
9834 | | |
9835 | 0 | [[nodiscard]] std::string url::get_protocol() const { |
9836 | 0 | if (is_special()) { |
9837 | 0 | return helpers::concat(ada::scheme::details::is_special_list[type], ":"); |
9838 | 0 | } |
9839 | | // We only move the 'scheme' if it is non-special. |
9840 | 0 | return helpers::concat(non_special_scheme, ":"); |
9841 | 0 | } |
9842 | | |
9843 | 0 | [[nodiscard]] std::string url::get_host() const { |
9844 | | // If url's host is null, then return the empty string. |
9845 | | // If url's port is null, return url's host, serialized. |
9846 | | // Return url's host, serialized, followed by U+003A (:) and url's port, |
9847 | | // serialized. |
9848 | 0 | if (!host.has_value()) { |
9849 | 0 | return ""; |
9850 | 0 | } |
9851 | 0 | if (port.has_value()) { |
9852 | 0 | return host.value() + ":" + get_port(); |
9853 | 0 | } |
9854 | 0 | return host.value(); |
9855 | 0 | } |
9856 | | |
9857 | 0 | [[nodiscard]] std::string url::get_hostname() const { |
9858 | 0 | return host.value_or(""); |
9859 | 0 | } |
9860 | | |
9861 | 0 | [[nodiscard]] std::string url::get_search() const { |
9862 | | // If this's URL's query is either null or the empty string, then return the |
9863 | | // empty string. Return U+003F (?), followed by this's URL's query. |
9864 | 0 | return (!query.has_value() || (query->empty())) ? "" : "?" + query.value(); |
9865 | 0 | } |
9866 | | |
9867 | 0 | [[nodiscard]] const std::string& url::get_username() const noexcept { |
9868 | 0 | return username; |
9869 | 0 | } |
9870 | | |
9871 | 0 | [[nodiscard]] const std::string& url::get_password() const noexcept { |
9872 | 0 | return password; |
9873 | 0 | } |
9874 | | |
9875 | 0 | [[nodiscard]] std::string url::get_port() const { |
9876 | 0 | return port.has_value() ? std::to_string(port.value()) : ""; |
9877 | 0 | } |
9878 | | |
9879 | 0 | [[nodiscard]] std::string url::get_hash() const { |
9880 | | // If this's URL's fragment is either null or the empty string, then return |
9881 | | // the empty string. Return U+0023 (#), followed by this's URL's fragment. |
9882 | 0 | return (!hash.has_value() || (hash->empty())) ? "" : "#" + hash.value(); |
9883 | 0 | } |
9884 | | |
9885 | 0 | bool url::needs_rollback_snapshot(size_t input_len) const noexcept { |
9886 | 0 | return get_href_size() + input_len + 16 > ada::get_max_input_length(); |
9887 | 0 | } |
9888 | | |
9889 | | template <bool override_hostname> |
9890 | 0 | bool url::set_host_or_hostname(const std::string_view input) { |
9891 | 0 | if (has_opaque_path) { |
9892 | 0 | return false; |
9893 | 0 | } |
9894 | | |
9895 | 0 | url saved_url(*this); |
9896 | |
|
9897 | 0 | size_t host_end_pos = input.find('#'); |
9898 | 0 | std::string _host(input.data(), host_end_pos != std::string_view::npos |
9899 | 0 | ? host_end_pos |
9900 | 0 | : input.size()); |
9901 | 0 | helpers::remove_ascii_tab_or_newline(_host); |
9902 | 0 | std::string_view new_host(_host); |
9903 | |
|
9904 | 0 | auto check_url_size = [&]() -> bool { |
9905 | 0 | if (get_href_size() > ada::get_max_input_length()) { |
9906 | 0 | *this = std::move(saved_url); |
9907 | 0 | return false; |
9908 | 0 | } |
9909 | 0 | return true; |
9910 | 0 | }; Unexecuted instantiation: ada::url::set_host_or_hostname<false>(std::__1::basic_string_view<char, std::__1::char_traits<char> >)::{lambda()#1}::operator()() constUnexecuted instantiation: ada::url::set_host_or_hostname<true>(std::__1::basic_string_view<char, std::__1::char_traits<char> >)::{lambda()#1}::operator()() const |
9911 | | |
9912 | | // If url's scheme is "file", then set state to file host state, instead of |
9913 | | // host state. |
9914 | 0 | if (type != ada::scheme::type::FILE) { |
9915 | 0 | std::string_view host_view(_host.data(), _host.length()); |
9916 | 0 | auto [location, found_colon] = |
9917 | 0 | helpers::get_host_delimiter_location(is_special(), host_view); |
9918 | | |
9919 | | // Otherwise, if c is U+003A (:) and insideBrackets is false, then: |
9920 | | // Note: the 'found_colon' value is true if and only if a colon was |
9921 | | // encountered while not inside brackets. |
9922 | 0 | if (found_colon) { |
9923 | | // If buffer is the empty string, host-missing validation error, return |
9924 | | // failure. |
9925 | 0 | std::string_view buffer = host_view.substr(0, location); |
9926 | 0 | if (buffer.empty()) { |
9927 | 0 | return false; |
9928 | 0 | } |
9929 | | |
9930 | | // If state override is given and state override is hostname state, then |
9931 | | // return failure. |
9932 | 0 | if constexpr (override_hostname) { |
9933 | 0 | return false; |
9934 | 0 | } |
9935 | | |
9936 | | // Let host be the result of host parsing buffer with url is not special. |
9937 | 0 | bool succeeded = parse_host(buffer); |
9938 | 0 | if (!succeeded) { |
9939 | 0 | *this = std::move(saved_url); |
9940 | 0 | return false; |
9941 | 0 | } |
9942 | | |
9943 | | // Set url's host to host, buffer to the empty string, and state to port |
9944 | | // state. |
9945 | 0 | std::string_view port_buffer = new_host.substr(location + 1); |
9946 | 0 | if (!port_buffer.empty()) { |
9947 | 0 | set_port(port_buffer); |
9948 | 0 | } |
9949 | 0 | return check_url_size(); |
9950 | 0 | } |
9951 | | // Otherwise, if one of the following is true: |
9952 | | // - c is the EOF code point, U+002F (/), U+003F (?), or U+0023 (#) |
9953 | | // - url is special and c is U+005C (\) |
9954 | 0 | else { |
9955 | | // If url is special and host_view is the empty string, host-missing |
9956 | | // validation error, return failure. |
9957 | 0 | if (host_view.empty() && is_special()) { |
9958 | 0 | return false; |
9959 | 0 | } |
9960 | | |
9961 | | // Otherwise, if state override is given, host_view is the empty string, |
9962 | | // and either url includes credentials or url's port is non-null, then |
9963 | | // return failure. |
9964 | 0 | if (host_view.empty() && (has_credentials() || port.has_value())) { |
9965 | 0 | return false; |
9966 | 0 | } |
9967 | | |
9968 | | // Let host be the result of host parsing host_view with url is not |
9969 | | // special. |
9970 | 0 | if (host_view.empty() && !is_special()) { |
9971 | 0 | host = ""; |
9972 | 0 | return check_url_size(); |
9973 | 0 | } |
9974 | | |
9975 | 0 | bool succeeded = parse_host(host_view); |
9976 | 0 | if (!succeeded) { |
9977 | 0 | *this = std::move(saved_url); |
9978 | 0 | return false; |
9979 | 0 | } |
9980 | 0 | return check_url_size(); |
9981 | 0 | } |
9982 | 0 | } |
9983 | | |
9984 | 0 | size_t location = new_host.find_first_of("/\\?"); |
9985 | 0 | if (location != std::string_view::npos) { |
9986 | 0 | new_host.remove_suffix(new_host.length() - location); |
9987 | 0 | } |
9988 | |
|
9989 | 0 | if (new_host.empty()) { |
9990 | | // Set url's host to the empty string. |
9991 | 0 | host = ""; |
9992 | 0 | } else { |
9993 | | // Let host be the result of host parsing buffer with url is not special. |
9994 | 0 | if (!parse_host(new_host)) { |
9995 | 0 | *this = std::move(saved_url); |
9996 | 0 | return false; |
9997 | 0 | } |
9998 | | |
9999 | | // If host is "localhost", then set host to the empty string. |
10000 | 0 | if (host == "localhost") { |
10001 | 0 | host = ""; |
10002 | 0 | } |
10003 | 0 | } |
10004 | 0 | return check_url_size(); |
10005 | 0 | } Unexecuted instantiation: bool ada::url::set_host_or_hostname<false>(std::__1::basic_string_view<char, std::__1::char_traits<char> >) Unexecuted instantiation: bool ada::url::set_host_or_hostname<true>(std::__1::basic_string_view<char, std::__1::char_traits<char> >) |
10006 | | |
10007 | 0 | bool url::set_host(const std::string_view input) { |
10008 | 0 | return set_host_or_hostname<false>(input); |
10009 | 0 | } |
10010 | | |
10011 | 0 | bool url::set_hostname(const std::string_view input) { |
10012 | 0 | return set_host_or_hostname<true>(input); |
10013 | 0 | } |
10014 | | |
10015 | 0 | bool url::set_username(const std::string_view input) { |
10016 | 0 | if (cannot_have_credentials_or_port()) { |
10017 | 0 | return false; |
10018 | 0 | } |
10019 | 0 | auto previous_username = std::move(username); |
10020 | 0 | username = ada::unicode::percent_encode( |
10021 | 0 | input, character_sets::USERINFO_PERCENT_ENCODE); |
10022 | 0 | if (get_href_size() > ada::get_max_input_length()) { |
10023 | 0 | username = std::move(previous_username); |
10024 | 0 | return false; |
10025 | 0 | } |
10026 | 0 | return true; |
10027 | 0 | } |
10028 | | |
10029 | 0 | bool url::set_password(const std::string_view input) { |
10030 | 0 | if (cannot_have_credentials_or_port()) { |
10031 | 0 | return false; |
10032 | 0 | } |
10033 | 0 | auto previous_password = std::move(password); |
10034 | 0 | password = ada::unicode::percent_encode( |
10035 | 0 | input, character_sets::USERINFO_PERCENT_ENCODE); |
10036 | 0 | if (get_href_size() > ada::get_max_input_length()) { |
10037 | 0 | password = std::move(previous_password); |
10038 | 0 | return false; |
10039 | 0 | } |
10040 | 0 | return true; |
10041 | 0 | } |
10042 | | |
10043 | 0 | bool url::set_port(const std::string_view input) { |
10044 | 0 | if (cannot_have_credentials_or_port()) { |
10045 | 0 | return false; |
10046 | 0 | } |
10047 | | |
10048 | 0 | if (input.empty()) { |
10049 | 0 | port = std::nullopt; |
10050 | 0 | return true; |
10051 | 0 | } |
10052 | | |
10053 | 0 | std::string trimmed(input); |
10054 | 0 | helpers::remove_ascii_tab_or_newline(trimmed); |
10055 | |
|
10056 | 0 | if (trimmed.empty()) { |
10057 | 0 | return true; |
10058 | 0 | } |
10059 | | |
10060 | | // Input should not start with a non-digit character. |
10061 | 0 | if (!ada::unicode::is_ascii_digit(trimmed.front())) { |
10062 | 0 | return false; |
10063 | 0 | } |
10064 | | |
10065 | | // Find the first non-digit character to determine the length of digits |
10066 | 0 | auto first_non_digit = |
10067 | 0 | std::ranges::find_if_not(trimmed, ada::unicode::is_ascii_digit); |
10068 | 0 | std::string_view digits_to_parse = |
10069 | 0 | std::string_view(trimmed.data(), first_non_digit - trimmed.begin()); |
10070 | | |
10071 | | // Revert changes if parse_port fails. |
10072 | 0 | std::optional<uint16_t> previous_port = port; |
10073 | 0 | parse_port(digits_to_parse); |
10074 | 0 | if (is_valid) { |
10075 | 0 | if (get_href_size() > ada::get_max_input_length()) { |
10076 | 0 | port = std::move(previous_port); |
10077 | 0 | return false; |
10078 | 0 | } |
10079 | 0 | return true; |
10080 | 0 | } |
10081 | 0 | port = std::move(previous_port); |
10082 | 0 | is_valid = true; |
10083 | 0 | return false; |
10084 | 0 | } |
10085 | | |
10086 | 0 | void url::set_hash(const std::string_view input) { |
10087 | 0 | if (input.empty()) { |
10088 | 0 | hash = std::nullopt; |
10089 | 0 | helpers::strip_trailing_spaces_from_opaque_path(*this); |
10090 | 0 | return; |
10091 | 0 | } |
10092 | | |
10093 | 0 | std::string new_value; |
10094 | 0 | new_value = input[0] == '#' ? input.substr(1) : input; |
10095 | 0 | helpers::remove_ascii_tab_or_newline(new_value); |
10096 | 0 | auto previous_hash = std::move(hash); |
10097 | 0 | hash = unicode::percent_encode(new_value, |
10098 | 0 | ada::character_sets::FRAGMENT_PERCENT_ENCODE); |
10099 | 0 | if (get_href_size() > ada::get_max_input_length()) { |
10100 | 0 | hash = std::move(previous_hash); |
10101 | 0 | } |
10102 | 0 | } |
10103 | | |
10104 | 0 | void url::set_search(const std::string_view input) { |
10105 | 0 | if (input.empty()) { |
10106 | 0 | query = std::nullopt; |
10107 | 0 | helpers::strip_trailing_spaces_from_opaque_path(*this); |
10108 | 0 | return; |
10109 | 0 | } |
10110 | | |
10111 | 0 | std::string new_value; |
10112 | 0 | new_value = input[0] == '?' ? input.substr(1) : input; |
10113 | 0 | helpers::remove_ascii_tab_or_newline(new_value); |
10114 | |
|
10115 | 0 | auto query_percent_encode_set = |
10116 | 0 | is_special() ? ada::character_sets::SPECIAL_QUERY_PERCENT_ENCODE |
10117 | 0 | : ada::character_sets::QUERY_PERCENT_ENCODE; |
10118 | |
|
10119 | 0 | auto previous_query = std::move(query); |
10120 | 0 | query = ada::unicode::percent_encode(new_value, query_percent_encode_set); |
10121 | 0 | if (get_href_size() > ada::get_max_input_length()) { |
10122 | 0 | query = std::move(previous_query); |
10123 | 0 | } |
10124 | 0 | } |
10125 | | |
10126 | 0 | bool url::set_pathname(const std::string_view input) { |
10127 | 0 | if (has_opaque_path) { |
10128 | 0 | return false; |
10129 | 0 | } |
10130 | 0 | auto previous_path = std::move(path); |
10131 | 0 | path.clear(); |
10132 | 0 | parse_path(input); |
10133 | 0 | if (get_href_size() > ada::get_max_input_length()) { |
10134 | 0 | path = std::move(previous_path); |
10135 | 0 | return false; |
10136 | 0 | } |
10137 | 0 | return true; |
10138 | 0 | } |
10139 | | |
10140 | 0 | bool url::set_protocol(const std::string_view input) { |
10141 | 0 | std::string view(input); |
10142 | 0 | helpers::remove_ascii_tab_or_newline(view); |
10143 | 0 | if (view.empty()) { |
10144 | 0 | return true; |
10145 | 0 | } |
10146 | | |
10147 | | // Schemes should start with alpha values. |
10148 | 0 | if (!checkers::is_alpha(view[0])) { |
10149 | 0 | return false; |
10150 | 0 | } |
10151 | | |
10152 | 0 | view.append(":"); |
10153 | |
|
10154 | 0 | std::string::iterator pointer = |
10155 | 0 | std::ranges::find_if_not(view, unicode::is_alnum_plus); |
10156 | |
|
10157 | 0 | if (pointer != view.end() && *pointer == ':') { |
10158 | 0 | std::optional<url> saved_url; |
10159 | 0 | if (needs_rollback_snapshot(view.size())) { |
10160 | 0 | saved_url = *this; |
10161 | 0 | } |
10162 | 0 | bool result = parse_scheme<true>( |
10163 | 0 | std::string_view(view.data(), pointer - view.begin())); |
10164 | 0 | if (result && saved_url && get_href_size() > ada::get_max_input_length()) { |
10165 | 0 | *this = std::move(*saved_url); |
10166 | 0 | return false; |
10167 | 0 | } |
10168 | 0 | return result; |
10169 | 0 | } |
10170 | 0 | return false; |
10171 | 0 | } |
10172 | | |
10173 | 0 | bool url::set_href(const std::string_view input) { |
10174 | 0 | ada::result<ada::url> out = ada::parse<ada::url>(input); |
10175 | |
|
10176 | 0 | if (out) { |
10177 | | // The parser enforces get_max_input_length() on both the input and the |
10178 | | // normalized result. This is a defense-in-depth check. |
10179 | 0 | if (out->get_href_size() > ada::get_max_input_length()) { |
10180 | 0 | return false; |
10181 | 0 | } |
10182 | 0 | *this = *out; |
10183 | 0 | } |
10184 | | |
10185 | 0 | return out.has_value(); |
10186 | 0 | } |
10187 | | |
10188 | | } // namespace ada |
10189 | | /* end file src/url.cpp */ |
10190 | | /* begin file src/parser.cpp */ |
10191 | | |
10192 | | #include <array> |
10193 | | #include <cstring> |
10194 | | #include <limits> |
10195 | | #include <ranges> |
10196 | | |
10197 | | |
10198 | | namespace ada::parser { |
10199 | | |
10200 | | // 0 = host byte, 1 = host delimiter (/ ? #), 2 = reject |
10201 | | namespace { |
10202 | | |
10203 | | constexpr std::array<uint8_t, 256> k_host_class = []() consteval { |
10204 | | std::array<uint8_t, 256> t{}; |
10205 | | for (size_t i = 0; i < 256; ++i) { |
10206 | | t[i] = 2; |
10207 | | } |
10208 | | for (size_t i = 0x21; i <= 0x7E; ++i) { |
10209 | | t[i] = 0; |
10210 | | } |
10211 | | for (uint8_t c : |
10212 | | {'#', '/', ':', '<', '>', '?', '@', '[', '\\', ']', '^', '|', '%'}) { |
10213 | | t[c] = 2; |
10214 | | } |
10215 | | t[static_cast<uint8_t>('/')] = 1; |
10216 | | t[static_cast<uint8_t>('?')] = 1; |
10217 | | t[static_cast<uint8_t>('#')] = 1; |
10218 | | return t; |
10219 | | }(); |
10220 | | |
10221 | | // 0 = ok, 1 = ?/#, 2 = reject. Path rejects '%' so "%2e" falls through. |
10222 | | constexpr std::array<uint8_t, 256> k_rest = []() consteval { |
10223 | | std::array<uint8_t, 256> t{}; |
10224 | | for (size_t i = 0; i < 256; ++i) { |
10225 | | t[i] = 2; |
10226 | | } |
10227 | | for (uint8_t c = 0x21; c <= 0x7E; ++c) { |
10228 | | t[c] = 0; |
10229 | | } |
10230 | | for (uint8_t c : {static_cast<uint8_t>('"'), static_cast<uint8_t>('<'), |
10231 | | static_cast<uint8_t>('>'), static_cast<uint8_t>('`'), |
10232 | | static_cast<uint8_t>('{'), static_cast<uint8_t>('}'), |
10233 | | static_cast<uint8_t>('^'), static_cast<uint8_t>('\\'), |
10234 | | static_cast<uint8_t>('%'), static_cast<uint8_t>('\'')}) { |
10235 | | t[c] = 2; |
10236 | | } |
10237 | | t[static_cast<uint8_t>('?')] = 1; |
10238 | | t[static_cast<uint8_t>('#')] = 1; |
10239 | | return t; |
10240 | | }(); |
10241 | | |
10242 | | } // namespace |
10243 | | |
10244 | | // Fast path for already-normalized absolute http(s) URLs. noinline keeps |
10245 | | // the fallthrough path small (IPv4 microbenches). |
10246 | | template <class result_type> |
10247 | | ada_never_inline bool try_parse_simple_absolute(std::string_view input, |
10248 | 142k | result_type& out) { |
10249 | 142k | constexpr bool is_ada_url = std::is_same_v<result_type, ada::url>; |
10250 | 142k | constexpr bool is_aggregator = |
10251 | 142k | std::is_same_v<result_type, ada::url_aggregator>; |
10252 | 142k | static_assert(is_ada_url || is_aggregator); |
10253 | | |
10254 | 142k | const size_t len = input.size(); |
10255 | 142k | if (len < 8) [[unlikely]] { |
10256 | 11.9k | return false; |
10257 | 11.9k | } |
10258 | 130k | const auto* b = reinterpret_cast<const uint8_t*>(input.data()); |
10259 | | |
10260 | 130k | size_t pos; |
10261 | 130k | ada::scheme::type scheme_type; |
10262 | 130k | uint32_t protocol_end; |
10263 | 130k | if (b[0] == 'h' && b[1] == 't' && b[2] == 't' && b[3] == 'p') { |
10264 | 83.5k | if (b[4] == ':' && b[5] == '/' && b[6] == '/') { |
10265 | 15.0k | pos = 7; |
10266 | 15.0k | scheme_type = ada::scheme::type::HTTP; |
10267 | 15.0k | protocol_end = 5; |
10268 | 68.4k | } else if (len >= 8 && b[4] == 's' && b[5] == ':' && b[6] == '/' && |
10269 | 67.2k | b[7] == '/') { |
10270 | 67.2k | pos = 8; |
10271 | 67.2k | scheme_type = ada::scheme::type::HTTPS; |
10272 | 67.2k | protocol_end = 6; |
10273 | 67.2k | } else { |
10274 | 1.24k | return false; |
10275 | 1.24k | } |
10276 | 83.5k | } else { |
10277 | 47.1k | return false; |
10278 | 47.1k | } |
10279 | 82.2k | if (pos < len && (b[pos] == '/' || b[pos] == '\\')) [[unlikely]] { |
10280 | 12 | return false; |
10281 | 12 | } |
10282 | | |
10283 | | // Digit-led hosts are IPv4/numeric; skip before scanning. |
10284 | 82.2k | if (pos < len && b[pos] >= '0' && b[pos] <= '9') { |
10285 | 0 | return false; |
10286 | 0 | } |
10287 | | |
10288 | 82.2k | const size_t host_start = pos; |
10289 | 82.2k | bool has_upper = false; |
10290 | 82.2k | size_t i = pos; |
10291 | 505k | for (; i < len; ++i) { |
10292 | 503k | const uint8_t c = b[i]; |
10293 | 503k | const uint8_t cls = k_host_class[c]; |
10294 | 503k | if (cls == 1) { |
10295 | 23.2k | break; |
10296 | 23.2k | } |
10297 | 480k | if (cls == 2) [[unlikely]] { |
10298 | 57.0k | return false; |
10299 | 57.0k | } |
10300 | 423k | if (c >= 'A' && c <= 'Z') { |
10301 | 2.85k | has_upper = true; |
10302 | 2.85k | } |
10303 | 423k | } |
10304 | 25.2k | const size_t host_end = i; |
10305 | 25.2k | if (host_start == host_end) [[unlikely]] { |
10306 | 4 | return false; |
10307 | 4 | } |
10308 | 25.2k | const size_t host_len = host_end - host_start; |
10309 | 25.2k | if (host_len > 253) [[unlikely]] { |
10310 | 6 | return false; |
10311 | 6 | } |
10312 | 25.2k | { |
10313 | 25.2k | std::string_view hv(input.data() + host_start, host_len); |
10314 | 25.2k | char host_buf[256]; |
10315 | 25.2k | if (has_upper) [[unlikely]] { |
10316 | 122 | std::memcpy(host_buf, input.data() + host_start, host_len); |
10317 | 122 | unicode::to_lower_ascii(host_buf, host_len); |
10318 | 122 | hv = std::string_view(host_buf, host_len); |
10319 | 122 | } |
10320 | 25.2k | if (checkers::is_ipv4(hv)) [[unlikely]] { |
10321 | 19 | return false; |
10322 | 19 | } |
10323 | 25.2k | static constexpr std::string_view xn{"xn-", 3}; |
10324 | 25.2k | if (hv.find(xn) != std::string_view::npos) [[unlikely]] { |
10325 | 183 | return false; |
10326 | 183 | } |
10327 | 25.2k | } |
10328 | | |
10329 | 25.0k | size_t path_start = host_end; |
10330 | 25.0k | size_t path_end = host_end; |
10331 | 25.0k | size_t query_start = std::string_view::npos; |
10332 | 25.0k | size_t hash_start = std::string_view::npos; |
10333 | 25.0k | bool has_path = false; |
10334 | 25.0k | bool path_has_dot = false; |
10335 | | |
10336 | 25.0k | if (i < len && b[i] == '/') { |
10337 | 22.8k | has_path = true; |
10338 | 22.8k | path_start = i; |
10339 | 22.8k | ++i; |
10340 | 28.1k | for (; i < len; ++i) { |
10341 | 5.60k | const uint8_t c = b[i]; |
10342 | 5.60k | const uint8_t cls = k_rest[c]; |
10343 | 5.60k | if (cls == 0) { |
10344 | 5.31k | path_has_dot |= (c == '.'); |
10345 | 5.31k | continue; |
10346 | 5.31k | } |
10347 | 297 | if (cls == 1) { |
10348 | 238 | path_end = i; |
10349 | 238 | if (c == '?') { |
10350 | 156 | query_start = i; |
10351 | 156 | ++i; |
10352 | 156 | goto scan_query; |
10353 | 156 | } |
10354 | 82 | hash_start = i; |
10355 | 82 | ++i; |
10356 | 82 | goto scan_hash; |
10357 | 238 | } |
10358 | 59 | return false; |
10359 | 297 | } |
10360 | 22.5k | path_end = i; |
10361 | 22.5k | } else if (i < len && b[i] == '?') { |
10362 | 108 | query_start = i; |
10363 | 108 | ++i; |
10364 | 108 | goto scan_query; |
10365 | 2.05k | } else if (i < len && b[i] == '#') { |
10366 | 101 | hash_start = i; |
10367 | 101 | ++i; |
10368 | 101 | goto scan_hash; |
10369 | 101 | } |
10370 | 24.5k | goto after_rest; |
10371 | | |
10372 | 24.5k | scan_query: |
10373 | 1.94k | for (; i < len; ++i) { |
10374 | 1.72k | const uint8_t c = b[i]; |
10375 | 1.72k | if (c == '#') { |
10376 | 17 | hash_start = i; |
10377 | 17 | ++i; |
10378 | 17 | goto scan_hash; |
10379 | 17 | } |
10380 | 1.71k | if (c == '?' || c == '%') { |
10381 | 423 | continue; |
10382 | 423 | } |
10383 | 1.28k | if (k_rest[c] == 2) [[unlikely]] { |
10384 | 29 | return false; |
10385 | 29 | } |
10386 | 1.28k | } |
10387 | 218 | goto after_rest; |
10388 | | |
10389 | 218 | scan_hash: |
10390 | 1.66k | for (; i < len; ++i) { |
10391 | 1.47k | const uint8_t c = b[i]; |
10392 | 1.47k | if (c == '?' || c == '#' || c == '%') { |
10393 | 592 | continue; |
10394 | 592 | } |
10395 | 882 | if (k_rest[c] == 2) [[unlikely]] { |
10396 | 14 | return false; |
10397 | 14 | } |
10398 | 882 | } |
10399 | | |
10400 | 24.9k | after_rest: |
10401 | 24.9k | if (path_has_dot) [[unlikely]] { |
10402 | 168 | const std::string_view path_body(input.data() + path_start, |
10403 | 168 | path_end - path_start); |
10404 | 168 | if (path_body.size() >= 2 && path_body[1] == '.') { |
10405 | 44 | if (path_body.size() == 2 || path_body[2] == '/' || |
10406 | 29 | (path_body.size() >= 3 && path_body[2] == '.' && |
10407 | 27 | (path_body.size() == 3 || path_body[3] == '/'))) { |
10408 | 27 | return false; |
10409 | 27 | } |
10410 | 44 | } |
10411 | 141 | static constexpr std::string_view slash_dot{"/.", 2}; |
10412 | 141 | size_t p = 1; |
10413 | 649 | while ((p = path_body.find(slash_dot, p)) != std::string_view::npos) { |
10414 | 607 | const size_t after = p + 2; |
10415 | 607 | if (after == path_body.size() || path_body[after] == '/' || |
10416 | 549 | (after + 1 <= path_body.size() && path_body[after] == '.' && |
10417 | 238 | (after + 1 == path_body.size() || path_body[after + 1] == '/'))) { |
10418 | 99 | return false; |
10419 | 99 | } |
10420 | 508 | p = after; |
10421 | 508 | } |
10422 | 141 | } |
10423 | | |
10424 | 24.8k | const bool need_slash = !has_path; |
10425 | 24.8k | out.type = scheme_type; |
10426 | 24.8k | out.is_valid = true; |
10427 | 24.8k | out.has_opaque_path = false; |
10428 | 24.8k | out.host_type = DEFAULT; |
10429 | | |
10430 | 24.8k | if constexpr (is_aggregator) { |
10431 | 24.8k | if (!need_slash) { |
10432 | 22.6k | out.buffer.resize(len); |
10433 | | // NOLINTNEXTLINE(bugprone-suspicious-stringview-data-usage) |
10434 | 22.6k | std::memcpy(out.buffer.data(), input.data(), len); |
10435 | 22.6k | if (has_upper) { |
10436 | 36 | unicode::to_lower_ascii(out.buffer.data() + host_start, |
10437 | 36 | host_end - host_start); |
10438 | 36 | } |
10439 | 22.6k | out.components.protocol_end = protocol_end; |
10440 | 22.6k | out.components.username_end = protocol_end + 2; |
10441 | 22.6k | out.components.host_start = protocol_end + 2; |
10442 | 22.6k | out.components.host_end = static_cast<uint32_t>(host_end); |
10443 | 22.6k | out.components.port = url_components::omitted; |
10444 | 22.6k | out.components.pathname_start = static_cast<uint32_t>(path_start); |
10445 | 22.6k | out.components.search_start = (query_start != std::string_view::npos) |
10446 | 22.6k | ? static_cast<uint32_t>(query_start) |
10447 | 22.6k | : url_components::omitted; |
10448 | 22.6k | out.components.hash_start = (hash_start != std::string_view::npos) |
10449 | 22.6k | ? static_cast<uint32_t>(hash_start) |
10450 | 22.6k | : url_components::omitted; |
10451 | 22.6k | } else { |
10452 | 2.15k | out.buffer.resize(len + 1); |
10453 | | // NOLINTNEXTLINE(bugprone-suspicious-stringview-data-usage) |
10454 | 2.15k | std::memcpy(out.buffer.data(), input.data(), host_end); |
10455 | 2.15k | out.buffer[host_end] = '/'; |
10456 | 2.15k | if (host_end < len) { |
10457 | 200 | std::memcpy(out.buffer.data() + host_end + 1, input.data() + host_end, |
10458 | 200 | len - host_end); |
10459 | 200 | } |
10460 | 2.15k | if (has_upper) { |
10461 | 59 | unicode::to_lower_ascii(out.buffer.data() + host_start, |
10462 | 59 | host_end - host_start); |
10463 | 59 | } |
10464 | 2.15k | out.components.protocol_end = protocol_end; |
10465 | 2.15k | out.components.username_end = protocol_end + 2; |
10466 | 2.15k | out.components.host_start = protocol_end + 2; |
10467 | 2.15k | out.components.host_end = static_cast<uint32_t>(host_end); |
10468 | 2.15k | out.components.port = url_components::omitted; |
10469 | 2.15k | out.components.pathname_start = static_cast<uint32_t>(host_end); |
10470 | 2.15k | out.components.search_start = (query_start != std::string_view::npos) |
10471 | 2.15k | ? static_cast<uint32_t>(query_start + 1) |
10472 | 2.15k | : url_components::omitted; |
10473 | 2.15k | out.components.hash_start = (hash_start != std::string_view::npos) |
10474 | 2.15k | ? static_cast<uint32_t>(hash_start + 1) |
10475 | 2.15k | : url_components::omitted; |
10476 | 2.15k | } |
10477 | 24.8k | } else { |
10478 | 0 | std::string host_str(input.substr(host_start, host_end - host_start)); |
10479 | 0 | if (has_upper) { |
10480 | 0 | unicode::to_lower_ascii(host_str.data(), host_str.size()); |
10481 | 0 | } |
10482 | 0 | out.host = std::move(host_str); |
10483 | 0 | if (need_slash) { |
10484 | 0 | out.path = "/"; |
10485 | 0 | } else { |
10486 | 0 | out.path.assign(input.data() + path_start, path_end - path_start); |
10487 | 0 | } |
10488 | 0 | if (query_start != std::string_view::npos) { |
10489 | 0 | const size_t q_end = |
10490 | 0 | (hash_start != std::string_view::npos) ? hash_start : len; |
10491 | 0 | out.query.emplace(input.data() + query_start + 1, |
10492 | 0 | q_end - query_start - 1); |
10493 | 0 | } |
10494 | 0 | if (hash_start != std::string_view::npos) { |
10495 | 0 | out.hash.emplace(input.data() + hash_start + 1, len - hash_start - 1); |
10496 | 0 | } |
10497 | 0 | } |
10498 | 24.8k | return true; |
10499 | 24.9k | } Unexecuted instantiation: bool ada::parser::try_parse_simple_absolute<ada::url>(std::__1::basic_string_view<char, std::__1::char_traits<char> >, ada::url&) bool ada::parser::try_parse_simple_absolute<ada::url_aggregator>(std::__1::basic_string_view<char, std::__1::char_traits<char> >, ada::url_aggregator&) Line | Count | Source | 10248 | 142k | result_type& out) { | 10249 | 142k | constexpr bool is_ada_url = std::is_same_v<result_type, ada::url>; | 10250 | 142k | constexpr bool is_aggregator = | 10251 | 142k | std::is_same_v<result_type, ada::url_aggregator>; | 10252 | 142k | static_assert(is_ada_url || is_aggregator); | 10253 | | | 10254 | 142k | const size_t len = input.size(); | 10255 | 142k | if (len < 8) [[unlikely]] { | 10256 | 11.9k | return false; | 10257 | 11.9k | } | 10258 | 130k | const auto* b = reinterpret_cast<const uint8_t*>(input.data()); | 10259 | | | 10260 | 130k | size_t pos; | 10261 | 130k | ada::scheme::type scheme_type; | 10262 | 130k | uint32_t protocol_end; | 10263 | 130k | if (b[0] == 'h' && b[1] == 't' && b[2] == 't' && b[3] == 'p') { | 10264 | 83.5k | if (b[4] == ':' && b[5] == '/' && b[6] == '/') { | 10265 | 15.0k | pos = 7; | 10266 | 15.0k | scheme_type = ada::scheme::type::HTTP; | 10267 | 15.0k | protocol_end = 5; | 10268 | 68.4k | } else if (len >= 8 && b[4] == 's' && b[5] == ':' && b[6] == '/' && | 10269 | 67.2k | b[7] == '/') { | 10270 | 67.2k | pos = 8; | 10271 | 67.2k | scheme_type = ada::scheme::type::HTTPS; | 10272 | 67.2k | protocol_end = 6; | 10273 | 67.2k | } else { | 10274 | 1.24k | return false; | 10275 | 1.24k | } | 10276 | 83.5k | } else { | 10277 | 47.1k | return false; | 10278 | 47.1k | } | 10279 | 82.2k | if (pos < len && (b[pos] == '/' || b[pos] == '\\')) [[unlikely]] { | 10280 | 12 | return false; | 10281 | 12 | } | 10282 | | | 10283 | | // Digit-led hosts are IPv4/numeric; skip before scanning. | 10284 | 82.2k | if (pos < len && b[pos] >= '0' && b[pos] <= '9') { | 10285 | 0 | return false; | 10286 | 0 | } | 10287 | | | 10288 | 82.2k | const size_t host_start = pos; | 10289 | 82.2k | bool has_upper = false; | 10290 | 82.2k | size_t i = pos; | 10291 | 505k | for (; i < len; ++i) { | 10292 | 503k | const uint8_t c = b[i]; | 10293 | 503k | const uint8_t cls = k_host_class[c]; | 10294 | 503k | if (cls == 1) { | 10295 | 23.2k | break; | 10296 | 23.2k | } | 10297 | 480k | if (cls == 2) [[unlikely]] { | 10298 | 57.0k | return false; | 10299 | 57.0k | } | 10300 | 423k | if (c >= 'A' && c <= 'Z') { | 10301 | 2.85k | has_upper = true; | 10302 | 2.85k | } | 10303 | 423k | } | 10304 | 25.2k | const size_t host_end = i; | 10305 | 25.2k | if (host_start == host_end) [[unlikely]] { | 10306 | 4 | return false; | 10307 | 4 | } | 10308 | 25.2k | const size_t host_len = host_end - host_start; | 10309 | 25.2k | if (host_len > 253) [[unlikely]] { | 10310 | 6 | return false; | 10311 | 6 | } | 10312 | 25.2k | { | 10313 | 25.2k | std::string_view hv(input.data() + host_start, host_len); | 10314 | 25.2k | char host_buf[256]; | 10315 | 25.2k | if (has_upper) [[unlikely]] { | 10316 | 122 | std::memcpy(host_buf, input.data() + host_start, host_len); | 10317 | 122 | unicode::to_lower_ascii(host_buf, host_len); | 10318 | 122 | hv = std::string_view(host_buf, host_len); | 10319 | 122 | } | 10320 | 25.2k | if (checkers::is_ipv4(hv)) [[unlikely]] { | 10321 | 19 | return false; | 10322 | 19 | } | 10323 | 25.2k | static constexpr std::string_view xn{"xn-", 3}; | 10324 | 25.2k | if (hv.find(xn) != std::string_view::npos) [[unlikely]] { | 10325 | 183 | return false; | 10326 | 183 | } | 10327 | 25.2k | } | 10328 | | | 10329 | 25.0k | size_t path_start = host_end; | 10330 | 25.0k | size_t path_end = host_end; | 10331 | 25.0k | size_t query_start = std::string_view::npos; | 10332 | 25.0k | size_t hash_start = std::string_view::npos; | 10333 | 25.0k | bool has_path = false; | 10334 | 25.0k | bool path_has_dot = false; | 10335 | | | 10336 | 25.0k | if (i < len && b[i] == '/') { | 10337 | 22.8k | has_path = true; | 10338 | 22.8k | path_start = i; | 10339 | 22.8k | ++i; | 10340 | 28.1k | for (; i < len; ++i) { | 10341 | 5.60k | const uint8_t c = b[i]; | 10342 | 5.60k | const uint8_t cls = k_rest[c]; | 10343 | 5.60k | if (cls == 0) { | 10344 | 5.31k | path_has_dot |= (c == '.'); | 10345 | 5.31k | continue; | 10346 | 5.31k | } | 10347 | 297 | if (cls == 1) { | 10348 | 238 | path_end = i; | 10349 | 238 | if (c == '?') { | 10350 | 156 | query_start = i; | 10351 | 156 | ++i; | 10352 | 156 | goto scan_query; | 10353 | 156 | } | 10354 | 82 | hash_start = i; | 10355 | 82 | ++i; | 10356 | 82 | goto scan_hash; | 10357 | 238 | } | 10358 | 59 | return false; | 10359 | 297 | } | 10360 | 22.5k | path_end = i; | 10361 | 22.5k | } else if (i < len && b[i] == '?') { | 10362 | 108 | query_start = i; | 10363 | 108 | ++i; | 10364 | 108 | goto scan_query; | 10365 | 2.05k | } else if (i < len && b[i] == '#') { | 10366 | 101 | hash_start = i; | 10367 | 101 | ++i; | 10368 | 101 | goto scan_hash; | 10369 | 101 | } | 10370 | 24.5k | goto after_rest; | 10371 | | | 10372 | 24.5k | scan_query: | 10373 | 1.94k | for (; i < len; ++i) { | 10374 | 1.72k | const uint8_t c = b[i]; | 10375 | 1.72k | if (c == '#') { | 10376 | 17 | hash_start = i; | 10377 | 17 | ++i; | 10378 | 17 | goto scan_hash; | 10379 | 17 | } | 10380 | 1.71k | if (c == '?' || c == '%') { | 10381 | 423 | continue; | 10382 | 423 | } | 10383 | 1.28k | if (k_rest[c] == 2) [[unlikely]] { | 10384 | 29 | return false; | 10385 | 29 | } | 10386 | 1.28k | } | 10387 | 218 | goto after_rest; | 10388 | | | 10389 | 218 | scan_hash: | 10390 | 1.66k | for (; i < len; ++i) { | 10391 | 1.47k | const uint8_t c = b[i]; | 10392 | 1.47k | if (c == '?' || c == '#' || c == '%') { | 10393 | 592 | continue; | 10394 | 592 | } | 10395 | 882 | if (k_rest[c] == 2) [[unlikely]] { | 10396 | 14 | return false; | 10397 | 14 | } | 10398 | 882 | } | 10399 | | | 10400 | 24.9k | after_rest: | 10401 | 24.9k | if (path_has_dot) [[unlikely]] { | 10402 | 168 | const std::string_view path_body(input.data() + path_start, | 10403 | 168 | path_end - path_start); | 10404 | 168 | if (path_body.size() >= 2 && path_body[1] == '.') { | 10405 | 44 | if (path_body.size() == 2 || path_body[2] == '/' || | 10406 | 29 | (path_body.size() >= 3 && path_body[2] == '.' && | 10407 | 27 | (path_body.size() == 3 || path_body[3] == '/'))) { | 10408 | 27 | return false; | 10409 | 27 | } | 10410 | 44 | } | 10411 | 141 | static constexpr std::string_view slash_dot{"/.", 2}; | 10412 | 141 | size_t p = 1; | 10413 | 649 | while ((p = path_body.find(slash_dot, p)) != std::string_view::npos) { | 10414 | 607 | const size_t after = p + 2; | 10415 | 607 | if (after == path_body.size() || path_body[after] == '/' || | 10416 | 549 | (after + 1 <= path_body.size() && path_body[after] == '.' && | 10417 | 238 | (after + 1 == path_body.size() || path_body[after + 1] == '/'))) { | 10418 | 99 | return false; | 10419 | 99 | } | 10420 | 508 | p = after; | 10421 | 508 | } | 10422 | 141 | } | 10423 | | | 10424 | 24.8k | const bool need_slash = !has_path; | 10425 | 24.8k | out.type = scheme_type; | 10426 | 24.8k | out.is_valid = true; | 10427 | 24.8k | out.has_opaque_path = false; | 10428 | 24.8k | out.host_type = DEFAULT; | 10429 | | | 10430 | 24.8k | if constexpr (is_aggregator) { | 10431 | 24.8k | if (!need_slash) { | 10432 | 22.6k | out.buffer.resize(len); | 10433 | | // NOLINTNEXTLINE(bugprone-suspicious-stringview-data-usage) | 10434 | 22.6k | std::memcpy(out.buffer.data(), input.data(), len); | 10435 | 22.6k | if (has_upper) { | 10436 | 36 | unicode::to_lower_ascii(out.buffer.data() + host_start, | 10437 | 36 | host_end - host_start); | 10438 | 36 | } | 10439 | 22.6k | out.components.protocol_end = protocol_end; | 10440 | 22.6k | out.components.username_end = protocol_end + 2; | 10441 | 22.6k | out.components.host_start = protocol_end + 2; | 10442 | 22.6k | out.components.host_end = static_cast<uint32_t>(host_end); | 10443 | 22.6k | out.components.port = url_components::omitted; | 10444 | 22.6k | out.components.pathname_start = static_cast<uint32_t>(path_start); | 10445 | 22.6k | out.components.search_start = (query_start != std::string_view::npos) | 10446 | 22.6k | ? static_cast<uint32_t>(query_start) | 10447 | 22.6k | : url_components::omitted; | 10448 | 22.6k | out.components.hash_start = (hash_start != std::string_view::npos) | 10449 | 22.6k | ? static_cast<uint32_t>(hash_start) | 10450 | 22.6k | : url_components::omitted; | 10451 | 22.6k | } else { | 10452 | 2.15k | out.buffer.resize(len + 1); | 10453 | | // NOLINTNEXTLINE(bugprone-suspicious-stringview-data-usage) | 10454 | 2.15k | std::memcpy(out.buffer.data(), input.data(), host_end); | 10455 | 2.15k | out.buffer[host_end] = '/'; | 10456 | 2.15k | if (host_end < len) { | 10457 | 200 | std::memcpy(out.buffer.data() + host_end + 1, input.data() + host_end, | 10458 | 200 | len - host_end); | 10459 | 200 | } | 10460 | 2.15k | if (has_upper) { | 10461 | 59 | unicode::to_lower_ascii(out.buffer.data() + host_start, | 10462 | 59 | host_end - host_start); | 10463 | 59 | } | 10464 | 2.15k | out.components.protocol_end = protocol_end; | 10465 | 2.15k | out.components.username_end = protocol_end + 2; | 10466 | 2.15k | out.components.host_start = protocol_end + 2; | 10467 | 2.15k | out.components.host_end = static_cast<uint32_t>(host_end); | 10468 | 2.15k | out.components.port = url_components::omitted; | 10469 | 2.15k | out.components.pathname_start = static_cast<uint32_t>(host_end); | 10470 | 2.15k | out.components.search_start = (query_start != std::string_view::npos) | 10471 | 2.15k | ? static_cast<uint32_t>(query_start + 1) | 10472 | 2.15k | : url_components::omitted; | 10473 | 2.15k | out.components.hash_start = (hash_start != std::string_view::npos) | 10474 | 2.15k | ? static_cast<uint32_t>(hash_start + 1) | 10475 | 2.15k | : url_components::omitted; | 10476 | 2.15k | } | 10477 | | } else { | 10478 | | std::string host_str(input.substr(host_start, host_end - host_start)); | 10479 | | if (has_upper) { | 10480 | | unicode::to_lower_ascii(host_str.data(), host_str.size()); | 10481 | | } | 10482 | | out.host = std::move(host_str); | 10483 | | if (need_slash) { | 10484 | | out.path = "/"; | 10485 | | } else { | 10486 | | out.path.assign(input.data() + path_start, path_end - path_start); | 10487 | | } | 10488 | | if (query_start != std::string_view::npos) { | 10489 | | const size_t q_end = | 10490 | | (hash_start != std::string_view::npos) ? hash_start : len; | 10491 | | out.query.emplace(input.data() + query_start + 1, | 10492 | | q_end - query_start - 1); | 10493 | | } | 10494 | | if (hash_start != std::string_view::npos) { | 10495 | | out.hash.emplace(input.data() + hash_start + 1, len - hash_start - 1); | 10496 | | } | 10497 | | } | 10498 | 24.8k | return true; | 10499 | 24.9k | } |
|
10500 | | |
10501 | | template <class result_type, bool store_values> |
10502 | | result_type parse_url_impl(std::string_view user_input, |
10503 | 213k | const result_type* base_url) { |
10504 | | // We can specialize the implementation per type. |
10505 | | // Important: result_type_is_ada_url is evaluated at *compile time*. This |
10506 | | // means that doing if constexpr(result_type_is_ada_url) { something } else { |
10507 | | // something else } is free (at runtime). This means that ada::url_aggregator |
10508 | | // and ada::url **do not have to support the exact same API**. |
10509 | 213k | constexpr bool result_type_is_ada_url = std::is_same_v<url, result_type>; |
10510 | 213k | constexpr bool result_type_is_ada_url_aggregator = |
10511 | 213k | std::is_same_v<url_aggregator, result_type>; |
10512 | 213k | static_assert(result_type_is_ada_url || |
10513 | 213k | result_type_is_ada_url_aggregator); // We don't support |
10514 | | // anything else for now. |
10515 | | |
10516 | 213k | ada_log("ada::parser::parse_url('", user_input, "' [", user_input.size(), |
10517 | 213k | " bytes],", (base_url != nullptr ? base_url->to_string() : "null"), |
10518 | 213k | ")"); |
10519 | | |
10520 | 213k | state state = state::SCHEME_START; |
10521 | 213k | result_type url{}; |
10522 | | |
10523 | 213k | const uint32_t max_input_length = ada::get_max_input_length(); |
10524 | | |
10525 | | // We refuse to parse URL strings that exceed the maximum input length. |
10526 | | // By default, this is 4GB but can be configured via |
10527 | | // ada::set_max_input_length(). |
10528 | 213k | if (user_input.size() > max_input_length) [[unlikely]] { |
10529 | 0 | url.is_valid = false; |
10530 | 0 | } |
10531 | | // Going forward, user_input.size() is in [0, |
10532 | | // std::numeric_limits<uint32_t>::max). If we are provided with an invalid |
10533 | | // base, or the optional_url was invalid, we must return. |
10534 | 213k | if (base_url != nullptr) { |
10535 | 6.63k | url.is_valid &= base_url->is_valid; |
10536 | 6.63k | } |
10537 | 213k | if (!url.is_valid) { |
10538 | 0 | return url; |
10539 | 0 | } |
10540 | | |
10541 | | // Simple absolute http(s) fast path (before tabs/newline scan). |
10542 | | // Skip digit-led hosts (IPv4) with a cheap peek. |
10543 | 213k | if constexpr (store_values) { |
10544 | 169k | if (base_url == nullptr) { |
10545 | 166k | const auto* p = reinterpret_cast<const uint8_t*>(user_input.data()); |
10546 | 166k | const size_t n = user_input.size(); |
10547 | 166k | const bool digit_led_host = (n >= 8 && p[4] == ':' && p[5] == '/' && |
10548 | 74.0k | p[6] == '/' && p[7] >= '0' && p[7] <= '9') || |
10549 | 142k | (n >= 9 && p[5] == ':' && p[6] == '/' && |
10550 | 67.7k | p[7] == '/' && p[8] >= '0' && p[8] <= '9'); |
10551 | 166k | if (!digit_led_host && try_parse_simple_absolute(user_input, url)) { |
10552 | 24.8k | if constexpr (result_type_is_ada_url_aggregator) { |
10553 | 24.8k | if (url.buffer.size() > max_input_length) [[unlikely]] { |
10554 | 0 | url.is_valid = false; |
10555 | 0 | } |
10556 | 24.8k | } else { |
10557 | 0 | if (url.get_href_size() > max_input_length) [[unlikely]] { |
10558 | 0 | url.is_valid = false; |
10559 | 0 | } |
10560 | 0 | } |
10561 | 24.8k | return url; |
10562 | 24.8k | } |
10563 | 166k | } |
10564 | 169k | } |
10565 | | |
10566 | 145k | std::string tmp_buffer; |
10567 | 213k | std::string_view url_data; |
10568 | 213k | if (unicode::has_tabs_or_newline(user_input)) [[unlikely]] { |
10569 | 759 | tmp_buffer = user_input; |
10570 | | // Optimization opportunity: Instead of copying and then pruning, we could |
10571 | | // just directly build the string from user_input. |
10572 | 759 | helpers::remove_ascii_tab_or_newline(tmp_buffer); |
10573 | 759 | url_data = tmp_buffer; |
10574 | 212k | } else [[likely]] { |
10575 | 212k | url_data = user_input; |
10576 | 212k | } |
10577 | | |
10578 | | // Leading and trailing control characters are uncommon and easy to deal with |
10579 | | // (no performance concern). |
10580 | 213k | helpers::trim_c0_whitespace(url_data); |
10581 | | |
10582 | 213k | if constexpr (result_type_is_ada_url_aggregator && store_values) { |
10583 | | // Most of the time, we just need user_input.size(). |
10584 | | // In some instances, we may need a bit more. |
10585 | | /////////////////////////// |
10586 | | // This is *very* important. This line should *not* be removed |
10587 | | // hastily. There are principled reasons why reserve is important |
10588 | | // for performance. If you have a benchmark with small inputs, |
10589 | | // it may not matter, but in other instances, it could. |
10590 | | //// |
10591 | | // This rounds up to the next power of two. |
10592 | | // We know that user_input.size() is in [0, |
10593 | | // std::numeric_limits<uint32_t>::max). |
10594 | 169k | uint32_t reserve_capacity = |
10595 | 169k | (0xFFFFFFFF >> |
10596 | 169k | helpers::leading_zeroes(uint32_t(1 | user_input.size()))) + |
10597 | 169k | 1; |
10598 | 169k | url.reserve(reserve_capacity); |
10599 | 169k | } |
10600 | | |
10601 | | // Optimization opportunity. Most websites do not have fragment. |
10602 | 213k | std::optional<std::string_view> fragment = helpers::prune_hash(url_data); |
10603 | | // We add it last so that an implementation like ada::url_aggregator |
10604 | | // can append it last to its internal buffer, thus improving performance. |
10605 | | |
10606 | | // Here url_data no longer has its fragment. |
10607 | | // We are going to access the data from url_data (it is immutable). |
10608 | | // At any given time, we are pointing at byte 'input_position' in url_data. |
10609 | | // The input_position variable should range from 0 to input_size. |
10610 | | // It is illegal to access url_data at input_size. |
10611 | 213k | size_t input_position = 0; |
10612 | 213k | const size_t input_size = url_data.size(); |
10613 | | // Keep running the following state machine by switching on state. |
10614 | | // If after a run pointer points to the EOF code point, go to the next step. |
10615 | | // Otherwise, increase pointer by 1 and continue with the state machine. |
10616 | | // We never decrement input_position. |
10617 | 1.30M | while (input_position <= input_size) { |
10618 | 1.17M | ada_log("In parsing at ", input_position, " out of ", input_size, |
10619 | 1.17M | " in state ", ada::to_string(state)); |
10620 | 1.17M | switch (state) { |
10621 | 188k | case state::SCHEME_START: { |
10622 | 188k | ada_log("SCHEME_START ", helpers::substring(url_data, input_position)); |
10623 | | // If c is an ASCII alpha, append c, lowercased, to buffer, and set |
10624 | | // state to scheme state. |
10625 | 188k | if ((input_position != input_size) && |
10626 | 175k | checkers::is_alpha(url_data[input_position])) { |
10627 | 170k | state = state::SCHEME; |
10628 | 170k | input_position++; |
10629 | 170k | } else { |
10630 | | // Otherwise, if state override is not given, set state to no scheme |
10631 | | // state and decrease pointer by 1. |
10632 | 18.1k | state = state::NO_SCHEME; |
10633 | 18.1k | } |
10634 | 188k | break; |
10635 | 0 | } |
10636 | 170k | case state::SCHEME: { |
10637 | 170k | ada_log("SCHEME ", helpers::substring(url_data, input_position)); |
10638 | | // If c is an ASCII alphanumeric, U+002B (+), U+002D (-), or U+002E (.), |
10639 | | // append c, lowercased, to buffer. |
10640 | 756k | while ((input_position != input_size) && |
10641 | 755k | (unicode::is_alnum_plus(url_data[input_position]))) { |
10642 | 586k | input_position++; |
10643 | 586k | } |
10644 | | // Otherwise, if c is U+003A (:), then: |
10645 | 170k | if ((input_position != input_size) && |
10646 | 168k | (url_data[input_position] == ':')) { |
10647 | 167k | ada_log("SCHEME the scheme should be ", |
10648 | 167k | url_data.substr(0, input_position)); |
10649 | 167k | if constexpr (result_type_is_ada_url) { |
10650 | 0 | if (!url.parse_scheme(url_data.substr(0, input_position))) { |
10651 | 0 | return url; |
10652 | 0 | } |
10653 | 167k | } else { |
10654 | | // we pass the colon along instead of painfully adding it back. |
10655 | 167k | if (!url.parse_scheme_with_colon( |
10656 | 167k | url_data.substr(0, input_position + 1))) { |
10657 | 0 | return url; |
10658 | 0 | } |
10659 | 167k | } |
10660 | 167k | ada_log("SCHEME the scheme is ", url.get_protocol()); |
10661 | | |
10662 | | // If url's scheme is "file", then: |
10663 | | // NOLINTNEXTLINE(bugprone-branch-clone) |
10664 | 167k | if (url.type == scheme::type::FILE) { |
10665 | | // Set state to file state. |
10666 | 50.0k | state = state::FILE; |
10667 | 50.0k | } |
10668 | | // Otherwise, if url is special, base is non-null, and base's scheme |
10669 | | // is url's scheme: Note: Doing base_url->scheme is unsafe if base_url |
10670 | | // != nullptr is false. |
10671 | 117k | else if (url.is_special() && base_url != nullptr && |
10672 | 3.20k | base_url->type == url.type) { |
10673 | | // Set state to special relative or authority state. |
10674 | 680 | state = state::SPECIAL_RELATIVE_OR_AUTHORITY; |
10675 | 680 | } |
10676 | | // Otherwise, if url is special, set state to special authority |
10677 | | // slashes state. |
10678 | 116k | else if (url.is_special()) { |
10679 | 109k | state = state::SPECIAL_AUTHORITY_SLASHES; |
10680 | 109k | } |
10681 | | // Otherwise, if remaining starts with an U+002F (/), set state to |
10682 | | // path or authority state and increase pointer by 1. |
10683 | 7.19k | else if (input_position + 1 < input_size && |
10684 | 6.26k | url_data[input_position + 1] == '/') { |
10685 | 4.26k | state = state::PATH_OR_AUTHORITY; |
10686 | 4.26k | input_position++; |
10687 | 4.26k | } |
10688 | | // Otherwise, set url's path to the empty string and set state to |
10689 | | // opaque path state. |
10690 | 2.92k | else { |
10691 | 2.92k | state = state::OPAQUE_PATH; |
10692 | 2.92k | } |
10693 | 167k | } |
10694 | | // Otherwise, if state override is not given, set buffer to the empty |
10695 | | // string, state to no scheme state, and start over (from the first code |
10696 | | // point in input). |
10697 | 2.94k | else { |
10698 | 2.94k | state = state::NO_SCHEME; |
10699 | 2.94k | input_position = 0; |
10700 | 2.94k | break; |
10701 | 2.94k | } |
10702 | 167k | input_position++; |
10703 | 167k | break; |
10704 | 170k | } |
10705 | 21.0k | case state::NO_SCHEME: { |
10706 | 21.0k | ada_log("NO_SCHEME ", helpers::substring(url_data, input_position)); |
10707 | | // The fragment was pruned from url_data before the state machine ran, |
10708 | | // so 'c is U+0023 (#)' holds exactly when a fragment was found and |
10709 | | // nothing else remains in front of it. |
10710 | 21.0k | const bool c_is_hash = |
10711 | 21.0k | fragment.has_value() && input_position == input_size; |
10712 | | // If base is null, or base has an opaque path and c is not U+0023 (#), |
10713 | | // validation error, return failure. |
10714 | 21.0k | if (base_url == nullptr || (base_url->has_opaque_path && !c_is_hash)) { |
10715 | 19.4k | ada_log("NO_SCHEME validation error"); |
10716 | 19.4k | url.is_valid = false; |
10717 | 19.4k | return url; |
10718 | 19.4k | } |
10719 | | // Otherwise, if base has an opaque path and c is U+0023 (#), |
10720 | | // set url's scheme to base's scheme, url's path to base's path, url's |
10721 | | // query to base's query, and set state to fragment state. |
10722 | 1.57k | else if (base_url->has_opaque_path && c_is_hash) { |
10723 | 118 | ada_log("NO_SCHEME opaque base with fragment"); |
10724 | 118 | url.copy_scheme(*base_url); |
10725 | 118 | url.has_opaque_path = base_url->has_opaque_path; |
10726 | | |
10727 | 118 | if constexpr (result_type_is_ada_url) { |
10728 | 0 | url.path = base_url->path; |
10729 | 0 | url.query = base_url->query; |
10730 | 118 | } else { |
10731 | 118 | url.update_base_pathname(base_url->get_pathname()); |
10732 | 118 | if (base_url->has_search()) { |
10733 | | // get_search() returns "" for an empty query string (URL ends |
10734 | | // with '?'). update_base_search("") would incorrectly clear the |
10735 | | // query, so pass "?" to preserve the empty query distinction. |
10736 | 35 | auto s = base_url->get_search(); |
10737 | 35 | url.update_base_search(s.empty() ? std::string_view("?") : s); |
10738 | 35 | } |
10739 | 118 | } |
10740 | 118 | url.update_unencoded_base_hash(*fragment); |
10741 | 118 | return url; |
10742 | 118 | } |
10743 | | // Otherwise, if base's scheme is not "file", set state to relative |
10744 | | // state and decrease pointer by 1. |
10745 | | // NOLINTNEXTLINE(bugprone-branch-clone) |
10746 | 1.45k | else if (base_url->type != scheme::type::FILE) { |
10747 | 950 | ada_log("NO_SCHEME non-file relative path"); |
10748 | 950 | state = state::RELATIVE_SCHEME; |
10749 | 950 | } |
10750 | | // Otherwise, set state to file state and decrease pointer by 1. |
10751 | 508 | else { |
10752 | 508 | ada_log("NO_SCHEME file base type"); |
10753 | 508 | state = state::FILE; |
10754 | 508 | } |
10755 | 1.45k | break; |
10756 | 21.0k | } |
10757 | 112k | case state::AUTHORITY: { |
10758 | 112k | ada_log("AUTHORITY ", helpers::substring(url_data, input_position)); |
10759 | | // most URLs have no @. Having no @ tells us that we don't have to worry |
10760 | | // about AUTHORITY. Of course, we could have @ and still not have to |
10761 | | // worry about AUTHORITY. |
10762 | | // TODO: Instead of just collecting a bool, collect the location of the |
10763 | | // '@' and do something useful with it. |
10764 | | // TODO: We could do various processing early on, using a single pass |
10765 | | // over the string to collect information about it, e.g., telling us |
10766 | | // whether there is a @ and if so, where (or how many). |
10767 | | |
10768 | | // Check if url data contains an @. |
10769 | 112k | if (url_data.find('@', input_position) == std::string_view::npos) { |
10770 | 40.7k | state = state::HOST; |
10771 | 40.7k | break; |
10772 | 40.7k | } |
10773 | 71.4k | bool at_sign_seen{false}; |
10774 | 71.4k | bool password_token_seen{false}; |
10775 | | /** |
10776 | | * We expect something of the sort... |
10777 | | * https://user:pass@example.com:1234/foo/bar?baz#quux |
10778 | | * --------^ |
10779 | | */ |
10780 | 166k | do { |
10781 | 166k | std::string_view view = url_data.substr(input_position); |
10782 | | // The delimiters are @, /, ? \\. |
10783 | 166k | size_t location = |
10784 | 166k | url.is_special() ? helpers::find_authority_delimiter_special(view) |
10785 | 166k | : helpers::find_authority_delimiter(view); |
10786 | 166k | std::string_view authority_view = view.substr(0, location); |
10787 | 166k | size_t end_of_authority = input_position + authority_view.size(); |
10788 | | // If c is U+0040 (@), then: |
10789 | 166k | if ((end_of_authority != input_size) && |
10790 | 164k | (url_data[end_of_authority] == '@')) { |
10791 | | // If atSignSeen is true, then prepend "%40" to buffer. |
10792 | 94.7k | if (at_sign_seen) { |
10793 | 23.4k | if (password_token_seen) { |
10794 | 6.46k | if constexpr (result_type_is_ada_url) { |
10795 | 0 | url.password += "%40"; |
10796 | 6.46k | } else { |
10797 | 6.46k | url.append_base_password("%40"); |
10798 | 6.46k | } |
10799 | 17.0k | } else { |
10800 | 17.0k | if constexpr (result_type_is_ada_url) { |
10801 | 0 | url.username += "%40"; |
10802 | 17.0k | } else { |
10803 | 17.0k | url.append_base_username("%40"); |
10804 | 17.0k | } |
10805 | 17.0k | } |
10806 | 23.4k | } |
10807 | | |
10808 | 94.7k | at_sign_seen = true; |
10809 | | |
10810 | 94.7k | if (!password_token_seen) { |
10811 | 88.2k | size_t password_token_location = authority_view.find(':'); |
10812 | 88.2k | password_token_seen = |
10813 | 88.2k | password_token_location != std::string_view::npos; |
10814 | | |
10815 | 88.2k | if constexpr (store_values) { |
10816 | 69.3k | if (!password_token_seen) { |
10817 | 10.4k | if constexpr (result_type_is_ada_url) { |
10818 | 0 | url.username += unicode::percent_encode( |
10819 | 0 | authority_view, |
10820 | 0 | character_sets::USERINFO_PERCENT_ENCODE); |
10821 | 10.4k | } else { |
10822 | 10.4k | url.append_base_username(unicode::percent_encode( |
10823 | 10.4k | authority_view, |
10824 | 10.4k | character_sets::USERINFO_PERCENT_ENCODE)); |
10825 | 10.4k | } |
10826 | 58.8k | } else { |
10827 | 58.8k | if constexpr (result_type_is_ada_url) { |
10828 | 0 | url.username += unicode::percent_encode( |
10829 | 0 | authority_view.substr(0, password_token_location), |
10830 | 0 | character_sets::USERINFO_PERCENT_ENCODE); |
10831 | 0 | url.password += unicode::percent_encode( |
10832 | 0 | authority_view.substr(password_token_location + 1), |
10833 | 0 | character_sets::USERINFO_PERCENT_ENCODE); |
10834 | 58.8k | } else { |
10835 | 58.8k | url.append_base_username(unicode::percent_encode( |
10836 | 58.8k | authority_view.substr(0, password_token_location), |
10837 | 58.8k | character_sets::USERINFO_PERCENT_ENCODE)); |
10838 | 58.8k | url.append_base_password(unicode::percent_encode( |
10839 | 58.8k | authority_view.substr(password_token_location + 1), |
10840 | 58.8k | character_sets::USERINFO_PERCENT_ENCODE)); |
10841 | 58.8k | } |
10842 | 58.8k | } |
10843 | 69.3k | } |
10844 | 88.2k | } else if constexpr (store_values) { |
10845 | 3.81k | if constexpr (result_type_is_ada_url) { |
10846 | 0 | url.password += unicode::percent_encode( |
10847 | 0 | authority_view, character_sets::USERINFO_PERCENT_ENCODE); |
10848 | 3.81k | } else { |
10849 | 3.81k | url.append_base_password(unicode::percent_encode( |
10850 | 3.81k | authority_view, character_sets::USERINFO_PERCENT_ENCODE)); |
10851 | 3.81k | } |
10852 | 3.81k | } |
10853 | 94.7k | } |
10854 | | // Otherwise, if one of the following is true: |
10855 | | // - c is the EOF code point, U+002F (/), U+003F (?), or U+0023 (#) |
10856 | | // - url is special and c is U+005C (\) |
10857 | 71.4k | else if (end_of_authority == input_size || |
10858 | 70.0k | url_data[end_of_authority] == '/' || |
10859 | 169 | url_data[end_of_authority] == '?' || |
10860 | 71.4k | (url.is_special() && url_data[end_of_authority] == '\\')) { |
10861 | | // If atSignSeen is true and authority_view is the empty string, |
10862 | | // validation error, return failure. |
10863 | 71.4k | if (at_sign_seen && authority_view.empty()) { |
10864 | 226 | url.is_valid = false; |
10865 | 226 | return url; |
10866 | 226 | } |
10867 | 71.1k | state = state::HOST; |
10868 | 71.1k | break; |
10869 | 71.4k | } |
10870 | 94.7k | if (end_of_authority == input_size) { |
10871 | 0 | if constexpr (store_values) { |
10872 | 0 | if (fragment.has_value()) { |
10873 | 0 | url.update_unencoded_base_hash(*fragment); |
10874 | 0 | } |
10875 | 0 | } |
10876 | 0 | return url; |
10877 | 0 | } |
10878 | 94.7k | input_position = end_of_authority + 1; |
10879 | 94.7k | } while (true); |
10880 | | |
10881 | 71.1k | break; |
10882 | 71.4k | } |
10883 | 71.1k | case state::SPECIAL_RELATIVE_OR_AUTHORITY: { |
10884 | 680 | ada_log("SPECIAL_RELATIVE_OR_AUTHORITY ", |
10885 | 680 | helpers::substring(url_data, input_position)); |
10886 | | |
10887 | | // If c is U+002F (/) and remaining starts with U+002F (/), |
10888 | | // then set state to special authority ignore slashes state and increase |
10889 | | // pointer by 1. |
10890 | 680 | if (url_data.substr(input_position, 2) == "//") { |
10891 | 412 | state = state::SPECIAL_AUTHORITY_IGNORE_SLASHES; |
10892 | 412 | input_position += 2; |
10893 | 412 | } else { |
10894 | | // Otherwise, validation error, set state to relative state and |
10895 | | // decrease pointer by 1. |
10896 | 268 | state = state::RELATIVE_SCHEME; |
10897 | 268 | } |
10898 | | |
10899 | 680 | break; |
10900 | 71.4k | } |
10901 | 4.26k | case state::PATH_OR_AUTHORITY: { |
10902 | 4.26k | ada_log("PATH_OR_AUTHORITY ", |
10903 | 4.26k | helpers::substring(url_data, input_position)); |
10904 | | |
10905 | | // If c is U+002F (/), then set state to authority state. |
10906 | 4.26k | if ((input_position != input_size) && |
10907 | 3.55k | (url_data[input_position] == '/')) { |
10908 | 2.20k | state = state::AUTHORITY; |
10909 | 2.20k | input_position++; |
10910 | 2.20k | } else { |
10911 | | // Otherwise, set state to path state, and decrease pointer by 1. |
10912 | 2.06k | state = state::PATH; |
10913 | 2.06k | } |
10914 | | |
10915 | 4.26k | break; |
10916 | 71.4k | } |
10917 | 1.21k | case state::RELATIVE_SCHEME: { |
10918 | 1.21k | ada_log("RELATIVE_SCHEME ", |
10919 | 1.21k | helpers::substring(url_data, input_position)); |
10920 | | |
10921 | | // Set url's scheme to base's scheme. |
10922 | 1.21k | url.copy_scheme(*base_url); |
10923 | | |
10924 | | // If c is U+002F (/), then set state to relative slash state. |
10925 | 1.21k | if ((input_position != input_size) && |
10926 | | // NOLINTNEXTLINE(bugprone-branch-clone) |
10927 | 928 | (url_data[input_position] == '/')) { |
10928 | 114 | ada_log( |
10929 | 114 | "RELATIVE_SCHEME if c is U+002F (/), then set state to relative " |
10930 | 114 | "slash state"); |
10931 | 114 | state = state::RELATIVE_SLASH; |
10932 | 1.10k | } else if (url.is_special() && (input_position != input_size) && |
10933 | 704 | (url_data[input_position] == '\\')) { |
10934 | | // Otherwise, if url is special and c is U+005C (\), validation error, |
10935 | | // set state to relative slash state. |
10936 | 4 | ada_log( |
10937 | 4 | "RELATIVE_SCHEME if url is special and c is U+005C, validation " |
10938 | 4 | "error, set state to relative slash state"); |
10939 | 4 | state = state::RELATIVE_SLASH; |
10940 | 1.10k | } else { |
10941 | 1.10k | ada_log("RELATIVE_SCHEME otherwise"); |
10942 | | // Set url's username to base's username, url's password to base's |
10943 | | // password, url's host to base's host, url's port to base's port, |
10944 | | // url's path to a clone of base's path, and url's query to base's |
10945 | | // query. |
10946 | 1.10k | if constexpr (result_type_is_ada_url) { |
10947 | 0 | url.username = base_url->username; |
10948 | 0 | url.password = base_url->password; |
10949 | 0 | url.host = base_url->host; |
10950 | 0 | url.port = base_url->port; |
10951 | | // cloning the base path includes cloning the has_opaque_path flag |
10952 | 0 | url.has_opaque_path = base_url->has_opaque_path; |
10953 | 0 | url.path = base_url->path; |
10954 | 0 | url.query = base_url->query; |
10955 | 1.10k | } else { |
10956 | 1.10k | url.update_base_authority(base_url->get_href(), |
10957 | 1.10k | base_url->get_components()); |
10958 | 1.10k | url.update_host_to_base_host(base_url->get_hostname()); |
10959 | 1.10k | url.update_base_port(base_url->retrieve_base_port()); |
10960 | | // cloning the base path includes cloning the has_opaque_path flag |
10961 | 1.10k | url.has_opaque_path = base_url->has_opaque_path; |
10962 | 1.10k | url.update_base_pathname(base_url->get_pathname()); |
10963 | 1.10k | if (base_url->has_search()) { |
10964 | | // get_search() returns "" for an empty query string (URL ends |
10965 | | // with '?'). update_base_search("") would incorrectly clear the |
10966 | | // query, so pass "?" to preserve the empty query distinction. |
10967 | 81 | auto s = base_url->get_search(); |
10968 | 81 | url.update_base_search(s.empty() ? std::string_view("?") : s); |
10969 | 81 | } |
10970 | 1.10k | } |
10971 | | |
10972 | 1.10k | url.has_opaque_path = base_url->has_opaque_path; |
10973 | | |
10974 | | // If c is U+003F (?), then set url's query to the empty string, and |
10975 | | // state to query state. |
10976 | 1.10k | if ((input_position != input_size) && |
10977 | 810 | (url_data[input_position] == '?')) { |
10978 | 14 | state = state::QUERY; |
10979 | 14 | } |
10980 | | // Otherwise, if c is not the EOF code point: |
10981 | 1.08k | else if (input_position != input_size) { |
10982 | | // Set url's query to null. |
10983 | 796 | url.clear_search(); |
10984 | 796 | if constexpr (result_type_is_ada_url) { |
10985 | | // Shorten url's path. |
10986 | 0 | helpers::shorten_path(url.path, url.type); |
10987 | 796 | } else { |
10988 | 796 | std::string_view path = url.get_pathname(); |
10989 | 796 | if (helpers::shorten_path(path, url.type)) { |
10990 | 392 | url.update_base_pathname(std::move(std::string(path))); |
10991 | 392 | } |
10992 | 796 | } |
10993 | | // Set state to path state and decrease pointer by 1. |
10994 | 796 | state = state::PATH; |
10995 | 796 | break; |
10996 | 796 | } |
10997 | 1.10k | } |
10998 | 422 | input_position++; |
10999 | 422 | break; |
11000 | 1.21k | } |
11001 | 118 | case state::RELATIVE_SLASH: { |
11002 | 118 | ada_log("RELATIVE_SLASH ", |
11003 | 118 | helpers::substring(url_data, input_position)); |
11004 | | |
11005 | | // If url is special and c is U+002F (/) or U+005C (\), then: |
11006 | | // NOLINTNEXTLINE(bugprone-branch-clone) |
11007 | 118 | if (url.is_special() && (input_position != input_size) && |
11008 | 90 | (url_data[input_position] == '/' || |
11009 | 48 | url_data[input_position] == '\\')) { |
11010 | | // Set state to special authority ignore slashes state. |
11011 | 46 | state = state::SPECIAL_AUTHORITY_IGNORE_SLASHES; |
11012 | 46 | } |
11013 | | // Otherwise, if c is U+002F (/), then set state to authority state. |
11014 | 72 | else if ((input_position != input_size) && |
11015 | 48 | (url_data[input_position] == '/')) { |
11016 | 2 | state = state::AUTHORITY; |
11017 | 2 | } |
11018 | | // Otherwise, set |
11019 | | // - url's username to base's username, |
11020 | | // - url's password to base's password, |
11021 | | // - url's host to base's host, |
11022 | | // - url's port to base's port, |
11023 | | // - state to path state, and then, decrease pointer by 1. |
11024 | 70 | else { |
11025 | 70 | if constexpr (result_type_is_ada_url) { |
11026 | 0 | url.username = base_url->username; |
11027 | 0 | url.password = base_url->password; |
11028 | 0 | url.host = base_url->host; |
11029 | 0 | url.port = base_url->port; |
11030 | 70 | } else { |
11031 | 70 | url.update_base_authority(base_url->get_href(), |
11032 | 70 | base_url->get_components()); |
11033 | 70 | url.update_host_to_base_host(base_url->get_hostname()); |
11034 | 70 | url.update_base_port(base_url->retrieve_base_port()); |
11035 | 70 | } |
11036 | 70 | state = state::PATH; |
11037 | 70 | break; |
11038 | 70 | } |
11039 | | |
11040 | 48 | input_position++; |
11041 | 48 | break; |
11042 | 118 | } |
11043 | 109k | case state::SPECIAL_AUTHORITY_SLASHES: { |
11044 | 109k | ada_log("SPECIAL_AUTHORITY_SLASHES ", |
11045 | 109k | helpers::substring(url_data, input_position)); |
11046 | | |
11047 | | // If c is U+002F (/) and remaining starts with U+002F (/), |
11048 | | // then set state to special authority ignore slashes state and increase |
11049 | | // pointer by 1. |
11050 | 109k | if (url_data.substr(input_position, 2) == "//") { |
11051 | 99.6k | input_position += 2; |
11052 | 99.6k | } |
11053 | | |
11054 | 109k | [[fallthrough]]; |
11055 | 109k | } |
11056 | 109k | case state::SPECIAL_AUTHORITY_IGNORE_SLASHES: { |
11057 | 109k | ada_log("SPECIAL_AUTHORITY_IGNORE_SLASHES ", |
11058 | 109k | helpers::substring(url_data, input_position)); |
11059 | | |
11060 | | // If c is neither U+002F (/) nor U+005C (\), then set state to |
11061 | | // authority state and decrease pointer by 1. |
11062 | 114k | while ((input_position != input_size) && |
11063 | 114k | ((url_data[input_position] == '/') || |
11064 | 112k | (url_data[input_position] == '\\'))) { |
11065 | 4.12k | input_position++; |
11066 | 4.12k | } |
11067 | 109k | state = state::AUTHORITY; |
11068 | | |
11069 | 109k | break; |
11070 | 109k | } |
11071 | 24.5k | case state::QUERY: { |
11072 | 24.5k | ada_log("QUERY ", helpers::substring(url_data, input_position)); |
11073 | 24.5k | if constexpr (store_values) { |
11074 | | // Let queryPercentEncodeSet be the special-query percent-encode set |
11075 | | // if url is special; otherwise the query percent-encode set. |
11076 | 24.5k | const uint8_t* query_percent_encode_set = |
11077 | 24.5k | url.is_special() ? character_sets::SPECIAL_QUERY_PERCENT_ENCODE |
11078 | 24.5k | : character_sets::QUERY_PERCENT_ENCODE; |
11079 | | |
11080 | | // Percent-encode after encoding, with encoding, buffer, and |
11081 | | // queryPercentEncodeSet, and append the result to url's query. |
11082 | 24.5k | url.update_base_search(url_data.substr(input_position), |
11083 | 24.5k | query_percent_encode_set); |
11084 | 24.5k | ada_log("QUERY update_base_search completed "); |
11085 | 24.5k | if (fragment.has_value()) { |
11086 | 22.2k | url.update_unencoded_base_hash(*fragment); |
11087 | 22.2k | } |
11088 | 24.5k | } |
11089 | 24.5k | return url; |
11090 | 109k | } |
11091 | 111k | case state::HOST: { |
11092 | 111k | ada_log("HOST ", helpers::substring(url_data, input_position)); |
11093 | | |
11094 | 111k | std::string_view host_view = url_data.substr(input_position); |
11095 | 111k | auto [location, found_colon] = |
11096 | 111k | helpers::get_host_delimiter_location(url.is_special(), host_view); |
11097 | 111k | input_position = (location != std::string_view::npos) |
11098 | 111k | ? input_position + location |
11099 | 111k | : input_size; |
11100 | | // Otherwise, if c is U+003A (:) and insideBrackets is false, then: |
11101 | | // Note: the 'found_colon' value is true if and only if a colon was |
11102 | | // encountered while not inside brackets. |
11103 | 111k | if (found_colon) { |
11104 | | // If buffer is the empty string, validation error, return failure. |
11105 | | // Let host be the result of host parsing buffer with url is not |
11106 | | // special. |
11107 | 36.1k | ada_log("HOST parsing ", host_view); |
11108 | 36.1k | if (!url.parse_host(host_view)) { |
11109 | 422 | return url; |
11110 | 422 | } |
11111 | 35.7k | ada_log("HOST parsing results in ", url.get_hostname()); |
11112 | | // Set url's host to host, buffer to the empty string, and state to |
11113 | | // port state. |
11114 | 35.7k | state = state::PORT; |
11115 | 35.7k | input_position++; |
11116 | 35.7k | } |
11117 | | // Otherwise, if one of the following is true: |
11118 | | // - c is the EOF code point, U+002F (/), U+003F (?), or U+0023 (#) |
11119 | | // - url is special and c is U+005C (\) |
11120 | | // The get_host_delimiter_location function either brings us to |
11121 | | // the colon outside of the bracket, or to one of those characters. |
11122 | 75.7k | else { |
11123 | | // If url is special and host_view is the empty string, validation |
11124 | | // error, return failure. |
11125 | 75.7k | if (host_view.empty() && url.is_special()) { |
11126 | 58 | url.is_valid = false; |
11127 | 58 | return url; |
11128 | 58 | } |
11129 | 75.6k | ada_log("HOST parsing ", host_view, " href=", url.get_href()); |
11130 | | // Let host be the result of host parsing host_view with url is not |
11131 | | // special. |
11132 | 75.6k | if (host_view.empty()) { |
11133 | 379 | url.update_base_hostname(""); |
11134 | 75.2k | } else if (!url.parse_host(host_view)) { |
11135 | 2.69k | return url; |
11136 | 2.69k | } |
11137 | 72.9k | ada_log("HOST parsing results in ", url.get_hostname(), |
11138 | 72.9k | " href=", url.get_href()); |
11139 | | |
11140 | | // Set url's host to host, and state to path start state. |
11141 | 72.9k | state = state::PATH_START; |
11142 | 72.9k | } |
11143 | | |
11144 | 108k | break; |
11145 | 111k | } |
11146 | 108k | case state::OPAQUE_PATH: { |
11147 | 2.92k | ada_log("OPAQUE_PATH ", helpers::substring(url_data, input_position)); |
11148 | | // Opaque path, query, and fragment are structurally always valid: |
11149 | | // the parser would just percent-encode whatever is there. When we |
11150 | | // are not storing values (can_parse), we can return immediately. |
11151 | | // We must set has_opaque_path = true before returning so that when |
11152 | | // this URL is used as an internal base inside can_parse, NO_SCHEME |
11153 | | // correctly rejects relative inputs against an opaque-path base |
11154 | | // (e.g. can_parse("", &"W:") must return false). |
11155 | 2.92k | if constexpr (!store_values) { |
11156 | 920 | url.has_opaque_path = true; |
11157 | 920 | return url; |
11158 | 920 | } |
11159 | 0 | std::string_view view = url_data.substr(input_position); |
11160 | | // If c is U+003F (?), then set url's query to the empty string and |
11161 | | // state to query state. |
11162 | 2.92k | size_t location = view.find('?'); |
11163 | 2.92k | if (location != std::string_view::npos) { |
11164 | 221 | view.remove_suffix(view.size() - location); |
11165 | 221 | state = state::QUERY; |
11166 | 221 | input_position += location + 1; |
11167 | 2.70k | } else { |
11168 | 2.70k | input_position = input_size + 1; |
11169 | 2.70k | } |
11170 | 2.92k | url.has_opaque_path = true; |
11171 | | |
11172 | | // This is a really unlikely scenario in real world. We should not seek |
11173 | | // to optimize it. |
11174 | 2.92k | if (view.ends_with(' ')) { |
11175 | 100 | std::string modified_view = |
11176 | 100 | std::string(view.substr(0, view.size() - 1)) + "%20"; |
11177 | 100 | url.update_base_pathname(unicode::percent_encode( |
11178 | 100 | modified_view, character_sets::C0_CONTROL_PERCENT_ENCODE)); |
11179 | 2.82k | } else { |
11180 | 2.82k | url.update_base_pathname(unicode::percent_encode( |
11181 | 2.82k | view, character_sets::C0_CONTROL_PERCENT_ENCODE)); |
11182 | 2.82k | } |
11183 | 2.92k | break; |
11184 | 111k | } |
11185 | 35.7k | case state::PORT: { |
11186 | 35.7k | ada_log("PORT ", helpers::substring(url_data, input_position)); |
11187 | 35.7k | std::string_view port_view = url_data.substr(input_position); |
11188 | 35.7k | input_position += url.parse_port(port_view, true); |
11189 | 35.7k | if (!url.is_valid) { |
11190 | 378 | return url; |
11191 | 378 | } |
11192 | 35.3k | state = state::PATH_START; |
11193 | 35.3k | [[fallthrough]]; |
11194 | 35.3k | } |
11195 | 157k | case state::PATH_START: { |
11196 | 157k | ada_log("PATH_START ", helpers::substring(url_data, input_position)); |
11197 | | // Path, query, and fragment are structurally always valid: the |
11198 | | // parser would just percent-encode whatever is there. When we are |
11199 | | // not storing values (can_parse), we can return immediately since |
11200 | | // no subsequent state can invalidate the URL. |
11201 | 157k | if constexpr (!store_values) { |
11202 | 30.1k | return url; |
11203 | 30.1k | } |
11204 | | |
11205 | | // If url is special, then: |
11206 | 157k | if (url.is_special()) { |
11207 | | // Set state to path state. |
11208 | 125k | state = state::PATH; |
11209 | | |
11210 | | // Optimization: Avoiding going into PATH state improves the |
11211 | | // performance of urls ending with /. |
11212 | 125k | if (input_position == input_size) { |
11213 | 5.40k | if constexpr (store_values) { |
11214 | 5.40k | url.update_base_pathname("/"); |
11215 | 5.40k | if (fragment.has_value()) { |
11216 | 691 | url.update_unencoded_base_hash(*fragment); |
11217 | 691 | } |
11218 | 5.40k | } |
11219 | 5.40k | return url; |
11220 | 5.40k | } |
11221 | | // If c is neither U+002F (/) nor U+005C (\), then decrease pointer |
11222 | | // by 1. We know that (input_position == input_size) is impossible |
11223 | | // here, because of the previous if-check. |
11224 | 120k | if ((url_data[input_position] != '/') && |
11225 | 891 | (url_data[input_position] != '\\')) { |
11226 | 842 | break; |
11227 | 842 | } |
11228 | 120k | } |
11229 | | // Otherwise, if state override is not given and c is U+003F (?), |
11230 | | // set url's query to the empty string and state to query state. |
11231 | 31.5k | else if ((input_position != input_size) && |
11232 | 663 | (url_data[input_position] == '?')) { |
11233 | 40 | state = state::QUERY; |
11234 | 40 | } |
11235 | | // Otherwise, if c is not the EOF code point: |
11236 | 31.5k | else if (input_position != input_size) { |
11237 | | // Set state to path state. |
11238 | 623 | state = state::PATH; |
11239 | | |
11240 | | // If c is not U+002F (/), then decrease pointer by 1. |
11241 | 623 | if (url_data[input_position] != '/') { |
11242 | 0 | break; |
11243 | 0 | } |
11244 | 623 | } |
11245 | | |
11246 | 150k | input_position++; |
11247 | 150k | break; |
11248 | 157k | } |
11249 | 124k | case state::PATH: { |
11250 | 124k | ada_log("PATH ", helpers::substring(url_data, input_position)); |
11251 | | // Path, query, and fragment are structurally always valid: the |
11252 | | // parser would just percent-encode whatever is there. When we are |
11253 | | // not storing values (can_parse), we can return immediately since |
11254 | | // no subsequent state can invalidate the URL. |
11255 | 124k | if constexpr (!store_values) { |
11256 | 1.70k | return url; |
11257 | 1.70k | } |
11258 | 0 | std::string_view view = url_data.substr(input_position); |
11259 | | |
11260 | | // Most time, we do not need percent encoding. |
11261 | | // Furthermore, we can immediately locate the '?'. |
11262 | 124k | size_t locofquestionmark = view.find('?'); |
11263 | 124k | if (locofquestionmark != std::string_view::npos) { |
11264 | 24.2k | state = state::QUERY; |
11265 | 24.2k | view.remove_suffix(view.size() - locofquestionmark); |
11266 | 24.2k | input_position += locofquestionmark + 1; |
11267 | 100k | } else { |
11268 | 100k | input_position = input_size + 1; |
11269 | 100k | } |
11270 | 124k | if constexpr (store_values) { |
11271 | 123k | if constexpr (result_type_is_ada_url) { |
11272 | 0 | helpers::parse_prepared_path(view, url.type, url.path); |
11273 | 123k | } else { |
11274 | 123k | url.consume_prepared_path(view); |
11275 | 123k | ADA_ASSERT_TRUE(url.validate()); |
11276 | 123k | } |
11277 | 123k | } |
11278 | 124k | break; |
11279 | 157k | } |
11280 | 49.5k | case state::FILE_SLASH: { |
11281 | 49.5k | ada_log("FILE_SLASH ", helpers::substring(url_data, input_position)); |
11282 | | |
11283 | | // If c is U+002F (/) or U+005C (\), then: |
11284 | 49.5k | if ((input_position != input_size) && |
11285 | 49.4k | (url_data[input_position] == '/' || |
11286 | 49.2k | url_data[input_position] == '\\')) { |
11287 | 49.2k | ada_log("FILE_SLASH c is U+002F or U+005C"); |
11288 | | // Set state to file host state. |
11289 | 49.2k | state = state::FILE_HOST; |
11290 | 49.2k | input_position++; |
11291 | 49.2k | } else { |
11292 | 276 | ada_log("FILE_SLASH otherwise"); |
11293 | | // If base is non-null and base's scheme is "file", then: |
11294 | | // Note: it is unsafe to do base_url->scheme unless you know that |
11295 | | // base_url_has_value() is true. |
11296 | 276 | if (base_url != nullptr && base_url->type == scheme::type::FILE) { |
11297 | | // Set url's host to base's host. |
11298 | 170 | if constexpr (result_type_is_ada_url) { |
11299 | 0 | url.host = base_url->host; |
11300 | 170 | } else { |
11301 | 170 | url.update_host_to_base_host(base_url->get_host()); |
11302 | 170 | } |
11303 | | // If the code point substring from pointer to the end of input does |
11304 | | // not start with a Windows drive letter and base's path[0] is a |
11305 | | // normalized Windows drive letter, then append base's path[0] to |
11306 | | // url's path. |
11307 | 170 | if (!base_url->get_pathname().empty()) { |
11308 | 85 | if (!checkers::is_windows_drive_letter( |
11309 | 85 | url_data.substr(input_position))) { |
11310 | 80 | std::string_view first_base_url_path = |
11311 | 80 | base_url->get_pathname().substr(1); |
11312 | 80 | size_t loc = first_base_url_path.find('/'); |
11313 | 80 | if (loc != std::string_view::npos) { |
11314 | 19 | helpers::resize(first_base_url_path, loc); |
11315 | 19 | } |
11316 | 80 | if (checkers::is_normalized_windows_drive_letter( |
11317 | 80 | first_base_url_path)) { |
11318 | 2 | if constexpr (result_type_is_ada_url) { |
11319 | 0 | url.path += '/'; |
11320 | 0 | url.path += first_base_url_path; |
11321 | 2 | } else { |
11322 | 2 | url.append_base_pathname( |
11323 | 2 | helpers::concat("/", first_base_url_path)); |
11324 | 2 | } |
11325 | 2 | } |
11326 | 80 | } |
11327 | 85 | } |
11328 | 170 | } |
11329 | | |
11330 | | // Set state to path state, and decrease pointer by 1. |
11331 | 276 | state = state::PATH; |
11332 | 276 | } |
11333 | | |
11334 | 49.5k | break; |
11335 | 157k | } |
11336 | 49.2k | case state::FILE_HOST: { |
11337 | 49.2k | ada_log("FILE_HOST ", helpers::substring(url_data, input_position)); |
11338 | 49.2k | std::string_view view = url_data.substr(input_position); |
11339 | | |
11340 | 49.2k | size_t location = view.find_first_of("/\\?"); |
11341 | 49.2k | std::string_view file_host_buffer = view.substr( |
11342 | 49.2k | 0, (location != std::string_view::npos) ? location : view.size()); |
11343 | | |
11344 | 49.2k | if (checkers::is_windows_drive_letter(file_host_buffer)) { |
11345 | 67 | state = state::PATH; |
11346 | 49.2k | } else if (file_host_buffer.empty()) { |
11347 | | // Set url's host to the empty string. |
11348 | 33.4k | if constexpr (result_type_is_ada_url) { |
11349 | 0 | url.host = ""; |
11350 | 33.4k | } else { |
11351 | 33.4k | url.update_base_hostname(""); |
11352 | 33.4k | } |
11353 | | // Set state to path start state. |
11354 | 33.4k | state = state::PATH_START; |
11355 | 33.4k | } else { |
11356 | 15.7k | size_t consumed_bytes = file_host_buffer.size(); |
11357 | 15.7k | input_position += consumed_bytes; |
11358 | | // Let host be the result of host parsing buffer with url is not |
11359 | | // special. |
11360 | 15.7k | if (!url.parse_host(file_host_buffer)) { |
11361 | 515 | return url; |
11362 | 515 | } |
11363 | | |
11364 | 15.2k | if constexpr (result_type_is_ada_url) { |
11365 | | // If host is "localhost", then set host to the empty string. |
11366 | 0 | if (url.host.has_value() && url.host.value() == "localhost") { |
11367 | 0 | url.host = ""; |
11368 | 0 | } |
11369 | 15.2k | } else { |
11370 | 15.2k | if (url.get_hostname() == "localhost") { |
11371 | 329 | url.update_base_hostname(""); |
11372 | 329 | } |
11373 | 15.2k | } |
11374 | | |
11375 | | // Set buffer to the empty string and state to path start state. |
11376 | 15.2k | state = state::PATH_START; |
11377 | 15.2k | } |
11378 | | |
11379 | 48.7k | break; |
11380 | 49.2k | } |
11381 | 50.5k | case state::FILE: { |
11382 | 50.5k | ada_log("FILE ", helpers::substring(url_data, input_position)); |
11383 | 50.5k | std::string_view file_view = url_data.substr(input_position); |
11384 | | |
11385 | 50.5k | url.set_protocol_as_file(); |
11386 | 50.5k | if constexpr (result_type_is_ada_url) { |
11387 | | // Set url's host to the empty string. |
11388 | 0 | url.host = ""; |
11389 | 50.5k | } else { |
11390 | 50.5k | url.update_base_hostname(""); |
11391 | 50.5k | } |
11392 | | // If c is U+002F (/) or U+005C (\), then: |
11393 | 50.5k | if (input_position != input_size && |
11394 | 50.4k | (url_data[input_position] == '/' || |
11395 | 49.5k | url_data[input_position] == '\\')) { |
11396 | 49.5k | ada_log("FILE c is U+002F or U+005C"); |
11397 | | // Set state to file slash state. |
11398 | 49.5k | state = state::FILE_SLASH; |
11399 | 49.5k | } |
11400 | | // Otherwise, if base is non-null and base's scheme is "file": |
11401 | 1.04k | else if (base_url != nullptr && base_url->type == scheme::type::FILE) { |
11402 | | // Set url's host to base's host, url's path to a clone of base's |
11403 | | // path, and url's query to base's query. |
11404 | 354 | ada_log("FILE base non-null"); |
11405 | 354 | if constexpr (result_type_is_ada_url) { |
11406 | 0 | url.host = base_url->host; |
11407 | 0 | url.path = base_url->path; |
11408 | 0 | url.query = base_url->query; |
11409 | 354 | } else { |
11410 | 354 | url.update_host_to_base_host(base_url->get_hostname()); |
11411 | 354 | url.update_base_pathname(base_url->get_pathname()); |
11412 | 354 | if (base_url->has_search()) { |
11413 | | // get_search() returns "" for an empty query string (URL ends |
11414 | | // with '?'). update_base_search("") would incorrectly clear the |
11415 | | // query, so pass "?" to preserve the empty query distinction. |
11416 | 42 | auto s = base_url->get_search(); |
11417 | 42 | url.update_base_search(s.empty() ? std::string_view("?") : s); |
11418 | 42 | } |
11419 | 354 | } |
11420 | 354 | url.has_opaque_path = base_url->has_opaque_path; |
11421 | | |
11422 | | // If c is U+003F (?), then set url's query to the empty string and |
11423 | | // state to query state. |
11424 | 354 | if (input_position != input_size && url_data[input_position] == '?') { |
11425 | 6 | state = state::QUERY; |
11426 | 6 | } |
11427 | | // Otherwise, if c is not the EOF code point: |
11428 | 348 | else if (input_position != input_size) { |
11429 | | // Set url's query to null. |
11430 | 244 | url.clear_search(); |
11431 | | // If the code point substring from pointer to the end of input does |
11432 | | // not start with a Windows drive letter, then shorten url's path. |
11433 | 244 | if (!checkers::is_windows_drive_letter(file_view)) { |
11434 | 228 | if constexpr (result_type_is_ada_url) { |
11435 | 0 | helpers::shorten_path(url.path, url.type); |
11436 | 228 | } else { |
11437 | 228 | std::string_view path = url.get_pathname(); |
11438 | 228 | if (helpers::shorten_path(path, url.type)) { |
11439 | 113 | url.update_base_pathname(std::move(std::string(path))); |
11440 | 113 | } |
11441 | 228 | } |
11442 | 228 | } |
11443 | | // Otherwise: |
11444 | 16 | else { |
11445 | | // Set url's path to an empty list. |
11446 | 16 | url.clear_pathname(); |
11447 | 16 | url.has_opaque_path = true; |
11448 | 16 | } |
11449 | | |
11450 | | // Set state to path state and decrease pointer by 1. |
11451 | 244 | state = state::PATH; |
11452 | 244 | break; |
11453 | 244 | } |
11454 | 354 | } |
11455 | | // Otherwise, set state to path state, and decrease pointer by 1. |
11456 | 690 | else { |
11457 | 690 | ada_log("FILE go to path"); |
11458 | 690 | state = state::PATH; |
11459 | 690 | break; |
11460 | 690 | } |
11461 | | |
11462 | 49.6k | input_position++; |
11463 | 49.6k | break; |
11464 | 50.5k | } |
11465 | 0 | default: |
11466 | 0 | unreachable(); |
11467 | 1.17M | } |
11468 | 1.17M | } |
11469 | 126k | if constexpr (store_values) { |
11470 | 126k | if (fragment.has_value()) { |
11471 | 1.17k | url.update_unencoded_base_hash(*fragment); |
11472 | 1.17k | } |
11473 | 126k | } |
11474 | | // Check the resulting (normalized) URL size against the maximum input length. |
11475 | | // Normalization (percent-encoding, IDNA, etc.) can expand the URL beyond the |
11476 | | // original input size. |
11477 | 126k | if constexpr (store_values) { |
11478 | 126k | if (url.is_valid) { |
11479 | 101k | if constexpr (result_type_is_ada_url_aggregator) { |
11480 | 101k | if (url.buffer.size() > max_input_length) { |
11481 | 0 | url.is_valid = false; |
11482 | 0 | } |
11483 | 101k | } else { |
11484 | 0 | if (url.get_href_size() > max_input_length) { |
11485 | 0 | url.is_valid = false; |
11486 | 0 | } |
11487 | 0 | } |
11488 | 101k | } |
11489 | 126k | } |
11490 | 126k | return url; |
11491 | 213k | } Unexecuted instantiation: ada::url ada::parser::parse_url_impl<ada::url, true>(std::__1::basic_string_view<char, std::__1::char_traits<char> >, ada::url const*) ada::url_aggregator ada::parser::parse_url_impl<ada::url_aggregator, true>(std::__1::basic_string_view<char, std::__1::char_traits<char> >, ada::url_aggregator const*) Line | Count | Source | 10503 | 169k | const result_type* base_url) { | 10504 | | // We can specialize the implementation per type. | 10505 | | // Important: result_type_is_ada_url is evaluated at *compile time*. This | 10506 | | // means that doing if constexpr(result_type_is_ada_url) { something } else { | 10507 | | // something else } is free (at runtime). This means that ada::url_aggregator | 10508 | | // and ada::url **do not have to support the exact same API**. | 10509 | 169k | constexpr bool result_type_is_ada_url = std::is_same_v<url, result_type>; | 10510 | 169k | constexpr bool result_type_is_ada_url_aggregator = | 10511 | 169k | std::is_same_v<url_aggregator, result_type>; | 10512 | 169k | static_assert(result_type_is_ada_url || | 10513 | 169k | result_type_is_ada_url_aggregator); // We don't support | 10514 | | // anything else for now. | 10515 | | | 10516 | 169k | ada_log("ada::parser::parse_url('", user_input, "' [", user_input.size(), | 10517 | 169k | " bytes],", (base_url != nullptr ? base_url->to_string() : "null"), | 10518 | 169k | ")"); | 10519 | | | 10520 | 169k | state state = state::SCHEME_START; | 10521 | 169k | result_type url{}; | 10522 | | | 10523 | 169k | const uint32_t max_input_length = ada::get_max_input_length(); | 10524 | | | 10525 | | // We refuse to parse URL strings that exceed the maximum input length. | 10526 | | // By default, this is 4GB but can be configured via | 10527 | | // ada::set_max_input_length(). | 10528 | 169k | if (user_input.size() > max_input_length) [[unlikely]] { | 10529 | 0 | url.is_valid = false; | 10530 | 0 | } | 10531 | | // Going forward, user_input.size() is in [0, | 10532 | | // std::numeric_limits<uint32_t>::max). If we are provided with an invalid | 10533 | | // base, or the optional_url was invalid, we must return. | 10534 | 169k | if (base_url != nullptr) { | 10535 | 3.31k | url.is_valid &= base_url->is_valid; | 10536 | 3.31k | } | 10537 | 169k | if (!url.is_valid) { | 10538 | 0 | return url; | 10539 | 0 | } | 10540 | | | 10541 | | // Simple absolute http(s) fast path (before tabs/newline scan). | 10542 | | // Skip digit-led hosts (IPv4) with a cheap peek. | 10543 | 169k | if constexpr (store_values) { | 10544 | 169k | if (base_url == nullptr) { | 10545 | 166k | const auto* p = reinterpret_cast<const uint8_t*>(user_input.data()); | 10546 | 166k | const size_t n = user_input.size(); | 10547 | 166k | const bool digit_led_host = (n >= 8 && p[4] == ':' && p[5] == '/' && | 10548 | 74.0k | p[6] == '/' && p[7] >= '0' && p[7] <= '9') || | 10549 | 142k | (n >= 9 && p[5] == ':' && p[6] == '/' && | 10550 | 67.7k | p[7] == '/' && p[8] >= '0' && p[8] <= '9'); | 10551 | 166k | if (!digit_led_host && try_parse_simple_absolute(user_input, url)) { | 10552 | 24.8k | if constexpr (result_type_is_ada_url_aggregator) { | 10553 | 24.8k | if (url.buffer.size() > max_input_length) [[unlikely]] { | 10554 | 0 | url.is_valid = false; | 10555 | 0 | } | 10556 | | } else { | 10557 | | if (url.get_href_size() > max_input_length) [[unlikely]] { | 10558 | | url.is_valid = false; | 10559 | | } | 10560 | | } | 10561 | 24.8k | return url; | 10562 | 24.8k | } | 10563 | 166k | } | 10564 | 169k | } | 10565 | | | 10566 | 145k | std::string tmp_buffer; | 10567 | 169k | std::string_view url_data; | 10568 | 169k | if (unicode::has_tabs_or_newline(user_input)) [[unlikely]] { | 10569 | 451 | tmp_buffer = user_input; | 10570 | | // Optimization opportunity: Instead of copying and then pruning, we could | 10571 | | // just directly build the string from user_input. | 10572 | 451 | helpers::remove_ascii_tab_or_newline(tmp_buffer); | 10573 | 451 | url_data = tmp_buffer; | 10574 | 169k | } else [[likely]] { | 10575 | 169k | url_data = user_input; | 10576 | 169k | } | 10577 | | | 10578 | | // Leading and trailing control characters are uncommon and easy to deal with | 10579 | | // (no performance concern). | 10580 | 169k | helpers::trim_c0_whitespace(url_data); | 10581 | | | 10582 | 169k | if constexpr (result_type_is_ada_url_aggregator && store_values) { | 10583 | | // Most of the time, we just need user_input.size(). | 10584 | | // In some instances, we may need a bit more. | 10585 | | /////////////////////////// | 10586 | | // This is *very* important. This line should *not* be removed | 10587 | | // hastily. There are principled reasons why reserve is important | 10588 | | // for performance. If you have a benchmark with small inputs, | 10589 | | // it may not matter, but in other instances, it could. | 10590 | | //// | 10591 | | // This rounds up to the next power of two. | 10592 | | // We know that user_input.size() is in [0, | 10593 | | // std::numeric_limits<uint32_t>::max). | 10594 | 169k | uint32_t reserve_capacity = | 10595 | 169k | (0xFFFFFFFF >> | 10596 | 169k | helpers::leading_zeroes(uint32_t(1 | user_input.size()))) + | 10597 | 169k | 1; | 10598 | 169k | url.reserve(reserve_capacity); | 10599 | 169k | } | 10600 | | | 10601 | | // Optimization opportunity. Most websites do not have fragment. | 10602 | 169k | std::optional<std::string_view> fragment = helpers::prune_hash(url_data); | 10603 | | // We add it last so that an implementation like ada::url_aggregator | 10604 | | // can append it last to its internal buffer, thus improving performance. | 10605 | | | 10606 | | // Here url_data no longer has its fragment. | 10607 | | // We are going to access the data from url_data (it is immutable). | 10608 | | // At any given time, we are pointing at byte 'input_position' in url_data. | 10609 | | // The input_position variable should range from 0 to input_size. | 10610 | | // It is illegal to access url_data at input_size. | 10611 | 169k | size_t input_position = 0; | 10612 | 169k | const size_t input_size = url_data.size(); | 10613 | | // Keep running the following state machine by switching on state. | 10614 | | // If after a run pointer points to the EOF code point, go to the next step. | 10615 | | // Otherwise, increase pointer by 1 and continue with the state machine. | 10616 | | // We never decrement input_position. | 10617 | 1.08M | while (input_position <= input_size) { | 10618 | 959k | ada_log("In parsing at ", input_position, " out of ", input_size, | 10619 | 959k | " in state ", ada::to_string(state)); | 10620 | 959k | switch (state) { | 10621 | 145k | case state::SCHEME_START: { | 10622 | 145k | ada_log("SCHEME_START ", helpers::substring(url_data, input_position)); | 10623 | | // If c is an ASCII alpha, append c, lowercased, to buffer, and set | 10624 | | // state to scheme state. | 10625 | 145k | if ((input_position != input_size) && | 10626 | 138k | checkers::is_alpha(url_data[input_position])) { | 10627 | 134k | state = state::SCHEME; | 10628 | 134k | input_position++; | 10629 | 134k | } else { | 10630 | | // Otherwise, if state override is not given, set state to no scheme | 10631 | | // state and decrease pointer by 1. | 10632 | 10.1k | state = state::NO_SCHEME; | 10633 | 10.1k | } | 10634 | 145k | break; | 10635 | 0 | } | 10636 | 134k | case state::SCHEME: { | 10637 | 134k | ada_log("SCHEME ", helpers::substring(url_data, input_position)); | 10638 | | // If c is an ASCII alphanumeric, U+002B (+), U+002D (-), or U+002E (.), | 10639 | | // append c, lowercased, to buffer. | 10640 | 591k | while ((input_position != input_size) && | 10641 | 590k | (unicode::is_alnum_plus(url_data[input_position]))) { | 10642 | 456k | input_position++; | 10643 | 456k | } | 10644 | | // Otherwise, if c is U+003A (:), then: | 10645 | 134k | if ((input_position != input_size) && | 10646 | 134k | (url_data[input_position] == ':')) { | 10647 | 133k | ada_log("SCHEME the scheme should be ", | 10648 | 133k | url_data.substr(0, input_position)); | 10649 | | if constexpr (result_type_is_ada_url) { | 10650 | | if (!url.parse_scheme(url_data.substr(0, input_position))) { | 10651 | | return url; | 10652 | | } | 10653 | 133k | } else { | 10654 | | // we pass the colon along instead of painfully adding it back. | 10655 | 133k | if (!url.parse_scheme_with_colon( | 10656 | 133k | url_data.substr(0, input_position + 1))) { | 10657 | 0 | return url; | 10658 | 0 | } | 10659 | 133k | } | 10660 | 133k | ada_log("SCHEME the scheme is ", url.get_protocol()); | 10661 | | | 10662 | | // If url's scheme is "file", then: | 10663 | | // NOLINTNEXTLINE(bugprone-branch-clone) | 10664 | 133k | if (url.type == scheme::type::FILE) { | 10665 | | // Set state to file state. | 10666 | 36.9k | state = state::FILE; | 10667 | 36.9k | } | 10668 | | // Otherwise, if url is special, base is non-null, and base's scheme | 10669 | | // is url's scheme: Note: Doing base_url->scheme is unsafe if base_url | 10670 | | // != nullptr is false. | 10671 | 96.1k | else if (url.is_special() && base_url != nullptr && | 10672 | 1.60k | base_url->type == url.type) { | 10673 | | // Set state to special relative or authority state. | 10674 | 340 | state = state::SPECIAL_RELATIVE_OR_AUTHORITY; | 10675 | 340 | } | 10676 | | // Otherwise, if url is special, set state to special authority | 10677 | | // slashes state. | 10678 | 95.8k | else if (url.is_special()) { | 10679 | 90.8k | state = state::SPECIAL_AUTHORITY_SLASHES; | 10680 | 90.8k | } | 10681 | | // Otherwise, if remaining starts with an U+002F (/), set state to | 10682 | | // path or authority state and increase pointer by 1. | 10683 | 4.95k | else if (input_position + 1 < input_size && | 10684 | 4.31k | url_data[input_position + 1] == '/') { | 10685 | 2.94k | state = state::PATH_OR_AUTHORITY; | 10686 | 2.94k | input_position++; | 10687 | 2.94k | } | 10688 | | // Otherwise, set url's path to the empty string and set state to | 10689 | | // opaque path state. | 10690 | 2.00k | else { | 10691 | 2.00k | state = state::OPAQUE_PATH; | 10692 | 2.00k | } | 10693 | 133k | } | 10694 | | // Otherwise, if state override is not given, set buffer to the empty | 10695 | | // string, state to no scheme state, and start over (from the first code | 10696 | | // point in input). | 10697 | 1.77k | else { | 10698 | 1.77k | state = state::NO_SCHEME; | 10699 | 1.77k | input_position = 0; | 10700 | 1.77k | break; | 10701 | 1.77k | } | 10702 | 133k | input_position++; | 10703 | 133k | break; | 10704 | 134k | } | 10705 | 11.9k | case state::NO_SCHEME: { | 10706 | 11.9k | ada_log("NO_SCHEME ", helpers::substring(url_data, input_position)); | 10707 | | // The fragment was pruned from url_data before the state machine ran, | 10708 | | // so 'c is U+0023 (#)' holds exactly when a fragment was found and | 10709 | | // nothing else remains in front of it. | 10710 | 11.9k | const bool c_is_hash = | 10711 | 11.9k | fragment.has_value() && input_position == input_size; | 10712 | | // If base is null, or base has an opaque path and c is not U+0023 (#), | 10713 | | // validation error, return failure. | 10714 | 11.9k | if (base_url == nullptr || (base_url->has_opaque_path && !c_is_hash)) { | 10715 | 11.1k | ada_log("NO_SCHEME validation error"); | 10716 | 11.1k | url.is_valid = false; | 10717 | 11.1k | return url; | 10718 | 11.1k | } | 10719 | | // Otherwise, if base has an opaque path and c is U+0023 (#), | 10720 | | // set url's scheme to base's scheme, url's path to base's path, url's | 10721 | | // query to base's query, and set state to fragment state. | 10722 | 788 | else if (base_url->has_opaque_path && c_is_hash) { | 10723 | 59 | ada_log("NO_SCHEME opaque base with fragment"); | 10724 | 59 | url.copy_scheme(*base_url); | 10725 | 59 | url.has_opaque_path = base_url->has_opaque_path; | 10726 | | | 10727 | | if constexpr (result_type_is_ada_url) { | 10728 | | url.path = base_url->path; | 10729 | | url.query = base_url->query; | 10730 | 59 | } else { | 10731 | 59 | url.update_base_pathname(base_url->get_pathname()); | 10732 | 59 | if (base_url->has_search()) { | 10733 | | // get_search() returns "" for an empty query string (URL ends | 10734 | | // with '?'). update_base_search("") would incorrectly clear the | 10735 | | // query, so pass "?" to preserve the empty query distinction. | 10736 | 35 | auto s = base_url->get_search(); | 10737 | 35 | url.update_base_search(s.empty() ? std::string_view("?") : s); | 10738 | 35 | } | 10739 | 59 | } | 10740 | 59 | url.update_unencoded_base_hash(*fragment); | 10741 | 59 | return url; | 10742 | 59 | } | 10743 | | // Otherwise, if base's scheme is not "file", set state to relative | 10744 | | // state and decrease pointer by 1. | 10745 | | // NOLINTNEXTLINE(bugprone-branch-clone) | 10746 | 729 | else if (base_url->type != scheme::type::FILE) { | 10747 | 475 | ada_log("NO_SCHEME non-file relative path"); | 10748 | 475 | state = state::RELATIVE_SCHEME; | 10749 | 475 | } | 10750 | | // Otherwise, set state to file state and decrease pointer by 1. | 10751 | 254 | else { | 10752 | 254 | ada_log("NO_SCHEME file base type"); | 10753 | 254 | state = state::FILE; | 10754 | 254 | } | 10755 | 729 | break; | 10756 | 11.9k | } | 10757 | 92.7k | case state::AUTHORITY: { | 10758 | 92.7k | ada_log("AUTHORITY ", helpers::substring(url_data, input_position)); | 10759 | | // most URLs have no @. Having no @ tells us that we don't have to worry | 10760 | | // about AUTHORITY. Of course, we could have @ and still not have to | 10761 | | // worry about AUTHORITY. | 10762 | | // TODO: Instead of just collecting a bool, collect the location of the | 10763 | | // '@' and do something useful with it. | 10764 | | // TODO: We could do various processing early on, using a single pass | 10765 | | // over the string to collect information about it, e.g., telling us | 10766 | | // whether there is a @ and if so, where (or how many). | 10767 | | | 10768 | | // Check if url data contains an @. | 10769 | 92.7k | if (url_data.find('@', input_position) == std::string_view::npos) { | 10770 | 33.2k | state = state::HOST; | 10771 | 33.2k | break; | 10772 | 33.2k | } | 10773 | 59.4k | bool at_sign_seen{false}; | 10774 | 59.4k | bool password_token_seen{false}; | 10775 | | /** | 10776 | | * We expect something of the sort... | 10777 | | * https://user:pass@example.com:1234/foo/bar?baz#quux | 10778 | | * --------^ | 10779 | | */ | 10780 | 132k | do { | 10781 | 132k | std::string_view view = url_data.substr(input_position); | 10782 | | // The delimiters are @, /, ? \\. | 10783 | 132k | size_t location = | 10784 | 132k | url.is_special() ? helpers::find_authority_delimiter_special(view) | 10785 | 132k | : helpers::find_authority_delimiter(view); | 10786 | 132k | std::string_view authority_view = view.substr(0, location); | 10787 | 132k | size_t end_of_authority = input_position + authority_view.size(); | 10788 | | // If c is U+0040 (@), then: | 10789 | 132k | if ((end_of_authority != input_size) && | 10790 | 131k | (url_data[end_of_authority] == '@')) { | 10791 | | // If atSignSeen is true, then prepend "%40" to buffer. | 10792 | 73.1k | if (at_sign_seen) { | 10793 | 13.8k | if (password_token_seen) { | 10794 | | if constexpr (result_type_is_ada_url) { | 10795 | | url.password += "%40"; | 10796 | 3.81k | } else { | 10797 | 3.81k | url.append_base_password("%40"); | 10798 | 3.81k | } | 10799 | 10.0k | } else { | 10800 | | if constexpr (result_type_is_ada_url) { | 10801 | | url.username += "%40"; | 10802 | 10.0k | } else { | 10803 | 10.0k | url.append_base_username("%40"); | 10804 | 10.0k | } | 10805 | 10.0k | } | 10806 | 13.8k | } | 10807 | | | 10808 | 73.1k | at_sign_seen = true; | 10809 | | | 10810 | 73.1k | if (!password_token_seen) { | 10811 | 69.3k | size_t password_token_location = authority_view.find(':'); | 10812 | 69.3k | password_token_seen = | 10813 | 69.3k | password_token_location != std::string_view::npos; | 10814 | | | 10815 | 69.3k | if constexpr (store_values) { | 10816 | 69.3k | if (!password_token_seen) { | 10817 | | if constexpr (result_type_is_ada_url) { | 10818 | | url.username += unicode::percent_encode( | 10819 | | authority_view, | 10820 | | character_sets::USERINFO_PERCENT_ENCODE); | 10821 | 10.4k | } else { | 10822 | 10.4k | url.append_base_username(unicode::percent_encode( | 10823 | 10.4k | authority_view, | 10824 | 10.4k | character_sets::USERINFO_PERCENT_ENCODE)); | 10825 | 10.4k | } | 10826 | 58.8k | } else { | 10827 | | if constexpr (result_type_is_ada_url) { | 10828 | | url.username += unicode::percent_encode( | 10829 | | authority_view.substr(0, password_token_location), | 10830 | | character_sets::USERINFO_PERCENT_ENCODE); | 10831 | | url.password += unicode::percent_encode( | 10832 | | authority_view.substr(password_token_location + 1), | 10833 | | character_sets::USERINFO_PERCENT_ENCODE); | 10834 | 58.8k | } else { | 10835 | 58.8k | url.append_base_username(unicode::percent_encode( | 10836 | 58.8k | authority_view.substr(0, password_token_location), | 10837 | 58.8k | character_sets::USERINFO_PERCENT_ENCODE)); | 10838 | 58.8k | url.append_base_password(unicode::percent_encode( | 10839 | 58.8k | authority_view.substr(password_token_location + 1), | 10840 | 58.8k | character_sets::USERINFO_PERCENT_ENCODE)); | 10841 | 58.8k | } | 10842 | 58.8k | } | 10843 | 69.3k | } | 10844 | 69.3k | } else if constexpr (store_values) { | 10845 | | if constexpr (result_type_is_ada_url) { | 10846 | | url.password += unicode::percent_encode( | 10847 | | authority_view, character_sets::USERINFO_PERCENT_ENCODE); | 10848 | 3.81k | } else { | 10849 | 3.81k | url.append_base_password(unicode::percent_encode( | 10850 | 3.81k | authority_view, character_sets::USERINFO_PERCENT_ENCODE)); | 10851 | 3.81k | } | 10852 | 3.81k | } | 10853 | 73.1k | } | 10854 | | // Otherwise, if one of the following is true: | 10855 | | // - c is the EOF code point, U+002F (/), U+003F (?), or U+0023 (#) | 10856 | | // - url is special and c is U+005C (\) | 10857 | 59.4k | else if (end_of_authority == input_size || | 10858 | 58.6k | url_data[end_of_authority] == '/' || | 10859 | 102 | url_data[end_of_authority] == '?' || | 10860 | 59.4k | (url.is_special() && url_data[end_of_authority] == '\\')) { | 10861 | | // If atSignSeen is true and authority_view is the empty string, | 10862 | | // validation error, return failure. | 10863 | 59.4k | if (at_sign_seen && authority_view.empty()) { | 10864 | 120 | url.is_valid = false; | 10865 | 120 | return url; | 10866 | 120 | } | 10867 | 59.3k | state = state::HOST; | 10868 | 59.3k | break; | 10869 | 59.4k | } | 10870 | 73.1k | if (end_of_authority == input_size) { | 10871 | 0 | if constexpr (store_values) { | 10872 | 0 | if (fragment.has_value()) { | 10873 | 0 | url.update_unencoded_base_hash(*fragment); | 10874 | 0 | } | 10875 | 0 | } | 10876 | 0 | return url; | 10877 | 0 | } | 10878 | 73.1k | input_position = end_of_authority + 1; | 10879 | 73.1k | } while (true); | 10880 | | | 10881 | 59.3k | break; | 10882 | 59.4k | } | 10883 | 59.3k | case state::SPECIAL_RELATIVE_OR_AUTHORITY: { | 10884 | 340 | ada_log("SPECIAL_RELATIVE_OR_AUTHORITY ", | 10885 | 340 | helpers::substring(url_data, input_position)); | 10886 | | | 10887 | | // If c is U+002F (/) and remaining starts with U+002F (/), | 10888 | | // then set state to special authority ignore slashes state and increase | 10889 | | // pointer by 1. | 10890 | 340 | if (url_data.substr(input_position, 2) == "//") { | 10891 | 206 | state = state::SPECIAL_AUTHORITY_IGNORE_SLASHES; | 10892 | 206 | input_position += 2; | 10893 | 206 | } else { | 10894 | | // Otherwise, validation error, set state to relative state and | 10895 | | // decrease pointer by 1. | 10896 | 134 | state = state::RELATIVE_SCHEME; | 10897 | 134 | } | 10898 | | | 10899 | 340 | break; | 10900 | 59.4k | } | 10901 | 2.94k | case state::PATH_OR_AUTHORITY: { | 10902 | 2.94k | ada_log("PATH_OR_AUTHORITY ", | 10903 | 2.94k | helpers::substring(url_data, input_position)); | 10904 | | | 10905 | | // If c is U+002F (/), then set state to authority state. | 10906 | 2.94k | if ((input_position != input_size) && | 10907 | 2.48k | (url_data[input_position] == '/')) { | 10908 | 1.59k | state = state::AUTHORITY; | 10909 | 1.59k | input_position++; | 10910 | 1.59k | } else { | 10911 | | // Otherwise, set state to path state, and decrease pointer by 1. | 10912 | 1.35k | state = state::PATH; | 10913 | 1.35k | } | 10914 | | | 10915 | 2.94k | break; | 10916 | 59.4k | } | 10917 | 609 | case state::RELATIVE_SCHEME: { | 10918 | 609 | ada_log("RELATIVE_SCHEME ", | 10919 | 609 | helpers::substring(url_data, input_position)); | 10920 | | | 10921 | | // Set url's scheme to base's scheme. | 10922 | 609 | url.copy_scheme(*base_url); | 10923 | | | 10924 | | // If c is U+002F (/), then set state to relative slash state. | 10925 | 609 | if ((input_position != input_size) && | 10926 | | // NOLINTNEXTLINE(bugprone-branch-clone) | 10927 | 464 | (url_data[input_position] == '/')) { | 10928 | 57 | ada_log( | 10929 | 57 | "RELATIVE_SCHEME if c is U+002F (/), then set state to relative " | 10930 | 57 | "slash state"); | 10931 | 57 | state = state::RELATIVE_SLASH; | 10932 | 552 | } else if (url.is_special() && (input_position != input_size) && | 10933 | 352 | (url_data[input_position] == '\\')) { | 10934 | | // Otherwise, if url is special and c is U+005C (\), validation error, | 10935 | | // set state to relative slash state. | 10936 | 2 | ada_log( | 10937 | 2 | "RELATIVE_SCHEME if url is special and c is U+005C, validation " | 10938 | 2 | "error, set state to relative slash state"); | 10939 | 2 | state = state::RELATIVE_SLASH; | 10940 | 550 | } else { | 10941 | 550 | ada_log("RELATIVE_SCHEME otherwise"); | 10942 | | // Set url's username to base's username, url's password to base's | 10943 | | // password, url's host to base's host, url's port to base's port, | 10944 | | // url's path to a clone of base's path, and url's query to base's | 10945 | | // query. | 10946 | | if constexpr (result_type_is_ada_url) { | 10947 | | url.username = base_url->username; | 10948 | | url.password = base_url->password; | 10949 | | url.host = base_url->host; | 10950 | | url.port = base_url->port; | 10951 | | // cloning the base path includes cloning the has_opaque_path flag | 10952 | | url.has_opaque_path = base_url->has_opaque_path; | 10953 | | url.path = base_url->path; | 10954 | | url.query = base_url->query; | 10955 | 550 | } else { | 10956 | 550 | url.update_base_authority(base_url->get_href(), | 10957 | 550 | base_url->get_components()); | 10958 | 550 | url.update_host_to_base_host(base_url->get_hostname()); | 10959 | 550 | url.update_base_port(base_url->retrieve_base_port()); | 10960 | | // cloning the base path includes cloning the has_opaque_path flag | 10961 | 550 | url.has_opaque_path = base_url->has_opaque_path; | 10962 | 550 | url.update_base_pathname(base_url->get_pathname()); | 10963 | 550 | if (base_url->has_search()) { | 10964 | | // get_search() returns "" for an empty query string (URL ends | 10965 | | // with '?'). update_base_search("") would incorrectly clear the | 10966 | | // query, so pass "?" to preserve the empty query distinction. | 10967 | 81 | auto s = base_url->get_search(); | 10968 | 81 | url.update_base_search(s.empty() ? std::string_view("?") : s); | 10969 | 81 | } | 10970 | 550 | } | 10971 | | | 10972 | 550 | url.has_opaque_path = base_url->has_opaque_path; | 10973 | | | 10974 | | // If c is U+003F (?), then set url's query to the empty string, and | 10975 | | // state to query state. | 10976 | 550 | if ((input_position != input_size) && | 10977 | 405 | (url_data[input_position] == '?')) { | 10978 | 7 | state = state::QUERY; | 10979 | 7 | } | 10980 | | // Otherwise, if c is not the EOF code point: | 10981 | 543 | else if (input_position != input_size) { | 10982 | | // Set url's query to null. | 10983 | 398 | url.clear_search(); | 10984 | | if constexpr (result_type_is_ada_url) { | 10985 | | // Shorten url's path. | 10986 | | helpers::shorten_path(url.path, url.type); | 10987 | 398 | } else { | 10988 | 398 | std::string_view path = url.get_pathname(); | 10989 | 398 | if (helpers::shorten_path(path, url.type)) { | 10990 | 392 | url.update_base_pathname(std::move(std::string(path))); | 10991 | 392 | } | 10992 | 398 | } | 10993 | | // Set state to path state and decrease pointer by 1. | 10994 | 398 | state = state::PATH; | 10995 | 398 | break; | 10996 | 398 | } | 10997 | 550 | } | 10998 | 211 | input_position++; | 10999 | 211 | break; | 11000 | 609 | } | 11001 | 59 | case state::RELATIVE_SLASH: { | 11002 | 59 | ada_log("RELATIVE_SLASH ", | 11003 | 59 | helpers::substring(url_data, input_position)); | 11004 | | | 11005 | | // If url is special and c is U+002F (/) or U+005C (\), then: | 11006 | | // NOLINTNEXTLINE(bugprone-branch-clone) | 11007 | 59 | if (url.is_special() && (input_position != input_size) && | 11008 | 45 | (url_data[input_position] == '/' || | 11009 | 24 | url_data[input_position] == '\\')) { | 11010 | | // Set state to special authority ignore slashes state. | 11011 | 23 | state = state::SPECIAL_AUTHORITY_IGNORE_SLASHES; | 11012 | 23 | } | 11013 | | // Otherwise, if c is U+002F (/), then set state to authority state. | 11014 | 36 | else if ((input_position != input_size) && | 11015 | 24 | (url_data[input_position] == '/')) { | 11016 | 1 | state = state::AUTHORITY; | 11017 | 1 | } | 11018 | | // Otherwise, set | 11019 | | // - url's username to base's username, | 11020 | | // - url's password to base's password, | 11021 | | // - url's host to base's host, | 11022 | | // - url's port to base's port, | 11023 | | // - state to path state, and then, decrease pointer by 1. | 11024 | 35 | else { | 11025 | | if constexpr (result_type_is_ada_url) { | 11026 | | url.username = base_url->username; | 11027 | | url.password = base_url->password; | 11028 | | url.host = base_url->host; | 11029 | | url.port = base_url->port; | 11030 | 35 | } else { | 11031 | 35 | url.update_base_authority(base_url->get_href(), | 11032 | 35 | base_url->get_components()); | 11033 | 35 | url.update_host_to_base_host(base_url->get_hostname()); | 11034 | 35 | url.update_base_port(base_url->retrieve_base_port()); | 11035 | 35 | } | 11036 | 35 | state = state::PATH; | 11037 | 35 | break; | 11038 | 35 | } | 11039 | | | 11040 | 24 | input_position++; | 11041 | 24 | break; | 11042 | 59 | } | 11043 | 90.8k | case state::SPECIAL_AUTHORITY_SLASHES: { | 11044 | 90.8k | ada_log("SPECIAL_AUTHORITY_SLASHES ", | 11045 | 90.8k | helpers::substring(url_data, input_position)); | 11046 | | | 11047 | | // If c is U+002F (/) and remaining starts with U+002F (/), | 11048 | | // then set state to special authority ignore slashes state and increase | 11049 | | // pointer by 1. | 11050 | 90.8k | if (url_data.substr(input_position, 2) == "//") { | 11051 | 84.9k | input_position += 2; | 11052 | 84.9k | } | 11053 | | | 11054 | 90.8k | [[fallthrough]]; | 11055 | 90.8k | } | 11056 | 91.1k | case state::SPECIAL_AUTHORITY_IGNORE_SLASHES: { | 11057 | 91.1k | ada_log("SPECIAL_AUTHORITY_IGNORE_SLASHES ", | 11058 | 91.1k | helpers::substring(url_data, input_position)); | 11059 | | | 11060 | | // If c is neither U+002F (/) nor U+005C (\), then set state to | 11061 | | // authority state and decrease pointer by 1. | 11062 | 93.6k | while ((input_position != input_size) && | 11063 | 93.6k | ((url_data[input_position] == '/') || | 11064 | 92.4k | (url_data[input_position] == '\\'))) { | 11065 | 2.55k | input_position++; | 11066 | 2.55k | } | 11067 | 91.1k | state = state::AUTHORITY; | 11068 | | | 11069 | 91.1k | break; | 11070 | 90.8k | } | 11071 | 24.5k | case state::QUERY: { | 11072 | 24.5k | ada_log("QUERY ", helpers::substring(url_data, input_position)); | 11073 | 24.5k | if constexpr (store_values) { | 11074 | | // Let queryPercentEncodeSet be the special-query percent-encode set | 11075 | | // if url is special; otherwise the query percent-encode set. | 11076 | 24.5k | const uint8_t* query_percent_encode_set = | 11077 | 24.5k | url.is_special() ? character_sets::SPECIAL_QUERY_PERCENT_ENCODE | 11078 | 24.5k | : character_sets::QUERY_PERCENT_ENCODE; | 11079 | | | 11080 | | // Percent-encode after encoding, with encoding, buffer, and | 11081 | | // queryPercentEncodeSet, and append the result to url's query. | 11082 | 24.5k | url.update_base_search(url_data.substr(input_position), | 11083 | 24.5k | query_percent_encode_set); | 11084 | 24.5k | ada_log("QUERY update_base_search completed "); | 11085 | 24.5k | if (fragment.has_value()) { | 11086 | 22.2k | url.update_unencoded_base_hash(*fragment); | 11087 | 22.2k | } | 11088 | 24.5k | } | 11089 | 24.5k | return url; | 11090 | 90.8k | } | 11091 | 92.5k | case state::HOST: { | 11092 | 92.5k | ada_log("HOST ", helpers::substring(url_data, input_position)); | 11093 | | | 11094 | 92.5k | std::string_view host_view = url_data.substr(input_position); | 11095 | 92.5k | auto [location, found_colon] = | 11096 | 92.5k | helpers::get_host_delimiter_location(url.is_special(), host_view); | 11097 | 92.5k | input_position = (location != std::string_view::npos) | 11098 | 92.5k | ? input_position + location | 11099 | 92.5k | : input_size; | 11100 | | // Otherwise, if c is U+003A (:) and insideBrackets is false, then: | 11101 | | // Note: the 'found_colon' value is true if and only if a colon was | 11102 | | // encountered while not inside brackets. | 11103 | 92.5k | if (found_colon) { | 11104 | | // If buffer is the empty string, validation error, return failure. | 11105 | | // Let host be the result of host parsing buffer with url is not | 11106 | | // special. | 11107 | 24.0k | ada_log("HOST parsing ", host_view); | 11108 | 24.0k | if (!url.parse_host(host_view)) { | 11109 | 222 | return url; | 11110 | 222 | } | 11111 | 23.8k | ada_log("HOST parsing results in ", url.get_hostname()); | 11112 | | // Set url's host to host, buffer to the empty string, and state to | 11113 | | // port state. | 11114 | 23.8k | state = state::PORT; | 11115 | 23.8k | input_position++; | 11116 | 23.8k | } | 11117 | | // Otherwise, if one of the following is true: | 11118 | | // - c is the EOF code point, U+002F (/), U+003F (?), or U+0023 (#) | 11119 | | // - url is special and c is U+005C (\) | 11120 | | // The get_host_delimiter_location function either brings us to | 11121 | | // the colon outside of the bracket, or to one of those characters. | 11122 | 68.5k | else { | 11123 | | // If url is special and host_view is the empty string, validation | 11124 | | // error, return failure. | 11125 | 68.5k | if (host_view.empty() && url.is_special()) { | 11126 | 41 | url.is_valid = false; | 11127 | 41 | return url; | 11128 | 41 | } | 11129 | 68.5k | ada_log("HOST parsing ", host_view, " href=", url.get_href()); | 11130 | | // Let host be the result of host parsing host_view with url is not | 11131 | | // special. | 11132 | 68.5k | if (host_view.empty()) { | 11133 | 333 | url.update_base_hostname(""); | 11134 | 68.1k | } else if (!url.parse_host(host_view)) { | 11135 | 1.40k | return url; | 11136 | 1.40k | } | 11137 | 67.1k | ada_log("HOST parsing results in ", url.get_hostname(), | 11138 | 67.1k | " href=", url.get_href()); | 11139 | | | 11140 | | // Set url's host to host, and state to path start state. | 11141 | 67.1k | state = state::PATH_START; | 11142 | 67.1k | } | 11143 | | | 11144 | 90.9k | break; | 11145 | 92.5k | } | 11146 | 90.9k | case state::OPAQUE_PATH: { | 11147 | 2.00k | ada_log("OPAQUE_PATH ", helpers::substring(url_data, input_position)); | 11148 | | // Opaque path, query, and fragment are structurally always valid: | 11149 | | // the parser would just percent-encode whatever is there. When we | 11150 | | // are not storing values (can_parse), we can return immediately. | 11151 | | // We must set has_opaque_path = true before returning so that when | 11152 | | // this URL is used as an internal base inside can_parse, NO_SCHEME | 11153 | | // correctly rejects relative inputs against an opaque-path base | 11154 | | // (e.g. can_parse("", &"W:") must return false). | 11155 | | if constexpr (!store_values) { | 11156 | | url.has_opaque_path = true; | 11157 | | return url; | 11158 | | } | 11159 | 2.00k | std::string_view view = url_data.substr(input_position); | 11160 | | // If c is U+003F (?), then set url's query to the empty string and | 11161 | | // state to query state. | 11162 | 2.00k | size_t location = view.find('?'); | 11163 | 2.00k | if (location != std::string_view::npos) { | 11164 | 221 | view.remove_suffix(view.size() - location); | 11165 | 221 | state = state::QUERY; | 11166 | 221 | input_position += location + 1; | 11167 | 1.78k | } else { | 11168 | 1.78k | input_position = input_size + 1; | 11169 | 1.78k | } | 11170 | 2.00k | url.has_opaque_path = true; | 11171 | | | 11172 | | // This is a really unlikely scenario in real world. We should not seek | 11173 | | // to optimize it. | 11174 | 2.00k | if (view.ends_with(' ')) { | 11175 | 100 | std::string modified_view = | 11176 | 100 | std::string(view.substr(0, view.size() - 1)) + "%20"; | 11177 | 100 | url.update_base_pathname(unicode::percent_encode( | 11178 | 100 | modified_view, character_sets::C0_CONTROL_PERCENT_ENCODE)); | 11179 | 1.90k | } else { | 11180 | 1.90k | url.update_base_pathname(unicode::percent_encode( | 11181 | 1.90k | view, character_sets::C0_CONTROL_PERCENT_ENCODE)); | 11182 | 1.90k | } | 11183 | 2.00k | break; | 11184 | 92.5k | } | 11185 | 23.8k | case state::PORT: { | 11186 | 23.8k | ada_log("PORT ", helpers::substring(url_data, input_position)); | 11187 | 23.8k | std::string_view port_view = url_data.substr(input_position); | 11188 | 23.8k | input_position += url.parse_port(port_view, true); | 11189 | 23.8k | if (!url.is_valid) { | 11190 | 204 | return url; | 11191 | 204 | } | 11192 | 23.5k | state = state::PATH_START; | 11193 | 23.5k | [[fallthrough]]; | 11194 | 23.5k | } | 11195 | 126k | case state::PATH_START: { | 11196 | 126k | ada_log("PATH_START ", helpers::substring(url_data, input_position)); | 11197 | | // Path, query, and fragment are structurally always valid: the | 11198 | | // parser would just percent-encode whatever is there. When we are | 11199 | | // not storing values (can_parse), we can return immediately since | 11200 | | // no subsequent state can invalidate the URL. | 11201 | | if constexpr (!store_values) { | 11202 | | return url; | 11203 | | } | 11204 | | | 11205 | | // If url is special, then: | 11206 | 126k | if (url.is_special()) { | 11207 | | // Set state to path state. | 11208 | 125k | state = state::PATH; | 11209 | | | 11210 | | // Optimization: Avoiding going into PATH state improves the | 11211 | | // performance of urls ending with /. | 11212 | 125k | if (input_position == input_size) { | 11213 | 5.40k | if constexpr (store_values) { | 11214 | 5.40k | url.update_base_pathname("/"); | 11215 | 5.40k | if (fragment.has_value()) { | 11216 | 691 | url.update_unencoded_base_hash(*fragment); | 11217 | 691 | } | 11218 | 5.40k | } | 11219 | 5.40k | return url; | 11220 | 5.40k | } | 11221 | | // If c is neither U+002F (/) nor U+005C (\), then decrease pointer | 11222 | | // by 1. We know that (input_position == input_size) is impossible | 11223 | | // here, because of the previous if-check. | 11224 | 120k | if ((url_data[input_position] != '/') && | 11225 | 891 | (url_data[input_position] != '\\')) { | 11226 | 842 | break; | 11227 | 842 | } | 11228 | 120k | } | 11229 | | // Otherwise, if state override is not given and c is U+003F (?), | 11230 | | // set url's query to the empty string and state to query state. | 11231 | 1.41k | else if ((input_position != input_size) && | 11232 | 663 | (url_data[input_position] == '?')) { | 11233 | 40 | state = state::QUERY; | 11234 | 40 | } | 11235 | | // Otherwise, if c is not the EOF code point: | 11236 | 1.37k | else if (input_position != input_size) { | 11237 | | // Set state to path state. | 11238 | 623 | state = state::PATH; | 11239 | | | 11240 | | // If c is not U+002F (/), then decrease pointer by 1. | 11241 | 623 | if (url_data[input_position] != '/') { | 11242 | 0 | break; | 11243 | 0 | } | 11244 | 623 | } | 11245 | | | 11246 | 120k | input_position++; | 11247 | 120k | break; | 11248 | 126k | } | 11249 | 123k | case state::PATH: { | 11250 | 123k | ada_log("PATH ", helpers::substring(url_data, input_position)); | 11251 | | // Path, query, and fragment are structurally always valid: the | 11252 | | // parser would just percent-encode whatever is there. When we are | 11253 | | // not storing values (can_parse), we can return immediately since | 11254 | | // no subsequent state can invalidate the URL. | 11255 | | if constexpr (!store_values) { | 11256 | | return url; | 11257 | | } | 11258 | 123k | std::string_view view = url_data.substr(input_position); | 11259 | | | 11260 | | // Most time, we do not need percent encoding. | 11261 | | // Furthermore, we can immediately locate the '?'. | 11262 | 123k | size_t locofquestionmark = view.find('?'); | 11263 | 123k | if (locofquestionmark != std::string_view::npos) { | 11264 | 24.2k | state = state::QUERY; | 11265 | 24.2k | view.remove_suffix(view.size() - locofquestionmark); | 11266 | 24.2k | input_position += locofquestionmark + 1; | 11267 | 98.9k | } else { | 11268 | 98.9k | input_position = input_size + 1; | 11269 | 98.9k | } | 11270 | 123k | if constexpr (store_values) { | 11271 | | if constexpr (result_type_is_ada_url) { | 11272 | | helpers::parse_prepared_path(view, url.type, url.path); | 11273 | 123k | } else { | 11274 | 123k | url.consume_prepared_path(view); | 11275 | 123k | ADA_ASSERT_TRUE(url.validate()); | 11276 | 123k | } | 11277 | 123k | } | 11278 | 123k | break; | 11279 | 126k | } | 11280 | 36.6k | case state::FILE_SLASH: { | 11281 | 36.6k | ada_log("FILE_SLASH ", helpers::substring(url_data, input_position)); | 11282 | | | 11283 | | // If c is U+002F (/) or U+005C (\), then: | 11284 | 36.6k | if ((input_position != input_size) && | 11285 | 36.5k | (url_data[input_position] == '/' || | 11286 | 36.4k | url_data[input_position] == '\\')) { | 11287 | 36.4k | ada_log("FILE_SLASH c is U+002F or U+005C"); | 11288 | | // Set state to file host state. | 11289 | 36.4k | state = state::FILE_HOST; | 11290 | 36.4k | input_position++; | 11291 | 36.4k | } else { | 11292 | 150 | ada_log("FILE_SLASH otherwise"); | 11293 | | // If base is non-null and base's scheme is "file", then: | 11294 | | // Note: it is unsafe to do base_url->scheme unless you know that | 11295 | | // base_url_has_value() is true. | 11296 | 150 | if (base_url != nullptr && base_url->type == scheme::type::FILE) { | 11297 | | // Set url's host to base's host. | 11298 | | if constexpr (result_type_is_ada_url) { | 11299 | | url.host = base_url->host; | 11300 | 85 | } else { | 11301 | 85 | url.update_host_to_base_host(base_url->get_host()); | 11302 | 85 | } | 11303 | | // If the code point substring from pointer to the end of input does | 11304 | | // not start with a Windows drive letter and base's path[0] is a | 11305 | | // normalized Windows drive letter, then append base's path[0] to | 11306 | | // url's path. | 11307 | 85 | if (!base_url->get_pathname().empty()) { | 11308 | 85 | if (!checkers::is_windows_drive_letter( | 11309 | 85 | url_data.substr(input_position))) { | 11310 | 80 | std::string_view first_base_url_path = | 11311 | 80 | base_url->get_pathname().substr(1); | 11312 | 80 | size_t loc = first_base_url_path.find('/'); | 11313 | 80 | if (loc != std::string_view::npos) { | 11314 | 19 | helpers::resize(first_base_url_path, loc); | 11315 | 19 | } | 11316 | 80 | if (checkers::is_normalized_windows_drive_letter( | 11317 | 80 | first_base_url_path)) { | 11318 | | if constexpr (result_type_is_ada_url) { | 11319 | | url.path += '/'; | 11320 | | url.path += first_base_url_path; | 11321 | 2 | } else { | 11322 | 2 | url.append_base_pathname( | 11323 | 2 | helpers::concat("/", first_base_url_path)); | 11324 | 2 | } | 11325 | 2 | } | 11326 | 80 | } | 11327 | 85 | } | 11328 | 85 | } | 11329 | | | 11330 | | // Set state to path state, and decrease pointer by 1. | 11331 | 150 | state = state::PATH; | 11332 | 150 | } | 11333 | | | 11334 | 36.6k | break; | 11335 | 126k | } | 11336 | 36.4k | case state::FILE_HOST: { | 11337 | 36.4k | ada_log("FILE_HOST ", helpers::substring(url_data, input_position)); | 11338 | 36.4k | std::string_view view = url_data.substr(input_position); | 11339 | | | 11340 | 36.4k | size_t location = view.find_first_of("/\\?"); | 11341 | 36.4k | std::string_view file_host_buffer = view.substr( | 11342 | 36.4k | 0, (location != std::string_view::npos) ? location : view.size()); | 11343 | | | 11344 | 36.4k | if (checkers::is_windows_drive_letter(file_host_buffer)) { | 11345 | 40 | state = state::PATH; | 11346 | 36.4k | } else if (file_host_buffer.empty()) { | 11347 | | // Set url's host to the empty string. | 11348 | | if constexpr (result_type_is_ada_url) { | 11349 | | url.host = ""; | 11350 | 22.4k | } else { | 11351 | 22.4k | url.update_base_hostname(""); | 11352 | 22.4k | } | 11353 | | // Set state to path start state. | 11354 | 22.4k | state = state::PATH_START; | 11355 | 22.4k | } else { | 11356 | 14.0k | size_t consumed_bytes = file_host_buffer.size(); | 11357 | 14.0k | input_position += consumed_bytes; | 11358 | | // Let host be the result of host parsing buffer with url is not | 11359 | | // special. | 11360 | 14.0k | if (!url.parse_host(file_host_buffer)) { | 11361 | 258 | return url; | 11362 | 258 | } | 11363 | | | 11364 | | if constexpr (result_type_is_ada_url) { | 11365 | | // If host is "localhost", then set host to the empty string. | 11366 | | if (url.host.has_value() && url.host.value() == "localhost") { | 11367 | | url.host = ""; | 11368 | | } | 11369 | 13.7k | } else { | 11370 | 13.7k | if (url.get_hostname() == "localhost") { | 11371 | 206 | url.update_base_hostname(""); | 11372 | 206 | } | 11373 | 13.7k | } | 11374 | | | 11375 | | // Set buffer to the empty string and state to path start state. | 11376 | 13.7k | state = state::PATH_START; | 11377 | 13.7k | } | 11378 | | | 11379 | 36.2k | break; | 11380 | 36.4k | } | 11381 | 37.2k | case state::FILE: { | 11382 | 37.2k | ada_log("FILE ", helpers::substring(url_data, input_position)); | 11383 | 37.2k | std::string_view file_view = url_data.substr(input_position); | 11384 | | | 11385 | 37.2k | url.set_protocol_as_file(); | 11386 | | if constexpr (result_type_is_ada_url) { | 11387 | | // Set url's host to the empty string. | 11388 | | url.host = ""; | 11389 | 37.2k | } else { | 11390 | 37.2k | url.update_base_hostname(""); | 11391 | 37.2k | } | 11392 | | // If c is U+002F (/) or U+005C (\), then: | 11393 | 37.2k | if (input_position != input_size && | 11394 | 37.1k | (url_data[input_position] == '/' || | 11395 | 36.6k | url_data[input_position] == '\\')) { | 11396 | 36.6k | ada_log("FILE c is U+002F or U+005C"); | 11397 | | // Set state to file slash state. | 11398 | 36.6k | state = state::FILE_SLASH; | 11399 | 36.6k | } | 11400 | | // Otherwise, if base is non-null and base's scheme is "file": | 11401 | 587 | else if (base_url != nullptr && base_url->type == scheme::type::FILE) { | 11402 | | // Set url's host to base's host, url's path to a clone of base's | 11403 | | // path, and url's query to base's query. | 11404 | 177 | ada_log("FILE base non-null"); | 11405 | | if constexpr (result_type_is_ada_url) { | 11406 | | url.host = base_url->host; | 11407 | | url.path = base_url->path; | 11408 | | url.query = base_url->query; | 11409 | 177 | } else { | 11410 | 177 | url.update_host_to_base_host(base_url->get_hostname()); | 11411 | 177 | url.update_base_pathname(base_url->get_pathname()); | 11412 | 177 | if (base_url->has_search()) { | 11413 | | // get_search() returns "" for an empty query string (URL ends | 11414 | | // with '?'). update_base_search("") would incorrectly clear the | 11415 | | // query, so pass "?" to preserve the empty query distinction. | 11416 | 42 | auto s = base_url->get_search(); | 11417 | 42 | url.update_base_search(s.empty() ? std::string_view("?") : s); | 11418 | 42 | } | 11419 | 177 | } | 11420 | 177 | url.has_opaque_path = base_url->has_opaque_path; | 11421 | | | 11422 | | // If c is U+003F (?), then set url's query to the empty string and | 11423 | | // state to query state. | 11424 | 177 | if (input_position != input_size && url_data[input_position] == '?') { | 11425 | 3 | state = state::QUERY; | 11426 | 3 | } | 11427 | | // Otherwise, if c is not the EOF code point: | 11428 | 174 | else if (input_position != input_size) { | 11429 | | // Set url's query to null. | 11430 | 122 | url.clear_search(); | 11431 | | // If the code point substring from pointer to the end of input does | 11432 | | // not start with a Windows drive letter, then shorten url's path. | 11433 | 122 | if (!checkers::is_windows_drive_letter(file_view)) { | 11434 | | if constexpr (result_type_is_ada_url) { | 11435 | | helpers::shorten_path(url.path, url.type); | 11436 | 114 | } else { | 11437 | 114 | std::string_view path = url.get_pathname(); | 11438 | 114 | if (helpers::shorten_path(path, url.type)) { | 11439 | 113 | url.update_base_pathname(std::move(std::string(path))); | 11440 | 113 | } | 11441 | 114 | } | 11442 | 114 | } | 11443 | | // Otherwise: | 11444 | 8 | else { | 11445 | | // Set url's path to an empty list. | 11446 | 8 | url.clear_pathname(); | 11447 | 8 | url.has_opaque_path = true; | 11448 | 8 | } | 11449 | | | 11450 | | // Set state to path state and decrease pointer by 1. | 11451 | 122 | state = state::PATH; | 11452 | 122 | break; | 11453 | 122 | } | 11454 | 177 | } | 11455 | | // Otherwise, set state to path state, and decrease pointer by 1. | 11456 | 410 | else { | 11457 | 410 | ada_log("FILE go to path"); | 11458 | 410 | state = state::PATH; | 11459 | 410 | break; | 11460 | 410 | } | 11461 | | | 11462 | 36.6k | input_position++; | 11463 | 36.6k | break; | 11464 | 37.2k | } | 11465 | 0 | default: | 11466 | 0 | unreachable(); | 11467 | 959k | } | 11468 | 959k | } | 11469 | 126k | if constexpr (store_values) { | 11470 | 126k | if (fragment.has_value()) { | 11471 | 1.17k | url.update_unencoded_base_hash(*fragment); | 11472 | 1.17k | } | 11473 | 126k | } | 11474 | | // Check the resulting (normalized) URL size against the maximum input length. | 11475 | | // Normalization (percent-encoding, IDNA, etc.) can expand the URL beyond the | 11476 | | // original input size. | 11477 | 126k | if constexpr (store_values) { | 11478 | 126k | if (url.is_valid) { | 11479 | 101k | if constexpr (result_type_is_ada_url_aggregator) { | 11480 | 101k | if (url.buffer.size() > max_input_length) { | 11481 | 0 | url.is_valid = false; | 11482 | 0 | } | 11483 | | } else { | 11484 | | if (url.get_href_size() > max_input_length) { | 11485 | | url.is_valid = false; | 11486 | | } | 11487 | | } | 11488 | 101k | } | 11489 | 126k | } | 11490 | 126k | return url; | 11491 | 169k | } |
ada::url_aggregator ada::parser::parse_url_impl<ada::url_aggregator, false>(std::__1::basic_string_view<char, std::__1::char_traits<char> >, ada::url_aggregator const*) Line | Count | Source | 10503 | 43.4k | const result_type* base_url) { | 10504 | | // We can specialize the implementation per type. | 10505 | | // Important: result_type_is_ada_url is evaluated at *compile time*. This | 10506 | | // means that doing if constexpr(result_type_is_ada_url) { something } else { | 10507 | | // something else } is free (at runtime). This means that ada::url_aggregator | 10508 | | // and ada::url **do not have to support the exact same API**. | 10509 | 43.4k | constexpr bool result_type_is_ada_url = std::is_same_v<url, result_type>; | 10510 | 43.4k | constexpr bool result_type_is_ada_url_aggregator = | 10511 | 43.4k | std::is_same_v<url_aggregator, result_type>; | 10512 | 43.4k | static_assert(result_type_is_ada_url || | 10513 | 43.4k | result_type_is_ada_url_aggregator); // We don't support | 10514 | | // anything else for now. | 10515 | | | 10516 | 43.4k | ada_log("ada::parser::parse_url('", user_input, "' [", user_input.size(), | 10517 | 43.4k | " bytes],", (base_url != nullptr ? base_url->to_string() : "null"), | 10518 | 43.4k | ")"); | 10519 | | | 10520 | 43.4k | state state = state::SCHEME_START; | 10521 | 43.4k | result_type url{}; | 10522 | | | 10523 | 43.4k | const uint32_t max_input_length = ada::get_max_input_length(); | 10524 | | | 10525 | | // We refuse to parse URL strings that exceed the maximum input length. | 10526 | | // By default, this is 4GB but can be configured via | 10527 | | // ada::set_max_input_length(). | 10528 | 43.4k | if (user_input.size() > max_input_length) [[unlikely]] { | 10529 | 0 | url.is_valid = false; | 10530 | 0 | } | 10531 | | // Going forward, user_input.size() is in [0, | 10532 | | // std::numeric_limits<uint32_t>::max). If we are provided with an invalid | 10533 | | // base, or the optional_url was invalid, we must return. | 10534 | 43.4k | if (base_url != nullptr) { | 10535 | 3.31k | url.is_valid &= base_url->is_valid; | 10536 | 3.31k | } | 10537 | 43.4k | if (!url.is_valid) { | 10538 | 0 | return url; | 10539 | 0 | } | 10540 | | | 10541 | | // Simple absolute http(s) fast path (before tabs/newline scan). | 10542 | | // Skip digit-led hosts (IPv4) with a cheap peek. | 10543 | | if constexpr (store_values) { | 10544 | | if (base_url == nullptr) { | 10545 | | const auto* p = reinterpret_cast<const uint8_t*>(user_input.data()); | 10546 | | const size_t n = user_input.size(); | 10547 | | const bool digit_led_host = (n >= 8 && p[4] == ':' && p[5] == '/' && | 10548 | | p[6] == '/' && p[7] >= '0' && p[7] <= '9') || | 10549 | | (n >= 9 && p[5] == ':' && p[6] == '/' && | 10550 | | p[7] == '/' && p[8] >= '0' && p[8] <= '9'); | 10551 | | if (!digit_led_host && try_parse_simple_absolute(user_input, url)) { | 10552 | | if constexpr (result_type_is_ada_url_aggregator) { | 10553 | | if (url.buffer.size() > max_input_length) [[unlikely]] { | 10554 | | url.is_valid = false; | 10555 | | } | 10556 | | } else { | 10557 | | if (url.get_href_size() > max_input_length) [[unlikely]] { | 10558 | | url.is_valid = false; | 10559 | | } | 10560 | | } | 10561 | | return url; | 10562 | | } | 10563 | | } | 10564 | | } | 10565 | | | 10566 | 43.4k | std::string tmp_buffer; | 10567 | 43.4k | std::string_view url_data; | 10568 | 43.4k | if (unicode::has_tabs_or_newline(user_input)) [[unlikely]] { | 10569 | 308 | tmp_buffer = user_input; | 10570 | | // Optimization opportunity: Instead of copying and then pruning, we could | 10571 | | // just directly build the string from user_input. | 10572 | 308 | helpers::remove_ascii_tab_or_newline(tmp_buffer); | 10573 | 308 | url_data = tmp_buffer; | 10574 | 43.1k | } else [[likely]] { | 10575 | 43.1k | url_data = user_input; | 10576 | 43.1k | } | 10577 | | | 10578 | | // Leading and trailing control characters are uncommon and easy to deal with | 10579 | | // (no performance concern). | 10580 | 43.4k | helpers::trim_c0_whitespace(url_data); | 10581 | | | 10582 | | if constexpr (result_type_is_ada_url_aggregator && store_values) { | 10583 | | // Most of the time, we just need user_input.size(). | 10584 | | // In some instances, we may need a bit more. | 10585 | | /////////////////////////// | 10586 | | // This is *very* important. This line should *not* be removed | 10587 | | // hastily. There are principled reasons why reserve is important | 10588 | | // for performance. If you have a benchmark with small inputs, | 10589 | | // it may not matter, but in other instances, it could. | 10590 | | //// | 10591 | | // This rounds up to the next power of two. | 10592 | | // We know that user_input.size() is in [0, | 10593 | | // std::numeric_limits<uint32_t>::max). | 10594 | | uint32_t reserve_capacity = | 10595 | | (0xFFFFFFFF >> | 10596 | | helpers::leading_zeroes(uint32_t(1 | user_input.size()))) + | 10597 | | 1; | 10598 | | url.reserve(reserve_capacity); | 10599 | | } | 10600 | | | 10601 | | // Optimization opportunity. Most websites do not have fragment. | 10602 | 43.4k | std::optional<std::string_view> fragment = helpers::prune_hash(url_data); | 10603 | | // We add it last so that an implementation like ada::url_aggregator | 10604 | | // can append it last to its internal buffer, thus improving performance. | 10605 | | | 10606 | | // Here url_data no longer has its fragment. | 10607 | | // We are going to access the data from url_data (it is immutable). | 10608 | | // At any given time, we are pointing at byte 'input_position' in url_data. | 10609 | | // The input_position variable should range from 0 to input_size. | 10610 | | // It is illegal to access url_data at input_size. | 10611 | 43.4k | size_t input_position = 0; | 10612 | 43.4k | const size_t input_size = url_data.size(); | 10613 | | // Keep running the following state machine by switching on state. | 10614 | | // If after a run pointer points to the EOF code point, go to the next step. | 10615 | | // Otherwise, increase pointer by 1 and continue with the state machine. | 10616 | | // We never decrement input_position. | 10617 | 220k | while (input_position <= input_size) { | 10618 | 219k | ada_log("In parsing at ", input_position, " out of ", input_size, | 10619 | 219k | " in state ", ada::to_string(state)); | 10620 | 219k | switch (state) { | 10621 | 43.4k | case state::SCHEME_START: { | 10622 | 43.4k | ada_log("SCHEME_START ", helpers::substring(url_data, input_position)); | 10623 | | // If c is an ASCII alpha, append c, lowercased, to buffer, and set | 10624 | | // state to scheme state. | 10625 | 43.4k | if ((input_position != input_size) && | 10626 | 37.3k | checkers::is_alpha(url_data[input_position])) { | 10627 | 35.4k | state = state::SCHEME; | 10628 | 35.4k | input_position++; | 10629 | 35.4k | } else { | 10630 | | // Otherwise, if state override is not given, set state to no scheme | 10631 | | // state and decrease pointer by 1. | 10632 | 7.94k | state = state::NO_SCHEME; | 10633 | 7.94k | } | 10634 | 43.4k | break; | 10635 | 0 | } | 10636 | 35.4k | case state::SCHEME: { | 10637 | 35.4k | ada_log("SCHEME ", helpers::substring(url_data, input_position)); | 10638 | | // If c is an ASCII alphanumeric, U+002B (+), U+002D (-), or U+002E (.), | 10639 | | // append c, lowercased, to buffer. | 10640 | 165k | while ((input_position != input_size) && | 10641 | 164k | (unicode::is_alnum_plus(url_data[input_position]))) { | 10642 | 130k | input_position++; | 10643 | 130k | } | 10644 | | // Otherwise, if c is U+003A (:), then: | 10645 | 35.4k | if ((input_position != input_size) && | 10646 | 34.5k | (url_data[input_position] == ':')) { | 10647 | 34.2k | ada_log("SCHEME the scheme should be ", | 10648 | 34.2k | url_data.substr(0, input_position)); | 10649 | | if constexpr (result_type_is_ada_url) { | 10650 | | if (!url.parse_scheme(url_data.substr(0, input_position))) { | 10651 | | return url; | 10652 | | } | 10653 | 34.2k | } else { | 10654 | | // we pass the colon along instead of painfully adding it back. | 10655 | 34.2k | if (!url.parse_scheme_with_colon( | 10656 | 34.2k | url_data.substr(0, input_position + 1))) { | 10657 | 0 | return url; | 10658 | 0 | } | 10659 | 34.2k | } | 10660 | 34.2k | ada_log("SCHEME the scheme is ", url.get_protocol()); | 10661 | | | 10662 | | // If url's scheme is "file", then: | 10663 | | // NOLINTNEXTLINE(bugprone-branch-clone) | 10664 | 34.2k | if (url.type == scheme::type::FILE) { | 10665 | | // Set state to file state. | 10666 | 13.1k | state = state::FILE; | 10667 | 13.1k | } | 10668 | | // Otherwise, if url is special, base is non-null, and base's scheme | 10669 | | // is url's scheme: Note: Doing base_url->scheme is unsafe if base_url | 10670 | | // != nullptr is false. | 10671 | 21.1k | else if (url.is_special() && base_url != nullptr && | 10672 | 1.60k | base_url->type == url.type) { | 10673 | | // Set state to special relative or authority state. | 10674 | 340 | state = state::SPECIAL_RELATIVE_OR_AUTHORITY; | 10675 | 340 | } | 10676 | | // Otherwise, if url is special, set state to special authority | 10677 | | // slashes state. | 10678 | 20.8k | else if (url.is_special()) { | 10679 | 18.5k | state = state::SPECIAL_AUTHORITY_SLASHES; | 10680 | 18.5k | } | 10681 | | // Otherwise, if remaining starts with an U+002F (/), set state to | 10682 | | // path or authority state and increase pointer by 1. | 10683 | 2.23k | else if (input_position + 1 < input_size && | 10684 | 1.94k | url_data[input_position + 1] == '/') { | 10685 | 1.31k | state = state::PATH_OR_AUTHORITY; | 10686 | 1.31k | input_position++; | 10687 | 1.31k | } | 10688 | | // Otherwise, set url's path to the empty string and set state to | 10689 | | // opaque path state. | 10690 | 920 | else { | 10691 | 920 | state = state::OPAQUE_PATH; | 10692 | 920 | } | 10693 | 34.2k | } | 10694 | | // Otherwise, if state override is not given, set buffer to the empty | 10695 | | // string, state to no scheme state, and start over (from the first code | 10696 | | // point in input). | 10697 | 1.16k | else { | 10698 | 1.16k | state = state::NO_SCHEME; | 10699 | 1.16k | input_position = 0; | 10700 | 1.16k | break; | 10701 | 1.16k | } | 10702 | 34.2k | input_position++; | 10703 | 34.2k | break; | 10704 | 35.4k | } | 10705 | 9.11k | case state::NO_SCHEME: { | 10706 | 9.11k | ada_log("NO_SCHEME ", helpers::substring(url_data, input_position)); | 10707 | | // The fragment was pruned from url_data before the state machine ran, | 10708 | | // so 'c is U+0023 (#)' holds exactly when a fragment was found and | 10709 | | // nothing else remains in front of it. | 10710 | 9.11k | const bool c_is_hash = | 10711 | 9.11k | fragment.has_value() && input_position == input_size; | 10712 | | // If base is null, or base has an opaque path and c is not U+0023 (#), | 10713 | | // validation error, return failure. | 10714 | 9.11k | if (base_url == nullptr || (base_url->has_opaque_path && !c_is_hash)) { | 10715 | 8.32k | ada_log("NO_SCHEME validation error"); | 10716 | 8.32k | url.is_valid = false; | 10717 | 8.32k | return url; | 10718 | 8.32k | } | 10719 | | // Otherwise, if base has an opaque path and c is U+0023 (#), | 10720 | | // set url's scheme to base's scheme, url's path to base's path, url's | 10721 | | // query to base's query, and set state to fragment state. | 10722 | 788 | else if (base_url->has_opaque_path && c_is_hash) { | 10723 | 59 | ada_log("NO_SCHEME opaque base with fragment"); | 10724 | 59 | url.copy_scheme(*base_url); | 10725 | 59 | url.has_opaque_path = base_url->has_opaque_path; | 10726 | | | 10727 | | if constexpr (result_type_is_ada_url) { | 10728 | | url.path = base_url->path; | 10729 | | url.query = base_url->query; | 10730 | 59 | } else { | 10731 | 59 | url.update_base_pathname(base_url->get_pathname()); | 10732 | 59 | if (base_url->has_search()) { | 10733 | | // get_search() returns "" for an empty query string (URL ends | 10734 | | // with '?'). update_base_search("") would incorrectly clear the | 10735 | | // query, so pass "?" to preserve the empty query distinction. | 10736 | 0 | auto s = base_url->get_search(); | 10737 | 0 | url.update_base_search(s.empty() ? std::string_view("?") : s); | 10738 | 0 | } | 10739 | 59 | } | 10740 | 59 | url.update_unencoded_base_hash(*fragment); | 10741 | 59 | return url; | 10742 | 59 | } | 10743 | | // Otherwise, if base's scheme is not "file", set state to relative | 10744 | | // state and decrease pointer by 1. | 10745 | | // NOLINTNEXTLINE(bugprone-branch-clone) | 10746 | 729 | else if (base_url->type != scheme::type::FILE) { | 10747 | 475 | ada_log("NO_SCHEME non-file relative path"); | 10748 | 475 | state = state::RELATIVE_SCHEME; | 10749 | 475 | } | 10750 | | // Otherwise, set state to file state and decrease pointer by 1. | 10751 | 254 | else { | 10752 | 254 | ada_log("NO_SCHEME file base type"); | 10753 | 254 | state = state::FILE; | 10754 | 254 | } | 10755 | 729 | break; | 10756 | 9.11k | } | 10757 | 19.4k | case state::AUTHORITY: { | 10758 | 19.4k | ada_log("AUTHORITY ", helpers::substring(url_data, input_position)); | 10759 | | // most URLs have no @. Having no @ tells us that we don't have to worry | 10760 | | // about AUTHORITY. Of course, we could have @ and still not have to | 10761 | | // worry about AUTHORITY. | 10762 | | // TODO: Instead of just collecting a bool, collect the location of the | 10763 | | // '@' and do something useful with it. | 10764 | | // TODO: We could do various processing early on, using a single pass | 10765 | | // over the string to collect information about it, e.g., telling us | 10766 | | // whether there is a @ and if so, where (or how many). | 10767 | | | 10768 | | // Check if url data contains an @. | 10769 | 19.4k | if (url_data.find('@', input_position) == std::string_view::npos) { | 10770 | 7.43k | state = state::HOST; | 10771 | 7.43k | break; | 10772 | 7.43k | } | 10773 | 11.9k | bool at_sign_seen{false}; | 10774 | 11.9k | bool password_token_seen{false}; | 10775 | | /** | 10776 | | * We expect something of the sort... | 10777 | | * https://user:pass@example.com:1234/foo/bar?baz#quux | 10778 | | * --------^ | 10779 | | */ | 10780 | 33.5k | do { | 10781 | 33.5k | std::string_view view = url_data.substr(input_position); | 10782 | | // The delimiters are @, /, ? \\. | 10783 | 33.5k | size_t location = | 10784 | 33.5k | url.is_special() ? helpers::find_authority_delimiter_special(view) | 10785 | 33.5k | : helpers::find_authority_delimiter(view); | 10786 | 33.5k | std::string_view authority_view = view.substr(0, location); | 10787 | 33.5k | size_t end_of_authority = input_position + authority_view.size(); | 10788 | | // If c is U+0040 (@), then: | 10789 | 33.5k | if ((end_of_authority != input_size) && | 10790 | 33.0k | (url_data[end_of_authority] == '@')) { | 10791 | | // If atSignSeen is true, then prepend "%40" to buffer. | 10792 | 21.5k | if (at_sign_seen) { | 10793 | 9.64k | if (password_token_seen) { | 10794 | | if constexpr (result_type_is_ada_url) { | 10795 | | url.password += "%40"; | 10796 | 2.65k | } else { | 10797 | 2.65k | url.append_base_password("%40"); | 10798 | 2.65k | } | 10799 | 6.98k | } else { | 10800 | | if constexpr (result_type_is_ada_url) { | 10801 | | url.username += "%40"; | 10802 | 6.98k | } else { | 10803 | 6.98k | url.append_base_username("%40"); | 10804 | 6.98k | } | 10805 | 6.98k | } | 10806 | 9.64k | } | 10807 | | | 10808 | 21.5k | at_sign_seen = true; | 10809 | | | 10810 | 21.5k | if (!password_token_seen) { | 10811 | 18.9k | size_t password_token_location = authority_view.find(':'); | 10812 | 18.9k | password_token_seen = | 10813 | 18.9k | password_token_location != std::string_view::npos; | 10814 | | | 10815 | | if constexpr (store_values) { | 10816 | | if (!password_token_seen) { | 10817 | | if constexpr (result_type_is_ada_url) { | 10818 | | url.username += unicode::percent_encode( | 10819 | | authority_view, | 10820 | | character_sets::USERINFO_PERCENT_ENCODE); | 10821 | | } else { | 10822 | | url.append_base_username(unicode::percent_encode( | 10823 | | authority_view, | 10824 | | character_sets::USERINFO_PERCENT_ENCODE)); | 10825 | | } | 10826 | | } else { | 10827 | | if constexpr (result_type_is_ada_url) { | 10828 | | url.username += unicode::percent_encode( | 10829 | | authority_view.substr(0, password_token_location), | 10830 | | character_sets::USERINFO_PERCENT_ENCODE); | 10831 | | url.password += unicode::percent_encode( | 10832 | | authority_view.substr(password_token_location + 1), | 10833 | | character_sets::USERINFO_PERCENT_ENCODE); | 10834 | | } else { | 10835 | | url.append_base_username(unicode::percent_encode( | 10836 | | authority_view.substr(0, password_token_location), | 10837 | | character_sets::USERINFO_PERCENT_ENCODE)); | 10838 | | url.append_base_password(unicode::percent_encode( | 10839 | | authority_view.substr(password_token_location + 1), | 10840 | | character_sets::USERINFO_PERCENT_ENCODE)); | 10841 | | } | 10842 | | } | 10843 | | } | 10844 | 18.9k | } else if constexpr (store_values) { | 10845 | 2.65k | if constexpr (result_type_is_ada_url) { | 10846 | 2.65k | url.password += unicode::percent_encode( | 10847 | 2.65k | authority_view, character_sets::USERINFO_PERCENT_ENCODE); | 10848 | 2.65k | } else { | 10849 | 2.65k | url.append_base_password(unicode::percent_encode( | 10850 | 2.65k | authority_view, character_sets::USERINFO_PERCENT_ENCODE)); | 10851 | 2.65k | } | 10852 | 2.65k | } | 10853 | 21.5k | } | 10854 | | // Otherwise, if one of the following is true: | 10855 | | // - c is the EOF code point, U+002F (/), U+003F (?), or U+0023 (#) | 10856 | | // - url is special and c is U+005C (\) | 10857 | 11.9k | else if (end_of_authority == input_size || | 10858 | 11.4k | url_data[end_of_authority] == '/' || | 10859 | 67 | url_data[end_of_authority] == '?' || | 10860 | 11.9k | (url.is_special() && url_data[end_of_authority] == '\\')) { | 10861 | | // If atSignSeen is true and authority_view is the empty string, | 10862 | | // validation error, return failure. | 10863 | 11.9k | if (at_sign_seen && authority_view.empty()) { | 10864 | 106 | url.is_valid = false; | 10865 | 106 | return url; | 10866 | 106 | } | 10867 | 11.8k | state = state::HOST; | 10868 | 11.8k | break; | 10869 | 11.9k | } | 10870 | 21.5k | if (end_of_authority == input_size) { | 10871 | | if constexpr (store_values) { | 10872 | | if (fragment.has_value()) { | 10873 | | url.update_unencoded_base_hash(*fragment); | 10874 | | } | 10875 | | } | 10876 | 0 | return url; | 10877 | 0 | } | 10878 | 21.5k | input_position = end_of_authority + 1; | 10879 | 21.5k | } while (true); | 10880 | | | 10881 | 11.8k | break; | 10882 | 11.9k | } | 10883 | 11.8k | case state::SPECIAL_RELATIVE_OR_AUTHORITY: { | 10884 | 340 | ada_log("SPECIAL_RELATIVE_OR_AUTHORITY ", | 10885 | 340 | helpers::substring(url_data, input_position)); | 10886 | | | 10887 | | // If c is U+002F (/) and remaining starts with U+002F (/), | 10888 | | // then set state to special authority ignore slashes state and increase | 10889 | | // pointer by 1. | 10890 | 340 | if (url_data.substr(input_position, 2) == "//") { | 10891 | 206 | state = state::SPECIAL_AUTHORITY_IGNORE_SLASHES; | 10892 | 206 | input_position += 2; | 10893 | 206 | } else { | 10894 | | // Otherwise, validation error, set state to relative state and | 10895 | | // decrease pointer by 1. | 10896 | 134 | state = state::RELATIVE_SCHEME; | 10897 | 134 | } | 10898 | | | 10899 | 340 | break; | 10900 | 11.9k | } | 10901 | 1.31k | case state::PATH_OR_AUTHORITY: { | 10902 | 1.31k | ada_log("PATH_OR_AUTHORITY ", | 10903 | 1.31k | helpers::substring(url_data, input_position)); | 10904 | | | 10905 | | // If c is U+002F (/), then set state to authority state. | 10906 | 1.31k | if ((input_position != input_size) && | 10907 | 1.06k | (url_data[input_position] == '/')) { | 10908 | 603 | state = state::AUTHORITY; | 10909 | 603 | input_position++; | 10910 | 713 | } else { | 10911 | | // Otherwise, set state to path state, and decrease pointer by 1. | 10912 | 713 | state = state::PATH; | 10913 | 713 | } | 10914 | | | 10915 | 1.31k | break; | 10916 | 11.9k | } | 10917 | 609 | case state::RELATIVE_SCHEME: { | 10918 | 609 | ada_log("RELATIVE_SCHEME ", | 10919 | 609 | helpers::substring(url_data, input_position)); | 10920 | | | 10921 | | // Set url's scheme to base's scheme. | 10922 | 609 | url.copy_scheme(*base_url); | 10923 | | | 10924 | | // If c is U+002F (/), then set state to relative slash state. | 10925 | 609 | if ((input_position != input_size) && | 10926 | | // NOLINTNEXTLINE(bugprone-branch-clone) | 10927 | 464 | (url_data[input_position] == '/')) { | 10928 | 57 | ada_log( | 10929 | 57 | "RELATIVE_SCHEME if c is U+002F (/), then set state to relative " | 10930 | 57 | "slash state"); | 10931 | 57 | state = state::RELATIVE_SLASH; | 10932 | 552 | } else if (url.is_special() && (input_position != input_size) && | 10933 | 352 | (url_data[input_position] == '\\')) { | 10934 | | // Otherwise, if url is special and c is U+005C (\), validation error, | 10935 | | // set state to relative slash state. | 10936 | 2 | ada_log( | 10937 | 2 | "RELATIVE_SCHEME if url is special and c is U+005C, validation " | 10938 | 2 | "error, set state to relative slash state"); | 10939 | 2 | state = state::RELATIVE_SLASH; | 10940 | 550 | } else { | 10941 | 550 | ada_log("RELATIVE_SCHEME otherwise"); | 10942 | | // Set url's username to base's username, url's password to base's | 10943 | | // password, url's host to base's host, url's port to base's port, | 10944 | | // url's path to a clone of base's path, and url's query to base's | 10945 | | // query. | 10946 | | if constexpr (result_type_is_ada_url) { | 10947 | | url.username = base_url->username; | 10948 | | url.password = base_url->password; | 10949 | | url.host = base_url->host; | 10950 | | url.port = base_url->port; | 10951 | | // cloning the base path includes cloning the has_opaque_path flag | 10952 | | url.has_opaque_path = base_url->has_opaque_path; | 10953 | | url.path = base_url->path; | 10954 | | url.query = base_url->query; | 10955 | 550 | } else { | 10956 | 550 | url.update_base_authority(base_url->get_href(), | 10957 | 550 | base_url->get_components()); | 10958 | 550 | url.update_host_to_base_host(base_url->get_hostname()); | 10959 | 550 | url.update_base_port(base_url->retrieve_base_port()); | 10960 | | // cloning the base path includes cloning the has_opaque_path flag | 10961 | 550 | url.has_opaque_path = base_url->has_opaque_path; | 10962 | 550 | url.update_base_pathname(base_url->get_pathname()); | 10963 | 550 | if (base_url->has_search()) { | 10964 | | // get_search() returns "" for an empty query string (URL ends | 10965 | | // with '?'). update_base_search("") would incorrectly clear the | 10966 | | // query, so pass "?" to preserve the empty query distinction. | 10967 | 0 | auto s = base_url->get_search(); | 10968 | 0 | url.update_base_search(s.empty() ? std::string_view("?") : s); | 10969 | 0 | } | 10970 | 550 | } | 10971 | | | 10972 | 550 | url.has_opaque_path = base_url->has_opaque_path; | 10973 | | | 10974 | | // If c is U+003F (?), then set url's query to the empty string, and | 10975 | | // state to query state. | 10976 | 550 | if ((input_position != input_size) && | 10977 | 405 | (url_data[input_position] == '?')) { | 10978 | 7 | state = state::QUERY; | 10979 | 7 | } | 10980 | | // Otherwise, if c is not the EOF code point: | 10981 | 543 | else if (input_position != input_size) { | 10982 | | // Set url's query to null. | 10983 | 398 | url.clear_search(); | 10984 | | if constexpr (result_type_is_ada_url) { | 10985 | | // Shorten url's path. | 10986 | | helpers::shorten_path(url.path, url.type); | 10987 | 398 | } else { | 10988 | 398 | std::string_view path = url.get_pathname(); | 10989 | 398 | if (helpers::shorten_path(path, url.type)) { | 10990 | 0 | url.update_base_pathname(std::move(std::string(path))); | 10991 | 0 | } | 10992 | 398 | } | 10993 | | // Set state to path state and decrease pointer by 1. | 10994 | 398 | state = state::PATH; | 10995 | 398 | break; | 10996 | 398 | } | 10997 | 550 | } | 10998 | 211 | input_position++; | 10999 | 211 | break; | 11000 | 609 | } | 11001 | 59 | case state::RELATIVE_SLASH: { | 11002 | 59 | ada_log("RELATIVE_SLASH ", | 11003 | 59 | helpers::substring(url_data, input_position)); | 11004 | | | 11005 | | // If url is special and c is U+002F (/) or U+005C (\), then: | 11006 | | // NOLINTNEXTLINE(bugprone-branch-clone) | 11007 | 59 | if (url.is_special() && (input_position != input_size) && | 11008 | 45 | (url_data[input_position] == '/' || | 11009 | 24 | url_data[input_position] == '\\')) { | 11010 | | // Set state to special authority ignore slashes state. | 11011 | 23 | state = state::SPECIAL_AUTHORITY_IGNORE_SLASHES; | 11012 | 23 | } | 11013 | | // Otherwise, if c is U+002F (/), then set state to authority state. | 11014 | 36 | else if ((input_position != input_size) && | 11015 | 24 | (url_data[input_position] == '/')) { | 11016 | 1 | state = state::AUTHORITY; | 11017 | 1 | } | 11018 | | // Otherwise, set | 11019 | | // - url's username to base's username, | 11020 | | // - url's password to base's password, | 11021 | | // - url's host to base's host, | 11022 | | // - url's port to base's port, | 11023 | | // - state to path state, and then, decrease pointer by 1. | 11024 | 35 | else { | 11025 | | if constexpr (result_type_is_ada_url) { | 11026 | | url.username = base_url->username; | 11027 | | url.password = base_url->password; | 11028 | | url.host = base_url->host; | 11029 | | url.port = base_url->port; | 11030 | 35 | } else { | 11031 | 35 | url.update_base_authority(base_url->get_href(), | 11032 | 35 | base_url->get_components()); | 11033 | 35 | url.update_host_to_base_host(base_url->get_hostname()); | 11034 | 35 | url.update_base_port(base_url->retrieve_base_port()); | 11035 | 35 | } | 11036 | 35 | state = state::PATH; | 11037 | 35 | break; | 11038 | 35 | } | 11039 | | | 11040 | 24 | input_position++; | 11041 | 24 | break; | 11042 | 59 | } | 11043 | 18.5k | case state::SPECIAL_AUTHORITY_SLASHES: { | 11044 | 18.5k | ada_log("SPECIAL_AUTHORITY_SLASHES ", | 11045 | 18.5k | helpers::substring(url_data, input_position)); | 11046 | | | 11047 | | // If c is U+002F (/) and remaining starts with U+002F (/), | 11048 | | // then set state to special authority ignore slashes state and increase | 11049 | | // pointer by 1. | 11050 | 18.5k | if (url_data.substr(input_position, 2) == "//") { | 11051 | 14.6k | input_position += 2; | 11052 | 14.6k | } | 11053 | | | 11054 | 18.5k | [[fallthrough]]; | 11055 | 18.5k | } | 11056 | 18.8k | case state::SPECIAL_AUTHORITY_IGNORE_SLASHES: { | 11057 | 18.8k | ada_log("SPECIAL_AUTHORITY_IGNORE_SLASHES ", | 11058 | 18.8k | helpers::substring(url_data, input_position)); | 11059 | | | 11060 | | // If c is neither U+002F (/) nor U+005C (\), then set state to | 11061 | | // authority state and decrease pointer by 1. | 11062 | 20.3k | while ((input_position != input_size) && | 11063 | 20.3k | ((url_data[input_position] == '/') || | 11064 | 19.5k | (url_data[input_position] == '\\'))) { | 11065 | 1.57k | input_position++; | 11066 | 1.57k | } | 11067 | 18.8k | state = state::AUTHORITY; | 11068 | | | 11069 | 18.8k | break; | 11070 | 18.5k | } | 11071 | 10 | case state::QUERY: { | 11072 | 10 | ada_log("QUERY ", helpers::substring(url_data, input_position)); | 11073 | | if constexpr (store_values) { | 11074 | | // Let queryPercentEncodeSet be the special-query percent-encode set | 11075 | | // if url is special; otherwise the query percent-encode set. | 11076 | | const uint8_t* query_percent_encode_set = | 11077 | | url.is_special() ? character_sets::SPECIAL_QUERY_PERCENT_ENCODE | 11078 | | : character_sets::QUERY_PERCENT_ENCODE; | 11079 | | | 11080 | | // Percent-encode after encoding, with encoding, buffer, and | 11081 | | // queryPercentEncodeSet, and append the result to url's query. | 11082 | | url.update_base_search(url_data.substr(input_position), | 11083 | | query_percent_encode_set); | 11084 | | ada_log("QUERY update_base_search completed "); | 11085 | | if (fragment.has_value()) { | 11086 | | url.update_unencoded_base_hash(*fragment); | 11087 | | } | 11088 | | } | 11089 | 10 | return url; | 11090 | 18.5k | } | 11091 | 19.3k | case state::HOST: { | 11092 | 19.3k | ada_log("HOST ", helpers::substring(url_data, input_position)); | 11093 | | | 11094 | 19.3k | std::string_view host_view = url_data.substr(input_position); | 11095 | 19.3k | auto [location, found_colon] = | 11096 | 19.3k | helpers::get_host_delimiter_location(url.is_special(), host_view); | 11097 | 19.3k | input_position = (location != std::string_view::npos) | 11098 | 19.3k | ? input_position + location | 11099 | 19.3k | : input_size; | 11100 | | // Otherwise, if c is U+003A (:) and insideBrackets is false, then: | 11101 | | // Note: the 'found_colon' value is true if and only if a colon was | 11102 | | // encountered while not inside brackets. | 11103 | 19.3k | if (found_colon) { | 11104 | | // If buffer is the empty string, validation error, return failure. | 11105 | | // Let host be the result of host parsing buffer with url is not | 11106 | | // special. | 11107 | 12.1k | ada_log("HOST parsing ", host_view); | 11108 | 12.1k | if (!url.parse_host(host_view)) { | 11109 | 200 | return url; | 11110 | 200 | } | 11111 | 11.9k | ada_log("HOST parsing results in ", url.get_hostname()); | 11112 | | // Set url's host to host, buffer to the empty string, and state to | 11113 | | // port state. | 11114 | 11.9k | state = state::PORT; | 11115 | 11.9k | input_position++; | 11116 | 11.9k | } | 11117 | | // Otherwise, if one of the following is true: | 11118 | | // - c is the EOF code point, U+002F (/), U+003F (?), or U+0023 (#) | 11119 | | // - url is special and c is U+005C (\) | 11120 | | // The get_host_delimiter_location function either brings us to | 11121 | | // the colon outside of the bracket, or to one of those characters. | 11122 | 7.14k | else { | 11123 | | // If url is special and host_view is the empty string, validation | 11124 | | // error, return failure. | 11125 | 7.14k | if (host_view.empty() && url.is_special()) { | 11126 | 17 | url.is_valid = false; | 11127 | 17 | return url; | 11128 | 17 | } | 11129 | 7.12k | ada_log("HOST parsing ", host_view, " href=", url.get_href()); | 11130 | | // Let host be the result of host parsing host_view with url is not | 11131 | | // special. | 11132 | 7.12k | if (host_view.empty()) { | 11133 | 46 | url.update_base_hostname(""); | 11134 | 7.08k | } else if (!url.parse_host(host_view)) { | 11135 | 1.28k | return url; | 11136 | 1.28k | } | 11137 | 5.84k | ada_log("HOST parsing results in ", url.get_hostname(), | 11138 | 5.84k | " href=", url.get_href()); | 11139 | | | 11140 | | // Set url's host to host, and state to path start state. | 11141 | 5.84k | state = state::PATH_START; | 11142 | 5.84k | } | 11143 | | | 11144 | 17.8k | break; | 11145 | 19.3k | } | 11146 | 17.8k | case state::OPAQUE_PATH: { | 11147 | 920 | ada_log("OPAQUE_PATH ", helpers::substring(url_data, input_position)); | 11148 | | // Opaque path, query, and fragment are structurally always valid: | 11149 | | // the parser would just percent-encode whatever is there. When we | 11150 | | // are not storing values (can_parse), we can return immediately. | 11151 | | // We must set has_opaque_path = true before returning so that when | 11152 | | // this URL is used as an internal base inside can_parse, NO_SCHEME | 11153 | | // correctly rejects relative inputs against an opaque-path base | 11154 | | // (e.g. can_parse("", &"W:") must return false). | 11155 | 920 | if constexpr (!store_values) { | 11156 | 920 | url.has_opaque_path = true; | 11157 | 920 | return url; | 11158 | 920 | } | 11159 | 0 | std::string_view view = url_data.substr(input_position); | 11160 | | // If c is U+003F (?), then set url's query to the empty string and | 11161 | | // state to query state. | 11162 | 920 | size_t location = view.find('?'); | 11163 | 920 | if (location != std::string_view::npos) { | 11164 | 0 | view.remove_suffix(view.size() - location); | 11165 | 0 | state = state::QUERY; | 11166 | 0 | input_position += location + 1; | 11167 | 920 | } else { | 11168 | 920 | input_position = input_size + 1; | 11169 | 920 | } | 11170 | 920 | url.has_opaque_path = true; | 11171 | | | 11172 | | // This is a really unlikely scenario in real world. We should not seek | 11173 | | // to optimize it. | 11174 | 920 | if (view.ends_with(' ')) { | 11175 | 0 | std::string modified_view = | 11176 | 0 | std::string(view.substr(0, view.size() - 1)) + "%20"; | 11177 | 0 | url.update_base_pathname(unicode::percent_encode( | 11178 | 0 | modified_view, character_sets::C0_CONTROL_PERCENT_ENCODE)); | 11179 | 920 | } else { | 11180 | 920 | url.update_base_pathname(unicode::percent_encode( | 11181 | 920 | view, character_sets::C0_CONTROL_PERCENT_ENCODE)); | 11182 | 920 | } | 11183 | 920 | break; | 11184 | 19.3k | } | 11185 | 11.9k | case state::PORT: { | 11186 | 11.9k | ada_log("PORT ", helpers::substring(url_data, input_position)); | 11187 | 11.9k | std::string_view port_view = url_data.substr(input_position); | 11188 | 11.9k | input_position += url.parse_port(port_view, true); | 11189 | 11.9k | if (!url.is_valid) { | 11190 | 174 | return url; | 11191 | 174 | } | 11192 | 11.7k | state = state::PATH_START; | 11193 | 11.7k | [[fallthrough]]; | 11194 | 11.7k | } | 11195 | 30.1k | case state::PATH_START: { | 11196 | 30.1k | ada_log("PATH_START ", helpers::substring(url_data, input_position)); | 11197 | | // Path, query, and fragment are structurally always valid: the | 11198 | | // parser would just percent-encode whatever is there. When we are | 11199 | | // not storing values (can_parse), we can return immediately since | 11200 | | // no subsequent state can invalidate the URL. | 11201 | 30.1k | if constexpr (!store_values) { | 11202 | 30.1k | return url; | 11203 | 30.1k | } | 11204 | | | 11205 | | // If url is special, then: | 11206 | 30.1k | if (url.is_special()) { | 11207 | | // Set state to path state. | 11208 | 0 | state = state::PATH; | 11209 | | | 11210 | | // Optimization: Avoiding going into PATH state improves the | 11211 | | // performance of urls ending with /. | 11212 | 0 | if (input_position == input_size) { | 11213 | | if constexpr (store_values) { | 11214 | | url.update_base_pathname("/"); | 11215 | | if (fragment.has_value()) { | 11216 | | url.update_unencoded_base_hash(*fragment); | 11217 | | } | 11218 | | } | 11219 | 0 | return url; | 11220 | 0 | } | 11221 | | // If c is neither U+002F (/) nor U+005C (\), then decrease pointer | 11222 | | // by 1. We know that (input_position == input_size) is impossible | 11223 | | // here, because of the previous if-check. | 11224 | 0 | if ((url_data[input_position] != '/') && | 11225 | 0 | (url_data[input_position] != '\\')) { | 11226 | 0 | break; | 11227 | 0 | } | 11228 | 0 | } | 11229 | | // Otherwise, if state override is not given and c is U+003F (?), | 11230 | | // set url's query to the empty string and state to query state. | 11231 | 30.1k | else if ((input_position != input_size) && | 11232 | 0 | (url_data[input_position] == '?')) { | 11233 | 0 | state = state::QUERY; | 11234 | 0 | } | 11235 | | // Otherwise, if c is not the EOF code point: | 11236 | 30.1k | else if (input_position != input_size) { | 11237 | | // Set state to path state. | 11238 | 0 | state = state::PATH; | 11239 | | | 11240 | | // If c is not U+002F (/), then decrease pointer by 1. | 11241 | 0 | if (url_data[input_position] != '/') { | 11242 | 0 | break; | 11243 | 0 | } | 11244 | 0 | } | 11245 | | | 11246 | 30.1k | input_position++; | 11247 | 30.1k | break; | 11248 | 30.1k | } | 11249 | 1.70k | case state::PATH: { | 11250 | 1.70k | ada_log("PATH ", helpers::substring(url_data, input_position)); | 11251 | | // Path, query, and fragment are structurally always valid: the | 11252 | | // parser would just percent-encode whatever is there. When we are | 11253 | | // not storing values (can_parse), we can return immediately since | 11254 | | // no subsequent state can invalidate the URL. | 11255 | 1.70k | if constexpr (!store_values) { | 11256 | 1.70k | return url; | 11257 | 1.70k | } | 11258 | 0 | std::string_view view = url_data.substr(input_position); | 11259 | | | 11260 | | // Most time, we do not need percent encoding. | 11261 | | // Furthermore, we can immediately locate the '?'. | 11262 | 1.70k | size_t locofquestionmark = view.find('?'); | 11263 | 1.70k | if (locofquestionmark != std::string_view::npos) { | 11264 | 0 | state = state::QUERY; | 11265 | 0 | view.remove_suffix(view.size() - locofquestionmark); | 11266 | 0 | input_position += locofquestionmark + 1; | 11267 | 1.70k | } else { | 11268 | 1.70k | input_position = input_size + 1; | 11269 | 1.70k | } | 11270 | | if constexpr (store_values) { | 11271 | | if constexpr (result_type_is_ada_url) { | 11272 | | helpers::parse_prepared_path(view, url.type, url.path); | 11273 | | } else { | 11274 | | url.consume_prepared_path(view); | 11275 | | ADA_ASSERT_TRUE(url.validate()); | 11276 | | } | 11277 | | } | 11278 | 1.70k | break; | 11279 | 30.1k | } | 11280 | 12.9k | case state::FILE_SLASH: { | 11281 | 12.9k | ada_log("FILE_SLASH ", helpers::substring(url_data, input_position)); | 11282 | | | 11283 | | // If c is U+002F (/) or U+005C (\), then: | 11284 | 12.9k | if ((input_position != input_size) && | 11285 | 12.8k | (url_data[input_position] == '/' || | 11286 | 12.8k | url_data[input_position] == '\\')) { | 11287 | 12.8k | ada_log("FILE_SLASH c is U+002F or U+005C"); | 11288 | | // Set state to file host state. | 11289 | 12.8k | state = state::FILE_HOST; | 11290 | 12.8k | input_position++; | 11291 | 12.8k | } else { | 11292 | 126 | ada_log("FILE_SLASH otherwise"); | 11293 | | // If base is non-null and base's scheme is "file", then: | 11294 | | // Note: it is unsafe to do base_url->scheme unless you know that | 11295 | | // base_url_has_value() is true. | 11296 | 126 | if (base_url != nullptr && base_url->type == scheme::type::FILE) { | 11297 | | // Set url's host to base's host. | 11298 | | if constexpr (result_type_is_ada_url) { | 11299 | | url.host = base_url->host; | 11300 | 85 | } else { | 11301 | 85 | url.update_host_to_base_host(base_url->get_host()); | 11302 | 85 | } | 11303 | | // If the code point substring from pointer to the end of input does | 11304 | | // not start with a Windows drive letter and base's path[0] is a | 11305 | | // normalized Windows drive letter, then append base's path[0] to | 11306 | | // url's path. | 11307 | 85 | if (!base_url->get_pathname().empty()) { | 11308 | 0 | if (!checkers::is_windows_drive_letter( | 11309 | 0 | url_data.substr(input_position))) { | 11310 | 0 | std::string_view first_base_url_path = | 11311 | 0 | base_url->get_pathname().substr(1); | 11312 | 0 | size_t loc = first_base_url_path.find('/'); | 11313 | 0 | if (loc != std::string_view::npos) { | 11314 | 0 | helpers::resize(first_base_url_path, loc); | 11315 | 0 | } | 11316 | 0 | if (checkers::is_normalized_windows_drive_letter( | 11317 | 0 | first_base_url_path)) { | 11318 | | if constexpr (result_type_is_ada_url) { | 11319 | | url.path += '/'; | 11320 | | url.path += first_base_url_path; | 11321 | 0 | } else { | 11322 | 0 | url.append_base_pathname( | 11323 | 0 | helpers::concat("/", first_base_url_path)); | 11324 | 0 | } | 11325 | 0 | } | 11326 | 0 | } | 11327 | 0 | } | 11328 | 85 | } | 11329 | | | 11330 | | // Set state to path state, and decrease pointer by 1. | 11331 | 126 | state = state::PATH; | 11332 | 126 | } | 11333 | | | 11334 | 12.9k | break; | 11335 | 30.1k | } | 11336 | 12.8k | case state::FILE_HOST: { | 11337 | 12.8k | ada_log("FILE_HOST ", helpers::substring(url_data, input_position)); | 11338 | 12.8k | std::string_view view = url_data.substr(input_position); | 11339 | | | 11340 | 12.8k | size_t location = view.find_first_of("/\\?"); | 11341 | 12.8k | std::string_view file_host_buffer = view.substr( | 11342 | 12.8k | 0, (location != std::string_view::npos) ? location : view.size()); | 11343 | | | 11344 | 12.8k | if (checkers::is_windows_drive_letter(file_host_buffer)) { | 11345 | 27 | state = state::PATH; | 11346 | 12.7k | } else if (file_host_buffer.empty()) { | 11347 | | // Set url's host to the empty string. | 11348 | | if constexpr (result_type_is_ada_url) { | 11349 | | url.host = ""; | 11350 | 11.0k | } else { | 11351 | 11.0k | url.update_base_hostname(""); | 11352 | 11.0k | } | 11353 | | // Set state to path start state. | 11354 | 11.0k | state = state::PATH_START; | 11355 | 11.0k | } else { | 11356 | 1.73k | size_t consumed_bytes = file_host_buffer.size(); | 11357 | 1.73k | input_position += consumed_bytes; | 11358 | | // Let host be the result of host parsing buffer with url is not | 11359 | | // special. | 11360 | 1.73k | if (!url.parse_host(file_host_buffer)) { | 11361 | 257 | return url; | 11362 | 257 | } | 11363 | | | 11364 | | if constexpr (result_type_is_ada_url) { | 11365 | | // If host is "localhost", then set host to the empty string. | 11366 | | if (url.host.has_value() && url.host.value() == "localhost") { | 11367 | | url.host = ""; | 11368 | | } | 11369 | 1.48k | } else { | 11370 | 1.48k | if (url.get_hostname() == "localhost") { | 11371 | 123 | url.update_base_hostname(""); | 11372 | 123 | } | 11373 | 1.48k | } | 11374 | | | 11375 | | // Set buffer to the empty string and state to path start state. | 11376 | 1.48k | state = state::PATH_START; | 11377 | 1.48k | } | 11378 | | | 11379 | 12.5k | break; | 11380 | 12.8k | } | 11381 | 13.3k | case state::FILE: { | 11382 | 13.3k | ada_log("FILE ", helpers::substring(url_data, input_position)); | 11383 | 13.3k | std::string_view file_view = url_data.substr(input_position); | 11384 | | | 11385 | 13.3k | url.set_protocol_as_file(); | 11386 | | if constexpr (result_type_is_ada_url) { | 11387 | | // Set url's host to the empty string. | 11388 | | url.host = ""; | 11389 | 13.3k | } else { | 11390 | 13.3k | url.update_base_hostname(""); | 11391 | 13.3k | } | 11392 | | // If c is U+002F (/) or U+005C (\), then: | 11393 | 13.3k | if (input_position != input_size && | 11394 | 13.3k | (url_data[input_position] == '/' || | 11395 | 12.9k | url_data[input_position] == '\\')) { | 11396 | 12.9k | ada_log("FILE c is U+002F or U+005C"); | 11397 | | // Set state to file slash state. | 11398 | 12.9k | state = state::FILE_SLASH; | 11399 | 12.9k | } | 11400 | | // Otherwise, if base is non-null and base's scheme is "file": | 11401 | 457 | else if (base_url != nullptr && base_url->type == scheme::type::FILE) { | 11402 | | // Set url's host to base's host, url's path to a clone of base's | 11403 | | // path, and url's query to base's query. | 11404 | 177 | ada_log("FILE base non-null"); | 11405 | | if constexpr (result_type_is_ada_url) { | 11406 | | url.host = base_url->host; | 11407 | | url.path = base_url->path; | 11408 | | url.query = base_url->query; | 11409 | 177 | } else { | 11410 | 177 | url.update_host_to_base_host(base_url->get_hostname()); | 11411 | 177 | url.update_base_pathname(base_url->get_pathname()); | 11412 | 177 | if (base_url->has_search()) { | 11413 | | // get_search() returns "" for an empty query string (URL ends | 11414 | | // with '?'). update_base_search("") would incorrectly clear the | 11415 | | // query, so pass "?" to preserve the empty query distinction. | 11416 | 0 | auto s = base_url->get_search(); | 11417 | 0 | url.update_base_search(s.empty() ? std::string_view("?") : s); | 11418 | 0 | } | 11419 | 177 | } | 11420 | 177 | url.has_opaque_path = base_url->has_opaque_path; | 11421 | | | 11422 | | // If c is U+003F (?), then set url's query to the empty string and | 11423 | | // state to query state. | 11424 | 177 | if (input_position != input_size && url_data[input_position] == '?') { | 11425 | 3 | state = state::QUERY; | 11426 | 3 | } | 11427 | | // Otherwise, if c is not the EOF code point: | 11428 | 174 | else if (input_position != input_size) { | 11429 | | // Set url's query to null. | 11430 | 122 | url.clear_search(); | 11431 | | // If the code point substring from pointer to the end of input does | 11432 | | // not start with a Windows drive letter, then shorten url's path. | 11433 | 122 | if (!checkers::is_windows_drive_letter(file_view)) { | 11434 | | if constexpr (result_type_is_ada_url) { | 11435 | | helpers::shorten_path(url.path, url.type); | 11436 | 114 | } else { | 11437 | 114 | std::string_view path = url.get_pathname(); | 11438 | 114 | if (helpers::shorten_path(path, url.type)) { | 11439 | 0 | url.update_base_pathname(std::move(std::string(path))); | 11440 | 0 | } | 11441 | 114 | } | 11442 | 114 | } | 11443 | | // Otherwise: | 11444 | 8 | else { | 11445 | | // Set url's path to an empty list. | 11446 | 8 | url.clear_pathname(); | 11447 | 8 | url.has_opaque_path = true; | 11448 | 8 | } | 11449 | | | 11450 | | // Set state to path state and decrease pointer by 1. | 11451 | 122 | state = state::PATH; | 11452 | 122 | break; | 11453 | 122 | } | 11454 | 177 | } | 11455 | | // Otherwise, set state to path state, and decrease pointer by 1. | 11456 | 280 | else { | 11457 | 280 | ada_log("FILE go to path"); | 11458 | 280 | state = state::PATH; | 11459 | 280 | break; | 11460 | 280 | } | 11461 | | | 11462 | 12.9k | input_position++; | 11463 | 12.9k | break; | 11464 | 13.3k | } | 11465 | 0 | default: | 11466 | 0 | unreachable(); | 11467 | 219k | } | 11468 | 219k | } | 11469 | | if constexpr (store_values) { | 11470 | | if (fragment.has_value()) { | 11471 | | url.update_unencoded_base_hash(*fragment); | 11472 | | } | 11473 | | } | 11474 | | // Check the resulting (normalized) URL size against the maximum input length. | 11475 | | // Normalization (percent-encoding, IDNA, etc.) can expand the URL beyond the | 11476 | | // original input size. | 11477 | | if constexpr (store_values) { | 11478 | | if (url.is_valid) { | 11479 | | if constexpr (result_type_is_ada_url_aggregator) { | 11480 | | if (url.buffer.size() > max_input_length) { | 11481 | | url.is_valid = false; | 11482 | | } | 11483 | | } else { | 11484 | | if (url.get_href_size() > max_input_length) { | 11485 | | url.is_valid = false; | 11486 | | } | 11487 | | } | 11488 | | } | 11489 | | } | 11490 | 197 | return url; | 11491 | 43.4k | } |
|
11492 | | |
11493 | | template url parse_url_impl<url, true>(std::string_view user_input, |
11494 | | const url* base_url = nullptr); |
11495 | | template url_aggregator parse_url_impl<url_aggregator, true>( |
11496 | | std::string_view user_input, const url_aggregator* base_url = nullptr); |
11497 | | template url_aggregator parse_url_impl<url_aggregator, false>( |
11498 | | std::string_view user_input, const url_aggregator* base_url = nullptr); |
11499 | | |
11500 | | template <class result_type> |
11501 | | result_type parse_url(std::string_view user_input, |
11502 | 0 | const result_type* base_url) { |
11503 | 0 | return parse_url_impl<result_type, true>(user_input, base_url); |
11504 | 0 | } Unexecuted instantiation: ada::url ada::parser::parse_url<ada::url>(std::__1::basic_string_view<char, std::__1::char_traits<char> >, ada::url const*) Unexecuted instantiation: ada::url_aggregator ada::parser::parse_url<ada::url_aggregator>(std::__1::basic_string_view<char, std::__1::char_traits<char> >, ada::url_aggregator const*) |
11505 | | |
11506 | | template url parse_url<url>(std::string_view user_input, |
11507 | | const url* base_url = nullptr); |
11508 | | template url_aggregator parse_url<url_aggregator>( |
11509 | | std::string_view user_input, const url_aggregator* base_url = nullptr); |
11510 | | } // namespace ada::parser |
11511 | | /* end file src/parser.cpp */ |
11512 | | /* begin file src/url_components.cpp */ |
11513 | | |
11514 | | #include <iterator> |
11515 | | #include <string> |
11516 | | |
11517 | | namespace ada { |
11518 | | |
11519 | 0 | [[nodiscard]] std::string url_components::to_string() const { |
11520 | 0 | std::string answer; |
11521 | 0 | auto back = std::back_insert_iterator(answer); |
11522 | 0 | answer.append("{\n"); |
11523 | |
|
11524 | 0 | answer.append("\t\"protocol_end\":\""); |
11525 | 0 | helpers::encode_json(std::to_string(protocol_end), back); |
11526 | 0 | answer.append("\",\n"); |
11527 | |
|
11528 | 0 | answer.append("\t\"username_end\":\""); |
11529 | 0 | helpers::encode_json(std::to_string(username_end), back); |
11530 | 0 | answer.append("\",\n"); |
11531 | |
|
11532 | 0 | answer.append("\t\"host_start\":\""); |
11533 | 0 | helpers::encode_json(std::to_string(host_start), back); |
11534 | 0 | answer.append("\",\n"); |
11535 | |
|
11536 | 0 | answer.append("\t\"host_end\":\""); |
11537 | 0 | helpers::encode_json(std::to_string(host_end), back); |
11538 | 0 | answer.append("\",\n"); |
11539 | |
|
11540 | 0 | answer.append("\t\"port\":\""); |
11541 | 0 | helpers::encode_json(std::to_string(port), back); |
11542 | 0 | answer.append("\",\n"); |
11543 | |
|
11544 | 0 | answer.append("\t\"pathname_start\":\""); |
11545 | 0 | helpers::encode_json(std::to_string(pathname_start), back); |
11546 | 0 | answer.append("\",\n"); |
11547 | |
|
11548 | 0 | answer.append("\t\"search_start\":\""); |
11549 | 0 | helpers::encode_json(std::to_string(search_start), back); |
11550 | 0 | answer.append("\",\n"); |
11551 | |
|
11552 | 0 | answer.append("\t\"hash_start\":\""); |
11553 | 0 | helpers::encode_json(std::to_string(hash_start), back); |
11554 | 0 | answer.append("\",\n"); |
11555 | |
|
11556 | 0 | answer.append("\n}"); |
11557 | 0 | return answer; |
11558 | 0 | } |
11559 | | |
11560 | | } // namespace ada |
11561 | | /* end file src/url_components.cpp */ |
11562 | | /* begin file src/url_aggregator.cpp */ |
11563 | | |
11564 | | #include <array> |
11565 | | #include <cstdint> |
11566 | | #include <cstring> |
11567 | | #include <iterator> |
11568 | | #include <ranges> |
11569 | | #include <string> |
11570 | | #include <string_view> |
11571 | | |
11572 | | namespace { |
11573 | | |
11574 | | ada_really_inline void apply_shifted_non_scheme_offsets( |
11575 | 169k | ada::url_components& components, uint32_t new_difference) { |
11576 | 169k | components.username_end += new_difference; |
11577 | 169k | components.host_start += new_difference; |
11578 | 169k | components.host_end += new_difference; |
11579 | 169k | components.pathname_start += new_difference; |
11580 | 169k | if (components.search_start != ada::url_components::omitted) { |
11581 | 268 | components.search_start += new_difference; |
11582 | 268 | } |
11583 | 169k | if (components.hash_start != ada::url_components::omitted) { |
11584 | 211 | components.hash_start += new_difference; |
11585 | 211 | } |
11586 | 169k | } |
11587 | | |
11588 | | } // namespace |
11589 | | |
11590 | | namespace ada { |
11591 | | template <bool has_state_override> |
11592 | | [[nodiscard]] ada_really_inline bool url_aggregator::parse_scheme_with_colon( |
11593 | 213k | const std::string_view input_with_colon) { |
11594 | 213k | ada_log("url_aggregator::parse_scheme_with_colon ", input_with_colon); |
11595 | 213k | ADA_ASSERT_TRUE(validate()); |
11596 | 213k | ADA_ASSERT_TRUE(!helpers::overlaps(input_with_colon, buffer)); |
11597 | 213k | std::string_view input{input_with_colon}; |
11598 | 213k | input.remove_suffix(1); |
11599 | 213k | auto parsed_type = ada::scheme::get_scheme_type(input); |
11600 | 213k | const bool is_input_special = (parsed_type != ada::scheme::NOT_SPECIAL); |
11601 | | /** |
11602 | | * In the common case, we will immediately recognize a special scheme (e.g., |
11603 | | *http, https), in which case, we can go really fast. |
11604 | | **/ |
11605 | 213k | if (is_input_special) { // fast path!!! |
11606 | 158k | if constexpr (has_state_override) { |
11607 | | // If url's scheme is not a special scheme and buffer is a special scheme, |
11608 | | // then return. |
11609 | 1.66k | if (is_special() != is_input_special) { |
11610 | 283 | return false; |
11611 | 283 | } |
11612 | | |
11613 | | // If url includes credentials or has a non-null port, and buffer is |
11614 | | // "file", then return. |
11615 | 1.38k | if ((has_credentials() || components.port != url_components::omitted) && |
11616 | 284 | parsed_type == ada::scheme::type::FILE) { |
11617 | 9 | return false; |
11618 | 9 | } |
11619 | | |
11620 | | // If url's scheme is "file" and its host is an empty host, then return. |
11621 | | // An empty host is the empty string. |
11622 | 1.37k | if (type == ada::scheme::type::FILE && |
11623 | 393 | components.host_start == components.host_end) { |
11624 | 117 | return false; |
11625 | 117 | } |
11626 | 1.37k | } |
11627 | | |
11628 | 1.25k | type = parsed_type; |
11629 | 158k | set_scheme_from_view_with_colon(input_with_colon); |
11630 | | |
11631 | 158k | if constexpr (has_state_override) { |
11632 | | // This is uncommon. |
11633 | 1.66k | uint16_t urls_scheme_port = get_special_port(); |
11634 | | |
11635 | 1.66k | if (urls_scheme_port) { |
11636 | | // If url's port is url's scheme's default port, then set url's port to |
11637 | | // null. |
11638 | 1.15k | if (components.port == urls_scheme_port) { |
11639 | 13 | clear_port(); |
11640 | 13 | } |
11641 | 1.15k | } |
11642 | 1.66k | } |
11643 | 158k | } else { // slow path |
11644 | 55.5k | std::string _buffer(input); |
11645 | | // Next function is only valid if the input is ASCII and returns false |
11646 | | // otherwise, but it seems that we always have ascii content so we do not |
11647 | | // need to check the return value. |
11648 | 55.5k | unicode::to_lower_ascii(_buffer.data(), _buffer.size()); |
11649 | | |
11650 | 55.5k | if constexpr (has_state_override) { |
11651 | | // The state-override validation errors below ("return" in the WHATWG URL |
11652 | | // parser) leave the URL unchanged. The setter contract is |
11653 | | // "true on success, false if the scheme is invalid" -- the fast path |
11654 | | // above already returns false here, so the slow path must agree. |
11655 | | |
11656 | | // If url's scheme is a special scheme and buffer is not a special scheme, |
11657 | | // then return. If url's scheme is not a special scheme and buffer is a |
11658 | | // special scheme, then return. |
11659 | 44.5k | if (is_special() != ada::scheme::is_special(_buffer)) { |
11660 | 44.3k | return false; |
11661 | 44.3k | } |
11662 | | |
11663 | | // If url includes credentials or has a non-null port, and buffer is |
11664 | | // "file", then return. |
11665 | 182 | if ((has_credentials() || components.port != url_components::omitted) && |
11666 | 68 | _buffer == "file") { |
11667 | 1 | return false; |
11668 | 1 | } |
11669 | | |
11670 | | // If url's scheme is "file" and its host is an empty host, then return. |
11671 | | // An empty host is the empty string. |
11672 | 181 | if (type == ada::scheme::type::FILE && |
11673 | 18 | components.host_start == components.host_end) { |
11674 | 3 | return false; |
11675 | 3 | } |
11676 | 181 | } |
11677 | | |
11678 | 178 | set_scheme(_buffer); |
11679 | | |
11680 | 55.5k | if constexpr (has_state_override) { |
11681 | | // This is uncommon. |
11682 | 44.5k | uint16_t urls_scheme_port = get_special_port(); |
11683 | | |
11684 | 44.5k | if (urls_scheme_port) { |
11685 | | // If url's port is url's scheme's default port, then set url's port to |
11686 | | // null. |
11687 | 97 | if (components.port == urls_scheme_port) { |
11688 | 2 | clear_port(); |
11689 | 2 | } |
11690 | 97 | } |
11691 | 44.5k | } |
11692 | 55.5k | } |
11693 | 0 | ADA_ASSERT_TRUE(validate()); |
11694 | 213k | return true; |
11695 | 213k | } bool ada::url_aggregator::parse_scheme_with_colon<false>(std::__1::basic_string_view<char, std::__1::char_traits<char> >) Line | Count | Source | 11593 | 167k | const std::string_view input_with_colon) { | 11594 | 167k | ada_log("url_aggregator::parse_scheme_with_colon ", input_with_colon); | 11595 | 167k | ADA_ASSERT_TRUE(validate()); | 11596 | 167k | ADA_ASSERT_TRUE(!helpers::overlaps(input_with_colon, buffer)); | 11597 | 167k | std::string_view input{input_with_colon}; | 11598 | 167k | input.remove_suffix(1); | 11599 | 167k | auto parsed_type = ada::scheme::get_scheme_type(input); | 11600 | 167k | const bool is_input_special = (parsed_type != ada::scheme::NOT_SPECIAL); | 11601 | | /** | 11602 | | * In the common case, we will immediately recognize a special scheme (e.g., | 11603 | | *http, https), in which case, we can go really fast. | 11604 | | **/ | 11605 | 167k | if (is_input_special) { // fast path!!! | 11606 | | if constexpr (has_state_override) { | 11607 | | // If url's scheme is not a special scheme and buffer is a special scheme, | 11608 | | // then return. | 11609 | | if (is_special() != is_input_special) { | 11610 | | return false; | 11611 | | } | 11612 | | | 11613 | | // If url includes credentials or has a non-null port, and buffer is | 11614 | | // "file", then return. | 11615 | | if ((has_credentials() || components.port != url_components::omitted) && | 11616 | | parsed_type == ada::scheme::type::FILE) { | 11617 | | return false; | 11618 | | } | 11619 | | | 11620 | | // If url's scheme is "file" and its host is an empty host, then return. | 11621 | | // An empty host is the empty string. | 11622 | | if (type == ada::scheme::type::FILE && | 11623 | | components.host_start == components.host_end) { | 11624 | | return false; | 11625 | | } | 11626 | | } | 11627 | | | 11628 | 156k | type = parsed_type; | 11629 | 156k | set_scheme_from_view_with_colon(input_with_colon); | 11630 | | | 11631 | | if constexpr (has_state_override) { | 11632 | | // This is uncommon. | 11633 | | uint16_t urls_scheme_port = get_special_port(); | 11634 | | | 11635 | | if (urls_scheme_port) { | 11636 | | // If url's port is url's scheme's default port, then set url's port to | 11637 | | // null. | 11638 | | if (components.port == urls_scheme_port) { | 11639 | | clear_port(); | 11640 | | } | 11641 | | } | 11642 | | } | 11643 | 156k | } else { // slow path | 11644 | 11.0k | std::string _buffer(input); | 11645 | | // Next function is only valid if the input is ASCII and returns false | 11646 | | // otherwise, but it seems that we always have ascii content so we do not | 11647 | | // need to check the return value. | 11648 | 11.0k | unicode::to_lower_ascii(_buffer.data(), _buffer.size()); | 11649 | | | 11650 | | if constexpr (has_state_override) { | 11651 | | // The state-override validation errors below ("return" in the WHATWG URL | 11652 | | // parser) leave the URL unchanged. The setter contract is | 11653 | | // "true on success, false if the scheme is invalid" -- the fast path | 11654 | | // above already returns false here, so the slow path must agree. | 11655 | | | 11656 | | // If url's scheme is a special scheme and buffer is not a special scheme, | 11657 | | // then return. If url's scheme is not a special scheme and buffer is a | 11658 | | // special scheme, then return. | 11659 | | if (is_special() != ada::scheme::is_special(_buffer)) { | 11660 | | return false; | 11661 | | } | 11662 | | | 11663 | | // If url includes credentials or has a non-null port, and buffer is | 11664 | | // "file", then return. | 11665 | | if ((has_credentials() || components.port != url_components::omitted) && | 11666 | | _buffer == "file") { | 11667 | | return false; | 11668 | | } | 11669 | | | 11670 | | // If url's scheme is "file" and its host is an empty host, then return. | 11671 | | // An empty host is the empty string. | 11672 | | if (type == ada::scheme::type::FILE && | 11673 | | components.host_start == components.host_end) { | 11674 | | return false; | 11675 | | } | 11676 | | } | 11677 | | | 11678 | 11.0k | set_scheme(_buffer); | 11679 | | | 11680 | | if constexpr (has_state_override) { | 11681 | | // This is uncommon. | 11682 | | uint16_t urls_scheme_port = get_special_port(); | 11683 | | | 11684 | | if (urls_scheme_port) { | 11685 | | // If url's port is url's scheme's default port, then set url's port to | 11686 | | // null. | 11687 | | if (components.port == urls_scheme_port) { | 11688 | | clear_port(); | 11689 | | } | 11690 | | } | 11691 | | } | 11692 | 11.0k | } | 11693 | 167k | ADA_ASSERT_TRUE(validate()); | 11694 | 167k | return true; | 11695 | 167k | } |
bool ada::url_aggregator::parse_scheme_with_colon<true>(std::__1::basic_string_view<char, std::__1::char_traits<char> >) Line | Count | Source | 11593 | 46.1k | const std::string_view input_with_colon) { | 11594 | 46.1k | ada_log("url_aggregator::parse_scheme_with_colon ", input_with_colon); | 11595 | 46.1k | ADA_ASSERT_TRUE(validate()); | 11596 | 46.1k | ADA_ASSERT_TRUE(!helpers::overlaps(input_with_colon, buffer)); | 11597 | 46.1k | std::string_view input{input_with_colon}; | 11598 | 46.1k | input.remove_suffix(1); | 11599 | 46.1k | auto parsed_type = ada::scheme::get_scheme_type(input); | 11600 | 46.1k | const bool is_input_special = (parsed_type != ada::scheme::NOT_SPECIAL); | 11601 | | /** | 11602 | | * In the common case, we will immediately recognize a special scheme (e.g., | 11603 | | *http, https), in which case, we can go really fast. | 11604 | | **/ | 11605 | 46.1k | if (is_input_special) { // fast path!!! | 11606 | 1.66k | if constexpr (has_state_override) { | 11607 | | // If url's scheme is not a special scheme and buffer is a special scheme, | 11608 | | // then return. | 11609 | 1.66k | if (is_special() != is_input_special) { | 11610 | 283 | return false; | 11611 | 283 | } | 11612 | | | 11613 | | // If url includes credentials or has a non-null port, and buffer is | 11614 | | // "file", then return. | 11615 | 1.38k | if ((has_credentials() || components.port != url_components::omitted) && | 11616 | 284 | parsed_type == ada::scheme::type::FILE) { | 11617 | 9 | return false; | 11618 | 9 | } | 11619 | | | 11620 | | // If url's scheme is "file" and its host is an empty host, then return. | 11621 | | // An empty host is the empty string. | 11622 | 1.37k | if (type == ada::scheme::type::FILE && | 11623 | 393 | components.host_start == components.host_end) { | 11624 | 117 | return false; | 11625 | 117 | } | 11626 | 1.37k | } | 11627 | | | 11628 | 1.25k | type = parsed_type; | 11629 | 1.66k | set_scheme_from_view_with_colon(input_with_colon); | 11630 | | | 11631 | 1.66k | if constexpr (has_state_override) { | 11632 | | // This is uncommon. | 11633 | 1.66k | uint16_t urls_scheme_port = get_special_port(); | 11634 | | | 11635 | 1.66k | if (urls_scheme_port) { | 11636 | | // If url's port is url's scheme's default port, then set url's port to | 11637 | | // null. | 11638 | 1.15k | if (components.port == urls_scheme_port) { | 11639 | 13 | clear_port(); | 11640 | 13 | } | 11641 | 1.15k | } | 11642 | 1.66k | } | 11643 | 44.5k | } else { // slow path | 11644 | 44.5k | std::string _buffer(input); | 11645 | | // Next function is only valid if the input is ASCII and returns false | 11646 | | // otherwise, but it seems that we always have ascii content so we do not | 11647 | | // need to check the return value. | 11648 | 44.5k | unicode::to_lower_ascii(_buffer.data(), _buffer.size()); | 11649 | | | 11650 | 44.5k | if constexpr (has_state_override) { | 11651 | | // The state-override validation errors below ("return" in the WHATWG URL | 11652 | | // parser) leave the URL unchanged. The setter contract is | 11653 | | // "true on success, false if the scheme is invalid" -- the fast path | 11654 | | // above already returns false here, so the slow path must agree. | 11655 | | | 11656 | | // If url's scheme is a special scheme and buffer is not a special scheme, | 11657 | | // then return. If url's scheme is not a special scheme and buffer is a | 11658 | | // special scheme, then return. | 11659 | 44.5k | if (is_special() != ada::scheme::is_special(_buffer)) { | 11660 | 44.3k | return false; | 11661 | 44.3k | } | 11662 | | | 11663 | | // If url includes credentials or has a non-null port, and buffer is | 11664 | | // "file", then return. | 11665 | 182 | if ((has_credentials() || components.port != url_components::omitted) && | 11666 | 68 | _buffer == "file") { | 11667 | 1 | return false; | 11668 | 1 | } | 11669 | | | 11670 | | // If url's scheme is "file" and its host is an empty host, then return. | 11671 | | // An empty host is the empty string. | 11672 | 181 | if (type == ada::scheme::type::FILE && | 11673 | 18 | components.host_start == components.host_end) { | 11674 | 3 | return false; | 11675 | 3 | } | 11676 | 181 | } | 11677 | | | 11678 | 178 | set_scheme(_buffer); | 11679 | | | 11680 | 44.5k | if constexpr (has_state_override) { | 11681 | | // This is uncommon. | 11682 | 44.5k | uint16_t urls_scheme_port = get_special_port(); | 11683 | | | 11684 | 44.5k | if (urls_scheme_port) { | 11685 | | // If url's port is url's scheme's default port, then set url's port to | 11686 | | // null. | 11687 | 97 | if (components.port == urls_scheme_port) { | 11688 | 2 | clear_port(); | 11689 | 2 | } | 11690 | 97 | } | 11691 | 44.5k | } | 11692 | 44.5k | } | 11693 | 0 | ADA_ASSERT_TRUE(validate()); | 11694 | 46.1k | return true; | 11695 | 46.1k | } |
|
11696 | | |
11697 | 1.33k | inline void url_aggregator::copy_scheme(const url_aggregator& u) { |
11698 | 1.33k | ada_log("url_aggregator::copy_scheme ", u.buffer); |
11699 | 1.33k | ADA_ASSERT_TRUE(validate()); |
11700 | | // next line could overflow but unsigned arithmetic has well-defined |
11701 | | // overflows. |
11702 | 1.33k | uint32_t new_difference = u.components.protocol_end - components.protocol_end; |
11703 | | |
11704 | 1.33k | type = u.type; |
11705 | 1.33k | buffer.erase(0, components.protocol_end); |
11706 | 1.33k | buffer.insert(0, u.get_protocol()); |
11707 | 1.33k | components.protocol_end = u.components.protocol_end; |
11708 | | |
11709 | | // No need to update the components |
11710 | 1.33k | if (new_difference == 0) { |
11711 | 268 | return; |
11712 | 268 | } |
11713 | | |
11714 | 1.06k | apply_shifted_non_scheme_offsets(components, new_difference); |
11715 | 1.06k | ADA_ASSERT_TRUE(validate()); |
11716 | 1.06k | } |
11717 | | |
11718 | | inline void url_aggregator::set_scheme_from_view_with_colon( |
11719 | 157k | std::string_view new_scheme_with_colon) { |
11720 | 157k | ada_log("url_aggregator::set_scheme_from_view_with_colon ", |
11721 | 157k | new_scheme_with_colon); |
11722 | 157k | ADA_ASSERT_TRUE(validate()); |
11723 | 157k | ADA_ASSERT_TRUE(!new_scheme_with_colon.empty() && |
11724 | 157k | new_scheme_with_colon.back() == ':'); |
11725 | | // next line could overflow but unsigned arithmetic has well-defined |
11726 | | // overflows. |
11727 | 157k | uint32_t new_difference = |
11728 | 157k | uint32_t(new_scheme_with_colon.size()) - components.protocol_end; |
11729 | | |
11730 | 157k | if (buffer.empty()) { |
11731 | 156k | buffer.append(new_scheme_with_colon); |
11732 | 156k | } else { |
11733 | 1.25k | buffer.erase(0, components.protocol_end); |
11734 | 1.25k | buffer.insert(0, new_scheme_with_colon); |
11735 | 1.25k | } |
11736 | 157k | components.protocol_end += new_difference; |
11737 | | |
11738 | 157k | apply_shifted_non_scheme_offsets(components, new_difference); |
11739 | 157k | ADA_ASSERT_TRUE(validate()); |
11740 | 157k | } |
11741 | | |
11742 | 11.2k | inline void url_aggregator::set_scheme(std::string_view new_scheme) { |
11743 | 11.2k | ada_log("url_aggregator::set_scheme ", new_scheme); |
11744 | 11.2k | ADA_ASSERT_TRUE(validate()); |
11745 | 11.2k | ADA_ASSERT_TRUE(new_scheme.empty() || new_scheme.back() != ':'); |
11746 | | // next line could overflow but unsigned arithmetic has well-defined |
11747 | | // overflows. |
11748 | 11.2k | uint32_t new_difference = |
11749 | 11.2k | uint32_t(new_scheme.size()) - components.protocol_end + 1; |
11750 | | |
11751 | 11.2k | type = ada::scheme::get_scheme_type(new_scheme); |
11752 | 11.2k | if (buffer.empty()) { |
11753 | 11.0k | buffer.append(helpers::concat(new_scheme, ":")); |
11754 | 11.0k | } else { |
11755 | 178 | buffer.erase(0, components.protocol_end); |
11756 | 178 | buffer.insert(0, helpers::concat(new_scheme, ":")); |
11757 | 178 | } |
11758 | 11.2k | components.protocol_end = uint32_t(new_scheme.size() + 1); |
11759 | | |
11760 | 11.2k | apply_shifted_non_scheme_offsets(components, new_difference); |
11761 | 11.2k | ADA_ASSERT_TRUE(validate()); |
11762 | 11.2k | } |
11763 | | |
11764 | 266k | bool url_aggregator::needs_rollback_snapshot(size_t input_len) const noexcept { |
11765 | | // 3x should cover worst-case percent-encoding of every input byte; the |
11766 | | // constant covers the handful of delimiter bytes a setter may add ("/.", "?", |
11767 | | // "#" and so on) |
11768 | 266k | return buffer.size() + input_len * 3 + 16 > ada::get_max_input_length(); |
11769 | 266k | } |
11770 | | |
11771 | 50.1k | bool url_aggregator::set_protocol(const std::string_view input) { |
11772 | 50.1k | ada_log("url_aggregator::set_protocol ", input); |
11773 | 50.1k | ADA_ASSERT_TRUE(validate()); |
11774 | 50.1k | ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer)); |
11775 | 50.1k | std::string view(input); |
11776 | 50.1k | helpers::remove_ascii_tab_or_newline(view); |
11777 | 50.1k | if (view.empty()) { |
11778 | 2.24k | return true; |
11779 | 2.24k | } |
11780 | | |
11781 | | // Schemes should start with alpha values. |
11782 | 47.8k | if (!checkers::is_alpha(view[0])) { |
11783 | 1.55k | return false; |
11784 | 1.55k | } |
11785 | | |
11786 | 46.3k | view.append(":"); |
11787 | | |
11788 | 46.3k | std::string::iterator pointer = |
11789 | 46.3k | std::ranges::find_if_not(view, unicode::is_alnum_plus); |
11790 | | |
11791 | 46.3k | if (pointer != view.end() && *pointer == ':') { |
11792 | 46.1k | std::optional<url_aggregator> saved_url; |
11793 | 46.1k | if (needs_rollback_snapshot(view.size())) { |
11794 | 0 | saved_url = *this; |
11795 | 0 | } |
11796 | 46.1k | bool result = parse_scheme_with_colon<true>( |
11797 | 46.1k | view.substr(0, pointer - view.begin() + 1)); |
11798 | 46.1k | if (result && saved_url && buffer.size() > ada::get_max_input_length()) { |
11799 | 0 | *this = std::move(*saved_url); |
11800 | 0 | return false; |
11801 | 0 | } |
11802 | 46.1k | return result; |
11803 | 46.1k | } |
11804 | 129 | return false; |
11805 | 46.3k | } |
11806 | | |
11807 | 50.1k | bool url_aggregator::set_username(const std::string_view input) { |
11808 | 50.1k | ada_log("url_aggregator::set_username '", input, "' "); |
11809 | 50.1k | ADA_ASSERT_TRUE(validate()); |
11810 | 50.1k | ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer)); |
11811 | 50.1k | if (cannot_have_credentials_or_port()) { |
11812 | 12.7k | return false; |
11813 | 12.7k | } |
11814 | 37.3k | std::optional<url_aggregator> saved_url; |
11815 | 37.3k | if (needs_rollback_snapshot(input.size())) { |
11816 | 0 | saved_url = *this; |
11817 | 0 | } |
11818 | 37.3k | size_t idx = ada::unicode::percent_encode_index( |
11819 | 37.3k | input, character_sets::USERINFO_PERCENT_ENCODE); |
11820 | 37.3k | if (idx == input.size()) { |
11821 | 34.8k | update_base_username(input); |
11822 | 34.8k | } else { |
11823 | | // We only create a temporary string if we have to! |
11824 | 2.55k | update_base_username(ada::unicode::percent_encode( |
11825 | 2.55k | input, character_sets::USERINFO_PERCENT_ENCODE, idx)); |
11826 | 2.55k | } |
11827 | 37.3k | if (saved_url && buffer.size() > ada::get_max_input_length()) { |
11828 | 0 | *this = std::move(*saved_url); |
11829 | 0 | return false; |
11830 | 0 | } |
11831 | 37.3k | ADA_ASSERT_TRUE(validate()); |
11832 | 37.3k | return true; |
11833 | 37.3k | } |
11834 | | |
11835 | 50.1k | bool url_aggregator::set_password(const std::string_view input) { |
11836 | 50.1k | ada_log("url_aggregator::set_password '", input, "'"); |
11837 | 50.1k | ADA_ASSERT_TRUE(validate()); |
11838 | 50.1k | ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer)); |
11839 | 50.1k | if (cannot_have_credentials_or_port()) { |
11840 | 12.7k | return false; |
11841 | 12.7k | } |
11842 | 37.3k | std::optional<url_aggregator> saved_url; |
11843 | 37.3k | if (needs_rollback_snapshot(input.size())) { |
11844 | 0 | saved_url = *this; |
11845 | 0 | } |
11846 | 37.3k | size_t idx = ada::unicode::percent_encode_index( |
11847 | 37.3k | input, character_sets::USERINFO_PERCENT_ENCODE); |
11848 | 37.3k | if (idx == input.size()) { |
11849 | 34.8k | update_base_password(input); |
11850 | 34.8k | } else { |
11851 | | // We only create a temporary string if we have to! |
11852 | 2.55k | update_base_password(ada::unicode::percent_encode( |
11853 | 2.55k | input, character_sets::USERINFO_PERCENT_ENCODE, idx)); |
11854 | 2.55k | } |
11855 | 37.3k | if (saved_url && buffer.size() > ada::get_max_input_length()) { |
11856 | 0 | *this = std::move(*saved_url); |
11857 | 0 | return false; |
11858 | 0 | } |
11859 | 37.3k | ADA_ASSERT_TRUE(validate()); |
11860 | 37.3k | return true; |
11861 | 37.3k | } |
11862 | | |
11863 | 51.5k | bool url_aggregator::set_port(const std::string_view input) { |
11864 | 51.5k | ada_log("url_aggregator::set_port ", input); |
11865 | 51.5k | ADA_ASSERT_TRUE(validate()); |
11866 | 51.5k | ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer)); |
11867 | 51.5k | if (cannot_have_credentials_or_port()) { |
11868 | 12.7k | return false; |
11869 | 12.7k | } |
11870 | | |
11871 | 38.7k | if (input.empty()) { |
11872 | 1.45k | clear_port(); |
11873 | 1.45k | return true; |
11874 | 1.45k | } |
11875 | | |
11876 | 37.3k | std::string trimmed(input); |
11877 | 37.3k | helpers::remove_ascii_tab_or_newline(trimmed); |
11878 | | |
11879 | 37.3k | if (trimmed.empty()) { |
11880 | 24 | return true; |
11881 | 24 | } |
11882 | | |
11883 | | // Input should not start with a non-digit character. |
11884 | 37.3k | if (!ada::unicode::is_ascii_digit(trimmed.front())) { |
11885 | 36.7k | return false; |
11886 | 36.7k | } |
11887 | | |
11888 | | // Find the first non-digit character to determine the length of digits |
11889 | 599 | auto first_non_digit = |
11890 | 599 | std::ranges::find_if_not(trimmed, ada::unicode::is_ascii_digit); |
11891 | 599 | std::string_view digits_to_parse = |
11892 | 599 | std::string_view(trimmed.data(), first_non_digit - trimmed.begin()); |
11893 | | |
11894 | | // parse_port only touches the buffer once the digits are already known to |
11895 | | // be in range, so an invalid port never mutates anything and needs no |
11896 | | // rollback; a valid one can only grow the buffer by a few bytes. |
11897 | 599 | std::optional<url_aggregator> saved_url; |
11898 | 599 | if (needs_rollback_snapshot(digits_to_parse.size())) { |
11899 | 0 | saved_url = *this; |
11900 | 0 | } |
11901 | 599 | parse_port(digits_to_parse); |
11902 | 599 | if (!is_valid) { |
11903 | 40 | is_valid = true; |
11904 | 40 | ADA_ASSERT_TRUE(validate()); |
11905 | 40 | return false; |
11906 | 40 | } |
11907 | 559 | if (saved_url && buffer.size() > ada::get_max_input_length()) { |
11908 | 0 | *this = std::move(*saved_url); |
11909 | 0 | return false; |
11910 | 0 | } |
11911 | 559 | return true; |
11912 | 559 | } |
11913 | | |
11914 | 50.1k | bool url_aggregator::set_pathname(const std::string_view input) { |
11915 | 50.1k | ada_log("url_aggregator::set_pathname ", input); |
11916 | 50.1k | ADA_ASSERT_TRUE(validate()); |
11917 | 50.1k | ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer)); |
11918 | 50.1k | if (has_opaque_path) { |
11919 | 541 | return false; |
11920 | 541 | } |
11921 | 49.5k | std::optional<url_aggregator> saved_url; |
11922 | 49.5k | if (needs_rollback_snapshot(input.size())) { |
11923 | 0 | saved_url = *this; |
11924 | 0 | } |
11925 | 49.5k | clear_pathname(); |
11926 | 49.5k | parse_path(input); |
11927 | 49.5k | if (get_pathname().starts_with("//") && !has_authority() && !has_dash_dot()) { |
11928 | 0 | buffer.insert(components.pathname_start, "/."); |
11929 | 0 | components.pathname_start += 2; |
11930 | 0 | if (components.search_start != url_components::omitted) { |
11931 | 0 | components.search_start += 2; |
11932 | 0 | } |
11933 | 0 | if (components.hash_start != url_components::omitted) { |
11934 | 0 | components.hash_start += 2; |
11935 | 0 | } |
11936 | 0 | } |
11937 | 49.5k | if (saved_url && buffer.size() > ada::get_max_input_length()) { |
11938 | 0 | *this = std::move(*saved_url); |
11939 | 0 | return false; |
11940 | 0 | } |
11941 | 49.5k | ADA_ASSERT_TRUE(validate()); |
11942 | 49.5k | return true; |
11943 | 49.5k | } |
11944 | | |
11945 | 49.5k | ada_really_inline void url_aggregator::parse_path(std::string_view input) { |
11946 | 49.5k | ada_log("url_aggregator::parse_path ", input); |
11947 | 49.5k | ADA_ASSERT_TRUE(validate()); |
11948 | 49.5k | ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer)); |
11949 | 49.5k | std::string tmp_buffer; |
11950 | 49.5k | std::string_view internal_input; |
11951 | 49.5k | if (unicode::has_tabs_or_newline(input)) { |
11952 | 116 | tmp_buffer = input; |
11953 | | // Optimization opportunity: Instead of copying and then pruning, we could |
11954 | | // just directly build the string from user_input. |
11955 | 116 | helpers::remove_ascii_tab_or_newline(tmp_buffer); |
11956 | 116 | internal_input = tmp_buffer; |
11957 | 49.4k | } else { |
11958 | 49.4k | internal_input = input; |
11959 | 49.4k | } |
11960 | | |
11961 | | // If url is special, then: |
11962 | 49.5k | if (is_special()) { |
11963 | 48.7k | if (internal_input.empty()) { |
11964 | 1.61k | update_base_pathname("/"); |
11965 | 47.1k | } else if ((internal_input[0] == '/') || (internal_input[0] == '\\')) { |
11966 | 13 | consume_prepared_path(internal_input.substr(1)); |
11967 | 47.1k | } else { |
11968 | 47.1k | consume_prepared_path(internal_input); |
11969 | 47.1k | } |
11970 | 48.7k | } else if (!internal_input.empty()) { |
11971 | 484 | if (internal_input[0] == '/') { |
11972 | 3 | consume_prepared_path(internal_input.substr(1)); |
11973 | 481 | } else { |
11974 | 481 | consume_prepared_path(internal_input); |
11975 | 481 | } |
11976 | 484 | } else { |
11977 | | // Non-special URLs with an empty host can have their paths erased |
11978 | | // Path-only URLs cannot have their paths erased |
11979 | 303 | if (components.host_start == components.host_end && !has_authority()) { |
11980 | 0 | update_base_pathname("/"); |
11981 | 0 | } |
11982 | 303 | } |
11983 | 49.5k | ADA_ASSERT_TRUE(validate()); |
11984 | 49.5k | } |
11985 | | |
11986 | 50.1k | void url_aggregator::set_search(const std::string_view input) { |
11987 | 50.1k | ada_log("url_aggregator::set_search ", input); |
11988 | 50.1k | ADA_ASSERT_TRUE(validate()); |
11989 | 50.1k | ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer)); |
11990 | 50.1k | if (input.empty()) { |
11991 | 2.21k | clear_search(); |
11992 | 2.21k | helpers::strip_trailing_spaces_from_opaque_path(*this); |
11993 | 2.21k | return; |
11994 | 2.21k | } |
11995 | | |
11996 | 47.8k | std::string new_value; |
11997 | 47.8k | new_value = input[0] == '?' ? input.substr(1) : input; |
11998 | 47.8k | helpers::remove_ascii_tab_or_newline(new_value); |
11999 | | |
12000 | 47.8k | auto query_percent_encode_set = |
12001 | 47.8k | is_special() ? ada::character_sets::SPECIAL_QUERY_PERCENT_ENCODE |
12002 | 47.8k | : ada::character_sets::QUERY_PERCENT_ENCODE; |
12003 | | |
12004 | 47.8k | std::optional<url_aggregator> saved_url; |
12005 | 47.8k | if (needs_rollback_snapshot(new_value.size())) { |
12006 | 0 | saved_url = *this; |
12007 | 0 | } |
12008 | 47.8k | update_base_search(new_value, query_percent_encode_set); |
12009 | 47.8k | if (saved_url && buffer.size() > ada::get_max_input_length()) { |
12010 | 0 | *this = std::move(*saved_url); |
12011 | 0 | return; |
12012 | 0 | } |
12013 | 47.8k | ADA_ASSERT_TRUE(validate()); |
12014 | 47.8k | } |
12015 | | |
12016 | 50.1k | void url_aggregator::set_hash(const std::string_view input) { |
12017 | 50.1k | ada_log("url_aggregator::set_hash ", input); |
12018 | 50.1k | ADA_ASSERT_TRUE(validate()); |
12019 | 50.1k | ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer)); |
12020 | 50.1k | if (input.empty()) { |
12021 | 2.21k | if (components.hash_start != url_components::omitted) { |
12022 | 252 | buffer.resize(components.hash_start); |
12023 | 252 | components.hash_start = url_components::omitted; |
12024 | 252 | } |
12025 | 2.21k | helpers::strip_trailing_spaces_from_opaque_path(*this); |
12026 | 2.21k | return; |
12027 | 2.21k | } |
12028 | | |
12029 | 47.8k | std::string new_value; |
12030 | 47.8k | new_value = input[0] == '#' ? input.substr(1) : input; |
12031 | 47.8k | helpers::remove_ascii_tab_or_newline(new_value); |
12032 | 47.8k | std::optional<url_aggregator> saved_url; |
12033 | 47.8k | if (needs_rollback_snapshot(new_value.size())) { |
12034 | 0 | saved_url = *this; |
12035 | 0 | } |
12036 | 47.8k | update_unencoded_base_hash(new_value); |
12037 | 47.8k | if (saved_url && buffer.size() > ada::get_max_input_length()) { |
12038 | 0 | *this = std::move(*saved_url); |
12039 | 0 | return; |
12040 | 0 | } |
12041 | 47.8k | ADA_ASSERT_TRUE(validate()); |
12042 | 47.8k | } |
12043 | | |
12044 | 50.1k | bool url_aggregator::set_href(const std::string_view input) { |
12045 | 50.1k | ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer)); |
12046 | 50.1k | ada_log("url_aggregator::set_href ", input, " [", input.size(), " bytes]"); |
12047 | 50.1k | ada::result<url_aggregator> out = ada::parse<url_aggregator>(input); |
12048 | 50.1k | ada_log("url_aggregator::set_href, success :", out.has_value()); |
12049 | | |
12050 | 50.1k | if (out) { |
12051 | | // The parser enforces get_max_input_length() on both the input and the |
12052 | | // normalized result. This is a defense-in-depth check. |
12053 | 50.1k | if (out->buffer.size() > ada::get_max_input_length()) { |
12054 | 0 | return false; |
12055 | 0 | } |
12056 | 50.1k | ada_log("url_aggregator::set_href, parsed ", out->to_string()); |
12057 | | // TODO: Figure out why the following line puts test to never finish. |
12058 | 50.1k | *this = *out; |
12059 | 50.1k | } |
12060 | | |
12061 | 50.1k | return out.has_value(); |
12062 | 50.1k | } |
12063 | | |
12064 | 220k | ada_really_inline bool url_aggregator::parse_host(std::string_view input) { |
12065 | 220k | ada_log("url_aggregator:parse_host \"", input, "\" [", input.size(), |
12066 | 220k | " bytes]"); |
12067 | 220k | ADA_ASSERT_TRUE(validate()); |
12068 | 220k | ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer)); |
12069 | 220k | if (input.empty()) { |
12070 | 27 | return is_valid = false; |
12071 | 27 | } // technically unnecessary. |
12072 | | // If input starts with U+005B ([), then: |
12073 | 220k | if (input[0] == '[') { |
12074 | | // If input does not end with U+005D (]), validation error, return failure. |
12075 | 2.59k | if (input.back() != ']') { |
12076 | 538 | return is_valid = false; |
12077 | 538 | } |
12078 | 2.05k | ada_log("parse_host ipv6"); |
12079 | | |
12080 | | // Return the result of IPv6 parsing input with its leading U+005B ([) and |
12081 | | // trailing U+005D (]) removed. |
12082 | 2.05k | input.remove_prefix(1); |
12083 | 2.05k | input.remove_suffix(1); |
12084 | 2.05k | return parse_ipv6(input); |
12085 | 2.59k | } |
12086 | | |
12087 | | // If isNotSpecial is true, then return the result of opaque-host parsing |
12088 | | // input. |
12089 | 217k | if (!is_special()) { |
12090 | 2.03k | return parse_opaque_host(input); |
12091 | 2.03k | } |
12092 | | // Let domain be the result of running UTF-8 decode without BOM on the |
12093 | | // percent-decoding of input. Let asciiDomain be the result of running domain |
12094 | | // to ASCII with domain and false. The most common case is an ASCII input, in |
12095 | | // which case we do not need to call the expensive 'to_ascii' if a few |
12096 | | // conditions are met: no '%' and no 'xn-' subsequence. |
12097 | | |
12098 | | // Often, the input does not contain any forbidden code points, and no upper |
12099 | | // case ASCII letter, then we can just copy it to the buffer. We want to |
12100 | | // optimize for such a common case. |
12101 | | |
12102 | | // Fast path: try to parse as pure decimal IPv4(a.b.c.d) first. |
12103 | 215k | const uint64_t fast_result = checkers::try_parse_ipv4_fast(input); |
12104 | 215k | if (fast_result < checkers::ipv4_fast_fail) { |
12105 | | // Fast path succeeded - input is pure decimal IPv4 |
12106 | 24.3k | if (!input.empty() && input.back() == '.') { |
12107 | 99 | update_base_hostname(input.substr(0, input.size() - 1)); |
12108 | 24.2k | } else { |
12109 | 24.2k | update_base_hostname(input); |
12110 | 24.2k | } |
12111 | 24.3k | host_type = IPV4; |
12112 | 24.3k | is_valid = true; |
12113 | 24.3k | ada_log("parse_host fast path decimal ipv4"); |
12114 | 24.3k | ADA_ASSERT_TRUE(validate()); |
12115 | 24.3k | return true; |
12116 | 24.3k | } |
12117 | 191k | uint8_t is_forbidden_or_upper = |
12118 | 191k | unicode::contains_forbidden_domain_code_point_or_upper(input.data(), |
12119 | 191k | input.size()); |
12120 | | // Minor optimization opportunity: |
12121 | | // contains_forbidden_domain_code_point_or_upper could be extend to check for |
12122 | | // the presence of characters that cannot appear in the ipv4 address and we |
12123 | | // could also check whether x and n and - are present, and so we could skip |
12124 | | // some of the checks below. However, the gains are likely to be small, and |
12125 | | // the code would be more complex. |
12126 | 191k | static constexpr std::string_view xn_dash{"xn-", 3}; |
12127 | 191k | if (is_forbidden_or_upper == 0 && |
12128 | 182k | input.find(xn_dash) == std::string_view::npos) { |
12129 | | // fast path |
12130 | 180k | update_base_hostname(input); |
12131 | | |
12132 | | // Check for other IPv4 formats (hex, octal, etc.) |
12133 | 180k | if (checkers::is_ipv4(get_hostname())) { |
12134 | 3.21k | ada_log("parse_host fast path ipv4"); |
12135 | 3.21k | return parse_ipv4(get_hostname(), true); |
12136 | 3.21k | } |
12137 | 177k | ada_log("parse_host fast path ", get_hostname()); |
12138 | 177k | is_valid = true; |
12139 | 177k | return true; |
12140 | 180k | } |
12141 | | // We have encountered at least one forbidden code point or the input contains |
12142 | | // 'xn-' (case insensitive), so we need to call 'to_ascii' to perform the full |
12143 | | // conversion. |
12144 | | |
12145 | 10.7k | ada_log("parse_host calling to_ascii"); |
12146 | 10.7k | std::optional<std::string> host = std::string(get_hostname()); |
12147 | 10.7k | is_valid = ada::unicode::to_ascii(host, input, input.find('%')); |
12148 | 10.7k | if (!is_valid) { |
12149 | 3.54k | ada_log("parse_host to_ascii returns false"); |
12150 | 3.54k | return is_valid = false; |
12151 | 3.54k | } |
12152 | 7.16k | ada_log("parse_host to_ascii succeeded ", *host, " [", host->size(), |
12153 | 7.16k | " bytes]"); |
12154 | | |
12155 | 7.16k | if (std::ranges::any_of(host.value(), |
12156 | 7.16k | ada::unicode::is_forbidden_domain_code_point)) { |
12157 | 0 | return is_valid = false; |
12158 | 0 | } |
12159 | | |
12160 | | // If asciiDomain ends in a number, then return the result of IPv4 parsing |
12161 | | // asciiDomain. |
12162 | 7.16k | if (checkers::is_ipv4(host.value())) { |
12163 | 896 | ada_log("parse_host got ipv4 ", *host); |
12164 | 896 | return parse_ipv4(host.value(), false); |
12165 | 896 | } |
12166 | | |
12167 | 6.26k | update_base_hostname(host.value()); |
12168 | 6.26k | ADA_ASSERT_TRUE(validate()); |
12169 | 6.26k | return true; |
12170 | 7.16k | } |
12171 | | |
12172 | | template <bool override_hostname> |
12173 | 100k | bool url_aggregator::set_host_or_hostname(const std::string_view input) { |
12174 | 100k | ada_log("url_aggregator::set_host_or_hostname ", input); |
12175 | 100k | ADA_ASSERT_TRUE(validate()); |
12176 | 100k | ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer)); |
12177 | 100k | if (has_opaque_path) { |
12178 | 1.08k | return false; |
12179 | 1.08k | } |
12180 | | |
12181 | 99.1k | url_aggregator saved_url(*this); |
12182 | | |
12183 | 99.1k | size_t host_end_pos = input.find('#'); |
12184 | 99.1k | std::string _host(input.data(), host_end_pos != std::string_view::npos |
12185 | 99.1k | ? host_end_pos |
12186 | 99.1k | : input.size()); |
12187 | 99.1k | helpers::remove_ascii_tab_or_newline(_host); |
12188 | 99.1k | std::string_view new_host(_host); |
12189 | | |
12190 | 99.1k | auto check_url_size = [&]() -> bool { |
12191 | 92.1k | if (buffer.size() > ada::get_max_input_length()) { |
12192 | 0 | *this = std::move(saved_url); |
12193 | 0 | return false; |
12194 | 0 | } |
12195 | 92.1k | return true; |
12196 | 92.1k | }; ada::url_aggregator::set_host_or_hostname<false>(std::__1::basic_string_view<char, std::__1::char_traits<char> >)::{lambda()#1}::operator()() constLine | Count | Source | 12190 | 46.8k | auto check_url_size = [&]() -> bool { | 12191 | 46.8k | if (buffer.size() > ada::get_max_input_length()) { | 12192 | 0 | *this = std::move(saved_url); | 12193 | 0 | return false; | 12194 | 0 | } | 12195 | 46.8k | return true; | 12196 | 46.8k | }; |
ada::url_aggregator::set_host_or_hostname<true>(std::__1::basic_string_view<char, std::__1::char_traits<char> >)::{lambda()#1}::operator()() constLine | Count | Source | 12190 | 45.2k | auto check_url_size = [&]() -> bool { | 12191 | 45.2k | if (buffer.size() > ada::get_max_input_length()) { | 12192 | 0 | *this = std::move(saved_url); | 12193 | 0 | return false; | 12194 | 0 | } | 12195 | 45.2k | return true; | 12196 | 45.2k | }; |
|
12197 | | |
12198 | | // If url's scheme is "file", then set state to file host state, instead of |
12199 | | // host state. |
12200 | 99.1k | if (type != ada::scheme::type::FILE) { |
12201 | 75.1k | std::string_view host_view(_host.data(), _host.length()); |
12202 | 75.1k | auto [location, found_colon] = |
12203 | 75.1k | helpers::get_host_delimiter_location(is_special(), host_view); |
12204 | | |
12205 | | // Otherwise, if c is U+003A (:) and insideBrackets is false, then: |
12206 | | // Note: the 'found_colon' value is true if and only if a colon was |
12207 | | // encountered while not inside brackets. |
12208 | 75.1k | if (found_colon) { |
12209 | | // If buffer is the empty string, host-missing validation error, return |
12210 | | // failure. |
12211 | 3.67k | std::string_view host_buffer = host_view.substr(0, location); |
12212 | 3.67k | if (host_buffer.empty()) { |
12213 | 30 | return false; |
12214 | 30 | } |
12215 | | |
12216 | | // If state override is given and state override is hostname state, then |
12217 | | // return failure. |
12218 | 3.64k | if constexpr (override_hostname) { |
12219 | 1.82k | return false; |
12220 | 1.82k | } |
12221 | | |
12222 | | // Let host be the result of host parsing buffer with url is not special. |
12223 | 0 | bool succeeded = parse_host(host_buffer); |
12224 | 3.64k | if (!succeeded) { |
12225 | 262 | *this = std::move(saved_url); |
12226 | 262 | return false; |
12227 | 3.38k | } else if (has_dash_dot()) { |
12228 | | // The url now has a non-null host, so the "/." that guarded a |
12229 | | // leading "//" path is no longer needed. Drop it before the port is |
12230 | | // inserted at host_end, otherwise it stays wedged in the path. |
12231 | 6 | delete_dash_dot(); |
12232 | 6 | } |
12233 | | |
12234 | | // Set url's host to host, buffer to the empty string, and state to port |
12235 | | // state. |
12236 | 3.38k | std::string_view port_buffer = new_host.substr(location + 1); |
12237 | 3.38k | if (!port_buffer.empty()) { |
12238 | 1.43k | set_port(port_buffer); |
12239 | 1.43k | } |
12240 | 3.38k | return check_url_size(); |
12241 | 3.64k | } |
12242 | | // Otherwise, if one of the following is true: |
12243 | | // - c is the EOF code point, U+002F (/), U+003F (?), or U+0023 (#) |
12244 | | // - url is special and c is U+005C (\) |
12245 | 71.4k | else { |
12246 | | // If url is special and host_view is the empty string, host-missing |
12247 | | // validation error, return failure. |
12248 | 71.4k | if (host_view.empty() && is_special()) { |
12249 | 2.88k | return false; |
12250 | 2.88k | } |
12251 | | |
12252 | | // Otherwise, if state override is given, host_view is the empty string, |
12253 | | // and either url includes credentials or url's port is non-null, then |
12254 | | // return failure. |
12255 | 68.5k | if (host_view.empty() && (has_credentials() || has_port())) { |
12256 | 98 | return false; |
12257 | 98 | } |
12258 | | |
12259 | | // Let host be the result of host parsing host_view with url is not |
12260 | | // special. |
12261 | 68.4k | if (host_view.empty() && !is_special()) { |
12262 | 518 | if (has_hostname()) { |
12263 | 346 | clear_hostname(); // easy! |
12264 | 346 | } else if (has_dash_dot()) { |
12265 | 24 | add_authority_slashes_if_needed(); |
12266 | 24 | delete_dash_dot(); |
12267 | 148 | } else { |
12268 | | // The url has no authority yet (e.g. "foo:/bar"); setting an empty |
12269 | | // host must still give it an (empty) authority, matching ada::url. |
12270 | 148 | add_authority_slashes_if_needed(); |
12271 | 148 | } |
12272 | 518 | return check_url_size(); |
12273 | 518 | } |
12274 | | |
12275 | 67.9k | bool succeeded = parse_host(host_view); |
12276 | 67.9k | if (!succeeded) { |
12277 | 776 | *this = std::move(saved_url); |
12278 | 776 | return false; |
12279 | 67.1k | } else if (has_dash_dot()) { |
12280 | | // Should remove dash_dot from pathname |
12281 | 8 | delete_dash_dot(); |
12282 | 8 | } |
12283 | 67.1k | return check_url_size(); |
12284 | 67.9k | } |
12285 | 75.1k | } |
12286 | | |
12287 | 24.0k | size_t location = new_host.find_first_of("/\\?"); |
12288 | 24.0k | if (location != std::string_view::npos) { |
12289 | 942 | new_host.remove_suffix(new_host.length() - location); |
12290 | 942 | } |
12291 | | |
12292 | 24.0k | if (new_host.empty()) { |
12293 | | // Set url's host to the empty string. |
12294 | 384 | clear_hostname(); |
12295 | 23.6k | } else { |
12296 | | // Let host be the result of host parsing buffer with url is not special. |
12297 | 23.6k | if (!parse_host(new_host)) { |
12298 | 1.12k | *this = std::move(saved_url); |
12299 | 1.12k | return false; |
12300 | 1.12k | } |
12301 | | |
12302 | | // If host is "localhost", then set host to the empty string. |
12303 | 22.5k | if (helpers::substring(buffer, components.host_start, |
12304 | 22.5k | components.host_end) == "localhost") { |
12305 | 4 | clear_hostname(); |
12306 | 4 | } |
12307 | 22.5k | } |
12308 | 22.8k | ADA_ASSERT_TRUE(validate()); |
12309 | 22.8k | return check_url_size(); |
12310 | 24.0k | } bool ada::url_aggregator::set_host_or_hostname<false>(std::__1::basic_string_view<char, std::__1::char_traits<char> >) Line | Count | Source | 12173 | 50.1k | bool url_aggregator::set_host_or_hostname(const std::string_view input) { | 12174 | 50.1k | ada_log("url_aggregator::set_host_or_hostname ", input); | 12175 | 50.1k | ADA_ASSERT_TRUE(validate()); | 12176 | 50.1k | ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer)); | 12177 | 50.1k | if (has_opaque_path) { | 12178 | 541 | return false; | 12179 | 541 | } | 12180 | | | 12181 | 49.5k | url_aggregator saved_url(*this); | 12182 | | | 12183 | 49.5k | size_t host_end_pos = input.find('#'); | 12184 | 49.5k | std::string _host(input.data(), host_end_pos != std::string_view::npos | 12185 | 49.5k | ? host_end_pos | 12186 | 49.5k | : input.size()); | 12187 | 49.5k | helpers::remove_ascii_tab_or_newline(_host); | 12188 | 49.5k | std::string_view new_host(_host); | 12189 | | | 12190 | 49.5k | auto check_url_size = [&]() -> bool { | 12191 | 49.5k | if (buffer.size() > ada::get_max_input_length()) { | 12192 | 49.5k | *this = std::move(saved_url); | 12193 | 49.5k | return false; | 12194 | 49.5k | } | 12195 | 49.5k | return true; | 12196 | 49.5k | }; | 12197 | | | 12198 | | // If url's scheme is "file", then set state to file host state, instead of | 12199 | | // host state. | 12200 | 49.5k | if (type != ada::scheme::type::FILE) { | 12201 | 37.5k | std::string_view host_view(_host.data(), _host.length()); | 12202 | 37.5k | auto [location, found_colon] = | 12203 | 37.5k | helpers::get_host_delimiter_location(is_special(), host_view); | 12204 | | | 12205 | | // Otherwise, if c is U+003A (:) and insideBrackets is false, then: | 12206 | | // Note: the 'found_colon' value is true if and only if a colon was | 12207 | | // encountered while not inside brackets. | 12208 | 37.5k | if (found_colon) { | 12209 | | // If buffer is the empty string, host-missing validation error, return | 12210 | | // failure. | 12211 | 1.83k | std::string_view host_buffer = host_view.substr(0, location); | 12212 | 1.83k | if (host_buffer.empty()) { | 12213 | 15 | return false; | 12214 | 15 | } | 12215 | | | 12216 | | // If state override is given and state override is hostname state, then | 12217 | | // return failure. | 12218 | | if constexpr (override_hostname) { | 12219 | | return false; | 12220 | | } | 12221 | | | 12222 | | // Let host be the result of host parsing buffer with url is not special. | 12223 | 1.82k | bool succeeded = parse_host(host_buffer); | 12224 | 1.82k | if (!succeeded) { | 12225 | 262 | *this = std::move(saved_url); | 12226 | 262 | return false; | 12227 | 1.56k | } else if (has_dash_dot()) { | 12228 | | // The url now has a non-null host, so the "/." that guarded a | 12229 | | // leading "//" path is no longer needed. Drop it before the port is | 12230 | | // inserted at host_end, otherwise it stays wedged in the path. | 12231 | 6 | delete_dash_dot(); | 12232 | 6 | } | 12233 | | | 12234 | | // Set url's host to host, buffer to the empty string, and state to port | 12235 | | // state. | 12236 | 1.56k | std::string_view port_buffer = new_host.substr(location + 1); | 12237 | 1.56k | if (!port_buffer.empty()) { | 12238 | 1.43k | set_port(port_buffer); | 12239 | 1.43k | } | 12240 | 1.56k | return check_url_size(); | 12241 | 1.82k | } | 12242 | | // Otherwise, if one of the following is true: | 12243 | | // - c is the EOF code point, U+002F (/), U+003F (?), or U+0023 (#) | 12244 | | // - url is special and c is U+005C (\) | 12245 | 35.7k | else { | 12246 | | // If url is special and host_view is the empty string, host-missing | 12247 | | // validation error, return failure. | 12248 | 35.7k | if (host_view.empty() && is_special()) { | 12249 | 1.44k | return false; | 12250 | 1.44k | } | 12251 | | | 12252 | | // Otherwise, if state override is given, host_view is the empty string, | 12253 | | // and either url includes credentials or url's port is non-null, then | 12254 | | // return failure. | 12255 | 34.2k | if (host_view.empty() && (has_credentials() || has_port())) { | 12256 | 49 | return false; | 12257 | 49 | } | 12258 | | | 12259 | | // Let host be the result of host parsing host_view with url is not | 12260 | | // special. | 12261 | 34.2k | if (host_view.empty() && !is_special()) { | 12262 | 259 | if (has_hostname()) { | 12263 | 87 | clear_hostname(); // easy! | 12264 | 172 | } else if (has_dash_dot()) { | 12265 | 24 | add_authority_slashes_if_needed(); | 12266 | 24 | delete_dash_dot(); | 12267 | 148 | } else { | 12268 | | // The url has no authority yet (e.g. "foo:/bar"); setting an empty | 12269 | | // host must still give it an (empty) authority, matching ada::url. | 12270 | 148 | add_authority_slashes_if_needed(); | 12271 | 148 | } | 12272 | 259 | return check_url_size(); | 12273 | 259 | } | 12274 | | | 12275 | 33.9k | bool succeeded = parse_host(host_view); | 12276 | 33.9k | if (!succeeded) { | 12277 | 388 | *this = std::move(saved_url); | 12278 | 388 | return false; | 12279 | 33.5k | } else if (has_dash_dot()) { | 12280 | | // Should remove dash_dot from pathname | 12281 | 8 | delete_dash_dot(); | 12282 | 8 | } | 12283 | 33.5k | return check_url_size(); | 12284 | 33.9k | } | 12285 | 37.5k | } | 12286 | | | 12287 | 12.0k | size_t location = new_host.find_first_of("/\\?"); | 12288 | 12.0k | if (location != std::string_view::npos) { | 12289 | 471 | new_host.remove_suffix(new_host.length() - location); | 12290 | 471 | } | 12291 | | | 12292 | 12.0k | if (new_host.empty()) { | 12293 | | // Set url's host to the empty string. | 12294 | 192 | clear_hostname(); | 12295 | 11.8k | } else { | 12296 | | // Let host be the result of host parsing buffer with url is not special. | 12297 | 11.8k | if (!parse_host(new_host)) { | 12298 | 561 | *this = std::move(saved_url); | 12299 | 561 | return false; | 12300 | 561 | } | 12301 | | | 12302 | | // If host is "localhost", then set host to the empty string. | 12303 | 11.2k | if (helpers::substring(buffer, components.host_start, | 12304 | 11.2k | components.host_end) == "localhost") { | 12305 | 2 | clear_hostname(); | 12306 | 2 | } | 12307 | 11.2k | } | 12308 | 11.4k | ADA_ASSERT_TRUE(validate()); | 12309 | 11.4k | return check_url_size(); | 12310 | 12.0k | } |
bool ada::url_aggregator::set_host_or_hostname<true>(std::__1::basic_string_view<char, std::__1::char_traits<char> >) Line | Count | Source | 12173 | 50.1k | bool url_aggregator::set_host_or_hostname(const std::string_view input) { | 12174 | 50.1k | ada_log("url_aggregator::set_host_or_hostname ", input); | 12175 | 50.1k | ADA_ASSERT_TRUE(validate()); | 12176 | 50.1k | ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer)); | 12177 | 50.1k | if (has_opaque_path) { | 12178 | 541 | return false; | 12179 | 541 | } | 12180 | | | 12181 | 49.5k | url_aggregator saved_url(*this); | 12182 | | | 12183 | 49.5k | size_t host_end_pos = input.find('#'); | 12184 | 49.5k | std::string _host(input.data(), host_end_pos != std::string_view::npos | 12185 | 49.5k | ? host_end_pos | 12186 | 49.5k | : input.size()); | 12187 | 49.5k | helpers::remove_ascii_tab_or_newline(_host); | 12188 | 49.5k | std::string_view new_host(_host); | 12189 | | | 12190 | 49.5k | auto check_url_size = [&]() -> bool { | 12191 | 49.5k | if (buffer.size() > ada::get_max_input_length()) { | 12192 | 49.5k | *this = std::move(saved_url); | 12193 | 49.5k | return false; | 12194 | 49.5k | } | 12195 | 49.5k | return true; | 12196 | 49.5k | }; | 12197 | | | 12198 | | // If url's scheme is "file", then set state to file host state, instead of | 12199 | | // host state. | 12200 | 49.5k | if (type != ada::scheme::type::FILE) { | 12201 | 37.5k | std::string_view host_view(_host.data(), _host.length()); | 12202 | 37.5k | auto [location, found_colon] = | 12203 | 37.5k | helpers::get_host_delimiter_location(is_special(), host_view); | 12204 | | | 12205 | | // Otherwise, if c is U+003A (:) and insideBrackets is false, then: | 12206 | | // Note: the 'found_colon' value is true if and only if a colon was | 12207 | | // encountered while not inside brackets. | 12208 | 37.5k | if (found_colon) { | 12209 | | // If buffer is the empty string, host-missing validation error, return | 12210 | | // failure. | 12211 | 1.83k | std::string_view host_buffer = host_view.substr(0, location); | 12212 | 1.83k | if (host_buffer.empty()) { | 12213 | 15 | return false; | 12214 | 15 | } | 12215 | | | 12216 | | // If state override is given and state override is hostname state, then | 12217 | | // return failure. | 12218 | 1.82k | if constexpr (override_hostname) { | 12219 | 1.82k | return false; | 12220 | 1.82k | } | 12221 | | | 12222 | | // Let host be the result of host parsing buffer with url is not special. | 12223 | 0 | bool succeeded = parse_host(host_buffer); | 12224 | 1.82k | if (!succeeded) { | 12225 | 0 | *this = std::move(saved_url); | 12226 | 0 | return false; | 12227 | 1.82k | } else if (has_dash_dot()) { | 12228 | | // The url now has a non-null host, so the "/." that guarded a | 12229 | | // leading "//" path is no longer needed. Drop it before the port is | 12230 | | // inserted at host_end, otherwise it stays wedged in the path. | 12231 | 0 | delete_dash_dot(); | 12232 | 0 | } | 12233 | | | 12234 | | // Set url's host to host, buffer to the empty string, and state to port | 12235 | | // state. | 12236 | 1.82k | std::string_view port_buffer = new_host.substr(location + 1); | 12237 | 1.82k | if (!port_buffer.empty()) { | 12238 | 0 | set_port(port_buffer); | 12239 | 0 | } | 12240 | 1.82k | return check_url_size(); | 12241 | 1.82k | } | 12242 | | // Otherwise, if one of the following is true: | 12243 | | // - c is the EOF code point, U+002F (/), U+003F (?), or U+0023 (#) | 12244 | | // - url is special and c is U+005C (\) | 12245 | 35.7k | else { | 12246 | | // If url is special and host_view is the empty string, host-missing | 12247 | | // validation error, return failure. | 12248 | 35.7k | if (host_view.empty() && is_special()) { | 12249 | 1.44k | return false; | 12250 | 1.44k | } | 12251 | | | 12252 | | // Otherwise, if state override is given, host_view is the empty string, | 12253 | | // and either url includes credentials or url's port is non-null, then | 12254 | | // return failure. | 12255 | 34.2k | if (host_view.empty() && (has_credentials() || has_port())) { | 12256 | 49 | return false; | 12257 | 49 | } | 12258 | | | 12259 | | // Let host be the result of host parsing host_view with url is not | 12260 | | // special. | 12261 | 34.2k | if (host_view.empty() && !is_special()) { | 12262 | 259 | if (has_hostname()) { | 12263 | 259 | clear_hostname(); // easy! | 12264 | 259 | } else if (has_dash_dot()) { | 12265 | 0 | add_authority_slashes_if_needed(); | 12266 | 0 | delete_dash_dot(); | 12267 | 0 | } else { | 12268 | | // The url has no authority yet (e.g. "foo:/bar"); setting an empty | 12269 | | // host must still give it an (empty) authority, matching ada::url. | 12270 | 0 | add_authority_slashes_if_needed(); | 12271 | 0 | } | 12272 | 259 | return check_url_size(); | 12273 | 259 | } | 12274 | | | 12275 | 33.9k | bool succeeded = parse_host(host_view); | 12276 | 33.9k | if (!succeeded) { | 12277 | 388 | *this = std::move(saved_url); | 12278 | 388 | return false; | 12279 | 33.5k | } else if (has_dash_dot()) { | 12280 | | // Should remove dash_dot from pathname | 12281 | 0 | delete_dash_dot(); | 12282 | 0 | } | 12283 | 33.5k | return check_url_size(); | 12284 | 33.9k | } | 12285 | 37.5k | } | 12286 | | | 12287 | 12.0k | size_t location = new_host.find_first_of("/\\?"); | 12288 | 12.0k | if (location != std::string_view::npos) { | 12289 | 471 | new_host.remove_suffix(new_host.length() - location); | 12290 | 471 | } | 12291 | | | 12292 | 12.0k | if (new_host.empty()) { | 12293 | | // Set url's host to the empty string. | 12294 | 192 | clear_hostname(); | 12295 | 11.8k | } else { | 12296 | | // Let host be the result of host parsing buffer with url is not special. | 12297 | 11.8k | if (!parse_host(new_host)) { | 12298 | 561 | *this = std::move(saved_url); | 12299 | 561 | return false; | 12300 | 561 | } | 12301 | | | 12302 | | // If host is "localhost", then set host to the empty string. | 12303 | 11.2k | if (helpers::substring(buffer, components.host_start, | 12304 | 11.2k | components.host_end) == "localhost") { | 12305 | 2 | clear_hostname(); | 12306 | 2 | } | 12307 | 11.2k | } | 12308 | 11.4k | ADA_ASSERT_TRUE(validate()); | 12309 | 11.4k | return check_url_size(); | 12310 | 12.0k | } |
|
12311 | | |
12312 | 50.1k | bool url_aggregator::set_host(const std::string_view input) { |
12313 | 50.1k | ada_log("url_aggregator::set_host '", input, "'"); |
12314 | 50.1k | ADA_ASSERT_TRUE(validate()); |
12315 | 50.1k | ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer)); |
12316 | 50.1k | return set_host_or_hostname<false>(input); |
12317 | 50.1k | } |
12318 | | |
12319 | 50.1k | bool url_aggregator::set_hostname(const std::string_view input) { |
12320 | 50.1k | ada_log("url_aggregator::set_hostname '", input, "'"); |
12321 | 50.1k | ADA_ASSERT_TRUE(validate()); |
12322 | 50.1k | ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer)); |
12323 | 50.1k | return set_host_or_hostname<true>(input); |
12324 | 50.1k | } |
12325 | | |
12326 | 52.8k | [[nodiscard]] std::string url_aggregator::get_origin() const { |
12327 | 52.8k | ada_log("url_aggregator::get_origin"); |
12328 | 52.8k | if (is_special()) { |
12329 | | // Return a new opaque origin. |
12330 | 51.0k | if (type == scheme::FILE) { |
12331 | 12.5k | return "null"; |
12332 | 12.5k | } |
12333 | | |
12334 | 38.5k | return helpers::concat(get_protocol(), "//", get_host()); |
12335 | 51.0k | } |
12336 | | |
12337 | 1.83k | if (get_protocol() == "blob:") { |
12338 | 283 | std::string_view path = get_pathname(); |
12339 | 283 | if (!path.empty()) { |
12340 | 273 | auto out = ada::parse<ada::url_aggregator>(path); |
12341 | 273 | if (out && (out->type == scheme::HTTP || out->type == scheme::HTTPS)) { |
12342 | | // If pathURL's scheme is not "http" and not "https", then return a |
12343 | | // new opaque origin. |
12344 | 31 | return helpers::concat(out->get_protocol(), "//", out->get_host()); |
12345 | 31 | } |
12346 | 273 | } |
12347 | 283 | } |
12348 | | |
12349 | | // Return a new opaque origin. |
12350 | 1.79k | return "null"; |
12351 | 1.83k | } |
12352 | | |
12353 | | [[nodiscard]] std::string_view url_aggregator::get_username() const |
12354 | 52.8k | ada_lifetime_bound { |
12355 | 52.8k | ada_log("url_aggregator::get_username"); |
12356 | 52.8k | if (has_non_empty_username()) { |
12357 | 36.1k | return helpers::substring(buffer, components.protocol_end + 2, |
12358 | 36.1k | components.username_end); |
12359 | 36.1k | } |
12360 | 16.7k | return ""; |
12361 | 52.8k | } |
12362 | | |
12363 | | [[nodiscard]] std::string_view url_aggregator::get_password() const |
12364 | 52.8k | ada_lifetime_bound { |
12365 | 52.8k | ada_log("url_aggregator::get_password"); |
12366 | 52.8k | if (has_non_empty_password()) { |
12367 | 36.0k | return helpers::substring(buffer, components.username_end + 1, |
12368 | 36.0k | components.host_start); |
12369 | 36.0k | } |
12370 | 16.8k | return ""; |
12371 | 52.8k | } |
12372 | | |
12373 | | [[nodiscard]] std::string_view url_aggregator::get_port() const |
12374 | 52.8k | ada_lifetime_bound { |
12375 | 52.8k | ada_log("url_aggregator::get_port"); |
12376 | 52.8k | if (components.port == url_components::omitted) { |
12377 | 41.1k | return ""; |
12378 | 41.1k | } |
12379 | 11.7k | return helpers::substring(buffer, components.host_end + 1, |
12380 | 11.7k | components.pathname_start); |
12381 | 52.8k | } |
12382 | | |
12383 | | [[nodiscard]] std::string_view url_aggregator::get_hash() const |
12384 | 52.8k | ada_lifetime_bound { |
12385 | 52.8k | ada_log("url_aggregator::get_hash"); |
12386 | | // If this's URL's fragment is either null or the empty string, then return |
12387 | | // the empty string. Return U+0023 (#), followed by this's URL's fragment. |
12388 | 52.8k | if (components.hash_start == url_components::omitted) { |
12389 | 4.61k | return ""; |
12390 | 4.61k | } |
12391 | 48.2k | if (buffer.size() - components.hash_start <= 1) { |
12392 | 125 | return ""; |
12393 | 125 | } |
12394 | 48.1k | return helpers::substring(buffer, components.hash_start); |
12395 | 48.2k | } |
12396 | | |
12397 | | [[nodiscard]] std::string_view url_aggregator::get_host() const |
12398 | 88.8k | ada_lifetime_bound { |
12399 | 88.8k | ada_log("url_aggregator::get_host"); |
12400 | | // Technically, we should check if there is a hostname, but |
12401 | | // the code below works even if there isn't. |
12402 | | // if(!has_hostname()) { return ""; } |
12403 | 88.8k | size_t start = components.host_start; |
12404 | 88.8k | if (components.host_end > components.host_start && |
12405 | 87.4k | buffer[components.host_start] == '@') { |
12406 | 71.6k | start++; |
12407 | 71.6k | } |
12408 | | // if we have an empty host, then the space between components.host_end and |
12409 | | // components.pathname_start may be occupied by /. |
12410 | 88.8k | if (start == components.host_end) { |
12411 | 1.34k | return {}; |
12412 | 1.34k | } |
12413 | 87.4k | return helpers::substring(buffer, start, components.pathname_start); |
12414 | 88.8k | } |
12415 | | |
12416 | | [[nodiscard]] std::string_view url_aggregator::get_hostname() const |
12417 | 266k | ada_lifetime_bound { |
12418 | 266k | ada_log("url_aggregator::get_hostname"); |
12419 | | // Technically, we should check if there is a hostname, but |
12420 | | // the code below works even if there isn't. |
12421 | | // if(!has_hostname()) { return ""; } |
12422 | 266k | size_t start = components.host_start; |
12423 | | // So host_start is not where the host begins. |
12424 | 266k | if (components.host_end > components.host_start && |
12425 | 254k | buffer[components.host_start] == '@') { |
12426 | 117k | start++; |
12427 | 117k | } |
12428 | 266k | return helpers::substring(buffer, start, components.host_end); |
12429 | 266k | } |
12430 | | |
12431 | | [[nodiscard]] std::string_view url_aggregator::get_search() const |
12432 | 53.0k | ada_lifetime_bound { |
12433 | 53.0k | ada_log("url_aggregator::get_search"); |
12434 | | // If this's URL's query is either null or the empty string, then return the |
12435 | | // empty string. Return U+003F (?), followed by this's URL's query. |
12436 | 53.0k | if (components.search_start == url_components::omitted) { |
12437 | 4.53k | return ""; |
12438 | 4.53k | } |
12439 | 48.4k | auto ending_index = uint32_t(buffer.size()); |
12440 | 48.4k | if (components.hash_start != url_components::omitted) { |
12441 | 47.9k | ending_index = components.hash_start; |
12442 | 47.9k | } |
12443 | 48.4k | if (ending_index - components.search_start <= 1) { |
12444 | 89 | return ""; |
12445 | 89 | } |
12446 | 48.4k | return helpers::substring(buffer, components.search_start, ending_index); |
12447 | 48.4k | } |
12448 | | |
12449 | | [[nodiscard]] std::string_view url_aggregator::get_protocol() const |
12450 | 94.5k | ada_lifetime_bound { |
12451 | 94.5k | ada_log("url_aggregator::get_protocol"); |
12452 | 94.5k | return helpers::substring(buffer, 0, components.protocol_end); |
12453 | 94.5k | } |
12454 | | |
12455 | 0 | [[nodiscard]] std::string ada::url_aggregator::to_string() const { |
12456 | 0 | ada_log("url_aggregator::to_string buffer:", buffer, " [", buffer.size(), |
12457 | 0 | " bytes]"); |
12458 | 0 | if (!is_valid) { |
12459 | 0 | return "null"; |
12460 | 0 | } |
12461 | | |
12462 | 0 | std::string answer; |
12463 | 0 | auto back = std::back_insert_iterator(answer); |
12464 | 0 | answer.append("{\n"); |
12465 | |
|
12466 | 0 | answer.append("\t\"buffer\":\""); |
12467 | 0 | helpers::encode_json(buffer, back); |
12468 | 0 | answer.append("\",\n"); |
12469 | |
|
12470 | 0 | answer.append("\t\"protocol\":\""); |
12471 | 0 | helpers::encode_json(get_protocol(), back); |
12472 | 0 | answer.append("\",\n"); |
12473 | |
|
12474 | 0 | if (has_credentials()) { |
12475 | 0 | answer.append("\t\"username\":\""); |
12476 | 0 | helpers::encode_json(get_username(), back); |
12477 | 0 | answer.append("\",\n"); |
12478 | 0 | answer.append("\t\"password\":\""); |
12479 | 0 | helpers::encode_json(get_password(), back); |
12480 | 0 | answer.append("\",\n"); |
12481 | 0 | } |
12482 | |
|
12483 | 0 | answer.append("\t\"host\":\""); |
12484 | 0 | helpers::encode_json(get_host(), back); |
12485 | 0 | answer.append("\",\n"); |
12486 | |
|
12487 | 0 | answer.append("\t\"path\":\""); |
12488 | 0 | helpers::encode_json(get_pathname(), back); |
12489 | 0 | answer.append("\",\n"); |
12490 | 0 | answer.append("\t\"opaque path\":"); |
12491 | 0 | answer.append((has_opaque_path ? "true" : "false")); |
12492 | 0 | answer.append(",\n"); |
12493 | |
|
12494 | 0 | if (components.search_start != url_components::omitted) { |
12495 | 0 | answer.append("\t\"query\":\""); |
12496 | 0 | helpers::encode_json(get_search(), back); |
12497 | 0 | answer.append("\",\n"); |
12498 | 0 | } |
12499 | 0 | if (components.hash_start != url_components::omitted) { |
12500 | 0 | answer.append("\t\"fragment\":\""); |
12501 | 0 | helpers::encode_json(get_hash(), back); |
12502 | 0 | answer.append("\",\n"); |
12503 | 0 | } |
12504 | |
|
12505 | 0 | auto convert_offset_to_string = [](uint32_t offset) -> std::string { |
12506 | 0 | if (offset == url_components::omitted) { |
12507 | 0 | return "null"; |
12508 | 0 | } else { |
12509 | 0 | return std::to_string(offset); |
12510 | 0 | } |
12511 | 0 | }; |
12512 | |
|
12513 | 0 | answer.append("\t\"protocol_end\":"); |
12514 | 0 | answer.append(convert_offset_to_string(components.protocol_end)); |
12515 | 0 | answer.append(",\n"); |
12516 | |
|
12517 | 0 | answer.append("\t\"username_end\":"); |
12518 | 0 | answer.append(convert_offset_to_string(components.username_end)); |
12519 | 0 | answer.append(",\n"); |
12520 | |
|
12521 | 0 | answer.append("\t\"host_start\":"); |
12522 | 0 | answer.append(convert_offset_to_string(components.host_start)); |
12523 | 0 | answer.append(",\n"); |
12524 | |
|
12525 | 0 | answer.append("\t\"host_end\":"); |
12526 | 0 | answer.append(convert_offset_to_string(components.host_end)); |
12527 | 0 | answer.append(",\n"); |
12528 | |
|
12529 | 0 | answer.append("\t\"port\":"); |
12530 | 0 | answer.append(convert_offset_to_string(components.port)); |
12531 | 0 | answer.append(",\n"); |
12532 | |
|
12533 | 0 | answer.append("\t\"pathname_start\":"); |
12534 | 0 | answer.append(convert_offset_to_string(components.pathname_start)); |
12535 | 0 | answer.append(",\n"); |
12536 | |
|
12537 | 0 | answer.append("\t\"search_start\":"); |
12538 | 0 | answer.append(convert_offset_to_string(components.search_start)); |
12539 | 0 | answer.append(",\n"); |
12540 | |
|
12541 | 0 | answer.append("\t\"hash_start\":"); |
12542 | 0 | answer.append(convert_offset_to_string(components.hash_start)); |
12543 | 0 | answer.append("\n}"); |
12544 | |
|
12545 | 0 | return answer; |
12546 | 0 | } |
12547 | | |
12548 | 0 | [[nodiscard]] bool url_aggregator::has_valid_domain() const noexcept { |
12549 | 0 | if (components.host_start == components.host_end) { |
12550 | 0 | return false; |
12551 | 0 | } |
12552 | | // Avoid allocation: construct a string_view directly into the buffer. |
12553 | 0 | size_t start = components.host_start; |
12554 | 0 | if (components.host_end > components.host_start && |
12555 | 0 | buffer[components.host_start] == '@') { |
12556 | 0 | start++; |
12557 | 0 | } |
12558 | 0 | return checkers::verify_dns_length( |
12559 | 0 | std::string_view(buffer.data() + start, components.host_end - start)); |
12560 | 0 | } |
12561 | | |
12562 | 4.11k | bool url_aggregator::parse_ipv4(std::string_view input, bool in_place) { |
12563 | 4.11k | ada_log("parse_ipv4 ", input, " [", input.size(), |
12564 | 4.11k | " bytes], overlaps with buffer: ", |
12565 | 4.11k | helpers::overlaps(input, buffer) ? "yes" : "no"); |
12566 | 4.11k | ADA_ASSERT_TRUE(validate()); |
12567 | 4.11k | if (input.empty()) { |
12568 | 0 | return is_valid = false; |
12569 | 0 | } |
12570 | 4.11k | const bool trailing_dot = (input.back() == '.'); |
12571 | 4.11k | if (trailing_dot) { |
12572 | 134 | input.remove_suffix(1); |
12573 | 134 | if (input.empty()) { |
12574 | 0 | return is_valid = false; |
12575 | 0 | } |
12576 | 134 | } |
12577 | | |
12578 | 4.11k | const uint64_t fast = checkers::try_parse_ipv4_fast(input); |
12579 | 4.11k | if (fast < checkers::ipv4_fast_fail) [[likely]] { |
12580 | | // Pure decimal: keep the buffer when it already holds the address. |
12581 | | // Otherwise write the (trailing-dot-stripped) input. |
12582 | 11 | if (!(in_place && !trailing_dot)) { |
12583 | 11 | update_base_hostname(input); |
12584 | 11 | } |
12585 | 11 | host_type = IPV4; |
12586 | 11 | ADA_ASSERT_TRUE(validate()); |
12587 | 11 | return true; |
12588 | 11 | } |
12589 | | |
12590 | 4.10k | const char* p = input.data(); |
12591 | 4.10k | const char* end = p + input.size(); |
12592 | 4.10k | uint64_t ipv4 = 0; |
12593 | 4.10k | int digit_count = 0; |
12594 | 4.10k | int pure_decimal_count = 0; |
12595 | | |
12596 | 6.38k | for (; digit_count < 4 && p < end; ++digit_count) { |
12597 | 6.32k | uint64_t segment = 0; |
12598 | 6.32k | bool pure = false; |
12599 | 6.32k | if (!detail::parse_ipv4_number(p, end, segment, pure)) { |
12600 | 796 | return is_valid = false; |
12601 | 796 | } |
12602 | 5.52k | if (pure) { |
12603 | 3.48k | ++pure_decimal_count; |
12604 | 3.48k | } |
12605 | 5.52k | if (p >= end) { |
12606 | 3.10k | const unsigned shift = static_cast<unsigned>(32 - digit_count * 8); |
12607 | 3.10k | if (segment >= (uint64_t{1} << shift)) { |
12608 | 60 | return is_valid = false; |
12609 | 60 | } |
12610 | 3.04k | ipv4 = (ipv4 << shift) | segment; |
12611 | 3.04k | goto ipv4_done; |
12612 | 3.10k | } |
12613 | 2.42k | if (segment > 255 || *p != '.') { |
12614 | 140 | return is_valid = false; |
12615 | 140 | } |
12616 | 2.28k | ipv4 = (ipv4 << 8) | segment; |
12617 | 2.28k | ++p; |
12618 | 2.28k | } |
12619 | 58 | if (digit_count != 4 || p != end) { |
12620 | 58 | return is_valid = false; |
12621 | 58 | } |
12622 | 3.04k | ipv4_done: |
12623 | 3.04k | ada_log("url_aggregator::parse_ipv4 completed ", get_href(), |
12624 | 3.04k | " host: ", get_host()); |
12625 | 3.04k | if (in_place && pure_decimal_count == 4 && !trailing_dot) { |
12626 | 0 | ada_log( |
12627 | 0 | "url_aggregator::parse_ipv4 completed and was already correct in the " |
12628 | 0 | "buffer"); |
12629 | 3.04k | } else { |
12630 | 3.04k | update_base_hostname(ada::serializers::ipv4(ipv4)); |
12631 | 3.04k | } |
12632 | 3.04k | host_type = IPV4; |
12633 | 3.04k | ADA_ASSERT_TRUE(validate()); |
12634 | 3.04k | return true; |
12635 | 58 | } |
12636 | | |
12637 | 2.05k | bool url_aggregator::parse_ipv6(std::string_view input) { |
12638 | 2.05k | ada_log("parse_ipv6 ", input, " [", input.size(), " bytes]"); |
12639 | 2.05k | ADA_ASSERT_TRUE(validate()); |
12640 | 2.05k | ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer)); |
12641 | 2.05k | if (input.empty() || input.size() > 45) [[unlikely]] { |
12642 | 106 | return is_valid = false; |
12643 | 106 | } |
12644 | | #if defined(ADA_AVX512) |
12645 | | if (!detail::ipv6_structure_plausible(input.data(), input.size())) |
12646 | | [[unlikely]] { |
12647 | | return is_valid = false; |
12648 | | } |
12649 | | #endif |
12650 | | |
12651 | 1.94k | std::array<uint16_t, 8> address{}; |
12652 | 1.94k | const char* pointer = input.data(); |
12653 | 1.94k | const char* const end = pointer + input.size(); |
12654 | 1.94k | int piece_index = 0; |
12655 | 1.94k | int compress = -1; |
12656 | | |
12657 | 1.94k | if (*pointer == ':') { |
12658 | 1.49k | if (input.size() == 1 || pointer[1] != ':') [[unlikely]] { |
12659 | 32 | return is_valid = false; |
12660 | 32 | } |
12661 | 1.46k | pointer += 2; |
12662 | 1.46k | compress = ++piece_index; |
12663 | 1.46k | } |
12664 | | |
12665 | 5.34k | while (pointer != end) { |
12666 | 3.78k | if (piece_index == 8) [[unlikely]] { |
12667 | 12 | return is_valid = false; |
12668 | 12 | } |
12669 | 3.77k | if (*pointer == ':') { |
12670 | 203 | if (compress != -1) [[unlikely]] { |
12671 | 10 | return is_valid = false; |
12672 | 10 | } |
12673 | 193 | ++pointer; |
12674 | 193 | compress = ++piece_index; |
12675 | 193 | continue; |
12676 | 203 | } |
12677 | | |
12678 | 3.57k | uint16_t value = 0; |
12679 | 3.57k | const int length = detail::parse_hex_piece(pointer, end, value); |
12680 | | |
12681 | 3.57k | if (pointer != end && *pointer == '.') { |
12682 | 202 | if (length == 0) [[unlikely]] { |
12683 | 15 | return is_valid = false; |
12684 | 15 | } |
12685 | 187 | pointer -= length; |
12686 | 187 | if (piece_index > 6) [[unlikely]] { |
12687 | 7 | return is_valid = false; |
12688 | 7 | } |
12689 | | |
12690 | 180 | int numbers_seen = 0; |
12691 | 517 | while (pointer != end) { |
12692 | 464 | int ipv4_piece = -1; |
12693 | 464 | if (numbers_seen > 0) { |
12694 | 284 | if (*pointer == '.' && numbers_seen < 4) { |
12695 | 244 | ++pointer; |
12696 | 244 | } else { |
12697 | 40 | return is_valid = false; |
12698 | 40 | } |
12699 | 284 | } |
12700 | 424 | if (pointer == end || *pointer < '0' || *pointer > '9') [[unlikely]] { |
12701 | 67 | return is_valid = false; |
12702 | 67 | } |
12703 | 357 | ipv4_piece = *pointer - '0'; |
12704 | 357 | ++pointer; |
12705 | 357 | if (pointer != end && *pointer >= '0' && *pointer <= '9') { |
12706 | 122 | if (ipv4_piece == 0) [[unlikely]] { |
12707 | 10 | return is_valid = false; |
12708 | 10 | } |
12709 | 112 | ipv4_piece = ipv4_piece * 10 + (*pointer - '0'); |
12710 | 112 | ++pointer; |
12711 | 112 | if (pointer != end && *pointer >= '0' && *pointer <= '9') { |
12712 | 52 | ipv4_piece = ipv4_piece * 10 + (*pointer - '0'); |
12713 | 52 | ++pointer; |
12714 | 52 | if (ipv4_piece > 255) [[unlikely]] { |
12715 | 10 | return is_valid = false; |
12716 | 10 | } |
12717 | 52 | } |
12718 | 112 | } |
12719 | 337 | address[static_cast<size_t>(piece_index)] = static_cast<uint16_t>( |
12720 | 337 | address[static_cast<size_t>(piece_index)] * 0x100 + |
12721 | 337 | static_cast<uint16_t>(ipv4_piece)); |
12722 | 337 | ++numbers_seen; |
12723 | 337 | if (numbers_seen == 2 || numbers_seen == 4) { |
12724 | 133 | ++piece_index; |
12725 | 133 | } |
12726 | 337 | } |
12727 | 53 | if (numbers_seen != 4) [[unlikely]] { |
12728 | 26 | return is_valid = false; |
12729 | 26 | } |
12730 | 27 | break; |
12731 | 53 | } |
12732 | | |
12733 | 3.36k | if (length == 0) [[unlikely]] { |
12734 | 97 | return is_valid = false; |
12735 | 97 | } |
12736 | | |
12737 | 3.27k | if (pointer != end && *pointer == ':') { |
12738 | 1.78k | ++pointer; |
12739 | 1.78k | if (pointer == end) [[unlikely]] { |
12740 | 12 | return is_valid = false; |
12741 | 12 | } |
12742 | 1.78k | } else if (pointer != end) [[unlikely]] { |
12743 | 24 | return is_valid = false; |
12744 | 24 | } |
12745 | | |
12746 | 3.23k | address[static_cast<size_t>(piece_index)] = value; |
12747 | 3.23k | ++piece_index; |
12748 | 3.23k | } |
12749 | | |
12750 | 1.58k | if (compress != -1) { |
12751 | 1.53k | const int right = piece_index - compress; |
12752 | 1.53k | if (right > 0) { |
12753 | 1.43k | const size_t dest = static_cast<size_t>(8 - right); |
12754 | 1.43k | const size_t src = static_cast<size_t>(compress); |
12755 | 1.43k | if (dest != src) { |
12756 | 3.51k | for (size_t i = static_cast<size_t>(right); i-- > 0;) { |
12757 | 2.14k | address[dest + i] = address[src + i]; |
12758 | 2.14k | address[src + i] = 0; |
12759 | 2.14k | } |
12760 | 1.36k | } |
12761 | 1.43k | } |
12762 | 1.53k | } else if (piece_index != 8) [[unlikely]] { |
12763 | 24 | return is_valid = false; |
12764 | 24 | } |
12765 | | |
12766 | | // Serialize once; skip rewrite when hostname is already canonical. |
12767 | 1.56k | const std::string serialized = ada::serializers::ipv6(address); |
12768 | 1.56k | const std::string_view current = get_hostname(); |
12769 | 1.56k | if (current.size() == serialized.size() && |
12770 | 84 | std::memcmp(current.data(), serialized.data(), serialized.size()) == 0) { |
12771 | 47 | ada_log("parse_ipv6 in-place canonical match"); |
12772 | 1.51k | } else { |
12773 | 1.51k | update_base_hostname(serialized); |
12774 | 1.51k | } |
12775 | 1.56k | ada_log("parse_ipv6 ", get_hostname()); |
12776 | 1.56k | ADA_ASSERT_TRUE(validate()); |
12777 | 1.56k | host_type = IPV6; |
12778 | 1.56k | return true; |
12779 | 1.58k | } |
12780 | | |
12781 | 2.03k | bool url_aggregator::parse_opaque_host(std::string_view input) { |
12782 | 2.03k | ada_log("parse_opaque_host ", input, " [", input.size(), " bytes]"); |
12783 | 2.03k | ADA_ASSERT_TRUE(validate()); |
12784 | 2.03k | ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer)); |
12785 | 2.03k | if (std::ranges::any_of(input, ada::unicode::is_forbidden_host_code_point)) { |
12786 | 131 | return is_valid = false; |
12787 | 131 | } |
12788 | | |
12789 | | // Return the result of running UTF-8 percent-encode on input using the C0 |
12790 | | // control percent-encode set. |
12791 | 1.90k | size_t idx = ada::unicode::percent_encode_index( |
12792 | 1.90k | input, character_sets::C0_CONTROL_PERCENT_ENCODE); |
12793 | 1.90k | if (idx == input.size()) { |
12794 | 1.27k | update_base_hostname(input); |
12795 | 1.27k | } else { |
12796 | | // We only create a temporary string if we need to. |
12797 | 630 | update_base_hostname(ada::unicode::percent_encode( |
12798 | 630 | input, character_sets::C0_CONTROL_PERCENT_ENCODE, idx)); |
12799 | 630 | } |
12800 | 1.90k | ADA_ASSERT_TRUE(validate()); |
12801 | 1.90k | return true; |
12802 | 2.03k | } |
12803 | | |
12804 | 0 | [[nodiscard]] std::string url_aggregator::to_diagram() const { |
12805 | 0 | if (!is_valid) { |
12806 | 0 | return "invalid"; |
12807 | 0 | } |
12808 | 0 | std::string answer; |
12809 | 0 | answer.append(buffer); |
12810 | 0 | answer.append(" ["); |
12811 | 0 | answer.append(std::to_string(buffer.size())); |
12812 | 0 | answer.append(" bytes]"); |
12813 | 0 | answer.append("\n"); |
12814 | | // first line |
12815 | 0 | std::string line1; |
12816 | 0 | line1.resize(buffer.size(), ' '); |
12817 | 0 | if (components.hash_start != url_components::omitted) { |
12818 | 0 | line1[components.hash_start] = '|'; |
12819 | 0 | } |
12820 | 0 | if (components.search_start != url_components::omitted) { |
12821 | 0 | line1[components.search_start] = '|'; |
12822 | 0 | } |
12823 | 0 | if (components.pathname_start != buffer.size()) { |
12824 | 0 | line1[components.pathname_start] = '|'; |
12825 | 0 | } |
12826 | 0 | if (components.host_end != buffer.size()) { |
12827 | 0 | line1[components.host_end] = '|'; |
12828 | 0 | } |
12829 | 0 | if (components.host_start != buffer.size()) { |
12830 | 0 | line1[components.host_start] = '|'; |
12831 | 0 | } |
12832 | 0 | if (components.username_end != buffer.size()) { |
12833 | 0 | line1[components.username_end] = '|'; |
12834 | 0 | } |
12835 | 0 | if (components.protocol_end != buffer.size()) { |
12836 | 0 | line1[components.protocol_end] = '|'; |
12837 | 0 | } |
12838 | 0 | answer.append(line1); |
12839 | 0 | answer.append("\n"); |
12840 | |
|
12841 | 0 | std::string line2 = line1; |
12842 | 0 | if (components.hash_start != url_components::omitted) { |
12843 | 0 | line2[components.hash_start] = '`'; |
12844 | 0 | line1[components.hash_start] = ' '; |
12845 | |
|
12846 | 0 | for (size_t i = components.hash_start + 1; i < line2.size(); i++) { |
12847 | 0 | line2[i] = '-'; |
12848 | 0 | } |
12849 | 0 | line2.append(" hash_start"); |
12850 | 0 | answer.append(line2); |
12851 | 0 | answer.append("\n"); |
12852 | 0 | } |
12853 | |
|
12854 | 0 | std::string line3 = line1; |
12855 | 0 | if (components.search_start != url_components::omitted) { |
12856 | 0 | line3[components.search_start] = '`'; |
12857 | 0 | line1[components.search_start] = ' '; |
12858 | |
|
12859 | 0 | for (size_t i = components.search_start + 1; i < line3.size(); i++) { |
12860 | 0 | line3[i] = '-'; |
12861 | 0 | } |
12862 | 0 | line3.append(" search_start "); |
12863 | 0 | line3.append(std::to_string(components.search_start)); |
12864 | 0 | answer.append(line3); |
12865 | 0 | answer.append("\n"); |
12866 | 0 | } |
12867 | |
|
12868 | 0 | std::string line4 = line1; |
12869 | 0 | if (components.pathname_start != buffer.size()) { |
12870 | 0 | line4[components.pathname_start] = '`'; |
12871 | 0 | line1[components.pathname_start] = ' '; |
12872 | 0 | for (size_t i = components.pathname_start + 1; i < line4.size(); i++) { |
12873 | 0 | line4[i] = '-'; |
12874 | 0 | } |
12875 | 0 | line4.append(" pathname_start "); |
12876 | 0 | line4.append(std::to_string(components.pathname_start)); |
12877 | 0 | answer.append(line4); |
12878 | 0 | answer.append("\n"); |
12879 | 0 | } |
12880 | |
|
12881 | 0 | std::string line5 = line1; |
12882 | 0 | if (components.host_end != buffer.size()) { |
12883 | 0 | line5[components.host_end] = '`'; |
12884 | 0 | line1[components.host_end] = ' '; |
12885 | |
|
12886 | 0 | for (size_t i = components.host_end + 1; i < line5.size(); i++) { |
12887 | 0 | line5[i] = '-'; |
12888 | 0 | } |
12889 | 0 | line5.append(" host_end "); |
12890 | 0 | line5.append(std::to_string(components.host_end)); |
12891 | 0 | answer.append(line5); |
12892 | 0 | answer.append("\n"); |
12893 | 0 | } |
12894 | |
|
12895 | 0 | std::string line6 = line1; |
12896 | 0 | if (components.host_start != buffer.size()) { |
12897 | 0 | line6[components.host_start] = '`'; |
12898 | 0 | line1[components.host_start] = ' '; |
12899 | |
|
12900 | 0 | for (size_t i = components.host_start + 1; i < line6.size(); i++) { |
12901 | 0 | line6[i] = '-'; |
12902 | 0 | } |
12903 | 0 | line6.append(" host_start "); |
12904 | 0 | line6.append(std::to_string(components.host_start)); |
12905 | 0 | answer.append(line6); |
12906 | 0 | answer.append("\n"); |
12907 | 0 | } |
12908 | |
|
12909 | 0 | std::string line7 = line1; |
12910 | 0 | if (components.username_end != buffer.size()) { |
12911 | 0 | line7[components.username_end] = '`'; |
12912 | 0 | line1[components.username_end] = ' '; |
12913 | |
|
12914 | 0 | for (size_t i = components.username_end + 1; i < line7.size(); i++) { |
12915 | 0 | line7[i] = '-'; |
12916 | 0 | } |
12917 | 0 | line7.append(" username_end "); |
12918 | 0 | line7.append(std::to_string(components.username_end)); |
12919 | 0 | answer.append(line7); |
12920 | 0 | answer.append("\n"); |
12921 | 0 | } |
12922 | |
|
12923 | 0 | std::string line8 = line1; |
12924 | 0 | if (components.protocol_end != buffer.size()) { |
12925 | 0 | line8[components.protocol_end] = '`'; |
12926 | 0 | line1[components.protocol_end] = ' '; |
12927 | |
|
12928 | 0 | for (size_t i = components.protocol_end + 1; i < line8.size(); i++) { |
12929 | 0 | line8[i] = '-'; |
12930 | 0 | } |
12931 | 0 | line8.append(" protocol_end "); |
12932 | 0 | line8.append(std::to_string(components.protocol_end)); |
12933 | 0 | answer.append(line8); |
12934 | 0 | answer.append("\n"); |
12935 | 0 | } |
12936 | |
|
12937 | 0 | if (components.hash_start == url_components::omitted) { |
12938 | 0 | answer.append("note: hash omitted\n"); |
12939 | 0 | } |
12940 | 0 | if (components.search_start == url_components::omitted) { |
12941 | 0 | answer.append("note: search omitted\n"); |
12942 | 0 | } |
12943 | 0 | if (components.protocol_end > buffer.size()) { |
12944 | 0 | answer.append("warning: protocol_end overflows\n"); |
12945 | 0 | } |
12946 | 0 | if (components.username_end > buffer.size()) { |
12947 | 0 | answer.append("warning: username_end overflows\n"); |
12948 | 0 | } |
12949 | 0 | if (components.host_start > buffer.size()) { |
12950 | 0 | answer.append("warning: host_start overflows\n"); |
12951 | 0 | } |
12952 | 0 | if (components.host_end > buffer.size()) { |
12953 | 0 | answer.append("warning: host_end overflows\n"); |
12954 | 0 | } |
12955 | 0 | if (components.pathname_start > buffer.size()) { |
12956 | 0 | answer.append("warning: pathname_start overflows\n"); |
12957 | 0 | } |
12958 | 0 | return answer; |
12959 | 0 | } |
12960 | | |
12961 | 48 | void url_aggregator::delete_dash_dot() { |
12962 | 48 | ada_log("url_aggregator::delete_dash_dot"); |
12963 | 48 | ADA_ASSERT_TRUE(validate()); |
12964 | 48 | ADA_ASSERT_TRUE(has_dash_dot()); |
12965 | 48 | buffer.erase(components.host_end, 2); |
12966 | 48 | components.pathname_start -= 2; |
12967 | 48 | if (components.search_start != url_components::omitted) { |
12968 | 16 | components.search_start -= 2; |
12969 | 16 | } |
12970 | 48 | if (components.hash_start != url_components::omitted) { |
12971 | 14 | components.hash_start -= 2; |
12972 | 14 | } |
12973 | 48 | ADA_ASSERT_TRUE(validate()); |
12974 | 48 | ADA_ASSERT_TRUE(!has_dash_dot()); |
12975 | 48 | } |
12976 | | |
12977 | 170k | inline void url_aggregator::consume_prepared_path(std::string_view input) { |
12978 | 170k | ada_log("url_aggregator::consume_prepared_path ", input); |
12979 | | /*** |
12980 | | * This is largely duplicated code from helpers::parse_prepared_path, which is |
12981 | | * unfortunate. This particular function is nearly identical, except that it |
12982 | | * is a method on url_aggregator. The idea is that the trivial path (which is |
12983 | | * very common) merely appends to the buffer. This is the same trivial path as |
12984 | | * with helpers::parse_prepared_path, except that we have the additional check |
12985 | | * for is_at_path(). Otherwise, we grab a copy of the current path and we |
12986 | | * modify it, and then insert it back into the buffer. |
12987 | | */ |
12988 | 170k | uint8_t accumulator = checkers::path_signature(input); |
12989 | | // Let us first detect a trivial case. |
12990 | | // If it is special, we check that we have no dot, no %, no \ and no |
12991 | | // character needing percent encoding. Otherwise, we check that we have no %, |
12992 | | // no dot, and no character needing percent encoding. |
12993 | 170k | constexpr uint8_t need_encoding = 1; |
12994 | 170k | constexpr uint8_t backslash_char = 2; |
12995 | 170k | constexpr uint8_t dot_char = 4; |
12996 | 170k | constexpr uint8_t percent_char = 8; |
12997 | 170k | bool special = type != ada::scheme::NOT_SPECIAL; |
12998 | 170k | bool may_need_slow_file_handling = (type == ada::scheme::type::FILE && |
12999 | 47.7k | checkers::is_windows_drive_letter(input)); |
13000 | 170k | bool trivial_path = |
13001 | 170k | (special ? (accumulator == 0) |
13002 | 170k | : ((accumulator & (need_encoding | dot_char | percent_char)) == |
13003 | 2.51k | 0)) && |
13004 | 161k | (!may_need_slow_file_handling); |
13005 | 170k | if (accumulator == dot_char && !may_need_slow_file_handling) { |
13006 | | // '4' means that we have at least one dot, but nothing that requires |
13007 | | // percent encoding or decoding. The only part that is not trivial is |
13008 | | // that we may have single dots and double dots path segments. |
13009 | | // If we have such segments, then we either have a path that begins |
13010 | | // with '.' (easy to check), or we have the sequence './'. |
13011 | | // Note: input cannot be empty, it must at least contain one character ('.') |
13012 | | // Note: we know that '\' is not present. |
13013 | 4.69k | if (input[0] != '.') { |
13014 | 4.22k | size_t slashdot = 0; |
13015 | 4.22k | bool dot_is_file = true; |
13016 | 8.02k | for (;;) { |
13017 | 8.02k | slashdot = input.find("/.", slashdot); |
13018 | 8.02k | if (slashdot == std::string_view::npos) { // common case |
13019 | 4.22k | break; |
13020 | 4.22k | } else { // uncommon |
13021 | | // only three cases matter: /./, /.. or a final / |
13022 | 3.80k | slashdot += 2; |
13023 | 3.80k | dot_is_file &= !(slashdot == input.size() || input[slashdot] == '.' || |
13024 | 1.22k | input[slashdot] == '/'); |
13025 | 3.80k | } |
13026 | 8.02k | } |
13027 | 4.22k | trivial_path = dot_is_file; |
13028 | 4.22k | } |
13029 | 4.69k | } |
13030 | 170k | if (trivial_path && is_at_path()) { |
13031 | 152k | ada_log("parse_path trivial"); |
13032 | 152k | buffer += '/'; |
13033 | 152k | buffer += input; |
13034 | 152k | return; |
13035 | 152k | } |
13036 | 17.9k | std::string path = std::string(get_pathname()); |
13037 | | // We are going to need to look a bit at the path, but let us see if we can |
13038 | | // ignore percent encoding *and* backslashes *and* percent characters. |
13039 | | // Except for the trivial case, this is likely to capture 99% of paths out |
13040 | | // there. |
13041 | 17.9k | bool fast_path = |
13042 | 17.9k | (special && |
13043 | 16.5k | (accumulator & (need_encoding | backslash_char | percent_char)) == 0) && |
13044 | 13.3k | (type != ada::scheme::type::FILE); |
13045 | 17.9k | if (fast_path) { |
13046 | 12.6k | ada_log("parse_prepared_path fast"); |
13047 | | // Here we don't need to worry about \ or percent encoding. |
13048 | | // We also do not have a file protocol. We might have dots, however, |
13049 | | // but dots must as appear as '.', and they cannot be encoded because |
13050 | | // the symbol '%' is not present. |
13051 | 12.6k | size_t previous_location = 0; // We start at 0. |
13052 | 22.0k | do { |
13053 | 22.0k | size_t new_location = input.find('/', previous_location); |
13054 | | // std::string_view path_view = input; |
13055 | | // We process the last segment separately: |
13056 | 22.0k | if (new_location == std::string_view::npos) { |
13057 | 12.6k | std::string_view path_view = input.substr(previous_location); |
13058 | 12.6k | if (path_view == "..") { // The path ends with .. |
13059 | | // e.g., if you receive ".." with an empty path, you go to "/". |
13060 | 113 | if (path.empty()) { |
13061 | 36 | path = '/'; |
13062 | 36 | update_base_pathname(path); |
13063 | 36 | return; |
13064 | 36 | } |
13065 | | // Fast case where we have nothing to do: |
13066 | 77 | if (path.back() == '/') { |
13067 | 23 | update_base_pathname(path); |
13068 | 23 | return; |
13069 | 23 | } |
13070 | | // If you have the path "/joe/myfriend", |
13071 | | // then you delete 'myfriend'. |
13072 | 54 | path.resize(path.rfind('/') + 1); |
13073 | 54 | update_base_pathname(path); |
13074 | 54 | return; |
13075 | 77 | } |
13076 | 12.5k | path += '/'; |
13077 | 12.5k | if (path_view != ".") { |
13078 | 12.5k | path.append(path_view); |
13079 | 12.5k | } |
13080 | 12.5k | update_base_pathname(path); |
13081 | 12.5k | return; |
13082 | 12.6k | } else { |
13083 | | // This is a non-final segment. |
13084 | 9.34k | std::string_view path_view = |
13085 | 9.34k | input.substr(previous_location, new_location - previous_location); |
13086 | 9.34k | previous_location = new_location + 1; |
13087 | 9.34k | if (path_view == "..") { |
13088 | 1.64k | size_t last_delimiter = path.rfind('/'); |
13089 | 1.64k | if (last_delimiter != std::string::npos) { |
13090 | 1.19k | path.erase(last_delimiter); |
13091 | 1.19k | } |
13092 | 7.69k | } else if (path_view != ".") { |
13093 | 6.84k | path += '/'; |
13094 | 6.84k | path.append(path_view); |
13095 | 6.84k | } |
13096 | 9.34k | } |
13097 | 22.0k | } while (true); |
13098 | 12.6k | } else { |
13099 | 5.24k | ada_log("parse_path slow"); |
13100 | | // we have reached the general case |
13101 | 5.24k | bool needs_percent_encoding = (accumulator & 1); |
13102 | 5.24k | std::string path_buffer_tmp; |
13103 | 21.4k | do { |
13104 | 21.4k | size_t location = (special && (accumulator & 2)) |
13105 | 21.4k | ? input.find_first_of("/\\") |
13106 | 21.4k | : input.find('/'); |
13107 | 21.4k | std::string_view path_view = input; |
13108 | 21.4k | if (location != std::string_view::npos) { |
13109 | 16.1k | path_view.remove_suffix(path_view.size() - location); |
13110 | 16.1k | input.remove_prefix(location + 1); |
13111 | 16.1k | } |
13112 | | // path_buffer is either path_view or it might point at a percent encoded |
13113 | | // temporary string. |
13114 | 21.4k | std::string_view path_buffer = |
13115 | 21.4k | (needs_percent_encoding && |
13116 | 10.5k | ada::unicode::percent_encode<false>( |
13117 | 10.5k | path_view, character_sets::PATH_PERCENT_ENCODE, path_buffer_tmp)) |
13118 | 21.4k | ? path_buffer_tmp |
13119 | 21.4k | : path_view; |
13120 | 21.4k | if (unicode::is_double_dot_path_segment(path_buffer)) { |
13121 | 3.86k | helpers::shorten_path(path, type); |
13122 | 3.86k | if (location == std::string_view::npos) { |
13123 | 702 | path += '/'; |
13124 | 702 | } |
13125 | 17.5k | } else if (unicode::is_single_dot_path_segment(path_buffer) && |
13126 | 1.37k | (location == std::string_view::npos)) { |
13127 | 112 | path += '/'; |
13128 | 112 | } |
13129 | | // Otherwise, if path_buffer is not a single-dot path segment, then: |
13130 | 17.4k | else if (!unicode::is_single_dot_path_segment(path_buffer)) { |
13131 | | // If url's scheme is "file", url's path is empty, and path_buffer is a |
13132 | | // Windows drive letter, then replace the second code point in |
13133 | | // path_buffer with U+003A (:). |
13134 | 16.1k | if (type == ada::scheme::type::FILE && path.empty() && |
13135 | 2.70k | checkers::is_windows_drive_letter(path_buffer)) { |
13136 | 175 | path += '/'; |
13137 | 175 | path += path_buffer[0]; |
13138 | 175 | path += ':'; |
13139 | 175 | path_buffer.remove_prefix(2); |
13140 | 175 | path.append(path_buffer); |
13141 | 15.9k | } else { |
13142 | | // Append path_buffer to url's path. |
13143 | 15.9k | path += '/'; |
13144 | 15.9k | path.append(path_buffer); |
13145 | 15.9k | } |
13146 | 16.1k | } |
13147 | 21.4k | if (location == std::string_view::npos) { |
13148 | 5.24k | update_base_pathname(path); |
13149 | 5.24k | return; |
13150 | 5.24k | } |
13151 | 21.4k | } while (true); |
13152 | 5.24k | } |
13153 | 17.9k | } |
13154 | | } // namespace ada |
13155 | | /* end file src/url_aggregator.cpp */ |
13156 | | |
13157 | | #if ADA_INCLUDE_URL_PATTERN |
13158 | | /* begin file src/url_pattern.cpp */ |
13159 | | #if ADA_INCLUDE_URL_PATTERN |
13160 | | |
13161 | | |
13162 | | #include <algorithm> |
13163 | | #include <optional> |
13164 | | #include <string> |
13165 | | |
13166 | | namespace ada { |
13167 | | |
13168 | | tl::expected<url_pattern_init, errors> url_pattern_init::process( |
13169 | | const url_pattern_init& init, url_pattern_init::process_type type, |
13170 | | std::optional<std::string_view> protocol, |
13171 | | std::optional<std::string_view> username, |
13172 | | std::optional<std::string_view> password, |
13173 | | std::optional<std::string_view> hostname, |
13174 | | std::optional<std::string_view> port, |
13175 | | std::optional<std::string_view> pathname, |
13176 | | std::optional<std::string_view> search, |
13177 | 0 | std::optional<std::string_view> hash) { |
13178 | | // Let result be the result of creating a new URLPatternInit. |
13179 | 0 | auto result = url_pattern_init{}; |
13180 | | |
13181 | | // If protocol is not null, set result["protocol"] to protocol. |
13182 | 0 | if (protocol.has_value()) result.protocol = *protocol; |
13183 | | |
13184 | | // If username is not null, set result["username"] to username. |
13185 | 0 | if (username.has_value()) result.username = *username; |
13186 | | |
13187 | | // If password is not null, set result["password"] to password. |
13188 | 0 | if (password.has_value()) result.password = *password; |
13189 | | |
13190 | | // If hostname is not null, set result["hostname"] to hostname. |
13191 | 0 | if (hostname.has_value()) result.hostname = *hostname; |
13192 | | |
13193 | | // If port is not null, set result["port"] to port. |
13194 | 0 | if (port.has_value()) result.port = *port; |
13195 | | |
13196 | | // If pathname is not null, set result["pathname"] to pathname. |
13197 | 0 | if (pathname.has_value()) result.pathname = *pathname; |
13198 | | |
13199 | | // If search is not null, set result["search"] to search. |
13200 | 0 | if (search.has_value()) result.search = *search; |
13201 | | |
13202 | | // If hash is not null, set result["hash"] to hash. |
13203 | 0 | if (hash.has_value()) result.hash = *hash; |
13204 | | |
13205 | | // Let baseURL be null. |
13206 | 0 | std::optional<url_aggregator> base_url{}; |
13207 | | |
13208 | | // If init["baseURL"] exists: |
13209 | 0 | if (init.base_url.has_value()) { |
13210 | | // Set baseURL to the result of parsing init["baseURL"]. |
13211 | 0 | auto parsing_result = ada::parse<url_aggregator>(*init.base_url); |
13212 | | // If baseURL is failure, then throw a TypeError. |
13213 | 0 | if (!parsing_result) { |
13214 | 0 | return tl::unexpected(errors::type_error); |
13215 | 0 | } |
13216 | 0 | base_url = std::move(*parsing_result); |
13217 | | |
13218 | | // If init["protocol"] does not exist, then set result["protocol"] to the |
13219 | | // result of processing a base URL string given baseURL's scheme and type. |
13220 | 0 | if (!init.protocol.has_value()) { |
13221 | 0 | ADA_ASSERT_TRUE(base_url.has_value()); |
13222 | 0 | std::string_view base_url_protocol = base_url->get_protocol(); |
13223 | 0 | if (base_url_protocol.ends_with(":")) base_url_protocol.remove_suffix(1); |
13224 | 0 | result.protocol = |
13225 | 0 | url_pattern_helpers::process_base_url_string(base_url_protocol, type); |
13226 | 0 | } |
13227 | | |
13228 | | // If type is not "pattern" and init contains none of "protocol", |
13229 | | // "hostname", "port" and "username", then set result["username"] to the |
13230 | | // result of processing a base URL string given baseURL's username and type. |
13231 | 0 | if (type != process_type::pattern && !init.protocol && !init.hostname && |
13232 | 0 | !init.port && !init.username) { |
13233 | 0 | result.username = url_pattern_helpers::process_base_url_string( |
13234 | 0 | base_url->get_username(), type); |
13235 | 0 | } |
13236 | | |
13237 | | // TODO: Optimization opportunity: Merge this with the previous check. |
13238 | | // If type is not "pattern" and init contains none of "protocol", |
13239 | | // "hostname", "port", "username" and "password", then set |
13240 | | // result["password"] to the result of processing a base URL string given |
13241 | | // baseURL's password and type. |
13242 | 0 | if (type != process_type::pattern && !init.protocol && !init.hostname && |
13243 | 0 | !init.port && !init.username && !init.password) { |
13244 | 0 | result.password = url_pattern_helpers::process_base_url_string( |
13245 | 0 | base_url->get_password(), type); |
13246 | 0 | } |
13247 | | |
13248 | | // If init contains neither "protocol" nor "hostname", then: |
13249 | 0 | if (!init.protocol && !init.hostname) { |
13250 | | // Let baseHost be baseURL's host. |
13251 | | // If baseHost is null, then set baseHost to the empty string. |
13252 | 0 | auto base_host = base_url->get_hostname(); |
13253 | | // Set result["hostname"] to the result of processing a base URL string |
13254 | | // given baseHost and type. |
13255 | 0 | result.hostname = |
13256 | 0 | url_pattern_helpers::process_base_url_string(base_host, type); |
13257 | 0 | } |
13258 | | |
13259 | | // If init contains none of "protocol", "hostname", and "port", then: |
13260 | 0 | if (!init.protocol && !init.hostname && !init.port) { |
13261 | | // If baseURL's port is null, then set result["port"] to the empty string. |
13262 | | // Otherwise, set result["port"] to baseURL's port, serialized. |
13263 | 0 | result.port = base_url->get_port(); |
13264 | 0 | } |
13265 | | |
13266 | | // If init contains none of "protocol", "hostname", "port", and "pathname", |
13267 | | // then set result["pathname"] to the result of processing a base URL string |
13268 | | // given the result of URL path serializing baseURL and type. |
13269 | 0 | if (!init.protocol && !init.hostname && !init.port && !init.pathname) { |
13270 | 0 | result.pathname = url_pattern_helpers::process_base_url_string( |
13271 | 0 | base_url->get_pathname(), type); |
13272 | 0 | } |
13273 | | |
13274 | | // If init contains none of "protocol", "hostname", "port", "pathname", and |
13275 | | // "search", then: |
13276 | 0 | if (!init.protocol && !init.hostname && !init.port && !init.pathname && |
13277 | 0 | !init.search) { |
13278 | | // Let baseQuery be baseURL's query. get_search() carries the leading "?" |
13279 | | // delimiter, but the spec inherits the query itself, so drop it. |
13280 | 0 | std::string_view base_query = base_url->get_search(); |
13281 | 0 | if (base_query.starts_with("?")) base_query.remove_prefix(1); |
13282 | | // Set result["search"] to the result of processing a base URL string |
13283 | | // given baseQuery and type. |
13284 | 0 | result.search = |
13285 | 0 | url_pattern_helpers::process_base_url_string(base_query, type); |
13286 | 0 | } |
13287 | | |
13288 | | // If init contains none of "protocol", "hostname", "port", "pathname", |
13289 | | // "search", and "hash", then: |
13290 | 0 | if (!init.protocol && !init.hostname && !init.port && !init.pathname && |
13291 | 0 | !init.search && !init.hash) { |
13292 | | // Let baseFragment be baseURL's fragment. get_hash() carries the leading |
13293 | | // "#" delimiter, but the spec inherits the fragment itself, so drop it. |
13294 | 0 | std::string_view base_fragment = base_url->get_hash(); |
13295 | 0 | if (base_fragment.starts_with("#")) base_fragment.remove_prefix(1); |
13296 | | // Set result["hash"] to the result of processing a base URL string given |
13297 | | // baseFragment and type. |
13298 | 0 | result.hash = |
13299 | 0 | url_pattern_helpers::process_base_url_string(base_fragment, type); |
13300 | 0 | } |
13301 | 0 | } |
13302 | | |
13303 | | // If init["protocol"] exists, then set result["protocol"] to the result of |
13304 | | // process protocol for init given init["protocol"] and type. |
13305 | 0 | if (init.protocol) { |
13306 | 0 | auto process_result = process_protocol(*init.protocol, type); |
13307 | 0 | if (!process_result) { |
13308 | 0 | return tl::unexpected(process_result.error()); |
13309 | 0 | } |
13310 | 0 | result.protocol = std::move(*process_result); |
13311 | 0 | } |
13312 | | |
13313 | | // If init["username"] exists, then set result["username"] to the result of |
13314 | | // process username for init given init["username"] and type. |
13315 | 0 | if (init.username.has_value()) { |
13316 | 0 | auto process_result = process_username(*init.username, type); |
13317 | 0 | if (!process_result) { |
13318 | 0 | return tl::unexpected(process_result.error()); |
13319 | 0 | } |
13320 | 0 | result.username = std::move(*process_result); |
13321 | 0 | } |
13322 | | |
13323 | | // If init["password"] exists, then set result["password"] to the result of |
13324 | | // process password for init given init["password"] and type. |
13325 | 0 | if (init.password.has_value()) { |
13326 | 0 | auto process_result = process_password(*init.password, type); |
13327 | 0 | if (!process_result) { |
13328 | 0 | return tl::unexpected(process_result.error()); |
13329 | 0 | } |
13330 | 0 | result.password = std::move(*process_result); |
13331 | 0 | } |
13332 | | |
13333 | | // If init["hostname"] exists, then set result["hostname"] to the result of |
13334 | | // process hostname for init given init["hostname"] and type. |
13335 | 0 | if (init.hostname.has_value()) { |
13336 | 0 | auto process_result = process_hostname(*init.hostname, type); |
13337 | 0 | if (!process_result) { |
13338 | 0 | return tl::unexpected(process_result.error()); |
13339 | 0 | } |
13340 | 0 | result.hostname = std::move(*process_result); |
13341 | 0 | } |
13342 | | |
13343 | | // If init["port"] exists, then set result["port"] to the result of process |
13344 | | // port for init given init["port"], result["protocol"], and type. |
13345 | 0 | if (init.port) { |
13346 | 0 | auto process_result = |
13347 | 0 | process_port(*init.port, result.protocol.value_or("fake"), type); |
13348 | 0 | if (!process_result) { |
13349 | 0 | return tl::unexpected(process_result.error()); |
13350 | 0 | } |
13351 | 0 | result.port = std::move(*process_result); |
13352 | 0 | } |
13353 | | |
13354 | | // If init["pathname"] exists: |
13355 | 0 | if (init.pathname.has_value()) { |
13356 | | // Set result["pathname"] to init["pathname"]. |
13357 | 0 | result.pathname = init.pathname; |
13358 | | |
13359 | | // If the following are all true: |
13360 | | // - baseURL is not null; |
13361 | | // - baseURL has an opaque path; and |
13362 | | // - the result of running is an absolute pathname given result["pathname"] |
13363 | | // and type is false, |
13364 | 0 | if (base_url && !base_url->has_opaque_path && |
13365 | 0 | !url_pattern_helpers::is_absolute_pathname(*result.pathname, type)) { |
13366 | | // Let baseURLPath be the result of running process a base URL string |
13367 | | // given the result of URL path serializing baseURL and type. |
13368 | | // TODO: Optimization opportunity: Avoid returning a string if no slash |
13369 | | // exist. |
13370 | 0 | std::string base_url_path = url_pattern_helpers::process_base_url_string( |
13371 | 0 | base_url->get_pathname(), type); |
13372 | | |
13373 | | // Let slash index be the index of the last U+002F (/) code point found in |
13374 | | // baseURLPath, interpreted as a sequence of code points, or null if there |
13375 | | // are no instances of the code point. |
13376 | 0 | auto slash_index = base_url_path.find_last_of('/'); |
13377 | | |
13378 | | // If slash index is not null: |
13379 | 0 | if (slash_index != std::string::npos) { |
13380 | | // Let new pathname be the code point substring from 0 to slash index + |
13381 | | // 1 within baseURLPath. |
13382 | 0 | base_url_path.resize(slash_index + 1); |
13383 | | // Append result["pathname"] to the end of new pathname. |
13384 | 0 | ADA_ASSERT_TRUE(result.pathname.has_value()); |
13385 | 0 | base_url_path.append(std::move(*result.pathname)); |
13386 | | // Set result["pathname"] to new pathname. |
13387 | 0 | result.pathname = std::move(base_url_path); |
13388 | 0 | } |
13389 | 0 | } |
13390 | | |
13391 | | // Set result["pathname"] to the result of process pathname for init given |
13392 | | // result["pathname"], result["protocol"], and type. |
13393 | 0 | auto pathname_processing_result = |
13394 | 0 | process_pathname(*result.pathname, result.protocol.value_or(""), type); |
13395 | 0 | if (!pathname_processing_result) { |
13396 | 0 | return tl::unexpected(pathname_processing_result.error()); |
13397 | 0 | } |
13398 | 0 | result.pathname = std::move(*pathname_processing_result); |
13399 | 0 | } |
13400 | | |
13401 | | // If init["search"] exists then set result["search"] to the result of process |
13402 | | // search for init given init["search"] and type. |
13403 | 0 | if (init.search) { |
13404 | 0 | auto process_result = process_search(*init.search, type); |
13405 | 0 | if (!process_result) { |
13406 | 0 | return tl::unexpected(process_result.error()); |
13407 | 0 | } |
13408 | 0 | result.search = std::move(*process_result); |
13409 | 0 | } |
13410 | | |
13411 | | // If init["hash"] exists then set result["hash"] to the result of process |
13412 | | // hash for init given init["hash"] and type. |
13413 | 0 | if (init.hash) { |
13414 | 0 | auto process_result = process_hash(*init.hash, type); |
13415 | 0 | if (!process_result) { |
13416 | 0 | return tl::unexpected(process_result.error()); |
13417 | 0 | } |
13418 | 0 | result.hash = std::move(*process_result); |
13419 | 0 | } |
13420 | | // Return result. |
13421 | 0 | return result; |
13422 | 0 | } |
13423 | | |
13424 | | tl::expected<std::string, errors> url_pattern_init::process_protocol( |
13425 | 0 | std::string_view value, process_type type) { |
13426 | 0 | ada_log("process_protocol=", value, " [", type, "]"); |
13427 | | // Let strippedValue be the given value with a single trailing U+003A (:) |
13428 | | // removed, if any. |
13429 | 0 | if (value.ends_with(":")) { |
13430 | 0 | value.remove_suffix(1); |
13431 | 0 | } |
13432 | | // If type is "pattern" then return strippedValue. |
13433 | 0 | if (type == process_type::pattern) { |
13434 | 0 | return std::string(value); |
13435 | 0 | } |
13436 | | // Return the result of running canonicalize a protocol given strippedValue. |
13437 | 0 | return url_pattern_helpers::canonicalize_protocol(value); |
13438 | 0 | } |
13439 | | |
13440 | | tl::expected<std::string, errors> url_pattern_init::process_username( |
13441 | 0 | std::string_view value, process_type type) { |
13442 | | // If type is "pattern" then return value. |
13443 | 0 | if (type == process_type::pattern) { |
13444 | 0 | return std::string(value); |
13445 | 0 | } |
13446 | | // Return the result of running canonicalize a username given value. |
13447 | 0 | return url_pattern_helpers::canonicalize_username(value); |
13448 | 0 | } |
13449 | | |
13450 | | tl::expected<std::string, errors> url_pattern_init::process_password( |
13451 | 0 | std::string_view value, process_type type) { |
13452 | | // If type is "pattern" then return value. |
13453 | 0 | if (type == process_type::pattern) { |
13454 | 0 | return std::string(value); |
13455 | 0 | } |
13456 | | // Return the result of running canonicalize a password given value. |
13457 | 0 | return url_pattern_helpers::canonicalize_password(value); |
13458 | 0 | } |
13459 | | |
13460 | | tl::expected<std::string, errors> url_pattern_init::process_hostname( |
13461 | 0 | std::string_view value, process_type type) { |
13462 | 0 | ada_log("process_hostname value=", value, " type=", type); |
13463 | | // If type is "pattern" then return value. |
13464 | 0 | if (type == process_type::pattern) { |
13465 | 0 | return std::string(value); |
13466 | 0 | } |
13467 | | // Return the result of running canonicalize a hostname given value. |
13468 | 0 | return url_pattern_helpers::canonicalize_hostname(value); |
13469 | 0 | } |
13470 | | |
13471 | | tl::expected<std::string, errors> url_pattern_init::process_port( |
13472 | 0 | std::string_view port, std::string_view protocol, process_type type) { |
13473 | | // If type is "pattern" then return portValue. |
13474 | 0 | if (type == process_type::pattern) { |
13475 | 0 | return std::string(port); |
13476 | 0 | } |
13477 | | // Return the result of running canonicalize a port given portValue and |
13478 | | // protocolValue. |
13479 | 0 | return url_pattern_helpers::canonicalize_port_with_protocol(port, protocol); |
13480 | 0 | } |
13481 | | |
13482 | | tl::expected<std::string, errors> url_pattern_init::process_pathname( |
13483 | 0 | std::string_view value, std::string_view protocol, process_type type) { |
13484 | | // If type is "pattern" then return pathnameValue. |
13485 | 0 | if (type == process_type::pattern) { |
13486 | 0 | return std::string(value); |
13487 | 0 | } |
13488 | | |
13489 | | // If protocolValue is a special scheme or the empty string, then return the |
13490 | | // result of running canonicalize a pathname given pathnameValue. |
13491 | 0 | if (protocol.empty() || scheme::is_special(protocol)) { |
13492 | 0 | return url_pattern_helpers::canonicalize_pathname(value); |
13493 | 0 | } |
13494 | | |
13495 | | // Return the result of running canonicalize an opaque pathname given |
13496 | | // pathnameValue. |
13497 | 0 | return url_pattern_helpers::canonicalize_opaque_pathname(value); |
13498 | 0 | } |
13499 | | |
13500 | | tl::expected<std::string, errors> url_pattern_init::process_search( |
13501 | 0 | std::string_view value, process_type type) { |
13502 | | // Let strippedValue be the given value with a single leading U+003F (?) |
13503 | | // removed, if any. |
13504 | 0 | if (value.starts_with("?")) { |
13505 | 0 | value.remove_prefix(1); |
13506 | 0 | } |
13507 | | // We cannot assert that the value is no longer starting with a single |
13508 | | // question mark because technically it can start. The question is whether or |
13509 | | // not we should remove the first question mark. Ref: |
13510 | | // https://github.com/ada-url/ada/pull/992 The spec is not clear on this. |
13511 | | |
13512 | | // If type is "pattern" then return strippedValue. |
13513 | 0 | if (type == process_type::pattern) { |
13514 | 0 | return std::string(value); |
13515 | 0 | } |
13516 | | // Return the result of running canonicalize a search given strippedValue. |
13517 | 0 | return url_pattern_helpers::canonicalize_search(value); |
13518 | 0 | } |
13519 | | |
13520 | | tl::expected<std::string, errors> url_pattern_init::process_hash( |
13521 | 0 | std::string_view value, process_type type) { |
13522 | | // Let strippedValue be the given value with a single leading U+0023 (#) |
13523 | | // removed, if any. |
13524 | 0 | if (value.starts_with("#")) { |
13525 | 0 | value.remove_prefix(1); |
13526 | 0 | } |
13527 | 0 | ADA_ASSERT_TRUE(!value.starts_with("#")); |
13528 | | // If type is "pattern" then return strippedValue. |
13529 | 0 | if (type == process_type::pattern) { |
13530 | 0 | return std::string(value); |
13531 | 0 | } |
13532 | | // Return the result of running canonicalize a hash given strippedValue. |
13533 | 0 | return url_pattern_helpers::canonicalize_hash(value); |
13534 | 0 | } |
13535 | | |
13536 | | } // namespace ada |
13537 | | |
13538 | | #endif // ADA_INCLUDE_URL_PATTERN |
13539 | | /* end file src/url_pattern.cpp */ |
13540 | | /* begin file src/url_pattern_helpers.cpp */ |
13541 | | #if ADA_INCLUDE_URL_PATTERN |
13542 | | |
13543 | | #include <algorithm> |
13544 | | #include <array> |
13545 | | #include <charconv> |
13546 | | #include <optional> |
13547 | | #include <ranges> |
13548 | | #include <string> |
13549 | | |
13550 | | |
13551 | | namespace ada::url_pattern_helpers { |
13552 | | |
13553 | | std::tuple<std::string, std::vector<std::string>> |
13554 | | generate_regular_expression_and_name_list( |
13555 | | const std::vector<url_pattern_part>& part_list, |
13556 | 0 | url_pattern_compile_component_options options) { |
13557 | | // Let result be "^" |
13558 | 0 | std::string result = "^"; |
13559 | | // Reserve capacity to reduce reallocations |
13560 | 0 | result.reserve(part_list.size() * 16); |
13561 | | |
13562 | | // Let name list be a new list |
13563 | 0 | std::vector<std::string> name_list{}; |
13564 | 0 | name_list.reserve(part_list.size()); |
13565 | | |
13566 | | // Pre-generate segment wildcard regexp if needed (avoids repeated generation) |
13567 | 0 | std::string segment_wildcard_regexp; |
13568 | | |
13569 | | // For each part of part list: |
13570 | 0 | for (const url_pattern_part& part : part_list) { |
13571 | | // If part's type is "fixed-text": |
13572 | 0 | if (part.type == url_pattern_part_type::FIXED_TEXT) { |
13573 | | // If part's modifier is "none" |
13574 | 0 | if (part.modifier == url_pattern_part_modifier::none) { |
13575 | 0 | result.append(escape_regexp_string(part.value)); |
13576 | 0 | } else { |
13577 | | // (?:<fixed text>)<modifier> |
13578 | 0 | result.append("(?:"); |
13579 | 0 | result.append(escape_regexp_string(part.value)); |
13580 | 0 | result.push_back(')'); |
13581 | 0 | result.append(convert_modifier_to_string(part.modifier)); |
13582 | 0 | } |
13583 | 0 | continue; |
13584 | 0 | } |
13585 | | |
13586 | | // Assert: part's name is not the empty string |
13587 | 0 | ADA_ASSERT_TRUE(!part.name.empty()); |
13588 | 0 | name_list.push_back(part.name); |
13589 | | |
13590 | | // Use string_view to avoid copies where possible |
13591 | 0 | std::string_view regexp_value = part.value; |
13592 | |
|
13593 | 0 | if (part.type == url_pattern_part_type::SEGMENT_WILDCARD) { |
13594 | | // Lazy generate segment wildcard regexp |
13595 | 0 | if (segment_wildcard_regexp.empty()) { |
13596 | 0 | segment_wildcard_regexp = generate_segment_wildcard_regexp(options); |
13597 | 0 | } |
13598 | 0 | regexp_value = segment_wildcard_regexp; |
13599 | 0 | } else if (part.type == url_pattern_part_type::FULL_WILDCARD) { |
13600 | 0 | regexp_value = ".*"; |
13601 | 0 | } |
13602 | | |
13603 | | // If part's prefix is the empty string and part's suffix is the empty |
13604 | | // string |
13605 | 0 | if (part.prefix.empty() && part.suffix.empty()) { |
13606 | | // If part's modifier is "none" or "optional" |
13607 | 0 | if (part.modifier == url_pattern_part_modifier::none || |
13608 | 0 | part.modifier == url_pattern_part_modifier::optional) { |
13609 | | // (<regexp value>)<modifier> |
13610 | 0 | result.push_back('('); |
13611 | 0 | result.append(regexp_value); |
13612 | 0 | result.push_back(')'); |
13613 | 0 | result.append(convert_modifier_to_string(part.modifier)); |
13614 | 0 | } else { |
13615 | | // ((?:<regexp value>)<modifier>) |
13616 | 0 | result.append("((?:"); |
13617 | 0 | result.append(regexp_value); |
13618 | 0 | result.push_back(')'); |
13619 | 0 | result.append(convert_modifier_to_string(part.modifier)); |
13620 | 0 | result.push_back(')'); |
13621 | 0 | } |
13622 | 0 | continue; |
13623 | 0 | } |
13624 | | |
13625 | | // If part's modifier is "none" or "optional" |
13626 | 0 | if (part.modifier == url_pattern_part_modifier::none || |
13627 | 0 | part.modifier == url_pattern_part_modifier::optional) { |
13628 | | // (?:<prefix>(<regexp value>)<suffix>)<modifier> |
13629 | 0 | result.append("(?:"); |
13630 | 0 | result.append(escape_regexp_string(part.prefix)); |
13631 | 0 | result.push_back('('); |
13632 | 0 | result.append(regexp_value); |
13633 | 0 | result.push_back(')'); |
13634 | 0 | result.append(escape_regexp_string(part.suffix)); |
13635 | 0 | result.push_back(')'); |
13636 | 0 | result.append(convert_modifier_to_string(part.modifier)); |
13637 | 0 | continue; |
13638 | 0 | } |
13639 | | |
13640 | | // Assert: part's modifier is "zero-or-more" or "one-or-more" |
13641 | 0 | ADA_ASSERT_TRUE(part.modifier == url_pattern_part_modifier::zero_or_more || |
13642 | 0 | part.modifier == url_pattern_part_modifier::one_or_more); |
13643 | | |
13644 | | // Assert: part's prefix is not the empty string or part's suffix is not the |
13645 | | // empty string |
13646 | 0 | ADA_ASSERT_TRUE(!part.prefix.empty() || !part.suffix.empty()); |
13647 | | |
13648 | | // (?:<prefix>((?:<regexp value>)(?:<suffix><prefix>(?:<regexp |
13649 | | // value>))*)<suffix>)? |
13650 | | // Append "(?:" to the end of result. |
13651 | 0 | result.append("(?:"); |
13652 | | // Append the result of running escape a regexp string given part's prefix |
13653 | | // to the end of result. |
13654 | 0 | result.append(escape_regexp_string(part.prefix)); |
13655 | | // Append "((?:" to the end of result. |
13656 | 0 | result.append("((?:"); |
13657 | | // Append regexp value to the end of result. |
13658 | 0 | result.append(regexp_value); |
13659 | | // Append ")(?:" to the end of result. |
13660 | 0 | result.append(")(?:"); |
13661 | | // Append the result of running escape a regexp string given part's suffix |
13662 | | // to the end of result. |
13663 | 0 | result.append(escape_regexp_string(part.suffix)); |
13664 | | // Append the result of running escape a regexp string given part's prefix |
13665 | | // to the end of result. |
13666 | 0 | result.append(escape_regexp_string(part.prefix)); |
13667 | | // Append "(?:" to the end of result. |
13668 | 0 | result.append("(?:"); |
13669 | | // Append regexp value to the end of result. |
13670 | 0 | result.append(regexp_value); |
13671 | | // Append "))*)" to the end of result. |
13672 | 0 | result.append("))*)"); |
13673 | | // Append the result of running escape a regexp string given part's suffix |
13674 | | // to the end of result. |
13675 | 0 | result.append(escape_regexp_string(part.suffix)); |
13676 | | // Append ")" to the end of result. |
13677 | 0 | result.append(")"); |
13678 | | |
13679 | | // If part's modifier is "zero-or-more" then append "?" to the end of result |
13680 | 0 | if (part.modifier == url_pattern_part_modifier::zero_or_more) { |
13681 | 0 | result += "?"; |
13682 | 0 | } |
13683 | 0 | } |
13684 | | |
13685 | | // Append "$" to the end of result |
13686 | 0 | result += "$"; |
13687 | | |
13688 | | // Return (result, name list) |
13689 | 0 | return {std::move(result), std::move(name_list)}; |
13690 | 0 | } |
13691 | | |
13692 | 0 | bool is_ipv6_address(std::string_view input) noexcept { |
13693 | | // If input's code point length is less than 2, then return false. |
13694 | 0 | if (input.size() < 2) return false; |
13695 | | |
13696 | | // Let input code points be input interpreted as a list of code points. |
13697 | | // If input code points[0] is U+005B ([), then return true. |
13698 | 0 | if (input.front() == '[') return true; |
13699 | | // If input code points[0] is U+007B ({) and input code points[1] is U+005B |
13700 | | // ([), then return true. |
13701 | 0 | if (input.starts_with("{[")) return true; |
13702 | | // If input code points[0] is U+005C (\) and input code points[1] is U+005B |
13703 | | // ([), then return true. |
13704 | 0 | return input.starts_with("\\["); |
13705 | 0 | } |
13706 | | |
13707 | | std::string_view convert_modifier_to_string( |
13708 | 0 | url_pattern_part_modifier modifier) { |
13709 | 0 | switch (modifier) { |
13710 | | // If modifier is "zero-or-more", then return "*". |
13711 | 0 | case url_pattern_part_modifier::zero_or_more: |
13712 | 0 | return "*"; |
13713 | | // If modifier is "optional", then return "?". |
13714 | 0 | case url_pattern_part_modifier::optional: |
13715 | 0 | return "?"; |
13716 | | // If modifier is "one-or-more", then return "+". |
13717 | 0 | case url_pattern_part_modifier::one_or_more: |
13718 | 0 | return "+"; |
13719 | | // Return the empty string. |
13720 | 0 | default: |
13721 | 0 | return ""; |
13722 | 0 | } |
13723 | 0 | } |
13724 | | |
13725 | | std::string generate_segment_wildcard_regexp( |
13726 | 0 | url_pattern_compile_component_options options) { |
13727 | | // Let result be "[^". |
13728 | 0 | std::string result = "[^"; |
13729 | | // Append the result of running escape a regexp string given options's |
13730 | | // delimiter code point to the end of result. |
13731 | 0 | result.append(escape_regexp_string(options.get_delimiter())); |
13732 | | // Append "]+?" to the end of result. |
13733 | 0 | result.append("]+?"); |
13734 | | // Return result. |
13735 | 0 | ada_log("generate_segment_wildcard_regexp result: ", result); |
13736 | 0 | return result; |
13737 | 0 | } |
13738 | | |
13739 | | namespace { |
13740 | | // Unified lookup table for URL pattern character classification |
13741 | | // Bit flags for different character types |
13742 | | constexpr uint8_t CHAR_SCHEME = 1; // valid in scheme (a-z, A-Z, 0-9, +, -, .) |
13743 | | constexpr uint8_t CHAR_UPPER = 2; // uppercase letter (needs lowercasing) |
13744 | | constexpr uint8_t CHAR_SIMPLE_HOSTNAME = 4; // simple hostname (a-z, 0-9, -, .) |
13745 | | constexpr uint8_t CHAR_SIMPLE_PATHNAME = |
13746 | | 8; // simple pathname (a-z, A-Z, 0-9, /, -, _, ~) |
13747 | | |
13748 | | constexpr std::array<uint8_t, 256> char_class_table = []() consteval { |
13749 | | std::array<uint8_t, 256> table{}; |
13750 | | for (int c = 'a'; c <= 'z'; c++) |
13751 | | table[c] = CHAR_SCHEME | CHAR_SIMPLE_HOSTNAME | CHAR_SIMPLE_PATHNAME; |
13752 | | for (int c = 'A'; c <= 'Z'; c++) |
13753 | | table[c] = CHAR_SCHEME | CHAR_UPPER | CHAR_SIMPLE_PATHNAME; |
13754 | | for (int c = '0'; c <= '9'; c++) |
13755 | | table[c] = CHAR_SCHEME | CHAR_SIMPLE_HOSTNAME | CHAR_SIMPLE_PATHNAME; |
13756 | | table['+'] = CHAR_SCHEME; |
13757 | | table['-'] = CHAR_SCHEME | CHAR_SIMPLE_HOSTNAME | CHAR_SIMPLE_PATHNAME; |
13758 | | table['.'] = |
13759 | | CHAR_SCHEME | CHAR_SIMPLE_HOSTNAME; // not pathname (needs normalization) |
13760 | | table['/'] = CHAR_SIMPLE_PATHNAME; |
13761 | | table['_'] = CHAR_SIMPLE_PATHNAME; |
13762 | | table['~'] = CHAR_SIMPLE_PATHNAME; |
13763 | | return table; |
13764 | | }(); |
13765 | | } // namespace |
13766 | | |
13767 | | tl::expected<std::string, errors> canonicalize_protocol( |
13768 | 0 | std::string_view input) { |
13769 | 0 | ada_log("canonicalize_protocol called with input=", input); |
13770 | 0 | if (input.empty()) [[unlikely]] { |
13771 | 0 | return ""; |
13772 | 0 | } |
13773 | | |
13774 | 0 | if (input.ends_with(":")) { |
13775 | 0 | input.remove_suffix(1); |
13776 | 0 | } |
13777 | | |
13778 | | // Fast path: special schemes are already canonical |
13779 | 0 | if (scheme::is_special(input)) { |
13780 | 0 | return std::string(input); |
13781 | 0 | } |
13782 | | |
13783 | | // Fast path: validate scheme chars and check for uppercase |
13784 | | // First char must be alpha (not +, -, ., or digit) |
13785 | 0 | uint8_t first_flags = char_class_table[static_cast<uint8_t>(input[0])]; |
13786 | 0 | if (!(first_flags & CHAR_SCHEME) || input[0] == '+' || input[0] == '-' || |
13787 | 0 | input[0] == '.' || unicode::is_ascii_digit(input[0])) { |
13788 | 0 | return tl::unexpected(errors::type_error); |
13789 | 0 | } |
13790 | | |
13791 | 0 | uint8_t needs_lowercase = first_flags & CHAR_UPPER; |
13792 | 0 | for (size_t i = 1; i < input.size(); i++) { |
13793 | 0 | uint8_t flags = char_class_table[static_cast<uint8_t>(input[i])]; |
13794 | 0 | if (!(flags & CHAR_SCHEME)) { |
13795 | 0 | return tl::unexpected(errors::type_error); |
13796 | 0 | } |
13797 | 0 | needs_lowercase |= flags & CHAR_UPPER; |
13798 | 0 | } |
13799 | | |
13800 | 0 | if (needs_lowercase == 0) { |
13801 | 0 | return std::string(input); |
13802 | 0 | } |
13803 | | |
13804 | 0 | std::string result(input); |
13805 | 0 | unicode::to_lower_ascii(result.data(), result.size()); |
13806 | 0 | return result; |
13807 | 0 | } |
13808 | | |
13809 | | tl::expected<std::string, errors> canonicalize_username( |
13810 | 0 | std::string_view input) { |
13811 | | // If value is the empty string, return value. |
13812 | 0 | if (input.empty()) [[unlikely]] { |
13813 | 0 | return ""; |
13814 | 0 | } |
13815 | | // Percent-encode the input using the userinfo percent-encode set. |
13816 | 0 | size_t idx = ada::unicode::percent_encode_index( |
13817 | 0 | input, character_sets::USERINFO_PERCENT_ENCODE); |
13818 | 0 | if (idx == input.size()) { |
13819 | | // No encoding needed, return input as-is |
13820 | 0 | return std::string(input); |
13821 | 0 | } |
13822 | | // Percent-encode from the first character that needs encoding |
13823 | 0 | return ada::unicode::percent_encode( |
13824 | 0 | input, character_sets::USERINFO_PERCENT_ENCODE, idx); |
13825 | 0 | } |
13826 | | |
13827 | | tl::expected<std::string, errors> canonicalize_password( |
13828 | 0 | std::string_view input) { |
13829 | | // If value is the empty string, return value. |
13830 | 0 | if (input.empty()) [[unlikely]] { |
13831 | 0 | return ""; |
13832 | 0 | } |
13833 | | // Percent-encode the input using the userinfo percent-encode set. |
13834 | 0 | size_t idx = ada::unicode::percent_encode_index( |
13835 | 0 | input, character_sets::USERINFO_PERCENT_ENCODE); |
13836 | 0 | if (idx == input.size()) { |
13837 | | // No encoding needed, return input as-is |
13838 | 0 | return std::string(input); |
13839 | 0 | } |
13840 | | // Percent-encode from the first character that needs encoding |
13841 | 0 | return ada::unicode::percent_encode( |
13842 | 0 | input, character_sets::USERINFO_PERCENT_ENCODE, idx); |
13843 | 0 | } |
13844 | | |
13845 | | tl::expected<std::string, errors> canonicalize_hostname( |
13846 | 0 | std::string_view input) { |
13847 | 0 | ada_log("canonicalize_hostname input=", input); |
13848 | 0 | if (input.empty()) [[unlikely]] { |
13849 | 0 | return ""; |
13850 | 0 | } |
13851 | | |
13852 | | // Fast path: simple hostnames (lowercase ASCII, digits, -, .) need no IDNA. |
13853 | | // The simple character set also covers IPv4-shaped hosts, which the slow |
13854 | | // path rewrites ("0" -> "0.0.0.0", "0x7f.1" -> "127.0.0.1"). Exclude those |
13855 | | // so the fast path can't return a non-canonical hostname. |
13856 | | // |
13857 | | // Pure-ASCII "xn--" labels are intentionally left on the fast path: with |
13858 | | // beStrict=false, domain-to-ASCII returns the lowercased ASCII input even |
13859 | | // when Unicode ToASCII would fail (e.g. invalid ACE "xn--a"). See |
13860 | | // https://url.spec.whatwg.org/#concept-domain-to-ascii |
13861 | 0 | bool needs_processing = false; |
13862 | 0 | for (char c : input) { |
13863 | 0 | needs_processing |= |
13864 | 0 | !(char_class_table[static_cast<uint8_t>(c)] & CHAR_SIMPLE_HOSTNAME); |
13865 | 0 | } |
13866 | 0 | if (!needs_processing && !checkers::is_ipv4(input)) { |
13867 | 0 | return std::string(input); |
13868 | 0 | } |
13869 | | |
13870 | | // Let dummyURL be a new URL record. |
13871 | | // Let parseResult be the result of running the basic URL parser given value |
13872 | | // with dummyURL as url and hostname state as state override. |
13873 | | |
13874 | | // IMPORTANT: The protocol needs to be a special protocol, otherwise the |
13875 | | // hostname will not be converted using IDNA. |
13876 | 0 | auto url = ada::parse<url_aggregator>("https://dummy.test", nullptr); |
13877 | 0 | ADA_ASSERT_TRUE(url); |
13878 | | // if (!isValidHostnameInput(hostname)) return kj::none; |
13879 | 0 | if (!url->set_hostname(input)) { |
13880 | | // If parseResult is failure, then throw a TypeError. |
13881 | 0 | return tl::unexpected(errors::type_error); |
13882 | 0 | } |
13883 | | // Return dummyURL's host, serialized, or empty string if it is null. |
13884 | 0 | return std::string(url->get_hostname()); |
13885 | 0 | } |
13886 | | |
13887 | | tl::expected<std::string, errors> canonicalize_ipv6_hostname( |
13888 | 0 | std::string_view input) { |
13889 | 0 | ada_log("canonicalize_ipv6_hostname input=", input); |
13890 | | // TODO: Optimization opportunity: Use lookup table to speed up checking |
13891 | 0 | if (std::ranges::any_of(input, [](char c) { |
13892 | 0 | return c != '[' && c != ']' && c != ':' && |
13893 | 0 | !unicode::is_ascii_hex_digit(c); |
13894 | 0 | })) { |
13895 | 0 | return tl::unexpected(errors::type_error); |
13896 | 0 | } |
13897 | | // Append the result of running ASCII lowercase given code point to the end of |
13898 | | // result. |
13899 | 0 | auto hostname = std::string(input); |
13900 | 0 | unicode::to_lower_ascii(hostname.data(), hostname.size()); |
13901 | 0 | return hostname; |
13902 | 0 | } |
13903 | | |
13904 | | tl::expected<std::string, errors> canonicalize_port( |
13905 | 0 | std::string_view port_value) { |
13906 | | // If portValue is the empty string, return portValue. |
13907 | 0 | if (port_value.empty()) [[unlikely]] { |
13908 | 0 | return ""; |
13909 | 0 | } |
13910 | | |
13911 | | // Remove ASCII tab or newline characters |
13912 | 0 | std::string trimmed(port_value); |
13913 | 0 | helpers::remove_ascii_tab_or_newline(trimmed); |
13914 | |
|
13915 | 0 | if (trimmed.empty()) { |
13916 | 0 | return ""; |
13917 | 0 | } |
13918 | | |
13919 | | // Input should start with a digit character |
13920 | 0 | if (!unicode::is_ascii_digit(trimmed.front())) { |
13921 | 0 | return tl::unexpected(errors::type_error); |
13922 | 0 | } |
13923 | | |
13924 | | // Find the first non-digit character |
13925 | 0 | auto first_non_digit = |
13926 | 0 | std::ranges::find_if_not(trimmed, unicode::is_ascii_digit); |
13927 | 0 | std::string_view digits_to_parse = |
13928 | 0 | std::string_view(trimmed.data(), first_non_digit - trimmed.begin()); |
13929 | | |
13930 | | // Here we have a range of ASCII digit characters identified by |
13931 | | // digits_to_parse. It is non-empty. The port state of the URL parser reads |
13932 | | // it as an integer, so leading zeros are part of the number: "0080" is 80 |
13933 | | // and "065535" is 65535, not a six-digit overflow. Only the significant |
13934 | | // digits count toward the 5-digit maximum, matching the fast path in |
13935 | | // implementation.cpp. |
13936 | 0 | size_t first_significant = digits_to_parse.find_first_not_of('0'); |
13937 | 0 | if (first_significant == std::string_view::npos) { |
13938 | | // The value is all zeros, i.e. port 0. |
13939 | 0 | return "0"; |
13940 | 0 | } |
13941 | 0 | digits_to_parse.remove_prefix(first_significant); |
13942 | | // We want to determine whether it is a valid port number (0-65535). |
13943 | | // Clearly, if the length is greater than 5, it is invalid. |
13944 | | // If the length is 5, we need to compare lexicographically to "65535". |
13945 | | // Otherwise it is valid. |
13946 | 0 | if (digits_to_parse.size() == 5) { |
13947 | 0 | if (digits_to_parse > "65535") { |
13948 | 0 | return tl::unexpected(errors::type_error); |
13949 | 0 | } |
13950 | 0 | } else if (digits_to_parse.size() > 5) { |
13951 | 0 | return tl::unexpected(errors::type_error); |
13952 | 0 | } |
13953 | | // It is valid! Most times, we do not need to parse it into an integer. |
13954 | 0 | return std::string(digits_to_parse); |
13955 | 0 | } |
13956 | | |
13957 | | tl::expected<std::string, errors> canonicalize_port_with_protocol( |
13958 | 0 | std::string_view port_value, std::string_view protocol) { |
13959 | | // If portValue is the empty string, return portValue. |
13960 | 0 | if (port_value.empty()) [[unlikely]] { |
13961 | 0 | return ""; |
13962 | 0 | } |
13963 | | |
13964 | | // Handle empty or trailing colon in protocol |
13965 | 0 | if (protocol.empty()) { |
13966 | 0 | protocol = "fake"; |
13967 | 0 | } else if (protocol.ends_with(":")) { |
13968 | 0 | protocol.remove_suffix(1); |
13969 | 0 | } |
13970 | | |
13971 | | // Remove ASCII tab or newline characters |
13972 | 0 | std::string trimmed(port_value); |
13973 | 0 | helpers::remove_ascii_tab_or_newline(trimmed); |
13974 | |
|
13975 | 0 | if (trimmed.empty()) { |
13976 | 0 | return ""; |
13977 | 0 | } |
13978 | | |
13979 | | // Input should start with a digit character |
13980 | 0 | if (!unicode::is_ascii_digit(trimmed.front())) { |
13981 | 0 | return tl::unexpected(errors::type_error); |
13982 | 0 | } |
13983 | | |
13984 | | // Find the first non-digit character |
13985 | 0 | auto first_non_digit = |
13986 | 0 | std::ranges::find_if_not(trimmed, unicode::is_ascii_digit); |
13987 | 0 | std::string_view digits_to_parse = |
13988 | 0 | std::string_view(trimmed.data(), first_non_digit - trimmed.begin()); |
13989 | | |
13990 | | // Parse the port number |
13991 | 0 | uint16_t parsed_port{}; |
13992 | | // NOLINTNEXTLINE(bugprone-suspicious-stringview-data-usage) |
13993 | 0 | auto result = std::from_chars(digits_to_parse.data(), |
13994 | 0 | digits_to_parse.data() + digits_to_parse.size(), |
13995 | 0 | parsed_port); |
13996 | |
|
13997 | 0 | if (result.ec == std::errc::result_out_of_range) { |
13998 | 0 | return tl::unexpected(errors::type_error); |
13999 | 0 | } |
14000 | | |
14001 | 0 | if (result.ec == std::errc()) { |
14002 | | // Check if this is the default port for the scheme |
14003 | 0 | uint16_t default_port = scheme::get_special_port(protocol); |
14004 | | |
14005 | | // If it's the default port for a special scheme, return empty string |
14006 | 0 | if (default_port != 0 && default_port == parsed_port) { |
14007 | 0 | return ""; |
14008 | 0 | } |
14009 | | |
14010 | | // Successfully parsed, return as string |
14011 | 0 | return std::to_string(parsed_port); |
14012 | 0 | } |
14013 | | |
14014 | 0 | return tl::unexpected(errors::type_error); |
14015 | 0 | } |
14016 | | |
14017 | | tl::expected<std::string, errors> canonicalize_pathname( |
14018 | 0 | std::string_view input) { |
14019 | 0 | if (input.empty()) [[unlikely]] { |
14020 | 0 | return ""; |
14021 | 0 | } |
14022 | | |
14023 | | // Fast path: simple pathnames (no . which needs normalization) can be |
14024 | | // returned as-is |
14025 | 0 | bool needs_processing = false; |
14026 | 0 | for (char c : input) { |
14027 | 0 | needs_processing |= |
14028 | 0 | !(char_class_table[static_cast<uint8_t>(c)] & CHAR_SIMPLE_PATHNAME); |
14029 | 0 | } |
14030 | 0 | if (!needs_processing) { |
14031 | 0 | return std::string(input); |
14032 | 0 | } |
14033 | | |
14034 | | // Let leading slash be true if the first code point in value is U+002F (/) |
14035 | | // and otherwise false. |
14036 | 0 | const bool leading_slash = input.starts_with("/"); |
14037 | | // Let modified value be "/-" if leading slash is false and otherwise the |
14038 | | // empty string. |
14039 | 0 | const auto modified_value = |
14040 | 0 | (leading_slash ? std::string() : std::string("/-")) + std::string(input); |
14041 | | // The spec runs the basic URL parser with the path in state override, where |
14042 | | // '?' and '#' are ordinary path code points (percent-encoded) and leading or |
14043 | | // trailing C0 control or space is kept. Building a full URL string and |
14044 | | // parsing it (no state override) instead let '?' and '#' start the |
14045 | | // query/fragment, so the pathname was silently truncated at the first literal |
14046 | | // '?' or '#'. set_pathname runs the parser in path state override, matching |
14047 | | // how canonicalize_hostname uses set_hostname. |
14048 | 0 | auto url = ada::parse<url_aggregator>("fake://fake-url", nullptr); |
14049 | 0 | ADA_ASSERT_TRUE(url); |
14050 | 0 | if (!url->set_pathname(modified_value)) { |
14051 | | // If parseResult is failure, then throw a TypeError. |
14052 | 0 | return tl::unexpected(errors::type_error); |
14053 | 0 | } |
14054 | 0 | const auto pathname = url->get_pathname(); |
14055 | | // If leading slash is false, then set result to the code point substring |
14056 | | // from 2 to the end of the string within result. |
14057 | 0 | if (!leading_slash) { |
14058 | | // pathname should start with "/-" but path traversal (e.g. "../../") |
14059 | | // can reduce it to just "/" which is shorter than 2 characters. |
14060 | 0 | if (pathname.size() < 2) { |
14061 | 0 | return tl::unexpected(errors::type_error); |
14062 | 0 | } |
14063 | 0 | return std::string(pathname.substr(2)); |
14064 | 0 | } |
14065 | 0 | return std::string(pathname); |
14066 | 0 | } |
14067 | | |
14068 | | tl::expected<std::string, errors> canonicalize_opaque_pathname( |
14069 | 0 | std::string_view input) { |
14070 | | // If value is the empty string, return value. |
14071 | 0 | if (input.empty()) [[unlikely]] { |
14072 | 0 | return ""; |
14073 | 0 | } |
14074 | | // Let dummyURL be a new URL record. |
14075 | | // Set dummyURL's path to the empty string. |
14076 | | // Let parseResult be the result of running URL parsing given value with |
14077 | | // dummyURL as url and opaque path state as state override. |
14078 | 0 | if (auto url = |
14079 | 0 | ada::parse<url_aggregator>("fake:" + std::string(input), nullptr)) { |
14080 | | // Return the result of URL path serializing dummyURL. |
14081 | 0 | return std::string(url->get_pathname()); |
14082 | 0 | } |
14083 | | // If parseResult is failure, then throw a TypeError. |
14084 | 0 | return tl::unexpected(errors::type_error); |
14085 | 0 | } |
14086 | | |
14087 | 0 | tl::expected<std::string, errors> canonicalize_search(std::string_view input) { |
14088 | | // If value is the empty string, return value. |
14089 | 0 | if (input.empty()) [[unlikely]] { |
14090 | 0 | return ""; |
14091 | 0 | } |
14092 | | // A leading '?' is a valid query code point here: it is the caller (process a |
14093 | | // search) that removes a single delimiter, not this step, which mirrors the |
14094 | | // basic URL parser's query state. |
14095 | 0 | std::string new_value(input); |
14096 | | // Remove ASCII tab or newline characters |
14097 | 0 | helpers::remove_ascii_tab_or_newline(new_value); |
14098 | |
|
14099 | 0 | if (new_value.empty()) { |
14100 | 0 | return ""; |
14101 | 0 | } |
14102 | | |
14103 | | // Percent-encode using QUERY_PERCENT_ENCODE (for non-special URLs) |
14104 | | // Note: "fake://dummy.test" is not a special URL, so we use |
14105 | | // QUERY_PERCENT_ENCODE |
14106 | 0 | size_t idx = ada::unicode::percent_encode_index( |
14107 | 0 | new_value, character_sets::QUERY_PERCENT_ENCODE); |
14108 | 0 | if (idx == new_value.size()) { |
14109 | | // No encoding needed |
14110 | 0 | return new_value; |
14111 | 0 | } |
14112 | | // Percent-encode from the first character that needs encoding |
14113 | 0 | return ada::unicode::percent_encode( |
14114 | 0 | new_value, character_sets::QUERY_PERCENT_ENCODE, idx); |
14115 | 0 | } |
14116 | | |
14117 | 0 | tl::expected<std::string, errors> canonicalize_hash(std::string_view input) { |
14118 | | // If value is the empty string, return value. |
14119 | 0 | if (input.empty()) [[unlikely]] { |
14120 | 0 | return ""; |
14121 | 0 | } |
14122 | | // A leading '#' is a valid fragment code point here: it is the caller |
14123 | | // (process a hash) that removes a single delimiter, not this step, which |
14124 | | // mirrors the basic URL parser's fragment state. |
14125 | 0 | std::string new_value(input); |
14126 | | // Remove ASCII tab or newline characters |
14127 | 0 | helpers::remove_ascii_tab_or_newline(new_value); |
14128 | |
|
14129 | 0 | if (new_value.empty()) { |
14130 | 0 | return ""; |
14131 | 0 | } |
14132 | | |
14133 | | // Percent-encode using FRAGMENT_PERCENT_ENCODE |
14134 | 0 | size_t idx = ada::unicode::percent_encode_index( |
14135 | 0 | new_value, character_sets::FRAGMENT_PERCENT_ENCODE); |
14136 | 0 | if (idx == new_value.size()) { |
14137 | | // No encoding needed |
14138 | 0 | return new_value; |
14139 | 0 | } |
14140 | | // Percent-encode from the first character that needs encoding |
14141 | 0 | return ada::unicode::percent_encode( |
14142 | 0 | new_value, character_sets::FRAGMENT_PERCENT_ENCODE, idx); |
14143 | 0 | } |
14144 | | |
14145 | | tl::expected<std::vector<token>, errors> tokenize(std::string_view input, |
14146 | 0 | token_policy policy) { |
14147 | 0 | ada_log("tokenize input: ", input); |
14148 | | // Let tokenizer be a new tokenizer. |
14149 | | // Set tokenizer's input to input. |
14150 | | // Set tokenizer's policy to policy. |
14151 | 0 | auto tokenizer = Tokenizer(input, policy); |
14152 | | // While tokenizer's index is less than tokenizer's input's code point length: |
14153 | 0 | while (tokenizer.index < tokenizer.input.size()) { |
14154 | | // Run seek and get the next code point given tokenizer and tokenizer's |
14155 | | // index. |
14156 | 0 | tokenizer.seek_and_get_next_code_point(tokenizer.index); |
14157 | | |
14158 | | // Malformed UTF-8 must not stall tokenization: report an invalid-char |
14159 | | // token (lenient) or fail fast (strict), while always making progress. |
14160 | 0 | if (tokenizer.had_invalid_code_point()) { |
14161 | 0 | if (auto error = tokenizer.process_tokenizing_error(tokenizer.next_index, |
14162 | 0 | tokenizer.index)) { |
14163 | 0 | return tl::unexpected(*error); |
14164 | 0 | } |
14165 | 0 | continue; |
14166 | 0 | } |
14167 | | |
14168 | | // If tokenizer's code point is U+002A (*): |
14169 | 0 | if (tokenizer.code_point == '*') { |
14170 | | // Run add a token with default position and length given tokenizer and |
14171 | | // "asterisk". |
14172 | 0 | tokenizer.add_token_with_defaults(token_type::ASTERISK); |
14173 | 0 | ada_log("add ASTERISK token"); |
14174 | | // Continue. |
14175 | 0 | continue; |
14176 | 0 | } |
14177 | | |
14178 | | // If tokenizer's code point is U+002B (+) or U+003F (?): |
14179 | 0 | if (tokenizer.code_point == '+' || tokenizer.code_point == '?') { |
14180 | | // Run add a token with default position and length given tokenizer and |
14181 | | // "other-modifier". |
14182 | 0 | tokenizer.add_token_with_defaults(token_type::OTHER_MODIFIER); |
14183 | | // Continue. |
14184 | 0 | continue; |
14185 | 0 | } |
14186 | | |
14187 | | // If tokenizer's code point is U+005C (\): |
14188 | 0 | if (tokenizer.code_point == '\\') { |
14189 | | // If tokenizer's index is equal to tokenizer's input's code point length |
14190 | | // - 1: |
14191 | 0 | if (tokenizer.index == tokenizer.input.size() - 1) { |
14192 | | // Run process a tokenizing error given tokenizer, tokenizer's next |
14193 | | // index, and tokenizer's index. |
14194 | 0 | if (auto error = tokenizer.process_tokenizing_error( |
14195 | 0 | tokenizer.next_index, tokenizer.index)) { |
14196 | 0 | ada_log("process_tokenizing_error failed"); |
14197 | 0 | return tl::unexpected(*error); |
14198 | 0 | } |
14199 | 0 | continue; |
14200 | 0 | } |
14201 | | |
14202 | | // Let escaped index be tokenizer's next index. |
14203 | 0 | auto escaped_index = tokenizer.next_index; |
14204 | | // Run get the next code point given tokenizer. |
14205 | 0 | tokenizer.get_next_code_point(); |
14206 | 0 | if (tokenizer.had_invalid_code_point()) { |
14207 | 0 | if (auto error = tokenizer.process_tokenizing_error( |
14208 | 0 | tokenizer.next_index, escaped_index)) { |
14209 | 0 | return tl::unexpected(*error); |
14210 | 0 | } |
14211 | 0 | continue; |
14212 | 0 | } |
14213 | | // Run add a token with default length given tokenizer, "escaped-char", |
14214 | | // tokenizer's next index, and escaped index. |
14215 | 0 | tokenizer.add_token_with_default_length( |
14216 | 0 | token_type::ESCAPED_CHAR, tokenizer.next_index, escaped_index); |
14217 | 0 | ada_log("add ESCAPED_CHAR token on next_index ", tokenizer.next_index, |
14218 | 0 | " with escaped index ", escaped_index); |
14219 | | // Continue. |
14220 | 0 | continue; |
14221 | 0 | } |
14222 | | |
14223 | | // If tokenizer's code point is U+007B ({): |
14224 | 0 | if (tokenizer.code_point == '{') { |
14225 | | // Run add a token with default position and length given tokenizer and |
14226 | | // "open". |
14227 | 0 | tokenizer.add_token_with_defaults(token_type::OPEN); |
14228 | 0 | ada_log("add OPEN token"); |
14229 | 0 | continue; |
14230 | 0 | } |
14231 | | |
14232 | | // If tokenizer's code point is U+007D (}): |
14233 | 0 | if (tokenizer.code_point == '}') { |
14234 | | // Run add a token with default position and length given tokenizer and |
14235 | | // "close". |
14236 | 0 | tokenizer.add_token_with_defaults(token_type::CLOSE); |
14237 | 0 | ada_log("add CLOSE token"); |
14238 | 0 | continue; |
14239 | 0 | } |
14240 | | |
14241 | | // If tokenizer's code point is U+003A (:): |
14242 | 0 | if (tokenizer.code_point == ':') { |
14243 | | // Let name position be tokenizer's next index. |
14244 | 0 | auto name_position = tokenizer.next_index; |
14245 | | // Let name start be name position. |
14246 | 0 | auto name_start = name_position; |
14247 | 0 | bool invalid_name = false; |
14248 | | // While name position is less than tokenizer's input's code point length: |
14249 | 0 | while (name_position < tokenizer.input.size()) { |
14250 | | // Run seek and get the next code point given tokenizer and name |
14251 | | // position. |
14252 | 0 | tokenizer.seek_and_get_next_code_point(name_position); |
14253 | 0 | if (tokenizer.had_invalid_code_point()) { |
14254 | 0 | if (auto error = tokenizer.process_tokenizing_error( |
14255 | 0 | tokenizer.next_index, name_position)) { |
14256 | 0 | return tl::unexpected(*error); |
14257 | 0 | } |
14258 | 0 | invalid_name = true; |
14259 | 0 | break; |
14260 | 0 | } |
14261 | | // Let first code point be true if name position equals name start and |
14262 | | // false otherwise. |
14263 | 0 | bool first_code_point = name_position == name_start; |
14264 | | // Let valid code point be the result of running is a valid name code |
14265 | | // point given tokenizer's code point and first code point. |
14266 | 0 | auto valid_code_point = |
14267 | 0 | idna::valid_name_code_point(tokenizer.code_point, first_code_point); |
14268 | 0 | ada_log("tokenizer.code_point=", uint32_t(tokenizer.code_point), |
14269 | 0 | " first_code_point=", first_code_point, |
14270 | 0 | " valid_code_point=", valid_code_point); |
14271 | | // If valid code point is false break. |
14272 | 0 | if (!valid_code_point) break; |
14273 | | // Set name position to tokenizer's next index. |
14274 | 0 | name_position = tokenizer.next_index; |
14275 | 0 | } |
14276 | | |
14277 | 0 | if (invalid_name) { |
14278 | 0 | continue; |
14279 | 0 | } |
14280 | | |
14281 | | // If name position is less than or equal to name start: |
14282 | 0 | if (name_position <= name_start) { |
14283 | | // Run process a tokenizing error given tokenizer, name start, and |
14284 | | // tokenizer's index. |
14285 | 0 | if (auto error = tokenizer.process_tokenizing_error(name_start, |
14286 | 0 | tokenizer.index)) { |
14287 | 0 | ada_log("process_tokenizing_error failed"); |
14288 | 0 | return tl::unexpected(*error); |
14289 | 0 | } |
14290 | | // Continue |
14291 | 0 | continue; |
14292 | 0 | } |
14293 | | |
14294 | | // Run add a token with default length given tokenizer, "name", name |
14295 | | // position, and name start. |
14296 | 0 | tokenizer.add_token_with_default_length(token_type::NAME, name_position, |
14297 | 0 | name_start); |
14298 | 0 | continue; |
14299 | 0 | } |
14300 | | |
14301 | | // If tokenizer's code point is U+0028 ((): |
14302 | 0 | if (tokenizer.code_point == '(') { |
14303 | | // Let depth be 1. |
14304 | 0 | size_t depth = 1; |
14305 | | // Let regexp position be tokenizer's next index. |
14306 | 0 | auto regexp_position = tokenizer.next_index; |
14307 | | // Let regexp start be regexp position. |
14308 | 0 | auto regexp_start = regexp_position; |
14309 | | // Let error be false. |
14310 | 0 | bool error = false; |
14311 | | |
14312 | | // While regexp position is less than tokenizer's input's code point |
14313 | | // length: |
14314 | 0 | while (regexp_position < tokenizer.input.size()) { |
14315 | | // Run seek and get the next code point given tokenizer and regexp |
14316 | | // position. |
14317 | 0 | tokenizer.seek_and_get_next_code_point(regexp_position); |
14318 | 0 | if (tokenizer.had_invalid_code_point()) { |
14319 | 0 | if (auto process_error = tokenizer.process_tokenizing_error( |
14320 | 0 | tokenizer.next_index, regexp_position)) { |
14321 | 0 | return tl::unexpected(*process_error); |
14322 | 0 | } |
14323 | 0 | error = true; |
14324 | 0 | break; |
14325 | 0 | } |
14326 | | |
14327 | | // TODO: Optimization opportunity: The next 2 if statements can be |
14328 | | // merged. If the result of running is ASCII given tokenizer's code |
14329 | | // point is false: |
14330 | 0 | if (!unicode::is_ascii(tokenizer.code_point)) { |
14331 | | // Run process a tokenizing error given tokenizer, regexp start, and |
14332 | | // tokenizer's index. |
14333 | 0 | if (auto process_error = tokenizer.process_tokenizing_error( |
14334 | 0 | regexp_start, tokenizer.index)) { |
14335 | 0 | return tl::unexpected(*process_error); |
14336 | 0 | } |
14337 | | // Set error to true. |
14338 | 0 | error = true; |
14339 | 0 | break; |
14340 | 0 | } |
14341 | | |
14342 | | // If regexp position equals regexp start and tokenizer's code point is |
14343 | | // U+003F (?): |
14344 | 0 | if (regexp_position == regexp_start && tokenizer.code_point == '?') { |
14345 | | // Run process a tokenizing error given tokenizer, regexp start, and |
14346 | | // tokenizer's index. |
14347 | 0 | if (auto process_error = tokenizer.process_tokenizing_error( |
14348 | 0 | regexp_start, tokenizer.index)) { |
14349 | 0 | return tl::unexpected(*process_error); |
14350 | 0 | } |
14351 | | // Set error to true; |
14352 | 0 | error = true; |
14353 | 0 | break; |
14354 | 0 | } |
14355 | | |
14356 | | // If tokenizer's code point is U+005C (\): |
14357 | 0 | if (tokenizer.code_point == '\\') { |
14358 | | // If regexp position equals tokenizer's input's code point length - 1 |
14359 | 0 | if (regexp_position == tokenizer.input.size() - 1) { |
14360 | | // Run process a tokenizing error given tokenizer, regexp start, and |
14361 | | // tokenizer's index. |
14362 | 0 | if (auto process_error = tokenizer.process_tokenizing_error( |
14363 | 0 | regexp_start, tokenizer.index)) { |
14364 | 0 | return tl::unexpected(*process_error); |
14365 | 0 | } |
14366 | | // Set error to true. |
14367 | 0 | error = true; |
14368 | 0 | break; |
14369 | 0 | } |
14370 | | // Run get the next code point given tokenizer. |
14371 | 0 | auto escaped_index = tokenizer.next_index; |
14372 | 0 | tokenizer.get_next_code_point(); |
14373 | 0 | if (tokenizer.had_invalid_code_point()) { |
14374 | 0 | if (auto process_error = tokenizer.process_tokenizing_error( |
14375 | 0 | tokenizer.next_index, escaped_index)) { |
14376 | 0 | return tl::unexpected(*process_error); |
14377 | 0 | } |
14378 | 0 | error = true; |
14379 | 0 | break; |
14380 | 0 | } |
14381 | | // If the result of running is ASCII given tokenizer's code point is |
14382 | | // false: |
14383 | 0 | if (!unicode::is_ascii(tokenizer.code_point)) { |
14384 | | // Run process a tokenizing error given tokenizer, regexp start, and |
14385 | | // tokenizer's index. |
14386 | 0 | if (auto process_error = tokenizer.process_tokenizing_error( |
14387 | 0 | regexp_start, tokenizer.index); |
14388 | 0 | process_error.has_value()) { |
14389 | 0 | return tl::unexpected(*process_error); |
14390 | 0 | } |
14391 | | // Set error to true. |
14392 | 0 | error = true; |
14393 | 0 | break; |
14394 | 0 | } |
14395 | | // Set regexp position to tokenizer's next index. |
14396 | 0 | regexp_position = tokenizer.next_index; |
14397 | 0 | continue; |
14398 | 0 | } |
14399 | | |
14400 | | // If tokenizer's code point is U+0029 ()): |
14401 | 0 | if (tokenizer.code_point == ')') { |
14402 | | // Decrement depth by 1. |
14403 | 0 | depth--; |
14404 | | // If depth is 0: |
14405 | 0 | if (depth == 0) { |
14406 | | // Set regexp position to tokenizer's next index. |
14407 | 0 | regexp_position = tokenizer.next_index; |
14408 | | // Break. |
14409 | 0 | break; |
14410 | 0 | } |
14411 | 0 | } else if (tokenizer.code_point == '(') { |
14412 | | // Otherwise if tokenizer's code point is U+0028 ((): |
14413 | | // Increment depth by 1. |
14414 | 0 | depth++; |
14415 | | // If regexp position equals tokenizer's input's code point length - |
14416 | | // 1: |
14417 | 0 | if (regexp_position == tokenizer.input.size() - 1) { |
14418 | | // Run process a tokenizing error given tokenizer, regexp start, and |
14419 | | // tokenizer's index. |
14420 | 0 | if (auto process_error = tokenizer.process_tokenizing_error( |
14421 | 0 | regexp_start, tokenizer.index)) { |
14422 | 0 | return tl::unexpected(*process_error); |
14423 | 0 | } |
14424 | | // Set error to true. |
14425 | 0 | error = true; |
14426 | 0 | break; |
14427 | 0 | } |
14428 | | // Let temporary position be tokenizer's next index. |
14429 | 0 | auto temporary_position = tokenizer.next_index; |
14430 | | // Run get the next code point given tokenizer. |
14431 | 0 | tokenizer.get_next_code_point(); |
14432 | 0 | if (tokenizer.had_invalid_code_point()) { |
14433 | 0 | if (auto process_error = tokenizer.process_tokenizing_error( |
14434 | 0 | tokenizer.next_index, temporary_position)) { |
14435 | 0 | return tl::unexpected(*process_error); |
14436 | 0 | } |
14437 | 0 | error = true; |
14438 | 0 | break; |
14439 | 0 | } |
14440 | | // If tokenizer's code point is not U+003F (?): |
14441 | 0 | if (tokenizer.code_point != '?') { |
14442 | | // Run process a tokenizing error given tokenizer, regexp start, and |
14443 | | // tokenizer's index. |
14444 | 0 | if (auto process_error = tokenizer.process_tokenizing_error( |
14445 | 0 | regexp_start, tokenizer.index)) { |
14446 | 0 | return tl::unexpected(*process_error); |
14447 | 0 | } |
14448 | | // Set error to true. |
14449 | 0 | error = true; |
14450 | 0 | break; |
14451 | 0 | } |
14452 | | // Set tokenizer's next index to temporary position. |
14453 | 0 | tokenizer.next_index = temporary_position; |
14454 | 0 | } |
14455 | | // Set regexp position to tokenizer's next index. |
14456 | 0 | regexp_position = tokenizer.next_index; |
14457 | 0 | } |
14458 | | |
14459 | | // If error is true continue. |
14460 | 0 | if (error) continue; |
14461 | | // If depth is not zero: |
14462 | 0 | if (depth != 0) { |
14463 | | // Run process a tokenizing error given tokenizer, regexp start, and |
14464 | | // tokenizer's index. |
14465 | 0 | if (auto process_error = tokenizer.process_tokenizing_error( |
14466 | 0 | regexp_start, tokenizer.index)) { |
14467 | 0 | return tl::unexpected(*process_error); |
14468 | 0 | } |
14469 | 0 | continue; |
14470 | 0 | } |
14471 | | // Let regexp length be regexp position - regexp start - 1. |
14472 | 0 | auto regexp_length = regexp_position - regexp_start - 1; |
14473 | | // If regexp length is zero: |
14474 | 0 | if (regexp_length == 0) { |
14475 | | // Run process a tokenizing error given tokenizer, regexp start, and |
14476 | | // tokenizer's index. |
14477 | 0 | if (auto process_error = tokenizer.process_tokenizing_error( |
14478 | 0 | regexp_start, tokenizer.index)) { |
14479 | 0 | ada_log("process_tokenizing_error failed"); |
14480 | 0 | return tl::unexpected(*process_error); |
14481 | 0 | } |
14482 | 0 | continue; |
14483 | 0 | } |
14484 | | // Run add a token given tokenizer, "regexp", regexp position, regexp |
14485 | | // start, and regexp length. |
14486 | 0 | tokenizer.add_token(token_type::REGEXP, regexp_position, regexp_start, |
14487 | 0 | regexp_length); |
14488 | 0 | continue; |
14489 | 0 | } |
14490 | | // Run add a token with default position and length given tokenizer and |
14491 | | // "char". |
14492 | 0 | tokenizer.add_token_with_defaults(token_type::CHAR); |
14493 | 0 | } |
14494 | | // Run add a token with default length given tokenizer, "end", tokenizer's |
14495 | | // index, and tokenizer's index. |
14496 | 0 | tokenizer.add_token_with_default_length(token_type::END, tokenizer.index, |
14497 | 0 | tokenizer.index); |
14498 | |
|
14499 | 0 | ada_log("tokenizer.token_list size is: ", tokenizer.token_list.size()); |
14500 | | // Return tokenizer's token list. |
14501 | 0 | return tokenizer.token_list; |
14502 | 0 | } |
14503 | | |
14504 | | namespace { |
14505 | | constexpr std::array<uint8_t, 256> escape_pattern_table = []() consteval { |
14506 | | std::array<uint8_t, 256> out{}; |
14507 | | for (auto& c : {'+', '*', '?', ':', '{', '}', '(', ')', '\\'}) { |
14508 | | out[c] = 1; |
14509 | | } |
14510 | | return out; |
14511 | | }(); |
14512 | | |
14513 | 0 | constexpr bool should_escape_pattern_char(char c) { |
14514 | 0 | return escape_pattern_table[static_cast<uint8_t>(c)]; |
14515 | 0 | } |
14516 | | } // namespace |
14517 | | |
14518 | 0 | std::string escape_pattern_string(std::string_view input) { |
14519 | 0 | ada_log("escape_pattern_string called with input=", input); |
14520 | 0 | if (input.empty()) [[unlikely]] { |
14521 | 0 | return ""; |
14522 | 0 | } |
14523 | | // Assert: input is an ASCII string. |
14524 | 0 | ADA_ASSERT_TRUE(ada::idna::is_ascii(input)); |
14525 | | // Let result be the empty string. |
14526 | 0 | std::string result{}; |
14527 | | // Reserve extra space for potential escapes |
14528 | 0 | result.reserve(input.size() * 2); |
14529 | | |
14530 | | // While index is less than input's length: |
14531 | 0 | for (const char c : input) { |
14532 | 0 | if (should_escape_pattern_char(c)) { |
14533 | | // Append U+005C (\) to the end of result. |
14534 | 0 | result.push_back('\\'); |
14535 | 0 | } |
14536 | | // Append c to the end of result. |
14537 | 0 | result.push_back(c); |
14538 | 0 | } |
14539 | | // Return result. |
14540 | 0 | return result; |
14541 | 0 | } |
14542 | | |
14543 | | namespace { |
14544 | | constexpr std::array<uint8_t, 256> escape_regexp_table = []() consteval { |
14545 | | std::array<uint8_t, 256> out{}; |
14546 | | for (auto& c : {'.', '+', '*', '?', '^', '$', '{', '}', '(', ')', '[', ']', |
14547 | | '|', '/', '\\'}) { |
14548 | | out[c] = 1; |
14549 | | } |
14550 | | return out; |
14551 | | }(); |
14552 | | |
14553 | 0 | constexpr bool should_escape_regexp_char(char c) { |
14554 | 0 | return escape_regexp_table[(uint8_t)c]; |
14555 | 0 | } |
14556 | | } // namespace |
14557 | | |
14558 | 0 | std::string escape_regexp_string(std::string_view input) { |
14559 | | // Assert: input is an ASCII string. |
14560 | 0 | ADA_ASSERT_TRUE(idna::is_ascii(input)); |
14561 | | // Let result be the empty string. |
14562 | 0 | std::string result{}; |
14563 | | // Reserve extra space for potential escapes (worst case: all chars escaped) |
14564 | 0 | result.reserve(input.size() * 2); |
14565 | 0 | for (const char c : input) { |
14566 | 0 | if (should_escape_regexp_char(c)) { |
14567 | | // Avoid temporary string allocation - directly append characters |
14568 | 0 | result.push_back('\\'); |
14569 | 0 | result.push_back(c); |
14570 | 0 | } else { |
14571 | 0 | result.push_back(c); |
14572 | 0 | } |
14573 | 0 | } |
14574 | 0 | return result; |
14575 | 0 | } |
14576 | | |
14577 | | std::string process_base_url_string(std::string_view input, |
14578 | 0 | url_pattern_init::process_type type) { |
14579 | | // If type is not "pattern" return input. |
14580 | 0 | if (type != url_pattern_init::process_type::pattern) { |
14581 | 0 | return std::string(input); |
14582 | 0 | } |
14583 | | // Return the result of escaping a pattern string given input. |
14584 | 0 | return escape_pattern_string(input); |
14585 | 0 | } |
14586 | | |
14587 | | constexpr bool is_absolute_pathname( |
14588 | 0 | std::string_view input, url_pattern_init::process_type type) noexcept { |
14589 | | // If input is the empty string, then return false. |
14590 | 0 | if (input.empty()) [[unlikely]] { |
14591 | 0 | return false; |
14592 | 0 | } |
14593 | | // If input[0] is U+002F (/), then return true. |
14594 | 0 | if (input.starts_with("/")) return true; |
14595 | | // If type is "url", then return false. |
14596 | 0 | if (type == url_pattern_init::process_type::url) return false; |
14597 | | // If input's code point length is less than 2, then return false. |
14598 | 0 | if (input.size() < 2) return false; |
14599 | | // If input[0] is U+005C (\) and input[1] is U+002F (/), then return true. |
14600 | | // If input[0] is U+007B ({) and input[1] is U+002F (/), then return true. |
14601 | | // Return false. |
14602 | 0 | return input[1] == '/' && (input[0] == '\\' || input[0] == '{'); |
14603 | 0 | } |
14604 | | |
14605 | | std::string generate_pattern_string( |
14606 | | std::vector<url_pattern_part>& part_list, |
14607 | 0 | url_pattern_compile_component_options& options) { |
14608 | | // Let result be the empty string. |
14609 | 0 | std::string result{}; |
14610 | | // Let index list be the result of getting the indices for part list. |
14611 | | // For each index of index list: |
14612 | 0 | for (size_t index = 0; index < part_list.size(); index++) { |
14613 | | // Let part be part list[index]. |
14614 | | // Use reference to avoid copy |
14615 | 0 | const auto& part = part_list[index]; |
14616 | | // Let previous part be part list[index - 1] if index is greater than 0, |
14617 | | // otherwise let it be null. |
14618 | | // Use pointer to avoid copy |
14619 | 0 | const url_pattern_part* previous_part = |
14620 | 0 | index == 0 ? nullptr : &part_list[index - 1]; |
14621 | | // Let next part be part list[index + 1] if index is less than index list's |
14622 | | // size - 1, otherwise let it be null. |
14623 | 0 | const url_pattern_part* next_part = |
14624 | 0 | index < part_list.size() - 1 ? &part_list[index + 1] : nullptr; |
14625 | | // If part's type is "fixed-text" then: |
14626 | 0 | if (part.type == url_pattern_part_type::FIXED_TEXT) { |
14627 | | // If part's modifier is "none" then: |
14628 | 0 | if (part.modifier == url_pattern_part_modifier::none) { |
14629 | | // Append the result of running escape a pattern string given part's |
14630 | | // value to the end of result. |
14631 | 0 | result.append(escape_pattern_string(part.value)); |
14632 | 0 | continue; |
14633 | 0 | } |
14634 | | // Append "{" to the end of result. |
14635 | 0 | result += "{"; |
14636 | | // Append the result of running escape a pattern string given part's value |
14637 | | // to the end of result. |
14638 | 0 | result.append(escape_pattern_string(part.value)); |
14639 | | // Append "}" to the end of result. |
14640 | 0 | result += "}"; |
14641 | | // Append the result of running convert a modifier to a string given |
14642 | | // part's modifier to the end of result. |
14643 | 0 | result.append(convert_modifier_to_string(part.modifier)); |
14644 | 0 | continue; |
14645 | 0 | } |
14646 | | // Let custom name be true if part's name[0] is not an ASCII digit; |
14647 | | // otherwise false. |
14648 | 0 | bool custom_name = !unicode::is_ascii_digit(part.name[0]); |
14649 | | // Let needs grouping be true if at least one of the following are true, |
14650 | | // otherwise let it be false: |
14651 | | // - part's suffix is not the empty string. |
14652 | | // - part's prefix is not the empty string and is not options's prefix code |
14653 | | // point. |
14654 | 0 | bool needs_grouping = |
14655 | 0 | !part.suffix.empty() || |
14656 | 0 | (!part.prefix.empty() && (options.get_prefix().empty() || |
14657 | 0 | part.prefix[0] != options.get_prefix()[0])); |
14658 | | |
14659 | | // If all of the following are true: |
14660 | | // - needs grouping is false; and |
14661 | | // - custom name is true; and |
14662 | | // - part's type is "segment-wildcard"; and |
14663 | | // - part's modifier is "none"; and |
14664 | | // - next part is not null; and |
14665 | | // - next part's prefix is the empty string; and |
14666 | | // - next part's suffix is the empty string |
14667 | 0 | if (!needs_grouping && custom_name && |
14668 | 0 | part.type == url_pattern_part_type::SEGMENT_WILDCARD && |
14669 | 0 | part.modifier == url_pattern_part_modifier::none && next_part && |
14670 | 0 | next_part->prefix.empty() && next_part->suffix.empty()) { |
14671 | | // If next part's type is "fixed-text": |
14672 | 0 | if (next_part->type == url_pattern_part_type::FIXED_TEXT) { |
14673 | | // Set needs grouping to true if the result of running is a valid name |
14674 | | // code point given next part's value's first code point and the boolean |
14675 | | // false is true. |
14676 | 0 | if (idna::valid_name_code_point(next_part->value[0], false)) { |
14677 | 0 | needs_grouping = true; |
14678 | 0 | } |
14679 | 0 | } else { |
14680 | | // Set needs grouping to true if next part's name[0] is an ASCII digit. |
14681 | 0 | needs_grouping = !next_part->name.empty() && |
14682 | 0 | unicode::is_ascii_digit(next_part->name[0]); |
14683 | 0 | } |
14684 | 0 | } |
14685 | | |
14686 | | // If all of the following are true: |
14687 | | // - needs grouping is false; and |
14688 | | // - part's prefix is the empty string; and |
14689 | | // - previous part is not null; and |
14690 | | // - previous part's type is "fixed-text"; and |
14691 | | // - previous part's value's last code point is options's prefix code point. |
14692 | | // then set needs grouping to true. |
14693 | 0 | if (!needs_grouping && part.prefix.empty() && previous_part && |
14694 | 0 | previous_part->type == url_pattern_part_type::FIXED_TEXT && |
14695 | 0 | !previous_part->value.empty() && !options.get_prefix().empty() && |
14696 | 0 | previous_part->value.back() == options.get_prefix()[0]) { |
14697 | 0 | needs_grouping = true; |
14698 | 0 | } |
14699 | | |
14700 | | // Assert: part's name is not the empty string or null. |
14701 | 0 | ADA_ASSERT_TRUE(!part.name.empty()); |
14702 | | |
14703 | | // If needs grouping is true, then append "{" to the end of result. |
14704 | 0 | if (needs_grouping) { |
14705 | 0 | result.append("{"); |
14706 | 0 | } |
14707 | | |
14708 | | // Append the result of running escape a pattern string given part's prefix |
14709 | | // to the end of result. |
14710 | 0 | result.append(escape_pattern_string(part.prefix)); |
14711 | | |
14712 | | // If custom name is true: |
14713 | 0 | if (custom_name) { |
14714 | | // Append ":" to the end of result. |
14715 | 0 | result.append(":"); |
14716 | | // Append part's name to the end of result. |
14717 | 0 | result.append(part.name); |
14718 | 0 | } |
14719 | | |
14720 | | // If part's type is "regexp" then: |
14721 | 0 | if (part.type == url_pattern_part_type::REGEXP) { |
14722 | | // Append "(" to the end of result. |
14723 | 0 | result.append("("); |
14724 | | // Append part's value to the end of result. |
14725 | 0 | result.append(part.value); |
14726 | | // Append ")" to the end of result. |
14727 | 0 | result.append(")"); |
14728 | 0 | } else if (part.type == url_pattern_part_type::SEGMENT_WILDCARD && |
14729 | 0 | !custom_name) { |
14730 | | // Otherwise if part's type is "segment-wildcard" and custom name is |
14731 | | // false: Append "(" to the end of result. |
14732 | 0 | result.append("("); |
14733 | | // Append the result of running generate a segment wildcard regexp given |
14734 | | // options to the end of result. |
14735 | 0 | result.append(generate_segment_wildcard_regexp(options)); |
14736 | | // Append ")" to the end of result. |
14737 | 0 | result.append(")"); |
14738 | 0 | } else if (part.type == url_pattern_part_type::FULL_WILDCARD) { |
14739 | | // Otherwise if part's type is "full-wildcard": |
14740 | | // If custom name is false and one of the following is true: |
14741 | | // - previous part is null; or |
14742 | | // - previous part's type is "fixed-text"; or |
14743 | | // - previous part's modifier is not "none"; or |
14744 | | // - needs grouping is true; or |
14745 | | // - part's prefix is not the empty string |
14746 | | // - then append "*" to the end of result. |
14747 | 0 | if (!custom_name && |
14748 | 0 | (!previous_part || |
14749 | 0 | previous_part->type == url_pattern_part_type::FIXED_TEXT || |
14750 | 0 | previous_part->modifier != url_pattern_part_modifier::none || |
14751 | 0 | needs_grouping || !part.prefix.empty())) { |
14752 | 0 | result.append("*"); |
14753 | 0 | } else { |
14754 | | // Append "(" to the end of result. |
14755 | | // Append full wildcard regexp value to the end of result. |
14756 | | // Append ")" to the end of result. |
14757 | 0 | result.append("(.*)"); |
14758 | 0 | } |
14759 | 0 | } |
14760 | | |
14761 | | // If all of the following are true: |
14762 | | // - part's type is "segment-wildcard"; and |
14763 | | // - custom name is true; and |
14764 | | // - part's suffix is not the empty string; and |
14765 | | // - The result of running is a valid name code point given part's suffix's |
14766 | | // first code point and the boolean false is true then append U+005C (\) to |
14767 | | // the end of result. |
14768 | 0 | if (part.type == url_pattern_part_type::SEGMENT_WILDCARD && custom_name && |
14769 | 0 | !part.suffix.empty() && |
14770 | 0 | idna::valid_name_code_point(part.suffix[0], false)) { |
14771 | 0 | result.append("\\"); |
14772 | 0 | } |
14773 | | |
14774 | | // Append the result of running escape a pattern string given part's suffix |
14775 | | // to the end of result. |
14776 | 0 | result.append(escape_pattern_string(part.suffix)); |
14777 | | // If needs grouping is true, then append "}" to the end of result. |
14778 | 0 | if (needs_grouping) result.append("}"); |
14779 | | // Append the result of running convert a modifier to a string given part's |
14780 | | // modifier to the end of result. |
14781 | 0 | result.append(convert_modifier_to_string(part.modifier)); |
14782 | 0 | } |
14783 | | // Return result. |
14784 | 0 | return result; |
14785 | 0 | } |
14786 | | } // namespace ada::url_pattern_helpers |
14787 | | |
14788 | | #endif // ADA_INCLUDE_URL_PATTERN |
14789 | | /* end file src/url_pattern_helpers.cpp */ |
14790 | | /* begin file src/url_pattern_regex.cpp */ |
14791 | | #if ADA_INCLUDE_URL_PATTERN |
14792 | | |
14793 | | |
14794 | | namespace ada::url_pattern_regex { |
14795 | | |
14796 | | #ifdef ADA_USE_UNSAFE_STD_REGEX_PROVIDER |
14797 | | std::optional<std::regex> std_regex_provider::create_instance( |
14798 | | std::string_view pattern, bool ignore_case) { |
14799 | | // Let flags be an empty string. |
14800 | | // If options's ignore case is true then set flags to "vi". |
14801 | | // Otherwise set flags to "v" |
14802 | | auto flags = ignore_case |
14803 | | ? std::regex::icase | std::regex_constants::ECMAScript |
14804 | | : std::regex_constants::ECMAScript; |
14805 | | try { |
14806 | | return std::regex(pattern.data(), pattern.size(), flags); |
14807 | | } catch (const std::regex_error& e) { |
14808 | | (void)e; |
14809 | | ada_log("std_regex_provider::create_instance failed:", e.what()); |
14810 | | return std::nullopt; |
14811 | | } |
14812 | | } |
14813 | | |
14814 | | std::optional<std::vector<std::optional<std::string>>> |
14815 | | std_regex_provider::regex_search(std::string_view input, |
14816 | | const std::regex& pattern) { |
14817 | | // Use iterator-based regex_search to avoid string allocation |
14818 | | std::match_results<std::string_view::const_iterator> match_result; |
14819 | | try { |
14820 | | if (!std::regex_search(input.begin(), input.end(), match_result, pattern, |
14821 | | std::regex_constants::match_any)) { |
14822 | | return std::nullopt; |
14823 | | } |
14824 | | } catch (const std::regex_error& e) { |
14825 | | (void)e; |
14826 | | ada_log("std_regex_provider::regex_search failed:", e.what()); |
14827 | | return std::nullopt; |
14828 | | } |
14829 | | std::vector<std::optional<std::string>> matches; |
14830 | | // An empty input can still match with capture groups (e.g. "(x*)" or an |
14831 | | // optional ":a?" against ""), so the group values must be extracted here |
14832 | | // just like for a non-empty input. A successful regex_search always leaves |
14833 | | // the full match at index 0, so match_result is never empty at this point. |
14834 | | if (match_result.empty()) { |
14835 | | return matches; |
14836 | | } |
14837 | | matches.reserve(match_result.size()); |
14838 | | for (size_t i = 1; i < match_result.size(); ++i) { |
14839 | | if (auto entry = match_result[i]; entry.matched) { |
14840 | | matches.emplace_back(entry.str()); |
14841 | | } else { |
14842 | | // A capture group that did not participate in the match is undefined, |
14843 | | // not absent. Emitting nullopt keeps the result aligned by position with |
14844 | | // the component's group name list; dropping it shifts every later group |
14845 | | // onto the wrong name. |
14846 | | matches.emplace_back(std::nullopt); |
14847 | | } |
14848 | | } |
14849 | | return matches; |
14850 | | } |
14851 | | |
14852 | | bool std_regex_provider::regex_match(std::string_view input, |
14853 | | const std::regex& pattern) { |
14854 | | try { |
14855 | | return std::regex_match(input.begin(), input.end(), pattern); |
14856 | | } catch (const std::regex_error& e) { |
14857 | | (void)e; |
14858 | | ada_log("std_regex_provider::regex_match failed:", e.what()); |
14859 | | return false; |
14860 | | } |
14861 | | } |
14862 | | |
14863 | | #endif // ADA_USE_UNSAFE_STD_REGEX_PROVIDER |
14864 | | |
14865 | | } // namespace ada::url_pattern_regex |
14866 | | |
14867 | | #endif // ADA_INCLUDE_URL_PATTERN |
14868 | | /* end file src/url_pattern_regex.cpp */ |
14869 | | #endif // ADA_INCLUDE_URL_PATTERN |
14870 | | |
14871 | | /* begin file src/ada_c.cpp */ |
14872 | | // NOLINTBEGIN(bugprone-exception-escape, |
14873 | | // bugprone-suspicious-stringview-data-usage) |
14874 | | |
14875 | 2.26M | ada::result<ada::url_aggregator>& get_instance(void* result) noexcept { |
14876 | 2.26M | return *(ada::result<ada::url_aggregator>*)result; |
14877 | 2.26M | } |
14878 | | |
14879 | | extern "C" { |
14880 | | typedef void* ada_url; |
14881 | | typedef void* ada_url_search_params; |
14882 | | typedef void* ada_strings; |
14883 | | typedef void* ada_url_search_params_keys_iter; |
14884 | | typedef void* ada_url_search_params_values_iter; |
14885 | | typedef void* ada_url_search_params_entries_iter; |
14886 | | |
14887 | | struct ada_string { |
14888 | | const char* data; |
14889 | | size_t length; |
14890 | | }; |
14891 | | |
14892 | | struct ada_owned_string { |
14893 | | const char* data; |
14894 | | size_t length; |
14895 | | }; |
14896 | | |
14897 | | struct ada_string_pair { |
14898 | | ada_string key; |
14899 | | ada_string value; |
14900 | | }; |
14901 | | |
14902 | 779k | ada_string ada_string_create(const char* data, size_t length) { |
14903 | 779k | ada_string out{}; |
14904 | 779k | out.data = data; |
14905 | 779k | out.length = length; |
14906 | 779k | return out; |
14907 | 779k | } |
14908 | | |
14909 | | struct ada_url_components { |
14910 | | /* |
14911 | | * By using 32-bit integers, we implicitly assume that the URL string |
14912 | | * cannot exceed 4 GB. |
14913 | | * |
14914 | | * https://user:pass@example.com:1234/foo/bar?baz#quux |
14915 | | * | | | | ^^^^| | | |
14916 | | * | | | | | | | `----- hash_start |
14917 | | * | | | | | | `--------- search_start |
14918 | | * | | | | | `----------------- pathname_start |
14919 | | * | | | | `--------------------- port |
14920 | | * | | | `----------------------- host_end |
14921 | | * | | `---------------------------------- host_start |
14922 | | * | `--------------------------------------- username_end |
14923 | | * `--------------------------------------------- protocol_end |
14924 | | */ |
14925 | | uint32_t protocol_end; |
14926 | | /** |
14927 | | * Username end is not `omitted` by default (-1) to make username and password |
14928 | | * getters less costly to implement. |
14929 | | */ |
14930 | | uint32_t username_end; |
14931 | | uint32_t host_start; |
14932 | | uint32_t host_end; |
14933 | | uint32_t port; |
14934 | | uint32_t pathname_start; |
14935 | | uint32_t search_start; |
14936 | | uint32_t hash_start; |
14937 | | }; |
14938 | | |
14939 | 105k | ada_url ada_parse(const char* input, size_t length) noexcept { |
14940 | 105k | return new ada::result<ada::url_aggregator>( |
14941 | 105k | ada::parse<ada::url_aggregator>(std::string_view(input, length))); |
14942 | 105k | } |
14943 | | |
14944 | | ada_url ada_parse_with_base(const char* input, size_t input_length, |
14945 | 11.0k | const char* base, size_t base_length) noexcept { |
14946 | 11.0k | auto base_out = |
14947 | 11.0k | ada::parse<ada::url_aggregator>(std::string_view(base, base_length)); |
14948 | | |
14949 | 11.0k | if (!base_out) { |
14950 | 7.69k | return new ada::result<ada::url_aggregator>(base_out); |
14951 | 7.69k | } |
14952 | | |
14953 | 3.31k | return new ada::result<ada::url_aggregator>(ada::parse<ada::url_aggregator>( |
14954 | 3.31k | std::string_view(input, input_length), &base_out.value())); |
14955 | 11.0k | } |
14956 | | |
14957 | 55.0k | bool ada_can_parse(const char* input, size_t length) noexcept { |
14958 | 55.0k | return ada::can_parse(std::string_view(input, length)); |
14959 | 55.0k | } |
14960 | | |
14961 | | bool ada_can_parse_with_base(const char* input, size_t input_length, |
14962 | 11.0k | const char* base, size_t base_length) noexcept { |
14963 | 11.0k | std::string_view base_view(base, base_length); |
14964 | 11.0k | return ada::can_parse(std::string_view(input, input_length), &base_view); |
14965 | 11.0k | } |
14966 | | |
14967 | 166k | void ada_free(ada_url result) noexcept { |
14968 | 166k | auto* r = (ada::result<ada::url_aggregator>*)result; |
14969 | 166k | delete r; |
14970 | 166k | } |
14971 | | |
14972 | 50.1k | ada_url ada_copy(ada_url input) noexcept { |
14973 | 50.1k | ada::result<ada::url_aggregator>& r = get_instance(input); |
14974 | 50.1k | return new ada::result<ada::url_aggregator>(r); |
14975 | 50.1k | } |
14976 | | |
14977 | 221k | bool ada_is_valid(ada_url result) noexcept { |
14978 | 221k | ada::result<ada::url_aggregator>& r = get_instance(result); |
14979 | 221k | return r.has_value(); |
14980 | 221k | } |
14981 | | |
14982 | | // caller must free the result with ada_free_owned_string |
14983 | 52.8k | ada_owned_string ada_get_origin(ada_url result) noexcept { |
14984 | 52.8k | ada::result<ada::url_aggregator>& r = get_instance(result); |
14985 | 52.8k | ada_owned_string owned{}; |
14986 | 52.8k | if (!r) { |
14987 | 0 | owned.data = nullptr; |
14988 | 0 | owned.length = 0; |
14989 | 0 | return owned; |
14990 | 0 | } |
14991 | 52.8k | std::string out = r->get_origin(); |
14992 | 52.8k | owned.length = out.size(); |
14993 | 52.8k | owned.data = new char[owned.length]; |
14994 | 52.8k | memcpy((void*)owned.data, out.data(), owned.length); |
14995 | 52.8k | return owned; |
14996 | 52.8k | } |
14997 | | |
14998 | 85.9k | void ada_free_owned_string(ada_owned_string owned) noexcept { |
14999 | 85.9k | delete[] owned.data; |
15000 | 85.9k | } |
15001 | | |
15002 | 203k | ada_string ada_get_href(ada_url result) noexcept { |
15003 | 203k | ada::result<ada::url_aggregator>& r = get_instance(result); |
15004 | 203k | if (!r) { |
15005 | 0 | return ada_string_create(nullptr, 0); |
15006 | 0 | } |
15007 | 203k | std::string_view out = r->get_href(); |
15008 | 203k | return ada_string_create(out.data(), out.length()); |
15009 | 203k | } |
15010 | | |
15011 | 52.8k | ada_string ada_get_username(ada_url result) noexcept { |
15012 | 52.8k | ada::result<ada::url_aggregator>& r = get_instance(result); |
15013 | 52.8k | if (!r) { |
15014 | 0 | return ada_string_create(nullptr, 0); |
15015 | 0 | } |
15016 | 52.8k | std::string_view out = r->get_username(); |
15017 | 52.8k | return ada_string_create(out.data(), out.length()); |
15018 | 52.8k | } |
15019 | | |
15020 | 52.8k | ada_string ada_get_password(ada_url result) noexcept { |
15021 | 52.8k | ada::result<ada::url_aggregator>& r = get_instance(result); |
15022 | 52.8k | if (!r) { |
15023 | 0 | return ada_string_create(nullptr, 0); |
15024 | 0 | } |
15025 | 52.8k | std::string_view out = r->get_password(); |
15026 | 52.8k | return ada_string_create(out.data(), out.length()); |
15027 | 52.8k | } |
15028 | | |
15029 | 52.8k | ada_string ada_get_port(ada_url result) noexcept { |
15030 | 52.8k | ada::result<ada::url_aggregator>& r = get_instance(result); |
15031 | 52.8k | if (!r) { |
15032 | 0 | return ada_string_create(nullptr, 0); |
15033 | 0 | } |
15034 | 52.8k | std::string_view out = r->get_port(); |
15035 | 52.8k | return ada_string_create(out.data(), out.length()); |
15036 | 52.8k | } |
15037 | | |
15038 | 52.8k | ada_string ada_get_hash(ada_url result) noexcept { |
15039 | 52.8k | ada::result<ada::url_aggregator>& r = get_instance(result); |
15040 | 52.8k | if (!r) { |
15041 | 0 | return ada_string_create(nullptr, 0); |
15042 | 0 | } |
15043 | 52.8k | std::string_view out = r->get_hash(); |
15044 | 52.8k | return ada_string_create(out.data(), out.length()); |
15045 | 52.8k | } |
15046 | | |
15047 | 50.1k | ada_string ada_get_host(ada_url result) noexcept { |
15048 | 50.1k | ada::result<ada::url_aggregator>& r = get_instance(result); |
15049 | 50.1k | if (!r) { |
15050 | 0 | return ada_string_create(nullptr, 0); |
15051 | 0 | } |
15052 | 50.1k | std::string_view out = r->get_host(); |
15053 | 50.1k | return ada_string_create(out.data(), out.length()); |
15054 | 50.1k | } |
15055 | | |
15056 | 52.8k | ada_string ada_get_hostname(ada_url result) noexcept { |
15057 | 52.8k | ada::result<ada::url_aggregator>& r = get_instance(result); |
15058 | 52.8k | if (!r) { |
15059 | 0 | return ada_string_create(nullptr, 0); |
15060 | 0 | } |
15061 | 52.8k | std::string_view out = r->get_hostname(); |
15062 | 52.8k | return ada_string_create(out.data(), out.length()); |
15063 | 52.8k | } |
15064 | | |
15065 | 52.8k | ada_string ada_get_pathname(ada_url result) noexcept { |
15066 | 52.8k | ada::result<ada::url_aggregator>& r = get_instance(result); |
15067 | 52.8k | if (!r) { |
15068 | 0 | return ada_string_create(nullptr, 0); |
15069 | 0 | } |
15070 | 52.8k | std::string_view out = r->get_pathname(); |
15071 | 52.8k | return ada_string_create(out.data(), out.length()); |
15072 | 52.8k | } |
15073 | | |
15074 | 52.8k | ada_string ada_get_search(ada_url result) noexcept { |
15075 | 52.8k | ada::result<ada::url_aggregator>& r = get_instance(result); |
15076 | 52.8k | if (!r) { |
15077 | 0 | return ada_string_create(nullptr, 0); |
15078 | 0 | } |
15079 | 52.8k | std::string_view out = r->get_search(); |
15080 | 52.8k | return ada_string_create(out.data(), out.length()); |
15081 | 52.8k | } |
15082 | | |
15083 | 52.8k | ada_string ada_get_protocol(ada_url result) noexcept { |
15084 | 52.8k | ada::result<ada::url_aggregator>& r = get_instance(result); |
15085 | 52.8k | if (!r) { |
15086 | 0 | return ada_string_create(nullptr, 0); |
15087 | 0 | } |
15088 | 52.8k | std::string_view out = r->get_protocol(); |
15089 | 52.8k | return ada_string_create(out.data(), out.length()); |
15090 | 52.8k | } |
15091 | | |
15092 | 50.1k | uint8_t ada_get_host_type(ada_url result) noexcept { |
15093 | 50.1k | ada::result<ada::url_aggregator>& r = get_instance(result); |
15094 | 50.1k | if (!r) { |
15095 | 0 | return 0; |
15096 | 0 | } |
15097 | 50.1k | return r->host_type; |
15098 | 50.1k | } |
15099 | | |
15100 | 50.1k | uint8_t ada_get_scheme_type(ada_url result) noexcept { |
15101 | 50.1k | ada::result<ada::url_aggregator>& r = get_instance(result); |
15102 | 50.1k | if (!r) { |
15103 | 0 | return 0; |
15104 | 0 | } |
15105 | 50.1k | return r->type; |
15106 | 50.1k | } |
15107 | | |
15108 | 50.1k | bool ada_set_href(ada_url result, const char* input, size_t length) noexcept { |
15109 | 50.1k | ada::result<ada::url_aggregator>& r = get_instance(result); |
15110 | 50.1k | if (!r) { |
15111 | 0 | return false; |
15112 | 0 | } |
15113 | 50.1k | return r->set_href(std::string_view(input, length)); |
15114 | 50.1k | } |
15115 | | |
15116 | 50.1k | bool ada_set_host(ada_url result, const char* input, size_t length) noexcept { |
15117 | 50.1k | ada::result<ada::url_aggregator>& r = get_instance(result); |
15118 | 50.1k | if (!r) { |
15119 | 0 | return false; |
15120 | 0 | } |
15121 | 50.1k | return r->set_host(std::string_view(input, length)); |
15122 | 50.1k | } |
15123 | | |
15124 | | bool ada_set_hostname(ada_url result, const char* input, |
15125 | 50.1k | size_t length) noexcept { |
15126 | 50.1k | ada::result<ada::url_aggregator>& r = get_instance(result); |
15127 | 50.1k | if (!r) { |
15128 | 0 | return false; |
15129 | 0 | } |
15130 | 50.1k | return r->set_hostname(std::string_view(input, length)); |
15131 | 50.1k | } |
15132 | | |
15133 | | bool ada_set_protocol(ada_url result, const char* input, |
15134 | 50.1k | size_t length) noexcept { |
15135 | 50.1k | ada::result<ada::url_aggregator>& r = get_instance(result); |
15136 | 50.1k | if (!r) { |
15137 | 0 | return false; |
15138 | 0 | } |
15139 | 50.1k | return r->set_protocol(std::string_view(input, length)); |
15140 | 50.1k | } |
15141 | | |
15142 | | bool ada_set_username(ada_url result, const char* input, |
15143 | 50.1k | size_t length) noexcept { |
15144 | 50.1k | ada::result<ada::url_aggregator>& r = get_instance(result); |
15145 | 50.1k | if (!r) { |
15146 | 0 | return false; |
15147 | 0 | } |
15148 | 50.1k | return r->set_username(std::string_view(input, length)); |
15149 | 50.1k | } |
15150 | | |
15151 | | bool ada_set_password(ada_url result, const char* input, |
15152 | 50.1k | size_t length) noexcept { |
15153 | 50.1k | ada::result<ada::url_aggregator>& r = get_instance(result); |
15154 | 50.1k | if (!r) { |
15155 | 0 | return false; |
15156 | 0 | } |
15157 | 50.1k | return r->set_password(std::string_view(input, length)); |
15158 | 50.1k | } |
15159 | | |
15160 | 50.1k | bool ada_set_port(ada_url result, const char* input, size_t length) noexcept { |
15161 | 50.1k | ada::result<ada::url_aggregator>& r = get_instance(result); |
15162 | 50.1k | if (!r) { |
15163 | 0 | return false; |
15164 | 0 | } |
15165 | 50.1k | return r->set_port(std::string_view(input, length)); |
15166 | 50.1k | } |
15167 | | |
15168 | | bool ada_set_pathname(ada_url result, const char* input, |
15169 | 50.1k | size_t length) noexcept { |
15170 | 50.1k | ada::result<ada::url_aggregator>& r = get_instance(result); |
15171 | 50.1k | if (!r) { |
15172 | 0 | return false; |
15173 | 0 | } |
15174 | 50.1k | return r->set_pathname(std::string_view(input, length)); |
15175 | 50.1k | } |
15176 | | |
15177 | | /** |
15178 | | * Update the search/query of the URL. |
15179 | | * |
15180 | | * If a URL has `?` as the search value, passing empty string to this function |
15181 | | * does not remove the attribute. If you need to remove it, please use |
15182 | | * `ada_clear_search` method. |
15183 | | */ |
15184 | 50.1k | void ada_set_search(ada_url result, const char* input, size_t length) noexcept { |
15185 | 50.1k | ada::result<ada::url_aggregator>& r = get_instance(result); |
15186 | 50.1k | if (r) { |
15187 | 50.1k | r->set_search(std::string_view(input, length)); |
15188 | 50.1k | } |
15189 | 50.1k | } |
15190 | | |
15191 | | /** |
15192 | | * Update the hash/fragment of the URL. |
15193 | | * |
15194 | | * If a URL has `#` as the hash value, passing empty string to this function |
15195 | | * does not remove the attribute. If you need to remove it, please use |
15196 | | * `ada_clear_hash` method. |
15197 | | */ |
15198 | 50.1k | void ada_set_hash(ada_url result, const char* input, size_t length) noexcept { |
15199 | 50.1k | ada::result<ada::url_aggregator>& r = get_instance(result); |
15200 | 50.1k | if (r) { |
15201 | 50.1k | r->set_hash(std::string_view(input, length)); |
15202 | 50.1k | } |
15203 | 50.1k | } |
15204 | | |
15205 | 50.1k | void ada_clear_port(ada_url result) noexcept { |
15206 | 50.1k | ada::result<ada::url_aggregator>& r = get_instance(result); |
15207 | 50.1k | if (r) { |
15208 | 50.1k | r->clear_port(); |
15209 | 50.1k | } |
15210 | 50.1k | } |
15211 | | |
15212 | | /** |
15213 | | * Removes the hash of the URL. |
15214 | | * |
15215 | | * Despite `ada_set_hash` method, this function allows the complete |
15216 | | * removal of the hash attribute, even if it has a value of `#`. |
15217 | | */ |
15218 | 50.1k | void ada_clear_hash(ada_url result) noexcept { |
15219 | 50.1k | ada::result<ada::url_aggregator>& r = get_instance(result); |
15220 | 50.1k | if (r) { |
15221 | 50.1k | r->clear_hash(); |
15222 | 50.1k | } |
15223 | 50.1k | } |
15224 | | |
15225 | | /** |
15226 | | * Removes the search of the URL. |
15227 | | * |
15228 | | * Despite `ada_set_search` method, this function allows the complete |
15229 | | * removal of the search attribute, even if it has a value of `?`. |
15230 | | */ |
15231 | 50.1k | void ada_clear_search(ada_url result) noexcept { |
15232 | 50.1k | ada::result<ada::url_aggregator>& r = get_instance(result); |
15233 | 50.1k | if (r) { |
15234 | 50.1k | r->clear_search(); |
15235 | 50.1k | } |
15236 | 50.1k | } |
15237 | | |
15238 | 52.8k | bool ada_has_credentials(ada_url result) noexcept { |
15239 | 52.8k | ada::result<ada::url_aggregator>& r = get_instance(result); |
15240 | 52.8k | if (!r) { |
15241 | 0 | return false; |
15242 | 0 | } |
15243 | 52.8k | return r->has_credentials(); |
15244 | 52.8k | } |
15245 | | |
15246 | 50.1k | bool ada_has_empty_hostname(ada_url result) noexcept { |
15247 | 50.1k | ada::result<ada::url_aggregator>& r = get_instance(result); |
15248 | 50.1k | if (!r) { |
15249 | 0 | return false; |
15250 | 0 | } |
15251 | 50.1k | return r->has_empty_hostname(); |
15252 | 50.1k | } |
15253 | | |
15254 | 50.1k | bool ada_has_hostname(ada_url result) noexcept { |
15255 | 50.1k | ada::result<ada::url_aggregator>& r = get_instance(result); |
15256 | 50.1k | if (!r) { |
15257 | 0 | return false; |
15258 | 0 | } |
15259 | 50.1k | return r->has_hostname(); |
15260 | 50.1k | } |
15261 | | |
15262 | 50.1k | bool ada_has_non_empty_username(ada_url result) noexcept { |
15263 | 50.1k | ada::result<ada::url_aggregator>& r = get_instance(result); |
15264 | 50.1k | if (!r) { |
15265 | 0 | return false; |
15266 | 0 | } |
15267 | 50.1k | return r->has_non_empty_username(); |
15268 | 50.1k | } |
15269 | | |
15270 | 50.1k | bool ada_has_non_empty_password(ada_url result) noexcept { |
15271 | 50.1k | ada::result<ada::url_aggregator>& r = get_instance(result); |
15272 | 50.1k | if (!r) { |
15273 | 0 | return false; |
15274 | 0 | } |
15275 | 50.1k | return r->has_non_empty_password(); |
15276 | 50.1k | } |
15277 | | |
15278 | 52.8k | bool ada_has_port(ada_url result) noexcept { |
15279 | 52.8k | ada::result<ada::url_aggregator>& r = get_instance(result); |
15280 | 52.8k | if (!r) { |
15281 | 0 | return false; |
15282 | 0 | } |
15283 | 52.8k | return r->has_port(); |
15284 | 52.8k | } |
15285 | | |
15286 | 50.1k | bool ada_has_password(ada_url result) noexcept { |
15287 | 50.1k | ada::result<ada::url_aggregator>& r = get_instance(result); |
15288 | 50.1k | if (!r) { |
15289 | 0 | return false; |
15290 | 0 | } |
15291 | 50.1k | return r->has_password(); |
15292 | 50.1k | } |
15293 | | |
15294 | 52.8k | bool ada_has_hash(ada_url result) noexcept { |
15295 | 52.8k | ada::result<ada::url_aggregator>& r = get_instance(result); |
15296 | 52.8k | if (!r) { |
15297 | 0 | return false; |
15298 | 0 | } |
15299 | 52.8k | return r->has_hash(); |
15300 | 52.8k | } |
15301 | | |
15302 | 52.8k | bool ada_has_search(ada_url result) noexcept { |
15303 | 52.8k | ada::result<ada::url_aggregator>& r = get_instance(result); |
15304 | 52.8k | if (!r) { |
15305 | 0 | return false; |
15306 | 0 | } |
15307 | 52.8k | return r->has_search(); |
15308 | 52.8k | } |
15309 | | |
15310 | | // returns a pointer to the internal url_aggregator::url_components |
15311 | 52.8k | const ada_url_components* ada_get_components(ada_url result) noexcept { |
15312 | 52.8k | static_assert(sizeof(ada_url_components) == sizeof(ada::url_components)); |
15313 | 52.8k | ada::result<ada::url_aggregator>& r = get_instance(result); |
15314 | 52.8k | if (!r) { |
15315 | 0 | return nullptr; |
15316 | 0 | } |
15317 | 52.8k | return reinterpret_cast<const ada_url_components*>(&r->get_components()); |
15318 | 52.8k | } |
15319 | | |
15320 | 11.0k | ada_owned_string ada_idna_to_unicode(const char* input, size_t length) { |
15321 | 11.0k | std::string out = ada::idna::to_unicode(std::string_view(input, length)); |
15322 | 11.0k | ada_owned_string owned{}; |
15323 | 11.0k | owned.length = out.length(); |
15324 | 11.0k | owned.data = new char[owned.length]; |
15325 | 11.0k | memcpy((void*)owned.data, out.data(), owned.length); |
15326 | 11.0k | return owned; |
15327 | 11.0k | } |
15328 | | |
15329 | 11.0k | ada_owned_string ada_idna_to_ascii(const char* input, size_t length) { |
15330 | 11.0k | std::string out = ada::idna::to_ascii(std::string_view(input, length)); |
15331 | 11.0k | ada_owned_string owned{}; |
15332 | 11.0k | owned.length = out.size(); |
15333 | 11.0k | owned.data = new char[owned.length]; |
15334 | 11.0k | memcpy((void*)owned.data, out.data(), owned.length); |
15335 | 11.0k | return owned; |
15336 | 11.0k | } |
15337 | | |
15338 | | ada_url_search_params ada_parse_search_params(const char* input, |
15339 | 11.0k | size_t length) { |
15340 | 11.0k | return new ada::result<ada::url_search_params>( |
15341 | 11.0k | ada::url_search_params(std::string_view(input, length))); |
15342 | 11.0k | } |
15343 | | |
15344 | 11.0k | void ada_free_search_params(ada_url_search_params result) { |
15345 | 11.0k | auto* r = (ada::result<ada::url_search_params>*)result; |
15346 | 11.0k | delete r; |
15347 | 11.0k | } |
15348 | | |
15349 | 11.0k | ada_owned_string ada_search_params_to_string(ada_url_search_params result) { |
15350 | 11.0k | ada::result<ada::url_search_params>& r = |
15351 | 11.0k | *(ada::result<ada::url_search_params>*)result; |
15352 | 11.0k | if (!r) return ada_owned_string{nullptr, 0}; |
15353 | 11.0k | std::string out = r->to_string(); |
15354 | 11.0k | ada_owned_string owned{}; |
15355 | 11.0k | owned.length = out.size(); |
15356 | 11.0k | owned.data = new char[owned.length]; |
15357 | 11.0k | memcpy((void*)owned.data, out.data(), owned.length); |
15358 | 11.0k | return owned; |
15359 | 11.0k | } |
15360 | | |
15361 | 11.0k | size_t ada_search_params_size(ada_url_search_params result) { |
15362 | 11.0k | ada::result<ada::url_search_params>& r = |
15363 | 11.0k | *(ada::result<ada::url_search_params>*)result; |
15364 | 11.0k | if (!r) { |
15365 | 0 | return 0; |
15366 | 0 | } |
15367 | 11.0k | return r->size(); |
15368 | 11.0k | } |
15369 | | |
15370 | 11.0k | void ada_search_params_sort(ada_url_search_params result) { |
15371 | 11.0k | ada::result<ada::url_search_params>& r = |
15372 | 11.0k | *(ada::result<ada::url_search_params>*)result; |
15373 | 11.0k | if (r) { |
15374 | 11.0k | r->sort(); |
15375 | 11.0k | } |
15376 | 11.0k | } |
15377 | | |
15378 | | void ada_search_params_reset(ada_url_search_params result, const char* input, |
15379 | 11.0k | size_t length) { |
15380 | 11.0k | ada::result<ada::url_search_params>& r = |
15381 | 11.0k | *(ada::result<ada::url_search_params>*)result; |
15382 | 11.0k | if (r) { |
15383 | 11.0k | r->reset(std::string_view(input, length)); |
15384 | 11.0k | } |
15385 | 11.0k | } |
15386 | | |
15387 | | void ada_search_params_append(ada_url_search_params result, const char* key, |
15388 | | size_t key_length, const char* value, |
15389 | 11.0k | size_t value_length) { |
15390 | 11.0k | ada::result<ada::url_search_params>& r = |
15391 | 11.0k | *(ada::result<ada::url_search_params>*)result; |
15392 | 11.0k | if (r) { |
15393 | 11.0k | r->append(std::string_view(key, key_length), |
15394 | 11.0k | std::string_view(value, value_length)); |
15395 | 11.0k | } |
15396 | 11.0k | } |
15397 | | |
15398 | | void ada_search_params_set(ada_url_search_params result, const char* key, |
15399 | | size_t key_length, const char* value, |
15400 | 11.0k | size_t value_length) { |
15401 | 11.0k | ada::result<ada::url_search_params>& r = |
15402 | 11.0k | *(ada::result<ada::url_search_params>*)result; |
15403 | 11.0k | if (r) { |
15404 | 11.0k | r->set(std::string_view(key, key_length), |
15405 | 11.0k | std::string_view(value, value_length)); |
15406 | 11.0k | } |
15407 | 11.0k | } |
15408 | | |
15409 | | void ada_search_params_remove(ada_url_search_params result, const char* key, |
15410 | 11.0k | size_t key_length) { |
15411 | 11.0k | ada::result<ada::url_search_params>& r = |
15412 | 11.0k | *(ada::result<ada::url_search_params>*)result; |
15413 | 11.0k | if (r) { |
15414 | 11.0k | r->remove(std::string_view(key, key_length)); |
15415 | 11.0k | } |
15416 | 11.0k | } |
15417 | | |
15418 | | void ada_search_params_remove_value(ada_url_search_params result, |
15419 | | const char* key, size_t key_length, |
15420 | 11.0k | const char* value, size_t value_length) { |
15421 | 11.0k | ada::result<ada::url_search_params>& r = |
15422 | 11.0k | *(ada::result<ada::url_search_params>*)result; |
15423 | 11.0k | if (r) { |
15424 | 11.0k | r->remove(std::string_view(key, key_length), |
15425 | 11.0k | std::string_view(value, value_length)); |
15426 | 11.0k | } |
15427 | 11.0k | } |
15428 | | |
15429 | | bool ada_search_params_has(ada_url_search_params result, const char* key, |
15430 | 11.0k | size_t key_length) { |
15431 | 11.0k | ada::result<ada::url_search_params>& r = |
15432 | 11.0k | *(ada::result<ada::url_search_params>*)result; |
15433 | 11.0k | if (!r) { |
15434 | 0 | return false; |
15435 | 0 | } |
15436 | 11.0k | return r->has(std::string_view(key, key_length)); |
15437 | 11.0k | } |
15438 | | |
15439 | | bool ada_search_params_has_value(ada_url_search_params result, const char* key, |
15440 | | size_t key_length, const char* value, |
15441 | 11.0k | size_t value_length) { |
15442 | 11.0k | ada::result<ada::url_search_params>& r = |
15443 | 11.0k | *(ada::result<ada::url_search_params>*)result; |
15444 | 11.0k | if (!r) { |
15445 | 0 | return false; |
15446 | 0 | } |
15447 | 11.0k | return r->has(std::string_view(key, key_length), |
15448 | 11.0k | std::string_view(value, value_length)); |
15449 | 11.0k | } |
15450 | | |
15451 | | ada_string ada_search_params_get(ada_url_search_params result, const char* key, |
15452 | 11.0k | size_t key_length) { |
15453 | 11.0k | ada::result<ada::url_search_params>& r = |
15454 | 11.0k | *(ada::result<ada::url_search_params>*)result; |
15455 | 11.0k | if (!r) { |
15456 | 0 | return ada_string_create(nullptr, 0); |
15457 | 0 | } |
15458 | 11.0k | auto found = r->get(std::string_view(key, key_length)); |
15459 | 11.0k | if (!found.has_value()) { |
15460 | 0 | return ada_string_create(nullptr, 0); |
15461 | 0 | } |
15462 | 11.0k | return ada_string_create(found->data(), found->length()); |
15463 | 11.0k | } |
15464 | | |
15465 | | ada_strings ada_search_params_get_all(ada_url_search_params result, |
15466 | 11.0k | const char* key, size_t key_length) { |
15467 | 11.0k | ada::result<ada::url_search_params>& r = |
15468 | 11.0k | *(ada::result<ada::url_search_params>*)result; |
15469 | 11.0k | if (!r) { |
15470 | 0 | return new ada::result<std::vector<std::string>>( |
15471 | 0 | std::vector<std::string>()); |
15472 | 0 | } |
15473 | 11.0k | return new ada::result<std::vector<std::string>>( |
15474 | 11.0k | r->get_all(std::string_view(key, key_length))); |
15475 | 11.0k | } |
15476 | | |
15477 | | ada_url_search_params_keys_iter ada_search_params_get_keys( |
15478 | 11.0k | ada_url_search_params result) { |
15479 | 11.0k | ada::result<ada::url_search_params>& r = |
15480 | 11.0k | *(ada::result<ada::url_search_params>*)result; |
15481 | 11.0k | if (!r) { |
15482 | 0 | return new ada::result<ada::url_search_params_keys_iter>( |
15483 | 0 | ada::url_search_params_keys_iter()); |
15484 | 0 | } |
15485 | 11.0k | return new ada::result<ada::url_search_params_keys_iter>(r->get_keys()); |
15486 | 11.0k | } |
15487 | | |
15488 | | ada_url_search_params_values_iter ada_search_params_get_values( |
15489 | 11.0k | ada_url_search_params result) { |
15490 | 11.0k | ada::result<ada::url_search_params>& r = |
15491 | 11.0k | *(ada::result<ada::url_search_params>*)result; |
15492 | 11.0k | if (!r) { |
15493 | 0 | return new ada::result<ada::url_search_params_values_iter>( |
15494 | 0 | ada::url_search_params_values_iter()); |
15495 | 0 | } |
15496 | 11.0k | return new ada::result<ada::url_search_params_values_iter>(r->get_values()); |
15497 | 11.0k | } |
15498 | | |
15499 | | ada_url_search_params_entries_iter ada_search_params_get_entries( |
15500 | 11.0k | ada_url_search_params result) { |
15501 | 11.0k | ada::result<ada::url_search_params>& r = |
15502 | 11.0k | *(ada::result<ada::url_search_params>*)result; |
15503 | 11.0k | if (!r) { |
15504 | 0 | return new ada::result<ada::url_search_params_entries_iter>( |
15505 | 0 | ada::url_search_params_entries_iter()); |
15506 | 0 | } |
15507 | 11.0k | return new ada::result<ada::url_search_params_entries_iter>(r->get_entries()); |
15508 | 11.0k | } |
15509 | | |
15510 | 11.0k | void ada_free_strings(ada_strings result) { |
15511 | 11.0k | auto* r = (ada::result<std::vector<std::string>>*)result; |
15512 | 11.0k | delete r; |
15513 | 11.0k | } |
15514 | | |
15515 | 11.0k | size_t ada_strings_size(ada_strings result) { |
15516 | 11.0k | auto* r = (ada::result<std::vector<std::string>>*)result; |
15517 | 11.0k | if (!r) { |
15518 | 0 | return 0; |
15519 | 0 | } |
15520 | 11.0k | return (*r)->size(); |
15521 | 11.0k | } |
15522 | | |
15523 | 11.0k | ada_string ada_strings_get(ada_strings result, size_t index) { |
15524 | 11.0k | auto* r = (ada::result<std::vector<std::string>>*)result; |
15525 | 11.0k | if (!r) { |
15526 | 0 | return ada_string_create(nullptr, 0); |
15527 | 0 | } |
15528 | 11.0k | std::string_view view = (*r)->at(index); |
15529 | 11.0k | return ada_string_create(view.data(), view.length()); |
15530 | 11.0k | } |
15531 | | |
15532 | 11.0k | void ada_free_search_params_keys_iter(ada_url_search_params_keys_iter result) { |
15533 | 11.0k | auto* r = (ada::result<ada::url_search_params_keys_iter>*)result; |
15534 | 11.0k | delete r; |
15535 | 11.0k | } |
15536 | | |
15537 | | ada_string ada_search_params_keys_iter_next( |
15538 | 20.3k | ada_url_search_params_keys_iter result) { |
15539 | 20.3k | auto* r = (ada::result<ada::url_search_params_keys_iter>*)result; |
15540 | 20.3k | if (!r) { |
15541 | 0 | return ada_string_create(nullptr, 0); |
15542 | 0 | } |
15543 | 20.3k | auto next = (*r)->next(); |
15544 | 20.3k | if (!next.has_value()) { |
15545 | 0 | return ada_string_create(nullptr, 0); |
15546 | 0 | } |
15547 | 20.3k | return ada_string_create(next->data(), next->length()); |
15548 | 20.3k | } |
15549 | | |
15550 | | bool ada_search_params_keys_iter_has_next( |
15551 | 31.3k | ada_url_search_params_keys_iter result) { |
15552 | 31.3k | auto* r = (ada::result<ada::url_search_params_keys_iter>*)result; |
15553 | 31.3k | if (!r) { |
15554 | 0 | return false; |
15555 | 0 | } |
15556 | 31.3k | return (*r)->has_next(); |
15557 | 31.3k | } |
15558 | | |
15559 | | void ada_free_search_params_values_iter( |
15560 | 11.0k | ada_url_search_params_values_iter result) { |
15561 | 11.0k | auto* r = (ada::result<ada::url_search_params_values_iter>*)result; |
15562 | 11.0k | delete r; |
15563 | 11.0k | } |
15564 | | |
15565 | | ada_string ada_search_params_values_iter_next( |
15566 | 20.3k | ada_url_search_params_values_iter result) { |
15567 | 20.3k | auto* r = (ada::result<ada::url_search_params_values_iter>*)result; |
15568 | 20.3k | if (!r) { |
15569 | 0 | return ada_string_create(nullptr, 0); |
15570 | 0 | } |
15571 | 20.3k | auto next = (*r)->next(); |
15572 | 20.3k | if (!next.has_value()) { |
15573 | 0 | return ada_string_create(nullptr, 0); |
15574 | 0 | } |
15575 | 20.3k | return ada_string_create(next->data(), next->length()); |
15576 | 20.3k | } |
15577 | | |
15578 | | bool ada_search_params_values_iter_has_next( |
15579 | 31.3k | ada_url_search_params_values_iter result) { |
15580 | 31.3k | auto* r = (ada::result<ada::url_search_params_values_iter>*)result; |
15581 | 31.3k | if (!r) { |
15582 | 0 | return false; |
15583 | 0 | } |
15584 | 31.3k | return (*r)->has_next(); |
15585 | 31.3k | } |
15586 | | |
15587 | | void ada_free_search_params_entries_iter( |
15588 | 11.0k | ada_url_search_params_entries_iter result) { |
15589 | 11.0k | auto* r = (ada::result<ada::url_search_params_entries_iter>*)result; |
15590 | 11.0k | delete r; |
15591 | 11.0k | } |
15592 | | |
15593 | | ada_string_pair ada_search_params_entries_iter_next( |
15594 | 20.3k | ada_url_search_params_entries_iter result) { |
15595 | 20.3k | auto* r = (ada::result<ada::url_search_params_entries_iter>*)result; |
15596 | 20.3k | if (!r) return {ada_string_create(nullptr, 0), ada_string_create(nullptr, 0)}; |
15597 | 20.3k | auto next = (*r)->next(); |
15598 | 20.3k | if (!next.has_value()) { |
15599 | 0 | return {ada_string_create(nullptr, 0), ada_string_create(nullptr, 0)}; |
15600 | 0 | } |
15601 | 20.3k | return ada_string_pair{ |
15602 | 20.3k | ada_string_create(next->first.data(), next->first.length()), |
15603 | 20.3k | ada_string_create(next->second.data(), next->second.length())}; |
15604 | 20.3k | } |
15605 | | |
15606 | | bool ada_search_params_entries_iter_has_next( |
15607 | 31.3k | ada_url_search_params_entries_iter result) { |
15608 | 31.3k | auto* r = (ada::result<ada::url_search_params_entries_iter>*)result; |
15609 | 31.3k | if (!r) { |
15610 | 0 | return false; |
15611 | 0 | } |
15612 | 31.3k | return (*r)->has_next(); |
15613 | 31.3k | } |
15614 | | |
15615 | 0 | void ada_set_max_input_length(uint32_t length) noexcept { |
15616 | 0 | ada::set_max_input_length(length); |
15617 | 0 | } |
15618 | | |
15619 | 0 | uint32_t ada_get_max_input_length() noexcept { |
15620 | 0 | return ada::get_max_input_length(); |
15621 | 0 | } |
15622 | | |
15623 | | typedef struct { |
15624 | | int major; |
15625 | | int minor; |
15626 | | int revision; |
15627 | | } ada_version_components; |
15628 | | |
15629 | 11.0k | const char* ada_get_version() { return ADA_VERSION; } |
15630 | | |
15631 | 11.0k | ada_version_components ada_get_version_components() { |
15632 | 11.0k | return ada_version_components{ |
15633 | 11.0k | .major = ada::ADA_VERSION_MAJOR, |
15634 | 11.0k | .minor = ada::ADA_VERSION_MINOR, |
15635 | 11.0k | .revision = ada::ADA_VERSION_REVISION, |
15636 | 11.0k | }; |
15637 | 11.0k | } |
15638 | | |
15639 | | } // extern "C" |
15640 | | // NOLINTEND(bugprone-exception-escape, |
15641 | | // bugprone-suspicious-stringview-data-usage) |
15642 | | /* end file src/ada_c.cpp */ |
15643 | | /* end file src/ada.cpp */ |