Coverage Report

Created: 2026-08-14 06:26

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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) const
Line
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) const
Line
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()() const
Unexecuted 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()() const
Line
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()() const
Line
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 */